From cabeaee67979ae67b4774008f5e6e721d6fab913 Mon Sep 17 00:00:00 2001 From: Shuanglei Tao Date: Tue, 17 Dec 2024 00:45:30 +0800 Subject: [PATCH] upgrade to sdk12 --- .gitignore | 5 +- EPD/EPD_Test.c | 18 +- EPD/EPD_ble.c | 67 +- EPD/EPD_ble.h | 5 +- Keil/EPD.uvprojx | 1277 +- .../Device/nRF51802_xxAA/arm_startup_nrf51.s | 259 + Keil/RTE/Device/nRF51802_xxAA/system_nrf51.c | 151 + .../Device/nRF51822_xxAB/arm_startup_nrf51.s | 90 +- Keil/RTE/Device/nRF51822_xxAB/system_nrf51.c | 58 +- Keil/RTE/_EPD/RTE_Components.h | 21 - Keil/RTE/_EPD_Debug/RTE_Components.h | 21 - Keil/RTE/_flash_softdevice/RTE_Components.h | 21 - .../ant_channel_config/ant_channel_config.c | 93 +- .../ant_channel_config/ant_channel_config.h | 60 +- .../ant/ant_encryption/ant_encrypt_config.c | 98 +- .../ant/ant_encryption/ant_encrypt_config.h | 69 +- .../ant_encrypt_negotiation_slave.c | 62 +- .../ant_encrypt_negotiation_slave.h | 59 +- components/{libraries => ant}/ant_fs/antfs.c | 282 +- components/{libraries => ant}/ant_fs/antfs.h | 89 +- components/ant/ant_fs/crc.c | 99 + components/ant/ant_fs/crc.h | 95 + components/ant/ant_fs/defines.h | 113 + .../ant/ant_key_manager/ant_key_manager.c | 55 +- .../ant/ant_key_manager/ant_key_manager.h | 59 +- .../config/ant_key_manager_config.h | 61 +- .../ant/ant_profiles/ant_bpwr/ant_bpwr.c | 88 +- .../ant/ant_profiles/ant_bpwr/ant_bpwr.h | 59 +- .../ant_profiles/ant_bpwr/ant_bpwr_local.h | 59 +- .../ant_bpwr/pages/ant_bpwr_common_data.c | 68 +- .../ant_bpwr/pages/ant_bpwr_common_data.h | 59 +- .../ant_bpwr/pages/ant_bpwr_page_1.c | 95 +- .../ant_bpwr/pages/ant_bpwr_page_1.h | 57 +- .../ant_bpwr/pages/ant_bpwr_page_16.c | 75 +- .../ant_bpwr/pages/ant_bpwr_page_16.h | 57 +- .../ant_bpwr/pages/ant_bpwr_page_17.c | 68 +- .../ant_bpwr/pages/ant_bpwr_page_17.h | 57 +- .../ant_bpwr/pages/ant_bpwr_page_18.c | 68 +- .../ant_bpwr/pages/ant_bpwr_page_18.h | 48 + .../ant_bpwr/pages/ant_bpwr_page_torque.c | 73 +- .../ant_bpwr/pages/ant_bpwr_page_torque.h | 57 +- .../ant_bpwr/pages/ant_bpwr_pages.h | 61 +- .../pages/logger/ant_bpwr_page_logger.h | 58 - .../ant_bpwr/simulator/ant_bpwr_simulator.c | 50 +- .../ant_bpwr/simulator/ant_bpwr_simulator.h | 57 +- .../simulator/ant_bpwr_simulator_local.h | 59 +- .../ant_bpwr/utils/ant_bpwr_utils.h | 59 +- components/ant/ant_profiles/ant_bsc/ant_bsc.c | 99 +- components/ant/ant_profiles/ant_bsc/ant_bsc.h | 61 +- .../ant/ant_profiles/ant_bsc/ant_bsc_local.h | 59 +- .../ant_bsc/pages/ant_bsc_combined_page_0.c | 85 +- .../ant_bsc/pages/ant_bsc_combined_page_0.h | 59 +- .../ant_bsc/pages/ant_bsc_page_0.c | 75 +- .../ant_bsc/pages/ant_bsc_page_0.h | 59 +- .../ant_bsc/pages/ant_bsc_page_1.c | 75 +- .../ant_bsc/pages/ant_bsc_page_1.h | 59 +- .../ant_bsc/pages/ant_bsc_page_2.c | 72 +- .../ant_bsc/pages/ant_bsc_page_2.h | 59 +- .../ant_bsc/pages/ant_bsc_page_3.c | 71 +- .../ant_bsc/pages/ant_bsc_page_3.h | 59 +- .../ant_bsc/pages/ant_bsc_page_4.c | 70 +- .../ant_bsc/pages/ant_bsc_page_4.h | 61 +- .../ant_bsc/pages/ant_bsc_page_5.c | 69 +- .../ant_bsc/pages/ant_bsc_page_5.h | 59 +- .../ant_bsc/pages/ant_bsc_pages.h | 59 +- .../pages/logger/ant_bsc_page_logger.h | 71 - .../ant_bsc/simulator/ant_bsc_simulator.c | 84 +- .../ant_bsc/simulator/ant_bsc_simulator.h | 66 +- .../simulator/ant_bsc_simulator_local.h | 58 +- .../ant_bsc/utils/ant_bsc_utils.h | 59 +- .../ant_request_controller.c | 58 +- .../ant_request_controller.h | 57 +- .../ant_common/pages/ant_common_page_70.c | 83 +- .../ant_common/pages/ant_common_page_70.h | 59 +- .../ant_common/pages/ant_common_page_80.c | 71 +- .../ant_common/pages/ant_common_page_80.h | 63 +- .../ant_common/pages/ant_common_page_81.c | 71 +- .../ant_common/pages/ant_common_page_81.h | 61 +- .../pages/logger/ant_common_page_logger.h | 26 - components/ant/ant_profiles/ant_hrm/ant_hrm.c | 81 +- components/ant/ant_profiles/ant_hrm/ant_hrm.h | 59 +- .../ant/ant_profiles/ant_hrm/ant_hrm_local.h | 59 +- .../ant_hrm/pages/ant_hrm_page_0.c | 76 +- .../ant_hrm/pages/ant_hrm_page_0.h | 57 +- .../ant_hrm/pages/ant_hrm_page_1.c | 76 +- .../ant_hrm/pages/ant_hrm_page_1.h | 57 +- .../ant_hrm/pages/ant_hrm_page_2.c | 68 +- .../ant_hrm/pages/ant_hrm_page_2.h | 57 +- .../ant_hrm/pages/ant_hrm_page_3.c | 70 +- .../ant_hrm/pages/ant_hrm_page_3.h | 57 +- .../ant_hrm/pages/ant_hrm_page_4.c | 70 +- .../ant_hrm/pages/ant_hrm_page_4.h | 57 +- .../ant_hrm/pages/ant_hrm_pages.h | 59 +- .../pages/logger/ant_hrm_page_logger.h | 57 - .../ant_hrm/simulator/ant_hrm_simulator.c | 52 +- .../ant_hrm/simulator/ant_hrm_simulator.h | 58 +- .../simulator/ant_hrm_simulator_local.h | 58 +- .../ant_hrm/utils/ant_hrm_utils.h | 59 +- components/ant/ant_profiles/ant_sdm/ant_sdm.c | 84 +- components/ant/ant_profiles/ant_sdm/ant_sdm.h | 61 +- .../ant/ant_profiles/ant_sdm/ant_sdm_local.h | 59 +- .../ant_sdm/pages/ant_sdm_common_data.c | 72 +- .../ant_sdm/pages/ant_sdm_common_data.h | 57 +- .../ant_sdm/pages/ant_sdm_page_1.c | 73 +- .../ant_sdm/pages/ant_sdm_page_1.h | 57 +- .../ant_sdm/pages/ant_sdm_page_16.c | 76 +- .../ant_sdm/pages/ant_sdm_page_16.h | 57 +- .../ant_sdm/pages/ant_sdm_page_2.c | 87 +- .../ant_sdm/pages/ant_sdm_page_2.h | 57 +- .../ant_sdm/pages/ant_sdm_page_22.c | 80 +- .../ant_sdm/pages/ant_sdm_page_22.h | 57 +- .../ant_sdm/pages/ant_sdm_page_3.c | 70 +- .../ant_sdm/pages/ant_sdm_page_3.h | 59 +- .../ant_sdm/pages/ant_sdm_pages.h | 61 +- .../pages/logger/ant_sdm_page_logger.h | 65 - .../ant_sdm/simulator/ant_sdm_simulator.c | 56 +- .../ant_sdm/simulator/ant_sdm_simulator.h | 58 +- .../simulator/ant_sdm_simulator_local.h | 58 +- .../ant_sdm/utils/ant_sdm_utils.h | 60 +- .../ant/ant_search_config/ant_search_config.c | 74 +- .../ant/ant_search_config/ant_search_config.h | 53 +- .../ant/ant_stack_config/ant_stack_config.c | 68 +- .../ant/ant_stack_config/ant_stack_config.h | 65 +- .../config/ant_stack_config_defs.h | 60 +- .../ant_state_indicator/ant_state_indicator.c | 58 +- .../ant_state_indicator/ant_state_indicator.h | 50 +- .../ble/ble_advertising/ble_advertising.c | 816 +- .../ble/ble_advertising/ble_advertising.h | 136 +- .../ble/ble_db_discovery/ble_db_discovery.c | 429 +- .../ble/ble_db_discovery/ble_db_discovery.h | 157 +- .../ble_debug_assert_handler.c | 50 +- .../ble_debug_assert_handler.h | 71 +- components/ble/ble_dtm/ble_dtm.c | 288 +- components/ble/ble_dtm/ble_dtm.h | 112 +- components/ble/ble_dtm/ble_dtm_hw.h | 104 + components/ble/ble_dtm/ble_dtm_hw_nrf51.c | 121 + components/ble/ble_dtm/ble_dtm_hw_nrf52.c | 119 + components/ble/ble_error_log/ble_error_log.c | 48 +- components/ble/ble_error_log/ble_error_log.h | 59 +- components/ble/ble_racp/ble_racp.c | 53 +- components/ble/ble_racp/ble_racp.h | 98 +- .../ble_radio_notification.c | 51 +- .../ble_radio_notification.h | 60 +- .../ble_ancs_c/ancs_app_attr_get.c | 365 + .../ble_ancs_c/ancs_app_attr_get.h | 67 + .../ble_ancs_c/ancs_attr_parser.c | 410 + .../ble_ancs_c/ancs_attr_parser.h | 78 + .../ble_services/ble_ancs_c/ancs_tx_buffer.c | 114 + .../ble_services/ble_ancs_c/ancs_tx_buffer.h | 104 + .../ble/ble_services/ble_ancs_c/ble_ancs_c.c | 737 - .../ble/ble_services/ble_ancs_c/ble_ancs_c.h | 320 - .../ble_services/ble_ancs_c/nrf_ble_ancs_c.c | 659 + .../ble_services/ble_ancs_c/nrf_ble_ancs_c.h | 582 + .../ble/ble_services/ble_ans_c/ble_ans_c.c | 882 +- .../ble/ble_services/ble_ans_c/ble_ans_c.h | 282 +- components/ble/ble_services/ble_bas/ble_bas.c | 68 +- components/ble/ble_services/ble_bas/ble_bas.h | 65 +- .../ble/ble_services/ble_bas_c/ble_bas_c.c | 215 +- .../ble/ble_services/ble_bas_c/ble_bas_c.h | 109 +- components/ble/ble_services/ble_bps/ble_bps.c | 105 +- components/ble/ble_services/ble_bps/ble_bps.h | 66 +- .../ble/ble_services/ble_cscs/ble_cscs.c | 60 +- .../ble/ble_services/ble_cscs/ble_cscs.h | 77 +- .../ble/ble_services/ble_cscs/ble_sc_ctrlpt.c | 58 +- .../ble/ble_services/ble_cscs/ble_sc_ctrlpt.h | 63 +- .../ble/ble_services/ble_cts_c/ble_cts_c.c | 169 +- .../ble/ble_services/ble_cts_c/ble_cts_c.h | 131 +- components/ble/ble_services/ble_dfu/ble_dfu.c | 776 +- components/ble/ble_services/ble_dfu/ble_dfu.h | 309 +- components/ble/ble_services/ble_dis/ble_dis.c | 58 +- components/ble/ble_services/ble_dis/ble_dis.h | 69 +- .../ble/ble_services/ble_escs/escs_defs.h | 134 + .../ble/ble_services/ble_escs/nrf_ble_escs.c | 661 + .../ble/ble_services/ble_escs/nrf_ble_escs.h | 262 + components/ble/ble_services/ble_gls/ble_gls.c | 77 +- components/ble/ble_services/ble_gls/ble_gls.h | 64 +- .../ble/ble_services/ble_gls/ble_gls_db.c | 51 +- .../ble/ble_services/ble_gls/ble_gls_db.h | 68 +- .../ble/ble_services/ble_hids/ble_hids.c | 104 +- .../ble/ble_services/ble_hids/ble_hids.h | 97 +- components/ble/ble_services/ble_hrs/ble_hrs.c | 89 +- components/ble/ble_services/ble_hrs/ble_hrs.h | 78 +- .../ble/ble_services/ble_hrs_c/ble_hrs_c.c | 209 +- .../ble/ble_services/ble_hrs_c/ble_hrs_c.h | 126 +- components/ble/ble_services/ble_hts/ble_hts.c | 63 +- components/ble/ble_services/ble_hts/ble_hts.h | 66 +- components/ble/ble_services/ble_ias/ble_ias.c | 56 +- components/ble/ble_services/ble_ias/ble_ias.h | 69 +- .../ble/ble_services/ble_ias_c/ble_ias_c.c | 262 +- .../ble/ble_services/ble_ias_c/ble_ias_c.h | 134 +- components/ble/ble_services/ble_lbs/ble_lbs.c | 83 +- components/ble/ble_services/ble_lbs/ble_lbs.h | 65 +- .../ble/ble_services/ble_lbs_c/ble_lbs_c.c | 392 + .../ble/ble_services/ble_lbs_c/ble_lbs_c.h | 231 + components/ble/ble_services/ble_lls/ble_lls.c | 56 +- components/ble/ble_services/ble_lls/ble_lls.h | 67 +- components/ble/ble_services/ble_nus/ble_nus.c | 86 +- components/ble/ble_services/ble_nus/ble_nus.h | 75 +- .../ble/ble_services/ble_nus_c/ble_nus_c.c | 207 +- .../ble/ble_services/ble_nus_c/ble_nus_c.h | 143 +- .../ble/ble_services/ble_rscs/ble_rscs.c | 64 +- .../ble/ble_services/ble_rscs/ble_rscs.h | 67 +- .../ble/ble_services/ble_rscs_c/ble_rscs_c.c | 173 +- .../ble/ble_services/ble_rscs_c/ble_rscs_c.h | 116 +- components/ble/ble_services/ble_tps/ble_tps.c | 56 +- components/ble/ble_services/ble_tps/ble_tps.h | 63 +- .../experimental_ble_lns/ble_ln_common.h | 95 + .../experimental_ble_lns/ble_ln_cp.c | 821 + .../experimental_ble_lns/ble_ln_cp.h | 256 + .../experimental_ble_lns/ble_ln_db.c | 152 + .../experimental_ble_lns/ble_ln_db.h | 123 + .../experimental_ble_lns/ble_lns.c | 1490 +- .../experimental_ble_lns/ble_lns.h | 297 +- .../experimental_nrf_ble_bms/nrf_ble_bms.c | 616 + .../experimental_nrf_ble_bms/nrf_ble_bms.h | 318 + .../experimental_nrf_ble_cgms/cgms_db.c | 145 + .../experimental_nrf_ble_cgms/cgms_db.h | 120 + .../experimental_nrf_ble_cgms/cgms_meas.c | 249 + .../experimental_nrf_ble_cgms/cgms_meas.h | 104 + .../experimental_nrf_ble_cgms/cgms_racp.c | 800 + .../experimental_nrf_ble_cgms/cgms_racp.h | 100 + .../experimental_nrf_ble_cgms/cgms_socp.c | 432 + .../experimental_nrf_ble_cgms/cgms_socp.h | 108 + .../experimental_nrf_ble_cgms/cgms_sst.c | 235 + .../experimental_nrf_ble_cgms/cgms_sst.h | 116 + .../experimental_nrf_ble_cgms/nrf_ble_cgms.c | 503 + .../experimental_nrf_ble_cgms/nrf_ble_cgms.h | 436 + components/ble/common/ble_advdata.c | 329 +- components/ble/common/ble_advdata.h | 83 +- components/ble/common/ble_conn_params.c | 50 +- components/ble/common/ble_conn_params.h | 61 +- components/ble/common/ble_conn_state.c | 61 +- components/ble/common/ble_conn_state.h | 67 +- components/ble/common/ble_date_time.h | 72 +- components/ble/common/ble_gatt_db.h | 70 +- components/ble/common/ble_sensor_location.h | 59 +- components/ble/common/ble_srv_common.c | 63 +- components/ble/common/ble_srv_common.h | 101 +- .../config/device_manager_cnfg.h | 98 - .../ble/device_manager/device_manager.h | 888 - .../device_manager/device_manager_central.c | 2793 --- .../device_manager_peripheral.c | 2914 --- components/ble/nrf_ble_gatt/nrf_ble_gatt.c | 303 + components/ble/nrf_ble_gatt/nrf_ble_gatt.h | 197 + components/ble/nrf_ble_qwr/nrf_ble_qwr.c | 405 + components/ble/nrf_ble_qwr/nrf_ble_qwr.h | 220 + .../ble/peer_manager/gatt_cache_manager.c | 330 +- .../ble/peer_manager/gatt_cache_manager.h | 94 +- .../ble/peer_manager/gattc_cache_manager.c | 108 - .../ble/peer_manager/gattc_cache_manager.h | 83 - .../ble/peer_manager/gatts_cache_manager.c | 304 +- .../ble/peer_manager/gatts_cache_manager.h | 74 +- components/ble/peer_manager/id_manager.c | 1081 +- components/ble/peer_manager/id_manager.h | 254 +- components/ble/peer_manager/peer_data.c | 161 +- components/ble/peer_manager/peer_data.h | 65 +- .../ble/peer_manager/peer_data_storage.c | 928 +- .../ble/peer_manager/peer_data_storage.h | 410 +- components/ble/peer_manager/peer_database.c | 596 +- components/ble/peer_manager/peer_database.h | 223 +- components/ble/peer_manager/peer_id.c | 146 +- components/ble/peer_manager/peer_id.h | 105 +- components/ble/peer_manager/peer_manager.c | 961 +- components/ble/peer_manager/peer_manager.h | 913 +- .../ble/peer_manager/peer_manager_internal.h | 200 + .../ble/peer_manager/peer_manager_types.h | 356 +- components/ble/peer_manager/pm_buffer.c | 76 +- components/ble/peer_manager/pm_buffer.h | 100 +- components/ble/peer_manager/pm_mutex.c | 54 +- components/ble/peer_manager/pm_mutex.h | 65 +- .../ble/peer_manager/security_dispatcher.c | 711 +- .../ble/peer_manager/security_dispatcher.h | 98 +- .../ble/peer_manager/security_manager.c | 413 +- .../ble/peer_manager/security_manager.h | 119 +- components/boards/arduino_primo.h | 117 + components/boards/boards.c | 165 + components/boards/boards.h | 319 + components/boards/d52_starterkit.h | 140 + components/boards/n5_starterkit.h | 139 + components/boards/nrf6310.h | 186 + components/boards/pca10000.h | 103 + components/boards/pca10001.h | 170 + components/boards/pca10003.h | 98 + components/boards/pca10028.h | 180 + components/boards/pca10031.h | 97 + components/boards/pca10036.h | 182 + components/boards/pca10040.h | 182 + components/boards/pca10056.h | 136 + components/boards/pca20006.h | 99 + components/boards/wt51822.h | 94 + components/device/compiler_abstraction.h | 106 +- components/device/nrf.h | 48 +- components/device/nrf51.h | 104 +- components/device/nrf51422_peripherals.h | 144 + components/device/nrf51802_peripherals.h | 144 + components/device/nrf51822_peripherals.h | 144 + components/device/nrf51_bitfields.h | 775 +- components/device/nrf51_deprecated.h | 10 +- components/device/nrf51_to_nrf52.h | 787 +- components/device/nrf51_to_nrf52840.h | 567 + components/device/nrf52.h | 69 +- components/device/nrf52832_peripherals.h | 218 + components/device/nrf52840.h | 2417 +++ components/device/nrf52840_bitfields.h | 14633 ++++++++++++++++ components/device/nrf52840_peripherals.h | 240 + components/device/nrf52_bitfields.h | 803 +- components/device/nrf52_name_change.h | 70 + components/device/nrf52_to_nrf52840.h | 88 + components/drivers_ext/adns2080/adns2080.c | 50 +- components/drivers_ext/adns2080/adns2080.h | 97 +- .../drivers_ext/cherry8x16/cherry8x16.c | 52 +- .../drivers_ext/cherry8x16/cherry8x16.h | 67 +- components/drivers_ext/ds1624/ds1624.c | 58 +- components/drivers_ext/ds1624/ds1624.h | 63 +- components/drivers_ext/max9850/max9850.c | 72 + components/drivers_ext/max9850/max9850.h | 131 + components/drivers_ext/mcp4725/mcp4725.c | 155 + components/drivers_ext/mcp4725/mcp4725.h | 100 + components/drivers_ext/mpu6050/mpu6050.c | 48 +- components/drivers_ext/mpu6050/mpu6050.h | 59 +- components/drivers_ext/nrf6350/nrf6350.c | 54 +- components/drivers_ext/nrf6350/nrf6350.h | 69 +- .../drivers_ext/segger_rtt/RTT_Syscalls_GCC.c | 8 +- .../drivers_ext/segger_rtt/RTT_Syscalls_IAR.c | 5 +- .../segger_rtt/RTT_Syscalls_KEIL.c | 47 +- .../drivers_ext/segger_rtt/SEGGER_RTT.c | 2 +- .../drivers_ext/segger_rtt/SEGGER_RTT.h | 2 +- .../drivers_ext/segger_rtt/SEGGER_RTT_Conf.h | 109 +- .../segger_rtt/SEGGER_RTT_printf.c | 7 + .../segger_rtt/license/license.txt | 38 + .../synaptics_touchpad/synaptics_touchpad.c | 52 +- .../synaptics_touchpad/synaptics_touchpad.h | 69 +- components/drivers_ext/uda1380/uda1380.c | 125 + components/drivers_ext/uda1380/uda1380.h | 141 + components/drivers_nrf/adc/nrf_drv_adc.c | 329 + components/drivers_nrf/adc/nrf_drv_adc.h | 295 + components/drivers_nrf/ble_flash/ble_flash.c | 54 +- components/drivers_nrf/ble_flash/ble_flash.h | 75 +- components/drivers_nrf/clock/nrf_drv_clock.c | 775 +- components/drivers_nrf/clock/nrf_drv_clock.h | 296 +- .../drivers_nrf/common/nrf_drv_common.c | 300 +- .../drivers_nrf/common/nrf_drv_common.h | 261 +- .../drivers_nrf/common/nrf_drv_validation.h | 21 - components/drivers_nrf/comp/nrf_drv_comp.c | 238 + components/drivers_nrf/comp/nrf_drv_comp.h | 244 + .../drivers_nrf/config/nrf_drv_config.h | 341 - .../config/nrf_drv_config_validation.h | 62 - components/drivers_nrf/delay/nrf_delay.c | 26 - components/drivers_nrf/delay/nrf_delay.h | 431 +- .../drivers_nrf/gpiote/nrf_drv_gpiote.c | 464 +- .../drivers_nrf/gpiote/nrf_drv_gpiote.h | 157 +- components/drivers_nrf/hal/nrf_adc.c | 64 +- components/drivers_nrf/hal/nrf_adc.h | 252 +- components/drivers_nrf/hal/nrf_clock.h | 351 +- components/drivers_nrf/hal/nrf_comp.h | 510 + components/drivers_nrf/hal/nrf_ecb.c | 65 +- components/drivers_nrf/hal/nrf_ecb.h | 62 +- components/drivers_nrf/hal/nrf_egu.h | 116 +- components/drivers_nrf/hal/nrf_gpio.h | 744 +- components/drivers_nrf/hal/nrf_gpiote.h | 136 +- components/drivers_nrf/hal/nrf_i2s.h | 564 + components/drivers_nrf/hal/nrf_lpcomp.h | 111 +- components/drivers_nrf/hal/nrf_nvmc.c | 197 +- components/drivers_nrf/hal/nrf_nvmc.h | 64 +- components/drivers_nrf/hal/nrf_pdm.h | 398 + components/drivers_nrf/hal/nrf_peripherals.h | 70 + components/drivers_nrf/hal/nrf_power.h | 1039 ++ components/drivers_nrf/hal/nrf_ppi.h | 118 +- components/drivers_nrf/hal/nrf_pwm.h | 702 + components/drivers_nrf/hal/nrf_qdec.h | 74 +- components/drivers_nrf/hal/nrf_qspi.h | 766 + components/drivers_nrf/hal/nrf_rng.h | 67 +- components/drivers_nrf/hal/nrf_rtc.h | 104 +- components/drivers_nrf/hal/nrf_saadc.c | 58 +- components/drivers_nrf/hal/nrf_saadc.h | 140 +- components/drivers_nrf/hal/nrf_spi.h | 171 +- components/drivers_nrf/hal/nrf_spim.h | 295 +- components/drivers_nrf/hal/nrf_spis.h | 250 +- components/drivers_nrf/hal/nrf_systick.h | 184 + components/drivers_nrf/hal/nrf_temp.h | 61 +- components/drivers_nrf/hal/nrf_timer.h | 676 +- components/drivers_nrf/hal/nrf_twi.h | 465 +- components/drivers_nrf/hal/nrf_twim.h | 519 + components/drivers_nrf/hal/nrf_twis.h | 338 +- components/drivers_nrf/hal/nrf_uart.h | 148 +- components/drivers_nrf/hal/nrf_uarte.h | 129 +- components/drivers_nrf/hal/nrf_usbd.h | 1289 ++ components/drivers_nrf/hal/nrf_wdt.h | 61 +- components/drivers_nrf/i2s/nrf_drv_i2s.c | 438 + components/drivers_nrf/i2s/nrf_drv_i2s.h | 256 + .../drivers_nrf/lpcomp/nrf_drv_lpcomp.c | 113 +- .../drivers_nrf/lpcomp/nrf_drv_lpcomp.h | 108 +- .../drivers_nrf/nrf_soc_nosd/nrf_error.h | 58 +- .../drivers_nrf/nrf_soc_nosd/nrf_nvic.c | 124 + .../drivers_nrf/nrf_soc_nosd/nrf_nvic.h | 167 + components/drivers_nrf/nrf_soc_nosd/nrf_soc.c | 129 +- components/drivers_nrf/nrf_soc_nosd/nrf_soc.h | 169 +- components/drivers_nrf/pdm/nrf_drv_pdm.c | 249 + components/drivers_nrf/pdm/nrf_drv_pdm.h | 204 + components/drivers_nrf/power/nrf_drv_power.c | 272 + components/drivers_nrf/power/nrf_drv_power.h | 349 + components/drivers_nrf/ppi/nrf_drv_ppi.c | 284 +- components/drivers_nrf/ppi/nrf_drv_ppi.h | 96 +- .../pstorage/config/pstorage_platform.h | 78 - components/drivers_nrf/pstorage/pstorage.c | 1572 -- components/drivers_nrf/pstorage/pstorage.h | 381 - .../drivers_nrf/pstorage/pstorage_nosd.c | 525 - .../drivers_nrf/pstorage/pstorage_raw.c | 471 - components/drivers_nrf/pwm/nrf_drv_pwm.c | 412 + components/drivers_nrf/pwm/nrf_drv_pwm.h | 479 + components/drivers_nrf/qdec/nrf_drv_qdec.c | 99 +- components/drivers_nrf/qdec/nrf_drv_qdec.h | 87 +- components/drivers_nrf/qspi/nrf_drv_qspi.c | 301 + components/drivers_nrf/qspi/nrf_drv_qspi.h | 312 + .../drivers_nrf/radio_config/radio_config.c | 96 +- .../drivers_nrf/radio_config/radio_config.h | 57 +- components/drivers_nrf/rng/nrf_drv_rng.c | 352 +- components/drivers_nrf/rng/nrf_drv_rng.h | 120 +- components/drivers_nrf/rtc/nrf_drv_rtc.c | 165 +- components/drivers_nrf/rtc/nrf_drv_rtc.h | 131 +- components/drivers_nrf/saadc/nrf_drv_saadc.c | 628 + components/drivers_nrf/saadc/nrf_drv_saadc.h | 327 + .../drivers_nrf/sdio/config/sdio_config.h | 57 +- components/drivers_nrf/sdio/sdio.c | 48 +- components/drivers_nrf/sdio/sdio.h | 67 +- .../drivers_nrf/spi_master/nrf_drv_spi.c | 589 +- .../drivers_nrf/spi_master/nrf_drv_spi.h | 248 +- .../drivers_nrf/spi_master/spi_5W_master.c | 54 +- .../drivers_nrf/spi_master/spi_5W_master.h | 85 +- .../drivers_nrf/spi_slave/nrf_drv_spis.c | 310 +- .../drivers_nrf/spi_slave/nrf_drv_spis.h | 205 +- components/drivers_nrf/swi/nrf_drv_swi.c | 137 +- components/drivers_nrf/swi/nrf_drv_swi.h | 94 +- .../drivers_nrf/systick/nrf_drv_systick.c | 173 + .../drivers_nrf/systick/nrf_drv_systick.h | 133 + components/drivers_nrf/timer/nrf_drv_timer.c | 393 +- components/drivers_nrf/timer/nrf_drv_timer.h | 386 +- .../deprecated/config/twi_master_config.h | 57 +- .../twi_master/deprecated/twi_hw_master.c | 60 +- .../twi_master/deprecated/twi_master.h | 71 +- .../twi_master/deprecated/twi_sw_master.c | 48 +- .../drivers_nrf/twi_master/nrf_drv_twi.c | 1522 +- .../drivers_nrf/twi_master/nrf_drv_twi.h | 480 +- .../drivers_nrf/twis_slave/nrf_drv_twis.c | 942 + .../drivers_nrf/twis_slave/nrf_drv_twis.h | 396 + .../twis_slave/nrf_drv_twis_inst.def | 20 + components/drivers_nrf/uart/nrf_drv_uart.c | 1091 +- components/drivers_nrf/uart/nrf_drv_uart.h | 304 +- components/drivers_nrf/usbd/nrf_drv_usbd.c | 1709 ++ components/drivers_nrf/usbd/nrf_drv_usbd.h | 659 + components/drivers_nrf/wdt/nrf_drv_wdt.c | 84 +- components/drivers_nrf/wdt/nrf_drv_wdt.h | 78 +- components/libraries/ant_fs/crc.c | 55 - components/libraries/ant_fs/crc.h | 42 - components/libraries/ant_fs/defines.h | 60 - components/libraries/atomic/nrf_atomic.h | 349 + .../libraries/atomic/nrf_atomic_internal.h | 245 + .../atomic/nrf_atomic_sanity_check.h | 154 + components/libraries/atomic_fifo/app_atfifo.c | 159 + components/libraries/atomic_fifo/app_atfifo.h | 448 + .../atomic_fifo/app_atfifo_internal.h | 576 + components/libraries/balloc/nrf_balloc.c | 323 + components/libraries/balloc/nrf_balloc.h | 298 + .../block_dev/empty/nrf_block_dev_empty.c | 211 + .../block_dev/empty/nrf_block_dev_empty.h | 141 + .../libraries/block_dev/nrf_block_dev.h | 353 + .../block_dev/qspi/nrf_block_dev_qspi.c | 758 + .../block_dev/qspi/nrf_block_dev_qspi.h | 173 + .../block_dev/qspi/nrf_serial_flash_params.c | 66 + .../block_dev/qspi/nrf_serial_flash_params.h | 84 + .../block_dev/ram/nrf_block_dev_ram.c | 206 + .../block_dev/ram/nrf_block_dev_ram.h | 141 + .../block_dev/sdc/nrf_block_dev_sdc.c | 393 + .../block_dev/sdc/nrf_block_dev_sdc.h | 141 + .../bootloader/ble_dfu/nrf_ble_dfu.c | 1021 ++ .../bootloader/ble_dfu/nrf_ble_dfu.h | 122 + components/libraries/bootloader/dfu/nrf_dfu.c | 177 + components/libraries/bootloader/dfu/nrf_dfu.h | 107 + .../libraries/bootloader/dfu/nrf_dfu_flash.c | 317 + .../libraries/bootloader/dfu/nrf_dfu_flash.h | 157 + .../libraries/bootloader/dfu/nrf_dfu_mbr.c | 135 + .../libraries/bootloader/dfu/nrf_dfu_mbr.h | 120 + .../bootloader/dfu/nrf_dfu_req_handler.h | 204 + .../bootloader/dfu/nrf_dfu_settings.c | 260 + .../bootloader/dfu/nrf_dfu_settings.h | 89 + .../bootloader/dfu/nrf_dfu_transport.c | 99 + .../bootloader/dfu/nrf_dfu_transport.h | 126 + .../libraries/bootloader/dfu/nrf_dfu_types.h | 237 + .../libraries/bootloader/dfu/nrf_dfu_utils.c | 574 + .../libraries/bootloader/dfu/nrf_dfu_utils.h | 120 + .../libraries/bootloader/nrf_bootloader.c | 101 + .../libraries/bootloader/nrf_bootloader.h | 93 + .../nrf_bootloader_app_start.c} | 131 +- .../bootloader/nrf_bootloader_app_start.h | 72 + .../bootloader/nrf_bootloader_info.c | 60 + .../bootloader/nrf_bootloader_info.h | 137 + .../ble_transport/hci_mem_pool_internal.h | 32 - .../libraries/bootloader_dfu/bootloader.c | 387 - .../libraries/bootloader_dfu/bootloader.h | 97 - .../bootloader_dfu/bootloader_settings.c | 36 - .../bootloader_dfu/bootloader_settings.h | 35 - .../bootloader_dfu/bootloader_types.h | 59 - .../bootloader_dfu/bootloader_util.h | 38 - components/libraries/bootloader_dfu/dfu.h | 134 - .../bootloader_dfu/dfu_app_handler.c | 192 - .../bootloader_dfu/dfu_app_handler.h | 86 - .../bootloader_dfu/dfu_bank_internal.h | 87 - .../libraries/bootloader_dfu/dfu_ble_svc.h | 80 - .../bootloader_dfu/dfu_ble_svc_internal.h | 43 - .../libraries/bootloader_dfu/dfu_dual_bank.c | 869 - .../libraries/bootloader_dfu/dfu_init.h | 134 - .../bootloader_dfu/dfu_init_template.c | 155 - .../bootloader_dfu/dfu_single_bank.c | 818 - .../libraries/bootloader_dfu/dfu_transport.h | 40 - .../bootloader_dfu/dfu_transport_ble.c | 1109 -- .../bootloader_dfu/dfu_transport_serial.c | 306 - .../libraries/bootloader_dfu/dfu_types.h | 147 - .../experimental/dfu_init_template_signing.c | 210 - .../bootloader_dfu/experimental/nrf_sec.h | 108 - .../hci_transport/hci_mem_pool_internal.h | 32 - .../hci_transport/hci_transport_config.h | 45 - components/libraries/bsp/bsp.c | 610 + components/libraries/bsp/bsp.h | 316 + components/libraries/bsp/bsp_btn_ant.c | 172 + components/libraries/bsp/bsp_btn_ant.h | 97 + components/libraries/bsp/bsp_btn_ble.c | 265 + components/libraries/bsp/bsp_btn_ble.h | 109 + components/libraries/bsp/bsp_config.h | 136 + components/libraries/bsp/bsp_nfc.c | 73 + components/libraries/bsp/bsp_nfc.h | 108 + components/libraries/button/app_button.c | 90 +- components/libraries/button/app_button.h | 71 +- components/libraries/console/console.c | 504 - components/libraries/console/console.h | 343 - components/libraries/crc16/crc16.c | 68 +- components/libraries/crc16/crc16.h | 76 +- components/libraries/crc32/crc32.c | 61 + components/libraries/crc32/crc32.h | 80 + components/libraries/crypto/nrf_crypto.c | 159 + components/libraries/crypto/nrf_crypto.h | 253 + components/libraries/crypto/nrf_crypto_svc.c | 93 + components/libraries/csense/nrf_csense.c | 658 + components/libraries/csense/nrf_csense.h | 345 + .../libraries/csense/nrf_csense_macros.h | 360 + .../libraries/csense_drv/nrf_drv_csense.c | 537 + .../libraries/csense_drv/nrf_drv_csense.h | 153 + components/libraries/ecc/ecc.c | 207 + components/libraries/ecc/ecc.h | 142 + components/libraries/eddystone/es.h | 199 + components/libraries/eddystone/es_adv.c | 309 + components/libraries/eddystone/es_adv.h | 127 + components/libraries/eddystone/es_adv_frame.c | 107 + components/libraries/eddystone/es_adv_frame.h | 72 + .../libraries/eddystone/es_adv_timing.c | 221 + .../libraries/eddystone/es_adv_timing.h | 98 + .../eddystone/es_adv_timing_resolver.c | 145 + .../eddystone/es_adv_timing_resolver.h | 97 + .../libraries/eddystone/es_battery_voltage.h | 67 + .../eddystone/es_battery_voltage_adc.c | 100 + .../eddystone/es_battery_voltage_saadc.c | 105 + components/libraries/eddystone/es_flash.c | 350 + components/libraries/eddystone/es_flash.h | 178 + components/libraries/eddystone/es_gatts.c | 188 + components/libraries/eddystone/es_gatts.h | 109 + .../libraries/eddystone/es_gatts_read.c | 246 + .../libraries/eddystone/es_gatts_read.h | 73 + .../libraries/eddystone/es_gatts_write.c | 254 + .../libraries/eddystone/es_gatts_write.h | 71 + components/libraries/eddystone/es_security.c | 531 + components/libraries/eddystone/es_security.h | 239 + .../libraries/eddystone/es_security_timing.c | 80 + .../libraries/eddystone/es_security_timing.h | 68 + components/libraries/eddystone/es_slot.c | 441 + components/libraries/eddystone/es_slot.h | 203 + components/libraries/eddystone/es_slot_reg.c | 182 + components/libraries/eddystone/es_slot_reg.h | 91 + components/libraries/eddystone/es_stopwatch.c | 106 + components/libraries/eddystone/es_stopwatch.h | 71 + components/libraries/eddystone/es_tlm.c | 141 + components/libraries/eddystone/es_tlm.h | 76 + components/libraries/eddystone/es_util.h | 137 + components/libraries/eddystone/nrf_ble_es.c | 429 + components/libraries/eddystone/nrf_ble_es.h | 98 + .../experimental_section_vars/section_vars.h | 320 +- components/libraries/fds/fds.c | 2752 +-- components/libraries/fds/fds.h | 961 +- components/libraries/fds/fds_config.h | 45 - components/libraries/fds/fds_internal_defs.h | 345 + components/libraries/fds/fds_types_internal.h | 158 - components/libraries/fifo/app_fifo.c | 169 +- components/libraries/fifo/app_fifo.h | 83 +- components/libraries/fstorage/fstorage.c | 774 +- components/libraries/fstorage/fstorage.h | 340 +- .../libraries/fstorage/fstorage_config.h | 81 - .../fstorage/fstorage_internal_defs.h | 166 + components/libraries/fstorage/fstorage_nosd.c | 39 + components/libraries/gpiote/app_gpiote.c | 174 +- components/libraries/gpiote/app_gpiote.h | 141 +- .../libraries/gpiote/app_gpiote_fast_detect.c | 539 - components/libraries/hardfault/hardfault.h | 96 + .../hardfault/hardfault_implementation.c | 91 + .../nrf51/handler/hardfault_handler_gcc.c | 84 + .../nrf51/handler/hardfault_handler_iar.c | 98 + .../nrf51/handler/hardfault_handler_keil.c | 88 + .../nrf52/handler/hardfault_handler_gcc.c | 81 + .../nrf52/handler/hardfault_handler_iar.c | 97 + .../nrf52/handler/hardfault_handler_keil.c | 87 + .../hci/config/hci_mem_pool_internal.h | 32 - .../hci/config/hci_transport_config.h | 40 - components/libraries/hci/hci_mem_pool.c | 189 +- components/libraries/hci/hci_mem_pool.h | 121 +- components/libraries/hci/hci_slip.c | 69 +- components/libraries/hci/hci_slip.h | 79 +- components/libraries/hci/hci_transport.c | 515 +- components/libraries/hci/hci_transport.h | 169 +- components/libraries/ic_info/nrf51_ic_info.c | 49 - components/libraries/ic_info/nrf_ic_info.c | 95 + components/libraries/ic_info/nrf_ic_info.h | 74 +- .../libraries/led_softblink/led_softblink.c | 103 +- .../libraries/led_softblink/led_softblink.h | 95 +- components/libraries/log/nrf_log.h | 205 + components/libraries/log/nrf_log_backend.h | 91 + components/libraries/log/nrf_log_ctrl.h | 229 + .../log/src/nrf_log_backend_serial.c | 496 + .../libraries/log/src/nrf_log_ctrl_internal.h | 97 + .../libraries/log/src/nrf_log_frontend.c | 826 + .../libraries/log/src/nrf_log_internal.h | 309 + .../libraries/low_power_pwm/low_power_pwm.c | 119 +- .../libraries/low_power_pwm/low_power_pwm.h | 112 +- components/libraries/mailbox/app_mailbox.c | 52 +- components/libraries/mailbox/app_mailbox.h | 59 +- .../libraries/mailbox/app_mailbox_local.h | 83 +- .../libraries/mem_manager/mem_manager.c | 161 +- .../libraries/mem_manager/mem_manager.h | 57 +- components/libraries/pwm/app_pwm.c | 315 +- components/libraries/pwm/app_pwm.h | 71 +- components/libraries/pwr_mgmt/nrf_pwr_mgmt.c | 409 + components/libraries/pwr_mgmt/nrf_pwr_mgmt.h | 146 + components/libraries/queue/nrf_queue.c | 435 + components/libraries/queue/nrf_queue.h | 402 + .../libraries/scheduler/app_scheduler.c | 184 +- .../libraries/scheduler/app_scheduler.h | 87 +- .../scheduler/app_scheduler_serconn.c | 92 +- components/libraries/sdcard/app_sdcard.c | 1175 ++ components/libraries/sdcard/app_sdcard.h | 211 + components/libraries/sensorsim/sensorsim.c | 48 +- components/libraries/sensorsim/sensorsim.h | 59 +- components/libraries/sha256/sha256.c | 113 +- components/libraries/sha256/sha256.h | 63 +- .../libraries/simple_timer/app_simple_timer.c | 115 +- .../libraries/simple_timer/app_simple_timer.h | 77 +- components/libraries/slip/slip.c | 86 +- components/libraries/slip/slip.h | 75 +- components/libraries/svc/nrf_svc_function.h | 88 + components/libraries/svc/nrf_svc_handler.c | 182 + components/libraries/svc/nrf_svci.h | 160 + components/libraries/timer/app_timer.c | 566 +- components/libraries/timer/app_timer.h | 150 +- components/libraries/timer/app_timer_appsh.c | 52 +- components/libraries/timer/app_timer_appsh.h | 59 +- .../libraries/timer/app_timer_ble_gzll.c | 581 +- .../libraries/timer/app_timer_freertos.c | 92 +- components/libraries/timer/app_timer_rtx.c | 113 +- components/libraries/trace/app_trace.c | 83 - components/libraries/trace/app_trace.h | 55 - components/libraries/twi/app_twi.c | 111 +- components/libraries/twi/app_twi.h | 63 +- components/libraries/uart/app_uart.c | 89 +- components/libraries/uart/app_uart.h | 66 +- components/libraries/uart/app_uart_fifo.c | 247 +- components/libraries/uart/retarget.c | 124 +- components/libraries/usbd/app_usbd.c | 898 + components/libraries/usbd/app_usbd.h | 383 + .../libraries/usbd/app_usbd_class_base.h | 838 + components/libraries/usbd/app_usbd_core.c | 1180 ++ components/libraries/usbd/app_usbd_core.h | 276 + .../libraries/usbd/app_usbd_descriptor.h | 334 + components/libraries/usbd/app_usbd_langid.h | 285 + components/libraries/usbd/app_usbd_request.h | 354 + .../libraries/usbd/app_usbd_string_desc.c | 188 + .../libraries/usbd/app_usbd_string_desc.h | 120 + components/libraries/usbd/app_usbd_types.h | 174 + .../usbd/class/audio/app_usbd_audio.c | 612 + .../usbd/class/audio/app_usbd_audio.h | 208 + .../usbd/class/audio/app_usbd_audio_desc.h | 319 + .../class/audio/app_usbd_audio_internal.h | 238 + .../usbd/class/audio/app_usbd_audio_types.h | 383 + .../usbd/class/cdc/acm/app_usbd_cdc_acm.c | 727 + .../usbd/class/cdc/acm/app_usbd_cdc_acm.h | 299 + .../class/cdc/acm/app_usbd_cdc_acm_internal.h | 218 + .../usbd/class/cdc/app_usbd_cdc_desc.h | 208 + .../usbd/class/cdc/app_usbd_cdc_types.h | 360 + .../libraries/usbd/class/hid/app_usbd_hid.c | 509 + .../libraries/usbd/class/hid/app_usbd_hid.h | 446 + .../usbd/class/hid/app_usbd_hid_types.h | 273 + .../class/hid/generic/app_usbd_hid_generic.c | 380 + .../class/hid/generic/app_usbd_hid_generic.h | 231 + .../hid/generic/app_usbd_hid_generic_desc.h | 90 + .../generic/app_usbd_hid_generic_internal.h | 216 + .../usbd/class/hid/kbd/app_usbd_hid_kbd.c | 402 + .../usbd/class/hid/kbd/app_usbd_hid_kbd.h | 300 + .../class/hid/kbd/app_usbd_hid_kbd_desc.h | 129 + .../class/hid/kbd/app_usbd_hid_kbd_internal.h | 197 + .../usbd/class/hid/mouse/app_usbd_hid_mouse.c | 461 + .../usbd/class/hid/mouse/app_usbd_hid_mouse.h | 179 + .../class/hid/mouse/app_usbd_hid_mouse_desc.h | 119 + .../hid/mouse/app_usbd_hid_mouse_internal.h | 186 + .../libraries/usbd/class/msc/app_usbd_msc.c | 2059 +++ .../libraries/usbd/class/msc/app_usbd_msc.h | 187 + .../usbd/class/msc/app_usbd_msc_desc.h | 105 + .../usbd/class/msc/app_usbd_msc_internal.h | 260 + .../usbd/class/msc/app_usbd_msc_scsi.h | 330 + .../usbd/class/msc/app_usbd_msc_types.h | 142 + .../usbd/config/app_usbd_string_config.h | 131 + components/libraries/util/app_error.c | 159 +- components/libraries/util/app_error.h | 212 +- components/libraries/util/app_error_weak.c | 66 + components/libraries/util/app_error_weak.h | 86 + components/libraries/util/app_util.h | 783 +- components/libraries/util/app_util_bds.h | 131 +- components/libraries/util/app_util_platform.c | 93 +- components/libraries/util/app_util_platform.h | 250 +- components/libraries/util/common.h | 38 - components/libraries/util/nordic_common.h | 139 +- components/libraries/util/nrf_assert.c | 66 +- components/libraries/util/nrf_assert.h | 94 +- components/libraries/util/nrf_bitmask.h | 149 + components/libraries/util/nrf_log.c | 380 - components/libraries/util/nrf_log.h | 518 - components/libraries/util/sdk_common.h | 62 +- components/libraries/util/sdk_errors.c | 91 + components/libraries/util/sdk_errors.h | 133 +- components/libraries/util/sdk_macros.h | 192 + components/libraries/util/sdk_mapped_flags.c | 58 +- components/libraries/util/sdk_mapped_flags.h | 59 +- components/libraries/util/sdk_os.h | 59 +- components/libraries/util/sdk_resources.h | 87 +- .../hal_t4t/hal_nfc_t4t.c | 964 + .../hal_t4t/hal_nfc_t4t.h | 193 + .../nfc/experimental_t4t_lib/license.txt | 36 + .../nfc/experimental_t4t_lib/nfc_fixes.h | 76 + .../nfc/experimental_t4t_lib/nfc_t4t_lib.h | 311 + .../experimental_t4t_lib/nfc_t4t_lib_gcc.a | Bin 0 -> 800914 bytes .../experimental_t4t_lib/nfc_t4t_lib_iar.a | Bin 0 -> 43694 bytes .../connection_handover/ac_rec/nfc_ac_rec.c | 160 + .../connection_handover/ac_rec/nfc_ac_rec.h | 196 + .../ble_oob_advdata/nfc_ble_oob_advdata.c | 393 + .../ble_oob_advdata/nfc_ble_oob_advdata.h | 132 + .../ble_pair_msg/nfc_ble_pair_msg.c | 557 + .../ble_pair_msg/nfc_ble_pair_msg.h | 280 + .../common/nfc_ble_pair_common.c | 47 + .../common/nfc_ble_pair_common.h | 43 + .../ep_oob_rec/nfc_ep_oob_rec.c | 238 + .../ep_oob_rec/nfc_ep_oob_rec.h | 87 + .../connection_handover/hs_rec/nfc_hs_rec.c | 103 + .../connection_handover/hs_rec/nfc_hs_rec.h | 162 + .../le_oob_rec/nfc_le_oob_rec.c | 144 + .../le_oob_rec/nfc_le_oob_rec.h | 87 + .../nfc/ndef/generic/message/nfc_ndef_msg.c | 186 + .../nfc/ndef/generic/message/nfc_ndef_msg.h | 189 + .../nfc/ndef/generic/record/nfc_ndef_record.c | 188 + .../nfc/ndef/generic/record/nfc_ndef_record.h | 306 + .../nfc/ndef/launchapp/nfc_launchapp_msg.c | 146 + .../nfc/ndef/launchapp/nfc_launchapp_msg.h | 101 + .../nfc/ndef/launchapp/nfc_launchapp_rec.c | 165 + .../nfc/ndef/launchapp/nfc_launchapp_rec.h | 102 + .../ndef/parser/message/nfc_ndef_msg_parser.c | 94 + .../ndef/parser/message/nfc_ndef_msg_parser.h | 124 + .../message/nfc_ndef_msg_parser_local.c | 164 + .../message/nfc_ndef_msg_parser_local.h | 168 + .../parser/record/nfc_ndef_record_parser.c | 219 + .../parser/record/nfc_ndef_record_parser.h | 101 + components/nfc/ndef/text/nfc_text_rec.c | 105 + components/nfc/ndef/text/nfc_text_rec.h | 163 + components/nfc/ndef/uri/nfc_uri_msg.c | 125 + components/nfc/ndef/uri/nfc_uri_msg.h | 96 + components/nfc/ndef/uri/nfc_uri_rec.c | 115 + components/nfc/ndef/uri/nfc_uri_rec.h | 133 + components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c | 733 + components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h | 190 + components/nfc/t2t_lib/license.txt | 36 + components/nfc/t2t_lib/nfc_fixes.h | 76 + components/nfc/t2t_lib/nfc_t2t_lib.h | 259 + components/nfc/t2t_lib/nfc_t2t_lib_gcc.a | Bin 0 -> 733000 bytes components/nfc/t2t_lib/nfc_t2t_lib_iar.a | Bin 0 -> 29244 bytes components/nfc/t2t_parser/nfc_t2t_parser.c | 679 + components/nfc/t2t_parser/nfc_t2t_parser.h | 196 + components/nfc/t2t_parser/nfc_tlv_block.h | 103 + components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c | 260 + components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h | 222 + .../nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c | 266 + .../nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h | 178 + .../nfc_t4t_hl_detection_procedures.c | 399 + .../nfc_t4t_hl_detection_procedures.h | 185 + .../nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c | 326 + .../nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h | 148 + components/properitary_rf/esb/arm/esb_arm.lib | Bin 80618 -> 0 bytes .../esb/arm/esb_sd_resources_arm.lib | Bin 81270 -> 0 bytes components/properitary_rf/esb/gcc/esb_gcc.a | Bin 50420 -> 0 bytes .../esb/gcc/esb_sd_resources_gcc.a | Bin 50420 -> 0 bytes components/properitary_rf/esb/iar/esb_iar.a | Bin 128574 -> 0 bytes .../esb/iar/esb_sd_resource_iar.a | Bin 129064 -> 0 bytes components/properitary_rf/esb/nrf_esb.h | 714 - .../properitary_rf/esb/nrf_esb_constants.h | 141 - .../properitary_rf/esb/nrf_esb_resources.h | 30 - .../properitary_rf/gzll/arm/gzll_arm.lib | Bin 145794 -> 0 bytes .../gzll/arm/gzll_sd_resources_arm.lib | Bin 146558 -> 0 bytes .../gzll/config/nrf_gzp_config.h | 124 - .../gzll/gcc/gzll_sd_resources_gcc.a | Bin 53732 -> 0 bytes .../properitary_rf/gzll/nrf_gzll_resources.h | 30 - .../properitary_rf/gzll/nrf_gzp_host_nrf51.c | 49 - components/proprietary_rf/esb/nrf_esb.c | 1299 ++ components/proprietary_rf/esb/nrf_esb.h | 526 + .../proprietary_rf/esb/nrf_esb_error_codes.h | 56 + .../proprietary_rf/esb/nrf_esb_resources.h | 73 + .../proprietary_rf/gzll/arm/license.txt | 37 + .../gzll/config/nrf_gzp_config.h | 166 + .../gzll/gcc/gzll_nrf51_gcc.a} | Bin .../gzll/gcc/gzll_nrf51_sd_resources_gcc.a | Bin 0 -> 53688 bytes .../proprietary_rf/gzll/gcc/gzll_nrf52_gcc.a | Bin 0 -> 53628 bytes .../gzll/gcc/gzll_nrf52_sd_resources_gcc.a | Bin 0 -> 53644 bytes .../proprietary_rf/gzll/gcc/license.txt | 37 + .../gzll/iar/gzll_nrf51_iar.a} | Bin .../gzll/iar/gzll_nrf51_sd_resource_iar.a} | Bin .../proprietary_rf/gzll/iar/gzll_nrf52_iar.a | Bin 0 -> 131304 bytes .../gzll/iar/gzll_nrf52_sd_resource_iar.a | Bin 0 -> 131516 bytes .../proprietary_rf/gzll/iar/license.txt | 37 + .../gzll/nrf_gzll.h | 264 +- .../gzll/nrf_gzll_constants.h | 94 +- .../proprietary_rf/gzll/nrf_gzll_error.h | 69 + .../proprietary_rf/gzll/nrf_gzll_resources.h | 67 + .../gzll/nrf_gzp.c | 127 +- .../gzll/nrf_gzp.h | 210 +- .../gzll/nrf_gzp_device.c | 257 +- .../gzll/nrf_gzp_host.c | 276 +- .../proprietary_rf/gzll/nrf_gzp_host_nrf5x.c | 76 + components/sdk_validation.h | 306 + .../application/codecs/common/ble_dtm_app.c | 54 +- .../application/codecs/common/ble_dtm_app.h | 82 +- .../application/codecs/common/ble_dtm_init.c | 50 +- .../codecs/common/conn_systemreset.c | 50 +- .../codecs/common/conn_systemreset.h | 61 +- .../codecs/s110/middleware/app_mw_ble.c | 501 - .../codecs/s110/middleware/app_mw_ble_gap.c | 1286 -- .../codecs/s110/middleware/app_mw_ble_gattc.c | 426 - .../codecs/s110/middleware/app_mw_ble_l2cap.c | 165 - .../codecs/s110/middleware/app_mw_nrf_soc.c | 100 - .../s110/serializers/app_ble_gap_sec_keys.c | 74 - .../s110/serializers/app_ble_gap_sec_keys.h | 79 - .../s110/serializers/app_ble_user_mem.c | 74 - .../s110/serializers/app_ble_user_mem.h | 81 - .../codecs/s110/serializers/ble_app.h | 445 - .../codecs/s110/serializers/ble_enable.c | 50 - .../codecs/s110/serializers/ble_event.c | 238 - .../codecs/s110/serializers/ble_evt_app.h | 110 - .../s110/serializers/ble_evt_tx_complete.c | 49 - .../serializers/ble_evt_user_mem_release.c | 78 - .../serializers/ble_evt_user_mem_request.c | 52 - .../s110/serializers/ble_gap_address_get.c | 75 - .../s110/serializers/ble_gap_address_set.c | 56 - .../s110/serializers/ble_gap_adv_data_set.c | 52 - .../s110/serializers/ble_gap_adv_start.c | 72 - .../s110/serializers/ble_gap_adv_stop.c | 40 - .../codecs/s110/serializers/ble_gap_app.h | 1158 -- .../s110/serializers/ble_gap_appearance_get.c | 70 - .../s110/serializers/ble_gap_appearance_set.c | 44 - .../s110/serializers/ble_gap_auth_key_reply.c | 76 - .../s110/serializers/ble_gap_authenticate.c | 52 - .../serializers/ble_gap_conn_param_update.c | 55 - .../s110/serializers/ble_gap_conn_sec_get.c | 74 - .../codecs/s110/serializers/ble_gap_connect.c | 54 - .../s110/serializers/ble_gap_connect_cancel.c | 42 - .../serializers/ble_gap_device_name_get.c | 84 - .../serializers/ble_gap_device_name_set.c | 66 - .../s110/serializers/ble_gap_disconnect.c | 45 - .../codecs/s110/serializers/ble_gap_encrypt.c | 68 - .../s110/serializers/ble_gap_evt_adv_report.c | 72 - .../codecs/s110/serializers/ble_gap_evt_app.h | 411 - .../ble_gap_evt_auth_key_request.c | 53 - .../serializers/ble_gap_evt_auth_status.c | 69 - .../ble_gap_evt_conn_param_update.c | 59 - .../ble_gap_evt_conn_param_update_request.c | 59 - .../serializers/ble_gap_evt_conn_sec_update.c | 57 - .../s110/serializers/ble_gap_evt_connected.c | 53 - .../serializers/ble_gap_evt_disconnected.c | 48 - .../serializers/ble_gap_evt_passkey_display.c | 57 - .../serializers/ble_gap_evt_rssi_changed.c | 53 - .../serializers/ble_gap_evt_scan_req_report.c | 58 - .../ble_gap_evt_sec_info_request.c | 55 - .../ble_gap_evt_sec_params_request.c | 56 - .../serializers/ble_gap_evt_sec_request.c | 59 - .../s110/serializers/ble_gap_evt_timeout.c | 52 - .../s110/serializers/ble_gap_ppcp_get.c | 68 - .../s110/serializers/ble_gap_ppcp_set.c | 54 - .../s110/serializers/ble_gap_rssi_get.c | 80 - .../s110/serializers/ble_gap_rssi_start.c | 53 - .../s110/serializers/ble_gap_rssi_stop.c | 45 - .../s110/serializers/ble_gap_scan_start.c | 45 - .../s110/serializers/ble_gap_scan_stop.c | 40 - .../s110/serializers/ble_gap_sec_info_reply.c | 78 - .../serializers/ble_gap_sec_params_reply.c | 87 - .../s110/serializers/ble_gap_tx_power_set.c | 45 - .../codecs/s110/serializers/ble_gattc_app.h | 406 - .../ble_gattc_char_value_by_uuid_read.c | 61 - .../serializers/ble_gattc_char_values_read.c | 48 - .../ble_gattc_characteristics_discover.c | 57 - .../ble_gattc_descriptors_discover.c | 53 - .../s110/serializers/ble_gattc_evt_app.h | 286 - .../serializers/ble_gattc_evt_char_disc_rsp.c | 103 - .../ble_gattc_evt_char_val_by_uuid_read_rsp.c | 78 - .../ble_gattc_evt_char_vals_read_rsp.c | 66 - .../serializers/ble_gattc_evt_desc_disc_rsp.c | 95 - .../s110/serializers/ble_gattc_evt_hvx.c | 66 - .../ble_gattc_evt_prim_srvc_disc_rsp.c | 78 - .../s110/serializers/ble_gattc_evt_read_rsp.c | 66 - .../serializers/ble_gattc_evt_rel_disc_rsp.c | 65 - .../s110/serializers/ble_gattc_evt_timeout.c | 75 - .../serializers/ble_gattc_evt_write_rsp.c | 66 - .../s110/serializers/ble_gattc_hv_confirm.c | 49 - .../ble_gattc_primary_services_discover.c | 59 - .../codecs/s110/serializers/ble_gattc_read.c | 47 - .../ble_gattc_relationships_discover.c | 57 - .../codecs/s110/serializers/ble_gattc_write.c | 68 - .../codecs/s110/serializers/ble_gatts_app.h | 554 - .../ble_gatts_characteristic_add.c | 89 - .../serializers/ble_gatts_descriptor_add.c | 91 - .../s110/serializers/ble_gatts_evt_app.h | 186 - .../s110/serializers/ble_gatts_evt_hvc.c | 51 - .../ble_gatts_evt_rw_authorize_request.c | 78 - .../serializers/ble_gatts_evt_sc_confirm.c | 49 - .../ble_gatts_evt_sys_attr_missing.c | 51 - .../s110/serializers/ble_gatts_evt_timeout.c | 50 - .../s110/serializers/ble_gatts_evt_write.c | 78 - .../codecs/s110/serializers/ble_gatts_hvx.c | 115 - .../s110/serializers/ble_gatts_include_add.c | 74 - .../ble_gatts_rw_authorize_reply.c | 57 - .../s110/serializers/ble_gatts_service_add.c | 83 - .../serializers/ble_gatts_service_changed.c | 55 - .../s110/serializers/ble_gatts_sys_attr_get.c | 113 - .../s110/serializers/ble_gatts_sys_attr_set.c | 65 - .../s110/serializers/ble_gatts_value_get.c | 126 - .../s110/serializers/ble_gatts_value_set.c | 84 - .../codecs/s110/serializers/ble_l2cap_app.h | 163 - .../s110/serializers/ble_l2cap_cid_register.c | 45 - .../serializers/ble_l2cap_cid_unregister.c | 45 - .../s110/serializers/ble_l2cap_evt_app.h | 61 - .../s110/serializers/ble_l2cap_evt_rx.c | 56 - .../codecs/s110/serializers/ble_l2cap_tx.c | 61 - .../codecs/s110/serializers/ble_opt_get.c | 126 - .../codecs/s110/serializers/ble_opt_set.c | 117 - .../serializers/ble_tx_buffer_count_get.c | 68 - .../s110/serializers/ble_user_mem_reply.c | 66 - .../codecs/s110/serializers/ble_uuid_decode.c | 84 - .../codecs/s110/serializers/ble_uuid_encode.c | 93 - .../codecs/s110/serializers/ble_uuid_vs_add.c | 83 - .../codecs/s110/serializers/ble_version_get.c | 73 - .../codecs/s110/serializers/nrf_soc_app.h | 90 - .../s110/serializers/power_system_off.c | 32 - .../codecs/s110/serializers/temp_get.c | 71 - .../codecs/s120/middleware/app_mw_ble.c | 501 - .../codecs/s120/middleware/app_mw_ble_gap.c | 1285 -- .../codecs/s120/middleware/app_mw_ble_gattc.c | 426 - .../codecs/s120/middleware/app_mw_ble_gatts.c | 571 - .../codecs/s120/middleware/app_mw_ble_l2cap.c | 165 - .../codecs/s120/middleware/app_mw_nrf_soc.c | 100 - .../s120/serializers/app_ble_gap_sec_keys.c | 73 - .../s120/serializers/app_ble_gap_sec_keys.h | 81 - .../s120/serializers/app_ble_user_mem.c | 74 - .../s120/serializers/app_ble_user_mem.h | 81 - .../codecs/s120/serializers/ble_app.h | 445 - .../codecs/s120/serializers/ble_enable.c | 50 - .../codecs/s120/serializers/ble_event.c | 241 - .../codecs/s120/serializers/ble_evt_app.h | 111 - .../s120/serializers/ble_evt_tx_complete.c | 49 - .../serializers/ble_evt_user_mem_release.c | 79 - .../serializers/ble_evt_user_mem_request.c | 53 - .../s120/serializers/ble_gap_address_get.c | 75 - .../s120/serializers/ble_gap_address_set.c | 60 - .../s120/serializers/ble_gap_adv_data_set.c | 52 - .../s120/serializers/ble_gap_adv_start.c | 72 - .../s120/serializers/ble_gap_adv_stop.c | 40 - .../codecs/s120/serializers/ble_gap_app.h | 1159 -- .../s120/serializers/ble_gap_appearance_get.c | 70 - .../s120/serializers/ble_gap_appearance_set.c | 44 - .../s120/serializers/ble_gap_auth_key_reply.c | 76 - .../s120/serializers/ble_gap_authenticate.c | 52 - .../serializers/ble_gap_conn_param_update.c | 55 - .../s120/serializers/ble_gap_conn_sec_get.c | 74 - .../codecs/s120/serializers/ble_gap_connect.c | 54 - .../s120/serializers/ble_gap_connect_cancel.c | 42 - .../serializers/ble_gap_device_name_get.c | 84 - .../serializers/ble_gap_device_name_set.c | 66 - .../s120/serializers/ble_gap_disconnect.c | 45 - .../codecs/s120/serializers/ble_gap_encrypt.c | 68 - .../s120/serializers/ble_gap_evt_adv_report.c | 72 - .../codecs/s120/serializers/ble_gap_evt_app.h | 409 - .../ble_gap_evt_auth_key_request.c | 53 - .../serializers/ble_gap_evt_auth_status.c | 69 - .../ble_gap_evt_conn_param_update.c | 59 - .../ble_gap_evt_conn_param_update_request.c | 59 - .../serializers/ble_gap_evt_conn_sec_update.c | 57 - .../s120/serializers/ble_gap_evt_connected.c | 53 - .../serializers/ble_gap_evt_disconnected.c | 48 - .../serializers/ble_gap_evt_passkey_display.c | 57 - .../serializers/ble_gap_evt_rssi_changed.c | 53 - .../serializers/ble_gap_evt_scan_req_report.c | 58 - .../ble_gap_evt_sec_info_request.c | 55 - .../ble_gap_evt_sec_params_request.c | 55 - .../serializers/ble_gap_evt_sec_request.c | 59 - .../s120/serializers/ble_gap_evt_timeout.c | 52 - .../s120/serializers/ble_gap_ppcp_get.c | 68 - .../s120/serializers/ble_gap_ppcp_set.c | 54 - .../s120/serializers/ble_gap_rssi_get.c | 80 - .../s120/serializers/ble_gap_rssi_start.c | 53 - .../s120/serializers/ble_gap_rssi_stop.c | 45 - .../s120/serializers/ble_gap_scan_start.c | 45 - .../s120/serializers/ble_gap_scan_stop.c | 40 - .../s120/serializers/ble_gap_sec_info_reply.c | 78 - .../serializers/ble_gap_sec_params_reply.c | 87 - .../s120/serializers/ble_gap_tx_power_set.c | 45 - .../codecs/s120/serializers/ble_gattc_app.h | 406 - .../ble_gattc_char_value_by_uuid_read.c | 61 - .../serializers/ble_gattc_char_values_read.c | 48 - .../ble_gattc_characteristics_discover.c | 57 - .../ble_gattc_descriptors_discover.c | 53 - .../s120/serializers/ble_gattc_evt_app.h | 286 - .../serializers/ble_gattc_evt_char_disc_rsp.c | 103 - .../ble_gattc_evt_char_val_by_uuid_read_rsp.c | 78 - .../ble_gattc_evt_char_vals_read_rsp.c | 66 - .../serializers/ble_gattc_evt_desc_disc_rsp.c | 95 - .../s120/serializers/ble_gattc_evt_hvx.c | 66 - .../ble_gattc_evt_prim_srvc_disc_rsp.c | 78 - .../s120/serializers/ble_gattc_evt_read_rsp.c | 66 - .../serializers/ble_gattc_evt_rel_disc_rsp.c | 65 - .../s120/serializers/ble_gattc_evt_timeout.c | 75 - .../serializers/ble_gattc_evt_write_rsp.c | 66 - .../s120/serializers/ble_gattc_hv_confirm.c | 49 - .../ble_gattc_primary_services_discover.c | 59 - .../codecs/s120/serializers/ble_gattc_read.c | 47 - .../ble_gattc_relationships_discover.c | 57 - .../codecs/s120/serializers/ble_gattc_write.c | 68 - .../codecs/s120/serializers/ble_gatts_app.h | 554 - .../ble_gatts_characteristic_add.c | 89 - .../serializers/ble_gatts_descriptor_add.c | 91 - .../s120/serializers/ble_gatts_evt_app.h | 186 - .../s120/serializers/ble_gatts_evt_hvc.c | 51 - .../ble_gatts_evt_rw_authorize_request.c | 78 - .../serializers/ble_gatts_evt_sc_confirm.c | 49 - .../ble_gatts_evt_sys_attr_missing.c | 51 - .../s120/serializers/ble_gatts_evt_timeout.c | 50 - .../s120/serializers/ble_gatts_evt_write.c | 78 - .../codecs/s120/serializers/ble_gatts_hvx.c | 115 - .../s120/serializers/ble_gatts_include_add.c | 74 - .../ble_gatts_rw_authorize_reply.c | 57 - .../s120/serializers/ble_gatts_service_add.c | 83 - .../serializers/ble_gatts_service_changed.c | 55 - .../s120/serializers/ble_gatts_sys_attr_get.c | 113 - .../s120/serializers/ble_gatts_sys_attr_set.c | 65 - .../s120/serializers/ble_gatts_value_get.c | 126 - .../s120/serializers/ble_gatts_value_set.c | 84 - .../codecs/s120/serializers/ble_l2cap_app.h | 163 - .../s120/serializers/ble_l2cap_cid_register.c | 45 - .../serializers/ble_l2cap_cid_unregister.c | 45 - .../s120/serializers/ble_l2cap_evt_app.h | 61 - .../s120/serializers/ble_l2cap_evt_rx.c | 56 - .../codecs/s120/serializers/ble_l2cap_tx.c | 61 - .../codecs/s120/serializers/ble_opt_get.c | 126 - .../codecs/s120/serializers/ble_opt_set.c | 117 - .../serializers/ble_tx_buffer_count_get.c | 68 - .../s120/serializers/ble_user_mem_reply.c | 65 - .../codecs/s120/serializers/ble_uuid_decode.c | 84 - .../codecs/s120/serializers/ble_uuid_encode.c | 93 - .../codecs/s120/serializers/ble_uuid_vs_add.c | 83 - .../codecs/s120/serializers/ble_version_get.c | 73 - .../codecs/s120/serializers/nrf_soc_app.h | 90 - .../s120/serializers/power_system_off.c | 32 - .../codecs/s120/serializers/temp_get.c | 71 - .../codecs/s130/middleware/app_mw_ble_gatts.c | 571 - .../codecs/s130/middleware/app_mw_nrf_soc.c | 100 - .../s130/serializers/app_ble_gap_sec_keys.c | 73 - .../s130/serializers/app_ble_gap_sec_keys.h | 81 - .../s130/serializers/app_ble_user_mem.c | 74 - .../s130/serializers/app_ble_user_mem.h | 81 - .../codecs/s130/serializers/ble_enable.c | 50 - .../codecs/s130/serializers/ble_event.c | 241 - .../codecs/s130/serializers/ble_evt_app.h | 111 - .../s130/serializers/ble_evt_tx_complete.c | 49 - .../serializers/ble_evt_user_mem_release.c | 79 - .../serializers/ble_evt_user_mem_request.c | 53 - .../s130/serializers/ble_gap_address_get.c | 75 - .../s130/serializers/ble_gap_address_set.c | 60 - .../s130/serializers/ble_gap_adv_data_set.c | 52 - .../s130/serializers/ble_gap_adv_start.c | 72 - .../s130/serializers/ble_gap_adv_stop.c | 40 - .../s130/serializers/ble_gap_appearance_get.c | 70 - .../s130/serializers/ble_gap_appearance_set.c | 44 - .../s130/serializers/ble_gap_auth_key_reply.c | 76 - .../s130/serializers/ble_gap_authenticate.c | 52 - .../serializers/ble_gap_conn_param_update.c | 55 - .../s130/serializers/ble_gap_conn_sec_get.c | 74 - .../codecs/s130/serializers/ble_gap_connect.c | 54 - .../s130/serializers/ble_gap_connect_cancel.c | 42 - .../serializers/ble_gap_device_name_get.c | 84 - .../serializers/ble_gap_device_name_set.c | 66 - .../s130/serializers/ble_gap_disconnect.c | 45 - .../codecs/s130/serializers/ble_gap_encrypt.c | 68 - .../s130/serializers/ble_gap_evt_adv_report.c | 72 - .../ble_gap_evt_auth_key_request.c | 53 - .../serializers/ble_gap_evt_auth_status.c | 69 - .../ble_gap_evt_conn_param_update.c | 59 - .../ble_gap_evt_conn_param_update_request.c | 59 - .../serializers/ble_gap_evt_conn_sec_update.c | 57 - .../s130/serializers/ble_gap_evt_connected.c | 53 - .../serializers/ble_gap_evt_disconnected.c | 48 - .../serializers/ble_gap_evt_passkey_display.c | 57 - .../serializers/ble_gap_evt_rssi_changed.c | 53 - .../serializers/ble_gap_evt_scan_req_report.c | 58 - .../ble_gap_evt_sec_info_request.c | 55 - .../ble_gap_evt_sec_params_request.c | 55 - .../serializers/ble_gap_evt_sec_request.c | 59 - .../s130/serializers/ble_gap_evt_timeout.c | 52 - .../s130/serializers/ble_gap_ppcp_get.c | 68 - .../s130/serializers/ble_gap_ppcp_set.c | 54 - .../s130/serializers/ble_gap_rssi_get.c | 80 - .../s130/serializers/ble_gap_rssi_start.c | 53 - .../s130/serializers/ble_gap_rssi_stop.c | 45 - .../s130/serializers/ble_gap_scan_start.c | 45 - .../s130/serializers/ble_gap_scan_stop.c | 40 - .../s130/serializers/ble_gap_sec_info_reply.c | 78 - .../serializers/ble_gap_sec_params_reply.c | 87 - .../s130/serializers/ble_gap_tx_power_set.c | 45 - .../ble_gattc_char_value_by_uuid_read.c | 61 - .../serializers/ble_gattc_char_values_read.c | 48 - .../ble_gattc_characteristics_discover.c | 57 - .../ble_gattc_descriptors_discover.c | 53 - .../serializers/ble_gattc_evt_char_disc_rsp.c | 103 - .../ble_gattc_evt_char_val_by_uuid_read_rsp.c | 78 - .../ble_gattc_evt_char_vals_read_rsp.c | 66 - .../serializers/ble_gattc_evt_desc_disc_rsp.c | 95 - .../s130/serializers/ble_gattc_evt_hvx.c | 66 - .../ble_gattc_evt_prim_srvc_disc_rsp.c | 78 - .../s130/serializers/ble_gattc_evt_read_rsp.c | 66 - .../serializers/ble_gattc_evt_rel_disc_rsp.c | 65 - .../s130/serializers/ble_gattc_evt_timeout.c | 75 - .../serializers/ble_gattc_evt_write_rsp.c | 66 - .../s130/serializers/ble_gattc_hv_confirm.c | 49 - .../ble_gattc_primary_services_discover.c | 59 - .../codecs/s130/serializers/ble_gattc_read.c | 47 - .../ble_gattc_relationships_discover.c | 57 - .../codecs/s130/serializers/ble_gattc_write.c | 68 - .../ble_gatts_characteristic_add.c | 89 - .../serializers/ble_gatts_descriptor_add.c | 91 - .../s130/serializers/ble_gatts_evt_hvc.c | 51 - .../ble_gatts_evt_rw_authorize_request.c | 78 - .../serializers/ble_gatts_evt_sc_confirm.c | 49 - .../ble_gatts_evt_sys_attr_missing.c | 51 - .../s130/serializers/ble_gatts_evt_timeout.c | 50 - .../s130/serializers/ble_gatts_evt_write.c | 78 - .../codecs/s130/serializers/ble_gatts_hvx.c | 115 - .../s130/serializers/ble_gatts_include_add.c | 74 - .../ble_gatts_rw_authorize_reply.c | 57 - .../s130/serializers/ble_gatts_service_add.c | 83 - .../serializers/ble_gatts_service_changed.c | 55 - .../s130/serializers/ble_gatts_sys_attr_get.c | 113 - .../s130/serializers/ble_gatts_sys_attr_set.c | 65 - .../s130/serializers/ble_gatts_value_get.c | 126 - .../s130/serializers/ble_gatts_value_set.c | 84 - .../s130/serializers/ble_l2cap_cid_register.c | 45 - .../serializers/ble_l2cap_cid_unregister.c | 45 - .../s130/serializers/ble_l2cap_evt_app.h | 61 - .../s130/serializers/ble_l2cap_evt_rx.c | 56 - .../codecs/s130/serializers/ble_l2cap_tx.c | 61 - .../codecs/s130/serializers/ble_opt_get.c | 126 - .../codecs/s130/serializers/ble_opt_set.c | 117 - .../serializers/ble_tx_buffer_count_get.c | 68 - .../s130/serializers/ble_user_mem_reply.c | 65 - .../codecs/s130/serializers/ble_uuid_decode.c | 84 - .../codecs/s130/serializers/ble_uuid_encode.c | 93 - .../codecs/s130/serializers/ble_uuid_vs_add.c | 83 - .../codecs/s130/serializers/ble_version_get.c | 73 - .../codecs/s130/serializers/nrf_soc_app.h | 90 - .../s130/serializers/power_system_off.c | 32 - .../codecs/s130/serializers/temp_get.c | 71 - .../{s130 => s132}/middleware/app_mw_ble.c | 127 +- .../middleware/app_mw_ble_gap.c | 738 +- .../middleware/app_mw_ble_gattc.c | 180 +- .../middleware/app_mw_ble_gatts.c | 263 +- .../middleware/app_mw_ble_l2cap.c | 66 +- .../codecs/s132/middleware/app_mw_nrf_soc.c | 172 + .../s132/serializers/app_ble_gap_sec_keys.c | 101 + .../s132/serializers/app_ble_gap_sec_keys.h | 120 + .../s132/serializers/app_ble_user_mem.c | 102 + .../s132/serializers/app_ble_user_mem.h | 119 + .../codecs/s132/serializers/ble_app.c | 411 + .../{s130 => s132}/serializers/ble_app.h | 296 +- .../codecs/s132/serializers/ble_event.c | 255 + .../codecs/s132/serializers/ble_evt_app.c | 128 + .../codecs/s132/serializers/ble_evt_app.h | 166 + .../codecs/s132/serializers/ble_gap_app.c | 852 + .../{s130 => s132}/serializers/ble_gap_app.h | 809 +- .../codecs/s132/serializers/ble_gap_evt_app.c | 312 + .../serializers/ble_gap_evt_app.h | 135 +- .../codecs/s132/serializers/ble_gattc_app.c | 287 + .../serializers/ble_gattc_app.h | 222 +- .../s132/serializers/ble_gattc_evt_app.c | 247 + .../serializers/ble_gattc_evt_app.h | 126 +- .../codecs/s132/serializers/ble_gatts_app.c | 440 + .../serializers/ble_gatts_app.h | 258 +- .../s132/serializers/ble_gatts_evt_app.c | 176 + .../serializers/ble_gatts_evt_app.h | 95 +- .../codecs/s132/serializers/ble_l2cap_app.c | 146 + .../serializers/ble_l2cap_app.h | 89 +- .../s132/serializers/ble_l2cap_evt_app.c | 57 + .../s132/serializers/ble_l2cap_evt_app.h | 97 + .../codecs/s132/serializers/nrf_soc_app.c | 96 + .../codecs/s132/serializers/nrf_soc_app.h | 158 + .../application/hal/arm_startup_nrf51.s | 16 +- .../application/hal/ser_app_hal.h | 95 +- .../application/hal/ser_app_hal_nrf51.c | 91 - .../application/hal/ser_app_hal_nrf5x.c | 161 + .../hal/ser_app_power_system_off.c | 52 +- .../hal/ser_app_power_system_off.h | 57 +- .../application/transport/ser_sd_transport.c | 67 +- .../application/transport/ser_sd_transport.h | 116 +- .../transport/ser_softdevice_handler.c | 114 +- .../transport/ser_softdevice_handler.h | 59 +- .../serialization/common/ble_serialization.c | 51 +- .../serialization/common/ble_serialization.h | 826 +- .../common/cond_field_serialization.c | 47 +- .../common/cond_field_serialization.h | 98 +- components/serialization/common/ser_config.h | 78 +- .../serialization/common/ser_dbg_sd_str.c | 268 + .../serialization/common/ser_dbg_sd_str.h | 45 + .../s110/ble_gap_struct_serialization.c | 1365 -- .../s110/ble_gap_struct_serialization.h | 352 - .../s110/ble_gattc_struct_serialization.c | 363 - .../s110/ble_gattc_struct_serialization.h | 88 - .../s110/ble_gatts_struct_serialization.c | 926 - .../s110/ble_gatts_struct_serialization.h | 160 - .../s110/ble_struct_serialization.c | 271 - .../s110/ble_struct_serialization.h | 75 - .../s120/ble_gap_struct_serialization.c | 1354 -- .../s120/ble_gap_struct_serialization.h | 353 - .../s120/ble_gattc_struct_serialization.c | 363 - .../s120/ble_gattc_struct_serialization.h | 88 - .../s120/ble_gatts_struct_serialization.c | 959 - .../s120/ble_gatts_struct_serialization.h | 170 - .../s120/ble_struct_serialization.c | 276 - .../s120/ble_struct_serialization.h | 75 - .../s130/ble_gap_struct_serialization.c | 1363 -- .../s130/ble_gattc_struct_serialization.c | 363 - .../s130/ble_gattc_struct_serialization.h | 88 - .../s130/ble_gatts_struct_serialization.c | 965 - .../s130/ble_gatts_struct_serialization.h | 170 - .../s130/ble_struct_serialization.c | 270 - .../s130/ble_struct_serialization.h | 75 - .../s132/ble_gap_struct_serialization.c | 1202 ++ .../ble_gap_struct_serialization.h | 389 +- .../s132/ble_gatt_struct_serialization.c | 136 + .../s132/ble_gatt_struct_serialization.h | 84 + .../s132/ble_gattc_struct_serialization.c | 694 + .../s132/ble_gattc_struct_serialization.h | 284 + .../s132/ble_gatts_struct_serialization.c | 615 + .../s132/ble_gatts_struct_serialization.h | 226 + .../s132/ble_struct_serialization.c | 494 + .../s132/ble_struct_serialization.h | 216 + .../s132/nrf_soc_struct_serialization.c | 91 + .../s132/nrf_soc_struct_serialization.h | 74 + .../debug/debug_hci_config_nrf6310.h | 44 - .../transport/debug/debug_hci_nrf6310.c | 228 - .../common/transport/dtm_uart_params.h | 59 +- .../common/transport/ser_hal_transport.c | 48 +- .../common/transport/ser_hal_transport.h | 152 +- .../ser_phy/config/ser_config_5W_app.h | 57 +- ...onfig_app_nrf51.h => ser_phy_config_app.h} | 59 +- .../ser_phy/config/ser_phy_config_conn.h | 79 + .../config/ser_phy_config_conn_nrf51.h | 42 - .../ser_phy/config/ser_phy_debug_app.h | 61 +- .../ser_phy/config/ser_phy_debug_conn.h | 59 +- .../common/transport/ser_phy/ser_phy.c | 48 +- .../common/transport/ser_phy/ser_phy.h | 191 +- .../common/transport/ser_phy/ser_phy_hci.c | 120 +- .../common/transport/ser_phy/ser_phy_hci.h | 101 +- .../transport/ser_phy/ser_phy_hci_slip.c | 67 +- .../common/transport/ser_phy/ser_phy_nohci.c | 49 +- .../ser_phy/ser_phy_nrf51_uart_stm_app.c | 754 - .../ser_phy/ser_phy_nrf51_uart_stm_conn.c | 784 - ...pi_5W_master.c => ser_phy_spi_5W_master.c} | 139 +- ..._spi_5W_slave.c => ser_phy_spi_5W_slave.c} | 70 +- ...f51_nrf_drv_spi.c => ser_phy_spi_master.c} | 106 +- ..._nrf51_spi_slave.c => ser_phy_spi_slave.c} | 58 +- .../{ser_phy_nrf51_uart.c => ser_phy_uart.c} | 93 +- .../common/transport/ser_phy/spi_5W_master.c | 603 - .../common/transport/ser_phy/spi_5W_master.h | 170 - .../common/transport/ser_phy_debug_comm.h | 61 +- .../connectivity/codecs/common/ble_dtm_conn.h | 67 +- .../connectivity/codecs/common/ble_dtm_init.c | 48 +- .../connectivity/codecs/common/conn_mw.c | 48 +- .../connectivity/codecs/common/conn_mw.h | 59 +- .../codecs/s110/middleware/conn_mw_ble.h | 178 - .../codecs/s110/middleware/conn_mw_ble_gap.c | 831 - .../codecs/s110/middleware/conn_mw_ble_gap.h | 504 - .../s110/middleware/conn_mw_ble_gattc.c | 293 - .../s110/middleware/conn_mw_ble_gattc.h | 180 - .../s110/middleware/conn_mw_ble_l2cap.c | 91 - .../s110/middleware/conn_mw_ble_l2cap.h | 72 - .../codecs/s110/middleware/conn_mw_items.c | 76 - .../codecs/s110/middleware/conn_mw_nrf_soc.c | 60 - .../codecs/s110/middleware/conn_mw_nrf_soc.h | 55 - .../codecs/s110/serializers/ble_conn.h | 447 - .../codecs/s110/serializers/ble_enable.c | 46 - .../codecs/s110/serializers/ble_event.c | 186 - .../codecs/s110/serializers/ble_evt_conn.h | 96 - .../s110/serializers/ble_evt_tx_complete.c | 38 - .../serializers/ble_evt_user_mem_release.c | 56 - .../serializers/ble_evt_user_mem_request.c | 46 - .../s110/serializers/ble_gap_address_get.c | 79 - .../s110/serializers/ble_gap_address_set.c | 49 - .../s110/serializers/ble_gap_adv_data_set.c | 49 - .../s110/serializers/ble_gap_adv_start.c | 88 - .../s110/serializers/ble_gap_adv_stop.c | 23 - .../s110/serializers/ble_gap_appearance_get.c | 76 - .../s110/serializers/ble_gap_appearance_set.c | 42 - .../s110/serializers/ble_gap_auth_key_reply.c | 68 - .../s110/serializers/ble_gap_authenticate.c | 57 - .../codecs/s110/serializers/ble_gap_conn.h | 1044 -- .../serializers/ble_gap_conn_param_update.c | 71 - .../s110/serializers/ble_gap_conn_sec_get.c | 75 - .../codecs/s110/serializers/ble_gap_connect.c | 55 - .../s110/serializers/ble_gap_connect_cancel.c | 25 - .../serializers/ble_gap_device_name_get.c | 92 - .../serializers/ble_gap_device_name_set.c | 61 - .../s110/serializers/ble_gap_disconnect.c | 52 - .../codecs/s110/serializers/ble_gap_encrypt.c | 60 - .../s110/serializers/ble_gap_evt_adv_report.c | 61 - .../ble_gap_evt_auth_key_request.c | 49 - .../serializers/ble_gap_evt_auth_status.c | 62 - .../s110/serializers/ble_gap_evt_conn.h | 336 - .../ble_gap_evt_conn_param_update.c | 49 - .../ble_gap_evt_conn_param_update_request.c | 49 - .../serializers/ble_gap_evt_conn_sec_update.c | 51 - .../s110/serializers/ble_gap_evt_connected.c | 49 - .../serializers/ble_gap_evt_disconnected.c | 49 - .../serializers/ble_gap_evt_passkey_display.c | 43 - .../serializers/ble_gap_evt_rssi_changed.c | 38 - .../serializers/ble_gap_evt_scan_req_report.c | 49 - .../ble_gap_evt_sec_info_request.c | 51 - .../ble_gap_evt_sec_params_request.c | 51 - .../serializers/ble_gap_evt_sec_request.c | 49 - .../s110/serializers/ble_gap_evt_timeout.c | 38 - .../s110/serializers/ble_gap_ppcp_get.c | 80 - .../s110/serializers/ble_gap_ppcp_set.c | 64 - .../s110/serializers/ble_gap_rssi_get.c | 77 - .../s110/serializers/ble_gap_rssi_start.c | 49 - .../s110/serializers/ble_gap_rssi_stop.c | 39 - .../s110/serializers/ble_gap_scan_start.c | 44 - .../s110/serializers/ble_gap_scan_stop.c | 23 - .../s110/serializers/ble_gap_sec_info_reply.c | 72 - .../serializers/ble_gap_sec_params_reply.c | 90 - .../s110/serializers/ble_gap_tx_power_set.c | 39 - .../ble_gattc_char_value_by_uuid_read.c | 65 - .../serializers/ble_gattc_char_values_read.c | 53 - .../ble_gattc_characteristics_discover.c | 63 - .../codecs/s110/serializers/ble_gattc_conn.h | 398 - .../ble_gattc_descriptors_discover.c | 62 - .../serializers/ble_gattc_evt_char_disc_rsp.c | 73 - .../ble_gattc_evt_char_val_by_uuid_read_rsp.c | 52 - .../ble_gattc_evt_char_vals_read_rsp.c | 59 - .../s110/serializers/ble_gattc_evt_conn.h | 236 - .../serializers/ble_gattc_evt_desc_disc_rsp.c | 53 - .../s110/serializers/ble_gattc_evt_hvx.c | 52 - .../ble_gattc_evt_prim_srvc_disc_rsp.c | 62 - .../s110/serializers/ble_gattc_evt_read_rsp.c | 52 - .../serializers/ble_gattc_evt_rel_disc_rsp.c | 51 - .../s110/serializers/ble_gattc_evt_timeout.c | 37 - .../serializers/ble_gattc_evt_write_rsp.c | 53 - .../s110/serializers/ble_gattc_hv_confirm.c | 45 - .../ble_gattc_primary_services_discover.c | 67 - .../codecs/s110/serializers/ble_gattc_read.c | 49 - .../ble_gattc_relationships_discover.c | 64 - .../codecs/s110/serializers/ble_gattc_write.c | 59 - .../ble_gatts_characteristic_add.c | 88 - .../serializers/ble_gatts_descriptor_add.c | 94 - .../s110/serializers/ble_gatts_evt_conn.h | 156 - .../s110/serializers/ble_gatts_evt_hvc.c | 38 - .../ble_gatts_evt_rw_authorize_request.c | 59 - .../serializers/ble_gatts_evt_sc_confirm.c | 37 - .../ble_gatts_evt_sys_attr_missing.c | 37 - .../s110/serializers/ble_gatts_evt_timeout.c | 37 - .../s110/serializers/ble_gatts_evt_write.c | 63 - .../codecs/s110/serializers/ble_gatts_hvx.c | 81 - .../s110/serializers/ble_gatts_include_add.c | 74 - .../ble_gatts_rw_authorize_reply.c | 53 - .../s110/serializers/ble_gatts_service_add.c | 76 - .../serializers/ble_gatts_service_changed.c | 55 - .../s110/serializers/ble_gatts_sys_attr_get.c | 125 - .../s110/serializers/ble_gatts_sys_attr_set.c | 76 - .../s110/serializers/ble_gatts_value_get.c | 105 - .../s110/serializers/ble_gatts_value_set.c | 74 - .../s110/serializers/ble_l2cap_cid_register.c | 46 - .../serializers/ble_l2cap_cid_unregister.c | 46 - .../codecs/s110/serializers/ble_l2cap_conn.h | 156 - .../s110/serializers/ble_l2cap_evt_conn.h | 56 - .../s110/serializers/ble_l2cap_evt_rx.c | 50 - .../codecs/s110/serializers/ble_l2cap_tx.c | 67 - .../codecs/s110/serializers/ble_opt_get.c | 130 - .../s110/serializers/ble_opt_id_pre_decoder.c | 36 - .../codecs/s110/serializers/ble_opt_set.c | 114 - .../serializers/ble_tx_buffer_count_get.c | 65 - .../s110/serializers/ble_user_mem_reply.c | 66 - .../codecs/s110/serializers/ble_uuid_decode.c | 77 - .../codecs/s110/serializers/ble_uuid_encode.c | 117 - .../codecs/s110/serializers/ble_uuid_vs_add.c | 73 - .../codecs/s110/serializers/ble_version_get.c | 77 - .../s110/serializers/conn_ble_gap_sec_keys.c | 74 - .../s110/serializers/conn_ble_gap_sec_keys.h | 84 - .../s110/serializers/conn_ble_user_mem.c | 78 - .../s110/serializers/conn_ble_user_mem.h | 81 - .../codecs/s110/serializers/nrf_soc_conn.h | 89 - .../s110/serializers/power_system_off.c | 28 - .../codecs/s110/serializers/temp_get.c | 71 - .../codecs/s120/middleware/conn_mw.h | 38 - .../codecs/s120/middleware/conn_mw_ble.c | 287 - .../codecs/s120/middleware/conn_mw_ble_gap.c | 830 - .../s120/middleware/conn_mw_ble_gatts.c | 407 - .../s120/middleware/conn_mw_ble_gatts.h | 216 - .../codecs/s120/middleware/conn_mw_nrf_soc.c | 60 - .../codecs/s120/middleware/conn_mw_nrf_soc.h | 55 - .../codecs/s120/serializers/ble_conn.h | 447 - .../codecs/s120/serializers/ble_enable.c | 46 - .../codecs/s120/serializers/ble_evt_conn.h | 95 - .../s120/serializers/ble_evt_tx_complete.c | 38 - .../serializers/ble_evt_user_mem_release.c | 55 - .../serializers/ble_evt_user_mem_request.c | 46 - .../s120/serializers/ble_gap_address_get.c | 79 - .../s120/serializers/ble_gap_address_set.c | 52 - .../s120/serializers/ble_gap_adv_data_set.c | 49 - .../s120/serializers/ble_gap_adv_start.c | 88 - .../s120/serializers/ble_gap_adv_stop.c | 23 - .../s120/serializers/ble_gap_appearance_get.c | 76 - .../s120/serializers/ble_gap_appearance_set.c | 42 - .../s120/serializers/ble_gap_auth_key_reply.c | 68 - .../s120/serializers/ble_gap_authenticate.c | 57 - .../codecs/s120/serializers/ble_gap_conn.h | 1043 -- .../serializers/ble_gap_conn_param_update.c | 71 - .../s120/serializers/ble_gap_conn_sec_get.c | 75 - .../codecs/s120/serializers/ble_gap_connect.c | 55 - .../s120/serializers/ble_gap_connect_cancel.c | 25 - .../serializers/ble_gap_device_name_get.c | 92 - .../serializers/ble_gap_device_name_set.c | 61 - .../s120/serializers/ble_gap_disconnect.c | 52 - .../codecs/s120/serializers/ble_gap_encrypt.c | 60 - .../s120/serializers/ble_gap_evt_adv_report.c | 61 - .../ble_gap_evt_auth_key_request.c | 49 - .../serializers/ble_gap_evt_auth_status.c | 62 - .../s120/serializers/ble_gap_evt_conn.h | 336 - .../ble_gap_evt_conn_param_update.c | 49 - .../ble_gap_evt_conn_param_update_request.c | 49 - .../serializers/ble_gap_evt_conn_sec_update.c | 51 - .../s120/serializers/ble_gap_evt_connected.c | 49 - .../serializers/ble_gap_evt_disconnected.c | 49 - .../serializers/ble_gap_evt_passkey_display.c | 43 - .../serializers/ble_gap_evt_rssi_changed.c | 38 - .../serializers/ble_gap_evt_scan_req_report.c | 49 - .../ble_gap_evt_sec_info_request.c | 51 - .../ble_gap_evt_sec_params_request.c | 51 - .../serializers/ble_gap_evt_sec_request.c | 49 - .../s120/serializers/ble_gap_evt_timeout.c | 38 - .../s120/serializers/ble_gap_ppcp_get.c | 80 - .../s120/serializers/ble_gap_ppcp_set.c | 64 - .../s120/serializers/ble_gap_rssi_get.c | 77 - .../s120/serializers/ble_gap_rssi_start.c | 49 - .../s120/serializers/ble_gap_rssi_stop.c | 39 - .../s120/serializers/ble_gap_scan_start.c | 44 - .../s120/serializers/ble_gap_scan_stop.c | 23 - .../s120/serializers/ble_gap_sec_info_reply.c | 72 - .../serializers/ble_gap_sec_params_reply.c | 90 - .../s120/serializers/ble_gap_tx_power_set.c | 39 - .../ble_gattc_char_value_by_uuid_read.c | 65 - .../serializers/ble_gattc_char_values_read.c | 53 - .../ble_gattc_characteristics_discover.c | 63 - .../codecs/s120/serializers/ble_gattc_conn.h | 398 - .../ble_gattc_descriptors_discover.c | 62 - .../serializers/ble_gattc_evt_char_disc_rsp.c | 73 - .../ble_gattc_evt_char_val_by_uuid_read_rsp.c | 52 - .../ble_gattc_evt_char_vals_read_rsp.c | 59 - .../s120/serializers/ble_gattc_evt_conn.h | 236 - .../serializers/ble_gattc_evt_desc_disc_rsp.c | 53 - .../s120/serializers/ble_gattc_evt_hvx.c | 52 - .../ble_gattc_evt_prim_srvc_disc_rsp.c | 62 - .../s120/serializers/ble_gattc_evt_read_rsp.c | 52 - .../serializers/ble_gattc_evt_rel_disc_rsp.c | 51 - .../s120/serializers/ble_gattc_evt_timeout.c | 37 - .../serializers/ble_gattc_evt_write_rsp.c | 53 - .../s120/serializers/ble_gattc_hv_confirm.c | 45 - .../ble_gattc_primary_services_discover.c | 67 - .../codecs/s120/serializers/ble_gattc_read.c | 49 - .../ble_gattc_relationships_discover.c | 64 - .../codecs/s120/serializers/ble_gattc_write.c | 59 - .../ble_gatts_characteristic_add.c | 88 - .../codecs/s120/serializers/ble_gatts_conn.h | 514 - .../serializers/ble_gatts_descriptor_add.c | 94 - .../s120/serializers/ble_gatts_evt_conn.h | 156 - .../s120/serializers/ble_gatts_evt_hvc.c | 38 - .../ble_gatts_evt_rw_authorize_request.c | 59 - .../serializers/ble_gatts_evt_sc_confirm.c | 37 - .../ble_gatts_evt_sys_attr_missing.c | 37 - .../s120/serializers/ble_gatts_evt_timeout.c | 37 - .../s120/serializers/ble_gatts_evt_write.c | 63 - .../codecs/s120/serializers/ble_gatts_hvx.c | 81 - .../s120/serializers/ble_gatts_include_add.c | 74 - .../ble_gatts_rw_authorize_reply.c | 53 - .../s120/serializers/ble_gatts_service_add.c | 76 - .../serializers/ble_gatts_service_changed.c | 55 - .../s120/serializers/ble_gatts_sys_attr_get.c | 125 - .../s120/serializers/ble_gatts_sys_attr_set.c | 76 - .../s120/serializers/ble_gatts_value_get.c | 105 - .../s120/serializers/ble_gatts_value_set.c | 74 - .../s120/serializers/ble_l2cap_cid_register.c | 46 - .../serializers/ble_l2cap_cid_unregister.c | 46 - .../codecs/s120/serializers/ble_l2cap_conn.h | 156 - .../s120/serializers/ble_l2cap_evt_conn.h | 56 - .../s120/serializers/ble_l2cap_evt_rx.c | 50 - .../codecs/s120/serializers/ble_l2cap_tx.c | 67 - .../codecs/s120/serializers/ble_opt_get.c | 130 - .../s120/serializers/ble_opt_id_pre_decoder.c | 36 - .../codecs/s120/serializers/ble_opt_set.c | 114 - .../serializers/ble_tx_buffer_count_get.c | 65 - .../s120/serializers/ble_user_mem_reply.c | 66 - .../codecs/s120/serializers/ble_uuid_decode.c | 77 - .../codecs/s120/serializers/ble_uuid_encode.c | 117 - .../codecs/s120/serializers/ble_uuid_vs_add.c | 73 - .../codecs/s120/serializers/ble_version_get.c | 77 - .../s120/serializers/conn_ble_gap_sec_keys.c | 73 - .../s120/serializers/conn_ble_gap_sec_keys.h | 86 - .../s120/serializers/conn_ble_user_mem.c | 78 - .../s120/serializers/conn_ble_user_mem.h | 81 - .../codecs/s120/serializers/nrf_soc_conn.h | 89 - .../s120/serializers/power_system_off.c | 28 - .../codecs/s120/serializers/temp_get.c | 71 - .../codecs/s130/middleware/conn_mw.h | 38 - .../codecs/s130/middleware/conn_mw_ble.c | 287 - .../codecs/s130/middleware/conn_mw_ble.h | 179 - .../codecs/s130/middleware/conn_mw_ble_gap.h | 532 - .../s130/middleware/conn_mw_ble_gattc.c | 293 - .../s130/middleware/conn_mw_ble_gattc.h | 180 - .../s130/middleware/conn_mw_ble_gatts.c | 407 - .../s130/middleware/conn_mw_ble_gatts.h | 216 - .../s130/middleware/conn_mw_ble_l2cap.c | 91 - .../s130/middleware/conn_mw_ble_l2cap.h | 72 - .../codecs/s130/middleware/conn_mw_items.c | 76 - .../codecs/s130/middleware/conn_mw_nrf_soc.c | 60 - .../codecs/s130/middleware/conn_mw_nrf_soc.h | 55 - .../codecs/s130/serializers/ble_enable.c | 46 - .../codecs/s130/serializers/ble_event.c | 184 - .../s130/serializers/ble_evt_tx_complete.c | 38 - .../serializers/ble_evt_user_mem_release.c | 55 - .../serializers/ble_evt_user_mem_request.c | 46 - .../s130/serializers/ble_gap_address_get.c | 79 - .../s130/serializers/ble_gap_address_set.c | 52 - .../s130/serializers/ble_gap_adv_data_set.c | 49 - .../s130/serializers/ble_gap_adv_start.c | 88 - .../s130/serializers/ble_gap_adv_stop.c | 23 - .../s130/serializers/ble_gap_appearance_get.c | 76 - .../s130/serializers/ble_gap_appearance_set.c | 42 - .../s130/serializers/ble_gap_auth_key_reply.c | 68 - .../s130/serializers/ble_gap_authenticate.c | 57 - .../serializers/ble_gap_conn_param_update.c | 71 - .../s130/serializers/ble_gap_conn_sec_get.c | 75 - .../codecs/s130/serializers/ble_gap_connect.c | 55 - .../s130/serializers/ble_gap_connect_cancel.c | 25 - .../serializers/ble_gap_device_name_get.c | 92 - .../serializers/ble_gap_device_name_set.c | 61 - .../s130/serializers/ble_gap_disconnect.c | 52 - .../codecs/s130/serializers/ble_gap_encrypt.c | 60 - .../s130/serializers/ble_gap_evt_adv_report.c | 61 - .../ble_gap_evt_auth_key_request.c | 49 - .../serializers/ble_gap_evt_auth_status.c | 62 - .../ble_gap_evt_conn_param_update.c | 49 - .../ble_gap_evt_conn_param_update_request.c | 49 - .../serializers/ble_gap_evt_conn_sec_update.c | 51 - .../s130/serializers/ble_gap_evt_connected.c | 49 - .../serializers/ble_gap_evt_disconnected.c | 49 - .../serializers/ble_gap_evt_passkey_display.c | 43 - .../serializers/ble_gap_evt_rssi_changed.c | 38 - .../serializers/ble_gap_evt_scan_req_report.c | 49 - .../ble_gap_evt_sec_info_request.c | 51 - .../ble_gap_evt_sec_params_request.c | 51 - .../serializers/ble_gap_evt_sec_request.c | 49 - .../s130/serializers/ble_gap_evt_timeout.c | 38 - .../s130/serializers/ble_gap_ppcp_get.c | 80 - .../s130/serializers/ble_gap_ppcp_set.c | 64 - .../s130/serializers/ble_gap_rssi_get.c | 77 - .../s130/serializers/ble_gap_rssi_start.c | 49 - .../s130/serializers/ble_gap_rssi_stop.c | 39 - .../s130/serializers/ble_gap_scan_start.c | 44 - .../s130/serializers/ble_gap_scan_stop.c | 23 - .../s130/serializers/ble_gap_sec_info_reply.c | 72 - .../serializers/ble_gap_sec_params_reply.c | 90 - .../s130/serializers/ble_gap_tx_power_set.c | 39 - .../ble_gattc_char_value_by_uuid_read.c | 65 - .../serializers/ble_gattc_char_values_read.c | 53 - .../ble_gattc_characteristics_discover.c | 63 - .../ble_gattc_descriptors_discover.c | 62 - .../serializers/ble_gattc_evt_char_disc_rsp.c | 73 - .../ble_gattc_evt_char_val_by_uuid_read_rsp.c | 52 - .../ble_gattc_evt_char_vals_read_rsp.c | 59 - .../serializers/ble_gattc_evt_desc_disc_rsp.c | 53 - .../s130/serializers/ble_gattc_evt_hvx.c | 52 - .../ble_gattc_evt_prim_srvc_disc_rsp.c | 62 - .../s130/serializers/ble_gattc_evt_read_rsp.c | 52 - .../serializers/ble_gattc_evt_rel_disc_rsp.c | 51 - .../s130/serializers/ble_gattc_evt_timeout.c | 37 - .../serializers/ble_gattc_evt_write_rsp.c | 53 - .../s130/serializers/ble_gattc_hv_confirm.c | 45 - .../ble_gattc_primary_services_discover.c | 67 - .../codecs/s130/serializers/ble_gattc_read.c | 49 - .../ble_gattc_relationships_discover.c | 64 - .../codecs/s130/serializers/ble_gattc_write.c | 59 - .../ble_gatts_characteristic_add.c | 88 - .../codecs/s130/serializers/ble_gatts_conn.h | 514 - .../serializers/ble_gatts_descriptor_add.c | 94 - .../s130/serializers/ble_gatts_evt_hvc.c | 38 - .../ble_gatts_evt_rw_authorize_request.c | 59 - .../serializers/ble_gatts_evt_sc_confirm.c | 37 - .../ble_gatts_evt_sys_attr_missing.c | 37 - .../s130/serializers/ble_gatts_evt_timeout.c | 37 - .../s130/serializers/ble_gatts_evt_write.c | 63 - .../codecs/s130/serializers/ble_gatts_hvx.c | 81 - .../s130/serializers/ble_gatts_include_add.c | 74 - .../ble_gatts_rw_authorize_reply.c | 53 - .../s130/serializers/ble_gatts_service_add.c | 76 - .../serializers/ble_gatts_service_changed.c | 55 - .../s130/serializers/ble_gatts_sys_attr_get.c | 125 - .../s130/serializers/ble_gatts_sys_attr_set.c | 76 - .../s130/serializers/ble_gatts_value_get.c | 105 - .../s130/serializers/ble_gatts_value_set.c | 74 - .../s130/serializers/ble_l2cap_cid_register.c | 46 - .../serializers/ble_l2cap_cid_unregister.c | 46 - .../s130/serializers/ble_l2cap_evt_conn.h | 56 - .../s130/serializers/ble_l2cap_evt_rx.c | 50 - .../codecs/s130/serializers/ble_l2cap_tx.c | 67 - .../codecs/s130/serializers/ble_opt_get.c | 130 - .../s130/serializers/ble_opt_id_pre_decoder.c | 36 - .../codecs/s130/serializers/ble_opt_set.c | 114 - .../serializers/ble_tx_buffer_count_get.c | 65 - .../s130/serializers/ble_user_mem_reply.c | 66 - .../codecs/s130/serializers/ble_uuid_decode.c | 77 - .../codecs/s130/serializers/ble_uuid_encode.c | 117 - .../codecs/s130/serializers/ble_uuid_vs_add.c | 73 - .../codecs/s130/serializers/ble_version_get.c | 77 - .../s130/serializers/conn_ble_gap_sec_keys.c | 73 - .../s130/serializers/conn_ble_gap_sec_keys.h | 86 - .../s130/serializers/conn_ble_user_mem.c | 78 - .../s130/serializers/conn_ble_user_mem.h | 81 - .../codecs/s130/serializers/nrf_soc_conn.h | 89 - .../s130/serializers/power_system_off.c | 28 - .../codecs/s130/serializers/temp_get.c | 71 - .../codecs/s132/middleware/conn_mw.h | 76 + .../{s110 => s132}/middleware/conn_mw_ble.c | 184 +- .../{s120 => s132}/middleware/conn_mw_ble.h | 64 +- .../middleware/conn_mw_ble_gap.c | 527 +- .../middleware/conn_mw_ble_gap.h | 297 +- .../middleware/conn_mw_ble_gattc.c | 104 +- .../middleware/conn_mw_ble_gattc.h | 92 +- .../middleware/conn_mw_ble_gatts.c | 145 +- .../middleware/conn_mw_ble_gatts.h | 113 +- .../middleware/conn_mw_ble_l2cap.c | 49 +- .../middleware/conn_mw_ble_l2cap.h | 57 +- .../{s120 => s132}/middleware/conn_mw_items.c | 61 +- .../codecs/s132/middleware/conn_mw_nrf_soc.c | 115 + .../codecs/s132/middleware/conn_mw_nrf_soc.h | 112 + .../codecs/s132/serializers/ble_conn.c | 445 + .../{s130 => s132}/serializers/ble_conn.h | 146 +- .../serializers/ble_event_enc.c} | 77 +- .../codecs/s132/serializers/ble_evt_conn.c | 106 + .../{s130 => s132}/serializers/ble_evt_conn.h | 89 +- .../codecs/s132/serializers/ble_gap_conn.c | 918 + .../{s130 => s132}/serializers/ble_gap_conn.h | 677 +- .../s132/serializers/ble_gap_evt_conn.c | 306 + .../serializers/ble_gap_evt_conn.h | 126 +- .../codecs/s132/serializers/ble_gattc_conn.c | 300 + .../serializers/ble_gattc_conn.h | 196 +- .../s132/serializers/ble_gattc_evt_conn.c | 236 + .../serializers/ble_gattc_evt_conn.h | 118 +- .../codecs/s132/serializers/ble_gatts_conn.c | 422 + .../serializers/ble_gatts_conn.h | 285 +- .../s132/serializers/ble_gatts_evt_conn.c | 164 + .../serializers/ble_gatts_evt_conn.h | 90 +- .../codecs/s132/serializers/ble_l2cap_conn.c | 157 + .../serializers/ble_l2cap_conn.h | 80 +- .../s132/serializers/ble_l2cap_evt_conn.c | 59 + .../s132/serializers/ble_l2cap_evt_conn.h | 92 + .../s132/serializers/conn_ble_gap_sec_keys.c | 101 + .../s132/serializers/conn_ble_gap_sec_keys.h | 128 + .../s132/serializers/conn_ble_user_mem.c | 106 + .../s132/serializers/conn_ble_user_mem.h | 119 + .../codecs/s132/serializers/nrf_soc_conn.c | 90 + .../codecs/s132/serializers/nrf_soc_conn.h | 159 + .../serialization/connectivity/hal/dtm_uart.c | 112 +- .../serialization/connectivity/hal/dtm_uart.h | 57 +- .../connectivity/pstorage_platform.h | 85 +- .../connectivity/ser_conn_cmd_decoder.c | 48 +- .../connectivity/ser_conn_cmd_decoder.h | 69 +- .../connectivity/ser_conn_dtm_cmd_decoder.c | 48 +- .../connectivity/ser_conn_dtm_cmd_decoder.h | 73 +- .../connectivity/ser_conn_error_handling.c | 70 +- .../connectivity/ser_conn_event_encoder.c | 48 +- .../connectivity/ser_conn_event_encoder.h | 62 +- .../connectivity/ser_conn_handlers.c | 55 +- .../connectivity/ser_conn_handlers.h | 59 +- .../connectivity/ser_conn_pkt_decoder.c | 57 +- .../connectivity/ser_conn_pkt_decoder.h | 63 +- .../connectivity/ser_conn_reset_cmd_decoder.c | 52 +- .../connectivity/ser_conn_reset_cmd_decoder.h | 65 +- .../startup/arm/arm_startup_nrf51.s | 16 +- .../ant_stack_handler_types.h | 68 +- .../common/softdevice_handler/app_ram_base.h | 188 + .../ble_stack_handler_types.h | 71 +- .../softdevice_handler/softdevice_handler.c | 393 +- .../softdevice_handler/softdevice_handler.h | 139 +- .../softdevice_handler_appsh.c | 48 +- .../softdevice_handler_appsh.h | 57 +- ...s110_nrf51822_8.0.0_migration_document.pdf | Bin 188439 -> 0 bytes .../s110_nrf51_8.0.0_licence-agreement.pdf | Bin 5553 -> 0 bytes .../s110/doc/s110_nrf51_8.0.0_readme.txt | 9 - .../doc/s110_nrf51_8.0.0_release-notes.pdf | Bin 50532 -> 0 bytes components/softdevice/s110/headers/ble.h | 455 - components/softdevice/s110/headers/ble_err.h | 83 - components/softdevice/s110/headers/ble_gap.h | 1349 -- .../softdevice/s110/headers/ble_gattc.h | 441 - .../softdevice/s110/headers/ble_gatts.h | 639 - .../softdevice/s110/headers/ble_l2cap.h | 177 - .../softdevice/s110/headers/ble_ranges.h | 119 - .../softdevice/s110/headers/ble_types.h | 198 - .../softdevice/s110/headers/nrf_error.h | 78 - .../softdevice/s110/headers/nrf_error_sdm.h | 60 - .../softdevice/s110/headers/nrf_sd_def.h | 23 - components/softdevice/s110/headers/nrf_sdm.h | 221 - .../s110/headers/softdevice_assert.h | 73 - .../s110/hex/s110_nrf51_8.0.0_softdevice.hex | 5649 ------ .../armgcc/armgcc_s110_nrf51422_xxaa.ld | 22 - .../armgcc/armgcc_s110_nrf51422_xxac.ld | 22 - .../armgcc/armgcc_s110_nrf51822_xxaa.ld | 22 - .../armgcc/armgcc_s110_nrf51822_xxab.ld | 22 - .../toolchain/iar/iar_s110_nrf51822_xxab.icf | 31 - .../s120_nrf51_2.1.0_licence_agreement.pdf | Bin 5553 -> 0 bytes .../s120/doc/s120_nrf51_2.1.0_readme.txt | 14 - .../doc/s120_nrf51_2.1.0_releasenotes.pdf | Bin 54062 -> 0 bytes components/softdevice/s120/headers/ble.h | 454 - components/softdevice/s120/headers/ble_gap.h | 1365 -- components/softdevice/s120/headers/ble_gatt.h | 200 - .../softdevice/s120/headers/ble_gattc.h | 441 - .../softdevice/s120/headers/ble_gatts.h | 615 - components/softdevice/s120/headers/ble_hci.h | 125 - .../softdevice/s120/headers/ble_l2cap.h | 177 - .../softdevice/s120/headers/nrf_error_sdm.h | 60 - .../softdevice/s120/headers/nrf_error_soc.h | 76 - components/softdevice/s120/headers/nrf_mbr.h | 185 - .../softdevice/s120/headers/nrf_sd_def.h | 23 - components/softdevice/s120/headers/nrf_sdm.h | 221 - components/softdevice/s120/headers/nrf_soc.h | 993 -- components/softdevice/s120/headers/nrf_svc.h | 69 - .../s120/headers/softdevice_assert.h | 73 - .../s120/hex/s120_nrf51_2.1.0_softdevice.hex | 7080 -------- .../armgcc/armgcc_s120_nrf51422_xxaa.ld | 22 - .../armgcc/armgcc_s120_nrf51422_xxac.ld | 22 - .../armgcc/armgcc_s120_nrf51822_xxaa.ld | 22 - .../armgcc/armgcc_s120_nrf51822_xxab.ld | 22 - .../toolchain/iar/iar_s120_nrf51422_xxaa.icf | 31 - .../toolchain/iar/iar_s120_nrf51422_xxac.icf | 31 - .../toolchain/iar/iar_s120_nrf51822_xxaa.icf | 31 - .../toolchain/iar/iar_s120_nrf51822_xxab.icf | 31 - .../s130_nrf51822_1.0.0_licence_agreement.pdf | Bin 5564 -> 0 bytes .../s130/doc/s130_nrf51822_1.0.0_readme.txt | 8 - .../doc/s130_nrf51822_1.0.0_releasenotes.pdf | Bin 22817 -> 0 bytes .../s130_nrf51822_2.0.1_licence_agreement.pdf | Bin 0 -> 5532 bytes .../s130/doc/s130_nrf51822_2.0.1_readme.txt | 10 + .../doc/s130_nrf51822_2.0.1_releasenotes.pdf | Bin 0 -> 51579 bytes ...=> s130_nrf51_2.0.1_licence_agreement.txt} | 187 +- .../s13x_nrf5x_2.0.1_migration_document.pdf | Bin 0 -> 45493 bytes components/softdevice/s130/headers/ble.h | 436 +- components/softdevice/s130/headers/ble_err.h | 9 +- components/softdevice/s130/headers/ble_gap.h | 610 +- components/softdevice/s130/headers/ble_gatt.h | 16 +- .../softdevice/s130/headers/ble_gattc.h | 180 +- .../softdevice/s130/headers/ble_gatts.h | 265 +- components/softdevice/s130/headers/ble_hci.h | 6 + .../softdevice/s130/headers/ble_l2cap.h | 71 +- .../softdevice/s130/headers/ble_ranges.h | 7 + .../softdevice/s130/headers/ble_types.h | 13 +- .../s130/headers/{ => nrf51}/nrf_mbr.h | 14 + .../softdevice/s130/headers/nrf_error.h | 11 +- .../softdevice/s130/headers/nrf_error_sdm.h | 27 +- .../softdevice/s130/headers/nrf_error_soc.h | 6 + components/softdevice/s130/headers/nrf_nvic.h | 485 + .../softdevice/s130/headers/nrf_sd_def.h | 59 +- components/softdevice/s130/headers/nrf_sdm.h | 183 +- components/softdevice/s130/headers/nrf_soc.h | 384 +- components/softdevice/s130/headers/nrf_svc.h | 43 +- .../s130/headers/softdevice_assert.h | 73 - .../s130/hex/s130_nrf51_1.0.0_softdevice.hex | 6861 -------- .../s130_nrf51_2.0.1_licence-agreement.txt} | 187 +- .../armgcc/armgcc_s130_nrf51422_xxaa.ld | 24 +- .../armgcc/armgcc_s130_nrf51422_xxac.ld | 24 +- .../armgcc/armgcc_s130_nrf51822_xxaa.ld | 24 +- .../armgcc/armgcc_s130_nrf51822_xxab.ld | 24 +- .../toolchain/iar/iar_s130_nrf51422_xxaa.icf | 9 +- .../toolchain/iar/iar_s130_nrf51422_xxac.icf | 9 +- .../toolchain/iar/iar_s130_nrf51822_xxaa.icf | 9 +- .../toolchain/iar/iar_s130_nrf51822_xxab.icf | 9 +- .../s132_nrf52_3.0.0_licence_agreement.pdf | Bin 0 -> 5532 bytes .../s132_nrf52_3.0.0_licence_agreement.txt} | 184 +- .../s132_nrf52_3.0.0_migration_document.pdf | Bin 0 -> 71996 bytes .../s132/doc/s132_nrf52_3.0.0_readme.txt | 12 + .../doc/s132_nrf52_3.0.0_releasenotes.pdf | Bin 0 -> 55456 bytes components/softdevice/s132/headers/ble.h | 681 + .../{s120 => s132}/headers/ble_err.h | 9 +- .../{s310 => s132}/headers/ble_gap.h | 1048 +- .../{s110 => s132}/headers/ble_gatt.h | 46 +- .../{s310 => s132}/headers/ble_gattc.h | 289 +- .../{s310 => s132}/headers/ble_gatts.h | 271 +- .../{s110 => s132}/headers/ble_hci.h | 6 + .../{s310 => s132}/headers/ble_l2cap.h | 33 +- .../{s120 => s132}/headers/ble_ranges.h | 57 +- .../{s120 => s132}/headers/ble_types.h | 15 +- .../headers => s132/headers/nrf52}/nrf_mbr.h | 51 +- .../{s120 => s132}/headers/nrf_error.h | 11 +- .../{s210 => s132}/headers/nrf_error_sdm.h | 7 + .../{s110 => s132}/headers/nrf_error_soc.h | 6 + components/softdevice/s132/headers/nrf_nvic.h | 485 + .../softdevice/s132/headers/nrf_sd_def.h | 60 + components/softdevice/s132/headers/nrf_sdm.h | 331 + .../{s110 => s132}/headers/nrf_soc.h | 395 +- .../{s110 => s132}/headers/nrf_svc.h | 43 +- .../s132_nrf52_3.0.0_licence-agreement.txt | 96 + .../armgcc/armgcc_s132_nrf52832_xxaa.ld | 28 + .../toolchain/iar/iar_s132_nrf52832_xxaa.icf} | 13 +- .../s210_nrf51422_5.0.0_licence_agreement.pdf | Bin 7025 -> 0 bytes .../s210_nrf51422_5.0.0_licence_agreement.txt | 110 - ...s210_nrf51422_5.0.0_migration_document.pdf | Bin 637984 -> 0 bytes .../s210/doc/s210_nrf51422_5.0.0_readme.txt | 14 - .../doc/s210_nrf51422_5.0.0_releasenotes.pdf | Bin 412251 -> 0 bytes .../softdevice/s210/headers/ant_error.h | 43 - .../softdevice/s210/headers/ant_interface.h | 939 - .../softdevice/s210/headers/ant_parameters.h | 725 - .../softdevice/s210/headers/nrf_error.h | 78 - .../softdevice/s210/headers/nrf_error_soc.h | 76 - components/softdevice/s210/headers/nrf_mbr.h | 184 - .../softdevice/s210/headers/nrf_sd_def.h | 23 - components/softdevice/s210/headers/nrf_sdm.h | 221 - components/softdevice/s210/headers/nrf_soc.h | 993 -- components/softdevice/s210/headers/nrf_svc.h | 71 - .../s210/headers/softdevice_assert.h | 73 - .../hex/s210_nrf51422_5.0.0_softdevice.hex | 2952 ---- .../armgcc/armgcc_s210_nrf51422_xxaa.ld | 22 - .../armgcc/armgcc_s210_nrf51422_xxac.ld | 22 - .../toolchain/iar/iar_s210_nrf51422_xxaa.icf | 31 - .../toolchain/iar/iar_s210_nrf51422_xxac.icf | 31 - .../softdevice/s212/headers/nrf_sd_def.h | 60 + .../armgcc/armgcc_s212_nrf52832_xxaa.ld | 28 + .../toolchain/iar/iar_s212_nrf52832_xxaa.icf} | 13 +- .../s310_nrf51822_3.0.0_licence_agreement.pdf | Bin 7025 -> 0 bytes .../s310_nrf51822_3.0.0_licence_agreement.txt | 110 - ...s310_nrf51822_3.0.0_migration_document.pdf | Bin 432939 -> 0 bytes .../s310/doc/s310_nrf51822_3.0.0_readme.txt | 14 - .../doc/s310_nrf51822_3.0.0_releasenotes.pdf | Bin 140119 -> 0 bytes .../softdevice/s310/headers/ant_error.h | 43 - .../softdevice/s310/headers/ant_interface.h | 939 - .../softdevice/s310/headers/ant_parameters.h | 725 - components/softdevice/s310/headers/ble.h | 455 - components/softdevice/s310/headers/ble_err.h | 83 - components/softdevice/s310/headers/ble_gatt.h | 200 - components/softdevice/s310/headers/ble_hci.h | 125 - .../softdevice/s310/headers/ble_ranges.h | 119 - .../softdevice/s310/headers/ble_types.h | 198 - .../softdevice/s310/headers/nrf_error.h | 78 - .../softdevice/s310/headers/nrf_error_sdm.h | 60 - .../softdevice/s310/headers/nrf_error_soc.h | 76 - components/softdevice/s310/headers/nrf_mbr.h | 184 - .../softdevice/s310/headers/nrf_sd_def.h | 23 - components/softdevice/s310/headers/nrf_sdm.h | 221 - components/softdevice/s310/headers/nrf_soc.h | 993 -- components/softdevice/s310/headers/nrf_svc.h | 71 - .../s310/headers/softdevice_assert.h | 73 - .../hex/s310_nrf51422_3.0.0_softdevice.hex | 7295 -------- .../armgcc/armgcc_s310_nrf51422_xxaa.ld | 22 - .../armgcc/armgcc_s310_nrf51422_xxac.ld | 22 - .../toolchain/iar/iar_s310_nrf51422_xxaa.icf | 31 - .../toolchain/iar/iar_s310_nrf51422_xxac.icf | 31 - .../softdevice/s332/headers/nrf_sd_def.h | 60 + .../armgcc/armgcc_s332_nrf52832_xxaa.ld | 28 + .../toolchain/iar/iar_s332_nrf52832_xxaa.icf} | 13 +- components/toolchain/arm/arm_startup_nrf51.s | 86 +- components/toolchain/arm/arm_startup_nrf52.s | 96 +- .../toolchain/arm/arm_startup_nrf52840.s | 509 + components/toolchain/arm/uicr_config.h | 82 +- components/toolchain/gcc/Makefile.common | 309 +- components/toolchain/gcc/Makefile.posix | 3 +- components/toolchain/gcc/Makefile.windows | 9 +- components/toolchain/gcc/arm_common_tables.h | 136 - components/toolchain/gcc/arm_const_structs.h | 79 - components/toolchain/gcc/arm_math.h | 7544 -------- components/toolchain/gcc/core_cm0.h | 711 - components/toolchain/gcc/core_cm4.h | 1802 -- components/toolchain/gcc/core_cmFunc.h | 637 - components/toolchain/gcc/core_cmInstr.h | 880 - components/toolchain/gcc/core_cmSimd.h | 697 - components/toolchain/gcc/file_list.mk | 2 + components/toolchain/gcc/gcc_nrf51_common.ld | 12 +- components/toolchain/gcc/gcc_startup_nrf51.s | 204 +- components/toolchain/gcc/gcc_startup_nrf52.s | 226 +- .../toolchain/gcc/gcc_startup_nrf52840.S | 538 + components/toolchain/gcc/nrf51_common.ld | 229 +- components/toolchain/gcc/nrf52840_xxaa.ld | 13 + components/toolchain/gcc/nrf52_common.ld | 229 +- components/toolchain/gcc/nrf5x_common.ld | 229 +- components/toolchain/iar/iar_startup_nrf51.s | 183 +- components/toolchain/iar/iar_startup_nrf52.s | 621 +- .../toolchain/iar/iar_startup_nrf52840.s | 623 + components/toolchain/system_nrf51.c | 58 +- components/toolchain/system_nrf51.h | 10 +- components/toolchain/system_nrf51422.c | 83 +- components/toolchain/system_nrf52.c | 201 +- components/toolchain/system_nrf52.h | 10 +- components/toolchain/system_nrf52840.c | 209 + components/toolchain/system_nrf52840.h | 69 + config/bsp.h | 9 - config/nrf_drv_config.h | 341 - config/pstorage_platform.h | 78 - config/sdk_config.h | 3738 ++++ main.c | 116 +- 1932 files changed, 185521 insertions(+), 192527 deletions(-) create mode 100644 Keil/RTE/Device/nRF51802_xxAA/arm_startup_nrf51.s create mode 100644 Keil/RTE/Device/nRF51802_xxAA/system_nrf51.c delete mode 100644 Keil/RTE/_EPD/RTE_Components.h delete mode 100644 Keil/RTE/_EPD_Debug/RTE_Components.h delete mode 100644 Keil/RTE/_flash_softdevice/RTE_Components.h rename components/{libraries => ant}/ant_fs/antfs.c (91%) rename components/{libraries => ant}/ant_fs/antfs.h (88%) create mode 100644 components/ant/ant_fs/crc.c create mode 100644 components/ant/ant_fs/crc.h create mode 100644 components/ant/ant_fs/defines.h delete mode 100644 components/ant/ant_profiles/ant_bpwr/pages/logger/ant_bpwr_page_logger.h delete mode 100644 components/ant/ant_profiles/ant_bsc/pages/logger/ant_bsc_page_logger.h delete mode 100644 components/ant/ant_profiles/ant_common/pages/logger/ant_common_page_logger.h delete mode 100644 components/ant/ant_profiles/ant_hrm/pages/logger/ant_hrm_page_logger.h delete mode 100644 components/ant/ant_profiles/ant_sdm/pages/logger/ant_sdm_page_logger.h create mode 100644 components/ble/ble_dtm/ble_dtm_hw.h create mode 100644 components/ble/ble_dtm/ble_dtm_hw_nrf51.c create mode 100644 components/ble/ble_dtm/ble_dtm_hw_nrf52.c create mode 100644 components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c create mode 100644 components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h create mode 100644 components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c create mode 100644 components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h create mode 100644 components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c create mode 100644 components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h delete mode 100644 components/ble/ble_services/ble_ancs_c/ble_ancs_c.c delete mode 100644 components/ble/ble_services/ble_ancs_c/ble_ancs_c.h create mode 100644 components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c create mode 100644 components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h create mode 100644 components/ble/ble_services/ble_escs/escs_defs.h create mode 100644 components/ble/ble_services/ble_escs/nrf_ble_escs.c create mode 100644 components/ble/ble_services/ble_escs/nrf_ble_escs.h create mode 100644 components/ble/ble_services/ble_lbs_c/ble_lbs_c.c create mode 100644 components/ble/ble_services/ble_lbs_c/ble_lbs_c.h create mode 100644 components/ble/ble_services/experimental_ble_lns/ble_ln_common.h create mode 100644 components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c create mode 100644 components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h create mode 100644 components/ble/ble_services/experimental_ble_lns/ble_ln_db.c create mode 100644 components/ble/ble_services/experimental_ble_lns/ble_ln_db.h create mode 100644 components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.c create mode 100644 components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.h create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c create mode 100644 components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h delete mode 100644 components/ble/device_manager/config/device_manager_cnfg.h delete mode 100644 components/ble/device_manager/device_manager.h delete mode 100644 components/ble/device_manager/device_manager_central.c delete mode 100644 components/ble/device_manager/device_manager_peripheral.c create mode 100644 components/ble/nrf_ble_gatt/nrf_ble_gatt.c create mode 100644 components/ble/nrf_ble_gatt/nrf_ble_gatt.h create mode 100644 components/ble/nrf_ble_qwr/nrf_ble_qwr.c create mode 100644 components/ble/nrf_ble_qwr/nrf_ble_qwr.h delete mode 100644 components/ble/peer_manager/gattc_cache_manager.c delete mode 100644 components/ble/peer_manager/gattc_cache_manager.h create mode 100644 components/ble/peer_manager/peer_manager_internal.h create mode 100644 components/boards/arduino_primo.h create mode 100644 components/boards/boards.c create mode 100644 components/boards/boards.h create mode 100644 components/boards/d52_starterkit.h create mode 100644 components/boards/n5_starterkit.h create mode 100644 components/boards/nrf6310.h create mode 100644 components/boards/pca10000.h create mode 100644 components/boards/pca10001.h create mode 100644 components/boards/pca10003.h create mode 100644 components/boards/pca10028.h create mode 100644 components/boards/pca10031.h create mode 100644 components/boards/pca10036.h create mode 100644 components/boards/pca10040.h create mode 100644 components/boards/pca10056.h create mode 100644 components/boards/pca20006.h create mode 100644 components/boards/wt51822.h create mode 100644 components/device/nrf51422_peripherals.h create mode 100644 components/device/nrf51802_peripherals.h create mode 100644 components/device/nrf51822_peripherals.h create mode 100644 components/device/nrf51_to_nrf52840.h create mode 100644 components/device/nrf52832_peripherals.h create mode 100644 components/device/nrf52840.h create mode 100644 components/device/nrf52840_bitfields.h create mode 100644 components/device/nrf52840_peripherals.h create mode 100644 components/device/nrf52_name_change.h create mode 100644 components/device/nrf52_to_nrf52840.h create mode 100644 components/drivers_ext/max9850/max9850.c create mode 100644 components/drivers_ext/max9850/max9850.h create mode 100644 components/drivers_ext/mcp4725/mcp4725.c create mode 100644 components/drivers_ext/mcp4725/mcp4725.h create mode 100644 components/drivers_ext/segger_rtt/license/license.txt create mode 100644 components/drivers_ext/uda1380/uda1380.c create mode 100644 components/drivers_ext/uda1380/uda1380.h create mode 100644 components/drivers_nrf/adc/nrf_drv_adc.c create mode 100644 components/drivers_nrf/adc/nrf_drv_adc.h delete mode 100644 components/drivers_nrf/common/nrf_drv_validation.h create mode 100644 components/drivers_nrf/comp/nrf_drv_comp.c create mode 100644 components/drivers_nrf/comp/nrf_drv_comp.h delete mode 100644 components/drivers_nrf/config/nrf_drv_config.h delete mode 100644 components/drivers_nrf/config/nrf_drv_config_validation.h delete mode 100644 components/drivers_nrf/delay/nrf_delay.c create mode 100644 components/drivers_nrf/hal/nrf_comp.h create mode 100644 components/drivers_nrf/hal/nrf_i2s.h create mode 100644 components/drivers_nrf/hal/nrf_pdm.h create mode 100644 components/drivers_nrf/hal/nrf_peripherals.h create mode 100644 components/drivers_nrf/hal/nrf_power.h create mode 100644 components/drivers_nrf/hal/nrf_pwm.h create mode 100644 components/drivers_nrf/hal/nrf_qspi.h create mode 100644 components/drivers_nrf/hal/nrf_systick.h create mode 100644 components/drivers_nrf/hal/nrf_twim.h create mode 100644 components/drivers_nrf/hal/nrf_usbd.h create mode 100644 components/drivers_nrf/i2s/nrf_drv_i2s.c create mode 100644 components/drivers_nrf/i2s/nrf_drv_i2s.h create mode 100644 components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c create mode 100644 components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h create mode 100644 components/drivers_nrf/pdm/nrf_drv_pdm.c create mode 100644 components/drivers_nrf/pdm/nrf_drv_pdm.h create mode 100644 components/drivers_nrf/power/nrf_drv_power.c create mode 100644 components/drivers_nrf/power/nrf_drv_power.h delete mode 100644 components/drivers_nrf/pstorage/config/pstorage_platform.h delete mode 100644 components/drivers_nrf/pstorage/pstorage.c delete mode 100644 components/drivers_nrf/pstorage/pstorage.h delete mode 100644 components/drivers_nrf/pstorage/pstorage_nosd.c delete mode 100644 components/drivers_nrf/pstorage/pstorage_raw.c create mode 100644 components/drivers_nrf/pwm/nrf_drv_pwm.c create mode 100644 components/drivers_nrf/pwm/nrf_drv_pwm.h create mode 100644 components/drivers_nrf/qspi/nrf_drv_qspi.c create mode 100644 components/drivers_nrf/qspi/nrf_drv_qspi.h create mode 100644 components/drivers_nrf/saadc/nrf_drv_saadc.c create mode 100644 components/drivers_nrf/saadc/nrf_drv_saadc.h create mode 100644 components/drivers_nrf/systick/nrf_drv_systick.c create mode 100644 components/drivers_nrf/systick/nrf_drv_systick.h create mode 100644 components/drivers_nrf/twis_slave/nrf_drv_twis.c create mode 100644 components/drivers_nrf/twis_slave/nrf_drv_twis.h create mode 100644 components/drivers_nrf/twis_slave/nrf_drv_twis_inst.def create mode 100644 components/drivers_nrf/usbd/nrf_drv_usbd.c create mode 100644 components/drivers_nrf/usbd/nrf_drv_usbd.h delete mode 100644 components/libraries/ant_fs/crc.c delete mode 100644 components/libraries/ant_fs/crc.h delete mode 100644 components/libraries/ant_fs/defines.h create mode 100644 components/libraries/atomic/nrf_atomic.h create mode 100644 components/libraries/atomic/nrf_atomic_internal.h create mode 100644 components/libraries/atomic/nrf_atomic_sanity_check.h create mode 100644 components/libraries/atomic_fifo/app_atfifo.c create mode 100644 components/libraries/atomic_fifo/app_atfifo.h create mode 100644 components/libraries/atomic_fifo/app_atfifo_internal.h create mode 100644 components/libraries/balloc/nrf_balloc.c create mode 100644 components/libraries/balloc/nrf_balloc.h create mode 100644 components/libraries/block_dev/empty/nrf_block_dev_empty.c create mode 100644 components/libraries/block_dev/empty/nrf_block_dev_empty.h create mode 100644 components/libraries/block_dev/nrf_block_dev.h create mode 100644 components/libraries/block_dev/qspi/nrf_block_dev_qspi.c create mode 100644 components/libraries/block_dev/qspi/nrf_block_dev_qspi.h create mode 100644 components/libraries/block_dev/qspi/nrf_serial_flash_params.c create mode 100644 components/libraries/block_dev/qspi/nrf_serial_flash_params.h create mode 100644 components/libraries/block_dev/ram/nrf_block_dev_ram.c create mode 100644 components/libraries/block_dev/ram/nrf_block_dev_ram.h create mode 100644 components/libraries/block_dev/sdc/nrf_block_dev_sdc.c create mode 100644 components/libraries/block_dev/sdc/nrf_block_dev_sdc.h create mode 100644 components/libraries/bootloader/ble_dfu/nrf_ble_dfu.c create mode 100644 components/libraries/bootloader/ble_dfu/nrf_ble_dfu.h create mode 100644 components/libraries/bootloader/dfu/nrf_dfu.c create mode 100644 components/libraries/bootloader/dfu/nrf_dfu.h create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_flash.c create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_flash.h create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_mbr.c create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_mbr.h create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_req_handler.h create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_settings.c create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_settings.h create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_transport.c create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_transport.h create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_types.h create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_utils.c create mode 100644 components/libraries/bootloader/dfu/nrf_dfu_utils.h create mode 100644 components/libraries/bootloader/nrf_bootloader.c create mode 100644 components/libraries/bootloader/nrf_bootloader.h rename components/libraries/{bootloader_dfu/bootloader_util.c => bootloader/nrf_bootloader_app_start.c} (71%) create mode 100644 components/libraries/bootloader/nrf_bootloader_app_start.h create mode 100644 components/libraries/bootloader/nrf_bootloader_info.c create mode 100644 components/libraries/bootloader/nrf_bootloader_info.h delete mode 100644 components/libraries/bootloader_dfu/ble_transport/hci_mem_pool_internal.h delete mode 100644 components/libraries/bootloader_dfu/bootloader.c delete mode 100644 components/libraries/bootloader_dfu/bootloader.h delete mode 100644 components/libraries/bootloader_dfu/bootloader_settings.c delete mode 100644 components/libraries/bootloader_dfu/bootloader_settings.h delete mode 100644 components/libraries/bootloader_dfu/bootloader_types.h delete mode 100644 components/libraries/bootloader_dfu/bootloader_util.h delete mode 100644 components/libraries/bootloader_dfu/dfu.h delete mode 100644 components/libraries/bootloader_dfu/dfu_app_handler.c delete mode 100644 components/libraries/bootloader_dfu/dfu_app_handler.h delete mode 100644 components/libraries/bootloader_dfu/dfu_bank_internal.h delete mode 100644 components/libraries/bootloader_dfu/dfu_ble_svc.h delete mode 100644 components/libraries/bootloader_dfu/dfu_ble_svc_internal.h delete mode 100644 components/libraries/bootloader_dfu/dfu_dual_bank.c delete mode 100644 components/libraries/bootloader_dfu/dfu_init.h delete mode 100644 components/libraries/bootloader_dfu/dfu_init_template.c delete mode 100644 components/libraries/bootloader_dfu/dfu_single_bank.c delete mode 100644 components/libraries/bootloader_dfu/dfu_transport.h delete mode 100644 components/libraries/bootloader_dfu/dfu_transport_ble.c delete mode 100644 components/libraries/bootloader_dfu/dfu_transport_serial.c delete mode 100644 components/libraries/bootloader_dfu/dfu_types.h delete mode 100644 components/libraries/bootloader_dfu/experimental/dfu_init_template_signing.c delete mode 100644 components/libraries/bootloader_dfu/experimental/nrf_sec.h delete mode 100644 components/libraries/bootloader_dfu/hci_transport/hci_mem_pool_internal.h delete mode 100644 components/libraries/bootloader_dfu/hci_transport/hci_transport_config.h create mode 100644 components/libraries/bsp/bsp.c create mode 100644 components/libraries/bsp/bsp.h create mode 100644 components/libraries/bsp/bsp_btn_ant.c create mode 100644 components/libraries/bsp/bsp_btn_ant.h create mode 100644 components/libraries/bsp/bsp_btn_ble.c create mode 100644 components/libraries/bsp/bsp_btn_ble.h create mode 100644 components/libraries/bsp/bsp_config.h create mode 100644 components/libraries/bsp/bsp_nfc.c create mode 100644 components/libraries/bsp/bsp_nfc.h delete mode 100644 components/libraries/console/console.c delete mode 100644 components/libraries/console/console.h create mode 100644 components/libraries/crc32/crc32.c create mode 100644 components/libraries/crc32/crc32.h create mode 100644 components/libraries/crypto/nrf_crypto.c create mode 100644 components/libraries/crypto/nrf_crypto.h create mode 100644 components/libraries/crypto/nrf_crypto_svc.c create mode 100644 components/libraries/csense/nrf_csense.c create mode 100644 components/libraries/csense/nrf_csense.h create mode 100644 components/libraries/csense/nrf_csense_macros.h create mode 100644 components/libraries/csense_drv/nrf_drv_csense.c create mode 100644 components/libraries/csense_drv/nrf_drv_csense.h create mode 100644 components/libraries/ecc/ecc.c create mode 100644 components/libraries/ecc/ecc.h create mode 100644 components/libraries/eddystone/es.h create mode 100644 components/libraries/eddystone/es_adv.c create mode 100644 components/libraries/eddystone/es_adv.h create mode 100644 components/libraries/eddystone/es_adv_frame.c create mode 100644 components/libraries/eddystone/es_adv_frame.h create mode 100644 components/libraries/eddystone/es_adv_timing.c create mode 100644 components/libraries/eddystone/es_adv_timing.h create mode 100644 components/libraries/eddystone/es_adv_timing_resolver.c create mode 100644 components/libraries/eddystone/es_adv_timing_resolver.h create mode 100644 components/libraries/eddystone/es_battery_voltage.h create mode 100644 components/libraries/eddystone/es_battery_voltage_adc.c create mode 100644 components/libraries/eddystone/es_battery_voltage_saadc.c create mode 100644 components/libraries/eddystone/es_flash.c create mode 100644 components/libraries/eddystone/es_flash.h create mode 100644 components/libraries/eddystone/es_gatts.c create mode 100644 components/libraries/eddystone/es_gatts.h create mode 100644 components/libraries/eddystone/es_gatts_read.c create mode 100644 components/libraries/eddystone/es_gatts_read.h create mode 100644 components/libraries/eddystone/es_gatts_write.c create mode 100644 components/libraries/eddystone/es_gatts_write.h create mode 100644 components/libraries/eddystone/es_security.c create mode 100644 components/libraries/eddystone/es_security.h create mode 100644 components/libraries/eddystone/es_security_timing.c create mode 100644 components/libraries/eddystone/es_security_timing.h create mode 100644 components/libraries/eddystone/es_slot.c create mode 100644 components/libraries/eddystone/es_slot.h create mode 100644 components/libraries/eddystone/es_slot_reg.c create mode 100644 components/libraries/eddystone/es_slot_reg.h create mode 100644 components/libraries/eddystone/es_stopwatch.c create mode 100644 components/libraries/eddystone/es_stopwatch.h create mode 100644 components/libraries/eddystone/es_tlm.c create mode 100644 components/libraries/eddystone/es_tlm.h create mode 100644 components/libraries/eddystone/es_util.h create mode 100644 components/libraries/eddystone/nrf_ble_es.c create mode 100644 components/libraries/eddystone/nrf_ble_es.h delete mode 100644 components/libraries/fds/fds_config.h create mode 100644 components/libraries/fds/fds_internal_defs.h delete mode 100644 components/libraries/fds/fds_types_internal.h delete mode 100644 components/libraries/fstorage/fstorage_config.h create mode 100644 components/libraries/fstorage/fstorage_internal_defs.h delete mode 100644 components/libraries/gpiote/app_gpiote_fast_detect.c create mode 100644 components/libraries/hardfault/hardfault.h create mode 100644 components/libraries/hardfault/hardfault_implementation.c create mode 100644 components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c create mode 100644 components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c create mode 100644 components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c create mode 100644 components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c create mode 100644 components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c create mode 100644 components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c delete mode 100644 components/libraries/hci/config/hci_mem_pool_internal.h delete mode 100644 components/libraries/hci/config/hci_transport_config.h delete mode 100644 components/libraries/ic_info/nrf51_ic_info.c create mode 100644 components/libraries/ic_info/nrf_ic_info.c create mode 100644 components/libraries/log/nrf_log.h create mode 100644 components/libraries/log/nrf_log_backend.h create mode 100644 components/libraries/log/nrf_log_ctrl.h create mode 100644 components/libraries/log/src/nrf_log_backend_serial.c create mode 100644 components/libraries/log/src/nrf_log_ctrl_internal.h create mode 100644 components/libraries/log/src/nrf_log_frontend.c create mode 100644 components/libraries/log/src/nrf_log_internal.h create mode 100644 components/libraries/pwr_mgmt/nrf_pwr_mgmt.c create mode 100644 components/libraries/pwr_mgmt/nrf_pwr_mgmt.h create mode 100644 components/libraries/queue/nrf_queue.c create mode 100644 components/libraries/queue/nrf_queue.h create mode 100644 components/libraries/sdcard/app_sdcard.c create mode 100644 components/libraries/sdcard/app_sdcard.h create mode 100644 components/libraries/svc/nrf_svc_function.h create mode 100644 components/libraries/svc/nrf_svc_handler.c create mode 100644 components/libraries/svc/nrf_svci.h delete mode 100644 components/libraries/trace/app_trace.c delete mode 100644 components/libraries/trace/app_trace.h create mode 100644 components/libraries/usbd/app_usbd.c create mode 100644 components/libraries/usbd/app_usbd.h create mode 100644 components/libraries/usbd/app_usbd_class_base.h create mode 100644 components/libraries/usbd/app_usbd_core.c create mode 100644 components/libraries/usbd/app_usbd_core.h create mode 100644 components/libraries/usbd/app_usbd_descriptor.h create mode 100644 components/libraries/usbd/app_usbd_langid.h create mode 100644 components/libraries/usbd/app_usbd_request.h create mode 100644 components/libraries/usbd/app_usbd_string_desc.c create mode 100644 components/libraries/usbd/app_usbd_string_desc.h create mode 100644 components/libraries/usbd/app_usbd_types.h create mode 100644 components/libraries/usbd/class/audio/app_usbd_audio.c create mode 100644 components/libraries/usbd/class/audio/app_usbd_audio.h create mode 100644 components/libraries/usbd/class/audio/app_usbd_audio_desc.h create mode 100644 components/libraries/usbd/class/audio/app_usbd_audio_internal.h create mode 100644 components/libraries/usbd/class/audio/app_usbd_audio_types.h create mode 100644 components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c create mode 100644 components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h create mode 100644 components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h create mode 100644 components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h create mode 100644 components/libraries/usbd/class/cdc/app_usbd_cdc_types.h create mode 100644 components/libraries/usbd/class/hid/app_usbd_hid.c create mode 100644 components/libraries/usbd/class/hid/app_usbd_hid.h create mode 100644 components/libraries/usbd/class/hid/app_usbd_hid_types.h create mode 100644 components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c create mode 100644 components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h create mode 100644 components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h create mode 100644 components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h create mode 100644 components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c create mode 100644 components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h create mode 100644 components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h create mode 100644 components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h create mode 100644 components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c create mode 100644 components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h create mode 100644 components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h create mode 100644 components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h create mode 100644 components/libraries/usbd/class/msc/app_usbd_msc.c create mode 100644 components/libraries/usbd/class/msc/app_usbd_msc.h create mode 100644 components/libraries/usbd/class/msc/app_usbd_msc_desc.h create mode 100644 components/libraries/usbd/class/msc/app_usbd_msc_internal.h create mode 100644 components/libraries/usbd/class/msc/app_usbd_msc_scsi.h create mode 100644 components/libraries/usbd/class/msc/app_usbd_msc_types.h create mode 100644 components/libraries/usbd/config/app_usbd_string_config.h create mode 100644 components/libraries/util/app_error_weak.c create mode 100644 components/libraries/util/app_error_weak.h delete mode 100644 components/libraries/util/common.h create mode 100644 components/libraries/util/nrf_bitmask.h delete mode 100644 components/libraries/util/nrf_log.c delete mode 100644 components/libraries/util/nrf_log.h create mode 100644 components/libraries/util/sdk_errors.c create mode 100644 components/libraries/util/sdk_macros.h create mode 100644 components/nfc/experimental_t4t_lib/hal_t4t/hal_nfc_t4t.c create mode 100644 components/nfc/experimental_t4t_lib/hal_t4t/hal_nfc_t4t.h create mode 100644 components/nfc/experimental_t4t_lib/license.txt create mode 100644 components/nfc/experimental_t4t_lib/nfc_fixes.h create mode 100644 components/nfc/experimental_t4t_lib/nfc_t4t_lib.h create mode 100644 components/nfc/experimental_t4t_lib/nfc_t4t_lib_gcc.a create mode 100644 components/nfc/experimental_t4t_lib/nfc_t4t_lib_iar.a create mode 100644 components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c create mode 100644 components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h create mode 100644 components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c create mode 100644 components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h create mode 100644 components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c create mode 100644 components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h create mode 100644 components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c create mode 100644 components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h create mode 100644 components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c create mode 100644 components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h create mode 100644 components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c create mode 100644 components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h create mode 100644 components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c create mode 100644 components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h create mode 100644 components/nfc/ndef/generic/message/nfc_ndef_msg.c create mode 100644 components/nfc/ndef/generic/message/nfc_ndef_msg.h create mode 100644 components/nfc/ndef/generic/record/nfc_ndef_record.c create mode 100644 components/nfc/ndef/generic/record/nfc_ndef_record.h create mode 100644 components/nfc/ndef/launchapp/nfc_launchapp_msg.c create mode 100644 components/nfc/ndef/launchapp/nfc_launchapp_msg.h create mode 100644 components/nfc/ndef/launchapp/nfc_launchapp_rec.c create mode 100644 components/nfc/ndef/launchapp/nfc_launchapp_rec.h create mode 100644 components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c create mode 100644 components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h create mode 100644 components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c create mode 100644 components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h create mode 100644 components/nfc/ndef/parser/record/nfc_ndef_record_parser.c create mode 100644 components/nfc/ndef/parser/record/nfc_ndef_record_parser.h create mode 100644 components/nfc/ndef/text/nfc_text_rec.c create mode 100644 components/nfc/ndef/text/nfc_text_rec.h create mode 100644 components/nfc/ndef/uri/nfc_uri_msg.c create mode 100644 components/nfc/ndef/uri/nfc_uri_msg.h create mode 100644 components/nfc/ndef/uri/nfc_uri_rec.c create mode 100644 components/nfc/ndef/uri/nfc_uri_rec.h create mode 100644 components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c create mode 100644 components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h create mode 100644 components/nfc/t2t_lib/license.txt create mode 100644 components/nfc/t2t_lib/nfc_fixes.h create mode 100644 components/nfc/t2t_lib/nfc_t2t_lib.h create mode 100644 components/nfc/t2t_lib/nfc_t2t_lib_gcc.a create mode 100644 components/nfc/t2t_lib/nfc_t2t_lib_iar.a create mode 100644 components/nfc/t2t_parser/nfc_t2t_parser.c create mode 100644 components/nfc/t2t_parser/nfc_t2t_parser.h create mode 100644 components/nfc/t2t_parser/nfc_tlv_block.h create mode 100644 components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c create mode 100644 components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h create mode 100644 components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c create mode 100644 components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h create mode 100644 components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c create mode 100644 components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h create mode 100644 components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c create mode 100644 components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h delete mode 100644 components/properitary_rf/esb/arm/esb_arm.lib delete mode 100644 components/properitary_rf/esb/arm/esb_sd_resources_arm.lib delete mode 100644 components/properitary_rf/esb/gcc/esb_gcc.a delete mode 100644 components/properitary_rf/esb/gcc/esb_sd_resources_gcc.a delete mode 100644 components/properitary_rf/esb/iar/esb_iar.a delete mode 100644 components/properitary_rf/esb/iar/esb_sd_resource_iar.a delete mode 100644 components/properitary_rf/esb/nrf_esb.h delete mode 100644 components/properitary_rf/esb/nrf_esb_constants.h delete mode 100644 components/properitary_rf/esb/nrf_esb_resources.h delete mode 100644 components/properitary_rf/gzll/arm/gzll_arm.lib delete mode 100644 components/properitary_rf/gzll/arm/gzll_sd_resources_arm.lib delete mode 100644 components/properitary_rf/gzll/config/nrf_gzp_config.h delete mode 100644 components/properitary_rf/gzll/gcc/gzll_sd_resources_gcc.a delete mode 100644 components/properitary_rf/gzll/nrf_gzll_resources.h delete mode 100644 components/properitary_rf/gzll/nrf_gzp_host_nrf51.c create mode 100644 components/proprietary_rf/esb/nrf_esb.c create mode 100644 components/proprietary_rf/esb/nrf_esb.h create mode 100644 components/proprietary_rf/esb/nrf_esb_error_codes.h create mode 100644 components/proprietary_rf/esb/nrf_esb_resources.h create mode 100644 components/proprietary_rf/gzll/arm/license.txt create mode 100644 components/proprietary_rf/gzll/config/nrf_gzp_config.h rename components/{properitary_rf/gzll/gcc/gzll_gcc.a => proprietary_rf/gzll/gcc/gzll_nrf51_gcc.a} (100%) create mode 100644 components/proprietary_rf/gzll/gcc/gzll_nrf51_sd_resources_gcc.a create mode 100644 components/proprietary_rf/gzll/gcc/gzll_nrf52_gcc.a create mode 100644 components/proprietary_rf/gzll/gcc/gzll_nrf52_sd_resources_gcc.a create mode 100644 components/proprietary_rf/gzll/gcc/license.txt rename components/{properitary_rf/gzll/iar/gzll_iar.a => proprietary_rf/gzll/iar/gzll_nrf51_iar.a} (100%) rename components/{properitary_rf/gzll/iar/gzll_sd_resource_iar.a => proprietary_rf/gzll/iar/gzll_nrf51_sd_resource_iar.a} (100%) create mode 100644 components/proprietary_rf/gzll/iar/gzll_nrf52_iar.a create mode 100644 components/proprietary_rf/gzll/iar/gzll_nrf52_sd_resource_iar.a create mode 100644 components/proprietary_rf/gzll/iar/license.txt rename components/{properitary_rf => proprietary_rf}/gzll/nrf_gzll.h (84%) rename components/{properitary_rf => proprietary_rf}/gzll/nrf_gzll_constants.h (75%) create mode 100644 components/proprietary_rf/gzll/nrf_gzll_error.h create mode 100644 components/proprietary_rf/gzll/nrf_gzll_resources.h rename components/{properitary_rf => proprietary_rf}/gzll/nrf_gzp.c (67%) rename components/{properitary_rf => proprietary_rf}/gzll/nrf_gzp.h (83%) rename components/{properitary_rf => proprietary_rf}/gzll/nrf_gzp_device.c (82%) rename components/{properitary_rf => proprietary_rf}/gzll/nrf_gzp_host.c (79%) create mode 100644 components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c create mode 100644 components/sdk_validation.h delete mode 100644 components/serialization/application/codecs/s110/middleware/app_mw_ble.c delete mode 100644 components/serialization/application/codecs/s110/middleware/app_mw_ble_gap.c delete mode 100644 components/serialization/application/codecs/s110/middleware/app_mw_ble_gattc.c delete mode 100644 components/serialization/application/codecs/s110/middleware/app_mw_ble_l2cap.c delete mode 100644 components/serialization/application/codecs/s110/middleware/app_mw_nrf_soc.c delete mode 100644 components/serialization/application/codecs/s110/serializers/app_ble_gap_sec_keys.c delete mode 100644 components/serialization/application/codecs/s110/serializers/app_ble_gap_sec_keys.h delete mode 100644 components/serialization/application/codecs/s110/serializers/app_ble_user_mem.c delete mode 100644 components/serialization/application/codecs/s110/serializers/app_ble_user_mem.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_enable.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_event.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_evt_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_evt_tx_complete.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_evt_user_mem_release.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_evt_user_mem_request.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_address_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_address_set.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_adv_data_set.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_adv_start.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_adv_stop.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_appearance_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_appearance_set.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_auth_key_reply.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_authenticate.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_conn_param_update.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_conn_sec_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_connect.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_connect_cancel.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_device_name_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_device_name_set.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_disconnect.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_encrypt.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_adv_report.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_auth_key_request.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_auth_status.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_param_update.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_param_update_request.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_sec_update.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_connected.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_disconnected.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_passkey_display.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_rssi_changed.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_scan_req_report.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_info_request.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_params_request.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_request.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_evt_timeout.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_ppcp_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_ppcp_set.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_rssi_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_rssi_start.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_rssi_stop.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_scan_start.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_scan_stop.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_sec_info_reply.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_sec_params_reply.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gap_tx_power_set.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_char_value_by_uuid_read.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_char_values_read.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_characteristics_discover.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_descriptors_discover.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_vals_read_rsp.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_desc_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_hvx.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_read_rsp.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_rel_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_timeout.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_evt_write_rsp.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_hv_confirm.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_primary_services_discover.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_read.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_relationships_discover.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gattc_write.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_characteristic_add.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_descriptor_add.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_evt_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_evt_hvc.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_evt_rw_authorize_request.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_evt_sc_confirm.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_evt_sys_attr_missing.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_evt_timeout.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_evt_write.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_hvx.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_include_add.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_rw_authorize_reply.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_service_add.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_service_changed.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_sys_attr_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_sys_attr_set.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_value_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_gatts_value_set.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_l2cap_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_l2cap_cid_register.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_l2cap_cid_unregister.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_l2cap_evt_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_l2cap_evt_rx.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_l2cap_tx.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_opt_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_opt_set.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_tx_buffer_count_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_user_mem_reply.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_uuid_decode.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_uuid_encode.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_uuid_vs_add.c delete mode 100644 components/serialization/application/codecs/s110/serializers/ble_version_get.c delete mode 100644 components/serialization/application/codecs/s110/serializers/nrf_soc_app.h delete mode 100644 components/serialization/application/codecs/s110/serializers/power_system_off.c delete mode 100644 components/serialization/application/codecs/s110/serializers/temp_get.c delete mode 100644 components/serialization/application/codecs/s120/middleware/app_mw_ble.c delete mode 100644 components/serialization/application/codecs/s120/middleware/app_mw_ble_gap.c delete mode 100644 components/serialization/application/codecs/s120/middleware/app_mw_ble_gattc.c delete mode 100644 components/serialization/application/codecs/s120/middleware/app_mw_ble_gatts.c delete mode 100644 components/serialization/application/codecs/s120/middleware/app_mw_ble_l2cap.c delete mode 100644 components/serialization/application/codecs/s120/middleware/app_mw_nrf_soc.c delete mode 100644 components/serialization/application/codecs/s120/serializers/app_ble_gap_sec_keys.c delete mode 100644 components/serialization/application/codecs/s120/serializers/app_ble_gap_sec_keys.h delete mode 100644 components/serialization/application/codecs/s120/serializers/app_ble_user_mem.c delete mode 100644 components/serialization/application/codecs/s120/serializers/app_ble_user_mem.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_enable.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_event.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_evt_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_evt_tx_complete.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_evt_user_mem_release.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_evt_user_mem_request.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_address_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_address_set.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_adv_data_set.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_adv_start.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_adv_stop.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_appearance_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_appearance_set.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_auth_key_reply.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_authenticate.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_conn_param_update.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_conn_sec_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_connect.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_connect_cancel.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_device_name_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_device_name_set.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_disconnect.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_encrypt.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_adv_report.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_auth_key_request.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_auth_status.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_param_update.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_param_update_request.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_sec_update.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_connected.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_disconnected.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_passkey_display.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_rssi_changed.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_scan_req_report.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_info_request.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_params_request.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_request.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_evt_timeout.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_ppcp_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_ppcp_set.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_rssi_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_rssi_start.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_rssi_stop.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_scan_start.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_scan_stop.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_sec_info_reply.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_sec_params_reply.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gap_tx_power_set.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_char_value_by_uuid_read.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_char_values_read.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_characteristics_discover.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_descriptors_discover.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_vals_read_rsp.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_desc_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_hvx.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_read_rsp.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_rel_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_timeout.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_evt_write_rsp.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_hv_confirm.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_primary_services_discover.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_read.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_relationships_discover.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gattc_write.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_characteristic_add.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_descriptor_add.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_evt_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_evt_hvc.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_evt_rw_authorize_request.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_evt_sc_confirm.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_evt_sys_attr_missing.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_evt_timeout.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_evt_write.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_hvx.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_include_add.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_rw_authorize_reply.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_service_add.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_service_changed.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_sys_attr_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_sys_attr_set.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_value_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_gatts_value_set.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_l2cap_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_l2cap_cid_register.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_l2cap_cid_unregister.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_l2cap_evt_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_l2cap_evt_rx.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_l2cap_tx.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_opt_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_opt_set.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_tx_buffer_count_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_user_mem_reply.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_uuid_decode.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_uuid_encode.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_uuid_vs_add.c delete mode 100644 components/serialization/application/codecs/s120/serializers/ble_version_get.c delete mode 100644 components/serialization/application/codecs/s120/serializers/nrf_soc_app.h delete mode 100644 components/serialization/application/codecs/s120/serializers/power_system_off.c delete mode 100644 components/serialization/application/codecs/s120/serializers/temp_get.c delete mode 100644 components/serialization/application/codecs/s130/middleware/app_mw_ble_gatts.c delete mode 100644 components/serialization/application/codecs/s130/middleware/app_mw_nrf_soc.c delete mode 100644 components/serialization/application/codecs/s130/serializers/app_ble_gap_sec_keys.c delete mode 100644 components/serialization/application/codecs/s130/serializers/app_ble_gap_sec_keys.h delete mode 100644 components/serialization/application/codecs/s130/serializers/app_ble_user_mem.c delete mode 100644 components/serialization/application/codecs/s130/serializers/app_ble_user_mem.h delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_enable.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_event.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_evt_app.h delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_evt_tx_complete.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_evt_user_mem_release.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_evt_user_mem_request.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_address_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_address_set.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_adv_data_set.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_adv_start.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_adv_stop.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_appearance_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_appearance_set.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_auth_key_reply.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_authenticate.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_conn_param_update.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_conn_sec_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_connect.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_connect_cancel.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_device_name_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_device_name_set.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_disconnect.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_encrypt.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_adv_report.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_auth_key_request.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_auth_status.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_param_update.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_param_update_request.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_sec_update.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_connected.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_disconnected.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_passkey_display.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_rssi_changed.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_scan_req_report.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_info_request.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_params_request.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_request.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_evt_timeout.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_ppcp_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_ppcp_set.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_rssi_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_rssi_start.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_rssi_stop.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_scan_start.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_scan_stop.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_sec_info_reply.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_sec_params_reply.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gap_tx_power_set.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_char_value_by_uuid_read.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_char_values_read.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_characteristics_discover.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_descriptors_discover.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_vals_read_rsp.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_evt_desc_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_evt_hvx.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_evt_read_rsp.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_evt_rel_disc_rsp.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_evt_timeout.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_evt_write_rsp.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_hv_confirm.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_primary_services_discover.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_read.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_relationships_discover.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gattc_write.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_characteristic_add.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_descriptor_add.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_evt_hvc.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_evt_rw_authorize_request.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_evt_sc_confirm.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_evt_sys_attr_missing.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_evt_timeout.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_evt_write.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_hvx.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_include_add.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_rw_authorize_reply.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_service_add.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_service_changed.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_sys_attr_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_sys_attr_set.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_value_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_gatts_value_set.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_l2cap_cid_register.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_l2cap_cid_unregister.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_l2cap_evt_app.h delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_l2cap_evt_rx.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_l2cap_tx.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_opt_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_opt_set.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_tx_buffer_count_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_user_mem_reply.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_uuid_decode.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_uuid_encode.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_uuid_vs_add.c delete mode 100644 components/serialization/application/codecs/s130/serializers/ble_version_get.c delete mode 100644 components/serialization/application/codecs/s130/serializers/nrf_soc_app.h delete mode 100644 components/serialization/application/codecs/s130/serializers/power_system_off.c delete mode 100644 components/serialization/application/codecs/s130/serializers/temp_get.c rename components/serialization/application/codecs/{s130 => s132}/middleware/app_mw_ble.c (79%) rename components/serialization/application/codecs/{s130 => s132}/middleware/app_mw_ble_gap.c (67%) rename components/serialization/application/codecs/{s130 => s132}/middleware/app_mw_ble_gattc.c (67%) rename components/serialization/application/codecs/{s110 => s132}/middleware/app_mw_ble_gatts.c (67%) rename components/serialization/application/codecs/{s130 => s132}/middleware/app_mw_ble_l2cap.c (65%) create mode 100644 components/serialization/application/codecs/s132/middleware/app_mw_nrf_soc.c create mode 100644 components/serialization/application/codecs/s132/serializers/app_ble_gap_sec_keys.c create mode 100644 components/serialization/application/codecs/s132/serializers/app_ble_gap_sec_keys.h create mode 100644 components/serialization/application/codecs/s132/serializers/app_ble_user_mem.c create mode 100644 components/serialization/application/codecs/s132/serializers/app_ble_user_mem.h create mode 100644 components/serialization/application/codecs/s132/serializers/ble_app.c rename components/serialization/application/codecs/{s130 => s132}/serializers/ble_app.h (58%) create mode 100644 components/serialization/application/codecs/s132/serializers/ble_event.c create mode 100644 components/serialization/application/codecs/s132/serializers/ble_evt_app.c create mode 100644 components/serialization/application/codecs/s132/serializers/ble_evt_app.h create mode 100644 components/serialization/application/codecs/s132/serializers/ble_gap_app.c rename components/serialization/application/codecs/{s130 => s132}/serializers/ble_gap_app.h (63%) create mode 100644 components/serialization/application/codecs/s132/serializers/ble_gap_evt_app.c rename components/serialization/application/codecs/{s130 => s132}/serializers/ble_gap_evt_app.h (80%) create mode 100644 components/serialization/application/codecs/s132/serializers/ble_gattc_app.c rename components/serialization/application/codecs/{s130 => s132}/serializers/ble_gattc_app.h (67%) create mode 100644 components/serialization/application/codecs/s132/serializers/ble_gattc_evt_app.c rename components/serialization/application/codecs/{s130 => s132}/serializers/ble_gattc_evt_app.h (73%) create mode 100644 components/serialization/application/codecs/s132/serializers/ble_gatts_app.c rename components/serialization/application/codecs/{s130 => s132}/serializers/ble_gatts_app.h (71%) create mode 100644 components/serialization/application/codecs/s132/serializers/ble_gatts_evt_app.c rename components/serialization/application/codecs/{s130 => s132}/serializers/ble_gatts_evt_app.h (70%) create mode 100644 components/serialization/application/codecs/s132/serializers/ble_l2cap_app.c rename components/serialization/application/codecs/{s130 => s132}/serializers/ble_l2cap_app.h (64%) create mode 100644 components/serialization/application/codecs/s132/serializers/ble_l2cap_evt_app.c create mode 100644 components/serialization/application/codecs/s132/serializers/ble_l2cap_evt_app.h create mode 100644 components/serialization/application/codecs/s132/serializers/nrf_soc_app.c create mode 100644 components/serialization/application/codecs/s132/serializers/nrf_soc_app.h delete mode 100644 components/serialization/application/hal/ser_app_hal_nrf51.c create mode 100644 components/serialization/application/hal/ser_app_hal_nrf5x.c create mode 100644 components/serialization/common/ser_dbg_sd_str.c create mode 100644 components/serialization/common/ser_dbg_sd_str.h delete mode 100644 components/serialization/common/struct_ser/s110/ble_gap_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s110/ble_gap_struct_serialization.h delete mode 100644 components/serialization/common/struct_ser/s110/ble_gattc_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s110/ble_gattc_struct_serialization.h delete mode 100644 components/serialization/common/struct_ser/s110/ble_gatts_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s110/ble_gatts_struct_serialization.h delete mode 100644 components/serialization/common/struct_ser/s110/ble_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s110/ble_struct_serialization.h delete mode 100644 components/serialization/common/struct_ser/s120/ble_gap_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s120/ble_gap_struct_serialization.h delete mode 100644 components/serialization/common/struct_ser/s120/ble_gattc_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s120/ble_gattc_struct_serialization.h delete mode 100644 components/serialization/common/struct_ser/s120/ble_gatts_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s120/ble_gatts_struct_serialization.h delete mode 100644 components/serialization/common/struct_ser/s120/ble_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s120/ble_struct_serialization.h delete mode 100644 components/serialization/common/struct_ser/s130/ble_gap_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s130/ble_gattc_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s130/ble_gattc_struct_serialization.h delete mode 100644 components/serialization/common/struct_ser/s130/ble_gatts_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s130/ble_gatts_struct_serialization.h delete mode 100644 components/serialization/common/struct_ser/s130/ble_struct_serialization.c delete mode 100644 components/serialization/common/struct_ser/s130/ble_struct_serialization.h create mode 100644 components/serialization/common/struct_ser/s132/ble_gap_struct_serialization.c rename components/serialization/common/struct_ser/{s130 => s132}/ble_gap_struct_serialization.h (54%) create mode 100644 components/serialization/common/struct_ser/s132/ble_gatt_struct_serialization.c create mode 100644 components/serialization/common/struct_ser/s132/ble_gatt_struct_serialization.h create mode 100644 components/serialization/common/struct_ser/s132/ble_gattc_struct_serialization.c create mode 100644 components/serialization/common/struct_ser/s132/ble_gattc_struct_serialization.h create mode 100644 components/serialization/common/struct_ser/s132/ble_gatts_struct_serialization.c create mode 100644 components/serialization/common/struct_ser/s132/ble_gatts_struct_serialization.h create mode 100644 components/serialization/common/struct_ser/s132/ble_struct_serialization.c create mode 100644 components/serialization/common/struct_ser/s132/ble_struct_serialization.h create mode 100644 components/serialization/common/struct_ser/s132/nrf_soc_struct_serialization.c create mode 100644 components/serialization/common/struct_ser/s132/nrf_soc_struct_serialization.h delete mode 100644 components/serialization/common/transport/debug/debug_hci_config_nrf6310.h delete mode 100644 components/serialization/common/transport/debug/debug_hci_nrf6310.c rename components/serialization/common/transport/ser_phy/config/{ser_phy_config_app_nrf51.h => ser_phy_config_app.h} (54%) create mode 100644 components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h delete mode 100644 components/serialization/common/transport/ser_phy/config/ser_phy_config_conn_nrf51.h delete mode 100644 components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_app.c delete mode 100644 components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_conn.c rename components/serialization/common/transport/ser_phy/{ser_phy_nrf51_spi_5W_master.c => ser_phy_spi_5W_master.c} (86%) rename components/serialization/common/transport/ser_phy/{ser_phy_nrf51_spi_5W_slave.c => ser_phy_spi_5W_slave.c} (87%) rename components/serialization/common/transport/ser_phy/{ser_phy_nrf51_nrf_drv_spi.c => ser_phy_spi_master.c} (87%) rename components/serialization/common/transport/ser_phy/{ser_phy_nrf51_spi_slave.c => ser_phy_spi_slave.c} (89%) rename components/serialization/common/transport/ser_phy/{ser_phy_nrf51_uart.c => ser_phy_uart.c} (84%) delete mode 100644 components/serialization/common/transport/ser_phy/spi_5W_master.c delete mode 100644 components/serialization/common/transport/ser_phy/spi_5W_master.h delete mode 100644 components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble.h delete mode 100644 components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gap.c delete mode 100644 components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gap.h delete mode 100644 components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gattc.c delete mode 100644 components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gattc.h delete mode 100644 components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_l2cap.c delete mode 100644 components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_l2cap.h delete mode 100644 components/serialization/connectivity/codecs/s110/middleware/conn_mw_items.c delete mode 100644 components/serialization/connectivity/codecs/s110/middleware/conn_mw_nrf_soc.c delete mode 100644 components/serialization/connectivity/codecs/s110/middleware/conn_mw_nrf_soc.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_conn.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_enable.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_event.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_evt_tx_complete.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_evt_user_mem_release.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_evt_user_mem_request.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_address_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_address_set.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_data_set.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_start.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_stop.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_appearance_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_appearance_set.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_auth_key_reply.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_authenticate.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn_param_update.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn_sec_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_connect.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_connect_cancel.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_device_name_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_device_name_set.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_disconnect.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_encrypt.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_adv_report.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_auth_key_request.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_auth_status.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_param_update.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_param_update_request.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_sec_update.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_connected.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_disconnected.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_passkey_display.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_rssi_changed.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_scan_req_report.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_info_request.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_params_request.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_request.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_timeout.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_ppcp_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_ppcp_set.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_start.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_stop.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_scan_start.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_scan_stop.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_sec_info_reply.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_sec_params_reply.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gap_tx_power_set.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_char_value_by_uuid_read.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_char_values_read.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_characteristics_discover.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_conn.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_descriptors_discover.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_vals_read_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_desc_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_hvx.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_read_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_rel_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_timeout.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_write_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_hv_confirm.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_primary_services_discover.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_read.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_relationships_discover.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gattc_write.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_characteristic_add.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_descriptor_add.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_hvc.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_rw_authorize_request.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_sc_confirm.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_sys_attr_missing.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_timeout.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_write.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_hvx.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_include_add.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_rw_authorize_reply.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_service_add.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_service_changed.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_sys_attr_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_sys_attr_set.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_value_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_gatts_value_set.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_cid_register.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_cid_unregister.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_conn.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_evt_rx.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_tx.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_opt_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_opt_id_pre_decoder.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_opt_set.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_tx_buffer_count_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_user_mem_reply.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_uuid_decode.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_uuid_encode.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_uuid_vs_add.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/ble_version_get.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/conn_ble_gap_sec_keys.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/conn_ble_gap_sec_keys.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/conn_ble_user_mem.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/conn_ble_user_mem.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/nrf_soc_conn.h delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/power_system_off.c delete mode 100644 components/serialization/connectivity/codecs/s110/serializers/temp_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/middleware/conn_mw.h delete mode 100644 components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble.c delete mode 100644 components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gap.c delete mode 100644 components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gatts.c delete mode 100644 components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gatts.h delete mode 100644 components/serialization/connectivity/codecs/s120/middleware/conn_mw_nrf_soc.c delete mode 100644 components/serialization/connectivity/codecs/s120/middleware/conn_mw_nrf_soc.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_enable.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_evt_tx_complete.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_evt_user_mem_release.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_evt_user_mem_request.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_address_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_address_set.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_data_set.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_start.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_stop.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_appearance_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_appearance_set.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_auth_key_reply.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_authenticate.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn_param_update.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn_sec_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_connect.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_connect_cancel.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_device_name_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_device_name_set.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_disconnect.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_encrypt.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_adv_report.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_auth_key_request.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_auth_status.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_param_update.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_param_update_request.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_sec_update.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_connected.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_disconnected.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_passkey_display.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_rssi_changed.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_scan_req_report.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_info_request.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_params_request.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_request.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_timeout.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_ppcp_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_ppcp_set.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_start.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_stop.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_scan_start.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_scan_stop.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_sec_info_reply.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_sec_params_reply.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gap_tx_power_set.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_char_value_by_uuid_read.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_char_values_read.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_characteristics_discover.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_descriptors_discover.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_vals_read_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_desc_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_hvx.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_read_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_rel_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_timeout.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_write_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_hv_confirm.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_primary_services_discover.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_read.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_relationships_discover.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gattc_write.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_characteristic_add.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_descriptor_add.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_hvc.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_rw_authorize_request.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_sc_confirm.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_sys_attr_missing.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_timeout.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_write.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_hvx.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_include_add.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_rw_authorize_reply.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_service_add.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_service_changed.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_sys_attr_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_sys_attr_set.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_value_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_gatts_value_set.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_cid_register.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_cid_unregister.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_evt_rx.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_tx.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_opt_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_opt_id_pre_decoder.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_opt_set.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_tx_buffer_count_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_user_mem_reply.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_uuid_decode.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_uuid_encode.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_uuid_vs_add.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/ble_version_get.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/conn_ble_gap_sec_keys.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/conn_ble_gap_sec_keys.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/conn_ble_user_mem.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/conn_ble_user_mem.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/nrf_soc_conn.h delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/power_system_off.c delete mode 100644 components/serialization/connectivity/codecs/s120/serializers/temp_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw.h delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble.c delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble.h delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gap.h delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gattc.c delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gattc.h delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gatts.c delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gatts.h delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_l2cap.c delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_l2cap.h delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_items.c delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_nrf_soc.c delete mode 100644 components/serialization/connectivity/codecs/s130/middleware/conn_mw_nrf_soc.h delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_enable.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_event.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_evt_tx_complete.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_evt_user_mem_release.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_evt_user_mem_request.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_address_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_address_set.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_data_set.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_start.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_stop.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_appearance_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_appearance_set.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_auth_key_reply.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_authenticate.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn_param_update.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn_sec_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_connect.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_connect_cancel.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_device_name_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_device_name_set.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_disconnect.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_encrypt.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_adv_report.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_auth_key_request.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_auth_status.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_param_update.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_param_update_request.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_sec_update.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_connected.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_disconnected.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_passkey_display.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_rssi_changed.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_scan_req_report.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_info_request.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_params_request.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_request.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_timeout.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_ppcp_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_ppcp_set.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_start.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_stop.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_scan_start.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_scan_stop.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_sec_info_reply.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_sec_params_reply.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gap_tx_power_set.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_char_value_by_uuid_read.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_char_values_read.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_characteristics_discover.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_descriptors_discover.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_vals_read_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_desc_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_hvx.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_read_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_rel_disc_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_timeout.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_write_rsp.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_hv_confirm.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_primary_services_discover.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_read.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_relationships_discover.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gattc_write.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_characteristic_add.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_conn.h delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_descriptor_add.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_hvc.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_rw_authorize_request.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_sc_confirm.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_sys_attr_missing.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_timeout.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_write.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_hvx.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_include_add.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_rw_authorize_reply.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_service_add.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_service_changed.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_sys_attr_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_sys_attr_set.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_value_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_gatts_value_set.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_cid_register.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_cid_unregister.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_evt_conn.h delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_evt_rx.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_tx.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_opt_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_opt_id_pre_decoder.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_opt_set.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_tx_buffer_count_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_user_mem_reply.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_uuid_decode.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_uuid_encode.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_uuid_vs_add.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/ble_version_get.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/conn_ble_gap_sec_keys.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/conn_ble_gap_sec_keys.h delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/conn_ble_user_mem.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/conn_ble_user_mem.h delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/nrf_soc_conn.h delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/power_system_off.c delete mode 100644 components/serialization/connectivity/codecs/s130/serializers/temp_get.c create mode 100644 components/serialization/connectivity/codecs/s132/middleware/conn_mw.h rename components/serialization/connectivity/codecs/{s110 => s132}/middleware/conn_mw_ble.c (64%) rename components/serialization/connectivity/codecs/{s120 => s132}/middleware/conn_mw_ble.h (79%) rename components/serialization/connectivity/codecs/{s130 => s132}/middleware/conn_mw_ble_gap.c (65%) rename components/serialization/connectivity/codecs/{s120 => s132}/middleware/conn_mw_ble_gap.h (70%) rename components/serialization/connectivity/codecs/{s120 => s132}/middleware/conn_mw_ble_gattc.c (72%) rename components/serialization/connectivity/codecs/{s120 => s132}/middleware/conn_mw_ble_gattc.h (69%) rename components/serialization/connectivity/codecs/{s110 => s132}/middleware/conn_mw_ble_gatts.c (72%) rename components/serialization/connectivity/codecs/{s110 => s132}/middleware/conn_mw_ble_gatts.h (68%) rename components/serialization/connectivity/codecs/{s120 => s132}/middleware/conn_mw_ble_l2cap.c (57%) rename components/serialization/connectivity/codecs/{s120 => s132}/middleware/conn_mw_ble_l2cap.h (59%) rename components/serialization/connectivity/codecs/{s120 => s132}/middleware/conn_mw_items.c (55%) create mode 100644 components/serialization/connectivity/codecs/s132/middleware/conn_mw_nrf_soc.c create mode 100644 components/serialization/connectivity/codecs/s132/middleware/conn_mw_nrf_soc.h create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_conn.c rename components/serialization/connectivity/codecs/{s130 => s132}/serializers/ble_conn.h (82%) rename components/serialization/connectivity/codecs/{s120/serializers/ble_event.c => s132/serializers/ble_event_enc.c} (67%) create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_evt_conn.c rename components/serialization/connectivity/codecs/{s130 => s132}/serializers/ble_evt_conn.h (50%) create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_gap_conn.c rename components/serialization/connectivity/codecs/{s130 => s132}/serializers/ble_gap_conn.h (67%) create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_gap_evt_conn.c rename components/serialization/connectivity/codecs/{s130 => s132}/serializers/ble_gap_evt_conn.h (78%) create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_gattc_conn.c rename components/serialization/connectivity/codecs/{s130 => s132}/serializers/ble_gattc_conn.h (69%) create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_gattc_evt_conn.c rename components/serialization/connectivity/codecs/{s130 => s132}/serializers/ble_gattc_evt_conn.h (71%) create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_gatts_conn.c rename components/serialization/connectivity/codecs/{s110 => s132}/serializers/ble_gatts_conn.h (67%) create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_gatts_evt_conn.c rename components/serialization/connectivity/codecs/{s130 => s132}/serializers/ble_gatts_evt_conn.h (66%) create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_conn.c rename components/serialization/connectivity/codecs/{s130 => s132}/serializers/ble_l2cap_conn.h (67%) create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_evt_conn.c create mode 100644 components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_evt_conn.h create mode 100644 components/serialization/connectivity/codecs/s132/serializers/conn_ble_gap_sec_keys.c create mode 100644 components/serialization/connectivity/codecs/s132/serializers/conn_ble_gap_sec_keys.h create mode 100644 components/serialization/connectivity/codecs/s132/serializers/conn_ble_user_mem.c create mode 100644 components/serialization/connectivity/codecs/s132/serializers/conn_ble_user_mem.h create mode 100644 components/serialization/connectivity/codecs/s132/serializers/nrf_soc_conn.c create mode 100644 components/serialization/connectivity/codecs/s132/serializers/nrf_soc_conn.h create mode 100644 components/softdevice/common/softdevice_handler/app_ram_base.h delete mode 100644 components/softdevice/s110/doc/s110_nrf51822_8.0.0_migration_document.pdf delete mode 100644 components/softdevice/s110/doc/s110_nrf51_8.0.0_licence-agreement.pdf delete mode 100644 components/softdevice/s110/doc/s110_nrf51_8.0.0_readme.txt delete mode 100644 components/softdevice/s110/doc/s110_nrf51_8.0.0_release-notes.pdf delete mode 100644 components/softdevice/s110/headers/ble.h delete mode 100644 components/softdevice/s110/headers/ble_err.h delete mode 100644 components/softdevice/s110/headers/ble_gap.h delete mode 100644 components/softdevice/s110/headers/ble_gattc.h delete mode 100644 components/softdevice/s110/headers/ble_gatts.h delete mode 100644 components/softdevice/s110/headers/ble_l2cap.h delete mode 100644 components/softdevice/s110/headers/ble_ranges.h delete mode 100644 components/softdevice/s110/headers/ble_types.h delete mode 100644 components/softdevice/s110/headers/nrf_error.h delete mode 100644 components/softdevice/s110/headers/nrf_error_sdm.h delete mode 100644 components/softdevice/s110/headers/nrf_sd_def.h delete mode 100644 components/softdevice/s110/headers/nrf_sdm.h delete mode 100644 components/softdevice/s110/headers/softdevice_assert.h delete mode 100644 components/softdevice/s110/hex/s110_nrf51_8.0.0_softdevice.hex delete mode 100644 components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51422_xxaa.ld delete mode 100644 components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51422_xxac.ld delete mode 100644 components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51822_xxaa.ld delete mode 100644 components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51822_xxab.ld delete mode 100644 components/softdevice/s110/toolchain/iar/iar_s110_nrf51822_xxab.icf delete mode 100644 components/softdevice/s120/doc/s120_nrf51_2.1.0_licence_agreement.pdf delete mode 100644 components/softdevice/s120/doc/s120_nrf51_2.1.0_readme.txt delete mode 100644 components/softdevice/s120/doc/s120_nrf51_2.1.0_releasenotes.pdf delete mode 100644 components/softdevice/s120/headers/ble.h delete mode 100644 components/softdevice/s120/headers/ble_gap.h delete mode 100644 components/softdevice/s120/headers/ble_gatt.h delete mode 100644 components/softdevice/s120/headers/ble_gattc.h delete mode 100644 components/softdevice/s120/headers/ble_gatts.h delete mode 100644 components/softdevice/s120/headers/ble_hci.h delete mode 100644 components/softdevice/s120/headers/ble_l2cap.h delete mode 100644 components/softdevice/s120/headers/nrf_error_sdm.h delete mode 100644 components/softdevice/s120/headers/nrf_error_soc.h delete mode 100644 components/softdevice/s120/headers/nrf_mbr.h delete mode 100644 components/softdevice/s120/headers/nrf_sd_def.h delete mode 100644 components/softdevice/s120/headers/nrf_sdm.h delete mode 100644 components/softdevice/s120/headers/nrf_soc.h delete mode 100644 components/softdevice/s120/headers/nrf_svc.h delete mode 100644 components/softdevice/s120/headers/softdevice_assert.h delete mode 100644 components/softdevice/s120/hex/s120_nrf51_2.1.0_softdevice.hex delete mode 100644 components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51422_xxaa.ld delete mode 100644 components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51422_xxac.ld delete mode 100644 components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51822_xxaa.ld delete mode 100644 components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51822_xxab.ld delete mode 100644 components/softdevice/s120/toolchain/iar/iar_s120_nrf51422_xxaa.icf delete mode 100644 components/softdevice/s120/toolchain/iar/iar_s120_nrf51422_xxac.icf delete mode 100644 components/softdevice/s120/toolchain/iar/iar_s120_nrf51822_xxaa.icf delete mode 100644 components/softdevice/s120/toolchain/iar/iar_s120_nrf51822_xxab.icf delete mode 100644 components/softdevice/s130/doc/s130_nrf51822_1.0.0_licence_agreement.pdf delete mode 100644 components/softdevice/s130/doc/s130_nrf51822_1.0.0_readme.txt delete mode 100644 components/softdevice/s130/doc/s130_nrf51822_1.0.0_releasenotes.pdf create mode 100644 components/softdevice/s130/doc/s130_nrf51822_2.0.1_licence_agreement.pdf create mode 100644 components/softdevice/s130/doc/s130_nrf51822_2.0.1_readme.txt create mode 100644 components/softdevice/s130/doc/s130_nrf51822_2.0.1_releasenotes.pdf rename components/softdevice/s130/doc/{s130_nrf51822_1.0.0_licence_agreement.txt => s130_nrf51_2.0.1_licence_agreement.txt} (71%) create mode 100644 components/softdevice/s130/doc/s13x_nrf5x_2.0.1_migration_document.pdf rename components/softdevice/s130/headers/{ => nrf51}/nrf_mbr.h (95%) create mode 100644 components/softdevice/s130/headers/nrf_nvic.h delete mode 100644 components/softdevice/s130/headers/softdevice_assert.h delete mode 100644 components/softdevice/s130/hex/s130_nrf51_1.0.0_softdevice.hex rename components/softdevice/{s120/doc/s120_nrf51822_2.0.0_licence_agreement.txt => s130/hex/s130_nrf51_2.0.1_licence-agreement.txt} (71%) create mode 100644 components/softdevice/s132/doc/s132_nrf52_3.0.0_licence_agreement.pdf rename components/softdevice/{s110/doc/s110_nrf51_8.0.0_licence-agreement.txt => s132/doc/s132_nrf52_3.0.0_licence_agreement.txt} (71%) create mode 100644 components/softdevice/s132/doc/s132_nrf52_3.0.0_migration_document.pdf create mode 100644 components/softdevice/s132/doc/s132_nrf52_3.0.0_readme.txt create mode 100644 components/softdevice/s132/doc/s132_nrf52_3.0.0_releasenotes.pdf create mode 100644 components/softdevice/s132/headers/ble.h rename components/softdevice/{s120 => s132}/headers/ble_err.h (94%) rename components/softdevice/{s310 => s132}/headers/ble_gap.h (55%) rename components/softdevice/{s110 => s132}/headers/ble_gatt.h (90%) rename components/softdevice/{s310 => s132}/headers/ble_gattc.h (59%) rename components/softdevice/{s310 => s132}/headers/ble_gatts.h (76%) rename components/softdevice/{s110 => s132}/headers/ble_hci.h (98%) rename components/softdevice/{s310 => s132}/headers/ble_l2cap.h (88%) rename components/softdevice/{s120 => s132}/headers/ble_ranges.h (75%) rename components/softdevice/{s120 => s132}/headers/ble_types.h (96%) rename components/softdevice/{s110/headers => s132/headers/nrf52}/nrf_mbr.h (76%) rename components/softdevice/{s120 => s132}/headers/nrf_error.h (92%) rename components/softdevice/{s210 => s132}/headers/nrf_error_sdm.h (97%) rename components/softdevice/{s110 => s132}/headers/nrf_error_soc.h (98%) create mode 100644 components/softdevice/s132/headers/nrf_nvic.h create mode 100644 components/softdevice/s132/headers/nrf_sd_def.h create mode 100644 components/softdevice/s132/headers/nrf_sdm.h rename components/softdevice/{s110 => s132}/headers/nrf_soc.h (77%) rename components/softdevice/{s110 => s132}/headers/nrf_svc.h (71%) create mode 100644 components/softdevice/s132/hex/s132_nrf52_3.0.0_licence-agreement.txt create mode 100644 components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld rename components/softdevice/{s110/toolchain/iar/iar_s110_nrf51422_xxac.icf => s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf} (74%) delete mode 100644 components/softdevice/s210/doc/s210_nrf51422_5.0.0_licence_agreement.pdf delete mode 100644 components/softdevice/s210/doc/s210_nrf51422_5.0.0_licence_agreement.txt delete mode 100644 components/softdevice/s210/doc/s210_nrf51422_5.0.0_migration_document.pdf delete mode 100644 components/softdevice/s210/doc/s210_nrf51422_5.0.0_readme.txt delete mode 100644 components/softdevice/s210/doc/s210_nrf51422_5.0.0_releasenotes.pdf delete mode 100644 components/softdevice/s210/headers/ant_error.h delete mode 100644 components/softdevice/s210/headers/ant_interface.h delete mode 100644 components/softdevice/s210/headers/ant_parameters.h delete mode 100644 components/softdevice/s210/headers/nrf_error.h delete mode 100644 components/softdevice/s210/headers/nrf_error_soc.h delete mode 100644 components/softdevice/s210/headers/nrf_mbr.h delete mode 100644 components/softdevice/s210/headers/nrf_sd_def.h delete mode 100644 components/softdevice/s210/headers/nrf_sdm.h delete mode 100644 components/softdevice/s210/headers/nrf_soc.h delete mode 100644 components/softdevice/s210/headers/nrf_svc.h delete mode 100644 components/softdevice/s210/headers/softdevice_assert.h delete mode 100644 components/softdevice/s210/hex/s210_nrf51422_5.0.0_softdevice.hex delete mode 100644 components/softdevice/s210/toolchain/armgcc/armgcc_s210_nrf51422_xxaa.ld delete mode 100644 components/softdevice/s210/toolchain/armgcc/armgcc_s210_nrf51422_xxac.ld delete mode 100644 components/softdevice/s210/toolchain/iar/iar_s210_nrf51422_xxaa.icf delete mode 100644 components/softdevice/s210/toolchain/iar/iar_s210_nrf51422_xxac.icf create mode 100644 components/softdevice/s212/headers/nrf_sd_def.h create mode 100644 components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld rename components/softdevice/{s110/toolchain/iar/iar_s110_nrf51822_xxaa.icf => s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf} (74%) delete mode 100644 components/softdevice/s310/doc/s310_nrf51822_3.0.0_licence_agreement.pdf delete mode 100644 components/softdevice/s310/doc/s310_nrf51822_3.0.0_licence_agreement.txt delete mode 100644 components/softdevice/s310/doc/s310_nrf51822_3.0.0_migration_document.pdf delete mode 100644 components/softdevice/s310/doc/s310_nrf51822_3.0.0_readme.txt delete mode 100644 components/softdevice/s310/doc/s310_nrf51822_3.0.0_releasenotes.pdf delete mode 100644 components/softdevice/s310/headers/ant_error.h delete mode 100644 components/softdevice/s310/headers/ant_interface.h delete mode 100644 components/softdevice/s310/headers/ant_parameters.h delete mode 100644 components/softdevice/s310/headers/ble.h delete mode 100644 components/softdevice/s310/headers/ble_err.h delete mode 100644 components/softdevice/s310/headers/ble_gatt.h delete mode 100644 components/softdevice/s310/headers/ble_hci.h delete mode 100644 components/softdevice/s310/headers/ble_ranges.h delete mode 100644 components/softdevice/s310/headers/ble_types.h delete mode 100644 components/softdevice/s310/headers/nrf_error.h delete mode 100644 components/softdevice/s310/headers/nrf_error_sdm.h delete mode 100644 components/softdevice/s310/headers/nrf_error_soc.h delete mode 100644 components/softdevice/s310/headers/nrf_mbr.h delete mode 100644 components/softdevice/s310/headers/nrf_sd_def.h delete mode 100644 components/softdevice/s310/headers/nrf_sdm.h delete mode 100644 components/softdevice/s310/headers/nrf_soc.h delete mode 100644 components/softdevice/s310/headers/nrf_svc.h delete mode 100644 components/softdevice/s310/headers/softdevice_assert.h delete mode 100644 components/softdevice/s310/hex/s310_nrf51422_3.0.0_softdevice.hex delete mode 100644 components/softdevice/s310/toolchain/armgcc/armgcc_s310_nrf51422_xxaa.ld delete mode 100644 components/softdevice/s310/toolchain/armgcc/armgcc_s310_nrf51422_xxac.ld delete mode 100644 components/softdevice/s310/toolchain/iar/iar_s310_nrf51422_xxaa.icf delete mode 100644 components/softdevice/s310/toolchain/iar/iar_s310_nrf51422_xxac.icf create mode 100644 components/softdevice/s332/headers/nrf_sd_def.h create mode 100644 components/softdevice/s332/toolchain/armgcc/armgcc_s332_nrf52832_xxaa.ld rename components/softdevice/{s110/toolchain/iar/iar_s110_nrf51422_xxaa.icf => s332/toolchain/iar/iar_s332_nrf52832_xxaa.icf} (74%) create mode 100644 components/toolchain/arm/arm_startup_nrf52840.s delete mode 100644 components/toolchain/gcc/arm_common_tables.h delete mode 100644 components/toolchain/gcc/arm_const_structs.h delete mode 100644 components/toolchain/gcc/arm_math.h delete mode 100644 components/toolchain/gcc/core_cm0.h delete mode 100644 components/toolchain/gcc/core_cm4.h delete mode 100644 components/toolchain/gcc/core_cmFunc.h delete mode 100644 components/toolchain/gcc/core_cmInstr.h delete mode 100644 components/toolchain/gcc/core_cmSimd.h create mode 100644 components/toolchain/gcc/file_list.mk create mode 100644 components/toolchain/gcc/gcc_startup_nrf52840.S create mode 100644 components/toolchain/gcc/nrf52840_xxaa.ld create mode 100644 components/toolchain/iar/iar_startup_nrf52840.s create mode 100644 components/toolchain/system_nrf52840.c create mode 100644 components/toolchain/system_nrf52840.h delete mode 100644 config/bsp.h delete mode 100644 config/nrf_drv_config.h delete mode 100644 config/pstorage_platform.h create mode 100644 config/sdk_config.h diff --git a/.gitignore b/.gitignore index 83229e6..ed200e0 100644 --- a/.gitignore +++ b/.gitignore @@ -42,8 +42,8 @@ *._ii # Generated output files -/Listings/* -/Objects/* +Keil/Listings/* +Keil/Objects/* # Debugger files # define exception below if needed @@ -78,5 +78,6 @@ # To explicitly override the above, define any exceptions here; e.g.: # !my_customized_scatter_file.sct +RTE_Components.h EventRecorderStub.scvd JLinkLog.txt \ No newline at end of file diff --git a/EPD/EPD_Test.c b/EPD/EPD_Test.c index 95251f1..3aea808 100644 --- a/EPD/EPD_Test.c +++ b/EPD/EPD_Test.c @@ -132,8 +132,16 @@ static void draw4Gray(void) } } + // Load LUT from register + EPD_4IN2_SendCommand(0x00); + EPD_4IN2_SendData(0x3f); + EPD_4IN2_4Gray_lut(); EPD_4IN2_TurnOnDisplay(); + + // Load LUT from OTP + EPD_4IN2_SendCommand(0x00); + EPD_4IN2_SendData(0x1f); } void EPD_4in2_test(void) @@ -145,16 +153,8 @@ void EPD_4in2_test(void) DEV_Delay_ms(500); drawNormal(); - DEV_Delay_ms(3000); - - EPD_4IN2_Clear(); - DEV_Delay_ms(500); + DEV_Delay_ms(1000); draw4Gray(); - DEV_Delay_ms(500); - - EPD_4IN2_Sleep(); - DEV_Delay_ms(500); - DEV_Module_Exit(); } diff --git a/EPD/EPD_ble.c b/EPD/EPD_ble.c index d488575..01801ac 100644 --- a/EPD/EPD_ble.c +++ b/EPD/EPD_ble.c @@ -16,12 +16,13 @@ #include "nrf_delay.h" #include "nrf_gpio.h" #include "nrf_soc.h" -#include "nrf_log.h" -#include "pstorage.h" +#include "fstorage.h" #include "EPD_4in2.h" #include "EPD_4in2_V2.h" #include "EPD_4in2b_V2.h" #include "EPD_ble.h" +#define NRF_LOG_MODULE_NAME "EPD_ble" +#include "nrf_log.h" #define BLE_EPD_CONFIG_ADDR (NRF_FICR->CODEPAGESIZE * (NRF_FICR->CODESIZE - 1)) // Last page of the flash #define BLE_EPD_BASE_UUID {{0XEC, 0X5A, 0X67, 0X1C, 0XC1, 0XB6, 0X46, 0XFB, \ @@ -31,8 +32,6 @@ #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) #define EPD_CONFIG_SIZE (sizeof(epd_config_t) / sizeof(uint8_t)) -static pstorage_handle_t m_flash_handle; - /** EPD drivers */ static epd_driver_t epd_drivers[] = { {EPD_DRIVER_4IN2, EPD_4IN2_Init, EPD_4IN2_Clear, @@ -58,24 +57,33 @@ static epd_driver_t *epd_driver_get(uint8_t id) return NULL; } +static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result) +{ + NRF_LOG_DEBUG("fs_evt_handler: %d\n", result); +} + +// fstorage configuration +FS_REGISTER_CFG(fs_config_t fs_config) = +{ + .callback = fs_evt_handler, + .num_pages = 1, +}; + static uint32_t epd_config_load(epd_config_t *cfg) { - return pstorage_load((uint8_t *)cfg, &m_flash_handle, sizeof(epd_config_t), 0); + memcpy(cfg, (void *)BLE_EPD_CONFIG_ADDR, sizeof(epd_config_t)); + return NRF_SUCCESS; } static uint32_t epd_config_clear(epd_config_t *cfg) { - return pstorage_clear(&m_flash_handle, sizeof(epd_config_t)); + return fs_erase(&fs_config, fs_config.p_start_addr, 1, NULL);; } static uint32_t epd_config_save(epd_config_t *cfg) { - uint32_t err_code; - if ((err_code = epd_config_clear(cfg)) != NRF_SUCCESS) - { - return err_code; - } - return pstorage_store(&m_flash_handle, (uint8_t *)cfg, sizeof(epd_config_t), 0); + uint16_t const len = (sizeof(epd_config_t) + sizeof(uint32_t) - 1) / sizeof(uint32_t); + return fs_store(&fs_config, fs_config.p_start_addr, (uint32_t *) cfg, len, NULL); } /**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the S110 SoftDevice. @@ -113,7 +121,7 @@ static void on_disconnect(ble_epd_t * p_epd, ble_evt_t * p_ble_evt) static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t length) { if (p_data == NULL || length <= 0) return; - NRF_LOG_PRINTF("[EPD]: CMD=0x%02x, LEN=%d\n", p_data[0], length); + NRF_LOG_DEBUG("[EPD]: CMD=0x%02x, LEN=%d\n", p_data[0], length); uint32_t err_code; @@ -132,10 +140,8 @@ static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t le EPD_BUSY_PIN = p_epd->config.busy_pin = p_data[6]; EPD_BS_PIN = p_epd->config.bs_pin = p_data[7]; err_code = epd_config_save(&p_epd->config); - NRF_LOG_PRINTF("epd_config_save: %d\n", err_code); - - NRF_LOG_PRINTF("[EPD]: MOSI=0x%02x SCLK=0x%02x CS=0x%02x DC=0x%02x RST=0x%02x BUSY=0x%02x BS=0x%02x\n", - EPD_MOSI_PIN, EPD_SCLK_PIN, EPD_CS_PIN, EPD_DC_PIN, EPD_RST_PIN, EPD_BUSY_PIN, EPD_BS_PIN); + NRF_LOG_DEBUG("epd_config_save: %d\n", err_code); + DEV_Module_Init(); break; @@ -148,11 +154,11 @@ static void epd_service_process(ble_epd_t * p_epd, uint8_t * p_data, uint16_t le p_epd->driver = driver; p_epd->config.driver_id = driver->id; err_code = epd_config_save(&p_epd->config); - NRF_LOG_PRINTF("epd_config_save: %d\n", err_code); + NRF_LOG_DEBUG("epd_config_save: %d\n", err_code); } } - NRF_LOG_PRINTF("[EPD]: DRIVER=%d\n", p_epd->driver->id); + NRF_LOG_INFO("[EPD]: DRIVER=%d\n", p_epd->driver->id); p_epd->driver->init(); break; @@ -381,15 +387,6 @@ void ble_epd_sleep_prepare(ble_epd_t * p_epd) } } -static void pstorage_callback(pstorage_handle_t * p_handle, - uint8_t op_code, - uint32_t result, - uint8_t * p_data, - uint32_t data_len) -{ - NRF_LOG_PRINTF("pstorage_callback: op_code=%d, result=%d\n", op_code, result); -} - uint32_t ble_epd_init(ble_epd_t * p_epd) { if (p_epd == NULL) @@ -402,20 +399,10 @@ uint32_t ble_epd_init(ble_epd_t * p_epd) p_epd->is_notification_enabled = false; uint32_t err_code; - pstorage_module_param_t param; - - param.block_count = 1; - param.block_size = sizeof(epd_config_t); - param.cb = pstorage_callback; - - err_code = pstorage_register(¶m, &m_flash_handle); + err_code = epd_config_load(&p_epd->config); if (err_code == NRF_SUCCESS) { - err_code = epd_config_load(&p_epd->config); - if (err_code == NRF_SUCCESS) - { - epd_config_init(p_epd); - } + epd_config_init(p_epd); } // Init led pin diff --git a/EPD/EPD_ble.h b/EPD/EPD_ble.h index 55d318f..6e0ce90 100644 --- a/EPD/EPD_ble.h +++ b/EPD/EPD_ble.h @@ -13,10 +13,11 @@ #ifndef EPD_BLE_H__ #define EPD_BLE_H__ -#include "ble.h" -#include "ble_srv_common.h" #include #include +#include "ble.h" +#include "ble_srv_common.h" +#include "sdk_config.h" #include "DEV_Config.h" #define BLE_UUID_EPD_SERVICE 0x0001 diff --git a/Keil/EPD.uvprojx b/Keil/EPD.uvprojx index 012ba9b..c8d6c76 100644 --- a/Keil/EPD.uvprojx +++ b/Keil/EPD.uvprojx @@ -7,7 +7,7 @@ - EPD + nRF51822_xxAB 0x4 ARM-ADS 5060960::V5.06 update 7 (build 960)::.\ARMCC @@ -16,14 +16,630 @@ nRF51822_xxAB Nordic Semiconductor - NordicSemiconductor.nRF_DeviceFamilyPack.8.2.0 - http://developer.nordicsemi.com/nRF51_SDK/pieces/nRF_DeviceFamilyPack/ + NordicSemiconductor.nRF_DeviceFamilyPack.8.11.1 + http://developer.nordicsemi.com/nRF5_SDK/pieces/nRF_DeviceFamilyPack/ IRAM(0x20000000,0x00004000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC4000 -FN1 -FF0nrf51xxx -FS00 -FL0200000 -FP0($$Device:nRF51822_xxAB$Flash\nrf51xxx.flm)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC4000 -FN1 -FF0nrf51xxx -FS00 -FL0200000 -FP0($$Device:nRF51822_xxAB$Flash\nrf51xxx.flm)) + 0 + $$Device:nRF51822_xxAB$Device\Include\nrf.h + + + + + + + + + + $$Device:nRF51822_xxAB$SVD\nrf51.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + EPD + 1 + 0 + 1 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + + DARMCM1.DLL + -pCM0 + SARMCM3.DLL + + TARMCM1.DLL + -pCM0 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4096 + + 1 + BIN\UL2CM3.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M0" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x4000 + + + 1 + 0x0 + 0x20000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x1b000 + 0x5000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20001fe8 + 0x2018 + + + 0 + 0x0 + 0x0 + + + + + + 1 + 4 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 3 + 3 + 1 + 1 + 0 + 0 + 0 + + + BLE_STACK_SUPPORT_REQD NRF51822 NRF_SD_BLE_API_VERSION=2 S130 NRF51 SOFTDEVICE_PRESENT SWI_DISABLE0 + + ..\config;..\EPD;..\components\toolchain;..\components\drivers_nrf\clock;..\components\drivers_nrf\common;..\components\drivers_nrf\delay;..\components\drivers_nrf\hal;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\twi_master;..\components\drivers_ext\segger_rtt;..\components\libraries\fstorage;..\components\libraries\experimental_section_vars;..\components\libraries\log;..\components\libraries\log\src;..\components\libraries\trace;..\components\libraries\timer;..\components\libraries\util;..\components\ble\common;..\components\ble\ble_advertising;..\components\softdevice\common\softdevice_handler;..\components\softdevice\s130\headers;..\components\softdevice\s130\headers\nrf51 + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + + BLE_STACK_SUPPORT_REQD NRF51822 NRF_SD_BLE_API_VERSION=2 S130 NRF51 SOFTDEVICE_PRESENT SWI_DISABLE0 + + ..\components;..\components\drivers_nrf\common;..\components\libraries\log;..\components\libraries\log\src;..\components\drivers_nrf\hal;..\components\drivers_nrf\delay;..\components\drivers_nrf\nrf_soc_nosd;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\uart;..\components\libraries\util;..\components\toolchain;..\config;..\EPD;..\GUI + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + + + + + + + + + + + + App + + + main.c + 1 + ..\main.c + + + sdk_config.h + 5 + ..\config\sdk_config.h + + + + + EPD + + + DEV_Config.c + 1 + ..\EPD\DEV_Config.c + + + EPD_4in2.c + 1 + ..\EPD\EPD_4in2.c + + + EPD_4in2_V2.c + 1 + ..\EPD\EPD_4in2_V2.c + + + EPD_4in2b_V2.c + 1 + ..\EPD\EPD_4in2b_V2.c + + + EPD_ble.c + 1 + ..\EPD\EPD_ble.c + + + + + nRF_BLE + + + ble_advertising.c + 1 + ..\components\ble\ble_advertising\ble_advertising.c + + + ble_advdata.c + 1 + ..\components\ble\common\ble_advdata.c + + + ble_conn_params.c + 1 + ..\components\ble\common\ble_conn_params.c + + + ble_srv_common.c + 1 + ..\components\ble\common\ble_srv_common.c + + + + + nRF_Drivers + + + nrf_drv_clock.c + 1 + ..\components\drivers_nrf\clock\nrf_drv_clock.c + + + nrf_drv_common.c + 1 + ..\components\drivers_nrf\common\nrf_drv_common.c + + + nrf_drv_spi.c + 1 + ..\components\drivers_nrf\spi_master\nrf_drv_spi.c + + + + + nRF_Libraries + + + app_error.c + 1 + ..\components\libraries\util\app_error.c + + + app_error_weak.c + 1 + ..\components\libraries\util\app_error_weak.c + + + app_timer.c + 1 + ..\components\libraries\timer\app_timer.c + + + app_util_platform.c + 1 + ..\components\libraries\util\app_util_platform.c + + + fstorage.c + 1 + ..\components\libraries\fstorage\fstorage.c + + + + + nRF_Log + + + nrf_log_backend_serial.c + 1 + ..\components\libraries\log\src\nrf_log_backend_serial.c + + + nrf_log_frontend.c + 1 + ..\components\libraries\log\src\nrf_log_frontend.c + + + + + nRF_Segger_RTT + + + RTT_Syscalls_KEIL.c + 1 + ..\components\drivers_ext\segger_rtt\RTT_Syscalls_KEIL.c + + + SEGGER_RTT.c + 1 + ..\components\drivers_ext\segger_rtt\SEGGER_RTT.c + + + SEGGER_RTT_printf.c + 1 + ..\components\drivers_ext\segger_rtt\SEGGER_RTT_printf.c + + + + + nRF_SoftDevice + + + softdevice_handler.c + 1 + ..\components\softdevice\common\softdevice_handler\softdevice_handler.c + + + + + ::CMSIS + + + ::Device + + + 0 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + + + + + + nRF51802_xxAA + 0x4 + ARM-ADS + 5060960::V5.06 update 7 (build 960)::.\ARMCC + 0 + + + nRF51802_xxAA + Nordic Semiconductor + NordicSemiconductor.nRF_DeviceFamilyPack.8.11.1 + http://developer.nordicsemi.com/nRF5_SDK/pieces/nRF_DeviceFamilyPack/ + IRAM(0x20000000,0x00004000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC4000 -FN1 -FF0nrf51xxx -FS00 -FL0200000 -FP0($$Device:nRF51802_xxAA$Flash\nrf51xxx.flm)) 0 - $$Device:nRF51822_xxAB$Device\Include\nrf.h + $$Device:nRF51802_xxAA$Device\Include\nrf.h @@ -33,7 +649,7 @@ - $$Device:nRF51822_xxAB$SVD\nrf51.svd + $$Device:nRF51802_xxAA$SVD\nrf51.svd 0 0 @@ -251,7 +867,7 @@ 1 0x0 - 0x20000 + 0x40000 0 @@ -275,8 +891,8 @@ 1 - 0x18000 - 0x8000 + 0x1b000 + 0x25000 1 @@ -300,8 +916,8 @@ 0 - 0x20002000 - 0x2000 + 0x20001fe8 + 0x2018 0 @@ -337,9 +953,9 @@ 0 - BLE_STACK_SUPPORT_REQD S110 SWI_DISABLE0 SOFTDEVICE_PRESENT NRF51 + BLE_STACK_SUPPORT_REQD NRF51802 NRF_SD_BLE_API_VERSION=2 S130 NRF51 SOFTDEVICE_PRESENT SWI_DISABLE0 - ..\config;..\EPD;..\components\toolchain;..\components\drivers_nrf\config;..\components\drivers_nrf\common;..\components\drivers_nrf\delay;..\components\drivers_nrf\gpiote;..\components\drivers_nrf\hal;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\pstorage;..\components\drivers_nrf\pstorage\config;..\components\drivers_nrf\twi_master;..\components\libraries\trace;..\components\libraries\timer;..\components\libraries\util;..\components\ble\common;..\components\ble\ble_advertising;..\components\softdevice\common\softdevice_handler;..\components\softdevice\s110\headers + ..\config;..\EPD;..\components\toolchain;..\components\drivers_nrf\clock;..\components\drivers_nrf\common;..\components\drivers_nrf\delay;..\components\drivers_nrf\gpiote;..\components\drivers_nrf\hal;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\twi_master;..\components\drivers_ext\segger_rtt;..\components\libraries\fstorage;..\components\libraries\experimental_section_vars;..\components\libraries\log;..\components\libraries\log\src;..\components\libraries\trace;..\components\libraries\timer;..\components\libraries\util;..\components\ble\common;..\components\ble\ble_advertising;..\components\softdevice\common\softdevice_handler;..\components\softdevice\s130\headers;..\components\softdevice\s130\headers\nrf51 @@ -355,7 +971,7 @@ 1 - BLE_STACK_SUPPORT_REQD S110 SWI_DISABLE0 SOFTDEVICE_PRESENT NRF51 + BLE_STACK_SUPPORT_REQD NRF51802 NRF_SD_BLE_API_VERSION=2 S130 NRF51 SOFTDEVICE_PRESENT SWI_DISABLE0 ..\components;..\components\drivers_nrf\common;..\components\libraries\log;..\components\libraries\log\src;..\components\drivers_nrf\hal;..\components\drivers_nrf\delay;..\components\drivers_nrf\nrf_soc_nosd;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\uart;..\components\libraries\util;..\components\toolchain;..\config;..\EPD;..\GUI @@ -389,81 +1005,15 @@ ..\main.c - bsp.h - 5 - ..\config\bsp.h - - - nrf_drv_config.h - 5 - ..\config\nrf_drv_config.h - - - pstorage_platform.h + sdk_config.h 5 - ..\config\pstorage_platform.h + ..\config\sdk_config.h EPD - - EPD_Test.c - 1 - ..\EPD\EPD_Test.c - - - 2 - 0 - 0 - 0 - 0 - 0 - 2 - 2 - 2 - 2 - 11 - - - 1 - - - - 2 - 0 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 2 - 0 - 2 - 2 - 2 - 2 - 2 - 0 - 0 - 2 - 2 - 2 - 2 - 2 - - - - - - - - - - DEV_Config.c 1 @@ -520,69 +1070,69 @@ nRF_Drivers - nrf_delay.c + nrf_drv_clock.c 1 - ..\components\drivers_nrf\delay\nrf_delay.c + ..\components\drivers_nrf\clock\nrf_drv_clock.c nrf_drv_common.c 1 ..\components\drivers_nrf\common\nrf_drv_common.c - - nrf_drv_gpiote.c - 1 - ..\components\drivers_nrf\gpiote\nrf_drv_gpiote.c - nrf_drv_spi.c 1 ..\components\drivers_nrf\spi_master\nrf_drv_spi.c - - pstorage.c - 1 - ..\components\drivers_nrf\pstorage\pstorage.c - nRF_Libraries - nrf_log.c + app_error.c 1 - ..\components\libraries\util\nrf_log.c + ..\components\libraries\util\app_error.c - nrf_assert.c + app_error_weak.c 1 - ..\components\libraries\util\nrf_assert.c + ..\components\libraries\util\app_error_weak.c - app_error.c + app_timer.c 1 - ..\components\libraries\util\app_error.c + ..\components\libraries\timer\app_timer.c - app_timer.c + app_util_platform.c 1 - ..\components\libraries\timer\app_timer.c + ..\components\libraries\util\app_util_platform.c + + + fstorage.c + 1 + ..\components\libraries\fstorage\fstorage.c - nRF_SoftDevice + nRF_Log - softdevice_handler.c + nrf_log_backend_serial.c 1 - ..\components\softdevice\common\softdevice_handler\softdevice_handler.c + ..\components\libraries\log\src\nrf_log_backend_serial.c + + + nrf_log_frontend.c + 1 + ..\components\libraries\log\src\nrf_log_frontend.c - SEGGER_RTT + nRF_Segger_RTT RTT_Syscalls_KEIL.c @@ -601,16 +1151,95 @@ + + nRF_SoftDevice + + + softdevice_handler.c + 1 + ..\components\softdevice\common\softdevice_handler\softdevice_handler.c + + + ::CMSIS ::Device + + + 0 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + - EPD_Debug + nRF51822_xxAB_flash_softdevice 0x4 ARM-ADS 5060960::V5.06 update 7 (build 960)::.\ARMCC @@ -619,8 +1248,8 @@ nRF51822_xxAB Nordic Semiconductor - NordicSemiconductor.nRF_DeviceFamilyPack.8.2.0 - http://developer.nordicsemi.com/nRF51_SDK/pieces/nRF_DeviceFamilyPack/ + NordicSemiconductor.nRF_DeviceFamilyPack.8.11.1 + http://developer.nordicsemi.com/nRF5_SDK/pieces/nRF_DeviceFamilyPack/ IRAM(0x20000000,0x00004000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE @@ -651,8 +1280,8 @@ 0 1 - .\Objects\ - EPD + ..\components\softdevice\s130\hex\ + s130_nrf51_2.0.1_softdevice.hex 1 0 1 @@ -878,8 +1507,8 @@ 1 - 0x18000 - 0x8000 + 0x1b000 + 0x5000 1 @@ -903,8 +1532,8 @@ 0 - 0x20002000 - 0x2000 + 0x20001fe8 + 0x2018 0 @@ -916,7 +1545,7 @@ 1 - 1 + 4 0 0 1 @@ -940,9 +1569,9 @@ 0 - BLE_STACK_SUPPORT_REQD S110 SWI_DISABLE0 SOFTDEVICE_PRESENT NRF51 DEBUG NRF_LOG_USES_RTT=1 + BLE_STACK_SUPPORT_REQD NRF51822 NRF_SD_BLE_API_VERSION=2 S130 NRF51 SOFTDEVICE_PRESENT SWI_DISABLE0 - ..\config;..\EPD;..\components\toolchain;..\components\drivers_nrf\config;..\components\drivers_nrf\common;..\components\drivers_nrf\delay;..\components\drivers_nrf\gpiote;..\components\drivers_nrf\hal;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\pstorage;..\components\drivers_ext\segger_rtt;..\components\libraries\trace;..\components\libraries\timer;..\components\libraries\util;..\components\ble\common;..\components\ble\ble_advertising;..\components\softdevice\common\softdevice_handler;..\components\softdevice\s110\headers + ..\config;..\EPD;..\components\toolchain;..\components\drivers_nrf\clock;..\components\drivers_nrf\common;..\components\drivers_nrf\delay;..\components\drivers_nrf\gpiote;..\components\drivers_nrf\hal;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\twi_master;..\components\drivers_ext\segger_rtt;..\components\libraries\fstorage;..\components\libraries\experimental_section_vars;..\components\libraries\log;..\components\libraries\log\src;..\components\libraries\trace;..\components\libraries\timer;..\components\libraries\util;..\components\ble\common;..\components\ble\ble_advertising;..\components\softdevice\common\softdevice_handler;..\components\softdevice\s130\headers;..\components\softdevice\s130\headers\nrf51 @@ -958,7 +1587,7 @@ 1 - BLE_STACK_SUPPORT_REQD S110 SWI_DISABLE0 SOFTDEVICE_PRESENT NRF51 + BLE_STACK_SUPPORT_REQD NRF51822 NRF_SD_BLE_API_VERSION=2 S130 NRF51 SOFTDEVICE_PRESENT SWI_DISABLE0 ..\components;..\components\drivers_nrf\common;..\components\libraries\log;..\components\libraries\log\src;..\components\drivers_nrf\hal;..\components\drivers_nrf\delay;..\components\drivers_nrf\nrf_soc_nosd;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\uart;..\components\libraries\util;..\components\toolchain;..\config;..\EPD;..\GUI @@ -992,30 +1621,15 @@ ..\main.c - bsp.h - 5 - ..\config\bsp.h - - - nrf_drv_config.h + sdk_config.h 5 - ..\config\nrf_drv_config.h - - - pstorage_platform.h - 5 - ..\config\pstorage_platform.h + ..\config\sdk_config.h EPD - - EPD_Test.c - 1 - ..\EPD\EPD_Test.c - DEV_Config.c 1 @@ -1072,69 +1686,69 @@ nRF_Drivers - nrf_delay.c + nrf_drv_clock.c 1 - ..\components\drivers_nrf\delay\nrf_delay.c + ..\components\drivers_nrf\clock\nrf_drv_clock.c nrf_drv_common.c 1 ..\components\drivers_nrf\common\nrf_drv_common.c - - nrf_drv_gpiote.c - 1 - ..\components\drivers_nrf\gpiote\nrf_drv_gpiote.c - nrf_drv_spi.c 1 ..\components\drivers_nrf\spi_master\nrf_drv_spi.c - - pstorage.c - 1 - ..\components\drivers_nrf\pstorage\pstorage.c - nRF_Libraries - nrf_log.c + app_error.c 1 - ..\components\libraries\util\nrf_log.c + ..\components\libraries\util\app_error.c - nrf_assert.c + app_error_weak.c 1 - ..\components\libraries\util\nrf_assert.c + ..\components\libraries\util\app_error_weak.c - app_error.c + app_timer.c 1 - ..\components\libraries\util\app_error.c + ..\components\libraries\timer\app_timer.c - app_timer.c + app_util_platform.c 1 - ..\components\libraries\timer\app_timer.c + ..\components\libraries\util\app_util_platform.c + + + fstorage.c + 1 + ..\components\libraries\fstorage\fstorage.c - nRF_SoftDevice + nRF_Log - softdevice_handler.c + nrf_log_backend_serial.c 1 - ..\components\softdevice\common\softdevice_handler\softdevice_handler.c + ..\components\libraries\log\src\nrf_log_backend_serial.c + + + nrf_log_frontend.c + 1 + ..\components\libraries\log\src\nrf_log_frontend.c - SEGGER_RTT + nRF_Segger_RTT RTT_Syscalls_KEIL.c @@ -1153,32 +1767,111 @@ + + nRF_SoftDevice + + + softdevice_handler.c + 1 + ..\components\softdevice\common\softdevice_handler\softdevice_handler.c + + + ::CMSIS ::Device + + + 0 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + - flash_softdevice + nRF51802_xxAA_flash_softdevice 0x4 ARM-ADS 5060960::V5.06 update 7 (build 960)::.\ARMCC 0 - nRF51822_xxAB + nRF51802_xxAA Nordic Semiconductor - NordicSemiconductor.nRF_DeviceFamilyPack.8.44.1 + NordicSemiconductor.nRF_DeviceFamilyPack.8.11.1 http://developer.nordicsemi.com/nRF5_SDK/pieces/nRF_DeviceFamilyPack/ - IRAM(0x20000000,0x00004000) IROM(0x00000000,0x00020000) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE + IRAM(0x20000000,0x00004000) IROM(0x00000000,0x00040000) CPUTYPE("Cortex-M0") CLOCK(12000000) ELITTLE - UL2CM3(-S0 -C0 -P0 -FD20000000 -FC4000 -FN1 -FF0nrf51xxx -FS00 -FL0200000 -FP0($$Device:nRF51822_xxAB$Flash\nrf51xxx.flm)) + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC4000 -FN1 -FF0nrf51xxx -FS00 -FL0200000 -FP0($$Device:nRF51802_xxAA$Flash\nrf51xxx.flm)) 0 - $$Device:nRF51822_xxAB$Device\Include\nrf.h + $$Device:nRF51802_xxAA$Device\Include\nrf.h @@ -1188,7 +1881,7 @@ - $$Device:nRF51822_xxAB$SVD\nrf51.svd + $$Device:nRF51802_xxAA$SVD\nrf51.svd 0 0 @@ -1203,8 +1896,8 @@ 0 1 - ..\components\softdevice\s110\hex\ - s110_nrf51_8.0.0_softdevice.hex + ..\components\softdevice\s130\hex\ + s130_nrf51_2.0.1_softdevice.hex 1 0 1 @@ -1293,7 +1986,7 @@ 1 BIN\UL2CM3.DLL - "" () + @@ -1406,7 +2099,7 @@ 1 0x0 - 0x20000 + 0x40000 0 @@ -1430,8 +2123,8 @@ 1 - 0x18000 - 0x8000 + 0x1b000 + 0x25000 1 @@ -1455,8 +2148,8 @@ 0 - 0x20002000 - 0x2000 + 0x20001fe8 + 0x2018 0 @@ -1492,9 +2185,9 @@ 0 - BLE_STACK_SUPPORT_REQD S110 BOARD_PCA10028 SWI_DISABLE0 SOFTDEVICE_PRESENT NRF51 + BLE_STACK_SUPPORT_REQD NRF51802 NRF_SD_BLE_API_VERSION=2 S130 NRF51 SOFTDEVICE_PRESENT SWI_DISABLE0 - ..\config;..\EPD;..\GUI;..\components\toolchain;..\components\drivers_nrf\config;..\components\drivers_nrf\common;..\components\drivers_nrf\delay;..\components\drivers_nrf\gpiote;..\components\drivers_nrf\hal;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\pstorage;..\components\libraries\log\src;..\components\libraries\log;..\components\libraries\trace;..\components\libraries\timer;..\components\libraries\util;..\components\ble\common;..\components\ble\ble_advertising;..\components\softdevice\common\softdevice_handler;..\components\softdevice\s110\headers + ..\config;..\EPD;..\components\toolchain;..\components\drivers_nrf\clock;..\components\drivers_nrf\common;..\components\drivers_nrf\delay;..\components\drivers_nrf\gpiote;..\components\drivers_nrf\hal;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\twi_master;..\components\drivers_ext\segger_rtt;..\components\libraries\fstorage;..\components\libraries\experimental_section_vars;..\components\libraries\log;..\components\libraries\log\src;..\components\libraries\trace;..\components\libraries\timer;..\components\libraries\util;..\components\ble\common;..\components\ble\ble_advertising;..\components\softdevice\common\softdevice_handler;..\components\softdevice\s130\headers;..\components\softdevice\s130\headers\nrf51 @@ -1510,7 +2203,7 @@ 1 - BLE_STACK_SUPPORT_REQD S110 BOARD_PCA10028 SWI_DISABLE0 SOFTDEVICE_PRESENT NRF51 + BLE_STACK_SUPPORT_REQD NRF51802 NRF_SD_BLE_API_VERSION=2 S130 NRF51 SOFTDEVICE_PRESENT SWI_DISABLE0 ..\components;..\components\drivers_nrf\common;..\components\libraries\log;..\components\libraries\log\src;..\components\drivers_nrf\hal;..\components\drivers_nrf\delay;..\components\drivers_nrf\nrf_soc_nosd;..\components\drivers_nrf\spi_master;..\components\drivers_nrf\uart;..\components\libraries\util;..\components\toolchain;..\config;..\EPD;..\GUI @@ -1544,30 +2237,15 @@ ..\main.c - bsp.h - 5 - ..\config\bsp.h - - - nrf_drv_config.h - 5 - ..\config\nrf_drv_config.h - - - pstorage_platform.h + sdk_config.h 5 - ..\config\pstorage_platform.h + ..\config\sdk_config.h EPD - - EPD_Test.c - 1 - ..\EPD\EPD_Test.c - DEV_Config.c 1 @@ -1624,69 +2302,69 @@ nRF_Drivers - nrf_delay.c + nrf_drv_clock.c 1 - ..\components\drivers_nrf\delay\nrf_delay.c + ..\components\drivers_nrf\clock\nrf_drv_clock.c nrf_drv_common.c 1 ..\components\drivers_nrf\common\nrf_drv_common.c - - nrf_drv_gpiote.c - 1 - ..\components\drivers_nrf\gpiote\nrf_drv_gpiote.c - nrf_drv_spi.c 1 ..\components\drivers_nrf\spi_master\nrf_drv_spi.c - - pstorage.c - 1 - ..\components\drivers_nrf\pstorage\pstorage.c - nRF_Libraries - nrf_log.c + app_error.c 1 - ..\components\libraries\util\nrf_log.c + ..\components\libraries\util\app_error.c - nrf_assert.c + app_error_weak.c 1 - ..\components\libraries\util\nrf_assert.c + ..\components\libraries\util\app_error_weak.c - app_error.c + app_timer.c 1 - ..\components\libraries\util\app_error.c + ..\components\libraries\timer\app_timer.c - app_timer.c + app_util_platform.c 1 - ..\components\libraries\timer\app_timer.c + ..\components\libraries\util\app_util_platform.c + + + fstorage.c + 1 + ..\components\libraries\fstorage\fstorage.c - nRF_SoftDevice + nRF_Log - softdevice_handler.c + nrf_log_backend_serial.c 1 - ..\components\softdevice\common\softdevice_handler\softdevice_handler.c + ..\components\libraries\log\src\nrf_log_backend_serial.c + + + nrf_log_frontend.c + 1 + ..\components\libraries\log\src\nrf_log_frontend.c - SEGGER_RTT + nRF_Segger_RTT RTT_Syscalls_KEIL.c @@ -1705,11 +2383,90 @@ + + nRF_SoftDevice + + + softdevice_handler.c + 1 + ..\components\softdevice\common\softdevice_handler\softdevice_handler.c + + + ::CMSIS ::Device + + + 0 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + + + + + + + + + @@ -1722,66 +2479,78 @@ - - + + + + - + - - + + + + - - - - - - - - - - - - - - - + + + + - - + + - + + + + - + + RTE\Device\nRF51802_xxAA\arm_startup_nrf51.s + + + + + + + + + RTE\Device\nRF51802_xxAA\system_nrf51.c + + + + + + + + RTE\Device\nRF51822_xxAB\arm_startup_nrf51.s - - + + - - - + + - + RTE\Device\nRF51822_xxAB\system_nrf51.c - - + + - - - + + diff --git a/Keil/RTE/Device/nRF51802_xxAA/arm_startup_nrf51.s b/Keil/RTE/Device/nRF51802_xxAA/arm_startup_nrf51.s new file mode 100644 index 0000000..fde9487 --- /dev/null +++ b/Keil/RTE/Device/nRF51802_xxAA/arm_startup_nrf51.s @@ -0,0 +1,259 @@ +;/* Copyright (c) 2012 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 :DEF: __STARTUP_CONFIG +#include "startup_config.h" + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Size EQU __STARTUP_CONFIG_STACK_SIZE + ELIF :DEF: __STACK_SIZE +Stack_Size EQU __STACK_SIZE + ELSE +Stack_Size EQU 2048 + ENDIF + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + IF :DEF: __STARTUP_CONFIG +Heap_Size EQU __STARTUP_CONFIG_HEAP_SIZE + ELIF :DEF: __HEAP_SIZE +Heap_Size EQU __HEAP_SIZE + ELSE +Heap_Size EQU 2048 + ENDIF + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UART0_IRQHandler + DCD SPI0_TWI0_IRQHandler + DCD SPI1_TWI1_IRQHandler + DCD 0 ; Reserved + DCD GPIOTE_IRQHandler + DCD ADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD LPCOMP_IRQHandler + DCD SWI0_IRQHandler + DCD SWI1_IRQHandler + DCD SWI2_IRQHandler + DCD SWI3_IRQHandler + DCD SWI4_IRQHandler + DCD SWI5_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset Handler + +NRF_POWER_RAMON_ADDRESS EQU 0x40000524 ; NRF_POWER->RAMON address +NRF_POWER_RAMONB_ADDRESS EQU 0x40000554 ; NRF_POWER->RAMONB address +NRF_POWER_RAMONx_RAMxON_ONMODE_Msk EQU 0x3 ; All RAM blocks on in onmode bit mask + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + MOVS R1, #NRF_POWER_RAMONx_RAMxON_ONMODE_Msk + + LDR R0, =NRF_POWER_RAMON_ADDRESS + LDR R2, [R0] + ORRS R2, R2, R1 + STR R2, [R0] + + LDR R0, =NRF_POWER_RAMONB_ADDRESS + LDR R2, [R0] + ORRS R2, R2, R1 + STR R2, [R0] + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT POWER_CLOCK_IRQHandler [WEAK] + EXPORT RADIO_IRQHandler [WEAK] + EXPORT UART0_IRQHandler [WEAK] + EXPORT SPI0_TWI0_IRQHandler [WEAK] + EXPORT SPI1_TWI1_IRQHandler [WEAK] + EXPORT GPIOTE_IRQHandler [WEAK] + EXPORT ADC_IRQHandler [WEAK] + EXPORT TIMER0_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT RTC0_IRQHandler [WEAK] + EXPORT TEMP_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT ECB_IRQHandler [WEAK] + EXPORT CCM_AAR_IRQHandler [WEAK] + EXPORT WDT_IRQHandler [WEAK] + EXPORT RTC1_IRQHandler [WEAK] + EXPORT QDEC_IRQHandler [WEAK] + EXPORT LPCOMP_IRQHandler [WEAK] + EXPORT SWI0_IRQHandler [WEAK] + EXPORT SWI1_IRQHandler [WEAK] + EXPORT SWI2_IRQHandler [WEAK] + EXPORT SWI3_IRQHandler [WEAK] + EXPORT SWI4_IRQHandler [WEAK] + EXPORT SWI5_IRQHandler [WEAK] +POWER_CLOCK_IRQHandler +RADIO_IRQHandler +UART0_IRQHandler +SPI0_TWI0_IRQHandler +SPI1_TWI1_IRQHandler +GPIOTE_IRQHandler +ADC_IRQHandler +TIMER0_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +RTC0_IRQHandler +TEMP_IRQHandler +RNG_IRQHandler +ECB_IRQHandler +CCM_AAR_IRQHandler +WDT_IRQHandler +RTC1_IRQHandler +QDEC_IRQHandler +LPCOMP_IRQHandler +SWI0_IRQHandler +SWI1_IRQHandler +SWI2_IRQHandler +SWI3_IRQHandler +SWI4_IRQHandler +SWI5_IRQHandler + B . + ENDP + ALIGN + +; User Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + + LDR R0, = Heap_Mem + LDR R1, = (Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/Keil/RTE/Device/nRF51802_xxAA/system_nrf51.c b/Keil/RTE/Device/nRF51802_xxAA/system_nrf51.c new file mode 100644 index 0000000..0ad09d5 --- /dev/null +++ b/Keil/RTE/Device/nRF51802_xxAA/system_nrf51.c @@ -0,0 +1,151 @@ +/* Copyright (c) 2012 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 THE COPYRIGHT HOLDER 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. + * + */ + +/* NOTE: Template files (including this one) are application specific and therefore expected to + be copied into the application project folder prior to its use! */ + +#include +#include +#include "nrf.h" +#include "system_nrf51.h" + +/*lint ++flb "Enter library region" */ + + +#define __SYSTEM_CLOCK (16000000UL) /*!< nRF51 devices use a fixed System Clock Frequency of 16MHz */ + +static bool is_manual_peripheral_setup_needed(void); +static bool is_disabled_in_debug_needed(void); +static bool is_peripheral_domain_setup_needed(void); + + +#if defined ( __CC_ARM ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; +#elif defined ( __ICCARM__ ) + __root uint32_t SystemCoreClock = __SYSTEM_CLOCK; +#elif defined ( __GNUC__ ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; +#endif + +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = __SYSTEM_CLOCK; +} + +void SystemInit(void) +{ + /* If desired, switch off the unused RAM to lower consumption by the use of RAMON register. + It can also be done in the application main() function. */ + + /* Prepare the peripherals for use as indicated by the PAN 26 "System: Manual setup is required + to enable the use of peripherals" found at Product Anomaly document for your device found at + https://www.nordicsemi.com/. The side effect of executing these instructions in the devices + that do not need it is that the new peripherals in the second generation devices (LPCOMP for + example) will not be available. */ + if (is_manual_peripheral_setup_needed()) + { + *(uint32_t volatile *)0x40000504 = 0xC007FFDF; + *(uint32_t volatile *)0x40006C18 = 0x00008000; + } + + /* Disable PROTENSET registers under debug, as indicated by PAN 59 "MPU: Reset value of DISABLEINDEBUG + register is incorrect" found at Product Anomaly document for your device found at + https://www.nordicsemi.com/. There is no side effect of using these instruction if not needed. */ + if (is_disabled_in_debug_needed()) + { + NRF_MPU->DISABLEINDEBUG = MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled << MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos; + } + + /* Execute the following code to eliminate excessive current in sleep mode with RAM retention in nRF51802 devices, + as indicated by PAN 76 "System: Excessive current in sleep mode with retention" found at Product Anomaly document + for your device found at https://www.nordicsemi.com/. */ + if (is_peripheral_domain_setup_needed()){ + if (*(uint32_t volatile *)0x4006EC00 != 1){ + *(uint32_t volatile *)0x4006EC00 = 0x9375; + while (*(uint32_t volatile *)0x4006EC00 != 1){ + } + } + *(uint32_t volatile *)0x4006EC14 = 0xC0; + } +} + + +static bool is_manual_peripheral_setup_needed(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) + { + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x00) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x10) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + } + + return false; +} + +static bool is_disabled_in_debug_needed(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) + { + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + } + + return false; +} + +static bool is_peripheral_domain_setup_needed(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) + { + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xA0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xD0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + } + + return false; +} + +/*lint --flb "Leave library region" */ diff --git a/Keil/RTE/Device/nRF51822_xxAB/arm_startup_nrf51.s b/Keil/RTE/Device/nRF51822_xxAB/arm_startup_nrf51.s index a7b5e93..fde9487 100644 --- a/Keil/RTE/Device/nRF51822_xxAB/arm_startup_nrf51.s +++ b/Keil/RTE/Device/nRF51822_xxAB/arm_startup_nrf51.s @@ -1,50 +1,52 @@ -; Copyright (c) 2015, Nordic Semiconductor ASA -; 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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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. - -; NOTE: Template files (including this one) are application specific and therefore -; expected to be copied into the application project folder prior to its use! - -; Description message - - IF :DEF: __STACK_SIZE -Stack_Size EQU __STACK_SIZE +;/* Copyright (c) 2012 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 :DEF: __STARTUP_CONFIG +#include "startup_config.h" + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Size EQU __STARTUP_CONFIG_STACK_SIZE + ELIF :DEF: __STACK_SIZE +Stack_Size EQU __STACK_SIZE ELSE -Stack_Size EQU 4096 +Stack_Size EQU 2048 ENDIF AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp - IF :DEF: __HEAP_SIZE -Heap_Size EQU __HEAP_SIZE + IF :DEF: __STARTUP_CONFIG +Heap_Size EQU __STARTUP_CONFIG_HEAP_SIZE + ELIF :DEF: __HEAP_SIZE +Heap_Size EQU __HEAP_SIZE ELSE -Heap_Size EQU 4096 +Heap_Size EQU 2048 ENDIF AREA HEAP, NOINIT, READWRITE, ALIGN=3 @@ -129,7 +131,7 @@ Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main - + MOVS R1, #NRF_POWER_RAMONx_RAMxON_ONMODE_Msk LDR R0, =NRF_POWER_RAMON_ADDRESS @@ -141,7 +143,7 @@ Reset_Handler PROC LDR R2, [R0] ORRS R2, R2, R1 STR R2, [R0] - + LDR R0, =SystemInit BLX R0 LDR R0, =__main @@ -231,7 +233,7 @@ SWI5_IRQHandler ; User Initial Stack & Heap IF :DEF:__MICROLIB - + EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit @@ -240,13 +242,15 @@ SWI5_IRQHandler IMPORT __use_two_region_memory EXPORT __user_initial_stackheap -__user_initial_stackheap + +__user_initial_stackheap PROC LDR R0, = Heap_Mem LDR R1, = (Stack_Mem + Stack_Size) LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR + ENDP ALIGN diff --git a/Keil/RTE/Device/nRF51822_xxAB/system_nrf51.c b/Keil/RTE/Device/nRF51822_xxAB/system_nrf51.c index 9bfe509..0ad09d5 100644 --- a/Keil/RTE/Device/nRF51822_xxAB/system_nrf51.c +++ b/Keil/RTE/Device/nRF51822_xxAB/system_nrf51.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, Nordic Semiconductor ASA +/* Copyright (c) 2012 ARM LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,9 +11,9 @@ * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - * * Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * * 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 @@ -27,8 +27,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - -/* NOTE: Template files (including this one) are application specific and therefore expected to + +/* NOTE: Template files (including this one) are application specific and therefore expected to be copied into the application project folder prior to its use! */ #include @@ -43,10 +43,11 @@ static bool is_manual_peripheral_setup_needed(void); static bool is_disabled_in_debug_needed(void); +static bool is_peripheral_domain_setup_needed(void); #if defined ( __CC_ARM ) - uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; #elif defined ( __ICCARM__ ) __root uint32_t SystemCoreClock = __SYSTEM_CLOCK; #elif defined ( __GNUC__ ) @@ -65,7 +66,7 @@ void SystemInit(void) /* Prepare the peripherals for use as indicated by the PAN 26 "System: Manual setup is required to enable the use of peripherals" found at Product Anomaly document for your device found at - https://www.nordicsemi.com/. The side effect of executing these instructions in the devices + https://www.nordicsemi.com/. The side effect of executing these instructions in the devices that do not need it is that the new peripherals in the second generation devices (LPCOMP for example) will not be available. */ if (is_manual_peripheral_setup_needed()) @@ -73,18 +74,30 @@ void SystemInit(void) *(uint32_t volatile *)0x40000504 = 0xC007FFDF; *(uint32_t volatile *)0x40006C18 = 0x00008000; } - + /* Disable PROTENSET registers under debug, as indicated by PAN 59 "MPU: Reset value of DISABLEINDEBUG - register is incorrect" found at Product Anomaly document four your device found at + register is incorrect" found at Product Anomaly document for your device found at https://www.nordicsemi.com/. There is no side effect of using these instruction if not needed. */ if (is_disabled_in_debug_needed()) { NRF_MPU->DISABLEINDEBUG = MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled << MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos; } + + /* Execute the following code to eliminate excessive current in sleep mode with RAM retention in nRF51802 devices, + as indicated by PAN 76 "System: Excessive current in sleep mode with retention" found at Product Anomaly document + for your device found at https://www.nordicsemi.com/. */ + if (is_peripheral_domain_setup_needed()){ + if (*(uint32_t volatile *)0x4006EC00 != 1){ + *(uint32_t volatile *)0x4006EC00 = 0x9375; + while (*(uint32_t volatile *)0x4006EC00 != 1){ + } + } + *(uint32_t volatile *)0x4006EC14 = 0xC0; + } } -static bool is_manual_peripheral_setup_needed(void) +static bool is_manual_peripheral_setup_needed(void) { if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) { @@ -101,11 +114,11 @@ static bool is_manual_peripheral_setup_needed(void) return true; } } - + return false; } -static bool is_disabled_in_debug_needed(void) +static bool is_disabled_in_debug_needed(void) { if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) { @@ -114,7 +127,24 @@ static bool is_disabled_in_debug_needed(void) return true; } } - + + return false; +} + +static bool is_peripheral_domain_setup_needed(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) + { + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xA0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xD0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + } + return false; } diff --git a/Keil/RTE/_EPD/RTE_Components.h b/Keil/RTE/_EPD/RTE_Components.h deleted file mode 100644 index 9350a11..0000000 --- a/Keil/RTE/_EPD/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'EPD' - * Target: 'EPD' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "nrf.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/Keil/RTE/_EPD_Debug/RTE_Components.h b/Keil/RTE/_EPD_Debug/RTE_Components.h deleted file mode 100644 index b55965f..0000000 --- a/Keil/RTE/_EPD_Debug/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'EPD' - * Target: 'EPD_Debug' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "nrf.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/Keil/RTE/_flash_softdevice/RTE_Components.h b/Keil/RTE/_flash_softdevice/RTE_Components.h deleted file mode 100644 index 6c704ae..0000000 --- a/Keil/RTE/_flash_softdevice/RTE_Components.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'EPD' - * Target: 'flash_softdevice' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "nrf.h" - - - -#endif /* RTE_COMPONENTS_H */ diff --git a/components/ant/ant_channel_config/ant_channel_config.c b/components/ant/ant_channel_config/ant_channel_config.c index 4be688d..a8116c0 100644 --- a/components/ant/ant_channel_config/ant_channel_config.c +++ b/components/ant/ant_channel_config/ant_channel_config.c @@ -1,68 +1,87 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_CHANNEL_CONFIG) +#include "nrf_error.h" #include "ant_channel_config.h" #include "ant_interface.h" #include "ant_parameters.h" -#include "nrf_error.h" uint32_t ant_channel_init(ant_channel_config_t const * p_config) { uint32_t err_code; // Set Channel Number. - err_code = sd_ant_channel_assign(p_config->channel_number, - p_config->channel_type, + err_code = sd_ant_channel_assign(p_config->channel_number, + p_config->channel_type, p_config->network_number, p_config->ext_assign); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Set Channel ID. - err_code = sd_ant_channel_id_set(p_config->channel_number, - p_config->device_number, - p_config->device_type, + err_code = sd_ant_channel_id_set(p_config->channel_number, + p_config->device_number, + p_config->device_type, p_config->transmission_type); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Set Channel RF frequency. err_code = sd_ant_channel_radio_freq_set(p_config->channel_number, p_config->rf_freq); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Set Channel period. if (!(p_config->ext_assign & EXT_PARAM_ALWAYS_SEARCH)) { err_code = sd_ant_channel_period_set(p_config->channel_number, p_config->channel_period); } - - + + #if ANT_CONFIG_ENCRYPTED_CHANNELS > 0 - if (err_code != NRF_SUCCESS) - { - return err_code; - } - + VERIFY_SUCCESS(err_code); + err_code = ant_channel_encrypt_config(p_config->channel_type , p_config->channel_number, p_config->p_crypto_settings); #endif - + return err_code; } + +#endif // NRF_MODULE_ENABLED(ANT_CHANNEL_CONFIG) diff --git a/components/ant/ant_channel_config/ant_channel_config.h b/components/ant/ant_channel_config/ant_channel_config.h index 35c5cd3..9a1f9c5 100644 --- a/components/ant/ant_channel_config/ant_channel_config.h +++ b/components/ant/ant_channel_config/ant_channel_config.h @@ -1,37 +1,80 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_CHANNEL_CONFIG_H__ #define ANT_CHANNEL_CONFIG_H__ /** @file * - * @defgroup ant_sdk_channel_config ANT channel configuration + * @defgroup ant_channel_config ANT channel configuration * @{ * @ingroup ant_sdk_utils * @brief ANT channel configuration module. */ #include -#include "ant_stack_config_defs.h" +#include "sdk_config.h" #ifndef ANT_CONFIG_ENCRYPTED_CHANNELS - #error Undefined ANT_CONFIG_ENCRYPTED_CHANNELS. It should be defined in ant_stack_config_defs.h file. + #error Undefined ANT_CONFIG_ENCRYPTED_CHANNELS. It should be defined in sdk_config.h file. #elif ANT_CONFIG_ENCRYPTED_CHANNELS > 0 #include "ant_encrypt_config.h" #endif +#ifdef __cplusplus +extern "C" { +#endif + /**@brief ANT channel configuration structure. */ typedef struct { uint8_t channel_number; ///< Assigned channel number. uint8_t channel_type; ///< Channel type (see Assign Channel Parameters in ant_parameters.h: @ref ant_parameters). uint8_t ext_assign; ///< Extended assign (see Ext. Assign Channel Parameters in ant_parameters.h: @ref ant_parameters). - uint8_t rf_freq; ///< Radio frequency offset from 2400 MHz (for example, 2466 MHz, ucFreq = 66). + uint8_t rf_freq; ///< Radio frequency offset from 2400 MHz (for example, 2466 MHz, rf_freq = 66). uint8_t transmission_type; ///< Transmission type. uint8_t device_type; ///< Device type. - uint8_t device_number; ///< Device number. + uint16_t device_number; ///< Device number. uint16_t channel_period; ///< The period in 32 kHz counts. uint8_t network_number; ///< Network number denoting the network key. - + #if ANT_CONFIG_ENCRYPTED_CHANNELS > 0 ant_encrypt_channel_settings_t * p_crypto_settings; ///< Pointer to cryptographic settings, NULL if this configuration have to be omitted. #endif @@ -46,5 +89,10 @@ typedef struct */ uint32_t ant_channel_init(ant_channel_config_t const * p_config); + +#ifdef __cplusplus +} +#endif + #endif // ANT_CHANNEL_CONFIG_H__ /** @} */ diff --git a/components/ant/ant_encryption/ant_encrypt_config.c b/components/ant/ant_encryption/ant_encrypt_config.c index e7a27e3..498c81e 100644 --- a/components/ant/ant_encryption/ant_encrypt_config.c +++ b/components/ant/ant_encryption/ant_encrypt_config.c @@ -1,23 +1,51 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_ENCRYPT_CONFIG) #include -#include #include "ant_encrypt_config.h" #include "ant_interface.h" #include "ant_parameters.h" -#include "nrf_error.h" -#ifdef ANT_ENCRYPT_SLAVE_NEGOTIATION_USED +#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED #include "ant_encrypt_negotiation_slave.h" #endif @@ -25,7 +53,7 @@ /** Flag for checking if stack was configured for encryption. */ static bool m_stack_encryption_configured = false; /*lint -restore */ - + /** Pointer to handler of module's events. */ static ant_encryp_user_handler_t m_ant_enc_evt_handler = NULL; @@ -39,21 +67,13 @@ ret_code_t ant_stack_encryption_config(ant_encrypt_stack_settings_t const * cons for ( uint32_t i = 0; i < p_crypto_set->key_number; i++) { err_code = sd_ant_crypto_key_set(i, p_crypto_set->pp_key[i]); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } if (p_crypto_set->p_adv_burst_config != NULL) { err_code = ant_enc_advance_burs_config_apply(p_crypto_set->p_adv_burst_config); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } // subcomands LUT for @ref sd_ant_crypto_info_set calls @@ -71,20 +91,17 @@ ret_code_t ant_stack_encryption_config(ant_encrypt_stack_settings_t const * cons err_code = sd_ant_crypto_info_set(set_enc_info_param_lut[i], p_crypto_set->info.pp_array[i]); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } } - #ifdef ANT_ENCRYPT_SLAVE_NEGOTIATION_USED + #ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED // all ANT channels have unsupported slave encryption tracking (even master's channel) ant_channel_encryp_negotiation_slave_init(); #endif - + m_ant_enc_evt_handler = NULL; - + m_stack_encryption_configured = true; return NRF_SUCCESS; @@ -133,20 +150,20 @@ ret_code_t ant_channel_encrypt_config(uint8_t channel_t // encryption of the stack should be initialized previously if (m_stack_encryption_configured == false) { - return MODULE_NOT_INITIALZED; + return NRF_ERROR_MODULE_NOT_INITIALZED; } switch (channel_type) { case CHANNEL_TYPE_MASTER: err_code = ant_channel_encrypt_config_perform(channel_number, p_crypto_config); -#ifdef ANT_ENCRYPT_SLAVE_NEGOTIATION_USED +#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED ant_channel_encryp_tracking_state_set(channel_number, ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED); #endif break; -#ifdef ANT_ENCRYPT_SLAVE_NEGOTIATION_USED +#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED case CHANNEL_TYPE_SLAVE: ant_slave_channel_encrypt_config(channel_number, p_crypto_config); @@ -172,7 +189,7 @@ ret_code_t ant_channel_encrypt_config(uint8_t channel_t } else { -#ifdef ANT_ENCRYPT_SLAVE_NEGOTIATION_USED +#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED ant_channel_encryp_tracking_state_set(channel_number, ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED); #endif @@ -194,21 +211,21 @@ static void ant_encrypt_user_handler_try_to_run(uint8_t ant_channel, ant_encrypt void ant_encrypt_event_handler(ant_evt_t * p_ant_evt) { uint8_t const ant_channel = p_ant_evt->channel; - -#ifdef ANT_ENCRYPT_SLAVE_NEGOTIATION_USED + +#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED ant_slave_encrypt_negotiation(p_ant_evt); #endif - + switch (p_ant_evt->event) { case EVENT_RX_FAIL_GO_TO_SEARCH: ant_encrypt_user_handler_try_to_run(ant_channel, ANT_ENC_EVT_CHANNEL_LOST); break; - + case EVENT_ENCRYPT_NEGOTIATION_SUCCESS: ant_encrypt_user_handler_try_to_run(ant_channel, ANT_ENC_EVT_NEGOTIATION_SUCCESS); break; - + case EVENT_ENCRYPT_NEGOTIATION_FAIL: ant_encrypt_user_handler_try_to_run(ant_channel, ANT_ENC_EVT_NEGOTIATION_FAIL); break; @@ -220,3 +237,4 @@ void ant_enc_event_handler_register(ant_encryp_user_handler_t user_handler_func) m_ant_enc_evt_handler = user_handler_func; } +#endif // NRF_MODULE_ENABLED(ANT_ENCRYPT_CONFIG) diff --git a/components/ant/ant_encryption/ant_encrypt_config.h b/components/ant/ant_encryption/ant_encrypt_config.h index 3a9489e..1778cb9 100644 --- a/components/ant/ant_encryption/ant_encrypt_config.h +++ b/components/ant/ant_encryption/ant_encrypt_config.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_ENCRYPT_CONFIG__ @@ -28,6 +56,10 @@ #include "sdk_errors.h" #include "ant_stack_handler_types.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @name Advanced burst configuration for encryption modules * @{ */ @@ -167,17 +199,17 @@ ret_code_t ant_channel_encrypt_config_perform(uint8_t c * for that channel. When called for a slave channel, it saves * the encryption configuration for future use. * - * This function should be used by the @ref ant_sdk_channel_config module. + * This function should be used by the @ref ant_channel_config module. * * @param[in] channel_type ANT channel type: CHANNEL_TYPE_SLAVE or CHANNEL_TYPE_MASTER. * @param[in] channel_num ANT channel number. * @param[in] p_crypto_config Pointer to the encryption configuration. * - * @retval NRF_SUCCESS If the function completed successfully. - * @retval NRF_ERROR_INVALID_PARAM If the channel type is invalid. - * @retval MODULE_NOT_INITIALZED If the stack is not configured for encryption. - * @retval Other Otherwise, the error value returned by the - * @ref ant_channel_encrypt_config_perform function is returned. + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_PARAM If the channel type is invalid. + * @retval NRF_ERROR_MODULE_NOT_INITIALZED If the stack is not configured for encryption. + * @retval Other Otherwise, the error value returned by the @ref + * ant_channel_encrypt_config_perform function is returned. */ ret_code_t ant_channel_encrypt_config(uint8_t channel_type, uint8_t channel_num, @@ -216,4 +248,9 @@ void ant_enc_event_handler_register(ant_encryp_user_handler_t p_handler); /** * @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_ENCRYPT_CONFIG__ diff --git a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c b/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c index 52cb9e6..12d5199 100644 --- a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c +++ b/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c @@ -1,15 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_ENCRYPT_NEGOTIATION_SLAVE) #include #include #include "ant_encrypt_config.h" @@ -18,13 +48,8 @@ #include "nrf_error.h" #include "app_error.h" -#include "ant_stack_config_defs.h" #include "ant_encrypt_negotiation_slave.h" -#ifndef ANT_ENCRYPT_SLAVE_NEGOTIATION_USED - #error "To use this module, ANT_ENCRYPT_SLAVE_NEGOTIATION_USED must be declared globally." -#else - /** Number of supported channels. */ #define NUMBER_OF_CHANNELS (ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED) @@ -140,7 +165,7 @@ void ant_slave_encrypt_negotiation(ant_evt_t * p_ant_evt) case EVENT_RX: /*lint -e545 -save*/ - p_ant_msg = (ANT_MESSAGE *) &(p_ant_evt->evt_buffer); + p_ant_msg = (ANT_MESSAGE *) &(p_ant_evt->msg.evt_buffer); /*lint -restore*/ ant_slave_encrypt_try_enable(ant_channel, p_ant_msg->ANT_MESSAGE_ucMesgID); break; @@ -162,7 +187,4 @@ void ant_slave_encrypt_negotiation(ant_evt_t * p_ant_evt) } } - -#endif - - +#endif // NRF_MODULE_ENABLED(ANT_ENCRYPT_NEGOTIATION_SLAVE) diff --git a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h b/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h index a5cd5ae..e09962e 100644 --- a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h +++ b/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_ENCRYPT_NEGOTIATION_SLAVE_H__ @@ -31,6 +59,10 @@ #include "ant_stack_handler_types.h" #include "ant_encrypt_config.h" +#ifdef __cplusplus +extern "C" { +#endif + /** Encryption negotiation states for a slave channel. */ typedef enum { @@ -100,5 +132,10 @@ void ant_slave_encrypt_negotiation(ant_evt_t * p_ant_evt); /** * @} - */ + */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_ENCRYPT_NEGOTIATION_SLAVE_H__ diff --git a/components/libraries/ant_fs/antfs.c b/components/ant/ant_fs/antfs.c similarity index 91% rename from components/libraries/ant_fs/antfs.c rename to components/ant/ant_fs/antfs.c index 1e33d84..105ece4 100644 --- a/components/libraries/ant_fs/antfs.c +++ b/components/ant/ant_fs/antfs.c @@ -1,9 +1,56 @@ -/* -This software is subject to the license described in the license.txt file included with this software distribution. -You may not use this file except in compliance with this license. -Copyright © Dynastream Innovations Inc. 2012 -All rights reserved. -*/ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2012 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * 1) Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * 2) 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. + * + * 3) Neither the name of Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANTFS) #include "antfs.h" #include @@ -13,15 +60,14 @@ All rights reserved. #include "ant_error.h" #include "ant_parameters.h" #include "ant_interface.h" +#include "ant_key_manager.h" #include "crc.h" -#include "app_util.h" -#ifdef LEDDRIVER_ACTIVE +#if ANTFS_CONFIG_DEBUG_LED_ENABLED #include "bsp.h" -#endif // LEDDRIVER_ACTIVE +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED #define BURST_PACKET_SIZE 8u /**< The burst packet size. */ -#define ANTFS_NETWORK_KEY {0,0,0,0,0,0,0,0} /**< The used ANT-FS network key. */ #define ANTFS_CONNECTION_TYPE_OFFSET 0x00u /**< The connection type offset within ANT-FS message. */ #define ANTFS_COMMAND_OFFSET 0x01u /**< The command offset within ANT-FS message. */ @@ -106,18 +152,12 @@ All rights reserved. #define UPLOAD_CRC_OFFSET_LOW 0x06u /**< Upload data CRC offset low. */ #define UPLOAD_CRC_OFFSET_HIGH 0x07u /**< Upload data CRC offset high. */ -// Below compile switches should be provided by antfs_config.h: -// - ANTFS_AUTH_TYPE_PAIRING /**< Use pairing and key exchange authentication. */ -// - ANTFS_AUTH_TYPE_PASSKEY /**< Use passkey authentication. */ -// - ANTFS_AUTH_TYPE_PASSTHROUGH /**< Allow host to bypass authentication. */ -// - ANTFS_INCLUDE_UPLOAD /**< Support upload operation. */ - // Authentication type. The highest level of authentication available is included in the beacon. -#if defined (ANTFS_AUTH_TYPE_PASSKEY) +#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED #define AUTHENTICATION_TYPE COMMAND_TYPE_REQUEST_PASSKEY /**< Passkey and pairing only mode set as authentication type in beacon. */ -#elif defined (ANTFS_AUTH_TYPE_PAIRING) +#elif ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED #define AUTHENTICATION_TYPE COMMAND_TYPE_REQUEST_PAIR /**< Pairing only mode set as authentication type in beacon. */ -#elif defined (ANTFS_AUTH_TYPE_PASSTHROUGH) +#elif ANTFS_CONFIG_AUTH_TYPE_PASSTHROUGH_ENABLED #define AUTHENTICATION_TYPE COMMAND_TYPE_PROCEED /**< Pass-through mode set as authentication type in beacon. */ #else #error "No valid auth type defined" @@ -175,9 +215,9 @@ static volatile uint8_t m_burst_wait; /**< P static uint8_t m_retry; /**< Retry counter */ APP_TIMER_DEF(m_timer_id); /**< Timer ID used with the timer module. */ -#if defined (ANTFS_AUTH_TYPE_PASSKEY) +#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED static uint32_t m_passkey_index; /**< Current location of Tx block (auth string). */ -#endif // ANTFS_AUTH_TYPE_PASSKEY +#endif // ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED // Download/upload. static bool m_is_data_request_pending; /**< Requested data pending. */ @@ -190,9 +230,9 @@ static ulong_union_t m_bytes_remaining; /**< T static ulong_union_t m_max_transfer_index; /**< Upper limit of the current Tx burst block (bytes). */ static uint32_t m_bytes_to_write; /**< Number of bytes to write to file (upload). */ static const uint8_t * mp_upload_data; /**< Address of begin of the buffer that holds data received from upload. */ -#ifdef ANTFS_INCLUDE_UPLOAD +#if ANTFS_CONFIG_UPLOAD_ENABLED static ulong_union_t m_block_size; /**< Number of bytes the client can receive in a single burst. */ -#endif // ANTFS_INCLUDE_UPLOAD +#endif // ANTFS_CONFIG_UPLOAD_ENABLED // CRC verification. static uint32_t m_saved_crc_offset; /**< CRC data offset (bytes) saved at last CRC update (save point). */ @@ -227,7 +267,7 @@ static void wait_burst_request_to_complete(void) { while (m_burst_wait != 0) { - if(m_burst_wait_handler != NULL) + if (m_burst_wait_handler != NULL) { m_burst_wait_handler(); } @@ -307,19 +347,19 @@ static void beacon_transmit(uint32_t message_type) if (message_type == MESG_BROADCAST_DATA_ID) { - if (sd_ant_broadcast_message_tx(ANTFS_CHANNEL, sizeof(tx_buffer), tx_buffer) != NRF_SUCCESS) + if (sd_ant_broadcast_message_tx(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer) != NRF_SUCCESS) { // @note: No implementation needed, as it is a valid and accepted use case for this call // to fail. This call can fail if we are in middle of bursting. } } - else if(message_type == MESG_BURST_DATA_ID) + else if (message_type == MESG_BURST_DATA_ID) { // Send as the first packet of a burst. - const uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, - sizeof(tx_buffer), - tx_buffer, - BURST_SEGMENT_START); + const uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, + sizeof(tx_buffer), + tx_buffer, + BURST_SEGMENT_START); APP_ERROR_CHECK(err_code); wait_burst_request_to_complete(); @@ -373,7 +413,7 @@ static void authenticate_response_transmit(uint8_t response_type, ) { // Send second packet (auth response). - err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_CONTINUE); @@ -395,7 +435,7 @@ static void authenticate_response_transmit(uint8_t response_type, } // Send auth string (last packets of the burst). - err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, password_length, tx_buffer_authenticate, BURST_SEGMENT_END); @@ -410,7 +450,7 @@ static void authenticate_response_transmit(uint8_t response_type, // If the authorization is rejected or there is no valid password, the auth response is the // last packet. - err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_END); @@ -437,7 +477,7 @@ static void authenticate_response_transmit(uint8_t response_type, bool antfs_pairing_resp_transmit(bool accept) { -#if defined(ANTFS_AUTH_TYPE_PAIRING) +#if ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED // This function should only be called when ANT-FS is in PAIRING mode. if ((m_current_state.state != ANTFS_STATE_AUTH) || (m_current_state.sub_state.auth_sub_state != ANTFS_AUTH_SUBSTATE_PAIR)) @@ -463,7 +503,7 @@ bool antfs_pairing_resp_transmit(bool accept) return true; #else return false; -#endif // ANTFS_AUTH_TYPE_PAIRING +#endif // ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED } @@ -474,9 +514,9 @@ bool antfs_pairing_resp_transmit(bool accept) static void event_queue_write(antfs_event_t event_code) { antfs_event_return_t * p_event = NULL; -#ifdef LEDDRIVER_ACTIVE +#if ANTFS_CONFIG_DEBUG_LED_ENABLED uint32_t err_code; -#endif +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED // Check if there is room in the queue for a new event. if (((m_event_queue.head + 1u) & (ANTFS_EVENT_QUEUE_SIZE - 1u)) != m_event_queue.tail) @@ -548,12 +588,12 @@ static void event_queue_write(antfs_event_t event_code) break; case ANTFS_EVENT_PAIRING_REQUEST: -#ifdef LEDDRIVER_ACTIVE +#if ANTFS_CONFIG_DEBUG_LED_ENABLED err_code = bsp_indication_set(BSP_INDICATE_BONDING); APP_ERROR_CHECK(err_code); -#endif // LEDDRIVER_ACTIVE - break; - +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED + break; + default: // No parameters need to be set. @@ -597,7 +637,7 @@ static void download_request_response_transmit(uint8_t response) tx_buffer[6] = m_bytes_remaining.bytes.byte2; tx_buffer[7] = m_bytes_remaining.bytes.byte3; - uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_CONTINUE); @@ -623,7 +663,7 @@ static void download_request_response_transmit(uint8_t response) // If the download was rejected or there is no data to send. // Set response to end since we're not downloading any data. - err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_END); @@ -634,7 +674,7 @@ static void download_request_response_transmit(uint8_t response) else { // Response will continue (data packets + CRC footer to follow). - err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_CONTINUE); @@ -843,7 +883,7 @@ uint32_t antfs_input_data_download(uint16_t index, download_request_response_transmit(response); } // Data index has gone too far and it is not possible to check CRC, fail and let host retry - else if(m_link_burst_index.data > m_saved_crc_offset) + else if (m_link_burst_index.data > m_saved_crc_offset) { response = RESPONSE_INVALID_CRC; download_request_response_transmit(response); @@ -878,11 +918,11 @@ uint32_t antfs_input_data_download(uint16_t index, num_of_bytes_to_burst += BURST_PACKET_SIZE; } - uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, num_of_bytes_to_burst, (uint8_t*)&(p_message[block_offset]), BURST_SEGMENT_CONTINUE); - if(err_code != NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR) + if (err_code != NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR) { // If burst failed before we are able to catch it, we will get a TRANSFER_SEQUENCE_NUMBER_ERROR // The message processing will send client back to correct state @@ -902,7 +942,7 @@ uint32_t antfs_input_data_download(uint16_t index, &(p_message[block_offset]), num_bytes); - if((m_link_burst_index.data - m_temp_crc_offset) > SAVE_DISTANCE) + if ((m_link_burst_index.data - m_temp_crc_offset) > SAVE_DISTANCE) { // Set CRC save point m_saved_transfer_crc = m_saved_buffer_crc; // Set CRC at buffer save point (will always be one behind to account for buffering) @@ -940,11 +980,11 @@ uint32_t antfs_input_data_download(uint16_t index, tx_buffer[6] = (uint8_t)m_transfer_crc; tx_buffer[7] = (uint8_t)(m_transfer_crc >> 8u); - err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_END); - if(err_code != NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR) + if (err_code != NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR) { // If burst failed before we are able to catch it, we will get a TRANSFER_SEQUENCE_NUMBER_ERROR // The message processing will send client back to correct state @@ -970,7 +1010,7 @@ uint32_t antfs_input_data_download(uint16_t index, bool antfs_upload_req_resp_transmit(uint8_t response, const antfs_request_info_t * const p_request_info) { -#if defined(ANTFS_INCLUDE_UPLOAD) +#if ANTFS_CONFIG_UPLOAD_ENABLED if (m_current_state.state != ANTFS_STATE_TRANS || // Only send the response if we were processing an upload request. (m_link_command_in_progress != ANTFS_CMD_UPLOAD_REQUEST_ID)) @@ -1033,7 +1073,7 @@ bool antfs_upload_req_resp_transmit(uint8_t response, tx_buffer[7] = m_link_burst_index.bytes.byte3; - uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_CONTINUE); @@ -1054,7 +1094,7 @@ bool antfs_upload_req_resp_transmit(uint8_t response, tx_buffer[6] = m_block_size.bytes.byte2; tx_buffer[7] = m_block_size.bytes.byte3; - err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_CONTINUE); @@ -1074,7 +1114,7 @@ bool antfs_upload_req_resp_transmit(uint8_t response, tx_buffer[6] = (uint8_t) m_transfer_crc; tx_buffer[7] = (uint8_t)(m_transfer_crc >> 8); - err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_END); @@ -1099,13 +1139,13 @@ bool antfs_upload_req_resp_transmit(uint8_t response, return true; #else return false; -#endif // ANTFS_INCLUDE_UPLOAD +#endif // ANTFS_CONFIG_UPLOAD_ENABLED } bool antfs_upload_data_resp_transmit(bool data_upload_success) { -#if defined(ANTFS_INCLUDE_UPLOAD) +#if ANTFS_CONFIG_UPLOAD_ENABLED // Should be in TRANSPORT layer to send this response. if (m_current_state.state != ANTFS_STATE_TRANS) { @@ -1128,7 +1168,7 @@ bool antfs_upload_data_resp_transmit(bool data_upload_success) beacon_transmit(MESG_BURST_DATA_ID); // Send last packet. - uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_END); @@ -1144,7 +1184,7 @@ bool antfs_upload_data_resp_transmit(bool data_upload_success) return true; #else return false; -#endif // ANTFS_INCLUDE_UPLOAD +#endif // ANTFS_CONFIG_UPLOAD_ENABLED } @@ -1168,7 +1208,7 @@ void antfs_erase_req_resp_transmit(uint8_t response) tx_buffer[6] = 0; tx_buffer[7] = 0; - uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CHANNEL, + uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer, BURST_SEGMENT_END); @@ -1239,7 +1279,7 @@ static void channel_period_set(uint32_t link_period) break; } - const uint32_t err_code = sd_ant_channel_period_set(ANTFS_CHANNEL, period); + const uint32_t err_code = sd_ant_channel_period_set(ANTFS_CONFIG_CHANNEL_NUMBER, period); APP_ERROR_CHECK(err_code); } @@ -1271,9 +1311,9 @@ static void authenticate_layer_transit(void) m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_NONE; m_link_command_in_progress = ANTFS_CMD_NONE; - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); - uint32_t err_code = sd_ant_channel_radio_freq_set(ANTFS_CHANNEL, m_active_beacon_frequency); + uint32_t err_code = sd_ant_channel_radio_freq_set(ANTFS_CONFIG_CHANNEL_NUMBER, m_active_beacon_frequency); APP_ERROR_CHECK(err_code); event_queue_write(ANTFS_EVENT_AUTH); @@ -1330,10 +1370,10 @@ static void link_layer_transit(void) if (m_current_state.state != ANTFS_STATE_OFF) { uint32_t err_code; -#ifdef LEDDRIVER_ACTIVE +#if ANTFS_CONFIG_DEBUG_LED_ENABLED err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); -#endif // LEDDRIVER_ACTIVE +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED m_current_state.state = ANTFS_STATE_LINK; m_current_state.sub_state.link_sub_state = ANTFS_LINK_SUBSTATE_NONE; @@ -1343,7 +1383,7 @@ static void link_layer_transit(void) timeout_disable(); - err_code = sd_ant_channel_radio_freq_set(ANTFS_CHANNEL, m_active_beacon_frequency); + err_code = sd_ant_channel_radio_freq_set(ANTFS_CONFIG_CHANNEL_NUMBER, m_active_beacon_frequency); APP_ERROR_CHECK(err_code); event_queue_write(ANTFS_EVENT_LINK); @@ -1361,11 +1401,11 @@ static void authenticate_layer_cmd_decode(uint8_t control_byte, { // @note: Response variable must have a static storage allocation as it keeps track of the // passkey authentication progress between multiple burst packets. -#if defined (ANTFS_AUTH_TYPE_PASSKEY) +#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED static uint32_t response; -#endif // ANTFS_AUTH_TYPE_PASSKEY +#endif // ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED - if((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0 && m_link_command_in_progress != ANTFS_CMD_NONE) + if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0 && m_link_command_in_progress != ANTFS_CMD_NONE) { // This is something new, and we're busy processing something already, so don't respond return; @@ -1377,7 +1417,7 @@ static void authenticate_layer_cmd_decode(uint8_t control_byte, if (p_command_buffer[ANTFS_COMMAND_OFFSET] == ANTFS_CMD_AUTHENTICATE_ID) { // Make sure it is the correct host - if(m_link_host_serial_number.bytes.byte0 != p_command_buffer[HOST_ID_OFFSET_0] || + if (m_link_host_serial_number.bytes.byte0 != p_command_buffer[HOST_ID_OFFSET_0] || m_link_host_serial_number.bytes.byte1 != p_command_buffer[HOST_ID_OFFSET_1] || m_link_host_serial_number.bytes.byte2 != p_command_buffer[HOST_ID_OFFSET_2] || m_link_host_serial_number.bytes.byte3 != p_command_buffer[HOST_ID_OFFSET_3]) @@ -1397,7 +1437,7 @@ static void authenticate_layer_cmd_decode(uint8_t control_byte, if (control_byte & SEQUENCE_LAST_MESSAGE) { // Don't do anything before the burst completes (last burst message received). - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); authenticate_response_transmit(AUTH_RESPONSE_N_A, ANTFS_REMOTE_FRIENDLY_NAME_MAX, // Send device friendly name if it exists. @@ -1405,19 +1445,19 @@ static void authenticate_layer_cmd_decode(uint8_t control_byte, } break; -#if defined (ANTFS_AUTH_TYPE_PASSTHROUGH) +#if ANTFS_CONFIG_AUTH_TYPE_PASSTHROUGH_ENABLED case COMMAND_TYPE_PROCEED: if (control_byte & SEQUENCE_LAST_MESSAGE) { // Don't do anything before the burst completes (last burst message received). - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); // Proceed directly to transport layer (no authentication required). authenticate_response_transmit(AUTH_RESPONSE_ACCEPT, 0, NULL); } break; -#endif // ANTFS_AUTH_TYPE_PASSTHROUGH -#if defined (ANTFS_AUTH_TYPE_PAIRING) +#endif // ANTFS_CONFIG_AUTH_TYPE_PASSTHROUGH_ENABLED +#if ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED case COMMAND_TYPE_REQUEST_PAIR: if ((control_byte & SEQUENCE_NUMBER_ROLLOVER) == 0) { @@ -1459,7 +1499,7 @@ static void authenticate_layer_cmd_decode(uint8_t control_byte, { // Last burst packet. - timeout_start(ANTFS_PAIRING_TIMEOUT); + timeout_start(ANTFS_CONFIG_PAIRING_TIMEOUT); if (m_friendly_name.friendly_name_size > 0) { m_friendly_name.is_name_set = true; @@ -1471,8 +1511,8 @@ static void authenticate_layer_cmd_decode(uint8_t control_byte, } break; -#endif // ANTFS_AUTH_TYPE_PAIRING -#if defined (ANTFS_AUTH_TYPE_PASSKEY) +#endif // ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED +#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED case COMMAND_TYPE_REQUEST_PASSKEY: if ((control_byte & SEQUENCE_NUMBER_ROLLOVER) == 0) { @@ -1534,13 +1574,13 @@ static void authenticate_layer_cmd_decode(uint8_t control_byte, response = AUTH_RESPONSE_REJECT; } - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_PASSKEY; authenticate_response_transmit(response, 0, NULL); } break; -#endif // ANTFS_AUTH_TYPE_PASSKEY +#endif // ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED default: break; } @@ -1556,7 +1596,7 @@ static void authenticate_layer_cmd_decode(uint8_t control_byte, else if (p_command_buffer[ANTFS_COMMAND_OFFSET] == ANTFS_CMD_PING_ID) { // Reset timeout. - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); m_link_command_in_progress = ANTFS_CMD_NONE; } else @@ -1584,12 +1624,12 @@ static void transport_layer_cmd_decode(uint8_t control_byte, const uint8_t * p_c { case ANTFS_CMD_PING_ID: // Reset timeout. - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); m_link_command_in_progress = ANTFS_CMD_NONE; break; case ANTFS_CMD_DISCONNECT_ID: - if(control_byte & SEQUENCE_LAST_MESSAGE) + if (control_byte & SEQUENCE_LAST_MESSAGE) { // Don't do anything before the burst completes (last burst message received). link_layer_transit(); @@ -1597,7 +1637,7 @@ static void transport_layer_cmd_decode(uint8_t control_byte, const uint8_t * p_c break; case ANTFS_CMD_ERASE_ID: - if(control_byte & SEQUENCE_LAST_MESSAGE) + if (control_byte & SEQUENCE_LAST_MESSAGE) { // Don't do anything before the burst completes (last burst message received). @@ -1607,7 +1647,7 @@ static void transport_layer_cmd_decode(uint8_t control_byte, const uint8_t * p_c // Send erase request to the application. event_queue_write(ANTFS_EVENT_ERASE_REQUEST); - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); m_link_command_in_progress = ANTFS_CMD_ERASE_ID; } break; @@ -1698,13 +1738,13 @@ static void transport_layer_cmd_decode(uint8_t control_byte, const uint8_t * p_c // Send download request to the application for further handling. event_queue_write(ANTFS_EVENT_DOWNLOAD_REQUEST); - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); m_link_command_in_progress = ANTFS_CMD_DOWNLOAD_ID; } break; case ANTFS_CMD_UPLOAD_REQUEST_ID: -#if defined(ANTFS_INCLUDE_UPLOAD) +#if ANTFS_CONFIG_UPLOAD_ENABLED if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0x00) { // First burst packet. @@ -1760,14 +1800,14 @@ static void transport_layer_cmd_decode(uint8_t control_byte, const uint8_t * p_c // Send upload request to the application for further handling. event_queue_write(ANTFS_EVENT_UPLOAD_REQUEST); - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); m_link_command_in_progress = ANTFS_CMD_UPLOAD_REQUEST_ID; } -#endif // ANTFS_INCLUDE_UPLOAD +#endif // ANTFS_CONFIG_UPLOAD_ENABLED break; case ANTFS_CMD_UPLOAD_DATA_ID: -#if defined(ANTFS_INCLUDE_UPLOAD) +#if ANTFS_CONFIG_UPLOAD_ENABLED if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0x00) { // First burst packet. @@ -1847,7 +1887,7 @@ static void transport_layer_cmd_decode(uint8_t control_byte, const uint8_t * p_c } } } -#endif // ANTFS_INCLUDE_UPLOAD +#endif // ANTFS_CONFIG_UPLOAD_ENABLED break; case ANTFS_CMD_LINK_ID: @@ -1862,7 +1902,7 @@ static void transport_layer_cmd_decode(uint8_t control_byte, const uint8_t * p_c m_active_beacon_status1_field.parameters.link_period = p_command_buffer[TRANSPORT_MESSAGE_PERIOD_OFFSET]; - const uint32_t err_code = sd_ant_channel_radio_freq_set(ANTFS_CHANNEL, + const uint32_t err_code = sd_ant_channel_radio_freq_set(ANTFS_CONFIG_CHANNEL_NUMBER, m_active_beacon_frequency); APP_ERROR_CHECK(err_code); @@ -1887,7 +1927,7 @@ static void transport_layer_cmd_decode(uint8_t control_byte, const uint8_t * p_c */ static void upload_data_process(uint8_t control_byte, const uint8_t * p_buffer) { -#if defined(ANTFS_INCLUDE_UPLOAD) +#if ANTFS_CONFIG_UPLOAD_ENABLED if (control_byte & SEQUENCE_LAST_MESSAGE) { // Last burst packet: upload complete. @@ -1917,7 +1957,7 @@ static void upload_data_process(uint8_t control_byte, const uint8_t * p_buffer) // Set initial number of bytes to 8 (size of burst packet). m_bytes_to_write = BURST_PACKET_SIZE; - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); if (m_link_burst_index.data > m_max_transfer_index.data) { @@ -1954,7 +1994,7 @@ static void upload_data_process(uint8_t control_byte, const uint8_t * p_buffer) m_saved_transfer_crc = m_transfer_crc; } } -#endif // ANTFS_INCLUDE_UPLOAD +#endif // ANTFS_CONFIG_UPLOAD_ENABLED } @@ -1964,14 +2004,14 @@ static void transport_layer_transit(void) { if (m_current_state.state != ANTFS_STATE_OFF) { -#ifdef LEDDRIVER_ACTIVE - uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); +#if ANTFS_CONFIG_DEBUG_LED_ENABLED + uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); -#endif // LEDDRIVER_ACTIVE +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED m_current_state.state = ANTFS_STATE_TRANS; m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_NONE; - timeout_start(ANTFS_LINK_COMMAND_TIMEOUT); + timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT); beacon_transmit(MESG_BROADCAST_DATA_ID); @@ -1982,13 +2022,13 @@ static void transport_layer_transit(void) void antfs_message_process(uint8_t * p_message) { -#ifdef LEDDRIVER_ACTIVE +#if ANTFS_CONFIG_DEBUG_LED_ENABLED uint32_t err_code; -#endif - +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED + if (p_message != NULL) { - if ((p_message[BUFFER_INDEX_CHANNEL_NUM] & CHANNEL_NUMBER_MASK) != ANTFS_CHANNEL) + if ((p_message[BUFFER_INDEX_CHANNEL_NUM] & CHANNEL_NUMBER_MASK) != ANTFS_CONFIG_CHANNEL_NUMBER) { // Only process messages corresponding to the ANT-FS channel here. return; @@ -2065,15 +2105,15 @@ void antfs_message_process(uint8_t * p_message) case ANTFS_STATE_AUTH: // Burst failed, retry sending the response - if(!m_retry) + if (!m_retry) { authenticate_layer_transit(); // Reload beacon } else { - if(m_current_state.sub_state.auth_sub_state == ANTFS_AUTH_SUBSTATE_ACCEPT) + if (m_current_state.sub_state.auth_sub_state == ANTFS_AUTH_SUBSTATE_ACCEPT) { - if(m_authenticate_command_type == COMMAND_TYPE_REQUEST_PAIR) + if (m_authenticate_command_type == COMMAND_TYPE_REQUEST_PAIR) { authenticate_response_transmit(AUTH_RESPONSE_ACCEPT, ANTFS_PASSKEY_SIZE, m_initial_parameters.p_pass_key); @@ -2083,11 +2123,11 @@ void antfs_message_process(uint8_t * p_message) authenticate_response_transmit(AUTH_RESPONSE_ACCEPT, 0, NULL); } } - else if(m_current_state.sub_state.auth_sub_state == ANTFS_AUTH_SUBSTATE_REJECT) + else if (m_current_state.sub_state.auth_sub_state == ANTFS_AUTH_SUBSTATE_REJECT) { authenticate_response_transmit(AUTH_RESPONSE_REJECT, 0, NULL); } - else if(m_authenticate_command_type == COMMAND_TYPE_REQUEST_SERIAL) + else if (m_authenticate_command_type == COMMAND_TYPE_REQUEST_SERIAL) { authenticate_response_transmit(AUTH_RESPONSE_N_A, ANTFS_REMOTE_FRIENDLY_NAME_MAX, @@ -2183,10 +2223,10 @@ void antfs_message_process(uint8_t * p_message) break; case EVENT_TX: -#ifdef LEDDRIVER_ACTIVE +#if ANTFS_CONFIG_DEBUG_LED_ENABLED err_code = bsp_indication_set(BSP_INDICATE_SENT_OK); APP_ERROR_CHECK(err_code); -#endif // LEDDRIVER_ACTIVE +#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED // Load beacon. beacon_transmit(MESG_BROADCAST_DATA_ID); break; @@ -2216,13 +2256,14 @@ void antfs_message_process(uint8_t * p_message) void antfs_channel_setup(void) { - const uint8_t network_key[] = ANTFS_NETWORK_KEY; - // Start channel configuration. - uint32_t err_code = sd_ant_network_address_set(ANTFS_NETWORK_NUMBER, (uint8_t*)network_key); + uint32_t err_code = ant_fs_key_set(ANTFS_CONFIG_NETWORK_NUMBER); APP_ERROR_CHECK(err_code); - err_code = sd_ant_channel_assign(ANTFS_CHANNEL, ANTFS_CHANNEL_TYPE, ANTFS_NETWORK_NUMBER, 0); + err_code = sd_ant_channel_assign(ANTFS_CONFIG_CHANNEL_NUMBER, + ANTFS_CHANNEL_TYPE, + ANTFS_CONFIG_NETWORK_NUMBER, + 0); APP_ERROR_CHECK(err_code); // Use the lower 2 bytes of the ESN for device number. @@ -2233,10 +2274,10 @@ void antfs_channel_setup(void) device_number = 2; } - err_code = sd_ant_channel_id_set(ANTFS_CHANNEL, + err_code = sd_ant_channel_id_set(ANTFS_CONFIG_CHANNEL_NUMBER, device_number, - ANTFS_DEVICE_TYPE, - ANTFS_TRANS_TYPE); + ANTFS_CONFIG_DEVICE_TYPE, + ANTFS_CONFIG_TRANS_TYPE); APP_ERROR_CHECK(err_code); // Remain in initialization state until channel is open. @@ -2247,12 +2288,12 @@ void antfs_channel_setup(void) channel_period_set(m_active_beacon_status1_field.parameters.link_period); - err_code = sd_ant_channel_open(ANTFS_CHANNEL); + err_code = sd_ant_channel_open(ANTFS_CONFIG_CHANNEL_NUMBER); APP_ERROR_CHECK(err_code); - err_code = sd_ant_channel_radio_tx_power_set(ANTFS_CHANNEL, - ANTFS_TRANSMIT_POWER, - ANTFS_CUSTOM_TRANSMIT_POWER); + err_code = sd_ant_channel_radio_tx_power_set(ANTFS_CONFIG_CHANNEL_NUMBER, + ANTFS_CONFIG_TRANSMIT_POWER, + ANTFS_CONFIG_CUSTOM_TRANSMIT_POWER); APP_ERROR_CHECK(err_code); m_current_state.state = ANTFS_STATE_LINK; @@ -2337,3 +2378,4 @@ void antfs_init(const antfs_params_t * const p_params, err_code = sd_ant_burst_handler_wait_flag_enable((uint8_t *)(&m_burst_wait)); APP_ERROR_CHECK(err_code); } +#endif // NRF_MODULE_ENABLED(ANTFS) diff --git a/components/libraries/ant_fs/antfs.h b/components/ant/ant_fs/antfs.h similarity index 88% rename from components/libraries/ant_fs/antfs.h rename to components/ant/ant_fs/antfs.h index f06cc8b..d9ba893 100644 --- a/components/libraries/ant_fs/antfs.h +++ b/components/ant/ant_fs/antfs.h @@ -1,14 +1,58 @@ -/* -This software is subject to the license described in the license.txt file included with this software distribution. -You may not use this file except in compliance with this license. -Copyright © Dynastream Innovations Inc. 2012 -All rights reserved. -*/ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2012 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * 1) Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * 2) 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. + * + * 3) Neither the name of Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ /**@file * @brief The ANT-FS client protocol interface. * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012 - * @defgroup ant_fs_client_main ANT-FS client device simulator + * @defgroup ant_fs ANT-FS client device simulator * @{ * @ingroup ant_sdk_utils * @@ -23,7 +67,11 @@ All rights reserved. #include #include #include "defines.h" -#include "antfs_config.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif #define ANTFS_VERSION_MAJOR 1u /**< Version major number. */ #define ANTFS_VERSION_MINOR 0 /**< Version minor number. */ @@ -34,16 +82,8 @@ All rights reserved. #define ANTFS_VERSION_DATE 20090522u /**< Version date. */ // ANT-FS options. -#define ANTFS_NETWORK_NUMBER 0 /**< ANT-FS Network Number. */ -#define ANTFS_CHANNEL 0 /**< ANT Channel Number. */ #define ANTFS_LINK_FREQ 50u /**< RF Frequency (+2400MHz). */ -#define ANTFS_PAIRING_TIMEOUT 120u /**< Pairing timeout (time the UI will wait for a response to the pairing request before switching to the link layer, in seconds). */ -#define ANTFS_LINK_COMMAND_TIMEOUT 10u /**< Command timeout (time the client will wait without receiving any commands before switching to the link layer, in seconds). */ -#define ANTFS_TRANS_TYPE 5u /**< ANT-FS Transmission Type. */ #define ANTFS_CHANNEL_TYPE CHANNEL_TYPE_MASTER /**< ANT-FS Client Channel Type. */ -#define ANTFS_BEACON_PERIOD_STATUS BEACON_PERIOD_4_HZ /**< ANT-FS Beacon Message Period. */ -#define ANTFS_TRANSMIT_POWER 3u /**< ANT Transmit Power (0dBm). */ -#define ANTFS_CUSTOM_TRANSMIT_POWER 0u /**< ANT Custom Transmit Power (0dBm). */ #define ANTFS_AUTH_STRING_MAX 255u /**< Maximum size of authentication strings (passkey/friendly name). */ #define ANTFS_PASSKEY_SIZE 16u /**< Passkey size. */ #define ANTFS_FRIENDLY_NAME_MAX 16u /**< Maximum size of friendly name received from host. */ @@ -64,19 +104,21 @@ All rights reserved. #define DATA_AVAILABLE_FLAG_SHIFT 0x05u /**< Shift value for masking out data available bit. */ #define DATA_AVAILABLE_FLAG_MASK (0x01u << DATA_AVAILABLE_FLAG_SHIFT) /**< Data available bitmask. */ +#if ANTFS_ENABLED // Build the default beacon settings. -#if defined (ANTFS_AUTH_TYPE_PAIRING) +#if ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED #define ANTFS_PAIRING_BIT PAIRING_AVAILABLE_FLAG_MASK /**< Build pairing enabled default beacon setting. */ #else #define ANTFS_PAIRING_BIT 0x00u /**< Build pairing disabled default beacon setting. */ -#endif // ANTFS_INCLUDE_PAIRING -#if defined (ANTFS_INCLUDE_UPLOAD) +#endif // ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED +#if ANTFS_CONFIG_UPLOAD_ENABLED #define ANTFS_UPLOAD_BIT UPLOAD_ENABLED_FLAG_MASK /**< Build upload enabled default beacon setting. */ #else #define ANTFS_UPLOAD_BIT 0x00u /**< Build upload disabled default beacon setting. */ -#endif // ANTFS_INCLUDE_UPLOAD +#endif // ANTFS_CONFIG_UPLOAD_ENABLED -#define ANTFS_DEFAULT_BEACON (ANTFS_BEACON_PERIOD_STATUS | ANTFS_UPLOAD_BIT | ANTFS_PAIRING_BIT | DATA_AVAILABLE_FLAG_MASK) /**< Define the default beacon setting. */ +#define ANTFS_DEFAULT_BEACON (ANTFS_CONFIG_BEACON_STATUS_PERIOD | ANTFS_UPLOAD_BIT | ANTFS_PAIRING_BIT | DATA_AVAILABLE_FLAG_MASK) /**< Define the default beacon setting. */ +#endif // ANTFS_ENABLED // Download/Upload responses. #define RESPONSE_MESSAGE_OK 0x00u /**< Download request ok. */ @@ -343,6 +385,11 @@ void antfs_message_process(uint8_t * p_message); */ void antfs_channel_setup(void); + +#ifdef __cplusplus +} +#endif + #endif // ANTFS_H__ /** diff --git a/components/ant/ant_fs/crc.c b/components/ant/ant_fs/crc.c new file mode 100644 index 0000000..294d7df --- /dev/null +++ b/components/ant/ant_fs/crc.c @@ -0,0 +1,99 @@ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2012 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * 1) Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * 2) 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. + * + * 3) Neither the name of Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ + +#include "crc.h" +#include "compiler_abstraction.h" + + +/**@brief Function for updating the current CRC-16 value for a single byte input. + * + * @param[in] current_crc The current calculated CRC-16 value. + * @param[in] byte The input data byte for the computation. + * + * @return The updated CRC-16 value, based on the input supplied. + */ +static __INLINE uint16_t crc16_get(uint16_t current_crc, uint8_t byte) +{ + static const uint16_t crc16_table[16] = + { + 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, + 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 + }; + + uint16_t temp; + + // Compute checksum of lower four bits of a byte. + temp = crc16_table[current_crc & 0xF]; + current_crc = (current_crc >> 4u) & 0x0FFFu; + current_crc = current_crc ^ temp ^ crc16_table[byte & 0xF]; + + // Now compute checksum of upper four bits of a byte. + temp = crc16_table[current_crc & 0xF]; + current_crc = (current_crc >> 4u) & 0x0FFFu; + current_crc = current_crc ^ temp ^ crc16_table[(byte >> 4u) & 0xF]; + + return current_crc; +} + + +uint16_t crc_crc16_update(uint16_t current_crc, const volatile void * p_data, uint32_t size) +{ + uint8_t * p_block = (uint8_t *)p_data; + + while (size != 0) + { + current_crc = crc16_get(current_crc, *p_block); + p_block++; + size--; + } + + return current_crc; +} diff --git a/components/ant/ant_fs/crc.h b/components/ant/ant_fs/crc.h new file mode 100644 index 0000000..e97a45f --- /dev/null +++ b/components/ant/ant_fs/crc.h @@ -0,0 +1,95 @@ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2012 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * 1) Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * 2) 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. + * + * 3) Neither the name of Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ + +/** @file + * @brief The CRC-16 interface. + * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012 + * @defgroup ant_fs_client_main ANT-FS client device simulator + * @{ + * @ingroup ant_fs + * + * @brief The ANT-FS client device simulator. + * + */ + +#ifndef CRC_H__ +#define CRC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for calculating CRC-16 in blocks. + * + * Feed each consecutive data block into this function, along with the current value of current_crc + * as returned by the previous call of this function. The first call of this function should pass + * the initial value (usually 0) of the crc in current_crc. + + * @param[in] current_crc The current calculated CRC-16 value. + * @param[in] p_data The input data block for computation. + * @param[in] size The size of the input data block in bytes. + * + * @return The updated CRC-16 value, based on the input supplied. + */ +uint16_t crc_crc16_update(uint16_t current_crc, const volatile void * p_data, uint32_t size); + + +#ifdef __cplusplus +} +#endif + +#endif // CRC_H__ + +/** + *@} + **/ diff --git a/components/ant/ant_fs/defines.h b/components/ant/ant_fs/defines.h new file mode 100644 index 0000000..a053f22 --- /dev/null +++ b/components/ant/ant_fs/defines.h @@ -0,0 +1,113 @@ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2012 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * 1) Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * 2) 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. + * + * 3) Neither the name of Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ + +/**@file + * @brief Definitions. + * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012 + * @defgroup ant_fs_client_main ANT-FS client device simulator + * @{ + * @ingroup nrf_ant_fs_client + * + * @brief The ANT-FS client device simulator. + * + */ + +#ifndef DEFINES_H__ +#define DEFINES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_ULONG 0xFFFFFFFFu /**< The Max value for the type. */ + +/**@brief uint16_t type presentation as an union. */ +typedef union +{ + uint16_t data; /**< The data content. */ + + struct + { + uint8_t low; /**< The low byte of the data content. */ + uint8_t high; /**< The high byte of the data content. */ + } bytes; +} ushort_union_t; + +/**@brief uint32_t type presentation as an union. */ +typedef union +{ + uint32_t data; /**< The data content as a single variable. */ + uint8_t data_bytes[sizeof(uint32_t)]; /**< The data content as a byte array. */ + + struct + { + // The least significant byte of the uint32_t in this structure is referenced by byte0. + uint8_t byte0; /**< Byte 0 of the data content. */ + uint8_t byte1; /**< Byte 1 of the data content. */ + uint8_t byte2; /**< Byte 2 of the data content. */ + uint8_t byte3; /**< Byte 3 of the data content. */ + } bytes; +} ulong_union_t; + +#define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ + + +#ifdef __cplusplus +} +#endif + +#endif // DEFINES_H__ + +/** + *@} + **/ diff --git a/components/ant/ant_key_manager/ant_key_manager.c b/components/ant/ant_key_manager/ant_key_manager.c index 9404945..8051286 100644 --- a/components/ant/ant_key_manager/ant_key_manager.c +++ b/components/ant/ant_key_manager/ant_key_manager.c @@ -1,15 +1,46 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -#include "stdio.h" + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_KEY_MANAGER) +#include #include "ant_key_manager.h" #include "ant_key_manager_config.h" #include "ant_interface.h" @@ -33,3 +64,5 @@ uint32_t ant_fs_key_set(uint8_t network_number) { return sd_ant_network_address_set(network_number, m_ant_fs_network_key); } + +#endif // NRF_MODULE_ENABLED(ANT_KEY_MANAGER) diff --git a/components/ant/ant_key_manager/ant_key_manager.h b/components/ant/ant_key_manager/ant_key_manager.h index 0c571a8..b763425 100644 --- a/components/ant/ant_key_manager/ant_key_manager.h +++ b/components/ant/ant_key_manager/ant_key_manager.h @@ -1,18 +1,50 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_KEY_MANAGER_H__ #define ANT_KEY_MANAGER_H__ -#include "stdint.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif /** * @file @@ -64,4 +96,9 @@ uint32_t ant_fs_key_set(uint8_t network_number); * @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_KEY_MANAGER_H__ diff --git a/components/ant/ant_key_manager/config/ant_key_manager_config.h b/components/ant/ant_key_manager/config/ant_key_manager_config.h index 4ee83b7..a071aea 100644 --- a/components/ant/ant_key_manager/config/ant_key_manager_config.h +++ b/components/ant/ant_key_manager/config/ant_key_manager_config.h @@ -1,18 +1,50 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_KEY_MANAGER_CONFIG_H__ #define ANT_KEY_MANAGER_CONFIG_H__ +#ifdef __cplusplus +extern "C" { +#endif + /** * @addtogroup ant_key_manager * @{ @@ -23,11 +55,16 @@ #endif //ANT_PLUS_NETWORK_KEY #ifndef ANT_FS_NETWORK_KEY - #define ANT_FS_NETWORK_KEY {0, 0, 0, 0, 0, 0, 0, 0} /**< The ANT-FS network key. */ + #define ANT_FS_NETWORK_KEY {0, 0, 0, 0, 0, 0, 0, 0} /**< The ANT-FS network key. */ #endif // ANT_FS_NETWORK_KEY /** * @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_KEY_MANAGER_CONFIG_H__ diff --git a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c b/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c index 743b2cf..7ca766e 100644 --- a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c +++ b/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c @@ -1,22 +1,59 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + #include "nrf_assert.h" #include "app_error.h" #include "ant_interface.h" -#include "app_util.h" #include "ant_bpwr.h" -#include "ant_bpwr_page_logger.h" -#include "app_error.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR" +#if ANT_BPWR_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_INFO_COLOR +#else // ANT_BPWR_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_LOG_ENABLED +#include "nrf_log.h" #define BPWR_CALIB_INT_TIMEOUT ((ANT_CLOCK_FREQUENCY * BPWR_CALIBRATION_TIMOUT_S) / BPWR_MSG_PERIOD) // calibration timeout in ant message period's unit @@ -54,7 +91,7 @@ static ret_code_t ant_bpwr_init(ant_bpwr_profile_t * p_profile, p_profile->page_80 = DEFAULT_ANT_COMMON_page80(); p_profile->page_81 = DEFAULT_ANT_COMMON_page81(); - LOG_BPWR("ANT B-PWR channel %u init\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT B-PWR channel %u init\r\n", p_profile->channel_number); return ant_channel_init(p_channel_config); } @@ -175,7 +212,7 @@ static void sens_message_encode(ant_bpwr_profile_t * p_profile, uint8_t * p_mess p_bpwr_message_payload->page_number = next_page_number_get(p_profile); - LOG_BPWR("B-PWR tx page: %u\r\n", p_bpwr_message_payload->page_number); + NRF_LOG_INFO("B-PWR tx page: %u\r\n", p_bpwr_message_payload->page_number); switch (p_bpwr_message_payload->page_number) { @@ -209,7 +246,7 @@ static void sens_message_encode(ant_bpwr_profile_t * p_profile, uint8_t * p_mess default: return; } - LOG_BPWR("\r\n"); + p_profile->evt_handler(p_profile, (ant_bpwr_evt_t)p_bpwr_message_payload->page_number); } @@ -248,7 +285,7 @@ static void disp_message_decode(ant_bpwr_profile_t * p_profile, uint8_t * p_mess const ant_bpwr_message_layout_t * p_bpwr_message_payload = (ant_bpwr_message_layout_t *)p_message_payload; - LOG_BPWR("B-PWR rx page: %u\r\n", p_bpwr_message_payload->page_number); + NRF_LOG_INFO("B-PWR rx page: %u\r\n", p_bpwr_message_payload->page_number); switch (p_bpwr_message_payload->page_number) { @@ -281,10 +318,9 @@ static void disp_message_decode(ant_bpwr_profile_t * p_profile, uint8_t * p_mess break; default: - LOG_BPWR("\r\n"); return; } - LOG_BPWR("\r\n"); + p_profile->evt_handler(p_profile, (ant_bpwr_evt_t)p_bpwr_message_payload->page_number); } @@ -309,7 +345,7 @@ ret_code_t ant_bpwr_calib_request(ant_bpwr_profile_t * p_profile, ant_bpwr_page1 { p_profile->_cb.p_disp_cb->calib_timeout = BPWR_CALIB_INT_TIMEOUT; // initialize watch on calibration's time-out p_profile->_cb.p_disp_cb->calib_stat = BPWR_DISP_CALIB_REQUESTED; - LOG_BPWR("Start calibration process\r\n"); + NRF_LOG_INFO("Start calibration process\r\n"); } return err_code; } @@ -360,7 +396,7 @@ static void service_calib(ant_bpwr_profile_t * p_profile, uint8_t event) return; } - LOG_BPWR("End calibration process\r\n"); + NRF_LOG_INFO("End calibration process\r\n"); p_profile->_cb.p_disp_cb->calib_stat = BPWR_DISP_CALIB_NONE; p_profile->evt_handler(p_profile, bpwr_event); @@ -384,7 +420,7 @@ static void ant_message_send(ant_bpwr_profile_t * p_profile) ret_code_t ant_bpwr_disp_open(ant_bpwr_profile_t * p_profile) { - LOG_BPWR("ANT B-PWR %u open\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT B-PWR %u open\r\n", p_profile->channel_number); return sd_ant_channel_open(p_profile->channel_number); } @@ -394,7 +430,7 @@ ret_code_t ant_bpwr_sens_open(ant_bpwr_profile_t * p_profile) // Fill tx buffer for the first frame ant_message_send(p_profile); - LOG_BPWR("ANT B-PWR %u open\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT B-PWR %u open\r\n", p_profile->channel_number); return sd_ant_channel_open(p_profile->channel_number); } @@ -412,7 +448,7 @@ void ant_bpwr_sens_evt_handler(ant_bpwr_profile_t * p_profile, ant_evt_t * p_ant break; case EVENT_RX: - p_message = (ANT_MESSAGE *)p_ant_event->evt_buffer; + p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; if (p_message->ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID) { @@ -432,7 +468,7 @@ void ant_bpwr_disp_evt_handler(ant_bpwr_profile_t * p_profile, ant_evt_t * p_ant { if (p_ant_event->channel == p_profile->channel_number) { - ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->evt_buffer; + ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; switch (p_ant_event->event) { @@ -453,4 +489,4 @@ void ant_bpwr_disp_evt_handler(ant_bpwr_profile_t * p_profile, ant_evt_t * p_ant } } - +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h b/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h index 2eec902..e9f007f 100644 --- a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h +++ b/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 - * @defgroup ant_sdk_profiles_bpwr Bicycle Power profile + * @defgroup ant_bpwr Bicycle Power profile * @{ * @ingroup ant_sdk_profiles * @brief This module implements the Bicycle Power profile. @@ -173,6 +201,10 @@ typedef void (* ant_bpwr_calib_handler_t) (ant_bpwr_profile_t *, ant_bpwr_page1_ #include "ant_bpwr_local.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Bicycle Power Sensor configuration structure. */ typedef struct { @@ -334,5 +366,10 @@ uint32_t ant_bpwr_calib_request(ant_bpwr_profile_t * p_profile, ant_bpwr_page1_d /** * @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_BICYCLE_POWER_H__ diff --git a/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h b/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h index e2f9b77..3059d54 100644 --- a/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h +++ b/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. * @@ -29,8 +57,12 @@ #include #include "ant_bpwr.h" +#ifdef __cplusplus +extern "C" { +#endif + /** - * @addtogroup ant_sdk_profiles_bpwr + * @addtogroup ant_bpwr * @{ */ @@ -62,4 +94,9 @@ typedef struct /** * @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_LOCAL_H__ diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c index b94c859..fa8f723 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c @@ -1,19 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + #include "ant_bpwr_common_data.h" #include "ant_bpwr_utils.h" -#include "ant_bpwr_page_logger.h" -#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_COMMON" +#if ANT_BPWR_COMMON_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_COMMON_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_COMMON_INFO_COLOR +#else // ANT_BPWR_COMMON_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_COMMON_LOG_ENABLED +#include "nrf_log.h" /**@brief BPWR common page data layout structure. */ typedef struct @@ -31,11 +69,11 @@ static void cadence_data_log(ant_bpwr_common_data_t const * p_common_data) { if (p_common_data->instantaneous_cadence == 0xFF) { - LOG_CADENCE("instantaneous cadence: -- rpm\n\r"); + NRF_LOG_INFO("instantaneous cadence: -- rpm\r\n\n"); } else { - LOG_CADENCE("instantaneous cadence: %u rpm\n\r", + NRF_LOG_INFO("instantaneous cadence: %u rpm\r\n\n", p_common_data->instantaneous_cadence); } } @@ -57,3 +95,5 @@ void ant_bpwr_cadence_decode(uint8_t const * p_page_buffer, cadence_data_log(p_common_data); } + +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h index d76424a..187e6d5 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BPWR_COMMON_DATA_H__ @@ -22,13 +50,17 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for BPWR common data. * * @details This structure stores data that is not associated with a particular page. */ typedef struct { - uint8_t instantaneous_cadence; ///< Crank cadence (rpm, 0-254, 255-> invalid). + uint8_t instantaneous_cadence; ///< Crank cadence (rpm, 0 - 254, 255-> invalid). } ant_bpwr_common_data_t; /**@brief Initialize common data. @@ -59,5 +91,10 @@ void ant_bpwr_cadence_encode(uint8_t * p_page_buffer, void ant_bpwr_cadence_decode(uint8_t const * p_page_buffer, ant_bpwr_common_data_t * p_common_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_COMMON_DATA_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c index b1c476e..ec885e0 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c @@ -1,20 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + #include #include "ant_bpwr_page_1.h" -#include "ant_bpwr_page_logger.h" -#include "app_util.h" -#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_PAGE_1" +#if ANT_BPWR_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_PAGE_1_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_1_INFO_COLOR +#else // ANT_BPWR_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_PAGE_1_LOG_ENABLED +#include "nrf_log.h" /**@brief bicycle power page 1 data layout structure. */ typedef struct @@ -54,7 +91,7 @@ typedef struct static void page1_data_log(ant_bpwr_page1_data_t const * p_page_data) { - LOG_PAGE1("Calibration id: %u\n\r", p_page_data->calibration_id); + NRF_LOG_INFO("Calibration id: %u\r\n", p_page_data->calibration_id); switch (p_page_data->calibration_id) { @@ -65,8 +102,8 @@ static void page1_data_log(ant_bpwr_page1_data_t const * p_page_data) case ANT_BPWR_CALIB_ID_MANUAL_SUCCESS: /* fall through */ case ANT_BPWR_CALIB_ID_FAILED: - LOG_PAGE1("General calibration data: %u\n\r", p_page_data->data.general_calib); - + NRF_LOG_INFO("General calibration data: %u\r\n", + p_page_data->data.general_calib); /* fall through */ case ANT_BPWR_CALIB_ID_AUTO: /* fall through */ @@ -75,21 +112,21 @@ static void page1_data_log(ant_bpwr_page1_data_t const * p_page_data) switch (p_page_data->auto_zero_status) { case ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED: - LOG_PAGE1("Auto zero not supported\n\r"); + NRF_LOG_INFO("Auto zero not supported\r\n\n"); break; case ANT_BPWR_AUTO_ZERO_OFF: - LOG_PAGE1("Auto zero off\n\r"); + NRF_LOG_INFO("Auto zero off\r\n\n"); break; case ANT_BPWR_AUTO_ZERO_ON: - LOG_PAGE1("Auto zero on\n\r"); + NRF_LOG_INFO("Auto zero on\r\n\n"); break; } break; case ANT_BPWR_CALIB_ID_CTF: - LOG_PAGE1("Not supported\n\r"); + NRF_LOG_INFO("Not supported\r\n\n"); break; case ANT_BPWR_CALIB_ID_CUSTOM_REQ: @@ -99,17 +136,13 @@ static void page1_data_log(ant_bpwr_page1_data_t const * p_page_data) case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE: /* fall through */ case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE_SUCCESS: - LOG_PAGE1("Manufacture specyfic: "); - - for (uint8_t i = 0; i < sizeof (p_page_data->data.custom_calib); i++) - { - LOG_PAGE1(" %u", p_page_data->data.custom_calib[i]); - } - LOG_PAGE1("\n\r"); + NRF_LOG_INFO("Manufacture specyfic: "); + NRF_LOG_HEXDUMP_INFO((uint8_t*)p_page_data->data.custom_calib, + sizeof (p_page_data->data.custom_calib)); break; default: // shouldn't occur - LOG_PAGE1("Unsupported calibration ID\n\r"); + NRF_LOG_INFO("Unsupported calibration ID\r\n\n"); break; } } @@ -150,7 +183,7 @@ void ant_bpwr_page_1_encode(uint8_t * p_page_buffer, break; case ANT_BPWR_CALIB_ID_CTF: - LOG_PAGE1("Not supported\n\r"); + NRF_LOG_INFO("Not supported\r\n"); break; case ANT_BPWR_CALIB_ID_AUTO_SUPPORT: @@ -212,7 +245,7 @@ void ant_bpwr_page_1_decode(uint8_t const * p_page_buffer, break; case ANT_BPWR_CALIB_ID_CTF: - LOG_PAGE1("Not supported\n\r"); + NRF_LOG_INFO("Not supported\r\n"); break; case ANT_BPWR_CALIB_ID_AUTO_SUPPORT: @@ -250,4 +283,4 @@ void ant_bpwr_page_1_decode(uint8_t const * p_page_buffer, page1_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h index 1962458..094a110 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BPWR_PAGE_1_H__ @@ -22,6 +50,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief BPWR Calibration ID. */ typedef enum @@ -96,5 +128,10 @@ void ant_bpwr_page_1_decode(uint8_t const * p_page_buffer, ant_bpwr_page1_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_PAGE_1_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c index e3fe474..121b610 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c @@ -1,19 +1,56 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + #include "ant_bpwr_page_16.h" -#include "ant_bpwr_page_logger.h" -#include "app_util.h" -#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_PAGE_16" +#if ANT_BPWR_PAGE_16_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_PAGE_16_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_16_INFO_COLOR +#else // ANT_BPWR_PAGE_16_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_PAGE_16_LOG_ENABLED +#include "nrf_log.h" /**@brief bicycle power page 16 data layout structure. */ typedef struct @@ -28,20 +65,20 @@ typedef struct static void page16_data_log(ant_bpwr_page16_data_t const * p_page_data) { - LOG_PAGE16("event count: %u\n\r", p_page_data->update_event_count); + NRF_LOG_INFO("event count: %u\r\n", p_page_data->update_event_count); if (p_page_data->pedal_power.byte != 0xFF) { - LOG_PAGE16("pedal power: %u %%\n\r", + NRF_LOG_INFO("pedal power: %u %%\r\n", p_page_data->pedal_power.items.distribution); } else { - LOG_PAGE16("pedal power: --\n\r"); + NRF_LOG_INFO("pedal power: --\r\n"); } - LOG_PAGE16("accumulated power: %u W\n\r", p_page_data->accumulated_power); - LOG_PAGE16("instantaneous power: %u W\n\r", p_page_data->instantaneous_power); + NRF_LOG_INFO("accumulated power: %u W\r\n", p_page_data->accumulated_power); + NRF_LOG_INFO("instantaneous power: %u W\r\n", p_page_data->instantaneous_power); } @@ -77,4 +114,4 @@ void ant_bpwr_page_16_decode(uint8_t const * p_page_buffer, page16_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h index caf0413..b282e2b 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BPWR_PAGE_16_H__ @@ -22,6 +50,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for Bicycle Power data page 16. * * @note This structure implements only page 16 specific data. @@ -71,5 +103,10 @@ void ant_bpwr_page_16_encode(uint8_t * p_page_buffer, void ant_bpwr_page_16_decode(uint8_t const * p_page_buffer, ant_bpwr_page16_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_PAGE_16_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c index cbbd31c..75d4cc3 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c @@ -1,25 +1,61 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + #include "ant_bpwr_page_17.h" -#include "app_util.h" -#include "ant_bpwr_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_PAGE_17" +#if ANT_BPWR_PAGE_17_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_PAGE_17_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_17_INFO_COLOR +#else // ANT_BPWR_PAGE_17_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_PAGE_17_LOG_ENABLED +#include "nrf_log.h" static void page17_data_log(ant_bpwr_page17_data_t const * p_page_data) { - LOG_PAGE17("Wheel:\n\r"); - #ifdef TRACE_BPWR_PAGE_17_ENABLE + NRF_LOG_INFO("Wheel:\r\n"); ant_bpwr_page_torque_log((ant_bpwr_page_torque_data_t *) p_page_data); - #endif // TRACE_BPWR_PAGE_17_ENABLE } @@ -38,4 +74,4 @@ void ant_bpwr_page_17_decode(uint8_t const * p_page_buffer, page17_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h index 6964655..3808144 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BPWR_PAGE_17_H__ @@ -23,6 +51,10 @@ #include #include "ant_bpwr_page_torque.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for Bicycle Power data page 17. * * @note This structure implements only page 17 specific data. @@ -49,5 +81,10 @@ void ant_bpwr_page_17_encode(uint8_t * p_page_buffer, void ant_bpwr_page_17_decode(uint8_t const * p_page_buffer, ant_bpwr_page17_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_PAGE_17_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c index 68a26c5..fbff37f 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c @@ -1,25 +1,61 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + #include "ant_bpwr_page_18.h" -#include "app_util.h" -#include "ant_bpwr_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_PAGE_18" +#if ANT_BPWR_PAGE_18_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_PAGE_18_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_18_INFO_COLOR +#else // ANT_BPWR_PAGE_18_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_PAGE_18_LOG_ENABLED +#include "nrf_log.h" static void page18_data_log(ant_bpwr_page18_data_t const * p_page_data) { - LOG_PAGE18("Crank:\n\r"); - #ifdef TRACE_BPWR_PAGE_18_ENABLE + NRF_LOG_INFO("Crank:\r\n"); ant_bpwr_page_torque_log((ant_bpwr_page_torque_data_t *) p_page_data); - #endif // TRACE_BPWR_PAGE_18_ENABLE } @@ -38,4 +74,4 @@ void ant_bpwr_page_18_decode(uint8_t const * p_page_buffer, page18_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h index 2a71b96..4252abc 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h @@ -1,3 +1,42 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BPWR_PAGE_18_H__ #define ANT_BPWR_PAGE_18_H__ @@ -11,6 +50,10 @@ #include #include "ant_bpwr_page_torque.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for Bicycle Power data page 18. * * @note This structure implements only page 18 specific data. @@ -37,5 +80,10 @@ void ant_bpwr_page_18_encode(uint8_t * p_page_buffer, void ant_bpwr_page_18_decode(uint8_t const * p_page_buffer, ant_bpwr_page18_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_PAGE_18_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c index 386ea02..7fa0b29 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c @@ -1,21 +1,58 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BPWR) + #include #include "ant_bpwr_page_torque.h" #include "ant_bpwr_utils.h" -#include "app_util.h" -#include "app_trace.h" -#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "ANT_BPWR_PAGE_TORQUE" +#if ANT_BPWR_PAGE_TORQUE_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BPWR_PAGE_TORQUE_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_TORQUE_INFO_COLOR +#else // ANT_BPWR_PAGE_TORQUE_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BPWR_PAGE_TORQUE_LOG_ENABLED +#include "nrf_log.h" /**@brief bicycle power page torque data layout structure. */ typedef struct @@ -35,12 +72,12 @@ void ant_bpwr_page_torque_log(ant_bpwr_page_torque_data_t const * p_page_data) uint16_t period = ANT_BPWR_TORQUE_PERIOD_RESCALE(p_page_data->period); uint32_t acc_torque = ANT_BPWR_ACC_TORQUE_RESCALE(p_page_data->accumulated_torque); - app_trace_log("event count: %u\n\r", p_page_data->update_event_count); - app_trace_log("tick: %u\n\r", p_page_data->tick); - app_trace_log("period: %u.%03us\n\r", + NRF_LOG_INFO("event count: %u\r\n", p_page_data->update_event_count); + NRF_LOG_INFO("tick: %u\r\n", p_page_data->tick); + NRF_LOG_INFO("period: %u.%03us\r\n", (unsigned int)(period / ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION), (unsigned int)(period % ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION)); - app_trace_log("accumulated torque: %u.%01uNm\n\r", + NRF_LOG_INFO("accumulated torque: %u.%01uNm\r\n", (unsigned int)(acc_torque / ANT_BPWR_ACC_TORQUE_DISP_PRECISION), (unsigned int)(acc_torque % ANT_BPWR_ACC_TORQUE_DISP_PRECISION)); } @@ -73,4 +110,4 @@ void ant_bpwr_page_torque_decode(uint8_t const * p_page_buffer, p_page_data->accumulated_torque = uint16_decode(p_incoming_data->accumulated_torque); } - +#endif // NRF_MODULE_ENABLED(ANT_BPWR) diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h index ace1e15..1463dd8 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BPWR_PAGE_TORQUE_COMMON_H__ @@ -22,6 +50,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Common data structure for Bicycle Power data pages 17, 18. * * @note This structure implements specific data that is common for pages 17, 18. @@ -66,5 +98,10 @@ void ant_bpwr_page_torque_decode(uint8_t const * p_page_buffer, */ void ant_bpwr_page_torque_log(ant_bpwr_page_torque_data_t const * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_PAGE_TORQUE_COMMON_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h index 5707db0..560b33e 100644 --- a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h +++ b/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BPWR_PAGES_H__ @@ -17,8 +45,8 @@ * * @defgroup ant_sdk_profiles_bpwr_pages Bicycle Power profile pages * @{ - * @ingroup ant_sdk_profiles_bpwr - * @brief This module implements functions for the BPWR data pages. + * @ingroup ant_bpwr + * @brief This module implements functions for the BPWR data pages. */ #include "ant_bpwr_page_1.h" // Calibration message main data page. @@ -29,5 +57,14 @@ #include "ant_common_page_80.h" // Manufacturer's information data page. #include "ant_common_page_81.h" // Product information data page. +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_PAGES_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bpwr/pages/logger/ant_bpwr_page_logger.h b/components/ant/ant_profiles/ant_bpwr/pages/logger/ant_bpwr_page_logger.h deleted file mode 100644 index 7f5a334..0000000 --- a/components/ant/ant_profiles/ant_bpwr/pages/logger/ant_bpwr_page_logger.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 ANT_BPWR_PAGE_LOGGER_H__ -#define ANT_BPWR_PAGE_LOGGER_H__ - -#ifdef TRACE_BPWR_GENERAL_ENABLE -#include "app_trace.h" -#define LOG_BPWR app_trace_log -#else -#define LOG_BPWR(...) -#endif // TRACE_BPWR_GENERAL_ENABLE - -#ifdef TRACE_BPWR_PAGE_1_ENABLE -#include "app_trace.h" -#define LOG_PAGE1 app_trace_log -#else -#define LOG_PAGE1(...) -#endif // TRACE_BPWR_PAGE_1_ENABLE - -#ifdef TRACE_BPWR_PAGE_16_ENABLE -#include "app_trace.h" -#define LOG_PAGE16 app_trace_log -#else -#define LOG_PAGE16(...) -#endif // TRACE_BPWR_PAGE_16_ENABLE - -#ifdef TRACE_BPWR_PAGE_17_ENABLE -#include "app_trace.h" -#define LOG_PAGE17 app_trace_log -#else -#define LOG_PAGE17(...) -#endif // TRACE_BPWR_PAGE_17_ENABLE - -#ifdef TRACE_BPWR_PAGE_18_ENABLE -#include "app_trace.h" -#define LOG_PAGE18 app_trace_log -#else -#define LOG_PAGE18(...) -#endif // TRACE_BPWR_PAGE_18_ENABLE - -#if ((defined TRACE_BPWR_PAGE_18_ENABLE) || (defined TRACE_BPWR_PAGE_17_ENABLE) || (defined TRACE_BPWR_PAGE_16_ENABLE)) -#include "app_trace.h" -#define LOG_CADENCE app_trace_log -#else -#define LOG_CADENCE(...) -#endif // ((defined TRACE_BPWR_PAGE_18_ENABLE) || (defined TRACE_BPWR_PAGE_17_ENABLE) || (defined TRACE_BPWR_PAGE_16_ENABLE)) - -#endif // ANT_BPWR_PAGE_LOGGER_H__ diff --git a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c b/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c index 3b2d909..9f0af3b 100644 --- a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c +++ b/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ant_bpwr_simulator.h" @@ -107,7 +135,7 @@ void ant_bpwr_simulator_one_iteration(ant_bpwr_simulator_t * p_simulator, ant_bp } p_simulator->p_profile->BPWR_PROFILE_instantaneous_cadence = p_simulator->_cb.cadence_sensorsim_state.current_val; - p_simulator->p_profile->BPWR_PROFILE_wheel_period = TORQUE_PERIOD; + p_simulator->p_profile->BPWR_PROFILE_wheel_period += TORQUE_PERIOD; p_simulator->_cb.tick_incr += SIMULATOR_TIME_INCREMENT; p_simulator->p_profile->BPWR_PROFILE_wheel_tick += diff --git a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h b/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h index f20ce1a..a1e8309 100644 --- a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h +++ b/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BPWR_SIMULATOR_H__ @@ -38,6 +66,10 @@ #include "sensorsim.h" #include "ant_bpwr_simulator_local.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief BPWR simulator configuration structure. */ typedef struct { @@ -83,5 +115,10 @@ void ant_bpwr_simulator_increment(ant_bpwr_simulator_t * p_simulator); */ void ant_bpwr_simulator_decrement(ant_bpwr_simulator_t * p_simulator); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_SIMULATOR_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h b/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h index 4281c32..c7edae1 100644 --- a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h +++ b/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BPWR_SIMULATOR_LOCAL_H__ @@ -19,7 +47,11 @@ #include "ant_bpwr.h" #include "sensorsim.h" -/** +#ifdef __cplusplus +extern "C" { +#endif + +/** * @ingroup ant_sdk_bpwr_simulator * @brief BPWR simulator control block structure. */ typedef struct @@ -35,4 +67,9 @@ typedef struct }ant_bpwr_simulator_cb_t; + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_SIMULATOR_LOCAL_H__ diff --git a/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h b/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h index 8fac8c6..bdf91e3 100644 --- a/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h +++ b/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BPWR_UTILS_H__ #define ANT_BPWR_UTILS_H__ @@ -16,11 +44,15 @@ #include "nrf_assert.h" #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @file * * @defgroup ant_sdk_profiles_bpwr_utils Bicycle Power profile utilities * @{ - * @ingroup ant_sdk_profiles_bpwr + * @ingroup ant_bpwr * @brief This module implements utilities for the Bicycle Power profile. * */ @@ -45,5 +77,10 @@ /** @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_BPWR_UTILS_H__ diff --git a/components/ant/ant_profiles/ant_bsc/ant_bsc.c b/components/ant/ant_profiles/ant_bsc/ant_bsc.c index 92959c3..8a8bde2 100644 --- a/components/ant/ant_profiles/ant_bsc/ant_bsc.c +++ b/components/ant/ant_profiles/ant_bsc/ant_bsc.c @@ -1,25 +1,64 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + #include "nrf_assert.h" +#include "nrf_error.h" #include "app_error.h" #include "ant_interface.h" -#include "app_util.h" #include "ant_bsc.h" #include "ant_bsc_utils.h" -#include "ant_bsc_page_logger.h" -#include "app_error.h" + +#define NRF_LOG_MODULE_NAME "ANT_BSC" +#if ANT_BSC_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_INFO_COLOR +#else // ANT_BSC_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_LOG_ENABLED +#include "nrf_log.h" #define MAIN_DATA_INTERVAL 4 /**< The number of background data pages sent between main data pages.*/ -#define BACKGROUND_DATA_INTERVAL 64 /**< The number of main data pages sent between background data page. +#define BACKGROUND_DATA_INTERVAL 64 /**< The number of main data pages sent between background data page. Background data page is sent every 65th message. */ #define TX_TOGGLE_DIVISOR 4 /**< The number of messages between changing state of toggle bit. */ @@ -63,7 +102,7 @@ static ret_code_t ant_bsc_init(ant_bsc_profile_t * p_profile, p_profile->page_5 = DEFAULT_ANT_BSC_PAGE5(); p_profile->page_comb_0 = DEFAULT_ANT_BSC_COMBINED_PAGE0(); - LOG_BSC("ANT BSC channel %u init\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT BSC channel %u init\r\n", p_profile->channel_number); return ant_channel_init(p_channel_config); } @@ -90,10 +129,10 @@ ret_code_t ant_bsc_sens_init(ant_bsc_profile_t * p_profile, ASSERT(p_profile != NULL); ASSERT(p_channel_config != NULL); ASSERT(p_sens_config != NULL); - ASSERT(p_sens_config->p_cb_buffer != NULL); + ASSERT(p_sens_config->p_cb != NULL); ASSERT(p_sens_config->evt_handler != NULL); - ASSERT((p_sens_config->main_page_number == ANT_BSC_PAGE_0) + ASSERT((p_sens_config->main_page_number == ANT_BSC_PAGE_0) || (p_sens_config->main_page_number == ANT_BSC_PAGE_5) || (p_sens_config->main_page_number == ANT_BSC_COMB_PAGE_0)); @@ -103,7 +142,7 @@ ret_code_t ant_bsc_sens_init(ant_bsc_profile_t * p_profile, p_profile->_cb.p_sens_cb->page_1_present = p_sens_config->page_1_present; p_profile->_cb.p_sens_cb->page_4_present = p_sens_config->page_4_present; p_profile->_cb.p_sens_cb->main_page_number = p_sens_config->main_page_number; - p_profile->_cb.p_sens_cb->bkgd_page_number = + p_profile->_cb.p_sens_cb->bkgd_page_number = p_sens_config->page_1_present ? ANT_BSC_PAGE_1 : ANT_BSC_PAGE_2; p_profile->_cb.p_sens_cb->message_counter = 0; p_profile->_cb.p_sens_cb->toggle_bit = true; @@ -120,7 +159,7 @@ ret_code_t ant_bsc_sens_init(ant_bsc_profile_t * p_profile, __STATIC_INLINE void next_bkgd_page_number_set(ant_bsc_profile_t * p_profile) { /* Determine the last background page*/ - ant_bsc_page_t last_bkgd_page = + ant_bsc_page_t last_bkgd_page = p_profile->_cb.p_sens_cb->page_4_present ? ANT_BSC_PAGE_4 : ANT_BSC_PAGE_3; /* Switch the background page according to user settings */ @@ -186,7 +225,7 @@ static void sens_message_encode(ant_bsc_profile_t * p_profile, uint8_t * p_messa if (p_profile->_cb.p_sens_cb->device_type == BSC_COMBINED_DEVICE_TYPE) { - LOG_BSC("%-30s \"Combined Speed & Cadence Page\"\n\r", "BSC TX Page:"); + NRF_LOG_INFO("BSC TX Page: \"Combined Speed & Cadence Page\"\r\n"); ant_bsc_combined_page_0_encode(p_bsc_message_payload->combined.page_payload, &(p_profile->page_comb_0)); bsc_sens_event = (ant_bsc_evt_t) ANT_BSC_COMB_PAGE_0_UPDATED; @@ -195,14 +234,14 @@ static void sens_message_encode(ant_bsc_profile_t * p_profile, uint8_t * p_messa { p_bsc_message_payload->speed_or_cadence.page_number = next_page_number_get(p_profile); p_bsc_message_payload->speed_or_cadence.toggle_bit = p_profile->_cb.p_sens_cb->toggle_bit; - LOG_BSC("%-30s %u\n\r", "BSC TX Page number:", + NRF_LOG_INFO("BSC TX Page number: %u\r\n", p_bsc_message_payload->speed_or_cadence.page_number); ant_bsc_page_0_encode(p_bsc_message_payload->speed_or_cadence.page_payload, &(p_profile->page_0)); bsc_sens_event = (ant_bsc_evt_t) p_bsc_message_payload->speed_or_cadence.page_number; - switch(p_bsc_message_payload->speed_or_cadence.page_number) + switch (p_bsc_message_payload->speed_or_cadence.page_number) { case ANT_BSC_PAGE_0: // No implementation needed @@ -232,7 +271,6 @@ static void sens_message_encode(ant_bsc_profile_t * p_profile, uint8_t * p_messa break; } } - LOG_BSC("\r\n"); p_profile->evt_handler(p_profile, bsc_sens_event); } @@ -274,7 +312,7 @@ ret_code_t ant_bsc_disp_open(ant_bsc_profile_t * p_profile) { ASSERT(p_profile != NULL); - LOG_BSC("ANT BSC channel %u open\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT BSC channel %u open\r\n", p_profile->channel_number); return sd_ant_channel_open(p_profile->channel_number); } @@ -285,7 +323,7 @@ ret_code_t ant_bsc_sens_open(ant_bsc_profile_t * p_profile) // Fill tx buffer for the first frame ant_message_send(p_profile); - LOG_BSC("ANT BSC channel %u open\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT BSC channel %u open\r\n", p_profile->channel_number); return sd_ant_channel_open(p_profile->channel_number); } @@ -298,20 +336,20 @@ ret_code_t ant_bsc_sens_open(ant_bsc_profile_t * p_profile) */ static void disp_message_decode(ant_bsc_profile_t * p_profile, uint8_t * p_message_payload) { - const ant_bsc_message_layout_t * p_bsc_message_payload = + const ant_bsc_message_layout_t * p_bsc_message_payload = (ant_bsc_message_layout_t *)p_message_payload; ant_bsc_evt_t bsc_disp_event; if (p_profile->_cb.p_disp_cb->device_type == BSC_COMBINED_DEVICE_TYPE) { - LOG_BSC("%-30s \"Combined Speed & Cadence Page\"\n\r", "BSC RX Page Number:"); + NRF_LOG_INFO("BSC RX Page Number: \"Combined Speed & Cadence Page\"\r\n"); ant_bsc_combined_page_0_decode(p_bsc_message_payload->combined.page_payload, &(p_profile->page_comb_0)); bsc_disp_event = (ant_bsc_evt_t) ANT_BSC_COMB_PAGE_0_UPDATED; } else { - LOG_BSC("%-30s %u\n\r", "BSC RX Page Number:", + NRF_LOG_INFO("BSC RX Page Number: %u\r\n", p_bsc_message_payload->speed_or_cadence.page_number); ant_bsc_page_0_decode(p_bsc_message_payload->speed_or_cadence.page_payload, &(p_profile->page_0)); // Page 0 is present in each message @@ -353,7 +391,6 @@ static void disp_message_decode(ant_bsc_profile_t * p_profile, uint8_t * p_messa break; } } - LOG_BSC("\r\n"); p_profile->evt_handler(p_profile, bsc_disp_event); } @@ -363,7 +400,7 @@ void ant_bsc_disp_evt_handler(ant_bsc_profile_t * p_profile, { if (p_ant_event->channel == p_profile->channel_number) { - ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->evt_buffer; + ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; switch (p_ant_event->event) { case EVENT_RX: @@ -380,3 +417,5 @@ void ant_bsc_disp_evt_handler(ant_bsc_profile_t * p_profile, } } } + +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/components/ant/ant_profiles/ant_bsc/ant_bsc.h b/components/ant/ant_profiles/ant_bsc/ant_bsc.h index 1251220..aec6226 100644 --- a/components/ant/ant_profiles/ant_bsc/ant_bsc.h +++ b/components/ant/ant_profiles/ant_bsc/ant_bsc.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ant_sdk_profiles_bsc Bicycle Speed and Cadence profile + * @defgroup ant_bsc Bicycle Speed and Cadence profile * @{ * @ingroup ant_sdk_profiles * @brief This module implements the Bicycle Speed and Cadence profile. @@ -193,7 +221,7 @@ typedef enum{ ANT_BSC_COMB_PAGE_0_UPDATED = ANT_BSC_COMB_PAGE_0, ///< Combined Speed and cadence data page has been updated (Display) or sent (Sensor). } ant_bsc_evt_t; -// Forward declaration of the ant_bsc_profile_t type. +// Forward declaration of the ant_bsc_profile_t type. typedef struct ant_bsc_profile_s ant_bsc_profile_t; /**@brief BSC event handler type. */ @@ -201,6 +229,10 @@ typedef void (* ant_bsc_evt_handler_t) (ant_bsc_profile_t *, ant_bsc_evt_t); #include "ant_bsc_local.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief BSC Display configuration structure. */ typedef struct { @@ -320,6 +352,11 @@ void ant_bsc_sens_evt_handler(ant_bsc_profile_t * p_profile, void ant_bsc_disp_evt_handler(ant_bsc_profile_t * p_profile, ant_evt_t * p_ant_event); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h b/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h index 9c93c04..41060be 100644 --- a/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h +++ b/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ @@ -18,8 +46,12 @@ #include #include "ant_bsc.h" +#ifdef __cplusplus +extern "C" { +#endif + /** - * @addtogroup ant_sdk_profiles_bsc + * @addtogroup ant_bsc * @{ */ @@ -45,4 +77,9 @@ typedef struct * @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_LOCAL_H__ diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c index e2e2614..7e430b5 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c @@ -1,18 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + #include "ant_bsc_combined_page_0.h" #include "ant_bsc_utils.h" -#include "ant_bsc_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_COMBINED_PAGE_0" +#if ANT_BSC_COMBINED_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_COMBINED_PAGE_0_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_COMBINED_PAGE_0_INFO_COLOR +#else // ANT_BSC_COMBINED_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_COMBINED_PAGE_0_LOG_ENABLED +#include "nrf_log.h" /**@brief BSC page 0 data layout structure. */ typedef struct @@ -30,24 +69,19 @@ typedef struct /**@brief Function for printing combined speed and cadence page0 data. */ static void comb_page0_data_log(ant_bsc_combined_page0_data_t const * p_page_data) { - LOG_COMB_PAGE0("%-30s %u\n\r", - "Cadence Revolution count:", + NRF_LOG_INFO("Cadence Revolution count: %u\r\n", (unsigned int)p_page_data->cadence_rev_count); - LOG_COMB_PAGE0("%-30s %u.", - "Cadence event time:", - (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->cadence_event_time)); - LOG_COMB_PAGE0("%03us\n\r", + NRF_LOG_INFO("Cadence event time: %u.%03us\r\n", + (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->cadence_event_time), (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->cadence_event_time)); - LOG_COMB_PAGE0("%-30s %u\n\r", - "Speed Revolution count:", + NRF_LOG_INFO("Speed Revolution count: %u\r\n", (unsigned int)p_page_data->speed_rev_count); - LOG_COMB_PAGE0("%-30s %u.", - "Speed event time:", - (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->speed_event_time)); - LOG_COMB_PAGE0("%03us\n\r", (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->speed_event_time)); + NRF_LOG_INFO("Speed event time: %u.%03us\r\n\n", + (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->speed_event_time), + (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->speed_event_time)); } void ant_bsc_combined_page_0_encode(uint8_t * p_page_buffer, ant_bsc_combined_page0_data_t const * p_page_data) @@ -75,11 +109,11 @@ void ant_bsc_combined_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_combi { ant_bsc_combined_page0_data_layout_t const * p_incoming_data = (ant_bsc_combined_page0_data_layout_t *)p_page_buffer; - uint16_t cadence_event_time = (uint16_t)((p_incoming_data->cadence_evt_time_MSB << 8) + uint16_t cadence_event_time = (uint16_t)((p_incoming_data->cadence_evt_time_MSB << 8) + p_incoming_data->cadence_evt_time_LSB); uint16_t cadence_revolution_count = (uint16_t) ((p_incoming_data->cadence_rev_count_MSB << 8) + p_incoming_data->cadence_rev_count_LSB); - uint16_t speed_event_time = (uint16_t)((p_incoming_data->speed_evt_time_MSB << 8) + uint16_t speed_event_time = (uint16_t)((p_incoming_data->speed_evt_time_MSB << 8) + p_incoming_data->speed_evt_time_LSB); uint16_t speed_revolution_count = (uint16_t) ((p_incoming_data->speed_rev_count_MSB << 8) + p_incoming_data->speed_rev_count_LSB); @@ -92,3 +126,4 @@ void ant_bsc_combined_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_combi comb_page0_data_log(p_page_data); } +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h index cabc52c..b6e6834 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BSC_COMBINED_PAGE_0_H__ #define ANT_BSC_COMBINED_PAGE_0_H__ @@ -21,9 +49,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for Bicycle Combined Speed and Cadence data page 0. * - * This structure is used as a common page. + * This structure is used as a common page. */ typedef struct { @@ -58,5 +90,10 @@ void ant_bsc_combined_page_0_encode(uint8_t * p_page_buffer, ant_bsc_combined_pa */ void ant_bsc_combined_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_combined_page0_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_COMBINED_PAGE_0_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c index 396dafd..aa6ead8 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c @@ -1,17 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + #include "ant_bsc_page_0.h" #include "ant_bsc_utils.h" -#include "ant_bsc_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_0" +#if ANT_BSC_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_0_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_0_INFO_COLOR +#else // ANT_BSC_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_0_LOG_ENABLED +#include "nrf_log.h" /**@brief BSC page 0 data layout structure. */ typedef struct @@ -26,13 +66,13 @@ typedef struct /**@brief Function for printing speed or cadence page0 data. */ static void page0_data_log(ant_bsc_page0_data_t const * p_page_data) { - LOG_PAGE0("%-30s %u\n\r", "Revolution count:", (unsigned int)p_page_data->rev_count); + NRF_LOG_INFO("Revolution count: %u\r\n", (unsigned int)p_page_data->rev_count); - LOG_PAGE0("%-30s %u.", - "BSC event time:", - (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->event_time)); + NRF_LOG_INFO("BSC event time: %u.%03us\r\n", + (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->event_time), + (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->event_time)); - LOG_PAGE0("%03us\n\r", (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->event_time)); +// NRF_LOG_INFO("%03us\r\n", (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->event_time)); } void ant_bsc_page_0_encode(uint8_t * p_page_buffer, ant_bsc_page0_data_t const * p_page_data) @@ -56,7 +96,7 @@ void ant_bsc_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_page0_data_t * { ant_bsc_page0_data_layout_t const * p_incoming_data = (ant_bsc_page0_data_layout_t *)p_page_buffer; - uint16_t event_time = (uint16_t)((p_incoming_data->bsc_evt_time_MSB << 8) + uint16_t event_time = (uint16_t)((p_incoming_data->bsc_evt_time_MSB << 8) + p_incoming_data->bsc_evt_time_LSB); uint16_t revolution_count = (uint16_t) ((p_incoming_data->bsc_rev_count_MSB << 8) @@ -68,3 +108,4 @@ void ant_bsc_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_page0_data_t * page0_data_log(p_page_data); } +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h index 4e9f8c1..d3362c1 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BSC_PAGE_0_H__ #define ANT_BSC_PAGE_0_H__ @@ -21,9 +49,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for BSC data page 0. * - * This structure is used as a common page. + * This structure is used as a common page. */ typedef struct { @@ -54,5 +86,10 @@ void ant_bsc_page_0_encode(uint8_t * p_page_buffer, ant_bsc_page0_data_t const * */ void ant_bsc_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_page0_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_PAGE_0_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c index a1d1d50..f878dd8 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c @@ -1,20 +1,60 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + #include "ant_bsc_page_1.h" #include "ant_bsc_utils.h" -#include "ant_bsc_page_logger.h" #include "app_util.h" #include "nordic_common.h" +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_1" +#if ANT_BSC_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_1_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_1_INFO_COLOR +#else // ANT_BSC_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_1_LOG_ENABLED +#include "nrf_log.h" + /**@brief BSC page 1 data layout structure. */ typedef struct { @@ -25,12 +65,11 @@ typedef struct /**@brief Function for printing speed or cadence page1 data. */ static void page1_data_log(ant_bsc_page1_data_t const * p_page_data) { - LOG_PAGE1("%-30s %ud ", - "Cumulative operating time:", - (unsigned int)ANT_BSC_OPERATING_DAYS(p_page_data->operating_time)); - LOG_PAGE1("%uh ", (unsigned int)ANT_BSC_OPERATING_HOURS(p_page_data->operating_time)); - LOG_PAGE1("%um ", (unsigned int)ANT_BSC_OPERATING_MINUTES(p_page_data->operating_time)); - LOG_PAGE1("%us\n\r", (unsigned int)ANT_BSC_OPERATING_SECONDS(p_page_data->operating_time)); + NRF_LOG_INFO("Cumulative operating time: %ud %uh %um %us\r\n", + (unsigned int)ANT_BSC_OPERATING_DAYS(p_page_data->operating_time), + (unsigned int)ANT_BSC_OPERATING_HOURS(p_page_data->operating_time), + (unsigned int)ANT_BSC_OPERATING_MINUTES(p_page_data->operating_time), + (unsigned int)ANT_BSC_OPERATING_SECONDS(p_page_data->operating_time)); } void ant_bsc_page_1_encode(uint8_t * p_page_buffer, ant_bsc_page1_data_t const * p_page_data) @@ -51,5 +90,5 @@ void ant_bsc_page_1_decode(uint8_t const * p_page_buffer, ant_bsc_page1_data_t * page1_data_log( p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h index fa8a221..4cb6bc4 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BSC_PAGE_1_H__ #define ANT_BSC_PAGE_1_H__ @@ -21,9 +49,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for BSC data page 1. * - * This structure implements only page 1 specific data. + * This structure implements only page 1 specific data. */ typedef struct { @@ -52,5 +84,10 @@ void ant_bsc_page_1_encode(uint8_t * p_page_buffer, ant_bsc_page1_data_t const * */ void ant_bsc_page_1_decode(uint8_t const * p_page_buffer, ant_bsc_page1_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_PAGE_1_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c index e57e1cc..c305d28 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c @@ -1,16 +1,56 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + #include "ant_bsc_page_2.h" -#include "ant_bsc_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_2" +#if ANT_BSC_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_2_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_2_INFO_COLOR +#else // ANT_BSC_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_2_LOG_ENABLED +#include "nrf_log.h" /**@brief BSC page 2 data layout structure. */ typedef struct @@ -24,9 +64,8 @@ typedef struct /**@brief Function for printing speed or cadence page2 data. */ static void page2_data_log(ant_bsc_page2_data_t const * p_page_data) { - LOG_PAGE2("%-30s %u\n\r", "Manufacturer ID:", (unsigned int)p_page_data->manuf_id); - LOG_PAGE2("%-30s 0x%X\n\r", - "Serial No (upper 16-bits):", + NRF_LOG_INFO("Manufacturer ID: %u\r\n", (unsigned int)p_page_data->manuf_id); + NRF_LOG_INFO("Serial No (upper 16-bits): 0x%X\r\n", (unsigned int)p_page_data->serial_num); } @@ -38,14 +77,14 @@ void ant_bsc_page_2_encode(uint8_t * p_page_buffer, ant_bsc_page2_data_t const * p_outcoming_data->manuf_id = (uint8_t)p_page_data->manuf_id; p_outcoming_data->serial_num_LSB = (uint8_t)(serial_num & UINT8_MAX); p_outcoming_data->serial_num_MSB = (uint8_t)((serial_num >> 8) & UINT8_MAX); - + page2_data_log( p_page_data); } void ant_bsc_page_2_decode(uint8_t const * p_page_buffer, ant_bsc_page2_data_t * p_page_data) { ant_bsc_page2_data_layout_t const * p_incoming_data = (ant_bsc_page2_data_layout_t *)p_page_buffer; - uint32_t serial_num = (uint32_t)((p_incoming_data->serial_num_MSB << 8) + uint32_t serial_num = (uint32_t)((p_incoming_data->serial_num_MSB << 8) + p_incoming_data->serial_num_LSB); p_page_data->manuf_id = (uint32_t)p_incoming_data->manuf_id; @@ -54,3 +93,4 @@ void ant_bsc_page_2_decode(uint8_t const * p_page_buffer, ant_bsc_page2_data_t * page2_data_log( p_page_data); } +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h index 668403f..c116ca9 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BSC_PAGE_2_H__ #define ANT_BSC_PAGE_2_H__ @@ -21,9 +49,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for BSC data page 2. * - * This structure implements only page 2 specific data. + * This structure implements only page 2 specific data. */ typedef struct { @@ -54,5 +86,10 @@ void ant_bsc_page_2_encode(uint8_t * p_page_buffer, ant_bsc_page2_data_t const * */ void ant_bsc_page_2_decode(uint8_t const * p_page_buffer, ant_bsc_page2_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_PAGE_2_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c index 6377f23..c0c04ba 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c @@ -1,16 +1,56 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + #include "ant_bsc_page_3.h" -#include "ant_bsc_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_3" +#if ANT_BSC_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_3_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_3_INFO_COLOR +#else // ANT_BSC_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_3_LOG_ENABLED +#include "nrf_log.h" /**@brief BSC page 3 data layout structure. */ typedef struct @@ -24,9 +64,9 @@ typedef struct /**@brief Function for printing speed or cadence page3 data. */ static void page3_data_log(ant_bsc_page3_data_t const * p_page_data) { - LOG_PAGE3("%-30s %u\n\r", "Hardware Rev ID:", (unsigned int)p_page_data->hw_version); - LOG_PAGE3("%-30s %u\n\r", "Model:", (unsigned int)p_page_data->model_num); - LOG_PAGE3("%-30s %u\n\r", "Software Ver ID:", (unsigned int)p_page_data->sw_version); + NRF_LOG_INFO("Hardware Rev ID: %u\r\n", (unsigned int)p_page_data->hw_version); + NRF_LOG_INFO("Model Number: %u\r\n", (unsigned int)p_page_data->model_num); + NRF_LOG_INFO("Software Ver ID: %u\r\n", (unsigned int)p_page_data->sw_version); } void ant_bsc_page_3_encode(uint8_t * p_page_buffer, ant_bsc_page3_data_t const * p_page_data) @@ -36,7 +76,7 @@ void ant_bsc_page_3_encode(uint8_t * p_page_buffer, ant_bsc_page3_data_t const * p_outcoming_data->hw_version = (uint8_t)p_page_data->hw_version; p_outcoming_data->sw_version = (uint8_t)p_page_data->sw_version; p_outcoming_data->model_num = (uint8_t)p_page_data->model_num; - + page3_data_log( p_page_data); } @@ -51,3 +91,4 @@ void ant_bsc_page_3_decode(uint8_t const * p_page_buffer, ant_bsc_page3_data_t * page3_data_log( p_page_data); } +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h index f4e2e40..a16e2bf 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BSC_PAGE_3_H__ #define ANT_BSC_PAGE_3_H__ @@ -21,9 +49,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for BSC data page 3. * - * This structure implements only page 3 specific data. + * This structure implements only page 3 specific data. */ typedef struct { @@ -56,5 +88,10 @@ void ant_bsc_page_3_encode(uint8_t * p_page_buffer, ant_bsc_page3_data_t const * */ void ant_bsc_page_3_decode(uint8_t const * p_page_buffer, ant_bsc_page3_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_PAGE_3_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c index b4d9051..9e8b110 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c @@ -1,19 +1,59 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + #include "ant_bsc_page_4.h" #include "ant_bsc_utils.h" -#include "ant_bsc_page_logger.h" #include "app_util.h" +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_4" +#if ANT_BSC_PAGE_4_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_4_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_4_INFO_COLOR +#else // ANT_BSC_PAGE_4_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_4_LOG_ENABLED +#include "nrf_log.h" + /**@brief BSC page 4 data layout structure. */ typedef struct { @@ -31,11 +71,10 @@ STATIC_ASSERT(ANT_BSC_BAT_VOLTAGE_PRECISION == 1000); /**@brief Function for printing speed or cadence page4 data. */ static void page4_data_log( ant_bsc_page4_data_t const * p_page_data) { - LOG_PAGE4("%-30s %u.%03uV\r\n", - "Battery voltage:", + NRF_LOG_INFO("Battery voltage: %u.%03uV\r\n", (unsigned int)p_page_data->coarse_bat_volt, (unsigned int)ANT_BSC_BAT_VOLTAGE_FRACTION_MV(p_page_data->fract_bat_volt)); - LOG_PAGE4("%-30s %u\n\r", "Battery status:", (unsigned int)p_page_data->bat_status); + NRF_LOG_INFO("Battery status: %u\r\n", (unsigned int)p_page_data->bat_status); } void ant_bsc_page_4_encode(uint8_t * p_page_buffer, ant_bsc_page4_data_t const * p_page_data) @@ -47,7 +86,7 @@ void ant_bsc_page_4_encode(uint8_t * p_page_buffer, ant_bsc_page4_data_t const * p_outcoming_data->coarse_bat_volt = p_page_data->coarse_bat_volt; p_outcoming_data->bat_status = p_page_data->bat_status; p_outcoming_data->bitfield_reserved = 0; - + page4_data_log( p_page_data); } @@ -62,3 +101,4 @@ void ant_bsc_page_4_decode(uint8_t const * p_page_buffer, ant_bsc_page4_data_t * page4_data_log( p_page_data); } +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h index e72b293..7af4919 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BSC_PAGE_4_H__ #define ANT_BSC_PAGE_4_H__ @@ -21,9 +49,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief BSC profile battery status. * - * This enum represents possible battery status values for the ANT BSC profile. + * This enum represents possible battery status values for the ANT BSC profile. */ typedef enum { @@ -39,7 +71,7 @@ typedef enum /**@brief Data structure for BSC data page 4. * - * This structure implements only page 4 specific data. + * This structure implements only page 4 specific data. */ typedef struct { @@ -72,5 +104,10 @@ void ant_bsc_page_4_encode(uint8_t * p_page_buffer, ant_bsc_page4_data_t const * */ void ant_bsc_page_4_decode(uint8_t const * p_page_buffer, ant_bsc_page4_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_PAGE_4_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c index 9a5bd94..07c5c91 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c @@ -1,17 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_BSC) + #include "ant_bsc_page_5.h" #include "ant_bsc_utils.h" -#include "ant_bsc_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_BCS_PAGE_5" +#if ANT_BSC_PAGE_5_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_BSC_PAGE_5_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_5_INFO_COLOR +#else // ANT_BSC_PAGE_5_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_BSC_PAGE_5_LOG_ENABLED +#include "nrf_log.h" /**@brief BSC profile page 5 bitfields definitions. */ #define ANT_BSC_STOP_IND_MASK 0x01 @@ -28,11 +68,11 @@ static void page5_data_log(ant_bsc_page5_data_t const * p_page_data) { if (p_page_data->stop_indicator) { - LOG_PAGE5("Bicycle stopped.\r\n"); + NRF_LOG_INFO("Bicycle stopped.\r\n"); } else { - LOG_PAGE5("Bicycle moving.\r\n"); + NRF_LOG_INFO("Bicycle moving.\r\n"); } } @@ -41,7 +81,7 @@ void ant_bsc_page_5_encode(uint8_t * p_page_buffer, ant_bsc_page5_data_t const * ant_bsc_page5_data_layout_t * p_outcoming_data = (ant_bsc_page5_data_layout_t *)p_page_buffer; p_outcoming_data->flags = (uint8_t)p_page_data->stop_indicator; - + page5_data_log( p_page_data); } @@ -54,3 +94,4 @@ void ant_bsc_page_5_decode(uint8_t const * p_page_buffer, ant_bsc_page5_data_t * page5_data_log( p_page_data); } +#endif // NRF_MODULE_ENABLED(ANT_BSC) diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h index e7d925a..22b250d 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BSC_PAGE_5_H__ #define ANT_BSC_PAGE_5_H__ @@ -21,9 +49,13 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for BSC data page 5. * - * This structure implements only page 5 specific data. + * This structure implements only page 5 specific data. */ typedef struct { @@ -54,5 +86,10 @@ void ant_bsc_page_5_encode(uint8_t * p_page_buffer, ant_bsc_page5_data_t const * */ void ant_bsc_page_5_decode(uint8_t const * p_page_buffer, ant_bsc_page5_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_PAGE_5_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h index 2b8990a..392678c 100644 --- a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h +++ b/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 __ANT_BSC_PAGES_H #define __ANT_BSC_PAGES_H @@ -16,7 +44,7 @@ * * @defgroup ant_sdk_profiles_bsc_pages Bicycle Speed and Cadence profile pages * @{ - * @ingroup ant_sdk_profiles_bsc + * @ingroup ant_bsc * @brief This module implements functions for the BSC data pages. */ @@ -28,5 +56,14 @@ #include "ant_bsc_page_5.h" #include "ant_bsc_combined_page_0.h" +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + #endif // __ANT_BSC_PAGES_H /** @} */ diff --git a/components/ant/ant_profiles/ant_bsc/pages/logger/ant_bsc_page_logger.h b/components/ant/ant_profiles/ant_bsc/pages/logger/ant_bsc_page_logger.h deleted file mode 100644 index 6b46312..0000000 --- a/components/ant/ant_profiles/ant_bsc/pages/logger/ant_bsc_page_logger.h +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 ANT_BSC_PAGE_LOGGER_H__ -#define ANT_BSC_PAGE_LOGGER_H__ - -#ifdef TRACE_BSC_GENERAL_ENABLE -#include "app_trace.h" -#define LOG_BSC app_trace_log -#else -#define LOG_BSC(...) -#endif // TRACE_BSC_GENERAL_ENABLE - -#ifdef TRACE_BSC_PAGE_0_ENABLE -#include "app_trace.h" -#define LOG_PAGE0 app_trace_log -#else -#define LOG_PAGE0(...) -#endif // TRACE_BSC_PAGE_0_ENABLE - -#ifdef TRACE_BSC_PAGE_1_ENABLE -#include "app_trace.h" -#define LOG_PAGE1 app_trace_log -#else -#define LOG_PAGE1(...) -#endif // TRACE_BSC_PAGE_1_ENABLE - -#ifdef TRACE_BSC_PAGE_2_ENABLE -#include "app_trace.h" -#define LOG_PAGE2 app_trace_log -#else -#define LOG_PAGE2(...) -#endif // TRACE_BSC_PAGE_2_ENABLE - -#ifdef TRACE_BSC_PAGE_3_ENABLE -#include "app_trace.h" -#define LOG_PAGE3 app_trace_log -#else -#define LOG_PAGE3(...) -#endif // TRACE_BSC_PAGE_3_ENABLE - -#ifdef TRACE_BSC_PAGE_4_ENABLE -#include "app_trace.h" -#define LOG_PAGE4 app_trace_log -#else -#define LOG_PAGE4(...) -#endif // TRACE_BSC_PAGE_4_ENABLE - -#ifdef TRACE_BSC_PAGE_5_ENABLE -#include "app_trace.h" -#define LOG_PAGE5 app_trace_log -#else -#define LOG_PAGE5(...) -#endif // TRACE_BSC_PAGE_5_ENABLE - -#ifdef TRACE_BSC_COMB_PAGE_0_ENABLE -#include "app_trace.h" -#define LOG_COMB_PAGE0 app_trace_log -#else -#define LOG_COMB_PAGE0(...) -#endif // TRACE_BSC_COMB_PAGE_0_ENABLE - -#endif // ANT_BSC_UTILS_H__ diff --git a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c b/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c index c1eb77f..0ea8062 100644 --- a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c +++ b/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ant_bsc_simulator.h" @@ -31,7 +59,7 @@ #define WHEEL_CIRCUMFERENCE 1766u ///< bike wheel circumference [mm] #define MM_TO_METERS(MM_VAL) ((MM_VAL) / 1000u) #define TWO_SEC_TO_TICKS 2048 ///< number of [1/1024s] ticks in 2 sec period -#define CUMULATIVE_TIME_UNIT 2 ///< cumulative time unit +#define CUMULATIVE_TIME_UNIT 2 ///< cumulative time unit void ant_bsc_simulator_init(ant_bsc_simulator_t * p_simulator, ant_bsc_simulator_cfg_t const * p_config, @@ -51,21 +79,21 @@ void ant_bsc_simulator_init(ant_bsc_simulator_t * p_simulator, p_simulator->_cb.sensorsim_s_cfg.max = SPEED_SIM_MAX_VAL; p_simulator->_cb.sensorsim_s_cfg.incr = SPEED_SIM_INCREMENT; p_simulator->_cb.sensorsim_s_cfg.start_at_max = false; - sensorsim_init(&(p_simulator->_cb.sensorsim_s_state), + sensorsim_init(&(p_simulator->_cb.sensorsim_s_state), &(p_simulator->_cb.sensorsim_s_cfg)); p_simulator->_cb.sensorsim_c_cfg.min = CADENCE_SIM_MIN_VAL; p_simulator->_cb.sensorsim_c_cfg.max = CADENCE_SIM_MAX_VAL; p_simulator->_cb.sensorsim_c_cfg.incr = CADENCE_SIM_INCREMENT; p_simulator->_cb.sensorsim_c_cfg.start_at_max = false; p_simulator->_cb.stop_cnt = 0; - sensorsim_init(&(p_simulator->_cb.sensorsim_c_state), + sensorsim_init(&(p_simulator->_cb.sensorsim_c_state), &(p_simulator->_cb.sensorsim_c_cfg)); } void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator) { - + // Set constant battery voltage p_simulator->p_profile->BSC_PROFILE_coarse_bat_volt = 2; p_simulator->p_profile->BSC_PROFILE_fract_bat_volt = 200; @@ -74,9 +102,9 @@ void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator) // Calculate speed and cadence values if (p_simulator->_cb.auto_change) { - p_simulator->_cb.speed_sim_val = sensorsim_measure(&(p_simulator->_cb.sensorsim_s_state), + p_simulator->_cb.speed_sim_val = sensorsim_measure(&(p_simulator->_cb.sensorsim_s_state), &(p_simulator->_cb.sensorsim_s_cfg)); - p_simulator->_cb.cadence_sim_val = sensorsim_measure(&(p_simulator->_cb.sensorsim_c_state), + p_simulator->_cb.cadence_sim_val = sensorsim_measure(&(p_simulator->_cb.sensorsim_c_state), &(p_simulator->_cb.sensorsim_c_cfg)); } else @@ -98,7 +126,7 @@ void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator) { if (p_simulator->_cb.stop_cnt == 60) { - p_simulator->_cb.stop_cnt = 0; + p_simulator->_cb.stop_cnt = 0; } } } @@ -111,16 +139,16 @@ void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator) p_simulator->p_profile->BSC_PROFILE_stop_indicator = 0; } - // @note: Take a local copy within scope in order to assist the compiler in variable register - // allocation. + // @note: Take a local copy within scope in order to assist the compiler in variable register + // allocation. const uint32_t computed_speed = p_simulator->_cb.speed_sim_val; const uint32_t computed_cadence = p_simulator->_cb.cadence_sim_val; // @note: This implementation assumes that the current instantaneous speed/cadence can vary and this // function is called with static frequency. - // value and the speed/cadence pulse interval is derived from it. The computation is based on 60 + // value and the speed/cadence pulse interval is derived from it. The computation is based on 60 // seconds in a minute and the used time base is 1/1024 seconds. - const uint32_t current_speed_pulse_interval = + const uint32_t current_speed_pulse_interval = MM_TO_METERS((WHEEL_CIRCUMFERENCE * 1024u) / computed_speed); const uint32_t current_cadence_pulse_interval = (60u * 1024u) / computed_cadence; @@ -133,14 +161,14 @@ void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator) p_simulator->_cb.fraction_since_last_c_evt += ITERATION_FRACTION(p_simulator->_cb.device_type); uint32_t add_period = p_simulator->_cb.fraction_since_last_s_evt / ANT_CLOCK_FREQUENCY; - if(add_period > 0) + if (add_period > 0) { p_simulator->_cb.time_since_last_s_evt++; p_simulator->_cb.fraction_since_last_s_evt %= ANT_CLOCK_FREQUENCY; } add_period = p_simulator->_cb.fraction_since_last_c_evt / ANT_CLOCK_FREQUENCY; - if(add_period > 0) + if (add_period > 0) { p_simulator->_cb.time_since_last_c_evt++; p_simulator->_cb.fraction_since_last_c_evt %= ANT_CLOCK_FREQUENCY; @@ -151,7 +179,7 @@ void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator) p_simulator->_cb.prev_time_since_evt; p_simulator->_cb.prev_time_since_evt = p_simulator->p_profile->BSC_PROFILE_event_time; - if(diff >= 0) // Check for time count overflow + if (diff >= 0) // Check for time count overflow { // No overflow p_simulator->_cb.cumulative_time += diff / TWO_SEC_TO_TICKS; @@ -184,8 +212,8 @@ void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator) p_simulator->p_profile->BSC_PROFILE_rev_count += new_s_events; p_simulator->p_profile->BSC_PROFILE_speed_rev_count += new_s_events; - // Current speed event time is the previous event time plus the current speed - // pulse interval. + // Current speed event time is the previous event time plus the current speed + // pulse interval. uint32_t current_speed_event_time = p_simulator->p_profile->BSC_PROFILE_event_time + add_speed_event_time; // Set current event time. @@ -208,8 +236,8 @@ void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator) p_simulator->p_profile->BSC_PROFILE_rev_count += new_c_events; p_simulator->p_profile->BSC_PROFILE_cadence_rev_count += new_c_events; - // Current speed event time is the previous event time plus the current speed - // pulse interval. + // Current speed event time is the previous event time plus the current speed + // pulse interval. uint32_t current_cadence_event_time = p_simulator->p_profile->BSC_PROFILE_event_time + add_cadence_event_time; // Set current event time. diff --git a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h b/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h index 95167df..249f7d6 100644 --- a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h +++ b/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BSC_SIMULATOR_H__ @@ -21,7 +49,7 @@ * @brief ANT BSC simulator module. * * @details This module simulates a pulse for the ANT Bicycle Speed and Cadence profile. The module - * calculates abstract values, which are handled by the BSC pages data model to ensure that + * calculates abstract values, which are handled by the BSC pages data model to ensure that * they are compatible. It provides a handler for changing the cadence and speed values manually * as well as functionality to change the values automatically. * @@ -29,12 +57,15 @@ #include #include -#include "bsp.h" #include "ant_bsc.h" #include "ant_bsc_utils.h" #include "sensorsim.h" #include "ant_bsc_simulator_local.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief BSC simulator configuration structure. */ typedef struct { @@ -61,11 +92,11 @@ void ant_bsc_simulator_init(ant_bsc_simulator_t * p_simulator, ant_bsc_simulator_cfg_t const * p_config, bool auto_change); -/**@brief Function for simulating a device event. - * +/**@brief Function for simulating a device event. + * * @details Based on this event, the transmitter data is simulated. * - * This function should be called in the BSC Sensor event handler. + * This function should be called in the BSC Sensor event handler. */ void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator); @@ -81,5 +112,10 @@ void ant_bsc_simulator_increment(ant_bsc_simulator_t * p_simulator); */ void ant_bsc_simulator_decrement(ant_bsc_simulator_t * p_simulator); + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_SIMULATOR_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h b/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h index e57277a..c405033 100644 --- a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h +++ b/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BSC_SIMULATOR_LOCAL_H__ @@ -15,10 +43,13 @@ #include #include -#include "bsp.h" #include "ant_bsc.h" #include "sensorsim.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief BSC simulator control block structure. */ typedef struct @@ -41,4 +72,9 @@ typedef struct uint8_t stop_cnt; ///< Counter used for simulating bicycle stopped state. } ant_bsc_simulator_cb_t; + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_SIMULATOR_LOCAL_H__ diff --git a/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h b/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h index 3d54697..964f53d 100644 --- a/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h +++ b/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h @@ -1,24 +1,56 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_BSC_UTILS_H__ #define ANT_BSC_UTILS_H__ #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @file * * @defgroup ant_sdk_profiles_bsc_utils Bicycle Speed and Cadence profile utilities * @{ - * @ingroup ant_sdk_profiles_bsc + * @ingroup ant_bsc * @brief This module implements utilities for the Bicycle Speed and Cadence profile. * */ @@ -87,5 +119,10 @@ /** @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_BSC_UTILS_H__ diff --git a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c b/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c index da9a0ed..f6aaa2c 100644 --- a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c +++ b/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c @@ -1,15 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_REQUEST_CONTROLLER) #include "ant_request_controller.h" #include "ant_interface.h" #include "ant_parameters.h" @@ -157,7 +187,7 @@ void ant_request_controller_sens_evt_handler(ant_request_controller_t * p_contro ASSERT(p_controller != NULL); ASSERT(p_ant_event != NULL); - ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->evt_buffer; + ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; ant_common_message_layout_t * p_message_payload = (ant_common_message_layout_t *)p_message->ANT_MESSAGE_aucPayload; @@ -171,13 +201,15 @@ void ant_request_controller_sens_evt_handler(ant_request_controller_t * p_contro } break; - case EVENT_TX: case EVENT_TRANSFER_TX_COMPLETED: if (p_controller->state == ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED) { p_controller->state = ANT_REQUEST_CONTROLLER_IDLE; } + /* fall through */ + + case EVENT_TX: if (p_controller->state == ANT_REQUEST_CONTROLLER_BROADCAST_REQUESTED || p_controller->state == ANT_REQUEST_CONTROLLER_ACK_REQUESTED) @@ -191,4 +223,4 @@ void ant_request_controller_sens_evt_handler(ant_request_controller_t * p_contro } } - +#endif // NRF_MODULE_ENABLED(ANT_REQUEST_CONTROLLER) diff --git a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h b/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h index 59b6e9a..1ad712a 100644 --- a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h +++ b/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -25,6 +53,10 @@ #include "ant_common_page_70.h" #include "ant_stack_handler_types.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Request controller events types. */ typedef enum { @@ -117,5 +149,10 @@ void ant_request_controller_sens_evt_handler(ant_request_controller_t * p_contro ant_evt_t * p_ant_event); + +#ifdef __cplusplus +} +#endif + #endif // ANT_REQUEST_CONTROLLER_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c b/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c index 7e5f60f..0ea6f7f 100644 --- a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c +++ b/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c @@ -1,20 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_COMMON_PAGE_70) + #include #include "ant_common_page_70.h" -#include "ant_common_page_logger.h" -#include "nordic_common.h" -#include "app_util.h" + +#define NRF_LOG_MODULE_NAME "ANT_COMMON_PAGE_70" +#if ANT_COMMON_PAGE_70_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_COMMON_PAGE_70_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_COMMON_PAGE_70_INFO_COLOR +#else // ANT_COMMON_PAGE_70_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_COMMON_PAGE_70_LOG_ENABLED +#include "nrf_log.h" /**@brief ANT+ common page 70 data layout structure. */ typedef struct @@ -32,42 +69,42 @@ typedef struct */ static void page70_data_log(volatile ant_common_page70_data_t const * p_page_data) { - LOG_PAGE70("Page %d request\n\r", p_page_data->page_number); + NRF_LOG_INFO("Page %d request\r\n", p_page_data->page_number); switch (p_page_data->transmission_response.specyfic) { case ANT_PAGE70_RESPONSE_TRANSMIT_UNTIL_SUCCESS: - LOG_PAGE70("Try to send until ACK\n\r"); + NRF_LOG_INFO("Try to send until ACK\r\n"); break; case ANT_PAGE70_RESPONSE_INVALID: - LOG_PAGE70("Invalid requested transmission response\n\r"); + NRF_LOG_INFO("Invalid requested transmission response\r\n"); break; default: if (p_page_data->transmission_response.items.ack_resposne) { - LOG_PAGE70("Answer with acknowledged messages\n\r"); + NRF_LOG_INFO("Answer with acknowledged messages\r\n"); } - LOG_PAGE70("Requested number of transmissions: %d\n\r", + NRF_LOG_INFO("Requested number of transmissions: %d\r\n", p_page_data->transmission_response.items.transmit_count); } switch (p_page_data->command_type) { case ANT_PAGE70_COMMAND_PAGE_DATA_REQUEST: - LOG_PAGE70("Request Data Page\n\r"); + NRF_LOG_INFO("Request Data Page\r\n"); break; case ANT_PAGE70_COMMAND_ANT_FS_SESSION_REQUEST: - LOG_PAGE70("Request ANT-FS Session\n\r"); + NRF_LOG_INFO("Request ANT-FS Session\r\n"); break; default: - LOG_PAGE70("Invalid request\n\r"); + NRF_LOG_INFO("Invalid request\r\n"); } - LOG_PAGE70("Descriptor %x\n\r", p_page_data->descriptor); + NRF_LOG_INFO("Descriptor %x\r\n\n", p_page_data->descriptor); } @@ -101,4 +138,4 @@ void ant_common_page_70_decode(uint8_t const * p_page_buffer page70_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_COMMON_PAGE_70) diff --git a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h b/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h index 385a344..db1325c 100644 --- a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h +++ b/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_COMMON_PAGE_70_H__ @@ -15,13 +43,17 @@ /** @file * - * @defgroup ant_sdk_common_page70 ANT+ common page 70 + * @defgroup ant_common_page_70 ANT+ common page 70 * @{ * @ingroup ant_sdk_common_pages */ #include +#ifdef __cplusplus +extern "C" { +#endif + #define ANT_COMMON_PAGE_70 (70) ///< @brief ID value of common page 70. #define ANT_PAGE70_INVALID_DESCRIPTOR UINT16_MAX ///< Invalid descriptor. @@ -95,5 +127,10 @@ void ant_common_page_70_encode(uint8_t * p_page_ void ant_common_page_70_decode(uint8_t const * p_page_buffer, volatile ant_common_page70_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_COMMON_PAGE_70_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c b/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c index 44822f4..9f7cc88 100644 --- a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c +++ b/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c @@ -1,20 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_COMMON_PAGE_80) + #include #include "ant_common_page_80.h" -#include "ant_common_page_logger.h" -#include "app_util.h" -#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "ANT_COMMON_PAGE_80" +#if ANT_COMMON_PAGE_80_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_COMMON_PAGE_80_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_COMMON_PAGE_80_INFO_COLOR +#else // ANT_COMMON_PAGE_80_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_COMMON_PAGE_80_LOG_ENABLED +#include "nrf_log.h" /**@brief ant+ common page 80 data layout structure. */ typedef struct @@ -32,9 +69,9 @@ typedef struct */ static void page80_data_log(volatile ant_common_page80_data_t const * p_page_data) { - LOG_PAGE80("hw revision: %u\n\r", p_page_data->hw_revision); - LOG_PAGE80("manufacturer id: %u\n\r", p_page_data->manufacturer_id); - LOG_PAGE80("model number: %u\n\r", p_page_data->model_number); + NRF_LOG_INFO("hw revision: %u\r\n", p_page_data->hw_revision); + NRF_LOG_INFO("manufacturer id: %u\r\n", p_page_data->manufacturer_id); + NRF_LOG_INFO("model number: %u\r\n\n", p_page_data->model_number); } @@ -70,4 +107,4 @@ void ant_common_page_80_decode(uint8_t const * p_page_buffer page80_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_COMMON_PAGE_80) diff --git a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h b/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h index 123bf72..ce0318e 100644 --- a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h +++ b/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_COMMON_PAGE_80_H__ @@ -18,24 +46,28 @@ * @defgroup ant_sdk_common_pages ANT+ common pages * @{ * @ingroup ant_sdk_profiles - * @brief This module implements functions for the ANT+ common pages. + * @brief This module implements functions for the ANT+ common pages. * @details ANT+ common data pages define common data formats that can be used by any device on any ANT network. The ability to send and receive these common pages is defined by the transmission type of the ANT channel parameter. * * Note that all unused pages in this section are not defined and therefore cannot be used. * @} * - * @defgroup ant_sdk_common_page80 ANT+ common page 80 + * @defgroup ant_common_page_80 ANT+ common page 80 * @{ * @ingroup ant_sdk_common_pages */ #include +#ifdef __cplusplus +extern "C" { +#endif + #define ANT_COMMON_PAGE_80 (80) ///< @brief ID value of common page 80. /**@brief Data structure for ANT+ common data page 80. * - * @note This structure implements only page 80 specific data. + * @note This structure implements only page 80 specific data. */ typedef struct { @@ -80,5 +112,10 @@ void ant_common_page_80_encode(uint8_t * p_page_buffer, void ant_common_page_80_decode(uint8_t const * p_page_buffer, volatile ant_common_page80_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_COMMON_PAGE_80_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c b/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c index d109fca..3259bae 100644 --- a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c +++ b/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c @@ -1,19 +1,56 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_COMMON_PAGE_81) + #include "ant_common_page_81.h" -#include "ant_common_page_logger.h" -#include "app_util.h" -#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "ANT_COMMON_PAGE_81" +#if ANT_COMMON_PAGE_81_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_COMMON_PAGE_81_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_COMMON_PAGE_81_INFO_COLOR +#else // ANT_COMMON_PAGE_81_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_COMMON_PAGE_81_LOG_ENABLED +#include "nrf_log.h" /**@brief ant+ common page 81 data layout structure. */ typedef struct @@ -33,16 +70,16 @@ static void page81_data_log(volatile ant_common_page81_data_t const * p_page_dat { if (p_page_data->sw_revision_minor != UINT8_MAX) { - LOG_PAGE81("sw revision: %u.%u\n\r", + NRF_LOG_INFO("sw revision: %u.%u\r\n", ((ant_common_page81_data_t const *) p_page_data)->sw_revision_major, ((ant_common_page81_data_t const *) p_page_data)->sw_revision_minor); } else { - LOG_PAGE81("sw revision: %u\n\r", p_page_data->sw_revision_major); + NRF_LOG_INFO("sw revision: %u\r\n", p_page_data->sw_revision_major); } - LOG_PAGE81("serial number: %u\n\r", (unsigned int) p_page_data->serial_number); + NRF_LOG_INFO("serial number: %u\r\n\n", (unsigned int) p_page_data->serial_number); } @@ -77,4 +114,4 @@ void ant_common_page_81_decode(uint8_t const * p_page_buffer page81_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_COMMON_PAGE_81) diff --git a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h b/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h index 1e8ef6c..a62e83e 100644 --- a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h +++ b/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_COMMON_PAGE_81_H__ @@ -15,18 +43,22 @@ /** @file * - * @defgroup ant_sdk_common_page81 ANT+ common page 81 + * @defgroup ant_common_page_81 ANT+ common page 81 * @{ * @ingroup ant_sdk_common_pages */ #include +#ifdef __cplusplus +extern "C" { +#endif + #define ANT_COMMON_PAGE_81 (81) ///< @brief ID value of common page 81. /**@brief Data structure for ANT+ common data page 81. * - * @note This structure implements only page 81 specific data. + * @note This structure implements only page 81 specific data. */ typedef struct { @@ -71,5 +103,10 @@ void ant_common_page_81_encode(uint8_t * p_page_buffer, void ant_common_page_81_decode(uint8_t const * p_page_buffer, volatile ant_common_page81_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_COMMON_PAGE_81_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_common/pages/logger/ant_common_page_logger.h b/components/ant/ant_profiles/ant_common/pages/logger/ant_common_page_logger.h deleted file mode 100644 index ed24c6c..0000000 --- a/components/ant/ant_profiles/ant_common/pages/logger/ant_common_page_logger.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef ANT_COMMON_PAGE_LOGGER_H__ -#define ANT_COMMON_PAGE_LOGGER_H__ - -#ifdef TRACE_COMMON_PAGE_70_ENABLE -#include "app_trace.h" -#define LOG_PAGE70 app_trace_log -#else -#define LOG_PAGE70(...) -#endif // TRACE_COMMON_PAGE_70_ENABLE - -#ifdef TRACE_COMMON_PAGE_80_ENABLE -#include "app_trace.h" -#define LOG_PAGE80 app_trace_log -#else -#define LOG_PAGE80(...) -#endif // TRACE_COMMON_PAGE_80_ENABLE - -#ifdef TRACE_COMMON_PAGE_81_ENABLE -#include "app_trace.h" -#define LOG_PAGE81 app_trace_log -#else -#define LOG_PAGE81(...) -#endif // TRACE_COMMON_PAGE_81_ENABLE - - -#endif // ANT_COMMON_PAGE_LOGGER_H__ diff --git a/components/ant/ant_profiles/ant_hrm/ant_hrm.c b/components/ant/ant_profiles/ant_hrm/ant_hrm.c index 2347b41..ac48339 100644 --- a/components/ant/ant_profiles/ant_hrm/ant_hrm.c +++ b/components/ant/ant_profiles/ant_hrm/ant_hrm.c @@ -1,23 +1,63 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_config.h" +#if ANT_HRM_ENABLED + #include "nrf_assert.h" #include "app_error.h" #include "ant_interface.h" #include "app_util.h" #include "ant_hrm.h" #include "ant_hrm_utils.h" -#include "ant_hrm_page_logger.h" #include "app_error.h" +#define NRF_LOG_MODULE_NAME "ANT_HRM" +#if ANT_HRM_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_INFO_COLOR +#else // ANT_HRM_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_LOG_ENABLED +#include "nrf_log.h" + #define BACKGROUND_DATA_INTERVAL 64 /**< The number of main data pages sent between background data page. Background data page is sent every 65th message. */ #define TX_TOGGLE_DIVISOR 4 /**< The number of messages between changing state of toggle bit. */ @@ -48,7 +88,7 @@ static ret_code_t ant_hrm_init(ant_hrm_profile_t * p_profile, p_profile->page_3 = DEFAULT_ANT_HRM_PAGE3(); p_profile->page_4 = DEFAULT_ANT_HRM_PAGE4(); - LOG_HRM("ANT HRM channel %u init\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT HRM channel %u init\r\n", p_profile->channel_number); return ant_channel_init(p_channel_config); } @@ -147,7 +187,7 @@ static void sens_message_encode(ant_hrm_profile_t * p_profile, uint8_t * p_messa p_hrm_message_payload->page_number = next_page_number_get(p_profile); p_hrm_message_payload->toggle_bit = p_hrm_cb->toggle_bit; - LOG_HRM("HRM TX Page number: %u\n\r", p_hrm_message_payload->page_number); + NRF_LOG_INFO("HRM TX Page number: %u\r\n", p_hrm_message_payload->page_number); ant_hrm_page_0_encode(p_hrm_message_payload->page_payload, &(p_profile->page_0)); // Page 0 is present in each message @@ -174,10 +214,9 @@ static void sens_message_encode(ant_hrm_profile_t * p_profile, uint8_t * p_messa break; default: - LOG_HRM("\r\n"); return; } - LOG_HRM("\r\n"); + p_profile->evt_handler(p_profile, (ant_hrm_evt_t)p_hrm_message_payload->page_number); } @@ -221,7 +260,7 @@ ret_code_t ant_hrm_disp_open(ant_hrm_profile_t * p_profile) { ASSERT(p_profile != NULL); - LOG_HRM("ANT HRM channel %u open\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT HRM channel %u open\r\n", p_profile->channel_number); return sd_ant_channel_open(p_profile->channel_number); } @@ -233,7 +272,7 @@ ret_code_t ant_hrm_sens_open(ant_hrm_profile_t * p_profile) // Fill tx buffer for the first frame ant_message_send(p_profile); - LOG_HRM("ANT HRM channel %u open\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT HRM channel %u open\r\n", p_profile->channel_number); return sd_ant_channel_open(p_profile->channel_number); } @@ -247,7 +286,7 @@ static void disp_message_decode(ant_hrm_profile_t * p_profile, uint8_t * p_messa const ant_hrm_message_layout_t * p_hrm_message_payload = (ant_hrm_message_layout_t *)p_message_payload; - LOG_HRM("HRM RX Page Number: %u\n\r", p_hrm_message_payload->page_number); + NRF_LOG_INFO("HRM RX Page Number: %u\r\n", p_hrm_message_payload->page_number); ant_hrm_page_0_decode(p_hrm_message_payload->page_payload, &(p_profile->page_0)); // Page 0 is present in each message @@ -274,10 +313,8 @@ static void disp_message_decode(ant_hrm_profile_t * p_profile, uint8_t * p_messa break; default: - LOG_HRM("\r\n"); return; } - LOG_HRM("\r\n"); p_profile->evt_handler(p_profile, (ant_hrm_evt_t)p_hrm_message_payload->page_number); } @@ -287,7 +324,7 @@ void ant_hrm_disp_evt_handler(ant_hrm_profile_t * p_profile, ant_evt_t * p_ant_e { if (p_ant_event->channel == p_profile->channel_number) { - ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->evt_buffer; + ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; switch (p_ant_event->event) { @@ -307,4 +344,4 @@ void ant_hrm_disp_evt_handler(ant_hrm_profile_t * p_profile, ant_evt_t * p_ant_e } } - +#endif // ANT_HRM_ENABLED diff --git a/components/ant/ant_profiles/ant_hrm/ant_hrm.h b/components/ant/ant_profiles/ant_hrm/ant_hrm.h index fca74af..e441ed7 100644 --- a/components/ant/ant_profiles/ant_hrm/ant_hrm.h +++ b/components/ant/ant_profiles/ant_hrm/ant_hrm.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ant_sdk_profiles_hrm Heart Rate Monitor profile + * @defgroup ant_hrm Heart Rate Monitor profile * @{ * @ingroup ant_sdk_profiles * @brief This module implements the Heart Rate Monitor profile. @@ -148,6 +176,10 @@ typedef void (* ant_hrm_evt_handler_t) (ant_hrm_profile_t *, ant_hrm_evt_t); #include "ant_hrm_local.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief HRM sensor configuration structure. */ typedef struct { @@ -249,6 +281,11 @@ void ant_hrm_sens_evt_handler(ant_hrm_profile_t * p_profile, ant_evt_t * p_ant_e * @param[in] p_ant_event Event received from the ANT stack. */ void ant_hrm_disp_evt_handler(ant_hrm_profile_t * p_profile, ant_evt_t * p_ant_event); + +#ifdef __cplusplus +} +#endif + #endif // ANT_HRM_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h b/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h index f112230..f8cca6a 100644 --- a/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h +++ b/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ @@ -18,8 +46,12 @@ #include #include "ant_hrm.h" +#ifdef __cplusplus +extern "C" { +#endif + /** - * @addtogroup ant_sdk_profiles_hrm + * @addtogroup ant_hrm * @{ */ @@ -37,4 +69,9 @@ typedef struct * @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_HRM_LOCAL_H__ diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c index 94645df..db90550 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c @@ -1,17 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_HRM) + #include "ant_hrm_page_0.h" #include "ant_hrm_utils.h" -#include "ant_hrm_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM_PAGE_0" +#if ANT_HRM_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_PAGE_0_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_0_INFO_COLOR +#else // ANT_HRM_PAGE_0_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_PAGE_0_LOG_ENABLED +#include "nrf_log.h" /**@brief HRM page 0 data layout structure. */ typedef struct @@ -30,12 +70,12 @@ typedef struct */ static void page0_data_log(ant_hrm_page0_data_t const * p_page_data) { - LOG_PAGE0("Heart beat count: %u\n\r", (unsigned int)p_page_data->beat_count); - LOG_PAGE0("Computed heart rate: %u\n\r", - (unsigned int)p_page_data->computed_heart_rate); - LOG_PAGE0("Heart beat event time: %u.", - (unsigned int)ANT_HRM_BEAT_TIME_SEC(p_page_data->beat_time)); - LOG_PAGE0("%03us\n\r", (unsigned int)ANT_HRM_BEAT_TIME_MSEC(p_page_data->beat_time)); + NRF_LOG_INFO("Heart beat count: %u\r\n", (unsigned int)p_page_data->beat_count); + NRF_LOG_INFO("Computed heart rate: %u\r\n", + (unsigned int) p_page_data->computed_heart_rate); + NRF_LOG_INFO("Heart beat event time: %u.%03us\r\n\n", + (unsigned int) ANT_HRM_BEAT_TIME_SEC(p_page_data->beat_time), + (unsigned int) ANT_HRM_BEAT_TIME_MSEC(p_page_data->beat_time)); } @@ -73,4 +113,4 @@ void ant_hrm_page_0_decode(uint8_t const * p_page_buffer, page0_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_HRM) diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h index 24cad8a..6006183 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_HRM_PAGE_0_H__ #define ANT_HRM_PAGE_0_H__ @@ -21,6 +49,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for HRM data page 0. * * This structure is used as a common page. @@ -58,5 +90,10 @@ void ant_hrm_page_0_encode(uint8_t * p_page_buffer, void ant_hrm_page_0_decode(uint8_t const * p_page_buffer, ant_hrm_page0_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_HRM_PAGE_0_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c index 9807fed..fccf06a 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c @@ -1,19 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_HRM) + #include "ant_hrm_page_1.h" #include "ant_hrm_utils.h" -#include "ant_hrm_page_logger.h" -#include "app_util.h" -#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM_PAGE_1" +#if ANT_HRM_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_PAGE_1_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_1_INFO_COLOR +#else // ANT_HRM_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_PAGE_1_LOG_ENABLED +#include "nrf_log.h" /**@brief HRM page 1 data layout structure. */ typedef struct @@ -29,11 +67,11 @@ typedef struct */ static void page1_data_log(ant_hrm_page1_data_t const * p_page_data) { - LOG_PAGE1("Cumulative operating time: %ud ", - (unsigned int)ANT_HRM_OPERATING_DAYS(p_page_data->operating_time)); - LOG_PAGE1("%uh ", (unsigned int)ANT_HRM_OPERATING_HOURS(p_page_data->operating_time)); - LOG_PAGE1("%um ", (unsigned int)ANT_HRM_OPERATING_MINUTES(p_page_data->operating_time)); - LOG_PAGE1("%us\n\r", (unsigned int)ANT_HRM_OPERATING_SECONDS(p_page_data->operating_time)); + NRF_LOG_INFO("Cumulative operating time: %ud %uh %um %us\r\n\n", + (unsigned int) ANT_HRM_OPERATING_DAYS(p_page_data->operating_time), + (unsigned int) ANT_HRM_OPERATING_HOURS(p_page_data->operating_time), + (unsigned int) ANT_HRM_OPERATING_MINUTES(p_page_data->operating_time), + (unsigned int) ANT_HRM_OPERATING_SECONDS(p_page_data->operating_time)); } @@ -61,4 +99,4 @@ void ant_hrm_page_1_decode(uint8_t const * p_page_buffer, page1_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_HRM) diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h index 7b02861..b79c28e 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_HRM_PAGE_1_H__ #define ANT_HRM_PAGE_1_H__ @@ -21,6 +49,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for HRM data page 1. * * This structure implements only page 1 specific data. @@ -54,5 +86,10 @@ void ant_hrm_page_1_encode(uint8_t * p_page_buffer, void ant_hrm_page_1_decode(uint8_t const * p_page_buffer, ant_hrm_page1_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_HRM_PAGE_1_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c index 3a9ff52..f73bc6c 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c @@ -1,16 +1,56 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_HRM) + #include "ant_hrm_page_2.h" -#include "ant_hrm_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM_PAGE_2" +#if ANT_HRM_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_PAGE_2_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_2_INFO_COLOR +#else // ANT_HRM_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_PAGE_2_LOG_ENABLED +#include "nrf_log.h" /**@brief HRM page 2 data layout structure. */ typedef struct @@ -28,8 +68,8 @@ typedef struct */ static void page2_data_log(ant_hrm_page2_data_t const * p_page_data) { - LOG_PAGE2("Manufacturer ID: %u\n\r", (unsigned int)p_page_data->manuf_id); - LOG_PAGE2("Serial No (upper 16-bits): 0x%X\n\r", (unsigned int)p_page_data->serial_num); + NRF_LOG_INFO("Manufacturer ID: %u\r\n", (unsigned int)p_page_data->manuf_id); + NRF_LOG_INFO("Serial No (upper 16-bits): 0x%X\r\n\n", (unsigned int)p_page_data->serial_num); } @@ -63,4 +103,4 @@ void ant_hrm_page_2_decode(uint8_t const * p_page_buffer, page2_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_HRM) diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h index 1ba449e..6d426e7 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_HRM_PAGE_2_H__ #define ANT_HRM_PAGE_2_H__ @@ -21,6 +49,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for HRM data page 2. * * This structure implements only page 2 specific data. @@ -56,5 +88,10 @@ void ant_hrm_page_2_encode(uint8_t * p_page_buffer, void ant_hrm_page_2_decode(uint8_t const * p_page_buffer, ant_hrm_page2_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_HRM_PAGE_2_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c index e9bd4de..5eb783d 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c @@ -1,16 +1,56 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_HRM) + #include "ant_hrm_page_3.h" -#include "ant_hrm_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM_PAGE_3" +#if ANT_HRM_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_PAGE_3_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_3_INFO_COLOR +#else // ANT_HRM_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_PAGE_3_LOG_ENABLED +#include "nrf_log.h" /**@brief HRM page 3 data layout structure. */ typedef struct @@ -28,9 +68,9 @@ typedef struct */ static void page3_data_log(ant_hrm_page3_data_t const * p_page_data) { - LOG_PAGE3("Hardware Rev ID %u\n\r", (unsigned int)p_page_data->hw_version); - LOG_PAGE3("Model %u\n\r", (unsigned int)p_page_data->model_num); - LOG_PAGE3("Software Ver ID %u\n\r", (unsigned int)p_page_data->sw_version); + NRF_LOG_INFO("Hardware Rev ID %u\r\n", (unsigned int)p_page_data->hw_version); + NRF_LOG_INFO("Model %u\r\n", (unsigned int)p_page_data->model_num); + NRF_LOG_INFO("Software Ver ID %u\r\n\n", (unsigned int)p_page_data->sw_version); } @@ -60,4 +100,4 @@ void ant_hrm_page_3_decode(uint8_t const * p_page_buffer, page3_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_HRM) diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h index 9455a2d..8f04b37 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_HRM_PAGE_3_H__ #define ANT_HRM_PAGE_3_H__ @@ -21,6 +49,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for HRM data page 3. * * This structure implements only page 3 specific data. @@ -58,5 +90,10 @@ void ant_hrm_page_3_encode(uint8_t * p_page_buffer, void ant_hrm_page_3_decode(uint8_t const * p_page_buffer, ant_hrm_page3_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_HRM_PAGE_3_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c index c73b6e3..3abf6b1 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c @@ -1,17 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_HRM) + #include "ant_hrm_page_4.h" #include "ant_hrm_utils.h" -#include "ant_hrm_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_HRM_PAGE_4" +#if ANT_HRM_PAGE_4_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_HRM_PAGE_4_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_4_INFO_COLOR +#else // ANT_HRM_PAGE_4_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_HRM_PAGE_4_LOG_ENABLED +#include "nrf_log.h" /**@brief HRM page 4 data layout structure. */ typedef struct @@ -29,9 +69,9 @@ typedef struct */ static void page4_data_log(ant_hrm_page4_data_t const * p_page_data) { - LOG_PAGE4("Previous heart beat event time: %u.", - (unsigned int)ANT_HRM_BEAT_TIME_SEC(p_page_data->prev_beat)); - LOG_PAGE4("%03us\n\r", (unsigned int)ANT_HRM_BEAT_TIME_MSEC(p_page_data->prev_beat)); + NRF_LOG_INFO("Previous heart beat event time: %u.%03us\r\n\n", + (unsigned int)ANT_HRM_BEAT_TIME_SEC(p_page_data->prev_beat), + (unsigned int)ANT_HRM_BEAT_TIME_MSEC(p_page_data->prev_beat)); } @@ -64,4 +104,4 @@ void ant_hrm_page_4_decode(uint8_t const * p_page_buffer, page4_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_HRM) diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h index e36d8af..a73e80c 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_HRM_PAGE_4_H__ #define ANT_HRM_PAGE_4_H__ @@ -21,6 +49,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for HRM data page 4. * * This structure implements only page 4 specific data. @@ -56,5 +88,10 @@ void ant_hrm_page_4_encode(uint8_t * p_page_buffer, void ant_hrm_page_4_decode(uint8_t const * p_page_buffer, ant_hrm_page4_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_HRM_PAGE_3_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h index bf4e4d9..ae82ba9 100644 --- a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h +++ b/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 __ANT_HRM_PAGES_H #define __ANT_HRM_PAGES_H @@ -16,7 +44,7 @@ * * @defgroup ant_sdk_profiles_hrm_pages Heart Rate Monitor profile pages * @{ - * @ingroup ant_sdk_profiles_hrm + * @ingroup ant_hrm * @brief This module implements functions for the HRM data pages. */ @@ -26,5 +54,14 @@ #include "ant_hrm_page_3.h" #include "ant_hrm_page_4.h" +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + #endif // __ANT_HRM_PAGES_H /** @} */ diff --git a/components/ant/ant_profiles/ant_hrm/pages/logger/ant_hrm_page_logger.h b/components/ant/ant_profiles/ant_hrm/pages/logger/ant_hrm_page_logger.h deleted file mode 100644 index fcf803c..0000000 --- a/components/ant/ant_profiles/ant_hrm/pages/logger/ant_hrm_page_logger.h +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 ANT_HRM_PAGE_LOGGER_H__ -#define ANT_HRM_PAGE_LOGGER_H__ - -#ifdef TRACE_HRM_GENERAL_ENABLE -#include "app_trace.h" -#define LOG_HRM app_trace_log -#else -#define LOG_HRM(...) -#endif // TRACE_HRM_GENERAL_ENABLE - -#ifdef TRACE_HRM_PAGE_0_ENABLE -#include "app_trace.h" -#define LOG_PAGE0 app_trace_log -#else -#define LOG_PAGE0(...) -#endif // TRACE_HRM_PAGE_0_ENABLE - -#ifdef TRACE_HRM_PAGE_1_ENABLE -#include "app_trace.h" -#define LOG_PAGE1 app_trace_log -#else -#define LOG_PAGE1(...) -#endif // TRACE_HRM_PAGE_1_ENABLE - -#ifdef TRACE_HRM_PAGE_2_ENABLE -#include "app_trace.h" -#define LOG_PAGE2 app_trace_log -#else -#define LOG_PAGE2(...) -#endif // TRACE_HRM_PAGE_2_ENABLE - -#ifdef TRACE_HRM_PAGE_3_ENABLE -#include "app_trace.h" -#define LOG_PAGE3 app_trace_log -#else -#define LOG_PAGE3(...) -#endif // TRACE_HRM_PAGE_3_ENABLE - -#ifdef TRACE_HRM_PAGE_4_ENABLE -#include "app_trace.h" -#define LOG_PAGE4 app_trace_log -#else -#define LOG_PAGE4(...) -#endif // TRACE_HRM_PAGE_4_ENABLE - -#endif // ANT_HRM_UTILS_H__ diff --git a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c b/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c index 062f6c2..5b6103e 100644 --- a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c +++ b/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c @@ -1,15 +1,46 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_config.h" +#if ANT_HRM_ENABLED + #include "ant_hrm_simulator.h" #include "ant_hrm_utils.h" #include "nordic_common.h" @@ -115,3 +146,4 @@ void ant_hrm_simulator_decrement(ant_hrm_simulator_t * p_simulator) } +#endif // ANT_HRM_ENABLED diff --git a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h b/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h index acc8976..6767afd 100644 --- a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h +++ b/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_HRM_SIMULATOR_H__ @@ -28,12 +56,15 @@ #include #include -#include "bsp.h" #include "ant_hrm.h" #include "ant_hrm_utils.h" #include "sensorsim.h" #include "ant_hrm_simulator_local.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief HRM simulator configuration structure. */ typedef struct @@ -91,5 +122,10 @@ void ant_hrm_simulator_increment(ant_hrm_simulator_t * p_simulator); */ void ant_hrm_simulator_decrement(ant_hrm_simulator_t * p_simulator); + +#ifdef __cplusplus +} +#endif + #endif // ANT_HRM_SIMULATOR_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h b/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h index f2a8899..d6c76a4 100644 --- a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h +++ b/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_HRM_SIMULATOR_LOCAL_H__ @@ -15,10 +43,13 @@ #include #include -#include "bsp.h" #include "ant_hrm.h" #include "sensorsim.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @ingroup ant_sdk_hrm_simulator * @brief HRM simulator control block structure. */ @@ -31,4 +62,9 @@ typedef struct sensorsim_cfg_t sensorsim_cfg; ///< Configuration of the simulated sensor. } ant_hrm_simulator_cb_t; + +#ifdef __cplusplus +} +#endif + #endif // ANT_HRM_SIMULATOR_LOCAL_H__ diff --git a/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h b/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h index c14aa77..f8e35d9 100644 --- a/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h +++ b/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_HRM_UTILS_H__ #define ANT_HRM_UTILS_H__ @@ -16,11 +44,15 @@ #include "nrf_assert.h" #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @file * * @defgroup ant_sdk_profiles_hrm_utils Heart Rate Monitor profile utilities * @{ - * @ingroup ant_sdk_profiles_hrm + * @ingroup ant_hrm * @brief This module implements utilities for the Heart Rate Monitor profile. * */ @@ -70,5 +102,10 @@ / ANT_HRM_BEAT_TIME_COUNTS_PER_SEC) /** @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_HRM_UTILS_H__ diff --git a/components/ant/ant_profiles/ant_sdm/ant_sdm.c b/components/ant/ant_profiles/ant_sdm/ant_sdm.c index 53cbbce..64d9290 100644 --- a/components/ant/ant_profiles/ant_sdm/ant_sdm.c +++ b/components/ant/ant_profiles/ant_sdm/ant_sdm.c @@ -1,24 +1,61 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + #include "nrf_assert.h" #include "app_error.h" #include "ant_interface.h" -#include "app_util.h" #include "ant_sdm.h" #include "app_error.h" -#include "ant_sdm_page_logger.h" #include "ant_sdm_utils.h" -#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM" +#if ANT_SDM_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR +#else // ANT_SDM_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_LOG_ENABLED +#include "nrf_log.h" #define COMMON_DATA_INTERVAL 64 /**< Common data page is sent every 65th message. */ @@ -50,7 +87,7 @@ static ret_code_t ant_sdm_init(ant_sdm_profile_t * p_profile, p_profile->page_80 = DEFAULT_ANT_COMMON_page80(); p_profile->page_81 = DEFAULT_ANT_COMMON_page81(); - LOG_SDM("ANT SDM channel %u init\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT SDM channel %u init\r\n", p_profile->channel_number); return ant_channel_init(p_channel_config); } @@ -103,7 +140,7 @@ ret_code_t ant_sdm_page_request(ant_sdm_profile_t * p_profile, ant_common_page70 uint32_t err_code = ant_request_controller_request(&(p_profile->_cb.p_disp_cb->req_controller), p_profile->channel_number, p_page_70); - LOG_SDM("\n\r"); + NRF_LOG_INFO("\r\n"); return err_code; } @@ -168,7 +205,7 @@ static void sens_message_encode(ant_sdm_profile_t * p_profile, uint8_t * p_messa p_sdm_message_payload->page_number = next_page_number_get(p_profile); - LOG_SDM("SDM Page number %u\n\r", p_sdm_message_payload->page_number); + NRF_LOG_INFO("SDM Page number: %u\r\n", p_sdm_message_payload->page_number); switch (p_sdm_message_payload->page_number) { @@ -206,11 +243,8 @@ static void sens_message_encode(ant_sdm_profile_t * p_profile, uint8_t * p_messa break; default: - LOG_SDM("\r\n"); return; } - LOG_SDM("\r\n"); - p_profile->evt_handler(p_profile, (ant_sdm_evt_t)p_sdm_message_payload->page_number); } @@ -253,7 +287,7 @@ ret_code_t ant_sdm_disp_open(ant_sdm_profile_t * p_profile) { ASSERT(p_profile != NULL); - LOG_SDM("ANT SDM channel %u open\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT SDM channel %u open\r\n", p_profile->channel_number); return sd_ant_channel_open(p_profile->channel_number); } @@ -272,7 +306,7 @@ ret_code_t ant_sdm_sens_open(ant_sdm_profile_t * p_profile) p_message_payload); APP_ERROR_CHECK(err_code); - LOG_SDM("ANT SDM channel %u open\n\r", p_profile->channel_number); + NRF_LOG_INFO("ANT SDM channel %u open\r\n", p_profile->channel_number); return sd_ant_channel_open(p_profile->channel_number); } @@ -285,7 +319,7 @@ static void disp_message_decode(ant_sdm_profile_t * p_profile, uint8_t * p_messa { const ant_sdm_message_layout_t * p_sdm_message_payload = (ant_sdm_message_layout_t *)p_message_payload; - LOG_SDM("SDM Page number %u\n\r", p_sdm_message_payload->page_number); + NRF_LOG_INFO("SDM Page number: %u\r\n", p_sdm_message_payload->page_number); switch (p_sdm_message_payload->page_number) { @@ -319,10 +353,8 @@ static void disp_message_decode(ant_sdm_profile_t * p_profile, uint8_t * p_messa break; default: - LOG_SDM("\n"); return; } - LOG_SDM("\n"); p_profile->evt_handler(p_profile, (ant_sdm_evt_t)p_sdm_message_payload->page_number); } @@ -334,7 +366,7 @@ void ant_sdm_disp_evt_handler(ant_sdm_profile_t * p_profile, ant_evt_t * p_ant_e if (p_ant_event->channel == p_profile->channel_number) { - ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->evt_buffer; + ANT_MESSAGE * p_message = (ANT_MESSAGE *)p_ant_event->msg.evt_buffer; ant_sdm_disp_cb_t * p_sdm_cb = p_profile->_cb.p_disp_cb; switch (ant_request_controller_disp_evt_handler(&(p_sdm_cb->req_controller), p_ant_event)) @@ -364,3 +396,5 @@ void ant_sdm_disp_evt_handler(ant_sdm_profile_t * p_profile, ant_evt_t * p_ant_e } } } + +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/components/ant/ant_profiles/ant_sdm/ant_sdm.h b/components/ant/ant_profiles/ant_sdm/ant_sdm.h index d9ee0b3..b7da9d0 100644 --- a/components/ant/ant_profiles/ant_sdm/ant_sdm.h +++ b/components/ant/ant_profiles/ant_sdm/ant_sdm.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ant_sdk_profiles_sdm Stride Based Speed and Distance Monitor profile + * @defgroup ant_sdm Stride Based Speed and Distance Monitor profile * @{ * @ingroup ant_sdk_profiles * @brief This module implements the Stride Based Speed and Distance Monitor profile. @@ -157,7 +185,7 @@ typedef enum{ ANT_SDM_PAGE_REQUEST_FAILED, ///< Data page request did not reach the destination. } ant_sdm_evt_t; -// Forward declaration of the ant_sdm_profile_t type. +// Forward declaration of the ant_sdm_profile_t type. typedef struct ant_sdm_profile_s ant_sdm_profile_t; /**@brief SDM event handler type. */ @@ -165,6 +193,10 @@ typedef void (* ant_sdm_evt_handler_t) (ant_sdm_profile_t *, ant_sdm_evt_t); #include "ant_sdm_local.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief SDM Sensor configuration structure. */ typedef struct { @@ -290,5 +322,10 @@ void ant_sdm_sens_evt_handler(ant_sdm_profile_t * p_profile, ant_evt_t * p_ant_e */ void ant_sdm_disp_evt_handler(ant_sdm_profile_t * p_profile, ant_evt_t * p_ant_event); + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h b/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h index bb3e4d4..6b19c77 100644 --- a/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h +++ b/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ @@ -18,8 +46,12 @@ #include #include "ant_sdm.h" +#ifdef __cplusplus +extern "C" { +#endif + /** - * @addtogroup ant_sdk_profiles_sdm + * @addtogroup ant_sdm * @{ */ @@ -43,4 +75,9 @@ typedef struct * @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_LOCAL_H__ diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c index 6c7e65f..d734057 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c @@ -1,19 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + #include "ant_sdm_common_data.h" #include "ant_sdm_utils.h" -#include "ant_sdm_page_logger.h" -#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM" +#if ANT_SDM_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR +#else // ANT_SDM_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_LOG_ENABLED +#include "nrf_log.h" /**@brief SDM common page data layout structure. */ typedef struct @@ -34,9 +72,9 @@ static void speed_data_log(ant_sdm_common_data_t const * p_common_data) uint32_t speed = ANT_SDM_SPEED_RESCALE(p_common_data->speed); UNUSED_VARIABLE(speed); - LOG_SPEED("Speed %u.%02u m/s\n\r", - (unsigned int)(speed / ANT_SDM_SPEED_DISP_PRECISION), - (unsigned int)(speed % ANT_SDM_SPEED_DISP_PRECISION)); + NRF_LOG_INFO("Speed %u.%02u m/s\r\n\n", + (unsigned int)(speed / ANT_SDM_SPEED_DISP_PRECISION), + (unsigned int)(speed % ANT_SDM_SPEED_DISP_PRECISION)); } void ant_sdm_speed_encode(uint8_t * p_page_buffer, @@ -55,7 +93,7 @@ void ant_sdm_speed_decode(uint8_t const * p_page_buffer, ant_sdm_common_data_t * p_common_data) { ant_sdm_speed_data_layout_t const * p_incoming_data = (ant_sdm_speed_data_layout_t *)p_page_buffer; - uint16_t speed = (p_incoming_data->speed_integer + uint16_t speed = (p_incoming_data->speed_integer * ANT_SDM_SPEED_UNIT_REVERSAL) + p_incoming_data->speed_fractional; @@ -63,3 +101,5 @@ void ant_sdm_speed_decode(uint8_t const * p_page_buffer, speed_data_log(p_common_data); } + +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h index 8b0be4e..afd2e2b 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_SDM_COMMON_DATA_H__ @@ -22,6 +50,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for SDM common data. * * @details This structure stores data that is not associated with a particular page. @@ -63,5 +95,10 @@ void ant_sdm_speed_encode(uint8_t * p_page_buffer, void ant_sdm_speed_decode(uint8_t const * p_page_buffer, ant_sdm_common_data_t * p_common_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_COMMON_DATA_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c index 51a60ef..e23f215 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c @@ -1,18 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + #include "ant_sdm_page_1.h" #include "ant_sdm_utils.h" -#include "ant_sdm_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM_PAGE_1" +#if ANT_SDM_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_PAGE_1_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_PAGE_1_INFO_COLOR +#else // ANT_SDM_PAGE_1_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_PAGE_1_LOG_ENABLED +#include "nrf_log.h" /**@brief SDM page 1 data layout structure. */ typedef struct @@ -39,23 +78,21 @@ STATIC_ASSERT(ANT_SDM_DISTANCE_DISP_PRECISION == 10); ///< Display forma static void page_1_data_log(ant_sdm_page1_data_t const * p_page_data, ant_sdm_common_data_t const * p_common_data) { -#ifdef TRACE_SDM_PAGE_1_ENABLE uint32_t strides = p_common_data->strides; uint64_t distance = ANT_SDM_DISTANCE_RESCALE(p_common_data->distance); uint16_t update_latency = ANT_SDM_UPDATE_LATENCY_RESCALE(p_page_data->update_latency); uint32_t time = ANT_SDM_TIME_RESCALE(p_page_data->time); -#endif // TRACE_SDM_PAGE_1_ENABLE - LOG_PAGE1("Update latency %u.%03u s\n\r", + NRF_LOG_INFO("Update latency %u.%03u s\r\n", update_latency / ANT_SDM_UPDATE_LATENCY_DISP_PRECISION, update_latency % ANT_SDM_UPDATE_LATENCY_DISP_PRECISION); - LOG_PAGE1("Time %u.%03u s\n\r", + NRF_LOG_INFO("Time %u.%03u s\r\n", (unsigned int)(time / ANT_SDM_TIME_DISP_PRECISION), (unsigned int)(time % ANT_SDM_TIME_DISP_PRECISION)); - LOG_PAGE1("Distance %u.%01um \n\r", + NRF_LOG_INFO("Distance %u.%01um \r\n", (unsigned int)(distance / ANT_SDM_DISTANCE_DISP_PRECISION), (unsigned int)(distance % ANT_SDM_DISTANCE_DISP_PRECISION)); - LOG_PAGE1("Strides %u\n\r", (unsigned int)strides); + NRF_LOG_INFO("Strides %u\r\n", (unsigned int)strides); } @@ -105,4 +142,4 @@ void ant_sdm_page_1_decode(uint8_t const * p_page_buffer, page_1_data_log(p_page_data, p_common_data); } - +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h index 5bcd9d2..4e2ca41 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_SDM_PAGE_1_H__ @@ -23,6 +51,10 @@ #include #include "ant_sdm_common_data.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for SDM data page 1. */ typedef struct @@ -61,5 +93,10 @@ void ant_sdm_page_1_decode(uint8_t const * p_page_buffer, ant_sdm_page1_data_t * p_page_data, ant_sdm_common_data_t * p_common_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_PAGE_1_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c index b9a1d34..b0f465d 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c @@ -1,19 +1,58 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + #include "ant_sdm_page_16.h" #include "ant_sdm_utils.h" -#include "nordic_common.h" -#include "ant_sdm_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM_PAGE_16" +#if ANT_SDM_PAGE_16_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_PAGE_16_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_PAGE_16_INFO_COLOR +#else // ANT_SDM_PAGE_16_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_PAGE_16_LOG_ENABLED +#include "nrf_log.h" + /**@brief SDM page 16 data layout structure. */ typedef struct @@ -30,14 +69,13 @@ STATIC_ASSERT(ANT_SDM_DISTANCE_DISP_PRECISION == 10); ///< Display format need t */ static void page_16_data_log(ant_sdm_common_data_t const * p_common_data) { -#ifdef TRACE_SDM_PAGE_16_ENABLE uint64_t distance = ANT_SDM_DISTANCE_RESCALE(p_common_data->distance); -#endif // TRACE_SDM_PAGE_16_ENABLE - LOG_PAGE16("Distance %u.%01u m\n\r", - (unsigned int)(distance / ANT_SDM_DISTANCE_DISP_PRECISION), - (unsigned int)(distance % ANT_SDM_DISTANCE_DISP_PRECISION)); - LOG_PAGE16("Strides %u\n\r", (unsigned int)p_common_data->strides); + NRF_LOG_INFO("Distance %u.%01u m\r\n", + (unsigned int)(distance / ANT_SDM_DISTANCE_DISP_PRECISION), + (unsigned int)(distance % ANT_SDM_DISTANCE_DISP_PRECISION)); + NRF_LOG_INFO("Strides %u\r\n\n", + (unsigned int)p_common_data->strides); } @@ -65,4 +103,4 @@ void ant_sdm_page_16_decode(uint8_t const * p_page_buffer, page_16_data_log(p_common_data); } - +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h index 11aa653..a721d2b 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_SDM_PAGE_16_H__ @@ -23,6 +51,10 @@ #include #include "ant_sdm_common_data.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Function for encoding page 16. * * @param[in] p_common_data Pointer to the page data. @@ -39,5 +71,10 @@ void ant_sdm_page_16_encode(uint8_t * p_page_buffer, void ant_sdm_page_16_decode(uint8_t const * p_page_buffer, ant_sdm_common_data_t * p_common_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_PAGE_16_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c index 2e11a94..b9f4a08 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c @@ -1,18 +1,58 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + #include "ant_sdm_page_2.h" #include "ant_sdm_utils.h" -#include "ant_sdm_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM_PAGE_2" +#if ANT_SDM_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_PAGE_2_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_PAGE_2_INFO_COLOR +#else // ANT_SDM_PAGE_2_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_PAGE_2_LOG_ENABLED +#include "nrf_log.h" + /**@brief SDM page 2 data layout structure. */ typedef struct @@ -32,24 +72,23 @@ typedef struct */ static void page_2_data_log(ant_sdm_page2_data_t const * p_page_data) { -#ifdef TRACE_SDM_PAGE_2_ENABLE static const char * p_location[4] = {"Laces", "Midsole", "Other", "Ankle"}; static const char * p_battery[4] = {"New", "Good", "OK", "Low"}; static const char * p_health[4] = {"OK", "Error", "Warning", ""}; static const char * p_state[4] = {"Inactive", "Active", "", ""}; uint16_t cadence = ANT_SDM_CADENCE_RESCALE(p_page_data->cadence); -#endif // TRACE_SDM_PAGE_2_ENABLE - - LOG_PAGE2("Status: state: %s\n\r", - p_state[p_page_data->status.items.state]); - LOG_PAGE2(" health: %s\n\r", - p_health[p_page_data->status.items.health]); - LOG_PAGE2(" battery: %s\n\r", - p_battery[p_page_data->status.items.battery]); - LOG_PAGE2(" location: %s\n\r", - p_location[p_page_data->status.items.location]); - LOG_PAGE2("Cadence %u.%01u strides/min\n\r", + + NRF_LOG_INFO("Status:\r\n"); + NRF_LOG_INFO("state: %s\r\n", + (uint32_t)p_state[p_page_data->status.items.state]); + NRF_LOG_INFO("health: %s\r\n", + (uint32_t)p_health[p_page_data->status.items.health]); + NRF_LOG_INFO("battery: %s\r\n", + (uint32_t)p_battery[p_page_data->status.items.battery]); + NRF_LOG_INFO("location: %s\r\n", + (uint32_t)p_location[p_page_data->status.items.location]); + NRF_LOG_INFO("Cadence %u.%01u strides/min\r\n", cadence / ANT_SDM_CADENCE_DISP_PRECISION, cadence % ANT_SDM_CADENCE_DISP_PRECISION); } @@ -88,4 +127,4 @@ void ant_sdm_page_2_decode(uint8_t const * p_page_buffer, page_2_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h index 26f5bff..5a008fb 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_SDM_PAGE_2_H__ @@ -22,6 +50,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for SDM data page 2. */ typedef struct @@ -89,5 +121,10 @@ void ant_sdm_page_2_encode(uint8_t * p_page_buffer, void ant_sdm_page_2_decode(uint8_t const * p_page_buffer, ant_sdm_page2_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_PAGE_2_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c index 4aee44a..c59ef4f 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c @@ -1,19 +1,59 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + #include #include "ant_sdm_page_22.h" #include "ant_sdm_utils.h" -#include "ant_sdm_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM_PAGE_22" +#if ANT_SDM_PAGE_22_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_PAGE_22_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_PAGE_22_INFO_COLOR +#else // ANT_SDM_PAGE_22_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_PAGE_22_LOG_ENABLED +#include "nrf_log.h" + /**@brief SDM page 22 data layout structure. */ typedef struct @@ -28,38 +68,38 @@ typedef struct */ static void page_22_data_log(ant_sdm_page22_data_t const * p_page_data) { - LOG_PAGE22("Capabilities: "); + NRF_LOG_INFO("Capabilities: "); if (p_page_data->capabilities.items.time_is_valid) { - LOG_PAGE22(" time"); + NRF_LOG_RAW_INFO(" time"); } if (p_page_data->capabilities.items.distance_is_valid) { - LOG_PAGE22(" distance"); + NRF_LOG_RAW_INFO(" distance"); } if (p_page_data->capabilities.items.speed_is_valid) { - LOG_PAGE22(" speed"); + NRF_LOG_RAW_INFO(" speed"); } if (p_page_data->capabilities.items.latency_is_valid) { - LOG_PAGE22(" latency"); + NRF_LOG_RAW_INFO(" latency"); } if (p_page_data->capabilities.items.cadency_is_valid) { - LOG_PAGE22(" cadency"); + NRF_LOG_RAW_INFO(" cadence"); } if (p_page_data->capabilities.items.calorie_is_valid) { - LOG_PAGE22(" calorie"); + NRF_LOG_RAW_INFO(" calories"); } - LOG_PAGE22("\n\r"); + NRF_LOG_RAW_INFO("\r\n\n"); } @@ -86,4 +126,4 @@ void ant_sdm_page_22_decode(uint8_t const * p_page_buffer, page_22_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h index 9e0aaa4..961d63b 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_SDM_PAGE_22_H__ @@ -23,6 +51,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for SDM data page 22. */ typedef struct @@ -66,5 +98,10 @@ void ant_sdm_page_22_encode(uint8_t * p_page_buffer, void ant_sdm_page_22_decode(uint8_t const * p_page_buffer, ant_sdm_page22_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_PAGE_22_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c index 276b144..6f6a946 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c @@ -1,18 +1,58 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + #include "ant_sdm_page_3.h" #include "ant_sdm_utils.h" -#include "ant_sdm_page_logger.h" + +#define NRF_LOG_MODULE_NAME "ANT_SDM_PAGE_3" +#if ANT_SDM_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL ANT_SDM_PAGE_3_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ANT_SDM_PAGE_3_INFO_COLOR +#else // ANT_SDM_PAGE_3_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // ANT_SDM_PAGE_3_LOG_ENABLED +#include "nrf_log.h" + /**@brief SDM page 3 data layout structure. */ typedef struct @@ -24,7 +64,7 @@ typedef struct static void page_3_data_log(ant_sdm_page3_data_t const * p_page_data) { - LOG_PAGE3("Calories: %u\n\r", p_page_data->calories); + NRF_LOG_INFO("Calories: %u\r\n\n", p_page_data->calories); } @@ -44,9 +84,11 @@ void ant_sdm_page_3_decode(uint8_t const * p_page_buffer, ant_sdm_page3_data_layout_t const * p_incoming_data = (ant_sdm_page3_data_layout_t *)p_page_buffer; - p_page_data->calories = p_incoming_data->calories; + uint8_t prev_calories = (uint8_t) p_page_data->calories; + + p_page_data->calories += ((p_incoming_data->calories - prev_calories) & UINT8_MAX); page_3_data_log(p_page_data); } - +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h index 658987d..a022769 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_SDM_PAGE_3_H__ @@ -22,11 +50,15 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Data structure for SDM data page 3. */ typedef struct { - uint8_t calories; ///< Calories. + uint32_t calories; ///< Calories. } ant_sdm_page3_data_t; /**@brief Initialize page 3. @@ -53,5 +85,10 @@ void ant_sdm_page_3_encode(uint8_t * p_page_buffer, void ant_sdm_page_3_decode(uint8_t const * p_page_buffer, ant_sdm_page3_data_t * p_page_data); + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_PAGE_3_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h index eba992a..f02dcd6 100644 --- a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h +++ b/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 __ANT_SDM_PAGES_H @@ -17,8 +45,8 @@ * * @defgroup ant_sdk_profiles_sdm_pages Stride Based Speed and Distance Monitor profile pages * @{ - * @ingroup ant_sdk_profiles_sdm - * @brief This module implements functions for the SDM data pages. + * @ingroup ant_sdm + * @brief This module implements functions for the SDM data pages. */ #include "ant_sdm_page_1.h" @@ -30,5 +58,14 @@ #include "ant_common_page_70.h" #include "ant_common_page_80.h" #include "ant_common_page_81.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + #endif // __ANT_SDM_PAGES_H /** @} */ diff --git a/components/ant/ant_profiles/ant_sdm/pages/logger/ant_sdm_page_logger.h b/components/ant/ant_profiles/ant_sdm/pages/logger/ant_sdm_page_logger.h deleted file mode 100644 index 898f7a4..0000000 --- a/components/ant/ant_profiles/ant_sdm/pages/logger/ant_sdm_page_logger.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 ANT_SDM_PAGE_LOGGER_H__ -#define ANT_SDM_PAGE_LOGGER_H__ - -#ifdef TRACE_SDM_GENERAL_ENABLE -#include "app_trace.h" -#define LOG_SDM app_trace_log -#else -#define LOG_SDM(...) -#endif // TRACE_SDM_GENERAL_ENABLE - -#ifdef TRACE_SDM_PAGE_1_ENABLE -#include "app_trace.h" -#define LOG_PAGE1 app_trace_log -#else -#define LOG_PAGE1(...) -#endif // TRACE_SDM_PAGE_1_ENABLE - -#ifdef TRACE_SDM_PAGE_2_ENABLE -#include "app_trace.h" -#define LOG_PAGE2 app_trace_log -#else -#define LOG_PAGE2(...) -#endif // TRACE_SDM_PAGE_2_ENABLE - -#ifdef TRACE_SDM_PAGE_3_ENABLE -#include "app_trace.h" -#define LOG_PAGE3 app_trace_log -#else -#define LOG_PAGE3(...) -#endif // TRACE_SDM_PAGE_3_ENABLE - -#ifdef TRACE_SDM_PAGE_16_ENABLE -#include "app_trace.h" -#define LOG_PAGE16 app_trace_log -#else -#define LOG_PAGE16(...) -#endif // TRACE_SDM_PAGE_16_ENABLE - -#ifdef TRACE_SDM_PAGE_22_ENABLE -#include "app_trace.h" -#define LOG_PAGE22 app_trace_log -#else -#define LOG_PAGE22(...) -#endif // TRACE_SDM_PAGE_22_ENABLE - -#if (defined TRACE_SDM_PAGE_2_ENABLE) || (defined TRACE_SDM_PAGE_3_ENABLE) -#include "app_trace.h" -#define LOG_SPEED app_trace_log -#else -#define LOG_SPEED(...) -#endif // (defined TRACE_SDM_PAGE_2_ENABLE) || (defined TRACE_SDM_PAGE_3_ENABLE) - -#endif // ANT_SDM_PAGE_LOGGER_H__ diff --git a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c b/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c index 37c98d9..de23ad8 100644 --- a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c +++ b/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c @@ -1,18 +1,48 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SDM) + #include "ant_sdm_simulator.h" #include "ant_sdm_utils.h" -#include "nordic_common.h" #define SIMULATOR_STRIDE_LENGTH_UNIT_REVERSAL 100 ///< Stride length unit is cm. #define SIMULATOR_BURN_RATE_UNIT 1000 ///< Burn rate uinit is kcal per km. @@ -85,7 +115,7 @@ void ant_sdm_simulator_one_iteration(ant_sdm_simulator_t * p_simulator) if (p_simulator->p_profile->SDM_PROFILE_capabilities.calorie_is_valid) { p_simulator->p_profile->SDM_PROFILE_calories = value_rescale(distance, - SIMULATOR_BURN_RATE_UNIT + SIMULATOR_BURN_RATE_UNIT * ANT_SDM_DISTANCE_UNIT_REVERSAL, p_simulator->_cb.burn_rate); } @@ -127,4 +157,4 @@ void ant_sdm_simulator_decrement(ant_sdm_simulator_t * p_simulator) } } - +#endif // NRF_MODULE_ENABLED(ANT_SDM) diff --git a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h b/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h index 5d95e13..626598b 100644 --- a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h +++ b/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_SDM_SIMULATOR_H__ @@ -29,12 +57,15 @@ #include #include -#include "bsp.h" #include "ant_sdm.h" #include "ant_sdm_utils.h" #include "sensorsim.h" #include "ant_sdm_simulator_local.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief SDM simulator configuration structure. */ typedef struct { @@ -100,5 +131,10 @@ void ant_sdm_simulator_increment(ant_sdm_simulator_t * p_simulator); */ void ant_sdm_simulator_decrement(ant_sdm_simulator_t * p_simulator); + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_SIMULATOR_H__ /** @} */ diff --git a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h b/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h index 6b6d8c3..2ccbd36 100644 --- a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h +++ b/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_SDM_SIMULATOR_LOCAL_H__ @@ -15,10 +43,13 @@ #include #include -#include "bsp.h" #include "ant_sdm.h" #include "sensorsim.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @ingroup ant_sdk_sdm_simulator * @brief SDM simulator control block structure. */ @@ -33,4 +64,9 @@ typedef struct sensorsim_cfg_t sensorsim_cfg; ///< Configuration of the simulated sensor. }ant_sdm_simulator_cb_t; + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_SIMULATOR_LOCAL_H__ diff --git a/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h b/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h index be14b64..870835a 100644 --- a/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h +++ b/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h @@ -1,27 +1,58 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_SDM_UTILS_H__ #define ANT_SDM_UTILS_H__ -#include "app_util.h" #include "nrf_assert.h" #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @file * * @defgroup ant_sdk_profiles_sdm_utils Stride Based Speed and Distance Monitor profile utilities * @{ - * @ingroup ant_sdk_profiles_sdm + * @ingroup ant_sdm * @brief This module implements utilities for the Stride Based Speed and Distance Monitor profile. * */ @@ -73,5 +104,10 @@ /** @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_SDM_UTILS_H__ diff --git a/components/ant/ant_search_config/ant_search_config.c b/components/ant/ant_search_config/ant_search_config.c index ecf583c..042e811 100644 --- a/components/ant/ant_search_config/ant_search_config.c +++ b/components/ant/ant_search_config/ant_search_config.c @@ -1,18 +1,48 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_SEARCH_CONFIG) + #include "ant_search_config.h" #include "ant_interface.h" -#include "nrf_error.h" uint32_t ant_search_init(ant_search_config_t const * p_config) { @@ -26,33 +56,23 @@ uint32_t ant_search_init(ant_search_config_t const * p_config) err_code = sd_ant_search_channel_priority_set(p_config->channel_number, p_config->search_priority); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); err_code = sd_ant_search_waveform_set(p_config->channel_number, p_config->waveform); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); err_code = sd_ant_channel_rx_search_timeout_set(p_config->channel_number, p_config->high_priority_timeout); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); err_code = sd_ant_channel_low_priority_rx_search_timeout_set(p_config->channel_number, p_config->low_priority_timeout); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); err_code = sd_ant_active_search_sharing_cycles_set(p_config->channel_number, p_config->search_sharing_cycles); return err_code; } + +#endif // NRF_MODULE_ENABLED(ANT_SEARCH_CONFIG) diff --git a/components/ant/ant_search_config/ant_search_config.h b/components/ant/ant_search_config/ant_search_config.h index a830609..4dd2cf7 100644 --- a/components/ant/ant_search_config/ant_search_config.h +++ b/components/ant/ant_search_config/ant_search_config.h @@ -1,9 +1,48 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_SEARCH_CONFIG_H__ #define ANT_SEARCH_CONFIG_H__ /** @file * - * @defgroup ant_sdk_search_config ANT search configuration + * @defgroup ant_search_config ANT search configuration * @{ * @ingroup ant_sdk_utils * @brief ANT channel search configuration module. @@ -11,16 +50,19 @@ #include #include "ant_parameters.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif #define ANT_SEARCH_SHARING_CYCLES_DISABLE 0x00 ///< Disable search sharing. #define ANT_LOW_PRIORITY_SEARCH_DISABLE 0x00 ///< Disable low priority search. #define ANT_LOW_PRIORITY_TIMEOUT_DISABLE 0xFF ///< Disable low priority search time-out. -#define ANT_DEFAULT_LOW_PRIORITY_TIMEOUT 0x02 ///< Default low priority search time-out. #define ANT_HIGH_PRIORITY_SEARCH_DISABLE 0x00 ///< Disable high priority search. #define ANT_HIGH_PRIORITY_TIMEOUT_DISABLE 0xFF ///< Disable high priority search time-out. -#define ANT_DEFAULT_HIGH_PRIORITY_TIMEOUT 0x0A ///< Default high priority search time-out. /**@brief Search priority. */ typedef enum @@ -78,5 +120,10 @@ typedef struct */ uint32_t ant_search_init(ant_search_config_t const * p_config); + +#ifdef __cplusplus +} +#endif + #endif // ANT_SEARCH_CONFIG_H__ /** @} */ diff --git a/components/ant/ant_stack_config/ant_stack_config.c b/components/ant/ant_stack_config/ant_stack_config.c index 71abf59..29af15b 100644 --- a/components/ant/ant_stack_config/ant_stack_config.c +++ b/components/ant/ant_stack_config/ant_stack_config.c @@ -1,29 +1,54 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_STACK_CONFIG) #include "nrf_assert.h" #include "ant_stack_config.h" #include "ant_interface.h" #include "ant_parameters.h" -// The header below should be provided by a project. -// At least ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED and ANT_CONFIG_ENCRYPTED_CHANNELS must be defined. -#include "ant_stack_config_defs.h" - -#ifndef ANT_CONFIG_BURST_QUEUE_SIZE - #define ANT_CONFIG_BURST_QUEUE_SIZE 128 // legacy tx burst buffer queue size 128 B -#endif - -#define ANT_BUFFER_SIZE_FOR_SD ANT_ENABLE_GET_REQUIRED_SPACE(ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED, ANT_CONFIG_ENCRYPTED_CHANNELS, ANT_CONFIG_BURST_QUEUE_SIZE) +#define ANT_BUFFER_SIZE_FOR_SD ANT_ENABLE_GET_REQUIRED_SPACE(ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED, \ + ANT_CONFIG_ENCRYPTED_CHANNELS, \ + ANT_CONFIG_BURST_QUEUE_SIZE, \ + ANT_CONFIG_EVENT_QUEUE_SIZE) static union { @@ -40,9 +65,12 @@ uint32_t ant_stack_static_config(void) { .ucTotalNumberOfChannels = ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED, .ucNumberOfEncryptedChannels = ANT_CONFIG_ENCRYPTED_CHANNELS, + .usNumberOfEvents = ANT_CONFIG_EVENT_QUEUE_SIZE, .pucMemoryBlockStartLocation = ant_stack_buffer.u8, .usMemoryBlockByteSize = ANT_BUFFER_SIZE_FOR_SD }; return sd_ant_enable(&m_ant_enable_cfg); } + +#endif // NRF_MODULE_ENABLED(ANT_STACK_CONFIG) diff --git a/components/ant/ant_stack_config/ant_stack_config.h b/components/ant/ant_stack_config/ant_stack_config.h index 8abdecb..24d7bc2 100644 --- a/components/ant/ant_stack_config/ant_stack_config.h +++ b/components/ant/ant_stack_config/ant_stack_config.h @@ -1,20 +1,52 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_STACK_CONFIG_H__ #define ANT_STACK_CONFIG_H__ #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @file */ @@ -24,14 +56,14 @@ * @{ * @ingroup ant_sdk_utils * @brief Configuration of resources used in the ANT stack. - * + * * This module initializes the stack according to the configuration of the ANT channels. */ /** * @brief Function for configuring and enabling the ANT stack. - * @details The function sets the channel configuration for the stack using the parameters provided - * in the ant_stack_config_defs.h file. It also assigns a correspondingly large buffer + * @details The function sets the channel configuration for the stack using the parameters provided + * in the sdk_config.h file. It also assigns a correspondingly large buffer * as static resource. * * @return A SoftDevice error code. @@ -42,4 +74,9 @@ uint32_t ant_stack_static_config(void); * @} */ + +#ifdef __cplusplus +} +#endif + #endif // ANT_STACK_CONFIG_H__ diff --git a/components/ant/ant_stack_config/config/ant_stack_config_defs.h b/components/ant/ant_stack_config/config/ant_stack_config_defs.h index d36578e..425f01e 100644 --- a/components/ant/ant_stack_config/config/ant_stack_config_defs.h +++ b/components/ant/ant_stack_config/config/ant_stack_config_defs.h @@ -1,20 +1,58 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANT_STACK_CONFIG_DEFS_H__ #define ANT_STACK_CONFIG_DEFS_H__ +#ifdef __cplusplus +extern "C" { +#endif + #define ANT_CONFIG_TOTAL_CHANNELS_ALLOCATED 0 #define ANT_CONFIG_ENCRYPTED_CHANNELS 0 #define ANT_CONFIG_BURST_QUEUE_SIZE 128 +#define ANT_CONFIG_EVENT_QUEUE_SIZE 32 + + +#ifdef __cplusplus +} +#endif #endif // ANT_STACK_CONFIG_DEFS_H__ diff --git a/components/ant/ant_state_indicator/ant_state_indicator.c b/components/ant/ant_state_indicator/ant_state_indicator.c index 3499737..5c4db39 100644 --- a/components/ant/ant_state_indicator/ant_state_indicator.c +++ b/components/ant/ant_state_indicator/ant_state_indicator.c @@ -1,15 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ANT_STATE_INDICATOR) #include "ant_parameters.h" #include "bsp.h" #include "ant_state_indicator.h" @@ -45,11 +75,11 @@ uint32_t ant_state_indicator_channel_opened(void) case CHANNEL_TYPE_SLAVE: err_code = bsp_indication_set(BSP_INDICATE_SCANNING); break; - + case CHANNEL_TYPE_SLAVE_RX_ONLY: err_code = bsp_indication_set(BSP_INDICATE_SCANNING); break; - + case CHANNEL_TYPE_MASTER: err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); break; @@ -88,7 +118,7 @@ void ant_state_indicator_evt_handler(ant_evt_t * p_ant_evt) err_code = bsp_indication_set(BSP_INDICATE_IDLE); ant_state_indicator_sleep_mode_enter(); break; - + case EVENT_RX_SEARCH_TIMEOUT: err_code = bsp_indication_set(BSP_INDICATE_IDLE); break; @@ -127,3 +157,5 @@ void ant_state_indicator_sleep_mode_enter(void) /** *@} */ + +#endif // NRF_MODULE_ENABLED(ANT_STATE_INDICATOR) diff --git a/components/ant/ant_state_indicator/ant_state_indicator.h b/components/ant/ant_state_indicator/ant_state_indicator.h index d991a1b..7fb9451 100644 --- a/components/ant/ant_state_indicator/ant_state_indicator.h +++ b/components/ant/ant_state_indicator/ant_state_indicator.h @@ -1,9 +1,48 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 __ANT_STATE_INDICATOR_H #define __ANT_STATE_INDICATOR_H /** @file * - * @defgroup ant_sdk_state_indicator ANT channel state indicator + * @defgroup ant_state_indicator ANT channel state indicator * @{ * @ingroup ant_sdk_utils * @brief ANT channel state indicator module. @@ -14,6 +53,10 @@ #include #include "ant_stack_handler_types.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Function for initializing the ANT channel state indicator. @@ -61,5 +104,10 @@ uint32_t ant_state_indicator_channel_opened(void); void ant_state_indicator_sleep_mode_enter(void); + +#ifdef __cplusplus +} +#endif + #endif /** @} */ diff --git a/components/ble/ble_advertising/ble_advertising.c b/components/ble/ble_advertising/ble_advertising.c index 1760166..8de7954 100644 --- a/components/ble/ble_advertising/ble_advertising.c +++ b/components/ble/ble_advertising/ble_advertising.c @@ -1,144 +1,438 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_ADVERTISING) #include "ble_advdata.h" #include "ble_advertising.h" #include "nrf_soc.h" -#include "app_trace.h" -#include "nordic_common.h" -#include "pstorage.h" +#include "nrf_log.h" +#include "fstorage.h" +#include "sdk_errors.h" + + +// Total number of possible advertising modes. +#define BLE_ADV_MODES (5) + + +static bool m_initialized; +static bool m_advertising_start_pending; /**< Flag to keep track of ongoing operations in flash. */ + +static ble_adv_evt_t m_adv_evt; /**< Advertising event propogated to the main application. The event is either a transaction to a new advertising mode, or a request for whitelist or peer address. */ + +static ble_adv_mode_t m_adv_mode_current; /**< Variable to keep track of the current advertising mode. */ +static ble_adv_modes_config_t m_adv_modes_config; /**< Struct to keep track of disabled and enabled advertising modes, as well as time-outs and intervals.*/ + +static ble_gap_addr_t m_peer_address; /**< Address of the most recently connected peer, used for direct advertising. */ +static bool m_peer_addr_reply_expected; /**< Flag to verify that peer address is only set when requested. */ + +static ble_advdata_t m_advdata; /**< Used by the initialization function to set name, appearance, and UUIDs and advertising flags visible to peer devices. */ +static ble_advdata_manuf_data_t m_manuf_specific_data; /**< Manufacturer specific data structure*/ +static uint8_t m_manuf_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the Manufacturer specific data*/ +static ble_advdata_service_data_t m_service_data; /**< Service data structure. */ +static uint8_t m_service_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the service data. */ +static ble_advdata_conn_int_t m_slave_conn_int; /**< Connection interval range structure.*/ +static uint16_t m_current_slave_link_conn_handle; /**< Connection handle for the active link. */ + +static ble_advertising_evt_handler_t m_evt_handler; /**< Handler for the advertising events. Can be initialized as NULL if no handling is implemented on in the main application. */ +static ble_advertising_error_handler_t m_error_handler; /**< Handler for the advertising error events. */ + +static bool m_whitelist_temporarily_disabled; /**< Flag to keep track of temporary disabling of the whitelist. */ +static bool m_whitelist_reply_expected; + +#if (NRF_SD_BLE_API_VERSION == 2) + + // For SoftDevices v 2.x, this module caches a whitelist which is retrieved from the + // application using an event, and which is passed as a parameter when calling + // sd_ble_gap_adv_start(). + + static ble_gap_addr_t * m_p_whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + static ble_gap_irk_t * m_p_whitelist_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; + static ble_gap_addr_t m_whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + static ble_gap_irk_t m_whitelist_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; + static ble_gap_whitelist_t m_whitelist = + { + .pp_addrs = m_p_whitelist_addrs, + .pp_irks = m_p_whitelist_irks + }; -#define LOG app_trace_log +#else -static bool m_advertising_start_pending = false; /**< Flag to keep track of ongoing operations on persistent memory. */ + // For SoftDevices v 3.x, this module does not need to cache a whitelist, but it needs to + // be aware of whether or not a whitelist has been set (e.g. using the Peer Manager) + // in order to start advertising with the proper advertising params (filter policy). -static ble_gap_addr_t m_peer_address; /**< Address of the most recently connected peer, used for direct advertising. */ -static ble_advdata_t m_advdata; /**< Used by the initialization function to set name, appearance, and UUIDs and advertising flags visible to peer devices. */ -static ble_adv_evt_t m_adv_evt; /**< Advertising event propogated to the main application. The event is either a transaction to a new advertising mode, or a request for whitelist or peer address.. */ -static ble_advertising_evt_handler_t m_evt_handler; /**< Handler for the advertising events. Can be initialized as NULL if no handling is implemented on in the main application. */ -static ble_advertising_error_handler_t m_error_handler; /**< Handler for the advertising error events. */ + static bool m_whitelist_in_use; -static ble_adv_mode_t m_adv_mode_current; /**< Variable to keep track of the current advertising mode. */ -static ble_adv_modes_config_t m_adv_modes_config; /**< Struct to keep track of disabled and enabled advertising modes, as well as time-outs and intervals.*/ +#endif -static ble_gap_whitelist_t m_whitelist; /**< Struct that points to whitelisted addresses. */ -static ble_gap_addr_t * mp_whitelist_addr[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; /**< Pointer to a list of addresses. Pointed to by the whitelist */ -static ble_gap_irk_t * mp_whitelist_irk[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; /**< Pointer to a list of Identity Resolving Keys (IRK). Pointed to by the whitelist */ -static bool m_whitelist_temporarily_disabled = false; /**< Flag to keep track of temporary disabling of the whitelist. */ -static bool m_whitelist_reply_expected = false; /**< Flag to verify that whitelist is only set when it is requested. */ -static bool m_peer_addr_reply_expected = false; /**< Flag to verify that peer address is only set when requested. */ -static ble_advdata_manuf_data_t m_manuf_specific_data; /**< Manufacturer specific data structure*/ -static uint8_t m_manuf_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the Manufacturer specific data*/ -static ble_advdata_service_data_t m_service_data; /**< Service data structure. */ -static uint8_t m_service_data_array[BLE_GAP_ADV_MAX_SIZE]; /**< Array to store the service data. */ -static ble_advdata_conn_int_t m_slave_conn_int; /**< Connection interval range structure.*/ -static int8_t m_tx_power_level; /**< TX power level*/ +#if (NRF_SD_BLE_API_VERSION == 2) + static bool whitelist_has_entries() + { + return ((m_whitelist.addr_count != 0) || (m_whitelist.irk_count != 0)); + } -/**@brief Function for checking that the whitelist has entries. +#else + + static bool whitelist_has_entries() + { + return m_whitelist_in_use; + } + +#endif + + + +/**@brief Function for checking if an address is valid. */ -static bool whitelist_has_entries(ble_gap_whitelist_t const * whitelist) +static bool addr_is_valid(uint8_t const * const addr) { - if ((whitelist->addr_count != 0) || (whitelist->irk_count != 0)) + for (uint32_t i = 0; i < BLE_GAP_ADDR_LEN; i++) { - return true; + if (addr[i] != 0) + { + return true; + } } return false; } -/**@brief Function for setting the stored peer address back to zero. +static ble_adv_mode_t adv_mode_next_get(ble_adv_mode_t adv_mode) +{ + return (ble_adv_mode_t)((adv_mode + 1) % BLE_ADV_MODES); +} + + +/**@brief Function for handling the Connected event. + * + * @param[in] p_ble_evt Event received from the BLE stack. */ -static void ble_advertising_peer_address_clear() +static void on_connected(ble_evt_t const * p_ble_evt) { - memset(&m_peer_address, 0, sizeof(m_peer_address)); + if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH) + { + m_current_slave_link_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + } } -/**@brief Function for checking if an address is non-zero. Used to determine if +/**@brief Function for handling the Disconnected event. + * + * @param[in] p_ble_evt Event received from the BLE stack. */ -static bool peer_address_exists(uint8_t const * address) +static void on_disconnected(ble_evt_t const * p_ble_evt) { - uint32_t i; + uint32_t ret; - for (i = 0; i < BLE_GAP_ADDR_LEN; i++) + m_whitelist_temporarily_disabled = false; + + if (p_ble_evt->evt.gap_evt.conn_handle == m_current_slave_link_conn_handle) { - if (address[i] != 0) + ret = ble_advertising_start(BLE_ADV_MODE_DIRECTED); + if ((ret != NRF_SUCCESS) && (m_error_handler != NULL)) + { + m_error_handler(ret); + } + } +} + + +/**@brief Function for handling the Timeout event. + * + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_timeout(ble_evt_t const * p_ble_evt) +{ + ret_code_t ret; + + if (p_ble_evt->evt.gap_evt.params.timeout.src != BLE_GAP_TIMEOUT_SRC_ADVERTISING) + { + // Nothing to do. + return; + } + + // Start advertising in the next mode. + ret = ble_advertising_start(adv_mode_next_get(m_adv_mode_current)); + + if ((ret != NRF_SUCCESS) && (m_error_handler != NULL)) + { + m_error_handler(ret); + } +} + + +/** @brief Function to determine if a flash write operation in in progress. + * + * @return true if a flash operation is in progress, false if not. + */ +static bool flash_access_in_progress() +{ + uint32_t count; + + (void)fs_queued_op_count_get(&count); + + return (count != 0); +} + + +/**@brief Get the next available advertising mode. + * + * @param[in] adv_mode Requested advertising mode. + * + * @returns adv_mode if possible, or the best available mode if not. + */ +static ble_adv_mode_t adv_mode_next_avail_get(ble_adv_mode_t adv_mode) +{ + bool peer_addr_is_valid = addr_is_valid(m_peer_address.addr); + + // If a mode is disabled, continue to the next mode. + + switch (adv_mode) + { + case BLE_ADV_MODE_DIRECTED: + if ((m_adv_modes_config.ble_adv_directed_enabled) && peer_addr_is_valid) + { + return BLE_ADV_MODE_DIRECTED; + } + // Fallthrough. + + case BLE_ADV_MODE_DIRECTED_SLOW: + if ((m_adv_modes_config.ble_adv_directed_slow_enabled) && peer_addr_is_valid) + { + return BLE_ADV_MODE_DIRECTED_SLOW; + } + // Fallthrough. + + case BLE_ADV_MODE_FAST: + if (m_adv_modes_config.ble_adv_fast_enabled) + { + return BLE_ADV_MODE_FAST; + } + // Fallthrough. + + case BLE_ADV_MODE_SLOW: + if (m_adv_modes_config.ble_adv_slow_enabled) + { + return BLE_ADV_MODE_SLOW; + } + // Fallthrough. + + default: + return BLE_ADV_MODE_IDLE; + } +} + + +/**@brief Function for starting directed advertising. + * + * @param[out] p_adv_params Advertising parameters. + * + * @return NRF_SUCCESS + */ +static ret_code_t set_adv_mode_directed(ble_gap_adv_params_t * p_adv_params) +{ + m_adv_evt = BLE_ADV_EVT_DIRECTED; + + p_adv_params->p_peer_addr = &m_peer_address; + p_adv_params->type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND; + p_adv_params->timeout = 0; + p_adv_params->interval = 0; + + return NRF_SUCCESS; +} + + +/**@brief Function for starting directed slow advertising. + * + * @param[out] p_adv_params Advertising parameters. + * + * @return NRF_SUCCESS + */ +static ret_code_t set_adv_mode_directed_slow(ble_gap_adv_params_t * p_adv_params) +{ + m_adv_evt = BLE_ADV_EVT_DIRECTED_SLOW; + + p_adv_params->p_peer_addr = &m_peer_address; + p_adv_params->type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND; + p_adv_params->timeout = m_adv_modes_config.ble_adv_directed_slow_timeout; + p_adv_params->interval = m_adv_modes_config.ble_adv_directed_slow_interval; + + return NRF_SUCCESS; +} + + +/**@brief Function for starting fast advertising. + * + * @param[out] p_adv_params Advertising parameters. + * + * @return NRF_SUCCESS or an error from @ref ble_advdata_set(). + */ +static ret_code_t set_adv_mode_fast(ble_gap_adv_params_t * p_adv_params) +{ + ret_code_t ret; + + p_adv_params->interval = m_adv_modes_config.ble_adv_fast_interval; + p_adv_params->timeout = m_adv_modes_config.ble_adv_fast_timeout; + + if ((m_adv_modes_config.ble_adv_whitelist_enabled) && + (!m_whitelist_temporarily_disabled) && + (whitelist_has_entries())) + { + #if (NRF_SD_BLE_API_VERSION == 2) + p_adv_params->p_whitelist = &m_whitelist; + #endif + + p_adv_params->fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; + m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; + + ret = ble_advdata_set(&m_advdata, NULL); + if (ret != NRF_SUCCESS) { - return true; + return ret; } + + m_adv_evt = BLE_ADV_EVT_FAST_WHITELIST; } - return false; + else + { + m_adv_evt = BLE_ADV_EVT_FAST; + } + + return NRF_SUCCESS; } -uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, - ble_advdata_t const * p_srdata, - ble_adv_modes_config_t const * p_config, - ble_advertising_evt_handler_t const evt_handler, - ble_advertising_error_handler_t const error_handler) +/**@brief Function for starting slow advertising. + * + * @param[out] p_adv_params Advertising parameters. + * + * @return NRF_SUCCESS or an error from @ref ble_advdata_set(). + */ +static ret_code_t set_adv_mode_slow(ble_gap_adv_params_t * p_adv_params) { - uint32_t err_code; + ret_code_t ret; + + p_adv_params->interval = m_adv_modes_config.ble_adv_slow_interval; + p_adv_params->timeout = m_adv_modes_config.ble_adv_slow_timeout; - if((p_advdata == NULL) || p_config == NULL) + if ((m_adv_modes_config.ble_adv_whitelist_enabled) && + (!m_whitelist_temporarily_disabled) && + (whitelist_has_entries())) { - return NRF_ERROR_NULL; + #if (NRF_SD_BLE_API_VERSION == 2) + { + p_adv_params->p_whitelist = &m_whitelist; + } + #endif + + p_adv_params->fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; + m_advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; + + ret = ble_advdata_set(&m_advdata, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + m_adv_evt = BLE_ADV_EVT_SLOW_WHITELIST; } - m_adv_mode_current = BLE_ADV_MODE_IDLE; - m_evt_handler = evt_handler; - m_error_handler = error_handler; - m_adv_modes_config = *p_config; + else + { + m_adv_evt = BLE_ADV_EVT_SLOW; + } + + return NRF_SUCCESS; +} - ble_advertising_peer_address_clear(); - // Prepare Whitelist. Address and IRK double pointers point to allocated arrays. - m_whitelist.pp_addrs = mp_whitelist_addr; - m_whitelist.pp_irks = mp_whitelist_irk; +uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, + ble_advdata_t const * p_srdata, + ble_adv_modes_config_t const * p_config, + ble_advertising_evt_handler_t const evt_handler, + ble_advertising_error_handler_t const error_handler) +{ + uint32_t ret; - // Copy and set advertising data. - memset(&m_advdata, 0, sizeof(m_advdata)); + if ((p_advdata == NULL) || (p_config == NULL)) + { + return NRF_ERROR_NULL; + } + + m_initialized = true; + m_adv_mode_current = BLE_ADV_MODE_IDLE; + m_adv_modes_config = *p_config; + m_evt_handler = evt_handler; + m_error_handler = error_handler; + m_current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID; + + memset(&m_peer_address, 0, sizeof(m_peer_address)); + memset(&m_advdata, 0, sizeof(m_advdata)); // Copy advertising data. m_advdata.name_type = p_advdata->name_type; m_advdata.include_appearance = p_advdata->include_appearance; m_advdata.flags = p_advdata->flags; m_advdata.short_name_len = p_advdata->short_name_len; - /* - if(p_advdata->uuids_complete != NULL) - { - m_advdata.uuids_complete = p_advdata->uuids_complete; - } - */ + m_advdata.uuids_complete = p_advdata->uuids_complete; m_advdata.uuids_more_available = p_advdata->uuids_more_available; m_advdata.uuids_solicited = p_advdata->uuids_solicited; - - if(p_advdata->p_manuf_specific_data != NULL) + + if (p_advdata->p_manuf_specific_data != NULL) { m_advdata.p_manuf_specific_data = &m_manuf_specific_data; m_manuf_specific_data.data.p_data = m_manuf_data_array; m_advdata.p_manuf_specific_data->company_identifier = p_advdata->p_manuf_specific_data->company_identifier; m_advdata.p_manuf_specific_data->data.size = p_advdata->p_manuf_specific_data->data.size; - - for(uint32_t i = 0; i < m_advdata.p_manuf_specific_data->data.size; i++) + + for (uint32_t i = 0; i < m_advdata.p_manuf_specific_data->data.size; i++) { m_manuf_data_array[i] = p_advdata->p_manuf_specific_data->data.p_data[i]; } } - - if(p_advdata->p_service_data_array != NULL) + + if (p_advdata->p_service_data_array != NULL) { m_service_data.data.p_data = m_service_data_array; m_advdata.p_service_data_array = &m_service_data; @@ -146,7 +440,7 @@ uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, m_advdata.p_service_data_array->data.size = p_advdata->p_service_data_array->data.size; m_advdata.p_service_data_array->service_uuid = p_advdata->p_service_data_array->service_uuid; - for(uint32_t i = 0; i < m_advdata.p_service_data_array->data.size; i++) + for (uint32_t i = 0; i < m_advdata.p_service_data_array->data.size; i++) { m_service_data_array[i] = p_advdata->p_service_data_array->data.p_data[i]; } @@ -154,58 +448,60 @@ uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, m_advdata.service_data_count = p_advdata->service_data_count; } - - if(p_advdata->p_slave_conn_int != NULL) + if (p_advdata->p_slave_conn_int != NULL) { m_advdata.p_slave_conn_int = &m_slave_conn_int; m_advdata.p_slave_conn_int->max_conn_interval = p_advdata->p_slave_conn_int->max_conn_interval; m_advdata.p_slave_conn_int->min_conn_interval = p_advdata->p_slave_conn_int->min_conn_interval; } - - if(p_advdata->p_tx_power_level != NULL) + + if (p_advdata->p_tx_power_level != NULL) { - m_advdata.p_tx_power_level = &m_tx_power_level; - m_advdata.p_tx_power_level = p_advdata->p_tx_power_level; + m_advdata.p_tx_power_level = p_advdata->p_tx_power_level; } - err_code = ble_advdata_set(&m_advdata, p_srdata); - return err_code; + +#if (NRF_SD_BLE_API_VERSION == 2) + for (int i = 0; i header.evt_id) { case BLE_GAP_EVT_CONNECTED: -#if (defined(S130) || defined(S132)) - if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH) - { - current_slave_link_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; - } -#else - current_slave_link_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; -#endif + on_connected(p_ble_evt); break; // Upon disconnection, whitelist will be activated and direct advertising is started. case BLE_GAP_EVT_DISCONNECTED: - { - uint32_t err_code; - m_whitelist_temporarily_disabled = false; - - if (p_ble_evt->evt.gap_evt.conn_handle == current_slave_link_conn_handle) - { - err_code = ble_advertising_start(BLE_ADV_MODE_DIRECTED); - if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL)) - { - m_error_handler(err_code); - } - } + on_disconnected(p_ble_evt); break; - } - // Upon time-out, the next advertising mode is started, i.e. go from fast to slow or from slow to idle. + + // Upon time-out, the next advertising mode is started. case BLE_GAP_EVT_TIMEOUT: - if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) - { - switch (m_adv_mode_current) - { - case BLE_ADV_MODE_DIRECTED: - LOG("[ADV]: Timed out from directed advertising.\r\n"); - { - uint32_t err_code; - err_code = ble_advertising_start(BLE_ADV_MODE_DIRECTED_SLOW); - if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL)) - { - m_error_handler(err_code); - } - } - break; - case BLE_ADV_MODE_DIRECTED_SLOW: - LOG("[ADV]: Timed out from directed slow advertising.\r\n"); - { - uint32_t err_code; - err_code = ble_advertising_start(BLE_ADV_MODE_FAST); - if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL)) - { - m_error_handler(err_code); - } - } - break; - case BLE_ADV_MODE_FAST: - { - uint32_t err_code; - m_adv_evt = BLE_ADV_EVT_FAST; - LOG("[ADV]: Timed out from fast advertising, starting slow advertising.\r\n"); - err_code = ble_advertising_start(BLE_ADV_MODE_SLOW); - if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL)) - { - m_error_handler(err_code); - } - break; - } - case BLE_ADV_MODE_SLOW: - m_adv_evt = BLE_ADV_EVT_IDLE; - LOG("[ADV]: Timed out from slow advertising, stopping advertising.\r\n"); - if (m_evt_handler != NULL) - { - m_evt_handler(m_adv_evt); - } - break; - - default: - // No implementation needed. - break; - } - } + on_timeout(p_ble_evt); break; default: - // No implementation needed. break; } } + + void ble_advertising_on_sys_evt(uint32_t sys_evt) { - uint32_t err_code = NRF_SUCCESS; + uint32_t ret; + switch (sys_evt) { - + //When a flash operation finishes, re-attempt to start advertising operations. case NRF_EVT_FLASH_OPERATION_SUCCESS: - // Fall through. - - //When a flash operation finishes, advertising no longer needs to be pending. case NRF_EVT_FLASH_OPERATION_ERROR: if (m_advertising_start_pending) { m_advertising_start_pending = false; - err_code = ble_advertising_start(m_adv_mode_current); - if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL)) + ret = ble_advertising_start(m_adv_mode_current); + if ((ret != NRF_SUCCESS) && (m_error_handler != NULL)) { - m_error_handler(err_code); + m_error_handler(ret); } } break; @@ -478,76 +634,86 @@ void ble_advertising_on_sys_evt(uint32_t sys_evt) } } + uint32_t ble_advertising_peer_addr_reply(ble_gap_addr_t * p_peer_address) { - if(m_peer_addr_reply_expected == false) + if (!m_peer_addr_reply_expected) { return NRF_ERROR_INVALID_STATE; } - m_peer_address.addr_type = p_peer_address->addr_type; + m_peer_addr_reply_expected = false; - for (int i = 0; i < BLE_GAP_ADDR_LEN; i++) - { - m_peer_address.addr[i] = p_peer_address->addr[i]; - } + memcpy(&m_peer_address, p_peer_address, sizeof(m_peer_address)); - m_peer_addr_reply_expected = false; return NRF_SUCCESS; } -uint32_t ble_advertising_whitelist_reply(ble_gap_whitelist_t * p_whitelist) +uint32_t ble_advertising_whitelist_reply(ble_gap_addr_t const * p_gap_addrs, + uint32_t addr_cnt, + ble_gap_irk_t const * p_gap_irks, + uint32_t irk_cnt) { - uint32_t i; - - if(m_whitelist_reply_expected == false) + if (!m_whitelist_reply_expected) { return NRF_ERROR_INVALID_STATE; } - m_whitelist.addr_count = p_whitelist->addr_count; - m_whitelist.irk_count = p_whitelist->irk_count; + m_whitelist_reply_expected = false; - for (i = 0; i < m_whitelist.irk_count; i++) - { - mp_whitelist_irk[i] = p_whitelist->pp_irks[i]; - } + #if (NRF_SD_BLE_API_VERSION == 2) - for (i = 0; i < m_whitelist.addr_count; i++) - { - mp_whitelist_addr[i] = p_whitelist->pp_addrs[i]; - } + m_whitelist.addr_count = addr_cnt; + m_whitelist.irk_count = irk_cnt; + + for (uint32_t i = 0; i < addr_cnt; i++) + { + *m_whitelist.pp_addrs[i] = p_gap_addrs[i]; + } + + for (uint32_t i = 0; i < irk_cnt; i++) + { + *m_whitelist.pp_irks[i] = p_gap_irks[i]; + } + + #else + + m_whitelist_in_use = ((addr_cnt > 0) || (irk_cnt > 0)); + + #endif - m_whitelist_reply_expected = false; return NRF_SUCCESS; } uint32_t ble_advertising_restart_without_whitelist(void) { - uint32_t err_code; + uint32_t ret; + + (void) sd_ble_gap_adv_stop(); + + m_whitelist_temporarily_disabled = true; - if( m_adv_modes_config.ble_adv_whitelist_enabled == BLE_ADV_WHITELIST_ENABLED - && !m_whitelist_temporarily_disabled) + #if (NRF_SD_BLE_API_VERSION == 3) + m_whitelist_in_use = false; + #endif + + m_advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; + + ret = ble_advdata_set(&m_advdata, NULL); + if (ret != NRF_SUCCESS) { - if (m_adv_mode_current != BLE_ADV_MODE_IDLE) - { - err_code = sd_ble_gap_adv_stop(); - if(err_code != NRF_SUCCESS) - { - return err_code; - } - } - m_whitelist_temporarily_disabled = true; + return ret; + } - err_code = ble_advertising_start(m_adv_mode_current); - if ((err_code != NRF_SUCCESS) && (m_error_handler != NULL)) - { - m_error_handler(err_code); - } + ret = ble_advertising_start(m_adv_mode_current); + if ((ret != NRF_SUCCESS) && (m_error_handler != NULL)) + { + m_error_handler(ret); } + return NRF_SUCCESS; } - +#endif // NRF_MODULE_ENABLED(BLE_ADVERTISING) diff --git a/components/ble/ble_advertising/ble_advertising.h b/components/ble/ble_advertising/ble_advertising.h index ea7558a..9976714 100644 --- a/components/ble/ble_advertising/ble_advertising.h +++ b/components/ble/ble_advertising/ble_advertising.h @@ -1,28 +1,57 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_lib_advertising Advertising Module + * @defgroup ble_advertising Advertising Module * @{ * @ingroup ble_sdk_lib * @brief Module for handling connectable BLE advertising. * - * @details The Advertising Module handles connectable advertising for your application. It can + * @details The Advertising Module handles connectable advertising for your application. It can * be configured with advertising modes to suit most typical use cases. * Your main application can react to changes in advertising modes * if an event handler is provided. * - * @note The Advertising Module supports only applications with a single slave link. + * @note The Advertising Module supports only applications with a single peripheral link. * * The application must propagate BLE stack events to this module by calling * @ref ble_advertising_on_ble_evt() and system events by calling @@ -34,16 +63,21 @@ #define BLE_ADVERTISING_H__ #include -#include "ble_gattc.h" -#include "ble.h" #include "nrf_error.h" +#include "ble.h" +#include "ble_gattc.h" #include "ble_advdata.h" +#ifdef __cplusplus +extern "C" { +#endif + + /**@brief Advertising modes. */ typedef enum { - BLE_ADV_MODE_IDLE, /**< Idle; no connectable advertising is ongoing.*/ + BLE_ADV_MODE_IDLE, /**< Idle; no connectable advertising is ongoing. */ BLE_ADV_MODE_DIRECTED, /**< Directed advertising attempts to connect to the most recently disconnected peer. */ BLE_ADV_MODE_DIRECTED_SLOW, /**< Directed advertising (low duty cycle) attempts to connect to the most recently disconnected peer. */ BLE_ADV_MODE_FAST, /**< Fast advertising will connect to any peer device, or filter with a whitelist if one exists. */ @@ -63,13 +97,14 @@ typedef enum BLE_ADV_EVT_DIRECTED, /**< Direct advertising mode has started. */ BLE_ADV_EVT_DIRECTED_SLOW, /**< Directed advertising (low duty cycle) has started. */ BLE_ADV_EVT_FAST, /**< Fast advertising mode has started. */ - BLE_ADV_EVT_SLOW, /**< Slow advertising mode has started.*/ + BLE_ADV_EVT_SLOW, /**< Slow advertising mode has started. */ BLE_ADV_EVT_FAST_WHITELIST, /**< Fast advertising mode using the whitelist has started. */ - BLE_ADV_EVT_SLOW_WHITELIST, /**< Slow advertising mode using the whitelist has started.*/ + BLE_ADV_EVT_SLOW_WHITELIST, /**< Slow advertising mode using the whitelist has started. */ BLE_ADV_EVT_WHITELIST_REQUEST, /**< Request a whitelist from the main application. For whitelist advertising to work, the whitelist must be set when this event occurs. */ BLE_ADV_EVT_PEER_ADDR_REQUEST /**< Request a peer address from the main application. For directed advertising to work, the peer address must be set when this event occurs. */ } ble_adv_evt_t; + /**@brief Options for the different advertisement modes. * * @details This structure is used to enable or disable advertising modes and to configure time-out @@ -80,15 +115,23 @@ typedef struct bool ble_adv_whitelist_enabled; /**< Enable or disable use of the whitelist. */ bool ble_adv_directed_enabled; /**< Enable or disable direct advertising mode. */ bool ble_adv_directed_slow_enabled; /**< Enable or disable direct advertising mode. */ + bool ble_adv_fast_enabled; /**< Enable or disable fast advertising mode. */ + bool ble_adv_slow_enabled; /**< Enable or disable slow advertising mode. */ uint32_t ble_adv_directed_slow_interval; /**< Advertising interval for directed advertising. */ uint32_t ble_adv_directed_slow_timeout; /**< Time-out (number of tries) for direct advertising. */ - bool ble_adv_fast_enabled; /**< Enable or disable fast advertising mode. */ uint32_t ble_adv_fast_interval; /**< Advertising interval for fast advertising. */ uint32_t ble_adv_fast_timeout; /**< Time-out (in seconds) for fast advertising. */ - bool ble_adv_slow_enabled; /**< Enable or disable slow advertising mode. */ uint32_t ble_adv_slow_interval; /**< Advertising interval for slow advertising. */ uint32_t ble_adv_slow_timeout; /**< Time-out (in seconds) for slow advertising. */ -}ble_adv_modes_config_t; +} ble_adv_modes_config_t; + + +typedef struct +{ + uint32_t interval; + uint32_t timeout; + bool enabled; +} ble_adv_mode_config_t; /**@brief BLE advertising event handler type. */ @@ -104,24 +147,7 @@ typedef struct ble_adv_modes_config_t options; /**< Parameters for advertising modes.*/ ble_advdata_t advdata; /**< Advertising data. */ ble_advertising_evt_handler_t evt_handler; /**< Event handler. */ -}ble_adv_init_t; - - -/* Defines to make the mode options easier to set during advertising init.*/ -#define BLE_ADV_DIRECTED_ENABLED true -#define BLE_ADV_DIRECTED_DISABLED false - -#define BLE_ADV_DIRECTED_SLOW_ENABLED true -#define BLE_ADV_DIRECTED_SLOW_DISABLED false - -#define BLE_ADV_FAST_ENABLED true -#define BLE_ADV_FAST_DISABLED false - -#define BLE_ADV_SLOW_ENABLED true -#define BLE_ADV_SLOW_DISABLED false - -#define BLE_ADV_WHITELIST_ENABLED true -#define BLE_ADV_WHITELIST_DISABLED false +} ble_adv_init_t; /**@brief Function for handling BLE events. @@ -161,11 +187,11 @@ void ble_advertising_on_sys_evt(uint32_t sys_evt); * * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned. */ -uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, - ble_advdata_t const * p_srdata, - ble_adv_modes_config_t const * p_config, - ble_advertising_evt_handler_t const evt_handler, - ble_advertising_error_handler_t const error_handler); +uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, + ble_advdata_t const * p_srdata, + ble_adv_modes_config_t const * p_config, + ble_advertising_evt_handler_t const evt_handler, + ble_advertising_error_handler_t const error_handler); /**@brief Function for starting advertising. @@ -176,10 +202,11 @@ uint32_t ble_advertising_init(ble_advdata_t const * p_advdata, * @param[in] advertising_mode Advertising mode. * * @retval @ref NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval @ref NRF_ERROR_INVALID_STATE + * @retval @ref NRF_ERROR_INVALID_STATE If the module is not initialized. */ uint32_t ble_advertising_start(ble_adv_mode_t advertising_mode); + /**@brief Function for setting the peer address. * * @details The peer address must be set by the application upon receiving a @@ -200,12 +227,19 @@ uint32_t ble_advertising_peer_addr_reply(ble_gap_addr_t * p_peer_addr); * @ref BLE_ADV_EVT_WHITELIST_REQUEST event. Without the whitelist, the whitelist * advertising for fast and slow modes will not be run. * - * @param[in] p_whitelist Pointer to a whitelist. + * @param[in] p_gap_addrs The list of GAP addresses to whitelist. + * @param[in] addr_cnt The number of GAP addresses to whitelist. + * @param[in] p_gap_irks The list of peer IRK to whitelist. + * @param[in] irk_cnt The number of peer IRK to whitelist. * - * @retval @ref NRF_SUCCESS Successfully stored pointers to the whitelist into the advertising module. - * @retval @ref NRF_ERROR_INVALID_STATE If a reply was not expected. + * @retval @ref NRF_SUCCESS If the operation was successful. + * @retval @ref NRF_ERROR_INVALID_STATE If a call to this function was made without a + * BLE_ADV_EVT_WHITELIST_REQUEST event being received. */ -uint32_t ble_advertising_whitelist_reply(ble_gap_whitelist_t * p_whitelist); +uint32_t ble_advertising_whitelist_reply(ble_gap_addr_t const * p_gap_addrs, + uint32_t addr_cnt, + ble_gap_irk_t const * p_gap_irks, + uint32_t irk_cnt); /**@brief Function for disabling whitelist advertising. @@ -216,8 +250,14 @@ uint32_t ble_advertising_whitelist_reply(ble_gap_whitelist_t * p_whitelist); * @retval @ref NRF_SUCCESS On success, else an error message propogated from the Softdevice. */ uint32_t ble_advertising_restart_without_whitelist(void); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif // BLE_ADVERTISING_H__ /** @} */ diff --git a/components/ble/ble_db_discovery/ble_db_discovery.c b/components/ble/ble_db_discovery/ble_db_discovery.c index e984eeb..d427a2d 100644 --- a/components/ble/ble_db_discovery/ble_db_discovery.c +++ b/components/ble/ble_db_discovery/ble_db_discovery.c @@ -1,32 +1,60 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_DB_DISCOVERY) #include "ble_db_discovery.h" #include -#include -#include "nrf_error.h" #include "ble.h" -#include "app_trace.h" -#include "nordic_common.h" +#include "ble_srv_common.h" +#define NRF_LOG_MODULE_NAME "BLE_DB_DISC" +#include "nrf_log.h" #define SRV_DISC_START_HANDLE 0x0001 /**< The start handle value used during service discovery. */ #define DB_DISCOVERY_MAX_USERS BLE_DB_DISCOVERY_MAX_SRV /**< The maximum number of users/registrations allowed by this module. */ -#define DB_LOG app_trace_log /**< A debug logger macro that can be used in this file to do logging information over UART. */ +#define MODULE_INITIALIZED (m_initialized == true) /**< Macro designating whether the module has been initialized properly. */ + /**@brief Array of structures containing information about the registered application modules. */ -static struct -{ - ble_uuid_t srv_uuid; /**< The UUID of the service for which the application module had registered itself.*/ - ble_db_discovery_evt_handler_t evt_handler; /**< The event handler of the application module to be called in case there are any events.*/ -} m_registered_handlers[DB_DISCOVERY_MAX_USERS]; +static ble_uuid_t m_registered_handlers[DB_DISCOVERY_MAX_USERS]; + /**@brief Array of structures containing pending events to be sent to the application modules. * @@ -40,6 +68,7 @@ static struct ble_db_discovery_evt_handler_t evt_handler; /**< The event handler which should be called to raise this event. */ } m_pending_user_evts[DB_DISCOVERY_MAX_USERS]; +static ble_db_discovery_evt_handler_t m_evt_handler; static uint32_t m_pending_usr_evt_index; /**< The index to the pending user event array, pointing to the last added pending user event. */ static uint32_t m_num_of_handlers_reg; /**< The number of handlers registered with the DB Discovery module. */ static bool m_initialized = false; /**< This variable Indicates if the module is initialized or not. */ @@ -51,15 +80,15 @@ static bool m_initialized = false; /**< This variable Indicates if the * @retval evt_handler Event handler of the module, registered for the given service UUID. * @retval NULL If no event handler is found. */ -static ble_db_discovery_evt_handler_t registered_handler_get(ble_uuid_t * p_srv_uuid) +static ble_db_discovery_evt_handler_t registered_handler_get(const ble_uuid_t * const p_srv_uuid) { uint32_t i; for (i = 0; i < m_num_of_handlers_reg; i++) { - if (BLE_UUID_EQ(&(m_registered_handlers[i].srv_uuid), p_srv_uuid)) + if (BLE_UUID_EQ(&(m_registered_handlers[i]), p_srv_uuid)) { - return (m_registered_handlers[i].evt_handler); + return (m_evt_handler); } } @@ -72,16 +101,19 @@ static ble_db_discovery_evt_handler_t registered_handler_get(ble_uuid_t * p_srv_ * @param[in] p_srv_uuid The UUID of the service. * @param[in] p_evt_handler The event handler provided by the application. * - * @retval NRF_SUCCESS If the handler was stored. + * @retval NRF_SUCCESS If the handler was stored or already present in the list. * @retval NRF_ERROR_NO_MEM If there is no space left to store the handler. */ static uint32_t registered_handler_set(const ble_uuid_t * const p_srv_uuid, ble_db_discovery_evt_handler_t p_evt_handler) { + if (registered_handler_get(p_srv_uuid) != NULL) + { + return NRF_SUCCESS; + } if (m_num_of_handlers_reg < DB_DISCOVERY_MAX_USERS) { - m_registered_handlers[m_num_of_handlers_reg].srv_uuid = *p_srv_uuid; - m_registered_handlers[m_num_of_handlers_reg].evt_handler = p_evt_handler; + m_registered_handlers[m_num_of_handlers_reg] = *p_srv_uuid; m_num_of_handlers_reg++; @@ -98,14 +130,13 @@ static uint32_t registered_handler_set(const ble_uuid_t * const p_srv_uuid */ static void pending_user_evts_send(void) { - uint32_t i; + uint32_t i = 0; for (i = 0; i < m_num_of_handlers_reg; i++) { // Pass the event to the corresponding event handler. m_pending_user_evts[i].evt_handler(&(m_pending_user_evts[i].evt)); } - m_pending_usr_evt_index = 0; } @@ -119,10 +150,12 @@ static void pending_user_evts_send(void) * * @param[in] p_db_discovery Pointer to the DB discovery structure. * @param[in] err_code Error code that should be provided to the application. + * @param[in] conn_handle Connection Handle. * */ static void discovery_error_evt_trigger(ble_db_discovery_t * const p_db_discovery, - uint32_t err_code) + uint32_t err_code, + uint16_t const conn_handle) { ble_db_discovery_evt_handler_t p_evt_handler; ble_gatt_db_srv_t * p_srv_being_discovered; @@ -133,29 +166,13 @@ static void discovery_error_evt_trigger(ble_db_discovery_t * const p_db_discover if (p_evt_handler != NULL) { - if (m_pending_usr_evt_index < DB_DISCOVERY_MAX_USERS) - { - // Insert an event into the pending event list. - m_pending_user_evts[m_pending_usr_evt_index].evt.conn_handle = - p_db_discovery->conn_handle; - m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type = - BLE_DB_DISCOVERY_ERROR; - m_pending_user_evts[m_pending_usr_evt_index].evt.params.err_code = err_code; - m_pending_user_evts[m_pending_usr_evt_index].evt_handler = p_evt_handler; + ble_db_discovery_evt_t evt; - m_pending_usr_evt_index++; + evt.conn_handle = conn_handle; + evt.evt_type = BLE_DB_DISCOVERY_ERROR; + evt.params.err_code = err_code; - if (m_pending_usr_evt_index == m_num_of_handlers_reg) - { - // All registered modules have pending events. - // Send all pending events to the user modules. - pending_user_evts_send(); - } - } - else - { - // Too many events pending. Do nothing. (Ideally this should not happen.) - } + p_evt_handler(&evt); } } @@ -170,9 +187,11 @@ static void discovery_error_evt_trigger(ble_db_discovery_t * const p_db_discover * * @param[in] p_db_discovery Pointer to the DB discovery structure. * @param[in] is_srv_found Variable to indicate if the service was found at the peer. + * @param[in] conn_handle Connection Handle. */ static void discovery_complete_evt_trigger(ble_db_discovery_t * const p_db_discovery, - bool is_srv_found) + bool is_srv_found, + uint16_t const conn_handle) { ble_db_discovery_evt_handler_t p_evt_handler; ble_gatt_db_srv_t * p_srv_being_discovered; @@ -186,16 +205,14 @@ static void discovery_complete_evt_trigger(ble_db_discovery_t * const p_db_disco if (m_pending_usr_evt_index < DB_DISCOVERY_MAX_USERS) { // Insert an event into the pending event list. - m_pending_user_evts[m_pending_usr_evt_index].evt.conn_handle = - p_db_discovery->conn_handle; + m_pending_user_evts[m_pending_usr_evt_index].evt.conn_handle = conn_handle; + m_pending_user_evts[m_pending_usr_evt_index].evt.params.discovered_db = + *p_srv_being_discovered; if (is_srv_found) { m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type = BLE_DB_DISCOVERY_COMPLETE; - - m_pending_user_evts[m_pending_usr_evt_index].evt.params.discovered_db = - *p_srv_being_discovered; } else { @@ -227,8 +244,10 @@ static void discovery_complete_evt_trigger(ble_db_discovery_t * const p_db_disco * and if so, initiate the discovery of the next service. * * @param[in] p_db_discovery Pointer to the DB Discovery Structure. + * @param[in] conn_handle Connection Handle. */ -static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery) +static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery, + uint16_t const conn_handle) { p_db_discovery->discoveries_count++; @@ -245,21 +264,20 @@ static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery) p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); - p_srv_being_discovered->srv_uuid = - m_registered_handlers[p_db_discovery->curr_srv_ind].srv_uuid; + p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind]; // Reset the characteristic count in the current service to zero since a new service // discovery is about to start. p_srv_being_discovered->char_count = 0; - DB_LOG("[DB]: Starting discovery of service with UUID 0x%x for Connection handle %d\r\n", - p_srv_being_discovered->srv_uuid.uuid, p_db_discovery->conn_handle); + NRF_LOG_INFO("Starting discovery of service with UUID 0x%x for Connection handle %d\r\n", + p_srv_being_discovered->srv_uuid.uuid, conn_handle); uint32_t err_code; err_code = sd_ble_gattc_primary_services_discover ( - p_db_discovery->conn_handle, + conn_handle, SRV_DISC_START_HANDLE, &(p_srv_being_discovered->srv_uuid) ); @@ -269,7 +287,11 @@ static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery) // Error with discovering the service. // Indicate the error to the registered user application. - discovery_error_evt_trigger(p_db_discovery, err_code); + discovery_error_evt_trigger(p_db_discovery, err_code, conn_handle); + + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = conn_handle; +// m_evt_handler(&m_pending_user_evts[0].evt); return; } @@ -277,7 +299,10 @@ static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery) else { // No more service discovery is needed. - p_db_discovery->discovery_in_progress = false; + p_db_discovery->discovery_in_progress = false; + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = conn_handle; + //m_evt_handler(&m_pending_user_evts[0].evt); } } @@ -294,8 +319,8 @@ static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery) * @param[in] p_db_discovery The pointer to the DB Discovery structure. * @param[in] p_after_char The pointer to the last discovered characteristic. * - * @retval True if a characteristic discovery is required. - * @retval False if a characteristic discovery is NOT required. + * @retval True if a characteristic discovery is required. + * @retval False if a characteristic discovery is NOT required. */ static bool is_char_discovery_reqd(ble_db_discovery_t * const p_db_discovery, ble_gattc_char_t * p_after_char) @@ -310,7 +335,7 @@ static bool is_char_discovery_reqd(ble_db_discovery_t * const p_db_discovery, // present. Hence a characteristic discovery is required. return true; } - + return false; } @@ -320,7 +345,7 @@ static bool is_char_discovery_reqd(ble_db_discovery_t * const p_db_discovery, * @details This function finds out if there is a possibility of existence of descriptors between * current characteristic and the next characteristic. If so, this function will compute * the handle range on which the descriptors may be present and will return it. - * If the current characteristic is the last known characteristic, then this function + * If the current characteristic is the last known characteristic, then this function * will use the service end handle to find out if the current characteristic can have * descriptors. * @@ -355,7 +380,7 @@ static bool is_desc_discovery_reqd(ble_db_discovery_t * p_db_discovery, } p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1; - + // Since the current characteristic is the last characteristic in the service, the end // handle should be the end handle of the service. p_handle_range->end_handle = @@ -382,12 +407,14 @@ static bool is_desc_discovery_reqd(ble_db_discovery_t * p_db_discovery, /**@brief Function for performing characteristic discovery. * * @param[in] p_db_discovery Pointer to the DB Discovery structure. + * @param[in] conn_handle Connection Handle. * * @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the characteristic * discovery. Otherwise an error code. This function returns the error code returned * by the SoftDevice API @ref sd_ble_gattc_characteristics_discover. */ -static uint32_t characteristics_discover(ble_db_discovery_t * const p_db_discovery) +static uint32_t characteristics_discover(ble_db_discovery_t * const p_db_discovery, + uint16_t const conn_handle) { ble_gatt_db_srv_t * p_srv_being_discovered; ble_gattc_handle_range_t handle_range; @@ -415,8 +442,7 @@ static uint32_t characteristics_discover(ble_db_discovery_t * const p_db_discove handle_range.end_handle = p_srv_being_discovered->handle_range.end_handle; - return sd_ble_gattc_characteristics_discover(p_db_discovery->conn_handle, - &handle_range); + return sd_ble_gattc_characteristics_discover(conn_handle, &handle_range); } @@ -431,6 +457,7 @@ static uint32_t characteristics_discover(ble_db_discovery_t * const p_db_discove * @param[out] p_raise_discov_complete The value pointed to by this pointer will be set to true if * the Discovery Complete event can be triggered to the * application. + * @param[in] conn_handle Connection Handle. * * @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the descriptor * discovery, or if no more descriptor discovery is required. Otherwise an error code. @@ -438,12 +465,13 @@ static uint32_t characteristics_discover(ble_db_discovery_t * const p_db_discove * sd_ble_gattc_descriptors_discover. */ static uint32_t descriptors_discover(ble_db_discovery_t * const p_db_discovery, - bool * p_raise_discov_complete) + bool * p_raise_discov_complete, + uint16_t const conn_handle) { ble_gattc_handle_range_t handle_range; ble_gatt_db_char_t * p_curr_char_being_discovered; ble_gatt_db_srv_t * p_srv_being_discovered; - bool is_discovery_reqd = false; + bool is_discovery_reqd = false; p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); @@ -507,8 +535,7 @@ static uint32_t descriptors_discover(ble_db_discovery_t * const p_db_discovery, *p_raise_discov_complete = false; - return sd_ble_gattc_descriptors_discover(p_db_discovery->conn_handle, - &handle_range); + return sd_ble_gattc_descriptors_discover(conn_handle, &handle_range); } @@ -523,20 +550,27 @@ static uint32_t descriptors_discover(ble_db_discovery_t * const p_db_discovery, static void on_primary_srv_discovery_rsp(ble_db_discovery_t * const p_db_discovery, const ble_gattc_evt_t * const p_ble_gattc_evt) { + ble_gatt_db_srv_t * p_srv_being_discovered; + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + + if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle) + { + return; + } if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS) { uint32_t err_code; const ble_gattc_evt_prim_srvc_disc_rsp_t * p_prim_srvc_disc_rsp_evt; - ble_gatt_db_srv_t * p_srv_being_discovered; - p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); + NRF_LOG_INFO("Found service UUID 0x%x\r\n", p_srv_being_discovered->srv_uuid.uuid); p_prim_srvc_disc_rsp_evt = &(p_ble_gattc_evt->params.prim_srvc_disc_rsp); p_srv_being_discovered->srv_uuid = p_prim_srvc_disc_rsp_evt->services[0].uuid; p_srv_being_discovered->handle_range = p_prim_srvc_disc_rsp_evt->services[0].handle_range; - err_code = characteristics_discover(p_db_discovery); + err_code = characteristics_discover(p_db_discovery, + p_ble_gattc_evt->conn_handle); if (err_code != NRF_SUCCESS) { @@ -544,15 +578,25 @@ static void on_primary_srv_discovery_rsp(ble_db_discovery_t * const p_db_disc // Error with discovering the service. // Indicate the error to the registered user application. - discovery_error_evt_trigger(p_db_discovery, err_code); + discovery_error_evt_trigger(p_db_discovery, + err_code, + p_ble_gattc_evt->conn_handle); + + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; + //m_evt_handler(&m_pending_user_evts[0].evt); } } else { + NRF_LOG_INFO("Service UUID 0x%x Not found\r\n", p_srv_being_discovered->srv_uuid.uuid); // Trigger Service Not Found event to the application. - discovery_complete_evt_trigger(p_db_discovery, false); + discovery_complete_evt_trigger(p_db_discovery, + false, + p_ble_gattc_evt->conn_handle); - on_srv_disc_completion(p_db_discovery); + on_srv_disc_completion(p_db_discovery, + p_ble_gattc_evt->conn_handle); } } @@ -567,8 +611,12 @@ static void on_characteristic_discovery_rsp(ble_db_discovery_t * const p_db_d { uint32_t err_code; ble_gatt_db_srv_t * p_srv_being_discovered; - bool perform_desc_discov = false; + bool perform_desc_discov = false; + if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle) + { + return; + } p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS) @@ -580,7 +628,7 @@ static void on_characteristic_discovery_rsp(ble_db_discovery_t * const p_db_d // Find out the number of characteristics that were previously discovered (in earlier // characteristic discovery responses, if any). uint8_t num_chars_prev_disc = p_srv_being_discovered->char_count; - + // Find out the number of characteristics that are currently discovered (in the // characteristic discovery response being handled). uint8_t num_chars_curr_disc = p_char_disc_rsp_evt->count; @@ -606,11 +654,14 @@ static void on_characteristic_discovery_rsp(ble_db_discovery_t * const p_db_d p_srv_being_discovered->charateristics[i].characteristic = p_char_disc_rsp_evt->chars[j]; - p_srv_being_discovered->charateristics[i].cccd_handle = BLE_GATT_HANDLE_INVALID; + p_srv_being_discovered->charateristics[i].cccd_handle = BLE_GATT_HANDLE_INVALID; + p_srv_being_discovered->charateristics[i].ext_prop_handle = BLE_GATT_HANDLE_INVALID; + p_srv_being_discovered->charateristics[i].user_desc_handle = BLE_GATT_HANDLE_INVALID; + p_srv_being_discovered->charateristics[i].report_ref_handle = BLE_GATT_HANDLE_INVALID; } - + ble_gattc_char_t * p_last_known_char; - + p_last_known_char = &(p_srv_being_discovered->charateristics[i - 1].characteristic); // If no more characteristic discovery is required, or if the maximum number of supported @@ -628,13 +679,20 @@ static void on_characteristic_discovery_rsp(ble_db_discovery_t * const p_db_d p_db_discovery->curr_char_ind = p_srv_being_discovered->char_count; // Perform another round of characteristic discovery. - err_code = characteristics_discover(p_db_discovery); + err_code = characteristics_discover(p_db_discovery, + p_ble_gattc_evt->conn_handle); if (err_code != NRF_SUCCESS) { p_db_discovery->discovery_in_progress = false; - discovery_error_evt_trigger(p_db_discovery, err_code); + discovery_error_evt_trigger(p_db_discovery, + err_code, + p_ble_gattc_evt->conn_handle); + + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; + //m_evt_handler(&m_pending_user_evts[0].evt); return; } @@ -653,13 +711,21 @@ static void on_characteristic_discovery_rsp(ble_db_discovery_t * const p_db_d p_db_discovery->curr_char_ind = 0; - err_code = descriptors_discover(p_db_discovery, &raise_discov_complete); + err_code = descriptors_discover(p_db_discovery, + &raise_discov_complete, + p_ble_gattc_evt->conn_handle); if (err_code != NRF_SUCCESS) { p_db_discovery->discovery_in_progress = false; - discovery_error_evt_trigger(p_db_discovery, err_code); + discovery_error_evt_trigger(p_db_discovery, + err_code, + p_ble_gattc_evt->conn_handle); + + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; + //m_evt_handler(&m_pending_user_evts[0].evt); return; } @@ -667,13 +733,16 @@ static void on_characteristic_discovery_rsp(ble_db_discovery_t * const p_db_d { // No more characteristics and descriptors need to be discovered. Discovery is complete. // Send a discovery complete event to the user application. - DB_LOG("[DB]: Discovery of service with UUID 0x%x completed with success for Connection" + NRF_LOG_INFO("Discovery of service with UUID 0x%x completed with success for Connection" " handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid, - p_db_discovery->conn_handle); + p_ble_gattc_evt->conn_handle); - discovery_complete_evt_trigger(p_db_discovery, true); + discovery_complete_evt_trigger(p_db_discovery, + true, + p_ble_gattc_evt->conn_handle); - on_srv_disc_completion(p_db_discovery); + on_srv_disc_completion(p_db_discovery, + p_ble_gattc_evt->conn_handle); } } } @@ -690,6 +759,11 @@ static void on_descriptor_discovery_rsp(ble_db_discovery_t * const p_db_disco const ble_gattc_evt_desc_disc_rsp_t * p_desc_disc_rsp_evt; ble_gatt_db_srv_t * p_srv_being_discovered; + if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle) + { + return; + } + p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); p_desc_disc_rsp_evt = &(p_ble_gattc_evt->params.desc_disc_rsp); @@ -700,20 +774,39 @@ static void on_descriptor_discovery_rsp(ble_db_discovery_t * const p_db_disco if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS) { // The descriptor was found at the peer. - // If the descriptor was a CCCD, then the cccd_handle needs to be populated. - - uint32_t i; - - // Loop through all the descriptors to find the CCCD. - for (i = 0; i < p_desc_disc_rsp_evt->count; i++) + // Iterate through and collect CCCD, Extended Properties, + // User Description & Report Reference descriptor handles. + for (uint32_t i = 0; i < p_desc_disc_rsp_evt->count; i++) { - if ( - p_desc_disc_rsp_evt->descs[i].uuid.uuid == - BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG - ) + switch (p_desc_disc_rsp_evt->descs[i].uuid.uuid) { - p_char_being_discovered->cccd_handle = p_desc_disc_rsp_evt->descs[i].handle; + case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG: + p_char_being_discovered->cccd_handle = + p_desc_disc_rsp_evt->descs[i].handle; + break; + + case BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP: + p_char_being_discovered->ext_prop_handle = + p_desc_disc_rsp_evt->descs[i].handle; + break; + + case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC: + p_char_being_discovered->user_desc_handle = + p_desc_disc_rsp_evt->descs[i].handle; + break; + + case BLE_UUID_REPORT_REF_DESCR: + p_char_being_discovered->report_ref_handle = + p_desc_disc_rsp_evt->descs[i].handle; + break; + } + /* Break if we've found all the descriptors we are looking for. */ + if (p_char_being_discovered->cccd_handle != BLE_GATT_HANDLE_INVALID && + p_char_being_discovered->ext_prop_handle != BLE_GATT_HANDLE_INVALID && + p_char_being_discovered->user_desc_handle != BLE_GATT_HANDLE_INVALID && + p_char_being_discovered->report_ref_handle != BLE_GATT_HANDLE_INVALID) + { break; } } @@ -735,7 +828,9 @@ static void on_descriptor_discovery_rsp(ble_db_discovery_t * const p_db_disco p_db_discovery->curr_char_ind++; - err_code = descriptors_discover(p_db_discovery, &raise_discov_complete); + err_code = descriptors_discover(p_db_discovery, + &raise_discov_complete, + p_ble_gattc_evt->conn_handle); if (err_code != NRF_SUCCESS) { @@ -743,7 +838,12 @@ static void on_descriptor_discovery_rsp(ble_db_discovery_t * const p_db_disco // Error with discovering the service. // Indicate the error to the registered user application. - discovery_error_evt_trigger(p_db_discovery, err_code); + discovery_error_evt_trigger(p_db_discovery, + err_code, + p_ble_gattc_evt->conn_handle); + + m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE; + m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle; return; } @@ -751,24 +851,32 @@ static void on_descriptor_discovery_rsp(ble_db_discovery_t * const p_db_disco if (raise_discov_complete) { - DB_LOG("[DB]: Discovery of service with UUID 0x%x completed with success for Connection" - "handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid, - p_db_discovery->conn_handle); + NRF_LOG_INFO("Discovery of service with UUID 0x%x completed with success for Connection" + " handle %d\r\n", p_srv_being_discovered->srv_uuid.uuid, + p_ble_gattc_evt->conn_handle); - discovery_complete_evt_trigger(p_db_discovery, true); + discovery_complete_evt_trigger(p_db_discovery, + true, + p_ble_gattc_evt->conn_handle); - on_srv_disc_completion(p_db_discovery); + on_srv_disc_completion(p_db_discovery, + p_ble_gattc_evt->conn_handle); } } -uint32_t ble_db_discovery_init(void) +uint32_t ble_db_discovery_init(const ble_db_discovery_evt_handler_t evt_handler) { + uint32_t err_code = NRF_SUCCESS; + VERIFY_PARAM_NOT_NULL(evt_handler); + m_num_of_handlers_reg = 0; m_initialized = true; m_pending_usr_evt_index = 0; + m_evt_handler = evt_handler; + + return err_code; - return NRF_SUCCESS; } @@ -782,41 +890,20 @@ uint32_t ble_db_discovery_close() } -uint32_t ble_db_discovery_evt_register(const ble_uuid_t * const p_uuid, - const ble_db_discovery_evt_handler_t evt_handler) +uint32_t ble_db_discovery_evt_register(const ble_uuid_t * const p_uuid) { - if ((p_uuid == NULL) || (evt_handler == NULL)) - { - return NRF_ERROR_NULL; - } - - if (!m_initialized) - { - return NRF_ERROR_INVALID_STATE; - } - - if (m_num_of_handlers_reg == DB_DISCOVERY_MAX_USERS) - { - // The limit on the maximum number of supported users has been reached. Return error. - return NRF_ERROR_NOT_SUPPORTED; - } + VERIFY_PARAM_NOT_NULL(p_uuid); + VERIFY_MODULE_INITIALIZED(); - return registered_handler_set(p_uuid, evt_handler); + return registered_handler_set(p_uuid, m_evt_handler); } uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle) { - if (p_db_discovery == NULL) - { - return NRF_ERROR_NULL; - } - - if (!m_initialized) - { - return NRF_ERROR_INVALID_STATE; - } + VERIFY_PARAM_NOT_NULL(p_db_discovery); + VERIFY_MODULE_INITIALIZED(); if (m_num_of_handlers_reg == 0) { @@ -829,61 +916,58 @@ uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, return NRF_ERROR_BUSY; } + p_db_discovery->conn_handle = conn_handle; ble_gatt_db_srv_t * p_srv_being_discovered; m_pending_usr_evt_index = 0; - p_db_discovery->conn_handle = conn_handle; p_db_discovery->discoveries_count = 0; - p_db_discovery->curr_srv_ind = 0; + p_db_discovery->curr_srv_ind = 0; + p_db_discovery->curr_char_ind = 0; p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]); - p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind].srv_uuid; + p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind]; + + NRF_LOG_INFO("Starting discovery of service with UUID 0x%x for Connection handle %d\r\n", + p_srv_being_discovered->srv_uuid.uuid, conn_handle); - DB_LOG("[DB]: Starting discovery of service with UUID 0x%x for Connection handle %d\r\n", - p_srv_being_discovered->srv_uuid.uuid, p_db_discovery->conn_handle); - uint32_t err_code; - err_code = sd_ble_gattc_primary_services_discover(p_db_discovery->conn_handle, + err_code = sd_ble_gattc_primary_services_discover(conn_handle, SRV_DISC_START_HANDLE, &(p_srv_being_discovered->srv_uuid)); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); p_db_discovery->discovery_in_progress = true; return NRF_SUCCESS; } -void ble_db_discovery_on_ble_evt(ble_db_discovery_t * const p_db_discovery, - const ble_evt_t * const p_ble_evt) +/**@brief Function for handling disconnected event. + * + * @param[in] p_db_discovery Pointer to the DB Discovery structure. + * @param[in] p_ble_gattc_evt Pointer to the GAP event. + */ +static void on_disconnected(ble_db_discovery_t * const p_db_discovery, + const ble_gap_evt_t * const p_evt) { - if ((p_db_discovery == NULL) || (p_ble_evt == NULL)) + if (p_evt->conn_handle == p_db_discovery->conn_handle) { - // Null pointer provided. Return. - return; + p_db_discovery->discovery_in_progress = false; } +} - if (!m_initialized) - { - return; - } + +void ble_db_discovery_on_ble_evt(ble_db_discovery_t * const p_db_discovery, + const ble_evt_t * const p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_db_discovery); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + VERIFY_MODULE_INITIALIZED_VOID(); switch (p_ble_evt->header.evt_id) { - case BLE_GAP_EVT_CONNECTED: - p_db_discovery->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; - break; - - case BLE_GAP_EVT_DISCONNECTED: - memset(p_db_discovery, 0, sizeof(ble_db_discovery_t)); - p_db_discovery->conn_handle = BLE_CONN_HANDLE_INVALID; - break; - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: on_primary_srv_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt)); break; @@ -896,7 +980,12 @@ void ble_db_discovery_on_ble_evt(ble_db_discovery_t * const p_db_discovery, on_descriptor_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt)); break; + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_db_discovery, &(p_ble_evt->evt.gap_evt)); + break; + default: break; } } +#endif // NRF_MODULE_ENABLED(BLE_DB_DISCOVERY) diff --git a/components/ble/ble_db_discovery/ble_db_discovery.h b/components/ble/ble_db_discovery/ble_db_discovery.h index c0b75d4..5433234 100644 --- a/components/ble/ble_db_discovery/ble_db_discovery.h +++ b/components/ble/ble_db_discovery/ble_db_discovery.h @@ -1,35 +1,62 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_lib_db_discovery Database Discovery + * @defgroup ble_db_discovery Database Discovery * @{ * @ingroup ble_sdk_lib * @brief Database discovery module. * * @details This module contains the APIs and types exposed by the DB Discovery module. These APIs * and types can be used by the application to perform discovery of a service and its - * characteristics at the peer server. This module can also be used to discover the + * characteristics at the peer server. This module can also be used to discover the * desired services in multiple remote devices. - * A typical use of this library is described in the figure below. - * @image html db_discovery.jpg * * @warning The maximum number of characteristics per service that can be discovered by this module * is determined by the number of characteristics in the service structure defined in - * ble_gatt_db.h. If the peer has more than the supported number of characteristics, then - * the first found will be discovered and any further characteristics will be ignored. No - * descriptors other than Client Characteristic Configuration Descriptors will be searched - * for at the peer. + * db_disc_config.h. If the peer has more than the supported number of characteristics, then + * the first found will be discovered and any further characteristics will be ignored. Only the + * following descriptors will be searched for at the peer: Client Characteristic Configuration, + * Characteristic Extended Properties, Characteristic User Description, and Report Reference. * * @note Presently only one instance of a Primary Service can be discovered by this module. If * there are multiple instances of the service at the peer, only the first instance @@ -44,25 +71,19 @@ #define BLE_DB_DISCOVERY_H__ #include -#include "ble_gattc.h" -#include "ble.h" #include "nrf_error.h" +#include "ble.h" +#include "ble_gattc.h" #include "ble_srv_common.h" #include "ble_gatt_db.h" -/** - * @defgroup db_disc_defines Defines - * @{ - */ +#ifdef __cplusplus +extern "C" { +#endif -#define BLE_DB_DISCOVERY_MAX_SRV 2 /**< Maximum number of services supported by this module. This also indicates the maximum number of users allowed to be registered to this module. (one user per service). */ -/** @} */ +#define BLE_DB_DISCOVERY_MAX_SRV 6 /**< Maximum number of services supported by this module. This also indicates the maximum number of users allowed to be registered to this module. (one user per service). */ -/** - * @defgroup db_disc_enums Enumerations - * @{ - */ /**@brief Type of the DB Discovery event. */ @@ -70,20 +91,15 @@ typedef enum { BLE_DB_DISCOVERY_COMPLETE, /**< Event indicating that the GATT Database discovery is complete. */ BLE_DB_DISCOVERY_ERROR, /**< Event indicating that an internal error has occurred in the DB Discovery module. This could typically be because of the SoftDevice API returning an error code during the DB discover.*/ - BLE_DB_DISCOVERY_SRV_NOT_FOUND /**< Event indicating that the service was not found at the peer.*/ + BLE_DB_DISCOVERY_SRV_NOT_FOUND, /**< Event indicating that the service was not found at the peer.*/ + BLE_DB_DISCOVERY_AVAILABLE /**< Event indicating that the DB discovery module is available.*/ } ble_db_discovery_evt_type_t; -/** @} */ - -/** - * @defgroup db_disc_structs Structures - * @{ - */ /**@brief Structure for holding the information related to the GATT database at the server. * - * @details This module identifies a remote database. Use one instance of this structure per + * @details This module identifies a remote database. Use one instance of this structure per * connection. * * @warning This structure must be zero-initialized. @@ -91,12 +107,12 @@ typedef enum typedef struct { ble_gatt_db_srv_t services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered. This is intended for internal use during service discovery.*/ - uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */ uint8_t srv_count; /**< Number of services at the peers GATT database.*/ uint8_t curr_char_ind; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/ uint8_t curr_srv_ind; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/ bool discovery_in_progress; /**< Variable to indicate if there is a service discovery in progress. */ uint8_t discoveries_count; /**< Number of service discoveries made, both successful and unsuccessful. */ + uint16_t conn_handle; /**< Connection handle on which the discovery is started*/ } ble_db_discovery_t; @@ -113,35 +129,20 @@ typedef struct } params; } ble_db_discovery_evt_t; -/** @} */ - -/** - * @defgroup db_disc_types Types - * @{ - */ /**@brief DB Discovery event handler type. */ typedef void (* ble_db_discovery_evt_handler_t)(ble_db_discovery_evt_t * p_evt); -/** @} */ - -/** - * @addtogroup db_disc_structs - * @{ - */ - -/** @} */ - -/** - * @defgroup db_disc_functions Functions - * @{ - */ /**@brief Function for initializing the DB Discovery module. * - * @retval NRF_SUCCESS on successful initialization. + * @param[in] evt_handler Event handler to be called by the DB discovery module when any event + * related to discovery of the registered service occurs. + * + * @retval NRF_SUCCESS On successful initialization. + * @retval NRF_ERROR_NULL If the handler was NULL. */ -uint32_t ble_db_discovery_init(void); +uint32_t ble_db_discovery_init(ble_db_discovery_evt_handler_t evt_handler); /**@brief Function for closing the DB Discovery module. @@ -150,58 +151,55 @@ uint32_t ble_db_discovery_init(void); * module. To re-use the module after calling this function, the function @ref * ble_db_discovery_init must be called again. * - * @retval NRF_SUCCESS Operation success. + * @retval NRF_SUCCESS Operation success. */ uint32_t ble_db_discovery_close(void); /**@brief Function for registering with the DB Discovery module. * - * @details The application can use this function to inform which service it is interested in + * @details The application can use this function to inform which service it is interested in * discovering at the server. * * @param[in] p_uuid Pointer to the UUID of the service to be discovered at the server. - * @param[in] evt_handler Event handler to be called by the DB discovery module when any event - * related to discovery of the registered service occurs. * - * @note The total number of services that can be discovered by this module is @ref - * BLE_DB_DISCOVERY_MAX_SRV. This effectively means that the maximum number of - * registrations possible is equal to the @ref BLE_DB_DISCOVERY_MAX_SRV. + * @note The total number of services that can be discovered by this module is @ref + * BLE_DB_DISCOVERY_MAX_SRV. This effectively means that the maximum number of + * registrations possible is equal to the @ref BLE_DB_DISCOVERY_MAX_SRV. * * @retval NRF_SUCCESS Operation success. * @retval NRF_ERROR_NULL When a NULL pointer is passed as input. - * @retval NRF_ERROR_INVALID_STATE If this function is called without calling the + * @retval NRF_ERROR_INVALID_STATE If this function is called without calling the * @ref ble_db_discovery_init. - * @retval NRF_ERROR_NOT_SUPPORTED The maximum number of registrations allowed by this module + * @retval NRF_ERROR_NO_MEM The maximum number of registrations allowed by this module * has been reached. */ -uint32_t ble_db_discovery_evt_register(const ble_uuid_t * const p_uuid, - const ble_db_discovery_evt_handler_t evt_handler); +uint32_t ble_db_discovery_evt_register(const ble_uuid_t * const p_uuid); + - /**@brief Function for starting the discovery of the GATT database at the server. * * @warning p_db_discovery structure must be zero-initialized. * * @param[out] p_db_discovery Pointer to the DB Discovery structure. - * @param[in] conn_handle The handle of the connection for which the discovery should be + * @param[in] conn_handle The handle of the connection for which the discovery should be * started. * * @retval NRF_SUCCESS Operation success. * @retval NRF_ERROR_NULL When a NULL pointer is passed as input. - * @retval NRF_ERROR_INVALID_STATE If this function is called without calling the - * @ref ble_db_discovery_init, or without calling + * @retval NRF_ERROR_INVALID_STATE If this function is called without calling the + * @ref ble_db_discovery_init, or without calling * @ref ble_db_discovery_evt_register. - * @retval NRF_ERROR_BUSY If a discovery is already in progress for the current + * @retval NRF_ERROR_BUSY If a discovery is already in progress for the current * connection. * - * @return This API propagates the error code returned by the + * @return This API propagates the error code returned by the * SoftDevice API @ref sd_ble_gattc_primary_services_discover. */ uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle); - + /**@brief Function for handling the Application's BLE Stack events. * * @param[in,out] p_db_discovery Pointer to the DB Discovery structure. @@ -210,7 +208,10 @@ uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, void ble_db_discovery_on_ble_evt(ble_db_discovery_t * const p_db_discovery, const ble_evt_t * const p_ble_evt); -/** @} */ + +#ifdef __cplusplus +} +#endif #endif // BLE_DB_DISCOVERY_H__ diff --git a/components/ble/ble_debug_assert_handler/ble_debug_assert_handler.c b/components/ble/ble_debug_assert_handler/ble_debug_assert_handler.c index a47ec5e..500a75a 100644 --- a/components/ble/ble_debug_assert_handler/ble_debug_assert_handler.c +++ b/components/ble/ble_debug_assert_handler/ble_debug_assert_handler.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_debug_assert_handler.h" @@ -37,7 +65,7 @@ void ble_debug_assert_handler(uint32_t error_code, uint32_t line_num, const uint UNUSED_VARIABLE(s_error_code); // WARNING: The PRIMASK register is set to disable ALL interrups during writing the error log. - // + // // Do not use __disable_irq() in normal operation. __disable_irq(); diff --git a/components/ble/ble_debug_assert_handler/ble_debug_assert_handler.h b/components/ble/ble_debug_assert_handler/ble_debug_assert_handler.h index 051e6a4..4d5a2eb 100644 --- a/components/ble/ble_debug_assert_handler/ble_debug_assert_handler.h +++ b/components/ble/ble_debug_assert_handler/ble_debug_assert_handler.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -22,29 +50,38 @@ * This module is ONLY for debugging purposes and must never be used in final product. * */ - + #ifndef BLE_DEBUG_ASSERT_HANDLER_H__ #define BLE_DEBUG_ASSERT_HANDLER_H__ #include - -/**@brief Function for handling the Debug assert, which can be called from an error handler. + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for handling the Debug assert, which can be called from an error handler. * To be used only for debugging purposes. * *@details This code will copy the filename and line number into local variables for them to always - * be accessible in Keil debugger. The function will also write the ARM Cortex-M0 stack - * memory into flash where it can be retrieved and manually un-winded in order to + * be accessible in Keil debugger. The function will also write the ARM Cortex-M0 stack + * memory into flash where it can be retrieved and manually un-winded in order to * back-trace the location where the error ocured.
* @warning ALL INTERRUPTS WILL BE DISABLED. - * + * * @note This function will never return but loop forever for debug purposes. * * @param[in] error_code Error code supplied to the handler. * @param[in] line_num Line number where the original handler is called. - * @param[in] p_file_name Pointer to the file name. + * @param[in] p_file_name Pointer to the file name. */ void ble_debug_assert_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name); + +#ifdef __cplusplus +} +#endif + #endif /* BLE_DEBUG_ASSERT_HANDLER_H__ */ diff --git a/components/ble/ble_dtm/ble_dtm.c b/components/ble/ble_dtm/ble_dtm.c index de0ed8d..6e9f272 100644 --- a/components/ble/ble_dtm/ble_dtm.c +++ b/components/ble/ble_dtm/ble_dtm.c @@ -1,35 +1,56 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_DTM) #include "ble_dtm.h" +#include "ble_dtm_hw.h" #include #include #include "nrf.h" #define DTM_HEADER_OFFSET 0 /**< Index where the header of the pdu is located. */ #define DTM_HEADER_SIZE 2 /**< Size of PDU header. */ -#define DTM_PAYLOAD_MAX_SIZE 37 /**< Maximum payload size allowed during dtm execution. */ +#define DTM_PAYLOAD_MAX_SIZE 255 /**< Maximum payload size allowed during dtm execution. */ #define DTM_LENGTH_OFFSET (DTM_HEADER_OFFSET + 1) /**< Index where the length of the payload is encoded. */ #define DTM_PDU_MAX_MEMORY_SIZE (DTM_HEADER_SIZE + DTM_PAYLOAD_MAX_SIZE) /**< Maximum PDU size allowed during dtm execution. */ - -/**@details The UART poll cycle in micro seconds. - * Baud rate of 19200 bits / second, and 8 data bits, 1 start/stop bit, no flow control, - * give the time to transmit a byte: 10 bits * 1/19200 = approx: 520 us. - * - * To ensure no loss of bytes, the UART should be polled every 260 us. - * - * @note If UART bit rate is changed, this value should be recalculated as well. - */ -#define UART_POLL_CYCLE 260 +#define DTM_ON_AIR_OVERHEAD_SIZE 10 /**< Size of the packet on air without the payload (preamble + sync word + type + RFU + length + CRC). */ #define RX_MODE true /**< Constant defining RX mode for radio during dtm test. */ #define TX_MODE false /**< Constant defining TX mode for radio during dtm test. */ @@ -41,11 +62,40 @@ #define RFPHY_TEST_0X0F_REF_PATTERN 0x0f /**< RF-PHY test packet patterns, for the repeated octet packets. */ #define RFPHY_TEST_0X55_REF_PATTERN 0x55 /**< RF-PHY test packet patterns, for the repeated octet packets. */ -#define PRBS9_CONTENT {0xff, 0xc1, 0xfb, 0xe8, 0x4c, 0x90, 0x72, 0x8b, \ - 0xe7, 0xb3, 0x51, 0x89, 0x63, 0xab, 0x23, 0x23, \ - 0x2, 0x84, 0x18, 0x72, 0xaa, 0x61, 0x2f, 0x3b, \ - 0x51, 0xa8, 0xe5, 0x37, 0x49, 0xfb, 0xc9, 0xca, \ - 0xc, 0x18, 0x53, 0x2c, 0xfd} /**< The PRBS9 sequence used as packet payload. */ +#define PRBS9_CONTENT {0xFF, 0xC1, 0xFB, 0xE8, 0x4C, 0x90, 0x72, 0x8B, \ + 0xE7, 0xB3, 0x51, 0x89, 0x63, 0xAB, 0x23, 0x23, \ + 0x02, 0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B, \ + 0x51, 0xA8, 0xE5, 0x37, 0x49, 0xFB, 0xC9, 0xCA, \ + 0x0C, 0x18, 0x53, 0x2C, 0xFD, 0x45, 0xE3, 0x9A, \ + 0xE6, 0xF1, 0x5D, 0xB0, 0xB6, 0x1B, 0xB4, 0xBE, \ + 0x2A, 0x50, 0xEA, 0xE9, 0x0E, 0x9C, 0x4B, 0x5E, \ + 0x57, 0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87, \ + 0xFF, 0xE0, 0x7D, 0x74, 0x26, 0x48, 0xB9, 0xC5, \ + 0xF3, 0xD9, 0xA8, 0xC4, 0xB1, 0xD5, 0x91, 0x11, \ + 0x01, 0x42, 0x0C, 0x39, 0xD5, 0xB0, 0x97, 0x9D, \ + 0x28, 0xD4, 0xF2, 0x9B, 0xA4, 0xFD, 0x64, 0x65, \ + 0x06, 0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D, \ + 0xF3, 0xF8, 0x2E, 0x58, 0xDB, 0x0D, 0x5A, 0x5F, \ + 0x15, 0x28, 0xF5, 0x74, 0x07, 0xCE, 0x25, 0xAF, \ + 0x2B, 0x12, 0xE6, 0xD0, 0xDB, 0x2C, 0xDC, 0xC3, \ + 0x7F, 0xF0, 0x3E, 0x3A, 0x13, 0xA4, 0xDC, 0xE2, \ + 0xF9, 0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88, \ + 0x00, 0x21, 0x86, 0x9C, 0x6A, 0xD8, 0xCB, 0x4E, \ + 0x14, 0x6A, 0xF9, 0x4D, 0xD2, 0x7E, 0xB2, 0x32, \ + 0x03, 0xC6, 0x14, 0x4B, 0x7F, 0xD1, 0xB8, 0xA6, \ + 0x79, 0x7C, 0x17, 0xAC, 0xED, 0x06, 0xAD, 0xAF, \ + 0x0A, 0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7, \ + 0x15, 0x09, 0x73, 0xE8, 0x6D, 0x16, 0xEE, 0xE1, \ + 0x3F, 0x78, 0x1F, 0x9D, 0x09, 0x52, 0x6E, 0xF1, \ + 0x7C, 0x36, 0x2A, 0x71, 0x6C, 0x75, 0x64, 0x44, \ + 0x80, 0x10, 0x43, 0x4E, 0x35, 0xEC, 0x65, 0x27, \ + 0x0A, 0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99, \ + 0x01, 0x63, 0x8A, 0xA5, 0xBF, 0x68, 0x5C, 0xD3, \ + 0x3C, 0xBE, 0x0B, 0xD6, 0x76, 0x83, 0xD6, 0x57, \ + 0x05, 0x4A, 0x3D, 0xDD, 0x81, 0x73, 0xC9, 0xEB, \ + 0x8A, 0x84, 0x39, 0xF4, 0x36, 0x0B, 0xF7} /**< The PRBS9 sequence used as packet payload. + The bytes in the sequence is in the right order, but the bits of each byte in the array is reverse. + of that found by running the PRBS9 algorithm. This is because of the endianess of the nRF5 radio. */ /**@brief Structure holding the PDU used for transmitting/receiving a PDU. */ @@ -71,7 +121,7 @@ static uint16_t m_rx_pkt_count; /** static pdu_type_t m_pdu; /**< PDU to be sent. */ static uint16_t m_event; /**< current command status - initially "ok", may be set if error detected, or to packet count. */ static bool m_new_event; /**< Command has been processed - number of not yet reported event bytes. */ -static uint8_t m_packet_length; /**< Payload length of transmitted PDU, bits 2:7 of 16-bit dtm command. */ +static uint32_t m_packet_length; /**< Payload length of transmitted PDU, bits 2:7 of 16-bit dtm command. */ static dtm_pkt_type_t m_packet_type; /**< Bits 0..1 of 16-bit transmit command, or 0xFFFFFFFF. */ static dtm_freq_t m_phys_ch; /**< 0..39 physical channel number (base 2402 MHz, Interval 2 MHz), bits 8:13 of 16-bit dtm command. */ static uint32_t m_current_time = 0; /**< Counter for interrupts from timer to ensure that the 2 bytes forming a DTM command are received within the time window. */ @@ -95,8 +145,8 @@ static uint8_t m_crcLength = RADIO_CRCCNF_LEN_Three; /** static uint32_t m_address = 0x71764129; /**< Address. */ static uint32_t m_crc_poly = 0x0000065B; /**< CRC polynomial. */ static uint32_t m_crc_init = 0x00555555; /**< Initial value for CRC calculation. */ -static uint8_t m_radio_mode = RADIO_MODE_MODE_Ble_1Mbit; /**< nRF51 specific radio mode vale. */ -static uint32_t m_txIntervaluS = 625; /**< Time between start of Tx packets (in uS). */ +static uint8_t m_radio_mode = RADIO_MODE_MODE_Ble_1Mbit; /**< nRF51 specific radio mode value. */ +static uint32_t m_txIntervaluS = 2500; /**< Time between start of Tx packets (in uS). */ /**@brief Function for verifying that a received PDU has the expected structure and content. @@ -106,7 +156,7 @@ static bool check_pdu(void) uint8_t k; // Byte pointer for running through PDU payload uint8_t pattern; // Repeating octet value in payload dtm_pkt_type_t pdu_packet_type; // Note: PDU packet type is a 4-bit field in HCI, but 2 bits in BLE DTM - uint8_t length; + uint32_t length = 0; pdu_packet_type = (dtm_pkt_type_t)(m_pdu.content[DTM_HEADER_OFFSET] & 0x0F); length = m_pdu.content[DTM_LENGTH_OFFSET]; @@ -119,7 +169,7 @@ static bool check_pdu(void) if (pdu_packet_type == DTM_PKT_PRBS9) { // Payload does not consist of one repeated octet; must compare ir with entire block into - return (memcmp(m_pdu.content+DTM_HEADER_SIZE, m_prbs_content, length) == 0); + return (memcmp(m_pdu.content + DTM_HEADER_SIZE, m_prbs_content, length) == 0); } if (pdu_packet_type == DTM_PKT_0X0F) @@ -133,7 +183,7 @@ static bool check_pdu(void) for (k = 0; k < length; k++) { - // Check repeated pattern filling the PDU payload + // Check repeated pattern filling the PDU payload if (m_pdu.content[k + 2] != pattern) { return false; @@ -171,28 +221,7 @@ static void radio_reset(void) */ static uint32_t radio_init(void) { -#ifdef NRF51 - // Handle BLE Radio tuning parameters from production for DTM if required. - // Only needed for DTM without SoftDevice, as the SoftDevice normally handles this. - // PCN-083. - if ( ((NRF_FICR->OVERRIDEEN) & FICR_OVERRIDEEN_BLE_1MBIT_Msk) == FICR_OVERRIDEEN_BLE_1MBIT_Override) - { - NRF_RADIO->OVERRIDE0 = NRF_FICR->BLE_1MBIT[0]; - NRF_RADIO->OVERRIDE1 = NRF_FICR->BLE_1MBIT[1]; - NRF_RADIO->OVERRIDE2 = NRF_FICR->BLE_1MBIT[2]; - NRF_RADIO->OVERRIDE3 = NRF_FICR->BLE_1MBIT[3]; - NRF_RADIO->OVERRIDE4 = NRF_FICR->BLE_1MBIT[4]; - } -#endif // NRF51 - - // Initializing code below is quite generic - for BLE, the values are fixed, and expressions - // are constant. Non-constant values are essentially set in radio_prepare(). - if (((m_tx_power & 0x03) != 0) || // tx_power should be a multiple of 4 - ((m_tx_power & 0xffffff00) != 0) || // Upper 24 bits are required to be zeroed - ((int8_t)m_tx_power > 4) || // Max tx_power is +4 dBm - ((int8_t)(m_tx_power & 0xff) < -40) || // Min tx_power is -40 dBm - (m_radio_mode > RADIO_MODE_MODE_Ble_1Mbit) // Values 0-2: Proprietary mode, 3 (last valid): BLE - ) + if(dtm_radio_validate(m_tx_power, m_radio_mode) != DTM_SUCCESS) { return DTM_ERROR_ILLEGAL_CONFIGURATION; } @@ -235,12 +264,7 @@ static uint32_t radio_init(void) */ static void radio_prepare(bool rx) { -#ifdef NRF51 - NRF_RADIO->TEST = 0; -#elif defined(NRF52) - NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos) | - (RADIO_MODECNF0_DTX_B1 << RADIO_MODECNF0_DTX_Pos); -#endif // NRF51 / NRF52 + dtm_turn_off_test(); NRF_RADIO->CRCPOLY = m_crc_poly; NRF_RADIO->CRCINIT = m_crc_init; NRF_RADIO->FREQUENCY = (m_phys_ch << 1) + 2; // Actual frequency (MHz): 2400 + register value @@ -265,12 +289,7 @@ static void radio_prepare(bool rx) */ static void dtm_test_done(void) { -#ifdef NRF51 - NRF_RADIO->TEST = 0; -#elif defined(NRF52) - NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos) | - (RADIO_MODECNF0_DTX_B1 << RADIO_MODECNF0_DTX_Pos); -#endif // NRF51 / NRF52 + dtm_turn_off_test(); NRF_PPI->CHENCLR = 0x01; NRF_PPI->CH[0].EEP = 0; // Break connection from timer to radio to stop transmit loop NRF_PPI->CH[0].TEP = 0; @@ -307,7 +326,7 @@ static uint32_t timer_init(void) mp_timer->SHORTS = 1 << TIMER_SHORTS_COMPARE0_CLEAR_Pos; // Clear the count every time timer reaches the CCREG0 count mp_timer->PRESCALER = 4; // Input clock is 16MHz, timer clock = 2 ^ prescale -> interval 1us mp_timer->CC[0] = m_txIntervaluS; // 625uS with 1MHz clock to the timer - mp_timer->CC[1] = UART_POLL_CYCLE; // 260uS with 1MHz clock to the timer + mp_timer->CC[1] = UART_POLL_CYCLE; // Depends on the baud rate of the UART. Default baud rate of 19200 will result in a 260uS time with 1MHz clock to the timer mp_timer->TASKS_START = 1; // Start the timer - it will be running continuously m_current_time = 0; return DTM_SUCCESS; @@ -335,13 +354,8 @@ static uint32_t dtm_vendor_specific_pkt(uint32_t vendor_cmd, dtm_freq_t vendor_o // Not a packet type, but used to indicate that a continuous carrier signal // should be transmitted by the radio. radio_prepare(TX_MODE); -#ifdef NRF51 - NRF_RADIO->TEST = (RADIO_TEST_PLL_LOCK_Enabled << RADIO_TEST_PLL_LOCK_Pos) | - (RADIO_TEST_CONST_CARRIER_Enabled << RADIO_TEST_CONST_CARRIER_Pos); -#elif defined(NRF52) - NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos) | - (RADIO_MODECNF0_DTX_B1 << RADIO_MODECNF0_DTX_Pos); -#endif // NRF51 / NRF52 + + dtm_constant_carrier(); // Shortcut between READY event and START task NRF_RADIO->SHORTS = 1 << RADIO_SHORTS_READY_START_Pos; @@ -376,8 +390,9 @@ uint32_t dtm_init(void) { return DTM_ERROR_ILLEGAL_CONFIGURATION; } - m_new_event = false; - m_state = STATE_IDLE; + m_new_event = false; + m_state = STATE_IDLE; + m_packet_length = 0; // Enable wake-up on event SCB->SCR |= SCB_SCR_SEVONPEND_Msk; @@ -393,7 +408,7 @@ uint32_t dtm_wait(void) for (;;) { - // Event may be the reception of a packet - + // Event may be the reception of a packet - // handle radio first, to give it highest priority: if (NRF_RADIO->EVENTS_END != 0) { @@ -438,19 +453,19 @@ uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t { // Save specified packet in static variable for tx/rx functions to use. // Note that BLE conformance testers always use full length packets. - m_packet_length = ((uint8_t)length & 0xFF); + m_packet_length = (m_packet_length & 0xC0) | ((uint8_t)length & 0x3F); m_packet_type = payload; m_phys_ch = freq; // Clean out any non-retrieved event that might linger from an earlier test m_new_event = true; - + // Set default event; any error will set it to LE_TEST_STATUS_EVENT_ERROR m_event = LE_TEST_STATUS_EVENT_SUCCESS; - + if (m_state == STATE_UNINITIALIZED) { - // Application has not explicitly initialized DTM, + // Application has not explicitly initialized DTM, return DTM_ERROR_UNINITIALIZED; } @@ -458,6 +473,14 @@ uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t { // Note that timer will continue running after a reset dtm_test_done(); + if (freq == 0x01) + { + m_packet_length = length << 6; + } + else + { + m_packet_length = 0; + } return DTM_SUCCESS; } @@ -478,15 +501,16 @@ uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t { // Sequencing error - only TEST_END/RESET are legal while test is running // Note: State is unchanged; ongoing test not affected - m_event = LE_TEST_STATUS_EVENT_ERROR; - return DTM_ERROR_INVALID_STATE; + m_event = LE_TEST_STATUS_EVENT_ERROR; + return DTM_ERROR_INVALID_STATE; } - if (m_phys_ch > PHYS_CH_MAX) + // Check for illegal values of m_phys_ch. Skip the check if the packet is vendor spesific. + if (payload != DTM_PKT_VENDORSPECIFIC && m_phys_ch > PHYS_CH_MAX) { // Parameter error // Note: State is unchanged; ongoing test not affected - m_event = LE_TEST_STATUS_EVENT_ERROR; + m_event = LE_TEST_STATUS_EVENT_ERROR; return DTM_ERROR_ILLEGAL_CHANNEL; } @@ -503,7 +527,8 @@ uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t if (cmd == LE_TRANSMITTER_TEST) { - if (m_packet_length > DTM_PAYLOAD_MAX_SIZE) + // Check for illegal values of m_packet_length. Skip the check if the packet is vendor spesific. + if (payload != DTM_PKT_VENDORSPECIFIC && m_packet_length > DTM_PAYLOAD_MAX_SIZE) { // Parameter error m_event = LE_TEST_STATUS_EVENT_ERROR; @@ -511,39 +536,58 @@ uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t } // Note that PDU uses 4 bits even though BLE DTM uses only 2 (the HCI SDU uses all 4) - m_pdu.content[DTM_HEADER_OFFSET] = ((uint8_t)m_packet_type & 0x0F); + m_pdu.content[DTM_HEADER_OFFSET] = ((uint8_t)m_packet_type & 0x0F); m_pdu.content[DTM_LENGTH_OFFSET] = m_packet_length; - + switch (m_packet_type) { case DTM_PKT_PRBS9: // Non-repeated, must copy entire pattern to PDU - memcpy(m_pdu.content + DTM_HEADER_SIZE, m_prbs_content, length); + memcpy(m_pdu.content + DTM_HEADER_SIZE, m_prbs_content, m_packet_length); break; - + case DTM_PKT_0X0F: // Bit pattern 00001111 repeated - memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X0F_REF_PATTERN, length); + memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X0F_REF_PATTERN, m_packet_length); break; - + case DTM_PKT_0X55: // Bit pattern 01010101 repeated - memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X55_REF_PATTERN, length); + memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X55_REF_PATTERN, m_packet_length); break; - + case DTM_PKT_VENDORSPECIFIC: // The length field is for indicating the vendor specific command to execute. // The frequency field is used for vendor specific options to the command. return dtm_vendor_specific_pkt(length, freq); - + default: - // Parameter error - m_event = LE_TEST_STATUS_EVENT_ERROR; + // Parameter error + m_event = LE_TEST_STATUS_EVENT_ERROR; return DTM_ERROR_ILLEGAL_CONFIGURATION; } // Initialize CRC value, set channel: radio_prepare(TX_MODE); + // Set the timer to the correct period. The delay between each packet is described in the + // Bluetooth Core Spsification version 4.2 Vol. 6 Part F Section 4.1.6. + if ((m_packet_length + DTM_ON_AIR_OVERHEAD_SIZE ) * 8 <= 376) + { + mp_timer->CC[0] = 625; // 625uS with 1MHz clock to the timer + } + else if ((m_packet_length + DTM_ON_AIR_OVERHEAD_SIZE ) * 8 <= 1000) + { + mp_timer->CC[0] = 1250; // 625uS with 1MHz clock to the timer + } + else if ((m_packet_length + DTM_ON_AIR_OVERHEAD_SIZE ) * 8 <= 1624) + { + mp_timer->CC[0] = 1875; // 625uS with 1MHz clock to the timer + } + else + { + mp_timer->CC[0] = 2500; // 625uS with 1MHz clock to the timer + } + // Configure PPI so that timer will activate radio every 625 us NRF_PPI->CH[0].EEP = (uint32_t)&mp_timer->EVENTS_COMPARE[0]; NRF_PPI->CH[0].TEP = (uint32_t)&NRF_RADIO->TASKS_TXEN; @@ -578,25 +622,21 @@ bool dtm_set_txpower(uint32_t new_tx_power) { // radio->TXPOWER register is 32 bits, low octet a signed value, upper 24 bits zeroed int8_t new_power8 = (int8_t)(new_tx_power & 0xFF); - + + // The two most significant bits are not sent in the 6 bit field of the DTM command. + // These two bits are 1's if and only if the tx_power is a negative number. + // All valid negative values have the fourth most significant bit as 1. + // All valid positive values have the fourth most significant bit as 0. + // By checking this bit, the two most significant bits can be determined. + new_power8 = (new_power8 & 0x30) != 0 ? (new_power8 | 0xC0) : new_power8; + if (m_state > STATE_IDLE) { // radio must be idle to change the tx power return false; } - if ((new_power8 > 4) || (new_power8 < -40)) - { - // Parameter outside valid range: nRF radio is restricted to the range -40 dBm to +4 dBm - return false; - } - - if (new_tx_power & 0x03) - { - // Parameter error: The nRF51 radio requires settings that are a multiple of 4. - return false; - } - m_tx_power = new_tx_power; + m_tx_power = new_power8; return true; } @@ -616,28 +656,8 @@ bool dtm_set_timer(uint32_t new_timer) { return false; } - if (new_timer == 0) - { - mp_timer = NRF_TIMER0; - m_timer_irq = TIMER0_IRQn; - } - else if (new_timer == 1) - { - mp_timer = NRF_TIMER1; - m_timer_irq = TIMER1_IRQn; - } - else if (new_timer == 2) - { - mp_timer = NRF_TIMER2; - m_timer_irq = TIMER2_IRQn; - } - else - { - // Parameter error: Only TIMER 0, 1, 2 provided by nRF51 - return false; - } - // New timer has been selected: - return true; + return dtm_hw_set_timer(&mp_timer, &m_timer_irq, new_timer); } -/// @} +/// @} +#endif // NRF_MODULE_ENABLED(BLE_DTM) diff --git a/components/ble/ble_dtm/ble_dtm.h b/components/ble/ble_dtm/ble_dtm.h index 76acb1e..8760551 100644 --- a/components/ble/ble_dtm/ble_dtm.h +++ b/components/ble/ble_dtm/ble_dtm.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_dtmlib_dtm DTM - Direct Test Mode + * @defgroup ble_dtm DTM - Direct Test Mode * @{ * @ingroup ble_sdk_lib * @brief Module for testing RF/PHY using DTM commands. @@ -23,9 +51,15 @@ #include #include +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif /**@brief Configuration parameters. */ +#define DTM_BITRATE UART_BAUDRATE_BAUDRATE_Baud19200/**< Serial bitrate on the UART */ #define DEFAULT_TX_POWER RADIO_TXPOWER_TXPOWER_0dBm /**< Default Transmission power using in the DTM module. */ #define DEFAULT_TIMER NRF_TIMER0 /**< Default timer used for timing. */ #define DEFAULT_TIMER_IRQn TIMER0_IRQn /**< IRQ used for timer. NOTE: MUST correspond to DEFAULT_TIMER. */ @@ -64,6 +98,43 @@ typedef uint32_t dtm_cmd_t; /**< DTM #define DTM_ERROR_ILLEGAL_CONFIGURATION 0x04 /**< Parameter out of range (legal range is function dependent). */ #define DTM_ERROR_UNINITIALIZED 0x05 /**< DTM module has not been initialized by the application. */ +/**@details The UART poll cycle in micro seconds. + * A baud rate of e.g. 19200 bits / second, and 8 data bits, 1 start/stop bit, no flow control, + * give the time to transmit a byte: 10 bits * 1/19200 = approx: 520 us. + * To ensure no loss of bytes, the UART should be polled every 260 us. + */ +#if DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud9600 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/9600/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud14400 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/14400/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud19200 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/19200/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud28800 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/28800/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud38400 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/38400/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud57600 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/57600/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud76800 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/768000/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud115200 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/115200/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud230400 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/230400/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud250000 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/250000/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud460800 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/460800/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud921600 +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/921600/2)) +#elif DTM_BITRATE == UART_BAUDRATE_BAUDRATE_Baud1M +#define UART_POLL_CYCLE ((uint32_t)(10*1e6/1e6/2)) +#else +// It is possible to find values that work for other baud rates, but the formula above is not +// guaranteed to work for all values. Suitable values may have to be found by trial and error. +#error "Unsupported baud rate set." +#endif + // Note: DTM_PKT_VENDORSPECIFIC, is not a packet type #define PACKET_TYPE_MAX DTM_PKT_0X55 /**< Highest value allowed as DTM Packet type. */ @@ -78,7 +149,7 @@ typedef uint32_t dtm_pkt_type_t; /**< Typ /**@brief Function for initializing or re-initializing DTM module - * + * * @return DTM_SUCCESS on successful initialization of the DTM module. */ uint32_t dtm_init(void); @@ -109,7 +180,7 @@ uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t /**@brief Function for reading the result of a DTM command * * @param[out] p_dtm_event Pointer to buffer for 16 bit event code according to DTM standard. - * + * * @return true: new event, false: no event since last call, this event has been read earlier */ bool dtm_event_get(dtm_event_t * p_dtm_event); @@ -117,25 +188,30 @@ bool dtm_event_get(dtm_event_t * p_dtm_event); /**@brief Function for configuring the timer to use. * - * @note Must be called when no DTM test is running. - * + * @note Must be called when no DTM test is running. + * * @param[in] new_timer Index (0..2) of timer to be used by the DTM library * - * @return true: success, new timer was selected, false: parameter error + * @return true: success, new timer was selected, false: parameter error */ -bool dtm_set_timer(uint32_t new_timer); +bool dtm_set_timer(uint32_t new_timer); /**@brief Function for configuring the transmit power. * * @note Must be called when no DTM test is running. - * + * * @param[in] new_tx_power New output level, +4..-40, in steps of 4. * * @return true: tx power setting changed, false: parameter error */ bool dtm_set_txpower(uint32_t new_tx_power); + +#ifdef __cplusplus +} +#endif + #endif // BLE_DTM_H__ /** @} */ diff --git a/components/ble/ble_dtm/ble_dtm_hw.h b/components/ble/ble_dtm/ble_dtm_hw.h new file mode 100644 index 0000000..08532f4 --- /dev/null +++ b/components/ble/ble_dtm/ble_dtm_hw.h @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_dtm_hw Direct Test Mode HW + * @{ + * @ingroup ble_sdk_lib + * @brief Module contains hardware related function for testing RF/PHY using DTM commands. + */ + +#ifndef BLE_DTM_HW_H__ +#define BLE_DTM_HW_H__ + +#include +#include +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Function for selecting a timer resource. + * This function may be called directly, or through dtm_cmd() specifying + * DTM_PKT_VENDORSPECIFIC as payload, SELECT_TIMER as length, and the timer as freq + * + * @param[out] mp_timer Pointer to timer instance used in dtm source file. + * @param[out] m_timer_irq Pointer to timer interrupt related to mp_timer. + * @param[in] new_timer Timer id for the timer to use. + * + * @retval true if the timer was successfully changed. + * @retval false if the error occurs. + */ + +bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer); + + +/**@brief Function for turning off radio test. + * This function is platform depending. For now only nRF51 requieres this special function. + */ +void dtm_turn_off_test(void); + + +/**@brief Function for setting constant carrier in radio settings. + * This function is used to handle vendor specific command testing continous carrier without + * a modulated signal. + */ +void dtm_constant_carrier(void); + + +/**@brief Function for validating tx power and radio move settings. + * @param[in] m_tx_power TX power for transmission test. + * @param[in] m_radio_mode Radio mode value. + * + * @retval DTM_SUCCESS if input parameters values are correct. + * @retval DTM_ERROR_ILLEGAL_CONFIGURATION if input parameters values are not correct. + */ +uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode); + +#ifdef __cplusplus +} +#endif + +#endif // BLE_DTM_HW_H__ + +/** @} */ diff --git a/components/ble/ble_dtm/ble_dtm_hw_nrf51.c b/components/ble/ble_dtm/ble_dtm_hw_nrf51.c new file mode 100644 index 0000000..b6a43bb --- /dev/null +++ b/components/ble/ble_dtm/ble_dtm_hw_nrf51.c @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_dtm_hw.h" +#include "ble_dtm.h" +#include +#include +#include "nrf.h" + + +void dtm_turn_off_test() +{ + NRF_RADIO->TEST = 0; +} + + +void dtm_constant_carrier() +{ + NRF_RADIO->TEST = (RADIO_TEST_PLL_LOCK_Enabled << RADIO_TEST_PLL_LOCK_Pos) | + (RADIO_TEST_CONST_CARRIER_Enabled << RADIO_TEST_CONST_CARRIER_Pos); +} + + +uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode) +{ + // Handle BLE Radio tuning parameters from production for DTM if required. + // Only needed for DTM without SoftDevice, as the SoftDevice normally handles this. + // PCN-083. + if ( ((NRF_FICR->OVERRIDEEN) & FICR_OVERRIDEEN_BLE_1MBIT_Msk) == FICR_OVERRIDEEN_BLE_1MBIT_Override) + { + NRF_RADIO->OVERRIDE0 = NRF_FICR->BLE_1MBIT[0]; + NRF_RADIO->OVERRIDE1 = NRF_FICR->BLE_1MBIT[1]; + NRF_RADIO->OVERRIDE2 = NRF_FICR->BLE_1MBIT[2]; + NRF_RADIO->OVERRIDE3 = NRF_FICR->BLE_1MBIT[3]; + NRF_RADIO->OVERRIDE4 = NRF_FICR->BLE_1MBIT[4]; + } + + // Initializing code below is quite generic - for BLE, the values are fixed, and expressions + // are constant. Non-constant values are essentially set in radio_prepare(). + if (!(m_tx_power == RADIO_TXPOWER_TXPOWER_0dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Pos4dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg30dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg20dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg16dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg12dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg8dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg4dBm + ) || + (m_radio_mode > RADIO_MODE_MODE_Ble_1Mbit) // Values 0 - 2: Proprietary mode, 3 (last valid): BLE + ) + { + return DTM_ERROR_ILLEGAL_CONFIGURATION; + } + + return DTM_SUCCESS; +} + + +bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer) +{ + if (new_timer == 0) + { + *mp_timer = NRF_TIMER0; + *m_timer_irq = TIMER0_IRQn; + } + else if (new_timer == 1) + { + *mp_timer = NRF_TIMER1; + *m_timer_irq = TIMER1_IRQn; + } + else if (new_timer == 2) + { + *mp_timer = NRF_TIMER2; + *m_timer_irq = TIMER2_IRQn; + } + else + { + // Parameter error: Only TIMER 0, 1, 2 provided by nRF51 + return false; + } + // New timer has been selected: + return true; +} + diff --git a/components/ble/ble_dtm/ble_dtm_hw_nrf52.c b/components/ble/ble_dtm/ble_dtm_hw_nrf52.c new file mode 100644 index 0000000..c4346be --- /dev/null +++ b/components/ble/ble_dtm/ble_dtm_hw_nrf52.c @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_dtm_hw.h" +#include "ble_dtm.h" +#include +#include +#include "nrf.h" + + +void dtm_turn_off_test() +{ +} + + +void dtm_constant_carrier() +{ +NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos) | + (RADIO_MODECNF0_DTX_Center << RADIO_MODECNF0_DTX_Pos); +} + + +uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode) +{ + // Initializing code below is quite generic - for BLE, the values are fixed, and expressions + // are constant. Non-constant values are essentially set in radio_prepare(). + if (!(m_tx_power == RADIO_TXPOWER_TXPOWER_0dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Pos4dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg30dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg20dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg16dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg12dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg8dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg4dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Pos3dBm || + m_tx_power == RADIO_TXPOWER_TXPOWER_Neg40dBm + ) || + (m_radio_mode > RADIO_MODE_MODE_Ble_1Mbit) // Values 0 - 2: Proprietary mode, 3 (last valid): BLE + ) + { + return DTM_ERROR_ILLEGAL_CONFIGURATION; + } + + return DTM_SUCCESS; +} + + +bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer) +{ + if (new_timer == 0) + { + *mp_timer = NRF_TIMER0; + *m_timer_irq = TIMER0_IRQn; + } + else if (new_timer == 1) + { + *mp_timer = NRF_TIMER1; + *m_timer_irq = TIMER1_IRQn; + } + else if (new_timer == 2) + { + *mp_timer = NRF_TIMER2; + *m_timer_irq = TIMER2_IRQn; + } + else if (new_timer == 3) + { + *mp_timer = NRF_TIMER3; + *m_timer_irq = TIMER3_IRQn; + } + else if (new_timer == 4) + { + *mp_timer = NRF_TIMER4; + *m_timer_irq = TIMER4_IRQn; + } + else + { + // Parameter error: Only TIMER 0, 1, 2, 3 and 4 provided by nRF52 + return false; + } + // New timer has been selected: + return true; +} diff --git a/components/ble/ble_error_log/ble_error_log.c b/components/ble/ble_error_log/ble_error_log.c index 0e26140..5755787 100644 --- a/components/ble/ble_error_log/ble_error_log.c +++ b/components/ble/ble_error_log/ble_error_log.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include diff --git a/components/ble/ble_error_log/ble_error_log.h b/components/ble/ble_error_log/ble_error_log.h index 825046f..efab897 100644 --- a/components/ble/ble_error_log/ble_error_log.h +++ b/components/ble/ble_error_log/ble_error_log.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -28,6 +56,10 @@ #include #include "ble_flash.h" +#ifdef __cplusplus +extern "C" { +#endif + #define ERROR_MESSAGE_LENGTH 128 /**< Length of error message to stored. */ #define STACK_DUMP_LENGTH 256 /**< Length of stack to be stored at max: 64 entries of 4 bytes each. */ #define FLASH_PAGE_ERROR_LOG (BLE_FLASH_PAGE_END - 2) /**< Address in flash where stack trace can be stored. */ @@ -49,7 +81,7 @@ typedef struct /**@brief Function for writing the file name/message, line number, and current program stack * to flash. - * + * * @note This function will force the writing to flash, and disregard any radio communication. * USE THIS FUNCTION WITH CARE. * @@ -64,6 +96,11 @@ typedef struct uint32_t ble_error_log_write(uint32_t err_code, const uint8_t * p_message, uint16_t line_number); + +#ifdef __cplusplus +} +#endif + #endif /* BLE_ERROR_LOG_H__ */ /** @} */ diff --git a/components/ble/ble_racp/ble_racp.c b/components/ble/ble_racp/ble_racp.c index 047c855..dbb9d46 100644 --- a/components/ble/ble_racp/ble_racp.c +++ b/components/ble/ble_racp/ble_racp.c @@ -1,14 +1,44 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_RACP) #include "ble_racp.h" #include @@ -19,7 +49,7 @@ void ble_racp_decode(uint8_t data_len, uint8_t * p_data, ble_racp_value_t * p_ra p_racp_val->operator = 0xFF; p_racp_val->operand_len = 0; p_racp_val->p_operand = NULL; - + if (data_len > 0) { p_racp_val->opcode = p_data[0]; @@ -54,3 +84,4 @@ uint8_t ble_racp_encode(const ble_racp_value_t * p_racp_val, uint8_t * p_data) return len; } +#endif // NRF_MODULE_ENABLED(BLE_RACP) diff --git a/components/ble/ble_racp/ble_racp.h b/components/ble/ble_racp/ble_racp.h index d3296e4..da64a15 100644 --- a/components/ble/ble_racp/ble_racp.h +++ b/components/ble/ble_racp/ble_racp.h @@ -1,17 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_lib_racp Record Access Control Point + * @defgroup ble_racp Record Access Control Point * @{ * @ingroup ble_sdk_lib * @brief Record Access Control Point library. @@ -24,7 +53,10 @@ #include #include "ble.h" #include "ble_types.h" -#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif /**@brief Record Access Control Point opcodes. */ #define RACP_OPCODE_RESERVED 0 /**< Record Access Control Point opcode - Reserved for future use. */ @@ -36,26 +68,29 @@ #define RACP_OPCODE_RESPONSE_CODE 6 /**< Record Access Control Point opcode - Response code. */ /**@brief Record Access Control Point operators. */ -#define RACP_OPERATOR_NULL 0 /**< Record Access Control Point operator - Null. */ -#define RACP_OPERATOR_ALL 1 /**< Record Access Control Point operator - All records. */ -#define RACP_OPERATOR_LESS_OR_EQUAL 2 /**< Record Access Control Point operator - Less than or equal to. */ -#define RACP_OPERATOR_GREATER_OR_EQUAL 3 /**< Record Access Control Point operator - Greater than or equal to. */ -#define RACP_OPERATOR_RANGE 4 /**< Record Access Control Point operator - Within range of (inclusive). */ -#define RACP_OPERATOR_FIRST 5 /**< Record Access Control Point operator - First record (i.e. oldest record). */ -#define RACP_OPERATOR_LAST 6 /**< Record Access Control Point operator - Last record (i.e. most recent record). */ -#define RACP_OPERATOR_RFU_START 7 /**< Record Access Control Point operator - Start of Reserved for Future Use area. */ +#define RACP_OPERATOR_NULL 0 /**< Record Access Control Point operator - Null. */ +#define RACP_OPERATOR_ALL 1 /**< Record Access Control Point operator - All records. */ +#define RACP_OPERATOR_LESS_OR_EQUAL 2 /**< Record Access Control Point operator - Less than or equal to. */ +#define RACP_OPERATOR_GREATER_OR_EQUAL 3 /**< Record Access Control Point operator - Greater than or equal to. */ +#define RACP_OPERATOR_RANGE 4 /**< Record Access Control Point operator - Within range of (inclusive). */ +#define RACP_OPERATOR_FIRST 5 /**< Record Access Control Point operator - First record (i.e. oldest record). */ +#define RACP_OPERATOR_LAST 6 /**< Record Access Control Point operator - Last record (i.e. most recent record). */ +#define RACP_OPERATOR_RFU_START 7 /**< Record Access Control Point operator - Start of Reserved for Future Use area. */ + +/**@brief Record Access Control Point Operand Filter Type Value. */ +#define RACP_OPERAND_FILTER_TYPE_TIME_OFFSET 1 /**< Record Access Control Point Operand Filter Type Value - Time Offset- */ /**@brief Record Access Control Point response codes. */ -#define RACP_RESPONSE_RESERVED 0 /**< Record Access Control Point response code - Reserved for future use. */ -#define RACP_RESPONSE_SUCCESS 1 /**< Record Access Control Point response code - Successful operation. */ -#define RACP_RESPONSE_OPCODE_UNSUPPORTED 2 /**< Record Access Control Point response code - Unsupported op code received. */ -#define RACP_RESPONSE_INVALID_OPERATOR 3 /**< Record Access Control Point response code - Operator not valid for service. */ -#define RACP_RESPONSE_OPERATOR_UNSUPPORTED 4 /**< Record Access Control Point response code - Unsupported operator. */ -#define RACP_RESPONSE_INVALID_OPERAND 5 /**< Record Access Control Point response code - Operand not valid for service. */ -#define RACP_RESPONSE_NO_RECORDS_FOUND 6 /**< Record Access Control Point response code - No matching records found. */ -#define RACP_RESPONSE_ABORT_FAILED 7 /**< Record Access Control Point response code - Abort could not be completed. */ -#define RACP_RESPONSE_PROCEDURE_NOT_DONE 8 /**< Record Access Control Point response code - Procedure could not be completed. */ -#define RACP_RESPONSE_OPERAND_UNSUPPORTED 9 /**< Record Access Control Point response code - Unsupported operand. */ +#define RACP_RESPONSE_RESERVED 0 /**< Record Access Control Point response code - Reserved for future use. */ +#define RACP_RESPONSE_SUCCESS 1 /**< Record Access Control Point response code - Successful operation. */ +#define RACP_RESPONSE_OPCODE_UNSUPPORTED 2 /**< Record Access Control Point response code - Unsupported op code received. */ +#define RACP_RESPONSE_INVALID_OPERATOR 3 /**< Record Access Control Point response code - Operator not valid for service. */ +#define RACP_RESPONSE_OPERATOR_UNSUPPORTED 4 /**< Record Access Control Point response code - Unsupported operator. */ +#define RACP_RESPONSE_INVALID_OPERAND 5 /**< Record Access Control Point response code - Operand not valid for service. */ +#define RACP_RESPONSE_NO_RECORDS_FOUND 6 /**< Record Access Control Point response code - No matching records found. */ +#define RACP_RESPONSE_ABORT_FAILED 7 /**< Record Access Control Point response code - Abort could not be completed. */ +#define RACP_RESPONSE_PROCEDURE_NOT_DONE 8 /**< Record Access Control Point response code - Procedure could not be completed. */ +#define RACP_RESPONSE_OPERAND_UNSUPPORTED 9 /**< Record Access Control Point response code - Unsupported operand. */ /**@brief Record Access Control Point value structure. */ typedef struct @@ -90,6 +125,11 @@ void ble_racp_decode(uint8_t data_len, uint8_t * p_data, ble_racp_value_t * p_ra */ uint8_t ble_racp_encode(const ble_racp_value_t * p_racp_val, uint8_t * p_data); + +#ifdef __cplusplus +} +#endif + #endif // BLE_RACP_H__ /** @} */ diff --git a/components/ble/ble_radio_notification/ble_radio_notification.c b/components/ble/ble_radio_notification/ble_radio_notification.c index 96ece18..fa297b7 100644 --- a/components/ble/ble_radio_notification/ble_radio_notification.c +++ b/components/ble/ble_radio_notification/ble_radio_notification.c @@ -1,12 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_radio_notification.h" @@ -27,8 +56,8 @@ void SWI1_IRQHandler(void) } -uint32_t ble_radio_notification_init(nrf_app_irq_priority_t irq_priority, - nrf_radio_notification_distance_t distance, +uint32_t ble_radio_notification_init(uint32_t irq_priority, + uint8_t distance, ble_radio_notification_evt_handler_t evt_handler) { uint32_t err_code; diff --git a/components/ble/ble_radio_notification/ble_radio_notification.h b/components/ble/ble_radio_notification/ble_radio_notification.h index dd47b36..8272eb4 100644 --- a/components/ble/ble_radio_notification/ble_radio_notification.h +++ b/components/ble/ble_radio_notification/ble_radio_notification.h @@ -1,12 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -24,6 +53,10 @@ #include #include "nrf_soc.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Application radio notification event handler type. */ typedef void (*ble_radio_notification_evt_handler_t) (bool radio_active); @@ -36,10 +69,15 @@ typedef void (*ble_radio_notification_evt_handler_t) (bool radio_active); * * @return NRF_SUCCESS on successful initialization, otherwise an error code. */ -uint32_t ble_radio_notification_init(nrf_app_irq_priority_t irq_priority, - nrf_radio_notification_distance_t distance, +uint32_t ble_radio_notification_init(uint32_t irq_priority, + uint8_t distance, ble_radio_notification_evt_handler_t evt_handler); + +#ifdef __cplusplus +} +#endif + #endif // BLE_RADIO_NOTIFICATION_H__ /** @} */ diff --git a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c b/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c new file mode 100644 index 0000000..5c57bbc --- /dev/null +++ b/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c @@ -0,0 +1,365 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA. + * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working. + */ + +#include "ancs_app_attr_get.h" +#include "nrf_ble_ancs_c.h" +#include "ancs_tx_buffer.h" +#include "sdk_macros.h" +#include "nrf_log.h" +#include "string.h" + +#define GATTC_OPCODE_SIZE 1 /**< Size of the GATTC OPCODE. */ +#define GATTC_ATTR_HANDLE_SIZE 4 /**< Size of the Attribute handle Size. */ +#define ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX (GATT_MTU_SIZE_DEFAULT - GATTC_OPCODE_SIZE - GATTC_ATTR_HANDLE_SIZE) /**< Maximum Length of the data we can send in one write. */ + + +/**@brief Enum to keep track of the state based encoding while requesting App attributes. */ +typedef enum +{ + APP_ATTR_COMMAND_ID, /**< Currently encoding the Command ID. */ + APP_ATTR_APP_ID, /**< Currently encoding the App ID. */ + APP_ATTR_ATTR_ID, /**< Currently encoding the Attribute ID. */ + APP_ATTR_DONE /**< Encoding done. */ +}encode_app_attr_t; + + +/**@brief Function for determening if an attribute is desired to get. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @return True If it is requested + * @return False If it is not be requested. +*/ +static bool app_attr_is_requested(ble_ancs_c_t * p_ancs, uint32_t attr_id) +{ + if(p_ancs->ancs_app_attr_list[attr_id].get == true) + { + return true; + } + return false; +} + +/**@brief Function for counting the number of attributes that will be requested upon a Get App Attribute. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @return Number of attributes that will be requested upon a Get App Attribute. +*/ +static uint32_t app_attr_nb_to_get(ble_ancs_c_t * p_ancs) +{ + uint32_t attr_nb_to_get = 0; + for(uint32_t i = 0; i < (sizeof(p_ancs->ancs_app_attr_list)/sizeof(ble_ancs_c_attr_list_t)); i++) + { + if(app_attr_is_requested(p_ancs,i)) + { + attr_nb_to_get++; + } + } + return attr_nb_to_get; +} + + +/**@brief Function for encoding the Command ID as part of assembling a "Get App Attributes" command. + * + * @param[in] conn_handle Connection handle for where the prepared write will be executed. + * @param[in] handle_value The handle that will receive the execute command. + * @param[in] p_offset Pointer to the offset for the write. + * @param[in] p_index Pointer to the length encoded so far for the current write. + * @param[in,out] p_msg Pointer to the tx message that has been filled out and will be added to + * tx queue in this function. + */ +static void queued_write_tx_message(uint16_t conn_handle, + uint16_t handle_value, + uint16_t * p_offset, + uint32_t * p_index, + tx_message_t * p_msg) +{ + NRF_LOG_DEBUG("Starting new TX message.\r\n"); + + p_msg->conn_handle = conn_handle; + p_msg->type = WRITE_REQ; + p_msg->req.write_req.gattc_params.len = *p_index; + p_msg->req.write_req.gattc_params.handle = handle_value; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + + p_msg->req.write_req.gattc_params.offset = *p_offset; + + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_PREP_WRITE_REQ; + + tx_buffer_insert(p_msg); +} + + +/**@brief Function for encoding the Command ID as part of assembling a "Get App Attributes" command. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] p_index Pointer to the length encoded so far for the current write. + * @param[in] p_offset Pointer to the accumulated offset for the next write. + * @param[in,out] p_msg Pointer to the tx message that will be filled out in this function. + */ +static encode_app_attr_t app_attr_encode_cmd_id(ble_ancs_c_t * p_ancs, + uint32_t * index, + tx_message_t * p_msg) +{ + NRF_LOG_DEBUG("Encoding Command ID\r\n"); + + // Encode Command ID. + p_msg->req.write_req.gattc_value[(*index)++] = BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES; + return APP_ATTR_APP_ID; +} + +/**@brief Function for encoding the App Identifier as part of assembling a "Get App Attributes" command. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] p_app_id The App ID for the App which we will request App Attributes for. + * @param[in] app_id_len Length of the App ID. + * @param[in] p_index Pointer to the length encoded so far for the current write. + * @param[in] p_offset Pointer to the accumulated offset for the next write. + * @param[in] p_app_id_bytes_encoded_count Variable to keep count of the encoded APP ID bytes. + * As long as it is lower than the length of the App ID, + * parsing will continue. + */ +static encode_app_attr_t app_attr_encode_app_id(ble_ancs_c_t * p_ancs, + uint32_t * p_index, + uint16_t * p_offset, + tx_message_t * p_msg, + const uint8_t * p_app_id, + const uint32_t app_id_len, + uint32_t * p_app_id_bytes_encoded_count) +{ + NRF_LOG_DEBUG("Encoding APP ID\r\n"); + if(*p_index >= ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX) + { + queued_write_tx_message(p_ancs->conn_handle, p_ancs->service.control_point_char.handle_value, p_offset, p_index, p_msg); + *(p_offset) += *p_index; + *p_index = 0; + } + + //Encode App Identifier. + if(*p_app_id_bytes_encoded_count == app_id_len) + { + p_msg->req.write_req.gattc_value[(*p_index)++] = '\0'; + (*p_app_id_bytes_encoded_count)++; + } + NRF_LOG_DEBUG("%c\r\n", p_app_id[(*p_app_id_bytes_encoded_count)]); + if(*p_app_id_bytes_encoded_count < app_id_len) + { + p_msg->req.write_req.gattc_value[(*p_index)++] = p_app_id[(*p_app_id_bytes_encoded_count)++]; + } + if(*p_app_id_bytes_encoded_count > app_id_len) + { + return APP_ATTR_ATTR_ID; + } + return APP_ATTR_APP_ID; +} + +/**@brief Function for encoding the Attribute ID as part of assembling a "Get App Attributes" command. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * + * @param[in] p_index Pointer to the length encoded so far for the current write. + * @param[in] p_offset Pointer to the accumulated offset for the next write. + * @param[in,out] p_msg Pointer to the tx message that will be filled out in this function. + * @param[in] p_attr_count Pointer to a variable that iterates the possible App Attributes. + */ +static encode_app_attr_t app_attr_encode_attr_id(ble_ancs_c_t * p_ancs, + uint32_t * p_index, + uint16_t * p_offset, + tx_message_t * p_msg, + uint32_t * p_attr_count, + uint32_t * attr_get_total_nb) +{ + NRF_LOG_DEBUG("Encoding Attribute ID\r\n"); + if((*p_index) >= ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX) + { + queued_write_tx_message(p_ancs->conn_handle, + p_ancs->service.control_point_char.handle_value, + p_offset, p_index, p_msg); + *(p_offset) += *p_index; + *p_index = 0; + } + //Encode Attribute ID. + if (*p_attr_count < BLE_ANCS_NB_OF_APP_ATTR) + { + if (app_attr_is_requested(p_ancs, *p_attr_count)) + { + p_msg->req.write_req.gattc_value[(*p_index)] = *p_attr_count; + p_ancs->number_of_requested_attr++; + (*p_index)++; + NRF_LOG_DEBUG("offset %i\r\n", *p_offset); + } + (*p_attr_count)++; + } + if (*p_attr_count == BLE_ANCS_NB_OF_APP_ATTR) + { + return APP_ATTR_DONE; + } + return APP_ATTR_APP_ID; +} + +/**@brief Function for writing the execute write command to a handle for a given connection. + * + * @param[in] conn_handle Connection handle for where the prepared write will be executed. + * @param[in] handle_value The handle that will receive the execute command. + * @param[in] p_msg Pointer to the message that will be filled out in this function and then + * added to the tx queue. + */ +static void app_attr_execute_write(uint16_t conn_handle, uint16_t handle_value, tx_message_t * p_msg) +{ + NRF_LOG_DEBUG("Sending Execute Write.\r\n"); + memset(p_msg,0,sizeof(tx_message_t)); + + p_msg->req.write_req.gattc_params.handle = handle_value; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_EXEC_WRITE_REQ; + p_msg->req.write_req.gattc_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE; + + p_msg->req.write_req.gattc_params.len = 0; + p_msg->conn_handle = conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_insert(p_msg); +} + + +/**@brief Function for sending a get App Attributes request. + * + * @details Since the APP id may not fit in a single write, we use long write + * with a state machine to encode the Get App Attribute request. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] p_app_id The App ID for the App which we will request App Attributes for. + * @param[in] app_id_len Length of the App ID. + * +*/ +static uint32_t app_attr_get(ble_ancs_c_t * p_ancs, + const uint8_t * p_app_id, + uint32_t app_id_len) +{ + uint32_t index = 0; + uint32_t attr_bytes_encoded_count = 0; + uint16_t offset = 0; + uint32_t app_id_bytes_encoded_count = 0; + encode_app_attr_t state = APP_ATTR_COMMAND_ID; + p_ancs->number_of_requested_attr = 0; + uint32_t attr_get_total_nb = app_attr_nb_to_get(p_ancs); + tx_message_t p_msg; + memset(&p_msg,0,sizeof(tx_message_t)); + + NRF_LOG_DEBUG("Attribute Get Started.\r\n"); + while(state != APP_ATTR_DONE) + { + switch(state) + { + case APP_ATTR_COMMAND_ID: + state = app_attr_encode_cmd_id(p_ancs, + &index, + &p_msg); + break; + case APP_ATTR_APP_ID: + state = app_attr_encode_app_id(p_ancs, + &index, + &offset, + &p_msg, + p_app_id, + app_id_len, + &app_id_bytes_encoded_count); + break; + case APP_ATTR_ATTR_ID: + state = app_attr_encode_attr_id(p_ancs, + &index, + &offset, + &p_msg, + &attr_bytes_encoded_count, + &attr_get_total_nb); + break; + case APP_ATTR_DONE: + break; + default: + break; + } + } + queued_write_tx_message(p_ancs->conn_handle, + p_ancs->service.control_point_char.handle_value, + &offset, + &index, + &p_msg); + + app_attr_execute_write(p_ancs->conn_handle, + p_ancs->service.control_point_char.handle_value, + &p_msg); + + p_ancs->parse_info.expected_number_of_attrs = p_ancs->number_of_requested_attr; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ancs_c_app_attr_request(ble_ancs_c_t * p_ancs, + const uint8_t * p_app_id, + uint32_t len) +{ + uint32_t err_code; + + if(len == 0) + { + return NRF_ERROR_DATA_SIZE; + } + if(p_app_id[len] != '\0') // App id to be requestes must be NULL terminated + { + return NRF_ERROR_INVALID_PARAM; + } + + p_ancs->parse_info.parse_state = COMMAND_ID; + err_code = app_attr_get(p_ancs, p_app_id, len); + VERIFY_SUCCESS(err_code); + return NRF_SUCCESS; +} diff --git a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h b/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h new file mode 100644 index 0000000..85b4f5a --- /dev/null +++ b/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANCS_APP_ATTR_GET_H__ +#define ANCS_APP_ATTR_GET_H__ + +#include "nrf_ble_ancs_c.h" +/** @file + * + * @addtogroup ble_ancs_c + * @{ + */ + +/**@brief Function for requesting attributes for an app. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] app_id App identifier of the app for which to request app attributes. + * @param[in] len Length of the app identifier. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +uint32_t ancs_c_app_attr_request(ble_ancs_c_t * p_ancs, + const uint8_t * app_id, + uint32_t len); + +/** @} */ + +#endif // ANCS_APP_ATTR_GET_H__ + diff --git a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c b/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c new file mode 100644 index 0000000..c37b072 --- /dev/null +++ b/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c @@ -0,0 +1,410 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA. + * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working. + */ + + #include "nrf_ble_ancs_c.h" + #include "ancs_attr_parser.h" + #include "nrf_log.h" + + +static bool all_req_attrs_parsed(ble_ancs_c_t * p_ancs) +{ + if (p_ancs->parse_info.expected_number_of_attrs == 0) + { + return true; + } + return false; +} + +static bool attr_is_requested(ble_ancs_c_t * p_ancs, ble_ancs_c_attr_t attr) +{ + if(p_ancs->parse_info.p_attr_list[attr.attr_id].get == true) + // || p_ancs->ancs_app_attr_list[attr.attr_id].get == true) + { + return true; + } + return false; +} + + +/**@brief Function for parsing command id and notification id. + * Used in the @ref parse_get_notif_attrs_response state machine. + * + * @details UID and command ID will be received only once at the beginning of the first + * GATTC notification of a new attribute request for a given iOS notification. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. + * + * @return The next parse state. + */ +static ble_ancs_c_parse_state_t command_id_parse(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + uint32_t * index) +{ + ble_ancs_c_parse_state_t parse_state; + + p_ancs->parse_info.command_id = (ble_ancs_c_cmd_id_val_t) p_data_src[(*index)++]; + + switch (p_ancs->parse_info.command_id) + { + case BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES: + p_ancs->evt.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE; + p_ancs->parse_info.p_attr_list = p_ancs->ancs_notif_attr_list; + p_ancs->parse_info.nb_of_attr = BLE_ANCS_NB_OF_NOTIF_ATTR; + parse_state = NOTIF_UID; + break; + + case BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES: + p_ancs->evt.evt_type = BLE_ANCS_C_EVT_APP_ATTRIBUTE; + p_ancs->parse_info.p_attr_list = p_ancs->ancs_app_attr_list; + p_ancs->parse_info.nb_of_attr = BLE_ANCS_NB_OF_APP_ATTR; + parse_state = APP_ID; + break; + + default: + //no valid command_id, abort the rest of the parsing procedure. + NRF_LOG_DEBUG("[ANCS]: Invalid Command ID"); + parse_state = DONE; + break; + } + return parse_state; +} + + +static ble_ancs_c_parse_state_t notif_uid_parse(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + uint32_t * index) +{ + p_ancs->evt.notif_uid = uint32_decode(&p_data_src[*index]); + *index += sizeof(uint32_t); + return ATTR_ID; +} + +static ble_ancs_c_parse_state_t app_id_parse(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + uint32_t * index) +{ + p_ancs->evt.app_id[p_ancs->parse_info.current_app_id_index] = p_data_src[(*index)++]; + + if(p_ancs->evt.app_id[p_ancs->parse_info.current_app_id_index] != '\0') + { + p_ancs->parse_info.current_app_id_index++; + return APP_ID; + } + else + { + return ATTR_ID; + } +} + +/**@brief Function for parsing the id of an iOS attribute. + * Used in the @ref parse_get_notif_attrs_response state machine. + * + * @details We only request attributes that are registered with @ref ble_ancs_c_attr_add + * once they have been reveiced we stop parsing. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. + * + * @return The next parse state. + */ +static ble_ancs_c_parse_state_t attr_id_parse(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + uint32_t * index) +{ + p_ancs->evt.attr.attr_id = p_data_src[(*index)++]; + p_ancs->evt.attr.p_attr_data = p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].p_attr_data; + + if(p_ancs->evt.attr.attr_id > p_ancs->parse_info.nb_of_attr) + { + return DONE; + } + + if (all_req_attrs_parsed(p_ancs)) + { + NRF_LOG_DEBUG("[ANCS]: All requested attributes received\n\r"); + return DONE; + } + else + { + if (attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + p_ancs->parse_info.expected_number_of_attrs--; + } + NRF_LOG_DEBUG("[ANCS]: Attribute ID %i \n\r", p_ancs->evt.attr.attr_id); + return ATTR_LEN1; + } +} + + +/**@brief Function for parsing the length of an iOS attribute. + * Used in the @ref parse_get_notif_attrs_response state machine. + * + * @details The Length is 2 bytes. Since there is a chance we reveice the bytes in two different + * GATTC notifications, we parse only the first byte here and then set the state machine + * ready to parse the next byte. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. + * + * @return The next parse state. + */ +static ble_ancs_c_parse_state_t attr_len1_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index) +{ + p_ancs->evt.attr.attr_len = p_data_src[(*index)++]; + return ATTR_LEN2; +} + +/**@brief Function for parsing the length of an iOS attribute. + * Used in the @ref parse_get_notif_attrs_response state machine. + * + * @details Second byte of the length field. If the length is zero, it means that the attribute is not + * present and the state machine is set to parse the next attribute. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. + * + * @return The next parse state. + */ +static ble_ancs_c_parse_state_t attr_len2_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index) +{ + p_ancs->evt.attr.attr_len |= (p_data_src[(*index)++] << 8); + p_ancs->parse_info.current_attr_index = 0; + + if (p_ancs->evt.attr.attr_len != 0) + { + return ATTR_DATA; + } + else + { + + NRF_LOG_DEBUG("[ANCS]: Attribute LEN %i \n\r", p_ancs->evt.attr.attr_len); + if(attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + p_ancs->evt_handler(&p_ancs->evt); + } + if(all_req_attrs_parsed(p_ancs)) + { + return DONE; + } + else + { + return ATTR_ID; + } + } +} + +/* +static ble_ancs_c_parse_state_t skip_data + if (!attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + // Since this attribute is not in the list of requested attrtibutes, + // We can not risk writing to the attributes memory location. + if (p_ancs->current_attr_index < p_ancs->evt.attr.attr_len) + { + p_ancs->current_attr_index++; + (*index)++; + } + } +*/ + +static void attr_terminate(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index) +{ + if (p_ancs->parse_info.current_attr_index == p_ancs->evt.attr.attr_len) + { + p_ancs->evt.attr.p_attr_data[p_ancs->parse_info.current_attr_index] = '\0'; + } +// if (p_ancs->current_attr_index == p_ancs->p_attr_list[p_ancs->evt.attr.attr_id].attr_len) + else + { + p_ancs->evt.attr.p_attr_data[p_ancs->parse_info.current_attr_index - 1] = '\0'; + } +} + +/**@brief Function for parsing the data of an iOS attribute. + * Used in the @ref parse_get_notif_attrs_response state machine. + * + * @details Read the data of the attribute into our local buffer. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed. + * + * @return The next parse state. + */ +static ble_ancs_c_parse_state_t attr_data_parse(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + uint32_t * index) +{ + + // We have not reached the end of the attribute, nor our max allocated internal size. + // Proceed with copying data over to our buffer. + if ( (p_ancs->parse_info.current_attr_index < p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len) + && (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len)) + { + p_ancs->evt.attr.p_attr_data[p_ancs->parse_info.current_attr_index++] = p_data_src[(*index)++]; + } + + // We have reached the end of the attribute, or our max allocated internal size. + // Stop copying data over to our buffer. NUL-terminate at the current index. + if ( (p_ancs->parse_info.current_attr_index == p_ancs->evt.attr.attr_len) || + (p_ancs->parse_info.current_attr_index == p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len)) + { + if (attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + attr_terminate(p_ancs, p_data_src, index); + } + + // If our max buffer size is smaller than the remaining attribute data, we must + // increase index to skip the data until the start of the next attribute. + if (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len) + { + return ATTR_SKIP; + } + NRF_LOG_DEBUG("[ANCS]: Attribute finished!\n\r"); + if(attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + p_ancs->evt_handler(&p_ancs->evt); + } + if(all_req_attrs_parsed(p_ancs)) + { + return DONE; + } + else + { + return ATTR_ID; + } + } + return ATTR_DATA; +} + + +static ble_ancs_c_parse_state_t attr_skip(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index) +{ + // We have not reached the end of the attribute, nor our max allocated internal size. + // Proceed with copying data over to our buffer. + if (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len) + { + p_ancs->parse_info.current_attr_index++; + (*index)++; + } + // At the end of the attribute, determine if it should be passed to event handler and + // continue parsing the next attribute ID if we are not done with all the attributes. + if (p_ancs->parse_info.current_attr_index == p_ancs->evt.attr.attr_len) + { + if(attr_is_requested(p_ancs, p_ancs->evt.attr)) + { + p_ancs->evt_handler(&p_ancs->evt); + } + if(all_req_attrs_parsed(p_ancs)) + { + return DONE; + } + else + { + return ATTR_ID; + } + } + return ATTR_SKIP; +} + + +void ancs_parse_get_attrs_response(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + const uint16_t hvx_data_len) +{ + uint32_t index; + + for (index = 0; index < hvx_data_len;) + { + switch (p_ancs->parse_info.parse_state) + { + case COMMAND_ID: + p_ancs->parse_info.parse_state = command_id_parse(p_ancs, p_data_src, &index); + break; + + case NOTIF_UID: + p_ancs->parse_info.parse_state = notif_uid_parse(p_ancs, p_data_src, &index); + break; + + case APP_ID: + p_ancs->parse_info.parse_state = app_id_parse(p_ancs, p_data_src, &index); + break; + + case ATTR_ID: + p_ancs->parse_info.parse_state = attr_id_parse(p_ancs, p_data_src, &index); + break; + + case ATTR_LEN1: + p_ancs->parse_info.parse_state = attr_len1_parse(p_ancs, p_data_src, &index); + break; + + case ATTR_LEN2: + p_ancs->parse_info.parse_state = attr_len2_parse(p_ancs, p_data_src, &index); + break; + + case ATTR_DATA: + p_ancs->parse_info.parse_state = attr_data_parse(p_ancs, p_data_src, &index); + break; + + case ATTR_SKIP: + p_ancs->parse_info.parse_state = attr_skip(p_ancs, p_data_src, &index); + break; + + case DONE: + NRF_LOG_DEBUG("[ANCS]: Parse state: Done \n\r"); + index = hvx_data_len; + break; + + default: + // Default case will never trigger intentionally. Go to the DONE state to minimize the consequences. + p_ancs->parse_info.parse_state = DONE; + break; + } + } +} diff --git a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h b/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h new file mode 100644 index 0000000..fe1bfaf --- /dev/null +++ b/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_ANCS_ATTR_PARSER_H__ +#define BLE_ANCS_ATTR_PARSER_H__ + +#include "nrf_ble_ancs_c.h" + +/** @file + * + * @addtogroup ble_ancs_c + * @{ + */ + +/**@brief Function for parsing notification or app attribute response data. + * + * @details The data that comes from the Notification Provider can be much longer than what + * would fit in a single GATTC notification. Therefore, this function relies on a + * state-oriented switch case. + * UID and command ID will be received only once at the beginning of the first + * GATTC notification of a new attribute request for a given iOS notification. + * After this, we can loop several ATTR_ID > LENGTH > DATA > ATTR_ID > LENGTH > DATA until + * we have received all attributes we wanted as a Notification Consumer. + * The Notification Provider can also simply stop sending attributes. + * + * 1 byte | 4 bytes |1 byte |2 bytes |... X bytes ... |1 bytes| 2 bytes| ... X bytes ... + * --------|-------------|-------|--------|----------------|-------|--------|---------------- + * CMD_ID | NOTIF_UID |ATTR_ID| LENGTH | DATA |ATTR_ID| LENGTH | DATA + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] hvx_data_len Length of the data that was received from the Notification Provider. + */ +void ancs_parse_get_attrs_response(ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + const uint16_t hvx_data_len); + +/** @} */ + +#endif // BLE_ANCS_ATTR_PARSER_H__ + diff --git a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c b/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c new file mode 100644 index 0000000..093896a --- /dev/null +++ b/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c @@ -0,0 +1,114 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA. + * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working. + */ + + #include "nrf_ble_ancs_c.h" + #include "ancs_tx_buffer.h" + #include "sdk_macros.h" + #include "nrf_log.h" + #include "string.h" + + +static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the Notification Provider. */ +static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ +static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ + + +void tx_buffer_init(void) +{ + memset(m_tx_buffer, 0, sizeof(m_tx_buffer)); +} + + +void tx_buffer_insert(tx_message_t * p_msg) +{ + + memset(&(m_tx_buffer[m_tx_insert_index]), 0, sizeof(m_tx_buffer)/sizeof(tx_message_t)); + + m_tx_buffer[m_tx_insert_index].conn_handle = p_msg->conn_handle; + m_tx_buffer[m_tx_insert_index].type = p_msg->type; + + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.handle = p_msg->req.write_req.gattc_params.handle; + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.len = p_msg->req.write_req.gattc_params.len; + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.write_op = p_msg->req.write_req.gattc_params.write_op; + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.flags = p_msg->req.write_req.gattc_params.flags; + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.p_value = m_tx_buffer[m_tx_insert_index].req.write_req.gattc_value; + m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.offset = p_msg->req.write_req.gattc_params.offset; + + if(p_msg->type == WRITE_REQ) + { + memcpy(m_tx_buffer[m_tx_insert_index].req.write_req.gattc_value, + p_msg->req.write_req.gattc_value, + WRITE_MESSAGE_LENGTH); + } + + m_tx_insert_index++; + m_tx_insert_index &= TX_BUFFER_MASK; +} + + + +void tx_buffer_process(void) +{ + if (m_tx_index != m_tx_insert_index) + { + uint32_t err_code; + + if (m_tx_buffer[m_tx_index].type == READ_REQ) + { + err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, + m_tx_buffer[m_tx_index].req.read_handle, + 0); + } + else + { + err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, + &m_tx_buffer[m_tx_index].req.write_req.gattc_params); + } + if (err_code == NRF_SUCCESS) + { + ++m_tx_index; + m_tx_index &= TX_BUFFER_MASK; + } + } +} diff --git a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h b/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h new file mode 100644 index 0000000..07013d4 --- /dev/null +++ b/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ANCS_TX_BUFFER_H__ +#define ANCS_TX_BUFFER_H__ + +#include "nrf_ble_ancs_c.h" + +/** @file + * + * @addtogroup ble_ancs_c + * @{ + */ + +#define TX_BUFFER_MASK 0x07 //!< TX buffer mask. Must be a mask of contiguous zeroes followed by a contiguous sequence of ones: 000...111. +#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) //!< Size of the send buffer, which is 1 bigger than the mask. +#define WRITE_MESSAGE_LENGTH 20 //!< Length of the write message for the CCCD/control point. + +/**@brief ANCS request types. + */ +typedef enum +{ + READ_REQ = 1, /**< Type identifying that this TX message is a read request. */ + WRITE_REQ /**< Type identifying that this TX message is a write request. */ +} tx_request_t; + + +/**@brief Structure for writing a message to the central, thus the Control Point or CCCD. + */ +typedef struct +{ + uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; //!< The message to write. + ble_gattc_write_params_t gattc_params; //!< GATTC parameters for this message. +} write_params_t; + + +/**@brief Data to be transmitted to the connected master. + */ +typedef struct +{ + uint16_t conn_handle; //!< Connection handle to be used when transmitting this message. + tx_request_t type; //!< Type of this message (read or write message). + union + { + uint16_t read_handle; //!< Read request message. + write_params_t write_req; //!< Write request message. + } req; +} tx_message_t; + +/**@brief Function for clearing the TX buffer. + * + * @details Always call this function before using the TX buffer. +*/ +void tx_buffer_init(void); + +/**@brief Function for moving the pointer of the ring buffer to the next element. +*/ +void tx_buffer_insert(tx_message_t * p_msg); + +/**@brief Function for passing any pending request from the buffer to the stack. +*/ +void tx_buffer_process(void); + +/** @} */ + +#endif // ANCS_TX_BUFFER_H__ + diff --git a/components/ble/ble_services/ble_ancs_c/ble_ancs_c.c b/components/ble/ble_services/ble_ancs_c/ble_ancs_c.c deleted file mode 100644 index a9bd03a..0000000 --- a/components/ble/ble_services/ble_ancs_c/ble_ancs_c.c +++ /dev/null @@ -1,737 +0,0 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA. - * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working. - */ - -#include "ble_ancs_c.h" -#include -#include -#include "ble_err.h" -#include "ble_srv_common.h" -#include "nordic_common.h" -#include "nrf_assert.h" -#include "device_manager.h" -#include "ble_db_discovery.h" -#include "app_error.h" -#include "app_trace.h" - -#define BLE_ANCS_NOTIF_EVT_ID_INDEX 0 /**< Index of the Event ID field when parsing notifications. */ -#define BLE_ANCS_NOTIF_FLAGS_INDEX 1 /**< Index of the Flags field when parsing notifications. */ -#define BLE_ANCS_NOTIF_CATEGORY_ID_INDEX 2 /**< Index of the Category ID field when parsing notifications. */ -#define BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX 3 /**< Index of the Category Count field when parsing notifications. */ -#define BLE_ANCS_NOTIF_NOTIF_UID 4 /**< Index of the Notification UID field when patsin notifications. */ - -#define LOG app_trace_log /**< Debug logger macro that will be used in this file to do logging of important information over UART. */ -#define LOG_DUMP app_trace_dump /**< Debug logger macro that will be used in this file to do logging of important information over UART. */ - -#define START_HANDLE_DISCOVER 0x0001 /**< Value of start handle during discovery. */ - -#define TX_BUFFER_MASK 0x07 /**< TX buffer mask. Must be a mask of contiguous zeroes followed by a contiguous sequence of ones: 000...111. */ -#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */ -#define WRITE_MESSAGE_LENGTH 20 /**< Length of the write message for CCCD/control point. */ -#define BLE_CCCD_NOTIFY_BIT_MASK 0x0001 /**< Enable notification bit. */ - -#define BLE_ANCS_MAX_DISCOVERED_CENTRALS DEVICE_MANAGER_MAX_BONDS /**< Maximum number of discovered services that can be stored in the flash. This number should be identical to maximum number of bonded peer devices. */ - -#define TIME_STRING_LEN 15 /**< Unicode Technical Standard (UTS) #35 date format pattern "yyyyMMdd'T'HHmmSS" + "'\0'". */ - -#define DISCOVERED_SERVICE_DB_SIZE \ - CEIL_DIV(sizeof(ble_ancs_c_service_t) * BLE_ANCS_MAX_DISCOVERED_CENTRALS, sizeof(uint32_t)) /**< Size of bonded peer's database in word size (4 byte). */ - - -/**@brief ANCS request types. - */ -typedef enum -{ - READ_REQ = 1, /**< Type identifying that this tx_message is a read request. */ - WRITE_REQ /**< Type identifying that this tx_message is a write request. */ -} ancs_tx_request_t; - - -/**@brief Structure used for holding the characteristic found during the discovery process. - */ -typedef struct -{ - ble_uuid_t uuid; /**< UUID identifying the characteristic. */ - ble_gatt_char_props_t properties; /**< Properties for the characteristic. */ - uint16_t handle_decl; /**< Characteristic Declaration Handle for the characteristic. */ - uint16_t handle_value; /**< Value Handle for the value provided in the characteristic. */ - uint16_t handle_cccd; /**< CCCD Handle value for the characteristic. */ -} ble_ancs_c_characteristic_t; - - -/**@brief Structure used for holding the Apple Notification Center Service found during the discovery process. - */ -typedef struct -{ - uint8_t handle; /**< Handle of Apple Notification Center Service, which identifies to which peer this discovered service belongs. */ - ble_gattc_service_t service; /**< The GATT Service holding the discovered Apple Notification Center Service. */ - ble_ancs_c_characteristic_t control_point; /**< Control Point Characteristic for the service. Allows interaction with the peer. */ - ble_ancs_c_characteristic_t notif_source; /**< Characteristic that keeps track of arrival, modification, and removal of notifications. */ - ble_ancs_c_characteristic_t data_source; /**< Characteristic where attribute data for the notifications is received from peer. */ -} ble_ancs_c_service_t; - - -/**@brief Structure for writing a message to the central, i.e. Control Point or CCCD. - */ -typedef struct -{ - uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */ - ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */ -} write_params_t; - - -/**@brief Structure for holding data to be transmitted to the connected master. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */ - ancs_tx_request_t type; /**< Type of this message, i.e. read or write message. */ - union - { - uint16_t read_handle; /**< Read request message. */ - write_params_t write_req; /**< Write request message. */ - } req; -} tx_message_t; - - -/**@brief Parsing states for received iOS notification attributes. - */ -typedef enum -{ - COMMAND_ID_AND_NOTIF_UID, /**< Parsing the command ID and the notification UID. */ - ATTR_ID, /**< Parsing attribute ID. */ - ATTR_LEN1, /**< Parsing the LSB of the attribute length. */ - ATTR_LEN2, /**< Parsing the MSB of the attribute length. */ - ATTR_DATA, /**< Parsing the attribute data. */ - DONE /**< Parsing is done. */ -} ble_ancs_c_parse_state_t; - -static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the Notification Provider. */ -static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ -static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ - -static ble_ancs_c_service_t m_service; /**< Current service data. */ -static ble_ancs_c_t * mp_ble_ancs; /**< Pointer to the current instance of the ANCS client module. The memory for this is provided by the application.*/ -static ble_ancs_c_attr_list_t m_ancs_attr_list[BLE_ANCS_NB_OF_ATTRS]; /**< For all attributes; contains whether they should be requested upon attribute request and the length and buffer of where to store attribute data. */ -static uint32_t m_expected_number_of_attrs; /**< Variable to keep track of when to stop reading incoming attributes. */ -static ble_ancs_c_evt_t m_ancs_evt; /**< The ANCS event that is created in this module and propagated to the application. */ - -static ble_ancs_c_parse_state_t m_parse_state = COMMAND_ID_AND_NOTIF_UID; /**< ANCS notification attribute parsing state. */ - - -/**@brief 128-bit service UUID for the Apple Notification Center Service. - */ -const ble_uuid128_t ble_ancs_base_uuid128 = -{ - { - // 7905F431-B5CE-4E99-A40F-4B1E122D00D0 - 0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4, - 0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79 - } -}; - - -/**@brief 128-bit control point UUID. - */ -const ble_uuid128_t ble_ancs_cp_base_uuid128 = -{ - { - // 69d1d8f3-45e1-49a8-9821-9BBDFDAAD9D9 - 0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98, - 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69 - } -}; - -/**@brief 128-bit notification source UUID. -*/ -const ble_uuid128_t ble_ancs_ns_base_uuid128 = -{ - { - // 9FBF120D-6301-42D9-8C58-25E699A21DBD - 0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c, - 0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f - - } -}; - -/**@brief 128-bit data source UUID. -*/ -const ble_uuid128_t ble_ancs_ds_base_uuid128 = -{ - { - // 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB - 0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe, - 0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22 - } -}; - - -/**@brief Function for handling events from the database discovery module. - * - * @details This function handles events from the database discovery module and determines - * if it relates to the discovery of the Apple Notification Center Service at the - * peer. If so, it will call the application's event handler indicating that the Apple - * Notification Center Service has been discovered at the peer. It also populates the - * event with the service-related information before providing it to the application. - * - * @param[in] p_evt Pointer to the event received from the database discovery module. - */ -static void db_discover_evt_handler(ble_db_discovery_evt_t * p_evt) -{ - LOG("[ANCS]: Database Discovery handler called with event 0x%x\r\n", p_evt->evt_type); - - ble_ancs_c_evt_t evt; - ble_gatt_db_char_t * p_chars; - - p_chars = p_evt->params.discovered_db.charateristics; - - // Check if the ANCS Service was discovered. - if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && - p_evt->params.discovered_db.srv_uuid.uuid == ANCS_UUID_SERVICE && - p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_VENDOR_BEGIN) - { - mp_ble_ancs->conn_handle = p_evt->conn_handle; - - // Find the handles of the ANCS characteristic. - uint32_t i; - - for (i = 0; i < p_evt->params.discovered_db.char_count; i++) - { - switch (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid) - { - case ANCS_UUID_CHAR_CONTROL_POINT: - LOG("[ANCS]: Control Point Characteristic found.\n\r"); - m_service.control_point.properties = p_chars[i].characteristic.char_props; - m_service.control_point.handle_decl = p_chars[i].characteristic.handle_decl; - m_service.control_point.handle_value = p_chars[i].characteristic.handle_value; - m_service.control_point.handle_cccd = p_chars[i].cccd_handle; - break; - - case ANCS_UUID_CHAR_DATA_SOURCE: - LOG("[ANCS]: Data Source Characteristic found.\n\r"); - m_service.data_source.properties = p_chars[i].characteristic.char_props; - m_service.data_source.handle_decl = p_chars[i].characteristic.handle_decl; - m_service.data_source.handle_value = p_chars[i].characteristic.handle_value; - m_service.data_source.handle_cccd = p_chars[i].cccd_handle; - break; - - case ANCS_UUID_CHAR_NOTIFICATION_SOURCE: - LOG("[ANCS]: Notification point Characteristic found.\n\r"); - m_service.notif_source.properties = p_chars[i].characteristic.char_props; - m_service.notif_source.handle_decl = p_chars[i].characteristic.handle_decl; - m_service.notif_source.handle_value = p_chars[i].characteristic.handle_value; - m_service.notif_source.handle_cccd = p_chars[i].cccd_handle; - break; - - default: - break; - } - } - evt.evt_type = BLE_ANCS_C_EVT_DISCOVER_COMPLETE; - mp_ble_ancs->evt_handler(&evt); - } - else - { - evt.evt_type = BLE_ANCS_C_EVT_DISCOVER_FAILED; - mp_ble_ancs->evt_handler(&evt); - } -} - - -/**@brief Function for passing any pending request from the buffer to the stack. - */ -static void tx_buffer_process(void) -{ - if (m_tx_index != m_tx_insert_index) - { - uint32_t err_code; - - if (m_tx_buffer[m_tx_index].type == READ_REQ) - { - err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, - m_tx_buffer[m_tx_index].req.read_handle, - 0); - } - else - { - err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, - &m_tx_buffer[m_tx_index].req.write_req.gattc_params); - } - if (err_code == NRF_SUCCESS) - { - ++m_tx_index; - m_tx_index &= TX_BUFFER_MASK; - } - } -} - - -/**@brief Function for parsing received notification attribute response data. - * - * @details The data that comes from the Notification Provider can be much longer than what - * would fit in a single GATTC notification. Therefore, function relies on static - * variables and a state-oriented switch case. - * UID and command ID will be received only once at the beginning of the first - * GATTC notification of a new attribute request for a given iOS notification. - * After this, we can loop several ID > LENGTH > DATA > ID > LENGTH > DATA until we have - * received all attributes we wanted as a Notification Consumer. The Notification Provider - * can also simply stop sending attributes. - * - * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. - * @param[in] p_data_src Pointer to data that was received from the Notification Provider. - * @param[in] hvx_len Length of the data that was received from the Notification Provider. - */ -static void parse_get_notif_attrs_response(ble_ancs_c_t * p_ancs, - const uint8_t * p_data_src, - const uint16_t hvx_data_len) -{ - static uint8_t * p_data_dest; - static uint16_t current_attr_index; - static ble_ancs_c_evt_t evt; - ble_ancs_c_command_id_values_t command_id; - uint32_t index; - - evt.ancs_attr_list = m_ancs_attr_list; - - for (index = 0; index < hvx_data_len;) - { - switch (m_parse_state) - { - case COMMAND_ID_AND_NOTIF_UID: - command_id = (ble_ancs_c_command_id_values_t) p_data_src[index++]; - if(command_id != BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES) - { - LOG("[ANCS]: Invalid Command ID"); - m_parse_state = DONE; - } - - evt.attr.notif_uid = uint32_decode(&p_data_src[index]); - index += sizeof(uint32_t); - m_parse_state = ATTR_ID; - - if (evt.attr.notif_uid != m_ancs_evt.notif.notif_uid) - { - LOG("UID mismatch: Notification UID %x , Attribute UID %x\n\r", - evt.notif.notif_uid, - evt.attr.notif_uid); - m_parse_state = DONE; - } - break; - - case ATTR_ID: - if (m_expected_number_of_attrs == 0) - { - LOG("[ANCS]: All requested attributes received\n\r"); - m_parse_state = DONE; - index++; - } - else - { - evt.attr.attr_id = (ble_ancs_c_notif_attr_id_values_t) p_data_src[index++]; - p_data_dest = m_ancs_attr_list[evt.attr.attr_id].p_attr_data; - if (m_ancs_attr_list[evt.attr.attr_id].get == true) - { - m_parse_state = ATTR_LEN1; - } - m_expected_number_of_attrs--; - LOG("Attribute ID %i \n\r", evt.attr.attr_id); - } - break; - - case ATTR_LEN1: - evt.attr.attr_len = p_data_src[index++]; - m_parse_state = ATTR_LEN2; - break; - - case ATTR_LEN2: - evt.attr.attr_len |= (p_data_src[index++] << 8); - current_attr_index = 0; - if (evt.attr.attr_len != 0) - { - m_parse_state = ATTR_DATA; - } - else - { - evt.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE; - p_ancs->evt_handler(&evt); - m_parse_state = ATTR_ID; - } - LOG("Attribute LEN %i \n\r", evt.attr.attr_len); - break; - - case ATTR_DATA: - // We have not reached the end of the attribute, nor our max allocated internal size. - // Proceed with copying data over to our buffer. - if ( (current_attr_index < m_ancs_attr_list[evt.attr.attr_id].attr_len) - && (current_attr_index < evt.attr.attr_len)) - { - p_data_dest[current_attr_index++] = p_data_src[index++]; - } - // We have reached the end of the attribute, or our max allocated internal size. - // Stop copying data over to our buffer. NUL-terminate at the current index. - if ( (current_attr_index == evt.attr.attr_len) || - (current_attr_index == m_ancs_attr_list[evt.attr.attr_id].attr_len)) - { - p_data_dest[current_attr_index] = '\0'; - - // If our max buffer size is smaller than the remaining attribute data, we must - // increase index to skip the data until the start of the next attribute. - if (current_attr_index < evt.attr.attr_len) - { - index += (evt.attr.attr_len - current_attr_index); - } - m_parse_state = ATTR_ID; - LOG("Attribute finished!\n\r"); - evt.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE; - p_ancs->evt_handler(&evt); - } - break; - - case DONE: - index = hvx_data_len; - break; - - default: - // Default case will never trigger intentionally. Go to the DONE state to minimize the consequences. - m_parse_state = DONE; - break; - } - } -} - - -/**@brief Function for checking if data in an iOS notification is out of bounds. - * - * @param[in] notif An iOS notification. - * - * @retval NRF_SUCCESS If the notification is within bounds. - * @retval NRF_ERROR_INVALID_PARAM If the notification is out of bounds. - */ -static uint32_t ble_ancs_verify_notification_format(const ble_ancs_c_evt_notif_t * notif) -{ - if( (notif->evt_id >= BLE_ANCS_NB_OF_EVT_ID) - || (notif->category_id >= BLE_ANCS_NB_OF_CATEGORY_ID)) - { - return NRF_ERROR_INVALID_PARAM; - } - return NRF_SUCCESS; -} - -/**@brief Function for receiving and validating notifications received from the Notification Provider. - * - * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. - * @param[in] p_ble_evt Bluetooth stack event. - * @param[in] p_data_src Pointer to data that was received from the Notification Provider. - * @param[in] hvx_len Length of the data that was received by the Notification Provider. - */ -static void parse_notif(const ble_ancs_c_t * p_ancs, - ble_ancs_c_evt_t * p_ancs_evt, - const uint8_t * p_data_src, - const uint16_t hvx_data_len) -{ - uint32_t err_code; - if (hvx_data_len != BLE_ANCS_NOTIFICATION_DATA_LENGTH) - { - m_ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF; - p_ancs->evt_handler(&m_ancs_evt); - } - - /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */ - p_ancs_evt->notif.evt_id = - (ble_ancs_c_evt_id_values_t) p_data_src[BLE_ANCS_NOTIF_EVT_ID_INDEX]; - - p_ancs_evt->notif.evt_flags.silent = - (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_SILENT) & 0x01; - - p_ancs_evt->notif.evt_flags.important = - (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_IMPORTANT) & 0x01; - - p_ancs_evt->notif.evt_flags.pre_existing = - (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_PREEXISTING) & 0x01; - - p_ancs_evt->notif.evt_flags.positive_action = - (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION) & 0x01; - - p_ancs_evt->notif.evt_flags.negative_action = - (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION) & 0x01; - - p_ancs_evt->notif.category_id = - (ble_ancs_c_category_id_values_t) p_data_src[BLE_ANCS_NOTIF_CATEGORY_ID_INDEX]; - - p_ancs_evt->notif.category_count = p_data_src[BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX]; - p_ancs_evt->notif.notif_uid = uint32_decode(&p_data_src[BLE_ANCS_NOTIF_NOTIF_UID]); - /*lint -restore*/ - - err_code = ble_ancs_verify_notification_format(&m_ancs_evt.notif); - if (err_code == NRF_SUCCESS) - { - m_ancs_evt.evt_type = BLE_ANCS_C_EVT_NOTIF; - } - else - { - m_ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF; - } - - p_ancs->evt_handler(&m_ancs_evt); -} - - -/**@brief Function for receiving and validating notifications received from the Notification Provider. - * - * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. - * @param[in] p_ble_evt Bluetooth stack event. - */ -static void on_evt_gattc_notif(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) -{ - const ble_gattc_evt_hvx_t * p_notif = &p_ble_evt->evt.gattc_evt.params.hvx; - - if (p_notif->handle == m_service.notif_source.handle_value) - { - BLE_UUID_COPY_INST(m_ancs_evt.uuid, m_service.notif_source.uuid); - parse_notif(p_ancs, &m_ancs_evt,p_notif->data,p_notif->len); - } - else if (p_notif->handle == m_service.data_source.handle_value) - { - BLE_UUID_COPY_INST(m_ancs_evt.uuid, m_service.data_source.uuid); - parse_get_notif_attrs_response(p_ancs, p_notif->data, p_notif->len); - } - else - { - // No applicable action. - } -} - -/**@brief Function for handling write response events. - */ -static void on_evt_write_rsp() -{ - tx_buffer_process(); -} - - -void ble_ancs_c_on_device_manager_evt(ble_ancs_c_t * p_ans, - dm_handle_t const * p_handle, - dm_event_t const * p_dm_evt) -{ - switch (p_dm_evt->event_id) - { - case DM_EVT_CONNECTION: - // Fall through. - case DM_EVT_SECURITY_SETUP_COMPLETE: - p_ans->central_handle = p_handle->device_id; - break; - - default: - // Do nothing. - break; - } -} - - -void ble_ancs_c_on_ble_evt(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) -{ - uint16_t evt = p_ble_evt->header.evt_id; - - switch (evt) - { - case BLE_GATTC_EVT_WRITE_RSP: - on_evt_write_rsp(); - break; - - case BLE_GATTC_EVT_HVX: - on_evt_gattc_notif(p_ancs, p_ble_evt); - break; - - default: - break; - } -} - - -uint32_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, const ble_ancs_c_init_t * p_ancs_init) -{ - if ((p_ancs == NULL) || p_ancs_init == NULL || (p_ancs_init->evt_handler == NULL)) - { - return NRF_ERROR_NULL; - } - - mp_ble_ancs = p_ancs; - - mp_ble_ancs->evt_handler = p_ancs_init->evt_handler; - mp_ble_ancs->error_handler = p_ancs_init->error_handler; - mp_ble_ancs->service_handle = BLE_GATT_HANDLE_INVALID; - mp_ble_ancs->central_handle = DM_INVALID_ID; - mp_ble_ancs->conn_handle = BLE_CONN_HANDLE_INVALID; - - memset(&m_service, 0, sizeof(ble_ancs_c_service_t)); - memset(m_tx_buffer, 0, TX_BUFFER_SIZE); - - m_service.handle = BLE_GATT_HANDLE_INVALID; - - ble_uuid_t ancs_uuid; - ancs_uuid.uuid = ANCS_UUID_SERVICE; - ancs_uuid.type = BLE_UUID_TYPE_VENDOR_BEGIN; - - return ble_db_discovery_evt_register(&ancs_uuid, db_discover_evt_handler); -} - - -/**@brief Function for creating a TX message for writing a CCCD. - * - * @param[in] conn_handle Connection handle on which to perform the configuration. - * @param[in] handle_cccd Handle of the CCCD. - * @param[in] enable Enable or disable GATTC notifications. - * - * @retval NRF_SUCCESS If the message was created successfully. - * @retval NRF_ERROR_INVALID_PARAM If one of the input parameters was invalid. - */ -static uint32_t cccd_configure(const uint16_t conn_handle, const uint16_t handle_cccd, bool enable) -{ - tx_message_t * p_msg; - uint16_t cccd_val = enable ? BLE_CCCD_NOTIFY_BIT_MASK : 0; - - p_msg = &m_tx_buffer[m_tx_insert_index++]; - m_tx_insert_index &= TX_BUFFER_MASK; - - p_msg->req.write_req.gattc_params.handle = handle_cccd; - p_msg->req.write_req.gattc_params.len = 2; - p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; - p_msg->req.write_req.gattc_params.offset = 0; - p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; - p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val); - p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val); - p_msg->conn_handle = conn_handle; - p_msg->type = WRITE_REQ; - - tx_buffer_process(); - return NRF_SUCCESS; -} - - -uint32_t ble_ancs_c_notif_source_notif_enable(const ble_ancs_c_t * p_ancs) -{ - LOG("[ANCS]: Enable Notification Source notifications. writing to handle: %i \n\r", - m_service.notif_source.handle_cccd); - return cccd_configure(p_ancs->conn_handle, m_service.notif_source.handle_cccd, true); -} - - -uint32_t ble_ancs_c_notif_source_notif_disable(const ble_ancs_c_t * p_ancs) -{ - return cccd_configure(p_ancs->conn_handle, m_service.notif_source.handle_cccd, false); -} - - -uint32_t ble_ancs_c_data_source_notif_enable(const ble_ancs_c_t * p_ancs) -{ - LOG("[ANCS]: Enable Data Source notifications. Writing to handle: %i \n\r", - m_service.data_source.handle_cccd); - return cccd_configure(p_ancs->conn_handle, m_service.data_source.handle_cccd, true); -} - - -uint32_t ble_ancs_c_data_source_notif_disable(const ble_ancs_c_t * p_ancs) -{ - return cccd_configure(p_ancs->conn_handle, m_service.data_source.handle_cccd, false); -} - - -uint32_t ble_ancs_get_notif_attrs(const ble_ancs_c_t * p_ancs, - const uint32_t p_uid) -{ - tx_message_t * p_msg; - uint32_t index = 0; - uint32_t number_of_requested_attr = 0; - - p_msg = &m_tx_buffer[m_tx_insert_index++]; - m_tx_insert_index &= TX_BUFFER_MASK; - - p_msg->req.write_req.gattc_params.handle = m_service.control_point.handle_value; - p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; - p_msg->req.write_req.gattc_params.offset = 0; - p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; - - //Encode Command ID. - p_msg->req.write_req.gattc_value[index++] = BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES; - - //Encode Notification UID. - index += uint32_encode(p_uid, &p_msg->req.write_req.gattc_value[index]); - - //Encode Attribute ID. - for (uint32_t attr = 0; attr < BLE_ANCS_NB_OF_ATTRS; attr++) - { - if (m_ancs_attr_list[attr].get == true) - { - p_msg->req.write_req.gattc_value[index++] = attr; - if ((attr == BLE_ANCS_NOTIF_ATTR_ID_TITLE) || - (attr == BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE) || - (attr == BLE_ANCS_NOTIF_ATTR_ID_MESSAGE)) - { - //Encode Length field, only applicable for Title, Subtitle and Message - index += uint16_encode(m_ancs_attr_list[attr].attr_len, - &p_msg->req.write_req.gattc_value[index]); - } - number_of_requested_attr++; - } - } - p_msg->req.write_req.gattc_params.len = index; - p_msg->conn_handle = p_ancs->conn_handle; - p_msg->type = WRITE_REQ; - m_expected_number_of_attrs = number_of_requested_attr; - - tx_buffer_process(); - - return NRF_SUCCESS; -} - - -uint32_t ble_ancs_c_attr_add(const ble_ancs_c_notif_attr_id_values_t id, - uint8_t * p_data, - const uint16_t len) -{ - if(p_data == NULL) - { - return NRF_ERROR_NULL; - } - if((len == 0) || (len > BLE_ANCS_ATTR_DATA_MAX)) - { - return NRF_ERROR_INVALID_LENGTH; - } - - m_ancs_attr_list[id].get = true; - m_ancs_attr_list[id].attr_len = len; - m_ancs_attr_list[id].p_attr_data = p_data; - - return NRF_SUCCESS; -} - - -uint32_t ble_ancs_c_request_attrs(const ble_ancs_c_evt_notif_t * notif) -{ - uint32_t err_code; - err_code = ble_ancs_verify_notification_format(notif); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = ble_ancs_get_notif_attrs(mp_ble_ancs, notif->notif_uid); - m_parse_state = COMMAND_ID_AND_NOTIF_UID; - if (err_code != NRF_SUCCESS) - { - return err_code; - } - return NRF_SUCCESS; -} - diff --git a/components/ble/ble_services/ble_ancs_c/ble_ancs_c.h b/components/ble/ble_services/ble_ancs_c/ble_ancs_c.h deleted file mode 100644 index 9a03956..0000000 --- a/components/ble/ble_services/ble_ancs_c/ble_ancs_c.h +++ /dev/null @@ -1,320 +0,0 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -/** @file - * - * @defgroup ble_sdk_srv_ancs_c Apple Notification Service client - * @{ - * @ingroup ble_sdk_srv - * @brief Apple Notification Center Service Client Module. - * - * @details Disclaimer: This client implementation of the Apple Notification Center Service can - * and will be changed at any time by Nordic Semiconductor ASA. - * - * Server implementations such as the ones found in iOS can be changed at any - * time by Apple and may cause this client implementation to stop working. - * - * This module implements the Apple Notification Center Service (ANCS) client. - * This client can be used as a Notification Consumer (NC) that receives data - * notifications from a Notification Provider (NP). The NP is typically an iOS - * device acting as a server. For terminology and up-to-date specs, see - * http://developer.apple.com. - * - * The term "notification" is used in two different meanings: - * - An iOS notification is the data received from the Notification Provider. - * - A GATTC notification is a way to transfer data with Bluetooth Smart. - * In this module, we receive iOS notifications using GATTC notifications. - * We use the full term (iOS notification or GATTC notification) where required. - * - * @note The application must propagate BLE stack events to this module - * by calling ble_ancs_c_on_ble_evt() from the @ref softdevice_handler callback. - */ -#ifndef BLE_ANCS_C_H__ -#define BLE_ANCS_C_H__ - - -#include "ble_types.h" -#include "ble_srv_common.h" -#include "device_manager.h" - - -#define BLE_ANCS_ATTR_DATA_MAX 32 /**< Maximum data length of an iOS notification attribute. */ -#define BLE_ANCS_NB_OF_CATEGORY_ID 12 /**< Number of iOS notification categories: Other, Incoming Call, Missed Call, Voice Mail, Social, Schedule, Email, News, Health And Fitness, Business And Finance, Location, Entertainment. */ -#define BLE_ANCS_NB_OF_ATTRS 8 /**< Number of iOS notification attributes: AppIdentifier, Title, Subtitle, Message, MessageSize, Date, PositiveActionLabel, NegativeActionLabel. */ -#define BLE_ANCS_NB_OF_EVT_ID 3 /**< Number of iOS notification events: Added, Modified, Removed.*/ - -/** @brief Length of the iOS notification data. - * - * @details 8 bytes: - * Event ID |Event flags |Category ID |Category count|Notification UID - * ---------|------------|------------|--------------|---------------- - * 1 byte | 1 byte | 1 byte | 1 byte | 4 bytes - */ -#define BLE_ANCS_NOTIFICATION_DATA_LENGTH 8 - -#define ANCS_UUID_SERVICE 0xF431 /**< 16-bit service UUID for the Apple Notification Center Service. */ -#define ANCS_UUID_CHAR_CONTROL_POINT 0xD8F3 /**< 16-bit control point UUID. */ -#define ANCS_UUID_CHAR_DATA_SOURCE 0xC6E9 /**< 16-bit data source UUID. */ -#define ANCS_UUID_CHAR_NOTIFICATION_SOURCE 0x120D /**< 16-bit notification source UUID. */ - -#define BLE_ANCS_EVENT_FLAG_SILENT 0 /**< 0b.......1 Silent: First (LSB) bit is set. All flags can be active at the same time.*/ -#define BLE_ANCS_EVENT_FLAG_IMPORTANT 1 /**< 0b......1. Important: Second (LSB) bit is set. All flags can be active at the same time.*/ -#define BLE_ANCS_EVENT_FLAG_PREEXISTING 2 /**< 0b.....1.. Pre-existing: Third (LSB) bit is set. All flags can be active at the same time.*/ -#define BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION 3 /**< 0b....1... Positive action: Fourth (LSB) bit is set. All flags can be active at the same time.*/ -#define BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION 4 /**< 0b...1.... Negative action: Fifth (LSB) bit is set. All flags can be active at the same time. */ - - -/**@brief Event types that are passed from client to application on an event. */ -typedef enum -{ - BLE_ANCS_C_EVT_DISCOVER_COMPLETE, /**< A successful connection has been established and the service was found on the connected peer. */ - BLE_ANCS_C_EVT_DISCOVER_FAILED, /**< It was not possible to discover the service or characteristics of the connected peer. */ - BLE_ANCS_C_EVT_NOTIF, /**< An iOS notification was received on the notification source control point. */ - BLE_ANCS_C_EVT_INVALID_NOTIF, /**< An iOS notification was received on the notification source control point, but the format is invalid. */ - BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE /**< A received iOS notification attribute has been parsed. */ -} ble_ancs_c_evt_type_t; - -/**@brief Category IDs for iOS notifications. */ -typedef enum -{ - BLE_ANCS_CATEGORY_ID_OTHER, /**< The iOS notification belongs to the "other" category. */ - BLE_ANCS_CATEGORY_ID_INCOMING_CALL, /**< The iOS notification belongs to the "Incoming Call" category. */ - BLE_ANCS_CATEGORY_ID_MISSED_CALL, /**< The iOS notification belongs to the "Missed Call" category. */ - BLE_ANCS_CATEGORY_ID_VOICE_MAIL, /**< The iOS notification belongs to the "Voice Mail" category. */ - BLE_ANCS_CATEGORY_ID_SOCIAL, /**< The iOS notification belongs to the "Social" category. */ - BLE_ANCS_CATEGORY_ID_SCHEDULE, /**< The iOS notification belongs to the "Schedule" category. */ - BLE_ANCS_CATEGORY_ID_EMAIL, /**< The iOS notification belongs to the "E-mail" category. */ - BLE_ANCS_CATEGORY_ID_NEWS, /**< The iOS notification belongs to the "News" category. */ - BLE_ANCS_CATEGORY_ID_HEALTH_AND_FITNESS, /**< The iOS notification belongs to the "Health and Fitness" category. */ - BLE_ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE, /**< The iOS notification belongs to the "Buisness and Finance" category. */ - BLE_ANCS_CATEGORY_ID_LOCATION, /**< The iOS notification belongs to the "Location" category. */ - BLE_ANCS_CATEGORY_ID_ENTERTAINMENT /**< The iOS notification belongs to the "Entertainment" category. */ -} ble_ancs_c_category_id_values_t; - -/**@brief Event IDs for iOS notifications. */ -typedef enum -{ - BLE_ANCS_EVENT_ID_NOTIFICATION_ADDED, /**< The iOS notification was added. */ - BLE_ANCS_EVENT_ID_NOTIFICATION_MODIFIED, /**< The iOS notification was modified. */ - BLE_ANCS_EVENT_ID_NOTIFICATION_REMOVED /**< The iOS notification was removed. */ -} ble_ancs_c_evt_id_values_t; - -/**@brief Control point command IDs that the Notification Consumer can send to the Notification Provider. */ -typedef enum -{ - BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given notification. */ - BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given iOS App. */ - BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION, /**< Requests an action to be performed on a given notification, for example dismiss an alarm. */ -} ble_ancs_c_command_id_values_t; - -/**@brief IDs for iOS notification attributes. */ -typedef enum -{ - BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER, /**< Identifies that the attribute data is of an "App Identifier" type. */ - BLE_ANCS_NOTIF_ATTR_ID_TITLE, /**< Identifies that the attribute data is a "Title". */ - BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE, /**< Identifies that the attribute data is a "Subtitle". */ - BLE_ANCS_NOTIF_ATTR_ID_MESSAGE, /**< Identifies that the attribute data is a "Message". */ - BLE_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE, /**< Identifies that the attribute data is a "Message Size". */ - BLE_ANCS_NOTIF_ATTR_ID_DATE, /**< Identifies that the attribute data is a "Date". */ - BLE_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, /**< The notification has a "Positive action" that can be executed associated with it. */ - BLE_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, /**< The notification has a "Negative action" that can be executed associated with it. */ -} ble_ancs_c_notif_attr_id_values_t; - - -/**@brief Flags for iOS notifications. */ -typedef struct -{ - uint8_t silent : 1; /**< If this flag is set, the notification has a low priority. */ - uint8_t important : 1; /**< If this flag is set, the notification has a high priority. */ - uint8_t pre_existing : 1; /**< If this flag is set, the notification is pre-existing. */ - uint8_t positive_action : 1; /**< If this flag is set, the notification has a positive action that can be taken. */ - uint8_t negative_action : 1; /**< If this flag is set, the notification has a negative action that can be taken. */ -} ble_ancs_c_notif_flags_t; - -/**@brief iOS notification structure. */ -typedef struct -{ - ble_ancs_c_evt_id_values_t evt_id; /**< Whether the notification was added, removed, or modified. */ - ble_ancs_c_notif_flags_t evt_flags; /**< Bitmask to signal if a special condition applies to the notification, for example, "Silent" or "Important". */ - ble_ancs_c_category_id_values_t category_id; /**< Classification of the notification type, for example, email or location. */ - uint8_t category_count; /**< Current number of active notifications for this category ID. */ - uint32_t notif_uid; /**< Notification UID. */ -} ble_ancs_c_evt_notif_t; - - -/**@brief iOS notification attribute structure for incomming attributes. */ -typedef struct -{ - uint32_t notif_uid; /**< UID of the notification that the attribute belongs to.*/ - uint16_t attr_len; /**< Length of the received attribute data. */ - ble_ancs_c_notif_attr_id_values_t attr_id; /**< Classification of the attribute type, for example, title or date. */ -} ble_ancs_c_evt_notif_attr_t; - - -/**@brief iOS notification attribute content wanted by our application. */ -typedef struct -{ - bool get; /**< Boolean to determine if this attribute will be requested from the Notification Provider. */ - ble_ancs_c_notif_attr_id_values_t attr_id; /**< Attribute ID: AppIdentifier(0), Title(1), Subtitle(2), Message(3), MessageSize(4), Date(5), PositiveActionLabel(6), NegativeActionLabel(7). */ - uint16_t attr_len; /**< Length of the attribute. If more data is received from the Notification Provider, all data beyond this length is discarded. */ - uint8_t * p_attr_data; /**< Pointer to where the memory is allocated for storing incoming attributes. */ -} ble_ancs_c_attr_list_t; - - -/**@brief ANCS client module event structure. - * - * @details The structure contains the event that should be handled by the main application. - */ -typedef struct -{ - ble_ancs_c_evt_type_t evt_type; /**< Type of event. */ - ble_uuid_t uuid; /**< UUID of the event if it is an iOS notification. */ - ble_ancs_c_evt_notif_t notif; /**< iOS notification. */ - ble_ancs_c_evt_notif_attr_t attr; /**< Currently received attribute for a given notification. */ - uint32_t error_code; /**< Additional status or error code if the event was caused by a stack error or GATT status, for example, during service discovery. */ - ble_ancs_c_attr_list_t * ancs_attr_list; /**< List of attributes that will be requested if attributes are requested for a notification.*/ -} ble_ancs_c_evt_t; - - -/**@brief iOS notification event handler type. */ -typedef void (*ble_ancs_c_evt_handler_t) (ble_ancs_c_evt_t * p_evt); - - -/**@brief iOS notification structure, which contains various status information for the client. */ -typedef struct -{ - ble_ancs_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Apple Notification client application. */ - ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ - uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack; BLE_CONN_HANDLE_INVALID if not in a connection). */ - uint8_t central_handle; /**< Handle of the currently connected peer (if we have a bond in the Device Manager). */ - uint8_t service_handle; /**< Handle of the service in the database to use for this instance. */ -} ble_ancs_c_t; - - -/**@brief Apple Notification client init structure, which contains all options and data needed for - * initialization of the client.*/ -typedef struct -{ - ble_ancs_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */ - ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ -} ble_ancs_c_init_t; - - -/**@brief Apple Notification Center Service UUIDs. */ -extern const ble_uuid128_t ble_ancs_base_uuid128; /**< Service UUID. */ -extern const ble_uuid128_t ble_ancs_cp_base_uuid128; /**< Control point UUID. */ -extern const ble_uuid128_t ble_ancs_ns_base_uuid128; /**< Notification source UUID. */ -extern const ble_uuid128_t ble_ancs_ds_base_uuid128; /**< Data source UUID. */ - - -/**@brief Function for handling the application's BLE Stack events. - * - * @details Handles all events from the BLE stack that are of interest to the ANCS client. - * - * @param[in] p_ancs ANCS client structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -void ble_ancs_c_on_ble_evt(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt); - - -/**@brief Function for handling the ANCS client Device Manager events. - * - * @details This function handles all events from the Device Manager that are of interest to the - * ANCS client. When reconnecting to the existing central and creating new bonds for - * handling service discovery and writing to the Apple Notification Control Point, the - * Notification Provider will send new and unread iOS notifications again. - * - * @param[in] p_ancs ANCS client structure. - * @param[in] p_handle Pointer to the ANCS device handle. - * @param[in] p_dm_evt Event received from the Device Manager. - */ -void ble_ancs_c_on_device_manager_evt(ble_ancs_c_t * p_ancs, - dm_handle_t const * p_handle, - dm_event_t const * p_dm_evt); - - -/**@brief Function for initializing the ANCS client. - * - * @param[out] p_ancs ANCS client structure. This structure must be - * supplied by the application. It is initialized by this function - * and will later be used to identify this particular client instance. - * @param[in] p_ancs_init Information needed to initialize the client. - * - * @retval NRF_SUCCESS If the client was initialized successfully. Otherwise, an error code is returned. - */ -uint32_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, const ble_ancs_c_init_t * p_ancs_init); - - -/**@brief Function for writing to the CCCD to enable notifications from the Apple Notification Service. - * - * @param[in] p_ancs iOS notification structure. This structure must be supplied by - * the application. It identifies the particular client instance to use. - * - * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. - */ -uint32_t ble_ancs_c_notif_source_notif_enable(const ble_ancs_c_t * p_ancs); - - -/**@brief Function for writing to the CCCD to enable data source notifications from the ANCS. - * - * @param[in] p_ancs iOS notification structure. This structure must be supplied by - * the application. It identifies the particular client instance to use. - * - * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. - */ -uint32_t ble_ancs_c_data_source_notif_enable(const ble_ancs_c_t * p_ancs); - - -/**@brief Function for writing to the CCCD to disable notifications from the ANCS. - * - * @param[in] p_ancs iOS notification structure. This structure must be supplied by - * the application. It identifies the particular client instance to use. - * - * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. - */ -uint32_t ble_ancs_c_notif_source_notif_disable(const ble_ancs_c_t * p_ancs); - - -/**@brief Function for writing to the CCCD to disable data source notifications from the ANCS. - * - * @param[in] p_ancs iOS notification structure. This structure must be supplied by - * the application. It identifies the particular client instance to use. - * - * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. - */ -uint32_t ble_ancs_c_data_source_notif_disable(const ble_ancs_c_t * p_ancs); - - -/**@brief Function for registering attributes that will be requested if ble_ancs_c_request_attrs - * is called. - * - * @param[in] id ID of the attribute that will be added. - * @param[in] p_data Pointer to a buffer where the data of the attribute can be stored. - * @param[in] len Length of the buffer where the data of the attribute can be stored. - - * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. - */ -uint32_t ble_ancs_c_attr_add(const ble_ancs_c_notif_attr_id_values_t id, uint8_t * p_data, const uint16_t len); - - -/**@brief Function for requesting attributes for a notification. - * - * @param[in] p_notif Pointer to the notification whose attributes will be requested from - * the Notification Provider. - * - * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. - */ -uint32_t ble_ancs_c_request_attrs(const ble_ancs_c_evt_notif_t * p_notif); - -#endif // BLE_ANCS_C_H__ - -/** @} */ - diff --git a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c b/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c new file mode 100644 index 0000000..4bda9f9 --- /dev/null +++ b/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c @@ -0,0 +1,659 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA. + * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working. + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_ANCS_C) +#include "nrf_ble_ancs_c.h" +#include "ancs_tx_buffer.h" +#include "ancs_attr_parser.h" +#include "ancs_app_attr_get.h" +#include "ble_err.h" +#include "ble_srv_common.h" +#include "nrf_assert.h" +#include "ble_db_discovery.h" +#include "app_error.h" +#define NRF_LOG_MODULE_NAME "BLE_ANCS_C" +#include "nrf_log.h" + +#define BLE_ANCS_NOTIF_EVT_ID_INDEX 0 /**< Index of the Event ID field when parsing notifications. */ +#define BLE_ANCS_NOTIF_FLAGS_INDEX 1 /**< Index of the Flags field when parsing notifications. */ +#define BLE_ANCS_NOTIF_CATEGORY_ID_INDEX 2 /**< Index of the Category ID field when parsing notifications. */ +#define BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX 3 /**< Index of the Category Count field when parsing notifications. */ +#define BLE_ANCS_NOTIF_NOTIF_UID 4 /**< Index of the Notification UID field when patsin notifications. */ + +#define BLE_CCCD_NOTIFY_BIT_MASK 0x0001 /**< Enable notification bit. */ + +#define TIME_STRING_LEN 15 /**< Unicode Technical Standard (UTS) #35 date format pattern "yyyyMMdd'T'HHmmSS" + "'\0'". */ + + +/**@brief 128-bit service UUID for the Apple Notification Center Service. + */ +const ble_uuid128_t ble_ancs_base_uuid128 = +{ + { + // 7905F431-B5CE-4E99-A40F-4B1E122D00D0 + 0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4, + 0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79 + } +}; + + +/**@brief 128-bit control point UUID. + */ +const ble_uuid128_t ble_ancs_cp_base_uuid128 = +{ + { + // 69d1d8f3-45e1-49a8-9821-9BBDFDAAD9D9 + 0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98, + 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69 + } +}; + +/**@brief 128-bit notification source UUID. +*/ +const ble_uuid128_t ble_ancs_ns_base_uuid128 = +{ + { + // 9FBF120D-6301-42D9-8C58-25E699A21DBD + 0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c, + 0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f + + } +}; + +/**@brief 128-bit data source UUID. +*/ +const ble_uuid128_t ble_ancs_ds_base_uuid128 = +{ + { + // 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB + 0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe, + 0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22 + } +}; + + +/**@brief Function for handling Disconnected event received from the SoftDevice. + * + * @details This function check if the disconnect event is happening on the link + * associated with the current instance of the module, if so it will set its + * conn_handle to invalid. + * + * @param[in] p_ancs Pointer to the ANCS client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_disconnected(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) +{ + if (p_ancs->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ancs->conn_handle = BLE_CONN_HANDLE_INVALID; + } +} + + +void ble_ancs_c_on_db_disc_evt(ble_ancs_c_t * p_ancs, ble_db_discovery_evt_t * p_evt) +{ + NRF_LOG_INFO("Database Discovery handler called with event 0x%x\r\n", p_evt->evt_type); + + ble_ancs_c_evt_t evt; + ble_gatt_db_char_t * p_chars; + + p_chars = p_evt->params.discovered_db.charateristics; + + // Check if the ANCS Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && + p_evt->params.discovered_db.srv_uuid.uuid == ANCS_UUID_SERVICE && + p_evt->params.discovered_db.srv_uuid.type == p_ancs->service.service.uuid.type) + { + // Find the handles of the ANCS characteristic. + uint32_t i; + + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + switch (p_chars[i].characteristic.uuid.uuid) + { + case ANCS_UUID_CHAR_CONTROL_POINT: + NRF_LOG_INFO("Control Point Characteristic found.\r\n"); + memcpy(&evt.service.control_point_char, + &p_chars[i].characteristic, + sizeof(ble_gattc_char_t)); + break; + + case ANCS_UUID_CHAR_DATA_SOURCE: + NRF_LOG_INFO("Data Source Characteristic found.\r\n"); + memcpy(&evt.service.data_source_char, + &p_chars[i].characteristic, + sizeof(ble_gattc_char_t)); + evt.service.data_source_cccd.handle = p_chars[i].cccd_handle; + break; + + case ANCS_UUID_CHAR_NOTIFICATION_SOURCE: + NRF_LOG_INFO("Notification point Characteristic found.\r\n"); + memcpy(&evt.service.notif_source_char, + &p_chars[i].characteristic, + sizeof(ble_gattc_char_t)); + evt.service.notif_source_cccd.handle = p_chars[i].cccd_handle; + break; + + default: + break; + } + } + evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_COMPLETE; + evt.conn_handle = p_evt->conn_handle; + p_ancs->evt_handler(&evt); + } + else + { + evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_FAILED; + p_ancs->evt_handler(&evt); + } +} + + +/**@brief Function for checking if data in an iOS notification is out of bounds. + * + * @param[in] notif An iOS notification. + * + * @retval NRF_SUCCESS If the notification is within bounds. + * @retval NRF_ERROR_INVALID_PARAM If the notification is out of bounds. + */ +static uint32_t ble_ancs_verify_notification_format(const ble_ancs_c_evt_notif_t * notif) +{ + if( (notif->evt_id >= BLE_ANCS_NB_OF_EVT_ID) + || (notif->category_id >= BLE_ANCS_NB_OF_CATEGORY_ID)) + { + return NRF_ERROR_INVALID_PARAM; + } + return NRF_SUCCESS; +} + +/**@brief Function for receiving and validating notifications received from the Notification Provider. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_data_src Pointer to data that was received from the Notification Provider. + * @param[in] hvx_len Length of the data that was received by the Notification Provider. + */ +static void parse_notif(const ble_ancs_c_t * p_ancs, + const uint8_t * p_data_src, + const uint16_t hvx_data_len) +{ + ble_ancs_c_evt_t ancs_evt; + uint32_t err_code; + if (hvx_data_len != BLE_ANCS_NOTIFICATION_DATA_LENGTH) + { + ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF; + p_ancs->evt_handler(&ancs_evt); + } + + /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */ + ancs_evt.notif.evt_id = + (ble_ancs_c_evt_id_values_t) p_data_src[BLE_ANCS_NOTIF_EVT_ID_INDEX]; + + ancs_evt.notif.evt_flags.silent = + (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_SILENT) & 0x01; + + ancs_evt.notif.evt_flags.important = + (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_IMPORTANT) & 0x01; + + ancs_evt.notif.evt_flags.pre_existing = + (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_PREEXISTING) & 0x01; + + ancs_evt.notif.evt_flags.positive_action = + (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION) & 0x01; + + ancs_evt.notif.evt_flags.negative_action = + (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION) & 0x01; + + ancs_evt.notif.category_id = + (ble_ancs_c_category_id_val_t) p_data_src[BLE_ANCS_NOTIF_CATEGORY_ID_INDEX]; + + ancs_evt.notif.category_count = p_data_src[BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX]; + ancs_evt.notif.notif_uid = uint32_decode(&p_data_src[BLE_ANCS_NOTIF_NOTIF_UID]); + /*lint -restore*/ + + err_code = ble_ancs_verify_notification_format(&ancs_evt.notif); + if (err_code == NRF_SUCCESS) + { + ancs_evt.evt_type = BLE_ANCS_C_EVT_NOTIF; + } + else + { + ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF; + } + + p_ancs->evt_handler(&ancs_evt); +} + + +ret_code_t nrf_ble_ancs_c_app_attr_request(ble_ancs_c_t * p_ancs, + const uint8_t * p_app_id, + uint32_t len) +{ + return ancs_c_app_attr_request(p_ancs, p_app_id, len); +} + + +/**@brief Function for receiving and validating notifications received from the Notification Provider. + * + * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs. + * @param[in] p_ble_evt Bluetooth stack event. + */ +static void on_evt_gattc_notif(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) +{ + const ble_gattc_evt_hvx_t * p_notif = &p_ble_evt->evt.gattc_evt.params.hvx; + + if(p_ble_evt->evt.gattc_evt.conn_handle != p_ancs->conn_handle) + { + return; + } + + if (p_notif->handle == p_ancs->service.notif_source_char.handle_value) + { + parse_notif(p_ancs, p_notif->data, p_notif->len); + } + else if (p_notif->handle == p_ancs->service.data_source_char.handle_value) + { + ancs_parse_get_attrs_response(p_ancs, p_notif->data, p_notif->len); + } + else + { + // No applicable action. + } +} + +/**@brief Function for handling error response events. + * + * @param[in] p_ancs_c Pointer to the Battery Service Client Structure. + * @param[in] p_ble_evt Pointer to the SoftDevice event. + */ +static void on_ctrlpt_error_rsp(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) +{ + ble_ancs_c_evt_t ancs_evt; + + ancs_evt.evt_type = BLE_ANCS_C_EVT_NP_ERROR; + ancs_evt.err_code_np = p_ble_evt->evt.gattc_evt.gatt_status; + + p_ancs->evt_handler(&ancs_evt); +} + +/**@brief Function for handling write response events. + * + * @param[in] p_ancs_c Pointer to the Battery Service Client Structure. + * @param[in] p_ble_evt Pointer to the SoftDevice event. + */ +static void on_write_rsp(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) +{ + // Check if the event if on the link for this instance + if (p_ancs->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + if ((p_ble_evt->evt.gattc_evt.error_handle != BLE_GATT_HANDLE_INVALID) + && (p_ble_evt->evt.gattc_evt.error_handle == p_ancs->service.control_point_char.handle_value)) + { + on_ctrlpt_error_rsp(p_ancs,p_ble_evt); + } + // Check if there is any message to be sent across to the peer and send it. + tx_buffer_process(); +} + + +void ble_ancs_c_on_ble_evt(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt) +{ + uint16_t evt = p_ble_evt->header.evt_id; + + switch (evt) + { + case BLE_GATTC_EVT_WRITE_RSP: + on_write_rsp(p_ancs, p_ble_evt); + break; + + case BLE_GATTC_EVT_HVX: + on_evt_gattc_notif(p_ancs, p_ble_evt); + break; + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ancs, p_ble_evt); + break; + default: + break; + } +} + + +ret_code_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, const ble_ancs_c_init_t * p_ancs_init) +{ + uint32_t err_code; + + //Verify that the parameters needed for to initialize this instance of ANCS are not NULL. + VERIFY_PARAM_NOT_NULL(p_ancs); + VERIFY_PARAM_NOT_NULL(p_ancs_init); + VERIFY_PARAM_NOT_NULL(p_ancs_init->evt_handler); + + //Initialize state for the attribute parsing state machine. + p_ancs->parse_info.parse_state = COMMAND_ID; + p_ancs->parse_info.p_data_dest = NULL; + p_ancs->parse_info.current_attr_index = 0; + p_ancs->parse_info.current_app_id_index = 0; + + p_ancs->evt_handler = p_ancs_init->evt_handler; + p_ancs->error_handler = p_ancs_init->error_handler; + p_ancs->conn_handle = BLE_CONN_HANDLE_INVALID; + + p_ancs->service.data_source_cccd.uuid.uuid = BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG; + p_ancs->service.notif_source_cccd.uuid.uuid = BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG; + + // Make sure instance of service is clear. GATT handles inside the service and characteristics are set to @ref BLE_GATT_HANDLE_INVALID. + memset(&p_ancs->service, 0, sizeof(ble_ancs_c_service_t)); + tx_buffer_init(); + + // Assign UUID types. + err_code = sd_ble_uuid_vs_add(&ble_ancs_base_uuid128, &p_ancs->service.service.uuid.type); + VERIFY_SUCCESS(err_code); + + err_code = sd_ble_uuid_vs_add(&ble_ancs_cp_base_uuid128, &p_ancs->service.control_point_char.uuid.type); + VERIFY_SUCCESS(err_code); + + err_code = sd_ble_uuid_vs_add(&ble_ancs_ns_base_uuid128, &p_ancs->service.notif_source_char.uuid.type); + VERIFY_SUCCESS(err_code); + + err_code = sd_ble_uuid_vs_add(&ble_ancs_ds_base_uuid128, &p_ancs->service.data_source_char.uuid.type); + VERIFY_SUCCESS(err_code); + + // Assign UUID to the service. + p_ancs->service.service.uuid.uuid = ANCS_UUID_SERVICE; + p_ancs->service.service.uuid.type = p_ancs->service.service.uuid.type; + + return ble_db_discovery_evt_register(&p_ancs->service.service.uuid); +} + + +/**@brief Function for creating a TX message for writing a CCCD. + * + * @param[in] conn_handle Connection handle on which to perform the configuration. + * @param[in] handle_cccd Handle of the CCCD. + * @param[in] enable Enable or disable GATTC notifications. + * + * @retval NRF_SUCCESS If the message was created successfully. + * @retval NRF_ERROR_INVALID_PARAM If one of the input parameters was invalid. + */ +static uint32_t cccd_configure(const uint16_t conn_handle, const uint16_t handle_cccd, bool enable) +{ + tx_message_t p_msg; + memset(&p_msg, 0, sizeof(tx_message_t)); + uint16_t cccd_val = enable ? BLE_CCCD_NOTIFY_BIT_MASK : 0; + + p_msg.req.write_req.gattc_params.handle = handle_cccd; + p_msg.req.write_req.gattc_params.len = 2; + p_msg.req.write_req.gattc_params.p_value = p_msg.req.write_req.gattc_value; + p_msg.req.write_req.gattc_params.offset = 0; + p_msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + p_msg.req.write_req.gattc_value[0] = LSB_16(cccd_val); + p_msg.req.write_req.gattc_value[1] = MSB_16(cccd_val); + p_msg.conn_handle = conn_handle; + p_msg.type = WRITE_REQ; + + tx_buffer_insert(&p_msg); + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +ret_code_t ble_ancs_c_notif_source_notif_enable(const ble_ancs_c_t * p_ancs) +{ + NRF_LOG_INFO("Enable Notification Source notifications. writing to handle: %i \r\n", + p_ancs->service.notif_source_cccd.handle); + return cccd_configure(p_ancs->conn_handle, p_ancs->service.notif_source_cccd.handle, true); +} + + +ret_code_t ble_ancs_c_notif_source_notif_disable(const ble_ancs_c_t * p_ancs) +{ + return cccd_configure(p_ancs->conn_handle, p_ancs->service.notif_source_cccd.handle, false); +} + + +ret_code_t ble_ancs_c_data_source_notif_enable(const ble_ancs_c_t * p_ancs) +{ + NRF_LOG_INFO("Enable Data Source notifications. Writing to handle: %i \r\n", + p_ancs->service.data_source_cccd.handle); + return cccd_configure(p_ancs->conn_handle, p_ancs->service.data_source_cccd.handle, true); +} + + +ret_code_t ble_ancs_c_data_source_notif_disable(const ble_ancs_c_t * p_ancs) +{ + return cccd_configure(p_ancs->conn_handle, p_ancs->service.data_source_cccd.handle, false); +} + + +uint32_t ble_ancs_get_notif_attrs(ble_ancs_c_t * p_ancs, + const uint32_t p_uid) +{ + tx_message_t p_msg; + memset(&p_msg, 0, sizeof(tx_message_t)); + + uint32_t index = 0; + p_ancs->number_of_requested_attr = 0; + + + p_msg.req.write_req.gattc_params.handle = p_ancs->service.control_point_char.handle_value; + p_msg.req.write_req.gattc_params.p_value = p_msg.req.write_req.gattc_value; + p_msg.req.write_req.gattc_params.offset = 0; + p_msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + + //Encode Command ID. + p_msg.req.write_req.gattc_value[index++] = BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES; + + //Encode Notification UID. + index += uint32_encode(p_uid, &(p_msg.req.write_req.gattc_value[index])); + + //Encode Attribute ID. + for (uint32_t attr = 0; attr < BLE_ANCS_NB_OF_NOTIF_ATTR; attr++) + { + if (p_ancs->ancs_notif_attr_list[attr].get == true) + { + p_msg.req.write_req.gattc_value[index++] = attr; + if ((attr == BLE_ANCS_NOTIF_ATTR_ID_TITLE) || + (attr == BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE) || + (attr == BLE_ANCS_NOTIF_ATTR_ID_MESSAGE)) + { + //Encode Length field, only applicable for Title, Subtitle and Message + index += uint16_encode(p_ancs->ancs_notif_attr_list[attr].attr_len, + &(p_msg.req.write_req.gattc_value[index])); + } + p_ancs->number_of_requested_attr++; + } + } + p_msg.req.write_req.gattc_params.len = index; + p_msg.conn_handle = p_ancs->conn_handle; + p_msg.type = WRITE_REQ; + p_ancs->parse_info.expected_number_of_attrs = p_ancs->number_of_requested_attr; + + tx_buffer_insert(&p_msg); + tx_buffer_process(); + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_ancs_c_attr_add(ble_ancs_c_t * p_ancs, + const ble_ancs_c_notif_attr_id_val_t id, + uint8_t * p_data, + const uint16_t len) +{ + VERIFY_PARAM_NOT_NULL(p_data); + + if((len == 0) || (len > BLE_ANCS_ATTR_DATA_MAX)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_ancs->ancs_notif_attr_list[id].get = true; + p_ancs->ancs_notif_attr_list[id].attr_len = len; + p_ancs->ancs_notif_attr_list[id].p_attr_data = p_data; + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_ancs_c_app_attr_add(ble_ancs_c_t * p_ancs, + const ble_ancs_c_app_attr_id_val_t id, + uint8_t * p_data, + const uint16_t len) +{ + VERIFY_PARAM_NOT_NULL(p_ancs); + VERIFY_PARAM_NOT_NULL(p_data); + + if((len == 0) || (len > BLE_ANCS_ATTR_DATA_MAX)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_ancs->ancs_app_attr_list[id].get = true; + p_ancs->ancs_app_attr_list[id].attr_len = len; + p_ancs->ancs_app_attr_list[id].p_attr_data = p_data; + + return NRF_SUCCESS; +} + +ret_code_t ble_ancs_c_app_attr_remove(ble_ancs_c_t * p_ancs, + const ble_ancs_c_app_attr_id_val_t id) +{ + p_ancs->ancs_app_attr_list[id].get = false; + p_ancs->ancs_app_attr_list[id].attr_len = 0; + p_ancs->ancs_app_attr_list[id].p_attr_data = NULL; + return NRF_SUCCESS; +} + +ret_code_t ble_ancs_c_notif_attr_remove(ble_ancs_c_t * p_ancs, + const ble_ancs_c_notif_attr_id_val_t id) +{ + p_ancs->ancs_notif_attr_list[id].get = false; + p_ancs->ancs_notif_attr_list[id].attr_len = 0; + p_ancs->ancs_notif_attr_list[id].p_attr_data = NULL; + return NRF_SUCCESS; +} + +ret_code_t nrf_ble_ancs_c_attr_req_clear_all(ble_ancs_c_t * p_ancs) +{ + memset(p_ancs->ancs_notif_attr_list, 0 , sizeof(p_ancs->ancs_notif_attr_list)); + memset(p_ancs->ancs_app_attr_list, 0 , sizeof(p_ancs->ancs_app_attr_list)); + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_ancs_c_request_attrs(ble_ancs_c_t * p_ancs, + const ble_ancs_c_evt_notif_t * p_notif) +{ + uint32_t err_code; + err_code = ble_ancs_verify_notification_format(p_notif); + VERIFY_SUCCESS(err_code); + + err_code = ble_ancs_get_notif_attrs(p_ancs, p_notif->notif_uid); + p_ancs->parse_info.parse_state = COMMAND_ID; + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + +static uint16_t encode_notif_action(uint8_t * p_encoded_data, uint32_t uid, ble_ancs_c_action_id_values_t action_id) +{ + uint8_t index = 0; + + p_encoded_data[index++] = BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION; + index += uint32_encode(uid, &p_encoded_data[index]); + p_encoded_data[index++] = (uint8_t)action_id; + + return index; +} + +ret_code_t nrf_ancs_perform_notif_action(ble_ancs_c_t * p_ancs, uint32_t uid, ble_ancs_c_action_id_values_t action_id) +{ + VERIFY_PARAM_NOT_NULL(p_ancs); + + tx_message_t msg; + memset(&msg, 0, sizeof(tx_message_t)); + + uint16_t len = 0; + + len = encode_notif_action(msg.req.write_req.gattc_value, uid, action_id); + + msg.req.write_req.gattc_params.handle = p_ancs->service.control_point_char.handle_value; + msg.req.write_req.gattc_params.p_value = msg.req.write_req.gattc_value; + msg.req.write_req.gattc_params.offset = 0; + msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + + msg.req.write_req.gattc_params.len = len; + msg.conn_handle = p_ancs->conn_handle; + msg.type = WRITE_REQ; + + tx_buffer_insert(&msg); + tx_buffer_process(); + + return NRF_SUCCESS; +} + +ret_code_t nrf_ble_ancs_c_handles_assign(ble_ancs_c_t * p_ancs, + const uint16_t conn_handle, + const ble_ancs_c_service_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ancs); + + p_ancs->conn_handle = conn_handle; + + if(p_peer_handles != NULL) + { + p_ancs->service.control_point_char.handle_value = p_peer_handles->control_point_char.handle_value; + p_ancs->service.data_source_cccd.handle = p_peer_handles->data_source_cccd.handle; + p_ancs->service.data_source_char.handle_value = p_peer_handles->data_source_char.handle_value; + p_ancs->service.notif_source_cccd.handle = p_peer_handles->notif_source_cccd.handle; + p_ancs->service.notif_source_char.handle_value = p_peer_handles->notif_source_char.handle_value; + } + + return NRF_SUCCESS; +} + +#endif// NRF_MODULE_ENABLED(BLE_ANCS_C) + diff --git a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h b/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h new file mode 100644 index 0000000..6a7c974 --- /dev/null +++ b/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h @@ -0,0 +1,582 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_ancs_c Apple Notification Service client + * @{ + * @ingroup ble_sdk_srv + * + * @brief Apple Notification Center Service Client Module. + * + * @details Disclaimer: This client implementation of the Apple Notification Center Service can + * be changed at any time by Nordic Semiconductor ASA. Server implementations such as the + * ones found in iOS can be changed at any time by Apple and may cause this client + * implementation to stop working. + * + * This module implements the Apple Notification Center Service (ANCS) client. + * This client can be used as a Notification Consumer (NC) that receives data + * notifications from a Notification Provider (NP). The NP is typically an iOS + * device acting as a server. For terminology and up-to-date specs, see + * http://developer.apple.com. + * + * The term "notification" is used in two different meanings: + * - An iOS notification is the data received from the Notification Provider. + * - A GATTC notification is a way to transfer data with Bluetooth Smart. + * In this module, we receive iOS notifications using GATTC notifications. + * We use the full term (iOS notification or GATTC notification) where required to avoid confusion. + * + * Upon initializing the module, you must add the different iOS notification attributes you + * would like to receive for iOS notifications (see @ref nrf_ble_ancs_c_attr_add). + * + * Once a connection is established with a central device, the module does a service discovery to + * discover the ANCS server handles. If this succeeds (@ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE), + * the handles for the ANCS server are part of the @ref ble_ancs_c_evt_t structure and must be + * assigned to an ANCS_C instance using the @ref nrf_ble_ancs_c_handles_assign function. For more + * information about service discovery, see the @ref lib_ble_db_discovery documentation. + * + * The application can now subscribe to iOS notifications using + * @ref ble_ancs_c_notif_source_notif_enable. They arrive in the @ref BLE_ANCS_C_EVT_NOTIF event. + * @ref nrf_ble_ancs_c_request_attrs can be used to request attributes for the notifications. They + * arrive in the @ref BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE event. + * @ref nrf_ble_ancs_c_app_attr_request can be used to request attributes of the app that issued + * the notifications. They arrive in the @ref BLE_ANCS_C_EVT_APP_ATTRIBUTE event. + * @ref nrf_ancs_perform_notif_action can be used to make the Notification Provider perform an + * action based on the provided notification. + * + * @msc + * hscale = "1.5"; + * Application, ANCS_C; + * |||; + * Application=>ANCS_C [label = "ble_ancs_c_attr_add(attribute)"]; + * Application=>ANCS_C [label = "ble_ancs_c_init(ancs_instance, event_handler)"]; + * ...; + * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_DISCOVERY_COMPLETE"]; + * Application=>ANCS_C [label = "ble_ancs_c_handles_assign(ancs_instance, conn_handle, service_handles)"]; + * Application=>ANCS_C [label = "ble_ancs_c_notif_source_notif_enable(ancs_instance)"]; + * Application=>ANCS_C [label = "ble_ancs_c_data_source_notif_enable(ancs_instance)"]; + * |||; + * ...; + * |||; + * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_NOTIF"]; + * |||; + * ...; + * |||; + * Application=>ANCS_C [label = "ble_ancs_c_request_attrs(attr_id, buffer)"]; + * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE"]; + * |||; + * @endmsc + * + * @note The application must propagate BLE stack events to this module + * by calling ble_ancs_c_on_ble_evt() from the @ref softdevice_handler callback. + */ +#ifndef BLE_ANCS_C_H__ +#define BLE_ANCS_C_H__ + +#include "ble_types.h" +#include "ble_srv_common.h" +#include "sdk_errors.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif +#define BLE_ANCS_ATTR_DATA_MAX 32 //!< Maximum data length of an iOS notification attribute. +#define BLE_ANCS_NB_OF_CATEGORY_ID 12 //!< Number of iOS notification categories: Other, Incoming Call, Missed Call, Voice Mail, Social, Schedule, Email, News, Health And Fitness, Business And Finance, Location, Entertainment. +#define BLE_ANCS_NB_OF_NOTIF_ATTR 8 //!< Number of iOS notification attributes: AppIdentifier, Title, Subtitle, Message, MessageSize, Date, PositiveActionLabel, NegativeActionLabel. +#define BLE_ANCS_NB_OF_APP_ATTR 1 //!< Number of iOS application attributes: DisplayName. +#define BLE_ANCS_NB_OF_EVT_ID 3 //!< Number of iOS notification events: Added, Modified, Removed. + +/** @brief Length of the iOS notification data. + * + * @details 8 bytes: + * Event ID |Event flags |Category ID |Category count|Notification UID + * ---------|------------|------------|--------------|---------------- + * 1 byte | 1 byte | 1 byte | 1 byte | 4 bytes + */ +#define BLE_ANCS_NOTIFICATION_DATA_LENGTH 8 + +#define ANCS_UUID_SERVICE 0xF431 //!< 16-bit service UUID for the Apple Notification Center Service. +#define ANCS_UUID_CHAR_CONTROL_POINT 0xD8F3 //!< 16-bit control point UUID. +#define ANCS_UUID_CHAR_DATA_SOURCE 0xC6E9 //!< 16-bit data source UUID. +#define ANCS_UUID_CHAR_NOTIFICATION_SOURCE 0x120D //!< 16-bit notification source UUID. + +#define BLE_ANCS_EVENT_FLAG_SILENT 0 //!< 0b.......1 Silent: First (LSB) bit is set. All flags can be active at the same time. +#define BLE_ANCS_EVENT_FLAG_IMPORTANT 1 //!< 0b......1. Important: Second (LSB) bit is set. All flags can be active at the same time. +#define BLE_ANCS_EVENT_FLAG_PREEXISTING 2 //!< 0b.....1.. Pre-existing: Third (LSB) bit is set. All flags can be active at the same time. +#define BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION 3 //!< 0b....1... Positive action: Fourth (LSB) bit is set. All flags can be active at the same time. +#define BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION 4 //!< 0b...1.... Negative action: Fifth (LSB) bit is set. All flags can be active at the same time. + +/** @defgroup BLE_ANCS_NP_ERROR_CODES Notification Provider (iOS) Error Codes + * @{ */ +#define BLE_ANCS_NP_UNKNOWN_COMMAND 0x01A0 //!< The command ID is unknown to the NP. +#define BLE_ANCS_NP_INVALID_COMMAND 0x01A1 //!< The command format is invalid. +#define BLE_ANCS_NP_INVALID_PARAMETER 0x01A2 //!< One or more parameters does not exist in the NP. +#define BLE_ANCS_NP_ACTION_FAILED 0x01A3 //!< The action failed to be performed by the NP. +/** @} */ + +/**@brief Event types that are passed from client to application on an event. */ +typedef enum +{ + BLE_ANCS_C_EVT_DISCOVERY_COMPLETE, /**< A successful connection has been established and the service was found on the connected peer. */ + BLE_ANCS_C_EVT_DISCOVERY_FAILED, /**< It was not possible to discover the service or characteristics of the connected peer. */ + BLE_ANCS_C_EVT_NOTIF, /**< An iOS notification was received on the notification source control point. */ + BLE_ANCS_C_EVT_INVALID_NOTIF, /**< An iOS notification was received on the notification source control point, but the format is invalid. */ + BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE, /**< A received iOS notification attribute has been parsed. */ + BLE_ANCS_C_EVT_APP_ATTRIBUTE, /**< An iOS app attribute has been parsed. */ + BLE_ANCS_C_EVT_NP_ERROR, /**< An error has been sent on the ANCS Control Point from the iOS Notification Provider. */ +} ble_ancs_c_evt_type_t; + +/**@brief Category IDs for iOS notifications. */ +typedef enum +{ + BLE_ANCS_CATEGORY_ID_OTHER, /**< The iOS notification belongs to the "other" category. */ + BLE_ANCS_CATEGORY_ID_INCOMING_CALL, /**< The iOS notification belongs to the "Incoming Call" category. */ + BLE_ANCS_CATEGORY_ID_MISSED_CALL, /**< The iOS notification belongs to the "Missed Call" category. */ + BLE_ANCS_CATEGORY_ID_VOICE_MAIL, /**< The iOS notification belongs to the "Voice Mail" category. */ + BLE_ANCS_CATEGORY_ID_SOCIAL, /**< The iOS notification belongs to the "Social" category. */ + BLE_ANCS_CATEGORY_ID_SCHEDULE, /**< The iOS notification belongs to the "Schedule" category. */ + BLE_ANCS_CATEGORY_ID_EMAIL, /**< The iOS notification belongs to the "E-mail" category. */ + BLE_ANCS_CATEGORY_ID_NEWS, /**< The iOS notification belongs to the "News" category. */ + BLE_ANCS_CATEGORY_ID_HEALTH_AND_FITNESS, /**< The iOS notification belongs to the "Health and Fitness" category. */ + BLE_ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE, /**< The iOS notification belongs to the "Buisness and Finance" category. */ + BLE_ANCS_CATEGORY_ID_LOCATION, /**< The iOS notification belongs to the "Location" category. */ + BLE_ANCS_CATEGORY_ID_ENTERTAINMENT /**< The iOS notification belongs to the "Entertainment" category. */ +} ble_ancs_c_category_id_val_t; + +/**@brief Event IDs for iOS notifications. */ +typedef enum +{ + BLE_ANCS_EVENT_ID_NOTIFICATION_ADDED, /**< The iOS notification was added. */ + BLE_ANCS_EVENT_ID_NOTIFICATION_MODIFIED, /**< The iOS notification was modified. */ + BLE_ANCS_EVENT_ID_NOTIFICATION_REMOVED /**< The iOS notification was removed. */ +} ble_ancs_c_evt_id_values_t; + +/**@brief Control point command IDs that the Notification Consumer can send to the Notification Provider. */ +typedef enum +{ + BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given notification. */ + BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given iOS app. */ + BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION, /**< Requests an action to be performed on a given notification, for example, dismiss an alarm. */ +} ble_ancs_c_cmd_id_val_t; + +/**@brief IDs for actions that can be performed for iOS notifications. */ +typedef enum +{ + ACTION_ID_POSITIVE = 0, /**< Positive action. */ + ACTION_ID_NEGATIVE /**< Negative action. */ +} ble_ancs_c_action_id_values_t; + +/**@brief App attribute ID values. + * @details Currently, only one value is defined. However, the number of app + * attributes might increase. Therefore, they are stored in an enumeration. + */ +typedef enum +{ + BLE_ANCS_APP_ATTR_ID_DISPLAY_NAME = 0 /**< Command used to get the display name for an app identifier. */ +} ble_ancs_c_app_attr_id_val_t; + +/**@brief IDs for iOS notification attributes. */ +typedef enum +{ + BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER = 0, /**< Identifies that the attribute data is of an "App Identifier" type. */ + BLE_ANCS_NOTIF_ATTR_ID_TITLE, /**< Identifies that the attribute data is a "Title". */ + BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE, /**< Identifies that the attribute data is a "Subtitle". */ + BLE_ANCS_NOTIF_ATTR_ID_MESSAGE, /**< Identifies that the attribute data is a "Message". */ + BLE_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE, /**< Identifies that the attribute data is a "Message Size". */ + BLE_ANCS_NOTIF_ATTR_ID_DATE, /**< Identifies that the attribute data is a "Date". */ + BLE_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, /**< The notification has a "Positive action" that can be executed associated with it. */ + BLE_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, /**< The notification has a "Negative action" that can be executed associated with it. */ +} ble_ancs_c_notif_attr_id_val_t; + + +/**@brief Flags for iOS notifications. */ +typedef struct +{ + uint8_t silent : 1; //!< If this flag is set, the notification has a low priority. + uint8_t important : 1; //!< If this flag is set, the notification has a high priority. + uint8_t pre_existing : 1; //!< If this flag is set, the notification is pre-existing. + uint8_t positive_action : 1; //!< If this flag is set, the notification has a positive action that can be taken. + uint8_t negative_action : 1; //!< If this flag is set, the notification has a negative action that can be taken. +} ble_ancs_c_notif_flags_t; + + +/**@brief Parsing states for received iOS notification and app attributes. + */ +typedef enum +{ + COMMAND_ID, /**< Parsing the command ID. */ + NOTIF_UID, /**< Parsing the notification UID. */ + APP_ID, /**< Parsing app ID. */ + ATTR_ID, /**< Parsing attribute ID. */ + ATTR_LEN1, /**< Parsing the LSB of the attribute length. */ + ATTR_LEN2, /**< Parsing the MSB of the attribute length. */ + ATTR_DATA, /**< Parsing the attribute data. */ + ATTR_SKIP, /**< Parsing is skipped for the rest (or entire) of an attribute. */ + DONE, /**< Parsing for one attribute is done. */ +} ble_ancs_c_parse_state_t; + + +/**@brief iOS notification structure. */ +typedef struct +{ + uint32_t notif_uid; //!< Notification UID. + ble_ancs_c_evt_id_values_t evt_id; //!< Whether the notification was added, removed, or modified. + ble_ancs_c_notif_flags_t evt_flags; //!< Bitmask to signal if a special condition applies to the notification, for example, "Silent" or "Important". + ble_ancs_c_category_id_val_t category_id; //!< Classification of the notification type, for example, email or location. + uint8_t category_count; //!< Current number of active notifications for this category ID. +} ble_ancs_c_evt_notif_t; + + +/**@brief iOS attribute structure. This type is used for both notification attributes and app attributes. */ +typedef struct +{ + uint16_t attr_len; //!< Length of the received attribute data. + uint32_t attr_id; //!< Classification of the attribute type, for example, title or date. + uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes. +} ble_ancs_c_attr_t; + +/**@brief iOS notification attribute structure for incoming attributes. */ +typedef struct +{ + uint32_t notif_uid; //!< UID of the notification that the attribute belongs to. + ble_ancs_c_attr_t attrs; //!< A received attribute. +} ble_ancs_c_evt_attr_t; + +typedef struct +{ + uint16_t attr_len; //!< Length of the received attribute data. + uint32_t attr_id; //!< Classification of the attribute type, for example, title or date. + uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes. +} ble_ancs_c_evt_app_attr_t; + +/**@brief iOS notification attribute content wanted by our application. */ +typedef struct +{ + bool get; //!< Boolean to determine if this attribute will be requested from the Notification Provider. + uint32_t attr_id; //!< Attribute ID: AppIdentifier(0), Title(1), Subtitle(2), Message(3), MessageSize(4), Date(5), PositiveActionLabel(6), NegativeActionLabel(7). + uint16_t attr_len; //!< Length of the attribute. If more data is received from the Notification Provider, all data beyond this length is discarded. + uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes. +} ble_ancs_c_attr_list_t; + + +/**@brief Structure used for holding the Apple Notification Center Service found during the + discovery process. + */ +typedef struct +{ + ble_gattc_service_t service; //!< The GATT Service holding the discovered Apple Notification Center Service. (0xF431). + ble_gattc_char_t control_point_char; //!< ANCS Control Point Characteristic. Allows interaction with the peer (0xD8F3). + ble_gattc_char_t notif_source_char; //!< ANCS Notification Source Characteristic. Keeps track of arrival, modification, and removal of notifications (0x120D). + ble_gattc_desc_t notif_source_cccd; //!< ANCS Notification Source Characteristic Descriptor. Enables or disables GATT notifications. + ble_gattc_char_t data_source_char; //!< ANCS Data Source Characteristic, where attribute data for the notifications is received from peer (0xC6E9). + ble_gattc_desc_t data_source_cccd; //!< ANCS Data Source Characteristic Descriptor. Enables or disables GATT notifications. +} ble_ancs_c_service_t; + + +/**@brief ANCS client module event structure. + * + * @details The structure contains the event that should be handled by the main application. + */ +typedef struct +{ + ble_ancs_c_evt_type_t evt_type; //!< Type of event. + uint16_t conn_handle; //!< Connection handle on which the ANCS service was discovered on the peer device. This field will be filled if the @p evt_type is @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE. + ble_ancs_c_evt_notif_t notif; //!< iOS notification. This field will be filled if @p evt_type is @ref BLE_ANCS_C_EVT_NOTIF. + uint16_t err_code_np; //!< An error coming from the Notification Provider. This field will be filled with @ref BLE_ANCS_NP_ERROR_CODES if @p evt_type is @ref BLE_ANCS_C_EVT_NP_ERROR. + ble_ancs_c_attr_t attr; //!< iOS notification attribute or app attribute, depending on the event type. + uint32_t notif_uid; //!< Notification UID. + uint8_t app_id[BLE_ANCS_ATTR_DATA_MAX]; //!< App identifier. + ble_ancs_c_service_t service; //!< Information on the discovered Alert Notification Service. This field will be filled if the @p evt_type is @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE. +} ble_ancs_c_evt_t; + + +/**@brief iOS notification event handler type. */ +typedef void (*ble_ancs_c_evt_handler_t) (ble_ancs_c_evt_t * p_evt); + + +typedef struct +{ + ble_ancs_c_attr_list_t * p_attr_list; //!< The current list of attributes being parsed. This field will point to either @ref ble_ancs_c_t::ancs_notif_attr_list or @ref ble_ancs_c_t::ancs_app_attr_list. + uint32_t nb_of_attr; //!< Number of possible attributes. When parsing begins, it is set to either @ref BLE_ANCS_NB_OF_NOTIF_ATTR or @ref BLE_ANCS_NB_OF_APP_ATTR. + uint32_t expected_number_of_attrs; //!< The number of attributes expected upon receiving attributes. Keeps track of when to stop reading incoming attributes. + ble_ancs_c_parse_state_t parse_state; //!< ANCS notification attribute parsing state. + ble_ancs_c_cmd_id_val_t command_id; //!< Variable to keep track of what command type we are currently parsing ( @ref BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES or @ref BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES. + uint8_t * p_data_dest; //!< Attribute that the parsed data will be copied into. + uint16_t current_attr_index; //!< Variable to keep track of how much (for a given attribute) we are done parsing. + uint32_t current_app_id_index; //!< Variable to keep track of how much (for a given app identifier) we are done parsing. +} ble_ancs_parse_sm_t; + + +/**@brief iOS notification structure, which contains various status information for the client. */ +typedef struct +{ + ble_ancs_c_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Apple Notification client application. + ble_srv_error_handler_t error_handler; //!< Function to be called in case of an error. + uint16_t conn_handle; //!< Handle of the current connection. Set with @ref nrf_ble_ancs_c_handles_assign when connected. + ble_ancs_c_service_t service; //!< Structure to store the different handles and UUIDs related to the service. + ble_ancs_c_attr_list_t ancs_notif_attr_list[BLE_ANCS_NB_OF_NOTIF_ATTR]; //!< For all attributes; contains whether they should be requested upon attribute request and the length and buffer of where to store attribute data. + ble_ancs_c_attr_list_t ancs_app_attr_list[BLE_ANCS_NB_OF_APP_ATTR]; //!< For all app attributes; contains whether they should be requested upon attribute request and the length and buffer of where to store attribute data. + uint32_t number_of_requested_attr; //!< The number of attributes that will be requested when an iOS notification attribute request is made. + ble_ancs_parse_sm_t parse_info; //!< Structure containing different information used to parse incoming attributes (from data_source characteristic) correctly. + ble_ancs_c_evt_t evt; //!< The event is filled with several iterations of the @ref ancs_parse_get_attrs_response function when requesting iOS notification attributes. So we must allocate memory for it here. +} ble_ancs_c_t; + + +/**@brief Apple Notification client init structure, which contains all options and data needed for + * initialization of the client. */ +typedef struct +{ + ble_ancs_c_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Battery Service. + ble_srv_error_handler_t error_handler; //!< Function to be called in case of an error. +} ble_ancs_c_init_t; + + + +/**@brief Apple Notification Center Service UUIDs. */ +extern const ble_uuid128_t ble_ancs_base_uuid128; //!< Service UUID. +extern const ble_uuid128_t ble_ancs_cp_base_uuid128; //!< Control point UUID. +extern const ble_uuid128_t ble_ancs_ns_base_uuid128; //!< Notification source UUID. +extern const ble_uuid128_t ble_ancs_ds_base_uuid128; //!< Data source UUID. + + +/**@brief Function for handling the application's BLE stack events. + * + * @details Handles all events from the BLE stack that are of interest to the ANCS client. + * + * @param[in] p_ancs ANCS client structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void ble_ancs_c_on_ble_evt(ble_ancs_c_t * p_ancs, const ble_evt_t * p_ble_evt); + + +/**@brief Function for handling events from the database discovery module. + * + * @details This function will handle an event from the database discovery module and determine + * if it relates to the discovery of ANCS at the peer. If so, it will + * call the application's event handler indicating that ANCS has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_ancs Pointer to the ANCS client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + */ + void ble_ancs_c_on_db_disc_evt(ble_ancs_c_t * p_ancs, ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for initializing the ANCS client. + * + * @param[out] p_ancs ANCS client structure. This structure must be + * supplied by the application. It is initialized by this function + * and will later be used to identify this particular client instance. + * @param[in] p_ancs_init Information needed to initialize the client. + * + * @retval NRF_SUCCESS If the client was initialized successfully. Otherwise, an error code is returned. + */ +ret_code_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, const ble_ancs_c_init_t * p_ancs_init); + + +/**@brief Function for writing to the CCCD to enable notifications from the Apple Notification Service. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. + */ +ret_code_t ble_ancs_c_notif_source_notif_enable(const ble_ancs_c_t * p_ancs); + + +/**@brief Function for writing to the CCCD to enable data source notifications from the ANCS. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. + */ +ret_code_t ble_ancs_c_data_source_notif_enable(const ble_ancs_c_t * p_ancs); + + +/**@brief Function for writing to the CCCD to disable notifications from the ANCS. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. + */ +ret_code_t ble_ancs_c_notif_source_notif_disable(const ble_ancs_c_t * p_ancs); + + +/**@brief Function for writing to the CCCD to disable data source notifications from the ANCS. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * + * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned. + */ +ret_code_t ble_ancs_c_data_source_notif_disable(const ble_ancs_c_t * p_ancs); + + +/**@brief Function for registering attributes that will be requested when @ref nrf_ble_ancs_c_request_attrs + * is called. + * + * @param[in] p_ancs ANCS client instance on which the attribute will be registered. + * @param[in] id ID of the attribute that will be added. + * @param[in] p_data Pointer to a buffer where the data of the attribute can be stored. + * @param[in] len Length of the buffer where the data of the attribute can be stored. + + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_attr_add(ble_ancs_c_t * p_ancs, + const ble_ancs_c_notif_attr_id_val_t id, + uint8_t * p_data, + const uint16_t len); + + +/**@brief Function for removing attributes so that they will no longer be requested when + * @ref nrf_ble_ancs_c_request_attrs is called. + * + * @param[in] p_ancs ANCS client instance on which the attribute will be removed. + * @param[in] id ID of the attribute that will be removed. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_attr_remove(ble_ancs_c_t * p_ancs, + const ble_ancs_c_notif_attr_id_val_t id); + +/**@brief Function for removing attributes so that they will no longer be requested when + * @ref nrf_ble_ancs_c_app_attr_request is called. + * + * @param[in] p_ancs ANCS client instance on which the attribute will be removed. + * @param[in] id ID of the attribute that will be removed. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_app_attr_remove(ble_ancs_c_t * p_ancs, + const ble_ancs_c_app_attr_id_val_t id); + + +/**@brief Function for registering attributes that will be requested when @ref nrf_ble_ancs_c_app_attr_request + * is called. + * + * @param[in] p_ancs ANCS client instance on which the attribute will be registered. + * @param[in] id ID of the attribute that will be added. + * @param[in] p_data Pointer to a buffer where the data of the attribute can be stored. + * @param[in] len Length of the buffer where the data of the attribute can be stored. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_app_attr_add(ble_ancs_c_t * p_ancs, + const ble_ancs_c_app_attr_id_val_t id, + uint8_t * p_data, + const uint16_t len); + +/**@brief Function for clearing the list of notification attributes and app attributes that + * would be requested from NP. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. +**/ +ret_code_t nrf_ble_ancs_c_attr_req_clear_all(ble_ancs_c_t * p_ancs); + +/**@brief Function for requesting attributes for a notification. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] p_notif Pointer to the notification whose attributes will be requested from + * the Notification Provider. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_request_attrs(ble_ancs_c_t * p_ancs, + const ble_ancs_c_evt_notif_t * p_notif); + +/**@brief Function for requesting attributes for a given app. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] p_app_id App identifier of the app for which the app attributes are requested. + * @param[in] len Length of the app identifier. + * + * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_ancs_c_app_attr_request(ble_ancs_c_t * p_ancs, + const uint8_t * p_app_id, + uint32_t len); + + +/**@brief Function for performing a notification action. + * + * @param[in] p_ancs iOS notification structure. This structure must be supplied by + * the application. It identifies the particular client instance to use. + * @param[in] uuid The UUID of the notification for which to perform the action. + * @param[in] action_id Perform a positive or negative action. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If @p p_ancs was a NULL pointer. + */ +ret_code_t nrf_ancs_perform_notif_action(ble_ancs_c_t * p_ancs, + uint32_t uuid, + ble_ancs_c_action_id_values_t action_id); + +/**@brief Function for assigning a handle to this instance of ancs_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ancs Pointer to the ANCS client structure instance to associate with these + * handles. + * @param[in] conn_handle Connection handle to associate with the given ANCS instance. + * @param[in] p_service Attribute handles on the ANCS server that you want this ANCS client to + * interact with. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If @p p_ancs was a NULL pointer. + */ +ret_code_t nrf_ble_ancs_c_handles_assign(ble_ancs_c_t * p_ancs, + const uint16_t conn_handle, + const ble_ancs_c_service_t * p_service); + +#endif // BLE_ANCS_C_H__ + +/** @} */ + diff --git a/components/ble/ble_services/ble_ans_c/ble_ans_c.c b/components/ble/ble_services/ble_ans_c/ble_ans_c.c index fca4b2c..a73a0b7 100644 --- a/components/ble/ble_services/ble_ans_c/ble_ans_c.c +++ b/components/ble/ble_services/ble_ans_c/ble_ans_c.c @@ -1,117 +1,98 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /* Attention! * To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_ANS_C) #include "ble_ans_c.h" #include #include #include "ble_err.h" #include "ble_srv_common.h" -#include "nordic_common.h" #include "nrf_assert.h" -#include "device_manager.h" -#include "pstorage.h" - -#define START_HANDLE_DISCOVER 0x0001 /**< Value of start handle during discovery. */ - -#define NOTIFICATION_DATA_LENGTH 2 /**< The mandatory length of notification data. After the mandatory data, the optional message is located. */ -#define READ_DATA_LENGTH_MIN 1 /**< Minimum data length in a valid Alert Notification Read Response message. */ +#include "ble_db_discovery.h" +#define NRF_LOG_MODULE_NAME "BLE_ANS_C" +#include "nrf_log.h" -#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of contiguous zeroes, followed by contiguous sequence of ones: 000...111. */ -#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */ -#define WRITE_MESSAGE_LENGTH 2 /**< Length of the write message for CCCD/control point. */ +#define NOTIFICATION_DATA_LENGTH 2 /**< The mandatory length of notification data. After the mandatory data, the optional message is located. */ +#define READ_DATA_LENGTH_MIN 1 /**< Minimum data length in a valid Alert Notification Read Response message. */ -#define BLE_ANS_MAX_DISCOVERED_CENTRALS DEVICE_MANAGER_MAX_BONDS /**< Maximum number of discovered services that can be stored in the flash. This number should be identical to maximum number of bonded centrals. */ +#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of contiguous zeroes, followed by contiguous sequence of ones: 000...111. */ +#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */ +#define WRITE_MESSAGE_LENGTH 2 /**< Length of the write message for CCCD/control point. */ -#define DISCOVERED_SERVICE_DB_SIZE \ - CEIL_DIV(sizeof(alert_service_t) * BLE_ANS_MAX_DISCOVERED_CENTRALS, sizeof(uint32_t)) /**< Size of bonded centrals database in word size (4 byte). */ typedef enum { - READ_REQ = 1, /**< Type identifying that this tx_message is a read request. */ - WRITE_REQ /**< Type identifying that this tx_message is a write request. */ + READ_REQ = 1, /**< Type identifying that this tx_message is a read request. */ + WRITE_REQ /**< Type identifying that this tx_message is a write request. */ } ans_tx_request_t; -typedef enum -{ - STATE_UNINITIALIZED, /**< Uninitialized state of the internal state machine. */ - STATE_IDLE, /**< Idle state, this is the state when no central has connected to this device. */ - STATE_DISC_SERV, /**< A BLE central is connected and a service discovery is in progress. */ - STATE_DISC_CHAR, /**< A BLE central is connected and characteristic discovery is in progress. */ - STATE_DISC_DESC, /**< A BLE central is connected and descriptor discovery is in progress. */ - STATE_RUNNING, /**< A BLE central is connected and complete service discovery has been performed. */ - STATE_WAITING_ENC, /**< A previously bonded BLE central has re-connected and the service awaits the setup of an encrypted link. */ - STATE_RUNNING_NOT_DISCOVERED, /**< A BLE central is connected and a service discovery is in progress. */ -} ans_state_t; - -/**@brief Structure used for holding the characteristic found during discovery process. - */ -typedef struct -{ - ble_uuid_t uuid; /**< UUID identifying this characteristic. */ - ble_gatt_char_props_t properties; /**< Properties for this characteristic. */ - uint16_t handle_decl; /**< Characteristic Declaration Handle for this characteristic. */ - uint16_t handle_value; /**< Value Handle for the value provided in this characteristic. */ - uint16_t handle_cccd; /**< CCCD Handle value for this characteristic. BLE_ANS_INVALID_HANDLE if not present in the central. */ -} alert_characteristic_t; - -/**@brief Structure used for holding the Alert Notification Service found during discovery process. - */ -typedef struct -{ - uint8_t handle; /**< Handle of Alert Notification Service which identifies to which central this discovered service belongs. */ - ble_gattc_service_t service; /**< The GATT service holding the discovered Alert Notification Service. */ - alert_characteristic_t alert_notif_ctrl_point; /**< Characteristic for the Alert Notification Control Point. */ - alert_characteristic_t suported_new_alert_cat; /**< Characteristic for the Supported New Alert category. */ - alert_characteristic_t suported_unread_alert_cat; /**< Characteristic for the Unread Alert category. */ - alert_characteristic_t new_alert; /**< Characteristic for the New Alert Notification. */ - alert_characteristic_t unread_alert_status; /**< Characteristic for the Unread Alert Notification. */ -} alert_service_t; /**@brief Structure for writing a message to the central, i.e. Control Point or CCCD. */ typedef struct { - uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */ - ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */ -} write_params_t; + uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */ + ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */ +} ans_write_params_t; /**@brief Structure for holding data to be transmitted to the connected central. */ typedef struct { - uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */ - ans_tx_request_t type; /**< Type of this message, i.e. read or write message. */ + uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */ + ans_tx_request_t type; /**< Type of this message, i.e. read or write message. */ union { - uint16_t read_handle; /**< Read request message. */ - write_params_t write_req; /**< Write request message. */ + uint16_t read_handle; /**< Read request message. */ + ans_write_params_t write_req; /**< Write request message. */ } req; -} tx_message_t; - -static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */ -static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where next message should be inserted. */ -static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ -static pstorage_handle_t m_flash_handle; /**< Flash handle where discovered services for bonded masters should be stored. */ +} ans_tx_message_t; -static ans_state_t m_client_state = STATE_UNINITIALIZED; /**< Current state of the Alert Notification State Machine. */ - -static uint32_t m_service_db[DISCOVERED_SERVICE_DB_SIZE]; /**< Service database for bonded centrals (Word size aligned). */ -static alert_service_t * mp_service_db; /**< Pointer to start of discovered services database. */ -static alert_service_t m_service; /**< Current service data. */ -static ble_ans_c_t * m_ans_c_obj; /**< Pointer to the instantiated object. */ +static ans_tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */ +static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where next message should be inserted. */ +static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ /**@brief Function for passing any pending request from the buffer to the stack. @@ -142,320 +123,87 @@ static void tx_buffer_process(void) } -/**@brief Function for updating the current state and sending an event on discovery failure. +/** @brief Function for copying a characteristic. */ -static void handle_discovery_failure(const ble_ans_c_t * p_ans, uint32_t code) +static void char_set(ble_gattc_char_t * p_dest_char, const ble_gattc_char_t * p_source_char) { - ble_ans_c_evt_t event; - - m_client_state = STATE_RUNNING_NOT_DISCOVERED; - event.evt_type = BLE_ANS_C_EVT_DISCOVER_FAILED; - event.data.error_code = code; - - p_ans->evt_handler(&event); + memcpy(p_dest_char, p_source_char, sizeof(ble_gattc_char_t)); } - -/**@brief Function for executing the Service Discovery Procedure. - */ -static void service_disc_req_send(const ble_ans_c_t * p_ans) +static void char_cccd_set(ble_gattc_desc_t * p_cccd, const uint16_t cccd_handle) { - uint16_t handle = START_HANDLE_DISCOVER; - ble_uuid_t ans_uuid; - uint32_t err_code; - - // Discover services on uuid Alert Notification. - BLE_UUID_BLE_ASSIGN(ans_uuid, BLE_UUID_ALERT_NOTIFICATION_SERVICE); - - err_code = sd_ble_gattc_primary_services_discover(p_ans->conn_handle, handle, &ans_uuid); - if (err_code != NRF_SUCCESS) - { - handle_discovery_failure(p_ans, err_code); - } - else - { - m_client_state = STATE_DISC_SERV; - } + p_cccd->handle = cccd_handle; } - -/**@brief Function for executing the Characteristic Discovery Procedure. +/** @brief Function to check that all handles required by the client to use the server are present. */ -static void characteristic_disc_req_send(const ble_ans_c_t * p_ans, - const ble_gattc_handle_range_t * p_handle) +static bool is_valid_ans_srv_discovered(const ble_ans_c_service_t * p_srv) { - uint32_t err_code; - - // With valid service, we should discover characteristics. - err_code = sd_ble_gattc_characteristics_discover(p_ans->conn_handle, p_handle); - - if (err_code == NRF_SUCCESS) - { - m_client_state = STATE_DISC_CHAR; - } - else + if ((p_srv->alert_notif_ctrl_point.handle_value == BLE_GATT_HANDLE_INVALID) || + (p_srv->suported_new_alert_cat.handle_value == BLE_GATT_HANDLE_INVALID) || + (p_srv->suported_unread_alert_cat.handle_value == BLE_GATT_HANDLE_INVALID) || + (p_srv->new_alert.handle_value == BLE_GATT_HANDLE_INVALID) || + (p_srv->unread_alert_status.handle_value == BLE_GATT_HANDLE_INVALID) || + (p_srv->new_alert_cccd.handle == BLE_GATT_HANDLE_INVALID) || + (p_srv->unread_alert_cccd.handle == BLE_GATT_HANDLE_INVALID) + ) { - handle_discovery_failure(p_ans, err_code); + // At least one required characteristic is missing on the server side. + return false; } + return true; } -/**@brief Function for executing the Characteristic Descriptor Discovery Procedure. - */ -static void descriptor_disc_req_send(const ble_ans_c_t * p_ans) +void ble_ans_c_on_db_disc_evt(ble_ans_c_t * p_ans, const ble_db_discovery_evt_t * p_evt) { - ble_gattc_handle_range_t descriptor_handle; - uint32_t err_code = NRF_SUCCESS; + ble_ans_c_evt_t evt; - // If we have not discovered descriptors for all characteristics, - // we will discover next descriptor. - if (m_service.new_alert.handle_cccd == BLE_ANS_INVALID_HANDLE) - { - descriptor_handle.start_handle = m_service.new_alert.handle_value + 1; - descriptor_handle.end_handle = m_service.new_alert.handle_value + 1; + memset(&evt, 0, sizeof(ble_ans_c_evt_t)); + evt.conn_handle = p_evt->conn_handle; + evt.evt_type = BLE_ANS_C_EVT_DISCOVERY_FAILED; - err_code = sd_ble_gattc_descriptors_discover(p_ans->conn_handle, &descriptor_handle); - } - else if (m_service.unread_alert_status.handle_cccd == BLE_ANS_INVALID_HANDLE) + // Check if the Alert Notification Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE + && + p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_ALERT_NOTIFICATION_SERVICE + && + p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) { - descriptor_handle.start_handle = m_service.unread_alert_status.handle_value + 1; - descriptor_handle.end_handle = m_service.unread_alert_status.handle_value + 1; - - err_code = sd_ble_gattc_descriptors_discover(p_ans->conn_handle, &descriptor_handle); - } - - if (err_code == NRF_SUCCESS) - { - m_client_state = STATE_DISC_DESC; - } - else - { - handle_discovery_failure(p_ans, err_code); - } -} - - -/**@brief Function for indicating that a connection has successfully been established. - * Either when the Service Discovery Procedure completes or a re-connection has been - * established to a bonded central. - * - * @details This function is executed when a service discovery or a re-connect to a bonded central - * occurs. In the event of re-connection to a bonded central, this function will ensure - * writing of the control point according to the Alert Notification Service Client - * specification. - * Finally an event is passed to the application: - * BLE_ANS_C_EVT_RECONNECT - When we are connected to an existing central and the - * alert notification control point has been written. - * BLE_ANS_C_EVT_DISCOVER_COMPLETE - When we are connected to a new central and the Service - * Discovery has been completed. - */ -static void connection_established(const ble_ans_c_t * p_ans) -{ - ble_ans_c_evt_t event; - - m_client_state = STATE_RUNNING; - - if (m_service.handle == INVALID_SERVICE_HANDLE) - { - m_service.handle = INVALID_SERVICE_HANDLE_DISC; - } - - if (p_ans->central_handle != DM_INVALID_ID && - m_service.handle < INVALID_SERVICE_HANDLE_BASE) - { - uint32_t err_code = ble_ans_c_new_alert_notify(p_ans, ANS_TYPE_ALL_ALERTS); - if (err_code != NRF_SUCCESS && p_ans->error_handler != NULL) + // Find the characteristics inside the service. + for (uint8_t i = 0; i < p_evt->params.discovered_db.char_count; i++) { - p_ans->error_handler(err_code); - } - - err_code = ble_ans_c_unread_alert_notify(p_ans, ANS_TYPE_ALL_ALERTS); - if (err_code != NRF_SUCCESS && p_ans->error_handler != NULL) - { - p_ans->error_handler(err_code); - } - - event.evt_type = BLE_ANS_C_EVT_RECONNECT; - p_ans->evt_handler(&event); - } - else - { - event.evt_type = BLE_ANS_C_EVT_DISCOVER_COMPLETE; - p_ans->evt_handler(&event); - } -} - - -/**@brief Function for waiting until an encrypted link has been established to a bonded central. - */ -static void encrypted_link_setup_wait(const ble_ans_c_t * p_ans) -{ - m_client_state = STATE_WAITING_ENC; -} - + const ble_gatt_db_char_t * p_char = &(p_evt->params.discovered_db.charateristics[i]); -/**@brief Function for handling the connect event when a central connects. - * - * @details This function will check if bonded central connects, and do the following - * Bonded central - enter wait for encryption state. - * Unknown central - Initiate service discovery procedure. - */ -static void event_connect(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) -{ - p_ans->conn_handle = p_ble_evt->evt.gatts_evt.conn_handle; - - if (p_ans->central_handle != DM_INVALID_ID) - { - m_service = mp_service_db[p_ans->central_handle]; - encrypted_link_setup_wait(p_ans); - } - else - { - m_service.handle = INVALID_SERVICE_HANDLE; - service_disc_req_send(p_ans); - } -} - - -/**@brief Function for handling the encrypted link event when a secure - * connection has been established with a central. - * - * @details This function will check if the service for the central is known. - * Service known - Execute action running / switch to running state. - * Service unknown - Initiate Service Discovery Procedure. - */ -static void event_encrypted_link(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) -{ - // If we are setting up a bonded connection and the UUID of the service - // is unknown, a new discovery must be performed. - if (m_service.service.uuid.uuid != BLE_UUID_ALERT_NOTIFICATION_SERVICE) - { - m_service.handle = INVALID_SERVICE_HANDLE; - service_disc_req_send(p_ans); - } - else - { - connection_established(p_ans); - } -} - - -/**@brief Function for handling the response on service discovery. - * - * @details This function will validate the response. - * Invalid response - Handle discovery failure. - * Valid response - Initiate Characteristic Discovery Procedure. - */ -static void event_discover_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) -{ - if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) - { - // We have received an unexpected result. - // As we are in a connected state, but can not continue - // our service discovery, we will go to running state. - handle_discovery_failure(p_ans, p_ble_evt->evt.gattc_evt.gatt_status); - } - else - { - BLE_UUID_COPY_INST(m_service.service.uuid, - p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[0].uuid); - - if (p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count > 0) - { - const ble_gattc_service_t * p_service; - - p_service = &(p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[0]); - - m_service.service.handle_range.start_handle = p_service->handle_range.start_handle; - m_service.service.handle_range.end_handle = p_service->handle_range.end_handle; - - characteristic_disc_req_send(p_ans, &(m_service.service.handle_range)); - } - else - { - // If we receive an answer, but it contains no service, we just go to state: Running. - handle_discovery_failure(p_ans, p_ble_evt->evt.gattc_evt.gatt_status); - } - } -} - - -/**@brief Function for setting the discovered characteristics in the alert service. - */ -static void characteristics_set(alert_characteristic_t * p_characteristic, - const ble_gattc_char_t * p_char_resp) -{ - BLE_UUID_COPY_INST(p_characteristic->uuid, p_char_resp->uuid); - - p_characteristic->properties = p_char_resp->char_props; - p_characteristic->handle_decl = p_char_resp->handle_decl; - p_characteristic->handle_value = p_char_resp->handle_value; - p_characteristic->handle_cccd = BLE_ANS_INVALID_HANDLE; -} - - -/**@brief Function for handling a characteristic discovery response event. - * - * @details This function will validate and store the characteristics received. - * If not all characteristics are discovered it will continue the characteristic discovery - * procedure, otherwise it will continue with the descriptor discovery procedure. - * If we receive a GATT Client error, we will go to handling of discovery failure. - */ -static void event_characteristic_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) -{ - if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND || - p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INVALID_HANDLE) - { - if ((m_service.alert_notif_ctrl_point.handle_value == 0) || - (m_service.suported_new_alert_cat.handle_value == 0) || - (m_service.suported_unread_alert_cat.handle_value == 0) || - (m_service.new_alert.handle_value == 0) || - (m_service.unread_alert_status.handle_value == 0)) - { - // At least one required characteristic is missing on the server side. - handle_discovery_failure(p_ans, NRF_ERROR_NOT_FOUND); - } - else - { - descriptor_disc_req_send(p_ans); - } - } - else if (p_ble_evt->evt.gattc_evt.gatt_status) - { - // We have received an unexpected result. - // As we are in a connected state, but can not continue - // our service discovery, we must go to running state. - handle_discovery_failure(p_ans, p_ble_evt->evt.gattc_evt.gatt_status); - } - else - { - uint32_t i; - const ble_gattc_char_t * p_char_resp = NULL; - - // Iterate trough the characteristics and find the correct one. - for (i = 0; i < p_ble_evt->evt.gattc_evt.params.char_disc_rsp.count; i++) - { - p_char_resp = &(p_ble_evt->evt.gattc_evt.params.char_disc_rsp.chars[i]); - switch (p_char_resp->uuid.uuid) + switch (p_char->characteristic.uuid.uuid) { case BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR: - characteristics_set(&m_service.alert_notif_ctrl_point, p_char_resp); + NRF_LOG_INFO("Found Ctrlpt \r\n\r"); + char_set(&evt.data.service.alert_notif_ctrl_point, &p_char->characteristic); break; case BLE_UUID_UNREAD_ALERT_CHAR: - characteristics_set(&m_service.unread_alert_status, p_char_resp); + NRF_LOG_INFO("Found Unread Alert \r\n\r"); + char_set(&evt.data.service.unread_alert_status, &p_char->characteristic); + char_cccd_set(&evt.data.service.unread_alert_cccd, + p_char->cccd_handle); break; case BLE_UUID_NEW_ALERT_CHAR: - characteristics_set(&m_service.new_alert, p_char_resp); + NRF_LOG_INFO("Found New Alert \r\n\r"); + char_set(&evt.data.service.new_alert, &p_char->characteristic); + char_cccd_set(&evt.data.service.new_alert_cccd, + p_char->cccd_handle); break; case BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR: - characteristics_set(&m_service.suported_unread_alert_cat, p_char_resp); + NRF_LOG_INFO("Found supported unread alert category \r\n\r"); + char_set(&evt.data.service.suported_unread_alert_cat, &p_char->characteristic); break; case BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR: - characteristics_set(&m_service.suported_new_alert_cat, p_char_resp); + NRF_LOG_INFO("Found supported new alert category \r\n\r"); + char_set(&evt.data.service.suported_new_alert_cat, &p_char->characteristic); break; default: @@ -463,80 +211,12 @@ static void event_characteristic_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_bl break; } } - - if (p_char_resp != NULL) - { - // If not all characteristics are received, we do a 2nd/3rd/... round. - ble_gattc_handle_range_t char_handle; - - char_handle.start_handle = p_char_resp->handle_value + 1; - char_handle.end_handle = m_service.service.handle_range.end_handle; - - characteristic_disc_req_send(p_ans, &char_handle); - } - else - { - characteristic_disc_req_send(p_ans, &(m_service.service.handle_range)); - } - } -} - - -/**@brief Function for setting the discovered descriptor in the alert service. - */ -static void descriptor_set(alert_service_t * p_service, const ble_gattc_desc_t * p_desc_resp) -{ - if (p_service->new_alert.handle_value == (p_desc_resp->handle - 1) && - p_desc_resp->uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG) - { - p_service->new_alert.handle_cccd = p_desc_resp->handle; - } - else if (p_service->unread_alert_status.handle_value == (p_desc_resp->handle - 1) && - p_desc_resp->uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG) - { - p_service->unread_alert_status.handle_cccd = p_desc_resp->handle; - } -} - - -/**@brief Function for handling of descriptor discovery responses. - * - * @details This function will validate and store the descriptor received. - * If not all descriptors are discovered it will continue the descriptor discovery - * procedure, otherwise it will continue to running state. - * If we receive a GATT Client error, we will go to handling of discovery failure. - */ -static void event_descriptor_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) -{ - if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND || - p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INVALID_HANDLE) - { - handle_discovery_failure(p_ans, NRF_ERROR_NOT_FOUND); - } - else if (p_ble_evt->evt.gattc_evt.gatt_status) - { - // We have received an unexpected result. - // As we are in a connected state, but can not continue - // our descriptor discovery, we will go to running state. - handle_discovery_failure(p_ans, p_ble_evt->evt.gattc_evt.gatt_status); - } - else - { - if (p_ble_evt->evt.gattc_evt.params.desc_disc_rsp.count > 0) + if (is_valid_ans_srv_discovered(&evt.data.service)) { - descriptor_set(&m_service, &(p_ble_evt->evt.gattc_evt.params.desc_disc_rsp.descs[0])); - } - - if (m_service.new_alert.handle_cccd == BLE_ANS_INVALID_HANDLE || - m_service.unread_alert_status.handle_cccd == BLE_ANS_INVALID_HANDLE) - { - descriptor_disc_req_send(p_ans); - } - else - { - connection_established(p_ans); + evt.evt_type = BLE_ANS_C_EVT_DISCOVERY_COMPLETE; } } + p_ans->evt_handler(&evt); } @@ -546,7 +226,7 @@ static void event_notify(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) { uint32_t message_length; ble_ans_c_evt_t event; - ble_ans_alert_notification_t * p_alert = &event.data.alert; + ble_ans_alert_notification_t * p_alert = &event.data.alert; const ble_gattc_evt_hvx_t * p_notification = &p_ble_evt->evt.gattc_evt.params.hvx; // Message is not valid -> ignore. @@ -557,13 +237,13 @@ static void event_notify(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) } message_length = p_notification->len - NOTIFICATION_DATA_LENGTH; - if (p_notification->handle == m_service.new_alert.handle_value) + if (p_notification->handle == p_ans->service.new_alert.handle_value) { - BLE_UUID_COPY_INST(event.uuid, m_service.new_alert.uuid); + BLE_UUID_COPY_INST(event.uuid, p_ans->service.new_alert.uuid); } - else if (p_notification->handle == m_service.unread_alert_status.handle_value) + else if (p_notification->handle == p_ans->service.unread_alert_status.handle_value) { - BLE_UUID_COPY_INST(event.uuid, m_service.unread_alert_status.uuid); + BLE_UUID_COPY_INST(event.uuid, p_ans->service.unread_alert_status.uuid); } else { @@ -576,11 +256,11 @@ static void event_notify(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) p_alert->alert_msg_length = (message_length > p_ans->message_buffer_size) ? p_ans->message_buffer_size : message_length; - p_alert->p_alert_msg_buf = p_ans->p_message_buffer; + p_alert->p_alert_msg_buf = p_ans->p_message_buffer; memcpy(p_alert->p_alert_msg_buf, &p_notification->data[NOTIFICATION_DATA_LENGTH], - p_alert->alert_msg_length); //lint !e416 + p_alert->alert_msg_length); //lint !e416 p_ans->evt_handler(&event); } @@ -595,7 +275,7 @@ static void event_write_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) /**@brief Function for validating and passing the response to the application, - * when a read response is received. + * when a read response is received. */ static void event_read_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) { @@ -611,13 +291,13 @@ static void event_read_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) return; } - if (p_response->handle == m_service.suported_new_alert_cat.handle_value) + if (p_response->handle == p_ans->service.suported_new_alert_cat.handle_value) { - BLE_UUID_COPY_INST(event.uuid, m_service.suported_new_alert_cat.uuid); + BLE_UUID_COPY_INST(event.uuid, p_ans->service.suported_new_alert_cat.uuid); } - else if (p_response->handle == m_service.suported_unread_alert_cat.handle_value) + else if (p_response->handle == p_ans->service.suported_unread_alert_cat.handle_value) { - BLE_UUID_COPY_INST(event.uuid, m_service.suported_unread_alert_cat.uuid); + BLE_UUID_COPY_INST(event.uuid, p_ans->service.suported_unread_alert_cat.uuid); } else { @@ -643,57 +323,21 @@ static void event_read_rsp(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) /**@brief Function for disconnecting and cleaning the current service. */ -static void event_disconnect(ble_ans_c_t * p_ans) +static void event_disconnect(ble_ans_c_t * p_ans, ble_evt_t const * p_ble_evt) { - ble_ans_c_evt_t event; - ans_state_t prev_state = m_client_state; - - m_client_state = STATE_IDLE; - - if (m_service.handle == INVALID_SERVICE_HANDLE_DISC && - p_ans->central_handle != DM_INVALID_ID) - { - m_service.handle = p_ans->central_handle; - } - - if (m_service.handle < BLE_ANS_MAX_DISCOVERED_CENTRALS) + if (p_ans->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) { - mp_service_db[m_service.handle] = m_service; - } + p_ans->conn_handle = BLE_CONN_HANDLE_INVALID; - memset(&m_service, 0, sizeof(alert_service_t)); + // Clearing all data for the service will also set all handle values to @ref BLE_GATT_HANDLE_INVALID + memset(&p_ans->service, 0, sizeof(ble_ans_c_service_t)); - m_service.handle = INVALID_SERVICE_HANDLE; - p_ans->service_handle = INVALID_SERVICE_HANDLE; - p_ans->conn_handle = BLE_CONN_HANDLE_INVALID; - p_ans->central_handle = DM_INVALID_ID; + // There was a valid instance of IAS on the peer. Send an event to the + // application, so that it can do any clean up related to this module. + ble_ans_c_evt_t evt; - // Only if our previous state was RUNNING, i.e. the client had fully initialized, then the - // application should be notified of the DISCONNECT_COMPLETE. - if (prev_state == STATE_RUNNING) - { - event.evt_type = BLE_ANS_C_EVT_DISCONN_COMPLETE; - p_ans->evt_handler(&event); - } -} - - -/**@brief Function for handling of Device Manager events. - */ -void ble_ans_c_on_device_manager_evt(ble_ans_c_t * p_ans, - dm_handle_t const * p_handle, - dm_event_t const * p_dm_evt) -{ - switch (p_dm_evt->event_id) - { - case DM_EVT_CONNECTION: - // Fall through. - case DM_EVT_SECURITY_SETUP_COMPLETE: - p_ans->central_handle = p_handle->device_id; - break; - default: - // Do nothing. - break; + evt.evt_type = BLE_ANS_C_EVT_DISCONN_COMPLETE; + p_ans->evt_handler(&evt); } } @@ -702,153 +346,58 @@ void ble_ans_c_on_device_manager_evt(ble_ans_c_t * p_ans, */ void ble_ans_c_on_ble_evt(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt) { - uint16_t event = p_ble_evt->header.evt_id; - - switch (m_client_state) + switch (p_ble_evt->header.evt_id) { - case STATE_UNINITIALIZED: - // Initialization is handle in special case, thus if we enter here, it means that an - // event is received even though we are not initialized --> ignore. - break; - - case STATE_IDLE: - if (event == BLE_GAP_EVT_CONNECTED) - { - event_connect(p_ans, p_ble_evt); - } - break; - - case STATE_WAITING_ENC: - if ((event == BLE_GAP_EVT_AUTH_STATUS) || (event == BLE_GAP_EVT_SEC_INFO_REQUEST)) - { - event_encrypted_link(p_ans, p_ble_evt); - } - else if (event == BLE_GAP_EVT_DISCONNECTED) - { - event_disconnect(p_ans); - } + case BLE_GATTC_EVT_HVX: + event_notify(p_ans, p_ble_evt); break; - case STATE_DISC_SERV: - if (event == BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP) - { - event_discover_rsp(p_ans, p_ble_evt); - } - else if (event == BLE_GAP_EVT_DISCONNECTED) - { - event_disconnect(p_ans); - } + case BLE_GATTC_EVT_WRITE_RSP: + event_write_rsp(p_ans, p_ble_evt); break; - case STATE_DISC_CHAR: - if (event == BLE_GATTC_EVT_CHAR_DISC_RSP) - { - event_characteristic_rsp(p_ans, p_ble_evt); - } - else if (event == BLE_GAP_EVT_DISCONNECTED) - { - event_disconnect(p_ans); - } + case BLE_GATTC_EVT_READ_RSP: + event_read_rsp(p_ans, p_ble_evt); break; - case STATE_DISC_DESC: - if (event == BLE_GATTC_EVT_DESC_DISC_RSP) - { - event_descriptor_rsp(p_ans, p_ble_evt); - } - else if (event == BLE_GAP_EVT_DISCONNECTED) - { - event_disconnect(p_ans); - } + case BLE_GAP_EVT_DISCONNECTED: + event_disconnect(p_ans, p_ble_evt); break; - - case STATE_RUNNING: - if (event == BLE_GATTC_EVT_HVX) - { - event_notify(p_ans, p_ble_evt); - } - else if (event == BLE_GATTC_EVT_READ_RSP) - { - event_read_rsp(p_ans, p_ble_evt); - } - else if (event == BLE_GATTC_EVT_WRITE_RSP) - { - event_write_rsp(p_ans, p_ble_evt); - } - else if (event == BLE_GAP_EVT_DISCONNECTED) - { - event_disconnect(p_ans); - } - else - { - // Do nothing, event not handled in this state. - } - break; - - case STATE_RUNNING_NOT_DISCOVERED: - if (event == BLE_GAP_EVT_DISCONNECTED) - { - event_disconnect(p_ans); - } - break; - - default: - event_disconnect(p_ans); - break; - } -} - - -static void ans_pstorage_callback(pstorage_handle_t * handle, - uint8_t op_code, - uint32_t reason, - uint8_t * p_data, - uint32_t param_len) -{ - if (reason != NRF_SUCCESS) - { - m_ans_c_obj->error_handler(reason); } } uint32_t ble_ans_c_init(ble_ans_c_t * p_ans, const ble_ans_c_init_t * p_ans_init) { - uint32_t err_code; - pstorage_module_param_t param; + VERIFY_PARAM_NOT_NULL(p_ans); + VERIFY_PARAM_NOT_NULL(p_ans_init); + VERIFY_PARAM_NOT_NULL(p_ans_init->evt_handler); - if (p_ans_init->evt_handler == NULL) - { - return NRF_ERROR_INVALID_PARAM; - } + // clear all handles + memset(p_ans, 0, sizeof(ble_ans_c_t)); + memset(m_tx_buffer, 0, TX_BUFFER_SIZE); + p_ans->conn_handle = BLE_CONN_HANDLE_INVALID; p_ans->evt_handler = p_ans_init->evt_handler; p_ans->error_handler = p_ans_init->error_handler; - p_ans->service_handle = INVALID_SERVICE_HANDLE; - p_ans->central_handle = DM_INVALID_ID; - p_ans->service_handle = 0; p_ans->message_buffer_size = p_ans_init->message_buffer_size; p_ans->p_message_buffer = p_ans_init->p_message_buffer; - p_ans->conn_handle = BLE_CONN_HANDLE_INVALID; - m_ans_c_obj = p_ans; + BLE_UUID_BLE_ASSIGN(p_ans->service.service.uuid, BLE_UUID_ALERT_NOTIFICATION_SERVICE); + BLE_UUID_BLE_ASSIGN(p_ans->service.new_alert.uuid, BLE_UUID_NEW_ALERT_CHAR); + BLE_UUID_BLE_ASSIGN(p_ans->service.alert_notif_ctrl_point.uuid, + BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR); + BLE_UUID_BLE_ASSIGN(p_ans->service.unread_alert_status.uuid, BLE_UUID_UNREAD_ALERT_CHAR); + BLE_UUID_BLE_ASSIGN(p_ans->service.suported_new_alert_cat.uuid, + BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR); + BLE_UUID_BLE_ASSIGN(p_ans->service.suported_unread_alert_cat.uuid, + BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR); - memset(&m_service, 0, sizeof(alert_service_t)); - memset(m_tx_buffer, 0, TX_BUFFER_SIZE); - - m_service.handle = INVALID_SERVICE_HANDLE; - m_client_state = STATE_IDLE; - - param.block_count = 1; - param.block_size = DISCOVERED_SERVICE_DB_SIZE * sizeof(uint32_t); // uint32_t array. - param.cb = ans_pstorage_callback; - - // Register with storage module. - err_code = pstorage_register(¶m, &m_flash_handle); + BLE_UUID_BLE_ASSIGN(p_ans->service.new_alert_cccd.uuid, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG); + BLE_UUID_BLE_ASSIGN(p_ans->service.unread_alert_cccd.uuid, + BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG); - mp_service_db = (alert_service_t *) (m_service_db); - - return err_code; + return ble_db_discovery_evt_register(&p_ans->service.service.uuid); } @@ -856,14 +405,9 @@ uint32_t ble_ans_c_init(ble_ans_c_t * p_ans, const ble_ans_c_init_t * p_ans_init */ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable) { - tx_message_t * p_msg; + ans_tx_message_t * p_msg; uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0; - if (m_client_state != STATE_RUNNING) - { - return NRF_ERROR_INVALID_STATE; - } - p_msg = &m_tx_buffer[m_tx_insert_index++]; m_tx_insert_index &= TX_BUFFER_MASK; @@ -884,24 +428,35 @@ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool uint32_t ble_ans_c_enable_notif_new_alert(const ble_ans_c_t * p_ans) { - return cccd_configure(p_ans->conn_handle, - m_service.new_alert.handle_cccd, - true); + if (p_ans->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + else + { + return cccd_configure(p_ans->conn_handle, + p_ans->service.new_alert_cccd.handle, + true); + } } uint32_t ble_ans_c_disable_notif_new_alert(const ble_ans_c_t * p_ans) { return cccd_configure(p_ans->conn_handle, - m_service.new_alert.handle_cccd, + p_ans->service.new_alert_cccd.handle, false); } uint32_t ble_ans_c_enable_notif_unread_alert(const ble_ans_c_t * p_ans) { + if ( p_ans->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } return cccd_configure(p_ans->conn_handle, - m_service.unread_alert_status.handle_cccd, + p_ans->service.unread_alert_cccd.handle, true); } @@ -909,7 +464,7 @@ uint32_t ble_ans_c_enable_notif_unread_alert(const ble_ans_c_t * p_ans) uint32_t ble_ans_c_disable_notif_unread_alert(const ble_ans_c_t * p_ans) { return cccd_configure(p_ans->conn_handle, - m_service.unread_alert_status.handle_cccd, + p_ans->service.unread_alert_cccd.handle, false); } @@ -917,17 +472,12 @@ uint32_t ble_ans_c_disable_notif_unread_alert(const ble_ans_c_t * p_ans) uint32_t ble_ans_c_control_point_write(const ble_ans_c_t * p_ans, const ble_ans_control_point_t * p_control_point) { - tx_message_t * p_msg; - - if (m_client_state != STATE_RUNNING) - { - return NRF_ERROR_INVALID_STATE; - } + ans_tx_message_t * p_msg; p_msg = &m_tx_buffer[m_tx_insert_index++]; m_tx_insert_index &= TX_BUFFER_MASK; - p_msg->req.write_req.gattc_params.handle = m_service.alert_notif_ctrl_point.handle_value; + p_msg->req.write_req.gattc_params.handle = p_ans->service.alert_notif_ctrl_point.handle_value; p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH; p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; p_msg->req.write_req.gattc_params.offset = 0; @@ -944,12 +494,12 @@ uint32_t ble_ans_c_control_point_write(const ble_ans_c_t * p_ans, uint32_t ble_ans_c_new_alert_read(const ble_ans_c_t * p_ans) { - tx_message_t * msg; + ans_tx_message_t * msg; msg = &m_tx_buffer[m_tx_insert_index++]; m_tx_insert_index &= TX_BUFFER_MASK; - msg->req.read_handle = m_service.suported_new_alert_cat.handle_value; + msg->req.read_handle = p_ans->service.suported_new_alert_cat.handle_value; msg->conn_handle = p_ans->conn_handle; msg->type = READ_REQ; @@ -960,12 +510,12 @@ uint32_t ble_ans_c_new_alert_read(const ble_ans_c_t * p_ans) uint32_t ble_ans_c_unread_alert_read(const ble_ans_c_t * p_ans) { - tx_message_t * msg; + ans_tx_message_t * msg; msg = &m_tx_buffer[m_tx_insert_index++]; m_tx_insert_index &= TX_BUFFER_MASK; - msg->req.read_handle = m_service.suported_unread_alert_cat.handle_value; + msg->req.read_handle = p_ans->service.suported_unread_alert_cat.handle_value; msg->conn_handle = p_ans->conn_handle; msg->type = READ_REQ; @@ -996,54 +546,30 @@ uint32_t ble_ans_c_unread_alert_notify(const ble_ans_c_t * p_ans, ble_ans_catego } -uint32_t ble_ans_c_service_load(const ble_ans_c_t * p_ans) +uint32_t ble_ans_c_handles_assign(ble_ans_c_t * p_ans, + const uint16_t conn_handle, + const ble_ans_c_service_t * p_peer_handles) { - uint32_t err_code; - uint32_t i; - - err_code = pstorage_load((uint8_t *)m_service_db, - &m_flash_handle, - (DISCOVERED_SERVICE_DB_SIZE * sizeof(uint32_t)), - 0); + VERIFY_PARAM_NOT_NULL(p_ans); - if (err_code != NRF_SUCCESS) + if (!is_valid_ans_srv_discovered(p_peer_handles)) { - // Problem with loading values from flash, initialize the RAM DB with default. - for (i = 0; i < BLE_ANS_MAX_DISCOVERED_CENTRALS; ++i) - { - mp_service_db[i].handle = INVALID_SERVICE_HANDLE; - } - - if (err_code == NRF_ERROR_NOT_FOUND) - { - // The flash does not contain any memorized centrals, set the return code to success. - err_code = NRF_SUCCESS; - } + return NRF_ERROR_INVALID_PARAM; } - return err_code; -} + p_ans->conn_handle = conn_handle; - -uint32_t ble_ans_c_service_store(void) -{ - uint32_t err_code; - - err_code = pstorage_store(&m_flash_handle, - (uint8_t *) m_service_db, - DISCOVERED_SERVICE_DB_SIZE * sizeof(uint32_t), - 0); - - return err_code; -} - - -uint32_t ble_ans_c_service_delete(void) -{ - if (m_client_state == STATE_UNINITIALIZED) + if (p_peer_handles != NULL) { - return NRF_SUCCESS; + // Copy the handles from the discovered characteristics over to the provided client instance. + char_set(&p_ans->service.alert_notif_ctrl_point, &p_peer_handles->alert_notif_ctrl_point); + char_set(&p_ans->service.suported_new_alert_cat, &p_peer_handles->suported_new_alert_cat); + char_set(&p_ans->service.suported_unread_alert_cat, &p_peer_handles->suported_unread_alert_cat); + char_set(&p_ans->service.new_alert, &p_peer_handles->new_alert); + char_cccd_set(&p_ans->service.new_alert_cccd, p_peer_handles->new_alert_cccd.handle); + char_set(&p_ans->service.unread_alert_status, &p_peer_handles->unread_alert_status); + char_cccd_set(&p_ans->service.unread_alert_cccd, p_peer_handles->unread_alert_cccd.handle); } - return pstorage_clear(&m_flash_handle, (DISCOVERED_SERVICE_DB_SIZE * sizeof(uint32_t))); + return NRF_SUCCESS; } - +#endif // NRF_MODULE_ENABLED(BLE_ANS_C) diff --git a/components/ble/ble_services/ble_ans_c/ble_ans_c.h b/components/ble/ble_services/ble_ans_c/ble_ans_c.h index 8c52e65..fe34514 100644 --- a/components/ble/ble_services/ble_ans_c/ble_ans_c.h +++ b/components/ble/ble_services/ble_ans_c/ble_ans_c.h @@ -1,17 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_ans_c Alert Notification Service Client + * @defgroup ble_ans_c Alert Notification Service Client * @{ * @ingroup ble_sdk_srv * @brief Alert Notification module. @@ -22,8 +51,8 @@ * @note The application must propagate BLE stack events to the Alert Notification Client module * by calling ble_ans_c_on_ble_evt() from the @ref softdevice_handler callback. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ #ifndef BLE_ANS_C_H__ @@ -32,15 +61,14 @@ #include "ble.h" #include "ble_gatts.h" #include "ble_types.h" +#include "sdk_common.h" #include "ble_srv_common.h" -#include "device_manager.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif -#define ANS_NB_OF_CHARACTERISTICS 5 /**< Number of characteristics as defined by Alert Notification Service specification. */ -#define ANS_NB_OF_SERVICES 1 /**< Number of services supported in one central. */ -#define INVALID_SERVICE_HANDLE_BASE 0xF0 /**< Base for indicating invalid service handle. */ -#define INVALID_SERVICE_HANDLE (INVALID_SERVICE_HANDLE_BASE + 0x0F) /**< Indication that the current service handle is invalid. */ -#define INVALID_SERVICE_HANDLE_DISC (INVALID_SERVICE_HANDLE_BASE + 0x0E) /**< Indication that the current service handle is invalid but the service has been discovered. */ -#define BLE_ANS_INVALID_HANDLE 0xFF /**< Indication that the current service handle is invalid. */ // Forward declaration of the ble_ans_c_t type. typedef struct ble_ans_c_s ble_ans_c_t; @@ -48,17 +76,17 @@ typedef struct ble_ans_c_s ble_ans_c_t; /** Alerts types as defined in the alert category id; UUID: 0x2A43. */ typedef enum { - ANS_TYPE_SIMPLE_ALERT = 0, /**< General text alert or non-text alert.*/ - ANS_TYPE_EMAIL = 1, /**< Alert when email messages arrives.*/ - ANS_TYPE_NEWS = 2, /**< News feeds such as RSS, Atom.*/ - ANS_TYPE_NOTIFICATION_CALL = 3, /**< Incoming call.*/ - ANS_TYPE_MISSED_CALL = 4, /**< Missed call.*/ - ANS_TYPE_SMS_MMS = 5, /**< SMS/MMS message arrives.*/ - ANS_TYPE_VOICE_MAIL = 6, /**< Voice mail.*/ - ANS_TYPE_SCHEDULE = 7, /**< Alert occurred on calendar, planner.*/ - ANS_TYPE_HIGH_PRIORITIZED_ALERT = 8, /**< Alert that should be handled as high priority.*/ - ANS_TYPE_INSTANT_MESSAGE = 9, /**< Alert for incoming instant messages.*/ - ANS_TYPE_ALL_ALERTS = 0xFF /**< Identifies All Alerts. */ + ANS_TYPE_SIMPLE_ALERT = 0, /**< General text alert or non-text alert.*/ + ANS_TYPE_EMAIL = 1, /**< Alert when email messages arrives.*/ + ANS_TYPE_NEWS = 2, /**< News feeds such as RSS, Atom.*/ + ANS_TYPE_NOTIFICATION_CALL = 3, /**< Incoming call.*/ + ANS_TYPE_MISSED_CALL = 4, /**< Missed call.*/ + ANS_TYPE_SMS_MMS = 5, /**< SMS/MMS message arrives.*/ + ANS_TYPE_VOICE_MAIL = 6, /**< Voice mail.*/ + ANS_TYPE_SCHEDULE = 7, /**< Alert occurred on calendar, planner.*/ + ANS_TYPE_HIGH_PRIORITIZED_ALERT = 8, /**< Alert that should be handled as high priority.*/ + ANS_TYPE_INSTANT_MESSAGE = 9, /**< Alert for incoming instant messages.*/ + ANS_TYPE_ALL_ALERTS = 0xFF /**< Identifies All Alerts. */ } ble_ans_category_id_t; /** Alerts notification control point commands as defined in the Alert Notification Specification; @@ -66,31 +94,30 @@ typedef enum */ typedef enum { - ANS_ENABLE_NEW_INCOMING_ALERT_NOTIFICATION = 0, /**< Enable New Incoming Alert Notification.*/ - ANS_ENABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION = 1, /**< Enable Unread Category Status Notification.*/ - ANS_DISABLE_NEW_INCOMING_ALERT_NOTIFICATION = 2, /**< Disable New Incoming Alert Notification.*/ - ANS_DISABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION = 3, /**< Disable Unread Category Status Notification.*/ - ANS_NOTIFY_NEW_INCOMING_ALERT_IMMEDIATELY = 4, /**< Notify New Incoming Alert immediately.*/ - ANS_NOTIFY_UNREAD_CATEGORY_STATUS_IMMEDIATELY = 5, /**< Notify Unread Category Status immediately.*/ + ANS_ENABLE_NEW_INCOMING_ALERT_NOTIFICATION = 0, /**< Enable New Incoming Alert Notification.*/ + ANS_ENABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION = 1, /**< Enable Unread Category Status Notification.*/ + ANS_DISABLE_NEW_INCOMING_ALERT_NOTIFICATION = 2, /**< Disable New Incoming Alert Notification.*/ + ANS_DISABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION = 3, /**< Disable Unread Category Status Notification.*/ + ANS_NOTIFY_NEW_INCOMING_ALERT_IMMEDIATELY = 4, /**< Notify New Incoming Alert immediately.*/ + ANS_NOTIFY_UNREAD_CATEGORY_STATUS_IMMEDIATELY = 5, /**< Notify Unread Category Status immediately.*/ } ble_ans_command_id_t; /**@brief Alert Notification Event types that are passed from client to application on an event. */ typedef enum { - BLE_ANS_C_EVT_DISCOVER_COMPLETE, /**< A successful connection has been established and the characteristics of the server has been fetched. */ - BLE_ANS_C_EVT_DISCOVER_FAILED, /**< It was not possible to discover service or characteristics of the connected peer. */ - BLE_ANS_C_EVT_RECONNECT, /**< A re-connection to a known and previously discovered central has occurred. */ - BLE_ANS_C_EVT_DISCONN_COMPLETE, /**< The connection has been taken down. */ - BLE_ANS_C_EVT_NOTIFICATION, /**< A valid Alert Notification has been received from the server.*/ - BLE_ANS_C_EVT_READ_RESP, /**< A read response has been received from the server.*/ - BLE_ANS_C_EVT_WRITE_RESP /**< A write response has been received from the server.*/ + BLE_ANS_C_EVT_DISCOVERY_COMPLETE, /**< A successful connection has been established and the characteristics of the server has been fetched. */ + BLE_ANS_C_EVT_DISCOVERY_FAILED, /**< It was not possible to discover service or characteristics of the connected peer. */ + BLE_ANS_C_EVT_DISCONN_COMPLETE, /**< The connection has been taken down. */ + BLE_ANS_C_EVT_NOTIFICATION, /**< A valid Alert Notification has been received from the server.*/ + BLE_ANS_C_EVT_READ_RESP, /**< A read response has been received from the server.*/ + BLE_ANS_C_EVT_WRITE_RESP /**< A write response has been received from the server.*/ } ble_ans_c_evt_type_t; /**@brief Alert Notification Control Point structure. */ typedef struct { - ble_ans_command_id_t command; /**< The command to be written to the control point, see @ref ble_ans_command_id_t. */ - ble_ans_category_id_t category; /**< The category for the control point for which the command applies, see @ref ble_ans_category_id_t. */ + ble_ans_command_id_t command; /**< The command to be written to the control point, see @ref ble_ans_command_id_t. */ + ble_ans_category_id_t category; /**< The category for the control point for which the command applies, see @ref ble_ans_category_id_t. */ } ble_ans_control_point_t; /**@brief Alert Notification Setting structure containing the supported alerts in the service. @@ -102,29 +129,45 @@ typedef struct */ typedef struct { - uint8_t ans_simple_alert_support : 1; /**< Support for General text alert or non-text alert.*/ - uint8_t ans_email_support : 1; /**< Support for Alert when email messages arrives.*/ - uint8_t ans_news_support : 1; /**< Support for News feeds such as RSS, Atom.*/ - uint8_t ans_notification_call_support : 1; /**< Support for Incoming call.*/ - uint8_t ans_missed_call_support : 1; /**< Support for Missed call.*/ - uint8_t ans_sms_mms_support : 1; /**< Support for SMS/MMS message arrives.*/ - uint8_t ans_voice_mail_support : 1; /**< Support for Voice mail.*/ - uint8_t ans_schedule_support : 1; /**< Support for Alert occurred on calendar, planner.*/ - uint8_t ans_high_prioritized_alert_support : 1; /**< Support for Alert that should be handled as high priority.*/ - uint8_t ans_instant_message_support : 1; /**< Support for Alert for incoming instant messages.*/ - uint8_t reserved : 6; /**< Reserved for future use. */ + uint8_t ans_simple_alert_support : 1; /**< Support for General text alert or non-text alert.*/ + uint8_t ans_email_support : 1; /**< Support for Alert when email messages arrives.*/ + uint8_t ans_news_support : 1; /**< Support for News feeds such as RSS, Atom.*/ + uint8_t ans_notification_call_support : 1; /**< Support for Incoming call.*/ + uint8_t ans_missed_call_support : 1; /**< Support for Missed call.*/ + uint8_t ans_sms_mms_support : 1; /**< Support for SMS/MMS message arrives.*/ + uint8_t ans_voice_mail_support : 1; /**< Support for Voice mail.*/ + uint8_t ans_schedule_support : 1; /**< Support for Alert occurred on calendar, planner.*/ + uint8_t ans_high_prioritized_alert_support : 1; /**< Support for Alert that should be handled as high priority.*/ + uint8_t ans_instant_message_support : 1; /**< Support for Alert for incoming instant messages.*/ + uint8_t reserved : 6; /**< Reserved for future use. */ } ble_ans_alert_settings_t; /**@brief Alert Notification structure */ typedef struct { - uint8_t alert_category; /**< Alert category to which this alert belongs.*/ - uint8_t alert_category_count; /**< Number of alerts in the category. */ - uint32_t alert_msg_length; /**< Length of optional text message send by the server. */ - uint8_t * p_alert_msg_buf; /**< Pointer to buffer containing the optional text message. */ + uint8_t alert_category; /**< Alert category to which this alert belongs.*/ + uint8_t alert_category_count; /**< Number of alerts in the category. */ + uint32_t alert_msg_length; /**< Length of optional text message send by the server. */ + uint8_t * p_alert_msg_buf; /**< Pointer to buffer containing the optional text message. */ } ble_ans_alert_notification_t; + +/**@brief Struct to hold information on the Alert Notification Service if found on the server. +*/ +typedef struct +{ + ble_gattc_service_t service; /**< The GATT service holding the discovered Alert Notification Service. */ + ble_gattc_char_t alert_notif_ctrl_point; /**< Characteristic for the Alert Notification Control Point. @ref BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR */ + ble_gattc_char_t suported_new_alert_cat; /**< Characteristic for the Supported New Alert category. @ref BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR */ + ble_gattc_char_t suported_unread_alert_cat; /**< Characteristic for the Unread Alert category. @ref BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR */ + ble_gattc_char_t new_alert; /**< Characteristic for the New Alert Notification. @ref BLE_UUID_NEW_ALERT_CHAR */ + ble_gattc_desc_t new_alert_cccd; /**< Characteristic Descriptor for New Alert Category. Enables or Disables GATT notifications */ + ble_gattc_char_t unread_alert_status; /**< Characteristic for the Unread Alert Notification. @ref BLE_UUID_UNREAD_ALERT_CHAR */ + ble_gattc_desc_t unread_alert_cccd; /**< Characteristic Descriptor for Unread Alert Category. Enables or Disables GATT notifications */ +} ble_ans_c_service_t; + + /**@brief Alert Notification Event structure * * @details The structure contains the event that should be handled, as well as @@ -132,66 +175,70 @@ typedef struct */ typedef struct { - ble_ans_c_evt_type_t evt_type; /**< Type of event. */ - ble_uuid_t uuid; /**< UUID of the event in case of an alert or notification. */ + ble_ans_c_evt_type_t evt_type; /**< Type of event. */ + uint16_t conn_handle; /**< Connection handle on which the ANS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE.*/ + ble_uuid_t uuid; /**< UUID of the event in case of an alert or notification. */ union { - ble_ans_alert_settings_t settings; /**< Setting returned from server on read request. */ - ble_ans_alert_notification_t alert; /**< Alert Notification data sent by the server. */ - uint32_t error_code; /**< Additional status/error code if the event was caused by a stack error or gatt status, e.g. during service discovery. */ + ble_ans_alert_settings_t settings; /**< Setting returned from server on read request. */ + ble_ans_alert_notification_t alert; /**< Alert Notification data sent by the server. */ + uint32_t error_code; /**< Additional status/error code if the event was caused by a stack error or gatt status, e.g. during service discovery. */ + ble_ans_c_service_t service; /**< Info on the discovered Alert Notification Service discovered. This will be filled if the evt_type is @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE.*/ } data; } ble_ans_c_evt_t; /**@brief Alert Notification event handler type. */ typedef void (*ble_ans_c_evt_handler_t) (ble_ans_c_evt_t * p_evt); + /**@brief Alert Notification structure. This contains various status information for the client. */ struct ble_ans_c_s { - ble_ans_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Alert Notification Client Application. */ - ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ - uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ - uint8_t central_handle; /**< Handle for the currently connected central if peer is bonded. */ - uint8_t service_handle; /**< Handle to the service in the database to use for this instance. */ - uint32_t message_buffer_size; /**< Size of message buffer to hold the additional text messages received on notifications. */ - uint8_t * p_message_buffer; /**< Pointer to the buffer to be used for additional text message handling. */ + ble_ans_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Alert Notification Client Application. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + uint8_t central_handle; /**< Handle for the currently connected central if peer is bonded. */ + uint8_t service_handle; /**< Handle to the service in the database to use for this instance. */ + uint32_t message_buffer_size; /**< Size of message buffer to hold the additional text messages received on notifications. */ + uint8_t * p_message_buffer; /**< Pointer to the buffer to be used for additional text message handling. */ + ble_ans_c_service_t service; /**< Struct to store the different handles and UUIDs related to the service. */ }; /**@brief Alert Notification init structure. This contains all options and data needed for * initialization of the client.*/ typedef struct { - ble_ans_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */ - ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ - uint32_t message_buffer_size; /**< Size of buffer to handle messages. */ - uint8_t * p_message_buffer; /**< Pointer to buffer for passing messages. */ + ble_ans_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint32_t message_buffer_size; /**< Size of buffer to handle messages. */ + uint8_t * p_message_buffer; /**< Pointer to buffer for passing messages. */ } ble_ans_c_init_t; -/**@brief Function for handling the Application's BLE Stack events. +/**@brief Function for handling events from the database discovery module. * - * @details Handles all events from the BLE stack of interest to the Alert Notification Client. + * @details Call this function when getting a callback event from the DB discovery modue. + * This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of heart rate service at the peer. If so, it will + * call the application's event handler indicating that the heart rate service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. * - * @param[in] p_ans Alert Notification Client structure. - * @param[in] p_ble_evt Event received from the BLE stack. + * @param[in] p_ans Pointer to the Alert Notification client structure instance that will handle + * the discovery. + * @param[in] p_evt Pointer to the event received from the database discovery module. */ -void ble_ans_c_on_ble_evt(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt); +void ble_ans_c_on_db_disc_evt(ble_ans_c_t * p_ans, const ble_db_discovery_evt_t * p_evt); -/**@brief Function for handling the Alert Notification Client - Device Manager Event. +/**@brief Function for handling the Application's BLE Stack events. * - * @details Handles all events from the Bond Manager of interest to the Alert Notification Client. - * The Alert Notification Client will use the events of re-connection to existing central - * and creation of new bonds for handling of service discovery and writing of the Alert - * Notification Control Point for re-send of New Alert and Unread Alert notifications. + * @details Handles all events from the BLE stack of interest to the Alert Notification Client. * - * @param[in] p_ans Alert Notification Client structure. - * @param[in] p_handle Handle. - * @param[in] p_dm_evt Event received from the Bond Manager. + * @param[in] p_ans Alert Notification Client structure. + * @param[in] p_ble_evt Event received from the BLE stack. */ -void ble_ans_c_on_device_manager_evt(ble_ans_c_t * p_ans, - dm_handle_t const * p_handle, - dm_event_t const * p_dm_evt); +void ble_ans_c_on_ble_evt(ble_ans_c_t * p_ans, const ble_evt_t * p_ble_evt); /**@brief Function for initializing the Alert Notification Client. @@ -258,7 +305,7 @@ uint32_t ble_ans_c_disable_notif_unread_alert(const ble_ans_c_t * p_ans); * * @return NRF_SUCCESS on successful writing of the Control Point, otherwise an error code. */ -uint32_t ble_ans_c_control_point_write(const ble_ans_c_t * p_ans, +uint32_t ble_ans_c_control_point_write(const ble_ans_c_t * p_ans, const ble_ans_control_point_t * p_control_point); @@ -306,45 +353,32 @@ uint32_t ble_ans_c_new_alert_notify(const ble_ans_c_t * p_ans, ble_ans_category_ uint32_t ble_ans_c_unread_alert_notify(const ble_ans_c_t * p_ans, ble_ans_category_id_t category); -/**@brief Function for loading previous discovered service and characteristic handles for bonded centrals from - * flash into RAM. - * - * @details Read the database of all discovered service and characteristic handles from flash. - * If the flash does not contain any valid data, the array of discovered service handles in - * RAM will be empty. +/**@brief Function for assigning a handles to a an instance of ans_c. * - * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by the - * application. It identifies the particular client instance to use. + * @details Call this function when a link has been established with a peer to + * associate this link to an instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of the ans_c module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE. * - * @note Currently the Alert Notification Client uses only one page in flash. + * @param[in] p_ans Pointer to the Alert Notification client structure instance to + * associate with the handles. + * @param[in] conn_handle Connection handle to associated with the given Alert Notification Client + * Instance. + * @param[in] p_peer_handles Attribute handles on the ANS server that you want this ANS client to + * interact with. * - * @return NRF_SUCCESS if all operations went successfully, an error_code otherwise. */ -uint32_t ble_ans_c_service_load(const ble_ans_c_t * p_ans); +uint32_t ble_ans_c_handles_assign(ble_ans_c_t * p_ans, + const uint16_t conn_handle, + const ble_ans_c_service_t * p_peer_handles); -/**@brief Function for storing discovered service and characteristic handles for bonded centrals into flash memory. - * - * @details This function will erase the flash page (if the data to store - * are diferent than the one already stored) and then write into flash. Those - * operations could prevent the radio to run. - * - * @note Do not call this function while in a connection or when advertising. If you do, the - * behavior is undefined. - * - * @return NRF_SUCCESS if all operations went successfully, an error_code otherwise. - */ -uint32_t ble_ans_c_service_store(void); -/**@brief Function for deleting the Alert Notification Client database from flash. - * - * @details After calling this function you should call ble_ans_c_init(...) to re-initialize - * the RAM database. - * - * @return NRF_SUCCESS if all operations went successfully. - */ -uint32_t ble_ans_c_service_delete(void); +#ifdef __cplusplus +} +#endif #endif // BLE_ANS_C_H__ diff --git a/components/ble/ble_services/ble_bas/ble_bas.c b/components/ble/ble_services/ble_bas/ble_bas.c index 2922a3a..05611c1 100644 --- a/components/ble/ble_services/ble_bas/ble_bas.c +++ b/components/ble/ble_services/ble_bas/ble_bas.c @@ -1,25 +1,52 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_BAS) #include "ble_bas.h" #include -#include "nordic_common.h" #include "ble_srv_common.h" -#include "app_util.h" #define INVALID_BATTERY_LEVEL 255 @@ -92,7 +119,7 @@ void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt) { return; } - + switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: @@ -199,9 +226,9 @@ static uint32_t battery_level_char_add(ble_bas_t * p_bas, const ble_bas_init_t * attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0; - + init_len = ble_srv_report_ref_encode(encoded_report_ref, p_bas_init->p_report_ref); - + memset(&attr_char_value, 0, sizeof(attr_char_value)); attr_char_value.p_uuid = &ble_uuid; @@ -234,7 +261,7 @@ uint32_t ble_bas_init(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init) { return NRF_ERROR_NULL; } - + uint32_t err_code; ble_uuid_t ble_uuid; @@ -264,7 +291,7 @@ uint32_t ble_bas_battery_level_update(ble_bas_t * p_bas, uint8_t battery_level) { return NRF_ERROR_NULL; } - + uint32_t err_code = NRF_SUCCESS; ble_gatts_value_t gatts_value; @@ -314,3 +341,4 @@ uint32_t ble_bas_battery_level_update(ble_bas_t * p_bas, uint8_t battery_level) return err_code; } +#endif // NRF_MODULE_ENABLED(BLE_BAS) diff --git a/components/ble/ble_services/ble_bas/ble_bas.h b/components/ble/ble_services/ble_bas/ble_bas.h index 7673a7c..0b6fd4a 100644 --- a/components/ble/ble_services/ble_bas/ble_bas.h +++ b/components/ble/ble_services/ble_bas/ble_bas.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_bas Battery Service + * @defgroup ble_bas Battery Service * @{ * @ingroup ble_sdk_srv * @brief Battery Service module. @@ -31,8 +59,8 @@ * @note The application must propagate BLE stack events to the Battery Service module by calling * ble_bas_on_ble_evt() from the @ref softdevice_handler callback. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -44,6 +72,10 @@ #include "ble.h" #include "ble_srv_common.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Battery Service event type. */ typedef enum { @@ -57,7 +89,7 @@ typedef struct ble_bas_evt_type_t evt_type; /**< Type of event. */ } ble_bas_evt_t; -// Forward declaration of the ble_bas_t type. +// Forward declaration of the ble_bas_t type. typedef struct ble_bas_s ble_bas_t; /**@brief Battery Service event handler type. */ @@ -128,6 +160,11 @@ void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt); */ uint32_t ble_bas_battery_level_update(ble_bas_t * p_bas, uint8_t battery_level); + +#ifdef __cplusplus +} +#endif + #endif // BLE_BAS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_bas_c/ble_bas_c.c b/components/ble/ble_services/ble_bas_c/ble_bas_c.c index 04d16e0..3bcceb9 100644 --- a/components/ble/ble_services/ble_bas_c/ble_bas_c.c +++ b/components/ble/ble_services/ble_bas_c/ble_bas_c.c @@ -1,24 +1,52 @@ -/* - * Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_BAS_C) #include "ble_bas_c.h" -#include #include "ble_db_discovery.h" #include "ble_types.h" #include "ble_srv_common.h" -#include "nrf_error.h" #include "ble_gattc.h" -#include "app_util.h" -#include "nordic_common.h" -#include "app_trace.h" +#define NRF_LOG_MODULE_NAME "BLE_BAS_C" +#include "nrf_log.h" -#define LOG app_trace_log /**< Debug logger macro that will be used in this file to do logging of important information over UART. */ #define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of contiguous zeroes, followed by contiguous sequence of ones: 000...111. */ #define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of the send buffer, which is 1 higher than the mask. */ #define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */ @@ -51,7 +79,6 @@ typedef struct } tx_message_t; -static ble_bas_c_t * mp_ble_bas_c; /**< Pointer to the current instance of the BAS Client module. The memory for this is provided by the application.*/ static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for the messages that will be transmitted to the central. */ static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer containing the next message to be transmitted. */ @@ -77,13 +104,13 @@ static void tx_buffer_process(void) } if (err_code == NRF_SUCCESS) { - LOG("[BAS_C]: SD Read/Write API returns Success..\r\n"); + NRF_LOG_DEBUG("SD Read/Write API returns Success..\r\n"); m_tx_index++; m_tx_index &= TX_BUFFER_MASK; } else { - LOG("[BAS_C]: SD Read/Write API returns error. This message sending will be " + NRF_LOG_DEBUG("SD Read/Write API returns error. This message sending will be " "attempted again..\r\n"); } } @@ -97,6 +124,11 @@ static void tx_buffer_process(void) */ static void on_write_rsp(ble_bas_c_t * p_bas_c, const ble_evt_t * p_ble_evt) { + // Check if the event if on the link for this instance + if (p_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } // Check if there is any message to be sent across to the peer and send it. tx_buffer_process(); } @@ -114,12 +146,19 @@ static void on_read_rsp(ble_bas_c_t * p_bas_c, const ble_evt_t * p_ble_evt) { const ble_gattc_evt_read_rsp_t * p_response; + // Check if the event if on the link for this instance + if (p_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp; - if (p_response->handle == p_bas_c->bl_handle) + if (p_response->handle == p_bas_c->peer_bas_db.bl_handle) { ble_bas_c_evt_t evt; + evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle; evt.evt_type = BLE_BAS_C_EVT_BATT_READ_RESP; evt.params.battery_level = p_response->data[0]; @@ -143,32 +182,29 @@ static void on_read_rsp(ble_bas_c_t * p_bas_c, const ble_evt_t * p_ble_evt) */ static void on_hvx(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt) { + // Check if the event if on the link for this instance + if (p_ble_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } // Check if this notification is a battery level notification. - if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_bas_c->bl_handle) + if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_bas_c->peer_bas_db.bl_handle) { - ble_bas_c_evt_t ble_bas_c_evt; - - ble_bas_c_evt.evt_type = BLE_BAS_C_EVT_BATT_NOTIFICATION; + if (p_ble_evt->evt.gattc_evt.params.hvx.len == 1) + { + ble_bas_c_evt_t ble_bas_c_evt; + ble_bas_c_evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle; + ble_bas_c_evt.evt_type = BLE_BAS_C_EVT_BATT_NOTIFICATION; - ble_bas_c_evt.params.battery_level = p_ble_evt->evt.gattc_evt.params.hvx.data[0]; + ble_bas_c_evt.params.battery_level = p_ble_evt->evt.gattc_evt.params.hvx.data[0]; - p_ble_bas_c->evt_handler(p_ble_bas_c, &ble_bas_c_evt); + p_ble_bas_c->evt_handler(p_ble_bas_c, &ble_bas_c_evt); + } } } -/**@brief Function for handling events from the database discovery module. - * - * @details This function will handle an event from the database discovery module, and determine - * if it relates to the discovery of Battery service at the peer. If so, it will - * call the application's event handler indicating that the Battery service has been - * discovered at the peer. It also populate the event with the service related - * information before providing it to the application. - * - * @param[in] p_evt Pointer to the event received from the database discovery module. - * - */ -static void db_discovery_evt_handler(ble_db_discovery_evt_t * p_evt) +void ble_bas_on_db_disc_evt(ble_bas_c_t * p_ble_bas_c, const ble_db_discovery_evt_t * p_evt) { // Check if the Battery Service was discovered. if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE @@ -177,36 +213,42 @@ static void db_discovery_evt_handler(ble_db_discovery_evt_t * p_evt) && p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) { - mp_ble_bas_c->conn_handle = p_evt->conn_handle; - // Find the CCCD Handle of the Battery Level characteristic. uint8_t i; + ble_bas_c_evt_t evt; + evt.evt_type = BLE_BAS_C_EVT_DISCOVERY_COMPLETE; + evt.conn_handle = p_evt->conn_handle; for (i = 0; i < p_evt->params.discovered_db.char_count; i++) { if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid == BLE_UUID_BATTERY_LEVEL_CHAR) { // Found Battery Level characteristic. Store CCCD handle and break. - mp_ble_bas_c->bl_cccd_handle = + evt.params.bas_db.bl_cccd_handle = p_evt->params.discovered_db.charateristics[i].cccd_handle; - mp_ble_bas_c->bl_handle = + evt.params.bas_db.bl_handle = p_evt->params.discovered_db.charateristics[i].characteristic.handle_value; break; } } - LOG("[BAS_C]: Battery Service discovered at peer.\r\n"); + NRF_LOG_DEBUG("Battery Service discovered at peer.\r\n"); - ble_bas_c_evt_t evt; - - evt.evt_type = BLE_BAS_C_EVT_DISCOVERY_COMPLETE; - - mp_ble_bas_c->evt_handler(mp_ble_bas_c, &evt); + //If the instance has been assigned prior to db_discovery, assign the db_handles + if (p_ble_bas_c->conn_handle != BLE_CONN_HANDLE_INVALID) + { + if ((p_ble_bas_c->peer_bas_db.bl_cccd_handle == BLE_GATT_HANDLE_INVALID)&& + (p_ble_bas_c->peer_bas_db.bl_handle == BLE_GATT_HANDLE_INVALID)) + { + p_ble_bas_c->peer_bas_db = evt.params.bas_db; + } + } + p_ble_bas_c->evt_handler(p_ble_bas_c, &evt); } else { - LOG("[BAS_C]: Battery Service discovery failure at peer. \r\n"); + NRF_LOG_DEBUG("Battery Service discovery failure at peer. \r\n"); } } @@ -215,7 +257,7 @@ static void db_discovery_evt_handler(ble_db_discovery_evt_t * p_evt) */ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool notification_enable) { - LOG("[BAS_C]: Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", + NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", handle_cccd,conn_handle); tx_message_t * p_msg; @@ -241,25 +283,40 @@ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool uint32_t ble_bas_c_init(ble_bas_c_t * p_ble_bas_c, ble_bas_c_init_t * p_ble_bas_c_init) { - if ((p_ble_bas_c == NULL) || (p_ble_bas_c_init == NULL)) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(p_ble_bas_c); + VERIFY_PARAM_NOT_NULL(p_ble_bas_c_init); ble_uuid_t bas_uuid; bas_uuid.type = BLE_UUID_TYPE_BLE; bas_uuid.uuid = BLE_UUID_BATTERY_SERVICE; - mp_ble_bas_c = p_ble_bas_c; + p_ble_bas_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_bas_c->peer_bas_db.bl_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_bas_c->peer_bas_db.bl_handle = BLE_GATT_HANDLE_INVALID; + p_ble_bas_c->evt_handler = p_ble_bas_c_init->evt_handler; + + return ble_db_discovery_evt_register(&bas_uuid); +} - mp_ble_bas_c->conn_handle = BLE_CONN_HANDLE_INVALID; - mp_ble_bas_c->bl_cccd_handle = BLE_GATT_HANDLE_INVALID; - mp_ble_bas_c->bl_handle = BLE_GATT_HANDLE_INVALID; - mp_ble_bas_c->evt_handler = p_ble_bas_c_init->evt_handler; - return ble_db_discovery_evt_register(&bas_uuid, - db_discovery_evt_handler); +/**@brief Function for handling Disconnected event received from the SoftDevice. + * + * @details This function check if the disconnect event is happening on the link + * associated with the current instance of the module, if so it will set its + * conn_handle to invalid. + * + * @param[in] p_ble_bas_c Pointer to the Battery Service Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_disconnected(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt) +{ + if (p_ble_bas_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ble_bas_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_bas_c->peer_bas_db.bl_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_bas_c->peer_bas_db.bl_handle = BLE_GATT_HANDLE_INVALID; + } } @@ -272,10 +329,6 @@ void ble_bas_c_on_ble_evt(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt switch (p_ble_evt->header.evt_id) { - case BLE_GAP_EVT_CONNECTED: - p_ble_bas_c->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; - break; - case BLE_GATTC_EVT_HVX: on_hvx(p_ble_bas_c, p_ble_evt); break; @@ -288,6 +341,10 @@ void ble_bas_c_on_ble_evt(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt on_read_rsp(p_ble_bas_c, p_ble_evt); break; + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ble_bas_c, p_ble_evt); + break; + default: break; } @@ -296,26 +353,50 @@ void ble_bas_c_on_ble_evt(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt uint32_t ble_bas_c_bl_notif_enable(ble_bas_c_t * p_ble_bas_c) { - if (p_ble_bas_c == NULL) + VERIFY_PARAM_NOT_NULL(p_ble_bas_c); + + if (p_ble_bas_c->conn_handle == BLE_CONN_HANDLE_INVALID) { - return NRF_ERROR_NULL; + return NRF_ERROR_INVALID_STATE; } - return cccd_configure(p_ble_bas_c->conn_handle, p_ble_bas_c->bl_cccd_handle, true); + return cccd_configure(p_ble_bas_c->conn_handle, p_ble_bas_c->peer_bas_db.bl_cccd_handle, true); } uint32_t ble_bas_c_bl_read(ble_bas_c_t * p_ble_bas_c) { + VERIFY_PARAM_NOT_NULL(p_ble_bas_c); + if (p_ble_bas_c->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + tx_message_t * msg; msg = &m_tx_buffer[m_tx_insert_index++]; m_tx_insert_index &= TX_BUFFER_MASK; - msg->req.read_handle = p_ble_bas_c->bl_handle; + msg->req.read_handle = p_ble_bas_c->peer_bas_db.bl_handle; msg->conn_handle = p_ble_bas_c->conn_handle; msg->type = READ_REQ; tx_buffer_process(); return NRF_SUCCESS; } + + +uint32_t ble_bas_c_handles_assign(ble_bas_c_t * p_ble_bas_c, + uint16_t conn_handle, + ble_bas_c_db_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ble_bas_c); + + p_ble_bas_c->conn_handle = conn_handle; + if (p_peer_handles != NULL) + { + p_ble_bas_c->peer_bas_db = *p_peer_handles; + } + return NRF_SUCCESS; +} +#endif // NRF_MODULE_ENABLED(BLE_BAS_C) diff --git a/components/ble/ble_services/ble_bas_c/ble_bas_c.h b/components/ble/ble_services/ble_bas_c/ble_bas_c.h index 242cc8d..c35975a 100644 --- a/components/ble/ble_services/ble_bas_c/ble_bas_c.h +++ b/components/ble/ble_services/ble_bas_c/ble_bas_c.h @@ -1,15 +1,46 @@ -/* - * Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_bas_c Battery Service Client + * @defgroup ble_bas_c Battery Service Client * @{ * @ingroup ble_sdk_srv * @brief Battery Service Client module. @@ -27,6 +58,11 @@ #include #include "ble.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif /** * @defgroup bas_c_enums Enumerations @@ -48,13 +84,23 @@ typedef enum * @{ */ + +/**@brief Structure containing the handles related to the Battery Service found on the peer. */ +typedef struct +{ + uint16_t bl_cccd_handle; /**< Handle of the CCCD of the Battery Level characteristic. */ + uint16_t bl_handle; /**< Handle of the Battery Level characteristic as provided by the SoftDevice. */ +} ble_bas_c_db_t; + /**@brief Battery Service Client Event structure. */ typedef struct { ble_bas_c_evt_type_t evt_type; /**< Event Type. */ + uint16_t conn_handle; /**< Connection handle relevent to this event.*/ union { - uint8_t battery_level; /**< Battery level received from peer. This field will be used for the events @ref BLE_BAS_C_EVT_BATT_NOTIFICATION and @ref BLE_BAS_C_EVT_BATT_READ_RESP.*/ + ble_bas_c_db_t bas_db; /**< Battery Service related handles found on the peer device. This will be filled if the evt_type is @ref BLE_BAS_C_EVT_DISCOVERY_COMPLETE.*/ + uint8_t battery_level; /**< Battery level received from peer. This field will be used for the events @ref BLE_BAS_C_EVT_BATT_NOTIFICATION and @ref BLE_BAS_C_EVT_BATT_READ_RESP.*/ } params; } ble_bas_c_evt_t; @@ -88,8 +134,7 @@ typedef void (* ble_bas_c_evt_handler_t) (ble_bas_c_t * p_bas_bas_c, ble_bas_c_e struct ble_bas_c_s { uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */ - uint16_t bl_cccd_handle; /**< Handle of the CCCD of the Battery Level characteristic. */ - uint16_t bl_handle; /**< Handle of the Battery Level characteristic as provided by the SoftDevice. */ + ble_bas_c_db_t peer_bas_db; /**< Handles related to BAS on the peer*/ ble_bas_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the Battery service. */ }; @@ -111,7 +156,7 @@ typedef struct * * @details This function will initialize the module and set up Database Discovery to discover * the Battery Service. After calling this function, call @ref ble_db_discovery_start - * to start discovery. + * to start discovery once a link with a peer has been established. * * @param[out] p_ble_bas_c Pointer to the Battery Service client structure. * @param[in] p_ble_bas_c_init Pointer to the Battery Service initialization structure containing @@ -147,7 +192,7 @@ void ble_bas_c_on_ble_evt(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt * * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer. * NRF_ERROR_NULL Parameter is NULL. - * Otherwise, an error code returned by the SoftDevice API @ref + * Otherwise, an error code returned by the SoftDevice API @ref * sd_ble_gattc_write. */ uint32_t ble_bas_c_bl_notif_enable(ble_bas_c_t * p_ble_bas_c); @@ -162,8 +207,46 @@ uint32_t ble_bas_c_bl_notif_enable(ble_bas_c_t * p_ble_bas_c); uint32_t ble_bas_c_bl_read(ble_bas_c_t * p_ble_bas_c); +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery modue. + * This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of Battery service at the peer. If so, it will + * call the application's event handler indicating that the Battery service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param p_ble_bas_c Pointer to the Battery Service client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + * + */ +void ble_bas_on_db_disc_evt(ble_bas_c_t * p_ble_bas_c, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for assigning handles to a this instance of bas_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_BAS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ble_bas_c Pointer to the Battery client structure instance to associate. + * @param[in] conn_handle Connection handle to associated with the given Battery Client Instance. + * @param[in] p_peer_handles Attribute handles on the BAS server you want this BAS client to + * interact with. + */ +uint32_t ble_bas_c_handles_assign(ble_bas_c_t * p_ble_bas_c, + uint16_t conn_handle, + ble_bas_c_db_t * p_peer_handles); + /** @} */ // End tag for Function group. + +#ifdef __cplusplus +} +#endif + #endif // BLE_BAS_C_H__ /** @} */ // End tag for the file. diff --git a/components/ble/ble_services/ble_bps/ble_bps.c b/components/ble/ble_services/ble_bps/ble_bps.c index a3b89ad..36f452e 100644 --- a/components/ble/ble_services/ble_bps/ble_bps.c +++ b/components/ble/ble_services/ble_bps/ble_bps.c @@ -1,26 +1,54 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_BPS) #include "ble_bps.h" #include #include "nordic_common.h" #include "ble_l2cap.h" #include "ble_srv_common.h" -#include "app_util.h" #define OPCODE_LENGTH 1 /**< Length of opcode inside Blood Pressure Measurement packet. */ @@ -242,7 +270,7 @@ static uint32_t bps_measurement_char_add(ble_bps_t * p_bps, const ble_bps_init_t ble_gatts_attr_md_t attr_md; ble_bps_meas_t initial_bpm; uint8_t encoded_bpm[MAX_BPM_LEN]; - + memset(&cccd_md, 0, sizeof(cccd_md)); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); @@ -250,16 +278,16 @@ static uint32_t bps_measurement_char_add(ble_bps_t * p_bps, const ble_bps_init_t cccd_md.write_perm = p_bps_init->bps_meas_attr_md.cccd_write_perm; memset(&char_md, 0, sizeof(char_md)); - + char_md.char_props.indicate = 1; char_md.p_char_user_desc = NULL; char_md.p_char_pf = NULL; char_md.p_user_desc_md = NULL; char_md.p_cccd_md = &cccd_md; char_md.p_sccd_md = NULL; - + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR); - + memset(&attr_md, 0, sizeof(attr_md)); attr_md.vloc = BLE_GATTS_VLOC_STACK; @@ -268,17 +296,17 @@ static uint32_t bps_measurement_char_add(ble_bps_t * p_bps, const ble_bps_init_t attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 1; - + memset(&attr_char_value, 0, sizeof(attr_char_value)); memset(&initial_bpm, 0, sizeof(initial_bpm)); - + attr_char_value.p_uuid = &ble_uuid; attr_char_value.p_attr_md = &attr_md; attr_char_value.init_len = bps_measurement_encode(p_bps, &initial_bpm, encoded_bpm); attr_char_value.init_offs = 0; attr_char_value.max_len = MAX_BPM_LEN; attr_char_value.p_value = encoded_bpm; - + return sd_ble_gatts_characteristic_add(p_bps->service_handle, &char_md, &attr_char_value, @@ -301,18 +329,18 @@ static uint32_t bps_feature_char_add(ble_bps_t * p_bps, const ble_bps_init_t * p ble_gatts_attr_md_t attr_md; uint8_t init_value_encoded[2]; uint8_t init_value_len; - + memset(&char_md, 0, sizeof(char_md)); - + char_md.char_props.read = 1; char_md.p_char_user_desc = NULL; char_md.p_char_pf = NULL; char_md.p_user_desc_md = NULL; char_md.p_cccd_md = NULL; char_md.p_sccd_md = NULL; - + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BLOOD_PRESSURE_FEATURE_CHAR); - + memset(&attr_md, 0, sizeof(attr_md)); attr_md.vloc = BLE_GATTS_VLOC_STACK; @@ -321,9 +349,9 @@ static uint32_t bps_feature_char_add(ble_bps_t * p_bps, const ble_bps_init_t * p attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0; - + memset(&attr_char_value, 0, sizeof(attr_char_value)); - + init_value_len = uint16_encode(p_bps_init->feature, init_value_encoded); attr_char_value.p_uuid = &ble_uuid; @@ -332,7 +360,7 @@ static uint32_t bps_feature_char_add(ble_bps_t * p_bps, const ble_bps_init_t * p attr_char_value.init_offs = 0; attr_char_value.max_len = init_value_len; attr_char_value.p_value = init_value_encoded; - + return sd_ble_gatts_characteristic_add(p_bps->service_handle, &char_md, &attr_char_value, @@ -358,21 +386,21 @@ uint32_t ble_bps_init(ble_bps_t * p_bps, const ble_bps_init_t * p_bps_init) { return err_code; } - + // Add measurement characteristic err_code = bps_measurement_char_add(p_bps, p_bps_init); if (err_code != NRF_SUCCESS) { return err_code; } - + // Add feature characteristic err_code = bps_feature_char_add(p_bps, p_bps_init); if (err_code != NRF_SUCCESS) { return err_code; } - + return NRF_SUCCESS; } @@ -388,18 +416,18 @@ uint32_t ble_bps_measurement_send(ble_bps_t * p_bps, ble_bps_meas_t * p_bps_meas uint16_t len; uint16_t hvx_len; ble_gatts_hvx_params_t hvx_params; - + len = bps_measurement_encode(p_bps, p_bps_meas, encoded_bps_meas); hvx_len = len; memset(&hvx_params, 0, sizeof(hvx_params)); - + hvx_params.handle = p_bps->meas_handles.value_handle; hvx_params.type = BLE_GATT_HVX_INDICATION; hvx_params.offset = 0; hvx_params.p_len = &hvx_len; hvx_params.p_data = encoded_bps_meas; - + err_code = sd_ble_gatts_hvx(p_bps->conn_handle, &hvx_params); if ((err_code == NRF_SUCCESS) && (hvx_len != len)) { @@ -427,13 +455,20 @@ uint32_t ble_bps_is_indication_enabled(ble_bps_t * p_bps, bool * p_indication_en gatts_value.len = BLE_CCCD_VALUE_LEN; gatts_value.offset = 0; gatts_value.p_value = cccd_value_buf; - + err_code = sd_ble_gatts_value_get(p_bps->conn_handle, p_bps->meas_handles.cccd_handle, &gatts_value); + if (err_code == NRF_SUCCESS) { *p_indication_enabled = ble_srv_is_indication_enabled(cccd_value_buf); } + if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) + { + *p_indication_enabled = false; + return NRF_SUCCESS; + } return err_code; } +#endif // NRF_MODULE_ENABLED(BLE_BPS) diff --git a/components/ble/ble_services/ble_bps/ble_bps.h b/components/ble/ble_services/ble_bps/ble_bps.h index 04404e6..8ce01eb 100644 --- a/components/ble/ble_services/ble_bps/ble_bps.h +++ b/components/ble/ble_services/ble_bps/ble_bps.h @@ -1,31 +1,60 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_bps Blood Pressure Service + * @defgroup ble_bps Blood Pressure Service * @{ * @ingroup ble_sdk_srv * @brief Blood Pressure Service module. * * @details This module implements the Blood Pressure Service. * - * If an event handler is supplied by the application, the Blood Pressure + * If an event handler is supplied by the application, the Blood Pressure * Service will generate Blood Pressure Service events to the application. * * @note The application must propagate BLE stack events to the Blood Pressure Service * module by calling ble_bps_on_ble_evt() from the @ref softdevice_handler function. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -38,6 +67,10 @@ #include "ble_srv_common.h" #include "ble_date_time.h" +#ifdef __cplusplus +extern "C" { +#endif + // Blood Pressure Feature bits #define BLE_BPS_FEATURE_BODY_MOVEMENT_BIT (0x01 << 0) /**< Body Movement Detection Support bit. */ #define BLE_BPS_FEATURE_CUFF_FIT_BIT (0x01 << 1) /**< Cuff Fit Detection Support bit. */ @@ -60,7 +93,7 @@ typedef struct ble_bps_evt_type_t evt_type; /**< Type of event. */ } ble_bps_evt_t; -// Forward declaration of the ble_bps_t type. +// Forward declaration of the ble_bps_t type. typedef struct ble_bps_s ble_bps_t; /**@brief Blood Pressure Service event handler type. */ @@ -156,6 +189,11 @@ uint32_t ble_bps_measurement_send(ble_bps_t * p_bps, ble_bps_meas_t * p_bps_meas */ uint32_t ble_bps_is_indication_enabled(ble_bps_t * p_bps, bool * p_indication_enabled); + +#ifdef __cplusplus +} +#endif + #endif // BLE_BPS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_cscs/ble_cscs.c b/components/ble/ble_services/ble_cscs/ble_cscs.c index 490c891..9585c4f 100644 --- a/components/ble/ble_services/ble_cscs/ble_cscs.c +++ b/components/ble/ble_services/ble_cscs/ble_cscs.c @@ -1,17 +1,45 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -200,7 +228,7 @@ static uint32_t csc_measurement_char_add(ble_cscs_t * p_cscs, const ble_cscs_ini char_md.p_sccd_md = NULL; BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CSC_MEASUREMENT_CHAR); - + memset(&attr_md, 0, sizeof(attr_md)); BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm ); @@ -253,7 +281,7 @@ static uint32_t csc_feature_char_add(ble_cscs_t * p_cscs, const ble_cscs_init_t char_md.p_sccd_md = NULL; BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CSC_FEATURE_CHAR); - + memset(&attr_md, 0, sizeof(attr_md)); attr_md.read_perm = p_cscs_init->csc_feature_attr_md.read_perm; @@ -263,9 +291,9 @@ static uint32_t csc_feature_char_add(ble_cscs_t * p_cscs, const ble_cscs_init_t attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0; - + memset(&attr_char_value, 0, sizeof(attr_char_value)); - + init_value_len = uint16_encode(p_cscs_init->feature, &init_value_encoded[0]); attr_char_value.p_uuid = &ble_uuid; diff --git a/components/ble/ble_services/ble_cscs/ble_cscs.h b/components/ble/ble_services/ble_cscs/ble_cscs.h index 5517ccb..210c074 100644 --- a/components/ble/ble_services/ble_cscs/ble_cscs.h +++ b/components/ble/ble_services/ble_cscs/ble_cscs.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_csc Cycling Speed and Cadence Service + * @defgroup ble_cscs Cycling Speed and Cadence Service * @{ * @ingroup ble_sdk_srv * @brief Cycling Speed and Cadence Service module. @@ -22,23 +50,23 @@ * calls ble_cscs_measurement_send(). * * To use this service, you need to provide the the supported features (@ref BLE_CSCS_FEATURES). - * If you choose to support Wheel revolution data (feature bit @ref BLE_CSCS_FEATURE_WHEEL_REV_BIT), - * you then need to support the 'setting of cumulative value' operation by the supporting the + * If you choose to support Wheel revolution data (feature bit @ref BLE_CSCS_FEATURE_WHEEL_REV_BIT), + * you then need to support the 'setting of cumulative value' operation by the supporting the * Speed and Cadence Control Point (@ref ble_sdk_srv_sc_ctrlpt) by setting the @ref BLE_SRV_SC_CTRLPT_CUM_VAL_OP_SUPPORTED * bit of the ctrplt_supported_functions in the @ref ble_cscs_init_t structure. * If you want to support the 'start autocalibration' control point feature, you need, after the @ref BLE_SC_CTRLPT_EVT_START_CALIBRATION * has been received and the auto calibration is finished, to call the @ref ble_sc_ctrlpt_rsp_send to indicate that the operation is finished * and thus be able to receive new control point operations. - * If you want to support the 'sensor location' related operation, you need to provide a list of supported location in the + * If you want to support the 'sensor location' related operation, you need to provide a list of supported location in the * @ref ble_cscs_init_t structure. - * * - * @note The application or the service using this module must propagate BLE stack events to the - * Cycling Speead and Candence Service module by calling ble_cscs_on_ble_evt() from the + * + * @note The application or the service using this module must propagate BLE stack events to the + * Cycling Speead and Candence Service module by calling ble_cscs_on_ble_evt() from the * from the @ref softdevice_handler function. This service will forward the event to the @ref ble_sdk_srv_sc_ctrlpt module. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -52,6 +80,10 @@ #include "ble_sc_ctrlpt.h" #include "ble_sensor_location.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @defgroup BLE_CSCS_FEATURES Cycling Speed and Cadence Service feature bits * @{ */ #define BLE_CSCS_FEATURE_WHEEL_REV_BIT (0x01 << 0) /**< Wheel Revolution Data Supported bit. */ @@ -72,7 +104,7 @@ typedef struct ble_cscs_evt_type_t evt_type; /**< Type of event. */ } ble_cscs_evt_t; -// Forward declaration of the ble_csc_t type. +// Forward declaration of the ble_csc_t type. typedef struct ble_cscs_s ble_cscs_t; /**@brief Cycling Speed and Cadence Service event handler type. */ @@ -156,6 +188,11 @@ void ble_cscs_on_ble_evt(ble_cscs_t * p_cscs, ble_evt_t * p_ble_evt); */ uint32_t ble_cscs_measurement_send(ble_cscs_t * p_cscs, ble_cscs_meas_t * p_measurement); + +#ifdef __cplusplus +} +#endif + #endif // BLE_CSCS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c b/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c index 33e24fc..e7bd514 100644 --- a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c +++ b/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /* Attention! @@ -272,7 +300,7 @@ static void sc_ctrlpt_resp_send(ble_sc_ctrlpt_t * p_sc_ctrlpt) // Wait for HVC event break; - case BLE_ERROR_NO_TX_BUFFERS: + case BLE_ERROR_NO_TX_PACKETS: // Wait for TX_COMPLETE event to retry transmission p_sc_ctrlpt->procedure_status = BLE_SCPT_INDICATION_PENDING; break; @@ -307,7 +335,11 @@ static void on_ctrlpt_write(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_sc_ctrlpt_evt_t evt; auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.offset = 0; + auth_reply.params.write.len = 0; + auth_reply.params.write.p_data = NULL; auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; if (is_cccd_configured(p_sc_ctrlpt)) { @@ -356,7 +388,7 @@ static void on_ctrlpt_write(ble_sc_ctrlpt_t * p_sc_ctrlpt, switch (rcvd_ctrlpt.opcode) { case BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS: - if ((p_sc_ctrlpt->supported_functions & + if ((p_sc_ctrlpt->supported_functions & BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED) == BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED) { @@ -369,7 +401,7 @@ static void on_ctrlpt_write(ble_sc_ctrlpt_t * p_sc_ctrlpt, break; case BLE_SCPT_UPDATE_SENSOR_LOCATION: - if ((p_sc_ctrlpt->supported_functions & + if ((p_sc_ctrlpt->supported_functions & BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED) == BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED) { diff --git a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h b/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h index fc5ac9b..ccc5637 100644 --- a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h +++ b/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -18,12 +46,12 @@ * @brief Speed and Cadence Control Point module. * * @details This module implements the Speed and Cadence control point behavior. It is used - * by the @ref ble_sdk_srv_csc module and the ble_sdk_srv_rsc module for control point + * by the @ref ble_cscs module and the ble_sdk_srv_rsc module for control point * mechanisms like setting a cumulative value, Start an automatic calibration, * Update the sensor location or request the supported locations. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -36,6 +64,10 @@ #include "ble_srv_common.h" #include "ble_sensor_location.h" +#ifdef __cplusplus +extern "C" { +#endif + #define BLE_SC_CTRLPT_MAX_LEN 19 /**< maximum lenght for Speed and cadence control point characteristic value. */ #define BLE_SC_CTRLPT_MIN_LEN 1 /**< minimum length for Speed and cadence control point characteristic value. */ @@ -206,6 +238,11 @@ uint32_t ble_sc_ctrlpt_rsp_send(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_scpt_response void ble_sc_ctrlpt_on_ble_evt(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t * p_ble_evt); + +#ifdef __cplusplus +} +#endif + #endif // BLE_SC_CTRLPT_H__ /** @} */ diff --git a/components/ble/ble_services/ble_cts_c/ble_cts_c.c b/components/ble/ble_services/ble_cts_c/ble_cts_c.c index 4dbc0b5..ac64bd2 100644 --- a/components/ble/ble_services/ble_cts_c/ble_cts_c.c +++ b/components/ble/ble_services/ble_cts_c/ble_cts_c.c @@ -1,35 +1,60 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_CTS_C) #include #include "ble.h" #include "ble_srv_common.h" #include "ble_gattc.h" #include "ble_cts_c.h" #include "ble_date_time.h" -#include "device_manager.h" #include "ble_db_discovery.h" -#include "app_trace.h" +#define NRF_LOG_MODULE_NAME "BLE_CTS_C" +#include "nrf_log.h" -#define LOG app_trace_log /**< Debug logger macro that will be used in this file to do logging of important information over UART. */ #define CTS_YEAR_MIN 1582 /**< The lowest valid Current Time year is the year when the western calendar was introduced. */ #define CTS_YEAR_MAX 9999 /**< The highest possible Current Time. */ #define CTS_C_CURRENT_TIME_EXPECTED_LENGTH 10 /**< | Year |Month |Day |Hours |Minutes |Seconds |Weekday |Fraction|Reason | | 2 bytes |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte | = 10 bytes. */ -static ble_cts_c_t * mp_ble_cts; /**< Pointer to the current instance of the CTS Client module. The memory for this provided by the application.*/ - - /**@brief Function for handling events from the database discovery module. * @@ -42,18 +67,21 @@ static ble_cts_c_t * mp_ble_cts; /**< Pointer to the current instan * @param[in] p_evt Pointer to the event received from the database discovery module. * */ -static void db_discover_evt_handler(ble_db_discovery_evt_t * p_evt) +void ble_cts_c_on_db_disc_evt(ble_cts_c_t * p_cts, ble_db_discovery_evt_t * p_evt) { - LOG("[CTS]: Database Discovery handler called with event 0x%x\r\n", p_evt->evt_type); + NRF_LOG_DEBUG("Database Discovery handler called with event 0x%x\r\n", p_evt->evt_type); ble_cts_c_evt_t evt; + const ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics; + + evt.evt_type = BLE_CTS_C_EVT_DISCOVERY_FAILED; + evt.conn_handle = p_evt->conn_handle; // Check if the Current Time Service was discovered. if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_CURRENT_TIME_SERVICE && p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) { - mp_ble_cts->conn_handle = p_evt->conn_handle; // Find the handles of the Current Time characteristic. uint32_t i; @@ -64,50 +92,39 @@ static void db_discover_evt_handler(ble_db_discovery_evt_t * p_evt) BLE_UUID_CURRENT_TIME_CHAR) { // Found Current Time characteristic. Store CCCD and value handle and break. - mp_ble_cts->cts_cccd_handle = - p_evt->params.discovered_db.charateristics[i].cccd_handle; - mp_ble_cts->current_time_handle = - p_evt->params.discovered_db.charateristics[i].characteristic.handle_value; + evt.params.char_handles.cts_handle = p_chars->characteristic.handle_value; + evt.params.char_handles.cts_cccd_handle = p_chars->cccd_handle; break; } } - LOG("[CTS]: Current Time Service discovered at peer.\r\n"); + NRF_LOG_INFO("Current Time Service discovered at peer.\r\n"); - evt.evt_type = BLE_CTS_C_EVT_DISCOVERY_COMPLETE; - - mp_ble_cts->evt_handler(mp_ble_cts, &evt); - } - else - { - evt.evt_type = BLE_CTS_C_EVT_SERVICE_NOT_FOUND; - mp_ble_cts->evt_handler(mp_ble_cts, &evt); + evt.evt_type = BLE_CTS_C_EVT_DISCOVERY_COMPLETE; } + p_cts->evt_handler(p_cts, &evt); } uint32_t ble_cts_c_init(ble_cts_c_t * p_cts, ble_cts_c_init_t const * p_cts_init) { - if ( (p_cts_init == NULL) - || (p_cts_init->error_handler == NULL) - || (p_cts_init->evt_handler == NULL) - || (p_cts == NULL)) - { - return NRF_ERROR_NULL; - } - - ble_uuid_t cts_uuid; + //Verify that the parameters needed for to initialize this instance of CTS are not NULL. + VERIFY_PARAM_NOT_NULL(p_cts); + VERIFY_PARAM_NOT_NULL(p_cts_init); + VERIFY_PARAM_NOT_NULL(p_cts_init->error_handler); + VERIFY_PARAM_NOT_NULL(p_cts_init->evt_handler); - mp_ble_cts = p_cts; + static ble_uuid_t cts_uuid; BLE_UUID_BLE_ASSIGN(cts_uuid, BLE_UUID_CURRENT_TIME_SERVICE); - p_cts->evt_handler = p_cts_init->evt_handler; - p_cts->error_handler = p_cts_init->error_handler; - p_cts->conn_handle = BLE_CONN_HANDLE_INVALID; - p_cts->current_time_handle = BLE_GATT_HANDLE_INVALID; + p_cts->evt_handler = p_cts_init->evt_handler; + p_cts->error_handler = p_cts_init->error_handler; + p_cts->conn_handle = BLE_CONN_HANDLE_INVALID; + p_cts->char_handles.cts_handle = BLE_GATT_HANDLE_INVALID; + p_cts->char_handles.cts_cccd_handle = BLE_GATT_HANDLE_INVALID; - return ble_db_discovery_evt_register(&cts_uuid, db_discover_evt_handler); + return ble_db_discovery_evt_register(&cts_uuid); } @@ -132,17 +149,8 @@ static uint32_t current_time_decode(current_time_char_t * p_time, return NRF_ERROR_DATA_SIZE; } - LOG("Current Time read response data: %02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X \r\n", - p_data[0], - p_data[1], - p_data[2], - p_data[3], - p_data[4], - p_data[5], - p_data[6], - p_data[7], - p_data[8], - p_data[9]); + NRF_LOG_DEBUG("Current Time read response data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG(p_data, 10); uint32_t index = 0; @@ -236,6 +244,12 @@ static void current_time_read(ble_cts_c_t * p_cts, const ble_evt_t * p_ble_evt) ble_cts_c_evt_t evt; uint32_t err_code = NRF_SUCCESS; + // Check if the event is on the same connection as this cts instance + if (p_cts->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_SUCCESS) { err_code = current_time_decode(&evt.params.current_time, @@ -246,7 +260,6 @@ static void current_time_read(ble_cts_c_t * p_cts, const ble_evt_t * p_ble_evt) { // The data length was invalid, decoding was not completed. evt.evt_type = BLE_CTS_C_EVT_INVALID_TIME; - p_cts->evt_handler(p_cts, &evt); } else { @@ -257,15 +270,14 @@ static void current_time_read(ble_cts_c_t * p_cts, const ble_evt_t * p_ble_evt) { // Invalid time received. evt.evt_type = BLE_CTS_C_EVT_INVALID_TIME; - p_cts->evt_handler(p_cts, &evt); } else { // Valid time reveiced. evt.evt_type = BLE_CTS_C_EVT_CURRENT_TIME; - p_cts->evt_handler(p_cts, &evt); } } + p_cts->evt_handler(p_cts, &evt); } } @@ -277,8 +289,10 @@ static void current_time_read(ble_cts_c_t * p_cts, const ble_evt_t * p_ble_evt) */ static void on_disconnect(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt) { - // The connection handle is now invalid. It will be re-initialized upon connection. - p_cts->conn_handle = BLE_CONN_HANDLE_INVALID; + if (p_cts->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_cts->conn_handle = BLE_CONN_HANDLE_INVALID; + } if (ble_cts_c_is_cts_discovered(p_cts)) { @@ -289,21 +303,18 @@ static void on_disconnect(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt) evt.evt_type = BLE_CTS_C_EVT_DISCONN_COMPLETE; p_cts->evt_handler(p_cts, &evt); - p_cts->current_time_handle = BLE_GATT_HANDLE_INVALID; + p_cts->char_handles.cts_handle = BLE_GATT_HANDLE_INVALID; + p_cts->char_handles.cts_cccd_handle = BLE_GATT_HANDLE_INVALID; } } void ble_cts_c_on_ble_evt(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt) { - LOG("[CTS]: BLE event handler called with event 0x%x\r\n", p_ble_evt->header.evt_id); + NRF_LOG_DEBUG("BLE event handler called with event 0x%x\r\n", p_ble_evt->header.evt_id); switch (p_ble_evt->header.evt_id) { - case BLE_GAP_EVT_CONNECTED: - p_cts->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; - break; - case BLE_GATTC_EVT_READ_RSP: current_time_read(p_cts, p_ble_evt); break; @@ -326,7 +337,23 @@ uint32_t ble_cts_c_current_time_read(ble_cts_c_t const * p_cts) return NRF_ERROR_NOT_FOUND; } - return sd_ble_gattc_read(p_cts->conn_handle, p_cts->current_time_handle, 0); + return sd_ble_gattc_read(p_cts->conn_handle, p_cts->char_handles.cts_handle, 0); } +uint32_t ble_cts_c_handles_assign(ble_cts_c_t * p_cts, + const uint16_t conn_handle, + const ble_cts_c_handles_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_cts); + + p_cts->conn_handle = conn_handle; + if (p_peer_handles != NULL) + { + p_cts->char_handles.cts_cccd_handle = p_peer_handles->cts_cccd_handle; + p_cts->char_handles.cts_handle = p_peer_handles->cts_handle; + } + + return NRF_SUCCESS; +} +#endif // NRF_MODULE_ENABLED(BLE_CTS_C) diff --git a/components/ble/ble_services/ble_cts_c/ble_cts_c.h b/components/ble/ble_services/ble_cts_c/ble_cts_c.h index eae377c..41c7855 100644 --- a/components/ble/ble_services/ble_cts_c/ble_cts_c.h +++ b/components/ble/ble_services/ble_cts_c/ble_cts_c.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_cts_c Current Time Service client + * @defgroup ble_cts_c Current Time Service client * @{ * @ingroup ble_sdk_srv * @brief Current Time Service client module. @@ -23,11 +51,17 @@ * the application can trigger a read of the current time from the connected server. * * The module informs the application about a successful discovery using the - * @ref BLE_CTS_C_EVT_DISCOVERY_COMPLETE event. The application can then use the function - * @ref ble_cts_c_current_time_read to read the current time. Calling this function - * triggers either a @ref BLE_CTS_C_EVT_CURRENT_TIME event or a - * @ref BLE_CTS_C_EVT_INVALID_TIME event, which is sent to the application. The current - * time is then available in the params field of the passed ble_cts_evt_t structure. + * @ref BLE_CTS_C_EVT_DISCOVERY_COMPLETE event. The handles for the CTS server is now + * available in the @ref ble_cts_c_evt_t structure. These handles must be assigned to an + * instance of CTS_C, using @ref ble_cts_c_handles_assign. For more information about + * service discovery, see the ble_discovery module documentation @ref lib_ble_db_discovery. + * + * The application can then use the function @ref ble_cts_c_current_time_read to read the + * current time. If the read succeeds, it will trigger either a + * @ref BLE_CTS_C_EVT_CURRENT_TIME event or a @ref BLE_CTS_C_EVT_INVALID_TIME event + * (depending on if the data that was read was actually a valid time), which is then sent + * to the application. The current time is then available in the params field of the + * passed @ref ble_cts_c_evt_t structure. * * @note The application must propagate BLE stack events to this module by calling * ble_cts_c_on_ble_evt() from the @ref softdevice_handler callback function. @@ -40,9 +74,13 @@ #include "ble_gattc.h" #include "ble.h" #include "ble_date_time.h" -#include "device_manager.h" +#include "ble_db_discovery.h" #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief "Day Date Time" field of the "Exact Time 256" field of the Current Time Characteristic. */ typedef struct @@ -80,33 +118,42 @@ typedef struct ble_cts_c_s ble_cts_c_t; /**@brief Current Time Service client event type. */ typedef enum { - BLE_CTS_C_EVT_SERVICE_NOT_FOUND, /**< The Current Time Service was not found at the peer. */ BLE_CTS_C_EVT_DISCOVERY_COMPLETE, /**< The Current Time Service was found at the peer. */ + BLE_CTS_C_EVT_DISCOVERY_FAILED, /**< The Current Time Service was not found at the peer. */ BLE_CTS_C_EVT_DISCONN_COMPLETE, /**< Event indicating that the Current Time Service client module has finished processing the BLE_GAP_EVT_DISCONNECTED event. This event is raised only if a valid instance of the Current Time Service was found at the server. The event can be used by the application to do clean up related to the Current Time Service client.*/ BLE_CTS_C_EVT_CURRENT_TIME, /**< A new current time reading has been received. */ BLE_CTS_C_EVT_INVALID_TIME /**< The current time value received from the peer is invalid.*/ } ble_cts_c_evt_type_t; +/**@brief Structure containing the handles related to the Heart Rate Service found on the peer. */ +typedef struct +{ + uint16_t cts_handle; /**< Handle of the Current Time characteristic as provided by the SoftDevice. */ + uint16_t cts_cccd_handle; /**< Handle of the CCCD of the Current Time characteristic. */ +} ble_cts_c_handles_t; + /**@brief Current Time Service client event. */ typedef struct { ble_cts_c_evt_type_t evt_type; /**< Type of event. */ + uint16_t conn_handle; /**< Connection handle on which the CTS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_CTS_C_EVT_DISCOVERY_COMPLETE.*/ union { - current_time_char_t current_time; /**< Current Time Characteristic data. See @ref BLE_CTS_C_EVT_CURRENT_TIME. */ + current_time_char_t current_time; /**< Current Time Characteristic data. This will be filled when the evt_type is @ref BLE_CTS_C_EVT_CURRENT_TIME. */ + ble_cts_c_handles_t char_handles; /**< Current Time related handles found on the peer device. This will be filled when the evt_type is @ref BLE_HRS_C_EVT_DISCOVERY_COMPLETE.*/ } params; } ble_cts_c_evt_t; /**@brief Current Time Service client event handler type. */ typedef void (* ble_cts_c_evt_handler_t) (ble_cts_c_t * p_cts, ble_cts_c_evt_t * p_evt); + /**@brief Current Time Service client structure. This structure contains status information for the client. */ struct ble_cts_c_s { ble_cts_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events from the Current Time Service client. */ ble_srv_error_handler_t error_handler; /**< Function to be called if an error occurs. */ - uint16_t current_time_handle; /**< Handle of Current Time Characteristic at the peer (handles are provided by the BLE stack through the DB Discovery module). */ - uint16_t cts_cccd_handle; /**< Handle of the CCCD of the Current Time Characteristic at the peer. */ + ble_cts_c_handles_t char_handles; /**< Handles of Current Time Characteristic at the peer (handles are provided by the BLE stack through the DB Discovery module). */ uint16_t conn_handle; /**< Handle of the current connection. BLE_CONN_HANDLE_INVALID if not in a connection. */ }; @@ -133,6 +180,20 @@ typedef struct uint32_t ble_cts_c_init(ble_cts_c_t * p_cts, const ble_cts_c_init_t * p_cts_init); +/**@brief Function for handling events from the database discovery module. + * + * @details This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of CTS at the peer. If so, it will + * call the application's event handler indicating that CTS has been + * discovered. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_cts Pointer to the CTS client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + */ + void ble_cts_c_on_db_disc_evt(ble_cts_c_t * p_cts, ble_db_discovery_evt_t * p_evt); + + /**@brief Function for handling the application's BLE stack events. * * @details This function handles all events from the BLE stack that are of interest to the @@ -152,7 +213,7 @@ void ble_cts_c_on_ble_evt(ble_cts_c_t * p_cts, const ble_evt_t * p_ble_evt); */ static __INLINE bool ble_cts_c_is_cts_discovered(const ble_cts_c_t * p_cts) { - return (p_cts->current_time_handle != BLE_GATT_HANDLE_INVALID); + return (p_cts->char_handles.cts_handle != BLE_GATT_HANDLE_INVALID); } @@ -164,6 +225,32 @@ static __INLINE bool ble_cts_c_is_cts_discovered(const ble_cts_c_t * p_cts) */ uint32_t ble_cts_c_current_time_read(ble_cts_c_t const * p_cts); + +/**@brief Function for assigning handles to a this instance of cts_c. + * + * @details Call this function when a link has been established with a peer to + * associate the link to this instance of the module. This makes it + * possible to handle several links and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_CTS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_cts Pointer to the CTS client structure instance to associate. + * @param[in] conn_handle Connection handle to associated with the given CTS instance. + * @param[in] p_peer_handles Attribute handles for the CTS server you want this CTS client to + * interact with. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If a p_cts was a NULL pointer. + */ +uint32_t ble_cts_c_handles_assign(ble_cts_c_t * p_cts, + const uint16_t conn_handle, + const ble_cts_c_handles_t * p_peer_handles); + + +#ifdef __cplusplus +} +#endif + #endif // BLE_CTS_C_H__ /** @} */ diff --git a/components/ble/ble_services/ble_dfu/ble_dfu.c b/components/ble/ble_services/ble_dfu/ble_dfu.c index 05d4b8b..4f6651e 100644 --- a/components/ble/ble_services/ble_dfu/ble_dfu.c +++ b/components/ble/ble_services/ble_dfu/ble_dfu.c @@ -1,182 +1,134 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +* qualification listings, this section of source code must not be modified. +*/ + #include "ble_dfu.h" -#include "nrf_error.h" -#include "ble_types.h" -#include "ble_gatts.h" -#include "app_util.h" -#include "ble_srv_common.h" -#include "nordic_common.h" -#include +#include "nrf_log.h" #include -#include - -#define MAX_DFU_PKT_LEN 20 /**< Maximum length (in bytes) of the DFU Packet characteristic. */ -#define PKT_START_DFU_PARAM_LEN 2 /**< Length (in bytes) of the parameters for Packet Start DFU Request. */ -#define PKT_INIT_DFU_PARAM_LEN 2 /**< Length (in bytes) of the parameters for Packet Init DFU Request. */ -#define PKT_RCPT_NOTIF_REQ_LEN 3 /**< Length (in bytes) of the Packet Receipt Notification Request. */ -#define MAX_PKTS_RCPT_NOTIF_LEN 6 /**< Maximum length (in bytes) of the Packets Receipt Notification. */ -#define MAX_RESPONSE_LEN 7 /**< Maximum length (in bytes) of the response to a Control Point command. */ -#define MAX_NOTIF_BUFFER_LEN MAX(MAX_PKTS_RCPT_NOTIF_LEN, MAX_RESPONSE_LEN) /**< Maximum length (in bytes) of the buffer needed by DFU Service while sending notifications to peer. */ - -enum -{ - OP_CODE_START_DFU = 1, /**< Value of the Op code field for 'Start DFU' command.*/ - OP_CODE_RECEIVE_INIT = 2, /**< Value of the Op code field for 'Initialize DFU parameters' command.*/ - OP_CODE_RECEIVE_FW = 3, /**< Value of the Op code field for 'Receive firmware image' command.*/ - OP_CODE_VALIDATE = 4, /**< Value of the Op code field for 'Validate firmware' command.*/ - OP_CODE_ACTIVATE_N_RESET = 5, /**< Value of the Op code field for 'Activate & Reset' command.*/ - OP_CODE_SYS_RESET = 6, /**< Value of the Op code field for 'Reset System' command.*/ - OP_CODE_IMAGE_SIZE_REQ = 7, /**< Value of the Op code field for 'Report received image size' command.*/ - OP_CODE_PKT_RCPT_NOTIF_REQ = 8, /**< Value of the Op code field for 'Request packet receipt notification.*/ - OP_CODE_RESPONSE = 16, /**< Value of the Op code field for 'Response.*/ - OP_CODE_PKT_RCPT_NOTIF = 17 /**< Value of the Op code field for 'Packets Receipt Notification'.*/ -}; - -static bool m_is_dfu_service_initialized = false; /**< Variable to check if the DFU service was initialized by the application.*/ -static uint8_t m_notif_buffer[MAX_NOTIF_BUFFER_LEN]; /**< Buffer used for sending notifications to peer. */ - -/**@brief Function for adding DFU Packet characteristic to the BLE Stack. - * - * @param[in] p_dfu DFU Service structure. - * - * @return NRF_SUCCESS on success. Otherwise an error code. - */ -static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu) -{ - ble_gatts_char_md_t char_md; - ble_gatts_attr_t attr_char_value; - ble_uuid_t char_uuid; - ble_gatts_attr_md_t attr_md; - - memset(&char_md, 0, sizeof(char_md)); - - char_md.char_props.write_wo_resp = 1; - char_md.p_char_user_desc = NULL; - char_md.p_char_pf = NULL; - char_md.p_user_desc_md = NULL; - char_md.p_cccd_md = NULL; - char_md.p_sccd_md = NULL; - - char_uuid.type = p_dfu->uuid_type; - char_uuid.uuid = BLE_DFU_PKT_CHAR_UUID; +#include "ble_hci.h" +#include "sdk_macros.h" +#include "ble_srv_common.h" +#include "nrf_dfu_settings.h" - memset(&attr_md, 0, sizeof(attr_md)); +#define MAX_CTRL_POINT_RESP_PARAM_LEN 3 - BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); +ble_dfu_t * p_m_dfu; - attr_md.vloc = BLE_GATTS_VLOC_STACK; - attr_md.rd_auth = 0; - attr_md.wr_auth = 0; - attr_md.vlen = 1; - memset(&attr_char_value, 0, sizeof(attr_char_value)); +void flash_callback(fs_evt_t const * const evt, fs_ret_t result) +{ + if (result == FS_SUCCESS) + { + NRF_LOG_INFO("Obtained settings, enter dfu is %d\n", s_dfu_settings.enter_buttonless_dfu); - attr_char_value.p_uuid = &char_uuid; - attr_char_value.p_attr_md = &attr_md; - attr_char_value.init_len = 0; - attr_char_value.init_offs = 0; - attr_char_value.max_len = MAX_DFU_PKT_LEN; - attr_char_value.p_value = NULL; + (void)sd_ble_gap_disconnect(p_m_dfu->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); - return sd_ble_gatts_characteristic_add(p_dfu->service_handle, - &char_md, - &attr_char_value, - &p_dfu->dfu_pkt_handles); + p_m_dfu->is_waiting_for_disconnection = true; + } } - -/**@brief Function for adding DFU Revision characteristic to the BLE Stack. - * - * @param[in] p_dfu DFU Service structure. - * - * @return NRF_SUCCESS on success. Otherwise an error code. - */ -static uint32_t dfu_rev_char_add(ble_dfu_t * const p_dfu, ble_dfu_init_t const * const p_dfu_init) +static void enter_bootloader(ble_dfu_t * p_dfu) { - ble_gatts_char_md_t char_md; - ble_gatts_attr_t attr_char_value; - ble_uuid_t char_uuid; - ble_gatts_attr_md_t attr_md; - - memset(&char_md, 0, sizeof(char_md)); - - char_md.char_props.read = 1; - char_md.p_char_user_desc = NULL; - char_md.p_char_pf = NULL; - char_md.p_user_desc_md = NULL; - char_md.p_cccd_md = NULL; - char_md.p_sccd_md = NULL; - - char_uuid.type = p_dfu->uuid_type; - char_uuid.uuid = BLE_DFU_REV_CHAR_UUID; - - memset(&attr_md, 0, sizeof(attr_md)); + if (p_dfu->evt_handler != NULL) + { + ble_dfu_evt_t evt; - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); - BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + evt.type = BLE_DFU_EVT_ENTERING_BOOTLOADER; - attr_md.vloc = BLE_GATTS_VLOC_STACK; - attr_md.rd_auth = 0; - attr_md.wr_auth = 0; - attr_md.vlen = 1; + p_dfu->evt_handler(p_dfu, &evt); + } - memset(&attr_char_value, 0, sizeof(attr_char_value)); + s_dfu_settings.enter_buttonless_dfu = true; - attr_char_value.p_uuid = &char_uuid; - attr_char_value.p_attr_md = &attr_md; - attr_char_value.init_len = sizeof(uint16_t); - attr_char_value.init_offs = 0; - attr_char_value.max_len = sizeof(uint16_t); - attr_char_value.p_value = (uint8_t *)&p_dfu_init->revision; + (void)nrf_dfu_settings_write(flash_callback); - return sd_ble_gatts_characteristic_add(p_dfu->service_handle, - &char_md, - &attr_char_value, - &p_dfu->dfu_rev_handles); + /* + TODO: + - Save bond data + */ } -/**@brief Function for adding DFU Control Point characteristic to the BLE Stack. +/**@brief Function for adding RX characteristic. * - * @param[in] p_dfu DFU Service structure. + * @param[in] p_nus Nordic UART Service structure. + * @param[in] p_nus_init Information needed to initialize the service. * - * @return NRF_SUCCESS on success. Otherwise an error code. + * @return NRF_SUCCESS on success, otherwise an error code. */ -static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu) +static uint32_t rx_char_add(ble_dfu_t * p_dfu, const ble_dfu_init_t * p_dfu_init) { + /**@snippet [Adding proprietary characteristic to S110 SoftDevice] */ ble_gatts_char_md_t char_md; + ble_gatts_attr_md_t cccd_md; ble_gatts_attr_t attr_char_value; - ble_uuid_t char_uuid; + ble_uuid_t ble_uuid; ble_gatts_attr_md_t attr_md; + memset(&cccd_md, 0, sizeof(cccd_md)); + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); + + cccd_md.vloc = BLE_GATTS_VLOC_STACK; + memset(&char_md, 0, sizeof(char_md)); - char_md.char_props.write = 1; char_md.char_props.notify = 1; + char_md.char_props.write = 1; char_md.p_char_user_desc = NULL; char_md.p_char_pf = NULL; char_md.p_user_desc_md = NULL; - char_md.p_cccd_md = NULL; + char_md.p_cccd_md = &cccd_md; char_md.p_sccd_md = NULL; - char_uuid.type = p_dfu->uuid_type; - char_uuid.uuid = BLE_DFU_CTRL_PT_UUID; + ble_uuid.type = p_dfu->uuid_type; + ble_uuid.uuid = 0x0001; memset(&attr_md, 0, sizeof(attr_md)); - BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); attr_md.vloc = BLE_GATTS_VLOC_STACK; @@ -186,481 +138,279 @@ static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu) memset(&attr_char_value, 0, sizeof(attr_char_value)); - attr_char_value.p_uuid = &char_uuid; + attr_char_value.p_uuid = &ble_uuid; attr_char_value.p_attr_md = &attr_md; attr_char_value.init_len = 0; attr_char_value.init_offs = 0; attr_char_value.max_len = BLE_L2CAP_MTU_DEF; - attr_char_value.p_value = NULL; return sd_ble_gatts_characteristic_add(p_dfu->service_handle, &char_md, &attr_char_value, - &p_dfu->dfu_ctrl_pt_handles); + &p_dfu->control_point_char); + /**@snippet [Adding proprietary characteristic to S110 SoftDevice] */ } -/**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the S110 SoftDevice. - * - * @param[in] p_dfu DFU Service Structure. - * @param[in] p_ble_evt Pointer to the event received from BLE stack. - */ -static void on_connect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) -{ - p_dfu->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; -} - -/**@brief Function for checking if the CCCD of DFU Control point is configured for Notification. - * - * @details This function checks if the CCCD of DFU Control Point characteristic is configured - * for Notification by the DFU Controller. - * - * @param[in] p_dfu DFU Service structure. - * - * @return True if the CCCD of DFU Control Point characteristic is configured for Notification. - * False otherwise. - */ -static bool is_cccd_configured(ble_dfu_t * p_dfu) +uint32_t ble_dfu_init(ble_dfu_t * p_dfu, const ble_dfu_init_t * p_dfu_init) { - // Check if the CCCDs are configured. - uint8_t cccd_val_buf[BLE_CCCD_VALUE_LEN]; - ble_gatts_value_t gatts_value; - - // Initialize value struct. - memset(&gatts_value, 0, sizeof(gatts_value)); - - gatts_value.len = BLE_CCCD_VALUE_LEN; - gatts_value.offset = 0; - gatts_value.p_value = cccd_val_buf; - - // Check the CCCD Value of DFU Control Point. - uint32_t err_code = sd_ble_gatts_value_get(p_dfu->conn_handle, - p_dfu->dfu_ctrl_pt_handles.cccd_handle, - &gatts_value); - if (err_code != NRF_SUCCESS) - { - if (p_dfu->error_handler != NULL) - { - p_dfu->error_handler(err_code); - } - return false; - } + uint32_t err_code; + ble_uuid_t ble_uuid; + ble_uuid128_t nus_base_uuid = BLE_DFU_BASE_UUID; - return ble_srv_is_notification_enabled(cccd_val_buf); -} + VERIFY_PARAM_NOT_NULL(p_dfu); + VERIFY_PARAM_NOT_NULL(p_dfu_init); + p_m_dfu = p_dfu; // TODO: find a nicer solution to this -/**@brief Function for handling a Write event on the Control Point characteristic. - * - * @param[in] p_dfu DFU Service Structure. - * @param[in] p_ble_write_evt Pointer to the write event received from BLE stack. - * - * @return NRF_SUCCESS on successful processing of control point write. Otherwise an error code. - */ -static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt) -{ - ble_gatts_rw_authorize_reply_params_t write_authorize_reply; + // Initialize the service structure. + p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID; + p_dfu->evt_handler = p_dfu_init->evt_handler; + p_dfu->is_waiting_for_disconnection = false; + p_dfu->is_ctrlpt_notification_enabled = false; - write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + /**@snippet [Adding proprietary Service to S110 SoftDevice] */ + // Add a custom base UUID. + err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_dfu->uuid_type); + VERIFY_SUCCESS(err_code); - if (!is_cccd_configured(p_dfu)) - { - // Send an error response to the peer indicating that the CCCD is improperly configured. - write_authorize_reply.params.write.gatt_status = - BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR; + ble_uuid.type = p_dfu->uuid_type; + ble_uuid.uuid = BLE_UUID_DFU_SERVICE; - return (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply)); + // Add the service. + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_dfu->service_handle); + /**@snippet [Adding proprietary Service to S110 SoftDevice] */ + VERIFY_SUCCESS(err_code); - } - else - { - uint32_t err_code; + // Add the RX Characteristic. + err_code = rx_char_add(p_dfu, p_dfu_init); + VERIFY_SUCCESS(err_code); - write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + err_code = nrf_dfu_flash_init(true); + VERIFY_SUCCESS(err_code); - err_code = (sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply)); + nrf_dfu_settings_init(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - } + return NRF_SUCCESS; +} - ble_dfu_evt_t ble_dfu_evt; +static void resp_send(ble_dfu_t * p_dfu, ble_dfu_buttonless_op_code_t op_code, ble_dfu_rsp_code_t rsp_code) +{ + // Send notification + uint16_t hvx_len; + uint8_t hvx_data[MAX_CTRL_POINT_RESP_PARAM_LEN]; + ble_gatts_hvx_params_t hvx_params; - switch (p_ble_write_evt->data[0]) - { - case OP_CODE_START_DFU: - ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_START; + memset(&hvx_params, 0, sizeof(hvx_params)); - if (p_ble_write_evt->len < PKT_START_DFU_PARAM_LEN) - { - return ble_dfu_response_send(p_dfu, - (ble_dfu_procedure_t) p_ble_write_evt->data[0], - BLE_DFU_RESP_VAL_OPER_FAILED); - } + hvx_len = 3; + hvx_data[0] = DFU_OP_RESPONSE_CODE; + hvx_data[1] = (uint8_t)op_code; + hvx_data[2] = (uint8_t)rsp_code; - ble_dfu_evt.evt.ble_dfu_pkt_write.len = 1; - ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]); + hvx_params.handle = p_dfu->control_point_char.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = hvx_data; - p_dfu->evt_handler(p_dfu, &ble_dfu_evt); - break; + (void)sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params); +} - case OP_CODE_RECEIVE_INIT: - ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_INIT_DATA; - if (p_ble_write_evt->len < PKT_INIT_DFU_PARAM_LEN) - { - return ble_dfu_response_send(p_dfu, - (ble_dfu_procedure_t) p_ble_write_evt->data[0], - BLE_DFU_RESP_VAL_OPER_FAILED); - } - - ble_dfu_evt.evt.ble_dfu_pkt_write.len = 1; - ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = &(p_ble_write_evt->data[1]); - p_dfu->evt_handler(p_dfu, &ble_dfu_evt); - break; +/**@brief Handle write events to the Location and Navigation Service Control Point characteristic. + * + * @param[in] p_dfu DFU Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_ctrlpt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t const * p_evt_write) +{ + uint32_t err_code; + ble_dfu_rsp_code_t rsp_code = DFU_RSP_OPERATION_FAILED; - case OP_CODE_RECEIVE_FW: - ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_RECEIVE_APP_DATA; + ble_gatts_rw_authorize_reply_params_t write_authorize_reply; + memset(&write_authorize_reply, 0, sizeof(write_authorize_reply)); - p_dfu->evt_handler(p_dfu, &ble_dfu_evt); - break; + write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; - case OP_CODE_VALIDATE: - ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_VALIDATE; + if (p_dfu->is_ctrlpt_notification_enabled) + { + write_authorize_reply.params.write.update = 1; + write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + } + else + { + write_authorize_reply.params.write.gatt_status = DFU_RSP_CCCD_CONFIG_IMPROPER; + } - p_dfu->evt_handler(p_dfu, &ble_dfu_evt); - break; + // reply to the write authorization + do { + err_code = sd_ble_gatts_rw_authorize_reply(p_dfu->conn_handle, &write_authorize_reply); + } while (err_code == NRF_ERROR_BUSY); - case OP_CODE_ACTIVATE_N_RESET: - ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_ACTIVATE_N_RESET; - p_dfu->evt_handler(p_dfu, &ble_dfu_evt); - break; + if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS) + { + return; + } - case OP_CODE_SYS_RESET: - ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_SYS_RESET; + // Start executing the control point write action - p_dfu->evt_handler(p_dfu, &ble_dfu_evt); + switch (p_evt_write->data[0]) + { + case BLE_DFU_ENTER_BOOTLOADER: + rsp_code = DFU_RSP_SUCCESS; break; - case OP_CODE_PKT_RCPT_NOTIF_REQ: - if (p_ble_write_evt->len < PKT_RCPT_NOTIF_REQ_LEN) - { - return (ble_dfu_response_send(p_dfu, - BLE_DFU_PKT_RCPT_REQ_PROCEDURE, - BLE_DFU_RESP_VAL_NOT_SUPPORTED)); - } - - ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts = - uint16_decode(&(p_ble_write_evt->data[1])); - - if (ble_dfu_evt.evt.pkt_rcpt_notif_req.num_of_pkts == 0) - { - ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_DISABLED; - } - else - { - ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PKT_RCPT_NOTIF_ENABLED; - } - - p_dfu->evt_handler(p_dfu, &ble_dfu_evt); - + // Unrecognized Op Code + default: + rsp_code = DFU_RSP_OP_CODE_NOT_SUPPORTED; break; + } - case OP_CODE_IMAGE_SIZE_REQ: - ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_BYTES_RECEIVED_SEND; - - p_dfu->evt_handler(p_dfu, &ble_dfu_evt); - break; + resp_send(p_dfu, (ble_dfu_buttonless_op_code_t)p_evt_write->data[0], rsp_code); - default: - // Unsupported op code. - return ble_dfu_response_send(p_dfu, - (ble_dfu_procedure_t) p_ble_write_evt->data[0], - BLE_DFU_RESP_VAL_NOT_SUPPORTED); + if (rsp_code == BLE_DFU_ENTER_BOOTLOADER + && p_evt_write->data[0] == BLE_DFU_ENTER_BOOTLOADER) + { + enter_bootloader(p_dfu); } - return NRF_SUCCESS; } -/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the S110 - * Stack. +/**@brief Write authorization request event handler. * - * @param[in] p_dfu DFU Service Structure. - * @param[in] p_ble_evt Pointer to the event received from BLE stack. + * @details The write authorization request event handler is called when writing to the control point. + * + * @param[in] p_dfu DFU structure. + * @param[in] p_ble_evt Event received from the BLE stack. */ -static void on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) +static void on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt) { - ble_gatts_evt_rw_authorize_request_t * p_authorize_request; + if (p_ble_evt->evt.gatts_evt.conn_handle != p_dfu->conn_handle) + { + return; + } - p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request); + const ble_gatts_evt_rw_authorize_request_t * p_auth_req = + &p_ble_evt->evt.gatts_evt.params.authorize_request; if ( - (p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && - (p_authorize_request->request.write.handle == p_dfu->dfu_ctrl_pt_handles.value_handle) - && - (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) + (p_auth_req->request.write.handle == p_dfu->control_point_char.value_handle) && - (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + (p_auth_req->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) && - (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) + (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + && + (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) ) { - uint32_t err_code; - - err_code = on_ctrl_pt_write(p_dfu, &(p_authorize_request->request.write)); - - if (err_code != NRF_SUCCESS && p_dfu->error_handler != NULL) - { - p_dfu->error_handler(err_code); - } + on_ctrlpt_write(p_dfu, &p_auth_req->request.write); } -} +} -/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the S110 SoftDevice. +/**@brief Connect event handler. * - * @param[in] p_dfu DFU Service Structure. - * @param[in] p_ble_evt Pointer to the event received from BLE stack. + * @param[in] p_dfu DFU Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. */ -static void on_write(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) +static void on_connect(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt) { - if (p_ble_evt->evt.gatts_evt.params.write.handle == p_dfu->dfu_pkt_handles.value_handle) - { - // DFU Packet written - - ble_dfu_evt_t ble_dfu_evt; - - ble_dfu_evt.ble_dfu_evt_type = BLE_DFU_PACKET_WRITE; - ble_dfu_evt.evt.ble_dfu_pkt_write.len = p_ble_evt->evt.gatts_evt.params.write.len; - ble_dfu_evt.evt.ble_dfu_pkt_write.p_data = p_ble_evt->evt.gatts_evt.params.write.data; - - p_dfu->evt_handler(p_dfu, &ble_dfu_evt); - } + p_dfu->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; } -/**@brief Function for handling the BLE_GAP_EVT_DISCONNECTED event from the S110 SoftDevice. +/**@brief Disconnect event handler. * - * @param[in] p_dfu DFU Service Structure. - * @param[in] p_ble_evt Pointer to the event received from BLE stack. + * @param[in] p_dfu DFU Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. */ -static void on_disconnect(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) -{ - p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID; -} - - -uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init) +static void on_disconnect(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt) { - if ((p_dfu == NULL) || (p_dfu_init == NULL) || (p_dfu_init->evt_handler == NULL)) + if (p_dfu->conn_handle != p_ble_evt->evt.gatts_evt.conn_handle) { - return NRF_ERROR_NULL; + return; } p_dfu->conn_handle = BLE_CONN_HANDLE_INVALID; - ble_uuid_t service_uuid; - uint32_t err_code; - - const ble_uuid128_t base_uuid128 = - { - { - 0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, - 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00 - } - }; - - service_uuid.uuid = BLE_DFU_SERVICE_UUID; - - err_code = sd_ble_uuid_vs_add(&base_uuid128, &(service_uuid.type)); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, - &service_uuid, - &(p_dfu->service_handle)); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - p_dfu->uuid_type = service_uuid.type; - - err_code = dfu_pkt_char_add(p_dfu); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = dfu_ctrl_pt_add(p_dfu); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = dfu_rev_char_add(p_dfu, p_dfu_init); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - p_dfu->evt_handler = p_dfu_init->evt_handler; - - if (p_dfu_init->error_handler != NULL) + if (p_dfu->is_waiting_for_disconnection) { - p_dfu->error_handler = p_dfu_init->error_handler; + NVIC_SystemReset(); } - - m_is_dfu_service_initialized = true; - - return NRF_SUCCESS; } - -void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) +/**@brief Write event handler. + * + * @param[in] p_dfu DFU Service structure. + * @param[in] p_ble_evt Event received from the BLE stack.rtt + */ +static void on_write(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt) { - if ((p_dfu == NULL) || (p_ble_evt == NULL)) + const ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle != p_dfu->control_point_char.cccd_handle) { return; } - if (p_dfu->evt_handler != NULL) + if (p_evt_write->len == BLE_CCCD_VALUE_LEN) { - switch (p_ble_evt->header.evt_id) - { - case BLE_GAP_EVT_CONNECTED: - on_connect(p_dfu, p_ble_evt); - break; - - case BLE_GATTS_EVT_WRITE: - on_write(p_dfu, p_ble_evt); - break; + // CCCD written, update indications state + p_dfu->is_ctrlpt_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data); - case BLE_GAP_EVT_DISCONNECTED: - on_disconnect(p_dfu, p_ble_evt); - break; + if (p_dfu->evt_handler != NULL) + { + ble_dfu_evt_t evt; - case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: - on_rw_authorize_req(p_dfu, p_ble_evt); - break; + if (p_dfu->is_ctrlpt_notification_enabled) + { + evt.type = BLE_DFU_EVT_INDICATION_ENABLED;; + } + else + { + evt.type = BLE_DFU_EVT_INDICATION_DISABLED;; + } - default: - // No implementation needed. - break; + p_dfu->evt_handler(p_dfu, &evt); } } } -uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd) -{ - if (p_dfu == NULL) - { - return NRF_ERROR_NULL; - } - - if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized) - { - return NRF_ERROR_INVALID_STATE; - } - - ble_gatts_hvx_params_t hvx_params; - uint16_t index = 0; - - // Encode the Op Code. - m_notif_buffer[index++] = OP_CODE_RESPONSE; - - // Encode the Reqest Op Code. - m_notif_buffer[index++] = OP_CODE_IMAGE_SIZE_REQ; - - // Encode the Response Value. - m_notif_buffer[index++] = (uint8_t)BLE_DFU_RESP_VAL_SUCCESS; - - index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]); - - memset(&hvx_params, 0, sizeof(hvx_params)); - - hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle; - hvx_params.type = BLE_GATT_HVX_NOTIFICATION; - hvx_params.offset = 0; - hvx_params.p_len = &index; - hvx_params.p_data = m_notif_buffer; - - return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params); -} - - -uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd) +void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) { - if (p_dfu == NULL) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL_VOID(p_dfu); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); - if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized) + switch (p_ble_evt->header.evt_id) { - return NRF_ERROR_INVALID_STATE; - } - - ble_gatts_hvx_params_t hvx_params; - uint16_t index = 0; - - m_notif_buffer[index++] = OP_CODE_PKT_RCPT_NOTIF; - - index += uint32_encode(num_of_firmware_bytes_rcvd, &m_notif_buffer[index]); - - memset(&hvx_params, 0, sizeof(hvx_params)); - - hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle; - hvx_params.type = BLE_GATT_HVX_NOTIFICATION; - hvx_params.offset = 0; - hvx_params.p_len = &index; - hvx_params.p_data = m_notif_buffer; + case BLE_GAP_EVT_CONNECTED: + on_connect(p_dfu, p_ble_evt); + break; - return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params); -} + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_dfu, p_ble_evt); + break; + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_authorize_req(p_dfu, p_ble_evt); + break; -uint32_t ble_dfu_response_send(ble_dfu_t * p_dfu, - ble_dfu_procedure_t dfu_proc, - ble_dfu_resp_val_t resp_val) -{ - if (p_dfu == NULL) - { - return NRF_ERROR_NULL; - } + case BLE_GATTS_EVT_WRITE: + on_write(p_dfu, p_ble_evt); + break; - if ((p_dfu->conn_handle == BLE_CONN_HANDLE_INVALID) || !m_is_dfu_service_initialized) - { - return NRF_ERROR_INVALID_STATE; + default: + // no implementation + break; } - ble_gatts_hvx_params_t hvx_params; - uint16_t index = 0; - - m_notif_buffer[index++] = OP_CODE_RESPONSE; - - // Encode the Request Op code - m_notif_buffer[index++] = (uint8_t)dfu_proc; - - // Encode the Response Value. - m_notif_buffer[index++] = (uint8_t)resp_val; - - memset(&hvx_params, 0, sizeof(hvx_params)); - - hvx_params.handle = p_dfu->dfu_ctrl_pt_handles.value_handle; - hvx_params.type = BLE_GATT_HVX_NOTIFICATION; - hvx_params.offset = 0; - hvx_params.p_len = &index; - hvx_params.p_data = m_notif_buffer; - - return sd_ble_gatts_hvx(p_dfu->conn_handle, &hvx_params); } diff --git a/components/ble/ble_services/ble_dfu/ble_dfu.h b/components/ble/ble_services/ble_dfu/ble_dfu.h index e63fe66..e58dae6 100644 --- a/components/ble/ble_services/ble_dfu/ble_dfu.h +++ b/components/ble/ble_services/ble_dfu/ble_dfu.h @@ -1,239 +1,154 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 +/** @file * - * @defgroup ble_sdk_srv_dfu Device Firmware Update Service + * @defgroup ble_dfu Buttonless DFU Service * @{ - * @ingroup ble_sdk_srv - * @brief Device Firmware Update Service + * @ingroup ble_sdk_srv + * @brief Buttonless DFU Service module. + * + * @details * - * @details The Device Firmware Update (DFU) service is a GATT based service that can be used for - * performing firmware updates over BLE. Note that this implementation uses vendor - * specific UUIDs for service and characteristics and is intended to demonstrate the - * firmware updates over BLE. Refer @ref bledfu_transport_bleservice and @ref - * bledfu_transport_bleprofile for more information on the service and profile respectively. + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * qualification listings, this section of source code must not be modified. */ #ifndef BLE_DFU_H__ #define BLE_DFU_H__ #include -#include "ble_gatts.h" -#include "ble_gap.h" -#include "ble.h" #include "ble_srv_common.h" -#define BLE_DFU_SERVICE_UUID 0x1530 /**< The UUID of the DFU Service. */ -#define BLE_DFU_PKT_CHAR_UUID 0x1532 /**< The UUID of the DFU Packet Characteristic. */ -#define BLE_DFU_CTRL_PT_UUID 0x1531 /**< The UUID of the DFU Control Point. */ -#define BLE_DFU_STATUS_REP_UUID 0x1533 /**< The UUID of the DFU Status Report Characteristic. */ -#define BLE_DFU_REV_CHAR_UUID 0x1534 /**< The UUID of the DFU Revision Characteristic. */ +#ifdef __cplusplus +extern "C" { +#endif -/**@brief DFU Event type. - * - * @details This enumeration contains the types of events that will be received from the DFU Service. - */ -typedef enum -{ - BLE_DFU_START, /**< The event indicating that the peer wants the application to prepare for a new firmware update. */ - BLE_DFU_RECEIVE_INIT_DATA, /**< The event indicating that the peer wants the application to prepare to receive init parameters. */ - BLE_DFU_RECEIVE_APP_DATA, /**< The event indicating that the peer wants the application to prepare to receive the new firmware image. */ - BLE_DFU_VALIDATE, /**< The event indicating that the peer wants the application to validate the newly received firmware image. */ - BLE_DFU_ACTIVATE_N_RESET, /**< The event indicating that the peer wants the application to undergo activate new firmware and restart with new valid application */ - BLE_DFU_SYS_RESET, /**< The event indicating that the peer wants the application to undergo a reset and start the currently valid application image.*/ - BLE_DFU_PKT_RCPT_NOTIF_ENABLED, /**< The event indicating that the peer has enabled packet receipt notifications. It is the responsibility of the application to call @ref ble_dfu_pkts_rcpt_notify each time the number of packets indicated by num_of_pkts field in @ref ble_dfu_evt_t is received.*/ - BLE_DFU_PKT_RCPT_NOTIF_DISABLED, /**< The event indicating that the peer has disabled the packet receipt notifications.*/ - BLE_DFU_PACKET_WRITE, /**< The event indicating that the peer has written a value to the 'DFU Packet' characteristic. The data received from the peer will be present in the @ref BLE_DFU_PACKET_WRITE element contained within @ref ble_dfu_evt_t.*/ - BLE_DFU_BYTES_RECEIVED_SEND /**< The event indicating that the peer is requesting for the number of bytes of firmware data last received by the application. It is the responsibility of the application to call @ref ble_dfu_pkts_rcpt_notify in response to this event. */ +#define BLE_UUID_DFU_SERVICE 0x0001 +#define BLE_DFU_BASE_UUID {{0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F, 0x60, 0x4F, 0x15, 0xF3, 0x00, 0x00, 0x40, 0x8E}} /**< Used vendor specific UUID. */ + +#define BLE_DFU_ENTER_BOOTLOADER 0x01 + +typedef enum { + BLE_DFU_EVT_ENTERING_BOOTLOADER, /**< Event indicating that the bootloader will be entered after return of this event.*/ + BLE_DFU_EVT_INDICATION_ENABLED, /**< Indication that the control point is enabled.*/ + BLE_DFU_EVT_INDICATION_DISABLED /**< Indication that the control point is disabled.*/ } ble_dfu_evt_type_t; -/**@brief DFU Procedure type. - * - * @details This enumeration contains the types of DFU procedures. - */ +typedef struct { + ble_dfu_evt_type_t type; +} ble_dfu_evt_t; +/* Forward declaration of the ble_nus_t type. */ +typedef struct ble_dfu_s ble_dfu_t; + +/**@brief Nordic UART Service event handler type. */ +typedef void (*ble_dfu_evt_handler_t) (ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt); + + + +// Control Point response values typedef enum { - BLE_DFU_START_PROCEDURE = 1, /**< DFU Start procedure.*/ - BLE_DFU_INIT_PROCEDURE = 2, /**< DFU Initialization procedure.*/ - BLE_DFU_RECEIVE_APP_PROCEDURE = 3, /**< Firmware receiving procedure.*/ - BLE_DFU_VALIDATE_PROCEDURE = 4, /**< Firmware image validation procedure .*/ - BLE_DFU_PKT_RCPT_REQ_PROCEDURE = 8 /**< Packet receipt notification request procedure. */ -} ble_dfu_procedure_t; - -/**@brief DFU Response value type. - */ + DFU_RSP_RESERVED = 0x00, /**< Reserved for future use. */ + DFU_RSP_SUCCESS = 0x01, /**< Success. */ + DFU_RSP_OP_CODE_NOT_SUPPORTED = 0x02, /**< Op Code not supported. */ + DFU_RSP_OPERATION_FAILED = 0x04, /**< Operation Failed. */ + DFU_RSP_CCCD_CONFIG_IMPROPER = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR /**< CCCD is improperly configured. */ +} ble_dfu_rsp_code_t; + +// Control Point Op Code values typedef enum { - BLE_DFU_RESP_VAL_SUCCESS = 1, /**< Success.*/ - BLE_DFU_RESP_VAL_INVALID_STATE, /**< Invalid state.*/ - BLE_DFU_RESP_VAL_NOT_SUPPORTED, /**< Operation not supported.*/ - BLE_DFU_RESP_VAL_DATA_SIZE, /**< Data size exceeds limit.*/ - BLE_DFU_RESP_VAL_CRC_ERROR, /**< CRC Error.*/ - BLE_DFU_RESP_VAL_OPER_FAILED /**< Operation failed.*/ -} ble_dfu_resp_val_t; + DFU_OP_RESERVED = 0x00, /**< Reserved for future use. */ + DFU_OP_ENTER_BOOTLOADER = 0x01, /**< Enter bootloader. */ + DFU_OP_RESPONSE_CODE = 0x20 /**< Response code. */ +} ble_dfu_buttonless_op_code_t; -/**@brief DFU Packet structure. - * - * @details This structure contains the value of the DFU Packet characteristic as written by the - * peer and the length of the value written. It will be filled by the DFU Service when the - * peer writes to the DFU Packet characteristic. - */ -typedef struct -{ - uint8_t * p_data; /**< Pointer to the received packet. This will point to a word aligned memory location.*/ - uint8_t len; /**< Length of the packet received. */ -} ble_dfu_pkt_write_t; -/**@brief Packet receipt notification request structure. - * - * @details This structure contains the contents of the packet receipt notification request - * sent by the DFU Controller. - */ -typedef struct -{ - uint16_t num_of_pkts; /**< The number of packets of firmware data to be received by application before sending the next Packet Receipt Notification to the peer. */ -} ble_pkt_rcpt_notif_req_t; +struct ble_dfu_s { + uint8_t uuid_type; /**< UUID type for DFU UUID. */ + uint16_t service_handle; /**< Handle of DFU (as provided by the SoftDevice). */ + uint16_t conn_handle; + ble_gatts_char_handles_t control_point_char; /**< Handles related to the DFU Control Point characteristic. */ + bool is_ctrlpt_notification_enabled; -/**@brief DFU Event structure. - * - * @details This structure contains the event generated by the DFU Service based on the data - * received from the peer. - */ -typedef struct -{ - ble_dfu_evt_type_t ble_dfu_evt_type; /**< Type of the event.*/ - union - { - ble_dfu_pkt_write_t ble_dfu_pkt_write; /**< The DFU packet received. This field is when the @ref ble_dfu_evt_type field is set to @ref BLE_DFU_PACKET_WRITE.*/ - ble_pkt_rcpt_notif_req_t pkt_rcpt_notif_req; /**< Packet receipt notification request. This field is when the @ref ble_dfu_evt_type field is set to @ref BLE_DFU_PKT_RCPT_NOTIF_ENABLED.*/ - } evt; -} ble_dfu_evt_t; - -// Forward declaration of the ble_dfu_t type. -typedef struct ble_dfu_s ble_dfu_t; + ble_dfu_evt_handler_t evt_handler; /**< Event handler which is called right before. */ -/**@brief DFU Service event handler type. */ -typedef void (*ble_dfu_evt_handler_t) (ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt); - -/**@brief DFU service structure. - * - * @details This structure contains status information related to the service. - */ -struct ble_dfu_s -{ - uint16_t conn_handle; /**< Handle of the current connection (as provided by the S110 SoftDevice). This will be BLE_CONN_HANDLE_INVALID when not in a connection. */ - uint16_t revision; /**< Handle of DFU Service (as provided by the S110 SoftDevice). */ - uint16_t service_handle; /**< Handle of DFU Service (as provided by the S110 SoftDevice). */ - uint8_t uuid_type; /**< UUID type assigned for DFU Service by the S110 SoftDevice. */ - ble_gatts_char_handles_t dfu_pkt_handles; /**< Handles related to the DFU Packet characteristic. */ - ble_gatts_char_handles_t dfu_ctrl_pt_handles; /**< Handles related to the DFU Control Point characteristic. */ - ble_gatts_char_handles_t dfu_status_rep_handles; /**< Handles related to the DFU Status Report characteristic. */ - ble_gatts_char_handles_t dfu_rev_handles; /**< Handles related to the DFU Revision characteristic. */ - ble_dfu_evt_handler_t evt_handler; /**< The event handler to be called when an event is to be sent to the application.*/ - ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + bool is_waiting_for_disconnection; }; -/**@brief DFU service initialization structure. - * - * @details This structure contains the initialization information for the DFU Service. The - * application needs to fill this structure and pass it to the DFU Service using the - * @ref ble_dfu_init function. - */ -typedef struct -{ - uint16_t revision; /**< Revision number to be exposed by the DFU service. */ - ble_dfu_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Device Firmware Update Service. */ - ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ +typedef struct { + ble_dfu_evt_handler_t evt_handler; /**< Event handler which is called right before. */ + security_req_t ctrl_point_security_req_write_perm; /**< Read security level of the LN Control Point characteristic. */ + security_req_t ctrl_point_security_req_cccd_write_perm; /**< CCCD write security level of the LN Control Point characteristic. */ } ble_dfu_init_t; -/**@brief Function for handling a BLE event. - * - * @details The DFU service expects the application to call this function each time an event - * is received from the S110 SoftDevice. This function processes the event, if it is - * relevant for the DFU service and calls the DFU event handler of the application if - * necessary. - * - * @param[in] p_dfu Pointer to the DFU service structure. - * @param[in] p_ble_evt Pointer to the event received from S110 SoftDevice. - */ -void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt); -/**@brief Function for initializing the DFU service. +/**@brief Function for initializing the Device Firmware Update module * - * @param[out] p_dfu Device Firmware Update service structure. This structure will have to be - * supplied by the application. It will be initialized by this function, - * and will later be used to identify the service instance. - * @param[in] p_dfu_init Information needed to initialize the service. * - * @return NRF_SUCCESS if the DFU service and its characteristics were successfully added to the - * S110 SoftDevice. Otherwise an error code. - * This function returns NRF_ERROR_NULL if the value of evt_handler in p_dfu_init - * structure provided is NULL or if the pointers supplied as input are NULL. - */ -uint32_t ble_dfu_init(ble_dfu_t * p_dfu, ble_dfu_init_t * p_dfu_init); - -/**@brief Function for sending response to a control point command. + * @param[in] p_dfu DFU Service structure. + * @param[in] p_dfu_init The structure containing the values of characteristics needed by the + * service. * - * @details This function will encode a DFU Control Point response using the given input - * parameters and will send a notification of the same to the peer. - * - * @param[in] p_dfu Pointer to the DFU service structure. - * @param[in] dfu_proc Procedure for which this response is to be sent. - * @param[in] resp_val Response value. - * - * @return NRF_SUCCESS if the DFU Service has successfully requested the S110 SoftDevice to - * send the notification. Otherwise an error code. - * This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a - * peer or if the DFU service is not initialized or if the notification of the DFU - * Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL - * if the pointer p_dfu is NULL. + * @return NRF_SUCCESS on successful initialization of service. */ -uint32_t ble_dfu_response_send(ble_dfu_t * p_dfu, - ble_dfu_procedure_t dfu_proc, - ble_dfu_resp_val_t resp_val); +uint32_t ble_dfu_init(ble_dfu_t * p_dfu, const ble_dfu_init_t * p_dfu_init); -/**@brief Function for notifying the peer about the number of bytes of firmware data received. - * - * @param[in] p_dfu Pointer to the DFU service structure. - * @param[in] num_of_firmware_bytes_rcvd Number of bytes. - * - * @return NRF_SUCCESS if the DFU Service has successfully requested the S110 SoftDevice to send - * the notification. Otherwise an error code. - * This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a - * peer or if the DFU service is not initialized or if the notification of the DFU - * Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL - * if the pointer p_dfu is NULL. - */ -uint32_t ble_dfu_bytes_rcvd_report(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd); -/**@brief Function for sending Packet Receipt Notification to the peer. - * - * This function will encode the number of bytes received as input parameter into a - * notification of the control point characteristic and send it to the peer. +/**@brief Function for handling the Application's BLE Stack events. * - * @param[in] p_dfu Pointer to the DFU service structure. - * @param[in] num_of_firmware_bytes_rcvd Number of bytes of firmware image received. + * @details Handles all events from the BLE stack of interest to the Battery Service. * - * @return NRF_SUCCESS if the DFU Service has successfully requested the S110 SoftDevice to send - * the notification. Otherwise an error code. - * This function returns NRF_ERROR_INVALID_STATE if the device is not connected to a - * peer or if the DFU service is not initialized or if the notification of the DFU - * Status Report characteristic was not enabled by the peer. It returns NRF_ERROR_NULL - * if the pointer p_dfu is NULL. + * @param[in] p_dfu DFU Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. */ -uint32_t ble_dfu_pkts_rcpt_notify(ble_dfu_t * p_dfu, uint32_t num_of_firmware_bytes_rcvd); +void ble_dfu_on_ble_evt(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt); + + +#ifdef __cplusplus +} +#endif -#endif // BLE_DFU_H__ +#endif // BLE_DIS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_dis/ble_dis.c b/components/ble/ble_services/ble_dis/ble_dis.c index 72abc58..f35edd2 100644 --- a/components/ble/ble_services/ble_dis/ble_dis.c +++ b/components/ble/ble_services/ble_dis/ble_dis.c @@ -1,29 +1,56 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_DIS) #include "ble_dis.h" #include #include #include "app_error.h" #include "ble_gatts.h" -#include "nordic_common.h" #include "ble_srv_common.h" -#include "app_util.h" #define BLE_DIS_SYS_ID_LEN 8 /**< Length of System ID Characteristic Value. */ @@ -275,3 +302,4 @@ uint32_t ble_dis_init(const ble_dis_init_t * p_dis_init) return NRF_SUCCESS; } +#endif // NRF_MODULE_ENABLED(BLE_DIS) diff --git a/components/ble/ble_services/ble_dis/ble_dis.h b/components/ble/ble_services/ble_dis/ble_dis.h index 603c611..ad2d768 100644 --- a/components/ble/ble_services/ble_dis/ble_dis.h +++ b/components/ble/ble_services/ble_dis/ble_dis.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_dis Device Information Service + * @defgroup ble_dis Device Information Service * @{ * @ingroup ble_sdk_srv * @brief Device Information Service module. @@ -21,8 +49,8 @@ * During initialization it adds the Device Information Service to the BLE stack database. * It then encodes the supplied information, and adds the curresponding characteristics. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -32,7 +60,11 @@ #include #include "ble_srv_common.h" -/** @defgroup DIS_VENDOR_ID_SRC_VALUES Vendor ID Source values +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup DIS_VENDOR_ID_SRC_VALUES Vendor ID Source values * @{ */ #define BLE_DIS_VENDOR_ID_SRC_BLUETOOTH_SIG 1 /**< Vendor ID assigned by Bluetooth SIG. */ @@ -62,7 +94,7 @@ typedef struct uint16_t product_version; /**< Product Version. */ } ble_dis_pnp_id_t; -/**@brief Device Information Service init structure. This contains all possible characteristics +/**@brief Device Information Service init structure. This contains all possible characteristics * needed for initialization of the service. */ typedef struct @@ -81,7 +113,7 @@ typedef struct /**@brief Function for initializing the Device Information Service. * - * @details This call allows the application to initialize the device information service. + * @details This call allows the application to initialize the device information service. * It adds the DIS service and DIS characteristics to the database, using the initial * values supplied through the p_dis_init parameter. Characteristics which are not to be * added, shall be set to NULL in p_dis_init. @@ -93,6 +125,11 @@ typedef struct */ uint32_t ble_dis_init(const ble_dis_init_t * p_dis_init); + +#ifdef __cplusplus +} +#endif + #endif // BLE_DIS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_escs/escs_defs.h b/components/ble/ble_services/ble_escs/escs_defs.h new file mode 100644 index 0000000..e342526 --- /dev/null +++ b/components/ble/ble_services/ble_escs/escs_defs.h @@ -0,0 +1,134 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ESCS_DEFS_H__ +#define ESCS_DEFS_H__ + +#include "es.h" + +/*@file Contains definitions specific to the Eddystone Configuration Service */ + +#define ESCS_LOCK_STATE_NEW_LOCK_CODE_WRITE_LENGTH 17 + +#define ESCS_UID_READ_LENGTH (ES_UID_LENGTH) +#define ESCS_UID_WRITE_LENGTH (ES_UID_NAMESPACE_LENGTH + \ + ES_UID_INSTANCE_LENGTH + ES_FRAME_TYPE_LENGTH) + +#define ESCS_TLM_READ_LENGTH (ESCS_TLM_READ_LENGTH) +#define ESCS_TLM_WRITE_LENGTH (ES_FRAME_TYPE_LENGTH) + +#define ESCS_EID_READ_LENGTH (14) +#define ESCS_EID_WRITE_ECDH_LENGTH (34) +#define ESCS_EID_WRITE_PUB_KEY_INDEX (1) +#define ESCS_EID_WRITE_ENC_ID_KEY_INDEX (1) +#define ESCS_EID_WRITE_IDK_LENGTH (18) + +#define ESCS_URL_MIN_WRITE_LENGTH (4) +#define ESCS_URL_WRITE_LENGTH (19) + +#ifdef NRF52 +#define ESCS_NUM_OF_SUPPORTED_TX_POWER (9) +/**@brief TX power levels, based on nRF52 specifications. */ +#define ESCS_SUPPORTED_TX_POWER {-40, -20, -16, -12, -8, -4, 0, 3, 4} +#elif NRF51 +/**@brief TX power levels, based on nRF51 specifications. */ +#define ESCS_NUM_OF_SUPPORTED_TX_POWER (8) +#define ESCS_SUPPORTED_TX_POWER {-30, -20, -16, -12, -8, -4, 0, 4} +#else +#error MISSING TX POWER +#endif + +// Defined in Eddystone Specifications +#define ESCS_AES_KEY_SIZE (16) +#define ESCS_ECDH_KEY_SIZE (32) + +#define ESCS_ADV_SLOT_CHAR_LENGTH_MAX (34) // Corresponds to when the slots is configured as an EID slot + +// Characteristic: Broadcast Capabilities + +// Field: nrf_ble_escs_init_params_t.broadcast_cap.cap_bitfield +#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_Yes (1) // Set if the beacon supports individual per-slot adv intervals +#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_No (0) +#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_Pos (0) +#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_Msk (1 << ESCS_BROADCAST_VAR_ADV_SUPPORTED_Pos) +#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Yes (1) // Set if the beacon supports individual per-slot TX intervals +#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_No (0) +#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Pos (1) +#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Msk (1 << ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Pos) +#define ESCS_BROADCAST_VAR_RFU_MASK (0x03) // AND Mask to guarantee that bits 0x04 to 0x80 (RFU) are cleared + +// Field: nrf_ble_escs_init_params_t.broadcast_cap.supp_frame_types +#define ESCS_FRAME_TYPE_UID_SUPPORTED_Yes (1) +#define ESCS_FRAME_TYPE_UID_SUPPORTED_No (0) +#define ESCS_FRAME_TYPE_UID_SUPPORTED_Pos (0) +#define ESCS_FRAME_TYPE_UID_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_UID_SUPPORTED_Pos) + +#define ESCS_FRAME_TYPE_URL_SUPPORTED_Yes (1) +#define ESCS_FRAME_TYPE_URL_SUPPORTED_No (0) +#define ESCS_FRAME_TYPE_URL_SUPPORTED_Pos (1) +#define ESCS_FRAME_TYPE_URL_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_URL_SUPPORTED_Pos) + +#define ESCS_FRAME_TYPE_TLM_SUPPORTED_Yes (1) +#define ESCS_FRAME_TYPE_TLM_SUPPORTED_No (0) +#define ESCS_FRAME_TYPE_TLM_SUPPORTED_Pos (2) +#define ESCS_FRAME_TYPE_TLM_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_TLM_SUPPORTED_Pos) + +#define ESCS_FRAME_TYPE_EID_SUPPORTED_Yes (1) +#define ESCS_FRAME_TYPE_EID_SUPPORTED_No (0) +#define ESCS_FRAME_TYPE_EID_SUPPORTED_Pos (3) +#define ESCS_FRAME_TYPE_EID_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_EID_SUPPORTED_Pos) + +#define ESCS_FRAME_TYPE_RFU_MASK (0x000F) // AND Mask to guarantee that bits 0x0010 to 0x8000 (RFU) are cleared + +// Characteristic: Lock State: Lock State (READ) +#define ESCS_LOCK_STATE_LOCKED (0x00) +#define ESCS_LOCK_STATE_UNLOCKED (0x01) +#define ESCS_LOCK_STATE_UNLOCKED_AUTO_RELOCK_DISABLED (0x02) + +// Characteristic: Lock State: Lock Byte (WRITE) +#define ESCS_LOCK_BYTE_LOCK (0x00) +#define ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK (0x02) + + +// Charcteristic: Remain Connectable +#define ESCS_FUNCT_REMAIN_CONNECTABLE_SUPPORTED_Yes (0x01) +#define ESCS_FUNCT_REMAIN_CONNECTABLE_SUPPORTED_No (0x00) + +#endif // ESCS_DEFS_H__ diff --git a/components/ble/ble_services/ble_escs/nrf_ble_escs.c b/components/ble/ble_services/ble_escs/nrf_ble_escs.c new file mode 100644 index 0000000..da9afe0 --- /dev/null +++ b/components/ble/ble_services/ble_escs/nrf_ble_escs.c @@ -0,0 +1,661 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_ble_escs.h" +#include +#include "es_app_config.h" + +#ifdef BLE_HANDLER_DEBUG + #include "SEGGER_RTT.h" + #define DEBUG_PRINTF SEGGER_RTT_printf +#else + #define DEBUG_PRINTF(...) +#endif + +#define EID_BUFF_SIZE 64 + +typedef struct +{ + uint16_t uuid; + uint8_t read:1; + uint8_t write:1; + uint8_t rd_auth:1; + uint8_t wr_auth:1; + uint8_t vlen:1; + uint8_t vloc:2; + uint8_t init_len; + uint8_t max_len; +} char_init_t; + +typedef struct +{ + uint16_t val_handle; + uint16_t uuid; +} val_handle_to_uuid_t; + +static const char_init_t BROADCAST_CAP_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_BROADCAST_CAP_CHAR, + .read = 1, + .write = 0, + .rd_auth = 1, + .wr_auth = 0, + .vlen = 1, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = NRF_BLE_ESCS_BROADCAST_CAP_LEN, + .max_len = NRF_BLE_ESCS_BROADCAST_CAP_LEN +}; + +static const char_init_t ACTIVE_SLOT_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_ACTIVE_SLOT_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_USER, + .init_len = sizeof(nrf_ble_escs_active_slot_t), + .max_len = sizeof(nrf_ble_escs_active_slot_t) +}; + +static const char_init_t ADV_INTERVAL_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_ADV_INTERVAL_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = sizeof(nrf_ble_escs_adv_interval_t), + .max_len = sizeof(nrf_ble_escs_adv_interval_t) +}; + +static const char_init_t RADIO_TX_PWR_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_RADIO_TX_PWR_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = sizeof(nrf_ble_escs_radio_tx_pwr_t), + .max_len = sizeof(nrf_ble_escs_radio_tx_pwr_t) +}; + +static const char_init_t ADV_TX_PWR_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_ADV_TX_PWR_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = sizeof(nrf_ble_escs_adv_tx_pwr_t), + .max_len = sizeof(nrf_ble_escs_adv_tx_pwr_t) +}; + +static const char_init_t LOCK_STATE_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_LOCK_STATE_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 1, + .vloc = BLE_GATTS_VLOC_USER, + .init_len = 1, + .max_len = 17 +}; + +static const char_init_t UNLOCK_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_UNLOCK_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = 1, + .max_len = ESCS_AES_KEY_SIZE +}; + +static const char_init_t PUBLIC_ECDH_KEY_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_PUBLIC_ECDH_KEY_CHAR, + .read = 1, + .write = 0, + .rd_auth = 1, + .wr_auth = 0, + .vlen = 1, + .init_len = 1, + .vloc = BLE_GATTS_VLOC_STACK, + .max_len = ESCS_ECDH_KEY_SIZE +}; + +static const char_init_t EID_ID_KEY_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_EID_ID_KEY_CHAR, + .read = 1, + .write = 0, + .rd_auth = 1, + .wr_auth = 0, + .vlen = 1, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = 1, + .max_len = ESCS_AES_KEY_SIZE +}; + +static const char_init_t RW_ADV_SLOT_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_RW_ADV_SLOT_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 1, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = 0, + .max_len = ESCS_ADV_SLOT_CHAR_LENGTH_MAX +}; + +static const char_init_t FACTORY_RESET_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_FACTORY_RESET_CHAR, + .read = 0, + .write = 1, + .rd_auth = 0, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = sizeof(nrf_ble_escs_factory_reset_t), + .max_len = sizeof(nrf_ble_escs_factory_reset_t) +}; + +static const char_init_t REMAIN_CONNECTABLE_CHAR_INIT = +{ + .uuid = BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR, + .read = 1, + .write = 1, + .rd_auth = 1, + .wr_auth = 1, + .vlen = 0, + .vloc = BLE_GATTS_VLOC_STACK, + .init_len = 1, + .max_len = 1 +}; + +static val_handle_to_uuid_t m_handle_to_uuid_map[BLE_ESCS_NUMBER_OF_CHARACTERISTICS]; //!< Map from handle to UUID. +static uint8_t m_handle_to_uuid_map_idx = 0; //!< Index of map from handle to UUID. +static uint8_t m_eid_mem[EID_BUFF_SIZE] = {0}; //!< Memory buffer used for EID writes. +static ble_user_mem_block_t m_eid_mem_block = +{ + .p_mem = m_eid_mem, + .len = EID_BUFF_SIZE +}; //!< Memory block used for EID writes. + + + +/**@brief Function for adding characteristic to Eddystone service. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_escs_init Information needed to initialize the service. + * @param[in] p_char_init Information needed to initialize the characteristic. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t char_add(const char_init_t * p_char_init, + nrf_ble_escs_t * p_escs, + void * p_value, + ble_gatts_char_handles_t * p_handles) +{ + uint32_t err_code; + ble_gatts_char_md_t char_md; + ble_gatts_attr_t attr_char_value; + ble_uuid_t ble_uuid; + ble_gatts_attr_md_t attr_md; + + VERIFY_PARAM_NOT_NULL(p_char_init); + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_value); + VERIFY_PARAM_NOT_NULL(p_handles); + + memset(&char_md, 0, sizeof(char_md)); + memset(&attr_char_value, 0, sizeof(attr_char_value)); + memset(&ble_uuid, 0, sizeof(ble_uuid)); + memset(&attr_md, 0, sizeof(attr_md)); + + if(p_char_init->read) + { + char_md.char_props.read = 1; + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); + } + + else + { + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + } + + if(p_char_init->write) + { + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + char_md.char_props.write = 1; + } + + else + { + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm); + } + + ble_uuid.type = p_escs->uuid_type; + ble_uuid.uuid = p_char_init->uuid; + + attr_md.vloc = p_char_init->vloc; + attr_md.rd_auth = p_char_init->rd_auth; + attr_md.wr_auth = p_char_init->wr_auth; + attr_md.vlen = p_char_init->vlen; + + attr_char_value.p_uuid = &ble_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.init_len = p_char_init->init_len; + attr_char_value.p_value = p_value; + attr_char_value.max_len = p_char_init->max_len; + + err_code = sd_ble_gatts_characteristic_add(p_escs->service_handle, + &char_md, + &attr_char_value, + p_handles); + + if(err_code == NRF_SUCCESS) + { + ASSERT(m_handle_to_uuid_map_idx < BLE_ESCS_NUMBER_OF_CHARACTERISTICS); + m_handle_to_uuid_map[m_handle_to_uuid_map_idx].val_handle = p_handles->value_handle; + m_handle_to_uuid_map[m_handle_to_uuid_map_idx].uuid = p_char_init->uuid; + m_handle_to_uuid_map_idx++; + } + + return err_code; +} + + +/**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the SoftDevice. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_connect(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_escs); + p_escs->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; +} + + +/**@brief Function for handling the @ref BLE_GAP_EVT_DISCONNECTED event from the SoftDevice. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_disconnect(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_escs); + UNUSED_PARAMETER(p_ble_evt); + p_escs->conn_handle = BLE_CONN_HANDLE_INVALID; +} + + +static uint32_t get_evt_type_for_handle(uint16_t handle, uint16_t * p_uuid) +{ + VERIFY_PARAM_NOT_NULL(p_uuid); + + for(uint8_t i = 0; i < BLE_ESCS_NUMBER_OF_CHARACTERISTICS; ++i) + { + if(m_handle_to_uuid_map[i].val_handle == handle) + { + *p_uuid = m_handle_to_uuid_map[i].uuid; + return NRF_SUCCESS; + } + } + + return NRF_ERROR_NOT_FOUND; +} + +/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: BLE_GATTS_AUTHORIZE_TYPE_WRITE event from the SoftDevice. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static ret_code_t on_write(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + uint16_t write_evt_uuid = 0; + + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_ble_evt); + + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.authorize_request.request.write; + + err_code = get_evt_type_for_handle(p_evt_write->handle, &write_evt_uuid); + RETURN_IF_ERROR(err_code); + + p_escs->write_evt_handler(p_escs, + write_evt_uuid, + p_evt_write->handle, + p_evt_write->data, + p_evt_write->len); + + return NRF_SUCCESS; +} + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: BLE_GATTS_AUTHORIZE_TYPE_WRITE: event from the SoftDevice. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_long_write(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + static uint16_t write_evt_uuid; + static bool write_evt_uuid_set = false; + uint32_t err_code; + + VERIFY_PARAM_NOT_NULL_VOID(p_escs); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + + ble_gatts_evt_write_t * p_evt_write = + &p_ble_evt->evt.gatts_evt.params.authorize_request.request.write; + ble_gatts_rw_authorize_reply_params_t reply = {0}; + + if (p_evt_write->op == BLE_GATTS_OP_PREP_WRITE_REQ) + { + err_code = get_evt_type_for_handle(p_evt_write->handle, &write_evt_uuid); + APP_ERROR_CHECK(err_code); + + write_evt_uuid_set = true; + + reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + reply.params.write.update = 0; + reply.params.write.offset = 0; + reply.params.write.len = p_evt_write->len; + reply.params.write.p_data = NULL; + + err_code = sd_ble_gatts_rw_authorize_reply(p_escs->conn_handle, &reply); + APP_ERROR_CHECK(err_code); + } + + else if (p_evt_write->op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + { + uint8_t value_buffer[ESCS_ADV_SLOT_CHAR_LENGTH_MAX] = {0}; + ble_gatts_value_t value = + { + .len = sizeof(value_buffer), + .offset = 0, + .p_value = &(value_buffer[0]) + }; + + ASSERT(write_evt_uuid_set); + write_evt_uuid_set = false; + + reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + reply.params.write.update = 0; + reply.params.write.offset = 0; + reply.params.write.len = p_evt_write->len; + reply.params.write.p_data = NULL; + + err_code = sd_ble_gatts_rw_authorize_reply(p_escs->conn_handle, &reply); + APP_ERROR_CHECK(err_code); + + // Now that the value has been accepted using 'sd_ble_gatts_rw_authorize_reply', it can be found in the database. + err_code = sd_ble_gatts_value_get( p_escs->conn_handle, + p_escs->rw_adv_slot_handles.value_handle, + &value); + APP_ERROR_CHECK(err_code); + + p_escs->write_evt_handler(p_escs, + write_evt_uuid, + p_evt_write->handle, + value.p_value, + value.len); + } + else + { + } +} + + +/**@brief Function for handling events from the SoftDevice related to long writes. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static ret_code_t on_read(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_ble_evt); + ret_code_t err_code; + uint16_t read_evt_uuid = 0; + uint16_t val_handle = p_ble_evt->evt.gatts_evt.params.authorize_request.request.read.handle; + err_code = get_evt_type_for_handle(val_handle, &read_evt_uuid); + RETURN_IF_ERROR(err_code); + + p_escs->read_evt_handler(p_escs, read_evt_uuid, val_handle); + + return NRF_SUCCESS; +} + + +static ret_code_t on_rw_authorize_req(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + ret_code_t err_code; + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_ble_evt); + + ble_gatts_evt_rw_authorize_request_t *ar = &p_ble_evt->evt.gatts_evt.params.authorize_request; + if (ar->type == BLE_GATTS_AUTHORIZE_TYPE_READ) + { + err_code = on_read(p_escs, p_ble_evt); + RETURN_IF_ERROR(err_code); + } + else if (ar->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + if (ar->request.write.op == BLE_GATTS_OP_WRITE_REQ + || ar->request.write.op == BLE_GATTS_OP_WRITE_CMD) + { + err_code = on_write(p_escs, p_ble_evt); + RETURN_IF_ERROR(err_code); + } + + else if(ar->request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ + || ar->request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + { + on_long_write(p_escs, p_ble_evt); + } + else + { + } + } + else + { + return NRF_ERROR_INVALID_STATE; + } + + return NRF_SUCCESS; +} + + + +ret_code_t nrf_ble_escs_on_ble_evt(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt) +{ + ret_code_t err_code; + + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_ble_evt); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_escs, p_ble_evt); + + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_escs, p_ble_evt); + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + err_code = on_rw_authorize_req(p_escs, p_ble_evt); + VERIFY_SUCCESS(err_code); + break; + + // BLE_EVT_USER_MEM_REQUEST & BLE_EVT_USER_MEM_RELEASE are for long writes to the RW ADV slot characteristic + case BLE_EVT_USER_MEM_REQUEST: + err_code = sd_ble_user_mem_reply(p_escs->conn_handle, &m_eid_mem_block); + VERIFY_SUCCESS(err_code); + break; + + case BLE_EVT_USER_MEM_RELEASE: + break; + + default: + // No implementation needed. + break; + } + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_escs_init(nrf_ble_escs_t * p_escs, const nrf_ble_escs_init_t * p_escs_init) +{ + uint32_t err_code; + ble_uuid_t ble_uuid; + ble_uuid128_t ecs_base_uuid = ESCS_BASE_UUID; + uint8_t zero_val = 0; + + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_escs_init); + + // Initialize the service structure. + p_escs->conn_handle = BLE_CONN_HANDLE_INVALID; + p_escs->write_evt_handler = p_escs_init->write_evt_handler; + p_escs->read_evt_handler = p_escs_init->read_evt_handler; + + // Add a custom base UUID. + err_code = sd_ble_uuid_vs_add(&ecs_base_uuid, &p_escs->uuid_type); + VERIFY_SUCCESS(err_code); + + ble_uuid.type = p_escs->uuid_type; + ble_uuid.uuid = BLE_UUID_ESCS_SERVICE; + + // Add the service. + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_escs->service_handle); + VERIFY_SUCCESS(err_code); + + m_handle_to_uuid_map_idx = 0; + + // Set up initial values for characteristics + + // Eddystone spec requires big endian + nrf_ble_escs_broadcast_cap_t temp = p_escs_init->p_init_vals->broadcast_cap; + temp.supp_frame_types = BYTES_SWAP_16BIT(temp.supp_frame_types); + + nrf_ble_escs_adv_interval_t temp_interval = p_escs_init->p_init_vals->adv_interval; + temp_interval = BYTES_SWAP_16BIT(temp_interval); + + // Adding chracteristics + + err_code = char_add(&BROADCAST_CAP_CHAR_INIT, p_escs, + &temp, &p_escs->broadcast_cap_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&ACTIVE_SLOT_CHAR_INIT, p_escs, + p_escs->p_active_slot, &p_escs->active_slot_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&ADV_INTERVAL_CHAR_INIT, p_escs, + &temp_interval, &p_escs->adv_interval_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&RADIO_TX_PWR_CHAR_INIT, p_escs, + &(p_escs_init->p_init_vals->radio_tx_pwr), &p_escs->radio_tx_pwr_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&ADV_TX_PWR_CHAR_INIT, p_escs, + &(p_escs_init->p_init_vals->adv_tx_pwr), &p_escs->adv_tx_pwr_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&LOCK_STATE_CHAR_INIT, p_escs, + p_escs->p_lock_state, &p_escs->lock_state_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&UNLOCK_CHAR_INIT, p_escs, + &zero_val, &p_escs->unlock_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&PUBLIC_ECDH_KEY_CHAR_INIT, p_escs, + &zero_val, &p_escs->pub_ecdh_key_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&EID_ID_KEY_CHAR_INIT, p_escs, + &zero_val, &p_escs->eid_id_key_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&RW_ADV_SLOT_CHAR_INIT, p_escs, + &zero_val, &p_escs->rw_adv_slot_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&FACTORY_RESET_CHAR_INIT, p_escs, + &(p_escs_init->p_init_vals->factory_reset), &p_escs->factory_reset_handles); + VERIFY_SUCCESS(err_code); + + err_code = char_add(&REMAIN_CONNECTABLE_CHAR_INIT, p_escs, + &(p_escs_init->p_init_vals->remain_connectable.r_is_non_connectable_supported), + &p_escs->remain_connectable_handles); + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} diff --git a/components/ble/ble_services/ble_escs/nrf_ble_escs.h b/components/ble/ble_services/ble_escs/nrf_ble_escs.h new file mode 100644 index 0000000..0965383 --- /dev/null +++ b/components/ble/ble_services/ble_escs/nrf_ble_escs.h @@ -0,0 +1,262 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_BLE_ESCS_H__ +#define NRF_BLE_ESCS_H__ + +#include "ble.h" +#include "ble_srv_common.h" +#include "app_util_platform.h" +#include "sdk_common.h" +#include "escs_defs.h" +#include +#include + + +/** + * @file + * @defgroup nrf_ble_escs Eddystone Configuration Service + * @brief Eddystone Configuration Service module. + * @ingroup ble_sdk_srv + * @{ + */ + +#define BLE_ESCS_NUMBER_OF_CHARACTERISTICS 13 //!< Number of characteristics contained in the Eddystone Configuration Service. + +#define BLE_UUID_ESCS_SERVICE 0x7500 //!< UUID of the Eddystone Configuration Service. + +// ECS UUIDs +#define BLE_UUID_ESCS_BROADCAST_CAP_CHAR 0x7501 +#define BLE_UUID_ESCS_ACTIVE_SLOT_CHAR 0x7502 +#define BLE_UUID_ESCS_ADV_INTERVAL_CHAR 0x7503 +#define BLE_UUID_ESCS_RADIO_TX_PWR_CHAR 0x7504 +#define BLE_UUID_ESCS_ADV_TX_PWR_CHAR 0x7505 +#define BLE_UUID_ESCS_LOCK_STATE_CHAR 0x7506 +#define BLE_UUID_ESCS_UNLOCK_CHAR 0x7507 +#define BLE_UUID_ESCS_PUBLIC_ECDH_KEY_CHAR 0x7508 +#define BLE_UUID_ESCS_EID_ID_KEY_CHAR 0x7509 +#define BLE_UUID_ESCS_RW_ADV_SLOT_CHAR 0x750A +#define BLE_UUID_ESCS_FACTORY_RESET_CHAR 0x750B +#define BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR 0x750C + +#define ESCS_BASE_UUID \ + {{0x95, 0xE2, 0xED, 0xEB, 0x1B, 0xA0, 0x39, 0x8A, 0xDF, 0x4B, 0xD3, 0x8E, 0x00, 0x00, 0xC8, \ + 0xA3}} +// A3C8XXXX-8ED3-4BDF-8A39-A01BEBEDE295 + +#define NRF_BLE_ESCS_BROADCAST_CAP_LEN (ESCS_NUM_OF_SUPPORTED_TX_POWER + 6) // According to the eddystone spec, there are 6 bytes of data in addition to the supported_radio_tx_power array + + +/**@brief Data fields in the Broadcast Capabilities characteristic. + * @note This is a packed structure. Therefore, you should not change it. + */ +typedef PACKED_STRUCT +{ + int8_t vers_byte; + int8_t max_supp_total_slots; + int8_t max_supp_eid_slots; + int8_t cap_bitfield; + int16_t supp_frame_types; + int8_t supp_radio_tx_power[ESCS_NUM_OF_SUPPORTED_TX_POWER]; +} nrf_ble_escs_broadcast_cap_t; + +typedef uint8_t nrf_ble_escs_active_slot_t; +typedef uint16_t nrf_ble_escs_adv_interval_t; +typedef int8_t nrf_ble_escs_radio_tx_pwr_t; +typedef int8_t nrf_ble_escs_adv_tx_pwr_t; + +/**@brief Read states of the Lock State characteristic. */ +typedef enum +{ + NRF_BLE_ESCS_LOCK_STATE_LOCKED = ESCS_LOCK_STATE_LOCKED, + NRF_BLE_ESCS_LOCK_STATE_UNLOCKED = ESCS_LOCK_STATE_UNLOCKED, + NRF_BLE_ESCS_LOCK_STATE_UNLOCKED_AUTO_RELOCK_DISABLED = + ESCS_LOCK_STATE_UNLOCKED_AUTO_RELOCK_DISABLED +} nrf_ble_escs_lock_state_read_t; + +/**@brief Write bytes of the Lock State characteristic. */ +typedef enum +{ + NRF_BLE_ESCS_LOCK_BYTE_LOCK = ESCS_LOCK_BYTE_LOCK, + NRF_BLE_ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK = ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK +} nrf_ble_escs_lock_byte_t; + +/**@brief Write data fields of the Lock State characteristic. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + nrf_ble_escs_lock_byte_t lock_byte; + int8_t encrypted_key[ESCS_AES_KEY_SIZE]; +} nrf_ble_escs_lock_state_write_t; + +/**@brief Lock State characteristic. */ +typedef union +{ + nrf_ble_escs_lock_state_read_t read; + nrf_ble_escs_lock_state_write_t write; +} nrf_ble_escs_lock_state_t; + +/**@brief Unlock characteristic (read/write). */ +typedef union +{ + int8_t r_challenge[ESCS_AES_KEY_SIZE]; + int8_t w_unlock_token[ESCS_AES_KEY_SIZE]; +} nrf_ble_escs_unlock_t; + +/**@brief Public ECDH Key characteristic. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + int8_t key[ESCS_ECDH_KEY_SIZE]; +} nrf_ble_escs_public_ecdh_key_t; + +/**@brief EID Identity Key characteristic. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + int8_t key[ESCS_AES_KEY_SIZE]; +} nrf_ble_escs_eid_id_key_t; + + +typedef uint8_t nrf_ble_escs_factory_reset_t; + +/**@brief Unlock characteristic (read/write). */ +typedef union +{ + uint8_t r_is_non_connectable_supported; + uint8_t w_remain_connectable_boolean; +} nrf_ble_escs_remain_conntbl_t; + +/**@brief Eddystone Configuration Service initialization parameters (corresponding to required characteristics). */ +typedef struct +{ + nrf_ble_escs_broadcast_cap_t broadcast_cap; + nrf_ble_escs_adv_interval_t adv_interval; + nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr; + nrf_ble_escs_adv_tx_pwr_t adv_tx_pwr; + nrf_ble_escs_factory_reset_t factory_reset; + nrf_ble_escs_remain_conntbl_t remain_connectable; + + +} nrf_ble_escs_init_params_t; + +// Forward Declaration of nrf_ble_escs_t type. +typedef struct nrf_ble_escs_s nrf_ble_escs_t; + +typedef void (*nrf_ble_escs_write_evt_handler_t)(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t value_handle, + uint8_t * p_data, + uint16_t length); + +typedef void (*nrf_ble_escs_read_evt_handler_t)(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t value_handle + ); + +/**@brief Eddystone Configuration Service initialization structure. + * + * @details This structure contains the initialization information for the service. The application + * must fill this structure and pass it to the service using the @ref nrf_ble_escs_init + * function. + */ +typedef struct +{ + nrf_ble_escs_init_params_t * p_init_vals; //!< Initialization parameters for the service. + nrf_ble_escs_write_evt_handler_t write_evt_handler; //!< Event handler to be called for authorizing write requests. + nrf_ble_escs_read_evt_handler_t read_evt_handler; //!< Event handler to be called for authorizing read requests. +} nrf_ble_escs_init_t; + +struct nrf_ble_escs_s +{ + uint8_t uuid_type; //!< UUID type for the Eddystone Configuration Service Base UUID. + uint16_t service_handle; //!< Handle of the Eddystone Configuration Service (as provided by the SoftDevice). + ble_gatts_char_handles_t broadcast_cap_handles; //!< Handles related to the Capabilities characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t active_slot_handles; //!< Handles related to the Active Slot characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t adv_interval_handles; //!< Handles related to the Advertising Interval characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t radio_tx_pwr_handles; //!< Handles related to the Radio Tx Power characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t adv_tx_pwr_handles; //!< Handles related to the (Advanced) Advertised Tx Power characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t lock_state_handles; //!< Handles related to the Lock State characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t unlock_handles; //!< Handles related to the Unlock characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t pub_ecdh_key_handles; //!< Handles related to the Public ECDH Key characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t eid_id_key_handles; //!< Handles related to the EID Identity Key characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t rw_adv_slot_handles; //!< Handles related to the ADV Slot Data characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t factory_reset_handles; //!< Handles related to the (Advanced) Factory reset characteristic (as provided by the SoftDevice). + ble_gatts_char_handles_t remain_connectable_handles; //!< Handles related to the (Advanced) Remain Connectable characteristic (as provided by the SoftDevice). + uint16_t conn_handle; //!< Handle of the current connection (as provided by the SoftDevice). @ref BLE_CONN_HANDLE_INVALID if not in a connection. + nrf_ble_escs_write_evt_handler_t write_evt_handler; //!< Event handler to be called for handling write attempts. + nrf_ble_escs_read_evt_handler_t read_evt_handler; //!< Event handler to be called for handling read attempts. + uint8_t * p_active_slot; + nrf_ble_escs_lock_state_read_t * p_lock_state; +}; + +/**@brief Function for initializing the Eddystone Configuration Service. + * + * @param[out] p_escs Eddystone Configuration Service structure. This structure must be supplied + * by the application. It is initialized by this function and will + * later be used to identify this particular service instance. + * @param[in] p_ecs_init Information needed to initialize the service. + * + * @retval NRF_SUCCESS If the service was successfully initialized. Otherwise, an error code is returned. + * @retval NRF_ERROR_NULL If either of the pointers @p p_escs or @p p_ecs_init is NULL. + */ +ret_code_t nrf_ble_escs_init(nrf_ble_escs_t * p_escs, const nrf_ble_escs_init_t * p_ecs_init); + +/**@brief Function for handling the Eddystone Configuration Service's BLE events. + * + * @details The Eddystone Configuration Service expects the application to call this function each time an + * event is received from the SoftDevice. This function processes the event if it + * is relevant and calls the Eddystone Configuration Service event handler of the + * application if necessary. + * + * @param[in] p_escs Eddystone Configuration Service structure. + * @param[in] p_ble_evt Event received from the SoftDevice. + * + * @retval NRF_ERROR_NULL If any of the arguments given are NULL. + * @retval NRF_SUCCESS otherwise. + */ +ret_code_t nrf_ble_escs_on_ble_evt(nrf_ble_escs_t * p_escs, ble_evt_t * p_ble_evt); + +/** @} */ + +#endif // NRF_BLE_ESCS_H__ diff --git a/components/ble/ble_services/ble_gls/ble_gls.c b/components/ble/ble_services/ble_gls/ble_gls.c index 4cd30d1..8e0090a 100644 --- a/components/ble/ble_services/ble_gls/ble_gls.c +++ b/components/ble/ble_services/ble_gls/ble_gls.c @@ -1,19 +1,49 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_GLS) #include "ble_gls.h" #include #include "ble_srv_common.h" @@ -219,7 +249,7 @@ static uint32_t glucose_feature_char_add(ble_gls_t * p_gls) memset(&char_md, 0, sizeof(char_md)); - char_md.char_props.read = 1; + char_md.char_props.read = 1; char_md.p_char_user_desc = NULL; char_md.p_char_pf = NULL; char_md.p_user_desc_md = NULL; @@ -298,9 +328,9 @@ static uint32_t record_access_control_point_char_add(ble_gls_t * p_gls) attr_md.rd_auth = 0; attr_md.wr_auth = 1; attr_md.vlen = 1; - + memset(&attr_char_value, 0, sizeof(attr_char_value)); - + attr_char_value.p_uuid = &ble_uuid; attr_char_value.p_attr_md = &attr_md; attr_char_value.init_len = 0; @@ -428,7 +458,7 @@ static void racp_send(ble_gls_t * p_gls, ble_racp_value_t * p_racp_val) state_set(STATE_RACP_RESPONSE_IND_VERIF); break; - case BLE_ERROR_NO_TX_BUFFERS: + case BLE_ERROR_NO_TX_PACKETS: // Wait for TX_COMPLETE event to retry transmission state_set(STATE_RACP_RESPONSE_PENDING); break; @@ -715,7 +745,7 @@ static void racp_report_records_procedure(ble_gls_t * p_gls) } break; - case BLE_ERROR_NO_TX_BUFFERS: + case BLE_ERROR_NO_TX_PACKETS: // Wait for TX_COMPLETE event to resume transmission return; @@ -1005,7 +1035,10 @@ static void on_racp_value_write(ble_gls_t * p_gls, ble_gatts_evt_write_t * p_evt bool are_cccd_configured; uint32_t err_code; - auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.offset = 0; + auth_reply.params.write.len = 0; + auth_reply.params.write.p_data = NULL; err_code = ble_gls_are_cccd_configured(p_gls, &are_cccd_configured); if (err_code != NRF_SUCCESS) @@ -1040,8 +1073,10 @@ static void on_racp_value_write(ble_gls_t * p_gls, ble_gatts_evt_write_t * p_evt if (is_request_to_be_executed(&racp_request, &response_code)) { auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; - err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle, - &auth_reply); + auth_reply.params.write.update = 1; + + err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle, + &auth_reply); if (err_code != NRF_SUCCESS) { @@ -1064,6 +1099,7 @@ static void on_racp_value_write(ble_gls_t * p_gls, ble_gatts_evt_write_t * p_evt else if (response_code != RACP_RESPONSE_RESERVED) { auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle, &auth_reply); @@ -1265,3 +1301,4 @@ uint32_t ble_gls_glucose_new_meas(ble_gls_t * p_gls, ble_gls_rec_t * p_rec) p_rec->meas.sequence_number = m_next_seq_num++; return ble_gls_db_record_add(p_rec); } +#endif // NRF_MODULE_ENABLED(BLE_GLS) diff --git a/components/ble/ble_services/ble_gls/ble_gls.h b/components/ble/ble_services/ble_gls/ble_gls.h index 8c33805..a1217f3 100644 --- a/components/ble/ble_services/ble_gls/ble_gls.h +++ b/components/ble/ble_services/ble_gls/ble_gls.h @@ -1,17 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_gls Glucose Service + * @defgroup ble_gls Glucose Service * @{ * @ingroup ble_sdk_srv * @brief Glucose Service module. @@ -21,8 +50,8 @@ * @note The application must propagate BLE stack events to the Glucose Service module by calling * ble_gls_on_ble_evt() from the @ref softdevice_handler callback. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -35,6 +64,10 @@ #include "ble_srv_common.h" #include "ble_date_time.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Glucose feature */ #define BLE_GLS_FEATURE_LOW_BATT 0x0001 /**< Low Battery Detection During Measurement Supported */ #define BLE_GLS_FEATURE_MALFUNC 0x0002 /**< Sensor Malfunction Detection Supported */ @@ -157,7 +190,7 @@ typedef struct ble_gls_evt_type_t evt_type; /**< Type of event. */ } ble_gls_evt_t; -// Forward declaration of the ble_gls_t type. +// Forward declaration of the ble_gls_t type. typedef struct ble_gls_s ble_gls_t; /**@brief Glucose Service event handler type. */ @@ -258,6 +291,11 @@ void ble_gls_on_ble_evt(ble_gls_t * p_gls, ble_evt_t * p_ble_evt); */ uint32_t ble_gls_glucose_new_meas(ble_gls_t * p_gls, ble_gls_rec_t * p_rec); + +#ifdef __cplusplus +} +#endif + #endif // BLE_GLS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_gls/ble_gls_db.c b/components/ble/ble_services/ble_gls/ble_gls_db.c index 0f7d1a9..c1bbe8b 100644 --- a/components/ble/ble_services/ble_gls/ble_gls_db.c +++ b/components/ble/ble_services/ble_gls/ble_gls_db.c @@ -1,14 +1,44 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_GLS) #include "ble_gls_db.h" @@ -110,3 +140,4 @@ uint32_t ble_gls_db_record_delete(uint8_t rec_ndx) return NRF_SUCCESS; } +#endif // NRF_MODULE_ENABLED(BLE_GLS) diff --git a/components/ble/ble_services/ble_gls/ble_gls_db.h b/components/ble/ble_services/ble_gls/ble_gls_db.h index 2f2f4f9..89407d2 100644 --- a/components/ble/ble_services/ble_gls/ble_gls_db.h +++ b/components/ble/ble_services/ble_gls/ble_gls_db.h @@ -1,12 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -18,8 +47,8 @@ * * @details This module implements at database of stored glucose measurement values. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, These APIs must not be modified. However, the corresponding * functions' implementations can be modified. */ @@ -30,13 +59,17 @@ #include #include "ble_gls.h" +#ifdef __cplusplus +extern "C" { +#endif + #define BLE_GLS_DB_MAX_RECORDS 20 /**@brief Function for initializing the glucose record database. * * @details This call initializes the database holding glucose records. * - * @return NRF_SUCCESS on success. + * @return NRF_SUCCESS on success. */ uint32_t ble_gls_db_init(void); @@ -54,7 +87,7 @@ uint16_t ble_gls_db_num_records_get(void); * * @param[in] record_num Index of the record to retrieve. * @param[out] p_rec Pointer to record structure where retrieved record is copied to. - * + * * @return NRF_SUCCESS on success. */ uint32_t ble_gls_db_record_get(uint8_t record_num, ble_gls_rec_t * p_rec); @@ -64,7 +97,7 @@ uint32_t ble_gls_db_record_get(uint8_t record_num, ble_gls_rec_t * p_rec); * @details This call adds a record as the last record in the database. * * @param[in] p_rec Pointer to record to add to database. - * + * * @return NRF_SUCCESS on success. */ uint32_t ble_gls_db_record_add(ble_gls_rec_t * p_rec); @@ -74,11 +107,16 @@ uint32_t ble_gls_db_record_add(ble_gls_rec_t * p_rec); * @details This call deletes an record from the database. * * @param[in] record_num Index of record to delete. - * + * * @return NRF_SUCCESS on success. */ uint32_t ble_gls_db_record_delete(uint8_t record_num); + +#ifdef __cplusplus +} +#endif + #endif // BLE_GLS_DB_H__ /** @} */ diff --git a/components/ble/ble_services/ble_hids/ble_hids.c b/components/ble/ble_services/ble_hids/ble_hids.c index 240a25f..367491a 100644 --- a/components/ble/ble_services/ble_hids/ble_hids.c +++ b/components/ble/ble_services/ble_hids/ble_hids.c @@ -1,26 +1,53 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_HIDS) #include "ble_hids.h" #include #include "app_error.h" -#include "nordic_common.h" #include "ble_srv_common.h" -#include "app_util.h" // Protocol Mode values @@ -79,14 +106,14 @@ static void on_connect(ble_hids_t * p_hids, ble_evt_t * p_ble_evt) { // Set Protocol Mode characteristic value to default value default_protocol_mode = DEFAULT_PROTOCOL_MODE; - + // Initialize value struct. memset(&gatts_value, 0, sizeof(gatts_value)); - + gatts_value.len = sizeof(uint8_t); gatts_value.offset = 0; gatts_value.p_value = &default_protocol_mode; - + err_code = sd_ble_gatts_value_set(p_hids->conn_handle, p_hids->protocol_mode_handles.value_handle, &gatts_value); @@ -450,7 +477,7 @@ static uint32_t protocol_mode_char_add(ble_hids_t * p_hids, char_md.p_sccd_md = NULL; BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_PROTOCOL_MODE_CHAR); - + memset(&attr_md, 0, sizeof(attr_md)); attr_md.read_perm = p_sec_mode->read_perm; @@ -459,18 +486,18 @@ static uint32_t protocol_mode_char_add(ble_hids_t * p_hids, attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0; - + memset(&attr_char_value, 0, sizeof(attr_char_value)); - + initial_protocol_mode = DEFAULT_PROTOCOL_MODE; - + attr_char_value.p_uuid = &ble_uuid; attr_char_value.p_attr_md = &attr_md; attr_char_value.init_len = sizeof(uint8_t); attr_char_value.init_offs = 0; attr_char_value.max_len = sizeof(uint8_t); attr_char_value.p_value = &initial_protocol_mode; - + return sd_ble_gatts_characteristic_add(p_hids->service_handle, &char_md, &attr_char_value, @@ -505,7 +532,7 @@ static uint32_t rep_char_add(ble_hids_t * p_hids, ble_uuid_t ble_uuid; ble_gatts_attr_md_t attr_md; uint8_t encoded_rep_ref[BLE_SRV_ENCODED_REPORT_REF_LEN]; - + // Add Report characteristic if (p_properties->notify) { @@ -514,18 +541,18 @@ static uint32_t rep_char_add(ble_hids_t * p_hids, cccd_md.write_perm = p_rep_ref_attr_md->cccd_write_perm; cccd_md.vloc = BLE_GATTS_VLOC_STACK; } - + memset(&char_md, 0, sizeof(char_md)); - + char_md.char_props = *p_properties; char_md.p_char_user_desc = NULL; char_md.p_char_pf = NULL; char_md.p_user_desc_md = NULL; char_md.p_cccd_md = (p_properties->notify) ? &cccd_md : NULL; char_md.p_sccd_md = NULL; - + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_CHAR); - + memset(&attr_md, 0, sizeof(attr_md)); attr_md.read_perm = p_rep_ref_attr_md->read_perm; @@ -534,16 +561,16 @@ static uint32_t rep_char_add(ble_hids_t * p_hids, attr_md.rd_auth = is_read_resp ? 1 : 0; attr_md.wr_auth = 0; attr_md.vlen = 1; - + memset(&attr_char_value, 0, sizeof(attr_char_value)); - + attr_char_value.p_uuid = &ble_uuid; attr_char_value.p_attr_md = &attr_md; attr_char_value.init_len = 0; attr_char_value.init_offs = 0; attr_char_value.max_len = max_len; attr_char_value.p_value = NULL; - + err_code = sd_ble_gatts_characteristic_add(p_hids->service_handle, &char_md, &attr_char_value, @@ -555,7 +582,7 @@ static uint32_t rep_char_add(ble_hids_t * p_hids, // Add Report Reference descriptor BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_REF_DESCR); - + memset(&attr_md, 0, sizeof(attr_md)); attr_md.read_perm = p_rep_ref_attr_md->read_perm; @@ -564,16 +591,16 @@ static uint32_t rep_char_add(ble_hids_t * p_hids, attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0; - + memset(&attr_char_value, 0, sizeof(attr_char_value)); - + attr_char_value.p_uuid = &ble_uuid; attr_char_value.p_attr_md = &attr_md; attr_char_value.init_len = ble_srv_report_ref_encode(encoded_rep_ref, p_rep_ref); attr_char_value.init_offs = 0; attr_char_value.max_len = attr_char_value.init_len; attr_char_value.p_value = encoded_rep_ref; - + return sd_ble_gatts_descriptor_add(p_rep_char->char_handles.value_handle, &attr_char_value, &p_rep_char->ref_handle); @@ -923,8 +950,8 @@ static uint32_t hid_control_point_char_add(ble_hids_t * p_hid attr_char_value.max_len = sizeof(uint8_t); attr_char_value.p_value = &initial_hid_control_point; - return sd_ble_gatts_characteristic_add(p_hids->service_handle, &char_md, - &attr_char_value, + return sd_ble_gatts_characteristic_add(p_hids->service_handle, &char_md, + &attr_char_value, &p_hids->hid_control_point_handles); } @@ -1001,7 +1028,7 @@ static uint32_t outp_rep_characteristics_add(ble_hids_t * p_hids, err_code = rep_char_add(p_hids, &properties, - p_rep_init->max_len, + p_rep_init->max_len, &p_rep_init->rep_ref, &p_rep_init->security_mode, p_rep_init->read_resp, @@ -1378,3 +1405,4 @@ uint32_t ble_hids_outp_rep_get(ble_hids_t * p_hids, /** @} */ +#endif // NRF_MODULE_ENABLED(BLE_HIDS) diff --git a/components/ble/ble_services/ble_hids/ble_hids.h b/components/ble/ble_services/ble_hids/ble_hids.h index ff18e00..34c8a2a 100644 --- a/components/ble/ble_services/ble_hids/ble_hids.h +++ b/components/ble/ble_services/ble_hids/ble_hids.h @@ -1,24 +1,52 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_hids Human Interface Device Service + * @defgroup ble_hids Human Interface Device Service * @{ * @ingroup ble_sdk_srv * @brief Human Interface Device Service module. * * @details This module implements the Human Interface Device Service with the corresponding set of - * characteristics. During initialization it adds the Human Interface Device Service and + * characteristics. During initialization it adds the Human Interface Device Service and * a set of characteristics as per the Human Interface Device Service specification and * the user requirements to the BLE stack database. * @@ -31,8 +59,8 @@ * @note The application must propagate BLE stack events to the Human Interface Device Service * module by calling ble_hids_on_ble_evt() from the @ref softdevice_handler callback. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -44,6 +72,10 @@ #include "ble.h" #include "ble_srv_common.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @name Report Type values * @anchor BLE_HIDS_REPORT_TYPE @{ */ @@ -98,7 +130,7 @@ typedef struct ble_hids_char_id_t char_id; /**< Id of characteristic having been written. */ uint16_t offset; /**< Offset for the write operation. */ uint16_t len; /**< Length of the incoming data. */ - uint8_t* data; /**< Incoming data, variable length */ + uint8_t* data; /**< Incoming data, variable length */ } char_write; struct { @@ -108,7 +140,7 @@ typedef struct ble_evt_t * p_ble_evt; /**< corresponding received ble event, NULL if not relevant */ } ble_hids_evt_t; -// Forward declaration of the ble_hids_t type. +// Forward declaration of the ble_hids_t type. typedef struct ble_hids_s ble_hids_t; /**@brief HID Service event handler type. */ @@ -123,7 +155,7 @@ typedef struct ble_srv_security_mode_t security_mode; /**< Security mode for the HID Information characteristic. */ } ble_hids_hid_information_t; -/**@brief HID Service Input Report characteristic init structure. This contains all options and +/**@brief HID Service Input Report characteristic init structure. This contains all options and * data needed for initialization of one Input Report characteristic. */ typedef struct { @@ -133,7 +165,7 @@ typedef struct uint8_t read_resp : 1; /**< Should application generate a response to read requests. */ } ble_hids_inp_rep_init_t; -/**@brief HID Service Output Report characteristic init structure. This contains all options and +/**@brief HID Service Output Report characteristic init structure. This contains all options and * data needed for initialization of one Output Report characteristic. */ typedef struct { @@ -143,7 +175,7 @@ typedef struct uint8_t read_resp : 1; /**< Should application generate a response to read requests. */ } ble_hids_outp_rep_init_t; -/**@brief HID Service Feature Report characteristic init structure. This contains all options and +/**@brief HID Service Feature Report characteristic init structure. This contains all options and * data needed for initialization of one Feature Report characteristic. */ typedef struct { @@ -153,7 +185,7 @@ typedef struct uint8_t read_resp : 1; /**< Should application generate a response to read requests. */ } ble_hids_feature_rep_init_t; -/**@brief HID Service Report Map characteristic init structure. This contains all options and data +/**@brief HID Service Report Map characteristic init structure. This contains all options and data * needed for initialization of the Report Map characteristic. */ typedef struct { @@ -171,7 +203,7 @@ typedef struct uint16_t ref_handle; /**< Handle of the Report Reference descriptor. */ } ble_hids_rep_char_t; -/**@brief HID Service init structure. This contains all options and data needed for initialization +/**@brief HID Service init structure. This contains all options and data needed for initialization * of the service. */ typedef struct { @@ -244,16 +276,16 @@ void ble_hids_on_ble_evt(ble_hids_t * p_hids, ble_evt_t * p_ble_evt); * @details Sends data on an Input Report characteristic. * * @param[in] p_hids HID Service structure. - * @param[in] rep_index Index of the characteristic (corresponding to the index in + * @param[in] rep_index Index of the characteristic (corresponding to the index in * ble_hids_t.inp_rep_array as passed to ble_hids_init()). * @param[in] len Length of data to be sent. * @param[in] p_data Pointer to data to be sent. * * @return NRF_SUCCESS on successful sending of input report, otherwise an error code. */ -uint32_t ble_hids_inp_rep_send(ble_hids_t * p_hids, - uint8_t rep_index, - uint16_t len, +uint32_t ble_hids_inp_rep_send(ble_hids_t * p_hids, + uint8_t rep_index, + uint16_t len, uint8_t * p_data); /**@brief Function for sending Boot Keyboard Input Report. @@ -266,8 +298,8 @@ uint32_t ble_hids_inp_rep_send(ble_hids_t * p_hids, * * @return NRF_SUCCESS on successful sending of the report, otherwise an error code. */ -uint32_t ble_hids_boot_kb_inp_rep_send(ble_hids_t * p_hids, - uint16_t len, +uint32_t ble_hids_boot_kb_inp_rep_send(ble_hids_t * p_hids, + uint16_t len, uint8_t * p_data); /**@brief Function for sending Boot Mouse Input Report. @@ -283,9 +315,9 @@ uint32_t ble_hids_boot_kb_inp_rep_send(ble_hids_t * p_hids, * * @return NRF_SUCCESS on successful sending of the report, otherwise an error code. */ -uint32_t ble_hids_boot_mouse_inp_rep_send(ble_hids_t * p_hids, - uint8_t buttons, - int8_t x_delta, +uint32_t ble_hids_boot_mouse_inp_rep_send(ble_hids_t * p_hids, + uint8_t buttons, + int8_t x_delta, int8_t y_delta, uint16_t optional_data_len, uint8_t * p_optional_data); @@ -309,6 +341,11 @@ uint32_t ble_hids_outp_rep_get(ble_hids_t * p_hids, uint8_t offset, uint8_t * p_outp_rep); + +#ifdef __cplusplus +} +#endif + #endif // BLE_HIDS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_hrs/ble_hrs.c b/components/ble/ble_services/ble_hrs/ble_hrs.c index 4975f07..73b88ef 100644 --- a/components/ble/ble_services/ble_hrs/ble_hrs.c +++ b/components/ble/ble_services/ble_hrs/ble_hrs.c @@ -1,40 +1,68 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_HRS) #include "ble_hrs.h" #include -#include "nordic_common.h" #include "ble_l2cap.h" #include "ble_srv_common.h" -#include "app_util.h" -#define OPCODE_LENGTH 1 /**< Length of opcode inside Heart Rate Measurement packet. */ -#define HANDLE_LENGTH 2 /**< Length of handle inside Heart Rate Measurement packet. */ -#define MAX_HRM_LEN (BLE_L2CAP_MTU_DEF - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Heart Rate Measurement. */ +#define OPCODE_LENGTH 1 /**< Length of opcode inside Heart Rate Measurement packet. */ +#define HANDLE_LENGTH 2 /**< Length of handle inside Heart Rate Measurement packet. */ +#define INIT_MAX_HRM_LEN (GATT_MTU_SIZE_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Heart Rate Measurement. */ +#define MAX_HRM_LEN (NRF_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Heart Rate Measurement. */ -#define INITIAL_VALUE_HRM 0 /**< Initial Heart Rate Measurement value. */ +#define INITIAL_VALUE_HRM 0 /**< Initial Heart Rate Measurement value. */ // Heart Rate Measurement flag bits -#define HRM_FLAG_MASK_HR_VALUE_16BIT (0x01 << 0) /**< Heart Rate Value Format bit. */ -#define HRM_FLAG_MASK_SENSOR_CONTACT_DETECTED (0x01 << 1) /**< Sensor Contact Detected bit. */ -#define HRM_FLAG_MASK_SENSOR_CONTACT_SUPPORTED (0x01 << 2) /**< Sensor Contact Supported bit. */ -#define HRM_FLAG_MASK_EXPENDED_ENERGY_INCLUDED (0x01 << 3) /**< Energy Expended Status bit. Feature Not Supported */ -#define HRM_FLAG_MASK_RR_INTERVAL_INCLUDED (0x01 << 4) /**< RR-Interval bit. */ +#define HRM_FLAG_MASK_HR_VALUE_16BIT (0x01 << 0) /**< Heart Rate Value Format bit. */ +#define HRM_FLAG_MASK_SENSOR_CONTACT_DETECTED (0x01 << 1) /**< Sensor Contact Detected bit. */ +#define HRM_FLAG_MASK_SENSOR_CONTACT_SUPPORTED (0x01 << 2) /**< Sensor Contact Supported bit. */ +#define HRM_FLAG_MASK_EXPENDED_ENERGY_INCLUDED (0x01 << 3) /**< Energy Expended Status bit. Feature Not Supported */ +#define HRM_FLAG_MASK_RR_INTERVAL_INCLUDED (0x01 << 4) /**< RR-Interval bit. */ /**@brief Function for handling the Connect event. @@ -170,7 +198,7 @@ static uint8_t hrm_encode(ble_hrs_t * p_hrs, uint16_t heart_rate, uint8_t * p_en } for (i = 0; i < p_hrs->rr_interval_count; i++) { - if (len + sizeof(uint16_t) > MAX_HRM_LEN) + if (len + sizeof(uint16_t) > p_hrs->max_hrm_len) { // Not all stored rr_interval values can fit into the encoded hrm, // move the remaining values to the start of the buffer. @@ -310,6 +338,7 @@ uint32_t ble_hrs_init(ble_hrs_t * p_hrs, const ble_hrs_init_t * p_hrs_init) p_hrs->conn_handle = BLE_CONN_HANDLE_INVALID; p_hrs->is_sensor_contact_detected = false; p_hrs->rr_interval_count = 0; + p_hrs->max_hrm_len = INIT_MAX_HRM_LEN; // Add service BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HEART_RATE_SERVICE); @@ -438,3 +467,13 @@ uint32_t ble_hrs_body_sensor_location_set(ble_hrs_t * p_hrs, uint8_t body_sensor return sd_ble_gatts_value_set(p_hrs->conn_handle, p_hrs->bsl_handles.value_handle, &gatts_value); } + + +void ble_hrs_on_gatt_evt(ble_hrs_t * p_hrs, nrf_ble_gatt_evt_t * p_gatt_evt) +{ + if (p_hrs->conn_handle == p_gatt_evt->conn_handle) + { + p_hrs->max_hrm_len = p_gatt_evt->att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH; + } +} +#endif // NRF_MODULE_ENABLED(BLE_HRS) diff --git a/components/ble/ble_services/ble_hrs/ble_hrs.h b/components/ble/ble_services/ble_hrs/ble_hrs.h index 7936091..330c611 100644 --- a/components/ble/ble_services/ble_hrs/ble_hrs.h +++ b/components/ble/ble_services/ble_hrs/ble_hrs.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_hrs Heart Rate Service + * @defgroup ble_hrs Heart Rate Service * @{ * @ingroup ble_sdk_srv * @brief Heart Rate Service module. @@ -36,8 +64,8 @@ * @note The application must propagate BLE stack events to the Heart Rate Service module by calling * ble_hrs_on_ble_evt() from the @ref softdevice_handler callback. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -48,6 +76,11 @@ #include #include "ble.h" #include "ble_srv_common.h" +#include "nrf_ble_gatt.h" + +#ifdef __cplusplus +extern "C" { +#endif // Body Sensor Location values #define BLE_HRS_BODY_SENSOR_LOCATION_OTHER 0 @@ -73,7 +106,7 @@ typedef struct ble_hrs_evt_type_t evt_type; /**< Type of event. */ } ble_hrs_evt_t; -// Forward declaration of the ble_hrs_t type. +// Forward declaration of the ble_hrs_t type. typedef struct ble_hrs_s ble_hrs_t; /**@brief Heart Rate Service event handler type. */ @@ -104,6 +137,7 @@ struct ble_hrs_s bool is_sensor_contact_detected; /**< TRUE if sensor contact has been detected. */ uint16_t rr_interval[BLE_HRS_MAX_BUFFERED_RR_INTERVALS]; /**< Set of RR Interval measurements since the last Heart Rate Measurement transmission. */ uint16_t rr_interval_count; /**< Number of RR Interval measurements since the last Heart Rate Measurement transmission. */ + uint8_t max_hrm_len; /**< Current maximum HR measurement length, adjusted according to the current ATT MTU. */ }; /**@brief Function for initializing the Heart Rate Service. @@ -117,6 +151,17 @@ struct ble_hrs_s */ uint32_t ble_hrs_init(ble_hrs_t * p_hrs, const ble_hrs_init_t * p_hrs_init); + +/**@brief Function for handling the GATT module's events. + * + * @details Handles all events from the GATT module of interest to the Heart Rate Service. + * + * @param[in] p_hrs Heart Rate Service structure. + * @param[in] p_gatt_evt Event received from the GATT module. + */ +void ble_hrs_on_gatt_evt(ble_hrs_t * p_hrs, nrf_ble_gatt_evt_t * p_gatt_evt); + + /**@brief Function for handling the Application's BLE Stack events. * * @details Handles all events from the BLE stack of interest to the Heart Rate Service. @@ -187,6 +232,11 @@ void ble_hrs_sensor_contact_detected_update(ble_hrs_t * p_hrs, bool is_sensor_co */ uint32_t ble_hrs_body_sensor_location_set(ble_hrs_t * p_hrs, uint8_t body_sensor_location); + +#ifdef __cplusplus +} +#endif + #endif // BLE_HRS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c b/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c index c38f1f1..4cdf539 100644 --- a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c +++ b/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c @@ -1,30 +1,59 @@ -/* - * Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /**@cond To Make Doxygen skip documentation generation for this file. * @{ */ - -#include +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_HRS_C) #include "ble_hrs_c.h" #include "ble_db_discovery.h" #include "ble_types.h" #include "ble_srv_common.h" -#include "nordic_common.h" -#include "nrf_error.h" #include "ble_gattc.h" -#include "app_util.h" -#include "app_trace.h" -#define LOG app_trace_log /**< Debug logger macro that will be used in this file to do logging of important information over UART. */ +#define NRF_LOG_MODULE_NAME "BLE_HRS_C" +#include "nrf_log.h" -#define HRM_FLAG_MASK_HR_16BIT (0x01 << 0) /**< Bit mask used to extract the type of heart rate value. This is used to find if the received heart rate is a 16 bit value or an 8 bit value. */ +#define HRM_FLAG_MASK_HR_16BIT (0x01 << 0) /**< Bit mask used to extract the type of heart rate value. This is used to find if the received heart rate is a 16 bit value or an 8 bit value. */ +#define HRM_FLAG_MASK_HR_RR_INT (0x01 << 4) /**< Bit mask used to extract the presence of RR_INTERVALS. This is used to find if the received measurement includes RR_INTERVALS. */ #define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of continuous zeroes, followed by continuous sequence of ones: 000...111. */ #define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */ @@ -60,7 +89,6 @@ typedef struct } tx_message_t; -static ble_hrs_c_t * mp_ble_hrs_c; /**< Pointer to the current instance of the HRS Client module. The memory for this provided by the application.*/ static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */ static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ @@ -87,13 +115,13 @@ static void tx_buffer_process(void) } if (err_code == NRF_SUCCESS) { - LOG("[HRS_C]: SD Read/Write API returns Success..\r\n"); + NRF_LOG_INFO("SD Read/Write API returns Success..\r\n"); m_tx_index++; m_tx_index &= TX_BUFFER_MASK; } else { - LOG("[HRS_C]: SD Read/Write API returns error. This message sending will be " + NRF_LOG_INFO("SD Read/Write API returns error. This message sending will be " "attempted again..\r\n"); } } @@ -107,6 +135,11 @@ static void tx_buffer_process(void) */ static void on_write_rsp(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt) { + // Check if the event if on the link for this instance + if (p_ble_hrs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } // Check if there is any message to be sent across to the peer and send it. tx_buffer_process(); } @@ -124,13 +157,25 @@ static void on_write_rsp(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt) */ static void on_hvx(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt) { + // Check if the event is on the link for this instance + if (p_ble_hrs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + NRF_LOG_DEBUG("received HVX on link 0x%x, not associated to this instance, ignore\r\n", + p_ble_evt->evt.gattc_evt.conn_handle); + return; + } + NRF_LOG_DEBUG("received HVX on handle 0x%x, hrm_handle 0x%x\r\n", + p_ble_evt->evt.gattc_evt.params.hvx.handle, + p_ble_hrs_c->peer_hrs_db.hrm_handle); // Check if this is a heart rate notification. - if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_hrs_c->hrm_handle) + if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_hrs_c->peer_hrs_db.hrm_handle) { ble_hrs_c_evt_t ble_hrs_c_evt; uint32_t index = 0; - ble_hrs_c_evt.evt_type = BLE_HRS_C_EVT_HRM_NOTIFICATION; + ble_hrs_c_evt.evt_type = BLE_HRS_C_EVT_HRM_NOTIFICATION; + ble_hrs_c_evt.conn_handle = p_ble_hrs_c->conn_handle; + ble_hrs_c_evt.params.hrm.rr_intervals_cnt = 0; if (!(p_ble_evt->evt.gattc_evt.params.hvx.data[index++] & HRM_FLAG_MASK_HR_16BIT)) { @@ -142,81 +187,113 @@ static void on_hvx(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt) // 16 bit heart rate value received. ble_hrs_c_evt.params.hrm.hr_value = uint16_decode(&(p_ble_evt->evt.gattc_evt.params.hvx.data[index])); + index += sizeof(uint16_t); + } + if ((p_ble_evt->evt.gattc_evt.params.hvx.data[0] & HRM_FLAG_MASK_HR_RR_INT)) + { + uint32_t i; + /*lint --e{415} --e{416} --e{662} --e{661} -save suppress Warning 415: possible access out of bond */ + for (i = 0; i < BLE_HRS_C_RR_INTERVALS_MAX_CNT; i ++) + { + if (index >= p_ble_evt->evt.gattc_evt.params.hvx.len) + { + break; + } + ble_hrs_c_evt.params.hrm.rr_intervals[i] = + uint16_decode(&(p_ble_evt->evt.gattc_evt.params.hvx.data[index])); + index += sizeof(uint16_t); + } + /*lint -restore*/ + ble_hrs_c_evt.params.hrm.rr_intervals_cnt = (uint8_t)i; } - p_ble_hrs_c->evt_handler(p_ble_hrs_c, &ble_hrs_c_evt); } } -/**@brief Function for handling events from the database discovery module. - * - * @details This function will handle an event from the database discovery module, and determine - * if it relates to the discovery of heart rate service at the peer. If so, it will - * call the application's event handler indicating that the heart rate service has been - * discovered at the peer. It also populates the event with the service related - * information before providing it to the application. +/**@brief Function for handling Disconnected event received from the SoftDevice. * - * @param[in] p_evt Pointer to the event received from the database discovery module. + * @details This function check if the disconnect event is happening on the link + * associated with the current instance of the module, if so it will set its + * conn_handle to invalid. * + * @param[in] p_ble_hrs_c Pointer to the Heart Rate Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. */ -static void db_discover_evt_handler(ble_db_discovery_evt_t * p_evt) +static void on_disconnected(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt) +{ + if (p_ble_hrs_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ble_hrs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_hrs_c->peer_hrs_db.hrm_handle = BLE_GATT_HANDLE_INVALID; + } +} + + +void ble_hrs_on_db_disc_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_db_discovery_evt_t * p_evt) { // Check if the Heart Rate Service was discovered. if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_HEART_RATE_SERVICE && p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) { - mp_ble_hrs_c->conn_handle = p_evt->conn_handle; - // Find the CCCD Handle of the Heart Rate Measurement characteristic. uint32_t i; + ble_hrs_c_evt_t evt; + + evt.evt_type = BLE_HRS_C_EVT_DISCOVERY_COMPLETE; + evt.conn_handle = p_evt->conn_handle; + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) { if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid == BLE_UUID_HEART_RATE_MEASUREMENT_CHAR) { // Found Heart Rate characteristic. Store CCCD handle and break. - mp_ble_hrs_c->hrm_cccd_handle = + evt.params.peer_db.hrm_cccd_handle = p_evt->params.discovered_db.charateristics[i].cccd_handle; - mp_ble_hrs_c->hrm_handle = + evt.params.peer_db.hrm_handle = p_evt->params.discovered_db.charateristics[i].characteristic.handle_value; break; } } - LOG("[HRS_C]: Heart Rate Service discovered at peer.\r\n"); - - ble_hrs_c_evt_t evt; + NRF_LOG_INFO("Heart Rate Service discovered at peer.\r\n"); + //If the instance has been assigned prior to db_discovery, assign the db_handles + if (p_ble_hrs_c->conn_handle != BLE_CONN_HANDLE_INVALID) + { + if ((p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle == BLE_GATT_HANDLE_INVALID)&& + (p_ble_hrs_c->peer_hrs_db.hrm_handle == BLE_GATT_HANDLE_INVALID)) + { + p_ble_hrs_c->peer_hrs_db = evt.params.peer_db; + } + } - evt.evt_type = BLE_HRS_C_EVT_DISCOVERY_COMPLETE; - mp_ble_hrs_c->evt_handler(mp_ble_hrs_c, &evt); + p_ble_hrs_c->evt_handler(p_ble_hrs_c, &evt); } } uint32_t ble_hrs_c_init(ble_hrs_c_t * p_ble_hrs_c, ble_hrs_c_init_t * p_ble_hrs_c_init) { - if ((p_ble_hrs_c == NULL) || (p_ble_hrs_c_init == NULL)) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(p_ble_hrs_c); + VERIFY_PARAM_NOT_NULL(p_ble_hrs_c_init); ble_uuid_t hrs_uuid; hrs_uuid.type = BLE_UUID_TYPE_BLE; hrs_uuid.uuid = BLE_UUID_HEART_RATE_SERVICE; - mp_ble_hrs_c = p_ble_hrs_c; - mp_ble_hrs_c->evt_handler = p_ble_hrs_c_init->evt_handler; - mp_ble_hrs_c->conn_handle = BLE_CONN_HANDLE_INVALID; - mp_ble_hrs_c->hrm_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_hrs_c->evt_handler = p_ble_hrs_c_init->evt_handler; + p_ble_hrs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_hrs_c->peer_hrs_db.hrm_handle = BLE_GATT_HANDLE_INVALID; - return ble_db_discovery_evt_register(&hrs_uuid, - db_discover_evt_handler); + return ble_db_discovery_evt_register(&hrs_uuid); } @@ -229,10 +306,6 @@ void ble_hrs_c_on_ble_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt switch (p_ble_evt->header.evt_id) { - case BLE_GAP_EVT_CONNECTED: - p_ble_hrs_c->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; - break; - case BLE_GATTC_EVT_HVX: on_hvx(p_ble_hrs_c, p_ble_evt); break; @@ -241,6 +314,10 @@ void ble_hrs_c_on_ble_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt on_write_rsp(p_ble_hrs_c, p_ble_evt); break; + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ble_hrs_c, p_ble_evt); + break; + default: break; } @@ -251,7 +328,7 @@ void ble_hrs_c_on_ble_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt */ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable) { - LOG("[HRS_C]: Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", + NRF_LOG_INFO("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", handle_cccd,conn_handle); tx_message_t * p_msg; @@ -277,14 +354,28 @@ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool uint32_t ble_hrs_c_hrm_notif_enable(ble_hrs_c_t * p_ble_hrs_c) { - if (p_ble_hrs_c == NULL) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(p_ble_hrs_c); - return cccd_configure(p_ble_hrs_c->conn_handle, p_ble_hrs_c->hrm_cccd_handle, true); + return cccd_configure(p_ble_hrs_c->conn_handle, + p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle, + true); } + +uint32_t ble_hrs_c_handles_assign(ble_hrs_c_t * p_ble_hrs_c, + uint16_t conn_handle, + const hrs_db_t * p_peer_hrs_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ble_hrs_c); + + p_ble_hrs_c->conn_handle = conn_handle; + if (p_peer_hrs_handles != NULL) + { + p_ble_hrs_c->peer_hrs_db = *p_peer_hrs_handles; + } + return NRF_SUCCESS; +} /** @} * @endcond */ +#endif // NRF_MODULE_ENABLED(BLE_HRS_C) diff --git a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h b/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h index 0bd080a..dd47dd5 100644 --- a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h +++ b/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h @@ -1,15 +1,46 @@ -/* - * Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_hrs_c Heart Rate Service Client + * @defgroup ble_hrs_c Heart Rate Service Client * @{ * @ingroup ble_sdk_srv * @brief Heart Rate Service Client module. @@ -36,6 +67,22 @@ #include #include "ble.h" +#include "ble_db_discovery.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Maximum number of RR intervals to be decoded for each HRM notifications (any extra RR intervals will be ignored). + * + * This define should be defined in the sdk_config.h file to override the default. + */ +#ifndef BLE_HRS_C_RR_INTERVALS_MAX_CNT +#define BLE_HRS_C_RR_INTERVALS_MAX_CNT 20 +#endif + /** * @defgroup hrs_c_enums Enumerations @@ -59,16 +106,29 @@ typedef enum /**@brief Structure containing the heart rate measurement received from the peer. */ typedef struct { - uint16_t hr_value; /**< Heart Rate Value. */ + uint16_t hr_value; /**< Heart Rate Value. */ + uint8_t rr_intervals_cnt; /**< Number of RR intervals. */ + uint16_t rr_intervals[BLE_HRS_C_RR_INTERVALS_MAX_CNT]; /**< RR intervals. */ } ble_hrm_t; + +/**@brief Structure containing the handles related to the Heart Rate Service found on the peer. */ +typedef struct +{ + uint16_t hrm_cccd_handle; /**< Handle of the CCCD of the Heart Rate Measurement characteristic. */ + uint16_t hrm_handle; /**< Handle of the Heart Rate Measurement characteristic as provided by the SoftDevice. */ +} hrs_db_t; + + /**@brief Heart Rate Event structure. */ typedef struct { - ble_hrs_c_evt_type_t evt_type; /**< Type of the event. */ + ble_hrs_c_evt_type_t evt_type; /**< Type of the event. */ + uint16_t conn_handle; /**< Connection handle on which the Heart Rate service was discovered on the peer device..*/ union { - ble_hrm_t hrm; /**< Heart rate measurement received. This will be filled if the evt_type is @ref BLE_HRS_C_EVT_HRM_NOTIFICATION. */ + hrs_db_t peer_db; /**< Heart Rate related handles found on the peer device.. This will be filled if the evt_type is @ref BLE_HRS_C_EVT_DISCOVERY_COMPLETE.*/ + ble_hrm_t hrm; /**< Heart rate measurement received. This will be filled if the evt_type is @ref BLE_HRS_C_EVT_HRM_NOTIFICATION. */ } params; } ble_hrs_c_evt_t; @@ -101,8 +161,7 @@ typedef void (* ble_hrs_c_evt_handler_t) (ble_hrs_c_t * p_ble_hrs_c, ble_hrs_c_e struct ble_hrs_c_s { uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */ - uint16_t hrm_cccd_handle; /**< Handle of the CCCD of the Heart Rate Measurement characteristic. */ - uint16_t hrm_handle; /**< Handle of the Heart Rate Measurement characteristic as provided by the SoftDevice. */ + hrs_db_t peer_hrs_db; /**< Handles related to HRS on the peer*/ ble_hrs_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the heart rate service. */ }; @@ -158,13 +217,52 @@ void ble_hrs_c_on_ble_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt * @param p_ble_hrs_c Pointer to the heart rate client structure. * * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer. - * Otherwise, an error code. This function propagates the error code returned + * Otherwise, an error code. This function propagates the error code returned * by the SoftDevice API @ref sd_ble_gattc_write. */ uint32_t ble_hrs_c_hrm_notif_enable(ble_hrs_c_t * p_ble_hrs_c); + +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery modue. + * This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of heart rate service at the peer. If so, it will + * call the application's event handler indicating that the heart rate service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_ble_hrs_c Pointer to the heart rate client structure instance to associate. + * @param[in] p_evt Pointer to the event received from the database discovery module. + * + */ +void ble_hrs_on_db_disc_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for assigning a handles to a this instance of hrs_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of this module.The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_HRS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ble_hrs_c Pointer to the heart rate client structure instance to associate. + * @param[in] conn_handle Connection handle to associated with the given Heart Rate Client Instance. + * @param[in] p_peer_hrs_handles Attribute handles for the HRS server you want this HRS_C client to + * interact with. + */ +uint32_t ble_hrs_c_handles_assign(ble_hrs_c_t * p_ble_hrs_c, + uint16_t conn_handle, + const hrs_db_t * p_peer_hrs_handles); + /** @} */ // End tag for Function group. + +#ifdef __cplusplus +} +#endif + #endif // BLE_HRS_C_H__ /** @} */ // End tag for the file. diff --git a/components/ble/ble_services/ble_hts/ble_hts.c b/components/ble/ble_services/ble_hts/ble_hts.c index 1ac6bed..184ec1d 100644 --- a/components/ble/ble_services/ble_hts/ble_hts.c +++ b/components/ble/ble_services/ble_hts/ble_hts.c @@ -1,26 +1,53 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_HTS) #include "ble_hts.h" #include -#include "nordic_common.h" #include "ble_l2cap.h" #include "ble_srv_common.h" -#include "app_util.h" #define OPCODE_LENGTH 1 /**< Length of opcode inside Health Thermometer Measurement packet. */ @@ -424,5 +451,11 @@ uint32_t ble_hts_is_indication_enabled(ble_hts_t * p_hts, bool * p_indication_en { *p_indication_enabled = ble_srv_is_indication_enabled(cccd_value_buf); } + if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING) + { + *p_indication_enabled = false; + return NRF_SUCCESS; + } return err_code; } +#endif // NRF_MODULE_ENABLED(BLE_HTS) diff --git a/components/ble/ble_services/ble_hts/ble_hts.h b/components/ble/ble_services/ble_hts/ble_hts.h index f6d5723..f346b33 100644 --- a/components/ble/ble_services/ble_hts/ble_hts.h +++ b/components/ble/ble_services/ble_hts/ble_hts.h @@ -1,31 +1,60 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_hts Health Thermometer Service + * @defgroup ble_hts Health Thermometer Service * @{ * @ingroup ble_sdk_srv * @brief Health Thermometer Service module. * * @details This module implements the Health Thermometer Service. * - * If an event handler is supplied by the application, the Health Thermometer + * If an event handler is supplied by the application, the Health Thermometer * Service will generate Health Thermometer Service events to the application. * * @note The application must propagate BLE stack events to the Health Thermometer Service * module by calling ble_hts_on_ble_evt() from the @ref softdevice_handler function. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -38,6 +67,10 @@ #include "ble_srv_common.h" #include "ble_date_time.h" +#ifdef __cplusplus +extern "C" { +#endif + // Temperature Type measurement locations #define BLE_HTS_TEMP_TYPE_ARMPIT 1 #define BLE_HTS_TEMP_TYPE_BODY 2 @@ -63,7 +96,7 @@ typedef struct ble_hts_evt_type_t evt_type; /**< Type of event. */ } ble_hts_evt_t; -// Forward declaration of the ble_hts_t type. +// Forward declaration of the ble_hts_t type. typedef struct ble_hts_s ble_hts_t; /**@brief Health Thermometer Service event handler type. */ @@ -155,6 +188,11 @@ uint32_t ble_hts_measurement_send(ble_hts_t * p_hts, ble_hts_meas_t * p_hts_meas */ uint32_t ble_hts_is_indication_enabled(ble_hts_t * p_hts, bool * p_indication_enabled); + +#ifdef __cplusplus +} +#endif + #endif // BLE_HTS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_ias/ble_ias.c b/components/ble/ble_services/ble_ias/ble_ias.c index da33c52..89f328b 100644 --- a/components/ble/ble_services/ble_ias/ble_ias.c +++ b/components/ble/ble_services/ble_ias/ble_ias.c @@ -1,20 +1,49 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_IAS) #include "ble_ias.h" #include #include "ble_srv_common.h" @@ -171,3 +200,4 @@ uint32_t ble_ias_alert_level_get(ble_ias_t * p_ias, uint8_t * p_alert_level) p_ias->alert_level_handles.value_handle, &gatts_value); } +#endif // NRF_MODULE_ENABLED(BLE_IAS) diff --git a/components/ble/ble_services/ble_ias/ble_ias.h b/components/ble/ble_services/ble_ias/ble_ias.h index 6089f59..2e45309 100644 --- a/components/ble/ble_services/ble_ias/ble_ias.h +++ b/components/ble/ble_services/ble_ias/ble_ias.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_ias Immediate Alert Service + * @defgroup ble_ias Immediate Alert Service * @{ * @ingroup ble_sdk_srv * @brief Immediate Alert Service module. @@ -21,8 +49,8 @@ * During initialization it adds the Immediate Alert Service and Alert Level characteristic * to the BLE stack database. * - * The application must supply an event handler for receiving Immediate Alert Service - * events. Using this handler, the service will notify the application when the + * The application must supply an event handler for receiving Immediate Alert Service + * events. Using this handler, the service will notify the application when the * Alert Level characteristic value changes. * * The service also provides a function for letting the application poll the current @@ -31,8 +59,8 @@ * @note The application must propagate BLE stack events to the Immediate Alert Service * module by calling ble_ias_on_ble_evt() from the @ref softdevice_handler callback. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -42,6 +70,10 @@ #include #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Immediate Alert Service event type. */ typedef enum { @@ -58,7 +90,7 @@ typedef struct } params; } ble_ias_evt_t; -// Forward declaration of the ble_ias_t type. +// Forward declaration of the ble_ias_t type. typedef struct ble_ias_s ble_ias_t; /**@brief Immediate Alert Service event handler type. */ @@ -108,6 +140,11 @@ void ble_ias_on_ble_evt(ble_ias_t * p_ias, ble_evt_t * p_ble_evt); */ uint32_t ble_ias_alert_level_get(ble_ias_t * p_ias, uint8_t * p_alert_level); + +#ifdef __cplusplus +} +#endif + #endif // BLE_IAS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_ias_c/ble_ias_c.c b/components/ble/ble_services/ble_ias_c/ble_ias_c.c index 223ec72..6ce851b 100644 --- a/components/ble/ble_services/ble_ias_c/ble_ias_c.c +++ b/components/ble/ble_services/ble_ias_c/ble_ias_c.c @@ -1,155 +1,122 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_IAS_C) #include "ble_ias_c.h" #include #include "ble.h" #include "ble_srv_common.h" #include "ble_gattc.h" +#include "ble_db_discovery.h" -#define START_HANDLE 0x0001 /**< Start handle to be used during service discovery procedure. */ - -static ble_uuid_t m_alert_level_uuid; /**< Structure to store the UUID of Alert Level characteristic. */ - - -uint32_t ble_ias_c_init(ble_ias_c_t * p_ias_c, ble_ias_c_init_t const * p_ias_c_init) -{ - if (p_ias_c_init->evt_handler == NULL) - { - return NRF_ERROR_INVALID_PARAM; - } - - p_ias_c->evt_handler = p_ias_c_init->evt_handler; - p_ias_c->error_handler = p_ias_c_init->error_handler; - p_ias_c->conn_handle = BLE_CONN_HANDLE_INVALID; - p_ias_c->alert_level_handle = BLE_GATT_HANDLE_INVALID; - BLE_UUID_BLE_ASSIGN(m_alert_level_uuid, BLE_UUID_ALERT_LEVEL_CHAR); - - return NRF_SUCCESS; -} - - -/**@brief Function for handling the Connect event. - * - * @param[in] p_ias_c Immediate Alert Service client structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static uint32_t on_connect(ble_ias_c_t * p_ias_c, ble_evt_t const * p_ble_evt) +void ble_ias_c_on_db_disc_evt(ble_ias_c_t * p_ias_c, const ble_db_discovery_evt_t * p_evt) { - ble_uuid_t ias_uuid; - - p_ias_c->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; - - // Discover Immediate alert service - BLE_UUID_BLE_ASSIGN(ias_uuid, BLE_UUID_IMMEDIATE_ALERT_SERVICE); - - return sd_ble_gattc_primary_services_discover(p_ias_c->conn_handle, START_HANDLE, &ias_uuid); -} + ble_ias_c_evt_t evt; + memset(&evt, 0, sizeof(ble_ias_c_evt_t)); + evt.evt_type = BLE_IAS_C_EVT_DISCOVERY_FAILED; + evt.conn_handle = p_evt->conn_handle; -/**@brief Function for handling the Primary Service Discovery Response event. - * - * @param[in] p_ias_c Immediate Alert Service client structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static uint32_t on_srv_disc_resp(ble_ias_c_t * p_ias_c, ble_evt_t const * p_ble_evt) -{ - uint32_t err_code = NRF_SUCCESS; + const ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics; - if ( - p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS - || - p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.count == 0 - ) + // Check if the Immediate Alert Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE + && + p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_IMMEDIATE_ALERT_SERVICE + && + p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) { - // The Immediate Alert Service was not found at the peer. Notify the application using - // evt_handler. - ble_ias_c_evt_t evt; - evt.evt_type = BLE_IAS_C_EVT_SRV_NOT_FOUND; + uint32_t i; - p_ias_c->evt_handler(p_ias_c, &evt); + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + // The Alert Level characteristic in the Immediate Alert Service instance is found + // on peer. Check if it has the correct property 'Write without response'. + switch (p_chars[i].characteristic.uuid.uuid) + { + case BLE_UUID_ALERT_LEVEL_CHAR: + if (p_chars[i].characteristic.char_props.write_wo_resp) + { + // Found Alert Level characteristic inside the Immediate Alert Service. + memcpy(&evt.alert_level, + &p_chars[i].characteristic, + sizeof(ble_gattc_char_t)); + } + break; + + default: + break; + } + } } - else + if (evt.alert_level.handle_value != BLE_GATT_HANDLE_INVALID) { - // As per Find Me profile specification, there shall be only one instance of - // Immediate Alert Service at the peer. So only the first element of the - // p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services array is of interest. - const ble_gattc_handle_range_t * p_service_handle_range = - &(p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp.services[0].handle_range); - - // Discover characteristics. - err_code = sd_ble_gattc_characteristics_discover(p_ias_c->conn_handle, - p_service_handle_range); + evt.evt_type = BLE_IAS_C_EVT_DISCOVERY_COMPLETE; } - - return err_code; + + p_ias_c->evt_handler(p_ias_c, &evt); } -/**@brief Function for handling the Characteristic Discovery Response event. - * - * @param[in] p_ias_c Immediate Alert Service client structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_char_disc_resp(ble_ias_c_t * p_ias_c, const ble_evt_t * p_ble_evt) +uint32_t ble_ias_c_init(ble_ias_c_t * p_ias_c, ble_ias_c_init_t const * p_ias_c_init) { - ble_ias_c_evt_t evt; + VERIFY_PARAM_NOT_NULL(p_ias_c); + VERIFY_PARAM_NOT_NULL(p_ias_c_init->evt_handler); + VERIFY_PARAM_NOT_NULL(p_ias_c_init); - if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_SUCCESS) - { - int i; - const ble_gattc_evt_char_disc_rsp_t * p_char_disc_rsp; + p_ias_c->evt_handler = p_ias_c_init->evt_handler; + p_ias_c->error_handler = p_ias_c_init->error_handler; + p_ias_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ias_c->alert_level_char.handle_value = BLE_GATT_HANDLE_INVALID; - p_char_disc_rsp = &(p_ble_evt->evt.gattc_evt.params.char_disc_rsp); + BLE_UUID_BLE_ASSIGN(p_ias_c->alert_level_char.uuid, BLE_UUID_ALERT_LEVEL_CHAR); + BLE_UUID_BLE_ASSIGN(p_ias_c->service_uuid, BLE_UUID_IMMEDIATE_ALERT_SERVICE); - // Iterate through the characteristics and find the correct one. - for (i = 0; i < p_char_disc_rsp->count; i++) - { - if (BLE_UUID_EQ(&m_alert_level_uuid, &(p_char_disc_rsp->chars[i].uuid))) - { - // The Alert Level characteristic in the Immediate Alert Service instance is found - // on peer. Check if it has the correct property 'Write without response' as per - // Section 3.3.1.1 in Bluetooth Specification Vol 3. - if (p_char_disc_rsp->chars[i].char_props.write_wo_resp) - { - // The Alert Level characteristic has the correct property. - p_ias_c->alert_level_handle = p_char_disc_rsp->chars[i].handle_value; - - evt.evt_type = BLE_IAS_C_EVT_SRV_DISCOVERED; - - p_ias_c->evt_handler(p_ias_c, &evt); - return; - } - else - { - // The property of Alert Level characteristic is invalid. Hence break out of the - // loop. - break; - } - } - } - } - - // The Alert Level characteristic in Immediate Alert Service was not found at the peer. Notify - // the application using evt_handler. - evt.evt_type = BLE_IAS_C_EVT_SRV_NOT_FOUND; - - p_ias_c->evt_handler(p_ias_c, &evt); + return ble_db_discovery_evt_register(&p_ias_c->service_uuid); } + /**@brief Function for handling the Disconnect event. * * @param[in] p_ias_c Immediate Alert Service client structure. @@ -158,18 +125,18 @@ static void on_char_disc_resp(ble_ias_c_t * p_ias_c, const ble_evt_t * p_ble_evt static void on_disconnect(ble_ias_c_t * p_ias_c, ble_evt_t const * p_ble_evt) { // The following values will be re-initialized when a new connection is made. - p_ias_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ias_c->conn_handle = BLE_CONN_HANDLE_INVALID; - if (p_ias_c->alert_level_handle != BLE_GATT_HANDLE_INVALID) + if (ble_ias_c_is_discovered(p_ias_c)) { - // There was a valid instance of IAS on the peer. Send an event to the + // There was a valid instance of IAS on the peer. Send an event to the // application, so that it can do any clean up related to this module. ble_ias_c_evt_t evt; evt.evt_type = BLE_IAS_C_EVT_DISCONN_COMPLETE; p_ias_c->evt_handler(p_ias_c, &evt); - p_ias_c->alert_level_handle = BLE_GATT_HANDLE_INVALID; + p_ias_c->alert_level_char.handle_value = BLE_GATT_HANDLE_INVALID; } } @@ -180,19 +147,7 @@ void ble_ias_c_on_ble_evt(ble_ias_c_t * p_ias_c, ble_evt_t const * p_ble_evt) switch (p_ble_evt->header.evt_id) { - case BLE_GAP_EVT_CONNECTED: - err_code = on_connect(p_ias_c, p_ble_evt); - break; - - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - err_code = on_srv_disc_resp(p_ias_c, p_ble_evt); - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - on_char_disc_resp(p_ias_c, p_ble_evt); - break; - - case BLE_GAP_EVT_DISCONNECTED: + case BLE_GAP_EVT_DISCONNECTED: on_disconnect(p_ias_c, p_ble_evt); break; @@ -226,11 +181,11 @@ static uint32_t write_characteristic_value(uint16_t conn_handle, memset(&write_params, 0, sizeof(write_params)); - write_params.handle = write_handle; - write_params.write_op = BLE_GATT_OP_WRITE_CMD; - write_params.offset = 0; - write_params.len = length; - write_params.p_value = p_value; + write_params.handle = write_handle; + write_params.write_op = BLE_GATT_OP_WRITE_CMD; + write_params.offset = 0; + write_params.len = length; + write_params.p_value = p_value; return sd_ble_gattc_write(conn_handle, &write_params); } @@ -238,13 +193,26 @@ static uint32_t write_characteristic_value(uint16_t conn_handle, uint32_t ble_ias_c_send_alert_level(ble_ias_c_t const * p_ias_c, uint8_t alert_level) { - if (!ble_ias_c_is_ias_discovered(p_ias_c)) + if (!ble_ias_c_is_discovered(p_ias_c)) { return NRF_ERROR_NOT_FOUND; } return write_characteristic_value(p_ias_c->conn_handle, - p_ias_c->alert_level_handle, + p_ias_c->alert_level_char.handle_value, sizeof(uint8_t), &alert_level); } + + +uint32_t ble_ias_c_handles_assign(ble_ias_c_t * p_ias_c, + const uint16_t conn_handle, + const uint16_t alert_level_handle) +{ + VERIFY_PARAM_NOT_NULL(p_ias_c); + + p_ias_c->conn_handle = conn_handle; + p_ias_c->alert_level_char.handle_value = alert_level_handle; + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(BLE_IAS_C) diff --git a/components/ble/ble_services/ble_ias_c/ble_ias_c.h b/components/ble/ble_services/ble_ias_c/ble_ias_c.h index 4b27158..453b64d 100644 --- a/components/ble/ble_services/ble_ias_c/ble_ias_c.h +++ b/components/ble/ble_services/ble_ias_c/ble_ias_c.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_ias_c Immediate Alert Service Client + * @defgroup ble_ias_c Immediate Alert Service Client * @{ * @ingroup ble_sdk_srv * @brief Immediate Alert Service Client module @@ -21,7 +49,7 @@ * profile. On @ref BLE_GAP_EVT_CONNECTED event, this module starts discovery of the * Immediate Alert Service with Alert Level characteristic at the peer. This module will * indicate the application about a successful service & characteristic discovery using - * @ref BLE_IAS_C_EVT_SRV_DISCOVERED event. The application can use @ref + * @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE event. The application can use @ref * ble_ias_c_send_alert_level function to signal alerts to the peer. * * @note The application must propagate BLE stack events to this module by calling @@ -31,10 +59,15 @@ #ifndef BLE_IAS_C_H__ #define BLE_IAS_C_H__ +#include #include "ble_srv_common.h" #include "ble_gattc.h" #include "ble.h" -#include +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif // Forward declaration of the ble_ias_c_t type. typedef struct ble_ias_c_s ble_ias_c_t; @@ -42,15 +75,17 @@ typedef struct ble_ias_c_s ble_ias_c_t; /**@brief Immediate Alert Service client event type. */ typedef enum { - BLE_IAS_C_EVT_SRV_DISCOVERED, /**< Event indicating that the Immediate Alert Service is found at the peer. */ - BLE_IAS_C_EVT_SRV_NOT_FOUND, /**< Event indicating that the Immediate Alert Service is not found at the peer. */ - BLE_IAS_C_EVT_DISCONN_COMPLETE /**< Event indicating that the Immediate Alert Service client module has completed the processing of BLE_GAP_EVT_DISCONNECTED event. This event is raised only if a valid instance of IAS was found at the peer during the discovery phase. This event can be used the application to do clean up related to the IAS Client.*/ + BLE_IAS_C_EVT_DISCOVERY_COMPLETE, /**< Event indicating that the Immediate Alert Service is found at the peer. */ + BLE_IAS_C_EVT_DISCOVERY_FAILED, /**< Event indicating that the Immediate Alert Service is not found at the peer. */ + BLE_IAS_C_EVT_DISCONN_COMPLETE /**< Event indicating that the Immediate Alert Service client module has completed the processing of BLE_GAP_EVT_DISCONNECTED event. This event is raised only if a valid instance of IAS was found at the peer during the discovery phase. This event can be used the application to do clean up related to the IAS Client.*/ } ble_ias_c_evt_type_t; /**@brief Immediate Alert Service client event. */ typedef struct { - ble_ias_c_evt_type_t evt_type; /**< Type of event. */ + ble_ias_c_evt_type_t evt_type; /**< Type of event. */ + uint16_t conn_handle; /**< Connection handle on which the IAS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE.*/ + ble_gattc_char_t alert_level; /**< Info on the discovered Alert Level characteristic discovered. This will be filled if the evt_type is @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE.*/ } ble_ias_c_evt_t; /**@brief Immediate Alert Service client event handler type. */ @@ -59,18 +94,19 @@ typedef void (*ble_ias_c_evt_handler_t) (ble_ias_c_t * p_ias_c, ble_ias_c_evt_t /**@brief IAS Client structure. This contains various status information for the client. */ struct ble_ias_c_s { - ble_ias_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Immediate Alert Service client. */ - ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ - uint16_t alert_level_handle; /**< Handle of Alert Level characteristic at peer (as provided by the BLE stack). */ - uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */ + ble_ias_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Immediate Alert Service client. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + uint16_t conn_handle; /**< Handle of the current connection. Set with @ref ble_ias_c_handles_assign when connected. */ + ble_uuid_t service_uuid; /**< The GATT Service holding the discovered Immediate Service. */ + ble_gattc_char_t alert_level_char; /**< IAS Alert Level Characteristic. Stores data about the alert characteristic found on the peer. */ }; /**@brief IAS Client init structure. This contains all options and data needed for initialization of * the client.*/ typedef struct { - ble_ias_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events from the Immediate Alert Service client. */ - ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ + ble_ias_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events from the Immediate Alert Service client. */ + ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */ } ble_ias_c_init_t; /**@brief Function for initializing the Immediate Alert Service client. @@ -109,13 +145,61 @@ void ble_ias_c_on_ble_evt(ble_ias_c_t * p_ias_c, const ble_evt_t * p_ble_evt); /**@brief Function for checking whether the peer's Immediate Alert Service instance and the alert level * characteristic have been discovered. + * * @param[in] p_ias_c Immediate Alert Service client structure. + * + * @return TRUE if a handle has been assigned to alert_level_handle, meaning it must have been + * discovered. FALSE if the handle is invalid. */ -static __INLINE bool ble_ias_c_is_ias_discovered(const ble_ias_c_t * p_ias_c) +static __INLINE bool ble_ias_c_is_discovered(const ble_ias_c_t * p_ias_c) { - return (p_ias_c->alert_level_handle != BLE_GATT_HANDLE_INVALID); + return (p_ias_c->alert_level_char.handle_value != BLE_GATT_HANDLE_INVALID); } + +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery modue. + * This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of heart rate service at the peer. If so, it will + * call the application's event handler indicating that the heart rate service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_ias_c Pointer to the immediate alert client structure instance that will handle + * the discovery. + * @param[in] p_evt Pointer to the event received from the database discovery module. + * + */ +void ble_ias_c_on_db_disc_evt(ble_ias_c_t * p_ias_c, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for assigning handles to an instance of ias_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several links and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ias_c Pointer to the IAS client structure instance to associate. + * @param[in] conn_handle Connection handle to associated with the given IAS Instance. + * @param[in] alert_level_handle Attribute handle on the IAS server that you want this IAS_C client to + * interact with. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If a p_ias_c was a NULL pointer. + */ +uint32_t ble_ias_c_handles_assign(ble_ias_c_t * p_ias_c, + uint16_t conn_handle, + uint16_t alert_level_handle); + + + +#ifdef __cplusplus +} #endif +#endif // BLE_IAS_C_H__ + /** @} */ diff --git a/components/ble/ble_services/ble_lbs/ble_lbs.c b/components/ble/ble_services/ble_lbs/ble_lbs.c index 0ebd7bb..68117db 100644 --- a/components/ble/ble_services/ble_lbs/ble_lbs.c +++ b/components/ble/ble_services/ble_lbs/ble_lbs.c @@ -1,14 +1,46 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the license.txt file. +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - -#include +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_LBS) #include "ble_lbs.h" -#include "nordic_common.h" #include "ble_srv_common.h" -#include "app_util.h" /**@brief Function for handling the Connect event. @@ -63,7 +95,7 @@ void ble_lbs_on_ble_evt(ble_lbs_t * p_lbs, ble_evt_t * p_ble_evt) case BLE_GAP_EVT_DISCONNECTED: on_disconnect(p_lbs, p_ble_evt); break; - + case BLE_GATTS_EVT_WRITE: on_write(p_lbs, p_ble_evt); break; @@ -101,7 +133,7 @@ static uint32_t led_char_add(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_ini ble_uuid.type = p_lbs->uuid_type; ble_uuid.uuid = LBS_UUID_LED_CHAR; - + memset(&attr_md, 0, sizeof(attr_md)); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm); @@ -110,7 +142,7 @@ static uint32_t led_char_add(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_ini attr_md.rd_auth = 0; attr_md.wr_auth = 0; attr_md.vlen = 0; - + memset(&attr_char_value, 0, sizeof(attr_char_value)); attr_char_value.p_uuid = &ble_uuid; @@ -147,9 +179,9 @@ static uint32_t button_char_add(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm); BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm); cccd_md.vloc = BLE_GATTS_VLOC_STACK; - + memset(&char_md, 0, sizeof(char_md)); - + char_md.char_props.read = 1; char_md.char_props.notify = 1; char_md.p_char_user_desc = NULL; @@ -197,32 +229,20 @@ uint32_t ble_lbs_init(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_init) // Add service. ble_uuid128_t base_uuid = {LBS_UUID_BASE}; err_code = sd_ble_uuid_vs_add(&base_uuid, &p_lbs->uuid_type); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); ble_uuid.type = p_lbs->uuid_type; ble_uuid.uuid = LBS_UUID_SERVICE; err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_lbs->service_handle); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Add characteristics. err_code = button_char_add(p_lbs, p_lbs_init); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); err_code = led_char_add(p_lbs, p_lbs_init); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); return NRF_SUCCESS; } @@ -231,12 +251,13 @@ uint32_t ble_lbs_on_button_change(ble_lbs_t * p_lbs, uint8_t button_state) { ble_gatts_hvx_params_t params; uint16_t len = sizeof(button_state); - + memset(¶ms, 0, sizeof(params)); params.type = BLE_GATT_HVX_NOTIFICATION; params.handle = p_lbs->button_char_handles.value_handle; params.p_data = &button_state; params.p_len = &len; - + return sd_ble_gatts_hvx(p_lbs->conn_handle, ¶ms); } +#endif // NRF_MODULE_ENABLED(BLE_LBS) diff --git a/components/ble/ble_services/ble_lbs/ble_lbs.h b/components/ble/ble_services/ble_lbs/ble_lbs.h index d7a1e1e..18d7595 100644 --- a/components/ble/ble_services/ble_lbs/ble_lbs.h +++ b/components/ble/ble_services/ble_lbs/ble_lbs.h @@ -1,22 +1,50 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_lbs LED Button Service + * @defgroup ble_lbs LED Button Service Server * @{ * @ingroup ble_sdk_srv * - * @brief LED Button Service module. + * @brief LED Button Service Server module. * * @details This module implements a custom LED Button Service with an LED and Button Characteristics. * During initialization, the module adds the LED Button Service and Characteristics @@ -41,13 +69,17 @@ #include "ble.h" #include "ble_srv_common.h" +#ifdef __cplusplus +extern "C" { +#endif + #define LBS_UUID_BASE {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \ 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00} #define LBS_UUID_SERVICE 0x1523 -#define LBS_UUID_LED_CHAR 0x1525 #define LBS_UUID_BUTTON_CHAR 0x1524 +#define LBS_UUID_LED_CHAR 0x1525 -// Forward declaration of the ble_lbs_t type. +// Forward declaration of the ble_lbs_t type. typedef struct ble_lbs_s ble_lbs_t; typedef void (*ble_lbs_led_write_handler_t) (ble_lbs_t * p_lbs, uint8_t new_state); @@ -99,6 +131,11 @@ void ble_lbs_on_ble_evt(ble_lbs_t * p_lbs, ble_evt_t * p_ble_evt); */ uint32_t ble_lbs_on_button_change(ble_lbs_t * p_lbs, uint8_t button_state); + +#ifdef __cplusplus +} +#endif + #endif // BLE_LBS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_lbs_c/ble_lbs_c.c b/components/ble/ble_services/ble_lbs_c/ble_lbs_c.c new file mode 100644 index 0000000..b2db520 --- /dev/null +++ b/components/ble/ble_services/ble_lbs_c/ble_lbs_c.c @@ -0,0 +1,392 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_LBS_C) + +#include "ble_lbs_c.h" +#include "ble_db_discovery.h" +#include "ble_types.h" +#include "ble_srv_common.h" +#include "ble_gattc.h" +#define NRF_LOG_MODULE_NAME "BLE_LBS_C" +#include "nrf_log.h" + +#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of continuous zeroes, followed by continuous sequence of ones: 000...111. */ +#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */ + +#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */ +#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */ + +typedef enum +{ + READ_REQ, /**< Type identifying that this tx_message is a read request. */ + WRITE_REQ /**< Type identifying that this tx_message is a write request. */ +} tx_request_t; + +/**@brief Structure for writing a message to the peer, i.e. CCCD. + */ +typedef struct +{ + uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */ + ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */ +} write_params_t; + +/**@brief Structure for holding data to be transmitted to the connected central. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */ + tx_request_t type; /**< Type of this message, i.e. read or write message. */ + union + { + uint16_t read_handle; /**< Read request message. */ + write_params_t write_req; /**< Write request message. */ + } req; +} tx_message_t; + + +static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */ +static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ +static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ + + +/**@brief Function for passing any pending request from the buffer to the stack. + */ +static void tx_buffer_process(void) +{ + if (m_tx_index != m_tx_insert_index) + { + uint32_t err_code; + + if (m_tx_buffer[m_tx_index].type == READ_REQ) + { + err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle, + m_tx_buffer[m_tx_index].req.read_handle, + 0); + } + else + { + err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle, + &m_tx_buffer[m_tx_index].req.write_req.gattc_params); + } + if (err_code == NRF_SUCCESS) + { + NRF_LOG_DEBUG("SD Read/Write API returns Success..\r\n"); + m_tx_index++; + m_tx_index &= TX_BUFFER_MASK; + } + else + { + NRF_LOG_DEBUG("SD Read/Write API returns error. This message sending will be " + "attempted again..\r\n"); + } + } +} + + +/**@brief Function for handling write response events. + * + * @param[in] p_ble_lbs_c Pointer to the Led Button Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_write_rsp(ble_lbs_c_t * p_ble_lbs_c, const ble_evt_t * p_ble_evt) +{ + // Check if the event if on the link for this instance + if (p_ble_lbs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + // Check if there is any message to be sent across to the peer and send it. + tx_buffer_process(); +} + + +/**@brief Function for handling Handle Value Notification received from the SoftDevice. + * + * @details This function will uses the Handle Value Notification received from the SoftDevice + * and checks if it is a notification of Button state from the peer. If + * it is, this function will decode the state of the button and send it to the + * application. + * + * @param[in] p_ble_lbs_c Pointer to the Led Button Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_hvx(ble_lbs_c_t * p_ble_lbs_c, const ble_evt_t * p_ble_evt) +{ + // Check if the event is on the link for this instance + if (p_ble_lbs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + // Check if this is a Button notification. + if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_lbs_c->peer_lbs_db.button_handle) + { + if (p_ble_evt->evt.gattc_evt.params.hvx.len == 1) + { + ble_lbs_c_evt_t ble_lbs_c_evt; + + ble_lbs_c_evt.evt_type = BLE_LBS_C_EVT_BUTTON_NOTIFICATION; + ble_lbs_c_evt.conn_handle = p_ble_lbs_c->conn_handle; + ble_lbs_c_evt.params.button.button_state = p_ble_evt->evt.gattc_evt.params.hvx.data[0]; + p_ble_lbs_c->evt_handler(p_ble_lbs_c, &ble_lbs_c_evt); + } + } +} + + +/**@brief Function for handling Disconnected event received from the SoftDevice. + * + * @details This function check if the disconnect event is happening on the link + * associated with the current instance of the module, if so it will set its + * conn_handle to invalid. + * + * @param[in] p_ble_lbs_c Pointer to the Led Button Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_disconnected(ble_lbs_c_t * p_ble_lbs_c, const ble_evt_t * p_ble_evt) +{ + if (p_ble_lbs_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ble_lbs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_lbs_c->peer_lbs_db.button_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_lbs_c->peer_lbs_db.button_handle = BLE_GATT_HANDLE_INVALID; + p_ble_lbs_c->peer_lbs_db.led_handle = BLE_GATT_HANDLE_INVALID; + } +} + + +void ble_lbs_on_db_disc_evt(ble_lbs_c_t * p_ble_lbs_c, const ble_db_discovery_evt_t * p_evt) +{ + // Check if the Led Button Service was discovered. + if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && + p_evt->params.discovered_db.srv_uuid.uuid == LBS_UUID_SERVICE && + p_evt->params.discovered_db.srv_uuid.type == p_ble_lbs_c->uuid_type) + { + ble_lbs_c_evt_t evt; + + evt.evt_type = BLE_LBS_C_EVT_DISCOVERY_COMPLETE; + evt.conn_handle = p_evt->conn_handle; + + uint32_t i; + for (i = 0; i < p_evt->params.discovered_db.char_count; i++) + { + const ble_gatt_db_char_t * p_char = &(p_evt->params.discovered_db.charateristics[i]); + switch (p_char->characteristic.uuid.uuid) + { + case LBS_UUID_LED_CHAR: + evt.params.peer_db.led_handle = p_char->characteristic.handle_value; + break; + case LBS_UUID_BUTTON_CHAR: + evt.params.peer_db.button_handle = p_char->characteristic.handle_value; + evt.params.peer_db.button_cccd_handle = p_char->cccd_handle; + break; + + default: + break; + } + } + + NRF_LOG_DEBUG("Led Button Service discovered at peer.\r\n"); + //If the instance has been assigned prior to db_discovery, assign the db_handles + if (p_ble_lbs_c->conn_handle != BLE_CONN_HANDLE_INVALID) + { + if ((p_ble_lbs_c->peer_lbs_db.led_handle == BLE_GATT_HANDLE_INVALID)&& + (p_ble_lbs_c->peer_lbs_db.button_handle == BLE_GATT_HANDLE_INVALID)&& + (p_ble_lbs_c->peer_lbs_db.button_cccd_handle == BLE_GATT_HANDLE_INVALID)) + { + p_ble_lbs_c->peer_lbs_db = evt.params.peer_db; + } + } + + p_ble_lbs_c->evt_handler(p_ble_lbs_c, &evt); + + } +} + + +uint32_t ble_lbs_c_init(ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_init_t * p_ble_lbs_c_init) +{ + uint32_t err_code; + ble_uuid_t lbs_uuid; + ble_uuid128_t lbs_base_uuid = {LBS_UUID_BASE}; + + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c); + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init); + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init->evt_handler); + + p_ble_lbs_c->peer_lbs_db.button_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_lbs_c->peer_lbs_db.button_handle = BLE_GATT_HANDLE_INVALID; + p_ble_lbs_c->peer_lbs_db.led_handle = BLE_GATT_HANDLE_INVALID; + p_ble_lbs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_lbs_c->evt_handler = p_ble_lbs_c_init->evt_handler; + + err_code = sd_ble_uuid_vs_add(&lbs_base_uuid, &p_ble_lbs_c->uuid_type); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + VERIFY_SUCCESS(err_code); + + lbs_uuid.type = p_ble_lbs_c->uuid_type; + lbs_uuid.uuid = LBS_UUID_SERVICE; + + return ble_db_discovery_evt_register(&lbs_uuid); +} + +void ble_lbs_c_on_ble_evt(ble_lbs_c_t * p_ble_lbs_c, const ble_evt_t * p_ble_evt) +{ + if ((p_ble_lbs_c == NULL) || (p_ble_evt == NULL)) + { + return; + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTC_EVT_HVX: + on_hvx(p_ble_lbs_c, p_ble_evt); + break; + + case BLE_GATTC_EVT_WRITE_RSP: + on_write_rsp(p_ble_lbs_c, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ble_lbs_c, p_ble_evt); + break; + + default: + break; + } +} + + +/**@brief Function for configuring the CCCD. + * + * @param[in] conn_handle The connection handle on which to configure the CCCD. + * @param[in] handle_cccd The handle of the CCCD to be configured. + * @param[in] enable Whether to enable or disable the CCCD. + * + * @return NRF_SUCCESS if the CCCD configure was successfully sent to the peer. + */ +static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable) +{ + NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", + handle_cccd,conn_handle); + + tx_message_t * p_msg; + uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0; + + p_msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + p_msg->req.write_req.gattc_params.handle = handle_cccd; + p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH; + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ; + p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val); + p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val); + p_msg->conn_handle = conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + + +uint32_t ble_lbs_c_button_notif_enable(ble_lbs_c_t * p_ble_lbs_c) +{ + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c); + + if (p_ble_lbs_c->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + + return cccd_configure(p_ble_lbs_c->conn_handle, + p_ble_lbs_c->peer_lbs_db.button_cccd_handle, + true); +} + + +uint32_t ble_lbs_led_status_send(ble_lbs_c_t * p_ble_lbs_c, uint8_t status) +{ + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c); + + if (p_ble_lbs_c->conn_handle == BLE_CONN_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_STATE; + } + + NRF_LOG_DEBUG("writing LED status 0x%x\r\n", status); + + tx_message_t * p_msg; + + p_msg = &m_tx_buffer[m_tx_insert_index++]; + m_tx_insert_index &= TX_BUFFER_MASK; + + p_msg->req.write_req.gattc_params.handle = p_ble_lbs_c->peer_lbs_db.led_handle; + p_msg->req.write_req.gattc_params.len = sizeof(status); + p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value; + p_msg->req.write_req.gattc_params.offset = 0; + p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_CMD; + p_msg->req.write_req.gattc_value[0] = status; + p_msg->conn_handle = p_ble_lbs_c->conn_handle; + p_msg->type = WRITE_REQ; + + tx_buffer_process(); + return NRF_SUCCESS; +} + +uint32_t ble_lbs_c_handles_assign(ble_lbs_c_t * p_ble_lbs_c, + uint16_t conn_handle, + const lbs_db_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ble_lbs_c); + + p_ble_lbs_c->conn_handle = conn_handle; + if (p_peer_handles != NULL) + { + p_ble_lbs_c->peer_lbs_db = *p_peer_handles; + } + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(BLE_LBS_C) diff --git a/components/ble/ble_services/ble_lbs_c/ble_lbs_c.h b/components/ble/ble_services/ble_lbs_c/ble_lbs_c.h new file mode 100644 index 0000000..6d50f4d --- /dev/null +++ b/components/ble/ble_services/ble_lbs_c/ble_lbs_c.h @@ -0,0 +1,231 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_lbs_c LED Button Service Client + * @{ + * @ingroup ble_sdk_srv + * @brief The LED Button Service client can be used to set a LED, and read a button state on a + * LED button service server. + * + * @details This module contains the APIs and types exposed by the LED Button Service Client + * module. These APIs and types can be used by the application to perform discovery of + * LED Button Service at the peer and interact with it. + * + * @note The application must propagate BLE stack events to this module by calling + * ble_lbs_c_on_ble_evt(). + * + */ + +#ifndef BLE_LBS_C_H__ +#define BLE_LBS_C_H__ + +#include +#include "ble.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LBS_UUID_BASE {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \ + 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00} +#define LBS_UUID_SERVICE 0x1523 +#define LBS_UUID_BUTTON_CHAR 0x1524 +#define LBS_UUID_LED_CHAR 0x1525 + +/**@brief LBS Client event type. */ +typedef enum +{ + BLE_LBS_C_EVT_DISCOVERY_COMPLETE = 1, /**< Event indicating that the LED Button Service has been discovered at the peer. */ + BLE_LBS_C_EVT_BUTTON_NOTIFICATION /**< Event indicating that a notification of the LED Button Button characteristic has been received from the peer. */ +} ble_lbs_c_evt_type_t; + + +/**@brief Structure containing the Button value received from the peer. */ +typedef struct +{ + uint8_t button_state; /**< Button Value. */ +} ble_button_t; + + +/**@brief Structure containing the handles related to the LED Button Service found on the peer. */ +typedef struct +{ + uint16_t button_cccd_handle; /**< Handle of the CCCD of the Button characteristic. */ + uint16_t button_handle; /**< Handle of the Button characteristic as provided by the SoftDevice. */ + uint16_t led_handle; /**< Handle of the LED characteristic as provided by the SoftDevice. */ +} lbs_db_t; + + +/**@brief LED Button Event structure. */ +typedef struct +{ + ble_lbs_c_evt_type_t evt_type; /**< Type of the event. */ + uint16_t conn_handle; /**< Connection handle on which the event occured.*/ + union + { + ble_button_t button; /**< Button Value received. This will be filled if the evt_type is @ref BLE_LBS_C_EVT_BUTTON_NOTIFICATION. */ + lbs_db_t peer_db; /**< LED Button Service related handles found on the peer device. This will be filled if the evt_type is @ref BLE_LBS_C_EVT_DISCOVERY_COMPLETE.*/ + } params; +} ble_lbs_c_evt_t; + + +// Forward declaration of the ble_lbs_c_t type. +typedef struct ble_lbs_c_s ble_lbs_c_t; + +/**@brief Event handler type. + * + * @details This is the type of the event handler that should be provided by the application + * of this module in order to receive events. + */ +typedef void (* ble_lbs_c_evt_handler_t) (ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_evt_t * p_evt); + + +/**@brief LED Button Client structure. */ +struct ble_lbs_c_s +{ + uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */ + lbs_db_t peer_lbs_db; /**< Handles related to LBS on the peer*/ + ble_lbs_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the LED Button service. */ + uint8_t uuid_type; /**< UUID type. */ +}; + +/**@brief LED Button Client initialization structure. */ +typedef struct +{ + ble_lbs_c_evt_handler_t evt_handler; /**< Event handler to be called by the LED Button Client module whenever there is an event related to the LED Button Service. */ +} ble_lbs_c_init_t; + + +/**@brief Function for initializing the LED Button client module. + * + * @details This function will register with the DB Discovery module. There it registers for the + * LED Button Service. Doing so will make the DB Discovery module look for the presence + * of a LED Button Service instance at the peer when a discovery is started. + * + * @param[in] p_ble_lbs_c Pointer to the LED Button client structure. + * @param[in] p_ble_lbs_c_init Pointer to the LED Button initialization structure containing the + * initialization information. + * + * @retval NRF_SUCCESS On successful initialization. Otherwise an error code. This function + * propagates the error code returned by the Database Discovery module API + * @ref ble_db_discovery_evt_register. + */ +uint32_t ble_lbs_c_init(ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_init_t * p_ble_lbs_c_init); + +/**@brief Function for handling BLE events from the SoftDevice. + * + * @details This function will handle the BLE events received from the SoftDevice. If a BLE event + * is relevant to the LED Button Client module, then it uses it to update interval + * variables and, if necessary, send events to the application. + * + * @param[in] p_ble_lbs_c Pointer to the LED button client structure. + * @param[in] p_ble_evt Pointer to the BLE event. + */ +void ble_lbs_c_on_ble_evt(ble_lbs_c_t * p_ble_lbs_c, const ble_evt_t * p_ble_evt); + + +/**@brief Function for requesting the peer to start sending notification of the Button + * Characteristic. + * + * @details This function will enable to notification of the Button at the peer + * by writing to the CCCD of the Button Characteristic. + * + * @param[in] p_ble_lbs_c Pointer to the LED Button Client structure. + * + * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer. + * Otherwise, an error code. This function propagates the error code returned + * by the SoftDevice API @ref sd_ble_gattc_write. + * NRF_ERROR_INVALID_STATE if no connection handle has been assigned (@ref ble_lbs_c_handles_assign) + * NRF_ERROR_NULL if the given parameter is NULL + */ +uint32_t ble_lbs_c_button_notif_enable(ble_lbs_c_t * p_ble_lbs_c); + + +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery module. This + * function will handle an event from the database discovery module, and determine if it + * relates to the discovery of LED Button service at the peer. If so, it will call the + * application's event handler indicating that the LED Button service has been discovered + * at the peer. It also populates the event with the service related information before + * providing it to the application. + * + * @param[in] p_ble_lbs_c Pointer to the LED Button client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + */ +void ble_lbs_on_db_disc_evt(ble_lbs_c_t * p_ble_lbs_c, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for assigning a Handles to this instance of lbs_c. + * + * @details Call this function when a link has been established with a peer to associate this link + * to this instance of the module. This makes it possible to handle several links and + * associate each link to a particular instance of this module. + * + * @param[in] p_ble_lbs_c Pointer to the LED Button client structure instance to associate. + * @param[in] conn_handle Connection handle to associate with the given LED Button Client Instance. + * @param[in] p_peer_handles LED Button Service handles found on the peer (from @ref BLE_LBS_C_EVT_DISCOVERY_COMPLETE event). + * + */ +uint32_t ble_lbs_c_handles_assign(ble_lbs_c_t * p_ble_lbs_c, + uint16_t conn_handle, + const lbs_db_t * p_peer_handles); + + +/**@brief Function for writing the LED status to the connected server. + * + * @param[in] p_ble_lbs_c Pointer to the LED Button client structure. + * @param[in] status LED status to send. + * + * @retval NRF_SUCCESS If the staus was sent successfully. Otherwise, an error code is returned. + */ +uint32_t ble_lbs_led_status_send(ble_lbs_c_t * p_ble_lbs_c, uint8_t status); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_LBS_C_H__ + +/** @} */ diff --git a/components/ble/ble_services/ble_lls/ble_lls.c b/components/ble/ble_services/ble_lls/ble_lls.c index bdc1ca8..9217720 100644 --- a/components/ble/ble_services/ble_lls/ble_lls.c +++ b/components/ble/ble_services/ble_lls/ble_lls.c @@ -1,20 +1,49 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_LLS) #include "ble_lls.h" #include #include "ble_hci.h" @@ -212,3 +241,4 @@ uint32_t ble_lls_alert_level_get(ble_lls_t * p_lls, uint8_t * p_alert_level) p_lls->alert_level_handles.value_handle, &gatts_value); } +#endif // NRF_MODULE_ENABLED(BLE_LLS) diff --git a/components/ble/ble_services/ble_lls/ble_lls.h b/components/ble/ble_services/ble_lls/ble_lls.h index 8a3e2cb..3d44566 100644 --- a/components/ble/ble_services/ble_lls/ble_lls.h +++ b/components/ble/ble_services/ble_lls/ble_lls.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_lls Link Loss Service + * @defgroup ble_lls Link Loss Service * @{ * @ingroup ble_sdk_srv * @brief Link Loss Service module. @@ -21,8 +49,8 @@ * During initialization it adds the Link Loss Service and Alert Level characteristic * to the BLE stack database. * - * The application must supply an event handler for receiving Link Loss Service - * events. Using this handler, the service will notify the application when the + * The application must supply an event handler for receiving Link Loss Service + * events. Using this handler, the service will notify the application when the * link has been lost, and which Alert Level has been set. * * The service also provides a function for letting the application poll the current @@ -31,8 +59,8 @@ * @note The application must propagate BLE stack events to the Link Loss Service * module by calling ble_lls_on_ble_evt() from the @ref softdevice_handler callback. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -43,6 +71,10 @@ #include "ble.h" #include "ble_srv_common.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Link Loss Service event type. */ typedef enum { @@ -111,6 +143,11 @@ void ble_lls_on_ble_evt(ble_lls_t * p_lls, ble_evt_t * p_ble_evt); */ uint32_t ble_lls_alert_level_get(ble_lls_t * p_lls, uint8_t * p_alert_level); + +#ifdef __cplusplus +} +#endif + #endif // BLE_LLS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_nus/ble_nus.c b/components/ble/ble_services/ble_nus/ble_nus.c index f92c223..27ac2a2 100644 --- a/components/ble/ble_services/ble_nus/ble_nus.c +++ b/components/ble/ble_services/ble_nus/ble_nus.c @@ -1,18 +1,45 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_NUS) #include "ble_nus.h" -#include -#include "nordic_common.h" #include "ble_srv_common.h" #define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */ @@ -232,10 +259,8 @@ uint32_t ble_nus_init(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init) ble_uuid_t ble_uuid; ble_uuid128_t nus_base_uuid = NUS_BASE_UUID; - if ((p_nus == NULL) || (p_nus_init == NULL)) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(p_nus); + VERIFY_PARAM_NOT_NULL(p_nus_init); // Initialize the service structure. p_nus->conn_handle = BLE_CONN_HANDLE_INVALID; @@ -245,10 +270,7 @@ uint32_t ble_nus_init(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init) /**@snippet [Adding proprietary Service to S110 SoftDevice] */ // Add a custom base UUID. err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_nus->uuid_type); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); ble_uuid.type = p_nus->uuid_type; ble_uuid.uuid = BLE_UUID_NUS_SERVICE; @@ -258,24 +280,15 @@ uint32_t ble_nus_init(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init) &ble_uuid, &p_nus->service_handle); /**@snippet [Adding proprietary Service to S110 SoftDevice] */ - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Add the RX Characteristic. err_code = rx_char_add(p_nus, p_nus_init); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Add the TX Characteristic. err_code = tx_char_add(p_nus, p_nus_init); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); return NRF_SUCCESS; } @@ -285,10 +298,7 @@ uint32_t ble_nus_string_send(ble_nus_t * p_nus, uint8_t * p_string, uint16_t len { ble_gatts_hvx_params_t hvx_params; - if (p_nus == NULL) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(p_nus); if ((p_nus->conn_handle == BLE_CONN_HANDLE_INVALID) || (!p_nus->is_notification_enabled)) { @@ -310,4 +320,4 @@ uint32_t ble_nus_string_send(ble_nus_t * p_nus, uint8_t * p_string, uint16_t len return sd_ble_gatts_hvx(p_nus->conn_handle, &hvx_params); } - +#endif // NRF_MODULE_ENABLED(BLE_NUS) diff --git a/components/ble/ble_services/ble_nus/ble_nus.h b/components/ble/ble_services/ble_nus/ble_nus.h index 01ec813..b52d44e 100644 --- a/components/ble/ble_services/ble_nus/ble_nus.h +++ b/components/ble/ble_services/ble_nus/ble_nus.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_nus Nordic UART Service + * @defgroup ble_nus Nordic UART Service * @{ * @ingroup ble_sdk_srv * @brief Nordic UART Service implementation. @@ -21,11 +49,11 @@ * Data received from the peer is passed to the application, and the data received * from the application of this service is sent to the peer as Handle Value * Notifications. This module demonstrates how to implement a custom GATT-based - * service and characteristics using the S110 SoftDevice. The service + * service and characteristics using the SoftDevice. The service * is used by the application to send and receive ASCII text strings to and from the * peer. * - * @note The application must propagate S110 SoftDevice events to the Nordic UART Service module + * @note The application must propagate SoftDevice events to the Nordic UART Service module * by calling the ble_nus_on_ble_evt() function from the ble_stack_handler callback. */ @@ -37,6 +65,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + #define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */ #define BLE_NUS_MAX_DATA_LEN (GATT_MTU_SIZE_DEFAULT - 3) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ @@ -64,10 +96,10 @@ typedef struct struct ble_nus_s { uint8_t uuid_type; /**< UUID type for Nordic UART Service Base UUID. */ - uint16_t service_handle; /**< Handle of Nordic UART Service (as provided by the S110 SoftDevice). */ - ble_gatts_char_handles_t tx_handles; /**< Handles related to the TX characteristic (as provided by the S110 SoftDevice). */ - ble_gatts_char_handles_t rx_handles; /**< Handles related to the RX characteristic (as provided by the S110 SoftDevice). */ - uint16_t conn_handle; /**< Handle of the current connection (as provided by the S110 SoftDevice). BLE_CONN_HANDLE_INVALID if not in a connection. */ + uint16_t service_handle; /**< Handle of Nordic UART Service (as provided by the SoftDevice). */ + ble_gatts_char_handles_t tx_handles; /**< Handles related to the TX characteristic (as provided by the SoftDevice). */ + ble_gatts_char_handles_t rx_handles; /**< Handles related to the RX characteristic (as provided by the SoftDevice). */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the SoftDevice). BLE_CONN_HANDLE_INVALID if not in a connection. */ bool is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/ ble_nus_data_handler_t data_handler; /**< Event handler to be called for handling received data. */ }; @@ -87,12 +119,12 @@ uint32_t ble_nus_init(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init); /**@brief Function for handling the Nordic UART Service's BLE events. * * @details The Nordic UART Service expects the application to call this function each time an - * event is received from the S110 SoftDevice. This function processes the event if it + * event is received from the SoftDevice. This function processes the event if it * is relevant and calls the Nordic UART Service event handler of the * application if necessary. * * @param[in] p_nus Nordic UART Service structure. - * @param[in] p_ble_evt Event received from the S110 SoftDevice. + * @param[in] p_ble_evt Event received from the SoftDevice. */ void ble_nus_on_ble_evt(ble_nus_t * p_nus, ble_evt_t * p_ble_evt); @@ -109,6 +141,11 @@ void ble_nus_on_ble_evt(ble_nus_t * p_nus, ble_evt_t * p_ble_evt); */ uint32_t ble_nus_string_send(ble_nus_t * p_nus, uint8_t * p_string, uint16_t length); + +#ifdef __cplusplus +} +#endif + #endif // BLE_NUS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_nus_c/ble_nus_c.c b/components/ble/ble_services/ble_nus_c/ble_nus_c.c index c424356..78006bf 100644 --- a/components/ble/ble_services/ble_nus_c/ble_nus_c.c +++ b/components/ble/ble_services/ble_nus_c/ble_nus_c.c @@ -1,71 +1,91 @@ -#include +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_NUS_C) #include // definition of NULL #include "ble.h" #include "ble_nus_c.h" -#include "ble_db_discovery.h" #include "ble_gattc.h" #include "ble_srv_common.h" -#include "nordic_common.h" #include "app_error.h" -static ble_nus_c_t * mp_ble_nus_c; - -/**@brief Function for handling events from the database discovery module. - * - * @details This function will handle an event from the database discovery module, and determine - * if it relates to the discovery of NUS at the peer. If so, it will - * call the application's event handler indicating that the NUS has been - * discovered at the peer. It also populates the event with the service related - * information before providing it to the application. - * - * @param[in] p_evt Pointer to the event received from the database discovery module. - * - */ -static void db_discover_evt_handler(ble_db_discovery_evt_t * p_evt) +void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt) { + ble_nus_c_evt_t nus_c_evt; + memset(&nus_c_evt,0,sizeof(ble_nus_c_evt_t)); + + ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics; + // Check if the NUS was discovered. if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_NUS_SERVICE && - p_evt->params.discovered_db.srv_uuid.type == mp_ble_nus_c->uuid_type) + p_evt->params.discovered_db.srv_uuid.type == p_ble_nus_c->uuid_type) { uint32_t i; for (i = 0; i < p_evt->params.discovered_db.char_count; i++) { - if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid - == BLE_UUID_NUS_TX_CHARACTERISTIC) - { - mp_ble_nus_c->nus_tx_handle = - p_evt->params.discovered_db.charateristics[i].characteristic.handle_value; - - if (mp_ble_nus_c->evt_handler != NULL) - { - ble_nus_c_evt_t nus_c_evt; - - nus_c_evt.evt_type = BLE_NUS_C_EVT_FOUND_NUS_TX_CHARACTERISTIC; - mp_ble_nus_c->evt_handler(mp_ble_nus_c, &nus_c_evt); - } - } - else if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid - == BLE_UUID_NUS_RX_CHARACTERISTIC) + switch (p_chars[i].characteristic.uuid.uuid) { - mp_ble_nus_c->nus_rx_handle = - p_evt->params.discovered_db.charateristics[i].characteristic.handle_value; - mp_ble_nus_c->nus_rx_cccd_handle = - p_evt->params.discovered_db.charateristics[i].cccd_handle; - - if (mp_ble_nus_c->evt_handler != NULL) - { - ble_nus_c_evt_t nus_c_evt; - - nus_c_evt.evt_type = BLE_NUS_C_EVT_FOUND_NUS_RX_CHARACTERISTIC; - mp_ble_nus_c->evt_handler(mp_ble_nus_c, &nus_c_evt); - } + case BLE_UUID_NUS_TX_CHARACTERISTIC: + nus_c_evt.handles.nus_tx_handle = p_chars[i].characteristic.handle_value; + break; + + case BLE_UUID_NUS_RX_CHARACTERISTIC: + nus_c_evt.handles.nus_rx_handle = p_chars[i].characteristic.handle_value; + nus_c_evt.handles.nus_rx_cccd_handle = p_chars[i].cccd_handle; + break; + + default: + break; } } + if (p_ble_nus_c->evt_handler != NULL) + { + nus_c_evt.conn_handle = p_evt->conn_handle; + nus_c_evt.evt_type = BLE_NUS_C_EVT_DISCOVERY_COMPLETE; + p_ble_nus_c->evt_handler(p_ble_nus_c, &nus_c_evt); + } } } @@ -82,8 +102,8 @@ static void db_discover_evt_handler(ble_db_discovery_evt_t * p_evt) static void on_hvx(ble_nus_c_t * p_ble_nus_c, const ble_evt_t * p_ble_evt) { // HVX can only occur from client sending. - if ( (p_ble_nus_c->nus_rx_handle != BLE_GATT_HANDLE_INVALID) - && (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_nus_c->nus_rx_handle) + if ( (p_ble_nus_c->handles.nus_rx_handle != BLE_GATT_HANDLE_INVALID) + && (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_nus_c->handles.nus_rx_handle) && (p_ble_nus_c->evt_handler != NULL) ) { @@ -102,30 +122,22 @@ uint32_t ble_nus_c_init(ble_nus_c_t * p_ble_nus_c, ble_nus_c_init_t * p_ble_nus_ uint32_t err_code; ble_uuid_t uart_uuid; ble_uuid128_t nus_base_uuid = NUS_BASE_UUID; - - if ((p_ble_nus_c == NULL) || (p_ble_nus_c_init == NULL)) - { - return NRF_ERROR_NULL; - } - + + VERIFY_PARAM_NOT_NULL(p_ble_nus_c); + VERIFY_PARAM_NOT_NULL(p_ble_nus_c_init); + err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_ble_nus_c->uuid_type); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - + VERIFY_SUCCESS(err_code); + uart_uuid.type = p_ble_nus_c->uuid_type; uart_uuid.uuid = BLE_UUID_NUS_SERVICE; - - // save the pointer to the ble_uart_c_t struct locally - mp_ble_nus_c = p_ble_nus_c; - - p_ble_nus_c->conn_handle = BLE_CONN_HANDLE_INVALID; - p_ble_nus_c->evt_handler = p_ble_nus_c_init->evt_handler; - p_ble_nus_c->nus_rx_handle = BLE_GATT_HANDLE_INVALID; - p_ble_nus_c->nus_tx_handle = BLE_GATT_HANDLE_INVALID; - - return ble_db_discovery_evt_register(&uart_uuid, db_discover_evt_handler); + + p_ble_nus_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_nus_c->evt_handler = p_ble_nus_c_init->evt_handler; + p_ble_nus_c->handles.nus_rx_handle = BLE_GATT_HANDLE_INVALID; + p_ble_nus_c->handles.nus_tx_handle = BLE_GATT_HANDLE_INVALID; + + return ble_db_discovery_evt_register(&uart_uuid); } void ble_nus_c_on_ble_evt(ble_nus_c_t * p_ble_nus_c, const ble_evt_t * p_ble_evt) @@ -134,28 +146,28 @@ void ble_nus_c_on_ble_evt(ble_nus_c_t * p_ble_nus_c, const ble_evt_t * p_ble_evt { return; } - - if ( (p_ble_nus_c->conn_handle != BLE_CONN_HANDLE_INVALID) + + if ( (p_ble_nus_c->conn_handle != BLE_CONN_HANDLE_INVALID) &&(p_ble_nus_c->conn_handle != p_ble_evt->evt.gap_evt.conn_handle) ) { return; } - + switch (p_ble_evt->header.evt_id) { case BLE_GATTC_EVT_HVX: on_hvx(p_ble_nus_c, p_ble_evt); break; - + case BLE_GAP_EVT_DISCONNECTED: if (p_ble_evt->evt.gap_evt.conn_handle == p_ble_nus_c->conn_handle && p_ble_nus_c->evt_handler != NULL) { ble_nus_c_evt_t nus_c_evt; - + nus_c_evt.evt_type = BLE_NUS_C_EVT_DISCONNECTED; - + p_ble_nus_c->conn_handle = BLE_CONN_HANDLE_INVALID; p_ble_nus_c->evt_handler(p_ble_nus_c, &nus_c_evt); } @@ -168,10 +180,10 @@ void ble_nus_c_on_ble_evt(ble_nus_c_t * p_ble_nus_c, const ble_evt_t * p_ble_evt static uint32_t cccd_configure(uint16_t conn_handle, uint16_t cccd_handle, bool enable) { uint8_t buf[BLE_CCCD_VALUE_LEN]; - + buf[0] = enable ? BLE_GATT_HVX_NOTIFICATION : 0; buf[1] = 0; - + const ble_gattc_write_params_t write_params = { .write_op = BLE_GATT_OP_WRITE_REQ, .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE, @@ -186,26 +198,21 @@ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t cccd_handle, bool uint32_t ble_nus_c_rx_notif_enable(ble_nus_c_t * p_ble_nus_c) { - if (p_ble_nus_c == NULL) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(p_ble_nus_c); + if ( (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID) - ||(p_ble_nus_c->nus_rx_cccd_handle == BLE_GATT_HANDLE_INVALID) + ||(p_ble_nus_c->handles.nus_rx_cccd_handle == BLE_GATT_HANDLE_INVALID) ) { return NRF_ERROR_INVALID_STATE; } - return cccd_configure(p_ble_nus_c->conn_handle,p_ble_nus_c->nus_rx_cccd_handle, true); + return cccd_configure(p_ble_nus_c->conn_handle,p_ble_nus_c->handles.nus_rx_cccd_handle, true); } uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length) { - if (p_ble_nus_c == NULL) - { - return NRF_ERROR_NULL; - } - + VERIFY_PARAM_NOT_NULL(p_ble_nus_c); + if (length > BLE_NUS_MAX_DATA_LEN) { return NRF_ERROR_INVALID_PARAM; @@ -214,15 +221,33 @@ uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, ui { return NRF_ERROR_INVALID_STATE; } - + const ble_gattc_write_params_t write_params = { .write_op = BLE_GATT_OP_WRITE_CMD, .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE, - .handle = p_ble_nus_c->nus_tx_handle, + .handle = p_ble_nus_c->handles.nus_tx_handle, .offset = 0, .len = length, .p_value = p_string }; - + return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params); } + + +uint32_t ble_nus_c_handles_assign(ble_nus_c_t * p_ble_nus, + const uint16_t conn_handle, + const ble_nus_c_handles_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ble_nus); + + p_ble_nus->conn_handle = conn_handle; + if (p_peer_handles != NULL) + { + p_ble_nus->handles.nus_rx_cccd_handle = p_peer_handles->nus_rx_cccd_handle; + p_ble_nus->handles.nus_rx_handle = p_peer_handles->nus_rx_handle; + p_ble_nus->handles.nus_tx_handle = p_peer_handles->nus_tx_handle; + } + return NRF_SUCCESS; +} +#endif // NRF_MODULE_ENABLED(BLE_NUS_C) diff --git a/components/ble/ble_services/ble_nus_c/ble_nus_c.h b/components/ble/ble_services/ble_nus_c/ble_nus_c.h index a81d281..fef1b53 100644 --- a/components/ble/ble_services/ble_nus_c/ble_nus_c.h +++ b/components/ble/ble_services/ble_nus_c/ble_nus_c.h @@ -1,15 +1,46 @@ -/* - * Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_nus_c Nordic UART Service Client + * @defgroup ble_nus_c Nordic UART Service Client * @{ * @ingroup ble_sdk_srv * @brief Nordic UART Service Client module. @@ -27,10 +58,15 @@ #ifndef BLE_NUS_C_H__ #define BLE_NUS_C_H__ -#include "ble.h" -#include "ble_gatt.h" #include #include +#include "ble.h" +#include "ble_gatt.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif #define NUS_BASE_UUID {{0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}} /**< Used vendor specific UUID. */ #define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */ @@ -39,33 +75,32 @@ #define BLE_NUS_MAX_DATA_LEN (GATT_MTU_SIZE_DEFAULT - 3) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */ -/** - * @defgroup hrs_c_enums Enumerations - * @{ - */ /**@brief NUS Client event type. */ -typedef enum +typedef enum { - BLE_NUS_C_EVT_FOUND_NUS_TX_CHARACTERISTIC = 1, /**< Event indicating that the TX characteristic was found. */ - BLE_NUS_C_EVT_FOUND_NUS_RX_CHARACTERISTIC, /**< Event indicating that the RX characteristic was found. */ - BLE_NUS_C_EVT_NUS_RX_EVT, /**< Event indicating that the central has received something from a peer. */ - BLE_NUS_C_EVT_DISCONNECTED /**< Event indicating that the NUS server has disconnected. */ + BLE_NUS_C_EVT_DISCOVERY_COMPLETE = 1, /**< Event indicating that the NUS service and its characteristics was found. */ + BLE_NUS_C_EVT_NUS_RX_EVT, /**< Event indicating that the central has received something from a peer. */ + BLE_NUS_C_EVT_DISCONNECTED /**< Event indicating that the NUS server has disconnected. */ } ble_nus_c_evt_type_t; -/** @} */ +/**@brief Handles on the connected peer device needed to interact with it. +*/ +typedef struct { + uint16_t nus_rx_handle; /**< Handle of the NUS RX characteristic as provided by a discovery. */ + uint16_t nus_rx_cccd_handle; /**< Handle of the CCCD of the NUS RX characteristic as provided by a discovery. */ + uint16_t nus_tx_handle; /**< Handle of the NUS TX characteristic as provided by a discovery. */ +} ble_nus_c_handles_t; -/** - * @defgroup hrs_c_structs Structures - * @{ - */ /**@brief Structure containing the NUS event data received from the peer. */ typedef struct { ble_nus_c_evt_type_t evt_type; - uint8_t * p_data; + uint16_t conn_handle; + uint8_t * p_data; uint8_t data_len; + ble_nus_c_handles_t handles; /**< Handles on which the Nordic Uart service characteristics was discovered on the peer device. This will be filled if the evt_type is @ref BLE_NUS_C_EVT_DISCOVERY_COMPLETE.*/ } ble_nus_c_evt_t; @@ -85,10 +120,8 @@ typedef void (* ble_nus_c_evt_handler_t)(ble_nus_c_t * p_ble_nus_c, const ble_nu struct ble_nus_c_s { uint8_t uuid_type; /**< UUID type. */ - uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */ - uint16_t nus_rx_handle; /**< Handle of the NUS RX characteristic as provided by a discovery. */ - uint16_t nus_rx_cccd_handle; /**< Handle of the CCCD of the NUS RX characteristic as provided by a discovery. */ - uint16_t nus_tx_handle; /**< Handle of the NUS TX characteristic as provided by a discovery. */ + uint16_t conn_handle; /**< Handle of the current connection. Set with @ref ble_nus_c_handles_assign when connected. */ + ble_nus_c_handles_t handles; /**< Handles on the connected peer device needed to interact with it. */ ble_nus_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the NUS. */ }; @@ -98,13 +131,6 @@ typedef struct { ble_nus_c_evt_handler_t evt_handler; } ble_nus_c_init_t; -/** @} */ - - -/** - * @defgroup nus_c_functions Functions - * @{ - */ /**@brief Function for initializing the Nordic UART client module. * @@ -117,13 +143,28 @@ typedef struct { * @param[in] p_ble_nus_c_init Pointer to the NUS initialization structure containing the * initialization information. * - * @retval NRF_SUCCESS If the module was initialized successfully. Otherwise, an error + * @retval NRF_SUCCESS If the module was initialized successfully. Otherwise, an error * code is returned. This function * propagates the error code returned by the Database Discovery module API * @ref ble_db_discovery_evt_register. */ uint32_t ble_nus_c_init(ble_nus_c_t * p_ble_nus_c, ble_nus_c_init_t * p_ble_nus_c_init); + +/**@brief Function for handling events from the database discovery module. + * + * @details This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of NUS at the peer. If so, it will + * call the application's event handler indicating that NUS has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param[in] p_ble_nus_c Pointer to the NUS client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + */ + void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt); + + /**@brief Function for handling BLE events from the SoftDevice. * * @details This function handles the BLE events received from the SoftDevice. If a BLE @@ -143,7 +184,7 @@ void ble_nus_c_on_ble_evt(ble_nus_c_t * p_ble_nus_c, const ble_evt_t * p_ble_evt * @param p_ble_nus_c Pointer to the NUS client structure. * * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer. - * Otherwise, an error code is returned. This function propagates the error + * Otherwise, an error code is returned. This function propagates the error * code returned by the SoftDevice API @ref sd_ble_gattc_write. */ uint32_t ble_nus_c_rx_notif_enable(ble_nus_c_t * p_ble_nus_c); @@ -160,7 +201,31 @@ uint32_t ble_nus_c_rx_notif_enable(ble_nus_c_t * p_ble_nus_c); */ uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length); -/** @} */ + +/**@brief Function for assigning handles to a this instance of nus_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_NUS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ble_nus_c Pointer to the NUS client structure instance to associate with these + * handles. + * @param[in] conn_handle Connection handle to associated with the given NUS Instance. + * @param[in] p_peer_handles Attribute handles on the NUS server that you want this NUS client to + * interact with. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If a p_nus was a NULL pointer. + */ +uint32_t ble_nus_c_handles_assign(ble_nus_c_t * p_ble_nus_c, const uint16_t conn_handle, const ble_nus_c_handles_t * p_peer_handles); + + + +#ifdef __cplusplus +} +#endif #endif // BLE_NUS_C_H__ diff --git a/components/ble/ble_services/ble_rscs/ble_rscs.c b/components/ble/ble_services/ble_rscs/ble_rscs.c index eac2bf5..b4c8473 100644 --- a/components/ble/ble_services/ble_rscs/ble_rscs.c +++ b/components/ble/ble_services/ble_rscs/ble_rscs.c @@ -1,26 +1,53 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_RSCS) #include "ble_rscs.h" #include -#include "nordic_common.h" #include "ble_l2cap.h" #include "ble_srv_common.h" -#include "app_util.h" #define OPCODE_LENGTH 1 /**< Length of opcode inside Running Speed and Cadence Measurement packet. */ #define HANDLE_LENGTH 2 /**< Length of handle inside Running Speed and Cadence Measurement packet. */ @@ -106,7 +133,7 @@ void ble_rscs_on_ble_evt(ble_rscs_t * p_rscs, ble_evt_t * p_ble_evt) { return; } - + switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: @@ -303,7 +330,7 @@ uint32_t ble_rscs_init(ble_rscs_t * p_rscs, const ble_rscs_init_t * p_rscs_init) { return NRF_ERROR_NULL; } - + uint32_t err_code; ble_uuid_t ble_uuid; @@ -348,7 +375,7 @@ uint32_t ble_rscs_measurement_send(ble_rscs_t * p_rscs, ble_rscs_meas_t * p_meas { return NRF_ERROR_NULL; } - + uint32_t err_code; // Send value if connected and notifying @@ -383,3 +410,4 @@ uint32_t ble_rscs_measurement_send(ble_rscs_t * p_rscs, ble_rscs_meas_t * p_meas return err_code; } +#endif // NRF_MODULE_ENABLED(BLE_RSCS) diff --git a/components/ble/ble_services/ble_rscs/ble_rscs.h b/components/ble/ble_services/ble_rscs/ble_rscs.h index 4c5c2d9..fd322d9 100644 --- a/components/ble/ble_services/ble_rscs/ble_rscs.h +++ b/components/ble/ble_services/ble_rscs/ble_rscs.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_rsc Running Speed and Cadence Service + * @defgroup ble_rscs Running Speed and Cadence Service * @{ * @ingroup ble_sdk_srv * @brief Running Speed and Cadence Service module. @@ -27,8 +55,8 @@ * @note The application must propagate BLE stack events to the Running Speead and Candence Service * module by calling ble_rscs_on_ble_evt() from the @ref softdevice_handler function. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -40,6 +68,10 @@ #include "ble.h" #include "ble_srv_common.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Running Speed and Cadence Service feature bits. */ #define BLE_RSCS_FEATURE_INSTANT_STRIDE_LEN_BIT (0x01 << 0) /**< Instantaneous Stride Length Measurement Supported bit. */ #define BLE_RSCS_FEATURE_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Total Distance Measurement Supported bit. */ @@ -60,7 +92,7 @@ typedef struct ble_rscs_evt_type_t evt_type; /**< Type of event. */ } ble_rscs_evt_t; -// Forward declaration of the ble_rsc types. +// Forward declaration of the ble_rsc types. typedef struct ble_rscs_s ble_rscs_t; typedef struct ble_rscs_meas_s ble_rscs_meas_t; @@ -88,7 +120,7 @@ typedef struct ble_srv_cccd_security_mode_t rsc_meas_attr_md; /**< Initial security level for running speed and cadence measurement attribute */ ble_srv_security_mode_t rsc_feature_attr_md; /**< Initial security level for feature attribute */ uint16_t feature; /**< Initial value for features of sensor. */ - ble_rscs_meas_t initial_rcm; /**< Initial Running Speed Cadence Measurement.*/ + ble_rscs_meas_t initial_rcm; /**< Initial Running Speed Cadence Measurement.*/ } ble_rscs_init_t; /**@brief Running Speed and Cadence Service structure. This contains various status information for @@ -139,6 +171,11 @@ void ble_rscs_on_ble_evt(ble_rscs_t * p_rscs, ble_evt_t * p_ble_evt); */ uint32_t ble_rscs_measurement_send(ble_rscs_t * p_rscs, ble_rscs_meas_t * p_measurement); + +#ifdef __cplusplus +} +#endif + #endif // BLE_RSCS_H__ /** @} */ diff --git a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c b/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c index 8f200a2..5f4c4f0 100644 --- a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c +++ b/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c @@ -1,28 +1,56 @@ -/* - * Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /**@cond To Make Doxygen skip documentation generation for this file. * @{ */ - -#include +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_RSCS_C) #include "ble_rscs_c.h" #include "ble_db_discovery.h" #include "ble_types.h" #include "ble_srv_common.h" -#include "nordic_common.h" -#include "nrf_error.h" #include "ble_gattc.h" -#include "app_util.h" -#include "app_trace.h" -#define LOG app_trace_log /**< Debug logger macro that will be used in this file to do logging of important information over UART. */ +#define NRF_LOG_MODULE_NAME "BLE_RSCS_C" +#include "nrf_log.h" #define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of continuous zeroes, followed by continuous sequence of ones: 000...111. */ #define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */ @@ -57,7 +85,6 @@ typedef struct } tx_message_t; -static ble_rscs_c_t * mp_ble_rscs_c; /**< Pointer to the current instance of the HRS Client module. The memory for this provided by the application.*/ static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */ static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */ static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */ @@ -84,13 +111,13 @@ static void tx_buffer_process(void) } if (err_code == NRF_SUCCESS) { - LOG("[RSCS_C]: SD Read/Write API returns Success.\r\n"); + NRF_LOG_INFO("SD Read/Write API returns Success.\r\n"); m_tx_index++; m_tx_index &= TX_BUFFER_MASK; } else { - LOG("[RSCS_C]: SD Read/Write API returns error. This message sending will be " + NRF_LOG_INFO("SD Read/Write API returns error. This message sending will be " "attempted again..\r\n"); } } @@ -104,6 +131,11 @@ static void tx_buffer_process(void) */ static void on_write_rsp(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt) { + // Check if the event if on the link for this instance + if (p_ble_rscs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } // Check if there is any message to be sent across to the peer and send it. tx_buffer_process(); } @@ -123,15 +155,22 @@ static void on_hvx(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt) { const ble_gattc_evt_hvx_t * p_notif = &p_ble_evt->evt.gattc_evt.params.hvx; + // Check if the event if on the link for this instance + if (p_ble_rscs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle) + { + return; + } + // Check if this is a Running Speed and Cadence notification. - if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_rscs_c->rsc_handle) + if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_rscs_c->peer_db.rsc_handle) { uint32_t index = 0; ble_rscs_c_evt_t ble_rscs_c_evt; - ble_rscs_c_evt.evt_type = BLE_RSCS_C_EVT_RSC_NOTIFICATION; + ble_rscs_c_evt.evt_type = BLE_RSCS_C_EVT_RSC_NOTIFICATION; + ble_rscs_c_evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle; //lint -save -e415 -e416 -e662 "Access of out of bounds pointer" "Creation of out of bounds pointer" - + // Flags field ble_rscs_c_evt.params.rsc.is_inst_stride_len_present = p_notif->data[index] >> BLE_RSCS_INSTANT_STRIDE_LEN_PRESENT & 0x01; ble_rscs_c_evt.params.rsc.is_total_distance_present = p_notif->data[index] >> BLE_RSCS_TOTAL_DISTANCE_PRESENT & 0x01; @@ -178,14 +217,16 @@ static void on_hvx(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt) * @param[in] p_evt Pointer to the event received from the database discovery module. * */ -static void db_discover_evt_handler(ble_db_discovery_evt_t * p_evt) +void ble_rscs_on_db_disc_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_db_discovery_evt_t * p_evt) { // Check if the Heart Rate Service was discovered. if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE && p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_RUNNING_SPEED_AND_CADENCE && p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE) { - mp_ble_rscs_c->conn_handle = p_evt->conn_handle; + + ble_rscs_c_evt_t evt; + evt.conn_handle = p_evt->conn_handle; // Find the CCCD Handle of the Running Speed and Cadence characteristic. uint32_t i; @@ -196,45 +237,84 @@ static void db_discover_evt_handler(ble_db_discovery_evt_t * p_evt) BLE_UUID_RSC_MEASUREMENT_CHAR) { // Found Running Speed and Cadence characteristic. Store CCCD handle and break. - mp_ble_rscs_c->rsc_cccd_handle = + evt.params.rscs_db.rsc_cccd_handle = p_evt->params.discovered_db.charateristics[i].cccd_handle; - mp_ble_rscs_c->rsc_handle = + evt.params.rscs_db.rsc_handle = p_evt->params.discovered_db.charateristics[i].characteristic.handle_value; break; } } - LOG("[rscs_c]: Running Speed and Cadence Service discovered at peer.\r\n"); + NRF_LOG_INFO("Running Speed and Cadence Service discovered at peer.\r\n"); - ble_rscs_c_evt_t evt; + //If the instance has been assigned prior to db_discovery, assign the db_handles + if (p_ble_rscs_c->conn_handle != BLE_CONN_HANDLE_INVALID) + { + if ((p_ble_rscs_c->peer_db.rsc_cccd_handle == BLE_GATT_HANDLE_INVALID)&& + (p_ble_rscs_c->peer_db.rsc_handle == BLE_GATT_HANDLE_INVALID)) + { + p_ble_rscs_c->peer_db = evt.params.rscs_db; + } + } evt.evt_type = BLE_RSCS_C_EVT_DISCOVERY_COMPLETE; - mp_ble_rscs_c->evt_handler(mp_ble_rscs_c, &evt); + p_ble_rscs_c->evt_handler(p_ble_rscs_c, &evt); } } uint32_t ble_rscs_c_init(ble_rscs_c_t * p_ble_rscs_c, ble_rscs_c_init_t * p_ble_rscs_c_init) { - if ((p_ble_rscs_c == NULL) || (p_ble_rscs_c_init == NULL)) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(p_ble_rscs_c); + VERIFY_PARAM_NOT_NULL(p_ble_rscs_c_init); ble_uuid_t rscs_uuid; rscs_uuid.type = BLE_UUID_TYPE_BLE; rscs_uuid.uuid = BLE_UUID_RUNNING_SPEED_AND_CADENCE; - mp_ble_rscs_c = p_ble_rscs_c; + p_ble_rscs_c->evt_handler = p_ble_rscs_c_init->evt_handler; + p_ble_rscs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_rscs_c->peer_db.rsc_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_rscs_c->peer_db.rsc_handle = BLE_GATT_HANDLE_INVALID; - mp_ble_rscs_c->evt_handler = p_ble_rscs_c_init->evt_handler; - mp_ble_rscs_c->conn_handle = BLE_CONN_HANDLE_INVALID; - mp_ble_rscs_c->rsc_cccd_handle = BLE_GATT_HANDLE_INVALID; + return ble_db_discovery_evt_register(&rscs_uuid); +} - return ble_db_discovery_evt_register(&rscs_uuid, - db_discover_evt_handler); + +uint32_t ble_rscs_c_handles_assign(ble_rscs_c_t * p_ble_rscs_c, + uint16_t conn_handle, + ble_rscs_c_db_t * p_peer_handles) +{ + VERIFY_PARAM_NOT_NULL(p_ble_rscs_c); + p_ble_rscs_c->conn_handle = conn_handle; + if (p_peer_handles != NULL) + { + p_ble_rscs_c->peer_db = *p_peer_handles; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for handling Disconnected event received from the SoftDevice. + * + * @details This function check if the disconnect event is happening on the link + * associated with the current instance of the module, if so it will set its + * conn_handle to invalid. + * + * @param[in] p_ble_rscs_c Pointer to the RSC Client structure. + * @param[in] p_ble_evt Pointer to the BLE event received. + */ +static void on_disconnected(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt) +{ + if (p_ble_rscs_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle) + { + p_ble_rscs_c->conn_handle = BLE_CONN_HANDLE_INVALID; + p_ble_rscs_c->peer_db.rsc_cccd_handle = BLE_GATT_HANDLE_INVALID; + p_ble_rscs_c->peer_db.rsc_handle = BLE_GATT_HANDLE_INVALID; + } } @@ -247,10 +327,6 @@ void ble_rscs_c_on_ble_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_ switch (p_ble_evt->header.evt_id) { - case BLE_GAP_EVT_CONNECTED: - p_ble_rscs_c->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; - break; - case BLE_GATTC_EVT_HVX: on_hvx(p_ble_rscs_c, p_ble_evt); break; @@ -259,6 +335,10 @@ void ble_rscs_c_on_ble_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_ on_write_rsp(p_ble_rscs_c, p_ble_evt); break; + case BLE_GAP_EVT_DISCONNECTED: + on_disconnected(p_ble_rscs_c, p_ble_evt); + break; + default: break; } @@ -269,7 +349,7 @@ void ble_rscs_c_on_ble_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_ */ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable) { - LOG("[rscs_c]: Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", + NRF_LOG_INFO("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d\r\n", handle_cccd, conn_handle); tx_message_t * p_msg; @@ -295,14 +375,17 @@ static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool uint32_t ble_rscs_c_rsc_notif_enable(ble_rscs_c_t * p_ble_rscs_c) { - if (p_ble_rscs_c == NULL) + VERIFY_PARAM_NOT_NULL(p_ble_rscs_c); + + if (p_ble_rscs_c->conn_handle == BLE_CONN_HANDLE_INVALID) { - return NRF_ERROR_NULL; + return NRF_ERROR_INVALID_STATE; } - return cccd_configure(p_ble_rscs_c->conn_handle, p_ble_rscs_c->rsc_cccd_handle, true); + return cccd_configure(p_ble_rscs_c->conn_handle, p_ble_rscs_c->peer_db.rsc_cccd_handle, true); } /** @} * @endcond */ +#endif // NRF_MODULE_ENABLED(BLE_RSCS_C) diff --git a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h b/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h index 7151b8d..801adb5 100644 --- a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h +++ b/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h @@ -1,12 +1,56 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_RSCS_C_H__ #define BLE_RSCS_C_H__ #include #include #include "ble.h" +#include "ble_db_discovery.h" + +#ifdef __cplusplus +extern "C" { +#endif /** - * @defgroup ble_sdk_srv_rscs_c Running Speed and Cadence Service Client + * @defgroup ble_rscs_c Running Speed and Cadence Service Client * @{ * @ingroup ble_sdk_srv * @@ -18,6 +62,14 @@ * ble_rscs_c_on_ble_evt(). */ + +/**@brief Structure containing the handles related to the Running Speed and Cadence Service found on the peer. */ +typedef struct +{ + uint16_t rsc_cccd_handle; /**< Handle of the CCCD of the Running Speed and Cadence characteristic. */ + uint16_t rsc_handle; /**< Handle of the Running Speed and Cadence characteristic as provided by the SoftDevice. */ +} ble_rscs_c_db_t; + /**@brief RSCS Client event type. */ typedef enum { @@ -45,15 +97,18 @@ typedef struct typedef struct { ble_rscs_c_evt_type_t evt_type; /**< Type of the event. */ + uint16_t conn_handle; /**< Connection handle on which the rscs_c event occured.*/ union { - ble_rsc_t rsc; /**< Running Speed and Cadence measurement received. This will be filled if the evt_type is @ref BLE_RSCS_C_EVT_RSC_NOTIFICATION. */ + ble_rscs_c_db_t rscs_db; /**< Running Speed and Cadence Service related handles found on the peer device. This will be filled if the evt_type is @ref BLE_RSCS_C_EVT_DISCOVERY_COMPLETE.*/ + ble_rsc_t rsc; /**< Running Speed and Cadence measurement received. This will be filled if the evt_type is @ref BLE_RSCS_C_EVT_RSC_NOTIFICATION. */ } params; } ble_rscs_c_evt_t; // Forward declaration of the ble_rscs_c_t type. typedef struct ble_rscs_c_s ble_rscs_c_t; + /**@brief Event handler type. * * @details This is the type of the event handler that should be provided by the application @@ -66,8 +121,7 @@ typedef void (* ble_rscs_c_evt_handler_t) (ble_rscs_c_t * p_ble_rscs_c, ble_rscs struct ble_rscs_c_s { uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */ - uint16_t rsc_cccd_handle; /**< Handle of the CCCD of the Running Speed and Cadence characteristic. */ - uint16_t rsc_handle; /**< Handle of the Running Speed and Cadence characteristic as provided by the SoftDevice. */ + ble_rscs_c_db_t peer_db; /**< Handles related to RSCS on the peer*/ ble_rscs_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the Running Speed and Cadence service. */ }; @@ -78,12 +132,66 @@ typedef struct ble_rscs_c_evt_handler_t evt_handler; /**< Event handler to be called by the Running Speed and Cadence Client module whenever there is an event related to the Running Speed and Cadence Service. */ } ble_rscs_c_init_t; + +/**@brief Function for initializing the Running Speed and Cadence Service Client module. + * + * @details This function will initialize the module and set up Database Discovery to discover + * the Running Speed and Cadence Service. After calling this function, call @ref ble_db_discovery_start + * to start discovery once a link with a peer has been established. + * + * @param[out] p_ble_rscs_c Pointer to the RSC Service client structure. + * @param[in] p_ble_rscs_c_init Pointer to the RSC Service initialization structure containing + * the initialization information. + * + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NULL A parameter is NULL. + * Otherwise, an error code returned by @ref ble_db_discovery_evt_register. + */ uint32_t ble_rscs_c_init(ble_rscs_c_t * p_ble_rscs_c, ble_rscs_c_init_t * p_ble_rscs_c_init); void ble_rscs_c_on_ble_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt); uint32_t ble_rscs_c_rsc_notif_enable(ble_rscs_c_t * p_ble_rscs_c); + +/**@brief Function for handling events from the database discovery module. + * + * @details Call this function when getting a callback event from the DB discovery modue. + * This function will handle an event from the database discovery module, and determine + * if it relates to the discovery of Running Speed and Cadence service at the peer. If so, it will + * call the application's event handler indicating that the RSC service has been + * discovered at the peer. It also populates the event with the service related + * information before providing it to the application. + * + * @param p_ble_rscs_c Pointer to the Runnind Speed and Cadence Service client structure. + * @param[in] p_evt Pointer to the event received from the database discovery module. + * + */ +void ble_rscs_on_db_disc_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_db_discovery_evt_t * p_evt); + + +/**@brief Function for assigning handles to a this instance of rscs_c. + * + * @details Call this function when a link has been established with a peer to + * associate this link to this instance of the module. This makes it + * possible to handle several link and associate each link to a particular + * instance of this module. The connection handle and attribute handles will be + * provided from the discovery event @ref BLE_RSCS_C_EVT_DISCOVERY_COMPLETE. + * + * @param[in] p_ble_rscs_c Pointer to the RSC client structure instance to associate. + * @param[in] conn_handle Connection handle to associated with the given RSCS Client Instance. + * @param[in] p_peer_handles Attribute handles on the RSCS server that you want this RSCS client to + * interact with. + */ +uint32_t ble_rscs_c_handles_assign(ble_rscs_c_t * p_ble_rscs_c, + uint16_t conn_handle, + ble_rscs_c_db_t * p_peer_handles); + + +#ifdef __cplusplus +} +#endif + #endif // BLE_RSCS_C_H__ /** @} */ // End tag for the file. diff --git a/components/ble/ble_services/ble_tps/ble_tps.c b/components/ble/ble_services/ble_tps/ble_tps.c index 8b2c0c2..8a88c5d 100644 --- a/components/ble/ble_services/ble_tps/ble_tps.c +++ b/components/ble/ble_services/ble_tps/ble_tps.c @@ -1,20 +1,49 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BLE_TPS) #include "ble_tps.h" #include #include "ble_srv_common.h" @@ -137,3 +166,4 @@ uint32_t ble_tps_tx_power_level_set(ble_tps_t * p_tps, int8_t tx_power_level) p_tps->tx_power_level_handles.value_handle, &gatts_value); } +#endif // NRF_MODULE_ENABLED(BLE_TPS) diff --git a/components/ble/ble_services/ble_tps/ble_tps.h b/components/ble/ble_services/ble_tps/ble_tps.h index f0b4454..0a8af37 100644 --- a/components/ble/ble_services/ble_tps/ble_tps.h +++ b/components/ble/ble_services/ble_tps/ble_tps.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_tps TX Power Service + * @defgroup ble_tps TX Power Service * @{ * @ingroup ble_sdk_srv * @brief TX Power Service module. @@ -24,8 +52,8 @@ * It provides a function for letting the application update the TX Power Level * characteristic. * - * @note Attention! - * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile + * @note Attention! + * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -36,6 +64,10 @@ #include "ble.h" #include "ble_srv_common.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief TX Power Service init structure. This contains all options and data needed for * initialization of the service. */ typedef struct @@ -81,6 +113,11 @@ void ble_tps_on_ble_evt(ble_tps_t * p_tps, ble_evt_t * p_ble_evt); */ uint32_t ble_tps_tx_power_level_set(ble_tps_t * p_tps, int8_t tx_power_level); + +#ifdef __cplusplus +} +#endif + #endif // BLE_TPS_H__ /** @} */ diff --git a/components/ble/ble_services/experimental_ble_lns/ble_ln_common.h b/components/ble/ble_services/experimental_ble_lns/ble_ln_common.h new file mode 100644 index 0000000..db6445c --- /dev/null +++ b/components/ble/ble_services/experimental_ble_lns/ble_ln_common.h @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_sdk_srv_ln_common Location and Navigation common defines + * @{ + * @ingroup ble_sdk_srv + * @brief Location and Navigation common defines + * + * @details This module contains define values common to LNS and LNCP + */ + +#ifndef BLE_LNS_COMMON_H__ +#define BLE_LNS_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_LNS_INVALID_ROUTE 0xFFFF +#define BLE_LNS_NO_FIX 0xFF + +#define BLE_LNS_MAX_NUM_ROUTES 10 /**< The maximum number of routes. This affects memory usage only. */ +#define BLE_LNS_MAX_ROUTE_NAME_LEN (BLE_L2CAP_MTU_DEF - 5) /**< The maximum length of length of a route name. */ +#define MAX_CTRL_POINT_RESP_PARAM_LEN BLE_LNS_MAX_ROUTE_NAME_LEN + 3 /**< Maximum length of a control point response. */ + +// Location and Navigation Service feature bits +#define BLE_LNS_FEATURE_INSTANT_SPEED_SUPPORTED (0x01 << 0) /**< Instaneous Speed Supported bit. */ +#define BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED (0x01 << 1) /**< Total Distance Supported bit. */ +#define BLE_LNS_FEATURE_LOCATION_SUPPORTED (0x01 << 2) /**< Location Supported bit. */ +#define BLE_LNS_FEATURE_ELEVATION_SUPPORTED (0x01 << 3) /**< Elevation Supported bit. */ +#define BLE_LNS_FEATURE_HEADING_SUPPORTED (0x01 << 4) /**< Heading Supported bit. */ +#define BLE_LNS_FEATURE_ROLLING_TIME_SUPPORTED (0x01 << 5) /**< Rolling Time Supported bit. */ +#define BLE_LNS_FEATURE_UTC_TIME_SUPPORTED (0x01 << 6) /**< UTC Time Supported bit. */ +#define BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED (0x01 << 7) /**< Remaining Distance Supported bit. */ +#define BLE_LNS_FEATURE_REMAINING_VERT_DISTANCE_SUPPORTED (0x01 << 8) /**< Remaining Vertical Distance Supported bit. */ +#define BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED (0x01 << 9) /**< Estimated Time of Arrival Supported bit. */ +#define BLE_LNS_FEATURE_NUM_SATS_IN_SOLUTION_SUPPORTED (0x01 << 10) /**< Number of Satellites in Solution Supported bit. */ +#define BLE_LNS_FEATURE_NUM_SATS_IN_VIEW_SUPPORTED (0x01 << 11) /**< Number of Satellites in View Supported bit. */ +#define BLE_LNS_FEATURE_TIME_TO_FIRST_FIX_SUPPORTED (0x01 << 12) /**< Time to First Fix Supported bit. */ +#define BLE_LNS_FEATURE_EST_HORZ_POS_ERROR_SUPPORTED (0x01 << 13) /**< Estimated Horizontal Position Error Supported bit. */ +#define BLE_LNS_FEATURE_EST_VERT_POS_ERROR_SUPPORTED (0x01 << 14) /**< Estimated Vertical Position Error Supported bit. */ +#define BLE_LNS_FEATURE_HORZ_DILUTION_OF_PRECISION_SUPPORTED (0x01 << 15) /**< Horizontal Dilution of Precision Supported bit. */ +#define BLE_LNS_FEATURE_VERT_DILUTION_OF_PRECISION_SUPPORTED (0x01 << 16) /**< Vertical Dilution of Precision Supported bit. */ +#define BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED (0x01 << 17) /**< Location and Speed Characteristic Content Masking Supported bit. */ +#define BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED (0x01 << 18) /**< Fix Rate Setting Supported bit. */ +#define BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED (0x01 << 19) /**< Elevation Setting Supported bit. */ +#define BLE_LNS_FEATURE_POSITION_STATUS_SUPPORTED (0x01 << 20) /**< Position Status Supported bit. */ + + +#ifdef __cplusplus +} +#endif + +#endif /* BLE_LNS_COMMON_H__ */ + +/** @} */ diff --git a/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c b/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c new file mode 100644 index 0000000..560dffa --- /dev/null +++ b/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c @@ -0,0 +1,821 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_ln_cp.h" +#include "ble_ln_db.h" +#include "ble_ln_common.h" +#include "sdk_common.h" + +#define NRF_LOG_MODULE_NAME "BLE_LN_CP" +#include "nrf_log.h" + +// Feature Mask bits +#define FEATURE_MASK_INSTANTANEOUS_SPEED (0x01 << 0) /**< Instantaneous Speed mask bit. */ +#define FEATURE_MASK_TOTAL_DISTANCE (0x01 << 1) /**< Total Distance mask bit. */ +#define FEATURE_MASK_LOCATION (0x01 << 2) /**< Location mask bit. */ +#define FEATURE_MASK_ELEVATION (0x01 << 3) /**< Elevation mask bit. */ +#define FEATURE_MASK_HEADING (0x01 << 4) /**< Heading mask bit. */ +#define FEATURE_MASK_ROLLING_TIME (0x01 << 5) /**< Rolling Time mask bit. */ +#define FEATURE_MASK_UTC_TIME (0x01 << 6) /**< UTC Time mask bit. */ + +// Data Control point parameter type lengths. +#define INT8_LEN 1 +#define INT16_LEN 2 +#define INT24_LEN 3 +#define INT32_LEN 4 + +#define OPCODE_LENGTH 1 /**< Length of opcode inside Location and Navigation Measurement packet. */ +#define HANDLE_LENGTH 2 /**< Length of handle inside Location and Navigation Measurement packet. */ + +static ble_lncp_rsp_code_t notify_app(ble_lncp_t const * p_lncp, ble_lncp_evt_t const * p_evt) +{ + ble_lncp_rsp_code_t rsp = LNCP_RSP_SUCCESS; + + if (p_lncp->evt_handler != NULL) + { + rsp = p_lncp->evt_handler(p_lncp, p_evt); + } + + return rsp; +} + + +static void resp_send(ble_lncp_t * p_lncp) +{ + // Send indication + uint16_t hvx_len; + uint8_t hvx_data[MAX_CTRL_POINT_RESP_PARAM_LEN]; + ble_gatts_hvx_params_t hvx_params; + uint32_t err_code; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_len = 3 + p_lncp->pending_rsp.rsp_param_len; + hvx_data[0] = LNCP_OP_RESPONSE_CODE; + hvx_data[1] = p_lncp->pending_rsp.op_code; + hvx_data[2] = p_lncp->pending_rsp.rsp_code; + + memcpy(&hvx_data[3], &p_lncp->pending_rsp.rsp_param[0], p_lncp->pending_rsp.rsp_param_len); + + hvx_params.handle = p_lncp->ctrlpt_handles.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = hvx_data; + + err_code = sd_ble_gatts_hvx(p_lncp->conn_handle, &hvx_params); + + // Error handling + if ((err_code == NRF_SUCCESS) && (hvx_len != p_lncp->pending_rsp.rsp_param_len + 3)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + + switch (err_code) + { + case NRF_SUCCESS: + p_lncp->procedure_status = LNCP_STATE_CONFIRMATION_PENDING; + // Wait for HVC event + break; + + case BLE_ERROR_NO_TX_PACKETS: + // Wait for TX_COMPLETE event to retry transmission + p_lncp->procedure_status = LNCP_STATE_INDICATION_PENDING; + break; + + default: + p_lncp->procedure_status = LNCP_STATE_INDICATION_PENDING; + // error + if (p_lncp->error_handler != NULL) + { + p_lncp->error_handler(err_code); + } + break; + } +} + + +static void on_connect(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + memset(&p_lncp->mask, 0, sizeof(ble_lncp_mask_t)); + p_lncp->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS; +} + + +static void on_disconnect(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + UNUSED_PARAMETER(p_ble_evt); + p_lncp->conn_handle = BLE_CONN_HANDLE_INVALID; + p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS; +} + + +static void on_hvc_confirm(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + if (p_ble_evt->evt.gatts_evt.params.hvc.handle == p_lncp->ctrlpt_handles.value_handle) + { + if (p_lncp->procedure_status == LNCP_STATE_CONFIRMATION_PENDING) + { + p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS; + } + else + { + if (p_lncp->error_handler != NULL) + { + p_lncp->error_handler(NRF_ERROR_INVALID_STATE); + } + } + } +} + + +static void on_tx_complete(ble_lncp_t * p_lncp) +{ + if (p_lncp->procedure_status == LNCP_STATE_INDICATION_PENDING) + { + resp_send(p_lncp); + } +} + + +/**@brief Handle write events to the control point cccd. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_lncp_cccd_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if (p_evt_write->len == BLE_CCCD_VALUE_LEN) + { + // CCCD written, update indications state + p_lncp->is_ctrlpt_indication_enabled = ble_srv_is_indication_enabled(p_evt_write->data); + } +} + + +/**@brief Handle write events to the navigation cccd. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_nav_cccd_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if (p_evt_write->len == BLE_CCCD_VALUE_LEN) + { + // CCCD written, update notification state + p_lncp->is_nav_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data); + } +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_set_cumulative_value(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if ( !(p_lncp->available_features & BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT24_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const uint32_t total_distance = uint24_decode(&p_evt_write->data[1]); + + const ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_TOTAL_DISTANCE_SET, + .params.total_distance = total_distance + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); + + if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS) + { + p_lncp->total_distance = total_distance; + } + +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_mask_loc_speed_content(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if ( !(p_lncp->available_features & BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + uint16_t rcvd_mask = uint16_decode(&p_evt_write->data[1]); + + if (rcvd_mask > 0x7F) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_MASK_SET, + .params.mask.flags = rcvd_mask + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); + + if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS) + { + p_lncp->mask.flags = rcvd_mask; + } +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_nav_control(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if ( !(p_lncp->is_navigation_present) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != LNCP_NAV_CMD_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */ + const uint8_t data_buf = p_evt_write->data[1]; + /*lint -restore*/ + + if (data_buf > LNCP_NAV_CMD_MAX) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const ble_lncp_nav_cmd_t cmd = (ble_lncp_nav_cmd_t) data_buf; + + if (cmd == LNCP_CMD_NAV_START || cmd == LNCP_CMD_NAV_CONTINUE || cmd == LNCP_CMD_NAV_NEAREST) + { + p_lncp->is_navigation_running = true; + } + else if (cmd == LNCP_CMD_NAV_STOP || cmd == LNCP_CMD_NAV_PAUSE) + { + p_lncp->is_navigation_running = false; + } + + const ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_NAV_COMMAND, + .params.nav_cmd = cmd + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_req_num_routes(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS; + + if ( !(p_lncp->is_navigation_present) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const uint8_t num_records = ble_ln_db_num_records_get(); + p_lncp->pending_rsp.rsp_param_len = uint16_encode(num_records, &p_lncp->pending_rsp.rsp_param[0]); +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_req_name_of_route(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + uint8_t * p_name; + uint32_t err_code; + + p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS; + + if ( !(p_lncp->is_navigation_present) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */ + const uint16_t route_num = uint16_decode(&p_evt_write->data[1]); + /*lint -restore*/ + + err_code = ble_ln_db_record_name_get(route_num, &p_name); + if (err_code != NRF_SUCCESS) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OPERATION_FAILED;; + return; + } + memcpy(&p_lncp->pending_rsp.rsp_param[0], p_name, BLE_LNS_MAX_ROUTE_NAME_LEN); + + p_lncp->pending_rsp.rsp_param_len = BLE_LNS_MAX_ROUTE_NAME_LEN; +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_select_route(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + if ( !(p_lncp->is_navigation_present)) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const uint16_t route_num = uint16_decode(&p_evt_write->data[1]); + const uint16_t stored_num = ble_ln_db_num_records_get(); + + if (route_num >= stored_num) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_ROUTE_SELECTED, + .params.selected_route = route_num + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); + + if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS) + { + p_lncp->selected_route = route_num; + } +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_set_fix_rate(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS; + + if ( !(p_lncp->available_features & BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT8_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */ + const uint8_t fix_rate = p_evt_write->data[1]; + /*lint -restore*/ + + const ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_FIX_RATE_SET, + .params.fix_rate = fix_rate + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); + + if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS) + { + p_lncp->fix_rate = fix_rate; + } +} + + +/**@brief Event handler for control point write. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_set_elevation(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS; + + if ( !(p_lncp->available_features & BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED) ) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + return; + } + + if (p_evt_write->len != OPCODE_LENGTH + INT24_LEN) + { + p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER; + return; + } + + const uint32_t elevation = uint24_decode(&p_evt_write->data[1]); + ble_lncp_evt_t evt = { + .evt_type = LNCP_EVT_ELEVATION_SET, + .params.elevation = elevation + }; + p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt); + + if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS) + { + p_lncp->elevation = elevation; + } +} + + +/**@brief Handle write events to the Location and Navigation Service Control Point characteristic. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_evt_write Write event received from the BLE stack. + */ +static void on_ctrlpt_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write) +{ + uint32_t err_code; + + p_lncp->pending_rsp.rsp_param_len = 0; + + ble_gatts_rw_authorize_reply_params_t write_authorize_reply; + memset(&write_authorize_reply, 0, sizeof(write_authorize_reply)); + + write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + + if (p_lncp->is_ctrlpt_indication_enabled) + { + if (p_lncp->procedure_status == LNCP_STATE_NO_PROC_IN_PROGRESS) + { + write_authorize_reply.params.write.update = 1; + write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + // if the op code is navigation control, its cccd must be checked + if (p_evt_write->len > 0 && p_lncp->is_navigation_present) + { + if ( p_evt_write->data[0] == LNCP_OP_NAV_CONTROL + || p_evt_write->data[0] == LNCP_OP_REQ_NAME_OF_ROUTE + || p_evt_write->data[0] == LNCP_OP_REQ_NUM_ROUTES) + { + if (!p_lncp->is_nav_notification_enabled) + { + write_authorize_reply.params.write.gatt_status = LNCP_RSP_CCCD_CONFIG_IMPROPER; + } + } + } + } + else + { + write_authorize_reply.params.write.gatt_status = LNCP_RSP_PROC_ALR_IN_PROG; + } + } + else + { + write_authorize_reply.params.write.gatt_status = LNCP_RSP_CCCD_CONFIG_IMPROPER; + } + + // reply to the write authorization + do { + err_code = sd_ble_gatts_rw_authorize_reply(p_lncp->conn_handle, &write_authorize_reply); + if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_BUSY) + { + if (p_lncp->error_handler != NULL) + { + p_lncp->error_handler(err_code); + } + } + } while (err_code == NRF_ERROR_BUSY); + + + if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS) + { + return; + } + + // Start executing the control point write action + p_lncp->procedure_status = LNCP_STATE_INDICATION_PENDING; + if (p_evt_write->len > 0) + { + p_lncp->pending_rsp.op_code = (ble_lncp_op_code_t) p_evt_write->data[0]; + switch (p_lncp->pending_rsp.op_code) + { + case LNCP_OP_SET_CUMULATIVE_VALUE: + on_set_cumulative_value(p_lncp, p_evt_write); + break; + + case LNCP_OP_MASK_LOC_SPEED_CONTENT: + on_mask_loc_speed_content(p_lncp, p_evt_write); + break; + + case LNCP_OP_NAV_CONTROL: + on_nav_control(p_lncp, p_evt_write); + break; + + case LNCP_OP_REQ_NUM_ROUTES: + on_req_num_routes(p_lncp, p_evt_write); + break; + + case LNCP_OP_REQ_NAME_OF_ROUTE: + on_req_name_of_route(p_lncp, p_evt_write); + break; + + case LNCP_OP_SELECT_ROUTE: + on_select_route(p_lncp, p_evt_write); + break; + + case LNCP_OP_SET_FIX_RATE: + on_set_fix_rate(p_lncp, p_evt_write); + break; + + case LNCP_OP_SET_ELEVATION: + on_set_elevation(p_lncp, p_evt_write); + break; + + // Unrecognized Op Code + default: + p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED; + break; + } + + resp_send(p_lncp); + } + else + { + p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS; + } +} + + +/**@brief Write authorization request event handler. + * + * @details The write authorization request event handler is only called when writing to the control point. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_rw_authorize_req(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + const ble_gatts_evt_rw_authorize_request_t * p_auth_req = + &p_ble_evt->evt.gatts_evt.params.authorize_request; + + if ( + (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + && + (p_auth_req->request.write.handle == p_lncp->ctrlpt_handles.value_handle) + && + (p_auth_req->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) + && + (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + && + (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) + ) + { + on_ctrlpt_write(p_lncp, &p_auth_req->request.write); + } + +} + + +/**@brief Write event handler. + * + * @param[in] p_lncp Location and Navigation Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + const ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + if (p_evt_write->handle == p_lncp->ctrlpt_handles.cccd_handle) + { + on_lncp_cccd_write(p_lncp, p_evt_write); + } + else if (p_evt_write->handle == p_lncp->navigation_handles.cccd_handle) + { + on_nav_cccd_write(p_lncp, p_evt_write); + } +} + + +void ble_lncp_on_ble_evt(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_lncp); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connect(p_lncp, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + if (p_ble_evt->evt.gap_evt.conn_handle == p_lncp->conn_handle) + { + on_disconnect(p_lncp, p_ble_evt); + } + break; + + case BLE_GATTS_EVT_WRITE: + if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle) + { + on_write(p_lncp, p_ble_evt); + } + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle) + { + on_rw_authorize_req(p_lncp, p_ble_evt); + } + break; + + case BLE_GATTS_EVT_HVC: + if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle) + { + on_hvc_confirm(p_lncp, p_ble_evt); + } + break; + + case BLE_EVT_TX_COMPLETE: + on_tx_complete(p_lncp); + break; + + default: + // no implementation + break; + } +} + + +uint32_t ble_lncp_total_distance_get(ble_lncp_t const * p_lncp) +{ + if (p_lncp == NULL) + { + return 0; + } + + return p_lncp->total_distance; +} + + +uint32_t ble_lncp_elevation_get(ble_lncp_t const * p_lncp) +{ + if (p_lncp == NULL) + { + return 0; + } + + return p_lncp->elevation; +} + + +ble_lncp_mask_t ble_lncp_mask_get(ble_lncp_t const * p_lncp) +{ + if (p_lncp == NULL) + { + const ble_lncp_mask_t empty_mask = {0}; + return empty_mask; + } + + return p_lncp->mask; +} + + +bool ble_lncp_is_navigation_running(ble_lncp_t const * p_lncp) +{ + if (p_lncp == NULL) + { + return false; + } + + return p_lncp->is_navigation_running; +} + + +ret_code_t ble_lncp_init(ble_lncp_t * p_lncp, ble_lncp_init_t const * p_lncp_init) +{ + VERIFY_PARAM_NOT_NULL(p_lncp); + VERIFY_PARAM_NOT_NULL(p_lncp_init); + + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + p_lncp->service_handle = p_lncp_init->service_handle; + p_lncp->evt_handler = p_lncp_init->evt_handler; + p_lncp->error_handler = p_lncp_init->error_handler; + p_lncp->available_features = p_lncp_init->available_features; + p_lncp->is_position_quality_present = p_lncp_init->is_position_quality_present; + p_lncp->is_navigation_present = p_lncp_init->is_navigation_present; + p_lncp->total_distance = p_lncp_init->total_distance; + p_lncp->elevation = p_lncp_init->elevation; + p_lncp->navigation_handles = p_lncp_init->navigation_handles; + + p_lncp->fix_rate = BLE_LNS_NO_FIX; + p_lncp->selected_route = BLE_LNS_INVALID_ROUTE; + + p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS; + p_lncp->conn_handle = BLE_CONN_HANDLE_INVALID; + p_lncp->is_navigation_running = false; + p_lncp->is_nav_notification_enabled = false; + p_lncp->is_ctrlpt_indication_enabled = false; + + memset(&p_lncp->mask, 0, sizeof(ble_lncp_mask_t)); + + add_char_params.uuid = BLE_UUID_LN_CONTROL_POINT_CHAR; + add_char_params.max_len = 0; + add_char_params.char_props.indicate = true; + add_char_params.char_props.write = true; + add_char_params.is_defered_write = true; + add_char_params.is_var_len = true; + add_char_params.max_len = BLE_L2CAP_MTU_DEF; + add_char_params.write_access = p_lncp_init->write_perm; + add_char_params.cccd_write_access = p_lncp_init->cccd_write_perm; + + NRF_LOG_DEBUG("Initialized\r\n"); + + return characteristic_add(p_lncp->service_handle, + &add_char_params, + &p_lncp->ctrlpt_handles); +} diff --git a/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h b/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h new file mode 100644 index 0000000..0422e33 --- /dev/null +++ b/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h @@ -0,0 +1,256 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_sdk_srv_lncp Location and Navigation Service Control Point + * @{ + * @ingroup ble_sdk_srv + * @brief Location and Navigation Service Control Point module + * + * @details This module implements the Location and Navigation Service Control Point behavior. + */ + +#ifndef BLE_LN_CTRLPT_H__ +#define BLE_LN_CTRLPT_H__ + +#include "ble_srv_common.h" +#include "sdk_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_LNS_MAX_ROUTE_NAME_LEN (BLE_L2CAP_MTU_DEF - 5) /**< The maximum length of length of a route name. */ +#define MAX_CTRL_POINT_RESP_PARAM_LEN BLE_LNS_MAX_ROUTE_NAME_LEN + 3 /**< Maximum length of a control point response. */ + +typedef struct ble_lncp_s ble_lncp_t; + +/** @brief Location and Navigation event type. This list defines the possible events types from the Location and Navigation Service. */ +typedef enum +{ + LNCP_EVT_ELEVATION_SET, /**< Location and Navigation elevation was set. */ + LNCP_EVT_FIX_RATE_SET, /**< Fix rate was set. */ + LNCP_EVT_ROUTE_SELECTED, /**< A route was selected. */ + LNCP_EVT_NAV_COMMAND, /**< A navigation command was issued. */ + LNCP_EVT_MASK_SET, /**< Location and Speed feature mask was set. */ + LNCP_EVT_TOTAL_DISTANCE_SET /**< Location and Navigation total distance was set. */ +} ble_lncp_evt_type_t; + + +/** @brief Navigation commands. These commands can be sent to the control point and returned by an event callback. */ +typedef enum +{ + LNCP_CMD_NAV_STOP = 0x00, /**< When received, is_navigation_running in @ref ble_lns_s will be set to false. */ + LNCP_CMD_NAV_START = 0x01, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */ + LNCP_CMD_NAV_PAUSE = 0x02, /**< When received, is_navigation_running in @ref ble_lns_s will be set to false. */ + LNCP_CMD_NAV_CONTINUE = 0x03, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */ + LNCP_CMD_NAV_SKIP_WAYPOINT = 0x04, /**< When received, is_navigation_running in @ref ble_lns_s will not be affected. */ + LNCP_CMD_NAV_NEAREST = 0x05, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */ +} ble_lncp_nav_cmd_t; +#define LNCP_NAV_CMD_MAX 0x05 +#define LNCP_NAV_CMD_LEN (OPCODE_LENGTH + 1) + + +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#endif + +/** @brief A mask can be used to temporarily enable and disable features of the Location and Speed characteristic.*/ +typedef union +{ + uint8_t flags; + struct + { + uint8_t instantaneous_speed :1; + uint8_t total_distance :1; + uint8_t location :1; + uint8_t elevation :1; + uint8_t heading :1; + uint8_t rolling_time :1; + uint8_t utc_time :1; + }; +} ble_lncp_mask_t; + +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + /* leave anonymous unions enabled */ +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#endif + +typedef struct +{ + ble_lncp_evt_type_t evt_type; + union + { + ble_lncp_mask_t mask; + ble_lncp_nav_cmd_t nav_cmd; + uint32_t total_distance; + uint8_t fix_rate; + uint16_t selected_route; + uint32_t elevation; + } params; +} ble_lncp_evt_t; + + +// Location and Navigation Control Point response values +typedef enum +{ + LNCP_RSP_RESERVED = 0x00, /**< Reserved for future use. */ + LNCP_RSP_SUCCESS = 0x01, /**< Success. */ + LNCP_RSP_OP_CODE_NOT_SUPPORTED = 0x02, /**< Op Code not supported. */ + LNCP_RSP_INVALID_PARAMETER = 0x03, /**< Invalid Parameter. */ + LNCP_RSP_OPERATION_FAILED = 0x04, /**< Operation Failed. */ + LNCP_RSP_PROC_ALR_IN_PROG = BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG, /**< Control point procedure is already in progress. */ + LNCP_RSP_CCCD_CONFIG_IMPROPER = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR /**< CCCD is improperly configured. */ +} ble_lncp_rsp_code_t; + + +typedef ble_lncp_rsp_code_t (*ble_lncp_evt_handler_t) (ble_lncp_t const * p_lncp, ble_lncp_evt_t const * p_evt); + +// Location and Navigation Control Point Op Code values +typedef enum +{ + LNCP_OP_RESERVED = 0x00, /**< Reserved for future use. */ + LNCP_OP_SET_CUMULATIVE_VALUE = 0x01, /**< Set Cumulative Value. */ + LNCP_OP_MASK_LOC_SPEED_CONTENT = 0x02, /**< Mask Location and Speed Characteristic Content. */ + LNCP_OP_NAV_CONTROL = 0x03, /**< Navigation Control. */ + LNCP_OP_REQ_NUM_ROUTES = 0x04, /**< Request Number of Routes. */ + LNCP_OP_REQ_NAME_OF_ROUTE = 0x05, /**< Request Name of Route. */ + LNCP_OP_SELECT_ROUTE = 0x06, /**< Select Route. */ + LNCP_OP_SET_FIX_RATE = 0x07, /**< Set Fix Rate. */ + LNCP_OP_SET_ELEVATION = 0x08, /**< Set Elevation. */ + LNCP_OP_RESPONSE_CODE = 0x20 /**< Response code. */ +} ble_lncp_op_code_t; + + +/** @brief Location and Navigation Control Point procedure status */ +typedef enum +{ + LNCP_STATE_NO_PROC_IN_PROGRESS, /**< No procedure in progress. */ + LNCP_STATE_INDICATION_PENDING, /**< Control Point indication is pending. */ + LNCP_STATE_CONFIRMATION_PENDING, /**< Waiting for the indication confirmation. */ +} ble_lncp_procedure_status_t; + + +/** @brief Information included in a control point write response indication. */ +typedef struct +{ + ble_lncp_op_code_t op_code; /**< Opcode of the control point write action. */ + ble_lncp_rsp_code_t rsp_code; /**< Response code of the control point write action. */ + uint8_t rsp_param_len; + uint8_t rsp_param[MAX_CTRL_POINT_RESP_PARAM_LEN]; +} ble_lncp_rsp_t; + + +typedef struct +{ + uint16_t service_handle; + ble_lncp_evt_handler_t evt_handler; + ble_srv_error_handler_t error_handler; + + uint32_t available_features; /**< Value of the LN feature. */ + bool is_position_quality_present; /**< If set to true, the position quality characteristic will be added. Else not. */ + bool is_control_point_present; /**< If set to true, the control point characteristic will be added. Else not. */ + bool is_navigation_present; /**< If set to true, the navigation characteristic will be added. Else not. */ + ble_gatts_char_handles_t navigation_handles; + + uint32_t total_distance; + uint32_t elevation; + + security_req_t write_perm; + security_req_t cccd_write_perm; +} ble_lncp_init_t; + + +struct ble_lncp_s +{ + uint16_t conn_handle; + uint16_t service_handle; + ble_gatts_char_handles_t ctrlpt_handles; + ble_gatts_char_handles_t navigation_handles; + ble_lncp_evt_handler_t evt_handler; + ble_srv_error_handler_t error_handler; + ble_lncp_procedure_status_t procedure_status; + ble_lncp_rsp_t pending_rsp; + + ble_lncp_mask_t mask; + uint32_t total_distance; + uint32_t elevation; + uint8_t fix_rate; + uint16_t selected_route; + uint32_t available_features; /**< Value of the LN feature. */ + bool is_position_quality_present; /**< If set to true, the position quality characteristic will be added. Else not. */ + bool is_control_point_present; /**< If set to true, the control point characteristic will be added. Else not. */ + bool is_navigation_present; /**< If set to true, the navigation characteristic will be added. Else not. */ + bool is_navigation_running; /**< This variable can be set using the control point. Must be true to be able to send navigation updates. */ + + bool is_ctrlpt_indication_enabled; /**< True if indication is enabled on the Control Point characteristic. */ + bool is_nav_notification_enabled; /**< True if notification is enabled on the Navigation characteristic. */ +}; + + +void ble_lncp_on_ble_evt(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt); + +uint32_t ble_lncp_total_distance_get(ble_lncp_t const * p_lncp); + +uint32_t ble_lncp_elevation_get(ble_lncp_t const * p_lncp); + +ble_lncp_mask_t ble_lncp_mask_get(ble_lncp_t const * p_lncp); + +bool ble_lncp_is_navigation_running(ble_lncp_t const * p_lncp); + +ret_code_t ble_lncp_init(ble_lncp_t * p_lncp, ble_lncp_init_t const * p_lncp_init); + + +#ifdef __cplusplus +} +#endif + +#endif //BLE_LN_CTRLPT_H__ + +/** @} */ diff --git a/components/ble/ble_services/experimental_ble_lns/ble_ln_db.c b/components/ble/ble_services/experimental_ble_lns/ble_ln_db.c new file mode 100644 index 0000000..9f42db2 --- /dev/null +++ b/components/ble/ble_services/experimental_ble_lns/ble_ln_db.c @@ -0,0 +1,152 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_ln_db.h" +#include "ble_ln_common.h" + +typedef struct +{ + bool in_use_flag; + ble_lns_route_t record; +} database_entry_t; + +static database_entry_t m_database[BLE_LNS_MAX_NUM_ROUTES]; +static uint8_t m_database_crossref[BLE_LNS_MAX_NUM_ROUTES]; +static uint16_t m_num_records; + +void ble_ln_db_init(void) +{ + int i; + + for (i = 0; i < BLE_LNS_MAX_NUM_ROUTES; i++) + { + m_database[i].in_use_flag = false; + m_database_crossref[i] = 0xFF; + } + + m_num_records = 0; +} + + +uint16_t ble_ln_db_num_records_get(void) +{ + return m_num_records; +} + + +ret_code_t ble_ln_db_record_get(uint8_t rec_ndx, ble_lns_route_t * p_rec) +{ + if (rec_ndx >= m_num_records) + { + return NRF_ERROR_INVALID_PARAM; + } + + // copy record to the specified memory + *p_rec = m_database[m_database_crossref[rec_ndx]].record; + + return NRF_SUCCESS; +} + + +ret_code_t ble_ln_db_record_name_get(uint8_t rec_ndx, uint8_t ** p_buf) +{ + if (rec_ndx >= m_num_records) + { + return NRF_ERROR_INVALID_PARAM; + } + + // copy record to the specified memory + *p_buf = m_database[m_database_crossref[rec_ndx]].record.route_name; + + return NRF_SUCCESS; +} + + +ret_code_t ble_ln_db_record_add(ble_lns_route_t * p_rec) +{ + int i; + + if (m_num_records == BLE_LNS_MAX_NUM_ROUTES) + { + return NRF_ERROR_NO_MEM; + } + + // find next available database entry + for (i = 0; i < BLE_LNS_MAX_NUM_ROUTES; i++) + { + if (!m_database[i].in_use_flag) + { + m_database[i].in_use_flag = true; + m_database[i].record = *p_rec; + m_database[i].record.route_id = i; + m_database_crossref[m_num_records] = i; + p_rec->route_id = i; + m_num_records++; + return NRF_SUCCESS; + } + } + + return NRF_ERROR_NO_MEM; +} + + +ret_code_t ble_ln_db_record_delete(uint8_t rec_ndx) +{ + int i; + + if (rec_ndx >= m_num_records) + { + return NRF_ERROR_NOT_FOUND; + } + + // free entry + m_database[m_database_crossref[rec_ndx]].in_use_flag = false; + + // decrease number of records + m_num_records--; + + // remove cross reference index + for (i = rec_ndx; i < m_num_records; i++) + { + m_database_crossref[i] = m_database_crossref[i + 1]; + } + + return NRF_SUCCESS; +} diff --git a/components/ble/ble_services/experimental_ble_lns/ble_ln_db.h b/components/ble/ble_services/experimental_ble_lns/ble_ln_db.h new file mode 100644 index 0000000..6b68633 --- /dev/null +++ b/components/ble/ble_services/experimental_ble_lns/ble_ln_db.h @@ -0,0 +1,123 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_sdk_srv_ln_db Location and Navigation database + * @{ + * @ingroup ble_sdk_srv + * @brief Location and Navigation route database + */ + +#ifndef BLE_LN_DB__ +#define BLE_LN_DB__ + +#include "ble_lns.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for initializing the route database. + * + * @details This call initializes the database holding route records. + * + * @return NRF_SUCCESS on success. + */ +void ble_ln_db_init(void); + +/**@brief Function for getting the number of records in the database. + * + * @details This call returns the number of records in the database. + * + * @return Number of records in the database. + */ +uint16_t ble_ln_db_num_records_get(void); + +/**@brief Function for getting a record from the database. + * + * @details This call returns a specified record from the database. + * + * @param[in] record_num Index of the record to retrieve. + * @param[out] p_rec Pointer to record structure where retrieved record is copied to. + * + * @return NRF_SUCCESS on success. + */ +ret_code_t ble_ln_db_record_get(uint8_t record_num, ble_lns_route_t * p_rec); + +/**@brief Function for getting a record name from the database. + * + * @details This call returns a specified record name from the database. + * + * @param[in] rec_ndx Index of the record to retrieve. + * @param[out] p_buf Pointer to array where retrieved record name is copied to. + * + * @return NRF_SUCCESS on success. + */ +ret_code_t ble_ln_db_record_name_get(uint8_t rec_ndx, uint8_t ** p_buf); + +/**@brief Function for adding a record at the end of the database. + * + * @details This call adds a record as the last record in the database. + * + * @param[in] p_rec Pointer to record to add to database. + * + * @return NRF_SUCCESS on success. + */ +ret_code_t ble_ln_db_record_add(ble_lns_route_t * p_rec); + +/**@brief Function for deleting a database entry. + * + * @details This call deletes an record from the database. + * + * @param[in] record_num Index of record to delete. + * + * @return NRF_SUCCESS on success. + */ +ret_code_t ble_ln_db_record_delete(uint8_t record_num); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_LN_DB_H__ + +/** @} */ diff --git a/components/ble/ble_services/experimental_ble_lns/ble_lns.c b/components/ble/ble_services/experimental_ble_lns/ble_lns.c index aeb1d73..8851cce 100644 --- a/components/ble/ble_services/experimental_ble_lns/ble_lns.c +++ b/components/ble/ble_services/experimental_ble_lns/ble_lns.c @@ -1,22 +1,50 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_lns.h" -#include -#include "nordic_common.h" -#include "ble_l2cap.h" -#include "ble_srv_common.h" -#include "app_util.h" -#include "ble_gatt.h" +#include "ble_ln_db.h" +#include "ble_ln_common.h" +#include "sdk_common.h" + +#define NRF_LOG_MODULE_NAME "BLE_LNS" +#include "nrf_log.h" // Location and Speed flag bits #define LOC_SPEED_FLAG_INSTANT_SPEED_PRESENT (0x01 << 0) /**< Instantaneous Speed Present bit. */ @@ -30,8 +58,8 @@ #define LOC_SPEED_FLAG_SPEED_AND_DIST_FORMAT (0x01 << 9) /**< Speed and Distance Format. */ #define LOC_SPEED_FLAG_ELEVATION_SOURCE (0x03 << 10) /**< Elevation Source bits(2). */ #define LOC_SPEED_FLAG_HEADING_SOURCE (0x01 << 12) /**< Heading Source. */ - -// Position Quality flag bits + +// Position Quality flag bits #define POS_QUAL_FLAG_NUM_SATS_IN_SOLUTION_PRESENT (0x01 << 0) /**< Number of Satellites in Solution Present bit. */ #define POS_QUAL_FLAG_NUM_SATS_IN_VIEW_PRESENT (0x01 << 1) /**< Number of Satellites in View Present bit. */ #define POS_QUAL_FLAG_TIME_TO_FIRST_FIX_PRESESNT (0x01 << 2) /**< Time to First Fix Present bit. */ @@ -40,8 +68,8 @@ #define POS_QUAL_FLAG_HDOP_PRESENT (0x01 << 5) /**< HDOP Present bit. */ #define POS_QUAL_FLAG_VDOP_PRESENT (0x01 << 6) /**< VDOP Present bit. */ #define POS_QUAL_FLAG_POSITION_STATUS (0x03 << 7) /**< Position Status bits(2). */ - -// Navigation flag bits + +// Navigation flag bits #define NAV_FLAG_REMAINING_DIST_PRESENT (0x01 << 0) /**< Remaining Distance Present bit. */ #define NAV_FLAG_REAMINGING_VERT_DIST_PRESESNT (0x01 << 1) /**< Remaining Vertical Distance Present bit . */ #define NAV_FLAG_ETA_PRESENT (0x01 << 2) /**< Estimated Time of Arrival Present bit. */ @@ -50,25 +78,56 @@ #define NAV_FLAG_NAVIGATION_INDICATOR_TYPE (0x01 << 6) /**< Navigation Indicator Type bit. */ #define NAV_FLAG_WAYPOINT_REACHED (0x01 << 7) /**< Waypoint Reached bit. */ #define NAV_FLAG_DESTINATION_REACHED (0x01 << 8) /**< Destination Reached bit. */ - -// Feature Mask bits -#define FEATURE_MASK_INSTANTANEOUS_SPEED (0x01 << 0) /**< Instantaneous Speed mask bit. */ -#define FEATURE_MASK_TOTAL_DISTANCE (0x01 << 1) /**< Total Distance mask bit. */ -#define FEATURE_MASK_LOCATION (0x01 << 2) /**< Location mask bit. */ -#define FEATURE_MASK_ELEVATION (0x01 << 3) /**< Elevation mask bit. */ -#define FEATURE_MASK_HEADING (0x01 << 4) /**< Heading mask bit. */ -#define FEATURE_MASK_ROLLING_TIME (0x01 << 5) /**< Rolling Time mask bit. */ -#define FEATURE_MASK_UTC_TIME (0x01 << 6) /**< UTC Time mask bit. */ - -// Data Control point parameter type lengths. -#define INT8_LEN 1 -#define INT16_LEN 2 -#define INT24_LEN 3 -#define INT32_LEN 4 - -#define OPCODE_LENGTH 1 /**< Length of opcode inside Location and Navigation Measurement packet. */ -#define HANDLE_LENGTH 2 /**< Length of handle inside Location and Navigation Measurement packet. */ -#define BLE_LNS_NAV_MAX_LEN 19 /**< The length of a navigation notification when all features are enabled. See @ref ble_lns_navigation_t to see what this represents, or check https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.navigation.xml. */ + +#define BLE_LNS_NAV_MAX_LEN 19 /**< The length of a navigation notification when all features are enabled. See @ref ble_lns_navigation_t to see what this represents, or check https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.navigation.xml. */ + + +static void notification_buffer_process(ble_lns_t * p_lns) +{ + notification_t * p_notification; + + // See if a notification is pending + if (p_lns->pending_loc_speed_notifications[0].is_pending == true) + { + p_notification = &p_lns->pending_loc_speed_notifications[0]; + } + else if (p_lns->pending_loc_speed_notifications[1].is_pending == true) + { + p_notification = &p_lns->pending_loc_speed_notifications[1]; + } + else if (p_lns->pending_navigation_notification.is_pending == true) + { + p_notification = &p_lns->pending_navigation_notification; + } + else + { + p_notification = NULL; + } + + // send the notification if necessary + if (p_notification != NULL) + { + uint32_t err_code; + ble_gatts_hvx_params_t hvx_params; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + uint16_t hvx_len = p_notification->len; + + hvx_params.handle = p_notification->handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = &p_notification->data[0]; + + err_code = sd_ble_gatts_hvx(p_lns->conn_handle, &hvx_params); + + if ((err_code == NRF_SUCCESS) && (hvx_len == p_notification->len)) + { + p_notification->is_pending = false; + } + } +} /**@brief Connect event handler. @@ -76,100 +135,108 @@ * @param[in] p_lns Location and Navigation Service structure. * @param[in] p_ble_evt Event received from the BLE stack. */ -static void on_connect(ble_lns_t * p_lns, ble_evt_t * p_ble_evt) +static void on_connect(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt) { - // Clear previous mask. No features are masked away. - memset(&p_lns->mask, 0, sizeof (p_lns->mask)); - p_lns->control_point_procedure_status = BLE_LNS_CTRLPT_STATE_NO_PROC_IN_PROGRESS; p_lns->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + + // clear pending notifications + p_lns->pending_loc_speed_notifications[0].is_pending = false; + p_lns->pending_loc_speed_notifications[1].is_pending = false; + p_lns->pending_navigation_notification.is_pending = false; } + /**@brief Disconnect event handler. * * @param[in] p_lns Location and Navigation Service structure. * @param[in] p_ble_evt Event received from the BLE stack. */ -static void on_disconnect(ble_lns_t * p_lns, ble_evt_t * p_ble_evt) +static void on_disconnect(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt) { - UNUSED_PARAMETER(p_ble_evt); + if (p_lns->conn_handle != p_ble_evt->evt.gatts_evt.conn_handle) + { + return; + } + p_lns->conn_handle = BLE_CONN_HANDLE_INVALID; - p_lns->control_point_procedure_status = BLE_LNS_CTRLPT_STATE_NO_PROC_IN_PROGRESS; } -/**@brief Handle write events to the Location and Speed cccd. + +/**@brief Handle write events to the control point cccd. * - * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_lncp Location and Navigation Service structure. * @param[in] p_evt_write Write event received from the BLE stack. */ -static void on_loc_speed_cccd_write(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) +static void on_ctrl_pt_cccd_write(ble_lns_t * p_lns, ble_gatts_evt_write_t const * p_evt_write) { if (p_evt_write->len == BLE_CCCD_VALUE_LEN) { - // CCCD written, update notification state - memcpy(p_lns->loc_speed_cccd_handle_status, p_evt_write->data, INT16_LEN); //lint !e420 "Apparent access beyond array" if (p_lns->evt_handler != NULL) { ble_lns_evt_t evt; - - if (ble_srv_is_notification_enabled(p_evt_write->data)) + + if (ble_srv_is_indication_enabled(p_evt_write->data)) { - evt.evt_type = BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_ENABLED; + evt.evt_type = BLE_LNS_CTRLPT_EVT_INDICATION_ENABLED;; } else { - evt.evt_type = BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_DISABLED; + evt.evt_type = BLE_LNS_CTRLPT_EVT_INDICATION_DISABLED;; } - + p_lns->evt_handler(p_lns, &evt); } } } -/**@brief Handle write events to the control point cccd. + +/**@brief Handle write events to the Location and Speed cccd. * * @param[in] p_lns Location and Navigation Service structure. * @param[in] p_evt_write Write event received from the BLE stack. */ -static void on_control_point_cccd_write(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) +static void on_loc_speed_cccd_write(ble_lns_t * p_lns, + ble_gatts_evt_write_t const * p_evt_write) { if (p_evt_write->len == BLE_CCCD_VALUE_LEN) { - // CCCD written, update indications state - memcpy(p_lns->ctrl_pnt_cccd_handle_status, p_evt_write->data, INT16_LEN); //lint !e420 "Apparent access beyond array" + // CCCD written, update notification state + p_lns->is_loc_speed_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data); if (p_lns->evt_handler != NULL) { ble_lns_evt_t evt; - - if (ble_srv_is_indication_enabled(p_evt_write->data)) + + if (p_lns->is_loc_speed_notification_enabled) { - evt.evt_type = BLE_LNS_CONTROL_POINT_EVT_INDICATION_ENABLED; + evt.evt_type = BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_ENABLED; } else { - evt.evt_type = BLE_LNS_CONTROL_POINT_EVT_INDICATION_DISABLED; + evt.evt_type = BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_DISABLED; } - + p_lns->evt_handler(p_lns, &evt); } } } + /**@brief Handle write events to the navigation cccd. * * @param[in] p_lns Location and Navigation Service structure. * @param[in] p_evt_write Write event received from the BLE stack. */ -static void on_navigation_cccd_write(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) +static void on_nav_cccd_write(ble_lns_t * p_lns, + ble_gatts_evt_write_t const * p_evt_write) { if (p_evt_write->len == BLE_CCCD_VALUE_LEN) { - // CCCD written, update notification state - memcpy(p_lns->navigation_cccd_handle_status, p_evt_write->data, INT16_LEN); //lint !e420 "Apparent access beyond array" + p_lns->is_nav_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data); if (p_lns->evt_handler != NULL) { ble_lns_evt_t evt; - - if (ble_srv_is_notification_enabled(p_evt_write->data)) + + if (p_lns->is_nav_notification_enabled) { evt.evt_type = BLE_LNS_NAVIGATION_EVT_NOTIFICATION_ENABLED; } @@ -177,634 +244,56 @@ static void on_navigation_cccd_write(ble_lns_t * p_lns, ble_gatts_evt_write_t * { evt.evt_type = BLE_LNS_NAVIGATION_EVT_NOTIFICATION_DISABLED; } - + p_lns->evt_handler(p_lns, &evt); } } } -static void ctrl_point_response_send(ble_lns_t * p_lns) -{ - // Send indication - uint16_t hvx_len; - uint8_t hvx_data[MAX_CTRL_POINT_RESP_PARAM_LEN]; - ble_gatts_hvx_params_t hvx_params; - uint32_t err_code; - - memset(&hvx_params, 0, sizeof(hvx_params)); - - hvx_len = 3 + p_lns->pending_ctrlpt_response.response_param_len; - hvx_data[0] = OP_CODE_RESPONSE_CODE; - hvx_data[1] = p_lns->pending_ctrlpt_response.op_code; - hvx_data[2] = p_lns->pending_ctrlpt_response.response_code; - - memcpy(&hvx_data[3], &p_lns->pending_ctrlpt_response.response_param[0], p_lns->pending_ctrlpt_response.response_param_len); - - hvx_params.handle = p_lns->ctrl_point_handles.value_handle; - hvx_params.type = BLE_GATT_HVX_INDICATION; - hvx_params.offset = 0; - hvx_params.p_len = &hvx_len; - hvx_params.p_data = hvx_data; - - err_code = sd_ble_gatts_hvx(p_lns->conn_handle, &hvx_params); - - // Error handling - if ((err_code == NRF_SUCCESS) && (hvx_len != p_lns->pending_ctrlpt_response.response_param_len + 3)) - { - err_code = NRF_ERROR_DATA_SIZE; - } - - switch (err_code) - { - case NRF_SUCCESS: - p_lns->control_point_procedure_status = BLE_LNS_CTRLPT_STATE_IND_CONFIRM_PENDING; - // Wait for HVC event - break; - - case BLE_ERROR_NO_TX_BUFFERS: - // Wait for TX_COMPLETE event to retry transmission - p_lns->control_point_procedure_status = BLE_LNS_CTRLPT_STATE_INDICATION_PENDING; - break; - - default: - p_lns->control_point_procedure_status = BLE_LNS_CTRLPT_STATE_INDICATION_PENDING; - // error - if (p_lns->error_handler != NULL) - { - p_lns->error_handler(err_code); - } - break; - } -} - -/**@brief Event handler for control point write. - * - * @param[in] p_lns Location and Navigation Service structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_set_cumulative_value(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) -{ - //lint -save -e415 -e416 "Likely access of out-of-bounds pointer" - ble_lns_evt_t lns_evt; - - if ( !(p_lns->available_features & BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED) ) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_OP_CODE_NOT_SUPPORTED; - return; - } - - if (p_evt_write->len != OPCODE_LENGTH + INT24_LEN) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - return; - } - - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_SUCCESS; - - p_lns->p_location_speed->total_distance = (p_evt_write->data[1]<<0) - | (p_evt_write->data[2]<<8) - | (p_evt_write->data[3]<<16); - if (p_lns->evt_handler != NULL) - { - lns_evt.evt_type = BLE_LNS_LOC_SPEED_EVT_TOTAL_DISTANCE_SET; - lns_evt.params.total_distance = p_lns->p_location_speed->total_distance; - p_lns->evt_handler(p_lns, &lns_evt); - } - //lint -restore -} - -/**@brief Event handler for control point write. - * - * @param[in] p_lns Location and Navigation Service structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_mask_loc_speed_content(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) -{ - //lint -save -e415 -e416 "Likely access of out-of-bounds pointer" - ble_lns_evt_t lns_evt; - - if ( !(p_lns->available_features & BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED) ) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_OP_CODE_NOT_SUPPORTED; - return; - } - if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - return; - } - - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_SUCCESS; - uint16_t rcvd_mask = uint16_decode(&p_evt_write->data[1]); - if(rcvd_mask > 0x7f) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - return; - } - - p_lns->mask.instantaneous_speed = !(!(rcvd_mask & FEATURE_MASK_INSTANTANEOUS_SPEED)); - p_lns->mask.total_distance = !(!(rcvd_mask & FEATURE_MASK_TOTAL_DISTANCE )); - p_lns->mask.location = !(!(rcvd_mask & FEATURE_MASK_LOCATION )); - p_lns->mask.elevation = !(!(rcvd_mask & FEATURE_MASK_ELEVATION )); - p_lns->mask.heading = !(!(rcvd_mask & FEATURE_MASK_HEADING )); - p_lns->mask.rolling_time = !(!(rcvd_mask & FEATURE_MASK_ROLLING_TIME )); - p_lns->mask.utc_time = !(!(rcvd_mask & FEATURE_MASK_UTC_TIME )); - - - if (p_lns->evt_handler != NULL) - { - lns_evt.evt_type = BLE_LNS_LOC_SPEED_EVT_MASK_SET; - lns_evt.params.mask = p_lns->mask; - p_lns->evt_handler(p_lns, &lns_evt); - } - //lint -restore -} - -/**@brief Event handler for control point write. - * - * @param[in] p_lns Location and Navigation Service structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_nav_control(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) -{ - //lint -save -e415 -e416 "Likely access of out-of-bounds pointer" - ble_lns_evt_t lns_evt; - - if ( !(p_lns->is_navigation_present) ) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_OP_CODE_NOT_SUPPORTED; - return; - } - - if(p_evt_write->len != OPCODE_LENGTH + INT8_LEN) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - return; - } - - if (p_evt_write->data[1] > 0x05) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - return; - } - - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_SUCCESS; - if ( p_evt_write->data[1] == BLE_LNS_NAVIGATION_START - || p_evt_write->data[1] == BLE_LNS_NAVIGATION_CONTINUE - || p_evt_write->data[1] == BLE_LNS_NAVIGATION_NEAREST - ) - { - p_lns->is_navigation_running = true; - } - else if ( p_evt_write->data[1] == BLE_LNS_NAVIGATION_STOP - || p_evt_write->data[1] == BLE_LNS_NAVIGATION_PAUSE - ) - { - p_lns->is_navigation_running = false; - } - - if (p_lns->evt_handler != NULL) - { - lns_evt.evt_type = BLE_LNS_NAVIGATION_EVT_COMMAND; - lns_evt.params.navigation_command = (ble_lns_navigation_command_t)p_evt_write->data[1]; - p_lns->evt_handler(p_lns, &lns_evt); - } - //lint -restore -} - -/**@brief Event handler for control point write. - * - * @param[in] p_lns Location and Navigation Service structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_req_num_routes(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) -{ - //lint -save -e415 -e416 "Likely access of out-of-bounds pointer" - if ( !(p_lns->is_navigation_present) ) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_OP_CODE_NOT_SUPPORTED; - return; - } - if(p_evt_write->len == OPCODE_LENGTH) - { - p_lns->pending_ctrlpt_response.response_param_len = - uint16_encode(p_lns->number_of_routes, &p_lns->pending_ctrlpt_response.response_param[0]); - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_SUCCESS; - } - else - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - } - //lint -restore -} - -/**@brief Event handler for control point write. - * - * @param[in] p_lns Location and Navigation Service structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_req_name_of_route(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) -{ - //lint -save -e415 -e416 "Likely access of out-of-bounds pointer" - if ( !(p_lns->is_navigation_present) ) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_OP_CODE_NOT_SUPPORTED; - return; - } - - if(p_evt_write->len != OPCODE_LENGTH + INT16_LEN) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - return; - } - - uint16_t route_num = uint16_decode(&p_evt_write->data[1]); - if (route_num < p_lns->number_of_routes) - { - memcpy(&p_lns->pending_ctrlpt_response.response_param[0], p_lns->routes[route_num].route_name, BLE_LNS_MAX_ROUTE_NAME_LEN); - p_lns->pending_ctrlpt_response.response_param_len = BLE_LNS_MAX_ROUTE_NAME_LEN; - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_SUCCESS; - } - else - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - } - //lint -restore -} - -/**@brief Event handler for control point write. - * - * @param[in] p_lns Location and Navigation Service structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_select_route(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) -{ - //lint -save -e415 -e416 "Likely access of out-of-bounds pointer" - ble_lns_evt_t lns_evt; - - if ( !(p_lns->is_navigation_present)) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_OP_CODE_NOT_SUPPORTED; - return; - } - - if(p_evt_write->len != OPCODE_LENGTH + INT16_LEN) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - return; - } - - uint16_t route_num = uint16_decode(&p_evt_write->data[1]); - if (route_num < p_lns->number_of_routes) - { - p_lns->selected_route = route_num; - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_SUCCESS; - if (p_lns->evt_handler != NULL) - { - lns_evt.evt_type = BLE_LNS_NAVIGATION_EVT_ROUTE_SELECTED; - lns_evt.params.selected_route = p_lns->selected_route; - p_lns->evt_handler(p_lns, &lns_evt); - } - } - else - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - } - //lint -restore -} - -/**@brief Event handler for control point write. - * - * @param[in] p_lns Location and Navigation Service structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_set_fix_rate(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) -{ - //lint -save -e415 -e416 "Likely access of out-of-bounds pointer" - ble_lns_evt_t lns_evt; - - if ( !(p_lns->available_features & BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED) ) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_OP_CODE_NOT_SUPPORTED; - return; - } - - if (p_evt_write->len != OPCODE_LENGTH + INT8_LEN) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - return; - } - - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_SUCCESS; - p_lns->fix_rate = p_evt_write->data[1]; - if (p_lns->evt_handler != NULL) - { - lns_evt.evt_type = BLE_LNS_POS_QUAL_EVT_FIX_RATE_SET; - lns_evt.params.fix_rate = p_lns->fix_rate; - p_lns->evt_handler(p_lns, &lns_evt); - } - //lint -restore -} - -/**@brief Event handler for control point write. - * - * @param[in] p_lns Location and Navigation Service structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_set_elevation(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) -{ - //lint -save -e415 -e416 "Likely access of out-of-bounds pointer" - ble_lns_evt_t lns_evt; - - if ( !(p_lns->available_features & BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED) ) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_OP_CODE_NOT_SUPPORTED; - return; - } - - if (p_evt_write->len != OPCODE_LENGTH + INT24_LEN) - { - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_INVALID_PARAMETER; - return; - } - - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_SUCCESS; - - p_lns->p_location_speed->elevation = (p_evt_write->data[1]<<0) - | (p_evt_write->data[2]<<8) - | (p_evt_write->data[3]<<16); - - if (p_lns->evt_handler != NULL) - { - lns_evt.evt_type = BLE_LNS_LOC_SPEED_EVT_ELEVATION_SET; - lns_evt.params.elevation = p_lns->p_location_speed->elevation; - p_lns->evt_handler(p_lns, &lns_evt); - } - //lint -restore -} - - -/**@brief Handle write events to the Location and Navigation Service Control Point characteristic. - * - * @param[in] p_lns Location and Navigation Service structure. - * @param[in] p_evt_write Write event received from the BLE stack. - */ -static void on_ctrl_point_write(ble_lns_t * p_lns, ble_gatts_evt_write_t * p_evt_write) -{ - uint32_t err_code; - - p_lns->pending_ctrlpt_response.response_param_len = 0; - - ble_gatts_rw_authorize_reply_params_t write_authorize_reply; - write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; - - if (ble_srv_is_indication_enabled(p_lns->ctrl_pnt_cccd_handle_status)) - { - if (p_lns->control_point_procedure_status == BLE_LNS_CTRLPT_STATE_NO_PROC_IN_PROGRESS) - { - write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; - - // if the op code is navigation control, its cccd must be checked - if (p_evt_write->len > 0 && p_lns->is_navigation_present) - { - if ( p_evt_write->data[0] == OP_CODE_NAV_CONTROL - || p_evt_write->data[0] == OP_CODE_REQ_NAME_OF_ROUTE - || p_evt_write->data[0] == OP_CODE_REQ_NUM_ROUTES) - { - if (ble_srv_is_notification_enabled(p_lns->navigation_cccd_handle_status) == false) - { - write_authorize_reply.params.write.gatt_status = CONTROL_POINT_RESP_CCCD_CONFIG_IMPROPER; - } - } - } - } - else - { - write_authorize_reply.params.write.gatt_status = CONTROL_POINT_RESP_PROC_ALR_IN_PROG; - } - } - else - { - write_authorize_reply.params.write.gatt_status = - CONTROL_POINT_RESP_CCCD_CONFIG_IMPROPER; - } - - // reply to the write authorization - do { - err_code = sd_ble_gatts_rw_authorize_reply(p_lns->conn_handle, &write_authorize_reply); - if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_BUSY) - { - if (p_lns->error_handler != NULL) - { - p_lns->error_handler(err_code); - } - } - } while (err_code == NRF_ERROR_BUSY); - - - if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS) - { - return; - } - - // Start executing the control point write action - p_lns->control_point_procedure_status = BLE_LNS_CTRLPT_STATE_INDICATION_PENDING; - if (p_evt_write->len > 0) - { - p_lns->pending_ctrlpt_response.op_code = p_evt_write->data[0]; - switch (p_lns->pending_ctrlpt_response.op_code) - { - case OP_CODE_SET_CUMULATIVE_VALUE: - on_set_cumulative_value(p_lns, p_evt_write); - break; - - case OP_CODE_MASK_LOC_SPEED_CONTENT: - on_mask_loc_speed_content(p_lns, p_evt_write); - break; - - case OP_CODE_NAV_CONTROL: - on_nav_control(p_lns, p_evt_write); - break; - - case OP_CODE_REQ_NUM_ROUTES: - on_req_num_routes(p_lns, p_evt_write); - break; - - case OP_CODE_REQ_NAME_OF_ROUTE: - on_req_name_of_route(p_lns, p_evt_write); - break; - - case OP_CODE_SELECT_ROUTE: - on_select_route(p_lns, p_evt_write); - break; - - case OP_CODE_SET_FIX_RATE: - on_set_fix_rate(p_lns, p_evt_write); - break; - - case OP_CODE_SET_ELEVATION: - on_set_elevation(p_lns, p_evt_write); - break; - - // Unrecognized Op Code - default: - p_lns->pending_ctrlpt_response.response_code = CONTROL_POINT_RESP_OP_CODE_NOT_SUPPORTED; - break; - } - - ctrl_point_response_send(p_lns); - } - else - { - p_lns->control_point_procedure_status = BLE_LNS_CTRLPT_STATE_NO_PROC_IN_PROGRESS; - } -} /**@brief Write event handler. * * @param[in] p_lns Location and Navigation Service structure. * @param[in] p_ble_evt Event received from the BLE stack. */ -static void on_write(ble_lns_t * p_lns, ble_evt_t * p_ble_evt) +static void on_write(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt) { - ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; - - if (p_evt_write->handle == p_lns->loc_speed_handles.cccd_handle) + if (p_lns->conn_handle != p_ble_evt->evt.gatts_evt.conn_handle) { - on_loc_speed_cccd_write(p_lns, p_evt_write); - } - else if (p_evt_write->handle == p_lns->ctrl_point_handles.cccd_handle) - { - on_control_point_cccd_write(p_lns, p_evt_write); - } - else if (p_evt_write->handle == p_lns->navigation_handles.cccd_handle) - { - on_navigation_cccd_write(p_lns, p_evt_write); - } - -} - -/**@brief Write authorization request event handler. - * - * @details The write authorization request event handler is only called when writing to the control point. - * - * @param[in] p_lns Location and Navigation Service structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_rw_authorize_req(ble_lns_t * p_lns, ble_evt_t * p_ble_evt) -{ - ble_gatts_evt_rw_authorize_request_t * p_authorize_request; - - p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request); - - if ( - (p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) - && - (p_authorize_request->request.write.handle == p_lns->ctrl_point_handles.value_handle) - && - (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) - && - (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) - && - (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) - ) - { - on_ctrl_point_write(p_lns, &(p_authorize_request->request.write)); + return; } - -} -/**@brief Tx Complete event handler. This is used to retry sending a packet. - * - * @details Tx Complete event handler. - * Handles WRITE events from the BLE stack and if an indication was pending try sending it - * again. - * - * @param[in] p_lns Location navigation structure. - */ -static void on_tx_complete(ble_lns_t * p_lns) -{ - if (p_lns->control_point_procedure_status == BLE_LNS_CTRLPT_STATE_INDICATION_PENDING) - { - ctrl_point_response_send(p_lns); - } -} + const ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; -/**@brief Function for handling the BLE_GATTS_EVT_HVC event. A control point procedure is finished when its indication is acknowledged. - * - * @param[in] p_lns LNS structure. - * @param[in] p_ble_evt Event received from the BLE stack. - */ -static void on_hvc_confirm(ble_lns_t * p_lns, ble_evt_t * p_ble_evt) -{ - if (p_ble_evt->evt.gatts_evt.params.hvc.handle == p_lns->ctrl_point_handles.value_handle) + if (p_evt_write->handle == p_lns->ctrlpt_handles.cccd_handle) { - if (p_lns->control_point_procedure_status == BLE_LNS_CTRLPT_STATE_IND_CONFIRM_PENDING) - { - p_lns->control_point_procedure_status = BLE_LNS_CTRLPT_STATE_NO_PROC_IN_PROGRESS; - } - else - { - if (p_lns->error_handler != NULL) - { - p_lns->error_handler(NRF_ERROR_INVALID_STATE); - } - } + on_ctrl_pt_cccd_write(p_lns, p_evt_write); } -} - -void ble_lns_on_ble_evt(ble_lns_t * p_lns, ble_evt_t * p_ble_evt) -{ - if (p_lns == NULL || p_ble_evt == NULL) + else if (p_evt_write->handle == p_lns->loc_speed_handles.cccd_handle) { - return; + on_loc_speed_cccd_write(p_lns, p_evt_write); } - - - switch (p_ble_evt->header.evt_id) + else if (p_evt_write->handle == p_lns->navigation_handles.cccd_handle) { - case BLE_GAP_EVT_CONNECTED: - on_connect(p_lns, p_ble_evt); - break; - - case BLE_GAP_EVT_DISCONNECTED: - if (p_ble_evt->evt.gap_evt.conn_handle == p_lns->conn_handle) - { - on_disconnect(p_lns, p_ble_evt); - } - break; - - case BLE_GATTS_EVT_WRITE: - if (p_ble_evt->evt.gatts_evt.conn_handle == p_lns->conn_handle) - { - on_write(p_lns, p_ble_evt); - } - break; - - case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: - if (p_ble_evt->evt.gatts_evt.conn_handle == p_lns->conn_handle) - { - on_rw_authorize_req(p_lns, p_ble_evt); - } - break; - - case BLE_GATTS_EVT_HVC: - if (p_ble_evt->evt.gatts_evt.conn_handle == p_lns->conn_handle) - { - on_hvc_confirm(p_lns, p_ble_evt); - } - break; - - case BLE_EVT_TX_COMPLETE: - on_tx_complete(p_lns); - break; - - default: - // no implementation - break; + on_nav_cccd_write(p_lns, p_evt_write); } } + +/**@brief Tx Complete event handler. This is used to retry sending a packet. + * + * @details Tx Complete event handler. + * Handles WRITE events from the BLE stack and if an indication was pending try sending it + * again. + * + * @param[in] p_lns Location navigation structure. + */ +static void on_tx_complete(ble_lns_t * p_lns) +{ + notification_buffer_process(p_lns); +} + + /**@brief Encode position quality. * * @param[in] p_lns Location and Navigation Service structure. @@ -813,13 +302,15 @@ void ble_lns_on_ble_evt(ble_lns_t * p_lns, ble_evt_t * p_ble_evt) * * @return Size of encoded data. */ -static uint8_t pos_qual_encode(ble_lns_t * p_lns, ble_lns_pos_quality_t const * p_pos_qual, uint8_t * p_encoded_buffer) +static uint8_t pos_qual_encode(ble_lns_t const * p_lns, + ble_lns_pos_quality_t const * p_pos_qual, + uint8_t * p_encoded_buffer) { uint16_t flags = 0; uint8_t len = 2; // flags are added at last - + flags |= ((uint16_t)p_pos_qual->position_status << 7) & POS_QUAL_FLAG_POSITION_STATUS; - + if (p_pos_qual->number_of_satellites_in_solution_present) { flags |= POS_QUAL_FLAG_NUM_SATS_IN_SOLUTION_PRESENT; @@ -843,7 +334,7 @@ static uint8_t pos_qual_encode(ble_lns_t * p_lns, ble_lns_pos_quality_t const * flags |= POS_QUAL_FLAG_EHPE_PRESENT; len += uint32_encode(p_pos_qual->ehpe, &p_encoded_buffer[len]); } - + if (p_pos_qual->evpe_present) { flags |= POS_QUAL_FLAG_EVPE_PRESENT; @@ -861,7 +352,7 @@ static uint8_t pos_qual_encode(ble_lns_t * p_lns, ble_lns_pos_quality_t const * flags |= POS_QUAL_FLAG_VDOP_PRESENT; p_encoded_buffer[len++] = p_pos_qual->vdop; } - + // Flags field uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function" @@ -869,113 +360,133 @@ static uint8_t pos_qual_encode(ble_lns_t * p_lns, ble_lns_pos_quality_t const * } -/**@brief Encode Location and Speed data. - * - * @details The Location and Speed data will be encoded into two packets. Each packet has its own flags. +/**@brief Encode Location and Speed data packet 1 * * @param[in] p_lns Location and Navigation Service structure. * @param[in] p_loc_speed Location and Speed data to be encoded. - * @param[out] p_encoded_buffer1 First buffer where encoded data will be written. - * @param[out] p_encoded_buffer2 Second buffer where encoded data will be written. - * @param[out] p_lengths The lengths of the resulting buffers. + * @param[out] p_encoded_buffer Pointer to buffer buffer where encoded data will be written. + * + * @return Size of encoded data. * */ -static void loc_speed_encode(ble_lns_t * p_lns, ble_lns_loc_speed_t const * p_loc_speed, - uint8_t * p_encoded_buffer1, uint8_t * p_encoded_buffer2, uint8_t * p_lengths) +static uint8_t loc_speed_encode_packet1(ble_lns_t const * p_lns, + ble_lns_loc_speed_t const * p_loc_speed, + uint8_t * p_encoded_buffer) { - uint16_t flags; + uint16_t flags = 0; + uint8_t len = 2; + + const ble_lncp_mask_t mask = ble_lncp_mask_get(&p_lns->ctrl_pt); - // Encode packet 1 - flags = 0; - p_lengths[0] = 2; - // Instantaneous Speed if (p_lns->available_features & BLE_LNS_FEATURE_INSTANT_SPEED_SUPPORTED) { - if ((p_loc_speed->instant_speed_present)&&(!p_lns->mask.instantaneous_speed)) + if (p_loc_speed->instant_speed_present && !mask.instantaneous_speed) { flags |= LOC_SPEED_FLAG_INSTANT_SPEED_PRESENT; flags |= ((uint16_t)p_loc_speed->data_format<<9) & LOC_SPEED_FLAG_SPEED_AND_DIST_FORMAT; - p_lengths[0] += uint16_encode(p_loc_speed->instant_speed, &p_encoded_buffer1[p_lengths[0]]); + len += uint16_encode(p_loc_speed->instant_speed, &p_encoded_buffer[len]); } } - // Total Distance + // Total Distance if (p_lns->available_features & BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED) { - if ((p_loc_speed->total_distance_present)&&(!p_lns->mask.total_distance)) + if (p_loc_speed->total_distance_present && !mask.total_distance) { + const uint32_t total_distance = ble_lncp_total_distance_get(&p_lns->ctrl_pt); flags |= LOC_SPEED_FLAG_TOTAL_DISTANCE_PRESENT; - p_encoded_buffer1[p_lengths[0]++] = ((p_loc_speed->total_distance >> 0) & 0xFF); - p_encoded_buffer1[p_lengths[0]++] = ((p_loc_speed->total_distance >> 8) & 0xFF); - p_encoded_buffer1[p_lengths[0]++] = ((p_loc_speed->total_distance >> 16) & 0xFF); + len += uint24_encode(total_distance, &p_encoded_buffer[len]); } } - + // Location if (p_lns->available_features & BLE_LNS_FEATURE_LOCATION_SUPPORTED) { - if ((p_loc_speed->location_present)&&(!p_lns->mask.location)) + if (p_loc_speed->location_present && !mask.location) { flags |= LOC_SPEED_FLAG_LOCATION_PRESENT; flags |= ((uint16_t)p_loc_speed->position_status <<7) & LOC_SPEED_FLAG_POSITION_STATUS; - p_lengths[0] += uint32_encode(p_loc_speed->latitude, &p_encoded_buffer1[p_lengths[0]]); - p_lengths[0] += uint32_encode(p_loc_speed->longitude, &p_encoded_buffer1[p_lengths[0]]); + len += uint32_encode(p_loc_speed->latitude, &p_encoded_buffer[len]); + len += uint32_encode(p_loc_speed->longitude, &p_encoded_buffer[len]); } } - + // Flags field - uint16_encode(flags, &p_encoded_buffer1[0]); //lint !e534 "Ignoring return value of function" + uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function" + + return len; +} + + +/**@brief Encode Location and Speed data packet 2 + * + * @param[in] p_lns Location and Navigation Service structure. + * @param[in] p_loc_speed Location and Speed data to be encoded. + * @param[out] p_encoded_buffer Pointer to buffer buffer where encoded data will be written. + * + * @return Size of encoded data. + * + */ +static uint8_t loc_speed_encode_packet2(ble_lns_t const * p_lns, + ble_lns_loc_speed_t const * p_loc_speed, + uint8_t * p_encoded_buffer) +{ + uint16_t flags = 0; + uint8_t len = 2; + + const ble_lncp_mask_t mask = ble_lncp_mask_get(&p_lns->ctrl_pt); - // Encode packet 2 flags = 0; - p_lengths[1] = 2; - + len = 2; + // Elevation if (p_lns->available_features & BLE_LNS_FEATURE_ELEVATION_SUPPORTED) { - if ((p_loc_speed->elevation_present)&&(!p_lns->mask.elevation)) + if (p_loc_speed->elevation_present && !mask.elevation) { + const uint32_t elevation = ble_lncp_elevation_get(&p_lns->ctrl_pt); + flags |= LOC_SPEED_FLAG_ELEVATION_PRESENT; - flags |= ((uint16_t)p_loc_speed->elevation_source<<10)& LOC_SPEED_FLAG_ELEVATION_SOURCE; - p_encoded_buffer2[p_lengths[1]++] = ((p_loc_speed->elevation >> 0) & 0xFF); - p_encoded_buffer2[p_lengths[1]++] = ((p_loc_speed->elevation >> 8) & 0xFF); - p_encoded_buffer2[p_lengths[1]++] = ((p_loc_speed->elevation >> 16) & 0xFF); + flags |= ((uint16_t) p_loc_speed->elevation_source << 10) & LOC_SPEED_FLAG_ELEVATION_SOURCE; + len += uint24_encode(elevation, &p_encoded_buffer[len]); } } - + // Heading if (p_lns->available_features & BLE_LNS_FEATURE_HEADING_SUPPORTED) { - if ((p_loc_speed->heading_present)&&(!p_lns->mask.heading)) + if (p_loc_speed->heading_present && !mask.heading) { flags |= LOC_SPEED_FLAG_HEADING_PRESENT; - flags |= ((uint16_t)p_loc_speed->heading_source<<12) & LOC_SPEED_FLAG_HEADING_SOURCE; - p_lengths[1] += uint16_encode(p_loc_speed->heading, &p_encoded_buffer2[p_lengths[1]]); + flags |= ((uint16_t) p_loc_speed->heading_source << 12) & LOC_SPEED_FLAG_HEADING_SOURCE; + len += uint16_encode(p_loc_speed->heading, &p_encoded_buffer[len]); } } - + // Rolling Time if (p_lns->available_features & BLE_LNS_FEATURE_ROLLING_TIME_SUPPORTED) { - if ((p_loc_speed->rolling_time_present)&&(!p_lns->mask.rolling_time)) + if ((p_loc_speed->rolling_time_present && !mask.rolling_time)) { flags |= LOC_SPEED_FLAG_ROLLING_TIME_PRESENT; - p_encoded_buffer2[p_lengths[1]++] = p_loc_speed->rolling_time; + p_encoded_buffer[len++] = p_loc_speed->rolling_time; } } // UTC Time if (p_lns->available_features & BLE_LNS_FEATURE_UTC_TIME_SUPPORTED) { - if ((p_loc_speed->utc_time_time_present)&&(!p_lns->mask.utc_time)) + if ((p_loc_speed->utc_time_time_present && !mask.utc_time)) { flags |= LOC_SPEED_FLAG_UTC_TIME_PRESENT; - p_lengths[1] += ble_date_time_encode(&p_loc_speed->utc_time, &p_encoded_buffer2[p_lengths[1]]); + len += ble_date_time_encode(&p_loc_speed->utc_time, &p_encoded_buffer[len]); } - } + } // Flags field - uint16_encode(flags, &p_encoded_buffer2[0]); //lint !e534 "Ignoring return value of function" + uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function" + + return len; } @@ -987,17 +498,19 @@ static void loc_speed_encode(ble_lns_t * p_lns, ble_lns_loc_speed_t const * p_lo * * @return Size of encoded data. */ -static uint8_t navigation_encode(ble_lns_t * p_lns, ble_lns_navigation_t const * p_navigation, uint8_t * p_encoded_buffer) +static uint8_t navigation_encode(ble_lns_t const * p_lns, + ble_lns_navigation_t const * p_navigation, + uint8_t * p_encoded_buffer) { uint16_t flags = 0; uint8_t len = 2; // Bearing len += uint16_encode(p_navigation->bearing, &p_encoded_buffer[len]); - + // Heading len += uint16_encode(p_navigation->heading, &p_encoded_buffer[len]); - + // Remaining Distance if (p_lns->available_features & BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED) { @@ -1009,7 +522,7 @@ static uint8_t navigation_encode(ble_lns_t * p_lns, ble_lns_navigation_t const * p_encoded_buffer[len++] = ((p_navigation->remaining_distance >> 16) & 0xFF); } } - + // Remaining Vertical Distance if (p_lns->available_features & BLE_LNS_FEATURE_REMAINING_VERT_DISTANCE_SUPPORTED) { @@ -1021,7 +534,7 @@ static uint8_t navigation_encode(ble_lns_t * p_lns, ble_lns_navigation_t const * p_encoded_buffer[len++] = ((p_navigation->remaining_vert_distance >> 16) & 0xFF); } } - + // Estimated Time of Arrival if (p_lns->available_features & BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED) { @@ -1031,13 +544,13 @@ static uint8_t navigation_encode(ble_lns_t * p_lns, ble_lns_navigation_t const * len += ble_date_time_encode(&p_navigation->eta, &p_encoded_buffer[len]); } } - + flags |= ((uint16_t)p_navigation->position_status <<3) & NAV_FLAG_POSITION_STATUS; flags |= ((uint16_t)p_navigation->heading_source <<5) & NAV_FLAG_HEADING_SOURCE; flags |= ((uint16_t)p_navigation->navigation_indicator_type<<6)& NAV_FLAG_NAVIGATION_INDICATOR_TYPE; flags |= ((uint16_t)p_navigation->waypoint_reached <<7)& NAV_FLAG_WAYPOINT_REACHED; flags |= ((uint16_t)p_navigation->destination_reached <<8)& NAV_FLAG_DESTINATION_REACHED; - + // Flags field uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function" @@ -1052,28 +565,29 @@ static uint8_t navigation_encode(ble_lns_t * p_lns, ble_lns_navigation_t const * * * @return NRF_SUCCESS on success, otherwise an error code. */ -static uint32_t loc_and_nav_feature_char_add(ble_lns_t * p_lns, const ble_lns_init_t * p_lns_init) +static ret_code_t loc_and_nav_feature_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init) { uint8_t init_value_encoded[sizeof(uint32_t)]; uint8_t len; ble_add_char_params_t add_char_params; - + len = uint32_encode(p_lns_init->available_features, init_value_encoded); - + memset(&add_char_params, 0, sizeof(add_char_params)); - + add_char_params.uuid = BLE_UUID_LN_FEATURE_CHAR; add_char_params.max_len = len; add_char_params.init_len = len; add_char_params.p_init_value = &init_value_encoded[0]; add_char_params.char_props.read = true; - add_char_params.read_access = p_lns_init->loc_nav_feature_security_req_read_perm; - - return characteristic_add(p_lns->service_handle, + add_char_params.read_access = p_lns_init->loc_nav_feature_security_req_read_perm; + + return characteristic_add(p_lns->service_handle, &add_char_params, &p_lns->feature_handles); } + /**@brief Add Location and Speed characteristic. * * @param[in] p_lns Location and Navigation Service structure. @@ -1081,31 +595,30 @@ static uint32_t loc_and_nav_feature_char_add(ble_lns_t * p_lns, const ble_lns_in * * @return NRF_SUCCESS on success, otherwise an error code. */ -static uint32_t loc_speed_char_add(ble_lns_t * p_lns, - const ble_lns_init_t * p_lns_init) +static ret_code_t loc_speed_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init) { uint8_t encoded_initial_loc_speed1[BLE_L2CAP_MTU_DEF ]; - uint8_t encoded_initial_loc_speed2[BLE_L2CAP_MTU_DEF ]; - uint8_t lengths[2]; + uint8_t len; ble_add_char_params_t add_char_params; - - loc_speed_encode(p_lns, p_lns_init->p_location_speed, &encoded_initial_loc_speed1[0], &encoded_initial_loc_speed2[0], &lengths[0]); - + + len = loc_speed_encode_packet1(p_lns, p_lns_init->p_location_speed, &encoded_initial_loc_speed1[0]); + memset(&add_char_params, 0, sizeof(add_char_params)); - + add_char_params.uuid = BLE_UUID_LN_LOCATION_AND_SPEED_CHAR; add_char_params.max_len = BLE_L2CAP_MTU_DEF ; - add_char_params.init_len = lengths[0]; + add_char_params.init_len = len; add_char_params.p_init_value = &encoded_initial_loc_speed1[0]; add_char_params.is_var_len = true; - add_char_params.char_props.notify = true; - add_char_params.cccd_write_access = p_lns_init->loc_speed_security_req_cccd_write_perm; - - return characteristic_add(p_lns->service_handle, + add_char_params.char_props.notify = true; + add_char_params.cccd_write_access = p_lns_init->loc_speed_security_req_cccd_write_perm; + + return characteristic_add(p_lns->service_handle, &add_char_params, &p_lns->loc_speed_handles); } + /**@brief Add Location and Navigation position quality characteristic. * * @param[in] p_lns Location and Navigation Service structure. @@ -1113,54 +626,28 @@ static uint32_t loc_speed_char_add(ble_lns_t * p_lns, * * @return NRF_SUCCESS on success, otherwise an error code. */ -static uint32_t pos_quality_char_add(ble_lns_t * p_lns, const ble_lns_init_t * p_lns_init) +static ret_code_t pos_quality_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init) { uint8_t len; uint8_t init_value_encoded[BLE_L2CAP_MTU_DEF]; ble_add_char_params_t add_char_params; - + len = pos_qual_encode(p_lns, p_lns_init->p_position_quality, init_value_encoded); - + memset(&add_char_params, 0, sizeof(add_char_params)); - + add_char_params.uuid = BLE_UUID_LN_POSITION_QUALITY_CHAR; add_char_params.max_len = BLE_L2CAP_MTU_DEF ; add_char_params.init_len = len; add_char_params.p_init_value = init_value_encoded; add_char_params.char_props.read = true; - add_char_params.read_access = p_lns_init->position_quality_security_req_read_perm; - - return characteristic_add(p_lns->service_handle, + add_char_params.read_access = p_lns_init->position_quality_security_req_read_perm; + + return characteristic_add(p_lns->service_handle, &add_char_params, &p_lns->pos_qual_handles); } -/**@brief Add Location and Navigation Control Point characteristic. - * - * @param[in] p_lns Location and Navigation Service structure. - * - * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. - */ -static uint32_t loc_and_nav_control_point_char_add(ble_lns_t * p_lns, const ble_lns_init_t * p_lns_init) -{ - ble_add_char_params_t add_char_params; - - memset(&add_char_params, 0, sizeof(add_char_params)); - - add_char_params.uuid = BLE_UUID_LN_CONTROL_POINT_CHAR; - add_char_params.max_len = 0; - add_char_params.char_props.indicate = true; - add_char_params.char_props.write = true; - add_char_params.is_defered_write = true; - add_char_params.is_var_len = true; - add_char_params.max_len = BLE_L2CAP_MTU_DEF; - add_char_params.write_access = p_lns_init->ctrl_point_security_req_write_perm; - add_char_params.cccd_write_access = p_lns_init->ctrl_point_security_req_cccd_write_perm; - - return characteristic_add(p_lns->service_handle, - &add_char_params, - &p_lns->ctrl_point_handles); -} /**@brief Add Navigation characteristic. * @@ -1169,36 +656,36 @@ static uint32_t loc_and_nav_control_point_char_add(ble_lns_t * p_lns, const ble_ * * @return NRF_SUCCESS on success, otherwise an error code. */ -static uint32_t navigation_char_add(ble_lns_t * p_lns, - const ble_lns_init_t * p_lns_init) +static ret_code_t navigation_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init) { - ble_add_char_params_t add_char_params; - + ble_add_char_params_t add_char_params; + memset(&add_char_params, 0, sizeof(add_char_params)); - + add_char_params.uuid = BLE_UUID_LN_NAVIGATION_CHAR; add_char_params.max_len = BLE_LNS_NAV_MAX_LEN; add_char_params.init_len = 0; add_char_params.p_init_value = NULL; add_char_params.char_props.notify = true; add_char_params.cccd_write_access = p_lns_init->navigation_security_req_cccd_write_perm; - - return characteristic_add(p_lns->service_handle, + + return characteristic_add(p_lns->service_handle, &add_char_params, &p_lns->navigation_handles); } + /** @brief Check if there is a mismatch in initialization parameters. * * @details It is possible to give an input which has an internal mismatch. Such a mismatch can arise in two different ways. - * One possibility is a mismatch between the characteristic present indicators and the available features specified. + * One possibility is a mismatch between the characteristic present indicators and the available features specified. * The other mismatch arises when no pointer to the characteristic data structure is specified. * * @param[in] p_lns_init The init structure which will be checked - * + * * @return false if there is no mismatch. true if there is a mismatch */ -static bool init_param_mismatch_present(const ble_lns_init_t * p_lns_init) +static bool init_param_mismatch_present(ble_lns_init_t const * p_lns_init) { if (p_lns_init->is_position_quality_present == false) { @@ -1218,7 +705,7 @@ static bool init_param_mismatch_present(const ble_lns_init_t * p_lns_init) { return true; } - } + } else if (p_lns_init->is_position_quality_present == true) { if (p_lns_init->p_position_quality == NULL) @@ -1226,7 +713,7 @@ static bool init_param_mismatch_present(const ble_lns_init_t * p_lns_init) return true; } } - + if (p_lns_init->is_control_point_present == false) { if (p_lns_init->available_features & @@ -1238,13 +725,13 @@ static bool init_param_mismatch_present(const ble_lns_init_t * p_lns_init) return true; } } - + if (p_lns_init->is_navigation_present == false) { - if (p_lns_init->available_features & - (BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED | + if (p_lns_init->available_features & + (BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED | BLE_LNS_FEATURE_REMAINING_VERT_DISTANCE_SUPPORTED | - BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED) + BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED) ) { return true; @@ -1252,7 +739,7 @@ static bool init_param_mismatch_present(const ble_lns_init_t * p_lns_init) if (p_lns_init->p_navigation != NULL) { return true; - } + } } else if (p_lns_init->is_navigation_present == true) { @@ -1267,88 +754,99 @@ static bool init_param_mismatch_present(const ble_lns_init_t * p_lns_init) { return true; } - + return false; } -uint32_t ble_lns_init(ble_lns_t * p_lns, const ble_lns_init_t * p_lns_init) + +void ble_lns_on_ble_evt(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt) { - if (p_lns == NULL || p_lns_init == NULL) + VERIFY_PARAM_NOT_NULL_VOID(p_lns); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + + ble_lncp_on_ble_evt(&p_lns->ctrl_pt, p_ble_evt); + + switch (p_ble_evt->header.evt_id) { - return NRF_ERROR_NULL; + case BLE_GAP_EVT_CONNECTED: + on_connect(p_lns, p_ble_evt); + break; + + case BLE_GAP_EVT_DISCONNECTED: + on_disconnect(p_lns, p_ble_evt); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_lns, p_ble_evt); + break; + + case BLE_EVT_TX_COMPLETE: + on_tx_complete(p_lns); + break; + + default: + // no implementation + break; } - +} + + +ret_code_t ble_lns_init(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init) +{ + VERIFY_PARAM_NOT_NULL(p_lns); + VERIFY_PARAM_NOT_NULL(p_lns_init); + if (init_param_mismatch_present(p_lns_init) == true) { - return NRF_ERROR_INVALID_PARAM; + return NRF_ERROR_INVALID_PARAM; } - - - uint32_t err_code; - ble_uuid_t service_uuid; - + + uint32_t err_code; + ble_uuid_t service_uuid; + ble_lncp_init_t lncp_init; + // Initialize service structure - p_lns->evt_handler = p_lns_init->evt_handler; - p_lns->error_handler = p_lns_init->error_handler; - p_lns->conn_handle = BLE_CONN_HANDLE_INVALID; - p_lns->available_features = p_lns_init->available_features; - p_lns->is_navigation_present = p_lns_init->is_navigation_present; - - memset(&p_lns->mask, 0, sizeof (p_lns->mask)); - - p_lns->p_location_speed = p_lns_init->p_location_speed; - p_lns->p_position_quality = p_lns_init->p_position_quality; - p_lns->p_navigation = p_lns_init->p_navigation; - - p_lns->control_point_procedure_status = BLE_LNS_CTRLPT_STATE_NO_PROC_IN_PROGRESS; - - memset(p_lns->ctrl_pnt_cccd_handle_status, 0, INT16_LEN); - memset(p_lns->navigation_cccd_handle_status, 0, INT16_LEN); - memset(p_lns->loc_speed_cccd_handle_status, 0, INT16_LEN); - - p_lns->is_navigation_running = false; - p_lns->number_of_routes = 0; - p_lns->selected_route = BLE_LNS_INVALID_ROUTE; - p_lns->fix_rate = BLE_LNS_NO_FIX; - - for (int i = 0; i < BLE_LNS_MAX_NUM_ROUTES; i++) - { - p_lns->routes[i].route_id = BLE_LNS_INVALID_ROUTE; - } - + p_lns->evt_handler = p_lns_init->evt_handler; + p_lns->error_handler = p_lns_init->error_handler; + p_lns->conn_handle = BLE_CONN_HANDLE_INVALID; + p_lns->available_features = p_lns_init->available_features; + p_lns->is_navigation_present = p_lns_init->is_navigation_present; + + // clear pending notifications + p_lns->pending_loc_speed_notifications[0].is_pending = false; + p_lns->pending_loc_speed_notifications[1].is_pending = false; + p_lns->pending_navigation_notification.is_pending = false; + + p_lns->p_location_speed = p_lns_init->p_location_speed; + p_lns->p_position_quality = p_lns_init->p_position_quality; + p_lns->p_navigation = p_lns_init->p_navigation; + + p_lns->is_loc_speed_notification_enabled = false; + p_lns->is_nav_notification_enabled = false; + + ble_ln_db_init(); + // Add service BLE_UUID_BLE_ASSIGN(service_uuid, BLE_UUID_LOCATION_AND_NAVIGATION_SERVICE); - + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &service_uuid, &p_lns->service_handle); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - + VERIFY_SUCCESS(err_code); + // Add location and navigation feature characteristic err_code = loc_and_nav_feature_char_add(p_lns, p_lns_init); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Add location and speed characteristic err_code = loc_speed_char_add(p_lns, p_lns_init); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - + VERIFY_SUCCESS(err_code); + if (p_lns_init->is_position_quality_present) { // Add Position quality characteristic err_code = pos_quality_char_add(p_lns, p_lns_init); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } - else + else { p_lns->pos_qual_handles.cccd_handle = BLE_GATT_HANDLE_INVALID; p_lns->pos_qual_handles.sccd_handle = BLE_GATT_HANDLE_INVALID; @@ -1356,225 +854,163 @@ uint32_t ble_lns_init(ble_lns_t * p_lns, const ble_lns_init_t * p_lns_init) p_lns->pos_qual_handles.value_handle = BLE_GATT_HANDLE_INVALID; } - if (p_lns_init->is_control_point_present) - { - // Add control pointer characteristic - err_code = loc_and_nav_control_point_char_add(p_lns, p_lns_init); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - } - else - { - p_lns->ctrl_point_handles.cccd_handle = BLE_GATT_HANDLE_INVALID; - p_lns->ctrl_point_handles.sccd_handle = BLE_GATT_HANDLE_INVALID; - p_lns->ctrl_point_handles.user_desc_handle = BLE_GATT_HANDLE_INVALID; - p_lns->ctrl_point_handles.value_handle = BLE_GATT_HANDLE_INVALID; - } - if (p_lns_init->is_navigation_present) { // Add navigation characteristic err_code = navigation_char_add(p_lns, p_lns_init); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } - else + else { p_lns->navigation_handles.cccd_handle = BLE_GATT_HANDLE_INVALID; p_lns->navigation_handles.sccd_handle = BLE_GATT_HANDLE_INVALID; p_lns->navigation_handles.user_desc_handle = BLE_GATT_HANDLE_INVALID; - p_lns->navigation_handles.value_handle = BLE_GATT_HANDLE_INVALID; + p_lns->navigation_handles.value_handle = BLE_GATT_HANDLE_INVALID; + } + + if (p_lns_init->is_control_point_present) + { + lncp_init.error_handler = p_lns_init->error_handler; + lncp_init.evt_handler = p_lns_init->lncp_evt_handler; + lncp_init.write_perm = p_lns_init->ctrl_point_security_req_write_perm; + lncp_init.cccd_write_perm = p_lns_init->ctrl_point_security_req_cccd_write_perm; + lncp_init.available_features = p_lns_init->available_features; + lncp_init.is_position_quality_present = p_lns_init->is_position_quality_present; + lncp_init.is_navigation_present = p_lns_init->is_navigation_present; + + lncp_init.total_distance = p_lns_init->p_location_speed->total_distance; + lncp_init.elevation = p_lns_init->p_location_speed->elevation; + + lncp_init.service_handle = p_lns->service_handle; + lncp_init.navigation_handles = p_lns->navigation_handles; + + // Add control pointer characteristic + err_code = ble_lncp_init(&p_lns->ctrl_pt, &lncp_init); + VERIFY_SUCCESS(err_code); + + memcpy(&p_lns->ctrlpt_handles, &p_lns->ctrl_pt.ctrlpt_handles, sizeof(ble_gatts_char_handles_t)); } - + + NRF_LOG_DEBUG("Initialized\r\n"); + return NRF_SUCCESS; } -uint32_t ble_lns_loc_speed_send(ble_lns_t * p_lns) +ret_code_t ble_lns_loc_speed_send(ble_lns_t * p_lns) { - if (p_lns == NULL) - { - return NRF_ERROR_NULL; - } - + VERIFY_PARAM_NOT_NULL(p_lns); + if (p_lns->conn_handle == BLE_CONN_HANDLE_INVALID) { return NRF_ERROR_INVALID_STATE; } - - uint32_t err_code; - - - // Location speed data is always sent as two packets. - uint8_t encoded_loc_speed1[BLE_L2CAP_MTU_DEF]; - uint8_t encoded_loc_speed2[BLE_L2CAP_MTU_DEF]; - uint8_t lengths[2]; - uint16_t hvx_len; - ble_gatts_hvx_params_t hvx_params; - - loc_speed_encode(p_lns, p_lns->p_location_speed, &encoded_loc_speed1[0], &encoded_loc_speed2[0], &lengths[0]); - - memset(&hvx_params, 0, sizeof(hvx_params)); - - hvx_params.handle = p_lns->loc_speed_handles.value_handle; - hvx_params.type = BLE_GATT_HVX_NOTIFICATION; - hvx_params.offset = 0; - hvx_params.p_len = &hvx_len; - - // send packet 1 - - hvx_len = lengths[0]; - hvx_params.p_data = &encoded_loc_speed1[0]; - - err_code = sd_ble_gatts_hvx(p_lns->conn_handle, &hvx_params); - - if (err_code == NRF_ERROR_INVALID_STATE) + + if (!p_lns->is_loc_speed_notification_enabled) { - return err_code; + return NRF_ERROR_INVALID_STATE; } - - if ((err_code == NRF_SUCCESS) && (hvx_len != lengths[0])) + + notification_t * notif1 = &p_lns->pending_loc_speed_notifications[0]; + notification_t * notif2 = &p_lns->pending_loc_speed_notifications[1]; + + // clear previous unsent data. Previous data is invalid. + notif1->is_pending = false; + notif2->is_pending = false; + + // check if it is necessary to send packet 1 + if (p_lns->available_features & (BLE_LNS_FEATURE_INSTANT_SPEED_SUPPORTED + | BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED + | BLE_LNS_FEATURE_LOCATION_SUPPORTED)) { - return NRF_ERROR_DATA_SIZE; + // encode + notif1->len = loc_speed_encode_packet1(p_lns, p_lns->p_location_speed, ¬if1->data[0]); + notif1->handle = p_lns->loc_speed_handles.value_handle; + notif1->is_pending = true; + + // send + notification_buffer_process(p_lns); } - - - // send packet 2 - hvx_len = lengths[1]; - hvx_params.p_data = &encoded_loc_speed2[0]; - - err_code = sd_ble_gatts_hvx(p_lns->conn_handle, &hvx_params); - - if ((err_code == NRF_SUCCESS) && (hvx_len != lengths[1])) + + // check if it is necessary to send packet 2 + if (p_lns->available_features & (BLE_LNS_FEATURE_ELEVATION_SUPPORTED + | BLE_LNS_FEATURE_HEADING_SUPPORTED + | BLE_LNS_FEATURE_ROLLING_TIME_SUPPORTED + | BLE_LNS_FEATURE_UTC_TIME_SUPPORTED)) { - return NRF_ERROR_DATA_SIZE; - } - + notif2->len = loc_speed_encode_packet2(p_lns, p_lns->p_location_speed, ¬if2->data[0]); + notif2->handle = p_lns->loc_speed_handles.value_handle; + notif2->is_pending = true; + // send + notification_buffer_process(p_lns); + } - return err_code; + return NRF_SUCCESS; } -uint32_t ble_lns_navigation_send(ble_lns_t * p_lns) + +ret_code_t ble_lns_navigation_send(ble_lns_t * p_lns) { - if (p_lns == NULL) - { - return NRF_ERROR_NULL; - } - + VERIFY_PARAM_NOT_NULL(p_lns); + if (p_lns->conn_handle == BLE_CONN_HANDLE_INVALID) { return NRF_ERROR_INVALID_STATE; } - - uint32_t err_code; - - // Send value if connected and notifying - if (p_lns->is_navigation_present) + + notification_t * notif = &p_lns->pending_navigation_notification; + + // clear previous unsent data. Previous data is invalid. + notif->is_pending = false; + + if (!p_lns->is_navigation_present) { - if (p_lns->is_navigation_running) - { - uint8_t encoded_navigation[BLE_L2CAP_MTU_DEF]; - uint16_t len; - uint16_t hvx_len; - ble_gatts_hvx_params_t hvx_params; - - len = navigation_encode(p_lns, p_lns->p_navigation, &encoded_navigation[0]); - hvx_len = len; - - memset(&hvx_params, 0, sizeof(hvx_params)); - - hvx_params.handle = p_lns->navigation_handles.value_handle; - hvx_params.type = BLE_GATT_HVX_NOTIFICATION; - hvx_params.offset = 0; - hvx_params.p_len = &hvx_len; - hvx_params.p_data = &encoded_navigation[0]; - - err_code = sd_ble_gatts_hvx(p_lns->conn_handle, &hvx_params); - if ((err_code == NRF_SUCCESS) && (hvx_len != len)) - { - err_code = NRF_ERROR_DATA_SIZE; - } - } - else - { - err_code = NRF_ERROR_INVALID_STATE; - } + return NRF_ERROR_NOT_SUPPORTED; + } + if (!p_lns->is_nav_notification_enabled) + { + return NRF_ERROR_INVALID_STATE; } - else + + if (!ble_lncp_is_navigation_running(&p_lns->ctrl_pt)) { - err_code = NRF_ERROR_NOT_SUPPORTED; + return NRF_ERROR_INVALID_STATE; } - return err_code; + notif->len = navigation_encode(p_lns, p_lns->p_navigation, ¬if->data[0]); + notif->handle = p_lns->navigation_handles.value_handle; + notif->is_pending = true; + + notification_buffer_process(p_lns); + + return NRF_SUCCESS; } -uint32_t ble_lns_add_route(ble_lns_t * p_lns, ble_lns_route_t * p_route) +ret_code_t ble_lns_add_route(ble_lns_t * p_lns, ble_lns_route_t * p_route) { - if (p_lns == NULL || p_route == NULL) - { - return NRF_ERROR_NULL; - } - + VERIFY_PARAM_NOT_NULL(p_lns); + VERIFY_PARAM_NOT_NULL(p_route); + if (p_lns->is_navigation_present == false) { return NRF_ERROR_NOT_SUPPORTED; } - - if (p_lns->number_of_routes >= BLE_LNS_MAX_NUM_ROUTES) - { - return NRF_ERROR_NO_MEM; - } - - // find an empty slot - for (int i = 0; i < BLE_LNS_MAX_NUM_ROUTES; i++) - { - if (p_lns->routes[i].route_id == BLE_LNS_INVALID_ROUTE) - { - memcpy(p_lns->routes[i].route_name, p_route->route_name, BLE_LNS_MAX_ROUTE_NAME_LEN); - p_lns->routes[i].route_id = i; - p_route->route_id = i; - - p_lns->number_of_routes++; - return NRF_SUCCESS; - } - } - // an inconsistency in the route the table - return NRF_ERROR_INTERNAL; + + return ble_ln_db_record_add(p_route); } -uint32_t ble_lns_remove_route(ble_lns_t * p_lns, uint16_t route_id) + +ret_code_t ble_lns_remove_route(ble_lns_t * p_lns, uint16_t route_id) { - if (p_lns == NULL) - { - return NRF_ERROR_NULL; - } - + VERIFY_PARAM_NOT_NULL(p_lns); + if (p_lns->is_navigation_present == false) { return NRF_ERROR_NOT_SUPPORTED; } - - if (route_id >= BLE_LNS_MAX_NUM_ROUTES) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (p_lns->routes[route_id].route_id != BLE_LNS_INVALID_ROUTE) - { - p_lns->routes[route_id].route_id = BLE_LNS_INVALID_ROUTE; - p_lns->number_of_routes--; - return NRF_SUCCESS; - } - else - { - return NRF_ERROR_INVALID_PARAM; - } -} + return ble_ln_db_record_delete(route_id); +} diff --git a/components/ble/ble_services/experimental_ble_lns/ble_lns.h b/components/ble/ble_services/experimental_ble_lns/ble_lns.h index 28164f4..d793c99 100644 --- a/components/ble/ble_services/experimental_ble_lns/ble_lns.h +++ b/components/ble/ble_services/experimental_ble_lns/ble_lns.h @@ -1,23 +1,51 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ble_sdk_srv_lns Location and Navigation Service + * @defgroup ble_lns Location and Navigation Service * @{ * @ingroup ble_sdk_srv * @brief Location and Navigation Service module. * - * @details This module implements the Location and Navigation Service with the Location and Speed, Position + * @details This module implements the Location and Navigation Service with the Location and Speed, Position * Quality, Feature, Control Point, and Navigation characteristics. * * If an event handler is supplied by the application, the Location and Navigation Service will @@ -30,177 +58,85 @@ #ifndef BLE_LNS_H__ #define BLE_LNS_H__ -#include -#include -#include "ble.h" #include "ble_srv_common.h" #include "ble_date_time.h" +#include "ble_ln_common.h" +#include "ble_ln_cp.h" +#include "sdk_common.h" + +#ifdef __cplusplus +extern "C" { +#endif -// Location and Navigation Service feature bits -#define BLE_LNS_FEATURE_INSTANT_SPEED_SUPPORTED (0x01 << 0) /**< Instaneous Speed Supported bit. */ -#define BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED (0x01 << 1) /**< Total Distance Supported bit. */ -#define BLE_LNS_FEATURE_LOCATION_SUPPORTED (0x01 << 2) /**< Location Supported bit. */ -#define BLE_LNS_FEATURE_ELEVATION_SUPPORTED (0x01 << 3) /**< Elevation Supported bit. */ -#define BLE_LNS_FEATURE_HEADING_SUPPORTED (0x01 << 4) /**< Heading Supported bit. */ -#define BLE_LNS_FEATURE_ROLLING_TIME_SUPPORTED (0x01 << 5) /**< Rolling Time Supported bit. */ -#define BLE_LNS_FEATURE_UTC_TIME_SUPPORTED (0x01 << 6) /**< UTC Time Supported bit. */ -#define BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED (0x01 << 7) /**< Remaining Distance Supported bit. */ -#define BLE_LNS_FEATURE_REMAINING_VERT_DISTANCE_SUPPORTED (0x01 << 8) /**< Remaining Vertical Distance Supported bit. */ -#define BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED (0x01 << 9) /**< Estimated Time of Arrival Supported bit. */ -#define BLE_LNS_FEATURE_NUM_SATS_IN_SOLUTION_SUPPORTED (0x01 << 10) /**< Number of Satellites in Solution Supported bit. */ -#define BLE_LNS_FEATURE_NUM_SATS_IN_VIEW_SUPPORTED (0x01 << 11) /**< Number of Satellites in View Supported bit. */ -#define BLE_LNS_FEATURE_TIME_TO_FIRST_FIX_SUPPORTED (0x01 << 12) /**< Time to First Fix Supported bit. */ -#define BLE_LNS_FEATURE_EST_HORZ_POS_ERROR_SUPPORTED (0x01 << 13) /**< Estimated Horizontal Position Error Supported bit. */ -#define BLE_LNS_FEATURE_EST_VERT_POS_ERROR_SUPPORTED (0x01 << 14) /**< Estimated Vertical Position Error Supported bit. */ -#define BLE_LNS_FEATURE_HORZ_DILUTION_OF_PRECISION_SUPPORTED (0x01 << 15) /**< Horizontal Dilution of Precision Supported bit. */ -#define BLE_LNS_FEATURE_VERT_DILUTION_OF_PRECISION_SUPPORTED (0x01 << 16) /**< Vertical Dilution of Precision Supported bit. */ -#define BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED (0x01 << 17) /**< Location and Speed Characteristic Content Masking Supported bit. */ -#define BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED (0x01 << 18) /**< Fix Rate Setting Supported bit. */ -#define BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED (0x01 << 19) /**< Elevation Setting Supported bit. */ -#define BLE_LNS_FEATURE_POSITION_STATUS_SUPPORTED (0x01 << 20) /**< Position Status Supported bit. */ - -#define BLE_LNS_MAX_ROUTE_NAME_LEN (BLE_L2CAP_MTU_DEF-5) /**< The maximum length of length of a route name. */ -#define BLE_LNS_MAX_NUM_ROUTES 3 /**< The maximum number of routes. This affects memory usage only. */ -#define BLE_LNS_INVALID_ROUTE 0xFFFF -#define BLE_LNS_NO_FIX 0xFF - -#define MAX_CTRL_POINT_RESP_PARAM_LEN BLE_LNS_MAX_ROUTE_NAME_LEN + 3 - -// Location and Navigation Control Point Op Code values -typedef enum { - OP_CODE_RESERVED = 0x00, /**< Reserved for future use. */ - OP_CODE_SET_CUMULATIVE_VALUE = 0x01, /**< Set Cumulative Value. */ - OP_CODE_MASK_LOC_SPEED_CONTENT = 0x02, /**< Mask Location and Speed Characteristic Content. */ - OP_CODE_NAV_CONTROL = 0x03, /**< Navigation Control. */ - OP_CODE_REQ_NUM_ROUTES = 0x04, /**< Request Number of Routes. */ - OP_CODE_REQ_NAME_OF_ROUTE = 0x05, /**< Request Name of Route. */ - OP_CODE_SELECT_ROUTE = 0x06, /**< Select Route. */ - OP_CODE_SET_FIX_RATE = 0x07, /**< Set Fix Rate. */ - OP_CODE_SET_ELEVATION = 0x08, /**< Set Elevation. */ - OP_CODE_RESPONSE_CODE = 0x20 /**< Response code. */ -} ble_lns_ctrl_point_opcodes_t; - -// Location and Navigation Control Point response values -typedef enum { - CONTROL_POINT_RESP_RESERVED = 0x00, /**< Reserved for future use. */ - CONTROL_POINT_RESP_SUCCESS = 0x01, /**< Success. */ - CONTROL_POINT_RESP_OP_CODE_NOT_SUPPORTED = 0x02, /**< Op Code not supported. */ - CONTROL_POINT_RESP_INVALID_PARAMETER = 0x03, /**< Invalid Parameter. */ - CONTROL_POINT_RESP_OPERATION_FAILED = 0x04, /**< Operation Failed. */ - CONTROL_POINT_RESP_PROC_ALR_IN_PROG = BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG, /**< Control point procedure is already in progress. */ - CONTROL_POINT_RESP_CCCD_CONFIG_IMPROPER = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR /**< CCCD is improperly configured. */ -} ble_lns_ctrl_point_response_codes_t; - /** @brief Location and Navigation event type. This list defines the possible events types from the Location and Navigation Service. */ -typedef enum { +typedef enum { + BLE_LNS_CTRLPT_EVT_INDICATION_ENABLED, /**< Control Point value indication was enabled. */ + BLE_LNS_CTRLPT_EVT_INDICATION_DISABLED, /**< Control Point value indication was disabled. */ BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_ENABLED, /**< Location and Speed value notification was enabled. */ - BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_DISABLED, /**< Location and Speed value notification was disabled. */ - BLE_LNS_LOC_SPEED_EVT_MASK_SET, /**< Location and Speed feature mask was set. */ - BLE_LNS_LOC_SPEED_EVT_TOTAL_DISTANCE_SET, /**< Location and Navigation total distance was set. */ - BLE_LNS_LOC_SPEED_EVT_ELEVATION_SET, /**< Location and Navigation elevation was set. */ - - BLE_LNS_POS_QUAL_EVT_FIX_RATE_SET, /**< Fix rate was set. */ - - BLE_LNS_CONTROL_POINT_EVT_INDICATION_ENABLED, /**< Location and Navigation Control point indication was enabled. */ - BLE_LNS_CONTROL_POINT_EVT_INDICATION_DISABLED, /**< Location and Navigation Control point indication was disabled. */ - - BLE_LNS_NAVIGATION_EVT_COMMAND, /**< A navigation command was issued. */ - BLE_LNS_NAVIGATION_EVT_ROUTE_SELECTED, /**< A route was selected. */ + BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_DISABLED, /**< Location and Speed value notification was disabled. */ BLE_LNS_NAVIGATION_EVT_NOTIFICATION_ENABLED, /**< Navigation value notification was enabled. */ - BLE_LNS_NAVIGATION_EVT_NOTIFICATION_DISABLED, /**< Navigation value notification was disabled. */ + BLE_LNS_NAVIGATION_EVT_NOTIFICATION_DISABLED, /**< Navigation value notification was disabled. */ } ble_lns_evt_type_t; -/** @brief Navigation commands. These commands can be sent to the control point and returned by an event callback. */ -typedef enum { - BLE_LNS_NAVIGATION_STOP = 0x00, /**< When received, is_navigation_running in @ref ble_lns_s will be set to false. */ - BLE_LNS_NAVIGATION_START = 0x01, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */ - BLE_LNS_NAVIGATION_PAUSE = 0x02, /**< When received, is_navigation_running in @ref ble_lns_s will be set to false. */ - BLE_LNS_NAVIGATION_CONTINUE = 0x03, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */ - BLE_LNS_NAVIGATION_SKIP_WAYPOINT = 0x04, /**< When received, is_navigation_running in @ref ble_lns_s will not be affected. */ - BLE_LNS_NAVIGATION_NEAREST = 0x05 /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */ -} ble_lns_navigation_command_t; - -/** @brief A mask can be used to temporarily enable and disable features of the Location and Speed characteristic.*/ -typedef struct { - bool instantaneous_speed; - bool total_distance; - bool location; - bool elevation; - bool heading; - bool rolling_time; - bool utc_time; -} ble_lns_mask_t; - /** @brief Location and Navigation event structure. When an event occurs, the data structures of the module are automatically updated. */ typedef struct { ble_lns_evt_type_t evt_type; - union { - ble_lns_mask_t mask; - uint32_t total_distance; - uint32_t elevation; - int8_t fix_rate; - ble_lns_navigation_command_t navigation_command; - uint16_t selected_route; - } params; } ble_lns_evt_t; -// Forward declarations of the ble_lns types. +// Forward declarations of the ble_lns types. typedef struct ble_lns_init_s ble_lns_init_t; typedef struct ble_lns_s ble_lns_t; typedef struct ble_lns_loc_speed_s ble_lns_loc_speed_t; typedef struct ble_lns_pos_quality_s ble_lns_pos_quality_t; typedef struct ble_lns_navigation_s ble_lns_navigation_t; + +typedef struct { + bool is_pending; + uint16_t handle; + uint16_t len; + uint8_t data[GATT_MTU_SIZE_DEFAULT]; +} notification_t; + + /**@brief Location and Navigation Service event handler type. */ -typedef void (*ble_lns_evt_handler_t) (ble_lns_t * p_lns, ble_lns_evt_t * p_evt); +typedef void (*ble_lns_evt_handler_t) (ble_lns_t const * p_lns, ble_lns_evt_t const * p_evt); + /**@brief Location and Navigation Service init structure. This structure contains all options and data needed to * initialize the service. */ struct ble_lns_init_s { - ble_lns_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Location and Navigation Service. */ - ble_srv_error_handler_t error_handler; /**< Errors will be sent back to this function. */ - - bool is_position_quality_present; /**< If set to true, the position quality characteristic will be added. Else not. */ - bool is_control_point_present; /**< If set to true, the control point characteristic will be added. Else not. */ - bool is_navigation_present; /**< If set to true, the navigation characteristic will be added. Else not. */ - - security_req_t loc_nav_feature_security_req_read_perm; /**< Read security level of the LN Feature characteristic. */ - security_req_t loc_speed_security_req_cccd_write_perm; /**< CCCD write security level of the Write Location and Speed characteristic. */ - security_req_t position_quality_security_req_read_perm; /**< Read security level of the Position Quality characteristic. */ - security_req_t navigation_security_req_cccd_write_perm; /**< CCCD write security level of the Navigation characteristic. */ - security_req_t ctrl_point_security_req_write_perm; /**< Read security level of the LN Control Point characteristic. */ - security_req_t ctrl_point_security_req_cccd_write_perm; /**< CCCD write security level of the LN Control Point characteristic. */ - - uint32_t available_features; /**< Value of the LN feature. */ - ble_lns_loc_speed_t * p_location_speed; /**< Initial Location and Speed. */ - ble_lns_pos_quality_t * p_position_quality; /**< Initial Position Quality. */ - ble_lns_navigation_t * p_navigation; /**< Initial Navigation data structure. */ + ble_lns_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Location and Navigation Service. */ + ble_lncp_evt_handler_t lncp_evt_handler; + ble_srv_error_handler_t error_handler; /**< Errors will be sent back to this function. */ + + bool is_position_quality_present; /**< If set to true, the position quality characteristic will be added. Else not. */ + bool is_control_point_present; /**< If set to true, the control point characteristic will be added. Else not. */ + bool is_navigation_present; /**< If set to true, the navigation characteristic will be added. Else not. */ + + security_req_t loc_nav_feature_security_req_read_perm; /**< Read security level of the LN Feature characteristic. */ + security_req_t loc_speed_security_req_cccd_write_perm; /**< CCCD write security level of the Write Location and Speed characteristic. */ + security_req_t position_quality_security_req_read_perm; /**< Read security level of the Position Quality characteristic. */ + security_req_t navigation_security_req_cccd_write_perm; /**< CCCD write security level of the Navigation characteristic. */ + security_req_t ctrl_point_security_req_write_perm; /**< Read security level of the LN Control Point characteristic. */ + security_req_t ctrl_point_security_req_cccd_write_perm; /**< CCCD write security level of the LN Control Point characteristic. */ + + uint32_t available_features; /**< Value of the LN feature. */ + ble_lns_loc_speed_t * p_location_speed; /**< Initial Location and Speed. */ + ble_lns_pos_quality_t * p_position_quality; /**< Initial Position Quality. */ + ble_lns_navigation_t * p_navigation; /**< Initial Navigation data structure. */ }; + /**@brief Definition of a navigation route.*/ -typedef struct ble_lns_routes_s +typedef struct { uint16_t route_id; uint8_t route_name[BLE_LNS_MAX_ROUTE_NAME_LEN]; } ble_lns_route_t; -/** @brief Location and Navigation Control Point procedure status (indicates if a procedure is in progress or not and which procedure is in progress).*/ -typedef enum { - BLE_LNS_CTRLPT_STATE_NO_PROC_IN_PROGRESS, /**< No procedure in progress. */ - BLE_LNS_CTRLPT_STATE_INDICATION_PENDING, /**< Control Point indication is pending. */ - BLE_LNS_CTRLPT_STATE_IND_CONFIRM_PENDING, /**< Waiting for the indication confirmation. */ -} ble_lns_ctrlpt_procedure_status_t; - -/** @brief Information included in a control point write response indication. */ -typedef struct { - uint8_t op_code; /**< Opcode of the control point write action. */ - uint8_t response_code; /**< Response code of the control point write action. */ - uint8_t response_param_len; - uint8_t response_param[MAX_CTRL_POINT_RESP_PARAM_LEN]; -} ble_lns_ctrlpt_response_t; - /**@brief Location and Navigation Service structure. This structure contains various status information for the service. */ struct ble_lns_s { @@ -213,28 +149,23 @@ struct ble_lns_s uint16_t service_handle; /**< Handle of Location and Navigation Service (as provided by the BLE stack). */ ble_gatts_char_handles_t loc_speed_handles; /**< Handles related to the Location and Speed characteristic. */ ble_gatts_char_handles_t feature_handles; /**< Handles related to the Location and Navigation Feature characteristic. */ - ble_gatts_char_handles_t ctrl_point_handles; /**< Handles related to the Location and Navigation Control Point characteristic. */ ble_gatts_char_handles_t navigation_handles; /**< Handles related to the Navigation characteristic. */ ble_gatts_char_handles_t pos_qual_handles; /**< Handles related to the Position Quality characteristic. */ + ble_gatts_char_handles_t ctrlpt_handles; uint32_t available_features; /**< Value of Location and Navigation feature. */ - - uint8_t loc_speed_cccd_handle_status[BLE_CCCD_VALUE_LEN]; /**< A buffer that stores the value of the CCCD handle of the Location and Speed characteristic.*/ - uint8_t ctrl_pnt_cccd_handle_status[BLE_CCCD_VALUE_LEN]; /**< A buffer that stores the value of the CCCD handle of the Control Point characteristic.*/ - uint8_t navigation_cccd_handle_status[BLE_CCCD_VALUE_LEN]; /**< A buffer that stores the value of the CCCD handle of the Navigation characteristic.*/ - uint8_t fix_rate; /**< The fix rate in seconds. */ - ble_lns_mask_t mask; /**< When a field is set to true, the feature is turned off. Can be set by writing to the control point. */ + bool is_loc_speed_notification_enabled; /**< True if notification is enabled on the Location and Speed characteristic. */ + bool is_nav_notification_enabled; /**< True if notification is enabled on the Navigation characteristic. */ + + notification_t pending_loc_speed_notifications[2]; /**< This buffer holds location and speed notifications. */ + notification_t pending_navigation_notification; /**< This buffer holds navigation notifications. */ ble_lns_loc_speed_t * p_location_speed; /**< Location and Speed. */ ble_lns_pos_quality_t * p_position_quality; /**< Position measurement quality. */ ble_lns_navigation_t * p_navigation; /**< Navigation data structure. */ - ble_lns_ctrlpt_procedure_status_t control_point_procedure_status; /**< Status of a control point action. */ - ble_lns_ctrlpt_response_t pending_ctrlpt_response; /**< Pending response data from a control point action. */ - bool is_navigation_running; /**< This variable can be set using the control point. Must be true to be able to send navigation updates. */ - uint16_t number_of_routes; /**< The number of routes present. */ - uint16_t selected_route; /**< Index of route selected. */ - ble_lns_route_t routes[BLE_LNS_MAX_NUM_ROUTES]; /**< The stored routes. */ + ble_lncp_t ctrl_pt; }; + /** @brief Position status. This enumeration defines how to interpret the position data. */ typedef enum { @@ -244,6 +175,7 @@ typedef enum BLE_LNS_LAST_KNOWN_POSITION = 3 } ble_lns_pos_status_type_t; + /** @brief The format of the position and speed measurements. */ typedef enum { @@ -251,8 +183,9 @@ typedef enum BLE_LNS_SPEED_DISTANCE_FORMAT_3D = 1 } ble_lns_speed_distance_format_t; + /** @brief Elevation source. */ -typedef enum +typedef enum { BLE_LNS_ELEV_SOURCE_POSITIONING_SYSTEM = 0, BLE_LNS_ELEV_SOURCE_BAROMETRIC = 1, @@ -260,13 +193,15 @@ typedef enum BLE_LNS_ELEV_SOURCE_OTHER = 3 } ble_lns_elevation_source_t; + /** @brief Heading source. */ -typedef enum +typedef enum { BLE_LNS_HEADING_SOURCE_MOVEMENT = 0, BLE_LNS_HEADING_SOURCE_COMPASS = 1 } ble_lns_heading_source_t; + /**@brief Location and Speed data structure. */ struct ble_lns_loc_speed_s { @@ -277,7 +212,7 @@ struct ble_lns_loc_speed_s bool heading_present; /**< Heading present (0=not present, 1=present). */ bool rolling_time_present; /**< Rolling Time present (0=not present, 1=present). */ bool utc_time_time_present; /**< UTC Time present (0=not present, 1=present). */ - ble_lns_pos_status_type_t position_status; /**< Status of current position */ + ble_lns_pos_status_type_t position_status; /**< Status of current position */ ble_lns_speed_distance_format_t data_format; /**< Format of data (either 2D or 3D). */ ble_lns_elevation_source_t elevation_source; /**< Source of the elevation measurement. */ ble_lns_heading_source_t heading_source; /**< Source of the heading measurement. */ @@ -291,6 +226,7 @@ struct ble_lns_loc_speed_s ble_date_time_t utc_time; /**< UTC Time. */ }; + /** @brief Position quality structure. */ struct ble_lns_pos_quality_s { @@ -301,7 +237,7 @@ struct ble_lns_pos_quality_s bool evpe_present; /**< Error in vertical position estimate present (0=not present, 1=present). */ bool hdop_present; /**< Horizontal dilution of precision present (0=not present, 1=present). */ bool vdop_present; /**< Vertical dilution of precision present (0=not present, 1=present). */ - ble_lns_pos_status_type_t position_status; /**< Status of last measured position. */ + ble_lns_pos_status_type_t position_status; /**< Status of last measured position. */ uint8_t number_of_satellites_in_solution; /**< The number of satellites in solution (unitless, with a resolution of 1). */ uint8_t number_of_satellites_in_view; /**< The number of satellites in view (unitless, with a resolution of 1). */ uint16_t time_to_first_fix; /**< Time to the first position fix (seconds, with a resolution of 1/10). */ @@ -311,20 +247,22 @@ struct ble_lns_pos_quality_s uint8_t vdop; /**< Vertical dilution of precision (unitless, with a resolution of 2/10). */ }; + /** @brief Navigation indicator type. */ -typedef enum +typedef enum { BLE_LNS_NAV_TO_WAYPOINT = 0, BLE_LNS_NAV_TO_DESTINATION = 1 } ble_lns_nav_indicator_type_t; + /**@brief Navigation data structure. */ struct ble_lns_navigation_s { bool remaining_dist_present; /**< Remaining Distance present (0=not present, 1=present). */ bool remaining_vert_dist_present; /**< Remaining Vertical Distance present (0=not present, 1=present). */ bool eta_present; /**< Estimated Time of Arrival present (0=not present, 1=present). */ - ble_lns_pos_status_type_t position_status; /**< Status of last measured position. */ + ble_lns_pos_status_type_t position_status; /**< Status of last measured position. */ ble_lns_heading_source_t heading_source; /**< Source of the heading measurement. */ ble_lns_nav_indicator_type_t navigation_indicator_type; /**< Navigation indicator type. */ bool waypoint_reached; /**< Waypoint Reached (0=not reached, 1=reached). */ @@ -346,10 +284,10 @@ struct ble_lns_navigation_s * * @retval NRF_SUCCESS If the service was initialized successfully. * @retval NRF_ERROR_NULL If a NULL parameter was provided. - * @retval NRF_INVALID_PARAMS If there is an inconsistency in the initialization structure. + * @retval NRF_INVALID_PARAMS If there is an inconsistency in the initialization structure. * @return Otherwise, an error code from either sd_ble_gatts_service_add() or sd_ble_gatts_characteristic_add() is returned. */ -uint32_t ble_lns_init(ble_lns_t * p_lns, const ble_lns_init_t * p_lns_init); +ret_code_t ble_lns_init(ble_lns_t * p_lns, const ble_lns_init_t * p_lns_init); /**@brief Function for handling Location and Navigation Service BLE stack events. * @@ -361,7 +299,7 @@ uint32_t ble_lns_init(ble_lns_t * p_lns, const ble_lns_init_t * p_lns_init); * @param[in] p_ble_evt Event received from the BLE stack. * */ -void ble_lns_on_ble_evt(ble_lns_t * p_lns, ble_evt_t * p_ble_evt); +void ble_lns_on_ble_evt(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt); /**@brief Function for sending location and speed data if notification has been enabled. * @@ -374,9 +312,8 @@ void ble_lns_on_ble_evt(ble_lns_t * p_lns, ble_evt_t * p_ble_evt); * @retval NRF_SUCCESS If the data was sent successfully. * @retval NRF_ERROR_NULL If a NULL parameter was provided. * @retval NRF_ERROR_INVALID_STATE If notification is disabled. - * @return Otherwise, an error code from @ref sd_ble_gatts_hvx() is returned. */ -uint32_t ble_lns_loc_speed_send(ble_lns_t * p_lns); +ret_code_t ble_lns_loc_speed_send(ble_lns_t * p_lns); /**@brief Function for sending navigation data if notification has been enabled. * @@ -390,9 +327,8 @@ uint32_t ble_lns_loc_speed_send(ble_lns_t * p_lns); * @retval NRF_ERROR_NULL If a NULL parameter was provided. * @retval NRF_ERROR_NOT_SUPPORTED If the navigation characteristic is absent. * @retval NRF_ERROR_INVALID_STATE If navigation is not running or notification is disabled. - * @return Otherwise, an error code from @ref sd_ble_gatts_hvx() is returned. */ -uint32_t ble_lns_navigation_send(ble_lns_t * p_lns); +ret_code_t ble_lns_navigation_send(ble_lns_t * p_lns); /**@brief Function for adding a route to the Location and Navigation Service. * @@ -402,10 +338,10 @@ uint32_t ble_lns_navigation_send(ble_lns_t * p_lns); * @retval NRF_SUCCESS If the route was added successfully. * @retval NRF_ERROR_NULL If a NULL parameter was provided. * @retval NRF_ERROR_NOT_SUPPORTED If the navigation characteristic is absent. - * @retval NRF_ERROR_NO_MEM If there is no memory left. + * @retval NRF_ERROR_NO_MEM If there is no memory left. * @retval NRF_ERROR_INTERNAL If there is an inconsistency in the routes table. */ -uint32_t ble_lns_add_route(ble_lns_t * p_lns, ble_lns_route_t * p_route); +ret_code_t ble_lns_add_route(ble_lns_t * p_lns, ble_lns_route_t * p_route); /**@brief Function for removing a route from the Location and Navigation Service. * @@ -417,7 +353,12 @@ uint32_t ble_lns_add_route(ble_lns_t * p_lns, ble_lns_route_t * p_route); * @retval NRF_ERROR_NOT_SUPPORTED If the navigation characteristic is absent. * @retval NRF_INVALID_PARAM If the route ID does not exist. */ -uint32_t ble_lns_remove_route(ble_lns_t * p_lns, uint16_t route_id); +ret_code_t ble_lns_remove_route(ble_lns_t * p_lns, uint16_t route_id); + + +#ifdef __cplusplus +} +#endif #endif // BLE_LNS_H__ diff --git a/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.c b/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.c new file mode 100644 index 0000000..fe786ef --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.c @@ -0,0 +1,616 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include + +#include "nrf_ble_bms.h" +#include "ble_srv_common.h" + +#define NRF_LOG_MODULE_NAME "BLE_BMS" +#include "nrf_log.h" + +/*@brief Check if a returned error code is NRF_SUCCESS, and call the error handler if not. + * + * @param[in] err_code Error code that should be checked. + * @param[in] err_handler Error handler that should be called. + */ +static void error_check(ret_code_t err_code, ble_srv_error_handler_t err_handler) +{ + if (err_code != NRF_SUCCESS) + { + err_handler(err_code); + } +} + + +/**@brief Function for adding the Bond Management Control Point characteristic. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_bms_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code returned by @ref characteristic_add. + */ +static ret_code_t ctrlpt_char_add(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t const * p_bms_init) +{ + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + add_char_params.uuid = BLE_UUID_BMS_CTRLPT; + add_char_params.char_props.write = 1; + add_char_params.is_defered_write = true; + add_char_params.is_var_len = true; + add_char_params.max_len = NRF_BLE_BMS_CTRLPT_MAX_LEN; + add_char_params.read_access = SEC_NO_ACCESS; + add_char_params.write_access = p_bms_init->bms_ctrlpt_sec_req; + + if (p_bms_init->p_qwr != NULL) + { + add_char_params.char_ext_props.reliable_wr = 1; + } + + return characteristic_add(p_bms->service_handle, &add_char_params, &p_bms->ctrlpt_handles); +} + + +/**@brief Forward an authorization request to the application, if necessary. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_ctrlpt Pointer to the received Control Point value. + */ +static void ctrlpt_auth(nrf_ble_bms_t * p_bms, nrf_ble_bms_ctrlpt_t * p_ctrlpt) +{ + nrf_ble_bms_features_t * p_feature = &p_bms->feature; + + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_ALLOWED; + + /* Check if the authorization feature is enabled for this op code. */ + if (( + (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY) && + (p_feature->delete_requesting_auth) + ) || + ( + (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY) && + (p_feature->delete_all_auth) + ) || + ( + (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY) && + (p_feature->delete_all_but_requesting_auth) + ) + ) + { + if (p_bms->evt_handler != NULL) + { + nrf_ble_bms_evt_t bms_evt; + + memset(&bms_evt, 0, sizeof(bms_evt)); + bms_evt.evt_type = NRF_BLE_BMS_EVT_AUTH; + bms_evt.auth_code.len = p_ctrlpt->auth_code.len; + memcpy(bms_evt.auth_code.code, p_ctrlpt->auth_code.code, p_ctrlpt->auth_code.len); + + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_PENDING; + + p_bms->evt_handler(p_bms, &bms_evt); + } + else + { + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED; + } + } +} + + +/**@brief Decode an incoming Control Point write. + * + * @param[in] p_rcvd_val Received write value. + * @param[in] len Value length. + * @param[out] p_ctrlpt Decoded control point structure. + * + * @retval NRF_ERROR_INVALID_LENGTH The supplied value length is invalid. + * @retval NRF_ERROR_NOT_SUPPORTED The supplied op code is not supported. + * @retval NRF_SUCCESS Operation successful. + */ +static ret_code_t ctrlpt_decode(uint8_t * p_rcvd_val, uint16_t len, nrf_ble_bms_ctrlpt_t * p_ctrlpt) +{ + uint16_t pos = 0; + + VERIFY_TRUE(len >= NRF_BLE_BMS_CTRLPT_MIN_LEN, NRF_ERROR_INVALID_LENGTH); + VERIFY_TRUE(len <= NRF_BLE_BMS_CTRLPT_MAX_LEN, NRF_ERROR_INVALID_LENGTH); + + p_ctrlpt->op_code = (nrf_ble_bms_op_t) p_rcvd_val[pos++]; + p_ctrlpt->auth_code.len = (len - pos); + memcpy(p_ctrlpt->auth_code.code, &(p_rcvd_val[pos]), p_ctrlpt->auth_code.len); + + return NRF_SUCCESS; +} + + +/**@brief Function for performing an operation requested through the Control Point. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] op_code Op code to execute. + */ +static void ctrlpt_execute(nrf_ble_bms_t * p_bms, nrf_ble_bms_op_t op_code) +{ + switch (op_code) + { + case NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY: + /* Delete single bond */ + p_bms->bond_callbacks.delete_requesting(p_bms); + break; // NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY + + case NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY: + /* Delete all bonds */ + p_bms->bond_callbacks.delete_all(p_bms); + break; // NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY + + case NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY: + /* Delete all but current bond */ + p_bms->bond_callbacks.delete_all_except_requesting(p_bms); + break; // NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY + + default: + /* No implemementation needed. */ + break; + } +} + + +/*@brief Validate an incoming Control Point write. + * + * @param[in] op_code Received op code. + * @param[in] p_feature Supported features. + * + * @returns True if the op code is supported, or false. + */ +static bool ctrlpt_validate(nrf_ble_bms_ctrlpt_t * p_ctrlpt, nrf_ble_bms_features_t * p_feature) +{ + switch (p_ctrlpt->op_code) + { + case NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY: + if (p_feature->delete_requesting || p_feature->delete_requesting_auth) + { + return true; + } + break; + + case NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY: + if (p_feature->delete_all || p_feature->delete_all_auth) + { + return true; + } + break; + + case NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY: + if (p_feature->delete_all_but_requesting || p_feature->delete_all_but_requesting_auth) + { + return true; + } + break; + + default: + /* No implementation needed. */ + break; + } + + return false; +} + + +/**@brief Function for processing a write to the Control Point. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_rcvd_val Received write value. + * @param[in] len Value length. + * @param[out] p_ctrlpt Decoded control point structure. + */ +static uint16_t ctrlpt_process(nrf_ble_bms_t * p_bms, + uint8_t * p_rcvd_val, + uint16_t len, + nrf_ble_bms_ctrlpt_t * p_ctrlpt) +{ + ret_code_t err_code; + + /* Decode operation */ + err_code = ctrlpt_decode(p_rcvd_val, len, p_ctrlpt); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Control point write: Operation failed.\r\n"); + return NRF_BLE_BMS_OPERATION_FAILED; + } + + /* Verify that the operation is allowed. */ + if (!ctrlpt_validate(p_ctrlpt, &p_bms->feature)) + { + NRF_LOG_ERROR("Control point write: Invalid op code.\r\n"); + return NRF_BLE_BMS_OPCODE_NOT_SUPPORTED; + } + + /* Request authorization */ + ctrlpt_auth(p_bms, p_ctrlpt); + if (p_bms->auth_status != NRF_BLE_BMS_AUTH_STATUS_ALLOWED) + { + NRF_LOG_ERROR("Control point long write: Invalid auth.\r\n"); + return BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION; + } + + return BLE_GATT_STATUS_SUCCESS; +} + + +/**@brief Function for encoding the Bond Management Feature characteristic. + * + * @param[in] p_bms Bond Management Service structure. + * @param[out] p_encoded_feature Encoded features. + * + * @return Size of the encoded feature. + */ +static uint8_t feature_encode(nrf_ble_bms_features_t const * p_feature, uint8_t * p_encoded_feature) +{ + uint32_t data = 0; + + if (p_feature->delete_all_auth) + { + data |= NRF_BLE_BMS_ALL_BONDS_LE_AUTH_CODE; + } + if (p_feature->delete_all_but_requesting_auth) + { + data |= NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE_AUTH_CODE; + } + if (p_feature->delete_all_but_requesting) + { + data |= NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE; + } + if (p_feature->delete_all) + { + data |= NRF_BLE_BMS_ALL_BONDS_LE; + } + if (p_feature->delete_requesting_auth) + { + data |= NRF_BLE_BMS_REQUESTING_DEVICE_LE_AUTH_CODE; + } + if (p_feature->delete_requesting) + { + data |= NRF_BLE_BMS_REQUESTING_DEVICE_LE; + } + + return (uint24_encode(data, p_encoded_feature)); +} + + +/**@brief Function for adding the Bond Management Feature characteristic. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_bms_init Information needed to initialize the service. + * + * @return NRF_SUCCESS on success, otherwise an error code returned by @ref characteristic_add. + */ +static ret_code_t feature_char_add(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t const * p_bms_init) +{ + uint8_t encoded_feature[NRF_BLE_BMS_FEATURE_LEN]; + uint8_t init_value_len; + ble_add_char_params_t add_char_params; + nrf_ble_bms_features_t * p_feature = &p_bms->feature; + + if ((p_feature->delete_all_auth) || + (p_feature->delete_all_but_requesting_auth) || + (p_feature->delete_requesting_auth)) + { + VERIFY_PARAM_NOT_NULL(p_bms_init->evt_handler); + } + + if ((p_feature->delete_requesting_auth) || + (p_feature->delete_requesting)) + { + VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_requesting); + } + + if ((p_feature->delete_all) || + (p_feature->delete_all_auth)) + { + VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_all); + } + + if ((p_feature->delete_all_but_requesting) || + (p_feature->delete_all_but_requesting_auth)) + { + VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_all_except_requesting); + } + + init_value_len = feature_encode(&p_bms->feature, encoded_feature); + + memset(&add_char_params, 0, sizeof(add_char_params)); + add_char_params.uuid = BLE_UUID_BMS_FEATURE; + add_char_params.char_props.read = true; + add_char_params.max_len = init_value_len; + add_char_params.p_init_value = encoded_feature; + add_char_params.init_len = init_value_len; + add_char_params.read_access = p_bms_init->bms_feature_sec_req; + add_char_params.write_access = SEC_NO_ACCESS; + + return characteristic_add(p_bms->service_handle, &add_char_params, &p_bms->feature_handles); +} + + +/**@brief Handle a write event to the Bond Management Service Control Point. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_ctrlpt_write(nrf_ble_bms_t * p_bms, + ble_gatts_evt_write_t * p_evt_write, + ble_gatts_authorize_params_t * p_auth_params) +{ + ret_code_t err_code; + nrf_ble_bms_ctrlpt_t ctrlpt; + + err_code = ctrlpt_process(p_bms, p_evt_write->data, p_evt_write->len, &ctrlpt); + if (err_code != NRF_SUCCESS) + { + p_auth_params->gatt_status = err_code; + p_auth_params->update = 0; + + return; + } + + p_auth_params->gatt_status = BLE_GATT_STATUS_SUCCESS; + p_auth_params->update = 1; + + NRF_LOG_INFO("Control point write: Success\r\n"); + + /* Execute the requested operation. */ + ctrlpt_execute(p_bms, ctrlpt.op_code); +} + + +/**@brief Authorize WRITE request event handler. + * + * @details Handles WRITE events from the BLE stack. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_gatts_evt GATTS Event received from the BLE stack. + * + */ +static void on_rw_auth_req(nrf_ble_bms_t * p_bms, ble_gatts_evt_t * p_gatts_evt) +{ + ble_gatts_evt_rw_authorize_request_t * p_auth_req = &p_gatts_evt->params.authorize_request; + ble_gatts_rw_authorize_reply_params_t auth_reply; + ret_code_t err_code; + + memset(&auth_reply, 0, sizeof(auth_reply)); + + if ((p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && + (p_auth_req->request.write.op == BLE_GATTS_OP_WRITE_REQ) && + (p_auth_req->request.write.handle == p_bms->ctrlpt_handles.value_handle)) + { + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + on_ctrlpt_write(p_bms, &p_auth_req->request.write, &auth_reply.params.write); + + /* Send authorization reply */ + err_code = sd_ble_gatts_rw_authorize_reply(p_bms->conn_handle, &auth_reply); + error_check(err_code, p_bms->error_handler); + } + +} + + +/**@brief Handle authorization request events from the Queued Write module. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_qwr Queued Write Structure. + * @param[in] p_evt Event received from the Queued Writes module. + * + * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted. + * @retval BLE_BMS_OPCODE_OPERATION_FAILED If the received event is not relevant for any of this module's attributes. + * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported. + * @retval BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION If the application handler returns that the authorization code is not valid. + */ +uint16_t on_qwr_auth_req(nrf_ble_bms_t * p_bms, nrf_ble_qwr_t * p_qwr, nrf_ble_qwr_evt_t * p_evt) +{ + ret_code_t err_code; + uint16_t len = NRF_BLE_BMS_CTRLPT_MAX_LEN; + uint8_t mem_buffer[NRF_BLE_BMS_CTRLPT_MAX_LEN]; + nrf_ble_bms_ctrlpt_t ctrlpt; + + err_code = nrf_ble_qwr_value_get(p_qwr, p_evt->attr_handle, mem_buffer, &len); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Control point write: Operation failed.\r\n"); + return NRF_BLE_BMS_OPERATION_FAILED; + } + + return ctrlpt_process(p_bms, mem_buffer, len, &ctrlpt); +} + + +/**@brief Handle execute write events to from the Queued Write module. + * + * @param[in] p_bms Bond Management Service structure. + * @param[in] p_qwr Queued Write Structure. + * @param[in] p_evt Event received from the Queued Writes module. + * + * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted. + * @retval BLE_BMS_OPCODE_OPERATION_FAILED If the received event is not relevant for any of this module's attributes. + * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported. + */ +uint16_t on_qwr_exec_write(nrf_ble_bms_t * p_bms, nrf_ble_qwr_t * p_qwr, nrf_ble_qwr_evt_t * p_evt) +{ + ret_code_t err_code; + uint16_t len = NRF_BLE_BMS_CTRLPT_MAX_LEN; + uint8_t mem_buffer[NRF_BLE_BMS_CTRLPT_MAX_LEN]; + nrf_ble_bms_ctrlpt_t ctrlpt; + ble_gatts_value_t ctrlpt_value; + + ctrlpt_value.len = NRF_BLE_BMS_CTRLPT_MAX_LEN; + ctrlpt_value.offset = 0; + ctrlpt_value.p_value = mem_buffer; + + const uint16_t ctrlpt_handle = p_bms->ctrlpt_handles.value_handle; + err_code = sd_ble_gatts_value_get(p_bms->conn_handle, ctrlpt_handle, &ctrlpt_value); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Control point write: Operation failed.\r\n"); + return NRF_BLE_BMS_OPERATION_FAILED; + } + + /* Decode operation */ + err_code = ctrlpt_decode(ctrlpt_value.p_value, len, &ctrlpt); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Control point write: Operation failed.\r\n"); + return NRF_BLE_BMS_OPERATION_FAILED; + } + + /* Execute the requested operation. */ + ctrlpt_execute(p_bms, ctrlpt.op_code); + + /* Reset authorization status */ + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED; + + return BLE_GATT_STATUS_SUCCESS; +} + + +uint16_t nrf_ble_bms_on_qwr_evt(nrf_ble_bms_t * p_bms, + nrf_ble_qwr_t * p_qwr, + nrf_ble_qwr_evt_t * p_evt) +{ + VERIFY_TRUE(p_bms != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE)); + VERIFY_TRUE(p_qwr != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE)); + VERIFY_TRUE(p_evt != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE)); + VERIFY_TRUE(p_evt->attr_handle == p_bms->ctrlpt_handles.value_handle, + (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE)); + + if (p_evt->evt_type == NRF_BLE_QWR_EVT_AUTH_REQUEST) + { + return on_qwr_auth_req(p_bms, p_qwr, p_evt); + } + else if ((p_evt->evt_type == NRF_BLE_QWR_EVT_EXECUTE_WRITE) && + (p_bms->auth_status == NRF_BLE_BMS_AUTH_STATUS_ALLOWED)) + { + return on_qwr_exec_write(p_bms, p_qwr, p_evt); + } + + return BLE_GATT_STATUS_SUCCESS; +} + + +void nrf_ble_bms_on_ble_evt(nrf_ble_bms_t * p_bms, ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_bms); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_auth_req(p_bms, &p_ble_evt->evt.gatts_evt); + break; + + default: + break; + } +} + + +ret_code_t nrf_ble_bms_set_conn_handle(nrf_ble_bms_t * p_bms, uint16_t conn_handle) +{ + VERIFY_PARAM_NOT_NULL(p_bms); + + p_bms->conn_handle = conn_handle; + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_bms_init(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t * p_bms_init) +{ + ret_code_t err_code; + ble_uuid_t ble_uuid; + + VERIFY_PARAM_NOT_NULL(p_bms_init); + VERIFY_PARAM_NOT_NULL(p_bms); + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BMS_SERVICE); + + p_bms->evt_handler = p_bms_init->evt_handler; + p_bms->error_handler = p_bms_init->error_handler; + p_bms->feature = p_bms_init->feature; + p_bms->bond_callbacks = p_bms_init->bond_callbacks; + p_bms->conn_handle = BLE_CONN_HANDLE_INVALID; + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_bms->service_handle); + VERIFY_SUCCESS(err_code); + + err_code = feature_char_add(p_bms, p_bms_init); + VERIFY_SUCCESS(err_code); + + err_code = ctrlpt_char_add(p_bms, p_bms_init); + VERIFY_SUCCESS(err_code); + + if (p_bms_init->p_qwr != NULL) + { + return nrf_ble_qwr_attr_register(p_bms_init->p_qwr, p_bms->ctrlpt_handles.value_handle); + } + + NRF_LOG_INFO("Init complete.\r\n"); + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_bms_auth_response(nrf_ble_bms_t * p_bms, bool authorize) +{ + VERIFY_PARAM_NOT_NULL(p_bms); + VERIFY_TRUE(p_bms->auth_status == NRF_BLE_BMS_AUTH_STATUS_PENDING, NRF_ERROR_INVALID_STATE); + + if (authorize) + { + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_ALLOWED; + } + else + { + p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED; + } + + return NRF_SUCCESS; +} + + diff --git a/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.h b/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.h new file mode 100644 index 0000000..7badb3f --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_bms/nrf_ble_bms.h @@ -0,0 +1,318 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_bms Bond Management Service + * @{ + * @ingroup ble_sdk_srv + * @brief Bond Management Service (BMS) module. + * + * @details This module implements the Bond Management Service (BMS). + * By writing to the Bond Management Control Point, the connected peer can request the deletion of + * bond information from the device. + * If authorization is configured, the application must supply an event handler for receiving Bond + * Management Service events. Using this handler, the service requests authorization when + * a procedure is requested by writing to the Bond Management Control Point. + * + * @msc + * hscale = "1.3"; + * APP,BMS,PEER; + * |||; + * APP rbox PEER [label="Connection established"]; + * |||; + * BMS<=PEER [label="BMCP write request {procedure}"]; + * APP<-BMS [label="NRF_BLE_BMS_EVT_AUTH {auth_code}"]; + * --- [label="Variant #1: app grants authorization"]; + * APP->BMS [label="nrf_ble_bms_auth_reponse (true)"]; + * BMS>>APP [label="NRF_SUCCESS"]; + * BMS=>PEER [label="BMCP write response"]; + * BMS rbox BMS [label="Procedure initiated"]; + * --- [label="Variant #2: app denies authorization"]; + * APP->BMS [label="nrf_ble_bms_auth_reponse (false)"]; + * BMS>>APP [label="NRF_SUCCESS"]; + * BMS=>PEER [label="BMCP error response"]; + * @endmsc + * + * @note The application must propagate BLE stack events to the Bond Management Service module by calling + * @ref nrf_ble_bms_on_ble_evt() from the @ref softdevice_handler callback. + * If the application uses the Queued Writes module, the application must propagate Queued Write events + * to the Bond Management Service module by calling @ref nrf_ble_bms_on_qwr_evt() from the + * @ref nrf_ble_qwr callback. + */ + +#ifndef NRF_BLE_BMS_H__ +#define NRF_BLE_BMS_H__ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "nrf_ble_qwr.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define NRF_BLE_BMS_FEATURE_LEN 3 //!< Length of the Feature Characteristic (in bytes). +#define NRF_BLE_BMS_CTRLPT_MAX_LEN 128 //!< Maximum length of the Bond Management Control Point Characteristic (in bytes). +#define NRF_BLE_BMS_CTRLPT_MIN_LEN 1 //!< Minimum length of the Bond Management Control Point Characteristic (in bytes). +#define NRF_BLE_BMS_AUTH_CODE_MAX_LEN NRF_BLE_BMS_CTRLPT_MAX_LEN - 1 //!< Maximum length of the Bond Management Control Point Authorization Code (in bytes). + + +/** @defgroup NRF_BLE_BMS_FEATURES BMS feature bits + * @{ */ +#define NRF_BLE_BMS_REQUESTING_DEVICE_BR_LE (0x01 << 0) //!< Delete bond of the requesting device (BR/EDR and LE). +#define NRF_BLE_BMS_REQUESTING_DEVICE_BR_LE_AUTH_CODE (0x01 << 1) //!< Delete bond of the requesting device (BR/EDR and LE) with an authorization code. +#define NRF_BLE_BMS_REQUESTING_DEVICE_BR (0x01 << 2) //!< Delete bond of the requesting device (BR/EDR transport only). +#define NRF_BLE_BMS_REQUESTING_DEVICE_BR_AUTH_CODE (0x01 << 3) //!< Delete bond of the requesting device (BR/EDR transport only) with an authorization code. +#define NRF_BLE_BMS_REQUESTING_DEVICE_LE (0x01 << 4) //!< Delete bond of the requesting device (LE transport only). +#define NRF_BLE_BMS_REQUESTING_DEVICE_LE_AUTH_CODE (0x01 << 5) //!< Delete bond of the requesting device (LE transport only) with an authorization code. +#define NRF_BLE_BMS_ALL_BONDS_BR_LE (0x01 << 6) //!< Delete all bonds on the device (BR/EDR and LE). +#define NRF_BLE_BMS_ALL_BONDS_BR_LE_AUTH_CODE (0x01 << 7) //!< Delete all bonds on the device (BR/EDR and LE) with an authorization code. +#define NRF_BLE_BMS_ALL_BONDS_BR (0x01 << 8) //!< Delete all bonds on the device (BR/EDR transport only). +#define NRF_BLE_BMS_ALL_BONDS_BR_AUTH_CODE (0x01 << 9) //!< Delete all bonds on the device (BR/EDR transport only) with an authorization code. +#define NRF_BLE_BMS_ALL_BONDS_LE (0x01 << 10) //!< Delete all bonds on the device (LE transport only). +#define NRF_BLE_BMS_ALL_BONDS_LE_AUTH_CODE (0x01 << 11) //!< Delete all bonds on the device (LE transport only) with an authorization code. +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR_LE (0x01 << 12) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR and LE). +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR_LE_AUTH_CODE (0x01 << 13) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR and LE) with an authorization code. +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR (0x01 << 14) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR transport only). +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR_AUTH_CODE (0x01 << 15) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR transport only) with an authorization code. +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE (0x01 << 16) //!< Delete all bonds on the device except for the bond of the requesting device (LE transport only). +#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE_AUTH_CODE (0x01 << 17) //!< Delete all bonds on the device except for the bond of the requesting device (LE transport only) with an authorization code. +/** @} */ + + +#define NRF_BLE_BMS_OPCODE_NOT_SUPPORTED (BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0) //!< Error sent back when receiving a control point write with an unsupported opcode. +#define NRF_BLE_BMS_OPERATION_FAILED (BLE_GATT_STATUS_ATTERR_APP_BEGIN + 1) //!< Error sent back when a control point operation fails. + + +/**@brief Supported features. */ +typedef struct +{ + bool delete_all : 1; //!< Indicates whether the application wants to support the operation to delete all bonds. + bool delete_all_auth : 1; //!< Indicates whether the application wants to support the operation to delete all bonds with authorization code. + bool delete_requesting : 1; //!< Indicates whether the application wants to support the operation to delete the bonds of the requesting device. + bool delete_requesting_auth : 1; //!< Indicates whether the application wants to support the operation to delete the bonds of the requesting device with authorization code. + bool delete_all_but_requesting : 1; //!< Indicates whether the application wants to support the operation to delete all bonds except for the bond of the requesting device. + bool delete_all_but_requesting_auth : 1; //!< Indicates whether the application wants to support the operation to delete all bonds except for the bond of the requesting device with authorization code. +} nrf_ble_bms_features_t; + + +/**@brief BMS Control Point opcodes. */ +typedef enum +{ + NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_BR_LE = 0x01, //!< Initiates the procedure to delete the bond of the requesting device on BR/EDR and LE transports. + NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_BR_ONLY = 0x02, //!< Initiates the procedure to delete the bond of the requesting device on BR/EDR transport. + NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY = 0x03, //!< Initiates the procedure to delete the bond of the requesting device on LE transport. + NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_BR_LE = 0x04, //!< Initiates the procedure to delete all bonds on the device on BR/EDR and LE transports. + NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_BR_ONLY = 0x05, //!< Initiates the procedure to delete all bonds on the device on BR/EDR transport. + NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY = 0x06, //!< Initiates the procedure to delete all bonds on the device on LE transport. + NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_BR_LE = 0x07, //!< Initiates the procedure to delete all bonds except for the one of the requesting device on BR/EDR and LE transports. + NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_BR_ONLY = 0x08, //!< Initiates the procedure to delete all bonds except for the one of the requesting device on BR/EDR transport. + NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY = 0x09, //!< Initiates the procedure to delete all bonds except for the one of the requesting device on LE transport. + NRF_BLE_BMS_OP_NONE = 0xFF //!< Indicates an invalid opcode or no pending opcode. +} nrf_ble_bms_op_t; + + +/**@brief Authorization status values. */ +typedef enum +{ + NRF_BLE_BMS_AUTH_STATUS_ALLOWED, //!< Authorization is granted. + NRF_BLE_BMS_AUTH_STATUS_DENIED, //!< Authorization is denied. + NRF_BLE_BMS_AUTH_STATUS_PENDING //!< Authorization is pending. +} nrf_ble_bms_auth_status_t; + + +/**@brief Received authorization codes. */ +typedef struct +{ + uint8_t code[NRF_BLE_BMS_AUTH_CODE_MAX_LEN]; //!< Authorization code. + uint16_t len; //!< Length of the authorization code. +} nrf_ble_bms_auth_code_t; + + +/**@brief BMS event types. */ +typedef enum +{ + NRF_BLE_BMS_EVT_AUTH, //!< Event that indicates that the application shall verify the supplied authentication code. +} nrf_ble_bms_evt_type_t; + + +/**@brief BMS events. */ +typedef struct +{ + nrf_ble_bms_evt_type_t evt_type; //!< Type of event. + nrf_ble_bms_auth_code_t auth_code; //!< Received authorization code. +} nrf_ble_bms_evt_t; + +/**@brief BMS control points. */ +typedef struct +{ + nrf_ble_bms_op_t op_code; //!< Control Point Op Code. + nrf_ble_bms_auth_code_t auth_code; //!< Control Point Authorization Code. +} nrf_ble_bms_ctrlpt_t; + + +// Forward declaration of the nrf_ble_bms_t type. +typedef struct nrf_ble_bms_s nrf_ble_bms_t; + + +/**@brief BMS event handler type. */ +typedef void (* nrf_ble_bms_bond_handler_t) (nrf_ble_bms_t const * p_bms); + + +/**@brief BMS bond management callbacks. */ +typedef struct +{ + nrf_ble_bms_bond_handler_t delete_requesting; //!< Function to be called to delete the bonding information of the requesting device. + nrf_ble_bms_bond_handler_t delete_all; //!< Function to be called to delete the bonding information of all bonded devices. + nrf_ble_bms_bond_handler_t delete_all_except_requesting; //!< Function to be called to delete the bonding information of all bonded devices except for the requesting device. +} nrf_ble_bms_bond_cbs_t; + + +/**@brief BMS event handler type. The event handler returns a @ref BLE_GATT_STATUS_CODES "BLE GATT status code". */ +typedef void (* ble_bms_evt_handler_t) (nrf_ble_bms_t * p_bms, nrf_ble_bms_evt_t * p_evt); + + +/**@brief BMS initialization structure that contains all information + * needed to initialize the service. */ +typedef struct +{ + ble_bms_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Bond Management Service. + ble_srv_error_handler_t error_handler; //!< Function to be called if an error occurs. + nrf_ble_bms_features_t feature; //!< Initial value for features of the service. + security_req_t bms_feature_sec_req; //!< Initial security level for the Feature characteristic. + security_req_t bms_ctrlpt_sec_req; //!< Initial security level for the Control Point characteristic. + nrf_ble_qwr_t * p_qwr; //!< Pointer to the initialized Queued Write context. + nrf_ble_bms_bond_cbs_t bond_callbacks; //!< Callback functions for deleting bonds. +} nrf_ble_bms_init_t; + + +/**@brief Status information for the service. */ +struct nrf_ble_bms_s +{ + uint16_t service_handle; //!< Handle of the Bond Management Service (as provided by the BLE stack). + uint16_t conn_handle; //!< Handle of the current connection (as provided by the BLE stack). @ref BLE_CONN_HANDLE_INVALID if not in a connection. + ble_bms_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Bond Management Service. + ble_srv_error_handler_t error_handler; //!< Function to be called if an error occurs. + nrf_ble_bms_features_t feature; //!< Value for features of the service (see @ref NRF_BLE_BMS_FEATURES). + ble_gatts_char_handles_t feature_handles; //!< Handles related to the Bond Management Feature characteristic. + ble_gatts_char_handles_t ctrlpt_handles; //!< Handles related to the Bond Management Control Point characteristic. + nrf_ble_bms_bond_cbs_t bond_callbacks; //!< Callback functions for deleting bonds. + nrf_ble_bms_auth_status_t auth_status; //!< Authorization status. +}; + + +/**@brief Function for responding to an authorization request. + * + * @details This function should be called when receiving the @ref NRF_BLE_BMS_EVT_AUTH event to + * respond to the service with an authorization result. + * + * @param[in] p_bms BMS structure. + * @param[in] authorize Authorization response. True if the authorization is considered successful. + * + * @retval NRF_ERROR_NULL If @p p_bms was NULL. + * @retval NRF_ERROR_INVALID_STATE If no authorization request was pending. + * @retval NRF_SUCCESS If the response was received successfully. + */ +ret_code_t nrf_ble_bms_auth_response(nrf_ble_bms_t * p_bms, bool authorize); + + +/**@brief Function for initializing the Bond Management Service. + * + * @param[out] p_bms BMS structure. + * @param[in] p_bms_init Information needed to initialize the service. + * + * @retval NRF_ERROR_NULL If @p p_bms or @p p_bms_init was NULL. + * @retval NRF_SUCCESS If the service was initialized successfully. + * Otherwise, an error code is returned. + */ +ret_code_t nrf_ble_bms_init(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t * p_bms_init); + + +/**@brief Function for assigning handles to the Bond Management Service instance. + * + * @details Call this function when a link with a peer has been established to + * associate the link to this instance of the module. + * + * @param[in] p_bms Pointer to the BMS structure instance to associate. + * @param[in] conn_handle Connection handle to be associated with the given BMS instance. + * + * @retval NRF_ERROR_NULL If @p p_bms was NULL. + * @retval NRF_SUCCESS If the operation was successful. + */ +ret_code_t nrf_ble_bms_set_conn_handle(nrf_ble_bms_t * p_bms, uint16_t conn_handle); + + +/**@brief Function for handling Bond Management BLE stack events. + * + * @details This function handles all events from the BLE stack that are of interest to the Bond Management Service. + * + * @param[in] p_bms BMS structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void nrf_ble_bms_on_ble_evt(nrf_ble_bms_t * p_bms, ble_evt_t * p_ble_evt); + + +/**@brief Function for handling events from the @ref nrf_ble_qwr. + * + * @param[in] p_bms BMS structure. + * @param[in] p_qwr Queued Write structure. + * @param[in] p_evt Event received from the Queued Writes module. + * + * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted. + * @retval NRF_BLE_QWR_REJ_REQUEST_ERR_CODE If the received event is not relevant for any of this module's attributes. + * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported. + * @retval BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION If the application handler returns that the authorization code is not valid. + */ +uint16_t nrf_ble_bms_on_qwr_evt(nrf_ble_bms_t * p_bms, + nrf_ble_qwr_t * p_qwr, + nrf_ble_qwr_evt_t * p_evt); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_BMS_H__ + +/** @} */ diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c new file mode 100644 index 0000000..f0d7a7f --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "cgms_db.h" + +typedef struct +{ + bool in_use_flag; + ble_cgms_rec_t record; +} database_entry_t; + +static database_entry_t m_database[CGMS_DB_MAX_RECORDS]; +static uint8_t m_database_crossref[CGMS_DB_MAX_RECORDS]; +static uint16_t m_num_records; + + +ret_code_t cgms_db_init(void) +{ + int i; + + for (i = 0; i < CGMS_DB_MAX_RECORDS; i++) + { + m_database[i].in_use_flag = false; + m_database_crossref[i] = 0xFF; + } + + m_num_records = 0; + + return NRF_SUCCESS; +} + + +uint16_t cgms_db_num_records_get(void) +{ + return m_num_records; +} + + +ret_code_t cgms_db_record_get(uint8_t record_num, ble_cgms_rec_t * p_rec) +{ + if (record_num >= m_num_records) + { + return NRF_ERROR_NOT_FOUND; + } + + // copy record to the specified memory + *p_rec = m_database[m_database_crossref[record_num]].record; + + return NRF_SUCCESS; +} + + +ret_code_t cgms_db_record_add(ble_cgms_rec_t * p_rec) +{ + int i; + + if (m_num_records == CGMS_DB_MAX_RECORDS) + { + return NRF_ERROR_NO_MEM; + } + + // find next available database entry + for (i = 0; i < CGMS_DB_MAX_RECORDS; i++) + { + if (!m_database[i].in_use_flag) + { + m_database[i].in_use_flag = true; + m_database[i].record = *p_rec; + + m_database_crossref[m_num_records] = i; + m_num_records++; + + return NRF_SUCCESS; + } + } + + return NRF_ERROR_NO_MEM; +} + + +ret_code_t cgms_db_record_delete(uint8_t record_num) +{ + int i; + + if (record_num >= m_num_records) + { + // Deleting a non-existent record is not an error + return NRF_SUCCESS; + } + + // free entry + m_database[m_database_crossref[record_num]].in_use_flag = false; + + // decrease number of records + m_num_records--; + + // remove cross reference index + for (i = record_num; i < m_num_records; i++) + { + m_database_crossref[i] = m_database_crossref[i + 1]; + } + + return NRF_SUCCESS; +} + + diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h new file mode 100644 index 0000000..d3b5125 --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_sdk_srv_cgms_db Continuous Glucose Monitoring Service database + * @{ + * @ingroup ble_cgms + * + * @brief Continuous Glucose Monitoring Service database module. + * + * @details This module implements a database of stored glucose measurement values. + * This database is meant as an example of a database that the @ref ble_cgms can use. + * Replace this module if this implementation does not suit + * your application. Any replacement implementation should follow the API below to ensure + * that the qualification of the @ref ble_cgms is not compromised. + */ + +#ifndef BLE_CGMS_DB_H__ +#define BLE_CGMS_DB_H__ + +#include "sdk_errors.h" +#include "nrf_ble_cgms.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CGMS_DB_MAX_RECORDS 100 // !< Number of records that can be stored in the database. + + +/**@brief Function for initializing the glucose record database. + * + * @retval NRF_SUCCESS If the database was successfully initialized. + */ +ret_code_t cgms_db_init(void); + + +/**@brief Function for getting the number of records in the database. + * + * @return The number of records in the database. + */ +uint16_t cgms_db_num_records_get(void); + + +/**@brief Function for getting a specific record from the database. + * + * @param[in] record_num Index of the record to retrieve. + * @param[out] p_rec Pointer to the record structure to which the retrieved record is copied. + * + * @retval NRF_SUCCESS If the record was successfully retrieved. + */ +ret_code_t cgms_db_record_get(uint8_t record_num, ble_cgms_rec_t * p_rec); + + +/**@brief Function for adding a record at the end of the database. + * + * @param[in] p_rec Pointer to the record to add to the database. + * + * @retval NRF_SUCCESS If the record was successfully added to the database. + */ +ret_code_t cgms_db_record_add(ble_cgms_rec_t * p_rec); + + +/**@brief Function for deleting a database entry. + * + * @details This call deletes an record from the database. + * + * @param[in] record_num Index of the record to delete. + * + * @retval NRF_SUCCESS If the record was successfully deleted from the database. + */ +ret_code_t cgms_db_record_delete(uint8_t record_num); + + +#ifdef __cplusplus +} +#endif + +#endif // BLE_CGMS_DB_H__ + +/** @} */ diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c new file mode 100644 index 0000000..913690c --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c @@ -0,0 +1,249 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ble.h" +#include "sdk_macros.h" +#include "ble_srv_common.h" +#include "nrf_ble_cgms.h" +#include "cgms_meas.h" +#include "cgms_db.h" + +/**@brief Function for encoding a Glucose measurement. + * + * @param[in] p_meas Measurement to be encoded. + * @param[out] p_encoded_buffer Pointer to buffer where the encoded measurement is to be stored. + * + * @return Size of encoded measurement. + */ +static uint8_t cgms_meas_encode(nrf_ble_cgms_t * p_cgms, + const nrf_ble_cgms_meas_t * p_meas, + uint8_t * p_encoded_buffer) +{ + uint8_t len = 2; + + uint8_t flags = p_meas->flags; + + len += uint16_encode(p_meas->glucose_concentration, + &p_encoded_buffer[len]); + len += uint16_encode(p_meas->time_offset, + &p_encoded_buffer[len]); + + if (p_meas->sensor_status_annunciation.warning != 0) + { + p_encoded_buffer[len++] = p_meas->sensor_status_annunciation.warning; + flags |= NRF_BLE_CGMS_STATUS_FLAGS_WARNING_OCT_PRESENT; + } + + if (p_meas->sensor_status_annunciation.calib_temp != 0) + { + p_encoded_buffer[len++] = p_meas->sensor_status_annunciation.calib_temp; + flags |= NRF_BLE_CGMS_STATUS_FLAGS_CALTEMP_OCT_PRESENT; + } + + if (p_meas->sensor_status_annunciation.status != 0) + { + p_encoded_buffer[len++] = p_meas->sensor_status_annunciation.status; + flags |= NRF_BLE_CGMS_STATUS_FLAGS_STATUS_OCT_PRESENT; + } + + // Trend field + if (p_cgms->feature.feature & NRF_BLE_CGMS_FEAT_CGM_TREND_INFORMATION_SUPPORTED) + { + if (flags & NRF_BLE_CGMS_FLAG_TREND_INFO_PRESENT) + { + len += uint16_encode(p_meas->trend, &p_encoded_buffer[len]); + } + } + + // Quality field + if (p_cgms->feature.feature & NRF_BLE_CGMS_FEAT_CGM_QUALITY_SUPPORTED) + { + if (flags & NRF_BLE_CGMS_FLAGS_QUALITY_PRESENT) + { + len += uint16_encode(p_meas->quality, &p_encoded_buffer[len]); + } + } + + p_encoded_buffer[1] = flags; + p_encoded_buffer[0] = len; + return len; +} + + +/**@brief Function for adding a characteristic for the Continuous Glucose Meter Measurement. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +ret_code_t cgms_meas_char_add(nrf_ble_cgms_t * p_cgms) +{ + uint8_t num_recs; + uint8_t encoded_cgms_meas[NRF_BLE_CGMS_MEAS_LEN_MAX]; + ble_add_char_params_t add_char_params; + ble_cgms_rec_t initial_cgms_rec_value; + + memset(&add_char_params, 0, sizeof(add_char_params)); + memset(&initial_cgms_rec_value, 0, sizeof(ble_cgms_rec_t)); + + num_recs = cgms_db_num_records_get(); + if (num_recs > 0) + { + uint32_t err_code = cgms_db_record_get(num_recs - 1, &initial_cgms_rec_value); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + add_char_params.uuid = BLE_UUID_CGM_MEASUREMENT; + add_char_params.max_len = NRF_BLE_CGMS_MEAS_LEN_MAX; + add_char_params.init_len = cgms_meas_encode(p_cgms, + &initial_cgms_rec_value.meas, + encoded_cgms_meas); + add_char_params.p_init_value = encoded_cgms_meas; + add_char_params.is_var_len = true; + add_char_params.char_props.notify = true; + add_char_params.cccd_write_access = SEC_JUST_WORKS; + + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.measurment); +} + + +ret_code_t cgms_meas_send(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec, uint8_t * p_count) +{ + + uint32_t err_code; + uint8_t encoded_meas[NRF_BLE_CGMS_MEAS_LEN_MAX + NRF_BLE_CGMS_MEAS_REC_LEN_MAX]; + uint16_t len = 0; + uint16_t hvx_len = NRF_BLE_CGMS_MEAS_LEN_MAX; + int i; + ble_gatts_hvx_params_t hvx_params; + + for (i = 0; i < *p_count; i++) + { + uint8_t meas_len = cgms_meas_encode(p_cgms, &(p_rec[i].meas), (encoded_meas + len)); + if (len + meas_len >= NRF_BLE_CGMS_MEAS_LEN_MAX) + { + break; + } + len += meas_len; + } + *p_count = i; + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_cgms->char_handles.measurment.value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_meas; + + err_code = sd_ble_gatts_hvx(p_cgms->conn_handle, &hvx_params); + if (err_code == NRF_SUCCESS) + { + if (hvx_len != len) + { + err_code = NRF_ERROR_DATA_SIZE; + } + else + { + // Measurement successfully sent + p_cgms->racp_data.racp_proc_records_reported++; + p_cgms->racp_data.racp_proc_records_reported_since_txcomplete++; + } + } + + return err_code; +} + + +/**@brief Function for handling the Glucose measurement CCCD write event. + * + * @param[in] p_cgms Service instance. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_meas_cccd_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t * p_evt_write) +{ + if (p_evt_write->len == 2) + { + // CCCD written, update notification state + if (p_cgms->evt_handler != NULL) + { + nrf_ble_cgms_evt_t evt; + + if (ble_srv_is_notification_enabled(p_evt_write->data)) + { + evt.evt_type = NRF_BLE_CGMS_EVT_NOTIFICATION_ENABLED; + } + else + { + evt.evt_type = NRF_BLE_CGMS_EVT_NOTIFICATION_DISABLED; + } + + p_cgms->evt_handler(p_cgms, &evt); + } + } +} + + +/**@brief Function for handling the WRITE event. + * + * @details Handles WRITE events from the BLE stack. + * + * @param[in] p_cgms Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void cgms_meas_on_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t * p_evt_write) +{ + + if (p_evt_write->handle == p_cgms->char_handles.measurment.cccd_handle) + { + on_meas_cccd_write(p_cgms, p_evt_write); + } +} + + diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h new file mode 100644 index 0000000..39e10ce --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h @@ -0,0 +1,104 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_sdk_srv_cgms_meas Continuous Glucose Monitoring Service Measurement + * @{ + * @ingroup ble_cgms + * @brief Continuous Glucose Monitoring Service Measurement module. + * + * @details This module implements parts of the Continuous Glucose Monitoring that relate to the + * Measurement characteristic. Events are propagated to this module from @ref ble_cgms + * using @ref cgms_meas_on_write. + * + */ + + +#ifndef NRF_BLE_CGMS_MEAS_H__ +#define NRF_BLE_CGMS_MEAS_H__ + +#include "ble.h" +#include "ble_srv_common.h" +#include "sdk_errors.h" +#include "nrf_ble_cgms.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Function for adding a characteristic for the Continuous Glucose Monitoring Measurement. + * + * @param[in] p_cgms Instance of the CGM Service. + * + * @retval NRF_SUCCESS If the characteristic was successfully added. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_meas_char_add(nrf_ble_cgms_t * p_cgms); + +/**@brief Function for sending a CGM Measurement. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_rec Measurement to be sent. + * @param[in] count Number of measurements to encode. + * + * @retval NRF_SUCCESS If the measurement was successfully sent. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_meas_send(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec, uint8_t * count); + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the BLE stack. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_evt_write Event received from the BLE stack. + */ +void cgms_meas_on_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t * p_evt_write); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_CGMS_MEAS_H__ + +/** @} */ diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c new file mode 100644 index 0000000..9b2d376 --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c @@ -0,0 +1,800 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "cgms_racp.h" +#include "cgms_db.h" +#include "cgms_meas.h" + +#define OPERAND_FILTER_TYPE_RESV 0x00 // !< Filter type value reserved for future use. +#define OPERAND_FILTER_TYPE_SEQ_NUM 0x01 // !< Filter data using Sequence Number criteria. +#define OPERAND_FILTER_TYPE_FACING_TIME 0x02 // !< Filter data using User Facing Time criteria. + +/**@brief Function for adding a characteristic for the Record Access Control Point. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +ret_code_t cgms_racp_char_add(nrf_ble_cgms_t * p_cgms) +{ + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + add_char_params.uuid = BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR; + add_char_params.max_len = BLE_L2CAP_MTU_DEF; + add_char_params.init_len = 0; + add_char_params.p_init_value = 0; + add_char_params.is_var_len = true; + add_char_params.write_access = SEC_JUST_WORKS; + add_char_params.char_props.write = true; + add_char_params.char_props.indicate = true; + add_char_params.cccd_write_access = SEC_JUST_WORKS; + add_char_params.is_defered_write = 1; + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.racp); +} + + +/**@brief Function for sending response from Specific Operation Control Point. + * + * @param[in] p_cgms Service instance. + * @param[in] p_racp_val RACP value to be sent. + */ +static void racp_send(nrf_ble_cgms_t * p_cgms, ble_racp_value_t * p_racp_val) +{ + uint32_t err_code; + uint8_t encoded_resp[25]; + uint8_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + if ( + (p_cgms->cgms_com_state != STATE_RACP_RESPONSE_PENDING) + && + (p_cgms->racp_data.racp_proc_records_reported_since_txcomplete > 0) + ) + { + p_cgms->cgms_com_state = STATE_RACP_RESPONSE_PENDING; + return; + } + + // Send indication + len = ble_racp_encode(p_racp_val, encoded_resp); + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_cgms->char_handles.racp.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_resp; + + err_code = sd_ble_gatts_hvx(p_cgms->conn_handle, &hvx_params); + + // Error handling + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + + switch (err_code) + { + case NRF_SUCCESS: + // Wait for HVC event + p_cgms->cgms_com_state = STATE_RACP_RESPONSE_IND_VERIF; + break; + + case BLE_ERROR_NO_TX_PACKETS: + // Wait for TX_COMPLETE event to retry transmission + p_cgms->cgms_com_state = STATE_RACP_RESPONSE_PENDING; + break; + + case NRF_ERROR_INVALID_STATE: + // Make sure state machine returns to the default state + p_cgms->cgms_com_state = STATE_NO_COMM; + break; + + default: + // Report error to application + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + + // Make sure state machine returns to the default state + p_cgms->cgms_com_state = STATE_NO_COMM; + break; + } +} + + +/**@brief Function for sending a RACP response containing a Response Code Op Code and Response Code Value. + * + * @param[in] p_cgms Service instance. + * @param[in] opcode RACP Op Code. + * @param[in] value RACP Response Code Value. + */ +static void racp_response_code_send(nrf_ble_cgms_t * p_cgms, uint8_t opcode, uint8_t value) +{ + p_cgms->racp_data.pending_racp_response.opcode = RACP_OPCODE_RESPONSE_CODE; + p_cgms->racp_data.pending_racp_response.operator = RACP_OPERATOR_NULL; + p_cgms->racp_data.pending_racp_response.operand_len = 2; + p_cgms->racp_data.pending_racp_response.p_operand = + p_cgms->racp_data.pending_racp_response_operand; + + p_cgms->racp_data.pending_racp_response_operand[0] = opcode; + p_cgms->racp_data.pending_racp_response_operand[1] = value; + + racp_send(p_cgms, &p_cgms->racp_data.pending_racp_response); +} + + +/**@brief Function for responding to the ALL operation. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t racp_report_records_all(nrf_ble_cgms_t * p_cgms) +{ + uint16_t total_records = cgms_db_num_records_get(); + uint16_t cur_nb_rec; + uint8_t i; + uint8_t nb_rec_to_send; + + if (p_cgms->racp_data.racp_proc_record_ndx >= total_records) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + uint32_t err_code; + ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX]; + + cur_nb_rec = total_records - p_cgms->racp_data.racp_proc_record_ndx; + if (cur_nb_rec > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX) + { + cur_nb_rec = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX; + } + nb_rec_to_send = (uint8_t)cur_nb_rec; + + for (i = 0; i < cur_nb_rec; i++) + { + err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i])); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for responding to the FIRST or the LAST operation. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static uint32_t racp_report_records_first_last(nrf_ble_cgms_t * p_cgms) +{ + uint32_t err_code; + ble_cgms_rec_t rec; + uint16_t total_records; + uint8_t nb_rec_to_send = 1; + + total_records = cgms_db_num_records_get(); + + if ((p_cgms->racp_data.racp_proc_records_reported != 0) || (total_records == 0)) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + if (p_cgms->racp_data.racp_proc_operator == RACP_OPERATOR_FIRST) + { + err_code = cgms_db_record_get(0, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else if (p_cgms->racp_data.racp_proc_operator == RACP_OPERATOR_LAST) + { + err_code = cgms_db_record_get(total_records - 1, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + err_code = cgms_meas_send(p_cgms, &rec, &nb_rec_to_send); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + p_cgms->racp_data.racp_proc_record_ndx++; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for responding to the LESS OR EQUAL operation. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static ret_code_t racp_report_records_less_equal(nrf_ble_cgms_t * p_cgms) +{ + uint16_t total_rec_nb; + uint16_t total_rec_nb_to_send; + uint16_t rec_nb_left_to_send; + uint8_t nb_rec_to_send; + uint16_t offset; + uint16_t i; + + if(p_cgms->racp_data.racp_request.operand_len != 2) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(NRF_ERROR_INVALID_LENGTH); + } + } + + total_rec_nb = cgms_db_num_records_get(); + + offset = uint16_decode(p_cgms->racp_data.racp_request.p_operand); + if (offset >= total_rec_nb) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + return NRF_SUCCESS; + } + + total_rec_nb_to_send = offset; + + if (p_cgms->racp_data.racp_proc_record_ndx >= total_rec_nb_to_send) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + uint32_t err_code; + ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX]; + + rec_nb_left_to_send = total_rec_nb_to_send - p_cgms->racp_data.racp_proc_records_reported; + + if (rec_nb_left_to_send > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX) + { + nb_rec_to_send = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX; + } + else + { + nb_rec_to_send = (uint8_t)rec_nb_left_to_send; + } + + p_cgms->racp_data.racp_proc_record_ndx = 0; + + for (i = 0; i < nb_rec_to_send; i++) + { + err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i])); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for responding to the GREATER OR EQUAL operation. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS on success, otherwise an error code. + */ +static ret_code_t racp_report_records_greater_equal(nrf_ble_cgms_t * p_cgms) +{ + uint16_t total_rec_nb; + uint16_t total_rec_nb_to_send; + uint16_t rec_nb_left_to_send; + uint8_t nb_rec_to_send; + uint16_t offset; + uint16_t i; + + if(p_cgms->racp_data.racp_request.operand_len != 2) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(NRF_ERROR_INVALID_LENGTH); + } + } + + total_rec_nb = cgms_db_num_records_get(); + + offset = uint16_decode(p_cgms->racp_data.racp_request.p_operand); + if (offset >= total_rec_nb) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + return NRF_SUCCESS; + } + + total_rec_nb_to_send = total_rec_nb - offset; + + if (p_cgms->racp_data.racp_proc_record_ndx >= total_rec_nb_to_send) + { + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + uint32_t err_code; + ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX]; + + rec_nb_left_to_send = total_rec_nb_to_send - p_cgms->racp_data.racp_proc_records_reported; + + if (rec_nb_left_to_send > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX) + { + nb_rec_to_send = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX; + } + else + { + nb_rec_to_send = (uint8_t)rec_nb_left_to_send; + } + + p_cgms->racp_data.racp_proc_record_ndx = offset; + + for (i = 0; i < nb_rec_to_send; i++) + { + err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i])); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send; + } + + return NRF_SUCCESS; +} + +/**@brief Function for informing that the REPORT RECORDS procedure is completed. + * + * @param[in] p_cgms Service instance. + */ +static void racp_report_records_completed(nrf_ble_cgms_t * p_cgms) +{ + uint8_t resp_code_value; + + if (p_cgms->racp_data.racp_proc_records_reported > 0) + { + resp_code_value = RACP_RESPONSE_SUCCESS; + } + else + { + resp_code_value = RACP_RESPONSE_NO_RECORDS_FOUND; + } + + racp_response_code_send(p_cgms, RACP_OPCODE_REPORT_RECS, resp_code_value); +} + + +/**@brief Function for the RACP report records procedure. + * + * @param[in] p_cgms Service instance. + */ +static void racp_report_records_procedure(nrf_ble_cgms_t * p_cgms) +{ + uint32_t err_code; + + while (p_cgms->cgms_com_state == STATE_RACP_PROC_ACTIVE) + { + // Execute requested procedure + switch (p_cgms->racp_data.racp_proc_operator) + { + case RACP_OPERATOR_ALL: + err_code = racp_report_records_all(p_cgms); + break; + + case RACP_OPERATOR_FIRST: + case RACP_OPERATOR_LAST: + err_code = racp_report_records_first_last(p_cgms); + break; + case RACP_OPERATOR_GREATER_OR_EQUAL: + err_code = racp_report_records_greater_equal(p_cgms); + break; + case RACP_OPERATOR_LESS_OR_EQUAL: + err_code = racp_report_records_less_equal(p_cgms); + break; + default: + // Report error to application + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(NRF_ERROR_INTERNAL); + } + + // Make sure state machine returns to the default state + // state_set(STATE_NO_COMM); + p_cgms->cgms_com_state = STATE_NO_COMM; + return; + } + + // Error handling + switch (err_code) + { + case NRF_SUCCESS: + if (p_cgms->cgms_com_state == STATE_RACP_PROC_ACTIVE) + { + //p_cgms->racp_data.racp_proc_record_ndx++; + } + else + { + racp_report_records_completed(p_cgms); + } + break; + + case BLE_ERROR_NO_TX_PACKETS: + // Wait for TX_COMPLETE event to resume transmission + return; + + case NRF_ERROR_INVALID_STATE: + // Notification is probably not enabled. Ignore request. + p_cgms->cgms_com_state = STATE_NO_COMM; + return; + + default: + // Report error to application + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + + // Make sure state machine returns to the default state + p_cgms->cgms_com_state = STATE_NO_COMM; + return; + } + } +} + + +/**@brief Function for testing if the received request is to be executed. + * + * @param[in] p_racp_request Request to be checked. + * @param[out] p_response_code Response code to be sent in case the request is rejected. + * RACP_RESPONSE_RESERVED is returned if the received message is + * to be rejected without sending a respone. + * + * @return TRUE if the request is to be executed, FALSE if it is to be rejected. + * If it is to be rejected, p_response_code will contain the response code to be + * returned to the central. + */ +static bool is_request_to_be_executed(nrf_ble_cgms_t * p_cgms, + const ble_racp_value_t * p_racp_request, + uint8_t * p_response_code) +{ + *p_response_code = RACP_RESPONSE_RESERVED; + + if (p_racp_request->opcode == RACP_OPCODE_ABORT_OPERATION) + { + if (p_cgms->cgms_com_state == STATE_RACP_PROC_ACTIVE) + { + if (p_racp_request->operator != RACP_OPERATOR_NULL) + { + *p_response_code = RACP_RESPONSE_INVALID_OPERATOR; + } + else if (p_racp_request->operand_len != 0) + { + *p_response_code = RACP_RESPONSE_INVALID_OPERAND; + } + else + { + *p_response_code = RACP_RESPONSE_SUCCESS; + } + } + else + { + *p_response_code = RACP_RESPONSE_ABORT_FAILED; + } + } + else if (p_cgms->cgms_com_state != STATE_NO_COMM) + { + return false; + } + // supported opcodes + else if ((p_racp_request->opcode == RACP_OPCODE_REPORT_RECS) || + (p_racp_request->opcode == RACP_OPCODE_REPORT_NUM_RECS)) + { + switch (p_racp_request->operator) + { + // operators WITHOUT a filter + case RACP_OPERATOR_ALL: + case RACP_OPERATOR_FIRST: + case RACP_OPERATOR_LAST: + if (p_racp_request->operand_len != 0) + { + *p_response_code = RACP_RESPONSE_INVALID_OPERAND; + } + break; + + // operators WITH a filter + case RACP_OPERATOR_GREATER_OR_EQUAL: + //*p_response_code = RACP_RESPONSE_OPERATOR_UNSUPPORTED; + break; + + // unsupported operators + case RACP_OPERATOR_LESS_OR_EQUAL: + break; + case RACP_OPERATOR_RANGE: + *p_response_code = RACP_RESPONSE_OPERATOR_UNSUPPORTED; + break; + + // invalid operators + case RACP_OPERATOR_NULL: + default: + *p_response_code = RACP_RESPONSE_INVALID_OPERATOR; + break; + } + } + // unsupported opcodes + else if (p_racp_request->opcode == RACP_OPCODE_DELETE_RECS) + { + *p_response_code = RACP_RESPONSE_OPCODE_UNSUPPORTED; + } + // unknown opcodes + else + { + *p_response_code = RACP_RESPONSE_OPCODE_UNSUPPORTED; + } + + // NOTE: The computation of the return value will change slightly when deferred write has been + // implemented in the stack. + return (*p_response_code == RACP_RESPONSE_RESERVED); +} + + +/**@brief Function for processing a REPORT RECORDS request. + * + * @param[in] p_cgms Service instance. + * @param[in] p_racp_request Request to be executed. + */ +static void report_records_request_execute(nrf_ble_cgms_t * p_cgms, + ble_racp_value_t * p_racp_request) +{ + p_cgms->cgms_com_state = STATE_RACP_PROC_ACTIVE; + + p_cgms->racp_data.racp_proc_record_ndx = 0; + p_cgms->racp_data.racp_proc_operator = p_racp_request->operator; + p_cgms->racp_data.racp_proc_records_reported = 0; + //p_cgms-> + racp_report_records_procedure(p_cgms); +} + + +/**@brief Function for processing a REPORT NUM RECORDS request. + * + * @param[in] p_cgms Service instance. + * @param[in] p_racp_request Request to be executed. + */ +static void report_num_records_request_execute(nrf_ble_cgms_t * p_cgms, + ble_racp_value_t * p_racp_request) +{ + uint16_t total_records; + uint16_t num_records; + + total_records = cgms_db_num_records_get(); + num_records = 0; + + if (p_racp_request->operator == RACP_OPERATOR_ALL) + { + num_records = total_records; + } + else if ((p_racp_request->operator == RACP_OPERATOR_FIRST) || + (p_racp_request->operator == RACP_OPERATOR_LAST)) + { + if (total_records > 0) + { + num_records = 1; + } + } + + p_cgms->racp_data.pending_racp_response.opcode = RACP_OPCODE_NUM_RECS_RESPONSE; + p_cgms->racp_data.pending_racp_response.operator = RACP_OPERATOR_NULL; + p_cgms->racp_data.pending_racp_response.operand_len = sizeof(uint16_t); + p_cgms->racp_data.pending_racp_response.p_operand = + p_cgms->racp_data.pending_racp_response_operand; + + p_cgms->racp_data.pending_racp_response_operand[0] = num_records & 0xFF; + p_cgms->racp_data.pending_racp_response_operand[1] = num_records >> 8; + + racp_send(p_cgms, &p_cgms->racp_data.pending_racp_response); +} + + +/**@brief Function for handling a write event to the Record Access Control Point. + * + * @param[in] p_cgms Service instance. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_racp_value_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t * p_evt_write) +{ +// ble_racp_value_t racp_request; + uint8_t response_code; + + // set up reply to authorized write. + ble_gatts_rw_authorize_reply_params_t auth_reply; + uint32_t err_code; + + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.offset = 0; + auth_reply.params.write.len = 0; + auth_reply.params.write.p_data = NULL; + + // Decode request + ble_racp_decode(p_evt_write->len, p_evt_write->data, &p_cgms->racp_data.racp_request); + + // Check if request is to be executed + if (is_request_to_be_executed(p_cgms,&p_cgms->racp_data.racp_request, &response_code)) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + + err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, + &auth_reply); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + return; + } + + // Execute request + if (p_cgms->racp_data.racp_request.opcode == RACP_OPCODE_REPORT_RECS) + { + report_records_request_execute(p_cgms, &p_cgms->racp_data.racp_request); + } + else if (p_cgms->racp_data.racp_request.opcode == RACP_OPCODE_REPORT_NUM_RECS) + { + report_num_records_request_execute(p_cgms, &p_cgms->racp_data.racp_request); + } + } + else if (response_code != RACP_RESPONSE_RESERVED) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, + &auth_reply); + + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + return; + } + // Abort any running procedure + p_cgms->cgms_com_state = STATE_NO_COMM; + + // Respond with error code + racp_response_code_send(p_cgms, p_cgms->racp_data.racp_request.opcode, response_code); + } + else + { + // ignore request + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, + &auth_reply); + + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + return; + } + } +} + + +void cgms_racp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t * p_auth_req) +{ + if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + if (p_auth_req->request.write.handle == p_cgms->char_handles.racp.value_handle) + { + on_racp_value_write(p_cgms, &p_auth_req->request.write); + } + } +} + + +/**@brief Function for handling the TX_COMPLETE event. + * + * @param[in] p_cgms Glucose Service structure. + */ +void cgms_racp_on_tx_complete(nrf_ble_cgms_t * p_cgms) +{ + p_cgms->racp_data.racp_proc_records_reported_since_txcomplete = 0; + + if (p_cgms->cgms_com_state == STATE_RACP_RESPONSE_PENDING) + { + racp_send(p_cgms, &p_cgms->racp_data.pending_racp_response); + } + else if (p_cgms->cgms_com_state == STATE_RACP_PROC_ACTIVE) + { + racp_report_records_procedure(p_cgms); + } +} + + diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h new file mode 100644 index 0000000..6d0b4d0 --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_sdk_srv_cgms_racp Record Access Control Point + * @{ + * @ingroup ble_cgms + * @brief Continuous Glucose Monitoring Service RACP module. + * + * @details This module implements parts of the Continuous Glucose Monitoring that relate to the + * Record Access Control Point. Events are propagated to this module from @ref ble_cgms + * using @ref cgms_racp_on_rw_auth_req and @ref cgms_racp_on_tx_complete. + * + */ + +#ifndef NRF_BLE_CGMS_RACP_H__ +#define NRF_BLE_CGMS_RACP_H__ + +#include "ble.h" +#include "ble_srv_common.h" +#include "sdk_errors.h" +#include "nrf_ble_cgms.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Function for adding a characteristic for the Record Access Control Point. + * + * @param[in] p_cgms Instance of the CGM Service. + * + * @retval NRF_SUCCESS If the characteristic was successfully added. + * @retval NRF_ERROR_NULL If any of the input parameters are NULL. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_racp_char_add(nrf_ble_cgms_t * p_cgms); + + +/**@brief Function for handling @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST events. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_auth_req Authorize request event to be handled. + */ +void cgms_racp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t * p_auth_req); + + +/**@brief Function for handling @ref BLE_EVT_TX_COMPLETE events. + * + * @param[in] p_cgms Instance of the CGM Service. + */ +void cgms_racp_on_tx_complete(nrf_ble_cgms_t * p_cgms); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_CGMS_RACP_H__ + +/** @} */ diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c new file mode 100644 index 0000000..1659e51 --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c @@ -0,0 +1,432 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "cgms_sst.h" +#include "cgms_socp.h" + + +#define NRF_BLE_CGMS_PLUS_INFINTE 0x07FE +#define NRF_BLE_CGMS_MINUS_INFINTE 0x0802 + +/**@brief Specific Operation Control Point opcodes. */ +#define SOCP_OPCODE_RESERVED 0x00 /**< Specific Operation Control Point opcode - Reserved for future use. */ +#define SOCP_WRITE_CGM_COMMUNICATION_INTERVAL 0x01 +#define SOCP_READ_CGM_COMMUNICATION_INTERVAL 0x02 +#define SOCP_READ_CGM_COMMUNICATION_INTERVAL_RESPONSE 0x03 +#define SOCP_WRITE_GLUCOSE_CALIBRATION_VALUE 0x04 +#define SOCP_READ_GLUCOSE_CALIBRATION_VALUE 0x05 +#define SOCP_READ_GLUCOSE_CALIBRATION_VALUE_RESPONSE 0x06 +#define SOCP_WRITE_PATIENT_HIGH_ALERT_LEVEL 0x07 +#define SOCP_READ_PATIENT_HIGH_ALERT_LEVEL 0x08 +#define SOCP_READ_PATIENT_HIGH_ALERT_LEVEL_RESPONSE 0x09 +#define SOCP_WRITE_PATIENT_LOW_ALERT_LEVEL 0x0A +#define SOCP_READ_PATIENT_LOW_ALERT_LEVEL 0x0B +#define SOCP_READ_PATIENT_LOW_ALERT_LEVEL_RESPONSE 0x0C +#define SOCP_SET_HYPO_ALERT_LEVEL 0x0D /**Set Hypo Alert Level Hypo Alert Level value in mg/dL The response to this control point is Response Code. */ +#define SOCP_GET_HYPO_ALERT_LEVEL 0x0E /**Get Hypo Alert Level N/A The normal response to this control point is Op Code 0x0F. For error conditions, the response is Response Code */ +#define SOCP_HYPO_ALERT_LEVEL_RESPONSE 0x0F /**Hypo Alert Level Response Hypo Alert Level value in mg/dL This is the normal response to Op Code 0x0E */ +#define SOCP_SET_HYPER_ALERT_LEVEL 0x10 /**Set Hyper Alert Level Hyper Alert Level value in mg/dL The response to this control point is Response Code. */ +#define SOCP_GET_HYPER_ALERT_LEVEL 0x11 /**Get Hyper Alert Level N/A The normal response to this control point is Op Code 0x12. For error conditions, the response is Response Code */ +#define SOCP_HYPER_ALERT_LEVEL_RESPONSE 0x12 /**Hyper Alert Level Response Hyper Alert Level value in mg/dL This is the normal response to Op Code 0x11 */ +#define SOCP_SET_RATE_OF_DECREASE_ALERT_LEVEL 0x13 /**Set Rate of Decrease Alert Level Rate of Decrease Alert Level value in mg/dL/min The response to this control point is Response Code. */ +#define SOCP_GET_RATE_OF_DECREASE_ALERT_LEVEL 0x14 /**Get Rate of Decrease Alert Level N/A The normal response to this control point is Op Code 0x15. For error conditions, the response is Response Code */ +#define SOCP_RATE_OF_DECREASE_ALERT_LEVEL_RESPONSE 0x15 /**Rate of Decrease Alert Level Response Rate of Decrease Alert Level value in mg/dL/min This is the normal response to Op Code 0x14 */ +#define SOCP_SET_RATE_OF_INCREASE_ALERT_LEVEL 0x16 /**Set Rate of Increase Alert Level Rate of Increase Alert Level value in mg/dL/min The response to this control point is Response Code. */ +#define SOCP_GET_RATE_OF_INCREASE_ALERT_LEVEL 0x17 /**Get Rate of Increase Alert Level N/A The normal response to this control point is Op Code 0x18. For error conditions, the response is Response Code */ +#define SOCP_RATE_OF_INCREASE_ALERT_LEVEL_RESPONSE 0x18 /**Rate of Increase Alert Level Response Rate of Increase Alert Level value in mg/dL/min This is the normal response to Op Code 0x17 */ +#define SOCP_RESET_DEVICE_SPECIFIC_ALERT 0x19 /**Reset Device Specific Alert N/A The response to this control point is Response Code. */ + +#define SOCP_START_THE_SESSION 0x1A +#define SOCP_STOP_THE_SESSION 0x1B +#define SOCP_RESPONSE_CODE 0x1C + +#define SOCP_RSP_RESERVED_FOR_FUTURE_USE 0x00 +#define SOCP_RSP_SUCCESS 0x01 +#define SOCP_RSP_OP_CODE_NOT_SUPPORTED 0x02 +#define SOCP_RSP_INVALID_OPERAND 0x03 +#define SOCP_RSP_PROCEDURE_NOT_COMPLETED 0x04 +#define SOCP_RSP_OUT_OF_RANGE 0x05 + +static void ble_socp_decode(uint8_t data_len, uint8_t * p_data, ble_cgms_socp_value_t * p_socp_val) +{ + p_socp_val->opcode = 0xFF; + p_socp_val->operand_len = 0; + p_socp_val->p_operand = NULL; + + if (data_len > 0) + { + p_socp_val->opcode = p_data[0]; + } + if (data_len > 1) + { + p_socp_val->operand_len = data_len - 1; + p_socp_val->p_operand = &p_data[1]; // lint !e416 + } +} + + +uint8_t ble_socp_encode(const ble_socp_rsp_t * p_socp_rsp, uint8_t * p_data) +{ + uint8_t len = 0; + int i; + + + if (p_data != NULL) + { + p_data[len++] = p_socp_rsp->opcode; + + if ( + (p_socp_rsp->opcode != SOCP_READ_CGM_COMMUNICATION_INTERVAL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_READ_PATIENT_HIGH_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_READ_PATIENT_LOW_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_HYPO_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_HYPER_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_RATE_OF_DECREASE_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_RATE_OF_INCREASE_ALERT_LEVEL_RESPONSE) + && (p_socp_rsp->opcode != SOCP_READ_GLUCOSE_CALIBRATION_VALUE_RESPONSE) + ) + { + p_data[len++] = p_socp_rsp->req_opcode; + p_data[len++] = p_socp_rsp->rsp_code; + } + + for (i = 0; i < p_socp_rsp->size_val; i++) + { + p_data[len++] = p_socp_rsp->resp_val[i]; + } + } + + return len; +} + + +/**@brief Function for adding a characteristic for the Specific Operations Control Point. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +ret_code_t cgms_socp_char_add(nrf_ble_cgms_t * p_cgms) +{ + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + add_char_params.uuid = BLE_UUID_CGM_SPECIFIC_OPS_CTRLPT; + add_char_params.max_len = BLE_L2CAP_MTU_DEF; + add_char_params.init_len = 0; + add_char_params.p_init_value = 0; + add_char_params.is_var_len = true; + add_char_params.char_props.indicate = true; + add_char_params.char_props.write = true; + add_char_params.write_access = SEC_JUST_WORKS; + add_char_params.cccd_write_access = SEC_JUST_WORKS; + add_char_params.is_defered_write = 1; + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.socp); +} + + +/**@brief Function for sending a response from the Specific Operation Control Point. + * + * @param[in] p_cgms Service instance. + */ +static void socp_send(nrf_ble_cgms_t * p_cgms) +{ + uint32_t err_code; + uint8_t encoded_resp[25]; + uint8_t len; + uint16_t hvx_len; + ble_gatts_hvx_params_t hvx_params; + + // Send indication + len = ble_socp_encode(&(p_cgms->socp_response), encoded_resp); + hvx_len = len; + + memset(&hvx_params, 0, sizeof(hvx_params)); + + hvx_params.handle = p_cgms->char_handles.socp.value_handle; + hvx_params.type = BLE_GATT_HVX_INDICATION; + hvx_params.offset = 0; + hvx_params.p_len = &hvx_len; + hvx_params.p_data = encoded_resp; + + err_code = sd_ble_gatts_hvx(p_cgms->conn_handle, &hvx_params); + + // Error handling + if ((err_code == NRF_SUCCESS) && (hvx_len != len)) + { + err_code = NRF_ERROR_DATA_SIZE; + } + + switch (err_code) + { + case NRF_SUCCESS: + // Wait for HVC event + p_cgms->cgms_com_state = STATE_SOCP_RESPONSE_IND_VERIF; + break; + + case BLE_ERROR_NO_TX_PACKETS: + // Wait for TX_COMPLETE event to retry transmission + p_cgms->cgms_com_state = STATE_SOCP_RESPONSE_PENDING; + break; + + case NRF_ERROR_INVALID_STATE: + // Make sure state machine returns to the default state + p_cgms->cgms_com_state = STATE_NO_COMM; + break; + + default: + // Report error to application + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + + // Make sure state machine returns to the default state + p_cgms->cgms_com_state = STATE_NO_COMM; + break; + } +} + + +void encode_get_response(uint8_t rsp_code, ble_socp_rsp_t * p_rsp, uint16_t in_val) +{ + p_rsp->opcode = rsp_code; + p_rsp->rsp_code = SOCP_RSP_SUCCESS; + p_rsp->size_val += uint16_encode(in_val, &(p_rsp->resp_val[p_rsp->size_val])); +} + + +void decode_set_opcode(nrf_ble_cgms_t * p_cgms, + ble_cgms_socp_value_t * rcv_val, + uint16_t min, + uint16_t max, + uint16_t * p_val) +{ + uint16_t rcvd_val = uint16_decode(rcv_val->p_operand); + + if ((rcvd_val == NRF_BLE_CGMS_PLUS_INFINTE) + || (rcvd_val == NRF_BLE_CGMS_MINUS_INFINTE) + || (rcvd_val > max) + || (rcvd_val < min)) + { + p_cgms->socp_response.rsp_code = SOCP_RSP_OUT_OF_RANGE; + } + else + { + p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS; + *p_val = rcvd_val; + } +} + + +static bool is_feature_present(nrf_ble_cgms_t * p_cgms, uint32_t feature) +{ + return (p_cgms->feature.feature & feature); +} + + +/**@brief Function for handling a write event to the Specific Operation Control Point. + * + * @param[in] p_cgms Service instance. + * @param[in] p_evt_write WRITE event to be handled. + */ +void on_socp_value_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t * p_evt_write) +{ + ble_cgms_socp_value_t socp_request; + nrf_ble_cgms_evt_t evt; + ble_gatts_rw_authorize_reply_params_t auth_reply; + uint32_t err_code; + + memset(&auth_reply, 0, sizeof(auth_reply)); + + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.params.write.update = 1; + + err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + return; + } + + // Decode request + ble_socp_decode(p_evt_write->len, p_evt_write->data, &socp_request); + + p_cgms->socp_response.opcode = SOCP_RESPONSE_CODE; + p_cgms->socp_response.req_opcode = socp_request.opcode; + p_cgms->socp_response.rsp_code = SOCP_RSP_OP_CODE_NOT_SUPPORTED; + p_cgms->socp_response.size_val = 0; + + + switch (socp_request.opcode) + { + case SOCP_WRITE_CGM_COMMUNICATION_INTERVAL: + p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS; + p_cgms->comm_interval = socp_request.p_operand[0]; + evt.evt_type = NRF_BLE_CGMS_EVT_WRITE_COMM_INTERVAL; + p_cgms->evt_handler(p_cgms, &evt); + break; + + case SOCP_READ_CGM_COMMUNICATION_INTERVAL: + p_cgms->socp_response.opcode = SOCP_READ_CGM_COMMUNICATION_INTERVAL_RESPONSE; + p_cgms->socp_response.resp_val[0] = p_cgms->comm_interval; + p_cgms->socp_response.size_val++; + break; + + case SOCP_START_THE_SESSION: + if (p_cgms->is_session_started) + { + p_cgms->socp_response.rsp_code = SOCP_RSP_PROCEDURE_NOT_COMPLETED; + } + else if ((p_cgms->nb_run_session != 0) && + !(is_feature_present(p_cgms, NRF_BLE_CGMS_FEAT_MULTIPLE_SESSIONS_SUPPORTED))) + { + p_cgms->socp_response.rsp_code = SOCP_RSP_PROCEDURE_NOT_COMPLETED; + } + else + { + p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS; + p_cgms->is_session_started = true; + p_cgms->nb_run_session++; + + if (p_cgms->evt_handler != NULL) + { + evt.evt_type = NRF_BLE_CGMS_EVT_START_SESSION; + p_cgms->evt_handler(p_cgms, &evt); + } + + ble_cgms_sst_t sst; + memset(&sst, 0, sizeof(ble_cgms_sst_t)); + + err_code = cgms_sst_set(p_cgms, &sst); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + } + p_cgms->sensor_status.time_offset = 0; + p_cgms->sensor_status.status.status &= (~NRF_BLE_CGMS_STATUS_SESSION_STOPPED); + + err_code = nrf_ble_cgms_update_status(p_cgms, &p_cgms->sensor_status); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + } + } + break; + + case SOCP_STOP_THE_SESSION: + { + nrf_ble_cgm_status_t status; + memset(&status, 0, sizeof(nrf_ble_cgm_status_t)); + + p_cgms->evt_handler(p_cgms, &evt); + p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS; + p_cgms->is_session_started = false; + + status.time_offset = p_cgms->sensor_status.time_offset; + status.status.status = p_cgms->sensor_status.status.status | + NRF_BLE_CGMS_STATUS_SESSION_STOPPED; + + if (p_cgms->evt_handler != NULL) + { + evt.evt_type = NRF_BLE_CGMS_EVT_STOP_SESSION; + p_cgms->evt_handler(p_cgms, &evt); + } + err_code = nrf_ble_cgms_update_status(p_cgms, &status); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + } + break; + } + + default: + p_cgms->socp_response.rsp_code = SOCP_RSP_OP_CODE_NOT_SUPPORTED; + break; + } + + socp_send(p_cgms); +} + + +void cgms_socp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t * p_auth_req) +{ + if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + if (p_auth_req->request.write.handle == p_cgms->char_handles.socp.value_handle) + { + on_socp_value_write(p_cgms, &p_auth_req->request.write); + } + } +} + + +void cgms_socp_on_tx_complete(nrf_ble_cgms_t * p_cgms) +{ + if (p_cgms->cgms_com_state == STATE_SOCP_RESPONSE_PENDING) + { + socp_send(p_cgms); + } +} + + diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h new file mode 100644 index 0000000..f7c7089 --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_sdk_srv_cgms_socp Specific Operations Control Point + * @{ + * @ingroup ble_cgms + * @brief Continuous Glucose Monitoring Service SOCP module. + * + * @details This module implements parts of the Continuous Glucose Monitoring that relate to the + * Specific Operations Control Point. Events are propagated to this module from @ref ble_cgms + * using @ref cgms_socp_on_rw_auth_req and @ref cgms_socp_on_tx_complete. + * + */ + +#ifndef NRF_BLE_CGMS_SOCP_H__ +#define NRF_BLE_CGMS_SOCP_H__ + +#include "ble.h" +#include "ble_srv_common.h" +#include "sdk_errors.h" +#include "nrf_ble_cgms.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Specific Operation Control Point value. */ +typedef struct +{ + uint8_t opcode; /**< Opcode. */ + uint8_t operand_len; /**< Length of the operand. */ + uint8_t * p_operand; /**< Pointer to the operand. */ +} ble_cgms_socp_value_t; + + +/**@brief Function for adding a characteristic for the Specific Operations Control Point. + * + * @param[in] p_cgms Instance of the CGM Service. + * + * @retval NRF_SUCCESS If the characteristic was successfully added. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_socp_char_add(nrf_ble_cgms_t * p_cgms); + + +/**@brief Function for handling @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST events. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_auth_req Authorize request event to be handled. + */ +void cgms_socp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t * p_auth_req); + + +/**@brief Function for handling @ref BLE_EVT_TX_COMPLETE events. + * + * @param[in] p_cgms Instance of the CGM Service. + */ +void cgms_socp_on_tx_complete(nrf_ble_cgms_t * p_cgms); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_CGMS_SOCP_H__ + +/** @} */ diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c new file mode 100644 index 0000000..1c7725b --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c @@ -0,0 +1,235 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include +#include "ble.h" +#include "ble_srv_common.h" +#include "nrf_ble_cgms.h" +#include "cgms_sst.h" + + +void sst_decode(ble_cgms_sst_t * p_sst, const uint8_t * p_data, const uint16_t len) +{ + uint32_t index; + + if (len != NRF_BLE_CGMS_SST_LEN) + { + return; + } + + index = ble_date_time_decode(&p_sst->date_time, p_data); + + p_sst->time_zone = p_data[index++]; + p_sst->dst = p_data[index++]; +} + + +void convert_ble_time_c_time(ble_cgms_sst_t * p_sst, struct tm * p_c_time_date) +{ + p_c_time_date->tm_sec = p_sst->date_time.seconds; + p_c_time_date->tm_min = p_sst->date_time.minutes; + p_c_time_date->tm_hour = p_sst->date_time.hours; + p_c_time_date->tm_mday = p_sst->date_time.day; + p_c_time_date->tm_mon = p_sst->date_time.month; + p_c_time_date->tm_year = p_sst->date_time.year - 1900; + + // Ignore daylight saving for this conversion. + p_c_time_date->tm_isdst = 0; +} + + +void calc_sst(uint16_t offset, struct tm * p_c_time_date) +{ + time_t c_time_in_sec; + + c_time_in_sec = mktime(p_c_time_date); + c_time_in_sec = c_time_in_sec - (offset * 60); + *p_c_time_date = *(localtime(&c_time_in_sec)); + + if(p_c_time_date->tm_isdst == 1) + { + // Daylight saving time is not used and must be removed. + p_c_time_date->tm_hour = p_c_time_date->tm_hour - 1; + p_c_time_date->tm_isdst = 0; + } +} + + +static void convert_c_time_ble_time(ble_cgms_sst_t * p_sst, struct tm * p_c_time_date) +{ + p_sst->date_time.seconds = p_c_time_date->tm_sec; + p_sst->date_time.minutes = p_c_time_date->tm_min; + p_sst->date_time.hours = p_c_time_date->tm_hour; + p_sst->date_time.day = p_c_time_date->tm_mday; + p_sst->date_time.month = p_c_time_date->tm_mon; + p_sst->date_time.year = p_c_time_date->tm_year + 1900; +} + + +static uint8_t sst_encode(ble_cgms_sst_t * p_sst, uint8_t * p_encoded_sst) +{ + uint8_t len; + + len = ble_date_time_encode(&p_sst->date_time, p_encoded_sst); + + p_encoded_sst[len++] = p_sst->time_zone; + p_encoded_sst[len++] = p_sst->dst; + + return len; +} + + +static ret_code_t cgm_update_sst(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write) +{ + ble_cgms_sst_t sst; + struct tm c_time_and_date; + + memset(&sst, 0, sizeof(ble_cgms_sst_t)); + + sst_decode(&sst, p_evt_write->data, p_evt_write->len); + convert_ble_time_c_time(&sst, &c_time_and_date); + calc_sst(p_cgms->sensor_status.time_offset, &c_time_and_date); + convert_c_time_ble_time(&sst, &c_time_and_date); + + return cgms_sst_set(p_cgms, &sst); +} + + +/**@brief Function for handling the Glucose session start time write event. + * + * @param[in] p_cgms Service instance. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_sst_value_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write) +{ + ble_gatts_rw_authorize_reply_params_t auth_reply; + uint32_t err_code; + + memset(&auth_reply, 0, sizeof(auth_reply)); + + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.update = 1; + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + } + + err_code = cgm_update_sst(p_cgms, p_evt_write); + if (err_code != NRF_SUCCESS) + { + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(err_code); + } + } +} + + +/**@brief Function for adding a characteristic for the Session Start Time. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +ret_code_t cgms_sst_char_add(nrf_ble_cgms_t * p_cgms) +{ + ble_add_char_params_t add_char_params; + uint8_t init_value[NRF_BLE_CGMS_SST_LEN] = {0}; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + add_char_params.uuid = BLE_UUID_CGM_SESSION_START_TIME; + add_char_params.max_len = NRF_BLE_CGMS_SST_LEN; + + add_char_params.init_len = NRF_BLE_CGMS_SST_LEN; + add_char_params.p_init_value = init_value; + + add_char_params.read_access = SEC_JUST_WORKS; + add_char_params.write_access = SEC_JUST_WORKS; + add_char_params.is_defered_write = 1; + add_char_params.char_props.write = true; + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.sst); +} + + +ret_code_t cgms_sst_set(nrf_ble_cgms_t * p_cgms, ble_cgms_sst_t * p_sst) +{ + uint16_t conn_handle; + uint16_t value_handle; + ble_gatts_value_t sst_val; + uint8_t encoded_start_session_time[NRF_BLE_CGMS_SST_LEN]; + uint8_t gatts_value_set_len = 0; + + gatts_value_set_len = sst_encode(p_sst, encoded_start_session_time); + conn_handle = p_cgms->conn_handle; + value_handle = p_cgms->char_handles.sst.value_handle; + memset(&sst_val, 0, sizeof(ble_gatts_value_t)); + sst_val.len = gatts_value_set_len; + sst_val.p_value = encoded_start_session_time; + sst_val.offset = 0; + + return (sd_ble_gatts_value_set(conn_handle, value_handle, &sst_val)); +} + + +void cgms_sst_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t const * p_auth_req) +{ + if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + if (p_auth_req->request.write.handle == p_cgms->char_handles.sst.value_handle) + { + on_sst_value_write(p_cgms, &p_auth_req->request.write); + } + } +} + + diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h new file mode 100644 index 0000000..69ae1d5 --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h @@ -0,0 +1,116 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_sdk_srv_cgms_sst Session Start Time + * @{ + * @ingroup ble_cgms + * + * @brief Continuous Glucose Monitoring Service SST module. + * + * @details This module implements parts of the Continuous Glucose Monitoring that relate to the + * Session Start Time characteristic. Events are propagated to this module from @ref ble_cgms + * using @ref cgms_sst_on_rw_auth_req. + * + */ + +#ifndef NRF_BLE_CGMS_SST_H__ +#define NRF_BLE_CGMS_SST_H__ + + +#include "ble.h" +#include "ble_srv_common.h" +#include "ble_date_time.h" +#include "sdk_errors.h" +#include "nrf_ble_cgms.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Required data for setting the SST characteristic value. */ +typedef struct +{ + ble_date_time_t date_time; /**< Date and time. */ + uint8_t time_zone; /**< Time zone. */ + uint8_t dst; /**< Daylight saving time. */ +}ble_cgms_sst_t; + +/**@brief Function for adding a characteristic for the Session Start Time. + * + * @param[in] p_cgms Instance of the CGM Service. + * + * @retval NRF_SUCCESS If the characteristic was successfully added. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_sst_char_add(nrf_ble_cgms_t * p_cgms); + + +/**@brief Function for setting the Session Run Time attribute. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_sst Time and date that will be displayed in the session start time attribute. + * + * @retval NRF_SUCCESS If the Session Run Time Attribute was successfully set. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t cgms_sst_set(nrf_ble_cgms_t * p_cgms, ble_cgms_sst_t * p_sst); + + +/**@brief Function for handling @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST events. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_auth_req Authorize request event to be handled. + */ +void cgms_sst_on_rw_auth_req(nrf_ble_cgms_t * p_cgms, + ble_gatts_evt_rw_authorize_request_t const * p_auth_req); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_CGMS_SST_H__ + +/** @} */ diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c b/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c new file mode 100644 index 0000000..b5e8e18 --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c @@ -0,0 +1,503 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + + +#include "ble_racp.h" +#include "ble_srv_common.h" + +#include "ble_date_time.h" +#include "sdk_common.h" + +#include "nrf_ble_cgms.h" +#include "cgms_db.h" +#include "cgms_meas.h" +#include "cgms_racp.h" +#include "cgms_socp.h" +#include "cgms_sst.h" + +#define OPERAND_FILTER_TYPE_RESV 0x00 /**< Filter type value reserved for future use. */ +#define OPERAND_FILTER_TYPE_SEQ_NUM 0x01 /**< Filter data using Sequence Number criteria. */ +#define OPERAND_FILTER_TYPE_FACING_TIME 0x02 /**< Filter data using User Facing Time criteria. */ + + +/**@brief Function for setting next sequence number by reading the last record in the data base. + * + * @return NRF_SUCCESS on successful initialization of service, otherwise an error code. + */ +static uint32_t next_sequence_number_set(void) +{ + uint16_t num_records; + ble_cgms_rec_t rec; + + num_records = cgms_db_num_records_get(); + if (num_records > 0) + { + // Get last record + uint32_t err_code = cgms_db_record_get(num_records - 1, &rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +uint8_t encode_feature_location_type(uint8_t * p_out_buffer, nrf_ble_cgms_feature_t * p_in_feature) +{ + uint8_t len = 0; + + len += uint24_encode(p_in_feature->feature, &p_out_buffer[len]); + p_out_buffer[len++] = (p_in_feature->sample_location << 4) | (p_in_feature->type & 0x0F); + len += uint16_encode(0xFFFF, &p_out_buffer[len]); + + return len; +} + + +/**@brief Function for adding a characteristic for the glucose feature. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +static uint32_t glucose_feature_char_add(nrf_ble_cgms_t * p_cgms) +{ + uint8_t init_value_len; + uint8_t encoded_initial_feature[NRF_BLE_CGMS_FEATURE_LEN]; + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + init_value_len = encode_feature_location_type(encoded_initial_feature, &(p_cgms->feature)); + + add_char_params.uuid = BLE_UUID_CGM_FEATURE; + add_char_params.max_len = init_value_len; + add_char_params.init_len = init_value_len; + add_char_params.p_init_value = encoded_initial_feature; + add_char_params.read_access = SEC_JUST_WORKS; + add_char_params.write_access = SEC_NO_ACCESS; + + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.feature); +} + + +uint8_t encode_status(uint8_t * p_out_buffer, nrf_ble_cgms_t * p_cgms) +{ + uint8_t len = 0; + + len += uint16_encode(p_cgms->sensor_status.time_offset, &p_out_buffer[len]); + + p_out_buffer[len++] = p_cgms->sensor_status.status.status; + p_out_buffer[len++] = p_cgms->sensor_status.status.calib_temp; + p_out_buffer[len++] = p_cgms->sensor_status.status.warning; + + return len; +} + + +/**@brief Function for adding a status characteristic for the CGMS. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +static uint32_t status_char_add(nrf_ble_cgms_t * p_cgms) +{ + uint8_t init_value_len; + uint8_t encoded_initial_status[NRF_BLE_CGMS_STATUS_LEN]; + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + init_value_len = encode_status(encoded_initial_status, p_cgms); + + add_char_params.uuid = BLE_UUID_CGM_STATUS; + add_char_params.max_len = init_value_len; + add_char_params.init_len = init_value_len; + add_char_params.p_init_value = encoded_initial_status; + add_char_params.read_access = SEC_JUST_WORKS; + add_char_params.write_access = SEC_NO_ACCESS; + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.status); +} + + +/**@brief Function for adding a characteristic for the Session Run Time. + * + * @param[in] p_cgms Service instance. + * + * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code. + */ +static uint32_t srt_char_add(nrf_ble_cgms_t * p_cgms) +{ + uint8_t len = 0; + uint8_t encoded_initial_srt[NRF_BLE_CGMS_SRT_LEN]; + ble_add_char_params_t add_char_params; + + memset(&add_char_params, 0, sizeof(add_char_params)); + + + len += uint16_encode(p_cgms->session_run_time, &(encoded_initial_srt[len])); + + add_char_params.uuid = BLE_UUID_CGM_SESSION_RUN_TIME; + add_char_params.max_len = NRF_BLE_CGMS_SRT_LEN; + add_char_params.init_len = len; + add_char_params.p_init_value = encoded_initial_srt; + add_char_params.read_access = SEC_JUST_WORKS; + add_char_params.write_access = SEC_NO_ACCESS; + + return characteristic_add(p_cgms->service_handle, + &add_char_params, + &p_cgms->char_handles.srt); +} + + +uint8_t init_calib_val[] = { + 0x3E, + 0x00, + 0x07, + 0x00, + 0x06, + 0x07, + 0x00, + 0x00, + 0x00, + 0x00, +}; +ret_code_t nrf_ble_cgms_init(nrf_ble_cgms_t * p_cgms, const nrf_ble_cgms_init_t * p_cgms_init) +{ + VERIFY_PARAM_NOT_NULL(p_cgms); + VERIFY_PARAM_NOT_NULL(p_cgms_init); + VERIFY_PARAM_NOT_NULL(p_cgms_init->evt_handler); + + uint32_t err_code; + ble_uuid_t ble_uuid; + + // Initialize data base + err_code = cgms_db_init(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = next_sequence_number_set(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Initialize service structure + p_cgms->evt_handler = p_cgms_init->evt_handler; + p_cgms->error_handler = p_cgms_init->error_handler; + p_cgms->feature = p_cgms_init->feature; + p_cgms->sensor_status = p_cgms_init->initial_sensor_status; + p_cgms->session_run_time = p_cgms_init->initial_run_time; + p_cgms->is_session_started = false; + p_cgms->nb_run_session = 0; + p_cgms->conn_handle = BLE_CONN_HANDLE_INVALID; + + p_cgms->feature.feature = 0; + p_cgms->feature.feature |= NRF_BLE_CGMS_FEAT_MULTIPLE_BOND_SUPPORTED; + p_cgms->feature.feature |= NRF_BLE_CGMS_FEAT_MULTIPLE_SESSIONS_SUPPORTED; + p_cgms->feature.type = NRF_BLE_CGMS_MEAS_TYPE_VEN_BLOOD; + p_cgms->feature.sample_location = NRF_BLE_CGMS_MEAS_LOC_AST; + p_cgms->feature.feature |= NRF_BLE_CGMS_FEAT_MULTIPLE_BOND_SUPPORTED; + + memcpy(p_cgms->calibration_val[0].value, init_calib_val, NRF_BLE_CGMS_MAX_CALIB_LEN); + + // Initialize global variables + p_cgms->cgms_com_state = STATE_NO_COMM; + p_cgms->racp_data.racp_proc_records_reported_since_txcomplete = 0; + + // Add service + BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CGM_SERVICE); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &ble_uuid, + &p_cgms->service_handle); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add glucose measurement characteristic + err_code = cgms_meas_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add glucose measurement feature characteristic + err_code = glucose_feature_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add glucose measurement status characteristic + err_code = status_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add record control access point characteristic + err_code = cgms_racp_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Start Session Time characteristic + err_code = cgms_sst_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Session Run Time characteristic + err_code = srt_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Add Specific Operations Control Point characteristic + err_code = cgms_socp_char_add(p_cgms); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + return NRF_SUCCESS; +} + + +/**@brief Function for handling the WRITE event. + * + * @details Handles WRITE events from the BLE stack. + * + * @param[in] p_cgms Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_write(nrf_ble_cgms_t * p_cgms, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write; + + cgms_meas_on_write(p_cgms, p_evt_write); +} + + +/**@brief Function for handling the TX_COMPLETE event. + * + * @details Handles TX_COMPLETE events from the BLE stack. + * + * @param[in] p_cgms Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_tx_complete(nrf_ble_cgms_t * p_cgms, ble_evt_t * p_ble_evt) +{ + p_cgms->racp_data.racp_proc_records_reported_since_txcomplete = 0; + + cgms_racp_on_tx_complete(p_cgms); + cgms_socp_on_tx_complete(p_cgms); +} + + +/**@brief Function for handling the HVC event. + * + * @details Handles HVC events from the BLE stack. + * + * @param[in] p_cgms Glucose Service structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +static void on_hvc(nrf_ble_cgms_t * p_cgms, ble_evt_t * p_ble_evt) +{ + ble_gatts_evt_hvc_t * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc; + + if (p_hvc->handle == p_cgms->char_handles.racp.value_handle) + { + if (p_cgms->cgms_com_state == STATE_RACP_RESPONSE_IND_VERIF) + { + // Indication has been acknowledged. Return to default state. + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + // We did not expect this event in this state. Report error to application. + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(NRF_ERROR_INVALID_STATE); + } + } + } + if (p_hvc->handle == p_cgms->char_handles.socp.value_handle) + { + if (p_cgms->cgms_com_state == STATE_SOCP_RESPONSE_IND_VERIF) + { + // Indication has been acknowledged. Return to default state. + p_cgms->cgms_com_state = STATE_NO_COMM; + } + else + { + // We did not expect this event in this state. Report error to application. + if (p_cgms->error_handler != NULL) + { + p_cgms->error_handler(NRF_ERROR_INVALID_STATE); + } + } + } +} + + +static void on_rw_authorize_request(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_t * p_gatts_evt) +{ + ble_gatts_evt_rw_authorize_request_t * p_auth_req = &p_gatts_evt->params.authorize_request; + + cgms_racp_on_rw_auth_req(p_cgms, p_auth_req); + cgms_socp_on_rw_auth_req(p_cgms, p_auth_req); + cgms_sst_on_rw_auth_req(p_cgms, p_auth_req); +} + + +void nrf_ble_cgms_on_ble_evt(nrf_ble_cgms_t * p_cgms, ble_evt_t * p_ble_evt) +{ + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + p_cgms->conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + p_cgms->cgms_com_state = STATE_NO_COMM; + break; + + case BLE_GAP_EVT_DISCONNECTED: + p_cgms->conn_handle = BLE_CONN_HANDLE_INVALID; + break; + + case BLE_GATTS_EVT_WRITE: + on_write(p_cgms, p_ble_evt); + break; + + case BLE_EVT_TX_COMPLETE: + on_tx_complete(p_cgms, p_ble_evt); + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_authorize_request(p_cgms, &p_ble_evt->evt.gatts_evt); + break; + + case BLE_GATTS_EVT_HVC: + on_hvc(p_cgms, p_ble_evt); + break; + + default: + // No implementation needed. + break; + } +} + + +ret_code_t nrf_ble_cgms_meas_create(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec) +{ + uint32_t err_code = NRF_SUCCESS; + uint8_t nb_rec_to_send = 1; + + err_code = cgms_db_record_add(p_rec); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + if ((p_cgms->conn_handle != BLE_CONN_HANDLE_INVALID) && (p_cgms->comm_interval != 0)) + { + err_code = cgms_meas_send(p_cgms, p_rec, &nb_rec_to_send); + } + return err_code; +} + + +ret_code_t nrf_ble_cgms_update_status(nrf_ble_cgms_t * p_cgms, nrf_ble_cgm_status_t * p_status) +{ + uint8_t encoded_status[NRF_BLE_CGMS_STATUS_LEN]; + ble_gatts_value_t status_val; + + memset(&status_val, 0, sizeof(status_val)); + p_cgms->sensor_status = *p_status; + status_val.len = encode_status(encoded_status, p_cgms); + status_val.p_value = encoded_status; + status_val.offset = 0; + + return (sd_ble_gatts_value_set(p_cgms->conn_handle, p_cgms->char_handles.status.value_handle, + &status_val)); +} + + +ret_code_t nrf_ble_cgms_conn_handle_assign(nrf_ble_cgms_t * p_cgms, uint16_t conn_handle) +{ + VERIFY_PARAM_NOT_NULL(p_cgms); + p_cgms->conn_handle = conn_handle; + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_cgms_srt_set(nrf_ble_cgms_t * p_cgms, uint16_t run_time) +{ + ble_gatts_value_t srt_val; + uint8_t encoded_session_run_time[NRF_BLE_CGMS_SRT_LEN]; + uint8_t gatts_value_set_len = 0; + + gatts_value_set_len = uint16_encode(run_time, encoded_session_run_time); // (p_sst, encoded_start_session_time); + + memset(&srt_val, 0, sizeof(ble_gatts_value_t)); + srt_val.len = gatts_value_set_len; + srt_val.p_value = encoded_session_run_time; + srt_val.offset = 0; + + return (sd_ble_gatts_value_set(p_cgms->conn_handle, p_cgms->char_handles.srt.value_handle, + &srt_val)); +} + + diff --git a/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h b/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h new file mode 100644 index 0000000..7a835a8 --- /dev/null +++ b/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h @@ -0,0 +1,436 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_cgms Continuous Glucose Monitoring Service + * @{ + * @ingroup ble_sdk_srv + * @brief Continuous Glucose Monitoring Service (CGMS) module. + * + * @details This module implements a sensor for the Continuous Glucose Monitoring Service. + * The sensor is a GATT Server that sends CGM measurements to a connected CGMS + * Collector. The CGMS Sensor stores records that can be accessed with the + * Record Access Control Point (RACP). The collector can access the features and status + * of the sensor. Session Run Time and Session Start Time can be used to convey timing + * information between the sensor and the collector. The Specific Operations Control Point + * is used to stop and start monitoring sessions, among other things. + * + * @note The application must propagate BLE stack events to the Continuous Glucose Monitoring + * Service module by calling @ref nrf_ble_cgms_on_ble_evt() from the + * @ref softdevice_handler callback. + */ + +#ifndef NRF_BLE_CGMS_H__ +#define NRF_BLE_CGMS_H__ + +#include "ble_srv_common.h" +#include "sdk_errors.h" +#include "ble_racp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@name CGM Feature characteristic defines + * @{ */ +#define NRF_BLE_CGMS_FEAT_CALIBRATION_SUPPORTED (0x01 << 0) //!< Calibration supported. +#define NRF_BLE_CGMS_FEAT_PATIENT_HIGH_LOW_ALERTS_SUPPORTED (0x01 << 1) //!< Patient High/Low Alerts supported. +#define NRF_BLE_CGMS_FEAT_HYPO_ALERTS_SUPPORTED (0x01 << 2) //!< Hypo Alerts supported. +#define NRF_BLE_CGMS_FEAT_HYPER_ALERTS_SUPPORTED (0x01 << 3) //!< Hyper Alerts supported. +#define NRF_BLE_CGMS_FEAT_RATE_OF_INCREASE_DECREASE_ALERTS_SUPPORTED (0x01 << 4) //!< Rate of Increase/Decrease Alerts supported. +#define NRF_BLE_CGMS_FEAT_DEVICE_SPECIFIC_ALERT_SUPPORTED (0x01 << 5) //!< Device Specific Alert supported. +#define NRF_BLE_CGMS_FEAT_SENSOR_MALFUNCTION_DETECTION_SUPPORTED (0x01 << 6) //!< Sensor Malfunction Detection supported. +#define NRF_BLE_CGMS_FEAT_SENSOR_TEMPERATURE_HIGH_LOW_DETECTION_SUPPORTED (0x01 << 7) //!< Sensor Temperature High-Low Detection supported. +#define NRF_BLE_CGMS_FEAT_SENSOR_RESULT_HIGH_LOW_DETECTION_SUPPORTED (0x01 << 8) //!< Sensor Result High-Low Detection supported. +#define NRF_BLE_CGMS_FEAT_LOW_BATTERY_DETECTION_SUPPORTED (0x01 << 9) //!< Low Battery Detection supported. +#define NRF_BLE_CGMS_FEAT_SENSOR_TYPE_ERROR_DETECTION_SUPPORTED (0x01 << 10) //!< Sensor Type Error Detection supported. +#define NRF_BLE_CGMS_FEAT_GENERAL_DEVICE_FAULT_SUPPORTED (0x01 << 11) //!< General Device Fault supported. +#define NRF_BLE_CGMS_FEAT_E2E_CRC_SUPPORTED (0x01 << 12) //!< E2E-CRC supported. +#define NRF_BLE_CGMS_FEAT_MULTIPLE_BOND_SUPPORTED (0x01 << 13) //!< Multiple Bond supported. +#define NRF_BLE_CGMS_FEAT_MULTIPLE_SESSIONS_SUPPORTED (0x01 << 14) //!< Multiple Sessions supported. +#define NRF_BLE_CGMS_FEAT_CGM_TREND_INFORMATION_SUPPORTED (0x01 << 15) //!< CGM Trend Information supported. +#define NRF_BLE_CGMS_FEAT_CGM_QUALITY_SUPPORTED (0x01 << 16) //!< CGM Quality supported. +/** @} */ + +/**@name Continuous Glucose Monitoring type + * @{ */ +#define NRF_BLE_CGMS_MEAS_TYPE_CAP_BLOOD 0x01 //!< Capillary Whole blood. +#define NRF_BLE_CGMS_MEAS_TYPE_CAP_PLASMA 0x02 //!< Capillary Plasma. +#define NRF_BLE_CGMS_MEAS_TYPE_VEN_BLOOD 0x03 //!< Venous Whole blood. +#define NRF_BLE_CGMS_MEAS_TYPE_VEN_PLASMA 0x04 //!< Venous Plasma. +#define NRF_BLE_CGMS_MEAS_TYPE_ART_BLOOD 0x05 //!< Arterial Whole blood. +#define NRF_BLE_CGMS_MEAS_TYPE_ART_PLASMA 0x06 //!< Arterial Plasma. +#define NRF_BLE_CGMS_MEAS_TYPE_UNDET_BLOOD 0x07 //!< Undetermined Whole blood. +#define NRF_BLE_CGMS_MEAS_TYPE_UNDET_PLASMA 0x08 //!< Undetermined Plasma. +#define NRF_BLE_CGMS_MEAS_TYPE_FLUID 0x09 //!< Interstitial Fluid (ISF). +#define NRF_BLE_CGMS_MEAS_TYPE_CONTROL 0x0A //!< Control Solution. +/** @} */ + +/**@name CGM sample location + * @{ */ +#define NRF_BLE_CGMS_MEAS_LOC_FINGER 0x01 //!< Finger. +#define NRF_BLE_CGMS_MEAS_LOC_AST 0x02 //!< Alternate Site Test (AST). +#define NRF_BLE_CGMS_MEAS_LOC_EAR 0x03 //!< Earlobe. +#define NRF_BLE_CGMS_MEAS_LOC_CONTROL 0x04 //!< Control solution. +#define NRF_BLE_CGMS_MEAS_LOC_SUB_TISSUE 0x05 //!< Subcutaneous tissue. +#define NRF_BLE_CGMS_MEAS_LOC_NOT_AVAIL 0x0F //!< Sample Location value not available. +/** @} */ + +/**@name CGM Measurement Sensor Status Annunciation + * @{ */ +#define NRF_BLE_CGMS_STATUS_SESSION_STOPPED (0x01 << 0) //!< Status: Session Stopped. +#define NRF_BLE_CGMS_STATUS_DEVICE_BATTERY_LOW (0x01 << 1) //!< Status: Device Battery Low. +#define NRF_BLE_CGMS_STATUS_SENSOR_TYPE_INCORRECT_FOR_DEVICE (0x01 << 2) //!< Status: Sensor type incorrect for device. +#define NRF_BLE_CGMS_STATUS_SENSOR_MALFUNCTION (0x01 << 3) //!< Status: Sensor malfunction. +#define NRF_BLE_CGMS_STATUS_DEVICE_SPECIFIC_ALERT (0x01 << 4) //!< Status: Device Specific Alert. +#define NRF_BLE_CGMS_STATUS_GENERAL_DEVICE_FAULT (0x01 << 5) //!< Status: General device fault has occurred in the sensor. +/** @} */ + +/**@name CGM Measurement flags + * @{ */ +#define NRF_BLE_CGMS_FLAG_TREND_INFO_PRESENT 0x01 //!< CGM Trend Information Present. +#define NRF_BLE_CGMS_FLAGS_QUALITY_PRESENT 0x02 //!< CGM Quality Present. +#define NRF_BLE_CGMS_STATUS_FLAGS_WARNING_OCT_PRESENT 0x20 //!< Sensor Status Annunciation Field, Warning-Octet present. +#define NRF_BLE_CGMS_STATUS_FLAGS_CALTEMP_OCT_PRESENT 0x40 //!< Sensor Status Annunciation Field, Cal/Temp-Octet present. +#define NRF_BLE_CGMS_STATUS_FLAGS_STATUS_OCT_PRESENT 0x80 //!< Sensor Status Annunciation Field, Status-Octet present. +/** @} */ + +/**@name Byte length of various commands (used for validating, encoding, and decoding data). + * @{ */ +#define NRF_BLE_CGMS_MEAS_OP_LEN 1 //!< Length of the opcode inside the Glucose Measurement packet. +#define NRF_BLE_CGMS_MEAS_HANDLE_LEN 2 //!< Length of the handle inside the Glucose Measurement packet. +#define NRF_BLE_CGMS_MEAS_LEN_MAX (BLE_L2CAP_MTU_DEF - \ + NRF_BLE_CGMS_MEAS_OP_LEN - \ + NRF_BLE_CGMS_MEAS_HANDLE_LEN) //!< Maximum size of a transmitted Glucose Measurement. + +#define NRF_BLE_CGMS_MEAS_REC_LEN_MAX 15 //!< Maximum length of one measurement record. Size 1 byte, flags 1 byte, glucose concentration 2 bytes, offset 2 bytes, status 3 bytes, trend 2 bytes, quality 2 bytes, CRC 2 bytes. +#define NRF_BLE_CGMS_MEAS_REC_LEN_MIN 6 //!< Minimum length of one measurement record. Size 1 byte, flags 1 byte, glucose concentration 2 bytes, offset 2 bytes. +#define NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX (NRF_BLE_CGMS_MEAS_LEN_MAX / \ + NRF_BLE_CGMS_MEAS_REC_LEN_MIN) //!< Maximum number of records per notification. We can send more than one measurement record per notification, but we do not want a a single record split over two notifications. + +#define NRF_BLE_CGMS_SOCP_RESP_CODE_LEN 2 //!< Length of a response. Response code 1 byte, response value 1 byte. +#define NRF_BLE_CGMS_FEATURE_LEN 6 //!< Length of a feature. Feature 3 bytes, type 4 bits, sample location 4 bits, CRC 2 bytes. +#define NRF_BLE_CGMS_STATUS_LEN 7 //!< Length of a status. Offset 2 bytes, status 3 bytes, CRC 2 bytes. +#define NRF_BLE_CGMS_MAX_CALIB_LEN 10 //!< Length of a calibration record. Concentration 2 bytes, time 2 bytes, calibration 4 bits, calibration sample location 4 bits, next calibration time 2 bytes, record number 2 bytes, calibration status 1 byte. +#define NRF_BLE_CGMS_CALIBS_NB_MAX 5 //!< Maximum number of calibration values that can be stored. +#define NRF_BLE_CGMS_SST_LEN 9 //!< Length of the start time. Date time 7 bytes, time zone 1 byte, DST 1 byte. +#define NRF_BLE_CGMS_CRC_LEN 2 //!< Length of the CRC bytes (if used). +#define NRF_BLE_CGMS_SRT_LEN 2 //!< Length of the Session Run Time attribute. + +#define NRF_BLE_CGMS_SOCP_RESP_LEN (NRF_BLE_CGMS_MEAS_LEN_MAX - \ + NRF_BLE_CGMS_SOCP_RESP_CODE_LEN) //!< Max lenth of a SOCP response. + +#define NRF_BLE_CGMS_RACP_PENDING_OPERANDS_MAX 2 // !< Maximum number of pending Record Access Control Point operations. +/** @} */ + +/** + * @defgroup nrf_ble_cgms_enums Enumerations + * @{ + */ + +/**@brief CGM Service events. */ +typedef enum +{ + NRF_BLE_CGMS_EVT_NOTIFICATION_ENABLED, /**< Glucose value notification enabled. */ + NRF_BLE_CGMS_EVT_NOTIFICATION_DISABLED, /**< Glucose value notification disabled. */ + NRF_BLE_CGMS_EVT_START_SESSION, /**< Glucose value notification start session. */ + NRF_BLE_CGMS_EVT_STOP_SESSION, /**< Glucose value notification stop session. */ + NRF_BLE_CGMS_EVT_WRITE_COMM_INTERVAL, /**< Glucose value write communication interval. */ +} nrf_ble_cgms_evt_type_t; + + +/**@brief CGM Service communication states. */ +typedef enum +{ + STATE_NO_COMM, /**< The service is not in a communicating state. */ + STATE_RACP_PROC_ACTIVE, /**< Processing requested data. */ + STATE_RACP_RESPONSE_PENDING, /**< There is an RACP indication waiting to be sent. */ + STATE_RACP_RESPONSE_IND_VERIF, /**< Waiting for a verification of an RACP indication. */ + STATE_SOCP_RESPONSE_PENDING, /**< There is an SOCP indication waiting to be sent. */ + STATE_SOCP_RESPONSE_IND_VERIF /**< Waiting for a verification of an SOCP indication. */ +} nrf_ble_cgms_com_state_t; + +/** @} */ // End tag for Enumeration group. + +/** + * @defgroup nrf_ble_cgms_structs Structures + * @{ + */ + +/**@brief CGM Service event. */ +typedef struct +{ + nrf_ble_cgms_evt_type_t evt_type; /**< Type of event. */ +} nrf_ble_cgms_evt_t; + +/** @} */ // End tag for Structure group. + +/** + * @defgroup nrf_ble_cgms_types Types + * @{ + */ + +/**@brief Forward declaration of the nrf_ble_cgms_t type. */ +typedef struct ble_cgms_s nrf_ble_cgms_t; + + +/**@brief CGM Service event handler type. */ +typedef void (* ble_cgms_evt_handler_t) (nrf_ble_cgms_t * p_cgms, nrf_ble_cgms_evt_t * p_evt); + +/** @} */ // End tag for Types group. + +/** + * @addtogroup nrf_ble_cgms_structs + * @{ + */ + +/**@brief CGM Measurement Sensor Status Annunciation. */ +typedef struct +{ + uint8_t warning; /**< Warning annunciation. */ + uint8_t calib_temp; /**< Calibration and Temperature annunciation. */ + uint8_t status; /**< Status annunciation. */ +} nrf_ble_cgms_sensor_annunc_t; + + +/**@brief CGM measurement. */ +typedef struct +{ + uint8_t flags; /**< Indicates the presence of optional fields and the Sensor Status Annunciation field. */ + uint16_t glucose_concentration; /**< Glucose concentration. 16-bit word comprising 4-bit exponent and signed 12-bit mantissa. */ + uint16_t time_offset; /**< Time offset. Represents the time difference between measurements. */ + nrf_ble_cgms_sensor_annunc_t sensor_status_annunciation; /**< Sensor Status Annunciation. Variable length, can include Status, Cal/Temp, and Warning. */ + uint16_t trend; /**< Optional field that can include Trend Information. */ + uint16_t quality; /**< Optional field that includes the Quality of the measurement. */ +} nrf_ble_cgms_meas_t; + + +/**@brief CGM Measurement record. */ +typedef struct +{ + nrf_ble_cgms_meas_t meas; /**< CGM measurement. */ +} ble_cgms_rec_t; + + +/**@brief Features supported by the CGM Service. */ +typedef struct +{ + uint32_t feature; /**< Information on supported features in the CGM Service. */ + uint8_t type; /**< Type. */ + uint8_t sample_location; /**< Sample location. */ +}nrf_ble_cgms_feature_t; + + +/**@brief Status of the CGM measurement. */ +typedef struct +{ + uint16_t time_offset; /**< Time offset. */ + nrf_ble_cgms_sensor_annunc_t status; /**< Status. */ +} nrf_ble_cgm_status_t; + + +/**@brief CGM Service initialization structure that contains all options and data needed for + * initializing the service. */ +typedef struct +{ + ble_cgms_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the CGM Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called when an error occurs. */ + nrf_ble_cgms_feature_t feature; /**< Features supported by the service. */ + nrf_ble_cgm_status_t initial_sensor_status; /**< Sensor status. */ + uint16_t initial_run_time; /**< Run time. */ +} nrf_ble_cgms_init_t; + + +/**@brief Specific Operation Control Point response structure. */ +typedef struct +{ + uint8_t opcode; /**< Opcode describing the response. */ + uint8_t req_opcode; /**< The original opcode for the request to which this response belongs. */ + uint8_t rsp_code; /**< Response code. */ + uint8_t resp_val[NRF_BLE_CGMS_SOCP_RESP_LEN]; /**< Array containing the response value. */ + uint8_t size_val; /**< Length of the response value. */ +} ble_socp_rsp_t; + + +/**@brief Calibration value. */ +typedef struct +{ + uint8_t value[NRF_BLE_CGMS_MAX_CALIB_LEN]; /**< Array containing the calibration value. */ +} nrf_ble_cgms_calib_t; + + +/**@brief Record Access Control Point transaction data. */ +typedef struct +{ + uint8_t racp_proc_operator; /**< Operator of the current request. */ + uint8_t racp_proc_record_ndx; /**< Current record index. */ + uint8_t racp_proc_records_reported; /**< Number of reported records. */ + uint8_t racp_proc_records_reported_since_txcomplete; /**< Number of reported records since the last TX_COMPLETE event. */ + ble_racp_value_t racp_request; + ble_racp_value_t pending_racp_response; /**< RACP response to be sent. */ + uint8_t pending_racp_response_operand[NRF_BLE_CGMS_RACP_PENDING_OPERANDS_MAX]; /**< Operand of the RACP response to be sent. */ +} nrf_ble_cgms_racp_t; + + +/** @brief Handles related to CGM characteristics. */ +typedef struct +{ + ble_gatts_char_handles_t measurment; /**< Handles related to the CGM Measurement characteristic. */ + ble_gatts_char_handles_t feature; /**< Handles related to the CGM Feature characteristic. */ + ble_gatts_char_handles_t sst; /**< Handles related to the CGM Session Start Time characteristic. */ + ble_gatts_char_handles_t racp; /**< Handles related to the CGM Record Access Control Point characteristic. */ + ble_gatts_char_handles_t srt; /**< Handles related to the CGM Session Run Time characteristic. */ + ble_gatts_char_handles_t socp; /**< Handles related to the CGM Specific Operations Control Point characteristic. */ + ble_gatts_char_handles_t status; /**< Handles related to the CGM Status characteristic. */ +} nrf_ble_cgms_char_handler_t; + + +/**@brief Status information for the CGM Service. */ +struct ble_cgms_s +{ + ble_cgms_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the CGM Service. */ + ble_srv_error_handler_t error_handler; /**< Function to be called if an error occurs. */ + uint16_t service_handle; /**< Handle of the CGM Service (as provided by the BLE stack). */ + nrf_ble_cgms_char_handler_t char_handles; /**< GATTS characteristic handles for the different characteristics in the service. */ + uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack; @ref BLE_CONN_HANDLE_INVALID if not in a connection). */ + nrf_ble_cgms_feature_t feature; /**< Structure to store the value of the feature characteristic. */ + uint8_t comm_interval; /**< Variable to keep track of the communication interval. */ + ble_socp_rsp_t socp_response; /**< Structure containing reponse data to be indicated to the peer device. */ + nrf_ble_cgms_calib_t calibration_val[NRF_BLE_CGMS_CALIBS_NB_MAX]; /**< Calibration value. Can be read from and written to SOCP. */ + bool is_session_started; /**< Indicator if we are currently in a session. */ + uint8_t nb_run_session; /**< Variable to keep track of the number of sessions that were run. */ + uint16_t session_run_time; /**< Variable to store the expected run time of a session. */ + nrf_ble_cgm_status_t sensor_status; /**< Structure to keep track of the sensor status. */ + nrf_ble_cgms_com_state_t cgms_com_state; /**< Current communication state. */ + nrf_ble_cgms_racp_t racp_data; /**< Structure to manage Record Access requests. */ +}; + +/** @} */ + +/** + * @defgroup nrf_ble_cgms_functions Functions + * @{ + */ + +/**@brief Function for updating the status. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_status New status. + * + * @retval NRF_SUCCESS If the status was updated successfully. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t nrf_ble_cgms_update_status(nrf_ble_cgms_t * p_cgms, nrf_ble_cgm_status_t * p_status); + + +/**@brief Function for initializing the CGM Service. + * + * @param[out] p_cgms CGM Service structure. This structure must be supplied by + * the application. It is initialized by this function and will later + * be used to identify this particular service instance. + * @param[in] p_cgms_init Information needed to initialize the service. + * + * @retval NRF_SUCCESS If the service was initialized successfully. + * @retval NRF_ERROR_NULL If any of the input parameters are NULL. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t nrf_ble_cgms_init(nrf_ble_cgms_t * p_cgms, const nrf_ble_cgms_init_t * p_cgms_init); + + +/**@brief Function for handling the application's BLE stack events. + * + * @details Handles all events from the BLE stack that are of interest to the CGM Service. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void nrf_ble_cgms_on_ble_evt(nrf_ble_cgms_t * p_cgms, ble_evt_t * p_ble_evt); + + +/**@brief Function for reporting a new glucose measurement to the CGM Service module. + * + * @details The application calls this function after having performed a new glucose measurement. + * The new measurement is recorded in the RACP database. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] p_rec Pointer to the glucose record (measurement plus context). + * + * @retval NRF_SUCCESS If a measurement was successfully created. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t nrf_ble_cgms_meas_create(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec); + + +/**@brief Function for assigning a connection handle to a CGM Service instance. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] conn_handle Connection Handle to use for this instance of the CGM Service. + * + * @retval NRF_SUCCESS If the connection handle was successfully stored in the CGM Service instance. + * @retval NRF_ERROR_NULL If any of the input parameters are NULL. + */ +ret_code_t nrf_ble_cgms_conn_handle_assign(nrf_ble_cgms_t * p_cgms, uint16_t conn_handle); + + +/**@brief Function for setting the Session Run Time attribute value. + * + * @param[in] p_cgms Instance of the CGM Service. + * @param[in] run_time Run Time that will be displayed in the Session Run Time + * attribute value. + * + * @retval NRF_SUCCESS If the Session Run Time attribute value was set successfully. + * @return If functions from other modules return errors to this function, + * the @ref nrf_error are propagated. + */ +ret_code_t nrf_ble_cgms_srt_set(nrf_ble_cgms_t * p_cgms, uint16_t run_time); + +/** @} */ // End tag for Function group. + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_CGMS_H__ + +/** @} */ diff --git a/components/ble/common/ble_advdata.c b/components/ble/common/ble_advdata.c index aef7f72..93be633 100644 --- a/components/ble/common/ble_advdata.c +++ b/components/ble/common/ble_advdata.c @@ -1,21 +1,47 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_advdata.h" -#include "nordic_common.h" -#include "nrf_error.h" #include "ble_gap.h" #include "ble_srv_common.h" -#include "app_util.h" +#include "sdk_common.h" // NOTE: For now, Security Manager Out of Band Flags (OOB) are omitted from the advertising data. @@ -23,71 +49,6 @@ #define AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC 0UL #define AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM 1UL -static uint32_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value, - uint8_t * p_encoded_data, - uint16_t * p_offset, - uint16_t max_size) -{ - int8_t i; - - // Check for buffer overflow. - if (((*p_offset) + AD_TYPE_TK_VALUE_SIZE) > max_size) - { - return NRF_ERROR_DATA_SIZE; - } - - // Encode LE Role. - p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE); - *p_offset += ADV_LENGTH_FIELD_SIZE; - p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE; - *p_offset += ADV_AD_TYPE_FIELD_SIZE; - - for (i = AD_TYPE_TK_VALUE_DATA_SIZE - 1; i >= 0; i--, (*p_offset)++) - { - p_encoded_data[*p_offset] = p_tk_value->tk[i]; - } - - return NRF_SUCCESS; -} - -static uint32_t le_role_encode(ble_advdata_le_role_t le_role, - uint8_t * p_encoded_data, - uint16_t * p_offset, - uint16_t max_size) -{ - // Check for buffer overflow. - if (((*p_offset) + AD_TYPE_LE_ROLE_SIZE) > max_size) - { - return NRF_ERROR_DATA_SIZE; - } - - // Encode LE Role. - p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE); - *p_offset += ADV_LENGTH_FIELD_SIZE; - p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_ROLE; - *p_offset += ADV_AD_TYPE_FIELD_SIZE; - switch(le_role) - { - case BLE_ADVDATA_ROLE_ONLY_PERIPH: - p_encoded_data[*p_offset] = 0; - break; - case BLE_ADVDATA_ROLE_ONLY_CENTRAL: - p_encoded_data[*p_offset] = 1; - break; - case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED: - p_encoded_data[*p_offset] = 2; - break; - case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED: - p_encoded_data[*p_offset] = 3; - break; - default: - return NRF_ERROR_INVALID_PARAM; - } - *p_offset += AD_TYPE_LE_ROLE_DATA_SIZE; - - return NRF_SUCCESS; -} - static uint32_t ble_device_addr_encode(uint8_t * p_encoded_data, uint16_t * p_offset, uint16_t max_size) @@ -101,14 +62,15 @@ static uint32_t ble_device_addr_encode(uint8_t * p_encoded_data, return NRF_ERROR_DATA_SIZE; } - // Get BLE address - err_code = sd_ble_gap_address_get(&device_addr); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + // Get BLE address. + #if (NRF_SD_BLE_API_VERSION == 3) + err_code = sd_ble_gap_addr_get(&device_addr); + #else + err_code = sd_ble_gap_address_get(&device_addr); + #endif + VERIFY_SUCCESS(err_code); - // Encode LE Bluetooth Device Address + // Encode LE Bluetooth Device Address. p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE); *p_offset += ADV_LENGTH_FIELD_SIZE; @@ -116,7 +78,7 @@ static uint32_t ble_device_addr_encode(uint8_t * p_encoded_data, *p_offset += ADV_AD_TYPE_FIELD_SIZE; memcpy(&p_encoded_data[*p_offset], &device_addr.addr[0], BLE_GAP_ADDR_LEN); *p_offset += BLE_GAP_ADDR_LEN; - if(BLE_GAP_ADDR_TYPE_PUBLIC == device_addr.addr_type) + if (BLE_GAP_ADDR_TYPE_PUBLIC == device_addr.addr_type) { p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC; } @@ -141,7 +103,7 @@ static uint32_t name_encode(const ble_advdata_t * p_advdata, // Validate parameters - if((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && (0 == p_advdata->short_name_len)) + if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && (0 == p_advdata->short_name_len)) { return NRF_ERROR_INVALID_PARAM; } @@ -160,11 +122,8 @@ static uint32_t name_encode(const ble_advdata_t * p_advdata, // Get GAP device name and length err_code = sd_ble_gap_device_name_get(&p_encoded_data[(*p_offset) + ADV_AD_DATA_OFFSET], &actual_length); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - + VERIFY_SUCCESS(err_code); + // Check if device intend to use short name and it can fit available data size. if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len)) { @@ -192,7 +151,7 @@ static uint32_t name_encode(const ble_advdata_t * p_advdata, } // There is only 1 byte intended to encode length which is (actual_length + ADV_AD_TYPE_FIELD_SIZE) - if(actual_length > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) + if (actual_length > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) { return NRF_ERROR_DATA_SIZE; } @@ -223,10 +182,7 @@ static uint32_t appearance_encode(uint8_t * p_encoded_data, // Get GAP appearance field. err_code = sd_ble_gap_appearance_get(&appearance); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Encode Length, AD Type and Appearance. p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_APPEARANCE_DATA_SIZE); @@ -260,28 +216,6 @@ static uint32_t flags_encode(int8_t flags, return NRF_SUCCESS; } -static uint32_t sec_mgr_oob_flags_encode(uint8_t oob_flags, - uint8_t * p_encoded_data, - uint16_t * p_offset, - uint16_t max_size) -{ - // Check for buffer overflow. - if (((*p_offset) + AD_TYPE_OOB_FLAGS_SIZE) > max_size) - { - return NRF_ERROR_DATA_SIZE; - } - - // Encode flags. - p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE); - *p_offset += ADV_LENGTH_FIELD_SIZE; - p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS; - *p_offset += ADV_AD_TYPE_FIELD_SIZE; - p_encoded_data[*p_offset] = oob_flags; - *p_offset += AD_TYPE_OOB_FLAGS_DATA_SIZE; - - return NRF_SUCCESS; -} - static uint32_t tx_power_level_encode(int8_t tx_power_level, uint8_t * p_encoded_data, uint16_t * p_offset, @@ -323,19 +257,16 @@ static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_li uint32_t err_code; uint8_t encoded_size; ble_uuid_t uuid = p_uuid_list->p_uuids[i]; - + // Find encoded uuid size. err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Check size. if (encoded_size == uuid_size) { uint8_t heading_bytes = (is_heading_written) ? 0 : ADV_AD_DATA_OFFSET; - + // Check for buffer overflow if (((*p_offset) + encoded_size + heading_bytes) > max_size) { @@ -353,10 +284,7 @@ static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_li // Write UUID. err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_offset]); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); *p_offset += encoded_size; } } @@ -366,7 +294,7 @@ static uint32_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_li // Write length. length = (*p_offset) - (start_pos + ADV_LENGTH_FIELD_SIZE); // There is only 1 byte intended to encode length - if(length > 0x00FF) + if (length > 0x00FF) { return NRF_ERROR_DATA_SIZE; } @@ -393,10 +321,7 @@ static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list, p_encoded_data, p_offset, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Encode 128 bit UUIDs. err_code = uuid_list_sized_encode(p_uuid_list, @@ -405,10 +330,7 @@ static uint32_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list, p_encoded_data, p_offset, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); return NRF_SUCCESS; } @@ -428,9 +350,9 @@ static uint32_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int) } // Check Maximum Connection Interval. - if ((p_conn_int->max_conn_interval < 0x0006) || + if ((p_conn_int->max_conn_interval < 0x0006) || ( - (p_conn_int->max_conn_interval > 0x0c80) && + (p_conn_int->max_conn_interval > 0x0c80) && (p_conn_int->max_conn_interval != 0xffff) ) ) @@ -466,10 +388,7 @@ static uint32_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int, // Check parameters. err_code = conn_int_check(p_conn_int); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); // Encode Length and AD Type. p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_CONN_INT_DATA_SIZE); @@ -499,7 +418,7 @@ static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_ma } // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE) - if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) + if (data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) { return NRF_ERROR_DATA_SIZE; } @@ -509,10 +428,10 @@ static uint32_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_ma *p_offset += ADV_LENGTH_FIELD_SIZE; p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA; *p_offset += ADV_AD_TYPE_FIELD_SIZE; - + // Encode Company Identifier. *p_offset += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_offset]); - + // Encode additional manufacturer specific data. if (p_manuf_sp_data->data.size > 0) { @@ -551,7 +470,7 @@ static uint32_t service_data_encode(const ble_advdata_t * p_advdata, data_size = AD_TYPE_SERV_DATA_16BIT_UUID_SIZE + p_service_data->data.size; // There is only 1 byte intended to encode length which is (data_size + ADV_AD_TYPE_FIELD_SIZE) - if(data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) + if (data_size > (0x00FF - ADV_AD_TYPE_FIELD_SIZE)) { return NRF_ERROR_DATA_SIZE; } @@ -588,68 +507,26 @@ uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, uint16_t max_size = *p_len; *p_len = 0; - //Encode Security Manager OOB Flags - if (p_advdata->p_sec_mgr_oob_flags != NULL) - { - err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags, - p_encoded_data, - p_len, - max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - } - - // Encode Security Manager TK value - if (NULL != p_advdata->p_tk_value) - { - err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - } - - // Encode LE Role - if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role) - { - err_code = le_role_encode(p_advdata->le_role, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - } - // Encode LE Bluetooth Device Address if (p_advdata->include_ble_device_addr) { err_code = ble_device_addr_encode(p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } // Encode appearance. if (p_advdata->include_appearance) { err_code = appearance_encode(p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } //Encode Flags - if(p_advdata->flags != 0 ) + if (p_advdata->flags != 0 ) { err_code = flags_encode(p_advdata->flags, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - } + VERIFY_SUCCESS(err_code); + } // Encode TX power level. if (p_advdata->p_tx_power_level != NULL) @@ -658,12 +535,9 @@ uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } - + // Encode 'more available' uuid list. if (p_advdata->uuids_more_available.uuid_cnt > 0) { @@ -673,10 +547,7 @@ uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } // Encode 'complete' uuid list. @@ -688,10 +559,7 @@ uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } // Encode 'solicited service' uuid list. @@ -703,20 +571,14 @@ uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } // Encode Slave Connection Interval Range. if (p_advdata->p_slave_conn_int != NULL) { err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } // Encode Manufacturer Specific Data. @@ -726,30 +588,21 @@ uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } // Encode Service Data. if (p_advdata->service_data_count > 0) { err_code = service_data_encode(p_advdata, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } // Encode name. WARNING: it is encoded last on purpose since too long device name is truncated. if (p_advdata->name_type != BLE_ADVDATA_NO_NAME) { err_code = name_encode(p_advdata, p_encoded_data, p_len, max_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } return err_code; @@ -796,16 +649,10 @@ uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * if (p_advdata != NULL) { err_code = advdata_check(p_advdata); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); err_code = adv_data_encode(p_advdata, encoded_advdata, &len_advdata); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); p_encoded_advdata = encoded_advdata; } else @@ -818,16 +665,10 @@ uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * if (p_srdata != NULL) { err_code = srdata_check(p_srdata); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); err_code = adv_data_encode(p_srdata, encoded_srdata, &len_srdata); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); p_encoded_srdata = encoded_srdata; } else diff --git a/components/ble/common/ble_advdata.h b/components/ble/common/ble_advdata.h index ef34b9d..ae6037b 100644 --- a/components/ble/common/ble_advdata.h +++ b/components/ble/common/ble_advdata.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -28,17 +56,15 @@ #include "ble.h" #include "app_util.h" +#ifdef __cplusplus +extern "C" { +#endif + #define ADV_LENGTH_FIELD_SIZE 1UL /**< Advertising Data and Scan Response format contains 1 octet for the length. */ #define ADV_AD_TYPE_FIELD_SIZE 1UL /**< Advertising Data and Scan Response format contains 1 octet for the AD type. */ #define ADV_AD_DATA_OFFSET (ADV_LENGTH_FIELD_SIZE + \ ADV_AD_TYPE_FIELD_SIZE) /**< Offset for the AD data field of the Advertising Data and Scan Response format. */ -#define AD_TYPE_TK_VALUE_DATA_SIZE (sizeof(ble_advdata_tk_value_t)) /**< Data size (in octets) of the Security Manager TK value AD type. */ -#define AD_TYPE_TK_VALUE_SIZE (ADV_AD_DATA_OFFSET + \ - AD_TYPE_TK_VALUE_DATA_SIZE) /**< Size (in octets) of the Security Manager TK value AD type. */ -#define AD_TYPE_LE_ROLE_DATA_SIZE 1UL /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */ -#define AD_TYPE_LE_ROLE_SIZE (ADV_AD_DATA_OFFSET + \ - AD_TYPE_LE_ROLE_DATA_SIZE) /**< Size (in octets) of the LE Bluetooth Device Address AD type. */ #define AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE 1UL /**< Data size (in octets) of the Address type of the LE Bluetooth Device Address AD type. */ #define AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE (BLE_GAP_ADDR_LEN + \ AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE) /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */ @@ -58,19 +84,6 @@ AD_TYPE_CONN_INT_DATA_SIZE) /**< Data size (in octets) of the Slave Connection Interval Range AD type. */ #define AD_TYPE_MANUF_SPEC_DATA_ID_SIZE 2UL /**< Size (in octets) of the Company Identifier Code, which is a part of the Manufacturer Specific Data AD type. */ #define AD_TYPE_SERV_DATA_16BIT_UUID_SIZE 2UL /**< Size (in octets) of the 16-bit UUID, which is a part of the Service Data AD type. */ -#define AD_TYPE_OOB_FLAGS_DATA_SIZE 1UL /**< Data size (in octets) of the Security Manager OOB Flags AD type. */ -#define AD_TYPE_OOB_FLAGS_SIZE (ADV_AD_DATA_OFFSET + \ - AD_TYPE_OOB_FLAGS_DATA_SIZE) /**< Size (in octets) of the Security Manager OOB Flags AD type. */ - -#define AD_TYPE_SEC_MGR_OOB_FLAG_SET 1U /**< Security Manager OOB Flag set. Flag selection is done using _POS defines */ -#define AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR 0U /**< Security Manager OOB Flag clear. Flag selection is done using _POS defines */ -#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS 0UL /**< Security Manager OOB Data Present Flag position. */ -#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS 1UL /**< Security Manager OOB Low Energy Supported Flag position. */ -#define AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS 2UL /**< Security Manager OOB Simultaneous LE and BR/EDR to Same Device Capable Flag position. */ -#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_PUBLIC 0UL /**< Security Manager OOB Public Address type. */ -#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM 1UL /**< Security Manager OOB Random Address type. */ -#define AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS 3UL /**< Security Manager OOB Address type Flag (0 = Public Address, 1 = Random Address) position. */ - /**@brief Security Manager TK value. */ typedef struct @@ -143,9 +156,10 @@ typedef struct ble_advdata_service_data_t * p_service_data_array; /**< Array of Service data structures. */ uint8_t service_data_count; /**< Number of Service data structures. */ bool include_ble_device_addr; /**< Determines if LE Bluetooth Device Address shall be included. */ - ble_advdata_le_role_t le_role; /**< LE Role field. Included when different from @ref BLE_ADVDATA_ROLE_NOT_PRESENT.*/ - ble_advdata_tk_value_t * p_tk_value; /**< Security Manager TK value field. Included when different from NULL.*/ - uint8_t * p_sec_mgr_oob_flags; /**< Security Manager Out Of Band Flags field. Included when different from NULL.*/ + ble_advdata_le_role_t le_role; /**< LE Role field. Included when different from @ref BLE_ADVDATA_ROLE_NOT_PRESENT. @warning This field can be used only for NFC. For BLE advertising, set it to NULL. */ + ble_advdata_tk_value_t * p_tk_value; /**< Security Manager TK value field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/ + uint8_t * p_sec_mgr_oob_flags; /**< Security Manager Out Of Band Flags field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/ + ble_gap_lesc_oob_data_t * p_lesc_data; /**< LE Secure Connections OOB data. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/ } ble_advdata_t; /**@brief Function for encoding data in the Advertising and Scan Response data format @@ -207,6 +221,11 @@ uint32_t adv_data_encode(ble_advdata_t const * const p_advdata, */ uint32_t ble_advdata_set(const ble_advdata_t * p_advdata, const ble_advdata_t * p_srdata); + +#ifdef __cplusplus +} +#endif + #endif // BLE_ADVDATA_H__ /** @} */ diff --git a/components/ble/common/ble_conn_params.c b/components/ble/common/ble_conn_params.c index ddc1ba9..1a03d6e 100644 --- a/components/ble/common/ble_conn_params.c +++ b/components/ble/common/ble_conn_params.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_conn_params.h" @@ -35,7 +63,7 @@ static bool is_conn_params_ok(ble_gap_conn_params_t * p_conn_params) // the client's connection interval. if ( (p_conn_params->max_conn_interval >= m_preferred_conn_params.min_conn_interval) - && + && (p_conn_params->max_conn_interval <= m_preferred_conn_params.max_conn_interval) ) { diff --git a/components/ble/common/ble_conn_params.h b/components/ble/common/ble_conn_params.h index 9983573..1d0952f 100644 --- a/components/ble/common/ble_conn_params.h +++ b/components/ble/common/ble_conn_params.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -25,6 +53,10 @@ #include "ble.h" #include "ble_srv_common.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Connection Parameters Module event type. */ typedef enum { @@ -58,7 +90,7 @@ typedef struct /**@brief Function for initializing the Connection Parameters module. * - * @note If the negotiation procedure should be triggered when notification/indication of + * @note If the negotiation procedure should be triggered when notification/indication of * any characteristic is enabled by the peer, then this function must be called after * having initialized the services. * @@ -83,7 +115,7 @@ uint32_t ble_conn_params_stop(void); /**@brief Function for changing the current connection parameters to a new set. * - * @details Use this function to change the connection parameters to a new set of parameter + * @details Use this function to change the connection parameters to a new set of parameter * (ie different from the ones given at init of the module). * This function is usefull for scenario where most of the time the application * needs a relatively big connection interval, and just sometimes, for a temporary @@ -106,6 +138,11 @@ uint32_t ble_conn_params_change_conn_params(ble_gap_conn_params_t *new_params); */ void ble_conn_params_on_ble_evt(ble_evt_t * p_ble_evt); + +#ifdef __cplusplus +} +#endif + #endif // BLE_CONN_PARAMS_H__ /** @} */ diff --git a/components/ble/common/ble_conn_state.c b/components/ble/common/ble_conn_state.c index dc1639f..d7d5132 100644 --- a/components/ble/common/ble_conn_state.c +++ b/components/ble/common/ble_conn_state.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_conn_state.h" @@ -50,7 +78,7 @@ typedef struct */ typedef struct { - uint16_t acquired_flags; /**< Bitmap for keeping track of which user flags have been acquired. */ + uint32_t acquired_flags; /**< Bitmap for keeping track of which user flags have been acquired. */ uint16_t valid_conn_handles[SDK_MAPPED_FLAGS_N_KEYS]; /**< List of connection handles used as keys for the sdk_mapped_flags module. */ union { @@ -149,7 +177,7 @@ static void record_purge_disconnected() m_bcs.valid_conn_handles, (~m_bcs.flags.connected_flags) & (m_bcs.flags.valid_flags)); - for (int i = 0; i < disconnected_list.len; i++) + for (uint32_t i = 0; i < disconnected_list.len; i++) { record_invalidate(disconnected_list.flag_keys[i]); } @@ -198,16 +226,9 @@ void ble_conn_state_on_ble_evt(ble_evt_t * p_ble_evt) } else { -#if defined(S110) - bool is_central = false; -#elif defined(S120) - bool is_central = true; -#elif defined(S130) || defined(S132) || defined(S332) bool is_central = (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_CENTRAL); -#else - /* BLE SoftDevice missing. */ -#endif + sdk_mapped_flags_update_by_key(m_bcs.valid_conn_handles, &m_bcs.flags.central_flags, p_ble_evt->evt.gap_evt.conn_handle, diff --git a/components/ble/common/ble_conn_state.h b/components/ble/common/ble_conn_state.h index 03b813c..b7dec0c 100644 --- a/components/ble/common/ble_conn_state.h +++ b/components/ble/common/ble_conn_state.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -45,6 +73,10 @@ #include "ble.h" #include "sdk_mapped_flags.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Connection handle statuses. */ typedef enum @@ -54,7 +86,7 @@ typedef enum BLE_CONN_STATUS_CONNECTED, /**< The connection handle refers to an active connection. */ } ble_conn_state_status_t; -#define BLE_CONN_STATE_N_USER_FLAGS 16 /**< The number of available user flags. */ +#define BLE_CONN_STATE_N_USER_FLAGS 24 /**< The number of available user flags. */ /**@brief One ID for each user flag collection. @@ -79,6 +111,14 @@ typedef enum BLE_CONN_STATE_USER_FLAG13, BLE_CONN_STATE_USER_FLAG14, BLE_CONN_STATE_USER_FLAG15, + BLE_CONN_STATE_USER_FLAG16, + BLE_CONN_STATE_USER_FLAG17, + BLE_CONN_STATE_USER_FLAG18, + BLE_CONN_STATE_USER_FLAG19, + BLE_CONN_STATE_USER_FLAG20, + BLE_CONN_STATE_USER_FLAG21, + BLE_CONN_STATE_USER_FLAG22, + BLE_CONN_STATE_USER_FLAG23, BLE_CONN_STATE_USER_FLAG_INVALID, } ble_conn_state_user_flag_id_t; @@ -264,4 +304,9 @@ sdk_mapped_flags_t ble_conn_state_user_flag_collection(ble_conn_state_user_flag_ /** @} */ /** @} */ + +#ifdef __cplusplus +} +#endif + #endif /* BLE_CONN_STATE_H__ */ diff --git a/components/ble/common/ble_date_time.h b/components/ble/common/ble_date_time.h index 38b274d..7bc7a6c 100644 --- a/components/ble/common/ble_date_time.h +++ b/components/ble/common/ble_date_time.h @@ -1,16 +1,45 @@ -/* Copyright (c) 2011 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -*/ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ -/* Attention! -* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile +/* Attention! +* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ @@ -31,6 +60,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Date and Time structure. */ typedef struct { @@ -46,13 +79,13 @@ static __INLINE uint8_t ble_date_time_encode(const ble_date_time_t * p_date_time uint8_t * p_encoded_data) { uint8_t len = uint16_encode(p_date_time->year, p_encoded_data); - + p_encoded_data[len++] = p_date_time->month; p_encoded_data[len++] = p_date_time->day; p_encoded_data[len++] = p_date_time->hours; p_encoded_data[len++] = p_date_time->minutes; p_encoded_data[len++] = p_date_time->seconds; - + return len; } @@ -60,17 +93,22 @@ static __INLINE uint8_t ble_date_time_decode(ble_date_time_t * p_date_time, const uint8_t * p_encoded_data) { uint8_t len = sizeof(uint16_t); - + p_date_time->year = uint16_decode(p_encoded_data); p_date_time->month = p_encoded_data[len++]; - p_date_time->day = p_encoded_data[len++]; + p_date_time->day = p_encoded_data[len++]; p_date_time->hours = p_encoded_data[len++]; p_date_time->minutes = p_encoded_data[len++]; p_date_time->seconds = p_encoded_data[len++]; - + return len; } + +#ifdef __cplusplus +} +#endif + #endif // BLE_DATE_TIME_H__ /** @} */ diff --git a/components/ble/common/ble_gatt_db.h b/components/ble/common/ble_gatt_db.h index 45e8b76..2cc2785 100644 --- a/components/ble/common/ble_gatt_db.h +++ b/components/ble/common/ble_gatt_db.h @@ -1,19 +1,72 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup ble_sdk_lib_gatt_db GATT Database Service Structure + * @{ + * @ingroup app_common + */ #ifndef BLE_GATT_DB_H__ #define BLE_GATT_DB_H__ -#include "stdint.h" +#include #include "ble.h" #include "ble_gattc.h" -#define BLE_GATT_DB_MAX_CHARS 4 /**< The maximum number of characteristics present in a service record. */ +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_GATT_DB_MAX_CHARS 5 /**< The maximum number of characteristics present in a service record. */ /**@brief Structure for holding the characteristic and the handle of its CCCD present on a server. */ typedef struct { - ble_gattc_char_t characteristic; /**< Structure containing information about the characteristic. */ - uint16_t cccd_handle; /**< CCCD Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a CCCD is not present at the server. */ + ble_gattc_char_t characteristic; /**< Structure containing information about the characteristic. */ + uint16_t cccd_handle; /**< CCCD Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a CCCD is not present at the server. */ + uint16_t ext_prop_handle; /**< Extended Properties Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if an Extended Properties descriptor is not present at the server. */ + uint16_t user_desc_handle; /**< User Description Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a User Description descriptor is not present at the server. */ + uint16_t report_ref_handle; /**< Report Refence Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a Report Reference descriptor is not present at the server. */ } ble_gatt_db_char_t; /**@brief Structure for holding information about the service and the characteristics present on a @@ -21,10 +74,17 @@ typedef struct */ typedef struct { - ble_uuid_t srv_uuid; /**< UUID of the service. */ + ble_uuid_t srv_uuid; /**< UUID of the service. */ uint8_t char_count; /**< Number of characteristics present in the service. */ ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ ble_gatt_db_char_t charateristics[BLE_GATT_DB_MAX_CHARS]; /**< Array of information related to the characteristics present in the service. This list can extend further than one. */ } ble_gatt_db_srv_t; + +#ifdef __cplusplus +} +#endif + #endif /* BLE_GATT_DB_H__ */ + +/** @} */ diff --git a/components/ble/common/ble_sensor_location.h b/components/ble/common/ble_sensor_location.h index 4fdbbf6..fb70e55 100644 --- a/components/ble/common/ble_sensor_location.h +++ b/components/ble/common/ble_sensor_location.h @@ -1,23 +1,55 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /* Attention! * To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile * qualification listings, this section of source code must not be modified. */ - + #ifndef BLE_SENSOR_LOCATION_H__ #define BLE_SENSOR_LOCATION_H__ +#ifdef __cplusplus +extern "C" { +#endif + typedef enum { BLE_SENSOR_LOCATION_OTHER = 0 , /**<-- Other */ BLE_SENSOR_LOCATION_TOP_OF_SHOE = 1 , /**<-- Top of shoe */ @@ -37,4 +69,9 @@ typedef enum { #define BLE_NB_MAX_SENSOR_LOCATIONS 14 + +#ifdef __cplusplus +} +#endif + #endif // BLE_SENSOR_LOCATION_H__ diff --git a/components/ble/common/ble_srv_common.c b/components/ble/common/ble_srv_common.c index 364798d..b8e3f02 100644 --- a/components/ble/common/ble_srv_common.c +++ b/components/ble/common/ble_srv_common.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /* Attention! @@ -21,6 +49,18 @@ #include "app_error.h" #include "ble.h" +bool ble_srv_is_notification_enabled(uint8_t const * p_encoded_data) +{ + uint16_t cccd_value = uint16_decode(p_encoded_data); + return ((cccd_value & BLE_GATT_HVX_NOTIFICATION) != 0); +} + +bool ble_srv_is_indication_enabled(uint8_t const * p_encoded_data) +{ + uint16_t cccd_value = uint16_decode(p_encoded_data); + return ((cccd_value & BLE_GATT_HVX_INDICATION) != 0); +} + uint8_t ble_srv_report_ref_encode(uint8_t * p_encoded_buffer, const ble_srv_report_ref_t * p_report_ref) { @@ -120,7 +160,8 @@ uint32_t characteristic_add(uint16_t service_handle, char_md.p_cccd_md = &cccd_md; } - char_md.char_props = p_char_props->char_props; + char_md.char_props = p_char_props->char_props; + char_md.char_ext_props = p_char_props->char_ext_props; memset(&attr_char_value, 0, sizeof(ble_gatts_attr_t)); attr_char_value.p_uuid = &char_uuid; diff --git a/components/ble/common/ble_srv_common.h b/components/ble/common/ble_srv_common.h index 94f6d94..f1daeff 100644 --- a/components/ble/common/ble_srv_common.h +++ b/components/ble/common/ble_srv_common.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -29,6 +57,10 @@ #include "ble_gap.h" #include "ble_gatt.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @defgroup UUID_SERVICES Service UUID definitions * @{ */ #define BLE_UUID_ALERT_NOTIFICATION_SERVICE 0x1811 /**< Alert Notification service UUID. */ @@ -51,12 +83,15 @@ #define BLE_UUID_SCAN_PARAMETERS_SERVICE 0x1813 /**< Scan Parameters service UUID. */ #define BLE_UUID_TX_POWER_SERVICE 0x1804 /**< TX Power service UUID. */ #define BLE_UUID_IPSP_SERVICE 0x1820 /**< Internet Protocol Support service UUID. */ +#define BLE_UUID_BMS_SERVICE 0x181E /**< BOND MANAGEMENT service UUID*/ +#define BLE_UUID_CGM_SERVICE 0x181F /**< Contiunous Glucose Monitoring service UUID*/ +#define BLE_UUID_PLX_SERVICE 0x1822 /**< Pulse Oximeter Service UUID*/ + + /** @} */ /** @defgroup UUID_CHARACTERISTICS Characteristic UUID definitions * @{ */ -#define BLE_UUID_BATTERY_LEVEL_STATE_CHAR 0x2A1B /**< Battery Level State characteristic UUID. */ -#define BLE_UUID_BATTERY_POWER_STATE_CHAR 0x2A1A /**< Battery Power State characteristic UUID. */ #define BLE_UUID_REMOVABLE_CHAR 0x2A3A /**< Removable characteristic UUID. */ #define BLE_UUID_SERVICE_REQUIRED_CHAR 0x2A3B /**< Service Required characteristic UUID. */ #define BLE_UUID_ALERT_CATEGORY_ID_CHAR 0x2A43 /**< Alert Category Id characteristic UUID. */ @@ -132,6 +167,22 @@ #define BLE_UUID_LN_LOCATION_AND_SPEED_CHAR 0x2A67 /**< Location Navigation Service, Location and Speed characteristic UUID. */ #define BLE_UUID_LN_NAVIGATION_CHAR 0x2A68 /**< Location Navigation Service, Navigation characteristic UUID. */ #define BLE_UUID_LN_CONTROL_POINT_CHAR 0x2A6B /**< Location Navigation Service, Control point characteristic UUID. */ +#define BLE_UUID_BMS_CTRLPT 0x2AA4 /**< BMS Control Point characteristic UUID. */ +#define BLE_UUID_BMS_FEATURE 0x2AA5 /**< BMS Feature characteristic UUID. */ +#define BLE_UUID_CGM_MEASUREMENT 0x2AA7 /**< CGM Service, Measurement characteristic UUID*/ +#define BLE_UUID_CGM_FEATURE 0x2AA8 /**< CGM Service, Feature characteristic UUID*/ +#define BLE_UUID_CGM_STATUS 0x2AA9 /**< CGM Service, Status characteristic UUID*/ +#define BLE_UUID_CGM_SESSION_START_TIME 0x2AAA /**< CGM Service, session start time characteristic UUID*/ +#define BLE_UUID_CGM_SESSION_RUN_TIME 0x2AAB /**< CGM Service, session run time characteristic UUID*/ +#define BLE_UUID_CGM_SPECIFIC_OPS_CTRLPT 0x2AAC /**< CGM Service, specific ops ctrlpt characteristic UUID*/ +#define BLE_UUID_PLX_SPOT_CHECK_MEAS 0x2A5E /**< PLX Service, spot check measurement characteristic UUID*/ +#define BLE_UUID_PLX_CONTINUOUS_MEAS 0x2A5F /**< PLX Service, continuous measurement characteristic UUID*/ +#define BLE_UUID_PLX_FEATURES 0x2A60 /**< PLX Service, feature characteristic UUID*/ + + + + + /** @} */ /** @defgroup ALERT_LEVEL_VALUES Definitions for the Alert Level characteristic values @@ -150,7 +201,7 @@ typedef void (*ble_srv_error_handler_t) (uint32_t nrf_error); -/**@brief Value of a Report Reference descriptor. +/**@brief Value of a Report Reference descriptor. * * @details This is mapping information that maps the parent characteristic to the Report ID(s) and * Report Type(s) defined within a Report Map characteristic. @@ -201,12 +252,9 @@ typedef struct * @retval TRUE If notification is enabled. * @retval FALSE Otherwise. */ -static __INLINE bool ble_srv_is_notification_enabled(uint8_t * p_encoded_data) -{ - uint16_t cccd_value = uint16_decode(p_encoded_data); - return ((cccd_value & BLE_GATT_HVX_NOTIFICATION) != 0); -} - +bool ble_srv_is_notification_enabled(uint8_t const * p_encoded_data); + + /**@brief Function for decoding a CCCD value, and then testing if indication is * enabled. * @@ -215,11 +263,8 @@ static __INLINE bool ble_srv_is_notification_enabled(uint8_t * p_encoded_data) * @retval TRUE If indication is enabled. * @retval FALSE Otherwise. */ -static __INLINE bool ble_srv_is_indication_enabled(uint8_t * p_encoded_data) -{ - uint16_t cccd_value = uint16_decode(p_encoded_data); - return ((cccd_value & BLE_GATT_HVX_INDICATION) != 0); -} +bool ble_srv_is_indication_enabled(uint8_t const * p_encoded_data); + /**@brief Function for encoding a Report Reference Descriptor. * @@ -283,6 +328,7 @@ typedef struct uint8_t * p_init_value; /**< Initial encoded value of the characteristic.*/ bool is_var_len; /**< Indicates if the characteristic value has variable length.*/ ble_gatt_char_props_t char_props; /**< Characteristic properties.*/ + ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic extended properties.*/ bool is_defered_read; /**< Indicate if deferred read operations are supported.*/ bool is_defered_write; /**< Indicate if deferred write operations are supported.*/ security_req_t read_access; /**< Security requirement for reading the characteristic value.*/ @@ -314,7 +360,7 @@ typedef struct } ble_add_descr_params_t; -/**@brief Function for adding a characteristic to a given service. +/**@brief Function for adding a characteristic to a given service. * * If no pointer is given for the initial value, * the initial length parameter will be ignored and the initial length will be 0. @@ -343,6 +389,11 @@ uint32_t descriptor_add(uint16_t char_handle, uint16_t * p_descr_handle); + +#ifdef __cplusplus +} +#endif + #endif // BLE_SRV_COMMON_H__ /** @} */ diff --git a/components/ble/device_manager/config/device_manager_cnfg.h b/components/ble/device_manager/config/device_manager_cnfg.h deleted file mode 100644 index 9aff537..0000000 --- a/components/ble/device_manager/config/device_manager_cnfg.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright (C) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * - */ - - /** - * @file device_manager_cnfg.h - * - * @cond - * @defgroup device_manager_cnfg Device Manager Configuration - * @ingroup device_manager - * @{ - * - * @brief Defines application specific configuration for Device Manager. - * - * @details All configurations that are specific to application have been defined - * here. Application should configuration that best suits its requirements. - */ - -#ifndef DEVICE_MANAGER_CNFG_H__ -#define DEVICE_MANAGER_CNFG_H__ - -/** - * @defgroup device_manager_inst Device Manager Instances - * @{ - */ -/** - * @brief Maximum applications that Device Manager can support. - * - * @details Maximum application that the Device Manager can support. - * Currently only one application can be supported. - * Minimum value : 1 - * Maximum value : 1 - * Dependencies : None. - */ -#define DEVICE_MANAGER_MAX_APPLICATIONS 1 - -/** - * @brief Maximum connections that Device Manager should simultaneously manage. - * - * @details Maximum connections that Device Manager should simultaneously manage. - * Minimum value : 1 - * Maximum value : Maximum links supported by SoftDevice. - * Dependencies : None. - */ -#define DEVICE_MANAGER_MAX_CONNECTIONS 1 - - -/** - * @brief Maximum bonds that Device Manager should manage. - * - * @details Maximum bonds that Device Manager should manage. - * Minimum value : 1 - * Maximum value : 254. - * Dependencies : None. - * @note In case of GAP Peripheral role, the Device Manager will accept bonding procedure - * requests from peers even if this limit is reached, but bonding information will not - * be stored. In such cases, application will be notified with DM_DEVICE_CONTEXT_FULL - * as event result at the completion of the security procedure. - */ -#define DEVICE_MANAGER_MAX_BONDS 7 - - -/** - * @brief Maximum Characteristic Client Descriptors used for GATT Server. - * - * @details Maximum Characteristic Client Descriptors used for GATT Server. - * Minimum value : 1 - * Maximum value : 254. - * Dependencies : None. - */ -#define DM_GATT_CCCD_COUNT 2 - - -/** - * @brief Size of application context. - * - * @details Size of application context that Device Manager should manage for each bonded device. - * Size had to be a multiple of word size. - * Minimum value : 4. - * Maximum value : 256. - * Dependencies : Needed only if Application Context saving is used by the application. - * @note If set to zero, its an indication that application context is not required to be managed - * by the module. - */ -#define DEVICE_MANAGER_APP_CONTEXT_SIZE 0 - -/* @} */ -/* @} */ -/** @endcond */ -#endif // DEVICE_MANAGER_CNFG_H__ - diff --git a/components/ble/device_manager/device_manager.h b/components/ble/device_manager/device_manager.h deleted file mode 100644 index 9aa465d..0000000 --- a/components/ble/device_manager/device_manager.h +++ /dev/null @@ -1,888 +0,0 @@ -/* Copyright (C) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * - */ - -/** - * @file device_manager.h - * - * @defgroup device_manager Device Manager - * @ingroup ble_sdk_lib - * @{ - * @brief Device Manager Application Interface Abstraction. - * - * @details The Device Manager module manages Active and Bonded Peers. Management of peer includes - * book keeping of contextual information like the Security Keys, GATT - * configuration and any application specific information. - * - * Active Peers are devices which are connected, and may or may not be bonded. - * Bonded Peers are devices which are bonded, and may or may not be Active (Connected). - * Active Bonded Peer refers to a device which is connected and bonded. - * - * Paired Devices refers to peer devices that are connected and have necessary context - * establishment/exchange for the current connection session. On disconnect, - * all contextual information is flushed. For example, SMP Information Exchanged during - * pairing and GATT Configuration is not retained on disconnection. - * - * Note that this module allows management of contextual information but - * does not provide an interface for connection management. Therefore, entering connectible - * mode, connection establishment, or disconnection of a link with peer is not in scope - * of this module. - * - * For bonded peers, the contextual information is required to be retained on disconnection - * and power cycling. Persistent storage of contextual information is handled by the - * module. This module categorizes the contextual information into 3 categories: - * - Bonding Information - * Bond information is the information exchanged between local and peer device to - * establish a bond. It also includes peer identification information, - * like the peer address or the IRK or both. From here on this category of information - * is referred to as Device Context. - * - Service/Protocol Information - * Service/Protocol information is the information retained for the peer to save on one-time - * procedures like the GATT Service Discovery procedures and Service Configurations. - * It allows devices to resume data exchange on subsequent reconnection without having - * to perform initial set-up procedures each time. From here on this category is - * referred to as Service Context. - * - Application Information - * Application information is the context that the application would like to associate with - * each of the bonded device. For example, if the application chooses to rank its peers - * in order to manage them better, the rank information could be treated as - * Application Information. This storage space is provided to save the application from - * maintaining a mapping table with each Device Instance and Application Information. - * However, if the application have no use for this, it is possible to not - * use or employ this at compile time. From here on this category of information is - * referred to as Application Context. - */ - - -#ifndef DEVICE_MANAGER_H__ -#define DEVICE_MANAGER_H__ - -#include -#include -#include "sdk_common.h" -#include "ble.h" -#include "ble_gap.h" -#include "device_manager_cnfg.h" - -/** - * @defgroup dm_service_cntext_types Service/Protocol Types - * - * @brief Describes the possible types of Service/Protocol Contexts for a bonded/peer device. - * - * @details Possible Service/Protocol context per peer device. The Device Manager provides the - * functionality of persistently storing the Service/Protocol context and can automatically - * load them when needed. - * For example system attributes for a GATT Server. Based on the nature of the application, - * not all service types may be needed. The application can specify - * only the service/protocol context it wants to use at the time of registration. - * @{ - */ -#define DM_PROTOCOL_CNTXT_NONE 0x00 /**< No Service Context, this implies the application does not want to associate any service/protocol context with the peer device */ -#define DM_PROTOCOL_CNTXT_GATT_SRVR_ID 0x01 /**< GATT Server Service Context, this implies the application does associate GATT Server with the peer device and this information will be loaded when needed for a bonded device */ -#define DM_PROTOCOL_CNTXT_GATT_CLI_ID 0x02 /**< GATT Client Service Context, this implies the application does associate GATT Client with the peer device and this information will be loaded when needed for a bonded device */ -#define DM_PROTOCOL_CNTXT_ALL \ - (DM_PROTOCOL_CNTXT_GATT_SRVR_ID | DM_PROTOCOL_CNTXT_GATT_CLI_ID) /**< All Service/Protocol Context, this implies that the application wants to associate all Service/Protocol Information with the bonded device. This is configurable based on system requirements. If the application has only one type of service, this define could be altered to reflect the same. */ -/** @} */ - - -/** - * @defgroup dm_events Device Manager Events - * - * @brief This section describes the device manager events that are notified to the application. - * - * @details The Device Manager notifies the application of various asynchronous events using the - * asynchronous event notification callback. All events has been categorized into: - * a. General. - * b. Link Status. - * c. Context Management. - * - * In the callback, these events are notified along with handle that uniquely identifies: - * application instance, active instance (if applicable), device instance - * bonding instance, (if applicable) and service instance. - * Not all events are pertaining to an active connection, for example a context deletion event could occur even if the peer - * is not connected. Also, general category of events may not be pertaining to any specific peer. - * See also \ref dm_event_cb_t and \ref dm_register. - * @{ - */ -/** - * @defgroup general_events General Events - * - * @brief General or miscellaneous events. - * - * @details This category of events are general events not pertaining to a peer or context. - * - * @{ - */ -#define DM_EVT_RFU 0x00 /**< Reserved for future use, is never notified. */ -#define DM_EVT_ERROR 0x01 /**< Device Manager Event Error. */ -/** @} */ - -/** - * @defgroup link_status_events Link Status Events - * - * @brief Link Status Events. - * - * @details This category of events notify the application of the link status. Event result associated - * with the event is provided along with the event in the callback to provide more details of - * whether a procedure succeeded or failed and assist the application in decision making of - * how to proceed. For example if a DM_DEVICE_CONNECT_IND is indicated with NRF_SUCCESS - * result, the application may want to proceed with discovering and association with - * service of the peer. However, if indicated with a failure result, the application may - * want to take an alternate action such as reattempting to connect or go into a - * sleep mode. - * - * @{ - */ -#define DM_EVT_CONNECTION 0x11 /**< Indicates that link with the peer is established. */ -#define DM_EVT_DISCONNECTION 0x12 /**< Indicates that link with peer is torn down. */ -#define DM_EVT_SECURITY_SETUP 0x13 /**< Security procedure for link started indication */ -#define DM_EVT_SECURITY_SETUP_COMPLETE 0x14 /**< Security procedure for link completion indication. */ -#define DM_EVT_LINK_SECURED 0x15 /**< Indicates that link with the peer is secured. For bonded devices, subsequent reconnections with bonded peer will result only in this event when the link is secured and setup procedures will not occur unless the bonding information is either lost or deleted on either or both sides. */ -#define DM_EVT_SECURITY_SETUP_REFRESH 0x16 /**< Indicates that the security on the link was re-established. */ -/** @} */ - -/** - * @defgroup context_mgmt_events Context Management Events - * - * @brief Context Management Events. - * - * @details These events notify the application of the status of context loading and storing. - * - * @{ - */ -#define DM_EVT_DEVICE_CONTEXT_LOADED 0x21 /**< Indicates that device context for a peer is loaded. */ -#define DM_EVT_DEVICE_CONTEXT_STORED 0x22 /**< Indicates that device context is stored persistently. */ -#define DM_EVT_DEVICE_CONTEXT_DELETED 0x23 /**< Indicates that device context is deleted. */ -#define DM_EVT_SERVICE_CONTEXT_LOADED 0x31 /**< Indicates that service context for a peer is loaded. */ -#define DM_EVT_SERVICE_CONTEXT_STORED 0x32 /**< Indicates that service context is stored persistently. */ -#define DM_EVT_SERVICE_CONTEXT_DELETED 0x33 /**< Indicates that service context is deleted. */ -#define DM_EVT_APPL_CONTEXT_LOADED 0x41 /**< Indicates that application context for a peer is loaded. */ -#define DM_EVT_APPL_CONTEXT_STORED 0x42 /**< Indicates that application context is stored persistently. */ -#define DM_EVT_APPL_CONTEXT_DELETED 0x43 /**< Indicates that application context is deleted. */ -/** @} */ -/** @} */ - -#define DM_INVALID_ID 0xFF /**< Invalid instance idenitifer. */ - -/** - * @defgroup dm_data_structure Device Manager Data Types - * - * @brief This section describes all the data types exposed by the module to the application. - * @{ - */ - -/** - * @brief Application Instance. - * - * @details Application instance uniquely identifies an application. The identifier is allocated by - * the device manager when application registers with the module. The application is - * expected to identify itself with this instance identifier when initiating subsequent - * requests. Application should use the utility API \ref dm_application_instance_set in - * order to set its application instance in dm_handle_t needed for all subsequent APIs. - * See also \ref dm_register. - */ -typedef uint8_t dm_application_instance_t; - -/** - * @brief Connection Instance. - * - * @details Identifies connection instance for an active device. This instance is allocated by the - * device manager when a connection is established and is notified with DM_EVT_CONNECTION - * with the event result NRF_SUCCESS. - */ -typedef uint8_t dm_connection_instance_t; - -/** - * @brief Device Instance. - * - * @details Uniquely identifies a bonded peer device. The peer device may or may not be connected. - * In case of the central: The bonded device instance to identify the peer is allocated when bonding procedure is initiated by the central using dm_security_setup_req. - * In case of the peripheral: When the bonding procedure is successful, the DM_EVT_SECURITY_SETUP_COMPLETE event with success event result, is received. - * In case the module cannot add more bonded devices, no instance is allocated, this is indicated by an appropriate error code for the API/event as the case may be. Application can choose to disconnect the link. - */ -typedef uint8_t dm_device_instance_t; - -/** - * @brief Service Instance. - * - * @details Uniquely identifies a peer device. The peer device may or may not be connected. This - * instance is allocated by the device manager when a device is bonded and is notified - * when security procedures have been initiated. - * Security Procedures initiation is notified with DM_SECURITY_SETUP_IND with - * success event result. In case the event result indicates that the module cannot add more - * bonded devices, no instance is allocated. Application can chose to disconnect the link. - */ -typedef uint8_t dm_service_instance_t; - -/** - * @brief Service/Protocol Type Identifier. - * - * @details Uniquely identifies a service or a protocol type. Service/Protocol Type identification - * is needed as each service/protocol can have its own contextual data. - * This allows the peer to access more than one service at a time. \ref dm_service_cntext_types describes the - * list of services/protocols supported. - */ -typedef uint8_t service_type_t; - -/**@brief Device Manager Master identification and encryption information. */ -typedef struct dm_enc_key -{ - ble_gap_enc_info_t enc_info; /**< GAP encryption information. */ - ble_gap_master_id_t master_id; /**< Master identification. */ -} dm_enc_key_t; - -/** @brief Device Manager identity and address information. */ -typedef struct dm_id_key -{ - ble_gap_irk_t id_info; /**< Identity information. */ - ble_gap_addr_t id_addr_info; /**< Identity address information. */ -} dm_id_key_t; - -/** @brief Device Manager signing information. */ -typedef struct dm_sign_key -{ - ble_gap_sign_info_t sign_key; /**< GAP signing information. */ -} dm_sign_key_t; - -/** @brief Security keys. */ -typedef struct dm_sec_keyset -{ - union - { - dm_enc_key_t * p_enc_key; /**< Pointer to Device Manager encryption information structure. */ - } enc_key; - dm_id_key_t * p_id_key; /**< Identity key, or NULL. */ - dm_sign_key_t * p_sign_key; /**< Signing key, or NULL. */ -} dm_sec_keys_t; - -/** @brief Device Manager security key set. */ -typedef struct -{ - dm_sec_keys_t keys_periph; /**< Keys distributed by the device in the Peripheral role. */ - dm_sec_keys_t keys_central; /**< Keys distributed by the device in the Central role. */ -} dm_sec_keyset_t; - -/** - * @brief Device Handle used for unique identification of each peer. - * - * @details This data type is used to uniquely identify each peer device. A peer device could be - * active and/or bonded. Therefore an instance for active and bonded is provided. - * However, the application is expected to treat this is an opaque structure and use this for - * all API interactions once stored on appropriate events. - * See \ref dm_events. - */ -typedef struct device_handle -{ - dm_application_instance_t appl_id; /**< Identifies the application instances for the device that is being managed. */ - dm_connection_instance_t connection_id; /**< Identifies the active connection instance. */ - dm_device_instance_t device_id; /**< Identifies peer instance in the data base. */ - dm_service_instance_t service_id; /**< Service instance identifier. */ -} dm_handle_t; - -/** - * @brief Definition of Data Context. - * - * @details Defines contextual data format, it consists of context data length and pointer to data. - */ -typedef struct -{ - uint32_t flags; /**< Additional flags identifying data. */ - uint32_t len; /**< Length of data. */ - uint8_t * p_data; /**< Pointer to contextual data, a copy is made of the data. */ -} dm_context_t; - - -/** - * @brief Device Context. - * - * @details Defines "device context" type for a device managed by device manager. - */ -typedef dm_context_t dm_device_context_t; - -/** - * @brief Service Context. - * - * @details Service context data for a service identified by the 'service_type' field. - */ -typedef struct -{ - service_type_t service_type; /**< Identifies the service/protocol to which the context data is related. */ - dm_context_t context_data; /**< Contains length and pointer to context data */ -} dm_service_context_t; - -/** - * @brief Application context. - * - * @details The application context can be used by the application to map any application level - * information that is to be mapped with a particular peer. - * For bonded peers, this information will be stored by the bond manager persistently. - * Note that the device manager treats this information as an - * opaque block of bytes. - * Necessary APIs to get and set this context for a peer have been provided. - */ -typedef dm_context_t dm_application_context_t; - -/** - * @brief Event parameters. - * - * @details Defines event parameters for each of the events notified by the module. - */ -typedef union -{ - ble_gap_evt_t * p_gap_param; /**< All events that are triggered in device manager as a result of GAP events, like connection, disconnection and security procedures are accompanied with GAP parameters. */ - dm_application_context_t * p_app_context; /**< All events that are associated with application context procedures of store, load, and deletion have this as event parameter. */ - dm_service_context_t * p_service_context; /**< All events that are associated with service context procedures of store, load and deletion have this as event parameter. */ - dm_device_context_t * p_device_context; /**< All events that are associated with device context procedures of store, load and deletion have this as event parameter. */ -} dm_event_param_t; - -/** - * @brief Asynchronous events details notified to the application by the module. - * - * @details Defines event type along with event parameters notified to the application by the - * module. - */ -typedef struct -{ - uint8_t event_id; /**< Identifies the event. See \ref dm_events for details on event types and their significance. */ - dm_event_param_t event_param; /**< Event parameters. Can be NULL if the event does not have any parameters. */ - uint16_t event_paramlen; /**< Length of the event parameters, is zero if the event does not have any parameters. */ -} dm_event_t; - -/** - * @brief Event notification callback registered by application with the module. - * - * @details Event notification callback registered by application with the module when registering - * the module using \ref dm_register API. - * - * @param[in] p_handle Identifies the peer for which the event is being notified. - * @param[in] p_event Identifies the event, any associated parameters and parameter length. - * See \ref dm_events for details on event types and their significance. - * @param[in,out] event_result Provide additional information on the event. - * In addition to SDK error codes there is also a return value - * indicating if maximum number of connections has been reached when connecting or bonding. - * - * @retval NRF_SUCCESS on success, or a failure to indicate if it could handle the event - * successfully. There is no action taken in case application returns a failure. - */ -typedef ret_code_t (*dm_event_cb_t)(dm_handle_t const * p_handle, - dm_event_t const * p_event, - ret_code_t event_result); - -/** - * @brief Initialization Parameters. - * - * @details Indicates the application parameters. Currently this only encompasses clearing - * all persistent data. - */ -typedef struct -{ - bool clear_persistent_data; /**< Set to true in case the module should clear all persistent data. */ -} dm_init_param_t; - -/** - * @brief Application Registration Parameters. - * - * @details Parameters needed by the module when registering with it. - */ -typedef struct -{ - dm_event_cb_t evt_handler; /**< Event Handler to be registered. It will receive asynchronous notification from the module, see \ref dm_events for asynchronous events. */ - uint8_t service_type; /**< Bit mask identifying services that the application intends to support for all peers. */ - ble_gap_sec_params_t sec_param; /**< Security parameters to be used for the application. */ -} dm_application_param_t; - -/** - * @brief Defines possible security status/states. - * - * @details Defines possible security status/states of a link when requested by application using - * the \ref dm_security_status_req. - */ -typedef enum -{ - NOT_ENCRYPTED, /**< The link is not secured. */ - ENCRYPTION_IN_PROGRESS, /**< Link security is being established.*/ - ENCRYPTED /**< The link is secure.*/ -} dm_security_status_t; -/** @} */ - -/** - * @defgroup dm_api Device Module APIs - * - * @brief This section describes APIs exposed by the module. - * - * @details This section describes APIs exposed by the module. The APIs have been categorized to provide - * better and specific look up for developers. Categories are: - * - Set up APIs. - * - Context Management APIs. - * - Utility APIs. - * - * MSCs describe usage of these APIs. - * See @ref dm_msc. - * @{ - */ -/** - * @defgroup dm_setup_api Device Module Set-up APIs - * - * @brief Initialization & registration APIs that are pre-requisite for all other module procedures. - * @details This section describes the Module Initialization and Registration APIs needed to be set up by - * the application before device manager can start managing devices and device contexts - * for the application. - * - * @{ - */ - -/** - * @brief Module Initialization Routine. - * - * @details Function for initializing the module. Must called before any other APIs of the module are used. - * - * @param[in] p_init_param Initialization parameters. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * - * @note It is mandatory that pstorage is initialized before initializing this module. - */ -ret_code_t dm_init(dm_init_param_t const * p_init_param); - -/** - * @brief Function for registering the application. - * - * @details This routine is used by the application to register for asynchronous events with the - * device manager. During registration the application also indicates the services that it - * intends to support on this instance. It is possible to register multiple times with the - * device manager. At least one instance shall be registered with the device manager after - * the module has been initialized. - * Maximum number of application instances device manager can support is determined - * by DM_MAX_APPLICATIONS. - * - * All applications must be registered before initiating or accepting connections from the peer. - * - * @param[in] p_appl_param Application parameters. - * @param[out] p_appl_instance Application Instance Identifier in case registration is successful. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization. - * @retval NRF_ERROR_NO_MEM If module cannot support more applications. - * - * @note Currently only one application instance is supported by the module. - */ -ret_code_t dm_register(dm_application_instance_t * p_appl_instance, - dm_application_param_t const * p_appl_param); - -/** - * @brief Function for handling BLE events. - * - * @details BLE Event Handler for the module. This routine should be called from BLE stack event - * dispatcher for the module to work as expected. - * - * @param[in] p_ble_evt BLE stack event being dispatched to the function. - * - */ -void dm_ble_evt_handler(ble_evt_t * p_ble_evt); - -/** @} */ - - -/** - * @defgroup dm_security_api APIs to set up or read status of security on a link. - * - * @brief This section describes APIs to set up Security. These APIs require that the peer is - * connected before the procedures can be requested. - * - * @details This group allows application to request security procedures - * or get the status of the security on a link. - * @{ - */ -/** - * @brief Function for requesting setting up security on a link. - * - * @details This API initiates security procedures with a peer device. - * @note For the GAP Central role, in case peer is not bonded, request to bond/pair is - * initiated. If it is bonded, the link is re-encrypted using the existing bond information. - * For the GAP peripheral role, a Slave security request is sent. - * @details If a pairing procedure is initiated successfully, application is notified of - * @ref DM_EVT_SECURITY_SETUP_COMPLETE. A result indicating success or failure is notified along with the event. - * In case the link is re-encrypted using existing bond information, @ref DM_EVT_LINK_SECURED is - * notified to the application. - * - * @param[in] p_handle Identifies the link on which security is desired. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle is NULL. - * @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application - * or if the peer is not connected when this procedure is requested. - */ -ret_code_t dm_security_setup_req(dm_handle_t * p_handle); - -/** - * @brief Function for reading the status of the security on a link. - * - * @details This API allows application to query status of security on a link. - * - * @param[in] p_handle Identifies the link on which security is desired. - * @param[out] p_status Pointer where security status is provided to the application. - * See \ref dm_security_status_t for possible statuses that can be expected. - * - * @retval NRF_SUCCESS Or appropriate error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle or p_status is NULL. - * @retval NRF_ERROR_INVALID_ADDR If peer is not identified by the handle provided by the application - * or if peer is not connected when this procedure is requested. - */ -ret_code_t dm_security_status_req(dm_handle_t const * p_handle, dm_security_status_t * p_status); - -/** - * @brief Function for creating the whitelist. - * - * @details This API allows application to create whitelist based on bonded peer devices in module - * data base. - * - * @param[in] p_handle Identifies the application requesting whitelist creation. - * @param[in,out] p_whitelist Pointer where created whitelist is provided to the application. - * - * @note 'addr_count' and 'irk_count' fields of the structure should be populated with the maximum - * number of devices that the application wishes to request in the whitelist. - * If the number of bonded devices is less than requested, the fields are updated with that number of devices. - * If the number of devices are more than requested, the module will populate the list - * with devices in the order the bond was established with the peer devices. Also, if this routine is - * called when a connection exists with one or more peer devices, - * those connected devices are not added to the whitelist. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle or p_whitelist is NULL. - */ -ret_code_t dm_whitelist_create(dm_application_instance_t const * p_handle, - ble_gap_whitelist_t * p_whitelist); - -/** @} */ - - -/** - * @defgroup dm_cntxt_mgmt_api Context Management APIs - * - * @brief Utility APIs offered by the device manager to get information about the peer if and - * when needed. - * - * @details This group of API allow the application to access information that is not required to be - * maintained by the application but may be needed. Hence it is possible to get the - * information from the module instead of mapping all the information with a device - * context. - * @{ - */ - -ret_code_t dm_device_add(dm_handle_t * p_handle, - dm_device_context_t const * p_context); - -/** - * @brief Function for deleting a peer device context and all related information from the database. - * - * @details Delete peer device context and all related information from database. If - * this API returns NRF_SUCCESS, DM_EVT_DEVICE_CONTEXT_DELETED event is notified to the - * application. Event result notified along with the event indicates success or failure - * of this procedure. - * - * @param[in] p_handle Identifies the peer device to be deleted. - * - * @retval NRF_SUCCESS on success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE In the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle is NULL. - * @retval NRF_ERROR_INVALID_ADDR If peer is not identified the handle provided by the application. - * - * @note Deleting device context results in deleting service and application context for the - * bonded device. The respective events DM_EVT_SERVICE_CONTEXT_DELETED and - * DM_EVT_APPL_CONTEXT_DELETED are not notified to the application. - */ -ret_code_t dm_device_delete(dm_handle_t const * p_handle); - -/** - * @brief Function for deleting all peer device context and all related information from the database. - * - * @details Delete peer device context and all related information from database. If - * this API returns NRF_SUCCESS, DM_EVT_DEVICE_CONTEXT_DELETED event is notified to the - * application for each device that is deleted from the data base. Event result - * notified along with the event indicates success or failure of this procedure. - * - * @param[in] p_handle Identifies application instance that is requesting - * the deletion of all bonded devices. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle is NULL. - * @retval NRF_ERROR_INVALID_ADDR If peer is not identified the handle provided by the application. - * - * @note Deleting device context results in deleting both service and application context for the - * bonded device. The respective events DM_EVT_SERVICE_CONTEXT_DELETED and - * DM_EVT_APPL_CONTEXT_DELETED are not notified to the application. - */ -ret_code_t dm_device_delete_all(dm_application_instance_t const * p_handle); - -/** - * @brief Function for setting Service Context for a peer device identified by 'p_handle' parameter. - * - * @details This API allows application to Set Service Context for a peer device identified by the - * 'p_handle' parameter. This API is useful when the Service Context cannot be requested - * from the SoftDevice, but needs to be assembled by the application or an another module. - * (or when service context is exchanged in an out of band way.) - * This API could also be used to trigger a storing of service context into persistent - * memory. If this is desired, a NULL pointer could be passed to the p_context. - * - * @param[in] p_handle Identifies peer device for which the procedure is requested. - * @param[in] p_context Service context being set. The context information includes length of - * data and pointer to the contextual data being set. The memory pointed to by - * the pointer to data is assumed to be resident when API is being called and - * can be freed or reused once the set procedure is complete. Set procedure - * completion is indicated by the event \ref DM_EVT_SERVICE_CONTEXT_STORED. - * The Event result is notified along with the event and indicates success or failure of - * this procedure. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle is NULL. - * @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application. - */ -ret_code_t dm_service_context_set(dm_handle_t const * p_handle, - dm_service_context_t const * p_context); - -/** - * @brief Function for getting Service Context for a peer device identified by 'p_handle' parameter. - * - * @details Get Service Context for a peer device identified by the 'p_handle' parameter. If - * this API returns NRF_SUCCESS, DM_EVT_SERVICE_CONTEXT_LOADED event is notified to the - * application. The event result is notified along with the event indicates success or failure - * of this procedure. - * - * @param[in] p_handle Identifies peer device for which procedure is requested. - * @param[in] p_context Application context being requested. The context information includes length - * of the data and a pointer to the data. Note that requesting a 'get' - * of application does not need to provide memory, the pointer to data will be - * pointing to service data and hence no data movement is involved. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE In case API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle is NULL. - * @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application. - */ -ret_code_t dm_service_context_get(dm_handle_t const * p_handle, - dm_service_context_t * p_context); - -/** - * @brief Function for deleting a Service Context for a peer device identified by the 'p_handle' parameter. - * - * @details This API allows application to delete a Service Context identified for a peer device - * identified by the 'p_handle' parameter. If this API returns NRF_SUCCESS, - * DM_EVT_SERVICE_CONTEXT_DELETED event is notified to the application. - * Event result is notified along with the event and indicates success or failure of this - * procedure. - * - * @param[in] p_handle Identifies peer device for which procedure is requested. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle is NULL. - * @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application. - */ -ret_code_t dm_service_context_delete(dm_handle_t const * p_handle); - -/** - * @brief Function for setting Application Context for a peer device identified by the 'p_handle' parameter. - * - * @details This application allows the setting of the application context for the peer device identified by - * the 'p_handle'. Application context is stored persistently by the module and can be - * requested by the application at any time using the \ref dm_application_context_get - * API. Note that this procedure is permitted only for bonded devices. If the - * device is not bonded, application context cannot be set. However, it is not mandatory - * that the bonded device is connected when requesting this procedure. - * - * @param[in] p_handle Identifies peer device for which procedure is requested. - * - * @param[in] p_context Application context being set. The context information includes length of the - * data and pointer to the contextual data being set. The memory pointed to by - * the data pointer is assumed to be resident when API is being called and - * can be freed or reused once the set procedure is complete. Set procedure - * completion is notified by the event \ref DM_EVT_APPL_CONTEXT_STORED. - * The event result is notified along with the event and indicates success or - * failure of this procedure. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle and/or p_context is NULL. - * @retval NRF_ERROR_INVALID_ADDR If peer is not identified the handle provided by the application. - * - * @note The API returns FEATURE_NOT_ENABLED in case DEVICE_MANAGER_APP_CONTEXT_SIZE is set to zero. - */ -ret_code_t dm_application_context_set(dm_handle_t const * p_handle, - dm_application_context_t const * p_context); - -/** - * @brief Function for getting Application Context for a peer device identified by the 'p_handle' parameter. - * - * @details Get Application Context for a peer device identified by the 'p_handle' parameter. If - * this API returns NRF_SUCCESS, DM_EVT_APPL_CONTEXT_LOADED event is notified to the - * application. Event result notified along with the event indicates success or failure - * of this procedure. - * - * @param[in] p_handle Identifies peer device for which procedure is requested. - * @param[in] p_context Application context being requested. The context information includes - * length of data and pointer to the contextual data is provided. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle and/or p_context is NULL. - * @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application. - * @retval DM_NO_APP_CONTEXT If no application context was set that can be fetched. - * - * @note The API returns FEATURE_NOT_ENABLED in case DEVICE_MANAGER_APP_CONTEXT_SIZE is set to - * zero. - */ -ret_code_t dm_application_context_get(dm_handle_t const * p_handle, - dm_application_context_t * p_context); - -/** - * @brief Function for deleting Application Context for a peer device identified by the 'p_handle' parameter. - * - * @details Delete Application Context for a peer device identified by the 'p_handle' parameter. If - * this API returns NRF_SUCCESS, DM_EVT_APPL_CONTEXT_DELETED event is notified to the - * application. The event result notified along with the event and indicates success or failure - * of this procedure. - * - * @param[in] p_handle Identifies peer device for which procedure is requested. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If the p_handle is NULL. - * @retval NRF_ERROR_INVALID_ADDR If peer is not identified the handle provided by the application. - * @retval DM_NO_APP_CONTEXT If no application context was set that can be deleted. - * - * @note The API returns FEATURE_NOT_ENABLED if the DEVICE_MANAGER_APP_CONTEXT_SIZE is set to zero. - */ -ret_code_t dm_application_context_delete(dm_handle_t const * p_handle); - -/** @} */ - - -/** - * @defgroup utility_api Utility APIs - * @{ - * @brief This section describes the utility APIs offered by the module. - * - * @details APIs defined in this section are utility or assisting/helper APIs. - */ -/** - * @brief Function for Setting/Copying Application instance to Device Manager handle. - * - * @param[in] p_appl_instance Application instance to be set. - * @param[out] p_handle Device Manager handle for which the instance is to be copied. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle and/or p_addr is NULL. - */ -ret_code_t dm_application_instance_set(dm_application_instance_t const * p_appl_instance, - dm_handle_t * p_handle); - -/** - * @brief Function for getting a peer's device address. - * - * @param[in] p_handle Identifies the peer device whose address is requested. Can not be NULL. - * @param[out] p_addr Pointer where address is to be copied. Can not be NULL. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle and/or p_addr is NULL. - * @retval NRF_ERROR_NOT_FOUND If the peer could not be identified. - */ -ret_code_t dm_peer_addr_get(dm_handle_t const * p_handle, - ble_gap_addr_t * p_addr); - -/** - * @brief Function for setting/updating a peer's device address. - * - * @param[in] p_handle Identifies the peer device whose address is requested to be set/updated. - * @param[out] p_addr Address to be set/updated. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If p_handle and/or p_addr is NULL. - * @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application. - * @retval NRF_ERROR_INVALID_PARAM If this procedure is requested while connected to the peer or if the address - * type was set to BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE. - * - * @note Setting or updating a peer's device address is permitted - * only for a peer that is bonded and disconnected. - * @note Updated address is reflected only after DM_EVT_DEVICE_CONTEXT_STORED is notified to the - * application for this bonded device instance. In order to avoid abnormal behaviour, it is - * recommended to not invite/initiate connections on the updated address unless this event - * has been notified. - */ -ret_code_t dm_peer_addr_set(dm_handle_t const * p_handle, - ble_gap_addr_t const * p_addr); - -/** - * @brief Function for initializing Device Manager handle. - * - * @param[in] p_handle Device Manager handle to be initialized. - * - * @retval NRF_SUCCESS On success. - * @retval NRF_ERROR_NULL If p_handle is NULL. - * - * @note This routine is permitted before initialization of the module. - */ -ret_code_t dm_handle_initialize(dm_handle_t * p_handle); - -/** - * @brief Function for getting distributed keys for a device. - * - * @param[in] p_handle Device Manager handle identifying the peer. - * @param[out] p_key_dist Pointer to distributed keys. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_INVALID_STATE If the API is called without module initialization and/or - * application registration. - * @retval NRF_ERROR_NULL If the p_handle and/or p_key_dist pointer is NULL. - * @retval NRF_ERROR_INVALID_ADDR If the peer is not identified by the handle provided by the application. - */ -ret_code_t dm_distributed_keys_get(dm_handle_t const * p_handle, - dm_sec_keyset_t * p_key_dist); - -/** - * @brief Function for getting the corresponding dm_handle_t based on the connection handle. - * - * @param[in] conn_handle Connection handle as provided by the SoftDevice. - * @param[in,out] p_handle Pointer to the p_handle containg the application instance for the - * registered application. If the application instance is valid then - * the p_handle will be filled with requested data. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - * @retval NRF_ERROR_NULL If the p_handle pointer is NULL. - * @retval NRF_ERROR_NOT_FOUND If no p_handle is found for the provided connection handle. - */ -ret_code_t dm_handle_get(uint16_t conn_handle, dm_handle_t * p_handle); - -/** @} */ -/** @} */ -/** @} */ -#endif // DEVICE_MANAGER_H__ - diff --git a/components/ble/device_manager/device_manager_central.c b/components/ble/device_manager/device_manager_central.c deleted file mode 100644 index f71d067..0000000 --- a/components/ble/device_manager/device_manager_central.c +++ /dev/null @@ -1,2793 +0,0 @@ -/* Copyright (C) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * - */ - -#include "device_manager.h" -#include "app_trace.h" -#include "ble_advdata.h" -#include "pstorage.h" -#include "ble_hci.h" -#include "app_error.h" - -#define INVALID_ADDR_TYPE 0xFF /**< Identifier for an invalid address type. */ - -/** - * @defgroup device_manager_app_states Connection Manager Application States - * @{ - */ -#define STATE_CONTROL_PROCEDURE_IN_PROGRESS 0x01 /**< State where a security procedure is ongoing. */ -#define STATE_QUEUED_CONTROL_REQUEST 0x02 /**< State where it is known if there is any queued security request or not. */ -/** @} */ - -/** - * @defgroup device_manager_conn_inst_states Connection Manager Connection Instances States. - * @{ - */ -#define STATE_IDLE 0x01 /**< State where connection instance is free. */ -#define STATE_CONNECTED 0x02 /**< State where connection is successfully established. */ -#define STATE_PAIRING 0x04 /**< State where pairing procedure is in progress. This state is used for pairing and bonding, as pairing is needed for both. */ -#define STATE_BONDED 0x08 /**< State where device is bonded. */ -#define STATE_DISCONNECTING 0x10 /**< State where disconnection is in progress, application will be notified first, but no further active procedures on the link. */ -#define STATE_PAIRING_PENDING 0x20 /**< State where pairing request is pending on the link. */ -#define STATE_BOND_INFO_UPDATE 0x40 /**< State where information has been updated, update the flash. */ -#define STATE_LINK_ENCRYPTED 0x80 /**< State where link is encrypted. */ -/** @} */ - -/** - * @defgroup device_manager_peer_id_defines Peer Identification Information Defines. - * - * @brief These defines are used to know which of the peer identification is applicable for a peer. - * - * @details These defines are used for peer identification. Here, bit map is used because it is - * possible that the application has both IRK and address for identification. - * @{ - */ -#define UNASSIGNED 0xFF /**< Peer instance is unassigned/unused. */ -#define IRK_ENTRY 0x01 /**< Peer instance has IRK as identification information. */ -#define ADDR_ENTRY 0x02 /**< Peer instance has address as identification information. */ -#define SERVICE_CONTEXT_ENTRY 0x04 /**< Peer instance has service context set. */ -#define APP_CONTEXT_ENTRY 0x08 /**< Peer instance has an application context set. */ -/** @} */ - -/**@brief Device store state identifiers. */ -typedef enum -{ - STORE_ALL_CONTEXT, /**< Store all context. */ - FIRST_BOND_STORE, /**< Store bond. */ - UPDATE_PEER_ADDR /**< Update peer address. */ -} device_store_state_t; - -/** - * @defgroup device_manager_context_offsets Context Offsets - * @{ - * - * @brief Context offsets each of the context information in persistent memory. - * - * @details Below is a layout showing how each how the context information is stored in persistent - * memory. - * - * All Device context is stored in the flash as follows: - * +---------+---------+---------+------------------+----------------+--------------------+ - * | Block / Device ID + Layout of stored information in storage block | - * +---------+---------+---------+------------------+----------------+--------------------+ - * | Block 0 | Device 0| Peer Id | Bond Information | Service Context| Application Context| - * +---------+---------+---------+------------------+----------------+--------------------+ - * | Block 1 | Device 1| Peer Id | Bond Information | Service Context| Application Context| - * +---------+---------+---------+------------------+----------------+--------------------+ - * | ... | .... | - * +---------+---------+---------+------------------+----------------+--------------------+ - * | Block N | Device N| Peer Id | Bond Information | Service Context| Application Context| - * +---------+---------+---------+------------------+----------------+--------------------+ - * - * The following defines are used to get offset of each of the components within a block. - */ - -#define PEER_ID_STORAGE_OFFSET 0 /**< Offset at which peer id is stored in the block. */ -#define BOND_STORAGE_OFFSET PEER_ID_SIZE /**< Offset at which bond information is stored in the block. */ -#define SERVICE_STORAGE_OFFSET (BOND_STORAGE_OFFSET + BOND_SIZE) /**< Offset at which service context is stored in the block. */ -#define APP_CONTEXT_STORAGE_OFFSET (SERVICE_STORAGE_OFFSET + SERVICE_CONTEXT_SIZE) /**< Offset at which application context is stored in the block. */ -/** @} */ - -/** - * @defgroup device_manager_context_size Context size. - * @{ - * - * @brief This group defines the size of each of the context information. - */ -#define PEER_ID_SIZE (sizeof(peer_id_t)) /**< Size of peer identification information. */ -#define BOND_SIZE (sizeof(bond_context_t)) /**< Size of bond information. */ -#define DEVICE_CONTEXT_SIZE (PEER_ID_SIZE + BOND_SIZE) /**< Size of Device context, include peer identification and bond information. */ -#define GATTS_SERVICE_CONTEXT_SIZE (sizeof(dm_gatts_context_t)) /**< Size of GATTS service context. */ -#define GATTC_SERVICE_CONTEXT_SIZE (sizeof(dm_gatt_client_context_t)) /**< Size of GATTC service context. */ -#define SERVICE_CONTEXT_SIZE (GATTS_SERVICE_CONTEXT_SIZE + GATTC_SERVICE_CONTEXT_SIZE) /**< Combined size of GATTS and GATTC service contexts. */ -#define APP_CONTEXT_MIN_SIZE 4 /**< Minimum size for application context data. */ -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) -#define APP_CONTEXT_SIZE (sizeof(uint32_t) + DEVICE_MANAGER_APP_CONTEXT_SIZE) /**< Size of application context including length field. */ -#else //DEVICE_MANAGER_APP_CONTEXT_SIZE -#define APP_CONTEXT_SIZE 0 /**< Size of application context. */ -#endif // DEVICE_MANAGER_APP_CONTEXT_SIZE -#define ALL_CONTEXT_SIZE (DEVICE_CONTEXT_SIZE + SERVICE_CONTEXT_SIZE + APP_CONTEXT_SIZE) /**< Size of all contexts. */ -/** @} */ - - -/** - * @defgroup device_manager_log Module's Log Macros - * - * @details Macros used for creating module logs which can be useful in understanding handling - * of events or actions on API requests. These are intended for debugging purposes and - * can be disabled by defining the DM_DISABLE_LOGS. - * - * @note That if ENABLE_DEBUG_LOG_SUPPORT is disabled, having DM_DISABLE_LOGS has no effect. - * @{ - */ -#define nDM_DISABLE_LOGS /**< Enable this macro to disable any logs from this module. */ - -#ifndef DM_DISABLE_LOGS -#define DM_LOG app_trace_log /**< Used for logging details. */ -#define DM_ERR app_trace_log /**< Used for logging errors in the module. */ -#define DM_TRC app_trace_log /**< Used for getting trace of execution in the module. */ -#define DM_DUMP app_trace_dump /**< Used for dumping octet information to get details of bond information etc. */ -#else //DM_DISABLE_LOGS -#define DM_DUMP(...) /**< Disables dumping of octet streams. */ -#define DM_LOG(...) /**< Disables detailed logs. */ -#define DM_ERR(...) /**< Disables error logs. */ -#define DM_TRC(...) /**< Disables traces. */ -#endif //DM_DISABLE_LOGS -/** @} */ - -/** - * @defgroup device_manager_mutex_lock_unlock Module's Mutex Lock/Unlock Macros. - * - * @details Macros used to lock and unlock modules. Currently the SDK does not use mutexes but - * framework is provided in case need arises to use an alternative architecture. - * @{ - */ -#define DM_MUTEX_LOCK() SDK_MUTEX_LOCK(m_dm_mutex) /**< Lock module using mutex. */ -#define DM_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_dm_mutex) /**< Unlock module using mutex. */ -/** @} */ - - -/** - * @defgroup device_manager_misc_defines Miscellaneous defines used across the module. - * @{ - */ -#define DM_GATT_ATTR_SIZE 4 /**< Size of each GATT attribute to be stored persistently. */ -#define DM_GATT_SERVER_ATTR_MAX_SIZE ((DM_GATT_ATTR_SIZE * DM_GATT_CCCD_COUNT) + 2) /**< Maximum size of GATT attributes to be stored.*/ -#define DM_SERVICE_CONTEXT_COUNT (DM_PROTOCOL_CNTXT_ALL + 1) /**< Maximum number of service contexts. */ -#define DM_EVT_DEVICE_CONTEXT_BASE 0x20 /**< Base for device context base. */ -#define DM_EVT_SERVICE_CONTEXT_BASE 0x30 /**< Base for service context base. */ -#define DM_EVT_APP_CONTEXT_BASE 0x40 /**< Base for application context base. */ -#define DM_LOAD_OPERATION_ID 0x01 /**< Load operation identifier. */ -#define DM_STORE_OPERATION_ID 0x02 /**< Store operation identifier. */ -#define DM_CLEAR_OPERATION_ID 0x03 /**< Clear operation identifier. */ -/** @} */ - -#define DM_GATTS_INVALID_SIZE 0xFFFFFFFF /**< Identifer for GATTS invalid size. */ - -/** - * @defgroup api_param_check API Parameters check macros. - * - * @details Macros for verifying parameters passed to the module in the APIs. These macros - * could be mapped to nothing in the final version of the code in order to save execution - * time and program size. - * @{ - */ - -//#define DM_DISABLE_API_PARAM_CHECK /**< Macro to disable API parameters check. */ - -#ifndef DM_DISABLE_API_PARAM_CHECK - -/**@brief Macro for verifying NULL parameters are not passed to API. - * - * @param[in] PARAM Parameter checked for NULL. - * - * @retval (NRF_ERROR_NULL | DEVICE_MANAGER_ERR_BASE) when @ref PARAM is NULL. - */ -#define NULL_PARAM_CHECK(PARAM) \ - if ((PARAM) == NULL) \ - { \ - return (NRF_ERROR_NULL | DEVICE_MANAGER_ERR_BASE); \ - } -/**@} */ - - -/**@brief Macro for verifying module's initialization status. - * - * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when module is not initialized. - */ -#define VERIFY_MODULE_INITIALIZED() \ - do \ - { \ - if (!m_module_initialized) \ - { \ - return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \ - } \ - } while (0) - - -/**@brief Macro for verifying module's initialization status. Returns in case it is not initialized. - */ -#define VERIFY_MODULE_INITIALIZED_VOID() \ - do \ - { \ - if (!m_module_initialized) \ - { \ - return; \ - } \ - } while (0) - - -/**@brief Macro for verifying that the application is registered. - * - * @param[in] X Application instance identifier. - * - * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when module API is called without - * registering an application with the module. - */ -#define VERIFY_APP_REGISTERED(X) \ - do \ - { \ - if (((X) >= DEVICE_MANAGER_MAX_APPLICATIONS) || \ - (m_application_table[(X)].ntf_cb == NULL)) \ - { \ - return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \ - } \ - } while (0) - - -/**@brief Macro for verifying that the application is registered. Returns in case it is not - * registered. - * - * @param[in] X Application instance identifier. - */ -#define VERIFY_APP_REGISTERED_VOID(X) \ - do \ - { \ - if (((X) >= DEVICE_MANAGER_MAX_APPLICATIONS) || \ - (m_application_table[(X)].ntf_cb == NULL)) \ - { \ - return; \ - } \ - } while (0) - - -/**@brief Macro for verifying connection instance is allocated. - * - * @param[in] X Connection instance identifier. - * - * @retval (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE) when connection instance is not - * allocated. - */ -#define VERIFY_CONNECTION_INSTANCE(X) \ - do \ - { \ - if (((X) >= DEVICE_MANAGER_MAX_CONNECTIONS) || \ - (m_connection_table[(X)].state == STATE_IDLE)) \ - { \ - return (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE); \ - } \ - } while (0) - - -/**@brief Macro for verifying if device instance is allocated. - * - * @param[in] X Device instance identifier. - * - * @retval (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE) when device instance is not allocated. - */ -#define VERIFY_DEVICE_INSTANCE(X) \ - do \ - { \ - if (((X) >= DEVICE_MANAGER_MAX_BONDS) || \ - (m_peer_table[(X)].id_bitmap == UNASSIGNED)) \ - { \ - return (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE); \ - } \ - } while (0) -#else -#define NULL_PARAM_CHECK(X) -#define VERIFY_MODULE_INITIALIZED() -#define VERIFY_MODULE_INITIALIZED_VOID() -#define VERIFY_APP_REGISTERED(X) -#define VERIFY_APP_REGISTERED_VOID(X) -#define VERIFY_CONNECTION_INSTANCE(X) -#define VERIFY_DEVICE_INSTANCE(X) -#endif //DM_DISABLE_API_PARAM_CHECK -/** @} */ - -#define INVALID_CONTEXT_LEN 0xFFFFFFFF /**< Identifier for invalid context length. */ -/**@brief Macro for checking that application context size is greater that minimal size. - * - * @param[in] X Size of application context. - * - * @retval (NRF_ERROR_INVALID_PARAM) when size is smaller than minimun required size. - */ -#define SIZE_CHECK_APP_CONTEXT(X) \ - if ((X) < (APP_CONTEXT_MIN_SIZE)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - - -/** - * @defgroup dm_data_types Module's internal data types. - * - * @brief This section describes a module's internal data structures. - * @{ - */ -/**@brief Peer identification information. - */ -typedef struct -{ - ble_gap_id_key_t peer_id; /**< IRK and/or address of peer. */ - uint8_t id_bitmap; /**< Contains information if above field is valid. */ -} peer_id_t; - -STATIC_ASSERT(sizeof(peer_id_t) % 4 == 0); /**< Check to ensure Peer identification information is a multiple of 4. */ - -/**@brief Portion of bonding information exchanged by a device during bond creation that needs to - * be stored persistently. - * - * @note An entry is not made in this table unless device is bonded. - */ -typedef struct -{ - ble_gap_enc_key_t peer_enc_key; /**< Local LTK info, central IRK and address */ -} bond_context_t; - -STATIC_ASSERT(sizeof(bond_context_t) % 4 == 0); /**< Check to ensure bond information is a multiple of 4. */ - -/**@brief GATT Server Attributes size and data. - */ -typedef struct -{ - uint32_t size; /**< Size of stored attributes. */ - uint8_t attributes[DM_GATT_SERVER_ATTR_MAX_SIZE]; /**< Array to hold the server attributes. */ -} dm_gatts_context_t; - -STATIC_ASSERT(sizeof(dm_gatts_context_t) % 4 == 0); /**< Check to ensure GATT Server Attributes size and data information is a multiple of 4. */ - -/**@brief GATT Client context information. Placeholder for now. - */ -typedef struct -{ - void * p_dummy; /**< Placeholder, currently unused. */ -} dm_gatt_client_context_t; - -STATIC_ASSERT(sizeof(dm_gatt_client_context_t) % 4 == 0); /**< Check to ensure GATT Client context information is a multiple of 4. */ -STATIC_ASSERT((DEVICE_MANAGER_APP_CONTEXT_SIZE % 4) == 0); /**< Check to ensure device manager application context information is a multiple of 4. */ - -/**@brief Connection instance definition. Maintains information with respect to an active peer. - */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Peer identification information. This information is retained as long as the connection session exists, once disconnected, for non-bonded devices this information is not stored persistently. */ - uint16_t conn_handle; /**< Connection handle for the device. */ - uint8_t state; /**< Link state. */ - uint8_t bonded_dev_id; /**< In case the device is bonded, this points to the corresponding bonded device. This index can be used to index service and bond context as well. */ -} connection_instance_t; - -/**@brief Application instance definition. Maintains information with respect to a registered - * application. - */ -typedef struct -{ - dm_event_cb_t ntf_cb; /**< Callback registered with the application. */ - ble_gap_sec_params_t sec_param; /**< Local security parameters registered by the application. */ - uint8_t state; /**< Application state. Currently this is used only for knowing if any security procedure is in progress and/or a security procedure is pending to be requested. */ - uint8_t service; /**< Service registered by the application. */ -} application_instance_t; - -/**@brief Function for performing necessary action of storing each of the service context as - * registered by the application. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is stored. - * - * @retval Operation result code. - */ -typedef ret_code_t (* service_context_access_t)(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -/**@brief Function for performing necessary action of applying the context information. - * - * @param[in] p_handle Device handle identifying device that is stored. - * - * @retval Operation result code. - */ -typedef ret_code_t (* service_context_apply_t)(dm_handle_t * p_handle); - -/**@brief Function for performing necessary functions of storing or updating. - * - * @param[in] p_dest Destination address where data is stored persistently. - * @param[in] p_src Source address containing data to be stored. - * @param[in] size Size of data to be stored expressed in bytes. Must be word aligned. - * @param[in] offset Offset in bytes to be applied when writing to the block. - * - * @retval Operation result code. - */ -typedef uint32_t (* storage_operation)(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset); -/** @} */ - -/** - * @defgroup dm_tables Module's internal tables. - * - * @brief This section describes the module's internal tables and the static global variables - * needed for its functionality. - * @{ - */ -#if(DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) -static uint8_t * m_app_context_table[DEVICE_MANAGER_MAX_BONDS]; /**< Table to remember application contexts of bonded devices. */ -#endif // DEVICE_MANAGER_APP_CONTEXT_SIZE -static peer_id_t m_peer_table[DEVICE_MANAGER_MAX_BONDS]; /**< Table to maintain bonded devices' identification information, an instance is allocated in the table when a device is bonded and freed when bond information is deleted. */ -static bond_context_t m_bond_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table to maintain bond information for active peers. */ -static dm_gatts_context_t m_gatts_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table for service information for active connection instances. */ -static connection_instance_t m_connection_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table to maintain active peer information. An instance is allocated in the table when a new connection is established and freed on disconnection. */ -static application_instance_t m_application_table[DEVICE_MANAGER_MAX_APPLICATIONS]; /**< Table to maintain application instances. */ -static pstorage_handle_t m_storage_handle; /**< Persistent storage handle for blocks requested by the module. */ -static uint32_t m_peer_addr_update; /**< 32-bit bitmap to remember peer device address update. */ -static ble_gap_id_key_t m_local_id_info; /**< ID information of central in case resolvable address is used. */ -static bool m_module_initialized = false; /**< State indicating if module is initialized or not. */ - -SDK_MUTEX_DEFINE(m_dm_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */ -/** @} */ - -static __INLINE ret_code_t no_service_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gatts_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gattc_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gattsc_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t no_service_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gatts_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gattc_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gattsc_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t no_service_context_apply(dm_handle_t * p_handle); - -static __INLINE ret_code_t gatts_context_apply(dm_handle_t * p_handle); - -static __INLINE ret_code_t gattc_context_apply(dm_handle_t * p_handle); - -static __INLINE ret_code_t gattsc_context_apply(dm_handle_t * p_handle); - - -/**< Array of function pointers based on the types of service registered. */ -const service_context_access_t m_service_context_store[DM_SERVICE_CONTEXT_COUNT] = -{ - no_service_context_store, /**< Dummy function, when there is no service context registered. */ - gatts_context_store, /**< GATT Server context store function. */ - gattc_context_store, /**< GATT Client context store function. */ - gattsc_context_store /**< GATT Server & Client context store function. */ -}; - - -/**< Array of function pointers based on the types of service registered. */ -const service_context_access_t m_service_context_load[DM_SERVICE_CONTEXT_COUNT] = -{ - no_service_context_load, /**< Dummy function, when there is no service context registered. */ - gatts_context_load, /**< GATT Server context load function. */ - gattc_context_load, /**< GATT Client context load function. */ - gattsc_context_load /**< GATT Server & Client context load function. */ -}; - - -/**< Array of function pointers based on the types of service registered. */ -const service_context_apply_t m_service_context_apply[DM_SERVICE_CONTEXT_COUNT] = -{ - no_service_context_apply, /**< Dummy function, when there is no service context registered. */ - gatts_context_apply, /**< GATT Server context apply function. */ - gattc_context_apply, /**< GATT Client context apply function. */ - gattsc_context_apply /**< GATT Server & Client context apply function. */ -}; - - -const uint32_t m_context_init_len = 0xFFFFFFFF; /**< Constant used to update the initial value for context in the flash. */ - -/**@brief Function for setting update status for the device identified by 'index'. - * - * @param[in] index Device identifier. - */ -static __INLINE void update_status_bit_set(uint32_t index) -{ - m_peer_addr_update |= (BIT_0 << index); -} - - -/**@brief Function for resetting update status for device identified by 'index'. - * - * @param[in] index Device identifier. - */ -static __INLINE void update_status_bit_reset(uint32_t index) -{ - m_peer_addr_update &= (~((uint32_t)BIT_0 << index)); -} - - -/**@brief Function for providing update status for the device identified by 'index'. - * - * @param[in] index Device identifier. - * - * @retval true if the bit is set, false otherwise. - */ -static __INLINE bool update_status_bit_is_set(uint32_t index) -{ - return ((m_peer_addr_update & (BIT_0 << index)) ? true : false); -} - - -/**@brief Function for initialiasing the application instance identified by 'index'. - * - * @param[in] index Device identifier. - */ -static __INLINE void application_instance_init(uint32_t index) -{ - DM_TRC("[DM]: Initializing Application Instance 0x%08X.\r\n", index); - - m_application_table[index].ntf_cb = NULL; - m_application_table[index].state = 0x00; - m_application_table[index].service = 0x00; -} - - -/**@brief Function for initialiasing the connection instance identified by 'index'. - * - * @param[in] index Device identifier. - */ -static __INLINE void connection_instance_init(uint32_t index) -{ - DM_TRC("[DM]: Initializing Connection Instance 0x%08X.\r\n", index); - - m_connection_table[index].state = STATE_IDLE; - m_connection_table[index].conn_handle = BLE_CONN_HANDLE_INVALID; - m_connection_table[index].bonded_dev_id = DM_INVALID_ID; - - memset(&m_connection_table[index].peer_addr, 0, sizeof (ble_gap_addr_t)); -} - - -/**@brief Function for initialiasing the peer device instance identified by 'index'. - * - * @param[in] index Device identifier. - */ -static __INLINE void peer_instance_init(uint32_t index) -{ - DM_TRC("[DM]: Initializing Peer Instance 0x%08X.\r\n", index); - - memset(m_peer_table[index].peer_id.id_addr_info.addr, 0, BLE_GAP_ADDR_LEN); - memset(m_peer_table[index].peer_id.id_info.irk, 0, BLE_GAP_SEC_KEY_LEN); - - //Initialize the address type to invalid. - m_peer_table[index].peer_id.id_addr_info.addr_type = INVALID_ADDR_TYPE; - - //Initialize the identification bit map to unassigned. - m_peer_table[index].id_bitmap = UNASSIGNED; - - //Reset the status bit. - update_status_bit_reset(index); - -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) - //Initialize the application context for bond device. - m_app_context_table[index] = NULL; -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE -} - - -/**@brief Function for searching connection instance matching the connection handle and the state - * requested. - * - * @details Connection handle and state information is used to get a connection instance, it - * is possible to ignore the connection handle by using BLE_CONN_HANDLE_INVALID. - * - * @param[in] conn_handle Connection handle. - * @param[in] state Connection instance state. - * @param[out] p_instance Connection instance. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. Invalid state - * @retval NRF_ERROR_NOT_FOUND Operation failure. Not found - */ -static ret_code_t connection_instance_find(uint16_t conn_handle, - uint8_t state, - uint32_t * p_instance) -{ - ret_code_t err_code; - uint32_t index; - - err_code = NRF_ERROR_INVALID_STATE; - - for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++) - { - //Search only based on the state. - if (state & m_connection_table[index].state) - { - //Ignore the connection handle. - if ((conn_handle == BLE_CONN_HANDLE_INVALID) || - (conn_handle == m_connection_table[index].conn_handle)) - { - //Search for matching connection handle. - (*p_instance) = index; - err_code = NRF_SUCCESS; - - break; - } - else - { - err_code = NRF_ERROR_NOT_FOUND; - } - } - } - - return err_code; -} - - -/**@brief Function for allocating device instance for a bonded device. - * - * @param[out] p_device_index Device index. - * @param[in] p_addr Peer identification information. - * - * @retval NRF_SUCCESS Operation success. - * @retval DM_DEVICE_CONTEXT_FULL Operation failure. - */ -static __INLINE ret_code_t device_instance_allocate(uint8_t * p_device_index, - ble_gap_addr_t const * p_addr) -{ - ret_code_t err_code; - uint32_t index; - - err_code = DM_DEVICE_CONTEXT_FULL; - - for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - DM_TRC("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n", - index, m_peer_table[index].peer_id.id_addr_info.addr_type); - DM_TRC("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n", - m_peer_table[index].peer_id.id_addr_info.addr[0], - m_peer_table[index].peer_id.id_addr_info.addr[1], - m_peer_table[index].peer_id.id_addr_info.addr[2], - m_peer_table[index].peer_id.id_addr_info.addr[3], - m_peer_table[index].peer_id.id_addr_info.addr[4], - m_peer_table[index].peer_id.id_addr_info.addr[5]); - - if (m_peer_table[index].id_bitmap == UNASSIGNED) - { - if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE) - { - m_peer_table[index].id_bitmap &= (~ADDR_ENTRY); - m_peer_table[index].peer_id.id_addr_info = (*p_addr); - } - else - { - m_peer_table[index].id_bitmap &= (~IRK_ENTRY); - } - - (*p_device_index) = index; - err_code = NRF_SUCCESS; - - DM_LOG("[DM]: Allocated device instance 0x%02X\r\n", index); - - break; - } - } - - return err_code; -} - - -/**@brief Function for freeing a device instance allocated for bonded device. - * - * @param[in] device_index Device index. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - */ -static __INLINE ret_code_t device_instance_free(uint32_t device_index) -{ - ret_code_t err_code; - pstorage_handle_t block_handle; - - //Get the block handle. - err_code = pstorage_block_identifier_get(&m_storage_handle, device_index, &block_handle); - - if (err_code == NRF_SUCCESS) - { - DM_TRC("[DM]:[DI 0x%02X]: Freeing Instance.\r\n", device_index); - - //Request clearing of the block. - err_code = pstorage_clear(&block_handle, ALL_CONTEXT_SIZE); - - if (err_code == NRF_SUCCESS) - { - peer_instance_init(device_index); - } - } - - return err_code; -} - - -/**@brief Function for searching for the device in the bonded device list. - * - * @param[in] p_addr Peer identification information. - * @param[out] p_device_index Device index. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_NOT_FOUND Operation failure. - */ -static ret_code_t device_instance_find(ble_gap_addr_t const * p_addr, uint32_t * p_device_index) -{ - ret_code_t err_code; - uint32_t index; - - err_code = NRF_ERROR_NOT_FOUND; - - DM_TRC("[DM]: Searching for device 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n", - p_addr->addr[0], - p_addr->addr[1], - p_addr->addr[2], - p_addr->addr[3], - p_addr->addr[4], - p_addr->addr[5]); - - for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - DM_TRC("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n", - index, m_peer_table[index].peer_id.id_addr_info.addr_type); - DM_TRC("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n", - m_peer_table[index].peer_id.id_addr_info.addr[0], - m_peer_table[index].peer_id.id_addr_info.addr[1], - m_peer_table[index].peer_id.id_addr_info.addr[2], - m_peer_table[index].peer_id.id_addr_info.addr[3], - m_peer_table[index].peer_id.id_addr_info.addr[4], - m_peer_table[index].peer_id.id_addr_info.addr[5]); - - if (memcmp(&m_peer_table[index].peer_id.id_addr_info, p_addr, sizeof(ble_gap_addr_t)) == 0) - { - DM_LOG("[DM]: Found device at instance 0x%02X\r\n", index); - - (*p_device_index) = index; - err_code = NRF_SUCCESS; - - break; - } - } - - return err_code; -} - - -/**@brief Function for notifying connection manager event to the application. - * - * @param[in] p_handle Device handle identifying device. - * @param[in] p_event Connection manager event details. - * @param[in] event_result Event result code. - */ -static __INLINE void app_evt_notify(dm_handle_t const * const p_handle, - dm_event_t const * const p_event, - uint32_t event_result) -{ - dm_event_cb_t app_cb = m_application_table[0].ntf_cb; - - DM_MUTEX_UNLOCK(); - - DM_TRC("[DM]: Notifying application of event 0x%02X\r\n", p_event->event_id); - - //No need to do any kind of return value processing thus can be supressed. - UNUSED_VARIABLE(app_cb(p_handle, p_event, event_result)); - - DM_MUTEX_LOCK(); -} - - -/**@brief Function for allocating instance. - * - * @details The instance identifier is provided in the 'p_instance' parameter if the routine - * succeeds. - * - * @param[out] p_instance Connection instance. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_NO_MEM Operation failure. No memory. - */ -static __INLINE uint32_t connection_instance_allocate(uint32_t * p_instance) -{ - uint32_t err_code; - - DM_TRC("[DM]: Request to allocation connection instance\r\n"); - - err_code = connection_instance_find(BLE_CONN_HANDLE_INVALID, STATE_IDLE, p_instance); - - if (err_code == NRF_SUCCESS) - { - DM_LOG("[DM]:[%02X]: Connection Instance Allocated.\r\n", (*p_instance)); - m_connection_table[*p_instance].state = STATE_CONNECTED; - } - else - { - DM_LOG("[DM]: No free connection instances available\r\n"); - err_code = NRF_ERROR_NO_MEM; - } - - return err_code; -} - - -/**@brief Function for freeing instance. Instance identifier is provided in the parameter - * 'p_instance' in case the routine succeeds. - * - * @param[in] p_instance Connection instance. - */ -static __INLINE void connection_instance_free(uint32_t const * p_instance) -{ - DM_TRC("[DM]:[CI 0x%02X]: Freeing connection instance\r\n", (*p_instance)); - - if (m_connection_table[*p_instance].state != STATE_IDLE) - { - DM_LOG("[DM]:[%02X]: Freed connection instance.\r\n", (*p_instance)); - connection_instance_init(*p_instance); - } -} - - -/**@brief Function for storage operation dummy handler. - * - * @param[in] p_dest Destination address where data is to be stored persistently. - * @param[in] p_src Source address containing data to be stored. API assumes this to be resident - * memory and no intermediate copy of data is made by the API. - * @param[in] size Size of data to be stored expressed in bytes. Should be word aligned. - * @param[in] offset Offset in bytes to be applied when writing to the block. - * For example, if within a block of 100 bytes, application wishes to - * write 20 bytes at offset of 12, then this field should be set to 12. - * Should be word aligned. - * - * @retval NRF_SUCCESS Operation success. - */ -static uint32_t storage_operation_dummy_handler(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset) -{ - return NRF_SUCCESS; -} - - -/**@brief Function for saving the device context persistently. - * - * @param[in] p_handle Device handle identifying device. - * @param[in] state Device store state. - */ -static __INLINE void device_context_store(dm_handle_t const * p_handle, device_store_state_t state) -{ - pstorage_handle_t block_handle; - storage_operation store_fn; - ret_code_t err_code; - - DM_LOG("[DM]: --> device_context_store\r\n"); - - err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - if (err_code == NRF_SUCCESS) - { - if ((STATE_BOND_INFO_UPDATE == - (m_connection_table[p_handle->connection_id].state & STATE_BOND_INFO_UPDATE)) || - (state == UPDATE_PEER_ADDR)) - { - DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> Updating bonding information.\r\n", - p_handle->device_id, p_handle->connection_id); - - store_fn = pstorage_update; - } - else if (state == FIRST_BOND_STORE) - { - DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> Storing bonding information.\r\n", - p_handle->device_id, p_handle->connection_id); - - store_fn = pstorage_store; - } - else - { - DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> No update in bonding information.\r\n", - p_handle->device_id, p_handle->connection_id); - - //No operation needed. - store_fn = storage_operation_dummy_handler; - } - - //Store the peer id. - err_code = store_fn(&block_handle, - (uint8_t *)&m_peer_table[p_handle->device_id], - PEER_ID_SIZE, - PEER_ID_STORAGE_OFFSET); - - if ((err_code == NRF_SUCCESS) && (state != UPDATE_PEER_ADDR)) - { - m_connection_table[p_handle->connection_id].state &= (~STATE_BOND_INFO_UPDATE); - - //Store the bond information. - err_code = store_fn(&block_handle, - (uint8_t *)&m_bond_table[p_handle->connection_id], - BOND_SIZE, - BOND_STORAGE_OFFSET); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]:[0x%02X]:Failed to store bond information, reason 0x%08X\r\n", - p_handle->device_id, err_code); - } - } - - if (state != UPDATE_PEER_ADDR) - { - //Store the service information - err_code = m_service_context_store[m_application_table[p_handle->appl_id].service] - ( - &block_handle, - p_handle - ); - - if (err_code != NRF_SUCCESS) - { - //Notify application of an error event. - DM_ERR("[DM]: Failed to store service context, reason %08X\r\n", err_code); - } - } - } - - if (err_code != NRF_SUCCESS) - { - //Notify application of an error event. - DM_ERR("[DM]: Failed to store device context, reason %08X\r\n", err_code); - } -} - - -/**@brief Function for storing when there is no service registered. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is loaded. - * - * @retval NRF_SUCCESS - */ -static __INLINE ret_code_t no_service_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> no_service_context_store\r\n"); - - return NRF_SUCCESS; -} - - -/**@brief Function for storing GATT Server context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is stored. - * - * @retval NRF_SUCCESS Operation success. - */ -static __INLINE ret_code_t gatts_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - storage_operation store_fn; - uint16_t attr_len = DM_GATT_SERVER_ATTR_MAX_SIZE; - uint8_t sys_data[DM_GATT_SERVER_ATTR_MAX_SIZE]; - - DM_LOG("[DM]: --> gatts_context_store\r\n"); - - uint32_t err_code = sd_ble_gatts_sys_attr_get( - m_connection_table[p_handle->connection_id].conn_handle, - sys_data, - &attr_len, - BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); - - if (err_code == NRF_SUCCESS) - { - if (memcmp(m_gatts_table[p_handle->connection_id].attributes, sys_data, attr_len) == 0) - { - //No store operation is needed. - DM_LOG("[DM]:[0x%02X]: No change in GATTS Context information.\r\n", - p_handle->device_id); - - if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) != - STATE_CONNECTED) - { - DM_LOG("[DM]:[0x%02X]: Resetting GATTS for active instance.\r\n", - p_handle->connection_id); - - //Reset GATTS information for the current context. - memset(&m_gatts_table[p_handle->connection_id], 0, sizeof(dm_gatts_context_t)); - } - } - else - { - if (m_gatts_table[p_handle->connection_id].size != 0) - { - //There is data already stored in persistent memory, therefore an update is needed. - DM_LOG("[DM]:[0x%02X]: Updating stored service context\r\n", p_handle->device_id); - - store_fn = pstorage_update; - } - else - { - //Fresh write, a store is needed. - DM_LOG("[DM]:[0x%02X]: Storing service context\r\n", p_handle->device_id); - - store_fn = pstorage_store; - } - - m_gatts_table[p_handle->connection_id].size = attr_len; - memcpy(m_gatts_table[p_handle->connection_id].attributes, sys_data, attr_len); - - DM_DUMP((uint8_t *)&m_gatts_table[p_handle->connection_id], sizeof(dm_gatts_context_t)); - - DM_LOG("[DM]:[0x%02X]: GATTS Data size 0x%08X\r\n", - p_handle->device_id, - m_gatts_table[p_handle->connection_id].size); - - //Store GATTS information. - err_code = store_fn((pstorage_handle_t *)p_block_handle, - (uint8_t *)&m_gatts_table[p_handle->connection_id], - GATTS_SERVICE_CONTEXT_SIZE, - SERVICE_STORAGE_OFFSET); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]:[0x%02X]:Failed to store service context, reason 0x%08X\r\n", - p_handle->device_id, - err_code); - } - else - { - DM_LOG("[DM]: Service context successfully stored.\r\n"); - } - } - } - - return NRF_SUCCESS; -} - - -/**@brief Function for storing GATT Client context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is stored. - * - * @retval NRF_SUCCESS Operation success. - */ -static __INLINE ret_code_t gattc_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> gattc_context_store\r\n"); - - return NRF_SUCCESS; -} - - -/**@brief Function for storing GATT Server & Client context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is stored. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - */ -static __INLINE ret_code_t gattsc_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> gattsc_context_store\r\n"); - - ret_code_t err_code = gatts_context_store(p_block_handle, p_handle); - - if (NRF_SUCCESS == err_code) - { - err_code = gattc_context_store(p_block_handle, p_handle); - } - - return err_code; -} - - -/**@brief Function for loading when there is no service registered. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is loaded. - * - * @retval NRF_SUCCESS - */ -static __INLINE ret_code_t no_service_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> no_service_context_load\r\n"); - - return NRF_SUCCESS; -} - - -/**@brief Function for loading GATT Server context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is loaded. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - */ -static __INLINE ret_code_t gatts_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: --> gatts_context_load\r\n", - p_handle->connection_id, - p_handle->device_id); - - ret_code_t err_code = pstorage_load((uint8_t *)&m_gatts_table[p_handle->connection_id], - (pstorage_handle_t *)p_block_handle, - GATTS_SERVICE_CONTEXT_SIZE, - SERVICE_STORAGE_OFFSET); - - if (err_code == NRF_SUCCESS) - { - DM_LOG("[DM]:[%02X]:[Block ID 0x%08X]: Service context loaded, size 0x%08X\r\n", - p_handle->connection_id, - p_block_handle->block_id, - m_gatts_table[p_handle->connection_id].size); - DM_DUMP((uint8_t *)&m_gatts_table[p_handle->connection_id], sizeof(dm_gatts_context_t)); - - if (m_gatts_table[p_handle->connection_id].size == DM_GATTS_INVALID_SIZE) - { - m_gatts_table[p_handle->connection_id].size = 0; - } - } - else - { - DM_ERR("[DM]:[%02X]: Failed to load Service context, reason %08X\r\n", - p_handle->connection_id, - err_code); - } - - return err_code; -} - - -/**@brief Function for loading GATT Client context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is loaded. - * - * @retval NRF_SUCCESS - */ -static __INLINE ret_code_t gattc_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> gattc_context_load\r\n"); - - return NRF_SUCCESS; -} - - -/**@brief Function for loading GATT Server & Client context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is loaded. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - */ -static __INLINE ret_code_t gattsc_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> gattsc_context_load\r\n"); - - ret_code_t err_code = gatts_context_load(p_block_handle, p_handle); - - if (NRF_SUCCESS == err_code) - { - err_code = gattc_context_load(p_block_handle, p_handle); - } - - return err_code; -} - - -/**@brief Function for applying when there is no service registered. - * - * @param[in] p_handle Device handle identifying device that is applied. - * - * @retval NRF_SUCCESS - */ -static __INLINE ret_code_t no_service_context_apply(dm_handle_t * p_handle) -{ - DM_LOG("[DM]: --> no_service_context_apply\r\n"); - DM_LOG("[DM]:[CI 0x%02X]: No Service context\r\n", p_handle->connection_id); - - return NRF_SUCCESS; -} - - -/**@brief Function for applying GATT Server context. - * - * @param[in] p_handle Device handle identifying device that is applied. - * - * @retval NRF_SUCCESS On success. - * @retval DM_SERVICE_CONTEXT_NOT_APPLIED On failure. - */ -static __INLINE ret_code_t gatts_context_apply(dm_handle_t * p_handle) -{ - uint32_t err_code; - - uint8_t * p_gatts_context = NULL; - uint16_t context_len = 0; - - DM_LOG("[DM]: --> gatts_context_apply\r\n"); - DM_LOG("[DM]:[CI 0x%02X]: State 0x%02X, Size 0x%08X\r\n", - p_handle->connection_id, - m_connection_table[p_handle->connection_id].state, - m_gatts_table[p_handle->connection_id].size); - - if ((m_gatts_table[p_handle->connection_id].size != 0) && - ( - ((m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED) && - ((m_connection_table[p_handle->connection_id].state & STATE_BOND_INFO_UPDATE) - != STATE_BOND_INFO_UPDATE) - ) - ) - { - DM_LOG("[DM]: Setting stored context.\r\n"); - - p_gatts_context = &m_gatts_table[p_handle->connection_id].attributes[0]; - context_len = m_gatts_table[p_handle->connection_id].size; - } - - err_code = sd_ble_gatts_sys_attr_set(m_connection_table[p_handle->connection_id].conn_handle, - p_gatts_context, - context_len, - BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); - - if (err_code != NRF_SUCCESS) - { - DM_LOG("[DM]: Failed to set system attributes, reason 0x%08X.\r\n", err_code); - - err_code = DM_SERVICE_CONTEXT_NOT_APPLIED; - } - - return err_code; -} - - -/**@brief Function for applying GATT Client context. - * - * @param[in] p_handle Device handle identifying device that is applied. - * - * @retval NRF_SUCCESS On success. - */ -static __INLINE ret_code_t gattc_context_apply(dm_handle_t * p_handle) -{ - DM_LOG("[DM]: --> gattc_context_apply\r\n"); - - return NRF_SUCCESS; -} - - -/**@brief Function for applying GATT Server & Client context. - * - * @param[in] p_handle Device handle identifying device that is applied. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - */ -static __INLINE ret_code_t gattsc_context_apply(dm_handle_t * p_handle) -{ - uint32_t err_code; - - DM_LOG("[DM]: --> gattsc_context_apply\r\n"); - - err_code = gatts_context_apply(p_handle); - - if (err_code == NRF_SUCCESS) - { - err_code = gattc_context_apply(p_handle); - } - - return err_code; -} - - -uint32_t initiate_security_request(const dm_handle_t * p_handle) -{ - uint32_t err_code; - - DM_LOG("[DM]: Initiating authentication request\r\n"); - DM_DUMP((uint8_t *)&m_application_table[p_handle->appl_id].sec_param, - sizeof (ble_gap_sec_params_t)); - - err_code = sd_ble_gap_authenticate(m_connection_table[p_handle->connection_id].conn_handle, - &m_application_table[p_handle->appl_id].sec_param); - - if (err_code == NRF_SUCCESS) - { - m_application_table[p_handle->appl_id].state |= STATE_CONTROL_PROCEDURE_IN_PROGRESS; - m_connection_table[p_handle->connection_id].state |= STATE_PAIRING; - m_connection_table[p_handle->connection_id].state &= (~STATE_PAIRING_PENDING); - } - - return err_code; -} - - -/**@brief Function for pstorage module callback. - * - * @param[in] p_handle Identifies module and block for which callback is received. - * @param[in] op_code Identifies the operation for which the event is notified. - * @param[in] result Identifies the result of flash access operation. - * NRF_SUCCESS implies, operation succeeded. - * @param[in] p_data Identifies the application data pointer. In case of store operation, this - * points to the resident source of application memory that application can now - * free or reuse. In case of clear, this is NULL as no application pointer is - * needed for this operation. - * @param[in] data_len Length of data provided by the application for the operation. - */ -static void dm_pstorage_cb_handler(pstorage_handle_t * p_handle, - uint8_t op_code, - uint32_t result, - uint8_t * p_data, - uint32_t data_len) -{ - VERIFY_APP_REGISTERED_VOID(0); - - if (data_len > ALL_CONTEXT_SIZE) - { - //Clearing of all bonds at initialization, no event is generated. - return; - } - - DM_MUTEX_LOCK(); - - dm_event_t dm_event; - dm_handle_t dm_handle; - dm_context_t context_data; - pstorage_handle_t block_handle; - uint32_t index_count; - uint32_t err_code; - - bool app_notify = true; - - err_code = dm_handle_initialize(&dm_handle); - APP_ERROR_CHECK(err_code); - - dm_handle.appl_id = 0; - dm_event.event_id = 0x00; - - //Construct the event which it is related to. - - //Initialize context data information and length. - context_data.p_data = p_data; - context_data.len = data_len; - - for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle); - if ((err_code == NRF_SUCCESS) && - ( - (memcmp(p_handle, &block_handle, sizeof(pstorage_handle_t)) == 0) - ) - ) - { - dm_handle.device_id = index; - break; - } - } - - if (dm_handle.device_id != DM_INVALID_ID) - { - if (op_code == PSTORAGE_CLEAR_OP_CODE) - { - if (data_len == ALL_CONTEXT_SIZE) - { - dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE; - } - else - { - dm_event.event_id = DM_EVT_APP_CONTEXT_BASE; - } - } - else - { - //Update or store operation. - //Context is identified based on the pointer value. Device context, application context - //and service context all have their own value range. - index_count = ((uint32_t)(p_data - (uint8_t *)m_peer_table)) / PEER_ID_SIZE; - - if (index_count < DEVICE_MANAGER_MAX_BONDS) - { - dm_event.event_param.p_device_context = &context_data; - - //Only the peer identification is stored, not bond information. Hence do not notify - //the application yet, unless the store operation resulted in a failure. - if ((result == NRF_SUCCESS) && - ( - (update_status_bit_is_set(dm_handle.device_id) == false) - ) - ) - { - app_notify = false; - } - else - { - //Reset update status since update is complete. - update_status_bit_reset(dm_handle.device_id); - - //Notify application of error in storing the context. - dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE; - } - } - else - { - index_count = ((uint32_t)(p_data - (uint8_t *)m_bond_table)) / BOND_SIZE; - - if (index_count < DEVICE_MANAGER_MAX_CONNECTIONS) - { - DM_LOG("[DM]:[0x%02X]:[0x%02X]: Bond context Event\r\n", - dm_handle.device_id, - dm_handle.connection_id); - - dm_event.event_param.p_device_context = &context_data; - dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE; - dm_handle.connection_id = index_count; - - ble_gap_sec_keyset_t keys_exchanged; - keys_exchanged.keys_central.p_enc_key = NULL; - keys_exchanged.keys_central.p_id_key = &m_local_id_info; - keys_exchanged.keys_periph.p_enc_key = &m_bond_table[index_count].peer_enc_key; - keys_exchanged.keys_periph.p_id_key = - &m_peer_table[dm_handle.device_id].peer_id; - - //Context information updated to provide the keys. - context_data.p_data = (uint8_t *)&keys_exchanged; - context_data.len = sizeof(ble_gap_sec_keyset_t); - } - else - { - index_count = ((uint32_t)(p_data - (uint8_t *)m_gatts_table)) / - GATTS_SERVICE_CONTEXT_SIZE; - - if (index_count < DEVICE_MANAGER_MAX_CONNECTIONS) - { - DM_LOG("[DM]:[0x%02X]:[0x%02X]: Service context Event\r\n", - dm_handle.device_id, - dm_handle.connection_id); - - //Notify application. - dm_event.event_id = DM_EVT_SERVICE_CONTEXT_BASE; - dm_handle.connection_id = index_count; - dm_handle.service_id = DM_PROTOCOL_CNTXT_GATT_SRVR_ID; - - //Reset the service context now that it was successfully written to the - //application and the link is disconnected. - if ((m_connection_table[index_count].state & STATE_CONNECTED) != - STATE_CONNECTED) - { - DM_LOG("[DM]:[0x%02X]:[0x%02X]: Resetting bond information for " - "active instance.\r\n", - dm_handle.device_id, - dm_handle.connection_id); - - memset(&m_gatts_table[dm_handle.connection_id], - 0, - sizeof(dm_gatts_context_t)); - } - } - else - { - DM_LOG("[DM]:[0x%02X]:[0x%02X]: App context Event\r\n", - dm_handle.device_id, - dm_handle.connection_id); - - app_notify = false; - dm_event.event_id = DM_EVT_APP_CONTEXT_BASE; -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) - - if (p_data == (uint8_t *)(&m_context_init_len)) - { - //Context data is deleted. - //This is a workaround to get the right event as on delete operation - //update operation is used instead of clear. - op_code = PSTORAGE_CLEAR_OP_CODE; - app_notify = true; - } - else if (m_app_context_table[dm_handle.device_id] == p_data) - { - app_notify = true; - dm_event.event_param.p_app_context = &context_data; - - //Verify if the device is connected, if yes set connection instance. - for (uint32_t index = 0; - index < DEVICE_MANAGER_MAX_CONNECTIONS; - index++) - { - if (dm_handle.device_id == m_connection_table[index].bonded_dev_id) - { - dm_handle.connection_id = index; - break; - } - } - } - else - { - //No implementation needed. - } -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE - } - } - } - } - - if (app_notify == true) - { - if (op_code == PSTORAGE_CLEAR_OP_CODE) - { - dm_event.event_id |= DM_CLEAR_OPERATION_ID; - } - else if (op_code == PSTORAGE_LOAD_OP_CODE) - { - dm_event.event_id |= DM_LOAD_OPERATION_ID; - } - else - { - dm_event.event_id |= DM_STORE_OPERATION_ID; - } - - dm_event.event_param.p_app_context = &context_data; - app_evt_notify(&dm_handle, &dm_event, result); - } - } - - DM_MUTEX_UNLOCK(); -} - - -ret_code_t dm_init(dm_init_param_t const * const p_init_param) -{ - pstorage_module_param_t param; - pstorage_handle_t block_handle; - ret_code_t err_code; - uint32_t index; - - DM_LOG("[DM]: >> dm_init.\r\n"); - - NULL_PARAM_CHECK(p_init_param); - - SDK_MUTEX_INIT(m_dm_mutex); - - DM_MUTEX_LOCK(); - - for (index = 0; index < DEVICE_MANAGER_MAX_APPLICATIONS; index++) - { - application_instance_init(index); - } - - for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++) - { - connection_instance_init(index); - } - - memset(m_gatts_table, 0, sizeof(m_gatts_table)); - - //Initialization of all device instances. - for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - peer_instance_init(index); - } - - //All context with respect to a particular device is stored contiguously. - param.block_size = ALL_CONTEXT_SIZE; - param.block_count = DEVICE_MANAGER_MAX_BONDS; - param.cb = dm_pstorage_cb_handler; - - err_code = pstorage_register(¶m, &m_storage_handle); - - if (err_code == NRF_SUCCESS) - { - m_module_initialized = true; - - if (p_init_param->clear_persistent_data == false) - { - DM_LOG("[DM]: Storage handle 0x%08X.\r\n", m_storage_handle.block_id); - - //Copy bonded peer device address and IRK to RAM table. - - //Bonded devices are stored in range (0,DEVICE_MANAGER_MAX_BONDS-1). The remaining - //range is for active connections that may or may not be bonded. - for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle); - - //Issue read request if you successfully get the block identifier. - if (err_code == NRF_SUCCESS) - { - DM_TRC("[DM]:[0x%02X]: Block handle 0x%08X.\r\n", index, block_handle.block_id); - - err_code = pstorage_load((uint8_t *)&m_peer_table[index], - &block_handle, - sizeof(peer_id_t), - 0); - - if (err_code != NRF_SUCCESS) - { - // In case a peer device could not be loaded successfully, rest of the - // initialization procedure are skipped and an error is sent to the - // application. - DM_ERR( - "[DM]: Failed to load peer device %08X from storage, reason %08X.\r\n", - index, - err_code); - - m_module_initialized = false; - break; - } - else - { - DM_TRC("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n", - index, - m_peer_table[index].peer_id.id_addr_info.addr_type); - DM_TRC("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n", - m_peer_table[index].peer_id.id_addr_info.addr[0], - m_peer_table[index].peer_id.id_addr_info.addr[1], - m_peer_table[index].peer_id.id_addr_info.addr[2], - m_peer_table[index].peer_id.id_addr_info.addr[3], - m_peer_table[index].peer_id.id_addr_info.addr[4], - m_peer_table[index].peer_id.id_addr_info.addr[5]); - } - } - else - { - //In case a peer device could not be loaded successfully, rest of the - //initialization procedure are skipped and an error is sent to the application. - DM_LOG("[DM]: Failed to get block handle for instance %08X, reason %08X.\r\n", - index, - err_code); - - m_module_initialized = false; - break; - } - } - } - else - { - err_code = pstorage_clear(&m_storage_handle, (param.block_size * param.block_count)); - DM_ERR("[DM]: Successfully requested clear of persistent data.\r\n"); - } - } - else - { - DM_ERR("[DM]: Failed to register with storage module, reason 0x%08X.\r\n", err_code); - } - - DM_MUTEX_UNLOCK(); - - DM_TRC("[DM]: << dm_init.\r\n"); - - return err_code; -} - - -ret_code_t dm_register(dm_application_instance_t * p_appl_instance, - dm_application_param_t const * p_appl_param) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_appl_instance); - NULL_PARAM_CHECK(p_appl_param); - NULL_PARAM_CHECK(p_appl_param->evt_handler); - - DM_MUTEX_LOCK(); - - DM_LOG("[DM]: >> dm_register.\r\n"); - - uint32_t err_code; - - //Verify if an application instance is available. Currently only one instance is supported. - if (m_application_table[0].ntf_cb == NULL) - { - DM_LOG("[DM]: Application Instance allocated.\r\n"); - - //Mark instance as allocated. - m_application_table[0].ntf_cb = p_appl_param->evt_handler; - m_application_table[0].sec_param = p_appl_param->sec_param; - m_application_table[0].service = p_appl_param->service_type; - - //Populate application's instance variable with the assigned allocation instance. - *p_appl_instance = 0; - err_code = NRF_SUCCESS; - } - else - { - err_code = (NRF_ERROR_NO_MEM | DEVICE_MANAGER_ERR_BASE); - } - - DM_MUTEX_UNLOCK(); - - DM_TRC("[DM]: << dm_register.\r\n"); - - return err_code; -} - - -ret_code_t dm_security_setup_req(dm_handle_t * p_handle) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_CONNECTION_INSTANCE(p_handle->connection_id); - - DM_MUTEX_LOCK(); - - DM_LOG("[DM]: >> dm_security_setup_req\r\n"); - - uint32_t err_code = (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); - - if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) == STATE_CONNECTED) - { - if ((p_handle->device_id != DM_INVALID_ID) || - (m_connection_table[p_handle->connection_id].bonded_dev_id != DM_INVALID_ID)) - { - p_handle->device_id = m_connection_table[p_handle->connection_id].bonded_dev_id; - - //Already bonded device, encrypt the link. - err_code = sd_ble_gap_encrypt(m_connection_table[p_handle->connection_id].conn_handle, - &m_bond_table[p_handle->connection_id].peer_enc_key.master_id, - &m_bond_table[p_handle->connection_id].peer_enc_key.enc_info); - } - else - { - uint8_t device_index; - - //Request for pairing, allocate a bonded device instance. - err_code = device_instance_allocate(&device_index, - &m_connection_table[p_handle->connection_id].peer_addr); - - if (err_code == NRF_SUCCESS) - { - m_connection_table[p_handle->connection_id].bonded_dev_id = device_index; - p_handle->device_id = device_index; - - if ((m_application_table[p_handle->appl_id].state & - STATE_CONTROL_PROCEDURE_IN_PROGRESS) == STATE_CONTROL_PROCEDURE_IN_PROGRESS) - { - DM_LOG("[DM]: Marked pending\r\n"); - - m_connection_table[p_handle->connection_id].state |= STATE_PAIRING_PENDING; - m_application_table[p_handle->appl_id].state |= - STATE_QUEUED_CONTROL_REQUEST; - err_code = NRF_SUCCESS; - } - else - { - err_code = initiate_security_request(p_handle); - } - } - } - } - - DM_TRC("[DM]: << dm_security_setup_req, 0x%08X\r\n", err_code); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_security_status_req(dm_handle_t const * p_handle, - dm_security_status_t * p_status) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_status); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_CONNECTION_INSTANCE(p_handle->connection_id); - - DM_MUTEX_LOCK(); - - DM_LOG("[DM]: >> dm_security_status_req\r\n"); - - if ((m_connection_table[p_handle->connection_id].state & STATE_PAIRING) || - (m_connection_table[p_handle->connection_id].state & STATE_PAIRING_PENDING)) - { - (*p_status) = ENCRYPTION_IN_PROGRESS; - } - else if (m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED) - { - (*p_status) = ENCRYPTED; - } - else - { - (*p_status) = NOT_ENCRYPTED; - } - - DM_TRC("[DM]: << dm_security_status_req\r\n"); - - DM_MUTEX_UNLOCK(); - - return NRF_SUCCESS; -} - - -ret_code_t dm_whitelist_create(dm_application_instance_t const * p_handle, - ble_gap_whitelist_t * p_whitelist) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_whitelist); - NULL_PARAM_CHECK(p_whitelist->pp_addrs); - NULL_PARAM_CHECK(p_whitelist->pp_irks); - VERIFY_APP_REGISTERED(*p_handle); - - DM_MUTEX_LOCK(); - - DM_LOG("[DM]: >> dm_whitelist_create\r\n"); - - uint32_t addr_count = 0; - uint32_t irk_count = 0; - bool connected = false; - - for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - connected = false; - - for (uint32_t c_index = 0; c_index < DEVICE_MANAGER_MAX_CONNECTIONS; c_index++) - { - if ((index == m_connection_table[c_index].bonded_dev_id) && - ((m_connection_table[c_index].state & STATE_CONNECTED) == STATE_CONNECTED)) - { - connected = true; - break; - } - } - - if (connected == false) - { - if ((irk_count < p_whitelist->irk_count) && - ((m_peer_table[index].id_bitmap & IRK_ENTRY) == 0)) - { - p_whitelist->pp_irks[irk_count] = &m_peer_table[index].peer_id.id_info; - irk_count++; - } - - if ((addr_count < p_whitelist->addr_count) && - (m_peer_table[index].id_bitmap & ADDR_ENTRY) == 0) - { - p_whitelist->pp_addrs[addr_count] = &m_peer_table[index].peer_id.id_addr_info; - addr_count++; - } - } - } - - p_whitelist->addr_count = addr_count; - p_whitelist->irk_count = irk_count; - - DM_LOG("[DM]: Created whitelist, number of IRK = 0x%02X, number of addr = 0x%02X\r\n", - irk_count, - addr_count); - - DM_TRC("[DM]: << dm_whitelist_create\r\n"); - - DM_MUTEX_UNLOCK(); - - return NRF_SUCCESS; -} - - -ret_code_t dm_device_add(dm_handle_t * p_handle, - dm_device_context_t const * p_context) -{ - return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE); -} - - -ret_code_t dm_device_delete(dm_handle_t const * p_handle) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_device_delete\r\n"); - - uint32_t err_code = device_instance_free(p_handle->device_id); - - DM_TRC("[DM]: << dm_device_delete\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_device_delete_all(dm_application_instance_t const * p_handle) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED((*p_handle)); - - DM_MUTEX_LOCK(); - - uint32_t err_code = NRF_SUCCESS; - - DM_TRC("[DM]: >> dm_device_delete_all\r\n"); - - for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - if (m_peer_table[index].id_bitmap != UNASSIGNED) - { - err_code = device_instance_free(index); - } - } - - DM_TRC("[DM]: << dm_device_delete_all\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_service_context_set(dm_handle_t const * p_handle, - dm_service_context_t const * p_context) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_context); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_CONNECTION_INSTANCE(p_handle->connection_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_service_context_set\r\n"); - - if ((p_context->context_data.p_data != NULL) && - ( - (p_context->context_data.len != 0) && - (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE) - ) - ) - { - if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID) - { - memcpy(m_gatts_table[p_handle->connection_id].attributes, - p_context->context_data.p_data, - p_context->context_data.len); - } - } - - pstorage_handle_t block_handle; - uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - err_code = m_service_context_store[p_context->service_type](&block_handle, p_handle); - - DM_TRC("[DM]: << dm_service_context_set\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_service_context_get(dm_handle_t const * p_handle, - dm_service_context_t * p_context) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_context); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) != STATE_CONNECTED) - { - DM_TRC("[DM]: Device must be connected to get context. \r\n"); - - return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE); - } - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_service_context_get\r\n"); - - if ((p_context->context_data.p_data == NULL) && - (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE)) - { - if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID) - { - p_context->context_data.p_data = m_gatts_table[p_handle->connection_id].attributes; - p_context->context_data.len = m_gatts_table[p_handle->connection_id].size; - } - } - - pstorage_handle_t block_handle; - uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - err_code = m_service_context_load[p_context->service_type](&block_handle, p_handle); - - DM_TRC("[DM]: << dm_service_context_get\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_service_context_delete(dm_handle_t const * p_handle) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_LOG("[DM]: Context delete is not supported yet.\r\n"); - - return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE); -} - - -ret_code_t dm_application_context_set(dm_handle_t const * p_handle, - dm_application_context_t const * p_context) -{ -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_context); - NULL_PARAM_CHECK(p_context->p_data); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - SIZE_CHECK_APP_CONTEXT(p_context->len); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_application_context_set\r\n"); - - uint32_t err_code; - uint32_t context_len; - pstorage_handle_t block_handle; - - storage_operation store_fn = pstorage_store; - - err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - if (err_code == NRF_SUCCESS) - { - err_code = pstorage_load((uint8_t *)&context_len, - &block_handle, - sizeof(uint32_t), - APP_CONTEXT_STORAGE_OFFSET); - - if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN)) - { - //Data already exists. Need an update. - store_fn = pstorage_update; - - DM_LOG("[DM]:[DI 0x%02X]: Updating existing application context, existing len 0x%08X, " - "new length 0x%08X.\r\n", - p_handle->device_id, - context_len, - p_context->len); - } - else - { - DM_LOG("[DM]: Storing application context.\r\n"); - } - - //Store/update context length. - err_code = store_fn(&block_handle, - (uint8_t *)(&p_context->len), - sizeof(uint32_t), - APP_CONTEXT_STORAGE_OFFSET); - - if (err_code == NRF_SUCCESS) - { - //Update context data is used for application context as flash is never - //cleared if a delete of application context is called. - err_code = pstorage_update(&block_handle, - p_context->p_data, - DEVICE_MANAGER_APP_CONTEXT_SIZE, - (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t))); - if (err_code == NRF_SUCCESS) - { - m_app_context_table[p_handle->device_id] = p_context->p_data; - } - } - } - - DM_TRC("[DM]: << dm_application_context_set\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; - -#else //DEVICE_MANAGER_APP_CONTEXT_SIZE - return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE); -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE -} - - -ret_code_t dm_application_context_get(dm_handle_t const * p_handle, - dm_application_context_t * p_context) -{ -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_context); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_application_context_get\r\n"); - - uint32_t context_len; - uint32_t err_code; - pstorage_handle_t block_handle; - - //Check if the context exists. - if (NULL == p_context->p_data) - { - p_context->p_data = m_app_context_table[p_handle->device_id]; - } - else - { - m_app_context_table[p_handle->device_id] = p_context->p_data; - } - - err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - if (err_code == NRF_SUCCESS) - { - err_code = pstorage_load((uint8_t *)&context_len, - &block_handle, - sizeof(uint32_t), - APP_CONTEXT_STORAGE_OFFSET); - - if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN)) - { - err_code = pstorage_load(p_context->p_data, - &block_handle, - DEVICE_MANAGER_APP_CONTEXT_SIZE, - (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t))); - if (err_code == NRF_SUCCESS) - { - p_context->len = context_len; - } - } - else - { - err_code = DM_NO_APP_CONTEXT; - } - } - - DM_TRC("[DM]: << dm_application_context_get\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; - -#else //DEVICE_MANAGER_APP_CONTEXT_SIZE - return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE); -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE -} - - -ret_code_t dm_application_context_delete(const dm_handle_t * p_handle) -{ -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_application_context_delete\r\n"); - - uint32_t err_code; - uint32_t context_len; - pstorage_handle_t block_handle; - - err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - if (err_code == NRF_SUCCESS) - { - err_code = pstorage_load((uint8_t *)&context_len, - &block_handle, - sizeof(uint32_t), - APP_CONTEXT_STORAGE_OFFSET); - - if (context_len != m_context_init_len) - { - err_code = pstorage_update(&block_handle, - (uint8_t *)&m_context_init_len, - sizeof(uint32_t), - APP_CONTEXT_STORAGE_OFFSET); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]: Failed to delete application context, reason 0x%08X\r\n", err_code); - } - else - { - m_app_context_table[p_handle->device_id] = NULL; - } - } - } - - DM_TRC("[DM]: << dm_application_context_delete\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -#else //DEVICE_MANAGER_APP_CONTEXT_SIZE - return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE); -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE -} - - -ret_code_t dm_application_instance_set(dm_application_instance_t const * p_appl_instance, - dm_handle_t * p_handle) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_appl_instance); - VERIFY_APP_REGISTERED((*p_appl_instance)); - - p_handle->appl_id = (*p_appl_instance); - - return NRF_SUCCESS; -} - - -uint32_t dm_handle_initialize(dm_handle_t * p_handle) -{ - NULL_PARAM_CHECK(p_handle); - - p_handle->appl_id = DM_INVALID_ID; - p_handle->connection_id = DM_INVALID_ID; - p_handle->device_id = DM_INVALID_ID; - p_handle->service_id = DM_INVALID_ID; - - return NRF_SUCCESS; -} - - -ret_code_t dm_peer_addr_set(dm_handle_t const * p_handle, - ble_gap_addr_t const * p_addr) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_addr); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_peer_addr_set\r\n"); - - ret_code_t err_code; - - if ((p_handle->connection_id == DM_INVALID_ID) && - (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)) - { - m_peer_table[p_handle->device_id].peer_id.id_addr_info = (*p_addr); - update_status_bit_set(p_handle->device_id); - device_context_store(p_handle, UPDATE_PEER_ADDR); - err_code = NRF_SUCCESS; - } - else - { - err_code = (NRF_ERROR_INVALID_PARAM | DEVICE_MANAGER_ERR_BASE); - } - - DM_TRC("[DM]: << dm_peer_addr_set\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_peer_addr_get(dm_handle_t const * p_handle, - ble_gap_addr_t * p_addr) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_addr); - VERIFY_APP_REGISTERED(p_handle->appl_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_peer_addr_get\r\n"); - - ret_code_t err_code; - - err_code = (NRF_ERROR_NOT_FOUND | DEVICE_MANAGER_ERR_BASE); - - if (p_handle->device_id == DM_INVALID_ID) - { - if ((p_handle->connection_id != DM_INVALID_ID) && - ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) == - STATE_CONNECTED)) - { - DM_TRC("[DM]:[CI 0x%02X]: Address get for non bonded active connection.\r\n", - p_handle->connection_id); - - (*p_addr) = m_connection_table[p_handle->connection_id].peer_addr; - err_code = NRF_SUCCESS; - } - } - else - { - if ((m_peer_table[p_handle->device_id].id_bitmap & ADDR_ENTRY) == 0) - { - DM_TRC("[DM]:[DI 0x%02X]: Address get for bonded device.\r\n", - p_handle->device_id); - - (*p_addr) = m_peer_table[p_handle->device_id].peer_id.id_addr_info; - err_code = NRF_SUCCESS; - } - } - - DM_TRC("[DM]: << dm_peer_addr_get\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_distributed_keys_get(dm_handle_t const * p_handle, - dm_sec_keyset_t * p_key_dist) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_key_dist); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_distributed_keys_get\r\n"); - - ret_code_t err_code; - ble_gap_enc_key_t peer_enc_key; - pstorage_handle_t block_handle; - - err_code = NRF_ERROR_NOT_FOUND; - p_key_dist->keys_central.enc_key.p_enc_key = NULL; - p_key_dist->keys_central.p_id_key = (dm_id_key_t *)&m_local_id_info; - p_key_dist->keys_central.p_sign_key = NULL; - p_key_dist->keys_periph.p_id_key = (dm_id_key_t *)&m_peer_table[p_handle->device_id].peer_id; - p_key_dist->keys_periph.p_sign_key = NULL; - - err_code = pstorage_block_identifier_get(&m_storage_handle, p_handle->device_id, &block_handle); - - if (err_code == NRF_SUCCESS) - { - - err_code = pstorage_load((uint8_t *)&peer_enc_key, - &block_handle, - BOND_SIZE, - BOND_STORAGE_OFFSET); - - if (err_code == NRF_SUCCESS) - { - p_key_dist->keys_central.enc_key.p_enc_key = NULL; - p_key_dist->keys_central.p_id_key = (dm_id_key_t *)&m_local_id_info; - p_key_dist->keys_central.p_sign_key = NULL; - p_key_dist->keys_periph.p_id_key = (dm_id_key_t *)&m_peer_table[p_handle->device_id].peer_id; - p_key_dist->keys_periph.p_sign_key = NULL; - p_key_dist->keys_periph.enc_key.p_enc_key = (dm_enc_key_t *)&peer_enc_key; - - } - } - - DM_TRC("[DM]: << dm_distributed_keys_get\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -void dm_ble_evt_handler(ble_evt_t * p_ble_evt) -{ - uint32_t err_code; - uint32_t index; - uint32_t device_index; - bool notify_app = false; - bool start_sec_procedure = false; - dm_handle_t handle; - dm_event_t event; - uint32_t event_result; - - VERIFY_MODULE_INITIALIZED_VOID(); - VERIFY_APP_REGISTERED_VOID(0); - DM_MUTEX_LOCK(); - - err_code = dm_handle_initialize(&handle); - APP_ERROR_CHECK(err_code); - - event_result = NRF_SUCCESS; - err_code = NRF_SUCCESS; - event.event_param.p_gap_param = &p_ble_evt->evt.gap_evt; - event.event_paramlen = sizeof (ble_gap_evt_t); - handle.device_id = DM_INVALID_ID; - handle.appl_id = 0; - index = 0x00; - - if (p_ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED) - { - err_code = connection_instance_find(p_ble_evt->evt.gap_evt.conn_handle, - STATE_CONNECTED, - &index); - - if (err_code == NRF_SUCCESS) - { - handle.device_id = m_connection_table[index].bonded_dev_id; - handle.connection_id = index; - } - } - - switch (p_ble_evt->header.evt_id) - { - case BLE_GAP_EVT_CONNECTED: - //Allocate connection instance for a new connection. - err_code = connection_instance_allocate(&index); - - //Connection instance is successfully allocated. - if (err_code == NRF_SUCCESS) - { - //Application notification related information. - notify_app = true; - event.event_id = DM_EVT_CONNECTION; - handle.connection_id = index; - - m_connection_table[index].conn_handle = p_ble_evt->evt.gap_evt.conn_handle; - m_connection_table[index].state = STATE_CONNECTED; - m_connection_table[index].peer_addr = - p_ble_evt->evt.gap_evt.params.connected.peer_addr; - - //Use the device address to check if the device exists in the bonded device list. - err_code = device_instance_find(&p_ble_evt->evt.gap_evt.params.connected.peer_addr, - &device_index); - - if (err_code == NRF_SUCCESS) - { - pstorage_handle_t block_handle; - - m_connection_table[index].bonded_dev_id = device_index; - m_connection_table[index].state |= STATE_BONDED; - handle.device_id = device_index; - err_code = pstorage_block_identifier_get(&m_storage_handle, - device_index, - &block_handle); - - if (err_code == NRF_SUCCESS) - { - DM_LOG("[DM]:[%02X]:[Block ID 0x%08X]:Loading bond information at %p, size 0x%08X, offset 0x%08X.\r\n", - index, - block_handle.block_id, - &m_bond_table[index], - BOND_SIZE, - BOND_STORAGE_OFFSET); - - err_code = pstorage_load((uint8_t *)&m_bond_table[index], - &block_handle, - BOND_SIZE, - BOND_STORAGE_OFFSET); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]:[%02X]: Failed to load Bond information, reason %08X\r\n", - index, - err_code); - } - - DM_LOG("[DM]:[%02X]:Loading service context at %p, size 0x%08X, offset 0x%08X.\r\n", - index, - &m_gatts_table[index], - sizeof(dm_gatts_context_t), - SERVICE_STORAGE_OFFSET); - err_code = m_service_context_load[m_application_table[0].service]( - &block_handle, - &handle); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]:[%02X]: Failed to load service information, reason %08X\r\n", - index, - err_code); - } - } - else - { - DM_ERR("[DM]:[%02X]: Failed to get block identifier for " - "device %08X, reason %08X.\r\n", - index, - device_index, - err_code); - } - } - } - break; - - case BLE_GAP_EVT_DISCONNECTED: - //Disconnection could be peer or self initiated hence disconnecting and connecting - //both states are permitted, however, connection handle must be known. - DM_LOG("[DM]: Disconnect Reason 0x%04X\r\n", - p_ble_evt->evt.gap_evt.params.disconnected.reason); - - m_connection_table[index].state &= (~STATE_CONNECTED); - - if ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED) - { - if ((m_connection_table[index].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED) - { - //Write bond information persistently. - device_context_store(&handle, STORE_ALL_CONTEXT); - } - } - else - { - //Free any allocated instances for devices that is not bonded. - if (handle.device_id != DM_INVALID_ID) - { - peer_instance_init(handle.device_id); - handle.device_id = DM_INVALID_ID; - } - } - - if ((m_connection_table[index].state & STATE_PAIRING) == STATE_PAIRING) - { - start_sec_procedure = true; - m_application_table[0].state &= (~STATE_CONTROL_PROCEDURE_IN_PROGRESS); - } - m_connection_table[index].state = STATE_DISCONNECTING; - - notify_app = true; - event.event_id = DM_EVT_DISCONNECTION; - - break; - - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_PARAMS_REQUEST\r\n"); - - notify_app = false; - ble_gap_sec_keyset_t keys_exchanged; - - DM_LOG("[DM]: 0x%02X, 0x%02X, 0x%02X, 0x%02X\r\n", - p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.enc, - p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.id, - p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.sign, - p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.bond); - - keys_exchanged.keys_central.p_enc_key = NULL; - keys_exchanged.keys_central.p_id_key = NULL; - keys_exchanged.keys_central.p_sign_key = NULL; - keys_exchanged.keys_periph.p_enc_key = &m_bond_table[index].peer_enc_key; - keys_exchanged.keys_periph.p_id_key = - &m_peer_table[m_connection_table[index].bonded_dev_id].peer_id; - keys_exchanged.keys_periph.p_sign_key = NULL; - - err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, - BLE_GAP_SEC_STATUS_SUCCESS, - NULL, - &keys_exchanged); - - if (err_code != NRF_SUCCESS) - { - DM_LOG("[DM]: Security parameter reply request failed, reason 0x%08X.\r\n", err_code); - event_result = err_code; - } - else - { - m_connection_table[index].state |= STATE_PAIRING; - } - break; - - case BLE_GAP_EVT_AUTH_STATUS: - { - DM_LOG("[DM]: >> BLE_GAP_EVT_AUTH_STATUS, status %08X\r\n", - p_ble_evt->evt.gap_evt.params.auth_status.auth_status); - - m_application_table[0].state &= (~STATE_CONTROL_PROCEDURE_IN_PROGRESS); - m_connection_table[index].state &= (~STATE_PAIRING); - event.event_id = DM_EVT_SECURITY_SETUP_COMPLETE; - notify_app = true; - start_sec_procedure = true; - - if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status != BLE_GAP_SEC_STATUS_SUCCESS) - { - event_result = p_ble_evt->evt.gap_evt.params.auth_status.auth_status; - } - else - { - DM_DUMP((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status, - sizeof(ble_gap_evt_auth_status_t)); - DM_DUMP((uint8_t *)&m_bond_table[index], sizeof (bond_context_t)); - - if (p_ble_evt->evt.gap_evt.params.auth_status.bonded == 1) - { - if (handle.device_id != DM_INVALID_ID) - { - m_connection_table[index].state |= STATE_BONDED; - - //IRK and/or public address is shared, update it. - if (p_ble_evt->evt.gap_evt.params.auth_status.kdist_periph.id == 1) - { - m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY); - } - - if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID) - { - DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n", - index, - handle.device_id); - - if (m_connection_table[index].peer_addr.addr_type != - BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE) - { - m_peer_table[handle.device_id].peer_id.id_addr_info = - m_connection_table[index].peer_addr; - m_peer_table[handle.device_id].id_bitmap &= (~ADDR_ENTRY); - - DM_DUMP((uint8_t *)&m_peer_table[handle.device_id].peer_id.id_addr_info, - sizeof(m_peer_table[handle.device_id].peer_id.id_addr_info)); - } - device_context_store(&handle, FIRST_BOND_STORE); - } - } - } - else - { - //Pairing request, no need to touch the bonding info. - } - } - break; - } - - case BLE_GAP_EVT_CONN_SEC_UPDATE: - DM_LOG("[DM]: >> BLE_GAP_EVT_CONN_SEC_UPDATE, Mode 0x%02X, Level 0x%02X\r\n", - p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm, - p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv); - - if ((p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv == 1) && - (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm == 1) && - ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED)) - { - //Lost bond case, generate a security refresh event! - memset(m_gatts_table[index].attributes, 0, DM_GATT_SERVER_ATTR_MAX_SIZE); - - event.event_id = DM_EVT_SECURITY_SETUP_REFRESH; - start_sec_procedure = true; - m_connection_table[index].state |= STATE_PAIRING_PENDING; - m_connection_table[index].state |= STATE_BOND_INFO_UPDATE; - m_application_table[0].state |= STATE_QUEUED_CONTROL_REQUEST; - } - else - { - m_connection_table[index].state |= STATE_LINK_ENCRYPTED; - event.event_id = DM_EVT_LINK_SECURED; - - //Apply service context. - err_code = m_service_context_apply[m_application_table[0].service](&handle); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]:[CI 0x%02X]:[DI 0x%02X]: Failed to apply service context\r\n", - handle.connection_id, - handle.device_id); - - event_result = DM_SERVICE_CONTEXT_NOT_APPLIED; - } - } - event_result = NRF_SUCCESS; - notify_app = true; - - break; - - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - DM_LOG("[DM]: >> BLE_GATTS_EVT_SYS_ATTR_MISSING\r\n"); - - //Apply service context. - event_result = m_service_context_apply[m_application_table[0].service](&handle); - break; - - case BLE_GAP_EVT_SEC_REQUEST: - DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_REQUEST\r\n"); - - //Verify if the device is already bonded, and if it is bonded, initiate encryption. - //If the device is not bonded, an instance needs to be allocated in order to initiate - //bonding. The application have to initiate the procedure, the module will not do this - //automatically. - event.event_id = DM_EVT_SECURITY_SETUP; - notify_app = true; - - break; - - default: - break; - } - - if (notify_app) - { - app_evt_notify(&handle, &event, event_result); - - //Freeing the instance after the event is notified so the application can get the context. - if (event.event_id == DM_EVT_DISCONNECTION) - { - //Free the instance. - connection_instance_free(&index); - } - } - - if (start_sec_procedure) - { - if ((m_application_table[0].state & STATE_QUEUED_CONTROL_REQUEST) == - STATE_QUEUED_CONTROL_REQUEST) - { - dm_handle_t pending_handle; - uint32_t pending_index; - - DM_LOG("[DM]:Queued request\r\n"); - err_code = connection_instance_find(BLE_CONN_HANDLE_INVALID, - STATE_PAIRING_PENDING, - &pending_index); - - if (err_code == NRF_SUCCESS) - { - pending_handle.appl_id = 0; - pending_handle.connection_id = pending_index; - pending_handle.device_id = m_connection_table[pending_index].bonded_dev_id; - err_code = initiate_security_request(&pending_handle); - DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Security request result 0x%08X\r\n", - pending_handle.connection_id, - pending_handle.device_id, - err_code); - } - else - { - DM_LOG("[DM]:Nothing pending!\r\n"); - m_application_table[0].state &= (~STATE_QUEUED_CONTROL_REQUEST); - } - } - } - - UNUSED_VARIABLE(err_code); - - DM_MUTEX_UNLOCK(); -} diff --git a/components/ble/device_manager/device_manager_peripheral.c b/components/ble/device_manager/device_manager_peripheral.c deleted file mode 100644 index fc3f06e..0000000 --- a/components/ble/device_manager/device_manager_peripheral.c +++ /dev/null @@ -1,2914 +0,0 @@ -/* Copyright (C) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * - */ - -#include "device_manager.h" -#include "app_trace.h" -#include "pstorage.h" -#include "ble_hci.h" -#include "app_error.h" - -#if defined ( __CC_ARM ) - #ifndef __ALIGN - #define __ALIGN(x) __align(x) /**< Forced aligment keyword for ARM Compiler */ - #endif -#elif defined ( __ICCARM__ ) - #ifndef __ALIGN - #define __ALIGN(x) /**< Forced aligment keyword for IAR Compiler */ - #endif -#elif defined ( __GNUC__ ) - #ifndef __ALIGN - #define __ALIGN(x) __attribute__((aligned(x))) /**< Forced aligment keyword for GNU Compiler */ - #endif -#endif - -#define INVALID_ADDR_TYPE 0xFF /**< Identifier for an invalid address type. */ -#define EDIV_INIT_VAL 0xFFFF /**< Initial value for diversifier. */ - -/** - * @defgroup device_manager_app_states Connection Manager Application States - * @{ - */ -#define STATE_CONTROL_PROCEDURE_IN_PROGRESS 0x01 /**< State where a security procedure is ongoing. */ -#define STATE_QUEUED_CONTROL_REQUEST 0x02 /**< State where it is known if there is any queued security request or not. */ -/** @} */ - -/** - * @defgroup device_manager_conn_inst_states Connection Manager Connection Instances States. - * @{ - */ -#define STATE_IDLE 0x01 /**< State where connection instance is free. */ -#define STATE_CONNECTED 0x02 /**< State where connection is successfully established. */ -#define STATE_PAIRING 0x04 /**< State where pairing procedure is in progress. This state is used for pairing and bonding, as pairing is needed for both. */ -#define STATE_BONDED 0x08 /**< State where device is bonded. */ -#define STATE_DISCONNECTING 0x10 /**< State where disconnection is in progress, application will be notified first, but no further active procedures on the link. */ -#define STATE_PAIRING_PENDING 0x20 /**< State where pairing request is pending on the link. */ -#define STATE_BOND_INFO_UPDATE 0x40 /**< State where information has been updated, update the flash. */ -#define STATE_LINK_ENCRYPTED 0x80 /**< State where link is encrypted. */ -/** @} */ - -/** - * @defgroup device_manager_peer_id_defines Peer Identification Information Defines. - * - * @brief These defines are used to know which of the peer identification is applicable for a peer. - * - * @details These defines are used for peer identification. Here, bit map is used because it is - * possible that the application has both IRK and address for identification. - * @{ - */ -#define UNASSIGNED 0xFF /**< Peer instance is unassigned/unused. */ -#define IRK_ENTRY 0x01 /**< Peer instance has IRK as identification information. */ -#define ADDR_ENTRY 0x02 /**< Peer instance has address as identification information. */ -#define SERVICE_CONTEXT_ENTRY 0x04 /**< Peer instance has service context set. */ -#define APP_CONTEXT_ENTRY 0x08 /**< Peer instance has an application context set. */ -/** @} */ - -/**@brief Device store state identifiers. */ -typedef enum -{ - STORE_ALL_CONTEXT, /**< Store all context. */ - FIRST_BOND_STORE, /**< Store bond. */ - UPDATE_PEER_ADDR /**< Update peer address. */ -} device_store_state_t; - -/** - * @defgroup device_manager_context_offsets Context Offsets - * @{ - * - * @brief Context offsets each of the context information in persistent memory. - * - * @details Below is a layout showing how each how the context information is stored in persistent - * memory. - * - * All Device context is stored in the flash as follows: - * +---------+---------+---------+------------------+----------------+--------------------+ - * | Block / Device ID + Layout of stored information in storage block | - * +---------+---------+---------+------------------+----------------+--------------------+ - * | Block 0 | Device 0| Peer Id | Bond Information | Service Context| Application Context| - * +---------+---------+---------+------------------+----------------+--------------------+ - * | Block 1 | Device 1| Peer Id | Bond Information | Service Context| Application Context| - * +---------+---------+---------+------------------+----------------+--------------------+ - * | ... | .... | - * +---------+---------+---------+------------------+----------------+--------------------+ - * | Block N | Device N| Peer Id | Bond Information | Service Context| Application Context| - * +---------+---------+---------+------------------+----------------+--------------------+ - * - * The following defines are used to get offset of each of the components within a block. - */ - -#define PEER_ID_STORAGE_OFFSET 0 /**< Offset at which peer id is stored in the block. */ -#define BOND_STORAGE_OFFSET PEER_ID_SIZE /**< Offset at which bond information is stored in the block. */ -#define SERVICE_STORAGE_OFFSET (BOND_STORAGE_OFFSET + BOND_SIZE) /**< Offset at which service context is stored in the block. */ -#define APP_CONTEXT_STORAGE_OFFSET (SERVICE_STORAGE_OFFSET + SERVICE_CONTEXT_SIZE) /**< Offset at which application context is stored in the block. */ -/** @} */ - -/** - * @defgroup device_manager_context_size Context size. - * @{ - * - * @brief This group defines the size of each of the context information. - */ -#define PEER_ID_SIZE (sizeof(peer_id_t)) /**< Size of peer identification information. */ -#define BOND_SIZE (sizeof(bond_context_t)) /**< Size of bond information. */ -#define DEVICE_CONTEXT_SIZE (PEER_ID_SIZE + BOND_SIZE) /**< Size of Device context, include peer identification and bond information. */ -#define GATTS_SERVICE_CONTEXT_SIZE (sizeof(dm_gatts_context_t)) /**< Size of GATTS service context. */ -#define GATTC_SERVICE_CONTEXT_SIZE (sizeof(dm_gatt_client_context_t)) /**< Size of GATTC service context. */ -#define SERVICE_CONTEXT_SIZE (GATTS_SERVICE_CONTEXT_SIZE + GATTC_SERVICE_CONTEXT_SIZE) /**< Combined size of GATTS and GATTC service contexts. */ -#define APP_CONTEXT_MIN_SIZE 4 /**< Minimum size for application context data. */ -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) -#define APP_CONTEXT_SIZE (sizeof(uint32_t) + DEVICE_MANAGER_APP_CONTEXT_SIZE) /**< Size of application context including length field. */ -#else //DEVICE_MANAGER_APP_CONTEXT_SIZE -#define APP_CONTEXT_SIZE 0 /**< Size of application context. */ -#endif // DEVICE_MANAGER_APP_CONTEXT_SIZE -#define ALL_CONTEXT_SIZE (DEVICE_CONTEXT_SIZE + SERVICE_CONTEXT_SIZE + APP_CONTEXT_SIZE) /**< Size of all contexts. */ -/** @} */ - - -/** - * @defgroup device_manager_log Module's Log Macros - * - * @details Macros used for creating module logs which can be useful in understanding handling - * of events or actions on API requests. These are intended for debugging purposes and - * can be disabled by defining the DM_DISABLE_LOGS. - * - * @note That if ENABLE_DEBUG_LOG_SUPPORT is disabled, having DM_DISABLE_LOGS has no effect. - * @{ - */ -#define nDM_DISABLE_LOGS /**< Enable this macro to disable any logs from this module. */ - -#ifndef DM_DISABLE_LOGS -#define DM_LOG app_trace_log /**< Used for logging details. */ -#define DM_ERR app_trace_log /**< Used for logging errors in the module. */ -#define DM_TRC app_trace_log /**< Used for getting trace of execution in the module. */ -#define DM_DUMP app_trace_dump /**< Used for dumping octet information to get details of bond information etc. */ -#else //DM_DISABLE_LOGS -#define DM_DUMP(...) /**< Disables dumping of octet streams. */ -#define DM_LOG(...) /**< Disables detailed logs. */ -#define DM_ERR(...) /**< Disables error logs. */ -#define DM_TRC(...) /**< Disables traces. */ -#endif //DM_DISABLE_LOGS -/** @} */ - -/** - * @defgroup device_manager_mutex_lock_unlock Module's Mutex Lock/Unlock Macros. - * - * @details Macros used to lock and unlock modules. Currently the SDK does not use mutexes but - * framework is provided in case need arises to use an alternative architecture. - * @{ - */ -#define DM_MUTEX_LOCK() SDK_MUTEX_LOCK(m_dm_mutex) /**< Lock module using mutex. */ -#define DM_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_dm_mutex) /**< Unlock module using mutex. */ -/** @} */ - - -/** - * @defgroup device_manager_misc_defines Miscellaneous defines used across the module. - * @{ - */ -#define DM_GATT_ATTR_SIZE 6 /**< Size of each GATT attribute to be stored persistently. */ -#define DM_GATT_SERVER_ATTR_MAX_SIZE ((DM_GATT_ATTR_SIZE * DM_GATT_CCCD_COUNT) + 2) /**< Maximum size of GATT attributes to be stored.*/ -#define DM_SERVICE_CONTEXT_COUNT (DM_PROTOCOL_CNTXT_ALL + 1) /**< Maximum number of service contexts. */ -#define DM_EVT_DEVICE_CONTEXT_BASE 0x20 /**< Base for device context base. */ -#define DM_EVT_SERVICE_CONTEXT_BASE 0x30 /**< Base for service context base. */ -#define DM_EVT_APP_CONTEXT_BASE 0x40 /**< Base for application context base. */ -#define DM_LOAD_OPERATION_ID 0x01 /**< Load operation identifier. */ -#define DM_STORE_OPERATION_ID 0x02 /**< Store operation identifier. */ -#define DM_CLEAR_OPERATION_ID 0x03 /**< Clear operation identifier. */ -/** @} */ - -#define DM_GATTS_INVALID_SIZE 0xFFFFFFFF /**< Identifer for GATTS invalid size. */ - -/** - * @defgroup api_param_check API Parameters check macros. - * - * @details Macros for verifying parameters passed to the module in the APIs. These macros - * could be mapped to nothing in the final version of the code in order to save execution - * time and program size. - * @{ - */ - -//#define DM_DISABLE_API_PARAM_CHECK /**< Macro to disable API parameters check. */ - -#ifndef DM_DISABLE_API_PARAM_CHECK - -/**@brief Macro for verifying NULL parameters are not passed to API. - * - * @param[in] PARAM Parameter checked for NULL. - * - * @retval (NRF_ERROR_NULL | DEVICE_MANAGER_ERR_BASE) when @ref PARAM is NULL. - */ -#define NULL_PARAM_CHECK(PARAM) \ - if ((PARAM) == NULL) \ - { \ - return (NRF_ERROR_NULL | DEVICE_MANAGER_ERR_BASE); \ - } -/**@} */ - - -/**@brief Macro for verifying module's initialization status. - * - * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when module is not initialized. - */ -#define VERIFY_MODULE_INITIALIZED() \ - do \ - { \ - if (!m_module_initialized) \ - { \ - return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \ - } \ - } while (0) - - -/**@brief Macro for verifying module's initialization status. Returns in case it is not initialized. - */ -#define VERIFY_MODULE_INITIALIZED_VOID() \ - do \ - { \ - if (!m_module_initialized) \ - { \ - return; \ - } \ - } while (0) - - -/**@brief Macro for verifying that the application is registered. - * - * @param[in] X Application instance identifier. - * - * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when module API is called without - * registering an application with the module. - */ -#define VERIFY_APP_REGISTERED(X) \ - do \ - { \ - if (((X) >= DEVICE_MANAGER_MAX_APPLICATIONS) || \ - (m_application_table[(X)].ntf_cb == NULL)) \ - { \ - return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \ - } \ - } while (0) - - -/**@brief Macro for verifying that the application is registered. Returns in case it is not - * registered. - * - * @param[in] X Application instance identifier. - */ -#define VERIFY_APP_REGISTERED_VOID(X) \ - do \ - { \ - if (((X) >= DEVICE_MANAGER_MAX_APPLICATIONS) || \ - (m_application_table[(X)].ntf_cb == NULL)) \ - { \ - return; \ - } \ - } while (0) - - -/**@brief Macro for verifying connection instance is allocated. - * - * @param[in] X Connection instance identifier. - * - * @retval (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE) when connection instance is not - * allocated. - */ -#define VERIFY_CONNECTION_INSTANCE(X) \ - do \ - { \ - if (((X) >= DEVICE_MANAGER_MAX_CONNECTIONS) || \ - (m_connection_table[(X)].state == STATE_IDLE)) \ - { \ - return (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE); \ - } \ - } while (0) - - -/**@brief Macro for verifying if device instance is allocated. - * - * @param[in] X Device instance identifier. - * - * @retval (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE) when device instance is not allocated. - */ -#define VERIFY_DEVICE_INSTANCE(X) \ - do \ - { \ - if (((X) >= DEVICE_MANAGER_MAX_BONDS) || \ - (m_peer_table[(X)].id_bitmap == UNASSIGNED)) \ - { \ - return (NRF_ERROR_INVALID_ADDR | DEVICE_MANAGER_ERR_BASE); \ - } \ - } while (0) - -/**@brief Macro for verifying if device is bonded and thus can store data persistantly. - * - * @param[in] X Connection instance identifier. - * - * @retval (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE) when device is not bonded. - */ -#define VERIFY_DEVICE_BOND(X) \ - do \ - { \ - if ((m_connection_table[(X)].state & STATE_BONDED) != STATE_BONDED)\ - { \ - return (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); \ - } \ - } while (0) -#else -#define NULL_PARAM_CHECK(X) -#define VERIFY_MODULE_INITIALIZED() -#define VERIFY_MODULE_INITIALIZED_VOID() -#define VERIFY_APP_REGISTERED(X) -#define VERIFY_APP_REGISTERED_VOID(X) -#define VERIFY_CONNECTION_INSTANCE(X) -#define VERIFY_DEVICE_INSTANCE(X) -#endif //DM_DISABLE_API_PARAM_CHECK -/** @} */ - -#define INVALID_CONTEXT_LEN 0xFFFFFFFF /**< Identifier for invalid context length. */ -/**@brief Macro for checking that application context size is greater that minimal size. - * - * @param[in] X Size of application context. - * - * @retval (NRF_ERROR_INVALID_PARAM) when size is smaller than minimun required size. - */ -#define SIZE_CHECK_APP_CONTEXT(X) \ - if ((X) < (APP_CONTEXT_MIN_SIZE)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - - -/** - * @defgroup dm_data_types Module's internal data types. - * - * @brief This section describes a module's internal data structures. - * @{ - */ -/**@brief Peer identification information. - */ -typedef struct -{ - ble_gap_id_key_t peer_id; /**< IRK and/or address of peer. */ - uint16_t ediv; /**< Peer's encrypted diversifier. */ - uint8_t id_bitmap; /**< Contains information if above field is valid. */ -} peer_id_t; - -STATIC_ASSERT(sizeof(peer_id_t) % 4 == 0); /**< Check to ensure Peer identification information is a multiple of 4. */ - -/**@brief Portion of bonding information exchanged by a device during bond creation that needs to - * be stored persistently. - * - * @note An entry is not made in this table unless device is bonded. - */ -typedef struct -{ - ble_gap_enc_key_t peer_enc_key; /**< Local LTK info, central IRK and address */ -} bond_context_t; - -STATIC_ASSERT(sizeof(bond_context_t) % 4 == 0); /**< Check to ensure bond information is a multiple of 4. */ - -/**@brief GATT Server Attributes size and data. - */ -typedef struct -{ - uint32_t flags; /**< Flags identifying the stored attributes. */ - uint32_t size; /**< Size of stored attributes. */ - uint8_t attributes[DM_GATT_SERVER_ATTR_MAX_SIZE]; /**< Array to hold the server attributes. */ -} dm_gatts_context_t; - -STATIC_ASSERT(sizeof(dm_gatts_context_t) % 4 == 0); /**< Check to ensure GATT Server Attributes size and data information is a multiple of 4. */ - -/**@brief GATT Client context information. Placeholder for now. - */ -typedef struct -{ - void * p_dummy; /**< Placeholder, currently unused. */ -} dm_gatt_client_context_t; - -STATIC_ASSERT(sizeof(dm_gatt_client_context_t) % 4 == 0); /**< Check to ensure GATT Client context information is a multiple of 4. */ -STATIC_ASSERT((DEVICE_MANAGER_APP_CONTEXT_SIZE % 4) == 0); /**< Check to ensure device manager application context information is a multiple of 4. */ - -/**@brief Connection instance definition. Maintains information with respect to an active peer. - */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Peer identification information. This information is retained as long as the connection session exists, once disconnected, for non-bonded devices this information is not stored persistently. */ - uint16_t conn_handle; /**< Connection handle for the device. */ - uint8_t state; /**< Link state. */ - uint8_t bonded_dev_id; /**< In case the device is bonded, this points to the corresponding bonded device. This index can be used to index service and bond context as well. */ -} connection_instance_t; - -/**@brief Application instance definition. Maintains information with respect to a registered - * application. - */ -typedef struct -{ - dm_event_cb_t ntf_cb; /**< Callback registered with the application. */ - ble_gap_sec_params_t sec_param; /**< Local security parameters registered by the application. */ - uint8_t state; /**< Application state. Currently this is used only for knowing if any security procedure is in progress and/or a security procedure is pending to be requested. */ - uint8_t service; /**< Service registered by the application. */ -} application_instance_t; - -/**@brief Function for performing necessary action of storing each of the service context as - * registered by the application. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is stored. - * - * @retval Operation result code. - */ -typedef ret_code_t (* service_context_access_t)(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -/**@brief Function for performing necessary action of applying the context information. - * - * @param[in] p_handle Device handle identifying device that is stored. - * - * @retval Operation result code. - */ -typedef ret_code_t (* service_context_apply_t)(dm_handle_t * p_handle); - -/**@brief Function for performing necessary functions of storing or updating. - * - * @param[in] p_dest Destination address where data is stored persistently. - * @param[in] p_src Source address containing data to be stored. - * @param[in] size Size of data to be stored expressed in bytes. Must be word aligned. - * @param[in] offset Offset in bytes to be applied when writing to the block. - * - * @retval Operation result code. - */ -typedef uint32_t (* storage_operation)(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset); -/** @} */ - -/** - * @defgroup dm_tables Module's internal tables. - * - * @brief This section describes the module's internal tables and the static global variables - * needed for its functionality. - * @{ - */ -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) -static uint8_t * m_app_context_table[DEVICE_MANAGER_MAX_BONDS]; /**< Table to remember application contexts of bonded devices. */ -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE -__ALIGN(sizeof(uint32_t)) -static peer_id_t m_peer_table[DEVICE_MANAGER_MAX_BONDS] ; /**< Table to maintain bonded devices' identification information, an instance is allocated in the table when a device is bonded and freed when bond information is deleted. */ -__ALIGN(sizeof(uint32_t)) -static bond_context_t m_bond_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table to maintain bond information for active peers. */ -static dm_gatts_context_t m_gatts_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table for service information for active connection instances. */ -static connection_instance_t m_connection_table[DEVICE_MANAGER_MAX_CONNECTIONS]; /**< Table to maintain active peer information. An instance is allocated in the table when a new connection is established and freed on disconnection. */ -static application_instance_t m_application_table[DEVICE_MANAGER_MAX_APPLICATIONS]; /**< Table to maintain application instances. */ -static pstorage_handle_t m_storage_handle; /**< Persistent storage handle for blocks requested by the module. */ -static uint32_t m_peer_addr_update; /**< 32-bit bitmap to remember peer device address update. */ -static ble_gap_id_key_t m_local_id_info; /**< ID information of central in case resolvable address is used. */ -static bool m_module_initialized = false; /**< State indicating if module is initialized or not. */ -static uint8_t m_irk_index_table[DEVICE_MANAGER_MAX_BONDS]; /**< List maintaining IRK index list. */ - -SDK_MUTEX_DEFINE(m_dm_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */ -/** @} */ - -static __INLINE ret_code_t no_service_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gatts_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gattc_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gattsc_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t no_service_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gatts_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gattc_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t gattsc_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle); - -static __INLINE ret_code_t no_service_context_apply(dm_handle_t * p_handle); - -static __INLINE ret_code_t gatts_context_apply(dm_handle_t * p_handle); - -static __INLINE ret_code_t gattc_context_apply(dm_handle_t * p_handle); - -static __INLINE ret_code_t gattsc_context_apply(dm_handle_t * p_handle); - - -/**< Array of function pointers based on the types of service registered. */ -const service_context_access_t m_service_context_store[DM_SERVICE_CONTEXT_COUNT] = -{ - no_service_context_store, /**< Dummy function, when there is no service context registered. */ - gatts_context_store, /**< GATT Server context store function. */ - gattc_context_store, /**< GATT Client context store function. */ - gattsc_context_store /**< GATT Server & Client context store function. */ -}; - - -/**< Array of function pointers based on the types of service registered. */ -const service_context_access_t m_service_context_load[DM_SERVICE_CONTEXT_COUNT] = -{ - no_service_context_load, /**< Dummy function, when there is no service context registered. */ - gatts_context_load, /**< GATT Server context load function. */ - gattc_context_load, /**< GATT Client context load function. */ - gattsc_context_load /**< GATT Server & Client context load function. */ -}; - - -/**< Array of function pointers based on the types of service registered. */ -const service_context_apply_t m_service_context_apply[DM_SERVICE_CONTEXT_COUNT] = -{ - no_service_context_apply, /**< Dummy function, when there is no service context registered. */ - gatts_context_apply, /**< GATT Server context apply function. */ - gattc_context_apply, /**< GATT Client context apply function. */ - gattsc_context_apply /**< GATT Server & Client context apply function. */ -}; - - -const uint32_t m_context_init_len = 0xFFFFFFFF; /**< Constant used to update the initial value for context in the flash. */ - -/**@brief Function for setting update status for the device identified by 'index'. - * - * @param[in] index Device identifier. - */ -static __INLINE void update_status_bit_set(uint32_t index) -{ - m_peer_addr_update |= (BIT_0 << index); -} - - -/**@brief Function for resetting update status for device identified by 'index'. - * - * @param[in] index Device identifier. - */ -static __INLINE void update_status_bit_reset(uint32_t index) -{ - m_peer_addr_update &= (~((uint32_t)BIT_0 << index)); -} - - -/**@brief Function for providing update status for the device identified by 'index'. - * - * @param[in] index Device identifier. - * - * @retval true if the bit is set, false otherwise. - */ -static __INLINE bool update_status_bit_is_set(uint32_t index) -{ - return ((m_peer_addr_update & (BIT_0 << index)) ? true : false); -} - - -/**@brief Function for initialiasing the application instance identified by 'index'. - * - * @param[in] index Device identifier. - */ -static __INLINE void application_instance_init(uint32_t index) -{ - DM_TRC("[DM]: Initializing Application Instance 0x%08X.\r\n", index); - - m_application_table[index].ntf_cb = NULL; - m_application_table[index].state = 0x00; - m_application_table[index].service = 0x00; -} - - -/**@brief Function for initialiasing the connection instance identified by 'index'. - * - * @param[in] index Device identifier. - */ -static __INLINE void connection_instance_init(uint32_t index) -{ - DM_TRC("[DM]: Initializing Connection Instance 0x%08X.\r\n", index); - - m_connection_table[index].state = STATE_IDLE; - m_connection_table[index].conn_handle = BLE_CONN_HANDLE_INVALID; - m_connection_table[index].bonded_dev_id = DM_INVALID_ID; - - memset(&m_connection_table[index].peer_addr, 0, sizeof (ble_gap_addr_t)); -} - - -/**@brief Function for initialiasing the peer device instance identified by 'index'. - * - * @param[in] index Device identifier. - */ -static __INLINE void peer_instance_init(uint32_t index) -{ - DM_TRC("[DM]: Initializing Peer Instance 0x%08X.\r\n", index); - - memset(m_peer_table[index].peer_id.id_addr_info.addr, 0, BLE_GAP_ADDR_LEN); - memset(m_peer_table[index].peer_id.id_info.irk, 0, BLE_GAP_SEC_KEY_LEN); - - //Initialize the address type to invalid. - m_peer_table[index].peer_id.id_addr_info.addr_type = INVALID_ADDR_TYPE; - - //Initialize the identification bit map to unassigned. - m_peer_table[index].id_bitmap = UNASSIGNED; - - // Initialize diversifier. - m_peer_table[index].ediv = EDIV_INIT_VAL; - - - //Reset the status bit. - update_status_bit_reset(index); - -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) - //Initialize the application context for bond device. - m_app_context_table[index] = NULL; -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE -} - - -/**@brief Function for searching connection instance matching the connection handle and the state - * requested. - * - * @details Connection handle and state information is used to get a connection instance, it - * is possible to ignore the connection handle by using BLE_CONN_HANDLE_INVALID. - * - * @param[in] conn_handle Connection handle. - * @param[in] state Connection instance state. - * @param[out] p_instance Connection instance. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. Invalid state - * @retval NRF_ERROR_NOT_FOUND Operation failure. Not found - */ -static ret_code_t connection_instance_find(uint16_t conn_handle, - uint8_t state, - uint32_t * p_instance) -{ - ret_code_t err_code; - uint32_t index; - - err_code = NRF_ERROR_INVALID_STATE; - - for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++) - { - //Search only based on the state. - if (state & m_connection_table[index].state) - { - //Ignore the connection handle. - if ((conn_handle == BLE_CONN_HANDLE_INVALID) || - (conn_handle == m_connection_table[index].conn_handle)) - { - //Search for matching connection handle. - (*p_instance) = index; - err_code = NRF_SUCCESS; - - break; - } - else - { - err_code = NRF_ERROR_NOT_FOUND; - } - } - } - - return err_code; -} - - -/**@brief Function for allocating device instance for a bonded device. - * - * @param[out] p_device_index Device index. - * @param[in] p_addr Peer identification information. - * - * @retval NRF_SUCCESS Operation success. - * @retval DM_DEVICE_CONTEXT_FULL Operation failure. - */ -static __INLINE ret_code_t device_instance_allocate(uint8_t * p_device_index, - ble_gap_addr_t const * p_addr) -{ - ret_code_t err_code; - uint32_t index; - - err_code = DM_DEVICE_CONTEXT_FULL; - - for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - DM_TRC("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n", - index, m_peer_table[index].peer_id.id_addr_info.addr_type); - DM_TRC("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n", - m_peer_table[index].peer_id.id_addr_info.addr[0], - m_peer_table[index].peer_id.id_addr_info.addr[1], - m_peer_table[index].peer_id.id_addr_info.addr[2], - m_peer_table[index].peer_id.id_addr_info.addr[3], - m_peer_table[index].peer_id.id_addr_info.addr[4], - m_peer_table[index].peer_id.id_addr_info.addr[5]); - - if (m_peer_table[index].id_bitmap == UNASSIGNED) - { - if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE) - { - m_peer_table[index].id_bitmap &= (~ADDR_ENTRY); - m_peer_table[index].peer_id.id_addr_info = (*p_addr); - } - else - { - m_peer_table[index].id_bitmap &= (~IRK_ENTRY); - } - - (*p_device_index) = index; - err_code = NRF_SUCCESS; - - DM_LOG("[DM]: Allocated device instance 0x%02X\r\n", index); - - break; - } - } - - return err_code; -} - - -/**@brief Function for freeing a device instance allocated for bonded device. - * - * @param[in] device_index Device index. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - */ -static __INLINE ret_code_t device_instance_free(uint32_t device_index) -{ - ret_code_t err_code; - pstorage_handle_t block_handle; - - //Get the block handle. - err_code = pstorage_block_identifier_get(&m_storage_handle, device_index, &block_handle); - - if (err_code == NRF_SUCCESS) - { - DM_TRC("[DM]:[DI 0x%02X]: Freeing Instance.\r\n", device_index); - - //Request clearing of the block. - err_code = pstorage_clear(&block_handle, ALL_CONTEXT_SIZE); - - if (err_code == NRF_SUCCESS) - { - peer_instance_init(device_index); - } - } - - return err_code; -} - - -/**@brief Function for searching for the device in the bonded device list. - * - * @param[in] p_addr Peer identification information. - * @param[out] p_device_index Device index. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_NOT_FOUND Operation failure. - */ -static ret_code_t device_instance_find(ble_gap_addr_t const * p_addr, uint32_t * p_device_index, uint16_t ediv) -{ - ret_code_t err_code; - uint32_t index; - - err_code = NRF_ERROR_NOT_FOUND; - - if (NULL != p_addr) - { - DM_TRC("[DM]: Searching for device 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n", - p_addr->addr[0], - p_addr->addr[1], - p_addr->addr[2], - p_addr->addr[3], - p_addr->addr[4], - p_addr->addr[5]); - } - - for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - DM_TRC("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n", - index, m_peer_table[index].peer_id.id_addr_info.addr_type); - DM_TRC("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n", - m_peer_table[index].peer_id.id_addr_info.addr[0], - m_peer_table[index].peer_id.id_addr_info.addr[1], - m_peer_table[index].peer_id.id_addr_info.addr[2], - m_peer_table[index].peer_id.id_addr_info.addr[3], - m_peer_table[index].peer_id.id_addr_info.addr[4], - m_peer_table[index].peer_id.id_addr_info.addr[5]); - - if (((NULL == p_addr) && (ediv == m_peer_table[index].ediv)) || - ((NULL != p_addr) && (memcmp(&m_peer_table[index].peer_id.id_addr_info, p_addr, sizeof(ble_gap_addr_t)) == 0))) - { - DM_LOG("[DM]: Found device at instance 0x%02X\r\n", index); - - (*p_device_index) = index; - err_code = NRF_SUCCESS; - - break; - } - } - - return err_code; -} - - -/**@brief Function for notifying connection manager event to the application. - * - * @param[in] p_handle Device handle identifying device. - * @param[in] p_event Connection manager event details. - * @param[in] event_result Event result code. - */ -static __INLINE void app_evt_notify(dm_handle_t const * const p_handle, - dm_event_t const * const p_event, - uint32_t event_result) -{ - dm_event_cb_t app_cb = m_application_table[0].ntf_cb; - - DM_MUTEX_UNLOCK(); - - DM_TRC("[DM]: Notifying application of event 0x%02X\r\n", p_event->event_id); - - //No need to do any kind of return value processing thus can be supressed. - UNUSED_VARIABLE(app_cb(p_handle, p_event, event_result)); - - DM_MUTEX_LOCK(); -} - - -/**@brief Function for allocating instance. - * - * @details The instance identifier is provided in the 'p_instance' parameter if the routine - * succeeds. - * - * @param[out] p_instance Connection instance. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_NO_MEM Operation failure. No memory. - */ -static __INLINE uint32_t connection_instance_allocate(uint32_t * p_instance) -{ - uint32_t err_code; - - DM_TRC("[DM]: Request to allocation connection instance\r\n"); - - err_code = connection_instance_find(BLE_CONN_HANDLE_INVALID, STATE_IDLE, p_instance); - - if (err_code == NRF_SUCCESS) - { - DM_LOG("[DM]:[%02X]: Connection Instance Allocated.\r\n", (*p_instance)); - m_connection_table[*p_instance].state = STATE_CONNECTED; - } - else - { - DM_LOG("[DM]: No free connection instances available\r\n"); - err_code = NRF_ERROR_NO_MEM; - } - - return err_code; -} - - -/**@brief Function for freeing instance. Instance identifier is provided in the parameter - * 'p_instance' in case the routine succeeds. - * - * @param[in] p_instance Connection instance. - */ -static __INLINE void connection_instance_free(uint32_t const * p_instance) -{ - DM_TRC("[DM]:[CI 0x%02X]: Freeing connection instance\r\n", (*p_instance)); - - if (m_connection_table[*p_instance].state != STATE_IDLE) - { - DM_LOG("[DM]:[%02X]: Freed connection instance.\r\n", (*p_instance)); - connection_instance_init(*p_instance); - } -} - - -/**@brief Function for storage operation dummy handler. - * - * @param[in] p_dest Destination address where data is to be stored persistently. - * @param[in] p_src Source address containing data to be stored. API assumes this to be resident - * memory and no intermediate copy of data is made by the API. - * @param[in] size Size of data to be stored expressed in bytes. Should be word aligned. - * @param[in] offset Offset in bytes to be applied when writing to the block. - * For example, if within a block of 100 bytes, application wishes to - * write 20 bytes at offset of 12, then this field should be set to 12. - * Should be word aligned. - * - * @retval NRF_SUCCESS Operation success. - */ -static uint32_t storage_operation_dummy_handler(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset) -{ - return NRF_SUCCESS; -} - - -/**@brief Function for saving the device context persistently. - * - * @param[in] p_handle Device handle identifying device. - * @param[in] state Device store state. - */ -static __INLINE void device_context_store(dm_handle_t const * p_handle, device_store_state_t state) -{ - pstorage_handle_t block_handle; - storage_operation store_fn; - ret_code_t err_code; - - DM_LOG("[DM]: --> device_context_store\r\n"); - - err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - if (err_code == NRF_SUCCESS) - { - if ((STATE_BOND_INFO_UPDATE == - (m_connection_table[p_handle->connection_id].state & STATE_BOND_INFO_UPDATE)) || - (state == UPDATE_PEER_ADDR)) - { - DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> Updating bonding information.\r\n", - p_handle->device_id, p_handle->connection_id); - - store_fn = pstorage_update; - } - else if (state == FIRST_BOND_STORE) - { - DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> Storing bonding information.\r\n", - p_handle->device_id, p_handle->connection_id); - - store_fn = pstorage_store; - } - else - { - DM_LOG("[DM]:[DI %02X]:[CI %02X]: -> No update in bonding information.\r\n", - p_handle->device_id, p_handle->connection_id); - - //No operation needed. - store_fn = storage_operation_dummy_handler; - } - - //Store the peer id. - err_code = store_fn(&block_handle, - (uint8_t *)&m_peer_table[p_handle->device_id], - PEER_ID_SIZE, - PEER_ID_STORAGE_OFFSET); - - if ((err_code == NRF_SUCCESS) && (state != UPDATE_PEER_ADDR)) - { - m_connection_table[p_handle->connection_id].state &= (~STATE_BOND_INFO_UPDATE); - - //Store the bond information. - err_code = store_fn(&block_handle, - (uint8_t *)&m_bond_table[p_handle->connection_id], - BOND_SIZE, - BOND_STORAGE_OFFSET); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]:[0x%02X]:Failed to store bond information, reason 0x%08X\r\n", - p_handle->device_id, err_code); - } - } - - if (state != UPDATE_PEER_ADDR) - { - //Store the service information - err_code = m_service_context_store[m_application_table[p_handle->appl_id].service] - ( - &block_handle, - p_handle - ); - - if (err_code != NRF_SUCCESS) - { - //Notify application of an error event. - DM_ERR("[DM]: Failed to store service context, reason %08X\r\n", err_code); - } - } - } - - if (err_code != NRF_SUCCESS) - { - //Notify application of an error event. - DM_ERR("[DM]: Failed to store device context, reason %08X\r\n", err_code); - } -} - - -/**@brief Function for storing when there is no service registered. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is loaded. - * - * @retval NRF_SUCCESS - */ -static __INLINE ret_code_t no_service_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> no_service_context_store\r\n"); - - return NRF_SUCCESS; -} - - -/**@brief Function for storing GATT Server context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is stored. - * - * @retval NRF_SUCCESS Operation success. - */ -static __INLINE ret_code_t gatts_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - storage_operation store_fn; - uint32_t attr_flags = BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS | BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS; - uint16_t attr_len = DM_GATT_SERVER_ATTR_MAX_SIZE; - uint8_t sys_data[DM_GATT_SERVER_ATTR_MAX_SIZE]; - - DM_LOG("[DM]: --> gatts_context_store\r\n"); - - uint32_t err_code = sd_ble_gatts_sys_attr_get( - m_connection_table[p_handle->connection_id].conn_handle, - sys_data, - &attr_len, - attr_flags); - - if (err_code == NRF_SUCCESS) - { - if (memcmp(m_gatts_table[p_handle->connection_id].attributes, sys_data, attr_len) == 0) - { - //No store operation is needed. - DM_LOG("[DM]:[0x%02X]: No change in GATTS Context information.\r\n", - p_handle->device_id); - - if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) != - STATE_CONNECTED) - { - DM_LOG("[DM]:[0x%02X]: Resetting GATTS for active instance.\r\n", - p_handle->connection_id); - - //Reset GATTS information for the current context. - memset(&m_gatts_table[p_handle->connection_id], 0, sizeof(dm_gatts_context_t)); - } - } - else - { - if (m_gatts_table[p_handle->connection_id].size != 0) - { - //There is data already stored in persistent memory, therefore an update is needed. - DM_LOG("[DM]:[0x%02X]: Updating stored service context\r\n", p_handle->device_id); - - store_fn = pstorage_update; - } - else - { - //Fresh write, a store is needed. - DM_LOG("[DM]:[0x%02X]: Storing service context\r\n", p_handle->device_id); - - store_fn = pstorage_store; - } - - m_gatts_table[p_handle->connection_id].flags = attr_flags; - m_gatts_table[p_handle->connection_id].size = attr_len; - memcpy(m_gatts_table[p_handle->connection_id].attributes, sys_data, attr_len); - - DM_DUMP((uint8_t *)&m_gatts_table[p_handle->connection_id], sizeof(dm_gatts_context_t)); - - DM_LOG("[DM]:[0x%02X]: GATTS Data size 0x%08X\r\n", - p_handle->device_id, - m_gatts_table[p_handle->connection_id].size); - - //Store GATTS information. - err_code = store_fn((pstorage_handle_t *)p_block_handle, - (uint8_t *)&m_gatts_table[p_handle->connection_id], - GATTS_SERVICE_CONTEXT_SIZE, - SERVICE_STORAGE_OFFSET); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]:[0x%02X]:Failed to store service context, reason 0x%08X\r\n", - p_handle->device_id, - err_code); - } - else - { - DM_LOG("[DM]: Service context successfully stored.\r\n"); - } - } - } - - return NRF_SUCCESS; -} - - -/**@brief Function for storing GATT Client context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is stored. - * - * @retval NRF_SUCCESS Operation success. - */ -static __INLINE ret_code_t gattc_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> gattc_context_store\r\n"); - - return NRF_SUCCESS; -} - - -/**@brief Function for storing GATT Server & Client context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is stored. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - */ -static __INLINE ret_code_t gattsc_context_store(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> gattsc_context_store\r\n"); - - ret_code_t err_code = gatts_context_store(p_block_handle, p_handle); - - if (NRF_SUCCESS == err_code) - { - err_code = gattc_context_store(p_block_handle, p_handle); - } - - return err_code; -} - - -/**@brief Function for loading when there is no service registered. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is loaded. - * - * @retval NRF_SUCCESS - */ -static __INLINE ret_code_t no_service_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> no_service_context_load\r\n"); - - return NRF_SUCCESS; -} - - -/**@brief Function for loading GATT Server context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is loaded. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - */ -static __INLINE ret_code_t gatts_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: --> gatts_context_load\r\n", - p_handle->connection_id, - p_handle->device_id); - - ret_code_t err_code = pstorage_load((uint8_t *)&m_gatts_table[p_handle->connection_id], - (pstorage_handle_t *)p_block_handle, - GATTS_SERVICE_CONTEXT_SIZE, - SERVICE_STORAGE_OFFSET); - - if (err_code == NRF_SUCCESS) - { - DM_LOG("[DM]:[%02X]:[Block ID 0x%08X]: Service context loaded, size 0x%08X\r\n", - p_handle->connection_id, - p_block_handle->block_id, - m_gatts_table[p_handle->connection_id].size); - DM_DUMP((uint8_t *)&m_gatts_table[p_handle->connection_id], sizeof(dm_gatts_context_t)); - - if (m_gatts_table[p_handle->connection_id].size == DM_GATTS_INVALID_SIZE) - { - m_gatts_table[p_handle->connection_id].size = 0; - } - } - else - { - DM_ERR("[DM]:[%02X]: Failed to load Service context, reason %08X\r\n", - p_handle->connection_id, - err_code); - } - - return err_code; -} - - -/**@brief Function for loading GATT Client context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is loaded. - * - * @retval NRF_SUCCESS - */ -static __INLINE ret_code_t gattc_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> gattc_context_load\r\n"); - - return NRF_SUCCESS; -} - - -/**@brief Function for loading GATT Server & Client context. - * - * @param[in] p_block_handle Storage block identifier. - * @param[in] p_handle Device handle identifying device that is loaded. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - */ -static __INLINE ret_code_t gattsc_context_load(pstorage_handle_t const * p_block_handle, - dm_handle_t const * p_handle) -{ - DM_LOG("[DM]: --> gattsc_context_load\r\n"); - - ret_code_t err_code = gatts_context_load(p_block_handle, p_handle); - - if (NRF_SUCCESS == err_code) - { - err_code = gattc_context_load(p_block_handle, p_handle); - } - - return err_code; -} - - -/**@brief Function for applying when there is no service registered. - * - * @param[in] p_handle Device handle identifying device that is applied. - * - * @retval NRF_SUCCESS - */ -static __INLINE ret_code_t no_service_context_apply(dm_handle_t * p_handle) -{ - DM_LOG("[DM]: --> no_service_context_apply\r\n"); - DM_LOG("[DM]:[CI 0x%02X]: No Service context\r\n", p_handle->connection_id); - - return NRF_SUCCESS; -} - - -/**@brief Function for applying GATT Server context. - * - * @param[in] p_handle Device handle identifying device that is applied. - * - * @retval NRF_SUCCESS On success. - * @retval DM_SERVICE_CONTEXT_NOT_APPLIED On failure. - */ -static __INLINE ret_code_t gatts_context_apply(dm_handle_t * p_handle) -{ - uint32_t err_code; - - uint8_t * p_gatts_context = NULL; - uint16_t context_len = 0; - uint32_t context_flags = 0; - - DM_LOG("[DM]: --> gatts_context_apply\r\n"); - DM_LOG("[DM]:[CI 0x%02X]: State 0x%02X, Size 0x%08X\r\n", - p_handle->connection_id, - m_connection_table[p_handle->connection_id].state, - m_gatts_table[p_handle->connection_id].size); - - if ((m_gatts_table[p_handle->connection_id].size != 0) && - ( - ((m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED) && - ((m_connection_table[p_handle->connection_id].state & STATE_BOND_INFO_UPDATE) - != STATE_BOND_INFO_UPDATE) - ) - ) - { - DM_LOG("[DM]: Setting stored context.\r\n"); - - p_gatts_context = &m_gatts_table[p_handle->connection_id].attributes[0]; - context_len = m_gatts_table[p_handle->connection_id].size; - context_flags = m_gatts_table[p_handle->connection_id].flags; - } - - err_code = sd_ble_gatts_sys_attr_set(m_connection_table[p_handle->connection_id].conn_handle, - p_gatts_context, - context_len, - context_flags); - - if (err_code == NRF_ERROR_INVALID_DATA) - { - // Indication that the ATT table has changed. Restore the system attributes to system - // services only and send a service changed indication if possible. - context_flags = BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS; - err_code = sd_ble_gatts_sys_attr_set(m_connection_table[p_handle->connection_id].conn_handle, - p_gatts_context, - context_len, - context_flags); - } - - if (err_code != NRF_SUCCESS) - { - DM_LOG("[DM]: Failed to set system attributes, reason 0x%08X.\r\n", err_code); - - err_code = DM_SERVICE_CONTEXT_NOT_APPLIED; - } - - if (context_flags == BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS) - { - err_code = sd_ble_gatts_service_changed(m_connection_table[p_handle->connection_id].conn_handle, - 0x000C, - 0xFFFF); - if (err_code != NRF_SUCCESS) - { - DM_LOG("[DM]: Failed to send Service Changed indication, reason 0x%08X.\r\n", err_code); - if ((err_code != BLE_ERROR_INVALID_CONN_HANDLE) && - (err_code != NRF_ERROR_INVALID_STATE) && - (err_code != BLE_ERROR_NO_TX_BUFFERS) && - (err_code != NRF_ERROR_BUSY)) - { - // Those errors can be expected when sending trying to send Service Changed - // Indication if the CCCD is not set to indicate. Thus set the returning error - // code to success. - err_code = NRF_SUCCESS; - } - else - { - err_code = DM_SERVICE_CONTEXT_NOT_APPLIED; - } - } - } - - return err_code; -} - - -/**@brief Function for applying GATT Client context. - * - * @param[in] p_handle Device handle identifying device that is applied. - * - * @retval NRF_SUCCESS On success. - */ -static __INLINE ret_code_t gattc_context_apply(dm_handle_t * p_handle) -{ - DM_LOG("[DM]: --> gattc_context_apply\r\n"); - - return NRF_SUCCESS; -} - - -/**@brief Function for applying GATT Server & Client context. - * - * @param[in] p_handle Device handle identifying device that is applied. - * - * @retval NRF_SUCCESS On success, else an error code indicating reason for failure. - */ -static __INLINE ret_code_t gattsc_context_apply(dm_handle_t * p_handle) -{ - uint32_t err_code; - - DM_LOG("[DM]: --> gattsc_context_apply\r\n"); - - err_code = gatts_context_apply(p_handle); - - if (err_code == NRF_SUCCESS) - { - err_code = gattc_context_apply(p_handle); - } - - return err_code; -} - - -/**@brief Function for pstorage module callback. - * - * @param[in] p_handle Identifies module and block for which callback is received. - * @param[in] op_code Identifies the operation for which the event is notified. - * @param[in] result Identifies the result of flash access operation. - * NRF_SUCCESS implies, operation succeeded. - * @param[in] p_data Identifies the application data pointer. In case of store operation, this - * points to the resident source of application memory that application can now - * free or reuse. In case of clear, this is NULL as no application pointer is - * needed for this operation. - * @param[in] data_len Length of data provided by the application for the operation. - */ -static void dm_pstorage_cb_handler(pstorage_handle_t * p_handle, - uint8_t op_code, - uint32_t result, - uint8_t * p_data, - uint32_t data_len) -{ - VERIFY_APP_REGISTERED_VOID(0); - - if (data_len > ALL_CONTEXT_SIZE) - { - //Clearing of all bonds at initialization, no event is generated. - return; - } - - DM_MUTEX_LOCK(); - - dm_event_t dm_event; - dm_handle_t dm_handle; - dm_context_t context_data; - pstorage_handle_t block_handle; - uint32_t index_count; - uint32_t err_code; - - bool app_notify = true; - - err_code = dm_handle_initialize(&dm_handle); - APP_ERROR_CHECK(err_code); - - dm_handle.appl_id = 0; - dm_event.event_id = 0x00; - - //Construct the event which it is related to. - - //Initialize context data information and length. - context_data.p_data = p_data; - context_data.len = data_len; - - for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle); - if ((err_code == NRF_SUCCESS) && - ( - (memcmp(p_handle, &block_handle, sizeof(pstorage_handle_t)) == 0) - ) - ) - { - dm_handle.device_id = index; - break; - } - } - - if (dm_handle.device_id != DM_INVALID_ID) - { - if (op_code == PSTORAGE_CLEAR_OP_CODE) - { - if (data_len == ALL_CONTEXT_SIZE) - { - dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE; - } - else - { - dm_event.event_id = DM_EVT_APP_CONTEXT_BASE; - } - } - else - { - //Update or store operation. - //Context is identified based on the pointer value. Device context, application context - //and service context all have their own value range. - index_count = ((uint32_t)(p_data - (uint8_t *)m_peer_table)) / PEER_ID_SIZE; - - if (index_count < DEVICE_MANAGER_MAX_BONDS) - { - dm_event.event_param.p_device_context = &context_data; - - //Only the peer identification is stored, not bond information. Hence do not notify - //the application yet, unless the store operation resulted in a failure. - if ((result == NRF_SUCCESS) && - ( - (update_status_bit_is_set(dm_handle.device_id) == false) - ) - ) - { - app_notify = false; - } - else - { - //Reset update status since update is complete. - update_status_bit_reset(dm_handle.device_id); - - //Notify application of error in storing the context. - dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE; - } - } - else - { - index_count = ((uint32_t)(p_data - (uint8_t *)m_bond_table)) / BOND_SIZE; - - if (index_count < DEVICE_MANAGER_MAX_CONNECTIONS) - { - DM_LOG("[DM]:[0x%02X]:[0x%02X]: Bond context Event\r\n", - dm_handle.device_id, - dm_handle.connection_id); - - dm_event.event_param.p_device_context = &context_data; - dm_event.event_id = DM_EVT_DEVICE_CONTEXT_BASE; - dm_handle.connection_id = index_count; - - ble_gap_sec_keyset_t keys_exchanged; - keys_exchanged.keys_central.p_enc_key = NULL; - keys_exchanged.keys_central.p_id_key = &m_local_id_info; - keys_exchanged.keys_periph.p_enc_key = &m_bond_table[index_count].peer_enc_key; - keys_exchanged.keys_periph.p_id_key = - &m_peer_table[dm_handle.device_id].peer_id; - - //Context information updated to provide the keys. - context_data.p_data = (uint8_t *)&keys_exchanged; - context_data.len = sizeof(ble_gap_sec_keyset_t); - } - else - { - index_count = ((uint32_t)(p_data - (uint8_t *)m_gatts_table)) / - GATTS_SERVICE_CONTEXT_SIZE; - - if (index_count < DEVICE_MANAGER_MAX_CONNECTIONS) - { - DM_LOG("[DM]:[0x%02X]:[0x%02X]: Service context Event\r\n", - dm_handle.device_id, - dm_handle.connection_id); - - //Notify application. - dm_event.event_id = DM_EVT_SERVICE_CONTEXT_BASE; - dm_handle.connection_id = index_count; - dm_handle.service_id = DM_PROTOCOL_CNTXT_GATT_SRVR_ID; - - //Reset the service context now that it was successfully written to the - //application and the link is disconnected. - if ((m_connection_table[index_count].state & STATE_CONNECTED) != - STATE_CONNECTED) - { - DM_LOG("[DM]:[0x%02X]:[0x%02X]: Resetting bond information for " - "active instance.\r\n", - dm_handle.device_id, - dm_handle.connection_id); - - memset(&m_gatts_table[dm_handle.connection_id], - 0, - sizeof(dm_gatts_context_t)); - } - } - else - { - DM_LOG("[DM]:[0x%02X]:[0x%02X]: App context Event\r\n", - dm_handle.device_id, - dm_handle.connection_id); - - app_notify = false; - dm_event.event_id = DM_EVT_APP_CONTEXT_BASE; -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) - - if (p_data == (uint8_t *)(&m_context_init_len)) - { - //Context data is deleted. - //This is a workaround to get the right event as on delete operation - //update operation is used instead of clear. - op_code = PSTORAGE_CLEAR_OP_CODE; - app_notify = true; - } - else if (m_app_context_table[dm_handle.device_id] == p_data) - { - app_notify = true; - dm_event.event_param.p_app_context = &context_data; - - //Verify if the device is connected, if yes set connection instance. - for (uint32_t index = 0; - index < DEVICE_MANAGER_MAX_CONNECTIONS; - index++) - { - if (dm_handle.device_id == m_connection_table[index].bonded_dev_id) - { - dm_handle.connection_id = index; - break; - } - } - } - else - { - //No implementation needed. - } -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE - } - } - } - } - - if (app_notify == true) - { - if (op_code == PSTORAGE_CLEAR_OP_CODE) - { - dm_event.event_id |= DM_CLEAR_OPERATION_ID; - } - else if (op_code == PSTORAGE_LOAD_OP_CODE) - { - dm_event.event_id |= DM_LOAD_OPERATION_ID; - } - else - { - dm_event.event_id |= DM_STORE_OPERATION_ID; - } - - dm_event.event_param.p_app_context = &context_data; - app_evt_notify(&dm_handle, &dm_event, result); - } - } - - DM_MUTEX_UNLOCK(); -} - - -ret_code_t dm_init(dm_init_param_t const * const p_init_param) -{ - pstorage_module_param_t param; - pstorage_handle_t block_handle; - ret_code_t err_code; - uint32_t index; - - DM_LOG("[DM]: >> dm_init.\r\n"); - - NULL_PARAM_CHECK(p_init_param); - - SDK_MUTEX_INIT(m_dm_mutex); - - DM_MUTEX_LOCK(); - - for (index = 0; index < DEVICE_MANAGER_MAX_APPLICATIONS; index++) - { - application_instance_init(index); - } - - for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++) - { - connection_instance_init(index); - } - - memset(m_gatts_table, 0, sizeof(m_gatts_table)); - - //Initialization of all device instances. - for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - peer_instance_init(index); - m_irk_index_table[index] = DM_INVALID_ID; - } - - //All context with respect to a particular device is stored contiguously. - param.block_size = ALL_CONTEXT_SIZE; - param.block_count = DEVICE_MANAGER_MAX_BONDS; - param.cb = dm_pstorage_cb_handler; - - err_code = pstorage_register(¶m, &m_storage_handle); - - if (err_code == NRF_SUCCESS) - { - m_module_initialized = true; - - if (p_init_param->clear_persistent_data == false) - { - DM_LOG("[DM]: Storage handle 0x%08X.\r\n", m_storage_handle.block_id); - - //Copy bonded peer device address and IRK to RAM table. - - //Bonded devices are stored in range (0,DEVICE_MANAGER_MAX_BONDS-1). The remaining - //range is for active connections that may or may not be bonded. - for (index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - err_code = pstorage_block_identifier_get(&m_storage_handle, index, &block_handle); - - //Issue read request if you successfully get the block identifier. - if (err_code == NRF_SUCCESS) - { - DM_TRC("[DM]:[0x%02X]: Block handle 0x%08X.\r\n", index, block_handle.block_id); - - err_code = pstorage_load((uint8_t *)&m_peer_table[index], - &block_handle, - sizeof(peer_id_t), - 0); - - if (err_code != NRF_SUCCESS) - { - // In case a peer device could not be loaded successfully, rest of the - // initialization procedure are skipped and an error is sent to the - // application. - DM_ERR( - "[DM]: Failed to load peer device %08X from storage, reason %08X.\r\n", - index, - err_code); - - m_module_initialized = false; - break; - } - else - { - DM_TRC("[DM]:[DI 0x%02X]: Device type 0x%02X.\r\n", - index, - m_peer_table[index].peer_id.id_addr_info.addr_type); - DM_TRC("[DM]: Device Addr 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X.\r\n", - m_peer_table[index].peer_id.id_addr_info.addr[0], - m_peer_table[index].peer_id.id_addr_info.addr[1], - m_peer_table[index].peer_id.id_addr_info.addr[2], - m_peer_table[index].peer_id.id_addr_info.addr[3], - m_peer_table[index].peer_id.id_addr_info.addr[4], - m_peer_table[index].peer_id.id_addr_info.addr[5]); - } - } - else - { - //In case a peer device could not be loaded successfully, rest of the - //initialization procedure are skipped and an error is sent to the application. - DM_LOG("[DM]: Failed to get block handle for instance %08X, reason %08X.\r\n", - index, - err_code); - - m_module_initialized = false; - break; - } - } - } - else - { - err_code = pstorage_clear(&m_storage_handle, (param.block_size * param.block_count)); - DM_ERR("[DM]: Successfully requested clear of persistent data.\r\n"); - } - } - else - { - DM_ERR("[DM]: Failed to register with storage module, reason 0x%08X.\r\n", err_code); - } - - DM_MUTEX_UNLOCK(); - - DM_TRC("[DM]: << dm_init.\r\n"); - - return err_code; -} - - -ret_code_t dm_register(dm_application_instance_t * p_appl_instance, - dm_application_param_t const * p_appl_param) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_appl_instance); - NULL_PARAM_CHECK(p_appl_param); - NULL_PARAM_CHECK(p_appl_param->evt_handler); - - DM_MUTEX_LOCK(); - - DM_LOG("[DM]: >> dm_register.\r\n"); - - uint32_t err_code; - - //Verify if an application instance is available. Currently only one instance is supported. - if (m_application_table[0].ntf_cb == NULL) - { - DM_LOG("[DM]: Application Instance allocated.\r\n"); - - //Mark instance as allocated. - m_application_table[0].ntf_cb = p_appl_param->evt_handler; - m_application_table[0].sec_param = p_appl_param->sec_param; - m_application_table[0].service = p_appl_param->service_type; - - m_application_table[0].sec_param.kdist_central.enc = 0; - m_application_table[0].sec_param.kdist_central.id = 1; - m_application_table[0].sec_param.kdist_central.sign = 0; - m_application_table[0].sec_param.kdist_periph.enc = 1; - m_application_table[0].sec_param.kdist_periph.id = 1; - m_application_table[0].sec_param.kdist_periph.sign = 0; - //Populate application's instance variable with the assigned allocation instance. - *p_appl_instance = 0; - err_code = NRF_SUCCESS; - } - else - { - err_code = (NRF_ERROR_NO_MEM | DEVICE_MANAGER_ERR_BASE); - } - - DM_MUTEX_UNLOCK(); - - DM_TRC("[DM]: << dm_register.\r\n"); - - return err_code; -} - - -ret_code_t dm_security_setup_req(dm_handle_t * p_handle) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_CONNECTION_INSTANCE(p_handle->connection_id); - - DM_MUTEX_LOCK(); - - DM_LOG("[DM]: >> dm_security_setup_req\r\n"); - - uint32_t err_code = (NRF_ERROR_INVALID_STATE | DEVICE_MANAGER_ERR_BASE); - - if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) == STATE_CONNECTED) - { - err_code = sd_ble_gap_authenticate(m_connection_table[p_handle->connection_id].conn_handle, - &m_application_table[0].sec_param); - } - - DM_TRC("[DM]: << dm_security_setup_req, 0x%08X\r\n", err_code); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_security_status_req(dm_handle_t const * p_handle, - dm_security_status_t * p_status) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_status); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_CONNECTION_INSTANCE(p_handle->connection_id); - - DM_MUTEX_LOCK(); - - DM_LOG("[DM]: >> dm_security_status_req\r\n"); - - if ((m_connection_table[p_handle->connection_id].state & STATE_PAIRING) || - (m_connection_table[p_handle->connection_id].state & STATE_PAIRING_PENDING)) - { - (*p_status) = ENCRYPTION_IN_PROGRESS; - } - else if (m_connection_table[p_handle->connection_id].state & STATE_LINK_ENCRYPTED) - { - (*p_status) = ENCRYPTED; - } - else - { - (*p_status) = NOT_ENCRYPTED; - } - - DM_TRC("[DM]: << dm_security_status_req\r\n"); - - DM_MUTEX_UNLOCK(); - - return NRF_SUCCESS; -} - - -ret_code_t dm_whitelist_create(dm_application_instance_t const * p_handle, - ble_gap_whitelist_t * p_whitelist) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_whitelist); - NULL_PARAM_CHECK(p_whitelist->pp_addrs); - NULL_PARAM_CHECK(p_whitelist->pp_irks); - VERIFY_APP_REGISTERED(*p_handle); - - DM_MUTEX_LOCK(); - - DM_LOG("[DM]: >> dm_whitelist_create\r\n"); - - uint32_t addr_count = 0; - uint32_t irk_count = 0; - bool connected = false; - - for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - connected = false; - - for (uint32_t c_index = 0; c_index < DEVICE_MANAGER_MAX_CONNECTIONS; c_index++) - { - if ((index == m_connection_table[c_index].bonded_dev_id) && - ((m_connection_table[c_index].state & STATE_CONNECTED) == STATE_CONNECTED)) - { - connected = true; - break; - } - } - - if (connected == false) - { - if ((irk_count < p_whitelist->irk_count) && - ((m_peer_table[index].id_bitmap & IRK_ENTRY) == 0)) - { - p_whitelist->pp_irks[irk_count] = &m_peer_table[index].peer_id.id_info; - m_irk_index_table[irk_count] = index; - irk_count++; - } - - if ((addr_count < p_whitelist->addr_count) && - (m_peer_table[index].id_bitmap & ADDR_ENTRY) == 0) - { - p_whitelist->pp_addrs[addr_count] = &m_peer_table[index].peer_id.id_addr_info; - addr_count++; - } - } - } - - p_whitelist->addr_count = addr_count; - p_whitelist->irk_count = irk_count; - - DM_LOG("[DM]: Created whitelist, number of IRK = 0x%02X, number of addr = 0x%02X\r\n", - irk_count, - addr_count); - - DM_TRC("[DM]: << dm_whitelist_create\r\n"); - - DM_MUTEX_UNLOCK(); - - return NRF_SUCCESS; -} - - -ret_code_t dm_device_add(dm_handle_t * p_handle, - dm_device_context_t const * p_context) -{ - return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE); -} - - -ret_code_t dm_device_delete(dm_handle_t const * p_handle) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_device_delete\r\n"); - - uint32_t err_code = device_instance_free(p_handle->device_id); - - DM_TRC("[DM]: << dm_device_delete\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_device_delete_all(dm_application_instance_t const * p_handle) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED((*p_handle)); - - DM_MUTEX_LOCK(); - - uint32_t err_code = NRF_SUCCESS; - - DM_TRC("[DM]: >> dm_device_delete_all\r\n"); - - for (uint32_t index = 0; index < DEVICE_MANAGER_MAX_BONDS; index++) - { - if (m_peer_table[index].id_bitmap != UNASSIGNED) - { - err_code = device_instance_free(index); - } - } - - DM_TRC("[DM]: << dm_device_delete_all\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_service_context_set(dm_handle_t const * p_handle, - dm_service_context_t const * p_context) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_context); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_CONNECTION_INSTANCE(p_handle->connection_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_service_context_set\r\n"); - - if ((p_context->context_data.p_data != NULL) && - ( - (p_context->context_data.len != 0) && - (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE) - ) - ) - { - if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID) - { - memcpy(m_gatts_table[p_handle->connection_id].attributes, - p_context->context_data.p_data, - p_context->context_data.len); - } - } - - pstorage_handle_t block_handle; - uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - err_code = m_service_context_store[p_context->service_type](&block_handle, p_handle); - - DM_TRC("[DM]: << dm_service_context_set\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_service_context_get(dm_handle_t const * p_handle, - dm_service_context_t * p_context) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_context); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - if ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) != STATE_CONNECTED) - { - DM_TRC("[DM]: Device must be connected to get context. \r\n"); - - return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE); - } - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_service_context_get\r\n"); - - if ((p_context->context_data.p_data == NULL) && - (p_context->context_data.len < DM_GATT_SERVER_ATTR_MAX_SIZE)) - { - if (p_context->service_type == DM_PROTOCOL_CNTXT_GATT_SRVR_ID) - { - p_context->context_data.p_data = m_gatts_table[p_handle->connection_id].attributes; - p_context->context_data.len = m_gatts_table[p_handle->connection_id].size; - } - } - - pstorage_handle_t block_handle; - uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - err_code = m_service_context_load[p_context->service_type](&block_handle, p_handle); - - DM_TRC("[DM]: << dm_service_context_get\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_service_context_delete(dm_handle_t const * p_handle) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_LOG("[DM]: Context delete is not supported yet.\r\n"); - - return (API_NOT_IMPLEMENTED | DEVICE_MANAGER_ERR_BASE); -} - - -ret_code_t dm_application_context_set(dm_handle_t const * p_handle, - dm_application_context_t const * p_context) -{ -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_context); - NULL_PARAM_CHECK(p_context->p_data); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - VERIFY_DEVICE_BOND(p_handle->connection_id); - SIZE_CHECK_APP_CONTEXT(p_context->len); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_application_context_set\r\n"); - - uint32_t err_code; - uint32_t context_len; - pstorage_handle_t block_handle; - - storage_operation store_fn = pstorage_store; - - err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - if (err_code == NRF_SUCCESS) - { - err_code = pstorage_load((uint8_t *)&context_len, - &block_handle, - sizeof(uint32_t), - APP_CONTEXT_STORAGE_OFFSET); - - if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN)) - { - //Data already exists. Need an update. - store_fn = pstorage_update; - - DM_LOG("[DM]:[DI 0x%02X]: Updating existing application context, existing len 0x%08X, " - "new length 0x%08X.\r\n", - p_handle->device_id, - context_len, - p_context->len); - } - else - { - DM_LOG("[DM]: Storing application context.\r\n"); - } - - //Store/update context length. - err_code = store_fn(&block_handle, - (uint8_t *)(&p_context->len), - sizeof(uint32_t), - APP_CONTEXT_STORAGE_OFFSET); - - if (err_code == NRF_SUCCESS) - { - //Update context data is used for application context as flash is never - //cleared if a delete of application context is called. - err_code = pstorage_update(&block_handle, - p_context->p_data, - DEVICE_MANAGER_APP_CONTEXT_SIZE, - (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t))); - if (err_code == NRF_SUCCESS) - { - m_app_context_table[p_handle->device_id] = p_context->p_data; - } - } - } - - DM_TRC("[DM]: << dm_application_context_set\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; - -#else //DEVICE_MANAGER_APP_CONTEXT_SIZE - return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE); -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE -} - - -ret_code_t dm_application_context_get(dm_handle_t const * p_handle, - dm_application_context_t * p_context) -{ -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_context); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_application_context_get\r\n"); - - uint32_t context_len; - uint32_t err_code; - pstorage_handle_t block_handle; - - //Check if the context exists. - if (NULL == p_context->p_data) - { - p_context->p_data = m_app_context_table[p_handle->device_id]; - } - else - { - m_app_context_table[p_handle->device_id] = p_context->p_data; - } - - err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - if (err_code == NRF_SUCCESS) - { - err_code = pstorage_load((uint8_t *)&context_len, - &block_handle, - sizeof(uint32_t), - APP_CONTEXT_STORAGE_OFFSET); - - if ((err_code == NRF_SUCCESS) && (context_len != INVALID_CONTEXT_LEN)) - { - err_code = pstorage_load(p_context->p_data, - &block_handle, - DEVICE_MANAGER_APP_CONTEXT_SIZE, - (APP_CONTEXT_STORAGE_OFFSET + sizeof(uint32_t))); - if (err_code == NRF_SUCCESS) - { - p_context->len = context_len; - } - } - else - { - err_code = DM_NO_APP_CONTEXT; - } - } - - DM_TRC("[DM]: << dm_application_context_get\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; - -#else //DEVICE_MANAGER_APP_CONTEXT_SIZE - return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE); -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE -} - - -ret_code_t dm_application_context_delete(const dm_handle_t * p_handle) -{ -#if (DEVICE_MANAGER_APP_CONTEXT_SIZE != 0) - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_application_context_delete\r\n"); - - uint32_t err_code; - uint32_t context_len; - pstorage_handle_t block_handle; - - err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - - if (err_code == NRF_SUCCESS) - { - err_code = pstorage_load((uint8_t *)&context_len, - &block_handle, - sizeof(uint32_t), - APP_CONTEXT_STORAGE_OFFSET); - - if (context_len != m_context_init_len) - { - err_code = pstorage_update(&block_handle, - (uint8_t *)&m_context_init_len, - sizeof(uint32_t), - APP_CONTEXT_STORAGE_OFFSET); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]: Failed to delete application context, reason 0x%08X\r\n", err_code); - } - else - { - m_app_context_table[p_handle->device_id] = NULL; - } - } - } - - DM_TRC("[DM]: << dm_application_context_delete\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -#else //DEVICE_MANAGER_APP_CONTEXT_SIZE - return (FEATURE_NOT_ENABLED | DEVICE_MANAGER_ERR_BASE); -#endif //DEVICE_MANAGER_APP_CONTEXT_SIZE -} - - -ret_code_t dm_application_instance_set(dm_application_instance_t const * p_appl_instance, - dm_handle_t * p_handle) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_appl_instance); - VERIFY_APP_REGISTERED((*p_appl_instance)); - - p_handle->appl_id = (*p_appl_instance); - - return NRF_SUCCESS; -} - - -uint32_t dm_handle_initialize(dm_handle_t * p_handle) -{ - NULL_PARAM_CHECK(p_handle); - - p_handle->appl_id = DM_INVALID_ID; - p_handle->connection_id = DM_INVALID_ID; - p_handle->device_id = DM_INVALID_ID; - p_handle->service_id = DM_INVALID_ID; - - return NRF_SUCCESS; -} - - -ret_code_t dm_peer_addr_set(dm_handle_t const * p_handle, - ble_gap_addr_t const * p_addr) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_addr); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_peer_addr_set\r\n"); - - ret_code_t err_code; - - if ((p_handle->connection_id == DM_INVALID_ID) && - (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)) - { - m_peer_table[p_handle->device_id].peer_id.id_addr_info = (*p_addr); - update_status_bit_set(p_handle->device_id); - device_context_store(p_handle, UPDATE_PEER_ADDR); - err_code = NRF_SUCCESS; - } - else - { - err_code = (NRF_ERROR_INVALID_PARAM | DEVICE_MANAGER_ERR_BASE); - } - - DM_TRC("[DM]: << dm_peer_addr_set\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_peer_addr_get(dm_handle_t const * p_handle, - ble_gap_addr_t * p_addr) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_addr); - VERIFY_APP_REGISTERED(p_handle->appl_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_peer_addr_get\r\n"); - - ret_code_t err_code; - - err_code = (NRF_ERROR_NOT_FOUND | DEVICE_MANAGER_ERR_BASE); - - if (p_handle->device_id == DM_INVALID_ID) - { - if ((p_handle->connection_id != DM_INVALID_ID) && - ((m_connection_table[p_handle->connection_id].state & STATE_CONNECTED) == - STATE_CONNECTED)) - { - DM_TRC("[DM]:[CI 0x%02X]: Address get for non bonded active connection.\r\n", - p_handle->connection_id); - - (*p_addr) = m_connection_table[p_handle->connection_id].peer_addr; - err_code = NRF_SUCCESS; - } - } - else - { - if ((m_peer_table[p_handle->device_id].id_bitmap & ADDR_ENTRY) == 0) - { - DM_TRC("[DM]:[DI 0x%02X]: Address get for bonded device.\r\n", - p_handle->device_id); - - (*p_addr) = m_peer_table[p_handle->device_id].peer_id.id_addr_info; - err_code = NRF_SUCCESS; - } - } - - DM_TRC("[DM]: << dm_peer_addr_get\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -ret_code_t dm_distributed_keys_get(dm_handle_t const * p_handle, - dm_sec_keyset_t * p_key_dist) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_handle); - NULL_PARAM_CHECK(p_key_dist); - VERIFY_APP_REGISTERED(p_handle->appl_id); - VERIFY_DEVICE_INSTANCE(p_handle->device_id); - - DM_MUTEX_LOCK(); - - DM_TRC("[DM]: >> dm_distributed_keys_get\r\n"); - - ret_code_t err_code; - ble_gap_enc_key_t peer_enc_key; - pstorage_handle_t block_handle; - - err_code = NRF_ERROR_NOT_FOUND; - p_key_dist->keys_central.enc_key.p_enc_key = NULL; - p_key_dist->keys_central.p_id_key = (dm_id_key_t *)&m_peer_table[p_handle->device_id].peer_id; - p_key_dist->keys_central.p_sign_key = NULL; - p_key_dist->keys_periph.p_id_key = (dm_id_key_t *)&m_local_id_info; - p_key_dist->keys_periph.p_sign_key = NULL; - p_key_dist->keys_periph.enc_key.p_enc_key = (dm_enc_key_t *)&peer_enc_key; - - if ((m_peer_table[p_handle->device_id].id_bitmap & IRK_ENTRY) == 0) - { -// p_key_dist->keys_periph.p_id_key->id_addr_info.addr_type = INVALID_ADDR_TYPE; - } - - err_code = pstorage_block_identifier_get(&m_storage_handle, p_handle->device_id, &block_handle); - if (err_code == NRF_SUCCESS) - { - - err_code = pstorage_load((uint8_t *)&peer_enc_key, - &block_handle, - BOND_SIZE, - BOND_STORAGE_OFFSET); - - if (err_code == NRF_SUCCESS) - { - p_key_dist->keys_central.enc_key.p_enc_key = NULL; - p_key_dist->keys_central.p_id_key = (dm_id_key_t *)&m_peer_table[p_handle->device_id].peer_id; - p_key_dist->keys_central.p_sign_key = NULL; - p_key_dist->keys_periph.p_id_key = (dm_id_key_t *)&m_local_id_info; - p_key_dist->keys_periph.p_sign_key = NULL; - p_key_dist->keys_periph.enc_key.p_enc_key = (dm_enc_key_t *)&peer_enc_key; - } - } - - DM_TRC("[DM]: << dm_distributed_keys_get\r\n"); - - DM_MUTEX_UNLOCK(); - - return err_code; -} - - -/**@brief Function for loading bond information for a connection instance. - */ -void bond_data_load(dm_handle_t * p_handle) -{ - pstorage_handle_t block_handle; - - uint32_t err_code = pstorage_block_identifier_get(&m_storage_handle, - p_handle->device_id, - &block_handle); - if (err_code == NRF_SUCCESS) - { - DM_LOG( - "[DM]:[%02X]:[Block ID 0x%08X]:Loading bond information at %p, size 0x%08X, offset 0x%08X.\r\n", - p_handle->connection_id, - block_handle.block_id, - &m_bond_table[p_handle->connection_id], - BOND_SIZE, - BOND_STORAGE_OFFSET); - - err_code = pstorage_load((uint8_t *)&m_bond_table[p_handle->connection_id], - &block_handle, - BOND_SIZE, - BOND_STORAGE_OFFSET); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]:[%02X]: Failed to load Bond information, reason %08X\r\n", - p_handle->connection_id, - err_code); - } - - DM_LOG( - "[DM]:[%02X]:Loading service context at %p, size 0x%08X, offset 0x%08X.\r\n", - p_handle->connection_id, - &m_gatts_table[p_handle->connection_id], - sizeof(dm_gatts_context_t), - SERVICE_STORAGE_OFFSET); - - err_code = m_service_context_load[m_application_table[0].service]( - &block_handle, - p_handle); - - if (err_code != NRF_SUCCESS) - { - DM_ERR( - "[DM]:[%02X]: Failed to load service information, reason %08X\r\n", - p_handle->connection_id, - err_code); - } - } - else - { - DM_ERR("[DM]:[%02X]: Failed to get block identifier for " - "device %08X, reason %08X.\r\n", p_handle->connection_id, p_handle->device_id, err_code); - } -} - - -void dm_ble_evt_handler(ble_evt_t * p_ble_evt) -{ - uint32_t err_code; - uint32_t index; - uint32_t device_index = DM_INVALID_ID; - bool notify_app = false; - dm_handle_t handle; - dm_event_t event; - uint32_t event_result; - ble_gap_enc_info_t * p_enc_info = NULL; - - VERIFY_MODULE_INITIALIZED_VOID(); - VERIFY_APP_REGISTERED_VOID(0); - DM_MUTEX_LOCK(); - - err_code = dm_handle_initialize(&handle); - APP_ERROR_CHECK(err_code); - - event_result = NRF_SUCCESS; - err_code = NRF_SUCCESS; - event.event_param.p_gap_param = &p_ble_evt->evt.gap_evt; - event.event_paramlen = sizeof(ble_gap_evt_t); - handle.device_id = DM_INVALID_ID; - handle.appl_id = 0; - index = 0x00; - - if (p_ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED) - { - err_code = connection_instance_find(p_ble_evt->evt.gap_evt.conn_handle, - STATE_CONNECTED, - &index); - - if (err_code == NRF_SUCCESS) - { - handle.device_id = m_connection_table[index].bonded_dev_id; - handle.connection_id = index; - } - } - - switch (p_ble_evt->header.evt_id) - { - case BLE_GAP_EVT_CONNECTED: - //Allocate connection instance for a new connection. - err_code = connection_instance_allocate(&index); - - //Connection instance is successfully allocated. - if (err_code == NRF_SUCCESS) - { - //Application notification related information. - notify_app = true; - event.event_id = DM_EVT_CONNECTION; - handle.connection_id = index; - - m_connection_table[index].conn_handle = p_ble_evt->evt.gap_evt.conn_handle; - m_connection_table[index].state = STATE_CONNECTED; - m_connection_table[index].peer_addr = - p_ble_evt->evt.gap_evt.params.connected.peer_addr; - - if (p_ble_evt->evt.gap_evt.params.connected.irk_match == 1) - { - if (m_irk_index_table[p_ble_evt->evt.gap_evt.params.connected.irk_match_idx] != DM_INVALID_ID) - { - device_index = m_irk_index_table[p_ble_evt->evt.gap_evt.params.connected.irk_match_idx]; - err_code = NRF_SUCCESS; - } - } - else - { - //Use the device address to check if the device exists in the bonded device list. - err_code = device_instance_find(&p_ble_evt->evt.gap_evt.params.connected.peer_addr, - &device_index, EDIV_INIT_VAL); - } - - if (err_code == NRF_SUCCESS) - { - m_connection_table[index].bonded_dev_id = device_index; - m_connection_table[index].state |= STATE_BONDED; - handle.device_id = device_index; - - bond_data_load(&handle); - } - } - break; - - case BLE_GAP_EVT_DISCONNECTED: - //Disconnection could be peer or self initiated hence disconnecting and connecting - //both states are permitted, however, connection handle must be known. - DM_LOG("[DM]: Disconnect Reason 0x%04X\r\n", - p_ble_evt->evt.gap_evt.params.disconnected.reason); - - m_connection_table[index].state &= (~STATE_CONNECTED); - - if ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED) - { - if ((m_connection_table[index].state & STATE_LINK_ENCRYPTED) == STATE_LINK_ENCRYPTED) - { - //Write bond information persistently. - device_context_store(&handle, STORE_ALL_CONTEXT); - } - } - else - { - //Free any allocated instances for devices that is not bonded. - if (handle.device_id != DM_INVALID_ID) - { - peer_instance_init(handle.device_id); - handle.device_id = DM_INVALID_ID; - } - } - - m_connection_table[index].state = STATE_DISCONNECTING; - notify_app = true; - event.event_id = DM_EVT_DISCONNECTION; - - break; - - case BLE_GAP_EVT_SEC_INFO_REQUEST: - DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_INFO_REQUEST\r\n"); - - //If the device is already bonded, respond with existing info, else NULL. - if (m_connection_table[index].bonded_dev_id == DM_INVALID_ID) - { - //Find device based on div. - err_code = device_instance_find(NULL,&device_index, p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.ediv); - if (err_code == NRF_SUCCESS) - { - //Load needed bonding information. - m_connection_table[index].bonded_dev_id = device_index; - m_connection_table[index].state |= STATE_BONDED; - handle.device_id = device_index; - bond_data_load(&handle); - } - } - - if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID) - { - p_enc_info = &m_bond_table[index].peer_enc_key.enc_info; - DM_DUMP((uint8_t *)p_enc_info, sizeof(ble_gap_enc_info_t)); - } - - err_code = sd_ble_gap_sec_info_reply(p_ble_evt->evt.gap_evt.conn_handle, - p_enc_info, - &m_peer_table[index].peer_id.id_info, - NULL); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]:[CI %02X]:[DI %02X]: Security information response failed, reason " - "0x%08X\r\n", index, m_connection_table[index].bonded_dev_id, err_code); - } - break; - - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_PARAMS_REQUEST\r\n"); - - event.event_id = DM_EVT_SECURITY_SETUP; - - m_connection_table[index].state |= STATE_PAIRING; - notify_app = true; - - if (m_connection_table[index].bonded_dev_id == DM_INVALID_ID) - { - //Assign a peer index as a new bond or update existing bonds. - err_code = device_instance_allocate((uint8_t *)&device_index, - &m_connection_table[index].peer_addr); - - //Allocation successful. - if (err_code == NRF_SUCCESS) - { - DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n",index, device_index); - - handle.device_id = device_index; - m_connection_table[index].bonded_dev_id = device_index; - } - else - { - DM_LOG("[DM]: Security parameter request failed, reason 0x%08X.\r\n", err_code); - event_result = err_code; - notify_app = true; - } - } - else - { - //Bond/key refresh. - event.event_id = DM_EVT_SECURITY_SETUP_REFRESH; - memset(m_gatts_table[index].attributes, 0, DM_GATT_SERVER_ATTR_MAX_SIZE); - - //Set the update flag for bond data. - m_connection_table[index].state |= STATE_BOND_INFO_UPDATE; - } - - ble_gap_sec_keyset_t keys_exchanged; - - DM_LOG("[DM]: 0x%02X, 0x%02X, 0x%02X, 0x%02X\r\n", - p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.enc, - p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_central.id, - p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.kdist_periph.sign, - p_ble_evt->evt.gap_evt.params.sec_params_request.peer_params.bond); - - keys_exchanged.keys_central.p_enc_key = NULL; - keys_exchanged.keys_central.p_id_key = &m_peer_table[m_connection_table[index].bonded_dev_id].peer_id; - keys_exchanged.keys_central.p_sign_key = NULL; - keys_exchanged.keys_periph.p_enc_key = &m_bond_table[index].peer_enc_key; - keys_exchanged.keys_periph.p_id_key = NULL; - keys_exchanged.keys_periph.p_sign_key = NULL; - - err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, - BLE_GAP_SEC_STATUS_SUCCESS, - &m_application_table[0].sec_param, - &keys_exchanged); - - if (err_code != NRF_SUCCESS) - { - DM_LOG("[DM]: Security parameter reply request failed, reason 0x%08X.\r\n", err_code); - event_result = err_code; - notify_app = false; - } - break; - - case BLE_GAP_EVT_AUTH_STATUS: - { - DM_LOG("[DM]: >> BLE_GAP_EVT_AUTH_STATUS, status %08X\r\n", - p_ble_evt->evt.gap_evt.params.auth_status.auth_status); - - m_application_table[0].state &= (~STATE_CONTROL_PROCEDURE_IN_PROGRESS); - m_connection_table[index].state &= (~STATE_PAIRING); - event.event_id = DM_EVT_SECURITY_SETUP_COMPLETE; - notify_app = true; - - if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status != BLE_GAP_SEC_STATUS_SUCCESS) - { - // Free the allocation as bonding failed. - ret_code_t result = device_instance_free(m_connection_table[index].bonded_dev_id); - (void) result; - event_result = p_ble_evt->evt.gap_evt.params.auth_status.auth_status; - } - else - { - DM_DUMP((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status, - sizeof(ble_gap_evt_auth_status_t)); - DM_DUMP((uint8_t *)&m_bond_table[index], sizeof(bond_context_t)); - - if (p_ble_evt->evt.gap_evt.params.auth_status.bonded == 1) - { - if (handle.device_id != DM_INVALID_ID) - { - m_connection_table[index].state |= STATE_BONDED; - - //IRK and/or public address is shared, update it. - if (p_ble_evt->evt.gap_evt.params.auth_status.kdist_central.id == 1) - { - m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY); - } - - if (m_connection_table[index].bonded_dev_id != DM_INVALID_ID) - { - DM_LOG("[DM]:[CI 0x%02X]:[DI 0x%02X]: Bonded!\r\n", - index, - handle.device_id); - - if (m_connection_table[index].peer_addr.addr_type != - BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE) - { - m_peer_table[handle.device_id].peer_id.id_addr_info = - m_connection_table[index].peer_addr; - m_peer_table[handle.device_id].id_bitmap &= (~ADDR_ENTRY); - - DM_DUMP((uint8_t *)&m_peer_table[handle.device_id].peer_id.id_addr_info, - sizeof(m_peer_table[handle.device_id].peer_id.id_addr_info)); - } - else - { - // Here we must fetch the keys from the keyset distributed. - m_peer_table[handle.device_id].ediv = m_bond_table[index].peer_enc_key.master_id.ediv; - m_peer_table[handle.device_id].id_bitmap &= (~IRK_ENTRY); - } - - device_context_store(&handle, FIRST_BOND_STORE); - } - } - } - else - { - //Pairing request, no need to touch the bonding info. - } - } - break; - } - - case BLE_GAP_EVT_CONN_SEC_UPDATE: - DM_LOG("[DM]: >> BLE_GAP_EVT_CONN_SEC_UPDATE, Mode 0x%02X, Level 0x%02X\r\n", - p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm, - p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv); - - if ((p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv == 1) && - (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm == 1) && - ((m_connection_table[index].state & STATE_BONDED) == STATE_BONDED)) - { - //Lost bond case, generate a security refresh event! - memset(m_gatts_table[index].attributes, 0, DM_GATT_SERVER_ATTR_MAX_SIZE); - - event.event_id = DM_EVT_SECURITY_SETUP_REFRESH; - m_connection_table[index].state |= STATE_PAIRING_PENDING; - m_connection_table[index].state |= STATE_BOND_INFO_UPDATE; - m_application_table[0].state |= STATE_QUEUED_CONTROL_REQUEST; - } - else - { - m_connection_table[index].state |= STATE_LINK_ENCRYPTED; - event.event_id = DM_EVT_LINK_SECURED; - - //Apply service context. - err_code = m_service_context_apply[m_application_table[0].service](&handle); - - if (err_code != NRF_SUCCESS) - { - DM_ERR("[DM]:[CI 0x%02X]:[DI 0x%02X]: Failed to apply service context\r\n", - handle.connection_id, - handle.device_id); - - event_result = DM_SERVICE_CONTEXT_NOT_APPLIED; - } - } - event_result = NRF_SUCCESS; - notify_app = true; - - break; - - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - DM_LOG("[DM]: >> BLE_GATTS_EVT_SYS_ATTR_MISSING\r\n"); - - //Apply service context. - event_result = m_service_context_apply[m_application_table[0].service](&handle); - break; - - case BLE_GAP_EVT_SEC_REQUEST: - DM_LOG("[DM]: >> BLE_GAP_EVT_SEC_REQUEST\r\n"); - - //Verify if the device is already bonded, and if it is bonded, initiate encryption. - //If the device is not bonded, an instance needs to be allocated in order to initiate - //bonding. The application have to initiate the procedure, the module will not do this - //automatically. - event.event_id = DM_EVT_SECURITY_SETUP; - notify_app = true; - - break; - - default: - break; - } - - if (notify_app) - { - app_evt_notify(&handle, &event, event_result); - - //Freeing the instance after the event is notified so the application can get the context. - if (event.event_id == DM_EVT_DISCONNECTION) - { - //Free the instance. - connection_instance_free(&index); - } - } - - UNUSED_VARIABLE(err_code); - - DM_MUTEX_UNLOCK(); -} - - -ret_code_t dm_handle_get(uint16_t conn_handle, dm_handle_t * p_handle) -{ - ret_code_t err_code; - uint32_t index; - - NULL_PARAM_CHECK(p_handle); - VERIFY_APP_REGISTERED(p_handle->appl_id); - - p_handle->device_id = DM_INVALID_ID; - - err_code = NRF_ERROR_NOT_FOUND; - - for (index = 0; index < DEVICE_MANAGER_MAX_CONNECTIONS; index++) - { - //Search for matching connection handle. - if (conn_handle == m_connection_table[index].conn_handle) - { - p_handle->connection_id = index; - p_handle->device_id = m_connection_table[index].bonded_dev_id; - - err_code = NRF_SUCCESS; - break; - } - } - return err_code; -} diff --git a/components/ble/nrf_ble_gatt/nrf_ble_gatt.c b/components/ble/nrf_ble_gatt/nrf_ble_gatt.c new file mode 100644 index 0000000..b5adf6d --- /dev/null +++ b/components/ble/nrf_ble_gatt/nrf_ble_gatt.c @@ -0,0 +1,303 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + + +#include "sdk_config.h" +#if NRF_BLE_GATT_ENABLED +#include "nrf_ble_gatt.h" +#include "ble_srv_common.h" +#include "sdk_common.h" +#include "app_error.h" +#include "sdk_macros.h" +#define NRF_LOG_MODULE_NAME "BLE_GATT" +#include "nrf_log.h" + + +#if (NRF_SD_BLE_API_VERSION == 3) +/**@brief Handle a connected event. + * + * @param[in] p_gatt GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void on_connected_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t * p_ble_evt) +{ + ret_code_t err_code; + uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle; + + if(p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH) + { + p_gatt->links[conn_handle].att_mtu_desired = p_gatt->att_mtu_desired_periph; + } + if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_CENTRAL) + { + p_gatt->links[conn_handle].att_mtu_desired = p_gatt->att_mtu_desired_central; + } + if (p_gatt->links[conn_handle].att_mtu_desired > GATT_MTU_SIZE_DEFAULT) + { + err_code = sd_ble_gattc_exchange_mtu_request(conn_handle, + p_gatt->links[conn_handle].att_mtu_desired); + if (err_code == NRF_ERROR_BUSY) + { + NRF_LOG_DEBUG("exchange_mtu_request for conn_handle %d returned busy, will retry\r\n", + conn_handle); + p_gatt->links[conn_handle].is_request_pending = true; + } + if (err_code == NRF_SUCCESS) + { + NRF_LOG_INFO("request ATT MTU %d for conn_handle %d \r\n", + p_gatt->links[conn_handle].att_mtu_desired, conn_handle); + } + } +} +#endif //(NRF_SD_BLE_API_VERSION == 3) + + +#if (NRF_SD_BLE_API_VERSION == 3) +/**@brief Handle a EXCHANGE_MTU_RSP event. + * + * @param[in] p_gatt GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void on_exchange_mtu_rsp_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t * p_ble_evt) +{ + uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle; + uint16_t server_rx_mtu = p_ble_evt->evt.gattc_evt.params.exchange_mtu_rsp.server_rx_mtu; + + p_gatt->links[conn_handle].att_mtu_effective = MIN(server_rx_mtu, + p_gatt->links[conn_handle].att_mtu_desired); + if (p_gatt->links[conn_handle].att_mtu_effective < GATT_MTU_SIZE_DEFAULT) + { + p_gatt->links[conn_handle].att_mtu_effective = GATT_MTU_SIZE_DEFAULT; + } + NRF_LOG_INFO("EXCHANGE_MTU_RSP effective ATT MTU is %d for conn_handle %d \r\n", + p_gatt->links[conn_handle].att_mtu_effective, conn_handle); + /*trigger an event indicating that the ATT MTU size has changed to m_effective_att_mtu*/ + if(p_gatt->evt_handler != NULL) + { + nrf_ble_gatt_evt_t evt; + evt.conn_handle = conn_handle; + evt.att_mtu_effective = p_gatt->links[conn_handle].att_mtu_effective; + p_gatt->evt_handler(p_gatt, &evt); + } + p_gatt->links[conn_handle].is_request_pending = false; +} +#endif //(NRF_SD_BLE_API_VERSION == 3) + + +#if (NRF_SD_BLE_API_VERSION == 3) +/**@brief Handle a EXCHANGE_MTU_REQUEST event. + * + * @param[in] p_gatt GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void on_exchange_mtu_request_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t * p_ble_evt) +{ + ret_code_t err_code; + uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle; + uint16_t clt_mtu = p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu; + + if (clt_mtu < GATT_MTU_SIZE_DEFAULT) + { + clt_mtu = GATT_MTU_SIZE_DEFAULT; + } + err_code = sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle, + p_gatt->links[conn_handle].att_mtu_desired); + APP_ERROR_CHECK(err_code); + p_gatt->links[conn_handle].att_mtu_effective = MIN(clt_mtu, + p_gatt->links[conn_handle].att_mtu_desired); + NRF_LOG_INFO("EXCHANGE_MTU_REQUEST effective ATT MTU is %d for conn_handle %d \r\n", + p_gatt->links[conn_handle].att_mtu_desired, conn_handle); + /*trigger an event indicating that the ATT MTU size has changed to m_effective_att_mtu*/ + if(p_gatt->evt_handler != NULL) + { + nrf_ble_gatt_evt_t evt; + evt.conn_handle = conn_handle; + evt.att_mtu_effective = p_gatt->links[conn_handle].att_mtu_effective; + p_gatt->evt_handler(p_gatt, &evt); + } + p_gatt->links[conn_handle].is_request_pending = false; +} +#endif //(NRF_SD_BLE_API_VERSION == 3) + + +#if (NRF_SD_BLE_API_VERSION == 3) +/**@brief Handle a DATA_LENGTH_CHANGED event. + * + * @param[in] p_gatt GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void on_data_length_changed_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t * p_ble_evt) +{ + uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle; + + NRF_LOG_INFO("Data Length Extended (DLE) for conn_handle %d \r\n", conn_handle); + NRF_LOG_DEBUG("max_rx_octets %d \r\n", + p_ble_evt->evt.common_evt.params.data_length_changed.max_rx_octets); + NRF_LOG_DEBUG("max_rx_time %d \r\n", + p_ble_evt->evt.common_evt.params.data_length_changed.max_rx_time); + NRF_LOG_DEBUG("max_tx_octets %d \r\n", + p_ble_evt->evt.common_evt.params.data_length_changed.max_tx_octets); + NRF_LOG_DEBUG("max_tx_time %d \r\n", + p_ble_evt->evt.common_evt.params.data_length_changed.max_tx_time); +} +#endif //(NRF_SD_BLE_API_VERSION == 3) + + +ret_code_t nrf_ble_gatt_init(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_handler_t evt_handler) +{ +#if (NRF_SD_BLE_API_VERSION == 3) + VERIFY_PARAM_NOT_NULL(p_gatt); + p_gatt->att_mtu_desired_periph = NRF_BLE_GATT_MAX_MTU_SIZE; + p_gatt->att_mtu_desired_central = NRF_BLE_GATT_MAX_MTU_SIZE; + for (uint8_t i = 0; i < NRF_BLE_GATT_LINK_COUNT; i++) + { + p_gatt->links[i].att_mtu_desired = NRF_BLE_GATT_MAX_MTU_SIZE; + p_gatt->links[i].att_mtu_effective = GATT_MTU_SIZE_DEFAULT; + p_gatt->links[i].is_request_pending = false; + } + p_gatt->evt_handler = evt_handler; +#endif + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_gatt_att_mtu_periph_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu) +{ +#if (NRF_SD_BLE_API_VERSION == 3) + VERIFY_PARAM_NOT_NULL(p_gatt); + + if ((desired_mtu < GATT_MTU_SIZE_DEFAULT) + ||(desired_mtu > NRF_BLE_GATT_MAX_MTU_SIZE)) + { + return NRF_ERROR_INVALID_PARAM; + } + p_gatt->att_mtu_desired_periph = desired_mtu; + return NRF_SUCCESS; +#endif +#if (NRF_SD_BLE_API_VERSION == 2) + return NRF_ERROR_NOT_SUPPORTED; +#endif +} + + +ret_code_t nrf_ble_gatt_att_mtu_central_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu) +{ +#if (NRF_SD_BLE_API_VERSION == 3) + VERIFY_PARAM_NOT_NULL(p_gatt); + + if ((desired_mtu < GATT_MTU_SIZE_DEFAULT) + ||(desired_mtu > NRF_BLE_GATT_MAX_MTU_SIZE)) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_gatt->att_mtu_desired_central = desired_mtu; + return NRF_SUCCESS; +#endif +#if (NRF_SD_BLE_API_VERSION == 2) + return NRF_ERROR_NOT_SUPPORTED; +#endif +} + + +uint16_t nrf_ble_gatt_eff_mtu_get(nrf_ble_gatt_t * p_gatt, uint16_t conn_handle) +{ +#if (NRF_SD_BLE_API_VERSION == 3) + if ((p_gatt == NULL)||(conn_handle >= NRF_BLE_GATT_LINK_COUNT)) + { + return 0; + } + return p_gatt->links[conn_handle].att_mtu_effective; +#endif +#if (NRF_SD_BLE_API_VERSION == 2) + return GATT_MTU_SIZE_DEFAULT; +#endif +} + + +void nrf_ble_gatt_on_ble_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t * p_ble_evt) +{ +#if (NRF_SD_BLE_API_VERSION == 3) + uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle; + if (conn_handle >= NRF_BLE_GATT_LINK_COUNT) + { + return; + } + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + on_connected_evt(p_gatt, p_ble_evt); + break; // BLE_GAP_EVT_CONNECTED + + case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: + on_exchange_mtu_rsp_evt(p_gatt, p_ble_evt); + break; // BLE_GATTC_EVT_EXCHANGE_MTU_RSP + + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + on_exchange_mtu_request_evt(p_gatt, p_ble_evt); + break; // BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST + + case BLE_EVT_DATA_LENGTH_CHANGED : + on_data_length_changed_evt(p_gatt, p_ble_evt); + break; // BLE_EVT_DATA_LENGTH_CHANGED + + default: + break; + } + if (p_gatt->links[conn_handle].is_request_pending) + { + ret_code_t err_code; + p_gatt->links[conn_handle].is_request_pending = false; + err_code = sd_ble_gattc_exchange_mtu_request(conn_handle, + p_gatt->links[conn_handle].att_mtu_desired); + if (err_code == NRF_ERROR_BUSY) + { + p_gatt->links[conn_handle].is_request_pending = true; + } + if (err_code == NRF_SUCCESS) + { + NRF_LOG_INFO("sent pending request ATT MTU %d for conn_handle %d \r\n", + p_gatt->links[conn_handle].att_mtu_desired, conn_handle); + } + } +#endif //(NRF_SD_BLE_API_VERSION == 3) +} + +#endif //NRF_BLE_GATT_ENABLED diff --git a/components/ble/nrf_ble_gatt/nrf_ble_gatt.h b/components/ble/nrf_ble_gatt/nrf_ble_gatt.h new file mode 100644 index 0000000..fb92b00 --- /dev/null +++ b/components/ble/nrf_ble_gatt/nrf_ble_gatt.h @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup nrf_ble_gatt GATT module + * @{ + * @ingroup ble_sdk_lib + * @brief Module for negotiating and keeping track of the maximum ATT_MTU size. + */ + +#ifndef NRF_BLE_GATT_H__ +#define NRF_BLE_GATT_H__ + +#include +#include +#include +#include "ble.h" +#include "app_util.h" +#include "sdk_errors.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Default maximum ATT_MTU size. + * + * This define specifies a fallback value for the case where + * NRF_BLE_GATT_MAX_MTU_SIZE is not set in the @ref nrf_ble_gatt_config. + */ +#ifndef NRF_BLE_GATT_MAX_MTU_SIZE + #define NRF_BLE_GATT_MAX_MTU_SIZE GATT_MTU_SIZE_DEFAULT +#endif + + +/** @brief Default maximum number of peripheral links. + * + * To override this default value, define the maximum number of peripheral + * links in your module. + */ +#ifndef NRF_BLE_CENTRAL_LINK_COUNT + #define NRF_BLE_CENTRAL_LINK_COUNT 1 +#endif + +/** @brief Default maximum number of central links. + * + * To override this default value, define the maximum number of central + * links in your module. + */ +#ifndef NRF_BLE_PERIPHERAL_LINK_COUNT + #define NRF_BLE_PERIPHERAL_LINK_COUNT 1 +#endif + +/** @brief The maximum number of peripheral and central links combined. */ +#define NRF_BLE_GATT_LINK_COUNT (NRF_BLE_PERIPHERAL_LINK_COUNT + NRF_BLE_CENTRAL_LINK_COUNT) + + +/**@brief GATT module event. */ +typedef struct +{ + uint16_t conn_handle; //!< Connection handle on which the event happened. + uint16_t att_mtu_effective; //!< Effective MTU after the event. +}nrf_ble_gatt_evt_t; + + +// Forward declaration of the nrf_ble_gatt_t type. +typedef struct nrf_ble_gatt_s nrf_ble_gatt_t; + +/**@brief GATT module event handler type. + * + * The GATT module calls a function of this type when the ATT_MTU value is changed. +*/ +typedef void (*nrf_ble_gatt_evt_handler_t) (nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t * p_evt); + +/**@brief GATT information for each link. */ +typedef struct +{ + uint16_t att_mtu_desired; //!< Requested ATT_MTU size for the link. + uint16_t att_mtu_effective; //!< Effective ATT_MTU size for the link. + bool is_request_pending; //!< Flag that indicates if a request to extend the MTU size is pending for the link (if the call to @ref sd_ble_gattc_exchange_mtu_request returned @ref NRF_ERROR_BUSY). +}nrf_ble_gatt_link_t; + + +/**@brief GATT structure that contains status information for the GATT module. */ +struct nrf_ble_gatt_s +{ + uint16_t att_mtu_desired_periph; //!< Requested ATT_MTU size for the next peripheral link that is established. + uint16_t att_mtu_desired_central; //!< Requested ATT_MTU size for the next central link that is established. + nrf_ble_gatt_link_t links[NRF_BLE_GATT_LINK_COUNT]; //!< GATT related information for all active links. + nrf_ble_gatt_evt_handler_t evt_handler; //!< GATT event handler. +}; + + +/**@brief Function for initializing the GATT module. + * + * @param[in] evt_handler Event handler. + * @param[out] p_gatt Pointer to the GATT structure. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If the pointer to @p p_gatt is NULL. + * + */ +ret_code_t nrf_ble_gatt_init(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_handler_t evt_handler); + + +/**@brief Function for setting the ATT_MTU size for the next link that is established as peripheral. + * + * @param[in] p_gatt Pointer to the GATT structure. + * @param[in] desired_mtu Requested ATT_MTU size. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If the pointer to @p p_gatt is NULL. + * @retval NRF_ERROR_INVALID_PARAM If the size of @p desired_mtu is bigger than @ref NRF_BLE_GATT_MAX_MTU_SIZE or smaller than @ref GATT_MTU_SIZE_DEFAULT. + * + */ +ret_code_t nrf_ble_gatt_att_mtu_periph_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu); + + +/**@brief Function for setting the ATT_MTU size for the next link that is established as central. + * + * @param[in] p_gatt Pointer to the GATT structure. + * @param[in] desired_mtu Requested ATT_MTU size. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If the pointer to @p p_gatt is NULL. + * @retval NRF_ERROR_INVALID_PARAM If the size of @p desired_mtu is bigger than @ref NRF_BLE_GATT_MAX_MTU_SIZE or smaller than @ref GATT_MTU_SIZE_DEFAULT. + * + */ +ret_code_t nrf_ble_gatt_att_mtu_central_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu); + + +/**@brief Function for handling BLE stack events. + * + * @details This function handles all events from the BLE stack that are of interest to the GATT module. + * + * @param[in] p_gatt Pointer to the GATT structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void nrf_ble_gatt_on_ble_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t * p_ble_evt); + + +/**@brief Function for getting the current ATT_MTU size for a connection handle. + * + * @param[in] p_gatt Pointer to the GATT structure. + * @param[in] conn_handle Connection handle of the link. + * + * @return ATT_MTU size for the given link. + * @retval 0 If the pointer to @p p_gatt is NULL or if @p conn_handle is larger than the supported maximum number of connections. + * + */ +uint16_t nrf_ble_gatt_eff_mtu_get(nrf_ble_gatt_t * p_gatt, uint16_t conn_handle); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_GATT_H__ + +/** @} */ diff --git a/components/ble/nrf_ble_qwr/nrf_ble_qwr.c b/components/ble/nrf_ble_qwr/nrf_ble_qwr.c new file mode 100644 index 0000000..fb3c9ce --- /dev/null +++ b/components/ble/nrf_ble_qwr/nrf_ble_qwr.c @@ -0,0 +1,405 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_BLE_QWR) +#include +#include "nrf_ble_qwr.h" +#include "ble.h" +#include "ble_srv_common.h" + +#define NRF_BLE_QWR_INITIALIZED 0xDE // Non-zero value used to make sure the given structure has been initialized by the module. +#define MODULE_INITIALIZED (p_qwr->initialized == NRF_BLE_QWR_INITIALIZED) +#include "sdk_macros.h" + +ret_code_t nrf_ble_qwr_init(nrf_ble_qwr_t * p_qwr, + nrf_ble_qwr_init_t const * p_qwr_init) +{ + VERIFY_PARAM_NOT_NULL(p_qwr); + VERIFY_PARAM_NOT_NULL(p_qwr_init); + if (MODULE_INITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + memset(p_qwr->attr_handles, 0, sizeof(p_qwr->attr_handles)); + p_qwr->nb_registered_attr = 0; + p_qwr->error_handler = p_qwr_init->error_handler; + p_qwr->is_user_mem_reply_pending = false; + p_qwr->conn_handle = BLE_CONN_HANDLE_INVALID; + p_qwr->initialized = NRF_BLE_QWR_INITIALIZED; + p_qwr->mem_buffer = p_qwr_init->mem_buffer; + p_qwr->callback = p_qwr_init->callback; + p_qwr->nb_written_handles = 0; + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_qwr_attr_register(nrf_ble_qwr_t * p_qwr, uint16_t attr_handle) +{ + VERIFY_PARAM_NOT_NULL(p_qwr); + VERIFY_MODULE_INITIALIZED(); + + if (p_qwr->nb_registered_attr == NRF_BLE_QWR_ATTR_LIST_SIZE) + { + return (NRF_ERROR_NO_MEM); + } + + if (attr_handle == BLE_GATT_HANDLE_INVALID) + { + return NRF_ERROR_INVALID_PARAM; + } + + p_qwr->attr_handles[p_qwr->nb_registered_attr] = attr_handle; + p_qwr->nb_registered_attr++; + + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_qwr_value_get(nrf_ble_qwr_t * p_qwr, + uint16_t attr_handle, + uint8_t * p_mem, + uint16_t * p_len) +{ + VERIFY_PARAM_NOT_NULL(p_qwr); + VERIFY_PARAM_NOT_NULL(p_mem); + VERIFY_PARAM_NOT_NULL(p_len); + VERIFY_MODULE_INITIALIZED(); + + uint16_t i = 0; + uint16_t handle = BLE_GATT_HANDLE_INVALID; + uint16_t val_len = 0; + uint16_t val_offset = 0; + uint16_t cur_len = 0; + + do + { + handle = uint16_decode(&(p_qwr->mem_buffer.p_mem[i])); + + if (handle == BLE_GATT_HANDLE_INVALID) + { + break; + } + + i += sizeof(uint16_t); + val_offset = uint16_decode(&(p_qwr->mem_buffer.p_mem[i])); + i += sizeof(uint16_t); + val_len = uint16_decode(&(p_qwr->mem_buffer.p_mem[i])); + i += sizeof(uint16_t); + + if (handle == attr_handle) + { + cur_len = val_offset + val_len; + if (cur_len <= *p_len) + { + memcpy((p_mem + val_offset), &(p_qwr->mem_buffer.p_mem[i]), val_len); + } + else + { + return NRF_ERROR_NO_MEM; + } + } + + i += val_len; + } + while (i < p_qwr->mem_buffer.len); + + *p_len = cur_len; + return NRF_SUCCESS; +} + + +ret_code_t nrf_ble_qwr_conn_handle_assign(nrf_ble_qwr_t * p_qwr, + uint16_t conn_handle) +{ + VERIFY_PARAM_NOT_NULL(p_qwr); + VERIFY_MODULE_INITIALIZED(); + p_qwr->conn_handle = conn_handle; + return NRF_SUCCESS; +} + + +/**@brief Handle a user memory request event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_common_evt User_mem_request event to be handled. + */ +static void on_user_mem_request(nrf_ble_qwr_t * p_qwr, + ble_common_evt_t const * p_common_evt) +{ + if (p_common_evt->conn_handle == p_qwr->conn_handle) + { + uint32_t err_code = sd_ble_user_mem_reply(p_common_evt->conn_handle, &p_qwr->mem_buffer); + if (err_code == NRF_SUCCESS) + { + p_qwr->is_user_mem_reply_pending = false; + } + else if (err_code == NRF_ERROR_BUSY) + { + p_qwr->is_user_mem_reply_pending = true; + } + else + { + p_qwr->error_handler(err_code); + } + } +} + + +/**@brief Handle a prepare write event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_evt_write WRITE event to be handled. + */ +static void on_prepare_write(nrf_ble_qwr_t * p_qwr, + ble_gatts_evt_write_t const * p_evt_write) +{ + uint32_t err_code; + ble_gatts_rw_authorize_reply_params_t auth_reply; + memset(&auth_reply, 0, sizeof(auth_reply)); + + auth_reply.params.write.gatt_status = NRF_BLE_QWR_REJ_REQUEST_ERR_CODE; + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + + uint32_t i; + + for (i = 0; i < p_qwr->nb_written_handles; i++) + { + if (p_qwr->written_attr_handles[i] == p_evt_write->handle) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + break; + } + } + + if (auth_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS) + { + for (i = 0; i < p_qwr->nb_registered_attr; i++) + { + if (p_qwr->attr_handles[i] == p_evt_write->handle) + { + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + p_qwr->written_attr_handles[p_qwr->nb_written_handles++] = p_evt_write->handle; + break; + } + } + } + + err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + // Cancel the current operation. + p_qwr->nb_written_handles = 0; + + // Report error to application. + p_qwr->error_handler(err_code); + } + +} + + +/**@brief Handle an execute write event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_evt_write EXEC WRITE event to be handled. + */ +static void on_execute_write(nrf_ble_qwr_t * p_qwr, + ble_gatts_evt_write_t const * p_evt_write) +{ + uint32_t err_code; + ble_gatts_rw_authorize_reply_params_t auth_reply; + memset(&auth_reply, 0, sizeof(auth_reply)); + + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + + if (p_qwr->nb_written_handles == 0) + { + auth_reply.params.write.gatt_status = NRF_BLE_QWR_REJ_REQUEST_ERR_CODE; + err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + // Report error to application. + p_qwr->error_handler(err_code); + } + return; + } + + for (uint16_t i = 0; i < p_qwr->nb_written_handles; i++) + { + nrf_ble_qwr_evt_t evt; + uint16_t ret_val; + + evt.evt_type = NRF_BLE_QWR_EVT_AUTH_REQUEST; + evt.attr_handle = p_qwr->written_attr_handles[i]; + ret_val = p_qwr->callback(p_qwr, &evt); + if (ret_val != BLE_GATT_STATUS_SUCCESS) + { + auth_reply.params.write.gatt_status = ret_val; + } + } + + err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + // Report error to application. + p_qwr->error_handler(err_code); + } + + // If the execute has not been rejected by any of the registered applications, propagate execute write event to all written handles. */ + if (auth_reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) + { + for (uint16_t i = 0; i < p_qwr->nb_written_handles; i++) + { + nrf_ble_qwr_evt_t evt; + evt.evt_type = NRF_BLE_QWR_EVT_EXECUTE_WRITE; + evt.attr_handle = p_qwr->written_attr_handles[i]; + /*lint -e534 -save "Ignoring return value of function" */ + p_qwr->callback(p_qwr, &evt); + /*lint -restore*/ + + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + } + } + p_qwr->nb_written_handles = 0; +} + + +/**@brief Handle a cancel write event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_evt_write EXEC WRITE event to be handled. + */ +static void on_cancel_write(nrf_ble_qwr_t * p_qwr, + ble_gatts_evt_write_t const * p_evt_write) +{ + uint32_t err_code; + ble_gatts_rw_authorize_reply_params_t auth_reply; + memset(&auth_reply, 0, sizeof(auth_reply)); + + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply); + if (err_code != NRF_SUCCESS) + { + // Report error to application. + p_qwr->error_handler(err_code); + } + p_qwr->nb_written_handles = 0; +} + + +/**@brief Handle a rw_authorize_request event. + * + * @param[in] p_qwr QWR structure. + * @param[in] p_gatts_evt RW_authorize_request event to be handled. + */ +static void on_rw_authorize_request(nrf_ble_qwr_t * p_qwr, + ble_gatts_evt_t const * p_gatts_evt) +{ + if (p_gatts_evt->conn_handle != p_qwr->conn_handle) + { + return; + } + + ble_gatts_evt_rw_authorize_request_t const * p_auth_req = &p_gatts_evt->params.authorize_request; + if (p_auth_req->type != BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + return; + } + + switch (p_auth_req->request.write.op) + { + case BLE_GATTS_OP_PREP_WRITE_REQ: + on_prepare_write(p_qwr, &p_auth_req->request.write); + break; // BLE_GATTS_OP_PREP_WRITE_REQ + + case BLE_GATTS_OP_EXEC_WRITE_REQ_NOW: + on_execute_write(p_qwr, &p_auth_req->request.write); + break; // BLE_GATTS_OP_EXEC_WRITE_REQ_NOW + + case BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL: + on_cancel_write(p_qwr, &p_auth_req->request.write); + break; // BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL + + default: + // No implementation needed. + break; + } +} + + +void nrf_ble_qwr_on_ble_evt(nrf_ble_qwr_t * p_qwr, + ble_evt_t * p_ble_evt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_qwr); + VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt); + VERIFY_MODULE_INITIALIZED_VOID(); + + if (p_qwr->is_user_mem_reply_pending) + { + on_user_mem_request(p_qwr, &p_ble_evt->evt.common_evt); + } + + switch (p_ble_evt->header.evt_id) + { + case BLE_EVT_USER_MEM_REQUEST: + on_user_mem_request(p_qwr, &p_ble_evt->evt.common_evt); + break; // BLE_EVT_USER_MEM_REQUEST + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + on_rw_authorize_request(p_qwr, &p_ble_evt->evt.gatts_evt); + break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST + + case BLE_GAP_EVT_DISCONNECTED: + if (p_ble_evt->evt.gap_evt.conn_handle == p_qwr->conn_handle) + { + p_qwr->conn_handle = BLE_CONN_HANDLE_INVALID; + p_qwr->nb_written_handles = 0; + } + break; // BLE_GAP_EVT_DISCONNECTED + + default: + break; + } + +} +#endif // NRF_MODULE_ENABLED(NRF_BLE_QWR) diff --git a/components/ble/nrf_ble_qwr/nrf_ble_qwr.h b/components/ble/nrf_ble_qwr/nrf_ble_qwr.h new file mode 100644 index 0000000..47dc533 --- /dev/null +++ b/components/ble/nrf_ble_qwr/nrf_ble_qwr.h @@ -0,0 +1,220 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup nrf_ble_qwr Queued Writes module + * @{ + * @ingroup ble_sdk_lib + * @brief Module for handling Queued Write operations. + * + * @details This module handles prepare write, execute write, and cancel write + * commands. It also manages memory requests related to these operations. + * + * @note The application must propagate BLE stack events to this module by calling + * @ref nrf_ble_qwr_on_ble_evt(). + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NRF_BLE_QUEUED_WRITES_H__ +#define NRF_BLE_QUEUED_WRITES_H__ + +#include +#include "nordic_common.h" +#include "sdk_common.h" +#include "ble.h" +#include "ble_srv_common.h" + +#ifndef NRF_BLE_QWR_ATTR_LIST_SIZE +#define NRF_BLE_QWR_ATTR_LIST_SIZE 10 //!< Maximum number of attribute handles that can be registered. This number must be adjusted according to the number of attributes for which Queued Writes will be enabled. +#endif + +#define NRF_BLE_QWR_REJ_REQUEST_ERR_CODE BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0 //!< Error code used by the module to reject prepare write requests on non-registered attributes. + +/**@brief Queued Writes module event types. */ +typedef enum +{ + NRF_BLE_QWR_EVT_EXECUTE_WRITE, //!< Event that indicates that an execute write command was received for a registered handle and that the received data was actually written and is now ready. + NRF_BLE_QWR_EVT_AUTH_REQUEST, //!< Event that indicates that an execute write command was received for a registered handle and that the write request must now be accepted or rejected. +} nrf_ble_qwr_evt_type_t; + + +/**@brief Queued Writes module events. */ +typedef struct +{ + nrf_ble_qwr_evt_type_t evt_type; //!< Type of the event. + uint16_t attr_handle; //!< Handle of the attribute to which the event relates. +} nrf_ble_qwr_evt_t; + + +// Forward declaration of the nrf_ble_qwr_t type. +struct nrf_ble_qwr_t; + +/**@brief Queued Writes module event handler type. + * + * If the provided event is of type @ref NRF_BLE_QWR_EVT_AUTH_REQUEST, + * this function must accept or reject the execute write request by returning + * one of the @ref BLE_GATT_STATUS_CODES.*/ +typedef uint16_t (* nrf_ble_qwr_evt_handler_t) (struct nrf_ble_qwr_t * p_qwr, + nrf_ble_qwr_evt_t * p_evt); + + +/**@brief Queued Writes structure. + * @details This structure contains status information for the Queued Writes module. */ +typedef struct nrf_ble_qwr_t +{ + uint8_t initialized; //!< Flag that indicates whether the module has been initialized. + uint16_t attr_handles[NRF_BLE_QWR_ATTR_LIST_SIZE]; //!< List of handles for registered attributes, for which the module accepts and handles prepare write operations. + uint8_t nb_registered_attr; //!< Number of registered attributes. + uint16_t written_attr_handles[NRF_BLE_QWR_ATTR_LIST_SIZE]; //!< List of attribute handles that have been written to during the current prepare write or execute write operation. + uint8_t nb_written_handles; //!< Number of attributes that have been written to during the current prepare write or execute write operation. + ble_user_mem_block_t mem_buffer; //!< Memory buffer that is provided to the SoftDevice on an ON_USER_MEM_REQUEST event. + ble_srv_error_handler_t error_handler; //!< Error handler. + bool is_user_mem_reply_pending; //!< Flag that indicates whether a mem_reply is pending (because a previous attempt returned busy). + uint16_t conn_handle; //!< Connection handle. + nrf_ble_qwr_evt_handler_t callback; //!< Event handler function that is called for events concerning the handles of all registered attributes. +} nrf_ble_qwr_t; + + +/**@brief Queued Writes init structure. + * @details This structure contains all information + * that is needed to initialize the Queued Writes module. */ +typedef struct +{ + ble_srv_error_handler_t error_handler; //!< Error handler. + ble_user_mem_block_t mem_buffer; //!< Memory buffer that is provided to the SoftDevice on an ON_USER_MEM_REQUEST event. + nrf_ble_qwr_evt_handler_t callback; //!< Event handler function that is called for events concerning the handles of all registered attributes. +} nrf_ble_qwr_init_t; + + +/**@brief Function for initializing the Queued Writes module. + * + * @details Call this function in the main entry of your application to + * initialize the Queued Writes module. It must be called only once with a + * given Queued Writes structure. + * + * @param[out] p_qwr Queued Writes structure. This structure must be + * supplied by the application. It is initialized by this function + * and is later used to identify the particular Queued Writes instance. + * @param[in] p_qwr_init Initialization structure. + * + * @retval NRF_SUCCESS If the Queued Writes module was initialized successfully. + * @retval NRF_ERROR_NULL If any of the given pointers is NULL. + * @retval NRF_ERROR_INVALID_STATE If the given context has already been initialized. + */ +ret_code_t nrf_ble_qwr_init(nrf_ble_qwr_t * p_qwr, + nrf_ble_qwr_init_t const * p_qwr_init); + + +/**@brief Function for registering an attribute with the Queued Writes module. + * + * @details Call this function for each attribute that you want to enable for + * Queued Writes (thus a series of prepare write and execute write operations). + * + * @param[in] p_qwr Queued Writes structure. + * @param[in] attr_handle Handle of the attribute to register. + * + * @retval NRF_SUCCESS If the registration was successful. + * @retval NRF_ERROR_NO_MEM If no more memory is available to add this registration. + * @retval NRF_ERROR_NULL If any of the given pointers is NULL. + * @retval NRF_ERROR_INVALID_STATE If the given context has not been initialized. + */ +ret_code_t nrf_ble_qwr_attr_register(nrf_ble_qwr_t * p_qwr, uint16_t attr_handle); + + +/**@brief Function for handling BLE stack events. + * + * @details Handles all events from the BLE stack that are of interest to the Queued Writes module. + * + * @param[in] p_qwr Queued Writes structure. + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void nrf_ble_qwr_on_ble_evt(nrf_ble_qwr_t * p_qwr, ble_evt_t * p_ble_evt); + + +/**@brief Function for retrieving the received data for a given attribute. + * + * @details Call this function after receiving an @ref NRF_BLE_QWR_EVT_AUTH_REQUEST + * event to retrieve a linear copy of the data that was received for the given attribute. + * + * @param[in] p_qwr Queued Writes structure. + * @param[in] attr_handle Handle of the attribute. + * @param[out] p_mem Pointer to the application buffer where the received data will be copied. + * @param[in,out] p_len Input: length of the input buffer. Output: length of the received data. + * + * + * @retval NRF_SUCCESS If the data was retrieved and stored successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer was smaller than the received data. + * @retval NRF_ERROR_NULL If any of the given pointers is NULL. + * @retval NRF_ERROR_INVALID_STATE If the given context has not been initialized. + */ +ret_code_t nrf_ble_qwr_value_get(nrf_ble_qwr_t * p_qwr, + uint16_t attr_handle, + uint8_t * p_mem, + uint16_t * p_len); + + +/**@brief Function for assigning a connection handle to a given instance of the Queued Writes module. + * + * @details Call this function when a link with a peer has been established to + * associate this link to the instance of the module. This makes it + * possible to handle several links and associate each link to a particular + * instance of this module. + * + * @param[in] p_qwr Queued Writes structure. + * @param[in] conn_handle Connection handle to be associated with the given Queued Writes instance. + * + * @retval NRF_SUCCESS If the assignment was successful. + * @retval NRF_ERROR_NULL If any of the given pointers is NULL. + * @retval NRF_ERROR_INVALID_STATE If the given context has not been initialized. + */ +ret_code_t nrf_ble_qwr_conn_handle_assign(nrf_ble_qwr_t * p_qwr, + uint16_t conn_handle); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_QUEUED_WRITES_H__ + +/** @} */ diff --git a/components/ble/peer_manager/gatt_cache_manager.c b/components/ble/peer_manager/gatt_cache_manager.c index dc24f63..53489a0 100644 --- a/components/ble/peer_manager/gatt_cache_manager.c +++ b/components/ble/peer_manager/gatt_cache_manager.c @@ -1,67 +1,95 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "gatt_cache_manager.h" -#include #include "ble_gap.h" #include "ble_conn_state.h" #include "peer_manager_types.h" -#include "peer_database.h" +#include "peer_manager_internal.h" #include "id_manager.h" #include "security_dispatcher.h" #include "gatts_cache_manager.h" -#include "gattc_cache_manager.h" -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * @ref NRF_ERROR_INVALID_STATE if not. - */ -#define VERIFY_MODULE_INITIALIZED() \ -do \ -{ \ - if (m_gcm.evt_handler == NULL) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * if not. - * - * @param[in] param The variable to check if is NULL. - */ -#define VERIFY_PARAM_NOT_NULL(param) \ -do \ -{ \ - if (param == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } \ -} while(0) +// The number of registered event handlers. +#define GCM_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) +// GATT Cache Manager event handler in Peer Manager. +extern void pm_gcm_evt_handler(gcm_evt_t const * p_gcm_evt); - -/**@brief Structure containing the module variable(s) of the GCM module. - */ -typedef struct +// GATT Cache Manager events' handlers. +// The number of elements in this array is GCM_EVENT_HANDLERS_CNT. +static gcm_evt_handler_t m_evt_handlers[] = { - gcm_evt_handler_t evt_handler; /**< The event handler to use for outbound GSCM events. */ - ble_conn_state_user_flag_id_t flag_id_local_db_update_pending; /**< Flag ID for flag collection to keep track of which connections need a local DB update procedure. */ - ble_conn_state_user_flag_id_t flag_id_local_db_apply_pending; /**< Flag ID for flag collection to keep track of which connections need a local DB apply procedure. */ - ble_conn_state_user_flag_id_t flag_id_service_changed_pending; /**< Flag ID for flag collection to keep track of which connections need to be sent a service changed indication. */ -} gcm_t; + pm_gcm_evt_handler +}; + +static bool m_module_initialized; +static ble_conn_state_user_flag_id_t m_flag_local_db_update_pending; /**< Flag ID for flag collection to keep track of which connections need a local DB update procedure. */ +static ble_conn_state_user_flag_id_t m_flag_local_db_apply_pending; /**< Flag ID for flag collection to keep track of which connections need a local DB apply procedure. */ +static ble_conn_state_user_flag_id_t m_flag_service_changed_pending; /**< Flag ID for flag collection to keep track of which connections need to be sent a service changed indication. */ +static ble_conn_state_user_flag_id_t m_flag_service_changed_sent; /**< Flag ID for flag collection to keep track of which connections have been sent a service changed indication and are waiting for a handle value confirmation. */ + -static gcm_t m_gcm; /**< Instantiation of module variable(s). */ +static void service_changed_pending_flags_check(void); /**@brief Function for resetting the module variable(s) of the GSCM module. * * @param[out] The instance to reset. */ -static void internal_state_reset(gcm_t * p_gcm) +static void internal_state_reset() { - memset(p_gcm, 0, sizeof(gcm_t)); + m_module_initialized = false; +} + + +static void evt_send(gcm_evt_t const * p_gcm_evt) +{ + for (uint32_t i = 0; i < GCM_EVENT_HANDLERS_CNT; i++) + { + m_evt_handlers[i](p_gcm_evt); + } } @@ -74,10 +102,9 @@ static void internal_state_reset(gcm_t * p_gcm) */ static bool cccd_written(ble_gatts_evt_write_t * p_write_evt) { - return ( (p_write_evt->op == BLE_GATTS_OP_WRITE_REQ) - && (p_write_evt->context.type == BLE_GATTS_ATTR_TYPE_DESC) - && (p_write_evt->context.desc_uuid.type == BLE_UUID_TYPE_BLE) - && (p_write_evt->context.desc_uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG) + return ( (p_write_evt->op == BLE_GATTS_OP_WRITE_REQ) + && (p_write_evt->uuid.type == BLE_UUID_TYPE_BLE) + && (p_write_evt->uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG) ); } @@ -103,14 +130,14 @@ static void local_db_apply_in_evt(uint16_t conn_handle) err_code = gscm_local_db_cache_apply(conn_handle); - switch(err_code) + switch (err_code) { case NRF_SUCCESS: event.evt_id = GCM_EVT_LOCAL_DB_CACHE_APPLIED; event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); event.params.local_db_cache_applied.conn_handle = conn_handle; - m_gcm.evt_handler(&event); + evt_send(&event); break; case NRF_ERROR_BUSY: @@ -122,7 +149,7 @@ static void local_db_apply_in_evt(uint16_t conn_handle) event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); event.params.error_local_db_cache_apply.conn_handle = conn_handle; - m_gcm.evt_handler(&event); + evt_send(&event); break; case BLE_ERROR_INVALID_CONN_HANDLE: @@ -135,11 +162,11 @@ static void local_db_apply_in_evt(uint16_t conn_handle) event.params.error_unexpected.conn_handle = conn_handle; event.params.error_unexpected.error = err_code; - m_gcm.evt_handler(&event); + evt_send(&event); break; } - ble_conn_state_user_flag_set(conn_handle, m_gcm.flag_id_local_db_apply_pending, set_procedure_as_pending); + ble_conn_state_user_flag_set(conn_handle, m_flag_local_db_apply_pending, set_procedure_as_pending); } @@ -157,14 +184,14 @@ static void local_db_update_in_evt(uint16_t conn_handle) bool set_procedure_as_pending = false; ret_code_t err_code = gscm_local_db_cache_update(conn_handle); - switch(err_code) + switch (err_code) { case NRF_SUCCESS: event.evt_id = GCM_EVT_LOCAL_DB_CACHE_UPDATED; event.params.local_db_cache_applied.conn_handle = conn_handle; event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); - m_gcm.evt_handler(&event); + evt_send(&event); break; case BLE_ERROR_INVALID_CONN_HANDLE: @@ -180,15 +207,15 @@ static void local_db_update_in_evt(uint16_t conn_handle) event.params.error_data_size.conn_handle = conn_handle; event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); - m_gcm.evt_handler(&event); + evt_send(&event); break; - case NRF_ERROR_NO_MEM: + case NRF_ERROR_STORAGE_FULL: event.evt_id = GCM_EVT_ERROR_STORAGE_FULL; event.params.error_no_mem.conn_handle = conn_handle; event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); - m_gcm.evt_handler(&event); + evt_send(&event); break; default: @@ -197,11 +224,11 @@ static void local_db_update_in_evt(uint16_t conn_handle) event.params.error_unexpected.conn_handle = conn_handle; event.params.error_unexpected.error = err_code; - m_gcm.evt_handler(&event); + evt_send(&event); break; } - ble_conn_state_user_flag_set(conn_handle, m_gcm.flag_id_local_db_update_pending, set_procedure_as_pending); + ble_conn_state_user_flag_set(conn_handle, m_flag_local_db_update_pending, set_procedure_as_pending); } @@ -216,70 +243,93 @@ static void local_db_update_in_evt(uint16_t conn_handle) static void service_changed_send_in_evt(uint16_t conn_handle) { gcm_evt_t event; + bool sc_pending_state = true; + bool sc_sent_state = false; ret_code_t err_code = gscm_service_changed_ind_send(conn_handle); - switch(err_code) + switch (err_code) { case NRF_SUCCESS: - /* Do nothing */ - break; + sc_sent_state = true; - case BLE_ERROR_INVALID_CONN_HANDLE: - /* Do nothing */ + event.evt_id = GCM_EVT_SERVICE_CHANGED_IND_SENT; + event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); + event.params.service_changed_ind_sent.conn_handle = conn_handle; + + evt_send(&event); break; case NRF_ERROR_BUSY: - /* Do nothing */ + // Do nothing. + break; + + case NRF_ERROR_INVALID_STATE: + // CCCDs not enabled. Drop indication. + // Fallthrough. + + case NRF_ERROR_NOT_SUPPORTED: + // Service changed not supported. Drop indication. + sc_pending_state = false; + gscm_db_change_notification_done(im_peer_id_get_by_conn_handle(conn_handle)); break; case BLE_ERROR_GATTS_SYS_ATTR_MISSING: local_db_apply_in_evt(conn_handle); break; + case BLE_ERROR_INVALID_CONN_HANDLE: + // Do nothing. + break; + default: event.evt_id = GCM_EVT_ERROR_UNEXPECTED; event.params.error_unexpected.conn_handle = conn_handle; event.params.error_unexpected.error = err_code; event.peer_id = im_peer_id_get_by_conn_handle(conn_handle); - m_gcm.evt_handler(&event); + evt_send(&event); break; } - ble_conn_state_user_flag_set(conn_handle, m_gcm.flag_id_service_changed_pending, true); + ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_pending, sc_pending_state); + ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_sent, sc_sent_state); } /**@brief Callback function for events from the GATT Cache Server Manager module. + * This handler is extern in GATTS Cache Manager module. * * @param[in] p_event The event from the GATT Cache Server Manager module. */ -static void gscm_evt_handler(gscm_evt_t const * p_event) +void gcm_gscm_evt_handler(gscm_evt_t const * p_event) { gcm_evt_t event; + event.peer_id = p_event->peer_id; + switch (p_event->evt_id) { case GSCM_EVT_LOCAL_DB_CACHE_STORED: event.evt_id = GCM_EVT_LOCAL_DB_CACHE_STORED; - event.peer_id = p_event->peer_id; - m_gcm.evt_handler(&event); + evt_send(&event); local_db_apply_in_evt(im_conn_handle_get(p_event->peer_id)); break; + case GSCM_EVT_LOCAL_DB_CACHE_UPDATED: event.evt_id = GCM_EVT_LOCAL_DB_CACHE_UPDATED; - event.peer_id = p_event->peer_id; event.params.local_db_cache_updated.conn_handle = p_event->params.local_db_cache_updated.conn_handle; - m_gcm.evt_handler(&event); + evt_send(&event); break; + case GSCM_EVT_SC_STATE_STORED: if (p_event->params.sc_state_stored.state) { uint16_t conn_handle = im_conn_handle_get(p_event->peer_id); if (conn_handle != BLE_CONN_HANDLE_INVALID) { - ble_conn_state_user_flag_set(conn_handle, m_gcm.flag_id_service_changed_pending, true); + ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_pending, true); + service_changed_pending_flags_check(); } } break; @@ -287,21 +337,12 @@ static void gscm_evt_handler(gscm_evt_t const * p_event) } -/**@brief Callback function for events from the GATT Cache Client Manager module. +/**@brief Callback function for events from the ID Manager module. + * This function is registered in the ID Manager module. * - * @param[in] p_event The event from the GATT Cache Client Manager module. + * @param[in] p_event The event from the ID Manager module. */ -static void gccm_evt_handler(gccm_evt_t const * p_event) -{ - -} - - -/**@brief Callback function for events from the Identity Manager module. - * - * @param[in] p_event The event from the Identity Manager module. - */ -static void im_evt_handler(im_evt_t const * p_event) +void gcm_im_evt_handler(im_evt_t const * p_event) { switch (p_event->evt_id) { @@ -309,7 +350,7 @@ static void im_evt_handler(im_evt_t const * p_event) local_db_apply_in_evt(p_event->conn_handle); if (gscm_service_changed_ind_needed(p_event->conn_handle)) { - ble_conn_state_user_flag_set(p_event->conn_handle, m_gcm.flag_id_service_changed_pending, true); + ble_conn_state_user_flag_set(p_event->conn_handle, m_flag_service_changed_pending, true); } break; default: @@ -319,10 +360,11 @@ static void im_evt_handler(im_evt_t const * p_event) /**@brief Callback function for events from the Security Dispatcher module. + * This handler is extern in Security Dispatcher. * * @param[in] p_event The event from the Security Dispatcher module. */ -static void smd_evt_handler(smd_evt_t const * p_event) +void gcm_smd_evt_handler(smd_evt_t const * p_event) { switch (p_event->evt_id) { @@ -335,58 +377,49 @@ static void smd_evt_handler(smd_evt_t const * p_event) } -ret_code_t gcm_init(gcm_evt_handler_t evt_handler) +ret_code_t gcm_init() { - VERIFY_PARAM_NOT_NULL(evt_handler); - - ret_code_t err_code; - - err_code = gscm_init(gscm_evt_handler); - if (err_code != NRF_SUCCESS) {return err_code;} - - err_code = gccm_init(gccm_evt_handler); - if (err_code != NRF_SUCCESS) {return err_code;} - - internal_state_reset(&m_gcm); - m_gcm.evt_handler = evt_handler; + NRF_PM_DEBUG_CHECK(!m_module_initialized); - err_code = im_register(im_evt_handler); - if (err_code != NRF_SUCCESS) {return err_code;} + internal_state_reset(); - err_code = smd_register(smd_evt_handler); - if (err_code != NRF_SUCCESS) {return err_code;} + m_flag_local_db_update_pending = ble_conn_state_user_flag_acquire(); + m_flag_local_db_apply_pending = ble_conn_state_user_flag_acquire(); + m_flag_service_changed_pending = ble_conn_state_user_flag_acquire(); + m_flag_service_changed_sent = ble_conn_state_user_flag_acquire(); - - m_gcm.flag_id_local_db_update_pending = ble_conn_state_user_flag_acquire(); - m_gcm.flag_id_local_db_apply_pending = ble_conn_state_user_flag_acquire(); - m_gcm.flag_id_service_changed_pending = ble_conn_state_user_flag_acquire(); - - if ((m_gcm.flag_id_local_db_update_pending == BLE_CONN_STATE_USER_FLAG_INVALID) - || (m_gcm.flag_id_local_db_apply_pending == BLE_CONN_STATE_USER_FLAG_INVALID) - || (m_gcm.flag_id_service_changed_pending == BLE_CONN_STATE_USER_FLAG_INVALID)) + if ((m_flag_local_db_update_pending == BLE_CONN_STATE_USER_FLAG_INVALID) + || (m_flag_local_db_apply_pending == BLE_CONN_STATE_USER_FLAG_INVALID) + || (m_flag_service_changed_pending == BLE_CONN_STATE_USER_FLAG_INVALID) + || (m_flag_service_changed_sent == BLE_CONN_STATE_USER_FLAG_INVALID)) { - err_code = NRF_ERROR_INTERNAL; + return NRF_ERROR_INTERNAL; } - return err_code; + m_module_initialized = true; + + return NRF_SUCCESS; } +// @todo emdi: apply_pending_flags_check() and update_pending_flags_check() should really be +// refactored into one function.. + /**@brief Function for performing the Local DB apply procedure if it is pending on any connections. */ static void apply_pending_flags_check(void) { sdk_mapped_flags_t apply_pending_flags; - apply_pending_flags = ble_conn_state_user_flag_collection(m_gcm.flag_id_local_db_apply_pending); + apply_pending_flags = ble_conn_state_user_flag_collection(m_flag_local_db_apply_pending); if (sdk_mapped_flags_any_set(apply_pending_flags)) { sdk_mapped_flags_key_list_t conn_handle_list; conn_handle_list = ble_conn_state_conn_handles(); - for (int i = 0; i < conn_handle_list.len; i++) + for (uint32_t i = 0; i < conn_handle_list.len; i++) { - if (ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_gcm.flag_id_local_db_apply_pending)) + if (ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_flag_local_db_apply_pending)) { local_db_apply_in_evt(conn_handle_list.flag_keys[i]); } @@ -401,15 +434,15 @@ static void update_pending_flags_check(void) { sdk_mapped_flags_t update_pending_flags; - update_pending_flags = ble_conn_state_user_flag_collection(m_gcm.flag_id_local_db_update_pending); + update_pending_flags = ble_conn_state_user_flag_collection(m_flag_local_db_update_pending); if (sdk_mapped_flags_any_set(update_pending_flags)) { sdk_mapped_flags_key_list_t conn_handle_list; conn_handle_list = ble_conn_state_conn_handles(); - for (int i = 0; i < conn_handle_list.len; i++) + for (uint32_t i = 0; i < conn_handle_list.len; i++) { - if (ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_gcm.flag_id_local_db_update_pending)) + if (ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_flag_local_db_update_pending)) { local_db_update_in_evt(conn_handle_list.flag_keys[i]); } @@ -424,15 +457,18 @@ static void service_changed_pending_flags_check(void) { sdk_mapped_flags_t service_changed_pending_flags; - service_changed_pending_flags = ble_conn_state_user_flag_collection(m_gcm.flag_id_service_changed_pending); + service_changed_pending_flags = ble_conn_state_user_flag_collection(m_flag_service_changed_pending); if (sdk_mapped_flags_any_set(service_changed_pending_flags)) { sdk_mapped_flags_key_list_t conn_handle_list; conn_handle_list = ble_conn_state_conn_handles(); - for (int i = 0; i < conn_handle_list.len; i++) + for (uint32_t i = 0; i < conn_handle_list.len; i++) { - if (ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_gcm.flag_id_service_changed_pending)) + if ( ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], + m_flag_service_changed_pending) + && !ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], + m_flag_service_changed_sent)) { service_changed_send_in_evt(conn_handle_list.flag_keys[i]); } @@ -447,15 +483,23 @@ static void service_changed_pending_flags_check(void) */ void gcm_ble_evt_handler(ble_evt_t * p_ble_evt) { - switch(p_ble_evt->header.evt_id) + gcm_evt_t event; + + switch (p_ble_evt->header.evt_id) { case BLE_GATTS_EVT_SYS_ATTR_MISSING: local_db_apply_in_evt(p_ble_evt->evt.gatts_evt.conn_handle); break; case BLE_GATTS_EVT_SC_CONFIRM: - gscm_peer_was_notified_of_db_change(im_peer_id_get_by_conn_handle(p_ble_evt->evt.gatts_evt.conn_handle)); - ble_conn_state_user_flag_set(p_ble_evt->evt.gatts_evt.conn_handle, m_gcm.flag_id_service_changed_pending, false); + event.evt_id = GCM_EVT_SERVICE_CHANGED_IND_CONFIRMED; + event.peer_id = im_peer_id_get_by_conn_handle(p_ble_evt->evt.gatts_evt.conn_handle); + event.params.service_changed_ind_sent.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle; + + gscm_db_change_notification_done(event.peer_id); + ble_conn_state_user_flag_set(p_ble_evt->evt.gatts_evt.conn_handle, m_flag_service_changed_pending, false); + + evt_send(&event); break; case BLE_GATTS_EVT_WRITE: @@ -472,26 +516,9 @@ void gcm_ble_evt_handler(ble_evt_t * p_ble_evt) } -ret_code_t gcm_remote_db_store(pm_peer_id_t peer_id, pm_peer_data_remote_gatt_db_t * p_remote_db) -{ - VERIFY_MODULE_INITIALIZED(); - - return gccm_remote_db_store(peer_id, p_remote_db); -} - - -ret_code_t gcm_remote_db_retrieve(pm_peer_id_t peer_id, pm_peer_data_remote_gatt_db_t * p_remote_db) -{ - VERIFY_MODULE_INITIALIZED(); - VERIFY_PARAM_NOT_NULL(p_remote_db); - - return gccm_remote_db_retrieve(peer_id, p_remote_db); -} - - ret_code_t gcm_local_db_cache_update(uint16_t conn_handle) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); ret_code_t err_code = gscm_local_db_cache_update(conn_handle); bool set_procedure_as_pending = false; @@ -502,7 +529,7 @@ ret_code_t gcm_local_db_cache_update(uint16_t conn_handle) err_code = NRF_SUCCESS; } - ble_conn_state_user_flag_set(conn_handle, m_gcm.flag_id_local_db_update_pending, set_procedure_as_pending); + ble_conn_state_user_flag_set(conn_handle, m_flag_local_db_update_pending, set_procedure_as_pending); return err_code; } @@ -510,20 +537,12 @@ ret_code_t gcm_local_db_cache_update(uint16_t conn_handle) ret_code_t gcm_local_db_cache_set(pm_peer_id_t peer_id, pm_peer_data_local_gatt_db_t * p_local_db) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); return gscm_local_db_cache_set(peer_id, p_local_db); } -ret_code_t gcm_local_db_cache_get(pm_peer_id_t peer_id, pm_peer_data_local_gatt_db_t * p_local_db) -{ - VERIFY_MODULE_INITIALIZED(); - - return gscm_local_db_cache_get(peer_id, p_local_db); -} - - void gcm_local_database_has_changed(void) { gscm_local_database_has_changed(); @@ -534,9 +553,10 @@ void gcm_local_database_has_changed(void) { if (im_peer_id_get_by_conn_handle(conn_handles.flag_keys[i]) == PM_PEER_ID_INVALID) { - ble_conn_state_user_flag_set(conn_handles.flag_keys[i], m_gcm.flag_id_service_changed_pending, true); + ble_conn_state_user_flag_set(conn_handles.flag_keys[i], m_flag_service_changed_pending, true); } } service_changed_pending_flags_check(); } +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/gatt_cache_manager.h b/components/ble/peer_manager/gatt_cache_manager.h index 010f829..d32ff10 100644 --- a/components/ble/peer_manager/gatt_cache_manager.h +++ b/components/ble/peer_manager/gatt_cache_manager.h @@ -1,17 +1,61 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 GATT_CACHE_MANAGER_H__ #define GATT_CACHE_MANAGER_H__ -#include "stdint.h" +#include #include "sdk_errors.h" #include "ble.h" #include "ble_gap.h" #include "peer_manager_types.h" +#ifdef __cplusplus +extern "C" { +#endif + /** + * @cond NO_DOXYGEN * @defgroup gatt_cache_manager GATT Cache Manager * @ingroup peer_manager * @{ @@ -29,7 +73,8 @@ typedef enum GCM_EVT_LOCAL_DB_CACHE_APPLIED, /**< The SoftDevice has been given local database values from the persistent cache, for one peer. */ GCM_EVT_ERROR_LOCAL_DB_CACHE_APPLY, /**< The stored local database values for a peer were rejected by the SoftDevice, which means the database has changed. */ GCM_EVT_REMOTE_DB_CACHE_UPDATED, /**< The persistent cache for the remote database has been updated with provided values, for one peer. */ - GCM_EVT_SERVICE_CHANGED_INDICATION_SENT, /**< A service changed indication has been sent to and confirmed by a peer. */ + GCM_EVT_SERVICE_CHANGED_IND_SENT, /**< A service changed indication has been sent to a peer. */ + GCM_EVT_SERVICE_CHANGED_IND_CONFIRMED, /**< A sent service changed indication has been confirmed by a peer. */ GCM_EVT_ERROR_DATA_SIZE, /**< An operation failed because the write buffer of the Peer Database module was not large enough. This is a fatal error. */ GCM_EVT_ERROR_STORAGE_FULL, /**< An operation failed because there was no available storage room in persistent storage. Please free up room, and the operation will automatically continue. */ GCM_EVT_ERROR_UNEXPECTED, /**< An operation failed with an unexpected error. The error is provided. This is possibly a fatal error. */ @@ -48,14 +93,15 @@ typedef struct */ typedef struct { - gcm_evt_id_t evt_id; /**< The type of event this is. */ + gcm_evt_id_t evt_id; /**< The type of event this is. */ pm_peer_id_t peer_id; /**< The peer ID this event pertains to. */ union { gcm_evt_param_conn_handle_t local_db_cache_updated; gcm_evt_param_conn_handle_t local_db_cache_applied; gcm_evt_param_conn_handle_t error_local_db_cache_apply; - gcm_evt_param_conn_handle_t service_changed_indication_sent; + gcm_evt_param_conn_handle_t service_changed_ind_sent; + gcm_evt_param_conn_handle_t service_changed_ind_confirmed; gcm_evt_param_conn_handle_t error_data_size; gcm_evt_param_conn_handle_t error_no_mem; struct @@ -77,12 +123,10 @@ typedef void (*gcm_evt_handler_t)(gcm_evt_t const * p_event); /**@brief Function for initializing the GATT Cache Manager module. * - * @param[in] evt_handler Callback for events from the GATT Cache Manager module. - * - * @retval NRF_SUCCESS Initialization was successful. - * @retval NRF_ERROR_NULL evt_handler was NULL. + * @retval NRF_SUCCESS Initialization was successful. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. */ -ret_code_t gcm_init(gcm_evt_handler_t evt_handler); +ret_code_t gcm_init(void); /**@brief Function for dispatching SoftDevice events to the GATT Cache Manager module. @@ -96,26 +140,35 @@ void gcm_ble_evt_handler(ble_evt_t * p_ble_evt); /**@brief Function for storing a discovered remote database persistently. * * @param[in] peer_id Peer to store the database for. - * @param[in] p_remote_db Database values to store. If NULL, values are cleared instead. + * @param[in] p_remote_db Database values to store as an array. Can be NULL if n_services is 0. + * @param[in] n_services Number of services in p_remote_db array. If 0, values are cleared. * * @retval NRF_SUCCESS Store procedure successfully started. * @retval NRF_ERROR_NOT_FOUND The peer id is invalid or unallocated. * @retval NRF_ERROR_INVALID_STATE Module is not initialized. */ -ret_code_t gcm_remote_db_store(pm_peer_id_t peer_id, pm_peer_data_remote_gatt_db_t * p_remote_db); +ret_code_t gcm_remote_db_store(pm_peer_id_t peer_id, + ble_gatt_db_srv_t * p_remote_db, + uint32_t n_services); /**@brief Function for retrieving a persistently stored remote database. * - * @param[in] peer_id Peer to retrieve data for. - * @param[inout] p_remote_db Copied database values. + * @param[in] peer_id Peer to retrieve data for. + * @param[out] p_remote_db If p_n_services was large enough: Copied database values. + * @param[inout] p_n_services In: Size of provided p_remote_db array. Out: Size of data in flash. + * + * @note p_n_services is always updated with the size of the data to be retrieved. The data is only + * copied if p_remote_db is large enough (p_n_services is large enough initially). * * @retval NRF_SUCCESS Data retrieved successfully. * @retval NRF_ERROR_NOT_FOUND The peer ID is invalid or unallocated. * @retval NRF_ERROR_NULL p_remote_db is NULL. * @retval NRF_ERROR_INVALID_STATE Module is not initialized. */ -ret_code_t gcm_remote_db_retrieve(pm_peer_id_t peer_id, pm_peer_data_remote_gatt_db_t * p_remote_db); +ret_code_t gcm_remote_db_retrieve(pm_peer_id_t peer_id, + ble_gatt_db_srv_t * p_remote_db, + uint32_t * p_n_services); /**@brief Function for triggering local GATT database data to be stored persistently. Values are @@ -131,9 +184,9 @@ ret_code_t gcm_remote_db_retrieve(pm_peer_id_t peer_id, pm_peer_data_remote_gatt * @retval BLE_ERROR_INVALID_CONN_HANDLE conn_handle does not refer to an active, bonded connection. * @retval NRF_ERROR_DATA_SIZE Write buffer not large enough. Call will never work with * this GATT database. - * @retval NRF_ERROR_NO_MEM No room in persistent_storage. Free up space; the + * @retval NRF_ERROR_STORAGE_FULL No room in persistent_storage. Free up space; the * operation will be automatically reattempted after the - * next compression procedure + * next FDS garbage collection procedure. * @retval NRF_ERROR_INVALID_STATE Module is not initialized. */ ret_code_t gcm_local_db_cache_update(uint16_t conn_handle); @@ -179,6 +232,13 @@ ret_code_t gcm_local_db_cache_get(pm_peer_id_t peer_id, pm_peer_data_local_gatt_ */ void gcm_local_database_has_changed(void); - /* @} */ +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif #endif /* GATT_CACHE_MANAGER_H__ */ diff --git a/components/ble/peer_manager/gattc_cache_manager.c b/components/ble/peer_manager/gattc_cache_manager.c deleted file mode 100644 index f301278..0000000 --- a/components/ble/peer_manager/gattc_cache_manager.c +++ /dev/null @@ -1,108 +0,0 @@ - -#include "gattc_cache_manager.h" - -#include -#include "ble_gap.h" -#include "ble_conn_state.h" -#include "peer_manager_types.h" -#include "peer_database.h" -#include "id_manager.h" - - -#define MAX_SIMUL_SEC_PROCEDURES 2 - - -#define VERIFY_MODULE_INITIALIZED() \ -do \ -{ \ - if (m_gccm.evt_handler == NULL) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ -} while(0) - -#define VERIFY_PARAM_NOT_NULL(param) \ -do \ -{ \ - if (param == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } \ -} while(0) - - - -typedef struct -{ - gccm_evt_handler_t evt_handler; -} gccm_t; - -static gccm_t m_gccm; - -static void internal_state_reset(gccm_t * gccm) -{ - memset(gccm, 0, sizeof(gccm_t)); -} - - -/**@brief Event handler for events from the peer_database module. - * - * @param[in] p_event The event that has happend with peer id and flags. - */ -static void pdb_evt_handler(pdb_evt_t const * p_event) -{ - gccm_evt_t gccm_evt; - gccm_evt.evt_id = GCCM_EVT_REMOTE_DB_STORED; - gccm_evt.peer_id = p_event->peer_id; - m_gccm.evt_handler(&gccm_evt); -} - - -ret_code_t gccm_init(gccm_evt_handler_t evt_handler) -{ - ret_code_t err_code; - if (evt_handler == NULL) - { - err_code = NRF_ERROR_NULL; - } - else - { - err_code = pdb_register(pdb_evt_handler); - if (err_code == NRF_SUCCESS) - { - internal_state_reset(&m_gccm); - m_gccm.evt_handler = evt_handler; - } - } - return err_code; -} - - -ret_code_t gccm_remote_db_store(pm_peer_id_t peer_id, pm_peer_data_remote_gatt_db_t * p_remote_db) -{ - VERIFY_MODULE_INITIALIZED(); - VERIFY_PARAM_NOT_NULL(p_remote_db); - - // Initialize the peer_data - pm_peer_data_const_t peer_data; - memset(&peer_data, 0, sizeof(peer_data)); - peer_data.data_type = PM_PEER_DATA_ID_GATT_REMOTE; - peer_data.data.p_remote_gatt_db = p_remote_db; - - return pdb_raw_store(peer_id, &peer_data, NULL); -} - - -ret_code_t gccm_remote_db_retrieve(pm_peer_id_t peer_id, pm_peer_data_remote_gatt_db_t * p_remote_db) -{ - VERIFY_MODULE_INITIALIZED(); - VERIFY_PARAM_NOT_NULL(p_remote_db); - - // Initialize the peer_data - pm_peer_data_t peer_data; - memset(&peer_data, 0, sizeof(peer_data)); - peer_data.data_type = PM_PEER_DATA_ID_GATT_REMOTE; - peer_data.data.p_remote_gatt_db = p_remote_db; - - return pdb_raw_read(peer_id, PM_PEER_DATA_ID_GATT_REMOTE, &peer_data); -} diff --git a/components/ble/peer_manager/gattc_cache_manager.h b/components/ble/peer_manager/gattc_cache_manager.h deleted file mode 100644 index c8e6e35..0000000 --- a/components/ble/peer_manager/gattc_cache_manager.h +++ /dev/null @@ -1,83 +0,0 @@ - - -#ifndef GATTC_CACHE_MANAGER_H__ -#define GATTC_CACHE_MANAGER_H__ - -#include "stdint.h" -#include "sdk_errors.h" -#include "ble.h" -#include "ble_gap.h" -#include "peer_manager_types.h" - - -/** - * @defgroup gattc_cache_manager GATT Client Cache Manager - * @ingroup peer_manager - * @{ - * @brief An internal module of @ref peer_manager. A module for managing persistent storing of GATT - * attributes pertaining to the GATT client role of the local device. - */ - - -/**@brief Events that can come from the GATT Cache Manager module. - */ -typedef enum -{ - GCCM_EVT_REMOTE_DB_UPDATED, /**< Values for the specified data has been updated in persistent storage. */ - GCCM_EVT_REMOTE_DB_STORED, /**< New values for the specified data has been written in persistent storage. */ -} gccm_evt_id_t; - - -typedef struct -{ - gccm_evt_id_t evt_id; - pm_peer_id_t peer_id; -} gccm_evt_t; - -/**@brief Event handler for events from the GATT Client Cache Manager module. - * - * @param[in] event The event that has happened. - * @param[in] peer The id of the peer the event pertains to. - * @param[in] flags The data the event pertains to. - */ -typedef void (*gccm_evt_handler_t)(gccm_evt_t const * p_event); - - -/**@brief Function for initializing the GATT Client Cache Manager module. - * - * @param[in] evt_handler Callback for events from the GATT Client Cache Manager module. - * - * @retval NRF_SUCCESS Initialization was successful. - * @retval NRF_ERROR_NULL evt_handler was NULL. - */ -ret_code_t gccm_init(gccm_evt_handler_t evt_handler); - - -/**@brief Function for storing a discovered remote database persistently. - * - * @param[in] peer_id Peer to store the database for. - * @param[in] p_remote_db Database values to store. If NULL, values are cleared instead. - * - * @retval NRF_SUCCESS Store procedure successfully started. - * @retval NRF_ERROR_NOT_FOUND The peer id is invalid or unallocated. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. - */ -ret_code_t gccm_remote_db_store(pm_peer_id_t peer_id, pm_peer_data_remote_gatt_db_t * p_remote_db); - - -/**@brief Function for retrieving a persistently stored remote database. - * - * @param[in] peer_id Peer to retrieve data for. - * @param[inout] p_remote_db Copied database values. If NULL, nothing is copied. - * - * @retval NRF_SUCCESS Data retrieved successfully. - * @retval NRF_ERROR_NOT_FOUND The peer ID is invalid or unallocated. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. - */ -ret_code_t gccm_remote_db_retrieve(pm_peer_id_t peer_id, - pm_peer_data_remote_gatt_db_t * p_remote_db); - - - /* @} */ - -#endif /* GATTC_CACHE_MANAGER_H__ */ diff --git a/components/ble/peer_manager/gatts_cache_manager.c b/components/ble/peer_manager/gatts_cache_manager.c index f67de76..13cbd35 100644 --- a/components/ble/peer_manager/gatts_cache_manager.c +++ b/components/ble/peer_manager/gatts_cache_manager.c @@ -1,88 +1,136 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "gatts_cache_manager.h" #include #include "ble_gap.h" -#include "ble_conn_state.h" #include "peer_manager_types.h" +#include "peer_manager_internal.h" #include "peer_database.h" #include "id_manager.h" -#include "nordic_common.h" -#define SYS_ATTR_SYS (BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS) /**< Shorthand define for the flag for system attributes. */ -#define SYS_ATTR_USR (BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS) /**< Shorthand define for the flag for user attributes. */ -#define SYS_ATTR_BOTH (SYS_ATTR_SYS | SYS_ATTR_USR) /**< Shorthand define for the combined flags for system and user attributes. */ +// Syntactic sugar, two spoons. +#define SYS_ATTR_SYS (BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS) +#define SYS_ATTR_USR (BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS) +#define SYS_ATTR_BOTH (SYS_ATTR_SYS | SYS_ATTR_USR) +// The number of registered event handlers. +#define GSCM_EVENT_HANDLERS_CNT (sizeof(m_evt_handler) / sizeof(m_evt_handler[0])) -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * @ref NRF_ERROR_INVALID_STATE if not. - */ -#define VERIFY_MODULE_INITIALIZED() \ -do \ -{ \ - if (m_gscm.evt_handler == NULL) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * if not. - */ -#define VERIFY_MODULE_INITIALIZED_VOID()\ -do \ -{ \ - if (m_gscm.evt_handler == NULL) \ - { \ - return; \ - } \ -} while(0) - - -/**@brief Macro for verifying that a variable (typically a function parameter) is not NULL. It will - * cause the function to return @ref NRF_ERROR_NULL if not. - * - * @param[in] param The variable to check if is NULL. - */ -#define VERIFY_PARAM_NOT_NULL(param) \ -do \ -{ \ - if (param == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } \ -} while(0) +// GATTS Cache Manager event handler in Peer Manager. +extern void gcm_gscm_evt_handler(gscm_evt_t const * p_event); +// GATTS Cache Manager events' handlers. +// The number of elements in this array is GSCM_EVENT_HANDLERS_CNT. +static gscm_evt_handler_t m_evt_handler[] = +{ + gcm_gscm_evt_handler +}; + +static bool m_module_initialized; +static pm_peer_id_t m_current_sc_store_peer_id; -/**@brief Structure containing the module variable(s) of the GSCM module. + +/**@brief Function for resetting the module variable(s) of the GSCM module. */ -typedef struct +static void internal_state_reset() { - gscm_evt_handler_t evt_handler; /**< The event handler to use for outbound GSCM events. */ -} gscm_t; + m_module_initialized = false; + m_current_sc_store_peer_id = PM_PEER_ID_INVALID; +} -static gscm_t m_gscm; /**< Instantiation of module variable(s). */ +static void evt_send(gscm_evt_t const * p_event) +{ + for (uint32_t i = 0; i < GSCM_EVENT_HANDLERS_CNT; i++) + { + m_evt_handler[i](p_event); + } +} -/**@brief Function for resetting the module variable(s) of the GSCM module. + +//lint -save -e550 +/**@brief Function for storing service_changed_pending = true to flash for all peers, in sequence. * - * @param[out] The instance to reset. + * This function aborts if it gets @ref NRF_ERROR_BUSY when trying to store. A subsequent call will + * continue where the last call was aborted. */ -static void internal_state_reset(gscm_t * gscm) +static void service_changed_pending_set(void) { - memset(gscm, 0, sizeof(gscm_t)); + NRF_PM_DEBUG_CHECK(m_module_initialized); + + ret_code_t err_code; + // Use a uint32_t to enforce 4-byte alignment. + static const uint32_t service_changed_pending = true; + + //lint -save -e65 -e64 + pm_peer_data_const_t peer_data = + { + .data_id = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, + .length_words = PM_SC_STATE_N_WORDS(), + .p_service_changed_pending = (bool*)&service_changed_pending, + }; + //lint -restore + + err_code = pdb_raw_store(m_current_sc_store_peer_id, &peer_data, NULL); + while ((m_current_sc_store_peer_id != PM_PEER_ID_INVALID) && (err_code != NRF_ERROR_BUSY)) + { + m_current_sc_store_peer_id = pdb_next_peer_id_get(m_current_sc_store_peer_id); + err_code = pdb_raw_store(m_current_sc_store_peer_id, &peer_data, NULL); + } } +//lint -restore -/**@brief Event handler for events from the peer_database module. +/**@brief Event handler for events from the Peer Database module. + * This function is extern in Peer Database. * * @param[in] p_event The event that has happend with peer id and flags. */ -static void pdb_evt_handler(pdb_evt_t const * p_event) +void gscm_pdb_evt_handler(pdb_evt_t const * p_event) { if (p_event->evt_id == PDB_EVT_RAW_STORED) { @@ -91,45 +139,43 @@ static void pdb_evt_handler(pdb_evt_t const * p_event) ret_code_t err_code; pm_peer_data_flash_t peer_data; - err_code = pdb_read_buf_get(p_event->peer_id, PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, &peer_data, NULL); + err_code = pdb_peer_data_ptr_get(p_event->peer_id, + PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, + &peer_data); if (err_code == NRF_SUCCESS) { gscm_evt_t gscm_evt; gscm_evt.evt_id = GSCM_EVT_SC_STATE_STORED; gscm_evt.peer_id = p_event->peer_id; - gscm_evt.params.sc_state_stored.state = *peer_data.data.p_service_changed_pending; + gscm_evt.params.sc_state_stored.state = *peer_data.p_service_changed_pending; - m_gscm.evt_handler(&gscm_evt); + evt_send(&gscm_evt); } } } + + if (m_current_sc_store_peer_id != PM_PEER_ID_INVALID) + { + service_changed_pending_set(); + } } -ret_code_t gscm_init(gscm_evt_handler_t evt_handler) +ret_code_t gscm_init() { - ret_code_t err_code; - if (evt_handler == NULL) - { - err_code = NRF_ERROR_NULL; - } - else - { - err_code = pdb_register(pdb_evt_handler); - if (err_code == NRF_SUCCESS) - { - internal_state_reset(&m_gscm); - m_gscm.evt_handler = evt_handler; - } - } - return err_code; + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + internal_state_reset(); + m_module_initialized = true; + + return NRF_SUCCESS; } ret_code_t gscm_local_db_cache_update(uint16_t conn_handle) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle); ret_code_t err_code; @@ -151,11 +197,11 @@ ret_code_t gscm_local_db_cache_update(uint16_t conn_handle) err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_GATT_LOCAL, n_bufs++, &peer_data); if (err_code == NRF_SUCCESS) { - pm_peer_data_local_gatt_db_t * p_local_gatt_db = peer_data.data.p_local_gatt_db; + pm_peer_data_local_gatt_db_t * p_local_gatt_db = peer_data.p_local_gatt_db; p_local_gatt_db->flags = SYS_ATTR_BOTH; - err_code = sd_ble_gatts_sys_attr_get(conn_handle, &p_local_gatt_db->p_data[0], &p_local_gatt_db->len, p_local_gatt_db->flags); + err_code = sd_ble_gatts_sys_attr_get(conn_handle, &p_local_gatt_db->data[0], &p_local_gatt_db->len, p_local_gatt_db->flags); if (err_code == NRF_SUCCESS) { @@ -171,11 +217,14 @@ ret_code_t gscm_local_db_cache_update(uint16_t conn_handle) else if (err_code == NRF_ERROR_NOT_FOUND) { // There are no sys attributes in the GATT db, so nothing needs to be stored. - pdb_clear(peer_id, PM_PEER_DATA_ID_GATT_LOCAL); err_code = NRF_SUCCESS; } - pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_GATT_LOCAL); + ret_code_t err_code_release = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_GATT_LOCAL); + if (err_code_release != NRF_SUCCESS) + { + err_code = NRF_ERROR_INTERNAL; + } } } else if (err_code == NRF_ERROR_INVALID_PARAM) @@ -192,30 +241,28 @@ ret_code_t gscm_local_db_cache_update(uint16_t conn_handle) ret_code_t gscm_local_db_cache_apply(uint16_t conn_handle) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle); ret_code_t err_code; pm_peer_data_flash_t peer_data; uint8_t const * p_sys_attr_data = NULL; - uint8_t sys_attr_data[100]; // Workaround for s130 v1, which does not accept pointers to flash. uint16_t sys_attr_len = 0; uint32_t sys_attr_flags = (SYS_ATTR_BOTH); bool all_attributes_applied = true; - if (peer_id == PM_PEER_ID_INVALID) + if (peer_id != PM_PEER_ID_INVALID) { - return BLE_ERROR_INVALID_CONN_HANDLE; - } + err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_GATT_LOCAL, &peer_data); + if (err_code == NRF_SUCCESS) + { + pm_peer_data_local_gatt_db_t const * p_local_gatt_db; - err_code = pdb_read_buf_get(peer_id, PM_PEER_DATA_ID_GATT_LOCAL, &peer_data, NULL); - if (err_code == NRF_SUCCESS) - { - pm_peer_data_local_gatt_db_flash_t const * p_local_gatt_db = peer_data.data.p_local_gatt_db; - p_sys_attr_data = sys_attr_data; - sys_attr_len = p_local_gatt_db->len; - sys_attr_flags = p_local_gatt_db->flags; - memcpy(sys_attr_data, p_local_gatt_db->p_data, MIN(sys_attr_len, sizeof(sys_attr_data))); + p_local_gatt_db = peer_data.p_local_gatt_db; + p_sys_attr_data = p_local_gatt_db->data; + sys_attr_len = p_local_gatt_db->len; + sys_attr_flags = p_local_gatt_db->flags; + } } do @@ -264,51 +311,23 @@ ret_code_t gscm_local_db_cache_apply(uint16_t conn_handle) ret_code_t gscm_local_db_cache_set(pm_peer_id_t peer_id, pm_peer_data_local_gatt_db_t * p_local_db) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); pm_peer_data_const_t peer_data; memset(&peer_data, 0, sizeof(pm_peer_data_const_t)); - peer_data.data_type = PM_PEER_DATA_ID_GATT_LOCAL; - peer_data.data.p_local_gatt_db = p_local_db; + peer_data.data_id = PM_PEER_DATA_ID_GATT_LOCAL; + peer_data.p_local_gatt_db = p_local_db; return pdb_raw_store(peer_id, &peer_data, NULL); } -ret_code_t gscm_local_db_cache_get(pm_peer_id_t peer_id, pm_peer_data_local_gatt_db_t * p_local_db) -{ - VERIFY_MODULE_INITIALIZED(); - - pm_peer_data_t peer_data; - memset(&peer_data, 0, sizeof(pm_peer_data_t)); - peer_data.data.p_local_gatt_db = p_local_db; - - return pdb_raw_read(peer_id, PM_PEER_DATA_ID_GATT_LOCAL, &peer_data); -} - - void gscm_local_database_has_changed(void) { - VERIFY_MODULE_INITIALIZED_VOID(); - - static const bool service_changed_pending = true; - pm_peer_id_t current_peer_id = PM_PEER_ID_INVALID; - pm_peer_data_const_t peer_data = - { - .data_type = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, - .length_words = PM_SC_STATE_N_WORDS(), - .data = - { - .p_service_changed_pending = &service_changed_pending - } - }; - - do - { - current_peer_id = pdb_next_peer_id_get(current_peer_id); - pdb_raw_store(current_peer_id, &peer_data, NULL); - } while(current_peer_id != PM_PEER_ID_INVALID); + NRF_PM_DEBUG_CHECK(m_module_initialized); + m_current_sc_store_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); + service_changed_pending_set(); } @@ -318,14 +337,14 @@ bool gscm_service_changed_ind_needed(uint16_t conn_handle) pm_peer_data_flash_t peer_data; pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle); - err_code = pdb_read_buf_get(peer_id, PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, &peer_data, NULL); + err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, &peer_data); if (err_code != NRF_SUCCESS) { return false; } - return *peer_data.data.p_service_changed_pending; + return *peer_data.p_service_changed_pending; } @@ -338,11 +357,7 @@ ret_code_t gscm_service_changed_ind_send(uint16_t conn_handle) do { err_code = sd_ble_gatts_service_changed(conn_handle, start_handle, end_handle); - if (err_code == NRF_ERROR_INVALID_STATE) - { - err_code = NRF_SUCCESS; - } - else if (err_code == BLE_ERROR_INVALID_ATTR_HANDLE) + if (err_code == BLE_ERROR_INVALID_ATTR_HANDLE) { start_handle += 1; } @@ -352,22 +367,25 @@ ret_code_t gscm_service_changed_ind_send(uint16_t conn_handle) } -void gscm_peer_was_notified_of_db_change(pm_peer_id_t peer_id) +void gscm_db_change_notification_done(pm_peer_id_t peer_id) { - VERIFY_MODULE_INITIALIZED_VOID(); + NRF_PM_DEBUG_CHECK(m_module_initialized); - static const bool service_changed_pending = false; + // Use a uint32_t to enforce 4-byte alignment. + static const uint32_t service_changed_pending = false; + //lint -save -e65 -e64 pm_peer_data_const_t peer_data = { - .data_type = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, - .length_words = PM_SC_STATE_N_WORDS(), - .data = - { - .p_service_changed_pending = &service_changed_pending - } + .data_id = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, + .length_words = PM_SC_STATE_N_WORDS(), + .p_service_changed_pending = (bool*)&service_changed_pending, }; + //lint -restore // Don't need to check return code, because all error conditions can be ignored. - pdb_raw_store(peer_id, &peer_data, NULL); + //lint -save -e550 + (void) pdb_raw_store(peer_id, &peer_data, NULL); + //lint -restore } +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/gatts_cache_manager.h b/components/ble/peer_manager/gatts_cache_manager.h index adb2aee..dde3064 100644 --- a/components/ble/peer_manager/gatts_cache_manager.h +++ b/components/ble/peer_manager/gatts_cache_manager.h @@ -1,17 +1,61 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 GATTS_CACHE_MANAGER_H__ #define GATTS_CACHE_MANAGER_H__ -#include "stdint.h" +#include #include "sdk_errors.h" #include "ble.h" #include "ble_gap.h" #include "peer_manager_types.h" +#ifdef __cplusplus +extern "C" { +#endif + /** + * @cond NO_DOXYGEN * @defgroup gatts_cache_manager GATT Server Cache Manager * @ingroup peer_manager * @{ @@ -34,8 +78,8 @@ typedef enum */ typedef struct { - gscm_evt_id_t evt_id; /**< The type of event this is. */ - pm_peer_id_t peer_id; /**< The peer ID this event pertains to. */ + gscm_evt_id_t evt_id; /**< The type of event this is. */ + pm_peer_id_t peer_id; /**< The peer ID this event pertains to. */ union { struct @@ -59,13 +103,11 @@ typedef void (*gscm_evt_handler_t)(gscm_evt_t const * p_event); /**@brief Function for initializing the GATT Server Cache Manager module. - * - * @param[in] evt_handler Callback for events from the GATT Server Cache Manager module. * * @retval NRF_SUCCESS Initialization was successful. - * @retval NRF_ERROR_NULL evt_handler was NULL. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. */ -ret_code_t gscm_init(gscm_evt_handler_t evt_handler); +ret_code_t gscm_init(void); /**@brief Function for triggering local GATT database data to be stored persistently. Values are @@ -79,9 +121,9 @@ ret_code_t gscm_init(gscm_evt_handler_t evt_handler); * @retval NRF_ERROR_BUSY Unable to perform operation at this time. Reattempt later. * @retval NRF_ERROR_DATA_SIZE Write buffer not large enough. Call will never work with * this GATT database. - * @retval NRF_ERROR_NO_MEM No room in persistent_storage. Free up space; the + * @retval NRF_ERROR_STORAGE_FULL No room in persistent_storage. Free up space; the * operation will be automatically reattempted after the - * next compression procedure + * next FDS garbage collection procedure. * @retval NRF_ERROR_INVALID_STATE Module is not initialized. */ ret_code_t gscm_local_db_cache_update(uint16_t conn_handle); @@ -165,6 +207,9 @@ bool gscm_service_changed_ind_needed(uint16_t conn_handle); * @retval NRF_ERROR_BUSY Unable to send indication at this time. Reattempt later. * @retval BLE_ERROR_GATTS_SYS_ATTR_MISSING Information missing. Apply local cache, then reattempt. * @retval NRF_ERROR_INVALID_PARAM From @ref sd_ble_gatts_service_changed. Unexpected. + * @retval NRF_ERROR_NOT_SUPPORTED Service changed characteristic is not present. + * @retval NRF_ERROR_INVALID_STATE Service changed cannot be indicated to this peer + * because the peer has not subscribed to it. */ ret_code_t gscm_service_changed_ind_send(uint16_t conn_handle); @@ -177,8 +222,15 @@ ret_code_t gscm_service_changed_ind_send(uint16_t conn_handle); * * @param[in] peer_id The connection to send the indication on. */ -void gscm_peer_was_notified_of_db_change(pm_peer_id_t peer_id); +void gscm_db_change_notification_done(pm_peer_id_t peer_id); + +/** @} + * @endcond +*/ + -/** @} */ +#ifdef __cplusplus +} +#endif #endif /* GATTS_CACHE_MANAGER_H__ */ diff --git a/components/ble/peer_manager/id_manager.c b/components/ble/peer_manager/id_manager.c index 5b87c84..cf8505b 100644 --- a/components/ble/peer_manager/id_manager.c +++ b/components/ble/peer_manager/id_manager.c @@ -1,51 +1,77 @@ -/* Copyright (C) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "id_manager.h" #include -#include "nrf_soc.h" +#include "ble.h" #include "ble_gap.h" #include "ble_conn_state.h" #include "peer_manager_types.h" #include "peer_database.h" -#include "nordic_common.h" - -#define IM_MAX_CONN_HANDLES 8 -#define IM_NO_INVALID_CONN_HANDLES 0xFF -#define MAX_REGISTRANTS 3 -#define WHITELIST_MAX_COUNT MAX(BLE_GAP_WHITELIST_ADDR_MAX_COUNT, \ - BLE_GAP_WHITELIST_IRK_MAX_COUNT) -#define IM_ADDR_CLEARTEXT_LENGTH 3 -#define IM_ADDR_CIPHERTEXT_LENGTH 3 - -#define MODULE_INITIALIZED (m_im.n_registrants > 0) - -#define VERIFY_MODULE_INITIALIZED() \ -do \ -{ \ - if (!MODULE_INITIALIZED) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ -} while(0) - -#define VERIFY_PARAM_NOT_NULL(param) \ -do \ -{ \ - if (param == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } \ -} while(0) +#include "peer_data_storage.h" +#include "nrf_soc.h" + + +#define IM_MAX_CONN_HANDLES (8) +#define IM_NO_INVALID_CONN_HANDLES (0xFF) +#define IM_ADDR_CLEARTEXT_LENGTH (3) +#define IM_ADDR_CIPHERTEXT_LENGTH (3) + +// The number of registered event handlers. +#define IM_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) + + +// Identity Manager event handlers in Peer Manager and GATT Cache Manager. +extern void pm_im_evt_handler(im_evt_t const * p_event); +extern void gcm_im_evt_handler(im_evt_t const * p_event); + +// Identity Manager events' handlers. +// The number of elements in this array is IM_EVENT_HANDLERS_CNT. +static im_evt_handler_t const m_evt_handlers[] = +{ + pm_im_evt_handler, + gcm_im_evt_handler +}; typedef struct @@ -55,29 +81,25 @@ typedef struct ble_gap_addr_t peer_address; } im_connection_t; -typedef struct -{ - im_evt_handler_t evt_handlers[MAX_REGISTRANTS]; - uint8_t n_registrants; - im_connection_t connections[8]; - pm_peer_id_t whitelist_peer_ids[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - ble_gap_irk_t whitelist_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - ble_gap_addr_t whitelist_addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - uint8_t n_whitelist_peer_ids; - ble_conn_state_user_flag_id_t conn_state_user_flag_id; -} im_t; +static bool m_module_initialized; +static im_connection_t m_connections[8]; +static ble_conn_state_user_flag_id_t m_conn_state_user_flag_id; + +static uint8_t m_wlisted_peer_cnt; +static pm_peer_id_t m_wlisted_peers[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + +#if (NRF_SD_BLE_API_VERSION == 2) + static ble_gap_addr_t m_current_id_addr; +#endif -static im_t m_im = {.n_registrants = 0}; static void internal_state_reset() { - memset(&m_im, 0, sizeof(im_t)); - m_im.n_registrants = 0; - m_im.n_whitelist_peer_ids = 0; - m_im.conn_state_user_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID; + m_conn_state_user_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID; + for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) { - m_im.connections[i].conn_handle = BLE_CONN_HANDLE_INVALID; + m_connections[i].conn_handle = BLE_CONN_HANDLE_INVALID; } } @@ -88,15 +110,15 @@ static void internal_state_reset() */ static void evt_send(im_evt_t * p_event) { - for (uint32_t i = 0; i < m_im.n_registrants; i++) + for (uint32_t i = 0; i < IM_EVENT_HANDLERS_CNT; i++) { - m_im.evt_handlers[i](p_event); + m_evt_handlers[i](p_event); } } -/**@brief Function finding a free position in m_im.connections. +/**@brief Function finding a free position in m_connections. * - * @detail All connection handles in the m_im.connections array are checked against the connection + * @detail All connection handles in the m_connections array are checked against the connection * state module. The index of the first one that is not a connection handle for a current * connection is returned. This position in the array can safely be used for a new connection. * @@ -107,9 +129,9 @@ uint8_t get_free_connection() { for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) { - // Query the connection state module to check if the connection handle does not belong to a - // valid connection. - if (!ble_conn_state_user_flag_get(m_im.connections[i].conn_handle, m_im.conn_state_user_flag_id)) + // Query the connection state module to check if the + // connection handle does not belong to a valid connection. + if (!ble_conn_state_user_flag_get(m_connections[i].conn_handle, m_conn_state_user_flag_id)) { return i; } @@ -119,7 +141,7 @@ uint8_t get_free_connection() } -/**@brief Function finding a particular connection handle m_im.connections. +/**@brief Function finding a particular connection handle m_connections. * * @param[in] conn_handle The handle to find. * @@ -128,11 +150,11 @@ uint8_t get_free_connection() */ uint8_t get_connection_by_conn_handle(uint16_t conn_handle) { - if (ble_conn_state_user_flag_get(conn_handle, m_im.conn_state_user_flag_id)) + if (ble_conn_state_user_flag_get(conn_handle, m_conn_state_user_flag_id)) { for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) { - if (m_im.connections[i].conn_handle == conn_handle) + if (m_connections[i].conn_handle == conn_handle) { return i; } @@ -157,7 +179,7 @@ uint8_t new_connection(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr) if ((p_ble_addr != NULL) && (conn_handle != BLE_CONN_HANDLE_INVALID)) { - ble_conn_state_user_flag_set(conn_handle, m_im.conn_state_user_flag_id, true); + ble_conn_state_user_flag_set(conn_handle, m_conn_state_user_flag_id, true); conn_index = get_connection_by_conn_handle(conn_handle); if (conn_index == IM_NO_INVALID_CONN_HANDLES) @@ -167,9 +189,9 @@ uint8_t new_connection(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr) if (conn_index != IM_NO_INVALID_CONN_HANDLES) { - m_im.connections[conn_index].conn_handle = conn_handle; - m_im.connections[conn_index].peer_id = PM_PEER_ID_INVALID; - m_im.connections[conn_index].peer_address = *p_ble_addr; + m_connections[conn_index].conn_handle = conn_handle; + m_connections[conn_index].peer_id = PM_PEER_ID_INVALID; + m_connections[conn_index].peer_address = *p_ble_addr; } } return conn_index; @@ -180,16 +202,18 @@ uint8_t new_connection(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr) * * @detail An all-zero IRK is not valid. This function will check if a given IRK is valid. * - * @param[in] irk The IRK for which the validity is going to be checked. + * @param[in] p_irk The IRK for which the validity is going to be checked. * * @retval true The IRK is valid. * @retval false The IRK is invalid. */ -bool is_valid_irk(ble_gap_irk_t const * irk) +bool is_valid_irk(ble_gap_irk_t const * p_irk) { + NRF_PM_DEBUG_CHECK(p_irk != NULL); + for (uint32_t i = 0; i < BLE_GAP_SEC_KEY_LEN; i++) { - if (irk->irk[i] != 0) + if (p_irk->irk[i] != 0) { return true; } @@ -210,6 +234,7 @@ bool is_valid_irk(ble_gap_irk_t const * irk) */ bool addr_compare(ble_gap_addr_t const * p_addr1, ble_gap_addr_t const * p_addr2) { + // @note emdi: use NRF_PM_DEBUG_CHECK ? if ((p_addr1 == NULL) || (p_addr2 == NULL)) { return false; @@ -227,88 +252,85 @@ bool addr_compare(ble_gap_addr_t const * p_addr1, ble_gap_addr_t const * p_addr2 void im_ble_evt_handler(ble_evt_t * ble_evt) { - ret_code_t err_code; - switch (ble_evt->header.evt_id) + ble_gap_evt_t gap_evt; + pm_peer_id_t bonded_matching_peer_id; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + + if (ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED) { - case BLE_GAP_EVT_CONNECTED: - { - pm_peer_id_t bonded_matching_peer_id = PM_PEER_ID_INVALID; + // Nothing to do. + return; + } - if (ble_evt->evt.gap_evt.params.connected.irk_match == 1) - { - // The peer was matched using a whitelist. - bonded_matching_peer_id - = m_im.whitelist_peer_ids[ble_evt->evt.gap_evt.params.connected.irk_match_idx]; - } - else if ( ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type - != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) + gap_evt = ble_evt->evt.gap_evt; + bonded_matching_peer_id = PM_PEER_ID_INVALID; + + if ( gap_evt.params.connected.peer_addr.addr_type + != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) + { + /* Search the database for bonding data matching the one that triggered the event. + * Public and static addresses can be matched on address alone, while resolvable + * random addresses can be resolved agains known IRKs. Non-resolvable random addresses + * are never matching because they are not longterm form of identification. + */ + + pm_peer_id_t peer_id; + pm_peer_data_flash_t peer_data; + + pds_peer_data_iterate_prepare(); + + switch (gap_evt.params.connected.peer_addr.addr_type) + { + case BLE_GAP_ADDR_TYPE_PUBLIC: + case BLE_GAP_ADDR_TYPE_RANDOM_STATIC: { - /* Search the database for bonding data matching the one that triggered the event. - * Public and static addresses can be matched on address alone, while resolvable - * random addresses can be resolved agains known IRKs. Non-resolvable random addresses - * are never matching because they are not longterm form of identification. - */ - pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); - while ( (compared_peer_id != PM_PEER_ID_INVALID) - && (bonded_matching_peer_id == PM_PEER_ID_INVALID)) + while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) { - pm_peer_data_flash_t compared_data; - switch (ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type) + if (addr_compare(&gap_evt.params.connected.peer_addr, + &peer_data.p_bonding_data->peer_ble_id.id_addr_info)) { - case BLE_GAP_ADDR_TYPE_PUBLIC: - /* fall-through */ - case BLE_GAP_ADDR_TYPE_RANDOM_STATIC: - err_code = pdb_read_buf_get(compared_peer_id, - PM_PEER_DATA_ID_BONDING, - &compared_data, - NULL); - if ((err_code == NRF_SUCCESS) && - addr_compare(&ble_evt->evt.gap_evt.params.connected.peer_addr, - &compared_data.data.p_bonding_data->peer_id.id_addr_info) - ) - { - bonded_matching_peer_id = compared_peer_id; - } - break; - - case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE: - err_code = pdb_read_buf_get(compared_peer_id, - PM_PEER_DATA_ID_BONDING, - &compared_data, - NULL); - if (err_code == NRF_SUCCESS && - im_address_resolve(&ble_evt->evt.gap_evt.params.connected.peer_addr, - &compared_data.data.p_bonding_data->peer_id.id_info) - ) - { - bonded_matching_peer_id = compared_peer_id; - } - break; - - case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE: - // Should not happen. - break; - - default: - break; + bonded_matching_peer_id = peer_id; + break; } - compared_peer_id = pdb_next_peer_id_get(compared_peer_id); } } - new_connection(ble_evt->evt.gap_evt.conn_handle, &ble_evt->evt.gap_evt.params.connected.peer_addr); + break; - if (bonded_matching_peer_id != PM_PEER_ID_INVALID) + case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE: { - im_new_peer_id(ble_evt->evt.gap_evt.conn_handle, bonded_matching_peer_id); - - // Send a bonded peer event - im_evt_t im_evt; - im_evt.conn_handle = ble_evt->evt.gap_evt.conn_handle; - im_evt.evt_id = IM_EVT_BONDED_PEER_CONNECTED; - evt_send(&im_evt); + while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) + { + if (im_address_resolve(&gap_evt.params.connected.peer_addr, + &peer_data.p_bonding_data->peer_ble_id.id_info)) + { + bonded_matching_peer_id = peer_id; + break; + } + } } + break; + + default: + NRF_PM_DEBUG_CHECK(false); + break; } } + + uint8_t new_index = new_connection(gap_evt.conn_handle, + &gap_evt.params.connected.peer_addr); + UNUSED_VARIABLE(new_index); + + if (bonded_matching_peer_id != PM_PEER_ID_INVALID) + { + im_new_peer_id(gap_evt.conn_handle, bonded_matching_peer_id); + + // Send a bonded peer event + im_evt_t im_evt; + im_evt.conn_handle = gap_evt.conn_handle; + im_evt.evt_id = IM_EVT_BONDED_PEER_CONNECTED; + evt_send(&im_evt); + } } @@ -320,108 +342,124 @@ void im_ble_evt_handler(ble_evt_t * ble_evt) * * @return True if the input matches, false if it does not. */ -bool is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1, - pm_peer_data_bonding_t const * p_bonding_data2) -{ - bool valid_irk = is_valid_irk(&p_bonding_data1->peer_id.id_info); - bool duplicate_irk = valid_irk && - (memcmp(p_bonding_data1->peer_id.id_info.irk, - p_bonding_data2->peer_id.id_info.irk, - BLE_GAP_SEC_KEY_LEN) == 0 - ); - bool duplicate_addr = addr_compare(&p_bonding_data1->peer_id.id_addr_info, - &p_bonding_data2->peer_id.id_addr_info - ); +bool im_is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1, + pm_peer_data_bonding_t const * p_bonding_data2) +{ + NRF_PM_DEBUG_CHECK(p_bonding_data1 != NULL); + NRF_PM_DEBUG_CHECK(p_bonding_data2 != NULL); + + if (!is_valid_irk(&p_bonding_data1->peer_ble_id.id_info)) + { + return false; + } + + bool duplicate_irk = (memcmp(p_bonding_data1->peer_ble_id.id_info.irk, + p_bonding_data2->peer_ble_id.id_info.irk, + BLE_GAP_SEC_KEY_LEN) == 0); + + bool duplicate_addr = addr_compare(&p_bonding_data1->peer_ble_id.id_addr_info, + &p_bonding_data2->peer_ble_id.id_addr_info); + return duplicate_irk || duplicate_addr; } -/**@brief Event handler for events from the peer_database module. +/**@brief Event handler for events from the Peer Database module. + * This function is extern in Peer Database. * * @param[in] p_event The event that has happend with peer id and flags. */ -static void pdb_evt_handler(pdb_evt_t const * p_event) +void im_pdb_evt_handler(pdb_evt_t const * p_event) { - ret_code_t err_code; - if ((p_event != NULL) && (p_event->evt_id == PDB_EVT_WRITE_BUF_STORED)) + ret_code_t ret; + pm_peer_id_t peer_id; + pm_peer_data_flash_t peer_data; + pm_peer_data_flash_t peer_data_duplicate; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_event != NULL); + + if ((p_event->evt_id != PDB_EVT_WRITE_BUF_STORED) || + (p_event->data_id != PM_PEER_DATA_ID_BONDING)) { - // If new data about peer id has been stored it is compared to other peers peer ids in - // search of duplicates. - if (p_event->data_id == PM_PEER_DATA_ID_BONDING) - { - pm_peer_data_flash_t written_data; - err_code = pdb_read_buf_get(p_event->peer_id, PM_PEER_DATA_ID_BONDING, &written_data, NULL); - if (err_code == NRF_SUCCESS) - { - pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); - while (compared_peer_id != PM_PEER_ID_INVALID) - { - pm_peer_data_flash_t compared_data; - err_code = pdb_read_buf_get(compared_peer_id, - PM_PEER_DATA_ID_BONDING, - &compared_data, - NULL); - if ( err_code == NRF_SUCCESS && - p_event->peer_id != compared_peer_id && - is_duplicate_bonding_data(written_data.data.p_bonding_data, - compared_data.data.p_bonding_data) - ) - { - im_evt_t im_evt; - im_evt.conn_handle = im_conn_handle_get(p_event->peer_id); - im_evt.evt_id = IM_EVT_DUPLICATE_ID; - im_evt.params.duplicate_id.peer_id_1 = p_event->peer_id; - im_evt.params.duplicate_id.peer_id_2 = compared_peer_id; - evt_send(&im_evt); - } - compared_peer_id = pdb_next_peer_id_get(compared_peer_id); - } - } - } + return; } -} + // If new data about peer id has been stored it is compared to other peers peer ids in + // search of duplicates. -ret_code_t im_register(im_evt_handler_t evt_handler) -{ - VERIFY_PARAM_NOT_NULL(evt_handler); - ret_code_t err_code = NRF_SUCCESS; + ret = pdb_peer_data_ptr_get(p_event->peer_id, PM_PEER_DATA_ID_BONDING, &peer_data); + + if (ret != NRF_SUCCESS) + { + // @note emdi: this shouldn't happen, since the data was just stored, right? + NRF_PM_DEBUG_CHECK(false); + return; + } + + pds_peer_data_iterate_prepare(); - if (!MODULE_INITIALIZED) + while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data_duplicate)) { - internal_state_reset(); - m_im.conn_state_user_flag_id = ble_conn_state_user_flag_acquire(); - if (m_im.conn_state_user_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) + if (p_event->peer_id == peer_id) { - err_code = NRF_ERROR_NO_MEM; + // Skip the iteration if the bonding data retrieved is for a peer + // with the same ID as the one contained in the event. + continue; } - else + + if (im_is_duplicate_bonding_data(peer_data.p_bonding_data, + peer_data_duplicate.p_bonding_data)) { - err_code = pdb_register(pdb_evt_handler); + im_evt_t im_evt; + im_evt.conn_handle = im_conn_handle_get(p_event->peer_id); + im_evt.evt_id = IM_EVT_DUPLICATE_ID; + im_evt.params.duplicate_id.peer_id_1 = p_event->peer_id; + im_evt.params.duplicate_id.peer_id_2 = peer_id; + evt_send(&im_evt); + break; } } - if (err_code == NRF_SUCCESS) +} + + +ret_code_t im_init(void) +{ + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + internal_state_reset(); + + m_conn_state_user_flag_id = ble_conn_state_user_flag_acquire(); + if (m_conn_state_user_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) { - if ((m_im.n_registrants < MAX_REGISTRANTS)) - { - m_im.evt_handlers[m_im.n_registrants++] = evt_handler; - } - else + return NRF_ERROR_INTERNAL; + } + + #if (NRF_SD_BLE_API_VERSION == 2) + ret_code_t ret_code = sd_ble_gap_address_get(&m_current_id_addr); + if (ret_code != NRF_SUCCESS) { - err_code = NRF_ERROR_NO_MEM; + return NRF_ERROR_INTERNAL; } - } - return err_code; + #endif + + m_module_initialized = true; + + return NRF_SUCCESS; } pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle) { - uint8_t conn_index = get_connection_by_conn_handle(conn_handle); + uint8_t conn_index; + + NRF_PM_DEBUG_CHECK(m_module_initialized); - if (MODULE_INITIALIZED && (conn_index != IM_NO_INVALID_CONN_HANDLES)) + conn_index = get_connection_by_conn_handle(conn_handle); + + if (conn_index != IM_NO_INVALID_CONN_HANDLES) { - return m_im.connections[conn_index].peer_id; + return m_connections[conn_index].peer_id; } return PM_PEER_ID_INVALID; @@ -430,13 +468,16 @@ pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle) ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr) { - VERIFY_MODULE_INITIALIZED(); - VERIFY_PARAM_NOT_NULL(p_ble_addr); + uint8_t conn_index; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_ble_addr != NULL); + + conn_index = get_connection_by_conn_handle(conn_handle); - uint8_t conn_index = get_connection_by_conn_handle(conn_handle); if (conn_index != IM_NO_INVALID_CONN_HANDLES) { - *p_ble_addr = m_im.connections[conn_index].peer_address; + *p_ble_addr = m_connections[conn_index].peer_address; return NRF_SUCCESS; } @@ -444,83 +485,62 @@ ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr) } -/**@brief Function for comparing two master ids - * @note Two invalid master IDs will not match. - * - * @param[in] p_master_id1 First master id for comparison - * @param[in] p_master_id2 Second master id for comparison - * - * @return True if the input matches, false if it does not. - */ -bool master_id_compare(ble_gap_master_id_t const * p_master_id1, - ble_gap_master_id_t const * p_master_id2) +bool im_master_ids_compare(ble_gap_master_id_t const * p_master_id1, + ble_gap_master_id_t const * p_master_id2) { - if(!im_master_id_is_valid(p_master_id1)) + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_master_id1 != NULL); + NRF_PM_DEBUG_CHECK(p_master_id2 != NULL); + + if (!im_master_id_is_valid(p_master_id1)) { return false; } + if (p_master_id1->ediv != p_master_id2->ediv) { return false; } + return (memcmp(p_master_id1->rand, p_master_id2->rand, BLE_GAP_SEC_RAND_LEN) == 0); } pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t * p_master_id) { - ret_code_t err_code; - // For each stored peer, check if the master_id match p_master_id - pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); - while (compared_peer_id != PM_PEER_ID_INVALID) - { - pm_peer_data_flash_t compared_data; - ble_gap_master_id_t const * p_compared_master_id; + pm_peer_id_t peer_id; + pm_peer_data_flash_t peer_data; - err_code = pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL); - if (err_code == NRF_SUCCESS) - { - p_compared_master_id = &compared_data.data.p_bonding_data->own_ltk.master_id; - if (compared_data.data.p_bonding_data->own_role == BLE_GAP_ROLE_CENTRAL) - { - p_compared_master_id = &compared_data.data.p_bonding_data->peer_ltk.master_id; - } - if (master_id_compare(p_master_id, p_compared_master_id)) - { - // If a matching master_id is found return the peer_id - return compared_peer_id; - } - } - compared_peer_id = pdb_next_peer_id_get(compared_peer_id); - } - // If no matching master_id is found return the PM_PEER_ID_INVALID - return PM_PEER_ID_INVALID; -} + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_master_id != NULL); + pds_peer_data_iterate_prepare(); -pm_peer_id_t im_peer_id_get_by_irk_match_idx(uint8_t irk_match_idx) -{ - // Verify that the requested idx is within the list - if (irk_match_idx < m_im.n_whitelist_peer_ids) - { - // Return the peer_id from the white list - return m_im.whitelist_peer_ids[irk_match_idx]; - } - else + // For each stored peer, check if the master_id matches p_master_id + while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) { - // Return PM_PEER_ID_INVALID to indicate that there was no peer with the requested idx - return PM_PEER_ID_INVALID; + if (im_master_ids_compare(p_master_id, &peer_data.p_bonding_data->own_ltk.master_id) || + im_master_ids_compare(p_master_id, &peer_data.p_bonding_data->peer_ltk.master_id)) + { + // If a matching master ID is found then return the peer ID. + return peer_id; + } } + + // If no matching master ID is found return PM_PEER_ID_INVALID. + return PM_PEER_ID_INVALID; } uint16_t im_conn_handle_get(pm_peer_id_t peer_id) { + NRF_PM_DEBUG_CHECK(m_module_initialized); + for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++) { - if (peer_id == m_im.connections[i].peer_id) + if (peer_id == m_connections[i].peer_id) { - return m_im.connections[i].conn_handle; + return m_connections[i].conn_handle; } } return BLE_CONN_HANDLE_INVALID; @@ -529,11 +549,13 @@ uint16_t im_conn_handle_get(pm_peer_id_t peer_id) bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id) { + NRF_PM_DEBUG_CHECK(m_module_initialized); if (p_master_id->ediv != 0) { return true; } + for (uint32_t i = 0; i < BLE_GAP_SEC_RAND_LEN; i++) { if (p_master_id->rand[i] != 0) @@ -545,125 +567,460 @@ bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id) } -void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id) +/**@brief Function to set the peer ID associated with a connection handle. + * + * @param[in] conn_handle The connection handle. + * @param[in] peer_id The peer ID to associate with @c conn_handle. + */ +static void peer_id_set(uint16_t conn_handle, pm_peer_id_t peer_id) { uint8_t conn_index = get_connection_by_conn_handle(conn_handle); if (conn_index != IM_NO_INVALID_CONN_HANDLES) { - m_im.connections[conn_index].peer_id = peer_id; + m_connections[conn_index].peer_id = peer_id; } } -ret_code_t im_wlist_create(pm_peer_id_t * p_peer_ids, - uint8_t n_peer_ids, - ble_gap_whitelist_t * p_whitelist) +void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + peer_id_set(conn_handle, peer_id); +} + + +ret_code_t im_peer_free(pm_peer_id_t peer_id) +{ + uint16_t conn_handle; + ret_code_t ret; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + + conn_handle = im_conn_handle_get(peer_id); + ret = pdb_peer_free(peer_id); + + if ((conn_handle != BLE_CONN_HANDLE_INVALID) && (ret == NRF_SUCCESS)) + { + peer_id_set(conn_handle, PM_PEER_ID_INVALID); + } + return ret; +} + + +/**@brief Given a list of peers, loads their GAP address and IRK into the provided buffers. + */ +static ret_code_t peers_id_keys_get(pm_peer_id_t const * p_peers, + uint32_t peer_cnt, + ble_gap_addr_t * p_gap_addrs, + uint32_t * p_addr_cnt, + ble_gap_irk_t * p_gap_irks, + uint32_t * p_irk_cnt) { - VERIFY_MODULE_INITIALIZED(); - VERIFY_PARAM_NOT_NULL(p_whitelist); - ret_code_t err_code; - p_whitelist->addr_count = 0; - p_whitelist->irk_count = 0; - m_im.n_whitelist_peer_ids = 0; - for (uint32_t peer_index = 0; peer_index < n_peer_ids; peer_index++) + ret_code_t ret; + + pm_peer_data_bonding_t bond_data; + pm_peer_data_t peer_data; + + uint32_t const buf_size = sizeof(bond_data); + + bool copy_addrs = false; + bool copy_irks = false; + + NRF_PM_DEBUG_CHECK(p_peers != NULL); + + // One of these two has to be provided. + NRF_PM_DEBUG_CHECK((p_gap_addrs != NULL) || (p_gap_irks != NULL)); + + if ((p_gap_addrs != NULL) && (p_addr_cnt != NULL)) + { + NRF_PM_DEBUG_CHECK((*p_addr_cnt) >= peer_cnt); + + copy_addrs = true; + *p_addr_cnt = 0; + } + + if ((p_gap_irks != NULL) && (p_irk_cnt != NULL)) { - bool peer_connected = false; - for (uint32_t conn_index = 0; conn_index < IM_MAX_CONN_HANDLES; conn_index++) + NRF_PM_DEBUG_CHECK((*p_irk_cnt) >= peer_cnt); + + copy_irks = true; + *p_irk_cnt = 0; + } + + memset(&peer_data, 0x00, sizeof(peer_data)); + peer_data.p_bonding_data = &bond_data; + + // Read through flash memory and look for peers ID keys. + + for (uint32_t i = 0; i < peer_cnt; i++) + { + memset(&bond_data, 0x00, sizeof(bond_data)); + + // Read peer data from flash. + ret = pds_peer_data_read(p_peers[i], PM_PEER_DATA_ID_BONDING, + &peer_data, &buf_size); + + if ((ret == NRF_ERROR_NOT_FOUND) || (ret == NRF_ERROR_INVALID_PARAM)) { - if (p_peer_ids[peer_index] == m_im.connections[conn_index].peer_id && - ble_conn_state_user_flag_get(m_im.connections[conn_index].conn_handle, m_im.conn_state_user_flag_id) - ) - { - peer_connected = true; - break; - } + // Peer data coulnd't be found in flash or peer ID is not valid. + return NRF_ERROR_NOT_FOUND; } - if (!peer_connected) + + uint8_t const addr_type = bond_data.peer_ble_id.id_addr_info.addr_type; + + if ((addr_type != BLE_GAP_ADDR_TYPE_PUBLIC) && + (addr_type != BLE_GAP_ADDR_TYPE_RANDOM_STATIC)) { - pm_peer_data_flash_t peer_data; - err_code = pdb_read_buf_get(p_peer_ids[peer_index], PM_PEER_DATA_ID_BONDING, &peer_data, NULL); - if (err_code == NRF_ERROR_INVALID_PARAM || err_code == NRF_ERROR_NOT_FOUND) - { - return NRF_ERROR_INVALID_PARAM; - } - if (p_whitelist->pp_addrs != NULL && - peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type - != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE && - peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type - != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE - ) + // The address shared by the peer during bonding can't be used for whitelisting. + return BLE_ERROR_GAP_INVALID_BLE_ADDR; + } + + // Copy the GAP address. + if (copy_addrs) + { + memcpy(&p_gap_addrs[i], &bond_data.peer_ble_id.id_addr_info, sizeof(ble_gap_addr_t)); + (*p_addr_cnt)++; + } + + // Copy the IRK. + if (copy_irks) + { + memcpy(&p_gap_irks[i], bond_data.peer_ble_id.id_info.irk, BLE_GAP_SEC_KEY_LEN); + (*p_irk_cnt)++; + } + } + + return NRF_SUCCESS; +} + + +ret_code_t im_device_identities_list_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt) +{ + #if (NRF_SD_BLE_API_VERSION == 3) + + ret_code_t ret; + pm_peer_data_t peer_data; + pm_peer_data_bonding_t bond_data; + + ble_gap_id_key_t keys[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + ble_gap_id_key_t const * key_ptrs[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + + if ((p_peers == NULL) || (peer_cnt == 0)) + { + // Clear the device identities list. + return sd_ble_gap_device_identities_set(NULL, NULL, 0); + } + + peer_data.p_bonding_data = &bond_data; + uint32_t const buf_size = sizeof(bond_data); + + memset(keys, 0x00, sizeof(keys)); + for (uint32_t i = 0; i < BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT; i++) + { + key_ptrs[i] = &keys[i]; + } + + for (uint32_t i = 0; i < peer_cnt; i++) + { + memset(&bond_data, 0x00, sizeof(bond_data)); + + // Read peer data from flash. + ret = pds_peer_data_read(p_peers[i], PM_PEER_DATA_ID_BONDING, + &peer_data, &buf_size); + + if ((ret == NRF_ERROR_NOT_FOUND) || (ret == NRF_ERROR_INVALID_PARAM)) { - memcpy(m_im.whitelist_addrs[peer_index].addr, - peer_data.data.p_bonding_data->peer_id.id_addr_info.addr, - BLE_GAP_ADDR_LEN - ); - m_im.whitelist_addrs[peer_index].addr_type = - peer_data.data.p_bonding_data->peer_id.id_addr_info.addr_type; - p_whitelist->pp_addrs[peer_index] = &m_im.whitelist_addrs[peer_index]; - p_whitelist->addr_count++; + // Peer data coulnd't be found in flash or peer ID is not valid. + return NRF_ERROR_NOT_FOUND; } - if (p_whitelist->pp_irks != NULL && - is_valid_irk(&(peer_data.data.p_bonding_data->peer_id.id_info)) - ) + + uint8_t const addr_type = bond_data.peer_ble_id.id_addr_info.addr_type; + + if ((addr_type != BLE_GAP_ADDR_TYPE_PUBLIC) && + (addr_type != BLE_GAP_ADDR_TYPE_RANDOM_STATIC)) { - memcpy(m_im.whitelist_irks[peer_index].irk, - peer_data.data.p_bonding_data->peer_id.id_info.irk, - BLE_GAP_SEC_KEY_LEN - ); - p_whitelist->pp_irks[peer_index] = &m_im.whitelist_irks[peer_index]; - p_whitelist->irk_count++; - m_im.whitelist_peer_ids[peer_index] = p_peer_ids[peer_index]; - m_im.n_whitelist_peer_ids++; + // The address shared by the peer during bonding can't be whitelisted. + return BLE_ERROR_GAP_INVALID_BLE_ADDR; } + + // Copy data to the buffer. + memcpy(&keys[i], &bond_data.peer_ble_id, sizeof(ble_gap_id_key_t)); } - } - return NRF_SUCCESS; + + return sd_ble_gap_device_identities_set(key_ptrs, NULL, peer_cnt); + + #else + + return NRF_ERROR_NOT_SUPPORTED; + + #endif } -ret_code_t im_wlist_set(ble_gap_whitelist_t * p_whitelist) +#if (NRF_SD_BLE_API_VERSION == 2) + +static ret_code_t address_set_v2(uint8_t cycle_mode, ble_gap_addr_t * p_addr) { - pm_peer_id_t new_whitelist_peer_ids[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - uint32_t n_new_whitelist_peer_ids = 0; - VERIFY_PARAM_NOT_NULL(p_whitelist); - for (uint32_t i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++) + NRF_PM_DEBUG_CHECK(p_addr != NULL); + + ret_code_t ret = sd_ble_gap_address_set(cycle_mode, p_addr); + + switch (ret) { - new_whitelist_peer_ids[i] = PM_PEER_ID_INVALID; + case NRF_SUCCESS: + case NRF_ERROR_BUSY: + case NRF_ERROR_INVALID_STATE: + case NRF_ERROR_INVALID_PARAM: // If cycle_mode is not AUTO or NONE. + case BLE_ERROR_GAP_INVALID_BLE_ADDR: // If the GAP address is not valid. + return ret; + + default: + return NRF_ERROR_INTERNAL; } - pm_peer_id_t compared_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); - while (compared_peer_id != PM_PEER_ID_INVALID) - { - pm_peer_data_flash_t compared_data; - pdb_read_buf_get(compared_peer_id, PM_PEER_DATA_ID_BONDING, &compared_data, NULL); - for (uint32_t i = 0; i < p_whitelist->irk_count; i++) +} + +#endif + + +ret_code_t im_id_addr_set(ble_gap_addr_t const * p_addr) +{ + #if (NRF_SD_BLE_API_VERSION == 2) + + ret_code_t ret; + ble_gap_addr_t current_addr; + + NRF_PM_DEBUG_CHECK(p_addr != NULL); + + (void) sd_ble_gap_address_get(¤t_addr); + + ret = address_set_v2(BLE_GAP_ADDR_CYCLE_MODE_NONE, (ble_gap_addr_t *)p_addr); + if (ret != NRF_SUCCESS) + { + return ret; + } + + if ( current_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE + || current_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) { - bool valid_irk = is_valid_irk(&compared_data.data.p_bonding_data->peer_id.id_info); - bool duplicate_irk = valid_irk && - (memcmp(p_whitelist->pp_irks[i]->irk, - compared_data.data.p_bonding_data->peer_id.id_info.irk, - BLE_GAP_SEC_KEY_LEN) == 0 - ); - if (duplicate_irk) + // If currently using privacy, it must be re-enabled. + // We force AUTO when privacy is enabled. + ret = address_set_v2(BLE_GAP_ADDR_CYCLE_MODE_AUTO, ¤t_addr); + if (ret != NRF_SUCCESS) { - new_whitelist_peer_ids[i] = compared_peer_id; - n_new_whitelist_peer_ids++; + return ret; } } - compared_peer_id = pdb_next_peer_id_get(compared_peer_id); - } - if (n_new_whitelist_peer_ids != p_whitelist->irk_count) + + memcpy(&m_current_id_addr, p_addr, sizeof(ble_gap_addr_t)); + + return NRF_SUCCESS; + + #else + + return sd_ble_gap_addr_set(p_addr); + + #endif +} + + +ret_code_t im_id_addr_get(ble_gap_addr_t * p_addr) +{ + NRF_PM_DEBUG_CHECK(p_addr != NULL); + + #if (NRF_SD_BLE_API_VERSION == 2) + memcpy(p_addr, &m_current_id_addr, sizeof(ble_gap_addr_t)); + return NRF_SUCCESS; + #else + return sd_ble_gap_addr_get(p_addr); + #endif +} + + +ret_code_t im_privacy_set(pm_privacy_params_t const * p_privacy_params) +{ + #if (NRF_SD_BLE_API_VERSION == 2) + + ret_code_t ret; + ble_gap_addr_t privacy_addr; + ble_gap_irk_t current_irk; + ble_opt_t privacy_options; + ble_opt_t current_privacy_options; + + NRF_PM_DEBUG_CHECK(p_privacy_params != NULL); + + privacy_addr.addr_type = p_privacy_params->private_addr_type; + privacy_options.gap_opt.privacy.p_irk = p_privacy_params->p_device_irk; + privacy_options.gap_opt.privacy.interval_s = p_privacy_params->private_addr_cycle_s; + current_privacy_options.gap_opt.privacy.p_irk = ¤t_irk; + + // Can not fail. + (void) sd_ble_opt_get(BLE_GAP_OPT_PRIVACY, ¤t_privacy_options); + (void) sd_ble_opt_set(BLE_GAP_OPT_PRIVACY, &privacy_options); + + if (p_privacy_params->privacy_mode == BLE_GAP_PRIVACY_MODE_OFF) + { + ret = address_set_v2(BLE_GAP_ADDR_CYCLE_MODE_NONE, &m_current_id_addr); + } + else + { + ret = address_set_v2(BLE_GAP_ADDR_CYCLE_MODE_AUTO, &privacy_addr); + } + + if (ret != NRF_SUCCESS) + { + // Restore previous settings. + (void) sd_ble_opt_set(BLE_GAP_OPT_PRIVACY, ¤t_privacy_options); + } + + // NRF_ERROR_BUSY, + // NRF_ERROR_INVALID_STATE, + // NRF_ERROR_INVALID_PARAM, if address type is not valid. + return ret; + + #else + + return sd_ble_gap_privacy_set(p_privacy_params); + + #endif +} + + +ret_code_t im_privacy_get(pm_privacy_params_t * p_privacy_params) +{ + #if (NRF_SD_BLE_API_VERSION == 2) + + ble_gap_addr_t cur_addr; + ble_opt_t cur_privacy_opt; + + NRF_PM_DEBUG_CHECK(p_privacy_params != NULL); + NRF_PM_DEBUG_CHECK(p_privacy_params->p_device_irk != NULL); + + cur_privacy_opt.gap_opt.privacy.p_irk = p_privacy_params->p_device_irk; + + // Can not fail. + (void) sd_ble_gap_address_get(&cur_addr); + + if ( cur_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE + || cur_addr.addr_type == BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) + { + p_privacy_params->privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY; + p_privacy_params->private_addr_type = cur_addr.addr_type; + } + else + { + p_privacy_params->privacy_mode = BLE_GAP_PRIVACY_MODE_OFF; + } + + // Can not fail. + (void) sd_ble_opt_get(BLE_GAP_OPT_PRIVACY, &cur_privacy_opt); + + p_privacy_params->private_addr_cycle_s = cur_privacy_opt.gap_opt.privacy.interval_s; + + return NRF_SUCCESS; + + #else + + return sd_ble_gap_privacy_get(p_privacy_params); + + #endif +} + + +/* Create a whitelist for the user using the cached list of peers. + * This whitelist is meant to be provided by the application to the Advertising module. + */ +ret_code_t im_whitelist_get(ble_gap_addr_t * p_addrs, + uint32_t * p_addr_cnt, + ble_gap_irk_t * p_irks, + uint32_t * p_irk_cnt) +{ + // One of the two buffers has to be provided. + NRF_PM_DEBUG_CHECK((p_addrs != NULL) || (p_irks != NULL)); + NRF_PM_DEBUG_CHECK((p_addr_cnt != NULL) || (p_irk_cnt != NULL)); + + if (((p_addr_cnt != NULL) && (m_wlisted_peer_cnt > *p_addr_cnt)) || + ((p_irk_cnt != NULL) && (m_wlisted_peer_cnt > *p_irk_cnt))) { - return NRF_ERROR_NOT_FOUND; + // The size of the cached list of peers is larger than the provided buffers. + return NRF_ERROR_NO_MEM; } - else + + // NRF_SUCCESS or + // NRF_ERROR_NOT_FOUND, if a peer or its data were not found. + // BLE_ERROR_GAP_INVALID_BLE_ADDR, if a peer address can not be used for whitelisting. + return peers_id_keys_get(m_wlisted_peers, m_wlisted_peer_cnt, + p_addrs, p_addr_cnt, + p_irks, p_irk_cnt); +} + + +/* Copies the peers to whitelist into a local cache. + * The cached list will be used by im_whitelist_get() to retrieve the active whitelist. + * For SoftDevices 3x, also loads the peers' GAP addresses and whitelists them using + * sd_ble_gap_whitelist_set(). + */ +ret_code_t im_whitelist_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt) +{ + // Clear the cache of whitelisted peers. + memset(m_wlisted_peers, 0x00, sizeof(m_wlisted_peers)); + + if ((p_peers == NULL) || (peer_cnt == 0)) { - for (uint32_t i = 0; i < n_new_whitelist_peer_ids; i++) + // Clear the current whitelist. + m_wlisted_peer_cnt = 0; + #if (NRF_SD_BLE_API_VERSION == 3) + // NRF_SUCCESS, or + // BLE_GAP_ERROR_WHITELIST_IN_USE + return sd_ble_gap_whitelist_set(NULL, 0); + #else + // The cached list of whitelisted peers is already cleared; nothing to do. + return NRF_SUCCESS; + #endif + } + + // @todo emdi: should not ever cache more than BLE_GAP_WHITELIST_ADDR_MAX_COUNT... + + // Copy the new whitelisted peers. + m_wlisted_peer_cnt = peer_cnt; + memcpy(m_wlisted_peers, p_peers, sizeof(pm_peer_id_t) * peer_cnt); + + #if (NRF_SD_BLE_API_VERSION == 3) + + ret_code_t ret; + uint32_t wlist_addr_cnt = 0; + + ble_gap_addr_t const * addr_ptrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + ble_gap_addr_t addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + + memset(addrs, 0x00, sizeof(addrs)); + + // Fetch GAP addresses for these peers, but don't fetch IRKs. + ret = peers_id_keys_get(p_peers, peer_cnt, addrs, &wlist_addr_cnt, NULL, NULL); + + if (ret != NRF_SUCCESS) { - m_im.whitelist_peer_ids[i] = new_whitelist_peer_ids[i]; + // NRF_ERROR_NOT_FOUND, if a peer or its data were not found. + // BLE_ERROR_GAP_INVALID_BLE_ADDR, if a peer address can not be used for whitelisting. + return ret; } - m_im.n_whitelist_peer_ids = n_new_whitelist_peer_ids; + + for (uint32_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++) + { + addr_ptrs[i] = &addrs[i]; + } + + // NRF_ERROR_DATA_SIZE, if peer_cnt > BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + // BLE_ERROR_GAP_WHITELIST_IN_USE, if a whitelist is in use. + return sd_ble_gap_whitelist_set(addr_ptrs, peer_cnt); + + #else + return NRF_SUCCESS; - } + + #endif } @@ -693,10 +1050,12 @@ ret_code_t im_wlist_set(ble_gap_whitelist_t * p_whitelist) void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash) { nrf_ecb_hal_data_t ecb_hal_data; + for (uint32_t i = 0; i < SOC_ECB_KEY_LENGTH; i++) { ecb_hal_data.key[i] = p_k[SOC_ECB_KEY_LENGTH - 1 - i]; } + memset(ecb_hal_data.cleartext, 0, SOC_ECB_KEY_LENGTH - IM_ADDR_CLEARTEXT_LENGTH); for (uint32_t i = 0; i < IM_ADDR_CLEARTEXT_LENGTH; i++) @@ -704,7 +1063,8 @@ void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash) ecb_hal_data.cleartext[SOC_ECB_KEY_LENGTH - 1 - i] = p_r[i]; } - sd_ecb_block_encrypt(&ecb_hal_data); + // Can only return NRF_SUCCESS. + (void) sd_ecb_block_encrypt(&ecb_hal_data); for (uint32_t i = 0; i < IM_ADDR_CIPHERTEXT_LENGTH; i++) { @@ -715,16 +1075,21 @@ void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash) bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk) { + NRF_PM_DEBUG_CHECK(m_module_initialized); + + uint8_t hash[IM_ADDR_CIPHERTEXT_LENGTH]; + uint8_t local_hash[IM_ADDR_CIPHERTEXT_LENGTH]; + uint8_t prand[IM_ADDR_CLEARTEXT_LENGTH]; + if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE) { return false; } - uint8_t hash[IM_ADDR_CIPHERTEXT_LENGTH]; - uint8_t local_hash[IM_ADDR_CIPHERTEXT_LENGTH]; - uint8_t prand[IM_ADDR_CLEARTEXT_LENGTH]; + memcpy(hash, p_addr->addr, IM_ADDR_CIPHERTEXT_LENGTH); memcpy(prand, &p_addr->addr[IM_ADDR_CIPHERTEXT_LENGTH], IM_ADDR_CLEARTEXT_LENGTH); ah(p_irk->irk, prand, local_hash); return (memcmp(hash, local_hash, IM_ADDR_CIPHERTEXT_LENGTH) == 0); } +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/id_manager.h b/components/ble/peer_manager/id_manager.h index fdb7eea..eb76508 100644 --- a/components/ble/peer_manager/id_manager.h +++ b/components/ble/peer_manager/id_manager.h @@ -1,25 +1,60 @@ -/* Copyright (C) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 PEER_ID_MANAGER_H__ #define PEER_ID_MANAGER_H__ -#include "stdint.h" +#include #include "sdk_errors.h" #include "ble.h" #include "ble_gap.h" #include "peer_manager_types.h" +#ifdef __cplusplus +extern "C" { +#endif + /** + * @cond NO_DOXYGEN * @defgroup id_manager ID Manager * @ingroup peer_manager * @{ @@ -58,17 +93,13 @@ typedef struct */ typedef void (*im_evt_handler_t)(im_evt_t const * p_event); -/**@brief Function for registering for events from the ID Manager module. - * - * @note This will also initialize the module if needed. - * - * @param[in] evt_handler Callback for events from the ID Manager module. + +/**@brief Function for initializing the Identity manager. * - * @retval NRF_SUCCESS Registration was successful. - * @retval NRF_ERROR_NO_MEM No more registrations possible. - * @retval NRF_ERROR_NULL evt_handler was NULL. + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INTERNAL If an error occurred. */ -ret_code_t im_register(im_evt_handler_t evt_handler); +ret_code_t im_init(void); /**@brief Function for dispatching SoftDevice events to the ID Manager module. @@ -96,16 +127,6 @@ pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle); pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t * p_master_id); -/**@brief Function for getting the corresponding peer ID from an IRK match index, see @ref - * ble_gap_evt_connected_t. - * - * @param[in] irk_match_idx The IRK match index. - * - * @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved. - */ -pm_peer_id_t im_peer_id_get_by_irk_match_idx(uint8_t irk_match_idx); - - /**@brief Function for getting the corresponding connection handle from a peer ID. * * @param[in] peer_id The peer ID. @@ -116,6 +137,18 @@ pm_peer_id_t im_peer_id_get_by_irk_match_idx(uint8_t irk_match_idx); uint16_t im_conn_handle_get(pm_peer_id_t peer_id); +/**@brief Function for comparing two master ids + * @note Two invalid master IDs will not match. + * + * @param[in] p_master_id1 First master id for comparison + * @param[in] p_master_id2 Second master id for comparison + * + * @return True if the input matches, false if it does not. + */ +bool im_master_ids_compare(ble_gap_master_id_t const * p_master_id1, + ble_gap_master_id_t const * p_master_id2); + + /**@brief Function for getting the BLE address used by the peer when connecting. * * @param[in] conn_handle The connection handle. @@ -140,6 +173,10 @@ ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr); bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id); +bool im_is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1, + pm_peer_data_bonding_t const * p_bonding_data2); + + /**@brief Function for reporting that a new peer ID has been allocated for a specified connection. * * @param[in] conn_handle The connection. @@ -148,51 +185,88 @@ bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id); void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id); -/** - * @brief Function for informing this module of what whitelist will be used. +/**@brief Function for deleting all of a peer's data from flash and disassociating it from any + * connection handles it is associated with. * - * @details This function is meant to be used when the app wants to use a custom whitelist. - * When using peer manager, this function must be used if a custom whitelist is used. + * @param[in] peer_id The peer to free. * - * @note When using a whitelist, always use the whitelist created/set by the most recent - * call to @ref im_wlist_create or to this function, whichever happened most recently. - * @note Do not call this function while scanning with another whitelist. - * @note Do not add any irks to the whitelist that are not present in the bonding data of a peer in - * the peer database. + * @return Any error code returned by @ref pdb_peer_free. + */ +ret_code_t im_peer_free(pm_peer_id_t peer_id); + + +/**@brief Function to set the local Bluetooth identity address. + * + * @details The local Bluetooth identity address is the address that identifies this device to other + * peers. The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref + * BLE_GAP_ADDR_TYPE_RANDOM_STATIC. The identity address cannot be changed while roles are + * running. + * + * @note This address will be distributed to the peer during bonding. + * If the address changes, the address stored in the peer device will not be valid and the + * ability to reconnect using the old address will be lost. * - * @param[in] p_whitelist The whitelist. + * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC + * upon being enabled. The address is a random number populated during the IC manufacturing + * process and remains unchanged for the lifetime of each IC. * - * @retval NRF_SUCCESS Whitelist successfully set. - * @retval NRF_ERROR_NULL p_whitelist was NULL. - * @retval NRF_ERROR_NOT_FOUND One or more of the whitelists irks was not found in the peer_database. + * @param[in] p_addr Pointer to address structure. + * + * @retval NRF_SUCCESS Address successfully set. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If the GAP address is invalid. + * @retval NRF_ERROR_BUSY Could not process at this time. Process SoftDevice events + * and retry. + * @retval NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising, + * scanning, or while in a connection. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. */ -ret_code_t im_wlist_set(ble_gap_whitelist_t * p_whitelist); +ret_code_t im_id_addr_set(ble_gap_addr_t const * p_addr); -/** - * @brief Function for constructing a whitelist for use when advertising. +/**@brief Function to get the local Bluetooth identity address. * - * @note When advertising with whitelist, always use the whitelist created/set by the most recent - * call to this function or to @ref im_wlist_set, whichever happened most recently. - * @note Do not call this function while advertising with another whitelist. + * @note This will always return the identity address irrespective of the privacy settings, + * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref + * BLE_GAP_ADDR_TYPE_RANDOM_STATIC. * - * @param[in] p_peer_ids The ids of the peers to be added to the whitelist. - * @param[in] n_peer_ids The number of peer ids in p_peer_ids. - * @param[in,out] p_whitelist The constructed whitelist. Note that p_adv_whitelist->pp_addrs - * must be NULL or point to an array with size @ref - * BLE_GAP_WHITELIST_ADDR_MAX_COUNT and p_adv_whitelist->pp_irks - * must be NULL or point to an array with size @ref - * BLE_GAP_WHITELIST_IRK_MAX_COUNT. + * @param[out] p_addr Pointer to address structure to be filled in. * - * @retval NRF_SUCCESS Whitelist successfully created. - * @retval NRF_ERROR_NULL p_whitelist was NULL. + * @retval NRF_SUCCESS If the address was successfully retrieved. */ -ret_code_t im_wlist_create(pm_peer_id_t * p_peer_ids, - uint8_t n_peer_ids, - ble_gap_whitelist_t * p_whitelist); +ret_code_t im_id_addr_get(ble_gap_addr_t * p_addr); -/** - * @brief Function for resolving a resolvable address with an identity resolution key (IRK). + +/**@brief Function to set privacy settings. + * + * @details Privacy settings cannot be set while advertising, scanning, or while in a connection. + * + * @param[in] p_privacy_params Privacy settings. + * + * @retval NRF_SUCCESS If privacy options were set successfully. + * @retval NRF_ERROR_NULL If @p p_privacy_params is NULL. + * @retval NRF_ERROR_INVALID_PARAM If the address type is not valid. + * @retval NRF_ERROR_BUSY If the request could not be processed at this time. + * Process SoftDevice events and retry. + * @retval NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while BLE roles using + * privacy are enabled. + */ +ret_code_t im_privacy_set(pm_privacy_params_t const * p_privacy_params); + + +/**@brief Function to retrieve the current privacy settings. + * + * @details The privacy settings returned include the current device irk as well. + * + * @param[in] p_privacy_params Privacy settings. + * + * @retval NRF_SUCCESS Successfully retrieved privacy settings. + * @retval NRF_ERROR_NULL @c p_privacy_params is NULL. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t im_privacy_get(pm_privacy_params_t * p_privacy_params); + + +/**@brief Function for resolving a resolvable address with an identity resolution key (IRK). * * @details This function will use the ECB peripheral to resolve a resolvable address. * This can be used to resolve the identity of a device distributing a random @@ -208,6 +282,60 @@ ret_code_t im_wlist_create(pm_peer_id_t * p_peer_ids, */ bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk); -/** @} */ + +/**@brief Function for setting / clearing the whitelist. + * + * @param p_peers The peers to whitelist. Pass NULL to clear the whitelist. + * @param peer_cnt The number of peers to whitelist. Pass zero to clear the whitelist. + * + * @retval NRF_SUCCESS If the whitelist was successfully set or cleared. + * @retval BLE_GAP_ERROR_WHITELIST_IN_USE If a whitelist is in use. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If any peer has an address which can not be used + * for whitelisting. + * @retval NRF_ERROR_NOT_FOUND If any peer or its data could not be found. + * @retval NRF_ERROR_DATA_SIZE If @p peer_cnt is greater than + * @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + */ +ret_code_t im_whitelist_set(pm_peer_id_t const * p_peers, + uint32_t const peer_cnt); + + +/**@brief Retrieves the current whitelist, set by a previous call to @ref im_whitelist_set. + * + * @param[out] A buffer where to copy the GAP addresses. + * @param[inout] In: the size of the @p p_addrs buffer. + * Out: the number of address copied into the buffer. + * @param[out] A buffer where to copy the IRKs. + * @param[inout] In: the size of the @p p_irks buffer. + * Out: the number of IRKs copied into the buffer. + * + * @retval NRF_SUCCESS If the whitelist was successfully retreived. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If any peer has an address which can not be used for + * whitelisting. + * @retval NRF_ERROR_NOT_FOUND If the data for any of the cached whitelisted peers + * can not be found anymore. It might have been deleted in + * the meanwhile. + * @retval NRF_ERROR_NO_MEM If the provided buffers are too small. + */ +ret_code_t im_whitelist_get(ble_gap_addr_t * p_addrs, + uint32_t * p_addr_cnt, + ble_gap_irk_t * p_irks, + uint32_t * p_irk_cnt); + + +/**@brief Set the device identities list. + */ +ret_code_t im_device_identities_list_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt); + + +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif #endif /* PEER_ID_MANAGER_H__ */ diff --git a/components/ble/peer_manager/peer_data.c b/components/ble/peer_manager/peer_data.c index b145898..de8a6bf 100644 --- a/components/ble/peer_manager/peer_data.c +++ b/components/ble/peer_manager/peer_data.c @@ -1,24 +1,51 @@ -/* Copyright (C) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "peer_data.h" -#include -#include #include "peer_manager_types.h" #include "fds.h" - void peer_data_parts_get(pm_peer_data_const_t const * p_peer_data, fds_record_chunk_t * p_chunks, uint16_t * p_n_chunks) { if (p_n_chunks == NULL) @@ -30,116 +57,36 @@ void peer_data_parts_get(pm_peer_data_const_t const * p_peer_data, fds_record_ch } else { - switch (p_peer_data->data_type) - { - case PM_PEER_DATA_ID_BONDING: - p_chunks[0].p_data = p_peer_data->data.p_bonding_data; - p_chunks[0].length_words = p_peer_data->length_words; - *p_n_chunks = 1; - break; - case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING: - p_chunks[0].p_data = p_peer_data->data.p_service_changed_pending; - p_chunks[0].length_words = p_peer_data->length_words; - *p_n_chunks = 1; - break; - case PM_PEER_DATA_ID_GATT_LOCAL: - p_chunks[0].p_data = p_peer_data->data.p_local_gatt_db; - p_chunks[0].length_words = PM_N_WORDS(PM_LOCAL_DB_LEN_OVERHEAD_BYTES); - p_chunks[1].p_data = p_peer_data->data.p_local_gatt_db->p_data; - p_chunks[1].length_words = p_peer_data->length_words - p_chunks[0].length_words; - *p_n_chunks = 2; - break; - case PM_PEER_DATA_ID_GATT_REMOTE: - p_chunks[0].p_data = p_peer_data->data.p_remote_gatt_db; - p_chunks[0].length_words = PM_N_WORDS(PM_REMOTE_DB_LEN_OVERHEAD_BYTES); - p_chunks[1].p_data = p_peer_data->data.p_remote_gatt_db->p_data; - p_chunks[1].length_words = p_peer_data->length_words - p_chunks[0].length_words; - *p_n_chunks = 2; - break; - case PM_PEER_DATA_ID_APPLICATION: - p_chunks[0].p_data = p_peer_data->data.p_application_data; - p_chunks[0].length_words = p_peer_data->length_words; - *p_n_chunks = 1; - break; - default: - *p_n_chunks = 0; - break; - } + p_chunks[0].p_data = p_peer_data->p_all_data; + p_chunks[0].length_words = p_peer_data->length_words; + *p_n_chunks = 1; } } ret_code_t peer_data_deserialize(pm_peer_data_flash_t const * p_in_data, pm_peer_data_t * p_out_data) { + ret_code_t err_code = NRF_SUCCESS; + if ((p_in_data == NULL) || (p_out_data == NULL)) { - return NRF_ERROR_NULL; + err_code = NRF_ERROR_NULL; } else { if (p_out_data->length_words < p_in_data->length_words) { p_out_data->length_words = p_in_data->length_words; - return NRF_ERROR_NO_MEM; + err_code = NRF_ERROR_NO_MEM; } - p_out_data->length_words = p_in_data->length_words; - p_out_data->data_type = p_in_data->data_type; - - switch (p_in_data->data_type) + else { - case PM_PEER_DATA_ID_BONDING: - *p_out_data->data.p_bonding_data = *p_in_data->data.p_bonding_data; - break; - case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING: - *p_out_data->data.p_service_changed_pending = *p_in_data->data.p_service_changed_pending; - break; - case PM_PEER_DATA_ID_GATT_LOCAL: - if (p_out_data->data.p_local_gatt_db->p_data == NULL) - { - return NRF_ERROR_NULL; - } - if (p_out_data->data.p_local_gatt_db->len < p_in_data->data.p_local_gatt_db->len) - { - p_out_data->data.p_local_gatt_db->len = p_in_data->data.p_local_gatt_db->len; - return NRF_ERROR_NO_MEM; - } - else - { - p_out_data->data.p_local_gatt_db->flags = p_in_data->data.p_local_gatt_db->flags; - p_out_data->data.p_local_gatt_db->len = p_in_data->data.p_local_gatt_db->len; - memcpy(p_out_data->data.p_local_gatt_db->p_data, - p_in_data->data.p_local_gatt_db->p_data, - p_in_data->data.p_local_gatt_db->len); - } - break; - case PM_PEER_DATA_ID_GATT_REMOTE: - if (p_out_data->data.p_remote_gatt_db->p_data == NULL) - { - return NRF_ERROR_NULL; - } - if (p_out_data->data.p_remote_gatt_db->service_count < p_in_data->data.p_remote_gatt_db->service_count) - { - p_out_data->data.p_remote_gatt_db->service_count = p_in_data->data.p_remote_gatt_db->service_count; - return NRF_ERROR_NO_MEM; - } - else - { - p_out_data->data.p_remote_gatt_db->service_count = p_in_data->data.p_remote_gatt_db->service_count; - memcpy(p_out_data->data.p_remote_gatt_db->p_data, - p_in_data->data.p_remote_gatt_db->p_data, - p_in_data->data.p_remote_gatt_db->service_count * sizeof(ble_gatt_db_srv_t)); - } - break; - case PM_PEER_DATA_ID_APPLICATION: - memcpy(p_out_data->data.p_application_data, - p_in_data->data.p_application_data, - p_in_data->length_words * 4); - break; - default: - break; + p_out_data->length_words = p_in_data->length_words; + p_out_data->data_id = p_in_data->data_id; + + memcpy(p_out_data->p_all_data, p_in_data->p_all_data, p_in_data->length_words * 4); } } - return NRF_SUCCESS; + return err_code; } - - +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/peer_data.h b/components/ble/peer_manager/peer_data.h index a69b454..86760a6 100644 --- a/components/ble/peer_manager/peer_data.h +++ b/components/ble/peer_manager/peer_data.h @@ -1,14 +1,42 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 PEER_DATA_H__ @@ -16,10 +44,16 @@ #include #include "peer_manager_types.h" +#include "peer_manager_internal.h" #include "fds.h" +#ifdef __cplusplus +extern "C" { +#endif + /** + * @cond NO_DOXYGEN * @defgroup peer_data Peer Data * @ingroup peer_manager * @{ @@ -48,6 +82,13 @@ void peer_data_parts_get(pm_peer_data_const_t const * p_peer_data, fds_record_ch */ ret_code_t peer_data_deserialize(pm_peer_data_flash_t const * p_in_data, pm_peer_data_t * p_out_data); -/** @} */ +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif #endif /* PEER_DATA_H__ */ diff --git a/components/ble/peer_manager/peer_data_storage.c b/components/ble/peer_manager/peer_data_storage.c index b480fbf..337c737 100644 --- a/components/ble/peer_manager/peer_data_storage.c +++ b/components/ble/peer_manager/peer_data_storage.c @@ -1,669 +1,693 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ - +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "peer_data_storage.h" #include #include #include "sdk_errors.h" #include "peer_manager_types.h" +#include "peer_manager_internal.h" #include "peer_id.h" #include "peer_data.h" #include "fds.h" -#include "nrf_log.h" -#define MAX_REGISTRANTS 6 /**< The number of user that can register with the module. */ -#define MODULE_INITIALIZED (m_pds.n_registrants > 0) /**< Expression which is true when the module is initialized. */ +// Macro for verifying that the peer id is within a valid range. +#define VERIFY_PEER_ID_IN_RANGE(id) VERIFY_FALSE((id >= PM_PEER_ID_N_AVAILABLE_IDS), \ + NRF_ERROR_INVALID_PARAM) -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * @ref NRF_ERROR_INVALID_STATE if not. - */ -#define VERIFY_MODULE_INITIALIZED() \ -do \ -{ \ - if (!MODULE_INITIALIZED) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * if not. - */ -#define VERIFY_MODULE_INITIALIZED_VOID() \ -do \ -{ \ - if (!MODULE_INITIALIZED) \ - { \ - return; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the param is not NULL. It will cause the function to return - * if not. - * - * @param[in] param The variable to check if is NULL. - */ -#define VERIFY_PARAM_NOT_NULL(param) \ -do \ -{ \ - if (param == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } \ -} while(0) - - -/**@brief Macro for verifying that param is not zero. It will cause the function to return - * if not. - * - * @param[in] param The variable to check if is zero. - */ -#define VERIFY_PARAM_NOT_ZERO(param) \ -do \ -{ \ - if (param == 0) \ - { \ - return NRF_ERROR_NULL; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the peer id is within a valid range - * - * @param[in] id The peer data id to check. - */ -#define VERIFY_PEER_ID_IN_RANGE(id) \ -do \ -{ \ - if ((id >= PM_PEER_ID_N_AVAILABLE_IDS)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } \ -} while (0) - - -/**@brief Macro for verifying that the peer data id is withing a valid range - * - * @param[in] id The peer data id to check. - */ -#define VERIFY_PEER_DATA_ID_IN_RANGE(id) \ -do \ -{ \ - if (!PM_PEER_DATA_ID_IS_VALID(id)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } \ -} while (0) - - -#define PEER_IDS_INITIALIZE() \ -do \ -{ \ - if (!m_pds.peer_ids_initialized) \ - { \ - peer_ids_init(); \ - } \ -} while (0) - - -typedef struct -{ - bool peer_ids_initialized; - pds_evt_handler_t evt_handlers[MAX_REGISTRANTS]; - uint8_t n_registrants; -} pds_t; +// Macro for verifying that the peer data id is withing a valid range. +#define VERIFY_PEER_DATA_ID_IN_RANGE(id) VERIFY_TRUE(peer_data_id_is_valid(id), \ + NRF_ERROR_INVALID_PARAM) -static pds_t m_pds = {.n_registrants = 0}; +// The number of registered event handlers. +#define PDS_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) -static void internal_state_reset(pds_t * p_pds) + +// Peer Data Storage event handler in Peer Database. +extern void pdb_pds_evt_handler(pds_evt_t const *); + +// Peer Data Storage events' handlers. +// The number of elements in this array is PDS_EVENT_HANDLERS_CNT. +static pds_evt_handler_t const m_evt_handlers[] = { - memset(p_pds, 0, sizeof(pds_t)); -} + pdb_pds_evt_handler, +}; -/**@brief Function for dispatching outbound events to all registered event handlers. - * - * @param[in] p_event The event to dispatch. - */ +static bool m_module_initialized = false; +static bool m_peer_delete_queued = false; +static bool m_peer_delete_ongoing = false; + +// A token used for Flash Data Storage searches. +static fds_find_token_t m_fds_ftok; + + +// Function for dispatching events to all registered event handlers. static void pds_evt_send(pds_evt_t * p_event) { - for (int i = 0; i < m_pds.n_registrants; i++) + for (uint32_t i = 0; i < PDS_EVENT_HANDLERS_CNT; i++) { - m_pds.evt_handlers[i](p_event); + m_evt_handlers[i](p_event); } } -/**@brief Function to convert peer id to instance id - * - * @param[in] peer_id Peer id to convert to instance id - * - * @return Value as instance id - */ -static fds_instance_id_t convert_peer_id_to_instance_id(pm_peer_id_t peer_id) + +// Function to convert peer IDs to file IDs. +static uint16_t peer_id_to_file_id(pm_peer_id_t peer_id) { - return (fds_instance_id_t)(peer_id + peer_id_to_instance_id); + return (uint16_t)(peer_id + PEER_ID_TO_FILE_ID); } -/**@brief Function to convert peer data id to type id - * - * @param[in] peer_data_id Peer data id to convert to type_id - * - * @return Value as type id - */ -static fds_type_id_t convert_peer_data_id_to_type_id(pm_peer_data_id_t peer_data_id) + +// Function to convert peer data id to type id. +static pm_peer_id_t file_id_to_peer_id(uint16_t file_id) { - return (fds_type_id_t)peer_data_id + (fds_type_id_t)peer_data_id_to_type_id; + return (pm_peer_id_t)(file_id + FILE_ID_TO_PEER_ID); } -/**@brief Function to convert peer data id to type id - * - * @param[in] peer_data_id Peer data id to convert to type_id - * - * @return Value as type id - */ -static pm_peer_id_t convert_instance_id_to_peer_id(fds_instance_id_t instance_id) +// Function to convert peer data IDs to record keys. +static uint16_t peer_data_id_to_record_key(pm_peer_data_id_t peer_data_id) { - return (pm_peer_id_t)(instance_id + instance_id_to_peer_id); + return (uint16_t)(peer_data_id + DATA_ID_TO_RECORD_KEY); } -/**@brief Function to type id to peer data id - * - * @param[in] type_id Type id to convert to peer data id - * - * @return Value as peer data id - */ -static pm_peer_data_id_t convert_type_id_to_peer_data_id(fds_type_id_t type_id) +// Function to convert record keys to peer data IDs. +static pm_peer_data_id_t record_key_to_peer_data_id(uint16_t record_key) { - return (pm_peer_data_id_t)(type_id + instance_id_to_peer_id); + return (pm_peer_data_id_t)(record_key + RECORD_KEY_TO_DATA_ID); } -static ret_code_t find_fds_item(pm_peer_id_t peer_id, - pm_peer_data_id_t data_id, - fds_record_desc_t * const p_desc) +// Function for checking whether a file ID is relevant for the Peer Manager. +static bool file_id_within_pm_range(uint16_t file_id) { - fds_find_token_t find_tok; + return ((PDS_FIRST_RESERVED_FILE_ID <= file_id) + && (file_id <= PDS_LAST_RESERVED_FILE_ID)); +} - VERIFY_PEER_ID_IN_RANGE(peer_id); - VERIFY_PEER_DATA_ID_IN_RANGE(data_id); - // pp_record verified outside - fds_type_id_t type_id = convert_peer_data_id_to_type_id(data_id); - fds_instance_id_t instance_id = convert_peer_id_to_instance_id(peer_id); +// Function for checking whether a record key is relevant for the Peer Manager. +static bool record_key_within_pm_range(uint16_t record_key) +{ + return ((PDS_FIRST_RESERVED_RECORD_KEY <= record_key) + && (record_key <= PDS_LAST_RESERVED_RECORD_KEY)); +} + - return fds_find(type_id, instance_id, p_desc, &find_tok); +static bool peer_data_id_is_valid(pm_peer_data_id_t data_id) +{ + return ((data_id == PM_PEER_DATA_ID_BONDING) || + (data_id == PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING) || + (data_id == PM_PEER_DATA_ID_GATT_LOCAL) || + (data_id == PM_PEER_DATA_ID_GATT_REMOTE) || + (data_id == PM_PEER_DATA_ID_PEER_RANK) || + (data_id == PM_PEER_DATA_ID_APPLICATION)); } -static void peer_ids_init() +// Function for deleting all data beloning to a peer. +// These operations will be sent to FDS one at a time. +static void peer_data_delete() { - fds_record_t record; - fds_record_desc_t record_desc; - fds_find_token_t find_tok; - fds_type_id_t const type_id = convert_peer_data_id_to_type_id(PM_PEER_DATA_ID_BONDING); - pm_peer_id_t peer_id; + ret_code_t ret; + pm_peer_id_t peer_id; + uint16_t file_id; + fds_record_desc_t desc; + fds_find_token_t ftok; + + memset(&ftok, 0x00, sizeof(fds_find_token_t)); + peer_id = peer_id_get_next_deleted(PM_PEER_ID_INVALID); + + while ( (peer_id != PM_PEER_ID_INVALID) + && (fds_record_find_in_file(peer_id_to_file_id(peer_id), &desc, &ftok) + == FDS_ERR_NOT_FOUND)) + { + peer_id_free(peer_id); + peer_id = peer_id_get_next_deleted(peer_id); + } - if (!m_pds.peer_ids_initialized) + if (!m_peer_delete_ongoing && (peer_id != PM_PEER_ID_INVALID)) { - while(fds_find_by_type(type_id, &record_desc, &find_tok) == NRF_SUCCESS) + m_peer_delete_ongoing = true; + + file_id = peer_id_to_file_id(peer_id); + ret = fds_file_delete(file_id); + + if (ret == FDS_ERR_NO_SPACE_IN_QUEUES) { - fds_open(&record_desc, &record); - fds_close(&record_desc); - peer_id = convert_instance_id_to_peer_id(record.header.ic.instance); - peer_id_allocate(peer_id); + m_peer_delete_queued = true; } + else if (ret != NRF_SUCCESS) + { + m_peer_delete_ongoing = false; + + pds_evt_t pds_evt; - m_pds.peer_ids_initialized = true; + pds_evt.evt_id = PDS_EVT_ERROR_UNEXPECTED; + pds_evt.peer_id = peer_id; + pds_evt.data_id = PM_PEER_DATA_ID_INVALID; + pds_evt.store_token = PM_STORE_TOKEN_INVALID; + pds_evt.result = ret; + + pds_evt_send(&pds_evt); + } } } -//uint32_t size_pad_to_mult_of_four(uint32_t unpadded_size) -//{ -// return (unpadded_size + 3) & 3; -//} -static void fds_evt_handler(ret_code_t result, - fds_cmd_id_t cmd, - fds_record_id_t record_id, - fds_record_key_t record_key - /*fds_record_t const * const p_record*/) +static ret_code_t peer_data_find(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + fds_record_desc_t * const p_desc) { - pds_evt_t evt; - switch(cmd) + ret_code_t ret; + fds_find_token_t ftok; + + NRF_PM_DEBUG_CHECK(peer_id < PM_PEER_ID_N_AVAILABLE_IDS); + NRF_PM_DEBUG_CHECK(peer_data_id_is_valid(data_id)); + NRF_PM_DEBUG_CHECK(p_desc != NULL); + + memset(&ftok, 0x00, sizeof(fds_find_token_t)); + + uint16_t file_id = peer_id_to_file_id(peer_id); + uint16_t record_key = peer_data_id_to_record_key(data_id); + + ret = fds_record_find(file_id, record_key, p_desc, &ftok); + + if (ret != FDS_SUCCESS) { - case FDS_CMD_INIT: + return NRF_ERROR_NOT_FOUND; + } - break; + return NRF_SUCCESS; +} - case FDS_CMD_UPDATE: - case FDS_CMD_WRITE: - evt.peer_id = convert_instance_id_to_peer_id(record_key.instance); - evt.evt_id = (result == NRF_SUCCESS) ? PDS_EVT_STORED : PDS_EVT_ERROR_STORE; - evt.data_id = convert_type_id_to_peer_data_id(record_key.type); - evt.store_token = record_id; - pds_evt_send(&evt); + +static void peer_ids_load() +{ + fds_record_desc_t record_desc; + fds_flash_record_t record; + fds_find_token_t ftok; + + memset(&ftok, 0x00, sizeof(fds_find_token_t)); + + uint16_t const record_key = peer_data_id_to_record_key(PM_PEER_DATA_ID_BONDING); + + while (fds_record_find_by_key(record_key, &record_desc, &ftok) == FDS_SUCCESS) + { + pm_peer_id_t peer_id; + + // It is safe to ignore the return value since the descriptor was + // just obtained and also 'record' is different from NULL. + (void)fds_record_open(&record_desc, &record); + peer_id = file_id_to_peer_id(record.p_header->ic.file_id); + (void)fds_record_close(&record_desc); + + (void)peer_id_allocate(peer_id); + } +} + + +static void fds_evt_handler(fds_evt_t const * const p_fds_evt) +{ + pds_evt_t pds_evt; + + pds_evt.result = (p_fds_evt->result == FDS_SUCCESS); + + switch (p_fds_evt->id) + { + case FDS_EVT_WRITE: + case FDS_EVT_UPDATE: + if ( file_id_within_pm_range(p_fds_evt->write.file_id) + || record_key_within_pm_range(p_fds_evt->write.record_key)) + { + pds_evt.peer_id = file_id_to_peer_id(p_fds_evt->write.file_id); + pds_evt.data_id = record_key_to_peer_data_id(p_fds_evt->write.record_key); + + if (p_fds_evt->id == FDS_EVT_WRITE) + { + pds_evt.evt_id = (p_fds_evt->result == FDS_SUCCESS) ? PDS_EVT_STORED : + PDS_EVT_ERROR_STORE; + } + else + { + pds_evt.evt_id = (p_fds_evt->result == FDS_SUCCESS) ? PDS_EVT_UPDATED : + PDS_EVT_ERROR_UPDATE; + } + + pds_evt.result = p_fds_evt->result; + pds_evt.store_token = p_fds_evt->write.record_id; + + pds_evt_send(&pds_evt); + } break; - case FDS_CMD_CLEAR: - evt.peer_id = convert_instance_id_to_peer_id(record_key.instance); - evt.evt_id = (result == NRF_SUCCESS) ? PDS_EVT_CLEARED : PDS_EVT_ERROR_CLEAR; - evt.data_id = convert_type_id_to_peer_data_id(record_key.type); - evt.store_token = record_id; - pds_evt_send(&evt); + case FDS_EVT_DEL_RECORD: + if ( file_id_within_pm_range(p_fds_evt->del.file_id) + || record_key_within_pm_range(p_fds_evt->del.record_key)) + { + pds_evt.peer_id = file_id_to_peer_id(p_fds_evt->del.file_id); + pds_evt.data_id = record_key_to_peer_data_id(p_fds_evt->del.record_key); + + pds_evt.evt_id = (p_fds_evt->result == FDS_SUCCESS) ? PDS_EVT_CLEARED : + PDS_EVT_ERROR_CLEAR; + + pds_evt.store_token = p_fds_evt->del.record_id; + + pds_evt_send(&pds_evt); + } break; - case FDS_CMD_CLEAR_INST: + case FDS_EVT_DEL_FILE: { - if ((record_key.type == FDS_TYPE_ID_INVALID) && - (record_key.instance != FDS_TYPE_ID_INVALID)) + if ( file_id_within_pm_range(p_fds_evt->del.file_id) + && (p_fds_evt->del.record_key == FDS_RECORD_KEY_DIRTY)) { - pm_peer_id_t peer_id = convert_instance_id_to_peer_id(record_key.instance); + pds_evt.peer_id = file_id_to_peer_id(p_fds_evt->del.file_id); + pds_evt.data_id = record_key_to_peer_data_id(p_fds_evt->del.record_key); - evt.peer_id = peer_id; - evt.data_id = PM_PEER_DATA_ID_INVALID; - if (result == NRF_SUCCESS) + pds_evt.data_id = PM_PEER_DATA_ID_INVALID; + if (p_fds_evt->result == FDS_SUCCESS) { - evt.evt_id = PDS_EVT_PEER_ID_CLEAR; - peer_id_free(peer_id); + pds_evt.evt_id = PDS_EVT_PEER_ID_CLEAR; + peer_id_free(pds_evt.peer_id); } else { - evt.evt_id = PDS_EVT_ERROR_PEER_ID_CLEAR; + pds_evt.evt_id = PDS_EVT_ERROR_PEER_ID_CLEAR; } - } - else - { - // TODO: Not supported yet (clear many without clearing peer_id) - } - pds_evt_send(&evt); + m_peer_delete_queued = false; + m_peer_delete_ongoing = false; + + peer_data_delete(); + + pds_evt_send(&pds_evt); + } } break; - case FDS_CMD_GC: - evt.peer_id = convert_instance_id_to_peer_id(record_key.instance); - evt.evt_id = PDS_EVT_COMPRESSED; - evt.data_id = convert_type_id_to_peer_data_id(record_key.type); - evt.store_token = record_id; - pds_evt_send(&evt); + case FDS_EVT_GC: + pds_evt.evt_id = PDS_EVT_COMPRESSED; + pds_evt_send(&pds_evt); break; default: - break; } + + if (m_peer_delete_queued) + { + m_peer_delete_queued = false; + peer_data_delete(); + } } -ret_code_t pds_register(pds_evt_handler_t evt_handler) +ret_code_t pds_init() { - if (m_pds.n_registrants >= MAX_REGISTRANTS) - { - return NRF_ERROR_NO_MEM; - } + ret_code_t ret; - VERIFY_PARAM_NOT_NULL(evt_handler); + // Check for re-initialization if debugging. + NRF_PM_DEBUG_CHECK(!m_module_initialized); - if (!MODULE_INITIALIZED) + ret = fds_register(fds_evt_handler); + if (ret != NRF_SUCCESS) { - ret_code_t retval; - internal_state_reset(&m_pds); - peer_id_init(); - - fds_cb_t cb = fds_evt_handler; - retval = fds_register(cb); - if(retval != NRF_SUCCESS) - { - return retval; - } + return NRF_ERROR_INTERNAL; + } - retval = fds_init(); - if(retval != NRF_SUCCESS) - { - return retval; - } + ret = fds_init(); + if (ret != NRF_SUCCESS) + { + return NRF_ERROR_STORAGE_FULL; } - m_pds.evt_handlers[m_pds.n_registrants] = evt_handler; - m_pds.n_registrants += 1; + peer_id_init(); + peer_ids_load(); - return NRF_SUCCESS; + m_module_initialized = true; + return NRF_SUCCESS; } -ret_code_t pds_peer_data_read_ptr_get(pm_peer_id_t peer_id, - pm_peer_data_id_t data_id, - pm_peer_data_flash_t * p_data, - pm_store_token_t * p_token) +ret_code_t pds_peer_data_read(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_t * const p_data, + uint32_t const * const p_buf_len) { - ret_code_t retval; + ret_code_t ret; + fds_record_desc_t rec_desc; + fds_flash_record_t rec_flash; - fds_record_t record; - fds_record_desc_t record_desc; + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_data != NULL); - VERIFY_MODULE_INITIALIZED(); VERIFY_PEER_ID_IN_RANGE(peer_id); VERIFY_PEER_DATA_ID_IN_RANGE(data_id); - retval = find_fds_item(peer_id, data_id, &record_desc); - if (retval != NRF_SUCCESS) + ret = peer_data_find(peer_id, data_id, &rec_desc); + + if (ret != NRF_SUCCESS) { - return retval; + return NRF_ERROR_NOT_FOUND; } - // Shouldn't fail, unless record is cleared. - fds_open(&record_desc, &record); - // No need to keep it open, since we are not reading. - fds_close(&record_desc); + // Shouldn't fail, unless the record was deleted in the meanwhile or the CRC check has failed. + ret = fds_record_open(&rec_desc, &rec_flash); - //NRF_LOG_PRINTF("Found item with peer_id: %d, data_id: %d, Address: %p\r\n", record.p_data); + if (ret != NRF_SUCCESS) + { + return NRF_ERROR_NOT_FOUND; + } - if (p_data != NULL) + // @note emdi: could this actually be set by the caller and used instead + // of an additional parameter (data_id) ? + p_data->data_id = data_id; + p_data->length_words = rec_flash.p_header->tl.length_words; + + // If p_buf_len is NULL, provide a pointer to data in flash, otherwise, + // check that the buffer is large enough and copy the data in flash into the buffer. + if (p_buf_len != NULL) { - p_data->data_type = data_id; - p_data->length_words = record.header.tl.length_words; + uint32_t const data_len_bytes = (p_data->length_words * sizeof(uint32_t)); - p_data->data.p_application_data = (uint8_t const*)record.p_data; + if ((*p_buf_len) <= data_len_bytes) + { + memcpy(p_data->p_all_data, rec_flash.p_data, data_len_bytes); + } + else + { + return NRF_ERROR_NO_MEM; + } } - - if (p_token != NULL) + else { - *p_token = (uint32_t)record.header.id; + // The cast is necessary because if no buffer is provided, we just copy the pointer, + // but it that case it should be considered a pointer to const data by the caller, + // since it is a pointer to data in flash. + p_data->p_all_data = (void*)rec_flash.p_data; } - return retval; -} - - -ret_code_t pds_peer_data_lock(pm_store_token_t store_token) -{ - VERIFY_MODULE_INITIALIZED(); - VERIFY_PARAM_NOT_ZERO(store_token); - - // TODO: Not implemented yet in fds + // Shouldn't fail unless the record was already closed, in which case it can be ignored. + (void)fds_record_close(&rec_desc); return NRF_SUCCESS; } -ret_code_t pds_peer_data_verify(pm_store_token_t store_token) +void pds_peer_data_iterate_prepare(void) { - VERIFY_MODULE_INITIALIZED(); - VERIFY_PARAM_NOT_ZERO(store_token); - - // TODO: Not implemented yet in fds - - return NRF_SUCCESS; + memset(&m_fds_ftok, 0x00, sizeof(fds_find_token_t)); } -ret_code_t pds_peer_data_read(pm_peer_id_t peer_id, - pm_peer_data_id_t data_id, - pm_peer_data_t * p_data, - fds_length_t * p_len_words) +bool pds_peer_data_iterate(pm_peer_data_id_t data_id, + pm_peer_id_t * const p_peer_id, + pm_peer_data_flash_t * const p_data) { - VERIFY_PEER_ID_IN_RANGE(peer_id); - VERIFY_PEER_DATA_ID_IN_RANGE(data_id); - VERIFY_PARAM_NOT_NULL(p_len_words); - VERIFY_PARAM_NOT_NULL(p_data); + ret_code_t ret; + uint16_t rec_key; + fds_record_desc_t rec_desc; + fds_flash_record_t rec_flash; - ret_code_t err_code; - pm_peer_data_flash_t peer_data_flash; + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_peer_id != NULL); + NRF_PM_DEBUG_CHECK(p_data != NULL); - err_code = pds_peer_data_read_ptr_get(peer_id, data_id, &peer_data_flash, NULL); + // @note emdi: should we check the data_id ? + rec_key = peer_data_id_to_record_key(data_id); - if (err_code != NRF_SUCCESS) + if (fds_record_find_by_key(rec_key, &rec_desc, &m_fds_ftok) != NRF_SUCCESS) { - return err_code; + return false; } - if ((*p_len_words) == 0) - { - (*p_len_words) = peer_data_flash.length_words; - return NRF_SUCCESS; - } - else if ((*p_len_words) < peer_data_flash.length_words) + ret = fds_record_open(&rec_desc, &rec_flash); + + if (ret != NRF_SUCCESS) { - return NRF_ERROR_NO_MEM; + // It can only happen if the record was deleted after the call to fds_record_find_by_key(), + // before we could open it, or if CRC support was enabled in Flash Data Storage at compile + // time and the CRC check failed. + return false; } - VERIFY_PARAM_NOT_NULL(p_data->data.p_application_data); + p_data->data_id = data_id; + p_data->length_words = rec_flash.p_header->tl.length_words; + p_data->p_all_data = rec_flash.p_data; + + *p_peer_id = file_id_to_peer_id(rec_flash.p_header->ic.file_id); - err_code = peer_data_deserialize(&peer_data_flash, p_data); + (void)fds_record_close(&rec_desc); - return err_code; + return true; } -ret_code_t pds_peer_data_write_prepare(pm_peer_data_const_t const * p_peer_data, - pm_prepare_token_t * p_prepare_token) +ret_code_t pds_space_reserve(pm_peer_data_const_t const * p_peer_data, + pm_prepare_token_t * p_prepare_token) { - ret_code_t retval; + ret_code_t ret; - VERIFY_MODULE_INITIALIZED(); - VERIFY_PARAM_NOT_NULL(p_peer_data); - VERIFY_PARAM_NOT_NULL(p_prepare_token); - VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type); + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_peer_data != NULL); + NRF_PM_DEBUG_CHECK(p_prepare_token != NULL); - retval = fds_reserve((fds_write_token_t*)p_prepare_token, p_peer_data->length_words); - return retval; -} + VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id); + ret = fds_reserve((fds_reserve_token_t*)p_prepare_token, p_peer_data->length_words); -ret_code_t pds_peer_data_write_prepare_cancel(pm_prepare_token_t prepare_token) -{ - ret_code_t retval; + switch (ret) + { + case FDS_SUCCESS: + return NRF_SUCCESS; + + case FDS_ERR_RECORD_TOO_LARGE: + return NRF_ERROR_INVALID_LENGTH; - VERIFY_MODULE_INITIALIZED(); - VERIFY_PARAM_NOT_ZERO(prepare_token); + case FDS_ERR_NO_SPACE_IN_FLASH: + return NRF_ERROR_STORAGE_FULL; - retval = fds_reserve_cancel((fds_write_token_t*)&prepare_token); - return retval; + default: + return NRF_ERROR_INTERNAL; + } } -ret_code_t pds_peer_data_write_prepared(pm_peer_id_t peer_id, - pm_peer_data_const_t const * p_peer_data, - pm_prepare_token_t prepare_token, - pm_store_token_t * p_store_token) +ret_code_t pds_space_reserve_cancel(pm_prepare_token_t prepare_token) { - ret_code_t retval; - fds_record_desc_t record_desc; - fds_record_key_t record_key; - fds_record_chunk_t chunks[2]; - uint16_t n_chunks; + ret_code_t ret; - VERIFY_MODULE_INITIALIZED(); - //VERIFY_PARAM_NOT_ZERO(prepare_token); - VERIFY_PARAM_NOT_NULL(p_peer_data); - VERIFY_PEER_ID_IN_RANGE(peer_id); - VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type); - - // Fill in the keys. - record_key.type = convert_peer_data_id_to_type_id(p_peer_data->data_type); - record_key.instance = convert_peer_id_to_instance_id(peer_id); - - // Create chunks. - peer_data_parts_get(p_peer_data, chunks, &n_chunks); + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(prepare_token != PDS_PREPARE_TOKEN_INVALID); - retval = fds_write_reserved((fds_write_token_t*)&prepare_token, &record_desc, - record_key, n_chunks, chunks); + ret = fds_reserve_cancel((fds_reserve_token_t*)&prepare_token); - if ((retval == NRF_SUCCESS) && (p_store_token != NULL)) + if (ret != FDS_SUCCESS) { - fds_record_id_from_desc(&record_desc, (fds_record_id_t*)p_store_token); + return NRF_ERROR_INTERNAL; } - return retval; + return NRF_SUCCESS; } -ret_code_t pds_peer_data_write(pm_peer_id_t peer_id, +ret_code_t pds_peer_data_store(pm_peer_id_t peer_id, pm_peer_data_const_t const * p_peer_data, + pm_prepare_token_t prepare_token, pm_store_token_t * p_store_token) { - ret_code_t retval; - fds_record_desc_t record_desc; - fds_record_key_t record_key; - fds_record_chunk_t chunks[2]; - uint16_t n_chunks; + ret_code_t ret; + fds_record_t rec; + fds_record_desc_t rec_desc; + fds_record_chunk_t rec_chunk; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_peer_data != NULL); - VERIFY_MODULE_INITIALIZED(); VERIFY_PEER_ID_IN_RANGE(peer_id); - VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type); + VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id); - // Fill in the keys. - record_key.type = convert_peer_data_id_to_type_id(p_peer_data->data_type); - record_key.instance = convert_peer_id_to_instance_id(peer_id); + // Prepare chunk. + rec_chunk.p_data = p_peer_data->p_all_data; + rec_chunk.length_words = p_peer_data->length_words; - // Create chunks - peer_data_parts_get(p_peer_data, chunks, &n_chunks); + // Prepare the record to be stored in flash. + rec.file_id = peer_id_to_file_id(peer_id); + rec.key = peer_data_id_to_record_key(p_peer_data->data_id); + rec.data.p_chunks = &rec_chunk; + rec.data.num_chunks = 1; - // Request write - retval = fds_write(&record_desc, record_key, n_chunks, chunks); + ret = peer_data_find(peer_id, p_peer_data->data_id, &rec_desc); - if ((retval == NRF_SUCCESS) && (p_store_token != NULL)) + if (ret == NRF_ERROR_NOT_FOUND) { - fds_record_id_from_desc(&record_desc, (fds_record_id_t*)p_store_token); + // No previous data exists in flash. + if (prepare_token == PDS_PREPARE_TOKEN_INVALID) + { + // No space was previously reserved. + ret = fds_record_write(&rec_desc, &rec); + } + else + { + // Space for this record was previously reserved. + ret = fds_record_write_reserved(&rec_desc, &rec, (fds_reserve_token_t*)&prepare_token); + } } + else // NRF_SUCCESS + { + if (prepare_token != PDS_PREPARE_TOKEN_INVALID) + { + (void)fds_reserve_cancel((fds_reserve_token_t*)&prepare_token); + } - return retval; -} - - -ret_code_t pds_peer_data_update(pm_peer_id_t peer_id, - pm_peer_data_const_t const * p_peer_data, - pm_store_token_t old_token, - pm_store_token_t * p_store_token) -{ - ret_code_t retval; - fds_record_desc_t record_desc; - fds_record_key_t record_key; - fds_record_chunk_t chunks[2]; - uint16_t n_chunks; - - VERIFY_MODULE_INITIALIZED(); - VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_type); - VERIFY_PARAM_NOT_NULL(p_peer_data); - - record_key.type = convert_peer_data_id_to_type_id(p_peer_data->data_type); - record_key.instance = convert_peer_id_to_instance_id(peer_id); + // Update existing record. + ret = fds_record_update(&rec_desc, &rec); + } - // Create chunks - peer_data_parts_get(p_peer_data, chunks, &n_chunks); + switch (ret) + { + case FDS_SUCCESS: + if (p_store_token != NULL) + { + // Update the store token. + (void)fds_record_id_from_desc(&rec_desc, (uint32_t*)p_store_token); + } + return NRF_SUCCESS; - fds_descriptor_from_rec_id(&record_desc, (fds_record_id_t)old_token); + case FDS_ERR_BUSY: + case FDS_ERR_NO_SPACE_IN_QUEUES: + return NRF_ERROR_BUSY; - retval = fds_update(&record_desc, record_key, n_chunks, chunks); + case FDS_ERR_NO_SPACE_IN_FLASH: + return NRF_ERROR_STORAGE_FULL; - if ((retval == NRF_SUCCESS) && (p_store_token != NULL)) - { - fds_record_id_from_desc(&record_desc, (fds_record_id_t*)p_store_token); + default: + return NRF_ERROR_INTERNAL; } - - return retval; } -ret_code_t pds_peer_data_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) + +// @note emdi: unused.. +ret_code_t pds_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) { - ret_code_t retval; - fds_type_id_t type_id; - fds_instance_id_t instance_id; + ret_code_t ret; fds_record_desc_t record_desc; - fds_find_token_t find_tok; - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); + VERIFY_PEER_ID_IN_RANGE(peer_id); VERIFY_PEER_DATA_ID_IN_RANGE(data_id); - type_id = convert_peer_data_id_to_type_id(data_id); - instance_id = convert_peer_id_to_instance_id(peer_id); + ret = peer_data_find(peer_id, data_id, &record_desc); - retval = fds_find(type_id, instance_id, &record_desc, &find_tok); - if(retval != NRF_SUCCESS) + if (ret != NRF_SUCCESS) { - return retval; + return NRF_ERROR_NOT_FOUND; } - retval = fds_clear(&record_desc); - return retval; + ret = fds_record_delete(&record_desc); + + switch (ret) + { + case FDS_SUCCESS: + return NRF_SUCCESS; + + case FDS_ERR_NO_SPACE_IN_QUEUES: + return NRF_ERROR_BUSY; + + default: + return NRF_ERROR_INTERNAL; + } } pm_peer_id_t pds_peer_id_allocate(void) { - if (!MODULE_INITIALIZED) - { - return PM_PEER_ID_INVALID; - } - PEER_IDS_INITIALIZE(); + NRF_PM_DEBUG_CHECK(m_module_initialized); return peer_id_allocate(PM_PEER_ID_INVALID); } ret_code_t pds_peer_id_free(pm_peer_id_t peer_id) { - ret_code_t retval; - fds_instance_id_t instance_id; - - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); VERIFY_PEER_ID_IN_RANGE(peer_id); - PEER_IDS_INITIALIZE(); - instance_id = convert_peer_id_to_instance_id(peer_id); + (void)peer_id_delete(peer_id); + peer_data_delete(); - retval = fds_clear_by_instance(instance_id); - return retval; + return NRF_SUCCESS; } bool pds_peer_id_is_allocated(pm_peer_id_t peer_id) { - if (!MODULE_INITIALIZED) - { - return false; - } - PEER_IDS_INITIALIZE(); - + NRF_PM_DEBUG_CHECK(m_module_initialized); return peer_id_is_allocated(peer_id); } pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id) { - if (!MODULE_INITIALIZED) - { - return PM_PEER_ID_INVALID; - } - PEER_IDS_INITIALIZE(); + NRF_PM_DEBUG_CHECK(m_module_initialized); + return peer_id_get_next_used(prev_peer_id); +} - return peer_id_next_id_get(prev_peer_id); + +pm_peer_id_t pds_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + return peer_id_get_next_deleted(prev_peer_id); } -uint32_t pds_n_peers(void) +uint32_t pds_peer_count_get(void) { - if (!MODULE_INITIALIZED) - { - return 0; - } - PEER_IDS_INITIALIZE(); + NRF_PM_DEBUG_CHECK(m_module_initialized); return peer_id_n_ids(); } - +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/peer_data_storage.h b/components/ble/peer_manager/peer_data_storage.h index ec0311f..0cf03dd 100644 --- a/components/ble/peer_manager/peer_data_storage.h +++ b/components/ble/peer_manager/peer_data_storage.h @@ -1,70 +1,108 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 PEER_DATA_STORAGE_H__ #define PEER_DATA_STORAGE_H__ -#include "stdint.h" +#include #include "sdk_errors.h" #include "ble_gap.h" #include "peer_manager_types.h" -#include "fds.h" +#include "peer_manager_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif /** + * @cond NO_DOXYGEN * @defgroup peer_data_storage Peer Data Storage * @ingroup peer_manager * @{ * @brief An internal module of @ref peer_manager. This module provides a Peer Manager-specific API * to the persistent storage. + * + * @details This module uses Flash Data Storage (FDS) to interface with persistent storage. */ -#define PDS_PREPARE_TOKEN_INVALID 0 -#define PDS_STORE_TOKEN_INVALID 0 - +#define PDS_PREPARE_TOKEN_INVALID (0) /**< Invalid value for prepare token. */ +#define PDS_FIRST_RESERVED_FILE_ID (0xC000) /**< The beginning of the range of file IDs reserved for Peer Manager. */ +#define PDS_LAST_RESERVED_FILE_ID (0xFFFE) /**< The end of the range of file IDs reserved for Peer Manager. */ +#define PDS_FIRST_RESERVED_RECORD_KEY (0xC000) /**< The beginning of the range of record keys reserved for Peer Manager. */ +#define PDS_LAST_RESERVED_RECORD_KEY (0xFFFE) /**< The end of the range of record keys reserved for Peer Manager. */ -typedef enum -{ - peer_id_to_instance_id = 16384, - instance_id_to_peer_id = -peer_id_to_instance_id, - peer_data_id_to_type_id = 32768, - type_id_to_peer_data_id = -peer_data_id_to_type_id, -} pds_convert_t; +#define PEER_ID_TO_FILE_ID ( PDS_FIRST_RESERVED_FILE_ID) //!< Macro for converting a @ref pm_peer_id_t to an FDS file ID. +#define FILE_ID_TO_PEER_ID (-PDS_FIRST_RESERVED_FILE_ID) //!< Macro for converting an FDS file ID to a @ref pm_peer_id_t. +#define DATA_ID_TO_RECORD_KEY ( PDS_FIRST_RESERVED_RECORD_KEY) //!< Macro for converting a @ref pm_peer_data_id_t to an FDS record ID. +#define RECORD_KEY_TO_DATA_ID (-PDS_FIRST_RESERVED_RECORD_KEY) //!< Macro for converting an FDS record ID to a @ref pm_peer_data_id_t. -/**@brief The types of events that can come from the peer_data_storage module. +/**@brief The events that come from this module. */ typedef enum { - PDS_EVT_STORED, /**< The specified data has been successfully stored. */ - PDS_EVT_CLEARED, /**< The specified data has been successfully cleared. */ - PDS_EVT_PEER_ID_CLEAR, /**< The peer id has been successfully cleared. */ - PDS_EVT_ERROR_STORE, /**< The specified data could not be stored. */ - PDS_EVT_ERROR_CLEAR, /**< The specified data could not be cleared. */ - PDS_EVT_ERROR_PEER_ID_CLEAR, /**< The peer id has been successfully cleared. */ - PDS_EVT_COMPRESSED, /**< A compress procedure has finished successfully. */ + PDS_EVT_STORED, //!< The specified data has been successfully stored. + PDS_EVT_UPDATED, //!< The specified data has been successfully updated. + PDS_EVT_CLEARED, //!< The specified data has been successfully cleared. + PDS_EVT_ERROR_STORE, //!< The specified data could not be stored. + PDS_EVT_ERROR_UPDATE, //!< The specified data could not be updated. + PDS_EVT_ERROR_CLEAR, //!< The specified data could not be cleared. + PDS_EVT_PEER_ID_CLEAR, //!< The peer id has been successfully cleared. + PDS_EVT_ERROR_PEER_ID_CLEAR, //!< The peer id has been successfully cleared. + PDS_EVT_COMPRESSED, //!< A compress procedure has finished successfully. + PDS_EVT_ERROR_UNEXPECTED, //!< An unexpected, possibly fatal error occurred. } pds_evt_id_t; -/**@brief Events that can come from the peer_data_storage module. +/**@brief The event structure for events generated by the this module. */ typedef struct { - pds_evt_id_t evt_id; /**< The type of event. */ - pm_peer_id_t peer_id; /**< The peer the event pertains to. */ - pm_peer_data_id_t data_id; /**< The data the event pertains to. */ - pm_store_token_t store_token; + pds_evt_id_t evt_id; /**< The type of event. */ + pm_peer_id_t peer_id; /**< The peer the event pertains to. */ + pm_peer_data_id_t data_id; /**< The data the event pertains to. */ + pm_store_token_t store_token; /**< A unique identifier for the operation. Can be compare to the token received when starting the operation. */ + ret_code_t result; /**< The result of the operation, or the unexpected error. */ } pds_evt_t; @@ -77,236 +115,134 @@ typedef struct typedef void (*pds_evt_handler_t)(pds_evt_t const * p_event); -/**@brief Function for registering for events from the peer database. - * - * @note This function will initialize the module if it is not already initialized. - * - * @param[in] evt_handler Event handler to register. - * - * @retval NRF_SUCCESS Registration successful. - * @retval NRF_ERROR_NO_MEM No more event handlers can be registered. - * @retval NRF_ERROR_NULL evt_handler was NULL. - * @retval NRF_ERROR_INVALID_PARAM Unexpected return code from @ref pm_buffer_init. - * @retval NRF_ERROR_INVALID_STATE FDS has not been initalized. - */ -ret_code_t pds_register(pds_evt_handler_t evt_handler); - - -#if 0 -/**@brief Function for initializing Peer Data storage and registering a - * callback for its events. +/**@brief Function for initializing the module. * - * @param[in] evt_handler Event handler to register. - * - * @retval NRF_SUCCESS Registration successful. - * @retval NRF_ERROR_NO_MEM No more event handlers can be registered. - * @retval NRF_ERROR_NULL evt_handler was NULL. - * @retval NRF_ERROR_INVALID_STATE FDS has not completed initialization. + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_STORAGE_FULL If no flash pages were available for use. + * @retval NRF_ERROR_INTERNAL If the module couldn't register with the flash filesystem. */ -ret_code_t pds_init(pds_evt_handler_t evt_handler); -#endif +ret_code_t pds_init(void); -/**@brief Function for retrieving a direct pointer to peer data in persistent storage. - * - * @param[in] peer_id The id of the peer whose data to read. - * @param[in] data_id Which data to get. - * @param[out] p_data The peer data pointer. - * @param[out] p_token Token that can be used to lock data in flash and check data validity. - * - * @retval NRF_SUCCESS The pointer was successfully retrieved. - * @retval NRF_ERROR_INVALID_PARAM Invalid data_id. - * @retval NRF_ERROR_NULL p_data was NULL. - * @retval NRF_ERROR_NOT_FOUND The requested data was not found in persistent storage. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. - */ -ret_code_t pds_peer_data_read_ptr_get(pm_peer_id_t peer_id, - pm_peer_data_id_t data_id, - pm_peer_data_flash_t * p_data, - pm_store_token_t * p_token); -/**@brief Function to lock the flash data (to defer compression from invalidating data) +/**@brief Function for reading peer data in flash. * - * @param[in] store_token The token representing the item to lock + * @param[in] peer_id The peer the data belongs to. + * @param[in] data_id The data to retrieve. + * @param[out] p_data The peer data. May not be @c NULL. + * @param[in] p_buf_len Length of the provided buffer, in bytes. Pass @c NULL to only copy + * a pointer to the data in flash. * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or @p data_id are invalid. + * @retval NRF_ERROR_NOT_FOUND If the data was not found in flash. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small. */ -ret_code_t pds_peer_data_lock(pm_store_token_t store_token); +ret_code_t pds_peer_data_read(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_t * const p_data, + uint32_t const * const p_buf_len); -/**@brief Function to verify flash data integrity - * - * @param[in] store_token The token representing the item to lock - * - * @retval NRF_SUCCESS The data integrity is valid. - * @retval NRF_ERROR_NULL The token is invalid. - * @retval NRF_ERROR_INVALID_DATA The data integrity is not valid. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. +/**@brief Function to prepare iterating over peer data in flash using @ref pds_peer_data_iterate. + * Call this function once each time before iterating using @ref pds_peer_data_iterate. */ -ret_code_t pds_peer_data_verify(pm_store_token_t store_token); +void pds_peer_data_iterate_prepare(void); -/**@brief Function for retrieving peer data from persistent storage by making a copy +/**@brief Function for iterating peers' data in flash. + * Always call @ref pds_peer_data_iterate_prepare before starting iterating. * - * @param[in] peer_id The id of the peer whose data to read. - * @param[in] data_id Which piece of data to read. - * @param[out] p_data Pointer to the peer data. - * @param[in,out] p_len_words Length available to copy to (in words). - * If set to NULL, then no copy will be made and the - * length will be reflected in p_len_words after the call returns. + * @param[in] data_id The peer data to iterate over. + * @param[out] p_peer_id The peer the data belongs to. + * @param[out] p_data The peer data in flash. * - * @retval NRF_SUCCESS The read was successful. - * @retval NRF_ERROR_INVALID_PARAM Invalid data_id. - * @retval NRF_ERROR_NULL data contained a NULL pointer. - * @retval NRF_ERROR_NOT_FOUND The requested data was not found in persistent storage. - * @retval NRF_ERROR_NO_MEM The length of stored data too large to copy out - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval true If the operation was successful. + * @retval false If the data was not found in flash, or another error occurred. */ -ret_code_t pds_peer_data_read(pm_peer_id_t peer_id, - pm_peer_data_id_t data_id, - pm_peer_data_t * p_data, - fds_length_t * p_len_words); +bool pds_peer_data_iterate(pm_peer_data_id_t data_id, + pm_peer_id_t * const p_peer_id, + pm_peer_data_flash_t * const p_data); -/**@brief Function for preparing persistent storage for a write. +/**@brief Function for reserving space in flash to store data. * - * @details If this call succeeds, space is reserved in persistent storage, so the write will fit. + * @param[in] p_peer_data The data to be stored in flash. Only data length and type (ID) are + * relevant for this operation. May not be @c NULL. + * @param[out] p_prepare_token A token identifying the reserved space. May not be @c NULL. * - * @note If space has already been prepared for this peer_id/data_id pair, no new space will be - * reserved, unless the previous reservation had too small size. - * - * @param[in] p_peer_data Data to prepare for. The data needs not be ready, but length and type - * values must. - * @param[out] p_prepare_token A token identifying the prepared memory area. - * - * @retval NRF_SUCCESS The call was successful. - * @retval NRF_ERROR_INVALID_PARAM Invalid data ID. - * @retval NRF_ERROR_INVALID_LENGTH Data length above the maximum allowed. - * @retval NRF_ERROR_NO_MEM No space available in persistent storage. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If the data ID in @p p_peer_data is invalid. + * @retval NRF_ERROR_INVALID_LENGTH If data length exceeds the maximum allowed length. + * @retval NRF_ERROR_STORAGE_FULL If no space is available in flash. + * @retval NRF_ERROR_INTERNAL If an unexpected error occurred. */ -ret_code_t pds_peer_data_write_prepare(pm_peer_data_const_t const * p_peer_data, - pm_prepare_token_t * p_prepare_token); +ret_code_t pds_space_reserve(pm_peer_data_const_t const * p_peer_data, + pm_prepare_token_t * p_prepare_token); -/**@brief Function for undoing a previous call to @ref pds_peer_data_write_prepare. +/**@brief Function for undoing a previous call to @ref pds_space_reserve. * - * @param[in] prepare_token A token identifying the prepared memory area to cancel. + * @param[in] prepare_token A token identifying the reservation to cancel. * - * @retval NRF_SUCCESS The call was successful. - * @retval NRF_ERROR_NOT_FOUND Invalid peer ID and/or prepare token. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INTERNAL If an unexpected error occurred. */ -ret_code_t pds_peer_data_write_prepare_cancel(pm_prepare_token_t prepare_token); +ret_code_t pds_space_reserve_cancel(pm_prepare_token_t prepare_token); -/**@brief Function for writing prepared (reserved) peer data to persistent storage. +/**@brief Function for storing peer data in flash. If the same piece of data already exists for the + * given peer, it will be updated. This operation is asynchronous. + * Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE event. * - * @details Writing happens asynchronously. Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE - * event. - * - * @param[in] peer_id The id of the peer the data pertains to. - * @param[in] p_peer_data The peer data. - * @param[in] prepare_token A token identifying the prepared memory area to write into. If - * the prepare token is invalid, e.g. PDS_PREPARE_TOKEN_INVALID, the - * prepare/write sequence will happen atomically. + * @param[in] peer_id The peer the data belongs to. + * @param[in] p_peer_data The peer data. May not be @c NULL. + * @param[in] prepare_token A token identifying the reservation made in flash to store the data. + * Pass @ref PDS_PREPARE_TOKEN_INVALID if no space was reserved. * @param[out] p_store_token A token identifying this particular store operation. The token can be - * used to identify events pertaining to this operation. - * - * @retval NRF_SUCCESS The write was initiated successfully. - * @retval NRF_ERROR_INVALID_PARAM Invalid data ID or store_flags. - * @retval NRF_ERROR_INVALID_LENGTH Length of data longer than in prepare call. - * @retval NRF_ERROR_NULL data contained a NULL pointer. - * @retval NRF_ERROR_NO_MEM No space available in persistent storage. This can only happen - * if p_prepare_token is NULL. - * @retval NRF_ERROR_BUSY FDS or underlying modules are busy and can't take any - * more requests - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * used to identify events pertaining to this operation. Pass @p NULL + * if not used. + * + * @retval NRF_SUCCESS If the operation was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or the data ID in @p_peer_data are invalid. + * @retval NRF_ERROR_STORAGE_FULL If no space is available in flash. This can only happen if + * @p p_prepare_token is @ref PDS_PREPARE_TOKEN_INVALID. + * @retval NRF_ERROR_BUSY If the flash filesystem was busy. + * @retval NRF_ERROR_INTERNAL If an unexpected error occurred. */ -ret_code_t pds_peer_data_write_prepared(pm_peer_id_t peer_id, - pm_peer_data_const_t const * p_peer_data, - pm_prepare_token_t prepare_token, - pm_store_token_t * p_store_token); - - -/**@brief Function for writing peer data to persistent storage. - * - * @details Writing happens asynchronously. Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE - * event. - * - * @param[in] peer_id The id of the peer the data pertains to. - * @param[in] p_peer_data The peer data. - * @param[out] p_store_token A token identifying this particular store operation. The token can be - * used to identify events pertaining to this operation. - * - * @retval NRF_SUCCESS The write was initiated successfully. - * @retval NRF_ERROR_INVALID_PARAM Invalid data ID or store_flags. - * @retval NRF_ERROR_NULL Data contained a NULL pointer. - * @retval NRF_ERROR_NO_MEM No space available in persistent storage. This can only happen - * if p_prepare_token is NULL. - * @retval NRF_ERROR_BUSY FDS or underlying modules are busy and can't take any - * more requests - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. - */ -ret_code_t pds_peer_data_write(pm_peer_id_t peer_id, +ret_code_t pds_peer_data_store(pm_peer_id_t peer_id, pm_peer_data_const_t const * p_peer_data, + pm_prepare_token_t prepare_token, pm_store_token_t * p_store_token); -/**@brief Function for updating currently stored peer data to a new version - * - * @details Updating happens asynchronously. - * Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE for the store token - * and a @ref PDS_EVT_ERROR_CLEAR or @ref PDS_EVT_ERROR_CLEAR for the old token - * - * @param[in] peer_id The peer which the data is associated to. - * @param[in] peer_data New data. - * @param[in] old_token Store token for the old data. - * @param[out] p_store_token Store token for the new data. - * - * @retval NRF_SUCESS The update was initiated successfully - * @retval NRF_ERROR_NOT_FOUND The old store token was invalid. - * @retval NRF_ERROR_NULL Data contained a NULL pointer. - * @retval NRF_ERROR_NO_MEM No space available in persistent storage. - * @retval NRF_ERROR_BUSY FDS or underlying modules are busy and can't take any - * more requests - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. - */ -ret_code_t pds_peer_data_update(pm_peer_id_t peer_id, - pm_peer_data_const_t const * peer_data, - pm_store_token_t old_token, - pm_store_token_t * p_store_token); - - -/**@brief Function for clearing peer data from persistent storage. - * - * @details Clearing happens asynchronously. Expect a @ref PDS_EVT_CLEARED or @ref PDS_EVT_ERROR_CLEAR - * event. +/**@brief Function for deleting peer data in flash. This operation is asynchronous. + * Expect a @ref PDS_EVT_CLEARED or @ref PDS_EVT_ERROR_CLEAR event. * - * @param[in] peer_id The id of the peer the data pertains to. - * @param[in] data_id Which data to clear. + * @param[in] peer_id The peer the data belongs to + * @param[in] data_id The data to delete. * - * @retval NRF_SUCCESS The clear was initiated successfully. - * @retval NRF_ERROR_INVALID_PARAM Data ID or was invalid. - * @retval NRF_ERROR_NOT_FOUND Nothing to clear for this peer ID. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval NRF_SUCCESS If the operation was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or @p data_id are invalid. + * @retval NRF_ERROR_NOT_FOUND If data was not found in flash. + * @retval NRF_ERROR_BUSY If the flash filesystem was busy. + * @retval NRF_ERROR_INTERNAL If an unexpected error occurred. */ -ret_code_t pds_peer_data_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id); +ret_code_t pds_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id); /**@brief Function for claiming an unused peer ID. * - * @return The first unused peer ID. - * @retval PM_PEER_ID_INVALID If no peer ID is available or module is not initialized. + * @retval PM_PEER_ID_INVALID If no peer ID was available. */ pm_peer_id_t pds_peer_id_allocate(void); -/**@brief Function for freeing a peer ID and clearing all data associated with it in persistent - * storage. +/**@brief Function for freeing a peer ID and deleting all data associated with it in flash. * - * @param[in] peer_id Peer ID to free. + * @param[in] peer_id The ID of the peer to free. * - * @retval NRF_SUCCESS The clear was initiated successfully - * @retval NRF_ERROR_BUSY Another peer_id clear was already requested or fds queue full + * @retval NRF_SUCCESS The operation was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM If @p peer_id is invalid. */ ret_code_t pds_peer_id_free(pm_peer_id_t peer_id); @@ -315,8 +251,8 @@ ret_code_t pds_peer_id_free(pm_peer_id_t peer_id); * * @param[in] peer_id The peer ID to inquire about. * - * @retval true peer_id is in use. - * @retval false peer_id is free, or the module is not initialized. + * @retval true @p peer_id is in use. + * @retval false @p peer_id is free. */ bool pds_peer_id_is_allocated(pm_peer_id_t peer_id); @@ -329,22 +265,44 @@ bool pds_peer_id_is_allocated(pm_peer_id_t peer_id); * * @param[in] prev_peer_id The previous peer ID. * - * @return The next peer ID. + * @return The first ordinary peer ID If @p prev_peer_id is @ref PM_PEER_ID_INVALID. + * @retval PM_PEER_ID_INVALID If @p prev_peer_id is the last ordinary peer ID or the module + * is not initialized. + */ +pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id); + + +/**@brief Function for getting the next peer ID in the sequence of all peer IDs pending deletion. + * Can be used to loop through all used peer IDs. + * + * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary + * peer ID. + * + * @param[in] prev_peer_id The previous peer ID. + * + * @return The next peer ID pending deletion. * @return The first ordinary peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID. * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module * is not initialized. */ -pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id); +pm_peer_id_t pds_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id); /**@brief Function for querying the number of valid peer IDs available. I.E the number of peers * in persistent storage. * - * @return The number of valid peer IDs, or 0 if module is not initialized. + * @return The number of valid peer IDs. + */ +uint32_t pds_peer_count_get(void); + + +/** @} + * @endcond */ -uint32_t pds_n_peers(void); -/** @} */ +#ifdef __cplusplus +} +#endif #endif /* PEER_DATA_STORAGE_H__ */ diff --git a/components/ble/peer_manager/peer_database.c b/components/ble/peer_manager/peer_database.c index d600d07..1392ac9 100644 --- a/components/ble/peer_manager/peer_database.c +++ b/components/ble/peer_manager/peer_database.c @@ -1,95 +1,118 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ - +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "peer_database.h" #include #include "peer_manager_types.h" +#include "peer_manager_internal.h" #include "peer_data_storage.h" #include "pm_buffer.h" -#define MAX_REGISTRANTS 6 /**< The number of user that can register with the module. */ - -#define MODULE_INITIALIZED (m_pdb.n_registrants > 0) /**< Expression which is true when the module is initialized. */ +#define N_WRITE_BUFFERS (8) /**< The number of write buffers available. */ +#define N_WRITE_BUFFER_RECORDS (N_WRITE_BUFFERS) /**< The number of write buffer records. */ -#define N_WRITE_BUFFERS 8 /**< The number of write buffers available. */ -#define N_WRITE_BUFFER_RECORDS (N_WRITE_BUFFERS) /**< The number of write buffer records. */ -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * @ref NRF_ERROR_INVALID_STATE if not. - */ -#define VERIFY_MODULE_INITIALIZED() \ -do \ -{ \ - if (!MODULE_INITIALIZED) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * if not. - */ -#define VERIFY_MODULE_INITIALIZED_VOID()\ -do \ -{ \ - if (!MODULE_INITIALIZED) \ - { \ - return; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * if not. +/**@brief Macro for verifying that the data ID is among the values eligible for using the write buffer. * - * @param[in] param The variable to check if is NULL. + * @param[in] data_id The data ID to verify. */ -#define VERIFY_PARAM_NOT_NULL(param) \ -do \ -{ \ - if (param == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } \ -} while(0) +// @note emdi: could this maybe be a function? +#define VERIFY_DATA_ID_WRITE_BUF(data_id) \ +do \ +{ \ + if (((data_id) != PM_PEER_DATA_ID_BONDING) && ((data_id) != PM_PEER_DATA_ID_GATT_LOCAL)) \ + { \ + return NRF_ERROR_INVALID_PARAM; \ + } \ +} while (0) + + +// The number of registered event handlers. +#define PDB_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) + + +// Peer Database event handlers in other Peer Manager submodules. +extern void pm_pdb_evt_handler(pdb_evt_t const * p_event); +extern void im_pdb_evt_handler(pdb_evt_t const * p_event); +extern void sm_pdb_evt_handler(pdb_evt_t const * p_event); +extern void smd_pdb_evt_handler(pdb_evt_t const * p_event); +extern void gscm_pdb_evt_handler(pdb_evt_t const * p_event); + +// Peer Database events' handlers. +// The number of elements in this array is PDB_EVENT_HANDLERS_CNT. +static pdb_evt_handler_t const m_evt_handlers[] = +{ + pm_pdb_evt_handler, + im_pdb_evt_handler, + sm_pdb_evt_handler, + smd_pdb_evt_handler, + gscm_pdb_evt_handler, +}; +/**@brief Struct for keeping track of one write buffer, from allocation, until it is fully written + * or cancelled. + */ typedef struct { - pm_peer_id_t peer_id; - pm_peer_data_id_t data_id; - uint8_t buffer_block_id; - uint8_t store_busy : 1; - uint8_t store_flash_full : 1; - uint8_t store_requested : 1; - uint32_t n_bufs; - pm_prepare_token_t prepare_token; - pm_store_token_t store_token; + pm_peer_id_t peer_id; /**< The peer ID this buffer belongs to. */ + pm_peer_data_id_t data_id; /**< The data ID this buffer belongs to. */ + pm_prepare_token_t prepare_token; /**< Token given by Peer Data Storage if room in flash has been reserved. */ + pm_store_token_t store_token; /**< Token given by Peer Data Storage when a flash write has been successfully requested. */ + uint32_t n_bufs; /**< The number of buffer blocks containing peer data. */ + uint8_t buffer_block_id; /**< The index of the first (or only) buffer block containing peer data. */ + uint8_t store_requested : 1; /**< Flag indicating that the buffer is being written to flash. */ + uint8_t store_flash_full : 1; /**< Flag indicating that the buffer was attempted written to flash, but a flash full error was returned and the operation should be retried after room has been made. */ + uint8_t store_busy : 1; /**< Flag indicating that the buffer was attempted written to flash, but a busy error was returned and the operation should be retried. */ } pdb_buffer_record_t; -typedef struct -{ - pdb_evt_handler_t evt_handlers[MAX_REGISTRANTS]; - uint8_t n_registrants; - pm_buffer_t write_buffer; - pdb_buffer_record_t write_buffer_records[N_WRITE_BUFFER_RECORDS]; - uint32_t n_writes; -} pdb_t; -static pdb_t m_pdb = {.n_registrants = 0}; +static bool m_module_initialized; +static pm_buffer_t m_write_buffer; /**< The state of the write buffer. */ +static pdb_buffer_record_t m_write_buffer_records[N_WRITE_BUFFER_RECORDS]; /**< The available write buffer records. */ +static uint32_t m_n_writes; /**< The number of pending (Not yet successfully requested in Peer Data Storage) store operations. */ + /**@brief Function for invalidating a record of a write buffer allocation. @@ -100,13 +123,33 @@ static void write_buffer_record_invalidate(pdb_buffer_record_t * p_record) { p_record->peer_id = PM_PEER_ID_INVALID; p_record->data_id = PM_PEER_DATA_ID_INVALID; - p_record->buffer_block_id = BUFFER_INVALID_ID; + p_record->buffer_block_id = PM_BUFFER_INVALID_ID; p_record->store_busy = false; p_record->store_flash_full = false; p_record->store_requested = false; p_record->n_bufs = 0; p_record->prepare_token = PDS_PREPARE_TOKEN_INVALID; - p_record->store_token = PDS_STORE_TOKEN_INVALID; + p_record->store_token = PM_STORE_TOKEN_INVALID; +} + + +/**@brief Function for finding a record of a write buffer allocation. + * + * @param[in] peer_id The peer ID in the record. + * @param[inout] p_index In: The starting index, out: The index of the record + * + * @return A pointer to the matching record, or NULL if none was found. + */ +static pdb_buffer_record_t * write_buffer_record_find_next(pm_peer_id_t peer_id, int * p_index) +{ + for (uint32_t i = *p_index; i < N_WRITE_BUFFER_RECORDS; i++) + { + if ((m_write_buffer_records[i].peer_id == peer_id)) + { + return &m_write_buffer_records[i]; + } + } + return NULL; } @@ -120,15 +163,16 @@ static void write_buffer_record_invalidate(pdb_buffer_record_t * p_record) static pdb_buffer_record_t * write_buffer_record_find(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) { - for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++) + int index = 0; + pdb_buffer_record_t * p_record = write_buffer_record_find_next(peer_id, &index); + + while ((p_record != NULL) && (p_record->data_id != data_id)) { - if ((m_pdb.write_buffer_records[i].peer_id == peer_id) - && (m_pdb.write_buffer_records[i].data_id == data_id)) - { - return &m_pdb.write_buffer_records[i]; - } + index++; + p_record = write_buffer_record_find_next(peer_id, &index); } - return NULL; + + return p_record; } @@ -152,15 +196,21 @@ static pdb_buffer_record_t * write_buffer_record_find_unused(void) */ static void write_buffer_record_release(pdb_buffer_record_t * p_write_buffer_record) { - for (int i = 0; i < p_write_buffer_record->n_bufs; i++) + for (uint32_t i = 0; i < p_write_buffer_record->n_bufs; i++) { - pm_buffer_release(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id + i); + pm_buffer_release(&m_write_buffer, p_write_buffer_record->buffer_block_id + i); } write_buffer_record_invalidate(p_write_buffer_record); } +/**@brief Function for claiming and activating a write buffer record. + * + * @param[out] pp_write_buffer_record The claimed record. + * @param[in] peer_id The peer ID this record should have. + * @param[in] data_id The data ID this record should have. + */ static void write_buffer_record_get(pdb_buffer_record_t ** pp_write_buffer_record, pm_peer_id_t peer_id, pm_peer_data_id_t data_id) { if (pp_write_buffer_record == NULL) @@ -184,9 +234,9 @@ static void write_buffer_record_get(pdb_buffer_record_t ** pp_write_buffer_recor */ static void pdb_evt_send(pdb_evt_t * p_event) { - for (int i = 0; i < m_pdb.n_registrants; i++) + for (uint32_t i = 0; i < PDB_EVENT_HANDLERS_CNT; i++) { - m_pdb.evt_handlers[i](p_event); + m_evt_handlers[i](p_event); } } @@ -195,21 +245,21 @@ static void pdb_evt_send(pdb_evt_t * p_event) * * @param[out] p_event The event to dispatch. */ -static void internal_state_reset(pdb_t * pdb) +static void internal_state_reset() { - memset(pdb, 0, sizeof(pdb_t)); - for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++) + for (uint32_t i = 0; i < N_WRITE_BUFFER_RECORDS; i++) { - write_buffer_record_invalidate(&pdb->write_buffer_records[i]); + write_buffer_record_invalidate(&m_write_buffer_records[i]); } } /**@brief Function for handling events from the Peer Data Storage module. + * This function is extern in Peer Data Storage. * * @param[in] p_event The event to handle. */ -static void pds_evt_handler(pds_evt_t const * p_event) +void pdb_pds_evt_handler(pds_evt_t const * p_event) { ret_code_t err_code; pdb_buffer_record_t * p_write_buffer_record; @@ -225,33 +275,38 @@ static void pds_evt_handler(pds_evt_t const * p_event) switch (p_event->evt_id) { case PDS_EVT_STORED: + case PDS_EVT_UPDATED: if ( (p_write_buffer_record != NULL) //&& (p_write_buffer_record->store_token == p_event->store_token) && (p_write_buffer_record->store_requested)) { write_buffer_record_release(p_write_buffer_record); event.evt_id = PDB_EVT_WRITE_BUF_STORED; + event.params.write_buf_stored_evt.update = (p_event->evt_id == PDS_EVT_UPDATED); pdb_evt_send(&event); } else { event.evt_id = PDB_EVT_RAW_STORED; + event.params.raw_stored_evt.store_token = p_event->store_token; pdb_evt_send(&event); } break; case PDS_EVT_ERROR_STORE: + case PDS_EVT_ERROR_UPDATE: if ( (p_write_buffer_record != NULL) && (p_write_buffer_record->store_token == p_event->store_token) && (p_write_buffer_record->store_requested)) { // Retry if internal buffer. - m_pdb.n_writes++; + m_n_writes++; p_write_buffer_record->store_requested = false; p_write_buffer_record->store_busy = true; } else { - event.evt_id = PDB_EVT_RAW_STORE_FAILED; + event.evt_id = PDB_EVT_RAW_STORE_FAILED; + event.params.error_raw_store_evt.err_code = p_event->result; pdb_evt_send(&event); } break; @@ -261,6 +316,16 @@ static void pds_evt_handler(pds_evt_t const * p_event) break; case PDS_EVT_ERROR_CLEAR: event.evt_id = PDB_EVT_CLEAR_FAILED; + event.params.clear_failed_evt.err_code = p_event->result; + pdb_evt_send(&event); + break; + case PDS_EVT_PEER_ID_CLEAR: + event.evt_id = PDB_EVT_PEER_FREED; + pdb_evt_send(&event); + break; + case PDS_EVT_ERROR_PEER_ID_CLEAR: + event.evt_id = PDB_EVT_PEER_FREE_FAILED; + event.params.peer_free_failed_evt.err_code = p_event->result; pdb_evt_send(&event); break; case PDS_EVT_COMPRESSED: @@ -268,30 +333,34 @@ static void pds_evt_handler(pds_evt_t const * p_event) event.evt_id = PDB_EVT_COMPRESSED; pdb_evt_send(&event); break; + case PDS_EVT_ERROR_UNEXPECTED: + event.params.error_unexpected.err_code = p_event->result; + break; default: break; } - if (m_pdb.n_writes > 0) + if (m_n_writes > 0) { - for (int i = 0; i < N_WRITE_BUFFER_RECORDS; i++) + for (uint32_t i = 0; i < N_WRITE_BUFFER_RECORDS; i++) { - if ((m_pdb.write_buffer_records[i].store_busy) - || (m_pdb.write_buffer_records[i].store_flash_full && retry_flash_full)) + if ((m_write_buffer_records[i].store_busy) + || (m_write_buffer_records[i].store_flash_full && retry_flash_full)) { - err_code = pdb_write_buf_store(m_pdb.write_buffer_records[i].peer_id, - m_pdb.write_buffer_records[i].data_id); + err_code = pdb_write_buf_store(m_write_buffer_records[i].peer_id, + m_write_buffer_records[i].data_id); if (err_code != NRF_SUCCESS) { - event.peer_id = m_pdb.write_buffer_records[i].peer_id; - event.data_id = m_pdb.write_buffer_records[i].data_id; - if (err_code == NRF_ERROR_NO_MEM) + event.peer_id = m_write_buffer_records[i].peer_id; + event.data_id = m_write_buffer_records[i].data_id; + if (err_code == NRF_ERROR_STORAGE_FULL) { event.evt_id = PDB_EVT_ERROR_NO_MEM; } else { - event.evt_id = PDB_EVT_ERROR_UNEXPECTED; + event.evt_id = PDB_EVT_ERROR_UNEXPECTED; + event.params.error_unexpected.err_code = err_code; } pdb_evt_send(&event); @@ -303,34 +372,22 @@ static void pds_evt_handler(pds_evt_t const * p_event) } -ret_code_t pdb_register(pdb_evt_handler_t evt_handler) +ret_code_t pdb_init() { - if (m_pdb.n_registrants >= MAX_REGISTRANTS) - { - return NRF_ERROR_NO_MEM; - } + ret_code_t ret; - VERIFY_PARAM_NOT_NULL(evt_handler); + NRF_PM_DEBUG_CHECK(!m_module_initialized); - if (!MODULE_INITIALIZED) - { - ret_code_t err_code; + internal_state_reset(); - internal_state_reset(&m_pdb); - err_code = pds_register(pds_evt_handler); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - PM_BUFFER_INIT(&m_pdb.write_buffer, N_WRITE_BUFFERS, PDB_WRITE_BUF_SIZE, err_code); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + PM_BUFFER_INIT(&m_write_buffer, N_WRITE_BUFFERS, PDB_WRITE_BUF_SIZE, ret); + + if (ret != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; } - m_pdb.evt_handlers[m_pdb.n_registrants] = evt_handler; - m_pdb.n_registrants += 1; + m_module_initialized = true; return NRF_SUCCESS; } @@ -338,83 +395,126 @@ ret_code_t pdb_register(pdb_evt_handler_t evt_handler) pm_peer_id_t pdb_peer_allocate(void) { + #if 0 if (!MODULE_INITIALIZED) { return PM_PEER_ID_INVALID; } + #endif + NRF_PM_DEBUG_CHECK(m_module_initialized); return pds_peer_id_allocate(); } ret_code_t pdb_peer_free(pm_peer_id_t peer_id) { - VERIFY_MODULE_INITIALIZED(); + ret_code_t err_code_in = NRF_SUCCESS; + ret_code_t err_code_out = NRF_SUCCESS; + + NRF_PM_DEBUG_CHECK(m_module_initialized); + + int index = 0; + pdb_buffer_record_t * p_record = write_buffer_record_find_next(peer_id, &index); + + while (p_record != NULL) + { + err_code_in = pdb_write_buf_release(peer_id, p_record->data_id); + + if ( (err_code_in != NRF_SUCCESS) + && (err_code_in != NRF_ERROR_NOT_FOUND)) + { + err_code_out = NRF_ERROR_INTERNAL; + } + + index++; + p_record = write_buffer_record_find_next(peer_id, &index); + } - return pds_peer_id_free(peer_id); + if (err_code_out == NRF_SUCCESS) + { + err_code_in = pds_peer_id_free(peer_id); + + if (err_code_in == NRF_SUCCESS) + { + // No action needed. + } + else if (err_code_in == NRF_ERROR_INVALID_PARAM) + { + err_code_out = NRF_ERROR_INVALID_PARAM; + } + else + { + err_code_out = NRF_ERROR_INTERNAL; + } + } + + return err_code_out; } -ret_code_t pdb_read_buf_get(pm_peer_id_t peer_id, - pm_peer_data_id_t data_id, - pm_peer_data_flash_t * p_peer_data, - pm_store_token_t * p_token) +ret_code_t pdb_peer_data_ptr_get(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_flash_t * const p_peer_data) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_peer_data != NULL); - return pds_peer_data_read_ptr_get(peer_id, data_id, p_peer_data, p_token); + // Pass NULL to only retrieve a pointer. + return pds_peer_data_read(peer_id, data_id, (pm_peer_data_t*)p_peer_data, NULL); } static void peer_data_point_to_buffer(pm_peer_data_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint16_t n_bufs) { uint16_t n_bytes = n_bufs * PDB_WRITE_BUF_SIZE; - p_peer_data->data_type = data_id; + p_peer_data->data_id = data_id; + + p_peer_data->p_all_data = (pm_peer_data_bonding_t *)p_buffer_memory; + p_peer_data->length_words = BYTES_TO_WORDS(n_bytes); +} + + +static void peer_data_const_point_to_buffer(pm_peer_data_const_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint32_t n_bufs) +{ + peer_data_point_to_buffer((pm_peer_data_t*)p_peer_data, data_id, p_buffer_memory, n_bufs); +} - switch(p_peer_data->data_type) + +static void write_buf_length_words_set(pm_peer_data_const_t * p_peer_data) +{ + switch (p_peer_data->data_id) { case PM_PEER_DATA_ID_BONDING: - p_peer_data->data.p_bonding_data = (pm_peer_data_bonding_t *)p_buffer_memory; p_peer_data->length_words = PM_BONDING_DATA_N_WORDS(); break; case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING: - p_peer_data->data.p_service_changed_pending = (bool *)p_buffer_memory; p_peer_data->length_words = PM_SC_STATE_N_WORDS(); break; - case PM_PEER_DATA_ID_GATT_LOCAL: - p_peer_data->data.p_local_gatt_db = (pm_peer_data_local_gatt_db_t *)p_buffer_memory; - p_peer_data->length_words = PM_LOCAL_DB_N_WORDS(n_bytes); + case PM_PEER_DATA_ID_PEER_RANK: + p_peer_data->length_words = PM_USAGE_INDEX_N_WORDS(); break; - case PM_PEER_DATA_ID_GATT_REMOTE: - p_peer_data->data.p_remote_gatt_db = (pm_peer_data_remote_gatt_db_t *)p_buffer_memory; - p_peer_data->length_words = PM_REMOTE_DB_N_WORDS(n_bytes / sizeof(ble_gatt_db_srv_t)); - break; - case PM_PEER_DATA_ID_APPLICATION: - p_peer_data->data.p_application_data = p_buffer_memory; - p_peer_data->length_words = PM_N_WORDS(n_bytes); + case PM_PEER_DATA_ID_GATT_LOCAL: + p_peer_data->length_words = PM_LOCAL_DB_N_WORDS(p_peer_data->p_local_gatt_db->len); break; default: - p_peer_data->length_words = 0; + // No action needed. break; } } -static void peer_data_const_point_to_buffer(pm_peer_data_const_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint32_t n_bufs) -{ - peer_data_point_to_buffer((pm_peer_data_t*)p_peer_data, data_id, p_buffer_memory, n_bufs); -} - - ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id, pm_peer_data_id_t data_id, uint32_t n_bufs, pm_peer_data_t * p_peer_data) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); + VERIFY_PARAM_NOT_NULL(p_peer_data); - if ( !PM_PEER_DATA_ID_IS_VALID(data_id) - || (n_bufs == 0) + VERIFY_DATA_ID_WRITE_BUF(data_id); + + if ( (n_bufs == 0) || (n_bufs > N_WRITE_BUFFERS) || !pds_peer_id_is_allocated(peer_id)) { @@ -423,6 +523,7 @@ ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id, pdb_buffer_record_t * write_buffer_record; uint8_t * p_buffer_memory; + bool new_record = false; write_buffer_record = write_buffer_record_find(peer_id, data_id); @@ -432,7 +533,7 @@ ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id, // Existing buffer is too small. for (uint8_t i = 0; i < write_buffer_record->n_bufs; i++) { - pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i); + pm_buffer_release(&m_write_buffer, write_buffer_record->buffer_block_id + i); } write_buffer_record_invalidate(write_buffer_record); write_buffer_record = NULL; @@ -442,7 +543,7 @@ ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id, // Release excess blocks. for (uint8_t i = n_bufs; i < write_buffer_record->n_bufs; i++) { - pm_buffer_release(&m_pdb.write_buffer, write_buffer_record->buffer_block_id + i); + pm_buffer_release(&m_write_buffer, write_buffer_record->buffer_block_id + i); } } @@ -455,20 +556,22 @@ ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id, } } - if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID) + if (write_buffer_record->buffer_block_id == PM_BUFFER_INVALID_ID) { - write_buffer_record->buffer_block_id = pm_buffer_block_acquire(&m_pdb.write_buffer, n_bufs); + write_buffer_record->buffer_block_id = pm_buffer_block_acquire(&m_write_buffer, n_bufs); - if (write_buffer_record->buffer_block_id == BUFFER_INVALID_ID) + if (write_buffer_record->buffer_block_id == PM_BUFFER_INVALID_ID) { write_buffer_record_invalidate(write_buffer_record); return NRF_ERROR_BUSY; } + + new_record = true; } write_buffer_record->n_bufs = n_bufs; - p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, write_buffer_record->buffer_block_id); + p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer, write_buffer_record->buffer_block_id); if (p_buffer_memory == NULL) { @@ -476,37 +579,9 @@ ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id, } peer_data_point_to_buffer(p_peer_data, data_id, p_buffer_memory, n_bufs); - switch(data_id) + if (new_record && (data_id == PM_PEER_DATA_ID_GATT_LOCAL)) { - case PM_PEER_DATA_ID_BONDING: - /* No action needed. */ - break; - case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING: - /* No action needed. */ - break; - case PM_PEER_DATA_ID_GATT_LOCAL: - { - uint32_t size_offset = sizeof(pm_peer_data_local_gatt_db_t); - p_peer_data->data.p_local_gatt_db->p_data = &p_buffer_memory[size_offset]; - p_peer_data->data.p_local_gatt_db->len = (PDB_WRITE_BUF_SIZE*n_bufs)-size_offset; - } - break; - case PM_PEER_DATA_ID_GATT_REMOTE: - { - uint32_t size_offset = sizeof(pm_peer_data_remote_gatt_db_t); - p_peer_data->data.p_remote_gatt_db->p_data = (ble_gatt_db_srv_t*)&(p_buffer_memory[size_offset]); - p_peer_data->data.p_remote_gatt_db->service_count - = ((PDB_WRITE_BUF_SIZE*n_bufs)-size_offset)/sizeof(ble_gatt_db_srv_t); - } - break; - case PM_PEER_DATA_ID_APPLICATION: - { - p_peer_data->data.p_application_data = p_buffer_memory; - } - break; - default: - // Invalid data_id. This should have been picked up earlier. - return NRF_ERROR_INTERNAL; + p_peer_data->p_local_gatt_db->len = PM_LOCAL_DB_LEN(p_peer_data->length_words); } return NRF_SUCCESS; @@ -515,7 +590,7 @@ ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id, ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); ret_code_t err_code = NRF_SUCCESS; pdb_buffer_record_t * p_write_buffer_record; @@ -528,7 +603,7 @@ ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id if (p_write_buffer_record->prepare_token != PDS_PREPARE_TOKEN_INVALID) { - err_code = pds_peer_data_write_prepare_cancel(p_write_buffer_record->prepare_token); + err_code = pds_space_reserve_cancel(p_write_buffer_record->prepare_token); if (err_code != NRF_SUCCESS) { err_code = NRF_ERROR_INTERNAL; @@ -543,7 +618,9 @@ ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); + + VERIFY_DATA_ID_WRITE_BUF(data_id); ret_code_t err_code = NRF_SUCCESS; pdb_buffer_record_t * p_write_buffer_record; @@ -556,8 +633,8 @@ ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t d if (p_write_buffer_record->prepare_token == PDS_PREPARE_TOKEN_INVALID) { - uint8_t * p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id); - pm_peer_data_const_t peer_data = {.data_type = data_id}; + uint8_t * p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer, p_write_buffer_record->buffer_block_id); + pm_peer_data_const_t peer_data = {.data_id = data_id}; if (p_buffer_memory == NULL) { @@ -566,7 +643,9 @@ ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t d peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs); - err_code = pds_peer_data_write_prepare(&peer_data, &p_write_buffer_record->prepare_token); + write_buf_length_words_set(&peer_data); + + err_code = pds_space_reserve(&peer_data, &p_write_buffer_record->prepare_token); if (err_code == NRF_ERROR_INVALID_LENGTH) { return NRF_ERROR_INTERNAL; @@ -577,45 +656,17 @@ ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t d } -static ret_code_t write_or_update(pm_peer_id_t peer_id, - pm_peer_data_id_t data_id, - pm_peer_data_const_t * p_peer_data, - pm_store_token_t * p_store_token, - pm_prepare_token_t prepare_token) -{ - pm_peer_data_flash_t old_peer_data; - pm_store_token_t old_store_token; - ret_code_t err_code = pds_peer_data_read_ptr_get(peer_id, data_id, &old_peer_data, &old_store_token); - - if (err_code == NRF_SUCCESS) - { - pds_peer_data_write_prepare_cancel(prepare_token); - err_code = pds_peer_data_update(peer_id, p_peer_data, old_store_token, p_store_token); - } - else if (err_code == NRF_ERROR_NOT_FOUND) - { - if (prepare_token == PDS_PREPARE_TOKEN_INVALID) - { - err_code = pds_peer_data_write(peer_id, p_peer_data, p_store_token); - } - else - { - err_code = pds_peer_data_write_prepared(peer_id, p_peer_data, prepare_token, p_store_token); - } - } - return err_code; -} - - ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); + + VERIFY_DATA_ID_WRITE_BUF(data_id); ret_code_t err_code = NRF_SUCCESS; pdb_buffer_record_t * p_write_buffer_record; uint8_t * p_buffer_memory; - pm_peer_data_const_t peer_data = {.data_type = data_id}; + pm_peer_data_const_t peer_data = {.data_id = data_id}; p_write_buffer_record = write_buffer_record_find(peer_id, data_id); @@ -630,7 +681,7 @@ ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id, return NRF_SUCCESS; } - p_buffer_memory = pm_buffer_ptr_get(&m_pdb.write_buffer, p_write_buffer_record->buffer_block_id); + p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer, p_write_buffer_record->buffer_block_id); if (p_buffer_memory == NULL) { @@ -639,32 +690,16 @@ ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id, peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs); - switch (data_id) - { - case PM_PEER_DATA_ID_BONDING: - peer_data.length_words = PM_BONDING_DATA_N_WORDS(); - break; - case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING: - peer_data.length_words = PM_SC_STATE_N_WORDS(); - break; - case PM_PEER_DATA_ID_GATT_LOCAL: - peer_data.length_words = PM_LOCAL_DB_N_WORDS(peer_data.data.p_local_gatt_db->len); - break; - case PM_PEER_DATA_ID_GATT_REMOTE: - peer_data.length_words = PM_REMOTE_DB_N_WORDS(peer_data.data.p_remote_gatt_db->service_count); - break; - case PM_PEER_DATA_ID_APPLICATION: - peer_data.length_words = PM_N_WORDS(p_write_buffer_record->n_bufs * PDB_WRITE_BUF_SIZE); - break; - default: - return NRF_ERROR_INVALID_PARAM; - } + write_buf_length_words_set(&peer_data); - err_code = write_or_update(peer_id, data_id, &peer_data, &p_write_buffer_record->store_token, p_write_buffer_record->prepare_token); + err_code = pds_peer_data_store(peer_id, + &peer_data, + p_write_buffer_record->prepare_token, + &p_write_buffer_record->store_token); if (p_write_buffer_record->store_busy && p_write_buffer_record->store_flash_full) { - m_pdb.n_writes--; + m_n_writes--; } if (err_code == NRF_SUCCESS) @@ -677,18 +712,18 @@ ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id, { if (err_code == NRF_ERROR_BUSY) { - m_pdb.n_writes++; + m_n_writes++; p_write_buffer_record->store_busy = true; p_write_buffer_record->store_flash_full = false; err_code = NRF_SUCCESS; } - else if (err_code == NRF_ERROR_NO_MEM) + else if (err_code == NRF_ERROR_STORAGE_FULL) { - m_pdb.n_writes++; + m_n_writes++; p_write_buffer_record->store_busy = false; p_write_buffer_record->store_flash_full = true; } - else if ((err_code != NRF_ERROR_NO_MEM) && (err_code != NRF_ERROR_INVALID_PARAM)) + else if (err_code != NRF_ERROR_INVALID_PARAM) { err_code = NRF_ERROR_INTERNAL; } @@ -700,40 +735,42 @@ ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id, ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) { - VERIFY_MODULE_INITIALIZED(); - - return pds_peer_data_clear(peer_id, data_id); + NRF_PM_DEBUG_CHECK(m_module_initialized); + return pds_peer_data_delete(peer_id, data_id); } uint32_t pdb_n_peers(void) { - if (!MODULE_INITIALIZED) - { - return 0; - } - - return pds_n_peers(); + NRF_PM_DEBUG_CHECK(m_module_initialized); + return pds_peer_count_get(); } pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id) { - if (!MODULE_INITIALIZED) - { - return PM_PEER_ID_INVALID; - } - + NRF_PM_DEBUG_CHECK(m_module_initialized); return pds_next_peer_id_get(prev_peer_id); } -ret_code_t pdb_raw_read(pm_peer_id_t peer_id, - pm_peer_data_id_t data_id, - pm_peer_data_t * p_peer_data) +pm_peer_id_t pdb_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id) { - VERIFY_MODULE_INITIALIZED(); - return pds_peer_data_read(peer_id, data_id, p_peer_data, &p_peer_data->length_words); + NRF_PM_DEBUG_CHECK(m_module_initialized); + return pds_next_deleted_peer_id_get(prev_peer_id); +} + + +ret_code_t pdb_peer_data_load(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_t * const p_peer_data) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_peer_data != NULL); + + // Provide the buffer length in bytes. + uint32_t const data_len_bytes = (p_peer_data->length_words * sizeof(uint32_t)); + return pds_peer_data_read(peer_id, data_id, p_peer_data, &data_len_bytes); } @@ -741,8 +778,7 @@ ret_code_t pdb_raw_store(pm_peer_id_t peer_id, pm_peer_data_const_t * p_peer_data, pm_store_token_t * p_store_token) { - VERIFY_MODULE_INITIALIZED(); - - return write_or_update(peer_id, p_peer_data->data_type, p_peer_data, p_store_token, PDS_PREPARE_TOKEN_INVALID); + NRF_PM_DEBUG_CHECK(m_module_initialized); + return pds_peer_data_store(peer_id, p_peer_data, PDS_PREPARE_TOKEN_INVALID, p_store_token); } - +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/peer_database.h b/components/ble/peer_manager/peer_database.h index 4ceb9a5..34e06ca 100644 --- a/components/ble/peer_manager/peer_database.h +++ b/components/ble/peer_manager/peer_database.h @@ -1,14 +1,42 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 PEER_DATABASE_H__ @@ -16,9 +44,15 @@ #include #include "peer_manager_types.h" +#include "peer_manager_internal.h" #include "sdk_errors.h" +#ifdef __cplusplus +extern "C" { +#endif + /** + * @cond NO_DOXYGEN * @defgroup peer_database Peer Database * @ingroup peer_manager * @{ @@ -27,17 +61,19 @@ * */ -#define PDB_WRITE_BUF_SIZE (sizeof(pm_peer_data_bonding_t)) +#define PDB_WRITE_BUF_SIZE (sizeof(pm_peer_data_bonding_t)) //!< The size (in bytes) of each block in the internal buffer accessible via @ref pdb_write_buf_get. /**@brief Events that can come from the peer_database module. */ typedef enum { - PDB_EVT_WRITE_BUF_STORED, /**< A pdb_write_buf_store operation has completed successfully. */ - PDB_EVT_RAW_STORED, /**< A pdb_raw_store operation has completed successfully. */ - PDB_EVT_RAW_STORE_FAILED, /**< A pdb_raw_store operation has failed. */ - PDB_EVT_CLEARED, /**< A pdb_clear operation has completed successfully. */ - PDB_EVT_CLEAR_FAILED, /**< A pdb_clear operation has failed. */ + PDB_EVT_WRITE_BUF_STORED, /**< A @ref pdb_write_buf_store operation has completed successfully. */ + PDB_EVT_RAW_STORED, /**< A @ref pdb_raw_store operation has completed successfully. */ + PDB_EVT_RAW_STORE_FAILED, /**< A @ref pdb_raw_store operation has failed. */ + PDB_EVT_CLEARED, /**< A @ref pdb_clear operation has completed successfully. */ + PDB_EVT_CLEAR_FAILED, /**< A @ref pdb_clear operation has failed. */ + PDB_EVT_PEER_FREED, /**< A @ref pdb_peer_free operation has completed successfully. All associated data has been erased. */ + PDB_EVT_PEER_FREE_FAILED, /**< A @ref pdb_peer_free operation has failed. */ PDB_EVT_COMPRESSED, /**< A compress procedure has completed. */ PDB_EVT_ERROR_NO_MEM, /**< An operation is blocked because the flash is full. It will be reattempted automatically after the next compress procedure. */ PDB_EVT_ERROR_UNEXPECTED, /**< An unexpected error occurred. This is a fatal error. */ @@ -52,14 +88,31 @@ typedef struct pm_peer_data_id_t data_id; /**< The data the event pertains to. */ union { + struct + { + bool update; /**< If true, an existing value was overwritten. */ + } write_buf_stored_evt; /**< Additional information pertaining to the @ref PDB_EVT_WRITE_BUF_STORED event. */ struct { pm_store_token_t store_token; /**< A token identifying the store operation this event pertains to. */ - } raw_stored_evt; + } raw_stored_evt; /**< Additional information pertaining to the @ref PDB_EVT_RAW_STORED event. */ struct { pm_store_token_t store_token; /**< A token identifying the store operation this event pertains to. */ - } error_raw_store_evt; + ret_code_t err_code; /**< Error code specifying what went wrong. */ + } error_raw_store_evt; /**< Additional information pertaining to the @ref PDB_EVT_RAW_STORE_FAILED event. */ + struct + { + ret_code_t err_code; /**< The error that occurred. */ + } clear_failed_evt; /**< Additional information pertaining to the @ref PDB_EVT_CLEAR_FAILED event. */ + struct + { + ret_code_t err_code; /**< The error that occurred. */ + } peer_free_failed_evt; /**< Additional information pertaining to the @ref PDB_EVT_PEER_FREE_FAILED event. */ + struct + { + ret_code_t err_code; /**< The unexpected error that occurred. */ + } error_unexpected; /**< Additional information pertaining to the @ref PDB_EVT_ERROR_UNEXPECTED event. */ } params; } pdb_evt_t; @@ -70,19 +123,12 @@ typedef struct typedef void (*pdb_evt_handler_t)(pdb_evt_t const * p_event); -/**@brief Function for registering for events from the peer database. - * - * @note This function will initialize the module if it is not already initialized. - * - * @param[in] evt_handler Event handler to register. +/**@brief Function for initializing the module. * - * @retval NRF_SUCCESS Registration successful. - * @retval NRF_ERROR_NO_MEM No more event handlers can be registered. - * @retval NRF_ERROR_NULL evt_handler was NULL. - * @retval NRF_ERROR_INVALID_PARAM Unexpected return code from @ref pm_buffer_init. - * @retval NRF_ERROR_INVALID_STATE FDS has not been initalized. + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INTERNAL An unexpected error happened. */ -ret_code_t pdb_register(pdb_evt_handler_t evt_handler); +ret_code_t pdb_init(void); /**@brief Function for allocating persistent bond storage for a peer. @@ -100,36 +146,29 @@ pm_peer_id_t pdb_peer_allocate(void); * @param[in] peer_id ID to be freed. * * @retval NRF_SUCCESS Peer ID was released and clear operation was initiated successfully. - * @retval NRF_ERROR_BUSY Another peer_id clear was already requested or could not be started. + * @retval NRF_ERROR_INVALID_PARAM Peer ID was invalid. * @retval NRF_ERROR_INVALID_STATE Module is not initialized. */ ret_code_t pdb_peer_free(pm_peer_id_t peer_id); -/**@brief Function for retrieving pointers to read-only peer data. +/**@brief Function for retrieving a pointer to peer data in flash (read-only). * - * @note Reading this pointer is not safe in the strictest sense. If a safe read is required: - * - Disable interrupts - * - Call this function. If the return code is @ref NRF_SUCCESS, the following read is safe. - * - Read memory. - * - Enable interrupts. - * @note This buffer does not need to be released. It is a pointer directly to flash. + * @note Dereferencing this pointer is not the safest thing to do if interrupts are enabled, + * because Flash Data Storage garbage collection might move the data around. Either disable + * interrupts while using the data, or use @ref pdb_peer_data_load. * - * @param[in] peer_id ID of peer to retrieve data for. - * @param[in] data_id Which piece of data to get. - * @param[out] p_peer_data Pointer to immutable peer data. - * @param[out] p_token Token that can be used to lock data in flash and check data validity. + * @param[in] peer_id The peer the data belongs to. + * @param[in] data_id The data to read. + * @param[out] p_peer_data The peer data, read-only. * - * @retval NRF_SUCCESS Data retrieved successfully. - * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated. - * @retval NRF_ERROR_NULL p_peer_data was NULL. - * @retval NRF_ERROR_NOT_FOUND This data was not found for this peer ID. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval NRF_SUCCESS If the pointer to the data was retrieved successfully. + * @retval NRF_ERROR_INVALID_PARAM If either @p peer_id or @p data_id are invalid. + * @retval NRF_ERROR_NOT_FOUND If data was not found in flash. */ -ret_code_t pdb_read_buf_get(pm_peer_id_t peer_id, - pm_peer_data_id_t data_id, - pm_peer_data_flash_t * p_peer_data, - pm_store_token_t * p_token); +ret_code_t pdb_peer_data_ptr_get(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_flash_t * const p_peer_data); /**@brief Function for retrieving pointers to a write buffer for peer data. @@ -197,7 +236,7 @@ ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id * @param[in] data_id The type of data to reserve space for. * * @retval NRF_SUCCESS Successfully reserved space in persistent storage. - * @retval NRF_ERROR_NO_MEM Not enough room in persistent storage. + * @retval NRF_ERROR_STORAGE_FULL Not enough room in persistent storage. * @retval NRF_ERROR_BUSY Could not process request at this time. Reattempt later. * @retval NRF_ERROR_NOT_FOUND No buffer has been allocated for this peer ID/data ID pair. * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated. @@ -214,7 +253,7 @@ ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t d * @param[in] data_id Which piece of data to store. * * @retval NRF_SUCCESS Data storing was successfully started. - * @retval NRF_ERROR_NO_MEM No space available in persistent storage. Please clear some + * @retval NRF_ERROR_STORAGE_FULL No space available in persistent storage. Please clear some * space, the operation will be reattempted after the next compress * procedure. This error will not happen if * @ref pdb_write_buf_store_prepare is called beforehand. @@ -232,11 +271,13 @@ ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id, * @param[in] peer_id ID of peer to clear data for. * @param[in] data_id Which piece of data to clear. * - * @retval NRF_SUCCESS Data clear was successfully started. - * @retval NRF_ERROR_INVALID_PARAM Data ID was invalid. - * @retval NRF_ERROR_NOT_FOUND Nothing to clear for this data for this peer ID. - * @retval NRF_ERROR_BUSY Could not process request at this time. Reattempt later. + * @retval NRF_SUCCESS The clear was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM Data ID or peer ID was invalid. + * @retval NRF_ERROR_NOT_FOUND Nothing to clear for this peer ID/data ID combination. + * @retval NRF_ERROR_BUSY Underlying modules are busy and can't take any more requests at + * this moment. * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval NRF_ERROR_INTERNAL Internal error. */ ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id); @@ -264,12 +305,27 @@ uint32_t pdb_n_peers(void); pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id); +/**@brief Function for getting the next peer ID in the sequence of all peer IDs pending deletion. + * Can be used to loop through all used peer IDs. + * + * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary + * peer ID. + * + * @param[in] prev_peer_id The previous peer ID. + * + * @return The next peer ID pending deletion. + * @return The first ordinary peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID. + * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID. + */ +pm_peer_id_t pdb_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id); + + /**@brief Function for updating currently stored peer data to a new version * - * @details Updating happens asynchronously. + * @details Updating happens asynchronously. * Expect a @ref PDS_EVT_STORED or @ref PDS_EVT_ERROR_STORE for the store token - * and a @ref PDS_EVT_ERROR_CLEAR or @ref PDS_EVT_ERROR_CLEAR for the old token - * + * and a @ref PDS_EVT_ERROR_CLEAR or @ref PDS_EVT_ERROR_CLEAR for the old token + * * @param[in] peer_data New data * @param[in] old_token Store token for the old data * @param[out] p_store_token Store token for the new data @@ -277,8 +333,8 @@ pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id); * @retval NRF_SUCESS The update was initiated successfully * @retval NRF_ERROR_NOT_FOUND The old store token was invalid. * @retval NRF_ERROR_NULL Data contained a NULL pointer. - * @retval NRF_ERROR_NO_MEM No space available in persistent storage. - * @retval NRF_ERROR_BUSY FDS or underlying modules are busy and can't take any + * @retval NRF_ERROR_STORAGE_FULL No space available in persistent storage. + * @retval NRF_ERROR_BUSY FDS or underlying modules are busy and can't take any * more requests * @retval NRF_ERROR_INVALID_STATE Module is not initialized. */ @@ -287,25 +343,24 @@ ret_code_t pdb_peer_data_update(pm_peer_data_const_t peer_data, pm_store_token_t * p_store_token); -/**@brief Function for reading data directly from persistent storage to external memory. +/**@brief Function for copy peer data from flash into a provided buffer. * - * @param[in] peer_id ID of peer to read data for. - * @param[in] data_id Which piece of data to read. - * @param[inout] p_peer_data Where to store the data. If the data to be read has variable length, - * the appropriate length field needs to reflect the available buffer - * space. On a successful read, the length field is updated to match the - * length of the read data. + * @param[in] peer_id The peer the data belongs to. + * @param[in] data_id The data to read. + * @param[inout] p_peer_data The buffer where to copy data into. The field @c length_words in this + * parameter must represent the buffer length in words. * - * @retval NRF_SUCCESS Data successfully read. - * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated. - * @retval NRF_ERROR_NULL p_peer_data contained a NULL pointer. - * @retval NRF_ERROR_NOT_FOUND This data was not found for this peer ID. - * @retval NRF_ERROR_DATA_SIZE The provided buffer was not large enough. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @note Actually, it represents the buffer length in bytes upon entering the function, + * and upon exit it represents the length of the data in words.. not good. Fix this. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or @p data_id are invalid. + * @retval NRF_ERROR_NOT_FOUND If the data was not found in flash. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small. */ -ret_code_t pdb_raw_read(pm_peer_id_t peer_id, - pm_peer_data_id_t data_id, - pm_peer_data_t * p_peer_data); +ret_code_t pdb_peer_data_load(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + pm_peer_data_t * const p_peer_data); /**@brief Function for writing data directly to persistent storage from external memory. @@ -318,16 +373,22 @@ ret_code_t pdb_raw_read(pm_peer_id_t peer_id, * @retval NRF_SUCCESS Data successfully written. * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated. * @retval NRF_ERROR_NULL p_peer_data contained a NULL pointer. - * @retval NRF_ERROR_NO_MEM No space available in persistent storage. + * @retval NRF_ERROR_STORAGE_FULL No space available in persistent storage. * @retval NRF_ERROR_INVALID_LENGTH Data length above the maximum allowed. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @retval NRF_ERROR_BUSY Unable to perform operation at this time. */ ret_code_t pdb_raw_store(pm_peer_id_t peer_id, pm_peer_data_const_t * p_peer_data, pm_store_token_t * p_store_token); +/** @} + * @endcond + */ + -/** @} */ +#ifdef __cplusplus +} +#endif #endif /* PEER_DATABASE_H__ */ diff --git a/components/ble/peer_manager/peer_id.c b/components/ble/peer_manager/peer_id.c index 34e0a4d..ae701be 100644 --- a/components/ble/peer_manager/peer_id.c +++ b/components/ble/peer_manager/peer_id.c @@ -1,16 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ - - +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "peer_id.h" #include @@ -22,11 +51,12 @@ typedef struct { - uint8_t peer_ids[MUTEX_STORAGE_SIZE(PM_PEER_ID_N_AVAILABLE_IDS)]; /*< bitmap. */ + uint8_t used_peer_ids[MUTEX_STORAGE_SIZE(PM_PEER_ID_N_AVAILABLE_IDS)]; /**< Bitmap designating which peer IDs are in use. */ + uint8_t deleted_peer_ids[MUTEX_STORAGE_SIZE(PM_PEER_ID_N_AVAILABLE_IDS)]; /**< Bitmap designating which peer IDs are marked for deletion. */ } pi_t; -static pi_t m_pi = {.peer_ids = {0}}; +static pi_t m_pi = {{0}, {0}}; static void internal_state_reset(pi_t * p_pi) @@ -38,16 +68,17 @@ static void internal_state_reset(pi_t * p_pi) void peer_id_init(void) { internal_state_reset(&m_pi); - pm_mutex_init(m_pi.peer_ids, PM_PEER_ID_N_AVAILABLE_IDS); + pm_mutex_init(m_pi.used_peer_ids, PM_PEER_ID_N_AVAILABLE_IDS); + pm_mutex_init(m_pi.deleted_peer_ids, PM_PEER_ID_N_AVAILABLE_IDS); } -pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id) +static pm_peer_id_t claim(pm_peer_id_t peer_id, uint8_t * mutex_group) { pm_peer_id_t allocated_peer_id = PM_PEER_ID_INVALID; if (peer_id == PM_PEER_ID_INVALID) { - allocated_peer_id = pm_mutex_lock_first_available(m_pi.peer_ids, PM_PEER_ID_N_AVAILABLE_IDS); + allocated_peer_id = pm_mutex_lock_first_available(mutex_group, PM_PEER_ID_N_AVAILABLE_IDS); if (allocated_peer_id == PM_PEER_ID_N_AVAILABLE_IDS) { allocated_peer_id = PM_PEER_ID_INVALID; @@ -55,38 +86,76 @@ pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id) } else if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS) { - bool lock_success = pm_mutex_lock(m_pi.peer_ids, peer_id); + bool lock_success = pm_mutex_lock(mutex_group, peer_id); allocated_peer_id = lock_success ? peer_id : PM_PEER_ID_INVALID; } return allocated_peer_id; } -void peer_id_free(pm_peer_id_t peer_id) +static void release(pm_peer_id_t peer_id, uint8_t * mutex_group) { if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS) { - pm_mutex_unlock(m_pi.peer_ids, peer_id); + pm_mutex_unlock(mutex_group, peer_id); } } +pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id) +{ + return claim(peer_id, m_pi.used_peer_ids); +} + + +bool peer_id_delete(pm_peer_id_t peer_id) +{ + pm_peer_id_t deleted_peer_id; + + if (peer_id == PM_PEER_ID_INVALID) + { + return false; + } + + deleted_peer_id = claim(peer_id, m_pi.deleted_peer_ids); + + return (deleted_peer_id == peer_id); +} + + +void peer_id_free(pm_peer_id_t peer_id) +{ + release(peer_id, m_pi.used_peer_ids); + release(peer_id, m_pi.deleted_peer_ids); +} + + bool peer_id_is_allocated(pm_peer_id_t peer_id) { if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS) { - return pm_mutex_lock_status_get(m_pi.peer_ids, peer_id); + return pm_mutex_lock_status_get(m_pi.used_peer_ids, peer_id); } return false; } -pm_peer_id_t peer_id_next_id_get(pm_peer_id_t prev_peer_id) +bool peer_id_is_deleted(pm_peer_id_t peer_id) +{ + if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS) + { + return pm_mutex_lock_status_get(m_pi.deleted_peer_ids, peer_id); + } + return false; +} + + +pm_peer_id_t next_id_get(pm_peer_id_t prev_peer_id, uint8_t * mutex_group) { pm_peer_id_t i = (prev_peer_id == PM_PEER_ID_INVALID) ? 0 : (prev_peer_id + 1); for (; i < PM_PEER_ID_N_AVAILABLE_IDS; i++) { - if (pm_mutex_lock_status_get(m_pi.peer_ids, i)) + if (pm_mutex_lock_status_get(mutex_group, i)) { return i; } @@ -96,16 +165,39 @@ pm_peer_id_t peer_id_next_id_get(pm_peer_id_t prev_peer_id) } +pm_peer_id_t peer_id_get_next_used(pm_peer_id_t peer_id) +{ + peer_id = next_id_get(peer_id, m_pi.used_peer_ids); + + while (peer_id != PM_PEER_ID_INVALID) + { + if (!peer_id_is_deleted(peer_id)) + { + return peer_id; + } + + peer_id = next_id_get(peer_id, m_pi.used_peer_ids); + } + + return peer_id; +} + + +pm_peer_id_t peer_id_get_next_deleted(pm_peer_id_t prev_peer_id) +{ + return next_id_get(prev_peer_id, m_pi.deleted_peer_ids); +} + + uint32_t peer_id_n_ids(void) { uint32_t n_ids = 0; for (pm_peer_id_t i = 0; i < PM_PEER_ID_N_AVAILABLE_IDS; i++) { - n_ids += pm_mutex_lock_status_get(m_pi.peer_ids, i); + n_ids += pm_mutex_lock_status_get(m_pi.used_peer_ids, i); } return n_ids; } - - +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/peer_id.h b/components/ble/peer_manager/peer_id.h index b2c40d7..4f9ad1c 100644 --- a/components/ble/peer_manager/peer_id.h +++ b/components/ble/peer_manager/peer_id.h @@ -1,27 +1,60 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 PEER_ID_H__ #define PEER_ID_H__ -#include "stdint.h" +#include #include "sdk_errors.h" #include "ble_gap.h" #include "peer_manager_types.h" +#ifdef __cplusplus +extern "C" { +#endif + /** + * @cond NO_DOXYGEN * @defgroup peer_id Peer IDs * @ingroup peer_manager * @{ @@ -46,6 +79,17 @@ void peer_id_init(void); pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id); +/**@brief Function for marking a peer ID for deletion. + * + * @param peer_id The peer ID to delete. + * + * @retval true Deletion was successful. + * @retval false Peer ID already marked for deletion, peer_id was PM_PEER_ID_INVALID, or module is + * not initialized. + */ +bool peer_id_delete(pm_peer_id_t peer_id); + + /**@brief Function for freeing a peer ID and clearing all data associated with it in persistent * storage. * @@ -54,6 +98,16 @@ pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id); void peer_id_free(pm_peer_id_t peer_id); +/**@brief Function for finding out whether a peer ID is marked for deletion. + * + * @param[in] peer_id The peer ID to inquire about. + * + * @retval true peer_id is in marked for deletion. + * @retval false peer_id is not marked for deletion, or the module is not initialized. + */ +bool peer_id_is_deleted(pm_peer_id_t peer_id); + + /**@brief Function for finding out whether a peer ID is in use. * * @param[in] peer_id The peer ID to inquire about. @@ -77,7 +131,23 @@ bool peer_id_is_allocated(pm_peer_id_t peer_id); * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module is * not initialized. */ -pm_peer_id_t peer_id_next_id_get(pm_peer_id_t prev_peer_id); +pm_peer_id_t peer_id_get_next_used(pm_peer_id_t prev_peer_id); + + +/**@brief Function for getting the next peer ID in the sequence of all peer IDs marked for deletion. + * Can be used to loop through all peer IDs marked for deletion. + * + * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary + * peer ID. + * + * @param[in] prev_peer_id The previous peer ID. + * + * @return The next peer ID. + * @return The first used peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID. + * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module is + * not initialized. + */ +pm_peer_id_t peer_id_get_next_deleted(pm_peer_id_t prev_peer_id); /**@brief Function for querying the number of valid peer IDs available. I.E the number of peers @@ -87,6 +157,13 @@ pm_peer_id_t peer_id_next_id_get(pm_peer_id_t prev_peer_id); */ uint32_t peer_id_n_ids(void); -/** @} */ +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif #endif /* PEER_ID_H__ */ diff --git a/components/ble/peer_manager/peer_manager.c b/components/ble/peer_manager/peer_manager.c index d48f511..cff2d84 100644 --- a/components/ble/peer_manager/peer_manager.c +++ b/components/ble/peer_manager/peer_manager.c @@ -1,132 +1,205 @@ -/* Copyright (C) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "peer_manager.h" #include #include "security_manager.h" +#include "security_dispatcher.h" #include "gatt_cache_manager.h" +#include "gatts_cache_manager.h" #include "peer_database.h" +#include "peer_data_storage.h" #include "id_manager.h" #include "ble_conn_state.h" +#include "peer_manager_internal.h" +/**< The number of event handlers that can be registered with the module. */ +#define MAX_REGISTRANTS (3) +/**< Macro indicating whether the module has been initialized properly. */ +#define MODULE_INITIALIZED (m_module_initialized) -#define MAX_REGISTRANTS 3 /**< The number of user that can register with the module. */ +static bool m_module_initialized; /**< Whether or not @ref pm_init has been called successfully. */ +static bool m_peer_rank_initialized; /**< Whether or not @ref rank_init has been called successfully. */ +static bool m_deleting_all; /**< True from when @ref pm_peers_delete is called until all peers have been deleted. */ +static pm_store_token_t m_peer_rank_token; /**< The store token of an ongoing peer rank update via a call to @ref pm_peer_rank_highest. If @ref PM_STORE_TOKEN_INVALID, there is no ongoing update. */ +static uint32_t m_current_highest_peer_rank; /**< The current highest peer rank. Used by @ref pm_peer_rank_highest. */ +static pm_peer_id_t m_highest_ranked_peer; /**< The peer with the highest peer rank. Used by @ref pm_peer_rank_highest. */ +static pm_evt_handler_t m_evt_handlers[MAX_REGISTRANTS]; /**< The subscribers to Peer Manager events, as registered through @ref pm_register. */ +static uint8_t m_n_registrants; /**< The number of event handlers registered through @ref pm_register. */ +static ble_conn_state_user_flag_id_t m_pairing_flag_id; /**< The flag ID for which connections are paired. */ +static ble_conn_state_user_flag_id_t m_bonding_flag_id; /**< The flag ID for which connections are bonded. */ -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * @ref NRF_ERROR_INVALID_STATE if not. - */ -#define VERIFY_MODULE_INITIALIZED() \ -do \ -{ \ - if (!m_pm.initialized) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * if not. - */ -#define VERIFY_MODULE_INITIALIZED_VOID()\ -do \ -{ \ - if (!m_pm.initialized) \ - { \ - return; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * if not. + +/**@brief Function for sending a Peer Manager event to all subscribers. * - * @param[in] param The variable to check if is NULL. + * @param[in] p_pm_evt The event to send. */ -#define VERIFY_PARAM_NOT_NULL(param) \ -do \ -{ \ - if (param == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } \ -} while(0) - - -typedef struct -{ - bool initialized; - pm_evt_handler_t evt_handlers[MAX_REGISTRANTS]; - uint8_t n_registrants; - ble_conn_state_user_flag_id_t pairing_flag_id; - ble_conn_state_user_flag_id_t bonding_flag_id; -} pm_t; - -static pm_t m_pm; - - -static void evt_send(pm_evt_t * p_event) +static void evt_send(pm_evt_t * p_pm_evt) { - for (int i = 0; i < m_pm.n_registrants; i++) + for (int i = 0; i < m_n_registrants; i++) { - m_pm.evt_handlers[i](p_event); + m_evt_handlers[i](p_pm_evt); } } -void pdb_evt_handler(pdb_evt_t const * p_evt) +/**@brief Event handler for events from the Peer Database module. + * This handler is extern in the Peer Database module. + * + * @param[in] p_pdb_evt The incoming Peer Database event. + */ +void pm_pdb_evt_handler(pdb_evt_t const * p_pdb_evt) { bool send_evt = true; pm_evt_t pm_evt; memset(&pm_evt, 0, sizeof(pm_evt_t)); - pm_evt.peer_id = p_evt->peer_id; + pm_evt.peer_id = p_pdb_evt->peer_id; pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id); - switch (p_evt->evt_id) + switch (p_pdb_evt->evt_id) { case PDB_EVT_WRITE_BUF_STORED: - pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED; - pm_evt.params.peer_data_updated_evt.data_id = p_evt->data_id; - pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_UPDATE; + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; + pm_evt.params.peer_data_update_succeeded.flash_changed = true; break; case PDB_EVT_RAW_STORED: - pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED; - pm_evt.params.peer_data_updated_evt.data_id = p_evt->data_id; - pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_UPDATE; + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.token + = p_pdb_evt->params.raw_stored_evt.store_token; + pm_evt.params.peer_data_update_succeeded.flash_changed = true; + + if ( (m_peer_rank_token != PM_STORE_TOKEN_INVALID) + && (m_peer_rank_token == p_pdb_evt->params.raw_stored_evt.store_token)) + { + m_peer_rank_token = PM_STORE_TOKEN_INVALID; + m_highest_ranked_peer = pm_evt.peer_id; + + pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; + } break; case PDB_EVT_RAW_STORE_FAILED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; - pm_evt.params.peer_data_update_failed_evt.data_id = p_evt->data_id; - pm_evt.params.peer_data_update_failed_evt.action = PM_PEER_DATA_ACTION_UPDATE; - pm_evt.params.peer_data_update_failed_evt.error = NRF_ERROR_INTERNAL; + pm_evt.params.peer_data_update_failed.data_id = p_pdb_evt->data_id; + pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_failed.token + = p_pdb_evt->params.error_raw_store_evt.store_token; + pm_evt.params.peer_data_update_failed.error + = p_pdb_evt->params.error_raw_store_evt.err_code; + + if ( (m_peer_rank_token != PM_STORE_TOKEN_INVALID) + && (m_peer_rank_token == p_pdb_evt->params.raw_stored_evt.store_token)) + { + m_peer_rank_token = PM_STORE_TOKEN_INVALID; + m_current_highest_peer_rank -= 1; + + pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; + } break; case PDB_EVT_CLEARED: - pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED; - pm_evt.params.peer_data_updated_evt.data_id = p_evt->data_id; - pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_CLEAR; + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.data_id = p_pdb_evt->data_id; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_DELETE; + pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; break; case PDB_EVT_CLEAR_FAILED: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; - pm_evt.params.peer_data_update_failed_evt.data_id = p_evt->data_id; - pm_evt.params.peer_data_update_failed_evt.action = PM_PEER_DATA_ACTION_CLEAR; - pm_evt.params.peer_data_update_failed_evt.error = NRF_ERROR_INTERNAL; + pm_evt.params.peer_data_update_failed.data_id = p_pdb_evt->data_id; + pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_DELETE; + pm_evt.params.peer_data_update_failed.error + = p_pdb_evt->params.clear_failed_evt.err_code; + break; + + case PDB_EVT_PEER_FREED: + pm_evt.evt_id = PM_EVT_PEER_DELETE_SUCCEEDED; + // Check that no peers marked for deletion are left. + if (m_deleting_all + && (pdb_next_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID) + && (pdb_next_deleted_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID)) + { + // pm_peers_delete() has been called and this is the last peer to be deleted. + m_deleting_all = false; + + pm_evt_t pm_delete_all_evt; + memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t)); + pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED; + pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID; + pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID; + + evt_send(&pm_delete_all_evt); + } + break; + + case PDB_EVT_PEER_FREE_FAILED: + pm_evt.evt_id = PM_EVT_PEER_DELETE_FAILED; + pm_evt.params.peer_delete_failed.error + = p_pdb_evt->params.peer_free_failed_evt.err_code; + if (m_deleting_all) + { + // pm_peers_delete() has been called and has thus failed. + + m_deleting_all = false; + + pm_evt_t pm_delete_all_evt; + memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t)); + pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_FAILED; + pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID; + pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID; + pm_delete_all_evt.params.peers_delete_failed_evt.error + = p_pdb_evt->params.peer_free_failed_evt.err_code; + + evt_send(&pm_delete_all_evt); + } break; case PDB_EVT_COMPRESSED: @@ -143,9 +216,10 @@ void pdb_evt_handler(pdb_evt_t const * p_evt) break; default: - /* No implementation necessary. */ + send_evt = false; break; } + if (send_evt) { evt_send(&pm_evt); @@ -153,7 +227,12 @@ void pdb_evt_handler(pdb_evt_t const * p_evt) } -void sm_evt_handler(sm_evt_t const * p_sm_evt) +/**@brief Event handler for events from the Security Manager module. + * This handler is extern in the Security Manager module. + * + * @param[in] p_sm_evt The incoming Security Manager event. + */ +void pm_sm_evt_handler(sm_evt_t const * p_sm_evt) { bool find_peer_id = true; bool send_evt = true; @@ -170,48 +249,46 @@ void sm_evt_handler(sm_evt_t const * p_sm_evt) case SM_EVT_SEC_PROCEDURE_START: { + pm_evt.evt_id = PM_EVT_CONN_SEC_START; bool pairing = p_sm_evt->params.sec_procedure_start.procedure != PM_LINK_SECURED_PROCEDURE_ENCRYPTION; bool bonding = p_sm_evt->params.sec_procedure_start.procedure == PM_LINK_SECURED_PROCEDURE_BONDING; - find_peer_id = false; - send_evt = false; - ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pm.pairing_flag_id, pairing); - ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pm.bonding_flag_id, bonding); + ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pairing_flag_id, pairing); + ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_bonding_flag_id, bonding); break; - } + case SM_EVT_PAIRING_SUCCESS: - pm_evt.evt_id = PM_EVT_LINK_SECURED; - pm_evt.params.link_secured_evt.procedure = + pm_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED; + pm_evt.params.conn_sec_succeeded.procedure = p_sm_evt->params.pairing_success.bonded ? PM_LINK_SECURED_PROCEDURE_BONDING : PM_LINK_SECURED_PROCEDURE_PAIRING; - ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pm.pairing_flag_id, true); + ble_conn_state_user_flag_set(p_sm_evt->conn_handle, m_pairing_flag_id, true); ble_conn_state_user_flag_set(p_sm_evt->conn_handle, - m_pm.bonding_flag_id, + m_bonding_flag_id, p_sm_evt->params.pairing_success.bonded ); break; case SM_EVT_PAIRING_FAIL: - pm_evt.evt_id = PM_EVT_LINK_SECURE_FAILED; - pm_evt.params.link_secure_failed_evt.procedure = - ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_pm.bonding_flag_id) + pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED; + pm_evt.params.conn_sec_failed.procedure = + ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_bonding_flag_id) ? PM_LINK_SECURED_PROCEDURE_BONDING : PM_LINK_SECURED_PROCEDURE_PAIRING; - pm_evt.params.link_secure_failed_evt.error.error_type = PM_ERROR_TYPE_SEC_STATUS; - pm_evt.params.link_secure_failed_evt.error.error_src + pm_evt.params.conn_sec_failed.error_src = p_sm_evt->params.pairing_failed.error_src; - pm_evt.params.link_secure_failed_evt.error.error.sec_status - = p_sm_evt->params.pairing_failed.auth_status; + pm_evt.params.conn_sec_failed.error + = p_sm_evt->params.pairing_failed.error; break; case SM_EVT_LINK_ENCRYPTION_UPDATE: - if (!ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_pm.pairing_flag_id)) + if (!ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_pairing_flag_id)) { - pm_evt.evt_id = PM_EVT_LINK_SECURED; - pm_evt.params.link_secured_evt.procedure = PM_LINK_SECURED_PROCEDURE_ENCRYPTION; + pm_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED; + pm_evt.params.conn_sec_succeeded.procedure = PM_LINK_SECURED_PROCEDURE_ENCRYPTION; } else { @@ -221,38 +298,36 @@ void sm_evt_handler(sm_evt_t const * p_sm_evt) break; case SM_EVT_LINK_ENCRYPTION_FAILED: - pm_evt.evt_id = PM_EVT_LINK_SECURE_FAILED; - pm_evt.params.link_secure_failed_evt.procedure + pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED; + pm_evt.params.conn_sec_failed.procedure = PM_LINK_SECURED_PROCEDURE_ENCRYPTION; - pm_evt.params.link_secure_failed_evt.error.error_type - = PM_ERROR_TYPE_PM_SEC_ERROR; - pm_evt.params.link_secure_failed_evt.error.error_src + pm_evt.params.conn_sec_failed.error_src = p_sm_evt->params.link_encryption_failed.error_src; - pm_evt.params.link_secure_failed_evt.error.error.sec_status + pm_evt.params.conn_sec_failed.error = p_sm_evt->params.link_encryption_failed.error; break; case SM_EVT_BONDING_INFO_STORED: - pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED; + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; pm_evt.peer_id = p_sm_evt->params.bonding_info_stored.peer_id; - pm_evt.params.peer_data_updated_evt.data_id = PM_PEER_DATA_ID_BONDING; - pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_UPDATE; + pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_BONDING; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; find_peer_id = false; break; case SM_EVT_ERROR_BONDING_INFO: pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED; pm_evt.peer_id = p_sm_evt->params.error_bonding_info.peer_id; - pm_evt.params.peer_data_update_failed_evt.data_id = PM_PEER_DATA_ID_BONDING; - pm_evt.params.peer_data_update_failed_evt.action = PM_PEER_DATA_ACTION_UPDATE; - pm_evt.params.peer_data_update_failed_evt.error + pm_evt.params.peer_data_update_failed.data_id = PM_PEER_DATA_ID_BONDING; + pm_evt.params.peer_data_update_failed.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_failed.error = p_sm_evt->params.error_bonding_info.error; find_peer_id = false; break; case SM_EVT_ERROR_UNEXPECTED: pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED; - pm_evt.params.error_unexpected_evt.error = p_sm_evt->params.error_unexpected.error; + pm_evt.params.error_unexpected.error = p_sm_evt->params.error_unexpected.error; break; case SM_EVT_ERROR_NO_MEM: @@ -260,15 +335,21 @@ void sm_evt_handler(sm_evt_t const * p_sm_evt) break; case SM_EVT_ERROR_SMP_TIMEOUT: - pm_evt.evt_id = PM_EVT_LINK_SECURE_FAILED; - pm_evt.params.link_secure_failed_evt.procedure - = ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_pm.bonding_flag_id) + pm_evt.evt_id = PM_EVT_CONN_SEC_FAILED; + pm_evt.params.conn_sec_failed.procedure + = ble_conn_state_user_flag_get(p_sm_evt->conn_handle, m_bonding_flag_id) ? PM_LINK_SECURED_PROCEDURE_BONDING : PM_LINK_SECURED_PROCEDURE_PAIRING; - pm_evt.params.link_secure_failed_evt.error.error_type = PM_ERROR_TYPE_PM_SEC_ERROR; - pm_evt.params.link_secure_failed_evt.error.error_src = BLE_GAP_SEC_STATUS_SOURCE_LOCAL; - pm_evt.params.link_secure_failed_evt.error.error.pm_sec_error - = PM_SEC_ERROR_SMP_TIMEOUT; + pm_evt.params.conn_sec_failed.error_src = BLE_GAP_SEC_STATUS_SOURCE_LOCAL; + pm_evt.params.conn_sec_failed.error = PM_CONN_SEC_ERROR_SMP_TIMEOUT; + break; + + case SM_EVT_CONN_SEC_CONFIG_REQ: + pm_evt.evt_id = PM_EVT_CONN_SEC_CONFIG_REQ; + break; + + default: + send_evt = false; break; } @@ -284,50 +365,54 @@ void sm_evt_handler(sm_evt_t const * p_sm_evt) } -void gcm_evt_handler(gcm_evt_t const * p_evt) +/**@brief Event handler for events from the GATT Cache Manager module. + * This handler is extern in GATT Cache Manager. + * + * @param[in] p_gcm_evt The incoming GATT Cache Manager event. + */ +void pm_gcm_evt_handler(gcm_evt_t const * p_gcm_evt) { - bool send_evt = true; pm_evt_t pm_evt; memset(&pm_evt, 0, sizeof(pm_evt_t)); - pm_evt.peer_id = p_evt->peer_id; + pm_evt.peer_id = p_gcm_evt->peer_id; pm_evt.conn_handle = im_conn_handle_get(pm_evt.peer_id); - switch (p_evt->evt_id) + switch (p_gcm_evt->evt_id) { case GCM_EVT_LOCAL_DB_CACHE_STORED: - pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED; - pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_UPDATE; - pm_evt.params.peer_data_updated_evt.data_id = PM_PEER_DATA_ID_GATT_LOCAL; + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_LOCAL; break; case GCM_EVT_LOCAL_DB_CACHE_UPDATED: - pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED; - pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_UPDATE; - pm_evt.params.peer_data_updated_evt.data_id = PM_PEER_DATA_ID_GATT_LOCAL; + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_LOCAL; break; case GCM_EVT_LOCAL_DB_CACHE_APPLIED: pm_evt.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLIED; - pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_UPDATE; - pm_evt.params.peer_data_updated_evt.data_id = PM_PEER_DATA_ID_GATT_LOCAL; break; case GCM_EVT_ERROR_LOCAL_DB_CACHE_APPLY: - pm_evt.evt_id = PM_EVT_ERROR_LOCAL_DB_CACHE_APPLY; - pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_UPDATE; - pm_evt.params.peer_data_updated_evt.data_id = PM_PEER_DATA_ID_GATT_LOCAL; + pm_evt.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED; break; case GCM_EVT_REMOTE_DB_CACHE_UPDATED: - pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATED; - pm_evt.params.peer_data_updated_evt.action = PM_PEER_DATA_ACTION_UPDATE; - pm_evt.params.peer_data_updated_evt.data_id = PM_PEER_DATA_ID_GATT_REMOTE; + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_GATT_REMOTE; + break; + + case GCM_EVT_SERVICE_CHANGED_IND_SENT: + pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_IND_SENT; break; - case GCM_EVT_SERVICE_CHANGED_INDICATION_SENT: - pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_INDICATION_SENT; + case GCM_EVT_SERVICE_CHANGED_IND_CONFIRMED: + pm_evt.evt_id = PM_EVT_SERVICE_CHANGED_IND_CONFIRMED; break; case GCM_EVT_ERROR_DATA_SIZE: @@ -340,8 +425,8 @@ void gcm_evt_handler(gcm_evt_t const * p_evt) case GCM_EVT_ERROR_UNEXPECTED: pm_evt.evt_id = PM_EVT_ERROR_UNEXPECTED; - pm_evt.params.error_unexpected_evt.error = p_evt->params.error_unexpected.error; - pm_evt.conn_handle = p_evt->params.error_unexpected.conn_handle; + pm_evt.params.error_unexpected.error = p_gcm_evt->params.error_unexpected.error; + pm_evt.conn_handle = p_gcm_evt->params.error_unexpected.conn_handle; break; } @@ -352,22 +437,30 @@ void gcm_evt_handler(gcm_evt_t const * p_evt) } -void im_evt_handler(im_evt_t const * p_evt) +/**@brief Event handler for events from the ID Manager module. + * This function is registered in the ID Manager. + * + * @param[in] p_im_evt The incoming ID Manager event. + */ +void pm_im_evt_handler(im_evt_t const * p_im_evt) { pm_evt_t pm_evt; + ret_code_t err_code; - switch (p_evt->evt_id) + switch (p_im_evt->evt_id) { case IM_EVT_DUPLICATE_ID: - // Delete the duplicate data to free space and avoid finding old data when scanning in the future - pm_peer_delete(p_evt->params.duplicate_id.peer_id_2); + // Attempt to delete the duplicate data to free space and avoid finding old data when + // scanning in the future + err_code = pm_peer_delete(p_im_evt->params.duplicate_id.peer_id_2); + UNUSED_VARIABLE(err_code); break; case IM_EVT_BONDED_PEER_CONNECTED: - ble_conn_state_user_flag_set(p_evt->conn_handle, m_pm.bonding_flag_id, true); + ble_conn_state_user_flag_set(p_im_evt->conn_handle, m_bonding_flag_id, true); memset(&pm_evt, 0, sizeof(pm_evt_t)); - pm_evt.conn_handle = p_evt->conn_handle; - pm_evt.peer_id = im_peer_id_get_by_conn_handle(p_evt->conn_handle); + pm_evt.conn_handle = p_im_evt->conn_handle; + pm_evt.peer_id = im_peer_id_get_by_conn_handle(p_im_evt->conn_handle); pm_evt.evt_id = PM_EVT_BONDED_PEER_CONNECTED; evt_send(&pm_evt); break; @@ -375,7 +468,7 @@ void im_evt_handler(im_evt_t const * p_evt) } -void pm_ble_evt_handler(ble_evt_t * p_ble_evt) +void pm_on_ble_evt(ble_evt_t * p_ble_evt) { VERIFY_MODULE_INITIALIZED_VOID(); @@ -385,51 +478,79 @@ void pm_ble_evt_handler(ble_evt_t * p_ble_evt) } +/**@brief Function for resetting the internal state of this module. + */ +static void internal_state_reset() +{ + m_highest_ranked_peer = PM_PEER_ID_INVALID; + m_peer_rank_token = PM_STORE_TOKEN_INVALID; + m_pairing_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID; + m_bonding_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID; +} + + ret_code_t pm_init(void) { ret_code_t err_code; - err_code = pdb_register(pdb_evt_handler); + err_code = pds_init(); if (err_code != NRF_SUCCESS) { - if (err_code != NRF_ERROR_INVALID_STATE) - { - err_code = NRF_ERROR_INTERNAL; - } - return err_code; + return NRF_ERROR_INTERNAL; } - err_code = sm_register(sm_evt_handler); + err_code = pdb_init(); if (err_code != NRF_SUCCESS) { return NRF_ERROR_INTERNAL; } - err_code = gcm_init(gcm_evt_handler); + err_code = sm_init(); if (err_code != NRF_SUCCESS) { return NRF_ERROR_INTERNAL; } - err_code = im_register(im_evt_handler); + err_code = smd_init(); if (err_code != NRF_SUCCESS) { return NRF_ERROR_INTERNAL; } - m_pm.pairing_flag_id = ble_conn_state_user_flag_acquire(); - if (m_pm.pairing_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) + err_code = gcm_init(); + if (err_code != NRF_SUCCESS) { return NRF_ERROR_INTERNAL; } - m_pm.bonding_flag_id = ble_conn_state_user_flag_acquire(); - if (m_pm.bonding_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) + err_code = gscm_init(); + if (err_code != NRF_SUCCESS) { return NRF_ERROR_INTERNAL; } - m_pm.initialized = true; + err_code = im_init(); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + internal_state_reset(); + + m_pairing_flag_id = ble_conn_state_user_flag_acquire(); + if (m_pairing_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) + { + return NRF_ERROR_INTERNAL; + } + + m_bonding_flag_id = ble_conn_state_user_flag_acquire(); + if (m_bonding_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) + { + return NRF_ERROR_INTERNAL; + } + + m_peer_rank_initialized = false; + m_module_initialized = true; return NRF_SUCCESS; } @@ -439,13 +560,13 @@ ret_code_t pm_register(pm_evt_handler_t event_handler) { VERIFY_MODULE_INITIALIZED(); - if (m_pm.n_registrants >= MAX_REGISTRANTS) + if (m_n_registrants >= MAX_REGISTRANTS) { return NRF_ERROR_NO_MEM; } - m_pm.evt_handlers[m_pm.n_registrants] = event_handler; - m_pm.n_registrants += 1; + m_evt_handlers[m_n_registrants] = event_handler; + m_n_registrants += 1; return NRF_SUCCESS; } @@ -459,16 +580,13 @@ ret_code_t pm_sec_params_set(ble_gap_sec_params_t * p_sec_params) err_code = sm_sec_params_set(p_sec_params); - if (err_code == NRF_ERROR_INVALID_STATE) - { - err_code = NRF_ERROR_INTERNAL; - } - + // NRF_ERROR_INVALID_PARAM if parameters are invalid, + // NRF_SUCCESS otherwise. return err_code; } -ret_code_t pm_link_secure(uint16_t conn_handle, bool force_repairing) +ret_code_t pm_conn_secure(uint16_t conn_handle, bool force_repairing) { VERIFY_MODULE_INITIALIZED(); @@ -480,139 +598,526 @@ ret_code_t pm_link_secure(uint16_t conn_handle, bool force_repairing) } +void pm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config) +{ + sm_conn_sec_config_reply(conn_handle, p_conn_sec_config); +} + + ret_code_t pm_sec_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params) { + VERIFY_MODULE_INITIALIZED(); return NRF_SUCCESS; } void pm_local_database_has_changed(void) { + VERIFY_MODULE_INITIALIZED_VOID(); gcm_local_database_has_changed(); } -ret_code_t pm_wlist_create(pm_peer_id_t * p_peer_ids, - uint8_t n_peer_ids, - ble_gap_whitelist_t * p_whitelist) +ret_code_t pm_id_addr_set(ble_gap_addr_t const * p_addr) +{ + VERIFY_MODULE_INITIALIZED(); + return im_id_addr_set(p_addr); +} + + +ret_code_t pm_id_addr_get(ble_gap_addr_t * p_addr) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_addr); + return im_id_addr_get(p_addr); +} + + +ret_code_t pm_privacy_set(pm_privacy_params_t const * p_privacy_params) { - return im_wlist_create(p_peer_ids, n_peer_ids, p_whitelist); + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_privacy_params); + return im_privacy_set(p_privacy_params); } -ret_code_t pm_wlist_set(ble_gap_whitelist_t * p_whitelist) +ret_code_t pm_privacy_get(pm_privacy_params_t * p_privacy_params) { - return im_wlist_set(p_whitelist); + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_privacy_params); + VERIFY_PARAM_NOT_NULL(p_privacy_params->p_device_irk); + return im_privacy_get(p_privacy_params); } -ret_code_t pm_link_status_get(uint16_t conn_handle, pm_link_status_t * p_link_status) +ret_code_t pm_whitelist_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt) { - VERIFY_PARAM_NOT_NULL(p_link_status); - if (conn_handle == BLE_CONN_HANDLE_INVALID) + VERIFY_MODULE_INITIALIZED(); + return im_whitelist_set(p_peers, peer_cnt); +} + + +ret_code_t pm_whitelist_get(ble_gap_addr_t * p_addrs, + uint32_t * p_addr_cnt, + ble_gap_irk_t * p_irks, + uint32_t * p_irk_cnt) +{ + VERIFY_MODULE_INITIALIZED(); + + if (((p_addrs == NULL) && (p_irks == NULL)) || + ((p_addrs != NULL) && (p_addr_cnt == NULL)) || + ((p_irks != NULL) && (p_irk_cnt == NULL))) { - return NRF_ERROR_INVALID_PARAM; + // The buffers can't be both NULL, and if a buffer is provided its size must be specified. + return NRF_ERROR_NULL; } - // Read the bonded status from the user flag that is maintained by events. - p_link_status->bonded = ble_conn_state_user_flag_get(conn_handle, m_pm.bonding_flag_id); - // Read the connected, encrypted and mitm status from the connection state module. - p_link_status->connected = ble_conn_state_valid(conn_handle); - p_link_status->encrypted = ble_conn_state_encrypted(conn_handle); - p_link_status->mitm_protected = ble_conn_state_mitm_protected(conn_handle); - return NRF_SUCCESS; + + return im_whitelist_get(p_addrs, p_addr_cnt, p_irks, p_irk_cnt); } -ret_code_t pm_peer_id_get(uint16_t conn_handle, pm_peer_id_t * p_peer_id) +ret_code_t pm_device_identities_list_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt) { - VERIFY_PARAM_NOT_NULL(p_peer_id); - * p_peer_id = im_peer_id_get_by_conn_handle(conn_handle); + VERIFY_MODULE_INITIALIZED(); + return im_device_identities_list_set(p_peers, peer_cnt); +} + + +ret_code_t pm_conn_sec_status_get(uint16_t conn_handle, pm_conn_sec_status_t * p_conn_sec_status) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_conn_sec_status); + + ble_conn_state_status_t status = ble_conn_state_status(conn_handle); + + if (status == BLE_CONN_STATUS_INVALID) + { + return BLE_ERROR_INVALID_CONN_HANDLE; + } + + p_conn_sec_status->connected = (status == BLE_CONN_STATUS_CONNECTED); + p_conn_sec_status->bonded = ble_conn_state_user_flag_get(conn_handle, m_bonding_flag_id); + p_conn_sec_status->encrypted = ble_conn_state_encrypted(conn_handle); + p_conn_sec_status->mitm_protected = ble_conn_state_mitm_protected(conn_handle); return NRF_SUCCESS; } +ret_code_t pm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key) +{ + VERIFY_MODULE_INITIALIZED(); + return sm_lesc_public_key_set(p_public_key); +} + + ret_code_t pm_conn_handle_get(pm_peer_id_t peer_id, uint16_t * p_conn_handle) { + VERIFY_MODULE_INITIALIZED(); VERIFY_PARAM_NOT_NULL(p_conn_handle); - * p_conn_handle = im_conn_handle_get(peer_id); + *p_conn_handle = im_conn_handle_get(peer_id); return NRF_SUCCESS; } -uint32_t pm_n_peers(void) +ret_code_t pm_peer_id_get(uint16_t conn_handle, pm_peer_id_t * p_peer_id) { + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_peer_id); + *p_peer_id = im_peer_id_get_by_conn_handle(conn_handle); + return NRF_SUCCESS; +} + + +uint32_t pm_peer_count(void) +{ + if (!MODULE_INITIALIZED) + { + return 0; + } return pdb_n_peers(); } pm_peer_id_t pm_next_peer_id_get(pm_peer_id_t prev_peer_id) { + if (!MODULE_INITIALIZED) + { + return PM_PEER_ID_INVALID; + } return pdb_next_peer_id_get(prev_peer_id); } -ret_code_t pm_peer_data_get(pm_peer_id_t peer_id, pm_peer_data_id_t data_id, pm_peer_data_t * p_peer_data) +ret_code_t pm_peer_data_load(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + void * p_data, + uint16_t * p_length) +{ + VERIFY_MODULE_INITIALIZED(); + VERIFY_PARAM_NOT_NULL(p_data); + VERIFY_PARAM_NOT_NULL(p_length); + if (ALIGN_NUM(4, *p_length) != *p_length) + { + return NRF_ERROR_INVALID_PARAM; + } + + pm_peer_data_t peer_data; + memset(&peer_data, 0, sizeof(peer_data)); + peer_data.length_words = BYTES_TO_WORDS(*p_length); + peer_data.data_id = data_id; + peer_data.p_all_data = p_data; + + ret_code_t err_code = pdb_peer_data_load(peer_id, data_id, &peer_data); + + *p_length = peer_data.length_words * BYTES_PER_WORD; + + return err_code; +} + + +ret_code_t pm_peer_data_bonding_load(pm_peer_id_t peer_id, + pm_peer_data_bonding_t * p_data) { - return pdb_raw_read(peer_id, data_id, p_peer_data); + uint16_t length = sizeof(pm_peer_data_bonding_t); + return pm_peer_data_load(peer_id, + PM_PEER_DATA_ID_BONDING, + p_data, + &length); } -ret_code_t pm_peer_data_store(pm_peer_id_t peer_id, - pm_peer_data_const_t * p_peer_data, - pm_store_token_t * p_token) +ret_code_t pm_peer_data_remote_db_load(pm_peer_id_t peer_id, + ble_gatt_db_srv_t * p_data, + uint16_t * p_length) { - return pdb_raw_store(peer_id, p_peer_data, p_token); + return pm_peer_data_load(peer_id, + PM_PEER_DATA_ID_GATT_REMOTE, + p_data, + p_length); } -ret_code_t pm_peer_data_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) +ret_code_t pm_peer_data_app_data_load(pm_peer_id_t peer_id, + uint8_t * p_data, + uint16_t * p_length) +{ + return pm_peer_data_load(peer_id, + PM_PEER_DATA_ID_APPLICATION, + p_data, + p_length); +} + + +ret_code_t pm_peer_data_store(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + void const * p_data, + uint16_t length, + pm_store_token_t * p_token) { - ret_code_t err_code; VERIFY_MODULE_INITIALIZED(); - if (data_id == PM_PEER_DATA_ID_BONDING || data_id == PM_PEER_DATA_ID_INVALID) + VERIFY_PARAM_NOT_NULL(p_data); + if (ALIGN_NUM(4, length) != length) { return NRF_ERROR_INVALID_PARAM; } - err_code = pdb_clear(peer_id, data_id); - return err_code; + + pm_peer_data_flash_t peer_data; + memset(&peer_data, 0, sizeof(peer_data)); + peer_data.length_words = BYTES_TO_WORDS(length); + peer_data.data_id = data_id; + peer_data.p_all_data = p_data; + + return pdb_raw_store(peer_id, &peer_data, p_token); +} + + +ret_code_t pm_peer_data_bonding_store(pm_peer_id_t peer_id, + pm_peer_data_bonding_t const * p_data, + pm_store_token_t * p_token) +{ + return pm_peer_data_store(peer_id, + PM_PEER_DATA_ID_BONDING, + p_data, + ALIGN_NUM(4, sizeof(pm_peer_data_bonding_t)), + p_token); } -ret_code_t pm_peer_new(pm_peer_data_bonding_t * p_bonding_data, - pm_peer_id_t * p_new_peer_id, - pm_store_token_t * p_token) +ret_code_t pm_peer_data_remote_db_store(pm_peer_id_t peer_id, + ble_gatt_db_srv_t const * p_data, + uint16_t length, + pm_store_token_t * p_token) +{ + return pm_peer_data_store(peer_id, + PM_PEER_DATA_ID_GATT_REMOTE, + p_data, + length, + p_token); +} + + +ret_code_t pm_peer_data_app_data_store(pm_peer_id_t peer_id, + uint8_t const * p_data, + uint16_t length, + pm_store_token_t * p_token) +{ + return pm_peer_data_store(peer_id, + PM_PEER_DATA_ID_APPLICATION, + p_data, + length, + p_token); +} + + +ret_code_t pm_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id) { + VERIFY_MODULE_INITIALIZED(); + + if (data_id == PM_PEER_DATA_ID_BONDING) + { + return NRF_ERROR_INVALID_PARAM; + } + + return pdb_clear(peer_id, data_id); +} + + +ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id, + pm_peer_data_bonding_t * p_bonding_data, + pm_store_token_t * p_token) +{ + ret_code_t err_code; + pm_peer_id_t peer_id; + pm_peer_data_flash_t peer_data; + VERIFY_MODULE_INITIALIZED(); VERIFY_PARAM_NOT_NULL(p_bonding_data); VERIFY_PARAM_NOT_NULL(p_new_peer_id); - * p_new_peer_id = pdb_peer_allocate(); - if (* p_new_peer_id == PM_PEER_ID_INVALID) + + memset(&peer_data, 0, sizeof(pm_peer_data_flash_t)); + + // Search through existing bonds to look for a duplicate. + pds_peer_data_iterate_prepare(); + + // @note emdi: should maybe use a critical section, since data is not copied while iterating. + while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data)) + { + if (im_is_duplicate_bonding_data(p_bonding_data, peer_data.p_bonding_data)) + { + *p_new_peer_id = peer_id; + return NRF_SUCCESS; + } + } + + // If no duplicate data is found, prepare to write a new bond to flash. + + *p_new_peer_id = pdb_peer_allocate(); + + if (*p_new_peer_id == PM_PEER_ID_INVALID) { return NRF_ERROR_NO_MEM; } - pm_peer_data_const_t peer_data; - memset(&peer_data, 0, sizeof(pm_peer_data_const_t)); - peer_data.length_words = PM_BONDING_DATA_N_WORDS(); - peer_data.data_type = PM_PEER_DATA_ID_BONDING; - peer_data.data.p_bonding_data = p_bonding_data; + memset(&peer_data, 0, sizeof(pm_peer_data_flash_t)); + + peer_data.data_id = PM_PEER_DATA_ID_BONDING; + peer_data.p_bonding_data = p_bonding_data; + peer_data.length_words = BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t)); + + err_code = pdb_raw_store(*p_new_peer_id, &peer_data, p_token); + + if (err_code != NRF_SUCCESS) + { + if (im_peer_free(*p_new_peer_id) != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } - return pm_peer_data_store(*p_new_peer_id, &peer_data, p_token); + // NRF_ERROR_STORAGE_FULL, if no space in flash. + // NRF_ERROR_BUSY, if flash filesystem was busy. + // NRF_ERROR_INTENRAL, on internal error. + return err_code; + } + + return NRF_SUCCESS; } -void pm_peer_delete(pm_peer_id_t peer_id) +ret_code_t pm_peer_delete(pm_peer_id_t peer_id) { - pdb_peer_free(peer_id); + VERIFY_MODULE_INITIALIZED(); + + return im_peer_free(peer_id); } -void pm_peer_delete_all(void) +ret_code_t pm_peers_delete(void) { - pm_peer_id_t current_peer_id = PM_PEER_ID_INVALID; - while (pdb_next_peer_id_get(PM_PEER_ID_INVALID) != PM_PEER_ID_INVALID) + VERIFY_MODULE_INITIALIZED(); + + m_deleting_all = true; + + pm_peer_id_t current_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); + while (current_peer_id != PM_PEER_ID_INVALID) { + ret_code_t err_code = pm_peer_delete(current_peer_id); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + current_peer_id = pdb_next_peer_id_get(current_peer_id); - pm_peer_delete(current_peer_id); } + + return NRF_SUCCESS; +} + + +ret_code_t pm_peer_ranks_get(pm_peer_id_t * p_highest_ranked_peer, + uint32_t * p_highest_rank, + pm_peer_id_t * p_lowest_ranked_peer, + uint32_t * p_lowest_rank) +{ + VERIFY_MODULE_INITIALIZED(); + + pm_peer_id_t peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID); + uint32_t peer_rank = 0; + //lint -save -e65 -e64 + pm_peer_data_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(peer_rank)), + .p_peer_rank = &peer_rank}; + //lint -restore + ret_code_t err_code = pdb_peer_data_load(peer_id, PM_PEER_DATA_ID_PEER_RANK, &peer_data); + uint32_t highest_rank = 0; + uint32_t lowest_rank = 0xFFFFFFFF; + pm_peer_id_t highest_ranked_peer = PM_PEER_ID_INVALID; + pm_peer_id_t lowest_ranked_peer = PM_PEER_ID_INVALID; + + if (err_code == NRF_ERROR_INVALID_PARAM) + { + // No peer IDs exist. + return NRF_ERROR_NOT_FOUND; + } + + while ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND)) + { + if (err_code == NRF_ERROR_NOT_FOUND) + { + peer_rank = 0; + } + if (peer_rank >= highest_rank) + { + highest_rank = peer_rank; + highest_ranked_peer = peer_id; + } + if (peer_rank < lowest_rank) + { + lowest_rank = peer_rank; + lowest_ranked_peer = peer_id; + } + peer_id = pdb_next_peer_id_get(peer_id); + err_code = pdb_peer_data_load(peer_id, PM_PEER_DATA_ID_PEER_RANK, &peer_data); + } + if (peer_id == PM_PEER_ID_INVALID) + { + err_code = NRF_SUCCESS; + if (p_highest_ranked_peer != NULL) + { + *p_highest_ranked_peer = highest_ranked_peer; + } + if (p_highest_rank != NULL) + { + *p_highest_rank = highest_rank; + } + if (p_lowest_ranked_peer != NULL) + { + *p_lowest_ranked_peer = lowest_ranked_peer; + } + if (p_lowest_rank != NULL) + { + *p_lowest_rank = lowest_rank; + } + } + else + { + err_code = NRF_ERROR_INTERNAL; + } + return err_code; +} + + +/**@brief Function for initializing peer rank statistics. + */ +static void rank_init(void) +{ + ret_code_t err_code = pm_peer_ranks_get(&m_highest_ranked_peer, + &m_current_highest_peer_rank, + NULL, + NULL); + if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND)) + { + m_peer_rank_initialized = true; + } +} + + +ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id) +{ + VERIFY_MODULE_INITIALIZED(); + + ret_code_t err_code; + //lint -save -e65 -e64 + pm_peer_data_flash_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(m_current_highest_peer_rank)), + .data_id = PM_PEER_DATA_ID_PEER_RANK, + .p_peer_rank = &m_current_highest_peer_rank}; + //lint -restore + + + if (!m_peer_rank_initialized) + { + rank_init(); + } + + if (!m_peer_rank_initialized || (m_peer_rank_token != PM_STORE_TOKEN_INVALID)) + { + err_code = NRF_ERROR_BUSY; + } + else + { + if ((peer_id == m_highest_ranked_peer) && (m_current_highest_peer_rank > 0)) + { + pm_evt_t pm_evt; + + // The reported peer is already regarded as highest (provided it has an index at all) + err_code = NRF_SUCCESS; + + memset(&pm_evt, 0, sizeof(pm_evt)); + pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED; + pm_evt.conn_handle = im_conn_handle_get(peer_id); + pm_evt.peer_id = peer_id; + pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_PEER_RANK; + pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE; + pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID; + pm_evt.params.peer_data_update_succeeded.flash_changed = false; + + evt_send(&pm_evt); + } + else + { + m_current_highest_peer_rank += 1; + err_code = pdb_raw_store(peer_id, &peer_data, &m_peer_rank_token); + if (err_code != NRF_SUCCESS) + { + m_peer_rank_token = PM_STORE_TOKEN_INVALID; + m_current_highest_peer_rank -= 1; + { + if ((err_code != NRF_ERROR_BUSY) && (err_code != NRF_ERROR_STORAGE_FULL)) + err_code = NRF_ERROR_INTERNAL; + } + } + } + } + return err_code; } +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/peer_manager.h b/components/ble/peer_manager/peer_manager.h index 26506fe..a98194a 100644 --- a/components/ble/peer_manager/peer_manager.h +++ b/components/ble/peer_manager/peer_manager.h @@ -1,26 +1,60 @@ -/* Copyright (C) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 peer_manager.h * * @defgroup peer_manager Peer Manager * @ingroup ble_sdk_lib * @{ - * @brief A module for managing BLE bonding. This involves controlling encryption and pairing + * @brief Module for managing BLE bonding, which includes controlling encryption and pairing * procedures as well as persistently storing different pieces of data that must be stored * when bonded. * - * @details The API consists of functions for configuring the pairing/encryption behavior of the - * device, and functions for manipulation of the stored data. + * @details The API consists of functions for configuring the pairing and encryption behavior of the + * device and functions for manipulating the stored data. + * + * This module uses Flash Data Storage (FDS) to interface with persistent storage. The + * Peer Manager needs exclusive use of certain FDS file IDs and record keys. See + * @ref lib_fds_functionality_keys for more information. */ @@ -35,236 +69,257 @@ #include "peer_manager_types.h" #include "peer_database.h" +#ifdef __cplusplus +extern "C" { +#endif -/**@brief Structure used to report the security status of a connection. - */ -typedef struct -{ - uint8_t connected : 1; /**< This connection is active. */ - uint8_t encrypted : 1; /**< Communication on this link is/was encrypted. */ - uint8_t mitm_protected : 1; /**< The encrypted communication is/was also protected against man-in-the-middle attacks. */ - uint8_t bonded : 1; /**< The peer is bonded with us. */ -} pm_link_status_t; - - -/**@brief Enum of the events that can come from the @ref peer_manager module. - */ -typedef enum -{ - PM_EVT_BONDED_PEER_CONNECTED, /**< A connected peer has been identified as one with which we have a bond. */ - PM_EVT_LINK_SECURED, /**< A link has been encrypted, either as a result of a call to @ref pm_link_secure, or of action by the peer. The event structure contains more information about the circumstances. */ - PM_EVT_LINK_SECURE_FAILED, /**< A pairing or encryption procedure has failed. In most cases, this will mean that security is not possible on this link. */ - // PM_EVT_SEC_PARAMS_REQ, /**< Not yet implemented. The specified link is being secured. Please respond, using pm_sec_params_reply(), with the desired security parameters for this link. */ - PM_EVT_STORAGE_FULL, /**< There is no more room for peer data in flash storage. This must be mitigated by performing a compress procedure in FDS, possibly preceded by deleting some information. */ - PM_EVT_ERROR_UNEXPECTED, /**< An operation failed with an unexpected error. The error is provided. This is possibly a fatal error. */ - PM_EVT_PEER_DATA_UPDATED, /**< A piece of peer data was stored, updated, or cleared in flash storage. */ - PM_EVT_PEER_DATA_UPDATE_FAILED, /**< A piece of peer data was attempted stored, updated, or cleared in flash storage, but failed. */ - // PM_EVT_ALL_PEER_DATA_DELETED, /**< Not yet implemented. A call to @ref pm_peer_delete_all has completed successfully. It is now safe to create BLE links. */ - PM_EVT_ERROR_LOCAL_DB_CACHE_APPLY, /**< The stored local database values for a peer were rejected by the SoftDevice, which means the database has changed. */ - PM_EVT_LOCAL_DB_CACHE_APPLIED, /**< The SoftDevice has been given local database values from the persistent cache, for one peer. */ - PM_EVT_SERVICE_CHANGED_INDICATION_SENT, /**< A service changed indication has been sent to and confirmed by a peer. */ -} pm_evt_id_t; - -/**@brief Structure containing parameters specific to the @ref PM_EVT_LINK_SECURED event. +/**@brief Security status of a connection. */ typedef struct { - pm_sec_procedure_t procedure; /**< The procedure that led to securing the link. */ -} pm_link_secured_evt_t; + uint8_t connected : 1; /**< @brief The connection is active (not disconnected). */ + uint8_t encrypted : 1; /**< @brief Communication on this link is encrypted. */ + uint8_t mitm_protected : 1; /**< @brief The encrypted communication is also protected against man-in-the-middle attacks. */ + uint8_t bonded : 1; /**< @brief The peer is bonded with us. */ +} pm_conn_sec_status_t; -/**@brief The different types of errors that can cause security establishment to fail. +/**@brief Types of events that can come from the @ref peer_manager module. */ typedef enum { - PM_ERROR_TYPE_SEC_STATUS, /**< Error is in the range defined in @ref BLE_GAP_SEC_STATUS. */ - PM_ERROR_TYPE_PM_SEC_ERROR, /**< Error is of type @ref pm_sec_error_code_t. */ -} pm_error_type_t; + PM_EVT_BONDED_PEER_CONNECTED, /**< @brief A connected peer has been identified as one with which we have a bond. When performing bonding with a peer for the first time, this event will not be sent until a new connection is established with the peer. When we are central, this event is always sent when the Peer Manager receives the @ref BLE_GAP_EVT_CONNECTED event. When we are peripheral, this event might in rare cases arrive later. */ + PM_EVT_CONN_SEC_START, /**< @brief A security procedure has started on a link, initiated either locally or remotely. The security procedure is using the last parameters provided via @ref pm_sec_params_set. This event is always followed by either a @ref PM_EVT_CONN_SEC_SUCCEEDED or a @ref PM_EVT_CONN_SEC_FAILED event. This is an informational event; no action is needed for the procedure to proceed. */ + PM_EVT_CONN_SEC_SUCCEEDED, /**< @brief A link has been encrypted, either as a result of a call to @ref pm_conn_secure or a result of an action by the peer. The event structure contains more information about the circumstances. This event might contain a peer ID with the value @ref PM_PEER_ID_INVALID, which means that the peer (central) used an address that could not be identified, but it used an encryption key (LTK) that is present in the database. */ + PM_EVT_CONN_SEC_FAILED, /**< @brief A pairing or encryption procedure has failed. In some cases, this means that security is not possible on this link (temporarily or permanently). How to handle this error depends on the application. */ + PM_EVT_CONN_SEC_CONFIG_REQ, /**< @brief The peer (central) has requested pairing, but a bond already exists with that peer. Reply by calling @ref pm_conn_sec_config_reply before the event handler returns. If no reply is sent, a default is used. */ + PM_EVT_STORAGE_FULL, /**< @brief There is no more room for peer data in flash storage. To solve this problem, delete data that is not needed anymore and run a garbage collection procedure in FDS. */ + PM_EVT_ERROR_UNEXPECTED, /**< @brief An unrecoverable error happened inside Peer Manager. An operation failed with the provided error. */ + PM_EVT_PEER_DATA_UPDATE_SUCCEEDED, /**< @brief A piece of peer data was stored, updated, or cleared in flash storage. This event is sent for all successful changes to peer data, also those initiated internally in Peer Manager. To identify an operation, compare the store token in the event with the store token received during the initiating function call. Events from internally initiated changes might have invalid store tokens. */ + PM_EVT_PEER_DATA_UPDATE_FAILED, /**< @brief A piece of peer data could not be stored, updated, or cleared in flash storage. This event is sent instead of @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED for the failed operation. */ + PM_EVT_PEER_DELETE_SUCCEEDED, /**< @brief A peer was cleared from flash storage, for example because a call to @ref pm_peer_delete succeeded. This event can also be sent as part of a call to @ref pm_peers_delete or internal cleanup. */ + PM_EVT_PEER_DELETE_FAILED, /**< @brief A peer could not be cleared from flash storage. This event is sent instead of @ref PM_EVT_PEER_DELETE_SUCCEEDED for the failed operation. */ + PM_EVT_PEERS_DELETE_SUCCEEDED, /**< @brief A call to @ref pm_peers_delete has completed successfully. Flash storage now contains no peer data. */ + PM_EVT_PEERS_DELETE_FAILED, /**< @brief A call to @ref pm_peers_delete has failed, which means that at least one of the peers could not be deleted. Other peers might have been deleted, or might still be queued to be deleted. No more @ref PM_EVT_PEERS_DELETE_SUCCEEDED or @ref PM_EVT_PEERS_DELETE_FAILED events are sent until the next time @ref pm_peers_delete is called. */ + PM_EVT_LOCAL_DB_CACHE_APPLIED, /**< @brief Local database values for a peer (taken from flash storage) have been provided to the SoftDevice. */ + PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED, /**< @brief Local database values for a peer (taken from flash storage) were rejected by the SoftDevice, which means that either the database has changed or the user has manually set the local database to an invalid value (using @ref pm_peer_data_store). */ + PM_EVT_SERVICE_CHANGED_IND_SENT, /**< @brief A service changed indication has been sent to a peer, as a result of a call to @ref pm_local_database_has_changed. This event will be followed by a @ref PM_EVT_SERVICE_CHANGED_IND_CONFIRMED event if the peer acknowledges the indication. */ + PM_EVT_SERVICE_CHANGED_IND_CONFIRMED, /**< @brief A service changed indication that was sent has been confirmed by a peer. The peer can now be considered aware that the local database has changed. */ +} pm_evt_id_t; -/**@brief Type describing all errors that can occur asynchronously when securing a link. +/**@brief Parameters specific to the @ref PM_EVT_CONN_SEC_SUCCEEDED event. */ typedef struct { - pm_error_type_t error_type; /**< Which type of error. Specifies which entry in the below union to read. */ - uint8_t error_src; /**< The party that raised the error, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ - union - { - uint8_t sec_status; /**< The error when the error_type is @ref PM_ERROR_TYPE_SEC_STATUS. See @ref BLE_GAP_SEC_STATUS. See also Table 3.7 ("Pairing Failed Reason Codes") in the Bluetooth Core Specification 4.2, Vol 3, Part H, Ch 3.5.5. */ - pm_sec_error_code_t pm_sec_error; /**< The error when the error_type is @ref PM_ERROR_TYPE_PM_SEC_ERROR. */ - } error; -} pm_sec_error_t; + pm_conn_sec_procedure_t procedure; /**< @brief The procedure that led to securing the link. */ +} pm_conn_secured_evt_t; -/**@brief Structure containing parameters specific to the @ref PM_EVT_LINK_SECURE_FAILED event. +/**@brief Parameters specific to the @ref PM_EVT_CONN_SEC_FAILED event. */ typedef struct { - pm_sec_procedure_t procedure; /**< The procedure that failed. */ - pm_sec_error_t error; /**< How the procedure failed. */ -} pm_link_secure_failed_evt_t; + pm_conn_sec_procedure_t procedure; /**< @brief The procedure that failed. */ + pm_sec_error_code_t error; /**< @brief An error code that describes the failure. */ + uint8_t error_src; /**< @brief The party that raised the error, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ +} pm_conn_secure_failed_evt_t; /**@brief Actions that can be performed to peer data in persistent storage. */ typedef enum { - PM_PEER_DATA_ACTION_UPDATE, /**< Overwriting the data. */ - PM_PEER_DATA_ACTION_CLEAR, /**< Removing the data. */ -} pm_peer_data_action_t; + PM_PEER_DATA_OP_UPDATE, /**< @brief Writing or overwriting the data. */ + PM_PEER_DATA_OP_DELETE, /**< @brief Removing the data. */ +} pm_peer_data_op_t; -/**@brief Structure containing parameters specific to the @ref PM_EVT_PEER_DATA_UPDATED event. +/**@brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event. */ typedef struct { - pm_peer_data_id_t data_id; /**< The type of data that was updated */ - pm_peer_data_action_t action; /**< What happened to the data. */ -} pm_peer_data_update_t; + pm_peer_data_id_t data_id; /**< @brief The type of the data that was changed. */ + pm_peer_data_op_t action; /**< @brief What happened to the data. */ + uint8_t flash_changed : 1; /**< @brief If this is false, no operation was done in flash, because the value was already what it should be. Please note that in certain scenarios, this flag will be true even if the new value is the same as the old. */ + pm_store_token_t token; /**< @brief Token that identifies the operation. For @ref PM_PEER_DATA_OP_DELETE actions, this token can be disregarded. For @ref PM_PEER_DATA_OP_UPDATE actions, compare this token with the token that is received from a call to a @ref PM_PEER_DATA_FUNCTIONS function. */ +} pm_peer_data_update_succeeded_evt_t; -/**@brief Structure containing parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_FAILED event. +/**@brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_FAILED event. */ typedef struct { - pm_peer_data_id_t data_id; /**< The type of data that was updated */ - pm_peer_data_action_t action; /**< The action that failed. */ - ret_code_t error; /**< The error that occurred. */ + pm_peer_data_id_t data_id; /**< @brief The type of the data that was supposed to be changed. */ + pm_peer_data_op_t action; /**< @brief The action that failed. */ + pm_store_token_t token; /**< @brief Token that identifies the operation. For @ref PM_PEER_DATA_OP_DELETE actions, this token can be disregarded. For @ref PM_PEER_DATA_OP_UPDATE actions, compare this token with the token that is received from a call to a @ref PM_PEER_DATA_FUNCTIONS function. */ + ret_code_t error; /**< @brief An error code that describes the failure. */ } pm_peer_data_update_failed_t; -/**@brief Structure containing parameters specific to the @ref PM_EVT_ERROR_UNEXPECTED event. +/**@brief Standard parameters for failure events. */ typedef struct { - ret_code_t error; /**< The unexpected error that occurred. */ -} pm_error_unexpected_evt_t; + ret_code_t error; /**< @brief The error that occurred. */ +} pm_failure_evt_t; -/**@brief Structure describing events from the @ref peer_manager module. +/**@brief An event from the @ref peer_manager module. + * + * @details The structure contains both standard parameters and parameters that are specific to some events. */ typedef struct { - pm_evt_id_t evt_id; /**< The type of the event. */ - uint16_t conn_handle; /**< The connection this event pertains to, or @ref BLE_CONN_HANDLE_INVALID. */ - pm_peer_id_t peer_id; /**< The connection this event pertains to, or @ref PM_PEER_ID_INVALID. */ + pm_evt_id_t evt_id; /**< @brief The type of the event. */ + uint16_t conn_handle; /**< @brief The connection that this event pertains to, or @ref BLE_CONN_HANDLE_INVALID. */ + pm_peer_id_t peer_id; /**< @brief The bonded peer that this event pertains to, or @ref PM_PEER_ID_INVALID. */ union { - pm_link_secured_evt_t link_secured_evt; /**< Parameters specific to the @ref PM_EVT_LINK_SECURED event. */ - pm_link_secure_failed_evt_t link_secure_failed_evt; /**< Parameters specific to the @ref PM_EVT_LINK_SECURE_FAILED event. */ - pm_peer_data_update_t peer_data_updated_evt; /**< Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATED event. */ - pm_peer_data_update_failed_t peer_data_update_failed_evt; /**< Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_FAILED event. */ - pm_error_unexpected_evt_t error_unexpected_evt; /**< Parameters specific to the @ref PM_EVT_ERROR_UNEXPECTED event. */ + pm_conn_secured_evt_t conn_sec_succeeded; /**< @brief Parameters specific to the @ref PM_EVT_CONN_SEC_SUCCEEDED event. */ + pm_conn_secure_failed_evt_t conn_sec_failed; /**< @brief Parameters specific to the @ref PM_EVT_CONN_SEC_FAILED event. */ + pm_peer_data_update_succeeded_evt_t peer_data_update_succeeded; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event. */ + pm_peer_data_update_failed_t peer_data_update_failed; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_FAILED event. */ + pm_failure_evt_t peer_delete_failed; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DELETE_FAILED event. */ + pm_failure_evt_t peers_delete_failed_evt; /**< @brief Parameters specific to the @ref PM_EVT_PEERS_DELETE_FAILED event. */ + pm_failure_evt_t error_unexpected; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DELETE_FAILED event. */ } params; } pm_evt_t; /**@brief Event handler for events from the @ref peer_manager module. * - * @param[in] p_event The event that has happened. + * @sa pm_register + * + * @param[in] p_event The event that has occurred. */ typedef void (*pm_evt_handler_t)(pm_evt_t const * p_event); -/**@brief Function for initializing the @ref peer_manager. +/**@brief Function for initializing the Peer Manager. * - * @note FDS must be initialized before calling this function. + * @details You must initialize the Peer Manager before you can call any other Peer Manager + * functions. * - * @retval NRF_SUCCESS Initialization was successful. - * @retval NRF_ERROR_INVALID_STATE FDS not initialized. - * @retval NRF_ERROR_NULL p_init_params was NULL. - * @retval NRF_ERROR_INTERNAL An unexpected internal error occurred. + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. */ ret_code_t pm_init(void); -/**@brief Function for registering with the Peer Manager. +/**@brief Function for registering an event handler with the Peer Manager. * - * @param[in] event_handler Callback for events from the @ref peer_manager module. + * @param[in] event_handler Callback for events from the @ref peer_manager module. @p event_handler + * is called for every event that the Peer Manager sends after this + * function is called. * - * @retval NRF_SUCCESS Initialization was successful. - * @retval NRF_ERROR_INVALID_STATE @ref peer_manager not initialized. - * @retval NRF_ERROR_NULL p_init_params was NULL. + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_NULL If @p event_handler was NULL. + * @retval NRF_ERROR_NO_MEM If no more registrations can happen. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. */ ret_code_t pm_register(pm_evt_handler_t event_handler); /**@brief Function for providing pairing and bonding parameters to use for pairing procedures. * - * @details Until this is called, all bonding procedures initiated by the peer will be rejected. - * This function can be called multiple times, even with NULL p_sec_params, in which case - * it will go back to rejecting all procedures. + * @details Until this function is called, all bonding procedures that are initiated by the + * peer are rejected. + * + * This function can be called multiple times with different parameters, even with NULL as + * @p p_sec_params, in which case the Peer Manager starts rejecting all procedures again. * - * @param[in] p_sec_params Security parameters to be used for all security procedures. + * @param[in] p_sec_params Security parameters to be used for subsequent security procedures. * - * @retval NRF_SUCCESS Success. - * @retval NRF_ERROR_INVALID_PARAM Invalid combination of parameters. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. - * @retval NRF_ERROR_INTERNAL An unexpected internal error occurred. + * @retval NRF_SUCCESS If the parameters were set successfully. + * @retval NRF_ERROR_INVALID_PARAM If the combination of parameters is invalid. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. */ ret_code_t pm_sec_params_set(ble_gap_sec_params_t * p_sec_params); /**@brief Function for passing BLE events to the Peer Manager. * - * @note This routine should be called from BLE stack event dispatcher for the module to work as - * expected. + * @details For the module to work as expected, this function must be called with each BLE event + * from the SoftDevice. It must be called after @ref ble_conn_state_on_ble_evt, but before + * the application processes the event. * - * @param[in] p_ble_evt BLE stack event being dispatched to the function. + * Calling this function before @ref pm_init is safe, but without effect. + * + * @param[in] p_ble_evt BLE stack event that is dispatched to the function. */ -void pm_ble_evt_handler(ble_evt_t * p_ble_evt); +void pm_on_ble_evt(ble_evt_t * p_ble_evt); -/**@brief Function for encrypting a link, and optionally establishing a bond. +/**@brief Function for establishing encryption on a connection, and optionally establishing a bond. + * + * @details This function attempts to secure the link that is specified by @p conn_handle. It uses + * the parameters that were previously provided in a call to @ref pm_sec_params_set. * - * @details The actions taken by this function is partly dictated by the parameters given in the - * @ref pm_sec_params_set. + * If the connection is a master connection, calling this function starts a security + * procedure on the link. If we have keys from a previous bonding procedure with this peer + * and the keys meet the security requirements in the currently active sec_params, the + * function attempts to establish encryption with the existing keys. If no key exists, the + * function attempts to pair and bond according to the currently active sec_params. * - * @note If the connection is a slave connection, this will send a security request to the master, - * but the master is not obligated to initiate pairing or encryption in response. + * If the function completes successfully, a @ref PM_EVT_CONN_SEC_START event is sent. + * The procedure might be queued, in which case the @ref PM_EVT_CONN_SEC_START event is + * delayed until the procedure is initiated in the SoftDevice. * - * @param[in] conn_handle Connection handle of the link as provided by the SoftDevice. - * @param[in] force_repairing Whether to force a pairing procedure to happen regardless of whether - * an encryption key already exists. This argument is only relevant for - * the central role. Recommended value: false + * If the connection is a slave connection, the function sends a security request to + * the peer (master). It is up to the peer then to initiate pairing or encryption. + * If the peer ignores the request, a @ref BLE_GAP_EVT_TIMEOUT event occurs + * with the source @ref BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST. Otherwise, the peer initiates + * security, in which case things happen as if the peer had initiated security itself. + * See @ref PM_EVT_CONN_SEC_START for information about peer-initiated security. * - * @retval NRF_SUCCESS Success. - * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations - * can be performed on this link. - * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. - * @retval NRF_ERROR_NOT_FOUND Security parameters have not been set. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized, or the peer is disconnected or - * in the process of disconnecting. - * @retval NRF_ERROR_INTERNAL An unexpected error occurred. + * @param[in] conn_handle Connection handle of the link as provided by the SoftDevice. + * @param[in] force_repairing Whether to force a pairing procedure even if there is an existing + * encryption key. This argument is relevant only for + * the central role. Recommended value: false. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_ERROR_TIMEOUT If there was an SMP time-out, so that no more SMP + * operations can be performed on this link. + * @retval BLE_ERROR_INVALID_CONN_HANDLE If the connection handle is invalid. + * @retval NRF_ERROR_NOT_FOUND If the security parameters have not been set. + * @retval NRF_ERROR_STORAGE_FULL If there is no more space in persistent storage. + * @retval NRF_ERROR_NO_MEM If no more authentication procedures can run in parallel + * for the given role. See @ref sd_ble_gap_authenticate. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized, or the peer is + * disconnected or in the process of disconnecting. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. */ -ret_code_t pm_link_secure(uint16_t conn_handle, bool force_repairing); +ret_code_t pm_conn_secure(uint16_t conn_handle, bool force_repairing); -/**@brief Function for replying with desired security parameters for a specific link. - * - * @warning This function is not yet implemented +/**@brief Function for providing security configuration for a link. * - * @details This function must be called if and only if a PM_EVT_SEC_PARAMS_REQ event was received. - * The PM_EVT_SEC_PARAMS_REQ is received only if the always_ask_for_sec_params option was - * set during initialization. + * @details This function is optional, and must be called in reply to a @ref + * PM_EVT_CONN_SEC_CONFIG_REQ event, before the Peer Manager event handler returns. If it + * is not called in time, a default configuration is used. See @ref pm_conn_sec_config_t + * for the value of the default. * - * @param[in] conn_handle The link to set the security parameters for. - * @param[in] p_sec_params The security parameters to set for the link. - * - * @retval NRF_SUCCESS Successfully set security parameters. - * @retval BLE_ERROR_INVALID_CONN_HANDLE Connection handle does not refer to an active connection. - * @retval NRF_ERROR_FORBIDDEN Security parameters have not been requested on this link. - * @retval NRF_ERROR_INVALID_PARAM Invalid value or combination in security parameters. + * @param[in] conn_handle The connection to set the configuration for. + * @param[in] p_conn_sec_config The configuration. */ -ret_code_t pm_sec_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params); +void pm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config); /**@brief Function for manually informing that the local database has changed. * - * @details This causes a service changed indication to be sent to all bonded peers that subscribe - * to it. + * @details This function sends a service changed indication to all bonded and/or connected peers + * that subscribe to this indication. If a bonded peer is not connected, the indication is + * sent when it reconnects. Every time an indication is sent, a @ref + * PM_EVT_SERVICE_CHANGED_IND_SENT event occurs, followed by a @ref + * PM_EVT_SERVICE_CHANGED_IND_CONFIRMED when the peer sends its confirmation. Peers that + * are not subscribed to the service changed indication when this function is called do not + * receive an indication, and no events are sent to the user. Likewise, if the service + * changed characteristic is not present in the local database, this no indications are + * sent peers, and no events are sent to the user. */ void pm_local_database_has_changed(void); @@ -272,204 +327,534 @@ void pm_local_database_has_changed(void); /**@brief Function for getting the security status of a connection. * * @param[in] conn_handle Connection handle of the link as provided by the SoftDevice. - * @param[out] p_link_status Security status of the link. + * @param[out] p_conn_sec_status Security status of the link. * - * @retval NRF_SUCCESS Pairing initiated successfully. - * @retval NRF_ERROR_INVALID_PARAM conn_handle is invalid or does not refer to an active connection. - * @retval NRF_ERROR_NULL p_link_status was NULL. + * @retval NRF_SUCCESS If pairing was initiated successfully. + * @retval BLE_ERROR_INVALID_CONN_HANDLE If the connection handle is invalid. + * @retval NRF_ERROR_NULL If @p p_conn_sec_status was NULL. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. */ -ret_code_t pm_link_status_get(uint16_t conn_handle, pm_link_status_t * p_link_status); +ret_code_t pm_conn_sec_status_get(uint16_t conn_handle, pm_conn_sec_status_t * p_conn_sec_status); -/** - * @brief Function for constructing a whitelist for use when advertising. +/**@brief Experimental function for specifying the public key to use for LESC operations. * - * @details Construct a whitelist containing the addresses and IRKs of the provided peer IDs. If - * p_peer_ids is NULL, the first (lowest) peer IDs will be chosen. If pp_addrs in - * p_whitelist is NULL, the whitelist will contain only IRKs, and vice versa. + * @details This function can be called multiple times. The specified public key will be used for + * all subsequent LESC (LE Secure Connections) operations until the next time this function + * is called. * - * @note When advertising with whitelist, always use the whitelist created/set by the most recent - * call to this function or to @ref im_wlist_set, whichever happened most recently. - * @note Do not call this function while advertising with another whitelist. + * @note The key must continue to reside in application memory as it is not copied by Peer Manager. * - * @param[in] p_peer_ids The ids of the peers to be added to the whitelist. - * @param[in] n_peer_ids The number of peer ids in p_peer_ids. - * @param[in,out] p_whitelist The constructed whitelist. Note that p_adv_whitelist->pp_addrs - * must be NULL or point to an array with size @ref - * BLE_GAP_WHITELIST_ADDR_MAX_COUNT and p_adv_whitelist->pp_irks - * must be NULL or point to an array with size @ref - * BLE_GAP_WHITELIST_IRK_MAX_COUNT. + * @param[in] p_public_key The public key to use for all subsequent LESC operations. * - * @retval NRF_SUCCESS Whitelist successfully created. - * @retval NRF_ERROR_NULL p_whitelist was NULL. + * @retval NRF_SUCCESS If pairing was initiated successfully. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. */ -ret_code_t pm_wlist_create(pm_peer_id_t * p_peer_ids, uint8_t n_peer_ids, ble_gap_whitelist_t * p_whitelist); +ret_code_t pm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key); -/** - * @brief Function for informing this module of what whitelist will be used. +/**@brief Function for setting or clearing the whitelist. * - * @details This function is meant to be used when the app wants to use a custom whitelist. - * When using peer manager, this function must be used if a custom whitelist is used. + * When using the S13x SoftDevice v3.x, this function sets or clears the whitelist. + * When using the S13x SoftDevice v2.x, this function caches a list of + * peers that can be retrieved later by @ref pm_whitelist_get to pass to the @ref lib_ble_advertising. * - * @note When using a whitelist, always use the whitelist created/set by the most recent - * call to @ref im_wlist_create or to this function, whichever happened most recently. - * @note Do not call this function while scanning with another whitelist. - * @note Do not add any irks to the whitelist that are not present in the bonding data of a peer in - * the peer database. + * To clear the current whitelist, pass either NULL as @p p_peers or zero as @p peer_cnt. * - * @param[in] p_whitelist The whitelist. + * @param[in] p_peers The peers to add to the whitelist. Pass NULL to clear the current whitelist. + * @param[in] peer_cnt The number of peers to add to the whitelist. The number must not be greater than + * @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. Pass zero to clear the current + * whitelist. * - * @retval NRF_SUCCESS Whitelist successfully set. - * @retval NRF_ERROR_NULL p_whitelist was NULL. - * @retval NRF_ERROR_NOT_FOUND One or more of the whitelists irks was not found in the peer_database. + * @retval NRF_SUCCESS If the whitelist was successfully set or cleared. + * @retval BLE_GAP_ERROR_WHITELIST_IN_USE If a whitelist is already in use and cannot be set. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If a peer in @p p_peers has an address that cannot + * be used for whitelisting. + * @retval NRF_ERROR_NOT_FOUND If any of the peers in @p p_peers cannot be found. + * @retval NRF_ERROR_DATA_SIZE If @p peer_cnt is greater than + * @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. */ -ret_code_t pm_wlist_set(ble_gap_whitelist_t * p_whitelist); +ret_code_t pm_whitelist_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt); -/** - * @brief Function for getting the corresponding connection handle based on the Peer ID. +/**@brief Function for retrieving the previously set whitelist. + * + * The function retrieves the whitelist of GAP addresses and IRKs that was + * previously set by @ref pm_whitelist_set. + * + * To retrieve only GAP addresses or only IRKs, provide only one of the + * buffers. If a buffer is provided, its size must be specified. + * + * @param[out] p_addrs The buffer where to store GAP addresses. Pass NULL to retrieve + * only IRKs (in that case, @p p_irks must not be NULL). + * @param[in,out] p_addr_cnt In: The size of the @p p_addrs buffer. + * May be NULL if and only if @p p_addrs is NULL. + * Out: The number of GAP addresses copied into the buffer. + * If @p p_addrs is NULL, this parameter remains unchanged. + * @param[out] p_irks The buffer where to store IRKs. Pass NULL to retrieve + * only GAP addresses (in that case, @p p_addrs must not NULL). + * @param[in,out] p_irk_cnt In: The size of the @p p_irks buffer. + * May be NULL if and only if @p p_irks is NULL. + * Out: The number of IRKs copied into the buffer. + * If @p p_irks is NULL, this paramater remains unchanged. + * + * @retval NRF_SUCCESS If the whitelist was successfully retrieved. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If a peer has an address that cannot be used for + * whitelisting (this error can occur only + * when using the S13x SoftDevice v2.x). + * @retval NRF_ERROR_NULL If a required parameter is NULL. + * @retval NRF_ERROR_NO_MEM If the provided buffers are too small. + * @retval NRF_ERROR_NOT_FOUND If the data for any of the cached whitelisted peers + * cannot be found. It might have been deleted. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_whitelist_get(ble_gap_addr_t * p_addrs, + uint32_t * p_addr_cnt, + ble_gap_irk_t * p_irks, + uint32_t * p_irk_cnt); + + +/**@brief Function for setting and clearing the device identities list. + * + * @param[in] p_peers The peers to add to the device identities list. Pass NULL to clear + * the device identities list. + * @param[in] peer_cnt The number of peers. Pass zero to clear the device identities list. + * + * @retval NRF_SUCCESS If the device identities list was successfully + * set or cleared. + * @retval NRF_ERROR_NOT_FOUND If a peer is invalid or its data could not + * be found in flash. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If a peer has an address that cannot be + * used for whitelisting. + * @retval BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE If the device identities list is in use and + * cannot be set. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_NOT_SUPPORTED If using a SoftDevice that does not support + * device identities, e.g. S130 v2.0. + */ +ret_code_t pm_device_identities_list_set(pm_peer_id_t const * p_peers, + uint32_t peer_cnt); + + +/**@brief Function for setting the local Bluetooth identity address. + * + * @details The local Bluetooth identity address is the address that identifies the device to other + * peers. The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref + * BLE_GAP_ADDR_TYPE_RANDOM_STATIC. The identity address cannot be changed while roles are + * running. + * + * The SoftDevice sets a default address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC + * when it is enabled. This default address is a random number that is populated during + * the IC manufacturing process. It remains unchanged for the lifetime of each IC, but the application can assign a different identity address. + * + * The identity address is distributed to the peer during bonding. + * If the address changes, the address stored in the peer device will not be valid and the + * ability to reconnect using the old address will be lost. + * + * + * @note The SoftDevice functions @ref sd_ble_gap_address_set (S13x v2.x), @ref sd_ble_gap_addr_set + * (S13x v3.x), and @ref sd_ble_gap_privacy_set (S13x v3.x) must not be called when using the Peer Manager. + * Use this function instead. + * + * @param[in] p_addr The GAP address to be set. + * + * @retval NRF_SUCCESS If the identity address was set successfully. + * @retval NRF_ERROR_NULL If @p p_addr is NULL. + * @retval NRF_ERROR_INVALID_ADDR If the @p p_addr pointer is invalid. + * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If the BLE address is invalid. + * @retval NRF_ERROR_BUSY If the SoftDevice was busy. Process SoftDevice events + * and retry. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized or if this function + * was called while advertising, scanning, or while connected. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_id_addr_set(ble_gap_addr_t const * p_addr); + + +/**@brief Function for retrieving the local Bluetooth identity address. + * + * This function always returns the identity address, irrespective of the privacy settings. + * This means that the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref + * BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * + * @param[out] p_addr Pointer to the address structure to be filled in. + * + * @retval NRF_SUCCESS If the address was retrieved successfully. + * @retval NRF_ERROR_NULL If @p p_addr is NULL. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_id_addr_get(ble_gap_addr_t * p_addr); + + +/**@brief Function for configuring privacy settings. + * + * The privacy settings cannot be configured while advertising, scanning, or while in a connection. + * + * @note The SoftDevice functions @ref sd_ble_gap_address_set (S13x v2.x), @ref sd_ble_gap_addr_set + * (S13x v3.x), and @ref sd_ble_gap_privacy_set (S13x v3.x) must not be called when using the Peer Manager. + * Use this function instead. + * + * @param[in] p_privacy_params Privacy settings. + * + * @retval NRF_SUCCESS If the privacy settings were configured successfully. + * @retval NRF_ERROR_NULL If @p p_privacy_params is NULL. + * @retval NRF_ERROR_BUSY If the operation could not be performed at this time. + * Process SoftDevice events and retry. + * @retval NRF_ERROR_INVALID_PARAM If the address type is invalid. + * @retval NRF_ERROR_INVALID_STATE If this function is called while BLE roles using + * privacy are enabled. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_privacy_set(pm_privacy_params_t const * p_privacy_params); + + +/**@brief Function for retrieving privacy settings. + * + * The privacy settings that are returned include the current IRK as well. + * + * @param[out] p_privacy_params Privacy settings. + * + * @retval NRF_SUCCESS If the privacy settings were retrieved successfully. + * @retval NRF_ERROR_NULL If @p p_privacy_params or @p p_privacy_params->p_device_irk is + * NULL. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_privacy_get(pm_privacy_params_t * p_privacy_params); + + +/**@brief Function for getting the connection handle of the connection with a bonded peer. * - * @param[out] peer_id Peer ID. - * @param[in] p_conn_handle Corresponding connection handle. BLE_INVALID_CONN_HANDLE if peer is - * not connected. + * @param[in] peer_id The peer ID of the bonded peer. + * @param[out] p_conn_handle Connection handle, or @ref BLE_ERROR_INVALID_CONN_HANDLE if the peer + * is not connected. * - * @retval NRF_SUCCESS Connection handle retrieved successfully. - * @retval NRF_ERROR_NULL p_conn_handle was NULL. + * @retval NRF_SUCCESS If the connection handle was retrieved successfully. + * @retval NRF_ERROR_NULL If @p p_conn_handle was NULL. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. */ ret_code_t pm_conn_handle_get(pm_peer_id_t peer_id, uint16_t * p_conn_handle); -/**@brief Function for getting the corresponding peer ID based on the connection handle. +/**@brief Function for retrieving the ID of a peer, given its connection handle. * - * @param[in] conn_handle Connection handle as provided by the SoftDevice. - * @param[out] p_peer_id Corresponding peer ID. + * @param[in] conn_handle The connection handle of the peer. + * @param[out] p_peer_id The peer ID, or @ref PM_PEER_ID_INVALID if the peer is not bonded or + * @p conn_handle does not refer to a valid connection. * - * @retval NRF_SUCCESS Peer ID retrieved successfully. - * @retval NRF_ERROR_NULL p_peer_id was NULL. - * @retval NRF_ERROR_NOT_FOUND No peer ID was found for the connection handle. This means that - * there is no bond with the connected peer, or the conn_handle - * does not refer to an active connection. + * @retval NRF_SUCCESS If the peer ID was retrieved successfully. + * @retval NRF_ERROR_NULL If @p p_peer_id was NULL. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. */ ret_code_t pm_peer_id_get(uint16_t conn_handle, pm_peer_id_t * p_peer_id); -/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be used to - * loop through all used peer IDs. +/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. * - * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last used - * peer ID. + * @details This function can be used to loop through all used peer IDs. The order in which + * peer IDs are returned should be considered unpredictable. @ref PM_PEER_ID_INVALID + * is considered to be before the first and after the last used peer ID. * - * @note The order the peer IDs are returned can be considered random. + * @details To loop through all peer IDs exactly once, use the following constuct: + * @code{c} + * pm_peer_id_t current_peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID); + * while (current_peer_id != PM_PEER_ID_INVALID) + * { + * // Do something with current_peer_id. + * current_peer_id = pm_next_peer_id_get(current_peer_id) + * } + * @endcode * * @param[in] prev_peer_id The previous peer ID. * - * @return The next peer ID. - * @return The first used peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID. - * @retval PM_PEER_ID_INVALID if prev_peer_id was the last used peer ID. + * @return The next peer ID. If @p prev_peer_id was @ref PM_PEER_ID_INVALID, the + * next peer ID is the first used peer ID. If @p prev_peer_id was the last + * used peer ID, the function returns @ref PM_PEER_ID_INVALID. */ pm_peer_id_t pm_next_peer_id_get(pm_peer_id_t prev_peer_id); -/**@brief Function for querying the number of valid peer IDs available (i.e the number of peers - * there exists data for in persistent storage). +/**@brief Function for querying the number of valid peer IDs that are available. + * + * @details This function returns the number of peers for which there is data in persistent storage. * * @return The number of valid peer IDs. */ -uint32_t pm_n_peers(void); +uint32_t pm_peer_count(void); -/**@brief Function for retrieving (copying out) stored data for a peer. - * - * @param[in] peer_id Peer ID to get info for. - * @param[in] data_id Which piece of data to read. - * @param[inout] p_peer_data Where to store the data. If the data to be read has variable length, - * the appropriate length field needs to reflect the available buffer - * space. On a successful read, the length field is updated to match the - * length of the read data. - * - * @retval NRF_SUCCESS Data successfully read. - * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated. - * @retval NRF_ERROR_NULL p_peer_data contained a NULL pointer. - * @retval NRF_ERROR_NOT_FOUND This data was not found for this peer ID. - * @retval NRF_ERROR_DATA_SIZE The provided buffer was not large enough. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + + +/**@anchor PM_PEER_DATA_FUNCTIONS + * @name Functions (Peer Data) + * Functions for manipulating peer data. + * @{ */ -ret_code_t pm_peer_data_get(pm_peer_id_t peer_id, pm_peer_data_id_t data_id, pm_peer_data_t * p_peer_data); +/** + * @{ + */ -/**@brief Function for setting/updating the stored data for a peer. +/**@brief Function for retrieving stored data of a peer. * - * @note Writing the data to persistent storage happens asynchronously. + * @note The length of the provided buffer must be a multiple of 4. * - * @param[in] peer_id Peer ID to get info for. - * @param[in] p_peer_data Data to set. For values that are NULL, the stored data will not be - * touched. - * @param[out] p_token A token identifying this particular store operation. The token can be - * used to identify events pertaining to this operation. + * @param[in] peer_id Peer ID to get data for. + * @param[in] data_id Which type of data to read. + * @param[out] p_data Where to put the retrieved data. + * @param[inout] p_len In: The length in bytes of @p p_data. + * Out: The length in bytes of the read data, if the read was successful. * - * @retval NRF_SUCCESS Data will be written to persistent storage ASAP. - * @retval NRF_ERROR_NULL p_peer_data is NULL. - * @retval NRF_ERROR_NOT_FOUND No peer found for that peer ID. - * @retval NRF_ERROR_BUSY Bonding procedure is in progress, so data integrity cannot be - * guaranteed. + * @retval NRF_SUCCESS If the data was read successfully. + * @retval NRF_ERROR_INVALID_PARAM If the the data type or the peer ID was invalid or unallocated, + * or if the length in @p p_length was not a multiple of 4. + * @retval NRF_ERROR_NULL If a pointer parameter was NULL. + * @retval NRF_ERROR_NOT_FOUND If no stored data was found for this peer ID/data ID combination. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer was not large enough. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_peer_data_load(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + void * p_data, + uint16_t * p_len); + +/**@brief Function for reading a peer's bonding data (@ref PM_PEER_DATA_ID_BONDING). + * @details See @ref pm_peer_data_load for parameters and return values. */ +ret_code_t pm_peer_data_bonding_load(pm_peer_id_t peer_id, + pm_peer_data_bonding_t * p_data); + +/**@brief Function for reading a peer's remote DB values. (@ref PM_PEER_DATA_ID_GATT_REMOTE). + * @details See @ref pm_peer_data_load for parameters and return values. */ +ret_code_t pm_peer_data_remote_db_load(pm_peer_id_t peer_id, + ble_gatt_db_srv_t * p_data, + uint16_t * p_len); + +/**@brief Function for reading a peer's application data. (@ref PM_PEER_DATA_ID_APPLICATION). + * @details See @ref pm_peer_data_load for parameters and return values. */ +ret_code_t pm_peer_data_app_data_load(pm_peer_id_t peer_id, + uint8_t * p_data, + uint16_t * p_len); +/** @}*/ + + +/** + * @{ */ -ret_code_t pm_peer_data_store(pm_peer_id_t peer_id, pm_peer_data_const_t * p_peer_data, pm_store_token_t * p_token); +/**@brief Function for setting or updating stored data of a peer. + * + * @note Writing the data to persistent storage happens asynchronously. Therefore, the buffer + * that contains the data must be kept alive until the operation has completed. + * + * @note The data written using this function might later be overwritten as a result of internal + * operations in the Peer Manager. A Peer Manager event is sent each time data is updated, + * regardless of whether the operation originated internally or from action by the user. + * + * @param[in] peer_id Peer ID to set data for. + * @param[in] data_id Which type of data to set. + * @param[in] p_data New value to set. + * @param[in] len The length in bytes of @p p_data. + * @param[out] p_token A token that identifies this particular store operation. The token can be + * used to identify events that pertain to this operation. This parameter can + * be NULL. + * + * @retval NRF_SUCCESS If the data is scheduled to be written to persistent storage. + * @retval NRF_ERROR_NULL If @p p_data is NULL. + * @retval NRF_ERROR_NOT_FOUND If no peer was found for the peer ID. + * @retval NRF_ERROR_BUSY If the underlying flash handler is busy with other flash + * operations. Try again after receiving a Peer Manager event. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + */ +ret_code_t pm_peer_data_store(pm_peer_id_t peer_id, + pm_peer_data_id_t data_id, + void const * p_data, + uint16_t len, + pm_store_token_t * p_token); + +/**@brief Function for setting or updating a peer's bonding data (@ref PM_PEER_DATA_ID_BONDING). + * @details See @ref pm_peer_data_store for parameters and return values. */ +ret_code_t pm_peer_data_bonding_store(pm_peer_id_t peer_id, + pm_peer_data_bonding_t const * p_data, + pm_store_token_t * p_token); + +/**@brief Function for setting or updating a peer's remote DB values. (@ref PM_PEER_DATA_ID_GATT_REMOTE). + * @details See @ref pm_peer_data_store for parameters and return values. */ +ret_code_t pm_peer_data_remote_db_store(pm_peer_id_t peer_id, + ble_gatt_db_srv_t const * p_data, + uint16_t len, + pm_store_token_t * p_token); + +/**@brief Function for setting or updating a peer's application data. (@ref PM_PEER_DATA_ID_APPLICATION). + * @details See @ref pm_peer_data_store for parameters and return values. */ +ret_code_t pm_peer_data_app_data_store(pm_peer_id_t peer_id, + uint8_t const * p_data, + uint16_t len, + pm_store_token_t * p_token); +/** @}*/ + + +/** + * @{ + */ -/**@brief Function for deleting a peer's stored data. +/**@brief Function for deleting a peer's stored pieces of data. * - * @note Clearing of data in persistent storage happens asynchronously. + * @details This function deletes specific data that is stored for a peer. Note that bonding data + * cannot be cleared separately. * - * @note Bonding data can not be cleared with on their own. Use pm_peer_delete() to delete all - * data for a spesified peer including bonding data. + * To delete all data for a peer (including bonding data), use @ref pm_peer_delete. * - * @param[in] peer_id Peer ID to clear info for. - * @param[in] data_id Which data to clear. Bonding data cannot be cleared, use @ref pm_peer_delete + * @note Clearing data in persistent storage happens asynchronously. * - * @retval NRF_SUCCESS Data will be cleared in persistent storage ASAP. - * @retval NRF_ERROR_INVALID_PARAM Attempted to delete bonding data or data id was invalid. - * @retval NRF_ERROR_NOT_FOUND Nothing to clear for this data for this peer ID. - * @retval NRF_ERROR_BUSY Could not process request at this time. Reattempt later. - * @retval NRF_ERROR_INVALID_STATE Module is not initialized. + * @param[in] peer_id Peer ID to clear data for. + * @param[in] data_id Which data to clear. + * + * @retval NRF_SUCCESS If the clear procedure was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM If @p data_id was PM_PEER_DATA_ID_BONDING or invalid, or + * @p peer_id was invalid. + * @retval NRF_ERROR_NOT_FOUND If there was no data to clear for this peer ID/data ID combination. + * @retval NRF_ERROR_BUSY If the underlying flash handler is busy with other flash + * operations. Try again after receiving a Peer Manager event. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. */ -ret_code_t pm_peer_data_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id); +ret_code_t pm_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id); -/**@brief Function for registering persistent storage for a new peer. +/**@brief Function for manually adding a peer to the persistent storage. + * + * @details This function allocates a new peer ID and stores bonding data for the new peer. The + * bonding data is necessary to prevent ambiguity/inconsistency in peer data. * - * @param[in] p_bonding_data The bonding data of the new peer. This must be provided to avoid - * inconsistencies (duplicate entries). Must contain a public/static - * address or a non-zero master ID. + * @param[in] p_bonding_data The bonding data of the new peer (must contain a public/static + * address or a non-zero IRK). * @param[out] p_new_peer_id Peer ID for the new peer, or an existing peer if a match was found. - * @param[out] p_token A token identifying this particular store operation (storing the - * bonding data). The token can be used to identify events pertaining to - * this operation. + * @param[out] p_token A token that identifies this particular store operation (storing the + * bonding data). The token can be used to identify events that pertain + * to this operation. This parameter can be NULL. * - * @retval NRF_SUCCESS Store operation for bonding data started successfully. - * @retval NRF_ERROR_NULL A parameter is NULL. - * @retval NRF_ERROR_NO_MEM No more space in persistent storage. New peer cannot be allocated. - * @retval NRF_ERROR_BUSY Operation cannot be performed at this time. Try again later. - * @retval NRF_ERROR_INVALID_PARAM Bonding data is invalid. - * @retval NRF_ERROR_INVALID_STATE Peer Manager not initialized. + * @retval NRF_SUCCESS If the store operation for bonding data was initiated successfully. + * @retval NRF_ERROR_NULL If @p p_bonding_data or @p p_new_peer_id is NULL. + * @retval NRF_ERROR_STORAGE_FULL If there is no more space in persistent storage. + * @retval NRF_ERROR_NO_MEM If there are no more available peer IDs. + * @retval NRF_ERROR_BUSY If the underlying flash filesystem is busy with other flash + * operations. Try again after receiving a Peer Manager event. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. */ -ret_code_t pm_peer_new(pm_peer_data_bonding_t * p_bonding_data, pm_peer_id_t * p_new_peer_id, pm_store_token_t * p_token); +ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id, + pm_peer_data_bonding_t * p_bonding_data, + pm_store_token_t * p_token); /**@brief Function for freeing persistent storage for a peer. * - * @param[in] peer_id Peer ID to be freed. + * @details This function deletes every piece of data that is associated with the specified peer and + * frees the peer ID to be used for another peer. The deletion happens asynchronously, and + * the peer ID is not freed until the data is deleted. When the operation finishes, a @ref + * PM_EVT_PEER_DELETE_SUCCEEDED or @ref PM_EVT_PEER_DELETE_FAILED event is sent. + * + * @warning Use this function only when not connected to or connectable for the peer that is being + * deleted. If the peer is or becomes connected or data is manually written in flash during + * this procedure (until the success or failure event happens), the behavior is undefined. + * + * @param[in] peer_id Peer ID to be freed and have all associated data deleted. + * + * @retval NRF_SUCCESS If the operation was initiated successfully. + * @retval NRF_ERROR_INVALID_PARAM If the peer ID was not valid. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. */ -void pm_peer_delete(pm_peer_id_t peer_id); +ret_code_t pm_peer_delete(pm_peer_id_t peer_id); /**@brief Function for deleting all data stored for all peers. * - * @note Use this only when not connected or connectable. + * @details This function sends either a @ref PM_EVT_PEERS_DELETE_SUCCEEDED or a @ref + * PM_EVT_PEERS_DELETE_FAILED event. In addition, a @ref PM_EVT_PEER_DELETE_SUCCEEDED or + * @ref PM_EVT_PEER_DELETE_FAILED event is sent for each deleted peer. + * + * @note No event is sent when there is no peer data in flash. + * + * @warning Use this function only when not connected or connectable. If a peer is or becomes + * connected or a @ref PM_PEER_DATA_FUNCTIONS function is used during this procedure (until + * the success or failure event happens), the behavior is undefined. + * + * @retval NRF_SUCCESS If the deletion process was initiated successfully. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_peers_delete(void); +/** @}*/ + + +/** + * @{ */ -void pm_peer_delete_all(void); +/**@brief Function for finding the highest and lowest ranked peers. + * + * @details The rank is saved in persistent storage under the data ID @ref PM_PEER_DATA_ID_PEER_RANK. + * + * @details The interpretation of rank is up to the user, because the rank is only updated by + * calling @ref pm_peer_rank_highest or by manipulating the value using a @ref + * PM_PEER_DATA_FUNCTIONS function. + * + * @note Any argument that is NULL is ignored. + * + * @param[out] p_highest_ranked_peer The peer ID with the highest rank of all peers, for example, + * the most recently used peer. + * @param[out] p_highest_rank The highest rank. + * @param[out] p_lowest_ranked_peer The peer ID with the lowest rank of all peers, for example, + * the least recently used peer. + * @param[out] p_lowest_rank The lowest rank. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_ERROR_NOT_FOUND If no peers were found. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_peer_ranks_get(pm_peer_id_t * p_highest_ranked_peer, + uint32_t * p_highest_rank, + pm_peer_id_t * p_lowest_ranked_peer, + uint32_t * p_lowest_rank); + + +/**@brief Function for updating the rank of a peer to be highest among all stored peers. + * + * @details If this function returns @ref NRF_SUCCESS, either a @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED or a + * @ref PM_EVT_PEER_DATA_UPDATE_FAILED event is sent with a @ref + * PM_STORE_TOKEN_INVALID store token when the operation is complete. Until the operation + * is complete, this function returns @ref NRF_ERROR_BUSY. + * + * When the operation is complete, the peer is the highest ranked peer as reported by + * @ref pm_peer_ranks_get. + * + * @note The @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event can arrive before the function returns if the peer + * is already ranked highest. In this case, the @ref pm_peer_data_update_succeeded_evt_t::flash_changed flag + * in the event will be false. + * + * @param[in] peer_id The peer to rank highest. + * + * @retval NRF_SUCCESS If the peer's rank is, or will be updated to be highest. + * @retval NRF_ERROR_BUSY If the underlying flash handler is busy with other flash + * operations, or if a previous call to this function has not + * completed. Try again after receiving a Peer Manager event. + * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized. + * @retval NRF_ERROR_INTERNAL If an internal error occurred. + */ +ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id); + +/** @}*/ + /** @} */ +/** @} */ + + +#ifdef __cplusplus +} +#endif + #endif // PEER_MANAGER_H__ diff --git a/components/ble/peer_manager/peer_manager_internal.h b/components/ble/peer_manager/peer_manager_internal.h new file mode 100644 index 0000000..927940a --- /dev/null +++ b/components/ble/peer_manager/peer_manager_internal.h @@ -0,0 +1,200 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 PEER_MANAGER_INTERNAL_H__ +#define PEER_MANAGER_INTERNAL_H__ + +#include +#include "sdk_errors.h" +#include "ble.h" +#include "ble_gap.h" +#include "peer_manager_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @cond NO_DOXYGEN + * @file peer_manager_types.h + * + * @addtogroup peer_manager + * @brief File containing definitions used solely inside the Peer Manager's modules. + * @{ + */ + +ANON_UNIONS_ENABLE + +/**@brief One piece of data associated with a peer, together with its type. + * + * @note This type is deprecated. + */ +typedef struct +{ + uint16_t length_words; /**< @brief The length of the data in words. */ + pm_peer_data_id_t data_id; /**< @brief ID that specifies the type of data (defines which member of the union is used). */ + union + { + pm_peer_data_bonding_t * p_bonding_data; /**< @brief The exchanged bond information in addition to metadata of the bonding. */ + uint32_t * p_peer_rank; /**< @brief A value locally assigned to this peer. Its interpretation is up to the user. The rank is not set automatically by the Peer Manager, but it is assigned by the user using either @ref pm_peer_rank_highest or a @ref PM_PEER_DATA_FUNCTIONS function. */ + bool * p_service_changed_pending; /**< @brief Whether a service changed indication should be sent to the peer. */ + pm_peer_data_local_gatt_db_t * p_local_gatt_db; /**< @brief Persistent information pertaining to a peer GATT client. */ + ble_gatt_db_srv_t * p_remote_gatt_db; /**< @brief Persistent information pertaining to a peer GATT server. */ + uint8_t * p_application_data; /**< @brief Arbitrary data to associate with the peer. This data can be freely used by the application. */ + void * p_all_data; /**< @brief Generic access pointer to the data. It is used only to handle the data without regard to type. */ + }; /**< @brief The data. */ +} pm_peer_data_t; + + +/**@brief Immutable version of @ref pm_peer_data_t. + * + * @note This type is deprecated. + */ +typedef struct +{ + uint16_t length_words; /**< @brief The length of the data in words. */ + pm_peer_data_id_t data_id; /**< @brief ID that specifies the type of data (defines which member of the union is used). */ + union + { + pm_peer_data_bonding_t const * p_bonding_data; /**< @brief Immutable @ref pm_peer_data_t::p_bonding_data. */ + uint32_t const * p_peer_rank; /**< @brief Immutable @ref pm_peer_data_t::p_peer_rank. */ + bool const * p_service_changed_pending; /**< @brief Immutable @ref pm_peer_data_t::p_service_changed_pending. */ + pm_peer_data_local_gatt_db_t const * p_local_gatt_db; /**< @brief Immutable @ref pm_peer_data_t::p_local_gatt_db. */ + ble_gatt_db_srv_t const * p_remote_gatt_db; /**< @brief Immutable @ref pm_peer_data_t::p_remote_gatt_db. */ + uint8_t const * p_application_data; /**< @brief Immutable @ref pm_peer_data_t::p_application_data. */ + void const * p_all_data; /**< @brief Immutable @ref pm_peer_data_t::p_all_data. */ + }; /**< @brief The data. */ +} pm_peer_data_const_t; + +ANON_UNIONS_DISABLE + + +/**@brief Version of @ref pm_peer_data_t that reflects the structure of peer data in flash. + * + * @note This type is deprecated. + */ +typedef pm_peer_data_const_t pm_peer_data_flash_t; + + +/**@brief Macro for calculating the flash size of bonding data. + * + * @return The number of words that the data takes in flash. + */ +#define PM_BONDING_DATA_N_WORDS() BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t)) + + +/**@brief Macro for calculating the flash size of service changed pending state. + * + * @return The number of words that the data takes in flash. + */ +#define PM_SC_STATE_N_WORDS() BYTES_TO_WORDS(sizeof(bool)) + + +/**@brief Macro for calculating the flash size of local GATT database data. + * + * @param[in] local_db_len The length, in bytes, of the database as reported by the SoftDevice. + * + * @return The number of words that the data takes in flash. + */ +#define PM_LOCAL_DB_N_WORDS(local_db_len) \ + BYTES_TO_WORDS((local_db_len) + PM_LOCAL_DB_LEN_OVERHEAD_BYTES) + + +/**@brief Macro for calculating the length of a local GATT database attribute array. + * + * @param[in] n_words The number of words that the data takes in flash. + * + * @return The length of the database attribute array. + */ +#define PM_LOCAL_DB_LEN(n_words) (((n_words) * BYTES_PER_WORD) - PM_LOCAL_DB_LEN_OVERHEAD_BYTES) + + +/**@brief Macro for calculating the flash size of remote GATT database data. + * + * @param[in] service_count The number of services in the service array. + * + * @return The number of words that the data takes in flash. + */ +#define PM_REMOTE_DB_N_WORDS(service_count) BYTES_TO_WORDS(sizeof(ble_gatt_db_srv_t) * (service_count)) + + +/**@brief Macro for calculating the flash size of remote GATT database data. + * + * @param[in] n_words The length in number of words. + * + * @return The number of words that the data takes in flash. + */ +#define PM_REMOTE_DB_N_SERVICES(n_words) (((n_words) * BYTES_PER_WORD) / sizeof(ble_gatt_db_srv_t)) + + +/**@brief Function for calculating the flash size of the usage index. + * + * @return The number of words that the data takes in flash. + */ +#define PM_USAGE_INDEX_N_WORDS() BYTES_TO_WORDS(sizeof(uint32_t)) + +/** @} + * @endcond + */ + + +#ifdef NRF_PM_DEBUG + + #define NRF_PM_DEBUG_CHECK(condition) \ + if (!(condition)) \ + { \ + __asm("bkpt #0"); \ + } + +#else + + // Prevent "variable set but never used" compiler warnings. + #define NRF_PM_DEBUG_CHECK(condition) (void)(condition) + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* PEER_MANAGER_INTERNAL_H__ */ diff --git a/components/ble/peer_manager/peer_manager_types.h b/components/ble/peer_manager/peer_manager_types.h index 0a3c5d5..ebf68a8 100644 --- a/components/ble/peer_manager/peer_manager_types.h +++ b/components/ble/peer_manager/peer_manager_types.h @@ -1,10 +1,42 @@ - - -#ifndef PEER_MANAGER_TYPES_H__ -#define PEER_MANAGER_TYPES_H__ - -#include -#include +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ /** @@ -14,256 +46,190 @@ * @{ */ +#ifndef PEER_MANAGER_TYPES_H__ +#define PEER_MANAGER_TYPES_H__ #include +#include #include +#include "nrf.h" #include "ble_gap.h" #include "ble_hci.h" #include "ble_gatt_db.h" -#include "compiler_abstraction.h" +#include "app_util.h" +#include "app_util_platform.h" -/**@brief Handle to uniquely identify a peer for which we have persistently stored data. - */ -typedef uint16_t pm_peer_id_t; - -#define PM_PEER_ID_INVALID 0xFFFF /**< Invalid value for @ref pm_peer_id_t. */ -#define PM_PEER_ID_N_AVAILABLE_IDS 256 /**< The number of available peer IDs. */ -#define PM_LOCAL_DB_LEN_OVERHEAD_BYTES offsetof(pm_peer_data_local_gatt_db_flash_t, p_data) -#define PM_REMOTE_DB_LEN_OVERHEAD_BYTES offsetof(pm_peer_data_remote_gatt_db_flash_t, p_data) +#ifdef __cplusplus +extern "C" { +#endif -static __INLINE uint16_t PM_N_WORDS(uint16_t n_bytes) -{ - return ((n_bytes + 3) >> 2); -} -/**@brief Errors originating from the Peer Manager module. - */ -typedef enum -{ - PM_SEC_ERROR_CODE_PIN_OR_KEY_MISSING = BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING, /**< Encryption failed because the peripheral has lost the LTK for this bond. */ - PM_SEC_ERROR_CODE_MIC_FAILURE = BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE, /**< Pairing ended with disconnection because of mismatching keys. */ - PM_SEC_ERROR_SMP_TIMEOUT, /**< Pairing/bonding could not start because an SMP timeout has already happened on this link. This means that no more pairing or bonding can happen on this link. To be able to pair or bond, the link must be disconnected and then reconnected. See Bluetooth specification 4.2 section 3.H.3.4 */ -} pm_sec_error_code_t; - - -/**@brief Enumeration describing the different procedures that can lead to an encrypted link. +/**@brief Handle to uniquely identify a peer for which we have persistently stored data. */ -typedef enum -{ - PM_LINK_SECURED_PROCEDURE_ENCRYPTION, /**< Using an LTK shared during a previous bonding procedure to encrypt the link. */ - PM_LINK_SECURED_PROCEDURE_BONDING, /**< A pairing procedure, followed by a bonding procedure. */ - PM_LINK_SECURED_PROCEDURE_PAIRING, /**< A pairing procedure with no bonding. */ -} pm_sec_procedure_t; - +typedef uint16_t pm_peer_id_t; -/**@brief Data associated with a bond to a peer. +/**@brief Type that is used for write prepares (used to reserve space in flash). */ -typedef struct -{ - uint8_t own_role; /**< The role of the local device during bonding. */ - ble_gap_id_key_t peer_id; /**< The peer's peer address and identity resolution key. */ - ble_gap_enc_key_t peer_ltk; /**< The peer's long term encryption key. */ - ble_gap_enc_key_t own_ltk; /**< Locally generated long term encryption key, distributed to the peer. */ -} pm_peer_data_bonding_t; - +typedef uint32_t pm_prepare_token_t; -/**@brief Function for calculating the flash size of bonding data. - * - * @return The number of words the data will take in flash. +/**@brief Type that is used to hold a reference to a stored item in flash. */ -static __INLINE uint16_t PM_BONDING_DATA_N_WORDS(void) -{ - return PM_N_WORDS(sizeof(pm_peer_data_bonding_t)); -} - +typedef uint32_t pm_store_token_t; -/**@brief Function for calculating the flash size of service changed pending state. +/**@brief Errors from security procedures in Peer Manager. * - * @return The number of words the data will take in flash. + * @details Possible values are defined in @ref PM_SEC_ERRORS and @ref BLE_GAP_SEC_STATUS. */ -static __INLINE uint16_t PM_SC_STATE_N_WORDS(void) -{ - return PM_N_WORDS(sizeof(bool)); -} +typedef uint16_t pm_sec_error_code_t; -/**@brief Data on a local GATT database. - */ -typedef struct -{ - uint32_t flags; /**< Flags describing the database attributes. */ - uint16_t len; /**< Size of attribute array. */ - uint8_t * p_data; /**< Array to hold the database attributes. */ -} pm_peer_data_local_gatt_db_t; +//lint -emacro(516,PM_LOCAL_DB_LEN_OVERHEAD_BYTES) - -/**@brief Data on a local GATT database, as formatted in flash. - */ -typedef struct -{ - uint32_t flags; - uint16_t len; - uint16_t _padding; - uint8_t p_data[]; -} pm_peer_data_local_gatt_db_flash_t; +#define PM_PEER_ID_INVALID 0xFFFF /**< @brief Invalid value for @ref pm_peer_id_t. */ +#define PM_STORE_TOKEN_INVALID 0 /**< @brief Invalid value for store token. */ +#define PM_PEER_ID_N_AVAILABLE_IDS 256 /**< @brief The number of available peer IDs. */ +#define PM_LOCAL_DB_LEN_OVERHEAD_BYTES offsetof(pm_peer_data_local_gatt_db_t, data) /**< @brief The static-length part of the local GATT data struct. */ -/**@brief Function for calculating the flash size of local GATT database data. - * - * @param[in] local_db_len The length of the database as reported by the SoftDevice. - * - * @return The number of words the data will take in flash. - */ -static __INLINE uint16_t PM_LOCAL_DB_N_WORDS(uint16_t local_db_len) -{ - return PM_N_WORDS(local_db_len + PM_LOCAL_DB_LEN_OVERHEAD_BYTES); -} +#define PM_CONN_SEC_ERROR_BASE 0x1000 /**< @brief The base for Peer Manager defined errors. See @ref PM_SEC_ERRORS and @ref pm_sec_error_code_t. */ -/**@brief Function for calculating the length of a local GATT database attribute array. +/**@defgroup PM_SEC_ERRORS Peer Manager defined security errors * - * @param[in] n_words The number of words the data takes in flash. - * - * @return The length of the database attribute array. - */ -static __INLINE uint16_t PM_LOCAL_DB_LEN(uint16_t n_words) -{ - return ((n_words * 4) - PM_LOCAL_DB_LEN_OVERHEAD_BYTES); -} - + * @details The first 256 numbers in this range correspond to the status codes in + * @ref BLE_HCI_STATUS_CODES. + * @{ */ +#define PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING (PM_CONN_SEC_ERROR_BASE + 0x06) /**< @brief Encryption failed because the peripheral has lost the LTK for this bond. See also @ref BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING and Table 3.7 ("Pairing Failed Reason Codes") in the Bluetooth Core Specification 4.2, section 3.H.3.5.5 (@linkBLEcore). */ +#define PM_CONN_SEC_ERROR_MIC_FAILURE (PM_CONN_SEC_ERROR_BASE + 0x3D) /**< @brief Encryption ended with disconnection because of mismatching keys or a stray packet during a procedure. See the SoftDevice GAP Message Sequence Charts on encryption (@linkBLEMSCgap), the Bluetooth Core Specification 4.2, sections 6.B.5.1.3.1 and 3.H.3.5.5 (@linkBLEcore), and @ref BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE. */ +#define PM_CONN_SEC_ERROR_DISCONNECT (PM_CONN_SEC_ERROR_BASE + 0x100) /**< @brief Pairing or encryption did not finish before the link disconnected for an unrelated reason. */ +#define PM_CONN_SEC_ERROR_SMP_TIMEOUT (PM_CONN_SEC_ERROR_BASE + 0x101) /**< @brief Pairing/bonding could not start because an SMP time-out has already happened on this link. This means that no more pairing or bonding can happen on this link. To be able to pair or bond, the link must be disconnected and then reconnected. See Bluetooth Core Specification 4.2 section 3.H.3.4 (@linkBLEcore). */ + /** @} */ -/**@brief Data on a remote GATT database. - */ -typedef struct -{ - uint32_t service_count; /**< Number of stored services. */ - ble_gatt_db_srv_t * p_data; /**< Array to hold the database attributes. */ -} pm_peer_data_remote_gatt_db_t; -/**@brief Data on a remote GATT database, as formatted in flash. - */ -typedef struct -{ - uint32_t service_count; - ble_gatt_db_srv_t p_data[]; -} pm_peer_data_remote_gatt_db_flash_t; +/**@defgroup PM_PEER_ID_VERSIONS All versions of Peer IDs. + * @brief The data ID for each iteration of the data formats in flash. + * @details Each time the format (in flash) of a piece of peer data changes, the data ID will also + * be updated. This list of defines is a record of each data ID that has ever existed, and + * code that caters to legacy formats can find the relevant IDs here. + * @{ */ +#define PM_PEER_DATA_ID_FIRST_VX 0 /**< @brief The smallest data ID. */ +#define PM_PEER_DATA_ID_BONDING_V1 0 /**< @brief The data ID of the first version of bonding data. */ +#define PM_PEER_DATA_ID_BONDING_V2 7 /**< @brief The data ID of the second version of bonding data. */ +#define PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING_V1 1 /**< @brief The data ID of the first version of the service changed pending flag. */ +#define PM_PEER_DATA_ID_GATT_LOCAL_V1 2 /**< @brief The data ID of the first version of local GATT data. */ +#define PM_PEER_DATA_ID_GATT_LOCAL_V2 8 /**< @brief The data ID of the second version of local GATT data. */ +#define PM_PEER_DATA_ID_GATT_REMOTE_V1 3 /**< @brief The data ID of the first version of remote GATT data. */ +#define PM_PEER_DATA_ID_APPLICATION_V1 4 /**< @brief The data ID of the first version of application data. */ +#define PM_PEER_DATA_ID_GATT_REMOTE_V2 5 /**< @brief The data ID of the second version of remote GATT data. */ +#define PM_PEER_DATA_ID_PEER_RANK_V1 6 /**< @brief The data ID of the first version of the rank. */ +#define PM_PEER_DATA_ID_LAST_VX 9 /**< @brief The data ID after the last valid one. */ +#define PM_PEER_DATA_ID_INVALID_VX 0xFF /**< @brief A data ID guaranteed to be invalid. */ +/**@}*/ - -/**@brief Function for calculating the flash size of remote GATT database data. - * - * @param[in] service_count The number of services in the service array. - * - * @return The number of words the data will take in flash. +/**@brief The different types of data associated with a peer. */ -static __INLINE uint16_t PM_REMOTE_DB_N_WORDS(uint16_t service_count) +typedef enum { - return PM_N_WORDS((sizeof(ble_gatt_db_srv_t) * service_count) + PM_REMOTE_DB_LEN_OVERHEAD_BYTES); -} + PM_PEER_DATA_ID_FIRST = PM_PEER_DATA_ID_FIRST_VX, /**< @brief The smallest data ID. */ + PM_PEER_DATA_ID_BONDING = PM_PEER_DATA_ID_BONDING_V2, /**< @brief The data ID for bonding data. See @ref pm_peer_data_bonding_t. */ + PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING_V1, /**< @brief The data ID for service changed state. */ + PM_PEER_DATA_ID_GATT_LOCAL = PM_PEER_DATA_ID_GATT_LOCAL_V2, /**< @brief The data ID for local GATT data (sys attributes). See @ref pm_peer_data_local_gatt_db_t. */ + PM_PEER_DATA_ID_GATT_REMOTE = PM_PEER_DATA_ID_GATT_REMOTE_V2, /**< @brief The data ID for remote GATT data. */ + PM_PEER_DATA_ID_PEER_RANK = PM_PEER_DATA_ID_PEER_RANK_V1, /**< @brief The data ID for peer rank. See @ref pm_peer_rank_highest. */ + PM_PEER_DATA_ID_APPLICATION = PM_PEER_DATA_ID_APPLICATION_V1, /**< @brief The data ID for application data. */ + PM_PEER_DATA_ID_LAST = PM_PEER_DATA_ID_LAST_VX, /**< @brief One more than the highest data ID. */ + PM_PEER_DATA_ID_INVALID = PM_PEER_DATA_ID_INVALID_VX, /**< @brief A data ID guaranteed to be invalid. */ +} pm_peer_data_id_t; -/**@brief Union of all data associated with one peer. +/**@brief Different procedures that can lead to an encrypted link. */ -typedef union +typedef enum { - pm_peer_data_bonding_t * p_bonding_data; /**< The exchanged bond information in addition to metadata of the bonding. */ - bool * p_service_changed_pending; /**< Whether a service changed indication should be sent to the peer. */ - pm_peer_data_local_gatt_db_t * p_local_gatt_db; /**< Persistent information pertaining to a peer GATT client. */ - pm_peer_data_remote_gatt_db_t * p_remote_gatt_db; /**< Persistent information pertaining to a peer GATT server. */ - uint8_t * p_application_data; /**< Arbitrary data to associate with the peer. This data can be freely used by the application. */ -} pm_peer_data_unit_t; + PM_LINK_SECURED_PROCEDURE_ENCRYPTION, /**< @brief Using an LTK that was shared during a previous bonding procedure to encrypt the link. */ + PM_LINK_SECURED_PROCEDURE_BONDING, /**< @brief A pairing procedure, followed by a bonding procedure. */ + PM_LINK_SECURED_PROCEDURE_PAIRING, /**< @brief A pairing procedure with no bonding. */ +} pm_conn_sec_procedure_t; -/**@brief Immutable version of @ref pm_peer_data_unit_t. +/**@brief Configuration of a security procedure. */ -typedef union +typedef struct { - pm_peer_data_bonding_t const * p_bonding_data; - bool const * p_service_changed_pending; - pm_peer_data_local_gatt_db_t const * p_local_gatt_db; - pm_peer_data_remote_gatt_db_t const * p_remote_gatt_db; - uint8_t const * p_application_data; -} pm_peer_data_unit_const_t; + bool allow_repairing; /** @brief Whether to allow the peer to pair if it wants to, but is already bonded. If this is false, the procedure is rejected, and no more events are sent. Default: false. */ +} pm_conn_sec_config_t; -/**@brief Data from @ref pm_peer_data_unit_t, as mapped in flash. +/**@brief Data associated with a bond to a peer. */ -typedef union +typedef struct { - pm_peer_data_bonding_t const * p_bonding_data; - bool const * p_service_changed_pending; - pm_peer_data_local_gatt_db_flash_t const * p_local_gatt_db; - pm_peer_data_remote_gatt_db_flash_t const * p_remote_gatt_db; - uint8_t const * p_application_data; -} pm_peer_data_unit_flash_t; + uint8_t own_role; /**< @brief The BLE role of the local device during bonding. See @ref BLE_GAP_ROLES. */ + ble_gap_id_key_t peer_ble_id; /**< @brief The peer's Bluetooth address and identity resolution key (IRK). */ + ble_gap_enc_key_t peer_ltk; /**< @brief The peer's long-term encryption key (LTK) and master ID. */ + ble_gap_enc_key_t own_ltk; /**< @brief Locally generated long-term encryption key (LTK) and master ID, distributed to the peer. */ +} pm_peer_data_bonding_t; -/**@brief The different types of data associated with a peer. +/**@brief Data on a local GATT database. */ -typedef enum +typedef struct { - PM_PEER_DATA_ID_BONDING, - PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, - PM_PEER_DATA_ID_GATT_LOCAL, - PM_PEER_DATA_ID_GATT_REMOTE, - PM_PEER_DATA_ID_APPLICATION, - PM_PEER_DATA_ID_INVALID, -} pm_peer_data_id_t; - - -//STATIC_ASSERT_MSG(sizeof(pm_peer_data_t) == sizeof(pm_peer_data_const_t), "Size of pm_peer_data_t different from immutable version."); + uint32_t flags; /**< @brief Flags that describe the database attributes. */ + uint16_t len; /**< @brief Size of the attribute array. */ + uint8_t data[1]; /**< @brief Array to hold the database attributes. */ +} pm_peer_data_local_gatt_db_t; -/**@brief Macro saying whether a data_id is valid, i.e. one of the valid enum values. +/**@brief Device Privacy. * - * @param[in] data_id The data_id to check. + * The privacy feature provides a way for the device to avoid being tracked over a period of + * time. The privacy feature, when enabled, hides the local device identity and replaces it + * with a private address that is automatically refreshed at a specified interval. + * + * If a device still wants to be recognized by other peers, it needs to share it's Identity + * Resolving Key (IRK). With this key, a device can generate a random private address that + * can only be recognized by peers in possession of that key, and devices can establish + * connections without revealing their real identities. + * + * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all + * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. + * The IRK distributed during bonding procedure is the device IRK that is active when @ref + * sd_ble_gap_sec_params_reply is called. */ -static __INLINE bool PM_PEER_DATA_ID_IS_VALID(pm_peer_data_id_t data_id) -{ - return ((data_id - PM_PEER_DATA_ID_BONDING) < (PM_PEER_DATA_ID_INVALID - PM_PEER_DATA_ID_BONDING)); -} - +#if (NRF_SD_BLE_API_VERSION < 3) -/**@brief One piece of data associated with a peer, together with the type. - */ typedef struct { - uint16_t length_words; - pm_peer_data_id_t data_type; - pm_peer_data_unit_t data; -} pm_peer_data_t; + uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ + uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ + uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ + ble_gap_irk_t * p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used. + When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored. + By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */ +} pm_privacy_params_t; -/**@brief Immutable version of @ref pm_peer_data_t. - */ -typedef struct -{ - uint16_t length_words; - pm_peer_data_id_t data_type; - pm_peer_data_unit_const_t data; -} pm_peer_data_const_t; -/**@brief Data from @ref pm_peer_data_t, as mapped in flash. - */ -typedef struct -{ - uint16_t length_words; - pm_peer_data_id_t data_type; - pm_peer_data_unit_flash_t data; -} pm_peer_data_flash_t; +/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes + * @{ */ +#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ +#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ +/**@} */ +#else -/**@brief Typedef for type used for write prepares. Used to reserve space in flash - */ -typedef uint32_t pm_prepare_token_t; +typedef ble_gap_privacy_params_t pm_privacy_params_t; +#endif -/**@brief Typedef for type used to hold reference to stored item in flash. - * this token can be used for locking and validity check - */ -typedef uint32_t pm_store_token_t; - /** @} */ +#ifdef __cplusplus +} +#endif #endif /* PEER_MANAGER_TYPES_H__ */ + +/** @} */ diff --git a/components/ble/peer_manager/pm_buffer.c b/components/ble/peer_manager/pm_buffer.c index 833070a..aa35ef8 100644 --- a/components/ble/peer_manager/pm_buffer.c +++ b/components/ble/peer_manager/pm_buffer.c @@ -1,16 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ - - +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "pm_buffer.h" #include @@ -36,7 +65,7 @@ ret_code_t pm_buffer_init(pm_buffer_t * p_buffer, if ( (p_buffer != NULL) && (p_buffer_memory != NULL) && (p_mutex_memory != NULL) - && (buffer_memory_size >= (n_blocks*block_size)) + && (buffer_memory_size >= (n_blocks * block_size)) && (mutex_memory_size >= MUTEX_STORAGE_SIZE(n_blocks)) && (n_blocks != 0) && (block_size != 0)) @@ -60,16 +89,16 @@ uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks) { if (!BUFFER_IS_VALID(p_buffer)) { - return ( BUFFER_INVALID_ID ); + return ( PM_BUFFER_INVALID_ID ); } - uint8_t first_locked_mutex = BUFFER_INVALID_ID; + uint8_t first_locked_mutex = PM_BUFFER_INVALID_ID; for (uint8_t i = 0; i < p_buffer->n_blocks; i++) { if (pm_mutex_lock(p_buffer->p_mutex, i)) { - if (first_locked_mutex == BUFFER_INVALID_ID) + if (first_locked_mutex == PM_BUFFER_INVALID_ID) { first_locked_mutex = i; } @@ -78,17 +107,17 @@ uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks) return first_locked_mutex; } } - else if (first_locked_mutex != BUFFER_INVALID_ID) + else if (first_locked_mutex != PM_BUFFER_INVALID_ID) { for (uint8_t j = first_locked_mutex; j < i; j++) { pm_buffer_release(p_buffer, j); } - first_locked_mutex = BUFFER_INVALID_ID; + first_locked_mutex = PM_BUFFER_INVALID_ID; } } - return ( BUFFER_INVALID_ID ); + return ( PM_BUFFER_INVALID_ID ); } @@ -99,10 +128,10 @@ uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id) return ( NULL ); } - if ( (id != BUFFER_INVALID_ID) + if ( (id != PM_BUFFER_INVALID_ID) && pm_mutex_lock_status_get(p_buffer->p_mutex, id) ) { - return ( &p_buffer->p_memory[id*p_buffer->block_size] ); + return ( &p_buffer->p_memory[id * p_buffer->block_size] ); } else { @@ -114,9 +143,10 @@ uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id) void pm_buffer_release(pm_buffer_t * p_buffer, uint8_t id) { if ( BUFFER_IS_VALID(p_buffer) - && (id != BUFFER_INVALID_ID) + && (id != PM_BUFFER_INVALID_ID) && pm_mutex_lock_status_get(p_buffer->p_mutex, id)) { pm_mutex_unlock(p_buffer->p_mutex, id); } } +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/pm_buffer.h b/components/ble/peer_manager/pm_buffer.h index 906d516..82dfb6f 100644 --- a/components/ble/peer_manager/pm_buffer.h +++ b/components/ble/peer_manager/pm_buffer.h @@ -1,25 +1,59 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BUFFER_H__ #define BUFFER_H__ #include +#include "compiler_abstraction.h" #include "sdk_errors.h" #include "pm_mutex.h" +#ifdef __cplusplus +extern "C" { +#endif + /** + * @cond NO_DOXYGEN * @defgroup pm_buffer Buffer * @ingroup peer_manager * @{ @@ -27,21 +61,29 @@ */ -#define BUFFER_INVALID_ID 0xFF +#define PM_BUFFER_INVALID_ID 0xFF //!< Invalid buffer block ID. + -#define PM_BUFFER_INIT(p_buffer, n_blocks, block_size, err_code) \ -do \ -{ \ - static uint8_t buffer_memory[(n_blocks) * (block_size)]; \ - static uint8_t mutex_memory[MUTEX_STORAGE_SIZE(n_blocks)]; \ - err_code = pm_buffer_init((p_buffer), \ - buffer_memory, \ - (n_blocks) * (block_size), \ - mutex_memory, \ - MUTEX_STORAGE_SIZE(n_blocks), \ - (n_blocks), \ - (block_size)); \ -} while(0) +/**@brief Convenience macro for declaring memory and initializing a buffer instance. + * + * @param[out] p_buffer The buffer instance to initialize. + * @param[in] n_blocks The desired number of blocks in the buffer. + * @param[in] block_size The desired block size of the buffer. + * @param[out] err_code The return code from @ref pm_buffer_init. + */ +#define PM_BUFFER_INIT(p_buffer, n_blocks, block_size, err_code) \ +do \ +{ \ + __ALIGN(4) static uint8_t buffer_memory[(n_blocks) * (block_size)]; \ + __ALIGN(4) static uint8_t mutex_memory[MUTEX_STORAGE_SIZE(n_blocks)]; \ + err_code = pm_buffer_init((p_buffer), \ + buffer_memory, \ + (n_blocks) * (block_size), \ + mutex_memory, \ + MUTEX_STORAGE_SIZE(n_blocks), \ + (n_blocks), \ + (block_size)); \ +} while (0) typedef struct @@ -82,7 +124,7 @@ ret_code_t pm_buffer_init(pm_buffer_t * p_buffer, * @param[in] n_blocks The number of contiguous blocks to acquire. * * @return The id of the acquired block, if successful. - * @retval BUFFER_INVALID_ID If unsuccessful. + * @retval PM_BUFFER_INVALID_ID If unsuccessful. */ uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks); @@ -106,8 +148,14 @@ uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id); void pm_buffer_release(pm_buffer_t * p_buffer, uint8_t id); + +#ifdef __cplusplus +} +#endif + #endif // BUFFER_H__ /** * @} + * @endcond */ diff --git a/components/ble/peer_manager/pm_mutex.c b/components/ble/peer_manager/pm_mutex.c index d6e9e2d..f4198bc 100644 --- a/components/ble/peer_manager/pm_mutex.c +++ b/components/ble/peer_manager/pm_mutex.c @@ -1,16 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ - +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "pm_mutex.h" #include @@ -113,3 +142,4 @@ bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_id) return true; } } +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/pm_mutex.h b/components/ble/peer_manager/pm_mutex.h index c75a0a7..ad4fe1b 100644 --- a/components/ble/peer_manager/pm_mutex.h +++ b/components/ble/peer_manager/pm_mutex.h @@ -1,15 +1,42 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ - +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 MUTEX_H__ @@ -19,7 +46,12 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** + * @cond NO_DOXYGEN * @defgroup pm_mutex Mutex * @ingroup peer_manager * @{ @@ -83,6 +115,13 @@ void pm_mutex_unlock(uint8_t * p_mutex, uint16_t mutex_bit_id); bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_bit_id); + +#ifdef __cplusplus +} +#endif + #endif // MUTEX_H__ -/** @} */ +/** @} + * @endcond + */ diff --git a/components/ble/peer_manager/security_dispatcher.c b/components/ble/peer_manager/security_dispatcher.c index 66c1724..e115367 100644 --- a/components/ble/peer_manager/security_dispatcher.c +++ b/components/ble/peer_manager/security_dispatcher.c @@ -1,15 +1,45 @@ -/* Copyright (C) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "security_dispatcher.h" #include @@ -21,150 +51,66 @@ #include "id_manager.h" -#define MAX_REGISTRANTS 3 /**< The number of user that can register with the module. */ +// The number of registered event handlers. +#define SMD_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) -#define MODULE_INITIALIZED (m_smd.n_registrants > 0) /**< Expression which is true when the module is initialized. */ - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * @ref NRF_ERROR_INVALID_STATE if not. - */ -#define VERIFY_MODULE_INITIALIZED() \ -do \ -{ \ - if (!MODULE_INITIALIZED) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * if not. - * - * @param[in] param The variable to check if is NULL. - */ -#define VERIFY_PARAM_NOT_NULL(param) \ -do \ -{ \ - if (param == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } \ -} while(0) +// Security Dispacher event handlers in Security Manager and GATT Cache Manager. +extern void sm_smd_evt_handler(smd_evt_t const * p_event); +extern void gcm_smd_evt_handler(smd_evt_t const * p_event); -typedef struct +// Security Dispatcher events' handlers. +// The number of elements in this array is SMD_EVENT_HANDLERS_CNT. +static smd_evt_handler_t const m_evt_handlers[] = { - smd_evt_handler_t evt_handlers[MAX_REGISTRANTS]; - uint8_t n_registrants; - pm_peer_id_t pending_bond_central; - pm_peer_id_t pending_bond_peripheral; -} smd_t; + sm_smd_evt_handler, + gcm_smd_evt_handler +}; -static smd_t m_smd; +static bool m_module_initialized; -static void internal_state_reset(smd_t * smd) -{ - memset(smd, 0, sizeof(smd_t)); - smd->pending_bond_central = PM_PEER_ID_INVALID; - smd->pending_bond_peripheral = PM_PEER_ID_INVALID; -} - - -/**@brief Function for storing the fact that a new bond is being made. - * - * @details This specifies that there is no bonding data yet stored for this peer. The role is - * needed because the SoftDevice supports two simultaneous bonding procedures, one per role. - * - * @param[in] role The role of the local device in the bonding procedure. - * @param[in] peer_id ID of the device being bonded with. - */ -static void pending_bond_push(uint8_t role, pm_peer_id_t peer_id) -{ - if (role == BLE_GAP_ROLE_CENTRAL) - { - m_smd.pending_bond_central = peer_id; - } - else - { - m_smd.pending_bond_peripheral = peer_id; - } -} - - -/**@brief Function for reading and clearing the record of whether a new bond is being made. - * - * @details If the bonding fails, and this function returns true this peer ID must be freed. The - * role is needed because the SoftDevice supports two simultaneous bonding procedures, one - * per role. - * - * @param[in] role The role of the local device in the bonding procedure. - * @param[in] peer_id ID of the device being bonded with. - * - * @return Whether a new bond was/is being made. I.E. whether @ref pending_bond_push has been - * called with the same parameters. - */ -static bool pending_bond_pop(uint8_t role, pm_peer_id_t peer_id) -{ - if (peer_id == PM_PEER_ID_INVALID) - { - return false; - } +static ble_conn_state_user_flag_id_t m_flag_sec_proc = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_sec_proc_pairing = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_sec_proc_new_peer = BLE_CONN_STATE_USER_FLAG_INVALID; - if ((role == BLE_GAP_ROLE_CENTRAL) && (m_smd.pending_bond_central == peer_id)) - { - m_smd.pending_bond_central = PM_PEER_ID_INVALID; - return true; - } - else if ((role == BLE_GAP_ROLE_PERIPH) && (m_smd.pending_bond_peripheral == peer_id)) - { - m_smd.pending_bond_peripheral = PM_PEER_ID_INVALID; - return true; - } - else - { - return false; - } -} +static ble_gap_lesc_p256_pk_t m_peer_pk; static void evt_send(smd_evt_t * p_event) { - for (int i = 0; i < m_smd.n_registrants; i++) + for (uint32_t i = 0; i < SMD_EVENT_HANDLERS_CNT; i++) { - m_smd.evt_handlers[i](p_event); + m_evt_handlers[i](p_event); } } -static void sec_start_send(uint16_t conn_handle, pm_sec_procedure_t procedure) +static void sec_start_send(uint16_t conn_handle, pm_conn_sec_procedure_t procedure) { smd_evt_t evt = { - .evt_id = SMD_EVT_SEC_PROCEDURE_START, + .evt_id = SMD_EVT_SEC_PROCEDURE_START, .conn_handle = conn_handle, - .params = {.sec_procedure_start = {.procedure = procedure}} + .params = {.sec_procedure_start = {.procedure = procedure}} }; evt_send(&evt); } -/**@brief Event handler for events from the peer_database module. +/**@brief Event handler for events from the Peer Database module. + * This handler is extern in Peer Database. * * @param[in] p_event The event that has happened. */ -static void pdb_evt_handler(pdb_evt_t const * p_event) +void smd_pdb_evt_handler(pdb_evt_t const * p_event) { if ((p_event->evt_id == PDB_EVT_WRITE_BUF_STORED) && (p_event->data_id == PM_PEER_DATA_ID_BONDING)) { smd_evt_t evt = { - .evt_id = SMD_EVT_BONDING_INFO_STORED, + .evt_id = SMD_EVT_BONDING_INFO_STORED, .conn_handle = im_conn_handle_get(p_event->peer_id), - .params = {.bonding_info_stored = - { - .peer_id = p_event->peer_id, - }} + .params = {.bonding_info_stored = {.peer_id = p_event->peer_id}} }; evt_send(&evt); } @@ -179,7 +125,7 @@ static void sec_params_request_process(ble_gap_evt_t * p_gap_evt) { smd_evt_t evt = { - .evt_id = SMD_EVT_PARAMS_REQ, + .evt_id = SMD_EVT_PARAMS_REQ, .conn_handle = p_gap_evt->conn_handle }; evt_send(&evt); @@ -187,6 +133,44 @@ static void sec_params_request_process(ble_gap_evt_t * p_gap_evt) } +/**@brief Function for administrative actions to be taken when a security process has been attempted. + * + * @param[in] conn_handle The connection the security process was attempted on. + * @param[in] peer_id The peer ID given to the connected peer. + * @param[in] success Whether the process was started successfully. + * @param[in] pairing Whether the process was a pairing process. + * @param[in] new_peer_created Whether a new peer was created during the process attempt. + */ +static void sec_proc_start(uint16_t conn_handle, + pm_peer_id_t peer_id, + bool success, + bool pairing, + bool new_peer_created) +{ + ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, success); + + if (success) + { + ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc_pairing, pairing); + ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc_new_peer, new_peer_created); + + if (new_peer_created) + { + im_new_peer_id(conn_handle, peer_id); + } + } + else + { + if (new_peer_created) + { + ret_code_t err_code = im_peer_free(peer_id); // Attempt to free allocated peer. + UNUSED_VARIABLE(err_code); + } + } +} + + + /**@brief Function for processing the @ref BLE_GAP_EVT_SEC_INFO_REQUEST event from the SoftDevice. * * @param[in] p_gap_evt The event from the SoftDevice. @@ -201,22 +185,23 @@ static void sec_info_request_process(ble_gap_evt_t * p_gap_evt) evt.conn_handle = p_gap_evt->conn_handle; + if (peer_id == PM_PEER_ID_INVALID) + { + peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle); + } + if (peer_id != PM_PEER_ID_INVALID) { - err_code = pdb_read_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data, NULL); + err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data); if (err_code == NRF_SUCCESS) { // There is stored bonding data for this peer. - ble_gap_enc_key_t const * p_existing_key = &peer_data.data.p_bonding_data->own_ltk; + ble_gap_enc_key_t const * p_existing_key = &peer_data.p_bonding_data->own_ltk; - if (peer_data.data.p_bonding_data->own_role == BLE_GAP_ROLE_CENTRAL) - { - // Role has changed since bonding. - p_existing_key = &peer_data.data.p_bonding_data->peer_ltk; - } - - if (im_master_id_is_valid(&p_existing_key->master_id)) + if ( p_existing_key->enc_info.lesc + || (im_master_ids_compare(&p_existing_key->master_id, + &p_gap_evt->params.sec_info_request.master_id))) { p_enc_info = &p_existing_key->enc_info; } @@ -236,15 +221,21 @@ static void sec_info_request_process(ble_gap_evt_t * p_gap_evt) else if (p_enc_info == NULL) { evt.evt_id = SMD_EVT_LINK_ENCRYPTION_FAILED; - evt.params.link_encryption_failed.error = PM_SEC_ERROR_CODE_PIN_OR_KEY_MISSING; + evt.params.link_encryption_failed.error = PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING; evt.params.link_encryption_failed.error_src = BLE_GAP_SEC_STATUS_SOURCE_LOCAL; evt_send(&evt); + + sec_proc_start(p_gap_evt->conn_handle, peer_id, false, false, false); } else { sec_start_send(p_gap_evt->conn_handle, PM_LINK_SECURED_PROCEDURE_ENCRYPTION); + + sec_proc_start(p_gap_evt->conn_handle, peer_id, err_code == NRF_SUCCESS, false, false); } + + return; } @@ -280,13 +271,13 @@ static void sec_request_process(ble_gap_evt_t * p_gap_evt) */ static void auth_status_success_process(ble_gap_evt_t * p_gap_evt) { - ret_code_t err_code = NRF_SUCCESS; - uint8_t role = ble_conn_state_role(p_gap_evt->conn_handle); - pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle); - ble_gap_sec_kdist_t kdist_periph = p_gap_evt->params.auth_status.kdist_periph; - ble_gap_sec_kdist_t kdist_central = p_gap_evt->params.auth_status.kdist_central; - ble_gap_sec_kdist_t kdist_own = (role == BLE_GAP_ROLE_CENTRAL) ? kdist_central : kdist_periph; - ble_gap_sec_kdist_t kdist_peer = (role == BLE_GAP_ROLE_CENTRAL) ? kdist_periph : kdist_central; + ret_code_t err_code = NRF_SUCCESS; + uint8_t role = ble_conn_state_role(p_gap_evt->conn_handle); + pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle); + ble_gap_sec_kdist_t kdist_own = p_gap_evt->params.auth_status.kdist_own; + ble_gap_sec_kdist_t kdist_peer = p_gap_evt->params.auth_status.kdist_peer; + + ble_conn_state_user_flag_set(p_gap_evt->conn_handle, m_flag_sec_proc, false); if (role == BLE_GAP_ROLE_INVALID) { @@ -294,66 +285,157 @@ static void auth_status_success_process(ble_gap_evt_t * p_gap_evt) return; } - pending_bond_pop(role, peer_id); + if (p_gap_evt->params.auth_status.bonded) + { - err_code = pdb_write_buf_store(peer_id, PM_PEER_DATA_ID_BONDING); - if (err_code != NRF_SUCCESS) + err_code = pdb_write_buf_store(peer_id, PM_PEER_DATA_ID_BONDING); + if (err_code != NRF_SUCCESS) + { + /* Unexpected */ + smd_evt_t error_evt; + + error_evt.evt_id = SMD_EVT_ERROR_BONDING_INFO; + error_evt.conn_handle = p_gap_evt->conn_handle; + error_evt.params.error_bonding_info.peer_id = peer_id; + error_evt.params.error_bonding_info.error = err_code; + + evt_send(&error_evt); + } + + } + else if (ble_conn_state_user_flag_get(p_gap_evt->conn_handle, m_flag_sec_proc_new_peer)) { - /* Unexpected */ - smd_evt_t error_evt = + ret_code_t err_code_free = im_peer_free(peer_id); + UNUSED_VARIABLE(err_code_free); // Errors can be safely ignored. + } + + smd_evt_t pairing_success_evt; + + pairing_success_evt.evt_id = SMD_EVT_PAIRING_SUCCESS; + pairing_success_evt.conn_handle = p_gap_evt->conn_handle; + pairing_success_evt.params.pairing_success.bonded = p_gap_evt->params.auth_status.bonded; + pairing_success_evt.params.pairing_success.mitm = p_gap_evt->params.auth_status.sm1_levels.lv3; + pairing_success_evt.params.pairing_success.kdist_own = kdist_own; + pairing_success_evt.params.pairing_success.kdist_peer = kdist_peer; + + evt_send(&pairing_success_evt); + return; +} + + +/**@brief Function for cleaning up after a failed pairing procedure. + * + * @param[in] conn_handle The handle of the connection the pairing procedure happens on. + * @param[in] peer_id The peer id used in the pairing procedure. + * @param[in] error The error the procedure failed with. + * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES. + */ +static void pairing_failure(uint16_t conn_handle, + pm_peer_id_t peer_id, + pm_sec_error_code_t error, + uint8_t error_src) +{ + ret_code_t err_code = NRF_SUCCESS; + + smd_evt_t evt = + { + .evt_id = SMD_EVT_PAIRING_FAIL, + .conn_handle = conn_handle, + .params = { - .evt_id = SMD_EVT_ERROR_BONDING_INFO, - .conn_handle = p_gap_evt->conn_handle, - .params = + .pairing_failed = { - .error_bonding_info = - { - .peer_id = peer_id, - .error = err_code, - } + .error = error, + .error_src = error_src, } - }; - evt_send(&error_evt); + } + }; + + if (ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc_new_peer)) + { + // The peer_id was created during the procedure, and should be freed, because no data is + // stored under it. + err_code = im_peer_free(peer_id); // Attempt to free allocated peer. + UNUSED_VARIABLE(err_code); + } + else + { + err_code = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING); + if ((err_code != NRF_SUCCESS) && (err_code == NRF_ERROR_NOT_FOUND /* No buffer was allocated */)) + { + smd_evt_t error_evt; + error_evt.evt_id = SMD_EVT_ERROR_UNEXPECTED; + error_evt.conn_handle = conn_handle; + error_evt.params.error_unexpected.error = err_code; + evt_send(&error_evt); + } } - smd_evt_t pairing_success_evt = + ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, false); + + evt_send(&evt); + return; +} + + +/**@brief Function for cleaning up after a failed encryption procedure. + * + * @param[in] conn_handle The handle of the connection the encryption procedure happens on. + * @param[in] error The error the procedure failed with. + * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES. + */ +static void encryption_failure(uint16_t conn_handle, + pm_sec_error_code_t error, + uint8_t error_src) +{ + smd_evt_t evt = { - .evt_id = SMD_EVT_PAIRING_SUCCESS, - .conn_handle = p_gap_evt->conn_handle, - .params = + .evt_id = SMD_EVT_LINK_ENCRYPTION_FAILED, + .conn_handle = conn_handle, + .params = { - .pairing_success = + .link_encryption_failed = { - .bonded = p_gap_evt->params.auth_status.bonded, - .mitm = p_gap_evt->params.auth_status.sm1_levels.lv3, - .kdist_own = kdist_own, - .kdist_peer = kdist_peer, + .error = error, + .error_src = error_src, } } }; - evt_send(&pairing_success_evt); + + ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, false); + + evt_send(&evt); return; } -/**@brief Function for cleaning up after a failed pairing procedure. +/**@brief Function for possibly cleaning up after a failed pairing or encryption procedure. * - * @param[in] role Our role in the pairing procedure. See @ref BLE_GAP_ROLES. - * @param[in] peer_id The peer id used in the pairing procedure. + * @param[in] conn_handle The handle of the connection the pairing procedure happens on. + * @param[in] peer_id The peer id used in the pairing procedure. + * @param[in] error The error the procedure failed with. + * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES. */ -static void pairing_failure(uint8_t role, pm_peer_id_t peer_id) +static void link_secure_failure(uint16_t conn_handle, + pm_sec_error_code_t error, + uint8_t error_src) { - if(pending_bond_pop(role, peer_id)) + if (ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc)) { - // The peer_id was created during the procedure, and should be freed, because no data is stored under it. - pdb_peer_free(peer_id); - } - else - { - pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING); - } + pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle); - return; + if (peer_id != PM_PEER_ID_INVALID) + { + if (ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc_pairing)) + { + pairing_failure(conn_handle, peer_id, error, error_src); + } + else + { + encryption_failure(conn_handle, error, error_src); + } + } + } } @@ -363,33 +445,12 @@ static void pairing_failure(uint8_t role, pm_peer_id_t peer_id) */ static void disconnect_process(ble_gap_evt_t * p_gap_evt) { - uint8_t role = ble_conn_state_role(p_gap_evt->conn_handle); - pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle); - - if ( (peer_id != PM_PEER_ID_INVALID) - && (p_gap_evt->params.disconnected.reason == BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE) - && (pending_bond_pop(role, peer_id))) - { -// smd_evt_t evt = -// { -// .evt_id = SMD_EVT_PAIRING_FAIL, -// .conn_handle = p_gap_evt->conn_handle, -// .params = -// { -// .pairing_failed = -// { -// .auth_status = ? -// .error_src = ? -// } -// } -// }; - - pairing_failure(role, peer_id); - -// evt_send(&evt); - } -} + pm_sec_error_code_t error = (p_gap_evt->params.disconnected.reason + == BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE) + ? PM_CONN_SEC_ERROR_MIC_FAILURE : PM_CONN_SEC_ERROR_DISCONNECT; + link_secure_failure(p_gap_evt->conn_handle, error, BLE_GAP_SEC_STATUS_SOURCE_LOCAL); +} /**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice, when @@ -399,25 +460,9 @@ static void disconnect_process(ble_gap_evt_t * p_gap_evt) */ static void auth_status_failure_process(ble_gap_evt_t * p_gap_evt) { - uint8_t role = ble_conn_state_role(p_gap_evt->conn_handle); - pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle); - smd_evt_t evt = - { - .evt_id = SMD_EVT_PAIRING_FAIL, - .conn_handle = p_gap_evt->conn_handle, - .params = - { - .pairing_failed = - { - .auth_status = p_gap_evt->params.auth_status.auth_status, - .error_src = p_gap_evt->params.auth_status.error_src, - } - } - }; - - pairing_failure(role, peer_id); - - evt_send(&evt); + link_secure_failure(p_gap_evt->conn_handle, + p_gap_evt->params.auth_status.auth_status, + p_gap_evt->params.auth_status.error_src); } @@ -427,16 +472,12 @@ static void auth_status_failure_process(ble_gap_evt_t * p_gap_evt) */ static void auth_status_process(ble_gap_evt_t * p_gap_evt) { - switch(p_gap_evt->params.auth_status.auth_status) + switch (p_gap_evt->params.auth_status.auth_status) { case BLE_GAP_SEC_STATUS_SUCCESS: auth_status_success_process(p_gap_evt); break; - case BLE_GAP_SEC_STATUS_PDU_INVALID: - /* Ignore, because they don't have anything to do with an ongoing procedure. */ - break; - default: auth_status_failure_process(p_gap_evt); break; @@ -450,69 +491,76 @@ static void auth_status_process(ble_gap_evt_t * p_gap_evt) */ static void conn_sec_update_process(ble_gap_evt_t * p_gap_evt) { - smd_evt_t evt; - - evt.conn_handle = p_gap_evt->conn_handle; - if (ble_conn_state_encrypted(p_gap_evt->conn_handle)) { + if (!ble_conn_state_user_flag_get(p_gap_evt->conn_handle, m_flag_sec_proc_pairing)) + { + ble_conn_state_user_flag_set(p_gap_evt->conn_handle, m_flag_sec_proc, false); + } + + smd_evt_t evt; + + evt.conn_handle = p_gap_evt->conn_handle; evt.evt_id = SMD_EVT_LINK_ENCRYPTION_UPDATE; evt.params.link_encryption_update.mitm_protected = ble_conn_state_mitm_protected(p_gap_evt->conn_handle); + evt_send(&evt); } else { - evt.evt_id = SMD_EVT_LINK_ENCRYPTION_FAILED; - evt.params.link_encryption_failed.error = PM_SEC_ERROR_CODE_PIN_OR_KEY_MISSING; - evt.params.link_encryption_failed.error_src = BLE_GAP_SEC_STATUS_SOURCE_REMOTE; + encryption_failure(p_gap_evt->conn_handle, + PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING, + BLE_GAP_SEC_STATUS_SOURCE_REMOTE); } - - evt_send(&evt); } -ret_code_t smd_register(smd_evt_handler_t evt_handler) +/**@brief Funtion for initializing a BLE Connection State user flag. + * + * @param[out] flag_id The flag to initialize. + */ +static void flag_id_init(ble_conn_state_user_flag_id_t * p_flag_id) { - ret_code_t err_code = NRF_SUCCESS; - if (evt_handler == NULL) + if (*p_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) { - err_code = NRF_ERROR_NULL; + *p_flag_id = ble_conn_state_user_flag_acquire(); } - else +} + + +ret_code_t smd_init(void) +{ + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + flag_id_init(&m_flag_sec_proc); + flag_id_init(&m_flag_sec_proc_pairing); + flag_id_init(&m_flag_sec_proc_new_peer); + + if ((m_flag_sec_proc == BLE_CONN_STATE_USER_FLAG_INVALID) || + (m_flag_sec_proc_pairing == BLE_CONN_STATE_USER_FLAG_INVALID) || + (m_flag_sec_proc_new_peer == BLE_CONN_STATE_USER_FLAG_INVALID)) { - if (!MODULE_INITIALIZED) - { - err_code = pdb_register(pdb_evt_handler); - if (err_code == NRF_SUCCESS) - { - internal_state_reset(&m_smd); - } - } - if ((err_code == NRF_SUCCESS)) - { - if ((m_smd.n_registrants < MAX_REGISTRANTS)) - { - m_smd.evt_handlers[m_smd.n_registrants++] = evt_handler; - } - else - { - err_code = NRF_ERROR_NO_MEM; - } - } + return NRF_ERROR_INTERNAL; } - return err_code; + + m_module_initialized = true; + + return NRF_SUCCESS; } -ret_code_t smd_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params) +ret_code_t smd_params_reply(uint16_t conn_handle, + ble_gap_sec_params_t * p_sec_params, + ble_gap_lesc_p256_pk_t * p_public_key) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); uint8_t role = ble_conn_state_role(conn_handle); pm_peer_id_t peer_id = PM_PEER_ID_INVALID; ret_code_t err_code = NRF_SUCCESS; uint8_t sec_status = BLE_GAP_SEC_STATUS_SUCCESS; ble_gap_sec_keyset_t sec_keyset; + bool new_peer_created = false; memset(&sec_keyset, 0, sizeof(ble_gap_sec_keyset_t)); @@ -539,7 +587,7 @@ ret_code_t smd_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_p peer_id = pdb_peer_allocate(); if (peer_id != PM_PEER_ID_INVALID) { - pending_bond_push(role, peer_id); + new_peer_created = true; } else { @@ -549,26 +597,25 @@ ret_code_t smd_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_p if (err_code == NRF_SUCCESS) { - // Peer ID is OK, retrieve memory buffer to receive data. + // Peer ID is ready, acquire a memory buffer to receive bonding data into. err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, 1, &peer_data); if (err_code == NRF_SUCCESS) { - peer_data.data.p_bonding_data->own_role = role; - - if (role == BLE_GAP_ROLE_CENTRAL) - { - sec_keyset.keys_central.p_enc_key = &peer_data.data.p_bonding_data->own_ltk; - sec_keyset.keys_periph.p_enc_key = &peer_data.data.p_bonding_data->peer_ltk; - sec_keyset.keys_periph.p_id_key = &peer_data.data.p_bonding_data->peer_id; - im_ble_addr_get(conn_handle, &peer_data.data.p_bonding_data->peer_id.id_addr_info); // Will be overwritten if ID is shared. - } - else - { - sec_keyset.keys_periph.p_enc_key = &peer_data.data.p_bonding_data->own_ltk; - sec_keyset.keys_central.p_enc_key = &peer_data.data.p_bonding_data->peer_ltk; - sec_keyset.keys_central.p_id_key = &peer_data.data.p_bonding_data->peer_id; - im_ble_addr_get(conn_handle, &peer_data.data.p_bonding_data->peer_id.id_addr_info); // Will be overwritten if ID is shared. - } + memset(peer_data.p_bonding_data, 0, sizeof(pm_peer_data_bonding_t)); + + peer_data.p_bonding_data->own_role = role; + + sec_keyset.keys_own.p_enc_key = &peer_data.p_bonding_data->own_ltk; + sec_keyset.keys_own.p_pk = p_public_key; + sec_keyset.keys_peer.p_enc_key = &peer_data.p_bonding_data->peer_ltk; + sec_keyset.keys_peer.p_id_key = &peer_data.p_bonding_data->peer_ble_id; + sec_keyset.keys_peer.p_pk = &m_peer_pk; + + // Retrieve the address the peer used during connection establishment. + // This address will be overwritten if ID is shared. Should not fail. + ret_code_t err_code_addr = im_ble_addr_get(conn_handle, + &peer_data.p_bonding_data->peer_ble_id.id_addr_info); + UNUSED_VARIABLE(err_code_addr); // Buffer is OK, reserve room in flash for the data. err_code = pdb_write_buf_store_prepare(peer_id, PM_PEER_DATA_ID_BONDING); @@ -594,7 +641,7 @@ ret_code_t smd_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_p if ((p_sec_params != NULL) && (err_code == NRF_SUCCESS)) { - pm_sec_procedure_t procedure = p_sec_params->bond + pm_conn_sec_procedure_t procedure = p_sec_params->bond ? PM_LINK_SECURED_PROCEDURE_BONDING : PM_LINK_SECURED_PROCEDURE_PAIRING; sec_start_send(conn_handle, procedure); @@ -602,52 +649,49 @@ ret_code_t smd_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_p } } - if(pending_bond_pop(role, peer_id)) - { - // New peer ID created, either report it or free it. - if (err_code == NRF_SUCCESS) - { - pending_bond_push(role, peer_id); - im_new_peer_id(conn_handle, peer_id); - } - else - { - pdb_peer_free(peer_id); - } - } + sec_proc_start(conn_handle, + peer_id, + (err_code == NRF_SUCCESS) && (sec_status != BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP), + true, + new_peer_created); + return err_code; } -static ret_code_t link_secure_central_existing_peer(uint16_t conn_handle, - ble_gap_sec_params_t * p_sec_params, - bool force_repairing, - pm_peer_id_t peer_id, - pm_sec_procedure_t * procedure) +static ret_code_t link_secure_central_existing_peer(uint16_t conn_handle, + ble_gap_sec_params_t * p_sec_params, + bool force_repairing, + pm_peer_id_t peer_id, + pm_conn_sec_procedure_t * procedure) { pm_peer_data_flash_t peer_data; pm_peer_data_t dummy_peer_data; ret_code_t err_code; ble_gap_enc_key_t const * p_existing_key = NULL; + bool lesc = false; - - err_code = pdb_read_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data, NULL); + err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data); if (err_code == NRF_SUCCESS) { - p_existing_key = &(peer_data.data.p_bonding_data->peer_ltk); - if (peer_data.data.p_bonding_data->own_role == BLE_GAP_ROLE_PERIPH) + // Use peer's key since they are peripheral. + p_existing_key = &(peer_data.p_bonding_data->peer_ltk); + + lesc = peer_data.p_bonding_data->own_ltk.enc_info.lesc; + if (lesc) // LESC was used during bonding. { - // Role has changed since bonding. - p_existing_key = &(peer_data.data.p_bonding_data->own_ltk); + // For LESC, always use own key. + p_existing_key = &(peer_data.p_bonding_data->own_ltk); } } if (!force_repairing && (err_code == NRF_SUCCESS) && (p_existing_key != NULL) - && (im_master_id_is_valid(&(p_existing_key->master_id))) /* There is an existing LTK stored. */ - && (p_existing_key->enc_info.auth >= p_sec_params->mitm)) /* The requested security is at or below the existing level. */ + && (lesc || im_master_id_is_valid(&(p_existing_key->master_id)))) /* There is a valid LTK stored. */ + //&& (p_existing_key->enc_info.auth >= p_sec_params->mitm) /* The requested MITM security is at or below the existing level. */ + //&& (!p_sec_params->mitm || (lesc >= p_sec_params->lesc))) /* The requested LESC security is at or below the existing level. We only care about LESC if MITM is required. */ { err_code = sd_ble_gap_encrypt(conn_handle, &(p_existing_key->master_id), &(p_existing_key->enc_info)); @@ -683,6 +727,12 @@ static ret_code_t link_secure_central_existing_peer(uint16_t conn_ } } + sec_proc_start(conn_handle, + peer_id, + err_code == NRF_SUCCESS, + *procedure != PM_LINK_SECURED_PROCEDURE_ENCRYPTION, + false); + return err_code; } @@ -709,17 +759,11 @@ static ret_code_t link_secure_central_new_peer(uint16_t conn_handl if (err_code != NRF_SUCCESS) { - ret_code_t err_code_release = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING); - if ((err_code_release != NRF_SUCCESS) && (err_code_release != NRF_ERROR_NOT_FOUND)) + ret_code_t err_code_free = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING); + if ((err_code_free != NRF_SUCCESS) && (err_code_free != NRF_ERROR_NOT_FOUND)) { err_code = NRF_ERROR_INTERNAL; } - pdb_peer_free(peer_id); - } - else - { - pending_bond_push(BLE_GAP_ROLE_CENTRAL, peer_id); - im_new_peer_id(conn_handle, peer_id); } } else @@ -727,6 +771,12 @@ static ret_code_t link_secure_central_new_peer(uint16_t conn_handl err_code = NRF_ERROR_INTERNAL; } + sec_proc_start(conn_handle, + peer_id, + err_code == NRF_SUCCESS, + true, + peer_id != PM_PEER_ID_INVALID); + return err_code; } @@ -743,8 +793,8 @@ static ret_code_t link_secure_central(uint16_t conn_handle, return sd_ble_gap_authenticate(conn_handle, NULL); } - pm_sec_procedure_t procedure = p_sec_params->bond ? PM_LINK_SECURED_PROCEDURE_BONDING - : PM_LINK_SECURED_PROCEDURE_PAIRING; + pm_conn_sec_procedure_t procedure = p_sec_params->bond ? PM_LINK_SECURED_PROCEDURE_BONDING + : PM_LINK_SECURED_PROCEDURE_PAIRING; peer_id = im_peer_id_get_by_conn_handle(conn_handle); @@ -764,7 +814,10 @@ static ret_code_t link_secure_central(uint16_t conn_handle, } else { + // No bonding, only pairing. err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params); + + sec_proc_start(conn_handle, peer_id, err_code == NRF_SUCCESS, true, false); } if (err_code == NRF_SUCCESS) @@ -776,24 +829,34 @@ static ret_code_t link_secure_central(uint16_t conn_handle, } +static ret_code_t link_secure_peripheral(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params) +{ + // This should never happen for a peripheral. + NRF_PM_DEBUG_CHECK(p_sec_params != NULL); + + // VERIFY_PARAM_NOT_NULL(p_sec_params); + + ret_code_t err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params); + + return err_code; +} + + ret_code_t smd_link_secure(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params, bool force_repairing) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); uint8_t role = ble_conn_state_role(conn_handle); switch (role) { case BLE_GAP_ROLE_CENTRAL: - return link_secure_central(conn_handle, - p_sec_params, - force_repairing); + return link_secure_central(conn_handle, p_sec_params, force_repairing); case BLE_GAP_ROLE_PERIPH: - VERIFY_PARAM_NOT_NULL(p_sec_params); - return sd_ble_gap_authenticate(conn_handle, p_sec_params); + return link_secure_peripheral(conn_handle, p_sec_params); default: return BLE_ERROR_INVALID_CONN_HANDLE; @@ -830,4 +893,4 @@ void smd_ble_evt_handler(ble_evt_t * p_ble_evt) break; }; } - +#endif //NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/security_dispatcher.h b/components/ble/peer_manager/security_dispatcher.h index bd1ef50..fde6714 100644 --- a/components/ble/peer_manager/security_dispatcher.h +++ b/components/ble/peer_manager/security_dispatcher.h @@ -1,26 +1,60 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SECURITY_DISPATCHER_H__ #define SECURITY_DISPATCHER_H__ -#include "stdint.h" +#include #include "sdk_errors.h" #include "ble.h" #include "ble_gap.h" #include "peer_manager_types.h" +#ifdef __cplusplus +extern "C" { +#endif + /** + * @cond NO_DOXYGEN * @defgroup security_dispatcher Security Dispatcher * @ingroup peer_manager * @{ @@ -61,7 +95,7 @@ typedef struct */ typedef struct { - pm_sec_procedure_t procedure; /**< The procedure that has started. */ + pm_conn_sec_procedure_t procedure; /**< The procedure that has started. */ } smd_evt_sec_procedure_start_t; @@ -80,8 +114,8 @@ typedef struct */ typedef struct { - uint8_t auth_status; /**< The error code describing the error. See @ref BLE_GAP_SEC_STATUS. */ - uint8_t error_src; /**< The origin of the error. See @ref BLE_GAP_SEC_STATUS_SOURCES. */ + pm_sec_error_code_t error; /**< What went wrong. */ + uint8_t error_src; /**< The party that raised the error, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ } smd_evt_pairing_failed_t; @@ -98,7 +132,7 @@ typedef struct typedef struct { pm_sec_error_code_t error; /**< What went wrong. */ - uint8_t error_src; /**< The party which raised the error, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ + uint8_t error_src; /**< The party that raised the error, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ } smd_evt_link_encryption_failed_t; @@ -115,7 +149,7 @@ typedef struct typedef struct { pm_peer_id_t peer_id; /**< The peer this event pertains to, if previously bonded. @ref PM_PEER_ID_INVALID if no successful bonding has happened with the peer before. */ - ret_code_t error; /**< The unexpected error that occurred. */ + ret_code_t error; /**< The unexpected error that occurred. */ } smd_evt_error_bonding_info_t; @@ -166,6 +200,7 @@ typedef struct typedef void (*smd_evt_handler_t)(smd_evt_t const * p_event); +#if 0 /**@brief Function for registering with the Security Dispatcher module. This function also * initializes the module if uninitialized. * @@ -176,6 +211,10 @@ typedef void (*smd_evt_handler_t)(smd_evt_t const * p_event); * @retval NRF_ERROR_NULL evt_handler was NULL. */ ret_code_t smd_register(smd_evt_handler_t evt_handler); +#endif + + +ret_code_t smd_init(void); /**@brief Function for dispatching SoftDevice events to the Security Dispatcher module. @@ -189,13 +228,14 @@ void smd_ble_evt_handler(ble_evt_t * ble_evt); * procedure on a connection. * * @note If this function returns an @ref NRF_ERROR_NULL, @ref NRF_ERROR_INVALID_PARAM, @ref - * BLE_ERROR_INVALID_CONN_HANDLE, or @ref NRF_ERROR_NO_MEM, this function can be called again - * after corrective action. + * BLE_ERROR_INVALID_CONN_HANDLE, or @ref NRF_ERROR_STORAGE_FULL, this function can be called + * again after corrective action. * * @note To reject a request, call this function with NULL p_sec_params. * * @param[in] conn_handle The connection handle of the connection the pairing is happening on. * @param[in] p_sec_params The security parameters to use for this link. + * @param[in] p_public_key A pointer to the public key to use if using LESC, or NULL. * * @retval NRF_SUCCESS Success. * @retval NRF_ERROR_INVALID_STATE Module is not initialized, or no parameters have been @@ -205,10 +245,13 @@ void smd_ble_evt_handler(ble_evt_t * ble_evt); * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations * can be performed on this link. * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. - * @retval NRF_ERROR_NO_MEM No more room in flash. Fix and reattempt later. + * @retval NRF_ERROR_STORAGE_FULL No more room in flash. Fix and reattempt after the next + * FDS garbage collection procedure. * @retval NRF_ERROR_BUSY No write buffer. Reattempt later. */ -ret_code_t smd_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params); +ret_code_t smd_params_reply(uint16_t conn_handle, + ble_gap_sec_params_t * p_sec_params, + ble_gap_lesc_p256_pk_t * p_public_key); /**@brief Function for initiating security on the link, with the specified parameters. @@ -235,14 +278,21 @@ ret_code_t smd_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_p * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations * can be performed on this link. * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. - * @retval NRF_ERROR_NO_MEM No more room in flash, or no space in RAM for - * peer_database to use. + * @retval NRF_ERROR_STORAGE_FULL No more room in flash. Fix and reattempt after the next + * FDS garbage collection procedure. * @retval NRF_ERROR_INTERNAL No more available peer IDs. */ ret_code_t smd_link_secure(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params, bool force_repairing); -/** @} */ +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif #endif /* SECURITY_DISPATCHER_H__ */ diff --git a/components/ble/peer_manager/security_manager.c b/components/ble/peer_manager/security_manager.c index 1a8cb21..ed31708 100644 --- a/components/ble/peer_manager/security_manager.c +++ b/components/ble/peer_manager/security_manager.c @@ -1,96 +1,88 @@ -/* Copyright (C) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PEER_MANAGER) #include "security_manager.h" + #include #include "security_dispatcher.h" #include "peer_database.h" #include "ble_conn_state.h" +#include "id_manager.h" +// The number of registered event handlers. +#define SM_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0])) -#define MAX_REGISTRANTS 3 /**< The number of user that can register with the module. */ -#define MODULE_INITIALIZED (m_sm.n_registrants > 0) /**< Expression which is true when the module is initialized. */ +// Security Manager event handler in Peer Manager. +extern void pm_sm_evt_handler(sm_evt_t const * p_sm_evt); -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * @ref NRF_ERROR_INVALID_STATE if not. - */ -#define VERIFY_MODULE_INITIALIZED() \ -do \ -{ \ - if (!MODULE_INITIALIZED) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * if not. - */ -#define VERIFY_MODULE_INITIALIZED_VOID()\ -do \ -{ \ - if (!MODULE_INITIALIZED) \ - { \ - return; \ - } \ -} while(0) - - -/**@brief Macro for verifying that the module is initialized. It will cause the function to return - * if not. - * - * @param[in] param The variable to check if is NULL. - */ -#define VERIFY_PARAM_NOT_NULL(param) \ -do \ -{ \ - if (param == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } \ -} while(0) +// Security Manager events' handlers. +// The number of elements in this array is SM_EVENT_HANDLERS_CNT. +static sm_evt_handler_t const m_evt_handlers[] = +{ + pm_sm_evt_handler +}; +static bool m_module_initialized; -typedef struct -{ - sm_evt_handler_t evt_handlers[MAX_REGISTRANTS]; - uint8_t n_registrants; - ble_conn_state_user_flag_id_t flag_id_link_secure_pending_busy; - ble_conn_state_user_flag_id_t flag_id_link_secure_pending_flash_full; - ble_conn_state_user_flag_id_t flag_id_link_secure_force_repairing; - ble_conn_state_user_flag_id_t flag_id_link_secure_null_params; - ble_conn_state_user_flag_id_t flag_id_params_reply_pending_busy; - ble_conn_state_user_flag_id_t flag_id_params_reply_pending_flash_full; - bool pdb_evt_handler_registered; - bool sec_params_valid; - ble_gap_sec_params_t sec_params; -} sm_t; - -static sm_t m_sm = {.flag_id_link_secure_pending_busy = BLE_CONN_STATE_USER_FLAG_INVALID, - .flag_id_link_secure_pending_flash_full = BLE_CONN_STATE_USER_FLAG_INVALID, - .flag_id_link_secure_force_repairing = BLE_CONN_STATE_USER_FLAG_INVALID, - .flag_id_link_secure_null_params = BLE_CONN_STATE_USER_FLAG_INVALID, - .flag_id_params_reply_pending_busy = BLE_CONN_STATE_USER_FLAG_INVALID, - .flag_id_params_reply_pending_flash_full = BLE_CONN_STATE_USER_FLAG_INVALID}; +static ble_gap_sec_params_t m_sec_params; +static bool m_sec_params_valid; + +static ble_gap_lesc_p256_pk_t * m_p_public_key; +static ble_conn_state_user_flag_id_t m_flag_link_secure_pending_busy = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_link_secure_pending_flash_full = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_link_secure_force_repairing = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_link_secure_null_params = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_params_reply_pending_busy = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_params_reply_pending_flash_full = BLE_CONN_STATE_USER_FLAG_INVALID; +static ble_conn_state_user_flag_id_t m_flag_reject_pairing = BLE_CONN_STATE_USER_FLAG_INVALID; static void evt_send(sm_evt_t * p_event) { - for (int i = 0; i < m_sm.n_registrants; i++) + for (uint32_t i = 0; i < SM_EVENT_HANDLERS_CNT; i++) { - m_sm.evt_handlers[i](p_event); + m_evt_handlers[i](p_event); } } @@ -100,14 +92,14 @@ static void flags_set_from_err_code(uint16_t conn_handle, ret_code_t err_code, b bool flag_value_flash_full = false; bool flag_value_busy = false; - if ( (err_code == NRF_ERROR_NO_MEM) + if ( (err_code == NRF_ERROR_STORAGE_FULL) || (err_code == NRF_ERROR_BUSY) || (err_code == NRF_SUCCESS)) { - if ((err_code == NRF_ERROR_NO_MEM)) + if ((err_code == NRF_ERROR_STORAGE_FULL)) { - flag_value_flash_full = true; flag_value_busy = false; + flag_value_flash_full = true; } else if (err_code == NRF_ERROR_BUSY) { @@ -123,25 +115,25 @@ static void flags_set_from_err_code(uint16_t conn_handle, ret_code_t err_code, b if (params_reply) { ble_conn_state_user_flag_set(conn_handle, - m_sm.flag_id_params_reply_pending_flash_full, + m_flag_params_reply_pending_flash_full, flag_value_flash_full); ble_conn_state_user_flag_set(conn_handle, - m_sm.flag_id_params_reply_pending_busy, + m_flag_params_reply_pending_busy, flag_value_busy); ble_conn_state_user_flag_set(conn_handle, - m_sm.flag_id_link_secure_pending_flash_full, + m_flag_link_secure_pending_flash_full, false); ble_conn_state_user_flag_set(conn_handle, - m_sm.flag_id_link_secure_pending_busy, + m_flag_link_secure_pending_busy, false); } else { ble_conn_state_user_flag_set(conn_handle, - m_sm.flag_id_link_secure_pending_flash_full, + m_flag_link_secure_pending_flash_full, flag_value_flash_full); ble_conn_state_user_flag_set(conn_handle, - m_sm.flag_id_link_secure_pending_busy, + m_flag_link_secure_pending_busy, flag_value_busy); } } @@ -163,7 +155,7 @@ static void events_send_from_err_code(uint16_t conn_handle, ret_code_t err_code) { evt.evt_id = SM_EVT_ERROR_SMP_TIMEOUT; } - else if (err_code == NRF_ERROR_NO_MEM) + else if (err_code == NRF_ERROR_STORAGE_FULL) { evt.evt_id = SM_EVT_ERROR_NO_MEM; } @@ -180,18 +172,18 @@ static ret_code_t link_secure(uint16_t conn_handle, bool null_params, bool force { ret_code_t err_code; - if (!null_params && !m_sm.sec_params_valid) + if (!null_params && !m_sec_params_valid) { return NRF_ERROR_NOT_FOUND; } - if(null_params) + if (null_params) { err_code = smd_link_secure(conn_handle, NULL, force_repairing); } else { - err_code = smd_link_secure(conn_handle, &m_sm.sec_params, force_repairing); + err_code = smd_link_secure(conn_handle, &m_sec_params, force_repairing); } flags_set_from_err_code(conn_handle, err_code, false); @@ -204,13 +196,13 @@ static ret_code_t link_secure(uint16_t conn_handle, bool null_params, bool force switch (err_code) { case NRF_ERROR_BUSY: - ble_conn_state_user_flag_set(conn_handle, m_sm.flag_id_link_secure_null_params, null_params); - ble_conn_state_user_flag_set(conn_handle, m_sm.flag_id_link_secure_force_repairing, force_repairing); + ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_null_params, null_params); + ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_force_repairing, force_repairing); err_code = NRF_SUCCESS; break; - case NRF_ERROR_NO_MEM: - ble_conn_state_user_flag_set(conn_handle, m_sm.flag_id_link_secure_null_params, null_params); - ble_conn_state_user_flag_set(conn_handle, m_sm.flag_id_link_secure_force_repairing, force_repairing); + case NRF_ERROR_STORAGE_FULL: + ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_null_params, null_params); + ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_force_repairing, force_repairing); break; case NRF_SUCCESS: case NRF_ERROR_TIMEOUT: @@ -227,17 +219,42 @@ static ret_code_t link_secure(uint16_t conn_handle, bool null_params, bool force } +static void send_config_req(uint16_t conn_handle) +{ + sm_evt_t sm_evt; + memset(&sm_evt, 0, sizeof(sm_evt)); + + sm_evt.evt_id = SM_EVT_CONN_SEC_CONFIG_REQ; + sm_evt.conn_handle = conn_handle; + + evt_send(&sm_evt); +} + + static void smd_params_reply_perform(uint16_t conn_handle) { ret_code_t err_code; - if (m_sm.sec_params_valid) + if ( (ble_conn_state_role(conn_handle) == BLE_GAP_ROLE_PERIPH) + && im_peer_id_get_by_conn_handle(conn_handle) != PM_PEER_ID_INVALID) { - err_code = smd_params_reply(conn_handle, &m_sm.sec_params); + // Bond already exists. Reject the pairing request if the user doesn't intervene. + ble_conn_state_user_flag_set(conn_handle, m_flag_reject_pairing, true); + send_config_req(conn_handle); } else { - err_code = smd_params_reply(conn_handle, NULL); + ble_conn_state_user_flag_set(conn_handle, m_flag_reject_pairing, false); + } + + if ( m_sec_params_valid + && !ble_conn_state_user_flag_get(conn_handle, m_flag_reject_pairing)) + { + err_code = smd_params_reply(conn_handle, &m_sec_params, m_p_public_key); + } + else + { + err_code = smd_params_reply(conn_handle, NULL, NULL); } flags_set_from_err_code(conn_handle, err_code, true); @@ -245,9 +262,14 @@ static void smd_params_reply_perform(uint16_t conn_handle) } -static void smd_evt_handler(smd_evt_t const * p_event) +/**@brief Event handler for events from the Security Dispatcher module. + * This handler is extern in Security Dispatcher. + * + * @param[in] p_event The event that has happened. + */ +void sm_smd_evt_handler(smd_evt_t const * p_event) { - switch(p_event->evt_id) + switch (p_event->evt_id) { case SMD_EVT_PARAMS_REQ: smd_params_reply_perform(p_event->conn_handle); @@ -255,20 +277,23 @@ static void smd_evt_handler(smd_evt_t const * p_event) case SMD_EVT_SLAVE_SECURITY_REQ: { bool null_params = false; - if (!m_sm.sec_params_valid) + if (!m_sec_params_valid) { null_params = true; } - else if ((bool)m_sm.sec_params.bond < (bool)p_event->params.slave_security_req.bond) + else if ((bool)m_sec_params.bond < (bool)p_event->params.slave_security_req.bond) { null_params = true; } - else if ((bool)m_sm.sec_params.mitm < (bool)p_event->params.slave_security_req.mitm) + else if ((bool)m_sec_params.mitm < (bool)p_event->params.slave_security_req.mitm) { null_params = true; } - link_secure(p_event->conn_handle, null_params, false, true); + ret_code_t err_code = link_secure(p_event->conn_handle, null_params, false, true); + UNUSED_VARIABLE(err_code); // It is acceptable to ignore the return code because it is + // acceptable to ignore a security request. } + /* fallthrough */ case SMD_EVT_PAIRING_SUCCESS: case SMD_EVT_PAIRING_FAIL: case SMD_EVT_LINK_ENCRYPTION_UPDATE: @@ -278,12 +303,11 @@ static void smd_evt_handler(smd_evt_t const * p_event) case SMD_EVT_ERROR_UNEXPECTED: case SMD_EVT_SEC_PROCEDURE_START: { - sm_evt_t evt = - { - .evt_id = (sm_evt_id_t)p_event->evt_id, - .conn_handle = p_event->conn_handle, - .params = p_event->params, - }; + sm_evt_t evt; + evt.evt_id = (sm_evt_id_t)p_event->evt_id; + evt.conn_handle = p_event->conn_handle; + evt.params = p_event->params; + evt_send(&evt); } break; @@ -298,15 +322,16 @@ static void link_secure_pending_process(ble_conn_state_user_flag_id_t flag_id) { sdk_mapped_flags_key_list_t conn_handle_list = ble_conn_state_conn_handles(); - for (int i = 0; i < conn_handle_list.len; i++) + for (uint32_t i = 0; i < conn_handle_list.len; i++) { bool pending = ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], flag_id); if (pending) { - bool force_repairing = ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_sm.flag_id_link_secure_force_repairing); - bool null_params = ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_sm.flag_id_link_secure_null_params); + bool force_repairing = ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_flag_link_secure_force_repairing); + bool null_params = ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], m_flag_link_secure_null_params); - link_secure(conn_handle_list.flag_keys[i], null_params, force_repairing, true); + ret_code_t err_code = link_secure(conn_handle_list.flag_keys[i], null_params, force_repairing, true); // If this fails, it will be automatically retried. + UNUSED_VARIABLE(err_code); } } } @@ -320,7 +345,7 @@ static void params_reply_pending_process(ble_conn_state_user_flag_id_t flag_id) { sdk_mapped_flags_key_list_t conn_handle_list = ble_conn_state_conn_handles(); - for (int i = 0; i < conn_handle_list.len; i++) + for (uint32_t i = 0; i < conn_handle_list.len; i++) { bool pending = ble_conn_state_user_flag_get(conn_handle_list.flag_keys[i], flag_id); if (pending) @@ -332,22 +357,28 @@ static void params_reply_pending_process(ble_conn_state_user_flag_id_t flag_id) } - -static void pdb_evt_handler(pdb_evt_t const * p_event) +/**@brief Event handler for events from the Peer Database module. + * This handler is extern in Peer Database. + * + * @param[in] p_event The event that has happened. + */ +void sm_pdb_evt_handler(pdb_evt_t const * p_event) { switch (p_event->evt_id) { case PDB_EVT_COMPRESSED: - params_reply_pending_process(m_sm.flag_id_params_reply_pending_flash_full); - link_secure_pending_process(m_sm.flag_id_link_secure_pending_flash_full); + params_reply_pending_process(m_flag_params_reply_pending_flash_full); + link_secure_pending_process(m_flag_link_secure_pending_flash_full); /* fallthrough */ case PDB_EVT_WRITE_BUF_STORED: case PDB_EVT_RAW_STORED: case PDB_EVT_RAW_STORE_FAILED: case PDB_EVT_CLEARED: case PDB_EVT_CLEAR_FAILED: - params_reply_pending_process(m_sm.flag_id_params_reply_pending_busy); - link_secure_pending_process(m_sm.flag_id_link_secure_pending_busy); + case PDB_EVT_PEER_FREED: + case PDB_EVT_PEER_FREE_FAILED: + params_reply_pending_process(m_flag_params_reply_pending_busy); + link_secure_pending_process(m_flag_link_secure_pending_busy); break; case PDB_EVT_ERROR_NO_MEM: case PDB_EVT_ERROR_UNEXPECTED: @@ -356,76 +387,48 @@ static void pdb_evt_handler(pdb_evt_t const * p_event) } -/**@brief Macro for initializing a BLE Connection State user flag. +/**@brief Funtion for initializing a BLE Connection State user flag. * * @param[out] flag_id The flag to initialize. */ -#define FLAG_ID_INIT(flag_id) \ -do \ -{ \ - if ((flag_id) == BLE_CONN_STATE_USER_FLAG_INVALID) \ - { \ - (flag_id) = ble_conn_state_user_flag_acquire(); \ - if ((flag_id) == BLE_CONN_STATE_USER_FLAG_INVALID)\ - { \ - return NRF_ERROR_INTERNAL; \ - } \ - } \ -} while(0) - - -ret_code_t sm_register(sm_evt_handler_t evt_handler) +static void flag_id_init(ble_conn_state_user_flag_id_t * p_flag_id) { - VERIFY_PARAM_NOT_NULL(evt_handler); - - ret_code_t err_code = NRF_SUCCESS; - - if (!MODULE_INITIALIZED) + if (*p_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID) { - FLAG_ID_INIT(m_sm.flag_id_link_secure_pending_busy); - FLAG_ID_INIT(m_sm.flag_id_link_secure_pending_flash_full); - FLAG_ID_INIT(m_sm.flag_id_link_secure_force_repairing); - FLAG_ID_INIT(m_sm.flag_id_link_secure_null_params); - FLAG_ID_INIT(m_sm.flag_id_params_reply_pending_busy); - FLAG_ID_INIT(m_sm.flag_id_params_reply_pending_flash_full); - - if (!m_sm.pdb_evt_handler_registered) - { - err_code = pdb_register(pdb_evt_handler); - if (err_code != NRF_SUCCESS) - { - return NRF_ERROR_INTERNAL; - } - m_sm.pdb_evt_handler_registered = true; - } - err_code = smd_register(smd_evt_handler); - if (err_code != NRF_SUCCESS) - { - return NRF_ERROR_INTERNAL; - } + *p_flag_id = ble_conn_state_user_flag_acquire(); } - if (err_code == NRF_SUCCESS) +} + + +ret_code_t sm_init(void) +{ + NRF_PM_DEBUG_CHECK(!m_module_initialized); + + flag_id_init(&m_flag_link_secure_pending_busy); + flag_id_init(&m_flag_link_secure_pending_flash_full); + flag_id_init(&m_flag_link_secure_force_repairing); + flag_id_init(&m_flag_link_secure_null_params); + flag_id_init(&m_flag_params_reply_pending_busy); + flag_id_init(&m_flag_params_reply_pending_flash_full); + flag_id_init(&m_flag_reject_pairing); + + if (m_flag_reject_pairing == BLE_CONN_STATE_USER_FLAG_INVALID) { - if ((m_sm.n_registrants < MAX_REGISTRANTS)) - { - m_sm.evt_handlers[m_sm.n_registrants++] = evt_handler; - } - else - { - err_code = NRF_ERROR_NO_MEM; - } + return NRF_ERROR_INTERNAL; } - return err_code; + + m_module_initialized = true; + + return NRF_SUCCESS; } void sm_ble_evt_handler(ble_evt_t * p_ble_evt) { - VERIFY_MODULE_INITIALIZED_VOID(); + NRF_PM_DEBUG_CHECK(p_ble_evt != NULL); smd_ble_evt_handler(p_ble_evt); - - link_secure_pending_process(m_sm.flag_id_link_secure_pending_busy); + link_secure_pending_process(m_flag_link_secure_pending_busy); } @@ -474,26 +477,32 @@ static bool sec_params_verify(ble_gap_sec_params_t * p_sec_params) } // Signing is not supported. - if (p_sec_params->kdist_periph.sign || p_sec_params->kdist_central.sign) + if (p_sec_params->kdist_own.sign || p_sec_params->kdist_peer.sign) + { + return false; + } + + // link bit must be 0. + if (p_sec_params->kdist_own.link || p_sec_params->kdist_peer.link) { return false; } // If bonding is not enabled, no keys can be distributed. - if (!p_sec_params->bond && ( p_sec_params->kdist_periph.enc - || p_sec_params->kdist_periph.id - || p_sec_params->kdist_central.enc - || p_sec_params->kdist_central.id)) + if (!p_sec_params->bond && ( p_sec_params->kdist_own.enc + || p_sec_params->kdist_own.id + || p_sec_params->kdist_peer.enc + || p_sec_params->kdist_peer.id)) { return false; } // If bonding is enabled, one or more keys must be distributed. if ( p_sec_params->bond - && !p_sec_params->kdist_periph.enc - && !p_sec_params->kdist_periph.id - && !p_sec_params->kdist_central.enc - && !p_sec_params->kdist_central.id) + && !p_sec_params->kdist_own.enc + && !p_sec_params->kdist_own.id + && !p_sec_params->kdist_peer.enc + && !p_sec_params->kdist_peer.id) { return false; } @@ -504,17 +513,17 @@ static bool sec_params_verify(ble_gap_sec_params_t * p_sec_params) ret_code_t sm_sec_params_set(ble_gap_sec_params_t * p_sec_params) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); if (p_sec_params == NULL) { - m_sm.sec_params_valid = false; + m_sec_params_valid = false; return NRF_SUCCESS; } else if (sec_params_verify(p_sec_params)) { - m_sm.sec_params = *p_sec_params; - m_sm.sec_params_valid = true; + m_sec_params = *p_sec_params; + m_sec_params_valid = true; return NRF_SUCCESS; } else @@ -524,17 +533,39 @@ ret_code_t sm_sec_params_set(ble_gap_sec_params_t * p_sec_params) } +void sm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + NRF_PM_DEBUG_CHECK(p_conn_sec_config != NULL); + + ble_conn_state_user_flag_set(conn_handle, m_flag_reject_pairing, !p_conn_sec_config->allow_repairing); +} + + +ret_code_t sm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key) +{ + NRF_PM_DEBUG_CHECK(m_module_initialized); + + m_p_public_key = p_public_key; + + return NRF_SUCCESS; +} + + ret_code_t sm_sec_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params) { - VERIFY_MODULE_INITIALIZED(); + NRF_PM_DEBUG_CHECK(m_module_initialized); return NRF_SUCCESS; } ret_code_t sm_link_secure(uint16_t conn_handle, bool force_repairing) { - VERIFY_MODULE_INITIALIZED(); - ret_code_t err_code = link_secure(conn_handle, false, force_repairing, false); - return err_code; -} + ret_code_t ret; + NRF_PM_DEBUG_CHECK(m_module_initialized); + + ret = link_secure(conn_handle, false, force_repairing, false); + return ret; +} +#endif // NRF_MODULE_ENABLED(PEER_MANAGER) diff --git a/components/ble/peer_manager/security_manager.h b/components/ble/peer_manager/security_manager.h index 6c2743b..0f19057 100644 --- a/components/ble/peer_manager/security_manager.h +++ b/components/ble/peer_manager/security_manager.h @@ -1,27 +1,61 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SECURITY_MANAGER_H__ #define SECURITY_MANAGER_H__ -#include "stdint.h" +#include #include "sdk_errors.h" #include "ble.h" #include "ble_gap.h" #include "peer_manager_types.h" #include "security_dispatcher.h" +#ifdef __cplusplus +extern "C" { +#endif + /** + * @cond NO_DOXYGEN * @defgroup security_manager Security Manager * @ingroup peer_manager * @{ @@ -35,7 +69,7 @@ typedef enum { // SM_EVT_PARAMS_REQ = SMD_EVT_PARAMS_REQ, /**< Parameters are required for a pairing procedure on the specified connection. The user must provide them using @ref sm_sec_params_set or @ref sm_sec_params_reply (only this procedure, currently unimplemented). */ - SM_EVT_SLAVE_SECURITY_REQ = SMD_EVT_SLAVE_SECURITY_REQ, /**< The peer (slave) has requested link encryption, which has been enabled. */ + SM_EVT_SLAVE_SECURITY_REQ = SMD_EVT_SLAVE_SECURITY_REQ, /**< The peer (peripheral) has requested link encryption, which has been enabled. */ SM_EVT_SEC_PROCEDURE_START = SMD_EVT_SEC_PROCEDURE_START, /**< A security procedure has started. */ SM_EVT_PAIRING_SUCCESS = SMD_EVT_PAIRING_SUCCESS, /**< A pairing procedure (and bonding if applicable) has completed with success. */ SM_EVT_PAIRING_FAIL = SMD_EVT_PAIRING_FAIL, /**< A pairing procedure has failed which means no encryption and no bond could be established. */ @@ -46,6 +80,7 @@ typedef enum SM_EVT_ERROR_UNEXPECTED = SMD_EVT_ERROR_UNEXPECTED, /**< An operation failed with an unexpected error. The error is provided. This is possibly a fatal error. */ SM_EVT_ERROR_NO_MEM /*= SMD_EVT_ERROR_NO_MEM*/, /**< An operation failed because there was no available storage room in persistent storage. Please free up room and the operation will automatically continue after the next compression. */ SM_EVT_ERROR_SMP_TIMEOUT, /**< An operation failed because there has been an SMP timeout on the link, which entails that no more security operations can be performed on it. */ + SM_EVT_CONN_SEC_CONFIG_REQ, /**< The peer (central) has requested pairing, but a bond already exists with that peer. Reply by calling @ref sm_conn_sec_config_reply before the event handler returns. If no reply is sent, a default is used. */ } sm_evt_id_t; @@ -57,7 +92,6 @@ typedef struct } sm_evt_t; - /**@brief Event handler for events from the Security Manager module. * * @param[in] event The event that has happened. @@ -66,17 +100,12 @@ typedef struct typedef void (*sm_evt_handler_t)(sm_evt_t const * p_event); -/**@brief Function for registering with the Security Manager module. This function also - * initializes the module if uninitialized. - * - * @param[in] evt_handler Callback for events from the Security Manager module. +/**@brief Function for initializing the Security Manager module. * - * @retval NRF_SUCCESS Registration was successful. - * @retval NRF_ERROR_NO_MEM No more registrations possible. - * @retval NRF_ERROR_NULL evt_handler was NULL. - * @retval NRF_ERROR_INTERNAL An unexpected error occurred. + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INTERNAL If an unexpected error occurred. */ -ret_code_t sm_register(sm_evt_handler_t evt_handler); +ret_code_t sm_init(void); /**@brief Function for dispatching SoftDevice events to the Security Manager module. @@ -102,14 +131,43 @@ void sm_ble_evt_handler(ble_evt_t * ble_evt); ret_code_t sm_sec_params_set(ble_gap_sec_params_t * p_sec_params); +/**@brief Function for providing security configuration for a link. + * + * @details This function is optional, and must be called in reply to a @ref + * SM_EVT_CONN_SEC_CONFIG_REQ event, before the Peer Manager event handler returns. If it + * is not called in time, a default configuration is used. See @ref pm_conn_sec_config_t + * for the value of the default. + * + * @param[in] conn_handle The connection to set the configuration for. + * @param[in] p_conn_sec_config The configuration. + */ +void sm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config); + + +/**@brief Experimental function for specifying the public key to use for LESC operations. + * + * @details This function can be called multiple times. The specified public key will be used for + * all subsequent LESC (LE Secure Connections) operations until the next time this function + * is called. + * + * @note The key must continue to reside in application memory as it is not copied by Peer Manager. + * + * @param[in] p_public_key The public key to use for all subsequent LESC operations. + * + * @retval NRF_SUCCESS Pairing initiated successfully. + * @retval NRF_ERROR_INVALID_STATE Peer Manager is not initialized. + */ +ret_code_t sm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key); + + /**@brief Function for providing pairing and bonding parameters to use for the current pairing * procedure on a connection. * * @warning This function is not yet implemented. * * @note If this function returns an @ref NRF_ERROR_NULL, @ref NRF_ERROR_INVALID_PARAM, @ref - * BLE_ERROR_INVALID_CONN_HANDLE, or @ref NRF_ERROR_NO_MEM, this function can be called again - * after corrective action. + * BLE_ERROR_INVALID_CONN_HANDLE, or @ref NRF_ERROR_STORAGE_FULL, this function can be called + * again after corrective action. * * @note To reject a request, call this function with NULL p_sec_params. * @@ -124,7 +182,7 @@ ret_code_t sm_sec_params_set(ble_gap_sec_params_t * p_sec_params); * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations * can be performed on this link. * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. - * @retval NRF_ERROR_NO_MEM No more room in flash. Fix and reattempt later. + * @retval NRF_ERROR_STORAGE_FULL No more room in flash. Fix and reattempt later. * @retval NRF_ERROR_BUSY No write buffer. Reattempt later. */ ret_code_t sm_sec_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params); @@ -153,6 +211,13 @@ ret_code_t sm_sec_params_reply(uint16_t conn_handle, ble_gap_sec_params_t * p_se */ ret_code_t sm_link_secure(uint16_t conn_handle, bool force_repairing); -/** @} */ +/** @} + * @endcond + */ + + +#ifdef __cplusplus +} +#endif #endif /* SECURITY_MANAGER_H__ */ diff --git a/components/boards/arduino_primo.h b/components/boards/arduino_primo.h new file mode 100644 index 0000000..3171382 --- /dev/null +++ b/components/boards/arduino_primo.h @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ARDUINO_PRIMO_H +#define ARDUINO_PRIMO_H + +#ifdef __cplusplus +extern "C" { +#endif + +// LEDs definitions +#define LEDS_NUMBER 1 + +#define LED_1 25 + +#define LEDS_ACTIVE_STATE 0 + +#define LEDS_LIST { LED_1} + +#define BSP_LED_0 LED_1 + +#define LEDS_INV_MASK 0 + +#define BUTTONS_NUMBER 1 + +#define BUTTON_START 7 +#define BUTTON_1 7 +#define BUTTON_STOP 7 +#define BUTTON_PULL NRF_GPIO_PIN_PULLUP + +#define BUTTONS_ACTIVE_STATE 0 + +#define BUTTONS_LIST { BUTTON_1 } + +#define BSP_BUTTON_0 BUTTON_1 + +#define RX_PIN_NUMBER 11 +#define TX_PIN_NUMBER 12 +#define CTS_PIN_NUMBER UART_PIN_DISCONNECTED +#define RTS_PIN_NUMBER UART_PIN_DISCONNECTED +#define HWFC false + +// Arduino board mappings +#define ARDUINO_SCL_PIN 27 // SCL signal pin +#define ARDUINO_SDA_PIN 26 // SDA signal pin +#define ARDUINO_AREF_PIN 2 // Aref pin +#define ARDUINO_13_PIN 25 // Digital pin 13 +#define ARDUINO_12_PIN 24 // Digital pin 12 +#define ARDUINO_11_PIN 23 // Digital pin 11 +#define ARDUINO_10_PIN 22 // Digital pin 10 +#define ARDUINO_9_PIN 20 // Digital pin 9 +#define ARDUINO_8_PIN 19 // Digital pin 8 + +#define ARDUINO_7_PIN 18 // Digital pin 7 +#define ARDUINO_6_PIN 17 // Digital pin 6 +#define ARDUINO_5_PIN 16 // Digital pin 5 +#define ARDUINO_4_PIN 15 // Digital pin 4 +#define ARDUINO_3_PIN 14 // Digital pin 3 +#define ARDUINO_2_PIN 13 // Digital pin 2 +#define ARDUINO_1_PIN 12 // Digital pin 1 +#define ARDUINO_0_PIN 11 // Digital pin 0 + +#define ARDUINO_A0_PIN 3 // Analog channel 0 +#define ARDUINO_A1_PIN 4 // Analog channel 1 +#define ARDUINO_A2_PIN 28 // Analog channel 2 +#define ARDUINO_A3_PIN 29 // Analog channel 3 +#define ARDUINO_A4_PIN 30 // Analog channel 4 +#define ARDUINO_A5_PIN 31 // Analog channel 5 + +// Low frequency clock source to be used by the SoftDevice +#define NRF_CLOCK_LFCLKSRC {.source = NRF_CLOCK_LF_SRC_XTAL, \ + .rc_ctiv = 0, \ + .rc_temp_ctiv = 0, \ + .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM} + + +#ifdef __cplusplus +} +#endif + +#endif // ARDUINO_PRIMO_H diff --git a/components/boards/boards.c b/components/boards/boards.c new file mode 100644 index 0000000..7fb6fe4 --- /dev/null +++ b/components/boards/boards.c @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "boards.h" +#include +#include + +#if LEDS_NUMBER > 0 +static const uint8_t m_board_led_list[LEDS_NUMBER] = LEDS_LIST; +#endif + +#if BUTTONS_NUMBER > 0 +static const uint8_t m_board_btn_list[BUTTONS_NUMBER] = BUTTONS_LIST; +#endif + +#if LEDS_NUMBER > 0 +bool bsp_board_led_state_get(uint32_t led_idx) +{ + ASSERT(led_idx < LEDS_NUMBER); + bool pin_set = nrf_gpio_pin_out_read(m_board_led_list[led_idx]) ? true : false; + return (pin_set == (LEDS_ACTIVE_STATE ? true : false)); +} + +void bsp_board_led_on(uint32_t led_idx) +{ + ASSERT(led_idx < LEDS_NUMBER); + nrf_gpio_pin_write(m_board_led_list[led_idx], LEDS_ACTIVE_STATE ? 1 : 0); +} + +void bsp_board_led_off(uint32_t led_idx) +{ + ASSERT(led_idx < LEDS_NUMBER); + nrf_gpio_pin_write(m_board_led_list[led_idx], LEDS_ACTIVE_STATE ? 0 : 1); +} + +void bsp_board_leds_off(void) +{ + uint32_t i; + for(i = 0; i < LEDS_NUMBER; ++i) + { + bsp_board_led_off(i); + } +} + +void bsp_board_leds_on(void) +{ + uint32_t i; + for(i = 0; i < LEDS_NUMBER; ++i) + { + bsp_board_led_on(i); + } +} + +void bsp_board_led_invert(uint32_t led_idx) +{ + ASSERT(led_idx < LEDS_NUMBER); + nrf_gpio_pin_toggle(m_board_led_list[led_idx]); +} + +void bsp_board_leds_init(void) +{ + uint32_t i; + for(i = 0; i < LEDS_NUMBER; ++i) + { + nrf_gpio_cfg_output(m_board_led_list[i]); + } + bsp_board_leds_off(); +} + +uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx) +{ + ASSERT(led_idx < LEDS_NUMBER); + return m_board_led_list[led_idx]; +} + +uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number) +{ + uint32_t ret = 0xFFFFFFFF; + uint32_t i; + for(i = 0; i < LEDS_NUMBER; ++i) + { + if (m_board_led_list[i] == pin_number) + { + ret = i; + break; + } + } + return ret; +} +#endif //LEDS_NUMBER > 0 + +#if BUTTONS_NUMBER > 0 +bool bsp_board_button_state_get(uint32_t button_idx) +{ + ASSERT(button_idx < BUTTONS_NUMBER); + bool pin_set = nrf_gpio_pin_read(m_board_btn_list[button_idx]) ? true : false; + return (pin_set == (BUTTONS_ACTIVE_STATE ? true : false)); +} + +void bsp_board_buttons_init(void) +{ + uint32_t i; + for(i = 0; i < BUTTONS_NUMBER; ++i) + { + nrf_gpio_cfg_input(m_board_btn_list[i], BUTTON_PULL); + } +} + +uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number) +{ + uint32_t i; + uint32_t ret = 0xFFFFFFFF; + for(i = 0; i < BUTTONS_NUMBER; ++i) + { + if (m_board_btn_list[i] == pin_number) + { + ret = i; + break; + } + } + return ret; +} + +uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx) +{ + ASSERT(button_idx < BUTTONS_NUMBER); + return m_board_btn_list[button_idx]; +} +#endif //BUTTONS_NUMBER > 0 diff --git a/components/boards/boards.h b/components/boards/boards.h new file mode 100644 index 0000000..87fca80 --- /dev/null +++ b/components/boards/boards.h @@ -0,0 +1,319 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BOARDS_H +#define BOARDS_H + +#include "nrf_gpio.h" + +#if defined(BOARD_NRF6310) + #include "nrf6310.h" +#elif defined(BOARD_PCA10000) + #include "pca10000.h" +#elif defined(BOARD_PCA10001) + #include "pca10001.h" +#elif defined(BOARD_PCA10002) + #include "pca10000.h" +#elif defined(BOARD_PCA10003) + #include "pca10003.h" +#elif defined(BOARD_PCA20006) + #include "pca20006.h" +#elif defined(BOARD_PCA10028) + #include "pca10028.h" +#elif defined(BOARD_PCA10031) + #include "pca10031.h" +#elif defined(BOARD_PCA10036) + #include "pca10036.h" +#elif defined(BOARD_PCA10040) + #include "pca10040.h" +#elif defined(BOARD_PCA10056) + #include "pca10056.h" +#elif defined(BOARD_WT51822) + #include "wt51822.h" +#elif defined(BOARD_N5DK1) + #include "n5_starterkit.h" +#elif defined (BOARD_D52DK1) + #include "d52_starterkit.h" +#elif defined (BOARD_ARDUINO_PRIMO) + #include "arduino_primo.h" +#elif defined(BOARD_CUSTOM) + #include "custom_board.h" +#else +#error "Board is not defined" + +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Function for returning the state of an LED. + * + * @param led_idx LED index (starting from 0), as defined in the board-specific header. + * + * @return True if the LED is turned on. + */ +bool bsp_board_led_state_get(uint32_t led_idx); + +/** + * Function for turning on an LED. + * + * @param led_idx LED index (starting from 0), as defined in the board-specific header. + */ +void bsp_board_led_on(uint32_t led_idx); + +/** + * Function for turning off an LED. + * + * @param led_idx LED index (starting from 0), as defined in the board-specific header. + */ +void bsp_board_led_off(uint32_t led_idx); + +/** + * Function for inverting the state of an LED. + * + * @param led_idx LED index (starting from 0), as defined in the board-specific header. + */ +void bsp_board_led_invert(uint32_t led_idx); +/** + * Function for turning off all LEDs. + */ +void bsp_board_leds_off(void); + +/** + * Function for turning on all LEDs. + */ +void bsp_board_leds_on(void); + +/** + * Function for initializing LEDs. + */ +void bsp_board_leds_init(void); + +/** + * Function for converting pin number to LED index. + * + * @param pin_number Pin number. + * + * @return LED index of the given pin or 0xFFFFFFFF if invalid pin provided. + */ +uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number); + +/** + * Function for converting LED index to pin number. + * + * @param led_idx LED index. + * + * @return Pin number. + */ +uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx); + +/** + * Function for returning the state of a button. + * + * @param button_idx Button index (starting from 0), as defined in the board-specific header. + * + * @return True if the button is pressed. + */ +bool bsp_board_button_state_get(uint32_t button_idx); + +/** + * Function for initializing buttons. + */ +void bsp_board_buttons_init(void); + +/** + * Function for converting pin number to button index. + * + * @param pin_number Pin number. + * + * @return Button index of the given pin or 0xFFFFFFFF if invalid pin provided. + */ +uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number); + + +/** + * Function for converting button index to pin number. + * + * @param button_idx Button index. + * + * @return Pin number. + */ +uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx); + +#define BSP_BOARD_LED_0 0 +#define BSP_BOARD_LED_1 1 +#define BSP_BOARD_LED_2 2 +#define BSP_BOARD_LED_3 3 +#define BSP_BOARD_LED_4 4 +#define BSP_BOARD_LED_5 5 +#define BSP_BOARD_LED_6 6 +#define BSP_BOARD_LED_7 7 + +#ifdef BSP_LED_0 +#define BSP_LED_0_MASK (1<OUTSET = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \ + NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0) + +#define LEDS_ON(leds_mask) do { ASSERT(sizeof(leds_mask) == 4); \ + NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \ + NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0) + +#define LED_IS_ON(leds_mask) ((leds_mask) & (NRF_GPIO->OUT ^ LEDS_INV_MASK) ) + +#define LEDS_INVERT(leds_mask) do { uint32_t gpio_state = NRF_GPIO->OUT; \ + ASSERT(sizeof(leds_mask) == 4); \ + NRF_GPIO->OUTSET = ((leds_mask) & ~gpio_state); \ + NRF_GPIO->OUTCLR = ((leds_mask) & gpio_state); } while (0) + +#define LEDS_CONFIGURE(leds_mask) do { uint32_t pin; \ + ASSERT(sizeof(leds_mask) == 4); \ + for (pin = 0; pin < 32; pin++) \ + if ( (leds_mask) & (1 << pin) ) \ + nrf_gpio_cfg_output(pin); } while (0) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/boards/d52_starterkit.h b/components/boards/d52_starterkit.h new file mode 100644 index 0000000..c2bd0bf --- /dev/null +++ b/components/boards/d52_starterkit.h @@ -0,0 +1,140 @@ +/** + * This software is subject to the ANT+ Shared Source License + * www.thisisant.com/swlicenses + * Copyright (c) Dynastream Innovations, Inc. 2016 + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * 1) Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * 2) 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. + * + * 3) Neither the name of Dynastream nor the names of its + * contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * The following actions are prohibited: + * 1) Redistribution of source code containing the ANT+ Network + * Key. The ANT+ Network Key is available to ANT+ Adopters. + * Please refer to http://thisisant.com to become an ANT+ + * Adopter and access the key. + * + * 2) Reverse engineering, decompilation, and/or disassembly of + * software provided in binary form under this license. + * + * 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 HEREBY + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW + * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE + * ABOVE LIMITATIONS MAY NOT APPLY TO YOU. + * + */ + +#ifndef D52STARTERKIT_H +#define D52STARTERKIT_H + +#include "nrf_gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// LEDs definitions for D52DK1 +#define LEDS_NUMBER 4 + +// IO board active low leds +// D52DK1 does not define LED_START or LED_STOP since the LEDS are not on sequential pins +#define LED_A 24 //LED A on D52 Starter Kit IO Board +#define LED_B 31 //LED B on D52 Starter Kit IO Board +#define LED_C 17 //LED C on D52 Starter Kit IO Board +#define LED_D 20 //LED D on D52 Starter Kit IO Board + +#define LEDS_ACTIVE_STATE 0 + +#define LEDS_LIST { LED_A, LED_B, LED_C, LED_D } + +#define BSP_LED_0 LED_A +#define BSP_LED_1 LED_B +#define BSP_LED_2 LED_C +#define BSP_LED_3 LED_D + +#define LEDS_INV_MASK LEDS_MASK + +#define BUTTONS_NUMBER 4 + +// IO board pull-up buttons +#define BUTTON_A 6 //BUTTON A on D52 Starter Kit IO Board +#define BUTTON_B 7 //BUTTON B on D52 Starter Kit IO Board +#define BUTTON_C 16 //BUTTON C on D52 Starter Kit IO Board +#define BUTTON_D 19 //BUTTON D on D52 Starter Kit IO Board +#define BUTTON_PULL NRF_GPIO_PIN_PULLUP + +#define BUTTONS_ACTIVE_STATE 0 + +#define BSP_BUTTON_0 BUTTON_A +#define BSP_BUTTON_1 BUTTON_B +#define BSP_BUTTON_2 BUTTON_C +#define BSP_BUTTON_3 BUTTON_D + +#define BUTTONS_LIST { BUTTON_A, BUTTON_B, BUTTON_C, BUTTON_D } + +// Battery board pull-up switches +#define SWITCH_1 12 // Switch 1 on D52 Starter Kit Battery Board +#define SWITCH_2 8 // Switch 2 on D52 Starter Kit Battery Board +#define SWITCH_3 15 // Switch 3 on D52 Starter Kit Battery Board +#define SWITCH_4 11 // Switch 4 on D52 Starter Kit Battery Board +#define SWITCH_5 14 // Switch 5 on D52 Starter Kit Battery Board +#define SWITCH_PULL NRF_GPIO_PIN_PULLUP + +#define SWITCHES_NUMBER 5 + +#define BSP_SWITCH_0 SWITCH_1 +#define BSP_SWITCH_1 SWITCH_2 +#define BSP_SWITCH_2 SWITCH_3 +#define BSP_SWITCH_3 SWITCH_4 +#define BSP_SWITCH_4 SWITCH_5 + +#define BSP_SWITCH_0_MASK (1<NFC Forum, NFC Digital Protocol Technical Specification */ +#define NFCT_SENSRES_BITFRAMESDD_Pos (0UL) /*!< Position of BITFRAMESDD field. */ +#define NFCT_SENSRES_BITFRAMESDD_Msk (0x1FUL << NFCT_SENSRES_BITFRAMESDD_Pos) /*!< Bit mask of BITFRAMESDD field. */ +#define NFCT_SENSRES_BITFRAMESDD_SDD00000 (0UL) /*!< SDD pattern 00000 */ +#define NFCT_SENSRES_BITFRAMESDD_SDD00001 (1UL) /*!< SDD pattern 00001 */ +#define NFCT_SENSRES_BITFRAMESDD_SDD00010 (2UL) /*!< SDD pattern 00010 */ +#define NFCT_SENSRES_BITFRAMESDD_SDD00100 (4UL) /*!< SDD pattern 00100 */ +#define NFCT_SENSRES_BITFRAMESDD_SDD01000 (8UL) /*!< SDD pattern 01000 */ +#define NFCT_SENSRES_BITFRAMESDD_SDD10000 (16UL) /*!< SDD pattern 10000 */ + +/* Register: NFCT_SELRES */ +/* Description: NFC-A SEL_RES auto-response settings */ + +/* Bit 7 : Reserved for future use. Shall be 0. */ +#define NFCT_SELRES_RFU7_Pos (7UL) /*!< Position of RFU7 field. */ +#define NFCT_SELRES_RFU7_Msk (0x1UL << NFCT_SELRES_RFU7_Pos) /*!< Bit mask of RFU7 field. */ + +/* Bits 6..5 : Protocol as defined by the b7:b6 of SEL_RES response in the NFC Forum, NFC Digital Protocol Technical Specification */ +#define NFCT_SELRES_PROTOCOL_Pos (5UL) /*!< Position of PROTOCOL field. */ +#define NFCT_SELRES_PROTOCOL_Msk (0x3UL << NFCT_SELRES_PROTOCOL_Pos) /*!< Bit mask of PROTOCOL field. */ + +/* Bits 4..3 : Reserved for future use. Shall be 0. */ +#define NFCT_SELRES_RFU43_Pos (3UL) /*!< Position of RFU43 field. */ +#define NFCT_SELRES_RFU43_Msk (0x3UL << NFCT_SELRES_RFU43_Pos) /*!< Bit mask of RFU43 field. */ + +/* Bit 2 : Cascade as defined by the b3 of SEL_RES response in the NFC Forum, NFC Digital Protocol Technical Specification (controlled by hardware, shall be 0) */ +#define NFCT_SELRES_CASCADE_Pos (2UL) /*!< Position of CASCADE field. */ +#define NFCT_SELRES_CASCADE_Msk (0x1UL << NFCT_SELRES_CASCADE_Pos) /*!< Bit mask of CASCADE field. */ + +/* Bits 1..0 : Reserved for future use. Shall be 0. */ +#define NFCT_SELRES_RFU10_Pos (0UL) /*!< Position of RFU10 field. */ +#define NFCT_SELRES_RFU10_Msk (0x3UL << NFCT_SELRES_RFU10_Pos) /*!< Bit mask of RFU10 field. */ + + +/* Peripheral: NVMC */ +/* Description: Non Volatile Memory Controller */ + +/* Register: NVMC_READY */ +/* Description: Ready flag */ + +/* Bit 0 : NVMC is ready or busy */ +#define NVMC_READY_READY_Pos (0UL) /*!< Position of READY field. */ +#define NVMC_READY_READY_Msk (0x1UL << NVMC_READY_READY_Pos) /*!< Bit mask of READY field. */ +#define NVMC_READY_READY_Busy (0UL) /*!< NVMC is busy (on-going write or erase operation) */ +#define NVMC_READY_READY_Ready (1UL) /*!< NVMC is ready */ + +/* Register: NVMC_CONFIG */ +/* Description: Configuration register */ + +/* Bits 1..0 : Program memory access mode. It is strongly recommended to only activate erase and write modes when they are actively used. Enabling write or erase will invalidate the cache and keep it invalidated. */ +#define NVMC_CONFIG_WEN_Pos (0UL) /*!< Position of WEN field. */ +#define NVMC_CONFIG_WEN_Msk (0x3UL << NVMC_CONFIG_WEN_Pos) /*!< Bit mask of WEN field. */ +#define NVMC_CONFIG_WEN_Ren (0UL) /*!< Read only access */ +#define NVMC_CONFIG_WEN_Wen (1UL) /*!< Write Enabled */ +#define NVMC_CONFIG_WEN_Een (2UL) /*!< Erase enabled */ + +/* Register: NVMC_ERASEPAGE */ +/* Description: Register for erasing a page in Code area */ + +/* Bits 31..0 : Register for starting erase of a page in Code area */ +#define NVMC_ERASEPAGE_ERASEPAGE_Pos (0UL) /*!< Position of ERASEPAGE field. */ +#define NVMC_ERASEPAGE_ERASEPAGE_Msk (0xFFFFFFFFUL << NVMC_ERASEPAGE_ERASEPAGE_Pos) /*!< Bit mask of ERASEPAGE field. */ + +/* Register: NVMC_ERASEPCR1 */ +/* Description: Deprecated register - Register for erasing a page in Code area. Equivalent to ERASEPAGE. */ + +/* Bits 31..0 : Register for erasing a page in Code area. Equivalent to ERASEPAGE. */ +#define NVMC_ERASEPCR1_ERASEPCR1_Pos (0UL) /*!< Position of ERASEPCR1 field. */ +#define NVMC_ERASEPCR1_ERASEPCR1_Msk (0xFFFFFFFFUL << NVMC_ERASEPCR1_ERASEPCR1_Pos) /*!< Bit mask of ERASEPCR1 field. */ + +/* Register: NVMC_ERASEALL */ +/* Description: Register for erasing all non-volatile user memory */ + +/* Bit 0 : Erase all non-volatile memory including UICR registers. Note that the erase must be enabled using CONFIG.WEN before the non-volatile memory can be erased. */ +#define NVMC_ERASEALL_ERASEALL_Pos (0UL) /*!< Position of ERASEALL field. */ +#define NVMC_ERASEALL_ERASEALL_Msk (0x1UL << NVMC_ERASEALL_ERASEALL_Pos) /*!< Bit mask of ERASEALL field. */ +#define NVMC_ERASEALL_ERASEALL_NoOperation (0UL) /*!< No operation */ +#define NVMC_ERASEALL_ERASEALL_Erase (1UL) /*!< Start chip erase */ + +/* Register: NVMC_ERASEPCR0 */ +/* Description: Deprecated register - Register for erasing a page in Code area. Equivalent to ERASEPAGE. */ + +/* Bits 31..0 : Register for starting erase of a page in Code area. Equivalent to ERASEPAGE. */ +#define NVMC_ERASEPCR0_ERASEPCR0_Pos (0UL) /*!< Position of ERASEPCR0 field. */ +#define NVMC_ERASEPCR0_ERASEPCR0_Msk (0xFFFFFFFFUL << NVMC_ERASEPCR0_ERASEPCR0_Pos) /*!< Bit mask of ERASEPCR0 field. */ + +/* Register: NVMC_ERASEUICR */ +/* Description: Register for erasing User Information Configuration Registers */ + +/* Bit 0 : Register starting erase of all User Information Configuration Registers. Note that the erase must be enabled using CONFIG.WEN before the UICR can be erased. */ +#define NVMC_ERASEUICR_ERASEUICR_Pos (0UL) /*!< Position of ERASEUICR field. */ +#define NVMC_ERASEUICR_ERASEUICR_Msk (0x1UL << NVMC_ERASEUICR_ERASEUICR_Pos) /*!< Bit mask of ERASEUICR field. */ +#define NVMC_ERASEUICR_ERASEUICR_NoOperation (0UL) /*!< No operation */ +#define NVMC_ERASEUICR_ERASEUICR_Erase (1UL) /*!< Start erase of UICR */ + +/* Register: NVMC_ICACHECNF */ +/* Description: I-Code cache configuration register. */ + +/* Bit 8 : Cache profiling enable */ +#define NVMC_ICACHECNF_CACHEPROFEN_Pos (8UL) /*!< Position of CACHEPROFEN field. */ +#define NVMC_ICACHECNF_CACHEPROFEN_Msk (0x1UL << NVMC_ICACHECNF_CACHEPROFEN_Pos) /*!< Bit mask of CACHEPROFEN field. */ +#define NVMC_ICACHECNF_CACHEPROFEN_Disabled (0UL) /*!< Disable cache profiling */ +#define NVMC_ICACHECNF_CACHEPROFEN_Enabled (1UL) /*!< Enable cache profiling */ + +/* Bit 0 : Cache enable */ +#define NVMC_ICACHECNF_CACHEEN_Pos (0UL) /*!< Position of CACHEEN field. */ +#define NVMC_ICACHECNF_CACHEEN_Msk (0x1UL << NVMC_ICACHECNF_CACHEEN_Pos) /*!< Bit mask of CACHEEN field. */ +#define NVMC_ICACHECNF_CACHEEN_Disabled (0UL) /*!< Disable cache. Invalidates all cache entries. */ +#define NVMC_ICACHECNF_CACHEEN_Enabled (1UL) /*!< Enable cache */ + +/* Register: NVMC_IHIT */ +/* Description: I-Code cache hit counter. */ + +/* Bits 31..0 : Number of cache hits */ +#define NVMC_IHIT_HITS_Pos (0UL) /*!< Position of HITS field. */ +#define NVMC_IHIT_HITS_Msk (0xFFFFFFFFUL << NVMC_IHIT_HITS_Pos) /*!< Bit mask of HITS field. */ + +/* Register: NVMC_IMISS */ +/* Description: I-Code cache miss counter. */ + +/* Bits 31..0 : Number of cache misses */ +#define NVMC_IMISS_MISSES_Pos (0UL) /*!< Position of MISSES field. */ +#define NVMC_IMISS_MISSES_Msk (0xFFFFFFFFUL << NVMC_IMISS_MISSES_Pos) /*!< Bit mask of MISSES field. */ + + +/* Peripheral: GPIO */ +/* Description: GPIO Port 1 */ + +/* Register: GPIO_OUT */ +/* Description: Write GPIO port */ + +/* Bit 31 : Pin 31 */ +#define GPIO_OUT_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_OUT_PIN31_Msk (0x1UL << GPIO_OUT_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_OUT_PIN31_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN31_High (1UL) /*!< Pin driver is high */ + +/* Bit 30 : Pin 30 */ +#define GPIO_OUT_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_OUT_PIN30_Msk (0x1UL << GPIO_OUT_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_OUT_PIN30_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN30_High (1UL) /*!< Pin driver is high */ + +/* Bit 29 : Pin 29 */ +#define GPIO_OUT_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_OUT_PIN29_Msk (0x1UL << GPIO_OUT_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_OUT_PIN29_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN29_High (1UL) /*!< Pin driver is high */ + +/* Bit 28 : Pin 28 */ +#define GPIO_OUT_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_OUT_PIN28_Msk (0x1UL << GPIO_OUT_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_OUT_PIN28_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN28_High (1UL) /*!< Pin driver is high */ + +/* Bit 27 : Pin 27 */ +#define GPIO_OUT_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_OUT_PIN27_Msk (0x1UL << GPIO_OUT_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_OUT_PIN27_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN27_High (1UL) /*!< Pin driver is high */ + +/* Bit 26 : Pin 26 */ +#define GPIO_OUT_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_OUT_PIN26_Msk (0x1UL << GPIO_OUT_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_OUT_PIN26_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN26_High (1UL) /*!< Pin driver is high */ + +/* Bit 25 : Pin 25 */ +#define GPIO_OUT_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_OUT_PIN25_Msk (0x1UL << GPIO_OUT_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_OUT_PIN25_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN25_High (1UL) /*!< Pin driver is high */ + +/* Bit 24 : Pin 24 */ +#define GPIO_OUT_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_OUT_PIN24_Msk (0x1UL << GPIO_OUT_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_OUT_PIN24_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN24_High (1UL) /*!< Pin driver is high */ + +/* Bit 23 : Pin 23 */ +#define GPIO_OUT_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_OUT_PIN23_Msk (0x1UL << GPIO_OUT_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_OUT_PIN23_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN23_High (1UL) /*!< Pin driver is high */ + +/* Bit 22 : Pin 22 */ +#define GPIO_OUT_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_OUT_PIN22_Msk (0x1UL << GPIO_OUT_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_OUT_PIN22_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN22_High (1UL) /*!< Pin driver is high */ + +/* Bit 21 : Pin 21 */ +#define GPIO_OUT_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_OUT_PIN21_Msk (0x1UL << GPIO_OUT_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_OUT_PIN21_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN21_High (1UL) /*!< Pin driver is high */ + +/* Bit 20 : Pin 20 */ +#define GPIO_OUT_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_OUT_PIN20_Msk (0x1UL << GPIO_OUT_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_OUT_PIN20_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN20_High (1UL) /*!< Pin driver is high */ + +/* Bit 19 : Pin 19 */ +#define GPIO_OUT_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_OUT_PIN19_Msk (0x1UL << GPIO_OUT_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_OUT_PIN19_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN19_High (1UL) /*!< Pin driver is high */ + +/* Bit 18 : Pin 18 */ +#define GPIO_OUT_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_OUT_PIN18_Msk (0x1UL << GPIO_OUT_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_OUT_PIN18_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN18_High (1UL) /*!< Pin driver is high */ + +/* Bit 17 : Pin 17 */ +#define GPIO_OUT_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_OUT_PIN17_Msk (0x1UL << GPIO_OUT_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_OUT_PIN17_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN17_High (1UL) /*!< Pin driver is high */ + +/* Bit 16 : Pin 16 */ +#define GPIO_OUT_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_OUT_PIN16_Msk (0x1UL << GPIO_OUT_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_OUT_PIN16_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN16_High (1UL) /*!< Pin driver is high */ + +/* Bit 15 : Pin 15 */ +#define GPIO_OUT_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_OUT_PIN15_Msk (0x1UL << GPIO_OUT_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_OUT_PIN15_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN15_High (1UL) /*!< Pin driver is high */ + +/* Bit 14 : Pin 14 */ +#define GPIO_OUT_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_OUT_PIN14_Msk (0x1UL << GPIO_OUT_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_OUT_PIN14_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN14_High (1UL) /*!< Pin driver is high */ + +/* Bit 13 : Pin 13 */ +#define GPIO_OUT_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_OUT_PIN13_Msk (0x1UL << GPIO_OUT_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_OUT_PIN13_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN13_High (1UL) /*!< Pin driver is high */ + +/* Bit 12 : Pin 12 */ +#define GPIO_OUT_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_OUT_PIN12_Msk (0x1UL << GPIO_OUT_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_OUT_PIN12_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN12_High (1UL) /*!< Pin driver is high */ + +/* Bit 11 : Pin 11 */ +#define GPIO_OUT_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_OUT_PIN11_Msk (0x1UL << GPIO_OUT_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_OUT_PIN11_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN11_High (1UL) /*!< Pin driver is high */ + +/* Bit 10 : Pin 10 */ +#define GPIO_OUT_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_OUT_PIN10_Msk (0x1UL << GPIO_OUT_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_OUT_PIN10_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN10_High (1UL) /*!< Pin driver is high */ + +/* Bit 9 : Pin 9 */ +#define GPIO_OUT_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_OUT_PIN9_Msk (0x1UL << GPIO_OUT_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_OUT_PIN9_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN9_High (1UL) /*!< Pin driver is high */ + +/* Bit 8 : Pin 8 */ +#define GPIO_OUT_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_OUT_PIN8_Msk (0x1UL << GPIO_OUT_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_OUT_PIN8_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN8_High (1UL) /*!< Pin driver is high */ + +/* Bit 7 : Pin 7 */ +#define GPIO_OUT_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_OUT_PIN7_Msk (0x1UL << GPIO_OUT_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_OUT_PIN7_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN7_High (1UL) /*!< Pin driver is high */ + +/* Bit 6 : Pin 6 */ +#define GPIO_OUT_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_OUT_PIN6_Msk (0x1UL << GPIO_OUT_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_OUT_PIN6_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN6_High (1UL) /*!< Pin driver is high */ + +/* Bit 5 : Pin 5 */ +#define GPIO_OUT_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_OUT_PIN5_Msk (0x1UL << GPIO_OUT_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_OUT_PIN5_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN5_High (1UL) /*!< Pin driver is high */ + +/* Bit 4 : Pin 4 */ +#define GPIO_OUT_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_OUT_PIN4_Msk (0x1UL << GPIO_OUT_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_OUT_PIN4_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN4_High (1UL) /*!< Pin driver is high */ + +/* Bit 3 : Pin 3 */ +#define GPIO_OUT_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_OUT_PIN3_Msk (0x1UL << GPIO_OUT_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_OUT_PIN3_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN3_High (1UL) /*!< Pin driver is high */ + +/* Bit 2 : Pin 2 */ +#define GPIO_OUT_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_OUT_PIN2_Msk (0x1UL << GPIO_OUT_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_OUT_PIN2_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN2_High (1UL) /*!< Pin driver is high */ + +/* Bit 1 : Pin 1 */ +#define GPIO_OUT_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_OUT_PIN1_Msk (0x1UL << GPIO_OUT_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_OUT_PIN1_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN1_High (1UL) /*!< Pin driver is high */ + +/* Bit 0 : Pin 0 */ +#define GPIO_OUT_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_OUT_PIN0_Msk (0x1UL << GPIO_OUT_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_OUT_PIN0_Low (0UL) /*!< Pin driver is low */ +#define GPIO_OUT_PIN0_High (1UL) /*!< Pin driver is high */ + +/* Register: GPIO_OUTSET */ +/* Description: Set individual bits in GPIO port */ + +/* Bit 31 : Pin 31 */ +#define GPIO_OUTSET_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_OUTSET_PIN31_Msk (0x1UL << GPIO_OUTSET_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_OUTSET_PIN31_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN31_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN31_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 30 : Pin 30 */ +#define GPIO_OUTSET_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_OUTSET_PIN30_Msk (0x1UL << GPIO_OUTSET_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_OUTSET_PIN30_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN30_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN30_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 29 : Pin 29 */ +#define GPIO_OUTSET_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_OUTSET_PIN29_Msk (0x1UL << GPIO_OUTSET_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_OUTSET_PIN29_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN29_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN29_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 28 : Pin 28 */ +#define GPIO_OUTSET_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_OUTSET_PIN28_Msk (0x1UL << GPIO_OUTSET_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_OUTSET_PIN28_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN28_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN28_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 27 : Pin 27 */ +#define GPIO_OUTSET_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_OUTSET_PIN27_Msk (0x1UL << GPIO_OUTSET_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_OUTSET_PIN27_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN27_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN27_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 26 : Pin 26 */ +#define GPIO_OUTSET_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_OUTSET_PIN26_Msk (0x1UL << GPIO_OUTSET_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_OUTSET_PIN26_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN26_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN26_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 25 : Pin 25 */ +#define GPIO_OUTSET_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_OUTSET_PIN25_Msk (0x1UL << GPIO_OUTSET_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_OUTSET_PIN25_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN25_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN25_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 24 : Pin 24 */ +#define GPIO_OUTSET_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_OUTSET_PIN24_Msk (0x1UL << GPIO_OUTSET_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_OUTSET_PIN24_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN24_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN24_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 23 : Pin 23 */ +#define GPIO_OUTSET_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_OUTSET_PIN23_Msk (0x1UL << GPIO_OUTSET_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_OUTSET_PIN23_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN23_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN23_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 22 : Pin 22 */ +#define GPIO_OUTSET_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_OUTSET_PIN22_Msk (0x1UL << GPIO_OUTSET_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_OUTSET_PIN22_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN22_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN22_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 21 : Pin 21 */ +#define GPIO_OUTSET_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_OUTSET_PIN21_Msk (0x1UL << GPIO_OUTSET_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_OUTSET_PIN21_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN21_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN21_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 20 : Pin 20 */ +#define GPIO_OUTSET_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_OUTSET_PIN20_Msk (0x1UL << GPIO_OUTSET_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_OUTSET_PIN20_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN20_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN20_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 19 : Pin 19 */ +#define GPIO_OUTSET_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_OUTSET_PIN19_Msk (0x1UL << GPIO_OUTSET_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_OUTSET_PIN19_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN19_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN19_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 18 : Pin 18 */ +#define GPIO_OUTSET_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_OUTSET_PIN18_Msk (0x1UL << GPIO_OUTSET_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_OUTSET_PIN18_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN18_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN18_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 17 : Pin 17 */ +#define GPIO_OUTSET_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_OUTSET_PIN17_Msk (0x1UL << GPIO_OUTSET_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_OUTSET_PIN17_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN17_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN17_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 16 : Pin 16 */ +#define GPIO_OUTSET_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_OUTSET_PIN16_Msk (0x1UL << GPIO_OUTSET_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_OUTSET_PIN16_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN16_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN16_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 15 : Pin 15 */ +#define GPIO_OUTSET_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_OUTSET_PIN15_Msk (0x1UL << GPIO_OUTSET_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_OUTSET_PIN15_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN15_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN15_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 14 : Pin 14 */ +#define GPIO_OUTSET_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_OUTSET_PIN14_Msk (0x1UL << GPIO_OUTSET_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_OUTSET_PIN14_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN14_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN14_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 13 : Pin 13 */ +#define GPIO_OUTSET_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_OUTSET_PIN13_Msk (0x1UL << GPIO_OUTSET_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_OUTSET_PIN13_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN13_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN13_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 12 : Pin 12 */ +#define GPIO_OUTSET_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_OUTSET_PIN12_Msk (0x1UL << GPIO_OUTSET_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_OUTSET_PIN12_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN12_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN12_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 11 : Pin 11 */ +#define GPIO_OUTSET_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_OUTSET_PIN11_Msk (0x1UL << GPIO_OUTSET_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_OUTSET_PIN11_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN11_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN11_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 10 : Pin 10 */ +#define GPIO_OUTSET_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_OUTSET_PIN10_Msk (0x1UL << GPIO_OUTSET_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_OUTSET_PIN10_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN10_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN10_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 9 : Pin 9 */ +#define GPIO_OUTSET_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_OUTSET_PIN9_Msk (0x1UL << GPIO_OUTSET_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_OUTSET_PIN9_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN9_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN9_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 8 : Pin 8 */ +#define GPIO_OUTSET_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_OUTSET_PIN8_Msk (0x1UL << GPIO_OUTSET_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_OUTSET_PIN8_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN8_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN8_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 7 : Pin 7 */ +#define GPIO_OUTSET_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_OUTSET_PIN7_Msk (0x1UL << GPIO_OUTSET_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_OUTSET_PIN7_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN7_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN7_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 6 : Pin 6 */ +#define GPIO_OUTSET_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_OUTSET_PIN6_Msk (0x1UL << GPIO_OUTSET_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_OUTSET_PIN6_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN6_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN6_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 5 : Pin 5 */ +#define GPIO_OUTSET_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_OUTSET_PIN5_Msk (0x1UL << GPIO_OUTSET_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_OUTSET_PIN5_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN5_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN5_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 4 : Pin 4 */ +#define GPIO_OUTSET_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_OUTSET_PIN4_Msk (0x1UL << GPIO_OUTSET_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_OUTSET_PIN4_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN4_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN4_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 3 : Pin 3 */ +#define GPIO_OUTSET_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_OUTSET_PIN3_Msk (0x1UL << GPIO_OUTSET_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_OUTSET_PIN3_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN3_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN3_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 2 : Pin 2 */ +#define GPIO_OUTSET_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_OUTSET_PIN2_Msk (0x1UL << GPIO_OUTSET_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_OUTSET_PIN2_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN2_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN2_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 1 : Pin 1 */ +#define GPIO_OUTSET_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_OUTSET_PIN1_Msk (0x1UL << GPIO_OUTSET_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_OUTSET_PIN1_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN1_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN1_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Bit 0 : Pin 0 */ +#define GPIO_OUTSET_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_OUTSET_PIN0_Msk (0x1UL << GPIO_OUTSET_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_OUTSET_PIN0_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTSET_PIN0_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTSET_PIN0_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ + +/* Register: GPIO_OUTCLR */ +/* Description: Clear individual bits in GPIO port */ + +/* Bit 31 : Pin 31 */ +#define GPIO_OUTCLR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_OUTCLR_PIN31_Msk (0x1UL << GPIO_OUTCLR_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_OUTCLR_PIN31_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN31_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN31_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 30 : Pin 30 */ +#define GPIO_OUTCLR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_OUTCLR_PIN30_Msk (0x1UL << GPIO_OUTCLR_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_OUTCLR_PIN30_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN30_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN30_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 29 : Pin 29 */ +#define GPIO_OUTCLR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_OUTCLR_PIN29_Msk (0x1UL << GPIO_OUTCLR_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_OUTCLR_PIN29_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN29_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN29_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 28 : Pin 28 */ +#define GPIO_OUTCLR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_OUTCLR_PIN28_Msk (0x1UL << GPIO_OUTCLR_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_OUTCLR_PIN28_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN28_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN28_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 27 : Pin 27 */ +#define GPIO_OUTCLR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_OUTCLR_PIN27_Msk (0x1UL << GPIO_OUTCLR_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_OUTCLR_PIN27_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN27_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN27_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 26 : Pin 26 */ +#define GPIO_OUTCLR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_OUTCLR_PIN26_Msk (0x1UL << GPIO_OUTCLR_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_OUTCLR_PIN26_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN26_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN26_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 25 : Pin 25 */ +#define GPIO_OUTCLR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_OUTCLR_PIN25_Msk (0x1UL << GPIO_OUTCLR_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_OUTCLR_PIN25_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN25_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN25_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 24 : Pin 24 */ +#define GPIO_OUTCLR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_OUTCLR_PIN24_Msk (0x1UL << GPIO_OUTCLR_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_OUTCLR_PIN24_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN24_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN24_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 23 : Pin 23 */ +#define GPIO_OUTCLR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_OUTCLR_PIN23_Msk (0x1UL << GPIO_OUTCLR_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_OUTCLR_PIN23_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN23_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN23_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 22 : Pin 22 */ +#define GPIO_OUTCLR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_OUTCLR_PIN22_Msk (0x1UL << GPIO_OUTCLR_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_OUTCLR_PIN22_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN22_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN22_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 21 : Pin 21 */ +#define GPIO_OUTCLR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_OUTCLR_PIN21_Msk (0x1UL << GPIO_OUTCLR_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_OUTCLR_PIN21_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN21_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN21_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 20 : Pin 20 */ +#define GPIO_OUTCLR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_OUTCLR_PIN20_Msk (0x1UL << GPIO_OUTCLR_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_OUTCLR_PIN20_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN20_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN20_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 19 : Pin 19 */ +#define GPIO_OUTCLR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_OUTCLR_PIN19_Msk (0x1UL << GPIO_OUTCLR_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_OUTCLR_PIN19_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN19_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN19_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 18 : Pin 18 */ +#define GPIO_OUTCLR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_OUTCLR_PIN18_Msk (0x1UL << GPIO_OUTCLR_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_OUTCLR_PIN18_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN18_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN18_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 17 : Pin 17 */ +#define GPIO_OUTCLR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_OUTCLR_PIN17_Msk (0x1UL << GPIO_OUTCLR_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_OUTCLR_PIN17_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN17_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN17_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 16 : Pin 16 */ +#define GPIO_OUTCLR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_OUTCLR_PIN16_Msk (0x1UL << GPIO_OUTCLR_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_OUTCLR_PIN16_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN16_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN16_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 15 : Pin 15 */ +#define GPIO_OUTCLR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_OUTCLR_PIN15_Msk (0x1UL << GPIO_OUTCLR_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_OUTCLR_PIN15_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN15_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN15_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 14 : Pin 14 */ +#define GPIO_OUTCLR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_OUTCLR_PIN14_Msk (0x1UL << GPIO_OUTCLR_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_OUTCLR_PIN14_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN14_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN14_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 13 : Pin 13 */ +#define GPIO_OUTCLR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_OUTCLR_PIN13_Msk (0x1UL << GPIO_OUTCLR_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_OUTCLR_PIN13_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN13_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN13_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 12 : Pin 12 */ +#define GPIO_OUTCLR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_OUTCLR_PIN12_Msk (0x1UL << GPIO_OUTCLR_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_OUTCLR_PIN12_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN12_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN12_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 11 : Pin 11 */ +#define GPIO_OUTCLR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_OUTCLR_PIN11_Msk (0x1UL << GPIO_OUTCLR_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_OUTCLR_PIN11_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN11_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN11_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 10 : Pin 10 */ +#define GPIO_OUTCLR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_OUTCLR_PIN10_Msk (0x1UL << GPIO_OUTCLR_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_OUTCLR_PIN10_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN10_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN10_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 9 : Pin 9 */ +#define GPIO_OUTCLR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_OUTCLR_PIN9_Msk (0x1UL << GPIO_OUTCLR_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_OUTCLR_PIN9_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN9_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN9_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 8 : Pin 8 */ +#define GPIO_OUTCLR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_OUTCLR_PIN8_Msk (0x1UL << GPIO_OUTCLR_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_OUTCLR_PIN8_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN8_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN8_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 7 : Pin 7 */ +#define GPIO_OUTCLR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_OUTCLR_PIN7_Msk (0x1UL << GPIO_OUTCLR_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_OUTCLR_PIN7_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN7_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN7_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 6 : Pin 6 */ +#define GPIO_OUTCLR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_OUTCLR_PIN6_Msk (0x1UL << GPIO_OUTCLR_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_OUTCLR_PIN6_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN6_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN6_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 5 : Pin 5 */ +#define GPIO_OUTCLR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_OUTCLR_PIN5_Msk (0x1UL << GPIO_OUTCLR_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_OUTCLR_PIN5_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN5_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN5_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 4 : Pin 4 */ +#define GPIO_OUTCLR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_OUTCLR_PIN4_Msk (0x1UL << GPIO_OUTCLR_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_OUTCLR_PIN4_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN4_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN4_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 3 : Pin 3 */ +#define GPIO_OUTCLR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_OUTCLR_PIN3_Msk (0x1UL << GPIO_OUTCLR_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_OUTCLR_PIN3_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN3_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN3_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 2 : Pin 2 */ +#define GPIO_OUTCLR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_OUTCLR_PIN2_Msk (0x1UL << GPIO_OUTCLR_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_OUTCLR_PIN2_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN2_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN2_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 1 : Pin 1 */ +#define GPIO_OUTCLR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_OUTCLR_PIN1_Msk (0x1UL << GPIO_OUTCLR_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_OUTCLR_PIN1_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN1_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN1_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Bit 0 : Pin 0 */ +#define GPIO_OUTCLR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_OUTCLR_PIN0_Msk (0x1UL << GPIO_OUTCLR_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_OUTCLR_PIN0_Low (0UL) /*!< Read: pin driver is low */ +#define GPIO_OUTCLR_PIN0_High (1UL) /*!< Read: pin driver is high */ +#define GPIO_OUTCLR_PIN0_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ + +/* Register: GPIO_IN */ +/* Description: Read GPIO port */ + +/* Bit 31 : Pin 31 */ +#define GPIO_IN_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_IN_PIN31_Msk (0x1UL << GPIO_IN_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_IN_PIN31_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN31_High (1UL) /*!< Pin input is high */ + +/* Bit 30 : Pin 30 */ +#define GPIO_IN_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_IN_PIN30_Msk (0x1UL << GPIO_IN_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_IN_PIN30_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN30_High (1UL) /*!< Pin input is high */ + +/* Bit 29 : Pin 29 */ +#define GPIO_IN_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_IN_PIN29_Msk (0x1UL << GPIO_IN_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_IN_PIN29_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN29_High (1UL) /*!< Pin input is high */ + +/* Bit 28 : Pin 28 */ +#define GPIO_IN_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_IN_PIN28_Msk (0x1UL << GPIO_IN_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_IN_PIN28_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN28_High (1UL) /*!< Pin input is high */ + +/* Bit 27 : Pin 27 */ +#define GPIO_IN_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_IN_PIN27_Msk (0x1UL << GPIO_IN_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_IN_PIN27_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN27_High (1UL) /*!< Pin input is high */ + +/* Bit 26 : Pin 26 */ +#define GPIO_IN_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_IN_PIN26_Msk (0x1UL << GPIO_IN_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_IN_PIN26_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN26_High (1UL) /*!< Pin input is high */ + +/* Bit 25 : Pin 25 */ +#define GPIO_IN_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_IN_PIN25_Msk (0x1UL << GPIO_IN_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_IN_PIN25_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN25_High (1UL) /*!< Pin input is high */ + +/* Bit 24 : Pin 24 */ +#define GPIO_IN_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_IN_PIN24_Msk (0x1UL << GPIO_IN_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_IN_PIN24_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN24_High (1UL) /*!< Pin input is high */ + +/* Bit 23 : Pin 23 */ +#define GPIO_IN_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_IN_PIN23_Msk (0x1UL << GPIO_IN_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_IN_PIN23_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN23_High (1UL) /*!< Pin input is high */ + +/* Bit 22 : Pin 22 */ +#define GPIO_IN_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_IN_PIN22_Msk (0x1UL << GPIO_IN_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_IN_PIN22_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN22_High (1UL) /*!< Pin input is high */ + +/* Bit 21 : Pin 21 */ +#define GPIO_IN_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_IN_PIN21_Msk (0x1UL << GPIO_IN_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_IN_PIN21_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN21_High (1UL) /*!< Pin input is high */ + +/* Bit 20 : Pin 20 */ +#define GPIO_IN_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_IN_PIN20_Msk (0x1UL << GPIO_IN_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_IN_PIN20_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN20_High (1UL) /*!< Pin input is high */ + +/* Bit 19 : Pin 19 */ +#define GPIO_IN_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_IN_PIN19_Msk (0x1UL << GPIO_IN_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_IN_PIN19_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN19_High (1UL) /*!< Pin input is high */ + +/* Bit 18 : Pin 18 */ +#define GPIO_IN_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_IN_PIN18_Msk (0x1UL << GPIO_IN_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_IN_PIN18_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN18_High (1UL) /*!< Pin input is high */ + +/* Bit 17 : Pin 17 */ +#define GPIO_IN_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_IN_PIN17_Msk (0x1UL << GPIO_IN_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_IN_PIN17_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN17_High (1UL) /*!< Pin input is high */ + +/* Bit 16 : Pin 16 */ +#define GPIO_IN_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_IN_PIN16_Msk (0x1UL << GPIO_IN_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_IN_PIN16_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN16_High (1UL) /*!< Pin input is high */ + +/* Bit 15 : Pin 15 */ +#define GPIO_IN_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_IN_PIN15_Msk (0x1UL << GPIO_IN_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_IN_PIN15_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN15_High (1UL) /*!< Pin input is high */ + +/* Bit 14 : Pin 14 */ +#define GPIO_IN_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_IN_PIN14_Msk (0x1UL << GPIO_IN_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_IN_PIN14_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN14_High (1UL) /*!< Pin input is high */ + +/* Bit 13 : Pin 13 */ +#define GPIO_IN_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_IN_PIN13_Msk (0x1UL << GPIO_IN_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_IN_PIN13_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN13_High (1UL) /*!< Pin input is high */ + +/* Bit 12 : Pin 12 */ +#define GPIO_IN_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_IN_PIN12_Msk (0x1UL << GPIO_IN_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_IN_PIN12_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN12_High (1UL) /*!< Pin input is high */ + +/* Bit 11 : Pin 11 */ +#define GPIO_IN_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_IN_PIN11_Msk (0x1UL << GPIO_IN_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_IN_PIN11_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN11_High (1UL) /*!< Pin input is high */ + +/* Bit 10 : Pin 10 */ +#define GPIO_IN_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_IN_PIN10_Msk (0x1UL << GPIO_IN_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_IN_PIN10_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN10_High (1UL) /*!< Pin input is high */ + +/* Bit 9 : Pin 9 */ +#define GPIO_IN_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_IN_PIN9_Msk (0x1UL << GPIO_IN_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_IN_PIN9_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN9_High (1UL) /*!< Pin input is high */ + +/* Bit 8 : Pin 8 */ +#define GPIO_IN_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_IN_PIN8_Msk (0x1UL << GPIO_IN_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_IN_PIN8_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN8_High (1UL) /*!< Pin input is high */ + +/* Bit 7 : Pin 7 */ +#define GPIO_IN_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_IN_PIN7_Msk (0x1UL << GPIO_IN_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_IN_PIN7_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN7_High (1UL) /*!< Pin input is high */ + +/* Bit 6 : Pin 6 */ +#define GPIO_IN_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_IN_PIN6_Msk (0x1UL << GPIO_IN_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_IN_PIN6_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN6_High (1UL) /*!< Pin input is high */ + +/* Bit 5 : Pin 5 */ +#define GPIO_IN_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_IN_PIN5_Msk (0x1UL << GPIO_IN_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_IN_PIN5_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN5_High (1UL) /*!< Pin input is high */ + +/* Bit 4 : Pin 4 */ +#define GPIO_IN_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_IN_PIN4_Msk (0x1UL << GPIO_IN_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_IN_PIN4_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN4_High (1UL) /*!< Pin input is high */ + +/* Bit 3 : Pin 3 */ +#define GPIO_IN_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_IN_PIN3_Msk (0x1UL << GPIO_IN_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_IN_PIN3_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN3_High (1UL) /*!< Pin input is high */ + +/* Bit 2 : Pin 2 */ +#define GPIO_IN_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_IN_PIN2_Msk (0x1UL << GPIO_IN_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_IN_PIN2_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN2_High (1UL) /*!< Pin input is high */ + +/* Bit 1 : Pin 1 */ +#define GPIO_IN_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_IN_PIN1_Msk (0x1UL << GPIO_IN_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_IN_PIN1_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN1_High (1UL) /*!< Pin input is high */ + +/* Bit 0 : Pin 0 */ +#define GPIO_IN_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_IN_PIN0_Msk (0x1UL << GPIO_IN_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_IN_PIN0_Low (0UL) /*!< Pin input is low */ +#define GPIO_IN_PIN0_High (1UL) /*!< Pin input is high */ + +/* Register: GPIO_DIR */ +/* Description: Direction of GPIO pins */ + +/* Bit 31 : Pin 31 */ +#define GPIO_DIR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_DIR_PIN31_Msk (0x1UL << GPIO_DIR_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_DIR_PIN31_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN31_Output (1UL) /*!< Pin set as output */ + +/* Bit 30 : Pin 30 */ +#define GPIO_DIR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_DIR_PIN30_Msk (0x1UL << GPIO_DIR_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_DIR_PIN30_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN30_Output (1UL) /*!< Pin set as output */ + +/* Bit 29 : Pin 29 */ +#define GPIO_DIR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_DIR_PIN29_Msk (0x1UL << GPIO_DIR_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_DIR_PIN29_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN29_Output (1UL) /*!< Pin set as output */ + +/* Bit 28 : Pin 28 */ +#define GPIO_DIR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_DIR_PIN28_Msk (0x1UL << GPIO_DIR_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_DIR_PIN28_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN28_Output (1UL) /*!< Pin set as output */ + +/* Bit 27 : Pin 27 */ +#define GPIO_DIR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_DIR_PIN27_Msk (0x1UL << GPIO_DIR_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_DIR_PIN27_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN27_Output (1UL) /*!< Pin set as output */ + +/* Bit 26 : Pin 26 */ +#define GPIO_DIR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_DIR_PIN26_Msk (0x1UL << GPIO_DIR_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_DIR_PIN26_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN26_Output (1UL) /*!< Pin set as output */ + +/* Bit 25 : Pin 25 */ +#define GPIO_DIR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_DIR_PIN25_Msk (0x1UL << GPIO_DIR_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_DIR_PIN25_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN25_Output (1UL) /*!< Pin set as output */ + +/* Bit 24 : Pin 24 */ +#define GPIO_DIR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_DIR_PIN24_Msk (0x1UL << GPIO_DIR_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_DIR_PIN24_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN24_Output (1UL) /*!< Pin set as output */ + +/* Bit 23 : Pin 23 */ +#define GPIO_DIR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_DIR_PIN23_Msk (0x1UL << GPIO_DIR_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_DIR_PIN23_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN23_Output (1UL) /*!< Pin set as output */ + +/* Bit 22 : Pin 22 */ +#define GPIO_DIR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_DIR_PIN22_Msk (0x1UL << GPIO_DIR_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_DIR_PIN22_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN22_Output (1UL) /*!< Pin set as output */ + +/* Bit 21 : Pin 21 */ +#define GPIO_DIR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_DIR_PIN21_Msk (0x1UL << GPIO_DIR_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_DIR_PIN21_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN21_Output (1UL) /*!< Pin set as output */ + +/* Bit 20 : Pin 20 */ +#define GPIO_DIR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_DIR_PIN20_Msk (0x1UL << GPIO_DIR_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_DIR_PIN20_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN20_Output (1UL) /*!< Pin set as output */ + +/* Bit 19 : Pin 19 */ +#define GPIO_DIR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_DIR_PIN19_Msk (0x1UL << GPIO_DIR_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_DIR_PIN19_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN19_Output (1UL) /*!< Pin set as output */ + +/* Bit 18 : Pin 18 */ +#define GPIO_DIR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_DIR_PIN18_Msk (0x1UL << GPIO_DIR_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_DIR_PIN18_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN18_Output (1UL) /*!< Pin set as output */ + +/* Bit 17 : Pin 17 */ +#define GPIO_DIR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_DIR_PIN17_Msk (0x1UL << GPIO_DIR_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_DIR_PIN17_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN17_Output (1UL) /*!< Pin set as output */ + +/* Bit 16 : Pin 16 */ +#define GPIO_DIR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_DIR_PIN16_Msk (0x1UL << GPIO_DIR_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_DIR_PIN16_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN16_Output (1UL) /*!< Pin set as output */ + +/* Bit 15 : Pin 15 */ +#define GPIO_DIR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_DIR_PIN15_Msk (0x1UL << GPIO_DIR_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_DIR_PIN15_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN15_Output (1UL) /*!< Pin set as output */ + +/* Bit 14 : Pin 14 */ +#define GPIO_DIR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_DIR_PIN14_Msk (0x1UL << GPIO_DIR_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_DIR_PIN14_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN14_Output (1UL) /*!< Pin set as output */ + +/* Bit 13 : Pin 13 */ +#define GPIO_DIR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_DIR_PIN13_Msk (0x1UL << GPIO_DIR_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_DIR_PIN13_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN13_Output (1UL) /*!< Pin set as output */ + +/* Bit 12 : Pin 12 */ +#define GPIO_DIR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_DIR_PIN12_Msk (0x1UL << GPIO_DIR_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_DIR_PIN12_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN12_Output (1UL) /*!< Pin set as output */ + +/* Bit 11 : Pin 11 */ +#define GPIO_DIR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_DIR_PIN11_Msk (0x1UL << GPIO_DIR_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_DIR_PIN11_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN11_Output (1UL) /*!< Pin set as output */ + +/* Bit 10 : Pin 10 */ +#define GPIO_DIR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_DIR_PIN10_Msk (0x1UL << GPIO_DIR_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_DIR_PIN10_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN10_Output (1UL) /*!< Pin set as output */ + +/* Bit 9 : Pin 9 */ +#define GPIO_DIR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_DIR_PIN9_Msk (0x1UL << GPIO_DIR_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_DIR_PIN9_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN9_Output (1UL) /*!< Pin set as output */ + +/* Bit 8 : Pin 8 */ +#define GPIO_DIR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_DIR_PIN8_Msk (0x1UL << GPIO_DIR_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_DIR_PIN8_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN8_Output (1UL) /*!< Pin set as output */ + +/* Bit 7 : Pin 7 */ +#define GPIO_DIR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_DIR_PIN7_Msk (0x1UL << GPIO_DIR_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_DIR_PIN7_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN7_Output (1UL) /*!< Pin set as output */ + +/* Bit 6 : Pin 6 */ +#define GPIO_DIR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_DIR_PIN6_Msk (0x1UL << GPIO_DIR_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_DIR_PIN6_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN6_Output (1UL) /*!< Pin set as output */ + +/* Bit 5 : Pin 5 */ +#define GPIO_DIR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_DIR_PIN5_Msk (0x1UL << GPIO_DIR_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_DIR_PIN5_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN5_Output (1UL) /*!< Pin set as output */ + +/* Bit 4 : Pin 4 */ +#define GPIO_DIR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_DIR_PIN4_Msk (0x1UL << GPIO_DIR_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_DIR_PIN4_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN4_Output (1UL) /*!< Pin set as output */ + +/* Bit 3 : Pin 3 */ +#define GPIO_DIR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_DIR_PIN3_Msk (0x1UL << GPIO_DIR_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_DIR_PIN3_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN3_Output (1UL) /*!< Pin set as output */ + +/* Bit 2 : Pin 2 */ +#define GPIO_DIR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_DIR_PIN2_Msk (0x1UL << GPIO_DIR_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_DIR_PIN2_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN2_Output (1UL) /*!< Pin set as output */ + +/* Bit 1 : Pin 1 */ +#define GPIO_DIR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_DIR_PIN1_Msk (0x1UL << GPIO_DIR_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_DIR_PIN1_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN1_Output (1UL) /*!< Pin set as output */ + +/* Bit 0 : Pin 0 */ +#define GPIO_DIR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_DIR_PIN0_Msk (0x1UL << GPIO_DIR_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_DIR_PIN0_Input (0UL) /*!< Pin set as input */ +#define GPIO_DIR_PIN0_Output (1UL) /*!< Pin set as output */ + +/* Register: GPIO_DIRSET */ +/* Description: DIR set register */ + +/* Bit 31 : Set as output pin 31 */ +#define GPIO_DIRSET_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_DIRSET_PIN31_Msk (0x1UL << GPIO_DIRSET_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_DIRSET_PIN31_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN31_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN31_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 30 : Set as output pin 30 */ +#define GPIO_DIRSET_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_DIRSET_PIN30_Msk (0x1UL << GPIO_DIRSET_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_DIRSET_PIN30_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN30_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN30_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 29 : Set as output pin 29 */ +#define GPIO_DIRSET_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_DIRSET_PIN29_Msk (0x1UL << GPIO_DIRSET_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_DIRSET_PIN29_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN29_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN29_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 28 : Set as output pin 28 */ +#define GPIO_DIRSET_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_DIRSET_PIN28_Msk (0x1UL << GPIO_DIRSET_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_DIRSET_PIN28_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN28_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN28_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 27 : Set as output pin 27 */ +#define GPIO_DIRSET_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_DIRSET_PIN27_Msk (0x1UL << GPIO_DIRSET_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_DIRSET_PIN27_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN27_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN27_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 26 : Set as output pin 26 */ +#define GPIO_DIRSET_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_DIRSET_PIN26_Msk (0x1UL << GPIO_DIRSET_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_DIRSET_PIN26_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN26_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN26_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 25 : Set as output pin 25 */ +#define GPIO_DIRSET_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_DIRSET_PIN25_Msk (0x1UL << GPIO_DIRSET_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_DIRSET_PIN25_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN25_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN25_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 24 : Set as output pin 24 */ +#define GPIO_DIRSET_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_DIRSET_PIN24_Msk (0x1UL << GPIO_DIRSET_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_DIRSET_PIN24_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN24_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN24_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 23 : Set as output pin 23 */ +#define GPIO_DIRSET_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_DIRSET_PIN23_Msk (0x1UL << GPIO_DIRSET_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_DIRSET_PIN23_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN23_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN23_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 22 : Set as output pin 22 */ +#define GPIO_DIRSET_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_DIRSET_PIN22_Msk (0x1UL << GPIO_DIRSET_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_DIRSET_PIN22_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN22_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN22_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 21 : Set as output pin 21 */ +#define GPIO_DIRSET_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_DIRSET_PIN21_Msk (0x1UL << GPIO_DIRSET_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_DIRSET_PIN21_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN21_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN21_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 20 : Set as output pin 20 */ +#define GPIO_DIRSET_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_DIRSET_PIN20_Msk (0x1UL << GPIO_DIRSET_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_DIRSET_PIN20_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN20_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN20_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 19 : Set as output pin 19 */ +#define GPIO_DIRSET_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_DIRSET_PIN19_Msk (0x1UL << GPIO_DIRSET_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_DIRSET_PIN19_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN19_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN19_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 18 : Set as output pin 18 */ +#define GPIO_DIRSET_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_DIRSET_PIN18_Msk (0x1UL << GPIO_DIRSET_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_DIRSET_PIN18_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN18_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN18_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 17 : Set as output pin 17 */ +#define GPIO_DIRSET_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_DIRSET_PIN17_Msk (0x1UL << GPIO_DIRSET_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_DIRSET_PIN17_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN17_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN17_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 16 : Set as output pin 16 */ +#define GPIO_DIRSET_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_DIRSET_PIN16_Msk (0x1UL << GPIO_DIRSET_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_DIRSET_PIN16_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN16_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN16_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 15 : Set as output pin 15 */ +#define GPIO_DIRSET_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_DIRSET_PIN15_Msk (0x1UL << GPIO_DIRSET_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_DIRSET_PIN15_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN15_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN15_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 14 : Set as output pin 14 */ +#define GPIO_DIRSET_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_DIRSET_PIN14_Msk (0x1UL << GPIO_DIRSET_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_DIRSET_PIN14_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN14_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN14_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 13 : Set as output pin 13 */ +#define GPIO_DIRSET_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_DIRSET_PIN13_Msk (0x1UL << GPIO_DIRSET_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_DIRSET_PIN13_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN13_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN13_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 12 : Set as output pin 12 */ +#define GPIO_DIRSET_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_DIRSET_PIN12_Msk (0x1UL << GPIO_DIRSET_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_DIRSET_PIN12_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN12_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN12_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 11 : Set as output pin 11 */ +#define GPIO_DIRSET_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_DIRSET_PIN11_Msk (0x1UL << GPIO_DIRSET_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_DIRSET_PIN11_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN11_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN11_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 10 : Set as output pin 10 */ +#define GPIO_DIRSET_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_DIRSET_PIN10_Msk (0x1UL << GPIO_DIRSET_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_DIRSET_PIN10_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN10_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN10_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 9 : Set as output pin 9 */ +#define GPIO_DIRSET_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_DIRSET_PIN9_Msk (0x1UL << GPIO_DIRSET_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_DIRSET_PIN9_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN9_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN9_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 8 : Set as output pin 8 */ +#define GPIO_DIRSET_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_DIRSET_PIN8_Msk (0x1UL << GPIO_DIRSET_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_DIRSET_PIN8_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN8_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN8_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 7 : Set as output pin 7 */ +#define GPIO_DIRSET_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_DIRSET_PIN7_Msk (0x1UL << GPIO_DIRSET_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_DIRSET_PIN7_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN7_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN7_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 6 : Set as output pin 6 */ +#define GPIO_DIRSET_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_DIRSET_PIN6_Msk (0x1UL << GPIO_DIRSET_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_DIRSET_PIN6_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN6_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN6_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 5 : Set as output pin 5 */ +#define GPIO_DIRSET_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_DIRSET_PIN5_Msk (0x1UL << GPIO_DIRSET_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_DIRSET_PIN5_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN5_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN5_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 4 : Set as output pin 4 */ +#define GPIO_DIRSET_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_DIRSET_PIN4_Msk (0x1UL << GPIO_DIRSET_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_DIRSET_PIN4_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN4_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN4_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 3 : Set as output pin 3 */ +#define GPIO_DIRSET_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_DIRSET_PIN3_Msk (0x1UL << GPIO_DIRSET_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_DIRSET_PIN3_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN3_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN3_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 2 : Set as output pin 2 */ +#define GPIO_DIRSET_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_DIRSET_PIN2_Msk (0x1UL << GPIO_DIRSET_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_DIRSET_PIN2_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN2_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN2_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 1 : Set as output pin 1 */ +#define GPIO_DIRSET_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_DIRSET_PIN1_Msk (0x1UL << GPIO_DIRSET_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_DIRSET_PIN1_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN1_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN1_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Bit 0 : Set as output pin 0 */ +#define GPIO_DIRSET_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_DIRSET_PIN0_Msk (0x1UL << GPIO_DIRSET_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_DIRSET_PIN0_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRSET_PIN0_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRSET_PIN0_Set (1UL) /*!< Write: writing a '1' sets pin to output; writing a '0' has no effect */ + +/* Register: GPIO_DIRCLR */ +/* Description: DIR clear register */ + +/* Bit 31 : Set as input pin 31 */ +#define GPIO_DIRCLR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_DIRCLR_PIN31_Msk (0x1UL << GPIO_DIRCLR_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_DIRCLR_PIN31_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN31_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN31_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 30 : Set as input pin 30 */ +#define GPIO_DIRCLR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_DIRCLR_PIN30_Msk (0x1UL << GPIO_DIRCLR_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_DIRCLR_PIN30_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN30_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN30_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 29 : Set as input pin 29 */ +#define GPIO_DIRCLR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_DIRCLR_PIN29_Msk (0x1UL << GPIO_DIRCLR_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_DIRCLR_PIN29_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN29_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN29_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 28 : Set as input pin 28 */ +#define GPIO_DIRCLR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_DIRCLR_PIN28_Msk (0x1UL << GPIO_DIRCLR_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_DIRCLR_PIN28_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN28_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN28_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 27 : Set as input pin 27 */ +#define GPIO_DIRCLR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_DIRCLR_PIN27_Msk (0x1UL << GPIO_DIRCLR_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_DIRCLR_PIN27_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN27_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN27_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 26 : Set as input pin 26 */ +#define GPIO_DIRCLR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_DIRCLR_PIN26_Msk (0x1UL << GPIO_DIRCLR_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_DIRCLR_PIN26_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN26_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN26_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 25 : Set as input pin 25 */ +#define GPIO_DIRCLR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_DIRCLR_PIN25_Msk (0x1UL << GPIO_DIRCLR_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_DIRCLR_PIN25_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN25_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN25_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 24 : Set as input pin 24 */ +#define GPIO_DIRCLR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_DIRCLR_PIN24_Msk (0x1UL << GPIO_DIRCLR_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_DIRCLR_PIN24_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN24_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN24_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 23 : Set as input pin 23 */ +#define GPIO_DIRCLR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_DIRCLR_PIN23_Msk (0x1UL << GPIO_DIRCLR_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_DIRCLR_PIN23_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN23_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN23_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 22 : Set as input pin 22 */ +#define GPIO_DIRCLR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_DIRCLR_PIN22_Msk (0x1UL << GPIO_DIRCLR_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_DIRCLR_PIN22_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN22_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN22_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 21 : Set as input pin 21 */ +#define GPIO_DIRCLR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_DIRCLR_PIN21_Msk (0x1UL << GPIO_DIRCLR_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_DIRCLR_PIN21_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN21_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN21_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 20 : Set as input pin 20 */ +#define GPIO_DIRCLR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_DIRCLR_PIN20_Msk (0x1UL << GPIO_DIRCLR_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_DIRCLR_PIN20_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN20_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN20_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 19 : Set as input pin 19 */ +#define GPIO_DIRCLR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_DIRCLR_PIN19_Msk (0x1UL << GPIO_DIRCLR_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_DIRCLR_PIN19_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN19_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN19_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 18 : Set as input pin 18 */ +#define GPIO_DIRCLR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_DIRCLR_PIN18_Msk (0x1UL << GPIO_DIRCLR_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_DIRCLR_PIN18_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN18_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN18_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 17 : Set as input pin 17 */ +#define GPIO_DIRCLR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_DIRCLR_PIN17_Msk (0x1UL << GPIO_DIRCLR_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_DIRCLR_PIN17_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN17_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN17_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 16 : Set as input pin 16 */ +#define GPIO_DIRCLR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_DIRCLR_PIN16_Msk (0x1UL << GPIO_DIRCLR_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_DIRCLR_PIN16_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN16_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN16_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 15 : Set as input pin 15 */ +#define GPIO_DIRCLR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_DIRCLR_PIN15_Msk (0x1UL << GPIO_DIRCLR_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_DIRCLR_PIN15_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN15_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN15_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 14 : Set as input pin 14 */ +#define GPIO_DIRCLR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_DIRCLR_PIN14_Msk (0x1UL << GPIO_DIRCLR_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_DIRCLR_PIN14_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN14_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN14_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 13 : Set as input pin 13 */ +#define GPIO_DIRCLR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_DIRCLR_PIN13_Msk (0x1UL << GPIO_DIRCLR_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_DIRCLR_PIN13_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN13_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN13_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 12 : Set as input pin 12 */ +#define GPIO_DIRCLR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_DIRCLR_PIN12_Msk (0x1UL << GPIO_DIRCLR_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_DIRCLR_PIN12_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN12_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN12_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 11 : Set as input pin 11 */ +#define GPIO_DIRCLR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_DIRCLR_PIN11_Msk (0x1UL << GPIO_DIRCLR_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_DIRCLR_PIN11_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN11_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN11_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 10 : Set as input pin 10 */ +#define GPIO_DIRCLR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_DIRCLR_PIN10_Msk (0x1UL << GPIO_DIRCLR_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_DIRCLR_PIN10_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN10_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN10_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 9 : Set as input pin 9 */ +#define GPIO_DIRCLR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_DIRCLR_PIN9_Msk (0x1UL << GPIO_DIRCLR_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_DIRCLR_PIN9_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN9_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN9_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 8 : Set as input pin 8 */ +#define GPIO_DIRCLR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_DIRCLR_PIN8_Msk (0x1UL << GPIO_DIRCLR_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_DIRCLR_PIN8_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN8_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN8_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 7 : Set as input pin 7 */ +#define GPIO_DIRCLR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_DIRCLR_PIN7_Msk (0x1UL << GPIO_DIRCLR_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_DIRCLR_PIN7_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN7_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN7_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 6 : Set as input pin 6 */ +#define GPIO_DIRCLR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_DIRCLR_PIN6_Msk (0x1UL << GPIO_DIRCLR_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_DIRCLR_PIN6_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN6_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN6_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 5 : Set as input pin 5 */ +#define GPIO_DIRCLR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_DIRCLR_PIN5_Msk (0x1UL << GPIO_DIRCLR_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_DIRCLR_PIN5_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN5_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN5_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 4 : Set as input pin 4 */ +#define GPIO_DIRCLR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_DIRCLR_PIN4_Msk (0x1UL << GPIO_DIRCLR_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_DIRCLR_PIN4_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN4_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN4_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 3 : Set as input pin 3 */ +#define GPIO_DIRCLR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_DIRCLR_PIN3_Msk (0x1UL << GPIO_DIRCLR_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_DIRCLR_PIN3_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN3_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN3_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 2 : Set as input pin 2 */ +#define GPIO_DIRCLR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_DIRCLR_PIN2_Msk (0x1UL << GPIO_DIRCLR_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_DIRCLR_PIN2_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN2_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN2_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 1 : Set as input pin 1 */ +#define GPIO_DIRCLR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_DIRCLR_PIN1_Msk (0x1UL << GPIO_DIRCLR_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_DIRCLR_PIN1_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN1_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN1_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Bit 0 : Set as input pin 0 */ +#define GPIO_DIRCLR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_DIRCLR_PIN0_Msk (0x1UL << GPIO_DIRCLR_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_DIRCLR_PIN0_Input (0UL) /*!< Read: pin set as input */ +#define GPIO_DIRCLR_PIN0_Output (1UL) /*!< Read: pin set as output */ +#define GPIO_DIRCLR_PIN0_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ + +/* Register: GPIO_LATCH */ +/* Description: Latch register indicating what GPIO pins that have met the criteria set in the PIN_CNF[n].SENSE registers */ + +/* Bit 31 : Status on whether PIN31 has met criteria set in PIN_CNF31.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_LATCH_PIN31_Msk (0x1UL << GPIO_LATCH_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_LATCH_PIN31_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN31_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 30 : Status on whether PIN30 has met criteria set in PIN_CNF30.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_LATCH_PIN30_Msk (0x1UL << GPIO_LATCH_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_LATCH_PIN30_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN30_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 29 : Status on whether PIN29 has met criteria set in PIN_CNF29.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_LATCH_PIN29_Msk (0x1UL << GPIO_LATCH_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_LATCH_PIN29_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN29_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 28 : Status on whether PIN28 has met criteria set in PIN_CNF28.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_LATCH_PIN28_Msk (0x1UL << GPIO_LATCH_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_LATCH_PIN28_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN28_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 27 : Status on whether PIN27 has met criteria set in PIN_CNF27.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_LATCH_PIN27_Msk (0x1UL << GPIO_LATCH_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_LATCH_PIN27_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN27_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 26 : Status on whether PIN26 has met criteria set in PIN_CNF26.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_LATCH_PIN26_Msk (0x1UL << GPIO_LATCH_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_LATCH_PIN26_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN26_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 25 : Status on whether PIN25 has met criteria set in PIN_CNF25.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_LATCH_PIN25_Msk (0x1UL << GPIO_LATCH_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_LATCH_PIN25_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN25_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 24 : Status on whether PIN24 has met criteria set in PIN_CNF24.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_LATCH_PIN24_Msk (0x1UL << GPIO_LATCH_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_LATCH_PIN24_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN24_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 23 : Status on whether PIN23 has met criteria set in PIN_CNF23.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_LATCH_PIN23_Msk (0x1UL << GPIO_LATCH_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_LATCH_PIN23_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN23_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 22 : Status on whether PIN22 has met criteria set in PIN_CNF22.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_LATCH_PIN22_Msk (0x1UL << GPIO_LATCH_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_LATCH_PIN22_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN22_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 21 : Status on whether PIN21 has met criteria set in PIN_CNF21.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_LATCH_PIN21_Msk (0x1UL << GPIO_LATCH_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_LATCH_PIN21_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN21_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 20 : Status on whether PIN20 has met criteria set in PIN_CNF20.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_LATCH_PIN20_Msk (0x1UL << GPIO_LATCH_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_LATCH_PIN20_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN20_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 19 : Status on whether PIN19 has met criteria set in PIN_CNF19.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_LATCH_PIN19_Msk (0x1UL << GPIO_LATCH_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_LATCH_PIN19_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN19_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 18 : Status on whether PIN18 has met criteria set in PIN_CNF18.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_LATCH_PIN18_Msk (0x1UL << GPIO_LATCH_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_LATCH_PIN18_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN18_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 17 : Status on whether PIN17 has met criteria set in PIN_CNF17.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_LATCH_PIN17_Msk (0x1UL << GPIO_LATCH_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_LATCH_PIN17_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN17_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 16 : Status on whether PIN16 has met criteria set in PIN_CNF16.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_LATCH_PIN16_Msk (0x1UL << GPIO_LATCH_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_LATCH_PIN16_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN16_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 15 : Status on whether PIN15 has met criteria set in PIN_CNF15.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_LATCH_PIN15_Msk (0x1UL << GPIO_LATCH_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_LATCH_PIN15_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN15_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 14 : Status on whether PIN14 has met criteria set in PIN_CNF14.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_LATCH_PIN14_Msk (0x1UL << GPIO_LATCH_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_LATCH_PIN14_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN14_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 13 : Status on whether PIN13 has met criteria set in PIN_CNF13.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_LATCH_PIN13_Msk (0x1UL << GPIO_LATCH_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_LATCH_PIN13_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN13_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 12 : Status on whether PIN12 has met criteria set in PIN_CNF12.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_LATCH_PIN12_Msk (0x1UL << GPIO_LATCH_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_LATCH_PIN12_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN12_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 11 : Status on whether PIN11 has met criteria set in PIN_CNF11.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_LATCH_PIN11_Msk (0x1UL << GPIO_LATCH_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_LATCH_PIN11_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN11_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 10 : Status on whether PIN10 has met criteria set in PIN_CNF10.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_LATCH_PIN10_Msk (0x1UL << GPIO_LATCH_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_LATCH_PIN10_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN10_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 9 : Status on whether PIN9 has met criteria set in PIN_CNF9.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_LATCH_PIN9_Msk (0x1UL << GPIO_LATCH_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_LATCH_PIN9_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN9_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 8 : Status on whether PIN8 has met criteria set in PIN_CNF8.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_LATCH_PIN8_Msk (0x1UL << GPIO_LATCH_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_LATCH_PIN8_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN8_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 7 : Status on whether PIN7 has met criteria set in PIN_CNF7.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_LATCH_PIN7_Msk (0x1UL << GPIO_LATCH_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_LATCH_PIN7_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN7_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 6 : Status on whether PIN6 has met criteria set in PIN_CNF6.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_LATCH_PIN6_Msk (0x1UL << GPIO_LATCH_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_LATCH_PIN6_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN6_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 5 : Status on whether PIN5 has met criteria set in PIN_CNF5.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_LATCH_PIN5_Msk (0x1UL << GPIO_LATCH_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_LATCH_PIN5_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN5_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 4 : Status on whether PIN4 has met criteria set in PIN_CNF4.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_LATCH_PIN4_Msk (0x1UL << GPIO_LATCH_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_LATCH_PIN4_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN4_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 3 : Status on whether PIN3 has met criteria set in PIN_CNF3.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_LATCH_PIN3_Msk (0x1UL << GPIO_LATCH_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_LATCH_PIN3_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN3_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 2 : Status on whether PIN2 has met criteria set in PIN_CNF2.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_LATCH_PIN2_Msk (0x1UL << GPIO_LATCH_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_LATCH_PIN2_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN2_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 1 : Status on whether PIN1 has met criteria set in PIN_CNF1.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_LATCH_PIN1_Msk (0x1UL << GPIO_LATCH_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_LATCH_PIN1_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN1_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 0 : Status on whether PIN0 has met criteria set in PIN_CNF0.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_LATCH_PIN0_Msk (0x1UL << GPIO_LATCH_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_LATCH_PIN0_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN0_Latched (1UL) /*!< Criteria has been met */ + +/* Register: GPIO_DETECTMODE */ +/* Description: Select between default DETECT signal behaviour and LDETECT mode */ + +/* Bit 0 : Select between default DETECT signal behaviour and LDETECT mode */ +#define GPIO_DETECTMODE_DETECTMODE_Pos (0UL) /*!< Position of DETECTMODE field. */ +#define GPIO_DETECTMODE_DETECTMODE_Msk (0x1UL << GPIO_DETECTMODE_DETECTMODE_Pos) /*!< Bit mask of DETECTMODE field. */ +#define GPIO_DETECTMODE_DETECTMODE_Default (0UL) /*!< DETECT directly connected to PIN DETECT signals */ +#define GPIO_DETECTMODE_DETECTMODE_LDETECT (1UL) /*!< Use the latched LDETECT behaviour */ + +/* Register: GPIO_PIN_CNF */ +/* Description: Description collection[0]: Configuration of GPIO pins */ + +/* Bits 17..16 : Pin sensing mechanism */ +#define GPIO_PIN_CNF_SENSE_Pos (16UL) /*!< Position of SENSE field. */ +#define GPIO_PIN_CNF_SENSE_Msk (0x3UL << GPIO_PIN_CNF_SENSE_Pos) /*!< Bit mask of SENSE field. */ +#define GPIO_PIN_CNF_SENSE_Disabled (0UL) /*!< Disabled */ +#define GPIO_PIN_CNF_SENSE_High (2UL) /*!< Sense for high level */ +#define GPIO_PIN_CNF_SENSE_Low (3UL) /*!< Sense for low level */ + +/* Bits 10..8 : Drive configuration */ +#define GPIO_PIN_CNF_DRIVE_Pos (8UL) /*!< Position of DRIVE field. */ +#define GPIO_PIN_CNF_DRIVE_Msk (0x7UL << GPIO_PIN_CNF_DRIVE_Pos) /*!< Bit mask of DRIVE field. */ +#define GPIO_PIN_CNF_DRIVE_S0S1 (0UL) /*!< Standard '0', standard '1' */ +#define GPIO_PIN_CNF_DRIVE_H0S1 (1UL) /*!< High drive '0', standard '1' */ +#define GPIO_PIN_CNF_DRIVE_S0H1 (2UL) /*!< Standard '0', high drive '1' */ +#define GPIO_PIN_CNF_DRIVE_H0H1 (3UL) /*!< High drive '0', high 'drive '1'' */ +#define GPIO_PIN_CNF_DRIVE_D0S1 (4UL) /*!< Disconnect '0' standard '1' (normally used for wired-or connections) */ +#define GPIO_PIN_CNF_DRIVE_D0H1 (5UL) /*!< Disconnect '0', high drive '1' (normally used for wired-or connections) */ +#define GPIO_PIN_CNF_DRIVE_S0D1 (6UL) /*!< Standard '0'. disconnect '1' (normally used for wired-and connections) */ +#define GPIO_PIN_CNF_DRIVE_H0D1 (7UL) /*!< High drive '0', disconnect '1' (normally used for wired-and connections) */ + +/* Bits 3..2 : Pull configuration */ +#define GPIO_PIN_CNF_PULL_Pos (2UL) /*!< Position of PULL field. */ +#define GPIO_PIN_CNF_PULL_Msk (0x3UL << GPIO_PIN_CNF_PULL_Pos) /*!< Bit mask of PULL field. */ +#define GPIO_PIN_CNF_PULL_Disabled (0UL) /*!< No pull */ +#define GPIO_PIN_CNF_PULL_Pulldown (1UL) /*!< Pull down on pin */ +#define GPIO_PIN_CNF_PULL_Pullup (3UL) /*!< Pull up on pin */ + +/* Bit 1 : Connect or disconnect input buffer */ +#define GPIO_PIN_CNF_INPUT_Pos (1UL) /*!< Position of INPUT field. */ +#define GPIO_PIN_CNF_INPUT_Msk (0x1UL << GPIO_PIN_CNF_INPUT_Pos) /*!< Bit mask of INPUT field. */ +#define GPIO_PIN_CNF_INPUT_Connect (0UL) /*!< Connect input buffer */ +#define GPIO_PIN_CNF_INPUT_Disconnect (1UL) /*!< Disconnect input buffer */ + +/* Bit 0 : Pin direction. Same physical register as DIR register */ +#define GPIO_PIN_CNF_DIR_Pos (0UL) /*!< Position of DIR field. */ +#define GPIO_PIN_CNF_DIR_Msk (0x1UL << GPIO_PIN_CNF_DIR_Pos) /*!< Bit mask of DIR field. */ +#define GPIO_PIN_CNF_DIR_Input (0UL) /*!< Configure pin as an input pin */ +#define GPIO_PIN_CNF_DIR_Output (1UL) /*!< Configure pin as an output pin */ + + +/* Peripheral: PDM */ +/* Description: Pulse Density Modulation (Digital Microphone) Interface */ + +/* Register: PDM_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 2 : Enable or disable interrupt for END event */ +#define PDM_INTEN_END_Pos (2UL) /*!< Position of END field. */ +#define PDM_INTEN_END_Msk (0x1UL << PDM_INTEN_END_Pos) /*!< Bit mask of END field. */ +#define PDM_INTEN_END_Disabled (0UL) /*!< Disable */ +#define PDM_INTEN_END_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for STOPPED event */ +#define PDM_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PDM_INTEN_STOPPED_Msk (0x1UL << PDM_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PDM_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define PDM_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for STARTED event */ +#define PDM_INTEN_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define PDM_INTEN_STARTED_Msk (0x1UL << PDM_INTEN_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define PDM_INTEN_STARTED_Disabled (0UL) /*!< Disable */ +#define PDM_INTEN_STARTED_Enabled (1UL) /*!< Enable */ + +/* Register: PDM_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 2 : Write '1' to Enable interrupt for END event */ +#define PDM_INTENSET_END_Pos (2UL) /*!< Position of END field. */ +#define PDM_INTENSET_END_Msk (0x1UL << PDM_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define PDM_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define PDM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PDM_INTENSET_STOPPED_Msk (0x1UL << PDM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PDM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for STARTED event */ +#define PDM_INTENSET_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define PDM_INTENSET_STARTED_Msk (0x1UL << PDM_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define PDM_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENSET_STARTED_Set (1UL) /*!< Enable */ + +/* Register: PDM_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 2 : Write '1' to Disable interrupt for END event */ +#define PDM_INTENCLR_END_Pos (2UL) /*!< Position of END field. */ +#define PDM_INTENCLR_END_Msk (0x1UL << PDM_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define PDM_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define PDM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PDM_INTENCLR_STOPPED_Msk (0x1UL << PDM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PDM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for STARTED event */ +#define PDM_INTENCLR_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define PDM_INTENCLR_STARTED_Msk (0x1UL << PDM_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define PDM_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define PDM_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define PDM_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ + +/* Register: PDM_ENABLE */ +/* Description: PDM module enable register */ + +/* Bit 0 : Enable or disable PDM module */ +#define PDM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define PDM_ENABLE_ENABLE_Msk (0x1UL << PDM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define PDM_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define PDM_ENABLE_ENABLE_Enabled (1UL) /*!< Enable */ + +/* Register: PDM_PDMCLKCTRL */ +/* Description: PDM clock generator control */ + +/* Bits 31..0 : PDM_CLK frequency */ +#define PDM_PDMCLKCTRL_FREQ_Pos (0UL) /*!< Position of FREQ field. */ +#define PDM_PDMCLKCTRL_FREQ_Msk (0xFFFFFFFFUL << PDM_PDMCLKCTRL_FREQ_Pos) /*!< Bit mask of FREQ field. */ +#define PDM_PDMCLKCTRL_FREQ_1000K (0x08000000UL) /*!< PDM_CLK = 32 MHz / 32 = 1.000 MHz */ +#define PDM_PDMCLKCTRL_FREQ_Default (0x08400000UL) /*!< PDM_CLK = 32 MHz / 31 = 1.032 MHz. Nominal clock for RATIO=Ratio64. */ +#define PDM_PDMCLKCTRL_FREQ_1067K (0x08800000UL) /*!< PDM_CLK = 32 MHz / 30 = 1.067 MHz */ +#define PDM_PDMCLKCTRL_FREQ_1231K (0x09800000UL) /*!< PDM_CLK = 32 MHz / 26 = 1.231 MHz */ +#define PDM_PDMCLKCTRL_FREQ_1280K (0x0A000000UL) /*!< PDM_CLK = 32 MHz / 25 = 1.280 MHz. Nominal clock for RATIO=Ratio80. */ +#define PDM_PDMCLKCTRL_FREQ_1333K (0x0A800000UL) /*!< PDM_CLK = 32 MHz / 24 = 1.333 MHz */ + +/* Register: PDM_MODE */ +/* Description: Defines the routing of the connected PDM microphones' signals */ + +/* Bit 1 : Defines on which PDM_CLK edge Left (or mono) is sampled */ +#define PDM_MODE_EDGE_Pos (1UL) /*!< Position of EDGE field. */ +#define PDM_MODE_EDGE_Msk (0x1UL << PDM_MODE_EDGE_Pos) /*!< Bit mask of EDGE field. */ +#define PDM_MODE_EDGE_LeftFalling (0UL) /*!< Left (or mono) is sampled on falling edge of PDM_CLK */ +#define PDM_MODE_EDGE_LeftRising (1UL) /*!< Left (or mono) is sampled on rising edge of PDM_CLK */ + +/* Bit 0 : Mono or stereo operation */ +#define PDM_MODE_OPERATION_Pos (0UL) /*!< Position of OPERATION field. */ +#define PDM_MODE_OPERATION_Msk (0x1UL << PDM_MODE_OPERATION_Pos) /*!< Bit mask of OPERATION field. */ +#define PDM_MODE_OPERATION_Stereo (0UL) /*!< Sample and store one pair (Left + Right) of 16bit samples per RAM word R=[31:16]; L=[15:0] */ +#define PDM_MODE_OPERATION_Mono (1UL) /*!< Sample and store two successive Left samples (16 bit each) per RAM word L1=[31:16]; L0=[15:0] */ + +/* Register: PDM_GAINL */ +/* Description: Left output gain adjustment */ + +/* Bits 6..0 : Left output gain adjustment, in 0.5 dB steps, around the default module gain (see electrical parameters) 0x00 -20 dB gain adjust 0x01 -19.5 dB gain adjust (...) 0x27 -0.5 dB gain adjust 0x28 0 dB gain adjust 0x29 +0.5 dB gain adjust (...) 0x4F +19.5 dB gain adjust 0x50 +20 dB gain adjust */ +#define PDM_GAINL_GAINL_Pos (0UL) /*!< Position of GAINL field. */ +#define PDM_GAINL_GAINL_Msk (0x7FUL << PDM_GAINL_GAINL_Pos) /*!< Bit mask of GAINL field. */ +#define PDM_GAINL_GAINL_MinGain (0x00UL) /*!< -20dB gain adjustment (minimum) */ +#define PDM_GAINL_GAINL_DefaultGain (0x28UL) /*!< 0dB gain adjustment ('2500 RMS' requirement) */ +#define PDM_GAINL_GAINL_MaxGain (0x50UL) /*!< +20dB gain adjustment (maximum) */ + +/* Register: PDM_GAINR */ +/* Description: Right output gain adjustment */ + +/* Bits 7..0 : Right output gain adjustment, in 0.5 dB steps, around the default module gain (see electrical parameters) */ +#define PDM_GAINR_GAINR_Pos (0UL) /*!< Position of GAINR field. */ +#define PDM_GAINR_GAINR_Msk (0xFFUL << PDM_GAINR_GAINR_Pos) /*!< Bit mask of GAINR field. */ +#define PDM_GAINR_GAINR_MinGain (0x00UL) /*!< -20dB gain adjustment (minimum) */ +#define PDM_GAINR_GAINR_DefaultGain (0x28UL) /*!< 0dB gain adjustment ('2500 RMS' requirement) */ +#define PDM_GAINR_GAINR_MaxGain (0x50UL) /*!< +20dB gain adjustment (maximum) */ + +/* Register: PDM_RATIO */ +/* Description: Selects the ratio between PDM_CLK and output sample rate. Change PDMCLKCTRL accordingly. */ + +/* Bit 0 : Selects the ratio between PDM_CLK and output sample rate */ +#define PDM_RATIO_RATIO_Pos (0UL) /*!< Position of RATIO field. */ +#define PDM_RATIO_RATIO_Msk (0x1UL << PDM_RATIO_RATIO_Pos) /*!< Bit mask of RATIO field. */ +#define PDM_RATIO_RATIO_Ratio64 (0UL) /*!< Ratio of 64 */ +#define PDM_RATIO_RATIO_Ratio80 (1UL) /*!< Ratio of 80 */ + +/* Register: PDM_PSEL_CLK */ +/* Description: Pin number configuration for PDM CLK signal */ + +/* Bit 31 : Connection */ +#define PDM_PSEL_CLK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define PDM_PSEL_CLK_CONNECT_Msk (0x1UL << PDM_PSEL_CLK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define PDM_PSEL_CLK_CONNECT_Connected (0UL) /*!< Connect */ +#define PDM_PSEL_CLK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define PDM_PSEL_CLK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define PDM_PSEL_CLK_PORT_Msk (0x3UL << PDM_PSEL_CLK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define PDM_PSEL_CLK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define PDM_PSEL_CLK_PIN_Msk (0x1FUL << PDM_PSEL_CLK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: PDM_PSEL_DIN */ +/* Description: Pin number configuration for PDM DIN signal */ + +/* Bit 31 : Connection */ +#define PDM_PSEL_DIN_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define PDM_PSEL_DIN_CONNECT_Msk (0x1UL << PDM_PSEL_DIN_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define PDM_PSEL_DIN_CONNECT_Connected (0UL) /*!< Connect */ +#define PDM_PSEL_DIN_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define PDM_PSEL_DIN_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define PDM_PSEL_DIN_PORT_Msk (0x3UL << PDM_PSEL_DIN_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define PDM_PSEL_DIN_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define PDM_PSEL_DIN_PIN_Msk (0x1FUL << PDM_PSEL_DIN_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: PDM_SAMPLE_PTR */ +/* Description: RAM address pointer to write samples to with EasyDMA */ + +/* Bits 31..0 : Address to write PDM samples to over DMA */ +#define PDM_SAMPLE_PTR_SAMPLEPTR_Pos (0UL) /*!< Position of SAMPLEPTR field. */ +#define PDM_SAMPLE_PTR_SAMPLEPTR_Msk (0xFFFFFFFFUL << PDM_SAMPLE_PTR_SAMPLEPTR_Pos) /*!< Bit mask of SAMPLEPTR field. */ + +/* Register: PDM_SAMPLE_MAXCNT */ +/* Description: Number of samples to allocate memory for in EasyDMA mode */ + +/* Bits 14..0 : Length of DMA RAM allocation in number of samples */ +#define PDM_SAMPLE_MAXCNT_BUFFSIZE_Pos (0UL) /*!< Position of BUFFSIZE field. */ +#define PDM_SAMPLE_MAXCNT_BUFFSIZE_Msk (0x7FFFUL << PDM_SAMPLE_MAXCNT_BUFFSIZE_Pos) /*!< Bit mask of BUFFSIZE field. */ + + +/* Peripheral: POWER */ +/* Description: Power control */ + +/* Register: POWER_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 9 : Write '1' to Enable interrupt for USBPWRRDY event */ +#define POWER_INTENSET_USBPWRRDY_Pos (9UL) /*!< Position of USBPWRRDY field. */ +#define POWER_INTENSET_USBPWRRDY_Msk (0x1UL << POWER_INTENSET_USBPWRRDY_Pos) /*!< Bit mask of USBPWRRDY field. */ +#define POWER_INTENSET_USBPWRRDY_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_USBPWRRDY_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_USBPWRRDY_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for USBREMOVED event */ +#define POWER_INTENSET_USBREMOVED_Pos (8UL) /*!< Position of USBREMOVED field. */ +#define POWER_INTENSET_USBREMOVED_Msk (0x1UL << POWER_INTENSET_USBREMOVED_Pos) /*!< Bit mask of USBREMOVED field. */ +#define POWER_INTENSET_USBREMOVED_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_USBREMOVED_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_USBREMOVED_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for USBDETECTED event */ +#define POWER_INTENSET_USBDETECTED_Pos (7UL) /*!< Position of USBDETECTED field. */ +#define POWER_INTENSET_USBDETECTED_Msk (0x1UL << POWER_INTENSET_USBDETECTED_Pos) /*!< Bit mask of USBDETECTED field. */ +#define POWER_INTENSET_USBDETECTED_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_USBDETECTED_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_USBDETECTED_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for SLEEPEXIT event */ +#define POWER_INTENSET_SLEEPEXIT_Pos (6UL) /*!< Position of SLEEPEXIT field. */ +#define POWER_INTENSET_SLEEPEXIT_Msk (0x1UL << POWER_INTENSET_SLEEPEXIT_Pos) /*!< Bit mask of SLEEPEXIT field. */ +#define POWER_INTENSET_SLEEPEXIT_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_SLEEPEXIT_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_SLEEPEXIT_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for SLEEPENTER event */ +#define POWER_INTENSET_SLEEPENTER_Pos (5UL) /*!< Position of SLEEPENTER field. */ +#define POWER_INTENSET_SLEEPENTER_Msk (0x1UL << POWER_INTENSET_SLEEPENTER_Pos) /*!< Bit mask of SLEEPENTER field. */ +#define POWER_INTENSET_SLEEPENTER_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_SLEEPENTER_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_SLEEPENTER_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for POFWARN event */ +#define POWER_INTENSET_POFWARN_Pos (2UL) /*!< Position of POFWARN field. */ +#define POWER_INTENSET_POFWARN_Msk (0x1UL << POWER_INTENSET_POFWARN_Pos) /*!< Bit mask of POFWARN field. */ +#define POWER_INTENSET_POFWARN_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENSET_POFWARN_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENSET_POFWARN_Set (1UL) /*!< Enable */ + +/* Register: POWER_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 9 : Write '1' to Disable interrupt for USBPWRRDY event */ +#define POWER_INTENCLR_USBPWRRDY_Pos (9UL) /*!< Position of USBPWRRDY field. */ +#define POWER_INTENCLR_USBPWRRDY_Msk (0x1UL << POWER_INTENCLR_USBPWRRDY_Pos) /*!< Bit mask of USBPWRRDY field. */ +#define POWER_INTENCLR_USBPWRRDY_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_USBPWRRDY_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_USBPWRRDY_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for USBREMOVED event */ +#define POWER_INTENCLR_USBREMOVED_Pos (8UL) /*!< Position of USBREMOVED field. */ +#define POWER_INTENCLR_USBREMOVED_Msk (0x1UL << POWER_INTENCLR_USBREMOVED_Pos) /*!< Bit mask of USBREMOVED field. */ +#define POWER_INTENCLR_USBREMOVED_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_USBREMOVED_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_USBREMOVED_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for USBDETECTED event */ +#define POWER_INTENCLR_USBDETECTED_Pos (7UL) /*!< Position of USBDETECTED field. */ +#define POWER_INTENCLR_USBDETECTED_Msk (0x1UL << POWER_INTENCLR_USBDETECTED_Pos) /*!< Bit mask of USBDETECTED field. */ +#define POWER_INTENCLR_USBDETECTED_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_USBDETECTED_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_USBDETECTED_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for SLEEPEXIT event */ +#define POWER_INTENCLR_SLEEPEXIT_Pos (6UL) /*!< Position of SLEEPEXIT field. */ +#define POWER_INTENCLR_SLEEPEXIT_Msk (0x1UL << POWER_INTENCLR_SLEEPEXIT_Pos) /*!< Bit mask of SLEEPEXIT field. */ +#define POWER_INTENCLR_SLEEPEXIT_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_SLEEPEXIT_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_SLEEPEXIT_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for SLEEPENTER event */ +#define POWER_INTENCLR_SLEEPENTER_Pos (5UL) /*!< Position of SLEEPENTER field. */ +#define POWER_INTENCLR_SLEEPENTER_Msk (0x1UL << POWER_INTENCLR_SLEEPENTER_Pos) /*!< Bit mask of SLEEPENTER field. */ +#define POWER_INTENCLR_SLEEPENTER_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_SLEEPENTER_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_SLEEPENTER_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for POFWARN event */ +#define POWER_INTENCLR_POFWARN_Pos (2UL) /*!< Position of POFWARN field. */ +#define POWER_INTENCLR_POFWARN_Msk (0x1UL << POWER_INTENCLR_POFWARN_Pos) /*!< Bit mask of POFWARN field. */ +#define POWER_INTENCLR_POFWARN_Disabled (0UL) /*!< Read: Disabled */ +#define POWER_INTENCLR_POFWARN_Enabled (1UL) /*!< Read: Enabled */ +#define POWER_INTENCLR_POFWARN_Clear (1UL) /*!< Disable */ + +/* Register: POWER_RESETREAS */ +/* Description: Reset reason */ + +/* Bit 20 : Reset due to wake up from System OFF mode by Vbus rising into valid range */ +#define POWER_RESETREAS_VBUS_Pos (20UL) /*!< Position of VBUS field. */ +#define POWER_RESETREAS_VBUS_Msk (0x1UL << POWER_RESETREAS_VBUS_Pos) /*!< Bit mask of VBUS field. */ +#define POWER_RESETREAS_VBUS_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_VBUS_Detected (1UL) /*!< Detected */ + +/* Bit 19 : Reset due to wake up from System OFF mode by NFC field detect */ +#define POWER_RESETREAS_NFC_Pos (19UL) /*!< Position of NFC field. */ +#define POWER_RESETREAS_NFC_Msk (0x1UL << POWER_RESETREAS_NFC_Pos) /*!< Bit mask of NFC field. */ +#define POWER_RESETREAS_NFC_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_NFC_Detected (1UL) /*!< Detected */ + +/* Bit 18 : Reset due to wake up from System OFF mode when wakeup is triggered from entering into debug interface mode */ +#define POWER_RESETREAS_DIF_Pos (18UL) /*!< Position of DIF field. */ +#define POWER_RESETREAS_DIF_Msk (0x1UL << POWER_RESETREAS_DIF_Pos) /*!< Bit mask of DIF field. */ +#define POWER_RESETREAS_DIF_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_DIF_Detected (1UL) /*!< Detected */ + +/* Bit 17 : Reset due to wake up from System OFF mode when wakeup is triggered from ANADETECT signal from LPCOMP */ +#define POWER_RESETREAS_LPCOMP_Pos (17UL) /*!< Position of LPCOMP field. */ +#define POWER_RESETREAS_LPCOMP_Msk (0x1UL << POWER_RESETREAS_LPCOMP_Pos) /*!< Bit mask of LPCOMP field. */ +#define POWER_RESETREAS_LPCOMP_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_LPCOMP_Detected (1UL) /*!< Detected */ + +/* Bit 16 : Reset due to wake up from System OFF mode when wakeup is triggered from DETECT signal from GPIO */ +#define POWER_RESETREAS_OFF_Pos (16UL) /*!< Position of OFF field. */ +#define POWER_RESETREAS_OFF_Msk (0x1UL << POWER_RESETREAS_OFF_Pos) /*!< Bit mask of OFF field. */ +#define POWER_RESETREAS_OFF_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_OFF_Detected (1UL) /*!< Detected */ + +/* Bit 3 : Reset from CPU lock-up detected */ +#define POWER_RESETREAS_LOCKUP_Pos (3UL) /*!< Position of LOCKUP field. */ +#define POWER_RESETREAS_LOCKUP_Msk (0x1UL << POWER_RESETREAS_LOCKUP_Pos) /*!< Bit mask of LOCKUP field. */ +#define POWER_RESETREAS_LOCKUP_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_LOCKUP_Detected (1UL) /*!< Detected */ + +/* Bit 2 : Reset from soft reset detected */ +#define POWER_RESETREAS_SREQ_Pos (2UL) /*!< Position of SREQ field. */ +#define POWER_RESETREAS_SREQ_Msk (0x1UL << POWER_RESETREAS_SREQ_Pos) /*!< Bit mask of SREQ field. */ +#define POWER_RESETREAS_SREQ_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_SREQ_Detected (1UL) /*!< Detected */ + +/* Bit 1 : Reset from watchdog detected */ +#define POWER_RESETREAS_DOG_Pos (1UL) /*!< Position of DOG field. */ +#define POWER_RESETREAS_DOG_Msk (0x1UL << POWER_RESETREAS_DOG_Pos) /*!< Bit mask of DOG field. */ +#define POWER_RESETREAS_DOG_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_DOG_Detected (1UL) /*!< Detected */ + +/* Bit 0 : Reset from pin-reset detected */ +#define POWER_RESETREAS_RESETPIN_Pos (0UL) /*!< Position of RESETPIN field. */ +#define POWER_RESETREAS_RESETPIN_Msk (0x1UL << POWER_RESETREAS_RESETPIN_Pos) /*!< Bit mask of RESETPIN field. */ +#define POWER_RESETREAS_RESETPIN_NotDetected (0UL) /*!< Not detected */ +#define POWER_RESETREAS_RESETPIN_Detected (1UL) /*!< Detected */ + +/* Register: POWER_RAMSTATUS */ +/* Description: Deprecated register - RAM status register */ + +/* Bit 3 : RAM block 3 is on or off/powering up */ +#define POWER_RAMSTATUS_RAMBLOCK3_Pos (3UL) /*!< Position of RAMBLOCK3 field. */ +#define POWER_RAMSTATUS_RAMBLOCK3_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK3_Pos) /*!< Bit mask of RAMBLOCK3 field. */ +#define POWER_RAMSTATUS_RAMBLOCK3_Off (0UL) /*!< Off */ +#define POWER_RAMSTATUS_RAMBLOCK3_On (1UL) /*!< On */ + +/* Bit 2 : RAM block 2 is on or off/powering up */ +#define POWER_RAMSTATUS_RAMBLOCK2_Pos (2UL) /*!< Position of RAMBLOCK2 field. */ +#define POWER_RAMSTATUS_RAMBLOCK2_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK2_Pos) /*!< Bit mask of RAMBLOCK2 field. */ +#define POWER_RAMSTATUS_RAMBLOCK2_Off (0UL) /*!< Off */ +#define POWER_RAMSTATUS_RAMBLOCK2_On (1UL) /*!< On */ + +/* Bit 1 : RAM block 1 is on or off/powering up */ +#define POWER_RAMSTATUS_RAMBLOCK1_Pos (1UL) /*!< Position of RAMBLOCK1 field. */ +#define POWER_RAMSTATUS_RAMBLOCK1_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK1_Pos) /*!< Bit mask of RAMBLOCK1 field. */ +#define POWER_RAMSTATUS_RAMBLOCK1_Off (0UL) /*!< Off */ +#define POWER_RAMSTATUS_RAMBLOCK1_On (1UL) /*!< On */ + +/* Bit 0 : RAM block 0 is on or off/powering up */ +#define POWER_RAMSTATUS_RAMBLOCK0_Pos (0UL) /*!< Position of RAMBLOCK0 field. */ +#define POWER_RAMSTATUS_RAMBLOCK0_Msk (0x1UL << POWER_RAMSTATUS_RAMBLOCK0_Pos) /*!< Bit mask of RAMBLOCK0 field. */ +#define POWER_RAMSTATUS_RAMBLOCK0_Off (0UL) /*!< Off */ +#define POWER_RAMSTATUS_RAMBLOCK0_On (1UL) /*!< On */ + +/* Register: POWER_USBREGSTATUS */ +/* Description: USB supply status */ + +/* Bit 1 : USB supply output settling time elapsed */ +#define POWER_USBREGSTATUS_OUTPUTRDY_Pos (1UL) /*!< Position of OUTPUTRDY field. */ +#define POWER_USBREGSTATUS_OUTPUTRDY_Msk (0x1UL << POWER_USBREGSTATUS_OUTPUTRDY_Pos) /*!< Bit mask of OUTPUTRDY field. */ +#define POWER_USBREGSTATUS_OUTPUTRDY_NotReady (0UL) /*!< USBREG output settling time not elapsed */ +#define POWER_USBREGSTATUS_OUTPUTRDY_Ready (1UL) /*!< USBREG output settling time elapsed (same information as USBPWRRDY event) */ + +/* Bit 0 : VBUS input detection status (USBDETECTED and USBREMOVED events are derived from this information) */ +#define POWER_USBREGSTATUS_VBUSDETECT_Pos (0UL) /*!< Position of VBUSDETECT field. */ +#define POWER_USBREGSTATUS_VBUSDETECT_Msk (0x1UL << POWER_USBREGSTATUS_VBUSDETECT_Pos) /*!< Bit mask of VBUSDETECT field. */ +#define POWER_USBREGSTATUS_VBUSDETECT_NoVbus (0UL) /*!< VBUS voltage below valid threshold */ +#define POWER_USBREGSTATUS_VBUSDETECT_VbusPresent (1UL) /*!< VBUS voltage above valid threshold */ + +/* Register: POWER_SYSTEMOFF */ +/* Description: System OFF register */ + +/* Bit 0 : Enable System OFF mode */ +#define POWER_SYSTEMOFF_SYSTEMOFF_Pos (0UL) /*!< Position of SYSTEMOFF field. */ +#define POWER_SYSTEMOFF_SYSTEMOFF_Msk (0x1UL << POWER_SYSTEMOFF_SYSTEMOFF_Pos) /*!< Bit mask of SYSTEMOFF field. */ +#define POWER_SYSTEMOFF_SYSTEMOFF_Enter (1UL) /*!< Enable System OFF mode */ + +/* Register: POWER_POFCON */ +/* Description: Power failure comparator configuration */ + +/* Bits 11..8 : Power failure comparator threshold setting for voltage supply on VDDH */ +#define POWER_POFCON_THRESHOLDVDDH_Pos (8UL) /*!< Position of THRESHOLDVDDH field. */ +#define POWER_POFCON_THRESHOLDVDDH_Msk (0xFUL << POWER_POFCON_THRESHOLDVDDH_Pos) /*!< Bit mask of THRESHOLDVDDH field. */ +#define POWER_POFCON_THRESHOLDVDDH_V27 (0UL) /*!< Set threshold to 2.7 V */ +#define POWER_POFCON_THRESHOLDVDDH_V28 (1UL) /*!< Set threshold to 2.8 V */ +#define POWER_POFCON_THRESHOLDVDDH_V29 (2UL) /*!< Set threshold to 2.9 V */ +#define POWER_POFCON_THRESHOLDVDDH_V30 (3UL) /*!< Set threshold to 3.0 V */ +#define POWER_POFCON_THRESHOLDVDDH_V31 (4UL) /*!< Set threshold to 3.1 V */ +#define POWER_POFCON_THRESHOLDVDDH_V32 (5UL) /*!< Set threshold to 3.2 V */ +#define POWER_POFCON_THRESHOLDVDDH_V33 (6UL) /*!< Set threshold to 3.3 V */ +#define POWER_POFCON_THRESHOLDVDDH_V34 (7UL) /*!< Set threshold to 3.4 V */ +#define POWER_POFCON_THRESHOLDVDDH_V35 (8UL) /*!< Set threshold to 3.5 V */ +#define POWER_POFCON_THRESHOLDVDDH_V36 (9UL) /*!< Set threshold to 3.6 V */ +#define POWER_POFCON_THRESHOLDVDDH_V37 (10UL) /*!< Set threshold to 3.7 V */ +#define POWER_POFCON_THRESHOLDVDDH_V38 (11UL) /*!< Set threshold to 3.8 V */ +#define POWER_POFCON_THRESHOLDVDDH_V39 (12UL) /*!< Set threshold to 3.9 V */ +#define POWER_POFCON_THRESHOLDVDDH_V40 (13UL) /*!< Set threshold to 4.0 V */ +#define POWER_POFCON_THRESHOLDVDDH_V41 (14UL) /*!< Set threshold to 4.1 V */ +#define POWER_POFCON_THRESHOLDVDDH_V42 (15UL) /*!< Set threshold to 4.2 V */ + +/* Bits 4..1 : Power failure comparator threshold setting */ +#define POWER_POFCON_THRESHOLD_Pos (1UL) /*!< Position of THRESHOLD field. */ +#define POWER_POFCON_THRESHOLD_Msk (0xFUL << POWER_POFCON_THRESHOLD_Pos) /*!< Bit mask of THRESHOLD field. */ +#define POWER_POFCON_THRESHOLD_V17 (4UL) /*!< Set threshold to 1.7 V */ +#define POWER_POFCON_THRESHOLD_V18 (5UL) /*!< Set threshold to 1.8 V */ +#define POWER_POFCON_THRESHOLD_V19 (6UL) /*!< Set threshold to 1.9 V */ +#define POWER_POFCON_THRESHOLD_V20 (7UL) /*!< Set threshold to 2.0 V */ +#define POWER_POFCON_THRESHOLD_V21 (8UL) /*!< Set threshold to 2.1 V */ +#define POWER_POFCON_THRESHOLD_V22 (9UL) /*!< Set threshold to 2.2 V */ +#define POWER_POFCON_THRESHOLD_V23 (10UL) /*!< Set threshold to 2.3 V */ +#define POWER_POFCON_THRESHOLD_V24 (11UL) /*!< Set threshold to 2.4 V */ +#define POWER_POFCON_THRESHOLD_V25 (12UL) /*!< Set threshold to 2.5 V */ +#define POWER_POFCON_THRESHOLD_V26 (13UL) /*!< Set threshold to 2.6 V */ +#define POWER_POFCON_THRESHOLD_V27 (14UL) /*!< Set threshold to 2.7 V */ +#define POWER_POFCON_THRESHOLD_V28 (15UL) /*!< Set threshold to 2.8 V */ + +/* Bit 0 : Enable or disable power failure comparator */ +#define POWER_POFCON_POF_Pos (0UL) /*!< Position of POF field. */ +#define POWER_POFCON_POF_Msk (0x1UL << POWER_POFCON_POF_Pos) /*!< Bit mask of POF field. */ +#define POWER_POFCON_POF_Disabled (0UL) /*!< Disable */ +#define POWER_POFCON_POF_Enabled (1UL) /*!< Enable */ + +/* Register: POWER_GPREGRET */ +/* Description: General purpose retention register */ + +/* Bits 7..0 : General purpose retention register */ +#define POWER_GPREGRET_GPREGRET_Pos (0UL) /*!< Position of GPREGRET field. */ +#define POWER_GPREGRET_GPREGRET_Msk (0xFFUL << POWER_GPREGRET_GPREGRET_Pos) /*!< Bit mask of GPREGRET field. */ + +/* Register: POWER_GPREGRET2 */ +/* Description: General purpose retention register */ + +/* Bits 7..0 : General purpose retention register */ +#define POWER_GPREGRET2_GPREGRET_Pos (0UL) /*!< Position of GPREGRET field. */ +#define POWER_GPREGRET2_GPREGRET_Msk (0xFFUL << POWER_GPREGRET2_GPREGRET_Pos) /*!< Bit mask of GPREGRET field. */ + +/* Register: POWER_DCDCEN */ +/* Description: Enable DC/DC converter for REG1 stage. */ + +/* Bit 0 : Enable DC/DC converter for REG1 stage. */ +#define POWER_DCDCEN_DCDCEN_Pos (0UL) /*!< Position of DCDCEN field. */ +#define POWER_DCDCEN_DCDCEN_Msk (0x1UL << POWER_DCDCEN_DCDCEN_Pos) /*!< Bit mask of DCDCEN field. */ +#define POWER_DCDCEN_DCDCEN_Disabled (0UL) /*!< Disable */ +#define POWER_DCDCEN_DCDCEN_Enabled (1UL) /*!< Enable */ + +/* Register: POWER_DCDCEN0 */ +/* Description: Enable DC/DC converter for REG0 stage. */ + +/* Bit 0 : Enable DC/DC converter for REG0 stage. */ +#define POWER_DCDCEN0_DCDCEN_Pos (0UL) /*!< Position of DCDCEN field. */ +#define POWER_DCDCEN0_DCDCEN_Msk (0x1UL << POWER_DCDCEN0_DCDCEN_Pos) /*!< Bit mask of DCDCEN field. */ +#define POWER_DCDCEN0_DCDCEN_Disabled (0UL) /*!< Disable */ +#define POWER_DCDCEN0_DCDCEN_Enabled (1UL) /*!< Enable */ + +/* Register: POWER_MAINREGSTATUS */ +/* Description: Main supply status */ + +/* Bit 0 : Main supply status */ +#define POWER_MAINREGSTATUS_MAINREGSTATUS_Pos (0UL) /*!< Position of MAINREGSTATUS field. */ +#define POWER_MAINREGSTATUS_MAINREGSTATUS_Msk (0x1UL << POWER_MAINREGSTATUS_MAINREGSTATUS_Pos) /*!< Bit mask of MAINREGSTATUS field. */ +#define POWER_MAINREGSTATUS_MAINREGSTATUS_Normal (0UL) /*!< Normal voltage mode. Voltage supplied on VDD. */ +#define POWER_MAINREGSTATUS_MAINREGSTATUS_High (1UL) /*!< High voltage mode. Voltage supplied on VDDH. */ + +/* Register: POWER_RAM_POWER */ +/* Description: Description cluster[0]: RAM0 power control register */ + +/* Bit 31 : Keep retention on RAM section S15 when RAM section is in OFF */ +#define POWER_RAM_POWER_S15RETENTION_Pos (31UL) /*!< Position of S15RETENTION field. */ +#define POWER_RAM_POWER_S15RETENTION_Msk (0x1UL << POWER_RAM_POWER_S15RETENTION_Pos) /*!< Bit mask of S15RETENTION field. */ +#define POWER_RAM_POWER_S15RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S15RETENTION_On (1UL) /*!< On */ + +/* Bit 30 : Keep retention on RAM section S14 when RAM section is in OFF */ +#define POWER_RAM_POWER_S14RETENTION_Pos (30UL) /*!< Position of S14RETENTION field. */ +#define POWER_RAM_POWER_S14RETENTION_Msk (0x1UL << POWER_RAM_POWER_S14RETENTION_Pos) /*!< Bit mask of S14RETENTION field. */ +#define POWER_RAM_POWER_S14RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S14RETENTION_On (1UL) /*!< On */ + +/* Bit 29 : Keep retention on RAM section S13 when RAM section is in OFF */ +#define POWER_RAM_POWER_S13RETENTION_Pos (29UL) /*!< Position of S13RETENTION field. */ +#define POWER_RAM_POWER_S13RETENTION_Msk (0x1UL << POWER_RAM_POWER_S13RETENTION_Pos) /*!< Bit mask of S13RETENTION field. */ +#define POWER_RAM_POWER_S13RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S13RETENTION_On (1UL) /*!< On */ + +/* Bit 28 : Keep retention on RAM section S12 when RAM section is in OFF */ +#define POWER_RAM_POWER_S12RETENTION_Pos (28UL) /*!< Position of S12RETENTION field. */ +#define POWER_RAM_POWER_S12RETENTION_Msk (0x1UL << POWER_RAM_POWER_S12RETENTION_Pos) /*!< Bit mask of S12RETENTION field. */ +#define POWER_RAM_POWER_S12RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S12RETENTION_On (1UL) /*!< On */ + +/* Bit 27 : Keep retention on RAM section S11 when RAM section is in OFF */ +#define POWER_RAM_POWER_S11RETENTION_Pos (27UL) /*!< Position of S11RETENTION field. */ +#define POWER_RAM_POWER_S11RETENTION_Msk (0x1UL << POWER_RAM_POWER_S11RETENTION_Pos) /*!< Bit mask of S11RETENTION field. */ +#define POWER_RAM_POWER_S11RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S11RETENTION_On (1UL) /*!< On */ + +/* Bit 26 : Keep retention on RAM section S10 when RAM section is in OFF */ +#define POWER_RAM_POWER_S10RETENTION_Pos (26UL) /*!< Position of S10RETENTION field. */ +#define POWER_RAM_POWER_S10RETENTION_Msk (0x1UL << POWER_RAM_POWER_S10RETENTION_Pos) /*!< Bit mask of S10RETENTION field. */ +#define POWER_RAM_POWER_S10RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S10RETENTION_On (1UL) /*!< On */ + +/* Bit 25 : Keep retention on RAM section S9 when RAM section is in OFF */ +#define POWER_RAM_POWER_S9RETENTION_Pos (25UL) /*!< Position of S9RETENTION field. */ +#define POWER_RAM_POWER_S9RETENTION_Msk (0x1UL << POWER_RAM_POWER_S9RETENTION_Pos) /*!< Bit mask of S9RETENTION field. */ +#define POWER_RAM_POWER_S9RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S9RETENTION_On (1UL) /*!< On */ + +/* Bit 24 : Keep retention on RAM section S8 when RAM section is in OFF */ +#define POWER_RAM_POWER_S8RETENTION_Pos (24UL) /*!< Position of S8RETENTION field. */ +#define POWER_RAM_POWER_S8RETENTION_Msk (0x1UL << POWER_RAM_POWER_S8RETENTION_Pos) /*!< Bit mask of S8RETENTION field. */ +#define POWER_RAM_POWER_S8RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S8RETENTION_On (1UL) /*!< On */ + +/* Bit 23 : Keep retention on RAM section S7 when RAM section is in OFF */ +#define POWER_RAM_POWER_S7RETENTION_Pos (23UL) /*!< Position of S7RETENTION field. */ +#define POWER_RAM_POWER_S7RETENTION_Msk (0x1UL << POWER_RAM_POWER_S7RETENTION_Pos) /*!< Bit mask of S7RETENTION field. */ +#define POWER_RAM_POWER_S7RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S7RETENTION_On (1UL) /*!< On */ + +/* Bit 22 : Keep retention on RAM section S6 when RAM section is in OFF */ +#define POWER_RAM_POWER_S6RETENTION_Pos (22UL) /*!< Position of S6RETENTION field. */ +#define POWER_RAM_POWER_S6RETENTION_Msk (0x1UL << POWER_RAM_POWER_S6RETENTION_Pos) /*!< Bit mask of S6RETENTION field. */ +#define POWER_RAM_POWER_S6RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S6RETENTION_On (1UL) /*!< On */ + +/* Bit 21 : Keep retention on RAM section S5 when RAM section is in OFF */ +#define POWER_RAM_POWER_S5RETENTION_Pos (21UL) /*!< Position of S5RETENTION field. */ +#define POWER_RAM_POWER_S5RETENTION_Msk (0x1UL << POWER_RAM_POWER_S5RETENTION_Pos) /*!< Bit mask of S5RETENTION field. */ +#define POWER_RAM_POWER_S5RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S5RETENTION_On (1UL) /*!< On */ + +/* Bit 20 : Keep retention on RAM section S4 when RAM section is in OFF */ +#define POWER_RAM_POWER_S4RETENTION_Pos (20UL) /*!< Position of S4RETENTION field. */ +#define POWER_RAM_POWER_S4RETENTION_Msk (0x1UL << POWER_RAM_POWER_S4RETENTION_Pos) /*!< Bit mask of S4RETENTION field. */ +#define POWER_RAM_POWER_S4RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S4RETENTION_On (1UL) /*!< On */ + +/* Bit 19 : Keep retention on RAM section S3 when RAM section is in OFF */ +#define POWER_RAM_POWER_S3RETENTION_Pos (19UL) /*!< Position of S3RETENTION field. */ +#define POWER_RAM_POWER_S3RETENTION_Msk (0x1UL << POWER_RAM_POWER_S3RETENTION_Pos) /*!< Bit mask of S3RETENTION field. */ +#define POWER_RAM_POWER_S3RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S3RETENTION_On (1UL) /*!< On */ + +/* Bit 18 : Keep retention on RAM section S2 when RAM section is in OFF */ +#define POWER_RAM_POWER_S2RETENTION_Pos (18UL) /*!< Position of S2RETENTION field. */ +#define POWER_RAM_POWER_S2RETENTION_Msk (0x1UL << POWER_RAM_POWER_S2RETENTION_Pos) /*!< Bit mask of S2RETENTION field. */ +#define POWER_RAM_POWER_S2RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S2RETENTION_On (1UL) /*!< On */ + +/* Bit 17 : Keep retention on RAM section S1 when RAM section is in OFF */ +#define POWER_RAM_POWER_S1RETENTION_Pos (17UL) /*!< Position of S1RETENTION field. */ +#define POWER_RAM_POWER_S1RETENTION_Msk (0x1UL << POWER_RAM_POWER_S1RETENTION_Pos) /*!< Bit mask of S1RETENTION field. */ +#define POWER_RAM_POWER_S1RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S1RETENTION_On (1UL) /*!< On */ + +/* Bit 16 : Keep retention on RAM section S0 when RAM section is in OFF */ +#define POWER_RAM_POWER_S0RETENTION_Pos (16UL) /*!< Position of S0RETENTION field. */ +#define POWER_RAM_POWER_S0RETENTION_Msk (0x1UL << POWER_RAM_POWER_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ +#define POWER_RAM_POWER_S0RETENTION_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S0RETENTION_On (1UL) /*!< On */ + +/* Bit 15 : Keep RAM section S15 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S15POWER_Pos (15UL) /*!< Position of S15POWER field. */ +#define POWER_RAM_POWER_S15POWER_Msk (0x1UL << POWER_RAM_POWER_S15POWER_Pos) /*!< Bit mask of S15POWER field. */ +#define POWER_RAM_POWER_S15POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S15POWER_On (1UL) /*!< On */ + +/* Bit 14 : Keep RAM section S14 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S14POWER_Pos (14UL) /*!< Position of S14POWER field. */ +#define POWER_RAM_POWER_S14POWER_Msk (0x1UL << POWER_RAM_POWER_S14POWER_Pos) /*!< Bit mask of S14POWER field. */ +#define POWER_RAM_POWER_S14POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S14POWER_On (1UL) /*!< On */ + +/* Bit 13 : Keep RAM section S13 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S13POWER_Pos (13UL) /*!< Position of S13POWER field. */ +#define POWER_RAM_POWER_S13POWER_Msk (0x1UL << POWER_RAM_POWER_S13POWER_Pos) /*!< Bit mask of S13POWER field. */ +#define POWER_RAM_POWER_S13POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S13POWER_On (1UL) /*!< On */ + +/* Bit 12 : Keep RAM section S12 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S12POWER_Pos (12UL) /*!< Position of S12POWER field. */ +#define POWER_RAM_POWER_S12POWER_Msk (0x1UL << POWER_RAM_POWER_S12POWER_Pos) /*!< Bit mask of S12POWER field. */ +#define POWER_RAM_POWER_S12POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S12POWER_On (1UL) /*!< On */ + +/* Bit 11 : Keep RAM section S11 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S11POWER_Pos (11UL) /*!< Position of S11POWER field. */ +#define POWER_RAM_POWER_S11POWER_Msk (0x1UL << POWER_RAM_POWER_S11POWER_Pos) /*!< Bit mask of S11POWER field. */ +#define POWER_RAM_POWER_S11POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S11POWER_On (1UL) /*!< On */ + +/* Bit 10 : Keep RAM section S10 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S10POWER_Pos (10UL) /*!< Position of S10POWER field. */ +#define POWER_RAM_POWER_S10POWER_Msk (0x1UL << POWER_RAM_POWER_S10POWER_Pos) /*!< Bit mask of S10POWER field. */ +#define POWER_RAM_POWER_S10POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S10POWER_On (1UL) /*!< On */ + +/* Bit 9 : Keep RAM section S9 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S9POWER_Pos (9UL) /*!< Position of S9POWER field. */ +#define POWER_RAM_POWER_S9POWER_Msk (0x1UL << POWER_RAM_POWER_S9POWER_Pos) /*!< Bit mask of S9POWER field. */ +#define POWER_RAM_POWER_S9POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S9POWER_On (1UL) /*!< On */ + +/* Bit 8 : Keep RAM section S8 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S8POWER_Pos (8UL) /*!< Position of S8POWER field. */ +#define POWER_RAM_POWER_S8POWER_Msk (0x1UL << POWER_RAM_POWER_S8POWER_Pos) /*!< Bit mask of S8POWER field. */ +#define POWER_RAM_POWER_S8POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S8POWER_On (1UL) /*!< On */ + +/* Bit 7 : Keep RAM section S7 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S7POWER_Pos (7UL) /*!< Position of S7POWER field. */ +#define POWER_RAM_POWER_S7POWER_Msk (0x1UL << POWER_RAM_POWER_S7POWER_Pos) /*!< Bit mask of S7POWER field. */ +#define POWER_RAM_POWER_S7POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S7POWER_On (1UL) /*!< On */ + +/* Bit 6 : Keep RAM section S6 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S6POWER_Pos (6UL) /*!< Position of S6POWER field. */ +#define POWER_RAM_POWER_S6POWER_Msk (0x1UL << POWER_RAM_POWER_S6POWER_Pos) /*!< Bit mask of S6POWER field. */ +#define POWER_RAM_POWER_S6POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S6POWER_On (1UL) /*!< On */ + +/* Bit 5 : Keep RAM section S5 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S5POWER_Pos (5UL) /*!< Position of S5POWER field. */ +#define POWER_RAM_POWER_S5POWER_Msk (0x1UL << POWER_RAM_POWER_S5POWER_Pos) /*!< Bit mask of S5POWER field. */ +#define POWER_RAM_POWER_S5POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S5POWER_On (1UL) /*!< On */ + +/* Bit 4 : Keep RAM section S4 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S4POWER_Pos (4UL) /*!< Position of S4POWER field. */ +#define POWER_RAM_POWER_S4POWER_Msk (0x1UL << POWER_RAM_POWER_S4POWER_Pos) /*!< Bit mask of S4POWER field. */ +#define POWER_RAM_POWER_S4POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S4POWER_On (1UL) /*!< On */ + +/* Bit 3 : Keep RAM section S3 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S3POWER_Pos (3UL) /*!< Position of S3POWER field. */ +#define POWER_RAM_POWER_S3POWER_Msk (0x1UL << POWER_RAM_POWER_S3POWER_Pos) /*!< Bit mask of S3POWER field. */ +#define POWER_RAM_POWER_S3POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S3POWER_On (1UL) /*!< On */ + +/* Bit 2 : Keep RAM section S2 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S2POWER_Pos (2UL) /*!< Position of S2POWER field. */ +#define POWER_RAM_POWER_S2POWER_Msk (0x1UL << POWER_RAM_POWER_S2POWER_Pos) /*!< Bit mask of S2POWER field. */ +#define POWER_RAM_POWER_S2POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S2POWER_On (1UL) /*!< On */ + +/* Bit 1 : Keep RAM section S1 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ +#define POWER_RAM_POWER_S1POWER_Msk (0x1UL << POWER_RAM_POWER_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ +#define POWER_RAM_POWER_S1POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S1POWER_On (1UL) /*!< On */ + +/* Bit 0 : Keep RAM section S0 ON or OFF in System ON mode. */ +#define POWER_RAM_POWER_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ +#define POWER_RAM_POWER_S0POWER_Msk (0x1UL << POWER_RAM_POWER_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ +#define POWER_RAM_POWER_S0POWER_Off (0UL) /*!< Off */ +#define POWER_RAM_POWER_S0POWER_On (1UL) /*!< On */ + +/* Register: POWER_RAM_POWERSET */ +/* Description: Description cluster[0]: RAM0 power control set register */ + +/* Bit 31 : Keep retention on RAM section S15 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S15RETENTION_Pos (31UL) /*!< Position of S15RETENTION field. */ +#define POWER_RAM_POWERSET_S15RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S15RETENTION_Pos) /*!< Bit mask of S15RETENTION field. */ +#define POWER_RAM_POWERSET_S15RETENTION_On (1UL) /*!< On */ + +/* Bit 30 : Keep retention on RAM section S14 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S14RETENTION_Pos (30UL) /*!< Position of S14RETENTION field. */ +#define POWER_RAM_POWERSET_S14RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S14RETENTION_Pos) /*!< Bit mask of S14RETENTION field. */ +#define POWER_RAM_POWERSET_S14RETENTION_On (1UL) /*!< On */ + +/* Bit 29 : Keep retention on RAM section S13 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S13RETENTION_Pos (29UL) /*!< Position of S13RETENTION field. */ +#define POWER_RAM_POWERSET_S13RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S13RETENTION_Pos) /*!< Bit mask of S13RETENTION field. */ +#define POWER_RAM_POWERSET_S13RETENTION_On (1UL) /*!< On */ + +/* Bit 28 : Keep retention on RAM section S12 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S12RETENTION_Pos (28UL) /*!< Position of S12RETENTION field. */ +#define POWER_RAM_POWERSET_S12RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S12RETENTION_Pos) /*!< Bit mask of S12RETENTION field. */ +#define POWER_RAM_POWERSET_S12RETENTION_On (1UL) /*!< On */ + +/* Bit 27 : Keep retention on RAM section S11 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S11RETENTION_Pos (27UL) /*!< Position of S11RETENTION field. */ +#define POWER_RAM_POWERSET_S11RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S11RETENTION_Pos) /*!< Bit mask of S11RETENTION field. */ +#define POWER_RAM_POWERSET_S11RETENTION_On (1UL) /*!< On */ + +/* Bit 26 : Keep retention on RAM section S10 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S10RETENTION_Pos (26UL) /*!< Position of S10RETENTION field. */ +#define POWER_RAM_POWERSET_S10RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S10RETENTION_Pos) /*!< Bit mask of S10RETENTION field. */ +#define POWER_RAM_POWERSET_S10RETENTION_On (1UL) /*!< On */ + +/* Bit 25 : Keep retention on RAM section S9 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S9RETENTION_Pos (25UL) /*!< Position of S9RETENTION field. */ +#define POWER_RAM_POWERSET_S9RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S9RETENTION_Pos) /*!< Bit mask of S9RETENTION field. */ +#define POWER_RAM_POWERSET_S9RETENTION_On (1UL) /*!< On */ + +/* Bit 24 : Keep retention on RAM section S8 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S8RETENTION_Pos (24UL) /*!< Position of S8RETENTION field. */ +#define POWER_RAM_POWERSET_S8RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S8RETENTION_Pos) /*!< Bit mask of S8RETENTION field. */ +#define POWER_RAM_POWERSET_S8RETENTION_On (1UL) /*!< On */ + +/* Bit 23 : Keep retention on RAM section S7 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S7RETENTION_Pos (23UL) /*!< Position of S7RETENTION field. */ +#define POWER_RAM_POWERSET_S7RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S7RETENTION_Pos) /*!< Bit mask of S7RETENTION field. */ +#define POWER_RAM_POWERSET_S7RETENTION_On (1UL) /*!< On */ + +/* Bit 22 : Keep retention on RAM section S6 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S6RETENTION_Pos (22UL) /*!< Position of S6RETENTION field. */ +#define POWER_RAM_POWERSET_S6RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S6RETENTION_Pos) /*!< Bit mask of S6RETENTION field. */ +#define POWER_RAM_POWERSET_S6RETENTION_On (1UL) /*!< On */ + +/* Bit 21 : Keep retention on RAM section S5 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S5RETENTION_Pos (21UL) /*!< Position of S5RETENTION field. */ +#define POWER_RAM_POWERSET_S5RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S5RETENTION_Pos) /*!< Bit mask of S5RETENTION field. */ +#define POWER_RAM_POWERSET_S5RETENTION_On (1UL) /*!< On */ + +/* Bit 20 : Keep retention on RAM section S4 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S4RETENTION_Pos (20UL) /*!< Position of S4RETENTION field. */ +#define POWER_RAM_POWERSET_S4RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S4RETENTION_Pos) /*!< Bit mask of S4RETENTION field. */ +#define POWER_RAM_POWERSET_S4RETENTION_On (1UL) /*!< On */ + +/* Bit 19 : Keep retention on RAM section S3 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S3RETENTION_Pos (19UL) /*!< Position of S3RETENTION field. */ +#define POWER_RAM_POWERSET_S3RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S3RETENTION_Pos) /*!< Bit mask of S3RETENTION field. */ +#define POWER_RAM_POWERSET_S3RETENTION_On (1UL) /*!< On */ + +/* Bit 18 : Keep retention on RAM section S2 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S2RETENTION_Pos (18UL) /*!< Position of S2RETENTION field. */ +#define POWER_RAM_POWERSET_S2RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S2RETENTION_Pos) /*!< Bit mask of S2RETENTION field. */ +#define POWER_RAM_POWERSET_S2RETENTION_On (1UL) /*!< On */ + +/* Bit 17 : Keep retention on RAM section S1 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S1RETENTION_Pos (17UL) /*!< Position of S1RETENTION field. */ +#define POWER_RAM_POWERSET_S1RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S1RETENTION_Pos) /*!< Bit mask of S1RETENTION field. */ +#define POWER_RAM_POWERSET_S1RETENTION_On (1UL) /*!< On */ + +/* Bit 16 : Keep retention on RAM section S0 when RAM section is switched off */ +#define POWER_RAM_POWERSET_S0RETENTION_Pos (16UL) /*!< Position of S0RETENTION field. */ +#define POWER_RAM_POWERSET_S0RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ +#define POWER_RAM_POWERSET_S0RETENTION_On (1UL) /*!< On */ + +/* Bit 15 : Keep RAM section S15 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S15POWER_Pos (15UL) /*!< Position of S15POWER field. */ +#define POWER_RAM_POWERSET_S15POWER_Msk (0x1UL << POWER_RAM_POWERSET_S15POWER_Pos) /*!< Bit mask of S15POWER field. */ +#define POWER_RAM_POWERSET_S15POWER_On (1UL) /*!< On */ + +/* Bit 14 : Keep RAM section S14 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S14POWER_Pos (14UL) /*!< Position of S14POWER field. */ +#define POWER_RAM_POWERSET_S14POWER_Msk (0x1UL << POWER_RAM_POWERSET_S14POWER_Pos) /*!< Bit mask of S14POWER field. */ +#define POWER_RAM_POWERSET_S14POWER_On (1UL) /*!< On */ + +/* Bit 13 : Keep RAM section S13 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S13POWER_Pos (13UL) /*!< Position of S13POWER field. */ +#define POWER_RAM_POWERSET_S13POWER_Msk (0x1UL << POWER_RAM_POWERSET_S13POWER_Pos) /*!< Bit mask of S13POWER field. */ +#define POWER_RAM_POWERSET_S13POWER_On (1UL) /*!< On */ + +/* Bit 12 : Keep RAM section S12 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S12POWER_Pos (12UL) /*!< Position of S12POWER field. */ +#define POWER_RAM_POWERSET_S12POWER_Msk (0x1UL << POWER_RAM_POWERSET_S12POWER_Pos) /*!< Bit mask of S12POWER field. */ +#define POWER_RAM_POWERSET_S12POWER_On (1UL) /*!< On */ + +/* Bit 11 : Keep RAM section S11 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S11POWER_Pos (11UL) /*!< Position of S11POWER field. */ +#define POWER_RAM_POWERSET_S11POWER_Msk (0x1UL << POWER_RAM_POWERSET_S11POWER_Pos) /*!< Bit mask of S11POWER field. */ +#define POWER_RAM_POWERSET_S11POWER_On (1UL) /*!< On */ + +/* Bit 10 : Keep RAM section S10 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S10POWER_Pos (10UL) /*!< Position of S10POWER field. */ +#define POWER_RAM_POWERSET_S10POWER_Msk (0x1UL << POWER_RAM_POWERSET_S10POWER_Pos) /*!< Bit mask of S10POWER field. */ +#define POWER_RAM_POWERSET_S10POWER_On (1UL) /*!< On */ + +/* Bit 9 : Keep RAM section S9 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S9POWER_Pos (9UL) /*!< Position of S9POWER field. */ +#define POWER_RAM_POWERSET_S9POWER_Msk (0x1UL << POWER_RAM_POWERSET_S9POWER_Pos) /*!< Bit mask of S9POWER field. */ +#define POWER_RAM_POWERSET_S9POWER_On (1UL) /*!< On */ + +/* Bit 8 : Keep RAM section S8 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S8POWER_Pos (8UL) /*!< Position of S8POWER field. */ +#define POWER_RAM_POWERSET_S8POWER_Msk (0x1UL << POWER_RAM_POWERSET_S8POWER_Pos) /*!< Bit mask of S8POWER field. */ +#define POWER_RAM_POWERSET_S8POWER_On (1UL) /*!< On */ + +/* Bit 7 : Keep RAM section S7 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S7POWER_Pos (7UL) /*!< Position of S7POWER field. */ +#define POWER_RAM_POWERSET_S7POWER_Msk (0x1UL << POWER_RAM_POWERSET_S7POWER_Pos) /*!< Bit mask of S7POWER field. */ +#define POWER_RAM_POWERSET_S7POWER_On (1UL) /*!< On */ + +/* Bit 6 : Keep RAM section S6 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S6POWER_Pos (6UL) /*!< Position of S6POWER field. */ +#define POWER_RAM_POWERSET_S6POWER_Msk (0x1UL << POWER_RAM_POWERSET_S6POWER_Pos) /*!< Bit mask of S6POWER field. */ +#define POWER_RAM_POWERSET_S6POWER_On (1UL) /*!< On */ + +/* Bit 5 : Keep RAM section S5 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S5POWER_Pos (5UL) /*!< Position of S5POWER field. */ +#define POWER_RAM_POWERSET_S5POWER_Msk (0x1UL << POWER_RAM_POWERSET_S5POWER_Pos) /*!< Bit mask of S5POWER field. */ +#define POWER_RAM_POWERSET_S5POWER_On (1UL) /*!< On */ + +/* Bit 4 : Keep RAM section S4 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S4POWER_Pos (4UL) /*!< Position of S4POWER field. */ +#define POWER_RAM_POWERSET_S4POWER_Msk (0x1UL << POWER_RAM_POWERSET_S4POWER_Pos) /*!< Bit mask of S4POWER field. */ +#define POWER_RAM_POWERSET_S4POWER_On (1UL) /*!< On */ + +/* Bit 3 : Keep RAM section S3 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S3POWER_Pos (3UL) /*!< Position of S3POWER field. */ +#define POWER_RAM_POWERSET_S3POWER_Msk (0x1UL << POWER_RAM_POWERSET_S3POWER_Pos) /*!< Bit mask of S3POWER field. */ +#define POWER_RAM_POWERSET_S3POWER_On (1UL) /*!< On */ + +/* Bit 2 : Keep RAM section S2 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S2POWER_Pos (2UL) /*!< Position of S2POWER field. */ +#define POWER_RAM_POWERSET_S2POWER_Msk (0x1UL << POWER_RAM_POWERSET_S2POWER_Pos) /*!< Bit mask of S2POWER field. */ +#define POWER_RAM_POWERSET_S2POWER_On (1UL) /*!< On */ + +/* Bit 1 : Keep RAM section S1 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ +#define POWER_RAM_POWERSET_S1POWER_Msk (0x1UL << POWER_RAM_POWERSET_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ +#define POWER_RAM_POWERSET_S1POWER_On (1UL) /*!< On */ + +/* Bit 0 : Keep RAM section S0 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERSET_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ +#define POWER_RAM_POWERSET_S0POWER_Msk (0x1UL << POWER_RAM_POWERSET_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ +#define POWER_RAM_POWERSET_S0POWER_On (1UL) /*!< On */ + +/* Register: POWER_RAM_POWERCLR */ +/* Description: Description cluster[0]: RAM0 power control clear register */ + +/* Bit 31 : Keep retention on RAM section S15 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S15RETENTION_Pos (31UL) /*!< Position of S15RETENTION field. */ +#define POWER_RAM_POWERCLR_S15RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S15RETENTION_Pos) /*!< Bit mask of S15RETENTION field. */ +#define POWER_RAM_POWERCLR_S15RETENTION_Off (1UL) /*!< Off */ + +/* Bit 30 : Keep retention on RAM section S14 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S14RETENTION_Pos (30UL) /*!< Position of S14RETENTION field. */ +#define POWER_RAM_POWERCLR_S14RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S14RETENTION_Pos) /*!< Bit mask of S14RETENTION field. */ +#define POWER_RAM_POWERCLR_S14RETENTION_Off (1UL) /*!< Off */ + +/* Bit 29 : Keep retention on RAM section S13 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S13RETENTION_Pos (29UL) /*!< Position of S13RETENTION field. */ +#define POWER_RAM_POWERCLR_S13RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S13RETENTION_Pos) /*!< Bit mask of S13RETENTION field. */ +#define POWER_RAM_POWERCLR_S13RETENTION_Off (1UL) /*!< Off */ + +/* Bit 28 : Keep retention on RAM section S12 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S12RETENTION_Pos (28UL) /*!< Position of S12RETENTION field. */ +#define POWER_RAM_POWERCLR_S12RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S12RETENTION_Pos) /*!< Bit mask of S12RETENTION field. */ +#define POWER_RAM_POWERCLR_S12RETENTION_Off (1UL) /*!< Off */ + +/* Bit 27 : Keep retention on RAM section S11 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S11RETENTION_Pos (27UL) /*!< Position of S11RETENTION field. */ +#define POWER_RAM_POWERCLR_S11RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S11RETENTION_Pos) /*!< Bit mask of S11RETENTION field. */ +#define POWER_RAM_POWERCLR_S11RETENTION_Off (1UL) /*!< Off */ + +/* Bit 26 : Keep retention on RAM section S10 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S10RETENTION_Pos (26UL) /*!< Position of S10RETENTION field. */ +#define POWER_RAM_POWERCLR_S10RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S10RETENTION_Pos) /*!< Bit mask of S10RETENTION field. */ +#define POWER_RAM_POWERCLR_S10RETENTION_Off (1UL) /*!< Off */ + +/* Bit 25 : Keep retention on RAM section S9 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S9RETENTION_Pos (25UL) /*!< Position of S9RETENTION field. */ +#define POWER_RAM_POWERCLR_S9RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S9RETENTION_Pos) /*!< Bit mask of S9RETENTION field. */ +#define POWER_RAM_POWERCLR_S9RETENTION_Off (1UL) /*!< Off */ + +/* Bit 24 : Keep retention on RAM section S8 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S8RETENTION_Pos (24UL) /*!< Position of S8RETENTION field. */ +#define POWER_RAM_POWERCLR_S8RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S8RETENTION_Pos) /*!< Bit mask of S8RETENTION field. */ +#define POWER_RAM_POWERCLR_S8RETENTION_Off (1UL) /*!< Off */ + +/* Bit 23 : Keep retention on RAM section S7 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S7RETENTION_Pos (23UL) /*!< Position of S7RETENTION field. */ +#define POWER_RAM_POWERCLR_S7RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S7RETENTION_Pos) /*!< Bit mask of S7RETENTION field. */ +#define POWER_RAM_POWERCLR_S7RETENTION_Off (1UL) /*!< Off */ + +/* Bit 22 : Keep retention on RAM section S6 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S6RETENTION_Pos (22UL) /*!< Position of S6RETENTION field. */ +#define POWER_RAM_POWERCLR_S6RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S6RETENTION_Pos) /*!< Bit mask of S6RETENTION field. */ +#define POWER_RAM_POWERCLR_S6RETENTION_Off (1UL) /*!< Off */ + +/* Bit 21 : Keep retention on RAM section S5 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S5RETENTION_Pos (21UL) /*!< Position of S5RETENTION field. */ +#define POWER_RAM_POWERCLR_S5RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S5RETENTION_Pos) /*!< Bit mask of S5RETENTION field. */ +#define POWER_RAM_POWERCLR_S5RETENTION_Off (1UL) /*!< Off */ + +/* Bit 20 : Keep retention on RAM section S4 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S4RETENTION_Pos (20UL) /*!< Position of S4RETENTION field. */ +#define POWER_RAM_POWERCLR_S4RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S4RETENTION_Pos) /*!< Bit mask of S4RETENTION field. */ +#define POWER_RAM_POWERCLR_S4RETENTION_Off (1UL) /*!< Off */ + +/* Bit 19 : Keep retention on RAM section S3 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S3RETENTION_Pos (19UL) /*!< Position of S3RETENTION field. */ +#define POWER_RAM_POWERCLR_S3RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S3RETENTION_Pos) /*!< Bit mask of S3RETENTION field. */ +#define POWER_RAM_POWERCLR_S3RETENTION_Off (1UL) /*!< Off */ + +/* Bit 18 : Keep retention on RAM section S2 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S2RETENTION_Pos (18UL) /*!< Position of S2RETENTION field. */ +#define POWER_RAM_POWERCLR_S2RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S2RETENTION_Pos) /*!< Bit mask of S2RETENTION field. */ +#define POWER_RAM_POWERCLR_S2RETENTION_Off (1UL) /*!< Off */ + +/* Bit 17 : Keep retention on RAM section S1 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S1RETENTION_Pos (17UL) /*!< Position of S1RETENTION field. */ +#define POWER_RAM_POWERCLR_S1RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S1RETENTION_Pos) /*!< Bit mask of S1RETENTION field. */ +#define POWER_RAM_POWERCLR_S1RETENTION_Off (1UL) /*!< Off */ + +/* Bit 16 : Keep retention on RAM section S0 when RAM section is switched off */ +#define POWER_RAM_POWERCLR_S0RETENTION_Pos (16UL) /*!< Position of S0RETENTION field. */ +#define POWER_RAM_POWERCLR_S0RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ +#define POWER_RAM_POWERCLR_S0RETENTION_Off (1UL) /*!< Off */ + +/* Bit 15 : Keep RAM section S15 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S15POWER_Pos (15UL) /*!< Position of S15POWER field. */ +#define POWER_RAM_POWERCLR_S15POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S15POWER_Pos) /*!< Bit mask of S15POWER field. */ +#define POWER_RAM_POWERCLR_S15POWER_Off (1UL) /*!< Off */ + +/* Bit 14 : Keep RAM section S14 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S14POWER_Pos (14UL) /*!< Position of S14POWER field. */ +#define POWER_RAM_POWERCLR_S14POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S14POWER_Pos) /*!< Bit mask of S14POWER field. */ +#define POWER_RAM_POWERCLR_S14POWER_Off (1UL) /*!< Off */ + +/* Bit 13 : Keep RAM section S13 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S13POWER_Pos (13UL) /*!< Position of S13POWER field. */ +#define POWER_RAM_POWERCLR_S13POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S13POWER_Pos) /*!< Bit mask of S13POWER field. */ +#define POWER_RAM_POWERCLR_S13POWER_Off (1UL) /*!< Off */ + +/* Bit 12 : Keep RAM section S12 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S12POWER_Pos (12UL) /*!< Position of S12POWER field. */ +#define POWER_RAM_POWERCLR_S12POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S12POWER_Pos) /*!< Bit mask of S12POWER field. */ +#define POWER_RAM_POWERCLR_S12POWER_Off (1UL) /*!< Off */ + +/* Bit 11 : Keep RAM section S11 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S11POWER_Pos (11UL) /*!< Position of S11POWER field. */ +#define POWER_RAM_POWERCLR_S11POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S11POWER_Pos) /*!< Bit mask of S11POWER field. */ +#define POWER_RAM_POWERCLR_S11POWER_Off (1UL) /*!< Off */ + +/* Bit 10 : Keep RAM section S10 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S10POWER_Pos (10UL) /*!< Position of S10POWER field. */ +#define POWER_RAM_POWERCLR_S10POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S10POWER_Pos) /*!< Bit mask of S10POWER field. */ +#define POWER_RAM_POWERCLR_S10POWER_Off (1UL) /*!< Off */ + +/* Bit 9 : Keep RAM section S9 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S9POWER_Pos (9UL) /*!< Position of S9POWER field. */ +#define POWER_RAM_POWERCLR_S9POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S9POWER_Pos) /*!< Bit mask of S9POWER field. */ +#define POWER_RAM_POWERCLR_S9POWER_Off (1UL) /*!< Off */ + +/* Bit 8 : Keep RAM section S8 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S8POWER_Pos (8UL) /*!< Position of S8POWER field. */ +#define POWER_RAM_POWERCLR_S8POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S8POWER_Pos) /*!< Bit mask of S8POWER field. */ +#define POWER_RAM_POWERCLR_S8POWER_Off (1UL) /*!< Off */ + +/* Bit 7 : Keep RAM section S7 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S7POWER_Pos (7UL) /*!< Position of S7POWER field. */ +#define POWER_RAM_POWERCLR_S7POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S7POWER_Pos) /*!< Bit mask of S7POWER field. */ +#define POWER_RAM_POWERCLR_S7POWER_Off (1UL) /*!< Off */ + +/* Bit 6 : Keep RAM section S6 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S6POWER_Pos (6UL) /*!< Position of S6POWER field. */ +#define POWER_RAM_POWERCLR_S6POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S6POWER_Pos) /*!< Bit mask of S6POWER field. */ +#define POWER_RAM_POWERCLR_S6POWER_Off (1UL) /*!< Off */ + +/* Bit 5 : Keep RAM section S5 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S5POWER_Pos (5UL) /*!< Position of S5POWER field. */ +#define POWER_RAM_POWERCLR_S5POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S5POWER_Pos) /*!< Bit mask of S5POWER field. */ +#define POWER_RAM_POWERCLR_S5POWER_Off (1UL) /*!< Off */ + +/* Bit 4 : Keep RAM section S4 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S4POWER_Pos (4UL) /*!< Position of S4POWER field. */ +#define POWER_RAM_POWERCLR_S4POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S4POWER_Pos) /*!< Bit mask of S4POWER field. */ +#define POWER_RAM_POWERCLR_S4POWER_Off (1UL) /*!< Off */ + +/* Bit 3 : Keep RAM section S3 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S3POWER_Pos (3UL) /*!< Position of S3POWER field. */ +#define POWER_RAM_POWERCLR_S3POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S3POWER_Pos) /*!< Bit mask of S3POWER field. */ +#define POWER_RAM_POWERCLR_S3POWER_Off (1UL) /*!< Off */ + +/* Bit 2 : Keep RAM section S2 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S2POWER_Pos (2UL) /*!< Position of S2POWER field. */ +#define POWER_RAM_POWERCLR_S2POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S2POWER_Pos) /*!< Bit mask of S2POWER field. */ +#define POWER_RAM_POWERCLR_S2POWER_Off (1UL) /*!< Off */ + +/* Bit 1 : Keep RAM section S1 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ +#define POWER_RAM_POWERCLR_S1POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ +#define POWER_RAM_POWERCLR_S1POWER_Off (1UL) /*!< Off */ + +/* Bit 0 : Keep RAM section S0 of RAM0 on or off in System ON mode */ +#define POWER_RAM_POWERCLR_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ +#define POWER_RAM_POWERCLR_S0POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ +#define POWER_RAM_POWERCLR_S0POWER_Off (1UL) /*!< Off */ + + +/* Peripheral: PPI */ +/* Description: Programmable Peripheral Interconnect */ + +/* Register: PPI_CHEN */ +/* Description: Channel enable register */ + +/* Bit 31 : Enable or disable channel 31 */ +#define PPI_CHEN_CH31_Pos (31UL) /*!< Position of CH31 field. */ +#define PPI_CHEN_CH31_Msk (0x1UL << PPI_CHEN_CH31_Pos) /*!< Bit mask of CH31 field. */ +#define PPI_CHEN_CH31_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH31_Enabled (1UL) /*!< Enable channel */ + +/* Bit 30 : Enable or disable channel 30 */ +#define PPI_CHEN_CH30_Pos (30UL) /*!< Position of CH30 field. */ +#define PPI_CHEN_CH30_Msk (0x1UL << PPI_CHEN_CH30_Pos) /*!< Bit mask of CH30 field. */ +#define PPI_CHEN_CH30_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH30_Enabled (1UL) /*!< Enable channel */ + +/* Bit 29 : Enable or disable channel 29 */ +#define PPI_CHEN_CH29_Pos (29UL) /*!< Position of CH29 field. */ +#define PPI_CHEN_CH29_Msk (0x1UL << PPI_CHEN_CH29_Pos) /*!< Bit mask of CH29 field. */ +#define PPI_CHEN_CH29_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH29_Enabled (1UL) /*!< Enable channel */ + +/* Bit 28 : Enable or disable channel 28 */ +#define PPI_CHEN_CH28_Pos (28UL) /*!< Position of CH28 field. */ +#define PPI_CHEN_CH28_Msk (0x1UL << PPI_CHEN_CH28_Pos) /*!< Bit mask of CH28 field. */ +#define PPI_CHEN_CH28_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH28_Enabled (1UL) /*!< Enable channel */ + +/* Bit 27 : Enable or disable channel 27 */ +#define PPI_CHEN_CH27_Pos (27UL) /*!< Position of CH27 field. */ +#define PPI_CHEN_CH27_Msk (0x1UL << PPI_CHEN_CH27_Pos) /*!< Bit mask of CH27 field. */ +#define PPI_CHEN_CH27_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH27_Enabled (1UL) /*!< Enable channel */ + +/* Bit 26 : Enable or disable channel 26 */ +#define PPI_CHEN_CH26_Pos (26UL) /*!< Position of CH26 field. */ +#define PPI_CHEN_CH26_Msk (0x1UL << PPI_CHEN_CH26_Pos) /*!< Bit mask of CH26 field. */ +#define PPI_CHEN_CH26_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH26_Enabled (1UL) /*!< Enable channel */ + +/* Bit 25 : Enable or disable channel 25 */ +#define PPI_CHEN_CH25_Pos (25UL) /*!< Position of CH25 field. */ +#define PPI_CHEN_CH25_Msk (0x1UL << PPI_CHEN_CH25_Pos) /*!< Bit mask of CH25 field. */ +#define PPI_CHEN_CH25_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH25_Enabled (1UL) /*!< Enable channel */ + +/* Bit 24 : Enable or disable channel 24 */ +#define PPI_CHEN_CH24_Pos (24UL) /*!< Position of CH24 field. */ +#define PPI_CHEN_CH24_Msk (0x1UL << PPI_CHEN_CH24_Pos) /*!< Bit mask of CH24 field. */ +#define PPI_CHEN_CH24_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH24_Enabled (1UL) /*!< Enable channel */ + +/* Bit 23 : Enable or disable channel 23 */ +#define PPI_CHEN_CH23_Pos (23UL) /*!< Position of CH23 field. */ +#define PPI_CHEN_CH23_Msk (0x1UL << PPI_CHEN_CH23_Pos) /*!< Bit mask of CH23 field. */ +#define PPI_CHEN_CH23_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH23_Enabled (1UL) /*!< Enable channel */ + +/* Bit 22 : Enable or disable channel 22 */ +#define PPI_CHEN_CH22_Pos (22UL) /*!< Position of CH22 field. */ +#define PPI_CHEN_CH22_Msk (0x1UL << PPI_CHEN_CH22_Pos) /*!< Bit mask of CH22 field. */ +#define PPI_CHEN_CH22_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH22_Enabled (1UL) /*!< Enable channel */ + +/* Bit 21 : Enable or disable channel 21 */ +#define PPI_CHEN_CH21_Pos (21UL) /*!< Position of CH21 field. */ +#define PPI_CHEN_CH21_Msk (0x1UL << PPI_CHEN_CH21_Pos) /*!< Bit mask of CH21 field. */ +#define PPI_CHEN_CH21_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH21_Enabled (1UL) /*!< Enable channel */ + +/* Bit 20 : Enable or disable channel 20 */ +#define PPI_CHEN_CH20_Pos (20UL) /*!< Position of CH20 field. */ +#define PPI_CHEN_CH20_Msk (0x1UL << PPI_CHEN_CH20_Pos) /*!< Bit mask of CH20 field. */ +#define PPI_CHEN_CH20_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH20_Enabled (1UL) /*!< Enable channel */ + +/* Bit 19 : Enable or disable channel 19 */ +#define PPI_CHEN_CH19_Pos (19UL) /*!< Position of CH19 field. */ +#define PPI_CHEN_CH19_Msk (0x1UL << PPI_CHEN_CH19_Pos) /*!< Bit mask of CH19 field. */ +#define PPI_CHEN_CH19_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH19_Enabled (1UL) /*!< Enable channel */ + +/* Bit 18 : Enable or disable channel 18 */ +#define PPI_CHEN_CH18_Pos (18UL) /*!< Position of CH18 field. */ +#define PPI_CHEN_CH18_Msk (0x1UL << PPI_CHEN_CH18_Pos) /*!< Bit mask of CH18 field. */ +#define PPI_CHEN_CH18_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH18_Enabled (1UL) /*!< Enable channel */ + +/* Bit 17 : Enable or disable channel 17 */ +#define PPI_CHEN_CH17_Pos (17UL) /*!< Position of CH17 field. */ +#define PPI_CHEN_CH17_Msk (0x1UL << PPI_CHEN_CH17_Pos) /*!< Bit mask of CH17 field. */ +#define PPI_CHEN_CH17_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH17_Enabled (1UL) /*!< Enable channel */ + +/* Bit 16 : Enable or disable channel 16 */ +#define PPI_CHEN_CH16_Pos (16UL) /*!< Position of CH16 field. */ +#define PPI_CHEN_CH16_Msk (0x1UL << PPI_CHEN_CH16_Pos) /*!< Bit mask of CH16 field. */ +#define PPI_CHEN_CH16_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH16_Enabled (1UL) /*!< Enable channel */ + +/* Bit 15 : Enable or disable channel 15 */ +#define PPI_CHEN_CH15_Pos (15UL) /*!< Position of CH15 field. */ +#define PPI_CHEN_CH15_Msk (0x1UL << PPI_CHEN_CH15_Pos) /*!< Bit mask of CH15 field. */ +#define PPI_CHEN_CH15_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH15_Enabled (1UL) /*!< Enable channel */ + +/* Bit 14 : Enable or disable channel 14 */ +#define PPI_CHEN_CH14_Pos (14UL) /*!< Position of CH14 field. */ +#define PPI_CHEN_CH14_Msk (0x1UL << PPI_CHEN_CH14_Pos) /*!< Bit mask of CH14 field. */ +#define PPI_CHEN_CH14_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH14_Enabled (1UL) /*!< Enable channel */ + +/* Bit 13 : Enable or disable channel 13 */ +#define PPI_CHEN_CH13_Pos (13UL) /*!< Position of CH13 field. */ +#define PPI_CHEN_CH13_Msk (0x1UL << PPI_CHEN_CH13_Pos) /*!< Bit mask of CH13 field. */ +#define PPI_CHEN_CH13_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH13_Enabled (1UL) /*!< Enable channel */ + +/* Bit 12 : Enable or disable channel 12 */ +#define PPI_CHEN_CH12_Pos (12UL) /*!< Position of CH12 field. */ +#define PPI_CHEN_CH12_Msk (0x1UL << PPI_CHEN_CH12_Pos) /*!< Bit mask of CH12 field. */ +#define PPI_CHEN_CH12_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH12_Enabled (1UL) /*!< Enable channel */ + +/* Bit 11 : Enable or disable channel 11 */ +#define PPI_CHEN_CH11_Pos (11UL) /*!< Position of CH11 field. */ +#define PPI_CHEN_CH11_Msk (0x1UL << PPI_CHEN_CH11_Pos) /*!< Bit mask of CH11 field. */ +#define PPI_CHEN_CH11_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH11_Enabled (1UL) /*!< Enable channel */ + +/* Bit 10 : Enable or disable channel 10 */ +#define PPI_CHEN_CH10_Pos (10UL) /*!< Position of CH10 field. */ +#define PPI_CHEN_CH10_Msk (0x1UL << PPI_CHEN_CH10_Pos) /*!< Bit mask of CH10 field. */ +#define PPI_CHEN_CH10_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH10_Enabled (1UL) /*!< Enable channel */ + +/* Bit 9 : Enable or disable channel 9 */ +#define PPI_CHEN_CH9_Pos (9UL) /*!< Position of CH9 field. */ +#define PPI_CHEN_CH9_Msk (0x1UL << PPI_CHEN_CH9_Pos) /*!< Bit mask of CH9 field. */ +#define PPI_CHEN_CH9_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH9_Enabled (1UL) /*!< Enable channel */ + +/* Bit 8 : Enable or disable channel 8 */ +#define PPI_CHEN_CH8_Pos (8UL) /*!< Position of CH8 field. */ +#define PPI_CHEN_CH8_Msk (0x1UL << PPI_CHEN_CH8_Pos) /*!< Bit mask of CH8 field. */ +#define PPI_CHEN_CH8_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH8_Enabled (1UL) /*!< Enable channel */ + +/* Bit 7 : Enable or disable channel 7 */ +#define PPI_CHEN_CH7_Pos (7UL) /*!< Position of CH7 field. */ +#define PPI_CHEN_CH7_Msk (0x1UL << PPI_CHEN_CH7_Pos) /*!< Bit mask of CH7 field. */ +#define PPI_CHEN_CH7_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH7_Enabled (1UL) /*!< Enable channel */ + +/* Bit 6 : Enable or disable channel 6 */ +#define PPI_CHEN_CH6_Pos (6UL) /*!< Position of CH6 field. */ +#define PPI_CHEN_CH6_Msk (0x1UL << PPI_CHEN_CH6_Pos) /*!< Bit mask of CH6 field. */ +#define PPI_CHEN_CH6_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH6_Enabled (1UL) /*!< Enable channel */ + +/* Bit 5 : Enable or disable channel 5 */ +#define PPI_CHEN_CH5_Pos (5UL) /*!< Position of CH5 field. */ +#define PPI_CHEN_CH5_Msk (0x1UL << PPI_CHEN_CH5_Pos) /*!< Bit mask of CH5 field. */ +#define PPI_CHEN_CH5_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH5_Enabled (1UL) /*!< Enable channel */ + +/* Bit 4 : Enable or disable channel 4 */ +#define PPI_CHEN_CH4_Pos (4UL) /*!< Position of CH4 field. */ +#define PPI_CHEN_CH4_Msk (0x1UL << PPI_CHEN_CH4_Pos) /*!< Bit mask of CH4 field. */ +#define PPI_CHEN_CH4_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH4_Enabled (1UL) /*!< Enable channel */ + +/* Bit 3 : Enable or disable channel 3 */ +#define PPI_CHEN_CH3_Pos (3UL) /*!< Position of CH3 field. */ +#define PPI_CHEN_CH3_Msk (0x1UL << PPI_CHEN_CH3_Pos) /*!< Bit mask of CH3 field. */ +#define PPI_CHEN_CH3_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH3_Enabled (1UL) /*!< Enable channel */ + +/* Bit 2 : Enable or disable channel 2 */ +#define PPI_CHEN_CH2_Pos (2UL) /*!< Position of CH2 field. */ +#define PPI_CHEN_CH2_Msk (0x1UL << PPI_CHEN_CH2_Pos) /*!< Bit mask of CH2 field. */ +#define PPI_CHEN_CH2_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH2_Enabled (1UL) /*!< Enable channel */ + +/* Bit 1 : Enable or disable channel 1 */ +#define PPI_CHEN_CH1_Pos (1UL) /*!< Position of CH1 field. */ +#define PPI_CHEN_CH1_Msk (0x1UL << PPI_CHEN_CH1_Pos) /*!< Bit mask of CH1 field. */ +#define PPI_CHEN_CH1_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH1_Enabled (1UL) /*!< Enable channel */ + +/* Bit 0 : Enable or disable channel 0 */ +#define PPI_CHEN_CH0_Pos (0UL) /*!< Position of CH0 field. */ +#define PPI_CHEN_CH0_Msk (0x1UL << PPI_CHEN_CH0_Pos) /*!< Bit mask of CH0 field. */ +#define PPI_CHEN_CH0_Disabled (0UL) /*!< Disable channel */ +#define PPI_CHEN_CH0_Enabled (1UL) /*!< Enable channel */ + +/* Register: PPI_CHENSET */ +/* Description: Channel enable set register */ + +/* Bit 31 : Channel 31 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH31_Pos (31UL) /*!< Position of CH31 field. */ +#define PPI_CHENSET_CH31_Msk (0x1UL << PPI_CHENSET_CH31_Pos) /*!< Bit mask of CH31 field. */ +#define PPI_CHENSET_CH31_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH31_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH31_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 30 : Channel 30 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH30_Pos (30UL) /*!< Position of CH30 field. */ +#define PPI_CHENSET_CH30_Msk (0x1UL << PPI_CHENSET_CH30_Pos) /*!< Bit mask of CH30 field. */ +#define PPI_CHENSET_CH30_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH30_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH30_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 29 : Channel 29 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH29_Pos (29UL) /*!< Position of CH29 field. */ +#define PPI_CHENSET_CH29_Msk (0x1UL << PPI_CHENSET_CH29_Pos) /*!< Bit mask of CH29 field. */ +#define PPI_CHENSET_CH29_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH29_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH29_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 28 : Channel 28 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH28_Pos (28UL) /*!< Position of CH28 field. */ +#define PPI_CHENSET_CH28_Msk (0x1UL << PPI_CHENSET_CH28_Pos) /*!< Bit mask of CH28 field. */ +#define PPI_CHENSET_CH28_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH28_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH28_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 27 : Channel 27 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH27_Pos (27UL) /*!< Position of CH27 field. */ +#define PPI_CHENSET_CH27_Msk (0x1UL << PPI_CHENSET_CH27_Pos) /*!< Bit mask of CH27 field. */ +#define PPI_CHENSET_CH27_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH27_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH27_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 26 : Channel 26 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH26_Pos (26UL) /*!< Position of CH26 field. */ +#define PPI_CHENSET_CH26_Msk (0x1UL << PPI_CHENSET_CH26_Pos) /*!< Bit mask of CH26 field. */ +#define PPI_CHENSET_CH26_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH26_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH26_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 25 : Channel 25 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH25_Pos (25UL) /*!< Position of CH25 field. */ +#define PPI_CHENSET_CH25_Msk (0x1UL << PPI_CHENSET_CH25_Pos) /*!< Bit mask of CH25 field. */ +#define PPI_CHENSET_CH25_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH25_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH25_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 24 : Channel 24 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH24_Pos (24UL) /*!< Position of CH24 field. */ +#define PPI_CHENSET_CH24_Msk (0x1UL << PPI_CHENSET_CH24_Pos) /*!< Bit mask of CH24 field. */ +#define PPI_CHENSET_CH24_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH24_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH24_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 23 : Channel 23 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH23_Pos (23UL) /*!< Position of CH23 field. */ +#define PPI_CHENSET_CH23_Msk (0x1UL << PPI_CHENSET_CH23_Pos) /*!< Bit mask of CH23 field. */ +#define PPI_CHENSET_CH23_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH23_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH23_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 22 : Channel 22 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH22_Pos (22UL) /*!< Position of CH22 field. */ +#define PPI_CHENSET_CH22_Msk (0x1UL << PPI_CHENSET_CH22_Pos) /*!< Bit mask of CH22 field. */ +#define PPI_CHENSET_CH22_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH22_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH22_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 21 : Channel 21 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH21_Pos (21UL) /*!< Position of CH21 field. */ +#define PPI_CHENSET_CH21_Msk (0x1UL << PPI_CHENSET_CH21_Pos) /*!< Bit mask of CH21 field. */ +#define PPI_CHENSET_CH21_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH21_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH21_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 20 : Channel 20 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH20_Pos (20UL) /*!< Position of CH20 field. */ +#define PPI_CHENSET_CH20_Msk (0x1UL << PPI_CHENSET_CH20_Pos) /*!< Bit mask of CH20 field. */ +#define PPI_CHENSET_CH20_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH20_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH20_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 19 : Channel 19 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH19_Pos (19UL) /*!< Position of CH19 field. */ +#define PPI_CHENSET_CH19_Msk (0x1UL << PPI_CHENSET_CH19_Pos) /*!< Bit mask of CH19 field. */ +#define PPI_CHENSET_CH19_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH19_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH19_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 18 : Channel 18 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH18_Pos (18UL) /*!< Position of CH18 field. */ +#define PPI_CHENSET_CH18_Msk (0x1UL << PPI_CHENSET_CH18_Pos) /*!< Bit mask of CH18 field. */ +#define PPI_CHENSET_CH18_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH18_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH18_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 17 : Channel 17 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH17_Pos (17UL) /*!< Position of CH17 field. */ +#define PPI_CHENSET_CH17_Msk (0x1UL << PPI_CHENSET_CH17_Pos) /*!< Bit mask of CH17 field. */ +#define PPI_CHENSET_CH17_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH17_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH17_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 16 : Channel 16 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH16_Pos (16UL) /*!< Position of CH16 field. */ +#define PPI_CHENSET_CH16_Msk (0x1UL << PPI_CHENSET_CH16_Pos) /*!< Bit mask of CH16 field. */ +#define PPI_CHENSET_CH16_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH16_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH16_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 15 : Channel 15 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH15_Pos (15UL) /*!< Position of CH15 field. */ +#define PPI_CHENSET_CH15_Msk (0x1UL << PPI_CHENSET_CH15_Pos) /*!< Bit mask of CH15 field. */ +#define PPI_CHENSET_CH15_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH15_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH15_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 14 : Channel 14 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH14_Pos (14UL) /*!< Position of CH14 field. */ +#define PPI_CHENSET_CH14_Msk (0x1UL << PPI_CHENSET_CH14_Pos) /*!< Bit mask of CH14 field. */ +#define PPI_CHENSET_CH14_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH14_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH14_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 13 : Channel 13 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH13_Pos (13UL) /*!< Position of CH13 field. */ +#define PPI_CHENSET_CH13_Msk (0x1UL << PPI_CHENSET_CH13_Pos) /*!< Bit mask of CH13 field. */ +#define PPI_CHENSET_CH13_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH13_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH13_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 12 : Channel 12 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH12_Pos (12UL) /*!< Position of CH12 field. */ +#define PPI_CHENSET_CH12_Msk (0x1UL << PPI_CHENSET_CH12_Pos) /*!< Bit mask of CH12 field. */ +#define PPI_CHENSET_CH12_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH12_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH12_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 11 : Channel 11 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH11_Pos (11UL) /*!< Position of CH11 field. */ +#define PPI_CHENSET_CH11_Msk (0x1UL << PPI_CHENSET_CH11_Pos) /*!< Bit mask of CH11 field. */ +#define PPI_CHENSET_CH11_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH11_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH11_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 10 : Channel 10 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH10_Pos (10UL) /*!< Position of CH10 field. */ +#define PPI_CHENSET_CH10_Msk (0x1UL << PPI_CHENSET_CH10_Pos) /*!< Bit mask of CH10 field. */ +#define PPI_CHENSET_CH10_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH10_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH10_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 9 : Channel 9 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH9_Pos (9UL) /*!< Position of CH9 field. */ +#define PPI_CHENSET_CH9_Msk (0x1UL << PPI_CHENSET_CH9_Pos) /*!< Bit mask of CH9 field. */ +#define PPI_CHENSET_CH9_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH9_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH9_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 8 : Channel 8 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH8_Pos (8UL) /*!< Position of CH8 field. */ +#define PPI_CHENSET_CH8_Msk (0x1UL << PPI_CHENSET_CH8_Pos) /*!< Bit mask of CH8 field. */ +#define PPI_CHENSET_CH8_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH8_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH8_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 7 : Channel 7 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH7_Pos (7UL) /*!< Position of CH7 field. */ +#define PPI_CHENSET_CH7_Msk (0x1UL << PPI_CHENSET_CH7_Pos) /*!< Bit mask of CH7 field. */ +#define PPI_CHENSET_CH7_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH7_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH7_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 6 : Channel 6 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH6_Pos (6UL) /*!< Position of CH6 field. */ +#define PPI_CHENSET_CH6_Msk (0x1UL << PPI_CHENSET_CH6_Pos) /*!< Bit mask of CH6 field. */ +#define PPI_CHENSET_CH6_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH6_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH6_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 5 : Channel 5 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH5_Pos (5UL) /*!< Position of CH5 field. */ +#define PPI_CHENSET_CH5_Msk (0x1UL << PPI_CHENSET_CH5_Pos) /*!< Bit mask of CH5 field. */ +#define PPI_CHENSET_CH5_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH5_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH5_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 4 : Channel 4 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH4_Pos (4UL) /*!< Position of CH4 field. */ +#define PPI_CHENSET_CH4_Msk (0x1UL << PPI_CHENSET_CH4_Pos) /*!< Bit mask of CH4 field. */ +#define PPI_CHENSET_CH4_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH4_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH4_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 3 : Channel 3 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH3_Pos (3UL) /*!< Position of CH3 field. */ +#define PPI_CHENSET_CH3_Msk (0x1UL << PPI_CHENSET_CH3_Pos) /*!< Bit mask of CH3 field. */ +#define PPI_CHENSET_CH3_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH3_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH3_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 2 : Channel 2 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH2_Pos (2UL) /*!< Position of CH2 field. */ +#define PPI_CHENSET_CH2_Msk (0x1UL << PPI_CHENSET_CH2_Pos) /*!< Bit mask of CH2 field. */ +#define PPI_CHENSET_CH2_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH2_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH2_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 1 : Channel 1 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH1_Pos (1UL) /*!< Position of CH1 field. */ +#define PPI_CHENSET_CH1_Msk (0x1UL << PPI_CHENSET_CH1_Pos) /*!< Bit mask of CH1 field. */ +#define PPI_CHENSET_CH1_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH1_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH1_Set (1UL) /*!< Write: Enable channel */ + +/* Bit 0 : Channel 0 enable set register. Writing '0' has no effect */ +#define PPI_CHENSET_CH0_Pos (0UL) /*!< Position of CH0 field. */ +#define PPI_CHENSET_CH0_Msk (0x1UL << PPI_CHENSET_CH0_Pos) /*!< Bit mask of CH0 field. */ +#define PPI_CHENSET_CH0_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENSET_CH0_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENSET_CH0_Set (1UL) /*!< Write: Enable channel */ + +/* Register: PPI_CHENCLR */ +/* Description: Channel enable clear register */ + +/* Bit 31 : Channel 31 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH31_Pos (31UL) /*!< Position of CH31 field. */ +#define PPI_CHENCLR_CH31_Msk (0x1UL << PPI_CHENCLR_CH31_Pos) /*!< Bit mask of CH31 field. */ +#define PPI_CHENCLR_CH31_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH31_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH31_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 30 : Channel 30 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH30_Pos (30UL) /*!< Position of CH30 field. */ +#define PPI_CHENCLR_CH30_Msk (0x1UL << PPI_CHENCLR_CH30_Pos) /*!< Bit mask of CH30 field. */ +#define PPI_CHENCLR_CH30_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH30_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH30_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 29 : Channel 29 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH29_Pos (29UL) /*!< Position of CH29 field. */ +#define PPI_CHENCLR_CH29_Msk (0x1UL << PPI_CHENCLR_CH29_Pos) /*!< Bit mask of CH29 field. */ +#define PPI_CHENCLR_CH29_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH29_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH29_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 28 : Channel 28 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH28_Pos (28UL) /*!< Position of CH28 field. */ +#define PPI_CHENCLR_CH28_Msk (0x1UL << PPI_CHENCLR_CH28_Pos) /*!< Bit mask of CH28 field. */ +#define PPI_CHENCLR_CH28_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH28_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH28_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 27 : Channel 27 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH27_Pos (27UL) /*!< Position of CH27 field. */ +#define PPI_CHENCLR_CH27_Msk (0x1UL << PPI_CHENCLR_CH27_Pos) /*!< Bit mask of CH27 field. */ +#define PPI_CHENCLR_CH27_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH27_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH27_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 26 : Channel 26 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH26_Pos (26UL) /*!< Position of CH26 field. */ +#define PPI_CHENCLR_CH26_Msk (0x1UL << PPI_CHENCLR_CH26_Pos) /*!< Bit mask of CH26 field. */ +#define PPI_CHENCLR_CH26_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH26_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH26_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 25 : Channel 25 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH25_Pos (25UL) /*!< Position of CH25 field. */ +#define PPI_CHENCLR_CH25_Msk (0x1UL << PPI_CHENCLR_CH25_Pos) /*!< Bit mask of CH25 field. */ +#define PPI_CHENCLR_CH25_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH25_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH25_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 24 : Channel 24 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH24_Pos (24UL) /*!< Position of CH24 field. */ +#define PPI_CHENCLR_CH24_Msk (0x1UL << PPI_CHENCLR_CH24_Pos) /*!< Bit mask of CH24 field. */ +#define PPI_CHENCLR_CH24_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH24_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH24_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 23 : Channel 23 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH23_Pos (23UL) /*!< Position of CH23 field. */ +#define PPI_CHENCLR_CH23_Msk (0x1UL << PPI_CHENCLR_CH23_Pos) /*!< Bit mask of CH23 field. */ +#define PPI_CHENCLR_CH23_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH23_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH23_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 22 : Channel 22 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH22_Pos (22UL) /*!< Position of CH22 field. */ +#define PPI_CHENCLR_CH22_Msk (0x1UL << PPI_CHENCLR_CH22_Pos) /*!< Bit mask of CH22 field. */ +#define PPI_CHENCLR_CH22_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH22_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH22_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 21 : Channel 21 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH21_Pos (21UL) /*!< Position of CH21 field. */ +#define PPI_CHENCLR_CH21_Msk (0x1UL << PPI_CHENCLR_CH21_Pos) /*!< Bit mask of CH21 field. */ +#define PPI_CHENCLR_CH21_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH21_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH21_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 20 : Channel 20 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH20_Pos (20UL) /*!< Position of CH20 field. */ +#define PPI_CHENCLR_CH20_Msk (0x1UL << PPI_CHENCLR_CH20_Pos) /*!< Bit mask of CH20 field. */ +#define PPI_CHENCLR_CH20_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH20_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH20_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 19 : Channel 19 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH19_Pos (19UL) /*!< Position of CH19 field. */ +#define PPI_CHENCLR_CH19_Msk (0x1UL << PPI_CHENCLR_CH19_Pos) /*!< Bit mask of CH19 field. */ +#define PPI_CHENCLR_CH19_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH19_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH19_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 18 : Channel 18 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH18_Pos (18UL) /*!< Position of CH18 field. */ +#define PPI_CHENCLR_CH18_Msk (0x1UL << PPI_CHENCLR_CH18_Pos) /*!< Bit mask of CH18 field. */ +#define PPI_CHENCLR_CH18_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH18_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH18_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 17 : Channel 17 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH17_Pos (17UL) /*!< Position of CH17 field. */ +#define PPI_CHENCLR_CH17_Msk (0x1UL << PPI_CHENCLR_CH17_Pos) /*!< Bit mask of CH17 field. */ +#define PPI_CHENCLR_CH17_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH17_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH17_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 16 : Channel 16 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH16_Pos (16UL) /*!< Position of CH16 field. */ +#define PPI_CHENCLR_CH16_Msk (0x1UL << PPI_CHENCLR_CH16_Pos) /*!< Bit mask of CH16 field. */ +#define PPI_CHENCLR_CH16_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH16_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH16_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 15 : Channel 15 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH15_Pos (15UL) /*!< Position of CH15 field. */ +#define PPI_CHENCLR_CH15_Msk (0x1UL << PPI_CHENCLR_CH15_Pos) /*!< Bit mask of CH15 field. */ +#define PPI_CHENCLR_CH15_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH15_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH15_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 14 : Channel 14 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH14_Pos (14UL) /*!< Position of CH14 field. */ +#define PPI_CHENCLR_CH14_Msk (0x1UL << PPI_CHENCLR_CH14_Pos) /*!< Bit mask of CH14 field. */ +#define PPI_CHENCLR_CH14_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH14_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH14_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 13 : Channel 13 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH13_Pos (13UL) /*!< Position of CH13 field. */ +#define PPI_CHENCLR_CH13_Msk (0x1UL << PPI_CHENCLR_CH13_Pos) /*!< Bit mask of CH13 field. */ +#define PPI_CHENCLR_CH13_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH13_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH13_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 12 : Channel 12 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH12_Pos (12UL) /*!< Position of CH12 field. */ +#define PPI_CHENCLR_CH12_Msk (0x1UL << PPI_CHENCLR_CH12_Pos) /*!< Bit mask of CH12 field. */ +#define PPI_CHENCLR_CH12_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH12_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH12_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 11 : Channel 11 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH11_Pos (11UL) /*!< Position of CH11 field. */ +#define PPI_CHENCLR_CH11_Msk (0x1UL << PPI_CHENCLR_CH11_Pos) /*!< Bit mask of CH11 field. */ +#define PPI_CHENCLR_CH11_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH11_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH11_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 10 : Channel 10 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH10_Pos (10UL) /*!< Position of CH10 field. */ +#define PPI_CHENCLR_CH10_Msk (0x1UL << PPI_CHENCLR_CH10_Pos) /*!< Bit mask of CH10 field. */ +#define PPI_CHENCLR_CH10_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH10_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH10_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 9 : Channel 9 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH9_Pos (9UL) /*!< Position of CH9 field. */ +#define PPI_CHENCLR_CH9_Msk (0x1UL << PPI_CHENCLR_CH9_Pos) /*!< Bit mask of CH9 field. */ +#define PPI_CHENCLR_CH9_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH9_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH9_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 8 : Channel 8 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH8_Pos (8UL) /*!< Position of CH8 field. */ +#define PPI_CHENCLR_CH8_Msk (0x1UL << PPI_CHENCLR_CH8_Pos) /*!< Bit mask of CH8 field. */ +#define PPI_CHENCLR_CH8_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH8_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH8_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 7 : Channel 7 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH7_Pos (7UL) /*!< Position of CH7 field. */ +#define PPI_CHENCLR_CH7_Msk (0x1UL << PPI_CHENCLR_CH7_Pos) /*!< Bit mask of CH7 field. */ +#define PPI_CHENCLR_CH7_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH7_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH7_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 6 : Channel 6 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH6_Pos (6UL) /*!< Position of CH6 field. */ +#define PPI_CHENCLR_CH6_Msk (0x1UL << PPI_CHENCLR_CH6_Pos) /*!< Bit mask of CH6 field. */ +#define PPI_CHENCLR_CH6_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH6_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH6_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 5 : Channel 5 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH5_Pos (5UL) /*!< Position of CH5 field. */ +#define PPI_CHENCLR_CH5_Msk (0x1UL << PPI_CHENCLR_CH5_Pos) /*!< Bit mask of CH5 field. */ +#define PPI_CHENCLR_CH5_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH5_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH5_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 4 : Channel 4 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH4_Pos (4UL) /*!< Position of CH4 field. */ +#define PPI_CHENCLR_CH4_Msk (0x1UL << PPI_CHENCLR_CH4_Pos) /*!< Bit mask of CH4 field. */ +#define PPI_CHENCLR_CH4_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH4_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH4_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 3 : Channel 3 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH3_Pos (3UL) /*!< Position of CH3 field. */ +#define PPI_CHENCLR_CH3_Msk (0x1UL << PPI_CHENCLR_CH3_Pos) /*!< Bit mask of CH3 field. */ +#define PPI_CHENCLR_CH3_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH3_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH3_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 2 : Channel 2 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH2_Pos (2UL) /*!< Position of CH2 field. */ +#define PPI_CHENCLR_CH2_Msk (0x1UL << PPI_CHENCLR_CH2_Pos) /*!< Bit mask of CH2 field. */ +#define PPI_CHENCLR_CH2_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH2_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH2_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 1 : Channel 1 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH1_Pos (1UL) /*!< Position of CH1 field. */ +#define PPI_CHENCLR_CH1_Msk (0x1UL << PPI_CHENCLR_CH1_Pos) /*!< Bit mask of CH1 field. */ +#define PPI_CHENCLR_CH1_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH1_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH1_Clear (1UL) /*!< Write: disable channel */ + +/* Bit 0 : Channel 0 enable clear register. Writing '0' has no effect */ +#define PPI_CHENCLR_CH0_Pos (0UL) /*!< Position of CH0 field. */ +#define PPI_CHENCLR_CH0_Msk (0x1UL << PPI_CHENCLR_CH0_Pos) /*!< Bit mask of CH0 field. */ +#define PPI_CHENCLR_CH0_Disabled (0UL) /*!< Read: channel disabled */ +#define PPI_CHENCLR_CH0_Enabled (1UL) /*!< Read: channel enabled */ +#define PPI_CHENCLR_CH0_Clear (1UL) /*!< Write: disable channel */ + +/* Register: PPI_CH_EEP */ +/* Description: Description cluster[0]: Channel 0 event end-point */ + +/* Bits 31..0 : Pointer to event register. Accepts only addresses to registers from the Event group. */ +#define PPI_CH_EEP_EEP_Pos (0UL) /*!< Position of EEP field. */ +#define PPI_CH_EEP_EEP_Msk (0xFFFFFFFFUL << PPI_CH_EEP_EEP_Pos) /*!< Bit mask of EEP field. */ + +/* Register: PPI_CH_TEP */ +/* Description: Description cluster[0]: Channel 0 task end-point */ + +/* Bits 31..0 : Pointer to task register. Accepts only addresses to registers from the Task group. */ +#define PPI_CH_TEP_TEP_Pos (0UL) /*!< Position of TEP field. */ +#define PPI_CH_TEP_TEP_Msk (0xFFFFFFFFUL << PPI_CH_TEP_TEP_Pos) /*!< Bit mask of TEP field. */ + +/* Register: PPI_CHG */ +/* Description: Description collection[0]: Channel group 0 */ + +/* Bit 31 : Include or exclude channel 31 */ +#define PPI_CHG_CH31_Pos (31UL) /*!< Position of CH31 field. */ +#define PPI_CHG_CH31_Msk (0x1UL << PPI_CHG_CH31_Pos) /*!< Bit mask of CH31 field. */ +#define PPI_CHG_CH31_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH31_Included (1UL) /*!< Include */ + +/* Bit 30 : Include or exclude channel 30 */ +#define PPI_CHG_CH30_Pos (30UL) /*!< Position of CH30 field. */ +#define PPI_CHG_CH30_Msk (0x1UL << PPI_CHG_CH30_Pos) /*!< Bit mask of CH30 field. */ +#define PPI_CHG_CH30_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH30_Included (1UL) /*!< Include */ + +/* Bit 29 : Include or exclude channel 29 */ +#define PPI_CHG_CH29_Pos (29UL) /*!< Position of CH29 field. */ +#define PPI_CHG_CH29_Msk (0x1UL << PPI_CHG_CH29_Pos) /*!< Bit mask of CH29 field. */ +#define PPI_CHG_CH29_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH29_Included (1UL) /*!< Include */ + +/* Bit 28 : Include or exclude channel 28 */ +#define PPI_CHG_CH28_Pos (28UL) /*!< Position of CH28 field. */ +#define PPI_CHG_CH28_Msk (0x1UL << PPI_CHG_CH28_Pos) /*!< Bit mask of CH28 field. */ +#define PPI_CHG_CH28_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH28_Included (1UL) /*!< Include */ + +/* Bit 27 : Include or exclude channel 27 */ +#define PPI_CHG_CH27_Pos (27UL) /*!< Position of CH27 field. */ +#define PPI_CHG_CH27_Msk (0x1UL << PPI_CHG_CH27_Pos) /*!< Bit mask of CH27 field. */ +#define PPI_CHG_CH27_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH27_Included (1UL) /*!< Include */ + +/* Bit 26 : Include or exclude channel 26 */ +#define PPI_CHG_CH26_Pos (26UL) /*!< Position of CH26 field. */ +#define PPI_CHG_CH26_Msk (0x1UL << PPI_CHG_CH26_Pos) /*!< Bit mask of CH26 field. */ +#define PPI_CHG_CH26_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH26_Included (1UL) /*!< Include */ + +/* Bit 25 : Include or exclude channel 25 */ +#define PPI_CHG_CH25_Pos (25UL) /*!< Position of CH25 field. */ +#define PPI_CHG_CH25_Msk (0x1UL << PPI_CHG_CH25_Pos) /*!< Bit mask of CH25 field. */ +#define PPI_CHG_CH25_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH25_Included (1UL) /*!< Include */ + +/* Bit 24 : Include or exclude channel 24 */ +#define PPI_CHG_CH24_Pos (24UL) /*!< Position of CH24 field. */ +#define PPI_CHG_CH24_Msk (0x1UL << PPI_CHG_CH24_Pos) /*!< Bit mask of CH24 field. */ +#define PPI_CHG_CH24_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH24_Included (1UL) /*!< Include */ + +/* Bit 23 : Include or exclude channel 23 */ +#define PPI_CHG_CH23_Pos (23UL) /*!< Position of CH23 field. */ +#define PPI_CHG_CH23_Msk (0x1UL << PPI_CHG_CH23_Pos) /*!< Bit mask of CH23 field. */ +#define PPI_CHG_CH23_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH23_Included (1UL) /*!< Include */ + +/* Bit 22 : Include or exclude channel 22 */ +#define PPI_CHG_CH22_Pos (22UL) /*!< Position of CH22 field. */ +#define PPI_CHG_CH22_Msk (0x1UL << PPI_CHG_CH22_Pos) /*!< Bit mask of CH22 field. */ +#define PPI_CHG_CH22_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH22_Included (1UL) /*!< Include */ + +/* Bit 21 : Include or exclude channel 21 */ +#define PPI_CHG_CH21_Pos (21UL) /*!< Position of CH21 field. */ +#define PPI_CHG_CH21_Msk (0x1UL << PPI_CHG_CH21_Pos) /*!< Bit mask of CH21 field. */ +#define PPI_CHG_CH21_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH21_Included (1UL) /*!< Include */ + +/* Bit 20 : Include or exclude channel 20 */ +#define PPI_CHG_CH20_Pos (20UL) /*!< Position of CH20 field. */ +#define PPI_CHG_CH20_Msk (0x1UL << PPI_CHG_CH20_Pos) /*!< Bit mask of CH20 field. */ +#define PPI_CHG_CH20_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH20_Included (1UL) /*!< Include */ + +/* Bit 19 : Include or exclude channel 19 */ +#define PPI_CHG_CH19_Pos (19UL) /*!< Position of CH19 field. */ +#define PPI_CHG_CH19_Msk (0x1UL << PPI_CHG_CH19_Pos) /*!< Bit mask of CH19 field. */ +#define PPI_CHG_CH19_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH19_Included (1UL) /*!< Include */ + +/* Bit 18 : Include or exclude channel 18 */ +#define PPI_CHG_CH18_Pos (18UL) /*!< Position of CH18 field. */ +#define PPI_CHG_CH18_Msk (0x1UL << PPI_CHG_CH18_Pos) /*!< Bit mask of CH18 field. */ +#define PPI_CHG_CH18_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH18_Included (1UL) /*!< Include */ + +/* Bit 17 : Include or exclude channel 17 */ +#define PPI_CHG_CH17_Pos (17UL) /*!< Position of CH17 field. */ +#define PPI_CHG_CH17_Msk (0x1UL << PPI_CHG_CH17_Pos) /*!< Bit mask of CH17 field. */ +#define PPI_CHG_CH17_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH17_Included (1UL) /*!< Include */ + +/* Bit 16 : Include or exclude channel 16 */ +#define PPI_CHG_CH16_Pos (16UL) /*!< Position of CH16 field. */ +#define PPI_CHG_CH16_Msk (0x1UL << PPI_CHG_CH16_Pos) /*!< Bit mask of CH16 field. */ +#define PPI_CHG_CH16_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH16_Included (1UL) /*!< Include */ + +/* Bit 15 : Include or exclude channel 15 */ +#define PPI_CHG_CH15_Pos (15UL) /*!< Position of CH15 field. */ +#define PPI_CHG_CH15_Msk (0x1UL << PPI_CHG_CH15_Pos) /*!< Bit mask of CH15 field. */ +#define PPI_CHG_CH15_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH15_Included (1UL) /*!< Include */ + +/* Bit 14 : Include or exclude channel 14 */ +#define PPI_CHG_CH14_Pos (14UL) /*!< Position of CH14 field. */ +#define PPI_CHG_CH14_Msk (0x1UL << PPI_CHG_CH14_Pos) /*!< Bit mask of CH14 field. */ +#define PPI_CHG_CH14_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH14_Included (1UL) /*!< Include */ + +/* Bit 13 : Include or exclude channel 13 */ +#define PPI_CHG_CH13_Pos (13UL) /*!< Position of CH13 field. */ +#define PPI_CHG_CH13_Msk (0x1UL << PPI_CHG_CH13_Pos) /*!< Bit mask of CH13 field. */ +#define PPI_CHG_CH13_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH13_Included (1UL) /*!< Include */ + +/* Bit 12 : Include or exclude channel 12 */ +#define PPI_CHG_CH12_Pos (12UL) /*!< Position of CH12 field. */ +#define PPI_CHG_CH12_Msk (0x1UL << PPI_CHG_CH12_Pos) /*!< Bit mask of CH12 field. */ +#define PPI_CHG_CH12_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH12_Included (1UL) /*!< Include */ + +/* Bit 11 : Include or exclude channel 11 */ +#define PPI_CHG_CH11_Pos (11UL) /*!< Position of CH11 field. */ +#define PPI_CHG_CH11_Msk (0x1UL << PPI_CHG_CH11_Pos) /*!< Bit mask of CH11 field. */ +#define PPI_CHG_CH11_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH11_Included (1UL) /*!< Include */ + +/* Bit 10 : Include or exclude channel 10 */ +#define PPI_CHG_CH10_Pos (10UL) /*!< Position of CH10 field. */ +#define PPI_CHG_CH10_Msk (0x1UL << PPI_CHG_CH10_Pos) /*!< Bit mask of CH10 field. */ +#define PPI_CHG_CH10_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH10_Included (1UL) /*!< Include */ + +/* Bit 9 : Include or exclude channel 9 */ +#define PPI_CHG_CH9_Pos (9UL) /*!< Position of CH9 field. */ +#define PPI_CHG_CH9_Msk (0x1UL << PPI_CHG_CH9_Pos) /*!< Bit mask of CH9 field. */ +#define PPI_CHG_CH9_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH9_Included (1UL) /*!< Include */ + +/* Bit 8 : Include or exclude channel 8 */ +#define PPI_CHG_CH8_Pos (8UL) /*!< Position of CH8 field. */ +#define PPI_CHG_CH8_Msk (0x1UL << PPI_CHG_CH8_Pos) /*!< Bit mask of CH8 field. */ +#define PPI_CHG_CH8_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH8_Included (1UL) /*!< Include */ + +/* Bit 7 : Include or exclude channel 7 */ +#define PPI_CHG_CH7_Pos (7UL) /*!< Position of CH7 field. */ +#define PPI_CHG_CH7_Msk (0x1UL << PPI_CHG_CH7_Pos) /*!< Bit mask of CH7 field. */ +#define PPI_CHG_CH7_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH7_Included (1UL) /*!< Include */ + +/* Bit 6 : Include or exclude channel 6 */ +#define PPI_CHG_CH6_Pos (6UL) /*!< Position of CH6 field. */ +#define PPI_CHG_CH6_Msk (0x1UL << PPI_CHG_CH6_Pos) /*!< Bit mask of CH6 field. */ +#define PPI_CHG_CH6_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH6_Included (1UL) /*!< Include */ + +/* Bit 5 : Include or exclude channel 5 */ +#define PPI_CHG_CH5_Pos (5UL) /*!< Position of CH5 field. */ +#define PPI_CHG_CH5_Msk (0x1UL << PPI_CHG_CH5_Pos) /*!< Bit mask of CH5 field. */ +#define PPI_CHG_CH5_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH5_Included (1UL) /*!< Include */ + +/* Bit 4 : Include or exclude channel 4 */ +#define PPI_CHG_CH4_Pos (4UL) /*!< Position of CH4 field. */ +#define PPI_CHG_CH4_Msk (0x1UL << PPI_CHG_CH4_Pos) /*!< Bit mask of CH4 field. */ +#define PPI_CHG_CH4_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH4_Included (1UL) /*!< Include */ + +/* Bit 3 : Include or exclude channel 3 */ +#define PPI_CHG_CH3_Pos (3UL) /*!< Position of CH3 field. */ +#define PPI_CHG_CH3_Msk (0x1UL << PPI_CHG_CH3_Pos) /*!< Bit mask of CH3 field. */ +#define PPI_CHG_CH3_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH3_Included (1UL) /*!< Include */ + +/* Bit 2 : Include or exclude channel 2 */ +#define PPI_CHG_CH2_Pos (2UL) /*!< Position of CH2 field. */ +#define PPI_CHG_CH2_Msk (0x1UL << PPI_CHG_CH2_Pos) /*!< Bit mask of CH2 field. */ +#define PPI_CHG_CH2_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH2_Included (1UL) /*!< Include */ + +/* Bit 1 : Include or exclude channel 1 */ +#define PPI_CHG_CH1_Pos (1UL) /*!< Position of CH1 field. */ +#define PPI_CHG_CH1_Msk (0x1UL << PPI_CHG_CH1_Pos) /*!< Bit mask of CH1 field. */ +#define PPI_CHG_CH1_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH1_Included (1UL) /*!< Include */ + +/* Bit 0 : Include or exclude channel 0 */ +#define PPI_CHG_CH0_Pos (0UL) /*!< Position of CH0 field. */ +#define PPI_CHG_CH0_Msk (0x1UL << PPI_CHG_CH0_Pos) /*!< Bit mask of CH0 field. */ +#define PPI_CHG_CH0_Excluded (0UL) /*!< Exclude */ +#define PPI_CHG_CH0_Included (1UL) /*!< Include */ + +/* Register: PPI_FORK_TEP */ +/* Description: Description cluster[0]: Channel 0 task end-point */ + +/* Bits 31..0 : Pointer to task register */ +#define PPI_FORK_TEP_TEP_Pos (0UL) /*!< Position of TEP field. */ +#define PPI_FORK_TEP_TEP_Msk (0xFFFFFFFFUL << PPI_FORK_TEP_TEP_Pos) /*!< Bit mask of TEP field. */ + + +/* Peripheral: PWM */ +/* Description: Pulse Width Modulation Unit 0 */ + +/* Register: PWM_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 4 : Shortcut between LOOPSDONE event and STOP task */ +#define PWM_SHORTS_LOOPSDONE_STOP_Pos (4UL) /*!< Position of LOOPSDONE_STOP field. */ +#define PWM_SHORTS_LOOPSDONE_STOP_Msk (0x1UL << PWM_SHORTS_LOOPSDONE_STOP_Pos) /*!< Bit mask of LOOPSDONE_STOP field. */ +#define PWM_SHORTS_LOOPSDONE_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define PWM_SHORTS_LOOPSDONE_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between LOOPSDONE event and SEQSTART[1] task */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART1_Pos (3UL) /*!< Position of LOOPSDONE_SEQSTART1 field. */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART1_Msk (0x1UL << PWM_SHORTS_LOOPSDONE_SEQSTART1_Pos) /*!< Bit mask of LOOPSDONE_SEQSTART1 field. */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART1_Disabled (0UL) /*!< Disable shortcut */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART1_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between LOOPSDONE event and SEQSTART[0] task */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART0_Pos (2UL) /*!< Position of LOOPSDONE_SEQSTART0 field. */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART0_Msk (0x1UL << PWM_SHORTS_LOOPSDONE_SEQSTART0_Pos) /*!< Bit mask of LOOPSDONE_SEQSTART0 field. */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART0_Disabled (0UL) /*!< Disable shortcut */ +#define PWM_SHORTS_LOOPSDONE_SEQSTART0_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between SEQEND[1] event and STOP task */ +#define PWM_SHORTS_SEQEND1_STOP_Pos (1UL) /*!< Position of SEQEND1_STOP field. */ +#define PWM_SHORTS_SEQEND1_STOP_Msk (0x1UL << PWM_SHORTS_SEQEND1_STOP_Pos) /*!< Bit mask of SEQEND1_STOP field. */ +#define PWM_SHORTS_SEQEND1_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define PWM_SHORTS_SEQEND1_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between SEQEND[0] event and STOP task */ +#define PWM_SHORTS_SEQEND0_STOP_Pos (0UL) /*!< Position of SEQEND0_STOP field. */ +#define PWM_SHORTS_SEQEND0_STOP_Msk (0x1UL << PWM_SHORTS_SEQEND0_STOP_Pos) /*!< Bit mask of SEQEND0_STOP field. */ +#define PWM_SHORTS_SEQEND0_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define PWM_SHORTS_SEQEND0_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: PWM_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 7 : Enable or disable interrupt for LOOPSDONE event */ +#define PWM_INTEN_LOOPSDONE_Pos (7UL) /*!< Position of LOOPSDONE field. */ +#define PWM_INTEN_LOOPSDONE_Msk (0x1UL << PWM_INTEN_LOOPSDONE_Pos) /*!< Bit mask of LOOPSDONE field. */ +#define PWM_INTEN_LOOPSDONE_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_LOOPSDONE_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable interrupt for PWMPERIODEND event */ +#define PWM_INTEN_PWMPERIODEND_Pos (6UL) /*!< Position of PWMPERIODEND field. */ +#define PWM_INTEN_PWMPERIODEND_Msk (0x1UL << PWM_INTEN_PWMPERIODEND_Pos) /*!< Bit mask of PWMPERIODEND field. */ +#define PWM_INTEN_PWMPERIODEND_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_PWMPERIODEND_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable interrupt for SEQEND[1] event */ +#define PWM_INTEN_SEQEND1_Pos (5UL) /*!< Position of SEQEND1 field. */ +#define PWM_INTEN_SEQEND1_Msk (0x1UL << PWM_INTEN_SEQEND1_Pos) /*!< Bit mask of SEQEND1 field. */ +#define PWM_INTEN_SEQEND1_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_SEQEND1_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for SEQEND[0] event */ +#define PWM_INTEN_SEQEND0_Pos (4UL) /*!< Position of SEQEND0 field. */ +#define PWM_INTEN_SEQEND0_Msk (0x1UL << PWM_INTEN_SEQEND0_Pos) /*!< Bit mask of SEQEND0 field. */ +#define PWM_INTEN_SEQEND0_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_SEQEND0_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable interrupt for SEQSTARTED[1] event */ +#define PWM_INTEN_SEQSTARTED1_Pos (3UL) /*!< Position of SEQSTARTED1 field. */ +#define PWM_INTEN_SEQSTARTED1_Msk (0x1UL << PWM_INTEN_SEQSTARTED1_Pos) /*!< Bit mask of SEQSTARTED1 field. */ +#define PWM_INTEN_SEQSTARTED1_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_SEQSTARTED1_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for SEQSTARTED[0] event */ +#define PWM_INTEN_SEQSTARTED0_Pos (2UL) /*!< Position of SEQSTARTED0 field. */ +#define PWM_INTEN_SEQSTARTED0_Msk (0x1UL << PWM_INTEN_SEQSTARTED0_Pos) /*!< Bit mask of SEQSTARTED0 field. */ +#define PWM_INTEN_SEQSTARTED0_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_SEQSTARTED0_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for STOPPED event */ +#define PWM_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PWM_INTEN_STOPPED_Msk (0x1UL << PWM_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PWM_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define PWM_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Register: PWM_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 7 : Write '1' to Enable interrupt for LOOPSDONE event */ +#define PWM_INTENSET_LOOPSDONE_Pos (7UL) /*!< Position of LOOPSDONE field. */ +#define PWM_INTENSET_LOOPSDONE_Msk (0x1UL << PWM_INTENSET_LOOPSDONE_Pos) /*!< Bit mask of LOOPSDONE field. */ +#define PWM_INTENSET_LOOPSDONE_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_LOOPSDONE_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_LOOPSDONE_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for PWMPERIODEND event */ +#define PWM_INTENSET_PWMPERIODEND_Pos (6UL) /*!< Position of PWMPERIODEND field. */ +#define PWM_INTENSET_PWMPERIODEND_Msk (0x1UL << PWM_INTENSET_PWMPERIODEND_Pos) /*!< Bit mask of PWMPERIODEND field. */ +#define PWM_INTENSET_PWMPERIODEND_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_PWMPERIODEND_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_PWMPERIODEND_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for SEQEND[1] event */ +#define PWM_INTENSET_SEQEND1_Pos (5UL) /*!< Position of SEQEND1 field. */ +#define PWM_INTENSET_SEQEND1_Msk (0x1UL << PWM_INTENSET_SEQEND1_Pos) /*!< Bit mask of SEQEND1 field. */ +#define PWM_INTENSET_SEQEND1_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_SEQEND1_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_SEQEND1_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for SEQEND[0] event */ +#define PWM_INTENSET_SEQEND0_Pos (4UL) /*!< Position of SEQEND0 field. */ +#define PWM_INTENSET_SEQEND0_Msk (0x1UL << PWM_INTENSET_SEQEND0_Pos) /*!< Bit mask of SEQEND0 field. */ +#define PWM_INTENSET_SEQEND0_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_SEQEND0_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_SEQEND0_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for SEQSTARTED[1] event */ +#define PWM_INTENSET_SEQSTARTED1_Pos (3UL) /*!< Position of SEQSTARTED1 field. */ +#define PWM_INTENSET_SEQSTARTED1_Msk (0x1UL << PWM_INTENSET_SEQSTARTED1_Pos) /*!< Bit mask of SEQSTARTED1 field. */ +#define PWM_INTENSET_SEQSTARTED1_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_SEQSTARTED1_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_SEQSTARTED1_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for SEQSTARTED[0] event */ +#define PWM_INTENSET_SEQSTARTED0_Pos (2UL) /*!< Position of SEQSTARTED0 field. */ +#define PWM_INTENSET_SEQSTARTED0_Msk (0x1UL << PWM_INTENSET_SEQSTARTED0_Pos) /*!< Bit mask of SEQSTARTED0 field. */ +#define PWM_INTENSET_SEQSTARTED0_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_SEQSTARTED0_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_SEQSTARTED0_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define PWM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PWM_INTENSET_STOPPED_Msk (0x1UL << PWM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PWM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Register: PWM_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 7 : Write '1' to Disable interrupt for LOOPSDONE event */ +#define PWM_INTENCLR_LOOPSDONE_Pos (7UL) /*!< Position of LOOPSDONE field. */ +#define PWM_INTENCLR_LOOPSDONE_Msk (0x1UL << PWM_INTENCLR_LOOPSDONE_Pos) /*!< Bit mask of LOOPSDONE field. */ +#define PWM_INTENCLR_LOOPSDONE_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_LOOPSDONE_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_LOOPSDONE_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for PWMPERIODEND event */ +#define PWM_INTENCLR_PWMPERIODEND_Pos (6UL) /*!< Position of PWMPERIODEND field. */ +#define PWM_INTENCLR_PWMPERIODEND_Msk (0x1UL << PWM_INTENCLR_PWMPERIODEND_Pos) /*!< Bit mask of PWMPERIODEND field. */ +#define PWM_INTENCLR_PWMPERIODEND_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_PWMPERIODEND_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_PWMPERIODEND_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for SEQEND[1] event */ +#define PWM_INTENCLR_SEQEND1_Pos (5UL) /*!< Position of SEQEND1 field. */ +#define PWM_INTENCLR_SEQEND1_Msk (0x1UL << PWM_INTENCLR_SEQEND1_Pos) /*!< Bit mask of SEQEND1 field. */ +#define PWM_INTENCLR_SEQEND1_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_SEQEND1_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_SEQEND1_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for SEQEND[0] event */ +#define PWM_INTENCLR_SEQEND0_Pos (4UL) /*!< Position of SEQEND0 field. */ +#define PWM_INTENCLR_SEQEND0_Msk (0x1UL << PWM_INTENCLR_SEQEND0_Pos) /*!< Bit mask of SEQEND0 field. */ +#define PWM_INTENCLR_SEQEND0_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_SEQEND0_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_SEQEND0_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for SEQSTARTED[1] event */ +#define PWM_INTENCLR_SEQSTARTED1_Pos (3UL) /*!< Position of SEQSTARTED1 field. */ +#define PWM_INTENCLR_SEQSTARTED1_Msk (0x1UL << PWM_INTENCLR_SEQSTARTED1_Pos) /*!< Bit mask of SEQSTARTED1 field. */ +#define PWM_INTENCLR_SEQSTARTED1_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_SEQSTARTED1_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_SEQSTARTED1_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for SEQSTARTED[0] event */ +#define PWM_INTENCLR_SEQSTARTED0_Pos (2UL) /*!< Position of SEQSTARTED0 field. */ +#define PWM_INTENCLR_SEQSTARTED0_Msk (0x1UL << PWM_INTENCLR_SEQSTARTED0_Pos) /*!< Bit mask of SEQSTARTED0 field. */ +#define PWM_INTENCLR_SEQSTARTED0_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_SEQSTARTED0_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_SEQSTARTED0_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define PWM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define PWM_INTENCLR_STOPPED_Msk (0x1UL << PWM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define PWM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define PWM_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define PWM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Register: PWM_ENABLE */ +/* Description: PWM module enable register */ + +/* Bit 0 : Enable or disable PWM module */ +#define PWM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define PWM_ENABLE_ENABLE_Msk (0x1UL << PWM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define PWM_ENABLE_ENABLE_Disabled (0UL) /*!< Disabled */ +#define PWM_ENABLE_ENABLE_Enabled (1UL) /*!< Enable */ + +/* Register: PWM_MODE */ +/* Description: Selects operating mode of the wave counter */ + +/* Bit 0 : Selects up or up and down as wave counter mode */ +#define PWM_MODE_UPDOWN_Pos (0UL) /*!< Position of UPDOWN field. */ +#define PWM_MODE_UPDOWN_Msk (0x1UL << PWM_MODE_UPDOWN_Pos) /*!< Bit mask of UPDOWN field. */ +#define PWM_MODE_UPDOWN_Up (0UL) /*!< Up counter - edge aligned PWM duty-cycle */ +#define PWM_MODE_UPDOWN_UpAndDown (1UL) /*!< Up and down counter - center aligned PWM duty cycle */ + +/* Register: PWM_COUNTERTOP */ +/* Description: Value up to which the pulse generator counter counts */ + +/* Bits 14..0 : Value up to which the pulse generator counter counts. This register is ignored when DECODER.MODE=WaveForm and only values from RAM will be used. */ +#define PWM_COUNTERTOP_COUNTERTOP_Pos (0UL) /*!< Position of COUNTERTOP field. */ +#define PWM_COUNTERTOP_COUNTERTOP_Msk (0x7FFFUL << PWM_COUNTERTOP_COUNTERTOP_Pos) /*!< Bit mask of COUNTERTOP field. */ + +/* Register: PWM_PRESCALER */ +/* Description: Configuration for PWM_CLK */ + +/* Bits 2..0 : Pre-scaler of PWM_CLK */ +#define PWM_PRESCALER_PRESCALER_Pos (0UL) /*!< Position of PRESCALER field. */ +#define PWM_PRESCALER_PRESCALER_Msk (0x7UL << PWM_PRESCALER_PRESCALER_Pos) /*!< Bit mask of PRESCALER field. */ +#define PWM_PRESCALER_PRESCALER_DIV_1 (0UL) /*!< Divide by 1 (16MHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_2 (1UL) /*!< Divide by 2 ( 8MHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_4 (2UL) /*!< Divide by 4 ( 4MHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_8 (3UL) /*!< Divide by 8 ( 2MHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_16 (4UL) /*!< Divide by 16 ( 1MHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_32 (5UL) /*!< Divide by 32 ( 500kHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_64 (6UL) /*!< Divide by 64 ( 250kHz) */ +#define PWM_PRESCALER_PRESCALER_DIV_128 (7UL) /*!< Divide by 128 ( 125kHz) */ + +/* Register: PWM_DECODER */ +/* Description: Configuration of the decoder */ + +/* Bit 8 : Selects source for advancing the active sequence */ +#define PWM_DECODER_MODE_Pos (8UL) /*!< Position of MODE field. */ +#define PWM_DECODER_MODE_Msk (0x1UL << PWM_DECODER_MODE_Pos) /*!< Bit mask of MODE field. */ +#define PWM_DECODER_MODE_RefreshCount (0UL) /*!< SEQ[n].REFRESH is used to determine loading internal compare registers */ +#define PWM_DECODER_MODE_NextStep (1UL) /*!< NEXTSTEP task causes a new value to be loaded to internal compare registers */ + +/* Bits 2..0 : How a sequence is read from RAM and spread to the compare register */ +#define PWM_DECODER_LOAD_Pos (0UL) /*!< Position of LOAD field. */ +#define PWM_DECODER_LOAD_Msk (0x7UL << PWM_DECODER_LOAD_Pos) /*!< Bit mask of LOAD field. */ +#define PWM_DECODER_LOAD_Common (0UL) /*!< 1st half word (16-bit) used in all PWM channels 0..3 */ +#define PWM_DECODER_LOAD_Grouped (1UL) /*!< 1st half word (16-bit) used in channel 0..1; 2nd word in channel 2..3 */ +#define PWM_DECODER_LOAD_Individual (2UL) /*!< 1st half word (16-bit) in ch.0; 2nd in ch.1; ...; 4th in ch.3 */ +#define PWM_DECODER_LOAD_WaveForm (3UL) /*!< 1st half word (16-bit) in ch.0; 2nd in ch.1; ...; 4th in COUNTERTOP */ + +/* Register: PWM_LOOP */ +/* Description: Amount of playback of a loop */ + +/* Bits 15..0 : Amount of playback of pattern cycles */ +#define PWM_LOOP_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define PWM_LOOP_CNT_Msk (0xFFFFUL << PWM_LOOP_CNT_Pos) /*!< Bit mask of CNT field. */ +#define PWM_LOOP_CNT_Disabled (0UL) /*!< Looping disabled (stop at the end of the sequence) */ + +/* Register: PWM_SEQ_PTR */ +/* Description: Description cluster[0]: Beginning address in Data RAM of sequence A */ + +/* Bits 31..0 : Beginning address in Data RAM of sequence A */ +#define PWM_SEQ_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define PWM_SEQ_PTR_PTR_Msk (0xFFFFFFFFUL << PWM_SEQ_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: PWM_SEQ_CNT */ +/* Description: Description cluster[0]: Amount of values (duty cycles) in sequence A */ + +/* Bits 14..0 : Amount of values (duty cycles) in sequence A */ +#define PWM_SEQ_CNT_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define PWM_SEQ_CNT_CNT_Msk (0x7FFFUL << PWM_SEQ_CNT_CNT_Pos) /*!< Bit mask of CNT field. */ +#define PWM_SEQ_CNT_CNT_Disabled (0UL) /*!< Sequence is disabled, and shall not be started as it is empty */ + +/* Register: PWM_SEQ_REFRESH */ +/* Description: Description cluster[0]: Amount of additional PWM periods between samples loaded to compare register (load every CNT+1 PWM periods) */ + +/* Bits 23..0 : Amount of additional PWM periods between samples loaded to compare register (load every CNT+1 PWM periods) */ +#define PWM_SEQ_REFRESH_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define PWM_SEQ_REFRESH_CNT_Msk (0xFFFFFFUL << PWM_SEQ_REFRESH_CNT_Pos) /*!< Bit mask of CNT field. */ +#define PWM_SEQ_REFRESH_CNT_Continuous (0UL) /*!< Update every PWM period */ + +/* Register: PWM_SEQ_ENDDELAY */ +/* Description: Description cluster[0]: Time added after the sequence */ + +/* Bits 23..0 : Time added after the sequence in PWM periods */ +#define PWM_SEQ_ENDDELAY_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define PWM_SEQ_ENDDELAY_CNT_Msk (0xFFFFFFUL << PWM_SEQ_ENDDELAY_CNT_Pos) /*!< Bit mask of CNT field. */ + +/* Register: PWM_PSEL_OUT */ +/* Description: Description collection[0]: Output pin select for PWM channel 0 */ + +/* Bit 31 : Connection */ +#define PWM_PSEL_OUT_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define PWM_PSEL_OUT_CONNECT_Msk (0x1UL << PWM_PSEL_OUT_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define PWM_PSEL_OUT_CONNECT_Connected (0UL) /*!< Connect */ +#define PWM_PSEL_OUT_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 9..8 : Port number */ +#define PWM_PSEL_OUT_PORT_Pos (8UL) /*!< Position of PORT field. */ +#define PWM_PSEL_OUT_PORT_Msk (0x3UL << PWM_PSEL_OUT_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define PWM_PSEL_OUT_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define PWM_PSEL_OUT_PIN_Msk (0x1FUL << PWM_PSEL_OUT_PIN_Pos) /*!< Bit mask of PIN field. */ + + +/* Peripheral: QDEC */ +/* Description: Quadrature Decoder */ + +/* Register: QDEC_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 6 : Shortcut between SAMPLERDY event and READCLRACC task */ +#define QDEC_SHORTS_SAMPLERDY_READCLRACC_Pos (6UL) /*!< Position of SAMPLERDY_READCLRACC field. */ +#define QDEC_SHORTS_SAMPLERDY_READCLRACC_Msk (0x1UL << QDEC_SHORTS_SAMPLERDY_READCLRACC_Pos) /*!< Bit mask of SAMPLERDY_READCLRACC field. */ +#define QDEC_SHORTS_SAMPLERDY_READCLRACC_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_SAMPLERDY_READCLRACC_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 5 : Shortcut between DBLRDY event and STOP task */ +#define QDEC_SHORTS_DBLRDY_STOP_Pos (5UL) /*!< Position of DBLRDY_STOP field. */ +#define QDEC_SHORTS_DBLRDY_STOP_Msk (0x1UL << QDEC_SHORTS_DBLRDY_STOP_Pos) /*!< Bit mask of DBLRDY_STOP field. */ +#define QDEC_SHORTS_DBLRDY_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_DBLRDY_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 4 : Shortcut between DBLRDY event and RDCLRDBL task */ +#define QDEC_SHORTS_DBLRDY_RDCLRDBL_Pos (4UL) /*!< Position of DBLRDY_RDCLRDBL field. */ +#define QDEC_SHORTS_DBLRDY_RDCLRDBL_Msk (0x1UL << QDEC_SHORTS_DBLRDY_RDCLRDBL_Pos) /*!< Bit mask of DBLRDY_RDCLRDBL field. */ +#define QDEC_SHORTS_DBLRDY_RDCLRDBL_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_DBLRDY_RDCLRDBL_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between REPORTRDY event and STOP task */ +#define QDEC_SHORTS_REPORTRDY_STOP_Pos (3UL) /*!< Position of REPORTRDY_STOP field. */ +#define QDEC_SHORTS_REPORTRDY_STOP_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_STOP_Pos) /*!< Bit mask of REPORTRDY_STOP field. */ +#define QDEC_SHORTS_REPORTRDY_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_REPORTRDY_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between REPORTRDY event and RDCLRACC task */ +#define QDEC_SHORTS_REPORTRDY_RDCLRACC_Pos (2UL) /*!< Position of REPORTRDY_RDCLRACC field. */ +#define QDEC_SHORTS_REPORTRDY_RDCLRACC_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_RDCLRACC_Pos) /*!< Bit mask of REPORTRDY_RDCLRACC field. */ +#define QDEC_SHORTS_REPORTRDY_RDCLRACC_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_REPORTRDY_RDCLRACC_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between SAMPLERDY event and STOP task */ +#define QDEC_SHORTS_SAMPLERDY_STOP_Pos (1UL) /*!< Position of SAMPLERDY_STOP field. */ +#define QDEC_SHORTS_SAMPLERDY_STOP_Msk (0x1UL << QDEC_SHORTS_SAMPLERDY_STOP_Pos) /*!< Bit mask of SAMPLERDY_STOP field. */ +#define QDEC_SHORTS_SAMPLERDY_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_SAMPLERDY_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between REPORTRDY event and READCLRACC task */ +#define QDEC_SHORTS_REPORTRDY_READCLRACC_Pos (0UL) /*!< Position of REPORTRDY_READCLRACC field. */ +#define QDEC_SHORTS_REPORTRDY_READCLRACC_Msk (0x1UL << QDEC_SHORTS_REPORTRDY_READCLRACC_Pos) /*!< Bit mask of REPORTRDY_READCLRACC field. */ +#define QDEC_SHORTS_REPORTRDY_READCLRACC_Disabled (0UL) /*!< Disable shortcut */ +#define QDEC_SHORTS_REPORTRDY_READCLRACC_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: QDEC_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 4 : Write '1' to Enable interrupt for STOPPED event */ +#define QDEC_INTENSET_STOPPED_Pos (4UL) /*!< Position of STOPPED field. */ +#define QDEC_INTENSET_STOPPED_Msk (0x1UL << QDEC_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define QDEC_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for DBLRDY event */ +#define QDEC_INTENSET_DBLRDY_Pos (3UL) /*!< Position of DBLRDY field. */ +#define QDEC_INTENSET_DBLRDY_Msk (0x1UL << QDEC_INTENSET_DBLRDY_Pos) /*!< Bit mask of DBLRDY field. */ +#define QDEC_INTENSET_DBLRDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENSET_DBLRDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENSET_DBLRDY_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for ACCOF event */ +#define QDEC_INTENSET_ACCOF_Pos (2UL) /*!< Position of ACCOF field. */ +#define QDEC_INTENSET_ACCOF_Msk (0x1UL << QDEC_INTENSET_ACCOF_Pos) /*!< Bit mask of ACCOF field. */ +#define QDEC_INTENSET_ACCOF_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENSET_ACCOF_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENSET_ACCOF_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for REPORTRDY event */ +#define QDEC_INTENSET_REPORTRDY_Pos (1UL) /*!< Position of REPORTRDY field. */ +#define QDEC_INTENSET_REPORTRDY_Msk (0x1UL << QDEC_INTENSET_REPORTRDY_Pos) /*!< Bit mask of REPORTRDY field. */ +#define QDEC_INTENSET_REPORTRDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENSET_REPORTRDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENSET_REPORTRDY_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for SAMPLERDY event */ +#define QDEC_INTENSET_SAMPLERDY_Pos (0UL) /*!< Position of SAMPLERDY field. */ +#define QDEC_INTENSET_SAMPLERDY_Msk (0x1UL << QDEC_INTENSET_SAMPLERDY_Pos) /*!< Bit mask of SAMPLERDY field. */ +#define QDEC_INTENSET_SAMPLERDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENSET_SAMPLERDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENSET_SAMPLERDY_Set (1UL) /*!< Enable */ + +/* Register: QDEC_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 4 : Write '1' to Disable interrupt for STOPPED event */ +#define QDEC_INTENCLR_STOPPED_Pos (4UL) /*!< Position of STOPPED field. */ +#define QDEC_INTENCLR_STOPPED_Msk (0x1UL << QDEC_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define QDEC_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for DBLRDY event */ +#define QDEC_INTENCLR_DBLRDY_Pos (3UL) /*!< Position of DBLRDY field. */ +#define QDEC_INTENCLR_DBLRDY_Msk (0x1UL << QDEC_INTENCLR_DBLRDY_Pos) /*!< Bit mask of DBLRDY field. */ +#define QDEC_INTENCLR_DBLRDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENCLR_DBLRDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENCLR_DBLRDY_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for ACCOF event */ +#define QDEC_INTENCLR_ACCOF_Pos (2UL) /*!< Position of ACCOF field. */ +#define QDEC_INTENCLR_ACCOF_Msk (0x1UL << QDEC_INTENCLR_ACCOF_Pos) /*!< Bit mask of ACCOF field. */ +#define QDEC_INTENCLR_ACCOF_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENCLR_ACCOF_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENCLR_ACCOF_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for REPORTRDY event */ +#define QDEC_INTENCLR_REPORTRDY_Pos (1UL) /*!< Position of REPORTRDY field. */ +#define QDEC_INTENCLR_REPORTRDY_Msk (0x1UL << QDEC_INTENCLR_REPORTRDY_Pos) /*!< Bit mask of REPORTRDY field. */ +#define QDEC_INTENCLR_REPORTRDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENCLR_REPORTRDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENCLR_REPORTRDY_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for SAMPLERDY event */ +#define QDEC_INTENCLR_SAMPLERDY_Pos (0UL) /*!< Position of SAMPLERDY field. */ +#define QDEC_INTENCLR_SAMPLERDY_Msk (0x1UL << QDEC_INTENCLR_SAMPLERDY_Pos) /*!< Bit mask of SAMPLERDY field. */ +#define QDEC_INTENCLR_SAMPLERDY_Disabled (0UL) /*!< Read: Disabled */ +#define QDEC_INTENCLR_SAMPLERDY_Enabled (1UL) /*!< Read: Enabled */ +#define QDEC_INTENCLR_SAMPLERDY_Clear (1UL) /*!< Disable */ + +/* Register: QDEC_ENABLE */ +/* Description: Enable the quadrature decoder */ + +/* Bit 0 : Enable or disable the quadrature decoder */ +#define QDEC_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define QDEC_ENABLE_ENABLE_Msk (0x1UL << QDEC_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define QDEC_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define QDEC_ENABLE_ENABLE_Enabled (1UL) /*!< Enable */ + +/* Register: QDEC_LEDPOL */ +/* Description: LED output pin polarity */ + +/* Bit 0 : LED output pin polarity */ +#define QDEC_LEDPOL_LEDPOL_Pos (0UL) /*!< Position of LEDPOL field. */ +#define QDEC_LEDPOL_LEDPOL_Msk (0x1UL << QDEC_LEDPOL_LEDPOL_Pos) /*!< Bit mask of LEDPOL field. */ +#define QDEC_LEDPOL_LEDPOL_ActiveLow (0UL) /*!< Led active on output pin low */ +#define QDEC_LEDPOL_LEDPOL_ActiveHigh (1UL) /*!< Led active on output pin high */ + +/* Register: QDEC_SAMPLEPER */ +/* Description: Sample period */ + +/* Bits 3..0 : Sample period. The SAMPLE register will be updated for every new sample */ +#define QDEC_SAMPLEPER_SAMPLEPER_Pos (0UL) /*!< Position of SAMPLEPER field. */ +#define QDEC_SAMPLEPER_SAMPLEPER_Msk (0xFUL << QDEC_SAMPLEPER_SAMPLEPER_Pos) /*!< Bit mask of SAMPLEPER field. */ +#define QDEC_SAMPLEPER_SAMPLEPER_128us (0UL) /*!< 128 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_256us (1UL) /*!< 256 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_512us (2UL) /*!< 512 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_1024us (3UL) /*!< 1024 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_2048us (4UL) /*!< 2048 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_4096us (5UL) /*!< 4096 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_8192us (6UL) /*!< 8192 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_16384us (7UL) /*!< 16384 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_32ms (8UL) /*!< 32768 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_65ms (9UL) /*!< 65536 us */ +#define QDEC_SAMPLEPER_SAMPLEPER_131ms (10UL) /*!< 131072 us */ + +/* Register: QDEC_SAMPLE */ +/* Description: Motion sample value */ + +/* Bits 31..0 : Last motion sample */ +#define QDEC_SAMPLE_SAMPLE_Pos (0UL) /*!< Position of SAMPLE field. */ +#define QDEC_SAMPLE_SAMPLE_Msk (0xFFFFFFFFUL << QDEC_SAMPLE_SAMPLE_Pos) /*!< Bit mask of SAMPLE field. */ + +/* Register: QDEC_REPORTPER */ +/* Description: Number of samples to be taken before REPORTRDY and DBLRDY events can be generated */ + +/* Bits 3..0 : Specifies the number of samples to be accumulated in the ACC register before the REPORTRDY and DBLRDY events can be generated */ +#define QDEC_REPORTPER_REPORTPER_Pos (0UL) /*!< Position of REPORTPER field. */ +#define QDEC_REPORTPER_REPORTPER_Msk (0xFUL << QDEC_REPORTPER_REPORTPER_Pos) /*!< Bit mask of REPORTPER field. */ +#define QDEC_REPORTPER_REPORTPER_10Smpl (0UL) /*!< 10 samples / report */ +#define QDEC_REPORTPER_REPORTPER_40Smpl (1UL) /*!< 40 samples / report */ +#define QDEC_REPORTPER_REPORTPER_80Smpl (2UL) /*!< 80 samples / report */ +#define QDEC_REPORTPER_REPORTPER_120Smpl (3UL) /*!< 120 samples / report */ +#define QDEC_REPORTPER_REPORTPER_160Smpl (4UL) /*!< 160 samples / report */ +#define QDEC_REPORTPER_REPORTPER_200Smpl (5UL) /*!< 200 samples / report */ +#define QDEC_REPORTPER_REPORTPER_240Smpl (6UL) /*!< 240 samples / report */ +#define QDEC_REPORTPER_REPORTPER_280Smpl (7UL) /*!< 280 samples / report */ +#define QDEC_REPORTPER_REPORTPER_1Smpl (8UL) /*!< 1 sample / report */ + +/* Register: QDEC_ACC */ +/* Description: Register accumulating the valid transitions */ + +/* Bits 31..0 : Register accumulating all valid samples (not double transition) read from the SAMPLE register */ +#define QDEC_ACC_ACC_Pos (0UL) /*!< Position of ACC field. */ +#define QDEC_ACC_ACC_Msk (0xFFFFFFFFUL << QDEC_ACC_ACC_Pos) /*!< Bit mask of ACC field. */ + +/* Register: QDEC_ACCREAD */ +/* Description: Snapshot of the ACC register, updated by the READCLRACC or RDCLRACC task */ + +/* Bits 31..0 : Snapshot of the ACC register. */ +#define QDEC_ACCREAD_ACCREAD_Pos (0UL) /*!< Position of ACCREAD field. */ +#define QDEC_ACCREAD_ACCREAD_Msk (0xFFFFFFFFUL << QDEC_ACCREAD_ACCREAD_Pos) /*!< Bit mask of ACCREAD field. */ + +/* Register: QDEC_PSEL_LED */ +/* Description: Pin select for LED signal */ + +/* Bit 31 : Connection */ +#define QDEC_PSEL_LED_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QDEC_PSEL_LED_CONNECT_Msk (0x1UL << QDEC_PSEL_LED_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QDEC_PSEL_LED_CONNECT_Connected (0UL) /*!< Connect */ +#define QDEC_PSEL_LED_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define QDEC_PSEL_LED_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QDEC_PSEL_LED_PORT_Msk (0x3UL << QDEC_PSEL_LED_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QDEC_PSEL_LED_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QDEC_PSEL_LED_PIN_Msk (0x1FUL << QDEC_PSEL_LED_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QDEC_PSEL_A */ +/* Description: Pin select for A signal */ + +/* Bit 31 : Connection */ +#define QDEC_PSEL_A_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QDEC_PSEL_A_CONNECT_Msk (0x1UL << QDEC_PSEL_A_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QDEC_PSEL_A_CONNECT_Connected (0UL) /*!< Connect */ +#define QDEC_PSEL_A_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define QDEC_PSEL_A_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QDEC_PSEL_A_PORT_Msk (0x3UL << QDEC_PSEL_A_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QDEC_PSEL_A_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QDEC_PSEL_A_PIN_Msk (0x1FUL << QDEC_PSEL_A_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QDEC_PSEL_B */ +/* Description: Pin select for B signal */ + +/* Bit 31 : Connection */ +#define QDEC_PSEL_B_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QDEC_PSEL_B_CONNECT_Msk (0x1UL << QDEC_PSEL_B_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QDEC_PSEL_B_CONNECT_Connected (0UL) /*!< Connect */ +#define QDEC_PSEL_B_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define QDEC_PSEL_B_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QDEC_PSEL_B_PORT_Msk (0x3UL << QDEC_PSEL_B_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QDEC_PSEL_B_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QDEC_PSEL_B_PIN_Msk (0x1FUL << QDEC_PSEL_B_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QDEC_DBFEN */ +/* Description: Enable input debounce filters */ + +/* Bit 0 : Enable input debounce filters */ +#define QDEC_DBFEN_DBFEN_Pos (0UL) /*!< Position of DBFEN field. */ +#define QDEC_DBFEN_DBFEN_Msk (0x1UL << QDEC_DBFEN_DBFEN_Pos) /*!< Bit mask of DBFEN field. */ +#define QDEC_DBFEN_DBFEN_Disabled (0UL) /*!< Debounce input filters disabled */ +#define QDEC_DBFEN_DBFEN_Enabled (1UL) /*!< Debounce input filters enabled */ + +/* Register: QDEC_LEDPRE */ +/* Description: Time period the LED is switched ON prior to sampling */ + +/* Bits 8..0 : Period in us the LED is switched on prior to sampling */ +#define QDEC_LEDPRE_LEDPRE_Pos (0UL) /*!< Position of LEDPRE field. */ +#define QDEC_LEDPRE_LEDPRE_Msk (0x1FFUL << QDEC_LEDPRE_LEDPRE_Pos) /*!< Bit mask of LEDPRE field. */ + +/* Register: QDEC_ACCDBL */ +/* Description: Register accumulating the number of detected double transitions */ + +/* Bits 3..0 : Register accumulating the number of detected double or illegal transitions. ( SAMPLE = 2 ). */ +#define QDEC_ACCDBL_ACCDBL_Pos (0UL) /*!< Position of ACCDBL field. */ +#define QDEC_ACCDBL_ACCDBL_Msk (0xFUL << QDEC_ACCDBL_ACCDBL_Pos) /*!< Bit mask of ACCDBL field. */ + +/* Register: QDEC_ACCDBLREAD */ +/* Description: Snapshot of the ACCDBL, updated by the READCLRACC or RDCLRDBL task */ + +/* Bits 3..0 : Snapshot of the ACCDBL register. This field is updated when the READCLRACC or RDCLRDBL task is triggered. */ +#define QDEC_ACCDBLREAD_ACCDBLREAD_Pos (0UL) /*!< Position of ACCDBLREAD field. */ +#define QDEC_ACCDBLREAD_ACCDBLREAD_Msk (0xFUL << QDEC_ACCDBLREAD_ACCDBLREAD_Pos) /*!< Bit mask of ACCDBLREAD field. */ + + +/* Peripheral: QSPI */ +/* Description: External flash interface */ + +/* Register: QSPI_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 0 : Enable or disable interrupt for READY event */ +#define QSPI_INTEN_READY_Pos (0UL) /*!< Position of READY field. */ +#define QSPI_INTEN_READY_Msk (0x1UL << QSPI_INTEN_READY_Pos) /*!< Bit mask of READY field. */ +#define QSPI_INTEN_READY_Disabled (0UL) /*!< Disable */ +#define QSPI_INTEN_READY_Enabled (1UL) /*!< Enable */ + +/* Register: QSPI_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 0 : Write '1' to Enable interrupt for READY event */ +#define QSPI_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ +#define QSPI_INTENSET_READY_Msk (0x1UL << QSPI_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ +#define QSPI_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ +#define QSPI_INTENSET_READY_Enabled (1UL) /*!< Read: Enabled */ +#define QSPI_INTENSET_READY_Set (1UL) /*!< Enable */ + +/* Register: QSPI_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 0 : Write '1' to Disable interrupt for READY event */ +#define QSPI_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ +#define QSPI_INTENCLR_READY_Msk (0x1UL << QSPI_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ +#define QSPI_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ +#define QSPI_INTENCLR_READY_Enabled (1UL) /*!< Read: Enabled */ +#define QSPI_INTENCLR_READY_Clear (1UL) /*!< Disable */ + +/* Register: QSPI_ENABLE */ +/* Description: Enable QSPI peripheral and acquire the pins selected in PSELn registers */ + +/* Bit 0 : Enable or disable QSPI */ +#define QSPI_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define QSPI_ENABLE_ENABLE_Msk (0x1UL << QSPI_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define QSPI_ENABLE_ENABLE_Disabled (0UL) /*!< Disable QSPI */ +#define QSPI_ENABLE_ENABLE_Enabled (1UL) /*!< Enable QSPI */ + +/* Register: QSPI_READ_SRC */ +/* Description: Flash memory source address */ + +/* Bits 31..0 : Word-aligned flash memory source address. */ +#define QSPI_READ_SRC_SRC_Pos (0UL) /*!< Position of SRC field. */ +#define QSPI_READ_SRC_SRC_Msk (0xFFFFFFFFUL << QSPI_READ_SRC_SRC_Pos) /*!< Bit mask of SRC field. */ + +/* Register: QSPI_READ_DST */ +/* Description: RAM destination address */ + +/* Bits 31..0 : Word-aligned RAM destination address. */ +#define QSPI_READ_DST_DST_Pos (0UL) /*!< Position of DST field. */ +#define QSPI_READ_DST_DST_Msk (0xFFFFFFFFUL << QSPI_READ_DST_DST_Pos) /*!< Bit mask of DST field. */ + +/* Register: QSPI_READ_CNT */ +/* Description: Read transfer length */ + +/* Bits 20..0 : Read transfer length in number of bytes. The length must be a multiple of 4 bytes. */ +#define QSPI_READ_CNT_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define QSPI_READ_CNT_CNT_Msk (0x1FFFFFUL << QSPI_READ_CNT_CNT_Pos) /*!< Bit mask of CNT field. */ + +/* Register: QSPI_WRITE_DST */ +/* Description: Flash destination address */ + +/* Bits 31..0 : Word-aligned flash destination address. */ +#define QSPI_WRITE_DST_DST_Pos (0UL) /*!< Position of DST field. */ +#define QSPI_WRITE_DST_DST_Msk (0xFFFFFFFFUL << QSPI_WRITE_DST_DST_Pos) /*!< Bit mask of DST field. */ + +/* Register: QSPI_WRITE_SRC */ +/* Description: RAM source address */ + +/* Bits 31..0 : Word-aligned RAM source address. */ +#define QSPI_WRITE_SRC_SRC_Pos (0UL) /*!< Position of SRC field. */ +#define QSPI_WRITE_SRC_SRC_Msk (0xFFFFFFFFUL << QSPI_WRITE_SRC_SRC_Pos) /*!< Bit mask of SRC field. */ + +/* Register: QSPI_WRITE_CNT */ +/* Description: Write transfer length */ + +/* Bits 20..0 : Write transfer length in number of bytes. The length must be a multiple of 4 bytes. */ +#define QSPI_WRITE_CNT_CNT_Pos (0UL) /*!< Position of CNT field. */ +#define QSPI_WRITE_CNT_CNT_Msk (0x1FFFFFUL << QSPI_WRITE_CNT_CNT_Pos) /*!< Bit mask of CNT field. */ + +/* Register: QSPI_ERASE_PTR */ +/* Description: Start address of flash block to be erased */ + +/* Bits 31..0 : Word-aligned start address of block to be erased. */ +#define QSPI_ERASE_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define QSPI_ERASE_PTR_PTR_Msk (0xFFFFFFFFUL << QSPI_ERASE_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: QSPI_ERASE_LEN */ +/* Description: Size of block to be erased. */ + +/* Bits 1..0 : LEN */ +#define QSPI_ERASE_LEN_LEN_Pos (0UL) /*!< Position of LEN field. */ +#define QSPI_ERASE_LEN_LEN_Msk (0x3UL << QSPI_ERASE_LEN_LEN_Pos) /*!< Bit mask of LEN field. */ +#define QSPI_ERASE_LEN_LEN_4KB (0UL) /*!< Erase 4 kB block (flash command 0x20) */ +#define QSPI_ERASE_LEN_LEN_64KB (1UL) /*!< Erase 64 kB block (flash command 0xD8) */ +#define QSPI_ERASE_LEN_LEN_All (2UL) /*!< Erase all (flash command 0xC7) */ + +/* Register: QSPI_PSEL_SCK */ +/* Description: Pin select for serial clock SCK */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_SCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_SCK_CONNECT_Msk (0x1UL << QSPI_PSEL_SCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_SCK_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_SCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define QSPI_PSEL_SCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_SCK_PORT_Msk (0x3UL << QSPI_PSEL_SCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_SCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_SCK_PIN_Msk (0x1FUL << QSPI_PSEL_SCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_PSEL_CSN */ +/* Description: Pin select for chip select signal CSN. */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_CSN_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_CSN_CONNECT_Msk (0x1UL << QSPI_PSEL_CSN_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_CSN_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_CSN_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define QSPI_PSEL_CSN_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_CSN_PORT_Msk (0x3UL << QSPI_PSEL_CSN_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_CSN_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_CSN_PIN_Msk (0x1FUL << QSPI_PSEL_CSN_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_PSEL_IO0 */ +/* Description: Pin select for serial data MOSI/IO0. */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_IO0_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_IO0_CONNECT_Msk (0x1UL << QSPI_PSEL_IO0_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_IO0_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_IO0_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define QSPI_PSEL_IO0_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_IO0_PORT_Msk (0x3UL << QSPI_PSEL_IO0_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_IO0_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_IO0_PIN_Msk (0x1FUL << QSPI_PSEL_IO0_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_PSEL_IO1 */ +/* Description: Pin select for serial data MISO/IO1. */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_IO1_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_IO1_CONNECT_Msk (0x1UL << QSPI_PSEL_IO1_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_IO1_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_IO1_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define QSPI_PSEL_IO1_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_IO1_PORT_Msk (0x3UL << QSPI_PSEL_IO1_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_IO1_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_IO1_PIN_Msk (0x1FUL << QSPI_PSEL_IO1_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_PSEL_IO2 */ +/* Description: Pin select for serial data IO2. */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_IO2_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_IO2_CONNECT_Msk (0x1UL << QSPI_PSEL_IO2_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_IO2_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_IO2_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define QSPI_PSEL_IO2_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_IO2_PORT_Msk (0x3UL << QSPI_PSEL_IO2_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_IO2_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_IO2_PIN_Msk (0x1FUL << QSPI_PSEL_IO2_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_PSEL_IO3 */ +/* Description: Pin select for serial data IO3. */ + +/* Bit 31 : Connection */ +#define QSPI_PSEL_IO3_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define QSPI_PSEL_IO3_CONNECT_Msk (0x1UL << QSPI_PSEL_IO3_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define QSPI_PSEL_IO3_CONNECT_Connected (0UL) /*!< Connect */ +#define QSPI_PSEL_IO3_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define QSPI_PSEL_IO3_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define QSPI_PSEL_IO3_PORT_Msk (0x3UL << QSPI_PSEL_IO3_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define QSPI_PSEL_IO3_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define QSPI_PSEL_IO3_PIN_Msk (0x1FUL << QSPI_PSEL_IO3_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: QSPI_XIPOFFSET */ +/* Description: Address offset into the external memory for Execute in Place operation. */ + +/* Bits 31..0 : Address offset into the external memory for Execute in Place operation. Value must be a multiple of 4. */ +#define QSPI_XIPOFFSET_XIPOFFSET_Pos (0UL) /*!< Position of XIPOFFSET field. */ +#define QSPI_XIPOFFSET_XIPOFFSET_Msk (0xFFFFFFFFUL << QSPI_XIPOFFSET_XIPOFFSET_Pos) /*!< Bit mask of XIPOFFSET field. */ + +/* Register: QSPI_IFCONFIG0 */ +/* Description: Interface configuration. */ + +/* Bit 7 : Enable deep power-down mode (DPM) feature. */ +#define QSPI_IFCONFIG0_DPMENABLE_Pos (7UL) /*!< Position of DPMENABLE field. */ +#define QSPI_IFCONFIG0_DPMENABLE_Msk (0x1UL << QSPI_IFCONFIG0_DPMENABLE_Pos) /*!< Bit mask of DPMENABLE field. */ +#define QSPI_IFCONFIG0_DPMENABLE_Disable (0UL) /*!< Disable DPM feature. */ +#define QSPI_IFCONFIG0_DPMENABLE_Enable (1UL) /*!< Enable DPM feature. */ + +/* Bit 6 : Addressing mode. */ +#define QSPI_IFCONFIG0_ADDRMODE_Pos (6UL) /*!< Position of ADDRMODE field. */ +#define QSPI_IFCONFIG0_ADDRMODE_Msk (0x1UL << QSPI_IFCONFIG0_ADDRMODE_Pos) /*!< Bit mask of ADDRMODE field. */ +#define QSPI_IFCONFIG0_ADDRMODE_24BIT (0UL) /*!< 24-bit addressing. */ +#define QSPI_IFCONFIG0_ADDRMODE_32BIT (1UL) /*!< 32-bit addressing. */ + +/* Bits 5..3 : Configure number of data lines and opcode used for writing. */ +#define QSPI_IFCONFIG0_WRITEOC_Pos (3UL) /*!< Position of WRITEOC field. */ +#define QSPI_IFCONFIG0_WRITEOC_Msk (0x7UL << QSPI_IFCONFIG0_WRITEOC_Pos) /*!< Bit mask of WRITEOC field. */ +#define QSPI_IFCONFIG0_WRITEOC_PP (0UL) /*!< Single data line SPI. PP (opcode 0x02). */ +#define QSPI_IFCONFIG0_WRITEOC_PP2O (1UL) /*!< Dual data line SPI. PP2O (opcode 0xA2). */ +#define QSPI_IFCONFIG0_WRITEOC_PP4O (2UL) /*!< Quad data line SPI. PP4O (opcode 0x32). */ +#define QSPI_IFCONFIG0_WRITEOC_PP4IO (3UL) /*!< Quad data line SPI. PP4IO (opcode 0x38). */ + +/* Bits 2..0 : Configure number of data lines and opcode used for reading. */ +#define QSPI_IFCONFIG0_READOC_Pos (0UL) /*!< Position of READOC field. */ +#define QSPI_IFCONFIG0_READOC_Msk (0x7UL << QSPI_IFCONFIG0_READOC_Pos) /*!< Bit mask of READOC field. */ +#define QSPI_IFCONFIG0_READOC_FASTREAD (0UL) /*!< Single data line SPI. FAST_READ (opcode 0x0B). */ +#define QSPI_IFCONFIG0_READOC_READ2O (1UL) /*!< Dual data line SPI. READ2O (opcode 0x3B). */ +#define QSPI_IFCONFIG0_READOC_READ2IO (2UL) /*!< Dual data line SPI. READ2IO (opcode 0xBB). */ +#define QSPI_IFCONFIG0_READOC_READ4O (3UL) /*!< Quad data line SPI. READ4O (opcode 0x6B). */ +#define QSPI_IFCONFIG0_READOC_READ4IO (4UL) /*!< Quad data line SPI. READ4IO (opcode 0xEB). */ + +/* Register: QSPI_IFCONFIG1 */ +/* Description: Interface configuration. */ + +/* Bits 31..28 : SCK frequency is given as 32 MHz / (SCKFREQ + 1). */ +#define QSPI_IFCONFIG1_SCKFREQ_Pos (28UL) /*!< Position of SCKFREQ field. */ +#define QSPI_IFCONFIG1_SCKFREQ_Msk (0xFUL << QSPI_IFCONFIG1_SCKFREQ_Pos) /*!< Bit mask of SCKFREQ field. */ + +/* Bit 25 : Select SPI mode. */ +#define QSPI_IFCONFIG1_SPIMODE_Pos (25UL) /*!< Position of SPIMODE field. */ +#define QSPI_IFCONFIG1_SPIMODE_Msk (0x1UL << QSPI_IFCONFIG1_SPIMODE_Pos) /*!< Bit mask of SPIMODE field. */ +#define QSPI_IFCONFIG1_SPIMODE_MODE0 (0UL) /*!< Mode 0: Data are captured on the clock's rising edge and data is output on a falling edge. Base level of clock is 0 (CPOL=0, CPHA=0). */ +#define QSPI_IFCONFIG1_SPIMODE_MODE3 (1UL) /*!< Mode 3: Data are captured on the clock's falling edge and data is output on a rising edge. Base level of clock is 1 (CPOL=1, CPHA=1). */ + +/* Bit 24 : Enter/exit deep power-down mode (DPM) for external flash memory. */ +#define QSPI_IFCONFIG1_DPMEN_Pos (24UL) /*!< Position of DPMEN field. */ +#define QSPI_IFCONFIG1_DPMEN_Msk (0x1UL << QSPI_IFCONFIG1_DPMEN_Pos) /*!< Bit mask of DPMEN field. */ +#define QSPI_IFCONFIG1_DPMEN_Exit (0UL) /*!< Exit DPM. */ +#define QSPI_IFCONFIG1_DPMEN_Enter (1UL) /*!< Enter DPM. */ + +/* Bits 7..0 : Minimum amount of time that the CSN pin must stay high before it can go low again. Value is specified in number of 16 MHz periods (62.5 ns). */ +#define QSPI_IFCONFIG1_SCKDELAY_Pos (0UL) /*!< Position of SCKDELAY field. */ +#define QSPI_IFCONFIG1_SCKDELAY_Msk (0xFFUL << QSPI_IFCONFIG1_SCKDELAY_Pos) /*!< Bit mask of SCKDELAY field. */ + +/* Register: QSPI_STATUS */ +/* Description: Status register. */ + +/* Bits 31..24 : Value of external flash devices Status Register. When the external flash has two bytes status register this field includes the value of the low byte. */ +#define QSPI_STATUS_SREG_Pos (24UL) /*!< Position of SREG field. */ +#define QSPI_STATUS_SREG_Msk (0xFFUL << QSPI_STATUS_SREG_Pos) /*!< Bit mask of SREG field. */ + +/* Bit 3 : Ready status. */ +#define QSPI_STATUS_READY_Pos (3UL) /*!< Position of READY field. */ +#define QSPI_STATUS_READY_Msk (0x1UL << QSPI_STATUS_READY_Pos) /*!< Bit mask of READY field. */ +#define QSPI_STATUS_READY_BUSY (0UL) /*!< QSPI peripheral is busy. It is not allowed to trigger any new tasks, writing custom instructions or enter/exit DPM. */ +#define QSPI_STATUS_READY_READY (1UL) /*!< QSPI peripheral is ready. It is allowed to trigger new tasks, writing custom instructions or enter/exit DPM. */ + +/* Bit 2 : Deep power-down mode (DPM) status of external flash. */ +#define QSPI_STATUS_DPM_Pos (2UL) /*!< Position of DPM field. */ +#define QSPI_STATUS_DPM_Msk (0x1UL << QSPI_STATUS_DPM_Pos) /*!< Bit mask of DPM field. */ +#define QSPI_STATUS_DPM_Disabled (0UL) /*!< External flash is not in DPM. */ +#define QSPI_STATUS_DPM_Enabled (1UL) /*!< External flash is in DPM. */ + +/* Register: QSPI_DPMDUR */ +/* Description: Set the duration required to enter/exit deep power-down mode (DPM). */ + +/* Bits 31..16 : Duration needed by external flash to exit DPM. Duration is given as EXIT * 256 * 62.5 ns. */ +#define QSPI_DPMDUR_EXIT_Pos (16UL) /*!< Position of EXIT field. */ +#define QSPI_DPMDUR_EXIT_Msk (0xFFFFUL << QSPI_DPMDUR_EXIT_Pos) /*!< Bit mask of EXIT field. */ + +/* Bits 15..0 : Duration needed by external flash to enter DPM. Duration is given as ENTER * 256 * 62.5 ns. */ +#define QSPI_DPMDUR_ENTER_Pos (0UL) /*!< Position of ENTER field. */ +#define QSPI_DPMDUR_ENTER_Msk (0xFFFFUL << QSPI_DPMDUR_ENTER_Pos) /*!< Bit mask of ENTER field. */ + +/* Register: QSPI_ADDRCONF */ +/* Description: Extended address configuration. */ + +/* Bit 27 : Send WREN (write enable opcode 0x06) before instruction. */ +#define QSPI_ADDRCONF_WREN_Pos (27UL) /*!< Position of WREN field. */ +#define QSPI_ADDRCONF_WREN_Msk (0x1UL << QSPI_ADDRCONF_WREN_Pos) /*!< Bit mask of WREN field. */ +#define QSPI_ADDRCONF_WREN_Disable (0UL) /*!< Do not send WREN. */ +#define QSPI_ADDRCONF_WREN_Enable (1UL) /*!< Send WREN. */ + +/* Bit 26 : Wait for write complete before sending command. */ +#define QSPI_ADDRCONF_WIPWAIT_Pos (26UL) /*!< Position of WIPWAIT field. */ +#define QSPI_ADDRCONF_WIPWAIT_Msk (0x1UL << QSPI_ADDRCONF_WIPWAIT_Pos) /*!< Bit mask of WIPWAIT field. */ +#define QSPI_ADDRCONF_WIPWAIT_Disable (0UL) /*!< No wait. */ +#define QSPI_ADDRCONF_WIPWAIT_Enable (1UL) /*!< Wait. */ + +/* Bits 25..24 : Extended addressing mode. */ +#define QSPI_ADDRCONF_MODE_Pos (24UL) /*!< Position of MODE field. */ +#define QSPI_ADDRCONF_MODE_Msk (0x3UL << QSPI_ADDRCONF_MODE_Pos) /*!< Bit mask of MODE field. */ +#define QSPI_ADDRCONF_MODE_NoInstr (0UL) /*!< Do not send any instruction. */ +#define QSPI_ADDRCONF_MODE_Opcode (1UL) /*!< Send opcode. */ +#define QSPI_ADDRCONF_MODE_OpByte0 (2UL) /*!< Send opcode, byte0. */ +#define QSPI_ADDRCONF_MODE_All (3UL) /*!< Send opcode, byte0, byte1. */ + +/* Bits 23..16 : Byte 1 following byte 0. */ +#define QSPI_ADDRCONF_BYTE1_Pos (16UL) /*!< Position of BYTE1 field. */ +#define QSPI_ADDRCONF_BYTE1_Msk (0xFFUL << QSPI_ADDRCONF_BYTE1_Pos) /*!< Bit mask of BYTE1 field. */ + +/* Bits 15..8 : Byte 0 following opcode. */ +#define QSPI_ADDRCONF_BYTE0_Pos (8UL) /*!< Position of BYTE0 field. */ +#define QSPI_ADDRCONF_BYTE0_Msk (0xFFUL << QSPI_ADDRCONF_BYTE0_Pos) /*!< Bit mask of BYTE0 field. */ + +/* Bits 7..0 : Opcode that enters the 32-bit addressing mode. */ +#define QSPI_ADDRCONF_OPCODE_Pos (0UL) /*!< Position of OPCODE field. */ +#define QSPI_ADDRCONF_OPCODE_Msk (0xFFUL << QSPI_ADDRCONF_OPCODE_Pos) /*!< Bit mask of OPCODE field. */ + +/* Register: QSPI_CINSTRCONF */ +/* Description: Custom instruction configuration register. */ + +/* Bit 15 : Send WREN (write enable opcode 0x06) before instruction. */ +#define QSPI_CINSTRCONF_WREN_Pos (15UL) /*!< Position of WREN field. */ +#define QSPI_CINSTRCONF_WREN_Msk (0x1UL << QSPI_CINSTRCONF_WREN_Pos) /*!< Bit mask of WREN field. */ +#define QSPI_CINSTRCONF_WREN_Disable (0UL) /*!< Do not send WREN. */ +#define QSPI_CINSTRCONF_WREN_Enable (1UL) /*!< Send WREN. */ + +/* Bit 14 : Wait for write complete before sending command. */ +#define QSPI_CINSTRCONF_WIPWAIT_Pos (14UL) /*!< Position of WIPWAIT field. */ +#define QSPI_CINSTRCONF_WIPWAIT_Msk (0x1UL << QSPI_CINSTRCONF_WIPWAIT_Pos) /*!< Bit mask of WIPWAIT field. */ +#define QSPI_CINSTRCONF_WIPWAIT_Disable (0UL) /*!< No wait. */ +#define QSPI_CINSTRCONF_WIPWAIT_Enable (1UL) /*!< Wait. */ + +/* Bit 13 : Level of the IO3 pin (if connected) during transmission of custom instruction. */ +#define QSPI_CINSTRCONF_LIO3_Pos (13UL) /*!< Position of LIO3 field. */ +#define QSPI_CINSTRCONF_LIO3_Msk (0x1UL << QSPI_CINSTRCONF_LIO3_Pos) /*!< Bit mask of LIO3 field. */ + +/* Bit 12 : Level of the IO2 pin (if connected) during transmission of custom instruction. */ +#define QSPI_CINSTRCONF_LIO2_Pos (12UL) /*!< Position of LIO2 field. */ +#define QSPI_CINSTRCONF_LIO2_Msk (0x1UL << QSPI_CINSTRCONF_LIO2_Pos) /*!< Bit mask of LIO2 field. */ + +/* Bits 11..8 : Length of custom instruction in number of bytes. */ +#define QSPI_CINSTRCONF_LENGTH_Pos (8UL) /*!< Position of LENGTH field. */ +#define QSPI_CINSTRCONF_LENGTH_Msk (0xFUL << QSPI_CINSTRCONF_LENGTH_Pos) /*!< Bit mask of LENGTH field. */ +#define QSPI_CINSTRCONF_LENGTH_1B (1UL) /*!< Send opcode only. */ +#define QSPI_CINSTRCONF_LENGTH_2B (2UL) /*!< Send opcode, CINSTRDAT0.BYTE0. */ +#define QSPI_CINSTRCONF_LENGTH_3B (3UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE1. */ +#define QSPI_CINSTRCONF_LENGTH_4B (4UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE2. */ +#define QSPI_CINSTRCONF_LENGTH_5B (5UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE3. */ +#define QSPI_CINSTRCONF_LENGTH_6B (6UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE4. */ +#define QSPI_CINSTRCONF_LENGTH_7B (7UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE5. */ +#define QSPI_CINSTRCONF_LENGTH_8B (8UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE6. */ +#define QSPI_CINSTRCONF_LENGTH_9B (9UL) /*!< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE7. */ + +/* Bits 7..0 : Opcode of Custom instruction. */ +#define QSPI_CINSTRCONF_OPCODE_Pos (0UL) /*!< Position of OPCODE field. */ +#define QSPI_CINSTRCONF_OPCODE_Msk (0xFFUL << QSPI_CINSTRCONF_OPCODE_Pos) /*!< Bit mask of OPCODE field. */ + +/* Register: QSPI_CINSTRDAT0 */ +/* Description: Custom instruction data register 0. */ + +/* Bits 31..24 : Data byte 3 */ +#define QSPI_CINSTRDAT0_BYTE3_Pos (24UL) /*!< Position of BYTE3 field. */ +#define QSPI_CINSTRDAT0_BYTE3_Msk (0xFFUL << QSPI_CINSTRDAT0_BYTE3_Pos) /*!< Bit mask of BYTE3 field. */ + +/* Bits 23..16 : Data byte 2 */ +#define QSPI_CINSTRDAT0_BYTE2_Pos (16UL) /*!< Position of BYTE2 field. */ +#define QSPI_CINSTRDAT0_BYTE2_Msk (0xFFUL << QSPI_CINSTRDAT0_BYTE2_Pos) /*!< Bit mask of BYTE2 field. */ + +/* Bits 15..8 : Data byte 1 */ +#define QSPI_CINSTRDAT0_BYTE1_Pos (8UL) /*!< Position of BYTE1 field. */ +#define QSPI_CINSTRDAT0_BYTE1_Msk (0xFFUL << QSPI_CINSTRDAT0_BYTE1_Pos) /*!< Bit mask of BYTE1 field. */ + +/* Bits 7..0 : Data byte 0 */ +#define QSPI_CINSTRDAT0_BYTE0_Pos (0UL) /*!< Position of BYTE0 field. */ +#define QSPI_CINSTRDAT0_BYTE0_Msk (0xFFUL << QSPI_CINSTRDAT0_BYTE0_Pos) /*!< Bit mask of BYTE0 field. */ + +/* Register: QSPI_CINSTRDAT1 */ +/* Description: Custom instruction data register 1. */ + +/* Bits 31..24 : Data byte 7 */ +#define QSPI_CINSTRDAT1_BYTE7_Pos (24UL) /*!< Position of BYTE7 field. */ +#define QSPI_CINSTRDAT1_BYTE7_Msk (0xFFUL << QSPI_CINSTRDAT1_BYTE7_Pos) /*!< Bit mask of BYTE7 field. */ + +/* Bits 23..16 : Data byte 6 */ +#define QSPI_CINSTRDAT1_BYTE6_Pos (16UL) /*!< Position of BYTE6 field. */ +#define QSPI_CINSTRDAT1_BYTE6_Msk (0xFFUL << QSPI_CINSTRDAT1_BYTE6_Pos) /*!< Bit mask of BYTE6 field. */ + +/* Bits 15..8 : Data byte 5 */ +#define QSPI_CINSTRDAT1_BYTE5_Pos (8UL) /*!< Position of BYTE5 field. */ +#define QSPI_CINSTRDAT1_BYTE5_Msk (0xFFUL << QSPI_CINSTRDAT1_BYTE5_Pos) /*!< Bit mask of BYTE5 field. */ + +/* Bits 7..0 : Data byte 4 */ +#define QSPI_CINSTRDAT1_BYTE4_Pos (0UL) /*!< Position of BYTE4 field. */ +#define QSPI_CINSTRDAT1_BYTE4_Msk (0xFFUL << QSPI_CINSTRDAT1_BYTE4_Pos) /*!< Bit mask of BYTE4 field. */ + +/* Register: QSPI_IFTIMING */ +/* Description: SPI interface timing. */ + +/* Bits 10..8 : Timing related to sampling of the input serial data. The value of RXDELAY specifies the number of 64 MHz cycles (15.625 ns) delay from the the rising edge of the SPI Clock (SCK) until the input serial data is sampled. As en example, if set to 0 the input serial data is sampled on the rising edge of SCK. */ +#define QSPI_IFTIMING_RXDELAY_Pos (8UL) /*!< Position of RXDELAY field. */ +#define QSPI_IFTIMING_RXDELAY_Msk (0x7UL << QSPI_IFTIMING_RXDELAY_Pos) /*!< Bit mask of RXDELAY field. */ + + +/* Peripheral: RADIO */ +/* Description: 2.4 GHz Radio */ + +/* Register: RADIO_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 19 : Shortcut between RXREADY event and START task */ +#define RADIO_SHORTS_RXREADY_START_Pos (19UL) /*!< Position of RXREADY_START field. */ +#define RADIO_SHORTS_RXREADY_START_Msk (0x1UL << RADIO_SHORTS_RXREADY_START_Pos) /*!< Bit mask of RXREADY_START field. */ +#define RADIO_SHORTS_RXREADY_START_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_RXREADY_START_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 18 : Shortcut between TXREADY event and START task */ +#define RADIO_SHORTS_TXREADY_START_Pos (18UL) /*!< Position of TXREADY_START field. */ +#define RADIO_SHORTS_TXREADY_START_Msk (0x1UL << RADIO_SHORTS_TXREADY_START_Pos) /*!< Bit mask of TXREADY_START field. */ +#define RADIO_SHORTS_TXREADY_START_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_TXREADY_START_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 17 : Shortcut between CCAIDLE event and STOP task */ +#define RADIO_SHORTS_CCAIDLE_STOP_Pos (17UL) /*!< Position of CCAIDLE_STOP field. */ +#define RADIO_SHORTS_CCAIDLE_STOP_Msk (0x1UL << RADIO_SHORTS_CCAIDLE_STOP_Pos) /*!< Bit mask of CCAIDLE_STOP field. */ +#define RADIO_SHORTS_CCAIDLE_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_CCAIDLE_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 16 : Shortcut between EDEND event and DISABLE task */ +#define RADIO_SHORTS_EDEND_DISABLE_Pos (16UL) /*!< Position of EDEND_DISABLE field. */ +#define RADIO_SHORTS_EDEND_DISABLE_Msk (0x1UL << RADIO_SHORTS_EDEND_DISABLE_Pos) /*!< Bit mask of EDEND_DISABLE field. */ +#define RADIO_SHORTS_EDEND_DISABLE_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_EDEND_DISABLE_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 15 : Shortcut between READY event and EDSTART task */ +#define RADIO_SHORTS_READY_EDSTART_Pos (15UL) /*!< Position of READY_EDSTART field. */ +#define RADIO_SHORTS_READY_EDSTART_Msk (0x1UL << RADIO_SHORTS_READY_EDSTART_Pos) /*!< Bit mask of READY_EDSTART field. */ +#define RADIO_SHORTS_READY_EDSTART_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_READY_EDSTART_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 14 : Shortcut between FRAMESTART event and BCSTART task */ +#define RADIO_SHORTS_FRAMESTART_BCSTART_Pos (14UL) /*!< Position of FRAMESTART_BCSTART field. */ +#define RADIO_SHORTS_FRAMESTART_BCSTART_Msk (0x1UL << RADIO_SHORTS_FRAMESTART_BCSTART_Pos) /*!< Bit mask of FRAMESTART_BCSTART field. */ +#define RADIO_SHORTS_FRAMESTART_BCSTART_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_FRAMESTART_BCSTART_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 13 : Shortcut between CCABUSY event and DISABLE task */ +#define RADIO_SHORTS_CCABUSY_DISABLE_Pos (13UL) /*!< Position of CCABUSY_DISABLE field. */ +#define RADIO_SHORTS_CCABUSY_DISABLE_Msk (0x1UL << RADIO_SHORTS_CCABUSY_DISABLE_Pos) /*!< Bit mask of CCABUSY_DISABLE field. */ +#define RADIO_SHORTS_CCABUSY_DISABLE_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_CCABUSY_DISABLE_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 12 : Shortcut between CCAIDLE event and TXEN task */ +#define RADIO_SHORTS_CCAIDLE_TXEN_Pos (12UL) /*!< Position of CCAIDLE_TXEN field. */ +#define RADIO_SHORTS_CCAIDLE_TXEN_Msk (0x1UL << RADIO_SHORTS_CCAIDLE_TXEN_Pos) /*!< Bit mask of CCAIDLE_TXEN field. */ +#define RADIO_SHORTS_CCAIDLE_TXEN_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_CCAIDLE_TXEN_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 11 : Shortcut between RXREADY event and CCASTART task */ +#define RADIO_SHORTS_RXREADY_CCASTART_Pos (11UL) /*!< Position of RXREADY_CCASTART field. */ +#define RADIO_SHORTS_RXREADY_CCASTART_Msk (0x1UL << RADIO_SHORTS_RXREADY_CCASTART_Pos) /*!< Bit mask of RXREADY_CCASTART field. */ +#define RADIO_SHORTS_RXREADY_CCASTART_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_RXREADY_CCASTART_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 8 : Shortcut between DISABLED event and RSSISTOP task */ +#define RADIO_SHORTS_DISABLED_RSSISTOP_Pos (8UL) /*!< Position of DISABLED_RSSISTOP field. */ +#define RADIO_SHORTS_DISABLED_RSSISTOP_Msk (0x1UL << RADIO_SHORTS_DISABLED_RSSISTOP_Pos) /*!< Bit mask of DISABLED_RSSISTOP field. */ +#define RADIO_SHORTS_DISABLED_RSSISTOP_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_DISABLED_RSSISTOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 6 : Shortcut between ADDRESS event and BCSTART task */ +#define RADIO_SHORTS_ADDRESS_BCSTART_Pos (6UL) /*!< Position of ADDRESS_BCSTART field. */ +#define RADIO_SHORTS_ADDRESS_BCSTART_Msk (0x1UL << RADIO_SHORTS_ADDRESS_BCSTART_Pos) /*!< Bit mask of ADDRESS_BCSTART field. */ +#define RADIO_SHORTS_ADDRESS_BCSTART_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_ADDRESS_BCSTART_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 5 : Shortcut between END event and START task */ +#define RADIO_SHORTS_END_START_Pos (5UL) /*!< Position of END_START field. */ +#define RADIO_SHORTS_END_START_Msk (0x1UL << RADIO_SHORTS_END_START_Pos) /*!< Bit mask of END_START field. */ +#define RADIO_SHORTS_END_START_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_END_START_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 4 : Shortcut between ADDRESS event and RSSISTART task */ +#define RADIO_SHORTS_ADDRESS_RSSISTART_Pos (4UL) /*!< Position of ADDRESS_RSSISTART field. */ +#define RADIO_SHORTS_ADDRESS_RSSISTART_Msk (0x1UL << RADIO_SHORTS_ADDRESS_RSSISTART_Pos) /*!< Bit mask of ADDRESS_RSSISTART field. */ +#define RADIO_SHORTS_ADDRESS_RSSISTART_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_ADDRESS_RSSISTART_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between DISABLED event and RXEN task */ +#define RADIO_SHORTS_DISABLED_RXEN_Pos (3UL) /*!< Position of DISABLED_RXEN field. */ +#define RADIO_SHORTS_DISABLED_RXEN_Msk (0x1UL << RADIO_SHORTS_DISABLED_RXEN_Pos) /*!< Bit mask of DISABLED_RXEN field. */ +#define RADIO_SHORTS_DISABLED_RXEN_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_DISABLED_RXEN_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between DISABLED event and TXEN task */ +#define RADIO_SHORTS_DISABLED_TXEN_Pos (2UL) /*!< Position of DISABLED_TXEN field. */ +#define RADIO_SHORTS_DISABLED_TXEN_Msk (0x1UL << RADIO_SHORTS_DISABLED_TXEN_Pos) /*!< Bit mask of DISABLED_TXEN field. */ +#define RADIO_SHORTS_DISABLED_TXEN_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_DISABLED_TXEN_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between END event and DISABLE task */ +#define RADIO_SHORTS_END_DISABLE_Pos (1UL) /*!< Position of END_DISABLE field. */ +#define RADIO_SHORTS_END_DISABLE_Msk (0x1UL << RADIO_SHORTS_END_DISABLE_Pos) /*!< Bit mask of END_DISABLE field. */ +#define RADIO_SHORTS_END_DISABLE_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_END_DISABLE_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between READY event and START task */ +#define RADIO_SHORTS_READY_START_Pos (0UL) /*!< Position of READY_START field. */ +#define RADIO_SHORTS_READY_START_Msk (0x1UL << RADIO_SHORTS_READY_START_Pos) /*!< Bit mask of READY_START field. */ +#define RADIO_SHORTS_READY_START_Disabled (0UL) /*!< Disable shortcut */ +#define RADIO_SHORTS_READY_START_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: RADIO_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 23 : Write '1' to Enable interrupt for MHRMATCH event */ +#define RADIO_INTENSET_MHRMATCH_Pos (23UL) /*!< Position of MHRMATCH field. */ +#define RADIO_INTENSET_MHRMATCH_Msk (0x1UL << RADIO_INTENSET_MHRMATCH_Pos) /*!< Bit mask of MHRMATCH field. */ +#define RADIO_INTENSET_MHRMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_MHRMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_MHRMATCH_Set (1UL) /*!< Enable */ + +/* Bit 22 : Write '1' to Enable interrupt for RXREADY event */ +#define RADIO_INTENSET_RXREADY_Pos (22UL) /*!< Position of RXREADY field. */ +#define RADIO_INTENSET_RXREADY_Msk (0x1UL << RADIO_INTENSET_RXREADY_Pos) /*!< Bit mask of RXREADY field. */ +#define RADIO_INTENSET_RXREADY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_RXREADY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_RXREADY_Set (1UL) /*!< Enable */ + +/* Bit 21 : Write '1' to Enable interrupt for TXREADY event */ +#define RADIO_INTENSET_TXREADY_Pos (21UL) /*!< Position of TXREADY field. */ +#define RADIO_INTENSET_TXREADY_Msk (0x1UL << RADIO_INTENSET_TXREADY_Pos) /*!< Bit mask of TXREADY field. */ +#define RADIO_INTENSET_TXREADY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_TXREADY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_TXREADY_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for RATEBOOST event */ +#define RADIO_INTENSET_RATEBOOST_Pos (20UL) /*!< Position of RATEBOOST field. */ +#define RADIO_INTENSET_RATEBOOST_Msk (0x1UL << RADIO_INTENSET_RATEBOOST_Pos) /*!< Bit mask of RATEBOOST field. */ +#define RADIO_INTENSET_RATEBOOST_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_RATEBOOST_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_RATEBOOST_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for CCASTOPPED event */ +#define RADIO_INTENSET_CCASTOPPED_Pos (19UL) /*!< Position of CCASTOPPED field. */ +#define RADIO_INTENSET_CCASTOPPED_Msk (0x1UL << RADIO_INTENSET_CCASTOPPED_Pos) /*!< Bit mask of CCASTOPPED field. */ +#define RADIO_INTENSET_CCASTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_CCASTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_CCASTOPPED_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for CCABUSY event */ +#define RADIO_INTENSET_CCABUSY_Pos (18UL) /*!< Position of CCABUSY field. */ +#define RADIO_INTENSET_CCABUSY_Msk (0x1UL << RADIO_INTENSET_CCABUSY_Pos) /*!< Bit mask of CCABUSY field. */ +#define RADIO_INTENSET_CCABUSY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_CCABUSY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_CCABUSY_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for CCAIDLE event */ +#define RADIO_INTENSET_CCAIDLE_Pos (17UL) /*!< Position of CCAIDLE field. */ +#define RADIO_INTENSET_CCAIDLE_Msk (0x1UL << RADIO_INTENSET_CCAIDLE_Pos) /*!< Bit mask of CCAIDLE field. */ +#define RADIO_INTENSET_CCAIDLE_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_CCAIDLE_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_CCAIDLE_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable interrupt for EDSTOPPED event */ +#define RADIO_INTENSET_EDSTOPPED_Pos (16UL) /*!< Position of EDSTOPPED field. */ +#define RADIO_INTENSET_EDSTOPPED_Msk (0x1UL << RADIO_INTENSET_EDSTOPPED_Pos) /*!< Bit mask of EDSTOPPED field. */ +#define RADIO_INTENSET_EDSTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_EDSTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_EDSTOPPED_Set (1UL) /*!< Enable */ + +/* Bit 15 : Write '1' to Enable interrupt for EDEND event */ +#define RADIO_INTENSET_EDEND_Pos (15UL) /*!< Position of EDEND field. */ +#define RADIO_INTENSET_EDEND_Msk (0x1UL << RADIO_INTENSET_EDEND_Pos) /*!< Bit mask of EDEND field. */ +#define RADIO_INTENSET_EDEND_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_EDEND_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_EDEND_Set (1UL) /*!< Enable */ + +/* Bit 14 : Write '1' to Enable interrupt for FRAMESTART event */ +#define RADIO_INTENSET_FRAMESTART_Pos (14UL) /*!< Position of FRAMESTART field. */ +#define RADIO_INTENSET_FRAMESTART_Msk (0x1UL << RADIO_INTENSET_FRAMESTART_Pos) /*!< Bit mask of FRAMESTART field. */ +#define RADIO_INTENSET_FRAMESTART_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_FRAMESTART_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_FRAMESTART_Set (1UL) /*!< Enable */ + +/* Bit 13 : Write '1' to Enable interrupt for CRCERROR event */ +#define RADIO_INTENSET_CRCERROR_Pos (13UL) /*!< Position of CRCERROR field. */ +#define RADIO_INTENSET_CRCERROR_Msk (0x1UL << RADIO_INTENSET_CRCERROR_Pos) /*!< Bit mask of CRCERROR field. */ +#define RADIO_INTENSET_CRCERROR_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_CRCERROR_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_CRCERROR_Set (1UL) /*!< Enable */ + +/* Bit 12 : Write '1' to Enable interrupt for CRCOK event */ +#define RADIO_INTENSET_CRCOK_Pos (12UL) /*!< Position of CRCOK field. */ +#define RADIO_INTENSET_CRCOK_Msk (0x1UL << RADIO_INTENSET_CRCOK_Pos) /*!< Bit mask of CRCOK field. */ +#define RADIO_INTENSET_CRCOK_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_CRCOK_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_CRCOK_Set (1UL) /*!< Enable */ + +/* Bit 10 : Write '1' to Enable interrupt for BCMATCH event */ +#define RADIO_INTENSET_BCMATCH_Pos (10UL) /*!< Position of BCMATCH field. */ +#define RADIO_INTENSET_BCMATCH_Msk (0x1UL << RADIO_INTENSET_BCMATCH_Pos) /*!< Bit mask of BCMATCH field. */ +#define RADIO_INTENSET_BCMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_BCMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_BCMATCH_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for RSSIEND event */ +#define RADIO_INTENSET_RSSIEND_Pos (7UL) /*!< Position of RSSIEND field. */ +#define RADIO_INTENSET_RSSIEND_Msk (0x1UL << RADIO_INTENSET_RSSIEND_Pos) /*!< Bit mask of RSSIEND field. */ +#define RADIO_INTENSET_RSSIEND_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_RSSIEND_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_RSSIEND_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for DEVMISS event */ +#define RADIO_INTENSET_DEVMISS_Pos (6UL) /*!< Position of DEVMISS field. */ +#define RADIO_INTENSET_DEVMISS_Msk (0x1UL << RADIO_INTENSET_DEVMISS_Pos) /*!< Bit mask of DEVMISS field. */ +#define RADIO_INTENSET_DEVMISS_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_DEVMISS_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_DEVMISS_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for DEVMATCH event */ +#define RADIO_INTENSET_DEVMATCH_Pos (5UL) /*!< Position of DEVMATCH field. */ +#define RADIO_INTENSET_DEVMATCH_Msk (0x1UL << RADIO_INTENSET_DEVMATCH_Pos) /*!< Bit mask of DEVMATCH field. */ +#define RADIO_INTENSET_DEVMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_DEVMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_DEVMATCH_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for DISABLED event */ +#define RADIO_INTENSET_DISABLED_Pos (4UL) /*!< Position of DISABLED field. */ +#define RADIO_INTENSET_DISABLED_Msk (0x1UL << RADIO_INTENSET_DISABLED_Pos) /*!< Bit mask of DISABLED field. */ +#define RADIO_INTENSET_DISABLED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_DISABLED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_DISABLED_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for END event */ +#define RADIO_INTENSET_END_Pos (3UL) /*!< Position of END field. */ +#define RADIO_INTENSET_END_Msk (0x1UL << RADIO_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define RADIO_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for PAYLOAD event */ +#define RADIO_INTENSET_PAYLOAD_Pos (2UL) /*!< Position of PAYLOAD field. */ +#define RADIO_INTENSET_PAYLOAD_Msk (0x1UL << RADIO_INTENSET_PAYLOAD_Pos) /*!< Bit mask of PAYLOAD field. */ +#define RADIO_INTENSET_PAYLOAD_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_PAYLOAD_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_PAYLOAD_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for ADDRESS event */ +#define RADIO_INTENSET_ADDRESS_Pos (1UL) /*!< Position of ADDRESS field. */ +#define RADIO_INTENSET_ADDRESS_Msk (0x1UL << RADIO_INTENSET_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ +#define RADIO_INTENSET_ADDRESS_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_ADDRESS_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_ADDRESS_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for READY event */ +#define RADIO_INTENSET_READY_Pos (0UL) /*!< Position of READY field. */ +#define RADIO_INTENSET_READY_Msk (0x1UL << RADIO_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ +#define RADIO_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENSET_READY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENSET_READY_Set (1UL) /*!< Enable */ + +/* Register: RADIO_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 23 : Write '1' to Disable interrupt for MHRMATCH event */ +#define RADIO_INTENCLR_MHRMATCH_Pos (23UL) /*!< Position of MHRMATCH field. */ +#define RADIO_INTENCLR_MHRMATCH_Msk (0x1UL << RADIO_INTENCLR_MHRMATCH_Pos) /*!< Bit mask of MHRMATCH field. */ +#define RADIO_INTENCLR_MHRMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_MHRMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_MHRMATCH_Clear (1UL) /*!< Disable */ + +/* Bit 22 : Write '1' to Disable interrupt for RXREADY event */ +#define RADIO_INTENCLR_RXREADY_Pos (22UL) /*!< Position of RXREADY field. */ +#define RADIO_INTENCLR_RXREADY_Msk (0x1UL << RADIO_INTENCLR_RXREADY_Pos) /*!< Bit mask of RXREADY field. */ +#define RADIO_INTENCLR_RXREADY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_RXREADY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_RXREADY_Clear (1UL) /*!< Disable */ + +/* Bit 21 : Write '1' to Disable interrupt for TXREADY event */ +#define RADIO_INTENCLR_TXREADY_Pos (21UL) /*!< Position of TXREADY field. */ +#define RADIO_INTENCLR_TXREADY_Msk (0x1UL << RADIO_INTENCLR_TXREADY_Pos) /*!< Bit mask of TXREADY field. */ +#define RADIO_INTENCLR_TXREADY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_TXREADY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_TXREADY_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for RATEBOOST event */ +#define RADIO_INTENCLR_RATEBOOST_Pos (20UL) /*!< Position of RATEBOOST field. */ +#define RADIO_INTENCLR_RATEBOOST_Msk (0x1UL << RADIO_INTENCLR_RATEBOOST_Pos) /*!< Bit mask of RATEBOOST field. */ +#define RADIO_INTENCLR_RATEBOOST_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_RATEBOOST_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_RATEBOOST_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for CCASTOPPED event */ +#define RADIO_INTENCLR_CCASTOPPED_Pos (19UL) /*!< Position of CCASTOPPED field. */ +#define RADIO_INTENCLR_CCASTOPPED_Msk (0x1UL << RADIO_INTENCLR_CCASTOPPED_Pos) /*!< Bit mask of CCASTOPPED field. */ +#define RADIO_INTENCLR_CCASTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_CCASTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_CCASTOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for CCABUSY event */ +#define RADIO_INTENCLR_CCABUSY_Pos (18UL) /*!< Position of CCABUSY field. */ +#define RADIO_INTENCLR_CCABUSY_Msk (0x1UL << RADIO_INTENCLR_CCABUSY_Pos) /*!< Bit mask of CCABUSY field. */ +#define RADIO_INTENCLR_CCABUSY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_CCABUSY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_CCABUSY_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for CCAIDLE event */ +#define RADIO_INTENCLR_CCAIDLE_Pos (17UL) /*!< Position of CCAIDLE field. */ +#define RADIO_INTENCLR_CCAIDLE_Msk (0x1UL << RADIO_INTENCLR_CCAIDLE_Pos) /*!< Bit mask of CCAIDLE field. */ +#define RADIO_INTENCLR_CCAIDLE_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_CCAIDLE_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_CCAIDLE_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable interrupt for EDSTOPPED event */ +#define RADIO_INTENCLR_EDSTOPPED_Pos (16UL) /*!< Position of EDSTOPPED field. */ +#define RADIO_INTENCLR_EDSTOPPED_Msk (0x1UL << RADIO_INTENCLR_EDSTOPPED_Pos) /*!< Bit mask of EDSTOPPED field. */ +#define RADIO_INTENCLR_EDSTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_EDSTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_EDSTOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 15 : Write '1' to Disable interrupt for EDEND event */ +#define RADIO_INTENCLR_EDEND_Pos (15UL) /*!< Position of EDEND field. */ +#define RADIO_INTENCLR_EDEND_Msk (0x1UL << RADIO_INTENCLR_EDEND_Pos) /*!< Bit mask of EDEND field. */ +#define RADIO_INTENCLR_EDEND_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_EDEND_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_EDEND_Clear (1UL) /*!< Disable */ + +/* Bit 14 : Write '1' to Disable interrupt for FRAMESTART event */ +#define RADIO_INTENCLR_FRAMESTART_Pos (14UL) /*!< Position of FRAMESTART field. */ +#define RADIO_INTENCLR_FRAMESTART_Msk (0x1UL << RADIO_INTENCLR_FRAMESTART_Pos) /*!< Bit mask of FRAMESTART field. */ +#define RADIO_INTENCLR_FRAMESTART_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_FRAMESTART_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_FRAMESTART_Clear (1UL) /*!< Disable */ + +/* Bit 13 : Write '1' to Disable interrupt for CRCERROR event */ +#define RADIO_INTENCLR_CRCERROR_Pos (13UL) /*!< Position of CRCERROR field. */ +#define RADIO_INTENCLR_CRCERROR_Msk (0x1UL << RADIO_INTENCLR_CRCERROR_Pos) /*!< Bit mask of CRCERROR field. */ +#define RADIO_INTENCLR_CRCERROR_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_CRCERROR_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_CRCERROR_Clear (1UL) /*!< Disable */ + +/* Bit 12 : Write '1' to Disable interrupt for CRCOK event */ +#define RADIO_INTENCLR_CRCOK_Pos (12UL) /*!< Position of CRCOK field. */ +#define RADIO_INTENCLR_CRCOK_Msk (0x1UL << RADIO_INTENCLR_CRCOK_Pos) /*!< Bit mask of CRCOK field. */ +#define RADIO_INTENCLR_CRCOK_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_CRCOK_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_CRCOK_Clear (1UL) /*!< Disable */ + +/* Bit 10 : Write '1' to Disable interrupt for BCMATCH event */ +#define RADIO_INTENCLR_BCMATCH_Pos (10UL) /*!< Position of BCMATCH field. */ +#define RADIO_INTENCLR_BCMATCH_Msk (0x1UL << RADIO_INTENCLR_BCMATCH_Pos) /*!< Bit mask of BCMATCH field. */ +#define RADIO_INTENCLR_BCMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_BCMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_BCMATCH_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for RSSIEND event */ +#define RADIO_INTENCLR_RSSIEND_Pos (7UL) /*!< Position of RSSIEND field. */ +#define RADIO_INTENCLR_RSSIEND_Msk (0x1UL << RADIO_INTENCLR_RSSIEND_Pos) /*!< Bit mask of RSSIEND field. */ +#define RADIO_INTENCLR_RSSIEND_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_RSSIEND_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_RSSIEND_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for DEVMISS event */ +#define RADIO_INTENCLR_DEVMISS_Pos (6UL) /*!< Position of DEVMISS field. */ +#define RADIO_INTENCLR_DEVMISS_Msk (0x1UL << RADIO_INTENCLR_DEVMISS_Pos) /*!< Bit mask of DEVMISS field. */ +#define RADIO_INTENCLR_DEVMISS_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_DEVMISS_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_DEVMISS_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for DEVMATCH event */ +#define RADIO_INTENCLR_DEVMATCH_Pos (5UL) /*!< Position of DEVMATCH field. */ +#define RADIO_INTENCLR_DEVMATCH_Msk (0x1UL << RADIO_INTENCLR_DEVMATCH_Pos) /*!< Bit mask of DEVMATCH field. */ +#define RADIO_INTENCLR_DEVMATCH_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_DEVMATCH_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_DEVMATCH_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for DISABLED event */ +#define RADIO_INTENCLR_DISABLED_Pos (4UL) /*!< Position of DISABLED field. */ +#define RADIO_INTENCLR_DISABLED_Msk (0x1UL << RADIO_INTENCLR_DISABLED_Pos) /*!< Bit mask of DISABLED field. */ +#define RADIO_INTENCLR_DISABLED_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_DISABLED_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_DISABLED_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for END event */ +#define RADIO_INTENCLR_END_Pos (3UL) /*!< Position of END field. */ +#define RADIO_INTENCLR_END_Msk (0x1UL << RADIO_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define RADIO_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for PAYLOAD event */ +#define RADIO_INTENCLR_PAYLOAD_Pos (2UL) /*!< Position of PAYLOAD field. */ +#define RADIO_INTENCLR_PAYLOAD_Msk (0x1UL << RADIO_INTENCLR_PAYLOAD_Pos) /*!< Bit mask of PAYLOAD field. */ +#define RADIO_INTENCLR_PAYLOAD_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_PAYLOAD_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_PAYLOAD_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for ADDRESS event */ +#define RADIO_INTENCLR_ADDRESS_Pos (1UL) /*!< Position of ADDRESS field. */ +#define RADIO_INTENCLR_ADDRESS_Msk (0x1UL << RADIO_INTENCLR_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ +#define RADIO_INTENCLR_ADDRESS_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_ADDRESS_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_ADDRESS_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for READY event */ +#define RADIO_INTENCLR_READY_Pos (0UL) /*!< Position of READY field. */ +#define RADIO_INTENCLR_READY_Msk (0x1UL << RADIO_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ +#define RADIO_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ +#define RADIO_INTENCLR_READY_Enabled (1UL) /*!< Read: Enabled */ +#define RADIO_INTENCLR_READY_Clear (1UL) /*!< Disable */ + +/* Register: RADIO_CRCSTATUS */ +/* Description: CRC status */ + +/* Bit 0 : CRC status of packet received */ +#define RADIO_CRCSTATUS_CRCSTATUS_Pos (0UL) /*!< Position of CRCSTATUS field. */ +#define RADIO_CRCSTATUS_CRCSTATUS_Msk (0x1UL << RADIO_CRCSTATUS_CRCSTATUS_Pos) /*!< Bit mask of CRCSTATUS field. */ +#define RADIO_CRCSTATUS_CRCSTATUS_CRCError (0UL) /*!< Packet received with CRC error */ +#define RADIO_CRCSTATUS_CRCSTATUS_CRCOk (1UL) /*!< Packet received with CRC ok */ + +/* Register: RADIO_RXMATCH */ +/* Description: Received address */ + +/* Bits 2..0 : Received address */ +#define RADIO_RXMATCH_RXMATCH_Pos (0UL) /*!< Position of RXMATCH field. */ +#define RADIO_RXMATCH_RXMATCH_Msk (0x7UL << RADIO_RXMATCH_RXMATCH_Pos) /*!< Bit mask of RXMATCH field. */ + +/* Register: RADIO_RXCRC */ +/* Description: CRC field of previously received packet */ + +/* Bits 23..0 : CRC field of previously received packet */ +#define RADIO_RXCRC_RXCRC_Pos (0UL) /*!< Position of RXCRC field. */ +#define RADIO_RXCRC_RXCRC_Msk (0xFFFFFFUL << RADIO_RXCRC_RXCRC_Pos) /*!< Bit mask of RXCRC field. */ + +/* Register: RADIO_DAI */ +/* Description: Device address match index */ + +/* Bits 2..0 : Device address match index */ +#define RADIO_DAI_DAI_Pos (0UL) /*!< Position of DAI field. */ +#define RADIO_DAI_DAI_Msk (0x7UL << RADIO_DAI_DAI_Pos) /*!< Bit mask of DAI field. */ + +/* Register: RADIO_PACKETPTR */ +/* Description: Packet pointer */ + +/* Bits 31..0 : Packet pointer */ +#define RADIO_PACKETPTR_PACKETPTR_Pos (0UL) /*!< Position of PACKETPTR field. */ +#define RADIO_PACKETPTR_PACKETPTR_Msk (0xFFFFFFFFUL << RADIO_PACKETPTR_PACKETPTR_Pos) /*!< Bit mask of PACKETPTR field. */ + +/* Register: RADIO_FREQUENCY */ +/* Description: Frequency */ + +/* Bit 8 : Channel map selection. */ +#define RADIO_FREQUENCY_MAP_Pos (8UL) /*!< Position of MAP field. */ +#define RADIO_FREQUENCY_MAP_Msk (0x1UL << RADIO_FREQUENCY_MAP_Pos) /*!< Bit mask of MAP field. */ +#define RADIO_FREQUENCY_MAP_Default (0UL) /*!< Channel map between 2400 MHZ .. 2500 MHz */ +#define RADIO_FREQUENCY_MAP_Low (1UL) /*!< Channel map between 2360 MHZ .. 2460 MHz */ + +/* Bits 6..0 : Radio channel frequency */ +#define RADIO_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ +#define RADIO_FREQUENCY_FREQUENCY_Msk (0x7FUL << RADIO_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ + +/* Register: RADIO_TXPOWER */ +/* Description: Output power */ + +/* Bits 7..0 : RADIO output power. */ +#define RADIO_TXPOWER_TXPOWER_Pos (0UL) /*!< Position of TXPOWER field. */ +#define RADIO_TXPOWER_TXPOWER_Msk (0xFFUL << RADIO_TXPOWER_TXPOWER_Pos) /*!< Bit mask of TXPOWER field. */ +#define RADIO_TXPOWER_TXPOWER_0dBm (0x0UL) /*!< 0 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos2dBm (0x2UL) /*!< +2 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos3dBm (0x3UL) /*!< +3 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos4dBm (0x4UL) /*!< +4 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos5dBm (0x5UL) /*!< +5 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos6dBm (0x6UL) /*!< +6 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos7dBm (0x7UL) /*!< +7 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos8dBm (0x8UL) /*!< +8 dBm */ +#define RADIO_TXPOWER_TXPOWER_Pos9dBm (0x9UL) /*!< +9 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg30dBm (0xD8UL) /*!< Deprecated enumerator - -40 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg40dBm (0xD8UL) /*!< -40 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg20dBm (0xECUL) /*!< -20 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg16dBm (0xF0UL) /*!< -16 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg12dBm (0xF4UL) /*!< -12 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg8dBm (0xF8UL) /*!< -8 dBm */ +#define RADIO_TXPOWER_TXPOWER_Neg4dBm (0xFCUL) /*!< -4 dBm */ + +/* Register: RADIO_MODE */ +/* Description: Data rate and modulation */ + +/* Bits 3..0 : Radio data rate and modulation setting. The radio supports Frequency-shift Keying (FSK) modulation. */ +#define RADIO_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */ +#define RADIO_MODE_MODE_Msk (0xFUL << RADIO_MODE_MODE_Pos) /*!< Bit mask of MODE field. */ +#define RADIO_MODE_MODE_Nrf_1Mbit (0UL) /*!< 1 Mbit/s Nordic proprietary radio mode */ +#define RADIO_MODE_MODE_Nrf_2Mbit (1UL) /*!< 2 Mbit/s Nordic proprietary radio mode */ +#define RADIO_MODE_MODE_Nrf_250Kbit (2UL) /*!< Deprecated enumerator - 250 kbit/s Nordic proprietary radio mode */ +#define RADIO_MODE_MODE_Ble_1Mbit (3UL) /*!< 1 Mbit/s Bluetooth Low Energy */ +#define RADIO_MODE_MODE_Ble_2Mbit (4UL) /*!< 2 Mbit/s Bluetooth Low Energy */ +#define RADIO_MODE_MODE_Ble_LR125Kbit (5UL) /*!< Long range 125 kbit/s (TX Only - RX supports both) */ +#define RADIO_MODE_MODE_Ble_LR500Kbit (6UL) /*!< Long range 500 kbit/s (TX Only - RX supports both) */ +#define RADIO_MODE_MODE_Ieee802154_250Kbit (15UL) /*!< IEEE 802.15.4-2006 250 kbit/s */ + +/* Register: RADIO_PCNF0 */ +/* Description: Packet configuration register 0 */ + +/* Bits 30..29 : Length of TERM field in Long Range operation */ +#define RADIO_PCNF0_TERMLEN_Pos (29UL) /*!< Position of TERMLEN field. */ +#define RADIO_PCNF0_TERMLEN_Msk (0x3UL << RADIO_PCNF0_TERMLEN_Pos) /*!< Bit mask of TERMLEN field. */ + +/* Bit 26 : Indicates if LENGTH field contains CRC or not */ +#define RADIO_PCNF0_CRCINC_Pos (26UL) /*!< Position of CRCINC field. */ +#define RADIO_PCNF0_CRCINC_Msk (0x1UL << RADIO_PCNF0_CRCINC_Pos) /*!< Bit mask of CRCINC field. */ +#define RADIO_PCNF0_CRCINC_Exclude (0UL) /*!< LENGTH does not contain CRC */ +#define RADIO_PCNF0_CRCINC_Include (1UL) /*!< LENGTH includes CRC */ + +/* Bits 25..24 : Length of preamble on air. Decision point: TASKS_START task */ +#define RADIO_PCNF0_PLEN_Pos (24UL) /*!< Position of PLEN field. */ +#define RADIO_PCNF0_PLEN_Msk (0x3UL << RADIO_PCNF0_PLEN_Pos) /*!< Bit mask of PLEN field. */ +#define RADIO_PCNF0_PLEN_8bit (0UL) /*!< 8-bit preamble */ +#define RADIO_PCNF0_PLEN_16bit (1UL) /*!< 16-bit preamble */ +#define RADIO_PCNF0_PLEN_32bitZero (2UL) /*!< 32-bit zero preamble - used for IEEE 802.15.4 */ +#define RADIO_PCNF0_PLEN_LongRange (3UL) /*!< Preamble - used for BTLE Long Range */ + +/* Bits 23..22 : Length of Code Indicator - Long Range */ +#define RADIO_PCNF0_CILEN_Pos (22UL) /*!< Position of CILEN field. */ +#define RADIO_PCNF0_CILEN_Msk (0x3UL << RADIO_PCNF0_CILEN_Pos) /*!< Bit mask of CILEN field. */ + +/* Bit 20 : Include or exclude S1 field in RAM */ +#define RADIO_PCNF0_S1INCL_Pos (20UL) /*!< Position of S1INCL field. */ +#define RADIO_PCNF0_S1INCL_Msk (0x1UL << RADIO_PCNF0_S1INCL_Pos) /*!< Bit mask of S1INCL field. */ +#define RADIO_PCNF0_S1INCL_Automatic (0UL) /*!< Include S1 field in RAM only if S1LEN > 0 */ +#define RADIO_PCNF0_S1INCL_Include (1UL) /*!< Always include S1 field in RAM independent of S1LEN */ + +/* Bits 19..16 : Length on air of S1 field in number of bits. */ +#define RADIO_PCNF0_S1LEN_Pos (16UL) /*!< Position of S1LEN field. */ +#define RADIO_PCNF0_S1LEN_Msk (0xFUL << RADIO_PCNF0_S1LEN_Pos) /*!< Bit mask of S1LEN field. */ + +/* Bit 8 : Length on air of S0 field in number of bytes. */ +#define RADIO_PCNF0_S0LEN_Pos (8UL) /*!< Position of S0LEN field. */ +#define RADIO_PCNF0_S0LEN_Msk (0x1UL << RADIO_PCNF0_S0LEN_Pos) /*!< Bit mask of S0LEN field. */ + +/* Bits 3..0 : Length on air of LENGTH field in number of bits. */ +#define RADIO_PCNF0_LFLEN_Pos (0UL) /*!< Position of LFLEN field. */ +#define RADIO_PCNF0_LFLEN_Msk (0xFUL << RADIO_PCNF0_LFLEN_Pos) /*!< Bit mask of LFLEN field. */ + +/* Register: RADIO_PCNF1 */ +/* Description: Packet configuration register 1 */ + +/* Bit 25 : Enable or disable packet whitening */ +#define RADIO_PCNF1_WHITEEN_Pos (25UL) /*!< Position of WHITEEN field. */ +#define RADIO_PCNF1_WHITEEN_Msk (0x1UL << RADIO_PCNF1_WHITEEN_Pos) /*!< Bit mask of WHITEEN field. */ +#define RADIO_PCNF1_WHITEEN_Disabled (0UL) /*!< Disable */ +#define RADIO_PCNF1_WHITEEN_Enabled (1UL) /*!< Enable */ + +/* Bit 24 : On air endianness of packet, this applies to the S0, LENGTH, S1 and the PAYLOAD fields. */ +#define RADIO_PCNF1_ENDIAN_Pos (24UL) /*!< Position of ENDIAN field. */ +#define RADIO_PCNF1_ENDIAN_Msk (0x1UL << RADIO_PCNF1_ENDIAN_Pos) /*!< Bit mask of ENDIAN field. */ +#define RADIO_PCNF1_ENDIAN_Little (0UL) /*!< Least Significant bit on air first */ +#define RADIO_PCNF1_ENDIAN_Big (1UL) /*!< Most significant bit on air first */ + +/* Bits 18..16 : Base address length in number of bytes */ +#define RADIO_PCNF1_BALEN_Pos (16UL) /*!< Position of BALEN field. */ +#define RADIO_PCNF1_BALEN_Msk (0x7UL << RADIO_PCNF1_BALEN_Pos) /*!< Bit mask of BALEN field. */ + +/* Bits 15..8 : Static length in number of bytes */ +#define RADIO_PCNF1_STATLEN_Pos (8UL) /*!< Position of STATLEN field. */ +#define RADIO_PCNF1_STATLEN_Msk (0xFFUL << RADIO_PCNF1_STATLEN_Pos) /*!< Bit mask of STATLEN field. */ + +/* Bits 7..0 : Maximum length of packet payload. If the packet payload is larger than MAXLEN, the radio will truncate the payload to MAXLEN. */ +#define RADIO_PCNF1_MAXLEN_Pos (0UL) /*!< Position of MAXLEN field. */ +#define RADIO_PCNF1_MAXLEN_Msk (0xFFUL << RADIO_PCNF1_MAXLEN_Pos) /*!< Bit mask of MAXLEN field. */ + +/* Register: RADIO_BASE0 */ +/* Description: Base address 0 */ + +/* Bits 31..0 : Base address 0 */ +#define RADIO_BASE0_BASE0_Pos (0UL) /*!< Position of BASE0 field. */ +#define RADIO_BASE0_BASE0_Msk (0xFFFFFFFFUL << RADIO_BASE0_BASE0_Pos) /*!< Bit mask of BASE0 field. */ + +/* Register: RADIO_BASE1 */ +/* Description: Base address 1 */ + +/* Bits 31..0 : Base address 1 */ +#define RADIO_BASE1_BASE1_Pos (0UL) /*!< Position of BASE1 field. */ +#define RADIO_BASE1_BASE1_Msk (0xFFFFFFFFUL << RADIO_BASE1_BASE1_Pos) /*!< Bit mask of BASE1 field. */ + +/* Register: RADIO_PREFIX0 */ +/* Description: Prefixes bytes for logical addresses 0-3 */ + +/* Bits 31..24 : Address prefix 3. */ +#define RADIO_PREFIX0_AP3_Pos (24UL) /*!< Position of AP3 field. */ +#define RADIO_PREFIX0_AP3_Msk (0xFFUL << RADIO_PREFIX0_AP3_Pos) /*!< Bit mask of AP3 field. */ + +/* Bits 23..16 : Address prefix 2. */ +#define RADIO_PREFIX0_AP2_Pos (16UL) /*!< Position of AP2 field. */ +#define RADIO_PREFIX0_AP2_Msk (0xFFUL << RADIO_PREFIX0_AP2_Pos) /*!< Bit mask of AP2 field. */ + +/* Bits 15..8 : Address prefix 1. */ +#define RADIO_PREFIX0_AP1_Pos (8UL) /*!< Position of AP1 field. */ +#define RADIO_PREFIX0_AP1_Msk (0xFFUL << RADIO_PREFIX0_AP1_Pos) /*!< Bit mask of AP1 field. */ + +/* Bits 7..0 : Address prefix 0. */ +#define RADIO_PREFIX0_AP0_Pos (0UL) /*!< Position of AP0 field. */ +#define RADIO_PREFIX0_AP0_Msk (0xFFUL << RADIO_PREFIX0_AP0_Pos) /*!< Bit mask of AP0 field. */ + +/* Register: RADIO_PREFIX1 */ +/* Description: Prefixes bytes for logical addresses 4-7 */ + +/* Bits 31..24 : Address prefix 7. */ +#define RADIO_PREFIX1_AP7_Pos (24UL) /*!< Position of AP7 field. */ +#define RADIO_PREFIX1_AP7_Msk (0xFFUL << RADIO_PREFIX1_AP7_Pos) /*!< Bit mask of AP7 field. */ + +/* Bits 23..16 : Address prefix 6. */ +#define RADIO_PREFIX1_AP6_Pos (16UL) /*!< Position of AP6 field. */ +#define RADIO_PREFIX1_AP6_Msk (0xFFUL << RADIO_PREFIX1_AP6_Pos) /*!< Bit mask of AP6 field. */ + +/* Bits 15..8 : Address prefix 5. */ +#define RADIO_PREFIX1_AP5_Pos (8UL) /*!< Position of AP5 field. */ +#define RADIO_PREFIX1_AP5_Msk (0xFFUL << RADIO_PREFIX1_AP5_Pos) /*!< Bit mask of AP5 field. */ + +/* Bits 7..0 : Address prefix 4. */ +#define RADIO_PREFIX1_AP4_Pos (0UL) /*!< Position of AP4 field. */ +#define RADIO_PREFIX1_AP4_Msk (0xFFUL << RADIO_PREFIX1_AP4_Pos) /*!< Bit mask of AP4 field. */ + +/* Register: RADIO_TXADDRESS */ +/* Description: Transmit address select */ + +/* Bits 2..0 : Transmit address select */ +#define RADIO_TXADDRESS_TXADDRESS_Pos (0UL) /*!< Position of TXADDRESS field. */ +#define RADIO_TXADDRESS_TXADDRESS_Msk (0x7UL << RADIO_TXADDRESS_TXADDRESS_Pos) /*!< Bit mask of TXADDRESS field. */ + +/* Register: RADIO_RXADDRESSES */ +/* Description: Receive address select */ + +/* Bit 7 : Enable or disable reception on logical address 7. */ +#define RADIO_RXADDRESSES_ADDR7_Pos (7UL) /*!< Position of ADDR7 field. */ +#define RADIO_RXADDRESSES_ADDR7_Msk (0x1UL << RADIO_RXADDRESSES_ADDR7_Pos) /*!< Bit mask of ADDR7 field. */ +#define RADIO_RXADDRESSES_ADDR7_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR7_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable reception on logical address 6. */ +#define RADIO_RXADDRESSES_ADDR6_Pos (6UL) /*!< Position of ADDR6 field. */ +#define RADIO_RXADDRESSES_ADDR6_Msk (0x1UL << RADIO_RXADDRESSES_ADDR6_Pos) /*!< Bit mask of ADDR6 field. */ +#define RADIO_RXADDRESSES_ADDR6_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR6_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable reception on logical address 5. */ +#define RADIO_RXADDRESSES_ADDR5_Pos (5UL) /*!< Position of ADDR5 field. */ +#define RADIO_RXADDRESSES_ADDR5_Msk (0x1UL << RADIO_RXADDRESSES_ADDR5_Pos) /*!< Bit mask of ADDR5 field. */ +#define RADIO_RXADDRESSES_ADDR5_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR5_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable reception on logical address 4. */ +#define RADIO_RXADDRESSES_ADDR4_Pos (4UL) /*!< Position of ADDR4 field. */ +#define RADIO_RXADDRESSES_ADDR4_Msk (0x1UL << RADIO_RXADDRESSES_ADDR4_Pos) /*!< Bit mask of ADDR4 field. */ +#define RADIO_RXADDRESSES_ADDR4_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR4_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable reception on logical address 3. */ +#define RADIO_RXADDRESSES_ADDR3_Pos (3UL) /*!< Position of ADDR3 field. */ +#define RADIO_RXADDRESSES_ADDR3_Msk (0x1UL << RADIO_RXADDRESSES_ADDR3_Pos) /*!< Bit mask of ADDR3 field. */ +#define RADIO_RXADDRESSES_ADDR3_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR3_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable reception on logical address 2. */ +#define RADIO_RXADDRESSES_ADDR2_Pos (2UL) /*!< Position of ADDR2 field. */ +#define RADIO_RXADDRESSES_ADDR2_Msk (0x1UL << RADIO_RXADDRESSES_ADDR2_Pos) /*!< Bit mask of ADDR2 field. */ +#define RADIO_RXADDRESSES_ADDR2_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR2_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable reception on logical address 1. */ +#define RADIO_RXADDRESSES_ADDR1_Pos (1UL) /*!< Position of ADDR1 field. */ +#define RADIO_RXADDRESSES_ADDR1_Msk (0x1UL << RADIO_RXADDRESSES_ADDR1_Pos) /*!< Bit mask of ADDR1 field. */ +#define RADIO_RXADDRESSES_ADDR1_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR1_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable reception on logical address 0. */ +#define RADIO_RXADDRESSES_ADDR0_Pos (0UL) /*!< Position of ADDR0 field. */ +#define RADIO_RXADDRESSES_ADDR0_Msk (0x1UL << RADIO_RXADDRESSES_ADDR0_Pos) /*!< Bit mask of ADDR0 field. */ +#define RADIO_RXADDRESSES_ADDR0_Disabled (0UL) /*!< Disable */ +#define RADIO_RXADDRESSES_ADDR0_Enabled (1UL) /*!< Enable */ + +/* Register: RADIO_CRCCNF */ +/* Description: CRC configuration */ + +/* Bits 9..8 : Include or exclude packet address field out of CRC calculation. */ +#define RADIO_CRCCNF_SKIPADDR_Pos (8UL) /*!< Position of SKIPADDR field. */ +#define RADIO_CRCCNF_SKIPADDR_Msk (0x3UL << RADIO_CRCCNF_SKIPADDR_Pos) /*!< Bit mask of SKIPADDR field. */ +#define RADIO_CRCCNF_SKIPADDR_Include (0UL) /*!< CRC calculation includes address field */ +#define RADIO_CRCCNF_SKIPADDR_Skip (1UL) /*!< CRC calculation does not include address field. The CRC calculation will start at the first byte after the address. */ +#define RADIO_CRCCNF_SKIPADDR_Ieee802154 (2UL) /*!< CRC calculation as per 802.15.4 standard. Starting at first byte after length field. */ + +/* Bits 1..0 : CRC length in number of bytes. */ +#define RADIO_CRCCNF_LEN_Pos (0UL) /*!< Position of LEN field. */ +#define RADIO_CRCCNF_LEN_Msk (0x3UL << RADIO_CRCCNF_LEN_Pos) /*!< Bit mask of LEN field. */ +#define RADIO_CRCCNF_LEN_Disabled (0UL) /*!< CRC length is zero and CRC calculation is disabled */ +#define RADIO_CRCCNF_LEN_One (1UL) /*!< CRC length is one byte and CRC calculation is enabled */ +#define RADIO_CRCCNF_LEN_Two (2UL) /*!< CRC length is two bytes and CRC calculation is enabled */ +#define RADIO_CRCCNF_LEN_Three (3UL) /*!< CRC length is three bytes and CRC calculation is enabled */ + +/* Register: RADIO_CRCPOLY */ +/* Description: CRC polynomial */ + +/* Bits 23..0 : CRC polynomial */ +#define RADIO_CRCPOLY_CRCPOLY_Pos (0UL) /*!< Position of CRCPOLY field. */ +#define RADIO_CRCPOLY_CRCPOLY_Msk (0xFFFFFFUL << RADIO_CRCPOLY_CRCPOLY_Pos) /*!< Bit mask of CRCPOLY field. */ + +/* Register: RADIO_CRCINIT */ +/* Description: CRC initial value */ + +/* Bits 23..0 : CRC initial value */ +#define RADIO_CRCINIT_CRCINIT_Pos (0UL) /*!< Position of CRCINIT field. */ +#define RADIO_CRCINIT_CRCINIT_Msk (0xFFFFFFUL << RADIO_CRCINIT_CRCINIT_Pos) /*!< Bit mask of CRCINIT field. */ + +/* Register: RADIO_TIFS */ +/* Description: Inter Frame Spacing in us */ + +/* Bits 9..0 : Inter Frame Spacing in us */ +#define RADIO_TIFS_TIFS_Pos (0UL) /*!< Position of TIFS field. */ +#define RADIO_TIFS_TIFS_Msk (0x3FFUL << RADIO_TIFS_TIFS_Pos) /*!< Bit mask of TIFS field. */ + +/* Register: RADIO_RSSISAMPLE */ +/* Description: RSSI sample */ + +/* Bits 6..0 : RSSI sample */ +#define RADIO_RSSISAMPLE_RSSISAMPLE_Pos (0UL) /*!< Position of RSSISAMPLE field. */ +#define RADIO_RSSISAMPLE_RSSISAMPLE_Msk (0x7FUL << RADIO_RSSISAMPLE_RSSISAMPLE_Pos) /*!< Bit mask of RSSISAMPLE field. */ + +/* Register: RADIO_STATE */ +/* Description: Current radio state */ + +/* Bits 3..0 : Current radio state */ +#define RADIO_STATE_STATE_Pos (0UL) /*!< Position of STATE field. */ +#define RADIO_STATE_STATE_Msk (0xFUL << RADIO_STATE_STATE_Pos) /*!< Bit mask of STATE field. */ +#define RADIO_STATE_STATE_Disabled (0UL) /*!< RADIO is in the Disabled state */ +#define RADIO_STATE_STATE_RxRu (1UL) /*!< RADIO is in the RXRU state */ +#define RADIO_STATE_STATE_RxIdle (2UL) /*!< RADIO is in the RXIDLE state */ +#define RADIO_STATE_STATE_Rx (3UL) /*!< RADIO is in the RX state */ +#define RADIO_STATE_STATE_RxDisable (4UL) /*!< RADIO is in the RXDISABLED state */ +#define RADIO_STATE_STATE_TxRu (9UL) /*!< RADIO is in the TXRU state */ +#define RADIO_STATE_STATE_TxIdle (10UL) /*!< RADIO is in the TXIDLE state */ +#define RADIO_STATE_STATE_Tx (11UL) /*!< RADIO is in the TX state */ +#define RADIO_STATE_STATE_TxDisable (12UL) /*!< RADIO is in the TXDISABLED state */ + +/* Register: RADIO_DATAWHITEIV */ +/* Description: Data whitening initial value */ + +/* Bits 6..0 : Data whitening initial value. Bit 6 is hard-wired to '1', writing '0' to it has no effect, and it will always be read back and used by the device as '1'. */ +#define RADIO_DATAWHITEIV_DATAWHITEIV_Pos (0UL) /*!< Position of DATAWHITEIV field. */ +#define RADIO_DATAWHITEIV_DATAWHITEIV_Msk (0x7FUL << RADIO_DATAWHITEIV_DATAWHITEIV_Pos) /*!< Bit mask of DATAWHITEIV field. */ + +/* Register: RADIO_BCC */ +/* Description: Bit counter compare */ + +/* Bits 31..0 : Bit counter compare */ +#define RADIO_BCC_BCC_Pos (0UL) /*!< Position of BCC field. */ +#define RADIO_BCC_BCC_Msk (0xFFFFFFFFUL << RADIO_BCC_BCC_Pos) /*!< Bit mask of BCC field. */ + +/* Register: RADIO_DAB */ +/* Description: Description collection[0]: Device address base segment 0 */ + +/* Bits 31..0 : Device address base segment 0 */ +#define RADIO_DAB_DAB_Pos (0UL) /*!< Position of DAB field. */ +#define RADIO_DAB_DAB_Msk (0xFFFFFFFFUL << RADIO_DAB_DAB_Pos) /*!< Bit mask of DAB field. */ + +/* Register: RADIO_DAP */ +/* Description: Description collection[0]: Device address prefix 0 */ + +/* Bits 15..0 : Device address prefix 0 */ +#define RADIO_DAP_DAP_Pos (0UL) /*!< Position of DAP field. */ +#define RADIO_DAP_DAP_Msk (0xFFFFUL << RADIO_DAP_DAP_Pos) /*!< Bit mask of DAP field. */ + +/* Register: RADIO_DACNF */ +/* Description: Device address match configuration */ + +/* Bit 15 : TxAdd for device address 7 */ +#define RADIO_DACNF_TXADD7_Pos (15UL) /*!< Position of TXADD7 field. */ +#define RADIO_DACNF_TXADD7_Msk (0x1UL << RADIO_DACNF_TXADD7_Pos) /*!< Bit mask of TXADD7 field. */ + +/* Bit 14 : TxAdd for device address 6 */ +#define RADIO_DACNF_TXADD6_Pos (14UL) /*!< Position of TXADD6 field. */ +#define RADIO_DACNF_TXADD6_Msk (0x1UL << RADIO_DACNF_TXADD6_Pos) /*!< Bit mask of TXADD6 field. */ + +/* Bit 13 : TxAdd for device address 5 */ +#define RADIO_DACNF_TXADD5_Pos (13UL) /*!< Position of TXADD5 field. */ +#define RADIO_DACNF_TXADD5_Msk (0x1UL << RADIO_DACNF_TXADD5_Pos) /*!< Bit mask of TXADD5 field. */ + +/* Bit 12 : TxAdd for device address 4 */ +#define RADIO_DACNF_TXADD4_Pos (12UL) /*!< Position of TXADD4 field. */ +#define RADIO_DACNF_TXADD4_Msk (0x1UL << RADIO_DACNF_TXADD4_Pos) /*!< Bit mask of TXADD4 field. */ + +/* Bit 11 : TxAdd for device address 3 */ +#define RADIO_DACNF_TXADD3_Pos (11UL) /*!< Position of TXADD3 field. */ +#define RADIO_DACNF_TXADD3_Msk (0x1UL << RADIO_DACNF_TXADD3_Pos) /*!< Bit mask of TXADD3 field. */ + +/* Bit 10 : TxAdd for device address 2 */ +#define RADIO_DACNF_TXADD2_Pos (10UL) /*!< Position of TXADD2 field. */ +#define RADIO_DACNF_TXADD2_Msk (0x1UL << RADIO_DACNF_TXADD2_Pos) /*!< Bit mask of TXADD2 field. */ + +/* Bit 9 : TxAdd for device address 1 */ +#define RADIO_DACNF_TXADD1_Pos (9UL) /*!< Position of TXADD1 field. */ +#define RADIO_DACNF_TXADD1_Msk (0x1UL << RADIO_DACNF_TXADD1_Pos) /*!< Bit mask of TXADD1 field. */ + +/* Bit 8 : TxAdd for device address 0 */ +#define RADIO_DACNF_TXADD0_Pos (8UL) /*!< Position of TXADD0 field. */ +#define RADIO_DACNF_TXADD0_Msk (0x1UL << RADIO_DACNF_TXADD0_Pos) /*!< Bit mask of TXADD0 field. */ + +/* Bit 7 : Enable or disable device address matching using device address 7 */ +#define RADIO_DACNF_ENA7_Pos (7UL) /*!< Position of ENA7 field. */ +#define RADIO_DACNF_ENA7_Msk (0x1UL << RADIO_DACNF_ENA7_Pos) /*!< Bit mask of ENA7 field. */ +#define RADIO_DACNF_ENA7_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA7_Enabled (1UL) /*!< Enabled */ + +/* Bit 6 : Enable or disable device address matching using device address 6 */ +#define RADIO_DACNF_ENA6_Pos (6UL) /*!< Position of ENA6 field. */ +#define RADIO_DACNF_ENA6_Msk (0x1UL << RADIO_DACNF_ENA6_Pos) /*!< Bit mask of ENA6 field. */ +#define RADIO_DACNF_ENA6_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA6_Enabled (1UL) /*!< Enabled */ + +/* Bit 5 : Enable or disable device address matching using device address 5 */ +#define RADIO_DACNF_ENA5_Pos (5UL) /*!< Position of ENA5 field. */ +#define RADIO_DACNF_ENA5_Msk (0x1UL << RADIO_DACNF_ENA5_Pos) /*!< Bit mask of ENA5 field. */ +#define RADIO_DACNF_ENA5_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA5_Enabled (1UL) /*!< Enabled */ + +/* Bit 4 : Enable or disable device address matching using device address 4 */ +#define RADIO_DACNF_ENA4_Pos (4UL) /*!< Position of ENA4 field. */ +#define RADIO_DACNF_ENA4_Msk (0x1UL << RADIO_DACNF_ENA4_Pos) /*!< Bit mask of ENA4 field. */ +#define RADIO_DACNF_ENA4_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA4_Enabled (1UL) /*!< Enabled */ + +/* Bit 3 : Enable or disable device address matching using device address 3 */ +#define RADIO_DACNF_ENA3_Pos (3UL) /*!< Position of ENA3 field. */ +#define RADIO_DACNF_ENA3_Msk (0x1UL << RADIO_DACNF_ENA3_Pos) /*!< Bit mask of ENA3 field. */ +#define RADIO_DACNF_ENA3_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA3_Enabled (1UL) /*!< Enabled */ + +/* Bit 2 : Enable or disable device address matching using device address 2 */ +#define RADIO_DACNF_ENA2_Pos (2UL) /*!< Position of ENA2 field. */ +#define RADIO_DACNF_ENA2_Msk (0x1UL << RADIO_DACNF_ENA2_Pos) /*!< Bit mask of ENA2 field. */ +#define RADIO_DACNF_ENA2_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA2_Enabled (1UL) /*!< Enabled */ + +/* Bit 1 : Enable or disable device address matching using device address 1 */ +#define RADIO_DACNF_ENA1_Pos (1UL) /*!< Position of ENA1 field. */ +#define RADIO_DACNF_ENA1_Msk (0x1UL << RADIO_DACNF_ENA1_Pos) /*!< Bit mask of ENA1 field. */ +#define RADIO_DACNF_ENA1_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA1_Enabled (1UL) /*!< Enabled */ + +/* Bit 0 : Enable or disable device address matching using device address 0 */ +#define RADIO_DACNF_ENA0_Pos (0UL) /*!< Position of ENA0 field. */ +#define RADIO_DACNF_ENA0_Msk (0x1UL << RADIO_DACNF_ENA0_Pos) /*!< Bit mask of ENA0 field. */ +#define RADIO_DACNF_ENA0_Disabled (0UL) /*!< Disabled */ +#define RADIO_DACNF_ENA0_Enabled (1UL) /*!< Enabled */ + +/* Register: RADIO_MODECNF0 */ +/* Description: Radio mode configuration register 0 */ + +/* Bits 9..8 : Default TX value */ +#define RADIO_MODECNF0_DTX_Pos (8UL) /*!< Position of DTX field. */ +#define RADIO_MODECNF0_DTX_Msk (0x3UL << RADIO_MODECNF0_DTX_Pos) /*!< Bit mask of DTX field. */ +#define RADIO_MODECNF0_DTX_B1 (0UL) /*!< Transmit '1' */ +#define RADIO_MODECNF0_DTX_B0 (1UL) /*!< Transmit '0' */ +#define RADIO_MODECNF0_DTX_Center (2UL) /*!< Transmit center frequency */ + +/* Bit 0 : Radio ramp-up time */ +#define RADIO_MODECNF0_RU_Pos (0UL) /*!< Position of RU field. */ +#define RADIO_MODECNF0_RU_Msk (0x1UL << RADIO_MODECNF0_RU_Pos) /*!< Bit mask of RU field. */ +#define RADIO_MODECNF0_RU_Default (0UL) /*!< Default ramp-up time (tRXEN), compatible with firmware written for nRF51 */ +#define RADIO_MODECNF0_RU_Fast (1UL) /*!< Fast ramp-up (tRXEN,FAST), see electrical specification for more information */ + +/* Register: RADIO_SFD */ +/* Description: IEEE 802.15.4 Start of Frame Delimiter */ + +/* Bits 7..0 : IEEE 802.15.4 Start of Frame Delimiter */ +#define RADIO_SFD_SFD_Pos (0UL) /*!< Position of SFD field. */ +#define RADIO_SFD_SFD_Msk (0xFFUL << RADIO_SFD_SFD_Pos) /*!< Bit mask of SFD field. */ + +/* Register: RADIO_EDCNT */ +/* Description: IEEE 802.15.4 Energy Detect Loop Count */ + +/* Bits 20..0 : IEEE 802.15.4 Energy Detect Loop Count */ +#define RADIO_EDCNT_EDCNT_Pos (0UL) /*!< Position of EDCNT field. */ +#define RADIO_EDCNT_EDCNT_Msk (0x1FFFFFUL << RADIO_EDCNT_EDCNT_Pos) /*!< Bit mask of EDCNT field. */ + +/* Register: RADIO_EDSAMPLE */ +/* Description: IEEE 802.15.4 Energy Detect Level */ + +/* Bits 7..0 : IEEE 802.15.4 Energy Detect Level */ +#define RADIO_EDSAMPLE_EDLVL_Pos (0UL) /*!< Position of EDLVL field. */ +#define RADIO_EDSAMPLE_EDLVL_Msk (0xFFUL << RADIO_EDSAMPLE_EDLVL_Pos) /*!< Bit mask of EDLVL field. */ + +/* Register: RADIO_CCACTRL */ +/* Description: IEEE 802.15.4 Clear Channel Assessment Control */ + +/* Bits 31..24 : Limit for occurances above CCACORRTHRES. When not equal to zero the corrolator based signal detect is enabled. */ +#define RADIO_CCACTRL_CCACORRCNT_Pos (24UL) /*!< Position of CCACORRCNT field. */ +#define RADIO_CCACTRL_CCACORRCNT_Msk (0xFFUL << RADIO_CCACTRL_CCACORRCNT_Pos) /*!< Bit mask of CCACORRCNT field. */ + +/* Bits 23..16 : CCA Correlator Busy Threshold. Only relevant to CarrierMode, CarrierAndEdMode and CarrierOrEdMode. */ +#define RADIO_CCACTRL_CCACORRTHRES_Pos (16UL) /*!< Position of CCACORRTHRES field. */ +#define RADIO_CCACTRL_CCACORRTHRES_Msk (0xFFUL << RADIO_CCACTRL_CCACORRTHRES_Pos) /*!< Bit mask of CCACORRTHRES field. */ + +/* Bits 15..8 : CCA Energy Busy Threshold. Used in all the CCA modes except CarrierMode. */ +#define RADIO_CCACTRL_CCAEDTHRES_Pos (8UL) /*!< Position of CCAEDTHRES field. */ +#define RADIO_CCACTRL_CCAEDTHRES_Msk (0xFFUL << RADIO_CCACTRL_CCAEDTHRES_Pos) /*!< Bit mask of CCAEDTHRES field. */ + +/* Bits 2..0 : CCA Mode Of Operation */ +#define RADIO_CCACTRL_CCAMODE_Pos (0UL) /*!< Position of CCAMODE field. */ +#define RADIO_CCACTRL_CCAMODE_Msk (0x7UL << RADIO_CCACTRL_CCAMODE_Pos) /*!< Bit mask of CCAMODE field. */ +#define RADIO_CCACTRL_CCAMODE_EdMode (0UL) /*!< Energy Above Threshold */ +#define RADIO_CCACTRL_CCAMODE_CarrierMode (1UL) /*!< Carrier Seen */ +#define RADIO_CCACTRL_CCAMODE_CarrierAndEdMode (2UL) /*!< Energy Above Threshold AND Carrier Seen */ +#define RADIO_CCACTRL_CCAMODE_CarrierOrEdMode (3UL) /*!< Energy Above Threshold OR Carrier Seen */ +#define RADIO_CCACTRL_CCAMODE_EdModeTest1 (4UL) /*!< Energy Above Threshold test mode that will abort when first ED measurement over threshold is seen. No averaging. */ + +/* Register: RADIO_POWER */ +/* Description: Peripheral power control */ + +/* Bit 0 : Peripheral power control. The peripheral and its registers will be reset to its initial state by switching the peripheral off and then back on again. */ +#define RADIO_POWER_POWER_Pos (0UL) /*!< Position of POWER field. */ +#define RADIO_POWER_POWER_Msk (0x1UL << RADIO_POWER_POWER_Pos) /*!< Bit mask of POWER field. */ +#define RADIO_POWER_POWER_Disabled (0UL) /*!< Peripheral is powered off */ +#define RADIO_POWER_POWER_Enabled (1UL) /*!< Peripheral is powered on */ + + +/* Peripheral: RNG */ +/* Description: Random Number Generator */ + +/* Register: RNG_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 0 : Shortcut between VALRDY event and STOP task */ +#define RNG_SHORTS_VALRDY_STOP_Pos (0UL) /*!< Position of VALRDY_STOP field. */ +#define RNG_SHORTS_VALRDY_STOP_Msk (0x1UL << RNG_SHORTS_VALRDY_STOP_Pos) /*!< Bit mask of VALRDY_STOP field. */ +#define RNG_SHORTS_VALRDY_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define RNG_SHORTS_VALRDY_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: RNG_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 0 : Write '1' to Enable interrupt for VALRDY event */ +#define RNG_INTENSET_VALRDY_Pos (0UL) /*!< Position of VALRDY field. */ +#define RNG_INTENSET_VALRDY_Msk (0x1UL << RNG_INTENSET_VALRDY_Pos) /*!< Bit mask of VALRDY field. */ +#define RNG_INTENSET_VALRDY_Disabled (0UL) /*!< Read: Disabled */ +#define RNG_INTENSET_VALRDY_Enabled (1UL) /*!< Read: Enabled */ +#define RNG_INTENSET_VALRDY_Set (1UL) /*!< Enable */ + +/* Register: RNG_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 0 : Write '1' to Disable interrupt for VALRDY event */ +#define RNG_INTENCLR_VALRDY_Pos (0UL) /*!< Position of VALRDY field. */ +#define RNG_INTENCLR_VALRDY_Msk (0x1UL << RNG_INTENCLR_VALRDY_Pos) /*!< Bit mask of VALRDY field. */ +#define RNG_INTENCLR_VALRDY_Disabled (0UL) /*!< Read: Disabled */ +#define RNG_INTENCLR_VALRDY_Enabled (1UL) /*!< Read: Enabled */ +#define RNG_INTENCLR_VALRDY_Clear (1UL) /*!< Disable */ + +/* Register: RNG_CONFIG */ +/* Description: Configuration register */ + +/* Bit 0 : Bias correction */ +#define RNG_CONFIG_DERCEN_Pos (0UL) /*!< Position of DERCEN field. */ +#define RNG_CONFIG_DERCEN_Msk (0x1UL << RNG_CONFIG_DERCEN_Pos) /*!< Bit mask of DERCEN field. */ +#define RNG_CONFIG_DERCEN_Disabled (0UL) /*!< Disabled */ +#define RNG_CONFIG_DERCEN_Enabled (1UL) /*!< Enabled */ + +/* Register: RNG_VALUE */ +/* Description: Output random number */ + +/* Bits 7..0 : Generated random number */ +#define RNG_VALUE_VALUE_Pos (0UL) /*!< Position of VALUE field. */ +#define RNG_VALUE_VALUE_Msk (0xFFUL << RNG_VALUE_VALUE_Pos) /*!< Bit mask of VALUE field. */ + + +/* Peripheral: RTC */ +/* Description: Real time counter 0 */ + +/* Register: RTC_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 19 : Write '1' to Enable interrupt for COMPARE[3] event */ +#define RTC_INTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define RTC_INTENSET_COMPARE3_Msk (0x1UL << RTC_INTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define RTC_INTENSET_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_COMPARE3_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for COMPARE[2] event */ +#define RTC_INTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define RTC_INTENSET_COMPARE2_Msk (0x1UL << RTC_INTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define RTC_INTENSET_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_COMPARE2_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for COMPARE[1] event */ +#define RTC_INTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define RTC_INTENSET_COMPARE1_Msk (0x1UL << RTC_INTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define RTC_INTENSET_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_COMPARE1_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable interrupt for COMPARE[0] event */ +#define RTC_INTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define RTC_INTENSET_COMPARE0_Msk (0x1UL << RTC_INTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define RTC_INTENSET_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_COMPARE0_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for OVRFLW event */ +#define RTC_INTENSET_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ +#define RTC_INTENSET_OVRFLW_Msk (0x1UL << RTC_INTENSET_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ +#define RTC_INTENSET_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_OVRFLW_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for TICK event */ +#define RTC_INTENSET_TICK_Pos (0UL) /*!< Position of TICK field. */ +#define RTC_INTENSET_TICK_Msk (0x1UL << RTC_INTENSET_TICK_Pos) /*!< Bit mask of TICK field. */ +#define RTC_INTENSET_TICK_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENSET_TICK_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENSET_TICK_Set (1UL) /*!< Enable */ + +/* Register: RTC_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 19 : Write '1' to Disable interrupt for COMPARE[3] event */ +#define RTC_INTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define RTC_INTENCLR_COMPARE3_Msk (0x1UL << RTC_INTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define RTC_INTENCLR_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_COMPARE3_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for COMPARE[2] event */ +#define RTC_INTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define RTC_INTENCLR_COMPARE2_Msk (0x1UL << RTC_INTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define RTC_INTENCLR_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_COMPARE2_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for COMPARE[1] event */ +#define RTC_INTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define RTC_INTENCLR_COMPARE1_Msk (0x1UL << RTC_INTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define RTC_INTENCLR_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_COMPARE1_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable interrupt for COMPARE[0] event */ +#define RTC_INTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define RTC_INTENCLR_COMPARE0_Msk (0x1UL << RTC_INTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define RTC_INTENCLR_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_COMPARE0_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for OVRFLW event */ +#define RTC_INTENCLR_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ +#define RTC_INTENCLR_OVRFLW_Msk (0x1UL << RTC_INTENCLR_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ +#define RTC_INTENCLR_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_OVRFLW_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for TICK event */ +#define RTC_INTENCLR_TICK_Pos (0UL) /*!< Position of TICK field. */ +#define RTC_INTENCLR_TICK_Msk (0x1UL << RTC_INTENCLR_TICK_Pos) /*!< Bit mask of TICK field. */ +#define RTC_INTENCLR_TICK_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_INTENCLR_TICK_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_INTENCLR_TICK_Clear (1UL) /*!< Disable */ + +/* Register: RTC_EVTEN */ +/* Description: Enable or disable event routing */ + +/* Bit 19 : Enable or disable event routing for COMPARE[3] event */ +#define RTC_EVTEN_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define RTC_EVTEN_COMPARE3_Msk (0x1UL << RTC_EVTEN_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define RTC_EVTEN_COMPARE3_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_COMPARE3_Enabled (1UL) /*!< Enable */ + +/* Bit 18 : Enable or disable event routing for COMPARE[2] event */ +#define RTC_EVTEN_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define RTC_EVTEN_COMPARE2_Msk (0x1UL << RTC_EVTEN_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define RTC_EVTEN_COMPARE2_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_COMPARE2_Enabled (1UL) /*!< Enable */ + +/* Bit 17 : Enable or disable event routing for COMPARE[1] event */ +#define RTC_EVTEN_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define RTC_EVTEN_COMPARE1_Msk (0x1UL << RTC_EVTEN_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define RTC_EVTEN_COMPARE1_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_COMPARE1_Enabled (1UL) /*!< Enable */ + +/* Bit 16 : Enable or disable event routing for COMPARE[0] event */ +#define RTC_EVTEN_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define RTC_EVTEN_COMPARE0_Msk (0x1UL << RTC_EVTEN_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define RTC_EVTEN_COMPARE0_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_COMPARE0_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable event routing for OVRFLW event */ +#define RTC_EVTEN_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ +#define RTC_EVTEN_OVRFLW_Msk (0x1UL << RTC_EVTEN_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ +#define RTC_EVTEN_OVRFLW_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_OVRFLW_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable event routing for TICK event */ +#define RTC_EVTEN_TICK_Pos (0UL) /*!< Position of TICK field. */ +#define RTC_EVTEN_TICK_Msk (0x1UL << RTC_EVTEN_TICK_Pos) /*!< Bit mask of TICK field. */ +#define RTC_EVTEN_TICK_Disabled (0UL) /*!< Disable */ +#define RTC_EVTEN_TICK_Enabled (1UL) /*!< Enable */ + +/* Register: RTC_EVTENSET */ +/* Description: Enable event routing */ + +/* Bit 19 : Write '1' to Enable event routing for COMPARE[3] event */ +#define RTC_EVTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define RTC_EVTENSET_COMPARE3_Msk (0x1UL << RTC_EVTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define RTC_EVTENSET_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_COMPARE3_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable event routing for COMPARE[2] event */ +#define RTC_EVTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define RTC_EVTENSET_COMPARE2_Msk (0x1UL << RTC_EVTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define RTC_EVTENSET_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_COMPARE2_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable event routing for COMPARE[1] event */ +#define RTC_EVTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define RTC_EVTENSET_COMPARE1_Msk (0x1UL << RTC_EVTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define RTC_EVTENSET_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_COMPARE1_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable event routing for COMPARE[0] event */ +#define RTC_EVTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define RTC_EVTENSET_COMPARE0_Msk (0x1UL << RTC_EVTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define RTC_EVTENSET_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_COMPARE0_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable event routing for OVRFLW event */ +#define RTC_EVTENSET_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ +#define RTC_EVTENSET_OVRFLW_Msk (0x1UL << RTC_EVTENSET_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ +#define RTC_EVTENSET_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_OVRFLW_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable event routing for TICK event */ +#define RTC_EVTENSET_TICK_Pos (0UL) /*!< Position of TICK field. */ +#define RTC_EVTENSET_TICK_Msk (0x1UL << RTC_EVTENSET_TICK_Pos) /*!< Bit mask of TICK field. */ +#define RTC_EVTENSET_TICK_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENSET_TICK_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENSET_TICK_Set (1UL) /*!< Enable */ + +/* Register: RTC_EVTENCLR */ +/* Description: Disable event routing */ + +/* Bit 19 : Write '1' to Disable event routing for COMPARE[3] event */ +#define RTC_EVTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define RTC_EVTENCLR_COMPARE3_Msk (0x1UL << RTC_EVTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define RTC_EVTENCLR_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_COMPARE3_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable event routing for COMPARE[2] event */ +#define RTC_EVTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define RTC_EVTENCLR_COMPARE2_Msk (0x1UL << RTC_EVTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define RTC_EVTENCLR_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_COMPARE2_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable event routing for COMPARE[1] event */ +#define RTC_EVTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define RTC_EVTENCLR_COMPARE1_Msk (0x1UL << RTC_EVTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define RTC_EVTENCLR_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_COMPARE1_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable event routing for COMPARE[0] event */ +#define RTC_EVTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define RTC_EVTENCLR_COMPARE0_Msk (0x1UL << RTC_EVTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define RTC_EVTENCLR_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_COMPARE0_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable event routing for OVRFLW event */ +#define RTC_EVTENCLR_OVRFLW_Pos (1UL) /*!< Position of OVRFLW field. */ +#define RTC_EVTENCLR_OVRFLW_Msk (0x1UL << RTC_EVTENCLR_OVRFLW_Pos) /*!< Bit mask of OVRFLW field. */ +#define RTC_EVTENCLR_OVRFLW_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_OVRFLW_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_OVRFLW_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable event routing for TICK event */ +#define RTC_EVTENCLR_TICK_Pos (0UL) /*!< Position of TICK field. */ +#define RTC_EVTENCLR_TICK_Msk (0x1UL << RTC_EVTENCLR_TICK_Pos) /*!< Bit mask of TICK field. */ +#define RTC_EVTENCLR_TICK_Disabled (0UL) /*!< Read: Disabled */ +#define RTC_EVTENCLR_TICK_Enabled (1UL) /*!< Read: Enabled */ +#define RTC_EVTENCLR_TICK_Clear (1UL) /*!< Disable */ + +/* Register: RTC_COUNTER */ +/* Description: Current COUNTER value */ + +/* Bits 23..0 : Counter value */ +#define RTC_COUNTER_COUNTER_Pos (0UL) /*!< Position of COUNTER field. */ +#define RTC_COUNTER_COUNTER_Msk (0xFFFFFFUL << RTC_COUNTER_COUNTER_Pos) /*!< Bit mask of COUNTER field. */ + +/* Register: RTC_PRESCALER */ +/* Description: 12 bit prescaler for COUNTER frequency (32768/(PRESCALER+1)).Must be written when RTC is stopped */ + +/* Bits 11..0 : Prescaler value */ +#define RTC_PRESCALER_PRESCALER_Pos (0UL) /*!< Position of PRESCALER field. */ +#define RTC_PRESCALER_PRESCALER_Msk (0xFFFUL << RTC_PRESCALER_PRESCALER_Pos) /*!< Bit mask of PRESCALER field. */ + +/* Register: RTC_CC */ +/* Description: Description collection[0]: Compare register 0 */ + +/* Bits 23..0 : Compare value */ +#define RTC_CC_COMPARE_Pos (0UL) /*!< Position of COMPARE field. */ +#define RTC_CC_COMPARE_Msk (0xFFFFFFUL << RTC_CC_COMPARE_Pos) /*!< Bit mask of COMPARE field. */ + + +/* Peripheral: SAADC */ +/* Description: Analog to Digital Converter */ + +/* Register: SAADC_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 21 : Enable or disable interrupt for CH[7].LIMITL event */ +#define SAADC_INTEN_CH7LIMITL_Pos (21UL) /*!< Position of CH7LIMITL field. */ +#define SAADC_INTEN_CH7LIMITL_Msk (0x1UL << SAADC_INTEN_CH7LIMITL_Pos) /*!< Bit mask of CH7LIMITL field. */ +#define SAADC_INTEN_CH7LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH7LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 20 : Enable or disable interrupt for CH[7].LIMITH event */ +#define SAADC_INTEN_CH7LIMITH_Pos (20UL) /*!< Position of CH7LIMITH field. */ +#define SAADC_INTEN_CH7LIMITH_Msk (0x1UL << SAADC_INTEN_CH7LIMITH_Pos) /*!< Bit mask of CH7LIMITH field. */ +#define SAADC_INTEN_CH7LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH7LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for CH[6].LIMITL event */ +#define SAADC_INTEN_CH6LIMITL_Pos (19UL) /*!< Position of CH6LIMITL field. */ +#define SAADC_INTEN_CH6LIMITL_Msk (0x1UL << SAADC_INTEN_CH6LIMITL_Pos) /*!< Bit mask of CH6LIMITL field. */ +#define SAADC_INTEN_CH6LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH6LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 18 : Enable or disable interrupt for CH[6].LIMITH event */ +#define SAADC_INTEN_CH6LIMITH_Pos (18UL) /*!< Position of CH6LIMITH field. */ +#define SAADC_INTEN_CH6LIMITH_Msk (0x1UL << SAADC_INTEN_CH6LIMITH_Pos) /*!< Bit mask of CH6LIMITH field. */ +#define SAADC_INTEN_CH6LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH6LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 17 : Enable or disable interrupt for CH[5].LIMITL event */ +#define SAADC_INTEN_CH5LIMITL_Pos (17UL) /*!< Position of CH5LIMITL field. */ +#define SAADC_INTEN_CH5LIMITL_Msk (0x1UL << SAADC_INTEN_CH5LIMITL_Pos) /*!< Bit mask of CH5LIMITL field. */ +#define SAADC_INTEN_CH5LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH5LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 16 : Enable or disable interrupt for CH[5].LIMITH event */ +#define SAADC_INTEN_CH5LIMITH_Pos (16UL) /*!< Position of CH5LIMITH field. */ +#define SAADC_INTEN_CH5LIMITH_Msk (0x1UL << SAADC_INTEN_CH5LIMITH_Pos) /*!< Bit mask of CH5LIMITH field. */ +#define SAADC_INTEN_CH5LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH5LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 15 : Enable or disable interrupt for CH[4].LIMITL event */ +#define SAADC_INTEN_CH4LIMITL_Pos (15UL) /*!< Position of CH4LIMITL field. */ +#define SAADC_INTEN_CH4LIMITL_Msk (0x1UL << SAADC_INTEN_CH4LIMITL_Pos) /*!< Bit mask of CH4LIMITL field. */ +#define SAADC_INTEN_CH4LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH4LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 14 : Enable or disable interrupt for CH[4].LIMITH event */ +#define SAADC_INTEN_CH4LIMITH_Pos (14UL) /*!< Position of CH4LIMITH field. */ +#define SAADC_INTEN_CH4LIMITH_Msk (0x1UL << SAADC_INTEN_CH4LIMITH_Pos) /*!< Bit mask of CH4LIMITH field. */ +#define SAADC_INTEN_CH4LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH4LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 13 : Enable or disable interrupt for CH[3].LIMITL event */ +#define SAADC_INTEN_CH3LIMITL_Pos (13UL) /*!< Position of CH3LIMITL field. */ +#define SAADC_INTEN_CH3LIMITL_Msk (0x1UL << SAADC_INTEN_CH3LIMITL_Pos) /*!< Bit mask of CH3LIMITL field. */ +#define SAADC_INTEN_CH3LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH3LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 12 : Enable or disable interrupt for CH[3].LIMITH event */ +#define SAADC_INTEN_CH3LIMITH_Pos (12UL) /*!< Position of CH3LIMITH field. */ +#define SAADC_INTEN_CH3LIMITH_Msk (0x1UL << SAADC_INTEN_CH3LIMITH_Pos) /*!< Bit mask of CH3LIMITH field. */ +#define SAADC_INTEN_CH3LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH3LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 11 : Enable or disable interrupt for CH[2].LIMITL event */ +#define SAADC_INTEN_CH2LIMITL_Pos (11UL) /*!< Position of CH2LIMITL field. */ +#define SAADC_INTEN_CH2LIMITL_Msk (0x1UL << SAADC_INTEN_CH2LIMITL_Pos) /*!< Bit mask of CH2LIMITL field. */ +#define SAADC_INTEN_CH2LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH2LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 10 : Enable or disable interrupt for CH[2].LIMITH event */ +#define SAADC_INTEN_CH2LIMITH_Pos (10UL) /*!< Position of CH2LIMITH field. */ +#define SAADC_INTEN_CH2LIMITH_Msk (0x1UL << SAADC_INTEN_CH2LIMITH_Pos) /*!< Bit mask of CH2LIMITH field. */ +#define SAADC_INTEN_CH2LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH2LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for CH[1].LIMITL event */ +#define SAADC_INTEN_CH1LIMITL_Pos (9UL) /*!< Position of CH1LIMITL field. */ +#define SAADC_INTEN_CH1LIMITL_Msk (0x1UL << SAADC_INTEN_CH1LIMITL_Pos) /*!< Bit mask of CH1LIMITL field. */ +#define SAADC_INTEN_CH1LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH1LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 8 : Enable or disable interrupt for CH[1].LIMITH event */ +#define SAADC_INTEN_CH1LIMITH_Pos (8UL) /*!< Position of CH1LIMITH field. */ +#define SAADC_INTEN_CH1LIMITH_Msk (0x1UL << SAADC_INTEN_CH1LIMITH_Pos) /*!< Bit mask of CH1LIMITH field. */ +#define SAADC_INTEN_CH1LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH1LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 7 : Enable or disable interrupt for CH[0].LIMITL event */ +#define SAADC_INTEN_CH0LIMITL_Pos (7UL) /*!< Position of CH0LIMITL field. */ +#define SAADC_INTEN_CH0LIMITL_Msk (0x1UL << SAADC_INTEN_CH0LIMITL_Pos) /*!< Bit mask of CH0LIMITL field. */ +#define SAADC_INTEN_CH0LIMITL_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH0LIMITL_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable interrupt for CH[0].LIMITH event */ +#define SAADC_INTEN_CH0LIMITH_Pos (6UL) /*!< Position of CH0LIMITH field. */ +#define SAADC_INTEN_CH0LIMITH_Msk (0x1UL << SAADC_INTEN_CH0LIMITH_Pos) /*!< Bit mask of CH0LIMITH field. */ +#define SAADC_INTEN_CH0LIMITH_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CH0LIMITH_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable interrupt for STOPPED event */ +#define SAADC_INTEN_STOPPED_Pos (5UL) /*!< Position of STOPPED field. */ +#define SAADC_INTEN_STOPPED_Msk (0x1UL << SAADC_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define SAADC_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for CALIBRATEDONE event */ +#define SAADC_INTEN_CALIBRATEDONE_Pos (4UL) /*!< Position of CALIBRATEDONE field. */ +#define SAADC_INTEN_CALIBRATEDONE_Msk (0x1UL << SAADC_INTEN_CALIBRATEDONE_Pos) /*!< Bit mask of CALIBRATEDONE field. */ +#define SAADC_INTEN_CALIBRATEDONE_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_CALIBRATEDONE_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable interrupt for RESULTDONE event */ +#define SAADC_INTEN_RESULTDONE_Pos (3UL) /*!< Position of RESULTDONE field. */ +#define SAADC_INTEN_RESULTDONE_Msk (0x1UL << SAADC_INTEN_RESULTDONE_Pos) /*!< Bit mask of RESULTDONE field. */ +#define SAADC_INTEN_RESULTDONE_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_RESULTDONE_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for DONE event */ +#define SAADC_INTEN_DONE_Pos (2UL) /*!< Position of DONE field. */ +#define SAADC_INTEN_DONE_Msk (0x1UL << SAADC_INTEN_DONE_Pos) /*!< Bit mask of DONE field. */ +#define SAADC_INTEN_DONE_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_DONE_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for END event */ +#define SAADC_INTEN_END_Pos (1UL) /*!< Position of END field. */ +#define SAADC_INTEN_END_Msk (0x1UL << SAADC_INTEN_END_Pos) /*!< Bit mask of END field. */ +#define SAADC_INTEN_END_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_END_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for STARTED event */ +#define SAADC_INTEN_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define SAADC_INTEN_STARTED_Msk (0x1UL << SAADC_INTEN_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define SAADC_INTEN_STARTED_Disabled (0UL) /*!< Disable */ +#define SAADC_INTEN_STARTED_Enabled (1UL) /*!< Enable */ + +/* Register: SAADC_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 21 : Write '1' to Enable interrupt for CH[7].LIMITL event */ +#define SAADC_INTENSET_CH7LIMITL_Pos (21UL) /*!< Position of CH7LIMITL field. */ +#define SAADC_INTENSET_CH7LIMITL_Msk (0x1UL << SAADC_INTENSET_CH7LIMITL_Pos) /*!< Bit mask of CH7LIMITL field. */ +#define SAADC_INTENSET_CH7LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH7LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH7LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for CH[7].LIMITH event */ +#define SAADC_INTENSET_CH7LIMITH_Pos (20UL) /*!< Position of CH7LIMITH field. */ +#define SAADC_INTENSET_CH7LIMITH_Msk (0x1UL << SAADC_INTENSET_CH7LIMITH_Pos) /*!< Bit mask of CH7LIMITH field. */ +#define SAADC_INTENSET_CH7LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH7LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH7LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for CH[6].LIMITL event */ +#define SAADC_INTENSET_CH6LIMITL_Pos (19UL) /*!< Position of CH6LIMITL field. */ +#define SAADC_INTENSET_CH6LIMITL_Msk (0x1UL << SAADC_INTENSET_CH6LIMITL_Pos) /*!< Bit mask of CH6LIMITL field. */ +#define SAADC_INTENSET_CH6LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH6LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH6LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for CH[6].LIMITH event */ +#define SAADC_INTENSET_CH6LIMITH_Pos (18UL) /*!< Position of CH6LIMITH field. */ +#define SAADC_INTENSET_CH6LIMITH_Msk (0x1UL << SAADC_INTENSET_CH6LIMITH_Pos) /*!< Bit mask of CH6LIMITH field. */ +#define SAADC_INTENSET_CH6LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH6LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH6LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for CH[5].LIMITL event */ +#define SAADC_INTENSET_CH5LIMITL_Pos (17UL) /*!< Position of CH5LIMITL field. */ +#define SAADC_INTENSET_CH5LIMITL_Msk (0x1UL << SAADC_INTENSET_CH5LIMITL_Pos) /*!< Bit mask of CH5LIMITL field. */ +#define SAADC_INTENSET_CH5LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH5LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH5LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable interrupt for CH[5].LIMITH event */ +#define SAADC_INTENSET_CH5LIMITH_Pos (16UL) /*!< Position of CH5LIMITH field. */ +#define SAADC_INTENSET_CH5LIMITH_Msk (0x1UL << SAADC_INTENSET_CH5LIMITH_Pos) /*!< Bit mask of CH5LIMITH field. */ +#define SAADC_INTENSET_CH5LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH5LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH5LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 15 : Write '1' to Enable interrupt for CH[4].LIMITL event */ +#define SAADC_INTENSET_CH4LIMITL_Pos (15UL) /*!< Position of CH4LIMITL field. */ +#define SAADC_INTENSET_CH4LIMITL_Msk (0x1UL << SAADC_INTENSET_CH4LIMITL_Pos) /*!< Bit mask of CH4LIMITL field. */ +#define SAADC_INTENSET_CH4LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH4LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH4LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 14 : Write '1' to Enable interrupt for CH[4].LIMITH event */ +#define SAADC_INTENSET_CH4LIMITH_Pos (14UL) /*!< Position of CH4LIMITH field. */ +#define SAADC_INTENSET_CH4LIMITH_Msk (0x1UL << SAADC_INTENSET_CH4LIMITH_Pos) /*!< Bit mask of CH4LIMITH field. */ +#define SAADC_INTENSET_CH4LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH4LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH4LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 13 : Write '1' to Enable interrupt for CH[3].LIMITL event */ +#define SAADC_INTENSET_CH3LIMITL_Pos (13UL) /*!< Position of CH3LIMITL field. */ +#define SAADC_INTENSET_CH3LIMITL_Msk (0x1UL << SAADC_INTENSET_CH3LIMITL_Pos) /*!< Bit mask of CH3LIMITL field. */ +#define SAADC_INTENSET_CH3LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH3LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH3LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 12 : Write '1' to Enable interrupt for CH[3].LIMITH event */ +#define SAADC_INTENSET_CH3LIMITH_Pos (12UL) /*!< Position of CH3LIMITH field. */ +#define SAADC_INTENSET_CH3LIMITH_Msk (0x1UL << SAADC_INTENSET_CH3LIMITH_Pos) /*!< Bit mask of CH3LIMITH field. */ +#define SAADC_INTENSET_CH3LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH3LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH3LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 11 : Write '1' to Enable interrupt for CH[2].LIMITL event */ +#define SAADC_INTENSET_CH2LIMITL_Pos (11UL) /*!< Position of CH2LIMITL field. */ +#define SAADC_INTENSET_CH2LIMITL_Msk (0x1UL << SAADC_INTENSET_CH2LIMITL_Pos) /*!< Bit mask of CH2LIMITL field. */ +#define SAADC_INTENSET_CH2LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH2LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH2LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 10 : Write '1' to Enable interrupt for CH[2].LIMITH event */ +#define SAADC_INTENSET_CH2LIMITH_Pos (10UL) /*!< Position of CH2LIMITH field. */ +#define SAADC_INTENSET_CH2LIMITH_Msk (0x1UL << SAADC_INTENSET_CH2LIMITH_Pos) /*!< Bit mask of CH2LIMITH field. */ +#define SAADC_INTENSET_CH2LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH2LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH2LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for CH[1].LIMITL event */ +#define SAADC_INTENSET_CH1LIMITL_Pos (9UL) /*!< Position of CH1LIMITL field. */ +#define SAADC_INTENSET_CH1LIMITL_Msk (0x1UL << SAADC_INTENSET_CH1LIMITL_Pos) /*!< Bit mask of CH1LIMITL field. */ +#define SAADC_INTENSET_CH1LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH1LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH1LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for CH[1].LIMITH event */ +#define SAADC_INTENSET_CH1LIMITH_Pos (8UL) /*!< Position of CH1LIMITH field. */ +#define SAADC_INTENSET_CH1LIMITH_Msk (0x1UL << SAADC_INTENSET_CH1LIMITH_Pos) /*!< Bit mask of CH1LIMITH field. */ +#define SAADC_INTENSET_CH1LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH1LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH1LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for CH[0].LIMITL event */ +#define SAADC_INTENSET_CH0LIMITL_Pos (7UL) /*!< Position of CH0LIMITL field. */ +#define SAADC_INTENSET_CH0LIMITL_Msk (0x1UL << SAADC_INTENSET_CH0LIMITL_Pos) /*!< Bit mask of CH0LIMITL field. */ +#define SAADC_INTENSET_CH0LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH0LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH0LIMITL_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for CH[0].LIMITH event */ +#define SAADC_INTENSET_CH0LIMITH_Pos (6UL) /*!< Position of CH0LIMITH field. */ +#define SAADC_INTENSET_CH0LIMITH_Msk (0x1UL << SAADC_INTENSET_CH0LIMITH_Pos) /*!< Bit mask of CH0LIMITH field. */ +#define SAADC_INTENSET_CH0LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CH0LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CH0LIMITH_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for STOPPED event */ +#define SAADC_INTENSET_STOPPED_Pos (5UL) /*!< Position of STOPPED field. */ +#define SAADC_INTENSET_STOPPED_Msk (0x1UL << SAADC_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define SAADC_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for CALIBRATEDONE event */ +#define SAADC_INTENSET_CALIBRATEDONE_Pos (4UL) /*!< Position of CALIBRATEDONE field. */ +#define SAADC_INTENSET_CALIBRATEDONE_Msk (0x1UL << SAADC_INTENSET_CALIBRATEDONE_Pos) /*!< Bit mask of CALIBRATEDONE field. */ +#define SAADC_INTENSET_CALIBRATEDONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_CALIBRATEDONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_CALIBRATEDONE_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for RESULTDONE event */ +#define SAADC_INTENSET_RESULTDONE_Pos (3UL) /*!< Position of RESULTDONE field. */ +#define SAADC_INTENSET_RESULTDONE_Msk (0x1UL << SAADC_INTENSET_RESULTDONE_Pos) /*!< Bit mask of RESULTDONE field. */ +#define SAADC_INTENSET_RESULTDONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_RESULTDONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_RESULTDONE_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for DONE event */ +#define SAADC_INTENSET_DONE_Pos (2UL) /*!< Position of DONE field. */ +#define SAADC_INTENSET_DONE_Msk (0x1UL << SAADC_INTENSET_DONE_Pos) /*!< Bit mask of DONE field. */ +#define SAADC_INTENSET_DONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_DONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_DONE_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for END event */ +#define SAADC_INTENSET_END_Pos (1UL) /*!< Position of END field. */ +#define SAADC_INTENSET_END_Msk (0x1UL << SAADC_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define SAADC_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for STARTED event */ +#define SAADC_INTENSET_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define SAADC_INTENSET_STARTED_Msk (0x1UL << SAADC_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define SAADC_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENSET_STARTED_Set (1UL) /*!< Enable */ + +/* Register: SAADC_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 21 : Write '1' to Disable interrupt for CH[7].LIMITL event */ +#define SAADC_INTENCLR_CH7LIMITL_Pos (21UL) /*!< Position of CH7LIMITL field. */ +#define SAADC_INTENCLR_CH7LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH7LIMITL_Pos) /*!< Bit mask of CH7LIMITL field. */ +#define SAADC_INTENCLR_CH7LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH7LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH7LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for CH[7].LIMITH event */ +#define SAADC_INTENCLR_CH7LIMITH_Pos (20UL) /*!< Position of CH7LIMITH field. */ +#define SAADC_INTENCLR_CH7LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH7LIMITH_Pos) /*!< Bit mask of CH7LIMITH field. */ +#define SAADC_INTENCLR_CH7LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH7LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH7LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for CH[6].LIMITL event */ +#define SAADC_INTENCLR_CH6LIMITL_Pos (19UL) /*!< Position of CH6LIMITL field. */ +#define SAADC_INTENCLR_CH6LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH6LIMITL_Pos) /*!< Bit mask of CH6LIMITL field. */ +#define SAADC_INTENCLR_CH6LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH6LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH6LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for CH[6].LIMITH event */ +#define SAADC_INTENCLR_CH6LIMITH_Pos (18UL) /*!< Position of CH6LIMITH field. */ +#define SAADC_INTENCLR_CH6LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH6LIMITH_Pos) /*!< Bit mask of CH6LIMITH field. */ +#define SAADC_INTENCLR_CH6LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH6LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH6LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for CH[5].LIMITL event */ +#define SAADC_INTENCLR_CH5LIMITL_Pos (17UL) /*!< Position of CH5LIMITL field. */ +#define SAADC_INTENCLR_CH5LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH5LIMITL_Pos) /*!< Bit mask of CH5LIMITL field. */ +#define SAADC_INTENCLR_CH5LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH5LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH5LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable interrupt for CH[5].LIMITH event */ +#define SAADC_INTENCLR_CH5LIMITH_Pos (16UL) /*!< Position of CH5LIMITH field. */ +#define SAADC_INTENCLR_CH5LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH5LIMITH_Pos) /*!< Bit mask of CH5LIMITH field. */ +#define SAADC_INTENCLR_CH5LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH5LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH5LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 15 : Write '1' to Disable interrupt for CH[4].LIMITL event */ +#define SAADC_INTENCLR_CH4LIMITL_Pos (15UL) /*!< Position of CH4LIMITL field. */ +#define SAADC_INTENCLR_CH4LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH4LIMITL_Pos) /*!< Bit mask of CH4LIMITL field. */ +#define SAADC_INTENCLR_CH4LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH4LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH4LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 14 : Write '1' to Disable interrupt for CH[4].LIMITH event */ +#define SAADC_INTENCLR_CH4LIMITH_Pos (14UL) /*!< Position of CH4LIMITH field. */ +#define SAADC_INTENCLR_CH4LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH4LIMITH_Pos) /*!< Bit mask of CH4LIMITH field. */ +#define SAADC_INTENCLR_CH4LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH4LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH4LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 13 : Write '1' to Disable interrupt for CH[3].LIMITL event */ +#define SAADC_INTENCLR_CH3LIMITL_Pos (13UL) /*!< Position of CH3LIMITL field. */ +#define SAADC_INTENCLR_CH3LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH3LIMITL_Pos) /*!< Bit mask of CH3LIMITL field. */ +#define SAADC_INTENCLR_CH3LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH3LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH3LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 12 : Write '1' to Disable interrupt for CH[3].LIMITH event */ +#define SAADC_INTENCLR_CH3LIMITH_Pos (12UL) /*!< Position of CH3LIMITH field. */ +#define SAADC_INTENCLR_CH3LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH3LIMITH_Pos) /*!< Bit mask of CH3LIMITH field. */ +#define SAADC_INTENCLR_CH3LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH3LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH3LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 11 : Write '1' to Disable interrupt for CH[2].LIMITL event */ +#define SAADC_INTENCLR_CH2LIMITL_Pos (11UL) /*!< Position of CH2LIMITL field. */ +#define SAADC_INTENCLR_CH2LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH2LIMITL_Pos) /*!< Bit mask of CH2LIMITL field. */ +#define SAADC_INTENCLR_CH2LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH2LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH2LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 10 : Write '1' to Disable interrupt for CH[2].LIMITH event */ +#define SAADC_INTENCLR_CH2LIMITH_Pos (10UL) /*!< Position of CH2LIMITH field. */ +#define SAADC_INTENCLR_CH2LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH2LIMITH_Pos) /*!< Bit mask of CH2LIMITH field. */ +#define SAADC_INTENCLR_CH2LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH2LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH2LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for CH[1].LIMITL event */ +#define SAADC_INTENCLR_CH1LIMITL_Pos (9UL) /*!< Position of CH1LIMITL field. */ +#define SAADC_INTENCLR_CH1LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH1LIMITL_Pos) /*!< Bit mask of CH1LIMITL field. */ +#define SAADC_INTENCLR_CH1LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH1LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH1LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for CH[1].LIMITH event */ +#define SAADC_INTENCLR_CH1LIMITH_Pos (8UL) /*!< Position of CH1LIMITH field. */ +#define SAADC_INTENCLR_CH1LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH1LIMITH_Pos) /*!< Bit mask of CH1LIMITH field. */ +#define SAADC_INTENCLR_CH1LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH1LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH1LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for CH[0].LIMITL event */ +#define SAADC_INTENCLR_CH0LIMITL_Pos (7UL) /*!< Position of CH0LIMITL field. */ +#define SAADC_INTENCLR_CH0LIMITL_Msk (0x1UL << SAADC_INTENCLR_CH0LIMITL_Pos) /*!< Bit mask of CH0LIMITL field. */ +#define SAADC_INTENCLR_CH0LIMITL_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH0LIMITL_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH0LIMITL_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for CH[0].LIMITH event */ +#define SAADC_INTENCLR_CH0LIMITH_Pos (6UL) /*!< Position of CH0LIMITH field. */ +#define SAADC_INTENCLR_CH0LIMITH_Msk (0x1UL << SAADC_INTENCLR_CH0LIMITH_Pos) /*!< Bit mask of CH0LIMITH field. */ +#define SAADC_INTENCLR_CH0LIMITH_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CH0LIMITH_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CH0LIMITH_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for STOPPED event */ +#define SAADC_INTENCLR_STOPPED_Pos (5UL) /*!< Position of STOPPED field. */ +#define SAADC_INTENCLR_STOPPED_Msk (0x1UL << SAADC_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define SAADC_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for CALIBRATEDONE event */ +#define SAADC_INTENCLR_CALIBRATEDONE_Pos (4UL) /*!< Position of CALIBRATEDONE field. */ +#define SAADC_INTENCLR_CALIBRATEDONE_Msk (0x1UL << SAADC_INTENCLR_CALIBRATEDONE_Pos) /*!< Bit mask of CALIBRATEDONE field. */ +#define SAADC_INTENCLR_CALIBRATEDONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_CALIBRATEDONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_CALIBRATEDONE_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for RESULTDONE event */ +#define SAADC_INTENCLR_RESULTDONE_Pos (3UL) /*!< Position of RESULTDONE field. */ +#define SAADC_INTENCLR_RESULTDONE_Msk (0x1UL << SAADC_INTENCLR_RESULTDONE_Pos) /*!< Bit mask of RESULTDONE field. */ +#define SAADC_INTENCLR_RESULTDONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_RESULTDONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_RESULTDONE_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for DONE event */ +#define SAADC_INTENCLR_DONE_Pos (2UL) /*!< Position of DONE field. */ +#define SAADC_INTENCLR_DONE_Msk (0x1UL << SAADC_INTENCLR_DONE_Pos) /*!< Bit mask of DONE field. */ +#define SAADC_INTENCLR_DONE_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_DONE_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_DONE_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for END event */ +#define SAADC_INTENCLR_END_Pos (1UL) /*!< Position of END field. */ +#define SAADC_INTENCLR_END_Msk (0x1UL << SAADC_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define SAADC_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for STARTED event */ +#define SAADC_INTENCLR_STARTED_Pos (0UL) /*!< Position of STARTED field. */ +#define SAADC_INTENCLR_STARTED_Msk (0x1UL << SAADC_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define SAADC_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define SAADC_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define SAADC_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ + +/* Register: SAADC_STATUS */ +/* Description: Status */ + +/* Bit 0 : Status */ +#define SAADC_STATUS_STATUS_Pos (0UL) /*!< Position of STATUS field. */ +#define SAADC_STATUS_STATUS_Msk (0x1UL << SAADC_STATUS_STATUS_Pos) /*!< Bit mask of STATUS field. */ +#define SAADC_STATUS_STATUS_Ready (0UL) /*!< ADC is ready. No on-going conversion. */ +#define SAADC_STATUS_STATUS_Busy (1UL) /*!< ADC is busy. Conversion in progress. */ + +/* Register: SAADC_ENABLE */ +/* Description: Enable or disable ADC */ + +/* Bit 0 : Enable or disable ADC */ +#define SAADC_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define SAADC_ENABLE_ENABLE_Msk (0x1UL << SAADC_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define SAADC_ENABLE_ENABLE_Disabled (0UL) /*!< Disable ADC */ +#define SAADC_ENABLE_ENABLE_Enabled (1UL) /*!< Enable ADC */ + +/* Register: SAADC_CH_PSELP */ +/* Description: Description cluster[0]: Input positive pin selection for CH[0] */ + +/* Bits 4..0 : Analog positive input channel */ +#define SAADC_CH_PSELP_PSELP_Pos (0UL) /*!< Position of PSELP field. */ +#define SAADC_CH_PSELP_PSELP_Msk (0x1FUL << SAADC_CH_PSELP_PSELP_Pos) /*!< Bit mask of PSELP field. */ +#define SAADC_CH_PSELP_PSELP_NC (0UL) /*!< Not connected */ +#define SAADC_CH_PSELP_PSELP_AnalogInput0 (1UL) /*!< AIN0 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput1 (2UL) /*!< AIN1 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput2 (3UL) /*!< AIN2 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput3 (4UL) /*!< AIN3 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput4 (5UL) /*!< AIN4 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput5 (6UL) /*!< AIN5 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput6 (7UL) /*!< AIN6 */ +#define SAADC_CH_PSELP_PSELP_AnalogInput7 (8UL) /*!< AIN7 */ +#define SAADC_CH_PSELP_PSELP_VDD (9UL) /*!< VDD */ +#define SAADC_CH_PSELP_PSELP_VDDHDIV5 (0x11UL) /*!< VDDH/5 */ + +/* Register: SAADC_CH_PSELN */ +/* Description: Description cluster[0]: Input negative pin selection for CH[0] */ + +/* Bits 4..0 : Analog negative input, enables differential channel */ +#define SAADC_CH_PSELN_PSELN_Pos (0UL) /*!< Position of PSELN field. */ +#define SAADC_CH_PSELN_PSELN_Msk (0x1FUL << SAADC_CH_PSELN_PSELN_Pos) /*!< Bit mask of PSELN field. */ +#define SAADC_CH_PSELN_PSELN_NC (0UL) /*!< Not connected */ +#define SAADC_CH_PSELN_PSELN_AnalogInput0 (1UL) /*!< AIN0 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput1 (2UL) /*!< AIN1 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput2 (3UL) /*!< AIN2 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput3 (4UL) /*!< AIN3 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput4 (5UL) /*!< AIN4 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput5 (6UL) /*!< AIN5 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput6 (7UL) /*!< AIN6 */ +#define SAADC_CH_PSELN_PSELN_AnalogInput7 (8UL) /*!< AIN7 */ +#define SAADC_CH_PSELN_PSELN_VDD (9UL) /*!< VDD */ +#define SAADC_CH_PSELN_PSELN_VDDHDIV5 (0x11UL) /*!< VDDH/5 */ + +/* Register: SAADC_CH_CONFIG */ +/* Description: Description cluster[0]: Input configuration for CH[0] */ + +/* Bit 24 : Enable burst mode */ +#define SAADC_CH_CONFIG_BURST_Pos (24UL) /*!< Position of BURST field. */ +#define SAADC_CH_CONFIG_BURST_Msk (0x1UL << SAADC_CH_CONFIG_BURST_Pos) /*!< Bit mask of BURST field. */ +#define SAADC_CH_CONFIG_BURST_Disabled (0UL) /*!< Burst mode is disabled (normal operation) */ +#define SAADC_CH_CONFIG_BURST_Enabled (1UL) /*!< Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM. */ + +/* Bit 20 : Enable differential mode */ +#define SAADC_CH_CONFIG_MODE_Pos (20UL) /*!< Position of MODE field. */ +#define SAADC_CH_CONFIG_MODE_Msk (0x1UL << SAADC_CH_CONFIG_MODE_Pos) /*!< Bit mask of MODE field. */ +#define SAADC_CH_CONFIG_MODE_SE (0UL) /*!< Single ended, PSELN will be ignored, negative input to ADC shorted to GND */ +#define SAADC_CH_CONFIG_MODE_Diff (1UL) /*!< Differential */ + +/* Bits 18..16 : Acquisition time, the time the ADC uses to sample the input voltage */ +#define SAADC_CH_CONFIG_TACQ_Pos (16UL) /*!< Position of TACQ field. */ +#define SAADC_CH_CONFIG_TACQ_Msk (0x7UL << SAADC_CH_CONFIG_TACQ_Pos) /*!< Bit mask of TACQ field. */ +#define SAADC_CH_CONFIG_TACQ_3us (0UL) /*!< 3 us */ +#define SAADC_CH_CONFIG_TACQ_5us (1UL) /*!< 5 us */ +#define SAADC_CH_CONFIG_TACQ_10us (2UL) /*!< 10 us */ +#define SAADC_CH_CONFIG_TACQ_15us (3UL) /*!< 15 us */ +#define SAADC_CH_CONFIG_TACQ_20us (4UL) /*!< 20 us */ +#define SAADC_CH_CONFIG_TACQ_40us (5UL) /*!< 40 us */ + +/* Bit 12 : Reference control */ +#define SAADC_CH_CONFIG_REFSEL_Pos (12UL) /*!< Position of REFSEL field. */ +#define SAADC_CH_CONFIG_REFSEL_Msk (0x1UL << SAADC_CH_CONFIG_REFSEL_Pos) /*!< Bit mask of REFSEL field. */ +#define SAADC_CH_CONFIG_REFSEL_Internal (0UL) /*!< Internal reference (0.6 V) */ +#define SAADC_CH_CONFIG_REFSEL_VDD1_4 (1UL) /*!< VDD/4 as reference */ + +/* Bits 10..8 : Gain control */ +#define SAADC_CH_CONFIG_GAIN_Pos (8UL) /*!< Position of GAIN field. */ +#define SAADC_CH_CONFIG_GAIN_Msk (0x7UL << SAADC_CH_CONFIG_GAIN_Pos) /*!< Bit mask of GAIN field. */ +#define SAADC_CH_CONFIG_GAIN_Gain1_6 (0UL) /*!< 1/6 */ +#define SAADC_CH_CONFIG_GAIN_Gain1_5 (1UL) /*!< 1/5 */ +#define SAADC_CH_CONFIG_GAIN_Gain1_4 (2UL) /*!< 1/4 */ +#define SAADC_CH_CONFIG_GAIN_Gain1_3 (3UL) /*!< 1/3 */ +#define SAADC_CH_CONFIG_GAIN_Gain1_2 (4UL) /*!< 1/2 */ +#define SAADC_CH_CONFIG_GAIN_Gain1 (5UL) /*!< 1 */ +#define SAADC_CH_CONFIG_GAIN_Gain2 (6UL) /*!< 2 */ +#define SAADC_CH_CONFIG_GAIN_Gain4 (7UL) /*!< 4 */ + +/* Bits 5..4 : Negative channel resistor control */ +#define SAADC_CH_CONFIG_RESN_Pos (4UL) /*!< Position of RESN field. */ +#define SAADC_CH_CONFIG_RESN_Msk (0x3UL << SAADC_CH_CONFIG_RESN_Pos) /*!< Bit mask of RESN field. */ +#define SAADC_CH_CONFIG_RESN_Bypass (0UL) /*!< Bypass resistor ladder */ +#define SAADC_CH_CONFIG_RESN_Pulldown (1UL) /*!< Pull-down to GND */ +#define SAADC_CH_CONFIG_RESN_Pullup (2UL) /*!< Pull-up to VDD */ +#define SAADC_CH_CONFIG_RESN_VDD1_2 (3UL) /*!< Set input at VDD/2 */ + +/* Bits 1..0 : Positive channel resistor control */ +#define SAADC_CH_CONFIG_RESP_Pos (0UL) /*!< Position of RESP field. */ +#define SAADC_CH_CONFIG_RESP_Msk (0x3UL << SAADC_CH_CONFIG_RESP_Pos) /*!< Bit mask of RESP field. */ +#define SAADC_CH_CONFIG_RESP_Bypass (0UL) /*!< Bypass resistor ladder */ +#define SAADC_CH_CONFIG_RESP_Pulldown (1UL) /*!< Pull-down to GND */ +#define SAADC_CH_CONFIG_RESP_Pullup (2UL) /*!< Pull-up to VDD */ +#define SAADC_CH_CONFIG_RESP_VDD1_2 (3UL) /*!< Set input at VDD/2 */ + +/* Register: SAADC_CH_LIMIT */ +/* Description: Description cluster[0]: High/low limits for event monitoring a channel */ + +/* Bits 31..16 : High level limit */ +#define SAADC_CH_LIMIT_HIGH_Pos (16UL) /*!< Position of HIGH field. */ +#define SAADC_CH_LIMIT_HIGH_Msk (0xFFFFUL << SAADC_CH_LIMIT_HIGH_Pos) /*!< Bit mask of HIGH field. */ + +/* Bits 15..0 : Low level limit */ +#define SAADC_CH_LIMIT_LOW_Pos (0UL) /*!< Position of LOW field. */ +#define SAADC_CH_LIMIT_LOW_Msk (0xFFFFUL << SAADC_CH_LIMIT_LOW_Pos) /*!< Bit mask of LOW field. */ + +/* Register: SAADC_RESOLUTION */ +/* Description: Resolution configuration */ + +/* Bits 2..0 : Set the resolution */ +#define SAADC_RESOLUTION_VAL_Pos (0UL) /*!< Position of VAL field. */ +#define SAADC_RESOLUTION_VAL_Msk (0x7UL << SAADC_RESOLUTION_VAL_Pos) /*!< Bit mask of VAL field. */ +#define SAADC_RESOLUTION_VAL_8bit (0UL) /*!< 8 bit */ +#define SAADC_RESOLUTION_VAL_10bit (1UL) /*!< 10 bit */ +#define SAADC_RESOLUTION_VAL_12bit (2UL) /*!< 12 bit */ +#define SAADC_RESOLUTION_VAL_14bit (3UL) /*!< 14 bit */ + +/* Register: SAADC_OVERSAMPLE */ +/* Description: Oversampling configuration. OVERSAMPLE should not be combined with SCAN. The RESOLUTION is applied before averaging, thus for high OVERSAMPLE a higher RESOLUTION should be used. */ + +/* Bits 3..0 : Oversample control */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Pos (0UL) /*!< Position of OVERSAMPLE field. */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Msk (0xFUL << SAADC_OVERSAMPLE_OVERSAMPLE_Pos) /*!< Bit mask of OVERSAMPLE field. */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Bypass (0UL) /*!< Bypass oversampling */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over2x (1UL) /*!< Oversample 2x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over4x (2UL) /*!< Oversample 4x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over8x (3UL) /*!< Oversample 8x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over16x (4UL) /*!< Oversample 16x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over32x (5UL) /*!< Oversample 32x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over64x (6UL) /*!< Oversample 64x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over128x (7UL) /*!< Oversample 128x */ +#define SAADC_OVERSAMPLE_OVERSAMPLE_Over256x (8UL) /*!< Oversample 256x */ + +/* Register: SAADC_SAMPLERATE */ +/* Description: Controls normal or continuous sample rate */ + +/* Bit 12 : Select mode for sample rate control */ +#define SAADC_SAMPLERATE_MODE_Pos (12UL) /*!< Position of MODE field. */ +#define SAADC_SAMPLERATE_MODE_Msk (0x1UL << SAADC_SAMPLERATE_MODE_Pos) /*!< Bit mask of MODE field. */ +#define SAADC_SAMPLERATE_MODE_Task (0UL) /*!< Rate is controlled from SAMPLE task */ +#define SAADC_SAMPLERATE_MODE_Timers (1UL) /*!< Rate is controlled from local timer (use CC to control the rate) */ + +/* Bits 10..0 : Capture and compare value. Sample rate is 16 MHz/CC */ +#define SAADC_SAMPLERATE_CC_Pos (0UL) /*!< Position of CC field. */ +#define SAADC_SAMPLERATE_CC_Msk (0x7FFUL << SAADC_SAMPLERATE_CC_Pos) /*!< Bit mask of CC field. */ + +/* Register: SAADC_RESULT_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define SAADC_RESULT_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define SAADC_RESULT_PTR_PTR_Msk (0xFFFFFFFFUL << SAADC_RESULT_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: SAADC_RESULT_MAXCNT */ +/* Description: Maximum number of buffer words to transfer */ + +/* Bits 14..0 : Maximum number of buffer words to transfer */ +#define SAADC_RESULT_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define SAADC_RESULT_MAXCNT_MAXCNT_Msk (0x7FFFUL << SAADC_RESULT_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: SAADC_RESULT_AMOUNT */ +/* Description: Number of buffer words transferred since last START */ + +/* Bits 14..0 : Number of buffer words transferred since last START. This register can be read after an END or STOPPED event. */ +#define SAADC_RESULT_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define SAADC_RESULT_AMOUNT_AMOUNT_Msk (0x7FFFUL << SAADC_RESULT_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + + +/* Peripheral: SPI */ +/* Description: Serial Peripheral Interface 0 */ + +/* Register: SPI_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 2 : Write '1' to Enable interrupt for READY event */ +#define SPI_INTENSET_READY_Pos (2UL) /*!< Position of READY field. */ +#define SPI_INTENSET_READY_Msk (0x1UL << SPI_INTENSET_READY_Pos) /*!< Bit mask of READY field. */ +#define SPI_INTENSET_READY_Disabled (0UL) /*!< Read: Disabled */ +#define SPI_INTENSET_READY_Enabled (1UL) /*!< Read: Enabled */ +#define SPI_INTENSET_READY_Set (1UL) /*!< Enable */ + +/* Register: SPI_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 2 : Write '1' to Disable interrupt for READY event */ +#define SPI_INTENCLR_READY_Pos (2UL) /*!< Position of READY field. */ +#define SPI_INTENCLR_READY_Msk (0x1UL << SPI_INTENCLR_READY_Pos) /*!< Bit mask of READY field. */ +#define SPI_INTENCLR_READY_Disabled (0UL) /*!< Read: Disabled */ +#define SPI_INTENCLR_READY_Enabled (1UL) /*!< Read: Enabled */ +#define SPI_INTENCLR_READY_Clear (1UL) /*!< Disable */ + +/* Register: SPI_ENABLE */ +/* Description: Enable SPI */ + +/* Bits 3..0 : Enable or disable SPI */ +#define SPI_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define SPI_ENABLE_ENABLE_Msk (0xFUL << SPI_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define SPI_ENABLE_ENABLE_Disabled (0UL) /*!< Disable SPI */ +#define SPI_ENABLE_ENABLE_Enabled (1UL) /*!< Enable SPI */ + +/* Register: SPI_PSEL_SCK */ +/* Description: Pin select for SCK */ + +/* Bit 31 : Connection */ +#define SPI_PSEL_SCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPI_PSEL_SCK_CONNECT_Msk (0x1UL << SPI_PSEL_SCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPI_PSEL_SCK_CONNECT_Connected (0UL) /*!< Connect */ +#define SPI_PSEL_SCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPI_PSEL_SCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPI_PSEL_SCK_PORT_Msk (0x3UL << SPI_PSEL_SCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPI_PSEL_SCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPI_PSEL_SCK_PIN_Msk (0x1FUL << SPI_PSEL_SCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPI_PSEL_MOSI */ +/* Description: Pin select for MOSI signal */ + +/* Bit 31 : Connection */ +#define SPI_PSEL_MOSI_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPI_PSEL_MOSI_CONNECT_Msk (0x1UL << SPI_PSEL_MOSI_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPI_PSEL_MOSI_CONNECT_Connected (0UL) /*!< Connect */ +#define SPI_PSEL_MOSI_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPI_PSEL_MOSI_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPI_PSEL_MOSI_PORT_Msk (0x3UL << SPI_PSEL_MOSI_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPI_PSEL_MOSI_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPI_PSEL_MOSI_PIN_Msk (0x1FUL << SPI_PSEL_MOSI_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPI_PSEL_MISO */ +/* Description: Pin select for MISO signal */ + +/* Bit 31 : Connection */ +#define SPI_PSEL_MISO_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPI_PSEL_MISO_CONNECT_Msk (0x1UL << SPI_PSEL_MISO_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPI_PSEL_MISO_CONNECT_Connected (0UL) /*!< Connect */ +#define SPI_PSEL_MISO_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPI_PSEL_MISO_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPI_PSEL_MISO_PORT_Msk (0x3UL << SPI_PSEL_MISO_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPI_PSEL_MISO_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPI_PSEL_MISO_PIN_Msk (0x1FUL << SPI_PSEL_MISO_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPI_RXD */ +/* Description: RXD register */ + +/* Bits 7..0 : RX data received. Double buffered */ +#define SPI_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */ +#define SPI_RXD_RXD_Msk (0xFFUL << SPI_RXD_RXD_Pos) /*!< Bit mask of RXD field. */ + +/* Register: SPI_TXD */ +/* Description: TXD register */ + +/* Bits 7..0 : TX data to send. Double buffered */ +#define SPI_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */ +#define SPI_TXD_TXD_Msk (0xFFUL << SPI_TXD_TXD_Pos) /*!< Bit mask of TXD field. */ + +/* Register: SPI_FREQUENCY */ +/* Description: SPI frequency. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : SPI master data rate */ +#define SPI_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ +#define SPI_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << SPI_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ +#define SPI_FREQUENCY_FREQUENCY_K125 (0x02000000UL) /*!< 125 kbps */ +#define SPI_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps */ +#define SPI_FREQUENCY_FREQUENCY_K500 (0x08000000UL) /*!< 500 kbps */ +#define SPI_FREQUENCY_FREQUENCY_M1 (0x10000000UL) /*!< 1 Mbps */ +#define SPI_FREQUENCY_FREQUENCY_M2 (0x20000000UL) /*!< 2 Mbps */ +#define SPI_FREQUENCY_FREQUENCY_M4 (0x40000000UL) /*!< 4 Mbps */ +#define SPI_FREQUENCY_FREQUENCY_M8 (0x80000000UL) /*!< 8 Mbps */ + +/* Register: SPI_CONFIG */ +/* Description: Configuration register */ + +/* Bit 2 : Serial clock (SCK) polarity */ +#define SPI_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */ +#define SPI_CONFIG_CPOL_Msk (0x1UL << SPI_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */ +#define SPI_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high */ +#define SPI_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low */ + +/* Bit 1 : Serial clock (SCK) phase */ +#define SPI_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */ +#define SPI_CONFIG_CPHA_Msk (0x1UL << SPI_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */ +#define SPI_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of clock, shift serial data on trailing edge */ +#define SPI_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of clock, shift serial data on leading edge */ + +/* Bit 0 : Bit order */ +#define SPI_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */ +#define SPI_CONFIG_ORDER_Msk (0x1UL << SPI_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */ +#define SPI_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit shifted out first */ +#define SPI_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit shifted out first */ + + +/* Peripheral: SPIM */ +/* Description: Serial Peripheral Interface Master with EasyDMA 0 */ + +/* Register: SPIM_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 17 : Shortcut between END event and START task */ +#define SPIM_SHORTS_END_START_Pos (17UL) /*!< Position of END_START field. */ +#define SPIM_SHORTS_END_START_Msk (0x1UL << SPIM_SHORTS_END_START_Pos) /*!< Bit mask of END_START field. */ +#define SPIM_SHORTS_END_START_Disabled (0UL) /*!< Disable shortcut */ +#define SPIM_SHORTS_END_START_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: SPIM_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 19 : Write '1' to Enable interrupt for STARTED event */ +#define SPIM_INTENSET_STARTED_Pos (19UL) /*!< Position of STARTED field. */ +#define SPIM_INTENSET_STARTED_Msk (0x1UL << SPIM_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define SPIM_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENSET_STARTED_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for ENDTX event */ +#define SPIM_INTENSET_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ +#define SPIM_INTENSET_ENDTX_Msk (0x1UL << SPIM_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define SPIM_INTENSET_ENDTX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENSET_ENDTX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENSET_ENDTX_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for END event */ +#define SPIM_INTENSET_END_Pos (6UL) /*!< Position of END field. */ +#define SPIM_INTENSET_END_Msk (0x1UL << SPIM_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define SPIM_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for ENDRX event */ +#define SPIM_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define SPIM_INTENSET_ENDRX_Msk (0x1UL << SPIM_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define SPIM_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENSET_ENDRX_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define SPIM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define SPIM_INTENSET_STOPPED_Msk (0x1UL << SPIM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define SPIM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Register: SPIM_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 19 : Write '1' to Disable interrupt for STARTED event */ +#define SPIM_INTENCLR_STARTED_Pos (19UL) /*!< Position of STARTED field. */ +#define SPIM_INTENCLR_STARTED_Msk (0x1UL << SPIM_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define SPIM_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for ENDTX event */ +#define SPIM_INTENCLR_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ +#define SPIM_INTENCLR_ENDTX_Msk (0x1UL << SPIM_INTENCLR_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define SPIM_INTENCLR_ENDTX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENCLR_ENDTX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENCLR_ENDTX_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for END event */ +#define SPIM_INTENCLR_END_Pos (6UL) /*!< Position of END field. */ +#define SPIM_INTENCLR_END_Msk (0x1UL << SPIM_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define SPIM_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for ENDRX event */ +#define SPIM_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define SPIM_INTENCLR_ENDRX_Msk (0x1UL << SPIM_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define SPIM_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define SPIM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define SPIM_INTENCLR_STOPPED_Msk (0x1UL << SPIM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define SPIM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIM_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Register: SPIM_STALLSTAT */ +/* Description: Stall status for EasyDMA RAM accesses. The fields in this register is set to STALL by hardware whenever a stall occurres and can be cleared (set to NOSTALL) by the CPU. */ + +/* Bit 1 : Stall status for EasyDMA RAM writes */ +#define SPIM_STALLSTAT_RX_Pos (1UL) /*!< Position of RX field. */ +#define SPIM_STALLSTAT_RX_Msk (0x1UL << SPIM_STALLSTAT_RX_Pos) /*!< Bit mask of RX field. */ +#define SPIM_STALLSTAT_RX_NOSTALL (0UL) /*!< No stall */ +#define SPIM_STALLSTAT_RX_STALL (1UL) /*!< A stall has occurred */ + +/* Bit 0 : Stall status for EasyDMA RAM reads */ +#define SPIM_STALLSTAT_TX_Pos (0UL) /*!< Position of TX field. */ +#define SPIM_STALLSTAT_TX_Msk (0x1UL << SPIM_STALLSTAT_TX_Pos) /*!< Bit mask of TX field. */ +#define SPIM_STALLSTAT_TX_NOSTALL (0UL) /*!< No stall */ +#define SPIM_STALLSTAT_TX_STALL (1UL) /*!< A stall has occurred */ + +/* Register: SPIM_ENABLE */ +/* Description: Enable SPIM */ + +/* Bits 3..0 : Enable or disable SPIM */ +#define SPIM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define SPIM_ENABLE_ENABLE_Msk (0xFUL << SPIM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define SPIM_ENABLE_ENABLE_Disabled (0UL) /*!< Disable SPIM */ +#define SPIM_ENABLE_ENABLE_Enabled (7UL) /*!< Enable SPIM */ + +/* Register: SPIM_PSEL_SCK */ +/* Description: Pin select for SCK */ + +/* Bit 31 : Connection */ +#define SPIM_PSEL_SCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIM_PSEL_SCK_CONNECT_Msk (0x1UL << SPIM_PSEL_SCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIM_PSEL_SCK_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIM_PSEL_SCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPIM_PSEL_SCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIM_PSEL_SCK_PORT_Msk (0x3UL << SPIM_PSEL_SCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIM_PSEL_SCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIM_PSEL_SCK_PIN_Msk (0x1FUL << SPIM_PSEL_SCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIM_PSEL_MOSI */ +/* Description: Pin select for MOSI signal */ + +/* Bit 31 : Connection */ +#define SPIM_PSEL_MOSI_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIM_PSEL_MOSI_CONNECT_Msk (0x1UL << SPIM_PSEL_MOSI_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIM_PSEL_MOSI_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIM_PSEL_MOSI_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPIM_PSEL_MOSI_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIM_PSEL_MOSI_PORT_Msk (0x3UL << SPIM_PSEL_MOSI_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIM_PSEL_MOSI_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIM_PSEL_MOSI_PIN_Msk (0x1FUL << SPIM_PSEL_MOSI_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIM_PSEL_MISO */ +/* Description: Pin select for MISO signal */ + +/* Bit 31 : Connection */ +#define SPIM_PSEL_MISO_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIM_PSEL_MISO_CONNECT_Msk (0x1UL << SPIM_PSEL_MISO_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIM_PSEL_MISO_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIM_PSEL_MISO_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPIM_PSEL_MISO_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIM_PSEL_MISO_PORT_Msk (0x3UL << SPIM_PSEL_MISO_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIM_PSEL_MISO_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIM_PSEL_MISO_PIN_Msk (0x1FUL << SPIM_PSEL_MISO_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIM_PSEL_CSN */ +/* Description: Pin select for CSN */ + +/* Bit 31 : Connection */ +#define SPIM_PSEL_CSN_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIM_PSEL_CSN_CONNECT_Msk (0x1UL << SPIM_PSEL_CSN_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIM_PSEL_CSN_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIM_PSEL_CSN_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPIM_PSEL_CSN_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIM_PSEL_CSN_PORT_Msk (0x3UL << SPIM_PSEL_CSN_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIM_PSEL_CSN_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIM_PSEL_CSN_PIN_Msk (0x1FUL << SPIM_PSEL_CSN_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIM_FREQUENCY */ +/* Description: SPI frequency. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : SPI master data rate */ +#define SPIM_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ +#define SPIM_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << SPIM_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ +#define SPIM_FREQUENCY_FREQUENCY_K125 (0x02000000UL) /*!< 125 kbps */ +#define SPIM_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps */ +#define SPIM_FREQUENCY_FREQUENCY_K500 (0x08000000UL) /*!< 500 kbps */ +#define SPIM_FREQUENCY_FREQUENCY_M16 (0x0A000000UL) /*!< 16 Mbps */ +#define SPIM_FREQUENCY_FREQUENCY_M1 (0x10000000UL) /*!< 1 Mbps */ +#define SPIM_FREQUENCY_FREQUENCY_M32 (0x14000000UL) /*!< 32 Mbps */ +#define SPIM_FREQUENCY_FREQUENCY_M2 (0x20000000UL) /*!< 2 Mbps */ +#define SPIM_FREQUENCY_FREQUENCY_M4 (0x40000000UL) /*!< 4 Mbps */ +#define SPIM_FREQUENCY_FREQUENCY_M8 (0x80000000UL) /*!< 8 Mbps */ + +/* Register: SPIM_RXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define SPIM_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define SPIM_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIM_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: SPIM_RXD_MAXCNT */ +/* Description: Maximum number of bytes in receive buffer */ + +/* Bits 15..0 : Maximum number of bytes in receive buffer */ +#define SPIM_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define SPIM_RXD_MAXCNT_MAXCNT_Msk (0xFFFFUL << SPIM_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: SPIM_RXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 15..0 : Number of bytes transferred in the last transaction */ +#define SPIM_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define SPIM_RXD_AMOUNT_AMOUNT_Msk (0xFFFFUL << SPIM_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: SPIM_RXD_LIST */ +/* Description: EasyDMA list type */ + +/* Bits 1..0 : List type */ +#define SPIM_RXD_LIST_LIST_Pos (0UL) /*!< Position of LIST field. */ +#define SPIM_RXD_LIST_LIST_Msk (0x3UL << SPIM_RXD_LIST_LIST_Pos) /*!< Bit mask of LIST field. */ +#define SPIM_RXD_LIST_LIST_Disabled (0UL) /*!< Disable EasyDMA list */ +#define SPIM_RXD_LIST_LIST_ArrayList (1UL) /*!< Use array list */ + +/* Register: SPIM_TXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define SPIM_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define SPIM_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIM_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: SPIM_TXD_MAXCNT */ +/* Description: Number of bytes in transmit buffer */ + +/* Bits 15..0 : Maximum number of bytes in transmit buffer */ +#define SPIM_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define SPIM_TXD_MAXCNT_MAXCNT_Msk (0xFFFFUL << SPIM_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: SPIM_TXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 15..0 : Number of bytes transferred in the last transaction */ +#define SPIM_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define SPIM_TXD_AMOUNT_AMOUNT_Msk (0xFFFFUL << SPIM_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: SPIM_TXD_LIST */ +/* Description: EasyDMA list type */ + +/* Bits 1..0 : List type */ +#define SPIM_TXD_LIST_LIST_Pos (0UL) /*!< Position of LIST field. */ +#define SPIM_TXD_LIST_LIST_Msk (0x3UL << SPIM_TXD_LIST_LIST_Pos) /*!< Bit mask of LIST field. */ +#define SPIM_TXD_LIST_LIST_Disabled (0UL) /*!< Disable EasyDMA list */ +#define SPIM_TXD_LIST_LIST_ArrayList (1UL) /*!< Use array list */ + +/* Register: SPIM_CONFIG */ +/* Description: Configuration register */ + +/* Bit 2 : Serial clock (SCK) polarity */ +#define SPIM_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */ +#define SPIM_CONFIG_CPOL_Msk (0x1UL << SPIM_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */ +#define SPIM_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high */ +#define SPIM_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low */ + +/* Bit 1 : Serial clock (SCK) phase */ +#define SPIM_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */ +#define SPIM_CONFIG_CPHA_Msk (0x1UL << SPIM_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */ +#define SPIM_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of clock, shift serial data on trailing edge */ +#define SPIM_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of clock, shift serial data on leading edge */ + +/* Bit 0 : Bit order */ +#define SPIM_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */ +#define SPIM_CONFIG_ORDER_Msk (0x1UL << SPIM_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */ +#define SPIM_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit shifted out first */ +#define SPIM_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit shifted out first */ + +/* Register: SPIM_IFTIMING_RXDELAY */ +/* Description: Sample delay for input serial data on MISO */ + +/* Bits 2..0 : Sample delay for input serial data on MISO. The value specifies the number of 64 MHz clock cycles (15.625 ns) delay from the the sampling edge of SCK (leading edge for CONFIG.CPHA = 0, trailing edge for CONFIG.CPHA = 1) until the input serial data is sampled. As en example, if RXDELAY = 0 and CONFIG.CPHA = 0, the input serial data is sampled on the rising edge of SCK. */ +#define SPIM_IFTIMING_RXDELAY_RXDELAY_Pos (0UL) /*!< Position of RXDELAY field. */ +#define SPIM_IFTIMING_RXDELAY_RXDELAY_Msk (0x7UL << SPIM_IFTIMING_RXDELAY_RXDELAY_Pos) /*!< Bit mask of RXDELAY field. */ + +/* Register: SPIM_IFTIMING_CSNDUR */ +/* Description: Minimum duration between edge of CSN and edge of SCK and minimum duration CSN must stay high between transactions */ + +/* Bits 7..0 : Minimum duration between edge of CSN and edge of SCK and minimum duration CSN must stay high between transactions. The value is specified in number of 64 MHz clock cycles (15.625 ns). */ +#define SPIM_IFTIMING_CSNDUR_CSNDUR_Pos (0UL) /*!< Position of CSNDUR field. */ +#define SPIM_IFTIMING_CSNDUR_CSNDUR_Msk (0xFFUL << SPIM_IFTIMING_CSNDUR_CSNDUR_Pos) /*!< Bit mask of CSNDUR field. */ + +/* Register: SPIM_ORC */ +/* Description: Byte transmitted after TXD.MAXCNT bytes have been transmitted in the case when RXD.MAXCNT is greater than TXD.MAXCNT */ + +/* Bits 7..0 : Byte transmitted after TXD.MAXCNT bytes have been transmitted in the case when RXD.MAXCNT is greater than TXD.MAXCNT. */ +#define SPIM_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */ +#define SPIM_ORC_ORC_Msk (0xFFUL << SPIM_ORC_ORC_Pos) /*!< Bit mask of ORC field. */ + + +/* Peripheral: SPIS */ +/* Description: SPI Slave 0 */ + +/* Register: SPIS_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 2 : Shortcut between END event and ACQUIRE task */ +#define SPIS_SHORTS_END_ACQUIRE_Pos (2UL) /*!< Position of END_ACQUIRE field. */ +#define SPIS_SHORTS_END_ACQUIRE_Msk (0x1UL << SPIS_SHORTS_END_ACQUIRE_Pos) /*!< Bit mask of END_ACQUIRE field. */ +#define SPIS_SHORTS_END_ACQUIRE_Disabled (0UL) /*!< Disable shortcut */ +#define SPIS_SHORTS_END_ACQUIRE_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: SPIS_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 10 : Write '1' to Enable interrupt for ACQUIRED event */ +#define SPIS_INTENSET_ACQUIRED_Pos (10UL) /*!< Position of ACQUIRED field. */ +#define SPIS_INTENSET_ACQUIRED_Msk (0x1UL << SPIS_INTENSET_ACQUIRED_Pos) /*!< Bit mask of ACQUIRED field. */ +#define SPIS_INTENSET_ACQUIRED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENSET_ACQUIRED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENSET_ACQUIRED_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for ENDRX event */ +#define SPIS_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define SPIS_INTENSET_ENDRX_Msk (0x1UL << SPIS_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define SPIS_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENSET_ENDRX_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for END event */ +#define SPIS_INTENSET_END_Pos (1UL) /*!< Position of END field. */ +#define SPIS_INTENSET_END_Msk (0x1UL << SPIS_INTENSET_END_Pos) /*!< Bit mask of END field. */ +#define SPIS_INTENSET_END_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENSET_END_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENSET_END_Set (1UL) /*!< Enable */ + +/* Register: SPIS_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 10 : Write '1' to Disable interrupt for ACQUIRED event */ +#define SPIS_INTENCLR_ACQUIRED_Pos (10UL) /*!< Position of ACQUIRED field. */ +#define SPIS_INTENCLR_ACQUIRED_Msk (0x1UL << SPIS_INTENCLR_ACQUIRED_Pos) /*!< Bit mask of ACQUIRED field. */ +#define SPIS_INTENCLR_ACQUIRED_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENCLR_ACQUIRED_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENCLR_ACQUIRED_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for ENDRX event */ +#define SPIS_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define SPIS_INTENCLR_ENDRX_Msk (0x1UL << SPIS_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define SPIS_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for END event */ +#define SPIS_INTENCLR_END_Pos (1UL) /*!< Position of END field. */ +#define SPIS_INTENCLR_END_Msk (0x1UL << SPIS_INTENCLR_END_Pos) /*!< Bit mask of END field. */ +#define SPIS_INTENCLR_END_Disabled (0UL) /*!< Read: Disabled */ +#define SPIS_INTENCLR_END_Enabled (1UL) /*!< Read: Enabled */ +#define SPIS_INTENCLR_END_Clear (1UL) /*!< Disable */ + +/* Register: SPIS_SEMSTAT */ +/* Description: Semaphore status register */ + +/* Bits 1..0 : Semaphore status */ +#define SPIS_SEMSTAT_SEMSTAT_Pos (0UL) /*!< Position of SEMSTAT field. */ +#define SPIS_SEMSTAT_SEMSTAT_Msk (0x3UL << SPIS_SEMSTAT_SEMSTAT_Pos) /*!< Bit mask of SEMSTAT field. */ +#define SPIS_SEMSTAT_SEMSTAT_Free (0UL) /*!< Semaphore is free */ +#define SPIS_SEMSTAT_SEMSTAT_CPU (1UL) /*!< Semaphore is assigned to CPU */ +#define SPIS_SEMSTAT_SEMSTAT_SPIS (2UL) /*!< Semaphore is assigned to SPI slave */ +#define SPIS_SEMSTAT_SEMSTAT_CPUPending (3UL) /*!< Semaphore is assigned to SPI but a handover to the CPU is pending */ + +/* Register: SPIS_STATUS */ +/* Description: Status from last transaction */ + +/* Bit 1 : RX buffer overflow detected, and prevented */ +#define SPIS_STATUS_OVERFLOW_Pos (1UL) /*!< Position of OVERFLOW field. */ +#define SPIS_STATUS_OVERFLOW_Msk (0x1UL << SPIS_STATUS_OVERFLOW_Pos) /*!< Bit mask of OVERFLOW field. */ +#define SPIS_STATUS_OVERFLOW_NotPresent (0UL) /*!< Read: error not present */ +#define SPIS_STATUS_OVERFLOW_Present (1UL) /*!< Read: error present */ +#define SPIS_STATUS_OVERFLOW_Clear (1UL) /*!< Write: clear error on writing '1' */ + +/* Bit 0 : TX buffer over-read detected, and prevented */ +#define SPIS_STATUS_OVERREAD_Pos (0UL) /*!< Position of OVERREAD field. */ +#define SPIS_STATUS_OVERREAD_Msk (0x1UL << SPIS_STATUS_OVERREAD_Pos) /*!< Bit mask of OVERREAD field. */ +#define SPIS_STATUS_OVERREAD_NotPresent (0UL) /*!< Read: error not present */ +#define SPIS_STATUS_OVERREAD_Present (1UL) /*!< Read: error present */ +#define SPIS_STATUS_OVERREAD_Clear (1UL) /*!< Write: clear error on writing '1' */ + +/* Register: SPIS_ENABLE */ +/* Description: Enable SPI slave */ + +/* Bits 3..0 : Enable or disable SPI slave */ +#define SPIS_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define SPIS_ENABLE_ENABLE_Msk (0xFUL << SPIS_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define SPIS_ENABLE_ENABLE_Disabled (0UL) /*!< Disable SPI slave */ +#define SPIS_ENABLE_ENABLE_Enabled (2UL) /*!< Enable SPI slave */ + +/* Register: SPIS_PSEL_SCK */ +/* Description: Pin select for SCK */ + +/* Bit 31 : Connection */ +#define SPIS_PSEL_SCK_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIS_PSEL_SCK_CONNECT_Msk (0x1UL << SPIS_PSEL_SCK_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIS_PSEL_SCK_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIS_PSEL_SCK_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPIS_PSEL_SCK_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIS_PSEL_SCK_PORT_Msk (0x3UL << SPIS_PSEL_SCK_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIS_PSEL_SCK_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIS_PSEL_SCK_PIN_Msk (0x1FUL << SPIS_PSEL_SCK_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIS_PSEL_MISO */ +/* Description: Pin select for MISO signal */ + +/* Bit 31 : Connection */ +#define SPIS_PSEL_MISO_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIS_PSEL_MISO_CONNECT_Msk (0x1UL << SPIS_PSEL_MISO_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIS_PSEL_MISO_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIS_PSEL_MISO_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPIS_PSEL_MISO_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIS_PSEL_MISO_PORT_Msk (0x3UL << SPIS_PSEL_MISO_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIS_PSEL_MISO_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIS_PSEL_MISO_PIN_Msk (0x1FUL << SPIS_PSEL_MISO_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIS_PSEL_MOSI */ +/* Description: Pin select for MOSI signal */ + +/* Bit 31 : Connection */ +#define SPIS_PSEL_MOSI_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIS_PSEL_MOSI_CONNECT_Msk (0x1UL << SPIS_PSEL_MOSI_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIS_PSEL_MOSI_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIS_PSEL_MOSI_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPIS_PSEL_MOSI_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIS_PSEL_MOSI_PORT_Msk (0x3UL << SPIS_PSEL_MOSI_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIS_PSEL_MOSI_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIS_PSEL_MOSI_PIN_Msk (0x1FUL << SPIS_PSEL_MOSI_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIS_PSEL_CSN */ +/* Description: Pin select for CSN signal */ + +/* Bit 31 : Connection */ +#define SPIS_PSEL_CSN_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define SPIS_PSEL_CSN_CONNECT_Msk (0x1UL << SPIS_PSEL_CSN_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define SPIS_PSEL_CSN_CONNECT_Connected (0UL) /*!< Connect */ +#define SPIS_PSEL_CSN_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define SPIS_PSEL_CSN_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define SPIS_PSEL_CSN_PORT_Msk (0x3UL << SPIS_PSEL_CSN_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define SPIS_PSEL_CSN_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define SPIS_PSEL_CSN_PIN_Msk (0x1FUL << SPIS_PSEL_CSN_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: SPIS_RXD_PTR */ +/* Description: RXD data pointer */ + +/* Bits 31..0 : RXD data pointer */ +#define SPIS_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define SPIS_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIS_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: SPIS_RXD_MAXCNT */ +/* Description: Maximum number of bytes in receive buffer */ + +/* Bits 7..0 : Maximum number of bytes in receive buffer */ +#define SPIS_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define SPIS_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << SPIS_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: SPIS_RXD_AMOUNT */ +/* Description: Number of bytes received in last granted transaction */ + +/* Bits 7..0 : Number of bytes received in the last granted transaction */ +#define SPIS_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define SPIS_RXD_AMOUNT_AMOUNT_Msk (0xFFUL << SPIS_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: SPIS_TXD_PTR */ +/* Description: TXD data pointer */ + +/* Bits 31..0 : TXD data pointer */ +#define SPIS_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define SPIS_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << SPIS_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: SPIS_TXD_MAXCNT */ +/* Description: Maximum number of bytes in transmit buffer */ + +/* Bits 7..0 : Maximum number of bytes in transmit buffer */ +#define SPIS_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define SPIS_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << SPIS_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: SPIS_TXD_AMOUNT */ +/* Description: Number of bytes transmitted in last granted transaction */ + +/* Bits 7..0 : Number of bytes transmitted in last granted transaction */ +#define SPIS_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define SPIS_TXD_AMOUNT_AMOUNT_Msk (0xFFUL << SPIS_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: SPIS_CONFIG */ +/* Description: Configuration register */ + +/* Bit 2 : Serial clock (SCK) polarity */ +#define SPIS_CONFIG_CPOL_Pos (2UL) /*!< Position of CPOL field. */ +#define SPIS_CONFIG_CPOL_Msk (0x1UL << SPIS_CONFIG_CPOL_Pos) /*!< Bit mask of CPOL field. */ +#define SPIS_CONFIG_CPOL_ActiveHigh (0UL) /*!< Active high */ +#define SPIS_CONFIG_CPOL_ActiveLow (1UL) /*!< Active low */ + +/* Bit 1 : Serial clock (SCK) phase */ +#define SPIS_CONFIG_CPHA_Pos (1UL) /*!< Position of CPHA field. */ +#define SPIS_CONFIG_CPHA_Msk (0x1UL << SPIS_CONFIG_CPHA_Pos) /*!< Bit mask of CPHA field. */ +#define SPIS_CONFIG_CPHA_Leading (0UL) /*!< Sample on leading edge of clock, shift serial data on trailing edge */ +#define SPIS_CONFIG_CPHA_Trailing (1UL) /*!< Sample on trailing edge of clock, shift serial data on leading edge */ + +/* Bit 0 : Bit order */ +#define SPIS_CONFIG_ORDER_Pos (0UL) /*!< Position of ORDER field. */ +#define SPIS_CONFIG_ORDER_Msk (0x1UL << SPIS_CONFIG_ORDER_Pos) /*!< Bit mask of ORDER field. */ +#define SPIS_CONFIG_ORDER_MsbFirst (0UL) /*!< Most significant bit shifted out first */ +#define SPIS_CONFIG_ORDER_LsbFirst (1UL) /*!< Least significant bit shifted out first */ + +/* Register: SPIS_DEF */ +/* Description: Default character. Character clocked out in case of an ignored transaction. */ + +/* Bits 7..0 : Default character. Character clocked out in case of an ignored transaction. */ +#define SPIS_DEF_DEF_Pos (0UL) /*!< Position of DEF field. */ +#define SPIS_DEF_DEF_Msk (0xFFUL << SPIS_DEF_DEF_Pos) /*!< Bit mask of DEF field. */ + +/* Register: SPIS_ORC */ +/* Description: Over-read character */ + +/* Bits 7..0 : Over-read character. Character clocked out after an over-read of the transmit buffer. */ +#define SPIS_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */ +#define SPIS_ORC_ORC_Msk (0xFFUL << SPIS_ORC_ORC_Pos) /*!< Bit mask of ORC field. */ + + +/* Peripheral: TEMP */ +/* Description: Temperature Sensor */ + +/* Register: TEMP_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 0 : Write '1' to Enable interrupt for DATARDY event */ +#define TEMP_INTENSET_DATARDY_Pos (0UL) /*!< Position of DATARDY field. */ +#define TEMP_INTENSET_DATARDY_Msk (0x1UL << TEMP_INTENSET_DATARDY_Pos) /*!< Bit mask of DATARDY field. */ +#define TEMP_INTENSET_DATARDY_Disabled (0UL) /*!< Read: Disabled */ +#define TEMP_INTENSET_DATARDY_Enabled (1UL) /*!< Read: Enabled */ +#define TEMP_INTENSET_DATARDY_Set (1UL) /*!< Enable */ + +/* Register: TEMP_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 0 : Write '1' to Disable interrupt for DATARDY event */ +#define TEMP_INTENCLR_DATARDY_Pos (0UL) /*!< Position of DATARDY field. */ +#define TEMP_INTENCLR_DATARDY_Msk (0x1UL << TEMP_INTENCLR_DATARDY_Pos) /*!< Bit mask of DATARDY field. */ +#define TEMP_INTENCLR_DATARDY_Disabled (0UL) /*!< Read: Disabled */ +#define TEMP_INTENCLR_DATARDY_Enabled (1UL) /*!< Read: Enabled */ +#define TEMP_INTENCLR_DATARDY_Clear (1UL) /*!< Disable */ + +/* Register: TEMP_TEMP */ +/* Description: Temperature in degC (0.25deg steps) */ + +/* Bits 31..0 : Temperature in degC (0.25deg steps) */ +#define TEMP_TEMP_TEMP_Pos (0UL) /*!< Position of TEMP field. */ +#define TEMP_TEMP_TEMP_Msk (0xFFFFFFFFUL << TEMP_TEMP_TEMP_Pos) /*!< Bit mask of TEMP field. */ + +/* Register: TEMP_A0 */ +/* Description: Slope of 1st piece wise linear function */ + +/* Bits 11..0 : Slope of 1st piece wise linear function */ +#define TEMP_A0_A0_Pos (0UL) /*!< Position of A0 field. */ +#define TEMP_A0_A0_Msk (0xFFFUL << TEMP_A0_A0_Pos) /*!< Bit mask of A0 field. */ + +/* Register: TEMP_A1 */ +/* Description: Slope of 2nd piece wise linear function */ + +/* Bits 11..0 : Slope of 2nd piece wise linear function */ +#define TEMP_A1_A1_Pos (0UL) /*!< Position of A1 field. */ +#define TEMP_A1_A1_Msk (0xFFFUL << TEMP_A1_A1_Pos) /*!< Bit mask of A1 field. */ + +/* Register: TEMP_A2 */ +/* Description: Slope of 3rd piece wise linear function */ + +/* Bits 11..0 : Slope of 3rd piece wise linear function */ +#define TEMP_A2_A2_Pos (0UL) /*!< Position of A2 field. */ +#define TEMP_A2_A2_Msk (0xFFFUL << TEMP_A2_A2_Pos) /*!< Bit mask of A2 field. */ + +/* Register: TEMP_A3 */ +/* Description: Slope of 4th piece wise linear function */ + +/* Bits 11..0 : Slope of 4th piece wise linear function */ +#define TEMP_A3_A3_Pos (0UL) /*!< Position of A3 field. */ +#define TEMP_A3_A3_Msk (0xFFFUL << TEMP_A3_A3_Pos) /*!< Bit mask of A3 field. */ + +/* Register: TEMP_A4 */ +/* Description: Slope of 5th piece wise linear function */ + +/* Bits 11..0 : Slope of 5th piece wise linear function */ +#define TEMP_A4_A4_Pos (0UL) /*!< Position of A4 field. */ +#define TEMP_A4_A4_Msk (0xFFFUL << TEMP_A4_A4_Pos) /*!< Bit mask of A4 field. */ + +/* Register: TEMP_A5 */ +/* Description: Slope of 6th piece wise linear function */ + +/* Bits 11..0 : Slope of 6th piece wise linear function */ +#define TEMP_A5_A5_Pos (0UL) /*!< Position of A5 field. */ +#define TEMP_A5_A5_Msk (0xFFFUL << TEMP_A5_A5_Pos) /*!< Bit mask of A5 field. */ + +/* Register: TEMP_B0 */ +/* Description: y-intercept of 1st piece wise linear function */ + +/* Bits 13..0 : y-intercept of 1st piece wise linear function */ +#define TEMP_B0_B0_Pos (0UL) /*!< Position of B0 field. */ +#define TEMP_B0_B0_Msk (0x3FFFUL << TEMP_B0_B0_Pos) /*!< Bit mask of B0 field. */ + +/* Register: TEMP_B1 */ +/* Description: y-intercept of 2nd piece wise linear function */ + +/* Bits 13..0 : y-intercept of 2nd piece wise linear function */ +#define TEMP_B1_B1_Pos (0UL) /*!< Position of B1 field. */ +#define TEMP_B1_B1_Msk (0x3FFFUL << TEMP_B1_B1_Pos) /*!< Bit mask of B1 field. */ + +/* Register: TEMP_B2 */ +/* Description: y-intercept of 3rd piece wise linear function */ + +/* Bits 13..0 : y-intercept of 3rd piece wise linear function */ +#define TEMP_B2_B2_Pos (0UL) /*!< Position of B2 field. */ +#define TEMP_B2_B2_Msk (0x3FFFUL << TEMP_B2_B2_Pos) /*!< Bit mask of B2 field. */ + +/* Register: TEMP_B3 */ +/* Description: y-intercept of 4th piece wise linear function */ + +/* Bits 13..0 : y-intercept of 4th piece wise linear function */ +#define TEMP_B3_B3_Pos (0UL) /*!< Position of B3 field. */ +#define TEMP_B3_B3_Msk (0x3FFFUL << TEMP_B3_B3_Pos) /*!< Bit mask of B3 field. */ + +/* Register: TEMP_B4 */ +/* Description: y-intercept of 5th piece wise linear function */ + +/* Bits 13..0 : y-intercept of 5th piece wise linear function */ +#define TEMP_B4_B4_Pos (0UL) /*!< Position of B4 field. */ +#define TEMP_B4_B4_Msk (0x3FFFUL << TEMP_B4_B4_Pos) /*!< Bit mask of B4 field. */ + +/* Register: TEMP_B5 */ +/* Description: y-intercept of 6th piece wise linear function */ + +/* Bits 13..0 : y-intercept of 6th piece wise linear function */ +#define TEMP_B5_B5_Pos (0UL) /*!< Position of B5 field. */ +#define TEMP_B5_B5_Msk (0x3FFFUL << TEMP_B5_B5_Pos) /*!< Bit mask of B5 field. */ + +/* Register: TEMP_T0 */ +/* Description: End point of 1st piece wise linear function */ + +/* Bits 7..0 : End point of 1st piece wise linear function */ +#define TEMP_T0_T0_Pos (0UL) /*!< Position of T0 field. */ +#define TEMP_T0_T0_Msk (0xFFUL << TEMP_T0_T0_Pos) /*!< Bit mask of T0 field. */ + +/* Register: TEMP_T1 */ +/* Description: End point of 2nd piece wise linear function */ + +/* Bits 7..0 : End point of 2nd piece wise linear function */ +#define TEMP_T1_T1_Pos (0UL) /*!< Position of T1 field. */ +#define TEMP_T1_T1_Msk (0xFFUL << TEMP_T1_T1_Pos) /*!< Bit mask of T1 field. */ + +/* Register: TEMP_T2 */ +/* Description: End point of 3rd piece wise linear function */ + +/* Bits 7..0 : End point of 3rd piece wise linear function */ +#define TEMP_T2_T2_Pos (0UL) /*!< Position of T2 field. */ +#define TEMP_T2_T2_Msk (0xFFUL << TEMP_T2_T2_Pos) /*!< Bit mask of T2 field. */ + +/* Register: TEMP_T3 */ +/* Description: End point of 4th piece wise linear function */ + +/* Bits 7..0 : End point of 4th piece wise linear function */ +#define TEMP_T3_T3_Pos (0UL) /*!< Position of T3 field. */ +#define TEMP_T3_T3_Msk (0xFFUL << TEMP_T3_T3_Pos) /*!< Bit mask of T3 field. */ + +/* Register: TEMP_T4 */ +/* Description: End point of 5th piece wise linear function */ + +/* Bits 7..0 : End point of 5th piece wise linear function */ +#define TEMP_T4_T4_Pos (0UL) /*!< Position of T4 field. */ +#define TEMP_T4_T4_Msk (0xFFUL << TEMP_T4_T4_Pos) /*!< Bit mask of T4 field. */ + + +/* Peripheral: TIMER */ +/* Description: Timer/Counter 0 */ + +/* Register: TIMER_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 13 : Shortcut between COMPARE[5] event and STOP task */ +#define TIMER_SHORTS_COMPARE5_STOP_Pos (13UL) /*!< Position of COMPARE5_STOP field. */ +#define TIMER_SHORTS_COMPARE5_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE5_STOP_Pos) /*!< Bit mask of COMPARE5_STOP field. */ +#define TIMER_SHORTS_COMPARE5_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE5_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 12 : Shortcut between COMPARE[4] event and STOP task */ +#define TIMER_SHORTS_COMPARE4_STOP_Pos (12UL) /*!< Position of COMPARE4_STOP field. */ +#define TIMER_SHORTS_COMPARE4_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE4_STOP_Pos) /*!< Bit mask of COMPARE4_STOP field. */ +#define TIMER_SHORTS_COMPARE4_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE4_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 11 : Shortcut between COMPARE[3] event and STOP task */ +#define TIMER_SHORTS_COMPARE3_STOP_Pos (11UL) /*!< Position of COMPARE3_STOP field. */ +#define TIMER_SHORTS_COMPARE3_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE3_STOP_Pos) /*!< Bit mask of COMPARE3_STOP field. */ +#define TIMER_SHORTS_COMPARE3_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE3_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 10 : Shortcut between COMPARE[2] event and STOP task */ +#define TIMER_SHORTS_COMPARE2_STOP_Pos (10UL) /*!< Position of COMPARE2_STOP field. */ +#define TIMER_SHORTS_COMPARE2_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE2_STOP_Pos) /*!< Bit mask of COMPARE2_STOP field. */ +#define TIMER_SHORTS_COMPARE2_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE2_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 9 : Shortcut between COMPARE[1] event and STOP task */ +#define TIMER_SHORTS_COMPARE1_STOP_Pos (9UL) /*!< Position of COMPARE1_STOP field. */ +#define TIMER_SHORTS_COMPARE1_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE1_STOP_Pos) /*!< Bit mask of COMPARE1_STOP field. */ +#define TIMER_SHORTS_COMPARE1_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE1_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 8 : Shortcut between COMPARE[0] event and STOP task */ +#define TIMER_SHORTS_COMPARE0_STOP_Pos (8UL) /*!< Position of COMPARE0_STOP field. */ +#define TIMER_SHORTS_COMPARE0_STOP_Msk (0x1UL << TIMER_SHORTS_COMPARE0_STOP_Pos) /*!< Bit mask of COMPARE0_STOP field. */ +#define TIMER_SHORTS_COMPARE0_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE0_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 5 : Shortcut between COMPARE[5] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE5_CLEAR_Pos (5UL) /*!< Position of COMPARE5_CLEAR field. */ +#define TIMER_SHORTS_COMPARE5_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE5_CLEAR_Pos) /*!< Bit mask of COMPARE5_CLEAR field. */ +#define TIMER_SHORTS_COMPARE5_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE5_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 4 : Shortcut between COMPARE[4] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE4_CLEAR_Pos (4UL) /*!< Position of COMPARE4_CLEAR field. */ +#define TIMER_SHORTS_COMPARE4_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE4_CLEAR_Pos) /*!< Bit mask of COMPARE4_CLEAR field. */ +#define TIMER_SHORTS_COMPARE4_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE4_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between COMPARE[3] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE3_CLEAR_Pos (3UL) /*!< Position of COMPARE3_CLEAR field. */ +#define TIMER_SHORTS_COMPARE3_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE3_CLEAR_Pos) /*!< Bit mask of COMPARE3_CLEAR field. */ +#define TIMER_SHORTS_COMPARE3_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE3_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between COMPARE[2] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE2_CLEAR_Pos (2UL) /*!< Position of COMPARE2_CLEAR field. */ +#define TIMER_SHORTS_COMPARE2_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE2_CLEAR_Pos) /*!< Bit mask of COMPARE2_CLEAR field. */ +#define TIMER_SHORTS_COMPARE2_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE2_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between COMPARE[1] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE1_CLEAR_Pos (1UL) /*!< Position of COMPARE1_CLEAR field. */ +#define TIMER_SHORTS_COMPARE1_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE1_CLEAR_Pos) /*!< Bit mask of COMPARE1_CLEAR field. */ +#define TIMER_SHORTS_COMPARE1_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE1_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between COMPARE[0] event and CLEAR task */ +#define TIMER_SHORTS_COMPARE0_CLEAR_Pos (0UL) /*!< Position of COMPARE0_CLEAR field. */ +#define TIMER_SHORTS_COMPARE0_CLEAR_Msk (0x1UL << TIMER_SHORTS_COMPARE0_CLEAR_Pos) /*!< Bit mask of COMPARE0_CLEAR field. */ +#define TIMER_SHORTS_COMPARE0_CLEAR_Disabled (0UL) /*!< Disable shortcut */ +#define TIMER_SHORTS_COMPARE0_CLEAR_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: TIMER_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 21 : Write '1' to Enable interrupt for COMPARE[5] event */ +#define TIMER_INTENSET_COMPARE5_Pos (21UL) /*!< Position of COMPARE5 field. */ +#define TIMER_INTENSET_COMPARE5_Msk (0x1UL << TIMER_INTENSET_COMPARE5_Pos) /*!< Bit mask of COMPARE5 field. */ +#define TIMER_INTENSET_COMPARE5_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE5_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE5_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for COMPARE[4] event */ +#define TIMER_INTENSET_COMPARE4_Pos (20UL) /*!< Position of COMPARE4 field. */ +#define TIMER_INTENSET_COMPARE4_Msk (0x1UL << TIMER_INTENSET_COMPARE4_Pos) /*!< Bit mask of COMPARE4 field. */ +#define TIMER_INTENSET_COMPARE4_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE4_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE4_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for COMPARE[3] event */ +#define TIMER_INTENSET_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define TIMER_INTENSET_COMPARE3_Msk (0x1UL << TIMER_INTENSET_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define TIMER_INTENSET_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE3_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for COMPARE[2] event */ +#define TIMER_INTENSET_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define TIMER_INTENSET_COMPARE2_Msk (0x1UL << TIMER_INTENSET_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define TIMER_INTENSET_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE2_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for COMPARE[1] event */ +#define TIMER_INTENSET_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define TIMER_INTENSET_COMPARE1_Msk (0x1UL << TIMER_INTENSET_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define TIMER_INTENSET_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE1_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable interrupt for COMPARE[0] event */ +#define TIMER_INTENSET_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define TIMER_INTENSET_COMPARE0_Msk (0x1UL << TIMER_INTENSET_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define TIMER_INTENSET_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENSET_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENSET_COMPARE0_Set (1UL) /*!< Enable */ + +/* Register: TIMER_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 21 : Write '1' to Disable interrupt for COMPARE[5] event */ +#define TIMER_INTENCLR_COMPARE5_Pos (21UL) /*!< Position of COMPARE5 field. */ +#define TIMER_INTENCLR_COMPARE5_Msk (0x1UL << TIMER_INTENCLR_COMPARE5_Pos) /*!< Bit mask of COMPARE5 field. */ +#define TIMER_INTENCLR_COMPARE5_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE5_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE5_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for COMPARE[4] event */ +#define TIMER_INTENCLR_COMPARE4_Pos (20UL) /*!< Position of COMPARE4 field. */ +#define TIMER_INTENCLR_COMPARE4_Msk (0x1UL << TIMER_INTENCLR_COMPARE4_Pos) /*!< Bit mask of COMPARE4 field. */ +#define TIMER_INTENCLR_COMPARE4_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE4_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE4_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for COMPARE[3] event */ +#define TIMER_INTENCLR_COMPARE3_Pos (19UL) /*!< Position of COMPARE3 field. */ +#define TIMER_INTENCLR_COMPARE3_Msk (0x1UL << TIMER_INTENCLR_COMPARE3_Pos) /*!< Bit mask of COMPARE3 field. */ +#define TIMER_INTENCLR_COMPARE3_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE3_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE3_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for COMPARE[2] event */ +#define TIMER_INTENCLR_COMPARE2_Pos (18UL) /*!< Position of COMPARE2 field. */ +#define TIMER_INTENCLR_COMPARE2_Msk (0x1UL << TIMER_INTENCLR_COMPARE2_Pos) /*!< Bit mask of COMPARE2 field. */ +#define TIMER_INTENCLR_COMPARE2_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE2_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE2_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for COMPARE[1] event */ +#define TIMER_INTENCLR_COMPARE1_Pos (17UL) /*!< Position of COMPARE1 field. */ +#define TIMER_INTENCLR_COMPARE1_Msk (0x1UL << TIMER_INTENCLR_COMPARE1_Pos) /*!< Bit mask of COMPARE1 field. */ +#define TIMER_INTENCLR_COMPARE1_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE1_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE1_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable interrupt for COMPARE[0] event */ +#define TIMER_INTENCLR_COMPARE0_Pos (16UL) /*!< Position of COMPARE0 field. */ +#define TIMER_INTENCLR_COMPARE0_Msk (0x1UL << TIMER_INTENCLR_COMPARE0_Pos) /*!< Bit mask of COMPARE0 field. */ +#define TIMER_INTENCLR_COMPARE0_Disabled (0UL) /*!< Read: Disabled */ +#define TIMER_INTENCLR_COMPARE0_Enabled (1UL) /*!< Read: Enabled */ +#define TIMER_INTENCLR_COMPARE0_Clear (1UL) /*!< Disable */ + +/* Register: TIMER_STATUS */ +/* Description: Timer status */ + +/* Bit 0 : Timer status */ +#define TIMER_STATUS_STATUS_Pos (0UL) /*!< Position of STATUS field. */ +#define TIMER_STATUS_STATUS_Msk (0x1UL << TIMER_STATUS_STATUS_Pos) /*!< Bit mask of STATUS field. */ +#define TIMER_STATUS_STATUS_Stopped (0UL) /*!< Timer is stopped */ +#define TIMER_STATUS_STATUS_Started (1UL) /*!< Timer is started */ + +/* Register: TIMER_MODE */ +/* Description: Timer mode selection */ + +/* Bits 1..0 : Timer mode */ +#define TIMER_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */ +#define TIMER_MODE_MODE_Msk (0x3UL << TIMER_MODE_MODE_Pos) /*!< Bit mask of MODE field. */ +#define TIMER_MODE_MODE_Timer (0UL) /*!< Select Timer mode */ +#define TIMER_MODE_MODE_Counter (1UL) /*!< Deprecated enumerator - Select Counter mode */ +#define TIMER_MODE_MODE_LowPowerCounter (2UL) /*!< Select Low Power Counter mode */ + +/* Register: TIMER_BITMODE */ +/* Description: Configure the number of bits used by the TIMER */ + +/* Bits 1..0 : Timer bit width */ +#define TIMER_BITMODE_BITMODE_Pos (0UL) /*!< Position of BITMODE field. */ +#define TIMER_BITMODE_BITMODE_Msk (0x3UL << TIMER_BITMODE_BITMODE_Pos) /*!< Bit mask of BITMODE field. */ +#define TIMER_BITMODE_BITMODE_16Bit (0UL) /*!< 16 bit timer bit width */ +#define TIMER_BITMODE_BITMODE_08Bit (1UL) /*!< 8 bit timer bit width */ +#define TIMER_BITMODE_BITMODE_24Bit (2UL) /*!< 24 bit timer bit width */ +#define TIMER_BITMODE_BITMODE_32Bit (3UL) /*!< 32 bit timer bit width */ + +/* Register: TIMER_PRESCALER */ +/* Description: Timer prescaler register */ + +/* Bits 3..0 : Prescaler value */ +#define TIMER_PRESCALER_PRESCALER_Pos (0UL) /*!< Position of PRESCALER field. */ +#define TIMER_PRESCALER_PRESCALER_Msk (0xFUL << TIMER_PRESCALER_PRESCALER_Pos) /*!< Bit mask of PRESCALER field. */ + +/* Register: TIMER_CC */ +/* Description: Description collection[0]: Capture/Compare register 0 */ + +/* Bits 31..0 : Capture/Compare value */ +#define TIMER_CC_CC_Pos (0UL) /*!< Position of CC field. */ +#define TIMER_CC_CC_Msk (0xFFFFFFFFUL << TIMER_CC_CC_Pos) /*!< Bit mask of CC field. */ + + +/* Peripheral: TWI */ +/* Description: I2C compatible Two-Wire Interface 0 */ + +/* Register: TWI_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 1 : Shortcut between BB event and STOP task */ +#define TWI_SHORTS_BB_STOP_Pos (1UL) /*!< Position of BB_STOP field. */ +#define TWI_SHORTS_BB_STOP_Msk (0x1UL << TWI_SHORTS_BB_STOP_Pos) /*!< Bit mask of BB_STOP field. */ +#define TWI_SHORTS_BB_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TWI_SHORTS_BB_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between BB event and SUSPEND task */ +#define TWI_SHORTS_BB_SUSPEND_Pos (0UL) /*!< Position of BB_SUSPEND field. */ +#define TWI_SHORTS_BB_SUSPEND_Msk (0x1UL << TWI_SHORTS_BB_SUSPEND_Pos) /*!< Bit mask of BB_SUSPEND field. */ +#define TWI_SHORTS_BB_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ +#define TWI_SHORTS_BB_SUSPEND_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: TWI_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 18 : Write '1' to Enable interrupt for SUSPENDED event */ +#define TWI_INTENSET_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWI_INTENSET_SUSPENDED_Msk (0x1UL << TWI_INTENSET_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWI_INTENSET_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_SUSPENDED_Set (1UL) /*!< Enable */ + +/* Bit 14 : Write '1' to Enable interrupt for BB event */ +#define TWI_INTENSET_BB_Pos (14UL) /*!< Position of BB field. */ +#define TWI_INTENSET_BB_Msk (0x1UL << TWI_INTENSET_BB_Pos) /*!< Bit mask of BB field. */ +#define TWI_INTENSET_BB_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_BB_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_BB_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ +#define TWI_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWI_INTENSET_ERROR_Msk (0x1UL << TWI_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWI_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for TXDSENT event */ +#define TWI_INTENSET_TXDSENT_Pos (7UL) /*!< Position of TXDSENT field. */ +#define TWI_INTENSET_TXDSENT_Msk (0x1UL << TWI_INTENSET_TXDSENT_Pos) /*!< Bit mask of TXDSENT field. */ +#define TWI_INTENSET_TXDSENT_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_TXDSENT_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_TXDSENT_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for RXDREADY event */ +#define TWI_INTENSET_RXDREADY_Pos (2UL) /*!< Position of RXDREADY field. */ +#define TWI_INTENSET_RXDREADY_Msk (0x1UL << TWI_INTENSET_RXDREADY_Pos) /*!< Bit mask of RXDREADY field. */ +#define TWI_INTENSET_RXDREADY_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_RXDREADY_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_RXDREADY_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define TWI_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWI_INTENSET_STOPPED_Msk (0x1UL << TWI_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWI_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Register: TWI_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 18 : Write '1' to Disable interrupt for SUSPENDED event */ +#define TWI_INTENCLR_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWI_INTENCLR_SUSPENDED_Msk (0x1UL << TWI_INTENCLR_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWI_INTENCLR_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_SUSPENDED_Clear (1UL) /*!< Disable */ + +/* Bit 14 : Write '1' to Disable interrupt for BB event */ +#define TWI_INTENCLR_BB_Pos (14UL) /*!< Position of BB field. */ +#define TWI_INTENCLR_BB_Msk (0x1UL << TWI_INTENCLR_BB_Pos) /*!< Bit mask of BB field. */ +#define TWI_INTENCLR_BB_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_BB_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_BB_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ +#define TWI_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWI_INTENCLR_ERROR_Msk (0x1UL << TWI_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWI_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for TXDSENT event */ +#define TWI_INTENCLR_TXDSENT_Pos (7UL) /*!< Position of TXDSENT field. */ +#define TWI_INTENCLR_TXDSENT_Msk (0x1UL << TWI_INTENCLR_TXDSENT_Pos) /*!< Bit mask of TXDSENT field. */ +#define TWI_INTENCLR_TXDSENT_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_TXDSENT_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_TXDSENT_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for RXDREADY event */ +#define TWI_INTENCLR_RXDREADY_Pos (2UL) /*!< Position of RXDREADY field. */ +#define TWI_INTENCLR_RXDREADY_Msk (0x1UL << TWI_INTENCLR_RXDREADY_Pos) /*!< Bit mask of RXDREADY field. */ +#define TWI_INTENCLR_RXDREADY_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_RXDREADY_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_RXDREADY_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define TWI_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWI_INTENCLR_STOPPED_Msk (0x1UL << TWI_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWI_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWI_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWI_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Register: TWI_ERRORSRC */ +/* Description: Error source */ + +/* Bit 2 : NACK received after sending a data byte (write '1' to clear) */ +#define TWI_ERRORSRC_DNACK_Pos (2UL) /*!< Position of DNACK field. */ +#define TWI_ERRORSRC_DNACK_Msk (0x1UL << TWI_ERRORSRC_DNACK_Pos) /*!< Bit mask of DNACK field. */ +#define TWI_ERRORSRC_DNACK_NotPresent (0UL) /*!< Read: error not present */ +#define TWI_ERRORSRC_DNACK_Present (1UL) /*!< Read: error present */ + +/* Bit 1 : NACK received after sending the address (write '1' to clear) */ +#define TWI_ERRORSRC_ANACK_Pos (1UL) /*!< Position of ANACK field. */ +#define TWI_ERRORSRC_ANACK_Msk (0x1UL << TWI_ERRORSRC_ANACK_Pos) /*!< Bit mask of ANACK field. */ +#define TWI_ERRORSRC_ANACK_NotPresent (0UL) /*!< Read: error not present */ +#define TWI_ERRORSRC_ANACK_Present (1UL) /*!< Read: error present */ + +/* Bit 0 : Overrun error */ +#define TWI_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ +#define TWI_ERRORSRC_OVERRUN_Msk (0x1UL << TWI_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define TWI_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Read: no overrun occured */ +#define TWI_ERRORSRC_OVERRUN_Present (1UL) /*!< Read: overrun occured */ + +/* Register: TWI_ENABLE */ +/* Description: Enable TWI */ + +/* Bits 3..0 : Enable or disable TWI */ +#define TWI_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define TWI_ENABLE_ENABLE_Msk (0xFUL << TWI_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define TWI_ENABLE_ENABLE_Disabled (0UL) /*!< Disable TWI */ +#define TWI_ENABLE_ENABLE_Enabled (5UL) /*!< Enable TWI */ + +/* Register: TWI_PSEL_SCL */ +/* Description: Pin select for SCL */ + +/* Bit 31 : Connection */ +#define TWI_PSEL_SCL_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWI_PSEL_SCL_CONNECT_Msk (0x1UL << TWI_PSEL_SCL_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWI_PSEL_SCL_CONNECT_Connected (0UL) /*!< Connect */ +#define TWI_PSEL_SCL_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define TWI_PSEL_SCL_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWI_PSEL_SCL_PORT_Msk (0x3UL << TWI_PSEL_SCL_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWI_PSEL_SCL_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWI_PSEL_SCL_PIN_Msk (0x1FUL << TWI_PSEL_SCL_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWI_PSEL_SDA */ +/* Description: Pin select for SDA */ + +/* Bit 31 : Connection */ +#define TWI_PSEL_SDA_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWI_PSEL_SDA_CONNECT_Msk (0x1UL << TWI_PSEL_SDA_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWI_PSEL_SDA_CONNECT_Connected (0UL) /*!< Connect */ +#define TWI_PSEL_SDA_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define TWI_PSEL_SDA_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWI_PSEL_SDA_PORT_Msk (0x3UL << TWI_PSEL_SDA_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWI_PSEL_SDA_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWI_PSEL_SDA_PIN_Msk (0x1FUL << TWI_PSEL_SDA_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWI_RXD */ +/* Description: RXD register */ + +/* Bits 7..0 : RXD register */ +#define TWI_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */ +#define TWI_RXD_RXD_Msk (0xFFUL << TWI_RXD_RXD_Pos) /*!< Bit mask of RXD field. */ + +/* Register: TWI_TXD */ +/* Description: TXD register */ + +/* Bits 7..0 : TXD register */ +#define TWI_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */ +#define TWI_TXD_TXD_Msk (0xFFUL << TWI_TXD_TXD_Pos) /*!< Bit mask of TXD field. */ + +/* Register: TWI_FREQUENCY */ +/* Description: TWI frequency. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : TWI master clock frequency */ +#define TWI_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ +#define TWI_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << TWI_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ +#define TWI_FREQUENCY_FREQUENCY_K100 (0x01980000UL) /*!< 100 kbps */ +#define TWI_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps */ +#define TWI_FREQUENCY_FREQUENCY_K400 (0x06680000UL) /*!< 400 kbps (actual rate 410.256 kbps) */ + +/* Register: TWI_ADDRESS */ +/* Description: Address used in the TWI transfer */ + +/* Bits 6..0 : Address used in the TWI transfer */ +#define TWI_ADDRESS_ADDRESS_Pos (0UL) /*!< Position of ADDRESS field. */ +#define TWI_ADDRESS_ADDRESS_Msk (0x7FUL << TWI_ADDRESS_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ + + +/* Peripheral: TWIM */ +/* Description: I2C compatible Two-Wire Master Interface with EasyDMA 0 */ + +/* Register: TWIM_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 12 : Shortcut between LASTRX event and STOP task */ +#define TWIM_SHORTS_LASTRX_STOP_Pos (12UL) /*!< Position of LASTRX_STOP field. */ +#define TWIM_SHORTS_LASTRX_STOP_Msk (0x1UL << TWIM_SHORTS_LASTRX_STOP_Pos) /*!< Bit mask of LASTRX_STOP field. */ +#define TWIM_SHORTS_LASTRX_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TWIM_SHORTS_LASTRX_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 10 : Shortcut between LASTRX event and STARTTX task */ +#define TWIM_SHORTS_LASTRX_STARTTX_Pos (10UL) /*!< Position of LASTRX_STARTTX field. */ +#define TWIM_SHORTS_LASTRX_STARTTX_Msk (0x1UL << TWIM_SHORTS_LASTRX_STARTTX_Pos) /*!< Bit mask of LASTRX_STARTTX field. */ +#define TWIM_SHORTS_LASTRX_STARTTX_Disabled (0UL) /*!< Disable shortcut */ +#define TWIM_SHORTS_LASTRX_STARTTX_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 9 : Shortcut between LASTTX event and STOP task */ +#define TWIM_SHORTS_LASTTX_STOP_Pos (9UL) /*!< Position of LASTTX_STOP field. */ +#define TWIM_SHORTS_LASTTX_STOP_Msk (0x1UL << TWIM_SHORTS_LASTTX_STOP_Pos) /*!< Bit mask of LASTTX_STOP field. */ +#define TWIM_SHORTS_LASTTX_STOP_Disabled (0UL) /*!< Disable shortcut */ +#define TWIM_SHORTS_LASTTX_STOP_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 8 : Shortcut between LASTTX event and SUSPEND task */ +#define TWIM_SHORTS_LASTTX_SUSPEND_Pos (8UL) /*!< Position of LASTTX_SUSPEND field. */ +#define TWIM_SHORTS_LASTTX_SUSPEND_Msk (0x1UL << TWIM_SHORTS_LASTTX_SUSPEND_Pos) /*!< Bit mask of LASTTX_SUSPEND field. */ +#define TWIM_SHORTS_LASTTX_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ +#define TWIM_SHORTS_LASTTX_SUSPEND_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 7 : Shortcut between LASTTX event and STARTRX task */ +#define TWIM_SHORTS_LASTTX_STARTRX_Pos (7UL) /*!< Position of LASTTX_STARTRX field. */ +#define TWIM_SHORTS_LASTTX_STARTRX_Msk (0x1UL << TWIM_SHORTS_LASTTX_STARTRX_Pos) /*!< Bit mask of LASTTX_STARTRX field. */ +#define TWIM_SHORTS_LASTTX_STARTRX_Disabled (0UL) /*!< Disable shortcut */ +#define TWIM_SHORTS_LASTTX_STARTRX_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: TWIM_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 24 : Enable or disable interrupt for LASTTX event */ +#define TWIM_INTEN_LASTTX_Pos (24UL) /*!< Position of LASTTX field. */ +#define TWIM_INTEN_LASTTX_Msk (0x1UL << TWIM_INTEN_LASTTX_Pos) /*!< Bit mask of LASTTX field. */ +#define TWIM_INTEN_LASTTX_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_LASTTX_Enabled (1UL) /*!< Enable */ + +/* Bit 23 : Enable or disable interrupt for LASTRX event */ +#define TWIM_INTEN_LASTRX_Pos (23UL) /*!< Position of LASTRX field. */ +#define TWIM_INTEN_LASTRX_Msk (0x1UL << TWIM_INTEN_LASTRX_Pos) /*!< Bit mask of LASTRX field. */ +#define TWIM_INTEN_LASTRX_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_LASTRX_Enabled (1UL) /*!< Enable */ + +/* Bit 20 : Enable or disable interrupt for TXSTARTED event */ +#define TWIM_INTEN_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIM_INTEN_TXSTARTED_Msk (0x1UL << TWIM_INTEN_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIM_INTEN_TXSTARTED_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_TXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for RXSTARTED event */ +#define TWIM_INTEN_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIM_INTEN_RXSTARTED_Msk (0x1UL << TWIM_INTEN_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIM_INTEN_RXSTARTED_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_RXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 18 : Enable or disable interrupt for SUSPENDED event */ +#define TWIM_INTEN_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTEN_SUSPENDED_Msk (0x1UL << TWIM_INTEN_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTEN_SUSPENDED_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_SUSPENDED_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for ERROR event */ +#define TWIM_INTEN_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIM_INTEN_ERROR_Msk (0x1UL << TWIM_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIM_INTEN_ERROR_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_ERROR_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for STOPPED event */ +#define TWIM_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIM_INTEN_STOPPED_Msk (0x1UL << TWIM_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIM_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Register: TWIM_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 24 : Write '1' to Enable interrupt for LASTTX event */ +#define TWIM_INTENSET_LASTTX_Pos (24UL) /*!< Position of LASTTX field. */ +#define TWIM_INTENSET_LASTTX_Msk (0x1UL << TWIM_INTENSET_LASTTX_Pos) /*!< Bit mask of LASTTX field. */ +#define TWIM_INTENSET_LASTTX_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_LASTTX_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_LASTTX_Set (1UL) /*!< Enable */ + +/* Bit 23 : Write '1' to Enable interrupt for LASTRX event */ +#define TWIM_INTENSET_LASTRX_Pos (23UL) /*!< Position of LASTRX field. */ +#define TWIM_INTENSET_LASTRX_Msk (0x1UL << TWIM_INTENSET_LASTRX_Pos) /*!< Bit mask of LASTRX field. */ +#define TWIM_INTENSET_LASTRX_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_LASTRX_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_LASTRX_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for TXSTARTED event */ +#define TWIM_INTENSET_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIM_INTENSET_TXSTARTED_Msk (0x1UL << TWIM_INTENSET_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIM_INTENSET_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_TXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for RXSTARTED event */ +#define TWIM_INTENSET_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIM_INTENSET_RXSTARTED_Msk (0x1UL << TWIM_INTENSET_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIM_INTENSET_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for SUSPENDED event */ +#define TWIM_INTENSET_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTENSET_SUSPENDED_Msk (0x1UL << TWIM_INTENSET_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTENSET_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_SUSPENDED_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ +#define TWIM_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIM_INTENSET_ERROR_Msk (0x1UL << TWIM_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIM_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define TWIM_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIM_INTENSET_STOPPED_Msk (0x1UL << TWIM_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIM_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Register: TWIM_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 24 : Write '1' to Disable interrupt for LASTTX event */ +#define TWIM_INTENCLR_LASTTX_Pos (24UL) /*!< Position of LASTTX field. */ +#define TWIM_INTENCLR_LASTTX_Msk (0x1UL << TWIM_INTENCLR_LASTTX_Pos) /*!< Bit mask of LASTTX field. */ +#define TWIM_INTENCLR_LASTTX_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_LASTTX_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_LASTTX_Clear (1UL) /*!< Disable */ + +/* Bit 23 : Write '1' to Disable interrupt for LASTRX event */ +#define TWIM_INTENCLR_LASTRX_Pos (23UL) /*!< Position of LASTRX field. */ +#define TWIM_INTENCLR_LASTRX_Msk (0x1UL << TWIM_INTENCLR_LASTRX_Pos) /*!< Bit mask of LASTRX field. */ +#define TWIM_INTENCLR_LASTRX_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_LASTRX_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_LASTRX_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for TXSTARTED event */ +#define TWIM_INTENCLR_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIM_INTENCLR_TXSTARTED_Msk (0x1UL << TWIM_INTENCLR_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIM_INTENCLR_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_TXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for RXSTARTED event */ +#define TWIM_INTENCLR_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIM_INTENCLR_RXSTARTED_Msk (0x1UL << TWIM_INTENCLR_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIM_INTENCLR_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_RXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for SUSPENDED event */ +#define TWIM_INTENCLR_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTENCLR_SUSPENDED_Msk (0x1UL << TWIM_INTENCLR_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTENCLR_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_SUSPENDED_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ +#define TWIM_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIM_INTENCLR_ERROR_Msk (0x1UL << TWIM_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIM_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define TWIM_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIM_INTENCLR_STOPPED_Msk (0x1UL << TWIM_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIM_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Register: TWIM_ERRORSRC */ +/* Description: Error source */ + +/* Bit 2 : NACK received after sending a data byte (write '1' to clear) */ +#define TWIM_ERRORSRC_DNACK_Pos (2UL) /*!< Position of DNACK field. */ +#define TWIM_ERRORSRC_DNACK_Msk (0x1UL << TWIM_ERRORSRC_DNACK_Pos) /*!< Bit mask of DNACK field. */ +#define TWIM_ERRORSRC_DNACK_NotReceived (0UL) /*!< Error did not occur */ +#define TWIM_ERRORSRC_DNACK_Received (1UL) /*!< Error occurred */ + +/* Bit 1 : NACK received after sending the address (write '1' to clear) */ +#define TWIM_ERRORSRC_ANACK_Pos (1UL) /*!< Position of ANACK field. */ +#define TWIM_ERRORSRC_ANACK_Msk (0x1UL << TWIM_ERRORSRC_ANACK_Pos) /*!< Bit mask of ANACK field. */ +#define TWIM_ERRORSRC_ANACK_NotReceived (0UL) /*!< Error did not occur */ +#define TWIM_ERRORSRC_ANACK_Received (1UL) /*!< Error occurred */ + +/* Bit 0 : Overrun error */ +#define TWIM_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ +#define TWIM_ERRORSRC_OVERRUN_Msk (0x1UL << TWIM_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define TWIM_ERRORSRC_OVERRUN_NotReceived (0UL) /*!< Error did not occur */ +#define TWIM_ERRORSRC_OVERRUN_Received (1UL) /*!< Error occurred */ + +/* Register: TWIM_ENABLE */ +/* Description: Enable TWIM */ + +/* Bits 3..0 : Enable or disable TWIM */ +#define TWIM_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define TWIM_ENABLE_ENABLE_Msk (0xFUL << TWIM_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define TWIM_ENABLE_ENABLE_Disabled (0UL) /*!< Disable TWIM */ +#define TWIM_ENABLE_ENABLE_Enabled (6UL) /*!< Enable TWIM */ + +/* Register: TWIM_PSEL_SCL */ +/* Description: Pin select for SCL signal */ + +/* Bit 31 : Connection */ +#define TWIM_PSEL_SCL_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWIM_PSEL_SCL_CONNECT_Msk (0x1UL << TWIM_PSEL_SCL_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWIM_PSEL_SCL_CONNECT_Connected (0UL) /*!< Connect */ +#define TWIM_PSEL_SCL_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define TWIM_PSEL_SCL_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWIM_PSEL_SCL_PORT_Msk (0x3UL << TWIM_PSEL_SCL_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWIM_PSEL_SCL_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWIM_PSEL_SCL_PIN_Msk (0x1FUL << TWIM_PSEL_SCL_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWIM_PSEL_SDA */ +/* Description: Pin select for SDA signal */ + +/* Bit 31 : Connection */ +#define TWIM_PSEL_SDA_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWIM_PSEL_SDA_CONNECT_Msk (0x1UL << TWIM_PSEL_SDA_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWIM_PSEL_SDA_CONNECT_Connected (0UL) /*!< Connect */ +#define TWIM_PSEL_SDA_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define TWIM_PSEL_SDA_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWIM_PSEL_SDA_PORT_Msk (0x3UL << TWIM_PSEL_SDA_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWIM_PSEL_SDA_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWIM_PSEL_SDA_PIN_Msk (0x1FUL << TWIM_PSEL_SDA_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWIM_FREQUENCY */ +/* Description: TWI frequency. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : TWI master clock frequency */ +#define TWIM_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ +#define TWIM_FREQUENCY_FREQUENCY_Msk (0xFFFFFFFFUL << TWIM_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ +#define TWIM_FREQUENCY_FREQUENCY_K100 (0x01980000UL) /*!< 100 kbps */ +#define TWIM_FREQUENCY_FREQUENCY_K250 (0x04000000UL) /*!< 250 kbps */ +#define TWIM_FREQUENCY_FREQUENCY_K400 (0x06400000UL) /*!< 400 kbps */ + +/* Register: TWIM_RXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define TWIM_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define TWIM_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << TWIM_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: TWIM_RXD_MAXCNT */ +/* Description: Maximum number of bytes in receive buffer */ + +/* Bits 7..0 : Maximum number of bytes in receive buffer */ +#define TWIM_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define TWIM_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << TWIM_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: TWIM_RXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 7..0 : Number of bytes transferred in the last transaction. In case of NACK error, includes the NACK'ed byte. */ +#define TWIM_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define TWIM_RXD_AMOUNT_AMOUNT_Msk (0xFFUL << TWIM_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: TWIM_RXD_LIST */ +/* Description: EasyDMA list type */ + +/* Bits 2..0 : List type */ +#define TWIM_RXD_LIST_LIST_Pos (0UL) /*!< Position of LIST field. */ +#define TWIM_RXD_LIST_LIST_Msk (0x7UL << TWIM_RXD_LIST_LIST_Pos) /*!< Bit mask of LIST field. */ +#define TWIM_RXD_LIST_LIST_Disabled (0UL) /*!< Disable EasyDMA list */ +#define TWIM_RXD_LIST_LIST_ArrayList (1UL) /*!< Use array list */ + +/* Register: TWIM_TXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define TWIM_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define TWIM_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << TWIM_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: TWIM_TXD_MAXCNT */ +/* Description: Maximum number of bytes in transmit buffer */ + +/* Bits 7..0 : Maximum number of bytes in transmit buffer */ +#define TWIM_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define TWIM_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << TWIM_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: TWIM_TXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 7..0 : Number of bytes transferred in the last transaction. In case of NACK error, includes the NACK'ed byte. */ +#define TWIM_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define TWIM_TXD_AMOUNT_AMOUNT_Msk (0xFFUL << TWIM_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: TWIM_TXD_LIST */ +/* Description: EasyDMA list type */ + +/* Bits 2..0 : List type */ +#define TWIM_TXD_LIST_LIST_Pos (0UL) /*!< Position of LIST field. */ +#define TWIM_TXD_LIST_LIST_Msk (0x7UL << TWIM_TXD_LIST_LIST_Pos) /*!< Bit mask of LIST field. */ +#define TWIM_TXD_LIST_LIST_Disabled (0UL) /*!< Disable EasyDMA list */ +#define TWIM_TXD_LIST_LIST_ArrayList (1UL) /*!< Use array list */ + +/* Register: TWIM_ADDRESS */ +/* Description: Address used in the TWI transfer */ + +/* Bits 6..0 : Address used in the TWI transfer */ +#define TWIM_ADDRESS_ADDRESS_Pos (0UL) /*!< Position of ADDRESS field. */ +#define TWIM_ADDRESS_ADDRESS_Msk (0x7FUL << TWIM_ADDRESS_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ + + +/* Peripheral: TWIS */ +/* Description: I2C compatible Two-Wire Slave Interface with EasyDMA 0 */ + +/* Register: TWIS_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 14 : Shortcut between READ event and SUSPEND task */ +#define TWIS_SHORTS_READ_SUSPEND_Pos (14UL) /*!< Position of READ_SUSPEND field. */ +#define TWIS_SHORTS_READ_SUSPEND_Msk (0x1UL << TWIS_SHORTS_READ_SUSPEND_Pos) /*!< Bit mask of READ_SUSPEND field. */ +#define TWIS_SHORTS_READ_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ +#define TWIS_SHORTS_READ_SUSPEND_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 13 : Shortcut between WRITE event and SUSPEND task */ +#define TWIS_SHORTS_WRITE_SUSPEND_Pos (13UL) /*!< Position of WRITE_SUSPEND field. */ +#define TWIS_SHORTS_WRITE_SUSPEND_Msk (0x1UL << TWIS_SHORTS_WRITE_SUSPEND_Pos) /*!< Bit mask of WRITE_SUSPEND field. */ +#define TWIS_SHORTS_WRITE_SUSPEND_Disabled (0UL) /*!< Disable shortcut */ +#define TWIS_SHORTS_WRITE_SUSPEND_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: TWIS_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 26 : Enable or disable interrupt for READ event */ +#define TWIS_INTEN_READ_Pos (26UL) /*!< Position of READ field. */ +#define TWIS_INTEN_READ_Msk (0x1UL << TWIS_INTEN_READ_Pos) /*!< Bit mask of READ field. */ +#define TWIS_INTEN_READ_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_READ_Enabled (1UL) /*!< Enable */ + +/* Bit 25 : Enable or disable interrupt for WRITE event */ +#define TWIS_INTEN_WRITE_Pos (25UL) /*!< Position of WRITE field. */ +#define TWIS_INTEN_WRITE_Msk (0x1UL << TWIS_INTEN_WRITE_Pos) /*!< Bit mask of WRITE field. */ +#define TWIS_INTEN_WRITE_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_WRITE_Enabled (1UL) /*!< Enable */ + +/* Bit 20 : Enable or disable interrupt for TXSTARTED event */ +#define TWIS_INTEN_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIS_INTEN_TXSTARTED_Msk (0x1UL << TWIS_INTEN_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIS_INTEN_TXSTARTED_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_TXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for RXSTARTED event */ +#define TWIS_INTEN_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIS_INTEN_RXSTARTED_Msk (0x1UL << TWIS_INTEN_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIS_INTEN_RXSTARTED_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_RXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for ERROR event */ +#define TWIS_INTEN_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIS_INTEN_ERROR_Msk (0x1UL << TWIS_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIS_INTEN_ERROR_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_ERROR_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for STOPPED event */ +#define TWIS_INTEN_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIS_INTEN_STOPPED_Msk (0x1UL << TWIS_INTEN_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIS_INTEN_STOPPED_Disabled (0UL) /*!< Disable */ +#define TWIS_INTEN_STOPPED_Enabled (1UL) /*!< Enable */ + +/* Register: TWIS_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 26 : Write '1' to Enable interrupt for READ event */ +#define TWIS_INTENSET_READ_Pos (26UL) /*!< Position of READ field. */ +#define TWIS_INTENSET_READ_Msk (0x1UL << TWIS_INTENSET_READ_Pos) /*!< Bit mask of READ field. */ +#define TWIS_INTENSET_READ_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_READ_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_READ_Set (1UL) /*!< Enable */ + +/* Bit 25 : Write '1' to Enable interrupt for WRITE event */ +#define TWIS_INTENSET_WRITE_Pos (25UL) /*!< Position of WRITE field. */ +#define TWIS_INTENSET_WRITE_Msk (0x1UL << TWIS_INTENSET_WRITE_Pos) /*!< Bit mask of WRITE field. */ +#define TWIS_INTENSET_WRITE_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_WRITE_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_WRITE_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for TXSTARTED event */ +#define TWIS_INTENSET_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIS_INTENSET_TXSTARTED_Msk (0x1UL << TWIS_INTENSET_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIS_INTENSET_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_TXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for RXSTARTED event */ +#define TWIS_INTENSET_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIS_INTENSET_RXSTARTED_Msk (0x1UL << TWIS_INTENSET_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIS_INTENSET_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ +#define TWIS_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIS_INTENSET_ERROR_Msk (0x1UL << TWIS_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIS_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STOPPED event */ +#define TWIS_INTENSET_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIS_INTENSET_STOPPED_Msk (0x1UL << TWIS_INTENSET_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIS_INTENSET_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENSET_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENSET_STOPPED_Set (1UL) /*!< Enable */ + +/* Register: TWIS_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 26 : Write '1' to Disable interrupt for READ event */ +#define TWIS_INTENCLR_READ_Pos (26UL) /*!< Position of READ field. */ +#define TWIS_INTENCLR_READ_Msk (0x1UL << TWIS_INTENCLR_READ_Pos) /*!< Bit mask of READ field. */ +#define TWIS_INTENCLR_READ_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_READ_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_READ_Clear (1UL) /*!< Disable */ + +/* Bit 25 : Write '1' to Disable interrupt for WRITE event */ +#define TWIS_INTENCLR_WRITE_Pos (25UL) /*!< Position of WRITE field. */ +#define TWIS_INTENCLR_WRITE_Msk (0x1UL << TWIS_INTENCLR_WRITE_Pos) /*!< Bit mask of WRITE field. */ +#define TWIS_INTENCLR_WRITE_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_WRITE_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_WRITE_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for TXSTARTED event */ +#define TWIS_INTENCLR_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define TWIS_INTENCLR_TXSTARTED_Msk (0x1UL << TWIS_INTENCLR_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define TWIS_INTENCLR_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_TXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for RXSTARTED event */ +#define TWIS_INTENCLR_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define TWIS_INTENCLR_RXSTARTED_Msk (0x1UL << TWIS_INTENCLR_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define TWIS_INTENCLR_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_RXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ +#define TWIS_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define TWIS_INTENCLR_ERROR_Msk (0x1UL << TWIS_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define TWIS_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STOPPED event */ +#define TWIS_INTENCLR_STOPPED_Pos (1UL) /*!< Position of STOPPED field. */ +#define TWIS_INTENCLR_STOPPED_Msk (0x1UL << TWIS_INTENCLR_STOPPED_Pos) /*!< Bit mask of STOPPED field. */ +#define TWIS_INTENCLR_STOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIS_INTENCLR_STOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIS_INTENCLR_STOPPED_Clear (1UL) /*!< Disable */ + +/* Register: TWIS_ERRORSRC */ +/* Description: Error source */ + +/* Bit 3 : TX buffer over-read detected, and prevented */ +#define TWIS_ERRORSRC_OVERREAD_Pos (3UL) /*!< Position of OVERREAD field. */ +#define TWIS_ERRORSRC_OVERREAD_Msk (0x1UL << TWIS_ERRORSRC_OVERREAD_Pos) /*!< Bit mask of OVERREAD field. */ +#define TWIS_ERRORSRC_OVERREAD_NotDetected (0UL) /*!< Error did not occur */ +#define TWIS_ERRORSRC_OVERREAD_Detected (1UL) /*!< Error occurred */ + +/* Bit 2 : NACK sent after receiving a data byte */ +#define TWIS_ERRORSRC_DNACK_Pos (2UL) /*!< Position of DNACK field. */ +#define TWIS_ERRORSRC_DNACK_Msk (0x1UL << TWIS_ERRORSRC_DNACK_Pos) /*!< Bit mask of DNACK field. */ +#define TWIS_ERRORSRC_DNACK_NotReceived (0UL) /*!< Error did not occur */ +#define TWIS_ERRORSRC_DNACK_Received (1UL) /*!< Error occurred */ + +/* Bit 0 : RX buffer overflow detected, and prevented */ +#define TWIS_ERRORSRC_OVERFLOW_Pos (0UL) /*!< Position of OVERFLOW field. */ +#define TWIS_ERRORSRC_OVERFLOW_Msk (0x1UL << TWIS_ERRORSRC_OVERFLOW_Pos) /*!< Bit mask of OVERFLOW field. */ +#define TWIS_ERRORSRC_OVERFLOW_NotDetected (0UL) /*!< Error did not occur */ +#define TWIS_ERRORSRC_OVERFLOW_Detected (1UL) /*!< Error occurred */ + +/* Register: TWIS_MATCH */ +/* Description: Status register indicating which address had a match */ + +/* Bit 0 : Which of the addresses in {ADDRESS} matched the incoming address */ +#define TWIS_MATCH_MATCH_Pos (0UL) /*!< Position of MATCH field. */ +#define TWIS_MATCH_MATCH_Msk (0x1UL << TWIS_MATCH_MATCH_Pos) /*!< Bit mask of MATCH field. */ + +/* Register: TWIS_ENABLE */ +/* Description: Enable TWIS */ + +/* Bits 3..0 : Enable or disable TWIS */ +#define TWIS_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define TWIS_ENABLE_ENABLE_Msk (0xFUL << TWIS_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define TWIS_ENABLE_ENABLE_Disabled (0UL) /*!< Disable TWIS */ +#define TWIS_ENABLE_ENABLE_Enabled (9UL) /*!< Enable TWIS */ + +/* Register: TWIS_PSEL_SCL */ +/* Description: Pin select for SCL signal */ + +/* Bit 31 : Connection */ +#define TWIS_PSEL_SCL_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWIS_PSEL_SCL_CONNECT_Msk (0x1UL << TWIS_PSEL_SCL_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWIS_PSEL_SCL_CONNECT_Connected (0UL) /*!< Connect */ +#define TWIS_PSEL_SCL_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define TWIS_PSEL_SCL_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWIS_PSEL_SCL_PORT_Msk (0x3UL << TWIS_PSEL_SCL_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWIS_PSEL_SCL_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWIS_PSEL_SCL_PIN_Msk (0x1FUL << TWIS_PSEL_SCL_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWIS_PSEL_SDA */ +/* Description: Pin select for SDA signal */ + +/* Bit 31 : Connection */ +#define TWIS_PSEL_SDA_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define TWIS_PSEL_SDA_CONNECT_Msk (0x1UL << TWIS_PSEL_SDA_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define TWIS_PSEL_SDA_CONNECT_Connected (0UL) /*!< Connect */ +#define TWIS_PSEL_SDA_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define TWIS_PSEL_SDA_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define TWIS_PSEL_SDA_PORT_Msk (0x3UL << TWIS_PSEL_SDA_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define TWIS_PSEL_SDA_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define TWIS_PSEL_SDA_PIN_Msk (0x1FUL << TWIS_PSEL_SDA_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: TWIS_RXD_PTR */ +/* Description: RXD Data pointer */ + +/* Bits 31..0 : RXD Data pointer */ +#define TWIS_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define TWIS_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << TWIS_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: TWIS_RXD_MAXCNT */ +/* Description: Maximum number of bytes in RXD buffer */ + +/* Bits 7..0 : Maximum number of bytes in RXD buffer */ +#define TWIS_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define TWIS_RXD_MAXCNT_MAXCNT_Msk (0xFFUL << TWIS_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: TWIS_RXD_AMOUNT */ +/* Description: Number of bytes transferred in the last RXD transaction */ + +/* Bits 7..0 : Number of bytes transferred in the last RXD transaction */ +#define TWIS_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define TWIS_RXD_AMOUNT_AMOUNT_Msk (0xFFUL << TWIS_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: TWIS_TXD_PTR */ +/* Description: TXD Data pointer */ + +/* Bits 31..0 : TXD Data pointer */ +#define TWIS_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define TWIS_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << TWIS_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: TWIS_TXD_MAXCNT */ +/* Description: Maximum number of bytes in TXD buffer */ + +/* Bits 7..0 : Maximum number of bytes in TXD buffer */ +#define TWIS_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define TWIS_TXD_MAXCNT_MAXCNT_Msk (0xFFUL << TWIS_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: TWIS_TXD_AMOUNT */ +/* Description: Number of bytes transferred in the last TXD transaction */ + +/* Bits 7..0 : Number of bytes transferred in the last TXD transaction */ +#define TWIS_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define TWIS_TXD_AMOUNT_AMOUNT_Msk (0xFFUL << TWIS_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: TWIS_ADDRESS */ +/* Description: Description collection[0]: TWI slave address 0 */ + +/* Bits 6..0 : TWI slave address */ +#define TWIS_ADDRESS_ADDRESS_Pos (0UL) /*!< Position of ADDRESS field. */ +#define TWIS_ADDRESS_ADDRESS_Msk (0x7FUL << TWIS_ADDRESS_ADDRESS_Pos) /*!< Bit mask of ADDRESS field. */ + +/* Register: TWIS_CONFIG */ +/* Description: Configuration register for the address match mechanism */ + +/* Bit 1 : Enable or disable address matching on ADDRESS[1] */ +#define TWIS_CONFIG_ADDRESS1_Pos (1UL) /*!< Position of ADDRESS1 field. */ +#define TWIS_CONFIG_ADDRESS1_Msk (0x1UL << TWIS_CONFIG_ADDRESS1_Pos) /*!< Bit mask of ADDRESS1 field. */ +#define TWIS_CONFIG_ADDRESS1_Disabled (0UL) /*!< Disabled */ +#define TWIS_CONFIG_ADDRESS1_Enabled (1UL) /*!< Enabled */ + +/* Bit 0 : Enable or disable address matching on ADDRESS[0] */ +#define TWIS_CONFIG_ADDRESS0_Pos (0UL) /*!< Position of ADDRESS0 field. */ +#define TWIS_CONFIG_ADDRESS0_Msk (0x1UL << TWIS_CONFIG_ADDRESS0_Pos) /*!< Bit mask of ADDRESS0 field. */ +#define TWIS_CONFIG_ADDRESS0_Disabled (0UL) /*!< Disabled */ +#define TWIS_CONFIG_ADDRESS0_Enabled (1UL) /*!< Enabled */ + +/* Register: TWIS_ORC */ +/* Description: Over-read character. Character sent out in case of an over-read of the transmit buffer. */ + +/* Bits 7..0 : Over-read character. Character sent out in case of an over-read of the transmit buffer. */ +#define TWIS_ORC_ORC_Pos (0UL) /*!< Position of ORC field. */ +#define TWIS_ORC_ORC_Msk (0xFFUL << TWIS_ORC_ORC_Pos) /*!< Bit mask of ORC field. */ + + +/* Peripheral: UART */ +/* Description: Universal Asynchronous Receiver/Transmitter */ + +/* Register: UART_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 4 : Shortcut between NCTS event and STOPRX task */ +#define UART_SHORTS_NCTS_STOPRX_Pos (4UL) /*!< Position of NCTS_STOPRX field. */ +#define UART_SHORTS_NCTS_STOPRX_Msk (0x1UL << UART_SHORTS_NCTS_STOPRX_Pos) /*!< Bit mask of NCTS_STOPRX field. */ +#define UART_SHORTS_NCTS_STOPRX_Disabled (0UL) /*!< Disable shortcut */ +#define UART_SHORTS_NCTS_STOPRX_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between CTS event and STARTRX task */ +#define UART_SHORTS_CTS_STARTRX_Pos (3UL) /*!< Position of CTS_STARTRX field. */ +#define UART_SHORTS_CTS_STARTRX_Msk (0x1UL << UART_SHORTS_CTS_STARTRX_Pos) /*!< Bit mask of CTS_STARTRX field. */ +#define UART_SHORTS_CTS_STARTRX_Disabled (0UL) /*!< Disable shortcut */ +#define UART_SHORTS_CTS_STARTRX_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: UART_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 17 : Write '1' to Enable interrupt for RXTO event */ +#define UART_INTENSET_RXTO_Pos (17UL) /*!< Position of RXTO field. */ +#define UART_INTENSET_RXTO_Msk (0x1UL << UART_INTENSET_RXTO_Pos) /*!< Bit mask of RXTO field. */ +#define UART_INTENSET_RXTO_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_RXTO_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_RXTO_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ +#define UART_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define UART_INTENSET_ERROR_Msk (0x1UL << UART_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define UART_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for TXDRDY event */ +#define UART_INTENSET_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UART_INTENSET_TXDRDY_Msk (0x1UL << UART_INTENSET_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UART_INTENSET_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_TXDRDY_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for RXDRDY event */ +#define UART_INTENSET_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UART_INTENSET_RXDRDY_Msk (0x1UL << UART_INTENSET_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UART_INTENSET_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_RXDRDY_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for NCTS event */ +#define UART_INTENSET_NCTS_Pos (1UL) /*!< Position of NCTS field. */ +#define UART_INTENSET_NCTS_Msk (0x1UL << UART_INTENSET_NCTS_Pos) /*!< Bit mask of NCTS field. */ +#define UART_INTENSET_NCTS_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_NCTS_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_NCTS_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for CTS event */ +#define UART_INTENSET_CTS_Pos (0UL) /*!< Position of CTS field. */ +#define UART_INTENSET_CTS_Msk (0x1UL << UART_INTENSET_CTS_Pos) /*!< Bit mask of CTS field. */ +#define UART_INTENSET_CTS_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENSET_CTS_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENSET_CTS_Set (1UL) /*!< Enable */ + +/* Register: UART_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 17 : Write '1' to Disable interrupt for RXTO event */ +#define UART_INTENCLR_RXTO_Pos (17UL) /*!< Position of RXTO field. */ +#define UART_INTENCLR_RXTO_Msk (0x1UL << UART_INTENCLR_RXTO_Pos) /*!< Bit mask of RXTO field. */ +#define UART_INTENCLR_RXTO_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_RXTO_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_RXTO_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ +#define UART_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define UART_INTENCLR_ERROR_Msk (0x1UL << UART_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define UART_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for TXDRDY event */ +#define UART_INTENCLR_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UART_INTENCLR_TXDRDY_Msk (0x1UL << UART_INTENCLR_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UART_INTENCLR_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_TXDRDY_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for RXDRDY event */ +#define UART_INTENCLR_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UART_INTENCLR_RXDRDY_Msk (0x1UL << UART_INTENCLR_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UART_INTENCLR_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_RXDRDY_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for NCTS event */ +#define UART_INTENCLR_NCTS_Pos (1UL) /*!< Position of NCTS field. */ +#define UART_INTENCLR_NCTS_Msk (0x1UL << UART_INTENCLR_NCTS_Pos) /*!< Bit mask of NCTS field. */ +#define UART_INTENCLR_NCTS_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_NCTS_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_NCTS_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for CTS event */ +#define UART_INTENCLR_CTS_Pos (0UL) /*!< Position of CTS field. */ +#define UART_INTENCLR_CTS_Msk (0x1UL << UART_INTENCLR_CTS_Pos) /*!< Bit mask of CTS field. */ +#define UART_INTENCLR_CTS_Disabled (0UL) /*!< Read: Disabled */ +#define UART_INTENCLR_CTS_Enabled (1UL) /*!< Read: Enabled */ +#define UART_INTENCLR_CTS_Clear (1UL) /*!< Disable */ + +/* Register: UART_ERRORSRC */ +/* Description: Error source */ + +/* Bit 3 : Break condition */ +#define UART_ERRORSRC_BREAK_Pos (3UL) /*!< Position of BREAK field. */ +#define UART_ERRORSRC_BREAK_Msk (0x1UL << UART_ERRORSRC_BREAK_Pos) /*!< Bit mask of BREAK field. */ +#define UART_ERRORSRC_BREAK_NotPresent (0UL) /*!< Read: error not present */ +#define UART_ERRORSRC_BREAK_Present (1UL) /*!< Read: error present */ + +/* Bit 2 : Framing error occurred */ +#define UART_ERRORSRC_FRAMING_Pos (2UL) /*!< Position of FRAMING field. */ +#define UART_ERRORSRC_FRAMING_Msk (0x1UL << UART_ERRORSRC_FRAMING_Pos) /*!< Bit mask of FRAMING field. */ +#define UART_ERRORSRC_FRAMING_NotPresent (0UL) /*!< Read: error not present */ +#define UART_ERRORSRC_FRAMING_Present (1UL) /*!< Read: error present */ + +/* Bit 1 : Parity error */ +#define UART_ERRORSRC_PARITY_Pos (1UL) /*!< Position of PARITY field. */ +#define UART_ERRORSRC_PARITY_Msk (0x1UL << UART_ERRORSRC_PARITY_Pos) /*!< Bit mask of PARITY field. */ +#define UART_ERRORSRC_PARITY_NotPresent (0UL) /*!< Read: error not present */ +#define UART_ERRORSRC_PARITY_Present (1UL) /*!< Read: error present */ + +/* Bit 0 : Overrun error */ +#define UART_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ +#define UART_ERRORSRC_OVERRUN_Msk (0x1UL << UART_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define UART_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Read: error not present */ +#define UART_ERRORSRC_OVERRUN_Present (1UL) /*!< Read: error present */ + +/* Register: UART_ENABLE */ +/* Description: Enable UART */ + +/* Bits 3..0 : Enable or disable UART */ +#define UART_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define UART_ENABLE_ENABLE_Msk (0xFUL << UART_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define UART_ENABLE_ENABLE_Disabled (0UL) /*!< Disable UART */ +#define UART_ENABLE_ENABLE_Enabled (4UL) /*!< Enable UART */ + +/* Register: UART_PSEL_RTS */ +/* Description: Pin select for RTS */ + +/* Bit 31 : Connection */ +#define UART_PSEL_RTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UART_PSEL_RTS_CONNECT_Msk (0x1UL << UART_PSEL_RTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UART_PSEL_RTS_CONNECT_Connected (0UL) /*!< Connect */ +#define UART_PSEL_RTS_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define UART_PSEL_RTS_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UART_PSEL_RTS_PORT_Msk (0x3UL << UART_PSEL_RTS_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UART_PSEL_RTS_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UART_PSEL_RTS_PIN_Msk (0x1FUL << UART_PSEL_RTS_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UART_PSEL_TXD */ +/* Description: Pin select for TXD */ + +/* Bit 31 : Connection */ +#define UART_PSEL_TXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UART_PSEL_TXD_CONNECT_Msk (0x1UL << UART_PSEL_TXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UART_PSEL_TXD_CONNECT_Connected (0UL) /*!< Connect */ +#define UART_PSEL_TXD_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define UART_PSEL_TXD_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UART_PSEL_TXD_PORT_Msk (0x3UL << UART_PSEL_TXD_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UART_PSEL_TXD_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UART_PSEL_TXD_PIN_Msk (0x1FUL << UART_PSEL_TXD_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UART_PSEL_CTS */ +/* Description: Pin select for CTS */ + +/* Bit 31 : Connection */ +#define UART_PSEL_CTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UART_PSEL_CTS_CONNECT_Msk (0x1UL << UART_PSEL_CTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UART_PSEL_CTS_CONNECT_Connected (0UL) /*!< Connect */ +#define UART_PSEL_CTS_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define UART_PSEL_CTS_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UART_PSEL_CTS_PORT_Msk (0x3UL << UART_PSEL_CTS_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UART_PSEL_CTS_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UART_PSEL_CTS_PIN_Msk (0x1FUL << UART_PSEL_CTS_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UART_PSEL_RXD */ +/* Description: Pin select for RXD */ + +/* Bit 31 : Connection */ +#define UART_PSEL_RXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UART_PSEL_RXD_CONNECT_Msk (0x1UL << UART_PSEL_RXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UART_PSEL_RXD_CONNECT_Connected (0UL) /*!< Connect */ +#define UART_PSEL_RXD_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define UART_PSEL_RXD_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UART_PSEL_RXD_PORT_Msk (0x3UL << UART_PSEL_RXD_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UART_PSEL_RXD_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UART_PSEL_RXD_PIN_Msk (0x1FUL << UART_PSEL_RXD_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UART_RXD */ +/* Description: RXD register */ + +/* Bits 7..0 : RX data received in previous transfers, double buffered */ +#define UART_RXD_RXD_Pos (0UL) /*!< Position of RXD field. */ +#define UART_RXD_RXD_Msk (0xFFUL << UART_RXD_RXD_Pos) /*!< Bit mask of RXD field. */ + +/* Register: UART_TXD */ +/* Description: TXD register */ + +/* Bits 7..0 : TX data to be transferred */ +#define UART_TXD_TXD_Pos (0UL) /*!< Position of TXD field. */ +#define UART_TXD_TXD_Msk (0xFFUL << UART_TXD_TXD_Pos) /*!< Bit mask of TXD field. */ + +/* Register: UART_BAUDRATE */ +/* Description: Baud rate. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : Baud rate */ +#define UART_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */ +#define UART_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UART_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */ +#define UART_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud (actual rate: 1205) */ +#define UART_BAUDRATE_BAUDRATE_Baud2400 (0x0009D000UL) /*!< 2400 baud (actual rate: 2396) */ +#define UART_BAUDRATE_BAUDRATE_Baud4800 (0x0013B000UL) /*!< 4800 baud (actual rate: 4808) */ +#define UART_BAUDRATE_BAUDRATE_Baud9600 (0x00275000UL) /*!< 9600 baud (actual rate: 9598) */ +#define UART_BAUDRATE_BAUDRATE_Baud14400 (0x003B0000UL) /*!< 14400 baud (actual rate: 14414) */ +#define UART_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud (actual rate: 19208) */ +#define UART_BAUDRATE_BAUDRATE_Baud28800 (0x0075F000UL) /*!< 28800 baud (actual rate: 28829) */ +#define UART_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud */ +#define UART_BAUDRATE_BAUDRATE_Baud38400 (0x009D5000UL) /*!< 38400 baud (actual rate: 38462) */ +#define UART_BAUDRATE_BAUDRATE_Baud56000 (0x00E50000UL) /*!< 56000 baud (actual rate: 55944) */ +#define UART_BAUDRATE_BAUDRATE_Baud57600 (0x00EBF000UL) /*!< 57600 baud (actual rate: 57762) */ +#define UART_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud (actual rate: 76923) */ +#define UART_BAUDRATE_BAUDRATE_Baud115200 (0x01D7E000UL) /*!< 115200 baud (actual rate: 115942) */ +#define UART_BAUDRATE_BAUDRATE_Baud230400 (0x03AFB000UL) /*!< 230400 baud (actual rate: 231884) */ +#define UART_BAUDRATE_BAUDRATE_Baud250000 (0x04000000UL) /*!< 250000 baud */ +#define UART_BAUDRATE_BAUDRATE_Baud460800 (0x075F7000UL) /*!< 460800 baud (actual rate: 470588) */ +#define UART_BAUDRATE_BAUDRATE_Baud921600 (0x0EBED000UL) /*!< 921600 baud (actual rate: 941176) */ +#define UART_BAUDRATE_BAUDRATE_Baud1M (0x10000000UL) /*!< 1Mega baud */ + +/* Register: UART_CONFIG */ +/* Description: Configuration of parity and hardware flow control */ + +/* Bits 3..1 : Parity */ +#define UART_CONFIG_PARITY_Pos (1UL) /*!< Position of PARITY field. */ +#define UART_CONFIG_PARITY_Msk (0x7UL << UART_CONFIG_PARITY_Pos) /*!< Bit mask of PARITY field. */ +#define UART_CONFIG_PARITY_Excluded (0x0UL) /*!< Exclude parity bit */ +#define UART_CONFIG_PARITY_Included (0x7UL) /*!< Include parity bit */ + +/* Bit 0 : Hardware flow control */ +#define UART_CONFIG_HWFC_Pos (0UL) /*!< Position of HWFC field. */ +#define UART_CONFIG_HWFC_Msk (0x1UL << UART_CONFIG_HWFC_Pos) /*!< Bit mask of HWFC field. */ +#define UART_CONFIG_HWFC_Disabled (0UL) /*!< Disabled */ +#define UART_CONFIG_HWFC_Enabled (1UL) /*!< Enabled */ + + +/* Peripheral: UARTE */ +/* Description: UART with EasyDMA 0 */ + +/* Register: UARTE_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 6 : Shortcut between ENDRX event and STOPRX task */ +#define UARTE_SHORTS_ENDRX_STOPRX_Pos (6UL) /*!< Position of ENDRX_STOPRX field. */ +#define UARTE_SHORTS_ENDRX_STOPRX_Msk (0x1UL << UARTE_SHORTS_ENDRX_STOPRX_Pos) /*!< Bit mask of ENDRX_STOPRX field. */ +#define UARTE_SHORTS_ENDRX_STOPRX_Disabled (0UL) /*!< Disable shortcut */ +#define UARTE_SHORTS_ENDRX_STOPRX_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 5 : Shortcut between ENDRX event and STARTRX task */ +#define UARTE_SHORTS_ENDRX_STARTRX_Pos (5UL) /*!< Position of ENDRX_STARTRX field. */ +#define UARTE_SHORTS_ENDRX_STARTRX_Msk (0x1UL << UARTE_SHORTS_ENDRX_STARTRX_Pos) /*!< Bit mask of ENDRX_STARTRX field. */ +#define UARTE_SHORTS_ENDRX_STARTRX_Disabled (0UL) /*!< Disable shortcut */ +#define UARTE_SHORTS_ENDRX_STARTRX_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: UARTE_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 22 : Enable or disable interrupt for TXSTOPPED event */ +#define UARTE_INTEN_TXSTOPPED_Pos (22UL) /*!< Position of TXSTOPPED field. */ +#define UARTE_INTEN_TXSTOPPED_Msk (0x1UL << UARTE_INTEN_TXSTOPPED_Pos) /*!< Bit mask of TXSTOPPED field. */ +#define UARTE_INTEN_TXSTOPPED_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_TXSTOPPED_Enabled (1UL) /*!< Enable */ + +/* Bit 20 : Enable or disable interrupt for TXSTARTED event */ +#define UARTE_INTEN_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define UARTE_INTEN_TXSTARTED_Msk (0x1UL << UARTE_INTEN_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define UARTE_INTEN_TXSTARTED_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_TXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for RXSTARTED event */ +#define UARTE_INTEN_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define UARTE_INTEN_RXSTARTED_Msk (0x1UL << UARTE_INTEN_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define UARTE_INTEN_RXSTARTED_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_RXSTARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 17 : Enable or disable interrupt for RXTO event */ +#define UARTE_INTEN_RXTO_Pos (17UL) /*!< Position of RXTO field. */ +#define UARTE_INTEN_RXTO_Msk (0x1UL << UARTE_INTEN_RXTO_Pos) /*!< Bit mask of RXTO field. */ +#define UARTE_INTEN_RXTO_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_RXTO_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for ERROR event */ +#define UARTE_INTEN_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define UARTE_INTEN_ERROR_Msk (0x1UL << UARTE_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define UARTE_INTEN_ERROR_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_ERROR_Enabled (1UL) /*!< Enable */ + +/* Bit 8 : Enable or disable interrupt for ENDTX event */ +#define UARTE_INTEN_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ +#define UARTE_INTEN_ENDTX_Msk (0x1UL << UARTE_INTEN_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define UARTE_INTEN_ENDTX_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_ENDTX_Enabled (1UL) /*!< Enable */ + +/* Bit 7 : Enable or disable interrupt for TXDRDY event */ +#define UARTE_INTEN_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTEN_TXDRDY_Msk (0x1UL << UARTE_INTEN_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTEN_TXDRDY_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_TXDRDY_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for ENDRX event */ +#define UARTE_INTEN_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define UARTE_INTEN_ENDRX_Msk (0x1UL << UARTE_INTEN_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define UARTE_INTEN_ENDRX_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_ENDRX_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for RXDRDY event */ +#define UARTE_INTEN_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTEN_RXDRDY_Msk (0x1UL << UARTE_INTEN_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTEN_RXDRDY_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_RXDRDY_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for NCTS event */ +#define UARTE_INTEN_NCTS_Pos (1UL) /*!< Position of NCTS field. */ +#define UARTE_INTEN_NCTS_Msk (0x1UL << UARTE_INTEN_NCTS_Pos) /*!< Bit mask of NCTS field. */ +#define UARTE_INTEN_NCTS_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_NCTS_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for CTS event */ +#define UARTE_INTEN_CTS_Pos (0UL) /*!< Position of CTS field. */ +#define UARTE_INTEN_CTS_Msk (0x1UL << UARTE_INTEN_CTS_Pos) /*!< Bit mask of CTS field. */ +#define UARTE_INTEN_CTS_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_CTS_Enabled (1UL) /*!< Enable */ + +/* Register: UARTE_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 22 : Write '1' to Enable interrupt for TXSTOPPED event */ +#define UARTE_INTENSET_TXSTOPPED_Pos (22UL) /*!< Position of TXSTOPPED field. */ +#define UARTE_INTENSET_TXSTOPPED_Msk (0x1UL << UARTE_INTENSET_TXSTOPPED_Pos) /*!< Bit mask of TXSTOPPED field. */ +#define UARTE_INTENSET_TXSTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_TXSTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_TXSTOPPED_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for TXSTARTED event */ +#define UARTE_INTENSET_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define UARTE_INTENSET_TXSTARTED_Msk (0x1UL << UARTE_INTENSET_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define UARTE_INTENSET_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_TXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for RXSTARTED event */ +#define UARTE_INTENSET_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define UARTE_INTENSET_RXSTARTED_Msk (0x1UL << UARTE_INTENSET_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define UARTE_INTENSET_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for RXTO event */ +#define UARTE_INTENSET_RXTO_Pos (17UL) /*!< Position of RXTO field. */ +#define UARTE_INTENSET_RXTO_Msk (0x1UL << UARTE_INTENSET_RXTO_Pos) /*!< Bit mask of RXTO field. */ +#define UARTE_INTENSET_RXTO_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_RXTO_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_RXTO_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ERROR event */ +#define UARTE_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define UARTE_INTENSET_ERROR_Msk (0x1UL << UARTE_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define UARTE_INTENSET_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_ERROR_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for ENDTX event */ +#define UARTE_INTENSET_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ +#define UARTE_INTENSET_ENDTX_Msk (0x1UL << UARTE_INTENSET_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define UARTE_INTENSET_ENDTX_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_ENDTX_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_ENDTX_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for TXDRDY event */ +#define UARTE_INTENSET_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTENSET_TXDRDY_Msk (0x1UL << UARTE_INTENSET_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTENSET_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_TXDRDY_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for ENDRX event */ +#define UARTE_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define UARTE_INTENSET_ENDRX_Msk (0x1UL << UARTE_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define UARTE_INTENSET_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_ENDRX_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for RXDRDY event */ +#define UARTE_INTENSET_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTENSET_RXDRDY_Msk (0x1UL << UARTE_INTENSET_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTENSET_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_RXDRDY_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for NCTS event */ +#define UARTE_INTENSET_NCTS_Pos (1UL) /*!< Position of NCTS field. */ +#define UARTE_INTENSET_NCTS_Msk (0x1UL << UARTE_INTENSET_NCTS_Pos) /*!< Bit mask of NCTS field. */ +#define UARTE_INTENSET_NCTS_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_NCTS_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_NCTS_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for CTS event */ +#define UARTE_INTENSET_CTS_Pos (0UL) /*!< Position of CTS field. */ +#define UARTE_INTENSET_CTS_Msk (0x1UL << UARTE_INTENSET_CTS_Pos) /*!< Bit mask of CTS field. */ +#define UARTE_INTENSET_CTS_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_CTS_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_CTS_Set (1UL) /*!< Enable */ + +/* Register: UARTE_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 22 : Write '1' to Disable interrupt for TXSTOPPED event */ +#define UARTE_INTENCLR_TXSTOPPED_Pos (22UL) /*!< Position of TXSTOPPED field. */ +#define UARTE_INTENCLR_TXSTOPPED_Msk (0x1UL << UARTE_INTENCLR_TXSTOPPED_Pos) /*!< Bit mask of TXSTOPPED field. */ +#define UARTE_INTENCLR_TXSTOPPED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_TXSTOPPED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_TXSTOPPED_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for TXSTARTED event */ +#define UARTE_INTENCLR_TXSTARTED_Pos (20UL) /*!< Position of TXSTARTED field. */ +#define UARTE_INTENCLR_TXSTARTED_Msk (0x1UL << UARTE_INTENCLR_TXSTARTED_Pos) /*!< Bit mask of TXSTARTED field. */ +#define UARTE_INTENCLR_TXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_TXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_TXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for RXSTARTED event */ +#define UARTE_INTENCLR_RXSTARTED_Pos (19UL) /*!< Position of RXSTARTED field. */ +#define UARTE_INTENCLR_RXSTARTED_Msk (0x1UL << UARTE_INTENCLR_RXSTARTED_Pos) /*!< Bit mask of RXSTARTED field. */ +#define UARTE_INTENCLR_RXSTARTED_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_RXSTARTED_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for RXTO event */ +#define UARTE_INTENCLR_RXTO_Pos (17UL) /*!< Position of RXTO field. */ +#define UARTE_INTENCLR_RXTO_Msk (0x1UL << UARTE_INTENCLR_RXTO_Pos) /*!< Bit mask of RXTO field. */ +#define UARTE_INTENCLR_RXTO_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_RXTO_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_RXTO_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ERROR event */ +#define UARTE_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ +#define UARTE_INTENCLR_ERROR_Msk (0x1UL << UARTE_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ +#define UARTE_INTENCLR_ERROR_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_ERROR_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_ERROR_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for ENDTX event */ +#define UARTE_INTENCLR_ENDTX_Pos (8UL) /*!< Position of ENDTX field. */ +#define UARTE_INTENCLR_ENDTX_Msk (0x1UL << UARTE_INTENCLR_ENDTX_Pos) /*!< Bit mask of ENDTX field. */ +#define UARTE_INTENCLR_ENDTX_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_ENDTX_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_ENDTX_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for TXDRDY event */ +#define UARTE_INTENCLR_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTENCLR_TXDRDY_Msk (0x1UL << UARTE_INTENCLR_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTENCLR_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_TXDRDY_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for ENDRX event */ +#define UARTE_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ +#define UARTE_INTENCLR_ENDRX_Msk (0x1UL << UARTE_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ +#define UARTE_INTENCLR_ENDRX_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for RXDRDY event */ +#define UARTE_INTENCLR_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTENCLR_RXDRDY_Msk (0x1UL << UARTE_INTENCLR_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTENCLR_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_RXDRDY_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for NCTS event */ +#define UARTE_INTENCLR_NCTS_Pos (1UL) /*!< Position of NCTS field. */ +#define UARTE_INTENCLR_NCTS_Msk (0x1UL << UARTE_INTENCLR_NCTS_Pos) /*!< Bit mask of NCTS field. */ +#define UARTE_INTENCLR_NCTS_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_NCTS_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_NCTS_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for CTS event */ +#define UARTE_INTENCLR_CTS_Pos (0UL) /*!< Position of CTS field. */ +#define UARTE_INTENCLR_CTS_Msk (0x1UL << UARTE_INTENCLR_CTS_Pos) /*!< Bit mask of CTS field. */ +#define UARTE_INTENCLR_CTS_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_CTS_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_CTS_Clear (1UL) /*!< Disable */ + +/* Register: UARTE_ERRORSRC */ +/* Description: Error source Note : this register is read / write one to clear. */ + +/* Bit 3 : Break condition */ +#define UARTE_ERRORSRC_BREAK_Pos (3UL) /*!< Position of BREAK field. */ +#define UARTE_ERRORSRC_BREAK_Msk (0x1UL << UARTE_ERRORSRC_BREAK_Pos) /*!< Bit mask of BREAK field. */ +#define UARTE_ERRORSRC_BREAK_NotPresent (0UL) /*!< Read: error not present */ +#define UARTE_ERRORSRC_BREAK_Present (1UL) /*!< Read: error present */ + +/* Bit 2 : Framing error occurred */ +#define UARTE_ERRORSRC_FRAMING_Pos (2UL) /*!< Position of FRAMING field. */ +#define UARTE_ERRORSRC_FRAMING_Msk (0x1UL << UARTE_ERRORSRC_FRAMING_Pos) /*!< Bit mask of FRAMING field. */ +#define UARTE_ERRORSRC_FRAMING_NotPresent (0UL) /*!< Read: error not present */ +#define UARTE_ERRORSRC_FRAMING_Present (1UL) /*!< Read: error present */ + +/* Bit 1 : Parity error */ +#define UARTE_ERRORSRC_PARITY_Pos (1UL) /*!< Position of PARITY field. */ +#define UARTE_ERRORSRC_PARITY_Msk (0x1UL << UARTE_ERRORSRC_PARITY_Pos) /*!< Bit mask of PARITY field. */ +#define UARTE_ERRORSRC_PARITY_NotPresent (0UL) /*!< Read: error not present */ +#define UARTE_ERRORSRC_PARITY_Present (1UL) /*!< Read: error present */ + +/* Bit 0 : Overrun error */ +#define UARTE_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ +#define UARTE_ERRORSRC_OVERRUN_Msk (0x1UL << UARTE_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define UARTE_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Read: error not present */ +#define UARTE_ERRORSRC_OVERRUN_Present (1UL) /*!< Read: error present */ + +/* Register: UARTE_ENABLE */ +/* Description: Enable UART */ + +/* Bits 3..0 : Enable or disable UARTE */ +#define UARTE_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define UARTE_ENABLE_ENABLE_Msk (0xFUL << UARTE_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define UARTE_ENABLE_ENABLE_Disabled (0UL) /*!< Disable UARTE */ +#define UARTE_ENABLE_ENABLE_Enabled (8UL) /*!< Enable UARTE */ + +/* Register: UARTE_PSEL_RTS */ +/* Description: Pin select for RTS signal */ + +/* Bit 31 : Connection */ +#define UARTE_PSEL_RTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UARTE_PSEL_RTS_CONNECT_Msk (0x1UL << UARTE_PSEL_RTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UARTE_PSEL_RTS_CONNECT_Connected (0UL) /*!< Connect */ +#define UARTE_PSEL_RTS_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define UARTE_PSEL_RTS_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UARTE_PSEL_RTS_PORT_Msk (0x3UL << UARTE_PSEL_RTS_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UARTE_PSEL_RTS_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UARTE_PSEL_RTS_PIN_Msk (0x1FUL << UARTE_PSEL_RTS_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UARTE_PSEL_TXD */ +/* Description: Pin select for TXD signal */ + +/* Bit 31 : Connection */ +#define UARTE_PSEL_TXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UARTE_PSEL_TXD_CONNECT_Msk (0x1UL << UARTE_PSEL_TXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UARTE_PSEL_TXD_CONNECT_Connected (0UL) /*!< Connect */ +#define UARTE_PSEL_TXD_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define UARTE_PSEL_TXD_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UARTE_PSEL_TXD_PORT_Msk (0x3UL << UARTE_PSEL_TXD_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UARTE_PSEL_TXD_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UARTE_PSEL_TXD_PIN_Msk (0x1FUL << UARTE_PSEL_TXD_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UARTE_PSEL_CTS */ +/* Description: Pin select for CTS signal */ + +/* Bit 31 : Connection */ +#define UARTE_PSEL_CTS_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UARTE_PSEL_CTS_CONNECT_Msk (0x1UL << UARTE_PSEL_CTS_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UARTE_PSEL_CTS_CONNECT_Connected (0UL) /*!< Connect */ +#define UARTE_PSEL_CTS_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define UARTE_PSEL_CTS_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UARTE_PSEL_CTS_PORT_Msk (0x3UL << UARTE_PSEL_CTS_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UARTE_PSEL_CTS_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UARTE_PSEL_CTS_PIN_Msk (0x1FUL << UARTE_PSEL_CTS_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UARTE_PSEL_RXD */ +/* Description: Pin select for RXD signal */ + +/* Bit 31 : Connection */ +#define UARTE_PSEL_RXD_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UARTE_PSEL_RXD_CONNECT_Msk (0x1UL << UARTE_PSEL_RXD_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UARTE_PSEL_RXD_CONNECT_Connected (0UL) /*!< Connect */ +#define UARTE_PSEL_RXD_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number */ +#define UARTE_PSEL_RXD_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UARTE_PSEL_RXD_PORT_Msk (0x3UL << UARTE_PSEL_RXD_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number */ +#define UARTE_PSEL_RXD_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UARTE_PSEL_RXD_PIN_Msk (0x1FUL << UARTE_PSEL_RXD_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UARTE_BAUDRATE */ +/* Description: Baud rate. Accuracy depends on the HFCLK source selected. */ + +/* Bits 31..0 : Baud rate */ +#define UARTE_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */ +#define UARTE_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UARTE_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */ +#define UARTE_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud (actual rate: 1205) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud2400 (0x0009D000UL) /*!< 2400 baud (actual rate: 2396) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud4800 (0x0013B000UL) /*!< 4800 baud (actual rate: 4808) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud9600 (0x00275000UL) /*!< 9600 baud (actual rate: 9598) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud14400 (0x003AF000UL) /*!< 14400 baud (actual rate: 14401) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud (actual rate: 19208) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud28800 (0x0075C000UL) /*!< 28800 baud (actual rate: 28777) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud */ +#define UARTE_BAUDRATE_BAUDRATE_Baud38400 (0x009D0000UL) /*!< 38400 baud (actual rate: 38369) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud56000 (0x00E50000UL) /*!< 56000 baud (actual rate: 55944) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud57600 (0x00EB0000UL) /*!< 57600 baud (actual rate: 57554) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud (actual rate: 76923) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud115200 (0x01D60000UL) /*!< 115200 baud (actual rate: 115108) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud230400 (0x03B00000UL) /*!< 230400 baud (actual rate: 231884) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud250000 (0x04000000UL) /*!< 250000 baud */ +#define UARTE_BAUDRATE_BAUDRATE_Baud460800 (0x07400000UL) /*!< 460800 baud (actual rate: 457143) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud921600 (0x0F000000UL) /*!< 921600 baud (actual rate: 941176) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud1M (0x10000000UL) /*!< 1Mega baud */ + +/* Register: UARTE_RXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define UARTE_RXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define UARTE_RXD_PTR_PTR_Msk (0xFFFFFFFFUL << UARTE_RXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: UARTE_RXD_MAXCNT */ +/* Description: Maximum number of bytes in receive buffer */ + +/* Bits 9..0 : Maximum number of bytes in receive buffer */ +#define UARTE_RXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define UARTE_RXD_MAXCNT_MAXCNT_Msk (0x3FFUL << UARTE_RXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: UARTE_RXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 9..0 : Number of bytes transferred in the last transaction */ +#define UARTE_RXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define UARTE_RXD_AMOUNT_AMOUNT_Msk (0x3FFUL << UARTE_RXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: UARTE_TXD_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer */ +#define UARTE_TXD_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define UARTE_TXD_PTR_PTR_Msk (0xFFFFFFFFUL << UARTE_TXD_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: UARTE_TXD_MAXCNT */ +/* Description: Maximum number of bytes in transmit buffer */ + +/* Bits 9..0 : Maximum number of bytes in transmit buffer */ +#define UARTE_TXD_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define UARTE_TXD_MAXCNT_MAXCNT_Msk (0x3FFUL << UARTE_TXD_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: UARTE_TXD_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 9..0 : Number of bytes transferred in the last transaction */ +#define UARTE_TXD_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define UARTE_TXD_AMOUNT_AMOUNT_Msk (0x3FFUL << UARTE_TXD_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: UARTE_CONFIG */ +/* Description: Configuration of parity and hardware flow control */ + +/* Bit 4 : Stop bits */ +#define UARTE_CONFIG_STOP_Pos (4UL) /*!< Position of STOP field. */ +#define UARTE_CONFIG_STOP_Msk (0x1UL << UARTE_CONFIG_STOP_Pos) /*!< Bit mask of STOP field. */ +#define UARTE_CONFIG_STOP_One (0UL) /*!< One stop bit */ +#define UARTE_CONFIG_STOP_Two (1UL) /*!< Two stop bits */ + +/* Bits 3..1 : Parity */ +#define UARTE_CONFIG_PARITY_Pos (1UL) /*!< Position of PARITY field. */ +#define UARTE_CONFIG_PARITY_Msk (0x7UL << UARTE_CONFIG_PARITY_Pos) /*!< Bit mask of PARITY field. */ +#define UARTE_CONFIG_PARITY_Excluded (0x0UL) /*!< Exclude parity bit */ +#define UARTE_CONFIG_PARITY_Included (0x7UL) /*!< Include even parity bit */ + +/* Bit 0 : Hardware flow control */ +#define UARTE_CONFIG_HWFC_Pos (0UL) /*!< Position of HWFC field. */ +#define UARTE_CONFIG_HWFC_Msk (0x1UL << UARTE_CONFIG_HWFC_Pos) /*!< Bit mask of HWFC field. */ +#define UARTE_CONFIG_HWFC_Disabled (0UL) /*!< Disabled */ +#define UARTE_CONFIG_HWFC_Enabled (1UL) /*!< Enabled */ + + +/* Peripheral: UICR */ +/* Description: User Information Configuration Registers */ + +/* Register: UICR_NRFFW */ +/* Description: Description collection[0]: Reserved for Nordic firmware design */ + +/* Bits 31..0 : Reserved for Nordic firmware design */ +#define UICR_NRFFW_NRFFW_Pos (0UL) /*!< Position of NRFFW field. */ +#define UICR_NRFFW_NRFFW_Msk (0xFFFFFFFFUL << UICR_NRFFW_NRFFW_Pos) /*!< Bit mask of NRFFW field. */ + +/* Register: UICR_NRFHW */ +/* Description: Description collection[0]: Reserved for Nordic hardware design */ + +/* Bits 31..0 : Reserved for Nordic hardware design */ +#define UICR_NRFHW_NRFHW_Pos (0UL) /*!< Position of NRFHW field. */ +#define UICR_NRFHW_NRFHW_Msk (0xFFFFFFFFUL << UICR_NRFHW_NRFHW_Pos) /*!< Bit mask of NRFHW field. */ + +/* Register: UICR_CUSTOMER */ +/* Description: Description collection[0]: Reserved for customer */ + +/* Bits 31..0 : Reserved for customer */ +#define UICR_CUSTOMER_CUSTOMER_Pos (0UL) /*!< Position of CUSTOMER field. */ +#define UICR_CUSTOMER_CUSTOMER_Msk (0xFFFFFFFFUL << UICR_CUSTOMER_CUSTOMER_Pos) /*!< Bit mask of CUSTOMER field. */ + +/* Register: UICR_PSELRESET */ +/* Description: Description collection[0]: Mapping of the nRESET function */ + +/* Bit 31 : Connection */ +#define UICR_PSELRESET_CONNECT_Pos (31UL) /*!< Position of CONNECT field. */ +#define UICR_PSELRESET_CONNECT_Msk (0x1UL << UICR_PSELRESET_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define UICR_PSELRESET_CONNECT_Connected (0UL) /*!< Connect */ +#define UICR_PSELRESET_CONNECT_Disconnected (1UL) /*!< Disconnect */ + +/* Bits 6..5 : Port number onto which nRESET is exposed */ +#define UICR_PSELRESET_PORT_Pos (5UL) /*!< Position of PORT field. */ +#define UICR_PSELRESET_PORT_Msk (0x3UL << UICR_PSELRESET_PORT_Pos) /*!< Bit mask of PORT field. */ + +/* Bits 4..0 : Pin number of PORT onto which nRESET is exposed */ +#define UICR_PSELRESET_PIN_Pos (0UL) /*!< Position of PIN field. */ +#define UICR_PSELRESET_PIN_Msk (0x1FUL << UICR_PSELRESET_PIN_Pos) /*!< Bit mask of PIN field. */ + +/* Register: UICR_APPROTECT */ +/* Description: Access port protection */ + +/* Bits 7..0 : Enable or disable Access Port protection. */ +#define UICR_APPROTECT_PALL_Pos (0UL) /*!< Position of PALL field. */ +#define UICR_APPROTECT_PALL_Msk (0xFFUL << UICR_APPROTECT_PALL_Pos) /*!< Bit mask of PALL field. */ +#define UICR_APPROTECT_PALL_Enabled (0x00UL) /*!< Enable */ +#define UICR_APPROTECT_PALL_Disabled (0xFFUL) /*!< Disable */ + +/* Register: UICR_NFCPINS */ +/* Description: Setting of pins dedicated to NFC functionality: NFC antenna or GPIO */ + +/* Bit 0 : Setting of pins dedicated to NFC functionality */ +#define UICR_NFCPINS_PROTECT_Pos (0UL) /*!< Position of PROTECT field. */ +#define UICR_NFCPINS_PROTECT_Msk (0x1UL << UICR_NFCPINS_PROTECT_Pos) /*!< Bit mask of PROTECT field. */ +#define UICR_NFCPINS_PROTECT_Disabled (0UL) /*!< Operation as GPIO pins. Same protection as normal GPIO pins */ +#define UICR_NFCPINS_PROTECT_NFC (1UL) /*!< Operation as NFC antenna pins. Configures the protection for NFC operation */ + +/* Register: UICR_EXTSUPPLY */ +/* Description: Enable external circuitry to be supplied from VDD pin. Applicable in 'High voltage mode' only. */ + +/* Bit 0 : Enable external circuitry to be supplied from VDD pin (output of REG0 stage). */ +#define UICR_EXTSUPPLY_EXTSUPPLY_Pos (0UL) /*!< Position of EXTSUPPLY field. */ +#define UICR_EXTSUPPLY_EXTSUPPLY_Msk (0x1UL << UICR_EXTSUPPLY_EXTSUPPLY_Pos) /*!< Bit mask of EXTSUPPLY field. */ +#define UICR_EXTSUPPLY_EXTSUPPLY_Disabled (0UL) /*!< No current can be drawn from the VDD pin. */ +#define UICR_EXTSUPPLY_EXTSUPPLY_Enabled (1UL) /*!< It is allowed to supply external circuitry from the VDD pin. */ + +/* Register: UICR_REGOUT0 */ +/* Description: GPIO reference voltage / external output supply voltage in 'High voltage mode'. */ + +/* Bits 2..0 : Output voltage from of REG0 regulator stage. The maximum output voltage from this stage is given as VDDH - VEXDIF. */ +#define UICR_REGOUT0_VOUT_Pos (0UL) /*!< Position of VOUT field. */ +#define UICR_REGOUT0_VOUT_Msk (0x7UL << UICR_REGOUT0_VOUT_Pos) /*!< Bit mask of VOUT field. */ +#define UICR_REGOUT0_VOUT_1V8 (0UL) /*!< 1.8 V */ +#define UICR_REGOUT0_VOUT_2V1 (1UL) /*!< 2.1 V */ +#define UICR_REGOUT0_VOUT_2V4 (2UL) /*!< 2.4 V */ +#define UICR_REGOUT0_VOUT_2V7 (3UL) /*!< 2.7 V */ +#define UICR_REGOUT0_VOUT_3V0 (4UL) /*!< 3.0 V */ +#define UICR_REGOUT0_VOUT_3V3 (5UL) /*!< 3.3 V */ +#define UICR_REGOUT0_VOUT_DEFAULT (7UL) /*!< Default voltage: 1.8 V */ + + +/* Peripheral: USBD */ +/* Description: Universal Serial Bus device */ + +/* Register: USBD_SHORTS */ +/* Description: Shortcut register */ + +/* Bit 4 : Shortcut between ENDEPOUT[0] event and EP0RCVOUT task */ +#define USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Pos (4UL) /*!< Position of ENDEPOUT0_EP0RCVOUT field. */ +#define USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Msk (0x1UL << USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Pos) /*!< Bit mask of ENDEPOUT0_EP0RCVOUT field. */ +#define USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Disabled (0UL) /*!< Disable shortcut */ +#define USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 3 : Shortcut between ENDEPOUT[0] event and EP0STATUS task */ +#define USBD_SHORTS_ENDEPOUT0_EP0STATUS_Pos (3UL) /*!< Position of ENDEPOUT0_EP0STATUS field. */ +#define USBD_SHORTS_ENDEPOUT0_EP0STATUS_Msk (0x1UL << USBD_SHORTS_ENDEPOUT0_EP0STATUS_Pos) /*!< Bit mask of ENDEPOUT0_EP0STATUS field. */ +#define USBD_SHORTS_ENDEPOUT0_EP0STATUS_Disabled (0UL) /*!< Disable shortcut */ +#define USBD_SHORTS_ENDEPOUT0_EP0STATUS_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 2 : Shortcut between EP0DATADONE event and EP0STATUS task */ +#define USBD_SHORTS_EP0DATADONE_EP0STATUS_Pos (2UL) /*!< Position of EP0DATADONE_EP0STATUS field. */ +#define USBD_SHORTS_EP0DATADONE_EP0STATUS_Msk (0x1UL << USBD_SHORTS_EP0DATADONE_EP0STATUS_Pos) /*!< Bit mask of EP0DATADONE_EP0STATUS field. */ +#define USBD_SHORTS_EP0DATADONE_EP0STATUS_Disabled (0UL) /*!< Disable shortcut */ +#define USBD_SHORTS_EP0DATADONE_EP0STATUS_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 1 : Shortcut between EP0DATADONE event and STARTEPOUT[0] task */ +#define USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Pos (1UL) /*!< Position of EP0DATADONE_STARTEPOUT0 field. */ +#define USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Msk (0x1UL << USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Pos) /*!< Bit mask of EP0DATADONE_STARTEPOUT0 field. */ +#define USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Disabled (0UL) /*!< Disable shortcut */ +#define USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Enabled (1UL) /*!< Enable shortcut */ + +/* Bit 0 : Shortcut between EP0DATADONE event and STARTEPIN[0] task */ +#define USBD_SHORTS_EP0DATADONE_STARTEPIN0_Pos (0UL) /*!< Position of EP0DATADONE_STARTEPIN0 field. */ +#define USBD_SHORTS_EP0DATADONE_STARTEPIN0_Msk (0x1UL << USBD_SHORTS_EP0DATADONE_STARTEPIN0_Pos) /*!< Bit mask of EP0DATADONE_STARTEPIN0 field. */ +#define USBD_SHORTS_EP0DATADONE_STARTEPIN0_Disabled (0UL) /*!< Disable shortcut */ +#define USBD_SHORTS_EP0DATADONE_STARTEPIN0_Enabled (1UL) /*!< Enable shortcut */ + +/* Register: USBD_INTEN */ +/* Description: Enable or disable interrupt */ + +/* Bit 25 : Enable or disable interrupt for ACCESSFAULT event */ +#define USBD_INTEN_ACCESSFAULT_Pos (25UL) /*!< Position of ACCESSFAULT field. */ +#define USBD_INTEN_ACCESSFAULT_Msk (0x1UL << USBD_INTEN_ACCESSFAULT_Pos) /*!< Bit mask of ACCESSFAULT field. */ +#define USBD_INTEN_ACCESSFAULT_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ACCESSFAULT_Enabled (1UL) /*!< Enable */ + +/* Bit 24 : Enable or disable interrupt for EPDATA event */ +#define USBD_INTEN_EPDATA_Pos (24UL) /*!< Position of EPDATA field. */ +#define USBD_INTEN_EPDATA_Msk (0x1UL << USBD_INTEN_EPDATA_Pos) /*!< Bit mask of EPDATA field. */ +#define USBD_INTEN_EPDATA_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_EPDATA_Enabled (1UL) /*!< Enable */ + +/* Bit 23 : Enable or disable interrupt for EP0SETUP event */ +#define USBD_INTEN_EP0SETUP_Pos (23UL) /*!< Position of EP0SETUP field. */ +#define USBD_INTEN_EP0SETUP_Msk (0x1UL << USBD_INTEN_EP0SETUP_Pos) /*!< Bit mask of EP0SETUP field. */ +#define USBD_INTEN_EP0SETUP_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_EP0SETUP_Enabled (1UL) /*!< Enable */ + +/* Bit 22 : Enable or disable interrupt for USBEVENT event */ +#define USBD_INTEN_USBEVENT_Pos (22UL) /*!< Position of USBEVENT field. */ +#define USBD_INTEN_USBEVENT_Msk (0x1UL << USBD_INTEN_USBEVENT_Pos) /*!< Bit mask of USBEVENT field. */ +#define USBD_INTEN_USBEVENT_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_USBEVENT_Enabled (1UL) /*!< Enable */ + +/* Bit 21 : Enable or disable interrupt for SOF event */ +#define USBD_INTEN_SOF_Pos (21UL) /*!< Position of SOF field. */ +#define USBD_INTEN_SOF_Msk (0x1UL << USBD_INTEN_SOF_Pos) /*!< Bit mask of SOF field. */ +#define USBD_INTEN_SOF_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_SOF_Enabled (1UL) /*!< Enable */ + +/* Bit 20 : Enable or disable interrupt for ENDISOOUT event */ +#define USBD_INTEN_ENDISOOUT_Pos (20UL) /*!< Position of ENDISOOUT field. */ +#define USBD_INTEN_ENDISOOUT_Msk (0x1UL << USBD_INTEN_ENDISOOUT_Pos) /*!< Bit mask of ENDISOOUT field. */ +#define USBD_INTEN_ENDISOOUT_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDISOOUT_Enabled (1UL) /*!< Enable */ + +/* Bit 19 : Enable or disable interrupt for ENDEPOUT[7] event */ +#define USBD_INTEN_ENDEPOUT7_Pos (19UL) /*!< Position of ENDEPOUT7 field. */ +#define USBD_INTEN_ENDEPOUT7_Msk (0x1UL << USBD_INTEN_ENDEPOUT7_Pos) /*!< Bit mask of ENDEPOUT7 field. */ +#define USBD_INTEN_ENDEPOUT7_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT7_Enabled (1UL) /*!< Enable */ + +/* Bit 18 : Enable or disable interrupt for ENDEPOUT[6] event */ +#define USBD_INTEN_ENDEPOUT6_Pos (18UL) /*!< Position of ENDEPOUT6 field. */ +#define USBD_INTEN_ENDEPOUT6_Msk (0x1UL << USBD_INTEN_ENDEPOUT6_Pos) /*!< Bit mask of ENDEPOUT6 field. */ +#define USBD_INTEN_ENDEPOUT6_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT6_Enabled (1UL) /*!< Enable */ + +/* Bit 17 : Enable or disable interrupt for ENDEPOUT[5] event */ +#define USBD_INTEN_ENDEPOUT5_Pos (17UL) /*!< Position of ENDEPOUT5 field. */ +#define USBD_INTEN_ENDEPOUT5_Msk (0x1UL << USBD_INTEN_ENDEPOUT5_Pos) /*!< Bit mask of ENDEPOUT5 field. */ +#define USBD_INTEN_ENDEPOUT5_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT5_Enabled (1UL) /*!< Enable */ + +/* Bit 16 : Enable or disable interrupt for ENDEPOUT[4] event */ +#define USBD_INTEN_ENDEPOUT4_Pos (16UL) /*!< Position of ENDEPOUT4 field. */ +#define USBD_INTEN_ENDEPOUT4_Msk (0x1UL << USBD_INTEN_ENDEPOUT4_Pos) /*!< Bit mask of ENDEPOUT4 field. */ +#define USBD_INTEN_ENDEPOUT4_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT4_Enabled (1UL) /*!< Enable */ + +/* Bit 15 : Enable or disable interrupt for ENDEPOUT[3] event */ +#define USBD_INTEN_ENDEPOUT3_Pos (15UL) /*!< Position of ENDEPOUT3 field. */ +#define USBD_INTEN_ENDEPOUT3_Msk (0x1UL << USBD_INTEN_ENDEPOUT3_Pos) /*!< Bit mask of ENDEPOUT3 field. */ +#define USBD_INTEN_ENDEPOUT3_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT3_Enabled (1UL) /*!< Enable */ + +/* Bit 14 : Enable or disable interrupt for ENDEPOUT[2] event */ +#define USBD_INTEN_ENDEPOUT2_Pos (14UL) /*!< Position of ENDEPOUT2 field. */ +#define USBD_INTEN_ENDEPOUT2_Msk (0x1UL << USBD_INTEN_ENDEPOUT2_Pos) /*!< Bit mask of ENDEPOUT2 field. */ +#define USBD_INTEN_ENDEPOUT2_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT2_Enabled (1UL) /*!< Enable */ + +/* Bit 13 : Enable or disable interrupt for ENDEPOUT[1] event */ +#define USBD_INTEN_ENDEPOUT1_Pos (13UL) /*!< Position of ENDEPOUT1 field. */ +#define USBD_INTEN_ENDEPOUT1_Msk (0x1UL << USBD_INTEN_ENDEPOUT1_Pos) /*!< Bit mask of ENDEPOUT1 field. */ +#define USBD_INTEN_ENDEPOUT1_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT1_Enabled (1UL) /*!< Enable */ + +/* Bit 12 : Enable or disable interrupt for ENDEPOUT[0] event */ +#define USBD_INTEN_ENDEPOUT0_Pos (12UL) /*!< Position of ENDEPOUT0 field. */ +#define USBD_INTEN_ENDEPOUT0_Msk (0x1UL << USBD_INTEN_ENDEPOUT0_Pos) /*!< Bit mask of ENDEPOUT0 field. */ +#define USBD_INTEN_ENDEPOUT0_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPOUT0_Enabled (1UL) /*!< Enable */ + +/* Bit 11 : Enable or disable interrupt for ENDISOIN event */ +#define USBD_INTEN_ENDISOIN_Pos (11UL) /*!< Position of ENDISOIN field. */ +#define USBD_INTEN_ENDISOIN_Msk (0x1UL << USBD_INTEN_ENDISOIN_Pos) /*!< Bit mask of ENDISOIN field. */ +#define USBD_INTEN_ENDISOIN_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDISOIN_Enabled (1UL) /*!< Enable */ + +/* Bit 10 : Enable or disable interrupt for EP0DATADONE event */ +#define USBD_INTEN_EP0DATADONE_Pos (10UL) /*!< Position of EP0DATADONE field. */ +#define USBD_INTEN_EP0DATADONE_Msk (0x1UL << USBD_INTEN_EP0DATADONE_Pos) /*!< Bit mask of EP0DATADONE field. */ +#define USBD_INTEN_EP0DATADONE_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_EP0DATADONE_Enabled (1UL) /*!< Enable */ + +/* Bit 9 : Enable or disable interrupt for ENDEPIN[7] event */ +#define USBD_INTEN_ENDEPIN7_Pos (9UL) /*!< Position of ENDEPIN7 field. */ +#define USBD_INTEN_ENDEPIN7_Msk (0x1UL << USBD_INTEN_ENDEPIN7_Pos) /*!< Bit mask of ENDEPIN7 field. */ +#define USBD_INTEN_ENDEPIN7_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN7_Enabled (1UL) /*!< Enable */ + +/* Bit 8 : Enable or disable interrupt for ENDEPIN[6] event */ +#define USBD_INTEN_ENDEPIN6_Pos (8UL) /*!< Position of ENDEPIN6 field. */ +#define USBD_INTEN_ENDEPIN6_Msk (0x1UL << USBD_INTEN_ENDEPIN6_Pos) /*!< Bit mask of ENDEPIN6 field. */ +#define USBD_INTEN_ENDEPIN6_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN6_Enabled (1UL) /*!< Enable */ + +/* Bit 7 : Enable or disable interrupt for ENDEPIN[5] event */ +#define USBD_INTEN_ENDEPIN5_Pos (7UL) /*!< Position of ENDEPIN5 field. */ +#define USBD_INTEN_ENDEPIN5_Msk (0x1UL << USBD_INTEN_ENDEPIN5_Pos) /*!< Bit mask of ENDEPIN5 field. */ +#define USBD_INTEN_ENDEPIN5_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN5_Enabled (1UL) /*!< Enable */ + +/* Bit 6 : Enable or disable interrupt for ENDEPIN[4] event */ +#define USBD_INTEN_ENDEPIN4_Pos (6UL) /*!< Position of ENDEPIN4 field. */ +#define USBD_INTEN_ENDEPIN4_Msk (0x1UL << USBD_INTEN_ENDEPIN4_Pos) /*!< Bit mask of ENDEPIN4 field. */ +#define USBD_INTEN_ENDEPIN4_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN4_Enabled (1UL) /*!< Enable */ + +/* Bit 5 : Enable or disable interrupt for ENDEPIN[3] event */ +#define USBD_INTEN_ENDEPIN3_Pos (5UL) /*!< Position of ENDEPIN3 field. */ +#define USBD_INTEN_ENDEPIN3_Msk (0x1UL << USBD_INTEN_ENDEPIN3_Pos) /*!< Bit mask of ENDEPIN3 field. */ +#define USBD_INTEN_ENDEPIN3_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN3_Enabled (1UL) /*!< Enable */ + +/* Bit 4 : Enable or disable interrupt for ENDEPIN[2] event */ +#define USBD_INTEN_ENDEPIN2_Pos (4UL) /*!< Position of ENDEPIN2 field. */ +#define USBD_INTEN_ENDEPIN2_Msk (0x1UL << USBD_INTEN_ENDEPIN2_Pos) /*!< Bit mask of ENDEPIN2 field. */ +#define USBD_INTEN_ENDEPIN2_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN2_Enabled (1UL) /*!< Enable */ + +/* Bit 3 : Enable or disable interrupt for ENDEPIN[1] event */ +#define USBD_INTEN_ENDEPIN1_Pos (3UL) /*!< Position of ENDEPIN1 field. */ +#define USBD_INTEN_ENDEPIN1_Msk (0x1UL << USBD_INTEN_ENDEPIN1_Pos) /*!< Bit mask of ENDEPIN1 field. */ +#define USBD_INTEN_ENDEPIN1_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN1_Enabled (1UL) /*!< Enable */ + +/* Bit 2 : Enable or disable interrupt for ENDEPIN[0] event */ +#define USBD_INTEN_ENDEPIN0_Pos (2UL) /*!< Position of ENDEPIN0 field. */ +#define USBD_INTEN_ENDEPIN0_Msk (0x1UL << USBD_INTEN_ENDEPIN0_Pos) /*!< Bit mask of ENDEPIN0 field. */ +#define USBD_INTEN_ENDEPIN0_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_ENDEPIN0_Enabled (1UL) /*!< Enable */ + +/* Bit 1 : Enable or disable interrupt for STARTED event */ +#define USBD_INTEN_STARTED_Pos (1UL) /*!< Position of STARTED field. */ +#define USBD_INTEN_STARTED_Msk (0x1UL << USBD_INTEN_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define USBD_INTEN_STARTED_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_STARTED_Enabled (1UL) /*!< Enable */ + +/* Bit 0 : Enable or disable interrupt for USBRESET event */ +#define USBD_INTEN_USBRESET_Pos (0UL) /*!< Position of USBRESET field. */ +#define USBD_INTEN_USBRESET_Msk (0x1UL << USBD_INTEN_USBRESET_Pos) /*!< Bit mask of USBRESET field. */ +#define USBD_INTEN_USBRESET_Disabled (0UL) /*!< Disable */ +#define USBD_INTEN_USBRESET_Enabled (1UL) /*!< Enable */ + +/* Register: USBD_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 25 : Write '1' to Enable interrupt for ACCESSFAULT event */ +#define USBD_INTENSET_ACCESSFAULT_Pos (25UL) /*!< Position of ACCESSFAULT field. */ +#define USBD_INTENSET_ACCESSFAULT_Msk (0x1UL << USBD_INTENSET_ACCESSFAULT_Pos) /*!< Bit mask of ACCESSFAULT field. */ +#define USBD_INTENSET_ACCESSFAULT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ACCESSFAULT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ACCESSFAULT_Set (1UL) /*!< Enable */ + +/* Bit 24 : Write '1' to Enable interrupt for EPDATA event */ +#define USBD_INTENSET_EPDATA_Pos (24UL) /*!< Position of EPDATA field. */ +#define USBD_INTENSET_EPDATA_Msk (0x1UL << USBD_INTENSET_EPDATA_Pos) /*!< Bit mask of EPDATA field. */ +#define USBD_INTENSET_EPDATA_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_EPDATA_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_EPDATA_Set (1UL) /*!< Enable */ + +/* Bit 23 : Write '1' to Enable interrupt for EP0SETUP event */ +#define USBD_INTENSET_EP0SETUP_Pos (23UL) /*!< Position of EP0SETUP field. */ +#define USBD_INTENSET_EP0SETUP_Msk (0x1UL << USBD_INTENSET_EP0SETUP_Pos) /*!< Bit mask of EP0SETUP field. */ +#define USBD_INTENSET_EP0SETUP_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_EP0SETUP_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_EP0SETUP_Set (1UL) /*!< Enable */ + +/* Bit 22 : Write '1' to Enable interrupt for USBEVENT event */ +#define USBD_INTENSET_USBEVENT_Pos (22UL) /*!< Position of USBEVENT field. */ +#define USBD_INTENSET_USBEVENT_Msk (0x1UL << USBD_INTENSET_USBEVENT_Pos) /*!< Bit mask of USBEVENT field. */ +#define USBD_INTENSET_USBEVENT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_USBEVENT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_USBEVENT_Set (1UL) /*!< Enable */ + +/* Bit 21 : Write '1' to Enable interrupt for SOF event */ +#define USBD_INTENSET_SOF_Pos (21UL) /*!< Position of SOF field. */ +#define USBD_INTENSET_SOF_Msk (0x1UL << USBD_INTENSET_SOF_Pos) /*!< Bit mask of SOF field. */ +#define USBD_INTENSET_SOF_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_SOF_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_SOF_Set (1UL) /*!< Enable */ + +/* Bit 20 : Write '1' to Enable interrupt for ENDISOOUT event */ +#define USBD_INTENSET_ENDISOOUT_Pos (20UL) /*!< Position of ENDISOOUT field. */ +#define USBD_INTENSET_ENDISOOUT_Msk (0x1UL << USBD_INTENSET_ENDISOOUT_Pos) /*!< Bit mask of ENDISOOUT field. */ +#define USBD_INTENSET_ENDISOOUT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDISOOUT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDISOOUT_Set (1UL) /*!< Enable */ + +/* Bit 19 : Write '1' to Enable interrupt for ENDEPOUT[7] event */ +#define USBD_INTENSET_ENDEPOUT7_Pos (19UL) /*!< Position of ENDEPOUT7 field. */ +#define USBD_INTENSET_ENDEPOUT7_Msk (0x1UL << USBD_INTENSET_ENDEPOUT7_Pos) /*!< Bit mask of ENDEPOUT7 field. */ +#define USBD_INTENSET_ENDEPOUT7_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT7_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT7_Set (1UL) /*!< Enable */ + +/* Bit 18 : Write '1' to Enable interrupt for ENDEPOUT[6] event */ +#define USBD_INTENSET_ENDEPOUT6_Pos (18UL) /*!< Position of ENDEPOUT6 field. */ +#define USBD_INTENSET_ENDEPOUT6_Msk (0x1UL << USBD_INTENSET_ENDEPOUT6_Pos) /*!< Bit mask of ENDEPOUT6 field. */ +#define USBD_INTENSET_ENDEPOUT6_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT6_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT6_Set (1UL) /*!< Enable */ + +/* Bit 17 : Write '1' to Enable interrupt for ENDEPOUT[5] event */ +#define USBD_INTENSET_ENDEPOUT5_Pos (17UL) /*!< Position of ENDEPOUT5 field. */ +#define USBD_INTENSET_ENDEPOUT5_Msk (0x1UL << USBD_INTENSET_ENDEPOUT5_Pos) /*!< Bit mask of ENDEPOUT5 field. */ +#define USBD_INTENSET_ENDEPOUT5_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT5_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT5_Set (1UL) /*!< Enable */ + +/* Bit 16 : Write '1' to Enable interrupt for ENDEPOUT[4] event */ +#define USBD_INTENSET_ENDEPOUT4_Pos (16UL) /*!< Position of ENDEPOUT4 field. */ +#define USBD_INTENSET_ENDEPOUT4_Msk (0x1UL << USBD_INTENSET_ENDEPOUT4_Pos) /*!< Bit mask of ENDEPOUT4 field. */ +#define USBD_INTENSET_ENDEPOUT4_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT4_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT4_Set (1UL) /*!< Enable */ + +/* Bit 15 : Write '1' to Enable interrupt for ENDEPOUT[3] event */ +#define USBD_INTENSET_ENDEPOUT3_Pos (15UL) /*!< Position of ENDEPOUT3 field. */ +#define USBD_INTENSET_ENDEPOUT3_Msk (0x1UL << USBD_INTENSET_ENDEPOUT3_Pos) /*!< Bit mask of ENDEPOUT3 field. */ +#define USBD_INTENSET_ENDEPOUT3_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT3_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT3_Set (1UL) /*!< Enable */ + +/* Bit 14 : Write '1' to Enable interrupt for ENDEPOUT[2] event */ +#define USBD_INTENSET_ENDEPOUT2_Pos (14UL) /*!< Position of ENDEPOUT2 field. */ +#define USBD_INTENSET_ENDEPOUT2_Msk (0x1UL << USBD_INTENSET_ENDEPOUT2_Pos) /*!< Bit mask of ENDEPOUT2 field. */ +#define USBD_INTENSET_ENDEPOUT2_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT2_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT2_Set (1UL) /*!< Enable */ + +/* Bit 13 : Write '1' to Enable interrupt for ENDEPOUT[1] event */ +#define USBD_INTENSET_ENDEPOUT1_Pos (13UL) /*!< Position of ENDEPOUT1 field. */ +#define USBD_INTENSET_ENDEPOUT1_Msk (0x1UL << USBD_INTENSET_ENDEPOUT1_Pos) /*!< Bit mask of ENDEPOUT1 field. */ +#define USBD_INTENSET_ENDEPOUT1_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT1_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT1_Set (1UL) /*!< Enable */ + +/* Bit 12 : Write '1' to Enable interrupt for ENDEPOUT[0] event */ +#define USBD_INTENSET_ENDEPOUT0_Pos (12UL) /*!< Position of ENDEPOUT0 field. */ +#define USBD_INTENSET_ENDEPOUT0_Msk (0x1UL << USBD_INTENSET_ENDEPOUT0_Pos) /*!< Bit mask of ENDEPOUT0 field. */ +#define USBD_INTENSET_ENDEPOUT0_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPOUT0_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPOUT0_Set (1UL) /*!< Enable */ + +/* Bit 11 : Write '1' to Enable interrupt for ENDISOIN event */ +#define USBD_INTENSET_ENDISOIN_Pos (11UL) /*!< Position of ENDISOIN field. */ +#define USBD_INTENSET_ENDISOIN_Msk (0x1UL << USBD_INTENSET_ENDISOIN_Pos) /*!< Bit mask of ENDISOIN field. */ +#define USBD_INTENSET_ENDISOIN_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDISOIN_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDISOIN_Set (1UL) /*!< Enable */ + +/* Bit 10 : Write '1' to Enable interrupt for EP0DATADONE event */ +#define USBD_INTENSET_EP0DATADONE_Pos (10UL) /*!< Position of EP0DATADONE field. */ +#define USBD_INTENSET_EP0DATADONE_Msk (0x1UL << USBD_INTENSET_EP0DATADONE_Pos) /*!< Bit mask of EP0DATADONE field. */ +#define USBD_INTENSET_EP0DATADONE_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_EP0DATADONE_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_EP0DATADONE_Set (1UL) /*!< Enable */ + +/* Bit 9 : Write '1' to Enable interrupt for ENDEPIN[7] event */ +#define USBD_INTENSET_ENDEPIN7_Pos (9UL) /*!< Position of ENDEPIN7 field. */ +#define USBD_INTENSET_ENDEPIN7_Msk (0x1UL << USBD_INTENSET_ENDEPIN7_Pos) /*!< Bit mask of ENDEPIN7 field. */ +#define USBD_INTENSET_ENDEPIN7_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN7_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN7_Set (1UL) /*!< Enable */ + +/* Bit 8 : Write '1' to Enable interrupt for ENDEPIN[6] event */ +#define USBD_INTENSET_ENDEPIN6_Pos (8UL) /*!< Position of ENDEPIN6 field. */ +#define USBD_INTENSET_ENDEPIN6_Msk (0x1UL << USBD_INTENSET_ENDEPIN6_Pos) /*!< Bit mask of ENDEPIN6 field. */ +#define USBD_INTENSET_ENDEPIN6_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN6_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN6_Set (1UL) /*!< Enable */ + +/* Bit 7 : Write '1' to Enable interrupt for ENDEPIN[5] event */ +#define USBD_INTENSET_ENDEPIN5_Pos (7UL) /*!< Position of ENDEPIN5 field. */ +#define USBD_INTENSET_ENDEPIN5_Msk (0x1UL << USBD_INTENSET_ENDEPIN5_Pos) /*!< Bit mask of ENDEPIN5 field. */ +#define USBD_INTENSET_ENDEPIN5_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN5_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN5_Set (1UL) /*!< Enable */ + +/* Bit 6 : Write '1' to Enable interrupt for ENDEPIN[4] event */ +#define USBD_INTENSET_ENDEPIN4_Pos (6UL) /*!< Position of ENDEPIN4 field. */ +#define USBD_INTENSET_ENDEPIN4_Msk (0x1UL << USBD_INTENSET_ENDEPIN4_Pos) /*!< Bit mask of ENDEPIN4 field. */ +#define USBD_INTENSET_ENDEPIN4_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN4_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN4_Set (1UL) /*!< Enable */ + +/* Bit 5 : Write '1' to Enable interrupt for ENDEPIN[3] event */ +#define USBD_INTENSET_ENDEPIN3_Pos (5UL) /*!< Position of ENDEPIN3 field. */ +#define USBD_INTENSET_ENDEPIN3_Msk (0x1UL << USBD_INTENSET_ENDEPIN3_Pos) /*!< Bit mask of ENDEPIN3 field. */ +#define USBD_INTENSET_ENDEPIN3_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN3_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN3_Set (1UL) /*!< Enable */ + +/* Bit 4 : Write '1' to Enable interrupt for ENDEPIN[2] event */ +#define USBD_INTENSET_ENDEPIN2_Pos (4UL) /*!< Position of ENDEPIN2 field. */ +#define USBD_INTENSET_ENDEPIN2_Msk (0x1UL << USBD_INTENSET_ENDEPIN2_Pos) /*!< Bit mask of ENDEPIN2 field. */ +#define USBD_INTENSET_ENDEPIN2_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN2_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN2_Set (1UL) /*!< Enable */ + +/* Bit 3 : Write '1' to Enable interrupt for ENDEPIN[1] event */ +#define USBD_INTENSET_ENDEPIN1_Pos (3UL) /*!< Position of ENDEPIN1 field. */ +#define USBD_INTENSET_ENDEPIN1_Msk (0x1UL << USBD_INTENSET_ENDEPIN1_Pos) /*!< Bit mask of ENDEPIN1 field. */ +#define USBD_INTENSET_ENDEPIN1_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN1_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN1_Set (1UL) /*!< Enable */ + +/* Bit 2 : Write '1' to Enable interrupt for ENDEPIN[0] event */ +#define USBD_INTENSET_ENDEPIN0_Pos (2UL) /*!< Position of ENDEPIN0 field. */ +#define USBD_INTENSET_ENDEPIN0_Msk (0x1UL << USBD_INTENSET_ENDEPIN0_Pos) /*!< Bit mask of ENDEPIN0 field. */ +#define USBD_INTENSET_ENDEPIN0_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_ENDEPIN0_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_ENDEPIN0_Set (1UL) /*!< Enable */ + +/* Bit 1 : Write '1' to Enable interrupt for STARTED event */ +#define USBD_INTENSET_STARTED_Pos (1UL) /*!< Position of STARTED field. */ +#define USBD_INTENSET_STARTED_Msk (0x1UL << USBD_INTENSET_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define USBD_INTENSET_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_STARTED_Set (1UL) /*!< Enable */ + +/* Bit 0 : Write '1' to Enable interrupt for USBRESET event */ +#define USBD_INTENSET_USBRESET_Pos (0UL) /*!< Position of USBRESET field. */ +#define USBD_INTENSET_USBRESET_Msk (0x1UL << USBD_INTENSET_USBRESET_Pos) /*!< Bit mask of USBRESET field. */ +#define USBD_INTENSET_USBRESET_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENSET_USBRESET_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENSET_USBRESET_Set (1UL) /*!< Enable */ + +/* Register: USBD_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 25 : Write '1' to Disable interrupt for ACCESSFAULT event */ +#define USBD_INTENCLR_ACCESSFAULT_Pos (25UL) /*!< Position of ACCESSFAULT field. */ +#define USBD_INTENCLR_ACCESSFAULT_Msk (0x1UL << USBD_INTENCLR_ACCESSFAULT_Pos) /*!< Bit mask of ACCESSFAULT field. */ +#define USBD_INTENCLR_ACCESSFAULT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ACCESSFAULT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ACCESSFAULT_Clear (1UL) /*!< Disable */ + +/* Bit 24 : Write '1' to Disable interrupt for EPDATA event */ +#define USBD_INTENCLR_EPDATA_Pos (24UL) /*!< Position of EPDATA field. */ +#define USBD_INTENCLR_EPDATA_Msk (0x1UL << USBD_INTENCLR_EPDATA_Pos) /*!< Bit mask of EPDATA field. */ +#define USBD_INTENCLR_EPDATA_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_EPDATA_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_EPDATA_Clear (1UL) /*!< Disable */ + +/* Bit 23 : Write '1' to Disable interrupt for EP0SETUP event */ +#define USBD_INTENCLR_EP0SETUP_Pos (23UL) /*!< Position of EP0SETUP field. */ +#define USBD_INTENCLR_EP0SETUP_Msk (0x1UL << USBD_INTENCLR_EP0SETUP_Pos) /*!< Bit mask of EP0SETUP field. */ +#define USBD_INTENCLR_EP0SETUP_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_EP0SETUP_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_EP0SETUP_Clear (1UL) /*!< Disable */ + +/* Bit 22 : Write '1' to Disable interrupt for USBEVENT event */ +#define USBD_INTENCLR_USBEVENT_Pos (22UL) /*!< Position of USBEVENT field. */ +#define USBD_INTENCLR_USBEVENT_Msk (0x1UL << USBD_INTENCLR_USBEVENT_Pos) /*!< Bit mask of USBEVENT field. */ +#define USBD_INTENCLR_USBEVENT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_USBEVENT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_USBEVENT_Clear (1UL) /*!< Disable */ + +/* Bit 21 : Write '1' to Disable interrupt for SOF event */ +#define USBD_INTENCLR_SOF_Pos (21UL) /*!< Position of SOF field. */ +#define USBD_INTENCLR_SOF_Msk (0x1UL << USBD_INTENCLR_SOF_Pos) /*!< Bit mask of SOF field. */ +#define USBD_INTENCLR_SOF_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_SOF_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_SOF_Clear (1UL) /*!< Disable */ + +/* Bit 20 : Write '1' to Disable interrupt for ENDISOOUT event */ +#define USBD_INTENCLR_ENDISOOUT_Pos (20UL) /*!< Position of ENDISOOUT field. */ +#define USBD_INTENCLR_ENDISOOUT_Msk (0x1UL << USBD_INTENCLR_ENDISOOUT_Pos) /*!< Bit mask of ENDISOOUT field. */ +#define USBD_INTENCLR_ENDISOOUT_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDISOOUT_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDISOOUT_Clear (1UL) /*!< Disable */ + +/* Bit 19 : Write '1' to Disable interrupt for ENDEPOUT[7] event */ +#define USBD_INTENCLR_ENDEPOUT7_Pos (19UL) /*!< Position of ENDEPOUT7 field. */ +#define USBD_INTENCLR_ENDEPOUT7_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT7_Pos) /*!< Bit mask of ENDEPOUT7 field. */ +#define USBD_INTENCLR_ENDEPOUT7_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT7_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT7_Clear (1UL) /*!< Disable */ + +/* Bit 18 : Write '1' to Disable interrupt for ENDEPOUT[6] event */ +#define USBD_INTENCLR_ENDEPOUT6_Pos (18UL) /*!< Position of ENDEPOUT6 field. */ +#define USBD_INTENCLR_ENDEPOUT6_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT6_Pos) /*!< Bit mask of ENDEPOUT6 field. */ +#define USBD_INTENCLR_ENDEPOUT6_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT6_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT6_Clear (1UL) /*!< Disable */ + +/* Bit 17 : Write '1' to Disable interrupt for ENDEPOUT[5] event */ +#define USBD_INTENCLR_ENDEPOUT5_Pos (17UL) /*!< Position of ENDEPOUT5 field. */ +#define USBD_INTENCLR_ENDEPOUT5_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT5_Pos) /*!< Bit mask of ENDEPOUT5 field. */ +#define USBD_INTENCLR_ENDEPOUT5_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT5_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT5_Clear (1UL) /*!< Disable */ + +/* Bit 16 : Write '1' to Disable interrupt for ENDEPOUT[4] event */ +#define USBD_INTENCLR_ENDEPOUT4_Pos (16UL) /*!< Position of ENDEPOUT4 field. */ +#define USBD_INTENCLR_ENDEPOUT4_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT4_Pos) /*!< Bit mask of ENDEPOUT4 field. */ +#define USBD_INTENCLR_ENDEPOUT4_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT4_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT4_Clear (1UL) /*!< Disable */ + +/* Bit 15 : Write '1' to Disable interrupt for ENDEPOUT[3] event */ +#define USBD_INTENCLR_ENDEPOUT3_Pos (15UL) /*!< Position of ENDEPOUT3 field. */ +#define USBD_INTENCLR_ENDEPOUT3_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT3_Pos) /*!< Bit mask of ENDEPOUT3 field. */ +#define USBD_INTENCLR_ENDEPOUT3_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT3_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT3_Clear (1UL) /*!< Disable */ + +/* Bit 14 : Write '1' to Disable interrupt for ENDEPOUT[2] event */ +#define USBD_INTENCLR_ENDEPOUT2_Pos (14UL) /*!< Position of ENDEPOUT2 field. */ +#define USBD_INTENCLR_ENDEPOUT2_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT2_Pos) /*!< Bit mask of ENDEPOUT2 field. */ +#define USBD_INTENCLR_ENDEPOUT2_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT2_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT2_Clear (1UL) /*!< Disable */ + +/* Bit 13 : Write '1' to Disable interrupt for ENDEPOUT[1] event */ +#define USBD_INTENCLR_ENDEPOUT1_Pos (13UL) /*!< Position of ENDEPOUT1 field. */ +#define USBD_INTENCLR_ENDEPOUT1_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT1_Pos) /*!< Bit mask of ENDEPOUT1 field. */ +#define USBD_INTENCLR_ENDEPOUT1_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT1_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT1_Clear (1UL) /*!< Disable */ + +/* Bit 12 : Write '1' to Disable interrupt for ENDEPOUT[0] event */ +#define USBD_INTENCLR_ENDEPOUT0_Pos (12UL) /*!< Position of ENDEPOUT0 field. */ +#define USBD_INTENCLR_ENDEPOUT0_Msk (0x1UL << USBD_INTENCLR_ENDEPOUT0_Pos) /*!< Bit mask of ENDEPOUT0 field. */ +#define USBD_INTENCLR_ENDEPOUT0_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPOUT0_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPOUT0_Clear (1UL) /*!< Disable */ + +/* Bit 11 : Write '1' to Disable interrupt for ENDISOIN event */ +#define USBD_INTENCLR_ENDISOIN_Pos (11UL) /*!< Position of ENDISOIN field. */ +#define USBD_INTENCLR_ENDISOIN_Msk (0x1UL << USBD_INTENCLR_ENDISOIN_Pos) /*!< Bit mask of ENDISOIN field. */ +#define USBD_INTENCLR_ENDISOIN_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDISOIN_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDISOIN_Clear (1UL) /*!< Disable */ + +/* Bit 10 : Write '1' to Disable interrupt for EP0DATADONE event */ +#define USBD_INTENCLR_EP0DATADONE_Pos (10UL) /*!< Position of EP0DATADONE field. */ +#define USBD_INTENCLR_EP0DATADONE_Msk (0x1UL << USBD_INTENCLR_EP0DATADONE_Pos) /*!< Bit mask of EP0DATADONE field. */ +#define USBD_INTENCLR_EP0DATADONE_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_EP0DATADONE_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_EP0DATADONE_Clear (1UL) /*!< Disable */ + +/* Bit 9 : Write '1' to Disable interrupt for ENDEPIN[7] event */ +#define USBD_INTENCLR_ENDEPIN7_Pos (9UL) /*!< Position of ENDEPIN7 field. */ +#define USBD_INTENCLR_ENDEPIN7_Msk (0x1UL << USBD_INTENCLR_ENDEPIN7_Pos) /*!< Bit mask of ENDEPIN7 field. */ +#define USBD_INTENCLR_ENDEPIN7_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN7_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN7_Clear (1UL) /*!< Disable */ + +/* Bit 8 : Write '1' to Disable interrupt for ENDEPIN[6] event */ +#define USBD_INTENCLR_ENDEPIN6_Pos (8UL) /*!< Position of ENDEPIN6 field. */ +#define USBD_INTENCLR_ENDEPIN6_Msk (0x1UL << USBD_INTENCLR_ENDEPIN6_Pos) /*!< Bit mask of ENDEPIN6 field. */ +#define USBD_INTENCLR_ENDEPIN6_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN6_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN6_Clear (1UL) /*!< Disable */ + +/* Bit 7 : Write '1' to Disable interrupt for ENDEPIN[5] event */ +#define USBD_INTENCLR_ENDEPIN5_Pos (7UL) /*!< Position of ENDEPIN5 field. */ +#define USBD_INTENCLR_ENDEPIN5_Msk (0x1UL << USBD_INTENCLR_ENDEPIN5_Pos) /*!< Bit mask of ENDEPIN5 field. */ +#define USBD_INTENCLR_ENDEPIN5_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN5_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN5_Clear (1UL) /*!< Disable */ + +/* Bit 6 : Write '1' to Disable interrupt for ENDEPIN[4] event */ +#define USBD_INTENCLR_ENDEPIN4_Pos (6UL) /*!< Position of ENDEPIN4 field. */ +#define USBD_INTENCLR_ENDEPIN4_Msk (0x1UL << USBD_INTENCLR_ENDEPIN4_Pos) /*!< Bit mask of ENDEPIN4 field. */ +#define USBD_INTENCLR_ENDEPIN4_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN4_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN4_Clear (1UL) /*!< Disable */ + +/* Bit 5 : Write '1' to Disable interrupt for ENDEPIN[3] event */ +#define USBD_INTENCLR_ENDEPIN3_Pos (5UL) /*!< Position of ENDEPIN3 field. */ +#define USBD_INTENCLR_ENDEPIN3_Msk (0x1UL << USBD_INTENCLR_ENDEPIN3_Pos) /*!< Bit mask of ENDEPIN3 field. */ +#define USBD_INTENCLR_ENDEPIN3_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN3_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN3_Clear (1UL) /*!< Disable */ + +/* Bit 4 : Write '1' to Disable interrupt for ENDEPIN[2] event */ +#define USBD_INTENCLR_ENDEPIN2_Pos (4UL) /*!< Position of ENDEPIN2 field. */ +#define USBD_INTENCLR_ENDEPIN2_Msk (0x1UL << USBD_INTENCLR_ENDEPIN2_Pos) /*!< Bit mask of ENDEPIN2 field. */ +#define USBD_INTENCLR_ENDEPIN2_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN2_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN2_Clear (1UL) /*!< Disable */ + +/* Bit 3 : Write '1' to Disable interrupt for ENDEPIN[1] event */ +#define USBD_INTENCLR_ENDEPIN1_Pos (3UL) /*!< Position of ENDEPIN1 field. */ +#define USBD_INTENCLR_ENDEPIN1_Msk (0x1UL << USBD_INTENCLR_ENDEPIN1_Pos) /*!< Bit mask of ENDEPIN1 field. */ +#define USBD_INTENCLR_ENDEPIN1_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN1_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN1_Clear (1UL) /*!< Disable */ + +/* Bit 2 : Write '1' to Disable interrupt for ENDEPIN[0] event */ +#define USBD_INTENCLR_ENDEPIN0_Pos (2UL) /*!< Position of ENDEPIN0 field. */ +#define USBD_INTENCLR_ENDEPIN0_Msk (0x1UL << USBD_INTENCLR_ENDEPIN0_Pos) /*!< Bit mask of ENDEPIN0 field. */ +#define USBD_INTENCLR_ENDEPIN0_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_ENDEPIN0_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_ENDEPIN0_Clear (1UL) /*!< Disable */ + +/* Bit 1 : Write '1' to Disable interrupt for STARTED event */ +#define USBD_INTENCLR_STARTED_Pos (1UL) /*!< Position of STARTED field. */ +#define USBD_INTENCLR_STARTED_Msk (0x1UL << USBD_INTENCLR_STARTED_Pos) /*!< Bit mask of STARTED field. */ +#define USBD_INTENCLR_STARTED_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_STARTED_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_STARTED_Clear (1UL) /*!< Disable */ + +/* Bit 0 : Write '1' to Disable interrupt for USBRESET event */ +#define USBD_INTENCLR_USBRESET_Pos (0UL) /*!< Position of USBRESET field. */ +#define USBD_INTENCLR_USBRESET_Msk (0x1UL << USBD_INTENCLR_USBRESET_Pos) /*!< Bit mask of USBRESET field. */ +#define USBD_INTENCLR_USBRESET_Disabled (0UL) /*!< Read: Disabled */ +#define USBD_INTENCLR_USBRESET_Enabled (1UL) /*!< Read: Enabled */ +#define USBD_INTENCLR_USBRESET_Clear (1UL) /*!< Disable */ + +/* Register: USBD_EVENTCAUSE */ +/* Description: Details on event that caused the USBEVENT event */ + +/* Bit 11 : Wrapper has re-initialized SFRs to the proper values. MAC is ready for normal operation. Write '1' to clear. */ +#define USBD_EVENTCAUSE_READY_Pos (11UL) /*!< Position of READY field. */ +#define USBD_EVENTCAUSE_READY_Msk (0x1UL << USBD_EVENTCAUSE_READY_Pos) /*!< Bit mask of READY field. */ +#define USBD_EVENTCAUSE_READY_NotDetected (0UL) /*!< USBEVENT was not issued due to USBD peripheral ready */ +#define USBD_EVENTCAUSE_READY_Ready (1UL) /*!< USBD peripheral is ready */ + +/* Bit 9 : Signals that a RESUME condition (K state or activity restart) has been detected on the USB lines. Write '1' to clear. */ +#define USBD_EVENTCAUSE_RESUME_Pos (9UL) /*!< Position of RESUME field. */ +#define USBD_EVENTCAUSE_RESUME_Msk (0x1UL << USBD_EVENTCAUSE_RESUME_Pos) /*!< Bit mask of RESUME field. */ +#define USBD_EVENTCAUSE_RESUME_NotDetected (0UL) /*!< Resume not detected */ +#define USBD_EVENTCAUSE_RESUME_Detected (1UL) /*!< Resume detected */ + +/* Bit 8 : Signals that the USB lines have been seen idle long enough for the device to enter suspend. Write '1' to clear. */ +#define USBD_EVENTCAUSE_SUSPEND_Pos (8UL) /*!< Position of SUSPEND field. */ +#define USBD_EVENTCAUSE_SUSPEND_Msk (0x1UL << USBD_EVENTCAUSE_SUSPEND_Pos) /*!< Bit mask of SUSPEND field. */ +#define USBD_EVENTCAUSE_SUSPEND_NotDetected (0UL) /*!< Suspend not detected */ +#define USBD_EVENTCAUSE_SUSPEND_Detected (1UL) /*!< Suspend detected */ + +/* Bit 0 : CRC error was detected on isochronous OUT endpoint 8. Write '1' to clear. */ +#define USBD_EVENTCAUSE_ISOOUTCRC_Pos (0UL) /*!< Position of ISOOUTCRC field. */ +#define USBD_EVENTCAUSE_ISOOUTCRC_Msk (0x1UL << USBD_EVENTCAUSE_ISOOUTCRC_Pos) /*!< Bit mask of ISOOUTCRC field. */ +#define USBD_EVENTCAUSE_ISOOUTCRC_NotDetected (0UL) /*!< No error detected */ +#define USBD_EVENTCAUSE_ISOOUTCRC_Detected (1UL) /*!< Error detected */ + +/* Register: USBD_BUSSTATE */ +/* Description: Provides the logic state of the D+ and D- lines */ + +/* Bit 1 : State of the D+ line */ +#define USBD_BUSSTATE_DP_Pos (1UL) /*!< Position of DP field. */ +#define USBD_BUSSTATE_DP_Msk (0x1UL << USBD_BUSSTATE_DP_Pos) /*!< Bit mask of DP field. */ +#define USBD_BUSSTATE_DP_Low (0UL) /*!< Low */ +#define USBD_BUSSTATE_DP_High (1UL) /*!< High */ + +/* Bit 0 : State of the D- line */ +#define USBD_BUSSTATE_DM_Pos (0UL) /*!< Position of DM field. */ +#define USBD_BUSSTATE_DM_Msk (0x1UL << USBD_BUSSTATE_DM_Pos) /*!< Bit mask of DM field. */ +#define USBD_BUSSTATE_DM_Low (0UL) /*!< Low */ +#define USBD_BUSSTATE_DM_High (1UL) /*!< High */ + +/* Register: USBD_HALTED_EPIN */ +/* Description: Description collection[0]: IN endpoint halted status. Can be used as is as response to a GetStatus() request to endpoint. */ + +/* Bits 15..0 : IN endpoint halted status. Can be used as is as response to a GetStatus() request to endpoint. */ +#define USBD_HALTED_EPIN_GETSTATUS_Pos (0UL) /*!< Position of GETSTATUS field. */ +#define USBD_HALTED_EPIN_GETSTATUS_Msk (0xFFFFUL << USBD_HALTED_EPIN_GETSTATUS_Pos) /*!< Bit mask of GETSTATUS field. */ +#define USBD_HALTED_EPIN_GETSTATUS_NotHalted (0UL) /*!< Endpoint is not halted */ +#define USBD_HALTED_EPIN_GETSTATUS_Halted (1UL) /*!< Endpoint is halted */ + +/* Register: USBD_HALTED_EPOUT */ +/* Description: Description collection[0]: OUT endpoint halted status. Can be used as is as response to a GetStatus() request to endpoint. */ + +/* Bits 15..0 : OUT endpoint halted status. Can be used as is as response to a GetStatus() request to endpoint. */ +#define USBD_HALTED_EPOUT_GETSTATUS_Pos (0UL) /*!< Position of GETSTATUS field. */ +#define USBD_HALTED_EPOUT_GETSTATUS_Msk (0xFFFFUL << USBD_HALTED_EPOUT_GETSTATUS_Pos) /*!< Bit mask of GETSTATUS field. */ +#define USBD_HALTED_EPOUT_GETSTATUS_NotHalted (0UL) /*!< Endpoint is not halted */ +#define USBD_HALTED_EPOUT_GETSTATUS_Halted (1UL) /*!< Endpoint is halted */ + +/* Register: USBD_EPSTATUS */ +/* Description: Provides information on which endpoint's EasyDMA registers have been captured */ + +/* Bit 24 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT8_Pos (24UL) /*!< Position of EPOUT8 field. */ +#define USBD_EPSTATUS_EPOUT8_Msk (0x1UL << USBD_EPSTATUS_EPOUT8_Pos) /*!< Bit mask of EPOUT8 field. */ +#define USBD_EPSTATUS_EPOUT8_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT8_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 23 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT7_Pos (23UL) /*!< Position of EPOUT7 field. */ +#define USBD_EPSTATUS_EPOUT7_Msk (0x1UL << USBD_EPSTATUS_EPOUT7_Pos) /*!< Bit mask of EPOUT7 field. */ +#define USBD_EPSTATUS_EPOUT7_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT7_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 22 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT6_Pos (22UL) /*!< Position of EPOUT6 field. */ +#define USBD_EPSTATUS_EPOUT6_Msk (0x1UL << USBD_EPSTATUS_EPOUT6_Pos) /*!< Bit mask of EPOUT6 field. */ +#define USBD_EPSTATUS_EPOUT6_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT6_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 21 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT5_Pos (21UL) /*!< Position of EPOUT5 field. */ +#define USBD_EPSTATUS_EPOUT5_Msk (0x1UL << USBD_EPSTATUS_EPOUT5_Pos) /*!< Bit mask of EPOUT5 field. */ +#define USBD_EPSTATUS_EPOUT5_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT5_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 20 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT4_Pos (20UL) /*!< Position of EPOUT4 field. */ +#define USBD_EPSTATUS_EPOUT4_Msk (0x1UL << USBD_EPSTATUS_EPOUT4_Pos) /*!< Bit mask of EPOUT4 field. */ +#define USBD_EPSTATUS_EPOUT4_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT4_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 19 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT3_Pos (19UL) /*!< Position of EPOUT3 field. */ +#define USBD_EPSTATUS_EPOUT3_Msk (0x1UL << USBD_EPSTATUS_EPOUT3_Pos) /*!< Bit mask of EPOUT3 field. */ +#define USBD_EPSTATUS_EPOUT3_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT3_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 18 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT2_Pos (18UL) /*!< Position of EPOUT2 field. */ +#define USBD_EPSTATUS_EPOUT2_Msk (0x1UL << USBD_EPSTATUS_EPOUT2_Pos) /*!< Bit mask of EPOUT2 field. */ +#define USBD_EPSTATUS_EPOUT2_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT2_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 17 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT1_Pos (17UL) /*!< Position of EPOUT1 field. */ +#define USBD_EPSTATUS_EPOUT1_Msk (0x1UL << USBD_EPSTATUS_EPOUT1_Pos) /*!< Bit mask of EPOUT1 field. */ +#define USBD_EPSTATUS_EPOUT1_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT1_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 16 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPOUT0_Pos (16UL) /*!< Position of EPOUT0 field. */ +#define USBD_EPSTATUS_EPOUT0_Msk (0x1UL << USBD_EPSTATUS_EPOUT0_Pos) /*!< Bit mask of EPOUT0 field. */ +#define USBD_EPSTATUS_EPOUT0_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPOUT0_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 8 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN8_Pos (8UL) /*!< Position of EPIN8 field. */ +#define USBD_EPSTATUS_EPIN8_Msk (0x1UL << USBD_EPSTATUS_EPIN8_Pos) /*!< Bit mask of EPIN8 field. */ +#define USBD_EPSTATUS_EPIN8_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN8_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 7 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN7_Pos (7UL) /*!< Position of EPIN7 field. */ +#define USBD_EPSTATUS_EPIN7_Msk (0x1UL << USBD_EPSTATUS_EPIN7_Pos) /*!< Bit mask of EPIN7 field. */ +#define USBD_EPSTATUS_EPIN7_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN7_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 6 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN6_Pos (6UL) /*!< Position of EPIN6 field. */ +#define USBD_EPSTATUS_EPIN6_Msk (0x1UL << USBD_EPSTATUS_EPIN6_Pos) /*!< Bit mask of EPIN6 field. */ +#define USBD_EPSTATUS_EPIN6_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN6_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 5 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN5_Pos (5UL) /*!< Position of EPIN5 field. */ +#define USBD_EPSTATUS_EPIN5_Msk (0x1UL << USBD_EPSTATUS_EPIN5_Pos) /*!< Bit mask of EPIN5 field. */ +#define USBD_EPSTATUS_EPIN5_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN5_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 4 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN4_Pos (4UL) /*!< Position of EPIN4 field. */ +#define USBD_EPSTATUS_EPIN4_Msk (0x1UL << USBD_EPSTATUS_EPIN4_Pos) /*!< Bit mask of EPIN4 field. */ +#define USBD_EPSTATUS_EPIN4_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN4_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 3 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN3_Pos (3UL) /*!< Position of EPIN3 field. */ +#define USBD_EPSTATUS_EPIN3_Msk (0x1UL << USBD_EPSTATUS_EPIN3_Pos) /*!< Bit mask of EPIN3 field. */ +#define USBD_EPSTATUS_EPIN3_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN3_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 2 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN2_Pos (2UL) /*!< Position of EPIN2 field. */ +#define USBD_EPSTATUS_EPIN2_Msk (0x1UL << USBD_EPSTATUS_EPIN2_Pos) /*!< Bit mask of EPIN2 field. */ +#define USBD_EPSTATUS_EPIN2_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN2_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 1 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN1_Pos (1UL) /*!< Position of EPIN1 field. */ +#define USBD_EPSTATUS_EPIN1_Msk (0x1UL << USBD_EPSTATUS_EPIN1_Pos) /*!< Bit mask of EPIN1 field. */ +#define USBD_EPSTATUS_EPIN1_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN1_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Bit 0 : Endpoint's EasyDMA registers captured state. Write '1' to clear. */ +#define USBD_EPSTATUS_EPIN0_Pos (0UL) /*!< Position of EPIN0 field. */ +#define USBD_EPSTATUS_EPIN0_Msk (0x1UL << USBD_EPSTATUS_EPIN0_Pos) /*!< Bit mask of EPIN0 field. */ +#define USBD_EPSTATUS_EPIN0_NoData (0UL) /*!< EasyDMA registers have not been captured for this endpoint */ +#define USBD_EPSTATUS_EPIN0_DataDone (1UL) /*!< EasyDMA registers have been captured for this endpoint */ + +/* Register: USBD_EPDATASTATUS */ +/* Description: Provides information on which endpoint(s) an acknowledged data transfer has occurred (EPDATA event) */ + +/* Bit 23 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT7_Pos (23UL) /*!< Position of EPOUT7 field. */ +#define USBD_EPDATASTATUS_EPOUT7_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT7_Pos) /*!< Bit mask of EPOUT7 field. */ +#define USBD_EPDATASTATUS_EPOUT7_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT7_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 22 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT6_Pos (22UL) /*!< Position of EPOUT6 field. */ +#define USBD_EPDATASTATUS_EPOUT6_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT6_Pos) /*!< Bit mask of EPOUT6 field. */ +#define USBD_EPDATASTATUS_EPOUT6_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT6_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 21 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT5_Pos (21UL) /*!< Position of EPOUT5 field. */ +#define USBD_EPDATASTATUS_EPOUT5_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT5_Pos) /*!< Bit mask of EPOUT5 field. */ +#define USBD_EPDATASTATUS_EPOUT5_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT5_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 20 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT4_Pos (20UL) /*!< Position of EPOUT4 field. */ +#define USBD_EPDATASTATUS_EPOUT4_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT4_Pos) /*!< Bit mask of EPOUT4 field. */ +#define USBD_EPDATASTATUS_EPOUT4_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT4_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 19 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT3_Pos (19UL) /*!< Position of EPOUT3 field. */ +#define USBD_EPDATASTATUS_EPOUT3_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT3_Pos) /*!< Bit mask of EPOUT3 field. */ +#define USBD_EPDATASTATUS_EPOUT3_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT3_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 18 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT2_Pos (18UL) /*!< Position of EPOUT2 field. */ +#define USBD_EPDATASTATUS_EPOUT2_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT2_Pos) /*!< Bit mask of EPOUT2 field. */ +#define USBD_EPDATASTATUS_EPOUT2_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT2_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 17 : Acknowledged data transfer on this OUT endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPOUT1_Pos (17UL) /*!< Position of EPOUT1 field. */ +#define USBD_EPDATASTATUS_EPOUT1_Msk (0x1UL << USBD_EPDATASTATUS_EPOUT1_Pos) /*!< Bit mask of EPOUT1 field. */ +#define USBD_EPDATASTATUS_EPOUT1_NotStarted (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPOUT1_Started (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 7 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN7_Pos (7UL) /*!< Position of EPIN7 field. */ +#define USBD_EPDATASTATUS_EPIN7_Msk (0x1UL << USBD_EPDATASTATUS_EPIN7_Pos) /*!< Bit mask of EPIN7 field. */ +#define USBD_EPDATASTATUS_EPIN7_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN7_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 6 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN6_Pos (6UL) /*!< Position of EPIN6 field. */ +#define USBD_EPDATASTATUS_EPIN6_Msk (0x1UL << USBD_EPDATASTATUS_EPIN6_Pos) /*!< Bit mask of EPIN6 field. */ +#define USBD_EPDATASTATUS_EPIN6_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN6_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 5 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN5_Pos (5UL) /*!< Position of EPIN5 field. */ +#define USBD_EPDATASTATUS_EPIN5_Msk (0x1UL << USBD_EPDATASTATUS_EPIN5_Pos) /*!< Bit mask of EPIN5 field. */ +#define USBD_EPDATASTATUS_EPIN5_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN5_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 4 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN4_Pos (4UL) /*!< Position of EPIN4 field. */ +#define USBD_EPDATASTATUS_EPIN4_Msk (0x1UL << USBD_EPDATASTATUS_EPIN4_Pos) /*!< Bit mask of EPIN4 field. */ +#define USBD_EPDATASTATUS_EPIN4_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN4_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 3 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN3_Pos (3UL) /*!< Position of EPIN3 field. */ +#define USBD_EPDATASTATUS_EPIN3_Msk (0x1UL << USBD_EPDATASTATUS_EPIN3_Pos) /*!< Bit mask of EPIN3 field. */ +#define USBD_EPDATASTATUS_EPIN3_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN3_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 2 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN2_Pos (2UL) /*!< Position of EPIN2 field. */ +#define USBD_EPDATASTATUS_EPIN2_Msk (0x1UL << USBD_EPDATASTATUS_EPIN2_Pos) /*!< Bit mask of EPIN2 field. */ +#define USBD_EPDATASTATUS_EPIN2_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN2_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Bit 1 : Acknowledged data transfer on this IN endpoint. Write '1' to clear. */ +#define USBD_EPDATASTATUS_EPIN1_Pos (1UL) /*!< Position of EPIN1 field. */ +#define USBD_EPDATASTATUS_EPIN1_Msk (0x1UL << USBD_EPDATASTATUS_EPIN1_Pos) /*!< Bit mask of EPIN1 field. */ +#define USBD_EPDATASTATUS_EPIN1_NotDone (0UL) /*!< No acknowledged data transfer on this endpoint */ +#define USBD_EPDATASTATUS_EPIN1_DataDone (1UL) /*!< Acknowledged data transfer on this endpoint has occurred */ + +/* Register: USBD_USBADDR */ +/* Description: Device USB address */ + +/* Bits 6..0 : Device USB address */ +#define USBD_USBADDR_ADDR_Pos (0UL) /*!< Position of ADDR field. */ +#define USBD_USBADDR_ADDR_Msk (0x7FUL << USBD_USBADDR_ADDR_Pos) /*!< Bit mask of ADDR field. */ + +/* Register: USBD_BMREQUESTTYPE */ +/* Description: SETUP data, byte 0, bmRequestType */ + +/* Bit 7 : Data transfer direction */ +#define USBD_BMREQUESTTYPE_DIRECTION_Pos (7UL) /*!< Position of DIRECTION field. */ +#define USBD_BMREQUESTTYPE_DIRECTION_Msk (0x1UL << USBD_BMREQUESTTYPE_DIRECTION_Pos) /*!< Bit mask of DIRECTION field. */ +#define USBD_BMREQUESTTYPE_DIRECTION_HostToDevice (0UL) /*!< Host-to-device */ +#define USBD_BMREQUESTTYPE_DIRECTION_DeviceToHost (1UL) /*!< Device-to-host */ + +/* Bits 6..5 : Data transfer type */ +#define USBD_BMREQUESTTYPE_TYPE_Pos (5UL) /*!< Position of TYPE field. */ +#define USBD_BMREQUESTTYPE_TYPE_Msk (0x3UL << USBD_BMREQUESTTYPE_TYPE_Pos) /*!< Bit mask of TYPE field. */ +#define USBD_BMREQUESTTYPE_TYPE_Standard (0UL) /*!< Standard */ +#define USBD_BMREQUESTTYPE_TYPE_Class (1UL) /*!< Class */ +#define USBD_BMREQUESTTYPE_TYPE_Vendor (2UL) /*!< Vendor */ + +/* Bits 4..0 : Data transfer type */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Pos (0UL) /*!< Position of RECIPIENT field. */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Msk (0x1FUL << USBD_BMREQUESTTYPE_RECIPIENT_Pos) /*!< Bit mask of RECIPIENT field. */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Device (0UL) /*!< Device */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Interface (1UL) /*!< Interface */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Endpoint (2UL) /*!< Endpoint */ +#define USBD_BMREQUESTTYPE_RECIPIENT_Other (3UL) /*!< Other */ + +/* Register: USBD_BREQUEST */ +/* Description: SETUP data, byte 1, bRequest */ + +/* Bits 7..0 : SETUP data, byte 1, bRequest. Values provides for standard requests only, user must implement Class and Vendor values. */ +#define USBD_BREQUEST_BREQUEST_Pos (0UL) /*!< Position of BREQUEST field. */ +#define USBD_BREQUEST_BREQUEST_Msk (0xFFUL << USBD_BREQUEST_BREQUEST_Pos) /*!< Bit mask of BREQUEST field. */ +#define USBD_BREQUEST_BREQUEST_STD_GET_STATUS (0UL) /*!< Standard request GET_STATUS */ +#define USBD_BREQUEST_BREQUEST_STD_CLEAR_FEATURE (1UL) /*!< Standard request CLEAR_FEATURE */ +#define USBD_BREQUEST_BREQUEST_STD_SET_FEATURE (3UL) /*!< Standard request SET_FEATURE */ +#define USBD_BREQUEST_BREQUEST_STD_SET_ADDRESS (5UL) /*!< Standard request SET_ADDRESS */ +#define USBD_BREQUEST_BREQUEST_STD_GET_DESCRIPTOR (6UL) /*!< Standard request GET_DESCRIPTOR */ +#define USBD_BREQUEST_BREQUEST_STD_SET_DESCRIPTOR (7UL) /*!< Standard request SET_DESCRIPTOR */ +#define USBD_BREQUEST_BREQUEST_STD_GET_CONFIGURATION (8UL) /*!< Standard request GET_CONFIGURATION */ +#define USBD_BREQUEST_BREQUEST_STD_SET_CONFIGURATION (9UL) /*!< Standard request SET_CONFIGURATION */ +#define USBD_BREQUEST_BREQUEST_STD_GET_INTERFACE (10UL) /*!< Standard request GET_INTERFACE */ +#define USBD_BREQUEST_BREQUEST_STD_SET_INTERFACE (11UL) /*!< Standard request SET_INTERFACE */ +#define USBD_BREQUEST_BREQUEST_STD_SYNCH_FRAME (12UL) /*!< Standard request SYNCH_FRAME */ + +/* Register: USBD_WVALUEL */ +/* Description: SETUP data, byte 2, LSB of wValue */ + +/* Bits 7..0 : SETUP data, byte 2, LSB of wValue */ +#define USBD_WVALUEL_WVALUEL_Pos (0UL) /*!< Position of WVALUEL field. */ +#define USBD_WVALUEL_WVALUEL_Msk (0xFFUL << USBD_WVALUEL_WVALUEL_Pos) /*!< Bit mask of WVALUEL field. */ + +/* Register: USBD_WVALUEH */ +/* Description: SETUP data, byte 3, MSB of wValue */ + +/* Bits 7..0 : SETUP data, byte 3, MSB of wValue */ +#define USBD_WVALUEH_WVALUEH_Pos (0UL) /*!< Position of WVALUEH field. */ +#define USBD_WVALUEH_WVALUEH_Msk (0xFFUL << USBD_WVALUEH_WVALUEH_Pos) /*!< Bit mask of WVALUEH field. */ + +/* Register: USBD_WINDEXL */ +/* Description: SETUP data, byte 4, LSB of wIndex */ + +/* Bits 7..0 : SETUP data, byte 4, LSB of wIndex */ +#define USBD_WINDEXL_WINDEXL_Pos (0UL) /*!< Position of WINDEXL field. */ +#define USBD_WINDEXL_WINDEXL_Msk (0xFFUL << USBD_WINDEXL_WINDEXL_Pos) /*!< Bit mask of WINDEXL field. */ + +/* Register: USBD_WINDEXH */ +/* Description: SETUP data, byte 5, MSB of wIndex */ + +/* Bits 7..0 : SETUP data, byte 5, MSB of wIndex */ +#define USBD_WINDEXH_WINDEXH_Pos (0UL) /*!< Position of WINDEXH field. */ +#define USBD_WINDEXH_WINDEXH_Msk (0xFFUL << USBD_WINDEXH_WINDEXH_Pos) /*!< Bit mask of WINDEXH field. */ + +/* Register: USBD_WLENGTHL */ +/* Description: SETUP data, byte 6, LSB of wLength */ + +/* Bits 7..0 : SETUP data, byte 6, LSB of wLength */ +#define USBD_WLENGTHL_WLENGTHL_Pos (0UL) /*!< Position of WLENGTHL field. */ +#define USBD_WLENGTHL_WLENGTHL_Msk (0xFFUL << USBD_WLENGTHL_WLENGTHL_Pos) /*!< Bit mask of WLENGTHL field. */ + +/* Register: USBD_WLENGTHH */ +/* Description: SETUP data, byte 7, MSB of wLength */ + +/* Bits 7..0 : SETUP data, byte 7, MSB of wLength */ +#define USBD_WLENGTHH_WLENGTHH_Pos (0UL) /*!< Position of WLENGTHH field. */ +#define USBD_WLENGTHH_WLENGTHH_Msk (0xFFUL << USBD_WLENGTHH_WLENGTHH_Pos) /*!< Bit mask of WLENGTHH field. */ + +/* Register: USBD_SIZE_EPOUT */ +/* Description: Description collection[0]: Amount of bytes received last in the data stage of this OUT endpoint */ + +/* Bits 6..0 : Amount of bytes received last in the data stage of this OUT endpoint */ +#define USBD_SIZE_EPOUT_SIZE_Pos (0UL) /*!< Position of SIZE field. */ +#define USBD_SIZE_EPOUT_SIZE_Msk (0x7FUL << USBD_SIZE_EPOUT_SIZE_Pos) /*!< Bit mask of SIZE field. */ + +/* Register: USBD_SIZE_ISOOUT */ +/* Description: Amount of bytes received last on this iso OUT data endpoint */ + +/* Bit 16 : Zero-length data packet received */ +#define USBD_SIZE_ISOOUT_ZERO_Pos (16UL) /*!< Position of ZERO field. */ +#define USBD_SIZE_ISOOUT_ZERO_Msk (0x1UL << USBD_SIZE_ISOOUT_ZERO_Pos) /*!< Bit mask of ZERO field. */ +#define USBD_SIZE_ISOOUT_ZERO_Normal (0UL) /*!< No zero-length data received, use value in SIZE */ +#define USBD_SIZE_ISOOUT_ZERO_ZeroData (1UL) /*!< Zero-length data received, ignore value in SIZE */ + +/* Bits 9..0 : Amount of bytes received last on this iso OUT data endpoint */ +#define USBD_SIZE_ISOOUT_SIZE_Pos (0UL) /*!< Position of SIZE field. */ +#define USBD_SIZE_ISOOUT_SIZE_Msk (0x3FFUL << USBD_SIZE_ISOOUT_SIZE_Pos) /*!< Bit mask of SIZE field. */ + +/* Register: USBD_ENABLE */ +/* Description: Enable USB */ + +/* Bit 0 : Enable USB */ +#define USBD_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ +#define USBD_ENABLE_ENABLE_Msk (0x1UL << USBD_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ +#define USBD_ENABLE_ENABLE_Disabled (0UL) /*!< USB peripheral is disabled */ +#define USBD_ENABLE_ENABLE_Enabled (1UL) /*!< USB peripheral is enabled */ + +/* Register: USBD_USBPULLUP */ +/* Description: Control of the USB pull-up */ + +/* Bit 0 : Control of the USB pull-up on the D+ line */ +#define USBD_USBPULLUP_CONNECT_Pos (0UL) /*!< Position of CONNECT field. */ +#define USBD_USBPULLUP_CONNECT_Msk (0x1UL << USBD_USBPULLUP_CONNECT_Pos) /*!< Bit mask of CONNECT field. */ +#define USBD_USBPULLUP_CONNECT_Disabled (0UL) /*!< Pull-up is disconnected */ +#define USBD_USBPULLUP_CONNECT_Enabled (1UL) /*!< Pull-up is connected to D+ */ + +/* Register: USBD_DPDMVALUE */ +/* Description: State at which the DPDMDRIVE task will force D+ and D-. The DPDMNODRIVE task reverts the control of the lines to MAC IP (no forcing). */ + +/* Bits 4..0 : State at which the DPDMDRIVE task will force D+ and D- */ +#define USBD_DPDMVALUE_STATE_Pos (0UL) /*!< Position of STATE field. */ +#define USBD_DPDMVALUE_STATE_Msk (0x1FUL << USBD_DPDMVALUE_STATE_Pos) /*!< Bit mask of STATE field. */ +#define USBD_DPDMVALUE_STATE_Resume (1UL) /*!< D+ forced low, D- forced high (K state) for a timing pre-set in hardware (50 us or 5 ms, depending on bus state) */ +#define USBD_DPDMVALUE_STATE_J (2UL) /*!< D+ forced high, D- forced low (J state) */ +#define USBD_DPDMVALUE_STATE_K (4UL) /*!< D+ forced low, D- forced high (K state) */ + +/* Register: USBD_DTOGGLE */ +/* Description: Data toggle control and status. */ + +/* Bits 9..8 : Data toggle value */ +#define USBD_DTOGGLE_VALUE_Pos (8UL) /*!< Position of VALUE field. */ +#define USBD_DTOGGLE_VALUE_Msk (0x3UL << USBD_DTOGGLE_VALUE_Pos) /*!< Bit mask of VALUE field. */ +#define USBD_DTOGGLE_VALUE_Nop (0UL) /*!< No action on data toggle when writing the register with this value */ +#define USBD_DTOGGLE_VALUE_Data0 (1UL) /*!< Data toggle is DATA0 on endpoint set by EP and IO */ +#define USBD_DTOGGLE_VALUE_Data1 (2UL) /*!< Data toggle is DATA1 on endpoint set by EP and IO */ + +/* Bit 7 : Selects IN or OUT endpoint */ +#define USBD_DTOGGLE_IO_Pos (7UL) /*!< Position of IO field. */ +#define USBD_DTOGGLE_IO_Msk (0x1UL << USBD_DTOGGLE_IO_Pos) /*!< Bit mask of IO field. */ +#define USBD_DTOGGLE_IO_Out (0UL) /*!< Selects OUT endpoint */ +#define USBD_DTOGGLE_IO_In (1UL) /*!< Selects IN endpoint */ + +/* Bits 2..0 : Select bulk endpoint number */ +#define USBD_DTOGGLE_EP_Pos (0UL) /*!< Position of EP field. */ +#define USBD_DTOGGLE_EP_Msk (0x7UL << USBD_DTOGGLE_EP_Pos) /*!< Bit mask of EP field. */ + +/* Register: USBD_EPINEN */ +/* Description: Endpoint IN enable */ + +/* Bit 8 : Enable iso IN endpoint */ +#define USBD_EPINEN_ISOIN_Pos (8UL) /*!< Position of ISOIN field. */ +#define USBD_EPINEN_ISOIN_Msk (0x1UL << USBD_EPINEN_ISOIN_Pos) /*!< Bit mask of ISOIN field. */ +#define USBD_EPINEN_ISOIN_Disable (0UL) /*!< Disable iso IN endpoint 8 */ +#define USBD_EPINEN_ISOIN_Enable (1UL) /*!< Enable iso IN endpoint 8 */ + +/* Bit 7 : Enable IN endpoint 7 */ +#define USBD_EPINEN_IN7_Pos (7UL) /*!< Position of IN7 field. */ +#define USBD_EPINEN_IN7_Msk (0x1UL << USBD_EPINEN_IN7_Pos) /*!< Bit mask of IN7 field. */ +#define USBD_EPINEN_IN7_Disable (0UL) /*!< Disable endpoint IN 7 (no response to IN tokens) */ +#define USBD_EPINEN_IN7_Enable (1UL) /*!< Enable endpoint IN 7 (response to IN tokens) */ + +/* Bit 6 : Enable IN endpoint 6 */ +#define USBD_EPINEN_IN6_Pos (6UL) /*!< Position of IN6 field. */ +#define USBD_EPINEN_IN6_Msk (0x1UL << USBD_EPINEN_IN6_Pos) /*!< Bit mask of IN6 field. */ +#define USBD_EPINEN_IN6_Disable (0UL) /*!< Disable endpoint IN 6 (no response to IN tokens) */ +#define USBD_EPINEN_IN6_Enable (1UL) /*!< Enable endpoint IN 6 (response to IN tokens) */ + +/* Bit 5 : Enable IN endpoint 5 */ +#define USBD_EPINEN_IN5_Pos (5UL) /*!< Position of IN5 field. */ +#define USBD_EPINEN_IN5_Msk (0x1UL << USBD_EPINEN_IN5_Pos) /*!< Bit mask of IN5 field. */ +#define USBD_EPINEN_IN5_Disable (0UL) /*!< Disable endpoint IN 5 (no response to IN tokens) */ +#define USBD_EPINEN_IN5_Enable (1UL) /*!< Enable endpoint IN 5 (response to IN tokens) */ + +/* Bit 4 : Enable IN endpoint 4 */ +#define USBD_EPINEN_IN4_Pos (4UL) /*!< Position of IN4 field. */ +#define USBD_EPINEN_IN4_Msk (0x1UL << USBD_EPINEN_IN4_Pos) /*!< Bit mask of IN4 field. */ +#define USBD_EPINEN_IN4_Disable (0UL) /*!< Disable endpoint IN 4 (no response to IN tokens) */ +#define USBD_EPINEN_IN4_Enable (1UL) /*!< Enable endpoint IN 4 (response to IN tokens) */ + +/* Bit 3 : Enable IN endpoint 3 */ +#define USBD_EPINEN_IN3_Pos (3UL) /*!< Position of IN3 field. */ +#define USBD_EPINEN_IN3_Msk (0x1UL << USBD_EPINEN_IN3_Pos) /*!< Bit mask of IN3 field. */ +#define USBD_EPINEN_IN3_Disable (0UL) /*!< Disable endpoint IN 3 (no response to IN tokens) */ +#define USBD_EPINEN_IN3_Enable (1UL) /*!< Enable endpoint IN 3 (response to IN tokens) */ + +/* Bit 2 : Enable IN endpoint 2 */ +#define USBD_EPINEN_IN2_Pos (2UL) /*!< Position of IN2 field. */ +#define USBD_EPINEN_IN2_Msk (0x1UL << USBD_EPINEN_IN2_Pos) /*!< Bit mask of IN2 field. */ +#define USBD_EPINEN_IN2_Disable (0UL) /*!< Disable endpoint IN 2 (no response to IN tokens) */ +#define USBD_EPINEN_IN2_Enable (1UL) /*!< Enable endpoint IN 2 (response to IN tokens) */ + +/* Bit 1 : Enable IN endpoint 1 */ +#define USBD_EPINEN_IN1_Pos (1UL) /*!< Position of IN1 field. */ +#define USBD_EPINEN_IN1_Msk (0x1UL << USBD_EPINEN_IN1_Pos) /*!< Bit mask of IN1 field. */ +#define USBD_EPINEN_IN1_Disable (0UL) /*!< Disable endpoint IN 1 (no response to IN tokens) */ +#define USBD_EPINEN_IN1_Enable (1UL) /*!< Enable endpoint IN 1 (response to IN tokens) */ + +/* Bit 0 : Enable IN endpoint 0 */ +#define USBD_EPINEN_IN0_Pos (0UL) /*!< Position of IN0 field. */ +#define USBD_EPINEN_IN0_Msk (0x1UL << USBD_EPINEN_IN0_Pos) /*!< Bit mask of IN0 field. */ +#define USBD_EPINEN_IN0_Disable (0UL) /*!< Disable endpoint IN 0 (no response to IN tokens) */ +#define USBD_EPINEN_IN0_Enable (1UL) /*!< Enable endpoint IN 0 (response to IN tokens) */ + +/* Register: USBD_EPOUTEN */ +/* Description: Endpoint OUT enable */ + +/* Bit 8 : Enable iso OUT endpoint 8 */ +#define USBD_EPOUTEN_ISOOUT_Pos (8UL) /*!< Position of ISOOUT field. */ +#define USBD_EPOUTEN_ISOOUT_Msk (0x1UL << USBD_EPOUTEN_ISOOUT_Pos) /*!< Bit mask of ISOOUT field. */ +#define USBD_EPOUTEN_ISOOUT_Disable (0UL) /*!< Disable iso OUT endpoint 8 */ +#define USBD_EPOUTEN_ISOOUT_Enable (1UL) /*!< Enable iso OUT endpoint 8 */ + +/* Bit 7 : Enable OUT endpoint 7 */ +#define USBD_EPOUTEN_OUT7_Pos (7UL) /*!< Position of OUT7 field. */ +#define USBD_EPOUTEN_OUT7_Msk (0x1UL << USBD_EPOUTEN_OUT7_Pos) /*!< Bit mask of OUT7 field. */ +#define USBD_EPOUTEN_OUT7_Disable (0UL) /*!< Disable endpoint OUT 7 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT7_Enable (1UL) /*!< Enable endpoint OUT 7 (response to OUT tokens) */ + +/* Bit 6 : Enable OUT endpoint 6 */ +#define USBD_EPOUTEN_OUT6_Pos (6UL) /*!< Position of OUT6 field. */ +#define USBD_EPOUTEN_OUT6_Msk (0x1UL << USBD_EPOUTEN_OUT6_Pos) /*!< Bit mask of OUT6 field. */ +#define USBD_EPOUTEN_OUT6_Disable (0UL) /*!< Disable endpoint OUT 6 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT6_Enable (1UL) /*!< Enable endpoint OUT 6 (response to OUT tokens) */ + +/* Bit 5 : Enable OUT endpoint 5 */ +#define USBD_EPOUTEN_OUT5_Pos (5UL) /*!< Position of OUT5 field. */ +#define USBD_EPOUTEN_OUT5_Msk (0x1UL << USBD_EPOUTEN_OUT5_Pos) /*!< Bit mask of OUT5 field. */ +#define USBD_EPOUTEN_OUT5_Disable (0UL) /*!< Disable endpoint OUT 5 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT5_Enable (1UL) /*!< Enable endpoint OUT 5 (response to OUT tokens) */ + +/* Bit 4 : Enable OUT endpoint 4 */ +#define USBD_EPOUTEN_OUT4_Pos (4UL) /*!< Position of OUT4 field. */ +#define USBD_EPOUTEN_OUT4_Msk (0x1UL << USBD_EPOUTEN_OUT4_Pos) /*!< Bit mask of OUT4 field. */ +#define USBD_EPOUTEN_OUT4_Disable (0UL) /*!< Disable endpoint OUT 4 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT4_Enable (1UL) /*!< Enable endpoint OUT 4 (response to OUT tokens) */ + +/* Bit 3 : Enable OUT endpoint 3 */ +#define USBD_EPOUTEN_OUT3_Pos (3UL) /*!< Position of OUT3 field. */ +#define USBD_EPOUTEN_OUT3_Msk (0x1UL << USBD_EPOUTEN_OUT3_Pos) /*!< Bit mask of OUT3 field. */ +#define USBD_EPOUTEN_OUT3_Disable (0UL) /*!< Disable endpoint OUT 3 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT3_Enable (1UL) /*!< Enable endpoint OUT 3 (response to OUT tokens) */ + +/* Bit 2 : Enable OUT endpoint 2 */ +#define USBD_EPOUTEN_OUT2_Pos (2UL) /*!< Position of OUT2 field. */ +#define USBD_EPOUTEN_OUT2_Msk (0x1UL << USBD_EPOUTEN_OUT2_Pos) /*!< Bit mask of OUT2 field. */ +#define USBD_EPOUTEN_OUT2_Disable (0UL) /*!< Disable endpoint OUT 2 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT2_Enable (1UL) /*!< Enable endpoint OUT 2 (response to OUT tokens) */ + +/* Bit 1 : Enable OUT endpoint 1 */ +#define USBD_EPOUTEN_OUT1_Pos (1UL) /*!< Position of OUT1 field. */ +#define USBD_EPOUTEN_OUT1_Msk (0x1UL << USBD_EPOUTEN_OUT1_Pos) /*!< Bit mask of OUT1 field. */ +#define USBD_EPOUTEN_OUT1_Disable (0UL) /*!< Disable endpoint OUT 1 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT1_Enable (1UL) /*!< Enable endpoint OUT 1 (response to OUT tokens) */ + +/* Bit 0 : Enable OUT endpoint 0 */ +#define USBD_EPOUTEN_OUT0_Pos (0UL) /*!< Position of OUT0 field. */ +#define USBD_EPOUTEN_OUT0_Msk (0x1UL << USBD_EPOUTEN_OUT0_Pos) /*!< Bit mask of OUT0 field. */ +#define USBD_EPOUTEN_OUT0_Disable (0UL) /*!< Disable endpoint OUT 0 (no response to OUT tokens) */ +#define USBD_EPOUTEN_OUT0_Enable (1UL) /*!< Enable endpoint OUT 0 (response to OUT tokens) */ + +/* Register: USBD_EPSTALL */ +/* Description: STALL endpoints */ + +/* Bit 8 : Stall selected endpoint */ +#define USBD_EPSTALL_STALL_Pos (8UL) /*!< Position of STALL field. */ +#define USBD_EPSTALL_STALL_Msk (0x1UL << USBD_EPSTALL_STALL_Pos) /*!< Bit mask of STALL field. */ +#define USBD_EPSTALL_STALL_UnStall (0UL) /*!< Don't stall selected endpoint */ +#define USBD_EPSTALL_STALL_Stall (1UL) /*!< Stall selected endpoint */ + +/* Bit 7 : Selects IN or OUT endpoint */ +#define USBD_EPSTALL_IO_Pos (7UL) /*!< Position of IO field. */ +#define USBD_EPSTALL_IO_Msk (0x1UL << USBD_EPSTALL_IO_Pos) /*!< Bit mask of IO field. */ +#define USBD_EPSTALL_IO_Out (0UL) /*!< Selects OUT endpoint */ +#define USBD_EPSTALL_IO_In (1UL) /*!< Selects IN endpoint */ + +/* Bits 2..0 : Select endpoint number */ +#define USBD_EPSTALL_EP_Pos (0UL) /*!< Position of EP field. */ +#define USBD_EPSTALL_EP_Msk (0x7UL << USBD_EPSTALL_EP_Pos) /*!< Bit mask of EP field. */ + +/* Register: USBD_ISOSPLIT */ +/* Description: Controls the split of ISO buffers */ + +/* Bits 15..0 : Controls the split of ISO buffers */ +#define USBD_ISOSPLIT_SPLIT_Pos (0UL) /*!< Position of SPLIT field. */ +#define USBD_ISOSPLIT_SPLIT_Msk (0xFFFFUL << USBD_ISOSPLIT_SPLIT_Pos) /*!< Bit mask of SPLIT field. */ +#define USBD_ISOSPLIT_SPLIT_OneDir (0x0000UL) /*!< Full buffer dedicated to either iso IN or OUT */ +#define USBD_ISOSPLIT_SPLIT_HalfIN (0x0080UL) /*!< Lower half for IN, upper half for OUT */ + +/* Register: USBD_FRAMECNTR */ +/* Description: Returns the current value of the start of frame counter */ + +/* Bits 10..0 : Returns the current value of the start of frame counter */ +#define USBD_FRAMECNTR_FRAMECNTR_Pos (0UL) /*!< Position of FRAMECNTR field. */ +#define USBD_FRAMECNTR_FRAMECNTR_Msk (0x7FFUL << USBD_FRAMECNTR_FRAMECNTR_Pos) /*!< Bit mask of FRAMECNTR field. */ + +/* Register: USBD_ISOINCONFIG */ +/* Description: Controls the response of the ISO IN endpoint to an IN token when no data is ready to be sent */ + +/* Bit 0 : Controls the response of the ISO IN endpoint to an IN token when no data is ready to be sent */ +#define USBD_ISOINCONFIG_RESPONSE_Pos (0UL) /*!< Position of RESPONSE field. */ +#define USBD_ISOINCONFIG_RESPONSE_Msk (0x1UL << USBD_ISOINCONFIG_RESPONSE_Pos) /*!< Bit mask of RESPONSE field. */ +#define USBD_ISOINCONFIG_RESPONSE_NoResp (0UL) /*!< Endpoint does not respond in that case */ +#define USBD_ISOINCONFIG_RESPONSE_ZeroData (1UL) /*!< Endpoint responds with a zero-length data packet in that case */ + +/* Register: USBD_EPIN_PTR */ +/* Description: Description cluster[0]: Data pointer */ + +/* Bits 31..0 : Data pointer. Accepts any address in Data RAM. */ +#define USBD_EPIN_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define USBD_EPIN_PTR_PTR_Msk (0xFFFFFFFFUL << USBD_EPIN_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: USBD_EPIN_MAXCNT */ +/* Description: Description cluster[0]: Maximum number of bytes to transfer */ + +/* Bits 6..0 : Maximum number of bytes to transfer */ +#define USBD_EPIN_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define USBD_EPIN_MAXCNT_MAXCNT_Msk (0x7FUL << USBD_EPIN_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: USBD_EPIN_AMOUNT */ +/* Description: Description cluster[0]: Number of bytes transferred in the last transaction */ + +/* Bits 6..0 : Number of bytes transferred in the last transaction */ +#define USBD_EPIN_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define USBD_EPIN_AMOUNT_AMOUNT_Msk (0x7FUL << USBD_EPIN_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: USBD_ISOIN_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer. Accepts any address in Data RAM. */ +#define USBD_ISOIN_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define USBD_ISOIN_PTR_PTR_Msk (0xFFFFFFFFUL << USBD_ISOIN_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: USBD_ISOIN_MAXCNT */ +/* Description: Maximum number of bytes to transfer */ + +/* Bits 9..0 : Maximum number of bytes to transfer */ +#define USBD_ISOIN_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define USBD_ISOIN_MAXCNT_MAXCNT_Msk (0x3FFUL << USBD_ISOIN_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: USBD_ISOIN_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 9..0 : Number of bytes transferred in the last transaction */ +#define USBD_ISOIN_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define USBD_ISOIN_AMOUNT_AMOUNT_Msk (0x3FFUL << USBD_ISOIN_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: USBD_EPOUT_PTR */ +/* Description: Description cluster[0]: Data pointer */ + +/* Bits 31..0 : Data pointer. Accepts any address in Data RAM. */ +#define USBD_EPOUT_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define USBD_EPOUT_PTR_PTR_Msk (0xFFFFFFFFUL << USBD_EPOUT_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: USBD_EPOUT_MAXCNT */ +/* Description: Description cluster[0]: Maximum number of bytes to transfer */ + +/* Bits 6..0 : Maximum number of bytes to transfer */ +#define USBD_EPOUT_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define USBD_EPOUT_MAXCNT_MAXCNT_Msk (0x7FUL << USBD_EPOUT_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: USBD_EPOUT_AMOUNT */ +/* Description: Description cluster[0]: Number of bytes transferred in the last transaction */ + +/* Bits 6..0 : Number of bytes transferred in the last transaction */ +#define USBD_EPOUT_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define USBD_EPOUT_AMOUNT_AMOUNT_Msk (0x7FUL << USBD_EPOUT_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + +/* Register: USBD_ISOOUT_PTR */ +/* Description: Data pointer */ + +/* Bits 31..0 : Data pointer. Accepts any address in Data RAM. */ +#define USBD_ISOOUT_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ +#define USBD_ISOOUT_PTR_PTR_Msk (0xFFFFFFFFUL << USBD_ISOOUT_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ + +/* Register: USBD_ISOOUT_MAXCNT */ +/* Description: Maximum number of bytes to transfer */ + +/* Bits 9..0 : Maximum number of bytes to transfer */ +#define USBD_ISOOUT_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ +#define USBD_ISOOUT_MAXCNT_MAXCNT_Msk (0x3FFUL << USBD_ISOOUT_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ + +/* Register: USBD_ISOOUT_AMOUNT */ +/* Description: Number of bytes transferred in the last transaction */ + +/* Bits 9..0 : Number of bytes transferred in the last transaction */ +#define USBD_ISOOUT_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ +#define USBD_ISOOUT_AMOUNT_AMOUNT_Msk (0x3FFUL << USBD_ISOOUT_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ + + +/* Peripheral: WDT */ +/* Description: Watchdog Timer */ + +/* Register: WDT_INTENSET */ +/* Description: Enable interrupt */ + +/* Bit 0 : Write '1' to Enable interrupt for TIMEOUT event */ +#define WDT_INTENSET_TIMEOUT_Pos (0UL) /*!< Position of TIMEOUT field. */ +#define WDT_INTENSET_TIMEOUT_Msk (0x1UL << WDT_INTENSET_TIMEOUT_Pos) /*!< Bit mask of TIMEOUT field. */ +#define WDT_INTENSET_TIMEOUT_Disabled (0UL) /*!< Read: Disabled */ +#define WDT_INTENSET_TIMEOUT_Enabled (1UL) /*!< Read: Enabled */ +#define WDT_INTENSET_TIMEOUT_Set (1UL) /*!< Enable */ + +/* Register: WDT_INTENCLR */ +/* Description: Disable interrupt */ + +/* Bit 0 : Write '1' to Disable interrupt for TIMEOUT event */ +#define WDT_INTENCLR_TIMEOUT_Pos (0UL) /*!< Position of TIMEOUT field. */ +#define WDT_INTENCLR_TIMEOUT_Msk (0x1UL << WDT_INTENCLR_TIMEOUT_Pos) /*!< Bit mask of TIMEOUT field. */ +#define WDT_INTENCLR_TIMEOUT_Disabled (0UL) /*!< Read: Disabled */ +#define WDT_INTENCLR_TIMEOUT_Enabled (1UL) /*!< Read: Enabled */ +#define WDT_INTENCLR_TIMEOUT_Clear (1UL) /*!< Disable */ + +/* Register: WDT_RUNSTATUS */ +/* Description: Run status */ + +/* Bit 0 : Indicates whether or not the watchdog is running */ +#define WDT_RUNSTATUS_RUNSTATUS_Pos (0UL) /*!< Position of RUNSTATUS field. */ +#define WDT_RUNSTATUS_RUNSTATUS_Msk (0x1UL << WDT_RUNSTATUS_RUNSTATUS_Pos) /*!< Bit mask of RUNSTATUS field. */ +#define WDT_RUNSTATUS_RUNSTATUS_NotRunning (0UL) /*!< Watchdog not running */ +#define WDT_RUNSTATUS_RUNSTATUS_Running (1UL) /*!< Watchdog is running */ + +/* Register: WDT_REQSTATUS */ +/* Description: Request status */ + +/* Bit 7 : Request status for RR[7] register */ +#define WDT_REQSTATUS_RR7_Pos (7UL) /*!< Position of RR7 field. */ +#define WDT_REQSTATUS_RR7_Msk (0x1UL << WDT_REQSTATUS_RR7_Pos) /*!< Bit mask of RR7 field. */ +#define WDT_REQSTATUS_RR7_DisabledOrRequested (0UL) /*!< RR[7] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR7_EnabledAndUnrequested (1UL) /*!< RR[7] register is enabled, and are not yet requesting reload */ + +/* Bit 6 : Request status for RR[6] register */ +#define WDT_REQSTATUS_RR6_Pos (6UL) /*!< Position of RR6 field. */ +#define WDT_REQSTATUS_RR6_Msk (0x1UL << WDT_REQSTATUS_RR6_Pos) /*!< Bit mask of RR6 field. */ +#define WDT_REQSTATUS_RR6_DisabledOrRequested (0UL) /*!< RR[6] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR6_EnabledAndUnrequested (1UL) /*!< RR[6] register is enabled, and are not yet requesting reload */ + +/* Bit 5 : Request status for RR[5] register */ +#define WDT_REQSTATUS_RR5_Pos (5UL) /*!< Position of RR5 field. */ +#define WDT_REQSTATUS_RR5_Msk (0x1UL << WDT_REQSTATUS_RR5_Pos) /*!< Bit mask of RR5 field. */ +#define WDT_REQSTATUS_RR5_DisabledOrRequested (0UL) /*!< RR[5] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR5_EnabledAndUnrequested (1UL) /*!< RR[5] register is enabled, and are not yet requesting reload */ + +/* Bit 4 : Request status for RR[4] register */ +#define WDT_REQSTATUS_RR4_Pos (4UL) /*!< Position of RR4 field. */ +#define WDT_REQSTATUS_RR4_Msk (0x1UL << WDT_REQSTATUS_RR4_Pos) /*!< Bit mask of RR4 field. */ +#define WDT_REQSTATUS_RR4_DisabledOrRequested (0UL) /*!< RR[4] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR4_EnabledAndUnrequested (1UL) /*!< RR[4] register is enabled, and are not yet requesting reload */ + +/* Bit 3 : Request status for RR[3] register */ +#define WDT_REQSTATUS_RR3_Pos (3UL) /*!< Position of RR3 field. */ +#define WDT_REQSTATUS_RR3_Msk (0x1UL << WDT_REQSTATUS_RR3_Pos) /*!< Bit mask of RR3 field. */ +#define WDT_REQSTATUS_RR3_DisabledOrRequested (0UL) /*!< RR[3] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR3_EnabledAndUnrequested (1UL) /*!< RR[3] register is enabled, and are not yet requesting reload */ + +/* Bit 2 : Request status for RR[2] register */ +#define WDT_REQSTATUS_RR2_Pos (2UL) /*!< Position of RR2 field. */ +#define WDT_REQSTATUS_RR2_Msk (0x1UL << WDT_REQSTATUS_RR2_Pos) /*!< Bit mask of RR2 field. */ +#define WDT_REQSTATUS_RR2_DisabledOrRequested (0UL) /*!< RR[2] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR2_EnabledAndUnrequested (1UL) /*!< RR[2] register is enabled, and are not yet requesting reload */ + +/* Bit 1 : Request status for RR[1] register */ +#define WDT_REQSTATUS_RR1_Pos (1UL) /*!< Position of RR1 field. */ +#define WDT_REQSTATUS_RR1_Msk (0x1UL << WDT_REQSTATUS_RR1_Pos) /*!< Bit mask of RR1 field. */ +#define WDT_REQSTATUS_RR1_DisabledOrRequested (0UL) /*!< RR[1] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR1_EnabledAndUnrequested (1UL) /*!< RR[1] register is enabled, and are not yet requesting reload */ + +/* Bit 0 : Request status for RR[0] register */ +#define WDT_REQSTATUS_RR0_Pos (0UL) /*!< Position of RR0 field. */ +#define WDT_REQSTATUS_RR0_Msk (0x1UL << WDT_REQSTATUS_RR0_Pos) /*!< Bit mask of RR0 field. */ +#define WDT_REQSTATUS_RR0_DisabledOrRequested (0UL) /*!< RR[0] register is not enabled, or are already requesting reload */ +#define WDT_REQSTATUS_RR0_EnabledAndUnrequested (1UL) /*!< RR[0] register is enabled, and are not yet requesting reload */ + +/* Register: WDT_CRV */ +/* Description: Counter reload value */ + +/* Bits 31..0 : Counter reload value in number of cycles of the 32.768 kHz clock */ +#define WDT_CRV_CRV_Pos (0UL) /*!< Position of CRV field. */ +#define WDT_CRV_CRV_Msk (0xFFFFFFFFUL << WDT_CRV_CRV_Pos) /*!< Bit mask of CRV field. */ + +/* Register: WDT_RREN */ +/* Description: Enable register for reload request registers */ + +/* Bit 7 : Enable or disable RR[7] register */ +#define WDT_RREN_RR7_Pos (7UL) /*!< Position of RR7 field. */ +#define WDT_RREN_RR7_Msk (0x1UL << WDT_RREN_RR7_Pos) /*!< Bit mask of RR7 field. */ +#define WDT_RREN_RR7_Disabled (0UL) /*!< Disable RR[7] register */ +#define WDT_RREN_RR7_Enabled (1UL) /*!< Enable RR[7] register */ + +/* Bit 6 : Enable or disable RR[6] register */ +#define WDT_RREN_RR6_Pos (6UL) /*!< Position of RR6 field. */ +#define WDT_RREN_RR6_Msk (0x1UL << WDT_RREN_RR6_Pos) /*!< Bit mask of RR6 field. */ +#define WDT_RREN_RR6_Disabled (0UL) /*!< Disable RR[6] register */ +#define WDT_RREN_RR6_Enabled (1UL) /*!< Enable RR[6] register */ + +/* Bit 5 : Enable or disable RR[5] register */ +#define WDT_RREN_RR5_Pos (5UL) /*!< Position of RR5 field. */ +#define WDT_RREN_RR5_Msk (0x1UL << WDT_RREN_RR5_Pos) /*!< Bit mask of RR5 field. */ +#define WDT_RREN_RR5_Disabled (0UL) /*!< Disable RR[5] register */ +#define WDT_RREN_RR5_Enabled (1UL) /*!< Enable RR[5] register */ + +/* Bit 4 : Enable or disable RR[4] register */ +#define WDT_RREN_RR4_Pos (4UL) /*!< Position of RR4 field. */ +#define WDT_RREN_RR4_Msk (0x1UL << WDT_RREN_RR4_Pos) /*!< Bit mask of RR4 field. */ +#define WDT_RREN_RR4_Disabled (0UL) /*!< Disable RR[4] register */ +#define WDT_RREN_RR4_Enabled (1UL) /*!< Enable RR[4] register */ + +/* Bit 3 : Enable or disable RR[3] register */ +#define WDT_RREN_RR3_Pos (3UL) /*!< Position of RR3 field. */ +#define WDT_RREN_RR3_Msk (0x1UL << WDT_RREN_RR3_Pos) /*!< Bit mask of RR3 field. */ +#define WDT_RREN_RR3_Disabled (0UL) /*!< Disable RR[3] register */ +#define WDT_RREN_RR3_Enabled (1UL) /*!< Enable RR[3] register */ + +/* Bit 2 : Enable or disable RR[2] register */ +#define WDT_RREN_RR2_Pos (2UL) /*!< Position of RR2 field. */ +#define WDT_RREN_RR2_Msk (0x1UL << WDT_RREN_RR2_Pos) /*!< Bit mask of RR2 field. */ +#define WDT_RREN_RR2_Disabled (0UL) /*!< Disable RR[2] register */ +#define WDT_RREN_RR2_Enabled (1UL) /*!< Enable RR[2] register */ + +/* Bit 1 : Enable or disable RR[1] register */ +#define WDT_RREN_RR1_Pos (1UL) /*!< Position of RR1 field. */ +#define WDT_RREN_RR1_Msk (0x1UL << WDT_RREN_RR1_Pos) /*!< Bit mask of RR1 field. */ +#define WDT_RREN_RR1_Disabled (0UL) /*!< Disable RR[1] register */ +#define WDT_RREN_RR1_Enabled (1UL) /*!< Enable RR[1] register */ + +/* Bit 0 : Enable or disable RR[0] register */ +#define WDT_RREN_RR0_Pos (0UL) /*!< Position of RR0 field. */ +#define WDT_RREN_RR0_Msk (0x1UL << WDT_RREN_RR0_Pos) /*!< Bit mask of RR0 field. */ +#define WDT_RREN_RR0_Disabled (0UL) /*!< Disable RR[0] register */ +#define WDT_RREN_RR0_Enabled (1UL) /*!< Enable RR[0] register */ + +/* Register: WDT_CONFIG */ +/* Description: Configuration register */ + +/* Bit 3 : Configure the watchdog to either be paused, or kept running, while the CPU is halted by the debugger */ +#define WDT_CONFIG_HALT_Pos (3UL) /*!< Position of HALT field. */ +#define WDT_CONFIG_HALT_Msk (0x1UL << WDT_CONFIG_HALT_Pos) /*!< Bit mask of HALT field. */ +#define WDT_CONFIG_HALT_Pause (0UL) /*!< Pause watchdog while the CPU is halted by the debugger */ +#define WDT_CONFIG_HALT_Run (1UL) /*!< Keep the watchdog running while the CPU is halted by the debugger */ + +/* Bit 0 : Configure the watchdog to either be paused, or kept running, while the CPU is sleeping */ +#define WDT_CONFIG_SLEEP_Pos (0UL) /*!< Position of SLEEP field. */ +#define WDT_CONFIG_SLEEP_Msk (0x1UL << WDT_CONFIG_SLEEP_Pos) /*!< Bit mask of SLEEP field. */ +#define WDT_CONFIG_SLEEP_Pause (0UL) /*!< Pause watchdog while the CPU is sleeping */ +#define WDT_CONFIG_SLEEP_Run (1UL) /*!< Keep the watchdog running while the CPU is sleeping */ + +/* Register: WDT_RR */ +/* Description: Description collection[0]: Reload request 0 */ + +/* Bits 31..0 : Reload request register */ +#define WDT_RR_RR_Pos (0UL) /*!< Position of RR field. */ +#define WDT_RR_RR_Msk (0xFFFFFFFFUL << WDT_RR_RR_Pos) /*!< Bit mask of RR field. */ +#define WDT_RR_RR_Reload (0x6E524635UL) /*!< Value to request a reload of the watchdog timer */ + + +/*lint --flb "Leave library region" */ +#endif diff --git a/components/device/nrf52840_peripherals.h b/components/device/nrf52840_peripherals.h new file mode 100644 index 0000000..0f7e9d9 --- /dev/null +++ b/components/device/nrf52840_peripherals.h @@ -0,0 +1,240 @@ +/* Copyright (c) 2016, Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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 _NRF52840_PERIPHERALS_H +#define _NRF52840_PERIPHERALS_H + + +/* Floating Point Unit */ +#define FPU_PRESENT +#define FPU_COUNT 1 + +/* Systick timer */ +#define SYSTICK_PRESENT +#define SYSTICK_COUNT 1 + +/* Software Interrupts */ +#define SWI_PRESENT +#define SWI_COUNT 6 + +/* Memory Watch Unit */ +#define MWU_PRESENT +#define MWU_COUNT 1 + +/* GPIO */ +#define GPIO_PRESENT +#define GPIO_COUNT 2 + +#define P0_PIN_NUM 32 +#define P1_PIN_NUM 16 + +/* ACL */ +#define ACL_PRESENT + +#define ACL_REGIONS_COUNT 8 + +/* Radio */ +#define RADIO_PRESENT +#define RADIO_COUNT 1 + +/* Accelerated Address Resolver */ +#define AAR_PRESENT +#define AAR_COUNT 1 + +#define AAR_MAX_IRK_NUM 16 + +/* AES Electronic CodeBook mode encryption */ +#define ECB_PRESENT +#define ECB_COUNT 1 + +/* AES CCM mode encryption */ +#define CCM_PRESENT +#define CCM_COUNT 1 + +/* NFC Tag */ +#define NFCT_PRESENT +#define NFCT_COUNT 1 + +/* Peripheral to Peripheral Interconnect */ +#define PPI_PRESENT +#define PPI_COUNT 1 + +#define PPI_CH_NUM 20 +#define PPI_GROUP_NUM 6 +#define PPI_FEATURE_FORKS_PRESENT + +/* Event Generator Unit */ +#define EGU_PRESENT +#define EGU_COUNT 6 + +#define EGU0_CH_NUM 16 +#define EGU1_CH_NUM 16 +#define EGU2_CH_NUM 16 +#define EGU3_CH_NUM 16 +#define EGU4_CH_NUM 16 +#define EGU5_CH_NUM 16 + +/* Timer/Counter */ +#define TIMER_PRESENT +#define TIMER_COUNT 5 + +#define TIMER0_MAX_SIZE 32 +#define TIMER1_MAX_SIZE 32 +#define TIMER2_MAX_SIZE 32 +#define TIMER3_MAX_SIZE 32 +#define TIMER4_MAX_SIZE 32 + +#define TIMER0_CC_NUM 4 +#define TIMER1_CC_NUM 4 +#define TIMER2_CC_NUM 4 +#define TIMER3_CC_NUM 6 +#define TIMER4_CC_NUM 6 + +/* Real Time Counter */ +#define RTC_PRESENT +#define RTC_COUNT 3 + +#define RTC0_CC_NUM 3 +#define RTC1_CC_NUM 4 +#define RTC2_CC_NUM 4 + +/* RNG */ +#define RNG_PRESENT +#define RNG_COUNT 1 + +/* Watchdog Timer */ +#define WDT_PRESENT +#define WDT_COUNT 1 + +/* Temperature Sensor */ +#define TEMP_PRESENT +#define TEMP_COUNT 1 + +/* Serial Peripheral Interface Master */ +#define SPI_PRESENT +#define SPI_COUNT 3 + +/* Serial Peripheral Interface Master with DMA */ +#define SPIM_PRESENT +#define SPIM_COUNT 4 + +#define SPIM0_MAX_DATARATE 8 +#define SPIM1_MAX_DATARATE 8 +#define SPIM2_MAX_DATARATE 8 +#define SPIM3_MAX_DATARATE 32 + +#define SPIM0_FEATURE_HARDWARE_CSN_PRESENT 0 +#define SPIM1_FEATURE_HARDWARE_CSN_PRESENT 0 +#define SPIM2_FEATURE_HARDWARE_CSN_PRESENT 0 +#define SPIM3_FEATURE_HARDWARE_CSN_PRESENT 1 + +/* Serial Peripheral Interface Slave with DMA*/ +#define SPIS_PRESENT +#define SPIS_COUNT 3 + +/* Two Wire Interface Master */ +#define TWI_PRESENT +#define TWI_COUNT 2 + +/* Two Wire Interface Master with DMA */ +#define TWIM_PRESENT +#define TWIM_COUNT 2 + +/* Two Wire Interface Slave with DMA */ +#define TWIS_PRESENT +#define TWIS_COUNT 2 + +/* Universal Asynchronous Receiver-Transmitter */ +#define UART_PRESENT +#define UART_COUNT 1 + +/* Universal Asynchronous Receiver-Transmitter with DMA */ +#define UARTE_PRESENT +#define UARTE_COUNT 2 + +/* Quadrature Decoder */ +#define QDEC_PRESENT +#define QDEC_COUNT 1 + +/* Successive Approximation Analog to Digital Converter */ +#define SAADC_PRESENT +#define SAADC_COUNT 1 + +/* GPIO Tasks and Events */ +#define GPIOTE_PRESENT +#define GPIOTE_COUNT 1 + +#define GPIOTE_CH_NUM 8 + +#define GPIOTE_FEATURE_SET_PRESENT +#define GPIOTE_FEATURE_CLR_PRESENT + +/* Low Power Comparator */ +#define LPCOMP_PRESENT +#define LPCOMP_COUNT 1 + +#define LPCOMP_REFSEL_RESOLUTION 16 + +#define LPCOMP_FEATURE_HYST_PRESENT + +/* Comparator */ +#define COMP_PRESENT +#define COMP_COUNT 1 + +/* Pulse Width Modulator */ +#define PWM_PRESENT +#define PWM_COUNT 4 + +#define PWM0_CH_NUM 4 +#define PWM1_CH_NUM 4 +#define PWM2_CH_NUM 4 +#define PWM3_CH_NUM 4 + +/* Pulse Density Modulator */ +#define PDM_PRESENT +#define PDM_COUNT 1 + +/* Inter-IC Sound Interface */ +#define I2S_PRESENT +#define I2S_COUNT 1 + +/* Universal Serial Bus Device */ +#define USBD_PRESENT +#define USBD_COUNT 1 + +/* ARM TrustZone Cryptocell 310 */ +#define CRYPTOCELL_PRESENT +#define CRYPTOCELL_COUNT 1 + +/* Quad SPI */ +#define QSPI_PRESENT +#define QSPI_COUNT 1 + +#endif // _NRF52840_PERIPHERALS_H diff --git a/components/device/nrf52_bitfields.h b/components/device/nrf52_bitfields.h index 6b55c81..b695bf8 100644 --- a/components/device/nrf52_bitfields.h +++ b/components/device/nrf52_bitfields.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, Nordic Semiconductor ASA +/* Copyright (c) 2016, Nordic Semiconductor ASA * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,6 +27,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ + #ifndef __NRF52_BITS_H #define __NRF52_BITS_H @@ -123,7 +124,7 @@ /* Register: AAR_SCRATCHPTR */ /* Description: Pointer to data area used for temporary storage */ -/* Bits 31..0 : Pointer to a "scratch" data area used for temporary storage during resolution.A space of minimum 3 bytes must be reserved. */ +/* Bits 31..0 : Pointer to a scratch data area used for temporary storage during resolution.A space of minimum 3 bytes must be reserved. */ #define AAR_SCRATCHPTR_SCRATCHPTR_Pos (0UL) /*!< Position of SCRATCHPTR field. */ #define AAR_SCRATCHPTR_SCRATCHPTR_Msk (0xFFFFFFFFUL << AAR_SCRATCHPTR_SCRATCHPTR_Pos) /*!< Bit mask of SCRATCHPTR field. */ @@ -522,9 +523,9 @@ #define BPROT_CONFIG1_REGION32_Enabled (1UL) /*!< Protection enabled */ /* Register: BPROT_DISABLEINDEBUG */ -/* Description: Disable protection mechanism in debug mode */ +/* Description: Disable protection mechanism in debug interface mode */ -/* Bit 0 : Disable the protection mechanism for NVM regions while in debug mode. This register will only disable the protection mechanism if the device is in debug mode. */ +/* Bit 0 : Disable the protection mechanism for NVM regions while in debug interface mode. This register will only disable the protection mechanism if the device is in debug interface mode. */ #define BPROT_DISABLEINDEBUG_DISABLEINDEBUG_Pos (0UL) /*!< Position of DISABLEINDEBUG field. */ #define BPROT_DISABLEINDEBUG_DISABLEINDEBUG_Msk (0x1UL << BPROT_DISABLEINDEBUG_DISABLEINDEBUG_Pos) /*!< Bit mask of DISABLEINDEBUG field. */ #define BPROT_DISABLEINDEBUG_DISABLEINDEBUG_Enabled (0UL) /*!< Enable in debug */ @@ -1044,7 +1045,7 @@ /* Register: CCM_SCRATCHPTR */ /* Description: Pointer to data area used for temporary storage */ -/* Bits 31..0 : Pointer to a "scratch" data area used for temporary storage during key-stream generation, MIC generation and encryption/decryption. */ +/* Bits 31..0 : Pointer to a scratch data area used for temporary storage during key-stream generation, MIC generation and encryption/decryption. */ #define CCM_SCRATCHPTR_SCRATCHPTR_Pos (0UL) /*!< Position of SCRATCHPTR field. */ #define CCM_SCRATCHPTR_SCRATCHPTR_Msk (0xFFFFFFFFUL << CCM_SCRATCHPTR_SCRATCHPTR_Pos) /*!< Bit mask of SCRATCHPTR field. */ @@ -1176,6 +1177,18 @@ /* Register: CLOCK_LFCLKSRC */ /* Description: Clock source for the LFCLK */ +/* Bit 17 : Enable or disable external source for LFCLK */ +#define CLOCK_LFCLKSRC_EXTERNAL_Pos (17UL) /*!< Position of EXTERNAL field. */ +#define CLOCK_LFCLKSRC_EXTERNAL_Msk (0x1UL << CLOCK_LFCLKSRC_EXTERNAL_Pos) /*!< Bit mask of EXTERNAL field. */ +#define CLOCK_LFCLKSRC_EXTERNAL_Disabled (0UL) /*!< Disable external source (use with Xtal) */ +#define CLOCK_LFCLKSRC_EXTERNAL_Enabled (1UL) /*!< Enable use of external source instead of Xtal (SRC needs to be set to Xtal) */ + +/* Bit 16 : Enable or disable bypass of LFCLK crystal oscillator with external clock source */ +#define CLOCK_LFCLKSRC_BYPASS_Pos (16UL) /*!< Position of BYPASS field. */ +#define CLOCK_LFCLKSRC_BYPASS_Msk (0x1UL << CLOCK_LFCLKSRC_BYPASS_Pos) /*!< Bit mask of BYPASS field. */ +#define CLOCK_LFCLKSRC_BYPASS_Disabled (0UL) /*!< Disable (use with Xtal or low-swing external source) */ +#define CLOCK_LFCLKSRC_BYPASS_Enabled (1UL) /*!< Enable (use with rail-to-rail external source) */ + /* Bits 1..0 : Clock source */ #define CLOCK_LFCLKSRC_SRC_Pos (0UL) /*!< Position of SRC field. */ #define CLOCK_LFCLKSRC_SRC_Msk (0x3UL << CLOCK_LFCLKSRC_SRC_Pos) /*!< Bit mask of SRC field. */ @@ -1184,7 +1197,7 @@ #define CLOCK_LFCLKSRC_SRC_Synth (2UL) /*!< 32.768 kHz synthesized from HFCLK */ /* Register: CLOCK_CTIV */ -/* Description: Calibration timer interval (retained register, same reset behaviour as RESETREAS) */ +/* Description: Calibration timer interval */ /* Bits 6..0 : Calibration timer interval in multiple of 0.25 seconds. Range: 0.25 seconds to 31.75 seconds. */ #define CLOCK_CTIV_CTIV_Pos (0UL) /*!< Position of CTIV field. */ @@ -1377,7 +1390,7 @@ #define COMP_REFSEL_REFSEL_Int1V8 (1UL) /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V) */ #define COMP_REFSEL_REFSEL_Int2V4 (2UL) /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V) */ #define COMP_REFSEL_REFSEL_VDD (4UL) /*!< VREF = VDD */ -#define COMP_REFSEL_REFSEL_ARef (5UL) /*!< VREF = AREF (VDD >= VREF >= AREFMIN) */ +#define COMP_REFSEL_REFSEL_ARef (7UL) /*!< VREF = AREF (VDD >= VREF >= AREFMIN) */ /* Register: COMP_EXTREFSEL */ /* Description: External reference select */ @@ -1391,14 +1404,14 @@ /* Register: COMP_TH */ /* Description: Threshold configuration for hysteresis unit */ -/* Bits 13..8 : VDOWN = (THDOWN+1)/64*VREF */ -#define COMP_TH_THDOWN_Pos (8UL) /*!< Position of THDOWN field. */ -#define COMP_TH_THDOWN_Msk (0x3FUL << COMP_TH_THDOWN_Pos) /*!< Bit mask of THDOWN field. */ - -/* Bits 5..0 : VUP = (THUP+1)/64*VREF */ -#define COMP_TH_THUP_Pos (0UL) /*!< Position of THUP field. */ +/* Bits 13..8 : VUP = (THUP+1)/64*VREF */ +#define COMP_TH_THUP_Pos (8UL) /*!< Position of THUP field. */ #define COMP_TH_THUP_Msk (0x3FUL << COMP_TH_THUP_Pos) /*!< Bit mask of THUP field. */ +/* Bits 5..0 : VDOWN = (THDOWN+1)/64*VREF */ +#define COMP_TH_THDOWN_Pos (0UL) /*!< Position of THDOWN field. */ +#define COMP_TH_THDOWN_Msk (0x3FUL << COMP_TH_THDOWN_Pos) /*!< Bit mask of THDOWN field. */ + /* Register: COMP_MODE */ /* Description: Mode configuration */ @@ -1831,17 +1844,6 @@ #define FICR_CODESIZE_CODESIZE_Pos (0UL) /*!< Position of CODESIZE field. */ #define FICR_CODESIZE_CODESIZE_Msk (0xFFFFFFFFUL << FICR_CODESIZE_CODESIZE_Pos) /*!< Bit mask of CODESIZE field. */ -/* Register: FICR_CONFIGID */ -/* Description: Configuration identifier */ - -/* Bits 31..16 : Deprecated field - Identification number for the FW that is pre-loaded into the chip */ -#define FICR_CONFIGID_FWID_Pos (16UL) /*!< Position of FWID field. */ -#define FICR_CONFIGID_FWID_Msk (0xFFFFUL << FICR_CONFIGID_FWID_Pos) /*!< Bit mask of FWID field. */ - -/* Bits 15..0 : Identification number for the HW */ -#define FICR_CONFIGID_HWID_Pos (0UL) /*!< Position of HWID field. */ -#define FICR_CONFIGID_HWID_Msk (0xFFFFUL << FICR_CONFIGID_HWID_Pos) /*!< Bit mask of HWID field. */ - /* Register: FICR_DEVICEID */ /* Description: Description collection[0]: Device identifier */ @@ -1889,13 +1891,15 @@ #define FICR_INFO_PART_PART_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ /* Register: FICR_INFO_VARIANT */ -/* Description: Part variant */ +/* Description: Part Variant, Hardware version and Production configuration */ -/* Bits 31..0 : Part variant */ +/* Bits 31..0 : Part Variant, Hardware version and Production configuration, encoded as ASCII */ #define FICR_INFO_VARIANT_VARIANT_Pos (0UL) /*!< Position of VARIANT field. */ #define FICR_INFO_VARIANT_VARIANT_Msk (0xFFFFFFFFUL << FICR_INFO_VARIANT_VARIANT_Pos) /*!< Bit mask of VARIANT field. */ -#define FICR_INFO_VARIANT_VARIANT_nRF52AA (0x2000UL) /*!< nRF52832-AA (Engineering sample) */ -#define FICR_INFO_VARIANT_VARIANT_nRF52A0 (0x2001UL) /*!< nRF52832-A0 */ +#define FICR_INFO_VARIANT_VARIANT_AAAA (0x41414141UL) /*!< AAAA */ +#define FICR_INFO_VARIANT_VARIANT_AAAB (0x41414142UL) /*!< AAAB */ +#define FICR_INFO_VARIANT_VARIANT_AABA (0x41414241UL) /*!< AABA */ +#define FICR_INFO_VARIANT_VARIANT_AABB (0x41414242UL) /*!< AABB */ #define FICR_INFO_VARIANT_VARIANT_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ /* Register: FICR_INFO_PACKAGE */ @@ -1904,9 +1908,9 @@ /* Bits 31..0 : Package option */ #define FICR_INFO_PACKAGE_PACKAGE_Pos (0UL) /*!< Position of PACKAGE field. */ #define FICR_INFO_PACKAGE_PACKAGE_Msk (0xFFFFFFFFUL << FICR_INFO_PACKAGE_PACKAGE_Pos) /*!< Bit mask of PACKAGE field. */ -#define FICR_INFO_PACKAGE_PACKAGE_QFN48 (0x0000UL) /*!< 48-pin QFN with 31 GPIO */ -#define FICR_INFO_PACKAGE_PACKAGE_nRF52832QF (0x2000UL) /*!< nRF52832 QFxx - 48-pin QFN */ -#define FICR_INFO_PACKAGE_PACKAGE_nRF52832CH (0x2001UL) /*!< nRF52832 CHxx - 7x8 WLCSP 56 balls */ +#define FICR_INFO_PACKAGE_PACKAGE_QF (0x2000UL) /*!< QFxx - 48-pin QFN */ +#define FICR_INFO_PACKAGE_PACKAGE_CH (0x2001UL) /*!< CHxx - 7x8 WLCSP 56 balls */ +#define FICR_INFO_PACKAGE_PACKAGE_CI (0x2002UL) /*!< CIxx - 7x8 WLCSP 56 balls */ #define FICR_INFO_PACKAGE_PACKAGE_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ /* Register: FICR_INFO_RAM */ @@ -1915,9 +1919,9 @@ /* Bits 31..0 : RAM variant */ #define FICR_INFO_RAM_RAM_Pos (0UL) /*!< Position of RAM field. */ #define FICR_INFO_RAM_RAM_Msk (0xFFFFFFFFUL << FICR_INFO_RAM_RAM_Pos) /*!< Bit mask of RAM field. */ -#define FICR_INFO_RAM_RAM_K16 (16UL) /*!< 16 kByte RAM */ -#define FICR_INFO_RAM_RAM_K32 (32UL) /*!< 32 kByte RAM */ -#define FICR_INFO_RAM_RAM_K64 (64UL) /*!< 64 kByte RAM */ +#define FICR_INFO_RAM_RAM_K16 (0x10UL) /*!< 16 kByte RAM */ +#define FICR_INFO_RAM_RAM_K32 (0x20UL) /*!< 32 kByte RAM */ +#define FICR_INFO_RAM_RAM_K64 (0x40UL) /*!< 64 kByte RAM */ #define FICR_INFO_RAM_RAM_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ /* Register: FICR_INFO_FLASH */ @@ -1926,9 +1930,9 @@ /* Bits 31..0 : Flash variant */ #define FICR_INFO_FLASH_FLASH_Pos (0UL) /*!< Position of FLASH field. */ #define FICR_INFO_FLASH_FLASH_Msk (0xFFFFFFFFUL << FICR_INFO_FLASH_FLASH_Pos) /*!< Bit mask of FLASH field. */ -#define FICR_INFO_FLASH_FLASH_K128 (128UL) /*!< 128 kByte FLASH */ -#define FICR_INFO_FLASH_FLASH_K256 (256UL) /*!< 256 kByte FLASH */ -#define FICR_INFO_FLASH_FLASH_K512 (512UL) /*!< 512 kByte FLASH */ +#define FICR_INFO_FLASH_FLASH_K128 (0x80UL) /*!< 128 kByte FLASH */ +#define FICR_INFO_FLASH_FLASH_K256 (0x100UL) /*!< 256 kByte FLASH */ +#define FICR_INFO_FLASH_FLASH_K512 (0x200UL) /*!< 512 kByte FLASH */ #define FICR_INFO_FLASH_FLASH_Unspecified (0xFFFFFFFFUL) /*!< Unspecified */ /* Register: FICR_TEMP_A0 */ @@ -2369,8 +2373,8 @@ /* Bit 0 : Enable I2S module. */ #define I2S_ENABLE_ENABLE_Pos (0UL) /*!< Position of ENABLE field. */ #define I2S_ENABLE_ENABLE_Msk (0x1UL << I2S_ENABLE_ENABLE_Pos) /*!< Bit mask of ENABLE field. */ -#define I2S_ENABLE_ENABLE_DISABLE (0UL) /*!< Disabl */ -#define I2S_ENABLE_ENABLE_ENABLE (1UL) /*!< Enable */ +#define I2S_ENABLE_ENABLE_Disabled (0UL) /*!< Disable */ +#define I2S_ENABLE_ENABLE_Enabled (1UL) /*!< Enable */ /* Register: I2S_CONFIG_MODE */ /* Description: I2S mode. */ @@ -2378,8 +2382,8 @@ /* Bit 0 : I2S mode. */ #define I2S_CONFIG_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */ #define I2S_CONFIG_MODE_MODE_Msk (0x1UL << I2S_CONFIG_MODE_MODE_Pos) /*!< Bit mask of MODE field. */ -#define I2S_CONFIG_MODE_MODE_MASTER (0UL) /*!< Master mode. SCK and LRCK generated from internal master clcok (MCK) and output on pins defined by PSEL.xxx. */ -#define I2S_CONFIG_MODE_MODE_SLAVE (1UL) /*!< Slave mode. SCK and LRCK generated by external master and received on pins defined by PSEL.xxx */ +#define I2S_CONFIG_MODE_MODE_Master (0UL) /*!< Master mode. SCK and LRCK generated from internal master clcok (MCK) and output on pins defined by PSEL.xxx. */ +#define I2S_CONFIG_MODE_MODE_Slave (1UL) /*!< Slave mode. SCK and LRCK generated by external master and received on pins defined by PSEL.xxx */ /* Register: I2S_CONFIG_RXEN */ /* Description: Reception (RX) enable. */ @@ -2387,8 +2391,8 @@ /* Bit 0 : Reception (RX) enable. */ #define I2S_CONFIG_RXEN_RXEN_Pos (0UL) /*!< Position of RXEN field. */ #define I2S_CONFIG_RXEN_RXEN_Msk (0x1UL << I2S_CONFIG_RXEN_RXEN_Pos) /*!< Bit mask of RXEN field. */ -#define I2S_CONFIG_RXEN_RXEN_DISABLE (0UL) /*!< Reception disabled and now data will be written to the RXD.PTR address. */ -#define I2S_CONFIG_RXEN_RXEN_ENABLE (1UL) /*!< Reception enabled. */ +#define I2S_CONFIG_RXEN_RXEN_Disabled (0UL) /*!< Reception disabled and now data will be written to the RXD.PTR address. */ +#define I2S_CONFIG_RXEN_RXEN_Enabled (1UL) /*!< Reception enabled. */ /* Register: I2S_CONFIG_TXEN */ /* Description: Transmission (TX) enable. */ @@ -2396,8 +2400,8 @@ /* Bit 0 : Transmission (TX) enable. */ #define I2S_CONFIG_TXEN_TXEN_Pos (0UL) /*!< Position of TXEN field. */ #define I2S_CONFIG_TXEN_TXEN_Msk (0x1UL << I2S_CONFIG_TXEN_TXEN_Pos) /*!< Bit mask of TXEN field. */ -#define I2S_CONFIG_TXEN_TXEN_DISABLE (0UL) /*!< Transmission disabled and now data will be read from the RXD.TXD address. */ -#define I2S_CONFIG_TXEN_TXEN_ENABLE (1UL) /*!< Transmission enabled. */ +#define I2S_CONFIG_TXEN_TXEN_Disabled (0UL) /*!< Transmission disabled and now data will be read from the RXD.TXD address. */ +#define I2S_CONFIG_TXEN_TXEN_Enabled (1UL) /*!< Transmission enabled. */ /* Register: I2S_CONFIG_MCKEN */ /* Description: Master clock generator enable. */ @@ -2405,8 +2409,8 @@ /* Bit 0 : Master clock generator enable. */ #define I2S_CONFIG_MCKEN_MCKEN_Pos (0UL) /*!< Position of MCKEN field. */ #define I2S_CONFIG_MCKEN_MCKEN_Msk (0x1UL << I2S_CONFIG_MCKEN_MCKEN_Pos) /*!< Bit mask of MCKEN field. */ -#define I2S_CONFIG_MCKEN_MCKEN_DISABLE (0UL) /*!< Master clock generator disabled and PSEL.MCK not connected(available as GPIO). */ -#define I2S_CONFIG_MCKEN_MCKEN_ENABLE (1UL) /*!< Master clock generator running and MCK output on PSEL.MCK. */ +#define I2S_CONFIG_MCKEN_MCKEN_Disabled (0UL) /*!< Master clock generator disabled and PSEL.MCK not connected(available as GPIO). */ +#define I2S_CONFIG_MCKEN_MCKEN_Enabled (1UL) /*!< Master clock generator running and MCK output on PSEL.MCK. */ /* Register: I2S_CONFIG_MCKFREQ */ /* Description: Master clock generator frequency. */ @@ -2455,9 +2459,9 @@ /* Bits 1..0 : Sample width. */ #define I2S_CONFIG_SWIDTH_SWIDTH_Pos (0UL) /*!< Position of SWIDTH field. */ #define I2S_CONFIG_SWIDTH_SWIDTH_Msk (0x3UL << I2S_CONFIG_SWIDTH_SWIDTH_Pos) /*!< Bit mask of SWIDTH field. */ -#define I2S_CONFIG_SWIDTH_SWIDTH_8BIT (0UL) /*!< 8 bit. */ -#define I2S_CONFIG_SWIDTH_SWIDTH_16BIT (1UL) /*!< 16 bit. */ -#define I2S_CONFIG_SWIDTH_SWIDTH_24BIT (2UL) /*!< 24 bit. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_8Bit (0UL) /*!< 8 bit. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_16Bit (1UL) /*!< 16 bit. */ +#define I2S_CONFIG_SWIDTH_SWIDTH_24Bit (2UL) /*!< 24 bit. */ /* Register: I2S_CONFIG_ALIGN */ /* Description: Alignment of sample within a frame. */ @@ -2465,8 +2469,8 @@ /* Bit 0 : Alignment of sample within a frame. */ #define I2S_CONFIG_ALIGN_ALIGN_Pos (0UL) /*!< Position of ALIGN field. */ #define I2S_CONFIG_ALIGN_ALIGN_Msk (0x1UL << I2S_CONFIG_ALIGN_ALIGN_Pos) /*!< Bit mask of ALIGN field. */ -#define I2S_CONFIG_ALIGN_ALIGN_LEFT (0UL) /*!< Left-aligned. */ -#define I2S_CONFIG_ALIGN_ALIGN_RIGHT (1UL) /*!< Right-aligned. */ +#define I2S_CONFIG_ALIGN_ALIGN_Left (0UL) /*!< Left-aligned. */ +#define I2S_CONFIG_ALIGN_ALIGN_Right (1UL) /*!< Right-aligned. */ /* Register: I2S_CONFIG_FORMAT */ /* Description: Frame format. */ @@ -2475,7 +2479,7 @@ #define I2S_CONFIG_FORMAT_FORMAT_Pos (0UL) /*!< Position of FORMAT field. */ #define I2S_CONFIG_FORMAT_FORMAT_Msk (0x1UL << I2S_CONFIG_FORMAT_FORMAT_Pos) /*!< Bit mask of FORMAT field. */ #define I2S_CONFIG_FORMAT_FORMAT_I2S (0UL) /*!< Original I2S format. */ -#define I2S_CONFIG_FORMAT_FORMAT_ALIGNED (1UL) /*!< Alternate (left- or right-aligned) format. */ +#define I2S_CONFIG_FORMAT_FORMAT_Aligned (1UL) /*!< Alternate (left- or right-aligned) format. */ /* Register: I2S_CONFIG_CHANNELS */ /* Description: Enable channels. */ @@ -2483,9 +2487,9 @@ /* Bits 1..0 : Enable channels. */ #define I2S_CONFIG_CHANNELS_CHANNELS_Pos (0UL) /*!< Position of CHANNELS field. */ #define I2S_CONFIG_CHANNELS_CHANNELS_Msk (0x3UL << I2S_CONFIG_CHANNELS_CHANNELS_Pos) /*!< Bit mask of CHANNELS field. */ -#define I2S_CONFIG_CHANNELS_CHANNELS_STEREO (0UL) /*!< Stereo. */ -#define I2S_CONFIG_CHANNELS_CHANNELS_LEFT (1UL) /*!< Left only. */ -#define I2S_CONFIG_CHANNELS_CHANNELS_RIGHT (2UL) /*!< Right only. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Stereo (0UL) /*!< Stereo. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Left (1UL) /*!< Left only. */ +#define I2S_CONFIG_CHANNELS_CHANNELS_Right (2UL) /*!< Right only. */ /* Register: I2S_RXD_PTR */ /* Description: Receive buffer RAM start address. */ @@ -2678,7 +2682,7 @@ /* Bit 0 : Result of last compare. Decision point SAMPLE task. */ #define LPCOMP_RESULT_RESULT_Pos (0UL) /*!< Position of RESULT field. */ #define LPCOMP_RESULT_RESULT_Msk (0x1UL << LPCOMP_RESULT_RESULT_Pos) /*!< Bit mask of RESULT field. */ -#define LPCOMP_RESULT_RESULT_Bellow (0UL) /*!< Input voltage is below the reference threshold (VIN+ < VIN-). */ +#define LPCOMP_RESULT_RESULT_Below (0UL) /*!< Input voltage is below the reference threshold (VIN+ < VIN-). */ #define LPCOMP_RESULT_RESULT_Above (1UL) /*!< Input voltage is above the reference threshold (VIN+ > VIN-). */ /* Register: LPCOMP_ENABLE */ @@ -3907,7 +3911,7 @@ /* Register: MWU_REGION_END */ /* Description: Description cluster[0]: End address of region 0 */ -/* Bits 31..0 : End address of region. Value 0 has a special meaning, see below. */ +/* Bits 31..0 : End address of region. */ #define MWU_REGION_END_END_Pos (0UL) /*!< Position of END field. */ #define MWU_REGION_END_END_Msk (0xFFFFFFFFUL << MWU_REGION_END_END_Pos) /*!< Bit mask of END field. */ @@ -4451,10 +4455,6 @@ /* Register: NFCT_ERRORSTATUS */ /* Description: NFC Error Status register */ -/* Bit 6 : No valid End of Frame detected */ -#define NFCT_ERRORSTATUS_EOFERROR_Pos (6UL) /*!< Position of EOFERROR field. */ -#define NFCT_ERRORSTATUS_EOFERROR_Msk (0x1UL << NFCT_ERRORSTATUS_EOFERROR_Pos) /*!< Bit mask of EOFERROR field. */ - /* Bit 3 : Field level is too low at min load resistance */ #define NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Pos (3UL) /*!< Position of NFCFIELDTOOWEAK field. */ #define NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk (0x1UL << NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Pos) /*!< Bit mask of NFCFIELDTOOWEAK field. */ @@ -4463,10 +4463,6 @@ #define NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Pos (2UL) /*!< Position of NFCFIELDTOOSTRONG field. */ #define NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk (0x1UL << NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Pos) /*!< Bit mask of NFCFIELDTOOSTRONG field. */ -/* Bit 1 : The received pulse does not match a valid NFC-A symbol */ -#define NFCT_ERRORSTATUS_INVALIDNFCSYMBOL_Pos (1UL) /*!< Position of INVALIDNFCSYMBOL field. */ -#define NFCT_ERRORSTATUS_INVALIDNFCSYMBOL_Msk (0x1UL << NFCT_ERRORSTATUS_INVALIDNFCSYMBOL_Pos) /*!< Bit mask of INVALIDNFCSYMBOL field. */ - /* Bit 0 : No STARTTX task triggered before expiration of the time set in FRAMEDELAYMAX */ #define NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Pos (0UL) /*!< Position of FRAMEDELAYTIMEOUT field. */ #define NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk (0x1UL << NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Pos) /*!< Bit mask of FRAMEDELAYTIMEOUT field. */ @@ -4827,193 +4823,193 @@ /* Register: GPIO_OUT */ /* Description: Write GPIO port */ -/* Bit 31 : P0.31 pin */ +/* Bit 31 : Pin 31 */ #define GPIO_OUT_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ #define GPIO_OUT_PIN31_Msk (0x1UL << GPIO_OUT_PIN31_Pos) /*!< Bit mask of PIN31 field. */ #define GPIO_OUT_PIN31_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN31_High (1UL) /*!< Pin driver is high */ -/* Bit 30 : P0.30 pin */ +/* Bit 30 : Pin 30 */ #define GPIO_OUT_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ #define GPIO_OUT_PIN30_Msk (0x1UL << GPIO_OUT_PIN30_Pos) /*!< Bit mask of PIN30 field. */ #define GPIO_OUT_PIN30_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN30_High (1UL) /*!< Pin driver is high */ -/* Bit 29 : P0.29 pin */ +/* Bit 29 : Pin 29 */ #define GPIO_OUT_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ #define GPIO_OUT_PIN29_Msk (0x1UL << GPIO_OUT_PIN29_Pos) /*!< Bit mask of PIN29 field. */ #define GPIO_OUT_PIN29_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN29_High (1UL) /*!< Pin driver is high */ -/* Bit 28 : P0.28 pin */ +/* Bit 28 : Pin 28 */ #define GPIO_OUT_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ #define GPIO_OUT_PIN28_Msk (0x1UL << GPIO_OUT_PIN28_Pos) /*!< Bit mask of PIN28 field. */ #define GPIO_OUT_PIN28_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN28_High (1UL) /*!< Pin driver is high */ -/* Bit 27 : P0.27 pin */ +/* Bit 27 : Pin 27 */ #define GPIO_OUT_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ #define GPIO_OUT_PIN27_Msk (0x1UL << GPIO_OUT_PIN27_Pos) /*!< Bit mask of PIN27 field. */ #define GPIO_OUT_PIN27_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN27_High (1UL) /*!< Pin driver is high */ -/* Bit 26 : P0.26 pin */ +/* Bit 26 : Pin 26 */ #define GPIO_OUT_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ #define GPIO_OUT_PIN26_Msk (0x1UL << GPIO_OUT_PIN26_Pos) /*!< Bit mask of PIN26 field. */ #define GPIO_OUT_PIN26_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN26_High (1UL) /*!< Pin driver is high */ -/* Bit 25 : P0.25 pin */ +/* Bit 25 : Pin 25 */ #define GPIO_OUT_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ #define GPIO_OUT_PIN25_Msk (0x1UL << GPIO_OUT_PIN25_Pos) /*!< Bit mask of PIN25 field. */ #define GPIO_OUT_PIN25_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN25_High (1UL) /*!< Pin driver is high */ -/* Bit 24 : P0.24 pin */ +/* Bit 24 : Pin 24 */ #define GPIO_OUT_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ #define GPIO_OUT_PIN24_Msk (0x1UL << GPIO_OUT_PIN24_Pos) /*!< Bit mask of PIN24 field. */ #define GPIO_OUT_PIN24_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN24_High (1UL) /*!< Pin driver is high */ -/* Bit 23 : P0.23 pin */ +/* Bit 23 : Pin 23 */ #define GPIO_OUT_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ #define GPIO_OUT_PIN23_Msk (0x1UL << GPIO_OUT_PIN23_Pos) /*!< Bit mask of PIN23 field. */ #define GPIO_OUT_PIN23_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN23_High (1UL) /*!< Pin driver is high */ -/* Bit 22 : P0.22 pin */ +/* Bit 22 : Pin 22 */ #define GPIO_OUT_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ #define GPIO_OUT_PIN22_Msk (0x1UL << GPIO_OUT_PIN22_Pos) /*!< Bit mask of PIN22 field. */ #define GPIO_OUT_PIN22_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN22_High (1UL) /*!< Pin driver is high */ -/* Bit 21 : P0.21 pin */ +/* Bit 21 : Pin 21 */ #define GPIO_OUT_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ #define GPIO_OUT_PIN21_Msk (0x1UL << GPIO_OUT_PIN21_Pos) /*!< Bit mask of PIN21 field. */ #define GPIO_OUT_PIN21_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN21_High (1UL) /*!< Pin driver is high */ -/* Bit 20 : P0.20 pin */ +/* Bit 20 : Pin 20 */ #define GPIO_OUT_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ #define GPIO_OUT_PIN20_Msk (0x1UL << GPIO_OUT_PIN20_Pos) /*!< Bit mask of PIN20 field. */ #define GPIO_OUT_PIN20_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN20_High (1UL) /*!< Pin driver is high */ -/* Bit 19 : P0.19 pin */ +/* Bit 19 : Pin 19 */ #define GPIO_OUT_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ #define GPIO_OUT_PIN19_Msk (0x1UL << GPIO_OUT_PIN19_Pos) /*!< Bit mask of PIN19 field. */ #define GPIO_OUT_PIN19_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN19_High (1UL) /*!< Pin driver is high */ -/* Bit 18 : P0.18 pin */ +/* Bit 18 : Pin 18 */ #define GPIO_OUT_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ #define GPIO_OUT_PIN18_Msk (0x1UL << GPIO_OUT_PIN18_Pos) /*!< Bit mask of PIN18 field. */ #define GPIO_OUT_PIN18_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN18_High (1UL) /*!< Pin driver is high */ -/* Bit 17 : P0.17 pin */ +/* Bit 17 : Pin 17 */ #define GPIO_OUT_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ #define GPIO_OUT_PIN17_Msk (0x1UL << GPIO_OUT_PIN17_Pos) /*!< Bit mask of PIN17 field. */ #define GPIO_OUT_PIN17_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN17_High (1UL) /*!< Pin driver is high */ -/* Bit 16 : P0.16 pin */ +/* Bit 16 : Pin 16 */ #define GPIO_OUT_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ #define GPIO_OUT_PIN16_Msk (0x1UL << GPIO_OUT_PIN16_Pos) /*!< Bit mask of PIN16 field. */ #define GPIO_OUT_PIN16_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN16_High (1UL) /*!< Pin driver is high */ -/* Bit 15 : P0.15 pin */ +/* Bit 15 : Pin 15 */ #define GPIO_OUT_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ #define GPIO_OUT_PIN15_Msk (0x1UL << GPIO_OUT_PIN15_Pos) /*!< Bit mask of PIN15 field. */ #define GPIO_OUT_PIN15_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN15_High (1UL) /*!< Pin driver is high */ -/* Bit 14 : P0.14 pin */ +/* Bit 14 : Pin 14 */ #define GPIO_OUT_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ #define GPIO_OUT_PIN14_Msk (0x1UL << GPIO_OUT_PIN14_Pos) /*!< Bit mask of PIN14 field. */ #define GPIO_OUT_PIN14_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN14_High (1UL) /*!< Pin driver is high */ -/* Bit 13 : P0.13 pin */ +/* Bit 13 : Pin 13 */ #define GPIO_OUT_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ #define GPIO_OUT_PIN13_Msk (0x1UL << GPIO_OUT_PIN13_Pos) /*!< Bit mask of PIN13 field. */ #define GPIO_OUT_PIN13_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN13_High (1UL) /*!< Pin driver is high */ -/* Bit 12 : P0.12 pin */ +/* Bit 12 : Pin 12 */ #define GPIO_OUT_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ #define GPIO_OUT_PIN12_Msk (0x1UL << GPIO_OUT_PIN12_Pos) /*!< Bit mask of PIN12 field. */ #define GPIO_OUT_PIN12_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN12_High (1UL) /*!< Pin driver is high */ -/* Bit 11 : P0.11 pin */ +/* Bit 11 : Pin 11 */ #define GPIO_OUT_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ #define GPIO_OUT_PIN11_Msk (0x1UL << GPIO_OUT_PIN11_Pos) /*!< Bit mask of PIN11 field. */ #define GPIO_OUT_PIN11_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN11_High (1UL) /*!< Pin driver is high */ -/* Bit 10 : P0.10 pin */ +/* Bit 10 : Pin 10 */ #define GPIO_OUT_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ #define GPIO_OUT_PIN10_Msk (0x1UL << GPIO_OUT_PIN10_Pos) /*!< Bit mask of PIN10 field. */ #define GPIO_OUT_PIN10_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN10_High (1UL) /*!< Pin driver is high */ -/* Bit 9 : P0.9 pin */ +/* Bit 9 : Pin 9 */ #define GPIO_OUT_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ #define GPIO_OUT_PIN9_Msk (0x1UL << GPIO_OUT_PIN9_Pos) /*!< Bit mask of PIN9 field. */ #define GPIO_OUT_PIN9_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN9_High (1UL) /*!< Pin driver is high */ -/* Bit 8 : P0.8 pin */ +/* Bit 8 : Pin 8 */ #define GPIO_OUT_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ #define GPIO_OUT_PIN8_Msk (0x1UL << GPIO_OUT_PIN8_Pos) /*!< Bit mask of PIN8 field. */ #define GPIO_OUT_PIN8_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN8_High (1UL) /*!< Pin driver is high */ -/* Bit 7 : P0.7 pin */ +/* Bit 7 : Pin 7 */ #define GPIO_OUT_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ #define GPIO_OUT_PIN7_Msk (0x1UL << GPIO_OUT_PIN7_Pos) /*!< Bit mask of PIN7 field. */ #define GPIO_OUT_PIN7_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN7_High (1UL) /*!< Pin driver is high */ -/* Bit 6 : P0.6 pin */ +/* Bit 6 : Pin 6 */ #define GPIO_OUT_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ #define GPIO_OUT_PIN6_Msk (0x1UL << GPIO_OUT_PIN6_Pos) /*!< Bit mask of PIN6 field. */ #define GPIO_OUT_PIN6_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN6_High (1UL) /*!< Pin driver is high */ -/* Bit 5 : P0.5 pin */ +/* Bit 5 : Pin 5 */ #define GPIO_OUT_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ #define GPIO_OUT_PIN5_Msk (0x1UL << GPIO_OUT_PIN5_Pos) /*!< Bit mask of PIN5 field. */ #define GPIO_OUT_PIN5_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN5_High (1UL) /*!< Pin driver is high */ -/* Bit 4 : P0.4 pin */ +/* Bit 4 : Pin 4 */ #define GPIO_OUT_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ #define GPIO_OUT_PIN4_Msk (0x1UL << GPIO_OUT_PIN4_Pos) /*!< Bit mask of PIN4 field. */ #define GPIO_OUT_PIN4_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN4_High (1UL) /*!< Pin driver is high */ -/* Bit 3 : P0.3 pin */ +/* Bit 3 : Pin 3 */ #define GPIO_OUT_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ #define GPIO_OUT_PIN3_Msk (0x1UL << GPIO_OUT_PIN3_Pos) /*!< Bit mask of PIN3 field. */ #define GPIO_OUT_PIN3_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN3_High (1UL) /*!< Pin driver is high */ -/* Bit 2 : P0.2 pin */ +/* Bit 2 : Pin 2 */ #define GPIO_OUT_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ #define GPIO_OUT_PIN2_Msk (0x1UL << GPIO_OUT_PIN2_Pos) /*!< Bit mask of PIN2 field. */ #define GPIO_OUT_PIN2_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN2_High (1UL) /*!< Pin driver is high */ -/* Bit 1 : P0.1 pin */ +/* Bit 1 : Pin 1 */ #define GPIO_OUT_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ #define GPIO_OUT_PIN1_Msk (0x1UL << GPIO_OUT_PIN1_Pos) /*!< Bit mask of PIN1 field. */ #define GPIO_OUT_PIN1_Low (0UL) /*!< Pin driver is low */ #define GPIO_OUT_PIN1_High (1UL) /*!< Pin driver is high */ -/* Bit 0 : P0.0 pin */ +/* Bit 0 : Pin 0 */ #define GPIO_OUT_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ #define GPIO_OUT_PIN0_Msk (0x1UL << GPIO_OUT_PIN0_Pos) /*!< Bit mask of PIN0 field. */ #define GPIO_OUT_PIN0_Low (0UL) /*!< Pin driver is low */ @@ -5022,224 +5018,224 @@ /* Register: GPIO_OUTSET */ /* Description: Set individual bits in GPIO port */ -/* Bit 31 : P0.31 pin */ +/* Bit 31 : Pin 31 */ #define GPIO_OUTSET_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ #define GPIO_OUTSET_PIN31_Msk (0x1UL << GPIO_OUTSET_PIN31_Pos) /*!< Bit mask of PIN31 field. */ #define GPIO_OUTSET_PIN31_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN31_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN31_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 30 : P0.30 pin */ +/* Bit 30 : Pin 30 */ #define GPIO_OUTSET_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ #define GPIO_OUTSET_PIN30_Msk (0x1UL << GPIO_OUTSET_PIN30_Pos) /*!< Bit mask of PIN30 field. */ #define GPIO_OUTSET_PIN30_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN30_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN30_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 29 : P0.29 pin */ +/* Bit 29 : Pin 29 */ #define GPIO_OUTSET_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ #define GPIO_OUTSET_PIN29_Msk (0x1UL << GPIO_OUTSET_PIN29_Pos) /*!< Bit mask of PIN29 field. */ #define GPIO_OUTSET_PIN29_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN29_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN29_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 28 : P0.28 pin */ +/* Bit 28 : Pin 28 */ #define GPIO_OUTSET_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ #define GPIO_OUTSET_PIN28_Msk (0x1UL << GPIO_OUTSET_PIN28_Pos) /*!< Bit mask of PIN28 field. */ #define GPIO_OUTSET_PIN28_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN28_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN28_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 27 : P0.27 pin */ +/* Bit 27 : Pin 27 */ #define GPIO_OUTSET_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ #define GPIO_OUTSET_PIN27_Msk (0x1UL << GPIO_OUTSET_PIN27_Pos) /*!< Bit mask of PIN27 field. */ #define GPIO_OUTSET_PIN27_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN27_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN27_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 26 : P0.26 pin */ +/* Bit 26 : Pin 26 */ #define GPIO_OUTSET_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ #define GPIO_OUTSET_PIN26_Msk (0x1UL << GPIO_OUTSET_PIN26_Pos) /*!< Bit mask of PIN26 field. */ #define GPIO_OUTSET_PIN26_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN26_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN26_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 25 : P0.25 pin */ +/* Bit 25 : Pin 25 */ #define GPIO_OUTSET_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ #define GPIO_OUTSET_PIN25_Msk (0x1UL << GPIO_OUTSET_PIN25_Pos) /*!< Bit mask of PIN25 field. */ #define GPIO_OUTSET_PIN25_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN25_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN25_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 24 : P0.24 pin */ +/* Bit 24 : Pin 24 */ #define GPIO_OUTSET_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ #define GPIO_OUTSET_PIN24_Msk (0x1UL << GPIO_OUTSET_PIN24_Pos) /*!< Bit mask of PIN24 field. */ #define GPIO_OUTSET_PIN24_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN24_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN24_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 23 : P0.23 pin */ +/* Bit 23 : Pin 23 */ #define GPIO_OUTSET_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ #define GPIO_OUTSET_PIN23_Msk (0x1UL << GPIO_OUTSET_PIN23_Pos) /*!< Bit mask of PIN23 field. */ #define GPIO_OUTSET_PIN23_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN23_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN23_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 22 : P0.22 pin */ +/* Bit 22 : Pin 22 */ #define GPIO_OUTSET_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ #define GPIO_OUTSET_PIN22_Msk (0x1UL << GPIO_OUTSET_PIN22_Pos) /*!< Bit mask of PIN22 field. */ #define GPIO_OUTSET_PIN22_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN22_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN22_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 21 : P0.21 pin */ +/* Bit 21 : Pin 21 */ #define GPIO_OUTSET_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ #define GPIO_OUTSET_PIN21_Msk (0x1UL << GPIO_OUTSET_PIN21_Pos) /*!< Bit mask of PIN21 field. */ #define GPIO_OUTSET_PIN21_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN21_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN21_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 20 : P0.20 pin */ +/* Bit 20 : Pin 20 */ #define GPIO_OUTSET_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ #define GPIO_OUTSET_PIN20_Msk (0x1UL << GPIO_OUTSET_PIN20_Pos) /*!< Bit mask of PIN20 field. */ #define GPIO_OUTSET_PIN20_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN20_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN20_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 19 : P0.19 pin */ +/* Bit 19 : Pin 19 */ #define GPIO_OUTSET_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ #define GPIO_OUTSET_PIN19_Msk (0x1UL << GPIO_OUTSET_PIN19_Pos) /*!< Bit mask of PIN19 field. */ #define GPIO_OUTSET_PIN19_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN19_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN19_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 18 : P0.18 pin */ +/* Bit 18 : Pin 18 */ #define GPIO_OUTSET_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ #define GPIO_OUTSET_PIN18_Msk (0x1UL << GPIO_OUTSET_PIN18_Pos) /*!< Bit mask of PIN18 field. */ #define GPIO_OUTSET_PIN18_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN18_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN18_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 17 : P0.17 pin */ +/* Bit 17 : Pin 17 */ #define GPIO_OUTSET_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ #define GPIO_OUTSET_PIN17_Msk (0x1UL << GPIO_OUTSET_PIN17_Pos) /*!< Bit mask of PIN17 field. */ #define GPIO_OUTSET_PIN17_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN17_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN17_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 16 : P0.16 pin */ +/* Bit 16 : Pin 16 */ #define GPIO_OUTSET_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ #define GPIO_OUTSET_PIN16_Msk (0x1UL << GPIO_OUTSET_PIN16_Pos) /*!< Bit mask of PIN16 field. */ #define GPIO_OUTSET_PIN16_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN16_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN16_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 15 : P0.15 pin */ +/* Bit 15 : Pin 15 */ #define GPIO_OUTSET_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ #define GPIO_OUTSET_PIN15_Msk (0x1UL << GPIO_OUTSET_PIN15_Pos) /*!< Bit mask of PIN15 field. */ #define GPIO_OUTSET_PIN15_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN15_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN15_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 14 : P0.14 pin */ +/* Bit 14 : Pin 14 */ #define GPIO_OUTSET_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ #define GPIO_OUTSET_PIN14_Msk (0x1UL << GPIO_OUTSET_PIN14_Pos) /*!< Bit mask of PIN14 field. */ #define GPIO_OUTSET_PIN14_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN14_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN14_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 13 : P0.13 pin */ +/* Bit 13 : Pin 13 */ #define GPIO_OUTSET_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ #define GPIO_OUTSET_PIN13_Msk (0x1UL << GPIO_OUTSET_PIN13_Pos) /*!< Bit mask of PIN13 field. */ #define GPIO_OUTSET_PIN13_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN13_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN13_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 12 : P0.12 pin */ +/* Bit 12 : Pin 12 */ #define GPIO_OUTSET_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ #define GPIO_OUTSET_PIN12_Msk (0x1UL << GPIO_OUTSET_PIN12_Pos) /*!< Bit mask of PIN12 field. */ #define GPIO_OUTSET_PIN12_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN12_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN12_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 11 : P0.11 pin */ +/* Bit 11 : Pin 11 */ #define GPIO_OUTSET_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ #define GPIO_OUTSET_PIN11_Msk (0x1UL << GPIO_OUTSET_PIN11_Pos) /*!< Bit mask of PIN11 field. */ #define GPIO_OUTSET_PIN11_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN11_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN11_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 10 : P0.10 pin */ +/* Bit 10 : Pin 10 */ #define GPIO_OUTSET_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ #define GPIO_OUTSET_PIN10_Msk (0x1UL << GPIO_OUTSET_PIN10_Pos) /*!< Bit mask of PIN10 field. */ #define GPIO_OUTSET_PIN10_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN10_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN10_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 9 : P0.9 pin */ +/* Bit 9 : Pin 9 */ #define GPIO_OUTSET_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ #define GPIO_OUTSET_PIN9_Msk (0x1UL << GPIO_OUTSET_PIN9_Pos) /*!< Bit mask of PIN9 field. */ #define GPIO_OUTSET_PIN9_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN9_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN9_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 8 : P0.8 pin */ +/* Bit 8 : Pin 8 */ #define GPIO_OUTSET_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ #define GPIO_OUTSET_PIN8_Msk (0x1UL << GPIO_OUTSET_PIN8_Pos) /*!< Bit mask of PIN8 field. */ #define GPIO_OUTSET_PIN8_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN8_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN8_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 7 : P0.7 pin */ +/* Bit 7 : Pin 7 */ #define GPIO_OUTSET_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ #define GPIO_OUTSET_PIN7_Msk (0x1UL << GPIO_OUTSET_PIN7_Pos) /*!< Bit mask of PIN7 field. */ #define GPIO_OUTSET_PIN7_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN7_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN7_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 6 : P0.6 pin */ +/* Bit 6 : Pin 6 */ #define GPIO_OUTSET_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ #define GPIO_OUTSET_PIN6_Msk (0x1UL << GPIO_OUTSET_PIN6_Pos) /*!< Bit mask of PIN6 field. */ #define GPIO_OUTSET_PIN6_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN6_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN6_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 5 : P0.5 pin */ +/* Bit 5 : Pin 5 */ #define GPIO_OUTSET_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ #define GPIO_OUTSET_PIN5_Msk (0x1UL << GPIO_OUTSET_PIN5_Pos) /*!< Bit mask of PIN5 field. */ #define GPIO_OUTSET_PIN5_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN5_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN5_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 4 : P0.4 pin */ +/* Bit 4 : Pin 4 */ #define GPIO_OUTSET_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ #define GPIO_OUTSET_PIN4_Msk (0x1UL << GPIO_OUTSET_PIN4_Pos) /*!< Bit mask of PIN4 field. */ #define GPIO_OUTSET_PIN4_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN4_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN4_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 3 : P0.3 pin */ +/* Bit 3 : Pin 3 */ #define GPIO_OUTSET_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ #define GPIO_OUTSET_PIN3_Msk (0x1UL << GPIO_OUTSET_PIN3_Pos) /*!< Bit mask of PIN3 field. */ #define GPIO_OUTSET_PIN3_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN3_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN3_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 2 : P0.2 pin */ +/* Bit 2 : Pin 2 */ #define GPIO_OUTSET_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ #define GPIO_OUTSET_PIN2_Msk (0x1UL << GPIO_OUTSET_PIN2_Pos) /*!< Bit mask of PIN2 field. */ #define GPIO_OUTSET_PIN2_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN2_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN2_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 1 : P0.1 pin */ +/* Bit 1 : Pin 1 */ #define GPIO_OUTSET_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ #define GPIO_OUTSET_PIN1_Msk (0x1UL << GPIO_OUTSET_PIN1_Pos) /*!< Bit mask of PIN1 field. */ #define GPIO_OUTSET_PIN1_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTSET_PIN1_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTSET_PIN1_Set (1UL) /*!< Write: writing a '1' sets the pin high; writing a '0' has no effect */ -/* Bit 0 : P0.0 pin */ +/* Bit 0 : Pin 0 */ #define GPIO_OUTSET_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ #define GPIO_OUTSET_PIN0_Msk (0x1UL << GPIO_OUTSET_PIN0_Pos) /*!< Bit mask of PIN0 field. */ #define GPIO_OUTSET_PIN0_Low (0UL) /*!< Read: pin driver is low */ @@ -5249,224 +5245,224 @@ /* Register: GPIO_OUTCLR */ /* Description: Clear individual bits in GPIO port */ -/* Bit 31 : P0.31 pin */ +/* Bit 31 : Pin 31 */ #define GPIO_OUTCLR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ #define GPIO_OUTCLR_PIN31_Msk (0x1UL << GPIO_OUTCLR_PIN31_Pos) /*!< Bit mask of PIN31 field. */ #define GPIO_OUTCLR_PIN31_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN31_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN31_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 30 : P0.30 pin */ +/* Bit 30 : Pin 30 */ #define GPIO_OUTCLR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ #define GPIO_OUTCLR_PIN30_Msk (0x1UL << GPIO_OUTCLR_PIN30_Pos) /*!< Bit mask of PIN30 field. */ #define GPIO_OUTCLR_PIN30_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN30_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN30_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 29 : P0.29 pin */ +/* Bit 29 : Pin 29 */ #define GPIO_OUTCLR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ #define GPIO_OUTCLR_PIN29_Msk (0x1UL << GPIO_OUTCLR_PIN29_Pos) /*!< Bit mask of PIN29 field. */ #define GPIO_OUTCLR_PIN29_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN29_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN29_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 28 : P0.28 pin */ +/* Bit 28 : Pin 28 */ #define GPIO_OUTCLR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ #define GPIO_OUTCLR_PIN28_Msk (0x1UL << GPIO_OUTCLR_PIN28_Pos) /*!< Bit mask of PIN28 field. */ #define GPIO_OUTCLR_PIN28_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN28_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN28_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 27 : P0.27 pin */ +/* Bit 27 : Pin 27 */ #define GPIO_OUTCLR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ #define GPIO_OUTCLR_PIN27_Msk (0x1UL << GPIO_OUTCLR_PIN27_Pos) /*!< Bit mask of PIN27 field. */ #define GPIO_OUTCLR_PIN27_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN27_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN27_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 26 : P0.26 pin */ +/* Bit 26 : Pin 26 */ #define GPIO_OUTCLR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ #define GPIO_OUTCLR_PIN26_Msk (0x1UL << GPIO_OUTCLR_PIN26_Pos) /*!< Bit mask of PIN26 field. */ #define GPIO_OUTCLR_PIN26_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN26_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN26_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 25 : P0.25 pin */ +/* Bit 25 : Pin 25 */ #define GPIO_OUTCLR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ #define GPIO_OUTCLR_PIN25_Msk (0x1UL << GPIO_OUTCLR_PIN25_Pos) /*!< Bit mask of PIN25 field. */ #define GPIO_OUTCLR_PIN25_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN25_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN25_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 24 : P0.24 pin */ +/* Bit 24 : Pin 24 */ #define GPIO_OUTCLR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ #define GPIO_OUTCLR_PIN24_Msk (0x1UL << GPIO_OUTCLR_PIN24_Pos) /*!< Bit mask of PIN24 field. */ #define GPIO_OUTCLR_PIN24_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN24_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN24_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 23 : P0.23 pin */ +/* Bit 23 : Pin 23 */ #define GPIO_OUTCLR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ #define GPIO_OUTCLR_PIN23_Msk (0x1UL << GPIO_OUTCLR_PIN23_Pos) /*!< Bit mask of PIN23 field. */ #define GPIO_OUTCLR_PIN23_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN23_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN23_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 22 : P0.22 pin */ +/* Bit 22 : Pin 22 */ #define GPIO_OUTCLR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ #define GPIO_OUTCLR_PIN22_Msk (0x1UL << GPIO_OUTCLR_PIN22_Pos) /*!< Bit mask of PIN22 field. */ #define GPIO_OUTCLR_PIN22_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN22_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN22_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 21 : P0.21 pin */ +/* Bit 21 : Pin 21 */ #define GPIO_OUTCLR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ #define GPIO_OUTCLR_PIN21_Msk (0x1UL << GPIO_OUTCLR_PIN21_Pos) /*!< Bit mask of PIN21 field. */ #define GPIO_OUTCLR_PIN21_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN21_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN21_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 20 : P0.20 pin */ +/* Bit 20 : Pin 20 */ #define GPIO_OUTCLR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ #define GPIO_OUTCLR_PIN20_Msk (0x1UL << GPIO_OUTCLR_PIN20_Pos) /*!< Bit mask of PIN20 field. */ #define GPIO_OUTCLR_PIN20_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN20_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN20_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 19 : P0.19 pin */ +/* Bit 19 : Pin 19 */ #define GPIO_OUTCLR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ #define GPIO_OUTCLR_PIN19_Msk (0x1UL << GPIO_OUTCLR_PIN19_Pos) /*!< Bit mask of PIN19 field. */ #define GPIO_OUTCLR_PIN19_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN19_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN19_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 18 : P0.18 pin */ +/* Bit 18 : Pin 18 */ #define GPIO_OUTCLR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ #define GPIO_OUTCLR_PIN18_Msk (0x1UL << GPIO_OUTCLR_PIN18_Pos) /*!< Bit mask of PIN18 field. */ #define GPIO_OUTCLR_PIN18_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN18_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN18_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 17 : P0.17 pin */ +/* Bit 17 : Pin 17 */ #define GPIO_OUTCLR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ #define GPIO_OUTCLR_PIN17_Msk (0x1UL << GPIO_OUTCLR_PIN17_Pos) /*!< Bit mask of PIN17 field. */ #define GPIO_OUTCLR_PIN17_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN17_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN17_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 16 : P0.16 pin */ +/* Bit 16 : Pin 16 */ #define GPIO_OUTCLR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ #define GPIO_OUTCLR_PIN16_Msk (0x1UL << GPIO_OUTCLR_PIN16_Pos) /*!< Bit mask of PIN16 field. */ #define GPIO_OUTCLR_PIN16_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN16_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN16_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 15 : P0.15 pin */ +/* Bit 15 : Pin 15 */ #define GPIO_OUTCLR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ #define GPIO_OUTCLR_PIN15_Msk (0x1UL << GPIO_OUTCLR_PIN15_Pos) /*!< Bit mask of PIN15 field. */ #define GPIO_OUTCLR_PIN15_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN15_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN15_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 14 : P0.14 pin */ +/* Bit 14 : Pin 14 */ #define GPIO_OUTCLR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ #define GPIO_OUTCLR_PIN14_Msk (0x1UL << GPIO_OUTCLR_PIN14_Pos) /*!< Bit mask of PIN14 field. */ #define GPIO_OUTCLR_PIN14_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN14_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN14_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 13 : P0.13 pin */ +/* Bit 13 : Pin 13 */ #define GPIO_OUTCLR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ #define GPIO_OUTCLR_PIN13_Msk (0x1UL << GPIO_OUTCLR_PIN13_Pos) /*!< Bit mask of PIN13 field. */ #define GPIO_OUTCLR_PIN13_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN13_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN13_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 12 : P0.12 pin */ +/* Bit 12 : Pin 12 */ #define GPIO_OUTCLR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ #define GPIO_OUTCLR_PIN12_Msk (0x1UL << GPIO_OUTCLR_PIN12_Pos) /*!< Bit mask of PIN12 field. */ #define GPIO_OUTCLR_PIN12_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN12_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN12_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 11 : P0.11 pin */ +/* Bit 11 : Pin 11 */ #define GPIO_OUTCLR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ #define GPIO_OUTCLR_PIN11_Msk (0x1UL << GPIO_OUTCLR_PIN11_Pos) /*!< Bit mask of PIN11 field. */ #define GPIO_OUTCLR_PIN11_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN11_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN11_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 10 : P0.10 pin */ +/* Bit 10 : Pin 10 */ #define GPIO_OUTCLR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ #define GPIO_OUTCLR_PIN10_Msk (0x1UL << GPIO_OUTCLR_PIN10_Pos) /*!< Bit mask of PIN10 field. */ #define GPIO_OUTCLR_PIN10_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN10_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN10_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 9 : P0.9 pin */ +/* Bit 9 : Pin 9 */ #define GPIO_OUTCLR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ #define GPIO_OUTCLR_PIN9_Msk (0x1UL << GPIO_OUTCLR_PIN9_Pos) /*!< Bit mask of PIN9 field. */ #define GPIO_OUTCLR_PIN9_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN9_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN9_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 8 : P0.8 pin */ +/* Bit 8 : Pin 8 */ #define GPIO_OUTCLR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ #define GPIO_OUTCLR_PIN8_Msk (0x1UL << GPIO_OUTCLR_PIN8_Pos) /*!< Bit mask of PIN8 field. */ #define GPIO_OUTCLR_PIN8_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN8_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN8_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 7 : P0.7 pin */ +/* Bit 7 : Pin 7 */ #define GPIO_OUTCLR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ #define GPIO_OUTCLR_PIN7_Msk (0x1UL << GPIO_OUTCLR_PIN7_Pos) /*!< Bit mask of PIN7 field. */ #define GPIO_OUTCLR_PIN7_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN7_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN7_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 6 : P0.6 pin */ +/* Bit 6 : Pin 6 */ #define GPIO_OUTCLR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ #define GPIO_OUTCLR_PIN6_Msk (0x1UL << GPIO_OUTCLR_PIN6_Pos) /*!< Bit mask of PIN6 field. */ #define GPIO_OUTCLR_PIN6_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN6_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN6_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 5 : P0.5 pin */ +/* Bit 5 : Pin 5 */ #define GPIO_OUTCLR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ #define GPIO_OUTCLR_PIN5_Msk (0x1UL << GPIO_OUTCLR_PIN5_Pos) /*!< Bit mask of PIN5 field. */ #define GPIO_OUTCLR_PIN5_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN5_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN5_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 4 : P0.4 pin */ +/* Bit 4 : Pin 4 */ #define GPIO_OUTCLR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ #define GPIO_OUTCLR_PIN4_Msk (0x1UL << GPIO_OUTCLR_PIN4_Pos) /*!< Bit mask of PIN4 field. */ #define GPIO_OUTCLR_PIN4_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN4_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN4_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 3 : P0.3 pin */ +/* Bit 3 : Pin 3 */ #define GPIO_OUTCLR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ #define GPIO_OUTCLR_PIN3_Msk (0x1UL << GPIO_OUTCLR_PIN3_Pos) /*!< Bit mask of PIN3 field. */ #define GPIO_OUTCLR_PIN3_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN3_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN3_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 2 : P0.2 pin */ +/* Bit 2 : Pin 2 */ #define GPIO_OUTCLR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ #define GPIO_OUTCLR_PIN2_Msk (0x1UL << GPIO_OUTCLR_PIN2_Pos) /*!< Bit mask of PIN2 field. */ #define GPIO_OUTCLR_PIN2_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN2_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN2_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 1 : P0.1 pin */ +/* Bit 1 : Pin 1 */ #define GPIO_OUTCLR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ #define GPIO_OUTCLR_PIN1_Msk (0x1UL << GPIO_OUTCLR_PIN1_Pos) /*!< Bit mask of PIN1 field. */ #define GPIO_OUTCLR_PIN1_Low (0UL) /*!< Read: pin driver is low */ #define GPIO_OUTCLR_PIN1_High (1UL) /*!< Read: pin driver is high */ #define GPIO_OUTCLR_PIN1_Clear (1UL) /*!< Write: writing a '1' sets the pin low; writing a '0' has no effect */ -/* Bit 0 : P0.0 pin */ +/* Bit 0 : Pin 0 */ #define GPIO_OUTCLR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ #define GPIO_OUTCLR_PIN0_Msk (0x1UL << GPIO_OUTCLR_PIN0_Pos) /*!< Bit mask of PIN0 field. */ #define GPIO_OUTCLR_PIN0_Low (0UL) /*!< Read: pin driver is low */ @@ -5476,193 +5472,193 @@ /* Register: GPIO_IN */ /* Description: Read GPIO port */ -/* Bit 31 : P0.31 pin */ +/* Bit 31 : Pin 31 */ #define GPIO_IN_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ #define GPIO_IN_PIN31_Msk (0x1UL << GPIO_IN_PIN31_Pos) /*!< Bit mask of PIN31 field. */ #define GPIO_IN_PIN31_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN31_High (1UL) /*!< Pin input is high */ -/* Bit 30 : P0.30 pin */ +/* Bit 30 : Pin 30 */ #define GPIO_IN_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ #define GPIO_IN_PIN30_Msk (0x1UL << GPIO_IN_PIN30_Pos) /*!< Bit mask of PIN30 field. */ #define GPIO_IN_PIN30_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN30_High (1UL) /*!< Pin input is high */ -/* Bit 29 : P0.29 pin */ +/* Bit 29 : Pin 29 */ #define GPIO_IN_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ #define GPIO_IN_PIN29_Msk (0x1UL << GPIO_IN_PIN29_Pos) /*!< Bit mask of PIN29 field. */ #define GPIO_IN_PIN29_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN29_High (1UL) /*!< Pin input is high */ -/* Bit 28 : P0.28 pin */ +/* Bit 28 : Pin 28 */ #define GPIO_IN_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ #define GPIO_IN_PIN28_Msk (0x1UL << GPIO_IN_PIN28_Pos) /*!< Bit mask of PIN28 field. */ #define GPIO_IN_PIN28_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN28_High (1UL) /*!< Pin input is high */ -/* Bit 27 : P0.27 pin */ +/* Bit 27 : Pin 27 */ #define GPIO_IN_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ #define GPIO_IN_PIN27_Msk (0x1UL << GPIO_IN_PIN27_Pos) /*!< Bit mask of PIN27 field. */ #define GPIO_IN_PIN27_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN27_High (1UL) /*!< Pin input is high */ -/* Bit 26 : P0.26 pin */ +/* Bit 26 : Pin 26 */ #define GPIO_IN_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ #define GPIO_IN_PIN26_Msk (0x1UL << GPIO_IN_PIN26_Pos) /*!< Bit mask of PIN26 field. */ #define GPIO_IN_PIN26_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN26_High (1UL) /*!< Pin input is high */ -/* Bit 25 : P0.25 pin */ +/* Bit 25 : Pin 25 */ #define GPIO_IN_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ #define GPIO_IN_PIN25_Msk (0x1UL << GPIO_IN_PIN25_Pos) /*!< Bit mask of PIN25 field. */ #define GPIO_IN_PIN25_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN25_High (1UL) /*!< Pin input is high */ -/* Bit 24 : P0.24 pin */ +/* Bit 24 : Pin 24 */ #define GPIO_IN_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ #define GPIO_IN_PIN24_Msk (0x1UL << GPIO_IN_PIN24_Pos) /*!< Bit mask of PIN24 field. */ #define GPIO_IN_PIN24_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN24_High (1UL) /*!< Pin input is high */ -/* Bit 23 : P0.23 pin */ +/* Bit 23 : Pin 23 */ #define GPIO_IN_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ #define GPIO_IN_PIN23_Msk (0x1UL << GPIO_IN_PIN23_Pos) /*!< Bit mask of PIN23 field. */ #define GPIO_IN_PIN23_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN23_High (1UL) /*!< Pin input is high */ -/* Bit 22 : P0.22 pin */ +/* Bit 22 : Pin 22 */ #define GPIO_IN_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ #define GPIO_IN_PIN22_Msk (0x1UL << GPIO_IN_PIN22_Pos) /*!< Bit mask of PIN22 field. */ #define GPIO_IN_PIN22_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN22_High (1UL) /*!< Pin input is high */ -/* Bit 21 : P0.21 pin */ +/* Bit 21 : Pin 21 */ #define GPIO_IN_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ #define GPIO_IN_PIN21_Msk (0x1UL << GPIO_IN_PIN21_Pos) /*!< Bit mask of PIN21 field. */ #define GPIO_IN_PIN21_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN21_High (1UL) /*!< Pin input is high */ -/* Bit 20 : P0.20 pin */ +/* Bit 20 : Pin 20 */ #define GPIO_IN_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ #define GPIO_IN_PIN20_Msk (0x1UL << GPIO_IN_PIN20_Pos) /*!< Bit mask of PIN20 field. */ #define GPIO_IN_PIN20_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN20_High (1UL) /*!< Pin input is high */ -/* Bit 19 : P0.19 pin */ +/* Bit 19 : Pin 19 */ #define GPIO_IN_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ #define GPIO_IN_PIN19_Msk (0x1UL << GPIO_IN_PIN19_Pos) /*!< Bit mask of PIN19 field. */ #define GPIO_IN_PIN19_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN19_High (1UL) /*!< Pin input is high */ -/* Bit 18 : P0.18 pin */ +/* Bit 18 : Pin 18 */ #define GPIO_IN_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ #define GPIO_IN_PIN18_Msk (0x1UL << GPIO_IN_PIN18_Pos) /*!< Bit mask of PIN18 field. */ #define GPIO_IN_PIN18_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN18_High (1UL) /*!< Pin input is high */ -/* Bit 17 : P0.17 pin */ +/* Bit 17 : Pin 17 */ #define GPIO_IN_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ #define GPIO_IN_PIN17_Msk (0x1UL << GPIO_IN_PIN17_Pos) /*!< Bit mask of PIN17 field. */ #define GPIO_IN_PIN17_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN17_High (1UL) /*!< Pin input is high */ -/* Bit 16 : P0.16 pin */ +/* Bit 16 : Pin 16 */ #define GPIO_IN_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ #define GPIO_IN_PIN16_Msk (0x1UL << GPIO_IN_PIN16_Pos) /*!< Bit mask of PIN16 field. */ #define GPIO_IN_PIN16_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN16_High (1UL) /*!< Pin input is high */ -/* Bit 15 : P0.15 pin */ +/* Bit 15 : Pin 15 */ #define GPIO_IN_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ #define GPIO_IN_PIN15_Msk (0x1UL << GPIO_IN_PIN15_Pos) /*!< Bit mask of PIN15 field. */ #define GPIO_IN_PIN15_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN15_High (1UL) /*!< Pin input is high */ -/* Bit 14 : P0.14 pin */ +/* Bit 14 : Pin 14 */ #define GPIO_IN_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ #define GPIO_IN_PIN14_Msk (0x1UL << GPIO_IN_PIN14_Pos) /*!< Bit mask of PIN14 field. */ #define GPIO_IN_PIN14_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN14_High (1UL) /*!< Pin input is high */ -/* Bit 13 : P0.13 pin */ +/* Bit 13 : Pin 13 */ #define GPIO_IN_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ #define GPIO_IN_PIN13_Msk (0x1UL << GPIO_IN_PIN13_Pos) /*!< Bit mask of PIN13 field. */ #define GPIO_IN_PIN13_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN13_High (1UL) /*!< Pin input is high */ -/* Bit 12 : P0.12 pin */ +/* Bit 12 : Pin 12 */ #define GPIO_IN_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ #define GPIO_IN_PIN12_Msk (0x1UL << GPIO_IN_PIN12_Pos) /*!< Bit mask of PIN12 field. */ #define GPIO_IN_PIN12_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN12_High (1UL) /*!< Pin input is high */ -/* Bit 11 : P0.11 pin */ +/* Bit 11 : Pin 11 */ #define GPIO_IN_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ #define GPIO_IN_PIN11_Msk (0x1UL << GPIO_IN_PIN11_Pos) /*!< Bit mask of PIN11 field. */ #define GPIO_IN_PIN11_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN11_High (1UL) /*!< Pin input is high */ -/* Bit 10 : P0.10 pin */ +/* Bit 10 : Pin 10 */ #define GPIO_IN_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ #define GPIO_IN_PIN10_Msk (0x1UL << GPIO_IN_PIN10_Pos) /*!< Bit mask of PIN10 field. */ #define GPIO_IN_PIN10_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN10_High (1UL) /*!< Pin input is high */ -/* Bit 9 : P0.9 pin */ +/* Bit 9 : Pin 9 */ #define GPIO_IN_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ #define GPIO_IN_PIN9_Msk (0x1UL << GPIO_IN_PIN9_Pos) /*!< Bit mask of PIN9 field. */ #define GPIO_IN_PIN9_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN9_High (1UL) /*!< Pin input is high */ -/* Bit 8 : P0.8 pin */ +/* Bit 8 : Pin 8 */ #define GPIO_IN_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ #define GPIO_IN_PIN8_Msk (0x1UL << GPIO_IN_PIN8_Pos) /*!< Bit mask of PIN8 field. */ #define GPIO_IN_PIN8_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN8_High (1UL) /*!< Pin input is high */ -/* Bit 7 : P0.7 pin */ +/* Bit 7 : Pin 7 */ #define GPIO_IN_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ #define GPIO_IN_PIN7_Msk (0x1UL << GPIO_IN_PIN7_Pos) /*!< Bit mask of PIN7 field. */ #define GPIO_IN_PIN7_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN7_High (1UL) /*!< Pin input is high */ -/* Bit 6 : P0.6 pin */ +/* Bit 6 : Pin 6 */ #define GPIO_IN_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ #define GPIO_IN_PIN6_Msk (0x1UL << GPIO_IN_PIN6_Pos) /*!< Bit mask of PIN6 field. */ #define GPIO_IN_PIN6_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN6_High (1UL) /*!< Pin input is high */ -/* Bit 5 : P0.5 pin */ +/* Bit 5 : Pin 5 */ #define GPIO_IN_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ #define GPIO_IN_PIN5_Msk (0x1UL << GPIO_IN_PIN5_Pos) /*!< Bit mask of PIN5 field. */ #define GPIO_IN_PIN5_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN5_High (1UL) /*!< Pin input is high */ -/* Bit 4 : P0.4 pin */ +/* Bit 4 : Pin 4 */ #define GPIO_IN_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ #define GPIO_IN_PIN4_Msk (0x1UL << GPIO_IN_PIN4_Pos) /*!< Bit mask of PIN4 field. */ #define GPIO_IN_PIN4_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN4_High (1UL) /*!< Pin input is high */ -/* Bit 3 : P0.3 pin */ +/* Bit 3 : Pin 3 */ #define GPIO_IN_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ #define GPIO_IN_PIN3_Msk (0x1UL << GPIO_IN_PIN3_Pos) /*!< Bit mask of PIN3 field. */ #define GPIO_IN_PIN3_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN3_High (1UL) /*!< Pin input is high */ -/* Bit 2 : P0.2 pin */ +/* Bit 2 : Pin 2 */ #define GPIO_IN_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ #define GPIO_IN_PIN2_Msk (0x1UL << GPIO_IN_PIN2_Pos) /*!< Bit mask of PIN2 field. */ #define GPIO_IN_PIN2_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN2_High (1UL) /*!< Pin input is high */ -/* Bit 1 : P0.1 pin */ +/* Bit 1 : Pin 1 */ #define GPIO_IN_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ #define GPIO_IN_PIN1_Msk (0x1UL << GPIO_IN_PIN1_Pos) /*!< Bit mask of PIN1 field. */ #define GPIO_IN_PIN1_Low (0UL) /*!< Pin input is low */ #define GPIO_IN_PIN1_High (1UL) /*!< Pin input is high */ -/* Bit 0 : P0.0 pin */ +/* Bit 0 : Pin 0 */ #define GPIO_IN_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ #define GPIO_IN_PIN0_Msk (0x1UL << GPIO_IN_PIN0_Pos) /*!< Bit mask of PIN0 field. */ #define GPIO_IN_PIN0_Low (0UL) /*!< Pin input is low */ @@ -5671,193 +5667,193 @@ /* Register: GPIO_DIR */ /* Description: Direction of GPIO pins */ -/* Bit 31 : P0.31 pin */ +/* Bit 31 : Pin 31 */ #define GPIO_DIR_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ #define GPIO_DIR_PIN31_Msk (0x1UL << GPIO_DIR_PIN31_Pos) /*!< Bit mask of PIN31 field. */ #define GPIO_DIR_PIN31_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN31_Output (1UL) /*!< Pin set as output */ -/* Bit 30 : P0.30 pin */ +/* Bit 30 : Pin 30 */ #define GPIO_DIR_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ #define GPIO_DIR_PIN30_Msk (0x1UL << GPIO_DIR_PIN30_Pos) /*!< Bit mask of PIN30 field. */ #define GPIO_DIR_PIN30_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN30_Output (1UL) /*!< Pin set as output */ -/* Bit 29 : P0.29 pin */ +/* Bit 29 : Pin 29 */ #define GPIO_DIR_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ #define GPIO_DIR_PIN29_Msk (0x1UL << GPIO_DIR_PIN29_Pos) /*!< Bit mask of PIN29 field. */ #define GPIO_DIR_PIN29_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN29_Output (1UL) /*!< Pin set as output */ -/* Bit 28 : P0.28 pin */ +/* Bit 28 : Pin 28 */ #define GPIO_DIR_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ #define GPIO_DIR_PIN28_Msk (0x1UL << GPIO_DIR_PIN28_Pos) /*!< Bit mask of PIN28 field. */ #define GPIO_DIR_PIN28_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN28_Output (1UL) /*!< Pin set as output */ -/* Bit 27 : P0.27 pin */ +/* Bit 27 : Pin 27 */ #define GPIO_DIR_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ #define GPIO_DIR_PIN27_Msk (0x1UL << GPIO_DIR_PIN27_Pos) /*!< Bit mask of PIN27 field. */ #define GPIO_DIR_PIN27_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN27_Output (1UL) /*!< Pin set as output */ -/* Bit 26 : P0.26 pin */ +/* Bit 26 : Pin 26 */ #define GPIO_DIR_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ #define GPIO_DIR_PIN26_Msk (0x1UL << GPIO_DIR_PIN26_Pos) /*!< Bit mask of PIN26 field. */ #define GPIO_DIR_PIN26_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN26_Output (1UL) /*!< Pin set as output */ -/* Bit 25 : P0.25 pin */ +/* Bit 25 : Pin 25 */ #define GPIO_DIR_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ #define GPIO_DIR_PIN25_Msk (0x1UL << GPIO_DIR_PIN25_Pos) /*!< Bit mask of PIN25 field. */ #define GPIO_DIR_PIN25_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN25_Output (1UL) /*!< Pin set as output */ -/* Bit 24 : P0.24 pin */ +/* Bit 24 : Pin 24 */ #define GPIO_DIR_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ #define GPIO_DIR_PIN24_Msk (0x1UL << GPIO_DIR_PIN24_Pos) /*!< Bit mask of PIN24 field. */ #define GPIO_DIR_PIN24_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN24_Output (1UL) /*!< Pin set as output */ -/* Bit 23 : P0.23 pin */ +/* Bit 23 : Pin 23 */ #define GPIO_DIR_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ #define GPIO_DIR_PIN23_Msk (0x1UL << GPIO_DIR_PIN23_Pos) /*!< Bit mask of PIN23 field. */ #define GPIO_DIR_PIN23_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN23_Output (1UL) /*!< Pin set as output */ -/* Bit 22 : P0.22 pin */ +/* Bit 22 : Pin 22 */ #define GPIO_DIR_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ #define GPIO_DIR_PIN22_Msk (0x1UL << GPIO_DIR_PIN22_Pos) /*!< Bit mask of PIN22 field. */ #define GPIO_DIR_PIN22_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN22_Output (1UL) /*!< Pin set as output */ -/* Bit 21 : P0.21 pin */ +/* Bit 21 : Pin 21 */ #define GPIO_DIR_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ #define GPIO_DIR_PIN21_Msk (0x1UL << GPIO_DIR_PIN21_Pos) /*!< Bit mask of PIN21 field. */ #define GPIO_DIR_PIN21_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN21_Output (1UL) /*!< Pin set as output */ -/* Bit 20 : P0.20 pin */ +/* Bit 20 : Pin 20 */ #define GPIO_DIR_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ #define GPIO_DIR_PIN20_Msk (0x1UL << GPIO_DIR_PIN20_Pos) /*!< Bit mask of PIN20 field. */ #define GPIO_DIR_PIN20_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN20_Output (1UL) /*!< Pin set as output */ -/* Bit 19 : P0.19 pin */ +/* Bit 19 : Pin 19 */ #define GPIO_DIR_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ #define GPIO_DIR_PIN19_Msk (0x1UL << GPIO_DIR_PIN19_Pos) /*!< Bit mask of PIN19 field. */ #define GPIO_DIR_PIN19_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN19_Output (1UL) /*!< Pin set as output */ -/* Bit 18 : P0.18 pin */ +/* Bit 18 : Pin 18 */ #define GPIO_DIR_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ #define GPIO_DIR_PIN18_Msk (0x1UL << GPIO_DIR_PIN18_Pos) /*!< Bit mask of PIN18 field. */ #define GPIO_DIR_PIN18_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN18_Output (1UL) /*!< Pin set as output */ -/* Bit 17 : P0.17 pin */ +/* Bit 17 : Pin 17 */ #define GPIO_DIR_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ #define GPIO_DIR_PIN17_Msk (0x1UL << GPIO_DIR_PIN17_Pos) /*!< Bit mask of PIN17 field. */ #define GPIO_DIR_PIN17_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN17_Output (1UL) /*!< Pin set as output */ -/* Bit 16 : P0.16 pin */ +/* Bit 16 : Pin 16 */ #define GPIO_DIR_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ #define GPIO_DIR_PIN16_Msk (0x1UL << GPIO_DIR_PIN16_Pos) /*!< Bit mask of PIN16 field. */ #define GPIO_DIR_PIN16_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN16_Output (1UL) /*!< Pin set as output */ -/* Bit 15 : P0.15 pin */ +/* Bit 15 : Pin 15 */ #define GPIO_DIR_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ #define GPIO_DIR_PIN15_Msk (0x1UL << GPIO_DIR_PIN15_Pos) /*!< Bit mask of PIN15 field. */ #define GPIO_DIR_PIN15_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN15_Output (1UL) /*!< Pin set as output */ -/* Bit 14 : P0.14 pin */ +/* Bit 14 : Pin 14 */ #define GPIO_DIR_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ #define GPIO_DIR_PIN14_Msk (0x1UL << GPIO_DIR_PIN14_Pos) /*!< Bit mask of PIN14 field. */ #define GPIO_DIR_PIN14_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN14_Output (1UL) /*!< Pin set as output */ -/* Bit 13 : P0.13 pin */ +/* Bit 13 : Pin 13 */ #define GPIO_DIR_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ #define GPIO_DIR_PIN13_Msk (0x1UL << GPIO_DIR_PIN13_Pos) /*!< Bit mask of PIN13 field. */ #define GPIO_DIR_PIN13_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN13_Output (1UL) /*!< Pin set as output */ -/* Bit 12 : P0.12 pin */ +/* Bit 12 : Pin 12 */ #define GPIO_DIR_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ #define GPIO_DIR_PIN12_Msk (0x1UL << GPIO_DIR_PIN12_Pos) /*!< Bit mask of PIN12 field. */ #define GPIO_DIR_PIN12_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN12_Output (1UL) /*!< Pin set as output */ -/* Bit 11 : P0.11 pin */ +/* Bit 11 : Pin 11 */ #define GPIO_DIR_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ #define GPIO_DIR_PIN11_Msk (0x1UL << GPIO_DIR_PIN11_Pos) /*!< Bit mask of PIN11 field. */ #define GPIO_DIR_PIN11_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN11_Output (1UL) /*!< Pin set as output */ -/* Bit 10 : P0.10 pin */ +/* Bit 10 : Pin 10 */ #define GPIO_DIR_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ #define GPIO_DIR_PIN10_Msk (0x1UL << GPIO_DIR_PIN10_Pos) /*!< Bit mask of PIN10 field. */ #define GPIO_DIR_PIN10_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN10_Output (1UL) /*!< Pin set as output */ -/* Bit 9 : P0.9 pin */ +/* Bit 9 : Pin 9 */ #define GPIO_DIR_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ #define GPIO_DIR_PIN9_Msk (0x1UL << GPIO_DIR_PIN9_Pos) /*!< Bit mask of PIN9 field. */ #define GPIO_DIR_PIN9_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN9_Output (1UL) /*!< Pin set as output */ -/* Bit 8 : P0.8 pin */ +/* Bit 8 : Pin 8 */ #define GPIO_DIR_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ #define GPIO_DIR_PIN8_Msk (0x1UL << GPIO_DIR_PIN8_Pos) /*!< Bit mask of PIN8 field. */ #define GPIO_DIR_PIN8_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN8_Output (1UL) /*!< Pin set as output */ -/* Bit 7 : P0.7 pin */ +/* Bit 7 : Pin 7 */ #define GPIO_DIR_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ #define GPIO_DIR_PIN7_Msk (0x1UL << GPIO_DIR_PIN7_Pos) /*!< Bit mask of PIN7 field. */ #define GPIO_DIR_PIN7_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN7_Output (1UL) /*!< Pin set as output */ -/* Bit 6 : P0.6 pin */ +/* Bit 6 : Pin 6 */ #define GPIO_DIR_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ #define GPIO_DIR_PIN6_Msk (0x1UL << GPIO_DIR_PIN6_Pos) /*!< Bit mask of PIN6 field. */ #define GPIO_DIR_PIN6_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN6_Output (1UL) /*!< Pin set as output */ -/* Bit 5 : P0.5 pin */ +/* Bit 5 : Pin 5 */ #define GPIO_DIR_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ #define GPIO_DIR_PIN5_Msk (0x1UL << GPIO_DIR_PIN5_Pos) /*!< Bit mask of PIN5 field. */ #define GPIO_DIR_PIN5_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN5_Output (1UL) /*!< Pin set as output */ -/* Bit 4 : P0.4 pin */ +/* Bit 4 : Pin 4 */ #define GPIO_DIR_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ #define GPIO_DIR_PIN4_Msk (0x1UL << GPIO_DIR_PIN4_Pos) /*!< Bit mask of PIN4 field. */ #define GPIO_DIR_PIN4_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN4_Output (1UL) /*!< Pin set as output */ -/* Bit 3 : P0.3 pin */ +/* Bit 3 : Pin 3 */ #define GPIO_DIR_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ #define GPIO_DIR_PIN3_Msk (0x1UL << GPIO_DIR_PIN3_Pos) /*!< Bit mask of PIN3 field. */ #define GPIO_DIR_PIN3_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN3_Output (1UL) /*!< Pin set as output */ -/* Bit 2 : P0.2 pin */ +/* Bit 2 : Pin 2 */ #define GPIO_DIR_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ #define GPIO_DIR_PIN2_Msk (0x1UL << GPIO_DIR_PIN2_Pos) /*!< Bit mask of PIN2 field. */ #define GPIO_DIR_PIN2_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN2_Output (1UL) /*!< Pin set as output */ -/* Bit 1 : P0.1 pin */ +/* Bit 1 : Pin 1 */ #define GPIO_DIR_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ #define GPIO_DIR_PIN1_Msk (0x1UL << GPIO_DIR_PIN1_Pos) /*!< Bit mask of PIN1 field. */ #define GPIO_DIR_PIN1_Input (0UL) /*!< Pin set as input */ #define GPIO_DIR_PIN1_Output (1UL) /*!< Pin set as output */ -/* Bit 0 : P0.0 pin */ +/* Bit 0 : Pin 0 */ #define GPIO_DIR_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ #define GPIO_DIR_PIN0_Msk (0x1UL << GPIO_DIR_PIN0_Pos) /*!< Bit mask of PIN0 field. */ #define GPIO_DIR_PIN0_Input (0UL) /*!< Pin set as input */ @@ -6318,11 +6314,199 @@ #define GPIO_DIRCLR_PIN0_Clear (1UL) /*!< Write: writing a '1' sets pin to input; writing a '0' has no effect */ /* Register: GPIO_LATCH */ -/* Description: Latch indicating which GPIO pins have met the criteria set in PIN_CNF[n].SENSE register */ - -/* Bits 31..0 : Register holding a '1' for each GPIO pins which has met the criteria set in PIN_CNF[n].SENSE */ -#define GPIO_LATCH_LATCH_Pos (0UL) /*!< Position of LATCH field. */ -#define GPIO_LATCH_LATCH_Msk (0xFFFFFFFFUL << GPIO_LATCH_LATCH_Pos) /*!< Bit mask of LATCH field. */ +/* Description: Latch register indicating what GPIO pins that have met the criteria set in the PIN_CNF[n].SENSE registers */ + +/* Bit 31 : Status on whether PIN31 has met criteria set in PIN_CNF31.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN31_Pos (31UL) /*!< Position of PIN31 field. */ +#define GPIO_LATCH_PIN31_Msk (0x1UL << GPIO_LATCH_PIN31_Pos) /*!< Bit mask of PIN31 field. */ +#define GPIO_LATCH_PIN31_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN31_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 30 : Status on whether PIN30 has met criteria set in PIN_CNF30.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN30_Pos (30UL) /*!< Position of PIN30 field. */ +#define GPIO_LATCH_PIN30_Msk (0x1UL << GPIO_LATCH_PIN30_Pos) /*!< Bit mask of PIN30 field. */ +#define GPIO_LATCH_PIN30_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN30_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 29 : Status on whether PIN29 has met criteria set in PIN_CNF29.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN29_Pos (29UL) /*!< Position of PIN29 field. */ +#define GPIO_LATCH_PIN29_Msk (0x1UL << GPIO_LATCH_PIN29_Pos) /*!< Bit mask of PIN29 field. */ +#define GPIO_LATCH_PIN29_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN29_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 28 : Status on whether PIN28 has met criteria set in PIN_CNF28.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN28_Pos (28UL) /*!< Position of PIN28 field. */ +#define GPIO_LATCH_PIN28_Msk (0x1UL << GPIO_LATCH_PIN28_Pos) /*!< Bit mask of PIN28 field. */ +#define GPIO_LATCH_PIN28_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN28_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 27 : Status on whether PIN27 has met criteria set in PIN_CNF27.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN27_Pos (27UL) /*!< Position of PIN27 field. */ +#define GPIO_LATCH_PIN27_Msk (0x1UL << GPIO_LATCH_PIN27_Pos) /*!< Bit mask of PIN27 field. */ +#define GPIO_LATCH_PIN27_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN27_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 26 : Status on whether PIN26 has met criteria set in PIN_CNF26.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN26_Pos (26UL) /*!< Position of PIN26 field. */ +#define GPIO_LATCH_PIN26_Msk (0x1UL << GPIO_LATCH_PIN26_Pos) /*!< Bit mask of PIN26 field. */ +#define GPIO_LATCH_PIN26_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN26_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 25 : Status on whether PIN25 has met criteria set in PIN_CNF25.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN25_Pos (25UL) /*!< Position of PIN25 field. */ +#define GPIO_LATCH_PIN25_Msk (0x1UL << GPIO_LATCH_PIN25_Pos) /*!< Bit mask of PIN25 field. */ +#define GPIO_LATCH_PIN25_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN25_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 24 : Status on whether PIN24 has met criteria set in PIN_CNF24.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN24_Pos (24UL) /*!< Position of PIN24 field. */ +#define GPIO_LATCH_PIN24_Msk (0x1UL << GPIO_LATCH_PIN24_Pos) /*!< Bit mask of PIN24 field. */ +#define GPIO_LATCH_PIN24_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN24_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 23 : Status on whether PIN23 has met criteria set in PIN_CNF23.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN23_Pos (23UL) /*!< Position of PIN23 field. */ +#define GPIO_LATCH_PIN23_Msk (0x1UL << GPIO_LATCH_PIN23_Pos) /*!< Bit mask of PIN23 field. */ +#define GPIO_LATCH_PIN23_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN23_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 22 : Status on whether PIN22 has met criteria set in PIN_CNF22.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN22_Pos (22UL) /*!< Position of PIN22 field. */ +#define GPIO_LATCH_PIN22_Msk (0x1UL << GPIO_LATCH_PIN22_Pos) /*!< Bit mask of PIN22 field. */ +#define GPIO_LATCH_PIN22_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN22_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 21 : Status on whether PIN21 has met criteria set in PIN_CNF21.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN21_Pos (21UL) /*!< Position of PIN21 field. */ +#define GPIO_LATCH_PIN21_Msk (0x1UL << GPIO_LATCH_PIN21_Pos) /*!< Bit mask of PIN21 field. */ +#define GPIO_LATCH_PIN21_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN21_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 20 : Status on whether PIN20 has met criteria set in PIN_CNF20.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN20_Pos (20UL) /*!< Position of PIN20 field. */ +#define GPIO_LATCH_PIN20_Msk (0x1UL << GPIO_LATCH_PIN20_Pos) /*!< Bit mask of PIN20 field. */ +#define GPIO_LATCH_PIN20_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN20_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 19 : Status on whether PIN19 has met criteria set in PIN_CNF19.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN19_Pos (19UL) /*!< Position of PIN19 field. */ +#define GPIO_LATCH_PIN19_Msk (0x1UL << GPIO_LATCH_PIN19_Pos) /*!< Bit mask of PIN19 field. */ +#define GPIO_LATCH_PIN19_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN19_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 18 : Status on whether PIN18 has met criteria set in PIN_CNF18.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN18_Pos (18UL) /*!< Position of PIN18 field. */ +#define GPIO_LATCH_PIN18_Msk (0x1UL << GPIO_LATCH_PIN18_Pos) /*!< Bit mask of PIN18 field. */ +#define GPIO_LATCH_PIN18_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN18_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 17 : Status on whether PIN17 has met criteria set in PIN_CNF17.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN17_Pos (17UL) /*!< Position of PIN17 field. */ +#define GPIO_LATCH_PIN17_Msk (0x1UL << GPIO_LATCH_PIN17_Pos) /*!< Bit mask of PIN17 field. */ +#define GPIO_LATCH_PIN17_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN17_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 16 : Status on whether PIN16 has met criteria set in PIN_CNF16.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN16_Pos (16UL) /*!< Position of PIN16 field. */ +#define GPIO_LATCH_PIN16_Msk (0x1UL << GPIO_LATCH_PIN16_Pos) /*!< Bit mask of PIN16 field. */ +#define GPIO_LATCH_PIN16_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN16_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 15 : Status on whether PIN15 has met criteria set in PIN_CNF15.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN15_Pos (15UL) /*!< Position of PIN15 field. */ +#define GPIO_LATCH_PIN15_Msk (0x1UL << GPIO_LATCH_PIN15_Pos) /*!< Bit mask of PIN15 field. */ +#define GPIO_LATCH_PIN15_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN15_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 14 : Status on whether PIN14 has met criteria set in PIN_CNF14.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN14_Pos (14UL) /*!< Position of PIN14 field. */ +#define GPIO_LATCH_PIN14_Msk (0x1UL << GPIO_LATCH_PIN14_Pos) /*!< Bit mask of PIN14 field. */ +#define GPIO_LATCH_PIN14_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN14_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 13 : Status on whether PIN13 has met criteria set in PIN_CNF13.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN13_Pos (13UL) /*!< Position of PIN13 field. */ +#define GPIO_LATCH_PIN13_Msk (0x1UL << GPIO_LATCH_PIN13_Pos) /*!< Bit mask of PIN13 field. */ +#define GPIO_LATCH_PIN13_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN13_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 12 : Status on whether PIN12 has met criteria set in PIN_CNF12.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN12_Pos (12UL) /*!< Position of PIN12 field. */ +#define GPIO_LATCH_PIN12_Msk (0x1UL << GPIO_LATCH_PIN12_Pos) /*!< Bit mask of PIN12 field. */ +#define GPIO_LATCH_PIN12_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN12_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 11 : Status on whether PIN11 has met criteria set in PIN_CNF11.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN11_Pos (11UL) /*!< Position of PIN11 field. */ +#define GPIO_LATCH_PIN11_Msk (0x1UL << GPIO_LATCH_PIN11_Pos) /*!< Bit mask of PIN11 field. */ +#define GPIO_LATCH_PIN11_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN11_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 10 : Status on whether PIN10 has met criteria set in PIN_CNF10.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN10_Pos (10UL) /*!< Position of PIN10 field. */ +#define GPIO_LATCH_PIN10_Msk (0x1UL << GPIO_LATCH_PIN10_Pos) /*!< Bit mask of PIN10 field. */ +#define GPIO_LATCH_PIN10_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN10_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 9 : Status on whether PIN9 has met criteria set in PIN_CNF9.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN9_Pos (9UL) /*!< Position of PIN9 field. */ +#define GPIO_LATCH_PIN9_Msk (0x1UL << GPIO_LATCH_PIN9_Pos) /*!< Bit mask of PIN9 field. */ +#define GPIO_LATCH_PIN9_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN9_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 8 : Status on whether PIN8 has met criteria set in PIN_CNF8.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN8_Pos (8UL) /*!< Position of PIN8 field. */ +#define GPIO_LATCH_PIN8_Msk (0x1UL << GPIO_LATCH_PIN8_Pos) /*!< Bit mask of PIN8 field. */ +#define GPIO_LATCH_PIN8_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN8_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 7 : Status on whether PIN7 has met criteria set in PIN_CNF7.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN7_Pos (7UL) /*!< Position of PIN7 field. */ +#define GPIO_LATCH_PIN7_Msk (0x1UL << GPIO_LATCH_PIN7_Pos) /*!< Bit mask of PIN7 field. */ +#define GPIO_LATCH_PIN7_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN7_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 6 : Status on whether PIN6 has met criteria set in PIN_CNF6.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN6_Pos (6UL) /*!< Position of PIN6 field. */ +#define GPIO_LATCH_PIN6_Msk (0x1UL << GPIO_LATCH_PIN6_Pos) /*!< Bit mask of PIN6 field. */ +#define GPIO_LATCH_PIN6_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN6_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 5 : Status on whether PIN5 has met criteria set in PIN_CNF5.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN5_Pos (5UL) /*!< Position of PIN5 field. */ +#define GPIO_LATCH_PIN5_Msk (0x1UL << GPIO_LATCH_PIN5_Pos) /*!< Bit mask of PIN5 field. */ +#define GPIO_LATCH_PIN5_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN5_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 4 : Status on whether PIN4 has met criteria set in PIN_CNF4.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN4_Pos (4UL) /*!< Position of PIN4 field. */ +#define GPIO_LATCH_PIN4_Msk (0x1UL << GPIO_LATCH_PIN4_Pos) /*!< Bit mask of PIN4 field. */ +#define GPIO_LATCH_PIN4_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN4_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 3 : Status on whether PIN3 has met criteria set in PIN_CNF3.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN3_Pos (3UL) /*!< Position of PIN3 field. */ +#define GPIO_LATCH_PIN3_Msk (0x1UL << GPIO_LATCH_PIN3_Pos) /*!< Bit mask of PIN3 field. */ +#define GPIO_LATCH_PIN3_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN3_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 2 : Status on whether PIN2 has met criteria set in PIN_CNF2.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN2_Pos (2UL) /*!< Position of PIN2 field. */ +#define GPIO_LATCH_PIN2_Msk (0x1UL << GPIO_LATCH_PIN2_Pos) /*!< Bit mask of PIN2 field. */ +#define GPIO_LATCH_PIN2_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN2_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 1 : Status on whether PIN1 has met criteria set in PIN_CNF1.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN1_Pos (1UL) /*!< Position of PIN1 field. */ +#define GPIO_LATCH_PIN1_Msk (0x1UL << GPIO_LATCH_PIN1_Pos) /*!< Bit mask of PIN1 field. */ +#define GPIO_LATCH_PIN1_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN1_Latched (1UL) /*!< Criteria has been met */ + +/* Bit 0 : Status on whether PIN0 has met criteria set in PIN_CNF0.SENSE register. Write '1' to clear. */ +#define GPIO_LATCH_PIN0_Pos (0UL) /*!< Position of PIN0 field. */ +#define GPIO_LATCH_PIN0_Msk (0x1UL << GPIO_LATCH_PIN0_Pos) /*!< Bit mask of PIN0 field. */ +#define GPIO_LATCH_PIN0_NotLatched (0UL) /*!< Criteria has not been met */ +#define GPIO_LATCH_PIN0_Latched (1UL) /*!< Criteria has been met */ /* Register: GPIO_DETECTMODE */ /* Description: Select between default DETECT signal behaviour and LDETECT mode */ @@ -6330,8 +6514,8 @@ /* Bit 0 : Select between default DETECT signal behaviour and LDETECT mode */ #define GPIO_DETECTMODE_DETECTMODE_Pos (0UL) /*!< Position of DETECTMODE field. */ #define GPIO_DETECTMODE_DETECTMODE_Msk (0x1UL << GPIO_DETECTMODE_DETECTMODE_Pos) /*!< Bit mask of DETECTMODE field. */ -#define GPIO_DETECTMODE_DETECTMODE_Default (0UL) /*!< Use default behaviour */ -#define GPIO_DETECTMODE_DETECTMODE_LDETECT (1UL) /*!< Use LDETECT behaviour */ +#define GPIO_DETECTMODE_DETECTMODE_Default (0UL) /*!< DETECT directly connected to PIN DETECT signals */ +#define GPIO_DETECTMODE_DETECTMODE_LDETECT (1UL) /*!< Use the latched LDETECT behaviour */ /* Register: GPIO_PIN_CNF */ /* Description: Description collection[0]: Configuration of GPIO pins */ @@ -6350,10 +6534,10 @@ #define GPIO_PIN_CNF_DRIVE_H0S1 (1UL) /*!< High drive '0', standard '1' */ #define GPIO_PIN_CNF_DRIVE_S0H1 (2UL) /*!< Standard '0', high drive '1' */ #define GPIO_PIN_CNF_DRIVE_H0H1 (3UL) /*!< High drive '0', high 'drive '1'' */ -#define GPIO_PIN_CNF_DRIVE_D0S1 (4UL) /*!< Disconnect '0' standard '1' */ -#define GPIO_PIN_CNF_DRIVE_D0H1 (5UL) /*!< Disconnect '0', high drive '1' */ -#define GPIO_PIN_CNF_DRIVE_S0D1 (6UL) /*!< Standard '0'. disconnect '1' */ -#define GPIO_PIN_CNF_DRIVE_H0D1 (7UL) /*!< High drive '0', disconnect '1' */ +#define GPIO_PIN_CNF_DRIVE_D0S1 (4UL) /*!< Disconnect '0' standard '1' (normally used for wired-or connections) */ +#define GPIO_PIN_CNF_DRIVE_D0H1 (5UL) /*!< Disconnect '0', high drive '1' (normally used for wired-or connections) */ +#define GPIO_PIN_CNF_DRIVE_S0D1 (6UL) /*!< Standard '0'. disconnect '1' (normally used for wired-and connections) */ +#define GPIO_PIN_CNF_DRIVE_H0D1 (7UL) /*!< High drive '0', disconnect '1' (normally used for wired-and connections) */ /* Bits 3..2 : Pull configuration */ #define GPIO_PIN_CNF_PULL_Pos (2UL) /*!< Position of PULL field. */ @@ -6368,7 +6552,7 @@ #define GPIO_PIN_CNF_INPUT_Connect (0UL) /*!< Connect input buffer */ #define GPIO_PIN_CNF_INPUT_Disconnect (1UL) /*!< Disconnect input buffer */ -/* Bit 0 : Pin direction */ +/* Bit 0 : Pin direction. Same physical register as DIR register */ #define GPIO_PIN_CNF_DIR_Pos (0UL) /*!< Position of DIR field. */ #define GPIO_PIN_CNF_DIR_Msk (0x1UL << GPIO_PIN_CNF_DIR_Pos) /*!< Bit mask of DIR field. */ #define GPIO_PIN_CNF_DIR_Input (0UL) /*!< Configure pin as an input pin */ @@ -6626,7 +6810,7 @@ #define POWER_RESETREAS_LOCKUP_NotDetected (0UL) /*!< Not detected */ #define POWER_RESETREAS_LOCKUP_Detected (1UL) /*!< Detected */ -/* Bit 2 : Reset from AIRCR.SYSRESETREQ detected */ +/* Bit 2 : Reset from soft reset detected */ #define POWER_RESETREAS_SREQ_Pos (2UL) /*!< Position of SREQ field. */ #define POWER_RESETREAS_SREQ_Msk (0x1UL << POWER_RESETREAS_SREQ_Pos) /*!< Bit mask of SREQ field. */ #define POWER_RESETREAS_SREQ_NotDetected (0UL) /*!< Not detected */ @@ -6685,12 +6869,16 @@ /* Bits 4..1 : Power failure comparator threshold setting */ #define POWER_POFCON_THRESHOLD_Pos (1UL) /*!< Position of THRESHOLD field. */ #define POWER_POFCON_THRESHOLD_Msk (0xFUL << POWER_POFCON_THRESHOLD_Pos) /*!< Bit mask of THRESHOLD field. */ +#define POWER_POFCON_THRESHOLD_V17 (4UL) /*!< Set threshold to 1.7 V */ +#define POWER_POFCON_THRESHOLD_V18 (5UL) /*!< Set threshold to 1.8 V */ #define POWER_POFCON_THRESHOLD_V19 (6UL) /*!< Set threshold to 1.9 V */ #define POWER_POFCON_THRESHOLD_V20 (7UL) /*!< Set threshold to 2.0 V */ #define POWER_POFCON_THRESHOLD_V21 (8UL) /*!< Set threshold to 2.1 V */ #define POWER_POFCON_THRESHOLD_V22 (9UL) /*!< Set threshold to 2.2 V */ #define POWER_POFCON_THRESHOLD_V23 (10UL) /*!< Set threshold to 2.3 V */ #define POWER_POFCON_THRESHOLD_V24 (11UL) /*!< Set threshold to 2.4 V */ +#define POWER_POFCON_THRESHOLD_V25 (12UL) /*!< Set threshold to 2.5 V */ +#define POWER_POFCON_THRESHOLD_V26 (13UL) /*!< Set threshold to 2.6 V */ #define POWER_POFCON_THRESHOLD_V27 (14UL) /*!< Set threshold to 2.7 V */ #define POWER_POFCON_THRESHOLD_V28 (15UL) /*!< Set threshold to 2.8 V */ @@ -6780,25 +6968,25 @@ /* Register: POWER_RAM_POWER */ /* Description: Description cluster[0]: RAM0 power control register */ -/* Bit 17 : Keep retention on RAM section S1 when RAM section is switched off */ +/* Bit 17 : Keep retention on RAM section S1 when RAM section is in OFF */ #define POWER_RAM_POWER_S1RETENTION_Pos (17UL) /*!< Position of S1RETENTION field. */ #define POWER_RAM_POWER_S1RETENTION_Msk (0x1UL << POWER_RAM_POWER_S1RETENTION_Pos) /*!< Bit mask of S1RETENTION field. */ #define POWER_RAM_POWER_S1RETENTION_Off (0UL) /*!< Off */ #define POWER_RAM_POWER_S1RETENTION_On (1UL) /*!< On */ -/* Bit 16 : Keep retention on RAM section S0 when RAM section is switched off */ +/* Bit 16 : Keep retention on RAM section S0 when RAM section is in OFF */ #define POWER_RAM_POWER_S0RETENTION_Pos (16UL) /*!< Position of S0RETENTION field. */ #define POWER_RAM_POWER_S0RETENTION_Msk (0x1UL << POWER_RAM_POWER_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ #define POWER_RAM_POWER_S0RETENTION_Off (0UL) /*!< Off */ #define POWER_RAM_POWER_S0RETENTION_On (1UL) /*!< On */ -/* Bit 1 : Keep RAM section S1 of RAMm on or off in System ON mode */ +/* Bit 1 : Keep RAM section S1 ON or OFF in System ON mode. */ #define POWER_RAM_POWER_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ #define POWER_RAM_POWER_S1POWER_Msk (0x1UL << POWER_RAM_POWER_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ #define POWER_RAM_POWER_S1POWER_Off (0UL) /*!< Off */ #define POWER_RAM_POWER_S1POWER_On (1UL) /*!< On */ -/* Bit 0 : Keep RAM section S0 of RAMm on or off in System ON mode */ +/* Bit 0 : Keep RAM section S0 ON or OFF in System ON mode. */ #define POWER_RAM_POWER_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ #define POWER_RAM_POWER_S0POWER_Msk (0x1UL << POWER_RAM_POWER_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ #define POWER_RAM_POWER_S0POWER_Off (0UL) /*!< Off */ @@ -6817,12 +7005,12 @@ #define POWER_RAM_POWERSET_S0RETENTION_Msk (0x1UL << POWER_RAM_POWERSET_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ #define POWER_RAM_POWERSET_S0RETENTION_On (1UL) /*!< On */ -/* Bit 1 : Keep RAM section S1 of RAMm on or off in System ON mode */ +/* Bit 1 : Keep RAM section S1 of RAM0 on or off in System ON mode */ #define POWER_RAM_POWERSET_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ #define POWER_RAM_POWERSET_S1POWER_Msk (0x1UL << POWER_RAM_POWERSET_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ #define POWER_RAM_POWERSET_S1POWER_On (1UL) /*!< On */ -/* Bit 0 : Keep RAM section S0 of RAMm on or off in System ON mode */ +/* Bit 0 : Keep RAM section S0 of RAM0 on or off in System ON mode */ #define POWER_RAM_POWERSET_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ #define POWER_RAM_POWERSET_S0POWER_Msk (0x1UL << POWER_RAM_POWERSET_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ #define POWER_RAM_POWERSET_S0POWER_On (1UL) /*!< On */ @@ -6840,12 +7028,12 @@ #define POWER_RAM_POWERCLR_S0RETENTION_Msk (0x1UL << POWER_RAM_POWERCLR_S0RETENTION_Pos) /*!< Bit mask of S0RETENTION field. */ #define POWER_RAM_POWERCLR_S0RETENTION_Off (1UL) /*!< Off */ -/* Bit 1 : Keep RAM section S1 of RAMm on or off in System ON mode */ +/* Bit 1 : Keep RAM section S1 of RAM0 on or off in System ON mode */ #define POWER_RAM_POWERCLR_S1POWER_Pos (1UL) /*!< Position of S1POWER field. */ #define POWER_RAM_POWERCLR_S1POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S1POWER_Pos) /*!< Bit mask of S1POWER field. */ #define POWER_RAM_POWERCLR_S1POWER_Off (1UL) /*!< Off */ -/* Bit 0 : Keep RAM section S0 of RAMm on or off in System ON mode */ +/* Bit 0 : Keep RAM section S0 of RAM0 on or off in System ON mode */ #define POWER_RAM_POWERCLR_S0POWER_Pos (0UL) /*!< Position of S0POWER field. */ #define POWER_RAM_POWERCLR_S0POWER_Msk (0x1UL << POWER_RAM_POWERCLR_S0POWER_Pos) /*!< Bit mask of S0POWER field. */ #define POWER_RAM_POWERCLR_S0POWER_Off (1UL) /*!< Off */ @@ -7971,24 +8159,24 @@ #define PWM_LOOP_CNT_Disabled (0UL) /*!< Looping disabled (stop at the end of the sequence) */ /* Register: PWM_SEQ_PTR */ -/* Description: Description cluster[0]: Beginning address in Data RAM of sequence A */ +/* Description: Description cluster[0]: Beginning address in Data RAM of this sequence */ -/* Bits 31..0 : Beginning address in Data RAM of sequence A */ +/* Bits 31..0 : Beginning address in Data RAM of this sequence */ #define PWM_SEQ_PTR_PTR_Pos (0UL) /*!< Position of PTR field. */ #define PWM_SEQ_PTR_PTR_Msk (0xFFFFFFFFUL << PWM_SEQ_PTR_PTR_Pos) /*!< Bit mask of PTR field. */ /* Register: PWM_SEQ_CNT */ -/* Description: Description cluster[0]: Amount of values (duty cycles) in sequence A */ +/* Description: Description cluster[0]: Amount of values (duty cycles) in this sequence */ -/* Bits 14..0 : Amount of values (duty cycles) in sequence A */ +/* Bits 14..0 : Amount of values (duty cycles) in this sequence */ #define PWM_SEQ_CNT_CNT_Pos (0UL) /*!< Position of CNT field. */ #define PWM_SEQ_CNT_CNT_Msk (0x7FFFUL << PWM_SEQ_CNT_CNT_Pos) /*!< Bit mask of CNT field. */ #define PWM_SEQ_CNT_CNT_Disabled (0UL) /*!< Sequence is disabled, and shall not be started as it is empty */ /* Register: PWM_SEQ_REFRESH */ -/* Description: Description cluster[0]: Amount of additional PWM periods between samples loaded to compare register (load every CNT+1 PWM periods) */ +/* Description: Description cluster[0]: Amount of additional PWM periods between samples loaded into compare register */ -/* Bits 23..0 : Amount of additional PWM periods between samples loaded to compare register (load every CNT+1 PWM periods) */ +/* Bits 23..0 : Amount of additional PWM periods between samples loaded into compare register (load every REFRESH.CNT+1 PWM periods) */ #define PWM_SEQ_REFRESH_CNT_Pos (0UL) /*!< Position of CNT field. */ #define PWM_SEQ_REFRESH_CNT_Msk (0xFFFFFFUL << PWM_SEQ_REFRESH_CNT_Pos) /*!< Bit mask of CNT field. */ #define PWM_SEQ_REFRESH_CNT_Continuous (0UL) /*!< Update every PWM period */ @@ -8535,6 +8723,12 @@ /* Register: RADIO_FREQUENCY */ /* Description: Frequency */ +/* Bit 8 : Channel map selection. */ +#define RADIO_FREQUENCY_MAP_Pos (8UL) /*!< Position of MAP field. */ +#define RADIO_FREQUENCY_MAP_Msk (0x1UL << RADIO_FREQUENCY_MAP_Pos) /*!< Bit mask of MAP field. */ +#define RADIO_FREQUENCY_MAP_Default (0UL) /*!< Channel map between 2400 MHZ .. 2500 MHz */ +#define RADIO_FREQUENCY_MAP_Low (1UL) /*!< Channel map between 2360 MHZ .. 2460 MHz */ + /* Bits 6..0 : Radio channel frequency */ #define RADIO_FREQUENCY_FREQUENCY_Pos (0UL) /*!< Position of FREQUENCY field. */ #define RADIO_FREQUENCY_FREQUENCY_Msk (0x7FUL << RADIO_FREQUENCY_FREQUENCY_Pos) /*!< Bit mask of FREQUENCY field. */ @@ -8916,8 +9110,8 @@ /* Bit 0 : Radio ramp-up time */ #define RADIO_MODECNF0_RU_Pos (0UL) /*!< Position of RU field. */ #define RADIO_MODECNF0_RU_Msk (0x1UL << RADIO_MODECNF0_RU_Pos) /*!< Bit mask of RU field. */ -#define RADIO_MODECNF0_RU_Default (0UL) /*!< Default ramp-up time, compatible with nRF51 */ -#define RADIO_MODECNF0_RU_Fast (1UL) /*!< Fast ramp-up, see product specification for more information */ +#define RADIO_MODECNF0_RU_Default (0UL) /*!< Default ramp-up time (tRXEN), compatible with firmware written for nRF51 */ +#define RADIO_MODECNF0_RU_Fast (1UL) /*!< Fast ramp-up (tRXEN,FAST), see electrical specification for more information */ /* Register: RADIO_POWER */ /* Description: Peripheral power control */ @@ -9729,6 +9923,12 @@ /* Register: SAADC_CH_CONFIG */ /* Description: Description cluster[0]: Input configuration for CH[0] */ +/* Bit 24 : Enable burst mode */ +#define SAADC_CH_CONFIG_BURST_Pos (24UL) /*!< Position of BURST field. */ +#define SAADC_CH_CONFIG_BURST_Msk (0x1UL << SAADC_CH_CONFIG_BURST_Pos) /*!< Bit mask of BURST field. */ +#define SAADC_CH_CONFIG_BURST_Disabled (0UL) /*!< Burst mode is disabled (normal operation) */ +#define SAADC_CH_CONFIG_BURST_Enabled (1UL) /*!< Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM. */ + /* Bit 20 : Enable differential mode */ #define SAADC_CH_CONFIG_MODE_Pos (20UL) /*!< Position of MODE field. */ #define SAADC_CH_CONFIG_MODE_Msk (0x1UL << SAADC_CH_CONFIG_MODE_Pos) /*!< Bit mask of MODE field. */ @@ -9840,16 +10040,16 @@ /* Register: SAADC_RESULT_MAXCNT */ /* Description: Maximum number of buffer words to transfer */ -/* Bits 15..0 : Maximum number of buffer words to transfer */ +/* Bits 14..0 : Maximum number of buffer words to transfer */ #define SAADC_RESULT_MAXCNT_MAXCNT_Pos (0UL) /*!< Position of MAXCNT field. */ -#define SAADC_RESULT_MAXCNT_MAXCNT_Msk (0xFFFFUL << SAADC_RESULT_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ +#define SAADC_RESULT_MAXCNT_MAXCNT_Msk (0x7FFFUL << SAADC_RESULT_MAXCNT_MAXCNT_Pos) /*!< Bit mask of MAXCNT field. */ /* Register: SAADC_RESULT_AMOUNT */ /* Description: Number of buffer words transferred since last START */ -/* Bits 15..0 : Number of buffer words transferred since last START. This register can be read after an END or STOPPED event. */ +/* Bits 14..0 : Number of buffer words transferred since last START. This register can be read after an END or STOPPED event. */ #define SAADC_RESULT_AMOUNT_AMOUNT_Pos (0UL) /*!< Position of AMOUNT field. */ -#define SAADC_RESULT_AMOUNT_AMOUNT_Msk (0xFFFFUL << SAADC_RESULT_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ +#define SAADC_RESULT_AMOUNT_AMOUNT_Msk (0x7FFFUL << SAADC_RESULT_AMOUNT_AMOUNT_Pos) /*!< Bit mask of AMOUNT field. */ /* Peripheral: SPI */ @@ -10749,7 +10949,7 @@ #define TIMER_MODE_MODE_Pos (0UL) /*!< Position of MODE field. */ #define TIMER_MODE_MODE_Msk (0x3UL << TIMER_MODE_MODE_Pos) /*!< Bit mask of MODE field. */ #define TIMER_MODE_MODE_Timer (0UL) /*!< Select Timer mode */ -#define TIMER_MODE_MODE_Counter (1UL) /*!< Select Counter mode */ +#define TIMER_MODE_MODE_Counter (1UL) /*!< Deprecated enumerator - Select Counter mode */ #define TIMER_MODE_MODE_LowPowerCounter (2UL) /*!< Select Low Power Counter mode */ /* Register: TIMER_BITMODE */ @@ -10894,18 +11094,21 @@ #define TWI_ERRORSRC_DNACK_Msk (0x1UL << TWI_ERRORSRC_DNACK_Pos) /*!< Bit mask of DNACK field. */ #define TWI_ERRORSRC_DNACK_NotPresent (0UL) /*!< Read: error not present */ #define TWI_ERRORSRC_DNACK_Present (1UL) /*!< Read: error present */ +#define TWI_ERRORSRC_DNACK_Clear (1UL) /*!< Write: clear error on writing '1' */ /* Bit 1 : NACK received after sending the address (write '1' to clear) */ #define TWI_ERRORSRC_ANACK_Pos (1UL) /*!< Position of ANACK field. */ #define TWI_ERRORSRC_ANACK_Msk (0x1UL << TWI_ERRORSRC_ANACK_Pos) /*!< Bit mask of ANACK field. */ #define TWI_ERRORSRC_ANACK_NotPresent (0UL) /*!< Read: error not present */ #define TWI_ERRORSRC_ANACK_Present (1UL) /*!< Read: error present */ +#define TWI_ERRORSRC_ANACK_Clear (1UL) /*!< Write: clear error on writing '1' */ /* Bit 0 : Overrun error */ #define TWI_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ #define TWI_ERRORSRC_OVERRUN_Msk (0x1UL << TWI_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ #define TWI_ERRORSRC_OVERRUN_NotPresent (0UL) /*!< Read: no overrun occured */ #define TWI_ERRORSRC_OVERRUN_Present (1UL) /*!< Read: overrun occured */ +#define TWI_ERRORSRC_OVERRUN_Clear (1UL) /*!< Write: clear error on writing '1' */ /* Register: TWI_ENABLE */ /* Description: Enable TWI */ @@ -11027,6 +11230,12 @@ #define TWIM_INTEN_RXSTARTED_Disabled (0UL) /*!< Disable */ #define TWIM_INTEN_RXSTARTED_Enabled (1UL) /*!< Enable */ +/* Bit 18 : Enable or disable interrupt for SUSPENDED event */ +#define TWIM_INTEN_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTEN_SUSPENDED_Msk (0x1UL << TWIM_INTEN_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTEN_SUSPENDED_Disabled (0UL) /*!< Disable */ +#define TWIM_INTEN_SUSPENDED_Enabled (1UL) /*!< Enable */ + /* Bit 9 : Enable or disable interrupt for ERROR event */ #define TWIM_INTEN_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWIM_INTEN_ERROR_Msk (0x1UL << TWIM_INTEN_ERROR_Pos) /*!< Bit mask of ERROR field. */ @@ -11070,6 +11279,13 @@ #define TWIM_INTENSET_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENSET_RXSTARTED_Set (1UL) /*!< Enable */ +/* Bit 18 : Write '1' to Enable interrupt for SUSPENDED event */ +#define TWIM_INTENSET_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTENSET_SUSPENDED_Msk (0x1UL << TWIM_INTENSET_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTENSET_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENSET_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENSET_SUSPENDED_Set (1UL) /*!< Enable */ + /* Bit 9 : Write '1' to Enable interrupt for ERROR event */ #define TWIM_INTENSET_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWIM_INTENSET_ERROR_Msk (0x1UL << TWIM_INTENSET_ERROR_Pos) /*!< Bit mask of ERROR field. */ @@ -11115,6 +11331,13 @@ #define TWIM_INTENCLR_RXSTARTED_Enabled (1UL) /*!< Read: Enabled */ #define TWIM_INTENCLR_RXSTARTED_Clear (1UL) /*!< Disable */ +/* Bit 18 : Write '1' to Disable interrupt for SUSPENDED event */ +#define TWIM_INTENCLR_SUSPENDED_Pos (18UL) /*!< Position of SUSPENDED field. */ +#define TWIM_INTENCLR_SUSPENDED_Msk (0x1UL << TWIM_INTENCLR_SUSPENDED_Pos) /*!< Bit mask of SUSPENDED field. */ +#define TWIM_INTENCLR_SUSPENDED_Disabled (0UL) /*!< Read: Disabled */ +#define TWIM_INTENCLR_SUSPENDED_Enabled (1UL) /*!< Read: Enabled */ +#define TWIM_INTENCLR_SUSPENDED_Clear (1UL) /*!< Disable */ + /* Bit 9 : Write '1' to Disable interrupt for ERROR event */ #define TWIM_INTENCLR_ERROR_Pos (9UL) /*!< Position of ERROR field. */ #define TWIM_INTENCLR_ERROR_Msk (0x1UL << TWIM_INTENCLR_ERROR_Pos) /*!< Bit mask of ERROR field. */ @@ -11144,6 +11367,12 @@ #define TWIM_ERRORSRC_ANACK_NotReceived (0UL) /*!< Error did not occur */ #define TWIM_ERRORSRC_ANACK_Received (1UL) /*!< Error occurred */ +/* Bit 0 : Overrun error */ +#define TWIM_ERRORSRC_OVERRUN_Pos (0UL) /*!< Position of OVERRUN field. */ +#define TWIM_ERRORSRC_OVERRUN_Msk (0x1UL << TWIM_ERRORSRC_OVERRUN_Pos) /*!< Bit mask of OVERRUN field. */ +#define TWIM_ERRORSRC_OVERRUN_NotReceived (0UL) /*!< Error did not occur */ +#define TWIM_ERRORSRC_OVERRUN_Received (1UL) /*!< Error occurred */ + /* Register: TWIM_ENABLE */ /* Description: Enable TWIM */ @@ -11732,7 +11961,7 @@ /* Register: UART_BAUDRATE */ /* Description: Baud rate */ -/* Bits 31..0 : Baud-rate */ +/* Bits 31..0 : Baud rate */ #define UART_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */ #define UART_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UART_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */ #define UART_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud (actual rate: 1205) */ @@ -11742,7 +11971,9 @@ #define UART_BAUDRATE_BAUDRATE_Baud14400 (0x003B0000UL) /*!< 14400 baud (actual rate: 14414) */ #define UART_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud (actual rate: 19208) */ #define UART_BAUDRATE_BAUDRATE_Baud28800 (0x0075F000UL) /*!< 28800 baud (actual rate: 28829) */ +#define UART_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud */ #define UART_BAUDRATE_BAUDRATE_Baud38400 (0x009D5000UL) /*!< 38400 baud (actual rate: 38462) */ +#define UART_BAUDRATE_BAUDRATE_Baud56000 (0x00E50000UL) /*!< 56000 baud (actual rate: 55944) */ #define UART_BAUDRATE_BAUDRATE_Baud57600 (0x00EBF000UL) /*!< 57600 baud (actual rate: 57762) */ #define UART_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud (actual rate: 76923) */ #define UART_BAUDRATE_BAUDRATE_Baud115200 (0x01D7E000UL) /*!< 115200 baud (actual rate: 115942) */ @@ -11825,12 +12056,24 @@ #define UARTE_INTEN_ENDTX_Disabled (0UL) /*!< Disable */ #define UARTE_INTEN_ENDTX_Enabled (1UL) /*!< Enable */ +/* Bit 7 : Enable or disable interrupt for TXDRDY event */ +#define UARTE_INTEN_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTEN_TXDRDY_Msk (0x1UL << UARTE_INTEN_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTEN_TXDRDY_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_TXDRDY_Enabled (1UL) /*!< Enable */ + /* Bit 4 : Enable or disable interrupt for ENDRX event */ #define UARTE_INTEN_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ #define UARTE_INTEN_ENDRX_Msk (0x1UL << UARTE_INTEN_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ #define UARTE_INTEN_ENDRX_Disabled (0UL) /*!< Disable */ #define UARTE_INTEN_ENDRX_Enabled (1UL) /*!< Enable */ +/* Bit 2 : Enable or disable interrupt for RXDRDY event */ +#define UARTE_INTEN_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTEN_RXDRDY_Msk (0x1UL << UARTE_INTEN_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTEN_RXDRDY_Disabled (0UL) /*!< Disable */ +#define UARTE_INTEN_RXDRDY_Enabled (1UL) /*!< Enable */ + /* Bit 1 : Enable or disable interrupt for NCTS event */ #define UARTE_INTEN_NCTS_Pos (1UL) /*!< Position of NCTS field. */ #define UARTE_INTEN_NCTS_Msk (0x1UL << UARTE_INTEN_NCTS_Pos) /*!< Bit mask of NCTS field. */ @@ -11888,6 +12131,13 @@ #define UARTE_INTENSET_ENDTX_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENSET_ENDTX_Set (1UL) /*!< Enable */ +/* Bit 7 : Write '1' to Enable interrupt for TXDRDY event */ +#define UARTE_INTENSET_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTENSET_TXDRDY_Msk (0x1UL << UARTE_INTENSET_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTENSET_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_TXDRDY_Set (1UL) /*!< Enable */ + /* Bit 4 : Write '1' to Enable interrupt for ENDRX event */ #define UARTE_INTENSET_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ #define UARTE_INTENSET_ENDRX_Msk (0x1UL << UARTE_INTENSET_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ @@ -11895,6 +12145,13 @@ #define UARTE_INTENSET_ENDRX_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENSET_ENDRX_Set (1UL) /*!< Enable */ +/* Bit 2 : Write '1' to Enable interrupt for RXDRDY event */ +#define UARTE_INTENSET_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTENSET_RXDRDY_Msk (0x1UL << UARTE_INTENSET_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTENSET_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENSET_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENSET_RXDRDY_Set (1UL) /*!< Enable */ + /* Bit 1 : Write '1' to Enable interrupt for NCTS event */ #define UARTE_INTENSET_NCTS_Pos (1UL) /*!< Position of NCTS field. */ #define UARTE_INTENSET_NCTS_Msk (0x1UL << UARTE_INTENSET_NCTS_Pos) /*!< Bit mask of NCTS field. */ @@ -11954,6 +12211,13 @@ #define UARTE_INTENCLR_ENDTX_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENCLR_ENDTX_Clear (1UL) /*!< Disable */ +/* Bit 7 : Write '1' to Disable interrupt for TXDRDY event */ +#define UARTE_INTENCLR_TXDRDY_Pos (7UL) /*!< Position of TXDRDY field. */ +#define UARTE_INTENCLR_TXDRDY_Msk (0x1UL << UARTE_INTENCLR_TXDRDY_Pos) /*!< Bit mask of TXDRDY field. */ +#define UARTE_INTENCLR_TXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_TXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_TXDRDY_Clear (1UL) /*!< Disable */ + /* Bit 4 : Write '1' to Disable interrupt for ENDRX event */ #define UARTE_INTENCLR_ENDRX_Pos (4UL) /*!< Position of ENDRX field. */ #define UARTE_INTENCLR_ENDRX_Msk (0x1UL << UARTE_INTENCLR_ENDRX_Pos) /*!< Bit mask of ENDRX field. */ @@ -11961,6 +12225,13 @@ #define UARTE_INTENCLR_ENDRX_Enabled (1UL) /*!< Read: Enabled */ #define UARTE_INTENCLR_ENDRX_Clear (1UL) /*!< Disable */ +/* Bit 2 : Write '1' to Disable interrupt for RXDRDY event */ +#define UARTE_INTENCLR_RXDRDY_Pos (2UL) /*!< Position of RXDRDY field. */ +#define UARTE_INTENCLR_RXDRDY_Msk (0x1UL << UARTE_INTENCLR_RXDRDY_Pos) /*!< Bit mask of RXDRDY field. */ +#define UARTE_INTENCLR_RXDRDY_Disabled (0UL) /*!< Read: Disabled */ +#define UARTE_INTENCLR_RXDRDY_Enabled (1UL) /*!< Read: Enabled */ +#define UARTE_INTENCLR_RXDRDY_Clear (1UL) /*!< Disable */ + /* Bit 1 : Write '1' to Disable interrupt for NCTS event */ #define UARTE_INTENCLR_NCTS_Pos (1UL) /*!< Position of NCTS field. */ #define UARTE_INTENCLR_NCTS_Msk (0x1UL << UARTE_INTENCLR_NCTS_Pos) /*!< Bit mask of NCTS field. */ @@ -12064,9 +12335,9 @@ #define UARTE_PSEL_RXD_PIN_Msk (0x1FUL << UARTE_PSEL_RXD_PIN_Pos) /*!< Bit mask of PIN field. */ /* Register: UARTE_BAUDRATE */ -/* Description: Baud rate */ +/* Description: Baud rate. Accuracy depends on the HFCLK source selected. */ -/* Bits 31..0 : Baud-rate */ +/* Bits 31..0 : Baud rate */ #define UARTE_BAUDRATE_BAUDRATE_Pos (0UL) /*!< Position of BAUDRATE field. */ #define UARTE_BAUDRATE_BAUDRATE_Msk (0xFFFFFFFFUL << UARTE_BAUDRATE_BAUDRATE_Pos) /*!< Bit mask of BAUDRATE field. */ #define UARTE_BAUDRATE_BAUDRATE_Baud1200 (0x0004F000UL) /*!< 1200 baud (actual rate: 1205) */ @@ -12076,7 +12347,9 @@ #define UARTE_BAUDRATE_BAUDRATE_Baud14400 (0x003AF000UL) /*!< 14400 baud (actual rate: 14401) */ #define UARTE_BAUDRATE_BAUDRATE_Baud19200 (0x004EA000UL) /*!< 19200 baud (actual rate: 19208) */ #define UARTE_BAUDRATE_BAUDRATE_Baud28800 (0x0075C000UL) /*!< 28800 baud (actual rate: 28777) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud31250 (0x00800000UL) /*!< 31250 baud */ #define UARTE_BAUDRATE_BAUDRATE_Baud38400 (0x009D0000UL) /*!< 38400 baud (actual rate: 38369) */ +#define UARTE_BAUDRATE_BAUDRATE_Baud56000 (0x00E50000UL) /*!< 56000 baud (actual rate: 55944) */ #define UARTE_BAUDRATE_BAUDRATE_Baud57600 (0x00EB0000UL) /*!< 57600 baud (actual rate: 57554) */ #define UARTE_BAUDRATE_BAUDRATE_Baud76800 (0x013A9000UL) /*!< 76800 baud (actual rate: 76923) */ #define UARTE_BAUDRATE_BAUDRATE_Baud115200 (0x01D60000UL) /*!< 115200 baud (actual rate: 115108) */ @@ -12182,9 +12455,9 @@ #define UICR_PSELRESET_PIN_Msk (0x1FUL << UICR_PSELRESET_PIN_Pos) /*!< Bit mask of PIN field. */ /* Register: UICR_APPROTECT */ -/* Description: Access port protection */ +/* Description: Access Port protection */ -/* Bits 7..0 : Blocks debugger read/write access to all CPU registers and memory mapped addresses */ +/* Bits 7..0 : Enable or disable Access Port protection. Any other value than 0xFF being written to this field will enable protection. */ #define UICR_APPROTECT_PALL_Pos (0UL) /*!< Position of PALL field. */ #define UICR_APPROTECT_PALL_Msk (0xFFUL << UICR_APPROTECT_PALL_Pos) /*!< Bit mask of PALL field. */ #define UICR_APPROTECT_PALL_Enabled (0x00UL) /*!< Enable */ diff --git a/components/device/nrf52_name_change.h b/components/device/nrf52_name_change.h new file mode 100644 index 0000000..61f90ad --- /dev/null +++ b/components/device/nrf52_name_change.h @@ -0,0 +1,70 @@ +/* Copyright (c) 2016, Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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 NRF52_NAME_CHANGE_H +#define NRF52_NAME_CHANGE_H + +/*lint ++flb "Enter library region */ + +/* This file is given to prevent your SW from not compiling with the updates made to nrf52.h and + * nrf52_bitfields.h. The macros defined in this file were available previously. Do not use these + * macros on purpose. Use the ones defined in nrf52.h and nrf52_bitfields.h instead. + */ + +/* I2S */ +/* Several enumerations changed case. Adding old macros to keep compilation compatibility. */ +#define I2S_ENABLE_ENABLE_DISABLE I2S_ENABLE_ENABLE_Disabled +#define I2S_ENABLE_ENABLE_ENABLE I2S_ENABLE_ENABLE_Enabled +#define I2S_CONFIG_MODE_MODE_MASTER I2S_CONFIG_MODE_MODE_Master +#define I2S_CONFIG_MODE_MODE_SLAVE I2S_CONFIG_MODE_MODE_Slave +#define I2S_CONFIG_RXEN_RXEN_DISABLE I2S_CONFIG_RXEN_RXEN_Disabled +#define I2S_CONFIG_RXEN_RXEN_ENABLE I2S_CONFIG_RXEN_RXEN_Enabled +#define I2S_CONFIG_TXEN_TXEN_DISABLE I2S_CONFIG_TXEN_TXEN_Disabled +#define I2S_CONFIG_TXEN_TXEN_ENABLE I2S_CONFIG_TXEN_TXEN_Enabled +#define I2S_CONFIG_MCKEN_MCKEN_DISABLE I2S_CONFIG_MCKEN_MCKEN_Disabled +#define I2S_CONFIG_MCKEN_MCKEN_ENABLE I2S_CONFIG_MCKEN_MCKEN_Enabled +#define I2S_CONFIG_SWIDTH_SWIDTH_8BIT I2S_CONFIG_SWIDTH_SWIDTH_8Bit +#define I2S_CONFIG_SWIDTH_SWIDTH_16BIT I2S_CONFIG_SWIDTH_SWIDTH_16Bit +#define I2S_CONFIG_SWIDTH_SWIDTH_24BIT I2S_CONFIG_SWIDTH_SWIDTH_24Bit +#define I2S_CONFIG_ALIGN_ALIGN_LEFT I2S_CONFIG_ALIGN_ALIGN_Left +#define I2S_CONFIG_ALIGN_ALIGN_RIGHT I2S_CONFIG_ALIGN_ALIGN_Right +#define I2S_CONFIG_FORMAT_FORMAT_ALIGNED I2S_CONFIG_FORMAT_FORMAT_Aligned +#define I2S_CONFIG_CHANNELS_CHANNELS_STEREO I2S_CONFIG_CHANNELS_CHANNELS_Stereo +#define I2S_CONFIG_CHANNELS_CHANNELS_LEFT I2S_CONFIG_CHANNELS_CHANNELS_Left +#define I2S_CONFIG_CHANNELS_CHANNELS_RIGHT I2S_CONFIG_CHANNELS_CHANNELS_Right + +/* LPCOMP */ +/* Corrected typo in RESULT register. */ +#define LPCOMP_RESULT_RESULT_Bellow LPCOMP_RESULT_RESULT_Below + +/*lint --flb "Leave library region" */ + +#endif /* NRF52_NAME_CHANGE_H */ + diff --git a/components/device/nrf52_to_nrf52840.h b/components/device/nrf52_to_nrf52840.h new file mode 100644 index 0000000..3067dcc --- /dev/null +++ b/components/device/nrf52_to_nrf52840.h @@ -0,0 +1,88 @@ +/* Copyright (c) 2016, Nordic Semiconductor ASA + * 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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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 NRF52_TO_NRF52840_H +#define NRF52_TO_NRF52840_H + +/*lint ++flb "Enter library region */ + +/* This file is given to prevent your SW from not compiling with the name changes between nRF51 or nRF52832 and nRF52840 devices. + * It redefines the old nRF51 or nRF52832 names into the new ones as long as the functionality is still supported. If the + * functionality is gone, there old names are not defined, so compilation will fail. Note that also includes macros + * from the nrf52_namechange.h file. */ + +/* Differences between latest nRF52 headers and nRF52840 headers. */ + +/* UART */ +/* The registers PSELRTS, PSELTXD, PSELCTS, PSELRXD were restructured into a struct. */ +#define PSELRTS PSEL.RTS +#define PSELTXD PSEL.TXD +#define PSELCTS PSEL.CTS +#define PSELRXD PSEL.RXD + +/* TWI */ +/* The registers PSELSCL, PSELSDA were restructured into a struct. */ +#define PSELSCL PSEL.SCL +#define PSELSDA PSEL.SDA + + +/* From nrf52_name_change.h. Several macros changed in different versions of nRF52 headers. By defining the following, any code written for any version of nRF52 headers will still compile. */ + +/* I2S */ +/* Several enumerations changed case. Adding old macros to keep compilation compatibility. */ +#define I2S_ENABLE_ENABLE_DISABLE I2S_ENABLE_ENABLE_Disabled +#define I2S_ENABLE_ENABLE_ENABLE I2S_ENABLE_ENABLE_Enabled +#define I2S_CONFIG_MODE_MODE_MASTER I2S_CONFIG_MODE_MODE_Master +#define I2S_CONFIG_MODE_MODE_SLAVE I2S_CONFIG_MODE_MODE_Slave +#define I2S_CONFIG_RXEN_RXEN_DISABLE I2S_CONFIG_RXEN_RXEN_Disabled +#define I2S_CONFIG_RXEN_RXEN_ENABLE I2S_CONFIG_RXEN_RXEN_Enabled +#define I2S_CONFIG_TXEN_TXEN_DISABLE I2S_CONFIG_TXEN_TXEN_Disabled +#define I2S_CONFIG_TXEN_TXEN_ENABLE I2S_CONFIG_TXEN_TXEN_Enabled +#define I2S_CONFIG_MCKEN_MCKEN_DISABLE I2S_CONFIG_MCKEN_MCKEN_Disabled +#define I2S_CONFIG_MCKEN_MCKEN_ENABLE I2S_CONFIG_MCKEN_MCKEN_Enabled +#define I2S_CONFIG_SWIDTH_SWIDTH_8BIT I2S_CONFIG_SWIDTH_SWIDTH_8Bit +#define I2S_CONFIG_SWIDTH_SWIDTH_16BIT I2S_CONFIG_SWIDTH_SWIDTH_16Bit +#define I2S_CONFIG_SWIDTH_SWIDTH_24BIT I2S_CONFIG_SWIDTH_SWIDTH_24Bit +#define I2S_CONFIG_ALIGN_ALIGN_LEFT I2S_CONFIG_ALIGN_ALIGN_Left +#define I2S_CONFIG_ALIGN_ALIGN_RIGHT I2S_CONFIG_ALIGN_ALIGN_Right +#define I2S_CONFIG_FORMAT_FORMAT_ALIGNED I2S_CONFIG_FORMAT_FORMAT_Aligned +#define I2S_CONFIG_CHANNELS_CHANNELS_STEREO I2S_CONFIG_CHANNELS_CHANNELS_Stereo +#define I2S_CONFIG_CHANNELS_CHANNELS_LEFT I2S_CONFIG_CHANNELS_CHANNELS_Left +#define I2S_CONFIG_CHANNELS_CHANNELS_RIGHT I2S_CONFIG_CHANNELS_CHANNELS_Right + +/* LPCOMP */ +/* Corrected typo in RESULT register. */ +#define LPCOMP_RESULT_RESULT_Bellow LPCOMP_RESULT_RESULT_Below + + +/*lint --flb "Leave library region" */ + +#endif /* NRF51_TO_NRF52840_H */ + diff --git a/components/drivers_ext/adns2080/adns2080.c b/components/drivers_ext/adns2080/adns2080.c index 0598eed..bbc9e84 100644 --- a/components/drivers_ext/adns2080/adns2080.c +++ b/components/drivers_ext/adns2080/adns2080.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include @@ -328,4 +356,4 @@ void adns2080_force_mode_set(adns2080_mode_t mode) sdio_write_byte(REG_PERFORMANCE, (uint8_t)((uint8_t)mode << 4)); } -/*lint --flb "Leave library region" */ +/*lint --flb "Leave library region" */ diff --git a/components/drivers_ext/adns2080/adns2080.h b/components/drivers_ext/adns2080/adns2080.h index e69fdcd..6ebe1df 100644 --- a/components/drivers_ext/adns2080/adns2080.h +++ b/components/drivers_ext/adns2080/adns2080.h @@ -1,13 +1,41 @@ - /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ADNS2080_H @@ -18,12 +46,16 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** @file * @brief ADNS2080 mouse sensor driver * * @defgroup nrf_drivers_adns2080 ADNS2080 driver * @{ -* @ingroup nrf_drivers +* @ingroup ext_drivers * @brief ADNS2080 mouse sensor driver. */ @@ -98,8 +130,8 @@ typedef enum * * Valid mouse sensor information will be available 50 milliseconds after this * function finishes. - * - * @return + * + * @return * @retval ADNS2080_OK Mouse sensor was initialized succesfully. * @retval ADNS2080_SERIAL_COMM_FAILURE Serial communications failure. * @retval ADNS2080_CHIP_NOT_DETECTED Could not find revision 0 ADNS2080 chip. @@ -112,7 +144,7 @@ adns2080_status_t adns2080_init(void); * Valid mouse sensor information will be available 50 milliseconds after this * function finishes. * All register settings will be lost and need to be reloaded. - * + * */ void adns2080_reset(void); @@ -148,22 +180,22 @@ void adns2080_powerdown(void); /** * @brief Function for waking up the mouse sensor. * - * After wakeup, all mouse sensor settings must be reloaded. Valid mouse sensor - * information will be available 55 milliseconds after this function finishes. + * After wakeup, all mouse sensor settings must be reloaded. Valid mouse sensor + * information will be available 55 milliseconds after this function finishes. */ void adns2080_wakeup(void); /** * @brief Function for configuring the MOTION interrupt output pin. * - * When motion is detected by the mouse sensor, the chip has a MOTION pin - * indicating there is motion data in DELTA_X and DELTA_Y registers. This + * When motion is detected by the mouse sensor, the chip has a MOTION pin + * indicating there is motion data in DELTA_X and DELTA_Y registers. This * function configures the polarity and sensitivity of that pin. * * Chip is expected to be initialized before calling this function. * * @param polarity MOTION output pin is either active LOW (default) or active HIGH - * @param sensitivity Level or Edge (default) sensitive + * @param sensitivity Level or Edge (default) sensitive * @return * @retval ADNS2080_OK Operation succeeded. * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range. @@ -176,7 +208,7 @@ adns2080_status_t adns2080_motion_interrupt_set(motion_output_polarity_t polarit * Chip is expected to be initialized before calling this function. * * @param resolution Desired resolution. - * @return + * @return * @retval ADNS2080_OK Operation succeeded. * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range. */ @@ -188,7 +220,7 @@ adns2080_status_t adns2080_resolution_set(adns2080_resolution_t resolution); * Chip is expected to be initialized before calling this function. * * @param motion_bits Desired number of bits. - * @return + * @return * @retval ADNS2080_OK Operation succeeded. * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range. */ @@ -206,7 +238,7 @@ adns2080_motion_bits_t adns2080_motion_bits_read(void); /** * @brief Function for reading X- and Y-axis movement (in counts) since last report. * - * Absolute value is determined by resolution. + * Absolute value is determined by resolution. * Chip is expected to be initialized before calling this function. * * @param p_delta_x Location to store X-axis movement @@ -227,7 +259,7 @@ bool adns2080_is_motion_detected(void); /** * @brief Function for setting mouse sensor Rest1, Rest2 and Rest3 mode motion detection time period. - * + * * Allowed range for the periods is 0x01 to 0xFD. * Resulting period is derived from the following equation : * Period = (Rest period + 1) * 10 milliseconds @@ -241,11 +273,11 @@ void adns2080_rest_periods_set(uint8_t rest1_period, uint8_t rest2_period, uint8 /** * @brief Function for setting mouse sensor mode downshift time periods. - * + * * Allowed range for run_to_rest1_mode_time period is 0x00 to 0xFF. - * Allowed range for rest1_to_rest2_mode_time period is 0x01 to 0xFF. - * Allowed range for rest2_to_rest3_mode_time period is 0x01 to 0xFF. - * + * Allowed range for rest1_to_rest2_mode_time period is 0x01 to 0xFF. + * Allowed range for rest2_to_rest3_mode_time period is 0x01 to 0xFF. + * * Chip is expected to be initialized before calling this function. * * @param run_to_rest1_mode_time Run mode to Rest1 mode downshift time period (Time = run_to_rest1_mode_time * 8 * 4) @@ -256,7 +288,7 @@ void adns2080_downshift_times_set(uint8_t run_to_rest1_mode_time, uint8_t rest1_ /** * @brief Function for forcing mouse sensor to a certain operating mode. - * + * * Chip is expected to be initialized before calling this function. * Normal operation will not continue until this function is called with ADNS2080_MODE_NORMAL parameter. * @@ -266,7 +298,7 @@ void adns2080_force_mode_set(adns2080_mode_t mode); /** * @brief Function for reading the current forced operating mode. - * + * * Chip is expected to be initialized before calling this function. * * @return Mode the sensor is forced to. @@ -277,5 +309,10 @@ adns2080_mode_t adns2080_force_mode_read(void); *@} **/ -/*lint --flb "Leave library region" */ +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_ext/cherry8x16/cherry8x16.c b/components/drivers_ext/cherry8x16/cherry8x16.c index 3e106bb..a5f9d29 100644 --- a/components/drivers_ext/cherry8x16/cherry8x16.c +++ b/components/drivers_ext/cherry8x16/cherry8x16.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ @@ -232,8 +260,8 @@ static void cherry8x16_remap_fn_keys(uint8_t * keys, uint8_t number_of_keys) #define MODIFIER_LEFT_CONTROL_HID 0xE0 #define MODIFER_RIGHT_CONTROL_HID 0xE4 - // Check if Fn key is pressed along with any other modifier key (only usage now is Fn+Left_Ctrl = Right Ctrl) - // So we modify the modifier byte if Fn+Left_Ctrl is pressed, HID for left_Ctrl = 0xE0 + // Check if Fn key is pressed along with any other modifier key (only usage now is Fn + Left_Ctrl = Right Ctrl) + // So we modify the modifier byte if Fn + Left_Ctrl is pressed, HID for left_Ctrl = 0xE0 if ( keys[0] & (1UL << (MODIFIER_LEFT_CONTROL_HID - MODIFIER_HID_START)) ) { keys[0] &= ~(1UL << (MODIFIER_LEFT_CONTROL_HID - MODIFIER_HID_START)); diff --git a/components/drivers_ext/cherry8x16/cherry8x16.h b/components/drivers_ext/cherry8x16/cherry8x16.h index 43f8e18..20ab86a 100644 --- a/components/drivers_ext/cherry8x16/cherry8x16.h +++ b/components/drivers_ext/cherry8x16/cherry8x16.h @@ -1,13 +1,41 @@ - /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 CHERRY8x16_H @@ -18,13 +46,17 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** @file * @brief Cherry 8x16 keyboard matrix driver * * * @defgroup nrf_drivers_cherry8x16 Cherry 8x16 keyboard matrix driver * @{ -* @ingroup nrf_drivers +* @ingroup ext_drivers * @brief Cherry 8x16 keyboard matrix driver. */ @@ -34,8 +66,8 @@ #define KEY_PACKET_MODIFIER_KEY_INDEX (0) //!< Index in the key packet where modifier keys such as ALT and Control are stored #define KEY_PACKET_RESERVED_INDEX (1) //!< Index in the key packet where OEMs can store information #define KEY_PACKET_KEY_INDEX (2) //!< Start index in the key packet where pressed keys are stored -#define KEY_PACKET_MAX_KEYS (6) //!< Maximum number of keys that can be stored into the key packet -#define KEY_PACKET_SIZE (KEY_PACKET_KEY_INDEX+KEY_PACKET_MAX_KEYS) //!< Total size of the key packet in bytes +#define KEY_PACKET_MAX_KEYS (6) //!< Maximum number of keys that can be stored into the key packet +#define KEY_PACKET_SIZE (KEY_PACKET_KEY_INDEX + KEY_PACKET_MAX_KEYS) //!< Total size of the key packet in bytes #define KEY_PACKET_NO_KEY (0) //!< Value to be stored to key index to indicate no key is pressed @@ -58,7 +90,7 @@ typedef enum * @param row_port Pointer to GPIO port address that is used as key matrix row input. * @param column_port Pointer to GPIO port address that is used as key matrix column output. * @param key_lookup_matrix If NULL, use a default key lookup matrix. Otherwise pointer to a 128 (8x16) element array containing HID keycodes. - * @return + * @return * @retval CHERRY8X16_OK Peripheral was initialized succesfully. * @retval CHERRY8X16_NOT_DETECTED Could not detect the peripheral. */ @@ -79,5 +111,10 @@ bool cherry8x16_new_packet(const uint8_t ** p_key_packet, uint8_t *p_key_packet_ *@} **/ -/*lint --flb "Leave library region" */ +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_ext/ds1624/ds1624.c b/components/drivers_ext/ds1624/ds1624.c index 21916d7..f2b7a36 100644 --- a/components/drivers_ext/ds1624/ds1624.c +++ b/components/drivers_ext/ds1624/ds1624.c @@ -1,15 +1,43 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - + #include "ds1624.h" #include "twi_master.h" #include "nrf_delay.h" @@ -18,13 +46,13 @@ #define DS1634_BASE_ADDRESS 0x90 //!< 4 MSBs of the DS1624 TWI address -#define DS1624_ONESHOT_MODE 0x01 //!< Bit in configuration register for 1-shot mode +#define DS1624_ONESHOT_MODE 0x01 //!< Bit in configuration register for 1-shot mode #define DS1624_CONVERSION_DONE 0x80 //!< Bit in configuration register to indicate completed temperature conversion static uint8_t m_device_address; //!< Device address in bits [7:1] const uint8_t command_access_memory = 0x17; //!< Reads or writes to 256-byte EEPROM memory -const uint8_t command_access_config = 0xAC; //!< Reads or writes configuration data to configuration register +const uint8_t command_access_config = 0xAC; //!< Reads or writes configuration data to configuration register const uint8_t command_read_temp = 0xAA; //!< Reads last converted temperature value from temperature register const uint8_t command_start_convert_temp = 0xEE; //!< Initiates temperature conversion. const uint8_t command_stop_convert_temp = 0x22; //!< Halts temperature conversion. @@ -112,7 +140,7 @@ bool ds1624_temp_read(int8_t * temperature_in_celcius, int8_t * temperature_frac uint8_t data_buffer[2]; // Read: 2 temperature bytes to data_buffer - if (twi_master_transfer(m_device_address | TWI_READ_BIT, data_buffer, 2, TWI_ISSUE_STOP)) + if (twi_master_transfer(m_device_address | TWI_READ_BIT, data_buffer, 2, TWI_ISSUE_STOP)) { *temperature_in_celcius = (int8_t)data_buffer[0]; *temperature_fraction = (int8_t)data_buffer[1]; @@ -124,4 +152,4 @@ bool ds1624_temp_read(int8_t * temperature_in_celcius, int8_t * temperature_frac return transfer_succeeded; } -/*lint --flb "Leave library region" */ +/*lint --flb "Leave library region" */ diff --git a/components/drivers_ext/ds1624/ds1624.h b/components/drivers_ext/ds1624/ds1624.h index 7441977..ae9556d 100644 --- a/components/drivers_ext/ds1624/ds1624.h +++ b/components/drivers_ext/ds1624/ds1624.h @@ -1,13 +1,41 @@ - /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 DS1624_H @@ -18,13 +46,17 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** @file * @brief DS1624 digital temperature sensor driver. * * * @defgroup nrf_drivers_ds1624 DS1624 digital temperature sensor driver * @{ -* @ingroup nrf_drivers +* @ingroup ext_drivers * @brief DS1624 digital temperature sensor driver. */ @@ -52,7 +84,7 @@ bool ds1624_init(uint8_t device_address); bool ds1624_temp_read(int8_t *temperature_in_celcius, int8_t *temperature_fraction); /** - * @brief Function for starting temperature conversion. Valid data will be available 400-1000 milliseconds after exiting this function. + * @brief Function for starting temperature conversion. Valid data will be available 400 - 1000 milliseconds after exiting this function. * * @return * @retval true Temperature conversion started. @@ -73,5 +105,10 @@ bool ds1624_is_temp_conversion_done(void); *@} **/ -/*lint --flb "Leave library region" */ +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_ext/max9850/max9850.c b/components/drivers_ext/max9850/max9850.c new file mode 100644 index 0000000..b739091 --- /dev/null +++ b/components/drivers_ext/max9850/max9850.c @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "max9850.h" + +#include + +ret_code_t max9850_init(max9850_config_t const * p_max9850) +{ + ret_code_t ret = NRF_SUCCESS; + + ret = nrf_drv_twi_init(&p_max9850->twi, &p_max9850->twi_cfg, NULL, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + nrf_drv_twi_enable(&p_max9850->twi); + + /*Probe device*/ + uint8_t rx[] = {0}; + ret = nrf_drv_twi_rx(&p_max9850->twi, p_max9850->twi_addr, rx, sizeof(rx)); + if (ret != NRF_SUCCESS) + { + return ret; + } + + uint8_t regs[sizeof(max9850_regmap_t) + 1]; + + regs[0] = 0x00; + memcpy(regs + 1, &p_max9850->regmap, sizeof(max9850_regmap_t)); + + /*Write configuration*/ + return nrf_drv_twi_tx(&p_max9850->twi, p_max9850->twi_addr, regs, sizeof(regs), false); +} diff --git a/components/drivers_ext/max9850/max9850.h b/components/drivers_ext/max9850/max9850.h new file mode 100644 index 0000000..620ed5d --- /dev/null +++ b/components/drivers_ext/max9850/max9850.h @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 MAX9850_H__ +#define MAX9850_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "nrf_drv_twi.h" + +/** + * @brief Default MAX9850 TWI configuration + * + * @param scl_pin SCL pin number + * @param sda_pin SDA pin number + */ +#define MAX9850_DEFAULT_TWI_CONFIG(scl_pin, sda_pin) { \ + .scl = scl_pin, \ + .sda = sda_pin, \ + .frequency = NRF_TWI_FREQ_100K, \ + .interrupt_priority = APP_IRQ_PRIORITY_HIGH, \ + .clear_bus_init = false, \ + .hold_bus_uninit = false \ +} + +/** + * @brief Internal MAX9850 register map + * */ +typedef struct { + uint8_t status_a; //!< Status register A (R) + uint8_t status_b; //!< Status register B (R) + uint8_t volume; //!< Volume control (RW) + uint8_t general_purpose; //!< General purpose register (RW) + uint8_t interrupt_enable; //!< Interrupt enable (RW) + uint8_t enable; //!< Enable register (RW) + uint8_t clock; //!< Clock control (RW) + uint8_t charge_pump; //!< Charge pump (RW) + uint8_t lrclk_msb; //!< LRCLK MSB register (RW) + uint8_t lrclk_lsb; //!< LRCLK LSB register (RW) + uint8_t digital_audio; //!< Digital audio (RW) +} max9850_regmap_t; + +/** + * @brief MAX9850 register map after reset + * */ +#define MAX9850_DEFAULT_REGMAP() { \ + .status_a = 0, \ + .status_b = 0, \ + .volume = 0x0C, \ + .general_purpose = 0, \ + .interrupt_enable = 0, \ + .enable = 0, \ + .clock = 0, \ + .charge_pump = 0, \ + .lrclk_msb = 0, \ + .lrclk_lsb = 0, \ + .digital_audio = 0, \ +} + +/** + * @brief Helper macro for creating MAX9850 TWI address + * */ +#define MAX9850_TWI_ADDR(v) (0x10 + (v)) + + +/** + * @brief MAX9850 configuration + * */ +typedef struct { + nrf_drv_twi_t twi; //!< TWI instance + nrf_drv_twi_config_t twi_cfg; //!< TWI configuration + max9850_regmap_t regmap; //!< MAX9850 register map + uint8_t twi_addr; //!< MAX9850 TWI address +} max9850_config_t; + +/** + * @brief Initializes MAX9850 IC + * + * @param p_max9850 MAX9850 configuration + * + * @return Standard error code + * */ +ret_code_t max9850_init(max9850_config_t const * p_max9850); + + +#ifdef __cplusplus +} +#endif + +#endif /* MAX9850_H__ */ diff --git a/components/drivers_ext/mcp4725/mcp4725.c b/components/drivers_ext/mcp4725/mcp4725.c new file mode 100644 index 0000000..cfec5f5 --- /dev/null +++ b/components/drivers_ext/mcp4725/mcp4725.c @@ -0,0 +1,155 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "mcp4725.h" +#include "nrf_drv_twi.h" +#include "nrf_delay.h" +#include "boards.h" +#include "app_util_platform.h" + +/*lint ++flb "Enter library region" */ +#define MCP4725_BASE_ADDRESS 0x60 //!< MCP4725 base address + +#define MCP4725_DAC_ADDRESS 0x40 //!< MCP4725 write-to-dac register +#define MCP4725_EEPROM_ADDRESS 0x60 //!< MCP4725 write-to-eeprom register + +#define RDY_BIT_POS 0x07 //!< Position of RDY bit + +/* TWI instance. */ +static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID_USED); + +/* Twi transfer indicators. */ +volatile bool m_xfer_done = false; +volatile bool m_read_done = false; + +/** + * @brief TWI events handler. + */ +static void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context) +{ + switch (p_event->type) + { + case NRF_DRV_TWI_EVT_DONE: + if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX) + { + m_xfer_done = true; + } + if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX) + { + m_read_done = true; + } + break; + default: + break; + } +} + +/** + * @brief TWI initialization. + */ +static ret_code_t twi_init (void) +{ + ret_code_t err_code; + + const nrf_drv_twi_config_t twi_mcp4725_config = { + .scl = ARDUINO_SCL_PIN, + .sda = ARDUINO_SDA_PIN, + .frequency = NRF_TWI_FREQ_100K, + .interrupt_priority = APP_IRQ_PRIORITY_HIGH, + .clear_bus_init = false + }; + + err_code = nrf_drv_twi_init(&m_twi, &twi_mcp4725_config, twi_handler, NULL); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + nrf_drv_twi_enable(&m_twi); + return NRF_SUCCESS; +} + +ret_code_t mcp4725_setup(void) +{ + ret_code_t err_code = twi_init(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + return NRF_SUCCESS; +} + +ret_code_t mcp4725_set_voltage(uint16_t val, bool write_eeprom) +{ + /* Shift parameter val to get 2 8-bits values. */ + uint8_t reg[3] = {write_eeprom ? MCP4725_EEPROM_ADDRESS : MCP4725_DAC_ADDRESS, + (val>>4), (val<<4)}; + + m_xfer_done = false; + + ret_code_t err_code = nrf_drv_twi_tx(&m_twi, MCP4725_BASE_ADDRESS, reg, sizeof(reg), false); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + while (m_xfer_done == false); + + return NRF_SUCCESS; +} + +bool mcp4725_is_busy(void) +{ + uint8_t busy; + m_read_done = false; + + ret_code_t err_code = nrf_drv_twi_rx(&m_twi, MCP4725_BASE_ADDRESS, &busy, sizeof(busy)); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + while (m_read_done == false); + + return (bool)(!(busy >> RDY_BIT_POS)); +} + +/*lint --flb "Leave library region" */ diff --git a/components/drivers_ext/mcp4725/mcp4725.h b/components/drivers_ext/mcp4725/mcp4725.h new file mode 100644 index 0000000..96a6be4 --- /dev/null +++ b/components/drivers_ext/mcp4725/mcp4725.h @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 MCP4725_H +#define MCP4725_H + +/*lint ++flb "Enter library region" */ + +#include +#include +#include "app_util_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file +* @brief MCP4725 digital DAC driver. +* +* +* @defgroup mcp4725 MCP4725 digital DAC driver +* @{ +* @ingroup ext_drivers +* @brief MCP4725 digital DAC driver. +*/ + +/** + * @brief Function for setting up the driver. + * + * @return Values returned by @ref nrf_drv_twi_init. + */ +ret_code_t mcp4725_setup(void); + + +/** + * @brief Function for setting new value to DAC. + * + * @param[in] val 12-bit value. Base on it voltage is set (Vout = (val/4095) * Vcc). + * @param[in] write_eeprom Defines if value will be written to DAC only or to EEPROM memmory also. + * + * @return Values returned by @ref nrf_drv_twi_tx. + */ +ret_code_t mcp4725_set_voltage(uint16_t val, bool write_eeprom); + +/** + * @brief Function for checking if DAC is busy saving data in EEPROM. + * + * @retval true If DAC is busy. + * @retval false If Dac is not busy. + */ +bool mcp4725_is_busy(void); + +/** + *@} + **/ + +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + +#endif //MCP4725_H diff --git a/components/drivers_ext/mpu6050/mpu6050.c b/components/drivers_ext/mpu6050/mpu6050.c index 9be6aeb..7a67615 100644 --- a/components/drivers_ext/mpu6050/mpu6050.c +++ b/components/drivers_ext/mpu6050/mpu6050.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include diff --git a/components/drivers_ext/mpu6050/mpu6050.h b/components/drivers_ext/mpu6050/mpu6050.h index e9d89f5..3c24510 100644 --- a/components/drivers_ext/mpu6050/mpu6050.h +++ b/components/drivers_ext/mpu6050/mpu6050.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 MPU6050_H @@ -18,13 +46,17 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** @file * @brief MPU6050 gyro/accelerometer driver. * * * @defgroup nrf_drivers_mpu6050 MPU6050 gyro/accelerometer driver * @{ -* @ingroup nrf_drivers +* @ingroup ext_drivers * @brief MPU6050 gyro/accelerometer driver. */ @@ -71,4 +103,9 @@ bool mpu6050_verify_product_id(void); /*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif /* MPU6050_H */ diff --git a/components/drivers_ext/nrf6350/nrf6350.c b/components/drivers_ext/nrf6350/nrf6350.c index 225bc3b..5cb5981 100644 --- a/components/drivers_ext/nrf6350/nrf6350.c +++ b/components/drivers_ext/nrf6350/nrf6350.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2008-2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2008 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "nrf6350.h" @@ -134,9 +162,9 @@ bool nrf6350_lcd_write_string(const char *p_text, uint8_t size, uint8_t line, ui { if (i == LCD_LLEN) break; - data_buffer[i+1] = (uint8_t)*p_text++; + data_buffer[i + 1] = (uint8_t) * p_text++; } - return twi_master_transfer(LCD_ADDR << 1, data_buffer, i+1, TWI_ISSUE_STOP); + return twi_master_transfer(LCD_ADDR << 1, data_buffer, i + 1, TWI_ISSUE_STOP); } bool nrf6350_js_get_value(int8_t * val) @@ -189,7 +217,7 @@ bool nrf6350_js_get_status(uint8_t * js_state) return true; } -/** @brief First time communication with the development kit nRF6350 display will fail, this +/** @brief First time communication with the development kit nRF6350 display will fail, this * returns false on timeout instead of attempting to recover. */ static bool nrf6350_lcd_write_without_recovery(uint8_t * data, diff --git a/components/drivers_ext/nrf6350/nrf6350.h b/components/drivers_ext/nrf6350/nrf6350.h index 447613e..3494077 100644 --- a/components/drivers_ext/nrf6350/nrf6350.h +++ b/components/drivers_ext/nrf6350/nrf6350.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF6350_H_ @@ -16,6 +44,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + #define LCD_LLEN 16 //!< LCD Line length #define JS_BUTTON_NONE 0x00 //!< Joystick not touched @@ -39,7 +71,7 @@ */ bool nrf6350_lcd_init(void); -/** +/** * @brief Function for writing a text string on the LCD-display. * * @param p_text A pointer to the text string to be written @@ -52,7 +84,7 @@ bool nrf6350_lcd_init(void); */ bool nrf6350_lcd_write_string(const char *p_text, uint8_t size, uint8_t line, uint8_t pos); -/** +/** * @brief Function for clearing the contents of the LCD-display. * * @return @@ -72,7 +104,7 @@ bool nrf6350_lcd_clear(void); */ bool nrf6350_lcd_set_contrast(uint8_t contrast); -/** +/** * @brief Function for turning ON the LCD-display. * * @return @@ -81,7 +113,7 @@ bool nrf6350_lcd_set_contrast(uint8_t contrast); */ bool nrf6350_lcd_on(void); -/** +/** * @brief Function for turning OFF the LCD-display. * * @return @@ -90,7 +122,7 @@ bool nrf6350_lcd_on(void); */ bool nrf6350_lcd_off(void); -/** +/** * @brief Function for getting the position of the joystick. * * @param val pointer to a 2 byte array where the X,Y position is stored @@ -100,7 +132,7 @@ bool nrf6350_lcd_off(void); */ bool nrf6350_js_get_value(int8_t *val); -/** +/** * @brief Function for getting the status of the joystick. * * @param js_state pointer to a uint8_t that receives the status of the joystick @@ -114,5 +146,10 @@ bool nrf6350_js_get_status(uint8_t *js_state); */ bool nrf6350_lcd_wake_up(void); + +#ifdef __cplusplus +} +#endif + #endif // NRF6350_H_ /** @} */ diff --git a/components/drivers_ext/segger_rtt/RTT_Syscalls_GCC.c b/components/drivers_ext/segger_rtt/RTT_Syscalls_GCC.c index 3d7429d..f435e5e 100644 --- a/components/drivers_ext/segger_rtt/RTT_Syscalls_GCC.c +++ b/components/drivers_ext/segger_rtt/RTT_Syscalls_GCC.c @@ -39,10 +39,12 @@ -------- END-OF-HEADER --------------------------------------------- File : SEGGER_RTT_Syscalls_GCC.c Purpose : Low-level functions for using printf() via RTT in GCC. - To use RTT for printf output, include this file in your + To use RTT for printf output, include this file in your application. ---------------------------------------------------------------------- */ + +#if defined(NRF_LOG_USES_RTT) && NRF_LOG_USES_RTT == 1 #include #include "SEGGER_RTT.h" @@ -95,4 +97,6 @@ int _write_r(struct _reent *r, int file, char *ptr, int len) { return len; } -/****** End Of File *************************************************/ \ No newline at end of file +#endif +/****** End Of File *************************************************/ + diff --git a/components/drivers_ext/segger_rtt/RTT_Syscalls_IAR.c b/components/drivers_ext/segger_rtt/RTT_Syscalls_IAR.c index 814f1e0..0e87178 100644 --- a/components/drivers_ext/segger_rtt/RTT_Syscalls_IAR.c +++ b/components/drivers_ext/segger_rtt/RTT_Syscalls_IAR.c @@ -39,10 +39,11 @@ -------- END-OF-HEADER --------------------------------------------- File : SEGGER_RTT_Syscalls_IAR.c Purpose : Low-level functions for using printf() via RTT in IAR. - To use RTT for printf output, include this file in your + To use RTT for printf output, include this file in your application and set the Library Configuration to Normal. ---------------------------------------------------------------------- */ +#if defined(NRF_LOG_USES_RTT) && NRF_LOG_USES_RTT == 1 #include #include "SEGGER_RTT.h" #pragma module_name = "?__write" @@ -92,4 +93,6 @@ size_t __write_buffered(int handle, const unsigned char * buffer, size_t size) { SEGGER_RTT_Write(0, (const char*)buffer, size); return size; } + +#endif /*NRF_LOG_USES_RTT==1*/ /****** End Of File *************************************************/ diff --git a/components/drivers_ext/segger_rtt/RTT_Syscalls_KEIL.c b/components/drivers_ext/segger_rtt/RTT_Syscalls_KEIL.c index b4c1fb8..8e07f2f 100644 --- a/components/drivers_ext/segger_rtt/RTT_Syscalls_KEIL.c +++ b/components/drivers_ext/segger_rtt/RTT_Syscalls_KEIL.c @@ -43,6 +43,8 @@ Purpose : Retargeting module for KEIL MDK-CM3. ---------------------------------------------------------------------- */ +#if defined(NRF_LOG_USES_RTT) && NRF_LOG_USES_RTT == 1 + #include #include #include @@ -56,8 +58,9 @@ Purpose : Retargeting module for KEIL MDK-CM3. * ********************************************************************** */ +#ifndef NRF_LOG_USES_RTT #pragma import(__use_no_semihosting) - +#endif #ifdef _MICROLIB #pragma import(__use_full_stdio) #endif @@ -101,7 +104,7 @@ const char __stderr_name[] = "STDERR"; * * Parameters: * c - character to output -* +* */ void _ttywrch(int c) { fputc(c, stdout); // stdout @@ -118,9 +121,9 @@ void _ttywrch(int c) { * Parameters: * sName - sName of the device/file to open * OpenMode - This parameter is currently ignored -* +* * Return value: -* != 0 - Handle to the object to open, otherwise +* != 0 - Handle to the object to open, otherwise * == 0 -"device" is not handled by this module * */ @@ -143,7 +146,7 @@ FILEHANDLE _sys_open(const char * sName, int OpenMode) { * * Parameters: * hFile - Handle to a file opened via _sys_open -* +* * Return value: * 0 - device/file closed * @@ -165,7 +168,7 @@ int _sys_close(FILEHANDLE hFile) { * pBuffer - Pointer to the data that shall be written * NumBytes - Number of bytes to write * Mode - The Mode that shall be used -* +* * Return value: * Number of bytes *not* written to the file/device * @@ -192,7 +195,7 @@ int _sys_write(FILEHANDLE hFile, const unsigned char * pBuffer, unsigned NumByte * pBuffer - Pointer to buffer to store the read data * NumBytes - Number of bytes to read * Mode - The Mode that shall be used -* +* * Return value: * Number of bytes read from the file/device * @@ -206,12 +209,12 @@ int _sys_read(FILEHANDLE hFile, unsigned char * pBuffer, unsigned NumBytes, int * _sys_istty * * Function description: -* This function shall return whether the opened file +* This function shall return whether the opened file * is a console device or not. * * Parameters: * hFile - Handle to a file opened via _sys_open -* +* * Return value: * 1 - Device is a console * 0 - Device is not a console @@ -233,10 +236,10 @@ int _sys_istty(FILEHANDLE hFile) { * * Parameters: * hFile - Handle to a file opened via _sys_open -* Pos - -* +* Pos - +* * Return value: -* int - +* int - * */ int _sys_seek(FILEHANDLE hFile, long Pos) { @@ -248,13 +251,13 @@ int _sys_seek(FILEHANDLE hFile, long Pos) { * _sys_ensure * * Function description: -* +* * * Parameters: * hFile - Handle to a file opened via _sys_open -* +* * Return value: -* int - +* int - * */ int _sys_ensure(FILEHANDLE hFile) { @@ -270,7 +273,7 @@ int _sys_ensure(FILEHANDLE hFile) { * * Parameters: * hFile - Handle to a file opened via _sys_open -* +* * Return value: * Length of the file * @@ -284,17 +287,17 @@ long _sys_flen(FILEHANDLE hFile) { * _sys_tmpnam * * Function description: -* This function converts the file number fileno for a temporary +* This function converts the file number fileno for a temporary * file to a unique filename, for example, tmp0001. * * Parameters: * pBuffer - Pointer to a buffer to store the name * FileNum - file number to convert * MaxLen - Size of the buffer -* +* * Return value: * 1 - Error -* 0 - Success +* 0 - Success * */ int _sys_tmpnam(char * pBuffer, int FileNum, unsigned MaxLen) { @@ -311,7 +314,7 @@ int _sys_tmpnam(char * pBuffer, int FileNum, unsigned MaxLen) { * Parameters: * cmd - Pointer to the command string * len - Length of the string -* +* * Return value: * == NULL - Command was not successfully executed * == sCmd - Command was passed successfully @@ -330,9 +333,11 @@ char * _sys_command_string(char * cmd, int len) { * * Parameters: * ReturnCode - Return code from the main function -* +* * */ void _sys_exit(int ReturnCode) { while (1); // Not implemented } + +#endif // NRF_LOG_USES_RTT == 1 diff --git a/components/drivers_ext/segger_rtt/SEGGER_RTT.c b/components/drivers_ext/segger_rtt/SEGGER_RTT.c index cc72fc2..8b48e05 100644 --- a/components/drivers_ext/segger_rtt/SEGGER_RTT.c +++ b/components/drivers_ext/segger_rtt/SEGGER_RTT.c @@ -580,7 +580,7 @@ unsigned SEGGER_RTT_WriteNoLock(unsigned BufferIndex, const void* pBuffer, unsig unsigned Avail; const char* pData; SEGGER_RTT_RING_BUFFER *pRing; - + pData = (const char *)pBuffer; // // Get "to-host" ring buffer. diff --git a/components/drivers_ext/segger_rtt/SEGGER_RTT.h b/components/drivers_ext/segger_rtt/SEGGER_RTT.h index 07bddb1..dadb259 100644 --- a/components/drivers_ext/segger_rtt/SEGGER_RTT.h +++ b/components/drivers_ext/segger_rtt/SEGGER_RTT.h @@ -39,7 +39,7 @@ ---------------------------END-OF-HEADER------------------------------ File : SEGGER_RTT.h Purpose : Implementation of SEGGER real-time transfer which allows - real-time communication on targets which support debugger + real-time communication on targets which support debugger memory accesses while the CPU is running. ---------------------------------------------------------------------- */ diff --git a/components/drivers_ext/segger_rtt/SEGGER_RTT_Conf.h b/components/drivers_ext/segger_rtt/SEGGER_RTT_Conf.h index ac99664..f5f9667 100644 --- a/components/drivers_ext/segger_rtt/SEGGER_RTT_Conf.h +++ b/components/drivers_ext/segger_rtt/SEGGER_RTT_Conf.h @@ -10,15 +10,17 @@ ********************************************************************** ---------------------------------------------------------------------- File : SEGGER_RTT_Conf.h -Purpose : Implementation of SEGGER real-time transfer (RTT) which - allows real-time communication on targets which support +Purpose : Implementation of SEGGER real-time transfer (RTT) which + allows real-time communication on targets which support debugger memory accesses while the CPU is running. ---------------------------END-OF-HEADER------------------------------ */ #ifndef SEGGER_RTT_CONF_H #define SEGGER_RTT_CONF_H - +#include "sdk_config.h" +#include "compiler_abstraction.h" +#include "app_util_platform.h" #ifdef __ICCARM__ #include #endif @@ -29,12 +31,17 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which * ********************************************************************** */ +#define SEGGER_RTT_MAX_NUM_UP_BUFFERS SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS // Max. number of up-buffers (T->H) available on this target (Default: 2) +#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS // Max. number of down-buffers (H->T) available on this target (Default: 2) -#define SEGGER_RTT_MAX_NUM_UP_BUFFERS (2) // Max. number of up-buffers (T->H) available on this target (Default: 2) -#define SEGGER_RTT_MAX_NUM_DOWN_BUFFERS (2) // Max. number of down-buffers (H->T) available on this target (Default: 2) +//Up Buffer size is set based on RTT configuration and nrf_log configuration. Larger buffer setting is used. +#if defined(NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE) && NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE > SEGGER_RTT_CONFIG_BUFFER_SIZE_UP +#define BUFFER_SIZE_UP NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE // Size of the buffer for terminal output of target, up to host (Default: 1k) +#else +#define BUFFER_SIZE_UP SEGGER_RTT_CONFIG_BUFFER_SIZE_UP // Size of the buffer for terminal output of target, up to host (Default: 1k) +#endif -#define BUFFER_SIZE_UP (1024) // Size of the buffer for terminal output of target, up to host (Default: 1k) -#define BUFFER_SIZE_DOWN (16) // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) +#define BUFFER_SIZE_DOWN SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN // Size of the buffer for terminal input to target from host (Usually keyboard input) (Default: 16) #define SEGGER_RTT_PRINTF_BUFFER_SIZE (64u) // Size of buffer for RTT printf to bulk-send chars via RTT (Default: 64) @@ -47,89 +54,17 @@ Purpose : Implementation of SEGGER real-time transfer (RTT) which // /********************************************************************* * -* RTT lock configuration for SEGGER Embedded Studio, +* RTT lock configuration for SEGGER Embedded Studio, * Rowley CrossStudio and GCC */ -#if (defined __SES_ARM) || (defined __CROSSWORKS_ARM) || (defined __GNUC__) - #ifdef __ARM_ARCH_6M__ - #define SEGGER_RTT_LOCK(SavedState) { \ - asm volatile ("mrs %0, primask \n\t" \ - "mov r1, $1 \n\t" \ - "msr primask, r1 \n\t" \ - : "=r" (SavedState) \ - : \ - : "r1" \ - ); \ - } - - #define SEGGER_RTT_UNLOCK(SavedState) { \ - asm volatile ("msr primask, %0 \n\t" \ - : \ - : "r" (SavedState) \ - : \ - ); \ - } - - #elif (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)) - #define SEGGER_RTT_LOCK(SavedState) { \ - asm volatile ("mrs %0, basepri \n\t" \ - "mov r1, $128 \n\t" \ - "msr basepri, r1 \n\t" \ - : "=r" (SavedState) \ - : \ - : "r1" \ - ); \ - } - #define SEGGER_RTT_UNLOCK(SavedState) { \ - asm volatile ("msr basepri, %0 \n\t" \ - : \ - : "r" (SavedState) \ - : \ - ); \ - } - #else - #define SEGGER_RTT_LOCK(SavedState) (void)(SavedState) - #define SEGGER_RTT_UNLOCK(SavedState) (void)(SavedState) - #endif -#endif - -/********************************************************************* -* -* RTT lock configuration for IAR EWARM -*/ -#ifdef __ICCARM__ - #if (defined (__ARM7M__) && (__CORE__ == __ARM7M__)) - #define SEGGER_RTT_LOCK(SavedState) { \ - SavedState = __get_PRIMASK(); \ - __set_PRIMASK(1); \ - } - - #define SEGGER_RTT_UNLOCK(SavedState) { \ - __set_PRIMASK(SavedState); \ - } - #elif (defined (__ARM7EM__) && (__CORE__ == __ARM7EM__)) - #define SEGGER_RTT_LOCK(SavedState) { \ - SavedState = __get_BASEPRI(); \ - __set_BASEPRI(128); \ - } - - #define SEGGER_RTT_UNLOCK(SavedState) { \ - __set_BASEPRI(SavedState); \ - } - #endif -#endif -/********************************************************************* -* -* RTT lock configuration fallback -*/ -#ifndef SEGGER_RTT_LOCK - #define SEGGER_RTT_LOCK(SavedState) (void)(SavedState) -#endif +#define SEGGER_RTT_LOCK(SavedState) \ + SavedState = 0; \ + CRITICAL_REGION_ENTER() -#ifndef SEGGER_RTT_UNLOCK - #define SEGGER_RTT_UNLOCK(SavedState) (void)(SavedState) -#endif +#define SEGGER_RTT_UNLOCK(SavedState) \ + (void)SavedState; \ + CRITICAL_REGION_EXIT() -#endif /*************************** End of file ****************************/ +#endif // SEGGER_RTT_CONF_H diff --git a/components/drivers_ext/segger_rtt/SEGGER_RTT_printf.c b/components/drivers_ext/segger_rtt/SEGGER_RTT_printf.c index d1878f3..5c40368 100644 --- a/components/drivers_ext/segger_rtt/SEGGER_RTT_printf.c +++ b/components/drivers_ext/segger_rtt/SEGGER_RTT_printf.c @@ -41,6 +41,9 @@ File : SEGGER_RTT_printf.c Purpose : Replacement for printf to write formatted data via RTT ---------------------------------------------------------------------- */ + +#if defined(NRF_LOG_USES_RTT) && NRF_LOG_USES_RTT == 1 + #include "SEGGER_RTT.h" #include "SEGGER_RTT_Conf.h" @@ -489,4 +492,8 @@ int SEGGER_RTT_printf(unsigned BufferIndex, const char * sFormat, ...) { va_start(ParamList, sFormat); return SEGGER_RTT_vprintf(BufferIndex, sFormat, &ParamList); } + + +#endif /* NRF_LOG_USES_RTT == 1 */ + /*************************** End of file ****************************/ diff --git a/components/drivers_ext/segger_rtt/license/license.txt b/components/drivers_ext/segger_rtt/license/license.txt new file mode 100644 index 0000000..1fe5b11 --- /dev/null +++ b/components/drivers_ext/segger_rtt/license/license.txt @@ -0,0 +1,38 @@ +/********************************************************************* +* SEGGER MICROCONTROLLER GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 2014 - 2015 SEGGER Microcontroller GmbH & Co. KG * +* * +* www.segger.com Support: support@segger.com * +* * +********************************************************************** +* * +* All rights reserved. * +* * +* * This software may in its unmodified form be freely redistributed * +* in source form. * +* * The source code may be modified, provided the source code * +* retains the above copyright notice, this list of conditions and * +* the following disclaimer. * +* * Modified versions of this software in source or linkable form * +* may not be distributed without prior consent of SEGGER. * +* * This software may only be used for communication with SEGGER * +* J-Link debug probes. * +* * +* 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 SEGGER Microcontroller 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. * +* * +********************************************************************** diff --git a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c b/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c index bc955cf..49963a2 100644 --- a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c +++ b/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include @@ -82,7 +110,7 @@ bool touchpad_read_register(uint8_t register_address, uint8_t *value) { bool transfer_succeeded = true; transfer_succeeded &= twi_master_transfer(m_device_address, ®ister_address, 1, TWI_DONT_ISSUE_STOP); - if (transfer_succeeded) + if (transfer_succeeded) { transfer_succeeded &= twi_master_transfer(m_device_address | TWI_READ_BIT, value, 1, TWI_ISSUE_STOP); } @@ -105,7 +133,7 @@ bool touchpad_product_id_read(uint8_t * product_id, uint8_t product_id_bytes) w2_data[0] = TOUCHPAD_PRODUCT_ID; transfer_succeeded &= twi_master_transfer(m_device_address, w2_data, 1, TWI_DONT_ISSUE_STOP); - if (transfer_succeeded) + if (transfer_succeeded) { transfer_succeeded &= twi_master_transfer(m_device_address | TWI_READ_BIT, product_id, product_id_bytes, TWI_ISSUE_STOP); } diff --git a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h b/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h index a892f59..f4bb130 100644 --- a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h +++ b/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SYNAPTICS_TOUCHPAD_H @@ -18,18 +46,22 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** @file * @brief Synaptics Touchpad driver * * -* @defgroup nrf_drivers_synaptics_touchpad Synaptics Touchpad driver. +* @defgroup nrf_drivers_synaptics_touchpad Synaptics Touchpad driver * @{ -* @ingroup nrf_drivers +* @ingroup ext_drivers * @brief Synaptics Touchpad driver. */ /** - Touchpad register addresses. + Touchpad register addresses. */ #define TOUCHPAD_INT_STATUS 0x14 //!< Interrupt status register #define TOUCHPAD_BUTTON_STATUS 0x41 //!< Button status register @@ -46,8 +78,8 @@ /** Operational states */ -typedef enum -{ +typedef enum +{ SleepmodeNormal = 0x00, //!< Normal operation SleepmodeSensorSleep = 0x01 //!< Low power operation } TouchpadSleepMode_t; @@ -85,7 +117,7 @@ bool touchpad_interrupt_status_read(uint8_t *interrupt_status); bool touchpad_set_sleep_mode(TouchpadSleepMode_t mode); /** - @brief Function for reading a touchpad register contents over TWI. + @brief Function for reading a touchpad register contents over TWI. @param[in] register_address Register address @param[out] value Pointer to a data buffer where read data will be stored @retval true Register read succeeded @@ -125,4 +157,9 @@ bool touchpad_product_id_verify(void); /*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif /* __TOUCHPAD_H__ */ diff --git a/components/drivers_ext/uda1380/uda1380.c b/components/drivers_ext/uda1380/uda1380.c new file mode 100644 index 0000000..7184f33 --- /dev/null +++ b/components/drivers_ext/uda1380/uda1380.c @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "uda1380.h" +#include + +ret_code_t uda1380_init(uda1380_iface_t const * p_iface, + uda1380_reg_t const * p_reg_config, + size_t reg_size) +{ + ret_code_t ret = NRF_SUCCESS; + + ret = nrf_drv_twi_init(&p_iface->twi, &p_iface->twi_cfg, NULL, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + nrf_drv_twi_enable(&p_iface->twi); + + /*Probe device*/ + uint8_t rx[] = {0}; + ret = nrf_drv_twi_rx(&p_iface->twi, p_iface->twi_addr, rx, sizeof(rx)); + if (ret != NRF_SUCCESS) + { + return ret; + } + + for (size_t i = 0; i < reg_size; ++i) + { + uint8_t p_dat[sizeof(uda1380_reg_t)]; + memcpy(p_dat, &p_reg_config[i], sizeof(uda1380_reg_t)); + ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false); + if (ret != NRF_SUCCESS) + { + break; + } + } + + return ret; +} + + +ret_code_t uda1380_enable(uda1380_iface_t const * p_iface) +{ + ret_code_t ret = NRF_SUCCESS; + + static const uda1380_reg_t enable[] = { + UDA1380_REG_INIT(UDA1380_REG_PWR, 0xA500), + UDA1380_REG_INIT(UDA1380_REG_CLK, 0x0332), + }; + + for (size_t i = 0; i < ARRAY_SIZE(enable); ++i) + { + uint8_t p_dat[sizeof(uda1380_reg_t)]; + memcpy(p_dat, &enable[i], sizeof(uda1380_reg_t)); + ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false); + if (ret != NRF_SUCCESS) + { + break; + } + } + + return ret; +} + + +ret_code_t uda1380_disable(uda1380_iface_t const * p_iface) +{ + ret_code_t ret = NRF_SUCCESS; + + static const uda1380_reg_t disable[] = { + UDA1380_REG_INIT(UDA1380_REG_PWR, 0x0000), + UDA1380_REG_INIT(UDA1380_REG_CLK, 0x0000), + }; + + for (size_t i = 0; i < ARRAY_SIZE(disable); ++i) + { + const uint8_t * p_dat = (const uint8_t *)&disable[i]; + ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false); + if (ret != NRF_SUCCESS) + { + break; + } + } + + return ret; +} diff --git a/components/drivers_ext/uda1380/uda1380.h b/components/drivers_ext/uda1380/uda1380.h new file mode 100644 index 0000000..021c2a7 --- /dev/null +++ b/components/drivers_ext/uda1380/uda1380.h @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 UDA1380_H__ +#define UDA1380_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "nrf_drv_twi.h" + + +#define UDA1380_REG_CLK 0x00 +#define UDA1380_REG_I2S 0x01 +#define UDA1380_REG_PWR 0x02 +#define UDA1380_REG_AMIX 0x03 +#define UDA1380_REG_HPA 0x04 + +#define UDA1380_REG_VOL 0x10 +#define UDA1380_REG_MIX_VOL 0x11 +#define UDA1380_REG_PPROC 0x12 +#define UDA1380_REG_DEEMP 0x13 +#define UDA1380_REG_MIXER 0x14 + +#define UDA1380_REG_RESET 0x7F + + +/** + * @brief Default UDA1380 TWI configuration + * + * @param scl_pin SCL pin number + * @param sda_pin SDA pin number + */ +#define UDA1380_DEFAULT_TWI_CONFIG(scl_pin, sda_pin) { \ + .scl = scl_pin, \ + .sda = sda_pin, \ + .frequency = NRF_TWI_FREQ_100K, \ + .interrupt_priority = APP_IRQ_PRIORITY_HIGH, \ + .clear_bus_init = false, \ + .hold_bus_uninit = false \ +} + +/** + * @brief UDA1380 register descriptor + * */ +typedef struct { + uint8_t addr; //!< Internal register address + uint8_t val[2]; //!< Internal register value +} uda1380_reg_t; + +#define UDA1380_REG_INIT(address, value) { \ + .addr = address, \ + .val = {(value) / 256, (value) & 0xFF}, \ +} + +/** + * @brief UDA1380 TWI bus address*/ +#define UDA1380_TWI_ADDRESS (0x18) + +/** + * @brief UDA1380 interface + * */ +typedef struct { + nrf_drv_twi_t twi; //!< TWI instance + nrf_drv_twi_config_t twi_cfg; //!< TWI configuration + uint8_t twi_addr; //!< UDA1380 TWI address +} uda1380_iface_t; + + +/** + * @brief Initializes UDA1380 codec IC + * + * @param p_iface Communication interface + * @param p_reg_config Configuration registers + * @param reg_size Number of configuration registers + * + * @return Standard error code + * */ +ret_code_t uda1380_init(uda1380_iface_t const * p_iface, + uda1380_reg_t const * p_reg_config, + size_t reg_size); + +/** + * @brief Enable UDA1380 codec + * + * @return Standard error code + * */ +ret_code_t uda1380_enable(uda1380_iface_t const * p_iface); + + +/** + * @brief Disable UDA1380 codec + * + * @return Standard error code + * */ +ret_code_t uda1380_disable(uda1380_iface_t const * p_iface); + +#ifdef __cplusplus +} +#endif + +#endif /* UDA1380_H__ */ diff --git a/components/drivers_nrf/adc/nrf_drv_adc.c b/components/drivers_nrf/adc/nrf_drv_adc.c new file mode 100644 index 0000000..050dc42 --- /dev/null +++ b/components/drivers_nrf/adc/nrf_drv_adc.c @@ -0,0 +1,329 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(ADC) +#include "nrf_drv_adc.h" +#include "nrf_drv_common.h" +#include "nrf_assert.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "ADC" + +#if ADC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL ADC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR ADC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR ADC_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_ADC_EVENT_END ? "NRF_ADC_EVENT_END" : "UNKNOWN EVENT") +#else //ADC_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //ADC_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +typedef struct +{ + nrf_drv_adc_event_handler_t event_handler; + nrf_drv_adc_channel_t * p_head; + nrf_drv_adc_channel_t * p_current_conv; + nrf_adc_value_t * p_buffer; + uint8_t size; + uint8_t idx; + nrf_drv_state_t state; +} adc_cb_t; + +static adc_cb_t m_cb; +static const nrf_drv_adc_config_t m_default_config = NRF_DRV_ADC_DEFAULT_CONFIG; + +ret_code_t nrf_drv_adc_init(nrf_drv_adc_config_t const * p_config, + nrf_drv_adc_event_handler_t event_handler) +{ + ret_code_t err_code; + + if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + nrf_adc_event_clear(NRF_ADC_EVENT_END); + if (event_handler) + { + if (!p_config) + { + p_config = (nrf_drv_adc_config_t *)&m_default_config; + } + nrf_drv_common_irq_enable(ADC_IRQn, p_config->interrupt_priority); + } + m_cb.event_handler = event_handler; + m_cb.state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + +void nrf_drv_adc_uninit(void) +{ + m_cb.p_head = NULL; + nrf_drv_common_irq_disable(ADC_IRQn); + nrf_adc_int_disable(NRF_ADC_INT_END_MASK); + nrf_adc_task_trigger(NRF_ADC_TASK_STOP); + + m_cb.state = NRF_DRV_STATE_UNINITIALIZED; +} + +void nrf_drv_adc_channel_enable(nrf_drv_adc_channel_t * const p_channel) +{ + ASSERT(!is_address_from_stack(p_channel)); + ASSERT(!nrf_drv_adc_is_busy()); + + p_channel->p_next = NULL; + if (m_cb.p_head == NULL) + { + m_cb.p_head = p_channel; + } + else + { + nrf_drv_adc_channel_t * p_curr_channel = m_cb.p_head; + while (p_curr_channel->p_next != NULL) + { + ASSERT(p_channel != p_curr_channel); + p_curr_channel = p_curr_channel->p_next; + } + p_curr_channel->p_next = p_channel; + } + + NRF_LOG_INFO("Enabled.\r\n"); +} + +void nrf_drv_adc_channel_disable(nrf_drv_adc_channel_t * const p_channel) +{ + ASSERT(m_cb.p_head); + ASSERT(!nrf_drv_adc_is_busy()); + + nrf_drv_adc_channel_t * p_curr_channel = m_cb.p_head; + nrf_drv_adc_channel_t * p_prev_channel = NULL; + while (p_curr_channel != p_channel) + { + p_prev_channel = p_curr_channel; + p_curr_channel = p_curr_channel->p_next; + ASSERT(p_curr_channel != NULL); + } + if (p_prev_channel) + { + p_prev_channel->p_next = p_curr_channel->p_next; + } + else + { + m_cb.p_head = p_curr_channel->p_next; + } + + NRF_LOG_INFO("Disabled.\r\n"); +} + +void nrf_drv_adc_sample(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(!nrf_adc_is_busy()); + nrf_adc_start(); +} + +ret_code_t nrf_drv_adc_sample_convert(nrf_drv_adc_channel_t const * const p_channel, + nrf_adc_value_t * p_value) +{ + ret_code_t err_code; + + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + if (m_cb.state == NRF_DRV_STATE_POWERED_ON) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + else + { + m_cb.state = NRF_DRV_STATE_POWERED_ON; + + nrf_adc_config_set(p_channel->config.data); + nrf_adc_enable(); + nrf_adc_int_disable(NRF_ADC_INT_END_MASK); + nrf_adc_start(); + if (p_value) + { + while (!nrf_adc_event_check(NRF_ADC_EVENT_END)) {} + nrf_adc_event_clear(NRF_ADC_EVENT_END); + *p_value = (nrf_adc_value_t)nrf_adc_result_get(); + nrf_adc_disable(); + + m_cb.state = NRF_DRV_STATE_INITIALIZED; + } + else + { + ASSERT(m_cb.event_handler); + m_cb.p_buffer = NULL; + nrf_adc_int_enable(NRF_ADC_INT_END_MASK); + } + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } +} + +static bool adc_sample_process() +{ + nrf_adc_event_clear(NRF_ADC_EVENT_END); + nrf_adc_disable(); + m_cb.p_buffer[m_cb.idx] = (nrf_adc_value_t)nrf_adc_result_get(); + m_cb.idx++; + if (m_cb.idx < m_cb.size) + { + bool task_trigger = false; + if (m_cb.p_current_conv->p_next == NULL) + { + m_cb.p_current_conv = m_cb.p_head; + } + else + { + m_cb.p_current_conv = m_cb.p_current_conv->p_next; + task_trigger = true; + } + nrf_adc_config_set(m_cb.p_current_conv->config.data); + nrf_adc_enable(); + if (task_trigger) + { + //nrf_adc_start(); + nrf_adc_task_trigger(NRF_ADC_TASK_START); + } + return false; + } + else + { + return true; + } +} + +ret_code_t nrf_drv_adc_buffer_convert(nrf_adc_value_t * buffer, uint16_t size) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + + NRF_LOG_INFO("Number of samples requested to convert: %d.\r\n", size); + + if (m_cb.state == NRF_DRV_STATE_POWERED_ON) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + else + { + m_cb.state = NRF_DRV_STATE_POWERED_ON; + m_cb.p_current_conv = m_cb.p_head; + m_cb.size = size; + m_cb.idx = 0; + m_cb.p_buffer = buffer; + nrf_adc_config_set(m_cb.p_current_conv->config.data); + nrf_adc_event_clear(NRF_ADC_EVENT_END); + nrf_adc_enable(); + if (m_cb.event_handler) + { + nrf_adc_int_enable(NRF_ADC_INT_END_MASK); + } + else + { + while (1) + { + while (!nrf_adc_event_check(NRF_ADC_EVENT_END)){} + + if (adc_sample_process()) + { + m_cb.state = NRF_DRV_STATE_INITIALIZED; + break; + } + } + } + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } +} + +bool nrf_drv_adc_is_busy(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + return (m_cb.state == NRF_DRV_STATE_POWERED_ON) ? true : false; +} + +void ADC_IRQHandler(void) +{ + if (m_cb.p_buffer == NULL) + { + nrf_adc_event_clear(NRF_ADC_EVENT_END); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_ADC_EVENT_END)); + nrf_adc_int_disable(NRF_ADC_INT_END_MASK); + nrf_adc_disable(); + nrf_drv_adc_evt_t evt; + evt.type = NRF_DRV_ADC_EVT_SAMPLE; + evt.data.sample.sample = (nrf_adc_value_t)nrf_adc_result_get(); + NRF_LOG_DEBUG("ADC data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)(&evt.data.sample.sample), sizeof(nrf_adc_value_t)); + m_cb.state = NRF_DRV_STATE_INITIALIZED; + m_cb.event_handler(&evt); + } + else if (adc_sample_process()) + { + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_ADC_EVENT_END)); + nrf_adc_int_disable(NRF_ADC_INT_END_MASK); + nrf_drv_adc_evt_t evt; + evt.type = NRF_DRV_ADC_EVT_DONE; + evt.data.done.p_buffer = m_cb.p_buffer; + evt.data.done.size = m_cb.size; + m_cb.state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_DEBUG("ADC data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)m_cb.p_buffer, m_cb.size * sizeof(nrf_adc_value_t)); + m_cb.event_handler(&evt); + } +} +#endif // NRF_MODULE_ENABLED(ADC) diff --git a/components/drivers_nrf/adc/nrf_drv_adc.h b/components/drivers_nrf/adc/nrf_drv_adc.h new file mode 100644 index 0000000..7eb3011 --- /dev/null +++ b/components/drivers_nrf/adc/nrf_drv_adc.h @@ -0,0 +1,295 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_adc.h" +#include "sdk_config.h" +#include "sdk_errors.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup nrf_adc ADC HAL and driver + * @ingroup nrf_drivers + * @brief Analog-to-digital converter (ADC) APIs. + * @details The ADC HAL provides basic APIs for accessing the registers of the analog-to-digital converter. + * The ADC driver provides APIs on a higher level. + * + * @defgroup nrf_drv_adc ADC driver + * @{ + * @ingroup nrf_adc + * @brief Analog-to-digital converter (ADC) driver. + */ + +/** + * @brief Driver event types. + */ +typedef enum +{ + NRF_DRV_ADC_EVT_DONE, ///< Event generated when the buffer is filled with samples. + NRF_DRV_ADC_EVT_SAMPLE, ///< Event generated when the requested channel is sampled. +} nrf_drv_adc_evt_type_t; + +typedef int16_t nrf_adc_value_t; + +/** + * @brief Analog-to-digital converter driver DONE event. + */ +typedef struct +{ + nrf_adc_value_t * p_buffer; ///< Pointer to buffer with converted samples. + uint16_t size; ///< Number of samples in the buffer. +} nrf_drv_adc_done_evt_t; + +/** + * @brief Analog-to-digital converter driver SAMPLE event. + */ +typedef struct +{ + nrf_adc_value_t sample; ///< Converted sample. +} nrf_drv_adc_sample_evt_t; + +/** + * @brief Analog-to-digital converter driver event. + */ +typedef struct +{ + nrf_drv_adc_evt_type_t type; ///< Event type. + union + { + nrf_drv_adc_done_evt_t done; ///< Data for DONE event. + nrf_drv_adc_sample_evt_t sample; ///< Data for SAMPLE event. + } data; +} nrf_drv_adc_evt_t; + +/**@brief Macro for initializing the ADC channel with the default configuration. */ +#define NRF_DRV_ADC_DEFAULT_CHANNEL(analog_input) \ + {{{ \ + .resolution = NRF_ADC_CONFIG_RES_10BIT, \ + .input = NRF_ADC_CONFIG_SCALING_INPUT_FULL_SCALE, \ + .reference = NRF_ADC_CONFIG_REF_VBG, \ + .ain = (analog_input) \ + }}, NULL} + +/** + * @brief ADC channel configuration. + * + * @note The bit fields reflect bit fields in the ADC CONFIG register. + */ +typedef struct +{ + uint32_t resolution :2; ///< 8 - 10 bit resolution. + uint32_t input :3; ///< Input selection and scaling. + uint32_t reference :2; ///< Reference source. + uint32_t reserved :1; ///< Unused bit fields. + uint32_t ain :8; ///< Analog input. + uint32_t external_reference:2; ///< Eternal reference source. +}nrf_drv_adc_channel_config_t; + +// Forward declaration of the nrf_drv_adc_channel_t type. +typedef struct nrf_drv_adc_channel_s nrf_drv_adc_channel_t; + +/** + * @brief ADC channel. + * + * This structure is defined by the user and used by the driver. Therefore, it should + * not be defined on the stack as a local variable. + */ +struct nrf_drv_adc_channel_s +{ + union + { + nrf_drv_adc_channel_config_t config; ///< Channel configuration. + uint32_t data; ///< Raw value. + } config; + nrf_drv_adc_channel_t * p_next; ///< Pointer to the next enabled channel (for internal use). +}; + +/** + * @brief ADC configuration. + */ +typedef struct +{ + uint8_t interrupt_priority; ///< Priority of ADC interrupt. +} nrf_drv_adc_config_t; + +/** @brief ADC default configuration. */ +#define NRF_DRV_ADC_DEFAULT_CONFIG \ +{ \ + .interrupt_priority = ADC_CONFIG_IRQ_PRIORITY \ +} + +/** + * @brief User event handler prototype. + * + * This function is called when the requested number of samples has been processed. + * + * @param p_event Event. + */ +typedef void (*nrf_drv_adc_event_handler_t)(nrf_drv_adc_evt_t const * p_event); + +/** + * @brief Function for initializing the ADC. + * + * If a valid event handler is provided, the driver is initialized in non-blocking mode. + * If event_handler is NULL, the driver works in blocking mode. + * + * @param[in] p_config Driver configuration. + * @param[in] event_handler Event handler provided by the user. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is already initialized. + */ +ret_code_t nrf_drv_adc_init(nrf_drv_adc_config_t const * p_config, + nrf_drv_adc_event_handler_t event_handler); + +/** + * @brief Function for uninitializing the ADC. + * + * This function stops all ongoing conversions and disables all channels. + */ +void nrf_drv_adc_uninit(void); + +/** + * @brief Function for enabling an ADC channel. + * + * This function configures and enables the channel. When @ref nrf_drv_adc_buffer_convert is + * called, all channels that have been enabled with this function are sampled. + * + * @note The channel instance variable @p p_channel is used by the driver as an item + * in a list. Therefore, it cannot be an automatic variable, and an assertion fails if it is + * an automatic variable (if asserts are enabled). + */ +void nrf_drv_adc_channel_enable(nrf_drv_adc_channel_t * const p_channel); + +/** + * @brief Function for disabling an ADC channel. + */ +void nrf_drv_adc_channel_disable(nrf_drv_adc_channel_t * const p_channel); + +/** + * @brief Function for starting ADC sampling. + * + * This function triggers single ADC sampling. If more than one channel is enabled, the driver + * emulates scanning and all channels are sampled in the order they were enabled. + */ +void nrf_drv_adc_sample(void); + +/** + * @brief Function for executing a single ADC conversion. + * + * This function selects the desired input and starts a single conversion. If a valid pointer + * is provided for the result, the function blocks until the conversion is completed. Otherwise, the + * function returns when the conversion is started, and the result is provided in an event (driver + * must be initialized in non-blocking mode otherwise an assertion will fail). The function will fail if + * ADC is busy. The channel does not need to be enabled to perform a single conversion. + * + * @param[in] p_channel Channel. + * @param[out] p_value Pointer to the location where the result should be placed. Unless NULL is + * provided, the function is blocking. + * + * @retval NRF_SUCCESS If conversion was successful. + * @retval NRF_ERROR_BUSY If the ADC driver is busy. + */ +ret_code_t nrf_drv_adc_sample_convert(nrf_drv_adc_channel_t const * const p_channel, + nrf_adc_value_t * p_value); + +/** + * @brief Function for converting data to the buffer. + * + * If the driver is initialized in non-blocking mode, this function returns when the first conversion + * is set up. When the buffer is filled, the application is notified by the event handler. If the + * driver is initialized in blocking mode, the function returns when the buffer is filled. + * + * Conversion is done on all enabled channels, but it is not triggered by this + * function. This function will prepare the ADC for sampling and then + * wait for the SAMPLE task. Sampling can be triggered manually by the @ref + * nrf_drv_adc_sample function or by PPI using the @ref NRF_ADC_TASK_START task. + * + * @note If more than one channel is enabled, the function emulates scanning, and + * a single START task will trigger conversion on all enabled channels. For example: + * If 3 channels are enabled and the user requests 6 samples, the completion event + * handler will be called after 2 START tasks. + * @note The application must adjust the sampling frequency. The maximum frequency + * depends on the sampling timer and the maximum latency of the ADC interrupt. If + * an interrupt is not handled before the next sampling is triggered, the sample + * will be lost. + * + * @param[in] buffer Result buffer. + * @param[in] size Buffer size in samples. + * + * @retval NRF_SUCCESS If conversion was successful. + * @retval NRF_ERROR_BUSY If the driver is busy. + */ +ret_code_t nrf_drv_adc_buffer_convert(nrf_adc_value_t * buffer, uint16_t size); + +/** + * @brief Function for retrieving the ADC state. + * + * @retval true If the ADC is busy. + * @retval false If the ADC is ready. + */ +bool nrf_drv_adc_is_busy(void); + +/** + * @brief Function for getting the address of the ADC START task. + * + * This function is used to get the address of the START task, which can be used to trigger ADC + * conversion. + * + * @return Start task address. + */ +__STATIC_INLINE uint32_t nrf_drv_adc_start_task_get(void); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t nrf_drv_adc_start_task_get(void) +{ + return nrf_adc_task_address_get(NRF_ADC_TASK_START); +} + +#ifdef __cplusplus +} +#endif + +#endif +/** @} */ diff --git a/components/drivers_nrf/ble_flash/ble_flash.c b/components/drivers_nrf/ble_flash/ble_flash.c index fbe3034..57dd661 100644 --- a/components/drivers_nrf/ble_flash/ble_flash.c +++ b/components/drivers_nrf/ble_flash/ble_flash.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_flash.h" @@ -42,7 +70,7 @@ uint16_t ble_flash_crc16_compute(uint8_t * p_data, uint16_t size, uint16_t * p_c /**@brief Function for erasing a page in flash. - * + * * @param[in] p_page Pointer to first word in page to be erased. */ static void flash_page_erase(uint32_t * p_page) @@ -89,7 +117,7 @@ static void flash_word_unprotected_write(uint32_t * p_address, uint32_t value) // Do nothing. } *p_address = value; - + // Wait flash write to finish while (NRF_NVMC->READY == NVMC_READY_READY_Busy) { @@ -237,7 +265,7 @@ uint32_t ble_flash_page_read(uint8_t page_num, uint32_t * p_out_array, uint8_t * uint16_t calc_crc; uint32_t tmp; - p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num); + p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_num); p_curr_addr = p_page; // Check if block is valid diff --git a/components/drivers_nrf/ble_flash/ble_flash.h b/components/drivers_nrf/ble_flash/ble_flash.h index 22c1583..ad135f1 100644 --- a/components/drivers_nrf/ble_flash/ble_flash.h +++ b/components/drivers_nrf/ble_flash/ble_flash.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -34,20 +62,24 @@ #include #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + #define BLE_FLASH_PAGE_SIZE ((uint16_t)NRF_FICR->CODEPAGESIZE) /**< Size of one flash page. */ #define BLE_FLASH_MAGIC_NUMBER 0x45DE0000 /**< Magic value to identify if flash contains valid data. */ #define BLE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */ /**@brief Macro for getting the end of the flash available for application. - * - * @details The result flash page number indicates the end boundary of the flash available - * to the application. If a bootloader is used, the end will be the start of the - * bootloader region. Otherwise, the end will be the size of the flash. + * + * @details The result flash page number indicates the end boundary of the flash available + * to the application. If a bootloader is used, the end will be the start of the + * bootloader region. Otherwise, the end will be the size of the flash. */ #define BLE_FLASH_PAGE_END \ - ((NRF_UICR->BOOTLOADERADDR != BLE_FLASH_EMPTY_MASK) \ - ? (NRF_UICR->BOOTLOADERADDR / BLE_FLASH_PAGE_SIZE) \ + ((NRF_UICR->NRFFW[0] != BLE_FLASH_EMPTY_MASK) \ + ? (NRF_UICR->NRFFW[0] / BLE_FLASH_PAGE_SIZE) \ : NRF_FICR->CODESIZE) /**@brief Function for erasing the specified flash page, and then writes the given data to this page. @@ -66,12 +98,12 @@ uint32_t ble_flash_page_write(uint8_t page_num, uint32_t * p_in_array, uint8_t w /**@brief Function for reading data from flash to RAM. * * @param[in] page_num Page number to read. - * @param[out] p_out_array Pointer to a RAM area where the found data will be written. + * @param[out] p_out_array Pointer to a RAM area where the found data will be written. * This area has to be 32 bits aligned. * @param[out] p_word_count Number of 32 bits words read. * * @return NRF_SUCCESS on successful upload, NRF_ERROR_NOT_FOUND if no valid data has been found - * in flash (first 32 bits not equal to the MAGIC_NUMBER+CRC). + * in flash (first 32 bits not equal to the MAGIC_NUMBER + CRC). */ uint32_t ble_flash_page_read(uint8_t page_num, uint32_t * p_out_array, uint8_t * p_word_count); @@ -118,7 +150,7 @@ uint32_t ble_flash_block_write(uint32_t * p_address, uint32_t * p_in_array, uint uint32_t ble_flash_page_addr(uint8_t page_num, uint32_t ** pp_page_addr); /**@brief Function for calculating a 16 bit CRC using the CRC-16-CCITT scheme. - * + * * @param[in] p_data Pointer to data on which the CRC is to be calulated. * @param[in] size Number of bytes on which the CRC is to be calulated. * @param[in] p_crc Initial CRC value (if NULL, a preset value is used as the initial value). @@ -137,6 +169,11 @@ uint16_t ble_flash_crc16_compute(uint8_t * p_data, uint16_t size, uint16_t * p_c */ void ble_flash_on_radio_active_evt(bool radio_active); + +#ifdef __cplusplus +} +#endif + #endif // BLE_FLASH_H__ /** @} */ diff --git a/components/drivers_nrf/clock/nrf_drv_clock.c b/components/drivers_nrf/clock/nrf_drv_clock.c index b4ad35d..3a71109 100644 --- a/components/drivers_nrf/clock/nrf_drv_clock.c +++ b/components/drivers_nrf/clock/nrf_drv_clock.c @@ -1,458 +1,599 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(CLOCK) #include "nrf_drv_clock.h" #include "nrf_error.h" -#include "nordic_common.h" - +#include "app_util_platform.h" #ifdef SOFTDEVICE_PRESENT +#include "softdevice_handler.h" #include "nrf_sdm.h" #include "nrf_soc.h" -#else -#include "app_util_platform.h" -#endif // SOFTDEVICE_PRESENT +#endif + +#define NRF_LOG_MODULE_NAME "CLOCK" + +#if CLOCK_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL CLOCK_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR CLOCK_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR CLOCK_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_CLOCK_EVENT_HFCLKSTARTED ? "NRF_CLOCK_EVENT_HFCLKSTARTED" : \ + (event == NRF_CLOCK_EVENT_LFCLKSTARTED ? "NRF_CLOCK_EVENT_LFCLKSTARTED" : \ + (event == NRF_CLOCK_EVENT_DONE ? "NRF_CLOCK_EVENT_DONE" : \ + (event == NRF_CLOCK_EVENT_CTTO ? "NRF_CLOCK_EVENT_CTTO" : "UNKNOWN EVENT")))) +#else //CLOCK_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //CLOCK_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +/* Validate configuration */ +INTERRUPT_PRIORITY_VALIDATION(CLOCK_CONFIG_IRQ_PRIORITY); /*lint -save -e652 */ -#define NRF_CLOCK_LF_SRC_RC CLOCK_LFCLKSRC_SRC_RC -#define NRF_CLOCK_LF_SRC_Xtal CLOCK_LFCLKSRC_SRC_Xtal -#define NRF_CLOCK_LF_SRC_Synth CLOCK_LFCLKSRC_SRC_Synth +#define NRF_CLOCK_LFCLK_RC CLOCK_LFCLKSRC_SRC_RC +#define NRF_CLOCK_LFCLK_Xtal CLOCK_LFCLKSRC_SRC_Xtal +#define NRF_CLOCK_LFCLK_Synth CLOCK_LFCLKSRC_SRC_Synth /*lint -restore */ -#define INT_MAX 0xFFFFFFFF +#if (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LFCLK_RC) && !defined(SOFTDEVICE_PRESENT) +#define CALIBRATION_SUPPORT 1 +#else +#define CALIBRATION_SUPPORT 0 +#endif +typedef enum +{ + CAL_STATE_IDLE, + CAL_STATE_CT, + CAL_STATE_HFCLK_REQ, + CAL_STATE_CAL, + CAL_STATE_ABORT, +} nrf_drv_clock_cal_state_t; /**@brief CLOCK control block. */ typedef struct { - bool module_initialized; /*< Indicate the state of module */ - uint32_t hfclk_requests; /*< High frequency clock state. */ -#ifndef SOFTDEVICE_PRESENT - uint32_t lfclk_requests; /*< Low frequency clock state. */ -#if CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC - volatile bool calibration_in_progress; /*< Indicate the state of calibration */ -#endif //CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC -#endif //SOFTDEVICE_PRESENT -}nrf_drv_clock_cb_t; + bool module_initialized; /*< Indicate the state of module */ + volatile bool hfclk_on; /*< High-frequency clock state. */ + volatile bool lfclk_on; /*< Low-frequency clock state. */ + volatile uint32_t hfclk_requests; /*< High-frequency clock request counter. */ + volatile nrf_drv_clock_handler_item_t * p_hf_head; + volatile uint32_t lfclk_requests; /*< Low-frequency clock request counter. */ + volatile nrf_drv_clock_handler_item_t * p_lf_head; +#if CALIBRATION_SUPPORT + nrf_drv_clock_handler_item_t cal_hfclk_started_handler_item; + nrf_drv_clock_event_handler_t cal_done_handler; + volatile nrf_drv_clock_cal_state_t cal_state; +#endif // CALIBRATION_SUPPORT +} nrf_drv_clock_cb_t; static nrf_drv_clock_cb_t m_clock_cb; -#if (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC) && (!defined SOFTDEVICE_PRESENT) - -static const nrf_drv_clock_config_t m_default_config = NRF_DRV_CLOCK_DEAFULT_CONFIG; - -static uint32_t m_in_critical_region = 0; - -#define CLOCK_CRITICAL_REGION_ENTER() \ - do { \ - nrf_drv_common_irq_disable(POWER_CLOCK_IRQn); \ - __DSB(); \ - __ISB(); \ - m_in_critical_region++; \ - } while (0) -#define CLOCK_CRITICAL_REGION_EXIT() \ - do { \ - m_in_critical_region--; \ - if (m_in_critical_region == 0) \ - { \ - NVIC_EnableIRQ(POWER_CLOCK_IRQn); \ - } \ - } while (0) - -#else - -#define CLOCK_CRITICAL_REGION_ENTER() \ - do { \ - } while (0) - -#define CLOCK_CRITICAL_REGION_EXIT() \ - do { \ - } while (0) +/**@brief Function for starting LFCLK. This function will return immediately without waiting for start. + */ +static void lfclk_start(void) +{ + nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); + nrf_clock_int_enable(NRF_CLOCK_INT_LF_STARTED_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART); +} +/**@brief Function for stopping LFCLK and calibration (if it was set up). + */ +static void lfclk_stop(void) +{ +#if CALIBRATION_SUPPORT + (void)nrf_drv_clock_calibration_abort(); #endif +#ifdef SOFTDEVICE_PRESENT + // If LFCLK is requested to stop while SD is still enabled, + // it indicates an error in the application. + // Enabling SD should increment the LFCLK request. + ASSERT(!softdevice_handler_is_enabled()); +#endif // SOFTDEVICE_PRESENT + + nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTOP); + while (nrf_clock_lf_is_running()) + {} + m_clock_cb.lfclk_on = false; +} -#ifndef SOFTDEVICE_PRESENT -/**@brief Function for starting hfclk. This function will return immediately without waiting for start. - */ static void hfclk_start(void) { +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + (void)sd_clock_hfclk_request(); + return; + } +#endif // SOFTDEVICE_PRESENT + nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + nrf_clock_int_enable(NRF_CLOCK_INT_HF_STARTED_MASK); nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTART); } - -/**@brief Function for stopping hfclk. - */ static void hfclk_stop(void) { - nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); - while (nrf_clock_hf_src_get() == NRF_CLOCK_HF_SRC_HIGH_ACCURACY) +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) { - + (void)sd_clock_hfclk_release(); + return; } -} +#endif // SOFTDEVICE_PRESENT + nrf_clock_task_trigger(NRF_CLOCK_TASK_HFCLKSTOP); + while (nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY)) + {} + m_clock_cb.hfclk_on = false; +} -/**@brief Function for starting lfclk. This function will return immediately without waiting for start. - * It will also set up calibration if it is needed. - */ -static void lfclk_start(void) +bool nrf_drv_clock_init_check(void) { - nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); - nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART); - -#if CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC - nrf_clock_int_enable(NRF_CLOCK_INT_DONE_MASK - | NRF_CLOCK_INT_CTTO_MASK); - nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO); - nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTART); -#endif + return m_clock_cb.module_initialized; } - -/**@brief Function for stopping lfclk and calibration(if it was set up). - */ -static void lfclk_stop(void) +ret_code_t nrf_drv_clock_init(void) { -#if CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC - nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK - | NRF_CLOCK_INT_CTTO_MASK - | NRF_CLOCK_INT_HF_STARTED_MASK); - m_clock_cb.calibration_in_progress = false; - nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTOP); -#endif // CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC - - nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTOP); - while (nrf_clock_lf_is_running()) + ret_code_t err_code = NRF_SUCCESS; + if (m_clock_cb.module_initialized) + { + err_code = NRF_ERROR_MODULE_ALREADY_INITIALIZED; + } + else { + m_clock_cb.p_hf_head = NULL; + m_clock_cb.hfclk_requests = 0; + m_clock_cb.p_lf_head = NULL; + m_clock_cb.lfclk_requests = 0; + nrf_drv_common_power_clock_irq_init(); +#ifdef SOFTDEVICE_PRESENT + if (!softdevice_handler_is_enabled()) +#endif + { + nrf_clock_lf_src_set((nrf_clock_lfclk_t)CLOCK_CONFIG_LF_SRC); + } + +#if CALIBRATION_SUPPORT + m_clock_cb.cal_state = CAL_STATE_IDLE; +#endif + m_clock_cb.module_initialized = true; } -} + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} -/**@brief Function for controling lfclk. This function decides whether lfclk should be started or stopped. - */ -static void lfclk_control(void) +void nrf_drv_clock_uninit(void) { - CLOCK_CRITICAL_REGION_ENTER(); + ASSERT(m_clock_cb.module_initialized); + nrf_drv_common_clock_irq_disable(); + nrf_clock_int_disable(0xFFFFFFFF); + + lfclk_stop(); + hfclk_stop(); + m_clock_cb.module_initialized = false; + NRF_LOG_INFO("Uninitialized.\r\n"); +} - if (m_clock_cb.lfclk_requests > 0) +static void item_enqueue(nrf_drv_clock_handler_item_t ** p_head, + nrf_drv_clock_handler_item_t * p_item) +{ + nrf_drv_clock_handler_item_t * p_next = *p_head; + while(p_next) { - if ((nrf_clock_lf_is_running() == false) - && (nrf_clock_lf_start_task_status_get() == NRF_CLOCK_START_TASK_NOT_TRIGGERED)) + if(p_next == p_item) { - lfclk_start(); + return; } + p_next = p_next->p_next; } - else + + p_item->p_next = (*p_head ? *p_head : NULL); + *p_head = p_item; +} + +static nrf_drv_clock_handler_item_t * item_dequeue(nrf_drv_clock_handler_item_t ** p_head) +{ + nrf_drv_clock_handler_item_t * p_item = *p_head; + if (p_item) { - if (nrf_clock_lf_is_running() - || (nrf_clock_lf_start_task_status_get() == NRF_CLOCK_START_TASK_TRIGGERED)) - { - lfclk_stop(); - } + *p_head = p_item->p_next; } - CLOCK_CRITICAL_REGION_EXIT(); + return p_item; } - -/**@brief Function for controling hfclk. - * - * @param[in] interrupt_enable Determines if this function will enable interrupt - * during hflck start. - * - * @retval true hfclk was started - * @retval false hfclk was not started - */ -static bool hfclk_control(bool interrupt_enable) +void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item) { - bool result = false; - - CLOCK_CRITICAL_REGION_ENTER(); + ASSERT(m_clock_cb.module_initialized); - if ((m_clock_cb.hfclk_requests > 0) -#if CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_Synth - || (m_clock_cb.lfclk_requests > 0) -#elif CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC - || (m_clock_cb.calibration_in_progress == true) -#endif - ) + if (m_clock_cb.lfclk_on) { - if ((nrf_clock_hf_src_get() != NRF_CLOCK_HF_SRC_HIGH_ACCURACY) - && (nrf_clock_hf_start_task_status_get() == NRF_CLOCK_START_TASK_NOT_TRIGGERED)) + if (p_handler_item) { - result = true; - - if (interrupt_enable) - { - nrf_clock_int_enable(NRF_CLOCK_INT_HF_STARTED_MASK); - } - hfclk_start(); + p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_LFCLK_STARTED); } + CRITICAL_REGION_ENTER(); + ++(m_clock_cb.lfclk_requests); + CRITICAL_REGION_EXIT(); } else { - if ((nrf_clock_hf_src_get() == NRF_CLOCK_HF_SRC_HIGH_ACCURACY) - || (nrf_clock_hf_start_task_status_get() == NRF_CLOCK_START_TASK_TRIGGERED)) + CRITICAL_REGION_ENTER(); + if (p_handler_item) + { + item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head, + p_handler_item); + } + if (m_clock_cb.lfclk_requests == 0) { - hfclk_stop(); + lfclk_start(); } + ++(m_clock_cb.lfclk_requests); + CRITICAL_REGION_EXIT(); } - CLOCK_CRITICAL_REGION_EXIT(); - return result; + ASSERT(m_clock_cb.lfclk_requests > 0); } -#endif // SOFTDEVICE_PRESENT - -ret_code_t nrf_drv_clock_init(nrf_drv_clock_config_t const * p_config) +void nrf_drv_clock_lfclk_release(void) { - uint32_t result = NRF_SUCCESS; + ASSERT(m_clock_cb.module_initialized); + ASSERT(m_clock_cb.lfclk_requests > 0); - if (m_clock_cb.module_initialized == false) + CRITICAL_REGION_ENTER(); + --(m_clock_cb.lfclk_requests); + if (m_clock_cb.lfclk_requests == 0) { - m_clock_cb.hfclk_requests = 0; -#ifndef SOFTDEVICE_PRESENT - m_clock_cb.lfclk_requests = 0; - - nrf_clock_xtalfreq_set(CLOCK_CONFIG_XTAL_FREQ); - nrf_clock_lf_src_set((nrf_clock_lf_src_t)CLOCK_CONFIG_LF_SRC); - -#if CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC + lfclk_stop(); + } + CRITICAL_REGION_EXIT(); +} - m_clock_cb.calibration_in_progress = false; +bool nrf_drv_clock_lfclk_is_running(void) +{ + ASSERT(m_clock_cb.module_initialized); - nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); - nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); - nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE); - nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO); +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + return true; + } +#endif // SOFTDEVICE_PRESENT - if (p_config == NULL) - { - p_config = &m_default_config; - } + return nrf_clock_lf_is_running(); +} - nrf_clock_cal_timer_timeout_set(p_config->cal_interval); - nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, p_config->interrupt_priority); +void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item) +{ + ASSERT(m_clock_cb.module_initialized); -#endif // CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC -#else // SOFTDEVICE_PRESENT - uint8_t is_enabled; - result = sd_softdevice_is_enabled(&is_enabled); - if((result == NRF_SUCCESS) && !is_enabled) + if (m_clock_cb.hfclk_on) + { + if (p_handler_item) { - result = NRF_ERROR_SOFTDEVICE_NOT_ENABLED; + p_handler_item->event_handler(NRF_DRV_CLOCK_EVT_HFCLK_STARTED); } -#endif // SOFTDEVICE_PRESENT + CRITICAL_REGION_ENTER(); + ++(m_clock_cb.hfclk_requests); + CRITICAL_REGION_EXIT(); } else { - result = MODULE_ALREADY_INITIALIZED; - } - - if (result == NRF_SUCCESS) - { - m_clock_cb.module_initialized = true; + CRITICAL_REGION_ENTER(); + if (p_handler_item) + { + item_enqueue((nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head, + p_handler_item); + } + if (m_clock_cb.hfclk_requests == 0) + { + hfclk_start(); + } + ++(m_clock_cb.hfclk_requests); + CRITICAL_REGION_EXIT(); } - return result; + ASSERT(m_clock_cb.hfclk_requests > 0); } - -void nrf_drv_clock_uninit(void) +void nrf_drv_clock_hfclk_release(void) { ASSERT(m_clock_cb.module_initialized); -#ifndef SOFTDEVICE_PRESENT - -#if CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC - nrf_drv_common_irq_disable(POWER_CLOCK_IRQn); -#endif // CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC - - lfclk_stop(); - hfclk_stop(); -#else - UNUSED_VARIABLE(sd_clock_hfclk_release()); -#endif // SOFTDEVICE_PRESENT + ASSERT(m_clock_cb.hfclk_requests > 0); - m_clock_cb.module_initialized = false; + CRITICAL_REGION_ENTER(); + --(m_clock_cb.hfclk_requests); + if (m_clock_cb.hfclk_requests == 0) + { + hfclk_stop(); + } + CRITICAL_REGION_EXIT(); } - -void nrf_drv_clock_lfclk_request(void) +bool nrf_drv_clock_hfclk_is_running(void) { ASSERT(m_clock_cb.module_initialized); -#ifndef SOFTDEVICE_PRESENT - ASSERT(m_clock_cb.lfclk_requests != INT_MAX); - m_clock_cb.lfclk_requests++; - UNUSED_VARIABLE(hfclk_control(false)); - lfclk_control(); -#endif // SOFTDEVICE_PRESENT -} - -void nrf_drv_clock_lfclk_release(void) -{ - ASSERT(m_clock_cb.module_initialized); -#ifndef SOFTDEVICE_PRESENT - ASSERT(m_clock_cb.lfclk_requests > 0); - m_clock_cb.lfclk_requests--; - UNUSED_VARIABLE(hfclk_control(false)); - lfclk_control(); +#ifdef SOFTDEVICE_PRESENT + if (softdevice_handler_is_enabled()) + { + uint32_t is_running; + UNUSED_VARIABLE(sd_clock_hfclk_is_running(&is_running)); + return (is_running ? true : false); + } #endif // SOFTDEVICE_PRESENT -} + return nrf_clock_hf_is_running(NRF_CLOCK_HFCLK_HIGH_ACCURACY); +} -bool nrf_drv_clock_lfclk_is_running(void) +#if CALIBRATION_SUPPORT +static void clock_calibration_hf_started(nrf_drv_clock_evt_type_t event) { - ASSERT(m_clock_cb.module_initialized); - bool result; -#ifndef SOFTDEVICE_PRESENT - result = nrf_clock_lf_is_running(); -#else - result = true; -#endif - return result; + if (m_clock_cb.cal_state == CAL_STATE_ABORT) + { + nrf_drv_clock_hfclk_release(); + m_clock_cb.cal_state = CAL_STATE_IDLE; + if (m_clock_cb.cal_done_handler) + { + m_clock_cb.cal_done_handler(NRF_DRV_CLOCK_EVT_CAL_ABORTED); + } + } + else + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE); + nrf_clock_int_enable(NRF_CLOCK_INT_DONE_MASK); + m_clock_cb.cal_state = CAL_STATE_CAL; + nrf_clock_task_trigger(NRF_CLOCK_TASK_CAL); + } } +#endif // CALIBRATION_SUPPORT - -void nrf_drv_clock_hfclk_request(void) +ret_code_t nrf_drv_clock_calibration_start(uint8_t interval, nrf_drv_clock_event_handler_t handler) { - ASSERT(m_clock_cb.module_initialized); - ASSERT(m_clock_cb.hfclk_requests != INT_MAX); - m_clock_cb.hfclk_requests++; -#ifndef SOFTDEVICE_PRESENT - UNUSED_VARIABLE(hfclk_control(false)); -#else - if(m_clock_cb.hfclk_requests == 1) + ret_code_t err_code = NRF_SUCCESS; +#if CALIBRATION_SUPPORT + ASSERT(m_clock_cb.cal_state == CAL_STATE_IDLE); + if (m_clock_cb.lfclk_on == false) { - UNUSED_VARIABLE(sd_clock_hfclk_request()); + err_code = NRF_ERROR_INVALID_STATE; } -#endif // SOFTDEVICE_PRESENT + else if (m_clock_cb.cal_state == CAL_STATE_IDLE) + { + m_clock_cb.cal_done_handler = handler; + m_clock_cb.cal_hfclk_started_handler_item.event_handler = clock_calibration_hf_started; + if (interval == 0) + { + m_clock_cb.cal_state = CAL_STATE_HFCLK_REQ; + nrf_drv_clock_hfclk_request(&m_clock_cb.cal_hfclk_started_handler_item); + } + else + { + m_clock_cb.cal_state = CAL_STATE_CT; + nrf_clock_cal_timer_timeout_set(interval); + nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO); + nrf_clock_int_enable(NRF_CLOCK_INT_CTTO_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTART); + } + } + else + { + err_code = NRF_ERROR_BUSY; + } + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +#else + err_code = NRF_ERROR_FORBIDDEN; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +#endif // CALIBRATION_SUPPORT } - -void nrf_drv_clock_hfclk_release(void) +ret_code_t nrf_drv_clock_calibration_abort(void) { - ASSERT(m_clock_cb.module_initialized); - ASSERT(m_clock_cb.hfclk_requests > 0); - m_clock_cb.hfclk_requests--; -#ifndef SOFTDEVICE_PRESENT - UNUSED_VARIABLE(hfclk_control(false)); -#else - if(m_clock_cb.hfclk_requests == 0) + ret_code_t err_code = NRF_SUCCESS; +#if CALIBRATION_SUPPORT + CRITICAL_REGION_ENTER(); + switch (m_clock_cb.cal_state) { - UNUSED_VARIABLE(sd_clock_hfclk_release()); + case CAL_STATE_CT: + nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK); + nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTOP); + m_clock_cb.cal_state = CAL_STATE_IDLE; + if (m_clock_cb.cal_done_handler) + { + m_clock_cb.cal_done_handler(NRF_DRV_CLOCK_EVT_CAL_ABORTED); + } + break; + case CAL_STATE_HFCLK_REQ: + /* fall through. */ + case CAL_STATE_CAL: + m_clock_cb.cal_state = CAL_STATE_ABORT; + break; + default: + break; } -#endif // SOFTDEVICE_PRESENT + CRITICAL_REGION_EXIT(); + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +#else + err_code = NRF_ERROR_FORBIDDEN; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +#endif // CALIBRATION_SUPPORT } - -bool nrf_drv_clock_hfclk_is_running(void) +ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating) { - bool result; + ret_code_t err_code = NRF_SUCCESS; +#if CALIBRATION_SUPPORT ASSERT(m_clock_cb.module_initialized); -#ifndef SOFTDEVICE_PRESENT - result = nrf_clock_hf_is_running(); + *p_is_calibrating = (m_clock_cb.cal_state != CAL_STATE_IDLE); + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; #else - uint32_t is_running; - UNUSED_VARIABLE(sd_clock_hfclk_is_running(&is_running)); - result = is_running ? true : false; -#endif - return result; + err_code = NRF_ERROR_FORBIDDEN; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +#endif // CALIBRATION_SUPPORT } - -ret_code_t nrf_drv_clock_calibration_force(void) +__STATIC_INLINE void clock_clk_started_notify(nrf_drv_clock_evt_type_t evt_type) { -#if ((!defined SOFTDEVICE_PRESENT) && (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC)) - uint32_t result; - ASSERT(m_clock_cb.module_initialized); - if (m_clock_cb.lfclk_requests > 0) + nrf_drv_clock_handler_item_t **p_head; + if (evt_type == NRF_DRV_CLOCK_EVT_HFCLK_STARTED) { - result = NRF_SUCCESS; - CLOCK_CRITICAL_REGION_ENTER(); - nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTOP); - - if (m_clock_cb.calibration_in_progress == false) - { - m_clock_cb.calibration_in_progress = true; - - if (hfclk_control(true) == false) - { - nrf_clock_task_trigger(NRF_CLOCK_TASK_CAL); - } - } - CLOCK_CRITICAL_REGION_EXIT(); + p_head = (nrf_drv_clock_handler_item_t **)&m_clock_cb.p_hf_head; } else { - result = NRF_ERROR_INVALID_STATE; + p_head = (nrf_drv_clock_handler_item_t **)&m_clock_cb.p_lf_head; } - return result; -#else // ((!defined SOFTDEVICE_PRESENT) && (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC)) - return NRF_ERROR_FORBIDDEN; -#endif -} + while (1) + { + nrf_drv_clock_handler_item_t * p_item = item_dequeue(p_head); + if (!p_item) + { + break; + } -ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating) -{ -#if ((!defined SOFTDEVICE_PRESENT) && (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC)) - ASSERT(m_clock_cb.module_initialized); - *p_is_calibrating = m_clock_cb.calibration_in_progress; - return NRF_SUCCESS; -#else // ((!defined SOFTDEVICE_PRESENT) && (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC)) - return NRF_ERROR_FORBIDDEN; -#endif + p_item->event_handler(evt_type); + } } - -#if ((!defined SOFTDEVICE_PRESENT) && (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC)) +#if NRF_DRV_COMMON_POWER_CLOCK_ISR +void nrf_drv_clock_onIRQ(void) +#else void POWER_CLOCK_IRQHandler(void) +#endif { - if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED) && - nrf_clock_int_enable_check(NRF_CLOCK_INT_HF_STARTED_MASK)) + if (nrf_clock_event_check(NRF_CLOCK_EVENT_HFCLKSTARTED)) { nrf_clock_event_clear(NRF_CLOCK_EVENT_HFCLKSTARTED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_HFCLKSTARTED)); nrf_clock_int_disable(NRF_CLOCK_INT_HF_STARTED_MASK); - - if (m_clock_cb.calibration_in_progress == true) - { - nrf_clock_task_trigger(NRF_CLOCK_TASK_CAL); - } + m_clock_cb.hfclk_on = true; + clock_clk_started_notify(NRF_DRV_CLOCK_EVT_HFCLK_STARTED); + } + if (nrf_clock_event_check(NRF_CLOCK_EVENT_LFCLKSTARTED)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_LFCLKSTARTED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_LFCLKSTARTED)); + nrf_clock_int_disable(NRF_CLOCK_INT_LF_STARTED_MASK); + m_clock_cb.lfclk_on = true; + clock_clk_started_notify(NRF_DRV_CLOCK_EVT_LFCLK_STARTED); } - if (nrf_clock_event_check(NRF_CLOCK_EVENT_CTTO) && - nrf_clock_int_enable_check(NRF_CLOCK_INT_CTTO_MASK)) +#if CALIBRATION_SUPPORT + if (nrf_clock_event_check(NRF_CLOCK_EVENT_CTTO)) { nrf_clock_event_clear(NRF_CLOCK_EVENT_CTTO); - m_clock_cb.calibration_in_progress = true; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_CTTO)); + nrf_clock_int_disable(NRF_CLOCK_INT_CTTO_MASK); + nrf_drv_clock_hfclk_request(&m_clock_cb.cal_hfclk_started_handler_item); + } - if(hfclk_control(true) == false) + if (nrf_clock_event_check(NRF_CLOCK_EVENT_DONE)) + { + nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_CLOCK_EVENT_DONE)); + nrf_clock_int_disable(NRF_CLOCK_INT_DONE_MASK); + nrf_drv_clock_hfclk_release(); + bool aborted = (m_clock_cb.cal_state == CAL_STATE_ABORT); + m_clock_cb.cal_state = CAL_STATE_IDLE; + if (m_clock_cb.cal_done_handler) { - nrf_clock_task_trigger(NRF_CLOCK_TASK_CAL); + m_clock_cb.cal_done_handler(aborted ? + NRF_DRV_CLOCK_EVT_CAL_ABORTED : NRF_DRV_CLOCK_EVT_CAL_DONE); } } +#endif // CALIBRATION_SUPPORT +} + +#ifdef SOFTDEVICE_PRESENT - if (nrf_clock_event_check(NRF_CLOCK_EVENT_DONE) && - nrf_clock_int_enable_check(NRF_CLOCK_INT_DONE_MASK)) +void nrf_drv_clock_on_soc_event(uint32_t evt_id) +{ + if (evt_id == NRF_EVT_HFCLKSTARTED) { - nrf_clock_event_clear(NRF_CLOCK_EVENT_DONE); - m_clock_cb.calibration_in_progress = false; - UNUSED_VARIABLE(hfclk_control(true)); - nrf_clock_task_trigger(NRF_CLOCK_TASK_CTSTART); + clock_clk_started_notify(NRF_DRV_CLOCK_EVT_HFCLK_STARTED); + } +} + +void nrf_drv_clock_on_sd_enable(void) +{ + CRITICAL_REGION_ENTER(); + /* Make sure that nrf_drv_clock module is initialized */ + if (!m_clock_cb.module_initialized) + { + (void)nrf_drv_clock_init(); } + /* SD is one of the LFCLK requesters, but it will enable it by itself. */ + ++(m_clock_cb.lfclk_requests); + m_clock_cb.lfclk_on = true; + CRITICAL_REGION_EXIT(); } -#endif // ((!defined SOFTDEVICE_PRESENT) && (CLOCK_CONFIG_LF_SRC == NRF_CLOCK_LF_SRC_RC)) -#undef NRF_CLOCK_LF_SRC_RC -#undef NRF_CLOCK_LF_SRC_Xtal -#undef NRF_CLOCK_LF_SRC_Synth +void nrf_drv_clock_on_sd_disable(void) +{ + /* Reinit interrupts */ + ASSERT(m_clock_cb.module_initialized); + nrf_drv_common_irq_enable(POWER_CLOCK_IRQn, CLOCK_CONFIG_IRQ_PRIORITY); + + /* SD leaves LFCLK enabled - disable it if it is no longer required. */ + nrf_drv_clock_lfclk_release(); +} + +#endif // SOFTDEVICE_PRESENT + +#undef NRF_CLOCK_LFCLK_RC +#undef NRF_CLOCK_LFCLK_Xtal +#undef NRF_CLOCK_LFCLK_Synth + +#endif // NRF_MODULE_ENABLED(CLOCK) diff --git a/components/drivers_nrf/clock/nrf_drv_clock.h b/components/drivers_nrf/clock/nrf_drv_clock.h index 1fdc606..263500d 100644 --- a/components/drivers_nrf/clock/nrf_drv_clock.h +++ b/components/drivers_nrf/clock/nrf_drv_clock.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_CLOCK_H__ @@ -18,139 +46,203 @@ #include "sdk_errors.h" #include "nrf_assert.h" #include "nrf_clock.h" -#include "nrf_drv_config.h" +#include "sdk_config.h" #include "nrf_drv_common.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * * @addtogroup nrf_clock Clock HAL and driver * @ingroup nrf_drivers * @brief Clock APIs. - * @details The clock HAL provides basic APIs for accessing the registers of the clock. + * @details The clock HAL provides basic APIs for accessing the registers of the clock. * The clock driver provides APIs on a higher level. * - * @defgroup nrf_clock_drv Clock driver + * @defgroup nrf_drv_clock Clock driver * @{ * @ingroup nrf_clock * @brief Driver for managing the low-frequency clock (LFCLK) and the high-frequency clock (HFCLK). */ /** - * @brief Calibration interval configuration for the low-frequency RC oscillator. - * - * @details Calibration can be affected by radio transmission. To avoid this problem, - * call @ref nrf_drv_clock_calibration_force() and wait for end of calibration. + * @brief Clock events. */ typedef enum { - RC_250MS_CALIBRATION_INTERVAL = 1, /*< Calibration every 250 ms. */ - RC_500MS_CALIBRATION_INTERVAL = 2, /*< Calibration every 500 ms. */ - RC_1000MS_CALIBRATION_INTERVAL = 4, /*< Calibration every 1000 ms. */ - RC_2000MS_CALIBRATION_INTERVAL = 8, /*< Calibration every 2000 ms. */ - RC_4000MS_CALIBRATION_INTERVAL = 16, /*< Calibration every 4000 ms. */ - RC_8000MS_CALIBRATION_INTERVAL = 32, /*< Calibration every 8000 ms. */ - RC_16000MS_CALIBRATION_INTERVAL = 64 /*< Calibration every 16000 ms. */ -} nrf_drv_clock_lf_cal_interval_t; - -/**@brief Struct for Clock initialization. Thise parameters are used when SoftDevice is not present - * and low-frequency RC oscillator is selected. - */ -typedef struct + NRF_DRV_CLOCK_EVT_HFCLK_STARTED, ///< HFCLK has been started. + NRF_DRV_CLOCK_EVT_LFCLK_STARTED, ///< LFCLK has been started. + NRF_DRV_CLOCK_EVT_CAL_DONE, ///< Calibration is done. + NRF_DRV_CLOCK_EVT_CAL_ABORTED, ///< Calibration has been aborted. +} nrf_drv_clock_evt_type_t; + +/** + * @brief Clock event handler. + * + * @param[in] event Event. + */ +typedef void (*nrf_drv_clock_event_handler_t)(nrf_drv_clock_evt_type_t event); + +// Forward declaration of the nrf_drv_clock_handler_item_t type. +typedef struct nrf_drv_clock_handler_item_s nrf_drv_clock_handler_item_t; + +struct nrf_drv_clock_handler_item_s { - nrf_drv_clock_lf_cal_interval_t cal_interval; /**< Calibration interval. */ - uint8_t interrupt_priority; /**< Clock interrupt priority. */ -} nrf_drv_clock_config_t; + nrf_drv_clock_handler_item_t * p_next; ///< A pointer to the next handler that should be called when the clock is started. + nrf_drv_clock_event_handler_t event_handler; ///< Function to be called when the clock is started. +}; -/**@brief Clock default configuration.*/ -#define NRF_DRV_CLOCK_DEAFULT_CONFIG \ - { \ - .cal_interval = CLOCK_CONFIG_LF_RC_CAL_INTERVAL, \ - .interrupt_priority = CLOCK_CONFIG_IRQ_PRIORITY, \ - } +/** + * @brief Function for checking if driver is already initialized + * + * This function is used to check whatever common POWER_CLOCK common interrupt + * should be disabled or not if @ref nrf_drv_power tries to disable the interrupt. + * + * @retval true Driver is initialized + * @retval false Driver is uninitialized + */ +bool nrf_drv_clock_init_check(void); /** - * @brief Function for initialization the nrf_drv_clock module. + * @brief Function for initializing the nrf_drv_clock module. * * After initialization, the module is in power off state (clocks are not requested). * - * @param[in] p_config Initial configuration. Default configuration used if NULL. - * - * @retval NRF_SUCCESS If the procedure was successful. - * @retval MODULE_ALREADY_INITIALIZED If the driver was already initialized. - * @retval NRF_ERROR_SOFTDEVICE_NOT_ENABLED If the SoftDevice was not enabled. + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED If the driver was already initialized. */ -ret_code_t nrf_drv_clock_init(nrf_drv_clock_config_t const * p_config); +ret_code_t nrf_drv_clock_init(void); /** - * @brief Function for uninitialization the nrf_drv_clock module. + * @brief Function for uninitializing the clock module. * - * After uninitialization, the module is in idle state. */ void nrf_drv_clock_uninit(void); /** - * @brief Function for requesting LFCLK. LFCLK can be repeatedly requested. + * @brief Function for requesting the LFCLK. + * + * The low-frequency clock can be requested by different modules + * or contexts. The driver ensures that the clock will be started only when it is requested + * the first time. If the clock is not ready but it was already started, the handler item that is + * provided as an input parameter is added to the list of handlers that will be notified + * when the clock is started. If the clock is already enabled, user callback is called from the + * current context. + * + * The first request will start the selected LFCLK source. If an event handler is + * provided, it will be called once the LFCLK is started. If the LFCLK was already started at this + * time, the event handler will be called from the context of this function. Additionally, + * the @ref nrf_drv_clock_lfclk_is_running function can be polled to check if the clock has started. * - * @note When Softdevice is enabled, LFCLK is always running. + * @note When a SoftDevice is enabled, the LFCLK is always running and the driver cannot control it. * - * @details If it is first request, selected LFCLK source will be started. - * The @ref nrf_drv_clock_lfclk_is_running() function can be polled to check if it has started. + * @note The handler item provided by the user cannot be an automatic variable. + * + * @param[in] p_handler_item A pointer to the event handler structure. */ -void nrf_drv_clock_lfclk_request(void); +void nrf_drv_clock_lfclk_request(nrf_drv_clock_handler_item_t * p_handler_item); /** - * @brief Function for releasing LFCLK. If there is no more requests, LFCLK source will be stopped. + * @brief Function for releasing the LFCLK. + * + * If there are no more requests, the LFCLK source will be stopped. * - * @note When Softdevice is enabled, LFCLK is always running. + * @note When a SoftDevice is enabled, the LFCLK is always running. */ void nrf_drv_clock_lfclk_release(void); /** - * @brief Function for checking LFCLK state. + * @brief Function for checking the LFCLK state. * - * @retval true if the LFCLK is running, false if not. + * @retval true If the LFCLK is running. + * @retval false If the LFCLK is not running. */ bool nrf_drv_clock_lfclk_is_running(void); /** - * @brief Function for requesting high-accuracy (for \nRFXX it is XTAL) source HFCLK. High-accuracy source - * can be repeatedly requested. + * @brief Function for requesting the high-accuracy source HFCLK. * - * @details The @ref nrf_drv_clock_hfclk_is_running() function can be polled to check if it has started. + * The high-accuracy source + * can be requested by different modules or contexts. The driver ensures that the high-accuracy + * clock will be started only when it is requested the first time. If the clock is not ready + * but it was already started, the handler item that is provided as an input parameter is added + * to the list of handlers that will be notified when the clock is started. + * + * If an event handler is provided, it will be called once the clock is started. If the clock was already + * started at this time, the event handler will be called from the context of this function. Additionally, + * the @ref nrf_drv_clock_hfclk_is_running function can be polled to check if the clock has started. + * + * @note If a SoftDevice is running, the clock is managed by the SoftDevice and all requests are handled by + * the SoftDevice. This function cannot be called from all interrupt priority levels in that case. + * @note The handler item provided by the user cannot be an automatic variable. + * + * @param[in] p_handler_item A pointer to the event handler structure. */ -void nrf_drv_clock_hfclk_request(void); +void nrf_drv_clock_hfclk_request(nrf_drv_clock_handler_item_t * p_handler_item); /** - * @brief Function for releasing high-accuracy source HFCLK. If there is no more requests, high-accuracy - * source will be released. + * @brief Function for releasing the high-accuracy source HFCLK. + * + * If there are no more requests, the high-accuracy source will be released. */ void nrf_drv_clock_hfclk_release(void); /** - * @brief Function for checking HFCLK state. + * @brief Function for checking the HFCLK state. * - * @retval true if the HFCLK is running (for \nRFXX XTAL source), false if not. + * @retval true If the HFCLK is running (for \nRFXX XTAL source). + * @retval false If the HFCLK is not running. */ bool nrf_drv_clock_hfclk_is_running(void); /** - * @brief Function for forcing calibration. + * @brief Function for starting a single calibration process. + * + * This function can also delay the start of calibration by a user-specified value. The delay will use + * a low-power timer that is part of the CLOCK module. @ref nrf_drv_clock_is_calibrating can be called to + * check if calibration is still in progress. If a handler is provided, the user can be notified when + * calibration is completed. The ext calibration can be started from the handler context. + * + * The calibration process consists of three phases: + * - Delay (optional) + * - Requesting the high-accuracy HFCLK + * - Hardware-supported calibration + * + * @param[in] delay Time after which the calibration will be started (in 0.25 s units). + * @param[in] handler NULL or user function to be called when calibration is completed or aborted. + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator. + * @retval NRF_ERROR_INVALID_STATE If the low-frequency clock is off. + * @retval NRF_ERROR_BUSY If calibration is in progress. + */ +ret_code_t nrf_drv_clock_calibration_start(uint8_t delay, nrf_drv_clock_event_handler_t handler); + +/** + * @brief Function for aborting calibration. * - * @details This function resets the calibration interval timer. The @ref nrf_drv_clock_is_calibrating() - * function can be polled to check if calibration is still in progress. + * This function aborts on-going calibration. If calibration was started, it cannot be stopped. If a handler + * was provided by @ref nrf_drv_clock_calibration_start, this handler will be called once + * aborted calibration is completed. @ref nrf_drv_clock_is_calibrating can also be used to check + * if the system is calibrating. * * @retval NRF_SUCCESS If the procedure was successful. - * @retval NRF_ERROR_FORBIDDEN If Softdevice is present or selected LFCLK source is not RC oscillator. + * @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator. */ -ret_code_t nrf_drv_clock_calibration_force(void); +ret_code_t nrf_drv_clock_calibration_abort(void); /** - * @brief Function for checking if calibration is in progress. + * @brief Function for checking if calibration is in progress. * - * @param[out] p_is_calibrating true if calibration is in progress, false if not. + * This function indicates that the system is + * in calibration if it is in any of the calibration process phases (see @ref nrf_drv_clock_calibration_start). + * + * @param[out] p_is_calibrating True if calibration is in progress, false if not. * * @retval NRF_SUCCESS If the procedure was successful. - * @retval NRF_ERROR_FORBIDDEN If Softdevice is present or selected LFCLK source is not RC oscillator. + * @retval NRF_ERROR_FORBIDDEN If a SoftDevice is present or the selected LFCLK source is not an RC oscillator. */ ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating); @@ -158,26 +250,66 @@ ret_code_t nrf_drv_clock_is_calibrating(bool * p_is_calibrating); * * @param[in] task One of the peripheral tasks. * - * @retval Task address. + * @return Task address. */ -__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task) -{ - return nrf_clock_task_address_get(task); -} +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task); /**@brief Function for returning a requested event address for the clock driver module. * * @param[in] event One of the peripheral events. * - * @retval Event address. + * @return Event address. + */ +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event); + + +#ifdef SOFTDEVICE_PRESENT +/** + * @brief Function called by the SoftDevice handler if an @ref nrf_soc event is received from the SoftDevice. + * + * @param[in] evt_id One of NRF_SOC_EVTS values. + */ +void nrf_drv_clock_on_soc_event(uint32_t evt_id); + +/** + * @brief Function called by the SoftDevice handler when the SoftDevice has been enabled. + * + * This function is called just after the SoftDevice has been properly enabled. + * Its main purpose is to mark that LFCLK has been requested by SD. + */ +void nrf_drv_clock_on_sd_enable(void); + +/** + * @brief Function called by the SoftDevice handler when the SoftDevice has been disabled. + * + * This function is called just after the SoftDevice has been properly disabled. + * It has two purposes: + * 1. Releases the LFCLK from the SD. + * 2. Reinitializes an interrupt after the SD releases POWER_CLOCK_IRQ. */ +void nrf_drv_clock_on_sd_disable(void); + +#endif +/** + *@} + **/ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION +__STATIC_INLINE uint32_t nrf_drv_clock_ppi_task_addr(nrf_clock_task_t task) +{ + return nrf_clock_task_address_get(task); +} + __STATIC_INLINE uint32_t nrf_drv_clock_ppi_event_addr(nrf_clock_event_t event) { return nrf_clock_event_address_get(event); } -/** - *@} - **/ +#endif //SUPPRESS_INLINE_IMPLEMENTATION /*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif // NRF_CLOCK_H__ diff --git a/components/drivers_nrf/common/nrf_drv_common.c b/components/drivers_nrf/common/nrf_drv_common.c index 96bf542..1474d6a 100644 --- a/components/drivers_nrf/common/nrf_drv_common.c +++ b/components/drivers_nrf/common/nrf_drv_common.c @@ -1,31 +1,297 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include #include "nrf_drv_common.h" #include "nrf_assert.h" -#include "nrf_error.h" +#include "app_util_platform.h" +#include "nrf_peripherals.h" +#if NRF_DRV_COMMON_POWER_CLOCK_ISR +#include "nrf_drv_power.h" +#include "nrf_drv_clock.h" +#endif #ifdef SOFTDEVICE_PRESENT #include "nrf_soc.h" #endif -void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority) +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +#define NRF_LOG_MODULE_NAME "COMMON" + +#if COMMON_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL COMMON_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR COMMON_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR COMMON_CONFIG_DEBUG_COLOR +#else //COMMON_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //COMMON_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +typedef struct { + nrf_drv_irq_handler_t handler; + bool acquired; +} shared_resource_t; + +// SPIM0, SPIS0, SPI0, TWIM0, TWIS0, TWI0 +#if (NRF_MODULE_ENABLED(SPI0) || NRF_MODULE_ENABLED(SPIS0) || NRF_MODULE_ENABLED(TWI0) || NRF_MODULE_ENABLED(TWIS0)) + #define SERIAL_BOX_0_IN_USE + // [this checking may need a different form in unit tests, hence macro] + #ifndef IS_SERIAL_BOX_0 + #define IS_SERIAL_BOX_0(p_per_base) (p_per_base == NRF_SPI0) + #endif + + static shared_resource_t m_serial_box_0 = { .acquired = false }; + void SPI0_TWI0_IRQHandler(void) + { + ASSERT(m_serial_box_0.handler); + m_serial_box_0.handler(); + } +#endif // (NRF_MODULE_ENABLED(SPI0) || NRF_MODULE_ENABLED(SPIS0) || NRF_MODULE_ENABLED(TWI0) || NRF_MODULE_ENABLED(TWIS0)) + +// SPIM1, SPIS1, SPI1, TWIM1, TWIS1, TWI1 +#if (NRF_MODULE_ENABLED(SPI1) || NRF_MODULE_ENABLED(SPIS1) || NRF_MODULE_ENABLED(TWI1) || NRF_MODULE_ENABLED(TWIS1)) + #define SERIAL_BOX_1_IN_USE + // [this checking may need a different form in unit tests, hence macro] + #ifndef IS_SERIAL_BOX_1 + #define IS_SERIAL_BOX_1(p_per_base) (p_per_base == NRF_SPI1) + #endif + + static shared_resource_t m_serial_box_1 = { .acquired = false }; +#ifdef TWIM_PRESENT + void SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler(void) +#else + void SPI1_TWI1_IRQHandler(void) +#endif + { + ASSERT(m_serial_box_1.handler); + m_serial_box_1.handler(); + } +#endif // (NRF_MODULE_ENABLED(SPI1) || NRF_MODULE_ENABLED(SPIS1) || NRF_MODULE_ENABLED(TWI1) || NRF_MODULE_ENABLED(TWIS1)) + +// SPIM2, SPIS2, SPI2 +#if (NRF_MODULE_ENABLED(SPI2) || NRF_MODULE_ENABLED(SPIS2)) + #define SERIAL_BOX_2_IN_USE + // [this checking may need a different form in unit tests, hence macro] + #ifndef IS_SERIAL_BOX_2 + #define IS_SERIAL_BOX_2(p_per_base) (p_per_base == NRF_SPI2) + #endif + + static shared_resource_t m_serial_box_2 = { .acquired = false }; + void SPIM2_SPIS2_SPI2_IRQHandler(void) + { + ASSERT(m_serial_box_2.handler); + m_serial_box_2.handler(); + } +#endif // (NRF_MODULE_ENABLED(SPI2) || NRF_MODULE_ENABLED(SPIS2)) + +// COMP, LPCOMP +#if (NRF_MODULE_ENABLED(COMP) || NRF_MODULE_ENABLED(LPCOMP)) + #define COMP_LPCOMP_IN_USE + + #ifndef IS_COMP_LPCOMP + #define IS_COMP_LPCOMP(p_per_base) ((p_per_base) == NRF_LPCOMP) + #endif + + static shared_resource_t m_comp_lpcomp = { .acquired = false }; + void LPCOMP_IRQHandler(void) + { + ASSERT(m_comp_lpcomp.handler); + m_comp_lpcomp.handler(); + } +#endif // (NRF_MODULE_ENABLED(COMP) || NRF_MODULE_ENABLED(LPCOMP)) + +#if defined(SERIAL_BOX_0_IN_USE) || \ + defined(SERIAL_BOX_1_IN_USE) || \ + defined(SERIAL_BOX_2_IN_USE) || \ + defined(COMP_LPCOMP_IN_USE) +static ret_code_t acquire_shared_resource(shared_resource_t * p_resource, + nrf_drv_irq_handler_t handler) { + ret_code_t err_code; + + bool busy = false; -#ifdef SOFTDEVICE_PRESENT - ASSERT((priority == NRF_APP_PRIORITY_LOW) || (priority == NRF_APP_PRIORITY_HIGH)); + CRITICAL_REGION_ENTER(); + if (p_resource->acquired) + { + busy = true; + } + else + { + p_resource->acquired = true; + } + CRITICAL_REGION_EXIT(); + + if (busy) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + p_resource->handler = handler; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} +#endif + +ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base, + nrf_drv_irq_handler_t handler) +{ +#ifdef SERIAL_BOX_0_IN_USE + if (IS_SERIAL_BOX_0(p_per_base)) + { + return acquire_shared_resource(&m_serial_box_0, handler); + } +#endif + +#ifdef SERIAL_BOX_1_IN_USE + if (IS_SERIAL_BOX_1(p_per_base)) + { + return acquire_shared_resource(&m_serial_box_1, handler); + } +#endif + +#ifdef SERIAL_BOX_2_IN_USE + if (IS_SERIAL_BOX_2(p_per_base)) + { + return acquire_shared_resource(&m_serial_box_2, handler); + } +#endif + +#ifdef COMP_LPCOMP_IN_USE + if (IS_COMP_LPCOMP(p_per_base)) + { + return acquire_shared_resource(&m_comp_lpcomp, handler); + } +#endif + ret_code_t err_code; + + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + +void nrf_drv_common_per_res_release(void const * p_per_base) +{ +#ifdef SERIAL_BOX_0_IN_USE + if (IS_SERIAL_BOX_0(p_per_base)) + { + m_serial_box_0.acquired = false; + } + else +#endif + +#ifdef SERIAL_BOX_1_IN_USE + if (IS_SERIAL_BOX_1(p_per_base)) + { + m_serial_box_1.acquired = false; + } + else +#endif + +#ifdef SERIAL_BOX_2_IN_USE + if (IS_SERIAL_BOX_2(p_per_base)) + { + m_serial_box_2.acquired = false; + } + else +#endif + +#ifdef COMP_LPCOMP_IN_USE + if (IS_COMP_LPCOMP(p_per_base)) + { + m_comp_lpcomp.acquired = false; + } + else +#endif + + {} +} + +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +#if NRF_MODULE_ENABLED(POWER) +void nrf_drv_common_power_irq_disable(void) +{ +#if NRF_DRV_COMMON_POWER_CLOCK_ISR + if(!nrf_drv_clock_init_check()) #endif + { + nrf_drv_common_irq_disable(POWER_CLOCK_IRQn); + } +} +#endif + +#if NRF_MODULE_ENABLED(CLOCK) +void nrf_drv_common_clock_irq_disable(void) +{ +#if NRF_DRV_COMMON_POWER_CLOCK_ISR + if(!nrf_drv_power_init_check()) +#endif + { + nrf_drv_common_irq_disable(POWER_CLOCK_IRQn); + } +} +#endif + +#if NRF_DRV_COMMON_POWER_CLOCK_ISR +void POWER_CLOCK_IRQHandler(void) +{ + extern void nrf_drv_clock_onIRQ(void); + extern void nrf_drv_power_onIRQ(void); + + nrf_drv_clock_onIRQ(); + nrf_drv_power_onIRQ(); +} +#endif // NRF_DRV_COMMON_POWER_CLOCK_ISR + + +void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority) +{ + INTERRUPT_PRIORITY_ASSERT(priority); - NVIC_SetPriority(IRQn, priority); - NVIC_ClearPendingIRQ(IRQn); - NVIC_EnableIRQ(IRQn); + NVIC_SetPriority(IRQn, priority); + NVIC_ClearPendingIRQ(IRQn); + NVIC_EnableIRQ(IRQn); } diff --git a/components/drivers_nrf/common/nrf_drv_common.h b/components/drivers_nrf/common/nrf_drv_common.h index 44e6dbb..6738267 100644 --- a/components/drivers_nrf/common/nrf_drv_common.h +++ b/components/drivers_nrf/common/nrf_drv_common.h @@ -1,42 +1,112 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_COMMON_H__ #define NRF_DRV_COMMON_H__ -#include "nrf.h" #include #include +#include "nrf.h" +#include "sdk_errors.h" +#include "sdk_common.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NRF51 +#ifdef SOFTDEVICE_PRESENT +#define INTERRUPT_PRIORITY_IS_VALID(pri) (((pri) == 1) || ((pri) == 3)) +#else +#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 4) +#endif //SOFTDEVICE_PRESENT +#else +#ifdef SOFTDEVICE_PRESENT +#define INTERRUPT_PRIORITY_IS_VALID(pri) ((((pri) > 1) && ((pri) < 4)) || (((pri) > 5) && ((pri) < 8))) +#else +#define INTERRUPT_PRIORITY_IS_VALID(pri) ((pri) < 8) +#endif //SOFTDEVICE_PRESENT +#endif //NRF52 + +#define INTERRUPT_PRIORITY_VALIDATION(pri) STATIC_ASSERT(INTERRUPT_PRIORITY_IS_VALID((pri))) +#define INTERRUPT_PRIORITY_ASSERT(pri) ASSERT(INTERRUPT_PRIORITY_IS_VALID((pri))) /** - * @brief Offset of event registers in every peripheral instance + * @defgroup nrf_drv_common Peripheral drivers common module + * @{ + * @ingroup nrf_drivers + */ + +/** + * @brief Offset of event registers in every peripheral instance. * - * This is the offset where event registers start in the every peripheral. + * This is the offset where event registers start in every peripheral. */ #define NRF_DRV_COMMON_EVREGS_OFFSET 0x100U /** - * @enum nrf_drv_state_t + * @brief The flag that is set when POWER_CLOCK ISR is implemented in common module + * + * This flag means that the function POWER_CLOCK_IRQHandler is implemented in + * nrf_drv_common.c file. In the @c clock and @c power modules functions + * nrf_drv_clock_onIRQ nrf_drv_power_onIRQ should be implemented + * and they would be called from common implementation. + * + * None of the checking is done here. + * The implementation functions in @c clock and @c power are required to handle + * correctly the case when they are called without any event bit set. + */ +#define NRF_DRV_COMMON_POWER_CLOCK_ISR (NRF_MODULE_ENABLED(CLOCK) && NRF_MODULE_ENABLED(POWER)) + +/** * @brief Driver state. */ -typedef enum -{ - NRF_DRV_STATE_UNINITIALIZED, /**< Uninitialized. */ - NRF_DRV_STATE_INITIALIZED, /**< Initialized but powered off. */ - NRF_DRV_STATE_POWERED_ON +typedef enum +{ + NRF_DRV_STATE_UNINITIALIZED, /**< Uninitialized. */ + NRF_DRV_STATE_INITIALIZED, /**< Initialized but powered off. */ + NRF_DRV_STATE_POWERED_ON } nrf_drv_state_t; /** - * @enum nrf_drv_pwr_ctrl_t * @brief Driver power state selection. */ typedef enum @@ -45,6 +115,52 @@ typedef enum NRF_DRV_PWR_CTRL_OFF /**< Power off request. */ } nrf_drv_pwr_ctrl_t; +/** + * @brief IRQ handler type. + */ +typedef void (*nrf_drv_irq_handler_t)(void); + + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +/** + * @brief Function for acquiring shared peripheral resources associated with + * the specified peripheral. + * + * Certain resources and registers are shared among peripherals that have + * the same ID (for example: SPI0, SPIM0, SPIS0, TWI0, TWIM0, and TWIS0). + * Only one of them can be utilized at a given time. This function reserves + * proper resources to be used by the specified peripheral. + * If PERIPHERAL_RESOURCE_SHARING_ENABLED is set to a non-zero value, IRQ + * handlers for peripherals that are sharing resources with others are + * implemented by the nrf_drv_common module instead of individual drivers. + * The drivers must then specify their interrupt handling routines and + * register them by using this function. + * + * @param[in] p_per_base Requested peripheral base pointer. + * @param[in] handler Interrupt handler to register. May be NULL + * if interrupts are not used for the peripheral. + * + * @retval NRF_SUCCESS If resources were acquired successfully. + * @retval NRF_ERROR_BUSY If resources were already acquired. + * @retval NRF_ERROR_INVALID_PARAM If the specified peripheral is not enabled + * or the peripheral does not share resources + * with other peripherals. + */ +ret_code_t nrf_drv_common_per_res_acquire(void const * p_per_base, + nrf_drv_irq_handler_t handler); + +/** + * @brief Function for releasing shared resources reserved previously by + * @ref nrf_drv_common_per_res_acquire() for the specified peripheral. + * + * @param[in] p_per_base Requested peripheral base pointer. + */ +void nrf_drv_common_per_res_release(void const * p_per_base); + +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + + /** * @brief Function sets priority and enables NVIC interrupt * @@ -55,6 +171,44 @@ typedef enum */ void nrf_drv_common_irq_enable(IRQn_Type IRQn, uint8_t priority); +#if NRF_MODULE_ENABLED(POWER) +/** + * @brief Disable power IRQ + * + * Power and clock peripheral uses the same IRQ. + * This function disables POWER_CLOCK IRQ only if CLOCK driver + * is uninitialized. + * + * @sa nrf_drv_common_power_clock_irq_init + */ +void nrf_drv_common_power_irq_disable(void); +#endif + +#if NRF_MODULE_ENABLED(CLOCK) +/** + * @brief Disable clock IRQ + * + * Power and clock peripheral uses the same IRQ. + * This function disables POWER_CLOCK IRQ only if POWER driver + * is uninitialized. + * + * @sa nrf_drv_common_power_clock_irq_init + */ +void nrf_drv_common_clock_irq_disable(void); +#endif + +/** + * @brief Check if interrupt is enabled + * + * Function that checks if selected interrupt is enabled. + * + * @param[in] IRQn Interrupt id + * + * @retval true Selected IRQ is enabled. + * @retval false Selected IRQ is disabled. + */ +__STATIC_INLINE bool nrf_drv_common_irq_enable_check(IRQn_Type IRQn); + /** * @brief Function disables NVIC interrupt * @@ -70,7 +224,7 @@ __STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn); * of peripheral instance. * * For example the result of this function can be casted directly to - * the types like @ref nrf_twis_event_t or @ref nrf_rng_events_t... + * the types like @ref nrf_twis_event_t or @ref nrf_rng_event_t * * @param bit Bit position in INTEN register * @return Event code to be casted to the right enum type or to be used in functions like @@ -86,7 +240,7 @@ __STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit); * This function can be used to get bit position in INTEN register from event code. * * @param event Event code that may be casted from enum values from types like - * @ref nrf_twis_event_t or @ref nrf_rng_events_t + * @ref nrf_twis_event_t or @ref nrf_rng_event_t * @return Bit position in INTEN register that corresponds to the given code. * * @sa nrf_drv_bitpos_to_event @@ -102,6 +256,28 @@ __STATIC_INLINE uint32_t nrf_drv_event_to_bitpos(uint32_t event); */ __STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst); +#if NRF_MODULE_ENABLED(CLOCK) || NRF_MODULE_ENABLED(POWER) +/** + * @brief Enable and setup power clock IRQ + * + * This function would be called from @ref nrf_drv_clock and @ref nrf_drv_power + * to enable related interrupt. + * This function avoids multiple interrupt configuration. + * + * @note + * This function is aviable only if @ref nrf_drv_clock or @ref nrf_drv_power + * module is enabled. + * + * @note + * If both @ref nrf_drv_clock and @ref nrf_drv_power modules are enabled, + * during the compilation the check is made that + * @ref CLOCK_CONFIG_IRQ_PRIORITY equals @ref POWER_CONFIG_IRQ_PRIORITY. + * + * @sa nrf_drv_common_power_irq_disable + * @sa nrf_drv_common_clock_irq_disable + */ +__STATIC_INLINE void nrf_drv_common_power_clock_irq_init(void); +#endif /** * @brief Check if given object is in RAM @@ -114,14 +290,19 @@ __STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst); */ __STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr); - #ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE bool nrf_drv_common_irq_enable_check(IRQn_Type IRQn) +{ + return 0 != (NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] & + (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))); +} + __STATIC_INLINE void nrf_drv_common_irq_disable(IRQn_Type IRQn) { NVIC_DisableIRQ(IRQn); } - __STATIC_INLINE uint32_t nrf_drv_bitpos_to_event(uint32_t bit) { return NRF_DRV_COMMON_EVREGS_OFFSET + bit * sizeof(uint32_t); @@ -138,10 +319,40 @@ __STATIC_INLINE IRQn_Type nrf_drv_get_IRQn(void const * const pinst) return (IRQn_Type) ret; } +#if NRF_MODULE_ENABLED(CLOCK) || NRF_MODULE_ENABLED(POWER) +__STATIC_INLINE void nrf_drv_common_power_clock_irq_init(void) +{ + if(!nrf_drv_common_irq_enable_check(POWER_CLOCK_IRQn)) + { + nrf_drv_common_irq_enable( + POWER_CLOCK_IRQn, +#if NRF_DRV_COMMON_POWER_CLOCK_ISR + #if CLOCK_CONFIG_IRQ_PRIORITY != POWER_CONFIG_IRQ_PRIORITY + #error CLOCK_CONFIG_IRQ_PRIORITY and POWER_CONFIG_IRQ_PRIORITY have to be the same. + #endif + CLOCK_CONFIG_IRQ_PRIORITY +#elif NRF_MODULE_ENABLED(CLOCK) + CLOCK_CONFIG_IRQ_PRIORITY +#elif NRF_MODULE_ENABLED(POWER) + POWER_CONFIG_IRQ_PRIORITY +#endif + ); + } +} +#endif + __STATIC_INLINE bool nrf_drv_is_in_RAM(void const * const ptr) { return ((((uintptr_t)ptr) & 0xE0000000u) == 0x20000000u); } + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} #endif -#endif //NRF_DRV_COMMON_H__ +#endif // NRF_DRV_COMMON_H__ + +/** @} */ diff --git a/components/drivers_nrf/common/nrf_drv_validation.h b/components/drivers_nrf/common/nrf_drv_validation.h deleted file mode 100644 index 88ff384..0000000 --- a/components/drivers_nrf/common/nrf_drv_validation.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_DRV_VALIDATION__ -#define NRF_DRV_VALIDATION__ - -#if TIMER1_ENABLED - #if (TIMER1_CONFIG_BIT_WIDTH == TIMER_BITMODE_BITMODE_24Bit) || (TIMER1_CONFIG_BIT_WIDTH == TIMER_BITMODE_BITMODE_32Bit) - #error "TIMER1 instance does not support such BIT_WIDTH" - #endif -#endif -#endif //NRF_DRV_VALIDATION__ diff --git a/components/drivers_nrf/comp/nrf_drv_comp.c b/components/drivers_nrf/comp/nrf_drv_comp.c new file mode 100644 index 0000000..85453e8 --- /dev/null +++ b/components/drivers_nrf/comp/nrf_drv_comp.c @@ -0,0 +1,238 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(COMP) +#include "nrf_drv_comp.h" + +#include "nrf_assert.h" +#include "nrf_error.h" +#include "nrf_soc.h" +#include "nrf_drv_common.h" +#include "app_util_platform.h" +#include +#include +#include + +#define NRF_LOG_MODULE_NAME "COMP" + +#if COMP_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL COMP_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR COMP_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR COMP_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_COMP_EVENT_READY ? "NRF_COMP_EVENT_READY" : \ + (event == NRF_COMP_EVENT_DOWN ? "NRF_COMP_EVENT_DOWN" : \ + (event == NRF_COMP_EVENT_UP ? "NRF_COMP_EVENT_UP" : \ + (event == NRF_COMP_EVENT_CROSS ? "NRF_COMP_EVENT_CROSS" : "UNKNOWN ERROR")))) +#else //COMP_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //COMP_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + + +static comp_events_handler_t m_comp_events_handler = NULL; +static nrf_drv_state_t m_state = NRF_DRV_STATE_UNINITIALIZED; + +static const nrf_drv_comp_config_t m_default_config = NRF_DRV_COMP_DEFAULT_CONFIG(NRF_COMP_INPUT_0); + +static void comp_execute_handler(nrf_comp_event_t event, uint32_t event_mask) +{ + if ( nrf_comp_event_check(event) && nrf_comp_int_enable_check(event_mask) ) + { + nrf_comp_event_clear(event); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(event)); + + m_comp_events_handler(event); + } +} + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME irq_handler_for_comp + #define IRQ_HANDLER static void IRQ_HANDLER_NAME(void) + + IRQ_HANDLER; +#else + #define IRQ_HANDLER void COMP_LPCOMP_IRQHandler(void) +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +IRQ_HANDLER +{ + comp_execute_handler(NRF_COMP_EVENT_READY, COMP_INTENSET_READY_Msk); + comp_execute_handler(NRF_COMP_EVENT_DOWN, COMP_INTENSET_DOWN_Msk); + comp_execute_handler(NRF_COMP_EVENT_UP, COMP_INTENSET_UP_Msk); + comp_execute_handler(NRF_COMP_EVENT_CROSS, COMP_INTENSET_CROSS_Msk); +} + + +ret_code_t nrf_drv_comp_init(const nrf_drv_comp_config_t * p_config, + comp_events_handler_t event_handler) +{ + ret_code_t err_code; + + if (m_state != NRF_DRV_STATE_UNINITIALIZED) + { // COMP driver is already initialized + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + if (p_config == NULL) + { + p_config = &m_default_config; + } + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(NRF_COMP, IRQ_HANDLER_NAME) != NRF_SUCCESS) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } +#endif + + nrf_comp_task_trigger(NRF_COMP_TASK_STOP); + nrf_comp_enable(); + + // Clear events to be sure there are no leftovers. + nrf_comp_event_clear(NRF_COMP_EVENT_READY); + nrf_comp_event_clear(NRF_COMP_EVENT_DOWN); + nrf_comp_event_clear(NRF_COMP_EVENT_UP); + nrf_comp_event_clear(NRF_COMP_EVENT_CROSS); + + nrf_comp_ref_set(p_config->reference); + + //If external source is chosen, write to appropriate register. + if (p_config->reference == COMP_REFSEL_REFSEL_ARef) + { + nrf_comp_ext_ref_set(p_config->ext_ref); + } + + nrf_comp_th_set(p_config->threshold); + nrf_comp_main_mode_set(p_config->main_mode); + nrf_comp_speed_mode_set(p_config->speed_mode); + nrf_comp_hysteresis_set(p_config->hyst); + nrf_comp_isource_set(p_config->isource); + nrf_comp_shorts_disable(NRF_DRV_COMP_SHORT_STOP_AFTER_CROSS_EVT | NRF_DRV_COMP_SHORT_STOP_AFTER_UP_EVT | + NRF_DRV_COMP_SHORT_STOP_AFTER_DOWN_EVT); + nrf_comp_int_disable(COMP_INTENCLR_CROSS_Msk | COMP_INTENCLR_UP_Msk | + COMP_INTENCLR_DOWN_Msk | COMP_INTENCLR_READY_Msk); + + if (event_handler) + { + m_comp_events_handler = event_handler; + } + else + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + nrf_comp_input_select(p_config->input); + + nrf_drv_common_irq_enable(COMP_LPCOMP_IRQn, p_config->interrupt_priority); + + m_state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +void nrf_drv_comp_uninit(void) +{ + ASSERT(m_state != NRF_DRV_STATE_UNINITIALIZED); + nrf_drv_common_irq_disable(COMP_LPCOMP_IRQn); + nrf_comp_disable(); +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(NRF_COMP); +#endif + m_state = NRF_DRV_STATE_UNINITIALIZED; + m_comp_events_handler = NULL; + NRF_LOG_INFO("Uninitialized.\r\n"); +} + +void nrf_drv_comp_pin_select(nrf_comp_input_t psel) +{ + bool comp_enable_state = nrf_comp_enable_check(); + nrf_comp_task_trigger(NRF_COMP_TASK_STOP); + if (m_state == NRF_DRV_STATE_POWERED_ON) + { + m_state = NRF_DRV_STATE_INITIALIZED; + } + nrf_comp_disable(); + nrf_comp_input_select(psel); + if (comp_enable_state == true) + { + nrf_comp_enable(); + } +} + +void nrf_drv_comp_start(uint32_t comp_int_mask, uint32_t comp_shorts_mask) +{ + ASSERT(m_state == NRF_DRV_STATE_INITIALIZED); + nrf_comp_int_enable(comp_int_mask); + nrf_comp_shorts_enable(comp_shorts_mask); + nrf_comp_task_trigger(NRF_COMP_TASK_START); + m_state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled.\r\n"); +} + +void nrf_drv_comp_stop(void) +{ + ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); + nrf_comp_shorts_disable(UINT32_MAX); + nrf_comp_int_disable(UINT32_MAX); + nrf_comp_task_trigger(NRF_COMP_TASK_STOP); + m_state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled.\r\n"); +} + +uint32_t nrf_drv_comp_sample() +{ + ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); + nrf_comp_task_trigger(NRF_COMP_TASK_SAMPLE); + return nrf_comp_result_get(); +} +#endif //NRF_MODULE_ENABLED(COMP) diff --git a/components/drivers_nrf/comp/nrf_drv_comp.h b/components/drivers_nrf/comp/nrf_drv_comp.h new file mode 100644 index 0000000..d569377 --- /dev/null +++ b/components/drivers_nrf/comp/nrf_drv_comp.h @@ -0,0 +1,244 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_COMP_H__ +#define NRF_DRV_COMP_H__ + +#include "sdk_config.h" +#include "nrf_comp.h" +#include "sdk_errors.h" +#include "nrf_drv_common.h" +#include "app_util_platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup nrf_comp COMP HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52 Comparator (COMP) APIs. + * @details The COMP HAL provides basic APIs for accessing the registers of Comparator. + * The COMP driver provides APIs on a higher level. + * + * @defgroup nrf_drv_comp COMP driver + * @{ + * @ingroup nrf_comp + * @brief @tagAPI52 Comparator (COMP) driver. + */ + +/** + * @brief Macro to convert the threshold voltage to an integer value (needed by the COMP_TH register). + * + * @param[in] vol Voltage to be changed to COMP_TH register value. This value must not be smaller than + * reference voltage divided by 64. + * @param[in] ref Reference voltage. + */ +#define VOLTAGE_THRESHOLD_TO_INT(vol, ref) (uint8_t)(((vol) > ((ref) / 64)) ? (ROUNDED_DIV((vol) * 64,(ref)) - 1) : 0) + +/**@brief COMP event handler function type. + * @param[in] event COMP event. + */ +typedef void (* comp_events_handler_t)(nrf_comp_event_t event); + +/** + * @enum nrf_drv_comp_short_mask_t + * @brief COMP shortcut masks. + */ +typedef enum +{ + NRF_DRV_COMP_SHORT_STOP_AFTER_CROSS_EVT = COMP_SHORTS_CROSS_STOP_Msk, /*!< Shortcut between the CROSS event and the STOP task. */ + NRF_DRV_COMP_SHORT_STOP_AFTER_UP_EVT = COMP_SHORTS_UP_STOP_Msk, /*!< Shortcut between the UP event and the STOP task. */ + NRF_DRV_COMP_SHORT_STOP_AFTER_DOWN_EVT = COMP_SHORTS_DOWN_STOP_Msk /*!< Shortcut between the DOWN event and the STOP task. */ +}nrf_drv_comp_short_mask_t; + +/** + * @enum nrf_drv_comp_evt_en_mask_t + * @brief COMP events masks. + */ +typedef enum +{ + NRF_DRV_COMP_EVT_EN_CROSS_MASK = COMP_INTENSET_CROSS_Msk, /*!< CROSS event (generated after VIN+ == VIN-). */ + NRF_DRV_COMP_EVT_EN_UP_MASK = COMP_INTENSET_UP_Msk, /*!< UP event (generated when VIN+ crosses VIN- while increasing). */ + NRF_DRV_COMP_EVT_EN_DOWN_MASK = COMP_INTENSET_DOWN_Msk, /*!< DOWN event (generated when VIN+ crosses VIN- while decreasing). */ + NRF_DRV_COMP_EVT_EN_READY_MASK = COMP_INTENSET_READY_Msk /*!< READY event (generated when the module is ready). */ +}nrf_drv_comp_evt_en_mask_t; + +/**@brief COMP configuration. + */ +typedef struct +{ + nrf_comp_ref_t reference; /**< Reference selection. */ + nrf_comp_ext_ref_t ext_ref; /**< External analog reference selection. */ + nrf_comp_main_mode_t main_mode; /**< Main operation mode. */ + nrf_comp_th_t threshold; /**< Structure holding THDOWN and THUP values needed by the COMP_TH register. */ + nrf_comp_sp_mode_t speed_mode; /**< Speed and power mode. */ + nrf_comp_hyst_t hyst; /**< Comparator hysteresis.*/ + nrf_isource_t isource; /**< Current source selected on analog input. */ + nrf_comp_input_t input; /**< Input to be monitored. */ + uint8_t interrupt_priority; /**< Interrupt priority. */ +} nrf_drv_comp_config_t; + +/** @brief COMP threshold default configuration. */ +#define COMP_CONFIG_TH \ +{ \ + .th_down = VOLTAGE_THRESHOLD_TO_INT(0.5, 1.8), \ + .th_up = VOLTAGE_THRESHOLD_TO_INT(1.5, 1.8) \ +} + +/** @brief COMP driver default configuration including the COMP HAL configuration. */ +#define NRF_DRV_COMP_DEFAULT_CONFIG(INPUT) \ +{ \ + .reference = (nrf_comp_ref_t)COMP_CONFIG_REF, \ + .main_mode = (nrf_comp_main_mode_t)COMP_CONFIG_MAIN_MODE, \ + .threshold = COMP_CONFIG_TH, \ + .speed_mode = (nrf_comp_sp_mode_t)COMP_CONFIG_SPEED_MODE, \ + .hyst = (nrf_comp_hyst_t)COMP_CONFIG_HYST, \ + .isource = (nrf_isource_t)COMP_CONFIG_ISOURCE, \ + .input = (nrf_comp_input_t)INPUT, \ + .interrupt_priority = COMP_CONFIG_IRQ_PRIORITY \ +} + +/** + * @brief Function for initializing the COMP driver. + * + * This function initializes the COMP driver, but does not enable the peripheral or any interrupts. + * To start the driver, call the function @ref nrf_drv_comp_start() after initialization. + * + * If no configuration structure is provided, the driver is initialized with the default settings. + * + * @param[in] p_config Initial configuration. If NULL, the default configuration is used. + * @param[in] event_handler Handler function. + * + * @retval NRF_ERROR_INVALID_PARAM If the configuration is invalid. + * @retval NRF_ERROR_INVALID_STATE If the driver has already been initialized. + * @retval NRF_ERROR_BUSY If the LPCOMP driver is initialized. + */ +ret_code_t nrf_drv_comp_init(const nrf_drv_comp_config_t * p_config, + comp_events_handler_t event_handler); + + +/** + * @brief Function for uninitializing the COMP driver. + * + * This function uninitializes the COMP driver. The COMP peripheral and + * its interrupts are disabled, and local variables are cleaned. After this call, you must + * initialize the driver again by calling nrf_drv_comp_init() if you want to use it. + * + * @sa nrf_drv_comp_stop() + */ +void nrf_drv_comp_uninit(void); + +/** + * @brief Function for setting the analog input. + * + * @param[in] psel COMP analog pin selection. + */ +void nrf_drv_comp_pin_select(nrf_comp_input_t psel); + +/** + * @brief Function for starting the COMP peripheral and interrupts. + * + * Before calling this function, the driver must be initialized. This function + * enables the COMP peripheral and its interrupts. + * + * @param[in] comp_evt_en_mask Mask of events to be enabled. This parameter should be built as + * 'or' of elements from @ref nrf_drv_comp_evt_en_mask_t. + * @param[in] comp_shorts_mask Mask of shorts to be enabled. This parameter should be built as + * 'or' of elements from @ref nrf_drv_comp_short_mask_t. + * + * @sa nrf_drv_comp_init() + * + */ +void nrf_drv_comp_start(uint32_t comp_evt_en_mask, uint32_t comp_shorts_mask); + +/**@brief Function for stopping the COMP peripheral. + * + * Before calling this function, the driver must be enabled. This function disables the COMP + * peripheral and its interrupts. + * + * @sa nrf_drv_comp_uninit() + * + */ +void nrf_drv_comp_stop(void); + +/** + * @brief Function for copying the current state of the comparator result to the RESULT register. + * + * @retval 0 If the input voltage is below the threshold (VIN+ < VIN-). + * @retval 1 If the input voltage is above the threshold (VIN+ > VIN-). + */ +uint32_t nrf_drv_comp_sample(void); + +/** + * @brief Function for getting the task address. + * + * Before calling this function, the driver must be enabled. + * + * @param[in] comp_task COMP task. + * + * @return Address of the given COMP task. + */ +__STATIC_INLINE uint32_t nrf_drv_comp_task_address_get(nrf_comp_task_t comp_task) +{ + return (uint32_t)nrf_comp_task_address_get(comp_task); +} + +/** + * @brief Function for getting the event address. + * + * @param[in] comp_event COMP event. + * + * @return Address of the given COMP event. + */ +__STATIC_INLINE uint32_t nrf_drv_comp_event_address_get(nrf_comp_event_t comp_event) +{ + return (uint32_t)nrf_comp_event_address_get(comp_event); +} + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif +#endif /* NRF_DRV_COMP_H__ */ diff --git a/components/drivers_nrf/config/nrf_drv_config.h b/components/drivers_nrf/config/nrf_drv_config.h deleted file mode 100644 index 3f958ce..0000000 --- a/components/drivers_nrf/config/nrf_drv_config.h +++ /dev/null @@ -1,341 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_DRV_CONFIG_H -#define NRF_DRV_CONFIG_H - -/* CLOCK */ -#define CLOCK_CONFIG_XTAL_FREQ NRF_CLOCK_XTALFREQ_Default -#define CLOCK_CONFIG_LF_SRC NRF_CLOCK_LF_SRC_Xtal -#define CLOCK_CONFIG_LF_RC_CAL_INTERVAL RC_2000MS_CALIBRATION_INTERVAL -#define CLOCK_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -/* GPIOTE */ -#define GPIOTE_ENABLED 0 - -#if (GPIOTE_ENABLED == 1) -#define GPIOTE_CONFIG_USE_SWI_EGU false -#define GPIOTE_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 1 -#endif - -/* TIMER */ -#define TIMER0_ENABLED 0 - -#if (TIMER0_ENABLED == 1) -#define TIMER0_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz -#define TIMER0_CONFIG_MODE TIMER_MODE_MODE_Timer -#define TIMER0_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit -#define TIMER0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TIMER0_INSTANCE_INDEX 0 -#endif - -#define TIMER1_ENABLED 0 - -#if (TIMER1_ENABLED == 1) -#define TIMER1_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz -#define TIMER1_CONFIG_MODE TIMER_MODE_MODE_Timer -#define TIMER1_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TIMER1_INSTANCE_INDEX (TIMER0_ENABLED) -#endif - -#define TIMER2_ENABLED 0 - -#if (TIMER2_ENABLED == 1) -#define TIMER2_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz -#define TIMER2_CONFIG_MODE TIMER_MODE_MODE_Timer -#define TIMER2_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TIMER2_INSTANCE_INDEX (TIMER1_ENABLED+TIMER0_ENABLED) -#endif - -#define TIMER3_ENABLED 0 - -#if (TIMER3_ENABLED == 1) -#define TIMER3_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz -#define TIMER3_CONFIG_MODE TIMER_MODE_MODE_Timer -#define TIMER3_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER3_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TIMER3_INSTANCE_INDEX (TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED) -#endif - -#define TIMER4_ENABLED 0 - -#if (TIMER4_ENABLED == 1) -#define TIMER4_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz -#define TIMER4_CONFIG_MODE TIMER_MODE_MODE_Timer -#define TIMER4_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER4_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TIMER4_INSTANCE_INDEX (TIMER3_ENABLED+TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED) -#endif - - -#define TIMER_COUNT (TIMER0_ENABLED + TIMER1_ENABLED + TIMER2_ENABLED + TIMER3_ENABLED + TIMER4_ENABLED) - -/* RTC */ -#define RTC0_ENABLED 0 - -#if (RTC0_ENABLED == 1) -#define RTC0_CONFIG_FREQUENCY 32678 -#define RTC0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#define RTC0_CONFIG_RELIABLE false - -#define RTC0_INSTANCE_INDEX 0 -#endif - -#define RTC1_ENABLED 0 - -#if (RTC1_ENABLED == 1) -#define RTC1_CONFIG_FREQUENCY 32768 -#define RTC1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#define RTC1_CONFIG_RELIABLE false - -#define RTC1_INSTANCE_INDEX (RTC0_ENABLED) -#endif - -#define RTC_COUNT (RTC0_ENABLED+RTC1_ENABLED) - -#define NRF_MAXIMUM_LATENCY_US 2000 - -/* RNG */ -#define RNG_ENABLED 0 - -#if (RNG_ENABLED == 1) -#define RNG_CONFIG_ERROR_CORRECTION true -#define RNG_CONFIG_POOL_SIZE 8 -#define RNG_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#endif - -/* SPI */ -#define SPI0_ENABLED 0 - -#if (SPI0_ENABLED == 1) -#define SPI0_USE_EASY_DMA 0 - -#define SPI0_CONFIG_SCK_PIN 2 -#define SPI0_CONFIG_MOSI_PIN 3 -#define SPI0_CONFIG_MISO_PIN 4 -#define SPI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPI0_INSTANCE_INDEX 0 -#endif - -#define SPI1_ENABLED 0 - -#if (SPI1_ENABLED == 1) -#define SPI1_USE_EASY_DMA 0 - -#define SPI1_CONFIG_SCK_PIN 2 -#define SPI1_CONFIG_MOSI_PIN 3 -#define SPI1_CONFIG_MISO_PIN 4 -#define SPI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPI1_INSTANCE_INDEX (SPI0_ENABLED) -#endif - -#define SPI2_ENABLED 0 - -#if (SPI2_ENABLED == 1) -#define SPI2_USE_EASY_DMA 0 - -#define SPI2_CONFIG_SCK_PIN 2 -#define SPI2_CONFIG_MOSI_PIN 3 -#define SPI2_CONFIG_MISO_PIN 4 -#define SPI2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPI2_INSTANCE_INDEX (SPI0_ENABLED + SPI1_ENABLED) -#endif - -#define SPI_COUNT (SPI0_ENABLED + SPI1_ENABLED + SPI2_ENABLED) - -/* SPIS */ -#define SPIS0_ENABLED 0 - -#if (SPIS0_ENABLED == 1) -#define SPIS0_CONFIG_SCK_PIN 2 -#define SPIS0_CONFIG_MOSI_PIN 3 -#define SPIS0_CONFIG_MISO_PIN 4 -#define SPIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPIS0_INSTANCE_INDEX 0 -#endif - -#define SPIS1_ENABLED 0 - -#if (SPIS1_ENABLED == 1) -#define SPIS1_CONFIG_SCK_PIN 2 -#define SPIS1_CONFIG_MOSI_PIN 3 -#define SPIS1_CONFIG_MISO_PIN 4 -#define SPIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPIS1_INSTANCE_INDEX SPIS0_ENABLED -#endif - -#define SPIS2_ENABLED 0 - -#if (SPIS2_ENABLED == 1) -#define SPIS2_CONFIG_SCK_PIN 2 -#define SPIS2_CONFIG_MOSI_PIN 3 -#define SPIS2_CONFIG_MISO_PIN 4 -#define SPIS2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPIS2_INSTANCE_INDEX (SPIS0_ENABLED + SPIS1_ENABLED) -#endif - -#define SPIS_COUNT (SPIS0_ENABLED + SPIS1_ENABLED + SPIS2_ENABLED) - -/* UART */ -#define UART0_ENABLED 0 - -#if (UART0_ENABLED == 1) -#define UART0_CONFIG_HWFC NRF_UART_HWFC_DISABLED -#define UART0_CONFIG_PARITY NRF_UART_PARITY_EXCLUDED -#define UART0_CONFIG_BAUDRATE NRF_UART_BAUDRATE_38400 -#define UART0_CONFIG_PSEL_TXD 0 -#define UART0_CONFIG_PSEL_RXD 0 -#define UART0_CONFIG_PSEL_CTS 0 -#define UART0_CONFIG_PSEL_RTS 0 -#define UART0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#ifdef NRF52 -#define UART0_CONFIG_USE_EASY_DMA false -//Compile time flag -#define UART_EASY_DMA_SUPPORT 1 -#define UART_LEGACY_SUPPORT 1 -#endif //NRF52 -#endif - -#define TWI0_ENABLED 0 - -#if (TWI0_ENABLED == 1) -#define TWI0_CONFIG_FREQUENCY NRF_TWI_FREQ_100K -#define TWI0_CONFIG_SCL 0 -#define TWI0_CONFIG_SDA 1 -#define TWI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TWI0_INSTANCE_INDEX 0 -#endif - -#define TWI1_ENABLED 0 - -#if (TWI1_ENABLED == 1) -#define TWI1_CONFIG_FREQUENCY NRF_TWI_FREQ_100K -#define TWI1_CONFIG_SCL 0 -#define TWI1_CONFIG_SDA 1 -#define TWI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TWI1_INSTANCE_INDEX (TWI0_ENABLED) -#endif - -#define TWI_COUNT (TWI0_ENABLED+TWI1_ENABLED) - -/* TWIS */ -#define TWIS0_ENABLED 0 - -#if (TWIS0_ENABLED == 1) - #define TWIS0_CONFIG_ADDR0 0 - #define TWIS0_CONFIG_ADDR1 0 /* 0: Disabled */ - #define TWIS0_CONFIG_SCL 0 - #define TWIS0_CONFIG_SDA 1 - #define TWIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - - #define TWIS0_INSTANCE_INDEX 0 -#endif - -#define TWIS1_ENABLED 0 - -#if (TWIS1_ENABLED == 1) - #define TWIS1_CONFIG_ADDR0 0 - #define TWIS1_CONFIG_ADDR1 0 /* 0: Disabled */ - #define TWIS1_CONFIG_SCL 0 - #define TWIS1_CONFIG_SDA 1 - #define TWIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - - #define TWIS1_INSTANCE_INDEX (TWIS0_ENABLED) -#endif - -#define TWIS_COUNT (TWIS0_ENABLED + TWIS1_ENABLED) -/* For more documentation see nrf_drv_twis.h file */ -#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -/* For more documentation see nrf_drv_twis.h file */ -#define TWIS_NO_SYNC_MODE 0 -/** - * @brief Definition for patching PAN problems - * - * Set this definition to nonzero value to patch anomalies - * from MPW3 - first lunch microcontroller. - * - * Concerns: - * - PAN-29: TWIS: incorrect bits in ERRORSRC - * - PAN-30: TWIS: STOP task does not work as expected - */ -#define NRF_TWIS_PATCH_FOR_MPW3 1 - - -/* QDEC */ -#define QDEC_ENABLED 0 - -#if (QDEC_ENABLED == 1) -#define QDEC_CONFIG_REPORTPER NRF_QDEC_REPORTPER_10 -#define QDEC_CONFIG_SAMPLEPER NRF_QDEC_SAMPLEPER_16384us -#define QDEC_CONFIG_PIO_A 1 -#define QDEC_CONFIG_PIO_B 2 -#define QDEC_CONFIG_PIO_LED 3 -#define QDEC_CONFIG_LEDPRE 511 -#define QDEC_CONFIG_LEDPOL NRF_QDEC_LEPOL_ACTIVE_HIGH -#define QDEC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#define QDEC_CONFIG_DBFEN false -#define QDEC_CONFIG_SAMPLE_INTEN false -#endif - -/* SAADC */ -#define SAADC_ENABLED 0 - -#if (SAADC_ENABLED == 1) -#define SAADC_CONFIG_RESOLUTION NRF_SAADC_RESOLUTION_10BIT -#define SAADC_CONFIG_OVERSAMPLE NRF_SAADC_OVERSAMPLE_DISABLED -#define SAADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#endif - -/* LPCOMP */ -#define LPCOMP_ENABLED 0 - -#if (LPCOMP_ENABLED == 1) -#define LPCOMP_CONFIG_REFERENCE NRF_LPCOMP_REF_SUPPLY_4_8 -#define LPCOMP_CONFIG_DETECTION NRF_LPCOMP_DETECT_DOWN -#define LPCOMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#define LPCOMP_CONFIG_INPUT NRF_LPCOMP_INPUT_0 -#endif - -/* WDT */ -#define WDT_ENABLED 0 - -#if (WDT_ENABLED == 1) -#define WDT_CONFIG_BEHAVIOUR NRF_WDT_BEHAVIOUR_RUN_SLEEP -#define WDT_CONFIG_RELOAD_VALUE 2000 -#define WDT_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH -#endif - -/* SWI EGU */ -#ifdef NRF52 - #define EGU_ENABLED 0 -#endif - - -#include "nrf_drv_config_validation.h" - -#endif // NRF_DRV_CONFIG_H diff --git a/components/drivers_nrf/config/nrf_drv_config_validation.h b/components/drivers_nrf/config/nrf_drv_config_validation.h deleted file mode 100644 index 7acf1f3..0000000 --- a/components/drivers_nrf/config/nrf_drv_config_validation.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_DRV_CONFIG_VALIDATION_H -#define NRF_DRV_CONFIG_VALIDATION_H - -#ifdef NRF52 - -#if (TWI0_ENABLED+SPI0_ENABLED+SPIS0_ENABLED+TWIS0_ENABLED)>1 -#error "TWI0, SPI0, SPIS0 or TWIS0 cannot be enabled together. Instances overlaps." -#endif - -#if (TWI1_ENABLED+SPI1_ENABLED+SPIS1_ENABLED+TWIS1_ENABLED)>1 -#error "TWI1, SPI1, SPIS1 or TWIS1 cannot be enabled together. Instances overlaps." -#endif - -#if (SPI2_ENABLED+SPIS2_ENABLED)>1 -#error "SPI2 and SPIS2 cannot be enabled together. Instances overlaps." -#endif - -#else //NRF51 - -#if (TWIS0_ENABLED + TWIS1_ENABLED) > 0 -#error "TWIS not present in NRF51." -#endif - -#if SPIS0_ENABLED > 0 -#error "SPIS0 instance not present in NRF51." -#endif - -#if SPI2_ENABLED + SPIS2_ENABLED > 0 -#error "SPI2/SPIS2 instance not present in NRF51." -#endif - -#if (TIMER3_ENABLED + TIMER4_ENABLED) > 0 -#error "TIMER3 and TIMER4 not present in NRF51" -#endif - -#if (TWI0_ENABLED+SPI0_ENABLED)>1 -#error "TWI0, SPI0 or TWIS0 cannot be enabled together. Peripherals overlaps." -#endif - -#if (TWI1_ENABLED+SPI1_ENABLED)>1 -#error "TWI1, SPI1 or TWIS1 cannot be enabled together. Peripherals overlaps." -#endif - -#if SAADC_ENABLED > 0 -#error "SAADC not present in NRF51." -#endif - -#endif //NRF51 - -#endif //NRF_DRV_CONFIG_VALIDATION_H diff --git a/components/drivers_nrf/delay/nrf_delay.c b/components/drivers_nrf/delay/nrf_delay.c deleted file mode 100644 index e8b561a..0000000 --- a/components/drivers_nrf/delay/nrf_delay.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "compiler_abstraction.h" -#include "nrf.h" -#include "nrf_delay.h" - -/*lint --e{438} "Variable not used" */ -void nrf_delay_ms(uint32_t volatile number_of_ms) -{ - while(number_of_ms != 0) - { - number_of_ms--; - nrf_delay_us(999); - } -} diff --git a/components/drivers_nrf/delay/nrf_delay.h b/components/drivers_nrf/delay/nrf_delay.h index c68bd9a..fd28e3e 100644 --- a/components/drivers_nrf/delay/nrf_delay.h +++ b/components/drivers_nrf/delay/nrf_delay.h @@ -1,242 +1,263 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 _NRF_DELAY_H #define _NRF_DELAY_H #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + +#define CLOCK_FREQ_16MHz (16000000UL) + /** * @brief Function for delaying execution for number of microseconds. * * @note NRF52 has instruction cache and because of that delay is not precise. * - * @param number_of_ms + * @param number_of_us + * */ -/*lint --e{438, 522} "Variable not used" "Function lacks side-effects" */ -#if defined ( __CC_ARM ) +/*lint --e{438, 522, 40, 10, 563} "Variable not used" "Function lacks side-effects" */ +__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us); -static __ASM void __INLINE nrf_delay_us(uint32_t volatile number_of_us) -{ -loop - SUBS R0, R0, #1 - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP -#ifdef NRF52 - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP - NOP -#endif - BNE loop - BX LR -} -#elif defined ( __ICCARM__ ) +/** + * @brief Function for delaying execution for number of miliseconds. + * + * @note NRF52 has instruction cache and because of that delay is not precise. + * + * @note Function internally calls @ref nrf_delay_us so the maximum delay is the + * same as in case of @ref nrf_delay_us, approx. 71 minutes. + * + * @param number_of_ms + * + */ + +/*lint --e{438, 522, 40, 10, 563} "Variable not used" "Function lacks side-effects" */ +__STATIC_INLINE void nrf_delay_ms(uint32_t number_of_ms); -static void __INLINE nrf_delay_us(uint32_t volatile number_of_us) +#if defined ( __CC_ARM ) +__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us) { -__ASM ( -"loop:\n\t" - " SUBS R0, R0, #1\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" -#ifdef NRF52 - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" - " NOP\n\t" + if(!number_of_us) + return; +__asm + { +loop: + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + CMP SystemCoreClock, CLOCK_FREQ_16MHz + BEQ cond + NOP +#if defined(NRF52) || defined(NRF52840_XXAA) || defined(NRF52832) + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP + NOP #endif - " BNE.n loop\n\t"); +cond: + SUBS number_of_us, #1 + BNE loop + } } #elif defined ( _WIN32 ) || defined ( __unix ) || defined( __APPLE__ ) -__STATIC_INLINE void nrf_delay_us(uint32_t volatile number_of_us); #ifndef CUSTOM_NRF_DELAY_US -__STATIC_INLINE void nrf_delay_us(uint32_t volatile number_of_us) +__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us) {} #endif -#elif defined ( __GNUC__ ) +#elif defined ( __GNUC__ ) || ( __ICCARM__ ) -static void __INLINE nrf_delay_us(uint32_t volatile number_of_us) __attribute__((always_inline)); -static void __INLINE nrf_delay_us(uint32_t volatile number_of_us) +__STATIC_INLINE void nrf_delay_us(uint32_t number_of_us) { -register uint32_t delay __ASM ("r0") = number_of_us; + const uint32_t clock16MHz = CLOCK_FREQ_16MHz; + if (number_of_us) + { __ASM volatile ( -#ifdef NRF51 - ".syntax unified\n" +#if ( defined(__GNUC__) && (__CORTEX_M == (0x00U) ) ) + ".syntax unified\n" #endif - "1:\n" - " SUBS %0, %0, #1\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" -#ifdef NRF52 - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" - " NOP\n" +"1:\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " CMP %[SystemCoreClock], %[clock16MHz]\n" + " BEQ.N 2f\n" + " NOP\n" +#if defined(NRF52) || defined(NRF52840_XXAA) || defined(NRF52832) + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" + " NOP\n" #endif - " BNE 1b\n" -#ifdef NRF51 +"2:\n" + " SUBS %[number_of_us], #1\n" + " BNE.N 1b\n" +#if ( defined(__GNUC__) && (__CORTEX_M == (0x00U) ) ) ".syntax divided\n" #endif - : "+r" (delay)); +#if ( __CORTEX_M == (0x00U) ) + // The SUBS instruction in Cortex-M0 is available only in 16-bit encoding, + // hence it requires a "lo" register (r0-r7) as an operand. + : [number_of_us] "=l" (number_of_us) +#else + : [number_of_us] "=r" (number_of_us) +#endif + : [SystemCoreClock] "r" (SystemCoreClock), + [clock16MHz] "r" (clock16MHz), + "[number_of_us]" (number_of_us) + ); + } } #endif -void nrf_delay_ms(uint32_t volatile number_of_ms); +__STATIC_INLINE void nrf_delay_ms(uint32_t number_of_ms) +{ + nrf_delay_us(1000*number_of_ms); +} + + +#ifdef __cplusplus +} +#endif #endif diff --git a/components/drivers_nrf/gpiote/nrf_drv_gpiote.c b/components/drivers_nrf/gpiote/nrf_drv_gpiote.c index 8966342..3fce9c3 100644 --- a/components/drivers_nrf/gpiote/nrf_drv_gpiote.c +++ b/components/drivers_nrf/gpiote/nrf_drv_gpiote.c @@ -1,20 +1,66 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(GPIOTE) #include "nrf_drv_gpiote.h" #include "nrf_drv_common.h" -#include "nrf_drv_config.h" #include "app_util_platform.h" #include "nrf_assert.h" +#include "nrf_bitmask.h" +#include + +#define NRF_LOG_MODULE_NAME "GPIOTE" + +#if GPIOTE_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL GPIOTE_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR GPIOTE_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR GPIOTE_CONFIG_DEBUG_COLOR +#else // GPIOTE_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // GPIOTE_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +/* Validate configuration */ +INTERRUPT_PRIORITY_VALIDATION(GPIOTE_CONFIG_IRQ_PRIORITY); #define FORBIDDEN_HANDLER_ADDRESS ((nrf_drv_gpiote_evt_handler_t)UINT32_MAX) #define PIN_NOT_USED (-1) @@ -24,23 +70,47 @@ #define SENSE_FIELD_MASK (0xC0) /** - * @brief Macro for conveting task-event index to an address of an event register. + * @brief Macro for converting task-event index to an address of an event register. + * + * Macro utilizes the fact that registers are grouped together in ascending order. + */ +#define TE_IDX_TO_EVENT_ADDR(idx) (nrf_gpiote_events_t)((uint32_t)NRF_GPIOTE_EVENTS_IN_0 + \ + (sizeof(uint32_t) * (idx))) + +/** + * @brief Macro for converting task-event index of OUT task to an address of a task register. * * Macro utilizes the fact that registers are grouped together in ascending order. */ -#define TE_IDX_TO_EVENT_ADDR(idx) (nrf_gpiote_events_t)((uint32_t)NRF_GPIOTE_EVENTS_IN_0+(sizeof(uint32_t)*(idx))) +#define TE_OUT_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_OUT_0 + \ + (sizeof(uint32_t) * (idx))) + +#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__SDK_DOXYGEN__) +/** + * @brief Macro for converting task-event index of SET task to an address of a task register. + * + * Macro utilizes the fact that registers are grouped together in ascending order. + */ +#define TE_SET_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_SET_0 + \ + (sizeof(uint32_t) * (idx))) + +#endif // defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__SDK_DOXYGEN__) +#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__SDK_DOXYGEN__) /** - * @brief Macro for conveting task-event index to an address of a task register. + * @brief Macro for converting task-event index of CLR task to an address of a task register. * * Macro utilizes the fact that registers are grouped together in ascending order. */ -#define TE_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_OUT_0+(sizeof(uint32_t)*(idx))) +#define TE_CLR_IDX_TO_TASK_ADDR(idx) (nrf_gpiote_tasks_t)((uint32_t)NRF_GPIOTE_TASKS_CLR_0 + \ + (sizeof(uint32_t) * (idx))) -//lint -save -e661 +#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__SDK_DOXYGEN__) + +/*lint -save -e661*/ typedef struct { - nrf_drv_gpiote_evt_handler_t handlers[NUMBER_OF_GPIO_TE+GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS]; + nrf_drv_gpiote_evt_handler_t handlers[GPIOTE_CH_NUM + GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS]; int8_t pin_assignments[NUMBER_OF_PINS]; int8_t port_handlers_pins[GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS]; nrf_drv_state_t state; @@ -53,67 +123,80 @@ __STATIC_INLINE bool pin_in_use(uint32_t pin) return (m_cb.pin_assignments[pin] != PIN_NOT_USED); } + __STATIC_INLINE bool pin_in_use_as_non_task_out(uint32_t pin) { return (m_cb.pin_assignments[pin] == PIN_USED); } + __STATIC_INLINE bool pin_in_use_by_te(uint32_t pin) { - return (m_cb.pin_assignments[pin] >= 0 && m_cb.pin_assignments[pin] < NUMBER_OF_GPIO_TE) ? true : false; + return (m_cb.pin_assignments[pin] >= 0 && m_cb.pin_assignments[pin] < + GPIOTE_CH_NUM) ? true : false; } + __STATIC_INLINE bool pin_in_use_by_port(uint32_t pin) { - return (m_cb.pin_assignments[pin] >= NUMBER_OF_GPIO_TE); + return (m_cb.pin_assignments[pin] >= GPIOTE_CH_NUM); } + __STATIC_INLINE bool pin_in_use_by_gpiote(uint32_t pin) { return (m_cb.pin_assignments[pin] >= 0); } -__STATIC_INLINE void pin_in_use_by_te_set(uint32_t pin, - uint32_t channel_id, + +__STATIC_INLINE void pin_in_use_by_te_set(uint32_t pin, + uint32_t channel_id, nrf_drv_gpiote_evt_handler_t handler, - bool is_channel) + bool is_channel) { m_cb.pin_assignments[pin] = channel_id; m_cb.handlers[channel_id] = handler; if (!is_channel) { - m_cb.port_handlers_pins[channel_id-NUMBER_OF_GPIO_TE] = (int8_t)pin; + m_cb.port_handlers_pins[channel_id - GPIOTE_CH_NUM] = (int8_t)pin; } } + __STATIC_INLINE void pin_in_use_set(uint32_t pin) { m_cb.pin_assignments[pin] = PIN_USED; } + __STATIC_INLINE void pin_in_use_clear(uint32_t pin) { m_cb.pin_assignments[pin] = PIN_NOT_USED; } + __STATIC_INLINE int8_t channel_port_get(uint32_t pin) { return m_cb.pin_assignments[pin]; } + __STATIC_INLINE nrf_drv_gpiote_evt_handler_t channel_handler_get(uint32_t channel) { return m_cb.handlers[channel]; } -static int8_t channel_port_alloc(uint32_t pin,nrf_drv_gpiote_evt_handler_t handler, bool channel) + +static int8_t channel_port_alloc(uint32_t pin, nrf_drv_gpiote_evt_handler_t handler, bool channel) { - int8_t channel_id = NO_CHANNELS; + int8_t channel_id = NO_CHANNELS; uint32_t i; - uint32_t start_idx = channel ? 0 : NUMBER_OF_GPIO_TE; - uint32_t end_idx = channel ? NUMBER_OF_GPIO_TE : (NUMBER_OF_GPIO_TE+GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS); - //critical section + uint32_t start_idx = channel ? 0 : GPIOTE_CH_NUM; + uint32_t end_idx = + channel ? GPIOTE_CH_NUM : (GPIOTE_CH_NUM + GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS); + + // critical section for (i = start_idx; i < end_idx; i++) { @@ -124,60 +207,77 @@ static int8_t channel_port_alloc(uint32_t pin,nrf_drv_gpiote_evt_handler_t handl break; } } - //critical section + // critical section return channel_id; } + static void channel_free(uint8_t channel_id) { m_cb.handlers[channel_id] = FORBIDDEN_HANDLER_ADDRESS; - if (channel_id >= NUMBER_OF_GPIO_TE) + if (channel_id >= GPIOTE_CH_NUM) { - m_cb.port_handlers_pins[channel_id-NUMBER_OF_GPIO_TE] = (int8_t)PIN_NOT_USED; + m_cb.port_handlers_pins[channel_id - GPIOTE_CH_NUM] = (int8_t)PIN_NOT_USED; } } + ret_code_t nrf_drv_gpiote_init(void) { + ret_code_t err_code; + if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) { - return NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)ERR_TO_STR(err_code)); + return err_code; } uint8_t i; + for (i = 0; i < NUMBER_OF_PINS; i++) { pin_in_use_clear(i); } - for (i = 0; i < (NUMBER_OF_GPIO_TE+GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS); i++) + + for (i = 0; i < (GPIOTE_CH_NUM + GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS); i++) { channel_free(i); } nrf_drv_common_irq_enable(GPIOTE_IRQn, GPIOTE_CONFIG_IRQ_PRIORITY); + nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT); nrf_gpiote_int_enable(GPIOTE_INTENSET_PORT_Msk); m_cb.state = NRF_DRV_STATE_INITIALIZED; - return NRF_SUCCESS; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, + (uint32_t)ERR_TO_STR(err_code)); + return err_code; } + bool nrf_drv_gpiote_is_init(void) { return (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) ? true : false; } + void nrf_drv_gpiote_uninit(void) { - ASSERT(m_cb.state!=NRF_DRV_STATE_UNINITIALIZED); + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); uint32_t i; + for (i = 0; i < NUMBER_OF_PINS; i++) { if (pin_in_use_as_non_task_out(i)) { nrf_drv_gpiote_out_uninit(i); } - else if( pin_in_use_by_gpiote(i)) + else if ( pin_in_use_by_gpiote(i)) { /* Disable gpiote_in is having the same effect on out pin as gpiote_out_uninit on * so it can be called on all pins used by GPIOTE. @@ -186,20 +286,22 @@ void nrf_drv_gpiote_uninit(void) } } m_cb.state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized.\r\n"); } -ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin, + +ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin, nrf_drv_gpiote_out_config_t const * p_config) { ASSERT(pin < NUMBER_OF_PINS); ASSERT(m_cb.state == NRF_DRV_STATE_INITIALIZED); ASSERT(p_config); - ret_code_t result = NRF_SUCCESS; + ret_code_t err_code = NRF_SUCCESS; if (pin_in_use(pin)) { - result = NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; } else { @@ -213,7 +315,7 @@ ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin, } else { - result = NRF_ERROR_NO_MEM; + err_code = NRF_ERROR_NO_MEM; } } else @@ -221,7 +323,7 @@ ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin, pin_in_use_set(pin); } - if (result == NRF_SUCCESS) + if (err_code == NRF_SUCCESS) { if (p_config->init_state == NRF_GPIOTE_INITIAL_VALUE_HIGH) { @@ -231,14 +333,17 @@ ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin, { nrf_gpio_pin_clear(pin); } - + nrf_gpio_cfg_output(pin); } } - return result; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, + (uint32_t)ERR_TO_STR(err_code)); + return err_code; } + void nrf_drv_gpiote_out_uninit(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); @@ -254,6 +359,7 @@ void nrf_drv_gpiote_out_uninit(nrf_drv_gpiote_pin_t pin) nrf_gpio_cfg_default(pin); } + void nrf_drv_gpiote_out_set(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); @@ -263,6 +369,7 @@ void nrf_drv_gpiote_out_set(nrf_drv_gpiote_pin_t pin) nrf_gpio_pin_set(pin); } + void nrf_drv_gpiote_out_clear(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); @@ -272,6 +379,7 @@ void nrf_drv_gpiote_out_clear(nrf_drv_gpiote_pin_t pin) nrf_gpio_pin_clear(pin); } + void nrf_drv_gpiote_out_toggle(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); @@ -281,6 +389,7 @@ void nrf_drv_gpiote_out_toggle(nrf_drv_gpiote_pin_t pin) nrf_gpio_pin_toggle(pin); } + void nrf_drv_gpiote_out_task_enable(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); @@ -290,6 +399,7 @@ void nrf_drv_gpiote_out_task_enable(nrf_drv_gpiote_pin_t pin) nrf_gpiote_task_enable(m_cb.pin_assignments[pin]); } + void nrf_drv_gpiote_out_task_disable(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); @@ -299,45 +409,105 @@ void nrf_drv_gpiote_out_task_disable(nrf_drv_gpiote_pin_t pin) nrf_gpiote_task_disable(m_cb.pin_assignments[pin]); } + uint32_t nrf_drv_gpiote_out_task_addr_get(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); ASSERT(pin_in_use_by_te(pin)); - - nrf_gpiote_tasks_t task = TE_IDX_TO_TASK_ADDR(channel_port_get(pin)); + + nrf_gpiote_tasks_t task = TE_OUT_IDX_TO_TASK_ADDR(channel_port_get(pin)); return nrf_gpiote_task_addr_get(task); } + +#if defined(GPIOTE_FEATURE_SET_PRESENT) +uint32_t nrf_drv_gpiote_set_task_addr_get(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_tasks_t task = TE_SET_IDX_TO_TASK_ADDR(channel_port_get(pin)); + return nrf_gpiote_task_addr_get(task); +} + + +#endif // defined(GPIOTE_FEATURE_SET_PRESENT) + +#if defined(GPIOTE_FEATURE_CLR_PRESENT) +uint32_t nrf_drv_gpiote_clr_task_addr_get(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_tasks_t task = TE_CLR_IDX_TO_TASK_ADDR(channel_port_get(pin)); + return nrf_gpiote_task_addr_get(task); +} + + +#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) + void nrf_drv_gpiote_out_task_force(nrf_drv_gpiote_pin_t pin, uint8_t state) { ASSERT(pin < NUMBER_OF_PINS); ASSERT(pin_in_use(pin)); ASSERT(pin_in_use_by_te(pin)); - - nrf_gpiote_outinit_t init_val = state ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW; + + nrf_gpiote_outinit_t init_val = + state ? NRF_GPIOTE_INITIAL_VALUE_HIGH : NRF_GPIOTE_INITIAL_VALUE_LOW; nrf_gpiote_task_force(m_cb.pin_assignments[pin], init_val); } + void nrf_drv_gpiote_out_task_trigger(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); ASSERT(pin_in_use(pin)); ASSERT(pin_in_use_by_te(pin)); - nrf_gpiote_tasks_t task = TE_IDX_TO_TASK_ADDR(channel_port_get(pin));; + nrf_gpiote_tasks_t task = TE_OUT_IDX_TO_TASK_ADDR(channel_port_get(pin)); nrf_gpiote_task_set(task); } -ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin, + +#if defined(GPIOTE_FEATURE_SET_PRESENT) +void nrf_drv_gpiote_set_task_trigger(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_tasks_t task = TE_SET_IDX_TO_TASK_ADDR(channel_port_get(pin)); + nrf_gpiote_task_set(task); +} + + +#endif // defined(GPIOTE_FEATURE_SET_PRESENT) + +#if defined(GPIOTE_FEATURE_CLR_PRESENT) +void nrf_drv_gpiote_clr_task_trigger(nrf_drv_gpiote_pin_t pin) +{ + ASSERT(pin < NUMBER_OF_PINS); + ASSERT(pin_in_use(pin)); + ASSERT(pin_in_use_by_te(pin)); + + nrf_gpiote_tasks_t task = TE_CLR_IDX_TO_TASK_ADDR(channel_port_get(pin)); + nrf_gpiote_task_set(task); +} + + +#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) + +ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin, nrf_drv_gpiote_in_config_t const * p_config, - nrf_drv_gpiote_evt_handler_t evt_handler) + nrf_drv_gpiote_evt_handler_t evt_handler) { ASSERT(pin < NUMBER_OF_PINS); - ret_code_t result = NRF_SUCCESS; + ret_code_t err_code = NRF_SUCCESS; + /* Only one GPIOTE channel can be assigned to one physical pin. */ if (pin_in_use_by_gpiote(pin)) { - result = NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; } else { @@ -350,39 +520,46 @@ ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin, } else { - nrf_gpio_cfg_input(pin,p_config->pull); + nrf_gpio_cfg_input(pin, p_config->pull); } if (p_config->hi_accuracy) { - nrf_gpiote_event_configure(channel, pin,p_config->sense); + nrf_gpiote_event_configure(channel, pin, p_config->sense); } else { - m_cb.port_handlers_pins[channel-NUMBER_OF_GPIO_TE] |= (p_config->sense)<< SENSE_FIELD_POS; + m_cb.port_handlers_pins[channel - + GPIOTE_CH_NUM] |= (p_config->sense) << SENSE_FIELD_POS; } } else { - result = NRF_ERROR_NO_MEM; + err_code = NRF_ERROR_NO_MEM; } } - return result; + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, + (uint32_t)ERR_TO_STR(err_code)); + return err_code; } + void nrf_drv_gpiote_in_event_enable(nrf_drv_gpiote_pin_t pin, bool int_enable) { ASSERT(pin < NUMBER_OF_PINS); ASSERT(pin_in_use_by_gpiote(pin)); if (pin_in_use_by_port(pin)) { - uint8_t pin_and_sense = m_cb.port_handlers_pins[channel_port_get(pin)-NUMBER_OF_GPIO_TE]; - nrf_gpiote_polarity_t polarity = (nrf_gpiote_polarity_t)(pin_and_sense >> SENSE_FIELD_POS); + uint8_t pin_and_sense = + m_cb.port_handlers_pins[channel_port_get(pin) - GPIOTE_CH_NUM]; + nrf_gpiote_polarity_t polarity = + (nrf_gpiote_polarity_t)(pin_and_sense >> SENSE_FIELD_POS); nrf_gpio_pin_sense_t sense; if (polarity == NRF_GPIOTE_POLARITY_TOGGLE) { /* read current pin state and set for next sense to oposit */ - sense = (nrf_gpio_pins_read() & (1 << pin)) ? + sense = (nrf_gpio_pin_read(pin)) ? NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH; } else @@ -390,13 +567,13 @@ void nrf_drv_gpiote_in_event_enable(nrf_drv_gpiote_pin_t pin, bool int_enable) sense = (polarity == NRF_GPIOTE_POLARITY_LOTOHI) ? NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW; } - nrf_gpio_cfg_sense_set(pin,sense); + nrf_gpio_cfg_sense_set(pin, sense); } - else if(pin_in_use_by_te(pin)) + else if (pin_in_use_by_te(pin)) { - int32_t channel = (int32_t)channel_port_get(pin); - nrf_gpiote_events_t event = TE_IDX_TO_EVENT_ADDR(channel); - + int32_t channel = (int32_t)channel_port_get(pin); + nrf_gpiote_events_t event = TE_IDX_TO_EVENT_ADDR(channel); + nrf_gpiote_event_enable(channel); nrf_gpiote_event_clear(event); @@ -412,15 +589,16 @@ void nrf_drv_gpiote_in_event_enable(nrf_drv_gpiote_pin_t pin, bool int_enable) } } + void nrf_drv_gpiote_in_event_disable(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); ASSERT(pin_in_use_by_gpiote(pin)); if (pin_in_use_by_port(pin)) { - nrf_gpio_cfg_sense_set(pin,NRF_GPIO_PIN_NOSENSE); + nrf_gpio_cfg_sense_set(pin, NRF_GPIO_PIN_NOSENSE); } - else if(pin_in_use_by_te(pin)) + else if (pin_in_use_by_te(pin)) { int32_t channel = (int32_t)channel_port_get(pin); nrf_gpiote_event_disable(channel); @@ -428,12 +606,13 @@ void nrf_drv_gpiote_in_event_disable(nrf_drv_gpiote_pin_t pin) } } + void nrf_drv_gpiote_in_uninit(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); ASSERT(pin_in_use_by_gpiote(pin)); nrf_drv_gpiote_in_event_disable(pin); - if(pin_in_use_by_te(pin)) + if (pin_in_use_by_te(pin)) { nrf_gpiote_te_default(channel_port_get(pin)); } @@ -442,32 +621,40 @@ void nrf_drv_gpiote_in_uninit(nrf_drv_gpiote_pin_t pin) pin_in_use_clear(pin); } + bool nrf_drv_gpiote_in_is_set(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); return nrf_gpio_pin_read(pin) ? true : false; } + uint32_t nrf_drv_gpiote_in_event_addr_get(nrf_drv_gpiote_pin_t pin) { ASSERT(pin < NUMBER_OF_PINS); - ASSERT(pin_in_use_by_te(pin)); - - nrf_gpiote_events_t event = TE_IDX_TO_EVENT_ADDR(channel_port_get(pin)); + ASSERT(pin_in_use_by_port(pin) || pin_in_use_by_te(pin)); + + nrf_gpiote_events_t event = NRF_GPIOTE_EVENTS_PORT; + + if (pin_in_use_by_te(pin)) + { + event = TE_IDX_TO_EVENT_ADDR(channel_port_get(pin)); + } return nrf_gpiote_event_addr_get(event); } + void GPIOTE_IRQHandler(void) { - uint32_t status = 0; - uint32_t input = 0; - + uint32_t status = 0; + uint32_t input[GPIO_COUNT] = {0}; /* collect status of all GPIOTE pin events. Processing is done once all are collected and cleared.*/ - uint32_t i; + uint32_t i; nrf_gpiote_events_t event = NRF_GPIOTE_EVENTS_IN_0; - uint32_t mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK; - for (i = 0; i < NUMBER_OF_GPIO_TE; i++) + uint32_t mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK; + + for (i = 0; i < GPIOTE_CH_NUM; i++) { if (nrf_gpiote_event_is_set(event) && nrf_gpiote_int_is_enabled(mask)) { @@ -486,21 +673,27 @@ void GPIOTE_IRQHandler(void) { nrf_gpiote_event_clear(NRF_GPIOTE_EVENTS_PORT); status |= (uint32_t)NRF_GPIOTE_INT_PORT_MASK; - input = nrf_gpio_pins_read(); + nrf_gpio_ports_read(0, GPIO_COUNT, input); } /* Process pin events. */ if (status & NRF_GPIOTE_INT_IN_MASK) { mask = (uint32_t)NRF_GPIOTE_INT_IN0_MASK; - for (i = 0; i < NUMBER_OF_GPIO_TE; i++) + + for (i = 0; i < GPIOTE_CH_NUM; i++) { if (mask & status) { nrf_drv_gpiote_pin_t pin = nrf_gpiote_event_pin_get(i); - nrf_gpiote_polarity_t polarity = nrf_gpiote_event_polarity_get(i); - nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(i); - handler(pin,polarity); + NRF_LOG_DEBUG("Event in number: %d.\r\n", i); + nrf_gpiote_polarity_t polarity = nrf_gpiote_event_polarity_get(i); + nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(i); + NRF_LOG_DEBUG("Pin: %d, polarity: %d.\r\n", pin, polarity); + if (handler) + { + handler(pin, polarity); + } } mask <<= 1; } @@ -509,33 +702,108 @@ void GPIOTE_IRQHandler(void) if (status & (uint32_t)NRF_GPIOTE_INT_PORT_MASK) { /* Process port event. */ - for (i = 0; i < GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS; i++) + uint32_t port_idx; + uint8_t repeat = 0; + uint32_t toggle_mask[GPIO_COUNT] = {0}; + uint32_t pins_to_check[GPIO_COUNT]; + + // Faster way of doing memset because in interrupt context. + for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++) + { + pins_to_check[port_idx] = 0xFFFFFFFF; + } + + do { - if (m_cb.port_handlers_pins[i] != PIN_NOT_USED) + repeat = 0; + + for (i = 0; i < GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS; i++) { - uint8_t pin_and_sense = m_cb.port_handlers_pins[i]; - nrf_drv_gpiote_pin_t pin = (pin_and_sense & ~SENSE_FIELD_MASK); - nrf_drv_gpiote_evt_handler_t handler = channel_handler_get(channel_port_get(pin)); - if (handler) + uint8_t pin_and_sense = m_cb.port_handlers_pins[i]; + nrf_drv_gpiote_pin_t pin = (pin_and_sense & ~SENSE_FIELD_MASK); + + if ((m_cb.port_handlers_pins[i] != PIN_NOT_USED) + && nrf_bitmask_bit_is_set(pin, pins_to_check)) { nrf_gpiote_polarity_t polarity = - (nrf_gpiote_polarity_t)((pin_and_sense & SENSE_FIELD_MASK) >> SENSE_FIELD_POS); - mask = 1 << pin; - nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin); - if (((mask & input) && (sense==NRF_GPIO_PIN_SENSE_HIGH)) || - (!(mask & input) && (sense==NRF_GPIO_PIN_SENSE_LOW)) ) + (nrf_gpiote_polarity_t)((pin_and_sense & + SENSE_FIELD_MASK) >> SENSE_FIELD_POS); + nrf_drv_gpiote_evt_handler_t handler = + channel_handler_get(channel_port_get(pin)); + if (handler || (polarity == NRF_GPIOTE_POLARITY_TOGGLE)) { if (polarity == NRF_GPIOTE_POLARITY_TOGGLE) { - nrf_gpio_pin_sense_t next_sense = (sense == NRF_GPIO_PIN_SENSE_HIGH) ? - NRF_GPIO_PIN_SENSE_LOW : NRF_GPIO_PIN_SENSE_HIGH; - nrf_gpio_cfg_sense_set(pin, next_sense); + nrf_bitmask_bit_set(pin, toggle_mask); + } + nrf_gpio_pin_sense_t sense = nrf_gpio_pin_sense_get(pin); + uint32_t pin_state = nrf_bitmask_bit_is_set(pin, input); + if ((pin_state && (sense == NRF_GPIO_PIN_SENSE_HIGH)) || + (!pin_state && (sense == NRF_GPIO_PIN_SENSE_LOW)) ) + { + NRF_LOG_DEBUG("PORT event for pin: %d, polarity: %d.\r\n", pin, + polarity); + if (polarity == NRF_GPIOTE_POLARITY_TOGGLE) + { + nrf_gpio_pin_sense_t next_sense = + (sense == NRF_GPIO_PIN_SENSE_HIGH) ? + NRF_GPIO_PIN_SENSE_LOW : + NRF_GPIO_PIN_SENSE_HIGH; + nrf_gpio_cfg_sense_set(pin, next_sense); + ++repeat; + + } + if (handler) + { + handler(pin, polarity); + } } - handler(pin, polarity); + } + } + } + + if (repeat) + { + // When one of the pins in low-accuracy and toggle mode becomes active, + // it's sense mode is inverted to clear the internal SENSE signal. + // State of any other enabled low-accuracy input in toggle mode must be checked + // explicitly, because it does not trigger the interrput when SENSE signal is active. + // For more information about SENSE functionality, refer to Product Specification. + + uint32_t new_input[GPIO_COUNT]; + bool input_unchanged = true; + nrf_gpio_ports_read(0, GPIO_COUNT, new_input); + + // Faster way of doing memcmp because in interrupt context. + for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++) + { + if (new_input[port_idx] != input[port_idx]) + { + input_unchanged = false; + break; + } + } + + if (input_unchanged) + { + // No change. + repeat = 0; + } + else + { + // Faster way of doing memcpy because in interrupt context. + for (port_idx = 0; port_idx < GPIO_COUNT; port_idx++) + { + input[port_idx] = new_input[port_idx]; + pins_to_check[port_idx] = toggle_mask[port_idx]; } } } } + while (repeat); } } -//lint -restore + + +/*lint -restore*/ +#endif // NRF_MODULE_ENABLED(GPIOTE) diff --git a/components/drivers_nrf/gpiote/nrf_drv_gpiote.h b/components/drivers_nrf/gpiote/nrf_drv_gpiote.h index 279a3ac..409652c 100644 --- a/components/drivers_nrf/gpiote/nrf_drv_gpiote.h +++ b/components/drivers_nrf/gpiote/nrf_drv_gpiote.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_GPIOTE__ @@ -25,10 +53,14 @@ #include "nrf_gpiote.h" #include "nrf_gpio.h" -#include "nrf_drv_config.h" #include "sdk_errors.h" #include #include +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif /**@brief Input pin configuration. */ typedef struct @@ -124,7 +156,7 @@ typedef void (*nrf_drv_gpiote_evt_handler_t)(nrf_drv_gpiote_pin_t pin, nrf_gpiot /** * @brief Function for initializing the GPIOTE module. * - * @details Only static configuration is supported to prevent the shared + * @details Only static configuration is supported to prevent the shared * resource being customized by the initiator. * * @retval NRF_SUCCESS If initialization was successful. @@ -150,8 +182,8 @@ void nrf_drv_gpiote_uninit(void); /** * @brief Function for initializing a GPIOTE output pin. - * @details The output pin can be controlled by the CPU or by PPI. The initial - * configuration specifies which mode is used. If PPI mode is used, the driver + * @details The output pin can be controlled by the CPU or by PPI. The initial + * configuration specifies which mode is used. If PPI mode is used, the driver * attempts to allocate one of the available GPIOTE channels. If no channel is * available, an error is returned. * @@ -169,72 +201,100 @@ ret_code_t nrf_drv_gpiote_out_init(nrf_drv_gpiote_pin_t pin, * @brief Function for uninitializing a GPIOTE output pin. * @details The driver frees the GPIOTE channel if the output pin was using one. * - * @param[in] pin Pin. + * @param[in] pin Pin. */ void nrf_drv_gpiote_out_uninit(nrf_drv_gpiote_pin_t pin); /** * @brief Function for setting a GPIOTE output pin. * - * @param[in] pin Pin. + * @param[in] pin Pin. */ void nrf_drv_gpiote_out_set(nrf_drv_gpiote_pin_t pin); /** * @brief Function for clearing a GPIOTE output pin. * - * @param[in] pin Pin. + * @param[in] pin Pin. */ void nrf_drv_gpiote_out_clear(nrf_drv_gpiote_pin_t pin); /** * @brief Function for toggling a GPIOTE output pin. * - * @param[in] pin Pin. + * @param[in] pin Pin. */ void nrf_drv_gpiote_out_toggle(nrf_drv_gpiote_pin_t pin); /** * @brief Function for enabling a GPIOTE output pin task. * - * @param[in] pin Pin. + * @param[in] pin Pin. */ void nrf_drv_gpiote_out_task_enable(nrf_drv_gpiote_pin_t pin); /** * @brief Function for disabling a GPIOTE output pin task. * - * @param[in] pin Pin. + * @param[in] pin Pin. */ void nrf_drv_gpiote_out_task_disable(nrf_drv_gpiote_pin_t pin); /** * @brief Function for getting the address of a configurable GPIOTE task. * - * @param[in] pin Pin. + * @param[in] pin Pin. + * + * @return Address of OUT task. */ uint32_t nrf_drv_gpiote_out_task_addr_get(nrf_drv_gpiote_pin_t pin); +#if defined(GPIOTE_FEATURE_SET_PRESENT) +/** + * @brief Function for getting the address of a configurable GPIOTE task. + * + * @param[in] pin Pin. + * + * @return Address of SET task. + */ +uint32_t nrf_drv_gpiote_set_task_addr_get(nrf_drv_gpiote_pin_t pin); +#endif // defined(GPIOTE_FEATURE_SET_PRESENT) + +#if defined(GPIOTE_FEATURE_CLR_PRESENT) +/** + * @brief Function for getting the address of a configurable GPIOTE task. + * + * @param[in] pin Pin. + * + * @return Address of CLR task. + */ +uint32_t nrf_drv_gpiote_clr_task_addr_get(nrf_drv_gpiote_pin_t pin); +#endif // defined(GPIOTE_FEATURE_CLR_PRESENT) + /** * @brief Function for initializing a GPIOTE input pin. - * @details The input pin can act in two ways: + * @details The input pin can act in two ways: * - lower accuracy but low power (high frequency clock not needed) * - higher accuracy (high frequency clock required) * * The initial configuration specifies which mode is used. - * If high-accuracy mode is used, the driver attempts to allocate one - * of the available GPIOTE channels. If no channel is + * If high-accuracy mode is used, the driver attempts to allocate one + * of the available GPIOTE channels. If no channel is * available, an error is returned. + * In low accuracy mode SENSE feature is used. In this case only one active pin + * can be detected at a time. It can be worked around by setting all of the used + * low accuracy pins to toggle mode. + * For more information about SENSE functionality, refer to Product Specification. * - * @param[in] pin Pin. - * @param[in] p_config Initial configuration. - * @param[in] evt_handler User function to be called when the configured transition occurs. + * @param[in] pin Pin. + * @param[in] p_config Initial configuration. + * @param[in] evt_handler User function to be called when the configured transition occurs. * * @retval NRF_SUCCESS If initialization was successful. * @retval NRF_ERROR_INVALID_STATE If the driver is not initialized or the pin is already used. * @retval NRF_ERROR_NO_MEM If no GPIOTE channel is available. */ -ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin, +ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin, nrf_drv_gpiote_in_config_t const * p_config, nrf_drv_gpiote_evt_handler_t evt_handler); @@ -242,19 +302,19 @@ ret_code_t nrf_drv_gpiote_in_init(nrf_drv_gpiote_pin_t pin, * @brief Function for uninitializing a GPIOTE input pin. * @details The driver frees the GPIOTE channel if the input pin was using one. * - * @param[in] pin Pin. + * @param[in] pin Pin. */ void nrf_drv_gpiote_in_uninit(nrf_drv_gpiote_pin_t pin); /** * @brief Function for enabling sensing of a GPIOTE input pin. * - * @details If the input pin is configured as high-accuracy pin, the function + * @details If the input pin is configured as high-accuracy pin, the function * enables an IN_EVENT. Otherwise, the function enables the GPIO sense mechanism. - * Note that a PORT event is shared between multiple pins, therefore the + * Note that a PORT event is shared between multiple pins, therefore the * interrupt is always enabled. * - * @param[in] pin Pin. + * @param[in] pin Pin. * @param[in] int_enable True to enable the interrupt. Always valid for a high-accuracy pin. */ void nrf_drv_gpiote_in_event_enable(nrf_drv_gpiote_pin_t pin, bool int_enable); @@ -262,14 +322,14 @@ void nrf_drv_gpiote_in_event_enable(nrf_drv_gpiote_pin_t pin, bool int_enable); /** * @brief Function for disabling a GPIOTE input pin. * - * @param[in] pin Pin. + * @param[in] pin Pin. */ void nrf_drv_gpiote_in_event_disable(nrf_drv_gpiote_pin_t pin); /** * @brief Function for checking if a GPIOTE input pin is set. * - * @param[in] pin Pin. + * @param[in] pin Pin. * @retval true If the input pin is set. * @retval false If the input pin is not set. */ @@ -279,27 +339,48 @@ bool nrf_drv_gpiote_in_is_set(nrf_drv_gpiote_pin_t pin); * @brief Function for getting the address of a GPIOTE input pin event. * @details If the pin is configured to use low-accuracy mode, the address of the PORT event is returned. * - * @param[in] pin Pin. + * @param[in] pin Pin. */ uint32_t nrf_drv_gpiote_in_event_addr_get(nrf_drv_gpiote_pin_t pin); /** * @brief Function for forcing a specific state on the pin configured as task. * - * @param[in] pin Pin. + * @param[in] pin Pin. * @param[in] state Pin state. */ void nrf_drv_gpiote_out_task_force(nrf_drv_gpiote_pin_t pin, uint8_t state); /** - * @brief Function for triggering the task manually. + * @brief Function for triggering the task OUT manually. * - * @param[in] pin Pin. + * @param[in] pin Pin. */ void nrf_drv_gpiote_out_task_trigger(nrf_drv_gpiote_pin_t pin); +#ifdef NRF52_SERIES +/** + * @brief Function for triggering the task SET manually. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_set_task_trigger(nrf_drv_gpiote_pin_t pin); + +/** + * @brief Function for triggering the task CLR manually. + * + * @param[in] pin Pin. + */ +void nrf_drv_gpiote_clr_task_trigger(nrf_drv_gpiote_pin_t pin); +#endif + /** *@} **/ + +#ifdef __cplusplus +} +#endif + #endif //NRF_DRV_GPIOTE__ diff --git a/components/drivers_nrf/hal/nrf_adc.c b/components/drivers_nrf/hal/nrf_adc.c index 1fc591e..0659770 100644 --- a/components/drivers_nrf/hal/nrf_adc.c +++ b/components/drivers_nrf/hal/nrf_adc.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -17,15 +45,15 @@ #include "nrf_adc.h" -#ifndef NRF52 +#ifdef ADC_PRESENT /** * @brief Function for configuring ADC. * - * This function power on ADC and configure it. ADC is in DISABLE state after configuration, + * This function powers on ADC and configures it. ADC is in DISABLE state after configuration, * so it should be enabled before using it. * - * @param[in] config is requested configuration + * @param[in] config Requested configuration. */ void nrf_adc_configure(nrf_adc_config_t * config) { @@ -51,14 +79,14 @@ void nrf_adc_configure(nrf_adc_config_t * config) /** * @brief Blocking function for executing single ADC conversion. * - * This function selects desired input, starts single conversion, - * waits for its finish and returns result. - * ADC is left in STOP state, given input is selected. + * This function selects the desired input, starts a single conversion, + * waits for it to finish, and returns the result. + * ADC is left in STOP state, the given input is selected. * This function does not check if ADC is initialized and powered. * - * @param[in] input is requested input to be selected + * @param[in] input Requested input to be selected. * - * @return conversion result + * @return Conversion result */ int32_t nrf_adc_convert_single(nrf_adc_config_input_t input) { diff --git a/components/drivers_nrf/hal/nrf_adc.h b/components/drivers_nrf/hal/nrf_adc.h index e360c43..6156982 100644 --- a/components/drivers_nrf/hal/nrf_adc.h +++ b/components/drivers_nrf/hal/nrf_adc.h @@ -1,40 +1,77 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - /** - * @file - * @brief ADC HAL API. + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_ADC_H_ #define NRF_ADC_H_ /** - * @defgroup nrf_adc ADC HAL + * @defgroup nrf_adc_hal ADC HAL * @{ - * @ingroup nrf_drivers - * @brief Hardware access layer for managing the analog-to-digital converter. + * @ingroup nrf_adc + * @brief @tagAPI51 Hardware access layer for managing the analog-to-digital converter (ADC). */ #include #include +#include "nrf_peripherals.h" #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(ADC_PRESENT) || defined(__SDK_DOXYGEN__) /** - * @enum nrf_adc_config_resolution_t + * @enum nrf_adc_config_resolution_t * @brief Resolution of the analog-to-digital converter. */ -#ifndef NRF52 + +/** + * @brief ADC interrupts. + */ +typedef enum +{ + NRF_ADC_INT_END_MASK = ADC_INTENSET_END_Msk, /**< ADC interrupt on END event. */ +} nrf_adc_int_mask_t; + typedef enum { NRF_ADC_CONFIG_RES_8BIT = ADC_CONFIG_RES_8bit, /**< 8 bit resolution. */ @@ -128,7 +165,7 @@ typedef struct /** * @brief Function for configuring ADC. * - * This function powers on the analog-to-digital converter and configures it. + * This function powers on the analog-to-digital converter and configures it. * After the configuration, the ADC is in DISABLE state and must be * enabled before using it. * @@ -201,35 +238,6 @@ __STATIC_INLINE bool nrf_adc_is_busy(void) return ( (NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) == ADC_BUSY_BUSY_Msk); } - -/** - * @brief Function for enabling interrupts from the ADC. - * - * @param[in] interrupts Mask of interrupts to be enabled. - * - * @sa nrf_adc_int_disable() - * @sa nrf_adc_int_get() - */ -__STATIC_INLINE void nrf_adc_int_enable(uint32_t interrupts) -{ - NRF_ADC->INTENSET = interrupts; -} - - -/** - * @brief Function for disabling interrupts from the ADC. - * - * @param[in] interrupts Mask of interrupts to be disabled. - * - * @sa nrf_adc_int_enable() - * @sa nrf_adc_int_get() - */ -__STATIC_INLINE void nrf_adc_int_disable(uint32_t interrupts) -{ - NRF_ADC->INTENCLR = interrupts; -} - - /** * @brief Function for getting the ADC's enabled interrupts. * @@ -259,7 +267,7 @@ __STATIC_INLINE void nrf_adc_start(void) /** - * @brief Function for stopping conversion. + * @brief Function for stopping conversion. * * If the analog-to-digital converter is in inactive state, power consumption is reduced. * @@ -284,7 +292,7 @@ __STATIC_INLINE bool nrf_adc_conversion_finished(void) } /** - * @brief Function for cleaning conversion end event. + * @brief Function for clearing the conversion END event. */ __STATIC_INLINE void nrf_adc_conversion_event_clean(void) { @@ -298,11 +306,7 @@ __STATIC_INLINE void nrf_adc_conversion_event_clean(void) * * @return Address of the specified ADC task. */ -__STATIC_INLINE uint32_t * nrf_adc_task_address_get(nrf_adc_task_t adc_task) -{ - return (uint32_t *)((uint8_t *)NRF_ADC + adc_task); -} - +__STATIC_INLINE uint32_t nrf_adc_task_address_get(nrf_adc_task_t adc_task); /** * @brief Function for getting the address of a specific ADC event register. @@ -311,14 +315,144 @@ __STATIC_INLINE uint32_t * nrf_adc_task_address_get(nrf_adc_task_t adc_task) * * @return Address of the specified ADC event. */ -__STATIC_INLINE uint32_t * nrf_adc_event_address_get(nrf_adc_event_t adc_event) +__STATIC_INLINE uint32_t nrf_adc_event_address_get(nrf_adc_event_t adc_event); + +/** + * @brief Function for setting the CONFIG register in ADC. + * + * @param[in] configuration Value to be written to the CONFIG register. + */ +__STATIC_INLINE void nrf_adc_config_set(uint32_t configuration); + +/** + * @brief Function for clearing an ADC event. + * + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_adc_event_clear(nrf_adc_event_t event); + +/** + * @brief Function for checking state of an ADC event. + * + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_adc_event_check(nrf_adc_event_t event); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_adc_int_enable(uint32_t int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_adc_int_disable(uint32_t int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] int_mask Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_adc_int_enable_check(nrf_adc_int_mask_t int_mask); + +/** + * @brief Function for activating a specific ADC task. + * + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_adc_task_trigger(nrf_adc_task_t task); + +/** + * @brief Function for enabling ADC. + * + */ +__STATIC_INLINE void nrf_adc_enable(void); + +/** + * @brief Function for disabling ADC. + * + */ +__STATIC_INLINE void nrf_adc_disable(void); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t nrf_adc_task_address_get(nrf_adc_task_t adc_task) +{ + return (uint32_t)((uint8_t *)NRF_ADC + adc_task); +} + +__STATIC_INLINE uint32_t nrf_adc_event_address_get(nrf_adc_event_t adc_event) +{ + return (uint32_t)((uint8_t *)NRF_ADC + adc_event); +} + +__STATIC_INLINE void nrf_adc_config_set(uint32_t configuration) { - return (uint32_t *)((uint8_t *)NRF_ADC + adc_event); + NRF_ADC->CONFIG = configuration; } -#endif /* NRF52 */ +__STATIC_INLINE void nrf_adc_event_clear(nrf_adc_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_adc_event_check(nrf_adc_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)event); +} + +__STATIC_INLINE void nrf_adc_int_enable(uint32_t int_mask) +{ + NRF_ADC->INTENSET = int_mask; +} + +__STATIC_INLINE void nrf_adc_int_disable(uint32_t int_mask) +{ + NRF_ADC->INTENCLR = int_mask; +} + +__STATIC_INLINE bool nrf_adc_int_enable_check(nrf_adc_int_mask_t int_mask) +{ + return (bool)(NRF_ADC->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_adc_task_trigger(nrf_adc_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_ADC + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE void nrf_adc_enable(void) +{ + NRF_ADC->ENABLE = 1; +} + +__STATIC_INLINE void nrf_adc_disable(void) +{ + NRF_ADC->ENABLE = 0; +} +#endif +#endif /* ADC_PRESENT */ /** *@} **/ + +#ifdef __cplusplus +} +#endif + #endif /* NRF_ADC_H_ */ diff --git a/components/drivers_nrf/hal/nrf_clock.h b/components/drivers_nrf/hal/nrf_clock.h index 0cbdf6a..adccea2 100644 --- a/components/drivers_nrf/hal/nrf_clock.h +++ b/components/drivers_nrf/hal/nrf_clock.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_CLOCK_H__ @@ -15,9 +43,13 @@ #include #include - + #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @defgroup nrf_clock_hal Clock HAL * @{ @@ -34,19 +66,19 @@ */ typedef enum { - NRF_CLOCK_LF_SRC_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */ - NRF_CLOCK_LF_SRC_Xtal = CLOCK_LFCLKSRC_SRC_Xtal, /**< External 32 kHz crystal. */ - NRF_CLOCK_LF_SRC_Synth = CLOCK_LFCLKSRC_SRC_Synth /**< Internal 32 kHz synthesizer from HFCLK system clock. */ -} nrf_clock_lf_src_t; + NRF_CLOCK_LFCLK_RC = CLOCK_LFCLKSRC_SRC_RC, /**< Internal 32 kHz RC oscillator. */ + NRF_CLOCK_LFCLK_Xtal = CLOCK_LFCLKSRC_SRC_Xtal, /**< External 32 kHz crystal. */ + NRF_CLOCK_LFCLK_Synth = CLOCK_LFCLKSRC_SRC_Synth /**< Internal 32 kHz synthesizer from HFCLK system clock. */ +} nrf_clock_lfclk_t; /** * @brief High-frequency clock sources. */ typedef enum { - NRF_CLOCK_HF_SRC_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_RC, /**< Internal 16 MHz RC oscillator. */ - NRF_CLOCK_HF_SRC_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_Xtal /**< External 16 MHz/32 MHz crystal oscillator. */ -} nrf_clock_hf_src_t; + NRF_CLOCK_HFCLK_LOW_ACCURACY = CLOCK_HFCLKSTAT_SRC_RC, /**< Internal 16 MHz RC oscillator. */ + NRF_CLOCK_HFCLK_HIGH_ACCURACY = CLOCK_HFCLKSTAT_SRC_Xtal /**< External 16 MHz/32 MHz crystal oscillator. */ +} nrf_clock_hfclk_t; /** * @brief Trigger status of task LFCLKSTART/HFCLKSTART. @@ -58,20 +90,6 @@ typedef enum NRF_CLOCK_START_TASK_TRIGGERED = CLOCK_LFCLKRUN_STATUS_Triggered /**< Task LFCLKSTART/HFCLKSTART has been triggered. */ } nrf_clock_start_task_status_t; -/** - * @brief Crystal frequency selection. - */ -typedef enum -{ -#ifdef NRF51 - NRF_CLOCK_XTALFREQ_Default = CLOCK_XTALFREQ_XTALFREQ_16MHz, /**< Default. 32MHz. */ - NRF_CLOCK_XTALFREQ_16MHz = CLOCK_XTALFREQ_XTALFREQ_16MHz, /**< 16 MHz crystal. */ - NRF_CLOCK_XTALFREQ_32MHz = CLOCK_XTALFREQ_XTALFREQ_32MHz /**< 32 MHz crystal. */ -#elif defined NRF52 - NRF_CLOCK_XTALFREQ_Default, /**< Default. 64MHz. */ -#endif -} nrf_clock_xtalfreq_t; - /** * @brief Interrupts. */ @@ -116,83 +134,58 @@ typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ * * @param[in] int_mask Interrupt. */ -__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask) -{ - NRF_CLOCK->INTENSET = int_mask; -} +__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask); /** * @brief Function for disabling a specific interrupt. * * @param[in] int_mask Interrupt. */ -__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask) -{ - NRF_CLOCK->INTENCLR = int_mask; -} +__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask); /** * @brief Function for retrieving the state of a specific interrupt. * * @param[in] int_mask Interrupt. * - * @retval true Interrupt is enabled. - * @retval false Interrupt is not enabled. + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. */ -__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask) -{ - return (bool)(NRF_CLOCK->INTENCLR & int_mask); -} +__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask); /** - * @brief Function for retrieving the address of a specific task. + * @brief Function for retrieving the address of a specific task. * @details This function can be used by the PPI module. * * @param[in] task Task. * - * @retval address of requested task register + * @return Address of the requested task register. */ -__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task) -{ - return ((uint32_t )NRF_CLOCK + task); -} +__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task); /** * @brief Function for setting a specific task. * * @param[in] task Task. */ -__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task) -{ - *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + task)) = NRF_CLOCK_TASK_TRIGGER; -} +__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task); /** - * @brief Function for retrieving the address of a specific event. + * @brief Function for retrieving the address of a specific event. * @details This function can be used by the PPI module. * * @param[in] event Event. * - * @retval address of requested event register + * @return Address of the requested event register. */ -__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event) -{ - return ((uint32_t)NRF_CLOCK + event); -} +__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event); /** * @brief Function for clearing a specific event. * * @param[in] event Event. */ -__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event) -{ - *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)) = NRF_CLOCK_EVENT_CLEAR; -#if __CORTEX_M == 0x04 - volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)); - (void)dummy; -#endif -} +__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event); /** * @brief Function for retrieving the state of a specific event. @@ -202,10 +195,7 @@ __STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event) * @retval true If the event is set. * @retval false If the event is not set. */ -__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event) -{ - return (bool)*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)); -} +__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event); /** * @brief Function for changing the low-frequency clock source. @@ -214,50 +204,34 @@ __STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event) * @param[in] source New low-frequency clock source. * */ -__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lf_src_t source) -{ - NRF_CLOCK->LFCLKSRC = - (uint32_t)((source << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); -} +__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source); /** * @brief Function for retrieving the selected source for the low-frequency clock. * - * @retval NRF_CLOCK_LF_SRC_RC If the internal 32 kHz RC oscillator is the selected source for the low-frequency clock. - * @retval NRF_CLOCK_LF_SRC_Xtal If an external 32 kHz crystal oscillator is the selected source for the low-frequency clock. - * @retval NRF_CLOCK_LF_SRC_Synth If the internal 32 kHz synthesizer from the HFCLK is the selected source for the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the selected source for the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the selected source for the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the selected source for the low-frequency clock. */ -__STATIC_INLINE nrf_clock_lf_src_t nrf_clock_lf_src_get(void) -{ - return (nrf_clock_lf_src_t)((NRF_CLOCK->LFCLKSRC & - CLOCK_LFCLKSRC_SRC_Msk) >> CLOCK_LFCLKSRC_SRC_Pos); -} +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void); /** * @brief Function for retrieving the active source of the low-frequency clock. * - * @retval NRF_CLOCK_LF_SRC_RC If the internal 32 kHz RC oscillator is the active source of the low-frequency clock. - * @retval NRF_CLOCK_LF_SRC_Xtal If an external 32 kHz crystal oscillator is the active source of the low-frequency clock. - * @retval NRF_CLOCK_LF_SRC_Synth If the internal 32 kHz synthesizer from the HFCLK is the active source of the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is the active source of the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is the active source of the low-frequency clock. + * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is the active source of the low-frequency clock. */ -__STATIC_INLINE nrf_clock_lf_src_t nrf_clock_lf_actv_src_get(void) -{ - return (nrf_clock_lf_src_t)((NRF_CLOCK->LFCLKSTAT & - CLOCK_LFCLKSTAT_SRC_Msk) >> CLOCK_LFCLKSTAT_SRC_Pos); -} +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void); /** * @brief Function for retrieving the clock source for the LFCLK clock when the task LKCLKSTART is triggered. * - * @retval NRF_CLOCK_LF_SRC_RC If the internal 32 kHz RC oscillator is running and generating the LFCLK clock. - * @retval NRF_CLOCK_LF_SRC_Xtal If an external 32 kHz crystal oscillator is running and generating the LFCLK clock. - * @retval NRF_CLOCK_LF_SRC_Synth If the internal 32 kHz synthesizer from the HFCLK is running and generating the LFCLK clock. + * @retval NRF_CLOCK_LFCLK_RC If the internal 32 kHz RC oscillator is running and generating the LFCLK clock. + * @retval NRF_CLOCK_LFCLK_Xtal If an external 32 kHz crystal oscillator is running and generating the LFCLK clock. + * @retval NRF_CLOCK_LFCLK_Synth If the internal 32 kHz synthesizer from the HFCLK is running and generating the LFCLK clock. */ -__STATIC_INLINE nrf_clock_lf_src_t nrf_clock_lf_srccopy_get(void) -{ - return (nrf_clock_lf_src_t)((NRF_CLOCK->LFCLKSRCCOPY & - CLOCK_LFCLKSRCCOPY_SRC_Msk) >> CLOCK_LFCLKSRCCOPY_SRC_Pos); -} +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void); /** * @brief Function for retrieving the state of the LFCLK clock. @@ -265,11 +239,7 @@ __STATIC_INLINE nrf_clock_lf_src_t nrf_clock_lf_srccopy_get(void) * @retval false If the LFCLK clock is not running. * @retval true If the LFCLK clock is running. */ -__STATIC_INLINE bool nrf_clock_lf_is_running(void) -{ - return ((NRF_CLOCK->LFCLKSTAT & - CLOCK_LFCLKSTAT_STATE_Msk) >> CLOCK_LFCLKSTAT_STATE_Pos); -} +__STATIC_INLINE bool nrf_clock_lf_is_running(void); /** * @brief Function for retrieving the trigger status of the task LFCLKSTART. @@ -277,36 +247,25 @@ __STATIC_INLINE bool nrf_clock_lf_is_running(void) * @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task LFCLKSTART has not been triggered. * @retval NRF_CLOCK_START_TASK_TRIGGERED If the task LFCLKSTART has been triggered. */ -__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void) -{ - return (nrf_clock_start_task_status_t)((NRF_CLOCK->LFCLKRUN & - CLOCK_LFCLKRUN_STATUS_Msk) >> - CLOCK_LFCLKRUN_STATUS_Pos); -} +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void); /** * @brief Function for retrieving the active source of the high-frequency clock. * - * @retval NRF_CLOCK_HF_SRC_RC If the internal 16 MHz RC oscillator is the active source of the high-frequency clock. - * @retval NRF_CLOCK_HF_SRC_Xtal If an external 16 MHz/32 MHz crystal oscillator is the active source of the high-frequency clock. + * @retval NRF_CLOCK_HFCLK_LOW_ACCURACY If the internal 16 MHz RC oscillator is the active source of the high-frequency clock. + * @retval NRF_CLOCK_HFCLK_HIGH_ACCURACY If an external 16 MHz/32 MHz crystal oscillator is the active source of the high-frequency clock. */ -__STATIC_INLINE nrf_clock_hf_src_t nrf_clock_hf_src_get(void) -{ - return (nrf_clock_hf_src_t)((NRF_CLOCK->HFCLKSTAT & - CLOCK_HFCLKSTAT_SRC_Msk) >> CLOCK_HFCLKSTAT_SRC_Pos); -} +__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void); /** * @brief Function for retrieving the state of the HFCLK clock. * + * @param[in] clk_src Clock source to be checked. + * * @retval false If the HFCLK clock is not running. * @retval true If the HFCLK clock is running. */ -__STATIC_INLINE bool nrf_clock_hf_is_running(void) -{ - return ((NRF_CLOCK->HFCLKSTAT & - CLOCK_HFCLKSTAT_STATE_Msk) >> CLOCK_HFCLKSTAT_STATE_Pos); -} +__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src); /** * @brief Function for retrieving the trigger status of the task HFCLKSTART. @@ -314,54 +273,130 @@ __STATIC_INLINE bool nrf_clock_hf_is_running(void) * @retval NRF_CLOCK_START_TASK_NOT_TRIGGERED If the task HFCLKSTART has not been triggered. * @retval NRF_CLOCK_START_TASK_TRIGGERED If the task HFCLKSTART has been triggered. */ -__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void) -{ - return (nrf_clock_start_task_status_t)((NRF_CLOCK->HFCLKRUN & - CLOCK_HFCLKRUN_STATUS_Msk) >> - CLOCK_HFCLKRUN_STATUS_Pos); -} +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void); /** - * @brief Function for retrieving the frequency selection of the external crystal. + * @brief Function for changing the calibration timer interval. * - * @retval NRF_CLOCK_XTALFREQ_16MHz If a 16 MHz crystal is used as source for the HFCLK oscillator. - * @retval NRF_CLOCK_XTALFREQ_32MHz If a 32 MHz crystal is used as source for the HFCLK oscillator. + * @param[in] interval New calibration timer interval in 0.25 s resolution (range: 0.25 seconds to 31.75 seconds). */ -__STATIC_INLINE nrf_clock_xtalfreq_t nrf_clock_xtalfreq_get(void) +__STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_clock_int_enable(uint32_t int_mask) { -#ifdef NRF51 - return (nrf_clock_xtalfreq_t)((NRF_CLOCK->XTALFREQ & - CLOCK_XTALFREQ_XTALFREQ_Msk) >> CLOCK_XTALFREQ_XTALFREQ_Pos); -#elif defined NRF52 - return NRF_CLOCK_XTALFREQ_Default; -#endif + NRF_CLOCK->INTENSET = int_mask; } -/** - * @brief Function for changing the frequency selection of the external crystal. - * - * @param[in] xtalfreq New frequency selection for the external crystal. - */ -__STATIC_INLINE void nrf_clock_xtalfreq_set(nrf_clock_xtalfreq_t xtalfreq) +__STATIC_INLINE void nrf_clock_int_disable(uint32_t int_mask) +{ + NRF_CLOCK->INTENCLR = int_mask; +} + +__STATIC_INLINE bool nrf_clock_int_enable_check(nrf_clock_int_mask_t int_mask) +{ + return (bool)(NRF_CLOCK->INTENCLR & int_mask); +} + +__STATIC_INLINE uint32_t nrf_clock_task_address_get(nrf_clock_task_t task) +{ + return ((uint32_t )NRF_CLOCK + task); +} + +__STATIC_INLINE void nrf_clock_task_trigger(nrf_clock_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + task)) = NRF_CLOCK_TASK_TRIGGER; +} + +__STATIC_INLINE uint32_t nrf_clock_event_address_get(nrf_clock_event_t event) +{ + return ((uint32_t)NRF_CLOCK + event); +} + +__STATIC_INLINE void nrf_clock_event_clear(nrf_clock_event_t event) { -#ifdef NRF51 - NRF_CLOCK->XTALFREQ = - (uint32_t)((xtalfreq << CLOCK_XTALFREQ_XTALFREQ_Pos) & CLOCK_XTALFREQ_XTALFREQ_Msk); -#elif defined NRF52 - return; + *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)) = NRF_CLOCK_EVENT_CLEAR; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)); + (void)dummy; #endif } -/** - * @brief Function for changing the calibration timer interval. - * - * @param[in] interval New calibration timer interval in 0.25 s resolution (range: 0.25 seconds to 31.75 seconds). - */ +__STATIC_INLINE bool nrf_clock_event_check(nrf_clock_event_t event) +{ + return (bool)*((volatile uint32_t *)((uint8_t *)NRF_CLOCK + event)); +} + +__STATIC_INLINE void nrf_clock_lf_src_set(nrf_clock_lfclk_t source) +{ + NRF_CLOCK->LFCLKSRC = + (uint32_t)((source << CLOCK_LFCLKSRC_SRC_Pos) & CLOCK_LFCLKSRC_SRC_Msk); +} + +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_src_get(void) +{ + return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRC & + CLOCK_LFCLKSRC_SRC_Msk) >> CLOCK_LFCLKSRC_SRC_Pos); +} + +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_actv_src_get(void) +{ + return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSTAT & + CLOCK_LFCLKSTAT_SRC_Msk) >> CLOCK_LFCLKSTAT_SRC_Pos); +} + +__STATIC_INLINE nrf_clock_lfclk_t nrf_clock_lf_srccopy_get(void) +{ + return (nrf_clock_lfclk_t)((NRF_CLOCK->LFCLKSRCCOPY & + CLOCK_LFCLKSRCCOPY_SRC_Msk) >> CLOCK_LFCLKSRCCOPY_SRC_Pos); +} + +__STATIC_INLINE bool nrf_clock_lf_is_running(void) +{ + return ((NRF_CLOCK->LFCLKSTAT & + CLOCK_LFCLKSTAT_STATE_Msk) >> CLOCK_LFCLKSTAT_STATE_Pos); +} + +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_lf_start_task_status_get(void) +{ + return (nrf_clock_start_task_status_t)((NRF_CLOCK->LFCLKRUN & + CLOCK_LFCLKRUN_STATUS_Msk) >> + CLOCK_LFCLKRUN_STATUS_Pos); +} + +__STATIC_INLINE nrf_clock_hfclk_t nrf_clock_hf_src_get(void) +{ + return (nrf_clock_hfclk_t)((NRF_CLOCK->HFCLKSTAT & + CLOCK_HFCLKSTAT_SRC_Msk) >> CLOCK_HFCLKSTAT_SRC_Pos); +} + +__STATIC_INLINE bool nrf_clock_hf_is_running(nrf_clock_hfclk_t clk_src) +{ + return (NRF_CLOCK->HFCLKSTAT & (CLOCK_HFCLKSTAT_STATE_Msk | CLOCK_HFCLKSTAT_SRC_Msk)) == + (CLOCK_HFCLKSTAT_STATE_Msk | (clk_src << CLOCK_HFCLKSTAT_SRC_Pos)); +} + +__STATIC_INLINE nrf_clock_start_task_status_t nrf_clock_hf_start_task_status_get(void) +{ + return (nrf_clock_start_task_status_t)((NRF_CLOCK->HFCLKRUN & + CLOCK_HFCLKRUN_STATUS_Msk) >> + CLOCK_HFCLKRUN_STATUS_Pos); +} + __STATIC_INLINE void nrf_clock_cal_timer_timeout_set(uint32_t interval) { NRF_CLOCK->CTIV = ((interval << CLOCK_CTIV_CTIV_Pos) & CLOCK_CTIV_CTIV_Msk); } + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + /** *@} **/ + +#ifdef __cplusplus +} +#endif + #endif // NRF_CLOCK_H__ diff --git a/components/drivers_nrf/hal/nrf_comp.h b/components/drivers_nrf/hal/nrf_comp.h new file mode 100644 index 0000000..e5f2304 --- /dev/null +++ b/components/drivers_nrf/hal/nrf_comp.h @@ -0,0 +1,510 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * @brief COMP HAL API. + */ + +#ifndef NRF_COMP_H_ +#define NRF_COMP_H_ + +/** + * @defgroup nrf_comp_hal COMP HAL + * @{ + * @ingroup nrf_comp + * @brief @tagAPI52 Hardware access layer for managing the Comparator (COMP). + */ + +#include "nrf.h" + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @enum nrf_comp_input_t + * @brief COMP analog pin selection. + */ +typedef enum +{ + NRF_COMP_INPUT_0 = COMP_PSEL_PSEL_AnalogInput0, /*!< AIN0 selected as analog input. */ + NRF_COMP_INPUT_1 = COMP_PSEL_PSEL_AnalogInput1, /*!< AIN1 selected as analog input. */ + NRF_COMP_INPUT_2 = COMP_PSEL_PSEL_AnalogInput2, /*!< AIN2 selected as analog input. */ + NRF_COMP_INPUT_3 = COMP_PSEL_PSEL_AnalogInput3, /*!< AIN3 selected as analog input. */ + NRF_COMP_INPUT_4 = COMP_PSEL_PSEL_AnalogInput4, /*!< AIN4 selected as analog input. */ + NRF_COMP_INPUT_5 = COMP_PSEL_PSEL_AnalogInput5, /*!< AIN5 selected as analog input. */ + NRF_COMP_INPUT_6 = COMP_PSEL_PSEL_AnalogInput6, /*!< AIN6 selected as analog input. */ + NRF_COMP_INPUT_7 = COMP_PSEL_PSEL_AnalogInput7 /*!< AIN7 selected as analog input. */ +}nrf_comp_input_t; + +/** + * @enum nrf_comp_ref_t + * @brief COMP reference selection. + */ +typedef enum +{ + NRF_COMP_REF_Int1V2 = COMP_REFSEL_REFSEL_Int1V2, /*!< VREF = internal 1.2 V reference (VDD >= 1.7 V). */ + NRF_COMP_REF_Int1V8 = COMP_REFSEL_REFSEL_Int1V8, /*!< VREF = internal 1.8 V reference (VDD >= VREF + 0.2 V). */ + NRF_COMP_REF_Int2V4 = COMP_REFSEL_REFSEL_Int2V4, /*!< VREF = internal 2.4 V reference (VDD >= VREF + 0.2 V). */ + NRF_COMP_REF_VDD = COMP_REFSEL_REFSEL_VDD, /*!< VREF = VDD. */ + NRF_COMP_REF_ARef = COMP_REFSEL_REFSEL_ARef /*!< VREF = AREF (VDD >= VREF >= AREFMIN). */ +}nrf_comp_ref_t; + +/** + * @enum nrf_comp_ext_ref_t + * @brief COMP external analog reference selection. + */ +typedef enum +{ + NRF_COMP_EXT_REF_0 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference0, /*!< Use AIN0 as external analog reference. */ + NRF_COMP_EXT_REF_1 = COMP_EXTREFSEL_EXTREFSEL_AnalogReference1 /*!< Use AIN1 as external analog reference. */ +}nrf_comp_ext_ref_t; + +/** + * @brief COMP THDOWN and THUP values that are used to calculate the threshold voltages VDOWN and VUP. + */ +typedef struct +{ + uint8_t th_down; /*!< THDOWN value. */ + uint8_t th_up; /*!< THUP value. */ +}nrf_comp_th_t; + +/** + * @enum nrf_comp_main_mode_t + * @brief COMP main operation mode. + */ +typedef enum +{ + NRF_COMP_MAIN_MODE_SE = COMP_MODE_MAIN_SE, /*!< Single ended mode. */ + NRF_COMP_MAIN_MODE_Diff = COMP_MODE_MAIN_Diff /*!< Differential mode. */ +}nrf_comp_main_mode_t; + +/** + * @enum nrf_comp_sp_mode_t + * @brief COMP speed and power mode. + */ +typedef enum +{ + NRF_COMP_SP_MODE_Low = COMP_MODE_SP_Low, /*!< Low power mode. */ + NRF_COMP_SP_MODE_Normal = COMP_MODE_SP_Normal, /*!< Normal mode. */ + NRF_COMP_SP_MODE_High = COMP_MODE_SP_High /*!< High speed mode. */ +}nrf_comp_sp_mode_t; + +/** + * @enum nrf_comp_hyst_t + * @brief COMP comparator hysteresis. + */ +typedef enum +{ + NRF_COMP_HYST_NoHyst = COMP_HYST_HYST_NoHyst, /*!< Comparator hysteresis disabled. */ + NRF_COMP_HYST_50mV = COMP_HYST_HYST_Hyst50mV /*!< Comparator hysteresis enabled. */ +}nrf_comp_hyst_t; + +/** + * @brief COMP current source selection on analog input. + */ +typedef enum +{ + NRF_COMP_ISOURCE_Off = COMP_ISOURCE_ISOURCE_Off, /*!< Current source disabled. */ + NRF_COMP_ISOURCE_Ien2uA5 = COMP_ISOURCE_ISOURCE_Ien2mA5, /*!< Current source enabled (+/- 2.5 uA). */ + NRF_COMP_ISOURCE_Ien5uA = COMP_ISOURCE_ISOURCE_Ien5mA, /*!< Current source enabled (+/- 5 uA). */ + NRF_COMP_ISOURCE_Ien10uA = COMP_ISOURCE_ISOURCE_Ien10mA /*!< Current source enabled (+/- 10 uA). */ +}nrf_isource_t; + +/** + * @enum nrf_comp_task_t + * @brief COMP tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_COMP_TASK_START = offsetof(NRF_COMP_Type, TASKS_START), /*!< COMP start sampling task. */ + NRF_COMP_TASK_STOP = offsetof(NRF_COMP_Type, TASKS_STOP), /*!< COMP stop sampling task. */ + NRF_COMP_TASK_SAMPLE = offsetof(NRF_COMP_Type, TASKS_SAMPLE) /*!< Sample comparator value. */ + /*lint -restore*/ +}nrf_comp_task_t; + +/** + * @enum nrf_comp_event_t + * @brief COMP events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_COMP_EVENT_READY = offsetof(NRF_COMP_Type, EVENTS_READY), /*!< COMP is ready and output is valid. */ + NRF_COMP_EVENT_DOWN = offsetof(NRF_COMP_Type, EVENTS_DOWN), /*!< Input voltage crossed the threshold going down. */ + NRF_COMP_EVENT_UP = offsetof(NRF_COMP_Type, EVENTS_UP), /*!< Input voltage crossed the threshold going up. */ + NRF_COMP_EVENT_CROSS = offsetof(NRF_COMP_Type, EVENTS_CROSS) /*!< Input voltage crossed the threshold in any direction. */ + /*lint -restore*/ +}nrf_comp_event_t; + +/** + * @brief COMP reference configuration. + */ +typedef struct +{ + nrf_comp_ref_t reference; /*!< COMP reference selection. */ + nrf_comp_ext_ref_t external; /*!< COMP external analog reference selection. */ +}nrf_comp_ref_conf_t; + + +/** + * @brief Function for enabling the COMP peripheral. + */ +__STATIC_INLINE void nrf_comp_enable(void); + + +/** + * @brief Function for disabling the COMP peripheral. + */ + +__STATIC_INLINE void nrf_comp_disable(void); + +/** + * @brief Function for checking if the COMP peripheral is enabled. + * + * @retval true If the COMP peripheral is enabled. + * @retval false If the COMP peripheral is not enabled. + */ +__STATIC_INLINE bool nrf_comp_enable_check(void); + +/** + * @brief Function for setting the reference source. + * + * @param[in] reference COMP reference selection. + */ +__STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference); + + +/** + * @brief Function for setting the external analog reference source. + * + * @param[in] ext_ref COMP external analog reference selection. + */ +__STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref); + + +/** + * @brief Function for setting threshold voltages. + * + * @param[in] threshold COMP VDOWN and VUP thresholds. + */ +__STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold); + + +/** + * @brief Function for setting the main mode. + * + * @param[in] main_mode COMP main operation mode. + */ +__STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode); + + +/** + * @brief Function for setting the speed mode. + * + * @param[in] speed_mode COMP speed and power mode. + */ +__STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode); + + +/** + * @brief Function for setting the hysteresis. + * + * @param[in] hyst COMP comparator hysteresis. + */ +__STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst); + + +/** + * @brief Function for setting the current source on the analog input. + * + * @param[in] isource COMP current source selection on analog input. + */ +__STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource); + + +/** + * @brief Function for selecting the active input of the COMP. + * + * @param[in] input Input to be selected. + */ +__STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input); + + +/** + * @brief Function for getting the last COMP compare result. + * + * @return The last compare result. If 0, then VIN+ < VIN-. If 1, then VIN+ > VIN-. + * + * @note If VIN+ == VIN-, the return value depends on the previous result. + */ +__STATIC_INLINE uint32_t nrf_comp_result_get(void); + + +/** + * @brief Function for enabling interrupts from COMP. + * + * @param[in] comp_int_mask Mask of interrupts to be enabled. + * + * @sa nrf_comp_int_enable_check() + */ +__STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask); + +/** + * @brief Function for disabling interrupts from COMP. + * + * @param[in] comp_int_mask Mask of interrupts to be disabled. + * + * @sa nrf_comp_int_enable_check() + */ +__STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask); + + +/** + * @brief Function for getting the enabled interrupts of COMP. + * + * @param[in] comp_int_mask Mask of interrupts to be checked. + * + * @retval true If any interrupts of the specified mask are enabled. + */ +__STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask); + + + +/** + * @brief Function for getting the address of a specific COMP task register. + * + * @param[in] comp_task COMP task. + * + * @return Address of the specified COMP task. + */ +__STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task); + + +/** + * @brief Function for getting the address of a specific COMP event register. + * + * @param[in] comp_event COMP event. + * + * @return Address of the specified COMP event. + */ +__STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event); + + +/** + * @brief Function for setting COMP shorts. + * + * @param[in] comp_short_mask COMP shorts by mask. + * + */ +__STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask); + + +/** + * @brief Function for clearing COMP shorts by mask. + * + * @param[in] comp_short_mask COMP shorts to be cleared. + * + */ +__STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask); + + +/** + * @brief Function for setting a specific COMP task. + * + * @param[in] comp_task COMP task to be set. + * + */ +__STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task); + + +/** + * @brief Function for clearing a specific COMP event. + * + * @param[in] comp_event COMP event to be cleared. + * + */ +__STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event); + + +/** + * @brief Function for getting the state of a specific COMP event. + * + * @retval true If the specified COMP event is active. + * + */ +__STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_comp_enable(void) +{ + NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Enabled << COMP_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_comp_disable(void) +{ + NRF_COMP->ENABLE = (COMP_ENABLE_ENABLE_Disabled << COMP_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE bool nrf_comp_enable_check(void) +{ + return ((NRF_COMP->ENABLE) & COMP_ENABLE_ENABLE_Enabled); +} + +__STATIC_INLINE void nrf_comp_ref_set(nrf_comp_ref_t reference) +{ + NRF_COMP->REFSEL = (reference << COMP_REFSEL_REFSEL_Pos); +} + +__STATIC_INLINE void nrf_comp_ext_ref_set(nrf_comp_ext_ref_t ext_ref) +{ + NRF_COMP->EXTREFSEL = (ext_ref << COMP_EXTREFSEL_EXTREFSEL_Pos); +} + +__STATIC_INLINE void nrf_comp_th_set(nrf_comp_th_t threshold) +{ + NRF_COMP->TH = + ((threshold.th_down << COMP_TH_THDOWN_Pos) & COMP_TH_THDOWN_Msk) | + ((threshold.th_up << COMP_TH_THUP_Pos) & COMP_TH_THUP_Msk); +} + +__STATIC_INLINE void nrf_comp_main_mode_set(nrf_comp_main_mode_t main_mode) +{ + NRF_COMP->MODE |= (main_mode << COMP_MODE_MAIN_Pos); +} + +__STATIC_INLINE void nrf_comp_speed_mode_set(nrf_comp_sp_mode_t speed_mode) +{ + NRF_COMP->MODE |= (speed_mode << COMP_MODE_SP_Pos); +} + +__STATIC_INLINE void nrf_comp_hysteresis_set(nrf_comp_hyst_t hyst) +{ + NRF_COMP->HYST = (hyst << COMP_HYST_HYST_Pos) & COMP_HYST_HYST_Msk; +} + +__STATIC_INLINE void nrf_comp_isource_set(nrf_isource_t isource) +{ + NRF_COMP->ISOURCE = (isource << COMP_ISOURCE_ISOURCE_Pos) & COMP_ISOURCE_ISOURCE_Msk; +} + +__STATIC_INLINE void nrf_comp_input_select(nrf_comp_input_t input) +{ + NRF_COMP->PSEL = ((uint32_t)input << COMP_PSEL_PSEL_Pos); +} + +__STATIC_INLINE uint32_t nrf_comp_result_get(void) +{ + return (uint32_t)NRF_COMP->RESULT; +} + +__STATIC_INLINE void nrf_comp_int_enable(uint32_t comp_int_mask) +{ + NRF_COMP->INTENSET = comp_int_mask; +} + +__STATIC_INLINE void nrf_comp_int_disable(uint32_t comp_int_mask) +{ + NRF_COMP->INTENCLR = comp_int_mask; +} + +__STATIC_INLINE bool nrf_comp_int_enable_check(uint32_t comp_int_mask) +{ + return (NRF_COMP->INTENSET & comp_int_mask); // when read this register will return the value of INTEN. +} + +__STATIC_INLINE uint32_t * nrf_comp_task_address_get(nrf_comp_task_t comp_task) +{ + return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_task); +} + +__STATIC_INLINE uint32_t * nrf_comp_event_address_get(nrf_comp_event_t comp_event) +{ + return (uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event); +} + +__STATIC_INLINE void nrf_comp_shorts_enable(uint32_t comp_short_mask) +{ + NRF_COMP->SHORTS |= comp_short_mask; +} + +__STATIC_INLINE void nrf_comp_shorts_disable(uint32_t comp_short_mask) +{ + NRF_COMP->SHORTS &= ~comp_short_mask; +} + +__STATIC_INLINE void nrf_comp_task_trigger(nrf_comp_task_t comp_task) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_task) ) = 1; +} + +__STATIC_INLINE void nrf_comp_event_clear(nrf_comp_event_t comp_event) +{ + *( (volatile uint32_t *)( (uint8_t *)NRF_COMP + (uint32_t)comp_event) ) = 0; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_COMP + (uint32_t)comp_event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_comp_event_check(nrf_comp_event_t comp_event) +{ + return (bool) (*(volatile uint32_t *)( (uint8_t *)NRF_COMP + comp_event)); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_COMP_H_ diff --git a/components/drivers_nrf/hal/nrf_ecb.c b/components/drivers_nrf/hal/nrf_ecb.c index a70398c..08154d7 100644 --- a/components/drivers_nrf/hal/nrf_ecb.c +++ b/components/drivers_nrf/hal/nrf_ecb.c @@ -1,17 +1,44 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -* $LastChangedRevision: 25419 $ -*/ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @brief Implementation of AES ECB driver */ @@ -22,11 +49,11 @@ #include #include #include -#include "nrf.h" +#include "nrf.h" #include "nrf_ecb.h" static uint8_t ecb_data[48]; ///< ECB data structure for RNG peripheral to access. -static uint8_t* ecb_key; ///< Key: Starts at ecb_data +static uint8_t* ecb_key; ///< Key: Starts at ecb_data static uint8_t* ecb_cleartext; ///< Cleartext: Starts at ecb_data + 16 bytes. static uint8_t* ecb_ciphertext; ///< Ciphertext: Starts at ecb_data + 32 bytes. @@ -44,22 +71,22 @@ bool nrf_ecb_init(void) bool nrf_ecb_crypt(uint8_t * dest_buf, const uint8_t * src_buf) { uint32_t counter = 0x1000000; - if(src_buf != ecb_cleartext) + if (src_buf != ecb_cleartext) { memcpy(ecb_cleartext,src_buf,16); } NRF_ECB->EVENTS_ENDECB = 0; NRF_ECB->TASKS_STARTECB = 1; - while(NRF_ECB->EVENTS_ENDECB == 0) + while (NRF_ECB->EVENTS_ENDECB == 0) { counter--; - if(counter == 0) + if (counter == 0) { return false; } } NRF_ECB->EVENTS_ENDECB = 0; - if(dest_buf != ecb_ciphertext) + if (dest_buf != ecb_ciphertext) { memcpy(dest_buf,ecb_ciphertext,16); } diff --git a/components/drivers_nrf/hal/nrf_ecb.h b/components/drivers_nrf/hal/nrf_ecb.h index 0d5997d..aac7abb 100644 --- a/components/drivers_nrf/hal/nrf_ecb.h +++ b/components/drivers_nrf/hal/nrf_ecb.h @@ -1,14 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic - * Semiconductor ASA.Terms and conditions of usage are described in detail - * in NORDIC 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. - * - * $LastChangedRevision: 13999 $ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -31,6 +58,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Function for initializing and powering on the ECB peripheral. * @@ -43,10 +74,10 @@ bool nrf_ecb_init(void); /** * @brief Function for encrypting and decrypting 16-byte data using current key. * - * This function avoids unnecessary copying of data if the parameters point to the + * This function avoids unnecessary copying of data if the parameters point to the * correct locations in the ECB data structure. * - * @param dst Result of encryption/decryption. 16 bytes will be written. + * @param dst Result of encryption/decryption. 16 bytes will be written. * @param src Source with 16-byte data to be encrypted/decrypted. * * @retval true If the encryption operation completed. @@ -61,6 +92,11 @@ bool nrf_ecb_crypt(uint8_t * dst, const uint8_t * src); */ void nrf_ecb_set_key(const uint8_t * key); + +#ifdef __cplusplus +} +#endif + #endif // NRF_ECB_H__ /** @} */ diff --git a/components/drivers_nrf/hal/nrf_egu.h b/components/drivers_nrf/hal/nrf_egu.h index a53e7f0..6ac50a3 100644 --- a/components/drivers_nrf/hal/nrf_egu.h +++ b/components/drivers_nrf/hal/nrf_egu.h @@ -1,27 +1,51 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_EGU_H__ #define NRF_EGU_H__ -#ifndef NRF52 - #error EGU is not supported on your chip. -#endif - /** * @defgroup nrf_egu EGU (Event Generator Unit) abstraction * @{ * @ingroup nrf_drivers -* @brief EGU (Event Generator Unit) module functions. +* @brief @tagAPI52 EGU (Event Generator Unit) module functions. * */ @@ -31,8 +55,9 @@ #include "nrf_assert.h" #include "nrf.h" -#define NRF_EGU_COUNT 6 /**< Number of EGU instances. */ -#define NRF_EGU_CHANNEL_COUNT 16 /**< Number of channels per EGU instance. */ +#ifdef __cplusplus +extern "C" { +#endif /** * @enum nrf_egu_task_t @@ -113,6 +138,34 @@ typedef enum NRF_EGU_INT_ALL = 0xFFFFuL } nrf_egu_int_mask_t; +/**@brief Function for getting max channel number of given EGU. + * + * @param NRF_EGUx EGU instance. + * + * @returns number of available channels. + */ +__STATIC_INLINE uint32_t nrf_egu_channel_count(NRF_EGU_Type * NRF_EGUx) +{ + if (NRF_EGUx == NRF_EGU0){ + return EGU0_CH_NUM; + } + if (NRF_EGUx == NRF_EGU1){ + return EGU1_CH_NUM; + } + if (NRF_EGUx == NRF_EGU2){ + return EGU2_CH_NUM; + } + if (NRF_EGUx == NRF_EGU3){ + return EGU3_CH_NUM; + } + if (NRF_EGUx == NRF_EGU4){ + return EGU4_CH_NUM; + } + if (NRF_EGUx == NRF_EGU5){ + return EGU5_CH_NUM; + } + return 0; +} /** * @brief Function for triggering a specific EGU task. @@ -148,7 +201,7 @@ __STATIC_INLINE uint32_t * nrf_egu_task_address_get(NRF_EGU_Type * NRF_EGUx, __STATIC_INLINE uint32_t * nrf_egu_task_trigger_addres_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel) { - ASSERT(channel < NRF_EGU_CHANNEL_COUNT); + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); return (uint32_t*)&NRF_EGUx->TASKS_TRIGGER[channel]; } @@ -156,11 +209,12 @@ __STATIC_INLINE uint32_t * nrf_egu_task_trigger_addres_get(NRF_EGU_Type * NRF_EG /** * @brief Function for returning the specific EGU TRIGGER task. * + * @param NRF_EGUx EGU instance. * @param channel Channel number. */ -__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(uint8_t channel) +__STATIC_INLINE nrf_egu_task_t nrf_egu_task_trigger_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel) { - ASSERT(channel <= NRF_EGU_CHANNEL_COUNT); + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); return (nrf_egu_task_t)((uint32_t) NRF_EGU_TASK_TRIGGER0 + (channel * sizeof(uint32_t))); } @@ -188,6 +242,10 @@ __STATIC_INLINE void nrf_egu_event_clear(NRF_EGU_Type * NRF_EGUx, nrf_egu_event_t egu_event) { *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_EGUx + (uint32_t)egu_event)); + (void)dummy; +#endif } @@ -213,7 +271,7 @@ __STATIC_INLINE uint32_t * nrf_egu_event_address_get(NRF_EGU_Type * NRF_EGUx, __STATIC_INLINE uint32_t * nrf_egu_event_triggered_addres_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel) { - ASSERT(channel < NRF_EGU_CHANNEL_COUNT); + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); return (uint32_t*)&NRF_EGUx->EVENTS_TRIGGERED[channel]; } @@ -221,11 +279,13 @@ __STATIC_INLINE uint32_t * nrf_egu_event_triggered_addres_get(NRF_EGU_Type * NRF /** * @brief Function for returning the specific EGU TRIGGERED event. * + * @param NRF_EGUx EGU instance. * @param channel Channel number. */ -__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(uint8_t channel) +__STATIC_INLINE nrf_egu_event_t nrf_egu_event_triggered_get(NRF_EGU_Type * NRF_EGUx, + uint8_t channel) { - ASSERT(channel < NRF_EGU_CHANNEL_COUNT); + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); return (nrf_egu_event_t)((uint32_t) NRF_EGU_EVENT_TRIGGERED0 + (channel * sizeof(uint32_t))); } @@ -271,16 +331,22 @@ __STATIC_INLINE void nrf_egu_int_disable(NRF_EGU_Type * NRF_EGUx, uint32_t egu_i /** * @brief Function for retrieving one or more specific EGU interrupts. * + * @param NRF_EGUx EGU instance. * @param channel Channel number. * * @returns EGU interrupt mask. */ -__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(uint8_t channel) +__STATIC_INLINE nrf_egu_int_mask_t nrf_egu_int_get(NRF_EGU_Type * NRF_EGUx, uint8_t channel) { - ASSERT(channel < NRF_EGU_CHANNEL_COUNT); + ASSERT(channel < nrf_egu_channel_count(NRF_EGUx)); return (nrf_egu_int_mask_t)((uint32_t) (EGU_INTENSET_TRIGGERED0_Msk << channel)); } /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_nrf/hal/nrf_gpio.h b/components/drivers_nrf/hal/nrf_gpio.h index 992bf55..ccd408c 100644 --- a/components/drivers_nrf/hal/nrf_gpio.h +++ b/components/drivers_nrf/hal/nrf_gpio.h @@ -1,96 +1,119 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -*/ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_GPIO_H__ #define NRF_GPIO_H__ #include "nrf.h" +#include "nrf_peripherals.h" +#include "nrf_assert.h" #include +#include + +#ifdef __cplusplus +extern "C" { +#endif /** * @defgroup nrf_gpio GPIO abstraction * @{ * @ingroup nrf_drivers * @brief GPIO pin abstraction and port abstraction for reading and writing byte-wise to GPIO ports. - * - * Here, the GPIO ports are defined as follows: - * - Port 0 -> pin 0-7 - * - Port 1 -> pin 8-15 - * - Port 2 -> pin 16-23 - * - Port 3 -> pin 24-31 */ -#define NUMBER_OF_PINS 32 +#if (GPIO_COUNT == 1) +#define NUMBER_OF_PINS (P0_PIN_NUM) +#define GPIO_REG_LIST {NRF_GPIO} +#elif (GPIO_COUNT == 2) +#define NUMBER_OF_PINS (P0_PIN_NUM + P1_PIN_NUM) +#define GPIO_REG_LIST {NRF_P0, NRF_P1} +#else +#error "Not supported." +#endif -/** - * @brief Enumerator used for selecting between port 0 - 3. - */ -typedef enum -{ - NRF_GPIO_PORT_SELECT_PORT0 = 0, ///< Port 0 (GPIO pin 0-7) - NRF_GPIO_PORT_SELECT_PORT1, ///< Port 1 (GPIO pin 8-15) - NRF_GPIO_PORT_SELECT_PORT2, ///< Port 2 (GPIO pin 16-23) - NRF_GPIO_PORT_SELECT_PORT3, ///< Port 3 (GPIO pin 24-31) -} nrf_gpio_port_select_t; /** - * @brief Enumerator used for setting the direction of a GPIO port. + * @brief Macro for mapping port and pin numbers to values understandable for nrf_gpio functions. */ -typedef enum -{ - NRF_GPIO_PORT_DIR_OUTPUT, ///< Output - NRF_GPIO_PORT_DIR_INPUT ///< Input -} nrf_gpio_port_dir_t; +#define NRF_GPIO_PIN_MAP(port, pin) ((port << 5) | (pin & 0x1F)) /** * @brief Pin direction definitions. */ typedef enum { - NRF_GPIO_PIN_DIR_INPUT = GPIO_PIN_CNF_DIR_Input, ///< Input - NRF_GPIO_PIN_DIR_OUTPUT = GPIO_PIN_CNF_DIR_Output ///< Output + NRF_GPIO_PIN_DIR_INPUT = GPIO_PIN_CNF_DIR_Input, ///< Input. + NRF_GPIO_PIN_DIR_OUTPUT = GPIO_PIN_CNF_DIR_Output ///< Output. } nrf_gpio_pin_dir_t; /** - * @brief Connection of input buffer + * @brief Connection of input buffer. */ typedef enum { - NRF_GPIO_PIN_INPUT_CONNECT = GPIO_PIN_CNF_INPUT_Connect, ///< Connect input buffer - NRF_GPIO_PIN_INPUT_DISCONNECT = GPIO_PIN_CNF_INPUT_Disconnect ///< Disconnect input buffer + NRF_GPIO_PIN_INPUT_CONNECT = GPIO_PIN_CNF_INPUT_Connect, ///< Connect input buffer. + NRF_GPIO_PIN_INPUT_DISCONNECT = GPIO_PIN_CNF_INPUT_Disconnect ///< Disconnect input buffer. } nrf_gpio_pin_input_t; /** - * @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration + * @brief Enumerator used for selecting the pin to be pulled down or up at the time of pin configuration. */ typedef enum { - NRF_GPIO_PIN_NOPULL = GPIO_PIN_CNF_PULL_Disabled, ///< Pin pullup resistor disabled - NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pulldown resistor enabled - NRF_GPIO_PIN_PULLUP = GPIO_PIN_CNF_PULL_Pullup, ///< Pin pullup resistor enabled + NRF_GPIO_PIN_NOPULL = GPIO_PIN_CNF_PULL_Disabled, ///< Pin pull-up resistor disabled. + NRF_GPIO_PIN_PULLDOWN = GPIO_PIN_CNF_PULL_Pulldown, ///< Pin pull-down resistor enabled. + NRF_GPIO_PIN_PULLUP = GPIO_PIN_CNF_PULL_Pullup, ///< Pin pull-up resistor enabled. } nrf_gpio_pin_pull_t; /** - * @brief Enumerator used for selecting output drive mode + * @brief Enumerator used for selecting output drive mode. */ typedef enum { - NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1' - NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High drive '0', standard '1' - NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high drive '1' - NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high 'drive '1'' - NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1' - NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high drive '1' - NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0'. disconnect '1' - NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High drive '0', disconnect '1' + NRF_GPIO_PIN_S0S1 = GPIO_PIN_CNF_DRIVE_S0S1, ///< !< Standard '0', standard '1'. + NRF_GPIO_PIN_H0S1 = GPIO_PIN_CNF_DRIVE_H0S1, ///< !< High-drive '0', standard '1'. + NRF_GPIO_PIN_S0H1 = GPIO_PIN_CNF_DRIVE_S0H1, ///< !< Standard '0', high-drive '1'. + NRF_GPIO_PIN_H0H1 = GPIO_PIN_CNF_DRIVE_H0H1, ///< !< High drive '0', high-drive '1'. + NRF_GPIO_PIN_D0S1 = GPIO_PIN_CNF_DRIVE_D0S1, ///< !< Disconnect '0' standard '1'. + NRF_GPIO_PIN_D0H1 = GPIO_PIN_CNF_DRIVE_D0H1, ///< !< Disconnect '0', high-drive '1'. + NRF_GPIO_PIN_S0D1 = GPIO_PIN_CNF_DRIVE_S0D1, ///< !< Standard '0', disconnect '1'. + NRF_GPIO_PIN_H0D1 = GPIO_PIN_CNF_DRIVE_H0D1, ///< !< High-drive '0', disconnect '1'. } nrf_gpio_pin_drive_t; /** @@ -98,92 +121,96 @@ typedef enum */ typedef enum { - NRF_GPIO_PIN_NOSENSE = GPIO_PIN_CNF_SENSE_Disabled, ///< Pin sense level disabled. - NRF_GPIO_PIN_SENSE_LOW = GPIO_PIN_CNF_SENSE_Low, ///< Pin sense low level. - NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High, ///< Pin sense high level. + NRF_GPIO_PIN_NOSENSE = GPIO_PIN_CNF_SENSE_Disabled, ///< Pin sense level disabled. + NRF_GPIO_PIN_SENSE_LOW = GPIO_PIN_CNF_SENSE_Low, ///< Pin sense low level. + NRF_GPIO_PIN_SENSE_HIGH = GPIO_PIN_CNF_SENSE_High, ///< Pin sense high level. } nrf_gpio_pin_sense_t; +#if (__LINT__ != 1) + /** - * @brief Function for configuring the GPIO pin range as outputs with normal drive strength. + * @brief Function for configuring the GPIO pin range as output pins with normal drive strength. * This function can be used to configure pin range as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). * - * @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) + * @param pin_range_start Specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30). * - * @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) + * @param pin_range_end Specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30). * - * @note For configuring only one pin as output use @ref nrf_gpio_cfg_output - * Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output. + * @note For configuring only one pin as output, use @ref nrf_gpio_cfg_output. + * Sense capability on the pin is disabled and input is disconnected from the buffer as the pins are configured as output. */ __STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end); /** - * @brief Function for configuring the GPIO pin range as inputs with given initial value set, hiding inner details. + * @brief Function for configuring the GPIO pin range as input pins with given initial value set, hiding inner details. * This function can be used to configure pin range as simple input. * - * @param pin_range_start specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) + * @param pin_range_start Specifies the start number (inclusive) in the range of pin numbers to be configured (allowed values 0-30). * - * @param pin_range_end specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30) + * @param pin_range_end Specifies the end number (inclusive) in the range of pin numbers to be configured (allowed values 0-30). * - * @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high) + * @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high). * - * @note For configuring only one pin as input use @ref nrf_gpio_cfg_input - * Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable + * @note For configuring only one pin as input, use @ref nrf_gpio_cfg_input. + * Sense capability on the pin is disabled and input is connected to buffer so that the GPIO->IN register is readable. */ -__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config); +__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, + uint32_t pin_range_end, + nrf_gpio_pin_pull_t pull_config); /** - * @brief Pin configuration function + * @brief Pin configuration function. * * The main pin configuration function. * This function allows to set any aspect in PIN_CNF register. - * @param pin_number Specifies the pin number (allowed values 0-31). - * @param dir Pin direction - * @param input Connect or disconnect input buffer - * @param pull Pull configuration - * @param drive Drive configuration - * @param sense Pin sensing mechanism + * @param pin_number Specifies the pin number. + * @param dir Pin direction. + * @param input Connect or disconnect the input buffer. + * @param pull Pull configuration. + * @param drive Drive configuration. + * @param sense Pin sensing mechanism. */ __STATIC_INLINE void nrf_gpio_cfg( - uint32_t pin_number, - nrf_gpio_pin_dir_t dir, - nrf_gpio_pin_input_t input, - nrf_gpio_pin_pull_t pull, - nrf_gpio_pin_drive_t drive, - nrf_gpio_pin_sense_t sense); + uint32_t pin_number, + nrf_gpio_pin_dir_t dir, + nrf_gpio_pin_input_t input, + nrf_gpio_pin_pull_t pull, + nrf_gpio_pin_drive_t drive, + nrf_gpio_pin_sense_t sense); /** - * @brief Function for configuring the given GPIO pin number as output with given initial value set, hiding inner details. - * This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). + * @brief Function for configuring the given GPIO pin number as output, hiding inner details. + * This function can be used to configure a pin as simple output with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). * - * @param pin_number specifies the pin number (allowed values 0-31) + * @param pin_number Specifies the pin number. * - * @note Sense capability on the pin is disabled, and input is disconnected from the buffer as the pins are configured as output. + * @note Sense capability on the pin is disabled and input is disconnected from the buffer as the pins are configured as output. */ __STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number); /** - * @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details. - * This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). + * @brief Function for configuring the given GPIO pin number as input, hiding inner details. + * This function can be used to configure a pin as simple input. * - * @param pin_number Specifies the pin number (allowed values 0-30). - * @param pull_config State of the pin range pull resistor (no pull, pulled down or pulled high). + * @param pin_number Specifies the pin number. + * @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high). * - * @note Sense capability on the pin is disabled, and input is connected to buffer so that the GPIO->IN register is readable + * @note Sense capability on the pin is disabled and input is connected to buffer so that the GPIO->IN register is readable. */ __STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config); /** - * @brief Function for reseting pin configuration to its default state. + * @brief Function for resetting pin configuration to its default state. * - * @param pin_number Specifies the pin number (allowed values 0-31). + * @param pin_number Specifies the pin number. */ __STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number); /** * @brief Function for configuring the given GPIO pin number as a watcher. Only input is connected. * - * @param pin_number Specifies the pin number (allowed values 0-31). + * @param pin_number Specifies the pin number. * */ __STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number); @@ -191,26 +218,28 @@ __STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number); /** * @brief Function for disconnecting input for the given GPIO. * - * @param pin_number Specifies the pin number (allowed values 0-31). + * @param pin_number Specifies the pin number. * */ __STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number); /** - * @brief Function for configuring the given GPIO pin number as input with given initial value set, hiding inner details. - * This function can be used to configure pin range as simple input with gate driving GPIO_PIN_CNF_DRIVE_S0S1 (normal cases). - * Sense capability on the pin is configurable, and input is connected to buffer so that the GPIO->IN register is readable. + * @brief Function for configuring the given GPIO pin number as input, hiding inner details. + * This function can be used to configure pin range as simple input. + * Sense capability on the pin is configurable and input is connected to buffer so that the GPIO->IN register is readable. * - * @param pin_number Specifies the pin number (allowed values 0-30). - * @param pull_config State of the pin pull resistor (no pull, pulled down or pulled high). - * @param sense_config Sense level of the pin (no sense, sense low or sense high). + * @param pin_number Specifies the pin number. + * @param pull_config State of the pin pull resistor (no pull, pulled down, or pulled high). + * @param sense_config Sense level of the pin (no sense, sense low, or sense high). */ -__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config); +__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, + nrf_gpio_pin_pull_t pull_config, + nrf_gpio_pin_sense_t sense_config); /** * @brief Function for configuring sense level for the given GPIO. * - * @param pin_number Specifies the pin number of gpio pin numbers to be configured (allowed values 0-30). + * @param pin_number Specifies the pin number. * @param sense_config Sense configuration. * */ @@ -219,65 +248,38 @@ __STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_se /** * @brief Function for setting the direction for a GPIO pin. * - * @param pin_number specifies the pin number [0:31] for which to - * set the direction. + * @param pin_number Specifies the pin number for which to set the direction. * - * @param direction specifies the direction + * @param direction Specifies the direction. */ __STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction); /** * @brief Function for setting a GPIO pin. * - * Note that the pin must be configured as an output for this - * function to have any effect. + * Note that the pin must be configured as an output for this function to have any effect. * - * @param pin_number specifies the pin number [0:31] to - * set. + * @param pin_number Specifies the pin number to set. */ __STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number); -/** - * @brief Function for setting GPIO pins. - * - * Note that pins must be configured as an output for this - * function to have any effect. - * - * @param pin_mask Specifies the pins to set. - * set. - */ -__STATIC_INLINE void nrf_gpio_pins_set(uint32_t pin_mask); - /** * @brief Function for clearing a GPIO pin. * * Note that the pin must be configured as an output for this * function to have any effect. * - * @param pin_number specifies the pin number [0:31] to - * clear. + * @param pin_number Specifies the pin number to clear. */ __STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number); -/** - * @brief Function for clearing GPIO pins. - * - * Note that pins must be configured as an output for this - * function to have any effect. - * - * @param pin_mask Specifies the pins to clear. - * set. - */ -__STATIC_INLINE void nrf_gpio_pins_clear(uint32_t pin_mask); - /** * @brief Function for toggling a GPIO pin. * * Note that the pin must be configured as an output for this * function to have any effect. * - * @param pin_number specifies the pin number [0:31] to - * toggle. + * @param pin_number Specifies the pin number to toggle. */ __STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number); @@ -287,12 +289,11 @@ __STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number); * Note that the pin must be configured as an output for this * function to have any effect. * - * @param pin_number specifies the pin number [0:31] to - * write. + * @param pin_number Specifies the pin number to write. * - * @param value specifies the value to be written to the pin. - * @arg 0 clears the pin - * @arg >=1 sets the pin. + * @param value Specifies the value to be written to the pin. + * @arg 0 Clears the pin. + * @arg >=1 Sets the pin. */ __STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value); @@ -302,123 +303,182 @@ __STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value); * Note that the pin must have input connected for the value * returned from this function to be valid. * - * @param pin_number specifies the pin number [0:31] to - * read. + * @param pin_number Specifies the pin number to read. * - * @return - * @retval 0 if the pin input level is low. - * @retval 1 if the pin input level is high. - * @retval > 1 should never occur. + * @return 0 if the pin input level is low. Positive value if the pin is high. */ __STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number); /** - * @brief Function for reading the input level of all GPIO pins. + * @brief Function for reading the output level of a GPIO pin. * - * Note that the pin must have input connected for the value - * returned from this function to be valid. + * @param pin_number Specifies the pin number to read. * - * @retval Status of input of all pins + * @return 0 if the pin output level is low. Positive value if pin output is high. */ -__STATIC_INLINE uint32_t nrf_gpio_pins_read(void); +__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin_number); /** * @brief Function for reading the sense configuration of a GPIO pin. * - * @param pin_number specifies the pin number [0:31] to - * read. + * @param pin_number Specifies the pin number to read. * - * @retval Sense configuration + * @retval Sense configuration. */ __STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number); /** - * @brief Generic function for writing a single byte of a 32 bit word at a given - * address. + * @brief Function for setting output direction on selected pins on a given port. * - * This function should not be called from outside the nrf_gpio - * abstraction layer. + * @param p_reg Pointer to the peripheral registers structure. + * @param out_mask Mask specifying the pins to set as output. * - * @param word_address is the address of the word to be written. + */ +__STATIC_INLINE void nrf_gpio_port_dir_output_set(NRF_GPIO_Type * p_reg, uint32_t out_mask); + +/** + * @brief Function for setting input direction on selected pins on a given port. * - * @param byte_no is the word byte number (0-3) to be written. + * @param p_reg Pointer to the peripheral registers structure. + * @param in_mask Mask specifying the pins to set as input. * - * @param value is the value to be written to byte "byte_no" of word - * at address "word_address" */ -__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value); +__STATIC_INLINE void nrf_gpio_port_dir_input_set(NRF_GPIO_Type * p_reg, uint32_t in_mask); /** - * @brief Generic function for reading a single byte of a 32 bit word at a given - * address. + * @brief Function for writing the direction configuration of GPIO pins in a given port. * - * This function should not be called from outside the nrf_gpio - * abstraction layer. + * @param p_reg Pointer to the peripheral registers structure. + * @param dir_mask Mask specifying the direction of pins. Bit set means that the given pin is configured as output. * - * @param word_address is the address of the word to be read. + */ +__STATIC_INLINE void nrf_gpio_port_dir_write(NRF_GPIO_Type * p_reg, uint32_t dir_mask); + +/** + * @brief Function for reading the direction configuration of a GPIO port. * - * @param byte_no is the byte number (0-3) of the word to be read. + * @param p_reg Pointer to the peripheral registers structure. * - * @return byte "byte_no" of word at address "word_address". + * @retval Pin configuration of the current direction settings. Bit set means that the given pin is configured as output. */ -__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no); +__STATIC_INLINE uint32_t nrf_gpio_port_dir_read(NRF_GPIO_Type const * p_reg); /** - * @brief Function for setting the direction of a port. + * @brief Function for reading the input signals of GPIO pins on a given port. * - * @param port is the port for which to set the direction. + * @param p_reg Pointer to the peripheral registers structure. * - * @param dir direction to be set for this port. + * @retval Port input values. */ -__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir); +__STATIC_INLINE uint32_t nrf_gpio_port_in_read(NRF_GPIO_Type const * p_reg); /** - * @brief Function for reading a GPIO port. + * @brief Function for reading the output signals of GPIO pins of a given port. * - * @param port is the port to read. + * @param p_reg Pointer to the peripheral registers structure. * - * @return the input value on this port. + * @retval Port output values. */ -__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port); +__STATIC_INLINE uint32_t nrf_gpio_port_out_read(NRF_GPIO_Type const * p_reg); /** - * @brief Function for writing to a GPIO port. + * @brief Function for writing the GPIO pins output on a given port. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param value Output port mask. * - * @param port is the port to write. + */ +__STATIC_INLINE void nrf_gpio_port_out_write(NRF_GPIO_Type * p_reg, uint32_t value); + +/** + * @brief Function for setting high level on selected GPIO pins of a given port. * - * @param value is the value to write to this port. + * @param p_reg Pointer to the peripheral registers structure. + * @param set_mask Mask with pins to set as logical high level. * - * @sa nrf_gpio_port_dir_set() */ -__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value); +__STATIC_INLINE void nrf_gpio_port_out_set(NRF_GPIO_Type * p_reg, uint32_t set_mask); /** - * @brief Function for setting individual pins on GPIO port. + * @brief Function for setting low level on selected GPIO pins of a given port. * - * @param port is the port for which to set the pins. + * @param p_reg Pointer to the peripheral registers structure. + * @param clr_mask Mask with pins to set as logical low level. * - * @param set_mask is a mask specifying which pins to set. A bit - * set to 1 indicates that the corresponding port pin shall be - * set. + */ +__STATIC_INLINE void nrf_gpio_port_out_clear(NRF_GPIO_Type * p_reg, uint32_t clr_mask); + +/** + * @brief Function for reading pins state of multiple consecutive ports. + * + * @param start_port Index of the first port to read. + * @param length Number of ports to read. + * @param p_masks Pointer to output array where port states will be stored. + */ +__STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port, uint32_t length, uint32_t * p_masks); + +#ifdef GPIO_DETECTMODE_DETECTMODE_LDETECT +/** + * @brief Function for reading latch state of multiple consecutive ports. * - * @sa nrf_gpio_port_dir_set() + * @param start_port Index of the first port to read. + * @param length Number of ports to read. + * @param p_masks Pointer to output array where latch states will be stored. */ -__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask); +__STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port, uint32_t length, + uint32_t * p_masks); /** - * @brief Function for clearing individual pins on GPIO port. + * @brief Function for reading latch state of single pin. + * + * @param pin_number Pin number. + * @return 0 if latch is not set. Positive value otherwise. * - * @param port is the port for which to clear the pins. + */ +__STATIC_INLINE uint32_t nrf_gpio_pin_latch_get(uint32_t pin_number); + +/** + * @brief Function for clearing latch state of a single pin. * - * @param clr_mask is a mask specifying which pins to clear. A bit - * set to 1 indicates that the corresponding port pin shall be - * cleared. + * @param pin_number Pin number. * - * @sa nrf_gpio_port_dir_set() */ -__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask); +__STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number); +#endif + + +#endif // #ifndef (__LINT__ != 1) #ifndef SUPPRESS_INLINE_IMPLEMENTATION + +/** + * @brief Function for extracting port and relative pin number from absolute pin number. + * + * @param[inout] Pointer to absolute pin number which is overriden by relative to port pin number. + * + * @return Pointer to port register set. + * + */ +__STATIC_INLINE NRF_GPIO_Type * nrf_gpio_pin_port_decode(uint32_t * p_pin) +{ + ASSERT(*p_pin < NUMBER_OF_PINS); +#if (GPIO_COUNT == 1) + // The oldest definition case + return NRF_GPIO; +#else + if (*p_pin < P0_PIN_NUM) + { + return NRF_P0; + } + else + { + *p_pin = *p_pin & (P0_PIN_NUM - 1); + return NRF_P1; + } +#endif +} + + __STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_t pin_range_end) { /*lint -e{845} // A zero has been given as right argument to operator '|'" */ @@ -428,7 +488,10 @@ __STATIC_INLINE void nrf_gpio_range_cfg_output(uint32_t pin_range_start, uint32_ } } -__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t pin_range_end, nrf_gpio_pin_pull_t pull_config) + +__STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, + uint32_t pin_range_end, + nrf_gpio_pin_pull_t pull_config) { /*lint -e{845} // A zero has been given as right argument to operator '|'" */ for (; pin_range_start <= pin_range_end; pin_range_start++) @@ -437,142 +500,151 @@ __STATIC_INLINE void nrf_gpio_range_cfg_input(uint32_t pin_range_start, uint32_t } } + __STATIC_INLINE void nrf_gpio_cfg( - uint32_t pin_number, - nrf_gpio_pin_dir_t dir, - nrf_gpio_pin_input_t input, - nrf_gpio_pin_pull_t pull, - nrf_gpio_pin_drive_t drive, - nrf_gpio_pin_sense_t sense) -{ - NRF_GPIO->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos) - | ((uint32_t)input << GPIO_PIN_CNF_INPUT_Pos) - | ((uint32_t)pull << GPIO_PIN_CNF_PULL_Pos) - | ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos) - | ((uint32_t)sense << GPIO_PIN_CNF_SENSE_Pos); + uint32_t pin_number, + nrf_gpio_pin_dir_t dir, + nrf_gpio_pin_input_t input, + nrf_gpio_pin_pull_t pull, + nrf_gpio_pin_drive_t drive, + nrf_gpio_pin_sense_t sense) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + reg->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos) + | ((uint32_t)input << GPIO_PIN_CNF_INPUT_Pos) + | ((uint32_t)pull << GPIO_PIN_CNF_PULL_Pos) + | ((uint32_t)drive << GPIO_PIN_CNF_DRIVE_Pos) + | ((uint32_t)sense << GPIO_PIN_CNF_SENSE_Pos); } + __STATIC_INLINE void nrf_gpio_cfg_output(uint32_t pin_number) { nrf_gpio_cfg( - pin_number, - NRF_GPIO_PIN_DIR_OUTPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_NOPULL, - NRF_GPIO_PIN_S0S1, - NRF_GPIO_PIN_NOSENSE); + pin_number, + NRF_GPIO_PIN_DIR_OUTPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); } + __STATIC_INLINE void nrf_gpio_cfg_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config) { nrf_gpio_cfg( - pin_number, - NRF_GPIO_PIN_DIR_INPUT, - NRF_GPIO_PIN_INPUT_CONNECT, - pull_config, - NRF_GPIO_PIN_S0S1, - NRF_GPIO_PIN_NOSENSE); + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + pull_config, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); } + __STATIC_INLINE void nrf_gpio_cfg_default(uint32_t pin_number) { nrf_gpio_cfg( - pin_number, - NRF_GPIO_PIN_DIR_INPUT, - NRF_GPIO_PIN_INPUT_DISCONNECT, - NRF_GPIO_PIN_NOPULL, - NRF_GPIO_PIN_S0S1, - NRF_GPIO_PIN_NOSENSE); + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); } + __STATIC_INLINE void nrf_gpio_cfg_watcher(uint32_t pin_number) { + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); /*lint -e{845} // A zero has been given as right argument to operator '|'" */ - uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk; - NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); + uint32_t cnf = reg->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk; + + reg->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos); } + __STATIC_INLINE void nrf_gpio_input_disconnect(uint32_t pin_number) { + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); /*lint -e{845} // A zero has been given as right argument to operator '|'" */ - uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk; - NRF_GPIO->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); + uint32_t cnf = reg->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_INPUT_Msk; + + reg->PIN_CNF[pin_number] = cnf | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); } -__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, nrf_gpio_pin_pull_t pull_config, nrf_gpio_pin_sense_t sense_config) + +__STATIC_INLINE void nrf_gpio_cfg_sense_input(uint32_t pin_number, + nrf_gpio_pin_pull_t pull_config, + nrf_gpio_pin_sense_t sense_config) { nrf_gpio_cfg( - pin_number, - NRF_GPIO_PIN_DIR_INPUT, - NRF_GPIO_PIN_INPUT_CONNECT, - pull_config, - NRF_GPIO_PIN_S0S1, - sense_config); + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + pull_config, + NRF_GPIO_PIN_S0S1, + sense_config); } + __STATIC_INLINE void nrf_gpio_cfg_sense_set(uint32_t pin_number, nrf_gpio_pin_sense_t sense_config) { + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + /*lint -e{845} // A zero has been given as right argument to operator '|'" */ - //uint32_t cnf = NRF_GPIO->PIN_CNF[pin_number] & ~GPIO_PIN_CNF_SENSE_Msk; - NRF_GPIO->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_SENSE_Msk; - NRF_GPIO->PIN_CNF[pin_number] |= (sense_config << GPIO_PIN_CNF_SENSE_Pos); + reg->PIN_CNF[pin_number] &= ~GPIO_PIN_CNF_SENSE_Msk; + reg->PIN_CNF[pin_number] |= (sense_config << GPIO_PIN_CNF_SENSE_Pos); } + __STATIC_INLINE void nrf_gpio_pin_dir_set(uint32_t pin_number, nrf_gpio_pin_dir_t direction) { - if(direction == NRF_GPIO_PIN_DIR_INPUT) + if (direction == NRF_GPIO_PIN_DIR_INPUT) { nrf_gpio_cfg( - pin_number, - NRF_GPIO_PIN_DIR_INPUT, - NRF_GPIO_PIN_INPUT_CONNECT, - NRF_GPIO_PIN_NOPULL, - NRF_GPIO_PIN_S0S1, - NRF_GPIO_PIN_NOSENSE); + pin_number, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_CONNECT, + NRF_GPIO_PIN_NOPULL, + NRF_GPIO_PIN_S0S1, + NRF_GPIO_PIN_NOSENSE); } else { - NRF_GPIO->DIRSET = (1UL << pin_number); + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + reg->DIRSET = (1UL << pin_number); } } + __STATIC_INLINE void nrf_gpio_pin_set(uint32_t pin_number) { - NRF_GPIO->OUTSET = (1UL << pin_number); -} + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); -__STATIC_INLINE void nrf_gpio_pins_set(uint32_t pin_mask) -{ - NRF_GPIO->OUTSET = pin_mask; + nrf_gpio_port_out_set(reg, 1UL << pin_number); } + __STATIC_INLINE void nrf_gpio_pin_clear(uint32_t pin_number) { - NRF_GPIO->OUTCLR = (1UL << pin_number); -} + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); -__STATIC_INLINE void nrf_gpio_pins_clear(uint32_t pin_mask) -{ - NRF_GPIO->OUTCLR = pin_mask; + nrf_gpio_port_out_clear(reg, 1UL << pin_number); } + __STATIC_INLINE void nrf_gpio_pin_toggle(uint32_t pin_number) { - const uint32_t pin_bit = 1UL << pin_number; - const uint32_t pin_state = ((NRF_GPIO->OUT >> pin_number) & 1UL); + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + uint32_t pins_state = reg->OUT; - if (pin_state == 0) - { - // Current state low, set high. - NRF_GPIO->OUTSET = pin_bit; - } - else - { - // Current state high, set low. - NRF_GPIO->OUTCLR = pin_bit; - } + reg->OUTSET = (~pins_state & (1UL << pin_number)); + reg->OUTCLR = (pins_state & (1UL << pin_number)); } + __STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value) { if (value == 0) @@ -585,63 +657,139 @@ __STATIC_INLINE void nrf_gpio_pin_write(uint32_t pin_number, uint32_t value) } } + __STATIC_INLINE uint32_t nrf_gpio_pin_read(uint32_t pin_number) { - return ((NRF_GPIO->IN >> pin_number) & 1UL); + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + return ((nrf_gpio_port_in_read(reg) >> pin_number) & 1UL); } -__STATIC_INLINE uint32_t nrf_gpio_pins_read(void) + +__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin_number) { - return NRF_GPIO->IN; + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + return ((nrf_gpio_port_out_read(reg) >> pin_number) & 1UL); } + __STATIC_INLINE nrf_gpio_pin_sense_t nrf_gpio_pin_sense_get(uint32_t pin_number) { - return (nrf_gpio_pin_sense_t)((NRF_GPIO->PIN_CNF[pin_number] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos); + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + return (nrf_gpio_pin_sense_t)((reg->PIN_CNF[pin_number] & + GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos); } -__STATIC_INLINE void nrf_gpio_word_byte_write(volatile uint32_t * word_address, uint8_t byte_no, uint8_t value) + +__STATIC_INLINE void nrf_gpio_port_dir_output_set(NRF_GPIO_Type * p_reg, uint32_t out_mask) { - *((volatile uint8_t*)(word_address) + byte_no) = value; + p_reg->DIRSET = out_mask; } -__STATIC_INLINE uint8_t nrf_gpio_word_byte_read(const volatile uint32_t* word_address, uint8_t byte_no) + +__STATIC_INLINE void nrf_gpio_port_dir_input_set(NRF_GPIO_Type * p_reg, uint32_t in_mask) { - return (*((const volatile uint8_t*)(word_address) + byte_no)); + p_reg->DIRCLR = in_mask; } -__STATIC_INLINE void nrf_gpio_port_dir_set(nrf_gpio_port_select_t port, nrf_gpio_port_dir_t dir) + +__STATIC_INLINE void nrf_gpio_port_dir_write(NRF_GPIO_Type * p_reg, uint32_t value) { - if (dir == NRF_GPIO_PORT_DIR_OUTPUT) - { - nrf_gpio_word_byte_write(&NRF_GPIO->DIRSET, port, 0xFF); - } - else - { - nrf_gpio_range_cfg_input(port*8, (port+1)*8-1, NRF_GPIO_PIN_NOPULL); - } + p_reg->DIR = value; } -__STATIC_INLINE uint8_t nrf_gpio_port_read(nrf_gpio_port_select_t port) + +__STATIC_INLINE uint32_t nrf_gpio_port_dir_read(NRF_GPIO_Type const * p_reg) +{ + return p_reg->DIR; +} + + +__STATIC_INLINE uint32_t nrf_gpio_port_in_read(NRF_GPIO_Type const * p_reg) +{ + return p_reg->IN; +} + + +__STATIC_INLINE uint32_t nrf_gpio_port_out_read(NRF_GPIO_Type const * p_reg) { - return nrf_gpio_word_byte_read(&NRF_GPIO->IN, port); + return p_reg->OUT; } -__STATIC_INLINE void nrf_gpio_port_write(nrf_gpio_port_select_t port, uint8_t value) + +__STATIC_INLINE void nrf_gpio_port_out_write(NRF_GPIO_Type * p_reg, uint32_t value) { - nrf_gpio_word_byte_write(&NRF_GPIO->OUT, port, value); + p_reg->OUT = value; } -__STATIC_INLINE void nrf_gpio_port_set(nrf_gpio_port_select_t port, uint8_t set_mask) + +__STATIC_INLINE void nrf_gpio_port_out_set(NRF_GPIO_Type * p_reg, uint32_t set_mask) { - nrf_gpio_word_byte_write(&NRF_GPIO->OUTSET, port, set_mask); + p_reg->OUTSET = set_mask; } -__STATIC_INLINE void nrf_gpio_port_clear(nrf_gpio_port_select_t port, uint8_t clr_mask) + +__STATIC_INLINE void nrf_gpio_port_out_clear(NRF_GPIO_Type * p_reg, uint32_t clr_mask) { - nrf_gpio_word_byte_write(&NRF_GPIO->OUTCLR, port, clr_mask); + p_reg->OUTCLR = clr_mask; } -#endif //SUPPRESS_INLINE_IMPLEMENTATION + + +__STATIC_INLINE void nrf_gpio_ports_read(uint32_t start_port, uint32_t length, uint32_t * p_masks) +{ + NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST; + + ASSERT(start_port + length <= GPIO_COUNT); + uint32_t i; + + for (i = start_port; i < (start_port + length); i++) + { + *p_masks = nrf_gpio_port_in_read(gpio_regs[i]); + p_masks++; + } +} + + +#ifdef GPIO_DETECTMODE_DETECTMODE_LDETECT +__STATIC_INLINE void nrf_gpio_latches_read(uint32_t start_port, uint32_t length, uint32_t * p_masks) +{ + NRF_GPIO_Type * gpio_regs[GPIO_COUNT] = GPIO_REG_LIST; + uint32_t i; + + for (i = start_port; i < (start_port + length); i++) + { + *p_masks = gpio_regs[i]->LATCH; + p_masks++; + } +} + + +__STATIC_INLINE uint32_t nrf_gpio_pin_latch_get(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + return (reg->LATCH & (1 << pin_number)) ? 1 : 0; +} + + +__STATIC_INLINE void nrf_gpio_pin_latch_clear(uint32_t pin_number) +{ + NRF_GPIO_Type * reg = nrf_gpio_pin_port_decode(&pin_number); + + reg->LATCH = (1 << pin_number); +} + + +#endif +#endif // SUPPRESS_INLINE_IMPLEMENTATION + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_nrf/hal/nrf_gpiote.h b/components/drivers_nrf/hal/nrf_gpiote.h index e3e998a..df9bd35 100644 --- a/components/drivers_nrf/hal/nrf_gpiote.h +++ b/components/drivers_nrf/hal/nrf_gpiote.h @@ -1,35 +1,66 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_GPIOTE_H__ #define NRF_GPIOTE_H__ +#include "nrf_peripherals.h" #include "nrf.h" #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef GPIOTE_CONFIG_PORT_Msk +#define GPIOTE_CONFIG_PORT_PIN_Msk (GPIOTE_CONFIG_PORT_Msk | GPIOTE_CONFIG_PSEL_Msk) +#else +#define GPIOTE_CONFIG_PORT_PIN_Msk GPIOTE_CONFIG_PSEL_Msk +#endif /** * @defgroup nrf_gpiote_abs GPIOTE abstraction * @{ * @ingroup nrf_gpiote * @brief GPIOTE abstraction for configuration of channels. */ -#ifdef NRF51 -#define NUMBER_OF_GPIO_TE 4 -#elif defined NRF52 -#define NUMBER_OF_GPIO_TE 8 -#else -#error "Chip family not specified" -#endif /** * @enum nrf_gpiote_polarity_t @@ -62,6 +93,32 @@ typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ NRF_GPIOTE_TASKS_OUT_1 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[1]), /**< Out task 1.*/ NRF_GPIOTE_TASKS_OUT_2 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[2]), /**< Out task 2.*/ NRF_GPIOTE_TASKS_OUT_3 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[3]), /**< Out task 3.*/ +#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__) + NRF_GPIOTE_TASKS_OUT_4 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[4]), /**< Out task 4.*/ + NRF_GPIOTE_TASKS_OUT_5 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[5]), /**< Out task 5.*/ + NRF_GPIOTE_TASKS_OUT_6 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[6]), /**< Out task 6.*/ + NRF_GPIOTE_TASKS_OUT_7 = offsetof(NRF_GPIOTE_Type, TASKS_OUT[7]), /**< Out task 7.*/ +#endif +#if defined(GPIOTE_FEATURE_SET_PRESENT) || defined(__SDK_DOXYGEN__) + NRF_GPIOTE_TASKS_SET_0 = offsetof(NRF_GPIOTE_Type, TASKS_SET[0]), /**< Set task 0.*/ + NRF_GPIOTE_TASKS_SET_1 = offsetof(NRF_GPIOTE_Type, TASKS_SET[1]), /**< Set task 1.*/ + NRF_GPIOTE_TASKS_SET_2 = offsetof(NRF_GPIOTE_Type, TASKS_SET[2]), /**< Set task 2.*/ + NRF_GPIOTE_TASKS_SET_3 = offsetof(NRF_GPIOTE_Type, TASKS_SET[3]), /**< Set task 3.*/ + NRF_GPIOTE_TASKS_SET_4 = offsetof(NRF_GPIOTE_Type, TASKS_SET[4]), /**< Set task 4.*/ + NRF_GPIOTE_TASKS_SET_5 = offsetof(NRF_GPIOTE_Type, TASKS_SET[5]), /**< Set task 5.*/ + NRF_GPIOTE_TASKS_SET_6 = offsetof(NRF_GPIOTE_Type, TASKS_SET[6]), /**< Set task 6.*/ + NRF_GPIOTE_TASKS_SET_7 = offsetof(NRF_GPIOTE_Type, TASKS_SET[7]), /**< Set task 7.*/ +#endif +#if defined(GPIOTE_FEATURE_CLR_PRESENT) || defined(__SDK_DOXYGEN__) + NRF_GPIOTE_TASKS_CLR_0 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[0]), /**< Clear task 0.*/ + NRF_GPIOTE_TASKS_CLR_1 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[1]), /**< Clear task 1.*/ + NRF_GPIOTE_TASKS_CLR_2 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[2]), /**< Clear task 2.*/ + NRF_GPIOTE_TASKS_CLR_3 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[3]), /**< Clear task 3.*/ + NRF_GPIOTE_TASKS_CLR_4 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[4]), /**< Clear task 4.*/ + NRF_GPIOTE_TASKS_CLR_5 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[5]), /**< Clear task 5.*/ + NRF_GPIOTE_TASKS_CLR_6 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[6]), /**< Clear task 6.*/ + NRF_GPIOTE_TASKS_CLR_7 = offsetof(NRF_GPIOTE_Type, TASKS_CLR[7]), /**< Clear task 7.*/ +#endif /*lint -restore*/ } nrf_gpiote_tasks_t; @@ -74,6 +131,12 @@ typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ NRF_GPIOTE_EVENTS_IN_1 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[1]), /**< In event 1.*/ NRF_GPIOTE_EVENTS_IN_2 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[2]), /**< In event 2.*/ NRF_GPIOTE_EVENTS_IN_3 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[3]), /**< In event 3.*/ +#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__) + NRF_GPIOTE_EVENTS_IN_4 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[4]), /**< In event 4.*/ + NRF_GPIOTE_EVENTS_IN_5 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[5]), /**< In event 5.*/ + NRF_GPIOTE_EVENTS_IN_6 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[6]), /**< In event 6.*/ + NRF_GPIOTE_EVENTS_IN_7 = offsetof(NRF_GPIOTE_Type, EVENTS_IN[7]), /**< In event 7.*/ +#endif NRF_GPIOTE_EVENTS_PORT = offsetof(NRF_GPIOTE_Type, EVENTS_PORT), /**< Port event.*/ /*lint -restore*/ } nrf_gpiote_events_t; @@ -88,11 +151,25 @@ typedef enum NRF_GPIOTE_INT_IN1_MASK = GPIOTE_INTENSET_IN1_Msk, /**< GPIOTE interrupt from IN1. */ NRF_GPIOTE_INT_IN2_MASK = GPIOTE_INTENSET_IN2_Msk, /**< GPIOTE interrupt from IN2. */ NRF_GPIOTE_INT_IN3_MASK = GPIOTE_INTENSET_IN3_Msk, /**< GPIOTE interrupt from IN3. */ +#if (GPIOTE_CH_NUM > 4) || defined(__SDK_DOXYGEN__) + NRF_GPIOTE_INT_IN4_MASK = GPIOTE_INTENSET_IN4_Msk, /**< GPIOTE interrupt from IN4. */ + NRF_GPIOTE_INT_IN5_MASK = GPIOTE_INTENSET_IN5_Msk, /**< GPIOTE interrupt from IN5. */ + NRF_GPIOTE_INT_IN6_MASK = GPIOTE_INTENSET_IN6_Msk, /**< GPIOTE interrupt from IN6. */ + NRF_GPIOTE_INT_IN7_MASK = GPIOTE_INTENSET_IN7_Msk, /**< GPIOTE interrupt from IN7. */ +#endif NRF_GPIOTE_INT_PORT_MASK = (int)GPIOTE_INTENSET_PORT_Msk, /**< GPIOTE interrupt from PORT event. */ } nrf_gpiote_int_t; #define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\ NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK) +#if (GPIOTE_CH_NUM > 4) +#undef NRF_GPIOTE_INT_IN_MASK +#define NRF_GPIOTE_INT_IN_MASK (NRF_GPIOTE_INT_IN0_MASK | NRF_GPIOTE_INT_IN1_MASK |\ + NRF_GPIOTE_INT_IN2_MASK | NRF_GPIOTE_INT_IN3_MASK |\ + NRF_GPIOTE_INT_IN4_MASK | NRF_GPIOTE_INT_IN5_MASK |\ + NRF_GPIOTE_INT_IN6_MASK | NRF_GPIOTE_INT_IN7_MASK) +#endif + /** * @brief Function for activating a specific GPIOTE task. * @@ -207,7 +284,7 @@ __STATIC_INLINE void nrf_gpiote_task_disable(uint32_t idx); * @param[in] idx Task-Event index. * @param[in] pin Pin associated with event. * @param[in] polarity Transition that should generate an event. - * @param[in] init_val Initial value of pin. + * @param[in] init_val Initial value of the pin. */ __STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin, nrf_gpiote_polarity_t polarity, @@ -283,14 +360,14 @@ __STATIC_INLINE void nrf_gpiote_event_disable(uint32_t idx) __STATIC_INLINE void nrf_gpiote_event_configure(uint32_t idx, uint32_t pin, nrf_gpiote_polarity_t polarity) { - NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PSEL_Msk | GPIOTE_CONFIG_POLARITY_Msk); - NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) | + NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PORT_PIN_Msk | GPIOTE_CONFIG_POLARITY_Msk); + NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk) | ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk); } __STATIC_INLINE uint32_t nrf_gpiote_event_pin_get(uint32_t idx) { - return ((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_PSEL_Msk) >> GPIOTE_CONFIG_PSEL_Pos); + return ((NRF_GPIOTE->CONFIG[idx] & GPIOTE_CONFIG_PORT_PIN_Msk) >> GPIOTE_CONFIG_PSEL_Pos); } __STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx) @@ -301,14 +378,16 @@ __STATIC_INLINE nrf_gpiote_polarity_t nrf_gpiote_event_polarity_get(uint32_t idx __STATIC_INLINE void nrf_gpiote_task_enable(uint32_t idx) { uint32_t final_config = NRF_GPIOTE->CONFIG[idx] | GPIOTE_CONFIG_MODE_Task; +#ifdef NRF51 /* Workaround for the OUTINIT PAN. When nrf_gpiote_task_config() is called a glitch happens on the GPIO if the GPIO in question is already assigned to GPIOTE and the pin is in the correct state in GPIOTE but not in the OUT register. */ - /* Configure channel to Pin31, not connected to the pin, and configure as a tasks that will set it to proper level */ - NRF_GPIOTE->CONFIG[idx] = final_config | ((31 << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk); + /* Configure channel to not existing, not connected to the pin, and configure as a tasks that will set it to proper level */ + NRF_GPIOTE->CONFIG[idx] = final_config | (((31) << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk); __NOP(); __NOP(); __NOP(); +#endif NRF_GPIOTE->CONFIG[idx] = final_config; } @@ -321,18 +400,18 @@ __STATIC_INLINE void nrf_gpiote_task_configure(uint32_t idx, uint32_t pin, nrf_gpiote_polarity_t polarity, nrf_gpiote_outinit_t init_val) { - NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PSEL_Msk | + NRF_GPIOTE->CONFIG[idx] &= ~(GPIOTE_CONFIG_PORT_PIN_Msk | GPIOTE_CONFIG_POLARITY_Msk | GPIOTE_CONFIG_OUTINIT_Msk); - NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PSEL_Msk) | + NRF_GPIOTE->CONFIG[idx] |= ((pin << GPIOTE_CONFIG_PSEL_Pos) & GPIOTE_CONFIG_PORT_PIN_Msk) | ((polarity << GPIOTE_CONFIG_POLARITY_Pos) & GPIOTE_CONFIG_POLARITY_Msk) | ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk); } __STATIC_INLINE void nrf_gpiote_task_force(uint32_t idx, nrf_gpiote_outinit_t init_val) { - NRF_GPIOTE->CONFIG[idx] = (NRF_GPIOTE->CONFIG[idx] & ~GPIOTE_CONFIG_OUTINIT_Msk) + NRF_GPIOTE->CONFIG[idx] = (NRF_GPIOTE->CONFIG[idx] & ~GPIOTE_CONFIG_OUTINIT_Msk) | ((init_val << GPIOTE_CONFIG_OUTINIT_Pos) & GPIOTE_CONFIG_OUTINIT_Msk); } @@ -343,4 +422,9 @@ __STATIC_INLINE void nrf_gpiote_te_default(uint32_t idx) #endif //SUPPRESS_INLINE_IMPLEMENTATION /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_nrf/hal/nrf_i2s.h b/components/drivers_nrf/hal/nrf_i2s.h new file mode 100644 index 0000000..de3a4b3 --- /dev/null +++ b/components/drivers_nrf/hal/nrf_i2s.h @@ -0,0 +1,564 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @defgroup nrf_i2s_hal I2S HAL + * @{ + * @ingroup nrf_i2s + * + * @brief @tagAPI52 Hardware access layer for managing the Inter-IC Sound (I2S) peripheral. + */ + +#ifndef NRF_I2S_H__ +#define NRF_I2S_H__ + +#include +#include +#include + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief This value can be provided as a parameter for the @ref nrf_i2s_pins_set + * function call to specify that a given I2S signal (SDOUT, SDIN, or MCK) + * shall not be connected to a physical pin. + */ +#define NRF_I2S_PIN_NOT_CONNECTED 0xFFFFFFFF + + +/** + * @brief I2S tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_I2S_TASK_START = offsetof(NRF_I2S_Type, TASKS_START), ///< Starts continuous I2S transfer. Also starts the MCK generator if this is enabled. + NRF_I2S_TASK_STOP = offsetof(NRF_I2S_Type, TASKS_STOP) ///< Stops I2S transfer. Also stops the MCK generator. + /*lint -restore*/ +} nrf_i2s_task_t; + +/** + * @brief I2S events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_I2S_EVENT_RXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_RXPTRUPD), ///< The RXD.PTR register has been copied to internal double-buffers. + NRF_I2S_EVENT_TXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_TXPTRUPD), ///< The TXD.PTR register has been copied to internal double-buffers. + NRF_I2S_EVENT_STOPPED = offsetof(NRF_I2S_Type, EVENTS_STOPPED) ///< I2S transfer stopped. + /*lint -restore*/ +} nrf_i2s_event_t; + +/** + * @brief I2S interrupts. + */ +typedef enum +{ + NRF_I2S_INT_RXPTRUPD_MASK = I2S_INTENSET_RXPTRUPD_Msk, ///< Interrupt on RXPTRUPD event. + NRF_I2S_INT_TXPTRUPD_MASK = I2S_INTENSET_TXPTRUPD_Msk, ///< Interrupt on TXPTRUPD event. + NRF_I2S_INT_STOPPED_MASK = I2S_INTENSET_STOPPED_Msk ///< Interrupt on STOPPED event. +} nrf_i2s_int_mask_t; + +/** + * @brief I2S modes of operation. + */ +typedef enum +{ + NRF_I2S_MODE_MASTER = I2S_CONFIG_MODE_MODE_Master, ///< Master mode. + NRF_I2S_MODE_SLAVE = I2S_CONFIG_MODE_MODE_Slave ///< Slave mode. +} nrf_i2s_mode_t; + +/** + * @brief I2S master clock generator settings. + */ +typedef enum +{ + NRF_I2S_MCK_DISABLED = 0, ///< MCK disabled. + // [conversion to 'int' needed to prevent compilers from complaining + // that the provided value (0x80000000UL) is out of range of "int"] + NRF_I2S_MCK_32MDIV2 = (int)I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2, ///< 32 MHz / 2 = 16.0 MHz. + NRF_I2S_MCK_32MDIV3 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV3, ///< 32 MHz / 3 = 10.6666667 MHz. + NRF_I2S_MCK_32MDIV4 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV4, ///< 32 MHz / 4 = 8.0 MHz. + NRF_I2S_MCK_32MDIV5 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV5, ///< 32 MHz / 5 = 6.4 MHz. + NRF_I2S_MCK_32MDIV6 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV6, ///< 32 MHz / 6 = 5.3333333 MHz. + NRF_I2S_MCK_32MDIV8 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8, ///< 32 MHz / 8 = 4.0 MHz. + NRF_I2S_MCK_32MDIV10 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10, ///< 32 MHz / 10 = 3.2 MHz. + NRF_I2S_MCK_32MDIV11 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11, ///< 32 MHz / 11 = 2.9090909 MHz. + NRF_I2S_MCK_32MDIV15 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV15, ///< 32 MHz / 15 = 2.1333333 MHz. + NRF_I2S_MCK_32MDIV16 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16, ///< 32 MHz / 16 = 2.0 MHz. + NRF_I2S_MCK_32MDIV21 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21, ///< 32 MHz / 21 = 1.5238095 MHz. + NRF_I2S_MCK_32MDIV23 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23, ///< 32 MHz / 23 = 1.3913043 MHz. + NRF_I2S_MCK_32MDIV31 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31, ///< 32 MHz / 31 = 1.0322581 MHz. + NRF_I2S_MCK_32MDIV42 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42, ///< 32 MHz / 42 = 0.7619048 MHz. + NRF_I2S_MCK_32MDIV63 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63, ///< 32 MHz / 63 = 0.5079365 MHz. + NRF_I2S_MCK_32MDIV125 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125 ///< 32 MHz / 125 = 0.256 MHz. +} nrf_i2s_mck_t; + +/** + * @brief I2S MCK/LRCK ratios. + */ +typedef enum +{ + NRF_I2S_RATIO_32X = I2S_CONFIG_RATIO_RATIO_32X, ///< LRCK = MCK / 32. + NRF_I2S_RATIO_48X = I2S_CONFIG_RATIO_RATIO_48X, ///< LRCK = MCK / 48. + NRF_I2S_RATIO_64X = I2S_CONFIG_RATIO_RATIO_64X, ///< LRCK = MCK / 64. + NRF_I2S_RATIO_96X = I2S_CONFIG_RATIO_RATIO_96X, ///< LRCK = MCK / 96. + NRF_I2S_RATIO_128X = I2S_CONFIG_RATIO_RATIO_128X, ///< LRCK = MCK / 128. + NRF_I2S_RATIO_192X = I2S_CONFIG_RATIO_RATIO_192X, ///< LRCK = MCK / 192. + NRF_I2S_RATIO_256X = I2S_CONFIG_RATIO_RATIO_256X, ///< LRCK = MCK / 256. + NRF_I2S_RATIO_384X = I2S_CONFIG_RATIO_RATIO_384X, ///< LRCK = MCK / 384. + NRF_I2S_RATIO_512X = I2S_CONFIG_RATIO_RATIO_512X ///< LRCK = MCK / 512. +} nrf_i2s_ratio_t; + +/** + * @brief I2S sample widths. + */ +typedef enum +{ + NRF_I2S_SWIDTH_8BIT = I2S_CONFIG_SWIDTH_SWIDTH_8Bit, ///< 8 bit. + NRF_I2S_SWIDTH_16BIT = I2S_CONFIG_SWIDTH_SWIDTH_16Bit, ///< 16 bit. + NRF_I2S_SWIDTH_24BIT = I2S_CONFIG_SWIDTH_SWIDTH_24Bit ///< 24 bit. +} nrf_i2s_swidth_t; + +/** + * @brief I2S alignments of sample within a frame. + */ +typedef enum +{ + NRF_I2S_ALIGN_LEFT = I2S_CONFIG_ALIGN_ALIGN_Left, ///< Left-aligned. + NRF_I2S_ALIGN_RIGHT = I2S_CONFIG_ALIGN_ALIGN_Right ///< Right-aligned. +} nrf_i2s_align_t; + +/** + * @brief I2S frame formats. + */ +typedef enum +{ + NRF_I2S_FORMAT_I2S = I2S_CONFIG_FORMAT_FORMAT_I2S, ///< Original I2S format. + NRF_I2S_FORMAT_ALIGNED = I2S_CONFIG_FORMAT_FORMAT_Aligned ///< Alternate (left- or right-aligned) format. +} nrf_i2s_format_t; + +/** + * @brief I2S enabled channels. + */ +typedef enum +{ + NRF_I2S_CHANNELS_STEREO = I2S_CONFIG_CHANNELS_CHANNELS_Stereo, ///< Stereo. + NRF_I2S_CHANNELS_LEFT = I2S_CONFIG_CHANNELS_CHANNELS_Left, ///< Left only. + NRF_I2S_CHANNELS_RIGHT = I2S_CONFIG_CHANNELS_CHANNELS_Right ///< Right only. +} nrf_i2s_channels_t; + + +/** + * @brief Function for activating a specific I2S task. + * + * @param[in] p_i2s I2S instance. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_i2s, + nrf_i2s_task_t task); + +/** + * @brief Function for getting the address of a specific I2S task register. + * + * @param[in] p_i2s I2S instance. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_task_t task); + +/** + * @brief Function for clearing a specific I2S event. + * + * @param[in] p_i2s I2S instance. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_i2s, + nrf_i2s_event_t event); + +/** + * @brief Function for checking the state of a specific I2S event. + * + * @param[in] p_i2s I2S instance. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event); + +/** + * @brief Function for getting the address of a specific I2S event register. + * + * @param[in] p_i2s I2S instance. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_i2s I2S instance. + * @param[in] mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_i2s, uint32_t mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_i2s I2S instance. + * @param[in] mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_i2s, uint32_t mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_i2s I2S instance. + * @param[in] i2s_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_int_mask_t i2s_int); + +/** + * @brief Function for enabling the I2S peripheral. + * + * @param[in] p_i2s I2S instance. + */ +__STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_i2s); + +/** + * @brief Function for disabling the I2S peripheral. + * + * @param[in] p_i2s I2S instance. + */ +__STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_i2s); + +/** + * @brief Function for configuring I2S pins. + * + * Usage of the SDOUT, SDIN, and MCK signals is optional. + * If a given signal is not needed, pass the @ref NRF_I2S_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_i2s I2S instance. + * @param[in] sck_pin SCK pin number. + * @param[in] lrck_pin LRCK pin number. + * @param[in] mck_pin MCK pin number. + * @param[in] sdout_pin SDOUT pin number. + * @param[in] sdin_pin SDIN pin number. + */ +__STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_i2s, + uint32_t sck_pin, + uint32_t lrck_pin, + uint32_t mck_pin, + uint32_t sdout_pin, + uint32_t sdin_pin); + +/** + * @brief Function for setting the I2S peripheral configuration. + * + * @param[in] p_i2s I2S instance. + * @param[in] mode Mode of operation (master or slave). + * @param[in] format I2S frame format. + * @param[in] alignment Alignment of sample within a frame. + * @param[in] sample_width Sample width. + * @param[in] channels Enabled channels. + * @param[in] mck_setup Master clock generator setup. + * @param[in] ratio MCK/LRCK ratio. + * + * @retval true If the configuration has been set successfully. + * @retval false If the requested configuration is not allowed. + */ +__STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_i2s, + nrf_i2s_mode_t mode, + nrf_i2s_format_t format, + nrf_i2s_align_t alignment, + nrf_i2s_swidth_t sample_width, + nrf_i2s_channels_t channels, + nrf_i2s_mck_t mck_setup, + nrf_i2s_ratio_t ratio); + +/** + * @brief Function for setting up the I2S transfer. + * + * This function sets up the RX and TX buffers and enables reception and/or + * transmission accordingly. If the transfer in a given direction is not + * required, pass NULL instead of the pointer to the corresponding buffer. + * + * @param[in] p_i2s I2S instance. + * @param[in] size Size of the buffers (in 32-bit words). + * @param[in] p_rx_buffer Pointer to the receive buffer. + * Pass NULL to disable reception. + * @param[in] p_tx_buffer Pointer to the transmit buffer. + * Pass NULL to disable transmission. + */ +__STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_i2s, + uint16_t size, + uint32_t * p_rx_buffer, + uint32_t const * p_tx_buffer); + +/** + * @brief Function for setting the pointer to the receive buffer. + * + * @note The size of the buffer can be set only by calling + * @ref nrf_i2s_transfer_set. + * + * @param[in] p_i2s I2S instance. + * @param[in] p_buffer Pointer to the receive buffer. + */ +__STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t * p_buffer); + +/** + * @brief Function for getting the pointer to the receive buffer. + * + * @param[in] p_i2s I2S instance. + * + * @return Pointer to the receive buffer. + */ +__STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_i2s); + +/** + * @brief Function for setting the pointer to the transmit buffer. + * + * @note The size of the buffer can be set only by calling + * @ref nrf_i2s_transfer_set. + * + * @param[in] p_i2s I2S instance. + * @param[in] p_buffer Pointer to the transmit buffer. + */ +__STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t const * p_buffer); + +/** + * @brief Function for getting the pointer to the transmit buffer. + * + * @param[in] p_i2s I2S instance. + * + * @return Pointer to the transmit buffer. + */ +__STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_i2s); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_i2s, + nrf_i2s_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_task_t task) +{ + return ((uint32_t)p_i2s + (uint32_t)task); +} + +__STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_i2s, + nrf_i2s_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_i2s + (uint32_t)event); +} + +__STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_i2s, + nrf_i2s_event_t event) +{ + return ((uint32_t)p_i2s + (uint32_t)event); +} + +__STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_i2s, uint32_t mask) +{ + p_i2s->INTENSET = mask; +} + +__STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_i2s, uint32_t mask) +{ + p_i2s->INTENCLR = mask; +} + +__STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_i2s, + nrf_i2s_int_mask_t i2s_int) +{ + return (bool)(p_i2s->INTENSET & i2s_int); +} + +__STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_i2s) +{ + p_i2s->ENABLE = (I2S_ENABLE_ENABLE_Enabled << I2S_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_i2s) +{ + p_i2s->ENABLE = (I2S_ENABLE_ENABLE_Disabled << I2S_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_i2s, + uint32_t sck_pin, + uint32_t lrck_pin, + uint32_t mck_pin, + uint32_t sdout_pin, + uint32_t sdin_pin) +{ + p_i2s->PSEL.SCK = sck_pin; + p_i2s->PSEL.LRCK = lrck_pin; + p_i2s->PSEL.MCK = mck_pin; + p_i2s->PSEL.SDOUT = sdout_pin; + p_i2s->PSEL.SDIN = sdin_pin; +} + +__STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_i2s, + nrf_i2s_mode_t mode, + nrf_i2s_format_t format, + nrf_i2s_align_t alignment, + nrf_i2s_swidth_t sample_width, + nrf_i2s_channels_t channels, + nrf_i2s_mck_t mck_setup, + nrf_i2s_ratio_t ratio) +{ + if (mode == NRF_I2S_MODE_MASTER) + { + // The MCK/LRCK ratio shall be a multiple of 2 * sample width. + if (((sample_width == NRF_I2S_SWIDTH_16BIT) && + (ratio == NRF_I2S_RATIO_48X)) + || + ((sample_width == NRF_I2S_SWIDTH_24BIT) && + ((ratio == NRF_I2S_RATIO_32X) || + (ratio == NRF_I2S_RATIO_64X) || + (ratio == NRF_I2S_RATIO_128X) || + (ratio == NRF_I2S_RATIO_256X) || + (ratio == NRF_I2S_RATIO_512X)))) + { + return false; + } + } + + p_i2s->CONFIG.MODE = mode; + p_i2s->CONFIG.FORMAT = format; + p_i2s->CONFIG.ALIGN = alignment; + p_i2s->CONFIG.SWIDTH = sample_width; + p_i2s->CONFIG.CHANNELS = channels; + p_i2s->CONFIG.RATIO = ratio; + + if (mck_setup == NRF_I2S_MCK_DISABLED) + { + p_i2s->CONFIG.MCKEN = + (I2S_CONFIG_MCKEN_MCKEN_Disabled << I2S_CONFIG_MCKEN_MCKEN_Pos); + } + else + { + p_i2s->CONFIG.MCKFREQ = mck_setup; + p_i2s->CONFIG.MCKEN = + (I2S_CONFIG_MCKEN_MCKEN_Enabled << I2S_CONFIG_MCKEN_MCKEN_Pos); + } + + return true; +} + +__STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_i2s, + uint16_t size, + uint32_t * p_buffer_rx, + uint32_t const * p_buffer_tx) +{ + p_i2s->RXTXD.MAXCNT = size; + + nrf_i2s_rx_buffer_set(p_i2s, p_buffer_rx); + p_i2s->CONFIG.RXEN = (p_buffer_rx != NULL) ? 1 : 0; + + nrf_i2s_tx_buffer_set(p_i2s, p_buffer_tx); + p_i2s->CONFIG.TXEN = (p_buffer_tx != NULL) ? 1 : 0; +} + +__STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t * p_buffer) +{ + p_i2s->RXD.PTR = (uint32_t)p_buffer; +} + +__STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_i2s) +{ + return (uint32_t *)(p_i2s->RXD.PTR); +} + +__STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_i2s, + uint32_t const * p_buffer) +{ + p_i2s->TXD.PTR = (uint32_t)p_buffer; +} + +__STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_i2s) +{ + return (uint32_t *)(p_i2s->TXD.PTR); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_I2S_H__ + +/** @} */ diff --git a/components/drivers_nrf/hal/nrf_lpcomp.h b/components/drivers_nrf/hal/nrf_lpcomp.h index 73e4662..4d4c2e5 100644 --- a/components/drivers_nrf/hal/nrf_lpcomp.h +++ b/components/drivers_nrf/hal/nrf_lpcomp.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -26,18 +54,23 @@ */ #include "nrf.h" +#include "nrf_peripherals.h" #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @enum nrf_lpcomp_ref_t * @brief LPCOMP reference selection. */ typedef enum { -#ifdef NRF51 +#if (LPCOMP_REFSEL_RESOLUTION == 8) || defined(__SDK_DOXYGEN__) NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_SupplyOneEighthPrescaling, /**< Use supply with a 1/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_SupplyTwoEighthsPrescaling, /**< Use supply with a 2/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_SupplyThreeEighthsPrescaling, /**< Use supply with a 3/8 prescaler as reference. */ @@ -45,7 +78,7 @@ typedef enum NRF_LPCOMP_REF_SUPPLY_5_8 = LPCOMP_REFSEL_REFSEL_SupplyFiveEighthsPrescaling, /**< Use supply with a 5/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_SupplySixEighthsPrescaling, /**< Use supply with a 6/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_SupplySevenEighthsPrescaling, /**< Use supply with a 7/8 prescaler as reference. */ -#elif defined NRF52 +#elif (LPCOMP_REFSEL_RESOLUTION == 16) || defined(__SDK_DOXYGEN__) NRF_LPCOMP_REF_SUPPLY_1_8 = LPCOMP_REFSEL_REFSEL_Ref1_8Vdd, /**< Use supply with a 1/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_2_8 = LPCOMP_REFSEL_REFSEL_Ref2_8Vdd, /**< Use supply with a 2/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_3_8 = LPCOMP_REFSEL_REFSEL_Ref3_8Vdd, /**< Use supply with a 3/8 prescaler as reference. */ @@ -54,13 +87,13 @@ typedef enum NRF_LPCOMP_REF_SUPPLY_6_8 = LPCOMP_REFSEL_REFSEL_Ref6_8Vdd, /**< Use supply with a 6/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_7_8 = LPCOMP_REFSEL_REFSEL_Ref7_8Vdd, /**< Use supply with a 7/8 prescaler as reference. */ NRF_LPCOMP_REF_SUPPLY_1_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 1/16 prescaler as reference. */ - NRF_LPCOMP_REF_SUPPLY_3_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 3/16 prescaler as reference. */ - NRF_LPCOMP_REF_SUPPLY_5_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 5/16 prescaler as reference. */ - NRF_LPCOMP_REF_SUPPLY_7_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 7/16 prescaler as reference. */ - NRF_LPCOMP_REF_SUPPLY_9_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 9/16 prescaler as reference. */ - NRF_LPCOMP_REF_SUPPLY_11_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 11/16 prescaler as reference. */ - NRF_LPCOMP_REF_SUPPLY_13_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 13/16 prescaler as reference. */ - NRF_LPCOMP_REF_SUPPLY_15_16 = LPCOMP_REFSEL_REFSEL_Ref1_16Vdd, /**< Use supply with a 15/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_3_16 = LPCOMP_REFSEL_REFSEL_Ref3_16Vdd, /**< Use supply with a 3/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_5_16 = LPCOMP_REFSEL_REFSEL_Ref5_16Vdd, /**< Use supply with a 5/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_7_16 = LPCOMP_REFSEL_REFSEL_Ref7_16Vdd, /**< Use supply with a 7/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_9_16 = LPCOMP_REFSEL_REFSEL_Ref9_16Vdd, /**< Use supply with a 9/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_11_16 = LPCOMP_REFSEL_REFSEL_Ref11_16Vdd, /**< Use supply with a 11/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_13_16 = LPCOMP_REFSEL_REFSEL_Ref13_16Vdd, /**< Use supply with a 13/16 prescaler as reference. */ + NRF_LPCOMP_REF_SUPPLY_15_16 = LPCOMP_REFSEL_REFSEL_Ref15_16Vdd, /**< Use supply with a 15/16 prescaler as reference. */ #endif NRF_LPCOMP_REF_EXT_REF0 = LPCOMP_REFSEL_REFSEL_ARef | (LPCOMP_EXTREFSEL_EXTREFSEL_AnalogReference0 << 16), /**< External reference 0. */ @@ -132,12 +165,26 @@ typedef enum NRF_LPCOMP_SHORT_READY_SAMPLE_MASK = LPCOMP_SHORTS_READY_SAMPLE_Msk /*!< Short between READY event and SAMPLE task. */ } nrf_lpcomp_short_mask_t; +#ifdef NRF52_SERIES +/** + * @enum nrf_lpcomp_hysteresis_t + * @brief LPCOMP hysteresis. + */ +typedef enum +{ + NRF_LPCOMP_HYST_NOHYST = LPCOMP_HYST_HYST_NoHyst, /**< Comparator hysteresis disabled. */ + NRF_LPCOMP_HYST_50mV = LPCOMP_HYST_HYST_Hyst50mV /**< Comparator hysteresis enabled (typ. 50 mV). */ +}nrf_lpcomp_hysteresis_t; +#endif // NRF52 /** @brief LPCOMP configuration. */ typedef struct { - nrf_lpcomp_ref_t reference; /**< LPCOMP reference. */ - nrf_lpcomp_detect_t detection; /**< LPCOMP detection type. */ + nrf_lpcomp_ref_t reference; /**< LPCOMP reference. */ + nrf_lpcomp_detect_t detection; /**< LPCOMP detection type. */ +#ifdef NRF52_SERIES + nrf_lpcomp_hysteresis_t hyst; /**< LPCOMP hysteresis. */ +#endif // NRF52 } nrf_lpcomp_config_t; /** Default LPCOMP configuration. */ @@ -165,11 +212,14 @@ __STATIC_INLINE void nrf_lpcomp_configure(const nrf_lpcomp_config_t * p_config) NRF_LPCOMP->EXTREFSEL = (extref << LPCOMP_EXTREFSEL_EXTREFSEL_Pos) & LPCOMP_EXTREFSEL_EXTREFSEL_Msk; } - NRF_LPCOMP->ANADETECT = + NRF_LPCOMP->ANADETECT = (p_config->detection << LPCOMP_ANADETECT_ANADETECT_Pos) & LPCOMP_ANADETECT_ANADETECT_Msk; - NRF_LPCOMP->SHORTS = 0; - NRF_LPCOMP->INTENCLR = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk | - LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk; +#ifdef NRF52_SERIES + NRF_LPCOMP->HYST = ((p_config->hyst) << LPCOMP_HYST_HYST_Pos) & LPCOMP_HYST_HYST_Msk; +#endif + NRF_LPCOMP->SHORTS = 0; + NRF_LPCOMP->INTENCLR = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk | + LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk; } @@ -259,7 +309,7 @@ __STATIC_INLINE void nrf_lpcomp_int_disable(uint32_t lpcomp_int_mask) /** - * @brief Function for getting the enabled interrupts of LCOMP. + * @brief Function for getting the enabled interrupts of LPCOMP. * * @param[in] lpcomp_int_mask Mask of interrupts to be checked. * @@ -345,6 +395,10 @@ __STATIC_INLINE void nrf_lpcomp_task_trigger(nrf_lpcomp_task_t lpcomp_task) __STATIC_INLINE void nrf_lpcomp_event_clear(nrf_lpcomp_event_t lpcomp_event) { *( (volatile uint32_t *)( (uint8_t *)NRF_LPCOMP + lpcomp_event) ) = 0; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_LPCOMP + lpcomp_event)); + (void)dummy; +#endif } @@ -364,4 +418,9 @@ __STATIC_INLINE bool nrf_lpcomp_event_check(nrf_lpcomp_event_t lpcomp_event) *@} **/ + +#ifdef __cplusplus +} +#endif + #endif /* NRF_LPCOMP_H_ */ diff --git a/components/drivers_nrf/hal/nrf_nvmc.c b/components/drivers_nrf/hal/nrf_nvmc.c index 34d5880..a487408 100644 --- a/components/drivers_nrf/hal/nrf_nvmc.c +++ b/components/drivers_nrf/hal/nrf_nvmc.c @@ -1,117 +1,144 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -* $LastChangedRevision: 17685 $ -*/ - -/** +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 - *@brief NMVC driver implementation + *@brief NMVC driver implementation */ -#include "stdbool.h" +#include #include "nrf.h" #include "nrf_nvmc.h" void nrf_nvmc_page_erase(uint32_t address) -{ - // Enable erase. - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } - - // Erase the page - NRF_NVMC->ERASEPAGE = address; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } - - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } +{ + // Enable erase. + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Een; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + // Erase the page + NRF_NVMC->ERASEPAGE = address; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } } void nrf_nvmc_write_byte(uint32_t address, uint8_t value) { - uint32_t byte_shift = address & (uint32_t)0x03; - uint32_t address32 = address & ~byte_shift; // Address to the word this byte is in. - uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3))); - value32 = value32 + ((uint32_t)value << (byte_shift << 3)); - - // Enable write. - NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos); - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } - - *(uint32_t*)address32 = value32; - while(NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } - - NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos); - { - } + uint32_t byte_shift = address & (uint32_t)0x03; + uint32_t address32 = address & ~byte_shift; // Address to the word this byte is in. + uint32_t value32 = (*(uint32_t*)address32 & ~((uint32_t)0xFF << (byte_shift << (uint32_t)3))); + value32 = value32 + ((uint32_t)value << (byte_shift << 3)); + + // Enable write. + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos); + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + *(uint32_t*)address32 = value32; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } + + NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos); + { + } } void nrf_nvmc_write_word(uint32_t address, uint32_t value) { - // Enable write. - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){ - } - - *(uint32_t*)address = value; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){ - } - - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } + // Enable write. + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){ + } + + *(uint32_t*)address = value; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){ + } + + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } } void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_bytes) { - uint32_t i; - for(i=0;iCONFIG = NVMC_CONFIG_WEN_Wen; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } - - for(i=0;iCONFIG = NVMC_CONFIG_WEN_Wen; while (NRF_NVMC->READY == NVMC_READY_READY_Busy) { } - } - NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy) - { - } + for (i=0;iREADY == NVMC_READY_READY_Busy) + { + } + } + + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy) + { + } } diff --git a/components/drivers_nrf/hal/nrf_nvmc.h b/components/drivers_nrf/hal/nrf_nvmc.h index c1d7e41..4ab8638 100644 --- a/components/drivers_nrf/hal/nrf_nvmc.h +++ b/components/drivers_nrf/hal/nrf_nvmc.h @@ -1,14 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic - * Semiconductor ASA.Terms and conditions of usage are described in detail - * in NORDIC 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. - * - * $LastChangedRevision: 17685 $ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -21,6 +48,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @defgroup nrf_nvmc Non-volatile memory controller @@ -39,7 +70,7 @@ * @brief Erase a page in flash. This is required before writing to any * address in the page. * - * @param address Start address of the page. + * @param address Start address of the page. */ void nrf_nvmc_page_erase(uint32_t address); @@ -57,7 +88,7 @@ void nrf_nvmc_write_byte(uint32_t address , uint8_t value); /** - * @brief Write a 32-bit word to flash. + * @brief Write a 32-bit word to flash. * @param address Address to write to. * @param value Value to write. */ @@ -76,7 +107,7 @@ void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_b /** * @brief Write consecutive words to flash. - * + * * @param address Address to write to. * @param src Pointer to data to copy from. * @param num_words Number of bytes in src to write. @@ -84,6 +115,11 @@ void nrf_nvmc_write_bytes(uint32_t address, const uint8_t * src, uint32_t num_b void nrf_nvmc_write_words(uint32_t address, const uint32_t * src, uint32_t num_words); + +#ifdef __cplusplus +} +#endif + #endif // NRF_NVMC_H__ /** @} */ diff --git a/components/drivers_nrf/hal/nrf_pdm.h b/components/drivers_nrf/hal/nrf_pdm.h new file mode 100644 index 0000000..4d8d181 --- /dev/null +++ b/components/drivers_nrf/hal/nrf_pdm.h @@ -0,0 +1,398 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_PDM_H_ +#define NRF_PDM_H_ + +/** + * @defgroup nrf_pdm_hal PDM HAL + * @{ + * @ingroup nrf_pdm + * + * @brief @tagAPI52 Hardware abstraction layer for accessing the pulse density modulation (PDM) peripheral. + */ + +#include +#include +#include "nrf.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define NRF_PDM_GAIN_MINIMUM 0x00 +#define NRF_PDM_GAIN_DEFAULT 0x28 +#define NRF_PDM_GAIN_MAXIMUM 0x50 + +typedef uint8_t nrf_pdm_gain_t; + + +/** + * @brief PDM tasks. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_PDM_TASK_START = offsetof(NRF_PDM_Type, TASKS_START), ///< Starts continuous PDM transfer. + NRF_PDM_TASK_STOP = offsetof(NRF_PDM_Type, TASKS_STOP) ///< Stops PDM transfer. +} nrf_pdm_task_t; + + +/** + * @brief PDM events. + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_PDM_EVENT_STARTED = offsetof(NRF_PDM_Type, EVENTS_STARTED), ///< PDM transfer has started. + NRF_PDM_EVENT_STOPPED = offsetof(NRF_PDM_Type, EVENTS_STOPPED), ///< PDM transfer has finished. + NRF_PDM_EVENT_END = offsetof(NRF_PDM_Type, EVENTS_END) ///< The PDM has written the last sample specified by SAMPLE.MAXCNT (or the last sample after a STOP task has been received) to Data RAM. +} nrf_pdm_event_t; + + +/** + * @brief PDM interrupt masks. + */ +typedef enum +{ + NRF_PDM_INT_STARTED = PDM_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event. + NRF_PDM_INT_STOPPED = PDM_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event. + NRF_PDM_INT_END = PDM_INTENSET_END_Msk ///< Interrupt on EVENTS_END event. +} nrf_pdm_int_mask_t; + +/** + * @brief PDM clock frequency. + */ +typedef enum +{ + NRF_PDM_FREQ_1000K = PDM_PDMCLKCTRL_FREQ_1000K, ///< PDM_CLK = 1.000 MHz. + NRF_PDM_FREQ_1032K = PDM_PDMCLKCTRL_FREQ_Default, ///< PDM_CLK = 1.032 MHz. + NRF_PDM_FREQ_1067K = PDM_PDMCLKCTRL_FREQ_1067K ///< PDM_CLK = 1.067 MHz. +} nrf_pdm_freq_t; + + +/** + * @brief PDM operation mode. + */ +typedef enum +{ + NRF_PDM_MODE_STEREO = PDM_MODE_OPERATION_Stereo, ///< Sample and store one pair (Left + Right) of 16-bit samples per RAM word. + NRF_PDM_MODE_MONO = PDM_MODE_OPERATION_Mono ///< Sample and store two successive Left samples (16 bit each) per RAM word. +} nrf_pdm_mode_t; + + +/** + * @brief PDM sampling mode. + */ +typedef enum +{ + NRF_PDM_EDGE_LEFTFALLING = PDM_MODE_EDGE_LeftFalling, ///< Left (or mono) is sampled on falling edge of PDM_CLK. + NRF_PDM_EDGE_LEFTRISING = PDM_MODE_EDGE_LeftRising ///< Left (or mono) is sampled on rising edge of PDM_CLK. +} nrf_pdm_edge_t; + + +/** + * @brief Function for triggering a PDM task. + * + * @param[in] pdm_task PDM task. + */ +__STATIC_INLINE void nrf_pdm_task_trigger(nrf_pdm_task_t pdm_task) +{ + *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_task)) = 0x1UL; +} + + +/** + * @brief Function for getting the address of a PDM task register. + * + * @param[in] pdm_task PDM task. + * + * @return Address of the specified PDM task. + */ +__STATIC_INLINE uint32_t nrf_pdm_task_address_get(nrf_pdm_task_t pdm_task) +{ + return (uint32_t)((uint8_t *)NRF_PDM + (uint32_t)pdm_task); +} + + +/** + * @brief Function for getting the state of a PDM event. + * + * @param[in] pdm_event PDM event. + * + * @return State of the specified PDM event. + */ +__STATIC_INLINE bool nrf_pdm_event_check(nrf_pdm_event_t pdm_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event); +} + + +/** + * @brief Function for clearing a PDM event. + * + * @param[in] pdm_event PDM event. + */ +__STATIC_INLINE void nrf_pdm_event_clear(nrf_pdm_event_t pdm_event) +{ + *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event)); + (void)dummy; +#endif +} + + +/** + * @brief Function for getting the address of a PDM event register. + * + * @param[in] pdm_event PDM event. + * + * @return Address of the specified PDM event. + */ +__STATIC_INLINE volatile uint32_t * nrf_pdm_event_address_get(nrf_pdm_event_t pdm_event) +{ + return (volatile uint32_t *)((uint8_t *)NRF_PDM + (uint32_t)pdm_event); +} + + +/** + * @brief Function for enabling PDM interrupts. + * + * @param[in] pdm_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_pdm_int_enable(uint32_t pdm_int_mask) +{ + NRF_PDM->INTENSET = pdm_int_mask; +} + + +/** + * @brief Function for retrieving the state of PDM interrupts. + * + * @param[in] pdm_int_mask Interrupts to check. + * + * @retval true If all specified interrupts are enabled. + * @retval false If at least one of the given interrupts is not enabled. + */ +__STATIC_INLINE bool nrf_pdm_int_enable_check(uint32_t pdm_int_mask) +{ + return (bool)(NRF_PDM->INTENSET & pdm_int_mask); +} + + +/** + * @brief Function for disabling interrupts. + * + * @param pdm_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_pdm_int_disable(uint32_t pdm_int_mask) +{ + NRF_PDM->INTENCLR = pdm_int_mask; +} + + +/** + * @brief Function for enabling the PDM peripheral. + * + * The PDM peripheral must be enabled before use. + */ +__STATIC_INLINE void nrf_pdm_enable(void) +{ + NRF_PDM->ENABLE = (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos); +} + + +/** + * @brief Function for disabling the PDM peripheral. + */ +__STATIC_INLINE void nrf_pdm_disable(void) +{ + NRF_PDM->ENABLE = (PDM_ENABLE_ENABLE_Disabled << PDM_ENABLE_ENABLE_Pos); +} + + +/** + * @brief Function for checking if the PDM peripheral is enabled. + * + * @retval true If the PDM peripheral is enabled. + * @retval false If the PDM peripheral is not enabled. + */ +__STATIC_INLINE bool nrf_pdm_enable_check(void) +{ + return (NRF_PDM->ENABLE == (PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos)); +} + + +/** + * @brief Function for setting the PDM operation mode. + * + * @param[in] pdm_mode PDM operation mode. + * @param[in] pdm_edge PDM sampling mode. + */ +__STATIC_INLINE void nrf_pdm_mode_set(nrf_pdm_mode_t pdm_mode, nrf_pdm_edge_t pdm_edge) +{ + NRF_PDM->MODE = ((pdm_mode << PDM_MODE_OPERATION_Pos) & PDM_MODE_OPERATION_Msk) + | ((pdm_edge << PDM_MODE_EDGE_Pos) & PDM_MODE_EDGE_Msk); +} + + +/** + * @brief Function for getting the PDM operation mode. + * + * @param[out] p_pdm_mode PDM operation mode. + * @param[out] p_pdm_edge PDM sampling mode. + */ +__STATIC_INLINE void nrf_pdm_mode_get(nrf_pdm_mode_t * p_pdm_mode, nrf_pdm_edge_t * p_pdm_edge) +{ + uint32_t mode = NRF_PDM->MODE; + *p_pdm_mode = (nrf_pdm_mode_t)((mode & PDM_MODE_OPERATION_Msk ) >> PDM_MODE_OPERATION_Pos); + *p_pdm_edge = (nrf_pdm_edge_t)((mode & PDM_MODE_EDGE_Msk ) >> PDM_MODE_EDGE_Pos); +} + + +/** + * @brief Function for setting the PDM clock frequency. + * + * @param[in] pdm_freq PDM clock frequency. + */ +__STATIC_INLINE void nrf_pdm_clock_set(nrf_pdm_freq_t pdm_freq) +{ + NRF_PDM->PDMCLKCTRL = ((pdm_freq << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk); +} + + +/** + * @brief Function for getting the PDM clock frequency. + */ +__STATIC_INLINE nrf_pdm_freq_t nrf_pdm_clock_get(void) +{ + return (nrf_pdm_freq_t) ((NRF_PDM->PDMCLKCTRL << PDM_PDMCLKCTRL_FREQ_Pos) & PDM_PDMCLKCTRL_FREQ_Msk); +} + + +/** + * @brief Function for setting up the PDM pins. + * + * @param[in] psel_clk CLK pin number. + * @param[in] psel_din DIN pin number. + */ +__STATIC_INLINE void nrf_pdm_psel_connect(uint32_t psel_clk, uint32_t psel_din) +{ + NRF_PDM->PSEL.CLK = psel_clk; + NRF_PDM->PSEL.DIN = psel_din; +} + +/** + * @brief Function for disconnecting the PDM pins. + */ +__STATIC_INLINE void nrf_pdm_psel_disconnect() +{ + NRF_PDM->PSEL.CLK = ((PDM_PSEL_CLK_CONNECT_Disconnected << PDM_PSEL_CLK_CONNECT_Pos) + & PDM_PSEL_CLK_CONNECT_Msk); + NRF_PDM->PSEL.DIN = ((PDM_PSEL_DIN_CONNECT_Disconnected << PDM_PSEL_DIN_CONNECT_Pos) + & PDM_PSEL_DIN_CONNECT_Msk); +} + + +/** + * @brief Function for setting the PDM gain. + * + * @param[in] gain_l Left channel gain. + * @param[in] gain_r Right channel gain. + */ +__STATIC_INLINE void nrf_pdm_gain_set(nrf_pdm_gain_t gain_l, nrf_pdm_gain_t gain_r) +{ + NRF_PDM->GAINL = gain_l; + NRF_PDM->GAINR = gain_r; +} + + +/** + * @brief Function for getting the PDM gain. + * + * @param[out] p_gain_l Left channel gain. + * @param[out] p_gain_r Right channel gain. + */ +__STATIC_INLINE void nrf_pdm_gain_get(nrf_pdm_gain_t * p_gain_l, nrf_pdm_gain_t * p_gain_r) +{ + *p_gain_l = NRF_PDM->GAINL; + *p_gain_r = NRF_PDM->GAINR; +} + + +/** + * @brief Function for setting the PDM sample buffer. + * + * @param[in] p_buffer Pointer to the RAM address where samples should be written with EasyDMA. + * @param[in] num Number of samples to allocate memory for in EasyDMA mode. + * + * The amount of allocated RAM depends on the operation mode. + * - For stereo mode: N 32-bit words. + * - For mono mode: Ceil(N/2) 32-bit words. + */ +__STATIC_INLINE void nrf_pdm_buffer_set(uint32_t * p_buffer, uint32_t num) +{ + NRF_PDM->SAMPLE.PTR = (uint32_t)p_buffer; + NRF_PDM->SAMPLE.MAXCNT = num; +} + +/** + * @brief Function for getting the current PDM sample buffer address. + * + * @return Pointer to the current sample buffer. + */ +__STATIC_INLINE uint32_t * nrf_pdm_buffer_get() +{ + return (uint32_t *)NRF_PDM->SAMPLE.PTR; +} + + +/** + *@} + **/ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_PDM_H_ */ diff --git a/components/drivers_nrf/hal/nrf_peripherals.h b/components/drivers_nrf/hal/nrf_peripherals.h new file mode 100644 index 0000000..3e56bce --- /dev/null +++ b/components/drivers_nrf/hal/nrf_peripherals.h @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_PERIPHERALS_H +#define NRF_PERIPHERALS_H + +/*lint ++flb "Enter library region */ + +#ifdef NRF51422 +#include "nrf51422_peripherals.h" +#endif + +#ifdef NRF51802 +#include "nrf51802_peripherals.h" +#endif + +#ifdef NRF51822 +#include "nrf51822_peripherals.h" +#endif + +#ifdef NRF52832 +#include "nrf52832_peripherals.h" +#endif + +#ifdef NRF52840_XXAA +#include "nrf52840_peripherals.h" +#endif + + +/*lint --flb "Leave library region" */ + +#endif /* NRF_PERIPHERALS_H */ + diff --git a/components/drivers_nrf/hal/nrf_power.h b/components/drivers_nrf/hal/nrf_power.h new file mode 100644 index 0000000..6d5bb7a --- /dev/null +++ b/components/drivers_nrf/hal/nrf_power.h @@ -0,0 +1,1039 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_POWER_H__ +#define NRF_POWER_H__ + +/** + * @ingroup nrf_power + * @defgroup nrf_power_hal POWER HAL + * @{ + * + * Hardware access layer for (POWER) peripheral. + */ +#include "nrf.h" +#include "sdk_config.h" +#include "nordic_common.h" +#include "nrf_assert.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name The implemented functionality + * @{ + * + * Macros that defines functionality that is implemented into POWER peripheral. + */ +#if defined(POWER_INTENSET_SLEEPENTER_Msk) || defined(__SDK_DOXYGEN__) +/** + * @brief The fact that sleep events are present + * + * In some MCUs there is possibility to process sleep entering and exiting + * events. + */ +#define NRF_POWER_HAS_SLEEPEVT 1 +#else +#define NRF_POWER_HAS_SLEEPEVT 0 +#endif + +#if defined(POWER_RAM_POWER_S0POWER_Msk) || defined(__SDK_DOXYGEN__) +/** + * @brief The fact that RAMPOWER registers are present + * + * After nRF51, new way to manage RAM power was implemented. + * Special registers, one for every RAM block that makes it possible to + * power ON or OFF RAM segments and turn ON and OFF RAM retention in system OFF + * state. + */ +#define NRF_POWER_HAS_RAMPOWER_REGS 1 +#else +#define NRF_POWER_HAS_RAMPOWER_REGS 0 +#endif + +#if defined(POWER_POFCON_THRESHOLDVDDH_Msk) || defined(__SDK_DOXYGEN__) +/** + * @brief Auxiliary definition to mark the fact that VDDH is present + * + * This definition can be used in a code to decide if the part with VDDH + * related settings should be implemented. + */ +#define NRF_POWER_HAS_VDDH 1 +#else +#define NRF_POWER_HAS_VDDH 0 +#endif + +#if defined(POWER_USBREGSTATUS_VBUSDETECT_Msk) || defined(__SDK_DOXYGEN__) +/** + * @brief The fact that power module manages USB regulator + * + * In devices that have USB, power peripheral manages also connection + * detection and USB power regulator, that converts 5 V to 3.3 V + * used by USBD peripheral. + */ +#define NRF_POWER_HAS_USBREG 1 +#else +#define NRF_POWER_HAS_USBREG 0 +#endif +/** @} */ + +/* ------------------------------------------------------------------------------------------------ + * Begin of automatically generated part + * ------------------------------------------------------------------------------------------------ + */ + +/** + * @brief POWER tasks + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_POWER_TASK_CONSTLAT = offsetof(NRF_POWER_Type, TASKS_CONSTLAT), /**< Enable constant latency mode */ + NRF_POWER_TASK_LOWPWR = offsetof(NRF_POWER_Type, TASKS_LOWPWR ), /**< Enable low power mode (variable latency) */ +}nrf_power_task_t; /*lint -restore */ + +/** + * @brief POWER events + */ +typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ +{ + NRF_POWER_EVENT_POFWARN = offsetof(NRF_POWER_Type, EVENTS_POFWARN ), /**< Power failure warning */ +#if NRF_POWER_HAS_SLEEPEVT + NRF_POWER_EVENT_SLEEPENTER = offsetof(NRF_POWER_Type, EVENTS_SLEEPENTER ), /**< CPU entered WFI/WFE sleep */ + NRF_POWER_EVENT_SLEEPEXIT = offsetof(NRF_POWER_Type, EVENTS_SLEEPEXIT ), /**< CPU exited WFI/WFE sleep */ +#endif +#if NRF_POWER_HAS_USBREG + NRF_POWER_EVENT_USBDETECTED = offsetof(NRF_POWER_Type, EVENTS_USBDETECTED), /**< Voltage supply detected on VBUS */ + NRF_POWER_EVENT_USBREMOVED = offsetof(NRF_POWER_Type, EVENTS_USBREMOVED ), /**< Voltage supply removed from VBUS */ + NRF_POWER_EVENT_USBPWRRDY = offsetof(NRF_POWER_Type, EVENTS_USBPWRRDY ), /**< USB 3.3 V supply ready */ +#endif +}nrf_power_event_t; /*lint -restore */ + +/** + * @brief POWER interrupts + */ +typedef enum +{ + NRF_POWER_INT_POFWARN_MASK = POWER_INTENSET_POFWARN_Msk , /**< Write '1' to Enable interrupt for POFWARN event */ +#if NRF_POWER_HAS_SLEEPEVT + NRF_POWER_INT_SLEEPENTER_MASK = POWER_INTENSET_SLEEPENTER_Msk , /**< Write '1' to Enable interrupt for SLEEPENTER event */ + NRF_POWER_INT_SLEEPEXIT_MASK = POWER_INTENSET_SLEEPEXIT_Msk , /**< Write '1' to Enable interrupt for SLEEPEXIT event */ +#endif +#if NRF_POWER_HAS_USBREG + NRF_POWER_INT_USBDETECTED_MASK = POWER_INTENSET_USBDETECTED_Msk, /**< Write '1' to Enable interrupt for USBDETECTED event */ + NRF_POWER_INT_USBREMOVED_MASK = POWER_INTENSET_USBREMOVED_Msk , /**< Write '1' to Enable interrupt for USBREMOVED event */ + NRF_POWER_INT_USBPWRRDY_MASK = POWER_INTENSET_USBPWRRDY_Msk , /**< Write '1' to Enable interrupt for USBPWRRDY event */ +#endif +}nrf_power_int_mask_t; + +/** + * @brief Function for activating a specific POWER task. + * + * @param task Task. + */ +__STATIC_INLINE void nrf_power_task_trigger(nrf_power_task_t task); + +/** + * @brief Function for returning the address of a specific POWER task register. + * + * @param task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_power_task_address_get(nrf_power_task_t task); + +/** + * @brief Function for clearing a specific event. + * + * @param event Event. + */ +__STATIC_INLINE void nrf_power_event_clear(nrf_power_event_t event); + +/** + * @brief Function for returning the state of a specific event. + * + * @param event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_power_event_check(nrf_power_event_t event); + +/** + * @brief Function for getting and clearing the state of specific event + * + * This function checks the state of the event and clears it. + * + * @param event Event. + * + * @retval true If the event was set. + * @retval false If the event was not set. + */ +__STATIC_INLINE bool nrf_power_event_get_and_clear(nrf_power_event_t event); + +/** + * @brief Function for returning the address of a specific POWER event register. + * + * @param event Event. + * + * @return Address. + */ +__STATIC_INLINE uint32_t nrf_power_event_address_get(nrf_power_event_t event); + +/** + * @brief Function for enabling selected interrupts. + * + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_power_int_enable(uint32_t int_mask); + +/** + * @brief Function for retrieving the state of selected interrupts. + * + * @param int_mask Interrupts mask. + * + * @retval true If any of selected interrupts is enabled. + * @retval false If none of selected interrupts is enabled. + */ +__STATIC_INLINE bool nrf_power_int_enable_check(uint32_t int_mask); + +/** + * @brief Function for retrieving the information about enabled interrupts. + * + * @return The flags of enabled interrupts. + */ +__STATIC_INLINE uint32_t nrf_power_int_enable_get(void); + +/** + * @brief Function for disabling selected interrupts. + * + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_power_int_disable(uint32_t int_mask); + + +/** @} */ /* End of nrf_power_hal */ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +/* ------------------------------------------------------------------------------------------------ + * Internal functions + */ + +/** + * @internal + * @brief Internal function for getting task/event register address + * + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile uint32_t * nrf_power_regptr_get(uint32_t offset) +{ + return (volatile uint32_t *)(((uint8_t *)NRF_POWER) + (uint32_t)offset); +} + +/** + * @internal + * @brief Internal function for getting task/event register address - constant version + * + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile const uint32_t * nrf_power_regptr_get_c( + uint32_t offset) +{ + return (volatile const uint32_t *)(((uint8_t *)NRF_POWER) + + (uint32_t)offset); +} + +/* ------------------------------------------------------------------------------------------------ + * Interface functions definitions + */ + +void nrf_power_task_trigger(nrf_power_task_t task) +{ + *(nrf_power_regptr_get((uint32_t)task)) = 1UL; +} + +uint32_t nrf_power_task_address_get(nrf_power_task_t task) +{ + return (uint32_t)nrf_power_regptr_get_c((uint32_t)task); +} + +void nrf_power_event_clear(nrf_power_event_t event) +{ + *(nrf_power_regptr_get((uint32_t)event)) = 0UL; +} + +bool nrf_power_event_check(nrf_power_event_t event) +{ + return (bool)*nrf_power_regptr_get_c((uint32_t)event); +} + +bool nrf_power_event_get_and_clear(nrf_power_event_t event) +{ + bool ret = nrf_power_event_check(event); + if(ret) + { + nrf_power_event_clear(event); + } + return ret; +} + +uint32_t nrf_power_event_address_get(nrf_power_event_t event) +{ + return (uint32_t)nrf_power_regptr_get_c((uint32_t)event); +} + +void nrf_power_int_enable(uint32_t int_mask) +{ + NRF_POWER->INTENSET = int_mask; +} + +bool nrf_power_int_enable_check(uint32_t int_mask) +{ + return !!(NRF_POWER->INTENSET & int_mask); +} + +uint32_t nrf_power_int_enable_get(void) +{ + return NRF_POWER->INTENSET; +} + +void nrf_power_int_disable(uint32_t int_mask) +{ + NRF_POWER->INTENCLR = int_mask; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +/* ------------------------------------------------------------------------------------------------ + * End of automatically generated part + * ------------------------------------------------------------------------------------------------ + */ +/** + * @ingroup nrf_power_hal + * @{ + */ + +/** + * @brief Reset reason + */ +typedef enum +{ + NRF_POWER_RESETREAS_RESETPIN_MASK = POWER_RESETREAS_RESETPIN_Msk, /*!< Bit mask of RESETPIN field. *///!< NRF_POWER_RESETREAS_RESETPIN_MASK + NRF_POWER_RESETREAS_DOG_MASK = POWER_RESETREAS_DOG_Msk , /*!< Bit mask of DOG field. */ //!< NRF_POWER_RESETREAS_DOG_MASK + NRF_POWER_RESETREAS_SREQ_MASK = POWER_RESETREAS_SREQ_Msk , /*!< Bit mask of SREQ field. */ //!< NRF_POWER_RESETREAS_SREQ_MASK + NRF_POWER_RESETREAS_LOCKUP_MASK = POWER_RESETREAS_LOCKUP_Msk , /*!< Bit mask of LOCKUP field. */ //!< NRF_POWER_RESETREAS_LOCKUP_MASK + NRF_POWER_RESETREAS_OFF_MASK = POWER_RESETREAS_OFF_Msk , /*!< Bit mask of OFF field. */ //!< NRF_POWER_RESETREAS_OFF_MASK + NRF_POWER_RESETREAS_LPCOMP_MASK = POWER_RESETREAS_LPCOMP_Msk , /*!< Bit mask of LPCOMP field. */ //!< NRF_POWER_RESETREAS_LPCOMP_MASK + NRF_POWER_RESETREAS_DIF_MASK = POWER_RESETREAS_DIF_Msk , /*!< Bit mask of DIF field. */ //!< NRF_POWER_RESETREAS_DIF_MASK +#if defined(POWER_RESETREAS_NFC_Msk) || defined(__SDK_DOXYGEN__) + NRF_POWER_RESETREAS_NFC_MASK = POWER_RESETREAS_NFC_Msk , /*!< Bit mask of NFC field. */ +#endif +#if defined(POWER_RESETREAS_VBUS_Msk) || defined(__SDK_DOXYGEN__) + NRF_POWER_RESETREAS_VBUS_MASK = POWER_RESETREAS_VBUS_Msk , /*!< Bit mask of VBUS field. */ +#endif +}nrf_power_resetreas_mask_t; + +#if NRF_POWER_HAS_USBREG +/** + * @brief USBREGSTATUS register bit masks + * + * @sa nrf_power_usbregstatus_get + */ +typedef enum +{ + NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK = POWER_USBREGSTATUS_VBUSDETECT_Msk, /**< USB detected or removed */ + NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK = POWER_USBREGSTATUS_OUTPUTRDY_Msk /**< USB 3.3 V supply ready */ +}nrf_power_usbregstatus_mask_t; +#endif + +/** + * @brief RAM blocks numbers + * + * @sa nrf_power_ramblock_mask_t + * @note + * Ram blocks has to been used in nrf51. + * In new CPU ram is divided into segments and this functionality is depreciated. + * For the newer MCU see the PS for mapping between internal RAM and RAM blocks, + * because this mapping is not 1:1, and functions related to old style blocks + * should not be used. + */ +typedef enum +{ + NRF_POWER_RAMBLOCK0 = POWER_RAMSTATUS_RAMBLOCK0_Pos, + NRF_POWER_RAMBLOCK1 = POWER_RAMSTATUS_RAMBLOCK1_Pos, + NRF_POWER_RAMBLOCK2 = POWER_RAMSTATUS_RAMBLOCK2_Pos, + NRF_POWER_RAMBLOCK3 = POWER_RAMSTATUS_RAMBLOCK3_Pos +}nrf_power_ramblock_t; + +/** + * @brief RAM blocks masks + * + * @sa nrf_power_ramblock_t + */ +typedef enum +{ + NRF_POWER_RAMBLOCK0_MASK = POWER_RAMSTATUS_RAMBLOCK0_Msk, + NRF_POWER_RAMBLOCK1_MASK = POWER_RAMSTATUS_RAMBLOCK1_Msk, + NRF_POWER_RAMBLOCK2_MASK = POWER_RAMSTATUS_RAMBLOCK2_Msk, + NRF_POWER_RAMBLOCK3_MASK = POWER_RAMSTATUS_RAMBLOCK3_Msk +}nrf_power_ramblock_mask_t; + +/** + * @brief RAM power state position of the bits + * + * @sa nrf_power_onoffram_mask_t + */ +typedef enum +{ + NRF_POWER_ONRAM0, /**< Keep RAM block 0 on or off in system ON Mode */ + NRF_POWER_OFFRAM0, /**< Keep retention on RAM block 0 when RAM block is switched off */ + NRF_POWER_ONRAM1, /**< Keep RAM block 1 on or off in system ON Mode */ + NRF_POWER_OFFRAM1, /**< Keep retention on RAM block 1 when RAM block is switched off */ + NRF_POWER_ONRAM2, /**< Keep RAM block 2 on or off in system ON Mode */ + NRF_POWER_OFFRAM2, /**< Keep retention on RAM block 2 when RAM block is switched off */ + NRF_POWER_ONRAM3, /**< Keep RAM block 3 on or off in system ON Mode */ + NRF_POWER_OFFRAM3, /**< Keep retention on RAM block 3 when RAM block is switched off */ +}nrf_power_onoffram_t; + +/** + * @brief RAM power state bit masks + * + * @sa nrf_power_onoffram_t + */ +typedef enum +{ + NRF_POWER_ONRAM0_MASK = 1U << NRF_POWER_ONRAM0, /**< Keep RAM block 0 on or off in system ON Mode */ + NRF_POWER_OFFRAM0_MASK = 1U << NRF_POWER_OFFRAM0, /**< Keep retention on RAM block 0 when RAM block is switched off */ + NRF_POWER_ONRAM1_MASK = 1U << NRF_POWER_ONRAM1, /**< Keep RAM block 1 on or off in system ON Mode */ + NRF_POWER_OFFRAM1_MASK = 1U << NRF_POWER_OFFRAM1, /**< Keep retention on RAM block 1 when RAM block is switched off */ + NRF_POWER_ONRAM2_MASK = 1U << NRF_POWER_ONRAM2, /**< Keep RAM block 2 on or off in system ON Mode */ + NRF_POWER_OFFRAM2_MASK = 1U << NRF_POWER_OFFRAM2, /**< Keep retention on RAM block 2 when RAM block is switched off */ + NRF_POWER_ONRAM3_MASK = 1U << NRF_POWER_ONRAM3, /**< Keep RAM block 3 on or off in system ON Mode */ + NRF_POWER_OFFRAM3_MASK = 1U << NRF_POWER_OFFRAM3, /**< Keep retention on RAM block 3 when RAM block is switched off */ +}nrf_power_onoffram_mask_t; + +/** + * @brief Power failure comparator thresholds + */ +typedef enum +{ + NRF_POWER_POFTHR_V21 = POWER_POFCON_THRESHOLD_V21, /**< Set threshold to 2.1 V */ + NRF_POWER_POFTHR_V23 = POWER_POFCON_THRESHOLD_V23, /**< Set threshold to 2.3 V */ + NRF_POWER_POFTHR_V25 = POWER_POFCON_THRESHOLD_V25, /**< Set threshold to 2.5 V */ + NRF_POWER_POFTHR_V27 = POWER_POFCON_THRESHOLD_V27, /**< Set threshold to 2.7 V */ +#if defined(POWER_POFCON_THRESHOLD_V17) || defined(__SDK_DOXYGEN__) + NRF_POWER_POFTHR_V17 = POWER_POFCON_THRESHOLD_V17, /**< Set threshold to 1.7 V */ + NRF_POWER_POFTHR_V18 = POWER_POFCON_THRESHOLD_V18, /**< Set threshold to 1.8 V */ + NRF_POWER_POFTHR_V19 = POWER_POFCON_THRESHOLD_V19, /**< Set threshold to 1.9 V */ + NRF_POWER_POFTHR_V20 = POWER_POFCON_THRESHOLD_V20, /**< Set threshold to 2.0 V */ + NRF_POWER_POFTHR_V22 = POWER_POFCON_THRESHOLD_V22, /**< Set threshold to 2.2 V */ + NRF_POWER_POFTHR_V24 = POWER_POFCON_THRESHOLD_V24, /**< Set threshold to 2.4 V */ + NRF_POWER_POFTHR_V26 = POWER_POFCON_THRESHOLD_V26, /**< Set threshold to 2.6 V */ + NRF_POWER_POFTHR_V28 = POWER_POFCON_THRESHOLD_V28, /**< Set threshold to 2.8 V */ +#endif +}nrf_power_pof_thr_t; + +#if NRF_POWER_HAS_VDDH +/** + * @brief Power failure comparator thresholds for VDDH + */ +typedef enum +{ + NRF_POWER_POFTHRVDDH_V27 = POWER_POFCON_THRESHOLDVDDH_V27, /**< Set threshold to 2.7 V */ + NRF_POWER_POFTHRVDDH_V28 = POWER_POFCON_THRESHOLDVDDH_V28, /**< Set threshold to 2.8 V */ + NRF_POWER_POFTHRVDDH_V29 = POWER_POFCON_THRESHOLDVDDH_V29, /**< Set threshold to 2.9 V */ + NRF_POWER_POFTHRVDDH_V30 = POWER_POFCON_THRESHOLDVDDH_V30, /**< Set threshold to 3.0 V */ + NRF_POWER_POFTHRVDDH_V31 = POWER_POFCON_THRESHOLDVDDH_V31, /**< Set threshold to 3.1 V */ + NRF_POWER_POFTHRVDDH_V32 = POWER_POFCON_THRESHOLDVDDH_V32, /**< Set threshold to 3.2 V */ + NRF_POWER_POFTHRVDDH_V33 = POWER_POFCON_THRESHOLDVDDH_V33, /**< Set threshold to 3.3 V */ + NRF_POWER_POFTHRVDDH_V34 = POWER_POFCON_THRESHOLDVDDH_V34, /**< Set threshold to 3.4 V */ + NRF_POWER_POFTHRVDDH_V35 = POWER_POFCON_THRESHOLDVDDH_V35, /**< Set threshold to 3.5 V */ + NRF_POWER_POFTHRVDDH_V36 = POWER_POFCON_THRESHOLDVDDH_V36, /**< Set threshold to 3.6 V */ + NRF_POWER_POFTHRVDDH_V37 = POWER_POFCON_THRESHOLDVDDH_V37, /**< Set threshold to 3.7 V */ + NRF_POWER_POFTHRVDDH_V38 = POWER_POFCON_THRESHOLDVDDH_V38, /**< Set threshold to 3.8 V */ + NRF_POWER_POFTHRVDDH_V39 = POWER_POFCON_THRESHOLDVDDH_V39, /**< Set threshold to 3.9 V */ + NRF_POWER_POFTHRVDDH_V40 = POWER_POFCON_THRESHOLDVDDH_V40, /**< Set threshold to 4.0 V */ + NRF_POWER_POFTHRVDDH_V41 = POWER_POFCON_THRESHOLDVDDH_V41, /**< Set threshold to 4.1 V */ + NRF_POWER_POFTHRVDDH_V42 = POWER_POFCON_THRESHOLDVDDH_V42, /**< Set threshold to 4.2 V */ +}nrf_power_pof_thrvddh_t; + +/** + * @brief Main regulator status + */ +typedef enum +{ + NRF_POWER_MAINREGSTATUS_NORMAL = POWER_MAINREGSTATUS_MAINREGSTATUS_Normal, /**< Normal voltage mode. Voltage supplied on VDD. */ + NRF_POWER_MAINREGSTATUS_HIGH = POWER_MAINREGSTATUS_MAINREGSTATUS_High /**< High voltage mode. Voltage supplied on VDDH. */ +}nrf_power_mainregstatus_t; + +#endif /* NRF_POWER_HAS_VDDH */ + +#if NRF_POWER_HAS_RAMPOWER_REGS +/** + * @brief Bit positions for RAMPOWER register + * + * All possible bits described, even if they are not used in selected MCU. + */ +typedef enum +{ + /** Keep RAM section S0 ON in System ON mode */ + NRF_POWER_RAMPOWER_S0POWER = POWER_RAM_POWER_S0POWER_Pos, + NRF_POWER_RAMPOWER_S1POWER, /**< Keep RAM section S1 ON in System ON mode */ + NRF_POWER_RAMPOWER_S2POWER, /**< Keep RAM section S2 ON in System ON mode */ + NRF_POWER_RAMPOWER_S3POWER, /**< Keep RAM section S3 ON in System ON mode */ + NRF_POWER_RAMPOWER_S4POWER, /**< Keep RAM section S4 ON in System ON mode */ + NRF_POWER_RAMPOWER_S5POWER, /**< Keep RAM section S5 ON in System ON mode */ + NRF_POWER_RAMPOWER_S6POWER, /**< Keep RAM section S6 ON in System ON mode */ + NRF_POWER_RAMPOWER_S7POWER, /**< Keep RAM section S7 ON in System ON mode */ + NRF_POWER_RAMPOWER_S8POWER, /**< Keep RAM section S8 ON in System ON mode */ + NRF_POWER_RAMPOWER_S9POWER, /**< Keep RAM section S9 ON in System ON mode */ + NRF_POWER_RAMPOWER_S10POWER, /**< Keep RAM section S10 ON in System ON mode */ + NRF_POWER_RAMPOWER_S11POWER, /**< Keep RAM section S11 ON in System ON mode */ + NRF_POWER_RAMPOWER_S12POWER, /**< Keep RAM section S12 ON in System ON mode */ + NRF_POWER_RAMPOWER_S13POWER, /**< Keep RAM section S13 ON in System ON mode */ + NRF_POWER_RAMPOWER_S14POWER, /**< Keep RAM section S14 ON in System ON mode */ + NRF_POWER_RAMPOWER_S15POWER, /**< Keep RAM section S15 ON in System ON mode */ + + /** Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S0RETENTION = POWER_RAM_POWER_S0RETENTION_Pos, + NRF_POWER_RAMPOWER_S1RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S2RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S3RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S4RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S5RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S6RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S7RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S8RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S9RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S10RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S11RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S12RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S13RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S14RETENTION, /**< Keep section retention in OFF mode when section is OFF */ + NRF_POWER_RAMPOWER_S15RETENTION, /**< Keep section retention in OFF mode when section is OFF */ +}nrf_power_rampower_t; + +#if defined ( __CC_ARM ) +#pragma push +#pragma diag_suppress 66 +#endif +/** + * @brief Bit masks for RAMPOWER register + * + * All possible bits described, even if they are not used in selected MCU. + */ +typedef enum +{ + NRF_POWER_RAMPOWER_S0POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S0POWER , + NRF_POWER_RAMPOWER_S1POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S1POWER , + NRF_POWER_RAMPOWER_S2POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S2POWER , + NRF_POWER_RAMPOWER_S3POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S3POWER , + NRF_POWER_RAMPOWER_S4POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S4POWER , + NRF_POWER_RAMPOWER_S5POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S5POWER , + NRF_POWER_RAMPOWER_S7POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S7POWER , + NRF_POWER_RAMPOWER_S8POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S8POWER , + NRF_POWER_RAMPOWER_S9POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S9POWER , + NRF_POWER_RAMPOWER_S10POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S10POWER, + NRF_POWER_RAMPOWER_S11POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S11POWER, + NRF_POWER_RAMPOWER_S12POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S12POWER, + NRF_POWER_RAMPOWER_S13POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S13POWER, + NRF_POWER_RAMPOWER_S14POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S14POWER, + NRF_POWER_RAMPOWER_S15POWER_MASK = 1UL << NRF_POWER_RAMPOWER_S15POWER, + + NRF_POWER_RAMPOWER_S0RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S0RETENTION , + NRF_POWER_RAMPOWER_S1RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S1RETENTION , + NRF_POWER_RAMPOWER_S2RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S2RETENTION , + NRF_POWER_RAMPOWER_S3RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S3RETENTION , + NRF_POWER_RAMPOWER_S4RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S4RETENTION , + NRF_POWER_RAMPOWER_S5RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S5RETENTION , + NRF_POWER_RAMPOWER_S7RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S7RETENTION , + NRF_POWER_RAMPOWER_S8RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S8RETENTION , + NRF_POWER_RAMPOWER_S9RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S9RETENTION , + NRF_POWER_RAMPOWER_S10RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S10RETENTION, + NRF_POWER_RAMPOWER_S11RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S11RETENTION, + NRF_POWER_RAMPOWER_S12RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S12RETENTION, + NRF_POWER_RAMPOWER_S13RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S13RETENTION, + NRF_POWER_RAMPOWER_S14RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S14RETENTION, + NRF_POWER_RAMPOWER_S15RETENTION_MASK = 1UL << NRF_POWER_RAMPOWER_S15RETENTION, +}nrf_power_rampower_mask_t; +#if defined ( __CC_ARM ) +#pragma pop +#endif +#endif /* NRF_POWER_HAS_RAMPOWER_REGS */ + + +/** + * @brief Get reset reason mask + * + * Function returns the reset reason. + * Unless cleared, the RESETREAS register is cumulative. + * A field is cleared by writing '1' to it (see @ref nrf_power_resetreas_clear). + * If none of the reset sources are flagged, + * this indicates that the chip was reset from the on-chip reset generator, + * which indicates a power-on-reset or a brown out reset. + * + * @return The mask of reset reasons constructed with @ref nrf_power_resetreas_mask_t. + */ +__STATIC_INLINE uint32_t nrf_power_resetreas_get(void); + +/** + * @brief Clear selected reset reason field + * + * Function clears selected reset reason fields. + * + * @param[in] mask The mask constructed from @ref nrf_power_resetreas_mask_t enumerator values. + * @sa nrf_power_resetreas_get + */ +__STATIC_INLINE void nrf_power_resetreas_clear(uint32_t mask); + +/** + * @brief Get RAMSTATUS register + * + * Returns the masks of RAM blocks that are powered ON. + * + * @return Value with bits sets according to masks in @ref nrf_power_ramblock_mask_t. + */ +__STATIC_INLINE uint32_t nrf_power_ramstatus_get(void); + +/** + * @brief Go to system OFF + * + * This function puts the CPU into system off mode. + * The only way to wake up the CPU is by reset. + * + * @note This function never returns. + */ +__STATIC_INLINE void nrf_power_system_off(void); + +/** + * @brief Set power failure comparator configuration + * + * Sets power failure comparator threshold and enable/disable flag. + * + * @param enabled Set to true if power failure comparator should be enabled. + * @param thr Set the voltage threshold value. + * + * @note + * If VDDH settings is present in the device, this function would + * clear it settings (set to the lowest voltage). + * Use @ref nrf_power_pofcon_vddh_set function to set new value. + */ +__STATIC_INLINE void nrf_power_pofcon_set(bool enabled, nrf_power_pof_thr_t thr); + +/** + * @brief Get power failure comparator configuration + * + * Get power failure comparator threshold and enable bit. + * + * @param[out] p_enabled Function would set this boolean variable to true + * if power failure comparator is enabled. + * The pointer can be NULL if we do not need this information. + * @return Threshold setting for power failure comparator + */ +__STATIC_INLINE nrf_power_pof_thr_t nrf_power_pofcon_get(bool * p_enabled); + +#if NRF_POWER_HAS_VDDH +/** + * @brief Set VDDH power failure comparator threshold + * + * @param thr Threshold to be set + */ +__STATIC_INLINE void nrf_power_pofcon_vddh_set(nrf_power_pof_thrvddh_t thr); + +/** + * @brief Get VDDH power failure comparator threshold + * + * @return VDDH threshold currently configured + */ +__STATIC_INLINE nrf_power_pof_thrvddh_t nrf_power_pofcon_vddh_get(void); +#endif + +/** + * @brief Set general purpose retention register + * + * @param val Value to be set in the register + */ +__STATIC_INLINE void nrf_power_gpregret_set(uint8_t val); + +/** + * @brief Get general purpose retention register + * + * @return The value from the register + */ +__STATIC_INLINE uint8_t nrf_power_gpregret_get(void); + +#if defined(POWER_GPREGRET2_GPREGRET_Msk) || defined(__SDK_DOXYGEN__) +/** + * @brief Set general purpose retention register 2 + * + * @param val Value to be set in the register + * @note This register is not available in nrf51 MCU family + */ +__STATIC_INLINE void nrf_power_gpregret2_set(uint8_t val); + +/** + * @brief Get general purpose retention register 2 + * + * @return The value from the register + * @note This register is not available in all MCUs. + */ +__STATIC_INLINE uint8_t nrf_power_gpregret2_get(void); +#endif + +/** + * @brief Enable or disable DCDC converter + * + * @param enable Set true to enable or false to disable DCDC converter. + * + * @note + * If the device consist of high voltage power input (VDDH) this setting + * would relate to the converter on low voltage side (1.3 V output). + */ +__STATIC_INLINE void nrf_power_dcdcen_set(bool enable); + +/** + * @brief Get the state of DCDC converter + * + * @retval true Converter is enabled + * @retval false Converter is disabled + * + * @note + * If the device consist of high voltage power input (VDDH) this setting + * would relate to the converter on low voltage side (1.3 V output). + */ +__STATIC_INLINE bool nrf_power_dcdcen_get(void); + +#if NRF_POWER_HAS_RAMPOWER_REGS +/** + * @brief Turn ON sections in selected RAM block. + * + * This function turns ON sections in block and also block retention. + * + * @sa nrf_power_rampower_mask_t + * @sa nrf_power_rampower_mask_off + * + * @param block RAM block index. + * @param section_mask Mask of the sections created by merging + * @ref nrf_power_rampower_mask_t flags. + */ +__STATIC_INLINE void nrf_power_rampower_mask_on(uint8_t block, uint32_t section_mask); + +/** + * @brief Turn ON sections in selected RAM block. + * + * This function turns OFF sections in block and also block retention. + * + * @sa nrf_power_rampower_mask_t + * @sa nrf_power_rampower_mask_off + * + * @param block RAM block index. + * @param section_mask Mask of the sections created by merging + * @ref nrf_power_rampower_mask_t flags. + */ +__STATIC_INLINE void nrf_power_rampower_mask_off(uint8_t block, uint32_t section_mask); + +/** + * @brief Get the mask of ON and retention sections in selected RAM block. + * + * @param block RAM block index. + * @return Mask of sections state composed from @ref nrf_power_rampower_mask_t flags. + */ +__STATIC_INLINE uint32_t nrf_power_rampower_mask_get(uint8_t block); +#endif /* NRF_POWER_HAS_RAMPOWER_REGS */ + +#if NRF_POWER_HAS_VDDH +/** + * @brief Enable of disable DCDC converter on VDDH + * + * @param enable Set true to enable or false to disable DCDC converter. + */ +__STATIC_INLINE void nrf_power_dcdcen_vddh_set(bool enable); + +/** + * @brief Get the state of DCDC converter on VDDH + * + * @retval true Converter is enabled + * @retval false Converter is disabled + */ +__STATIC_INLINE bool nrf_power_dcdcen_vddh_get(void); + +/** + * @brief Get main supply status + * + * @return Current main supply status + */ +__STATIC_INLINE nrf_power_mainregstatus_t nrf_power_mainregstatus_get(void); +#endif /* NRF_POWER_HAS_VDDH */ + +#if NRF_POWER_HAS_USBREG +/** + * + * @return Get the whole USBREGSTATUS register + * + * @return The USBREGSTATUS register value. + * Use @ref nrf_power_usbregstatus_mask_t values for bit masking. + * + * @sa nrf_power_usbregstatus_vbusdet_get + * @sa nrf_power_usbregstatus_outrdy_get + */ +__STATIC_INLINE uint32_t nrf_power_usbregstatus_get(void); + +/** + * @brief VBUS input detection status + * + * USBDETECTED and USBREMOVED events are derived from this information + * + * @retval false VBUS voltage below valid threshold + * @retval true VBUS voltage above valid threshold + * + * @sa nrf_power_usbregstatus_get + */ +__STATIC_INLINE bool nrf_power_usbregstatus_vbusdet_get(void); + +/** + * @brief USB supply output settling time elapsed + * + * @retval false USBREG output settling time not elapsed + * @retval true USBREG output settling time elapsed + * (same information as USBPWRRDY event) + * + * @sa nrf_power_usbregstatus_get + */ +__STATIC_INLINE bool nrf_power_usbregstatus_outrdy_get(void); +#endif /* NRF_POWER_HAS_USBREG */ + +/** @} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t nrf_power_resetreas_get(void) +{ + return NRF_POWER->RESETREAS; +} + +__STATIC_INLINE void nrf_power_resetreas_clear(uint32_t mask) +{ + NRF_POWER->RESETREAS = mask; +} + +__STATIC_INLINE uint32_t nrf_power_ramstatus_get(void) +{ + return NRF_POWER->RAMSTATUS; +} + +__STATIC_INLINE void nrf_power_system_off(void) +{ + NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter; + /* Solution for simulated System OFF in debug mode. + * Also, because dead loop is placed here, we do not need to implement + * any barriers here. */ + while(true) + { + /* Intentionally empty - we would be here only in debug mode */ + } +} + +__STATIC_INLINE void nrf_power_pofcon_set(bool enabled, nrf_power_pof_thr_t thr) +{ + ASSERT(thr == (thr & (POWER_POFCON_THRESHOLD_Msk >> POWER_POFCON_THRESHOLD_Pos))); + NRF_POWER->POFCON = (((uint32_t)thr) << POWER_POFCON_THRESHOLD_Pos) | + (enabled ? + (POWER_POFCON_POF_Enabled << POWER_POFCON_POF_Pos) + : + (POWER_POFCON_POF_Disabled << POWER_POFCON_POF_Pos)); +} + +__STATIC_INLINE nrf_power_pof_thr_t nrf_power_pofcon_get(bool * p_enabled) +{ + uint32_t pofcon = NRF_POWER->POFCON; + if(NULL != p_enabled) + { + (*p_enabled) = ((pofcon & POWER_POFCON_POF_Msk) >> POWER_POFCON_POF_Pos) + == POWER_POFCON_POF_Enabled; + } + return (nrf_power_pof_thr_t)((pofcon & POWER_POFCON_THRESHOLD_Msk) >> + POWER_POFCON_THRESHOLD_Pos); +} + +#if NRF_POWER_HAS_VDDH +__STATIC_INLINE void nrf_power_pofcon_vddh_set(nrf_power_pof_thrvddh_t thr) +{ + ASSERT(thr == (thr & (POWER_POFCON_THRESHOLDVDDH_Msk >> POWER_POFCON_THRESHOLDVDDH_Pos))); + uint32_t pofcon = NRF_POWER->POFCON; + pofcon &= ~POWER_POFCON_THRESHOLDVDDH_Msk; + pofcon |= (((uint32_t)thr) << POWER_POFCON_THRESHOLDVDDH_Pos); + NRF_POWER->POFCON = pofcon; +} + +__STATIC_INLINE nrf_power_pof_thrvddh_t nrf_power_pofcon_vddh_get(void) +{ + return (nrf_power_pof_thrvddh_t)((NRF_POWER->POFCON & + POWER_POFCON_THRESHOLDVDDH_Msk) >> POWER_POFCON_THRESHOLDVDDH_Pos); +} +#endif /* NRF_POWER_HAS_VDDH */ + +__STATIC_INLINE void nrf_power_gpregret_set(uint8_t val) +{ + NRF_POWER->GPREGRET = val; +} + +__STATIC_INLINE uint8_t nrf_power_gpregret_get(void) +{ + return NRF_POWER->GPREGRET; +} + +#if defined(POWER_GPREGRET2_GPREGRET_Msk) || defined(__SDK_DOXYGEN__) +void nrf_power_gpregret2_set(uint8_t val) +{ + NRF_POWER->GPREGRET2 = val; +} + +__STATIC_INLINE uint8_t nrf_power_gpregret2_get(void) +{ + return NRF_POWER->GPREGRET2; +} +#endif + +__STATIC_INLINE void nrf_power_dcdcen_set(bool enable) +{ +#if NRF_POWER_HAS_VDDH + NRF_POWER->DCDCEN = (enable ? + POWER_DCDCEN_DCDCEN_Enabled : POWER_DCDCEN_DCDCEN_Disabled) << + POWER_DCDCEN_DCDCEN_Pos; +#else + NRF_POWER->DCDCEN = (enable ? + POWER_DCDCEN_DCDCEN_Enabled : POWER_DCDCEN_DCDCEN_Disabled) << + POWER_DCDCEN_DCDCEN_Pos; +#endif +} + +__STATIC_INLINE bool nrf_power_dcdcen_get(void) +{ +#if NRF_POWER_HAS_VDDH + return (NRF_POWER->DCDCEN & POWER_DCDCEN_DCDCEN_Msk) + == + (POWER_DCDCEN_DCDCEN_Enabled << POWER_DCDCEN_DCDCEN_Pos); +#else + return (NRF_POWER->DCDCEN & POWER_DCDCEN_DCDCEN_Msk) + == + (POWER_DCDCEN_DCDCEN_Enabled << POWER_DCDCEN_DCDCEN_Pos); +#endif +} + +#if NRF_POWER_HAS_RAMPOWER_REGS +__STATIC_INLINE void nrf_power_rampower_mask_on(uint8_t block, uint32_t section_mask) +{ + ASSERT(block < ARRAY_SIZE(NRF_POWER->RAM)); + NRF_POWER->RAM[block].POWERSET = section_mask; +} + +__STATIC_INLINE void nrf_power_rampower_mask_off(uint8_t block, uint32_t section_mask) +{ + ASSERT(block < ARRAY_SIZE(NRF_POWER->RAM)); + NRF_POWER->RAM[block].POWERCLR = section_mask; +} + +__STATIC_INLINE uint32_t nrf_power_rampower_mask_get(uint8_t block) +{ + ASSERT(block < ARRAY_SIZE(NRF_POWER->RAM)); + return NRF_POWER->RAM[block].POWER; +} +#endif /* NRF_POWER_HAS_RAMPOWER_REGS */ + +#if NRF_POWER_HAS_VDDH +__STATIC_INLINE void nrf_power_dcdcen_vddh_set(bool enable) +{ + NRF_POWER->DCDCEN0 = (enable ? + POWER_DCDCEN0_DCDCEN_Enabled : POWER_DCDCEN0_DCDCEN_Disabled) << + POWER_DCDCEN0_DCDCEN_Pos; +} + +bool nrf_power_dcdcen_vddh_get(void) +{ + return (NRF_POWER->DCDCEN0 & POWER_DCDCEN0_DCDCEN_Msk) + == + (POWER_DCDCEN0_DCDCEN_Enabled << POWER_DCDCEN0_DCDCEN_Pos); +} + +nrf_power_mainregstatus_t nrf_power_mainregstatus_get(void) +{ + return (nrf_power_mainregstatus_t)(((NRF_POWER->MAINREGSTATUS) & + POWER_MAINREGSTATUS_MAINREGSTATUS_Msk) >> + POWER_MAINREGSTATUS_MAINREGSTATUS_Pos); +} +#endif /* NRF_POWER_HAS_VDDH */ + +#if NRF_POWER_HAS_USBREG +__STATIC_INLINE uint32_t nrf_power_usbregstatus_get(void) +{ + return NRF_POWER->USBREGSTATUS; +} + +__STATIC_INLINE bool nrf_power_usbregstatus_vbusdet_get(void) +{ + return (nrf_power_usbregstatus_get() & + NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK) != 0; +} + +__STATIC_INLINE bool nrf_power_usbregstatus_outrdy_get(void) +{ + return (nrf_power_usbregstatus_get() & + NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK) != 0; +} +#endif /* NRF_POWER_HAS_USBREG */ + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_POWER_H__ */ diff --git a/components/drivers_nrf/hal/nrf_ppi.h b/components/drivers_nrf/hal/nrf_ppi.h index ddea41d..f3c2f4b 100644 --- a/components/drivers_nrf/hal/nrf_ppi.h +++ b/components/drivers_nrf/hal/nrf_ppi.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_PPI_H__ @@ -15,6 +43,11 @@ #include #include "nrf.h" +#include "nrf_peripherals.h" + +#ifdef __cplusplus +extern "C" { +#endif /** * @defgroup nrf_ppi_hal PPI HAL @@ -47,6 +80,12 @@ typedef enum NRF_PPI_CHANNEL13 = PPI_CHEN_CH13_Pos, /**< Channel 13. */ NRF_PPI_CHANNEL14 = PPI_CHEN_CH14_Pos, /**< Channel 14. */ NRF_PPI_CHANNEL15 = PPI_CHEN_CH15_Pos, /**< Channel 15. */ +#if (PPI_CH_NUM > 16) || defined(__SDK_DOXYGEN__) + NRF_PPI_CHANNEL16 = PPI_CHEN_CH16_Pos, /**< Channel 16. */ + NRF_PPI_CHANNEL17 = PPI_CHEN_CH17_Pos, /**< Channel 17. */ + NRF_PPI_CHANNEL18 = PPI_CHEN_CH18_Pos, /**< Channel 18. */ + NRF_PPI_CHANNEL19 = PPI_CHEN_CH19_Pos, /**< Channel 19. */ +#endif NRF_PPI_CHANNEL20 = PPI_CHEN_CH20_Pos, /**< Channel 20. */ NRF_PPI_CHANNEL21 = PPI_CHEN_CH21_Pos, /**< Channel 21. */ NRF_PPI_CHANNEL22 = PPI_CHEN_CH22_Pos, /**< Channel 22. */ @@ -70,7 +109,11 @@ typedef enum NRF_PPI_CHANNEL_GROUP0 = 0, /**< Channel group 0. */ NRF_PPI_CHANNEL_GROUP1 = 1, /**< Channel group 1. */ NRF_PPI_CHANNEL_GROUP2 = 2, /**< Channel group 2. */ - NRF_PPI_CHANNEL_GROUP3 = 3 /**< Channel group 3. */ + NRF_PPI_CHANNEL_GROUP3 = 3, /**< Channel group 3. */ +#if (PPI_GROUP_NUM > 4) || defined(__SDK_DOXYGEN__) + NRF_PPI_CHANNEL_GROUP4 = 4, /**< Channel group 4. */ + NRF_PPI_CHANNEL_GROUP5 = 5 /**< Channel group 5. */ +#endif } nrf_ppi_channel_group_t; /** @@ -107,7 +150,13 @@ typedef enum NRF_PPI_TASK_CHG2_EN = offsetof(NRF_PPI_Type, TASKS_CHG[2].EN), /**< Task for enabling channel group 2 */ NRF_PPI_TASK_CHG2_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[2].DIS), /**< Task for disabling channel group 2 */ NRF_PPI_TASK_CHG3_EN = offsetof(NRF_PPI_Type, TASKS_CHG[3].EN), /**< Task for enabling channel group 3 */ - NRF_PPI_TASK_CHG3_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[3].DIS) /**< Task for disabling channel group 3 */ + NRF_PPI_TASK_CHG3_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[3].DIS), /**< Task for disabling channel group 3 */ +#if (PPI_GROUP_NUM > 4) || defined(__SDK_DOXYGEN__) + NRF_PPI_TASK_CHG4_EN = offsetof(NRF_PPI_Type, TASKS_CHG[4].EN), /**< Task for enabling channel group 4 */ + NRF_PPI_TASK_CHG4_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[4].DIS), /**< Task for disabling channel group 4 */ + NRF_PPI_TASK_CHG5_EN = offsetof(NRF_PPI_Type, TASKS_CHG[5].EN), /**< Task for enabling channel group 5 */ + NRF_PPI_TASK_CHG5_DIS = offsetof(NRF_PPI_Type, TASKS_CHG[5].DIS) /**< Task for disabling channel group 5 */ +#endif /*lint -restore*/ } nrf_ppi_task_t; @@ -170,7 +219,6 @@ __STATIC_INLINE void nrf_ppi_channel_disable_all(void) NRF_PPI->CHENCLR = ((uint32_t)0xFFFFFFFFuL); } - /** * @brief Function for disabling multiple PPI channels. * @@ -181,13 +229,12 @@ __STATIC_INLINE void nrf_ppi_channels_disable(uint32_t mask) NRF_PPI->CHENCLR = mask; } - /** * @brief Function for setting up event and task endpoints for a given PPI channel. * - * @param[in] eep Event register address (register value). + * @param[in] eep Event register address. * - * @param[in] tep Task register address (register value). + * @param[in] tep Task register address. * * @param[in] channel Channel to which the given endpoints are assigned. */ @@ -199,6 +246,40 @@ __STATIC_INLINE void nrf_ppi_channel_endpoint_setup(nrf_ppi_channel_t channel, NRF_PPI->CH[(uint32_t) channel].TEP = tep; } +#if defined(PPI_FEATURE_FORKS_PRESENT) || defined(__SDK_DOXYGEN__) +/** + * @brief Function for setting up task endpoint for a given PPI fork. + * + * @param[in] fork_tep Task register address. + * + * @param[in] channel Channel to which the given fork endpoint is assigned. + */ +__STATIC_INLINE void nrf_ppi_fork_endpoint_setup(nrf_ppi_channel_t channel, + uint32_t fork_tep) +{ + NRF_PPI->FORK[(uint32_t) channel].TEP = fork_tep; +} + +/** + * @brief Function for setting up event and task endpoints for a given PPI channel and fork. + * + * @param[in] eep Event register address. + * + * @param[in] tep Task register address. + * + * @param[in] fork_tep Fork task register address (register value). + * + * @param[in] channel Channel to which the given endpoints are assigned. + */ +__STATIC_INLINE void nrf_ppi_channel_and_fork_endpoint_setup(nrf_ppi_channel_t channel, + uint32_t eep, + uint32_t tep, + uint32_t fork_tep) +{ + nrf_ppi_channel_endpoint_setup(channel, eep, tep); + nrf_ppi_fork_endpoint_setup(channel, fork_tep); +} +#endif /** * @brief Function for including a PPI channel in a channel group. @@ -351,4 +432,9 @@ __STATIC_INLINE uint32_t * nrf_ppi_task_group_disable_address_get(nrf_ppi_channe **/ /*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif // NRF_PPI_H__ diff --git a/components/drivers_nrf/hal/nrf_pwm.h b/components/drivers_nrf/hal/nrf_pwm.h new file mode 100644 index 0000000..a90b48c --- /dev/null +++ b/components/drivers_nrf/hal/nrf_pwm.h @@ -0,0 +1,702 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @defgroup nrf_pwm_hal PWM HAL + * @{ + * @ingroup nrf_pwm + * + * @brief @tagAPI52 Hardware access layer for managing the Pulse Width Modulation (PWM) + * peripheral. + */ + +#ifndef NRF_PWM_H__ +#define NRF_PWM_H__ + +#include +#include +#include + +#include "nrf.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief This value can be provided as a parameter for the @ref nrf_pwm_pins_set + * function call to specify that a given output channel shall not be + * connected to a physical pin. + */ +#define NRF_PWM_PIN_NOT_CONNECTED 0xFFFFFFFF + +/** + * @brief Number of channels in each Pointer to the peripheral registers structure. + */ +#define NRF_PWM_CHANNEL_COUNT 4 + + +/** + * @brief PWM tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_PWM_TASK_STOP = offsetof(NRF_PWM_Type, TASKS_STOP), ///< Stops PWM pulse generation on all channels at the end of the current PWM period, and stops the sequence playback. + NRF_PWM_TASK_SEQSTART0 = offsetof(NRF_PWM_Type, TASKS_SEQSTART[0]), ///< Starts playback of sequence 0. + NRF_PWM_TASK_SEQSTART1 = offsetof(NRF_PWM_Type, TASKS_SEQSTART[1]), ///< Starts playback of sequence 1. + NRF_PWM_TASK_NEXTSTEP = offsetof(NRF_PWM_Type, TASKS_NEXTSTEP) ///< Steps by one value in the current sequence if the decoder is set to @ref NRF_PWM_STEP_TRIGGERED mode. + /*lint -restore*/ +} nrf_pwm_task_t; + +/** + * @brief PWM events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_PWM_EVENT_STOPPED = offsetof(NRF_PWM_Type, EVENTS_STOPPED), ///< Response to STOP task, emitted when PWM pulses are no longer generated. + NRF_PWM_EVENT_SEQSTARTED0 = offsetof(NRF_PWM_Type, EVENTS_SEQSTARTED[0]), ///< First PWM period started on sequence 0. + NRF_PWM_EVENT_SEQSTARTED1 = offsetof(NRF_PWM_Type, EVENTS_SEQSTARTED[1]), ///< First PWM period started on sequence 1. + NRF_PWM_EVENT_SEQEND0 = offsetof(NRF_PWM_Type, EVENTS_SEQEND[0]), ///< Emitted at the end of every sequence 0 when its last value has been read from RAM. + NRF_PWM_EVENT_SEQEND1 = offsetof(NRF_PWM_Type, EVENTS_SEQEND[1]), ///< Emitted at the end of every sequence 1 when its last value has been read from RAM. + NRF_PWM_EVENT_PWMPERIODEND = offsetof(NRF_PWM_Type, EVENTS_PWMPERIODEND), ///< Emitted at the end of each PWM period. + NRF_PWM_EVENT_LOOPSDONE = offsetof(NRF_PWM_Type, EVENTS_LOOPSDONE) ///< Concatenated sequences have been played the requested number of times. + /*lint -restore*/ +} nrf_pwm_event_t; + +/** + * @brief PWM interrupts. + */ +typedef enum +{ + NRF_PWM_INT_STOPPED_MASK = PWM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_PWM_INT_SEQSTARTED0_MASK = PWM_INTENSET_SEQSTARTED0_Msk, ///< Interrupt on SEQSTARTED[0] event. + NRF_PWM_INT_SEQSTARTED1_MASK = PWM_INTENSET_SEQSTARTED1_Msk, ///< Interrupt on SEQSTARTED[1] event. + NRF_PWM_INT_SEQEND0_MASK = PWM_INTENSET_SEQEND0_Msk, ///< Interrupt on SEQEND[0] event. + NRF_PWM_INT_SEQEND1_MASK = PWM_INTENSET_SEQEND1_Msk, ///< Interrupt on SEQEND[1] event. + NRF_PWM_INT_PWMPERIODEND_MASK = PWM_INTENSET_PWMPERIODEND_Msk, ///< Interrupt on PWMPERIODEND event. + NRF_PWM_INT_LOOPSDONE_MASK = PWM_INTENSET_LOOPSDONE_Msk ///< Interrupt on LOOPSDONE event. +} nrf_pwm_int_mask_t; + +/** + * @brief PWM shortcuts. + */ +typedef enum +{ + NRF_PWM_SHORT_SEQEND0_STOP_MASK = PWM_SHORTS_SEQEND0_STOP_Msk, ///< Shortcut between SEQEND[0] event and STOP task. + NRF_PWM_SHORT_SEQEND1_STOP_MASK = PWM_SHORTS_SEQEND1_STOP_Msk, ///< Shortcut between SEQEND[1] event and STOP task. + NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK = PWM_SHORTS_LOOPSDONE_SEQSTART0_Msk, ///< Shortcut between LOOPSDONE event and SEQSTART[0] task. + NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK = PWM_SHORTS_LOOPSDONE_SEQSTART1_Msk, ///< Shortcut between LOOPSDONE event and SEQSTART[1] task. + NRF_PWM_SHORT_LOOPSDONE_STOP_MASK = PWM_SHORTS_LOOPSDONE_STOP_Msk ///< Shortcut between LOOPSDONE event and STOP task. +} nrf_pwm_short_mask_t; + +/** + * @brief PWM modes of operation. + */ +typedef enum +{ + NRF_PWM_MODE_UP = PWM_MODE_UPDOWN_Up, ///< Up counter (edge-aligned PWM duty cycle). + NRF_PWM_MODE_UP_AND_DOWN = PWM_MODE_UPDOWN_UpAndDown, ///< Up and down counter (center-aligned PWM duty cycle). +} nrf_pwm_mode_t; + +/** + * @brief PWM base clock frequencies. + */ +typedef enum +{ + NRF_PWM_CLK_16MHz = PWM_PRESCALER_PRESCALER_DIV_1, ///< 16 MHz / 1 = 16 MHz. + NRF_PWM_CLK_8MHz = PWM_PRESCALER_PRESCALER_DIV_2, ///< 16 MHz / 2 = 8 MHz. + NRF_PWM_CLK_4MHz = PWM_PRESCALER_PRESCALER_DIV_4, ///< 16 MHz / 4 = 4 MHz. + NRF_PWM_CLK_2MHz = PWM_PRESCALER_PRESCALER_DIV_8, ///< 16 MHz / 8 = 2 MHz. + NRF_PWM_CLK_1MHz = PWM_PRESCALER_PRESCALER_DIV_16, ///< 16 MHz / 16 = 1 MHz. + NRF_PWM_CLK_500kHz = PWM_PRESCALER_PRESCALER_DIV_32, ///< 16 MHz / 32 = 500 kHz. + NRF_PWM_CLK_250kHz = PWM_PRESCALER_PRESCALER_DIV_64, ///< 16 MHz / 64 = 250 kHz. + NRF_PWM_CLK_125kHz = PWM_PRESCALER_PRESCALER_DIV_128 ///< 16 MHz / 128 = 125 kHz. +} nrf_pwm_clk_t; + +/** + * @brief PWM decoder load modes. + * + * The selected mode determines how the sequence data is read from RAM and + * spread to the compare registers. + */ +typedef enum +{ + NRF_PWM_LOAD_COMMON = PWM_DECODER_LOAD_Common, ///< 1st half word (16-bit) used in all PWM channels (0-3). + NRF_PWM_LOAD_GROUPED = PWM_DECODER_LOAD_Grouped, ///< 1st half word (16-bit) used in channels 0 and 1; 2nd word in channels 2 and 3. + NRF_PWM_LOAD_INDIVIDUAL = PWM_DECODER_LOAD_Individual, ///< 1st half word (16-bit) used in channel 0; 2nd in channel 1; 3rd in channel 2; 4th in channel 3. + NRF_PWM_LOAD_WAVE_FORM = PWM_DECODER_LOAD_WaveForm ///< 1st half word (16-bit) used in channel 0; 2nd in channel 1; ... ; 4th as the top value for the pulse generator counter. +} nrf_pwm_dec_load_t; + +/** + * @brief PWM decoder next step modes. + * + * The selected mode determines when the next value from the active sequence + * is loaded. + */ +typedef enum +{ + NRF_PWM_STEP_AUTO = PWM_DECODER_MODE_RefreshCount, ///< Automatically after the current value is played and repeated the requested number of times. + NRF_PWM_STEP_TRIGGERED = PWM_DECODER_MODE_NextStep ///< When the @ref NRF_PWM_TASK_NEXTSTEP task is triggered. +} nrf_pwm_dec_step_t; + + +/** + * @brief Type used for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_COMMON mode. + */ +typedef uint16_t nrf_pwm_values_common_t; + +/** + * @brief Structure for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_GROUPED mode. + */ +typedef struct { + uint16_t group_0; ///< Duty cycle value for group 0 (channels 0 and 1). + uint16_t group_1; ///< Duty cycle value for group 1 (channels 2 and 3). +} nrf_pwm_values_grouped_t; + +/** + * @brief Structure for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_INDIVIDUAL mode. + */ +typedef struct +{ + uint16_t channel_0; ///< Duty cycle value for channel 0. + uint16_t channel_1; ///< Duty cycle value for channel 1. + uint16_t channel_2; ///< Duty cycle value for channel 2. + uint16_t channel_3; ///< Duty cycle value for channel 3. +} nrf_pwm_values_individual_t; + +/** + * @brief Structure for defining duty cycle values for a sequence + * loaded in @ref NRF_PWM_LOAD_WAVE_FORM mode. + */ +typedef struct { + uint16_t channel_0; ///< Duty cycle value for channel 0. + uint16_t channel_1; ///< Duty cycle value for channel 1. + uint16_t channel_2; ///< Duty cycle value for channel 2. + uint16_t counter_top; ///< Top value for the pulse generator counter. +} nrf_pwm_values_wave_form_t; + +/** + * @brief Union grouping pointers to arrays of duty cycle values applicable to + * various loading modes. + */ +typedef union { + nrf_pwm_values_common_t const * p_common; ///< Pointer to be used in @ref NRF_PWM_LOAD_COMMON mode. + nrf_pwm_values_grouped_t const * p_grouped; ///< Pointer to be used in @ref NRF_PWM_LOAD_GROUPED mode. + nrf_pwm_values_individual_t const * p_individual; ///< Pointer to be used in @ref NRF_PWM_LOAD_INDIVIDUAL mode. + nrf_pwm_values_wave_form_t const * p_wave_form; ///< Pointer to be used in @ref NRF_PWM_LOAD_WAVE_FORM mode. + uint16_t const * p_raw; ///< Pointer providing raw access to the values. +} nrf_pwm_values_t; + +/** + * @brief Structure for defining a sequence of PWM duty cycles. + * + * When the sequence is set (by a call to @ref nrf_pwm_sequence_set), the + * provided duty cycle values are not copied. The @p values pointer is stored + * in the peripheral's internal register, and the values are loaded from RAM + * during the sequence playback. Therefore, you must ensure that the values + * do not change before and during the sequence playback (for example, + * the values cannot be placed in a local variable that is allocated on stack). + * If the sequence is played in a loop and the values should be updated + * before the next iteration, it is safe to modify them when the corresponding + * event signaling the end of sequence occurs (@ref NRF_PWM_EVENT_SEQEND0 + * or @ref NRF_PWM_EVENT_SEQEND1, respectively). + * + * @note The @p repeats and @p end_delay values (which are written to the + * SEQ[n].REFRESH and SEQ[n].ENDDELAY registers in the peripheral, + * respectively) are ignored at the end of a complex sequence + * playback, indicated by the LOOPSDONE event. + * See the @linkProductSpecification52 for more information. + */ +typedef struct +{ + nrf_pwm_values_t values; ///< Pointer to an array with duty cycle values. This array must be in Data RAM. + /**< This field is defined as an union of pointers + * to provide a convenient way to define duty + * cycle values in various loading modes + * (see @ref nrf_pwm_dec_load_t). + * In each value, the most significant bit (15) + * determines the polarity of the output and the + * others (14-0) compose the 15-bit value to be + * compared with the pulse generator counter. */ + uint16_t length; ///< Number of 16-bit values in the array pointed by @p values. + uint32_t repeats; ///< Number of times that each duty cycle should be repeated (after being played once). Ignored in @ref NRF_PWM_STEP_TRIGGERED mode. + uint32_t end_delay; ///< Additional time (in PWM periods) that the last duty cycle is to be kept after the sequence is played. Ignored in @ref NRF_PWM_STEP_TRIGGERED mode. +} nrf_pwm_sequence_t; + +/** + * @brief Helper macro for calculating the number of 16-bit values in specified + * array of duty cycle values. + */ +#define NRF_PWM_VALUES_LENGTH(array) (sizeof(array) / sizeof(uint16_t)) + + +/** + * @brief Function for activating a specific PWM task. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_reg, + nrf_pwm_task_t task); + +/** + * @brief Function for getting the address of a specific PWM task register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_reg, + nrf_pwm_task_t task); + +/** + * @brief Function for clearing a specific PWM event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_reg, + nrf_pwm_event_t event); + +/** + * @brief Function for checking the state of a specific PWM event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_reg, + nrf_pwm_event_t event); + +/** + * @brief Function for getting the address of a specific PWM event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_reg, + nrf_pwm_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask); + +/** + * @brief Function for setting the configuration of PWM shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_shorts_mask Shortcuts configuration to set. + */ +__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask); + +/** + * @brief Function for setting the configuration of PWM interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_int_mask Interrupts configuration to set. + */ +__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] pwm_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_reg, + nrf_pwm_int_mask_t pwm_int); + +/** + * @brief Function for enabling the PWM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_reg); + +/** + * @brief Function for disabling the PWM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_reg); + +/** + * @brief Function for assigning pins to PWM output channels. + * + * Usage of all PWM output channels is optional. If a given channel is not + * needed, pass the @ref NRF_PWM_PIN_NOT_CONNECTED value instead of its pin + * number. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] out_pins Array with pin numbers for individual PWM output channels. + */ +__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_reg, + uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]); + +/** + * @brief Function for configuring the PWM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] base_clock Base clock frequency. + * @param[in] mode Operating mode of the pulse generator counter. + * @param[in] top_value Value up to which the pulse generator counter counts. + */ +__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_reg, + nrf_pwm_clk_t base_clock, + nrf_pwm_mode_t mode, + uint16_t top_value); + +/** + * @brief Function for defining a sequence of PWM duty cycles. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] p_seq Pointer to the sequence definition. + */ +__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + nrf_pwm_sequence_t const * p_seq); + +/** + * @brief Function for modifying the pointer to the duty cycle values + * in the specified sequence. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] p_values Pointer to an array with duty cycle values. + */ +__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint16_t const * p_values); + +/** + * @brief Function for modifying the total number of duty cycle values + * in the specified sequence. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] length Number of duty cycle values. + */ +__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint16_t length); + +/** + * @brief Function for modifying the additional number of PWM periods spent + * on each duty cycle value in the specified sequence. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] refresh Number of additional PWM periods for each duty cycle value. + */ +__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint32_t refresh); + +/** + * @brief Function for modifying the additional time added after the sequence + * is played. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] end_delay Number of PWM periods added at the end of the sequence. + */ +__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint32_t end_delay); + +/** + * @brief Function for setting the mode of loading sequence data from RAM + * and advancing the sequence. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] dec_load Mode of loading sequence data from RAM. + * @param[in] dec_step Mode of advancing the active sequence. + */ +__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_reg, + nrf_pwm_dec_load_t dec_load, + nrf_pwm_dec_step_t dec_step); + +/** + * @brief Function for setting the number of times the sequence playback + * should be performed. + * + * This function applies to two-sequence playback (concatenated sequence 0 and 1). + * A single sequence can be played back only once. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] loop_count Number of times to perform the sequence playback. + */ +__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_reg, + uint16_t loop_count); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_pwm_task_trigger(NRF_PWM_Type * p_reg, + nrf_pwm_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_pwm_task_address_get(NRF_PWM_Type const * p_reg, + nrf_pwm_task_t task) +{ + return ((uint32_t)p_reg + (uint32_t)task); +} + +__STATIC_INLINE void nrf_pwm_event_clear(NRF_PWM_Type * p_reg, + nrf_pwm_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_pwm_event_check(NRF_PWM_Type const * p_reg, + nrf_pwm_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t nrf_pwm_event_address_get(NRF_PWM_Type const * p_reg, + nrf_pwm_event_t event) +{ + return ((uint32_t)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_pwm_shorts_enable(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask) +{ + p_reg->SHORTS |= pwm_shorts_mask; +} + +__STATIC_INLINE void nrf_pwm_shorts_disable(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask) +{ + p_reg->SHORTS &= ~(pwm_shorts_mask); +} + +__STATIC_INLINE void nrf_pwm_shorts_set(NRF_PWM_Type * p_reg, + uint32_t pwm_shorts_mask) +{ + p_reg->SHORTS = pwm_shorts_mask; +} + +__STATIC_INLINE void nrf_pwm_int_enable(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask) +{ + p_reg->INTENSET = pwm_int_mask; +} + +__STATIC_INLINE void nrf_pwm_int_disable(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask) +{ + p_reg->INTENCLR = pwm_int_mask; +} + +__STATIC_INLINE void nrf_pwm_int_set(NRF_PWM_Type * p_reg, + uint32_t pwm_int_mask) +{ + p_reg->INTEN = pwm_int_mask; +} + +__STATIC_INLINE bool nrf_pwm_int_enable_check(NRF_PWM_Type const * p_reg, + nrf_pwm_int_mask_t pwm_int) +{ + return (bool)(p_reg->INTENSET & pwm_int); +} + +__STATIC_INLINE void nrf_pwm_enable(NRF_PWM_Type * p_reg) +{ + p_reg->ENABLE = (PWM_ENABLE_ENABLE_Enabled << PWM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_pwm_disable(NRF_PWM_Type * p_reg) +{ + p_reg->ENABLE = (PWM_ENABLE_ENABLE_Disabled << PWM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_pwm_pins_set(NRF_PWM_Type * p_reg, + uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]) +{ + uint8_t i; + for (i = 0; i < NRF_PWM_CHANNEL_COUNT; ++i) + { + p_reg->PSEL.OUT[i] = out_pins[i]; + } +} + +__STATIC_INLINE void nrf_pwm_configure(NRF_PWM_Type * p_reg, + nrf_pwm_clk_t base_clock, + nrf_pwm_mode_t mode, + uint16_t top_value) +{ + ASSERT(top_value <= PWM_COUNTERTOP_COUNTERTOP_Msk); + + p_reg->PRESCALER = base_clock; + p_reg->MODE = mode; + p_reg->COUNTERTOP = top_value; +} + +__STATIC_INLINE void nrf_pwm_sequence_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + nrf_pwm_sequence_t const * p_seq) +{ + ASSERT(p_seq != NULL); + + nrf_pwm_seq_ptr_set( p_reg, seq_id, p_seq->values.p_raw); + nrf_pwm_seq_cnt_set( p_reg, seq_id, p_seq->length); + nrf_pwm_seq_refresh_set( p_reg, seq_id, p_seq->repeats); + nrf_pwm_seq_end_delay_set(p_reg, seq_id, p_seq->end_delay); +} + +__STATIC_INLINE void nrf_pwm_seq_ptr_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint16_t const * p_values) +{ + ASSERT(seq_id <= 1); + ASSERT(p_values != NULL); + p_reg->SEQ[seq_id].PTR = (uint32_t)p_values; +} + +__STATIC_INLINE void nrf_pwm_seq_cnt_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint16_t length) +{ + ASSERT(seq_id <= 1); + ASSERT(length != 0); + ASSERT(length <= PWM_SEQ_CNT_CNT_Msk); + p_reg->SEQ[seq_id].CNT = length; +} + +__STATIC_INLINE void nrf_pwm_seq_refresh_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint32_t refresh) +{ + ASSERT(seq_id <= 1); + ASSERT(refresh <= PWM_SEQ_REFRESH_CNT_Msk); + p_reg->SEQ[seq_id].REFRESH = refresh; +} + +__STATIC_INLINE void nrf_pwm_seq_end_delay_set(NRF_PWM_Type * p_reg, + uint8_t seq_id, + uint32_t end_delay) +{ + ASSERT(seq_id <= 1); + ASSERT(end_delay <= PWM_SEQ_ENDDELAY_CNT_Msk); + p_reg->SEQ[seq_id].ENDDELAY = end_delay; +} + +__STATIC_INLINE void nrf_pwm_decoder_set(NRF_PWM_Type * p_reg, + nrf_pwm_dec_load_t dec_load, + nrf_pwm_dec_step_t dec_step) +{ + p_reg->DECODER = ((uint32_t)dec_load << PWM_DECODER_LOAD_Pos) | + ((uint32_t)dec_step << PWM_DECODER_MODE_Pos); +} + +__STATIC_INLINE void nrf_pwm_loop_set(NRF_PWM_Type * p_reg, + uint16_t loop_count) +{ + p_reg->LOOP = loop_count; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_PWM_H__ + +/** @} */ diff --git a/components/drivers_nrf/hal/nrf_qdec.h b/components/drivers_nrf/hal/nrf_qdec.h index 7b117ff..e6a0fcc 100644 --- a/components/drivers_nrf/hal/nrf_qdec.h +++ b/components/drivers_nrf/hal/nrf_qdec.h @@ -1,21 +1,53 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_QDEC_H__ #define NRF_QDEC_H__ -#include "stddef.h" +#include #include "nrf_error.h" #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + /*lint ++flb "Enter library region" */ /** @@ -228,15 +260,10 @@ __STATIC_INLINE uint32_t nrf_qdec_dbfen_get(void) */ __STATIC_INLINE void nrf_qdec_pio_assign( uint32_t psela, uint32_t pselb, uint32_t pselled) { -#ifdef NRF51 NRF_QDEC->PSELA = psela; NRF_QDEC->PSELB = pselb; NRF_QDEC->PSELLED = pselled; -#elif defined NRF52 - NRF_QDEC->PSEL.A = psela; - NRF_QDEC->PSEL.B = pselb; - NRF_QDEC->PSEL.LED = pselled; -#endif + } /** @@ -266,6 +293,10 @@ __STATIC_INLINE uint32_t * nrf_qdec_task_address_get(nrf_qdec_task_t qdec_task) __STATIC_INLINE void nrf_qdec_event_clear(nrf_qdec_event_t qdec_event) { *( (volatile uint32_t *)( (uint8_t *)NRF_QDEC + qdec_event) ) = 0; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_QDEC + qdec_event)); + (void)dummy; +#endif } @@ -326,7 +357,7 @@ __STATIC_INLINE int32_t nrf_qdec_sampleper_reg_get(void) */ __STATIC_INLINE uint32_t nrf_qdec_sampleper_to_value(uint32_t sampleper) { - return (1 << (7+sampleper)); + return (1 << (7 + sampleper)); } /** @@ -436,7 +467,7 @@ __STATIC_INLINE uint32_t nrf_qdec_reportper_reg_get(void) */ __STATIC_INLINE uint32_t nrf_qdec_reportper_to_value(uint32_t reportper) { - return (reportper == NRF_QDEC_REPORTPER_10) ? 10 : reportper*40; + return (reportper == NRF_QDEC_REPORTPER_10) ? 10 : reportper * 40; } @@ -465,4 +496,9 @@ __STATIC_INLINE uint32_t nrf_qdec_ledpol_get(void) **/ /*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_nrf/hal/nrf_qspi.h b/components/drivers_nrf/hal/nrf_qspi.h new file mode 100644 index 0000000..dd02fdd --- /dev/null +++ b/components/drivers_nrf/hal/nrf_qspi.h @@ -0,0 +1,766 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @defgroup nrf_qspi_hal QSPI HAL + * @{ + * @ingroup nrf_qspi + * + * @brief Hardware access layer for accessing the QSPI peripheral. + */ + +#ifndef NRF_QSPI_H__ +#define NRF_QSPI_H__ + +#include +#include +#include "boards.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief This value can be used as a parameter for the @ref nrf_qspi_pins_set + * function to specify that a given QSPI signal (SCK, CSN, IO0, IO1, IO2, or IO3) + * will not be connected to a physical pin. + */ +#define NRF_QSPI_PIN_NOT_CONNECTED 0xFF + +/** + * @brief Macro for setting proper values to pin registers. + */ + +#define NRF_QSPI_PIN_VAL(pin) (pin) == NRF_QSPI_PIN_NOT_CONNECTED ? 0xFFFFFFFF : (pin) + +/** + * @brief QSPI tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_QSPI_TASK_ACTIVATE = offsetof(NRF_QSPI_Type, TASKS_ACTIVATE), /**< Activate the QSPI interface. */ + NRF_QSPI_TASK_READSTART = offsetof(NRF_QSPI_Type, TASKS_READSTART), /**< Start transfer from external flash memory to internal RAM. */ + NRF_QSPI_TASK_WRITESTART = offsetof(NRF_QSPI_Type, TASKS_WRITESTART), /**< Start transfer from internal RAM to external flash memory. */ + NRF_QSPI_TASK_ERASESTART = offsetof(NRF_QSPI_Type, TASKS_ERASESTART), /**< Start external flash memory erase operation. */ + /*lint -restore*/ +} nrf_qspi_task_t; + +/** + * @brief QSPI events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_QSPI_EVENT_READY = offsetof(NRF_QSPI_Type, EVENTS_READY) /**< QSPI peripheral is ready after it executes any task. */ + /*lint -restore*/ +} nrf_qspi_event_t; + +/** + * @brief QSPI interrupts. + */ +typedef enum +{ + NRF_QSPI_INT_READY_MASK = QSPI_INTENSET_READY_Msk /**< Interrupt on READY event. */ +} nrf_qspi_int_mask_t; + +/** + * @brief QSPI frequency divider values. + */ +typedef enum +{ + NRF_QSPI_FREQ_32MDIV1, /**< 32.0 MHz. */ + NRF_QSPI_FREQ_32MDIV2, /**< 16.0 MHz. */ + NRF_QSPI_FREQ_32MDIV3, /**< 10.6 MHz. */ + NRF_QSPI_FREQ_32MDIV4, /**< 8.00 MHz. */ + NRF_QSPI_FREQ_32MDIV5, /**< 6.40 MHz. */ + NRF_QSPI_FREQ_32MDIV6, /**< 5.33 MHz. */ + NRF_QSPI_FREQ_32MDIV7, /**< 4.57 MHz. */ + NRF_QSPI_FREQ_32MDIV8, /**< 4.00 MHz. */ + NRF_QSPI_FREQ_32MDIV9, /**< 3.55 MHz. */ + NRF_QSPI_FREQ_32MDIV10, /**< 3.20 MHz. */ + NRF_QSPI_FREQ_32MDIV11, /**< 2.90 MHz. */ + NRF_QSPI_FREQ_32MDIV12, /**< 2.66 MHz. */ + NRF_QSPI_FREQ_32MDIV13, /**< 2.46 MHz. */ + NRF_QSPI_FREQ_32MDIV14, /**< 2.29 MHz. */ + NRF_QSPI_FREQ_32MDIV15, /**< 2.13 MHz. */ + NRF_QSPI_FREQ_32MDIV16, /**< 2.00 MHz. */ +} nrf_qspi_frequency_t; + +/** + * @brief Interface configuration for a read operation. + */ +typedef enum +{ + NRF_QSPI_READOC_FASTREAD = QSPI_IFCONFIG0_READOC_FASTREAD, /**< Single data line SPI. FAST_READ (opcode 0x0B). */ + NRF_QSPI_READOC_READ2O = QSPI_IFCONFIG0_READOC_READ2O, /**< Dual data line SPI. READ2O (opcode 0x3B). */ + NRF_QSPI_READOC_READ2IO = QSPI_IFCONFIG0_READOC_READ2IO, /**< Dual data line SPI. READ2IO (opcode 0xBB). */ + NRF_QSPI_READOC_READ4O = QSPI_IFCONFIG0_READOC_READ4O, /**< Quad data line SPI. READ4O (opcode 0x6B). */ + NRF_QSPI_READOC_READ4IO = QSPI_IFCONFIG0_READOC_READ4IO /**< Quad data line SPI. READ4IO (opcode 0xEB). */ +} nrf_qspi_readoc_t; + +/** + * @brief Interface configuration for a write operation. + */ +typedef enum +{ + NRF_QSPI_WRITEOC_PP = QSPI_IFCONFIG0_WRITEOC_PP, /**< Single data line SPI. PP (opcode 0x02). */ + NRF_QSPI_WRITEOC_PP2O = QSPI_IFCONFIG0_WRITEOC_PP2O, /**< Dual data line SPI. PP2O (opcode 0xA2). */ + NRF_QSPI_WRITEOC_PP4O = QSPI_IFCONFIG0_WRITEOC_PP4O, /**< Quad data line SPI. PP4O (opcode 0x32). */ + NRF_QSPI_WRITEOC_PP4IO = QSPI_IFCONFIG0_WRITEOC_PP4IO, /**< Quad data line SPI. READ4O (opcode 0x38). */ +} nrf_qspi_writeoc_t; + +/** + * @brief Interface configuration for addressing mode. + */ +typedef enum +{ + NRF_QSPI_ADDRMODE_24BIT = QSPI_IFCONFIG0_ADDRMODE_24BIT, /**< 24-bit addressing. */ + NRF_QSPI_ADDRMODE_32BIT = QSPI_IFCONFIG0_ADDRMODE_32BIT /**< 32-bit addressing. */ +} nrf_qspi_addrmode_t; + +/** + * @brief QSPI SPI mode. Polarization and phase configuration. + */ +typedef enum +{ + NRF_QSPI_MODE_0 = QSPI_IFCONFIG1_SPIMODE_MODE0, /**< Mode 0 (CPOL=0, CPHA=0). */ + NRF_QSPI_MODE_1 = QSPI_IFCONFIG1_SPIMODE_MODE3 /**< Mode 1 (CPOL=1, CPHA=1). */ +} nrf_qspi_spi_mode_t; + +/** + * @brief Addressing configuration mode. + */ +typedef enum +{ + NRF_QSPI_ADDRCONF_MODE_NOINSTR = QSPI_ADDRCONF_MODE_NoInstr, /**< Do not send any instruction. */ + NRF_QSPI_ADDRCONF_MODE_OPCODE = QSPI_ADDRCONF_MODE_Opcode, /**< Send opcode. */ + NRF_QSPI_ADDRCONF_MODE_OPBYTE0 = QSPI_ADDRCONF_MODE_OpByte0, /**< Send opcode, byte0. */ + NRF_QSPI_ADDRCONF_MODE_ALL = QSPI_ADDRCONF_MODE_All /**< Send opcode, byte0, byte1. */ +} nrf_qspi_addrconfig_mode_t; + +/** + * @brief Erasing data length. + */ +typedef enum +{ + NRF_QSPI_ERASE_LEN_4KB = QSPI_ERASE_LEN_LEN_4KB, /**< Erase 4 kB block (flash command 0x20). */ + NRF_QSPI_ERASE_LEN_64KB = QSPI_ERASE_LEN_LEN_64KB, /**< Erase 64 kB block (flash command 0xD8). */ + NRF_QSPI_ERASE_LEN_ALL = QSPI_ERASE_LEN_LEN_All /**< Erase all (flash command 0xC7). */ +} nrf_qspi_erase_len_t; + +/** + * @brief Custom instruction length. + */ +typedef enum +{ + NRF_QSPI_CINSTR_LEN_1B = QSPI_CINSTRCONF_LENGTH_1B, /**< Send opcode only. */ + NRF_QSPI_CINSTR_LEN_2B = QSPI_CINSTRCONF_LENGTH_2B, /**< Send opcode, CINSTRDAT0.BYTE0. */ + NRF_QSPI_CINSTR_LEN_3B = QSPI_CINSTRCONF_LENGTH_3B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE1. */ + NRF_QSPI_CINSTR_LEN_4B = QSPI_CINSTRCONF_LENGTH_4B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE2. */ + NRF_QSPI_CINSTR_LEN_5B = QSPI_CINSTRCONF_LENGTH_5B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT0.BYTE3. */ + NRF_QSPI_CINSTR_LEN_6B = QSPI_CINSTRCONF_LENGTH_6B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE4. */ + NRF_QSPI_CINSTR_LEN_7B = QSPI_CINSTRCONF_LENGTH_7B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE5. */ + NRF_QSPI_CINSTR_LEN_8B = QSPI_CINSTRCONF_LENGTH_8B, /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE6. */ + NRF_QSPI_CINSTR_LEN_9B = QSPI_CINSTRCONF_LENGTH_9B /**< Send opcode, CINSTRDAT0.BYTE0 -> CINSTRDAT1.BYTE7. */ +} nrf_qspi_cinstr_len_t; + +/** + * @brief Pins configuration. + */ +typedef struct +{ + uint8_t sck_pin; /**< SCK pin number. */ + uint8_t csn_pin; /**< Chip select pin number. */ + uint8_t io0_pin; /**< IO0/MOSI pin number. */ + uint8_t io1_pin; /**< IO1/MISO pin number. */ + uint8_t io2_pin; /**< IO2 pin number (optional). + * Set to @ref NRF_QSPI_PIN_NOT_CONNECTED if this signal is not needed. + */ + uint8_t io3_pin; /**< IO3 pin number (optional). + * Set to @ref NRF_QSPI_PIN_NOT_CONNECTED if this signal is not needed. + */ +} nrf_qspi_pins_t; + +/** + * @brief Custom instruction configuration. + */ +typedef struct +{ + uint8_t opcode; /**< Opcode used in custom instruction transmission. */ + nrf_qspi_cinstr_len_t length; /**< Length of the custom instruction data. */ + bool io2_level; /**< I/O line level during transmission. */ + bool io3_level; /**< I/O line level during transmission. */ + bool wipwait; /**< Wait if a Wait in Progress bit is set in the memory status byte. */ + bool wren; /**< Send write enable before instruction. */ +} nrf_qspi_cinstr_conf_t; + +/** + * @brief Addressing mode register configuration. See @ref nrf_qspi_addrconfig_set + */ +typedef struct +{ + uint8_t opcode; /**< Opcode used to enter proper addressing mode. */ + uint8_t byte0; /**< Byte following the opcode. */ + uint8_t byte1; /**< Byte following byte0. */ + nrf_qspi_addrconfig_mode_t mode; /**< Extended addresing mode. */ + bool wipwait; /**< Enable/disable waiting for complete operation execution. */ + bool wren; /**< Send write enable before instruction. */ +} nrf_qspi_addrconfig_conf_t; + +/** + * @brief Structure with QSPI protocol interface configuration. + */ +typedef struct +{ + nrf_qspi_readoc_t readoc; /**< Read operation code. */ + nrf_qspi_writeoc_t writeoc; /**< Write operation code. */ + nrf_qspi_addrmode_t addrmode; /**< Addresing mode (24-bit or 32-bit). */ + bool dpmconfig; /**< Enable the Deep Power-down Mode (DPM) feature. */ +} nrf_qspi_prot_conf_t; + +/** + * @brief QSPI physical interface configuration. + */ +typedef struct +{ + uint8_t sck_delay; /**< tSHSL, tWHSL, and tSHWL in number of 16 MHz periods (62.5ns). */ + bool dpmen; /**< Enable the DPM feature. */ + nrf_qspi_spi_mode_t spi_mode; /**< SPI phase and polarization. */ + nrf_qspi_frequency_t sck_freq; /**< SCK frequency given as enum @ref nrf_qspi_frequency_t. */ +} nrf_qspi_phy_conf_t; + +/** + * @brief Function for activating a specific QSPI task. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_qspi_task_trigger(NRF_QSPI_Type * p_reg, nrf_qspi_task_t task); + +/** + * @brief Function for getting the address of a specific QSPI task register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t nrf_qspi_task_address_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_task_t task); + +/** + * @brief Function for clearing a specific QSPI event. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_event Event to clear. + */ +__STATIC_INLINE void nrf_qspi_event_clear(NRF_QSPI_Type * p_reg, nrf_qspi_event_t qspi_event); + +/** + * @brief Function for checking the state of a specific SPI event. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_qspi_event_check(NRF_QSPI_Type const * p_reg, nrf_qspi_event_t qspi_event); + +/** + * @brief Function for getting the address of a specific QSPI event register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_qspi_event_address_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_event_t qspi_event); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_qspi_int_enable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_qspi_int_disable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask); + +/** + * @brief Function for retrieving the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] qspi_int Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_qspi_int_enable_check(NRF_QSPI_Type const * p_reg, + nrf_qspi_int_mask_t qspi_int); + +/** + * @brief Function for enabling the QSPI peripheral. + * + * @param[in] p_reg Pointer to the peripheral register structure. + */ +__STATIC_INLINE void nrf_qspi_enable(NRF_QSPI_Type * p_reg); + +/** + * @brief Function for disabling the QSPI peripheral. + * + * @param[in] p_reg Pointer to the peripheral register structure. + */ +__STATIC_INLINE void nrf_qspi_disable(NRF_QSPI_Type * p_reg); + +/** + * @brief Function for configuring QSPI pins. + * + * If a given signal is not needed, pass the @ref NRF_QSPI_PIN_NOT_CONNECTED + * value instead of its pin number. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_pins Pointer to the pins configuration structure. See @ref nrf_qspi_pins_t. + */ +__STATIC_INLINE void nrf_qspi_pins_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_pins_t * p_pins); + +/** + * @brief Function for setting the QSPI IFCONFIG0 register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_config Pointer to the QSPI protocol interface configuration structure. See @ref nrf_qspi_prot_conf_t. + */ +__STATIC_INLINE void nrf_qspi_ifconfig0_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_prot_conf_t * p_config); + +/** + * @brief Function for setting the QSPI IFCONFIG1 register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_config Pointer to the QSPI physical interface configuration structure. See @ref nrf_qspi_phy_conf_t. + */ +__STATIC_INLINE void nrf_qspi_ifconfig1_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_phy_conf_t * p_config); + +/** + * @brief Function for setting the QSPI ADDRCONF register. + * + * Function must be executed before sending task NRF_QSPI_TASK_ACTIVATE. Data stored in the structure + * is sent during the start of the peripheral. Remember that the reset instruction can set + * addressing mode to default in the memory device. If memory reset is necessary before configuring + * the addressing mode, use custom instruction feature instead of this function. + * Case with reset: Enable the peripheral without setting ADDRCONF register, send reset instructions + * using a custom instruction feature (reset enable and then reset), set proper addressing mode + * using the custom instruction feature. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_config Pointer to the addressing mode configuration structure. See @ref nrf_qspi_addrconfig_conf_t. +*/ +__STATIC_INLINE void nrf_qspi_addrconfig_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_addrconfig_conf_t * p_config); + +/** + * @brief Function for setting write data into the peripheral register (without starting the process). + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_buffer Pointer to the writing buffer. + * @param[in] length Lenght of the writing data. + * @param[in] dest_addr Address in memory to write to. + */ +__STATIC_INLINE void nrf_qspi_write_buffer_set(NRF_QSPI_Type * p_reg, + void const * p_buffer, + uint32_t length, + uint32_t dest_addr); + +/** + * @brief Function for setting read data into the peripheral register (without starting the process). + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[out] p_buffer Pointer to the reading buffer. + * @param[in] length Length of the read data. + * @param[in] src_addr Address in memory to read from. + */ +__STATIC_INLINE void nrf_qspi_read_buffer_set(NRF_QSPI_Type * p_reg, + void * p_buffer, + uint32_t length, + uint32_t src_addr); + +/** + * @brief Function for setting erase data into the peripheral register (without starting the process). + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] erase_addr Start address to erase. Address must have padding set to 4 bytes. + * @param[in] len Size of erasing area. + */ +__STATIC_INLINE void nrf_qspi_erase_ptr_set(NRF_QSPI_Type * p_reg, + uint32_t erase_addr, + nrf_qspi_erase_len_t len); + +/** + * @brief Function for getting the peripheral status register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * + * @return Peripheral status register. + */ +__STATIC_INLINE uint32_t nrf_qspi_status_reg_get(NRF_QSPI_Type const * p_reg); + +/** + * @brief Function for getting the device status register stored in the peripheral status register. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * + * @return Device status register (lower byte). + */ +__STATIC_INLINE uint8_t nrf_qspi_sreg_get(NRF_QSPI_Type const * p_reg); + +/** + * @brief Function for checking if the peripheral is busy or not. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * + * @retval true If QSPI is busy. + * @retval false If QSPI is ready. + */ +__STATIC_INLINE bool nrf_qspi_busy_check(NRF_QSPI_Type const * p_reg); + +/** + * @brief Function for setting registers sending with custom instruction transmission. + * + * This function can be ommited when using NRF_QSPI_CINSTR_LEN_1B as the length argument + * (sending only opcode without data). + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] length Length of the custom instruction data. + * @param[in] p_tx_data Pointer to the data to send with the custom instruction. + */ +__STATIC_INLINE void nrf_qspi_cinstrdata_set(NRF_QSPI_Type * p_reg, + nrf_qspi_cinstr_len_t length, + void const * p_tx_data); + +/** + * @brief Function for getting data from register after custom instruction transmission. + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] length Length of the custom instruction data. + * @param[in] p_rx_data Pointer to the reading buffer. + */ +__STATIC_INLINE void nrf_qspi_cinstrdata_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_cinstr_len_t length, + void * p_rx_data); + +/** + * @brief Function for sending custom instruction to external memory. + * + * @param[in] p_reg Pointer to the peripheral register structure. + * @param[in] p_config Pointer to the custom instruction configuration structure. See @ref nrf_qspi_cinstr_conf_t. + */ + +__STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * p_reg, + const nrf_qspi_cinstr_conf_t * p_config); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_qspi_task_trigger(NRF_QSPI_Type * p_reg, nrf_qspi_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t nrf_qspi_task_address_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_task_t task) +{ + return ((uint32_t)p_reg + (uint32_t)task); +} + +__STATIC_INLINE void nrf_qspi_event_clear(NRF_QSPI_Type * p_reg, nrf_qspi_event_t qspi_event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event)) = 0x0UL; +} + +__STATIC_INLINE bool nrf_qspi_event_check(NRF_QSPI_Type const * p_reg, nrf_qspi_event_t qspi_event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event); +} + +__STATIC_INLINE uint32_t * nrf_qspi_event_address_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_event_t qspi_event) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)qspi_event); +} + +__STATIC_INLINE void nrf_qspi_int_enable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask) +{ + p_reg->INTENSET = qspi_int_mask; +} + +__STATIC_INLINE void nrf_qspi_int_disable(NRF_QSPI_Type * p_reg, uint32_t qspi_int_mask) +{ + p_reg->INTENCLR = qspi_int_mask; +} + +__STATIC_INLINE bool nrf_qspi_int_enable_check(NRF_QSPI_Type const * p_reg, + nrf_qspi_int_mask_t qspi_int) +{ + return (bool)(p_reg->INTENSET & qspi_int); +} + +__STATIC_INLINE void nrf_qspi_enable(NRF_QSPI_Type * p_reg) +{ + p_reg->ENABLE = (QSPI_ENABLE_ENABLE_Enabled << QSPI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_qspi_disable(NRF_QSPI_Type * p_reg) +{ + p_reg->ENABLE = (QSPI_ENABLE_ENABLE_Disabled << QSPI_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_qspi_pins_set(NRF_QSPI_Type * p_reg, const nrf_qspi_pins_t * p_pins) +{ + p_reg->PSEL.SCK = NRF_QSPI_PIN_VAL(p_pins->sck_pin); + p_reg->PSEL.CSN = NRF_QSPI_PIN_VAL(p_pins->csn_pin); + p_reg->PSEL.IO0 = NRF_QSPI_PIN_VAL(p_pins->io0_pin); + p_reg->PSEL.IO1 = NRF_QSPI_PIN_VAL(p_pins->io1_pin); + p_reg->PSEL.IO2 = NRF_QSPI_PIN_VAL(p_pins->io2_pin); + p_reg->PSEL.IO3 = NRF_QSPI_PIN_VAL(p_pins->io3_pin); +} + +__STATIC_INLINE void nrf_qspi_ifconfig0_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_prot_conf_t * p_config) +{ + uint32_t config = p_config->readoc; + config |= ((uint32_t)p_config->writeoc) << QSPI_IFCONFIG0_WRITEOC_Pos; + config |= ((uint32_t)p_config->addrmode) << QSPI_IFCONFIG0_ADDRMODE_Pos; + config |= (p_config->dpmconfig ? 1U : 0U ) << QSPI_IFCONFIG0_DPMENABLE_Pos; + + p_reg->IFCONFIG0 = config; +} + +__STATIC_INLINE void nrf_qspi_ifconfig1_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_phy_conf_t * p_config) +{ + // IFCONFIG1 mask for reserved fields in the register. + uint32_t config = p_reg->IFCONFIG1 & 0x00FFFF00; + config |= p_config->sck_delay; + config |= (p_config->dpmen ? 1U : 0U) << QSPI_IFCONFIG1_DPMEN_Pos; + config |= ((uint32_t)(p_config->spi_mode)) << QSPI_IFCONFIG1_SPIMODE_Pos; + config |= ((uint32_t)(p_config->sck_freq)) << QSPI_IFCONFIG1_SCKFREQ_Pos; + + p_reg->IFCONFIG1 = config; +} + +__STATIC_INLINE void nrf_qspi_addrconfig_set(NRF_QSPI_Type * p_reg, + const nrf_qspi_addrconfig_conf_t * p_config) +{ + uint32_t config = p_config->opcode; + config |= ((uint32_t)p_config->byte0) << QSPI_ADDRCONF_BYTE0_Pos; + config |= ((uint32_t)p_config->byte1) << QSPI_ADDRCONF_BYTE1_Pos; + config |= ((uint32_t)(p_config->mode)) << QSPI_ADDRCONF_MODE_Pos; + config |= (p_config->wipwait ? 1U : 0U) << QSPI_ADDRCONF_WIPWAIT_Pos; + config |= (p_config->wren ? 1U : 0U) << QSPI_ADDRCONF_WREN_Pos; + + p_reg->ADDRCONF = config; +} + +__STATIC_INLINE void nrf_qspi_write_buffer_set(NRF_QSPI_Type * p_reg, + void const * p_buffer, + uint32_t length, + uint32_t dest_addr) +{ + p_reg->WRITE.DST = dest_addr; + p_reg->WRITE.SRC = (uint32_t) p_buffer; + p_reg->WRITE.CNT = length; +} + +__STATIC_INLINE void nrf_qspi_read_buffer_set(NRF_QSPI_Type * p_reg, + void * p_buffer, + uint32_t length, + uint32_t src_addr) +{ + p_reg->READ.SRC = src_addr; + p_reg->READ.DST = (uint32_t) p_buffer; + p_reg->READ.CNT = length; +} + +__STATIC_INLINE void nrf_qspi_erase_ptr_set(NRF_QSPI_Type * p_reg, + uint32_t erase_addr, + nrf_qspi_erase_len_t len) +{ + p_reg->ERASE.PTR = erase_addr; + p_reg->ERASE.LEN = len; +} + +__STATIC_INLINE uint32_t nrf_qspi_status_reg_get(NRF_QSPI_Type const * p_reg) +{ + return p_reg->STATUS; +} + +__STATIC_INLINE uint8_t nrf_qspi_sreg_get(NRF_QSPI_Type const * p_reg) +{ + return (uint8_t)(p_reg->STATUS & QSPI_STATUS_SREG_Msk) >> QSPI_STATUS_SREG_Pos; +} + +__STATIC_INLINE bool nrf_qspi_busy_check(NRF_QSPI_Type const * p_reg) +{ + return ((p_reg->STATUS & QSPI_STATUS_READY_Msk) >> + QSPI_STATUS_READY_Pos) == QSPI_STATUS_READY_BUSY; +} + +__STATIC_INLINE void nrf_qspi_cinstrdata_set(NRF_QSPI_Type * p_reg, + nrf_qspi_cinstr_len_t length, + void const * p_tx_data) +{ + uint32_t reg = 0; + uint8_t const *p_tx_data_8 = (uint8_t const *) p_tx_data; + + // Load custom instruction. + switch (length) + { + case NRF_QSPI_CINSTR_LEN_9B: + reg |= ((uint32_t)p_tx_data_8[7]) << QSPI_CINSTRDAT1_BYTE7_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_8B: + reg |= ((uint32_t)p_tx_data_8[6]) << QSPI_CINSTRDAT1_BYTE6_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_7B: + reg |= ((uint32_t)p_tx_data_8[5]) << QSPI_CINSTRDAT1_BYTE5_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_6B: + reg |= ((uint32_t)p_tx_data_8[4]); + p_reg->CINSTRDAT1 = reg; + reg = 0; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_5B: + reg |= ((uint32_t)p_tx_data_8[3]) << QSPI_CINSTRDAT0_BYTE3_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_4B: + reg |= ((uint32_t)p_tx_data_8[2]) << QSPI_CINSTRDAT0_BYTE2_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_3B: + reg |= ((uint32_t)p_tx_data_8[1]) << QSPI_CINSTRDAT0_BYTE1_Pos; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_2B: + reg |= ((uint32_t)p_tx_data_8[0]); + p_reg->CINSTRDAT0 = reg; + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_1B: + /* Send only opcode. Case to avoid compiler warnings. */ + break; + default: + break; + } +} + +__STATIC_INLINE void nrf_qspi_cinstrdata_get(NRF_QSPI_Type const * p_reg, + nrf_qspi_cinstr_len_t length, + void * p_rx_data) +{ + uint8_t *p_rx_data_8 = (uint8_t *) p_rx_data; + + uint32_t reg = p_reg->CINSTRDAT1; + switch (length) + { + case NRF_QSPI_CINSTR_LEN_9B: + p_rx_data_8[7] = (uint8_t)(reg >> QSPI_CINSTRDAT1_BYTE7_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_8B: + p_rx_data_8[6] = (uint8_t)(reg >> QSPI_CINSTRDAT1_BYTE6_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_7B: + p_rx_data_8[5] = (uint8_t)(reg >> QSPI_CINSTRDAT1_BYTE5_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_6B: + p_rx_data_8[4] = (uint8_t)(reg); + /* fall-through */ + default: + break; + } + + reg = p_reg->CINSTRDAT0; + switch (length) + { + case NRF_QSPI_CINSTR_LEN_5B: + p_rx_data_8[3] = (uint8_t)(reg >> QSPI_CINSTRDAT0_BYTE3_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_4B: + p_rx_data_8[2] = (uint8_t)(reg >> QSPI_CINSTRDAT0_BYTE2_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_3B: + p_rx_data_8[1] = (uint8_t)(reg >> QSPI_CINSTRDAT0_BYTE1_Pos); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_2B: + p_rx_data_8[0] = (uint8_t)(reg); + /* fall-through */ + case NRF_QSPI_CINSTR_LEN_1B: + /* Send only opcode. Case to avoid compiler warnings. */ + break; + default: + break; + } +} + +__STATIC_INLINE void nrf_qspi_cinstr_transfer_start(NRF_QSPI_Type * p_reg, + const nrf_qspi_cinstr_conf_t * p_config) +{ + p_reg->CINSTRCONF = (((uint32_t)p_config->opcode << QSPI_CINSTRCONF_OPCODE_Pos) | + ((uint32_t)p_config->length << QSPI_CINSTRCONF_LENGTH_Pos) | + ((uint32_t)p_config->io2_level << QSPI_CINSTRCONF_LIO2_Pos) | + ((uint32_t)p_config->io3_level << QSPI_CINSTRCONF_LIO3_Pos) | + ((uint32_t)p_config->wipwait << QSPI_CINSTRCONF_WIPWAIT_Pos) | + ((uint32_t)p_config->wren << QSPI_CINSTRCONF_WREN_Pos)); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#ifdef __cplusplus +} +#endif + +#endif // NRF_QSPI_H__ + +/** @} */ diff --git a/components/drivers_nrf/hal/nrf_rng.h b/components/drivers_nrf/hal/nrf_rng.h index 00d5308..f1875e0 100644 --- a/components/drivers_nrf/hal/nrf_rng.h +++ b/components/drivers_nrf/hal/nrf_rng.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -29,6 +57,10 @@ #include #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + #define NRF_RNG_TASK_SET (1UL) #define NRF_RNG_EVENT_CLEAR (0UL) /** @@ -102,7 +134,7 @@ __STATIC_INLINE bool nrf_rng_int_get(nrf_rng_int_mask_t rng_int_mask) } /** - * @brief Function for getting the address of a specific task. + * @brief Function for getting the address of a specific task. * * This function can be used by the PPI module. * @@ -124,7 +156,7 @@ __STATIC_INLINE void nrf_rng_task_trigger(nrf_rng_task_t rng_task) } /** - * @brief Function for getting address of a specific event. + * @brief Function for getting address of a specific event. * * This function can be used by the PPI module. * @@ -143,6 +175,10 @@ __STATIC_INLINE uint32_t * nrf_rng_event_address_get(nrf_rng_event_t rng_event) __STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event) { *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)) = NRF_RNG_EVENT_CLEAR; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)); + (void)dummy; +#endif } /** @@ -155,7 +191,7 @@ __STATIC_INLINE void nrf_rng_event_clear(nrf_rng_event_t rng_event) */ __STATIC_INLINE bool nrf_rng_event_get(nrf_rng_event_t rng_event) { - return (bool)*((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)); + return (bool) * ((volatile uint32_t *)((uint8_t *)NRF_RNG + rng_event)); } /** @@ -208,4 +244,9 @@ __STATIC_INLINE void nrf_rng_error_correction_disable(void) /** *@} **/ + +#ifdef __cplusplus +} +#endif + #endif /* NRF_RNG_H__ */ diff --git a/components/drivers_nrf/hal/nrf_rtc.h b/components/drivers_nrf/hal/nrf_rtc.h index ecdc6a5..f341b6a 100644 --- a/components/drivers_nrf/hal/nrf_rtc.h +++ b/components/drivers_nrf/hal/nrf_rtc.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -30,16 +58,31 @@ #include #include "nrf.h" #include "nrf_assert.h" +#include "nrf_peripherals.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Macro for getting the number of compare channels available + * in a given RTC instance. + */ -#define RTC_CHANNEL_NUM 4 /**< Number of compare channels in the RTC instance. */ +#define NRF_RTC_CC_CHANNEL_COUNT(id) CONCAT_3(RTC, id, _CC_NUM) #define RTC_INPUT_FREQ 32768 /**< Input frequency of the RTC instance. */ +/** + * @brief Macro for converting expected frequency to prescaler setting. + */ +#define RTC_FREQ_TO_PRESCALER(FREQ) (uint16_t)((RTC_INPUT_FREQ / (FREQ)) - 1) + /**< Macro for wrapping values to RTC capacity. */ #define RTC_WRAP(val) (val & RTC_COUNTER_COUNTER_Msk) #define RTC_CHANNEL_INT_MASK(ch) ((uint32_t)NRF_RTC_INT_COMPARE0_MASK << ch) -#define RTC_CHANNEL_EVENT_ADDR(ch) (nrf_rtc_event_t)(NRF_RTC_EVENT_COMPARE_0 + ch*sizeof(uint32_t)) +#define RTC_CHANNEL_EVENT_ADDR(ch) (nrf_rtc_event_t)(NRF_RTC_EVENT_COMPARE_0 + ch * sizeof(uint32_t)) /** * @enum nrf_rtc_task_t * @brief RTC tasks. @@ -86,7 +129,7 @@ typedef enum /**@brief Function for setting a compare value for a channel. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] ch Channel. * @param[in] cc_val Compare value to set. */ @@ -94,7 +137,7 @@ __STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_rtc, uint32_t ch, uint32_t /**@brief Function for returning the compare value for a channel. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] ch Channel. * * @return COMPARE[ch] value. @@ -103,21 +146,21 @@ __STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_rtc, uint32_t ch); /**@brief Function for enabling interrupts. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] mask Interrupt mask to be enabled. */ __STATIC_INLINE void nrf_rtc_int_enable(NRF_RTC_Type * p_rtc, uint32_t mask); /**@brief Function for disabling interrupts. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] mask Interrupt mask to be disabled. */ __STATIC_INLINE void nrf_rtc_int_disable(NRF_RTC_Type * p_rtc, uint32_t mask); /**@brief Function for checking if interrupts are enabled. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] mask Mask of interrupt flags to check. * * @return Mask with enabled interrupts. @@ -126,7 +169,7 @@ __STATIC_INLINE uint32_t nrf_rtc_int_is_enabled(NRF_RTC_Type * p_rtc, uint32_t m /**@brief Function for returning the status of currently enabled interrupts. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * * @return Value in INTEN register. */ @@ -134,7 +177,7 @@ __STATIC_INLINE uint32_t nrf_rtc_int_get(NRF_RTC_Type * p_rtc); /**@brief Function for checking if an event is pending. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] event Address of the event. * * @return Mask of pending events. @@ -143,14 +186,14 @@ __STATIC_INLINE uint32_t nrf_rtc_event_pending(NRF_RTC_Type * p_rtc, nrf_rtc_eve /**@brief Function for clearing an event. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] event Event to clear. */ __STATIC_INLINE void nrf_rtc_event_clear(NRF_RTC_Type * p_rtc, nrf_rtc_event_t event); /**@brief Function for returning a counter value. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * * @return Counter value. */ @@ -158,14 +201,14 @@ __STATIC_INLINE uint32_t nrf_rtc_counter_get(NRF_RTC_Type * p_rtc); /**@brief Function for setting a prescaler value. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] val Value to set the prescaler to. */ __STATIC_INLINE void nrf_rtc_prescaler_set(NRF_RTC_Type * p_rtc, uint32_t val); /**@brief Function for returning the address of an event. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] event Requested event. * * @return Address of the requested event register. @@ -174,7 +217,7 @@ __STATIC_INLINE uint32_t nrf_rtc_event_address_get(NRF_RTC_Type * p_rtc, nrf_rtc /**@brief Function for returning the address of a task. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] task Requested task. * * @return Address of the requested task register. @@ -183,21 +226,21 @@ __STATIC_INLINE uint32_t nrf_rtc_task_address_get(NRF_RTC_Type * p_rtc, nrf_rtc_ /**@brief Function for starting a task. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] task Requested task. */ __STATIC_INLINE void nrf_rtc_task_trigger(NRF_RTC_Type * p_rtc, nrf_rtc_task_t task); /**@brief Function for enabling events. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] mask Mask of event flags to enable. */ __STATIC_INLINE void nrf_rtc_event_enable(NRF_RTC_Type * p_rtc, uint32_t mask); /**@brief Function for disabling an event. * - * @param[in] p_rtc Pointer to the instance register structure. + * @param[in] p_rtc Pointer to the peripheral registers structure. * @param[in] event Requested event. */ __STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t event); @@ -211,13 +254,11 @@ __STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t event) __STATIC_INLINE void nrf_rtc_cc_set(NRF_RTC_Type * p_rtc, uint32_t ch, uint32_t cc_val) { - ASSERT(chCC[ch] = cc_val; } __STATIC_INLINE uint32_t nrf_rtc_cc_get(NRF_RTC_Type * p_rtc, uint32_t ch) { - ASSERT(chCC[ch]; } @@ -295,4 +336,9 @@ __STATIC_INLINE void nrf_rtc_event_disable(NRF_RTC_Type * p_rtc, uint32_t mask) } #endif + +#ifdef __cplusplus +} +#endif + #endif /* NRF_RTC_H */ diff --git a/components/drivers_nrf/hal/nrf_saadc.c b/components/drivers_nrf/hal/nrf_saadc.c index b2d5cc8..f932c42 100644 --- a/components/drivers_nrf/hal/nrf_saadc.c +++ b/components/drivers_nrf/hal/nrf_saadc.c @@ -1,31 +1,63 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @brief SAADC HAL implementation */ - +#include "sdk_config.h" +#if SAADC_ENABLED #include "nrf_saadc.h" void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * const config) { - NRF_SAADC->CH[channel].CONFIG = + NRF_SAADC->CH[channel].CONFIG = ((config->resistor_p << SAADC_CH_CONFIG_RESP_Pos) & SAADC_CH_CONFIG_RESP_Msk) | ((config->resistor_n << SAADC_CH_CONFIG_RESN_Pos) & SAADC_CH_CONFIG_RESN_Msk) | ((config->gain << SAADC_CH_CONFIG_GAIN_Pos) & SAADC_CH_CONFIG_GAIN_Msk) | ((config->reference << SAADC_CH_CONFIG_REFSEL_Pos) & SAADC_CH_CONFIG_REFSEL_Msk) | ((config->acq_time << SAADC_CH_CONFIG_TACQ_Pos) & SAADC_CH_CONFIG_TACQ_Msk) - | ((config->mode << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk); + | ((config->mode << SAADC_CH_CONFIG_MODE_Pos) & SAADC_CH_CONFIG_MODE_Msk) + | ((config->burst << SAADC_CH_CONFIG_BURST_Pos) & SAADC_CH_CONFIG_BURST_Msk); nrf_saadc_channel_input_set(channel, config->pin_p, config->pin_n); return; } +#endif //SAADC_ENABLED + diff --git a/components/drivers_nrf/hal/nrf_saadc.h b/components/drivers_nrf/hal/nrf_saadc.h index 6888977..951b4e0 100644 --- a/components/drivers_nrf/hal/nrf_saadc.h +++ b/components/drivers_nrf/hal/nrf_saadc.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ @@ -19,7 +47,7 @@ * @{ * @ingroup nrf_saadc * - * @brief Hardware access layer for accessing the SAADC peripheral. + * @brief @tagAPI52 Hardware access layer for accessing the SAADC peripheral. */ #include @@ -27,6 +55,10 @@ #include "nrf.h" #include "nrf_assert.h" +#ifdef __cplusplus +extern "C" { +#endif + #define NRF_SAADC_CHANNEL_COUNT 8 /** @@ -138,6 +170,16 @@ typedef enum } nrf_saadc_mode_t; +/** + * @brief Analog-to-digital converter channel burst mode. + */ +typedef enum +{ + NRF_SAADC_BURST_DISABLED = SAADC_CH_CONFIG_BURST_Disabled, ///< Burst mode is disabled (normal operation). + NRF_SAADC_BURST_ENABLED = SAADC_CH_CONFIG_BURST_Enabled ///< Burst mode is enabled. SAADC takes 2^OVERSAMPLE number of samples as fast as it can, and sends the average to Data RAM. +} nrf_saadc_burst_t; + + /** * @brief Analog-to-digital converter tasks. */ @@ -157,6 +199,8 @@ typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ { NRF_SAADC_EVENT_STARTED = offsetof(NRF_SAADC_Type, EVENTS_STARTED), ///< The ADC has started. NRF_SAADC_EVENT_END = offsetof(NRF_SAADC_Type, EVENTS_END), ///< The ADC has filled up the result buffer. + NRF_SAADC_EVENT_DONE = offsetof(NRF_SAADC_Type, EVENTS_DONE), ///< A conversion task has been completed. + NRF_SAADC_EVENT_RESULTDONE = offsetof(NRF_SAADC_Type, EVENTS_RESULTDONE), ///< A result is ready to get transferred to RAM. NRF_SAADC_EVENT_CALIBRATEDONE = offsetof(NRF_SAADC_Type, EVENTS_CALIBRATEDONE), ///< Calibration is complete. NRF_SAADC_EVENT_STOPPED = offsetof(NRF_SAADC_Type, EVENTS_STOPPED), ///< The ADC has stopped. NRF_SAADC_EVENT_CH0_LIMITH = offsetof(NRF_SAADC_Type, EVENTS_CH[0].LIMITH), ///< Last result is equal or above CH[0].LIMIT.HIGH. @@ -183,25 +227,29 @@ typedef enum /*lint -save -e30 -esym(628,__INTADDR__) */ */ typedef enum { - NRF_SAADC_INT_STARTED = SAADC_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event. - NRF_SAADC_INT_END = SAADC_INTENSET_END_Msk, ///< Interrupt on EVENTS_END event. - NRF_SAADC_INT_STOPPED = SAADC_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event. - NRF_SAADC_INT_CH0LIMITH = SAADC_INTENSET_CH0LIMITH_Msk, ///< Interrupt on EVENTS_CH[0].LIMITH event. - NRF_SAADC_INT_CH0LIMITL = SAADC_INTENSET_CH0LIMITL_Msk, ///< Interrupt on EVENTS_CH[0].LIMITL event. - NRF_SAADC_INT_CH1LIMITH = SAADC_INTENSET_CH1LIMITH_Msk, ///< Interrupt on EVENTS_CH[1].LIMITH event. - NRF_SAADC_INT_CH1LIMITL = SAADC_INTENSET_CH1LIMITL_Msk, ///< Interrupt on EVENTS_CH[1].LIMITL event. - NRF_SAADC_INT_CH2LIMITH = SAADC_INTENSET_CH2LIMITH_Msk, ///< Interrupt on EVENTS_CH[2].LIMITH event. - NRF_SAADC_INT_CH2LIMITL = SAADC_INTENSET_CH2LIMITL_Msk, ///< Interrupt on EVENTS_CH[2].LIMITL event. - NRF_SAADC_INT_CH3LIMITH = SAADC_INTENSET_CH3LIMITH_Msk, ///< Interrupt on EVENTS_CH[3].LIMITH event. - NRF_SAADC_INT_CH3LIMITL = SAADC_INTENSET_CH3LIMITL_Msk, ///< Interrupt on EVENTS_CH[3].LIMITL event. - NRF_SAADC_INT_CH4LIMITH = SAADC_INTENSET_CH4LIMITH_Msk, ///< Interrupt on EVENTS_CH[4].LIMITH event. - NRF_SAADC_INT_CH4LIMITL = SAADC_INTENSET_CH4LIMITL_Msk, ///< Interrupt on EVENTS_CH[4].LIMITL event. - NRF_SAADC_INT_CH5LIMITH = SAADC_INTENSET_CH5LIMITH_Msk, ///< Interrupt on EVENTS_CH[5].LIMITH event. - NRF_SAADC_INT_CH5LIMITL = SAADC_INTENSET_CH5LIMITL_Msk, ///< Interrupt on EVENTS_CH[5].LIMITL event. - NRF_SAADC_INT_CH6LIMITH = SAADC_INTENSET_CH6LIMITH_Msk, ///< Interrupt on EVENTS_CH[6].LIMITH event. - NRF_SAADC_INT_CH6LIMITL = SAADC_INTENSET_CH6LIMITL_Msk, ///< Interrupt on EVENTS_CH[6].LIMITL event. - NRF_SAADC_INT_CH7LIMITH = SAADC_INTENSET_CH7LIMITH_Msk, ///< Interrupt on EVENTS_CH[7].LIMITH event. - NRF_SAADC_INT_CH7LIMITL = SAADC_INTENSET_CH7LIMITL_Msk, ///< Interrupt on EVENTS_CH[7].LIMITL event. + NRF_SAADC_INT_STARTED = SAADC_INTENSET_STARTED_Msk, ///< Interrupt on EVENTS_STARTED event. + NRF_SAADC_INT_END = SAADC_INTENSET_END_Msk, ///< Interrupt on EVENTS_END event. + NRF_SAADC_INT_DONE = SAADC_INTENSET_DONE_Msk, ///< Interrupt on EVENTS_DONE event. + NRF_SAADC_INT_RESULTDONE = SAADC_INTENSET_RESULTDONE_Msk, ///< Interrupt on EVENTS_RESULTDONE event. + NRF_SAADC_INT_CALIBRATEDONE = SAADC_INTENSET_CALIBRATEDONE_Msk, ///< Interrupt on EVENTS_CALIBRATEDONE event. + NRF_SAADC_INT_STOPPED = SAADC_INTENSET_STOPPED_Msk, ///< Interrupt on EVENTS_STOPPED event. + NRF_SAADC_INT_CH0LIMITH = SAADC_INTENSET_CH0LIMITH_Msk, ///< Interrupt on EVENTS_CH[0].LIMITH event. + NRF_SAADC_INT_CH0LIMITL = SAADC_INTENSET_CH0LIMITL_Msk, ///< Interrupt on EVENTS_CH[0].LIMITL event. + NRF_SAADC_INT_CH1LIMITH = SAADC_INTENSET_CH1LIMITH_Msk, ///< Interrupt on EVENTS_CH[1].LIMITH event. + NRF_SAADC_INT_CH1LIMITL = SAADC_INTENSET_CH1LIMITL_Msk, ///< Interrupt on EVENTS_CH[1].LIMITL event. + NRF_SAADC_INT_CH2LIMITH = SAADC_INTENSET_CH2LIMITH_Msk, ///< Interrupt on EVENTS_CH[2].LIMITH event. + NRF_SAADC_INT_CH2LIMITL = SAADC_INTENSET_CH2LIMITL_Msk, ///< Interrupt on EVENTS_CH[2].LIMITL event. + NRF_SAADC_INT_CH3LIMITH = SAADC_INTENSET_CH3LIMITH_Msk, ///< Interrupt on EVENTS_CH[3].LIMITH event. + NRF_SAADC_INT_CH3LIMITL = SAADC_INTENSET_CH3LIMITL_Msk, ///< Interrupt on EVENTS_CH[3].LIMITL event. + NRF_SAADC_INT_CH4LIMITH = SAADC_INTENSET_CH4LIMITH_Msk, ///< Interrupt on EVENTS_CH[4].LIMITH event. + NRF_SAADC_INT_CH4LIMITL = SAADC_INTENSET_CH4LIMITL_Msk, ///< Interrupt on EVENTS_CH[4].LIMITL event. + NRF_SAADC_INT_CH5LIMITH = SAADC_INTENSET_CH5LIMITH_Msk, ///< Interrupt on EVENTS_CH[5].LIMITH event. + NRF_SAADC_INT_CH5LIMITL = SAADC_INTENSET_CH5LIMITL_Msk, ///< Interrupt on EVENTS_CH[5].LIMITL event. + NRF_SAADC_INT_CH6LIMITH = SAADC_INTENSET_CH6LIMITH_Msk, ///< Interrupt on EVENTS_CH[6].LIMITH event. + NRF_SAADC_INT_CH6LIMITL = SAADC_INTENSET_CH6LIMITL_Msk, ///< Interrupt on EVENTS_CH[6].LIMITL event. + NRF_SAADC_INT_CH7LIMITH = SAADC_INTENSET_CH7LIMITH_Msk, ///< Interrupt on EVENTS_CH[7].LIMITH event. + NRF_SAADC_INT_CH7LIMITL = SAADC_INTENSET_CH7LIMITL_Msk, ///< Interrupt on EVENTS_CH[7].LIMITL event. + NRF_SAADC_INT_ALL = 0x7FFFFFFFUL ///< Mask of all interrupts. } nrf_saadc_int_mask_t; @@ -241,6 +289,7 @@ typedef struct nrf_saadc_reference_t reference; nrf_saadc_acqtime_t acq_time; nrf_saadc_mode_t mode; + nrf_saadc_burst_t burst; nrf_saadc_input_t pin_p; nrf_saadc_input_t pin_n; } nrf_saadc_channel_config_t; @@ -291,6 +340,10 @@ __STATIC_INLINE bool nrf_saadc_event_check(nrf_saadc_event_t saadc_event) __STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t saadc_event) { *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event)); + (void)dummy; +#endif } @@ -301,9 +354,9 @@ __STATIC_INLINE void nrf_saadc_event_clear(nrf_saadc_event_t saadc_event) * * @return Address of the specified SAADC event. */ -__STATIC_INLINE volatile uint32_t * nrf_saadc_event_address_get(nrf_saadc_event_t saadc_event) +__STATIC_INLINE uint32_t nrf_saadc_event_address_get(nrf_saadc_event_t saadc_event) { - return (volatile uint32_t *)((uint8_t *)NRF_SAADC + (uint32_t)saadc_event); + return (uint32_t )((uint8_t *)NRF_SAADC + (uint32_t)saadc_event); } @@ -339,13 +392,13 @@ __STATIC_INLINE nrf_saadc_event_t nrf_saadc_event_limit_get(uint8_t channel, nrf { if (limit_type == NRF_SAADC_LIMIT_HIGH) { - return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITH + + return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITH + (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITH - NRF_SAADC_EVENT_CH0_LIMITH) * (uint32_t) channel ); } else { - return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITL + + return (nrf_saadc_event_t)( (uint32_t) NRF_SAADC_EVENT_CH0_LIMITL + (uint32_t) (NRF_SAADC_EVENT_CH1_LIMITL - NRF_SAADC_EVENT_CH0_LIMITL) * (uint32_t) channel ); } @@ -421,7 +474,7 @@ __STATIC_INLINE void nrf_saadc_int_disable(uint32_t saadc_int_mask) /** * @brief Function for generating masks for SAADC channel limit interrupts. - * + * * @param[in] channel SAADC channel number. * @param[in] limit_type Limit type. * @@ -496,10 +549,20 @@ __STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * buffer, uint32_t NRF_SAADC->RESULT.MAXCNT = num; } +/** + * @brief Function for getting the number of buffer words transferred since last START operation. + * + * @returns Number of words transferred. + */ +__STATIC_INLINE uint16_t nrf_saadc_amount_get(void) +{ + return NRF_SAADC->RESULT.AMOUNT; +} + /** * @brief Function for setting the SAADC sample resolution. - * + * * @param[in] resolution Bit resolution. */ __STATIC_INLINE void nrf_saadc_resolution_set(nrf_saadc_resolution_t resolution) @@ -540,4 +603,9 @@ void nrf_saadc_channel_init(uint8_t channel, nrf_saadc_channel_config_t const * *@} **/ + +#ifdef __cplusplus +} +#endif + #endif /* NRF_SAADC_H_ */ diff --git a/components/drivers_nrf/hal/nrf_spi.h b/components/drivers_nrf/hal/nrf_spi.h index 2d3897d..989eb30 100644 --- a/components/drivers_nrf/hal/nrf_spi.h +++ b/components/drivers_nrf/hal/nrf_spi.h @@ -1,19 +1,47 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** * @defgroup nrf_spi_hal SPI HAL * @{ - * @ingroup nrf_spi_master + * @ingroup nrf_spi * * @brief Hardware access layer for accessing the SPI peripheral. */ @@ -27,6 +55,10 @@ #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief This value can be used as a parameter for the @ref nrf_spi_pins_set @@ -94,78 +126,78 @@ typedef enum /** * @brief Function for clearing a specific SPI event. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spi_event Event to clear. */ -__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_reg, nrf_spi_event_t spi_event); /** * @brief Function for checking the state of a specific SPI event. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spi_event Event to check. * * @retval true If the event is set. * @retval false If the event is not set. */ -__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_spi, +__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_reg, nrf_spi_event_t spi_event); /** * @brief Function for getting the address of a specific SPI event register. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spi_event Requested event. * * @return Address of the specified event register. */ -__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_spi, +__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_reg, nrf_spi_event_t spi_event); /** * @brief Function for enabling specified interrupts. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spi_int_mask Interrupts to enable. */ -__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_reg, uint32_t spi_int_mask); /** * @brief Function for disabling specified interrupts. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spi_int_mask Interrupts to disable. */ -__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_reg, uint32_t spi_int_mask); /** * @brief Function for retrieving the state of a given interrupt. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spi_int Interrupt to check. * * @retval true If the interrupt is enabled. * @retval false If the interrupt is not enabled. */ -__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_spi, +__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_reg, nrf_spi_int_mask_t spi_int); /** * @brief Function for enabling the SPI peripheral. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_spi); +__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_reg); /** * @brief Function for disabling the SPI peripheral. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_spi); +__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_reg); /** * @brief Function for configuring SPI pins. @@ -173,12 +205,12 @@ __STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_spi); * If a given signal is not needed, pass the @ref NRF_SPI_PIN_NOT_CONNECTED * value instead of its pin number. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] sck_pin SCK pin number. * @param[in] mosi_pin MOSI pin number. * @param[in] miso_pin MISO pin number. */ -__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_reg, uint32_t sck_pin, uint32_t mosi_pin, uint32_t miso_pin); @@ -186,116 +218,120 @@ __STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_spi, /** * @brief Function for writing data to the SPI transmitter register. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] data TX data to send. */ -__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_spi, uint8_t data); +__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_reg, uint8_t data); /** * @brief Function for reading data from the SPI receiver register. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * * @return RX data received. */ -__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_spi); +__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_reg); /** * @brief Function for setting the SPI master data rate. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] frequency SPI frequency. */ -__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_reg, nrf_spi_frequency_t frequency); /** * @brief Function for setting the SPI configuration. * - * @param[in] p_spi SPI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spi_mode SPI mode. * @param[in] spi_bit_order SPI bit order. */ -__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_reg, nrf_spi_mode_t spi_mode, nrf_spi_bit_order_t spi_bit_order); #ifndef SUPPRESS_INLINE_IMPLEMENTATION -__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_event_clear(NRF_SPI_Type * p_reg, nrf_spi_event_t spi_event) { - *((volatile uint32_t *)((uint8_t *)p_spi + (uint32_t)spi_event)) = 0x0UL; + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event)); + (void)dummy; +#endif } -__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_spi, +__STATIC_INLINE bool nrf_spi_event_check(NRF_SPI_Type * p_reg, nrf_spi_event_t spi_event) { - return (bool)*(volatile uint32_t *)((uint8_t *)p_spi + (uint32_t)spi_event); + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event); } -__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_spi, +__STATIC_INLINE uint32_t * nrf_spi_event_address_get(NRF_SPI_Type * p_reg, nrf_spi_event_t spi_event) { - return (uint32_t *)((uint8_t *)p_spi + (uint32_t)spi_event); + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)spi_event); } -__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_int_enable(NRF_SPI_Type * p_reg, uint32_t spi_int_mask) { - p_spi->INTENSET = spi_int_mask; + p_reg->INTENSET = spi_int_mask; } -__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_int_disable(NRF_SPI_Type * p_reg, uint32_t spi_int_mask) { - p_spi->INTENCLR = spi_int_mask; + p_reg->INTENCLR = spi_int_mask; } -__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_spi, +__STATIC_INLINE bool nrf_spi_int_enable_check(NRF_SPI_Type * p_reg, nrf_spi_int_mask_t spi_int) { - return (bool)(p_spi->INTENSET & spi_int); + return (bool)(p_reg->INTENSET & spi_int); } -__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_spi) +__STATIC_INLINE void nrf_spi_enable(NRF_SPI_Type * p_reg) { - p_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); + p_reg->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); } -__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_spi) +__STATIC_INLINE void nrf_spi_disable(NRF_SPI_Type * p_reg) { - p_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos); + p_reg->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos); } -__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_pins_set(NRF_SPI_Type * p_reg, uint32_t sck_pin, uint32_t mosi_pin, uint32_t miso_pin) { - p_spi->PSELSCK = sck_pin; - p_spi->PSELMOSI = mosi_pin; - p_spi->PSELMISO = miso_pin; + p_reg->PSELSCK = sck_pin; + p_reg->PSELMOSI = mosi_pin; + p_reg->PSELMISO = miso_pin; } -__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_spi, uint8_t data) +__STATIC_INLINE void nrf_spi_txd_set(NRF_SPI_Type * p_reg, uint8_t data) { - p_spi->TXD = data; + p_reg->TXD = data; } -__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_spi) +__STATIC_INLINE uint8_t nrf_spi_rxd_get(NRF_SPI_Type * p_reg) { - return p_spi->RXD; + return p_reg->RXD; } -__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_frequency_set(NRF_SPI_Type * p_reg, nrf_spi_frequency_t frequency) { - p_spi->FREQUENCY = frequency; + p_reg->FREQUENCY = frequency; } -__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_spi, +__STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_reg, nrf_spi_mode_t spi_mode, nrf_spi_bit_order_t spi_bit_order) { @@ -324,11 +360,16 @@ __STATIC_INLINE void nrf_spi_configure(NRF_SPI_Type * p_spi, (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos); break; } - p_spi->CONFIG = config; + p_reg->CONFIG = config; } #endif // SUPPRESS_INLINE_IMPLEMENTATION + +#ifdef __cplusplus +} +#endif + #endif // NRF_SPI_H__ /** @} */ diff --git a/components/drivers_nrf/hal/nrf_spim.h b/components/drivers_nrf/hal/nrf_spim.h index b7aeb91..d65f896 100644 --- a/components/drivers_nrf/hal/nrf_spim.h +++ b/components/drivers_nrf/hal/nrf_spim.h @@ -1,19 +1,47 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** * @defgroup nrf_spim_hal SPIM HAL * @{ - * @ingroup nrf_spi_master + * @ingroup nrf_spi * * @brief Hardware access layer for accessing the SPIM peripheral. */ @@ -27,6 +55,10 @@ #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief This value can be used as a parameter for the @ref nrf_spim_pins_set @@ -57,15 +89,12 @@ typedef enum /*lint -save -e30*/ NRF_SPIM_EVENT_STOPPED = offsetof(NRF_SPIM_Type, EVENTS_STOPPED), ///< SPI transaction has stopped. NRF_SPIM_EVENT_ENDRX = offsetof(NRF_SPIM_Type, EVENTS_ENDRX), ///< End of RXD buffer reached. -#ifdef NRF52 NRF_SPIM_EVENT_END = offsetof(NRF_SPIM_Type, EVENTS_END), ///< End of RXD buffer and TXD buffer reached. -#endif NRF_SPIM_EVENT_ENDTX = offsetof(NRF_SPIM_Type, EVENTS_ENDTX), ///< End of TXD buffer reached. NRF_SPIM_EVENT_STARTED = offsetof(NRF_SPIM_Type, EVENTS_STARTED) ///< Transaction started. /*lint -restore*/ } nrf_spim_event_t; -#ifdef NRF52 /** * @brief SPIM shortcuts. */ @@ -73,7 +102,6 @@ typedef enum { NRF_SPIM_SHORT_END_START_MASK = SPIM_SHORTS_END_START_Msk ///< Shortcut between END event and START task. } nrf_spim_short_mask_t; -#endif /** * @brief SPIM interrupts. @@ -82,9 +110,7 @@ typedef enum { NRF_SPIM_INT_STOPPED_MASK = SPIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. NRF_SPIM_INT_ENDRX_MASK = SPIM_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event. -#ifdef NRF52 NRF_SPIM_INT_END_MASK = SPIM_INTENSET_END_Msk, ///< Interrupt on END event. -#endif NRF_SPIM_INT_ENDTX_MASK = SPIM_INTENSET_ENDTX_Msk, ///< Interrupt on ENDTX event. NRF_SPIM_INT_STARTED_MASK = SPIM_INTENSET_STARTED_Msk ///< Interrupt on STARTED event. } nrf_spim_int_mask_t; @@ -129,116 +155,122 @@ typedef enum /** * @brief Function for activating a specific SPIM task. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spim_task Task to activate. */ -__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_reg, nrf_spim_task_t spim_task); /** * @brief Function for getting the address of a specific SPIM task register. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spim_task Requested task. * * @return Address of the specified task register. */ -__STATIC_INLINE uint32_t * nrf_spim_task_address_get(NRF_SPIM_Type * p_spim, - nrf_spim_task_t spim_task); +__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_reg, + nrf_spim_task_t spim_task); /** * @brief Function for clearing a specific SPIM event. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spim_event Event to clear. */ -__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_reg, nrf_spim_event_t spim_event); /** * @brief Function for checking the state of a specific SPIM event. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spim_event Event to check. * * @retval true If the event is set. * @retval false If the event is not set. */ -__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_spim, +__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_reg, nrf_spim_event_t spim_event); /** * @brief Function for getting the address of a specific SPIM event register. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spim_event Requested event. * * @return Address of the specified event register. */ -__STATIC_INLINE uint32_t * nrf_spim_event_address_get(NRF_SPIM_Type * p_spim, - nrf_spim_event_t spim_event); -#ifdef NRF52 +__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_reg, + nrf_spim_event_t spim_event); /** * @brief Function for enabling specified shortcuts. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spim_shorts_mask Shortcuts to enable. */ -__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg, uint32_t spim_shorts_mask); /** * @brief Function for disabling specified shortcuts. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spim_shorts_mask Shortcuts to disable. */ -__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg, uint32_t spim_shorts_mask); -#endif + +/** + * @brief Function for getting shorts setting. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_reg); + /** * @brief Function for enabling specified interrupts. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spim_int_mask Interrupts to enable. */ -__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_reg, uint32_t spim_int_mask); /** * @brief Function for disabling specified interrupts. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spim_int_mask Interrupts to disable. */ -__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_reg, uint32_t spim_int_mask); /** * @brief Function for retrieving the state of a given interrupt. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spim_int Interrupt to check. * * @retval true If the interrupt is enabled. * @retval false If the interrupt is not enabled. */ -__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_spim, +__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_reg, nrf_spim_int_mask_t spim_int); /** * @brief Function for enabling the SPIM peripheral. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_spim); +__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_reg); /** * @brief Function for disabling the SPIM peripheral. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_spim); +__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_reg); /** * @brief Function for configuring SPIM pins. @@ -246,12 +278,12 @@ __STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_spim); * If a given signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED * value instead of its pin number. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] sck_pin SCK pin number. * @param[in] mosi_pin MOSI pin number. * @param[in] miso_pin MISO pin number. */ -__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_reg, uint32_t sck_pin, uint32_t mosi_pin, uint32_t miso_pin); @@ -259,162 +291,197 @@ __STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_spim, /** * @brief Function for setting the SPI master data rate. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] frequency SPI frequency. */ -__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_reg, nrf_spim_frequency_t frequency); /** * @brief Function for setting the transmit buffer. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] p_buffer Pointer to the buffer with data to send. * @param[in] length Maximum number of data bytes to transmit. */ -__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_reg, uint8_t const * p_buffer, uint8_t length); /** * @brief Function for setting the receive buffer. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] p_buffer Pointer to the buffer for received data. * @param[in] length Maximum number of data bytes to receive. */ -__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_reg, uint8_t * p_buffer, uint8_t length); /** * @brief Function for setting the SPI configuration. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spi_mode SPI mode. * @param[in] spi_bit_order SPI bit order. */ -__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_reg, nrf_spim_mode_t spi_mode, nrf_spim_bit_order_t spi_bit_order); /** * @brief Function for setting the over-read character. * - * @param[in] p_spim SPIM instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] orc Over-read character that is clocked out in case of * an over-read of the TXD buffer. */ -__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_reg, uint8_t orc); +/** + * @brief Function for enabling the TX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg); + +/** + * @brief Function for disabling the TX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg); + +/** + * @brief Function for enabling the RX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg); + +/** + * @brief Function for disabling the RX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg); #ifndef SUPPRESS_INLINE_IMPLEMENTATION -__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_reg, nrf_spim_task_t spim_task) { - *((volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_task)) = 0x1UL; + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_task)) = 0x1UL; } -__STATIC_INLINE uint32_t * nrf_spim_task_address_get(NRF_SPIM_Type * p_spim, - nrf_spim_task_t spim_task) +__STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_reg, + nrf_spim_task_t spim_task) { - return (uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_task); + return (uint32_t)((uint8_t *)p_reg + (uint32_t)spim_task); } -__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_reg, nrf_spim_event_t spim_event) { - *((volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_event)) = 0x0UL; + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event)); + (void)dummy; +#endif } -__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_spim, +__STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_reg, nrf_spim_event_t spim_event) { - return (bool)*(volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_event); + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spim_event); } -__STATIC_INLINE uint32_t * nrf_spim_event_address_get(NRF_SPIM_Type * p_spim, - nrf_spim_event_t spim_event) +__STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_reg, + nrf_spim_event_t spim_event) { - return (uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_event); + return (uint32_t)((uint8_t *)p_reg + (uint32_t)spim_event); } -#ifdef NRF52 -__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_reg, uint32_t spim_shorts_mask) { - p_spim->SHORTS |= spim_shorts_mask; + p_reg->SHORTS |= spim_shorts_mask; } -__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_reg, uint32_t spim_shorts_mask) { - p_spim->SHORTS &= ~(spim_shorts_mask); + p_reg->SHORTS &= ~(spim_shorts_mask); } -#endif -__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_spim, + +__STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_reg) +{ + return p_reg->SHORTS; +} + +__STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_reg, uint32_t spim_int_mask) { - p_spim->INTENSET = spim_int_mask; + p_reg->INTENSET = spim_int_mask; } -__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_reg, uint32_t spim_int_mask) { - p_spim->INTENCLR = spim_int_mask; + p_reg->INTENCLR = spim_int_mask; } -__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_spim, +__STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_reg, nrf_spim_int_mask_t spim_int) { - return (bool)(p_spim->INTENSET & spim_int); + return (bool)(p_reg->INTENSET & spim_int); } -__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_spim) +__STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_reg) { - p_spim->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos); + p_reg->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos); } -__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_spim) +__STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_reg) { - p_spim->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos); + p_reg->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos); } -__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_reg, uint32_t sck_pin, uint32_t mosi_pin, uint32_t miso_pin) { - p_spim->PSEL.SCK = sck_pin; - p_spim->PSEL.MOSI = mosi_pin; - p_spim->PSEL.MISO = miso_pin; + p_reg->PSEL.SCK = sck_pin; + p_reg->PSEL.MOSI = mosi_pin; + p_reg->PSEL.MISO = miso_pin; } -__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_reg, nrf_spim_frequency_t frequency) { - p_spim->FREQUENCY = frequency; + p_reg->FREQUENCY = frequency; } -__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_reg, uint8_t const * p_buffer, uint8_t length) { - p_spim->TXD.PTR = (uint32_t)p_buffer; - p_spim->TXD.MAXCNT = length; + p_reg->TXD.PTR = (uint32_t)p_buffer; + p_reg->TXD.MAXCNT = length; } -__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_reg, uint8_t * p_buffer, uint8_t length) { - p_spim->RXD.PTR = (uint32_t)p_buffer; - p_spim->RXD.MAXCNT = length; + p_reg->RXD.PTR = (uint32_t)p_buffer; + p_reg->RXD.MAXCNT = length; } -__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_reg, nrf_spim_mode_t spi_mode, nrf_spim_bit_order_t spi_bit_order) { @@ -443,17 +510,43 @@ __STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_spim, (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); break; } - p_spim->CONFIG = config; + p_reg->CONFIG = config; } -__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_spim, +__STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_reg, uint8_t orc) { - p_spim->ORC = orc; + p_reg->ORC = orc; +} + + +__STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_reg) +{ + p_reg->TXD.LIST = 1; +} + +__STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_reg) +{ + p_reg->TXD.LIST = 0; +} + +__STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_reg) +{ + p_reg->RXD.LIST = 1; +} + +__STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_reg) +{ + p_reg->RXD.LIST = 0; } #endif // SUPPRESS_INLINE_IMPLEMENTATION + +#ifdef __cplusplus +} +#endif + #endif // NRF_SPIM_H__ /** @} */ diff --git a/components/drivers_nrf/hal/nrf_spis.h b/components/drivers_nrf/hal/nrf_spis.h index 077eb41..801f954 100644 --- a/components/drivers_nrf/hal/nrf_spis.h +++ b/components/drivers_nrf/hal/nrf_spis.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -26,6 +54,11 @@ #include #include "nrf.h" +#include "nrf_peripherals.h" + +#ifdef __cplusplus +extern "C" { +#endif /** @@ -118,134 +151,134 @@ typedef enum /** * @brief Function for activating a specific SPIS task. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spis_task Task to activate. */ -__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_reg, nrf_spis_task_t spis_task); /** * @brief Function for getting the address of a specific SPIS task register. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spis_task Requested task. * * @return Address of the specified task register. */ -__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_spis, +__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_reg, nrf_spis_task_t spis_task); /** * @brief Function for clearing a specific SPIS event. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spis_event Event to clear. */ -__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_reg, nrf_spis_event_t spis_event); /** * @brief Function for checking the state of a specific SPIS event. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spis_event Event to check. * * @retval true If the event is set. * @retval false If the event is not set. */ -__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_spis, +__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_reg, nrf_spis_event_t spis_event); /** * @brief Function for getting the address of a specific SPIS event register. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spis_event Requested event. * * @return Address of the specified event register. */ -__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_spis, +__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_reg, nrf_spis_event_t spis_event); /** * @brief Function for enabling specified shortcuts. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spis_shorts_mask Shortcuts to enable. */ -__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_reg, uint32_t spis_shorts_mask); /** * @brief Function for disabling specified shortcuts. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spis_shorts_mask Shortcuts to disable. */ -__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_reg, uint32_t spis_shorts_mask); /** * @brief Function for enabling specified interrupts. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spis_int_mask Interrupts to enable. */ -__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_reg, uint32_t spis_int_mask); /** * @brief Function for disabling specified interrupts. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spis_int_mask Interrupts to disable. */ -__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_reg, uint32_t spis_int_mask); /** * @brief Function for retrieving the state of a given interrupt. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spis_int Interrupt to check. * * @retval true If the interrupt is enabled. * @retval false If the interrupt is not enabled. */ -__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_spis, +__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_reg, nrf_spis_int_mask_t spis_int); /** * @brief Function for enabling the SPIS peripheral. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_spis); +__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_reg); /** * @brief Function for disabling the SPIS peripheral. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_spis); +__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_reg); /** * @brief Function for retrieving the SPIS semaphore status. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * * @returns Current semaphore status. */ -__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_spis); +__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_reg); /** * @brief Function for retrieving the SPIS status. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * * @returns Current SPIS status. */ -__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_spis); +__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_reg); /** * @brief Function for configuring SPIS pins. @@ -253,13 +286,13 @@ __STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_spi * If a given signal is not needed, pass the @ref NRF_SPIS_PIN_NOT_CONNECTED * value instead of its pin number. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] sck_pin SCK pin number. * @param[in] mosi_pin MOSI pin number. * @param[in] miso_pin MISO pin number. * @param[in] csn_pin CSN pin number. */ -__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_reg, uint32_t sck_pin, uint32_t mosi_pin, uint32_t miso_pin, @@ -268,22 +301,22 @@ __STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_spis, /** * @brief Function for setting the transmit buffer. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] p_buffer Pointer to the buffer that contains the data to send. * @param[in] length Maximum number of data bytes to transmit. */ -__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_reg, uint8_t const * p_buffer, uint8_t length); /** * @brief Function for setting the receive buffer. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] p_buffer Pointer to the buffer for received data. * @param[in] length Maximum number of data bytes to receive. */ -__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_reg, uint8_t * p_buffer, uint8_t length); @@ -291,176 +324,180 @@ __STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_spis, * @brief Function for getting the number of bytes transmitted * in the last granted transaction. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * * @returns Number of bytes transmitted. */ -__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_spis); +__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_reg); /** * @brief Function for getting the number of bytes received * in the last granted transaction. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * * @returns Number of bytes received. */ -__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_spis); +__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_reg); /** * @brief Function for setting the SPI configuration. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] spi_mode SPI mode. * @param[in] spi_bit_order SPI bit order. */ -__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_reg, nrf_spis_mode_t spi_mode, nrf_spis_bit_order_t spi_bit_order); /** * @brief Function for setting the default character. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] def Default character that is clocked out in case of * an overflow of the RXD buffer. */ -__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_reg, uint8_t def); /** * @brief Function for setting the over-read character. * - * @param[in] p_spis SPIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] orc Over-read character that is clocked out in case of * an over-read of the TXD buffer. */ -__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_reg, uint8_t orc); #ifndef SUPPRESS_INLINE_IMPLEMENTATION -__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_task_trigger(NRF_SPIS_Type * p_reg, nrf_spis_task_t spis_task) { - *((volatile uint32_t *)((uint8_t *)p_spis + (uint32_t)spis_task)) = 0x1UL; + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_task)) = 0x1UL; } -__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_spis, +__STATIC_INLINE uint32_t nrf_spis_task_address_get(NRF_SPIS_Type const * p_reg, nrf_spis_task_t spis_task) { - return (uint32_t)p_spis + (uint32_t)spis_task; -} + return (uint32_t)p_reg + (uint32_t)spis_task; +} -__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_event_clear(NRF_SPIS_Type * p_reg, nrf_spis_event_t spis_event) { - *((volatile uint32_t *)((uint8_t *)p_spis + (uint32_t)spis_event)) = 0x0UL; + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_event)); + (void)dummy; +#endif } -__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_spis, +__STATIC_INLINE bool nrf_spis_event_check(NRF_SPIS_Type const * p_reg, nrf_spis_event_t spis_event) { - return (bool)*(volatile uint32_t *)((uint8_t *)p_spis + (uint32_t)spis_event); + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)spis_event); } -__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_spis, +__STATIC_INLINE uint32_t nrf_spis_event_address_get(NRF_SPIS_Type const * p_reg, nrf_spis_event_t spis_event) { - return (uint32_t)p_spis + (uint32_t)spis_event; + return (uint32_t)p_reg + (uint32_t)spis_event; } -__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_shorts_enable(NRF_SPIS_Type * p_reg, uint32_t spis_shorts_mask) { - p_spis->SHORTS |= spis_shorts_mask; + p_reg->SHORTS |= spis_shorts_mask; } -__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_shorts_disable(NRF_SPIS_Type * p_reg, uint32_t spis_shorts_mask) { - p_spis->SHORTS &= ~(spis_shorts_mask); + p_reg->SHORTS &= ~(spis_shorts_mask); } -__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_int_enable(NRF_SPIS_Type * p_reg, uint32_t spis_int_mask) { - p_spis->INTENSET = spis_int_mask; + p_reg->INTENSET = spis_int_mask; } -__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_int_disable(NRF_SPIS_Type * p_reg, uint32_t spis_int_mask) { - p_spis->INTENCLR = spis_int_mask; + p_reg->INTENCLR = spis_int_mask; } -__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_spis, +__STATIC_INLINE bool nrf_spis_int_enable_check(NRF_SPIS_Type const * p_reg, nrf_spis_int_mask_t spis_int) { - return (bool)(p_spis->INTENSET & spis_int); + return (bool)(p_reg->INTENSET & spis_int); } -__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_spis) +__STATIC_INLINE void nrf_spis_enable(NRF_SPIS_Type * p_reg) { - p_spis->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos); + p_reg->ENABLE = (SPIS_ENABLE_ENABLE_Enabled << SPIS_ENABLE_ENABLE_Pos); } -__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_spis) +__STATIC_INLINE void nrf_spis_disable(NRF_SPIS_Type * p_reg) { - p_spis->ENABLE = (SPIS_ENABLE_ENABLE_Disabled << SPIS_ENABLE_ENABLE_Pos); + p_reg->ENABLE = (SPIS_ENABLE_ENABLE_Disabled << SPIS_ENABLE_ENABLE_Pos); } -__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_spis) +__STATIC_INLINE nrf_spis_semstat_t nrf_spis_semaphore_status_get(NRF_SPIS_Type * p_reg) { - return (nrf_spis_semstat_t) ((p_spis->SEMSTAT & SPIS_SEMSTAT_SEMSTAT_Msk) + return (nrf_spis_semstat_t) ((p_reg->SEMSTAT & SPIS_SEMSTAT_SEMSTAT_Msk) >> SPIS_SEMSTAT_SEMSTAT_Pos); } -__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_spis) +__STATIC_INLINE nrf_spis_status_mask_t nrf_spis_status_get(NRF_SPIS_Type * p_reg) { - return (nrf_spis_status_mask_t) p_spis->STATUS; + return (nrf_spis_status_mask_t) p_reg->STATUS; } -__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_pins_set(NRF_SPIS_Type * p_reg, uint32_t sck_pin, uint32_t mosi_pin, uint32_t miso_pin, uint32_t csn_pin) { - p_spis->PSELSCK = sck_pin; - p_spis->PSELMOSI = mosi_pin; - p_spis->PSELMISO = miso_pin; - p_spis->PSELCSN = csn_pin; + p_reg->PSELSCK = sck_pin; + p_reg->PSELMOSI = mosi_pin; + p_reg->PSELMISO = miso_pin; + p_reg->PSELCSN = csn_pin; } -__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_tx_buffer_set(NRF_SPIS_Type * p_reg, uint8_t const * p_buffer, uint8_t length) { - p_spis->TXDPTR = (uint32_t)p_buffer; - p_spis->MAXTX = length; + p_reg->TXDPTR = (uint32_t)p_buffer; + p_reg->MAXTX = length; } -__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_rx_buffer_set(NRF_SPIS_Type * p_reg, uint8_t * p_buffer, uint8_t length) { - p_spis->RXDPTR = (uint32_t)p_buffer; - p_spis->MAXRX = length; + p_reg->RXDPTR = (uint32_t)p_buffer; + p_reg->MAXRX = length; } -__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_spis) +__STATIC_INLINE uint8_t nrf_spis_tx_amount_get(NRF_SPIS_Type const * p_reg) { - return (uint8_t) p_spis->AMOUNTRX; + return (uint8_t) p_reg->AMOUNTTX; } -__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_spis) +__STATIC_INLINE uint8_t nrf_spis_rx_amount_get(NRF_SPIS_Type const * p_reg) { - return (uint8_t) p_spis->AMOUNTTX; + return (uint8_t) p_reg->AMOUNTRX; } -__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_reg, nrf_spis_mode_t spi_mode, nrf_spis_bit_order_t spi_bit_order) { @@ -490,23 +527,28 @@ __STATIC_INLINE void nrf_spis_configure(NRF_SPIS_Type * p_spis, (SPIS_CONFIG_CPHA_Trailing << SPIS_CONFIG_CPHA_Pos); break; } - p_spis->CONFIG = config; + p_reg->CONFIG = config; } -__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_orc_set(NRF_SPIS_Type * p_reg, uint8_t orc) { - p_spis->ORC = orc; + p_reg->ORC = orc; } -__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_spis, +__STATIC_INLINE void nrf_spis_def_set(NRF_SPIS_Type * p_reg, uint8_t def) { - p_spis->DEF = def; + p_reg->DEF = def; } #endif // SUPPRESS_INLINE_IMPLEMENTATION + +#ifdef __cplusplus +} +#endif + #endif // NRF_SPIS_H__ /** @} */ diff --git a/components/drivers_nrf/hal/nrf_systick.h b/components/drivers_nrf/hal/nrf_systick.h new file mode 100644 index 0000000..26fbf37 --- /dev/null +++ b/components/drivers_nrf/hal/nrf_systick.h @@ -0,0 +1,184 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SYSTICK_H__ +#define NRF_SYSTICK_H__ + +#include "nrf.h" +#include +#include +#include + +/** + * @defgroup nrf_systick_hal SYSTICK HAL + * @{ + * @ingroup nrf_systick + * + * @brief Hardware access layer for accessing the SYSTICK peripheral. + * + * SYSTICK is ARM peripheral, not Nordic design. + * It means that it has no Nordic-typical interface with Tasks and Events. + * + * Its usage is limited here to implement simple delays. + * Also keep in mind that this timer would be stopped when CPU is sleeping + * (WFE/WFI instruction is successfully executed). + */ + +/** + * @brief Mask of usable bits in the SysTick value + */ +#define NRF_SYSTICK_VAL_MASK SysTick_VAL_CURRENT_Msk + +/** + * @brief Flags used by SysTick configuration. + * + * @sa nrf_systick_csr_set + * @sa nrf_systick_csr_get + */ +typedef enum { + NRF_SYSTICK_CSR_COUNTFLAG_MASK = SysTick_CTRL_COUNTFLAG_Msk, /**< Status flag: Returns 1 if timer counted to 0 since the last read of this register. */ + + NRF_SYSTICK_CSR_CLKSOURCE_MASK = SysTick_CTRL_CLKSOURCE_Msk, /**< Configuration bit: Select the SysTick clock source. */ + NRF_SYSTICK_CSR_CLKSOURCE_REF = 0U << SysTick_CTRL_CLKSOURCE_Pos, /**< Configuration value: Select reference clock. */ + NRF_SYSTICK_CSR_CLKSOURCE_CPU = 1U << SysTick_CTRL_CLKSOURCE_Pos, /**< Configuration value: Select CPU clock. */ + + NRF_SYSTICK_CSR_TICKINT_MASK = SysTick_CTRL_TICKINT_Msk, /**< Configuration bit: Enables SysTick exception request. */ + NRF_SYSTICK_CSR_TICKINT_ENABLE = 1U << SysTick_CTRL_TICKINT_Pos, /**< Configuration value: Counting down to zero does not assert the SysTick exception request. */ + NRF_SYSTICK_CSR_TICKINT_DISABLE = 0U << SysTick_CTRL_TICKINT_Pos, /**< Configuration value: Counting down to zero to asserts the SysTick exception request. */ + + NRF_SYSTICK_CSR_ENABLE_MASK = SysTick_CTRL_ENABLE_Msk, /**< Configuration bit: Enable the SysTick timer. */ + NRF_SYSTICK_CSR_ENABLE = 1U << SysTick_CTRL_ENABLE_Pos, /**< Configuration value: Counter enabled. */ + NRF_SYSTICK_CSR_DISABLE = 0U << SysTick_CTRL_ENABLE_Pos /**< Configuration value: Counter disabled. */ +} nrf_systick_csr_flags_t; + +/** + * @brief Get Configuration and Status Register + * + * @return Values composed by @ref nrf_systick_csr_flags_t. + * @note The @ref NRF_SYSTICK_CSR_COUNTFLAG_MASK value is cleared when CSR register is read. + */ +__STATIC_INLINE uint32_t nrf_systick_csr_get(void); + +/** + * @brief Set Configuration and Status Register + * + * @param[in] val The value composed from @ref nrf_systick_csr_flags_t. + */ +__STATIC_INLINE void nrf_systick_csr_set(uint32_t val); + +/** + * @brief Get the current reload value. + * + * @return The reload register value. + */ +__STATIC_INLINE uint32_t nrf_systick_load_get(void); + +/** + * @brief Configure the reload value. + * + * @param[in] val The value to set in the reload register. + */ +__STATIC_INLINE void nrf_systick_load_set(uint32_t val); + +/** + * @brief Read the SysTick current value + * + * @return The current SysTick value + * @sa NRF_SYSTICK_VAL_MASK + */ +__STATIC_INLINE uint32_t nrf_systick_val_get(void); + +/** + * @brief Clear the SysTick current value + * + * @note The SysTick does not allow setting current value. + * Any write to VAL register would clear the timer. + */ +__STATIC_INLINE void nrf_systick_val_clear(void); + +/** + * @brief Read the calibration register + * + * @return The calibration register value + */ +__STATIC_INLINE uint32_t nrf_systick_calib_get(void); + + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t nrf_systick_csr_get(void) +{ + return SysTick->CTRL; +} + +__STATIC_INLINE void nrf_systick_csr_set(uint32_t val) +{ + SysTick->CTRL = val; +} + +__STATIC_INLINE uint32_t nrf_systick_load_get(void) +{ + return SysTick->LOAD; +} + +__STATIC_INLINE void nrf_systick_load_set(uint32_t val) +{ + SysTick->LOAD = val; +} + +__STATIC_INLINE uint32_t nrf_systick_val_get(void) +{ + return SysTick->VAL; +} + +__STATIC_INLINE void nrf_systick_val_clear(void) +{ + SysTick->VAL = 0; +} + +__STATIC_INLINE uint32_t nrf_systick_calib_get(void) +{ + return SysTick->CALIB; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +/** @} */ +#endif /* NRF_SYSTICK_H__ */ diff --git a/components/drivers_nrf/hal/nrf_temp.h b/components/drivers_nrf/hal/nrf_temp.h index 8c4cf5a..14b9df0 100644 --- a/components/drivers_nrf/hal/nrf_temp.h +++ b/components/drivers_nrf/hal/nrf_temp.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_TEMP_H__ @@ -15,6 +43,10 @@ #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @defgroup nrf_temperature TEMP (temperature) abstraction * @{ @@ -44,12 +76,17 @@ static __INLINE void nrf_temp_init(void) * The function reads the 10 bit 2's complement value and transforms it to a 32 bit 2's complement value. */ static __INLINE int32_t nrf_temp_read(void) -{ +{ /**@note Workaround for PAN_028 rev2.0A anomaly 28 - TEMP: Negative measured values are not represented correctly */ - return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ? (NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (NRF_TEMP->TEMP); + return ((NRF_TEMP->TEMP & MASK_SIGN) != 0) ? (NRF_TEMP->TEMP | MASK_SIGN_EXTENSION) : (NRF_TEMP->TEMP); } /**@endcond */ /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_nrf/hal/nrf_timer.h b/components/drivers_nrf/hal/nrf_timer.h index 912d647..012976b 100644 --- a/components/drivers_nrf/hal/nrf_timer.h +++ b/components/drivers_nrf/hal/nrf_timer.h @@ -1,22 +1,51 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - - /** + +/** * @defgroup nrf_timer_hal Timer HAL * @{ * @ingroup nrf_timer * * @brief Hardware access layer for accessing the timer peripheral. */ + #ifndef NRF_TIMER_H__ #define NRF_TIMER_H__ @@ -24,380 +53,579 @@ #include #include +#include "nrf_peripherals.h" #include "nrf.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + -#define TIMER_INSTANCE_NUMBER 3 -#define TIMER_CHANNEL_NUMBER 4 +/** + * @brief Macro for validating the correctness of the BIT_WIDTH setting. + */ +#define TIMER_MAX_SIZE(id) CONCAT_3(TIMER, id, _MAX_SIZE) + +#define TIMER_BIT_WIDTH_MAX(id, bit_width) \ + (TIMER_MAX_SIZE(id) == 8 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) : \ + (TIMER_MAX_SIZE(id) == 16 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_16) : \ + (TIMER_MAX_SIZE(id) == 24 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_16) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_24) : \ + (TIMER_MAX_SIZE(id) == 32 ? (bit_width == NRF_TIMER_BIT_WIDTH_8) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_16) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_24) || \ + (bit_width == NRF_TIMER_BIT_WIDTH_32) : \ + false)))) + +#if TIMER_COUNT > 3 +#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \ + ((p_reg == NRF_TIMER0) && (TIMER_BIT_WIDTH_MAX(0, bit_width))) \ + || ((p_reg == NRF_TIMER1) && (TIMER_BIT_WIDTH_MAX(1, bit_width))) \ + || ((p_reg == NRF_TIMER2) && (TIMER_BIT_WIDTH_MAX(2, bit_width))) \ + || ((p_reg == NRF_TIMER3) && (TIMER_BIT_WIDTH_MAX(3, bit_width))) \ + || ((p_reg == NRF_TIMER4) && (TIMER_BIT_WIDTH_MAX(4, bit_width))) ) + +#else +#define NRF_TIMER_IS_BIT_WIDTH_VALID(p_reg, bit_width) ( \ + ((p_reg == NRF_TIMER0) && TIMER_BIT_WIDTH_MAX(0, bit_width)) \ + || ((p_reg == NRF_TIMER1) && TIMER_BIT_WIDTH_MAX(1, bit_width)) \ + || ((p_reg == NRF_TIMER2) && TIMER_BIT_WIDTH_MAX(2, bit_width)) ) + +#endif /** - * @brief Macro for validating correctness of BIT_WIDTH setting. + * @brief Macro for getting the number of capture/compare channels available + * in a given timer instance. */ -#define TIMER_IS_BIT_WIDTH_VALID(instance_id, mode) \ - (((instance_id>0) && (mode>NRF_TIMER_BIT_WIDTH_16)) ? false : true) +#define NRF_TIMER_CC_CHANNEL_COUNT(id) CONCAT_3(TIMER, id, _CC_NUM) -#define TIMER_CC_SHORT(ch) ((TIMER_SHORTS_COMPARE0_STOP_Msk << ch) | \ - (TIMER_SHORTS_COMPARE0_CLEAR_Msk << ch)) /** - * @enum nrf_timer_task_t * @brief Timer tasks. */ typedef enum { /*lint -save -e30 -esym(628,__INTADDR__)*/ - NRF_TIMER_TASK_START = offsetof(NRF_TIMER_Type, TASKS_START), /**< Task for starting the timer. */ - NRF_TIMER_TASK_STOP = offsetof(NRF_TIMER_Type, TASKS_STOP), /**< Task for stoping the timer. */ - NRF_TIMER_TASK_COUNT = offsetof(NRF_TIMER_Type, TASKS_COUNT), /**< Task for incrementing the timer (in counter mode). */ - NRF_TIMER_TASK_CLEAR = offsetof(NRF_TIMER_Type, TASKS_CLEAR), /**< Task for resetting the timer value. */ - NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), /**< Task for powering off the timer. */ - NRF_TIMER_TASK_CAPTURE0 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[0]), /**< Task for capturing the timer value on channel 0. */ - NRF_TIMER_TASK_CAPTURE1 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[1]), /**< Task for capturing the timer value on channel 1. */ - NRF_TIMER_TASK_CAPTURE2 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[2]), /**< Task for capturing the timer value on channel 2. */ - NRF_TIMER_TASK_CAPTURE3 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[3]), /**< Task for capturing the timer value on channel 3. */ + NRF_TIMER_TASK_START = offsetof(NRF_TIMER_Type, TASKS_START), ///< Task for starting the timer. + NRF_TIMER_TASK_STOP = offsetof(NRF_TIMER_Type, TASKS_STOP), ///< Task for stopping the timer. + NRF_TIMER_TASK_COUNT = offsetof(NRF_TIMER_Type, TASKS_COUNT), ///< Task for incrementing the timer (in counter mode). + NRF_TIMER_TASK_CLEAR = offsetof(NRF_TIMER_Type, TASKS_CLEAR), ///< Task for resetting the timer value. + NRF_TIMER_TASK_SHUTDOWN = offsetof(NRF_TIMER_Type, TASKS_SHUTDOWN), ///< Task for powering off the timer. + NRF_TIMER_TASK_CAPTURE0 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[0]), ///< Task for capturing the timer value on channel 0. + NRF_TIMER_TASK_CAPTURE1 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[1]), ///< Task for capturing the timer value on channel 1. + NRF_TIMER_TASK_CAPTURE2 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[2]), ///< Task for capturing the timer value on channel 2. + NRF_TIMER_TASK_CAPTURE3 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[3]), ///< Task for capturing the timer value on channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_TASK_CAPTURE4 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[4]), ///< Task for capturing the timer value on channel 4. + NRF_TIMER_TASK_CAPTURE5 = offsetof(NRF_TIMER_Type, TASKS_CAPTURE[5]), ///< Task for capturing the timer value on channel 5. +#endif /*lint -restore*/ } nrf_timer_task_t; /** - * @enum nrf_timer_event_t * @brief Timer events. */ typedef enum { /*lint -save -e30*/ - NRF_TIMER_EVENT_COMPARE0 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[0]), /**< Event from compare channel 0. */ - NRF_TIMER_EVENT_COMPARE1 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[1]), /**< Event from compare channel 1. */ - NRF_TIMER_EVENT_COMPARE2 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[2]), /**< Event from compare channel 2. */ - NRF_TIMER_EVENT_COMPARE3 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[3]) /**< Event from compare channel 3. */ + NRF_TIMER_EVENT_COMPARE0 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[0]), ///< Event from compare channel 0. + NRF_TIMER_EVENT_COMPARE1 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[1]), ///< Event from compare channel 1. + NRF_TIMER_EVENT_COMPARE2 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[2]), ///< Event from compare channel 2. + NRF_TIMER_EVENT_COMPARE3 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[3]), ///< Event from compare channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_EVENT_COMPARE4 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[4]), ///< Event from compare channel 4. + NRF_TIMER_EVENT_COMPARE5 = offsetof(NRF_TIMER_Type, EVENTS_COMPARE[5]), ///< Event from compare channel 5. +#endif /*lint -restore*/ } nrf_timer_event_t; /** - * @enum nrf_timer_short_mask_t * @brief Types of timer shortcuts. */ typedef enum { - NRF_TIMER_SHORT_COMPARE0_STOP_MASK = TIMER_SHORTS_COMPARE0_STOP_Msk, /**< Shortcut for stopping the timer based on compare 0. */ - NRF_TIMER_SHORT_COMPARE1_STOP_MASK = TIMER_SHORTS_COMPARE1_STOP_Msk, /**< Shortcut for stopping the timer based on compare 1. */ - NRF_TIMER_SHORT_COMPARE2_STOP_MASK = TIMER_SHORTS_COMPARE2_STOP_Msk, /**< Shortcut for stopping the timer based on compare 2. */ - NRF_TIMER_SHORT_COMPARE3_STOP_MASK = TIMER_SHORTS_COMPARE3_STOP_Msk, /**< Shortcut for stopping the timer based on compare 3. */ - NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK = TIMER_SHORTS_COMPARE0_CLEAR_Msk, /**< Shortcut for clearing the timer based on compare 0. */ - NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK = TIMER_SHORTS_COMPARE1_CLEAR_Msk, /**< Shortcut for clearing the timer based on compare 1. */ - NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK = TIMER_SHORTS_COMPARE2_CLEAR_Msk, /**< Shortcut for clearing the timer based on compare 2. */ - NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK = TIMER_SHORTS_COMPARE3_CLEAR_Msk /**< Shortcut for clearing the timer based on compare 3. */ + NRF_TIMER_SHORT_COMPARE0_STOP_MASK = TIMER_SHORTS_COMPARE0_STOP_Msk, ///< Shortcut for stopping the timer based on compare 0. + NRF_TIMER_SHORT_COMPARE1_STOP_MASK = TIMER_SHORTS_COMPARE1_STOP_Msk, ///< Shortcut for stopping the timer based on compare 1. + NRF_TIMER_SHORT_COMPARE2_STOP_MASK = TIMER_SHORTS_COMPARE2_STOP_Msk, ///< Shortcut for stopping the timer based on compare 2. + NRF_TIMER_SHORT_COMPARE3_STOP_MASK = TIMER_SHORTS_COMPARE3_STOP_Msk, ///< Shortcut for stopping the timer based on compare 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_SHORT_COMPARE4_STOP_MASK = TIMER_SHORTS_COMPARE4_STOP_Msk, ///< Shortcut for stopping the timer based on compare 4. + NRF_TIMER_SHORT_COMPARE5_STOP_MASK = TIMER_SHORTS_COMPARE5_STOP_Msk, ///< Shortcut for stopping the timer based on compare 5. +#endif + NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK = TIMER_SHORTS_COMPARE0_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 0. + NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK = TIMER_SHORTS_COMPARE1_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 1. + NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK = TIMER_SHORTS_COMPARE2_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 2. + NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK = TIMER_SHORTS_COMPARE3_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK = TIMER_SHORTS_COMPARE4_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 4. + NRF_TIMER_SHORT_COMPARE5_CLEAR_MASK = TIMER_SHORTS_COMPARE5_CLEAR_Msk, ///< Shortcut for clearing the timer based on compare 5. +#endif } nrf_timer_short_mask_t; /** - * @enum nrf_timer_mode_t * @brief Timer modes. */ typedef enum { - NRF_TIMER_MODE_TIMER = TIMER_MODE_MODE_Timer, /**< Timer mode: timer. */ - NRF_TIMER_MODE_COUNTER = TIMER_MODE_MODE_Counter /**< Timer mode: counter. */ + NRF_TIMER_MODE_TIMER = TIMER_MODE_MODE_Timer, ///< Timer mode: timer. + NRF_TIMER_MODE_COUNTER = TIMER_MODE_MODE_Counter, ///< Timer mode: counter. +#if defined(TIMER_MODE_MODE_LowPowerCounter) || defined(__SDK_DOXYGEN__) + NRF_TIMER_MODE_LOW_POWER_COUNTER = TIMER_MODE_MODE_LowPowerCounter, ///< Timer mode: low-power counter. +#endif } nrf_timer_mode_t; /** - * @enum nrf_timer_bit_width_t * @brief Timer bit width. */ typedef enum { - NRF_TIMER_BIT_WIDTH_8 = TIMER_BITMODE_BITMODE_08Bit, /**< Timer bit width 8 bit. */ - NRF_TIMER_BIT_WIDTH_16 = TIMER_BITMODE_BITMODE_16Bit, /**< Timer bit width 16 bit. */ - NRF_TIMER_BIT_WIDTH_24 = TIMER_BITMODE_BITMODE_24Bit, /**< Timer bit width 24 bit. */ - NRF_TIMER_BIT_WIDTH_32 = TIMER_BITMODE_BITMODE_32Bit /**< Timer bit width 32 bit. */ + NRF_TIMER_BIT_WIDTH_8 = TIMER_BITMODE_BITMODE_08Bit, ///< Timer bit width 8 bit. + NRF_TIMER_BIT_WIDTH_16 = TIMER_BITMODE_BITMODE_16Bit, ///< Timer bit width 16 bit. + NRF_TIMER_BIT_WIDTH_24 = TIMER_BITMODE_BITMODE_24Bit, ///< Timer bit width 24 bit. + NRF_TIMER_BIT_WIDTH_32 = TIMER_BITMODE_BITMODE_32Bit ///< Timer bit width 32 bit. } nrf_timer_bit_width_t; /** - * @enum nrf_timer_frequency_t * @brief Timer prescalers. */ typedef enum { - NRF_TIMER_FREQ_16MHz = 0, /**< Timer frequency 16 MHz. */ - NRF_TIMER_FREQ_8MHz, /**< Timer frequency 8 MHz. */ - NRF_TIMER_FREQ_4MHz, /**< Timer frequency 4 MHz. */ - NRF_TIMER_FREQ_2MHz, /**< Timer frequency 2 MHz. */ - NRF_TIMER_FREQ_1MHz, /**< Timer frequency 1 MHz. */ - NRF_TIMER_FREQ_500kHz, /**< Timer frequency 500 kHz. */ - NRF_TIMER_FREQ_250kHz, /**< Timer frequency 250 kHz. */ - NRF_TIMER_FREQ_125kHz, /**< Timer frequency 125 kHz. */ - NRF_TIMER_FREQ_62500Hz, /**< Timer frequency 62500 Hz. */ - NRF_TIMER_FREQ_31250Hz /**< Timer frequency 31250 Hz. */ + NRF_TIMER_FREQ_16MHz = 0, ///< Timer frequency 16 MHz. + NRF_TIMER_FREQ_8MHz, ///< Timer frequency 8 MHz. + NRF_TIMER_FREQ_4MHz, ///< Timer frequency 4 MHz. + NRF_TIMER_FREQ_2MHz, ///< Timer frequency 2 MHz. + NRF_TIMER_FREQ_1MHz, ///< Timer frequency 1 MHz. + NRF_TIMER_FREQ_500kHz, ///< Timer frequency 500 kHz. + NRF_TIMER_FREQ_250kHz, ///< Timer frequency 250 kHz. + NRF_TIMER_FREQ_125kHz, ///< Timer frequency 125 kHz. + NRF_TIMER_FREQ_62500Hz, ///< Timer frequency 62500 Hz. + NRF_TIMER_FREQ_31250Hz ///< Timer frequency 31250 Hz. } nrf_timer_frequency_t; /** - * @enum nrf_timer_cc_channel_t - * @brief Timer compare/capture channels. + * @brief Timer capture/compare channels. */ typedef enum { - NRF_TIMER_CC_CHANNEL0 = 0, /**< Timer compare/capture channel 0. */ - NRF_TIMER_CC_CHANNEL1, /**< Timer compare/capture channel 1. */ - NRF_TIMER_CC_CHANNEL2, /**< Timer compare/capture channel 2. */ - NRF_TIMER_CC_CHANNEL3 /**< Timer compare/capture channel 3. */ + NRF_TIMER_CC_CHANNEL0 = 0, ///< Timer capture/compare channel 0. + NRF_TIMER_CC_CHANNEL1, ///< Timer capture/compare channel 1. + NRF_TIMER_CC_CHANNEL2, ///< Timer capture/compare channel 2. + NRF_TIMER_CC_CHANNEL3, ///< Timer capture/compare channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_CC_CHANNEL4, ///< Timer capture/compare channel 4. + NRF_TIMER_CC_CHANNEL5, ///< Timer capture/compare channel 5. +#endif } nrf_timer_cc_channel_t; /** - * @enum nrf_timer_int_mask_t * @brief Timer interrupts. */ typedef enum { - NRF_TIMER_INT_COMPARE0_MASK = TIMER_INTENSET_COMPARE0_Msk, /**< Timer interrupt from compare event on channel 0. */ - NRF_TIMER_INT_COMPARE1_MASK = TIMER_INTENSET_COMPARE1_Msk, /**< Timer interrupt from compare event on channel 1. */ - NRF_TIMER_INT_COMPARE2_MASK = TIMER_INTENSET_COMPARE2_Msk, /**< Timer interrupt from compare event on channel 2. */ - NRF_TIMER_INT_COMPARE3_MASK = TIMER_INTENSET_COMPARE3_Msk /**< Timer interrupt from compare event on channel 3. */ + NRF_TIMER_INT_COMPARE0_MASK = TIMER_INTENSET_COMPARE0_Msk, ///< Timer interrupt from compare event on channel 0. + NRF_TIMER_INT_COMPARE1_MASK = TIMER_INTENSET_COMPARE1_Msk, ///< Timer interrupt from compare event on channel 1. + NRF_TIMER_INT_COMPARE2_MASK = TIMER_INTENSET_COMPARE2_Msk, ///< Timer interrupt from compare event on channel 2. + NRF_TIMER_INT_COMPARE3_MASK = TIMER_INTENSET_COMPARE3_Msk, ///< Timer interrupt from compare event on channel 3. +#if (TIMER_COUNT > 3) || defined(__SDK_DOXYGEN__) + NRF_TIMER_INT_COMPARE4_MASK = TIMER_INTENSET_COMPARE4_Msk, ///< Timer interrupt from compare event on channel 4. + NRF_TIMER_INT_COMPARE5_MASK = TIMER_INTENSET_COMPARE5_Msk, ///< Timer interrupt from compare event on channel 5. +#endif } nrf_timer_int_mask_t; + /** * @brief Function for activating a specific timer task. * - * @param NRF_TIMERx Timer instance. - * - * @param timer_task Timer task. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Task to activate. */ -__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * NRF_TIMERx, nrf_timer_task_t timer_task) -{ - *((volatile uint32_t *)((uint8_t *)NRF_TIMERx + (uint32_t)timer_task)) = 0x1UL; -} - +__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task); /** - * @brief Function for returning the address of a specific timer task register. + * @brief Function for getting the address of a specific timer task register. * - * @param NRF_TIMERx Timer instance. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Requested task. * - * @param timer_task Timer task. + * @return Address of the specified task register. */ -__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * NRF_TIMERx, - nrf_timer_task_t timer_task) -{ - return (uint32_t *)((uint8_t *)NRF_TIMERx + (uint32_t)timer_task); -} - +__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task); /** * @brief Function for clearing a specific timer event. * - * @param NRF_TIMERx Timer instance. - * - * @param timer_event Timer event to clear. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. */ -__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * NRF_TIMERx, - nrf_timer_event_t timer_event) -{ - *((volatile uint32_t *)((uint8_t *)NRF_TIMERx + (uint32_t)timer_event)) = 0x0UL; -} - +__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event); /** - * @brief Function for returning the state of a specific event. + * @brief Function for checking the state of a specific timer event. * - * @param NRF_TIMERx Timer instance. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. * - * @param timer_event Timer event to check. + * @retval true If the event is set. + * @retval false If the event is not set. */ -__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * NRF_TIMERx, - nrf_timer_event_t timer_event) -{ - return (bool)*(volatile uint32_t *)((uint8_t *)NRF_TIMERx + (uint32_t)timer_event); -} - +__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event); /** - * @brief Function for returning the address of a specific timer event register. + * @brief Function for getting the address of a specific timer event register. * - * @param NRF_TIMERx Timer instance. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Requested event. * - * @param timer_event Timer event. + * @return Address of the specified event register. */ -__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * NRF_TIMERx, - nrf_timer_event_t timer_event) -{ - return (uint32_t *)((uint8_t *)NRF_TIMERx + (uint32_t)timer_event); -} +__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event); +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask); /** - * @brief Function for seting a shortcut for a specific compare channel. + * @brief Function for disabling specified shortcuts. * - * @param NRF_TIMERx Timer instance. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask); + +/** + * @brief Function for enabling specified interrupts. * - * @param timer_short_mask Type of timer shortcut. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_int_mask Interrupts to enable. */ -__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * NRF_TIMERx, uint32_t timer_short_mask) -{ - NRF_TIMERx->SHORTS |= timer_short_mask; -} +__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask); +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask); /** - * @brief Function for clearing a shortcut for a specific compare channel. + * @brief Function for retrieving the state of a given interrupt. * - * @param NRF_TIMERx Timer instance. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] timer_int Interrupt to check. * - * @param timer_short_mask Type of timer shortcut. + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. */ -__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * NRF_TIMERx, uint32_t timer_short_mask) -{ - NRF_TIMERx->SHORTS &= ~(timer_short_mask); -} - +__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg, + uint32_t timer_int); /** * @brief Function for setting the timer mode. * - * @param NRF_TIMERx Timer instance. - * - * @param timer_mode Timer mode. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] mode Timer mode. */ -__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * NRF_TIMERx, nrf_timer_mode_t timer_mode) -{ - NRF_TIMERx->MODE = (NRF_TIMERx->MODE & ~TIMER_MODE_MODE_Msk) | - ((timer_mode << TIMER_MODE_MODE_Pos) & TIMER_MODE_MODE_Msk); -} - +__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg, + nrf_timer_mode_t mode); /** * @brief Function for retrieving the timer mode. * - * @param NRF_TIMERx Timer instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * + * @return Timer mode. */ -__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * NRF_TIMERx) -{ - return (nrf_timer_mode_t)(NRF_TIMERx->MODE); -} - +__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg); /** * @brief Function for setting the timer bit width. * - * @param NRF_TIMERx Timer instance. - * @param timer_bit_width Timer bit width. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] bit_width Timer bit width. */ -__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * NRF_TIMERx, - nrf_timer_bit_width_t timer_bit_width) -{ - NRF_TIMERx->BITMODE = (NRF_TIMERx->BITMODE & ~TIMER_BITMODE_BITMODE_Msk) | - ((timer_bit_width << - TIMER_BITMODE_BITMODE_Pos) & TIMER_BITMODE_BITMODE_Msk); -} - +__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg, + nrf_timer_bit_width_t bit_width); /** * @brief Function for retrieving the timer bit width. * - * @param NRF_TIMERx Timer instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * + * @return Timer bit width. */ -__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * NRF_TIMERx) -{ - return (nrf_timer_bit_width_t)(NRF_TIMERx->BITMODE); -} - +__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg); /** * @brief Function for setting the timer frequency. * - * @param NRF_TIMERx Timer instance. - * - * @param timer_frequency Timer frequency value. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] frequency Timer frequency. */ -__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * NRF_TIMERx, - nrf_timer_frequency_t timer_frequency) -{ - NRF_TIMERx->PRESCALER = (NRF_TIMERx->PRESCALER & ~TIMER_PRESCALER_PRESCALER_Msk) | - ((timer_frequency << - TIMER_PRESCALER_PRESCALER_Pos) & TIMER_PRESCALER_PRESCALER_Msk); -} - +__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg, + nrf_timer_frequency_t frequency); /** * @brief Function for retrieving the timer frequency. * - * @param NRF_TIMERx Timer instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * + * @return Timer frequency. */ -__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * NRF_TIMERx) -{ - return (nrf_timer_frequency_t)(NRF_TIMERx->PRESCALER); -} +__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg); +/** + * @brief Function for writing the capture/compare register for a specified channel. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] cc_channel Requested capture/compare channel. + * @param[in] cc_value Value to write to the capture/compare register. + */ +__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value); /** - * @brief Function for retrieving the value of a given CC channel. + * @brief Function for retrieving the capture/compare value for a specified channel. * - * @param NRF_TIMERx Timer instance. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] cc_channel Requested capture/compare channel. * - * @param cc_channel CC channel to read. + * @return Value from the requested capture/compare register. */ -__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * NRF_TIMERx, - nrf_timer_cc_channel_t cc_channel) -{ - return (uint32_t)NRF_TIMERx->CC[cc_channel]; -} - +__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel); /** - * @brief Function for writing to a specific CC channel. + * @brief Function for getting a specific timer capture task. * - * @param NRF_TIMERx Timer instance. - * @param cc_channel CC channel to write to. - * @param cc_value Value to write to the CC channel. + * @param[in] channel Capture channel. + * + * @return Capture task. */ -__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * NRF_TIMERx, - nrf_timer_cc_channel_t cc_channel, - uint32_t cc_value) -{ - NRF_TIMERx->CC[cc_channel] = cc_value; -} - +__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel); /** - * @brief Function for enableing a specific interrupt. + * @brief Function for getting a specific timer compare event. * - * @param NRF_TIMERx Timer instance. + * @param[in] channel Compare channel. * - * @param timer_int Interrupt to enable. + * @return Compare event. */ -__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * NRF_TIMERx, uint32_t timer_int) -{ - NRF_TIMERx->INTENSET = timer_int; -} - +__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel); /** - * @brief Function for retrieving the state of a given interrupt. + * @brief Function for getting a specific timer compare interrupt. * - * @param NRF_TIMERx Timer instance. - * @param timer_int Interrupt to check. + * @param[in] channel Compare channel. * - * @retval true If the interrupt is enabled. - * @retval false If the interrupt is not enabled. + * @return Compare interrupt. */ -__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * NRF_TIMERx, uint32_t timer_int) -{ - return (bool)(NRF_TIMERx->INTENSET & timer_int); -} +__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel); +/** + * @brief Function for calculating the number of timer ticks for a given time + * (in microseconds) and timer frequency. + * + * @param[in] time_us Time in microseconds. + * @param[in] frequency Timer frequency. + * + * @return Number of timer ticks. + */ +__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us, + nrf_timer_frequency_t frequency); /** - * @brief Function for disabling a specific interrupt. + * @brief Function for calculating the number of timer ticks for a given time + * (in milliseconds) and timer frequency. * - * @param NRF_TIMERx Timer instance. + * @param[in] time_ms Time in milliseconds. + * @param[in] frequency Timer frequency. * - * @param timer_int Interrupt to disable. + * @return Number of timer ticks. */ -__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * NRF_TIMERx, uint32_t timer_int) +__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms, + nrf_timer_frequency_t frequency); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_timer_task_trigger(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task) { - NRF_TIMERx->INTENCLR = timer_int; + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; } -/** - *@} - **/ +__STATIC_INLINE uint32_t * nrf_timer_task_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_task_t task) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task); +} + +__STATIC_INLINE void nrf_timer_event_clear(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_timer_event_check(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t * nrf_timer_event_address_get(NRF_TIMER_Type * p_reg, + nrf_timer_event_t event) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_timer_shorts_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask) +{ + p_reg->SHORTS |= timer_shorts_mask; +} + +__STATIC_INLINE void nrf_timer_shorts_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_shorts_mask) +{ + p_reg->SHORTS &= ~(timer_shorts_mask); +} + +__STATIC_INLINE void nrf_timer_int_enable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask) +{ + p_reg->INTENSET = timer_int_mask; +} + +__STATIC_INLINE void nrf_timer_int_disable(NRF_TIMER_Type * p_reg, + uint32_t timer_int_mask) +{ + p_reg->INTENCLR = timer_int_mask; +} + +__STATIC_INLINE bool nrf_timer_int_enable_check(NRF_TIMER_Type * p_reg, + uint32_t timer_int) +{ + return (bool)(p_reg->INTENSET & timer_int); +} + +__STATIC_INLINE void nrf_timer_mode_set(NRF_TIMER_Type * p_reg, + nrf_timer_mode_t mode) +{ + p_reg->MODE = (p_reg->MODE & ~TIMER_MODE_MODE_Msk) | + ((mode << TIMER_MODE_MODE_Pos) & TIMER_MODE_MODE_Msk); +} + +__STATIC_INLINE nrf_timer_mode_t nrf_timer_mode_get(NRF_TIMER_Type * p_reg) +{ + return (nrf_timer_mode_t)(p_reg->MODE); +} + +__STATIC_INLINE void nrf_timer_bit_width_set(NRF_TIMER_Type * p_reg, + nrf_timer_bit_width_t bit_width) +{ + p_reg->BITMODE = (p_reg->BITMODE & ~TIMER_BITMODE_BITMODE_Msk) | + ((bit_width << TIMER_BITMODE_BITMODE_Pos) & + TIMER_BITMODE_BITMODE_Msk); +} + +__STATIC_INLINE nrf_timer_bit_width_t nrf_timer_bit_width_get(NRF_TIMER_Type * p_reg) +{ + return (nrf_timer_bit_width_t)(p_reg->BITMODE); +} + +__STATIC_INLINE void nrf_timer_frequency_set(NRF_TIMER_Type * p_reg, + nrf_timer_frequency_t frequency) +{ + p_reg->PRESCALER = (p_reg->PRESCALER & ~TIMER_PRESCALER_PRESCALER_Msk) | + ((frequency << TIMER_PRESCALER_PRESCALER_Pos) & + TIMER_PRESCALER_PRESCALER_Msk); +} + +__STATIC_INLINE nrf_timer_frequency_t nrf_timer_frequency_get(NRF_TIMER_Type * p_reg) +{ + return (nrf_timer_frequency_t)(p_reg->PRESCALER); +} + +__STATIC_INLINE void nrf_timer_cc_write(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value) +{ + p_reg->CC[cc_channel] = cc_value; +} + +__STATIC_INLINE uint32_t nrf_timer_cc_read(NRF_TIMER_Type * p_reg, + nrf_timer_cc_channel_t cc_channel) +{ + return (uint32_t)p_reg->CC[cc_channel]; +} + +__STATIC_INLINE nrf_timer_task_t nrf_timer_capture_task_get(uint32_t channel) +{ + return (nrf_timer_task_t) + ((uint32_t)NRF_TIMER_TASK_CAPTURE0 + (channel * sizeof(uint32_t))); +} + +__STATIC_INLINE nrf_timer_event_t nrf_timer_compare_event_get(uint32_t channel) +{ + return (nrf_timer_event_t) + ((uint32_t)NRF_TIMER_EVENT_COMPARE0 + (channel * sizeof(uint32_t))); +} + +__STATIC_INLINE nrf_timer_int_mask_t nrf_timer_compare_int_get(uint32_t channel) +{ + return (nrf_timer_int_mask_t) + ((uint32_t)NRF_TIMER_INT_COMPARE0_MASK << channel); +} + +__STATIC_INLINE uint32_t nrf_timer_us_to_ticks(uint32_t time_us, + nrf_timer_frequency_t frequency) +{ + // The "frequency" parameter here is actually the prescaler value, and the + // timer runs at the following frequency: f = 16 MHz / 2^prescaler. + uint32_t prescaler = (uint32_t)frequency; + ASSERT(time_us <= (UINT32_MAX / 16UL)); + return ((time_us * 16UL) >> prescaler); +} + +__STATIC_INLINE uint32_t nrf_timer_ms_to_ticks(uint32_t time_ms, + nrf_timer_frequency_t frequency) +{ + // The "frequency" parameter here is actually the prescaler value, and the + // timer runs at the following frequency: f = 16000 kHz / 2^prescaler. + uint32_t prescaler = (uint32_t)frequency; + ASSERT(time_ms <= (UINT32_MAX / 16000UL)); + return ((time_ms * 16000UL) >> prescaler); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_TIMER_H__ -#endif /* NRF_TIMER_H__ */ +/** @} */ diff --git a/components/drivers_nrf/hal/nrf_twi.h b/components/drivers_nrf/hal/nrf_twi.h index 2caebee..7818ba2 100644 --- a/components/drivers_nrf/hal/nrf_twi.h +++ b/components/drivers_nrf/hal/nrf_twi.h @@ -1,384 +1,453 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_TWI_H__ +#define NRF_TWI_H__ + +/** * @defgroup nrf_twi_hal TWI HAL * @{ - * @ingroup nrf_twi_master + * @ingroup nrf_twi * - * @brief Hardware access layer for the two-wire interface (TWI) peripheral. + * @brief Hardware access layer for managing the TWI peripheral. */ -#ifndef NRF_TWI_H__ -#define NRF_TWI_H__ -#include "nrf.h" #include #include #include + +#include "nrf_peripherals.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + /** - * @enum nrf_twi_tasks_t * @brief TWI tasks. */ typedef enum { - /*lint -save -e30 -esym(628,__INTADDR__)*/ - NRF_TWI_TASKS_STARTRX = offsetof(NRF_TWI_Type, TASKS_STARTRX), /**< Start receive sequence. */ - NRF_TWI_TASKS_STARTTX = offsetof(NRF_TWI_Type, TASKS_STARTTX), /**< Start transmit sequence. */ - NRF_TWI_TASKS_STOP = offsetof(NRF_TWI_Type, TASKS_STOP), /**< Stop transaction. */ - NRF_TWI_TASKS_SUSPEND = offsetof(NRF_TWI_Type, TASKS_SUSPEND), /**< Suspend transaction. */ - NRF_TWI_TASKS_RESUME = offsetof(NRF_TWI_Type, TASKS_RESUME) /**< Resume transaction. */ + /*lint -save -e30*/ + NRF_TWI_TASK_STARTRX = offsetof(NRF_TWI_Type, TASKS_STARTRX), ///< Start TWI receive sequence. + NRF_TWI_TASK_STARTTX = offsetof(NRF_TWI_Type, TASKS_STARTTX), ///< Start TWI transmit sequence. + NRF_TWI_TASK_STOP = offsetof(NRF_TWI_Type, TASKS_STOP), ///< Stop TWI transaction. + NRF_TWI_TASK_SUSPEND = offsetof(NRF_TWI_Type, TASKS_SUSPEND), ///< Suspend TWI transaction. + NRF_TWI_TASK_RESUME = offsetof(NRF_TWI_Type, TASKS_RESUME) ///< Resume TWI transaction. /*lint -restore*/ -} nrf_twi_tasks_t; +} nrf_twi_task_t; /** - * @enum nrf_twi_events_t * @brief TWI events. */ typedef enum { /*lint -save -e30*/ - NRF_TWI_EVENTS_STOPPED = offsetof(NRF_TWI_Type, EVENTS_STOPPED), /**< Stopped. */ - NRF_TWI_EVENTS_RXDREADY = offsetof(NRF_TWI_Type, EVENTS_RXDREADY), /**< RXD byte received. */ - NRF_TWI_EVENTS_TXDSENT = offsetof(NRF_TWI_Type, EVENTS_TXDSENT), /**< TXD byte sent. */ - NRF_TWI_EVENTS_ERROR = offsetof(NRF_TWI_Type, EVENTS_ERROR), /**< Error. */ - NRF_TWI_EVENTS_BB = offsetof(NRF_TWI_Type, EVENTS_BB), /**< Byte boundary, generated before each byte that is sent or received. */ - NRF_TWI_EVENTS_SUSPENDED = offsetof(NRF_TWI_Type, EVENTS_SUSPENDED) /**< Entered the suspended state. */ + NRF_TWI_EVENT_STOPPED = offsetof(NRF_TWI_Type, EVENTS_STOPPED), ///< TWI stopped. + NRF_TWI_EVENT_RXDREADY = offsetof(NRF_TWI_Type, EVENTS_RXDREADY), ///< TWI RXD byte received. + NRF_TWI_EVENT_TXDSENT = offsetof(NRF_TWI_Type, EVENTS_TXDSENT), ///< TWI TXD byte sent. + NRF_TWI_EVENT_ERROR = offsetof(NRF_TWI_Type, EVENTS_ERROR), ///< TWI error. + NRF_TWI_EVENT_BB = offsetof(NRF_TWI_Type, EVENTS_BB), ///< TWI byte boundary, generated before each byte that is sent or received. + NRF_TWI_EVENT_SUSPENDED = offsetof(NRF_TWI_Type, EVENTS_SUSPENDED) ///< TWI entered the suspended state. /*lint -restore*/ -} nrf_twi_events_t; +} nrf_twi_event_t; /** - * @enum nrf_twi_int_mask_t - * @brief TWI interrupts. + * @brief TWI shortcuts. */ typedef enum { - NRF_TWI_INT_SUSPENDED_MASK = TWI_INTENSET_SUSPENDED_Msk, /**< TWI interrupt on suspend event. */ - NRF_TWI_INT_BB_MASK = TWI_INTENSET_BB_Msk, /**< TWI interrupt on byte boundary event. */ - NRF_TWI_INT_ERROR_MASK = TWI_INTENSET_ERROR_Msk, /**< TWI interrupt on error event. */ - NRF_TWI_INT_TXDSENT_MASK = TWI_INTENSET_TXDSENT_Msk, /**< TWI interrupt on txdsent event. */ - NRF_TWI_INT_RXDREADY_MASK = TWI_INTENSET_RXDREADY_Msk, /**< TWI interrupt on rxdready event. */ - NRF_TWI_INT_STOPPED_MASK = TWI_INTENSET_STOPPED_Msk, /**< TWI interrupt on stopped event. */ -} nrf_twi_int_mask_t; + NRF_TWI_SHORT_BB_SUSPEND_MASK = TWI_SHORTS_BB_SUSPEND_Msk, ///< Shortcut between BB event and SUSPEND task. + NRF_TWI_SHORT_BB_STOP_MASK = TWI_SHORTS_BB_STOP_Msk, ///< Shortcut between BB event and STOP task. +} nrf_twi_short_mask_t; /** - * @enum nrf_twi_shorts_mask_t - * @brief Types of TWI shortcuts. + * @brief TWI interrupts. */ typedef enum { - NRF_TWI_SHORTS_BB_SUSPEND_MASK = TWI_SHORTS_BB_SUSPEND_Msk, /**< Shortcut between bb event and suspend task. */ - NRF_TWI_SHORTS_BB_STOP_MASK = TWI_SHORTS_BB_STOP_Msk, /**< Shortcut between bb event and stop task. */ -} nrf_twi_shorts_mask_t; + NRF_TWI_INT_STOPPED_MASK = TWI_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_TWI_INT_RXDREADY_MASK = TWI_INTENSET_RXDREADY_Msk, ///< Interrupt on RXDREADY event. + NRF_TWI_INT_TXDSENT_MASK = TWI_INTENSET_TXDSENT_Msk, ///< Interrupt on TXDSENT event. + NRF_TWI_INT_ERROR_MASK = TWI_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event. + NRF_TWI_INT_BB_MASK = TWI_INTENSET_BB_Msk, ///< Interrupt on BB event. + NRF_TWI_INT_SUSPENDED_MASK = TWI_INTENSET_SUSPENDED_Msk ///< Interrupt on SUSPENDED event. +} nrf_twi_int_mask_t; /** - * @enum nrf_twi_frequency_t - * @brief TWI master clock frequency. + * @brief TWI error source. */ typedef enum { - NRF_TWI_FREQ_100K = TWI_FREQUENCY_FREQUENCY_K100, /**< 100 kbps. */ - NRF_TWI_FREQ_250K = TWI_FREQUENCY_FREQUENCY_K250, /**< 250 kbps. */ - NRF_TWI_FREQ_400K = TWI_FREQUENCY_FREQUENCY_K400 /**< 400 kbps. */ -} nrf_twi_frequency_t; + NRF_TWI_ERROR_ADDRESS_NACK = TWI_ERRORSRC_ANACK_Msk, ///< NACK received after sending the address. + NRF_TWI_ERROR_DATA_NACK = TWI_ERRORSRC_DNACK_Msk, ///< NACK received after sending a data byte. + NRF_TWI_ERROR_OVERRUN = TWI_ERRORSRC_OVERRUN_Msk ///< Overrun error. + /**< A new byte was received before the previous byte was read + * from the RXD register (previous data is lost). */ +} nrf_twi_error_t; /** - * @enum nrf_twi_error_t - * @brief TWI error source. + * @brief TWI master clock frequency. */ typedef enum { - NRF_TWI_ERROR_ADDRESS_NACK = TWI_ERRORSRC_ANACK_Msk, /**< NACK received after sending the address. */ - NRF_TWI_ERROR_OVERRUN_NACK = TWI_ERRORSRC_OVERRUN_Msk, /**< Byte received in RXD register before read of the last received byte (data loss). */ - NRF_TWI_ERROR_DATA_NACK = TWI_ERRORSRC_DNACK_Msk, /**< NACK received after sending a data byte. */ -} nrf_twi_error_t; + NRF_TWI_FREQ_100K = TWI_FREQUENCY_FREQUENCY_K100, ///< 100 kbps. + NRF_TWI_FREQ_250K = TWI_FREQUENCY_FREQUENCY_K250, ///< 250 kbps. + NRF_TWI_FREQ_400K = TWI_FREQUENCY_FREQUENCY_K400 ///< 400 kbps. +} nrf_twi_frequency_t; + /** * @brief Function for activating a specific TWI task. * - * @param[in] p_twi TWI instance. - * @param[in] task Task. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Task to activate. */ -__STATIC_INLINE void nrf_twi_task_set(NRF_TWI_Type * p_twi, nrf_twi_tasks_t task); +__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_reg, + nrf_twi_task_t task); /** - * @brief Function for returning the address of a specific TWI task register. + * @brief Function for getting the address of a specific TWI task register. * - * @param[in] p_twi TWI instance. - * @param[in] task Task. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Requested task. * - * @return Task address. + * @return Address of the specified task register. */ -__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_twi, - nrf_twi_tasks_t task); +__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_reg, + nrf_twi_task_t task); /** - * @brief Function for clearing a specific event. + * @brief Function for clearing a specific TWI event. * - * @param[in] p_twi TWI instance. - * @param[in] event Event. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. */ -__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_twi, - nrf_twi_events_t event); +__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_reg, + nrf_twi_event_t event); + /** - * @brief Function for returning the state of a specific event. + * @brief Function for checking the state of a specific event. * - * @param[in] p_twi TWI instance. - * @param[in] event Event. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. * * @retval true If the event is set. * @retval false If the event is not set. */ -__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_twi, - nrf_twi_events_t event); +__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_reg, + nrf_twi_event_t event); /** - * @brief Function for returning the address of a specific TWI event register. + * @brief Function for getting the address of a specific TWI event register. * - * @param[in] p_twi TWI instance. - * @param[in] event Event. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Requested event. * - * @return Address. + * @return Address of the specified event register. */ -__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_twi, - nrf_twi_events_t event); +__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_reg, + nrf_twi_event_t event); /** - * @brief Function for setting a shortcut. + * @brief Function for enabling specified shortcuts. * - * @param[in] p_twi TWI instance. - * @param[in] short_mask Shortcuts mask. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] shorts_mask Shortcuts to enable. */ -__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_twi, uint32_t short_mask); +__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_reg, + uint32_t shorts_mask); /** - * @brief Function for clearing shortcuts. + * @brief Function for disabling specified shortcuts. * - * @param[in] p_twi TWI instance. - * @param[in] short_mask Shortcuts mask. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] shorts_mask Shortcuts to disable. */ -__STATIC_INLINE void nrf_twi_shorts_clear(NRF_TWI_Type * p_twi, uint32_t short_mask); +__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_reg, + uint32_t shorts_mask); /** - * @brief Function for enabling a specific interrupt. + * @brief Function for enabling specified interrupts. * - * @param[in] p_twi TWI instance. - * @param[in] int_mask Interrupts mask. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupts to enable. */ -__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_twi, uint32_t int_mask); +__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_reg, + uint32_t int_mask); /** - * @brief Function for retrieving the state of a given interrupt. + * @brief Function for disabling specified interrupts. * - * @param[in] p_twi TWI instance. - * @param[in] int_mask Interrupts mask. - * - * @retval true If the interrupts are enabled. - * @retval false If the interrupts are not enabled. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupts to disable. */ -__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_twi, uint32_t int_mask); +__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_reg, + uint32_t int_mask); /** - * @brief Function for disabling a specific interrupt. + * @brief Function for retrieving the state of a given interrupt. * - * @param[in] p_twi TWI instance. - * @param[in] int_mask Interrupts mask. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. */ -__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_twi, uint32_t int_mask); +__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_reg, + nrf_twi_int_mask_t int_mask); /** - * @brief Function for setting the TWI master clock frequency. + * @brief Function for enabling the TWI peripheral. * - * @param[in] p_twi TWI instance. - * @param[in] frequency TWI frequency value. + * @param[in] p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_twi, - nrf_twi_frequency_t frequency); +__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_reg); /** - * @brief Function for retrieving the TWI frequency. - * - * @param[in] p_twi TWI instance. + * @brief Function for disabling the TWI peripheral. * - * @return Frequency. + * @param[in] p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE nrf_twi_frequency_t nrf_twi_frequency_get(NRF_TWI_Type * p_twi); +__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_reg); /** - * @brief Function for retrieving the TWI error source. - * @details Error sources are cleared after read. + * @brief Function for configuring TWI pins. * - * @param[in] p_twi TWI instance. * - * @return Error source mask. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] scl_pin SCL pin number. + * @param[in] sda_pin SDA pin number. */ -__STATIC_INLINE uint32_t nrf_twi_error_source_get(NRF_TWI_Type * p_twi); +__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_reg, + uint32_t scl_pin, + uint32_t sda_pin); /** - * @brief Function for enabling TWI. + * @brief Function for setting the TWI master clock frequency. * - * @param[in] p_twi TWI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] frequency TWI frequency. */ -__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_twi); +__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_reg, + nrf_twi_frequency_t frequency); /** - * @brief Function for disabling TWI. + * @brief Function for checking the TWI error source. + * + * The error flags are cleared after reading. * - * @param[in] p_twi TWI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Mask with error source flags. */ -__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_twi); +__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg); /** - * @brief Function for configuring TWI pins. + * @brief Function for setting the address to be used in TWI transfers. * - * @param[in] p_twi TWI instance. - * @param[in] scl SCL pin number. - * @param[in] sda SDA pin number. + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] address Address to be used in transfers. */ -__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_twi, uint32_t scl, uint32_t sda); +__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_reg, uint8_t address); /** - * @brief Function for reading RX data from TWI. + * @brief Function for reading data received by TWI. * - * @param[in] p_twi TWI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * - * @return RX data. + * @return Received data. */ -__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_twi); +__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_reg); + /** - * @brief Function for writing data to TWI. + * @brief Function for writing data to be transmitted by TWI. * - * @param[in] p_twi TWI instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] data Data to be transmitted. */ -__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_twi, uint8_t data); +__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_reg, uint8_t data); -/** - * @brief Function for setting the slave address. - * - * @param[in] p_twi TWI instance. - * @param[in] addr Address of next transaction. - */ -__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_twi, uint8_t addr); +__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_reg, + uint32_t shorts_mask); /** - *@} - **/ + * @} + */ #ifndef SUPPRESS_INLINE_IMPLEMENTATION -__STATIC_INLINE void nrf_twi_task_set(NRF_TWI_Type * p_twi, nrf_twi_tasks_t task) +__STATIC_INLINE void nrf_twi_task_trigger(NRF_TWI_Type * p_reg, + nrf_twi_task_t task) { - *((volatile uint32_t *)((uint8_t *)p_twi + (uint32_t)task)) = 0x1UL; + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; } -__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_twi, - nrf_twi_tasks_t task) +__STATIC_INLINE uint32_t * nrf_twi_task_address_get(NRF_TWI_Type * p_reg, + nrf_twi_task_t task) { - return (uint32_t *)((uint8_t *)p_twi + (uint32_t)task); + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task); } -__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_twi, - nrf_twi_events_t event) +__STATIC_INLINE void nrf_twi_event_clear(NRF_TWI_Type * p_reg, + nrf_twi_event_t event) { - *((volatile uint32_t *)((uint8_t *)p_twi + (uint32_t)event)) = 0x0UL; + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif } -__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_twi, - nrf_twi_events_t event) +__STATIC_INLINE bool nrf_twi_event_check(NRF_TWI_Type * p_reg, + nrf_twi_event_t event) { - return (bool)*(volatile uint32_t *)((uint8_t *)p_twi + (uint32_t)event); + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); } -__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_twi, - nrf_twi_events_t event) +__STATIC_INLINE uint32_t * nrf_twi_event_address_get(NRF_TWI_Type * p_reg, + nrf_twi_event_t event) { - return (uint32_t *)((uint8_t *)p_twi + (uint32_t)event); + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event); } -__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_twi, uint32_t short_mask) +__STATIC_INLINE void nrf_twi_shorts_enable(NRF_TWI_Type * p_reg, + uint32_t shorts_mask) { - p_twi->SHORTS |= short_mask; + p_reg->SHORTS |= shorts_mask; } -__STATIC_INLINE void nrf_twi_shorts_clear(NRF_TWI_Type * p_twi, uint32_t short_mask) +__STATIC_INLINE void nrf_twi_shorts_disable(NRF_TWI_Type * p_reg, + uint32_t shorts_mask) { - p_twi->SHORTS &= ~(short_mask); + p_reg->SHORTS &= ~(shorts_mask); } -__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_twi, uint32_t int_mask) +__STATIC_INLINE void nrf_twi_int_enable(NRF_TWI_Type * p_reg, + uint32_t int_mask) { - p_twi->INTENSET = int_mask; + p_reg->INTENSET = int_mask; } -__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_twi, uint32_t int_mask) +__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_reg, + uint32_t int_mask) { - return (bool)(p_twi->INTENSET & int_mask); + p_reg->INTENCLR = int_mask; } -__STATIC_INLINE void nrf_twi_int_disable(NRF_TWI_Type * p_twi, uint32_t int_mask) +__STATIC_INLINE bool nrf_twi_int_enable_check(NRF_TWI_Type * p_reg, + nrf_twi_int_mask_t int_mask) { - p_twi->INTENCLR = int_mask; + return (bool)(p_reg->INTENSET & int_mask); } -__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_twi, - nrf_twi_frequency_t frequency) +__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_reg) { - p_twi->FREQUENCY = frequency; + p_reg->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos); } -__STATIC_INLINE nrf_twi_frequency_t nrf_twi_frequency_get(NRF_TWI_Type * p_twi) +__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_reg) { - return (nrf_twi_frequency_t)(p_twi->FREQUENCY); + p_reg->ENABLE = (TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos); } -__STATIC_INLINE uint32_t nrf_twi_error_source_get(NRF_TWI_Type * p_twi) +__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_reg, + uint32_t scl_pin, + uint32_t sda_pin) { - uint32_t error_source = p_twi->ERRORSRC; - - p_twi->ERRORSRC = error_source; - return error_source; +#if defined(TWI_PSEL_SCL_CONNECT_Pos) + p_reg->PSEL.SCL = scl_pin; +#else + p_reg->PSELSCL = scl_pin; +#endif + +#if defined(TWI_PSEL_SDA_CONNECT_Pos) + p_reg->PSEL.SDA = sda_pin; +#else + p_reg->PSELSDA = sda_pin; +#endif } -__STATIC_INLINE void nrf_twi_enable(NRF_TWI_Type * p_twi) +__STATIC_INLINE void nrf_twi_frequency_set(NRF_TWI_Type * p_reg, + nrf_twi_frequency_t frequency) { - p_twi->ENABLE = (TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos); + p_reg->FREQUENCY = frequency; } -__STATIC_INLINE void nrf_twi_disable(NRF_TWI_Type * p_twi) +__STATIC_INLINE uint32_t nrf_twi_errorsrc_get_and_clear(NRF_TWI_Type * p_reg) { - p_twi->ENABLE = (TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos); + uint32_t error_source = p_reg->ERRORSRC; + + // [error flags are cleared by writing '1' on their position] + p_reg->ERRORSRC = error_source; + + return error_source; } -__STATIC_INLINE void nrf_twi_pins_set(NRF_TWI_Type * p_twi, uint32_t scl, uint32_t sda) +__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_reg, uint8_t address) { - p_twi->PSELSCL = scl; - p_twi->PSELSDA = sda; + p_reg->ADDRESS = address; } -__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_twi) +__STATIC_INLINE uint8_t nrf_twi_rxd_get(NRF_TWI_Type * p_reg) { - return (uint8_t)p_twi->RXD; + return (uint8_t)p_reg->RXD; } -__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_twi, uint8_t data) +__STATIC_INLINE void nrf_twi_txd_set(NRF_TWI_Type * p_reg, uint8_t data) { - p_twi->TXD = data; + p_reg->TXD = data; } -__STATIC_INLINE void nrf_twi_address_set(NRF_TWI_Type * p_twi, uint8_t addr) +__STATIC_INLINE void nrf_twi_shorts_set(NRF_TWI_Type * p_reg, + uint32_t shorts_mask) { - p_twi->ADDRESS = addr; + p_reg->SHORTS = shorts_mask; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus } -#endif //SUPPRESS_INLINE_IMPLEMENTATION +#endif -#endif //NRF_TWI_H__ +#endif // NRF_TWI_H__ diff --git a/components/drivers_nrf/hal/nrf_twim.h b/components/drivers_nrf/hal/nrf_twim.h new file mode 100644 index 0000000..bbc3a36 --- /dev/null +++ b/components/drivers_nrf/hal/nrf_twim.h @@ -0,0 +1,519 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_TWIM_H__ +#define NRF_TWIM_H__ + +/** + * @defgroup nrf_twim_hal TWIM HAL + * @{ + * @ingroup nrf_twi + * + * @brief Hardware access layer for managing the TWIM peripheral. + */ + +#include +#include +#include + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief TWIM tasks. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWIM_TASK_STARTRX = offsetof(NRF_TWIM_Type, TASKS_STARTRX), ///< Start TWI receive sequence. + NRF_TWIM_TASK_STARTTX = offsetof(NRF_TWIM_Type, TASKS_STARTTX), ///< Start TWI transmit sequence. + NRF_TWIM_TASK_STOP = offsetof(NRF_TWIM_Type, TASKS_STOP), ///< Stop TWI transaction. + NRF_TWIM_TASK_SUSPEND = offsetof(NRF_TWIM_Type, TASKS_SUSPEND), ///< Suspend TWI transaction. + NRF_TWIM_TASK_RESUME = offsetof(NRF_TWIM_Type, TASKS_RESUME) ///< Resume TWI transaction. + /*lint -restore*/ +} nrf_twim_task_t; + +/** + * @brief TWIM events. + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_TWIM_EVENT_STOPPED = offsetof(NRF_TWIM_Type, EVENTS_STOPPED), ///< TWI stopped. + NRF_TWIM_EVENT_ERROR = offsetof(NRF_TWIM_Type, EVENTS_ERROR), ///< TWI error. + NRF_TWIM_EVENT_SUSPENDED = 0x148, ///< TWI suspended. + NRF_TWIM_EVENT_RXSTARTED = offsetof(NRF_TWIM_Type, EVENTS_RXSTARTED), ///< Receive sequence started. + NRF_TWIM_EVENT_TXSTARTED = offsetof(NRF_TWIM_Type, EVENTS_TXSTARTED), ///< Transmit sequence started. + NRF_TWIM_EVENT_LASTRX = offsetof(NRF_TWIM_Type, EVENTS_LASTRX), ///< Byte boundary, starting to receive the last byte. + NRF_TWIM_EVENT_LASTTX = offsetof(NRF_TWIM_Type, EVENTS_LASTTX) ///< Byte boundary, starting to transmit the last byte. + /*lint -restore*/ +} nrf_twim_event_t; + +/** + * @brief TWIM shortcuts. + */ +typedef enum +{ + NRF_TWIM_SHORT_LASTTX_STARTRX_MASK = TWIM_SHORTS_LASTTX_STARTRX_Msk, ///< Shortcut between LASTTX event and STARTRX task. + NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK = TWIM_SHORTS_LASTTX_SUSPEND_Msk, ///< Shortcut between LASTTX event and SUSPEND task. + NRF_TWIM_SHORT_LASTTX_STOP_MASK = TWIM_SHORTS_LASTTX_STOP_Msk, ///< Shortcut between LASTTX event and STOP task. + NRF_TWIM_SHORT_LASTRX_STARTTX_MASK = TWIM_SHORTS_LASTRX_STARTTX_Msk, ///< Shortcut between LASTRX event and STARTTX task. + NRF_TWIM_SHORT_LASTRX_STOP_MASK = TWIM_SHORTS_LASTRX_STOP_Msk ///< Shortcut between LASTRX event and STOP task. +} nrf_twim_short_mask_t; + +/** + * @brief TWIM interrupts. + */ +typedef enum +{ + NRF_TWIM_INT_STOPPED_MASK = TWIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event. + NRF_TWIM_INT_ERROR_MASK = TWIM_INTENSET_ERROR_Msk, ///< Interrupt on ERROR event. + NRF_TWIM_INT_SUSPENDED_MASK = (1 << 18), ///< Interrupt on SUSPENDED event. + NRF_TWIM_INT_RXSTARTED_MASK = TWIM_INTENSET_RXSTARTED_Msk, ///< Interrupt on RXSTARTED event. + NRF_TWIM_INT_TXSTARTED_MASK = TWIM_INTENSET_TXSTARTED_Msk, ///< Interrupt on TXSTARTED event. + NRF_TWIM_INT_LASTRX_MASK = TWIM_INTENSET_LASTRX_Msk, ///< Interrupt on LASTRX event. + NRF_TWIM_INT_LASTTX_MASK = TWIM_INTENSET_LASTTX_Msk ///< Interrupt on LASTTX event. +} nrf_twim_int_mask_t; + +/** + * @brief TWIM master clock frequency. + */ +typedef enum +{ + NRF_TWIM_FREQ_100K = TWIM_FREQUENCY_FREQUENCY_K100, ///< 100 kbps. + NRF_TWIM_FREQ_250K = TWIM_FREQUENCY_FREQUENCY_K250, ///< 250 kbps. + NRF_TWIM_FREQ_400K = TWIM_FREQUENCY_FREQUENCY_K400 ///< 400 kbps. +} nrf_twim_frequency_t; + +/** + * @brief TWIM error source. + */ +typedef enum +{ + NRF_TWIM_ERROR_ADDRESS_NACK = TWIM_ERRORSRC_ANACK_Msk, ///< NACK received after sending the address. + NRF_TWIM_ERROR_DATA_NACK = TWIM_ERRORSRC_DNACK_Msk ///< NACK received after sending a data byte. +} nrf_twim_error_t; + + +/** + * @brief Function for activating a specific TWIM task. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Task to activate. + */ +__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_reg, + nrf_twim_task_t task); + +/** + * @brief Function for getting the address of a specific TWIM task register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] task Requested task. + * + * @return Address of the specified task register. + */ +__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_reg, + nrf_twim_task_t task); + +/** + * @brief Function for clearing a specific TWIM event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to clear. + */ +__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event); + +/** + * @brief Function for checking the state of a specific TWIM event. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Event to check. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event); + +/** + * @brief Function for getting the address of a specific TWIM event register. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] event Requested event. + * + * @return Address of the specified event register. + */ +__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event); + +/** + * @brief Function for enabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask); + +/** + * @brief Function for disabling specified shortcuts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask); + +/** + * @brief Function for enabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupts to enable. + */ +__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_reg, + uint32_t int_mask); + +/** + * @brief Function for disabling specified interrupts. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupts to disable. + */ +__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_reg, + uint32_t int_mask); + +/** + * @brief Function for checking the state of a given interrupt. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] int_mask Interrupt to check. + * + * @retval true If the interrupt is enabled. + * @retval false If the interrupt is not enabled. + */ +__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_reg, + nrf_twim_int_mask_t int_mask); + +/** + * @brief Function for enabling the TWIM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for disabling the TWIM peripheral. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for configuring TWI pins. + * + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] scl_pin SCL pin number. + * @param[in] sda_pin SDA pin number. + */ +__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_reg, + uint32_t scl_pin, + uint32_t sda_pin); + +/** + * @brief Function for setting the TWI master clock frequency. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] frequency TWI frequency. + */ +__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_reg, + nrf_twim_frequency_t frequency); + +/** + * @brief Function for checking the TWI error source. + * + * The error flags are cleared after reading. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * + * @return Mask with error source flags. + */ +__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for setting the address to be used in TWI transfers. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] address Address to be used in transfers. + */ +__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_reg, + uint8_t address); + +/** + * @brief Function for setting the transmit buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] p_buffer Pointer to the buffer with data to send. + * @param[in] length Maximum number of data bytes to transmit. + */ +__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length); + +/** + * @brief Function for setting the receive buffer. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + * @param[in] p_buffer Pointer to the buffer for received data. + * @param[in] length Maximum number of data bytes to receive. + */ +__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_reg, + uint8_t * p_buffer, + uint8_t length); + +__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask); + +__STATIC_INLINE uint32_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_reg); + +__STATIC_INLINE uint32_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for enabling the TX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for disabling the TX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for enabling the RX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_reg); + +/** + * @brief Function for disabling the RX list feature. + * + * @param[in] p_reg Pointer to the peripheral registers structure. + */ +__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_reg); + +/** + * @} + */ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_twim_task_trigger(NRF_TWIM_Type * p_reg, + nrf_twim_task_t task) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; +} + +__STATIC_INLINE uint32_t * nrf_twim_task_address_get(NRF_TWIM_Type * p_reg, + nrf_twim_task_t task) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)task); +} + +__STATIC_INLINE void nrf_twim_event_clear(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event) +{ + *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif +} + +__STATIC_INLINE bool nrf_twim_event_check(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event) +{ + return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE uint32_t * nrf_twim_event_address_get(NRF_TWIM_Type * p_reg, + nrf_twim_event_t event) +{ + return (uint32_t *)((uint8_t *)p_reg + (uint32_t)event); +} + +__STATIC_INLINE void nrf_twim_shorts_enable(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask) +{ + p_reg->SHORTS |= shorts_mask; +} + +__STATIC_INLINE void nrf_twim_shorts_disable(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask) +{ + p_reg->SHORTS &= ~(shorts_mask); +} + +__STATIC_INLINE void nrf_twim_int_enable(NRF_TWIM_Type * p_reg, + uint32_t int_mask) +{ + p_reg->INTENSET = int_mask; +} + +__STATIC_INLINE void nrf_twim_int_disable(NRF_TWIM_Type * p_reg, + uint32_t int_mask) +{ + p_reg->INTENCLR = int_mask; +} + +__STATIC_INLINE bool nrf_twim_int_enable_check(NRF_TWIM_Type * p_reg, + nrf_twim_int_mask_t int_mask) +{ + return (bool)(p_reg->INTENSET & int_mask); +} + +__STATIC_INLINE void nrf_twim_enable(NRF_TWIM_Type * p_reg) +{ + p_reg->ENABLE = (TWIM_ENABLE_ENABLE_Enabled << TWIM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_twim_disable(NRF_TWIM_Type * p_reg) +{ + p_reg->ENABLE = (TWIM_ENABLE_ENABLE_Disabled << TWIM_ENABLE_ENABLE_Pos); +} + +__STATIC_INLINE void nrf_twim_pins_set(NRF_TWIM_Type * p_reg, + uint32_t scl_pin, + uint32_t sda_pin) +{ + p_reg->PSEL.SCL = scl_pin; + p_reg->PSEL.SDA = sda_pin; +} + +__STATIC_INLINE void nrf_twim_frequency_set(NRF_TWIM_Type * p_reg, + nrf_twim_frequency_t frequency) +{ + p_reg->FREQUENCY = frequency; +} + +__STATIC_INLINE uint32_t nrf_twim_errorsrc_get_and_clear(NRF_TWIM_Type * p_reg) +{ + uint32_t error_source = p_reg->ERRORSRC; + + // [error flags are cleared by writing '1' on their position] + p_reg->ERRORSRC = error_source; + + return error_source; +} + +__STATIC_INLINE void nrf_twim_address_set(NRF_TWIM_Type * p_reg, + uint8_t address) +{ + p_reg->ADDRESS = address; +} + +__STATIC_INLINE void nrf_twim_tx_buffer_set(NRF_TWIM_Type * p_reg, + uint8_t const * p_buffer, + uint8_t length) +{ + p_reg->TXD.PTR = (uint32_t)p_buffer; + p_reg->TXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_twim_rx_buffer_set(NRF_TWIM_Type * p_reg, + uint8_t * p_buffer, + uint8_t length) +{ + p_reg->RXD.PTR = (uint32_t)p_buffer; + p_reg->RXD.MAXCNT = length; +} + +__STATIC_INLINE void nrf_twim_shorts_set(NRF_TWIM_Type * p_reg, + uint32_t shorts_mask) +{ + p_reg->SHORTS = shorts_mask; +} + +__STATIC_INLINE uint32_t nrf_twim_txd_amount_get(NRF_TWIM_Type * p_reg) +{ + return p_reg->TXD.AMOUNT; +} + +__STATIC_INLINE uint32_t nrf_twim_rxd_amount_get(NRF_TWIM_Type * p_reg) +{ + return p_reg->RXD.AMOUNT; +} + +__STATIC_INLINE void nrf_twim_tx_list_enable(NRF_TWIM_Type * p_reg) +{ + p_reg->TXD.LIST = 1; +} + +__STATIC_INLINE void nrf_twim_tx_list_disable(NRF_TWIM_Type * p_reg) +{ + p_reg->TXD.LIST = 0; +} + +__STATIC_INLINE void nrf_twim_rx_list_enable(NRF_TWIM_Type * p_reg) +{ + p_reg->RXD.LIST = 1; +} + +__STATIC_INLINE void nrf_twim_rx_list_disable(NRF_TWIM_Type * p_reg) +{ + p_reg->RXD.LIST = 0; +} +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_TWIM_H__ diff --git a/components/drivers_nrf/hal/nrf_twis.h b/components/drivers_nrf/hal/nrf_twis.h index 551bf46..35b0811 100644 --- a/components/drivers_nrf/hal/nrf_twis.h +++ b/components/drivers_nrf/hal/nrf_twis.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -15,18 +43,21 @@ * @defgroup nrf_twis_hal TWIS HAL * @{ * - * @brief Hardware access layer for Two Wire Interface Slave with EasyDMA + * @brief @tagAPI52 Hardware access layer for Two Wire Interface Slave with EasyDMA * (TWIS) peripheral. */ #ifndef NRF_TWIS_H__ #define NRF_TWIS_H__ #include "nrf.h" -#include "nrf_drv_config.h" +#include "sdk_config.h" #include #include #include +#ifdef __cplusplus +extern "C" { +#endif /** * @brief TWIS tasks @@ -34,10 +65,7 @@ typedef enum { /*lint -save -e30*/ -#if !NRF_TWIS_PATCH_FOR_MPW3 /* STOP task is not functional in MPW3 (PAN-30) */ - /* Stop task is not working properly for first release */ NRF_TWIS_TASK_STOP = offsetof(NRF_TWIS_Type, TASKS_STOP), /**< Stop TWIS transaction */ -#endif NRF_TWIS_TASK_SUSPEND = offsetof(NRF_TWIS_Type, TASKS_SUSPEND), /**< Suspend TWIS transaction */ NRF_TWIS_TASK_RESUME = offsetof(NRF_TWIS_Type, TASKS_RESUME), /**< Resume TWIS transaction */ NRF_TWIS_TASK_PREPARERX = offsetof(NRF_TWIS_Type, TASKS_PREPARERX), /**< Prepare the TWIS slave to respond to a write command */ @@ -88,15 +116,8 @@ typedef enum typedef enum { NRF_TWIS_ERROR_OVERFLOW = TWIS_ERRORSRC_OVERFLOW_Msk, /**< RX buffer overflow detected, and prevented */ -#if NRF_TWIS_PATCH_FOR_MPW3 - /* Patched version of bit positions in ERRORSRC register (PAN-29) */ - NRF_TWIS_ERROR_DATA_NACK = 1U << 1, /**< NACK sent after receiving a data byte */ - NRF_TWIS_ERROR_OVERREAD = 1U << 2 /**< TX buffer over-read detected, and prevented */ -#else - /* Code that meets current documentation */ NRF_TWIS_ERROR_DATA_NACK = TWIS_ERRORSRC_DNACK_Msk, /**< NACK sent after receiving a data byte */ NRF_TWIS_ERROR_OVERREAD = TWIS_ERRORSRC_OVERREAD_Msk /**< TX buffer over-read detected, and prevented */ -#endif } nrf_twis_error_t; /** @@ -135,43 +156,43 @@ typedef uint8_t nrf_twis_address_t; /** * @brief Function for activating a specific TWIS task. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param task Task. */ -__STATIC_INLINE void nrf_twis_task_trigger(NRF_TWIS_Type * const p_twis, nrf_twis_task_t task); +__STATIC_INLINE void nrf_twis_task_trigger(NRF_TWIS_Type * const p_reg, nrf_twis_task_t task); /** * @brief Function for returning the address of a specific TWIS task register. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param task Task. * * @return Task address. */ __STATIC_INLINE uint32_t nrf_twis_task_address_get( - NRF_TWIS_Type const * const p_twis, + NRF_TWIS_Type const * const p_reg, nrf_twis_task_t task); /** * @brief Function for clearing a specific event. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param event Event. */ __STATIC_INLINE void nrf_twis_event_clear( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, nrf_twis_event_t event); /** * @brief Function for returning the state of a specific event. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param event Event. * * @retval true If the event is set. * @retval false If the event is not set. */ __STATIC_INLINE bool nrf_twis_event_check( - NRF_TWIS_Type const * const p_twis, + NRF_TWIS_Type const * const p_reg, nrf_twis_event_t event); @@ -179,132 +200,132 @@ __STATIC_INLINE bool nrf_twis_event_check( * @brief Function for getting and clearing the state of specific event * * This function checks the state of the event and clears it. - * @param[in,out] p_twis TWIS instance + * @param[in,out] p_reg Pointer to the peripheral registers structure. * @param event Event. * * @retval true If the event was set. * @retval false If the event was not set. */ __STATIC_INLINE bool nrf_twis_event_get_and_clear( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, nrf_twis_event_t event); /** * @brief Function for returning the address of a specific TWIS event register. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param event Event. * * @return Address. */ __STATIC_INLINE uint32_t nrf_twis_event_address_get( - NRF_TWIS_Type const * const p_twis, + NRF_TWIS_Type const * const p_reg, nrf_twis_event_t event); /** * @brief Function for setting a shortcut. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param short_mask Shortcuts mask. */ -__STATIC_INLINE void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_twis, uint32_t short_mask); +__STATIC_INLINE void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_reg, uint32_t short_mask); /** * @brief Function for clearing shortcuts. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param short_mask Shortcuts mask. */ -__STATIC_INLINE void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_twis, uint32_t short_mask); +__STATIC_INLINE void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_reg, uint32_t short_mask); /** * @brief Get the shorts mask * * Function returns shorts register. - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @return Flags of currently enabled shortcuts */ -__STATIC_INLINE uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_twis); +__STATIC_INLINE uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_reg); /** * @brief Function for enabling selected interrupts. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param int_mask Interrupts mask. */ -__STATIC_INLINE void nrf_twis_int_enable(NRF_TWIS_Type * const p_twis, uint32_t int_mask); +__STATIC_INLINE void nrf_twis_int_enable(NRF_TWIS_Type * const p_reg, uint32_t int_mask); /** * @brief Function for retrieving the state of selected interrupts. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param int_mask Interrupts mask. * * @retval true If any of selected interrupts is enabled. * @retval false If none of selected interrupts is enabled. */ -__STATIC_INLINE bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_twis, uint32_t int_mask); +__STATIC_INLINE bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_reg, uint32_t int_mask); /** * @brief Function for disabling selected interrupts. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param int_mask Interrupts mask. */ -__STATIC_INLINE void nrf_twis_int_disable(NRF_TWIS_Type * const p_twis, uint32_t int_mask); +__STATIC_INLINE void nrf_twis_int_disable(NRF_TWIS_Type * const p_reg, uint32_t int_mask); /** * @brief Function for retrieving and clearing the TWIS error source. * * @attention Error sources are cleared after read. - * @param[in] p_twis TWIS instance + * @param[in] p_reg Pointer to the peripheral registers structure. * @return Error source mask with values from @ref nrf_twis_error_t. */ -__STATIC_INLINE uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_twis); +__STATIC_INLINE uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_reg); /** * @brief Get information which of addresses matched * * Function returns index in the address table * that points to the address that already matched. - * @param[in] p_twis TWIS instance + * @param[in] p_reg Pointer to the peripheral registers structure. * @return Index of matched address */ -__STATIC_INLINE uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_twis); +__STATIC_INLINE uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_reg); /** * @brief Function for enabling TWIS. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_twis_enable(NRF_TWIS_Type * const p_twis); +__STATIC_INLINE void nrf_twis_enable(NRF_TWIS_Type * const p_reg); /** * @brief Function for disabling TWIS. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. */ -__STATIC_INLINE void nrf_twis_disable(NRF_TWIS_Type * const p_twis); +__STATIC_INLINE void nrf_twis_disable(NRF_TWIS_Type * const p_reg); /** * @brief Function for configuring TWIS pins. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param scl SCL pin number. * @param sda SDA pin number. */ -__STATIC_INLINE void nrf_twis_pins_set(NRF_TWIS_Type * const p_twis, uint32_t scl, uint32_t sda); +__STATIC_INLINE void nrf_twis_pins_set(NRF_TWIS_Type * const p_reg, uint32_t scl, uint32_t sda); /** * @brief Function for setting the receive buffer. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param p_buf Pointer to the buffer for received data. * @param length Maximum number of data bytes to receive. */ __STATIC_INLINE void nrf_twis_rx_buffer_set( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint8_t * p_buf, nrf_twis_amount_t length); @@ -312,32 +333,32 @@ __STATIC_INLINE void nrf_twis_rx_buffer_set( * @brief Function that prepares TWIS for receiving * * This function sets receive buffer and then sets NRF_TWIS_TASK_PREPARERX task. - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param p_buf Pointer to the buffer for received data. * @param length Maximum number of data bytes to receive. */ __STATIC_INLINE void nrf_twis_rx_prepare( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint8_t * p_buf, nrf_twis_amount_t length); /** * @brief Function for getting number of bytes received in the last transaction. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg TWIS instance. * @return Amount of bytes received. * */ -__STATIC_INLINE nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_twis); +__STATIC_INLINE nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_reg); /** * @brief Function for setting the transmit buffer. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param p_buf Pointer to the buffer with data to send. * @param length Maximum number of data bytes to transmit. */ __STATIC_INLINE void nrf_twis_tx_buffer_set( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint8_t const * p_buf, nrf_twis_amount_t length); @@ -345,35 +366,35 @@ __STATIC_INLINE void nrf_twis_tx_buffer_set( * @brief Function that prepares TWIS for transmitting * * This function sets transmit buffer and then sets NRF_TWIS_TASK_PREPARETX task. - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param p_buf Pointer to the buffer with data to send. * @param length Maximum number of data bytes to transmit. */ __STATIC_INLINE void nrf_twis_tx_prepare( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint8_t const * p_buf, nrf_twis_amount_t length); /** * @brief Function for getting number of bytes transmitted in the last transaction. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @return Amount of bytes transmitted. */ -__STATIC_INLINE nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_twis); +__STATIC_INLINE nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_reg); /** * @brief Function for setting slave address * * Function sets the selected address for this TWI interface. - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param n Index of address to set * @param addr Addres to set * @sa nrf_twis_config_address_set * @sa nrf_twis_config_address_get */ __STATIC_INLINE void nrf_twis_address_set( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint_fast8_t n, nrf_twis_address_t addr); @@ -381,54 +402,54 @@ __STATIC_INLINE void nrf_twis_address_set( * @brief Function for retrieving configured slave address * * Function gets the selected address for this TWI interface. - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param n Index of address to get */ __STATIC_INLINE nrf_twis_address_t nrf_twis_address_get( - NRF_TWIS_Type const * const p_twis, + NRF_TWIS_Type const * const p_reg, uint_fast8_t n); /** * @brief Function for setting the device address configuration. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param addr_mask Mask of address indexes of what device should answer to. * * @sa nrf_twis_address_set */ __STATIC_INLINE void nrf_twis_config_address_set( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, nrf_twis_config_addr_mask_t addr_mask); /** * @brief Function for retrieving the device address configuration. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * * @return Mask of address indexes of what device should answer to. */ __STATIC_INLINE nrf_twis_config_addr_mask_t nrf_twis_config_address_get( - NRF_TWIS_Type const * const p_twis); + NRF_TWIS_Type const * const p_reg); /** * @brief Function for setting the over-read character. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] orc Over-read character. Character clocked out in case of * over-read of the TXD buffer. */ __STATIC_INLINE void nrf_twis_orc_set( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint8_t orc); /** * @brief Function for setting the over-read character. * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * * @return Over-read character configured for selected instance. */ -__STATIC_INLINE uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_twis); +__STATIC_INLINE uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_reg); /** @} */ /* End of nrf_twis_hal */ @@ -443,30 +464,30 @@ __STATIC_INLINE uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_twis); * @internal * @brief Internal function for getting task/event register address * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @oaram offset Offset of the register from the instance beginning * * @attention offset has to be modulo 4 value. In other case we can get hardware fault. * @return Pointer to the register */ -__STATIC_INLINE volatile uint32_t* nrf_twis_getRegPtr(NRF_TWIS_Type * const p_twis, uint32_t offset) +__STATIC_INLINE volatile uint32_t* nrf_twis_getRegPtr(NRF_TWIS_Type * const p_reg, uint32_t offset) { - return (volatile uint32_t*)((uint8_t *)p_twis + (uint32_t)offset); + return (volatile uint32_t*)((uint8_t *)p_reg + (uint32_t)offset); } /** * @internal * @brief Internal function for getting task/event register address - constant version * - * @param[in] p_twis TWIS instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @oaram offset Offset of the register from the instance beginning * * @attention offset has to be modulo 4 value. In other case we can get hardware fault. * @return Pointer to the register */ -__STATIC_INLINE volatile const uint32_t* nrf_twis_getRegPtr_c(NRF_TWIS_Type const * const p_twis, uint32_t offset) +__STATIC_INLINE volatile const uint32_t* nrf_twis_getRegPtr_c(NRF_TWIS_Type const * const p_reg, uint32_t offset) { - return (volatile const uint32_t*)((uint8_t *)p_twis + (uint32_t)offset); + return (volatile const uint32_t*)((uint8_t *)p_reg + (uint32_t)offset); } @@ -475,203 +496,212 @@ __STATIC_INLINE volatile const uint32_t* nrf_twis_getRegPtr_c(NRF_TWIS_Type cons */ -void nrf_twis_task_trigger(NRF_TWIS_Type * const p_twis, nrf_twis_task_t task) +void nrf_twis_task_trigger(NRF_TWIS_Type * const p_reg, nrf_twis_task_t task) { - *(nrf_twis_getRegPtr(p_twis, (uint32_t)task)) = 1UL; + *(nrf_twis_getRegPtr(p_reg, (uint32_t)task)) = 1UL; } uint32_t nrf_twis_task_address_get( - NRF_TWIS_Type const * const p_twis, + NRF_TWIS_Type const * const p_reg, nrf_twis_task_t task) { - return (uint32_t)nrf_twis_getRegPtr_c(p_twis, (uint32_t)task); + return (uint32_t)nrf_twis_getRegPtr_c(p_reg, (uint32_t)task); } void nrf_twis_event_clear( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, nrf_twis_event_t event) { - *(nrf_twis_getRegPtr(p_twis, (uint32_t)event)) = 0UL; + *(nrf_twis_getRegPtr(p_reg, (uint32_t)event)) = 0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif } bool nrf_twis_event_check( - NRF_TWIS_Type const * const p_twis, + NRF_TWIS_Type const * const p_reg, nrf_twis_event_t event) { - return (bool)*nrf_twis_getRegPtr_c(p_twis, (uint32_t)event); + return (bool)*nrf_twis_getRegPtr_c(p_reg, (uint32_t)event); } bool nrf_twis_event_get_and_clear( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, nrf_twis_event_t event) { - bool ret = nrf_twis_event_check(p_twis, event); - if(ret) + bool ret = nrf_twis_event_check(p_reg, event); + if (ret) { - nrf_twis_event_clear(p_twis, event); + nrf_twis_event_clear(p_reg, event); } return ret; } uint32_t nrf_twis_event_address_get( - NRF_TWIS_Type const * const p_twis, + NRF_TWIS_Type const * const p_reg, nrf_twis_event_t event) { - return (uint32_t)nrf_twis_getRegPtr_c(p_twis, (uint32_t)event); + return (uint32_t)nrf_twis_getRegPtr_c(p_reg, (uint32_t)event); } -void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_twis, uint32_t short_mask) +void nrf_twis_shorts_enable(NRF_TWIS_Type * const p_reg, uint32_t short_mask) { - p_twis->SHORTS |= short_mask; + p_reg->SHORTS |= short_mask; } -void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_twis, uint32_t short_mask) +void nrf_twis_shorts_disable(NRF_TWIS_Type * const p_reg, uint32_t short_mask) { - if(~0U == short_mask) + if (~0U == short_mask) { /* Optimized version for "disable all" */ - p_twis->SHORTS = 0; + p_reg->SHORTS = 0; } else { - p_twis->SHORTS &= ~short_mask; + p_reg->SHORTS &= ~short_mask; } } -uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_twis) +uint32_t nrf_twis_shorts_get(NRF_TWIS_Type * const p_reg) { - return p_twis->SHORTS; + return p_reg->SHORTS; } -void nrf_twis_int_enable(NRF_TWIS_Type * const p_twis, uint32_t int_mask) +void nrf_twis_int_enable(NRF_TWIS_Type * const p_reg, uint32_t int_mask) { - p_twis->INTENSET = int_mask; + p_reg->INTENSET = int_mask; } -bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_twis, uint32_t int_mask) +bool nrf_twis_int_enable_check(NRF_TWIS_Type const * const p_reg, uint32_t int_mask) { - return (bool)(p_twis->INTENSET & int_mask); + return (bool)(p_reg->INTENSET & int_mask); } -void nrf_twis_int_disable(NRF_TWIS_Type * const p_twis, uint32_t int_mask) +void nrf_twis_int_disable(NRF_TWIS_Type * const p_reg, uint32_t int_mask) { - p_twis->INTENCLR = int_mask; + p_reg->INTENCLR = int_mask; } -uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_twis) +uint32_t nrf_twis_error_source_get_and_clear(NRF_TWIS_Type * const p_reg) { - uint32_t ret = p_twis->ERRORSRC; - p_twis->ERRORSRC = ret; + uint32_t ret = p_reg->ERRORSRC; + p_reg->ERRORSRC = ret; return ret; } -uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_twis) +uint_fast8_t nrf_twis_match_get(NRF_TWIS_Type const * p_reg) { - return (uint_fast8_t)p_twis->MATCH; + return (uint_fast8_t)p_reg->MATCH; } -void nrf_twis_enable(NRF_TWIS_Type * const p_twis) +void nrf_twis_enable(NRF_TWIS_Type * const p_reg) { - p_twis->ENABLE = (TWIS_ENABLE_ENABLE_Enabled << TWIS_ENABLE_ENABLE_Pos); + p_reg->ENABLE = (TWIS_ENABLE_ENABLE_Enabled << TWIS_ENABLE_ENABLE_Pos); } -void nrf_twis_disable(NRF_TWIS_Type * const p_twis) +void nrf_twis_disable(NRF_TWIS_Type * const p_reg) { - p_twis->ENABLE = (TWIS_ENABLE_ENABLE_Disabled << TWIS_ENABLE_ENABLE_Pos); + p_reg->ENABLE = (TWIS_ENABLE_ENABLE_Disabled << TWIS_ENABLE_ENABLE_Pos); } -void nrf_twis_pins_set(NRF_TWIS_Type * const p_twis, uint32_t scl, uint32_t sda) +void nrf_twis_pins_set(NRF_TWIS_Type * const p_reg, uint32_t scl, uint32_t sda) { - p_twis->PSEL.SCL = scl; - p_twis->PSEL.SDA = sda; + p_reg->PSEL.SCL = scl; + p_reg->PSEL.SDA = sda; } void nrf_twis_rx_buffer_set( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint8_t * p_buf, nrf_twis_amount_t length) { - p_twis->RXD.PTR = (uint32_t)p_buf; - p_twis->RXD.MAXCNT = length; + p_reg->RXD.PTR = (uint32_t)p_buf; + p_reg->RXD.MAXCNT = length; } __STATIC_INLINE void nrf_twis_rx_prepare( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint8_t * p_buf, nrf_twis_amount_t length) { - nrf_twis_rx_buffer_set(p_twis, p_buf, length); - nrf_twis_task_trigger(p_twis, NRF_TWIS_TASK_PREPARERX); + nrf_twis_rx_buffer_set(p_reg, p_buf, length); + nrf_twis_task_trigger(p_reg, NRF_TWIS_TASK_PREPARERX); } -nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_twis) +nrf_twis_amount_t nrf_twis_rx_amount_get(NRF_TWIS_Type const * const p_reg) { - return (nrf_twis_amount_t)p_twis->RXD.AMOUNT; + return (nrf_twis_amount_t)p_reg->RXD.AMOUNT; } void nrf_twis_tx_buffer_set( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint8_t const * p_buf, nrf_twis_amount_t length) { - p_twis->TXD.PTR = (uint32_t)p_buf; - p_twis->TXD.MAXCNT = length; + p_reg->TXD.PTR = (uint32_t)p_buf; + p_reg->TXD.MAXCNT = length; } __STATIC_INLINE void nrf_twis_tx_prepare( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint8_t const * p_buf, nrf_twis_amount_t length) { - nrf_twis_tx_buffer_set(p_twis, p_buf, length); - nrf_twis_task_trigger(p_twis, NRF_TWIS_TASK_PREPARETX); + nrf_twis_tx_buffer_set(p_reg, p_buf, length); + nrf_twis_task_trigger(p_reg, NRF_TWIS_TASK_PREPARETX); } -nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_twis) +nrf_twis_amount_t nrf_twis_tx_amount_get(NRF_TWIS_Type const * const p_reg) { - return (nrf_twis_amount_t)p_twis->TXD.AMOUNT; + return (nrf_twis_amount_t)p_reg->TXD.AMOUNT; } void nrf_twis_address_set( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint_fast8_t n, nrf_twis_address_t addr) { - p_twis->ADDRESS[n] = addr; + p_reg->ADDRESS[n] = addr; } nrf_twis_address_t nrf_twis_address_get( - NRF_TWIS_Type const * const p_twis, + NRF_TWIS_Type const * const p_reg, uint_fast8_t n) { - return (nrf_twis_address_t)p_twis->ADDRESS[n]; + return (nrf_twis_address_t)p_reg->ADDRESS[n]; } void nrf_twis_config_address_set( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, nrf_twis_config_addr_mask_t addr_mask) { /* This is the only configuration in TWIS - just write it without masking */ - p_twis->CONFIG = addr_mask; + p_reg->CONFIG = addr_mask; } -nrf_twis_config_addr_mask_t nrf_twis_config_address_get(NRF_TWIS_Type const * const p_twis) +nrf_twis_config_addr_mask_t nrf_twis_config_address_get(NRF_TWIS_Type const * const p_reg) { - return (nrf_twis_config_addr_mask_t)(p_twis->CONFIG & TWIS_ADDRESS_ADDRESS_Msk); + return (nrf_twis_config_addr_mask_t)(p_reg->CONFIG & TWIS_ADDRESS_ADDRESS_Msk); } void nrf_twis_orc_set( - NRF_TWIS_Type * const p_twis, + NRF_TWIS_Type * const p_reg, uint8_t orc) { - p_twis->ORC = orc; + p_reg->ORC = orc; } -uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_twis) +uint8_t nrf_twis_orc_get(NRF_TWIS_Type const * const p_reg) { - return (uint8_t)p_twis->ORC; + return (uint8_t)p_reg->ORC; } #endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +#ifdef __cplusplus +} +#endif + #endif /* NRF_TWIS_H__ */ diff --git a/components/drivers_nrf/hal/nrf_uart.h b/components/drivers_nrf/hal/nrf_uart.h index 4cac940..5bb1dcd 100644 --- a/components/drivers_nrf/hal/nrf_uart.h +++ b/components/drivers_nrf/hal/nrf_uart.h @@ -1,22 +1,58 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_UART_H__ #define NRF_UART_H__ #include "nrf.h" +#include "nrf_peripherals.h" #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + +//Temporary defining legacy UART for instance 1 +#define NRF_UART1 (NRF_UART_Type *)NRF_UARTE1 + /** * @defgroup nrf_uart_hal UART HAL * @{ @@ -80,7 +116,7 @@ typedef enum */ typedef enum { -#ifdef NRF52 +#ifdef UARTE_PRESENT NRF_UART_BAUDRATE_1200 = UARTE_BAUDRATE_BAUDRATE_Baud1200, /**< 1200 baud. */ NRF_UART_BAUDRATE_2400 = UARTE_BAUDRATE_BAUDRATE_Baud2400, /**< 2400 baud. */ NRF_UART_BAUDRATE_4800 = UARTE_BAUDRATE_BAUDRATE_Baud4800, /**< 4800 baud. */ @@ -152,7 +188,7 @@ typedef enum /** * @brief Function for clearing a specific UART event. * - * @param[in] p_reg UART instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] event Event to clear. */ __STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event); @@ -160,7 +196,7 @@ __STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_ /** * @brief Function for checking the state of a specific UART event. * - * @param[in] p_reg UART instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] event Event to check. * * @retval True if event is set, False otherwise. @@ -170,7 +206,7 @@ __STATIC_INLINE bool nrf_uart_event_check(NRF_UART_Type * p_reg, nrf_uart_event_ /** * @brief Function for returning the address of a specific UART event register. * - * @param[in] p_reg UART instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] event Desired event. * * @retval Address of specified event register. @@ -181,7 +217,7 @@ __STATIC_INLINE uint32_t nrf_uart_event_address_get(NRF_UART_Type * p_reg, /** * @brief Function for enabling a specific interrupt. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param int_mask Interrupts to enable. */ __STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mask); @@ -189,7 +225,7 @@ __STATIC_INLINE void nrf_uart_int_enable(NRF_UART_Type * p_reg, uint32_t int_mas /** * @brief Function for retrieving the state of a given interrupt. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param int_mask Mask of interrupt to check. * * @retval true If the interrupt is enabled. @@ -200,7 +236,7 @@ __STATIC_INLINE bool nrf_uart_int_enable_check(NRF_UART_Type * p_reg, uint32_t i /** * @brief Function for disabling specific interrupts. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param int_mask Interrupts to disable. */ __STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_mask); @@ -208,7 +244,7 @@ __STATIC_INLINE void nrf_uart_int_disable(NRF_UART_Type * p_reg, uint32_t int_ma /** * @brief Function for getting error source mask. Function is clearing error source flags after reading. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @return Mask with error source flags. */ __STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg); @@ -216,21 +252,21 @@ __STATIC_INLINE uint32_t nrf_uart_errorsrc_get_and_clear(NRF_UART_Type * p_reg); /** * @brief Function for enabling UART. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE void nrf_uart_enable(NRF_UART_Type * p_reg); /** * @brief Function for disabling UART. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg); /** * @brief Function for configuring TX/RX pins. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param pseltxd TXD pin number. * @param pselrxd RXD pin number. */ @@ -239,35 +275,35 @@ __STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t psel /** * @brief Function for disconnecting TX/RX pins. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg); /** * @brief Function for getting TX pin. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg); /** * @brief Function for getting RX pin. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg); /** * @brief Function for getting RTS pin. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg); /** * @brief Function for getting CTS pin. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg); @@ -275,7 +311,7 @@ __STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg); /** * @brief Function for configuring flow control pins. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param pselrts RTS pin number. * @param pselcts CTS pin number. */ @@ -286,14 +322,14 @@ __STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, /** * @brief Function for disconnecting flow control pins. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg); /** * @brief Function for reading RX data. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @return Received byte. */ __STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg); @@ -301,7 +337,7 @@ __STATIC_INLINE uint8_t nrf_uart_rxd_get(NRF_UART_Type * p_reg); /** * @brief Function for setting Tx data. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param txd Byte. */ __STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd); @@ -309,7 +345,7 @@ __STATIC_INLINE void nrf_uart_txd_set(NRF_UART_Type * p_reg, uint8_t txd); /** * @brief Function for starting an UART task. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param task Task. */ __STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_t task); @@ -317,7 +353,7 @@ __STATIC_INLINE void nrf_uart_task_trigger(NRF_UART_Type * p_reg, nrf_uart_task_ /** * @brief Function for returning the address of a specific task register. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param task Task. * * @return Task address. @@ -327,7 +363,7 @@ __STATIC_INLINE uint32_t nrf_uart_task_address_get(NRF_UART_Type * p_reg, nrf_ua /** * @brief Function for configuring UART. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param hwfc Hardware flow control. Enabled if true. * @param parity Parity. Included if true. */ @@ -338,7 +374,7 @@ __STATIC_INLINE void nrf_uart_configure(NRF_UART_Type * p_reg, /** * @brief Function for setting UART baudrate. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param baudrate Baudrate. */ __STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_baudrate_t baudrate); @@ -347,6 +383,10 @@ __STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_bau __STATIC_INLINE void nrf_uart_event_clear(NRF_UART_Type * p_reg, nrf_uart_event_t event) { *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif } @@ -395,8 +435,16 @@ __STATIC_INLINE void nrf_uart_disable(NRF_UART_Type * p_reg) __STATIC_INLINE void nrf_uart_txrx_pins_set(NRF_UART_Type * p_reg, uint32_t pseltxd, uint32_t pselrxd) { - p_reg->PSELTXD = pseltxd; +#if defined(UART_PSEL_RXD_CONNECT_Pos) + p_reg->PSEL.RXD = pselrxd; +#else p_reg->PSELRXD = pselrxd; +#endif +#if defined(UART_PSEL_TXD_CONNECT_Pos) + p_reg->PSEL.TXD = pseltxd; +#else + p_reg->PSELTXD = pseltxd; +#endif } __STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg) @@ -406,28 +454,53 @@ __STATIC_INLINE void nrf_uart_txrx_pins_disconnect(NRF_UART_Type * p_reg) __STATIC_INLINE uint32_t nrf_uart_tx_pin_get(NRF_UART_Type * p_reg) { +#if defined(UART_PSEL_TXD_CONNECT_Pos) + return p_reg->PSEL.TXD; +#else return p_reg->PSELTXD; +#endif } __STATIC_INLINE uint32_t nrf_uart_rx_pin_get(NRF_UART_Type * p_reg) { +#if defined(UART_PSEL_RXD_CONNECT_Pos) + return p_reg->PSEL.RXD; +#else return p_reg->PSELRXD; +#endif } __STATIC_INLINE uint32_t nrf_uart_rts_pin_get(NRF_UART_Type * p_reg) { +#if defined(UART_PSEL_RTS_CONNECT_Pos) + return p_reg->PSEL.RTS; +#else return p_reg->PSELRTS; +#endif } __STATIC_INLINE uint32_t nrf_uart_cts_pin_get(NRF_UART_Type * p_reg) { +#if defined(UART_PSEL_RTS_CONNECT_Pos) + return p_reg->PSEL.CTS; +#else return p_reg->PSELCTS; +#endif } __STATIC_INLINE void nrf_uart_hwfc_pins_set(NRF_UART_Type * p_reg, uint32_t pselrts, uint32_t pselcts) { +#if defined(UART_PSEL_RTS_CONNECT_Pos) + p_reg->PSEL.RTS = pselrts; +#else p_reg->PSELRTS = pselrts; +#endif + +#if defined(UART_PSEL_RTS_CONNECT_Pos) + p_reg->PSEL.CTS = pselcts; +#else p_reg->PSELCTS = pselcts; +#endif } __STATIC_INLINE void nrf_uart_hwfc_pins_disconnect(NRF_UART_Type * p_reg) @@ -468,4 +541,9 @@ __STATIC_INLINE void nrf_uart_baudrate_set(NRF_UART_Type * p_reg, nrf_uart_bau } #endif //SUPPRESS_INLINE_IMPLEMENTATION /** @} */ + +#ifdef __cplusplus +} +#endif + #endif //NRF_UART_H__ diff --git a/components/drivers_nrf/hal/nrf_uarte.h b/components/drivers_nrf/hal/nrf_uarte.h index cc79744..c4b6abd 100644 --- a/components/drivers_nrf/hal/nrf_uarte.h +++ b/components/drivers_nrf/hal/nrf_uarte.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_UARTE_H__ #define NRF_UARTE_H__ @@ -17,6 +45,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + #define NRF_UARTE_PSEL_DISCONNECTED 0xFFFFFFFF /** @@ -148,7 +180,7 @@ typedef enum /** * @brief Function for clearing a specific UARTE event. * - * @param[in] p_reg UARTE instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] event Event to clear. */ __STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event); @@ -156,7 +188,7 @@ __STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_eve /** * @brief Function for checking the state of a specific UARTE event. * - * @param[in] p_reg UARTE instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] event Event to check. * * @retval True if event is set, False otherwise. @@ -166,7 +198,7 @@ __STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_eve /** * @brief Function for returning the address of a specific UARTE event register. * - * @param[in] p_reg UARTE instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] event Desired event. * * @retval Address of specified event register. @@ -174,10 +206,26 @@ __STATIC_INLINE bool nrf_uarte_event_check(NRF_UARTE_Type * p_reg, nrf_uarte_eve __STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event); +/** + * @brief Function for enabling UARTE shortcuts. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param shorts_mask Shortcuts to enable. + */ +__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask); + +/** + * @brief Function for disabling UARTE shortcuts. + * + * @param p_reg Pointer to the peripheral registers structure. + * @param shorts_mask Shortcuts to disable. + */ +__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask); + /** * @brief Function for enabling UARTE interrupts. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param int_mask Interrupts to enable. */ __STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_mask); @@ -185,7 +233,7 @@ __STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_m /** * @brief Function for retrieving the state of a given interrupt. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param int_mask Mask of interrupt to check. * * @retval true If the interrupt is enabled. @@ -204,7 +252,7 @@ __STATIC_INLINE void nrf_uarte_int_disable(NRF_UARTE_Type * p_reg, uint32_t int_ /** * @brief Function for getting error source mask. Function is clearing error source flags after reading. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @return Mask with error source flags. */ __STATIC_INLINE uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg); @@ -212,21 +260,21 @@ __STATIC_INLINE uint32_t nrf_uarte_errorsrc_get_and_clear(NRF_UARTE_Type * p_reg /** * @brief Function for enabling UARTE. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE void nrf_uarte_enable(NRF_UARTE_Type * p_reg); /** * @brief Function for disabling UARTE. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE void nrf_uarte_disable(NRF_UARTE_Type * p_reg); /** * @brief Function for configuring TX/RX pins. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param pseltxd TXD pin number. * @param pselrxd RXD pin number. */ @@ -235,35 +283,35 @@ __STATIC_INLINE void nrf_uarte_txrx_pins_set(NRF_UARTE_Type * p_reg, uint32_t ps /** * @brief Function for disconnecting TX/RX pins. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE void nrf_uarte_txrx_pins_disconnect(NRF_UARTE_Type * p_reg); /** * @brief Function for getting TX pin. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE uint32_t nrf_uarte_tx_pin_get(NRF_UARTE_Type * p_reg); /** * @brief Function for getting RX pin. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE uint32_t nrf_uarte_rx_pin_get(NRF_UARTE_Type * p_reg); /** * @brief Function for getting RTS pin. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE uint32_t nrf_uarte_rts_pin_get(NRF_UARTE_Type * p_reg); /** * @brief Function for getting CTS pin. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg); @@ -271,7 +319,7 @@ __STATIC_INLINE uint32_t nrf_uarte_cts_pin_get(NRF_UARTE_Type * p_reg); /** * @brief Function for configuring flow control pins. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param pselrts RTS pin number. * @param pselcts CTS pin number. */ @@ -282,14 +330,14 @@ __STATIC_INLINE void nrf_uarte_hwfc_pins_set(NRF_UARTE_Type * p_reg, /** * @brief Function for disconnecting flow control pins. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. */ __STATIC_INLINE void nrf_uarte_hwfc_pins_disconnect(NRF_UARTE_Type * p_reg); /** * @brief Function for starting an UARTE task. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param task Task. */ __STATIC_INLINE void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_task_t task); @@ -297,7 +345,7 @@ __STATIC_INLINE void nrf_uarte_task_trigger(NRF_UARTE_Type * p_reg, nrf_uarte_ta /** * @brief Function for returning the address of a specific task register. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param task Task. * * @return Task address. @@ -307,7 +355,7 @@ __STATIC_INLINE uint32_t nrf_uarte_task_address_get(NRF_UARTE_Type * p_reg, nrf_ /** * @brief Function for configuring UARTE. * - * @param p_reg Instance. + * @param p_reg Pointer to the peripheral registers structure. * @param hwfc Hardware flow control. Enabled if true. * @param parity Parity. Included if true. */ @@ -347,7 +395,7 @@ __STATIC_INLINE uint32_t nrf_uarte_tx_amount_get(NRF_UARTE_Type * p_reg); /** * @brief Function for setting the receive buffer. * - * @param[in] p_reg Instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * @param[in] p_buffer Pointer to the buffer for received data. * @param[in] length Maximum number of data bytes to receive. */ @@ -358,7 +406,7 @@ __STATIC_INLINE void nrf_uarte_rx_buffer_set(NRF_UARTE_Type * p_reg, /** * @brief Function for getting number of bytes received in the last transaction. * - * @param[in] p_reg Instance. + * @param[in] p_reg Pointer to the peripheral registers structure. * * @retval Amount of bytes received. */ @@ -368,6 +416,10 @@ __STATIC_INLINE uint32_t nrf_uarte_rx_amount_get(NRF_UARTE_Type * p_reg); __STATIC_INLINE void nrf_uarte_event_clear(NRF_UARTE_Type * p_reg, nrf_uarte_event_t event) { *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); + (void)dummy; +#endif } @@ -382,6 +434,16 @@ __STATIC_INLINE uint32_t nrf_uarte_event_address_get(NRF_UARTE_Type * p_reg, return (uint32_t)((uint8_t *)p_reg + (uint32_t)event); } +__STATIC_INLINE void nrf_uarte_shorts_enable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask) +{ + p_reg->SHORTS |= shorts_mask; +} + +__STATIC_INLINE void nrf_uarte_shorts_disable(NRF_UARTE_Type * p_reg, uint32_t shorts_mask) +{ + p_reg->SHORTS &= ~(shorts_mask); +} + __STATIC_INLINE void nrf_uarte_int_enable(NRF_UARTE_Type * p_reg, uint32_t int_mask) { p_reg->INTENSET = int_mask; @@ -505,4 +567,9 @@ __STATIC_INLINE uint32_t nrf_uarte_rx_amount_get(NRF_UARTE_Type * p_reg) } #endif //SUPPRESS_INLINE_IMPLEMENTATION /** @} */ + +#ifdef __cplusplus +} +#endif + #endif //NRF_UARTE_H__ diff --git a/components/drivers_nrf/hal/nrf_usbd.h b/components/drivers_nrf/hal/nrf_usbd.h new file mode 100644 index 0000000..37eee83 --- /dev/null +++ b/components/drivers_nrf/hal/nrf_usbd.h @@ -0,0 +1,1289 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_USBD_H__ +#define NRF_USBD_H__ + +/** + * @ingroup nrf_drivers + * @defgroup nrf_usbd_hal USBD HAL + * @{ + * + * @brief @tagAPI52840 Hardware access layer for Two Wire Interface Slave with EasyDMA + * (USBD) peripheral. + */ + +#include "nrf_peripherals.h" +#include "nrf.h" +#include "nrf_assert.h" +#include +#include +#include + +/** + * @brief USBD tasks + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_USBD_TASK_STARTEPIN0 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[0] ), /**< Captures the EPIN[0].PTR, EPIN[0].MAXCNT and EPIN[0].CONFIG registers values, and enables control endpoint IN 0 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN1 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[1] ), /**< Captures the EPIN[1].PTR, EPIN[1].MAXCNT and EPIN[1].CONFIG registers values, and enables data endpoint IN 1 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN2 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[2] ), /**< Captures the EPIN[2].PTR, EPIN[2].MAXCNT and EPIN[2].CONFIG registers values, and enables data endpoint IN 2 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN3 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[3] ), /**< Captures the EPIN[3].PTR, EPIN[3].MAXCNT and EPIN[3].CONFIG registers values, and enables data endpoint IN 3 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN4 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[4] ), /**< Captures the EPIN[4].PTR, EPIN[4].MAXCNT and EPIN[4].CONFIG registers values, and enables data endpoint IN 4 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN5 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[5] ), /**< Captures the EPIN[5].PTR, EPIN[5].MAXCNT and EPIN[5].CONFIG registers values, and enables data endpoint IN 5 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN6 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[6] ), /**< Captures the EPIN[6].PTR, EPIN[6].MAXCNT and EPIN[6].CONFIG registers values, and enables data endpoint IN 6 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPIN7 = offsetof(NRF_USBD_Type, TASKS_STARTEPIN[7] ), /**< Captures the EPIN[7].PTR, EPIN[7].MAXCNT and EPIN[7].CONFIG registers values, and enables data endpoint IN 7 to respond to traffic from host */ + NRF_USBD_TASK_STARTISOIN = offsetof(NRF_USBD_Type, TASKS_STARTISOIN ), /**< Captures the ISOIN.PTR, ISOIN.MAXCNT and ISOIN.CONFIG registers values, and enables sending data on iso endpoint 8 */ + NRF_USBD_TASK_STARTEPOUT0 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[0]), /**< Captures the EPOUT[0].PTR, EPOUT[0].MAXCNT and EPOUT[0].CONFIG registers values, and enables control endpoint 0 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT1 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[1]), /**< Captures the EPOUT[1].PTR, EPOUT[1].MAXCNT and EPOUT[1].CONFIG registers values, and enables data endpoint 1 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT2 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[2]), /**< Captures the EPOUT[2].PTR, EPOUT[2].MAXCNT and EPOUT[2].CONFIG registers values, and enables data endpoint 2 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT3 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[3]), /**< Captures the EPOUT[3].PTR, EPOUT[3].MAXCNT and EPOUT[3].CONFIG registers values, and enables data endpoint 3 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT4 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[4]), /**< Captures the EPOUT[4].PTR, EPOUT[4].MAXCNT and EPOUT[4].CONFIG registers values, and enables data endpoint 4 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT5 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[5]), /**< Captures the EPOUT[5].PTR, EPOUT[5].MAXCNT and EPOUT[5].CONFIG registers values, and enables data endpoint 5 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT6 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[6]), /**< Captures the EPOUT[6].PTR, EPOUT[6].MAXCNT and EPOUT[6].CONFIG registers values, and enables data endpoint 6 to respond to traffic from host */ + NRF_USBD_TASK_STARTEPOUT7 = offsetof(NRF_USBD_Type, TASKS_STARTEPOUT[7]), /**< Captures the EPOUT[7].PTR, EPOUT[7].MAXCNT and EPOUT[7].CONFIG registers values, and enables data endpoint 7 to respond to traffic from host */ + NRF_USBD_TASK_STARTISOOUT = offsetof(NRF_USBD_Type, TASKS_STARTISOOUT ), /**< Captures the ISOOUT.PTR, ISOOUT.MAXCNT and ISOOUT.CONFIG registers values, and enables receiving of data on iso endpoint 8 */ + NRF_USBD_TASK_EP0RCVOUT = offsetof(NRF_USBD_Type, TASKS_EP0RCVOUT ), /**< Allows OUT data stage on control endpoint 0 */ + NRF_USBD_TASK_EP0STATUS = offsetof(NRF_USBD_Type, TASKS_EP0STATUS ), /**< Allows status stage on control endpoint 0 */ + NRF_USBD_TASK_EP0STALL = offsetof(NRF_USBD_Type, TASKS_EP0STALL ), /**< STALLs data and status stage on control endpoint 0 */ + NRF_USBD_TASK_DRIVEDPDM = offsetof(NRF_USBD_Type, TASKS_DPDMDRIVE ), /**< Forces D+ and D-lines to the state defined in the DPDMVALUE register */ + NRF_USBD_TASK_NODRIVEDPDM = offsetof(NRF_USBD_Type, TASKS_DPDMNODRIVE ), /**< Stops forcing D+ and D- lines to any state (USB engine takes control) */ + /*lint -restore*/ +}nrf_usbd_task_t; + +/** + * @brief USBD events + */ +typedef enum +{ + /*lint -save -e30*/ + NRF_USBD_EVENT_USBRESET = offsetof(NRF_USBD_Type, EVENTS_USBRESET ), /**< Signals that a USB reset condition has been detected on the USB lines */ + NRF_USBD_EVENT_STARTED = offsetof(NRF_USBD_Type, EVENTS_STARTED ), /**< Confirms that the EPIN[n].PTR, EPIN[n].MAXCNT, EPIN[n].CONFIG, or EPOUT[n].PTR, EPOUT[n].MAXCNT and EPOUT[n].CONFIG registers have been captured on all endpoints reported in the EPSTATUS register */ + NRF_USBD_EVENT_ENDEPIN0 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[0] ), /**< The whole EPIN[0] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN1 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[1] ), /**< The whole EPIN[1] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN2 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[2] ), /**< The whole EPIN[2] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN3 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[3] ), /**< The whole EPIN[3] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN4 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[4] ), /**< The whole EPIN[4] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN5 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[5] ), /**< The whole EPIN[5] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN6 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[6] ), /**< The whole EPIN[6] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPIN7 = offsetof(NRF_USBD_Type, EVENTS_ENDEPIN[7] ), /**< The whole EPIN[7] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_EP0DATADONE = offsetof(NRF_USBD_Type, EVENTS_EP0DATADONE), /**< An acknowledged data transfer has taken place on the control endpoint */ + NRF_USBD_EVENT_ENDISOIN0 = offsetof(NRF_USBD_Type, EVENTS_ENDISOIN ), /**< The whole ISOIN buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT0 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[0]), /**< The whole EPOUT[0] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT1 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[1]), /**< The whole EPOUT[1] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT2 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[2]), /**< The whole EPOUT[2] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT3 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[3]), /**< The whole EPOUT[3] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT4 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[4]), /**< The whole EPOUT[4] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT5 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[5]), /**< The whole EPOUT[5] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT6 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[6]), /**< The whole EPOUT[6] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDEPOUT7 = offsetof(NRF_USBD_Type, EVENTS_ENDEPOUT[7]), /**< The whole EPOUT[7] buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_ENDISOOUT0 = offsetof(NRF_USBD_Type, EVENTS_ENDISOOUT ), /**< The whole ISOOUT buffer has been consumed. The RAM buffer can be accessed safely by software. */ + NRF_USBD_EVENT_SOF = offsetof(NRF_USBD_Type, EVENTS_SOF ), /**< Signals that a SOF (start of frame) condition has been detected on the USB lines */ + NRF_USBD_EVENT_USBEVENT = offsetof(NRF_USBD_Type, EVENTS_USBEVENT ), /**< An event or an error not covered by specific events has occurred, check EVENTCAUSE register to find the cause */ + NRF_USBD_EVENT_EP0SETUP = offsetof(NRF_USBD_Type, EVENTS_EP0SETUP ), /**< A valid SETUP token has been received (and acknowledged) on the control endpoint */ + NRF_USBD_EVENT_DATAEP = offsetof(NRF_USBD_Type, EVENTS_EPDATA ), /**< A data transfer has occurred on a data endpoint, indicated by the EPDATASTATUS register */ + NRF_USBD_EVENT_ACCESSFAULT = offsetof(NRF_USBD_Type, EVENTS_ACCESSFAULT), /**< >Access to an unavailable USB register has been attempted (software or EasyDMA) */ + /*lint -restore*/ +}nrf_usbd_event_t; + +/** + * @brief USBD shorts + */ +typedef enum +{ + NRF_USBD_SHORT_EP0DATADONE_STARTEPIN0_MASK = USBD_SHORTS_EP0DATADONE_STARTEPIN0_Msk , /**< Shortcut between EP0DATADONE event and STARTEPIN0 task */ + NRF_USBD_SHORT_EP0DATADONE_STARTEPOUT0_MASK = USBD_SHORTS_EP0DATADONE_STARTEPOUT0_Msk, /**< Shortcut between EP0DATADONE event and STARTEPOUT0 task */ + NRF_USBD_SHORT_EP0DATADONE_EP0STATUS_MASK = USBD_SHORTS_EP0DATADONE_EP0STATUS_Msk , /**< Shortcut between EP0DATADONE event and EP0STATUS task */ + NRF_USBD_SHORT_ENDEPOUT0_EP0STATUS_MASK = USBD_SHORTS_ENDEPOUT0_EP0STATUS_Msk , /**< Shortcut between ENDEPOUT[0] event and EP0STATUS task */ + NRF_USBD_SHORT_ENDEPOUT0_EP0RCVOUT_MASK = USBD_SHORTS_ENDEPOUT0_EP0RCVOUT_Msk , /**< Shortcut between ENDEPOUT[0] event and EP0RCVOUT task */ +}nrf_usbd_short_mask_t; + +/** + * @brief USBD interrupts + */ +typedef enum +{ + NRF_USBD_INT_USBRESET_MASK = USBD_INTEN_USBRESET_Msk , /**< Enable or disable interrupt for USBRESET event */ + NRF_USBD_INT_STARTED_MASK = USBD_INTEN_STARTED_Msk , /**< Enable or disable interrupt for STARTED event */ + NRF_USBD_INT_ENDEPIN0_MASK = USBD_INTEN_ENDEPIN0_Msk , /**< Enable or disable interrupt for ENDEPIN[0] event */ + NRF_USBD_INT_ENDEPIN1_MASK = USBD_INTEN_ENDEPIN1_Msk , /**< Enable or disable interrupt for ENDEPIN[1] event */ + NRF_USBD_INT_ENDEPIN2_MASK = USBD_INTEN_ENDEPIN2_Msk , /**< Enable or disable interrupt for ENDEPIN[2] event */ + NRF_USBD_INT_ENDEPIN3_MASK = USBD_INTEN_ENDEPIN3_Msk , /**< Enable or disable interrupt for ENDEPIN[3] event */ + NRF_USBD_INT_ENDEPIN4_MASK = USBD_INTEN_ENDEPIN4_Msk , /**< Enable or disable interrupt for ENDEPIN[4] event */ + NRF_USBD_INT_ENDEPIN5_MASK = USBD_INTEN_ENDEPIN5_Msk , /**< Enable or disable interrupt for ENDEPIN[5] event */ + NRF_USBD_INT_ENDEPIN6_MASK = USBD_INTEN_ENDEPIN6_Msk , /**< Enable or disable interrupt for ENDEPIN[6] event */ + NRF_USBD_INT_ENDEPIN7_MASK = USBD_INTEN_ENDEPIN7_Msk , /**< Enable or disable interrupt for ENDEPIN[7] event */ + NRF_USBD_INT_EP0DATADONE_MASK = USBD_INTEN_EP0DATADONE_Msk, /**< Enable or disable interrupt for EP0DATADONE event */ + NRF_USBD_INT_ENDISOIN0_MASK = USBD_INTEN_ENDISOIN_Msk , /**< Enable or disable interrupt for ENDISOIN[0] event */ + NRF_USBD_INT_ENDEPOUT0_MASK = USBD_INTEN_ENDEPOUT0_Msk , /**< Enable or disable interrupt for ENDEPOUT[0] event */ + NRF_USBD_INT_ENDEPOUT1_MASK = USBD_INTEN_ENDEPOUT1_Msk , /**< Enable or disable interrupt for ENDEPOUT[1] event */ + NRF_USBD_INT_ENDEPOUT2_MASK = USBD_INTEN_ENDEPOUT2_Msk , /**< Enable or disable interrupt for ENDEPOUT[2] event */ + NRF_USBD_INT_ENDEPOUT3_MASK = USBD_INTEN_ENDEPOUT3_Msk , /**< Enable or disable interrupt for ENDEPOUT[3] event */ + NRF_USBD_INT_ENDEPOUT4_MASK = USBD_INTEN_ENDEPOUT4_Msk , /**< Enable or disable interrupt for ENDEPOUT[4] event */ + NRF_USBD_INT_ENDEPOUT5_MASK = USBD_INTEN_ENDEPOUT5_Msk , /**< Enable or disable interrupt for ENDEPOUT[5] event */ + NRF_USBD_INT_ENDEPOUT6_MASK = USBD_INTEN_ENDEPOUT6_Msk , /**< Enable or disable interrupt for ENDEPOUT[6] event */ + NRF_USBD_INT_ENDEPOUT7_MASK = USBD_INTEN_ENDEPOUT7_Msk , /**< Enable or disable interrupt for ENDEPOUT[7] event */ + NRF_USBD_INT_ENDISOOUT0_MASK = USBD_INTEN_ENDISOOUT_Msk , /**< Enable or disable interrupt for ENDISOOUT[0] event */ + NRF_USBD_INT_SOF_MASK = USBD_INTEN_SOF_Msk , /**< Enable or disable interrupt for SOF event */ + NRF_USBD_INT_USBEVENT_MASK = USBD_INTEN_USBEVENT_Msk , /**< Enable or disable interrupt for USBEVENT event */ + NRF_USBD_INT_EP0SETUP_MASK = USBD_INTEN_EP0SETUP_Msk , /**< Enable or disable interrupt for EP0SETUP event */ + NRF_USBD_INT_DATAEP_MASK = USBD_INTEN_EPDATA_Msk , /**< Enable or disable interrupt for EPDATA event */ + NRF_USBD_INT_ACCESSFAULT_MASK = USBD_INTEN_ACCESSFAULT_Msk, /**< Enable or disable interrupt for ACCESSFAULT event */ +}nrf_usbd_int_mask_t; + + +/** + * @brief Function for activating a specific USBD task. + * + * @param task Task. + */ +__STATIC_INLINE void nrf_usbd_task_trigger(nrf_usbd_task_t task); + +/** + * @brief Function for returning the address of a specific USBD task register. + * + * @param task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_usbd_task_address_get(nrf_usbd_task_t task); + +/** + * @brief Function for clearing a specific event. + * + * @param event Event. + */ +__STATIC_INLINE void nrf_usbd_event_clear(nrf_usbd_event_t event); + +/** + * @brief Function for returning the state of a specific event. + * + * @param event Event. + * + * @retval true If the event is set. + * @retval false If the event is not set. + */ +__STATIC_INLINE bool nrf_usbd_event_check(nrf_usbd_event_t event); + +/** + * @brief Function for getting and clearing the state of specific event + * + * This function checks the state of the event and clears it. + * + * @param event Event. + * + * @retval true If the event was set. + * @retval false If the event was not set. + */ +__STATIC_INLINE bool nrf_usbd_event_get_and_clear(nrf_usbd_event_t event); + +/** + * @brief Function for returning the address of a specific USBD event register. + * + * @param event Event. + * + * @return Address. + */ +__STATIC_INLINE uint32_t nrf_usbd_event_address_get(nrf_usbd_event_t event); + +/** + * @brief Function for setting a shortcut. + * + * @param short_mask Shortcuts mask. + */ +__STATIC_INLINE void nrf_usbd_shorts_enable(uint32_t short_mask); + +/** + * @brief Function for clearing shortcuts. + * + * @param short_mask Shortcuts mask. + */ +__STATIC_INLINE void nrf_usbd_shorts_disable(uint32_t short_mask); + +/** + * @brief Get the shorts mask + * + * Function returns shorts register. + * + * @return Flags of currently enabled shortcuts + */ +__STATIC_INLINE uint32_t nrf_usbd_shorts_get(void); + +/** + * @brief Function for enabling selected interrupts. + * + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_usbd_int_enable(uint32_t int_mask); + +/** + * @brief Function for retrieving the state of selected interrupts. + * + * @param int_mask Interrupts mask. + * + * @retval true If any of selected interrupts is enabled. + * @retval false If none of selected interrupts is enabled. + */ +__STATIC_INLINE bool nrf_usbd_int_enable_check(uint32_t int_mask); + +/** + * @brief Function for retrieving the information about enabled interrupts. + * + * @return The flags of enabled interrupts. + */ +__STATIC_INLINE uint32_t nrf_usbd_int_enable_get(void); + +/** + * @brief Function for disabling selected interrupts. + * + * @param int_mask Interrupts mask. + */ +__STATIC_INLINE void nrf_usbd_int_disable(uint32_t int_mask); + + +/** @} */ /* End of nrf_usbd_hal */ + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +/* ------------------------------------------------------------------------------------------------ + * Internal functions + */ + +/** + * @internal + * @brief Internal function for getting task/event register address + * + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile uint32_t* nrf_usbd_getRegPtr(uint32_t offset) +{ + return (volatile uint32_t*)(((uint8_t *)NRF_USBD) + (uint32_t)offset); +} + +/** + * @internal + * @brief Internal function for getting task/event register address - constant version + * + * @oaram offset Offset of the register from the instance beginning + * + * @attention offset has to be modulo 4 value. In other case we can get hardware fault. + * @return Pointer to the register + */ +__STATIC_INLINE volatile const uint32_t* nrf_usbd_getRegPtr_c(uint32_t offset) +{ + return (volatile const uint32_t*)(((uint8_t *)NRF_USBD) + (uint32_t)offset); +} + +/* ------------------------------------------------------------------------------------------------ + * Interface functions definitions + */ + +void nrf_usbd_task_trigger(nrf_usbd_task_t task) +{ + *(nrf_usbd_getRegPtr((uint32_t)task)) = 1UL; + __ISB(); + __DSB(); +} + +uint32_t nrf_usbd_task_address_get(nrf_usbd_task_t task) +{ + return (uint32_t)nrf_usbd_getRegPtr_c((uint32_t)task); +} + +void nrf_usbd_event_clear(nrf_usbd_event_t event) +{ + *(nrf_usbd_getRegPtr((uint32_t)event)) = 0UL; + __ISB(); + __DSB(); +} + +bool nrf_usbd_event_check(nrf_usbd_event_t event) +{ + return (bool)*nrf_usbd_getRegPtr_c((uint32_t)event); +} + +bool nrf_usbd_event_get_and_clear(nrf_usbd_event_t event) +{ + bool ret = nrf_usbd_event_check(event); + if(ret) + { + nrf_usbd_event_clear(event); + } + return ret; +} + +uint32_t nrf_usbd_event_address_get(nrf_usbd_event_t event) +{ + return (uint32_t)nrf_usbd_getRegPtr_c((uint32_t)event); +} + +void nrf_usbd_shorts_enable(uint32_t short_mask) +{ + NRF_USBD->SHORTS |= short_mask; +} + +void nrf_usbd_shorts_disable(uint32_t short_mask) +{ + if(~0U == short_mask) + { + /* Optimized version for "disable all" */ + NRF_USBD->SHORTS = 0; + } + else + { + NRF_USBD->SHORTS &= ~short_mask; + } +} + +uint32_t nrf_usbd_shorts_get(void) +{ + return NRF_USBD->SHORTS; +} + +void nrf_usbd_int_enable(uint32_t int_mask) +{ + NRF_USBD->INTENSET = int_mask; +} + +bool nrf_usbd_int_enable_check(uint32_t int_mask) +{ + return !!(NRF_USBD->INTENSET & int_mask); +} + +uint32_t nrf_usbd_int_enable_get(void) +{ + return NRF_USBD->INTENSET; +} + +void nrf_usbd_int_disable(uint32_t int_mask) +{ + NRF_USBD->INTENCLR = int_mask; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +/* ------------------------------------------------------------------------------------------------ + * End of automatically generated part + * ------------------------------------------------------------------------------------------------ + */ +/** + * @ingroup nrf_usbd_hal + * @{ + */ + +/** + * @brief Frame counter size + * + * The number of counts that can be fitted into frame counter + */ +#define NRF_USBD_FRAMECNTR_SIZE ( (USBD_FRAMECNTR_FRAMECNTR_Msk >> USBD_FRAMECNTR_FRAMECNTR_Pos) + 1UL ) +#ifndef USBD_FRAMECNTR_FRAMECNTR_Msk +#error USBD_FRAMECNTR_FRAMECNTR_Msk should be changed into USBD_FRAMECNTR_FRAMECNTR_Msk +#endif + +/** + * @brief First isochronous endpoint number + * + * The number of the first isochronous endpoint + */ +#define NRF_USBD_EPISO_FIRST 8 + +/** + * @brief Total number of IN endpoints + * + * Total number of IN endpoint (including ISOCHRONOUS). + */ +#define NRF_USBD_EPIN_CNT 9 + +/** + * @brief Total number of OUT endpoints + * + * Total number of OUT endpoint (including ISOCHRONOUS). + */ +#define NRF_USBD_EPOUT_CNT 9 + +/** + * @brief Mask of the direction bit in endpoint number + */ +#define NRF_USBD_EP_DIR_Msk (1U << 7) + +/** + * @brief The value of direction bit for IN endpoint direction + */ +#define NRF_USBD_EP_DIR_IN (1U << 7) + +/** + * @brief The value of direction bit for OUT endpoint direction + */ +#define NRF_USBD_EP_DIR_OUT (0U << 7) + +/** + * @brief Make IN endpoint identifier from endpoint number + * + * Macro that sets direction bit to make IN endpoint + * @param[in] epnr Endpoint number + * @return IN Endpoint identifier + */ +#define NRF_USBD_EPIN(epnr) (((uint8_t)(epnr)) | NRF_USBD_EP_DIR_IN) + +/** + * @brief Make OUT endpoint identifier from endpoint number + * + * Macro that sets direction bit to make OUT endpoint + * @param[in] epnr Endpoint number + * @return OUT Endpoint identifier + */ +#define NRF_USBD_EPOUT(epnr) (((uint8_t)(epnr)) | NRF_USBD_EP_DIR_OUT) + +/** + * @brief Extract the endpoint number from endpoint identifier + * + * Macro that strips out the information about endpoint direction. + * @param[in] ep Endpoint identifier + * @return Endpoint number + */ +#define NRF_USBD_EP_NR_GET(ep) ((uint8_t)(((uint8_t)(ep)) & 0xFU)) + +/** + * @brief Macro for checking endpoint direction + * + * This macro checks if given endpoint has IN direction + * @param ep Endpoint identifier + * @retval true If the endpoint direction is IN + * @retval false If the endpoint direction is OUT + */ +#define NRF_USBD_EPIN_CHECK(ep) ( (((uint8_t)(ep)) & NRF_USBD_EP_DIR_Msk) == NRF_USBD_EP_DIR_IN ) + +/** + * @brief Macro for checking endpoint direction + * + * This macro checks if given endpoint has OUT direction + * @param ep Endpoint identifier + * @retval true If the endpoint direction is OUT + * @retval false If the endpoint direction is IN + */ +#define NRF_USBD_EPOUT_CHECK(ep) ( (((uint8_t)(ep)) & NRF_USBD_EP_DIR_Msk) == NRF_USBD_EP_DIR_OUT ) + +/** + * @brief Macro for checking if endpoint is isochronous + * + * @param ep It can be endpoint identifier or just endpoint number to check + * @retval true The endpoint is isochronous type + * @retval false The endpoint is bulk of interrupt type + */ +#define NRF_USBD_EPISO_CHECK(ep) (NRF_USBD_EP_NR_GET(ep) >= NRF_USBD_EPISO_FIRST) + + +/** + * @brief EVENTCAUSE register bit masks + */ +typedef enum +{ + NRF_USBD_EVENTCAUSE_ISOOUTCRC_MASK = USBD_EVENTCAUSE_ISOOUTCRC_Msk, /**< CRC error was detected on isochronous OUT endpoint 8. */ + NRF_USBD_EVENTCAUSE_SUSPEND_MASK = USBD_EVENTCAUSE_SUSPEND_Msk , /**< Signals that the USB lines have been seen idle long enough for the device to enter suspend. */ + NRF_USBD_EVENTCAUSE_RESUME_MASK = USBD_EVENTCAUSE_RESUME_Msk , /**< Signals that a RESUME condition (K state or activity restart) has been detected on the USB lines. */ + NRF_USBD_EVENTCAUSE_READY_MASK = USBD_EVENTCAUSE_READY_Msk /**< MAC is ready for normal operation, rised few us after USBD enabling */ +}nrf_usbd_eventcause_mask_t; + +/** + * @brief BUSSTATE register bit masks + */ +typedef enum +{ + NRF_USBD_BUSSTATE_DM_MASK = USBD_BUSSTATE_DM_Msk, /**< Negative line mask */ + NRF_USBD_BUSSTATE_DP_MASK = USBD_BUSSTATE_DP_Msk, /**< Positive line mask */ + /** Both lines are low */ + NRF_USBD_BUSSTATE_DPDM_LL = (USBD_BUSSTATE_DM_Low << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_Low << USBD_BUSSTATE_DP_Pos), + /** Positive line is high, negative line is low */ + NRF_USBD_BUSSTATE_DPDM_HL = (USBD_BUSSTATE_DM_Low << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_High << USBD_BUSSTATE_DP_Pos), + /** Positive line is low, negative line is high */ + NRF_USBD_BUSSTATE_DPDM_LH = (USBD_BUSSTATE_DM_High << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_Low << USBD_BUSSTATE_DP_Pos), + /** Both lines are high */ + NRF_USBD_BUSSTATE_DPDM_HH = (USBD_BUSSTATE_DM_High << USBD_BUSSTATE_DM_Pos) | (USBD_BUSSTATE_DP_High << USBD_BUSSTATE_DP_Pos), + /** J state */ + NRF_USBD_BUSSTATE_J = NRF_USBD_BUSSTATE_DPDM_HL, + /** K state */ + NRF_USBD_BUSSTATE_K = NRF_USBD_BUSSTATE_DPDM_LH, + /** Single ended 0 */ + NRF_USBD_BUSSTATE_SE0 = NRF_USBD_BUSSTATE_DPDM_LL, + /** Single ended 1 */ + NRF_USBD_BUSSTATE_SE1 = NRF_USBD_BUSSTATE_DPDM_HH +}nrf_usbd_busstate_t; + +/** + * @brief DPDMVALUE register + */ +typedef enum +{ + /**Generate Resume signal. Signal is generated for 50 us or 5 ms, + * depending on bus state */ + NRF_USBD_DPDMVALUE_RESUME = USBD_DPDMVALUE_STATE_Resume, + /** D+ Forced high, D- forced low (J state) */ + NRF_USBD_DPDMVALUE_J = USBD_DPDMVALUE_STATE_J, + /** D+ Forced low, D- forced high (K state) */ + NRF_USBD_DPMVALUE_K = USBD_DPDMVALUE_STATE_K +}nrf_usbd_dpdmvalue_t; + +/** + * @brief Dtoggle value or operation + */ +typedef enum +{ + NRF_USBD_DTOGGLE_NOP = USBD_DTOGGLE_VALUE_Nop, /**< No operation - do not change current data toggle on selected endpoint */ + NRF_USBD_DTOGGLE_DATA0 = USBD_DTOGGLE_VALUE_Data0,/**< Data toggle is DATA0 on selected endpoint */ + NRF_USBD_DTOGGLE_DATA1 = USBD_DTOGGLE_VALUE_Data1 /**< Data toggle is DATA1 on selected endpoint */ +}nrf_usbd_dtoggle_t; + +/** + * @brief EPSTATUS bit masks + */ +typedef enum +{ + NRF_USBD_EPSTATUS_EPIN0_MASK = USBD_EPSTATUS_EPIN0_Msk, + NRF_USBD_EPSTATUS_EPIN1_MASK = USBD_EPSTATUS_EPIN1_Msk, + NRF_USBD_EPSTATUS_EPIN2_MASK = USBD_EPSTATUS_EPIN2_Msk, + NRF_USBD_EPSTATUS_EPIN3_MASK = USBD_EPSTATUS_EPIN3_Msk, + NRF_USBD_EPSTATUS_EPIN4_MASK = USBD_EPSTATUS_EPIN4_Msk, + NRF_USBD_EPSTATUS_EPIN5_MASK = USBD_EPSTATUS_EPIN5_Msk, + NRF_USBD_EPSTATUS_EPIN6_MASK = USBD_EPSTATUS_EPIN6_Msk, + NRF_USBD_EPSTATUS_EPIN7_MASK = USBD_EPSTATUS_EPIN7_Msk, + + NRF_USBD_EPSTATUS_EPOUT0_MASK = USBD_EPSTATUS_EPOUT0_Msk, + NRF_USBD_EPSTATUS_EPOUT1_MASK = USBD_EPSTATUS_EPOUT1_Msk, + NRF_USBD_EPSTATUS_EPOUT2_MASK = USBD_EPSTATUS_EPOUT2_Msk, + NRF_USBD_EPSTATUS_EPOUT3_MASK = USBD_EPSTATUS_EPOUT3_Msk, + NRF_USBD_EPSTATUS_EPOUT4_MASK = USBD_EPSTATUS_EPOUT4_Msk, + NRF_USBD_EPSTATUS_EPOUT5_MASK = USBD_EPSTATUS_EPOUT5_Msk, + NRF_USBD_EPSTATUS_EPOUT6_MASK = USBD_EPSTATUS_EPOUT6_Msk, + NRF_USBD_EPSTATUS_EPOUT7_MASK = USBD_EPSTATUS_EPOUT7_Msk, +}nrf_usbd_epstatus_mask_t; + +/** + * @brief DATAEPSTATUS bit masks + */ +typedef enum +{ + NRF_USBD_EPDATASTATUS_EPIN1_MASK = USBD_EPDATASTATUS_EPIN1_Msk, + NRF_USBD_EPDATASTATUS_EPIN2_MASK = USBD_EPDATASTATUS_EPIN2_Msk, + NRF_USBD_EPDATASTATUS_EPIN3_MASK = USBD_EPDATASTATUS_EPIN3_Msk, + NRF_USBD_EPDATASTATUS_EPIN4_MASK = USBD_EPDATASTATUS_EPIN4_Msk, + NRF_USBD_EPDATASTATUS_EPIN5_MASK = USBD_EPDATASTATUS_EPIN5_Msk, + NRF_USBD_EPDATASTATUS_EPIN6_MASK = USBD_EPDATASTATUS_EPIN6_Msk, + NRF_USBD_EPDATASTATUS_EPIN7_MASK = USBD_EPDATASTATUS_EPIN7_Msk, + + NRF_USBD_EPDATASTATUS_EPOUT1_MASK = USBD_EPDATASTATUS_EPOUT1_Msk, + NRF_USBD_EPDATASTATUS_EPOUT2_MASK = USBD_EPDATASTATUS_EPOUT2_Msk, + NRF_USBD_EPDATASTATUS_EPOUT3_MASK = USBD_EPDATASTATUS_EPOUT3_Msk, + NRF_USBD_EPDATASTATUS_EPOUT4_MASK = USBD_EPDATASTATUS_EPOUT4_Msk, + NRF_USBD_EPDATASTATUS_EPOUT5_MASK = USBD_EPDATASTATUS_EPOUT5_Msk, + NRF_USBD_EPDATASTATUS_EPOUT6_MASK = USBD_EPDATASTATUS_EPOUT6_Msk, + NRF_USBD_EPDATASTATUS_EPOUT7_MASK = USBD_EPDATASTATUS_EPOUT7_Msk, +}nrf_usbd_dataepstatus_mask_t; + +/** + * @brief ISOSPLIT configurations + */ +typedef enum +{ + NRF_USBD_ISOSPLIT_OneDir = USBD_ISOSPLIT_SPLIT_OneDir, /**< Full buffer dedicated to either iso IN or OUT */ + NRF_USBD_ISOSPLIT_Half = USBD_ISOSPLIT_SPLIT_HalfIN, /**< Buffer divided in half */ + +}nrf_usbd_isosplit_t; + +/** + * @brief Enable USBD + */ +__STATIC_INLINE void nrf_usbd_enable(void); + +/** + * @brief Disable USBD + */ +__STATIC_INLINE void nrf_usbd_disable(void); + +/** + * @brief Get EVENTCAUSE register + * + * @return Flag values defined in @ref nrf_usbd_eventcause_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_eventcause_get(void); + +/** + * @brief Clear EVENTCAUSE flags + * + * @param flags Flags defined in @ref nrf_usbd_eventcause_mask_t + */ +__STATIC_INLINE void nrf_usbd_eventcause_clear(uint32_t flags); + +/** + * @brief Get EVENTCAUSE register and clear flags that are set + * + * The safest way to return current EVENTCAUSE register. + * All the flags that are returned would be cleared inside EVENTCAUSE register. + * + * @return Flag values defined in @ref nrf_usbd_eventcause_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_eventcause_get_and_clear(void); + +/** + * @brief Get BUSSTATE register value + * + * @return The value of BUSSTATE register + */ +__STATIC_INLINE nrf_usbd_busstate_t nrf_usbd_busstate_get(void); + +/** + * @brief Get HALTEDEPIN register value + * + * @param ep Endpoint number with IN/OUT flag + * + * @return The value of HALTEDEPIN or HALTEDOUT register for selected endpoint + * + * @note + * Use this function for the response for GetStatus() request to endpoint. + * To check if endpoint is stalled in the code use @ref nrf_usbd_ep_is_stall. + */ +__STATIC_INLINE uint32_t nrf_usbd_haltedep(uint8_t ep); + +/** + * @brief Check if selected endpoint is stalled + * + * Function to be used as a syntax sweeter for @ref nrf_usbd_haltedep. + * + * Also as the isochronous endpoint cannot be halted - it returns always false + * if isochronous endpoint is checked. + * + * @param ep Endpoint number with IN/OUT flag + * + * @return The information if the enepoint is halted. + */ +__STATIC_INLINE bool nrf_usbd_ep_is_stall(uint8_t ep); + +/** + * @brief Get EPSTATUS register value + * + * @return Flag values defined in @ref nrf_usbd_epstatus_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_epstatus_get(void); + +/** + * @brief Clear EPSTATUS register value + * + * @param flags Flags defined in @ref nrf_usbd_epstatus_mask_t + */ +__STATIC_INLINE void nrf_usbd_epstatus_clear(uint32_t flags); + +/** + * @brief Get and clear EPSTATUS register value + * + * Function clears all flags in register set before returning its value. + * @return Flag values defined in @ref nrf_usbd_epstatus_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_epstatus_get_and_clear(void); + +/** + * @brief Get DATAEPSTATUS register value + * + * @return Flag values defined in @ref nrf_usbd_dataepstatus_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_epdatastatus_get(void); + +/** + * @brief Clear DATAEPSTATUS register value + * + * @param flags Flags defined in @ref nrf_usbd_dataepstatus_mask_t + */ +__STATIC_INLINE void nrf_usbd_epdatastatus_clear(uint32_t flags); + +/** + * @brief Get and clear DATAEPSTATUS register value + * + * Function clears all flags in register set before returning its value. + * @return Flag values defined in @ref nrf_usbd_dataepstatus_mask_t + */ +__STATIC_INLINE uint32_t nrf_usbd_epdatastatus_get_and_clear(void); + +/** + * @name Setup command frame functions + * + * Functions for setup command frame parts access + * @{ + */ + /** + * @brief Read BMREQUESTTYPE - part of SETUP packet + * + * @return the value of BREQUESTTYPE on last received SETUP frame + */ + __STATIC_INLINE uint8_t nrf_usbd_setup_bmrequesttype_get(void); + + /** + * @brief Read BMREQUEST - part of SETUP packet + * + * @return the value of BREQUEST on last received SETUP frame + */ + __STATIC_INLINE uint8_t nrf_usbd_setup_brequest_get(void); + + /** + * @brief Read WVALUE - part of SETUP packet + * + * @return the value of WVALUE on last received SETUP frame + */ + __STATIC_INLINE uint16_t nrf_usbd_setup_wvalue_get(void); + + /** + * @brief Read WINDEX - part of SETUP packet + * + * @return the value of WINDEX on last received SETUP frame + */ + __STATIC_INLINE uint16_t nrf_usbd_setup_windex_get(void); + + /** + * @brief Read WLENGTH - part of SETUP packet + * + * @return the value of WLENGTH on last received SETUP frame + */ + __STATIC_INLINE uint16_t nrf_usbd_setup_wlength_get(void); +/** @} */ + +/** + * @brief Get number of received bytes on selected endpoint + * + * @param ep Endpoint identifier. + * + * @return Number of received bytes. + * + * @note This function may be used on Bulk/Interrupt and Isochronous endpoints. + */ +__STATIC_INLINE size_t nrf_usbd_epout_size_get(uint8_t ep); + +/** + * @brief Clear out endpoint to accept any new incoming traffic + * + * @param ep ep Endpoint identifier. Only OUT Interrupt/Bulk endpoints are accepted. + */ +__STATIC_INLINE void nrf_usbd_epout_clear(uint8_t ep); + +/** + * @brief Enable USB pullup + */ +__STATIC_INLINE void nrf_usbd_pullup_enable(void); + +/** + * @brief Disable USB pullup + */ +__STATIC_INLINE void nrf_usbd_pullup_disable(void); + +/** + * @brief Return USB pullup state + */ +__STATIC_INLINE bool nrf_usbd_pullup_check(void); + +/** + * @brief Configure the value to be forced on the bus on DRIVEDPDM task + * + * Selected state would be forced on the bus when @ref NRF_USBD_TASK_DRIVEDPM is set. + * The state would be removed from the bus on @ref NRF_USBD_TASK_NODRIVEDPM and + * the control would be returned to the USBD peripheral. + * @param val State to be set + */ +__STATIC_INLINE void nrf_usbd_dpdmvalue_set(nrf_usbd_dpdmvalue_t val); + +/** + * @brief Data toggle set + * + * Configuration of current state of data toggling + * @param ep Endpoint number with the information about its direction + * @param op Operation to execute + */ +__STATIC_INLINE void nrf_usbd_dtoggle_set(uint8_t ep, nrf_usbd_dtoggle_t op); + +/** + * @brief Data toggle get + * + * Get the current state of data toggling + * @param ep Endpoint number to return the information about current data toggling + * @retval NRF_USBD_DTOGGLE_DATA0 Data toggle is DATA0 on selected endpoint + * @retval NRF_USBD_DTOGGLE_DATA1 Data toggle is DATA1 on selected endpoint + */ +__STATIC_INLINE nrf_usbd_dtoggle_t nrf_usbd_dtoggle_get(uint8_t ep); + +/** + * @brief Enable selected endpoint + * + * Enabled endpoint responds for the tokens on the USB bus + * + * @param ep Endpoint id to enable + */ +__STATIC_INLINE void nrf_usbd_ep_enable(uint8_t ep); + +/** + * @brief Disable selected endpoint + * + * Disabled endpoint does not respond for the tokens on the USB bus + * + * @param ep Endpoint id to disable + */ +__STATIC_INLINE void nrf_usbd_ep_disable(uint8_t ep); + +/** + * @brief Disable all endpoints + * + * Auxiliary function to simply disable all aviable endpoints. + * It lefts only EP0 IN and OUT enabled. + */ +__STATIC_INLINE void nrf_usbd_ep_all_disable(void); + +/** + * @brief Stall selected endpoint + * + * @param ep Endpoint identifier + * @note This function cannot be called on isochronous endpoint + */ +__STATIC_INLINE void nrf_usbd_ep_stall(uint8_t ep); + +/** + * @brief Unstall selected endpoint + * + * @param ep Endpoint identifier + * @note This function cannot be called on isochronous endpoint + */ +__STATIC_INLINE void nrf_usbd_ep_unstall(uint8_t ep); + +/** + * @brief Configure isochronous buffer splitting + * + * Configure isochronous buffer splitting between IN and OUT endpoints. + * + * @param split Required configuration + */ +__STATIC_INLINE void nrf_usbd_isosplit_set(nrf_usbd_isosplit_t split); + +/** + * @brief Get the isochronous buffer splitting configuration + * + * Get the current isochronous buffer splitting configuration. + * + * @return Current configuration + */ +__STATIC_INLINE nrf_usbd_isosplit_t nrf_usbd_isosplit_get(void); + +/** + * @brief Get current frame counter + * + * @return Current frame counter + */ +__STATIC_INLINE uint32_t nrf_usbd_framecntr_get(void); + +/** + * @brief Configure EasyDMA channel + * + * Configures EasyDMA for the transfer. + * + * @param ep Endpoint identifier (with direction) + * @param ptr Pointer to the data + * @param maxcnt Number of bytes to transfer + */ +__STATIC_INLINE void nrf_usbd_ep_easydma_set(uint8_t ep, uint32_t ptr, uint32_t maxcnt); + +/** + * @brief Get number of transferred bytes + * + * Get number of transferred bytes in the last transaction + * + * @param ep Endpoint identifier + * + * @return The content of the AMOUNT register + */ +__STATIC_INLINE uint32_t nrf_usbd_ep_amount_get(uint8_t ep); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +void nrf_usbd_enable(void) +{ +#ifdef NRF_FPGA_IMPLEMENTATION + *(volatile uint32_t *)0x400005F4 = 3; + __ISB(); + __DSB(); + *(volatile uint32_t *)0x400005F0 = 3; + __ISB(); + __DSB(); +#endif + + NRF_USBD->ENABLE = USBD_ENABLE_ENABLE_Enabled << USBD_ENABLE_ENABLE_Pos; + __ISB(); + __DSB(); +} + +void nrf_usbd_disable(void) +{ + NRF_USBD->ENABLE = USBD_ENABLE_ENABLE_Disabled << USBD_ENABLE_ENABLE_Pos; + __ISB(); + __DSB(); +} + +uint32_t nrf_usbd_eventcause_get(void) +{ + return NRF_USBD->EVENTCAUSE; +} + +void nrf_usbd_eventcause_clear(uint32_t flags) +{ + NRF_USBD->EVENTCAUSE = flags; + __ISB(); + __DSB(); +} + +uint32_t nrf_usbd_eventcause_get_and_clear(void) +{ + uint32_t ret; + ret = nrf_usbd_eventcause_get(); + nrf_usbd_eventcause_clear(ret); + __ISB(); + __DSB(); + return ret; +} + +nrf_usbd_busstate_t nrf_usbd_busstate_get(void) +{ + return (nrf_usbd_busstate_t)(NRF_USBD->BUSSTATE); +} + +uint32_t nrf_usbd_haltedep(uint8_t ep) +{ + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + if(NRF_USBD_EPIN_CHECK(ep)) + { + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->HALTED.EPIN)); + return NRF_USBD->HALTED.EPIN[epnr]; + } + else + { + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->HALTED.EPOUT)); + return NRF_USBD->HALTED.EPOUT[epnr]; + } +} + +bool nrf_usbd_ep_is_stall(uint8_t ep) +{ + if(NRF_USBD_EPISO_CHECK(ep)) + return false; + return USBD_HALTED_EPOUT_GETSTATUS_Halted == nrf_usbd_haltedep(ep); +} + +uint32_t nrf_usbd_epstatus_get(void) +{ + return NRF_USBD->EPSTATUS; +} + +void nrf_usbd_epstatus_clear(uint32_t flags) +{ + NRF_USBD->EPSTATUS = flags; + __ISB(); + __DSB(); +} + +uint32_t nrf_usbd_epstatus_get_and_clear(void) +{ + uint32_t ret; + ret = nrf_usbd_epstatus_get(); + nrf_usbd_epstatus_clear(ret); + return ret; +} + +uint32_t nrf_usbd_epdatastatus_get(void) +{ + return NRF_USBD->EPDATASTATUS; +} + +void nrf_usbd_epdatastatus_clear(uint32_t flags) +{ + NRF_USBD->EPDATASTATUS = flags; + __ISB(); + __DSB(); +} + +uint32_t nrf_usbd_epdatastatus_get_and_clear(void) +{ + uint32_t ret; + ret = nrf_usbd_epdatastatus_get(); + nrf_usbd_epdatastatus_clear(ret); + __ISB(); + __DSB(); + return ret; +} + +uint8_t nrf_usbd_setup_bmrequesttype_get(void) +{ + return (uint8_t)(NRF_USBD->BMREQUESTTYPE); +} + +uint8_t nrf_usbd_setup_brequest_get(void) +{ + return (uint8_t)(NRF_USBD->BREQUEST); +} + +uint16_t nrf_usbd_setup_wvalue_get(void) +{ + const uint16_t val = NRF_USBD->WVALUEL; + return (uint16_t)(val | ((NRF_USBD->WVALUEH) << 8)); +} + +uint16_t nrf_usbd_setup_windex_get(void) +{ + const uint16_t val = NRF_USBD->WINDEXL; + return (uint16_t)(val | ((NRF_USBD->WINDEXH) << 8)); +} + +uint16_t nrf_usbd_setup_wlength_get(void) +{ + const uint16_t val = NRF_USBD->WLENGTHL; + return (uint16_t)(val | ((NRF_USBD->WLENGTHH) << 8)); +} + +size_t nrf_usbd_epout_size_get(uint8_t ep) +{ + ASSERT(NRF_USBD_EPOUT_CHECK(ep)); + if(NRF_USBD_EPISO_CHECK(ep)) + { + ASSERT(NRF_USBD_EP_NR_GET(ep) == ARRAY_SIZE(NRF_USBD->SIZE.EPOUT)); /* Only single isochronous endpoint supported */ + return NRF_USBD->SIZE.ISOOUT; + } + + ASSERT(NRF_USBD_EP_NR_GET(ep) < ARRAY_SIZE(NRF_USBD->SIZE.EPOUT)); + return NRF_USBD->SIZE.EPOUT[NRF_USBD_EP_NR_GET(ep)]; +} + +void nrf_usbd_epout_clear(uint8_t ep) +{ + ASSERT(NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < ARRAY_SIZE(NRF_USBD->SIZE.EPOUT))); + NRF_USBD->SIZE.EPOUT[NRF_USBD_EP_NR_GET(ep)] = 0; + __ISB(); + __DSB(); +} + +void nrf_usbd_pullup_enable(void) +{ + NRF_USBD->USBPULLUP = USBD_USBPULLUP_CONNECT_Enabled << USBD_USBPULLUP_CONNECT_Pos; + __ISB(); + __DSB(); +} + +void nrf_usbd_pullup_disable(void) +{ + NRF_USBD->USBPULLUP = USBD_USBPULLUP_CONNECT_Disabled << USBD_USBPULLUP_CONNECT_Pos; + __ISB(); + __DSB(); +} + +bool nrf_usbd_pullup_check(void) +{ + return NRF_USBD->USBPULLUP == (USBD_USBPULLUP_CONNECT_Enabled << USBD_USBPULLUP_CONNECT_Pos); +} + +void nrf_usbd_dpdmvalue_set(nrf_usbd_dpdmvalue_t val) +{ + NRF_USBD->DPDMVALUE = ((uint32_t)val) << USBD_DPDMVALUE_STATE_Pos; +} + +void nrf_usbd_dtoggle_set(uint8_t ep, nrf_usbd_dtoggle_t op) +{ + NRF_USBD->DTOGGLE = ep | (op << USBD_DTOGGLE_VALUE_Pos); + __ISB(); + __DSB(); +} + +nrf_usbd_dtoggle_t nrf_usbd_dtoggle_get(uint8_t ep) +{ + uint32_t retval; + /* Select the endpoint to read */ + nrf_usbd_dtoggle_set(ep, NRF_USBD_DTOGGLE_NOP); + retval = ((NRF_USBD->DTOGGLE) & USBD_DTOGGLE_VALUE_Msk) >> USBD_DTOGGLE_VALUE_Pos; + return (nrf_usbd_dtoggle_t)retval; +} + +void nrf_usbd_ep_enable(uint8_t ep) +{ + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + ASSERT(epnr <= USBD_EPINEN_ISOIN_Pos); + + if(NRF_USBD_EPIN_CHECK(ep)) + { + NRF_USBD->EPINEN |= 1UL<EPOUTEN |= 1UL<EPINEN &= ~(1UL<EPOUTEN &= ~(1UL<EPINEN = USBD_EPINEN_IN0_Enable << USBD_EPINEN_IN0_Pos; + NRF_USBD->EPOUTEN = USBD_EPOUTEN_OUT0_Enable << USBD_EPOUTEN_OUT0_Pos; + __ISB(); + __DSB(); +} + +void nrf_usbd_ep_stall(uint8_t ep) +{ + ASSERT(!NRF_USBD_EPISO_CHECK(ep)); + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_Stall << USBD_EPSTALL_STALL_Pos) | ep; + __ISB(); + __DSB(); +} + +void nrf_usbd_ep_unstall(uint8_t ep) +{ + ASSERT(!NRF_USBD_EPISO_CHECK(ep)); + NRF_USBD->EPSTALL = (USBD_EPSTALL_STALL_UnStall << USBD_EPSTALL_STALL_Pos) | ep; + __ISB(); + __DSB(); +} + +void nrf_usbd_isosplit_set(nrf_usbd_isosplit_t split) +{ + NRF_USBD->ISOSPLIT = split << USBD_ISOSPLIT_SPLIT_Pos; +} + +nrf_usbd_isosplit_t nrf_usbd_isosplit_get(void) +{ + return (nrf_usbd_isosplit_t)(((NRF_USBD->ISOSPLIT) & USBD_ISOSPLIT_SPLIT_Msk) >> USBD_ISOSPLIT_SPLIT_Pos); +} + +uint32_t nrf_usbd_framecntr_get(void) +{ + return NRF_USBD->FRAMECNTR; +} + +void nrf_usbd_ep_easydma_set(uint8_t ep, uint32_t ptr, uint32_t maxcnt) +{ + if(NRF_USBD_EPIN_CHECK(ep)) + { + if(NRF_USBD_EPISO_CHECK(ep)) + { + NRF_USBD->ISOIN.PTR = ptr; + NRF_USBD->ISOIN.MAXCNT = maxcnt; + } + else + { + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPIN)); + NRF_USBD->EPIN[epnr].PTR = ptr; + NRF_USBD->EPIN[epnr].MAXCNT = maxcnt; + } + } + else + { + if(NRF_USBD_EPISO_CHECK(ep)) + { + NRF_USBD->ISOOUT.PTR = ptr; + NRF_USBD->ISOOUT.MAXCNT = maxcnt; + } + else + { + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPOUT)); + NRF_USBD->EPOUT[epnr].PTR = ptr; + NRF_USBD->EPOUT[epnr].MAXCNT = maxcnt; + } + } +} + +uint32_t nrf_usbd_ep_amount_get(uint8_t ep) +{ + uint32_t ret; + + if(NRF_USBD_EPIN_CHECK(ep)) + { + if(NRF_USBD_EPISO_CHECK(ep)) + { + ret = NRF_USBD->ISOIN.AMOUNT; + } + else + { + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPOUT)); + ret = NRF_USBD->EPIN[epnr].AMOUNT; + } + } + else + { + if(NRF_USBD_EPISO_CHECK(ep)) + { + ret = NRF_USBD->ISOOUT.AMOUNT; + } + else + { + uint8_t epnr = NRF_USBD_EP_NR_GET(ep); + ASSERT(epnr < ARRAY_SIZE(NRF_USBD->EPOUT)); + ret = NRF_USBD->EPOUT[epnr].AMOUNT; + } + } + + return ret; +} + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + +/** @} */ +#endif /* NRF_USBD_H__ */ diff --git a/components/drivers_nrf/hal/nrf_wdt.h b/components/drivers_nrf/hal/nrf_wdt.h index f797af5..faac5ba 100644 --- a/components/drivers_nrf/hal/nrf_wdt.h +++ b/components/drivers_nrf/hal/nrf_wdt.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -27,6 +55,10 @@ #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + #define NRF_WDT_CHANNEL_NUMBER 0x8UL #define NRF_WDT_RR_VALUE 0x6E524635UL /* Fixed value, shouldn't be modified.*/ @@ -122,6 +154,10 @@ __STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task) __STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event) { *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR; +#if __CORTEX_M == 0x04 + volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)); + (void)dummy; +#endif } @@ -294,6 +330,11 @@ __STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_registe } + +#ifdef __cplusplus +} +#endif + #endif /** @} */ diff --git a/components/drivers_nrf/i2s/nrf_drv_i2s.c b/components/drivers_nrf/i2s/nrf_drv_i2s.c new file mode 100644 index 0000000..657f6df --- /dev/null +++ b/components/drivers_nrf/i2s/nrf_drv_i2s.c @@ -0,0 +1,438 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(I2S) +#include "nrf_drv_i2s.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "nrf_assert.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "I2S" + +#if I2S_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL I2S_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR I2S_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR I2S_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_I2S_EVENT_RXPTRUPD ? "NRF_I2S_EVENT_RXPTRUPD" : \ + (event == NRF_I2S_EVENT_TXPTRUPD ? "NRF_I2S_EVENT_TXPTRUPD" : \ + (event == NRF_I2S_EVENT_STOPPED ? "NRF_I2S_EVENT_STOPPED" : "UNKNOWN EVENT"))) +#else //I2S_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //I2S_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +#define MODULE_INITIALIZED (m_cb.state == NRF_DRV_STATE_INITIALIZED) /**< Macro designating whether the module has been initialized properly. */ + +// Control block - driver instance local data. +typedef struct +{ + nrf_drv_i2s_data_handler_t handler; + nrf_drv_state_t state; + + bool synchronized_mode : 1; + bool rx_ready : 1; + bool tx_ready : 1; + bool just_started : 1; + uint16_t buffer_half_size; + uint32_t * p_rx_buffer; + uint32_t * p_tx_buffer; +} i2s_control_block_t; +static i2s_control_block_t m_cb; + + +static nrf_drv_i2s_config_t const m_default_config = NRF_DRV_I2S_DEFAULT_CONFIG; + + +static void configure_pins(nrf_drv_i2s_config_t const * p_config) +{ + uint32_t mck_pin, sdout_pin, sdin_pin; + + // Configure pins used by the peripheral: + + // - SCK and LRCK (required) - depending on the mode of operation these + // pins are configured as outputs (in Master mode) or inputs (in Slave + // mode). + if (p_config->mode == NRF_I2S_MODE_MASTER) + { + nrf_gpio_cfg_output(p_config->sck_pin); + nrf_gpio_cfg_output(p_config->lrck_pin); + } + else + { + nrf_gpio_cfg_input(p_config->sck_pin, NRF_GPIO_PIN_NOPULL); + nrf_gpio_cfg_input(p_config->lrck_pin, NRF_GPIO_PIN_NOPULL); + } + + // - MCK (optional) - always output, + if (p_config->mck_pin != NRF_DRV_I2S_PIN_NOT_USED) + { + mck_pin = p_config->mck_pin; + nrf_gpio_cfg_output(mck_pin); + } + else + { + mck_pin = NRF_I2S_PIN_NOT_CONNECTED; + } + + // - SDOUT (optional) - always output, + if (p_config->sdout_pin != NRF_DRV_I2S_PIN_NOT_USED) + { + sdout_pin = p_config->sdout_pin; + nrf_gpio_cfg_output(sdout_pin); + } + else + { + sdout_pin = NRF_I2S_PIN_NOT_CONNECTED; + } + + // - SDIN (optional) - always input. + if (p_config->sdin_pin != NRF_DRV_I2S_PIN_NOT_USED) + { + sdin_pin = p_config->sdin_pin; + nrf_gpio_cfg_input(sdin_pin, NRF_GPIO_PIN_NOPULL); + } + else + { + sdin_pin = NRF_I2S_PIN_NOT_CONNECTED; + } + + nrf_i2s_pins_set(NRF_I2S, p_config->sck_pin, p_config->lrck_pin, + mck_pin, sdout_pin, sdin_pin); +} + + +ret_code_t nrf_drv_i2s_init(nrf_drv_i2s_config_t const * p_config, + nrf_drv_i2s_data_handler_t handler) +{ + ASSERT(handler); + + ret_code_t err_code; + + if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + if (p_config == NULL) + { + p_config = &m_default_config; + } + + if (!nrf_i2s_configure(NRF_I2S, p_config->mode, + p_config->format, + p_config->alignment, + p_config->sample_width, + p_config->channels, + p_config->mck_setup, + p_config->ratio)) + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + configure_pins(p_config); + + m_cb.handler = handler; + + nrf_drv_common_irq_enable(I2S_IRQn, p_config->irq_priority); + + m_cb.state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +void nrf_drv_i2s_uninit(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_drv_i2s_stop(); + + nrf_drv_common_irq_disable(I2S_IRQn); + + m_cb.state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Initialized.\r\n"); +} + + +ret_code_t nrf_drv_i2s_start(uint32_t * p_rx_buffer, + uint32_t * p_tx_buffer, + uint16_t buffer_size, + uint8_t flags) +{ + ASSERT((p_rx_buffer != NULL) || (p_tx_buffer != NULL)); + + uint16_t buffer_half_size = buffer_size / 2; + ASSERT(buffer_half_size != 0); + + VERIFY_MODULE_INITIALIZED(); + + ret_code_t err_code; + + if ((p_rx_buffer != NULL) && !nrf_drv_is_in_RAM(p_rx_buffer)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + if ((p_tx_buffer != NULL) && !nrf_drv_is_in_RAM(p_tx_buffer)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + // Initially we set up the peripheral to use the first half of each buffer, + // then in 'I2S_IRQHandler' we will switch to the second half. + nrf_i2s_transfer_set(NRF_I2S, buffer_half_size, p_rx_buffer, p_tx_buffer); + + m_cb.p_rx_buffer = p_rx_buffer; + m_cb.p_tx_buffer = p_tx_buffer; + m_cb.buffer_half_size = buffer_half_size; + m_cb.just_started = true; + + if ((flags & NRF_DRV_I2S_FLAG_SYNCHRONIZED_MODE) && + // [synchronized mode makes sense only when both RX and TX are enabled] + (m_cb.p_rx_buffer != NULL) && (m_cb.p_tx_buffer != NULL)) + { + m_cb.synchronized_mode = true; + m_cb.rx_ready = false; + m_cb.tx_ready = false; + } + else + { + m_cb.synchronized_mode = false; + } + + nrf_i2s_enable(NRF_I2S); + + m_cb.state = NRF_DRV_STATE_POWERED_ON; + + if (m_cb.p_tx_buffer != NULL) + { + // Get from the application the first portion of data to be sent - we + // need to have it in the transmit buffer before we start the transfer. + // Unless the synchronized mode is active. In this mode we must wait + // with this until the first portion of data is received, so here we + // just make sure that there will be silence on the SDOUT line prior + // to that moment. + if (m_cb.synchronized_mode) + { + memset(m_cb.p_tx_buffer, 0, buffer_size); + } + else + { + m_cb.handler(NULL, m_cb.p_tx_buffer, m_cb.buffer_half_size); + } + } + + nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_RXPTRUPD); + nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_TXPTRUPD); + nrf_i2s_int_enable(NRF_I2S, + NRF_I2S_INT_RXPTRUPD_MASK | NRF_I2S_INT_TXPTRUPD_MASK); + nrf_i2s_task_trigger(NRF_I2S, NRF_I2S_TASK_START); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +void nrf_drv_i2s_stop(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + // First disable interrupts, then trigger the STOP task, so no spurious + // RXPTRUPD and TXPTRUPD events (see FTPAN-55) will be processed. + nrf_i2s_int_disable(NRF_I2S, + NRF_I2S_INT_RXPTRUPD_MASK | NRF_I2S_INT_TXPTRUPD_MASK); + + nrf_i2s_task_trigger(NRF_I2S, NRF_I2S_TASK_STOP); + + nrf_i2s_disable(NRF_I2S); + + m_cb.state = NRF_DRV_STATE_INITIALIZED; + + NRF_LOG_INFO("Disabled."); +} + + +void I2S_IRQHandler(void) +{ + uint32_t * p_data_received = NULL; + uint32_t * p_data_to_send = NULL; + + if (nrf_i2s_event_check(NRF_I2S, NRF_I2S_EVENT_TXPTRUPD)) + { + nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_TXPTRUPD); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_I2S_EVENT_TXPTRUPD)); + + // If transmission is not enabled, but for some reason the TXPTRUPD + // event has been generated, just ignore it. + if (m_cb.p_tx_buffer != NULL) + { + uint32_t * p_tx_buffer_next; + if (nrf_i2s_tx_buffer_get(NRF_I2S) == m_cb.p_tx_buffer) + { + p_tx_buffer_next = m_cb.p_tx_buffer + m_cb.buffer_half_size; + } + else + { + p_tx_buffer_next = m_cb.p_tx_buffer; + } + nrf_i2s_tx_buffer_set(NRF_I2S, p_tx_buffer_next); + + m_cb.tx_ready = true; + + // Now the part of the buffer that we've configured as "next" should + // be filled by the application with proper data to be sent; + // the peripheral is sending data from the other part of the buffer + // (but it will finish soon...). + p_data_to_send = p_tx_buffer_next; + + } + } + + if (nrf_i2s_event_check(NRF_I2S, NRF_I2S_EVENT_RXPTRUPD)) + { + nrf_i2s_event_clear(NRF_I2S, NRF_I2S_EVENT_RXPTRUPD); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_I2S_EVENT_RXPTRUPD)); + + // If reception is not enabled, but for some reason the RXPTRUPD event + // has been generated, just ignore it. + if (m_cb.p_rx_buffer != NULL) + { + uint32_t * p_rx_buffer_next; + if (nrf_i2s_rx_buffer_get(NRF_I2S) == m_cb.p_rx_buffer) + { + p_rx_buffer_next = m_cb.p_rx_buffer + m_cb.buffer_half_size; + } + else + { + p_rx_buffer_next = m_cb.p_rx_buffer; + } + nrf_i2s_rx_buffer_set(NRF_I2S, p_rx_buffer_next); + + m_cb.rx_ready = true; + + // The RXPTRUPD event is generated for the first time right after + // the transfer is started. Since there is no data received yet at + // this point we only update the buffer pointer (it is done above), + // there is no callback to the application. + // [for synchronized mode this has to be handled differently - + // see below] + if (m_cb.just_started && !m_cb.synchronized_mode) + { + m_cb.just_started = false; + } + else + { + // The RXPTRUPD event indicates that from now on the peripheral + // will be filling the part of the buffer that was pointed at + // the time the event has been generated, hence now we can let + // the application process the data stored in the other part of + // the buffer - the one that we've just set to be filled next. + p_data_received = p_rx_buffer_next; + } + } + } + + // Call the data handler passing received data to the application and/or + // requesting data to be sent. + if (!m_cb.synchronized_mode) + { + if ((p_data_received != NULL) || (p_data_to_send != NULL)) + { + if (p_data_received != NULL) + { + NRF_LOG_DEBUG("Rx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_data_received, + m_cb.buffer_half_size * sizeof(p_data_received)); + } + m_cb.handler(p_data_received, p_data_to_send, + m_cb.buffer_half_size); + if (p_data_to_send != NULL) + { + NRF_LOG_DEBUG("Tx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_data_to_send, + m_cb.buffer_half_size * sizeof(p_data_to_send)); + } + } + } + // In the synchronized mode wait until the events for both RX and TX occur. + // And ignore the initial occurrences of these events, since they only + // indicate that the transfer has started - no data is received yet at + // that moment, so we have got nothing to pass to the application. + else + { + if (m_cb.rx_ready && m_cb.tx_ready) + { + m_cb.rx_ready = false; + m_cb.tx_ready = false; + + if (m_cb.just_started) + { + m_cb.just_started = false; + } + else + { + NRF_LOG_DEBUG("Rx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)nrf_i2s_rx_buffer_get(NRF_I2S), + m_cb.buffer_half_size * sizeof(p_data_to_send)); + m_cb.handler(nrf_i2s_rx_buffer_get(NRF_I2S), + nrf_i2s_tx_buffer_get(NRF_I2S), + m_cb.buffer_half_size); + NRF_LOG_DEBUG("Tx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)nrf_i2s_tx_buffer_get(NRF_I2S), + m_cb.buffer_half_size * sizeof(p_data_to_send)); + } + } + } +} +#endif //NRF_MODULE_ENABLED(I2S) diff --git a/components/drivers_nrf/i2s/nrf_drv_i2s.h b/components/drivers_nrf/i2s/nrf_drv_i2s.h new file mode 100644 index 0000000..035fa73 --- /dev/null +++ b/components/drivers_nrf/i2s/nrf_drv_i2s.h @@ -0,0 +1,256 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * @addtogroup nrf_i2s I2S HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52 Inter-IC Sound (I2S) interface APIs. + * + * @defgroup nrf_drv_i2s I2S driver + * @{ + * @ingroup nrf_i2s + * @brief @tagAPI52 Inter-IC Sound (I2S) interface driver. + */ + + +#ifndef NRF_DRV_I2S_H__ +#define NRF_DRV_I2S_H__ + +#include "nordic_common.h" +#include "sdk_config.h" +#include "nrf_i2s.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @brief This value can be provided instead of a pin number for the signals + * SDOUT, SDIN, and MCK to specify that a given signal is not used + * and therefore does not need to be connected to a pin. + */ +#define NRF_DRV_I2S_PIN_NOT_USED 0xFF + +/** + * @brief Flag indicating that calls to the data handler for RX and TX should + * be synchronized, thus always combined into one call. + * + * Use this flag when calling @ref nrf_drv_i2s_start to force a common call + * to the @ref nrf_drv_i2s_data_handler_t "data handler" for RX and TX data. + * This is useful, for example, when received data should be processed and + * then be sent back. Obviously, this flag is only applicable when both + * directions (RX and TX) are enabled. + */ +#define NRF_DRV_I2S_FLAG_SYNCHRONIZED_MODE 0x01 + +/** + * @brief I2S driver configuration structure. + */ +typedef struct +{ + uint8_t sck_pin; ///< SCK pin number. + uint8_t lrck_pin; ///< LRCK pin number. + uint8_t mck_pin; ///< MCK pin number. + /**< Optional. Use @ref NRF_DRV_I2S_PIN_NOT_USED + * if this signal is not needed. */ + uint8_t sdout_pin; ///< SDOUT pin number. + /**< Optional. Use @ref NRF_DRV_I2S_PIN_NOT_USED + * if this signal is not needed. */ + uint8_t sdin_pin; ///< SDIN pin number. + /**< Optional. Use @ref NRF_DRV_I2S_PIN_NOT_USED + * if this signal is not needed. */ + uint8_t irq_priority; ///< Interrupt priority. + + nrf_i2s_mode_t mode; ///< Mode of operation. + nrf_i2s_format_t format; ///< Frame format. + nrf_i2s_align_t alignment; ///< Alignment of sample within a frame. + nrf_i2s_swidth_t sample_width; ///< Sample width. + nrf_i2s_channels_t channels; ///< Enabled channels. + nrf_i2s_mck_t mck_setup; ///< Master clock setup. + nrf_i2s_ratio_t ratio; ///< MCK/LRCK ratio. +} nrf_drv_i2s_config_t; + +/** + * @brief I2S driver default configuration. + */ +#define NRF_DRV_I2S_DEFAULT_CONFIG \ +{ \ + .sck_pin = I2S_CONFIG_SCK_PIN, \ + .lrck_pin = I2S_CONFIG_LRCK_PIN, \ + .mck_pin = I2S_CONFIG_MCK_PIN, \ + .sdout_pin = I2S_CONFIG_SDOUT_PIN, \ + .sdin_pin = I2S_CONFIG_SDIN_PIN, \ + .irq_priority = I2S_CONFIG_IRQ_PRIORITY, \ + .mode = (nrf_i2s_mode_t)I2S_CONFIG_MASTER, \ + .format = (nrf_i2s_format_t)I2S_CONFIG_FORMAT, \ + .alignment = (nrf_i2s_align_t)I2S_CONFIG_ALIGN, \ + .sample_width = (nrf_i2s_swidth_t)I2S_CONFIG_SWIDTH, \ + .channels = (nrf_i2s_channels_t)I2S_CONFIG_CHANNELS, \ + .mck_setup = (nrf_i2s_mck_t)I2S_CONFIG_MCK_SETUP, \ + .ratio = (nrf_i2s_ratio_t)I2S_CONFIG_RATIO, \ +} + +/** + * @brief I2S driver data handler type. + * + * A data handling function of this type must be specified during initialization + * of the driver. The driver will call this function when a new portion of data + * is received or a new portion of data should be prepared for transmission. + * The first case is indicated by a non-NULL value in the @p p_data_received + * parameter (which points to the memory containing the received data). + * Similarly, the second case is indicated by a non-NULL value in the + * @p p_data_to_send parameter (which points to where the data to be transmitted + * should be placed). + * + * @note The two cases mentioned above may be indicated separately or combined + * into one call (depending on the environment in which the driver is + * used). Therefore, both parameters should be checked and handled + * properly in every call. @ref NRF_DRV_I2S_FLAG_SYNCHRONIZED_MODE + * "Synchronized mode" can be used to always combine these indications. + * + * @param[in] p_data_received Pointer to the buffer with received data, + * or NULL if the handler is called to prepare + * transmission only. + * @param[out] p_data_to_send Pointer to the buffer where data to be sent + * should be written, or NULL if the handler is + * called for received data only. + * @param[in] number_of_words Length of data received and/or to be written + * (in 32-bit words). This value is always equal to + * half the size of the buffers set by the call + * to the @ref nrf_drv_i2s_start function. + */ +typedef void (* nrf_drv_i2s_data_handler_t)(uint32_t const * p_data_received, + uint32_t * p_data_to_send, + uint16_t number_of_words); + + +/** + * @brief Function for initializing the I2S driver. + * + * @param[in] p_config Pointer to the structure with initial configuration. + * If NULL, the default configuration is used. + * @param[in] handler Data handler provided by the user. Must not be NULL. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver was already initialized. + * @retval NRF_ERROR_INVALID_PARAM If the requested combination of configuration + * options is not allowed by the I2S peripheral. + */ +ret_code_t nrf_drv_i2s_init(nrf_drv_i2s_config_t const * p_config, + nrf_drv_i2s_data_handler_t handler); + +/** + * @brief Function for uninitializing the I2S driver. + */ +void nrf_drv_i2s_uninit(void); + +/** + * @brief Function for starting the continuous I2S transfer. + * + * The I2S data transfer can be performed in one of three modes: RX (reception) + * only, TX (transmission) only, or in both directions simultaneously. + * The mode is selected by specifying a proper buffer for a given direction + * in the call to this function or by passing NULL instead if this direction + * should be disabled. + * + * The length of the buffer (which is a common value for RX and TX if both + * directions are enabled) is specified in 32-bit words. One 32-bit memory + * word can either contain four 8-bit samples, two 16-bit samples, or one + * right-aligned 24-bit sample sign-extended to a 32-bit value. + * For a detailed memory mapping for different supported configurations, + * see the @linkProductSpecification52. + * + * The provided buffers are logically divided into two parts of equal size. + * One of them is in use by the peripheral (for storing received data or for + * getting data to be transmitted, respectively). The other part is provided + * to the application via a call to the defined @ref nrf_drv_i2s_data_handler_t + * "data handling function", so that the application can process the received + * data or prepare the next portion of data to be sent. The two parts are + * swapped every time @p buffer_size/2 data words are received or transmitted. + * + * Additional options are provided using the @p flags parameter: + * - @ref NRF_DRV_I2S_FLAG_SYNCHRONIZED_MODE - the calls to data handler should + * be done in a synchronized manner (one common call for TX and RX). + * Applicable only when both RX and TX are enabled. + * + * @attention All data exchange is done in the data handler only. In particular, + * no data should be written to the transmit buffer before calling + * this function (a proper call to the data handler to get the first + * portion of data to be sent will be done before the actual transfer + * starts). + * + * @note Peripherals using EasyDMA (like I2S) require the transfer buffers + * to be placed in the Data RAM region. If this condition is not met, + * this function will fail with the error code NRF_ERROR_INVALID_ADDR. + * + * @param[in] p_rx_buffer Pointer to the receive buffer. + * Pass NULL if reception is not required. + * @param[in] p_tx_buffer Pointer to the transmit buffer. + * Pass NULL if transmission is not required. + * @param[in] buffer_size Size of the buffers (in 32-bit words). + * The size must be an even number greater than 0. + * @param[in] flags Transfer options (0 for default settings). + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_STATE If a transfer was already started or + * the driver has not been initialized. + * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed + * in the Data RAM region. + */ +ret_code_t nrf_drv_i2s_start(uint32_t * p_rx_buffer, + uint32_t * p_tx_buffer, + uint16_t buffer_size, + uint8_t flags); + +/** + * @brief Function for stopping the I2S transfer. + */ +void nrf_drv_i2s_stop(void); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_I2S_H__ + +/** @} */ diff --git a/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.c b/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.c index a7bdaa2..ce37da8 100644 --- a/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.c +++ b/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.c @@ -1,17 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(LPCOMP) #include "nrf_drv_lpcomp.h" - #include "nrf_assert.h" #include "nrf_error.h" #include "nrf_soc.h" @@ -21,23 +49,49 @@ #include #include +#define NRF_LOG_MODULE_NAME "LPCOMP" + +#if LPCOMP_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL LPCOMP_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR LPCOMP_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR LPCOMP_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_LPCOMP_EVENT_READY ? "NRF_LPCOMP_EVENT_READY" : \ + (event == NRF_LPCOMP_EVENT_DOWN ? "NRF_LPCOMP_EVENT_DOWN" : \ + (event == NRF_LPCOMP_EVENT_UP ? "NRF_LPCOMP_EVENT_UP" : \ + (event == NRF_LPCOMP_EVENT_CROSS ? "NRF_LPCOMP_EVENT_CROSS" : "UNKNOWN EVENT")))) +#else //LPCOMP_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //LPCOMP_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + static lpcomp_events_handler_t m_lpcomp_events_handler = NULL; static nrf_drv_state_t m_state = NRF_DRV_STATE_UNINITIALIZED; -static const nrf_drv_lpcomp_config_t m_default_config = NRF_DRV_LPCONF_DEFAULT_CONFIG; +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME irq_handler_for_lpcomp + #define IRQ_HANDLER static void IRQ_HANDLER_NAME(void) + + IRQ_HANDLER; +#else + #define IRQ_HANDLER void LPCOMP_IRQHandler(void) +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) static void lpcomp_execute_handler(nrf_lpcomp_event_t event, uint32_t event_mask) { if ( nrf_lpcomp_event_check(event) && nrf_lpcomp_int_enable_check(event_mask) ) { nrf_lpcomp_event_clear(event); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(event)); m_lpcomp_events_handler(event); } } -void LPCOMP_IRQHandler(void) +IRQ_HANDLER { lpcomp_execute_handler(NRF_LPCOMP_EVENT_READY, LPCOMP_INTENSET_READY_Msk); lpcomp_execute_handler(NRF_LPCOMP_EVENT_DOWN, LPCOMP_INTENSET_DOWN_Msk); @@ -49,15 +103,24 @@ void LPCOMP_IRQHandler(void) ret_code_t nrf_drv_lpcomp_init(const nrf_drv_lpcomp_config_t * p_config, lpcomp_events_handler_t events_handler) { + ASSERT(p_config); + ret_code_t err_code; + if (m_state != NRF_DRV_STATE_UNINITIALIZED) { // LPCOMP driver is already initialized - return NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } - if (p_config == NULL) +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(NRF_LPCOMP, IRQ_HANDLER_NAME) != NRF_SUCCESS) { - p_config = &m_default_config; + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } +#endif nrf_lpcomp_configure(&(p_config->hal) ); @@ -67,7 +130,9 @@ ret_code_t nrf_drv_lpcomp_init(const nrf_drv_lpcomp_config_t * p_config, } else { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } nrf_lpcomp_input_select(p_config->input); @@ -95,7 +160,9 @@ ret_code_t nrf_drv_lpcomp_init(const nrf_drv_lpcomp_config_t * p_config, m_state = NRF_DRV_STATE_INITIALIZED; - return NRF_SUCCESS; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } @@ -104,8 +171,12 @@ void nrf_drv_lpcomp_uninit(void) ASSERT(m_state != NRF_DRV_STATE_UNINITIALIZED); nrf_drv_common_irq_disable(LPCOMP_IRQn); nrf_drv_lpcomp_disable(); +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(NRF_LPCOMP); +#endif m_state = NRF_DRV_STATE_UNINITIALIZED; m_lpcomp_events_handler = NULL; + NRF_LOG_INFO("Uninitialized.\r\n"); } void nrf_drv_lpcomp_enable(void) @@ -114,6 +185,7 @@ void nrf_drv_lpcomp_enable(void) nrf_lpcomp_enable(); nrf_lpcomp_task_trigger(NRF_LPCOMP_TASK_START); m_state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled.\r\n"); } void nrf_drv_lpcomp_disable(void) @@ -122,6 +194,7 @@ void nrf_drv_lpcomp_disable(void) nrf_lpcomp_disable(); nrf_lpcomp_task_trigger(NRF_LPCOMP_TASK_STOP); m_state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Disabled.\r\n"); } void nrf_drv_lpcomp_event_handler_register(lpcomp_events_handler_t lpcomp_events_handler) @@ -129,4 +202,4 @@ void nrf_drv_lpcomp_event_handler_register(lpcomp_events_handler_t lpcomp_events m_lpcomp_events_handler = lpcomp_events_handler; } - +#endif //NRF_MODULE_ENABLED(LPCOMP) diff --git a/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.h b/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.h index 65c1377..6b56129 100644 --- a/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.h +++ b/components/drivers_nrf/lpcomp/nrf_drv_lpcomp.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_LPCOMP_H__ @@ -16,18 +44,23 @@ #include "nrf_lpcomp.h" #include "sdk_errors.h" #include "nrf_drv_common.h" -#include "nrf_drv_config.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + /** * @addtogroup nrf_lpcomp LPCOMP HAL and driver * @ingroup nrf_drivers * @brief Low Power Comparator (LPCOMP) APIs. - * @details The LPCOMP HAL provides basic APIs for accessing the registers of Low Power Comparator. + * @details The LPCOMP HAL provides basic APIs for accessing the registers of Low Power Comparator. * The LPCOMP driver provides APIs on a higher level. * - * @defgroup nrf_drivers_lpcomp LPCOMP driver + * @defgroup nrf_drv_lpcomp LPCOMP driver * @{ * @ingroup nrf_lpcomp - * @brief Low Power Comparator (LPCOMP) driver. + * @brief Low Power Comparator (LPCOMP) driver. */ /**@brief LPCOMP event handler function type. @@ -41,27 +74,37 @@ typedef struct { nrf_lpcomp_config_t hal; /**< LPCOMP HAL configuration. */ nrf_lpcomp_input_t input; /**< Input to be monitored. */ - uint8_t interrupt_priority; /**< LPCOMP interrupt priority */ + uint8_t interrupt_priority; /**< LPCOMP interrupt priority. */ } nrf_drv_lpcomp_config_t; -/** LPCOMP driver default configuration, including the LPCOMP HAL configuration. */ -#define NRF_DRV_LPCONF_DEFAULT_CONFIG \ - { \ - .hal = {LPCOMP_CONFIG_REFERENCE , LPCOMP_CONFIG_DETECTION}, \ - .input = LPCOMP_CONFIG_INPUT, \ - .interrupt_priority = LPCOMP_CONFIG_IRQ_PRIORITY \ +/** @brief LPCOMP driver default configuration including the LPCOMP HAL configuration. */ +#ifdef NRF52_SERIES +#define NRF_DRV_LPCOMP_DEFAULT_CONFIG \ + { \ + .hal = {(nrf_lpcomp_ref_t)LPCOMP_CONFIG_REFERENCE , (nrf_lpcomp_detect_t)LPCOMP_CONFIG_DETECTION, \ + (nrf_lpcomp_hysteresis_t)LPCOMP_CONFIG_HYST}, \ + .input = (nrf_lpcomp_input_t)LPCOMP_CONFIG_INPUT, \ + .interrupt_priority = LPCOMP_CONFIG_IRQ_PRIORITY \ } +#else +#define NRF_DRV_LPCOMP_DEFAULT_CONFIG \ + { \ + .hal = {(nrf_lpcomp_ref_t)LPCOMP_CONFIG_REFERENCE , (nrf_lpcomp_detect_t)LPCOMP_CONFIG_DETECTION}, \ + .input = (nrf_lpcomp_input_t)LPCOMP_CONFIG_INPUT, \ + .interrupt_priority = LPCOMP_CONFIG_IRQ_PRIORITY \ + } +#endif /** - * @brief Function for initializing the LCOMP driver. - * - * This function initializes the LPCOMP driver, but does not enable the peripheral nor any interrupts. - * To start the driver, the function nrf_drv_lpcomp_enable() should be executed after initialization. + * @brief Function for initializing the LPCOMP driver. + * + * This function initializes the LPCOMP driver, but does not enable the peripheral or any interrupts. + * To start the driver, call the function nrf_drv_lpcomp_enable() after initialization. * - * @note Driver will be initialized to default settings if configuration struct is not provided. + * If no configuration structure is provided, the driver is initialized with the default settings. * - * @param[in] p_config Initial configuration. Default configuration used if NULL. - * @param[in] events_handler Handler function + * @param[in] p_config Initial configuration. If NULL, the default configuration is used. + * @param[in] events_handler Handler function. * @retval NRF_ERROR_INVALID_PARAM If the configuration is invalid. * @retval NRF_ERROR_INVALID_STATE If the driver has already been initialized. */ @@ -72,8 +115,8 @@ ret_code_t nrf_drv_lpcomp_init(const nrf_drv_lpcomp_config_t * p_config, /** * @brief Function for uninitializing the LCOMP driver. * - * This function uninitializes the LCOMP driver. The LPCOMP peripheral and - * its interrupts are disabled and local variables are cleaned. After this call, you must + * This function uninitializes the LPCOMP driver. The LPCOMP peripheral and + * its interrupts are disabled, and local variables are cleaned. After this call, you must * initialize the driver again by calling nrf_drv_lpcomp_init() if you want to use it. * * @sa nrf_drv_lpcomp_disable() @@ -103,4 +146,9 @@ void nrf_drv_lpcomp_disable(void); *@} **/ + +#ifdef __cplusplus +} +#endif + #endif /* NRF_DRV_LPCOMP_H__ */ diff --git a/components/drivers_nrf/nrf_soc_nosd/nrf_error.h b/components/drivers_nrf/nrf_soc_nosd/nrf_error.h index 1174ac2..9216d3e 100644 --- a/components/drivers_nrf/nrf_soc_nosd/nrf_error.h +++ b/components/drivers_nrf/nrf_soc_nosd/nrf_error.h @@ -1,17 +1,52 @@ -/* - * Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /* Header guard */ #ifndef NRF_ERROR_H__ #define NRF_ERROR_H__ -/// @cond Make doxygen skip this file +#ifdef __cplusplus +extern "C" { +#endif + +/// @cond Make doxygen skip this file /** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions * @{ */ @@ -40,9 +75,14 @@ #define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address #define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy + +#ifdef __cplusplus +} +#endif + #endif // NRF_ERROR_H__ -/// @endcond +/// @endcond /** @} */ diff --git a/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c b/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c new file mode 100644 index 0000000..eddcd0b --- /dev/null +++ b/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "nrf_soc.h" +#include "nrf_error.h" + +static uint8_t m_in_critical_region = 0; + +uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) +{ + NVIC_EnableIRQ(IRQn); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) +{ + NVIC_DisableIRQ(IRQn); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) +{ + if (p_pending_irq != NULL) + { + *p_pending_irq = NVIC_GetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + return NRF_ERROR_NULL; +} + +uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC_SetPendingIRQ(IRQn); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC_ClearPendingIRQ(IRQn); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + NVIC_SetPriority(IRQn, priority); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority) +{ + if (p_priority != NULL) + { + *p_priority = NVIC_GetPriority(IRQn); + return NRF_SUCCESS; + } + + return NRF_ERROR_NULL; +} + +uint32_t sd_nvic_SystemReset(void) +{ + NVIC_SystemReset(); + return NRF_SUCCESS; +} + +uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) +{ + __disable_irq(); + + *p_is_nested_critical_region = (m_in_critical_region != 0); + m_in_critical_region++; + + return NRF_SUCCESS; +} + +uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) +{ + m_in_critical_region--; + + if (is_nested_critical_region == 0) + { + m_in_critical_region = 0; + __enable_irq(); + } + return NRF_SUCCESS; +} diff --git a/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h b/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h new file mode 100644 index 0000000..6172c60 --- /dev/null +++ b/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h @@ -0,0 +1,167 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SOC_H__ +#define NRF_SOC_H__ + +#include +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Enable External Interrupt. + * @note Corresponds to NVIC_EnableIRQ in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was enabled. + */ +uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn); + +/**@brief Disable External Interrupt. + * @note Corresponds to NVIC_DisableIRQ in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS + * + * @retval ::NRF_SUCCESS The interrupt was disabled. + */ +uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn); + +/**@brief Get Pending Interrupt. + * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. + * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. + * + * @retval ::NRF_SUCCESS The interrupt is available for the application. + */ +uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq); + +/**@brief Set Pending Interrupt. + * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt is set pending. + */ +uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn); + +/**@brief Clear Pending Interrupt. + * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. + */ +uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn); + +/**@brief Set Interrupt Priority. + * @note Corresponds to NVIC_SetPriority in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * @pre{priority is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. + * @param[in] priority A valid IRQ priority for use by the application. + * + * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. + */ +uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority); + +/**@brief Get Interrupt Priority. + * @note Corresponds to NVIC_GetPriority in CMSIS. + * + * @pre{IRQn is valid and not reserved by the stack} + * + * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. + * @param[out] p_priority Return value from NVIC_GetPriority. + * + * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. + */ +uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority); + +/**@brief System Reset. + * @note Corresponds to NVIC_SystemReset in CMSIS. + * + * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN + */ +uint32_t sd_nvic_SystemReset(void); + +/**@brief Enters critical region. + * + * @post Application interrupts will be disabled. + * @sa sd_nvic_critical_region_exit + * + * @param[out] p_is_nested_critical_region 1: If in a nested critical region. + * 0: Otherwise. + * + * @retval ::NRF_SUCCESS + */ +uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region); + +/**@brief Exit critical region. + * + * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. + * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. + * + * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. + * + * @retval ::NRF_SUCCESS + */ +uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SOC_H__ */ diff --git a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c b/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c index 1227109..88ccd0f 100644 --- a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c +++ b/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c @@ -1,100 +1,47 @@ - /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include #include "nrf_soc.h" #include "nrf_error.h" -static uint8_t m_in_critical_region = 0; - -uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) -{ - NVIC_EnableIRQ(IRQn); - return NRF_SUCCESS; -} - -uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) -{ - NVIC_DisableIRQ(IRQn); - return NRF_SUCCESS; -} - -uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) -{ - if (p_pending_irq != NULL) - { - *p_pending_irq = NVIC_GetPendingIRQ(IRQn); - return NRF_SUCCESS; - } - return NRF_ERROR_NULL; -} - -uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC_SetPendingIRQ(IRQn); - return NRF_SUCCESS; -} - -uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC_ClearPendingIRQ(IRQn); - return NRF_SUCCESS; -} - -uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t priority) -{ - NVIC_SetPriority(IRQn, priority); - return NRF_SUCCESS; -} - -uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t * p_priority) -{ - if (p_priority != NULL) - { - *p_priority = NVIC_GetPriority(IRQn); - return NRF_SUCCESS; - } - - return NRF_ERROR_NULL; -} - -uint32_t sd_nvic_SystemReset(void) -{ - NVIC_SystemReset(); - return NRF_SUCCESS; -} - -uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) -{ - __disable_irq(); - - *p_is_nested_critical_region = (m_in_critical_region != 0); - m_in_critical_region++; - - return NRF_SUCCESS; -} - -uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) -{ - m_in_critical_region--; - - if (is_nested_critical_region == 0) - { - m_in_critical_region = 0; - __enable_irq(); - } - return NRF_SUCCESS; -} - uint32_t sd_app_evt_wait(void) { __WFE(); diff --git a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h b/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h index 267ab5e..64af135 100644 --- a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h +++ b/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SOC_H__ @@ -16,119 +44,9 @@ #include #include "nrf.h" -/**@brief The interrupt priorities available to the application while the softdevice is active. */ -typedef uint8_t nrf_app_irq_priority_t; - -/**@brief Enable External Interrupt. - * @note Corresponds to NVIC_EnableIRQ in CMSIS. - * - * @pre{IRQn is valid and not reserved by the stack} - * - * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was enabled. - */ -uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn); - -/**@brief Disable External Interrupt. - * @note Corresponds to NVIC_DisableIRQ in CMSIS. - * - * @pre{IRQn is valid and not reserved by the stack} - * - * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS - * - * @retval ::NRF_SUCCESS The interrupt was disabled. - */ -uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn); - -/**@brief Get Pending Interrupt. - * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. - * - * @pre{IRQn is valid and not reserved by the stack} - * - * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. - * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. - * - * @retval ::NRF_SUCCESS The interrupt is available for the application. - */ -uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq); - -/**@brief Set Pending Interrupt. - * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. - * - * @pre{IRQn is valid and not reserved by the stack} - * - * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt is set pending. - */ -uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn); - -/**@brief Clear Pending Interrupt. - * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. - * - * @pre{IRQn is valid and not reserved by the stack} - * - * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. - */ -uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn); - -/**@brief Set Interrupt Priority. - * @note Corresponds to NVIC_SetPriority in CMSIS. - * - * @pre{IRQn is valid and not reserved by the stack} - * @pre{priority is valid and not reserved by the stack} - * - * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. - * @param[in] priority A valid IRQ priority for use by the application. - * - * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. - */ -uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t priority); - -/**@brief Get Interrupt Priority. - * @note Corresponds to NVIC_GetPriority in CMSIS. - * - * @pre{IRQn is valid and not reserved by the stack} - * - * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. - * @param[out] p_priority Return value from NVIC_GetPriority. - * - * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. - */ -uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t * p_priority); - -/**@brief System Reset. - * @note Corresponds to NVIC_SystemReset in CMSIS. - * - * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN - */ -uint32_t sd_nvic_SystemReset(void); - -/**@brief Enters critical region. - * - * @post Application interrupts will be disabled. - * @sa sd_nvic_critical_region_exit - * - * @param[out] p_is_nested_critical_region 1: If in a nested critical region. - * 0: Otherwise. - * - * @retval ::NRF_SUCCESS - */ -uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region); - -/**@brief Exit critical region. - * - * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. - * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. - * - * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. - * - * @retval ::NRF_SUCCESS - */ -uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); +#ifdef __cplusplus +extern "C" { +#endif /**@brief Waits for an application event. * @@ -155,4 +73,9 @@ uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region); */ uint32_t sd_app_evt_wait(void); + +#ifdef __cplusplus +} +#endif + #endif /* NRF_SOC_H__ */ diff --git a/components/drivers_nrf/pdm/nrf_drv_pdm.c b/components/drivers_nrf/pdm/nrf_drv_pdm.c new file mode 100644 index 0000000..c5c315b --- /dev/null +++ b/components/drivers_nrf/pdm/nrf_drv_pdm.c @@ -0,0 +1,249 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PDM) +#include "nrf_drv_pdm.h" +#include "nrf_assert.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" + +#define NRF_LOG_MODULE_NAME "PDM" + +#if PDM_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL PDM_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR PDM_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR PDM_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_PDM_EVENT_STARTED ? "NRF_PDM_EVENT_STARTED" : \ + (event == NRF_PDM_EVENT_STOPPED ? "NRF_COMP_EVENT_DOWN" : \ + (event == NRF_PDM_EVENT_END ? "NRF_COMP_EVENT_CROSS" : "UNKNOWN EVENT"))) +#else //PDM_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //PDM_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +/** @brief PDM interface status. */ +typedef enum +{ + NRF_PDM_STATE_IDLE, + NRF_PDM_STATE_RUNNING, + NRF_PDM_STATE_TRANSITION +} nrf_drv_pdm_state_t; + + +/** @brief PDM interface control block.*/ +typedef struct +{ + nrf_drv_state_t drv_state; ///< Driver state. + nrf_drv_pdm_state_t status; ///< Sampling state. + nrf_drv_pdm_event_handler_t event_handler; ///< Event handler function pointer. + uint16_t buffer_length; ///< Length of a single buffer in 16-bit words. + uint32_t * buffers[2]; ///< Sample buffers. +} nrf_drv_pdm_cb_t; + +static nrf_drv_pdm_cb_t m_cb; + + +void PDM_IRQHandler(void) +{ + if (nrf_pdm_event_check(NRF_PDM_EVENT_END)) + { + nrf_pdm_event_clear(NRF_PDM_EVENT_END); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_PDM_EVENT_END)); + + //Buffer is ready to process. + if (nrf_pdm_buffer_get() == m_cb.buffers[0]) + { + NRF_LOG_DEBUG("PDM data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)m_cb.buffers[1], m_cb.buffer_length * sizeof(m_cb.buffers[1])); + m_cb.event_handler(m_cb.buffers[1], m_cb.buffer_length); + } + else + { + NRF_LOG_DEBUG("PDM data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)m_cb.buffers[0], m_cb.buffer_length * sizeof(m_cb.buffers[0])); + m_cb.event_handler(m_cb.buffers[0], m_cb.buffer_length); + } + } + else if (nrf_pdm_event_check(NRF_PDM_EVENT_STARTED)) + { + nrf_pdm_event_clear(NRF_PDM_EVENT_STARTED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_PDM_EVENT_STARTED)); + m_cb.status = NRF_PDM_STATE_RUNNING; + + //Swap buffer. + if (nrf_pdm_buffer_get() == m_cb.buffers[0]) + { + nrf_pdm_buffer_set(m_cb.buffers[1],m_cb.buffer_length); + } + else + { + nrf_pdm_buffer_set(m_cb.buffers[0],m_cb.buffer_length); + } + } + else if (nrf_pdm_event_check(NRF_PDM_EVENT_STOPPED)) + { + nrf_pdm_event_clear(NRF_PDM_EVENT_STOPPED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_PDM_EVENT_STOPPED)); + nrf_pdm_disable(); + m_cb.status = NRF_PDM_STATE_IDLE; + } +} + + +ret_code_t nrf_drv_pdm_init(nrf_drv_pdm_config_t const * p_config, + nrf_drv_pdm_event_handler_t event_handler) +{ + ret_code_t err_code; + + if (m_cb.drv_state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + if ((p_config == NULL) + || (event_handler == NULL)) + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + if (p_config->gain_l > NRF_PDM_GAIN_MAXIMUM + || p_config->gain_r > NRF_PDM_GAIN_MAXIMUM + || p_config->buffer_length > NRF_PDM_MAX_BUFFER_SIZE) + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + m_cb.buffers[0] = (uint32_t*)p_config->buffer_a; + m_cb.buffers[1] = (uint32_t*)p_config->buffer_b; + m_cb.buffer_length = p_config->buffer_length; + m_cb.event_handler = event_handler; + m_cb.status = NRF_PDM_STATE_IDLE; + + nrf_pdm_buffer_set(m_cb.buffers[0],m_cb.buffer_length); + nrf_pdm_clock_set(p_config->clock_freq); + nrf_pdm_mode_set(p_config->mode, p_config->edge); + nrf_pdm_gain_set(p_config->gain_l, p_config->gain_r); + + nrf_gpio_cfg_output(p_config->pin_clk); + nrf_gpio_pin_clear(p_config->pin_clk); + nrf_gpio_cfg_input(p_config->pin_din, NRF_GPIO_PIN_NOPULL); + nrf_pdm_psel_connect(p_config->pin_clk, p_config->pin_din); + + m_cb.drv_state = NRF_DRV_STATE_INITIALIZED; + nrf_pdm_int_enable(NRF_PDM_INT_STARTED | NRF_PDM_INT_END | NRF_PDM_INT_STOPPED); + nrf_drv_common_irq_enable(PDM_IRQn, p_config->interrupt_priority); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +void nrf_drv_pdm_uninit(void) +{ + nrf_pdm_disable(); + nrf_pdm_psel_disconnect(); + m_cb.drv_state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized.\r\n"); +} + + +ret_code_t nrf_drv_pdm_start(void) +{ + ASSERT(m_cb.drv_state != NRF_DRV_STATE_UNINITIALIZED); + ret_code_t err_code; + + if (m_cb.status != NRF_PDM_STATE_IDLE) + { + if (m_cb.status == NRF_PDM_STATE_RUNNING) + { + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + m_cb.status = NRF_PDM_STATE_TRANSITION; + m_cb.drv_state = NRF_DRV_STATE_POWERED_ON; + nrf_pdm_enable(); + nrf_pdm_event_clear(NRF_PDM_EVENT_STARTED); + nrf_pdm_task_trigger(NRF_PDM_TASK_START); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +ret_code_t nrf_drv_pdm_stop(void) +{ + ASSERT(m_cb.drv_state != NRF_DRV_STATE_UNINITIALIZED); + ret_code_t err_code; + + if (m_cb.status != NRF_PDM_STATE_RUNNING) + { + if (m_cb.status == NRF_PDM_STATE_IDLE) + { + nrf_pdm_disable(); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + m_cb.status = NRF_PDM_STATE_TRANSITION; + m_cb.drv_state = NRF_DRV_STATE_INITIALIZED; + nrf_pdm_task_trigger(NRF_PDM_TASK_STOP); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} +#endif //NRF_MODULE_ENABLED(PDM) diff --git a/components/drivers_nrf/pdm/nrf_drv_pdm.h b/components/drivers_nrf/pdm/nrf_drv_pdm.h new file mode 100644 index 0000000..81398ee --- /dev/null +++ b/components/drivers_nrf/pdm/nrf_drv_pdm.h @@ -0,0 +1,204 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @addtogroup nrf_pdm PDM HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52 Pulse density modulation (PDM) interface APIs. + * + * The PDM HAL provides basic APIs for accessing the registers of the PDM interface peripheral. + * The PDM driver provides APIs on a higher level. + * + * @defgroup nrf_drv_pdm PDM driver + * @{ + * @ingroup nrf_pdm + * + * @brief @tagAPI52 Pulse density modulation (PDM) interface driver. + */ + + +#ifndef NRF_DRV_PDM_H__ +#define NRF_DRV_PDM_H__ + +#include "sdk_config.h" +#include "nrf_pdm.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define NRF_PDM_MAX_BUFFER_SIZE 32768 + + +/** + * @brief PDM interface driver configuration structure. + */ +typedef struct +{ + nrf_pdm_mode_t mode; ///< Interface operation mode. + nrf_pdm_edge_t edge; ///< Sampling mode. + uint8_t pin_clk; ///< CLK pin. + uint8_t pin_din; ///< DIN pin. + nrf_pdm_freq_t clock_freq; ///< Clock frequency. + nrf_pdm_gain_t gain_l; ///< Left channel gain. + nrf_pdm_gain_t gain_r; ///< Right channel gain. + uint8_t interrupt_priority; ///< Interrupt priority. + uint16_t buffer_length; ///< Length of a single buffer (in 16-bit words). + int16_t * buffer_a; ///< Sample buffer A (filled first). + int16_t * buffer_b; ///< Sample buffer B (filled after buffer A). +} nrf_drv_pdm_config_t; + + +/** + * @brief Macro for setting @ref nrf_drv_pdm_config_t to default settings + * in single ended mode. + * + * @param PIN_CLK CLK output pin. + * @param PIN_DIN DIN input pin. + * @param BUFF_A Sample buffer A (filled first). + * @param BUFF_B Sample buffer B (filled after buffer A). + * @param BUFF_LEN Length of a single buffer (in 16-bit words). + */ +#define NRF_DRV_PDM_DEFAULT_CONFIG(PIN_CLK, PIN_DIN, BUFF_A, BUFF_B, BUFF_LEN) \ +{ \ + .mode = (nrf_pdm_mode_t)PDM_CONFIG_MODE, \ + .edge = (nrf_pdm_edge_t)PDM_CONFIG_EDGE, \ + .pin_clk = PIN_CLK, \ + .pin_din = PIN_DIN, \ + .clock_freq = (nrf_pdm_freq_t)PDM_CONFIG_CLOCK_FREQ, \ + .gain_l = NRF_PDM_GAIN_DEFAULT, \ + .gain_r = NRF_PDM_GAIN_DEFAULT, \ + .interrupt_priority = PDM_CONFIG_IRQ_PRIORITY, \ + .buffer_length = BUFF_LEN, \ + .buffer_a = BUFF_A, \ + .buffer_b = BUFF_B \ +} + + +/** + * @brief Handler for PDM interface ready events. + * + * This event handler is called when a buffer is full and ready to be processed. + * + * @param[in] p_buffer Sample buffer pointer. + * @param[in] length Buffer length in 16-bit words. + */ +typedef void (*nrf_drv_pdm_event_handler_t)(uint32_t * buffer, uint16_t length); + + +/** + * @brief Function for initializing the PDM interface. + * + * @param[in] p_config Pointer to a configuration structure. If NULL, the default one is used. + * @param[in] event_handler Event handler provided by the user. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is already initialized. + * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified. + */ +ret_code_t nrf_drv_pdm_init(nrf_drv_pdm_config_t const * p_config, + nrf_drv_pdm_event_handler_t event_handler); + + +/** + * @brief Function for uninitializing the PDM interface. + * + * This function stops PDM sampling, if it is in progress. + */ +void nrf_drv_pdm_uninit(void); + + +/** + * @brief Function for getting the address of a PDM interface task. + * + * @param[in] task Task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_pdm_task_address_get(nrf_pdm_task_t task) +{ + return nrf_pdm_task_address_get(task); +} + + +/** + * @brief Function for getting the state of the PDM interface. + * + * @retval TRUE If the PDM interface is enabled. + * @retval FALSE If the PDM interface is disabled. + */ +__STATIC_INLINE bool nrf_drv_pdm_enable_check() +{ + return nrf_pdm_enable_check(); +} + + +/** + * @brief Function for starting PDM sampling. + * + * @retval NRF_SUCCESS If sampling was started successfully or was already in progress. + * @retval NRF_ERROR_BUSY If a previous start/stop operation is in progress. + */ +ret_code_t nrf_drv_pdm_start(void); + + +/** + * @brief Function for stopping PDM sampling. + * + * When this function is called, the PDM interface is stopped after finishing + * the current frame. + * The event handler function might be called once more after calling this function. + * + * @retval NRF_SUCCESS If sampling was stopped successfully or was already stopped before. + * @retval NRF_ERROR_BUSY If a previous start/stop operation is in progress. + */ +ret_code_t nrf_drv_pdm_stop(void); + + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_PDM_H__ + +/** @} */ diff --git a/components/drivers_nrf/power/nrf_drv_power.c b/components/drivers_nrf/power/nrf_drv_power.c new file mode 100644 index 0000000..024badb --- /dev/null +++ b/components/drivers_nrf/power/nrf_drv_power.c @@ -0,0 +1,272 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if POWER_ENABLED + +#include "nrf_drv_power.h" +#include "nrf_assert.h" +#include "nordic_common.h" + +/* Validate configuration */ +INTERRUPT_PRIORITY_VALIDATION(POWER_CONFIG_IRQ_PRIORITY); + +/** + * @internal + * @defgroup nrf_drv_power_internals POWER driver internals + * @ingroup nrf_drv_power + * + * Internal variables, auxiliary macros and functions of POWER driver. + * @{ + */ + +/** + * @brief Default configuration + * + * The structure with default configuration data. + * This structure would be used if configuration pointer given + * to the @ref nrf_drv_power_init is set to NULL. + */ +static const nrf_drv_power_config_t m_drv_power_config_default = +{ + .dcdcen = POWER_CONFIG_DEFAULT_DCDCEN, +#if NRF_POWER_HAS_VDDH + .dcdcenhv = POWER_CONFIG_DEFAULT_DCDCENHV, +#endif +}; + +/** + * @brief The initialization flag + */ +static bool m_initialized; + +/** + * @brief The handler of power fail comparator warning event + */ +static nrf_drv_power_pofwarn_event_handler_t m_pofwarn_handler; + +#if NRF_POWER_HAS_SLEEPEVT +/** + * @brief The handler of sleep event handler + */ +static nrf_drv_power_sleep_event_handler_t m_sleepevt_handler; +#endif + +#if NRF_POWER_HAS_USBREG +/** + * @brief The handler of USB power events + */ +static nrf_drv_power_usb_event_handler_t m_usbevt_handler; +#endif + +/** @} */ + +bool nrf_drv_power_init_check(void) +{ + return m_initialized; +} + +ret_code_t nrf_drv_power_init(nrf_drv_power_config_t const * p_config) +{ + nrf_drv_power_config_t const * p_used_config; + if(m_initialized) + { + return NRF_ERROR_MODULE_ALREADY_INITIALIZED; + } + + p_used_config = (p_config != NULL) ? + p_config : (&m_drv_power_config_default); + nrf_power_dcdcen_set(p_used_config->dcdcen); +#if NRF_POWER_HAS_VDDH + nrf_power_dcdcen_vddh_set(p_used_config->dcdcenhv); +#endif + + nrf_drv_common_power_clock_irq_init(); + + m_initialized = true; + return NRF_SUCCESS; +} + +void nrf_drv_power_uninit(void) +{ + ASSERT(m_initialized); + nrf_drv_power_pof_uninit(); +#if NRF_POWER_HAS_SLEEPEVT + nrf_drv_power_sleepevt_uninit(); +#endif +#if NRF_POWER_HAS_USBREG + nrf_drv_power_usbevt_uninit(); +#endif + m_initialized = false; +} + +void nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_config) +{ + ASSERT(p_config != NULL); + + nrf_drv_power_pof_uninit(); + nrf_power_pofcon_set(true, p_config->thr); +#if NRF_POWER_HAS_VDDH + nrf_power_pofcon_vddh_set(p_config->thrvddh); +#endif + if(p_config->handler != NULL) + { + m_pofwarn_handler = p_config->handler; + nrf_power_int_enable(NRF_POWER_INT_POFWARN_MASK); + } +} + +void nrf_drv_power_pof_uninit(void) +{ + nrf_power_int_disable(NRF_POWER_INT_POFWARN_MASK); + m_pofwarn_handler = NULL; +} + +#if NRF_POWER_HAS_SLEEPEVT +void nrf_drv_power_sleepevt_init(nrf_drv_power_sleepevt_config_t const * p_config) +{ + ASSERT(p_config != NULL); + + nrf_drv_power_sleepevt_uninit(); + if(p_config->handler != NULL) + { + uint32_t enmask = 0; + m_sleepevt_handler = p_config->handler; + if(p_config->en_enter) + { + enmask |= NRF_POWER_INT_SLEEPENTER_MASK; + } + if(p_config->en_exit) + { + enmask |= NRF_POWER_INT_SLEEPEXIT_MASK; + } + nrf_power_int_enable(enmask); + } +} + +void nrf_drv_power_sleepevt_uninit(void) +{ + nrf_power_int_disable( + NRF_POWER_INT_SLEEPENTER_MASK | + NRF_POWER_INT_SLEEPEXIT_MASK); + m_sleepevt_handler = NULL; +} +#endif /* NRF_POWER_HAS_SLEEPEVT */ + +#if NRF_POWER_HAS_USBREG +void nrf_drv_power_usbevt_init(nrf_drv_power_usbevt_config_t const * p_config) +{ + nrf_drv_power_usbevt_uninit(); + if(p_config->handler != NULL) + { + m_usbevt_handler = p_config->handler; + nrf_power_int_enable( + NRF_POWER_INT_USBDETECTED_MASK | + NRF_POWER_INT_USBREMOVED_MASK | + NRF_POWER_INT_USBPWRRDY_MASK); + } +} + +void nrf_drv_power_usbevt_uninit(void) +{ + nrf_power_int_disable( + NRF_POWER_INT_USBDETECTED_MASK | + NRF_POWER_INT_USBREMOVED_MASK | + NRF_POWER_INT_USBPWRRDY_MASK); + m_usbevt_handler = NULL; +} +#endif /* NRF_POWER_HAS_USBREG */ + + +/** + * @ingroup nrf_drv_power_internals + * @brief Interrupt handler + * + * POWER peripheral interrupt handler + */ +#if NRF_DRV_COMMON_POWER_CLOCK_ISR +void nrf_drv_power_onIRQ(void) +#else +void POWER_POWER_IRQHandler(void) +#endif +{ + uint32_t enabled = nrf_power_int_enable_get(); + if((0 != (enabled & NRF_POWER_INT_POFWARN_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_POFWARN)) + { + ASSERT(m_pofwarn_handler != NULL); /* Cannot be null if event is enabled */ + m_pofwarn_handler(); + } +#if NRF_POWER_HAS_SLEEPEVT + if((0 != (enabled & NRF_POWER_INT_SLEEPENTER_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_SLEEPENTER)) + { + ASSERT(m_sleepevt_handler != NULL); /* Cannot be null if event is enabled */ + m_sleepevt_handler(NRF_DRV_POWER_SLEEP_EVT_ENTER); + } + if((0 != (enabled & NRF_POWER_INT_SLEEPEXIT_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_SLEEPEXIT)) + { + ASSERT(m_sleepevt_handler != NULL); /* Cannot be null if event is enabled */ + m_sleepevt_handler(NRF_DRV_POWER_SLEEP_EVT_EXIT); + } +#endif +#if NRF_POWER_HAS_USBREG + if((0 != (enabled & NRF_POWER_INT_USBDETECTED_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBDETECTED)) + { + ASSERT(m_usbevt_handler != NULL); /* Cannot be null if event is enabled */ + m_usbevt_handler(NRF_DRV_POWER_USB_EVT_DETECTED); + } + if((0 != (enabled & NRF_POWER_INT_USBREMOVED_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBREMOVED)) + { + ASSERT(m_usbevt_handler != NULL); /* Cannot be null if event is enabled */ + m_usbevt_handler(NRF_DRV_POWER_USB_EVT_REMOVED); + } + if((0 != (enabled & NRF_POWER_INT_USBPWRRDY_MASK)) && + nrf_power_event_get_and_clear(NRF_POWER_EVENT_USBPWRRDY)) + { + ASSERT(m_usbevt_handler != NULL); /* Cannot be null if event is enabled */ + m_usbevt_handler(NRF_DRV_POWER_USB_EVT_READY); + } +#endif +} + +#endif /* POWER_ENABLED */ diff --git a/components/drivers_nrf/power/nrf_drv_power.h b/components/drivers_nrf/power/nrf_drv_power.h new file mode 100644 index 0000000..9242517 --- /dev/null +++ b/components/drivers_nrf/power/nrf_drv_power.h @@ -0,0 +1,349 @@ +/** + * Copyright (c) 2017 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_POWER_H__ +#define NRF_DRV_POWER_H__ + +#include +#include +#include "nrf_power.h" +#include "sdk_config.h" +#include "nrf_drv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_power Power HAL and driver + * @ingroup nrf_drivers + * @brief POWER peripheral APIs. + * + * The power peripheral HAL provides basic APIs for accessing + * the registers of the POWER peripheral. + * The POWER driver provides APIs on a higher level. + */ + +/** + * @defgroup nrf_drv_power POWER driver + * @{ + * @ingroup nrf_power + * @brief Driver for managing events and the state of POWER peripheral. + * + */ + +/** + * @brief Power mode possible configurations + */ +typedef enum +{ + NRF_DRV_POWER_MODE_CONSTLAT, /**< Constant latency mode *///!< NRF_DRV_POWER_MODE_CONSTLAT + NRF_DRV_POWER_MODE_LOWPWR /**< Low power mode *///!< NRF_DRV_POWER_MODE_LOWPWR +}nrf_drv_power_mode_t; + +#if NRF_POWER_HAS_SLEEPEVT +/** + * @brief Events from power system + */ +typedef enum +{ + NRF_DRV_POWER_SLEEP_EVT_ENTER, /**< CPU entered WFI/WFE sleep + * + * Keep in mind that if this interrupt is enabled, + * it means that CPU was waken up just after WFI by this interrupt. + */ + NRF_DRV_POWER_SLEEP_EVT_EXIT /**< CPU exited WFI/WFE sleep */ +}nrf_drv_power_sleep_evt_t; +#endif /* NRF_POWER_HAS_SLEEPEVT */ + +#if NRF_POWER_HAS_USBREG +/** + * @brief Events from USB power system + */ +typedef enum +{ + NRF_DRV_POWER_USB_EVT_DETECTED, /**< USB power detected on the connector (plugged in). */ + NRF_DRV_POWER_USB_EVT_REMOVED, /**< USB power removed from the connector. */ + NRF_DRV_POWER_USB_EVT_READY /**< USB power regulator ready. */ +}nrf_drv_power_usb_evt_t; + +/** + * @brief USB power state + * + * The single enumerator that holds all data about current state of USB + * related POWER. + * + * Organized this way that higher power state has higher numeric value + */ +typedef enum +{ + NRF_DRV_POWER_USB_STATE_DISCONNECTED, /**< No power on USB lines detected */ + NRF_DRV_POWER_USB_STATE_CONNECTED, /**< The USB power is detected, but USB power regulator is not ready */ + NRF_DRV_POWER_USB_STATE_READY /**< From the power point of view USB is ready for working */ +}nrf_drv_power_usb_state_t; +#endif /* NRF_POWER_HAS_USBREG */ + +/** + * @name Callback types + * + * Defined types of callback functions + * @{ + */ +/** + * @brief Event handler for power failure warning + */ +typedef void (*nrf_drv_power_pofwarn_event_handler_t)(void); + +#if NRF_POWER_HAS_SLEEPEVT +/** + * @brief Event handler for entering/exiting sleep + * + * @param event Event type + */ +typedef void (*nrf_drv_power_sleep_event_handler_t)(nrf_drv_power_sleep_evt_t event); +#endif + +#if NRF_POWER_HAS_USBREG +/** + * @brief Event handler for USB related power events + * + * @param event Event type + */ +typedef void (*nrf_drv_power_usb_event_handler_t)(nrf_drv_power_usb_evt_t event); +#endif +/** @} */ + +/** + * @brief General power configuration + * + * Parameters required to initialize power driver. + */ +typedef struct +{ + /** + * @brief Enable main DCDC regulator + * + * This bit only informs the driver that elements for DCDC regulator + * are installed and regulator can be used. + * The regulator would be enabled or disabled automatically + * automatically by the hardware, basing on current power requirement. + */ + bool dcdcen:1; + +#if NRF_POWER_HAS_VDDH + /** + * @brief Enable HV DCDC regulator + * + * This bit only informs the driver that elements for DCDC regulator + * are installed and regulator can be used. + * The regulator would be enabled or disabled automatically + * automatically by the hardware, basing on current power requirement. + */ + bool dcdcenhv: 1; +#endif +}nrf_drv_power_config_t; + +/** + * @brief The configuration for power failure comparator + * + * Configuration used to enable and configure power failure comparator + */ +typedef struct +{ + nrf_drv_power_pofwarn_event_handler_t handler; //!< Event handler + nrf_power_pof_thr_t thr; //!< Threshold for power failure detection +#if NRF_POWER_HAS_VDDH + nrf_power_pof_thrvddh_t thrvddh; //!< Threshold for power failure detection on VDDH pin +#endif +}nrf_drv_power_pofwarn_config_t; + +#if NRF_POWER_HAS_SLEEPEVT +/** + * @brief The configuration of sleep event processing + * + * Configuration used to enable and configure sleep event handling + */ +typedef struct +{ + nrf_drv_power_sleep_event_handler_t handler; //!< Event handler + bool en_enter:1; //!< Enable event on sleep entering + bool en_exit :1; //!< Enable event on sleep exiting +}nrf_drv_power_sleepevt_config_t; +#endif + +#if NRF_POWER_HAS_USBREG +/** + * @brief The configuration of USB related power events + * + * Configuration used to enable and configure USB power event handling + */ +typedef struct +{ + nrf_drv_power_usb_event_handler_t handler; //!< Event processing +}nrf_drv_power_usbevt_config_t; +#endif /* NRF_POWER_HAS_USBREG */ + +/** + * @brief Function for checking if driver is already initialized + * + * This function is used to check whatever common POWER_CLOCK common interrupt + * should be disabled or not if @ref nrf_drv_clock tries to disable the interrupt. + * + * @retval true Driver is initialized + * @retval false Driver is uninitialized + * + * @sa nrf_drv_power_uninit + */ +bool nrf_drv_power_init_check(void); + +/** + * @brief Initialize power module driver + * + * Enabled power module driver would process all the interrupts from power system. + * + * @param[in] p_config Driver configuration. Can be NULL - the default configuration + * from @em sdk_config.h file would be used then. + * + * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED Module is initialized already. + * @retval NRF_SUCCESS Successfully initialized. + */ +ret_code_t nrf_drv_power_init(nrf_drv_power_config_t const * p_config); + +/** + * @brief Unintialize power module driver + * + * Disables all the interrupt handling in the module. + * + * @sa nrf_drv_power_init + */ +void nrf_drv_power_uninit(void); + +/** + * @brief Initialize power failure comparator + * + * Configures and setups the power failure comparator and enables it. + * + * @param[in] p_config Configuration with values and event handler. + * If event handler is set to NULL, interrupt would be disabled. + */ +void nrf_drv_power_pof_init(nrf_drv_power_pofwarn_config_t const * p_config); + +/** + * @brief Turn off the power failure comparator + * + * Disables and clears the settings of the power failure comparator. + */ +void nrf_drv_power_pof_uninit(void); + +#if NRF_POWER_HAS_SLEEPEVT +/** + * @brief Initialize sleep entering and exiting events processing + * + * Configures and setups the sleep event processing. + * + * @param[in] p_config Configuration with values and event handler. + * + * @sa nrf_drv_power_sleepevt_uninit + */ +void nrf_drv_power_sleepevt_init(nrf_drv_power_sleepevt_config_t const * p_config); + +/** + * @brief Uninitialize sleep entering and exiting events processing + * + * @sa nrf_drv_power_sleepevt_init + */ +void nrf_drv_power_sleepevt_uninit(void); +#endif /* NRF_POWER_HAS_SLEEPEVT */ + +#if NRF_POWER_HAS_USBREG +/** + * @brief Initialize USB power event processing + * + * Configures and setups the USB power event processing. + * + * @param[in] p_config Configuration with values and event handler. + * + * @sa nrf_drv_power_usbevt_uninit + */ +void nrf_drv_power_usbevt_init(nrf_drv_power_usbevt_config_t const * p_config); + +/** + * @brief Uninitalize USB power event processing + * + * @sa nrf_drv_power_usbevt_init + */ +void nrf_drv_power_usbevt_uninit(void); + +/** + * @brief Get the status of USB power + * + * @return Current USB power status + */ +__STATIC_INLINE nrf_drv_power_usb_state_t nrf_drv_power_usbstatus_get(void); + +#endif /* NRF_POWER_HAS_USBREG */ + +/** @} */ + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +#if NRF_POWER_HAS_USBREG +__STATIC_INLINE nrf_drv_power_usb_state_t nrf_drv_power_usbstatus_get(void) +{ + uint32_t status = nrf_power_usbregstatus_get(); + if(0 == (status & NRF_POWER_USBREGSTATUS_VBUSDETECT_MASK)) + { + return NRF_DRV_POWER_USB_STATE_DISCONNECTED; + } + if(0 == (status & NRF_POWER_USBREGSTATUS_OUTPUTRDY_MASK)) + { + return NRF_DRV_POWER_USB_STATE_CONNECTED; + } + return NRF_DRV_POWER_USB_STATE_READY; +} +#endif /* NRF_POWER_HAS_USBREG */ + +#endif /* SUPPRESS_INLINE_IMPLEMENTATION */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_DRV_POWER_H__ */ diff --git a/components/drivers_nrf/ppi/nrf_drv_ppi.c b/components/drivers_nrf/ppi/nrf_drv_ppi.c index 585073a..a305a10 100644 --- a/components/drivers_nrf/ppi/nrf_drv_ppi.c +++ b/components/drivers_nrf/ppi/nrf_drv_ppi.c @@ -1,18 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - -#include +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PPI) #include -#include #include "nrf.h" #include "nrf_drv_ppi.h" @@ -20,6 +47,18 @@ #include "nrf_ppi.h" #include "app_util_platform.h" +#define NRF_LOG_MODULE_NAME "PPI" + +#if PPI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL PPI_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR PPI_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR PPI_CONFIG_DEBUG_COLOR +#else //PPI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //PPI_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + static nrf_drv_state_t m_drv_state; /**< Driver state */ static uint32_t m_channels_allocated; /**< Bitmap representing channels availability. 1 when a channel is allocated, 0 otherwise. */ @@ -167,23 +206,28 @@ uint32_t nrf_drv_ppi_init(void) } else { - err_code = MODULE_ALREADY_INITIALIZED; + + err_code = NRF_ERROR_MODULE_ALREADY_INITIALIZED; } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); return err_code; } uint32_t nrf_drv_ppi_uninit(void) { + ret_code_t err_code = NRF_SUCCESS; uint32_t mask = NRF_PPI_ALL_APP_GROUPS_MASK; nrf_ppi_channel_group_t group; if (m_drv_state == NRF_DRV_STATE_UNINITIALIZED) { - return NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } - + m_drv_state = NRF_DRV_STATE_UNINITIALIZED; // Disable all channels and groups @@ -191,20 +235,21 @@ uint32_t nrf_drv_ppi_uninit(void) for (group = NRF_PPI_CHANNEL_GROUP0; mask != 0; mask &= ~group_to_mask(group), group++) { - if(mask & group_to_mask(group)) + if (mask & group_to_mask(group)) { nrf_ppi_channel_group_clear(group); } } channel_allocated_clr_all(); group_allocated_clr_all(); - return NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } uint32_t nrf_drv_ppi_channel_alloc(nrf_ppi_channel_t * p_channel) { - uint32_t err_code; + uint32_t err_code = NRF_SUCCESS; nrf_ppi_channel_t channel; uint32_t mask = 0; @@ -223,76 +268,127 @@ uint32_t nrf_drv_ppi_channel_alloc(nrf_ppi_channel_t * p_channel) CRITICAL_REGION_EXIT(); if (err_code == NRF_SUCCESS) { + NRF_LOG_INFO("Allocated channel: %d.\r\n", channel); break; } } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); return err_code; } uint32_t nrf_drv_ppi_channel_free(nrf_ppi_channel_t channel) { + ret_code_t err_code = NRF_SUCCESS; + if (!is_programmable_app_channel(channel)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; } - // First disable this channel - nrf_ppi_channel_disable(channel); - CRITICAL_REGION_ENTER(); - channel_allocated_clr(channel); - CRITICAL_REGION_EXIT(); - return NRF_SUCCESS; + else + { + // First disable this channel + nrf_ppi_channel_disable(channel); + CRITICAL_REGION_ENTER(); + channel_allocated_clr(channel); + CRITICAL_REGION_EXIT(); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } uint32_t nrf_drv_ppi_channel_assign(nrf_ppi_channel_t channel, uint32_t eep, uint32_t tep) { - if (((uint32_t *)eep == NULL) || ((uint32_t *)tep == NULL)) + VERIFY_PARAM_NOT_NULL((uint32_t *)eep); + VERIFY_PARAM_NOT_NULL((uint32_t *)tep); + + ret_code_t err_code = NRF_SUCCESS; + + if (!is_programmable_app_channel(channel)) { - return NRF_ERROR_NULL; + err_code = NRF_ERROR_INVALID_PARAM; } - if (!is_programmable_app_channel(channel)) + else if (!is_allocated_channel(channel)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_STATE; } - if (!is_allocated_channel(channel)) + else { - return NRF_ERROR_INVALID_STATE; + nrf_ppi_channel_endpoint_setup(channel, eep, tep); + NRF_LOG_INFO("Assigned channel: %d, event end point: %x, task end point: %x.\r\n", channel, eep, tep); } - - nrf_ppi_channel_endpoint_setup(channel, eep, tep); - return NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } +uint32_t nrf_drv_ppi_channel_fork_assign(nrf_ppi_channel_t channel, uint32_t fork_tep) +{ + ret_code_t err_code = NRF_SUCCESS; +#ifdef PPI_FEATURE_FORKS_PRESENT + if (!is_programmable_app_channel(channel)) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + else if (!is_allocated_channel(channel)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else + { + nrf_ppi_fork_endpoint_setup(channel, fork_tep); + NRF_LOG_INFO("Fork assigned channel: %d, task end point: %d.\r\n", channel, fork_tep); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +#else + err_code = NRF_ERROR_NOT_SUPPORTED; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +#endif +} uint32_t nrf_drv_ppi_channel_enable(nrf_ppi_channel_t channel) { + ret_code_t err_code = NRF_SUCCESS; + if (!is_app_channel(channel)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; + } + else if (is_programmable_app_channel(channel) && !is_allocated_channel(channel)) + { + err_code = NRF_ERROR_INVALID_STATE; } - if (is_programmable_app_channel(channel) && !is_allocated_channel(channel)) + else { - return NRF_ERROR_INVALID_STATE; + nrf_ppi_channel_enable(channel); } - nrf_ppi_channel_enable(channel); - return NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } uint32_t nrf_drv_ppi_channel_disable(nrf_ppi_channel_t channel) { + ret_code_t err_code = NRF_SUCCESS; + if (!is_app_channel(channel)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; } - if (is_programmable_app_channel(channel) && !is_allocated_channel(channel)) + else if (is_programmable_app_channel(channel) && !is_allocated_channel(channel)) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else { - return NRF_ERROR_INVALID_STATE; + nrf_ppi_channel_disable(channel); + err_code = NRF_SUCCESS; } - nrf_ppi_channel_disable(channel); - return NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } @@ -317,96 +413,128 @@ uint32_t nrf_drv_ppi_group_alloc(nrf_ppi_channel_group_t * p_group) CRITICAL_REGION_EXIT(); if (err_code == NRF_SUCCESS) { + NRF_LOG_INFO("Allocated group: %d.\r\n", group); break; } } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); return err_code; } uint32_t nrf_drv_ppi_group_free(nrf_ppi_channel_group_t group) { + ret_code_t err_code = NRF_SUCCESS; + if (!is_app_group(group)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; } if (!is_allocated_group(group)) { - return NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; } else - nrf_ppi_group_disable(group); - CRITICAL_REGION_ENTER(); - group_allocated_clr(group); - CRITICAL_REGION_EXIT(); - return NRF_SUCCESS; + { + nrf_ppi_group_disable(group); + CRITICAL_REGION_ENTER(); + group_allocated_clr(group); + CRITICAL_REGION_EXIT(); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } uint32_t nrf_drv_ppi_group_enable(nrf_ppi_channel_group_t group) { + ret_code_t err_code = NRF_SUCCESS; + if (!is_app_group(group)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; } - if (!is_allocated_group(group)) + else if (!is_allocated_group(group)) { - return NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; } - nrf_ppi_group_enable(group); - return NRF_SUCCESS; + else + { + nrf_ppi_group_enable(group); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } uint32_t nrf_drv_ppi_group_disable(nrf_ppi_channel_group_t group) { + ret_code_t err_code = NRF_SUCCESS; + if (!is_app_group(group)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; } - nrf_ppi_group_disable(group); - return NRF_SUCCESS; + else + { + nrf_ppi_group_disable(group); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } uint32_t nrf_drv_ppi_channels_remove_from_group(uint32_t channel_mask, nrf_ppi_channel_group_t group) { + ret_code_t err_code = NRF_SUCCESS; + if (!is_app_group(group)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; } - if (!is_allocated_group(group)) + else if (!is_allocated_group(group)) { - return NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; } - if (!are_app_channels(channel_mask)) + else if (!are_app_channels(channel_mask)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; } - CRITICAL_REGION_ENTER(); - nrf_ppi_channels_remove_from_group(channel_mask, group); - CRITICAL_REGION_EXIT(); - return NRF_SUCCESS; + else + { + CRITICAL_REGION_ENTER(); + nrf_ppi_channels_remove_from_group(channel_mask, group); + CRITICAL_REGION_EXIT(); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } uint32_t nrf_drv_ppi_channels_include_in_group(uint32_t channel_mask, nrf_ppi_channel_group_t group) { + ret_code_t err_code = NRF_SUCCESS; + if (!is_app_group(group)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; } - if (!is_allocated_group(group)) + else if (!is_allocated_group(group)) { - return NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; } - if (!are_app_channels(channel_mask)) + else if (!are_app_channels(channel_mask)) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; } - CRITICAL_REGION_ENTER(); - nrf_ppi_channels_include_in_group(channel_mask, group); - CRITICAL_REGION_EXIT(); - return NRF_SUCCESS; + else + { + CRITICAL_REGION_ENTER(); + nrf_ppi_channels_include_in_group(channel_mask, group); + CRITICAL_REGION_EXIT(); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } +#endif //NRF_MODULE_ENABLED(PPI) diff --git a/components/drivers_nrf/ppi/nrf_drv_ppi.h b/components/drivers_nrf/ppi/nrf_drv_ppi.h index 06a4e60..329c4c9 100644 --- a/components/drivers_nrf/ppi/nrf_drv_ppi.h +++ b/components/drivers_nrf/ppi/nrf_drv_ppi.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_PPI_H @@ -25,10 +53,10 @@ * @ingroup nrf_drivers * @brief Programmable Peripheral Interconnect (PPI) APIs. * - * @details The PPI HAL provides basic APIs for accessing the registers of the PPI. + * @details The PPI HAL provides basic APIs for accessing the registers of the PPI. * The PPI driver provides APIs on a higher level. * - * @defgroup lib_driver_ppi PPI driver + * @defgroup nrf_drv_ppi PPI driver * @{ * @ingroup nrf_ppi * @@ -37,29 +65,29 @@ #include "sdk_resources.h" -#ifdef NRF52 - - #define NRF_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFFFFFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< All PPI channels available to the application. */ - #define NRF_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x000FFFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< Programmable PPI channels available to the application. */ - #define NRF_PPI_ALL_APP_GROUPS_MASK ((uint32_t)0x0000003FuL & ~(NRF_PPI_GROUPS_USED)) /**< All PPI groups available to the application. */ +#ifdef __cplusplus +extern "C" { +#endif +#if PPI_CH_NUM > 16 +#define NRF_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFFFFFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< All PPI channels available to the application. */ +#define NRF_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x000FFFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< Programmable PPI channels available to the application. */ #else - - #define NRF_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFF0FFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< All PPI channels available to the application. */ - #define NRF_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x0000FFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< Programmable PPI channels available to the application. */ - #define NRF_PPI_ALL_APP_GROUPS_MASK ((uint32_t)0x0000000FuL & ~(NRF_PPI_GROUPS_USED)) /**< All PPI groups available to the application. */ - +#define NRF_PPI_ALL_APP_CHANNELS_MASK ((uint32_t)0xFFF0FFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< All PPI channels available to the application. */ +#define NRF_PPI_PROG_APP_CHANNELS_MASK ((uint32_t)0x0000FFFFuL & ~(NRF_PPI_CHANNELS_USED)) /**< Programmable PPI channels available to the application. */ #endif +#define NRF_PPI_ALL_APP_GROUPS_MASK (((1uL << PPI_GROUP_NUM) - 1) & ~(NRF_PPI_GROUPS_USED)) /**< All PPI groups available to the application. */ + /**@brief Function for initializing PPI module. * - * @retval NRF_SUCCESS If the module was successfully initialized. - * @retval MODULE_ALREADY_INITIALIZED If the module has already been initialized. + * @retval NRF_SUCCESS If the module was successfully initialized. + * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED If the module has already been initialized. */ uint32_t nrf_drv_ppi_init(void); -/**@brief Function for uninitializing the PPI module. +/**@brief Function for uninitializing the PPI module. * * This function also disables all channels and clears the channel groups. * @@ -103,6 +131,19 @@ uint32_t nrf_drv_ppi_channel_free(nrf_ppi_channel_t channel); */ uint32_t nrf_drv_ppi_channel_assign(nrf_ppi_channel_t channel, uint32_t eep, uint32_t tep); +/**@brief Function for assigning or clearing fork endpoint to the PPI channel. + * + * @param[in] channel PPI channel to be assigned endpoints. + * + * @param[in] fork_tep Fork task endpoint address or 0 to clear. + * + * @retval NRF_SUCCESS If the channel was successfully assigned. + * @retval NRF_ERROR_INVALID_STATE If the channel is not allocated for the user. + * @retval NRF_ERROR_INVALID_PARAM If the channel is not user-configurable. + * @retval NRF_ERROR_NOT_SUPPORTED If function is not supported. + */ +uint32_t nrf_drv_ppi_channel_fork_assign(nrf_ppi_channel_t channel, uint32_t fork_tep); + /**@brief Function for enabling a PPI channel. * * @param[in] channel PPI channel to be enabled. @@ -268,4 +309,9 @@ __STATIC_INLINE uint32_t nrf_drv_ppi_task_addr_group_disable_get(nrf_ppi_channel **/ /*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif // NRF_DRV_PPI_H diff --git a/components/drivers_nrf/pstorage/config/pstorage_platform.h b/components/drivers_nrf/pstorage/config/pstorage_platform.h deleted file mode 100644 index 910b99b..0000000 --- a/components/drivers_nrf/pstorage/config/pstorage_platform.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - - /** @cond To make doxygen skip this file */ - -/** @file - * This header contains defines with respect persistent storage that are specific to - * persistent storage implementation and application use case. - */ -#ifndef PSTORAGE_PL_H__ -#define PSTORAGE_PL_H__ - -#include -#include "nrf.h" - -static __INLINE uint16_t pstorage_flash_page_size() -{ - return (uint16_t)NRF_FICR->CODEPAGESIZE; -} - -#define PSTORAGE_FLASH_PAGE_SIZE pstorage_flash_page_size() /**< Size of one flash page. */ -#define PSTORAGE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */ - -#ifdef NRF51 -#define BOOTLOADER_ADDRESS (NRF_UICR->BOOTLOADERADDR) -#elif defined NRF52 -#define BOOTLOADER_ADDRESS (PSTORAGE_FLASH_EMPTY_MASK) -#endif - -static __INLINE uint32_t pstorage_flash_page_end() -{ - uint32_t bootloader_addr = BOOTLOADER_ADDRESS; - - return ((bootloader_addr != PSTORAGE_FLASH_EMPTY_MASK) ? - (bootloader_addr/ PSTORAGE_FLASH_PAGE_SIZE) : NRF_FICR->CODESIZE); -} - -#define PSTORAGE_FLASH_PAGE_END pstorage_flash_page_end() - -#define PSTORAGE_NUM_OF_PAGES 1 /**< Number of flash pages allocated for the pstorage module excluding the swap page, configurable based on system requirements. */ -#define PSTORAGE_MIN_BLOCK_SIZE 0x0010 /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation is not have this value to be at least size of word. */ - -#define PSTORAGE_DATA_START_ADDR ((PSTORAGE_FLASH_PAGE_END - PSTORAGE_NUM_OF_PAGES - 1) \ - * PSTORAGE_FLASH_PAGE_SIZE) /**< Start address for persistent data, configurable according to system requirements. */ -#define PSTORAGE_DATA_END_ADDR ((PSTORAGE_FLASH_PAGE_END - 1) * PSTORAGE_FLASH_PAGE_SIZE) /**< End address for persistent data, configurable according to system requirements. */ -#define PSTORAGE_SWAP_ADDR PSTORAGE_DATA_END_ADDR /**< Top-most page is used as swap area for clear and update. */ - -#define PSTORAGE_MAX_BLOCK_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. And should be greater than or equal to the minimum size. */ -#define PSTORAGE_CMD_QUEUE_SIZE 10 /**< Maximum number of flash access commands that can be maintained by the module for all applications. Configurable. */ - - -/** Abstracts persistently memory block identifier. */ -typedef uint32_t pstorage_block_t; - -typedef struct -{ - uint32_t module_id; /**< Module ID.*/ - pstorage_block_t block_id; /**< Block ID.*/ -} pstorage_handle_t; - -typedef uint16_t pstorage_size_t; /** Size of length and offset fields. */ - -/**@brief Handles Flash Access Result Events. To be called in the system event dispatcher of the application. */ -void pstorage_sys_event_handler (uint32_t sys_evt); - -#endif // PSTORAGE_PL_H__ - -/** @} */ -/** @endcond */ diff --git a/components/drivers_nrf/pstorage/pstorage.c b/components/drivers_nrf/pstorage/pstorage.c deleted file mode 100644 index a1e08b7..0000000 --- a/components/drivers_nrf/pstorage/pstorage.c +++ /dev/null @@ -1,1572 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "pstorage.h" -#include -#include -#include -#include "nordic_common.h" -#include "nrf_error.h" -#include "nrf_assert.h" -#include "nrf.h" -#include "nrf_soc.h" -#include "app_util.h" -#include "app_error.h" - -#define INVALID_OPCODE 0x00 /**< Invalid op code identifier. */ -#define SOC_MAX_WRITE_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum write size allowed for a single call to \ref sd_flash_write as specified in the SoC API. */ -#define RAW_MODE_APP_ID (PSTORAGE_NUM_OF_PAGES + 1) /**< Application id for raw mode. */ - -#if defined(NRF52) -#define SD_CMD_MAX_TRIES 1000 /**< Number of times to try a softdevice flash operatoion, specific for nRF52 to account for longest time of flash page erase*/ -#else -#define SD_CMD_MAX_TRIES 3 /**< Number of times to try a softdevice flash operation when the @ref NRF_EVT_FLASH_OPERATION_ERROR sys_evt is received. */ -#endif /* defined(NRF52) */ - -#define MASK_TAIL_SWAP_DONE (1 << 0) /**< Flag for checking if the tail restore area has been written to swap page. */ -#define MASK_SINGLE_PAGE_OPERATION (1 << 1) /**< Flag for checking if command is a single flash page operation. */ -#define MASK_MODULE_INITIALIZED (1 << 2) /**< Flag for checking if the module has been initialized. */ -#define MASK_FLASH_API_ERR_BUSY (1 << 3) /**< Flag for checking if flash API returned NRF_ERROR_BUSY. */ - -/** - * @defgroup api_param_check API Parameters check macros. - * - * @details Macros that verify parameters passed to the module in the APIs. These macros - * could be mapped to nothing in final code versions to save execution and size. - * - * @{ - */ - -/**@brief Check if the input pointer is NULL, if so it returns NRF_ERROR_NULL. - */ -#define NULL_PARAM_CHECK(PARAM) \ - if ((PARAM) == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } - -/**@brief Verifies that the module identifier supplied by the application is within permissible - * range. - */ -#define MODULE_ID_RANGE_CHECK(ID) \ - if ((((ID)->module_id) >= PSTORAGE_NUM_OF_PAGES) || \ - (m_app_table[(ID)->module_id].cb == NULL)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@brief Verifies that the block identifier supplied by the application is within the permissible - * range. - */ -#define BLOCK_ID_RANGE_CHECK(ID) \ - if (((ID)->block_id) >= (m_app_table[(ID)->module_id].base_id + \ - (m_app_table[(ID)->module_id].block_count * MODULE_BLOCK_SIZE(ID)))) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@brief Verifies that the block size requested by the application can be supported by the module. - */ -#define BLOCK_SIZE_CHECK(X) \ - if (((X) > PSTORAGE_MAX_BLOCK_SIZE) || ((X) < PSTORAGE_MIN_BLOCK_SIZE)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@brief Verifies the block size requested by the application in registration API. - */ -#define BLOCK_COUNT_CHECK(COUNT, SIZE) \ - if (((COUNT) == 0) || \ - ((m_next_page_addr + ((COUNT) *(SIZE)) > PSTORAGE_SWAP_ADDR))) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@brief Verifies the size parameter provided by the application in API. - */ -#define SIZE_CHECK(ID, SIZE) \ - if(((SIZE) == 0) || ((SIZE) > MODULE_BLOCK_SIZE(ID))) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@brief Verifies the offset parameter provided by the application in API. - */ -#define OFFSET_CHECK(ID, OFFSET, SIZE) \ - if(((SIZE) + (OFFSET)) > MODULE_BLOCK_SIZE(ID)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -#ifdef PSTORAGE_RAW_MODE_ENABLE - -/**@brief Verifies the module identifier supplied by the application. - */ -#define MODULE_RAW_HANDLE_CHECK(ID) \ - if ((((ID)->module_id) != RAW_MODE_APP_ID)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -#endif // PSTORAGE_RAW_MODE_ENABLE - -/**@} */ - - -/**@brief Verify module's initialization status. - * - * @details Verify module's initialization status. Returns NRF_ERROR_INVALID_STATE when a - * module API is called without initializing the module. - */ -#define VERIFY_MODULE_INITIALIZED() \ - do \ - { \ - if (!(m_flags & MASK_MODULE_INITIALIZED)) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ - } while(0) - -/**@brief Macro to fetch the block size registered for the module. */ -#define MODULE_BLOCK_SIZE(ID) (m_app_table[(ID)->module_id].block_size) - -/**@brief Main state machine of the component. */ -typedef enum -{ - STATE_IDLE, /**< State for being idle (no command execution in progress). */ - STATE_STORE, /**< State for storing data when using store/update API. */ - STATE_DATA_ERASE_WITH_SWAP, /**< State for erasing the data page when using update/clear API when use of swap page is required. */ - STATE_DATA_ERASE, /**< State for erasing the data page when using update/clear API without the need to use the swap page. */ - STATE_ERROR /**< State entered when command processing is terminated abnormally. */ -} pstorage_state_t; - -/**@brief Sub state machine contained by @ref STATE_DATA_ERASE_WITH_SWAP super state machine. */ -typedef enum -{ - STATE_ERASE_SWAP, /**< State for erasing the swap page when using the update/clear API. */ - STATE_WRITE_DATA_TO_SWAP, /**< State for writing the data page into the swap page when using update/clear API. */ - STATE_ERASE_DATA_PAGE, /**< State for erasing data page when using update/clear API. */ - STATE_RESTORE_TAIL, /**< State for restoring tail (end) of backed up data from swap to data page when using update/clear API. */ - STATE_RESTORE_HEAD, /**< State for restoring head (beginning) of backed up data from swap to data page when using update/clear API. */ - SWAP_SUB_STATE_MAX /**< Enumeration upper bound. */ -} flash_swap_sub_state_t; - -/**@brief Application registration information. - * - * @details Defines application specific information that the application needs to maintain to be able - * to process requests from each one of them. - */ -typedef struct -{ - pstorage_ntf_cb_t cb; /**< Callback registered with the module to be notified of result of flash access. */ - pstorage_block_t base_id; /**< Base block ID assigned to the module. */ - pstorage_size_t block_size; /**< Size of block for the module. */ - pstorage_size_t block_count; /**< Number of blocks requested by the application. */ -} pstorage_module_table_t; - - -#ifdef PSTORAGE_RAW_MODE_ENABLE -/**@brief Application registration information. - * - * @details Defines application specific information that the application registered for raw mode. - */ -typedef struct -{ - pstorage_ntf_cb_t cb; /**< Callback registered with the module to be notified of the result of flash access. */ -} pstorage_raw_module_table_t; -#endif // PSTORAGE_RAW_MODE_ENABLE - - -/**@brief Defines command queue element. - * - * @details Defines command queue element. Each element encapsulates needed information to process - * a flash access command. - */ -typedef struct -{ - uint8_t op_code; /**< Identifies the flash access operation being queued. Element is free if op-code is INVALID_OPCODE. */ - pstorage_size_t size; /**< Identifies the size in bytes requested for the operation. */ - pstorage_size_t offset; /**< Offset requested by the application for the access operation. */ - pstorage_handle_t storage_addr; /**< Address/Identifier for persistent memory. */ - uint8_t * p_data_addr; /**< Address/Identifier for data memory. This is assumed to be resident memory. */ -} cmd_queue_element_t; - - -/**@brief Defines command queue, an element is free if the op_code field is not invalid. - * - * @details Defines commands enqueued for flash access. At any point in time, this queue has one or - * more flash access operations pending if the count field is not zero. When the queue is - * not empty, the rp (read pointer) field points to the flash access command in progress - * or, if none is in progress, the command to be requested next. The queue implements a - * simple first in first out algorithm. Data addresses are assumed to be resident. - */ -typedef struct -{ - uint8_t rp; /**< Read pointer, pointing to flash access that is ongoing or to be requested next. */ - uint8_t count; /**< Number of elements in the queue. */ - cmd_queue_element_t cmd[PSTORAGE_CMD_QUEUE_SIZE]; /**< Array to maintain flash access operation details. */ -} cmd_queue_t; - -static cmd_queue_t m_cmd_queue; /**< Flash operation request queue. */ -static pstorage_size_t m_next_app_instance; /**< Points to the application module instance that can be allocated next. */ -static uint32_t m_next_page_addr; /**< Points to the flash address that can be allocated to a module next. This is needed as blocks of a module that can span across flash pages. */ -static pstorage_state_t m_state; /**< Main state tracking variable. */ -static flash_swap_sub_state_t m_swap_sub_state; /**< Flash swap erase when swap used state tracking variable. */ -static uint32_t m_head_word_size; /**< Head restore area size in words. */ -static uint32_t m_tail_word_size; /**< Tail restore area size in words. */ -static uint32_t m_current_page_id; /**< Variable for tracking the flash page being processed. */ -static uint32_t m_num_of_command_retries; /**< Variable for tracking flash operation retries upon flash operation failures. */ -static pstorage_module_table_t m_app_table[PSTORAGE_NUM_OF_PAGES]; /**< Registered application information table. */ -static uint32_t m_num_of_bytes_written; /**< Variable for tracking the number of bytes written by the store operation. */ -static uint32_t m_app_data_size; /**< Variable for storing the application command size parameter internally. */ -static uint32_t m_flags = 0; /**< Storage for boolean flags for state tracking. */ - -#ifdef PSTORAGE_RAW_MODE_ENABLE -static pstorage_raw_module_table_t m_raw_app_table; /**< Registered application information table for raw mode. */ -#endif // PSTORAGE_RAW_MODE_ENABLE - -// Required forward declarations. -static void cmd_process(void); -static void store_operation_execute(void); -static void app_notify(uint32_t result, cmd_queue_element_t * p_elem); -static void cmd_queue_element_init(uint32_t index); -static void cmd_queue_dequeue(void); -static void sm_state_change(pstorage_state_t new_state); -static void swap_sub_state_state_change(flash_swap_sub_state_t new_state); - -/**@brief Function for consuming a command queue element. - * - * @details Function for consuming a command queue element, which has been fully processed. - */ -static void command_queue_element_consume(void) -{ - // Initialize/free the element as it is now processed. - cmd_queue_element_init(m_cmd_queue.rp); - - // Adjust command queue state tracking variables. - --(m_cmd_queue.count); - if (++(m_cmd_queue.rp) == PSTORAGE_CMD_QUEUE_SIZE) - { - m_cmd_queue.rp = 0; - } -} - - -/**@brief Function for executing the finalization procedure for the command executed. - * - * @details Function for executing the finalization procedure for command executed, which includes - * notifying the application of command completion, consuming the command queue element, - * and changing the internal state. - */ -static void command_end_procedure_run(void) -{ - app_notify(NRF_SUCCESS, &m_cmd_queue.cmd[m_cmd_queue.rp]); - - command_queue_element_consume(); - - sm_state_change(STATE_IDLE); -} - - -/**@brief Function for idle state entry actions. - * - * @details Function for idle state entry actions, which include resetting relevant state data and - * scheduling any possible queued flash access operation. - */ -static void state_idle_entry_run(void) -{ - m_num_of_command_retries = 0; - m_num_of_bytes_written = 0; - - // Schedule any possible queued flash access operation. - cmd_queue_dequeue(); -} - - -/**@brief Function for notifying an application of command completion and transitioning to an error - * state. - * - * @param[in] result Result code of the operation for the application. - */ -static void app_notify_error_state_transit(uint32_t result) -{ - app_notify(result, &m_cmd_queue.cmd[m_cmd_queue.rp]); - sm_state_change(STATE_ERROR); -} - - -/**@brief Function for processing flash API error code. - * - * @param[in] err_code Error code from the flash API. - */ -static void flash_api_err_code_process(uint32_t err_code) -{ - switch (err_code) - { - case NRF_SUCCESS: - break; - - case NRF_ERROR_BUSY: - // Flash access operation was not accepted and must be reissued upon flash operation - // complete event. - m_flags |= MASK_FLASH_API_ERR_BUSY; - break; - - default: - // Complete the operation with appropriate result code and transit to an error state. - app_notify_error_state_transit(err_code); - break; - } -} - -/**@brief Function for writing data to flash. - * - * @param[in] p_dst Pointer to start of flash location to be written. - * @param[in] p_src Pointer to buffer with data to be written. - * @param[in] size_in_words Number of 32-bit words to write. - */ -static void flash_write(uint32_t * const p_dst, - uint32_t const * const p_src, - uint32_t size_in_words) -{ - flash_api_err_code_process(sd_flash_write(p_dst, p_src, size_in_words)); -} - - -/**@brief Function for writing data to flash upon store command. - * - * @details Function for writing data to flash upon executing store command. Data is written to - * flash in reverse order, meaning starting at the end. If the data that is to be written - * is greater than the flash page size, it will be fragmented to fit the flash page size. - */ -static void store_cmd_flash_write_execute(void) -{ - const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - - if (p_cmd->size > SOC_MAX_WRITE_SIZE) - { - const uint32_t offset = p_cmd->size - PSTORAGE_FLASH_PAGE_SIZE; - flash_write((uint32_t *)(p_cmd->storage_addr.block_id + p_cmd->offset + offset), - (uint32_t *)(p_cmd->p_data_addr + offset), - PSTORAGE_FLASH_PAGE_SIZE / sizeof(uint32_t)); - - m_num_of_bytes_written = PSTORAGE_FLASH_PAGE_SIZE; - } - else - { - flash_write((uint32_t *)(p_cmd->storage_addr.block_id + p_cmd->offset), - (uint32_t *)(p_cmd->p_data_addr), - p_cmd->size / sizeof(uint32_t)); - - m_num_of_bytes_written = p_cmd->size; - } -} - - -/**@brief Function for store state entry action. - * - * @details Function for store state entry action, which includes writing data to a flash page. - */ -static void state_store_entry_run(void) -{ - store_cmd_flash_write_execute(); -} - - -/**@brief Function for data erase with swap state entry actions. - * - * @details Function for data erase with swap state entry actions. This includes adjusting relevant - * state and data variables and transitioning to the correct sub state. - */ -static void state_data_erase_swap_entry_run(void) -{ - m_flags &= ~MASK_TAIL_SWAP_DONE; - - const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - const pstorage_block_t cmd_block_id = p_cmd->storage_addr.block_id; - - const uint32_t clear_start_page_id = cmd_block_id / PSTORAGE_FLASH_PAGE_SIZE; - m_current_page_id = clear_start_page_id; - - // @note: No need to include p_cmd->offset when calculating clear_end_page_id as: - // - clear API does not include offset parameter - // - update and store APIs are limited to operate on single block boundary thus the boolean - // clause ((m_head_word_size == 0) && is_more_than_one_page) below in this function will never - // evaluate as true as if is_more_than_one_page == true m_head_word_size is always != 0 - const uint32_t clear_end_page_id = (cmd_block_id + p_cmd->size - 1u) / - PSTORAGE_FLASH_PAGE_SIZE; - - if (clear_start_page_id == clear_end_page_id) - { - m_flags |= MASK_SINGLE_PAGE_OPERATION; - } - else - { - m_flags &= ~MASK_SINGLE_PAGE_OPERATION; - } - - if ((m_head_word_size == 0) && !(m_flags & MASK_SINGLE_PAGE_OPERATION)) - { - // No head restore required and clear/update area is shared by multiple flash pages, which - // means the current flash page does not have any tail area to restore. You can proceed with - // data page erase directly as no swap is needed for the current flash page. - swap_sub_state_state_change(STATE_ERASE_DATA_PAGE); - } - else - { - swap_sub_state_state_change(STATE_ERASE_SWAP); - } -} - - -/**@brief Function for erasing flash page. - * - * @param[in] page_number Page number of the page to be erased. - */ -static void flash_page_erase(uint32_t page_number) -{ - flash_api_err_code_process(sd_flash_page_erase(page_number)); -} - - -/**@brief Function for data erase state entry action. - * - * @details Function for data erase state entry action, which includes erasing the data flash page. - */ -static void state_data_erase_entry_run(void) -{ - flash_page_erase(m_current_page_id); -} - - -/**@brief Function for dispatching the correct application main state entry action. - */ -static void state_entry_action_run(void) -{ - switch (m_state) - { - case STATE_IDLE: - state_idle_entry_run(); - break; - - case STATE_STORE: - state_store_entry_run(); - break; - - case STATE_DATA_ERASE_WITH_SWAP: - state_data_erase_swap_entry_run(); - break; - - case STATE_DATA_ERASE: - state_data_erase_entry_run(); - break; - - default: - // No action needed. - break; - } -} - - -/**@brief Function for changing application main state and dispatching state entry action. - * - * @param[in] new_state New application main state to transit to. - */ -static void sm_state_change(pstorage_state_t new_state) -{ - m_state = new_state; - state_entry_action_run(); -} - - -/**@brief Function for swap erase state entry action. - * - * @details Function for swap erase state entry action, which includes erasing swap flash - * page. - */ -static void state_swap_erase_entry_run(void) -{ - flash_page_erase(PSTORAGE_SWAP_ADDR / PSTORAGE_FLASH_PAGE_SIZE); -} - - -/**@brief Function for write data to the swap state entry action. - * - * @details Function for write data to the swap state entry action, which includes writing the - * current data page to the swap flash page. - */ -static void state_write_data_swap_entry_run(void) -{ - // @note: There is room for further optimization here as there is only need to write the - // whole flash page to swap area if there is both head and tail area to be restored. In any - // other case we can omit some data from the head or end of the page as that is the clear area. - flash_write((uint32_t *)(PSTORAGE_SWAP_ADDR), - (uint32_t *)(m_current_page_id * PSTORAGE_FLASH_PAGE_SIZE), - PSTORAGE_FLASH_PAGE_SIZE / sizeof(uint32_t)); -} - - -/**@brief Function for erase data page state entry action. - * - * @details Function for erase data page state entry action, which includes erasing the data flash - * page. - */ -static void state_erase_data_page_entry_run(void) -{ - flash_page_erase(m_current_page_id); -} - - -/**@brief Function for restore tail state entry action. - * - * @details Function for restore tail state entry action, which includes writing the tail section - * back from swap to the data page. - */ -static void state_restore_tail_entry_run(void) -{ - const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - const pstorage_block_t cmd_block_id = p_cmd->storage_addr.block_id; - - const uint32_t tail_offset = (cmd_block_id + p_cmd->size + p_cmd->offset) % - PSTORAGE_FLASH_PAGE_SIZE; - - flash_write((uint32_t *)(cmd_block_id + p_cmd->size + p_cmd->offset), - (uint32_t *)(PSTORAGE_SWAP_ADDR + tail_offset), - m_tail_word_size); -} - - -/**@brief Function for restore head state entry action. - * - * @details Function for restore head state entry action, which includes writing the head section - * back from swap to the data page. - */ -static void state_restore_head_entry_run(void) -{ - flash_write((uint32_t *)((m_current_page_id - 1u) * PSTORAGE_FLASH_PAGE_SIZE), - (uint32_t *)PSTORAGE_SWAP_ADDR, - m_head_word_size); -} - - -/**@brief Function for dispatching the correct swap sub state entry action. - */ -static void swap_sub_state_entry_action_run(void) -{ - static void (* const swap_sub_state_sm_lut[SWAP_SUB_STATE_MAX])(void) = - { - state_swap_erase_entry_run, - state_write_data_swap_entry_run, - state_erase_data_page_entry_run, - state_restore_tail_entry_run, - state_restore_head_entry_run - }; - - swap_sub_state_sm_lut[m_swap_sub_state](); -} - - -/**@brief Function for changing the swap sub state and dispatching state entry action. - * - * @param[in] new_state New swap sub state to transit to. - */ -static void swap_sub_state_state_change(flash_swap_sub_state_t new_state) -{ - m_swap_sub_state = new_state; - swap_sub_state_entry_action_run(); -} - - -/**@brief Function for initializing the command queue element. - * - * @param[in] index Index of the element to be initialized. - */ -static void cmd_queue_element_init(uint32_t index) -{ - // Internal function and checks on range of index can be avoided. - m_cmd_queue.cmd[index].op_code = INVALID_OPCODE; - m_cmd_queue.cmd[index].size = 0; - m_cmd_queue.cmd[index].storage_addr.module_id = PSTORAGE_NUM_OF_PAGES; - m_cmd_queue.cmd[index].storage_addr.block_id = 0; - m_cmd_queue.cmd[index].p_data_addr = NULL; - m_cmd_queue.cmd[index].offset = 0; -} - - -/**@brief Function for initializing the command queue. - */ -static void cmd_queue_init(void) -{ - m_cmd_queue.rp = 0; - m_cmd_queue.count = 0; - - for (uint32_t cmd_index = 0; cmd_index < PSTORAGE_CMD_QUEUE_SIZE; ++cmd_index) - { - cmd_queue_element_init(cmd_index); - } -} - - -/**@brief Function for enqueuing, and possibly dispatching, a flash access operation. - * - * @param[in] opcode Identifies the operation requested to be enqueued. - * @param[in] p_storage_addr Identifies the module and flash address on which the operation is - * requested. - * @param[in] p_data_addr Identifies the data address for flash access. - * @param[in] size Size in bytes of data requested for the access operation. - * @param[in] offset Offset within the flash memory block at which operation is requested. - * - * @retval NRF_SUCCESS Upon success. - * @retval NRF_ERROR_NO_MEM Upon failure, when no space is available in the command queue. - */ -static uint32_t cmd_queue_enqueue(uint8_t opcode, - pstorage_handle_t * p_storage_addr, - uint8_t * p_data_addr, - pstorage_size_t size, - pstorage_size_t offset) -{ - uint32_t err_code; - - if (m_cmd_queue.count != PSTORAGE_CMD_QUEUE_SIZE) - { - // Enqueue the command if it the queue is not full. - uint32_t write_index = m_cmd_queue.rp + m_cmd_queue.count; - - if (write_index >= PSTORAGE_CMD_QUEUE_SIZE) - { - write_index -= PSTORAGE_CMD_QUEUE_SIZE; - } - - m_cmd_queue.cmd[write_index].op_code = opcode; - m_cmd_queue.cmd[write_index].p_data_addr = p_data_addr; - m_cmd_queue.cmd[write_index].storage_addr = (*p_storage_addr); - m_cmd_queue.cmd[write_index].size = size; - m_cmd_queue.cmd[write_index].offset = offset; - - m_cmd_queue.count++; - - if (m_state == STATE_IDLE) - { - cmd_process(); - } - - err_code = NRF_SUCCESS; - } - else - { - err_code = NRF_ERROR_NO_MEM; - } - - return err_code; -} - - -/**@brief Function for dequeing a possible pending flash access operation. - */ -static void cmd_queue_dequeue(void) -{ - if ((m_cmd_queue.count != 0)) - { - cmd_process(); - } -} - - -/**@brief Function for notifying an application of command completion. - * - * @param[in] result Result code of the operation for the application. - * @param[in] p_elem Pointer to the command queue element for which this result was received. - */ -static void app_notify(uint32_t result, cmd_queue_element_t * p_elem) -{ - pstorage_ntf_cb_t ntf_cb; - const uint8_t op_code = p_elem->op_code; - -#ifdef PSTORAGE_RAW_MODE_ENABLE - if (p_elem->storage_addr.module_id == RAW_MODE_APP_ID) - { - ntf_cb = m_raw_app_table.cb; - } - else -#endif // PSTORAGE_RAW_MODE_ENABLE - { - ntf_cb = m_app_table[p_elem->storage_addr.module_id].cb; - } - - ntf_cb(&p_elem->storage_addr, op_code, result, p_elem->p_data_addr, m_app_data_size); -} - - -/**@brief Function for evaluating if a data page swap is required for the tail section on the - * current page. - * - * @retval true If data page swap is required. - * @retval false If data page swap is not required. - */ -static bool is_tail_data_page_swap_required(void) -{ - bool ret_value; - - // Extract id of the last page command is executed upon. - const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - const pstorage_block_t cmd_block_id = p_cmd->storage_addr.block_id; - const uint32_t last_page_id = (cmd_block_id + p_cmd->size + p_cmd->offset - 1u) / - PSTORAGE_FLASH_PAGE_SIZE; - - // If tail section area exists and the current page is the last page then tail data page swap is - // required. - if ((m_tail_word_size != 0) && (m_current_page_id == last_page_id)) - { - ret_value = true; - } - else - { - ret_value = false; - } - - return ret_value; -} - - -/**@brief Function for performing post processing for the update and clear commands. - * - * @details Function for performing post processing for the update and clear commands, which implies - * executing the correct execution path depending on the command. - */ -static void clear_post_processing_run(void) -{ - const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - - if (p_cmd->op_code != PSTORAGE_UPDATE_OP_CODE) - { - command_end_procedure_run(); - } - else - { - store_operation_execute(); - } -} - - -/**@brief Function for doing swap sub state exit action. - */ -static void swap_sub_sm_exit_action_run(void) -{ - clear_post_processing_run(); -} - - -/**@brief Function for evaluating if the page erase operation is required for the current page. - * - * @retval true If page erase is required. - * @retval false If page erase is not required. - */ -static bool is_page_erase_required(void) -{ - bool ret; - - const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - const pstorage_block_t cmd_block_id = p_cmd->storage_addr.block_id; - const uint32_t id_last_page_to_be_cleared = (cmd_block_id + p_cmd->size + - p_cmd->offset - 1u) / - PSTORAGE_FLASH_PAGE_SIZE; - - // True if: - // - current page is not the last page OR - // - current page is the last page AND no tail exists - if ((m_current_page_id < id_last_page_to_be_cleared) || - ((m_current_page_id == id_last_page_to_be_cleared) && (m_tail_word_size == 0))) - { - ret = true; - } - else - { - ret = false; - } - - return ret; -} - - -/**@brief Function for reissuing the last flash operation request, which was rejected by the flash - * API, in swap sub sate. - */ -static void swap_sub_state_err_busy_process(void) -{ - // Reissue the request by doing a self transition to the current state. - m_flags &= ~MASK_FLASH_API_ERR_BUSY; - swap_sub_state_state_change(m_swap_sub_state); -} - - -/**@brief Function for doing restore head state action upon flash operation success event. - * - * @details Function for doing restore head state action upon flash operation success event, which - * includes making a state transition depending on the current state. - */ -static void head_restore_state_run(void) -{ - if (!(m_flags & MASK_FLASH_API_ERR_BUSY)) - { - if (is_tail_data_page_swap_required()) - { - // Additional data page needs to be swapped for tail section as we are clearing a block, - // which is shared between 2 flash pages. - - // Adjust variables to ensure correct state transition path is taken after the tail - // section swap has completed. - m_head_word_size = 0; - m_flags |= MASK_TAIL_SWAP_DONE; - - swap_sub_state_state_change(STATE_ERASE_SWAP); - } - else if (is_page_erase_required()) - { - // Additional page erase operation is required. - - // Adjust variable to ensure correct state transition path is taken after the additional - // page erase operation has completed. - m_head_word_size = 0; - swap_sub_state_state_change(STATE_ERASE_DATA_PAGE); - } - else if (m_tail_word_size != 0) - { - // Proceed with restoring tail from swap to data page. - swap_sub_state_state_change(STATE_RESTORE_TAIL); - } - else - { - // Swap statemachine execution end reached. - swap_sub_sm_exit_action_run(); - } - } - else - { - // As operation request was rejected by the flash API reissue the request. - swap_sub_state_err_busy_process(); - } -} - - -/**@brief Function for doing restore tail state action upon flash operation success event. - */ -static void tail_restore_state_run(void) -{ - if (!(m_flags & MASK_FLASH_API_ERR_BUSY)) - { - swap_sub_sm_exit_action_run(); - } - else - { - // As operation request was rejected by the flash API reissue the request. - swap_sub_state_err_busy_process(); - } -} - - -/**@brief Function for doing data page erase state action upon a flash operation success event. - * - * @details Function for doing data page erase state action upon a flash operation success event, - * which includes making a state transit to a new state depending on the current state. - */ -static void data_page_erase_state_run(void) -{ - if (!(m_flags & MASK_FLASH_API_ERR_BUSY)) - { - ++m_current_page_id; - - if (m_head_word_size != 0) - { - swap_sub_state_state_change(STATE_RESTORE_HEAD); - } - else if (is_page_erase_required()) - { - // Additional page erase operation is required. - swap_sub_state_state_change(STATE_ERASE_DATA_PAGE); - } - else if (m_tail_word_size != 0) - { - if (!(m_flags & MASK_TAIL_SWAP_DONE)) - { - // Tail area restore is required and we have not yet written the relevant data page - // to swap area. Start the process of writing the data page to swap. - m_flags |= MASK_TAIL_SWAP_DONE; - - swap_sub_state_state_change(STATE_ERASE_SWAP); - } - else - { - // Tail area restore is required and we have already written the relevant data page - // to swap area. Proceed by restoring the tail area. - swap_sub_state_state_change(STATE_RESTORE_TAIL); - } - } - else - { - swap_sub_sm_exit_action_run(); - } - } - else - { - // As operation request was rejected by the flash API reissue the request. - swap_sub_state_err_busy_process(); - } -} - - -/**@brief Function for doing data to swap write state action upon flash operation success event. - */ -static void data_to_swap_write_state_run(void) -{ - if (!(m_flags & MASK_FLASH_API_ERR_BUSY)) - { - // If the operation is executed only on 1 single flash page it automatically means that tail - // area is written to the swap, which we store to flags. - if (m_flags & MASK_SINGLE_PAGE_OPERATION) - { - m_flags |= MASK_TAIL_SWAP_DONE; - } - - swap_sub_state_state_change(STATE_ERASE_DATA_PAGE); - } - else - { - // As operation request was rejected by the flash API reissue the request. - swap_sub_state_err_busy_process(); - } -} - - -/**@brief Function for doing swap erase state action upon flash operation success event. - */ -static void swap_erase_state_run(void) -{ - if (!(m_flags & MASK_FLASH_API_ERR_BUSY)) - { - swap_sub_state_state_change(STATE_WRITE_DATA_TO_SWAP); - } - else - { - // As operation request was rejected by the flash API reissue the request. - swap_sub_state_err_busy_process(); - } -} - - -/**@brief Function for dispatching the correct state action for data erase with a swap composite -* state upon a flash operation success event. - */ -static void swap_sub_state_sm_run(void) -{ - static void (* const swap_sub_state_sm_lut[SWAP_SUB_STATE_MAX])(void) = - { - swap_erase_state_run, - data_to_swap_write_state_run, - data_page_erase_state_run, - tail_restore_state_run, - head_restore_state_run - }; - - swap_sub_state_sm_lut[m_swap_sub_state](); -} - - -/**@brief Function for reissuing the last flash operation request, which was rejected by the flash - * API, in main sate. - */ -static void main_state_err_busy_process(void) -{ - // Reissue the request by doing a self transition to the current state. - m_flags &= ~MASK_FLASH_API_ERR_BUSY; - sm_state_change(m_state); -} - - -/**@brief Function for doing erase state action upon flash operation success event. - * - * @details Function for doing erase state action upon flash operation success event, which includes - * making a state transition depending on the current state. - */ -static void erase_sub_state_sm_run(void) -{ - if (!(m_flags & MASK_FLASH_API_ERR_BUSY)) - { - // Clear operation request has succeeded. - ++m_current_page_id; - - if (!is_page_erase_required()) - { - clear_post_processing_run(); - } - else - { - // All required flash pages have not yet been erased, issue erase by doing a self - // transit. - sm_state_change(m_state); - } - } - else - { - // As operation request was rejected by the flash API reissue the request. - main_state_err_busy_process(); - } -} - - -/**@brief Function for doing store state action upon flash operation success event. - */ -static void store_sub_state_sm_run(void) -{ - if (!(m_flags & MASK_FLASH_API_ERR_BUSY)) - { - // As write operation request has succeeded, adjust the size tracking state information - // accordingly. - cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - p_cmd->size -= m_num_of_bytes_written; - - if (p_cmd->size == 0) - { - command_end_procedure_run(); - } - else - { - store_cmd_flash_write_execute(); - } - } - else - { - // As operation request was rejected by the flash API reissue the request. - main_state_err_busy_process(); - } -} - - -/**@brief Function for doing action upon flash operation success event. - */ -static void flash_operation_success_run(void) -{ - switch (m_state) - { - case STATE_STORE: - store_sub_state_sm_run(); - break; - - case STATE_DATA_ERASE: - erase_sub_state_sm_run(); - break; - - case STATE_DATA_ERASE_WITH_SWAP: - swap_sub_state_sm_run(); - break; - - default: - // No implementation needed. - break; - } -} - - -/**@brief Function for doing action upon flash operation failure event. - * - * @details Function for doing action upon flash operation failure event, which includes retrying - * the last operation or if retry count has been reached completing the operation with - * appropriate result code and transitioning to an error state. - * - * @note The command is not removed from the command queue, which will result to stalling of the - * command pipeline and the appropriate application recovery procedure for this is to reset - * the system by issuing @ref pstorage_init which will also result to flushing of the - * command queue. - */ -static void flash_operation_failure_run(void) -{ - if (++m_num_of_command_retries != SD_CMD_MAX_TRIES) - { - // Retry the last operation by doing a self transition to the current state. - - if (m_state != STATE_DATA_ERASE_WITH_SWAP) - { - sm_state_change(m_state); - } - else - { - swap_sub_state_state_change(m_swap_sub_state); - } - } - else - { - // Complete the operation with appropriate result code and transit to an error state. - app_notify_error_state_transit(NRF_ERROR_TIMEOUT); - } -} - - -/**@brief Function for handling flash access result events. - * - * @param[in] sys_evt System event to be handled. - */ -void pstorage_sys_event_handler(uint32_t sys_evt) -{ - if (m_state != STATE_IDLE && m_state != STATE_ERROR) - { - switch (sys_evt) - { - case NRF_EVT_FLASH_OPERATION_SUCCESS: - flash_operation_success_run(); - break; - - case NRF_EVT_FLASH_OPERATION_ERROR: - if (!(m_flags & MASK_FLASH_API_ERR_BUSY)) - { - flash_operation_failure_run(); - } - else - { - // As our last flash operation request was rejected by the flash API reissue the - // request by doing same code execution path as for flash operation sucess - // event. This will promote code reuse in the implementation. - flash_operation_success_run(); - } - break; - - default: - // No implementation needed. - break; - } - - } -} - - -/**@brief Function for calculating the tail area size in number of 32-bit words. - * - * @param[in] cmd_end_of_storage_address End of storage area within the scope of the command. - * @param[in] end_of_storage_address End of allocated storage area for the application. - */ -static void tail_word_size_calculate(pstorage_size_t cmd_end_of_storage_address, - pstorage_size_t end_of_storage_address) -{ - // Two different cases to resolve when calculating correct size for restore tail section: - // 1) End of storage area and command end area are in the same page. - // 2) End of storage area and command end area are not in the same page. - - const uint32_t end_of_storage_area_page = end_of_storage_address / - PSTORAGE_FLASH_PAGE_SIZE; - const uint32_t command_end_of_storage_area_page = cmd_end_of_storage_address / - PSTORAGE_FLASH_PAGE_SIZE; - - if (end_of_storage_area_page == command_end_of_storage_area_page) - { - //lint -e{573} suppress "Signed-unsigned mix with divide". - m_tail_word_size = (end_of_storage_address - cmd_end_of_storage_address) / sizeof(uint32_t); - } - else - { - //lint -e{573} suppress "Signed-unsigned mix with divide". - m_tail_word_size = (PSTORAGE_FLASH_PAGE_SIZE - - (cmd_end_of_storage_address % PSTORAGE_FLASH_PAGE_SIZE)) / - sizeof(uint32_t); - } -} - - -/**@brief Function for executing the clear operation. - */ -static void clear_operation_execute(void) -{ - const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - const pstorage_block_t cmd_block_id = p_cmd->storage_addr.block_id; - - const pstorage_size_t block_size = m_app_table[p_cmd->storage_addr.module_id].block_size; - const pstorage_size_t block_count = m_app_table[p_cmd->storage_addr.module_id].block_count; - const pstorage_block_t block_base_id = m_app_table[p_cmd->storage_addr.module_id].base_id; - - const bool is_start_address_page_aligned = (cmd_block_id % PSTORAGE_FLASH_PAGE_SIZE) == 0; - - // Calculate the end (1 beyond allocated area) for complete storage area and to the area only - // within scope of this command. - const pstorage_block_t end_of_storage_address = block_base_id + (block_size * block_count); - const pstorage_block_t cmd_end_of_storage_address = cmd_block_id + p_cmd->size + p_cmd->offset; - - // Zero tail to make sure no extra erase is done erroneously. - m_tail_word_size = 0; - - // If the following is true no swap access is needed: - // - 1st logical test covers the case of: clear/update 1 complete single page. - // - 2nd logical test covers the case of: - // 1) Clear/update last allocated page and page is not full (page can't be shared between - // multiple clients so the end of the page is unused area). - // 2) Clear/update all allocated storage. - if ((is_start_address_page_aligned && (p_cmd->size == PSTORAGE_FLASH_PAGE_SIZE)) || - (is_start_address_page_aligned && (cmd_end_of_storage_address == end_of_storage_address) && - (p_cmd->offset == 0)) || (p_cmd->storage_addr.module_id == RAW_MODE_APP_ID)) - { - // Nothing to put to the swap and we can just erase the pages(s). - - m_current_page_id = cmd_block_id / PSTORAGE_FLASH_PAGE_SIZE; - - sm_state_change(STATE_DATA_ERASE); - } - else - { - // Not all the blocks for the module can be cleared, we need to use swap page for storing - // data temporarily. - - m_head_word_size = ((cmd_block_id + p_cmd->offset) % PSTORAGE_FLASH_PAGE_SIZE) / - sizeof(uint32_t); - - const bool is_cmd_end_address_page_aligned = ((cmd_end_of_storage_address % - PSTORAGE_FLASH_PAGE_SIZE) == 0); - if ((cmd_end_of_storage_address != end_of_storage_address) && - !is_cmd_end_address_page_aligned) - { - // When command area is not equal to end of the storage allocation area and not ending - // to page boundary there is a need to restore the tail area. - tail_word_size_calculate(cmd_end_of_storage_address, end_of_storage_address); - } - - sm_state_change(STATE_DATA_ERASE_WITH_SWAP); - } -} - - -/**@brief Function for executing the store operation. - */ -static void store_operation_execute(void) -{ - sm_state_change(STATE_STORE); -} - - -/**@brief Function for executing the update operation. - */ -static void update_operation_execute(void) -{ - clear_operation_execute(); -} - - -/**@brief Function for dispatching the flash access operation. - */ -static void cmd_process(void) -{ - const cmd_queue_element_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - m_app_data_size = p_cmd->size; - - switch (p_cmd->op_code) - { - case PSTORAGE_STORE_OP_CODE: - store_operation_execute(); - break; - - case PSTORAGE_CLEAR_OP_CODE: - clear_operation_execute(); - break; - - case PSTORAGE_UPDATE_OP_CODE: - update_operation_execute(); - break; - - default: - // No action required. - break; - } -} - - -uint32_t pstorage_init(void) -{ - cmd_queue_init(); - - m_next_app_instance = 0; - m_next_page_addr = PSTORAGE_DATA_START_ADDR; - m_current_page_id = 0; - - for (uint32_t index = 0; index < PSTORAGE_NUM_OF_PAGES; index++) - { - m_app_table[index].cb = NULL; - m_app_table[index].block_size = 0; - m_app_table[index].block_count = 0; - } - -#ifdef PSTORAGE_RAW_MODE_ENABLE - m_raw_app_table.cb = NULL; -#endif //PSTORAGE_RAW_MODE_ENABLE - - m_state = STATE_IDLE; - m_num_of_command_retries = 0; - m_flags = 0; - m_num_of_bytes_written = 0; - m_flags |= MASK_MODULE_INITIALIZED; - - return NRF_SUCCESS; -} - - -uint32_t pstorage_register(pstorage_module_param_t * p_module_param, - pstorage_handle_t * p_block_id) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_module_param); - NULL_PARAM_CHECK(p_block_id); - NULL_PARAM_CHECK(p_module_param->cb); - BLOCK_SIZE_CHECK(p_module_param->block_size); - BLOCK_COUNT_CHECK(p_module_param->block_count, p_module_param->block_size); - - if (!((p_module_param->block_size % sizeof(uint32_t)) == 0)) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (m_next_app_instance == PSTORAGE_NUM_OF_PAGES) - { - return NRF_ERROR_NO_MEM; - } - - p_block_id->module_id = m_next_app_instance; - p_block_id->block_id = m_next_page_addr; - - m_app_table[m_next_app_instance].base_id = p_block_id->block_id; - m_app_table[m_next_app_instance].cb = p_module_param->cb; - m_app_table[m_next_app_instance].block_size = p_module_param->block_size; - m_app_table[m_next_app_instance].block_count = p_module_param->block_count; - - // Calculate number of flash pages allocated for the device and adjust next free page address. - /*lint -save -e666 */ - const uint32_t page_count = CEIL_DIV((p_module_param->block_size * p_module_param->block_count), - PSTORAGE_FLASH_PAGE_SIZE); - /*lint -restore */ - m_next_page_addr += page_count * PSTORAGE_FLASH_PAGE_SIZE; - - ++m_next_app_instance; - - return NRF_SUCCESS; -} - - -uint32_t pstorage_block_identifier_get(pstorage_handle_t * p_base_id, - pstorage_size_t block_num, - pstorage_handle_t * p_block_id) -{ - pstorage_handle_t temp_id; - - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_base_id); - NULL_PARAM_CHECK(p_block_id); - MODULE_ID_RANGE_CHECK(p_base_id); - - temp_id = (*p_base_id); - temp_id.block_id += (block_num * MODULE_BLOCK_SIZE(p_base_id)); - - BLOCK_ID_RANGE_CHECK(&temp_id); - - (*p_block_id) = temp_id; - - return NRF_SUCCESS; -} - - -uint32_t pstorage_store(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_src); - NULL_PARAM_CHECK(p_dest); - MODULE_ID_RANGE_CHECK(p_dest); - BLOCK_ID_RANGE_CHECK(p_dest); - SIZE_CHECK(p_dest, size); - OFFSET_CHECK(p_dest, offset, size); - - if ((!is_word_aligned(p_src)) || - (!is_word_aligned((void *)(uint32_t)offset)) || - (!is_word_aligned((uint32_t *)p_dest->block_id))) - { - return NRF_ERROR_INVALID_ADDR; - } - - return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset); -} - - -uint32_t pstorage_update(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_src); - NULL_PARAM_CHECK(p_dest); - MODULE_ID_RANGE_CHECK(p_dest); - BLOCK_ID_RANGE_CHECK(p_dest); - SIZE_CHECK(p_dest, size); - OFFSET_CHECK(p_dest, offset, size); - - if ((!is_word_aligned(p_src)) || - (!is_word_aligned((void *)(uint32_t)offset)) || - (!is_word_aligned((uint32_t *)p_dest->block_id))) - { - return NRF_ERROR_INVALID_ADDR; - } - - return cmd_queue_enqueue(PSTORAGE_UPDATE_OP_CODE, p_dest, p_src, size, offset); -} - - -uint32_t pstorage_load(uint8_t * p_dest, - pstorage_handle_t * p_src, - pstorage_size_t size, - pstorage_size_t offset) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_src); - NULL_PARAM_CHECK(p_dest); - MODULE_ID_RANGE_CHECK(p_src); - BLOCK_ID_RANGE_CHECK(p_src); - SIZE_CHECK(p_src, size); - OFFSET_CHECK(p_src, offset, size); - - if ((!is_word_aligned(p_dest)) || - (!is_word_aligned((void *)(uint32_t)offset)) || - (!is_word_aligned((uint32_t *)p_src->block_id))) - { - return NRF_ERROR_INVALID_ADDR; - } - - memcpy(p_dest, (((uint8_t *)p_src->block_id) + offset), size); - - m_app_table[p_src->module_id].cb(p_src, PSTORAGE_LOAD_OP_CODE, NRF_SUCCESS, p_dest, size); - - return NRF_SUCCESS; -} - - -uint32_t pstorage_clear(pstorage_handle_t * p_dest, pstorage_size_t size) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_dest); - MODULE_ID_RANGE_CHECK(p_dest); - BLOCK_ID_RANGE_CHECK(p_dest); - - if ((!is_word_aligned((uint32_t *)p_dest->block_id))) - { - return NRF_ERROR_INVALID_ADDR; - } - - // Check is the area starting from block_id multiple of block_size. - if ( - !( - ((p_dest->block_id - m_app_table[p_dest->module_id].base_id) % - m_app_table[p_dest->module_id].block_size) == 0 - ) - ) - { - return NRF_ERROR_INVALID_PARAM; - } - - // Check is requested size multiple of registered block size or 0. - if (((size % m_app_table[p_dest->module_id].block_size) != 0) || (size == 0)) - { - return NRF_ERROR_INVALID_PARAM; - } - - const uint32_t registered_allocation_size = m_app_table[p_dest->module_id].block_size * - m_app_table[p_dest->module_id].block_count; - - const pstorage_block_t clear_request_end_address = p_dest->block_id + size; - const pstorage_block_t allocation_end_address = m_app_table[p_dest->module_id].base_id + - registered_allocation_size; - // Check if request would lead to a buffer overrun. - if (clear_request_end_address > allocation_end_address) - { - return NRF_ERROR_INVALID_PARAM; - } - - return cmd_queue_enqueue(PSTORAGE_CLEAR_OP_CODE, p_dest, NULL, size, 0); -} - - -uint32_t pstorage_access_status_get(uint32_t * p_count) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_count); - - (*p_count) = m_cmd_queue.count; - - return NRF_SUCCESS; -} - -#ifdef PSTORAGE_RAW_MODE_ENABLE - -uint32_t pstorage_raw_register(pstorage_module_param_t * p_module_param, - pstorage_handle_t * p_block_id) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_module_param); - NULL_PARAM_CHECK(p_block_id); - NULL_PARAM_CHECK(p_module_param->cb); - - if (m_raw_app_table.cb != NULL) - { - return NRF_ERROR_NO_MEM; - } - - p_block_id->module_id = RAW_MODE_APP_ID; - m_raw_app_table.cb = p_module_param->cb; - - return NRF_SUCCESS; -} - - -uint32_t pstorage_raw_store(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_src); - NULL_PARAM_CHECK(p_dest); - MODULE_RAW_HANDLE_CHECK(p_dest); - - if (size == 0) - { - return NRF_ERROR_INVALID_PARAM; - } - - // Verify word alignment. - if ((!is_word_aligned(p_src)) || - (!is_word_aligned((void *)(uint32_t)size)) || - (!is_word_aligned((void *)(uint32_t)offset)) || - (!is_word_aligned((void *)(p_dest->block_id)))) - { - return NRF_ERROR_INVALID_ADDR; - } - - return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset); -} - - -uint32_t pstorage_raw_clear(pstorage_handle_t * p_dest, pstorage_size_t size) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_dest); - MODULE_RAW_HANDLE_CHECK(p_dest); - - if ((!is_word_aligned((uint32_t *)p_dest->block_id))) - { - return NRF_ERROR_INVALID_ADDR; - } - - return cmd_queue_enqueue(PSTORAGE_CLEAR_OP_CODE, p_dest, NULL, size, 0); -} - -#endif // PSTORAGE_RAW_MODE_ENABLE diff --git a/components/drivers_nrf/pstorage/pstorage.h b/components/drivers_nrf/pstorage/pstorage.h deleted file mode 100644 index d500599..0000000 --- a/components/drivers_nrf/pstorage/pstorage.h +++ /dev/null @@ -1,381 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup persistent_storage Persistent Storage Interface - * @{ - * @ingroup app_common - * @brief Abstracted flash interface. - * - * @details An abstracted interface is provided by the module to easily port the application and - * SDK modules to an alternate option. This ensures that the SDK and application are moved - * to alternate persistent storage instead of the one provided by default. - */ - -#ifndef PSTORAGE_H__ -#define PSTORAGE_H__ - -#include "pstorage_platform.h" - - -/**@defgroup ps_opcode Persistent Storage Access Operation Codes - * @{ - * @brief Persistent Storage Access Operation Codes. - * - * @details Persistent Storage Access Operation Codes are used by Persistent storage operation - * completion callback @ref pstorage_ntf_cb_t to identify the operation type requested by - * the application. - */ -#define PSTORAGE_STORE_OP_CODE 0x01 /**< Store Operation type. */ -#define PSTORAGE_LOAD_OP_CODE 0x02 /**< Load Operation type. */ -#define PSTORAGE_CLEAR_OP_CODE 0x03 /**< Clear Operation type. */ -#define PSTORAGE_UPDATE_OP_CODE 0x04 /**< Update Operation type. */ - -/**@} */ - -/**@defgroup pstorage_data_types Persistent Memory Interface Data Types - * @{ - * @brief Data Types needed for interfacing with persistent memory. - * - * @details Data Types needed for interfacing with persistent memory. - */ - -/**@brief Persistent storage operation completion callback function type. - * - * @details The persistent storage operation completion callback is used by the interface to report - * success or failure of a flash operation. Since data is not copied for a store operation, - * a callback is an indication that the resident memory can now be reused or freed. - * - * @param[in] handle Identifies the module and block for the callback that is received. - * @param[in] op_code Identifies the operation for the event that is notified. - * @param[in] result Identifies the result of a flash access operation. NRF_SUCCESS implies - * operation succeeded. - * - * @note Unmanaged (abnormal behaviour) error codes from the SoftDevice flash - * access API are forwarded as is and are expected to be handled by the - * application. For details refer to the implementation file and corresponding - * SoftDevice flash API documentation. - * - * @param[in] p_data Identifies the application data pointer. For a store operation, this points - * to the resident source of application memory that the application can now - * free or reuse. When there is a clear operation, this is NULL since no - * application pointer is needed for this operation. - * @param[in] data_len Length data the application provided for the operation. - */ -typedef void (*pstorage_ntf_cb_t)(pstorage_handle_t * p_handle, - uint8_t op_code, - uint32_t result, - uint8_t * p_data, - uint32_t data_len); - -/**@brief Struct containing module registration context. */ -typedef struct -{ - pstorage_ntf_cb_t cb; /**< Persistent storage operation completion callback function @ref pstorage_ntf_cb_t. */ - pstorage_size_t block_size; /**< Desired block size for persistent memory storage. For example, if a module has a table with 10 entries, and each entry is 64 bytes in size, - * it can request 10 blocks with a block size of 64 bytes. The module can also request one block that is 640 bytes depending - * on how it would like to access or alter the memory in persistent memory. - * The first option is preferred when it is a single entry that needs to be updated often and doesn't impact the other entries. - * The second option is preferred when table entries are not changed individually but have a common point of loading and storing - * data. */ - pstorage_size_t block_count; /** Number of blocks requested by the module; minimum values is 1. */ -} pstorage_module_param_t; - -/**@} */ - -/**@defgroup pstorage_routines Persistent Storage Access Routines - * @{ - * @brief Functions/Interface SDK modules used to persistently store data. - * - * @details Interface for the Application and SDK modules to load/store information persistently. - * Note: While implementation of each of the persistent storage access functions - * depends on the system and is specific to system/solution, the signature of the - * interface routines should not be altered. - */ - -/**@brief Function for initializing the module. - * - * @details Function for initializing the module. This function is called once before any other APIs - * of the module are used. - * - * @retval NRF_SUCCESS Operation success. - */ -uint32_t pstorage_init(void); - -/**@brief Function for registering with persistent storage interface. - * - * @param[in] p_module_param Module registration parameter. - * @param[out] p_block_id Block identifier to identify persistent memory blocks when - * registration succeeds. Application is expected to use the block IDs - * for subsequent operations on requested persistent memory. Maximum - * registrations permitted is determined by the configuration of the - * parameter PSTORAGE_NUM_OF_PAGES. If more than one memory block is - * requested, the identifier provided here is the base identifier for the - * first block and used to identify the subsequent block. The application - * uses \@ref pstorage_block_identifier_get with this base identifier and - * block number. Therefore if 10 blocks of size 64 are requested and the - * application wishes to store memory in the 6th block, it shall use - * \@ref pstorage_block_identifier_get with the base ID and provide a - * block number of 5. This way the application is only expected to - * remember the base block identifier. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module - * initialization. - * @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed. - * @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed. - * @retval NRF_ERROR_NO_MEM Operation failure. Additional registrations can't be - * supported. - */ -uint32_t pstorage_register(pstorage_module_param_t * p_module_param, - pstorage_handle_t * p_block_id); - -/**@brief Function for getting block ID with reference to base block identifier provided at the time - * of registration. - * - * @details Function to get the block ID with reference to base block identifier provided at the - * time of registration. - * If more than one memory block was requested when registering, the identifier provided - * here is the base identifier for the first block which is used to identify subsequent - * blocks. The application shall use this routine to get the block identifier, providing - * input as base identifier and block number. Therefore, if 10 blocks of size 64 are - * requested and the application wishes to store memory in the 6th block, it shall use - * \@ref pstorage_block_identifier_get with the base ID and provide a block number of 5. - * This way the application is only expected to remember the base block identifier. - * - * @param[in] p_base_id Base block ID received at the time of registration. - * @param[in] block_num Block Number, with first block numbered zero. - * @param[out] p_block_id Block identifier for the block number requested when the API succeeds. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module - * initialization. - * @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed. - * @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed. - */ -uint32_t pstorage_block_identifier_get(pstorage_handle_t * p_base_id, - pstorage_size_t block_num, - pstorage_handle_t * p_block_id); - -/**@brief Function for persistently storing data of length 'size' contained in the 'p_src' address - * in the storage module at 'p_dest' address. Equivalent to Storage Write. - * - * @param[in] p_dest Destination address where data is to be stored persistently. - * @param[in] p_src Source address containing data to be stored. API assumes this to be resident - * memory and no intermediate copy of data is made by the API. Must be word - * aligned. - * @param[in] size Size of data to be stored expressed in bytes. Must be word aligned and size + - * offset must be <= block size. - * @param[in] offset Offset in bytes to be applied when writing to the block. - * For example, if within a block of 100 bytes, the application wishes to - * write 20 bytes at an offset of 12, then this field should be set to 12. - * Must be word aligned. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module - * initialization. - * @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed. - * @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed. - * @retval NRF_ERROR_INVALID_ADDR Operation failure. Parameter is not aligned. - * @retval NRF_ERROR_NO_MEM Operation failure. No storage space available. - * - * @warning No copy of the data is made, meaning memory provided for the data source that is to - * be written to flash cannot be freed or reused by the application until this procedure - * is complete. The application is notified when the procedure is finished using the - * notification callback registered by the application. - */ -uint32_t pstorage_store(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset); - -/**@brief Function for updating persistently stored data of length 'size' contained in the 'p_src' - * address in the storage module at 'p_dest' address. - * - * @param[in] p_dest Destination address where data is to be updated. - * @param[in] p_src Source address containing data to be stored. API assumes this to be resident - * memory and no intermediate copy of data is made by the API. - * @param[in] size Size of data to be stored expressed in bytes. Must be word aligned and size + - * offset must be <= block size. - * @param[in] offset Offset in bytes to be applied when writing to the block. - * For example, if within a block of 100 bytes, the application wishes to - * write 20 bytes at an offset of 12 bytes, then this field should be set to 12. - * Must be word aligned. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module - * initialization. - * @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed. - * @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed. - * @retval NRF_ERROR_INVALID_ADDR Operation failure. Parameter is not aligned. - * @retval NRF_ERROR_NO_MEM Operation failure. No storage space available. - * - * @warning No copy of the data is made, meaning memory provided for the data source that is to - * be written to flash cannot be freed or reused by the application until this procedure - * is complete. The application is notified when the procedure is finished using the - * notification callback registered by the application. - */ -uint32_t pstorage_update(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset); - -/**@brief Function for loading persistently stored data of length 'size' from 'p_src' address - * to 'p_dest' address. Equivalent to Storage Read. - * - * @param[in] p_dest Destination address where persistently stored data is to be loaded. - * @param[in] p_src Source where data is loaded from persistent memory. - * @param[in] size Size of data to be loaded from persistent memory expressed in bytes. - * Should be word aligned. - * @param[in] offset Offset in bytes, to be applied when loading from the block. - * For example, if within a block of 100 bytes, the application wishes to - * load 20 bytes from offset of 12 bytes, then this field should be set to 12. - * Should be word aligned. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module - * initialization. - * @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed. - * @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed. - * @retval NRF_ERROR_INVALID_ADDR Operation failure. Parameter is not aligned. - * @retval NRF_ERROR_NO_MEM Operation failure. No storage space available. - */ -uint32_t pstorage_load(uint8_t * p_dest, - pstorage_handle_t * p_src, - pstorage_size_t size, - pstorage_size_t offset); - -/**@brief Function for clearing data in persistent memory. - * - * @param[in] p_base_id Base block identifier in persistent memory that needs to be cleared; - * equivalent to an Erase Operation. - * @param[in] size Size of data to be cleared from persistent memory expressed in bytes. - * This parameter is to provision for clearing of certain blocks - * of memory, or all memory blocks in a registered module. If the total size - * of the application module is used (blocks * block size) in combination with - * the identifier for the first block in the module, all blocks in the - * module will be erased. Must be multiple of block size. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module - * initialization. - * @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed. - * @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed. - * @retval NRF_ERROR_INVALID_ADDR Operation failure. Parameter is not aligned. - * @retval NRF_ERROR_NO_MEM Operation failure. No storage space available. - * - * @note Clear operations may take time. This API however, does not block until the clear - * procedure is complete. The application is notified of procedure completion using - * a notification callback registered by the application. The 'result' parameter of the - * callback indicates if the procedure was successful or not. - */ -uint32_t pstorage_clear(pstorage_handle_t * p_base_id, pstorage_size_t size); - -/**@brief Function for getting the number of pending operations with the module. - * - * @param[out] p_count Number of storage operations pending with the module. If 0, there are no - * outstanding requests. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module - * initialization. - * @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed. - */ -uint32_t pstorage_access_status_get(uint32_t * p_count); - -#ifdef PSTORAGE_RAW_MODE_ENABLE - -/**@brief Function for registering with the persistent storage interface. - * - * @param[in] p_module_param Module registration parameter. - * @param[out] p_block_id Block identifier used to identify persistent memory blocks upon - * successful registration. The application is expected to use the block - * IDs for subsequent operations on requested persistent memory. When - * more than one memory block is requested, this identifier is the base - * identifier for the first block and used to identify subsequent blocks. - * The application shall use \@ref pstorage_block_identifier_get with - * this base identifier and block number. Therefore if 10 blocks of size - * 64 are requested and the application wishes to store memory in the 6th - * block, it shall use \@ref pstorage_block_identifier_get with the base - * ID and provide a block number of 5. Therefore, the application is only - * expected to remember the base block identifier. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module - * initialization. - * @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed. - * @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed. - * @retval NRF_ERROR_NO_MEM Operation failure. No storage space available. - */ -uint32_t pstorage_raw_register(pstorage_module_param_t * p_module_param, - pstorage_handle_t * p_block_id); - -/**@brief Function for persistently storing data of length 'size' contained in 'p_src' address in - * storage module at 'p_dest' address. Equivalent to Storage Write. - * - * @param[in] p_dest Destination address where data is to be stored persistently. - * @param[in] p_src Source address containing data to be stored. The API assumes this is resident - * memory and no intermediate copy of data is made by the API. Must be word - * aligned. - * @param[in] size Size of data to be stored expressed in bytes. Must be word aligned. - * @param[in] offset Offset in bytes to be applied when writing to the block. - * For example, if within a block of 100 bytes, the application wishes to - * write 20 bytes at an offset of 12 bytes, this field should be set to 12. - * Must be word aligned. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module - * initialization. - * @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed. - * @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed. - * @retval NRF_ERROR_INVALID_ADDR Operation failure. Parameter is not aligned. - * @retval NRF_ERROR_NO_MEM Operation failure. No storage space available. - * - * @warning No copy of the data is made, meaning memory provided for data source that is to be - * written to flash cannot be freed or reused by the application until this procedure - * is complete. The application is notified when the procedure is finished using the - * notification callback registered by the application. - */ -uint32_t pstorage_raw_store(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset); - -/**@brief Function for clearing data in persistent memory in raw mode. - * - * @param[in] p_dest Base block identifier in persistent memory that needs to be cleared. - * Equivalent to an Erase Operation. - * @param[in] size Size of data to be cleared from persistent memory expressed in bytes. - * Not used. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. API is called without module - * initialization. - * @retval NRF_ERROR_NULL Operation failure. NULL parameter has been passed. - * @retval NRF_ERROR_INVALID_PARAM Operation failure. Invalid parameter has been passed. - * @retval NRF_ERROR_NO_MEM Operation failure. No storage space available. - * - * @note Clear operations may take time. This API, however, does not block until the clear - * procedure is complete. The application is notified of procedure completion using - * a notification callback registered by the application. The 'result' parameter of the - * callback indicates if the procedure was successful or not. - */ -uint32_t pstorage_raw_clear(pstorage_handle_t * p_dest, pstorage_size_t size); - -#endif // PSTORAGE_RAW_MODE_ENABLE - -/**@} */ -/**@} */ - -#endif // PSTORAGE_H__ - diff --git a/components/drivers_nrf/pstorage/pstorage_nosd.c b/components/drivers_nrf/pstorage/pstorage_nosd.c deleted file mode 100644 index 7416da7..0000000 --- a/components/drivers_nrf/pstorage/pstorage_nosd.c +++ /dev/null @@ -1,525 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "pstorage.h" -#include "nordic_common.h" -#include "nrf_error.h" -#include "ble_flash.h" -#include "app_util.h" -#include -#include -#include - - -#define no_SUPPORT_MODULES_LARGER_THAN_PAGE - -/** - * @defgroup api_param_check API Parameters check macros. - * - * @details Macros that verify parameters passed to the module in the APIs. These macros - * could be mapped to nothing in final versions of code to save execution and size. - * - * @{ - */ -/** - * @brief Checks if API parameters are null. Mostly used for pointer parameters. - */ -#define NULL_PARAM_CHECK(PARAM) \ - if ((PARAM) == NULL) \ - { \ - return NRF_ERROR_NULL; \ - } - -/**@brief Verifies the module identifier supplied by the application is within permissible - * range. - */ -#define MODULE_ID_RANGE_CHECK(ID) \ - if ((PSTORAGE_NUM_OF_PAGES <= ((ID)->module_id)) || \ - (m_app_table[(ID)->module_id].cb == NULL)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@brief Verifies the block identifier supplied by the application is within the permissible - * range. - */ -#define BLOCK_ID_RANGE_CHECK(ID) \ - if ( \ - ( \ - m_app_table[(ID)->module_id].base_id \ - + \ - ( \ - m_app_table[(ID)->module_id].block_count \ - * \ - MODULE_BLOCK_SIZE(ID) \ - ) \ - ) \ - <= \ - ((ID)->block_id) \ - ) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - - -/**@brief Verifies the block size requested by the application can be supported by the module. */ -#define BLOCK_SIZE_CHECK(X) \ - if (((X) > PSTORAGE_MAX_BLOCK_SIZE) || ((X) < PSTORAGE_MIN_BLOCK_SIZE)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@brief Verifies block size requested by Application in registration API */ -#define BLOCK_COUNT_CHECK(COUNT, SIZE) \ - if (((COUNT) == 0) || ((m_next_page_addr + ((COUNT) *(SIZE)) > PSTORAGE_DATA_END_ADDR))) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@brief Verifies size parameter provided by application in API. */ -#define SIZE_CHECK(ID, SIZE) \ - if(((SIZE) == 0) || ((SIZE) > MODULE_BLOCK_SIZE(ID))) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@brief Verifies offset parameter provided by application in API. */ -#define OFFSET_CHECK(ID, OFFSET, SIZE) \ - if(((SIZE) + (OFFSET)) > MODULE_BLOCK_SIZE(ID)) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@brief SET BASE by masking offset bits for a address within page */ -#define PAGE_BASE_ADDR(flash_address) ((flash_address)&(~((uint32_t)PSTORAGE_FLASH_PAGE_SIZE-1))) - -/**@brief Verifies the total module size requested by the application can be supported by the module. */ -#define MODULE_SIZE_CHECK(X) \ - if ((X) > PSTORAGE_FLASH_PAGE_SIZE) \ - { \ - return NRF_ERROR_INVALID_PARAM; \ - } - -/**@} */ - - /**@brief Verify module's initialization status. - * - * @details Verify module's initialization status. Returns NRF_ERROR_INVALID_STATE in case a - * module API is called without initializing the module. - */ -#define VERIFY_MODULE_INITIALIZED() \ - do \ - { \ - if (!m_module_initialized) \ - { \ - return NRF_ERROR_INVALID_STATE; \ - } \ - } while(0) - -/**@brief Macro to fetch the block size registered for the module. */ -#define MODULE_BLOCK_SIZE(ID) (m_app_table[(ID)->module_id].block_size) - -/**@} */ - -/** - * @brief Application registration information. - * - * @details Abstracts application specific information that application needs to maintain to be able - * to process requests from each one of them. - * - */ -typedef struct ps_module_table -{ - pstorage_ntf_cb_t cb; /**< Callback registered with the module to be notified of any error occurring in persistent memory management */ - pstorage_block_t base_id; /**< Base block id assigned to the module */ - uint16_t block_size; /**< Size of block for the module */ - uint16_t block_count; /**< Number of block requested by application */ - uint16_t no_of_pages; /**< Variable to remember how many pages have been allocated for this module. This information is used for clearing of block, so that application does not need to have knowledge of number of pages its using. */ -} pstorage_module_table_t; - -static pstorage_module_table_t m_app_table[PSTORAGE_NUM_OF_PAGES]; /**< Registered application information table. */ - -static uint32_t m_next_app_instance; /**< Points to the application module instance that can be allocated next */ -static uint32_t m_next_page_addr; /**< Points to the flash address that can be allocated to a module next, this is needed as blocks of a module can span across flash pages. */ - -static bool m_module_initialized = false; /**< Flag for checking if module has been initialized. */ - - -/** - * @brief Routine to notify application of any errors. - * - * @param[in] result Result of event being notified. - */ -static __INLINE void app_notify(pstorage_handle_t * p_handle, - uint8_t * p_addr, - uint8_t op_code, - pstorage_size_t size, - uint32_t result) -{ - pstorage_ntf_cb_t ntf_cb; - - ntf_cb = m_app_table[p_handle->module_id].cb; - - // Indicate result to client. - // For PSTORAGE_CLEAR_OP_CODE no size is returned as the size field is used only internally - // for clients registering multiple pages. - ntf_cb(p_handle, - op_code, - result, - p_addr, - size); -} - - -uint32_t pstorage_init(void) -{ - m_next_app_instance = 0; - m_next_page_addr = PSTORAGE_DATA_START_ADDR; - m_module_initialized = true; - return NRF_SUCCESS; -} - - -uint32_t pstorage_register(pstorage_module_param_t * p_module_param, - pstorage_handle_t * p_block_id) -{ - - - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_module_param); - NULL_PARAM_CHECK(p_block_id); - NULL_PARAM_CHECK(p_module_param->cb); - BLOCK_SIZE_CHECK(p_module_param->block_size); - BLOCK_COUNT_CHECK(p_module_param->block_count, p_module_param->block_size); - -#ifndef SUPPORT_MODULES_LARGER_THAN_PAGE - MODULE_SIZE_CHECK(((uint16_t)(p_module_param->block_size)*(p_module_param->block_count))); -#endif - - - if (m_next_app_instance == PSTORAGE_NUM_OF_PAGES) - { - return NRF_ERROR_NO_MEM; - } - - p_block_id->module_id = m_next_app_instance; - p_block_id->block_id = m_next_page_addr; - - m_app_table[m_next_app_instance].base_id = p_block_id->block_id; - m_app_table[m_next_app_instance].cb = p_module_param->cb; - m_app_table[m_next_app_instance].block_size = p_module_param->block_size; - m_app_table[m_next_app_instance].block_count = p_module_param->block_count; - - // Calculate number of flash pages allocated for the device. - - -#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE - uint16_t page_count = 0; - uint32_t total_size; - total_size = p_module_param->block_size * p_module_param->block_count; - do - { - page_count++; - - if (total_size > PSTORAGE_FLASH_PAGE_SIZE) - { - total_size -= PSTORAGE_FLASH_PAGE_SIZE; - } - else - { - total_size = 0; - } - - m_next_page_addr += PSTORAGE_FLASH_PAGE_SIZE; - - } while (total_size >= PSTORAGE_FLASH_PAGE_SIZE); - m_app_table[m_next_app_instance].no_of_pages = page_count; -#else - m_app_table[m_next_app_instance].no_of_pages = 1; - m_next_page_addr += PSTORAGE_FLASH_PAGE_SIZE; -#endif - m_next_app_instance++; - - return NRF_SUCCESS; -} - - -uint32_t pstorage_block_identifier_get(pstorage_handle_t * p_base_id, - pstorage_size_t block_num, - pstorage_handle_t * p_block_id) -{ - pstorage_handle_t temp_id; - - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_base_id); - NULL_PARAM_CHECK(p_block_id); - MODULE_ID_RANGE_CHECK(p_base_id); - - temp_id = (*p_base_id); - temp_id.block_id += (block_num * MODULE_BLOCK_SIZE(p_base_id)); - - BLOCK_ID_RANGE_CHECK(&temp_id); - - (*p_block_id) = temp_id; - - return NRF_SUCCESS; -} - - -uint32_t pstorage_store(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_src); - NULL_PARAM_CHECK(p_dest); - MODULE_ID_RANGE_CHECK(p_dest); - BLOCK_ID_RANGE_CHECK(p_dest); - SIZE_CHECK(p_dest, size); - OFFSET_CHECK(p_dest, offset, size); - - // Verify word alignment. - if ((!is_word_aligned(p_src)) || (!is_word_aligned((void *)(uint32_t)offset))) - { - return NRF_ERROR_INVALID_ADDR; - } - - uint32_t storage_addr = p_dest->block_id + offset; - - uint32_t retval = ble_flash_block_write((uint32_t *)storage_addr, - (uint32_t *)p_src, - (size /sizeof(uint32_t))); - - app_notify(p_dest, p_src, PSTORAGE_STORE_OP_CODE, size, retval); - - return retval; -} - -/** @brief Function for handling flash updates using swap page - * - * __________________________________________________ - * | Page1 | - * |_______________________________________________| - * | head | body (to be updated ) | tail | - * |______|_________________________________|______| - * - * ________________________________________________________________________________________ - * | Page1 | Page2 | - * |_______________________________________________|______________________________________| - * | head | body (to be updated ) | tail | - * |________________|________________________________________|____________________________| - * - * - * ToDo: pointers not uint32_t for addresses - * - */ - -uint32_t pstorage_update(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset) -{ - - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_src); - NULL_PARAM_CHECK(p_dest); - MODULE_ID_RANGE_CHECK(p_dest); - BLOCK_ID_RANGE_CHECK(p_dest); - SIZE_CHECK(p_dest, size); - OFFSET_CHECK(p_dest, offset, size); - - uint32_t *p_swap_addr = (uint32_t *)PSTORAGE_SWAP_ADDR; - uint32_t *p_page_addr1 = (uint32_t *) PAGE_BASE_ADDR(p_dest->block_id + offset); -#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE - uint32_t *p_page_addr2 = (uint32_t *) PAGE_BASE_ADDR(p_dest->block_id + offset + size-1); -#endif - // block may not be aligned with page, so head must include all trailing blocks - uint16_t head_word_count = (uint32_t)((uint32_t *)p_dest->block_id - p_page_addr1) + (offset)/sizeof(uint32_t); - uint16_t body_word_count = size/sizeof(uint32_t); - uint16_t tail_word_count; - uint32_t retval; - - // Verify word alignment. - if ((!is_word_aligned(p_src)) || (!is_word_aligned((void *)(uint32_t)offset))) - { - return NRF_ERROR_INVALID_ADDR; - } - // erase swap page - (void) ble_flash_page_erase(PSTORAGE_SWAP_ADDR / BLE_FLASH_PAGE_SIZE); -#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE - if (p_page_addr1 == p_page_addr2) - { -#endif - // tail is in the same page as head - tail_word_count = BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - head_word_count - body_word_count; - // copy of the head - if (head_word_count) - { - retval = ble_flash_block_write(p_swap_addr, p_page_addr1, head_word_count ); - if (retval != NRF_SUCCESS) - { - app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval); - return retval; - } - } - // copy of the body - retval = ble_flash_block_write(p_swap_addr+head_word_count, (uint32_t *)p_src, body_word_count); - if (retval != NRF_SUCCESS) - { - app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval); - return retval; - } - // copy of the tail - if (tail_word_count) - { - retval = ble_flash_block_write(p_swap_addr+head_word_count+body_word_count, p_page_addr1+head_word_count+body_word_count, tail_word_count ); - if (retval != NRF_SUCCESS) - { - app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval); - return retval; - } - } - // erase active page - (void) ble_flash_page_erase((uint32_t)p_page_addr1 / BLE_FLASH_PAGE_SIZE); - // restore updated page - retval = ble_flash_block_write(p_page_addr1, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t)); -#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE - } - else - { - // tail is in NOT in the same page as head - need to swap twice - uint16_t body1_word_count = BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - head_word_count; - uint16_t body2_word_count = body_word_count - body1_word_count; - tail_word_count = BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - body2_word_count; - // copy head - retval = ble_flash_block_write(p_swap_addr, p_page_addr1, head_word_count ); - if (retval != NRF_SUCCESS) - { - app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval); - return retval; - } - // copy body1 - retval = ble_flash_block_write(p_swap_addr, (uint32_t *)p_src, body1_word_count ); - if (retval != NRF_SUCCESS) - { - app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval); - return retval; - } - // erase active page - (void) ble_flash_page_erase((uint32_t)p_page_addr1 / BLE_FLASH_PAGE_SIZE); - // restore updated page1 - retval = ble_flash_block_write(p_page_addr1, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t)); - if (retval != NRF_SUCCESS) - { - app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval); - return retval; - } - // erase swap page - (void) ble_flash_page_erase(PSTORAGE_SWAP_ADDR / BLE_FLASH_PAGE_SIZE); - // copy body2 - retval = ble_flash_block_write(p_swap_addr, (uint32_t *)p_src + body1_word_count, body2_word_count ); - if (retval != NRF_SUCCESS) - { - app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval); - return retval; - } - // copy tail - retval = ble_flash_block_write(p_swap_addr, p_page_addr2+body2_word_count, tail_word_count ); - if (retval != NRF_SUCCESS) - { - app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval); - return retval; - } - // erase active page - (void) ble_flash_page_erase((uint32_t)p_page_addr2 / BLE_FLASH_PAGE_SIZE); - // restore updated page2 - retval = ble_flash_block_write(p_page_addr2, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t)); - if (retval != NRF_SUCCESS) - { - app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval); - return retval; - } - } -#endif - app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval); - return retval; - -} - -uint32_t pstorage_load(uint8_t * p_dest, - pstorage_handle_t * p_src, - pstorage_size_t size, - pstorage_size_t offset) -{ - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_src); - NULL_PARAM_CHECK(p_dest); - MODULE_ID_RANGE_CHECK (p_src); - BLOCK_ID_RANGE_CHECK(p_src); - SIZE_CHECK(p_src,size); - OFFSET_CHECK(p_src,offset,size); - - // Verify word alignment. - if ((!is_word_aligned(p_dest)) || (!is_word_aligned((void *)(uint32_t)offset))) - { - return NRF_ERROR_INVALID_ADDR; - } - - memcpy(p_dest, (((uint8_t *)p_src->block_id) + offset), size); - - app_notify(p_src, p_dest, PSTORAGE_LOAD_OP_CODE, size, NRF_SUCCESS); - - return NRF_SUCCESS; -} - - -uint32_t pstorage_clear(pstorage_handle_t * p_dest, pstorage_size_t size) -{ - uint32_t page_addr; - uint32_t retval; - uint16_t page_count; - - VERIFY_MODULE_INITIALIZED(); - NULL_PARAM_CHECK(p_dest); - MODULE_ID_RANGE_CHECK(p_dest); - - page_addr = p_dest->block_id / BLE_FLASH_PAGE_SIZE; - - retval = NRF_SUCCESS; - - for (page_count = 0; page_count < m_app_table[p_dest->module_id].no_of_pages; page_count++) - { - retval = ble_flash_page_erase(page_addr); - page_addr++; - if (retval != NRF_SUCCESS) - { - break; - } - } - app_notify(p_dest, NULL, PSTORAGE_CLEAR_OP_CODE, size, retval); - return retval; -} - -void pstorage_sys_event_handler(uint32_t sys_evt) -{ - -} - -uint32_t pstorage_access_status_get(uint32_t * p_count) -{ - if (p_count) - { - *p_count = 0; - } - return NRF_SUCCESS; -} diff --git a/components/drivers_nrf/pstorage/pstorage_raw.c b/components/drivers_nrf/pstorage/pstorage_raw.c deleted file mode 100644 index 2d70cdb..0000000 --- a/components/drivers_nrf/pstorage/pstorage_raw.c +++ /dev/null @@ -1,471 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "pstorage.h" -#include -#include -#include "nordic_common.h" -#include "nrf_error.h" -#include "nrf_assert.h" -#include "nrf.h" -#include "nrf_soc.h" -#include "app_util.h" - -/** @file - * - * @defgroup persistent_storage_raw Persistent Storage Interface - Raw Mode Implementation - * @{ - * @ingroup persistent_storage - * @brief Persistent Storage Interface - Raw Mode Implementation. - * - * @details This file contains the source code for raw mode implementation of pstorage. - * It is intended for special use cases where flash size is critical or the application must have - * full control of the flash, such as DFU. The registration function in this implementation only - * allocates a module id for the queue but does not locate any flash pages for the registrant. - * This implementation provides no safety checking of addresses when clearing or storing data into - * flash. The application is responsible for handling flash addresses and care must therefore be - * taken in application not to erase application area. - * This implementation does not support the @ref pstorage_update function. - */ - -#define INVALID_OPCODE 0x00 /**< Invalid op code identifier. */ - -#ifdef NRF51 -#define SOC_MAX_WRITE_SIZE 1024 /**< Maximum write size allowed for a single call to \ref sd_flash_write as specified in the SoC API on the nRF51. */ -#elif NRF52 -#define SOC_MAX_WRITE_SIZE 4096 /**< Maximum write size allowed for a single call to \ref sd_flash_write as specified in the SoC API on the nRF52. */ -#else -#error No target defined -#endif - - -/** - * @brief Application registration information. - * - * @details Define application specific information that application needs to maintain to be able - * to process requests from each one of them. - */ -typedef struct -{ - pstorage_ntf_cb_t cb; /**< Callback registered with the module to be notified of result of flash access. */ -} pstorage_module_table_t; - - -/** - * @brief Defines command queue element. - * - * @details Defines command queue element. Each element encapsulates needed information to process - * a flash access command. - */ -typedef struct -{ - uint8_t op_code; /**< Identifies flash access operation being queued. Element is free is op-code is INVALID_OPCODE */ - pstorage_size_t size; /**< Identifies size in bytes requested for the operation. */ - pstorage_size_t offset; /**< Offset requested by the application for access operation. */ - pstorage_handle_t storage_addr; /**< Address/Identifier for persistent memory. */ - uint8_t * p_data_addr; /**< Address/Identifier for data memory. This is assumed to be resident memory. */ -} cmd_queue_element_t; - - -/** - * @brief Defines command queue, an element is free is op_code field is not invalid. - * - * @details Defines commands enqueued for flash access. At any point of time, this queue has one or - * more flash access operation pending if the count field is not zero. When the queue is - * not empty, the rp (read pointer) field points to the flash access command in progress - * or to requested next. The queue implements a simple first in first out algorithm. - * Data addresses are assumed to be resident. - */ -typedef struct -{ - uint8_t rp; /**< Read pointer, pointing to flash access that is ongoing or to be requested next. */ - uint8_t count; /**< Number of elements in the queue. */ - bool flash_access; /**< Flag to ensure an flash event received is for an request issued by the module. */ - cmd_queue_element_t cmd[PSTORAGE_CMD_QUEUE_SIZE]; /**< Array to maintain flash access operation details */ -}cmd_queue_t; - -static cmd_queue_t m_cmd_queue; /**< Flash operation request queue. */ -static pstorage_module_table_t m_app_table[PSTORAGE_NUM_OF_PAGES]; /**< Registered application information table. */ -static pstorage_size_t m_next_app_instance; /**< Points to the application module instance that can be allocated next */ -static pstorage_size_t m_round_val; /**< Round value for multiple round operations. For erase operations, the round value will contain current round counter which is identical to number of pages erased. For store operations, the round value contains current round of operation * SOC_MAX_WRITE_SIZE to ensure each store to the SoC Flash API is within the SoC limit. */ - -/** - * @brief Function for processing of commands and issuing flash access request to the SoftDevice. - * - * @return The return value received from SoftDevice. - */ -static uint32_t cmd_process(void); - - -/** - * @brief Function for notifying application of any errors. - * - * @param[in] result Result of event being notified. - * @param[in] p_elem Pointer to the element for which a notification should be given. - */ -static void app_notify(uint32_t result, cmd_queue_element_t * p_elem); - - -/** - * @defgroup utility_functions Utility internal functions. - * @{ - * @details Utility functions needed for interfacing with flash through SoC APIs. - * SoC APIs are non blocking and provide the result of flash access through an event. - * - * @note Only one flash access operation is permitted at a time by SoC. Hence a queue is - * maintained by this module. - */ - -/** - * @brief Function for initializing a command queue element. - * - * @param[in] index Index identifying element to be initialized. - */ -static void cmd_queue_element_init(uint32_t index) -{ - // Internal function and checks on range of index can be avoided - m_cmd_queue.cmd[index].op_code = INVALID_OPCODE; - m_cmd_queue.cmd[index].size = 0; - m_cmd_queue.cmd[index].storage_addr.module_id = PSTORAGE_NUM_OF_PAGES; - m_cmd_queue.cmd[index].storage_addr.block_id = 0; - m_cmd_queue.cmd[index].p_data_addr = NULL; - m_cmd_queue.cmd[index].offset = 0; -} - - -/** - * @brief Function for initializing the command queue. - */ -static void cmd_queue_init(void) -{ - uint32_t cmd_index; - - m_round_val = 0; - m_cmd_queue.rp = 0; - m_cmd_queue.count = 0; - m_cmd_queue.flash_access = false; - - for(cmd_index = 0; cmd_index < PSTORAGE_CMD_QUEUE_SIZE; cmd_index++) - { - cmd_queue_element_init(cmd_index); - } -} - - -/** - * @brief Function for enqueueing a flash access operation. - * - * @param[in] opcode Operation code for the command to queue. - * @param[in] p_storage_addr Pointer to the destination address. - * @param[in] p_data_addr Pointer to the source address containing the data. - * @param[in] size Size of data clear or write. - * @param[in] offset Offset to the address identified by the source data address. - * - * @retval NRF_SUCCESS If the enqueueing succeeded. - * @retval NRF_ERROR_NO_MEM In case the queue is full. - * @return Any error returned by the SoftDevice flash API. - */ -static uint32_t cmd_queue_enqueue(uint8_t opcode, - pstorage_handle_t * p_storage_addr, - uint8_t * p_data_addr, - pstorage_size_t size, - pstorage_size_t offset) -{ - uint32_t retval; - - if (m_cmd_queue.count != PSTORAGE_CMD_QUEUE_SIZE) - { - uint8_t write_index = m_cmd_queue.rp + m_cmd_queue.count; - - if (write_index >= PSTORAGE_CMD_QUEUE_SIZE) - { - write_index -= PSTORAGE_CMD_QUEUE_SIZE; - } - - m_cmd_queue.cmd[write_index].op_code = opcode; - m_cmd_queue.cmd[write_index].p_data_addr = p_data_addr; - m_cmd_queue.cmd[write_index].storage_addr = (*p_storage_addr); - m_cmd_queue.cmd[write_index].size = size; - m_cmd_queue.cmd[write_index].offset = offset; - retval = NRF_SUCCESS; - if (m_cmd_queue.flash_access == false) - { - retval = cmd_process(); - if (retval == NRF_ERROR_BUSY) - { - // In case of busy error code, it is possible to attempt to access flash. - retval = NRF_SUCCESS; - } - } - m_cmd_queue.count++; - } - else - { - retval = NRF_ERROR_NO_MEM; - } - - return retval; -} - - -/** - * @brief Function for dequeueing a command element. - * - * @retval NRF_SUCCESS If the dequeueing succeeded and next command was processed. - * @return Any error returned by the SoftDevice flash API. - */ -static uint32_t cmd_queue_dequeue(void) -{ - uint32_t retval = NRF_SUCCESS; - - // If any flash operation is enqueued, schedule - if ((m_cmd_queue.count > 0) && (m_cmd_queue.flash_access == false)) - { - retval = cmd_process(); - if (retval != NRF_SUCCESS) - { - // Flash could be accessed by other modules, hence a busy error is - // acceptable, but any other error needs to be indicated. - if (retval == NRF_ERROR_BUSY) - { - // In case of busy error code, it is possible to attempt to access flash. - retval = NRF_SUCCESS; - } - } - } - else - { - // No flash access request pending. - } - - return retval; -} - - -/** - * @brief Function for notifying application of any errors. - * - * @param[in] result Result of event being notified. - * @param[in] p_elem Pointer to the element for which a notification should be given. - */ -static void app_notify(uint32_t result, cmd_queue_element_t * p_elem) -{ - pstorage_ntf_cb_t ntf_cb; - uint8_t op_code = p_elem->op_code; - - ntf_cb = m_app_table[p_elem->storage_addr.module_id].cb; - - // Indicate result to client. - ntf_cb(&p_elem->storage_addr, - op_code, - result, - p_elem->p_data_addr, - p_elem->size); -} - - -/** - * @brief Function for handling of system events from SoftDevice. - * - * @param[in] sys_evt System event received. - */ -void pstorage_sys_event_handler(uint32_t sys_evt) -{ - uint32_t retval = NRF_SUCCESS; - - // The event shall only be processed if requested by this module. - if (m_cmd_queue.flash_access == true) - { - cmd_queue_element_t * p_cmd; - m_cmd_queue.flash_access = false; - switch (sys_evt) - { - case NRF_EVT_FLASH_OPERATION_SUCCESS: - { - p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - m_round_val++; - - bool command_finished = ((m_round_val * SOC_MAX_WRITE_SIZE) >= p_cmd->size); - - if (command_finished) - { - uint8_t queue_rp = m_cmd_queue.rp; - - m_round_val = 0; - m_cmd_queue.count--; - m_cmd_queue.rp++; - - if (m_cmd_queue.rp >= PSTORAGE_CMD_QUEUE_SIZE) - { - m_cmd_queue.rp -= PSTORAGE_CMD_QUEUE_SIZE; - } - - app_notify(retval, &m_cmd_queue.cmd[queue_rp]); - - // Initialize/free the element as it is now processed. - cmd_queue_element_init(queue_rp); - } - // Schedule any queued flash access operations. - retval = cmd_queue_dequeue(); - if (retval != NRF_SUCCESS) - { - app_notify(retval, &m_cmd_queue.cmd[m_cmd_queue.rp]); - } - } - break; - - case NRF_EVT_FLASH_OPERATION_ERROR: - app_notify(NRF_ERROR_TIMEOUT, &m_cmd_queue.cmd[m_cmd_queue.rp]); - break; - - default: - // No implementation needed. - break; - } - } -} - - -/** - * @brief Function for processing of commands and issuing flash access request to the SoftDevice. - * - * @return The return value received from SoftDevice. - */ -static uint32_t cmd_process(void) -{ - uint32_t retval; - uint32_t storage_addr; - cmd_queue_element_t * p_cmd; - - retval = NRF_ERROR_FORBIDDEN; - - p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - - storage_addr = p_cmd->storage_addr.block_id; - - switch (p_cmd->op_code) - { - case PSTORAGE_STORE_OP_CODE: - { - uint32_t size; - uint32_t offset; - uint8_t * p_data_addr = p_cmd->p_data_addr; - - offset = (m_round_val * SOC_MAX_WRITE_SIZE); - size = p_cmd->size - offset; - p_data_addr += offset; - storage_addr += (p_cmd->offset + offset); - - if (size < SOC_MAX_WRITE_SIZE) - { - retval = sd_flash_write(((uint32_t *)storage_addr), - (uint32_t *)p_data_addr, - size / sizeof(uint32_t)); - } - else - { - retval = sd_flash_write(((uint32_t *)storage_addr), - (uint32_t *)p_data_addr, - SOC_MAX_WRITE_SIZE / sizeof(uint32_t)); - } - } - break; - - case PSTORAGE_CLEAR_OP_CODE: - { - uint32_t page_number; - - page_number = ((storage_addr / PSTORAGE_FLASH_PAGE_SIZE) + - m_round_val); - - retval = sd_flash_page_erase(page_number); - } - break; - - default: - // Should never reach here. - break; - } - - if (retval == NRF_SUCCESS) - { - m_cmd_queue.flash_access = true; - } - - return retval; -} -/** @} */ - - -uint32_t pstorage_init(void) -{ - cmd_queue_init(); - - m_next_app_instance = 0; - m_round_val = 0; - - for(unsigned int index = 0; index < PSTORAGE_NUM_OF_PAGES; index++) - { - m_app_table[index].cb = NULL; - } - - return NRF_SUCCESS; -} - - -uint32_t pstorage_register(pstorage_module_param_t * p_module_param, - pstorage_handle_t * p_block_id) -{ - if (m_next_app_instance == PSTORAGE_NUM_OF_PAGES) - { - return NRF_ERROR_NO_MEM; - } - - p_block_id->module_id = m_next_app_instance; - m_app_table[m_next_app_instance++].cb = p_module_param->cb; - - return NRF_SUCCESS; -} - - -uint32_t pstorage_block_identifier_get(pstorage_handle_t * p_base_id, - pstorage_size_t block_num, - pstorage_handle_t * p_block_id) -{ - return NRF_ERROR_NOT_SUPPORTED; -} - - -uint32_t pstorage_store(pstorage_handle_t * p_dest, - uint8_t * p_src, - pstorage_size_t size, - pstorage_size_t offset) -{ - // Verify word alignment. - if ((!is_word_aligned(p_src)) || (!is_word_aligned(p_src+offset))) - { - return NRF_ERROR_INVALID_ADDR; - } - - return cmd_queue_enqueue(PSTORAGE_STORE_OP_CODE, p_dest, p_src, size, offset); -} - - -uint32_t pstorage_clear(pstorage_handle_t * p_dest, pstorage_size_t size) -{ - return cmd_queue_enqueue(PSTORAGE_CLEAR_OP_CODE, p_dest, NULL , size, 0); -} - - -/** - * @} - */ diff --git a/components/drivers_nrf/pwm/nrf_drv_pwm.c b/components/drivers_nrf/pwm/nrf_drv_pwm.c new file mode 100644 index 0000000..8174dd9 --- /dev/null +++ b/components/drivers_nrf/pwm/nrf_drv_pwm.c @@ -0,0 +1,412 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(PWM) +#define ENABLED_PWM_COUNT (PWM0_ENABLED+PWM1_ENABLED+PWM2_ENABLED) +#if ENABLED_PWM_COUNT +#include +#include "nrf_drv_pwm.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "PWM" + +#if PWM_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL PWM_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR PWM_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR PWM_CONFIG_DEBUG_COLOR +#else //PWM_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //PWM_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +// Control block - driver instance local data. +typedef struct +{ + nrf_drv_pwm_handler_t handler; + nrf_drv_state_t volatile state; +} pwm_control_block_t; +static pwm_control_block_t m_cb[ENABLED_PWM_COUNT]; + +static void configure_pins(nrf_drv_pwm_t const * const p_instance, + nrf_drv_pwm_config_t const * p_config) +{ + uint32_t out_pins[NRF_PWM_CHANNEL_COUNT]; + uint8_t i; + + for (i = 0; i < NRF_PWM_CHANNEL_COUNT; ++i) + { + uint8_t output_pin = p_config->output_pins[i]; + if (output_pin != NRF_DRV_PWM_PIN_NOT_USED) + { + bool inverted = output_pin & NRF_DRV_PWM_PIN_INVERTED; + out_pins[i] = output_pin & ~NRF_DRV_PWM_PIN_INVERTED; + + if (inverted) + { + nrf_gpio_pin_set(out_pins[i]); + } + else + { + nrf_gpio_pin_clear(out_pins[i]); + } + + nrf_gpio_cfg_output(out_pins[i]); + } + else + { + out_pins[i] = NRF_PWM_PIN_NOT_CONNECTED; + } + } + + nrf_pwm_pins_set(p_instance->p_registers, out_pins); +} + + +ret_code_t nrf_drv_pwm_init(nrf_drv_pwm_t const * const p_instance, + nrf_drv_pwm_config_t const * p_config, + nrf_drv_pwm_handler_t handler) +{ + ASSERT(p_config); + + ret_code_t err_code; + + pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + p_cb->handler = handler; + + configure_pins(p_instance, p_config); + + nrf_pwm_enable(p_instance->p_registers); + nrf_pwm_configure(p_instance->p_registers, + p_config->base_clock, p_config->count_mode, p_config->top_value); + nrf_pwm_decoder_set(p_instance->p_registers, + p_config->load_mode, p_config->step_mode); + + nrf_pwm_shorts_set(p_instance->p_registers, 0); + nrf_pwm_int_set(p_instance->p_registers, 0); + nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_LOOPSDONE); + nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_SEQEND0); + nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_SEQEND1); + nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_STOPPED); + + if (p_cb->handler) + { + nrf_drv_common_irq_enable(nrf_drv_get_IRQn(p_instance->p_registers), + p_config->irq_priority); + } + + p_cb->state = NRF_DRV_STATE_INITIALIZED; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +void nrf_drv_pwm_uninit(nrf_drv_pwm_t const * const p_instance) +{ + pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_drv_common_irq_disable(nrf_drv_get_IRQn(p_instance->p_registers)); + + nrf_pwm_disable(p_instance->p_registers); + + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; +} + + +static void start_playback(nrf_drv_pwm_t const * const p_instance, + pwm_control_block_t * p_cb, + uint8_t flags, + nrf_pwm_task_t starting_task) +{ + p_cb->state = NRF_DRV_STATE_POWERED_ON; + + if (p_cb->handler) + { + // The notification about finished playback is by default enabled, but + // this can be suppressed. The notification that the peripheral has been + // stopped is always enable. + uint32_t int_mask = NRF_PWM_INT_LOOPSDONE_MASK | + NRF_PWM_INT_STOPPED_MASK; + + if (flags & NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0) + { + int_mask |= NRF_PWM_INT_SEQEND0_MASK; + } + if (flags & NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1) + { + int_mask |= NRF_PWM_INT_SEQEND1_MASK; + } + if (flags & NRF_DRV_PWM_FLAG_NO_EVT_FINISHED) + { + int_mask &= ~NRF_PWM_INT_LOOPSDONE_MASK; + } + + nrf_pwm_int_set(p_instance->p_registers, int_mask); + } + + nrf_pwm_event_clear(p_instance->p_registers, NRF_PWM_EVENT_STOPPED); + + nrf_pwm_task_trigger(p_instance->p_registers, starting_task); +} + + +void nrf_drv_pwm_simple_playback(nrf_drv_pwm_t const * const p_instance, + nrf_pwm_sequence_t const * p_sequence, + uint16_t playback_count, + uint32_t flags) +{ + pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(playback_count > 0); + ASSERT(nrf_drv_is_in_RAM(p_sequence->values.p_raw)); + + // To take advantage of the looping mechanism, we need to use both sequences + // (single sequence can be played back only once). + nrf_pwm_sequence_set(p_instance->p_registers, 0, p_sequence); + nrf_pwm_sequence_set(p_instance->p_registers, 1, p_sequence); + bool odd = (playback_count & 1); + nrf_pwm_loop_set(p_instance->p_registers, playback_count / 2 + (odd ? 1 : 0)); + + uint32_t shorts_mask; + if (flags & NRF_DRV_PWM_FLAG_STOP) + { + shorts_mask = NRF_PWM_SHORT_LOOPSDONE_STOP_MASK; + } + else if (flags & NRF_DRV_PWM_FLAG_LOOP) + { + shorts_mask = odd ? NRF_PWM_SHORT_LOOPSDONE_SEQSTART1_MASK + : NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; + } + else + { + shorts_mask = 0; + } + nrf_pwm_shorts_set(p_instance->p_registers, shorts_mask); + + NRF_LOG_INFO("Function: %s, sequence length: %d.\r\n", (uint32_t)__func__, + p_sequence->length * sizeof(p_sequence->values)); + NRF_LOG_DEBUG("Sequence data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_sequence->values.p_raw, p_sequence->length * sizeof(p_sequence->values)); + start_playback(p_instance, p_cb, flags, odd ? NRF_PWM_TASK_SEQSTART1 + : NRF_PWM_TASK_SEQSTART0); +} + + +void nrf_drv_pwm_complex_playback(nrf_drv_pwm_t const * const p_instance, + nrf_pwm_sequence_t const * p_sequence_0, + nrf_pwm_sequence_t const * p_sequence_1, + uint16_t playback_count, + uint32_t flags) +{ + pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(playback_count > 0); + ASSERT(nrf_drv_is_in_RAM(p_sequence_0->values.p_raw)); + ASSERT(nrf_drv_is_in_RAM(p_sequence_1->values.p_raw)); + + nrf_pwm_sequence_set(p_instance->p_registers, 0, p_sequence_0); + nrf_pwm_sequence_set(p_instance->p_registers, 1, p_sequence_1); + nrf_pwm_loop_set(p_instance->p_registers, playback_count); + + uint32_t shorts_mask; + if (flags & NRF_DRV_PWM_FLAG_STOP) + { + shorts_mask = NRF_PWM_SHORT_LOOPSDONE_STOP_MASK; + } + else if (flags & NRF_DRV_PWM_FLAG_LOOP) + { + shorts_mask = NRF_PWM_SHORT_LOOPSDONE_SEQSTART0_MASK; + } + else + { + shorts_mask = 0; + } + nrf_pwm_shorts_set(p_instance->p_registers, shorts_mask); + + NRF_LOG_INFO("Function: %s, sequence 0 length: %d.\r\n", (uint32_t)__func__, + p_sequence_0->length * sizeof(p_sequence_0->values)); + NRF_LOG_INFO("Function: %s, sequence 1 length: %d.\r\n", (uint32_t)__func__, + p_sequence_1->length * sizeof(p_sequence_1->values)); + NRF_LOG_DEBUG("Sequence 0 data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_sequence_0->values.p_raw, + p_sequence_0->length * sizeof(p_sequence_0->values)); + NRF_LOG_DEBUG("Sequence 1 data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_sequence_1->values.p_raw, + p_sequence_1->length * sizeof(p_sequence_1->values)); + start_playback(p_instance, p_cb, flags, NRF_PWM_TASK_SEQSTART0); +} + + +bool nrf_drv_pwm_stop(nrf_drv_pwm_t const * const p_instance, + bool wait_until_stopped) +{ + ASSERT(m_cb[p_instance->drv_inst_idx].state != NRF_DRV_STATE_UNINITIALIZED); + + bool ret_val = false; + + if (nrf_drv_pwm_is_stopped(p_instance)) + { + ret_val = true; + } + else + { + nrf_pwm_task_trigger(p_instance->p_registers, NRF_PWM_TASK_STOP); + + do { + if (nrf_drv_pwm_is_stopped(p_instance)) + { + ret_val = true; + break; + } + } while (wait_until_stopped); + } + + NRF_LOG_INFO("%s returned %d.\r\n", (uint32_t)__func__, ret_val); + return ret_val; +} + + +bool nrf_drv_pwm_is_stopped(nrf_drv_pwm_t const * const p_instance) +{ + pwm_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + bool ret_val = false; + + // If the event handler is used (interrupts are enabled), the state will + // be changed in interrupt handler when the STOPPED event occurs. + if (p_cb->state != NRF_DRV_STATE_POWERED_ON) + { + ret_val = true; + } + // If interrupts are disabled, we must check the STOPPED event here. + if (nrf_pwm_event_check(p_instance->p_registers, NRF_PWM_EVENT_STOPPED)) + { + p_cb->state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled.\r\n"); + ret_val = true; + } + + NRF_LOG_INFO("%s returned %d.\r\n", (uint32_t)__func__, ret_val); + return ret_val; +} + + +static void irq_handler(NRF_PWM_Type * p_pwm, pwm_control_block_t * p_cb) +{ + ASSERT(p_cb->handler); + + // The SEQEND0 and SEQEND1 events are only handled when the user asked for + // it (by setting proper flags when starting the playback). + if (nrf_pwm_int_enable_check(p_pwm, NRF_PWM_INT_SEQEND0_MASK) && + nrf_pwm_event_check(p_pwm, NRF_PWM_EVENT_SEQEND0)) + { + nrf_pwm_event_clear(p_pwm, NRF_PWM_EVENT_SEQEND0); + p_cb->handler(NRF_DRV_PWM_EVT_END_SEQ0); + } + if (nrf_pwm_int_enable_check(p_pwm, NRF_PWM_INT_SEQEND1_MASK) && + nrf_pwm_event_check(p_pwm, NRF_PWM_EVENT_SEQEND1)) + { + nrf_pwm_event_clear(p_pwm, NRF_PWM_EVENT_SEQEND1); + p_cb->handler(NRF_DRV_PWM_EVT_END_SEQ1); + } + + // The LOOPSDONE event is handled by default, but this can be disabled. + if (nrf_pwm_int_enable_check(p_pwm, NRF_PWM_INT_LOOPSDONE_MASK) && + nrf_pwm_event_check(p_pwm, NRF_PWM_EVENT_LOOPSDONE)) + { + nrf_pwm_event_clear(p_pwm, NRF_PWM_EVENT_LOOPSDONE); + p_cb->handler(NRF_DRV_PWM_EVT_FINISHED); + } + + if (nrf_pwm_event_check(p_pwm, NRF_PWM_EVENT_STOPPED)) + { + nrf_pwm_event_clear(p_pwm, NRF_PWM_EVENT_STOPPED); + + p_cb->state = NRF_DRV_STATE_INITIALIZED; + + p_cb->handler(NRF_DRV_PWM_EVT_STOPPED); + } +} + + +#if NRF_MODULE_ENABLED(PWM0) +void PWM0_IRQHandler(void) +{ + irq_handler(NRF_PWM0, &m_cb[PWM0_INSTANCE_INDEX]); +} +#endif + +#if NRF_MODULE_ENABLED(PWM1) +void PWM1_IRQHandler(void) +{ + irq_handler(NRF_PWM1, &m_cb[PWM1_INSTANCE_INDEX]); +} +#endif + +#if NRF_MODULE_ENABLED(PWM2) +void PWM2_IRQHandler(void) +{ + irq_handler(NRF_PWM2, &m_cb[PWM2_INSTANCE_INDEX]); +} +#endif + +#if PWM3_ENABLED +void PWM3_IRQHandler(void) +{ + irq_handler(NRF_PWM3, &m_cb[PWM3_INSTANCE_INDEX]); +} +#endif +#endif //ENABLED_PWM_COUNT +#endif //NRF_MODULE_ENABLED(PWM) diff --git a/components/drivers_nrf/pwm/nrf_drv_pwm.h b/components/drivers_nrf/pwm/nrf_drv_pwm.h new file mode 100644 index 0000000..579ea1f --- /dev/null +++ b/components/drivers_nrf/pwm/nrf_drv_pwm.h @@ -0,0 +1,479 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * @addtogroup nrf_pwm PWM HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52 Pulse Width Modulation (PWM) module APIs. + * + * @defgroup nrf_drv_pwm PWM driver + * @{ + * @ingroup nrf_pwm + * @brief @tagAPI52 Pulse Width Modulation (PWM) module driver. + */ + + +#ifndef NRF_DRV_PWM_H__ +#define NRF_DRV_PWM_H__ + +#include "nordic_common.h" +#include "sdk_config.h" +#include "nrf_pwm.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PWM0_ENABLED +#define PWM0_ENABLED 0 +#endif +#ifndef PWM1_ENABLED +#define PWM1_ENABLED 0 +#endif +#ifndef PWM2_ENABLED +#define PWM2_ENABLED 0 +#endif +#ifndef PWM3_ENABLED +#define PWM3_ENABLED 0 +#endif +/** + * @brief PWM driver instance data structure. + */ +typedef struct +{ + NRF_PWM_Type * p_registers; ///< Pointer to the structure with PWM peripheral instance registers. + uint8_t drv_inst_idx; ///< Driver instance index. +} nrf_drv_pwm_t; + +#define PWM0_INSTANCE_INDEX 0 +#define PWM1_INSTANCE_INDEX PWM0_INSTANCE_INDEX+PWM0_ENABLED +#define PWM2_INSTANCE_INDEX PWM1_INSTANCE_INDEX+PWM1_ENABLED +#define PWM3_INSTANCE_INDEX PWM2_INSTANCE_INDEX+PWM2_ENABLED + +/** + * @brief Macro for creating a PWM driver instance. + */ +#define NRF_DRV_PWM_INSTANCE(id) \ +{ \ + .p_registers = CONCAT_2(NRF_PWM, id), \ + .drv_inst_idx = CONCAT_3(PWM, id, _INSTANCE_INDEX), \ +} + + +/** + * @brief This value can be provided instead of a pin number for any channel + * to specify that its output is not used and therefore does not need + * to be connected to a pin. + */ +#define NRF_DRV_PWM_PIN_NOT_USED 0xFF + +/** + * @brief This value can be added to a pin number to inverse its polarity + * (set idle state = 1). + */ +#define NRF_DRV_PWM_PIN_INVERTED 0x80 + +/** + * @brief PWM driver configuration structure. + */ +typedef struct +{ + uint8_t output_pins[NRF_PWM_CHANNEL_COUNT]; ///< Pin numbers for individual output channels (optional). + /**< Use @ref NRF_DRV_PWM_PIN_NOT_USED + * if a given output channel is not needed. */ + uint8_t irq_priority; ///< Interrupt priority. + nrf_pwm_clk_t base_clock; ///< Base clock frequency. + nrf_pwm_mode_t count_mode; ///< Operating mode of the pulse generator counter. + uint16_t top_value; ///< Value up to which the pulse generator counter counts. + nrf_pwm_dec_load_t load_mode; ///< Mode of loading sequence data from RAM. + nrf_pwm_dec_step_t step_mode; ///< Mode of advancing the active sequence. +} nrf_drv_pwm_config_t; + +/** + * @brief PWM driver default configuration. + */ +#define NRF_DRV_PWM_DEFAULT_CONFIG \ +{ \ + .output_pins = {PWM_DEFAULT_CONFIG_OUT0_PIN, \ + PWM_DEFAULT_CONFIG_OUT1_PIN, \ + PWM_DEFAULT_CONFIG_OUT2_PIN, \ + PWM_DEFAULT_CONFIG_OUT3_PIN }, \ + .irq_priority = PWM_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .base_clock = (nrf_pwm_clk_t)PWM_DEFAULT_CONFIG_BASE_CLOCK, \ + .count_mode = (nrf_pwm_mode_t)PWM_DEFAULT_CONFIG_COUNT_MODE, \ + .top_value = PWM_DEFAULT_CONFIG_TOP_VALUE, \ + .load_mode = (nrf_pwm_dec_load_t)PWM_DEFAULT_CONFIG_LOAD_MODE, \ + .step_mode = (nrf_pwm_dec_step_t)PWM_DEFAULT_CONFIG_STEP_MODE, \ +} + + +/** + * @brief PWM flags providing additional playback options. + */ +typedef enum +{ + NRF_DRV_PWM_FLAG_STOP = 0x01, /**< When the requested playback is finished, + the peripheral should be stopped. + @note The STOP task is triggered when + the last value of the final sequence is + loaded from RAM, and the peripheral stops + at the end of the current PWM period. + For sequences with configured repeating + of duty cycle values, this might result in + less than the requested number of repeats + of the last value. */ + NRF_DRV_PWM_FLAG_LOOP = 0x02, /**< When the requested playback is finished, + it should be started from the beginning. + This flag is ignored if used together + with @ref NRF_DRV_PWM_FLAG_STOP. */ + NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0 = 0x04, /**< The event handler should be + called when the last value + from sequence 0 is loaded. */ + NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1 = 0x08, /**< The event handler should be + called when the last value + from sequence 1 is loaded. */ + NRF_DRV_PWM_FLAG_NO_EVT_FINISHED = 0x10, /**< The playback finished event + (enabled by default) should be + suppressed. */ +} nrf_drv_pwm_flag_t; + + +/** + * @brief PWM driver event type. + */ +typedef enum +{ + NRF_DRV_PWM_EVT_FINISHED, ///< Sequence playback finished. + NRF_DRV_PWM_EVT_END_SEQ0, /**< End of sequence 0 reached. Its data can be + safely modified now. */ + NRF_DRV_PWM_EVT_END_SEQ1, /**< End of sequence 1 reached. Its data can be + safely modified now. */ + NRF_DRV_PWM_EVT_STOPPED, ///< The PWM peripheral has been stopped. +} nrf_drv_pwm_evt_type_t; + +/** + * @brief PWM driver event handler type. + */ +typedef void (* nrf_drv_pwm_handler_t)(nrf_drv_pwm_evt_type_t event_type); + + +/** + * @brief Function for initializing the PWM driver. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Pointer to the structure with initial configuration. + * If NULL, the default configuration is used. + * @param[in] handler Event handler provided by the user. If NULL is passed + * instead, event notifications are not done and PWM + * interrupts are disabled. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver was already initialized. + */ +ret_code_t nrf_drv_pwm_init(nrf_drv_pwm_t const * const p_instance, + nrf_drv_pwm_config_t const * p_config, + nrf_drv_pwm_handler_t handler); + +/** + * @brief Function for uninitializing the PWM driver. + * + * If any sequence playback is in progress, it is stopped immediately. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +void nrf_drv_pwm_uninit(nrf_drv_pwm_t const * const p_instance); + +/** + * @brief Function for starting a single sequence playback. + * + * To take advantage of the looping mechanism in the PWM peripheral, both + * sequences must be used (single sequence can be played back only once by + * the peripheral). Therefore, the provided sequence is internally set and + * played back as both sequence 0 and sequence 1. Consequently, if end of + * sequence notifications are required, events for both sequences should be + * used (that means that both the @ref NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0 flag + * and the @ref NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1 flag should be specified and + * the @ref NRF_DRV_PWM_EVT_END_SEQ0 event and the @ref NRF_DRV_PWM_EVT_END_SEQ1 + * event should be handled in the same way). + * + * @note The array containing the duty cycle values for the specified sequence + * must be in RAM and cannot be allocated on stack. + * For detailed information, see @ref nrf_pwm_sequence_t. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_sequence Sequence to be played back. + * @param[in] playback_count Number of playbacks to be performed (must not be 0). + * @param[in] flags Additional options. Pass any combination of + * @ref nrf_drv_pwm_flag_t "playback flags", or 0 + * for default settings. + */ +void nrf_drv_pwm_simple_playback(nrf_drv_pwm_t const * const p_instance, + nrf_pwm_sequence_t const * p_sequence, + uint16_t playback_count, + uint32_t flags); + +/** + * @brief Function for starting a two-sequence playback. + * + * @note The array containing the duty cycle values for the specified sequence + * must be in RAM and cannot be allocated on stack. + * For detailed information, see @ref nrf_pwm_sequence_t. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_sequence_0 First sequence to be played back. + * @param[in] p_sequence_1 Second sequence to be played back. + * @param[in] playback_count Number of playbacks to be performed (must not be 0). + * @param[in] flags Additional options. Pass any combination of + * @ref nrf_drv_pwm_flag_t "playback flags", or 0 + * for default settings. + */ +void nrf_drv_pwm_complex_playback(nrf_drv_pwm_t const * const p_instance, + nrf_pwm_sequence_t const * p_sequence_0, + nrf_pwm_sequence_t const * p_sequence_1, + uint16_t playback_count, + uint32_t flags); + +/** + * @brief Function for advancing the active sequence. + * + * This function only applies to @ref NRF_PWM_STEP_TRIGGERED mode. + * + * @param[in] p_instance Pointer to the driver instance structure. + */ +__STATIC_INLINE void nrf_drv_pwm_step(nrf_drv_pwm_t const * const p_instance); + +/** + * @brief Function for stopping the sequence playback. + * + * The playback is stopped at the end of the current PWM period. + * This means that if the active sequence is configured to repeat each duty + * cycle value for a certain number of PWM periods, the last played value + * might appear on the output less times than requested. + * + * @note This function can be instructed to wait until the playback is stopped + * (by setting @p wait_until_stopped to true). Note that, depending on + * the length of the PMW period, this might take a significant amount of + * time. Alternatively, the @ref nrf_drv_pwm_is_stopped function can be + * used to poll the status, or the @ref NRF_DRV_PWM_EVT_STOPPED event can + * be used to get the notification when the playback is stopped, provided + * the event handler is defined. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] wait_until_stopped If true, the function will not return until + * the playback is stopped. + * + * @retval true If the PWM peripheral is stopped. + * @retval false If the PWM peripheral is not stopped. + */ +bool nrf_drv_pwm_stop(nrf_drv_pwm_t const * const p_instance, + bool wait_until_stopped); + +/** + * @brief Function for checking the status of the PWM peripheral. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true If the PWM peripheral is stopped. + * @retval false If the PWM peripheral is not stopped. + */ +bool nrf_drv_pwm_is_stopped(nrf_drv_pwm_t const * const p_instance); + +/** + * @brief Function for updating the sequence data during playback. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] p_sequence Pointer to the new sequence definition. + */ +__STATIC_INLINE void nrf_drv_pwm_sequence_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + nrf_pwm_sequence_t const * p_sequence); + +/** + * @brief Function for updating the pointer to the duty cycle values + * in the specified sequence during playback. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] values New pointer to the duty cycle values. + */ +__STATIC_INLINE void nrf_drv_pwm_sequence_values_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + nrf_pwm_values_t values); + +/** + * @brief Function for updating the number of duty cycle values + * in the specified sequence during playback. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] length New number of the duty cycle values. + */ +__STATIC_INLINE void nrf_drv_pwm_sequence_length_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint16_t length); + +/** + * @brief Function for updating the number of repeats for duty cycle values + * in specified sequence during playback. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] repeats New number of repeats. + */ +__STATIC_INLINE void nrf_drv_pwm_sequence_repeats_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint32_t repeats); + +/** + * @brief Function for updating the additional delay after the specified + * sequence during playback. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] seq_id Identifier of the sequence (0 or 1). + * @param[in] end_delay New end delay value (in PWM periods). + */ +__STATIC_INLINE void nrf_drv_pwm_sequence_end_delay_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint32_t end_delay); + +/** + * @brief Function for returning the address of a specified PWM task that can + * be used in PPI module. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] task Requested task. + * + * @return Task address. + */ +__STATIC_INLINE uint32_t nrf_drv_pwm_task_address_get( + nrf_drv_pwm_t const * const p_instance, + nrf_pwm_task_t task); + +/**@brief Function for returning the address of a specified PWM event that can + * be used in PPI module. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] event Requested event. + * + * @return Event address. + */ +__STATIC_INLINE uint32_t nrf_drv_pwm_event_address_get( + nrf_drv_pwm_t const * const p_instance, + nrf_pwm_event_t event); + + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nrf_drv_pwm_step(nrf_drv_pwm_t const * const p_instance) +{ + nrf_pwm_task_trigger(p_instance->p_registers, NRF_PWM_TASK_NEXTSTEP); +} + +__STATIC_INLINE void nrf_drv_pwm_sequence_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + nrf_pwm_sequence_t const * p_sequence) +{ + nrf_pwm_sequence_set(p_instance->p_registers, seq_id, p_sequence); +} + +__STATIC_INLINE void nrf_drv_pwm_sequence_values_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + nrf_pwm_values_t values) +{ + nrf_pwm_seq_ptr_set(p_instance->p_registers, seq_id, values.p_raw); +} + +__STATIC_INLINE void nrf_drv_pwm_sequence_length_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint16_t length) +{ + nrf_pwm_seq_cnt_set(p_instance->p_registers, seq_id, length); +} + +__STATIC_INLINE void nrf_drv_pwm_sequence_repeats_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint32_t repeats) +{ + nrf_pwm_seq_refresh_set(p_instance->p_registers, seq_id, repeats); +} + +__STATIC_INLINE void nrf_drv_pwm_sequence_end_delay_update( + nrf_drv_pwm_t const * const p_instance, + uint8_t seq_id, + uint32_t end_delay) +{ + nrf_pwm_seq_end_delay_set(p_instance->p_registers, seq_id, end_delay); +} + +__STATIC_INLINE uint32_t nrf_drv_pwm_task_address_get( + nrf_drv_pwm_t const * const p_instance, + nrf_pwm_task_t task) +{ + return nrf_pwm_task_address_get(p_instance->p_registers, task); +} + +__STATIC_INLINE uint32_t nrf_drv_pwm_event_address_get( + nrf_drv_pwm_t const * const p_instance, + nrf_pwm_event_t event) +{ + return nrf_pwm_event_address_get(p_instance->p_registers, event); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_PWM_H__ + +/** @} */ diff --git a/components/drivers_nrf/qdec/nrf_drv_qdec.c b/components/drivers_nrf/qdec/nrf_drv_qdec.c index 87ac97b..5ce1047 100644 --- a/components/drivers_nrf/qdec/nrf_drv_qdec.c +++ b/components/drivers_nrf/qdec/nrf_drv_qdec.c @@ -1,15 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(QDEC) #include #include @@ -22,6 +52,23 @@ #include "app_util_platform.h" #include "nrf_assert.h" +#define NRF_LOG_MODULE_NAME "QDEC" + +#if QDEC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL QDEC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR QDEC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR QDEC_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_QDEC_EVENT_SAMPLERDY ? "NRF_QDEC_EVENT_SAMPLERDY" : \ + (event == NRF_QDEC_EVENT_REPORTRDY ? "NRF_QDEC_EVENT_REPORTRDY" : \ + (event == NRF_QDEC_EVENT_ACCOF ? "NRF_QDEC_EVENT_ACCOF" : "UNKNOWN EVENT"))) +#else //QDEC_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //QDEC_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + static qdec_event_handler_t m_qdec_event_handler = NULL; static const nrf_drv_qdec_config_t m_default_config = NRF_DRV_QDEC_DEFAULT_CONFIG; static nrf_drv_state_t m_state = NRF_DRV_STATE_UNINITIALIZED; @@ -32,7 +79,8 @@ void QDEC_IRQHandler(void) if ( nrf_qdec_event_check(NRF_QDEC_EVENT_SAMPLERDY) && nrf_qdec_int_enable_check(NRF_QDEC_INT_SAMPLERDY_MASK) ) { - nrf_qdec_event_clear(NRF_QDEC_EVENT_SAMPLERDY); + nrf_qdec_event_clear(NRF_QDEC_EVENT_SAMPLERDY); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_QDEC_EVENT_SAMPLERDY)); event.type = NRF_QDEC_EVENT_SAMPLERDY; event.data.sample.value = (int8_t)nrf_qdec_sample_get(); @@ -43,6 +91,7 @@ void QDEC_IRQHandler(void) nrf_qdec_int_enable_check(NRF_QDEC_INT_REPORTRDY_MASK) ) { nrf_qdec_event_clear(NRF_QDEC_EVENT_REPORTRDY); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_QDEC_INT_REPORTRDY_MASK)); event.type = NRF_QDEC_EVENT_REPORTRDY; @@ -55,6 +104,7 @@ void QDEC_IRQHandler(void) nrf_qdec_int_enable_check(NRF_QDEC_INT_ACCOF_MASK) ) { nrf_qdec_event_clear(NRF_QDEC_EVENT_ACCOF); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_QDEC_EVENT_ACCOF)); event.type = NRF_QDEC_EVENT_ACCOF; m_qdec_event_handler(event); @@ -65,9 +115,13 @@ void QDEC_IRQHandler(void) ret_code_t nrf_drv_qdec_init(const nrf_drv_qdec_config_t * p_config, qdec_event_handler_t event_handler) { + ret_code_t err_code; + if (m_state != NRF_DRV_STATE_UNINITIALIZED) { - return NRF_ERROR_INVALID_STATE; // qdec_event_handler has been already registered + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } if (p_config == NULL) @@ -81,11 +135,13 @@ ret_code_t nrf_drv_qdec_init(const nrf_drv_qdec_config_t * p_config, } else { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } nrf_qdec_sampleper_set(p_config->sampleper); - nrf_gpio_cfg_input(p_config->pselled,NRF_GPIO_PIN_NOPULL); + nrf_gpio_cfg_input(p_config->pselled, NRF_GPIO_PIN_NOPULL); nrf_gpio_cfg_input(p_config->psela, NRF_GPIO_PIN_NOPULL); nrf_gpio_cfg_input(p_config->pselb, NRF_GPIO_PIN_NOPULL); nrf_qdec_pio_assign( p_config->psela, p_config->pselb, p_config->pselled); @@ -120,7 +176,9 @@ ret_code_t nrf_drv_qdec_init(const nrf_drv_qdec_config_t * p_config, m_state = NRF_DRV_STATE_INITIALIZED; - return NRF_SUCCESS; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } void nrf_drv_qdec_uninit(void) @@ -129,6 +187,7 @@ void nrf_drv_qdec_uninit(void) nrf_drv_qdec_disable(); nrf_drv_common_irq_disable(QDEC_IRQn); m_state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized.\r\n"); } void nrf_drv_qdec_enable(void) @@ -137,14 +196,16 @@ void nrf_drv_qdec_enable(void) nrf_qdec_enable(); nrf_qdec_task_trigger(NRF_QDEC_TASK_START); m_state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled.\r\n"); } void nrf_drv_qdec_disable(void) { ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); - nrf_qdec_disable(); nrf_qdec_task_trigger(NRF_QDEC_TASK_STOP); + nrf_qdec_disable(); m_state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled.\r\n"); } void nrf_drv_qdec_accumulators_read(int16_t * p_acc, int16_t * p_accdbl) @@ -154,6 +215,11 @@ void nrf_drv_qdec_accumulators_read(int16_t * p_acc, int16_t * p_accdbl) *p_acc = (int16_t)nrf_qdec_accread_get(); *p_accdbl = (int16_t)nrf_qdec_accdblread_get(); + + NRF_LOG_DEBUG("Accumulators data, ACC register:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_acc, sizeof(p_acc)); + NRF_LOG_DEBUG("Accumulators data, ACCDBL register:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_accdbl, sizeof(p_accdbl)); } void nrf_drv_qdec_task_address_get(nrf_qdec_task_t task, uint32_t * p_task) @@ -166,3 +232,4 @@ void nrf_drv_qdec_event_address_get(nrf_qdec_event_t event, uint32_t * p_event) *p_event = (uint32_t)nrf_qdec_event_address_get(event); } +#endif //NRF_MODULE_ENABLED(QDEC) diff --git a/components/drivers_nrf/qdec/nrf_drv_qdec.h b/components/drivers_nrf/qdec/nrf_drv_qdec.h index f825d8d..77c7c41 100644 --- a/components/drivers_nrf/qdec/nrf_drv_qdec.h +++ b/components/drivers_nrf/qdec/nrf_drv_qdec.h @@ -1,32 +1,64 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_QDEC_H__ #define NRF_DRV_QDEC_H__ #include "nrf_qdec.h" -#include "nrf_drv_config.h" +#include "sdk_config.h" #include "sdk_errors.h" #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @addtogroup nrf_qdec QDEC HAL and driver * @ingroup nrf_drivers * @brief Quadrature decoder (QDEC) APIs. - * @details The QDEC HAL provides basic APIs for accessing the registers of the QDEC. + * @details The QDEC HAL provides basic APIs for accessing the registers of the QDEC. * The QDEC driver provides APIs on a higher level. * - * @defgroup nrf_drivers_qdec QDEC driver + * @defgroup nrf_drv_qdec QDEC driver * @{ * @ingroup nrf_qdec * @brief Quadrature decoder (QDEC) driver. @@ -48,18 +80,18 @@ typedef struct } nrf_drv_qdec_config_t; /**@brief QDEC default configuration. */ -#define NRF_DRV_QDEC_DEFAULT_CONFIG \ - { \ - .reportper = QDEC_CONFIG_REPORTPER, \ - .sampleper = QDEC_CONFIG_SAMPLEPER, \ - .psela = QDEC_CONFIG_PIO_A, \ - .pselb = QDEC_CONFIG_PIO_B, \ - .pselled = QDEC_CONFIG_PIO_LED, \ - .ledpre = QDEC_CONFIG_LEDPRE, \ - .ledpol = QDEC_CONFIG_LEDPOL, \ - .interrupt_priority = QDEC_CONFIG_IRQ_PRIORITY, \ - .dbfen = QDEC_CONFIG_DBFEN, \ - .sample_inten = QDEC_CONFIG_SAMPLE_INTEN \ +#define NRF_DRV_QDEC_DEFAULT_CONFIG \ + { \ + .reportper = (nrf_qdec_reportper_t)QDEC_CONFIG_REPORTPER, \ + .sampleper = (nrf_qdec_sampleper_t)QDEC_CONFIG_SAMPLEPER, \ + .psela = QDEC_CONFIG_PIO_A, \ + .pselb = QDEC_CONFIG_PIO_B, \ + .pselled = QDEC_CONFIG_PIO_LED, \ + .ledpre = QDEC_CONFIG_LEDPRE, \ + .ledpol = (nrf_qdec_ledpol_t)QDEC_CONFIG_LEDPOL, \ + .interrupt_priority = QDEC_CONFIG_IRQ_PRIORITY, \ + .dbfen = QDEC_CONFIG_DBFEN, \ + .sample_inten = QDEC_CONFIG_SAMPLE_INTEN \ } /**@brief QDEC sample event data.*/ @@ -146,4 +178,9 @@ void nrf_drv_qdec_event_address_get(nrf_qdec_event_t event, uint32_t * p_event); /** *@} **/ + +#ifdef __cplusplus +} +#endif + #endif /* NRF_DRV_QDEC_H__ */ diff --git a/components/drivers_nrf/qspi/nrf_drv_qspi.c b/components/drivers_nrf/qspi/nrf_drv_qspi.c new file mode 100644 index 0000000..66e5fad --- /dev/null +++ b/components/drivers_nrf/qspi/nrf_drv_qspi.c @@ -0,0 +1,301 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" + +#if QSPI_ENABLED + +#include "nrf_drv_qspi.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "nrf_assert.h" + +/** + * @brief Command byte used to read status register. + * + */ +#define QSPI_STD_CMD_RDSR 0x05 + +/** + * @brief Byte used to mask status register and retrieve the write-in-progess bit. + * + */ +#define QSPI_MEM_STATUSREG_WIP_Pos 0x01 + +#define QSPI_WAIT_READY() do { \ + while (!nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY)); \ + } while(0) + +/** + * @brief Control block - driver instance local data. + * + */ +typedef struct +{ + nrf_drv_qspi_handler_t handler; /**< Handler. */ + nrf_drv_state_t state; /**< Driver state. */ + volatile bool interrupt_driven; /**< Information if the current operation is performed and is interrupt-driven. */ + void * p_context; /**< Driver context used in interrupt. */ +} qspi_control_block_t; + +static qspi_control_block_t m_cb; + +static ret_code_t qspi_task_perform(nrf_qspi_task_t task) +{ + // Wait for peripheral + if (m_cb.interrupt_driven) + { + return NRF_ERROR_BUSY; + } + + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + + if (m_cb.handler) + { + m_cb.interrupt_driven = true; + nrf_qspi_int_enable(NRF_QSPI, NRF_QSPI_INT_READY_MASK); + } + + nrf_qspi_task_trigger(NRF_QSPI, task); + + if (m_cb.handler == NULL) + { + QSPI_WAIT_READY(); + } + return NRF_SUCCESS; +} + +static bool qspi_pins_configure(nrf_qspi_pins_t const * p_config) +{ + // Check if the user set meaningful values to struct fields. If not, return false. + if ((p_config->sck_pin == NRF_QSPI_PIN_NOT_CONNECTED) || + (p_config->csn_pin == NRF_QSPI_PIN_NOT_CONNECTED) || + (p_config->io0_pin == NRF_QSPI_PIN_NOT_CONNECTED) || + (p_config->io1_pin == NRF_QSPI_PIN_NOT_CONNECTED)) + { + return false; + } + + nrf_qspi_pins_set(NRF_QSPI, p_config); + + return true; +} + +ret_code_t nrf_drv_qspi_init(nrf_drv_qspi_config_t const * p_config, + nrf_drv_qspi_handler_t handler, + void * p_context) +{ + if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + if (!qspi_pins_configure(&p_config->pins)) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_qspi_ifconfig0_set(NRF_QSPI, &p_config->prot_if); + nrf_qspi_ifconfig1_set(NRF_QSPI, &p_config->phy_if); + + m_cb.interrupt_driven = false; + m_cb.handler = handler; + m_cb.p_context = p_context; + + /* QSPI interrupt is disabled because the device should be enabled in polling mode (wait for activate + task event ready)*/ + nrf_qspi_int_disable(NRF_QSPI, NRF_QSPI_INT_READY_MASK); + + if (handler) + { + nrf_drv_common_irq_enable(QSPI_IRQn, p_config->irq_priority); + } + + m_cb.state = NRF_DRV_STATE_INITIALIZED; + + nrf_qspi_enable(NRF_QSPI); + + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + nrf_qspi_task_trigger(NRF_QSPI, NRF_QSPI_TASK_ACTIVATE); + + // Waiting for the peripheral to activate + QSPI_WAIT_READY(); + + return NRF_SUCCESS; +} + +ret_code_t nrf_drv_qspi_cinstr_xfer(nrf_qspi_cinstr_conf_t const * p_config, + void const * p_tx_buffer, + void * p_rx_buffer) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + if (m_cb.interrupt_driven) + { + return NRF_ERROR_BUSY; + } + + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + /* In some cases, only opcode should be sent. To prevent execution, set function code is + * surrounded by an if. + */ + if (p_tx_buffer) + { + nrf_qspi_cinstrdata_set(NRF_QSPI, p_config->length, p_tx_buffer); + } + nrf_qspi_int_disable(NRF_QSPI, NRF_QSPI_INT_READY_MASK); + + nrf_qspi_cinstr_transfer_start(NRF_QSPI, p_config); + + QSPI_WAIT_READY(); + nrf_qspi_int_enable(NRF_QSPI, NRF_QSPI_INT_READY_MASK); + + if (p_rx_buffer) + { + nrf_qspi_cinstrdata_get(NRF_QSPI, p_config->length, p_rx_buffer); + } + + return NRF_SUCCESS; +} + +ret_code_t nrf_drv_qspi_cinstr_quick_send(uint8_t opcode, + nrf_qspi_cinstr_len_t length, + void const * p_tx_buffer) +{ + nrf_qspi_cinstr_conf_t config = NRF_DRV_QSPI_DEFAULT_CINSTR(opcode, length); + return nrf_drv_qspi_cinstr_xfer(&config, p_tx_buffer, NULL); +} + +ret_code_t nrf_drv_qspi_mem_busy_check(void) +{ + ret_code_t ret_code; + uint8_t status_value = 0; + + nrf_qspi_cinstr_conf_t config = NRF_DRV_QSPI_DEFAULT_CINSTR(QSPI_STD_CMD_RDSR, + NRF_QSPI_CINSTR_LEN_2B); + + ret_code = nrf_drv_qspi_cinstr_xfer(&config, &status_value, &status_value); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + if ((status_value & QSPI_MEM_STATUSREG_WIP_Pos) != 0x00) + { + return NRF_ERROR_BUSY; + } + + return NRF_SUCCESS; +} + +void nrf_drv_qspi_uninit(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_qspi_int_disable(NRF_QSPI, NRF_QSPI_INT_READY_MASK); + + nrf_qspi_disable(NRF_QSPI); + + nrf_drv_common_irq_disable(QSPI_IRQn); + + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + + m_cb.state = NRF_DRV_STATE_UNINITIALIZED; +} + +ret_code_t nrf_drv_qspi_write(void const * p_tx_buffer, + size_t tx_buffer_length, + uint32_t dst_address) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_tx_buffer != NULL); + + if (!nrf_drv_is_in_RAM(p_tx_buffer)) + { + return NRF_ERROR_INVALID_ADDR; + } + + nrf_qspi_write_buffer_set(NRF_QSPI, p_tx_buffer, tx_buffer_length, dst_address); + return qspi_task_perform(NRF_QSPI_TASK_WRITESTART); + +} + +ret_code_t nrf_drv_qspi_read(void * p_rx_buffer, + size_t rx_buffer_length, + uint32_t src_address) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_rx_buffer != NULL); + + if (!nrf_drv_is_in_RAM(p_rx_buffer)) + { + return NRF_ERROR_INVALID_ADDR; + } + + nrf_qspi_read_buffer_set(NRF_QSPI, p_rx_buffer, rx_buffer_length, src_address); + return qspi_task_perform(NRF_QSPI_TASK_READSTART); +} + +ret_code_t nrf_drv_qspi_erase(nrf_qspi_erase_len_t length, + uint32_t start_address) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + nrf_qspi_erase_ptr_set(NRF_QSPI, start_address, length); + return qspi_task_perform(NRF_QSPI_TASK_ERASESTART); +} + +ret_code_t nrf_drv_qspi_chip_erase(void) +{ + return nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_ALL, 0); +} + +void QSPI_IRQHandler(void) +{ + // Catch Event ready interrupts + if (nrf_qspi_event_check(NRF_QSPI, NRF_QSPI_EVENT_READY)) + { + m_cb.interrupt_driven = false; + nrf_qspi_event_clear(NRF_QSPI, NRF_QSPI_EVENT_READY); + m_cb.handler(NRF_DRV_QSPI_EVENT_DONE, m_cb.p_context); + } +} + +#endif // QSPI_ENABLED diff --git a/components/drivers_nrf/qspi/nrf_drv_qspi.h b/components/drivers_nrf/qspi/nrf_drv_qspi.h new file mode 100644 index 0000000..e33071f --- /dev/null +++ b/components/drivers_nrf/qspi/nrf_drv_qspi.h @@ -0,0 +1,312 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * @addtogroup nrf_qspi QSPI HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52840 Quad serial peripheral interface (QSPI) APIs. + * + * @defgroup nrf_drv_qspi QSPI driver + * @{ + * @ingroup nrf_qspi + * @brief @tagAPI52840 Quad serial peripheral interface (QSPI) driver. + */ + +#ifndef NRF_DRV_QSPI_H__ +#define NRF_DRV_QSPI_H__ + +#include "nordic_common.h" +#include "sdk_config.h" +#include "nrf_qspi.h" +#include "sdk_errors.h" +#include "boards.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief QSPI driver instance configuration structure. + */ +typedef struct +{ + nrf_qspi_pins_t pins; /**< Pins configuration structure. */ + nrf_qspi_prot_conf_t prot_if; /**< Protocol layer interface configuration structure. */ + nrf_qspi_phy_conf_t phy_if; /**< Physical layer interface configuration structure. */ + uint8_t irq_priority; /**< Interrupt priority. */ +} nrf_drv_qspi_config_t; + +#if QSPI_PIN_SCK == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_SCK + #define QSPI_PIN_SCK BSP_QSPI_SCK_PIN +#endif +#if QSPI_PIN_CSN == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_CSN + #define QSPI_PIN_CSN BSP_QSPI_CSN_PIN +#endif +#if QSPI_PIN_IO0 == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_IO0 + #define QSPI_PIN_IO0 BSP_QSPI_IO0_PIN +#endif +#if QSPI_PIN_IO1 == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_IO1 + #define QSPI_PIN_IO1 BSP_QSPI_IO1_PIN +#endif +#if QSPI_PIN_IO2 == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_IO2 + #define QSPI_PIN_IO2 BSP_QSPI_IO2_PIN +#endif +#if QSPI_PIN_IO3 == NRF_QSPI_PIN_NOT_CONNECTED + #undef QSPI_PIN_IO3 + #define QSPI_PIN_IO3 BSP_QSPI_IO3_PIN +#endif +/** + * @brief QSPI instance default configuration. + */ +#define NRF_DRV_QSPI_DEFAULT_CONFIG \ +{ \ + .pins = { \ + .sck_pin = QSPI_PIN_SCK, \ + .csn_pin = QSPI_PIN_CSN, \ + .io0_pin = QSPI_PIN_IO0, \ + .io1_pin = QSPI_PIN_IO1, \ + .io2_pin = QSPI_PIN_IO2, \ + .io3_pin = QSPI_PIN_IO3, \ + }, \ + .irq_priority = (uint8_t)QSPI_CONFIG_IRQ_PRIORITY, \ + .prot_if = { \ + .readoc = (nrf_qspi_readoc_t) QSPI_CONFIG_READOC, \ + .writeoc = (nrf_qspi_writeoc_t) QSPI_CONFIG_WRITEOC, \ + .addrmode = (nrf_qspi_addrmode_t) QSPI_CONFIG_ADDRMODE, \ + .dpmconfig = false, \ + }, \ + .phy_if = { \ + .sck_freq = (nrf_qspi_frequency_t) QSPI_CONFIG_FREQUENCY, \ + .sck_delay = (uint8_t) QSPI_CONFIG_SCK_DELAY, \ + .spi_mode = (nrf_qspi_spi_mode_t) QSPI_CONFIG_MODE, \ + .dpmen = false \ + } \ +} + + +/** + * @brief QSPI custom instruction helper with default configuration. + */ +#define NRF_DRV_QSPI_DEFAULT_CINSTR(opc, len) \ +{ \ + .opcode = (opc), \ + .length = (len), \ + .io2_level = false, \ + .io3_level = false, \ + .wipwait = false, \ + .wren = false \ +} + +/** + * @brief QSPI master driver event types, passed to the handler routine provided + * during initialization. + */ +typedef enum +{ + NRF_DRV_QSPI_EVENT_DONE, /**< Transfer done. */ +} nrf_drv_qspi_evt_t; + +/** + * @brief QSPI driver event handler type. + */ +typedef void (*nrf_drv_qspi_handler_t)(nrf_drv_qspi_evt_t event, void * p_context); + +/** + * @brief Function for initializing the QSPI driver instance. + * + * @param[in] p_config Pointer to the structure with the initial configuration. + * @param[in] handler Event handler provided by the user. If NULL, transfers + * will be performed in blocking mode. + * @param[in] p_context Pointer to context. Use in interrupt handler. + * + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver was already initialized. + * @retval NRF_ERROR_INVALID_PARAM If the pin configuration was incorrect. + */ +ret_code_t nrf_drv_qspi_init(nrf_drv_qspi_config_t const * p_config, + nrf_drv_qspi_handler_t handler, + void * p_context); + +/** + * @brief Function for uninitializing the QSPI driver instance. + */ +void nrf_drv_qspi_uninit(void); + +/** + * @brief Function for reading data from QSPI memory. + * + * Write, read, and erase operations check memory device busy state before starting the operation. + * If the memory is busy, the resulting action depends on the mode in which the read operation is used: + * - blocking mode (without handler) - a delay occurs until the last operation still runs and + * until operation data is still being read. + * - interrupt mode (with handler) - event emission occurs after the last operation + * and reading of data are finished. + * + * @param[out] p_rx_buffer Pointer to the receive buffer. + * @param[in] rx_buffer_length Size of the data to read. + * @param[in] src_address Address in memory to read from. + * + * @retval NRF_SUCCESS If the operation was successful (blocking mode) or operation + * was commissioned (handler mode). + * @retval NRF_ERROR_BUSY If the driver currently handles another operation. + * @retval NRF_ERROR_INVALID_ADDR If the provided buffer is not placed in the Data RAM region. + */ +ret_code_t nrf_drv_qspi_read(void * p_rx_buffer, + size_t rx_buffer_length, + uint32_t src_address); + +/** + * @brief Function for writing data to QSPI memory. + * + * Write, read, and erase operations check memory device busy state before starting the operation. + * If the memory is busy, the resulting action depends on the mode in which the write operation is used: + * - blocking mode (without handler) - a delay occurs until the last operation still runs and + * until operation data is still being sent. + * - interrupt mode (with handler) - event emission occurs after the last operation + * and sending of operation data are finished. + * To manually control operation execution in the memory device, use @ref nrf_drv_qspi_mem_busy_check + * after executing the write function. + * Remember that an incoming event signalizes only that data was sent to the memory device and the periheral + * before the write operation checked if memory was busy. + * + * @param[in] p_tx_buffer Pointer to the writing buffer. + * @param[in] tx_buffer_length Size of the data to write. + * @param[in] dst_address Address in memory to write to. + * + * @retval NRF_SUCCESS If the operation was successful (blocking mode) or operation + * was commissioned (handler mode). + * @retval NRF_ERROR_BUSY If the driver currently handles other operation. + * @retval NRF_ERROR_INVALID_ADDR If the provided buffer is not placed in the Data RAM region. + */ +ret_code_t nrf_drv_qspi_write(void const * p_tx_buffer, + size_t tx_buffer_length, + uint32_t dst_address); + +/** + * @brief Function for starting erasing of one memory block - 4KB, 64KB, or the whole chip. + * + * Write, read, and erase operations check memory device busy state before starting the operation. + * If the memory is busy, the resulting action depends on the mode in which the erase operation is used: + * - blocking mode (without handler) - a delay occurs until the last operation still runs and + * until operation data is still being sent. + * - interrupt mode (with handler) - event emission occurs after the last operation + * and sending of operation data are finished. + * To manually control operation execution in the memory device, use @ref nrf_drv_qspi_mem_busy_check + * after executing the erase function. + * Remember that an incoming event signalizes only that data was sent to the memory device and the periheral + * before the erase operation checked if memory was busy. + * + * @param[in] length Size of data to erase. See @ref nrf_qspi_erase_len_t. + * @param[in] start_address Memory address to start erasing. If chip erase is performed, address + * field is ommited. + * + * @retval NRF_SUCCESS If the operation was successful (blocking mode) or operation + * was commissioned (handler mode). + * @retval NRF_ERROR_BUSY If the driver currently handles another operation. + */ +ret_code_t nrf_drv_qspi_erase(nrf_qspi_erase_len_t length, + uint32_t start_address); + +/** + * @brief Function for starting an erase operation of the whole chip. + * + * @retval NRF_SUCCESS If the operation was successful (blocking mode) or operation + * was commissioned (handler mode). + * @retval NRF_ERROR_BUSY If the driver currently handles another operation. + */ +ret_code_t nrf_drv_qspi_chip_erase(void); + +/** + * @brief Function for getting the current driver status and status byte of memory device with + * testing WIP (write in progress) bit. + * + * @retval NRF_SUCCESS If the driver and memory are ready to handle a new operation. + * @retval NRF_ERROR_BUSY If the driver or memory currently handle another operation. + */ +ret_code_t nrf_drv_qspi_mem_busy_check(void); + +/** + * @brief Function for sending operation code, sending data, and receiving data from the memory device. + * + * Use this function to transfer configuration data to memory and to receive data from memory. + * Pointers can be addresses from flash memory. + * This function is a synchronous function and should be used only if necessary. + * See more: @ref hardware_driver_qspi. + * + * @param[in] p_config Pointer to the structure with opcode and transfer configuration. + * @param[in] p_tx_buffer Pointer to the array with data to send. Can be NULL if only opcode is transmitted. + * @param[out] p_rx_buffer Pointer to the array for data to receive. Can be NULL if there is nothing to receive. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_BUSY If the driver currently handles other operation. + */ +ret_code_t nrf_drv_qspi_cinstr_xfer(nrf_qspi_cinstr_conf_t const * p_config, + void const * p_tx_buffer, + void * p_rx_buffer); +/** + * @brief Function for sending operation code and data to the memory device with simpler configuration. + * + * Use this function to transfer configuration data to memory and to receive data from memory. + * This function is a synchronous function and should be used only if necessary. + * + * @param[in] opcode Operation code. Sending first. + * @param[in] length Length of the data to send and opcode. See @ref nrf_qspi_cinstr_len_t. + * @param[in] p_tx_buffer Pointer to input data array. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_BUSY If the driver currently handles another operation. + */ +ret_code_t nrf_drv_qspi_cinstr_quick_send(uint8_t opcode, + nrf_qspi_cinstr_len_t length, + void const * p_tx_buffer); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_QSPI_H__ + +/** @} */ diff --git a/components/drivers_nrf/radio_config/radio_config.c b/components/drivers_nrf/radio_config/radio_config.c index a739025..5f529a7 100644 --- a/components/drivers_nrf/radio_config/radio_config.c +++ b/components/drivers_nrf/radio_config/radio_config.c @@ -1,30 +1,58 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @addtogroup nrf_dev_radio_rx_example_main nrf_dev_radio_tx_example_main * @{ */ - + #include "radio_config.h" #include "nrf_delay.h" -/* These are set to zero as Shockburst packets don't have corresponding fields. */ +/* These are set to zero as ShockBurst packets don't have corresponding fields. */ #define PACKET_S1_FIELD_SIZE (0UL) /**< Packet S1 field size in bits. */ #define PACKET_S0_FIELD_SIZE (0UL) /**< Packet S0 field size in bits. */ #define PACKET_LENGTH_FIELD_SIZE (0UL) /**< Packet length field size in bits. */ /** * @brief Function for swapping/mirroring bits in a byte. - * + * *@verbatim * output_bit_7 = input_bit_0 * output_bit_6 = input_bit_1 @@ -41,10 +69,10 @@ static uint32_t swap_bits(uint32_t inp); /** * @brief Function for swapping bits in a 32 bit word for each byte individually. - * + * * The bits are swapped as follows: * @verbatim - * output[31:24] = input[24:31] + * output[31:24] = input[24:31] * output[23:16] = input[16:23] * output[15:8] = input[8:15] * output[7:0] = input[0:7] @@ -60,15 +88,15 @@ static uint32_t swap_bits(uint32_t inp) { uint32_t i; uint32_t retval = 0; - + inp = (inp & 0x000000FFUL); - + for (i = 0; i < 8; i++) { - retval |= ((inp >> i) & 0x01) << (7 - i); + retval |= ((inp >> i) & 0x01) << (7 - i); } - - return retval; + + return retval; } @@ -81,17 +109,17 @@ static uint32_t bytewise_bitswap(uint32_t inp) } -/** - * @brief Function for configuring the radio to operate in Shockburst compatible mode. - * +/** + * @brief Function for configuring the radio to operate in ShockBurst compatible mode. + * * To configure the application running on nRF24L series devices: * * @verbatim * uint8_t tx_address[5] = { 0xC0, 0x01, 0x23, 0x45, 0x67 }; * hal_nrf_set_rf_channel(7); - * hal_nrf_set_address_width(HAL_NRF_AW_5BYTES); + * hal_nrf_set_address_width(HAL_NRF_AW_5BYTES); * hal_nrf_set_address(HAL_NRF_TX, tx_address); - * hal_nrf_set_address(HAL_NRF_PIPE0, tx_address); + * hal_nrf_set_address(HAL_NRF_PIPE0, tx_address); * hal_nrf_open_pipe(0, false); * hal_nrf_set_datarate(HAL_NRF_1MBPS); * hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT); @@ -102,7 +130,7 @@ static uint32_t bytewise_bitswap(uint32_t inp) * When transmitting packets with hal_nrf_write_tx_payload(const uint8_t *tx_pload, uint8_t length), * match the length with PACKET_STATIC_LENGTH. * hal_nrf_write_tx_payload(payload, PACKET_STATIC_LENGTH); - * + * */ void radio_configure() { @@ -112,20 +140,20 @@ void radio_configure() NRF_RADIO->MODE = (RADIO_MODE_MODE_Nrf_1Mbit << RADIO_MODE_MODE_Pos); // Radio address config - NRF_RADIO->PREFIX0 = + NRF_RADIO->PREFIX0 = ((uint32_t)swap_bits(0xC3) << 24) // Prefix byte of address 3 converted to nRF24L series format | ((uint32_t)swap_bits(0xC2) << 16) // Prefix byte of address 2 converted to nRF24L series format | ((uint32_t)swap_bits(0xC1) << 8) // Prefix byte of address 1 converted to nRF24L series format | ((uint32_t)swap_bits(0xC0) << 0); // Prefix byte of address 0 converted to nRF24L series format - - NRF_RADIO->PREFIX1 = + + NRF_RADIO->PREFIX1 = ((uint32_t)swap_bits(0xC7) << 24) // Prefix byte of address 7 converted to nRF24L series format | ((uint32_t)swap_bits(0xC6) << 16) // Prefix byte of address 6 converted to nRF24L series format | ((uint32_t)swap_bits(0xC4) << 0); // Prefix byte of address 4 converted to nRF24L series format NRF_RADIO->BASE0 = bytewise_bitswap(0x01234567UL); // Base address for prefix 0 converted to nRF24L series format NRF_RADIO->BASE1 = bytewise_bitswap(0x89ABCDEFUL); // Base address for prefix 1-7 converted to nRF24L series format - + NRF_RADIO->TXADDRESS = 0x00UL; // Set device address 0 to use when transmitting NRF_RADIO->RXADDRESSES = 0x01UL; // Enable device address 0 to use to select which addresses to receive @@ -145,16 +173,16 @@ void radio_configure() NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos); // Number of checksum bits if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos)) { - NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value - NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16+x^12^x^5+1 + NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value + NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16 + x^12^x^5 + 1 } else if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_One << RADIO_CRCCNF_LEN_Pos)) { NRF_RADIO->CRCINIT = 0xFFUL; // Initial value - NRF_RADIO->CRCPOLY = 0x107UL; // CRC poly: x^8+x^2^x^1+1 + NRF_RADIO->CRCPOLY = 0x107UL; // CRC poly: x^8 + x^2^x^1 + 1 } } -/** +/** * @} */ diff --git a/components/drivers_nrf/radio_config/radio_config.h b/components/drivers_nrf/radio_config/radio_config.h index 734ff14..2b4cacd 100644 --- a/components/drivers_nrf/radio_config/radio_config.h +++ b/components/drivers_nrf/radio_config/radio_config.h @@ -1,21 +1,58 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 RADIO_CONFIG_H #define RADIO_CONFIG_H +#ifdef __cplusplus +extern "C" { +#endif + #define PACKET_BASE_ADDRESS_LENGTH (4UL) //!< Packet base address length field size in bytes #define PACKET_STATIC_LENGTH (1UL) //!< Packet static length in bytes #define PACKET_PAYLOAD_MAXSIZE (PACKET_STATIC_LENGTH) //!< Packet payload maximum size in bytes void radio_configure(void); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_nrf/rng/nrf_drv_rng.c b/components/drivers_nrf/rng/nrf_drv_rng.c index 7294b9b..fb4a9ea 100644 --- a/components/drivers_nrf/rng/nrf_drv_rng.c +++ b/components/drivers_nrf/rng/nrf_drv_rng.c @@ -1,219 +1,297 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(RNG) + #include #include - #include "nrf_drv_rng.h" -#include "nrf_assert.h" #include "nrf_drv_common.h" #include "nordic_common.h" -#include "nrf_error.h" #include "nrf_assert.h" +#include "nrf_queue.h" + #ifdef SOFTDEVICE_PRESENT -#include "nrf_sdm.h" -#include "nrf_soc.h" -#else -#include "app_fifo.h" -#include "app_util_platform.h" + #include "softdevice_handler.h" + #include "nrf_soc.h" + #include "app_util_platform.h" +#endif // SOFTDEVICE_PRESENT -static __INLINE uint32_t fifo_length(app_fifo_t * p_fifo) -{ - uint32_t tmp = p_fifo->read_pos; - return p_fifo->write_pos - tmp; -} +#define NRF_LOG_MODULE_NAME "RNG" -#define FIFO_LENGTH(fifo) fifo_length(&(fifo)) /**< Macro for calculating the FIFO length. */ +#if RNG_CONFIG_LOG_ENABLED + #define NRF_LOG_LEVEL RNG_CONFIG_LOG_LEVEL + #define NRF_LOG_INFO_COLOR RNG_CONFIG_INFO_COLOR + #define NRF_LOG_DEBUG_COLOR RNG_CONFIG_DEBUG_COLOR +#else //RNG_CONFIG_LOG_ENABLED + #define NRF_LOG_LEVEL 0 +#endif //RNG_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +/* Validate configuration */ +INTERRUPT_PRIORITY_VALIDATION(RNG_CONFIG_IRQ_PRIORITY); -#endif // SOFTDEVICE_PRESENT typedef struct { - nrf_drv_state_t state; -#ifndef SOFTDEVICE_PRESENT - app_fifo_t rand_pool; - uint8_t buffer[RNG_CONFIG_POOL_SIZE]; -#endif // SOFTDEVICE_PRESENT + nrf_drv_state_t state; + nrf_drv_rng_config_t config; } nrf_drv_rng_cb_t; static nrf_drv_rng_cb_t m_rng_cb; -#ifndef SOFTDEVICE_PRESENT +NRF_QUEUE_DEF(uint8_t, m_rand_pool, RNG_CONFIG_POOL_SIZE, NRF_QUEUE_MODE_OVERFLOW); static const nrf_drv_rng_config_t m_default_config = NRF_DRV_RNG_DEFAULT_CONFIG; -static void rng_start(void) + +#ifdef SOFTDEVICE_PRESENT + #define SD_RAND_POOL_SIZE (32) + STATIC_ASSERT(RNG_CONFIG_POOL_SIZE == SD_RAND_POOL_SIZE); + + #define NRF_DRV_RNG_LOCK() CRITICAL_REGION_ENTER() + #define NRF_DRV_RNG_RELEASE() CRITICAL_REGION_EXIT() + #define NRF_DRV_RNG_SD_IS_ENABLED() softdevice_handler_is_enabled() +#else + #define NRF_DRV_RNG_LOCK() do { } while (0) + #define NRF_DRV_RNG_RELEASE() do { } while (0) + #define NRF_DRV_RNG_SD_IS_ENABLED() false +#endif // SOFTDEVICE_PRESENT + +/** + * @brief Function for starting generation. + */ +static void nrf_drv_rng_start(void) { - if (FIFO_LENGTH(m_rng_cb.rand_pool) <= m_rng_cb.rand_pool.buf_size_mask) - { - nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); - nrf_rng_int_enable(NRF_RNG_INT_VALRDY_MASK); - nrf_rng_task_trigger(NRF_RNG_TASK_START); - } -} + ASSERT(!NRF_DRV_RNG_SD_IS_ENABLED()); + nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); + nrf_rng_int_enable(NRF_RNG_INT_VALRDY_MASK); + nrf_rng_task_trigger(NRF_RNG_TASK_START); +} -static void rng_stop(void) +/** + * @brief Function for stoping generation. + */ +static void nrf_drv_rng_stop(void) { + ASSERT(!NRF_DRV_RNG_SD_IS_ENABLED()); + nrf_rng_int_disable(NRF_RNG_INT_VALRDY_MASK); nrf_rng_task_trigger(NRF_RNG_TASK_STOP); } +/** + * @brief Function for setting up RNG hardware. + */ +static void nrf_drv_rng_setup(void) +{ + ASSERT(!NRF_DRV_RNG_SD_IS_ENABLED()); -#endif // SOFTDEVICE_PRESENT - + if (m_rng_cb.config.error_correction) + { + nrf_rng_error_correction_enable(); + } + nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK); + nrf_drv_common_irq_enable(RNG_IRQn, m_rng_cb.config.interrupt_priority); +} ret_code_t nrf_drv_rng_init(nrf_drv_rng_config_t const * p_config) { - uint32_t result; - - if (m_rng_cb.state == NRF_DRV_STATE_UNINITIALIZED) + if (m_rng_cb.state != NRF_DRV_STATE_UNINITIALIZED) { -#ifndef SOFTDEVICE_PRESENT + return NRF_ERROR_MODULE_ALREADY_INITIALIZED; + } - result = app_fifo_init(&m_rng_cb.rand_pool, m_rng_cb.buffer, RNG_CONFIG_POOL_SIZE); + if (p_config == NULL) + { + p_config = &m_default_config; + } + m_rng_cb.config = *p_config; - if (p_config == NULL) - { - p_config = &m_default_config; - } + NRF_DRV_RNG_LOCK(); - if (result == NRF_SUCCESS) - { - if (p_config->error_correction) - { - nrf_rng_error_correction_enable(); - } + if (!NRF_DRV_RNG_SD_IS_ENABLED()) + { + nrf_drv_rng_setup(); + nrf_drv_rng_start(); + } - nrf_drv_common_irq_enable(RNG_IRQn, p_config->interrupt_priority); + NRF_DRV_RNG_RELEASE(); - nrf_rng_shorts_disable(NRF_RNG_SHORT_VALRDY_STOP_MASK); + m_rng_cb.state = NRF_DRV_STATE_INITIALIZED; - rng_start(); - m_rng_cb.state = NRF_DRV_STATE_INITIALIZED; - } -#else - UNUSED_VARIABLE(p_config); - uint8_t softdevice_is_enabled; - result = sd_softdevice_is_enabled(&softdevice_is_enabled); - - if (softdevice_is_enabled) - { - m_rng_cb.state = NRF_DRV_STATE_INITIALIZED; - } - else - { - result = NRF_ERROR_SOFTDEVICE_NOT_ENABLED; - } -#endif // SOFTDEVICE_PRESENT - } - else - { - result = NRF_ERROR_INVALID_STATE; - } - return result; + return NRF_SUCCESS; } - void nrf_drv_rng_uninit(void) { ASSERT(m_rng_cb.state == NRF_DRV_STATE_INITIALIZED); + NRF_DRV_RNG_LOCK(); + + if (!NRF_DRV_RNG_SD_IS_ENABLED()) + { + nrf_drv_rng_stop(); + nrf_drv_common_irq_disable(RNG_IRQn); + } + + NRF_DRV_RNG_RELEASE(); + + nrf_queue_reset(&m_rand_pool); m_rng_cb.state = NRF_DRV_STATE_UNINITIALIZED; -#ifndef SOFTDEVICE_PRESENT - rng_stop(); - nrf_drv_common_irq_disable(RNG_IRQn); -#endif // SOFTDEVICE_PRESENT + NRF_LOG_INFO("Uninitialized.\r\n"); } -ret_code_t nrf_drv_rng_bytes_available(uint8_t * p_bytes_available) +void nrf_drv_rng_bytes_available(uint8_t * p_bytes_available) { - ret_code_t result; ASSERT(m_rng_cb.state == NRF_DRV_STATE_INITIALIZED); -#ifndef SOFTDEVICE_PRESENT - - result = NRF_SUCCESS; - *p_bytes_available = FIFO_LENGTH(m_rng_cb.rand_pool); - -#else - - result = sd_rand_application_bytes_available_get(p_bytes_available); - +#ifdef SOFTDEVICE_PRESENT + if (NRF_DRV_RNG_SD_IS_ENABLED()) + { + if (NRF_SUCCESS == sd_rand_application_bytes_available_get(p_bytes_available)) + { + return; + } + } #endif // SOFTDEVICE_PRESENT - return result; + *p_bytes_available = nrf_queue_utilization_get(&m_rand_pool); + + NRF_LOG_INFO("Function: %s, available bytes: %d.\r\n", (uint32_t)__func__, *p_bytes_available); } -ret_code_t nrf_drv_rng_pool_capacity(uint8_t * p_pool_capacity) +ret_code_t nrf_drv_rng_rand(uint8_t * p_buff, uint8_t length) { - ret_code_t result; + ret_code_t err_code = NRF_SUCCESS; ASSERT(m_rng_cb.state == NRF_DRV_STATE_INITIALIZED); -#ifndef SOFTDEVICE_PRESENT - - result = NRF_SUCCESS; - *p_pool_capacity = RNG_CONFIG_POOL_SIZE; +#ifdef SOFTDEVICE_PRESENT + do { + bool sd_is_enabled; + NRF_DRV_RNG_LOCK(); + sd_is_enabled = NRF_DRV_RNG_SD_IS_ENABLED(); + if (!sd_is_enabled) +#endif // SOFTDEVICE_PRESENT + { + err_code = nrf_queue_read(&m_rand_pool, p_buff, (uint32_t)length); + nrf_drv_rng_start(); + } +#ifdef SOFTDEVICE_PRESENT + NRF_DRV_RNG_RELEASE(); -#else + if (sd_is_enabled) + { + err_code = sd_rand_application_vector_get(p_buff, length); + if (err_code == NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES) + { + err_code = NRF_ERROR_NOT_FOUND; + } + } + } while (err_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED); +#endif // SOFTDEVICE_PRESENT + ASSERT((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND)); - result = sd_rand_application_pool_capacity_get(p_pool_capacity); + NRF_LOG_DEBUG("Rand buffer data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_buff, length); + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, + (uint32_t)ERR_TO_STR(err_code)); -#endif // SOFTDEVICE_PRESENT - return result; + return err_code; } -ret_code_t nrf_drv_rng_rand(uint8_t * p_buff, uint8_t length) +void nrf_drv_rng_block_rand(uint8_t * p_buff, uint32_t length) { - ret_code_t result; - ASSERT(m_rng_cb.state == NRF_DRV_STATE_INITIALIZED); -#ifndef SOFTDEVICE_PRESENT - if (FIFO_LENGTH(m_rng_cb.rand_pool) >= length) + while (length) { - result = NRF_SUCCESS; - - for (uint32_t i = 0; (i < length) && (result == NRF_SUCCESS); i++) - { - result = app_fifo_get(&(m_rng_cb.rand_pool), &p_buff[i]); - } - rng_start(); - } - else - { - result = NRF_ERROR_NO_MEM; - } -#else - - result = sd_rand_application_vector_get(p_buff, length); + uint32_t len = MIN(length, RNG_CONFIG_POOL_SIZE); + ret_code_t err_code; -#endif // SOFTDEVICE_PRESENT + do { + err_code = nrf_drv_rng_rand(p_buff, len); + } while(err_code != NRF_SUCCESS); + length -= len; + p_buff += len; + } - return result; + NRF_LOG_DEBUG("Rand buffer data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_buff, length); } +#ifdef SOFTDEVICE_PRESENT +void nrf_drv_rng_on_sd_disable(void) +{ + NRF_DRV_RNG_LOCK(); + if (m_rng_cb.state == NRF_DRV_STATE_INITIALIZED) + { + nrf_drv_rng_setup(); + nrf_drv_rng_start(); + } + NRF_DRV_RNG_RELEASE(); +} +#endif // SOFTDEVICE_PRESENT -#ifndef SOFTDEVICE_PRESENT void RNG_IRQHandler(void) { - if (nrf_rng_event_get(NRF_RNG_EVENT_VALRDY) && + NRF_DRV_RNG_LOCK(); + if ( + !NRF_DRV_RNG_SD_IS_ENABLED() && + nrf_rng_event_get(NRF_RNG_EVENT_VALRDY) && nrf_rng_int_get(NRF_RNG_INT_VALRDY_MASK)) { nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY); - uint32_t nrf_error = app_fifo_put(&m_rng_cb.rand_pool, nrf_rng_random_value_get()); - if ((FIFO_LENGTH(m_rng_cb.rand_pool) > m_rng_cb.rand_pool.buf_size_mask) || (nrf_error == NRF_ERROR_NO_MEM)) + uint8_t new_value = nrf_rng_random_value_get(); + UNUSED_RETURN_VALUE(nrf_queue_push(&m_rand_pool, &new_value)); + + if (nrf_queue_is_full(&m_rand_pool)) { - rng_stop(); + nrf_drv_rng_stop(); } + + NRF_LOG_DEBUG("Event: NRF_RNG_EVENT_VALRDY.\r\n"); } + NRF_DRV_RNG_RELEASE(); } -#endif // SOFTDEVICE_PRESENT +#endif // NRF_MODULE_ENABLED(RNG) diff --git a/components/drivers_nrf/rng/nrf_drv_rng.h b/components/drivers_nrf/rng/nrf_drv_rng.h index 52136eb..887445a 100644 --- a/components/drivers_nrf/rng/nrf_drv_rng.h +++ b/components/drivers_nrf/rng/nrf_drv_rng.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_RNG_H__ @@ -18,14 +46,19 @@ #include "nrf_rng.h" #include "sdk_errors.h" -#include "nrf_drv_config.h" +#include "sdk_config.h" +#include "nrf_drv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif /** * @addtogroup nrf_rng RNG HAL and driver * @ingroup nrf_drivers * @brief Random number generator (RNG) APIs. - * @details The RNG HAL provides basic APIs for accessing the registers of the random number generator. - * The RNG driver provides APIs on a higher level. + * @details The RNG HAL provides basic APIs for accessing the registers of the random number + * generator. The RNG driver provides APIs on a higher level. * * @defgroup nrf_drv_rng RNG driver * @{ @@ -50,12 +83,10 @@ typedef struct /** * @brief Function for initializing the nrf_drv_rng module. * - * @param[in] p_config Initial configuration. Default configuration used if NULL. + * @param[in] p_config Initial configuration. Default configuration used if NULL. * - * @retval NRF_SUCCESS Driver was successfully initialized. - * @retval NRF_ERROR_INVALID_STATE Driver was already initialized. - * @retval NRF_ERROR_INVALID_LENGTH Pool size have to be a power of 2. - * @retval NRF_ERROR_SOFTDEVICE_NOT_ENABLED SoftDevice is present, but not enabled. + * @retval NRF_SUCCESS Driver was successfully initialized. + * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED Driver was already initialized. */ ret_code_t nrf_drv_rng_init(nrf_drv_rng_config_t const * p_config); @@ -67,38 +98,51 @@ void nrf_drv_rng_uninit(void); /** * @brief Function for getting the number of currently available random bytes. * - * @param[out] p_bytes_available The number of bytes currently available in the pool. - * - * @retval NRF_SUCCESS If the number of available random bytes was written to p_bytes_available. - * @retval NRF_ERROR_INVALID_STATE If the driver was not initialized. + * @param[out] p_bytes_available The number of bytes currently available in the pool. */ -ret_code_t nrf_drv_rng_bytes_available(uint8_t * p_bytes_available); +void nrf_drv_rng_bytes_available(uint8_t * p_bytes_available); /** - * @brief Function for querying the capacity of the application random pool. + * @brief Function for getting the vector of random numbers. * - * @param[out] p_pool_capacity The capacity of the pool. + * @param[out] p_buff Pointer to uint8_t buffer for storing the bytes. + * @param[in] length Number of bytes to take from the pool and place in p_buff. * - * @retval NRF_SUCCESS If the capacity of the pool was written to p_pool_capacity. - * @retval NRF_ERROR_INVALID_STATE If the driver was not initialized. + * @retval NRF_SUCCESS If the requested bytes were written to p_buff. + * @retval NRF_ERROR_NOT_FOUND If no bytes were written to the buffer because there were + * not enough bytes available in the pool. */ -ret_code_t nrf_drv_rng_pool_capacity(uint8_t * p_pool_capacity); +ret_code_t nrf_drv_rng_rand(uint8_t * p_buff, uint8_t length); /** - * @brief Function for getting the vector of random numbers. + * @brief Blocking function for getting an arbitrary array of random numbers. * - * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. - * @param[in] length Number of bytes to take from the pool and place in p_buff. + * @note This function may execute for a substantial amount of time depending on the length + * of the buffer required and on the state of the current internal pool of random numbers. * - * @retval NRF_SUCCESS If the requested bytes were written to p_buff. - * @retval NRF_ERROR_INVALID_STATE If the driver was not initialized. - * @retval NRF_ERROR_NO_MEM If no bytes were written to the buffer - * because there were not enough bytes available in p_buff. - * @retval NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES If no bytes were written to the buffer - * because there were not enough bytes available in the pool. + * @param[out] p_buff Pointer to uint8_t buffer for storing the bytes. + * @param[in] length Number of bytes place in p_buff. */ -ret_code_t nrf_drv_rng_rand(uint8_t * p_buff, uint8_t length); +void nrf_drv_rng_block_rand(uint8_t * p_buff, uint32_t length); + +#ifdef SOFTDEVICE_PRESENT +/** + * @brief Function called by the SoftDevice handler when the SoftDevice has been disabled. + * + * This function is called just after the SoftDevice has been properly disabled. + * It has two purposes: + * 1. Reinitializes RNG hardware. + * 2. Trigger new random numbers generation. + */ +void nrf_drv_rng_on_sd_disable(void); + +#endif /** *@} **/ + +#ifdef __cplusplus +} +#endif + #endif // NRF_DRV_RNG_H__ diff --git a/components/drivers_nrf/rtc/nrf_drv_rtc.c b/components/drivers_nrf/rtc/nrf_drv_rtc.c index 2588885..21a7de5 100644 --- a/components/drivers_nrf/rtc/nrf_drv_rtc.c +++ b/components/drivers_nrf/rtc/nrf_drv_rtc.c @@ -1,20 +1,72 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(RTC) +#define ENABLED_RTC_COUNT (RTC0_ENABLED+RTC1_ENABLED+RTC2_ENABLED) +#if ENABLED_RTC_COUNT + #include "nrf_drv_rtc.h" #include "nrf_rtc.h" #include "nrf_assert.h" #include "app_util_platform.h" +#define NRF_LOG_MODULE_NAME "RTC" + +#if RTC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL RTC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR RTC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR RTC_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_RTC_EVENT_TICK ? "NRF_RTC_EVENT_TICK" : \ + (event == NRF_RTC_EVENT_OVERFLOW ? "NRF_RTC_EVENT_OVERFLOW" : \ + (event == NRF_RTC_EVENT_COMPARE_0 ? "NRF_RTC_EVENT_COMPARE_0" : \ + (event == NRF_RTC_EVENT_COMPARE_1 ? "NRF_RTC_EVENT_COMPARE_1" : \ + (event == NRF_RTC_EVENT_COMPARE_2 ? "NRF_RTC_EVENT_COMPARE_2" : \ + (event == NRF_RTC_EVENT_COMPARE_3 ? "NRF_RTC_EVENT_COMPARE_3" : "UNKNOWN EVENT") +#else //RTC_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //RTC_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + /**@brief RTC driver instance control block structure. */ typedef struct { @@ -24,39 +76,33 @@ typedef struct } nrf_drv_rtc_cb_t; // User callbacks local storage. -static nrf_drv_rtc_handler_t m_handlers[RTC_COUNT]; -static nrf_drv_rtc_cb_t m_cb[RTC_COUNT]; - -static const nrf_drv_rtc_config_t m_default_config[] = { -#if (RTC0_ENABLED == 1) - NRF_DRV_RTC_DEFAULT_CONFIG(0), -#endif -#if (RTC1_ENABLED == 1) - NRF_DRV_RTC_DEFAULT_CONFIG(1) -#endif -}; +static nrf_drv_rtc_handler_t m_handlers[ENABLED_RTC_COUNT]; +static nrf_drv_rtc_cb_t m_cb[ENABLED_RTC_COUNT]; ret_code_t nrf_drv_rtc_init(nrf_drv_rtc_t const * const p_instance, nrf_drv_rtc_config_t const * p_config, nrf_drv_rtc_handler_t handler) { + ASSERT(p_config); + + ret_code_t err_code; + if (handler) { m_handlers[p_instance->instance_id] = handler; } else { - return NRF_ERROR_INVALID_PARAM; - } - - if (p_config == NULL) - { - p_config = &m_default_config[p_instance->instance_id]; + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } if (m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED) { - return NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } nrf_drv_common_irq_enable(p_instance->irq, p_config->interrupt_priority); @@ -65,7 +111,9 @@ ret_code_t nrf_drv_rtc_init(nrf_drv_rtc_t const * const p_instance, m_cb[p_instance->instance_id].tick_latency = p_config->tick_latency; m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED; - return NRF_SUCCESS; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } void nrf_drv_rtc_uninit(nrf_drv_rtc_t const * const p_instance) @@ -85,6 +133,7 @@ void nrf_drv_rtc_uninit(nrf_drv_rtc_t const * const p_instance) nrf_rtc_int_disable(p_instance->p_reg, mask); m_cb[p_instance->instance_id].state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized.\r\n"); } void nrf_drv_rtc_enable(nrf_drv_rtc_t const * const p_instance) @@ -93,21 +142,24 @@ void nrf_drv_rtc_enable(nrf_drv_rtc_t const * const p_instance) nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_START); m_cb[p_instance->instance_id].state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled.\r\n"); } void nrf_drv_rtc_disable(nrf_drv_rtc_t const * const p_instance) { - ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); + ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_STOP); m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled.\r\n"); } ret_code_t nrf_drv_rtc_cc_disable(nrf_drv_rtc_t const * const p_instance, uint32_t channel) { ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); - ASSERT(channelcc_channel_count); + ret_code_t err_code; uint32_t int_mask = RTC_CHANNEL_INT_MASK(channel); nrf_rtc_event_t event = RTC_CHANNEL_EVENT_ADDR(channel); @@ -118,10 +170,15 @@ ret_code_t nrf_drv_rtc_cc_disable(nrf_drv_rtc_t const * const p_instance, uint32 if (nrf_rtc_event_pending(p_instance->p_reg,event)) { nrf_rtc_event_clear(p_instance->p_reg,event); - return NRF_ERROR_TIMEOUT; + err_code = NRF_ERROR_TIMEOUT; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } } - return NRF_SUCCESS; + NRF_LOG_INFO("RTC id: %d, channel disabled: %d.\r\n", p_instance->instance_id, channel); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } ret_code_t nrf_drv_rtc_cc_set(nrf_drv_rtc_t const * const p_instance, @@ -130,8 +187,9 @@ ret_code_t nrf_drv_rtc_cc_set(nrf_drv_rtc_t const * const p_instance, bool enable_irq) { ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); - ASSERT(channelcc_channel_count); + ret_code_t err_code; uint32_t int_mask = RTC_CHANNEL_INT_MASK(channel); nrf_rtc_event_t event = RTC_CHANNEL_EVENT_ADDR(channel); @@ -150,7 +208,9 @@ ret_code_t nrf_drv_rtc_cc_set(nrf_drv_rtc_t const * const p_instance, } if (diff < m_cb[p_instance->instance_id].tick_latency) { - return NRF_ERROR_TIMEOUT; + err_code = NRF_ERROR_TIMEOUT; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } } else @@ -165,7 +225,10 @@ ret_code_t nrf_drv_rtc_cc_set(nrf_drv_rtc_t const * const p_instance, } nrf_rtc_event_enable(p_instance->p_reg,int_mask); - return NRF_SUCCESS; + NRF_LOG_INFO("RTC id: %d, channel enabled: %d, compare value: %d.\r\n", p_instance->instance_id, channel, val); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } void nrf_drv_rtc_tick_enable(nrf_drv_rtc_t const * const p_instance, bool enable_irq) @@ -179,6 +242,7 @@ void nrf_drv_rtc_tick_enable(nrf_drv_rtc_t const * const p_instance, bool enable { nrf_rtc_int_enable(p_instance->p_reg, mask); } + NRF_LOG_INFO("Tick events enabled.\r\n"); } void nrf_drv_rtc_tick_disable(nrf_drv_rtc_t const * const p_instance) @@ -187,6 +251,7 @@ void nrf_drv_rtc_tick_disable(nrf_drv_rtc_t const * const p_instance) nrf_rtc_event_disable(p_instance->p_reg, mask); nrf_rtc_int_disable(p_instance->p_reg, mask); + NRF_LOG_INFO("Tick events disabled.\r\n"); } void nrf_drv_rtc_overflow_enable(nrf_drv_rtc_t const * const p_instance, bool enable_irq) @@ -210,7 +275,6 @@ void nrf_drv_rtc_overflow_disable(nrf_drv_rtc_t const * const p_instance) uint32_t nrf_drv_rtc_max_ticks_get(nrf_drv_rtc_t const * const p_instance) { - ASSERT(m_cb[p_instance->instance_id].reliable); uint32_t ticks; if (m_cb[p_instance->instance_id].reliable) { @@ -228,19 +292,23 @@ uint32_t nrf_drv_rtc_max_ticks_get(nrf_drv_rtc_t const * const p_instance) * @param[in] p_reg Pointer to instance register structure. * @param[in] instance_id Index of instance. */ -__STATIC_INLINE void nrf_drv_rtc_int_handler(NRF_RTC_Type * p_reg, uint32_t instance_id) +__STATIC_INLINE void nrf_drv_rtc_int_handler(NRF_RTC_Type * p_reg, + uint32_t instance_id, + uint32_t channel_count) { uint32_t i; uint32_t int_mask = (uint32_t)NRF_RTC_INT_COMPARE0_MASK; nrf_rtc_event_t event = NRF_RTC_EVENT_COMPARE_0; - for (i = 0; i < RTC_CHANNEL_NUM; i++) + for (i = 0; i < channel_count; i++) { if (nrf_rtc_int_is_enabled(p_reg,int_mask) && nrf_rtc_event_pending(p_reg,event)) { nrf_rtc_event_disable(p_reg,int_mask); nrf_rtc_int_disable(p_reg,int_mask); nrf_rtc_event_clear(p_reg,event); + NRF_LOG_DEBUG("Event: %s, instance id: %d.\r\n", + (uint32_t)EVT_TO_STR(event), (uint32_t)instance_id); m_handlers[instance_id]((nrf_drv_rtc_int_type_t)i); } int_mask <<= 1; @@ -251,6 +319,7 @@ __STATIC_INLINE void nrf_drv_rtc_int_handler(NRF_RTC_Type * p_reg, uint32_t inst nrf_rtc_event_pending(p_reg, event)) { nrf_rtc_event_clear(p_reg, event); + NRF_LOG_DEBUG("Event: %s, instance id: %d.\r\n", (uint32_t)EVT_TO_STR(event), instance_id); m_handlers[instance_id](NRF_DRV_RTC_INT_TICK); } @@ -259,20 +328,30 @@ __STATIC_INLINE void nrf_drv_rtc_int_handler(NRF_RTC_Type * p_reg, uint32_t inst nrf_rtc_event_pending(p_reg, event)) { nrf_rtc_event_clear(p_reg,event); + NRF_LOG_DEBUG("Event: %s, instance id: %d.\r\n", (uint32_t)EVT_TO_STR(event), instance_id); m_handlers[instance_id](NRF_DRV_RTC_INT_OVERFLOW); } } -#if (RTC0_ENABLED == 1) +#if NRF_MODULE_ENABLED(RTC0) void RTC0_IRQHandler(void) { - nrf_drv_rtc_int_handler(NRF_RTC0,RTC0_INSTANCE_INDEX); + nrf_drv_rtc_int_handler(NRF_RTC0,RTC0_INSTANCE_INDEX, NRF_RTC_CC_CHANNEL_COUNT(0)); } #endif -#if (RTC1_ENABLED == 1) +#if NRF_MODULE_ENABLED(RTC1) void RTC1_IRQHandler(void) { - nrf_drv_rtc_int_handler(NRF_RTC1,RTC1_INSTANCE_INDEX); + nrf_drv_rtc_int_handler(NRF_RTC1,RTC1_INSTANCE_INDEX, NRF_RTC_CC_CHANNEL_COUNT(1)); +} +#endif + +#if NRF_MODULE_ENABLED(RTC2) +void RTC2_IRQHandler(void) +{ + nrf_drv_rtc_int_handler(NRF_RTC2,RTC2_INSTANCE_INDEX, NRF_RTC_CC_CHANNEL_COUNT(2)); } #endif +#endif //ENABLED_RTC_COUNT +#endif //NRF_MODULE_ENABLED(RTC) diff --git a/components/drivers_nrf/rtc/nrf_drv_rtc.h b/components/drivers_nrf/rtc/nrf_drv_rtc.h index 6b5d003..a11ce75 100644 --- a/components/drivers_nrf/rtc/nrf_drv_rtc.h +++ b/components/drivers_nrf/rtc/nrf_drv_rtc.h @@ -1,25 +1,57 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_RTC_H #define NRF_DRV_RTC_H +#include "sdk_config.h" #include "nordic_common.h" -#include "nrf_drv_config.h" #include "nrf_drv_common.h" #include "nrf_rtc.h" #include "sdk_errors.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @addtogroup nrf_rtc RTC HAL and driver * @ingroup nrf_drivers @@ -34,7 +66,7 @@ */ /**@brief Macro to convert microseconds into ticks. */ -#define RTC_US_TO_TICKS(us,freq) ((us*freq)/1000000) +#define RTC_US_TO_TICKS(us,freq) ((us * freq) / 1000000) /** * @enum nrf_drv_rtc_int_type_t @@ -53,17 +85,23 @@ typedef enum /**@brief RTC driver instance structure. */ typedef struct { - NRF_RTC_Type * p_reg; /**< Pointer to instance register set. */ - IRQn_Type irq; /**< Instance IRQ ID. */ - uint8_t instance_id; /**< Instance index. */ + NRF_RTC_Type * p_reg; /**< Pointer to instance register set. */ + IRQn_Type irq; /**< Instance IRQ ID. */ + uint8_t instance_id; /**< Instance index. */ + uint8_t cc_channel_count; /**< Number of capture/compare channels. */ } nrf_drv_rtc_t; +#define RTC0_INSTANCE_INDEX 0 +#define RTC1_INSTANCE_INDEX RTC0_INSTANCE_INDEX+RTC0_ENABLED +#define RTC2_INSTANCE_INDEX RTC1_INSTANCE_INDEX+RTC1_ENABLED + /**@brief Macro for creating RTC driver instance.*/ -#define NRF_DRV_RTC_INSTANCE(id) \ -{ \ - .p_reg = CONCAT_2(NRF_RTC, id), \ - .irq = CONCAT_3(RTC, id, _IRQn), \ - .instance_id = CONCAT_3(RTC, id, _INSTANCE_INDEX) \ +#define NRF_DRV_RTC_INSTANCE(id) \ +{ \ + .p_reg = CONCAT_2(NRF_RTC, id), \ + .irq = CONCAT_3(RTC, id, _IRQn), \ + .instance_id = CONCAT_3(RTC, id, _INSTANCE_INDEX),\ + .cc_channel_count = NRF_RTC_CC_CHANNEL_COUNT(id), \ } /**@brief RTC driver instance configuration structure. */ @@ -76,12 +114,12 @@ typedef struct } nrf_drv_rtc_config_t; /**@brief RTC instance default configuration. */ -#define NRF_DRV_RTC_DEFAULT_CONFIG(id) \ -{ \ - .prescaler = (uint16_t)(RTC_INPUT_FREQ / CONCAT_3(RTC, id, _CONFIG_FREQUENCY))-1, \ - .interrupt_priority = CONCAT_3(RTC, id, _CONFIG_IRQ_PRIORITY), \ - .reliable = CONCAT_3(RTC, id, _CONFIG_RELIABLE), \ - .tick_latency = RTC_US_TO_TICKS(NRF_MAXIMUM_LATENCY_US, CONCAT_3(RTC, id, _CONFIG_FREQUENCY)), \ +#define NRF_DRV_RTC_DEFAULT_CONFIG \ +{ \ + .prescaler = RTC_FREQ_TO_PRESCALER(RTC_DEFAULT_CONFIG_FREQUENCY), \ + .interrupt_priority = RTC_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .reliable = RTC_DEFAULT_CONFIG_RELIABLE, \ + .tick_latency = RTC_US_TO_TICKS(NRF_MAXIMUM_LATENCY_US, RTC_DEFAULT_CONFIG_FREQUENCY), \ } /**@brief RTC driver instance handler type. */ @@ -91,7 +129,7 @@ typedef void (*nrf_drv_rtc_handler_t)(nrf_drv_rtc_int_type_t int_type); * * After initialization, the instance is in power off state. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] p_config Initial configuration. Default configuration used if NULL. * @param[in] handler User's event handler. * @@ -108,7 +146,7 @@ ret_code_t nrf_drv_rtc_init(nrf_drv_rtc_t const * const p_instance, * After uninitialization, the instance is in idle state. The hardware should return to the state * before initialization. The function asserts if the instance is in idle state. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_rtc_uninit(nrf_drv_rtc_t const * const p_instance); @@ -116,7 +154,7 @@ void nrf_drv_rtc_uninit(nrf_drv_rtc_t const * const p_instance); * * @note Function asserts if instance is enabled. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_rtc_enable(nrf_drv_rtc_t const * const p_instance); @@ -124,7 +162,7 @@ void nrf_drv_rtc_enable(nrf_drv_rtc_t const * const p_instance); * * @note Function asserts if instance is disabled. * - * @param[in] p_instance Pointer to instance. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_rtc_disable(nrf_drv_rtc_t const * const p_instance); @@ -138,12 +176,12 @@ void nrf_drv_rtc_disable(nrf_drv_rtc_t const * const p_instance); * is short in time, there is a risk that the driver sets a compare value that is * behind. If RTCn_CONFIG_RELIABLE is 1 for the given instance, the Reliable mode handles that case. * However, to detect if the requested value is behind, this mode makes the following assumptions: - * - The maximum preemption time in ticks (8-bit value) is known and is less than 7.7 ms + * - The maximum preemption time in ticks (8 - bit value) is known and is less than 7.7 ms * (for prescaler = 0, RTC frequency 32 kHz). - * - The requested absolute compare value is not bigger than (0x00FFFFFF)-tick_latency. It is + * - The requested absolute compare value is not bigger than (0x00FFFFFF) - tick_latency. It is * the user's responsibility to ensure that. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] channel One of the instance's channels. * @param[in] val Absolute value to be set in the compare register. * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt. @@ -162,7 +200,7 @@ ret_code_t nrf_drv_rtc_cc_set(nrf_drv_rtc_t const * const p_instance, * This function disables channel events and channel interrupts. The function asserts if the instance is not * initialized or if the channel parameter is wrong. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] channel One of the instance's channels. * * @retval NRF_SUCCESS If the procedure was successful. @@ -175,7 +213,7 @@ ret_code_t nrf_drv_rtc_cc_disable(nrf_drv_rtc_t const * const p_instance, uint32 * This function enables the tick event and optionally the interrupt. The function asserts if the instance is not * powered on. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt. */ void nrf_drv_rtc_tick_enable(nrf_drv_rtc_t const * const p_instance, bool enable_irq); @@ -184,7 +222,7 @@ void nrf_drv_rtc_tick_enable(nrf_drv_rtc_t const * const p_instance, bool enable * * This function disables the tick event and interrupt. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_rtc_tick_disable(nrf_drv_rtc_t const * const p_instance); @@ -193,7 +231,7 @@ void nrf_drv_rtc_tick_disable(nrf_drv_rtc_t const * const p_instance); * This function enables the overflow event and optionally the interrupt. The function asserts if the instance is * not powered on. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] enable_irq True to enable the interrupt. False to disable the interrupt. */ void nrf_drv_rtc_overflow_enable(nrf_drv_rtc_t const * const p_instance, bool enable_irq); @@ -202,7 +240,7 @@ void nrf_drv_rtc_overflow_enable(nrf_drv_rtc_t const * const p_instance, bool en * * This function disables the overflow event and interrupt. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_rtc_overflow_disable(nrf_drv_rtc_t const * const p_instance); @@ -213,7 +251,7 @@ void nrf_drv_rtc_overflow_disable(nrf_drv_rtc_t const * const p_instance); * maximum latency is taken into account and the return value is smaller than the RTC counter * resolution. If Reliable mode is disabled, the return value equals the counter resolution. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. * * @retval ticks Maximum ticks value. */ @@ -221,7 +259,7 @@ uint32_t nrf_drv_rtc_max_ticks_get(nrf_drv_rtc_t const * const p_instance); /**@brief Function for disabling all instance interrupts. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] p_mask Pointer to the location where the mask is filled. */ __STATIC_INLINE void nrf_drv_rtc_int_disable(nrf_drv_rtc_t const * const p_instance, @@ -229,7 +267,7 @@ __STATIC_INLINE void nrf_drv_rtc_int_disable(nrf_drv_rtc_t const * const p_insta /**@brief Function for enabling instance interrupts. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] mask Mask of interrupts to enable. */ __STATIC_INLINE void nrf_drv_rtc_int_enable(nrf_drv_rtc_t const * const p_instance, uint32_t mask); @@ -238,7 +276,7 @@ __STATIC_INLINE void nrf_drv_rtc_int_enable(nrf_drv_rtc_t const * const p_instan * * This function asserts if the instance is not powered on or if p_val is NULL. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. * * @retval value Counter value. */ @@ -248,7 +286,7 @@ __STATIC_INLINE uint32_t nrf_drv_rtc_counter_get(nrf_drv_rtc_t const * const p_i * * This function asserts if the instance is not powered on. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. */ __STATIC_INLINE void nrf_drv_rtc_counter_clear(nrf_drv_rtc_t const * const p_instance); @@ -268,7 +306,7 @@ __STATIC_INLINE uint32_t nrf_drv_rtc_task_address_get(nrf_drv_rtc_t const * cons * * This function asserts if the output pointer is NULL. The event address can be used by the PPI module. * - * @param[in] p_instance Pointer to the instance. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] event One of the peripheral events. * * @retval Address of event register. @@ -320,4 +358,9 @@ __STATIC_INLINE uint32_t nrf_drv_rtc_event_address_get(nrf_drv_rtc_t const * con /** *@} **/ + +#ifdef __cplusplus +} +#endif + #endif /* NRF_DRV_RTC_H */ diff --git a/components/drivers_nrf/saadc/nrf_drv_saadc.c b/components/drivers_nrf/saadc/nrf_drv_saadc.c new file mode 100644 index 0000000..d07eb7f --- /dev/null +++ b/components/drivers_nrf/saadc/nrf_drv_saadc.c @@ -0,0 +1,628 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SAADC) +#include "nrf_drv_saadc.h" +#include "nrf_assert.h" +#include "nrf_drv_common.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "SAADC" + +#if SAADC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL SAADC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR SAADC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR SAADC_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_SAADC_EVENT_STARTED ? "NRF_SAADC_EVENT_STARTED" : \ + (event == NRF_SAADC_EVENT_END ? "NRF_SAADC_EVENT_END" : \ + (event == NRF_SAADC_EVENT_DONE ? "NRF_SAADC_EVENT_DONE" : \ + (event == NRF_SAADC_EVENT_RESULTDONE ? "NRF_SAADC_EVENT_RESULTDONE" : \ + (event == NRF_SAADC_EVENT_CALIBRATEDONE ? "NRF_SAADC_EVENT_CALIBRATEDONE" : \ + (event == NRF_SAADC_EVENT_STOPPED ? "NRF_SAADC_EVENT_STOPPED" : "UNKNOWN EVENT")))))) +#define EVT_TO_STR_LIMIT(event) (event == NRF_SAADC_LIMIT_LOW ? "NRF_SAADC_LIMIT_LOW" : \ + (event == NRF_SAADC_LIMIT_HIGH ? "NRF_SAADC_LIMIT_HIGH" : "UNKNOWN EVENT")) +#else //SAADC_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //SAADC_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +typedef enum +{ + NRF_SAADC_STATE_IDLE = 0, + NRF_SAADC_STATE_BUSY = 1, + NRF_SAADC_STATE_CALIBRATION = 2 +} nrf_saadc_state_t; + + +typedef struct +{ + nrf_saadc_input_t pselp; + nrf_saadc_input_t pseln; +} nrf_saadc_psel_buffer; + +static const nrf_drv_saadc_config_t m_default_config = NRF_DRV_SAADC_DEFAULT_CONFIG; + +/** @brief SAADC control block.*/ +typedef struct +{ + nrf_drv_saadc_event_handler_t event_handler; ///< Event handler function pointer. + volatile nrf_saadc_value_t * p_buffer; ///< Sample buffer. + volatile uint16_t buffer_size; ///< Size of the sample buffer. + volatile nrf_saadc_value_t * p_secondary_buffer; ///< Secondary sample buffer. + volatile nrf_saadc_state_t adc_state; ///< State of the SAADC. + uint32_t limits_enabled_flags; ///< Enabled limits flags. + uint16_t secondary_buffer_size; ///< Size of the secondary buffer. + uint16_t buffer_size_left; ///< When low power mode is active indicates how many samples left to convert on current buffer. + nrf_saadc_psel_buffer psel[NRF_SAADC_CHANNEL_COUNT]; ///< Pin configurations of SAADC channels. + nrf_drv_state_t state; ///< Driver initialization state. + uint8_t active_channels; ///< Number of enabled SAADC channels. + bool low_power_mode; ///< Indicates if low power mode is active. + bool conversions_end; ///< When low power mode is active indicates end of conversions on current buffer. +} nrf_drv_saadc_cb_t; + +static nrf_drv_saadc_cb_t m_cb; + +#define LOW_LIMIT_TO_FLAG(channel) ((2 * channel + 1)) +#define HIGH_LIMIT_TO_FLAG(channel) ((2 * channel)) +#define FLAG_IDX_TO_EVENT(idx) ((nrf_saadc_event_t)((uint32_t)NRF_SAADC_EVENT_CH0_LIMITH + \ + 4 * idx)) +#define LIMIT_EVENT_TO_CHANNEL(event) (uint8_t)(((uint32_t)event - \ + (uint32_t)NRF_SAADC_EVENT_CH0_LIMITH) / 8) +#define LIMIT_EVENT_TO_LIMIT_TYPE(event)((((uint32_t)event - (uint32_t)NRF_SAADC_EVENT_CH0_LIMITH) & 4) \ + ? NRF_SAADC_LIMIT_LOW : NRF_SAADC_LIMIT_HIGH) +#define HW_TIMEOUT 10000 + +void SAADC_IRQHandler(void) +{ + if (nrf_saadc_event_check(NRF_SAADC_EVENT_END)) + { + nrf_saadc_event_clear(NRF_SAADC_EVENT_END); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_END)); + + if (!m_cb.low_power_mode || m_cb.conversions_end) + { + nrf_drv_saadc_evt_t evt; + evt.type = NRF_DRV_SAADC_EVT_DONE; + evt.data.done.p_buffer = (nrf_saadc_value_t *)m_cb.p_buffer; + evt.data.done.size = m_cb.buffer_size; + + if (m_cb.p_secondary_buffer == NULL) + { + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + } + else + { + m_cb.buffer_size_left = m_cb.secondary_buffer_size; + m_cb.p_buffer = m_cb.p_secondary_buffer; + m_cb.buffer_size = m_cb.secondary_buffer_size; + m_cb.p_secondary_buffer = NULL; + if (!m_cb.low_power_mode) + { + nrf_saadc_task_trigger(NRF_SAADC_TASK_START); + } + } + m_cb.event_handler(&evt); + m_cb.conversions_end = false; + } + } + if (m_cb.low_power_mode && nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED)) + { + nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_STARTED)); + + if (m_cb.buffer_size_left > m_cb.active_channels) + { + // More samples to convert than for single event. + m_cb.buffer_size_left -= m_cb.active_channels; + nrf_saadc_buffer_init((nrf_saadc_value_t *)&m_cb.p_buffer[m_cb.buffer_size - + m_cb.buffer_size_left], + m_cb.active_channels); + } + else if ((m_cb.buffer_size_left == m_cb.active_channels) && + + (m_cb.p_secondary_buffer != NULL)) + { + // Samples to convert for one event, prepare next buffer. + m_cb.conversions_end = true; + m_cb.buffer_size_left = 0; + nrf_saadc_buffer_init((nrf_saadc_value_t *)m_cb.p_secondary_buffer, + m_cb.active_channels); + } + else if (m_cb.buffer_size_left == m_cb.active_channels) + { + // Samples to convert for one event, but no second buffer. + m_cb.conversions_end = true; + m_cb.buffer_size_left = 0; + } + nrf_saadc_event_clear(NRF_SAADC_EVENT_END); + nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); + } + if (nrf_saadc_event_check(NRF_SAADC_EVENT_CALIBRATEDONE)) + { + nrf_saadc_event_clear(NRF_SAADC_EVENT_CALIBRATEDONE); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_CALIBRATEDONE)); + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + + nrf_drv_saadc_evt_t evt; + evt.type = NRF_DRV_SAADC_EVT_CALIBRATEDONE; + m_cb.event_handler(&evt); + } + if (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED)) + { + nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SAADC_EVENT_STOPPED)); + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + } + else + { + uint32_t limit_flags = m_cb.limits_enabled_flags; + uint32_t flag_idx; + nrf_saadc_event_t event; + + while (limit_flags) + { + flag_idx = __CLZ(limit_flags); + limit_flags &= ~((1UL << 31) >> flag_idx); + event = FLAG_IDX_TO_EVENT(flag_idx); + if (nrf_saadc_event_check(event)) + { + nrf_saadc_event_clear(event); + nrf_drv_saadc_evt_t evt; + evt.type = NRF_DRV_SAADC_EVT_LIMIT; + evt.data.limit.channel = LIMIT_EVENT_TO_CHANNEL(event); + evt.data.limit.limit_type = LIMIT_EVENT_TO_LIMIT_TYPE(event); + NRF_LOG_DEBUG("Event limit, channel: %d, limit type: %s.\r\n", evt.data.limit.channel, (uint32_t)EVT_TO_STR(evt.data.limit.limit_type)); + m_cb.event_handler(&evt); + } + } + } +} + + +ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config, + nrf_drv_saadc_event_handler_t event_handler) +{ + ret_code_t err_code; + + if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + if (event_handler == NULL) + { + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + if (p_config == NULL) + { + p_config = &m_default_config; + } + + m_cb.event_handler = event_handler; + nrf_saadc_resolution_set(p_config->resolution); + nrf_saadc_oversample_set(p_config->oversample); + m_cb.low_power_mode = p_config->low_power_mode; + m_cb.state = NRF_DRV_STATE_INITIALIZED; + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + m_cb.active_channels = 0; + m_cb.limits_enabled_flags = 0; + m_cb.conversions_end = false; + + nrf_saadc_int_disable(NRF_SAADC_INT_ALL); + nrf_saadc_event_clear(NRF_SAADC_EVENT_END); + nrf_drv_common_irq_enable(SAADC_IRQn, p_config->interrupt_priority); + nrf_saadc_int_enable(NRF_SAADC_INT_END); + if (m_cb.low_power_mode) + { + nrf_saadc_int_enable(NRF_SAADC_INT_STARTED); + } + + nrf_saadc_enable(); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +void nrf_drv_saadc_uninit(void) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_saadc_int_disable(NRF_SAADC_INT_ALL); + nrf_drv_common_irq_disable(SAADC_IRQn); + nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP); + + // Wait for ADC being stopped. + uint32_t timeout = HW_TIMEOUT; + + while (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED) == 0 && timeout > 0) + { + --timeout; + } + ASSERT(timeout > 0); + + nrf_saadc_disable(); + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + + for (uint8_t channel = 0; channel < NRF_SAADC_CHANNEL_COUNT; ++channel) + { + if (m_cb.psel[channel].pselp != NRF_SAADC_INPUT_DISABLED) + { + (void)nrf_drv_saadc_channel_uninit(channel); + } + } + + m_cb.state = NRF_DRV_STATE_UNINITIALIZED; +} + + +ret_code_t nrf_drv_saadc_channel_init(uint8_t channel, + nrf_saadc_channel_config_t const * const p_config) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(channel < NRF_SAADC_CHANNEL_COUNT); + // Oversampling can be used only with one channel. + ASSERT((nrf_saadc_oversample_get() == NRF_SAADC_OVERSAMPLE_DISABLED) || + (m_cb.active_channels == 0)); + ASSERT((p_config->pin_p <= NRF_SAADC_INPUT_VDD) && + (p_config->pin_p > NRF_SAADC_INPUT_DISABLED)); + ASSERT(p_config->pin_n <= NRF_SAADC_INPUT_VDD); + + ret_code_t err_code; + + // A channel can only be initialized if the driver is in the idle state. + if (m_cb.adc_state != NRF_SAADC_STATE_IDLE) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + if (!m_cb.psel[channel].pselp) + { + ++m_cb.active_channels; + } + m_cb.psel[channel].pselp = p_config->pin_p; + m_cb.psel[channel].pseln = p_config->pin_n; + nrf_saadc_channel_init(channel, p_config); + nrf_saadc_channel_input_set(channel, p_config->pin_p, p_config->pin_n); + NRF_LOG_INFO("Channel initialized: %d.\r\n", channel); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +ret_code_t nrf_drv_saadc_channel_uninit(uint8_t channel) +{ + ASSERT(channel < NRF_SAADC_CHANNEL_COUNT) + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + + // A channel can only be uninitialized if the driver is in the idle state. + if (m_cb.adc_state != NRF_SAADC_STATE_IDLE) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + if (m_cb.psel[channel].pselp) + { + --m_cb.active_channels; + } + m_cb.psel[channel].pselp = NRF_SAADC_INPUT_DISABLED; + m_cb.psel[channel].pseln = NRF_SAADC_INPUT_DISABLED; + nrf_saadc_channel_input_set(channel, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED); + nrf_drv_saadc_limits_set(channel, NRF_DRV_SAADC_LIMITL_DISABLED, NRF_DRV_SAADC_LIMITH_DISABLED); + NRF_LOG_INFO("Channel denitialized: %d.\r\n", channel); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", + (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +uint32_t nrf_drv_saadc_sample_task_get(void) +{ + return nrf_saadc_task_address_get( + m_cb.low_power_mode ? NRF_SAADC_TASK_START : NRF_SAADC_TASK_SAMPLE); +} + + +ret_code_t nrf_drv_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value) +{ + ret_code_t err_code; + + if (m_cb.adc_state != NRF_SAADC_STATE_IDLE) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + m_cb.adc_state = NRF_SAADC_STATE_BUSY; + nrf_saadc_int_disable(NRF_SAADC_INT_STARTED | NRF_SAADC_INT_END); + nrf_saadc_buffer_init(p_value, 1); + if (m_cb.active_channels > 1) + { + for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i) + { + nrf_saadc_channel_input_set(i, NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED); + } + } + nrf_saadc_channel_input_set(channel, + m_cb.psel[channel].pselp, m_cb.psel[channel].pseln); + nrf_saadc_task_trigger(NRF_SAADC_TASK_START); + nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); + + uint32_t timeout = HW_TIMEOUT; + + while (0 == nrf_saadc_event_check(NRF_SAADC_EVENT_END) && timeout > 0) + { + timeout--; + } + nrf_saadc_event_clear(NRF_SAADC_EVENT_END); + + NRF_LOG_INFO("Conversion value: %d, channel.\r\n", *p_value, channel); + + if (m_cb.active_channels > 1) + { + for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i) + { + nrf_saadc_channel_input_set(i, m_cb.psel[i].pselp, m_cb.psel[i].pseln); + } + } + + if (m_cb.low_power_mode) + { + nrf_saadc_int_enable(NRF_SAADC_INT_STARTED | NRF_SAADC_INT_END); + } + else + { + nrf_saadc_int_enable(NRF_SAADC_INT_END); + } + + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + + err_code = NRF_SUCCESS; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +ret_code_t nrf_drv_saadc_buffer_convert(nrf_saadc_value_t * p_buffer, uint16_t size) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT((size % m_cb.active_channels) == 0); + ret_code_t err_code; + + + nrf_saadc_int_disable(NRF_SAADC_INT_END | NRF_SAADC_INT_CALIBRATEDONE); + if (m_cb.adc_state == NRF_SAADC_STATE_CALIBRATION) + { + nrf_saadc_int_enable(NRF_SAADC_INT_END | NRF_SAADC_INT_CALIBRATEDONE); + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + if (m_cb.adc_state == NRF_SAADC_STATE_BUSY) + { + if ( m_cb.p_secondary_buffer) + { + nrf_saadc_int_enable(NRF_SAADC_INT_END); + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + else + { + m_cb.p_secondary_buffer = p_buffer; + m_cb.secondary_buffer_size = size; + if (!m_cb.low_power_mode) + { + while (nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) == 0); + nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); + nrf_saadc_buffer_init(p_buffer, size); + } + nrf_saadc_int_enable(NRF_SAADC_INT_END); + err_code = NRF_SUCCESS; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + } + nrf_saadc_int_enable(NRF_SAADC_INT_END); + m_cb.adc_state = NRF_SAADC_STATE_BUSY; + + m_cb.p_buffer = p_buffer; + m_cb.buffer_size = size; + m_cb.p_secondary_buffer = NULL; + + NRF_LOG_INFO("Function: %d, buffer length: %d, active channels: %d.\r\n", + (uint32_t)__func__, size, m_cb.active_channels); + + if (m_cb.low_power_mode) + { + m_cb.buffer_size_left = size; + nrf_saadc_buffer_init(p_buffer, m_cb.active_channels); + } + else + { + nrf_saadc_buffer_init(p_buffer, size); + nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED); + nrf_saadc_task_trigger(NRF_SAADC_TASK_START); + } + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +ret_code_t nrf_drv_saadc_sample() +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code = NRF_SUCCESS; + if (m_cb.adc_state != NRF_SAADC_STATE_BUSY) + { + err_code = NRF_ERROR_INVALID_STATE; + } + else if (m_cb.low_power_mode) + { + nrf_saadc_task_trigger(NRF_SAADC_TASK_START); + } + else + { + nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); + } + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +ret_code_t nrf_drv_saadc_calibrate_offset() +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + + if (m_cb.adc_state != NRF_SAADC_STATE_IDLE) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + m_cb.adc_state = NRF_SAADC_STATE_CALIBRATION; + + nrf_saadc_event_clear(NRF_SAADC_EVENT_CALIBRATEDONE); + nrf_saadc_int_enable(NRF_SAADC_INT_CALIBRATEDONE); + nrf_saadc_task_trigger(NRF_SAADC_TASK_CALIBRATEOFFSET); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +bool nrf_drv_saadc_is_busy(void) +{ + return (m_cb.adc_state != NRF_SAADC_STATE_IDLE); +} + + +void nrf_drv_saadc_abort(void) +{ + if (nrf_drv_saadc_is_busy()) + { + nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED); + nrf_saadc_task_trigger(NRF_SAADC_TASK_STOP); + + if (m_cb.adc_state == NRF_SAADC_STATE_CALIBRATION) + { + m_cb.adc_state = NRF_SAADC_STATE_IDLE; + } + else + { + // Wait for ADC being stopped. + uint32_t timeout = HW_TIMEOUT; + + while ((m_cb.adc_state != NRF_SAADC_STATE_IDLE) && (timeout > 0)) + { + --timeout; + } + ASSERT(timeout > 0); + } + + m_cb.p_buffer = 0; + m_cb.p_secondary_buffer = 0; + NRF_LOG_INFO("Conversion aborted.\r\n"); + } +} + + +void nrf_drv_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high) +{ + ASSERT(m_cb.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(m_cb.event_handler); // only non blocking mode supported + ASSERT(limit_low >= NRF_DRV_SAADC_LIMITL_DISABLED); + ASSERT(limit_high <= NRF_DRV_SAADC_LIMITH_DISABLED); + ASSERT(limit_low < limit_high); + nrf_saadc_channel_limits_set(channel, limit_low, limit_high); + + uint32_t int_mask = nrf_saadc_limit_int_get(channel, NRF_SAADC_LIMIT_LOW); + if (limit_low == NRF_DRV_SAADC_LIMITL_DISABLED) + { + m_cb.limits_enabled_flags &= ~(0x80000000 >> LOW_LIMIT_TO_FLAG(channel)); + nrf_saadc_int_disable(int_mask); + } + else + { + m_cb.limits_enabled_flags |= (0x80000000 >> LOW_LIMIT_TO_FLAG(channel)); + nrf_saadc_int_enable(int_mask); + } + + int_mask = nrf_saadc_limit_int_get(channel, NRF_SAADC_LIMIT_HIGH); + if (limit_high == NRF_DRV_SAADC_LIMITH_DISABLED) + { + m_cb.limits_enabled_flags &= ~(0x80000000 >> HIGH_LIMIT_TO_FLAG(channel)); + nrf_saadc_int_disable(int_mask); + } + else + { + m_cb.limits_enabled_flags |= (0x80000000 >> HIGH_LIMIT_TO_FLAG(channel)); + nrf_saadc_int_enable(int_mask); + } +} +#endif //NRF_MODULE_ENABLED(SAADC) diff --git a/components/drivers_nrf/saadc/nrf_drv_saadc.h b/components/drivers_nrf/saadc/nrf_drv_saadc.h new file mode 100644 index 0000000..e0cbda8 --- /dev/null +++ b/components/drivers_nrf/saadc/nrf_drv_saadc.h @@ -0,0 +1,327 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @addtogroup nrf_saadc SAADC HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52 Successive Approximation Analog-to-Digital Converter (SAADC) APIs. + * @details The SAADC HAL provides basic APIs for accessing the registers of the SAADC peripheral. + * The SAADC driver provides APIs on a higher level. + * + * @defgroup nrf_drv_saadc SAADC driver + * @{ + * @ingroup nrf_saadc + * + * @brief @tagAPI52 Successive Approximation Analog-to-Digital Converter (SAADC) driver. + */ + +#ifndef NRF_DRV_SAADC_H__ +#define NRF_DRV_SAADC_H__ + +#include "sdk_config.h" +#include "nrf_saadc.h" +#include "sdk_errors.h" +#include "nrf_drv_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Value that should be set as high limit to disable limit detection. + */ +#define NRF_DRV_SAADC_LIMITH_DISABLED (2047) +/** + * @brief Value that should be set as low limit to disable limit detection. + */ +#define NRF_DRV_SAADC_LIMITL_DISABLED (-2048) + +/** + * @brief Macro for setting @ref nrf_drv_saadc_config_t to default settings. + */ +#define NRF_DRV_SAADC_DEFAULT_CONFIG \ + { \ + .resolution = (nrf_saadc_resolution_t)SAADC_CONFIG_RESOLUTION, \ + .oversample = (nrf_saadc_oversample_t)SAADC_CONFIG_OVERSAMPLE, \ + .interrupt_priority = SAADC_CONFIG_IRQ_PRIORITY, \ + .low_power_mode = SAADC_CONFIG_LP_MODE \ + } + +/** + * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings + * in single ended mode. + * + * @param PIN_P Analog input. + */ +#define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(PIN_P) \ + { \ + .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ + .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ + .gain = NRF_SAADC_GAIN1_6, \ + .reference = NRF_SAADC_REFERENCE_INTERNAL, \ + .acq_time = NRF_SAADC_ACQTIME_10US, \ + .mode = NRF_SAADC_MODE_SINGLE_ENDED, \ + .burst = NRF_SAADC_BURST_DISABLED, \ + .pin_p = (nrf_saadc_input_t)(PIN_P), \ + .pin_n = NRF_SAADC_INPUT_DISABLED \ + } + +/** + * @brief Macro for setting @ref nrf_saadc_channel_config_t to default settings + * in differential mode. + * + * @param PIN_P Positive analog input. + * @param PIN_N Negative analog input. + */ +#define NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_DIFFERENTIAL(PIN_P, PIN_N) \ + { \ + .resistor_p = NRF_SAADC_RESISTOR_DISABLED, \ + .resistor_n = NRF_SAADC_RESISTOR_DISABLED, \ + .gain = NRF_SAADC_GAIN1_6, \ + .reference = NRF_SAADC_REFERENCE_INTERNAL, \ + .acq_time = NRF_SAADC_ACQTIME_10US, \ + .mode = NRF_SAADC_MODE_DIFFERENTIAL, \ + .pin_p = (nrf_saadc_input_t)(PIN_P), \ + .pin_n = (nrf_saadc_input_t)(PIN_N) \ + } + +/** + * @brief Analog-to-digital converter driver configuration structure. + */ +typedef struct +{ + nrf_saadc_resolution_t resolution; ///< Resolution configuration. + nrf_saadc_oversample_t oversample; ///< Oversampling configuration. + uint8_t interrupt_priority; ///< Interrupt priority. + bool low_power_mode; ///< Indicates if low power mode is active. +} nrf_drv_saadc_config_t; + +/** + * @brief Driver event types. + */ +typedef enum +{ + NRF_DRV_SAADC_EVT_DONE, ///< Event generated when the buffer is filled with samples. + NRF_DRV_SAADC_EVT_LIMIT, ///< Event generated after one of the limits is reached. + NRF_DRV_SAADC_EVT_CALIBRATEDONE ///< Event generated when the calibration is complete. +} nrf_drv_saadc_evt_type_t; + +/** + * @brief Analog-to-digital converter driver done event data. + */ +typedef struct +{ + nrf_saadc_value_t * p_buffer; ///< Pointer to buffer with converted samples. + uint16_t size; ///< Number of samples in the buffer. +} nrf_drv_saadc_done_evt_t; + +/** + * @brief Analog-to-digital converter driver limit event data. + */ +typedef struct +{ + uint8_t channel; ///< Channel on which the limit was detected. + nrf_saadc_limit_t limit_type; ///< Type of limit detected. +} nrf_drv_saadc_limit_evt_t; + +/** + * @brief Analog-to-digital converter driver event structure. + */ +typedef struct +{ + nrf_drv_saadc_evt_type_t type; ///< Event type. + union + { + nrf_drv_saadc_done_evt_t done; ///< Data for @ref NRF_DRV_SAADC_EVT_DONE event. + nrf_drv_saadc_limit_evt_t limit; ///< Data for @ref NRF_DRV_SAADC_EVT_LIMIT event. + } data; +} nrf_drv_saadc_evt_t; + +/** + * @brief ADC event handler. + * + * @param[in] p_event Pointer to an ADC event. The event structure is allocated on + * the stack, so it is valid only within the context of + * the event handler. + */ +typedef void (* nrf_drv_saadc_event_handler_t)(nrf_drv_saadc_evt_t const * p_event); + +/** + * @brief Function for initializing the SAADC. + * + * @param[in] p_config Pointer to a configuration structure. If NULL, the default one is used. + * @param[in] event_handler Event handler provided by the user. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is already initialized. + * @retval NRF_ERROR_INVALID_PARAM If event_handler is NULL. + */ +ret_code_t nrf_drv_saadc_init(nrf_drv_saadc_config_t const * p_config, + nrf_drv_saadc_event_handler_t event_handler); + +/** + * @brief Function for uninitializing the SAADC. + * + * This function stops all ongoing conversions and disables all channels. + */ +void nrf_drv_saadc_uninit(void); + + +/** + * @brief Function for getting the address of a SAMPLE SAADC task. + * + * @return Task address. + */ +uint32_t nrf_drv_saadc_sample_task_get(void); + +/** + * @brief Function for initializing an SAADC channel. + * + * This function configures and enables the channel. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the ADC was not initialized. + * @retval NRF_ERROR_NO_MEM If the specified channel was already allocated. + */ +ret_code_t nrf_drv_saadc_channel_init(uint8_t channel, + nrf_saadc_channel_config_t const * const p_config); + + +/** + * @brief Function for uninitializing an SAADC channel. + * + * @retval NRF_SUCCESS If uninitialization was successful. + * @retval NRF_ERROR_BUSY If the ADC is busy. + */ +ret_code_t nrf_drv_saadc_channel_uninit(uint8_t channel); + +/** + * @brief Function for starting SAADC sampling. + * + * @retval NRF_SUCCESS If ADC sampling was triggered. + * @retval NRF_ERROR_INVALID_STATE If ADC is in idle state. + */ +ret_code_t nrf_drv_saadc_sample(void); + +/** + * @brief Blocking function for executing a single ADC conversion. + * + * This function selects the desired input, starts a single conversion, + * waits for it to finish, and returns the result. + * + * The function will fail if ADC is busy. + * + * @param[in] channel Channel. + * @param[out] p_value Pointer to the location where the result should be placed. + * + * @retval NRF_SUCCESS If conversion was successful. + * @retval NRF_ERROR_BUSY If the ADC driver is busy. + */ +ret_code_t nrf_drv_saadc_sample_convert(uint8_t channel, nrf_saadc_value_t * p_value); + +/** + * @brief Function for issuing conversion of data to the buffer. + * + * This function is non-blocking. The application is notified about filling the buffer by the event handler. + * Conversion will be done on all enabled channels. If the ADC is in idle state, the function will set up Easy + * DMA for the conversion. The ADC will be ready for sampling and wait for the SAMPLE task. It can be + * triggered manually by the @ref nrf_drv_saadc_sample function or by PPI using the @ref NRF_SAADC_TASK_SAMPLE + * task. If one buffer is already set and the conversion is ongoing, calling this function will + * result in queuing the given buffer. The driver will start filling the issued buffer when the first one is + * completed. If the function is called again before the first buffer is filled or calibration is in progress, + * it will return with error. + * + * @param[in] buffer Result buffer. + * @param[in] size Buffer size in words. + * + * @retval NRF_SUCCESS If conversion was successful. + * @retval NRF_ERROR_BUSY If the driver already has two buffers set or calibration is in progress. + */ +ret_code_t nrf_drv_saadc_buffer_convert(nrf_saadc_value_t * buffer, uint16_t size); + +/** + * @brief Function for triggering the ADC offset calibration. + * + * This function is non-blocking. The application is notified about completion by the event handler. + * Calibration will also trigger DONE and RESULTDONE events. + * + * The function will fail if ADC is busy or calibration is already in progress. + * + * @retval NRF_SUCCESS If calibration was started successfully. + * @retval NRF_ERROR_BUSY If the ADC driver is busy. + */ +ret_code_t nrf_drv_saadc_calibrate_offset(void); + +/** + * @brief Function for retrieving the SAADC state. + * + * @retval true If the ADC is busy. + * @retval false If the ADC is ready. + */ +bool nrf_drv_saadc_is_busy(void); + +/** + * @brief Function for aborting ongoing and buffered conversions. + * @note @ref NRF_DRV_SAADC_EVT_DONE event will be generated if there is a conversion in progress. + * Event will contain number of words in the sample buffer. + */ +void nrf_drv_saadc_abort(void); + +/** + * @brief Function for setting the SAADC channel limits. + * When limits are enabled and the result exceeds the defined bounds, the limit handler function is called. + * + * @param[in] channel SAADC channel number. + * @param[in] limit_low Lower limit (valid values from @ref NRF_DRV_SAADC_LIMITL_DISABLED to + * @ref NRF_DRV_SAADC_LIMITH_DISABLED). Conversion results below this value will trigger + * the handler function. Set to @ref NRF_DRV_SAADC_LIMITL_DISABLED to disable this limit. + * @param[in] limit_high Upper limit (valid values from @ref NRF_DRV_SAADC_LIMITL_DISABLED to + * @ref NRF_DRV_SAADC_LIMITH_DISABLED). Conversion results above this value will trigger + * the handler function. Set to @ref NRF_DRV_SAADC_LIMITH_DISABLED to disable this limit. + */ +void nrf_drv_saadc_limits_set(uint8_t channel, int16_t limit_low, int16_t limit_high); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DRV_SAADC_H__ + +/** @} */ diff --git a/components/drivers_nrf/sdio/config/sdio_config.h b/components/drivers_nrf/sdio/config/sdio_config.h index c3f1efb..f59e553 100644 --- a/components/drivers_nrf/sdio/config/sdio_config.h +++ b/components/drivers_nrf/sdio/config/sdio_config.h @@ -1,18 +1,55 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SDIO_CONFIG_H #define SDIO_CONFIG_H +#ifdef __cplusplus +extern "C" { +#endif + #define SDIO_CONFIG_CLOCK_PIN_NUMBER 24 #define SDIO_CONFIG_DATA_PIN_NUMBER 25 + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_nrf/sdio/sdio.c b/components/drivers_nrf/sdio/sdio.c index cb88160..f10bed0 100644 --- a/components/drivers_nrf/sdio/sdio.c +++ b/components/drivers_nrf/sdio/sdio.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include diff --git a/components/drivers_nrf/sdio/sdio.h b/components/drivers_nrf/sdio/sdio.h index 5e6a9a7..4d729df 100644 --- a/components/drivers_nrf/sdio/sdio.h +++ b/components/drivers_nrf/sdio/sdio.h @@ -1,13 +1,41 @@ - /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SDIO_H @@ -18,6 +46,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** @file * @brief 2-wire serial interface driver (compatible with ADNS2080 mouse sensor driver) * @@ -30,13 +62,13 @@ /** * @brief Function for initializing 2-wire serial interface and trying to handle stuck slaves. - * + * */ void sdio_init(void); /** * @brief Function for reading a byte over 2-wire serial interface. - * + * * Developer needs to implement this function in a way that suits the hardware. * @param address Register address to read from * @return Byte read @@ -45,7 +77,7 @@ uint8_t sdio_read_byte(uint8_t address); /** * @brief Function for reading several bytes over 2-wire serial interface using burst mode. - * + * * Developer needs to implement this function in a way that suits the hardware. * @param target_buffer Buffer location to store read bytes to * @param target_buffer_size Bytes allocated for target_buffer @@ -54,7 +86,7 @@ void sdio_read_burst(uint8_t *target_buffer, uint8_t target_buffer_size); /** * @brief Function for writing a byte over 2-wire serial interface. - * + * * Developer needs to implement this function in a way that suits the hardware. * @param address Register address to write to * @param data_byte Data byte to write @@ -65,5 +97,10 @@ void sdio_write_byte(uint8_t address, uint8_t data_byte); *@} **/ -/*lint --flb "Leave library region" */ +/*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_nrf/spi_master/nrf_drv_spi.c b/components/drivers_nrf/spi_master/nrf_drv_spi.c index e2f5ca5..70061a4 100644 --- a/components/drivers_nrf/spi_master/nrf_drv_spi.c +++ b/components/drivers_nrf/spi_master/nrf_drv_spi.c @@ -1,43 +1,109 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SPI) +#define ENABLED_SPI_COUNT (SPI0_ENABLED+SPI1_ENABLED+SPI2_ENABLED) +#if ENABLED_SPI_COUNT + #include "nrf_drv_spi.h" #include "nrf_drv_common.h" #include "nrf_gpio.h" #include "nrf_assert.h" #include "app_util_platform.h" +#define NRF_LOG_MODULE_NAME "SPI" + +#if SPI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL SPI_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR SPI_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR SPI_CONFIG_DEBUG_COLOR +#else //SPI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //SPI_CONFIG_LOG_ENABLED +#include "nrf_log.h" + +#ifndef SPIM_PRESENT + // Make sure SPIx_USE_EASY_DMA is 0 for nRF51 (if a common + // "nrf_drv_config.h" file is provided for nRF51 and nRF52). + #undef SPI0_USE_EASY_DMA + #define SPI0_USE_EASY_DMA 0 + #undef SPI1_USE_EASY_DMA + #define SPI1_USE_EASY_DMA 0 + #undef SPI2_USE_EASY_DMA + #define SPI2_USE_EASY_DMA 0 +#endif + +#ifndef SPI0_USE_EASY_DMA +#define SPI0_USE_EASY_DMA 0 +#endif + +#ifndef SPI1_USE_EASY_DMA +#define SPI1_USE_EASY_DMA 0 +#endif + +#ifndef SPI2_USE_EASY_DMA +#define SPI2_USE_EASY_DMA 0 +#endif + // This set of macros makes it possible to exclude parts of code when one type // of supported peripherals is not used. -#if ((SPI0_ENABLED == 1 && SPI0_USE_EASY_DMA == 1 && defined(NRF52)) || \ - (SPI1_ENABLED == 1 && SPI1_USE_EASY_DMA == 1) || \ - (SPI2_ENABLED == 1 && SPI2_USE_EASY_DMA == 1)) +#if ((NRF_MODULE_ENABLED(SPI0) && SPI0_USE_EASY_DMA) || \ + (NRF_MODULE_ENABLED(SPI1) && SPI1_USE_EASY_DMA) || \ + (NRF_MODULE_ENABLED(SPI2) && SPI2_USE_EASY_DMA)) #define SPIM_IN_USE #endif -#if ((SPI0_ENABLED == 1 && SPI0_USE_EASY_DMA == 0) || \ - (SPI0_ENABLED == 1 && defined(NRF51)) || \ - (SPI1_ENABLED == 1 && SPI1_USE_EASY_DMA == 0) || \ - (SPI2_ENABLED == 1 && SPI2_USE_EASY_DMA == 0)) +#if ((NRF_MODULE_ENABLED(SPI0) && !SPI0_USE_EASY_DMA) || \ + (NRF_MODULE_ENABLED(SPI1) && !SPI1_USE_EASY_DMA) || \ + (NRF_MODULE_ENABLED(SPI2) && !SPI2_USE_EASY_DMA)) #define SPI_IN_USE #endif -#if (defined(SPIM_IN_USE) && defined(SPI_IN_USE)) +#if defined(SPIM_IN_USE) && defined(SPI_IN_USE) // SPIM and SPI combined #define CODE_FOR_SPIM(code) if (p_instance->use_easy_dma) { code } #define CODE_FOR_SPI(code) else { code } -#elif (defined(SPIM_IN_USE) && !defined(SPI_IN_USE)) +#elif defined(SPIM_IN_USE) && !defined(SPI_IN_USE) // SPIM only #define CODE_FOR_SPIM(code) { code } #define CODE_FOR_SPI(code) -#elif (!defined(SPIM_IN_USE) && defined(SPI_IN_USE)) +#elif !defined(SPIM_IN_USE) && defined(SPI_IN_USE) // SPI only #define CODE_FOR_SPIM(code) #define CODE_FOR_SPI(code) { code } @@ -45,11 +111,15 @@ #error "Wrong configuration." #endif +#ifdef SPIM_IN_USE +#define END_INT_MASK NRF_SPIM_INT_END_MASK +#endif // Control block - driver instance local data. typedef struct { nrf_drv_spi_handler_t handler; + nrf_drv_spi_evt_t evt; // Keep the struct that is ready for event handler. Less memcpy. nrf_drv_state_t state; volatile bool transfer_in_progress; @@ -57,45 +127,66 @@ typedef struct // are not concurrently used in IRQ handlers and main line code] uint8_t ss_pin; uint8_t orc; - uint8_t tx_buffer_length; - uint8_t rx_buffer_length; uint8_t bytes_transferred; - uint8_t const * p_tx_buffer; - uint8_t * p_rx_buffer; bool tx_done : 1; bool rx_done : 1; } spi_control_block_t; -static spi_control_block_t m_cb[SPI_COUNT]; +static spi_control_block_t m_cb[ENABLED_SPI_COUNT]; -static nrf_drv_spi_config_t const m_default_config[SPI_COUNT] = { -#if (SPI0_ENABLED == 1) - NRF_DRV_SPI_DEFAULT_CONFIG(0), -#endif -#if (SPI1_ENABLED == 1) - NRF_DRV_SPI_DEFAULT_CONFIG(1), -#endif -#if (SPI2_ENABLED == 1) - NRF_DRV_SPI_DEFAULT_CONFIG(2), -#endif -}; +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n + #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void) + + #if NRF_MODULE_ENABLED(SPI0) + IRQ_HANDLER(0); + #endif + #if NRF_MODULE_ENABLED(SPI1) + IRQ_HANDLER(1); + #endif + #if NRF_MODULE_ENABLED(SPI2) + IRQ_HANDLER(2); + #endif + static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_SPI_COUNT] = { + #if NRF_MODULE_ENABLED(SPI0) + IRQ_HANDLER_NAME(0), + #endif + #if NRF_MODULE_ENABLED(SPI1) + IRQ_HANDLER_NAME(1), + #endif + #if NRF_MODULE_ENABLED(SPI2) + IRQ_HANDLER_NAME(2), + #endif + }; +#else + #define IRQ_HANDLER(n) void SPI##n##_IRQ_HANDLER(void) +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) ret_code_t nrf_drv_spi_init(nrf_drv_spi_t const * const p_instance, nrf_drv_spi_config_t const * p_config, nrf_drv_spi_handler_t handler) { + ASSERT(p_config); spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - + ret_code_t err_code; + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) { - return NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } - if (p_config == NULL) +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(p_instance->p_registers, + m_irq_handlers[p_instance->drv_inst_idx]) != NRF_SUCCESS) { - p_config = &m_default_config[p_instance->drv_inst_idx]; + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } +#endif p_cb->handler = handler; @@ -163,9 +254,7 @@ ret_code_t nrf_drv_spi_init(nrf_drv_spi_t const * const p_instance, if (p_cb->handler) { - nrf_spim_int_enable(p_spim, - NRF_SPIM_INT_ENDTX_MASK | NRF_SPIM_INT_ENDRX_MASK | - NRF_SPIM_INT_STOPPED_MASK); + nrf_spim_int_enable(p_spim, END_INT_MASK); } nrf_spim_enable(p_spim); @@ -198,7 +287,11 @@ ret_code_t nrf_drv_spi_init(nrf_drv_spi_t const * const p_instance, p_cb->transfer_in_progress = false; p_cb->state = NRF_DRV_STATE_INITIALIZED; - return NRF_SUCCESS; + NRF_LOG_INFO("Init\r\n"); + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance) @@ -212,12 +305,20 @@ void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance) } #define DISABLE_ALL 0xFFFFFFFF + CODE_FOR_SPIM ( NRF_SPIM_Type * p_spim = p_instance->p_registers; if (p_cb->handler) { nrf_spim_int_disable(p_spim, DISABLE_ALL); + if (p_cb->transfer_in_progress) + { + // Ensure that SPI is not performing any transfer. + nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_STOP); + while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_STOPPED)) {} + p_cb->transfer_in_progress = false; + } } nrf_spim_disable(p_spim); ) @@ -232,9 +333,50 @@ void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance) ) #undef DISABLE_ALL +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(p_instance->p_registers); +#endif + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; } +ret_code_t nrf_drv_spi_transfer(nrf_drv_spi_t const * const p_instance, + uint8_t const * p_tx_buffer, + uint8_t tx_buffer_length, + uint8_t * p_rx_buffer, + uint8_t rx_buffer_length) +{ + nrf_drv_spi_xfer_desc_t xfer_desc; + xfer_desc.p_tx_buffer = p_tx_buffer; + xfer_desc.p_rx_buffer = p_rx_buffer; + xfer_desc.tx_length = tx_buffer_length; + xfer_desc.rx_length = rx_buffer_length; + + NRF_LOG_INFO("Transfer tx_len:%d, rx_len:%d.\r\n", tx_buffer_length, rx_buffer_length); + NRF_LOG_DEBUG("Tx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_tx_buffer, tx_buffer_length * sizeof(p_tx_buffer)); + return nrf_drv_spi_xfer(p_instance, &xfer_desc, 0); +} + +static void finish_transfer(spi_control_block_t * p_cb) +{ + // If Slave Select signal is used, this is the time to deactivate it. + if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) + { + nrf_gpio_pin_set(p_cb->ss_pin); + } + + // By clearing this flag before calling the handler we allow subsequent + // transfers to be started directly from the handler function. + p_cb->transfer_in_progress = false; + p_cb->evt.type = NRF_DRV_SPI_EVENT_DONE; + NRF_LOG_INFO("Transfer rx_len:%d.\r\n", p_cb->evt.data.done.rx_length); + NRF_LOG_DEBUG("Rx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_cb->evt.data.done.p_rx_buffer, + p_cb->evt.data.done.rx_length * sizeof(p_cb->evt.data.done.p_rx_buffer)); + p_cb->handler(&p_cb->evt); +} + #ifdef SPI_IN_USE // This function is called from IRQ handler or, in blocking mode, directly // from the 'nrf_drv_spi_transfer' function. @@ -245,9 +387,9 @@ static bool transfer_byte(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb) // Read the data byte received in this transfer and store it in RX buffer, // if needed. volatile uint8_t rx_data = nrf_spi_rxd_get(p_spi); - if (p_cb->bytes_transferred < p_cb->rx_buffer_length) + if (p_cb->bytes_transferred < p_cb->evt.data.done.rx_length) { - p_cb->p_rx_buffer[p_cb->bytes_transferred] = rx_data; + p_cb->evt.data.done.p_rx_buffer[p_cb->bytes_transferred] = rx_data; } ++p_cb->bytes_transferred; @@ -261,197 +403,229 @@ static bool transfer_byte(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb) // see how the transfer is started in the 'nrf_drv_spi_transfer' // function. uint16_t bytes_used = p_cb->bytes_transferred + 1; - if (bytes_used < p_cb->tx_buffer_length) + if (bytes_used < p_cb->evt.data.done.tx_length) { - nrf_spi_txd_set(p_spi, p_cb->p_tx_buffer[bytes_used]); + nrf_spi_txd_set(p_spi, p_cb->evt.data.done.p_tx_buffer[bytes_used]); return true; } - else if (bytes_used < p_cb->rx_buffer_length) + else if (bytes_used < p_cb->evt.data.done.rx_length) { nrf_spi_txd_set(p_spi, p_cb->orc); return true; } - return (p_cb->bytes_transferred < p_cb->tx_buffer_length || - p_cb->bytes_transferred < p_cb->rx_buffer_length); + return (p_cb->bytes_transferred < p_cb->evt.data.done.tx_length || + p_cb->bytes_transferred < p_cb->evt.data.done.rx_length); } -#endif // SPI_IN_USE -ret_code_t nrf_drv_spi_transfer(nrf_drv_spi_t const * const p_instance, - uint8_t const * p_tx_buffer, - uint8_t tx_buffer_length, - uint8_t * p_rx_buffer, - uint8_t rx_buffer_length) +static void spi_xfer(NRF_SPI_Type * p_spi, + spi_control_block_t * p_cb, + nrf_drv_spi_xfer_desc_t const * p_xfer_desc) { - spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); - ASSERT(p_tx_buffer != NULL || tx_buffer_length == 0); - ASSERT(p_rx_buffer != NULL || rx_buffer_length == 0); + p_cb->bytes_transferred = 0; + nrf_spi_int_disable(p_spi, NRF_SPI_INT_READY_MASK); - if (p_cb->transfer_in_progress) + nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); + + // Start the transfer by writing some byte to the TXD register; + // if TX buffer is not empty, take the first byte from this buffer, + // otherwise - use over-run character. + nrf_spi_txd_set(p_spi, + (p_xfer_desc->tx_length > 0 ? p_xfer_desc->p_tx_buffer[0] : p_cb->orc)); + + // TXD register is double buffered, so next byte to be transmitted can + // be written immediately, if needed, i.e. if TX or RX transfer is to + // be more that 1 byte long. Again - if there is something more in TX + // buffer send it, otherwise use over-run character. + if (p_xfer_desc->tx_length > 1) { - return NRF_ERROR_BUSY; + nrf_spi_txd_set(p_spi, p_xfer_desc->p_tx_buffer[1]); } - - // Finish zero-length transfers immediately. - if (tx_buffer_length == 0 && rx_buffer_length == 0) + else if (p_xfer_desc->rx_length > 1) { - return NRF_SUCCESS; + nrf_spi_txd_set(p_spi, p_cb->orc); } - // Activate Slave Select signal, if it is to be used. - if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) + // For blocking mode (user handler not provided) wait here for READY + // events (indicating that the byte from TXD register was transmitted + // and a new incoming byte was moved to the RXD register) and continue + // transaction until all requested bytes are transferred. + // In non-blocking mode - IRQ service routine will do this stuff. + if (p_cb->handler) { - nrf_gpio_pin_clear(p_cb->ss_pin); + nrf_spi_int_enable(p_spi, NRF_SPI_INT_READY_MASK); } - - CODE_FOR_SPIM - ( - // EasyDMA requires that transfer buffers are placed in Data RAM region; - // signal error if they are not. - if ((p_tx_buffer != NULL && !nrf_drv_is_in_RAM(p_tx_buffer)) || - (p_rx_buffer != NULL && !nrf_drv_is_in_RAM(p_rx_buffer))) + else + { + do { + while (!nrf_spi_event_check(p_spi, NRF_SPI_EVENT_READY)) {} + nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); + NRF_LOG_DEBUG("SPI: Event: NRF_SPI_EVENT_READY.\r\n"); + } while (transfer_byte(p_spi, p_cb)); + if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) { - return NRF_ERROR_INVALID_ADDR; + nrf_gpio_pin_set(p_cb->ss_pin); } + } +} +#endif // SPI_IN_USE - NRF_SPIM_Type * p_spim = p_instance->p_registers; +#ifdef SPIM_IN_USE +__STATIC_INLINE void spim_int_enable(NRF_SPIM_Type * p_spim, bool enable) +{ + if (!enable) + { + nrf_spim_int_disable(p_spim, END_INT_MASK); + } + else + { + nrf_spim_int_enable(p_spim, END_INT_MASK); + } +} + +__STATIC_INLINE void spim_list_enable_handle(NRF_SPIM_Type * p_spim, uint32_t flags) +{ + if (NRF_DRV_SPI_FLAG_TX_POSTINC & flags) + { + nrf_spim_tx_list_enable(p_spim); + } + else + { + nrf_spim_tx_list_disable(p_spim); + } - nrf_spim_tx_buffer_set(p_spim, p_tx_buffer, tx_buffer_length); - nrf_spim_rx_buffer_set(p_spim, p_rx_buffer, rx_buffer_length); + if (NRF_DRV_SPI_FLAG_RX_POSTINC & flags) + { + nrf_spim_rx_list_enable(p_spim); + } + else + { + nrf_spim_rx_list_disable(p_spim); + } +} - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_ENDTX); - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_ENDRX); - p_cb->tx_done = false; - p_cb->rx_done = false; - - if (p_cb->handler) - { - p_cb->transfer_in_progress = true; - } - - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_STOPPED); - nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_START); +static ret_code_t spim_xfer(NRF_SPIM_Type * p_spim, + spi_control_block_t * p_cb, + nrf_drv_spi_xfer_desc_t const * p_xfer_desc, + uint32_t flags) +{ + ret_code_t err_code; + // EasyDMA requires that transfer buffers are placed in Data RAM region; + // signal error if they are not. + if ((p_xfer_desc->p_tx_buffer != NULL && !nrf_drv_is_in_RAM(p_xfer_desc->p_tx_buffer)) || + (p_xfer_desc->p_rx_buffer != NULL && !nrf_drv_is_in_RAM(p_xfer_desc->p_rx_buffer))) + { + p_cb->transfer_in_progress = false; + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } - if (!p_cb->handler) - { - while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_ENDTX) || - !nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_ENDRX)) {} + nrf_spim_tx_buffer_set(p_spim, p_xfer_desc->p_tx_buffer, p_xfer_desc->tx_length); + nrf_spim_rx_buffer_set(p_spim, p_xfer_desc->p_rx_buffer, p_xfer_desc->rx_length); - // Stop the peripheral after transaction is finished. - nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_STOP); - while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_STOPPED)) {} - if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) - { - nrf_gpio_pin_set(p_cb->ss_pin); - } - } - ) - CODE_FOR_SPI - ( - NRF_SPI_Type * p_spi = p_instance->p_registers; + nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END); - p_cb->p_tx_buffer = p_tx_buffer; - p_cb->tx_buffer_length = tx_buffer_length; - p_cb->p_rx_buffer = p_rx_buffer; - p_cb->rx_buffer_length = rx_buffer_length; - p_cb->bytes_transferred = 0; + spim_list_enable_handle(p_spim, flags); - + if (!(flags & NRF_DRV_SPI_FLAG_HOLD_XFER)) + { + nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_START); + } - if (p_cb->handler) + if (!p_cb->handler) + { + while (!nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END)){} + if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) { - p_cb->transfer_in_progress = true; - nrf_spi_int_disable(p_spi, NRF_SPI_INT_READY_MASK); + nrf_gpio_pin_set(p_cb->ss_pin); } - nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); - - // Start the transfer by writing some byte to the TXD register; - // if TX buffer is not empty, take the first byte from this buffer, - // otherwise - use over-run character. - nrf_spi_txd_set(p_spi, - (tx_buffer_length > 0 ? p_tx_buffer[0] : p_cb->orc)); - - // TXD register is double buffered, so next byte to be transmitted can - // be written immediately, if needed, i.e. if TX or RX transfer is to - // be more that 1 byte long. Again - if there is something more in TX - // buffer send it, otherwise use over-run character. - if (tx_buffer_length > 1) + } + else { - nrf_spi_txd_set(p_spi, p_tx_buffer[1]); + spim_int_enable(p_spim, !(flags & NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER)); } - else if (rx_buffer_length > 1) + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} +#endif + +ret_code_t nrf_drv_spi_xfer(nrf_drv_spi_t const * const p_instance, + nrf_drv_spi_xfer_desc_t const * p_xfer_desc, + uint32_t flags) +{ + spi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_xfer_desc->p_tx_buffer != NULL || p_xfer_desc->tx_length == 0); + ASSERT(p_xfer_desc->p_rx_buffer != NULL || p_xfer_desc->rx_length == 0); + + ret_code_t err_code = NRF_SUCCESS; + + if (p_cb->transfer_in_progress) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + else + { + if (p_cb->handler && !(flags & (NRF_DRV_SPI_FLAG_REPEATED_XFER | NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER))) { - nrf_spi_txd_set(p_spi, p_cb->orc); + p_cb->transfer_in_progress = true; } + } - // For blocking mode (user handler not provided) wait here for READY - // events (indicating that the byte from TXD register was transmitted - // and a new incoming byte was moved to the RXD register) and continue - // transaction until all requested bytes are transferred. - // In non-blocking mode - IRQ service routine will do this stuff. - if (p_cb->handler) + p_cb->evt.data.done = *p_xfer_desc; + p_cb->tx_done = false; + p_cb->rx_done = false; + + if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) + { + nrf_gpio_pin_clear(p_cb->ss_pin); + } + CODE_FOR_SPIM + ( + return spim_xfer(p_instance->p_registers, p_cb, p_xfer_desc, flags); + ) + CODE_FOR_SPI + ( + if (flags) { - nrf_spi_int_enable(p_spi, NRF_SPI_INT_READY_MASK); + p_cb->transfer_in_progress = false; + err_code = NRF_ERROR_NOT_SUPPORTED; } else { - do { - while (!nrf_spi_event_check(p_spi, NRF_SPI_EVENT_READY)) {} - nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); - } while (transfer_byte(p_spi, p_cb)); - if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) - { - nrf_gpio_pin_set(p_cb->ss_pin); - } + spi_xfer(p_instance->p_registers, p_cb, p_xfer_desc); } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; ) - - return NRF_SUCCESS; -} - -static void finish_transfer(spi_control_block_t * p_cb) -{ - // If Slave Select signal is used, this is the time to deactivate it. - if (p_cb->ss_pin != NRF_DRV_SPI_PIN_NOT_USED) - { - nrf_gpio_pin_set(p_cb->ss_pin); - } - - // By clearing this flag before calling the handler we allow subsequent - // transfers to be started directly from the handler function. - p_cb->transfer_in_progress = false; - p_cb->handler(NRF_DRV_SPI_EVENT_DONE); } - #ifdef SPIM_IN_USE static void irq_handler_spim(NRF_SPIM_Type * p_spim, spi_control_block_t * p_cb) { ASSERT(p_cb->handler); - if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_STOPPED)) + if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END)) { - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_STOPPED); + nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END); + NRF_LOG_DEBUG("SPIM: Event: NRF_SPIM_EVENT_END.\r\n"); finish_transfer(p_cb); } - else - { - if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_ENDTX)) - { - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_ENDTX); - p_cb->tx_done = true; - } - if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_ENDRX)) - { - nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_ENDRX); - p_cb->rx_done = true; - } +} - if (p_cb->tx_done && p_cb->rx_done) - { - nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_STOP); - } - } +uint32_t nrf_drv_spi_start_task_get(nrf_drv_spi_t const * p_instance) +{ + NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_registers; + return nrf_spim_task_address_get(p_spim, NRF_SPIM_TASK_START); +} + +uint32_t nrf_drv_spi_end_event_get(nrf_drv_spi_t const * p_instance) +{ + NRF_SPIM_Type * p_spim = (NRF_SPIM_Type *)p_instance->p_registers; + return nrf_spim_event_address_get(p_spim, NRF_SPIM_EVENT_END); } #endif // SPIM_IN_USE @@ -461,6 +635,7 @@ static void irq_handler_spi(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb) ASSERT(p_cb->handler); nrf_spi_event_clear(p_spi, NRF_SPI_EVENT_READY); + NRF_LOG_DEBUG("SPI: Event: NRF_SPI_EVENT_READY.\r\n"); if (!transfer_byte(p_spi, p_cb)) { @@ -469,38 +644,40 @@ static void irq_handler_spi(NRF_SPI_Type * p_spi, spi_control_block_t * p_cb) } #endif // SPI_IN_USE -#if (SPI0_ENABLED == 1) -void SPI0_IRQ_HANDLER(void) +#if NRF_MODULE_ENABLED(SPI0) +IRQ_HANDLER(0) { - #if (SPI0_USE_EASY_DMA == 1) && defined(NRF52) - irq_handler_spim(NRF_SPIM0, + spi_control_block_t * p_cb = &m_cb[SPI0_INSTANCE_INDEX]; + #if SPI0_USE_EASY_DMA + irq_handler_spim(NRF_SPIM0, p_cb); #else - irq_handler_spi(NRF_SPI0, + irq_handler_spi(NRF_SPI0, p_cb); #endif - &m_cb[SPI0_INSTANCE_INDEX]); } -#endif // (SPI0_ENABLED == 1) +#endif // NRF_MODULE_ENABLED(SPI0) -#if (SPI1_ENABLED == 1) -void SPI1_IRQ_HANDLER(void) +#if NRF_MODULE_ENABLED(SPI1) +IRQ_HANDLER(1) { - #if (SPI1_USE_EASY_DMA == 1) - irq_handler_spim(NRF_SPIM1, + spi_control_block_t * p_cb = &m_cb[SPI1_INSTANCE_INDEX]; + #if SPI1_USE_EASY_DMA + irq_handler_spim(NRF_SPIM1, p_cb); #else - irq_handler_spi(NRF_SPI1, + irq_handler_spi(NRF_SPI1, p_cb); #endif - &m_cb[SPI1_INSTANCE_INDEX]); } -#endif // (SPI1_ENABLED == 1) +#endif // NRF_MODULE_ENABLED(SPI1) -#if (SPI2_ENABLED == 1) -void SPI2_IRQ_HANDLER(void) +#if NRF_MODULE_ENABLED(SPI2) +IRQ_HANDLER(2) { - #if (SPI2_USE_EASY_DMA == 1) - irq_handler_spim(NRF_SPIM2, + spi_control_block_t * p_cb = &m_cb[SPI2_INSTANCE_INDEX]; + #if SPI2_USE_EASY_DMA + irq_handler_spim(NRF_SPIM2, p_cb); #else - irq_handler_spi(NRF_SPI2, + irq_handler_spi(NRF_SPI2, p_cb); #endif - &m_cb[SPI2_INSTANCE_INDEX]); } -#endif // (SPI2_ENABLED == 1) +#endif // NRF_MODULE_ENABLED(SPI2) +#endif // ENABLED_SPI_COUNT +#endif // NRF_MODULE_ENABLED(SPI) diff --git a/components/drivers_nrf/spi_master/nrf_drv_spi.h b/components/drivers_nrf/spi_master/nrf_drv_spi.h index 677f2cc..e221d82 100644 --- a/components/drivers_nrf/spi_master/nrf_drv_spi.h +++ b/components/drivers_nrf/spi_master/nrf_drv_spi.h @@ -1,36 +1,67 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 - * @addtogroup nrf_spi Serial peripheral interface (SPI) + * @addtogroup nrf_spi Serial peripheral interface (SPI/SPIM) * @ingroup nrf_drivers - * @brief Serial peripheral interface (SPI) APIs. + * @brief Serial peripheral interface (SPI/SPIM) APIs. * - * - * @addtogroup nrf_spi_master SPI master HAL and driver - * @ingroup nrf_spi - * @brief SPI master APIs. */ #ifndef NRF_DRV_SPI_H__ #define NRF_DRV_SPI_H__ #include "nordic_common.h" -#include "nrf_drv_config.h" +#include "sdk_config.h" +#include "nrf_peripherals.h" #include "nrf_spi.h" +#ifdef SPIM_PRESENT #include "nrf_spim.h" +#endif #include "sdk_errors.h" -#if defined(NRF52) +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(SPIM_PRESENT) #define NRF_DRV_SPI_PERIPHERAL(id) \ (CONCAT_3(SPI, id, _USE_EASY_DMA) == 1 ? \ (void *)CONCAT_2(NRF_SPIM, id) \ @@ -47,9 +78,9 @@ /** - * @defgroup nrf_drv_spi_master SPI master driver + * @defgroup nrf_drv_spi SPI master driver * @{ - * @ingroup nrf_spi_master + * @ingroup nrf_spi * * @brief Multi-instance SPI master driver. */ @@ -65,6 +96,10 @@ typedef struct bool use_easy_dma; ///< True if the peripheral with EasyDMA (SPIM) shall be used. } nrf_drv_spi_t; +#define SPI0_INSTANCE_INDEX 0 +#define SPI1_INSTANCE_INDEX SPI0_INSTANCE_INDEX+SPI0_ENABLED +#define SPI2_INSTANCE_INDEX SPI1_INSTANCE_INDEX+SPI1_ENABLED + /** * @brief Macro for creating an SPI master driver instance. */ @@ -124,14 +159,17 @@ typedef struct { uint8_t sck_pin; ///< SCK pin number. uint8_t mosi_pin; ///< MOSI pin number (optional). - /**< Set @ref NRF_DRV_SPI_PIN_NOT_USED + /**< Set to @ref NRF_DRV_SPI_PIN_NOT_USED * if this signal is not needed. */ uint8_t miso_pin; ///< MISO pin number (optional). - /**< Set @ref NRF_DRV_SPI_PIN_NOT_USED + /**< Set to @ref NRF_DRV_SPI_PIN_NOT_USED * if this signal is not needed. */ uint8_t ss_pin; ///< Slave Select pin number (optional). - /**< Set @ref NRF_DRV_SPI_PIN_NOT_USED - * if this signal is not needed. */ + /**< Set to @ref NRF_DRV_SPI_PIN_NOT_USED + * if this signal is not needed. The driver + * supports only active low for this signal. + * If the signal should be active high, + * it must be controlled externally. */ uint8_t irq_priority; ///< Interrupt priority. uint8_t orc; ///< Over-run character. /**< This character is used when all bytes from the TX buffer are sent, @@ -144,32 +182,90 @@ typedef struct /** * @brief SPI master instance default configuration. */ -#define NRF_DRV_SPI_DEFAULT_CONFIG(id) \ +#define NRF_DRV_SPI_DEFAULT_CONFIG \ { \ - .sck_pin = CONCAT_3(SPI, id, _CONFIG_SCK_PIN), \ - .mosi_pin = CONCAT_3(SPI, id, _CONFIG_MOSI_PIN), \ - .miso_pin = CONCAT_3(SPI, id, _CONFIG_MISO_PIN), \ + .sck_pin = NRF_DRV_SPI_PIN_NOT_USED, \ + .mosi_pin = NRF_DRV_SPI_PIN_NOT_USED, \ + .miso_pin = NRF_DRV_SPI_PIN_NOT_USED, \ .ss_pin = NRF_DRV_SPI_PIN_NOT_USED, \ - .irq_priority = CONCAT_3(SPI, id, _CONFIG_IRQ_PRIORITY), \ + .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY, \ .orc = 0xFF, \ .frequency = NRF_DRV_SPI_FREQ_4M, \ .mode = NRF_DRV_SPI_MODE_0, \ .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST, \ } +#define NRF_DRV_SPI_FLAG_TX_POSTINC (1UL << 0) /**< TX buffer address incremented after transfer. */ +#define NRF_DRV_SPI_FLAG_RX_POSTINC (1UL << 1) /**< RX buffer address incremented after transfer. */ +#define NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER (1UL << 2) /**< Interrupt after each transfer is suppressed, and the event handler is not called. */ +#define NRF_DRV_SPI_FLAG_HOLD_XFER (1UL << 3) /**< Set up the transfer but do not start it. */ +#define NRF_DRV_SPI_FLAG_REPEATED_XFER (1UL << 4) /**< Flag indicating that the transfer will be executed multiple times. */ + /** - * @brief SPI master driver events, passed to the handler routine provided + * @brief Single transfer descriptor structure. + */ +typedef struct +{ + uint8_t const * p_tx_buffer; ///< Pointer to TX buffer. + uint8_t tx_length; ///< TX buffer length. + uint8_t * p_rx_buffer; ///< Pointer to RX buffer. + uint8_t rx_length; ///< RX buffer length. +}nrf_drv_spi_xfer_desc_t; + + +/** + * @brief Macro for setting up single transfer descriptor. + * + * This macro is for internal use only. + */ +#define NRF_DRV_SPI_SINGLE_XFER(p_tx, tx_len, p_rx, rx_len) \ + { \ + .p_tx_buffer = (uint8_t const *)(p_tx), \ + .tx_length = (tx_len), \ + .p_rx_buffer = (p_rx), \ + .rx_length = (rx_len), \ + } + +/** + * @brief Macro for setting duplex TX RX transfer. + */ +#define NRF_DRV_SPI_XFER_TRX(p_tx_buf, tx_length, p_rx_buf, rx_length) \ + NRF_DRV_SPI_SINGLE_XFER(p_tx_buf, tx_length, p_rx_buf, rx_length) + +/** + * @brief Macro for setting TX transfer. + */ +#define NRF_DRV_SPI_XFER_TX(p_buf, length) \ + NRF_DRV_SPI_SINGLE_XFER(p_buf, length, NULL, 0) + +/** + * @brief Macro for setting RX transfer. + */ +#define NRF_DRV_SPI_XFER_RX(p_buf, length) \ + NRF_DRV_SPI_SINGLE_XFER(NULL, 0, p_buf, length) + +/** + * @brief SPI master driver event types, passed to the handler routine provided * during initialization. */ typedef enum { NRF_DRV_SPI_EVENT_DONE, ///< Transfer done. -} nrf_drv_spi_event_t; +} nrf_drv_spi_evt_type_t; + +typedef struct +{ + nrf_drv_spi_evt_type_t type; ///< Event type. + union + { + nrf_drv_spi_xfer_desc_t done; ///< Event data for DONE event. + } data; +} nrf_drv_spi_evt_t; /** * @brief SPI master driver event handler type. */ -typedef void (*nrf_drv_spi_handler_t)(nrf_drv_spi_event_t event); +typedef void (*nrf_drv_spi_handler_t)(nrf_drv_spi_evt_t const * p_event); /** @@ -177,7 +273,7 @@ typedef void (*nrf_drv_spi_handler_t)(nrf_drv_spi_event_t event); * * This function configures and enables the specified peripheral. * - * @param[in] p_instance Pointer to the instance structure. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] p_config Pointer to the structure with the initial configuration. * If NULL, the default configuration is used. * @param handler Event handler provided by the user. If NULL, transfers @@ -185,6 +281,10 @@ typedef void (*nrf_drv_spi_handler_t)(nrf_drv_spi_event_t event); * * @retval NRF_SUCCESS If initialization was successful. * @retval NRF_ERROR_INVALID_STATE If the driver was already initialized. + * @retval NRF_ERROR_BUSY If some other peripheral with the same + * instance ID is already in use. This is + * possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED + * is set to a value other than zero. */ ret_code_t nrf_drv_spi_init(nrf_drv_spi_t const * const p_instance, nrf_drv_spi_config_t const * p_config, @@ -193,7 +293,7 @@ ret_code_t nrf_drv_spi_init(nrf_drv_spi_t const * const p_instance, /** * @brief Function for uninitializing the SPI master driver instance. * - * @param[in] p_instance Pointer to the instance structure. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance); @@ -206,10 +306,10 @@ void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance); * returns when the transfer is finished. * * @note Peripherals using EasyDMA (for example, SPIM) require the transfer buffers - * to be placed in the data RAM region. If they are not and an SPIM instance is + * to be placed in the Data RAM region. If they are not and an SPIM instance is * used, this function will fail with the error code NRF_ERROR_INVALID_ADDR. * - * @param[in] p_instance Pointer to the instance structure. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] p_tx_buffer Pointer to the transmit buffer. Can be NULL * if there is nothing to send. * @param tx_buffer_length Length of the transmit buffer. @@ -220,7 +320,7 @@ void nrf_drv_spi_uninit(nrf_drv_spi_t const * const p_instance); * @retval NRF_SUCCESS If the operation was successful. * @retval NRF_ERROR_BUSY If a previously started transfer has not finished * yet. - * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the data + * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the Data * RAM region. */ ret_code_t nrf_drv_spi_transfer(nrf_drv_spi_t const * const p_instance, @@ -229,6 +329,80 @@ ret_code_t nrf_drv_spi_transfer(nrf_drv_spi_t const * const p_instance, uint8_t * p_rx_buffer, uint8_t rx_buffer_length); + +/** + * @brief Function for starting the SPI data transfer with additional option flags. + * + * Function enables customizing the transfer by using option flags. + * + * Additional options are provided using the flags parameter: + * + * - @ref NRF_DRV_SPI_FLAG_TX_POSTINC and @ref NRF_DRV_SPI_FLAG_RX_POSTINC: + * Post-incrementation of buffer addresses. Supported only by SPIM. + * - @ref NRF_DRV_SPI_FLAG_HOLD_XFER: Driver is not starting the transfer. Use this + * flag if the transfer is triggered externally by PPI. Supported only by SPIM. Use + * @ref nrf_drv_twi_start_task_get to get the address of the start task. + * - @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER: No user event handler after transfer + * completion. This also means no interrupt at the end of the transfer. Supported only by SPIM. + * If @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER is used, the driver does not set the instance into + * busy state, so you must ensure that the next transfers are set up when SPIM is not active. + * @ref nrf_drv_spi_end_event_get function can be used to detect end of transfer. Option can be used + * together with @ref NRF_DRV_SPI_FLAG_REPEATED_XFER to prepare a sequence of SPI transfers + * without interruptions. + * - @ref NRF_DRV_SPI_FLAG_REPEATED_XFER: Prepare for repeated transfers. You can set + * up a number of transfers that will be triggered externally (for example by PPI). An example is + * a TXRX transfer with the options @ref NRF_DRV_SPI_FLAG_RX_POSTINC, + * @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER, and @ref NRF_DRV_SPI_FLAG_REPEATED_XFER. After the + * transfer is set up, a set of transfers can be triggered by PPI that will read, for example, + * the same register of an external component and put it into a RAM buffer without any interrupts. + * @ref nrf_drv_spi_end_event_get can be used to get the address of the END event, which can be + * used to count the number of transfers. If @ref NRF_DRV_SPI_FLAG_REPEATED_XFER is used, + * the driver does not set the instance into busy state, so you must ensure that the next + * transfers are set up when SPIM is not active. Supported only by SPIM. + * @note Function is intended to be used only in non-blocking mode. + * + * @param p_instance Pointer to the driver instance structure. + * @param p_xfer_desc Pointer to the transfer descriptor. + * @param flags Transfer options (0 for default settings). + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. + * @retval NRF_ERROR_NOT_SUPPORTED If the provided parameters are not supported. + * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the Data + * RAM region. + */ +ret_code_t nrf_drv_spi_xfer(nrf_drv_spi_t const * const p_instance, + nrf_drv_spi_xfer_desc_t const * p_xfer_desc, + uint32_t flags); + +/** + * @brief Function for returning the address of a SPIM start task. + * + * This function should be used if @ref nrf_drv_spi_xfer was called with the flag @ref NRF_DRV_SPI_FLAG_HOLD_XFER. + * In that case, the transfer is not started by the driver, but it must be started externally by PPI. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @return Start task address. + */ +uint32_t nrf_drv_spi_start_task_get(nrf_drv_spi_t const * p_instance); + +/** + * @brief Function for returning the address of a END SPIM event. + * + * A END event can be used to detect the end of a transfer if the @ref NRF_DRV_SPI_FLAG_NO_XFER_EVT_HANDLER + * option is used. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @return END event address. + */ +uint32_t nrf_drv_spi_end_event_get(nrf_drv_spi_t const * p_instance); + +#ifdef __cplusplus +} +#endif + #endif // NRF_DRV_SPI_H__ /** @} */ diff --git a/components/drivers_nrf/spi_master/spi_5W_master.c b/components/drivers_nrf/spi_master/spi_5W_master.c index 3913c1b..1a00ccf 100644 --- a/components/drivers_nrf/spi_master/spi_5W_master.c +++ b/components/drivers_nrf/spi_master/spi_5W_master.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -26,6 +54,7 @@ #include "spi_5W_master.h" #include "ser_config_5W_app.h" #include "ser_phy_debug_app.h" +#include "sdk_common.h" #define _static @@ -291,10 +320,7 @@ uint32_t spi_master_open(const spi_master_hw_instance_t spi_master_hw_instanc #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) - if (p_spi_master_config == NULL) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(p_spi_master_config); spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); diff --git a/components/drivers_nrf/spi_master/spi_5W_master.h b/components/drivers_nrf/spi_master/spi_5W_master.h index 940db8b..fc3600b 100644 --- a/components/drivers_nrf/spi_master/spi_5W_master.h +++ b/components/drivers_nrf/spi_master/spi_5W_master.h @@ -1,15 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_SPI_MASTER_H #define APP_SPI_MASTER_H @@ -17,6 +45,10 @@ #include #include "boards.h" +#ifdef __cplusplus +extern "C" { +#endif + #define _SPI_5W_ /**@brief Struct containing configuration parameters of the SPI master. */ @@ -42,7 +74,7 @@ typedef enum SPI_MASTER_EVT_FIRST_BYTE_RECEIVED, /**< An event indicating end of one byte transfer */ SPI_MASTER_EVT_TYPE_MAX /**< Enumeration upper bound. */ } spi_master_evt_type_t; - + /**@brief Struct containing parameters of the SPI MASTER event */ typedef struct { @@ -65,14 +97,14 @@ typedef enum #ifdef SPI_MASTER_0_ENABLE SPI_MASTER_0, /**< A instance of SPI master 0. */ #endif - + #ifdef SPI_MASTER_1_ENABLE SPI_MASTER_1, /**< A instance of SPI master 1. */ - #endif - + #endif + SPI_MASTER_HW_ENABLED_COUNT /**< A number of enabled instances of SPI master. */ } spi_master_hw_instance_t; - + /**@brief Type of generic callback function handler to be used by all SPI MASTER driver events. * * @param[in] spi_master_evt SPI MASTER driver event. @@ -88,19 +120,19 @@ typedef void (*spi_master_event_handler_t) (spi_master_evt_t spi_master_evt); * called before spi_master_open can be called again. * * @param[in] spi_master_hw_instance Instance of SPI master module. - * @param[in] p_spi_master_config Pointer to configuration structure which will be used + * @param[in] p_spi_master_config Pointer to configuration structure which will be used * to initialize SPI MASTER hardware. * * @retval NRF_SUCCESS Operation success. * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. - * To call it again the function @ref spi_master_close + * To call it again the function @ref spi_master_close * has to be called previously. * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. */ uint32_t spi_master_open(const spi_master_hw_instance_t spi_master_hw_instance, spi_master_config_t const * const p_spi_master_config); - + /**@brief Function for closing a SPI MASTER driver. * * @note Function disable hardware, reset internal module states and unregister events callback @@ -110,7 +142,7 @@ uint32_t spi_master_open(const spi_master_hw_instance_t spi_master_hw_instance, */ void spi_master_close(const spi_master_hw_instance_t spi_master_hw_instance); - + /**@brief Function for transferring data between SPI master and SPI slave * * @note Function registers buffers pointed by p_tx_buf and p_rx_buf parameters, after that starts transmission. @@ -138,7 +170,7 @@ void spi_master_close(const spi_master_hw_instance_t spi_master_hw_instance); * @ref SPI_MASTER_EVT_TRANSFER_STARTED and @ref SPI_MASTER_EVT_TRANSFER_COMPLETED. * * @param[in] spi_master_hw_instance Instance of SPI master module. -* @param[in] event_handler Generic callback function handler to be used +* @param[in] event_handler Generic callback function handler to be used * by all SPI master driver events. */ void spi_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance, @@ -148,12 +180,12 @@ void spi_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_ins /**@brief Function for getting current state of the SPI master driver. * * @note Function gets current state of the SPI master driver. - * + * * @param[in] spi_master_hw_instance Instance of SPI master module. * * @retval SPI_MASTER_STATE_DISABLED SPI MASTER is disabled. - * @retval SPI_MASTER_STATE_BUSY SPI_MASTER is sending now. - * @retval SPI_MASTER_STATE_IDLE SPI_MASTER is idle now. + * @retval SPI_MASTER_STATE_BUSY SPI_MASTER is sending now. + * @retval SPI_MASTER_STATE_IDLE SPI_MASTER is idle now. */ spi_master_state_t spi_master_get_state(const spi_master_hw_instance_t spi_master_hw_instance); @@ -167,4 +199,9 @@ void spi_5W_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_ spi_master_event_handler_t event_handler); #endif + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_nrf/spi_slave/nrf_drv_spis.c b/components/drivers_nrf/spi_slave/nrf_drv_spis.c index 098f210..c545be0 100644 --- a/components/drivers_nrf/spi_slave/nrf_drv_spis.c +++ b/components/drivers_nrf/spi_slave/nrf_drv_spis.c @@ -1,15 +1,47 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SPIS) +#define ENABLED_SPIS_COUNT (SPIS0_ENABLED+SPIS1_ENABLED+SPIS2_ENABLED) +#if ENABLED_SPIS_COUNT #include "nrf_drv_spis.h" #include #include @@ -17,29 +49,70 @@ #include "nrf_gpio.h" #include "app_error.h" #include "app_util_platform.h" -#include "nrf_drv_config.h" #include "nrf_drv_common.h" -#include "nordic_common.h" -#include "sdk_common.h" #include "nrf_assert.h" -#if !SPIS_COUNT - #warning No SPIS instances enabled. -#else +#define NRF_LOG_MODULE_NAME "SPIS" + +#if SPIS_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL SPIS_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR SPIS_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR SPIS_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_SPIS_EVENT_ACQUIRED ? "NRF_SPIS_EVENT_ACQUIRED" : \ + (event == NRF_SPIS_EVENT_END ? "NRF_SPIS_EVENT_END" : "UNKNOWN ERROR")) + +#else //SPIS_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //SPIS_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + /**@brief States of the SPI transaction state machine. */ typedef enum { - SPIS_STATE_INIT, /**< Initialization state. In this state the module waits for a call to @ref spi_slave_buffers_set. */ + SPIS_STATE_INIT, /**< Initialization state. In this state the module waits for a call to @ref spi_slave_buffers_set. */ SPIS_BUFFER_RESOURCE_REQUESTED, /**< State where the configuration of the memory buffers, which are to be used in SPI transaction, has started. */ SPIS_BUFFER_RESOURCE_CONFIGURED, /**< State where the configuration of the memory buffers, which are to be used in SPI transaction, has completed. */ SPIS_XFER_COMPLETED /**< State where SPI transaction has been completed. */ } nrf_drv_spis_state_t; -#define SPIS_IRQHANDLER_TEMPLATE(NUM) void SPIS##NUM##_IRQ_HANDLER(void) \ - { \ - spis_irq_handler(NRF_SPIS##NUM, &m_cb[SPIS##NUM##_INSTANCE_INDEX]); \ - } + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n + #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void) + + #if NRF_MODULE_ENABLED(SPIS0) + IRQ_HANDLER(0); + #endif + #if NRF_MODULE_ENABLED(SPIS1) + IRQ_HANDLER(1); + #endif + #if NRF_MODULE_ENABLED(SPIS2) + IRQ_HANDLER(2); + #endif + static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_SPIS_COUNT] = { + #if NRF_MODULE_ENABLED(SPIS0) + IRQ_HANDLER_NAME(0), + #endif + #if NRF_MODULE_ENABLED(SPIS1) + IRQ_HANDLER_NAME(1), + #endif + #if NRF_MODULE_ENABLED(SPIS2) + IRQ_HANDLER_NAME(2), + #endif + }; +#else + #define IRQ_HANDLER(n) void SPIS##n##_IRQ_HANDLER(void) +#endif // PERIPHERAL_RESOURCE_SHARING_ENABLED + +#define SPIS_IRQHANDLER_TEMPLATE(NUM) \ + IRQ_HANDLER(NUM) \ + { \ + spis_irq_handler(NRF_SPIS##NUM, &m_cb[SPIS##NUM##_INSTANCE_INDEX]); \ + } + /**@brief SPIS control block - driver instance local data. */ typedef struct @@ -53,50 +126,51 @@ typedef struct volatile nrf_drv_spis_state_t spi_state; //!< SPI slave state. } spis_cb_t; -static spis_cb_t m_cb[SPIS_COUNT]; - -static nrf_drv_spis_config_t const m_default_config[SPIS_COUNT] = { -#if (SPIS0_ENABLED == 1) - NRF_DRV_SPIS_DEFAULT_CONFIG(0), -#endif -#if (SPIS1_ENABLED == 1) - NRF_DRV_SPIS_DEFAULT_CONFIG(1), -#endif -#if (SPIS2_ENABLED == 1) - NRF_DRV_SPIS_DEFAULT_CONFIG(2), -#endif -}; - +static spis_cb_t m_cb[ENABLED_SPIS_COUNT]; ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance, nrf_drv_spis_config_t const * p_config, nrf_drv_spis_event_handler_t event_handler) { + ASSERT(p_config); spis_cb_t * p_cb = &m_cb[p_instance->instance_id]; + ret_code_t err_code; + NRF_SPIS_Type * p_spis = p_instance->p_reg; + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) { - return NRF_ERROR_INVALID_STATE; - } - if (p_config == NULL) - { - p_config = &m_default_config[p_instance->instance_id]; + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } + if ((uint32_t)p_config->mode > (uint32_t)NRF_DRV_SPIS_MODE_3) { - return NRF_ERROR_INVALID_PARAM; + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } if (!event_handler) { - return NRF_ERROR_NULL; + err_code = NRF_ERROR_NULL; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } - - NRF_SPIS_Type * p_spis = p_instance->p_reg; +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(p_spis, + m_irq_handlers[p_instance->instance_id]) != NRF_SUCCESS) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } +#endif // Configure the SPI pins for input. uint32_t mosi_pin; uint32_t miso_pin; - + if (p_config->miso_pin != NRF_DRV_SPIS_PIN_NOT_USED) { nrf_gpio_cfg(p_config->miso_pin, @@ -111,7 +185,7 @@ ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance, { miso_pin = NRF_SPIS_PIN_NOT_CONNECTED; } - + if (p_config->mosi_pin != NRF_DRV_SPIS_PIN_NOT_USED) { nrf_gpio_cfg(p_config->mosi_pin, @@ -126,14 +200,14 @@ ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance, { mosi_pin = NRF_SPIS_PIN_NOT_CONNECTED; } - + nrf_gpio_cfg(p_config->csn_pin, NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_CONNECT, p_config->csn_pullup, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE); - + nrf_gpio_cfg(p_config->sck_pin, NRF_GPIO_PIN_DIR_INPUT, NRF_GPIO_PIN_INPUT_CONNECT, @@ -142,39 +216,41 @@ ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance, NRF_GPIO_PIN_NOSENSE); nrf_spis_pins_set(p_spis, p_config->sck_pin, mosi_pin, miso_pin, p_config->csn_pin); - + nrf_spis_rx_buffer_set(p_spis, NULL, 0); nrf_spis_tx_buffer_set(p_spis, NULL, 0); - + // Configure SPI mode. nrf_spis_configure(p_spis, (nrf_spis_mode_t) p_config->mode, (nrf_spis_bit_order_t) p_config->bit_order); - + // Configure DEF and ORC characters. nrf_spis_def_set(p_spis, p_config->def); nrf_spis_orc_set(p_spis, p_config->orc); - + // Clear possible pending events. nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_END); nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_ACQUIRED); - - // Enable END_ACQUIRE shortcut. + + // Enable END_ACQUIRE shortcut. nrf_spis_shorts_enable(p_spis, NRF_SPIS_SHORT_END_ACQUIRE); - + m_cb[p_instance->instance_id].spi_state = SPIS_STATE_INIT; m_cb[p_instance->instance_id].handler = event_handler; - + // Enable IRQ. nrf_spis_int_enable(p_spis, NRF_SPIS_INT_ACQUIRED_MASK | NRF_SPIS_INT_END_MASK); nrf_drv_common_irq_enable(p_instance->irq, p_config->irq_priority); - + p_cb->state = NRF_DRV_STATE_INITIALIZED; - - // Enable SPI slave device. + + // Enable SPI slave device. nrf_spis_enable(p_spis); - - return NRF_SUCCESS; + + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } @@ -182,14 +258,21 @@ void nrf_drv_spis_uninit(nrf_drv_spis_t const * const p_instance) { spis_cb_t * p_cb = &m_cb[p_instance->instance_id]; ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); - + + NRF_SPIS_Type * p_spis = p_instance->p_reg; + #define DISABLE_ALL 0xFFFFFFFF - nrf_spis_disable(p_instance->p_reg); + nrf_spis_disable(p_spis); nrf_drv_common_irq_disable(p_instance->irq); - nrf_spis_int_disable(p_instance->p_reg, DISABLE_ALL); + nrf_spis_int_disable(p_spis, DISABLE_ALL); #undef DISABLE_ALL - + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(p_spis); +#endif + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Initialized.\r\n"); } @@ -198,32 +281,35 @@ static void spis_state_entry_action_execute(NRF_SPIS_Type * p_spis, spis_cb_t * p_cb) { nrf_drv_spis_event_t event; - + switch (p_cb->spi_state) - { + { case SPIS_BUFFER_RESOURCE_REQUESTED: nrf_spis_task_trigger(p_spis, NRF_SPIS_TASK_ACQUIRE); - break; - + break; + case SPIS_BUFFER_RESOURCE_CONFIGURED: event.evt_type = NRF_DRV_SPIS_BUFFERS_SET_DONE; event.rx_amount = 0; - event.tx_amount = 0; - + event.tx_amount = 0; + APP_ERROR_CHECK_BOOL(p_cb->handler != NULL); p_cb->handler(event); break; - - case SPIS_XFER_COMPLETED: + + case SPIS_XFER_COMPLETED: event.evt_type = NRF_DRV_SPIS_XFER_DONE; event.rx_amount = nrf_spis_rx_amount_get(p_spis); - event.tx_amount = nrf_spis_tx_amount_get(p_spis); + event.tx_amount = nrf_spis_tx_amount_get(p_spis); + NRF_LOG_INFO("Transfer rx_len:%d.\r\n", event.rx_amount); + NRF_LOG_DEBUG("Rx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_cb->rx_buffer, event.rx_amount * sizeof(p_cb->rx_buffer)); APP_ERROR_CHECK_BOOL(p_cb->handler != NULL); p_cb->handler(event); break; - + default: - // No implementation required. + // No implementation required. break; } } @@ -252,69 +338,71 @@ ret_code_t nrf_drv_spis_buffers_set(nrf_drv_spis_t const * const p_instance, spis_cb_t * p_cb = &m_cb[p_instance->instance_id]; uint32_t err_code; - if ((p_tx_buffer == NULL) || (p_rx_buffer == NULL)) - { - return NRF_ERROR_NULL; - } - + VERIFY_PARAM_NOT_NULL(p_rx_buffer); + VERIFY_PARAM_NOT_NULL(p_tx_buffer); + // EasyDMA requires that transfer buffers are placed in Data RAM region; // signal error if they are not. if ((p_tx_buffer != NULL && !nrf_drv_is_in_RAM(p_tx_buffer)) || (p_rx_buffer != NULL && !nrf_drv_is_in_RAM(p_rx_buffer))) { - return NRF_ERROR_INVALID_ADDR; + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } - + switch (p_cb->spi_state) { case SPIS_STATE_INIT: case SPIS_XFER_COMPLETED: - case SPIS_BUFFER_RESOURCE_CONFIGURED: + case SPIS_BUFFER_RESOURCE_CONFIGURED: p_cb->tx_buffer = p_tx_buffer; p_cb->rx_buffer = p_rx_buffer; p_cb->tx_buffer_size = tx_buffer_length; - p_cb->rx_buffer_size = rx_buffer_length; - err_code = NRF_SUCCESS; - - spis_state_change(p_instance->p_reg, p_cb, SPIS_BUFFER_RESOURCE_REQUESTED); + p_cb->rx_buffer_size = rx_buffer_length; + err_code = NRF_SUCCESS; + + spis_state_change(p_instance->p_reg, p_cb, SPIS_BUFFER_RESOURCE_REQUESTED); break; case SPIS_BUFFER_RESOURCE_REQUESTED: - err_code = NRF_ERROR_INVALID_STATE; + err_code = NRF_ERROR_INVALID_STATE; break; - + default: // @note: execution of this code path would imply internal error in the design. - err_code = NRF_ERROR_INTERNAL; + err_code = NRF_ERROR_INTERNAL; break; } - + + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); return err_code; } static void spis_irq_handler(NRF_SPIS_Type * p_spis, spis_cb_t * p_cb) { - // @note: as multiple events can be pending for processing, the correct event processing order + // @note: as multiple events can be pending for processing, the correct event processing order // is as follows: // - SPI semaphore acquired event. // - SPI transaction complete event. - + // Check for SPI semaphore acquired event. if (nrf_spis_event_check(p_spis, NRF_SPIS_EVENT_ACQUIRED)) { nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_ACQUIRED); - + NRF_LOG_DEBUG("SPIS: Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SPIS_EVENT_ACQUIRED)); + switch (p_cb->spi_state) - { - case SPIS_BUFFER_RESOURCE_REQUESTED: + { + case SPIS_BUFFER_RESOURCE_REQUESTED: nrf_spis_tx_buffer_set(p_spis, (uint8_t *)p_cb->tx_buffer, p_cb->tx_buffer_size); nrf_spis_rx_buffer_set(p_spis, (uint8_t *)p_cb->rx_buffer, p_cb->rx_buffer_size); - + nrf_spis_task_trigger(p_spis, NRF_SPIS_TASK_RELEASE); - - spis_state_change(p_spis, p_cb, SPIS_BUFFER_RESOURCE_CONFIGURED); + + spis_state_change(p_spis, p_cb, SPIS_BUFFER_RESOURCE_CONFIGURED); break; - + default: // No implementation required. break; @@ -325,30 +413,32 @@ static void spis_irq_handler(NRF_SPIS_Type * p_spis, spis_cb_t * p_cb) if (nrf_spis_event_check(p_spis, NRF_SPIS_EVENT_END)) { nrf_spis_event_clear(p_spis, NRF_SPIS_EVENT_END); - + NRF_LOG_DEBUG("SPIS: Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_SPIS_EVENT_END)); + switch (p_cb->spi_state) { - case SPIS_BUFFER_RESOURCE_CONFIGURED: + case SPIS_BUFFER_RESOURCE_CONFIGURED: spis_state_change(p_spis, p_cb, SPIS_XFER_COMPLETED); break; default: - // No implementation required. - break; - } + // No implementation required. + break; + } } } -#if (SPIS0_ENABLED == 1) +#if NRF_MODULE_ENABLED(SPIS0) SPIS_IRQHANDLER_TEMPLATE(0) #endif -#if (SPIS1_ENABLED == 1) +#if NRF_MODULE_ENABLED(SPIS1) SPIS_IRQHANDLER_TEMPLATE(1) #endif -#if (SPIS2_ENABLED == 1) +#if NRF_MODULE_ENABLED(SPIS2) SPIS_IRQHANDLER_TEMPLATE(2) #endif #endif // SPI_COUNT > 0 +#endif // NRF_MODULE_ENABLED(SPIS) diff --git a/components/drivers_nrf/spi_slave/nrf_drv_spis.h b/components/drivers_nrf/spi_slave/nrf_drv_spis.h index 41088d0..b79e595 100644 --- a/components/drivers_nrf/spi_slave/nrf_drv_spis.h +++ b/components/drivers_nrf/spi_slave/nrf_drv_spis.h @@ -1,28 +1,48 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * @addtogroup nrf_spis SPIS HAL and driver + * @ingroup nrf_drivers + * @brief SPIS APIs. * - * @defgroup nrf_spis SPI slave HAL and driver - * @ingroup nrf_spi - * @brief SPI slave API. - * @details The SPIS HAL provides basic APIs for accessing the registers - * of the SPIS. The SPIS driver provides APIs on a higher level. - * - * @defgroup lib_driver_spi_slave Software controlled SPI slave driver - * @{ - * @ingroup nrf_spis - * - * @brief Driver for the software controlled SPI slave. */ #ifndef SPI_SLAVE_H__ @@ -31,38 +51,44 @@ #include #include "nrf.h" #include "nrf_error.h" -#include "nrf_drv_config.h" +#include "sdk_config.h" #include "nrf_spis.h" #include "nrf_gpio.h" #include "sdk_common.h" #include "app_util_platform.h" +#include "nrf_peripherals.h" -/** - * @brief This value can be provided instead of a pin number for the signals MOSI - * and MISO to specify that the given signal is not used and therefore - * does not need to be connected to a pin. - */ -#define NRF_DRV_SPIS_PIN_NOT_USED 0xFF +#ifdef __cplusplus +extern "C" { +#endif -#define NRF_DRV_SPIS_DEFAULT_CSN_PULLUP NRF_GPIO_PIN_NOPULL /**< Default pull-up configuration of the SPI CS. */ -#define NRF_DRV_SPIS_DEFAULT_MISO_DRIVE NRF_GPIO_PIN_S0S1 /**< Default drive configuration of the SPI MISO. */ -#define NRF_DRV_SPIS_DEFAULT_DEF 0xFF /**< Default DEF character. */ -#define NRF_DRV_SPIS_DEFAULT_ORC 0xFF /**< Default ORC character. */ -#if defined(NRF52) - #define SPIS2_IRQ SPIM2_SPIS2_SPI2_IRQn - #define SPIS2_IRQ_HANDLER SPIM2_SPIS2_SPI2_IRQHandler - #define SPIS0_IRQ SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQn - #define SPIS0_IRQ_HANDLER SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler - #define SPIS1_IRQ SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQn - #define SPIS1_IRQ_HANDLER SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler -#else #define SPIS0_IRQ SPI0_TWI0_IRQn #define SPIS0_IRQ_HANDLER SPI0_TWI0_IRQHandler #define SPIS1_IRQ SPI1_TWI1_IRQn #define SPIS1_IRQ_HANDLER SPI1_TWI1_IRQHandler + +#if SPIS_COUNT > 2 + #define SPIS2_IRQ SPIM2_SPIS2_SPI2_IRQn + #define SPIS2_IRQ_HANDLER SPIM2_SPIS2_SPI2_IRQHandler #endif +/** + * @defgroup nrf_drv_spis SPI slave driver + * @{ + * @ingroup nrf_spis + * @brief Multi-instance SPI slave driver. + */ + +#define NRF_DRV_SPIS_DEFAULT_CSN_PULLUP NRF_GPIO_PIN_NOPULL /**< Default pull-up configuration of the SPI CS. */ +#define NRF_DRV_SPIS_DEFAULT_MISO_DRIVE NRF_GPIO_PIN_S0S1 /**< Default drive configuration of the SPI MISO. */ + +/** +* @brief This value can be provided instead of a pin number for the signals MOSI +* and MISO to specify that the given signal is not used and therefore +* does not need to be connected to a pin. +*/ +#define NRF_DRV_SPIS_PIN_NOT_USED 0xFF /** @brief SPIS transaction bit order definitions. */ typedef enum @@ -84,8 +110,8 @@ typedef enum typedef enum { NRF_DRV_SPIS_BUFFERS_SET_DONE, /**< Memory buffer set event. Memory buffers have been set successfully to the SPI slave device, and SPI transactions can be done. */ - NRF_DRV_SPIS_XFER_DONE, /**< SPI transaction event. SPI transaction has been completed. */ - NRF_DRV_SPIS_EVT_TYPE_MAX /**< Enumeration upper bound. */ + NRF_DRV_SPIS_XFER_DONE, /**< SPI transaction event. SPI transaction has been completed. */ + NRF_DRV_SPIS_EVT_TYPE_MAX /**< Enumeration upper bound. */ } nrf_drv_spis_event_type_t; /** @brief Structure containing the event context from the SPI slave driver. */ @@ -104,6 +130,10 @@ typedef struct IRQn_Type irq; //!< IRQ of the specific instance. } nrf_drv_spis_t; +#define SPIS0_INSTANCE_INDEX 0 +#define SPIS1_INSTANCE_INDEX SPIS0_INSTANCE_INDEX+SPIS0_ENABLED +#define SPIS2_INSTANCE_INDEX SPIS1_INSTANCE_INDEX+SPIS1_ENABLED + /** @brief Macro for creating an SPI slave driver instance. */ #define NRF_DRV_SPIS_INSTANCE(id) \ { \ @@ -113,23 +143,23 @@ typedef struct } /** @brief SPI slave instance default configuration. */ -#define NRF_DRV_SPIS_DEFAULT_CONFIG(id) \ -{ \ - .sck_pin = CONCAT_3(SPIS, id, _CONFIG_SCK_PIN), \ - .mosi_pin = CONCAT_3(SPIS, id, _CONFIG_MOSI_PIN), \ - .miso_pin = CONCAT_3(SPIS, id, _CONFIG_MISO_PIN), \ - .csn_pin = NRF_DRV_SPIS_PIN_NOT_USED, \ - .miso_drive = NRF_DRV_SPIS_DEFAULT_MISO_DRIVE, \ - .csn_pullup = NRF_DRV_SPIS_DEFAULT_CSN_PULLUP, \ - .orc = NRF_DRV_SPIS_DEFAULT_ORC, \ - .def = NRF_DRV_SPIS_DEFAULT_DEF, \ - .mode = NRF_DRV_SPIS_MODE_0, \ - .bit_order = NRF_DRV_SPIS_BIT_ORDER_MSB_FIRST, \ - .irq_priority = CONCAT_3(SPIS, id, _CONFIG_IRQ_PRIORITY), \ +#define NRF_DRV_SPIS_DEFAULT_CONFIG \ +{ \ + .sck_pin = NRF_DRV_SPIS_PIN_NOT_USED, \ + .mosi_pin = NRF_DRV_SPIS_PIN_NOT_USED, \ + .miso_pin = NRF_DRV_SPIS_PIN_NOT_USED, \ + .csn_pin = NRF_DRV_SPIS_PIN_NOT_USED, \ + .miso_drive = NRF_DRV_SPIS_DEFAULT_MISO_DRIVE, \ + .csn_pullup = NRF_DRV_SPIS_DEFAULT_CSN_PULLUP, \ + .orc = SPIS_DEFAULT_ORC, \ + .def = SPIS_DEFAULT_DEF, \ + .mode = (nrf_drv_spis_mode_t)SPIS_DEFAULT_MODE, \ + .bit_order = (nrf_drv_spis_endian_t)SPIS_DEFAULT_BIT_ORDER, \ + .irq_priority = SPIS_DEFAULT_CONFIG_IRQ_PRIORITY, \ } /** @brief SPI peripheral device configuration data. */ -typedef struct +typedef struct { uint32_t miso_pin; //!< SPI MISO pin (optional). /**< Set @ref NRF_DRV_SPIS_PIN_NOT_USED @@ -151,19 +181,23 @@ typedef struct /** @brief SPI slave event callback function type. * - * @param[in] event SPI slave driver event. + * @param[in] event SPI slave driver event. */ typedef void (*nrf_drv_spis_event_handler_t)(nrf_drv_spis_event_t event); /** @brief Function for initializing the SPI slave driver instance. * - * @param[in] p_instance Pointer to the instance structure. - * @param[in] p_config Pointer to the structure with the initial configuration. - * If NULL, the default configuration will be used. - * @param[in] event_handler Function to be called by the SPI slave driver upon event. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Pointer to the structure with the initial configuration. + * If NULL, the default configuration will be used. + * @param[in] event_handler Function to be called by the SPI slave driver upon event. * - * @retval NRF_SUCCESS If the initialization was successful. - * @retval NRF_ERROR_INVALID_PARAM If an invalid parameter is supplied. + * @retval NRF_SUCCESS If the initialization was successful. + * @retval NRF_ERROR_INVALID_PARAM If an invalid parameter is supplied. + * @retval NRF_ERROR_BUSY If some other peripheral with the same + * instance ID is already in use. This is + * possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED + * is set to a value other than zero. */ ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance, nrf_drv_spis_config_t const * p_config, @@ -172,48 +206,53 @@ ret_code_t nrf_drv_spis_init(nrf_drv_spis_t const * const p_instance, /** * @brief Function for uninitializing the SPI slave driver instance. * - * @param[in] p_instance Pointer to the instance structure. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_spis_uninit(nrf_drv_spis_t const * const p_instance); - + /** @brief Function for preparing the SPI slave instance for a single SPI transaction. - * - * This function prepares the SPI slave device to be ready for a single SPI transaction. It configures - * the SPI slave device to use the memory supplied with the function call in SPI transactions. - * - * When either the memory buffer configuration or the SPI transaction has been - * completed, the event callback function will be called with the appropriate event - * @ref nrf_drv_spis_event_type_t. Note that the callback function can be called before returning from + * + * This function prepares the SPI slave device to be ready for a single SPI transaction. It configures + * the SPI slave device to use the memory supplied with the function call in SPI transactions. + * + * When either the memory buffer configuration or the SPI transaction has been + * completed, the event callback function will be called with the appropriate event + * @ref nrf_drv_spis_event_type_t. Note that the callback function can be called before returning from * this function, because it is called from the SPI slave interrupt context. * * @note This function can be called from the callback function context. * - * @note Client applications must call this function after every @ref NRF_DRV_SPIS_XFER_DONE event if - * the SPI slave driver should be prepared for a possible new SPI transaction. + * @note Client applications must call this function after every @ref NRF_DRV_SPIS_XFER_DONE event if + * the SPI slave driver should be prepared for a possible new SPI transaction. * * @note Peripherals that are using EasyDMA (for example, SPIS) require the transfer buffers - * to be placed in the data RAM region. Otherwise, this function will fail + * to be placed in the Data RAM region. Otherwise, this function will fail * with the error code NRF_ERROR_INVALID_ADDR. * - * @param[in] p_instance SPIS instance. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] p_tx_buffer Pointer to the TX buffer. * @param[in] p_rx_buffer Pointer to the RX buffer. * @param[in] tx_buffer_length Length of the TX buffer in bytes. - * @param[in] rx_buffer_length Length of the RX buffer in bytes. + * @param[in] rx_buffer_length Length of the RX buffer in bytes. * * @retval NRF_SUCCESS If the operation was successful. - * @retval NRF_ERROR_NULL If the operation failed because a NULL pointer was supplied. + * @retval NRF_ERROR_NULL If the operation failed because a NULL pointer was supplied. * @retval NRF_ERROR_INVALID_STATE If the operation failed because the SPI slave device is in an incorrect state. - * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the data + * @retval NRF_ERROR_INVALID_ADDR If the provided buffers are not placed in the Data * RAM region. * @retval NRF_ERROR_INTERNAL If the operation failed because of an internal error. */ ret_code_t nrf_drv_spis_buffers_set(nrf_drv_spis_t const * const p_instance, - const uint8_t * p_tx_buffer, - uint8_t tx_buffer_length, - uint8_t * p_rx_buffer, + const uint8_t * p_tx_buffer, + uint8_t tx_buffer_length, + uint8_t * p_rx_buffer, uint8_t rx_buffer_length); + +#ifdef __cplusplus +} +#endif + #endif // SPI_SLAVE_H__ /** @} */ diff --git a/components/drivers_nrf/swi/nrf_drv_swi.c b/components/drivers_nrf/swi/nrf_drv_swi.c index 687ed7c..0dbac0a 100644 --- a/components/drivers_nrf/swi/nrf_drv_swi.c +++ b/components/drivers_nrf/swi/nrf_drv_swi.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "nrf_drv_common.h" @@ -19,9 +47,22 @@ #include "nrf_drv_swi.h" #include "app_util_platform.h" +#define NRF_LOG_MODULE_NAME "SWI" + +#if EGU_ENABLED +#if SWI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL SWI_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR SWI_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR SWI_CONFIG_DEBUG_COLOR +#else //SWI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //SWI_CONFIG_LOG_ENABLED +#endif //EGU_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + STATIC_ASSERT(SWI_COUNT > 0); STATIC_ASSERT(SWI_COUNT <= SWI_MAX); -STATIC_ASSERT(SWI_MAX_FLAGS <= sizeof(nrf_swi_flags_t) * 8); #ifdef SWI_DISABLE0 #undef SWI_DISABLE0 @@ -111,8 +152,45 @@ static nrf_swi_handler_t m_swi_handlers[SWI_ARRAY_SIZE]; static nrf_swi_flags_t m_swi_flags[SWI_ARRAY_SIZE]; #endif +/**@brief Function for getting max channel number of given SWI. + * + * @param[in] swi SWI number. + * @return number of available channels. + */ +#if NRF_MODULE_ENABLED(EGU) +__STATIC_INLINE uint32_t swi_channel_number(nrf_swi_t swi) +{ + uint32_t retval = 0; + switch(swi){ + case 0: + retval = EGU0_CH_NUM; + break; + case 1: + retval = EGU1_CH_NUM; + break; + case 2: + retval = EGU2_CH_NUM; + break; + case 3: + retval = EGU3_CH_NUM; + break; + case 4: + retval = EGU4_CH_NUM; + break; + case 5: + retval = EGU5_CH_NUM; + break; + default: + retval = 0; + } + + return retval; +} +#else +#define swi_channel_number(swi) SWI_MAX_FLAGS +#endif -#if EGU_ENABLED > 0 +#if NRF_MODULE_ENABLED(EGU) /**@brief Get the specific EGU instance. */ __STATIC_INLINE NRF_EGU_Type * egu_instance_get(nrf_swi_t swi) @@ -126,17 +204,17 @@ static void nrf_drv_swi_process(nrf_swi_t swi) ASSERT(m_swi_handlers[swi - SWI_START_NUMBER]); nrf_swi_flags_t flags = 0; NRF_EGU_Type * NRF_EGUx = egu_instance_get(swi); - - for (uint8_t i = 0; i < NRF_EGU_CHANNEL_COUNT; ++i) + + for (uint8_t i = 0; i < swi_channel_number(swi); ++i) { - nrf_egu_event_t egu_event = nrf_egu_event_triggered_get(i); + nrf_egu_event_t egu_event = nrf_egu_event_triggered_get(NRF_EGUx, i); if (nrf_egu_event_check(NRF_EGUx, egu_event)) { flags |= (1u << i); nrf_egu_event_clear(NRF_EGUx, egu_event); } } - + m_swi_handlers[swi - SWI_START_NUMBER](swi, flags); } @@ -225,15 +303,20 @@ __STATIC_INLINE bool swi_is_allocated(nrf_swi_t swi) return m_swi_handlers[swi - SWI_START_NUMBER]; } - ret_code_t nrf_drv_swi_init(void) { + ret_code_t err_code; + if (m_drv_state == NRF_DRV_STATE_UNINITIALIZED) { m_drv_state = NRF_DRV_STATE_INITIALIZED; - return NRF_SUCCESS; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } - return MODULE_ALREADY_INITIALIZED; + err_code = NRF_ERROR_MODULE_ALREADY_INITIALIZED; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } @@ -245,7 +328,7 @@ void nrf_drv_swi_uninit(void) { m_swi_handlers[i - SWI_START_NUMBER] = NULL; nrf_drv_common_irq_disable(nrf_drv_swi_irq_of((nrf_swi_t) i)); -#if EGU_ENABLED > 0 +#if NRF_MODULE_ENABLED(EGU) NRF_EGU_Type * NRF_EGUx = egu_instance_get(i); nrf_egu_int_disable(NRF_EGUx, NRF_EGU_INT_ALL); #endif @@ -277,7 +360,7 @@ ret_code_t nrf_drv_swi_alloc(nrf_swi_t * p_swi, nrf_swi_handler_t event_handler, m_swi_handlers[i - SWI_START_NUMBER] = event_handler; *p_swi = (nrf_swi_t) i; nrf_drv_common_irq_enable(nrf_drv_swi_irq_of(*p_swi), priority); -#if EGU_ENABLED > 0 +#if NRF_MODULE_ENABLED(EGU) NRF_EGU_Type * NRF_EGUx = egu_instance_get(i); nrf_egu_int_enable(NRF_EGUx, NRF_EGU_INT_ALL); #endif @@ -286,9 +369,11 @@ ret_code_t nrf_drv_swi_alloc(nrf_swi_t * p_swi, nrf_swi_handler_t event_handler, CRITICAL_REGION_EXIT(); if (err_code == NRF_SUCCESS) { + NRF_LOG_INFO("SWI channel allocated: %d.\r\n", (*p_swi)); break; } } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); return err_code; } @@ -296,19 +381,18 @@ ret_code_t nrf_drv_swi_alloc(nrf_swi_t * p_swi, nrf_swi_handler_t event_handler, void nrf_drv_swi_trigger(nrf_swi_t swi, uint8_t flag_number) { ASSERT(swi_is_allocated((uint32_t) swi)); -#if EGU_ENABLED > 0 - ASSERT(flag_number < NRF_EGU_CHANNEL_COUNT); + ASSERT(flag_number < swi_channel_number(swi)); +#if NRF_MODULE_ENABLED(EGU) NRF_EGU_Type * NRF_EGUx = egu_instance_get(swi); - nrf_egu_task_trigger(NRF_EGUx, nrf_egu_task_trigger_get(flag_number)); + nrf_egu_task_trigger(NRF_EGUx, nrf_egu_task_trigger_get(NRF_EGUx, flag_number)); #else - ASSERT(flag_number < SWI_MAX_FLAGS); m_swi_flags[swi - SWI_START_NUMBER] |= (1 << flag_number); NVIC_SetPendingIRQ(nrf_drv_swi_irq_of(swi)); #endif } -#if EGU_ENABLED > 0 +#if NRF_MODULE_ENABLED(EGU) uint32_t nrf_drv_swi_task_trigger_address_get(nrf_swi_t swi, uint8_t channel) { @@ -323,4 +407,3 @@ uint32_t nrf_drv_swi_event_triggered_address_get(nrf_swi_t swi, uint8_t channel) } #endif - diff --git a/components/drivers_nrf/swi/nrf_drv_swi.h b/components/drivers_nrf/swi/nrf_drv_swi.h index a83e8ff..400bcc1 100644 --- a/components/drivers_nrf/swi/nrf_drv_swi.h +++ b/components/drivers_nrf/swi/nrf_drv_swi.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup lib_driver_swi SWI driver + * @defgroup nrf_drv_swi SWI driver * @{ * @ingroup nrf_drivers * @@ -27,17 +55,22 @@ #include #include "app_util.h" #include "app_util_platform.h" -#include "nrf_drv_config.h" +#include "sdk_common.h" #include "sdk_errors.h" +#include "nrf_peripherals.h" #ifndef EGU_ENABLED #define EGU_ENABLED 0 #endif -#if EGU_ENABLED > 0 +#if NRF_MODULE_ENABLED(EGU) #include "nrf_egu.h" #endif +#ifdef __cplusplus +extern "C" { +#endif + typedef uint8_t nrf_swi_t; ///< @brief SWI channel (unsigned integer). /** @brief SWI user flags (unsigned integer). @@ -56,27 +89,14 @@ typedef uint16_t nrf_swi_flags_t; typedef void (* nrf_swi_handler_t)(nrf_swi_t, nrf_swi_flags_t); /**@brief Maximum numbers of SWIs. This number is fixed for a specific chip. */ -#if EGU_ENABLED > 0 -#define SWI_MAX NRF_EGU_COUNT +#if NRF_MODULE_ENABLED(EGU) +#define SWI_MAX EGU_COUNT #else -#define SWI_MAX 6 -#endif - +#define SWI_MAX SWI_COUNT /**@brief Number of flags per SWI (fixed number). */ -#if EGU_ENABLED > 0 -#define SWI_MAX_FLAGS NRF_EGU_CHANNEL_COUNT -#else #define SWI_MAX_FLAGS 16 #endif -#ifndef SWI_COUNT -/** @brief Number of software interrupts available. - * - * This number can be set in the range from 1 to SWI_MAX. - */ -#define SWI_COUNT 4 -#endif - #ifdef SOFTDEVICE_PRESENT #if SWI_COUNT > 2 #undef SWI_COUNT @@ -93,13 +113,13 @@ typedef void (* nrf_swi_handler_t)(nrf_swi_t, nrf_swi_flags_t); #endif /**@brief Default SWI priority. */ -#define SWI_DEFAULT_PRIORITY APP_IRQ_PRIORITY_LOW +#define SWI_DEFAULT_PRIORITY APP_IRQ_PRIORITY_LOWEST /**@brief Function for initializing the SWI module. * - * @retval NRF_SUCCESS If the module was successfully initialized. - * @retval MODULE_ALREADY_INITIALIZED If the module has already been initialized. + * @retval NRF_SUCCESS If the module was successfully initialized. + * @retval NRF_ERROR_MODULE_ALREADY_INITIALIZED If the module has already been initialized. */ ret_code_t nrf_drv_swi_init(void); @@ -139,7 +159,8 @@ void nrf_drv_swi_free(nrf_swi_t * p_swi); void nrf_drv_swi_trigger(nrf_swi_t swi, uint8_t flag_number); -#if EGU_ENABLED > 0 +#if (EGU_ENABLED > 0) || defined(__SDK_DOXYGEN__) + /**@brief Function for returning the EGU trigger task address. * @@ -159,9 +180,14 @@ uint32_t nrf_drv_swi_task_trigger_address_get(nrf_swi_t swi, uint8_t channel); */ uint32_t nrf_drv_swi_event_triggered_address_get(nrf_swi_t swi, uint8_t channel); -#endif // EGU_ENABLED > 0 +#endif // NRF_MODULE_ENABLED(EGU) + +#ifdef __cplusplus +} +#endif + #endif // NRF_DRV_SWI_H__ /** @} */ diff --git a/components/drivers_nrf/systick/nrf_drv_systick.c b/components/drivers_nrf/systick/nrf_drv_systick.c new file mode 100644 index 0000000..d7fe5c1 --- /dev/null +++ b/components/drivers_nrf/systick/nrf_drv_systick.c @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SYSTICK) +#include "nrf_drv_systick.h" +#include "nrf_systick.h" +#include "nrf.h" +#include "nrf_assert.h" + +/** + * @brief Maximum number of ticks to delay + * + * The maximum number of ticks should be much lower than + * Physical maximum count of the SysTick timer. + * It is dictated by the fact that it would be impossible to detect delay + * properly when the timer value warps around the starting point. + */ +#define NRF_DRV_SYSTICK_TICKS_MAX (NRF_SYSTICK_VAL_MASK / 2UL) + +/** + * @brief Number of milliseconds in a second + */ +#define NRF_DRV_SYSTICK_MS (1000UL) + +/** + * @brief Number of microseconds in a second + */ +#define NRF_DRV_SYSTICK_US (1000UL * NRF_DRV_SYSTICK_MS) + +/** + * @brief Number of milliseconds to wait in single loop + * + * Constant used by @ref nrd_drv_systick_delay_ms function + * to split waiting into loops and rest. + * + * It describes the number of milliseconds to wait in single loop. + * + * See @ref nrf_drv_systick_delay_ms source code for details. + */ +#define NRF_DRV_SYSTICK_MS_STEP (64U) + +/** + * @brief Checks if the given time is in correct range + * + * Function tests given time is not to big for this library. + * Assertion is used for testing. + * + * @param us Time in microseconds to check + */ +#define NRF_DRV_SYSTICK_ASSERT_TIMEOUT(us) \ + ASSERT(us <= (NRF_DRV_SYSTICK_TICKS_MAX / ((SystemCoreClock) / NRF_DRV_SYSTICK_US))); + +/** + * @brief Function that converts microseconds to ticks + * + * Function converts from microseconds to CPU ticks. + * + * @param us Number of microseconds + * + * @return Number of ticks + * + * @sa nrf_drv_systick_ms_tick + */ +static inline uint32_t nrf_drv_systick_us_tick(uint32_t us) +{ + return us * ((SystemCoreClock) / NRF_DRV_SYSTICK_US); +} + +/** + * @brief Function that converts milliseconds to ticks + * + * Function converts from milliseconds to CPU ticks. + * + * @param us Number of milliseconds + * + * @return Number of ticks + * + * @sa nrf_drv_systick_us_tick + */ +static inline uint32_t nrf_drv_systick_ms_tick(uint32_t ms) +{ + return ms * ((SystemCoreClock) / NRF_DRV_SYSTICK_MS); +} + +void nrf_drv_systick_init(void) +{ + nrf_systick_load_set(NRF_SYSTICK_VAL_MASK); + nrf_systick_csr_set( + NRF_SYSTICK_CSR_CLKSOURCE_CPU | + NRF_SYSTICK_CSR_TICKINT_DISABLE | + NRF_SYSTICK_CSR_ENABLE); +} + +void nrf_drv_systick_get(nrf_drv_systick_state_t * p_state) +{ + p_state->time = nrf_systick_val_get(); +} + +bool nrf_drv_systick_test(nrf_drv_systick_state_t const * p_state, uint32_t us) +{ + NRF_DRV_SYSTICK_ASSERT_TIMEOUT(us); + + const uint32_t diff = NRF_SYSTICK_VAL_MASK & ((p_state->time) - nrf_systick_val_get()); + return (diff >= nrf_drv_systick_us_tick(us)); +} + +void nrf_drv_systick_delay_ticks(uint32_t ticks) +{ + ASSERT(ticks <= NRF_DRV_SYSTICK_TICKS_MAX) + + const uint32_t start = nrf_systick_val_get(); + while((NRF_SYSTICK_VAL_MASK & (start - nrf_systick_val_get())) < ticks) + { + /* Nothing to do */ + } +} + +void nrf_drv_systick_delay_us(uint32_t us) +{ + NRF_DRV_SYSTICK_ASSERT_TIMEOUT(us); + nrf_drv_systick_delay_ticks(nrf_drv_systick_us_tick(us)); +} + +void nrf_drv_systick_delay_ms(uint32_t ms) +{ + uint32_t n = ms / NRF_DRV_SYSTICK_MS_STEP; + uint32_t r = ms % NRF_DRV_SYSTICK_MS_STEP; + while(0 != (n--)) + { + nrf_drv_systick_delay_ticks(nrf_drv_systick_ms_tick(NRF_DRV_SYSTICK_MS_STEP)); + } + nrf_drv_systick_delay_ticks(nrf_drv_systick_ms_tick(r)); +} + +#endif // NRF_MODULE_ENABLED(SYSTICK) diff --git a/components/drivers_nrf/systick/nrf_drv_systick.h b/components/drivers_nrf/systick/nrf_drv_systick.h new file mode 100644 index 0000000..34492af --- /dev/null +++ b/components/drivers_nrf/systick/nrf_drv_systick.h @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_SYSTICK_H__ +#define NRF_DRV_SYSTICK_H__ +#include +#include + + +/** + * @addtogroup nrf_systick SysTick HAL and driver + * @ingroup nrf_drivers + * @brief System Timer (SysTick) APIs + * + * The SysTick HAL provides basic APIs for accessing the registers of the system timer (SysTick). + * The SysTick driver provides APIs on a higher level. + */ + +/** + * @defgroup nrf_drv_systick SysTick driver + * @{ + * @ingroup nrf_systick + * + * This library configures SysTick as a free-running timer. + * This timer is used to generate delays and pool for timeouts. + * Only relatively short timeouts are supported. + * The SysTick works on 64MHz and is 24-bits wide. + * It means that it overflows around 4 times per second and around 250 ms + * would be the highest supported time in the library. + * But it would be really hard to detect if overflow was generated without + * using interrupts. For safely we would limit the maximum delay range by half. + */ + +/** + * @brief The value type that holds the SysTick state + * + * This variable is used to count the requested timeout. + * @sa nrf_drv_systick_get + */ +typedef struct { + uint32_t time; //!< Registered time value +}nrf_drv_systick_state_t; + +/** + * @brief Configure and start the timer + * + * Function configures SysTick as a free-running timer without interrupt. + */ +void nrf_drv_systick_init(void); + +/** + * @brief Get current SysTick state + * + * Function gets current state of the SysTick timer. + * It can be used to check time-out by @ref nrf_drv_systick_test. + * + * @param[out] p_state The pointer to the state variable to be filled + */ +void nrf_drv_systick_get(nrf_drv_systick_state_t * p_state); + +/** + * @brief Test if specified time is up in relation to remembered state + * + * @param[in] p_state Remembered state set by @ref nrf_drv_systick_get + * @param[in] us Required time-out. + * + * @retval true If current time is higher than specified state plus given time-out. + * @retval false If current time is lower than specified state plus given time-out + */ +bool nrf_drv_systick_test(nrf_drv_systick_state_t const * p_state, uint32_t us); + +/** + * @brief Blocking delay in CPU ticks + * + * @param[in] ticks Number of CPU ticks to delay. + */ +void nrf_drv_systick_delay_ticks(uint32_t ticks); + +/** + * @brief Blocking delay in us + * + * @param[in] us Number of microseconds to delay. + */ +void nrf_drv_systick_delay_us(uint32_t us); + +/** + * @brief Blocking delay in ms + * + * This delay function removes the limits of the highest possible delay value. + * + * @param[in] ms Number of milliseconds to delay. + */ +void nrf_drv_systick_delay_ms(uint32_t ms); + + +/** @} */ +#endif /* NRF_DRV_SYSTICK_H__ */ diff --git a/components/drivers_nrf/timer/nrf_drv_timer.c b/components/drivers_nrf/timer/nrf_drv_timer.c index 888b1cd..a61b88c 100644 --- a/components/drivers_nrf/timer/nrf_drv_timer.c +++ b/components/drivers_nrf/timer/nrf_drv_timer.c @@ -1,116 +1,156 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(TIMER) +#define ENABLED_TIMER_COUNT (TIMER0_ENABLED+TIMER1_ENABLED+TIMER2_ENABLED+TIMER3_ENABLED+TIMER4_ENABLED) +#if ENABLED_TIMER_COUNT #include "nrf_drv_timer.h" -#include "nrf_assert.h" #include "nrf_drv_common.h" #include "app_util_platform.h" +#define NRF_LOG_MODULE_NAME "TIMER" + +#if TIMER_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL TIMER_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR TIMER_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR TIMER_CONFIG_DEBUG_COLOR +#else //TIMER_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //TIMER_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + /**@brief Timer control block. */ typedef struct { - nrf_drv_state_t state; -} nrf_drv_timer_cb_t; + nrf_timer_event_handler_t handler; + void * context; + nrf_drv_state_t state; +} timer_control_block_t; -/**@brief Array for storing timers event handlers. */ -static nrf_timer_event_handler_t m_timer_event_handlers[TIMER_COUNT]; -static nrf_drv_timer_cb_t m_cb[TIMER_COUNT]; -static void* mp_contexts[TIMER_COUNT]; - -static const nrf_drv_timer_config_t m_default_config[] = { -#if (TIMER0_ENABLED == 1) - NRF_DRV_TIMER_DEFAULT_CONFIG(0), -#endif -#if (TIMER1_ENABLED == 1) - NRF_DRV_TIMER_DEFAULT_CONFIG(1), -#endif -#if (TIMER2_ENABLED == 1) - NRF_DRV_TIMER_DEFAULT_CONFIG(2) -#endif -}; +static timer_control_block_t m_cb[ENABLED_TIMER_COUNT]; ret_code_t nrf_drv_timer_init(nrf_drv_timer_t const * const p_instance, nrf_drv_timer_config_t const * p_config, nrf_timer_event_handler_t timer_event_handler) { - ASSERT((p_instance->instance_id) < TIMER_INSTANCE_NUMBER); - ASSERT(TIMER_IS_BIT_WIDTH_VALID(p_instance->instance_id, p_config->bit_width)); - - if (m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED) - { - return NRF_ERROR_INVALID_STATE; // timer already initialized - } + timer_control_block_t * p_cb = &m_cb[p_instance->instance_id]; + ASSERT(((p_instance->p_reg == NRF_TIMER0) && TIMER0_ENABLED) || (p_instance->p_reg != NRF_TIMER0)); + ASSERT(((p_instance->p_reg == NRF_TIMER1) && TIMER1_ENABLED) || (p_instance->p_reg != NRF_TIMER1)); + ASSERT(((p_instance->p_reg == NRF_TIMER2) && TIMER2_ENABLED) || (p_instance->p_reg != NRF_TIMER2)); +#if TIMER_COUNT == 5 + ASSERT(((p_instance->p_reg == NRF_TIMER3) && TIMER3_ENABLED) || (p_instance->p_reg != NRF_TIMER3)); + ASSERT(((p_instance->p_reg == NRF_TIMER4) && TIMER4_ENABLED) || (p_instance->p_reg != NRF_TIMER4)); +#endif //TIMER_COUNT +#ifdef SOFTDEVICE_PRESENT + ASSERT(p_instance->p_reg != NRF_TIMER0); + ASSERT(p_config); +#endif + ret_code_t err_code; - if (p_config == NULL) + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) { - p_config = &m_default_config[p_instance->instance_id]; + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } -#ifdef SOFTDEVICE_PRESENT - if (p_instance->p_reg == NRF_TIMER0) - { - return NRF_ERROR_INVALID_PARAM; - } -#endif - - nrf_drv_common_irq_enable(p_instance->irq, p_config->interrupt_priority); - - mp_contexts[p_instance->instance_id] = p_config->p_context; - - if (timer_event_handler != NULL) + if (timer_event_handler == NULL) { - m_timer_event_handlers[p_instance->instance_id] = timer_event_handler; + err_code = NRF_ERROR_INVALID_PARAM; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } - else + + /* Warning 685: Relational operator '<=' always evaluates to 'true'" + * Warning in NRF_TIMER_IS_BIT_WIDTH_VALID macro. Macro validate timers resolution. + * Not necessary in nRF52 based systems. Obligatory in nRF51 based systems. + */ + + /*lint -save -e685 */ + + ASSERT(NRF_TIMER_IS_BIT_WIDTH_VALID(p_instance->p_reg, p_config->bit_width)); + + //lint -restore + + p_cb->handler = timer_event_handler; + p_cb->context = p_config->p_context; + + uint8_t i; + for (i = 0; i < p_instance->cc_channel_count; ++i) { - return NRF_ERROR_INVALID_PARAM; + nrf_timer_event_clear(p_instance->p_reg, + nrf_timer_compare_event_get(i)); } + nrf_drv_common_irq_enable(nrf_drv_get_IRQn(p_instance->p_reg), + p_config->interrupt_priority); + nrf_timer_mode_set(p_instance->p_reg, p_config->mode); nrf_timer_bit_width_set(p_instance->p_reg, p_config->bit_width); nrf_timer_frequency_set(p_instance->p_reg, p_config->frequency); - m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED; + p_cb->state = NRF_DRV_STATE_INITIALIZED; - return NRF_SUCCESS; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } void nrf_drv_timer_uninit(nrf_drv_timer_t const * const p_instance) { - uint32_t i; - - nrf_drv_common_irq_disable(p_instance->irq); - - m_timer_event_handlers[p_instance->instance_id] = NULL; - - nrf_drv_timer_disable(p_instance); - - //lint -save -e655 - nrf_timer_shorts_disable(p_instance->p_reg, NRF_TIMER_SHORT_COMPARE0_STOP_MASK | - NRF_TIMER_SHORT_COMPARE1_STOP_MASK | - NRF_TIMER_SHORT_COMPARE2_STOP_MASK | - NRF_TIMER_SHORT_COMPARE3_STOP_MASK | - NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK | - NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK | - NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK | - NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK); - //lint -restore - - for(i=0; ip_reg, NRF_TIMER_INT_COMPARE0_MASK << i); + nrf_drv_common_irq_disable(nrf_drv_get_IRQn(p_instance->p_reg)); + + #define DISABLE_ALL UINT32_MAX + nrf_timer_shorts_disable(p_instance->p_reg, DISABLE_ALL); + nrf_timer_int_disable(p_instance->p_reg, DISABLE_ALL); + #undef DISABLE_ALL + + if (m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON) + { + nrf_drv_timer_disable(p_instance); } - + m_cb[p_instance->instance_id].state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Uninitialized instance: %d.\r\n", p_instance->instance_id); } void nrf_drv_timer_enable(nrf_drv_timer_t const * const p_instance) @@ -118,6 +158,7 @@ void nrf_drv_timer_enable(nrf_drv_timer_t const * const p_instance) ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_INITIALIZED); nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_START); m_cb[p_instance->instance_id].state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled instance: %d.\r\n", p_instance->instance_id); } void nrf_drv_timer_disable(nrf_drv_timer_t const * const p_instance) @@ -125,18 +166,21 @@ void nrf_drv_timer_disable(nrf_drv_timer_t const * const p_instance) ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_SHUTDOWN); m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Disabled instance: %d.\r\n", p_instance->instance_id); } void nrf_drv_timer_resume(nrf_drv_timer_t const * const p_instance) { ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_START); + NRF_LOG_INFO("Resumed instance: %d.\r\n", p_instance->instance_id); } void nrf_drv_timer_pause(nrf_drv_timer_t const * const p_instance) { ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_STOP); + NRF_LOG_INFO("Paused instance: %d.\r\n", p_instance->instance_id); } void nrf_drv_timer_clear(nrf_drv_timer_t const * const p_instance) @@ -148,96 +192,32 @@ void nrf_drv_timer_clear(nrf_drv_timer_t const * const p_instance) void nrf_drv_timer_increment(nrf_drv_timer_t const * const p_instance) { ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); - ASSERT(nrf_timer_mode_get(p_instance->p_reg) == NRF_TIMER_MODE_COUNTER); - - nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_COUNT); -} + ASSERT(nrf_timer_mode_get(p_instance->p_reg) != NRF_TIMER_MODE_TIMER); -uint32_t nrf_drv_timer_task_address_get(nrf_drv_timer_t const * const p_instance, - nrf_timer_task_t timer_task) -{ - return (uint32_t)nrf_timer_task_address_get(p_instance->p_reg, timer_task); -} - -uint32_t nrf_drv_timer_event_address_get(nrf_drv_timer_t const * const p_instance, - nrf_timer_event_t timer_event) -{ - return (uint32_t)nrf_timer_event_address_get(p_instance->p_reg, timer_event); -} - -/** - * @brief Function for getting the specific timer capture task. - * - * @param[in] channel Capture channel number. - * - * @retval Capture task. - */ -__STATIC_INLINE nrf_timer_task_t nrf_drv_timer_capture_task_get(uint32_t channel) -{ - /* nrf_timer_tasks_t stores offset value and distance between two tasks equals to sizeof(uint32_t) = 4 */ - return (nrf_timer_task_t)((uint32_t) NRF_TIMER_TASK_CAPTURE0 + (channel * sizeof(uint32_t))); -} - -/** - * @brief Function for getting the specific timer compare event. - * - * @param[in] channel Compare channel number. - * - * @retval Compare event. - */ -__STATIC_INLINE nrf_timer_event_t nrf_drv_timer_compare_event_get(uint32_t channel) -{ - return (nrf_timer_event_t)((uint32_t) NRF_TIMER_EVENT_COMPARE0 + (channel * sizeof(uint32_t))); -} - -uint32_t nrf_drv_timer_capture_task_address_get(nrf_drv_timer_t const * const p_instance, - uint32_t channel) -{ - ASSERT(channel < TIMER_CHANNEL_NUMBER); - return (uint32_t)nrf_timer_task_address_get(p_instance->p_reg, - nrf_drv_timer_capture_task_get(channel)); -} - -uint32_t nrf_drv_timer_compare_event_address_get(nrf_drv_timer_t const * const p_instance, - uint32_t channel) -{ - ASSERT(channel < TIMER_CHANNEL_NUMBER); - return (uint32_t)nrf_timer_event_address_get(p_instance->p_reg, - nrf_drv_timer_compare_event_get(channel) ); + nrf_timer_task_trigger(p_instance->p_reg, NRF_TIMER_TASK_COUNT); } uint32_t nrf_drv_timer_capture(nrf_drv_timer_t const * const p_instance, - nrf_timer_cc_channel_t cc_channel) + nrf_timer_cc_channel_t cc_channel) { ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); - ASSERT(cc_channel < TIMER_CHANNEL_NUMBER); - - /*lint -save -e644*/ - nrf_timer_task_trigger(p_instance->p_reg, nrf_drv_timer_capture_task_get(cc_channel)); - /*lint -restore*/ - return nrf_timer_cc_read(p_instance->p_reg, cc_channel); -} + ASSERT(cc_channel < p_instance->cc_channel_count); -uint32_t nrf_drv_timer_capture_get(nrf_drv_timer_t const * const p_instance, - nrf_timer_cc_channel_t cc_channel) -{ + nrf_timer_task_trigger(p_instance->p_reg, + nrf_timer_capture_task_get(cc_channel)); return nrf_timer_cc_read(p_instance->p_reg, cc_channel); } void nrf_drv_timer_compare(nrf_drv_timer_t const * const p_instance, - nrf_timer_cc_channel_t cc_channel, - uint32_t cc_value, - bool enable) + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value, + bool enable_int) { - nrf_timer_int_mask_t timer_int; + nrf_timer_int_mask_t timer_int = nrf_timer_compare_int_get(cc_channel); - timer_int = (nrf_timer_int_mask_t)((uint32_t)NRF_TIMER_INT_COMPARE0_MASK << cc_channel); - - if (enable == true) + if (enable_int) { - /*lint -save -e644*/ nrf_timer_int_enable(p_instance->p_reg, timer_int); - /*lint -restore*/ } else { @@ -245,117 +225,108 @@ void nrf_drv_timer_compare(nrf_drv_timer_t const * const p_instance, } nrf_timer_cc_write(p_instance->p_reg, cc_channel, cc_value); + NRF_LOG_INFO("Timer id: %d, capture value set: %d, channel: %d.\r\n", p_instance->instance_id, cc_value, cc_channel); } void nrf_drv_timer_extended_compare(nrf_drv_timer_t const * const p_instance, - nrf_timer_cc_channel_t cc_channel, - uint32_t cc_value, - nrf_timer_short_mask_t timer_short_mask, - bool enable) + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value, + nrf_timer_short_mask_t timer_short_mask, + bool enable_int) { - nrf_timer_shorts_disable(p_instance->p_reg, TIMER_CC_SHORT(cc_channel)); + nrf_timer_shorts_disable(p_instance->p_reg, + (TIMER_SHORTS_COMPARE0_STOP_Msk << cc_channel) | + (TIMER_SHORTS_COMPARE0_CLEAR_Msk << cc_channel)); + nrf_timer_shorts_enable(p_instance->p_reg, timer_short_mask); (void)nrf_drv_timer_compare(p_instance, cc_channel, cc_value, - enable); -} - -uint32_t nrf_drv_timer_us_to_ticks(nrf_drv_timer_t const * const p_instance, - uint32_t time_us) -{ - uint32_t multiplier = 512UL; //must be divisible by 2^(PRESCALER_MAX) - uint32_t prescaler_value = nrf_timer_frequency_get(p_instance->p_reg); - ASSERT(prescaler_value <= 9); //maximum prescaler value - ASSERT((UINT32_MAX / (multiplier >> prescaler_value)) > time_us); - return (((multiplier >> prescaler_value) * time_us) / 32UL); //32 -> multiplier divided by clock freq. in MHz -} - - -uint32_t nrf_drv_timer_ms_to_ticks(nrf_drv_timer_t const * const p_instance, - uint32_t time_ms) -{ - uint32_t multiplier = 64000UL; //must be divisible by 2^(PRESCALER_MAX) - uint32_t prescaler_value = nrf_timer_frequency_get(p_instance->p_reg); - ASSERT(prescaler_value <= 9); //maximum prescaler value - ASSERT((UINT32_MAX / (multiplier >> prescaler_value)) > time_ms); - return (((multiplier >> prescaler_value) * time_ms) / 4UL); //4 -> multiplier divided by clock freq. in kHz + enable_int); + NRF_LOG_INFO("Timer id: %d, capture value set: %d, channel: %d.\r\n", p_instance->instance_id, cc_value, cc_channel); } void nrf_drv_timer_compare_int_enable(nrf_drv_timer_t const * const p_instance, uint32_t channel) { ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); - ASSERT(channel < TIMER_CHANNEL_NUMBER); - nrf_timer_event_clear(p_instance->p_reg, nrf_drv_timer_compare_event_get(channel)); - nrf_timer_int_enable(p_instance->p_reg, (uint32_t) NRF_TIMER_INT_COMPARE0_MASK << channel); + ASSERT(channel < p_instance->cc_channel_count); + + nrf_timer_event_clear(p_instance->p_reg, + nrf_timer_compare_event_get(channel)); + nrf_timer_int_enable(p_instance->p_reg, + nrf_timer_compare_int_get(channel)); } void nrf_drv_timer_compare_int_disable(nrf_drv_timer_t const * const p_instance, uint32_t channel) { ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); - ASSERT(channel < TIMER_CHANNEL_NUMBER); - nrf_timer_int_disable(p_instance->p_reg, (uint32_t) NRF_TIMER_INT_COMPARE0_MASK << channel); + ASSERT(channel < p_instance->cc_channel_count); + + nrf_timer_int_disable(p_instance->p_reg, + nrf_timer_compare_int_get(channel)); } -/** - * @brief This function is generic interrupt handler - * - * @param[in] p_reg pointer to timer registers - * @param[in] timer_id specifies the timer id - * - * @return NRF_SUCCESS on success, otherwise an error code. - */ -static void nrf_drv_timer_interrupt_handle(NRF_TIMER_Type * p_reg, uint32_t timer_id) +static void irq_handler(NRF_TIMER_Type * p_reg, + timer_control_block_t * p_cb, + uint8_t channel_count) { - uint32_t i; - - for(i=0; ihandler(event, p_cb->context); } } } -#if TIMER0_ENABLED == 1 +#if NRF_MODULE_ENABLED(TIMER0) void TIMER0_IRQHandler(void) { - nrf_drv_timer_interrupt_handle(NRF_TIMER0, TIMER0_INSTANCE_INDEX); + irq_handler(NRF_TIMER0, &m_cb[TIMER0_INSTANCE_INDEX], + NRF_TIMER_CC_CHANNEL_COUNT(0)); } #endif -#if TIMER1_ENABLED == 1 +#if NRF_MODULE_ENABLED(TIMER1) void TIMER1_IRQHandler(void) { - nrf_drv_timer_interrupt_handle(NRF_TIMER1, TIMER1_INSTANCE_INDEX); + irq_handler(NRF_TIMER1, &m_cb[TIMER1_INSTANCE_INDEX], + NRF_TIMER_CC_CHANNEL_COUNT(1)); } #endif -#if TIMER2_ENABLED == 1 +#if NRF_MODULE_ENABLED(TIMER2) void TIMER2_IRQHandler(void) { - nrf_drv_timer_interrupt_handle(NRF_TIMER2, TIMER2_INSTANCE_INDEX); + irq_handler(NRF_TIMER2, &m_cb[TIMER2_INSTANCE_INDEX], + NRF_TIMER_CC_CHANNEL_COUNT(2)); } #endif -#if TIMER3_ENABLED == 1 +#if NRF_MODULE_ENABLED(TIMER3) void TIMER3_IRQHandler(void) { - nrf_drv_timer_interrupt_handle(NRF_TIMER3, TIMER3_INSTANCE_INDEX); + irq_handler(NRF_TIMER3, &m_cb[TIMER3_INSTANCE_INDEX], + NRF_TIMER_CC_CHANNEL_COUNT(3)); } #endif -#if TIMER4_ENABLED == 1 +#if NRF_MODULE_ENABLED(TIMER4) void TIMER4_IRQHandler(void) { - nrf_drv_timer_interrupt_handle(NRF_TIMER4, TIMER4_INSTANCE_INDEX); + irq_handler(NRF_TIMER4, &m_cb[TIMER4_INSTANCE_INDEX], + NRF_TIMER_CC_CHANNEL_COUNT(4)); } #endif +#endif // ENABLED_TIMER_COUNT +#endif // NRF_MODULE_ENABLED(TIMER) diff --git a/components/drivers_nrf/timer/nrf_drv_timer.h b/components/drivers_nrf/timer/nrf_drv_timer.h index 7c80fa0..0e08f71 100644 --- a/components/drivers_nrf/timer/nrf_drv_timer.h +++ b/components/drivers_nrf/timer/nrf_drv_timer.h @@ -1,281 +1,334 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @addtogroup nrf_timer Timer HAL and driver - * @ingroup nrf_drivers - * @brief Timer APIs. - * @details The timer HAL provides basic APIs for accessing the registers of the timer. - * The timer driver provides APIs on a higher level. + * @ingroup nrf_drivers + * @brief Timer APIs. + * @details The timer HAL provides basic APIs for accessing the registers + * of the timer. The timer driver provides APIs on a higher level. * - * @defgroup lib_driver_timer Timer driver + * @defgroup nrf_drv_timer Timer driver * @{ - * @ingroup nrf_timer - * - * @brief Multi-instance timer driver. + * @ingroup nrf_timer + * @brief Multi-instance timer driver. */ #ifndef NRF_DRV_TIMER_H__ #define NRF_DRV_TIMER_H__ #include "nordic_common.h" -#include "nrf_drv_config.h" +#include "sdk_config.h" #include "nrf_timer.h" #include "sdk_errors.h" +#include "nrf_assert.h" -/**@brief Struct for TIMER instance. */ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Timer driver instance data structure. + */ typedef struct { - NRF_TIMER_Type * p_reg; /**< Pointer to timer instance registers struct. */ - IRQn_Type irq; /**< Instance IRQ id. */ - uint8_t instance_id; /**< Instance ID. */ + NRF_TIMER_Type * p_reg; ///< Pointer to the structure with TIMER peripheral instance registers. + uint8_t instance_id; ///< Driver instance index. + uint8_t cc_channel_count; ///< Number of capture/compare channels. } nrf_drv_timer_t; -#define NRF_DRV_TIMER_INSTANCE(id) \ - { \ - .p_reg = CONCAT_2(NRF_TIMER, id), \ - .irq = CONCAT_3(TIMER, id, _IRQn), \ - .instance_id = CONCAT_3(TIMER, id, _INSTANCE_INDEX), \ - } +#define ENABLED_TIMER_COUNT (TIMER0_ENABLED+TIMER1_ENABLED+TIMER2_ENABLED+TIMER3_ENABLED+TIMER4_ENABLED) + +#define TIMER0_INSTANCE_INDEX 0 +#define TIMER1_INSTANCE_INDEX TIMER0_INSTANCE_INDEX+TIMER0_ENABLED +#define TIMER2_INSTANCE_INDEX TIMER1_INSTANCE_INDEX+TIMER1_ENABLED +#define TIMER3_INSTANCE_INDEX TIMER2_INSTANCE_INDEX+TIMER2_ENABLED +#define TIMER4_INSTANCE_INDEX TIMER3_INSTANCE_INDEX+TIMER3_ENABLED -/**@brief Struct for TIMER instance configuration. */ +/** + * @brief Macro for creating a timer driver instance. + */ +#define NRF_DRV_TIMER_INSTANCE(id) \ +{ \ + .p_reg = CONCAT_2(NRF_TIMER, id), \ + .instance_id = CONCAT_3(TIMER, id, _INSTANCE_INDEX), \ + .cc_channel_count = NRF_TIMER_CC_CHANNEL_COUNT(id), \ +} + +/** + * @brief Timer driver instance configuration structure. + */ typedef struct { - nrf_timer_frequency_t frequency; /**< Frequency. */ - nrf_timer_mode_t mode; /**< Mode of operation. */ - nrf_timer_bit_width_t bit_width; /**< Bit width. */ - uint8_t interrupt_priority; /**< TIMER interrupt priority */ - void* p_context; /**< Context passed to interrupt handler */ + nrf_timer_frequency_t frequency; ///< Frequency. + nrf_timer_mode_t mode; ///< Mode of operation. + nrf_timer_bit_width_t bit_width; ///< Bit width. + uint8_t interrupt_priority; ///< Interrupt priority. + void * p_context; ///< Context passed to interrupt handler. } nrf_drv_timer_config_t; -#define TIMER_CONFIG_FREQUENCY(id) CONCAT_3(TIMER, id, _CONFIG_FREQUENCY) -#define TIMER_CONFIG_MODE(id) CONCAT_3(TIMER, id, _CONFIG_MODE) -#define TIMER_CONFIG_BIT_WIDTH(id) CONCAT_3(TIMER, id, _CONFIG_BIT_WIDTH) -#define TIMER_CONFIG_IRQ_PRIORITY(id) CONCAT_3(TIMER, id, _CONFIG_IRQ_PRIORITY) - -/**@brief TIMER instance default configuration. */ -#define NRF_DRV_TIMER_DEFAULT_CONFIG(id) \ - { \ - .frequency = TIMER_CONFIG_FREQUENCY(id), \ - .mode = (nrf_timer_mode_t)TIMER_CONFIG_MODE(id), \ - .bit_width = (nrf_timer_bit_width_t)TIMER_CONFIG_BIT_WIDTH(id), \ - .interrupt_priority = TIMER_CONFIG_IRQ_PRIORITY(id), \ - .p_context = NULL \ - } +/** + * @brief Timer driver instance default configuration. + */ +#define NRF_DRV_TIMER_DEFAULT_CONFIG \ +{ \ + .frequency = (nrf_timer_frequency_t)TIMER_DEFAULT_CONFIG_FREQUENCY,\ + .mode = (nrf_timer_mode_t)TIMER_DEFAULT_CONFIG_MODE, \ + .bit_width = (nrf_timer_bit_width_t)TIMER_DEFAULT_CONFIG_BIT_WIDTH,\ + .interrupt_priority = TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .p_context = NULL \ +} /** - * @brief TIMER interrupt event handler. + * @brief Timer driver event handler type. * - * @param[in] event_type Timer event. - * @param[in] p_context General purpose parameter set during initialization of the timer. - Can be used to pass additional information to handler function, e.g. timer ID. + * @param[in] event_type Timer event. + * @param[in] p_context General purpose parameter set during initialization of + * the timer. This parameter can be used to pass + * additional information to the handler function, for + * example, the timer ID. */ -typedef void (*nrf_timer_event_handler_t)(nrf_timer_event_t event_type, void* p_context); +typedef void (* nrf_timer_event_handler_t)(nrf_timer_event_t event_type, + void * p_context); /** * @brief Function for initializing the timer. * - * @param[in] p_instance Timer. - * @param[in] p_config Initial configuration. Default configuration used if NULL. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Initial configuration. + * If NULL, the default configuration is used. + * @param[in] timer_event_handler Event handler provided by the user. + * Must not be NULL. * - * @param[in] timer_event_handler Event handler provided by the user. - * - * @retval NRF_SUCCESS If initialization was successful. - * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were supplied. + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the instance is already initialized. + * @retval NRF_ERROR_INVALID_PARAM If no handler was provided. */ ret_code_t nrf_drv_timer_init(nrf_drv_timer_t const * const p_instance, nrf_drv_timer_config_t const * p_config, - nrf_timer_event_handler_t timer_event_handler); + nrf_timer_event_handler_t timer_event_handler); /** * @brief Function for uninitializing the timer. * - * @param[in] p_instance Timer. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_timer_uninit(nrf_drv_timer_t const * const p_instance); /** - * @brief Function for turning on timer + * @brief Function for turning on the timer. * - * @param[in] p_instance Timer + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_timer_enable(nrf_drv_timer_t const * const p_instance); /** * @brief Function for turning off the timer. * - * @note Timer will allow to enter lowest possible SYSTEM_ON state only after this - * function is called. + * Note that the timer will allow to enter the lowest possible SYSTEM_ON state + * only after this function is called. * - * @param[in] p_instance Timer. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_timer_disable(nrf_drv_timer_t const * const p_instance); /** * @brief Function for pausing the timer. * - * @param[in] p_instance Timer + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_timer_pause(nrf_drv_timer_t const * const p_instance); /** * @brief Function for resuming the timer. * - * @param[in] p_instance Timer. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_timer_resume(nrf_drv_timer_t const * const p_instance); /** - * @brief Function for clearing the timer + * @brief Function for clearing the timer. * - * @param[in] p_instance Timer. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_timer_clear(nrf_drv_timer_t const * const p_instance); /** * @brief Function for incrementing the timer. * - * @param[in] p_instance Timer. + * @param[in] p_instance Pointer to the driver instance structure. */ void nrf_drv_timer_increment(nrf_drv_timer_t const * const p_instance); /** * @brief Function for returning the address of a specific timer task. * - * @param[in] p_instance Timer. - * @param[in] timer_task Timer task. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] timer_task Timer task. * - * @retval Task address. + * @return Task address. */ -uint32_t nrf_drv_timer_task_address_get(nrf_drv_timer_t const * const p_instance, - nrf_timer_task_t timer_task); +__STATIC_INLINE uint32_t nrf_drv_timer_task_address_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_task_t timer_task); /** * @brief Function for returning the address of a specific timer capture task. * - * @param[in] p_instance Timer. - * @param[in] channel Capture channel number. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] channel Capture channel number. * - * @retval Task address. + * @return Task address. */ -uint32_t nrf_drv_timer_capture_task_address_get(nrf_drv_timer_t const * const p_instance, - uint32_t channel); +__STATIC_INLINE uint32_t nrf_drv_timer_capture_task_address_get( + nrf_drv_timer_t const * const p_instance, + uint32_t channel); /** * @brief Function for returning the address of a specific timer event. * - * @param[in] p_instance Timer. - * @param[in] timer_event Timer event. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] timer_event Timer event. * - * @retval Event address. + * @return Event address. */ -uint32_t nrf_drv_timer_event_address_get(nrf_drv_timer_t const * const p_instance, - nrf_timer_event_t timer_event); +__STATIC_INLINE uint32_t nrf_drv_timer_event_address_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_event_t timer_event); /** * @brief Function for returning the address of a specific timer compare event. * - * @param[in] p_instance Timer. - * @param[in] channel Compare channel number. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] channel Compare channel number. * - * @retval Event address. + * @return Event address. */ -uint32_t nrf_drv_timer_compare_event_address_get(nrf_drv_timer_t const * const p_instance, - uint32_t channel); +__STATIC_INLINE uint32_t nrf_drv_timer_compare_event_address_get( + nrf_drv_timer_t const * const p_instance, + uint32_t channel); /** * @brief Function for capturing the timer value. * - * @param[in] p_instance Timer. - * @param[in] cc_channel Channel. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] cc_channel Capture channel number. * - * @retval Captured value. + * @return Captured value. */ uint32_t nrf_drv_timer_capture(nrf_drv_timer_t const * const p_instance, - nrf_timer_cc_channel_t cc_channel); + nrf_timer_cc_channel_t cc_channel); /** * @brief Function for returning the capture value from a specific channel. * - * @note Function for reading channel value when PPI is used for capturing. + * Use this function to read channel values when PPI is used for capturing. * - * @param[in] p_instance Timer. - * @param[in] cc_channel Channel. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] cc_channel Capture channel number. * - * @retval Captured value. + * @return Captured value. */ -uint32_t nrf_drv_timer_capture_get(nrf_drv_timer_t const * const p_instance, - nrf_timer_cc_channel_t cc_channel); +__STATIC_INLINE uint32_t nrf_drv_timer_capture_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_cc_channel_t cc_channel); /** * @brief Function for setting the timer channel in compare mode. * - * @param[in] p_instance Timer. - * @param[in] cc_channel Channel. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] cc_channel Compare channel number. * @param[in] cc_value Compare value. - * @param[in] enable Enable or disable the interrupt for the compare channel. + * @param[in] enable_int Enable or disable the interrupt for the compare channel. */ void nrf_drv_timer_compare(nrf_drv_timer_t const * const p_instance, - nrf_timer_cc_channel_t cc_channel, - uint32_t cc_value, - bool enable); + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value, + bool enable_int); /** * @brief Function for setting the timer channel in extended compare mode. * - * @param[in] p_instance Timer. - * @param[in] cc_channel Channel. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] cc_channel Compare channel number. * @param[in] cc_value Compare value. * @param[in] timer_short_mask Shortcut between the compare event on the channel * and the timer task (STOP or CLEAR). - * @param[in] enable Enable or disable the interrupt for the compare channel. + * @param[in] enable_int Enable or disable the interrupt for the compare + * channel. */ void nrf_drv_timer_extended_compare(nrf_drv_timer_t const * const p_instance, - nrf_timer_cc_channel_t cc_channel, - uint32_t cc_value, - nrf_timer_short_mask_t timer_short_mask, - bool enable); + nrf_timer_cc_channel_t cc_channel, + uint32_t cc_value, + nrf_timer_short_mask_t timer_short_mask, + bool enable_int); /** - * @brief Function for converting microseconds to ticks. - * - * @param[in] p_instance Timer. - * @param[in] timer_us Time in microseconds. + * @brief Function for converting time in microseconds to timer ticks. * - * @note Function asserts if there was a 32-bit integer overflow. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] time_us Time in microseconds. * - * @retval Number of ticks. + * @return Number of ticks. */ -uint32_t nrf_drv_timer_us_to_ticks(nrf_drv_timer_t const * const p_instance, - uint32_t timer_us); +__STATIC_INLINE uint32_t nrf_drv_timer_us_to_ticks( + nrf_drv_timer_t const * const p_instance, + uint32_t time_us); /** - * @brief Function for converting milliseconds to ticks. - * - * @param[in] p_instance Timer. - * @param[in] timer_ms Time in milliseconds. + * @brief Function for converting time in milliseconds to timer ticks. * - * @note Function asserts if there was a 32-bit integer overflow. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] time_ms Time in milliseconds. * - * @retval Number of ticks. + * @return Number of ticks. */ -uint32_t nrf_drv_timer_ms_to_ticks(nrf_drv_timer_t const * const p_instance, - uint32_t timer_ms); +__STATIC_INLINE uint32_t nrf_drv_timer_ms_to_ticks( + nrf_drv_timer_t const * const p_instance, + uint32_t time_ms); /** * @brief Function for enabling timer compare interrupt. * - * @param[in] p_instance Timer. - * @param[in] channel Compare channel + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] channel Compare channel. */ void nrf_drv_timer_compare_int_enable(nrf_drv_timer_t const * const p_instance, uint32_t channel); @@ -283,14 +336,77 @@ void nrf_drv_timer_compare_int_enable(nrf_drv_timer_t const * const p_instance, /** * @brief Function for disabling timer compare interrupt. * - * @param[in] p_instance Timer. - * @param[in] channel Compare channel + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] channel Compare channel. */ void nrf_drv_timer_compare_int_disable(nrf_drv_timer_t const * const p_instance, uint32_t channel); +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE uint32_t nrf_drv_timer_task_address_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_task_t timer_task) +{ + return (uint32_t)nrf_timer_task_address_get(p_instance->p_reg, timer_task); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_capture_task_address_get( + nrf_drv_timer_t const * const p_instance, + uint32_t channel) +{ + ASSERT(channel < p_instance->cc_channel_count); + return (uint32_t)nrf_timer_task_address_get(p_instance->p_reg, + nrf_timer_capture_task_get(channel)); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_event_address_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_event_t timer_event) +{ + return (uint32_t)nrf_timer_event_address_get(p_instance->p_reg, timer_event); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_compare_event_address_get( + nrf_drv_timer_t const * const p_instance, + uint32_t channel) +{ + ASSERT(channel < p_instance->cc_channel_count); + return (uint32_t)nrf_timer_event_address_get(p_instance->p_reg, + nrf_timer_compare_event_get(channel)); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_capture_get( + nrf_drv_timer_t const * const p_instance, + nrf_timer_cc_channel_t cc_channel) +{ + return nrf_timer_cc_read(p_instance->p_reg, cc_channel); +} + +__STATIC_INLINE uint32_t nrf_drv_timer_us_to_ticks( + nrf_drv_timer_t const * const p_instance, + uint32_t timer_us) +{ + return nrf_timer_us_to_ticks(timer_us, + nrf_timer_frequency_get(p_instance->p_reg)); +} +__STATIC_INLINE uint32_t nrf_drv_timer_ms_to_ticks( + nrf_drv_timer_t const * const p_instance, + uint32_t timer_ms) +{ + return nrf_timer_ms_to_ticks(timer_ms, + nrf_timer_frequency_get(p_instance->p_reg)); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + + +#ifdef __cplusplus +} #endif +#endif // NRF_DRV_TIMER_H__ + /** @} */ diff --git a/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h b/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h index 523c646..8a161cc 100644 --- a/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h +++ b/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h @@ -1,18 +1,55 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 TWI_MASTER_CONFIG #define TWI_MASTER_CONFIG +#ifdef __cplusplus +extern "C" { +#endif + #define TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER (24U) #define TWI_MASTER_CONFIG_DATA_PIN_NUMBER (25U) + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c b/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c index d214d95..357366c 100644 --- a/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c +++ b/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "twi_master.h" @@ -46,10 +74,10 @@ static bool twi_master_write(uint8_t * data, uint8_t data_length, bool issue_sto if (timeout == 0 || NRF_TWI1->EVENTS_ERROR != 0) { // Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at - // Product Anomaly Notification document found at + // Product Anomaly Notification document found at // https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads NRF_TWI1->EVENTS_ERROR = 0; - NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; + NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos; NRF_TWI1->POWER = 0; nrf_delay_us(5); NRF_TWI1->POWER = 1; @@ -73,8 +101,8 @@ static bool twi_master_write(uint8_t * data, uint8_t data_length, bool issue_sto { NRF_TWI1->EVENTS_STOPPED = 0; NRF_TWI1->TASKS_STOP = 1; - /* Wait until stop sequence is sent */ - while(NRF_TWI1->EVENTS_STOPPED == 0) + /* Wait until stop sequence is sent */ + while (NRF_TWI1->EVENTS_STOPPED == 0) { // Do nothing. } @@ -83,7 +111,7 @@ static bool twi_master_write(uint8_t * data, uint8_t data_length, bool issue_sto } -/** @brief Function for read by twi_master. +/** @brief Function for read by twi_master. */ static bool twi_master_read(uint8_t * data, uint8_t data_length, bool issue_stop_condition) { @@ -155,7 +183,7 @@ static bool twi_master_read(uint8_t * data, uint8_t data_length, bool issue_stop /** @snippet [TWI HW master read] */ /* Wait until stop sequence is sent */ - while(NRF_TWI1->EVENTS_STOPPED == 0) + while (NRF_TWI1->EVENTS_STOPPED == 0) { // Do nothing. } diff --git a/components/drivers_nrf/twi_master/deprecated/twi_master.h b/components/drivers_nrf/twi_master/deprecated/twi_master.h index 4e83de7..ec872d6 100644 --- a/components/drivers_nrf/twi_master/deprecated/twi_master.h +++ b/components/drivers_nrf/twi_master/deprecated/twi_master.h @@ -1,13 +1,41 @@ - /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 TWI_MASTER_H @@ -18,6 +46,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** @file * @brief Software controlled TWI Master driver. * @@ -45,13 +77,13 @@ /* These macros are needed to see if the slave is stuck and we as master send dummy clock cycles to end its wait */ /*lint -e717 -save "Suppress do {} while (0) for these macros" */ /*lint ++flb "Enter library region" */ -#define TWI_SCL_HIGH() do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while(0) /*!< Pulls SCL line high */ -#define TWI_SCL_LOW() do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while(0) /*!< Pulls SCL line low */ -#define TWI_SDA_HIGH() do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while(0) /*!< Pulls SDA line high */ -#define TWI_SDA_LOW() do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while(0) /*!< Pulls SDA line low */ -#define TWI_SDA_INPUT() do { NRF_GPIO->DIRCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while(0) /*!< Configures SDA pin as input */ -#define TWI_SDA_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while(0) /*!< Configures SDA pin as output */ -#define TWI_SCL_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while(0) /*!< Configures SCL pin as output */ +#define TWI_SCL_HIGH() do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line high */ +#define TWI_SCL_LOW() do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line low */ +#define TWI_SDA_HIGH() do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line high */ +#define TWI_SDA_LOW() do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line low */ +#define TWI_SDA_INPUT() do { NRF_GPIO->DIRCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Configures SDA pin as input */ +#define TWI_SDA_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Configures SDA pin as output */ +#define TWI_SCL_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Configures SCL pin as output */ /*lint -restore */ #define TWI_SDA_READ() ((NRF_GPIO->IN >> TWI_MASTER_CONFIG_DATA_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SDA */ @@ -98,4 +130,9 @@ bool twi_master_transfer(uint8_t address, uint8_t *data, uint8_t data_length, bo **/ /*lint --flb "Leave library region" */ + +#ifdef __cplusplus +} +#endif + #endif //TWI_MASTER_H diff --git a/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c b/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c index 106ef81..6284ca4 100644 --- a/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c +++ b/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include diff --git a/components/drivers_nrf/twi_master/nrf_drv_twi.c b/components/drivers_nrf/twi_master/nrf_drv_twi.c index 6a53d66..df4e5df 100644 --- a/components/drivers_nrf/twi_master/nrf_drv_twi.c +++ b/components/drivers_nrf/twi_master/nrf_drv_twi.c @@ -1,746 +1,1136 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(TWI) +#define ENABLED_TWI_COUNT (TWI0_ENABLED+TWI1_ENABLED) +#if ENABLED_TWI_COUNT #include "nrf_drv_twi.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" #include "nrf_assert.h" #include "app_util_platform.h" #include "nrf_delay.h" -#include "nrf_gpio.h" - -/**@brief Determine how long driver will be wait for event (in blocking mode). */ -#define BUSY_LOOP_TIMEOUT 0xFFF - -#define DISABLE_MASK UINT32_MAX - -#define SCL_PIN_CONF ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ - | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ - | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ - | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ - | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)) -#define SDA_PIN_CONF SCL_PIN_CONF -#define SCL_PIN_CONF_CLR ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ - | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ - | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ - | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ - | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos)) -#define SDA_PIN_CONF_CLR SCL_PIN_CONF_CLR - -/**@brief TWI powered on substates. */ -typedef enum -{ - NRF_DRV_TWI_SUBSTATE_IDLE, /**< Idle state. Transmission is stoped. */ - NRF_DRV_TWI_SUBSTATE_SUSPEND, /**< Tx transmission is suspended. */ - NRF_DRV_TWI_SUBSTATE_RX_SUSPEND, /**< Rx transmission is suspended. */ - NRF_DRV_TWI_SUBSTATE_STOP, /**< Transmission will be stoped. */ - NRF_DRV_TWI_SUBSTATE_ERROR /**< Error condition. */ -} substate_t; - -/**@brief State machine events. */ -typedef enum -{ - TX_ADDR_REQ, - RX_ADDR_REQ, - TX_DONE, - RX_DONE, - TO_STOP, - ON_ERROR -} sm_evt_t; - -/**@brief TWI transfer structure. */ -typedef struct -{ - bool is_tx; /**< Transmission from master to slave (if is_tx is set) or from slave to master (if not). */ - bool xfer_pending; /**< Transmission will be suspended (if xfer_pending is set) or stopped (if not). */ - bool error_condition; /**< Error has occured. */ - uint8_t address; /**< Address of slave device. */ - uint8_t * p_data; /**< Pointer to data buffer. */ - uint16_t length; /**< Length of data buffer. */ - uint16_t count; /**< Count of already transferred bytes. */ - nrf_twi_tasks_t task; /**< Next task. */ - nrf_twi_events_t end_event; /**< Event for which the state machine waits. */ - nrf_twi_int_mask_t end_int; /**< Interrupt for which the state machine waits. */ -} transfer_t; - -/**@brief TWI driver instance control block structure. */ -typedef struct -{ - nrf_drv_state_t state; /**< Instance state. */ - substate_t substate; /**< Instance substate when powered on. */ - bool volatile transfer_in_progress; /**< Data transfer is in progress. */ - transfer_t transfer; /**< Transfer structure. */ -} control_block_t; - -/**@brief Macro for getting the number of elements of the array. */ -#define ARRAY_LENGTH(a) (sizeof(a) / sizeof(a[0])) - -/** @brief User callbacks storage. */ -static nrf_drv_twi_evt_handler_t m_handlers[TWI_COUNT]; +#include + +#define NRF_LOG_MODULE_NAME "TWI" + +#if TWI_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL TWI_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR TWI_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR TWI_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_DRV_TWI_EVT_DONE ? "EVT_DONE" : \ + (event == NRF_DRV_TWI_EVT_ADDRESS_NACK ? "EVT_ADDRESS_NACK" : \ + (event == NRF_DRV_TWI_EVT_DATA_NACK ? "EVT_DATA_NACK" : "UNKNOWN ERROR")))))) +#define EVT_TO_STR_TWI(event) (event == NRF_TWI_EVENT_STOPPED ? "NRF_TWI_EVENT_STOPPED" : \ + (event == NRF_TWI_EVENT_RXDREADY ? "NRF_TWI_EVENT_RXDREADY" : \ + (event == NRF_TWI_EVENT_TXDSENT ? "NRF_TWI_EVENT_TXDSENT" : \ + (event == NRF_TWI_EVENT_ERROR ? "NRF_TWI_EVENT_ERROR" : \ + (event == NRF_TWI_EVENT_BB ? "NRF_TWI_EVENT_BB" : \ + (event == NRF_TWI_EVENT_SUSPENDED ? "NRF_TWI_EVENT_SUSPENDED" : "UNKNOWN ERROR")))))) +#define EVT_TO_STR_TWIM(event) (event == NRF_TWIM_EVENT_STOPPED ? "NRF_TWIM_EVENT_STOPPED" : \ + (event == NRF_TWIM_EVENT_ERROR ? "NRF_TWIM_EVENT_ERROR" : \ + (event == NRF_TWIM_EVENT_SUSPENDED ? "NRF_TWIM_EVENT_SUSPENDED" : \ + (event == NRF_TWIM_EVENT_RXSTARTED ? "NRF_TWIM_EVENT_RXSTARTED" : \ + (event == NRF_TWIM_EVENT_TXSTARTED ? "NRF_TWIM_EVENT_TXSTARTED" : \ + (event == NRF_TWIM_EVENT_LASTRX ? "NRF_TWIM_EVENT_LASTRX" : \ + (event == NRF_TWIM_EVENT_LASTTX ? "NRF_TWIM_EVENT_LASTTX" : "UNKNOWN ERROR"))))))) +#define TRANSFER_TO_STR(type) (type == NRF_DRV_TWI_XFER_TX ? "XFER_TX" : \ + (type == NRF_DRV_TWI_XFER_RX ? "XFER_RX" : \ + (type == NRF_DRV_TWI_XFER_TXRX ? "XFER_TXRX" : \ + (type == NRF_DRV_TWI_XFER_TXTX ? "XFER_TXTX" : "UNKNOWN TRANSFER TYPE")))) +#else //TWI_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define EVT_TO_STR_TWI(event) "" +#define EVT_TO_STR_TWIM(event) "" +#define TRANSFER_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //TWI_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + +#define TWI0_IRQ_HANDLER SPI0_TWI0_IRQHandler +#define TWI1_IRQ_HANDLER SPI1_TWI1_IRQHandler + +#if (defined(TWIM_IN_USE) && defined(TWI_IN_USE)) + // TWIM and TWI combined + #define CODE_FOR_TWIM(code) if (p_instance->use_easy_dma) { code } + #define CODE_FOR_TWI(code) else { code } +#elif (defined(TWIM_IN_USE) && !defined(TWI_IN_USE)) + // TWIM only + #define CODE_FOR_TWIM(code) { code } + #define CODE_FOR_TWI(code) +#elif (!defined(TWIM_IN_USE) && defined(TWI_IN_USE)) + // TWI only + #define CODE_FOR_TWIM(code) + #define CODE_FOR_TWI(code) { code } +#else + #error "Wrong configuration." +#endif -/** @brief Context pointers, passed to user callbacks. */ -static void * mp_contexts[TWI_COUNT]; +// All interrupt flags +#define DISABLE_ALL_INT_SHORT 0xFFFFFFFF -/** @brief Control blocks storage. */ -static control_block_t m_cb[TWI_COUNT]; +#define SCL_PIN_INIT_CONF ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ + | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)) +#define SDA_PIN_INIT_CONF SCL_PIN_INIT_CONF -/** @brief TWI instances pointers storage. */ -static nrf_drv_twi_t const * m_instances[TWI_COUNT]; +#define SDA_PIN_UNINIT_CONF ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + | (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) \ + | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) \ + | (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) \ + | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos)) +#define SCL_PIN_UNINIT_CONF SDA_PIN_UNINIT_CONF -static const nrf_drv_twi_config_t m_default_config[] = { -#if (TWI0_ENABLED == 1) - NRF_DRV_TWI_DEFAULT_CONFIG(0), -#endif -#if (TWI1_ENABLED == 1) - NRF_DRV_TWI_DEFAULT_CONFIG(1) -#endif -}; +#define SCL_PIN_INIT_CONF_CLR ( (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \ + | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \ + | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \ + | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \ + | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos)) +#define SDA_PIN_INIT_CONF_CLR SCL_PIN_INIT_CONF_CLR -/**@brief TWI state machine action. */ -typedef void (* sm_action_t)(nrf_drv_twi_t const * const p_instance); -/**@brief TWI transition structure. */ +// Control block - driver instance local data. typedef struct { - sm_evt_t evt; - substate_t next_state; - sm_action_t func; -} transition_t; - -/** - * @brief Function for initializing data transfer (from master to slave). - * - * @param[in] p_instance TWI. - */ -static void address_req(nrf_drv_twi_t const * const p_instance); + nrf_drv_twi_evt_handler_t handler; + void * p_context; + volatile uint32_t int_mask; + nrf_drv_twi_xfer_desc_t xfer_desc; + uint32_t flags; + uint8_t * p_curr_buf; + uint8_t curr_length; + bool curr_no_stop; + nrf_drv_state_t state; + bool error; + volatile bool busy; + bool repeated; + uint8_t bytes_transferred; + bool hold_bus_uninit; +} twi_control_block_t; + +static twi_control_block_t m_cb[ENABLED_TWI_COUNT]; + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n + #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void) + + #if NRF_MODULE_ENABLED(TWI0) + IRQ_HANDLER(0); + #endif + #if NRF_MODULE_ENABLED(TWI1) + IRQ_HANDLER(1); + #endif + static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_TWI_COUNT] = { + #if NRF_MODULE_ENABLED(TWI0) + IRQ_HANDLER_NAME(0), + #endif + #if NRF_MODULE_ENABLED(TWI1) + IRQ_HANDLER_NAME(1), + #endif + }; +#else + #define IRQ_HANDLER(n) void SPI##n##_TWI##n##_IRQHandler(void) +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +static ret_code_t twi_process_error(uint32_t errorsrc) +{ + ret_code_t ret = NRF_ERROR_INTERNAL; -/** - * @brief Function for initializing data transfer (from slave to master). - * - * @param[in] p_instance TWI. - */ -static void rx_address_req(nrf_drv_twi_t const * const p_instance); + if (errorsrc & NRF_TWI_ERROR_OVERRUN) + { + ret = NRF_ERROR_DRV_TWI_ERR_OVERRUN;; + } -/** - * @brief Function for preparing byte transfer (from master to slave). - * - * @param[in] p_instance TWI. - */ -static void tx_prepare(nrf_drv_twi_t const * const p_instance); + if (errorsrc & NRF_TWI_ERROR_ADDRESS_NACK) + { + ret = NRF_ERROR_DRV_TWI_ERR_ANACK; + } -/** - * @brief Function for confirming byte transfer (from master to slave). - * - * @param[in] p_instance TWI. - */ -static void tx_done(nrf_drv_twi_t const * const p_instance); + if (errorsrc & NRF_TWI_ERROR_DATA_NACK) + { + ret = NRF_ERROR_DRV_TWI_ERR_DNACK; + } -/** - * @brief Function for preparing byte transfer (from slave to master). - * - * @param[in] p_instance TWI. - */ -static void rx_prepare(nrf_drv_twi_t const * const p_instance); + return ret; +} -/** - * @brief Function for confirming byte transfer (from slave to master). - * - * @param[in] p_instance TWI. - */ -static void rx_done(nrf_drv_twi_t const * const p_instance); +static void twi_clear_bus(nrf_drv_twi_config_t const * p_config) +{ + NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF; + NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF; -/** - * @brief Function for ending transfer after an error. - * - * @param[in] p_instance TWI. - */ -static void on_error(nrf_drv_twi_t const * const p_instance); + nrf_gpio_pin_set(p_config->scl); + nrf_gpio_pin_set(p_config->sda); -/** - * @brief Function for ending transfer after an error. - * - * @param[in] p_instance TWI. - */ -static void ack_error(nrf_drv_twi_t const * const p_instance); - -/**@brief List of idle state transitions. */ -static const transition_t m_idle[] = { - {TX_ADDR_REQ, NRF_DRV_TWI_SUBSTATE_SUSPEND, address_req}, - {RX_ADDR_REQ, NRF_DRV_TWI_SUBSTATE_RX_SUSPEND, rx_address_req}, -}; - -/**@brief List of TX suspended state transitions. */ -static const transition_t m_tx_suspended[] = { - {TX_DONE, NRF_DRV_TWI_SUBSTATE_SUSPEND, tx_done}, - {RX_ADDR_REQ, NRF_DRV_TWI_SUBSTATE_RX_SUSPEND, rx_address_req}, - {TX_ADDR_REQ, NRF_DRV_TWI_SUBSTATE_SUSPEND, tx_prepare}, - {TO_STOP, NRF_DRV_TWI_SUBSTATE_STOP, NULL}, - {ON_ERROR, NRF_DRV_TWI_SUBSTATE_ERROR, on_error} -}; - -/**@brief List of RX suspended state transitions. */ -static const transition_t m_rx_suspended[] = { - {RX_ADDR_REQ, NRF_DRV_TWI_SUBSTATE_RX_SUSPEND, rx_prepare}, - {RX_DONE, NRF_DRV_TWI_SUBSTATE_RX_SUSPEND, rx_done}, - {TO_STOP, NRF_DRV_TWI_SUBSTATE_STOP, NULL}, - {ON_ERROR, NRF_DRV_TWI_SUBSTATE_ERROR, on_error} -}; - -/**@brief List of stopped state transitions. */ -static const transition_t m_stopped[] = { - {RX_DONE, NRF_DRV_TWI_SUBSTATE_IDLE, rx_done}, - {TX_DONE, NRF_DRV_TWI_SUBSTATE_IDLE, tx_done}, - {ON_ERROR, NRF_DRV_TWI_SUBSTATE_IDLE, ack_error} -}; - -/**@brief List of error state transitions. */ -static const transition_t m_error[] = { - {RX_DONE, NRF_DRV_TWI_SUBSTATE_IDLE, ack_error}, - {TX_DONE, NRF_DRV_TWI_SUBSTATE_IDLE, ack_error}, - {ON_ERROR, NRF_DRV_TWI_SUBSTATE_IDLE, ack_error} -}; - -/**@brief List of state machine states. */ -static const transition_t * mp_states[] = { - m_idle, - m_tx_suspended, - m_rx_suspended, - m_stopped, - m_error -}; - -/**@brief List of amounts for each state transitions. */ -static const uint32_t m_states_len[] = -{ - ARRAY_LENGTH(m_idle), - ARRAY_LENGTH(m_tx_suspended), - ARRAY_LENGTH(m_rx_suspended), - ARRAY_LENGTH(m_stopped), - ARRAY_LENGTH(m_error) -}; + NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF_CLR; + NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF_CLR; -/** - * @brief Function for running state machine. - * - * @param[in] p_instance TWI. - * @param[in] evt State machine event. - */ -static void state_machine(nrf_drv_twi_t const * const p_instance, sm_evt_t evt) -{ - bool evt_found = false; - substate_t substate = m_cb[p_instance->instance_id].substate; - transition_t const * p_state = mp_states[substate]; + nrf_delay_us(4); - for (uint32_t i = 0; i < m_states_len[substate]; i++) + for (int i = 0; i < 9; i++) { - if (evt == p_state[i].evt) + if (nrf_gpio_pin_read(p_config->sda)) { - m_cb[p_instance->instance_id].substate = p_state[i].next_state; - - if (p_state[i].func) + if (i == 0) + { + return; + } + else { - p_state[i].func(p_instance); + break; } - evt_found = true; - break; } + nrf_gpio_pin_clear(p_config->scl); + nrf_delay_us(4); + nrf_gpio_pin_set(p_config->scl); + nrf_delay_us(4); } - UNUSED_VARIABLE(evt_found); - ASSERT(evt_found); + nrf_gpio_pin_clear(p_config->sda); + nrf_delay_us(4); + nrf_gpio_pin_set(p_config->sda); } - -/** - * @brief Function for prepering shortcut register. - * - * @param[in] p_instance TWI. - */ -static void txrx_shorts_set_task_start(nrf_drv_twi_t const * const p_instance) +ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const * p_instance, + nrf_drv_twi_config_t const * p_config, + nrf_drv_twi_evt_handler_t event_handler, + void * p_context) { - uint32_t short_mask; - transfer_t * p_transfer = &(m_cb[p_instance->instance_id].transfer); - - nrf_twi_shorts_clear(p_instance->p_reg, - NRF_TWI_SHORTS_BB_SUSPEND_MASK | NRF_TWI_SHORTS_BB_STOP_MASK); - - // if the last one and no pending transfer prepare to wait for stopped event - if (((p_transfer->count + 1) == p_transfer->length) && p_transfer->xfer_pending == false) + ASSERT(p_config); + ASSERT(p_config->scl != p_config->sda); + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ret_code_t err_code; + + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) { - short_mask = NRF_TWI_SHORTS_BB_STOP_MASK; + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } - p_transfer->end_event = NRF_TWI_EVENTS_STOPPED; - nrf_twi_event_clear(p_instance->p_reg, p_transfer->end_event); +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(p_instance->reg.p_twi, + m_irq_handlers[p_instance->drv_inst_idx]) != NRF_SUCCESS) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) - if (m_handlers[p_instance->instance_id]) - { - nrf_twi_int_disable(p_instance->p_reg, p_transfer->end_int); - p_transfer->end_int = NRF_TWI_INT_STOPPED_MASK; - nrf_twi_int_enable(p_instance->p_reg, p_transfer->end_int); - } + p_cb->handler = event_handler; + p_cb->p_context = p_context; + p_cb->int_mask = 0; + p_cb->repeated = false; + p_cb->busy = false; + p_cb->hold_bus_uninit = p_config->hold_bus_uninit; - state_machine(p_instance, TO_STOP); + if(p_config->clear_bus_init) + { + /* Send clocks (max 9) until slave device back from stuck mode */ + twi_clear_bus(p_config); } - else + + /* To secure correct signal levels on the pins used by the TWI + master when the system is in OFF mode, and when the TWI master is + disabled, these pins must be configured in the GPIO peripheral. + */ + NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_INIT_CONF; + NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_INIT_CONF; + + CODE_FOR_TWIM + ( + NRF_TWIM_Type * p_twim = p_instance->reg.p_twim; + nrf_twim_pins_set(p_twim, p_config->scl, p_config->sda); + nrf_twim_frequency_set(p_twim, + (nrf_twim_frequency_t)p_config->frequency); + ) + CODE_FOR_TWI + ( + NRF_TWI_Type * p_twi = p_instance->reg.p_twi; + nrf_twi_pins_set(p_twi, p_config->scl, p_config->sda); + nrf_twi_frequency_set(p_twi, + (nrf_twi_frequency_t)p_config->frequency); + ) + + if (p_cb->handler) { - short_mask = NRF_TWI_SHORTS_BB_SUSPEND_MASK; + CODE_FOR_TWIM + ( + nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twim), + p_config->interrupt_priority); + ) + CODE_FOR_TWI + ( + nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twi), + p_config->interrupt_priority); + ) } - nrf_twi_shorts_set(p_instance->p_reg, short_mask); - nrf_twi_tasks_t prev_task = p_transfer->task; - p_transfer->task = NRF_TWI_TASKS_RESUME; - nrf_twi_task_set(p_instance->p_reg, prev_task); -} + p_cb->state = NRF_DRV_STATE_INITIALIZED; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} -static void address_req(nrf_drv_twi_t const * const p_instance) +void nrf_drv_twi_uninit(nrf_drv_twi_t const * p_instance) { - transfer_t * p_transfer = &(m_cb[p_instance->instance_id].transfer); - nrf_twi_address_set(p_instance->p_reg, p_transfer->address); + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); - nrf_twi_task_set(p_instance->p_reg, NRF_TWI_TASKS_RESUME); - p_transfer->task = NRF_TWI_TASKS_STARTTX; - p_transfer->end_event = NRF_TWI_EVENTS_TXDSENT; - nrf_twi_event_clear(p_instance->p_reg, p_transfer->end_event); - - if (m_handlers[p_instance->instance_id]) + if (p_cb->handler) { - nrf_twi_int_disable(p_instance->p_reg, p_transfer->end_int); - p_transfer->end_int = NRF_TWI_INT_TXDSENT_MASK; - nrf_twi_int_enable(p_instance->p_reg, p_transfer->end_int); + CODE_FOR_TWIM + ( + nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twim)); + ) + CODE_FOR_TWI + ( + nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_twi)); + ) } + nrf_drv_twi_disable(p_instance); - tx_prepare(p_instance); -} - - -static void rx_address_req(nrf_drv_twi_t const * const p_instance) -{ - transfer_t * p_transfer = &(m_cb[p_instance->instance_id].transfer); +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(p_instance->reg.p_twi); +#endif - nrf_twi_address_set(p_instance->p_reg, p_transfer->address); - nrf_twi_task_set(p_instance->p_reg, NRF_TWI_TASKS_RESUME); - p_transfer->task = NRF_TWI_TASKS_STARTRX; - p_transfer->end_event = NRF_TWI_EVENTS_RXDREADY; - nrf_twi_event_clear(p_instance->p_reg, p_transfer->end_event); - if (m_handlers[p_instance->instance_id]) + if (!p_cb->hold_bus_uninit) { - nrf_twi_int_disable(p_instance->p_reg, p_transfer->end_int); - p_transfer->end_int = NRF_TWI_INT_RXDREADY_MASK; - nrf_twi_int_enable(p_instance->p_reg, p_transfer->end_int); + CODE_FOR_TWIM + ( + NRF_GPIO->PIN_CNF[p_instance->reg.p_twim->PSEL.SCL] = SCL_PIN_UNINIT_CONF; + NRF_GPIO->PIN_CNF[p_instance->reg.p_twim->PSEL.SDA] = SDA_PIN_UNINIT_CONF; + ) + CODE_FOR_TWI + ( + NRF_GPIO->PIN_CNF[p_instance->reg.p_twi->PSELSCL] = SCL_PIN_UNINIT_CONF; + NRF_GPIO->PIN_CNF[p_instance->reg.p_twi->PSELSDA] = SDA_PIN_UNINIT_CONF; + ) } - rx_prepare(p_instance); + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; + NRF_LOG_INFO("Instance uninitialized: %d.\r\n", p_instance->drv_inst_idx); } - -static void rx_prepare(nrf_drv_twi_t const * const p_instance) +void nrf_drv_twi_enable(nrf_drv_twi_t const * p_instance) { - txrx_shorts_set_task_start(p_instance); -} + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state == NRF_DRV_STATE_INITIALIZED); + CODE_FOR_TWIM + ( + NRF_TWIM_Type * p_twim = p_instance->reg.p_twim; -static void rx_done(nrf_drv_twi_t const * const p_instance) -{ - transfer_t * p_transfer = &(m_cb[p_instance->instance_id].transfer); + nrf_twim_enable(p_twim); + ) + CODE_FOR_TWI + ( + NRF_TWI_Type * p_twi = p_instance->reg.p_twi; - p_transfer->p_data[p_transfer->count] = nrf_twi_rxd_get(p_instance->p_reg); - p_transfer->count++; + nrf_twi_enable(p_twi); + ) - if (p_transfer->count < p_transfer->length) - { - rx_prepare(p_instance); - } + p_cb->state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Instance enabled: %d.\r\n", p_instance->drv_inst_idx); } - -static void tx_prepare(nrf_drv_twi_t const * const p_instance) +void nrf_drv_twi_disable(nrf_drv_twi_t const * p_instance) { - transfer_t * p_transfer = &(m_cb[p_instance->instance_id].transfer); - - nrf_twi_txd_set(p_instance->p_reg, p_transfer->p_data[p_transfer->count]); - txrx_shorts_set_task_start(p_instance); + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state != NRF_DRV_STATE_UNINITIALIZED); + + CODE_FOR_TWIM + ( + NRF_TWIM_Type * p_twim = p_instance->reg.p_twim; + p_cb->int_mask = 0; + nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT); + nrf_twim_shorts_disable(p_twim, DISABLE_ALL_INT_SHORT); + nrf_twim_disable(p_twim); + ) + CODE_FOR_TWI + ( + NRF_TWI_Type * p_twi = p_instance->reg.p_twi; + nrf_twi_int_disable(p_twi, DISABLE_ALL_INT_SHORT); + nrf_twi_shorts_disable(p_twi, DISABLE_ALL_INT_SHORT); + nrf_twi_disable(p_twi); + ) + + p_cb->state = NRF_DRV_STATE_INITIALIZED; + NRF_LOG_INFO("Instance disabled: %d.\r\n", p_instance->drv_inst_idx); } +#ifdef TWI_IN_USE +static bool twi_send_byte(NRF_TWI_Type * p_twi, + uint8_t const * p_data, + uint8_t length, + uint8_t * p_bytes_transferred, + bool no_stop) +{ + if (*p_bytes_transferred < length) + { + nrf_twi_txd_set(p_twi, p_data[*p_bytes_transferred]); + ++(*p_bytes_transferred); + } + else + { + if (no_stop) + { + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_SUSPEND); + return false; + } + else + { + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); + } + } + return true; +} -static void tx_done(nrf_drv_twi_t const * const p_instance) +static void twi_receive_byte(NRF_TWI_Type * p_twi, + uint8_t * p_data, + uint8_t length, + uint8_t * p_bytes_transferred) { - transfer_t * p_transfer = &(m_cb[p_instance->instance_id].transfer); + if (*p_bytes_transferred < length) + { + p_data[*p_bytes_transferred] = nrf_twi_rxd_get(p_twi); - p_transfer->count++; + ++(*p_bytes_transferred); - if (p_transfer->count < p_transfer->length) - { - tx_prepare(p_instance); + if (*p_bytes_transferred == length - 1) + { + nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_STOP_MASK); + } + else if (*p_bytes_transferred == length) + { + return; + } + + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME); } } - -static void on_error(nrf_drv_twi_t const * const p_instance) +static bool twi_transfer(NRF_TWI_Type * p_twi, + bool * p_error, + uint8_t * p_bytes_transferred, + uint8_t * p_data, + uint8_t length, + bool no_stop) { - transfer_t * p_transfer = &(m_cb[p_instance->instance_id].transfer); - - p_transfer->end_event = NRF_TWI_EVENTS_STOPPED; - nrf_twi_event_clear(p_instance->p_reg, p_transfer->end_event); + bool do_stop_check = ((*p_error) || ((*p_bytes_transferred) == length)); - if (m_handlers[p_instance->instance_id]) + if (*p_error) { - nrf_twi_int_disable(p_instance->p_reg, p_transfer->end_int); - p_transfer->end_int = NRF_TWI_INT_STOPPED_MASK; - nrf_twi_int_enable(p_instance->p_reg, p_transfer->end_int); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); + } + else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR)) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR)); + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); + *p_error = true; + } + else + { + if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_TXDSENT)) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_TXDSENT)); + if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR)) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR)); + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); + *p_error = true; + } + else + { + if (!twi_send_byte(p_twi, p_data, length, p_bytes_transferred, no_stop)) + { + return false; + } + } + } + else if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_RXDREADY)) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_RXDREADY)); + if (nrf_twi_event_check(p_twi, NRF_TWI_EVENT_ERROR)) + { + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_ERROR)); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STOP); + *p_error = true; + } + else + { + twi_receive_byte(p_twi, p_data, length, p_bytes_transferred); + } + } } - nrf_twi_task_set(p_instance->p_reg, NRF_TWI_TASKS_RESUME); - nrf_twi_task_set(p_instance->p_reg, NRF_TWI_TASKS_STOP); -} + if (do_stop_check && nrf_twi_event_check(p_twi, NRF_TWI_EVENT_STOPPED)) + { + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED); + NRF_LOG_DEBUG("TWI: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWI(NRF_TWI_EVENT_STOPPED)); + return false; + } -static void ack_error(nrf_drv_twi_t const * const p_instance) -{ - transfer_t * p_transfer = &(m_cb[p_instance->instance_id].transfer); - p_transfer->error_condition = true; + return true; } -/** - * @brief Function for blocking the module until desired event occurs. - * - * @param[in] p_instance TWI. - * - * @return False if any error has occurred. - */ -static bool twi_action_wait(nrf_drv_twi_t const * const p_instance) +static ret_code_t twi_tx_start_transfer(twi_control_block_t * p_cb, + NRF_TWI_Type * p_twi, + uint8_t const * p_data, + uint8_t length, + bool no_stop) { - bool error; - bool done; - uint32_t timeout = 0; - transfer_t * p_transfer = &(m_cb[p_instance->instance_id].transfer); - - do - { - done = nrf_twi_event_check(p_instance->p_reg, p_transfer->end_event); - error = nrf_twi_event_check(p_instance->p_reg, NRF_TWI_EVENTS_ERROR); - error |= (++timeout < BUSY_LOOP_TIMEOUT) ? false : true; - } while (!(error | done)); - return !error; -} + ret_code_t ret_code = NRF_SUCCESS; -static void twi_clear_bus(nrf_drv_twi_t const * const p_instance, nrf_drv_twi_config_t const * p_config) -{ - NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_CONF; - NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_CONF; + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); + nrf_twi_shorts_set(p_twi, 0); - nrf_gpio_pin_set(p_config->scl); - nrf_gpio_pin_set(p_config->sda); + p_cb->bytes_transferred = 0; + p_cb->error = false; - NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_CONF_CLR; - NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_CONF_CLR; + // In case TWI is suspended resume its operation. + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME); + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STARTTX); - nrf_delay_us(4); + (void)twi_send_byte(p_twi, p_data, length, &p_cb->bytes_transferred, no_stop); - for(int i = 0; i < 9; i++) + if (p_cb->handler) { - if (nrf_gpio_pin_read(p_config->sda)) + p_cb->int_mask = NRF_TWI_INT_STOPPED_MASK | + NRF_TWI_INT_ERROR_MASK | + NRF_TWI_INT_TXDSENT_MASK | + NRF_TWI_INT_RXDREADY_MASK; + nrf_twi_int_enable(p_twi, p_cb->int_mask); + } + else + { + while (twi_transfer(p_twi, &p_cb->error, &p_cb->bytes_transferred, (uint8_t *)p_data, length, no_stop)) + {} + + if (p_cb->error) { - if(i == 0) + uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(p_twi); + + if (errorsrc) { - return; - } - else - { - break; + ret_code = twi_process_error(errorsrc); } } - nrf_gpio_pin_clear(p_config->scl); - nrf_delay_us(4); - nrf_gpio_pin_set(p_config->scl); - nrf_delay_us(4); + } - nrf_gpio_pin_clear(p_config->sda); - nrf_delay_us(4); - nrf_gpio_pin_set(p_config->sda); + return ret_code; } -/** - * @brief Function for transferring data. - * - * @note Transmission will be stopped when error or timeout occurs. - * - * @param[in] p_instance TWI. - * @param[in] address Address of specific slave device (only 7 LSB). - * @param[in] p_data Pointer to a receive buffer. - * @param[in] length Number of bytes to be received. - * @param[in] xfer_pending After a specified number of bytes transmission will be - * suspended (if xfer_pending is set) or stopped (if not) - * @param[in] is_tx Indicate transfer direction (true for master to slave transmission). - * - * @retval NRF_SUCCESS If the procedure was successful. - * @retval NRF_ERROR_BUSY Driver is not ready for new transfer. - * @retval NRF_ERROR_INTERNAL NRF_TWI_EVENTS_ERROR or timeout has occured (only in blocking mode). - */ -static ret_code_t twi_transfer(nrf_drv_twi_t const * const p_instance, - uint8_t address, - uint8_t const * p_data, - uint32_t length, - bool xfer_pending, - bool is_tx) +static ret_code_t twi_rx_start_transfer(twi_control_block_t * p_cb, + NRF_TWI_Type * p_twi, + uint8_t const * p_data, + uint8_t length) { - ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_POWERED_ON); - ASSERT(length > 0); + ret_code_t ret_code = NRF_SUCCESS; - control_block_t * p_cb = &m_cb[p_instance->instance_id]; + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_STOPPED); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_ERROR); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_TXDSENT); + nrf_twi_event_clear(p_twi, NRF_TWI_EVENT_RXDREADY); - bool is_busy = false; - CRITICAL_REGION_ENTER(); - if (p_cb->transfer_in_progress) + p_cb->bytes_transferred = 0; + p_cb->error = false; + + if (length == 1) { - is_busy = true; + nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_STOP_MASK); } else { - p_cb->transfer_in_progress = true; + nrf_twi_shorts_set(p_twi, NRF_TWI_SHORT_BB_SUSPEND_MASK); } - CRITICAL_REGION_EXIT(); - if (is_busy) + // In case TWI is suspended resume its operation. + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_RESUME); + nrf_twi_task_trigger(p_twi, NRF_TWI_TASK_STARTRX); + + if (p_cb->handler) { - return NRF_ERROR_BUSY; + p_cb->int_mask = NRF_TWI_INT_STOPPED_MASK | + NRF_TWI_INT_ERROR_MASK | + NRF_TWI_INT_TXDSENT_MASK | + NRF_TWI_INT_RXDREADY_MASK; + nrf_twi_int_enable(p_twi, p_cb->int_mask); } - - transfer_t * p_transfer = &p_cb->transfer; - p_transfer->address = address; - p_transfer->length = (uint16_t)length; - p_transfer->p_data = (uint8_t *)p_data; - p_transfer->count = 0; - p_transfer->xfer_pending = xfer_pending; - p_transfer->is_tx = is_tx; - p_transfer->error_condition = false; - - state_machine(p_instance, p_transfer->is_tx ? TX_ADDR_REQ : RX_ADDR_REQ); - - if (!m_handlers[p_instance->instance_id]) + else { - // blocking mode - sm_evt_t evt = p_transfer->is_tx ? TX_DONE : RX_DONE; - do + while (twi_transfer(p_twi, &p_cb->error, &p_cb->bytes_transferred, (uint8_t*)p_data, length, false)) + {} + + if (p_cb->error) { - if (twi_action_wait(p_instance) == false) - { - nrf_twi_event_clear(p_instance->p_reg, NRF_TWI_EVENTS_ERROR); - evt = ON_ERROR; - } - nrf_twi_event_clear(p_instance->p_reg, p_transfer->end_event); - state_machine(p_instance, evt); + uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(p_twi); - if (p_transfer->error_condition) + if (errorsrc) { - p_cb->transfer_in_progress = false; - return NRF_ERROR_INTERNAL; + ret_code = twi_process_error(errorsrc); } } - while (p_transfer->count < p_transfer->length); - p_cb->transfer_in_progress = false; } - return NRF_SUCCESS; + return ret_code; } - -ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const * const p_instance, - nrf_drv_twi_config_t const * p_config, - nrf_drv_twi_evt_handler_t event_handler, - void * p_context) +__STATIC_INLINE ret_code_t twi_xfer(twi_control_block_t * p_cb, + NRF_TWI_Type * p_twi, + nrf_drv_twi_xfer_desc_t const * p_xfer_desc, + uint32_t flags) { - if (m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED) + + ret_code_t err_code = NRF_SUCCESS; + + /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */ + nrf_twi_int_disable(p_twi, DISABLE_ALL_INT_SHORT); + + if (p_cb->busy) { - return NRF_ERROR_INVALID_STATE; + nrf_twi_int_enable(p_twi, p_cb->int_mask); + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } - - if (p_config == NULL) + else { - p_config = &m_default_config[p_instance->instance_id]; + p_cb->busy = (NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & flags) ? false : true; } + if (flags & NRF_DRV_TWI_FLAG_HOLD_XFER) + { + err_code = NRF_ERROR_NOT_SUPPORTED; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } - m_handlers[p_instance->instance_id] = event_handler; - mp_contexts[p_instance->instance_id] = p_context; - m_instances[p_instance->instance_id] = (nrf_drv_twi_t *)p_instance; - - twi_clear_bus(p_instance, p_config); + p_cb->flags = flags; + p_cb->xfer_desc = *p_xfer_desc; + p_cb->curr_length = p_xfer_desc->primary_length; + p_cb->p_curr_buf = p_xfer_desc->p_primary_buf; + nrf_twi_address_set(p_twi, p_xfer_desc->address); - /* To secure correct signal levels on the pins used by the TWI - master when the system is in OFF mode, and when the TWI master is - disabled, these pins must be configured in the GPIO peripheral. - */ - NRF_GPIO->PIN_CNF[p_config->scl] = SCL_PIN_CONF; - NRF_GPIO->PIN_CNF[p_config->sda] = SDA_PIN_CONF; + if (p_xfer_desc->type != NRF_DRV_TWI_XFER_RX) + { + p_cb->curr_no_stop = ((p_xfer_desc->type == NRF_DRV_TWI_XFER_TX) && + !(flags & NRF_DRV_TWI_FLAG_TX_NO_STOP)) ? false : true; - nrf_twi_frequency_set(p_instance->p_reg, p_config->frequency); - nrf_twi_pins_set(p_instance->p_reg, p_config->scl, p_config->sda); + err_code = twi_tx_start_transfer(p_cb, p_twi, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length, p_cb->curr_no_stop); + } + else + { + p_cb->curr_no_stop = false; - if (m_handlers[p_instance->instance_id]) + err_code = twi_rx_start_transfer(p_cb, p_twi, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); + } + if (p_cb->handler == NULL) { - nrf_drv_common_irq_enable(p_instance->irq, p_config->interrupt_priority); + p_cb->busy = false; } - - m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED; - - return NRF_SUCCESS; + return err_code; } +#endif +#ifdef TWIM_IN_USE +__STATIC_INLINE void twim_list_enable_handle(NRF_TWIM_Type * p_twim, uint32_t flags) +{ + if (NRF_DRV_TWI_FLAG_TX_POSTINC & flags) + { + nrf_twim_tx_list_enable(p_twim); + } + else + { + nrf_twim_tx_list_disable(p_twim); + } -void nrf_drv_twi_uninit(nrf_drv_twi_t const * const p_instance) + if (NRF_DRV_TWI_FLAG_RX_POSTINC & flags) + { + nrf_twim_rx_list_enable(p_twim); + } + else + { + nrf_twim_rx_list_disable(p_twim); + } +} +__STATIC_INLINE ret_code_t twim_xfer(twi_control_block_t * p_cb, + NRF_TWIM_Type * p_twim, + nrf_drv_twi_xfer_desc_t const * p_xfer_desc, + uint32_t flags) { - ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); + ret_code_t err_code = NRF_SUCCESS; + nrf_twim_task_t start_task = NRF_TWIM_TASK_STARTTX; + nrf_twim_event_t evt_to_wait = NRF_TWIM_EVENT_STOPPED; - if (m_handlers[p_instance->instance_id]) + if (!nrf_drv_is_in_RAM(p_xfer_desc->p_primary_buf)) { - nrf_drv_common_irq_disable(p_instance->irq); + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + /* Block TWI interrupts to ensure that function is not interrupted by TWI interrupt. */ + nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT); + if (p_cb->busy) + { + nrf_twim_int_enable(p_twim, p_cb->int_mask); + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + else + { + p_cb->busy = ((NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & flags) || + (NRF_DRV_TWI_FLAG_REPEATED_XFER & flags)) ? false: true; } - nrf_drv_twi_disable(p_instance); - nrf_twi_shorts_clear(p_instance->p_reg, DISABLE_MASK); - m_cb[p_instance->instance_id].state = NRF_DRV_STATE_UNINITIALIZED; -} + p_cb->xfer_desc = *p_xfer_desc; + p_cb->repeated = (flags & NRF_DRV_TWI_FLAG_REPEATED_XFER) ? true : false; + nrf_twim_address_set(p_twim, p_xfer_desc->address); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); -void nrf_drv_twi_enable(nrf_drv_twi_t const * const p_instance) -{ - ASSERT(m_cb[p_instance->instance_id].state == NRF_DRV_STATE_INITIALIZED); + twim_list_enable_handle(p_twim, flags); + switch (p_xfer_desc->type) + { + case NRF_DRV_TWI_XFER_TXTX: + ASSERT(!(flags & NRF_DRV_TWI_FLAG_REPEATED_XFER)); + ASSERT(!(flags & NRF_DRV_TWI_FLAG_HOLD_XFER)); + ASSERT(!(flags & NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER)); + if (!nrf_drv_is_in_RAM(p_xfer_desc->p_secondary_buf)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK); + nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); + while (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_TXSTARTED)) + {} + NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_TXSTARTED)); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_TXSTARTED); + nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length); + p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK; + break; + case NRF_DRV_TWI_XFER_TXRX: + nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); + if (!nrf_drv_is_in_RAM(p_xfer_desc->p_secondary_buf)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length); + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STARTRX_MASK | + NRF_TWIM_SHORT_LASTRX_STOP_MASK); + p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; + break; + case NRF_DRV_TWI_XFER_TX: + nrf_twim_tx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); + if (NRF_DRV_TWI_FLAG_TX_NO_STOP & flags) + { + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_SUSPEND_MASK); + p_cb->int_mask = NRF_TWIM_INT_SUSPENDED_MASK | NRF_TWIM_INT_ERROR_MASK; + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); + evt_to_wait = NRF_TWIM_EVENT_SUSPENDED; + } + else + { + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK); + p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; + } + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + break; + case NRF_DRV_TWI_XFER_RX: + nrf_twim_rx_buffer_set(p_twim, p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length); + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTRX_STOP_MASK); + p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; + start_task = NRF_TWIM_TASK_STARTRX; + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + break; + default: + err_code = NRF_ERROR_INVALID_PARAM; + break; + } - nrf_twi_event_clear(p_instance->p_reg, NRF_TWI_EVENTS_STOPPED); - nrf_twi_event_clear(p_instance->p_reg, NRF_TWI_EVENTS_RXDREADY); - nrf_twi_event_clear(p_instance->p_reg, NRF_TWI_EVENTS_TXDSENT); - nrf_twi_event_clear(p_instance->p_reg, NRF_TWI_EVENTS_ERROR); + if (!(flags & NRF_DRV_TWI_FLAG_HOLD_XFER) && (p_xfer_desc->type != NRF_DRV_TWI_XFER_TXTX)) + { + nrf_twim_task_trigger(p_twim, start_task); + } - if (m_handlers[p_instance->instance_id]) + if (p_cb->handler) { - nrf_twi_int_enable(p_instance->p_reg, NRF_TWI_INT_ERROR_MASK); + if (flags & NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER) + { + p_cb->int_mask = NRF_TWIM_INT_ERROR_MASK; + } + nrf_twim_int_enable(p_twim, p_cb->int_mask); } + else + { + while (!nrf_twim_event_check(p_twim, evt_to_wait)) + { + if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR)) + { + NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR)); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP); + evt_to_wait = NRF_TWIM_EVENT_STOPPED; + } + } - nrf_twi_enable(p_instance->p_reg); - m_cb[p_instance->instance_id].state = NRF_DRV_STATE_POWERED_ON; - m_cb[p_instance->instance_id].substate = NRF_DRV_TWI_SUBSTATE_IDLE; -} + uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim); + p_cb->busy = false; + + if (errorsrc) + { + err_code = twi_process_error(errorsrc); + } + } + return err_code; +} +#endif -void nrf_drv_twi_disable(nrf_drv_twi_t const * const p_instance) +ret_code_t nrf_drv_twi_xfer(nrf_drv_twi_t const * p_instance, + nrf_drv_twi_xfer_desc_t const * p_xfer_desc, + uint32_t flags) { - ASSERT(m_cb[p_instance->instance_id].state != NRF_DRV_STATE_UNINITIALIZED); - nrf_twi_task_set(p_instance->p_reg, NRF_TWI_TASKS_STOP); - nrf_twi_disable(p_instance->p_reg); - nrf_twi_int_disable(p_instance->p_reg, DISABLE_MASK); - m_cb[p_instance->instance_id].state = NRF_DRV_STATE_INITIALIZED; -} + ret_code_t err_code = NRF_SUCCESS; + twi_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + + // TXRX and TXTX transfers are support only in non-blocking mode. + ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRF_DRV_TWI_XFER_TXRX))); + ASSERT( !((p_cb->handler == NULL) && (p_xfer_desc->type == NRF_DRV_TWI_XFER_TXTX))); + + NRF_LOG_INFO("Transfer type: %s.\r\n", (uint32_t)TRANSFER_TO_STR(p_xfer_desc->type)); + NRF_LOG_INFO("Transfer buffers length: primary: %d, secondary: %d.\r\n", p_xfer_desc->primary_length, p_xfer_desc->secondary_length); + NRF_LOG_DEBUG("Primary buffer data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_xfer_desc->p_primary_buf, p_xfer_desc->primary_length * sizeof(p_xfer_desc->p_primary_buf)); + NRF_LOG_DEBUG("Secondary buffer data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_xfer_desc->p_secondary_buf, p_xfer_desc->secondary_length * sizeof(p_xfer_desc->p_secondary_buf)); + + CODE_FOR_TWIM + ( + + err_code = twim_xfer(p_cb, (NRF_TWIM_Type *)p_instance->reg.p_twim, p_xfer_desc, flags); + ) + CODE_FOR_TWI + ( + if ( (NRF_DRV_TWI_FLAG_TX_POSTINC | NRF_DRV_TWI_FLAG_RX_POSTINC) & flags) + { + err_code = NRF_ERROR_NOT_SUPPORTED; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + err_code = twi_xfer(p_cb, (NRF_TWI_Type *)p_instance->reg.p_twi, p_xfer_desc, flags); + ) + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} -ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * const p_instance, - uint8_t address, - uint8_t const * p_data, - uint32_t length, - bool xfer_pending) +ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance, + uint8_t address, + uint8_t const * p_data, + uint8_t length, + bool no_stop) { - return twi_transfer(p_instance, address, - p_data, length, - xfer_pending, true); -} + nrf_drv_twi_xfer_desc_t xfer = NRF_DRV_TWI_XFER_DESC_TX(address, (uint8_t*)p_data, length); + return nrf_drv_twi_xfer(p_instance, &xfer, no_stop ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0); +} -ret_code_t nrf_drv_twi_rx(nrf_drv_twi_t const * const p_instance, - uint8_t address, - uint8_t * p_data, - uint32_t length, - bool xfer_pending) +ret_code_t nrf_drv_twi_rx(nrf_drv_twi_t const * p_instance, + uint8_t address, + uint8_t * p_data, + uint8_t length) { - return twi_transfer(p_instance, address, - p_data, length, - xfer_pending, false); + nrf_drv_twi_xfer_desc_t xfer = NRF_DRV_TWI_XFER_DESC_RX(address, p_data, length); + return nrf_drv_twi_xfer(p_instance, &xfer, 0); } - uint32_t nrf_drv_twi_data_count_get(nrf_drv_twi_t const * const p_instance) { - volatile transfer_t * p_transfer = &(m_cb[p_instance->instance_id].transfer); - - return p_transfer->count; + CODE_FOR_TWIM + ( + ASSERT(false); + return 0; + ) + CODE_FOR_TWI + ( + return m_cb[p_instance->drv_inst_idx].bytes_transferred; + ) +} +uint32_t nrf_drv_twi_start_task_get(nrf_drv_twi_t const * p_instance, nrf_drv_twi_xfer_type_t xfer_type) +{ + CODE_FOR_TWIM + ( + return (uint32_t)nrf_twim_task_address_get(p_instance->reg.p_twim, + (xfer_type != NRF_DRV_TWI_XFER_RX) ? NRF_TWIM_TASK_STARTTX : NRF_TWIM_TASK_STARTRX); + ) + CODE_FOR_TWI + ( + return (uint32_t)nrf_twi_task_address_get(p_instance->reg.p_twi, + (xfer_type != NRF_DRV_TWI_XFER_RX) ? NRF_TWI_TASK_STARTTX : NRF_TWI_TASK_STARTRX); + ) } +uint32_t nrf_drv_twi_stopped_event_get(nrf_drv_twi_t const * p_instance) +{ + CODE_FOR_TWIM + ( + return (uint32_t)nrf_twim_event_address_get(p_instance->reg.p_twim, NRF_TWIM_EVENT_STOPPED); + ) + CODE_FOR_TWI + ( + return (uint32_t)nrf_twi_event_address_get(p_instance->reg.p_twi, NRF_TWI_EVENT_STOPPED); + ) +} -/**@brief Generic function for handling TWI interrupt - * - * @param[in] p_reg Pointer to instance register structure. - * @param[in] instance_id Index of instance. - */ -__STATIC_INLINE void nrf_drv_twi_int_handler(NRF_TWI_Type * p_reg, uint32_t instance_id) +#ifdef TWIM_IN_USE +static void irq_handler_twim(NRF_TWIM_Type * p_twim, twi_control_block_t * p_cb) { - control_block_t * p_cb = &m_cb[instance_id]; - transfer_t * p_transfer = &p_cb->transfer; - sm_evt_t sm_event; + ASSERT(p_cb->handler); + + if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_ERROR)) + { + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_ERROR); + NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_ERROR)); + if (!nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED)) + { + nrf_twim_int_disable(p_twim, p_cb->int_mask); + p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK; + nrf_twim_int_enable(p_twim, p_cb->int_mask); + + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STOP); + return; + } + } + + nrf_drv_twi_evt_t event; + + if (nrf_twim_event_check(p_twim, NRF_TWIM_EVENT_STOPPED)) + { + NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_STOPPED)); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_STOPPED); + event.xfer_desc = p_cb->xfer_desc; + if (p_cb->error) + { + + event.xfer_desc.primary_length = (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_RX) ? + (uint8_t)nrf_twim_rxd_amount_get(p_twim) : (uint8_t)nrf_twim_txd_amount_get(p_twim); + event.xfer_desc.secondary_length = (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX) ? + (uint8_t)nrf_twim_rxd_amount_get(p_twim) : (uint8_t)nrf_twim_txd_amount_get(p_twim); + + } + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTTX); + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_LASTRX); + if (!p_cb->repeated || p_cb->error) + { + nrf_twim_shorts_set(p_twim, 0); + p_cb->int_mask = 0; + nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT); + } + } + else + { + nrf_twim_event_clear(p_twim, NRF_TWIM_EVENT_SUSPENDED); + NRF_LOG_DEBUG("TWIM: Event: %s.\r\n", (uint32_t)EVT_TO_STR_TWIM(NRF_TWIM_EVENT_SUSPENDED)); + if (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TX) + { + event.xfer_desc = p_cb->xfer_desc; + if (!p_cb->repeated) + { + nrf_twim_shorts_set(p_twim, 0); + p_cb->int_mask = 0; + nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT); + } + } + else + { + nrf_twim_shorts_set(p_twim, NRF_TWIM_SHORT_LASTTX_STOP_MASK); + p_cb->int_mask = NRF_TWIM_INT_STOPPED_MASK | NRF_TWIM_INT_ERROR_MASK; + nrf_twim_int_disable(p_twim, DISABLE_ALL_INT_SHORT); + nrf_twim_int_enable(p_twim, p_cb->int_mask); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_STARTTX); + nrf_twim_task_trigger(p_twim, NRF_TWIM_TASK_RESUME); + return; + } + } + + uint32_t errorsrc = nrf_twim_errorsrc_get_and_clear(p_twim); + if (errorsrc & NRF_TWIM_ERROR_ADDRESS_NACK) + { + event.type = NRF_DRV_TWI_EVT_ADDRESS_NACK; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_ADDRESS_NACK)); + } + else if (errorsrc & NRF_TWIM_ERROR_DATA_NACK) + { + event.type = NRF_DRV_TWI_EVT_DATA_NACK; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DATA_NACK)); + } + else + { + event.type = NRF_DRV_TWI_EVT_DONE; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DONE)); + } + + if (!p_cb->repeated) + { + p_cb->busy = false; + } + p_cb->handler(&event, p_cb->p_context); +} +#endif // TWIM_IN_USE - bool error_occured = nrf_twi_event_check(p_reg, NRF_TWI_EVENTS_ERROR); - bool end_evt_occured = nrf_twi_event_check(p_reg, p_transfer->end_event); +#ifdef TWI_IN_USE +static void irq_handler_twi(NRF_TWI_Type * p_twi, twi_control_block_t * p_cb) +{ + ASSERT(p_cb->handler); - nrf_twi_event_clear(p_reg, NRF_TWI_EVENTS_ERROR); - nrf_twi_event_clear(p_reg, NRF_TWI_EVENTS_TXDSENT); - nrf_twi_event_clear(p_reg, NRF_TWI_EVENTS_RXDREADY); - nrf_twi_event_clear(p_reg, NRF_TWI_EVENTS_STOPPED); + if (twi_transfer(p_twi, &p_cb->error, &p_cb->bytes_transferred, p_cb->p_curr_buf, p_cb->curr_length, p_cb->curr_no_stop )) + { + return; + } - if (error_occured || end_evt_occured) + if (!p_cb->error && + ((p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXRX) || + (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXTX)) && + p_cb->p_curr_buf == p_cb->xfer_desc.p_primary_buf) { - if (error_occured) + p_cb->p_curr_buf = p_cb->xfer_desc.p_secondary_buf; + p_cb->curr_length = p_cb->xfer_desc.secondary_length; + p_cb->curr_no_stop = (p_cb->flags & NRF_DRV_TWI_FLAG_TX_NO_STOP); + + if (p_cb->xfer_desc.type == NRF_DRV_TWI_XFER_TXTX) { - sm_event = ON_ERROR; + (void)twi_tx_start_transfer(p_cb, p_twi, p_cb->p_curr_buf, p_cb->curr_length, p_cb->curr_no_stop); } else { - sm_event = p_transfer->is_tx ? TX_DONE : RX_DONE; + (void)twi_rx_start_transfer(p_cb, p_twi, p_cb->p_curr_buf, p_cb->curr_length); } - state_machine(m_instances[instance_id], sm_event); + } + else + { + nrf_drv_twi_evt_t event; + event.xfer_desc = p_cb->xfer_desc; - if (p_transfer->error_condition) + if (p_cb->error) { - p_cb->transfer_in_progress = false; - nrf_drv_twi_evt_t evt = + uint32_t errorsrc = nrf_twi_errorsrc_get_and_clear(p_twi); + if (errorsrc & NRF_TWI_ERROR_ADDRESS_NACK) + { + event.type = NRF_DRV_TWI_EVT_ADDRESS_NACK; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_ADDRESS_NACK)); + } + else if (errorsrc & NRF_TWI_ERROR_DATA_NACK) { - .type = NRF_DRV_TWI_ERROR, - .p_data = p_transfer->p_data, - .length = p_transfer->count, - // Driver uses shortcuts, so NRF_TWI_ERROR_OVERRUN_NACK will not take place. - .error_src = (nrf_twi_error_source_get(p_reg) & - NRF_TWI_ERROR_ADDRESS_NACK) ? NRF_TWI_ERROR_ADDRESS_NACK - : NRF_TWI_ERROR_DATA_NACK, - }; - m_handlers[instance_id](&evt, mp_contexts[instance_id]); + event.type = NRF_DRV_TWI_EVT_DATA_NACK; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DATA_NACK)); + } } - else if (p_transfer->count >= p_transfer->length) + else { - p_cb->transfer_in_progress = false; - nrf_drv_twi_evt_t evt = - { - .type = p_transfer->is_tx ? NRF_DRV_TWI_TX_DONE : NRF_DRV_TWI_RX_DONE, - .p_data = p_transfer->p_data, - .length = p_transfer->count, - }; - m_handlers[instance_id](&evt, mp_contexts[instance_id]); + event.type = NRF_DRV_TWI_EVT_DONE; + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_DRV_TWI_EVT_DONE)); + } + + p_cb->busy = false; + + if (!(NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER & p_cb->flags)) + { + p_cb->handler(&event, p_cb->p_context); } } -} +} +#endif // TWI_IN_USE -#if (TWI0_ENABLED == 1) -void SPI0_TWI0_IRQHandler(void) +#if NRF_MODULE_ENABLED(TWI0) +IRQ_HANDLER(0) { - nrf_drv_twi_int_handler(NRF_TWI0, TWI0_INSTANCE_INDEX); + #if (TWI0_USE_EASY_DMA == 1) + irq_handler_twim(NRF_TWIM0, + #else + irq_handler_twi(NRF_TWI0, + #endif + &m_cb[TWI0_INSTANCE_INDEX]); } -#endif // (TWI0_ENABLED == 1) +#endif // NRF_MODULE_ENABLED(TWI0) -#if (TWI1_ENABLED == 1) -void SPI1_TWI1_IRQHandler(void) +#if NRF_MODULE_ENABLED(TWI1) +IRQ_HANDLER(1) { - nrf_drv_twi_int_handler(NRF_TWI1, TWI1_INSTANCE_INDEX); + #if (TWI1_USE_EASY_DMA == 1) + irq_handler_twim(NRF_TWIM1, + #else + irq_handler_twi(NRF_TWI1, + #endif + &m_cb[TWI1_INSTANCE_INDEX]); } -#endif // (TWI1_ENABLED == 1) +#endif // NRF_MODULE_ENABLED(TWI1) +#endif // TWI_COUNT +#endif // NRF_MODULE_ENABLED(TWI) diff --git a/components/drivers_nrf/twi_master/nrf_drv_twi.h b/components/drivers_nrf/twi_master/nrf_drv_twi.h index 2c374d2..7c492e9 100644 --- a/components/drivers_nrf/twi_master/nrf_drv_twi.h +++ b/components/drivers_nrf/twi_master/nrf_drv_twi.h @@ -1,227 +1,429 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * @addtogroup nrf_twi Two Wire master interface (TWI/TWIM) + * @ingroup nrf_drivers + * @brief Two Wire master interface (TWI/TWIM) APIs. * - * 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. * + * @defgroup nrf_drv_twi TWIS driver + * @{ + * @ingroup nrf_twi + * @brief TWI master APIs. */ - #ifndef NRF_DRV_TWI_H__ #define NRF_DRV_TWI_H__ #include "nordic_common.h" -#include "nrf_drv_config.h" -#include "nrf_drv_common.h" +#include "sdk_config.h" + +// This set of macros makes it possible to exclude parts of code when one type +// of supported peripherals is not used. +#if ((TWI0_ENABLED == 1 && TWI0_USE_EASY_DMA == 1) || \ + (TWI1_ENABLED == 1 && TWI1_USE_EASY_DMA == 1)) + #define TWIM_IN_USE +#endif +#if ((TWI0_ENABLED == 1 && TWI0_USE_EASY_DMA != 1) || \ + (TWI1_ENABLED == 1 && TWI1_USE_EASY_DMA != 1)) + #define TWI_IN_USE +#endif + #include "nrf_twi.h" +#ifdef TWIM_IN_USE + #include "nrf_twim.h" +#endif #include "sdk_errors.h" -#define TWI0_IRQ SPI0_TWI0_IRQn -#define TWI1_IRQ SPI1_TWI1_IRQn +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(TWIM_IN_USE) + #define NRF_DRV_TWI_PERIPHERAL(id) \ + (CONCAT_3(TWI, id, _USE_EASY_DMA) == 1 ? \ + (void *)CONCAT_2(NRF_TWIM, id) \ + : (void *)CONCAT_2(NRF_TWI, id)) +#else + #define NRF_DRV_TWI_PERIPHERAL(id) (void *)CONCAT_2(NRF_TWI, id) +#endif + /** - * - * @defgroup nrf_twi Two-wire interface (TWI) - * @ingroup nrf_drivers - * @brief Two-wire interface (TWI) APIs. - * - * @defgroup nrf_twi_master TWI master HAL and driver - * @ingroup nrf_twi - * @brief TWI master APIs. - * @details The TWIM HAL provides basic APIs for accessing the registers of the TWI. - * The TWIM master driver provides APIs on a higher level. - * - * @defgroup nrf_twi_drv TWI master driver - * @{ - * @ingroup nrf_twi_master - * @brief Driver for managing the TWI. + * @brief Structure for the TWI master driver instance. */ +typedef struct +{ + union + { +#ifdef TWIM_IN_USE + NRF_TWIM_Type * p_twim; ///< Pointer to a structure with TWIM registers. +#endif + NRF_TWI_Type * p_twi; ///< Pointer to a structure with TWI registers. + } reg; + uint8_t drv_inst_idx; ///< Driver instance index. + bool use_easy_dma; ///< True if the peripheral with EasyDMA (TWIM) shall be used. +} nrf_drv_twi_t; + +#define TWI0_INSTANCE_INDEX 0 +#define TWI1_INSTANCE_INDEX TWI0_INSTANCE_INDEX+TWI0_ENABLED -/**@brief TWI events. */ +/** + * @brief Macro for creating a TWI master driver instance. + */ +#define NRF_DRV_TWI_INSTANCE(id) \ +{ \ + .reg = {NRF_DRV_TWI_PERIPHERAL(id)}, \ + .drv_inst_idx = CONCAT_3(TWI, id, _INSTANCE_INDEX), \ + .use_easy_dma = CONCAT_3(TWI, id, _USE_EASY_DMA) \ +} + +/** + * @brief Structure for the TWI master driver instance configuration. + */ +typedef struct +{ + uint32_t scl; ///< SCL pin number. + uint32_t sda; ///< SDA pin number. + nrf_twi_frequency_t frequency; ///< TWI frequency. + uint8_t interrupt_priority; ///< Interrupt priority. + bool clear_bus_init; ///< Clear bus during init. + bool hold_bus_uninit; ///< Hold pull up state on gpio pins after uninit. +} nrf_drv_twi_config_t; + +/** + * @brief TWI master driver instance default configuration. + */ +#define NRF_DRV_TWI_DEFAULT_CONFIG \ +{ \ + .frequency = (nrf_twi_frequency_t)TWI_DEFAULT_CONFIG_FREQUENCY, \ + .scl = 31, \ + .sda = 31, \ + .interrupt_priority = TWI_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .clear_bus_init = TWI_DEFAULT_CONFIG_CLR_BUS_INIT, \ + .hold_bus_uninit = TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT, \ +} + +#define NRF_DRV_TWI_FLAG_TX_POSTINC (1UL << 0) /**< TX buffer address incremented after transfer. */ +#define NRF_DRV_TWI_FLAG_RX_POSTINC (1UL << 1) /**< RX buffer address incremented after transfer. */ +#define NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER (1UL << 2) /**< Interrupt after each transfer is suppressed, and the event handler is not called. */ +#define NRF_DRV_TWI_FLAG_HOLD_XFER (1UL << 3) /**< Set up the transfer but do not start it. */ +#define NRF_DRV_TWI_FLAG_REPEATED_XFER (1UL << 4) /**< Flag indicating that the transfer will be executed multiple times. */ +#define NRF_DRV_TWI_FLAG_TX_NO_STOP (1UL << 5) /**< Flag indicating that the TX transfer will not end with a stop condition. */ + +/** + * @brief TWI master driver event types. + */ typedef enum { - NRF_DRV_TWI_RX_DONE, - NRF_DRV_TWI_TX_DONE, - NRF_DRV_TWI_ERROR + NRF_DRV_TWI_EVT_DONE, ///< Transfer completed event. + NRF_DRV_TWI_EVT_ADDRESS_NACK, ///< Error event: NACK received after sending the address. + NRF_DRV_TWI_EVT_DATA_NACK ///< Error event: NACK received after sending a data byte. } nrf_drv_twi_evt_type_t; -/**@brief Structure for a TWI event. */ -typedef struct +/** + * @brief TWI master driver transfer types. + */ +typedef enum { - nrf_drv_twi_evt_type_t type; /**< Event type. */ - uint8_t * p_data; /**< Pointer to transferred data. */ - uint32_t length; /**< Number of bytes transferred. */ - nrf_twi_error_t error_src; /**< TWI error source (valid only for NRF_DRV_TWI_ERROR event). */ -} nrf_drv_twi_evt_t; + NRF_DRV_TWI_XFER_TX, ///< TX transfer. + NRF_DRV_TWI_XFER_RX, ///< RX transfer. + NRF_DRV_TWI_XFER_TXRX, ///< TX transfer followed by RX transfer with repeated start. + NRF_DRV_TWI_XFER_TXTX ///< TX transfer followed by TX transfer with repeated start. +} nrf_drv_twi_xfer_type_t; -/**@brief TWI driver instance structure. */ +/** + * @brief Structure for a TWI transfer descriptor. + */ typedef struct { - NRF_TWI_Type * p_reg; /**< Pointer to the instance register set. */ - IRQn_Type irq; /**< Instance IRQ ID. */ - uint8_t instance_id; /**< Instance index. */ -} nrf_drv_twi_t; + nrf_drv_twi_xfer_type_t type; ///< Type of transfer. + uint8_t address; ///< Slave address. + uint8_t primary_length; ///< Number of bytes transferred. + uint8_t secondary_length; ///< Number of bytes transferred. + uint8_t * p_primary_buf; ///< Pointer to transferred data. + uint8_t * p_secondary_buf; ///< Pointer to transferred data. +} nrf_drv_twi_xfer_desc_t; -/**@brief Macro for creating a TWI driver instance.*/ -#define NRF_DRV_TWI_INSTANCE(id) \ -{ \ - .p_reg = CONCAT_2(NRF_TWI, id), \ - .irq = CONCAT_3(TWI, id, _IRQ), \ - .instance_id = CONCAT_3(TWI, id, _INSTANCE_INDEX) \ -} -/**@brief Structure for TWI instance configuration. */ -typedef struct -{ - uint32_t scl; /**< SCL pin number. */ - uint32_t sda; /**< SDA pin number. */ - nrf_twi_frequency_t frequency; /**< Frequency. */ - uint8_t interrupt_priority; /**< Interrupt priority. */ -} nrf_drv_twi_config_t; +/**@brief Macro for setting the TX transfer descriptor. */ +#define NRF_DRV_TWI_XFER_DESC_TX(addr, p_data, length) \ + { \ + .type = NRF_DRV_TWI_XFER_TX, \ + .address = addr, \ + .primary_length = length, \ + .p_primary_buf = p_data, \ + } -/**@brief TWI instance default configuration. */ -#define NRF_DRV_TWI_DEFAULT_CONFIG(id) \ -{ \ - .frequency = CONCAT_3(TWI, id, _CONFIG_FREQUENCY), \ - .scl = CONCAT_3(TWI, id, _CONFIG_SCL), \ - .sda = CONCAT_3(TWI, id, _CONFIG_SDA), \ - .interrupt_priority = CONCAT_3(TWI, id, _CONFIG_IRQ_PRIORITY) \ -} +/**@brief Macro for setting the RX transfer descriptor. */ +#define NRF_DRV_TWI_XFER_DESC_RX(addr, p_data, length) \ + { \ + .type = NRF_DRV_TWI_XFER_RX, \ + .address = addr, \ + .primary_length = length, \ + .p_primary_buf = p_data, \ + } + +/**@brief Macro for setting the TXRX transfer descriptor. */ +#define NRF_DRV_TWI_XFER_DESC_TXRX(addr, p_tx, tx_len, p_rx, rx_len) \ + { \ + .type = NRF_DRV_TWI_XFER_TXRX, \ + .address = addr, \ + .primary_length = tx_len, \ + .secondary_length = rx_len, \ + .p_primary_buf = p_tx, \ + .p_secondary_buf = p_rx, \ + } + +/**@brief Macro for setting the TXTX transfer descriptor. */ +#define NRF_DRV_TWI_XFER_DESC_TXTX(addr, p_tx, tx_len, p_tx2, tx_len2) \ + { \ + .type = NRF_DRV_TWI_XFER_TXTX, \ + .address = addr, \ + .primary_length = tx_len, \ + .secondary_length = tx_len2, \ + .p_primary_buf = p_tx, \ + .p_secondary_buf = p_tx2, \ + } -/**@brief TWI event handler prototype. */ +/** + * @brief Structure for a TWI event. + */ +typedef struct +{ + nrf_drv_twi_evt_type_t type; ///< Event type. + nrf_drv_twi_xfer_desc_t xfer_desc; ///< Transfer details. +} nrf_drv_twi_evt_t; + +/** + * @brief TWI event handler prototype. + */ typedef void (* nrf_drv_twi_evt_handler_t)(nrf_drv_twi_evt_t const * p_event, void * p_context); /** - * @brief Function for initializing the TWI instance. + * @brief Function for initializing the TWI driver instance. * - * @param[in] p_instance TWI instance. + * @param[in] p_instance Pointer to the driver instance structure. * @param[in] p_config Initial configuration. If NULL, the default configuration is used. * @param[in] event_handler Event handler provided by the user. If NULL, blocking mode is enabled. - * @param[in] p_context Context pointer, passed to event handler. + * @param[in] p_context Context passed to event handler. * - * @retval NRF_SUCCESS If initialization was successful. - * @retval NRF_ERROR_INVALID_STATE If the driver is in invalid state. + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is in invalid state. + * @retval NRF_ERROR_BUSY If some other peripheral with the same + * instance ID is already in use. This is + * possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED + * is set to a value other than zero. */ -ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const * const p_instance, +ret_code_t nrf_drv_twi_init(nrf_drv_twi_t const * p_instance, nrf_drv_twi_config_t const * p_config, nrf_drv_twi_evt_handler_t event_handler, void * p_context); /** - * @brief Function for uninitializing the TWI. + * @brief Function for uninitializing the TWI instance. * - * @param[in] p_instance TWI instance. + * @param[in] p_instance Pointer to the driver instance structure. */ -void nrf_drv_twi_uninit(nrf_drv_twi_t const * const p_instance); +void nrf_drv_twi_uninit(nrf_drv_twi_t const * p_instance); /** * @brief Function for enabling the TWI instance. * - * @param[in] p_instance TWI instance. + * @param[in] p_instance Pointer to the driver instance structure. */ -void nrf_drv_twi_enable(nrf_drv_twi_t const * const p_instance); +void nrf_drv_twi_enable(nrf_drv_twi_t const * p_instance); /** * @brief Function for disabling the TWI instance. * - * @param[in] p_instance TWI instance. + * @param[in] p_instance Pointer to the driver instance structure. */ -void nrf_drv_twi_disable(nrf_drv_twi_t const * const p_instance); +void nrf_drv_twi_disable(nrf_drv_twi_t const * p_instance); /** * @brief Function for sending data to a TWI slave. * - * The transmission will be stopped when an error or time-out occurs. + * The transmission will be stopped when an error occurs. If a transfer is ongoing, + * the function returns the error code @ref NRF_ERROR_BUSY. * - * @param[in] p_instance TWI instance. - * @param[in] address Address of a specific slave device (only 7 LSB). - * @param[in] p_data Pointer to a transmit buffer. - * @param[in] length Number of bytes to send. - * @param[in] xfer_pending After a specified number of bytes, transmission will - * be suspended (if xfer_pending is set) or stopped (if not). + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] address Address of a specific slave device (only 7 LSB). + * @param[in] p_data Pointer to a transmit buffer. + * @param[in] length Number of bytes to send. + * @param[in] no_stop If set, the stop condition is not generated on the bus + * after the transfer has completed successfully (allowing + * for a repeated start in the next transfer). * - * @retval NRF_SUCCESS If the procedure was successful. - * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. - * @retval NRF_ERROR_INTERNAL If an @ref NRF_TWI_EVENTS_ERROR or a time-out has occurred (only in blocking mode). + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. + * @retval NRF_ERROR_INTERNAL If an error was detected by hardware. + * @retval NRF_ERROR_INVALID_ADDR If the EasyDMA is used and memory adress in not in RAM. + * @retval NRF_ERROR_DRV_TWI_ERR_ANACK If NACK received after sending the address. + * @retval NRF_ERROR_DRV_TWI_ERR_DNACK If NACK received after sending a data byte. */ -ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * const p_instance, - uint8_t address, - uint8_t const * p_data, - uint32_t length, - bool xfer_pending); +ret_code_t nrf_drv_twi_tx(nrf_drv_twi_t const * p_instance, + uint8_t address, + uint8_t const * p_data, + uint8_t length, + bool no_stop); /** * @brief Function for reading data from a TWI slave. * - * Transmission will be stopped when error or time-out occurs. + * The transmission will be stopped when an error occurs. If a transfer is ongoing, + * the function returns the error code @ref NRF_ERROR_BUSY. * - * @param[in] p_instance TWI instance. - * @param[in] address Address of a specific slave device (only 7 LSB). - * @param[in] p_data Pointer to a receive buffer. - * @param[in] length Number of bytes to be received. - * @param[in] xfer_pending After a specified number of bytes, transmission will - * be suspended (if xfer_pending is set) or stopped (if not). + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] address Address of a specific slave device (only 7 LSB). + * @param[in] p_data Pointer to a receive buffer. + * @param[in] length Number of bytes to be received. * - * @retval NRF_SUCCESS If the procedure was successful. - * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. - * @retval NRF_ERROR_INTERNAL If an @ref NRF_TWI_EVENTS_ERROR or a time-out has occured (only in blocking mode). + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. + * @retval NRF_ERROR_INTERNAL If an error was detected by hardware. + * @retval NRF_ERROR_DRV_TWI_ERR_OVERRUN If the unread data was replaced by new data + * @retval NRF_ERROR_DRV_TWI_ERR_ANACK If NACK received after sending the address. + * @retval NRF_ERROR_DRV_TWI_ERR_DNACK If NACK received after sending a data byte. */ -ret_code_t nrf_drv_twi_rx(nrf_drv_twi_t const * const p_instance, - uint8_t address, - uint8_t * p_data, - uint32_t length, - bool xfer_pending); +ret_code_t nrf_drv_twi_rx(nrf_drv_twi_t const * p_instance, + uint8_t address, + uint8_t * p_data, + uint8_t length); /** - * @brief Function for getting transferred data count. + * @brief Function for preparing a TWI transfer. + * + * The following transfer types can be configured (@ref nrf_drv_twi_xfer_desc_t::type): + * - @ref NRF_DRV_TWI_XFER_TXRX: Write operation followed by a read operation (without STOP condition in between). + * - @ref NRF_DRV_TWI_XFER_TXTX: Write operation followed by a write operation (without STOP condition in between). + * - @ref NRF_DRV_TWI_XFER_TX: Write operation (with or without STOP condition). + * - @ref NRF_DRV_TWI_XFER_RX: Read operation (with STOP condition). + * + * Additional options are provided using the flags parameter: + * - @ref NRF_DRV_TWI_FLAG_TX_POSTINC and @ref NRF_DRV_TWI_FLAG_RX_POSTINC: Post-incrementation of buffer addresses. Supported only by TWIM. + * - @ref NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER: No user event handler after transfer completion. In most cases, this also means no interrupt at the end of the transfer. + * - @ref NRF_DRV_TWI_FLAG_HOLD_XFER: Driver is not starting the transfer. Use this flag if the transfer is triggered externally by PPI. Supported only by TWIM. + * Use @ref nrf_drv_twi_start_task_get to get the address of the start task. + * - @ref NRF_DRV_TWI_FLAG_REPEATED_XFER: Prepare for repeated transfers. You can set up a number of transfers that will be triggered externally (for example by PPI). + * An example is a TXRX transfer with the options @ref NRF_DRV_TWI_FLAG_RX_POSTINC, @ref NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER, and @ref NRF_DRV_TWI_FLAG_REPEATED_XFER. + * After the transfer is set up, a set of transfers can be triggered by PPI that will read, for example, the same register of an + * external component and put it into a RAM buffer without any interrupts. @ref nrf_drv_twi_stopped_event_get can be used to get the + * address of the STOPPED event, which can be used to count the number of transfers. If @ref NRF_DRV_TWI_FLAG_REPEATED_XFER is used, + * the driver does not set the driver instance into busy state, so you must ensure that the next transfers are set up + * when TWIM is not active. Supported only by TWIM. + * - @ref NRF_DRV_TWI_FLAG_TX_NO_STOP: No stop condition after TX transfer. * - * @param[in] p_instance TWI instance. + * @note + * Some flag combinations are invalid: + * - @ref NRF_DRV_TWI_FLAG_TX_NO_STOP with @ref nrf_drv_twi_xfer_desc_t::type different than @ref NRF_DRV_TWI_XFER_TX + * - @ref NRF_DRV_TWI_FLAG_REPEATED_XFER with @ref nrf_drv_twi_xfer_desc_t::type set to @ref NRF_DRV_TWI_XFER_TXTX + * + * If @ref nrf_drv_twi_xfer_desc_t::type is set to @ref NRF_DRV_TWI_XFER_TX and the @ref NRF_DRV_TWI_FLAG_TX_NO_STOP and @ref NRF_DRV_TWI_FLAG_REPEATED_XFER + * flags are set, two tasks must be used to trigger a transfer: TASKS_RESUME followed by TASKS_STARTTX. If no stop condition is generated, + * TWIM is in SUSPENDED state. Therefore, it must be resumed before the transfer can be started. + * + * @note + * This function should be used only if the instance is configured to work in non-blocking mode. If the function is used in blocking mode, the driver asserts. + * @note If you are using this function with TWI, the only supported flag is @ref NRF_DRV_TWI_FLAG_TX_NO_STOP. All other flags require TWIM. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_xfer_desc Pointer to the transfer descriptor. + * @param[in] flags Transfer options (0 for default settings). + * + * @retval NRF_SUCCESS If the procedure was successful. + * @retval NRF_ERROR_BUSY If the driver is not ready for a new transfer. + * @retval NRF_ERROR_NOT_SUPPORTED If the provided parameters are not supported. + * @retval NRF_ERROR_INTERNAL If an error was detected by hardware. + * @retval NRF_ERROR_INVALID_ADDR If the EasyDMA is used and memory adress in not in RAM + * @retval NRF_ERROR_DRV_TWI_ERR_OVERRUN If the unread data was replaced by new data (TXRX and RX) + * @retval NRF_ERROR_DRV_TWI_ERR_ANACK If NACK received after sending the address. + * @retval NRF_ERROR_DRV_TWI_ERR_DNACK If NACK received after sending a data byte. + */ +ret_code_t nrf_drv_twi_xfer(nrf_drv_twi_t const * p_instance, + nrf_drv_twi_xfer_desc_t const * p_xfer_desc, + uint32_t flags); + +/** + * @brief Function for getting the transferred data count. + * + * This function provides valid results only in legacy mode. + * + * @param[in] p_instance Pointer to the driver instance structure. * * @return Data count. */ uint32_t nrf_drv_twi_data_count_get(nrf_drv_twi_t const * const p_instance); /** - * @brief Function for returning the address of a specific TWI task. + * @brief Function for returning the address of a TWI/TWIM start task. * - * @param[in] p_instance TWI instance. - * @param[in] task Task. + * This function should be used if @ref nrf_drv_twi_xfer was called with the flag @ref NRF_DRV_TWI_FLAG_HOLD_XFER. + * In that case, the transfer is not started by the driver, but it must be started externally by PPI. * - * @return Task address. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] xfer_type Transfer type used in the last call of the @ref nrf_drv_twi_xfer function. + * + * @return Start task address (TX or RX) depending on the value of xfer_type. */ -__STATIC_INLINE uint32_t nrf_drv_twi_task_address_get(nrf_drv_twi_t const * const p_instance, - nrf_twi_tasks_t task); +uint32_t nrf_drv_twi_start_task_get(nrf_drv_twi_t const * p_instance, nrf_drv_twi_xfer_type_t xfer_type); /** - * @brief Function for returning the address of a specific TWI event. + * @brief Function for returning the address of a STOPPED TWI/TWIM event. + * + * A STOPPED event can be used to detect the end of a transfer if the @ref NRF_DRV_TWI_FLAG_NO_XFER_EVT_HANDLER + * option is used. * - * @param[in] p_instance TWI instance. - * @param[in] event Event. + * @param[in] p_instance Pointer to the driver instance structure. * - * @return Event address. + * @return STOPPED event address. */ -__STATIC_INLINE uint32_t nrf_drv_twi_event_address_get(nrf_drv_twi_t const * const p_instance, - nrf_twi_events_t event); - -#ifndef SUPPRESS_INLINE_IMPLEMENTATION -__STATIC_INLINE uint32_t nrf_drv_twi_task_address_get(nrf_drv_twi_t const * const p_instance, - nrf_twi_tasks_t task) -{ - return (uint32_t)nrf_twi_task_address_get(p_instance->p_reg, task); -} - -__STATIC_INLINE uint32_t nrf_drv_twi_event_address_get(nrf_drv_twi_t const * const p_instance, - nrf_twi_events_t event) -{ - return (uint32_t)nrf_twi_event_address_get(p_instance->p_reg, event); -} -#endif // SUPPRESS_INLINE_IMPLEMENTATION +uint32_t nrf_drv_twi_stopped_event_get(nrf_drv_twi_t const * p_instance); /** *@} **/ + +#ifdef __cplusplus +} +#endif + #endif // NRF_DRV_TWI_H__ diff --git a/components/drivers_nrf/twis_slave/nrf_drv_twis.c b/components/drivers_nrf/twis_slave/nrf_drv_twis.c new file mode 100644 index 0000000..d70e00d --- /dev/null +++ b/components/drivers_nrf/twis_slave/nrf_drv_twis.c @@ -0,0 +1,942 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(TWIS) +#define ENABLED_TWIS_COUNT (TWIS0_ENABLED+TWIS1_ENABLED) +#if ENABLED_TWIS_COUNT +#include "nrf_drv_twis.h" +#include "nrf_assert.h" +#include "app_util_platform.h" +#include "compiler_abstraction.h" + +#define NRF_LOG_MODULE_NAME "TWIS" + +#if TWIS_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL TWIS_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR TWIS_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR TWIS_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_TWIS_EVENT_STOPPED ? "NRF_TWIS_EVENT_STOPPED" : \ + (event == NRF_TWIS_EVENT_ERROR ? "NRF_TWIS_EVENT_ERROR" : \ + (event == NRF_TWIS_EVENT_RXSTARTED ? "NRF_TWIS_EVENT_RXSTARTED" : \ + (event == NRF_TWIS_EVENT_TXSTARTED ? "NRF_TWIS_EVENT_TXSTARTED" : \ + (event == NRF_TWIS_EVENT_WRITE ? "NRF_TWIS_EVENT_WRITE" : \ + (event == NRF_TWIS_EVENT_READ ? "NRF_TWIS_EVENT_READ" : "UNKNOWN EVENT")))))) +#else //TWIS_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //TWIS_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + +/** + * @internal + * @ingroup lib_twis_drv + * @defgroup lib_twis_drv_ivars Software controlled TWI Slave internal variables + * + * Internal variables for TWIS. + * @{ + */ + +/** + * @brief Actual state of internal state machine + * + * Current substate of powered on state. + */ +typedef enum +{ + NRF_DRV_TWIS_SUBSTATE_IDLE, ///< No ongoing transmission + NRF_DRV_TWIS_SUBSTATE_READ_WAITING, ///< Read request received, waiting for data + NRF_DRV_TWIS_SUBSTATE_READ_PENDING, ///< Reading is actually pending (data sending) + NRF_DRV_TWIS_SUBSTATE_WRITE_WAITING, ///< Write request received, waiting for data buffer + NRF_DRV_TWIS_SUBSTATE_WRITE_PENDING, ///< Writing is actually pending (data receiving) +}nrf_drv_twis_substate_t; + +/** + * @brief Constant instance part + * + * Instance data that have not to change. + * It may be placed in FLASH memory. + */ +typedef struct +{ + NRF_TWIS_Type * const p_reg; ///< Peripheral registry address +} nrf_drv_twis_const_inst_t; + +/** + * @brief Variable instance part + * + * There are all informations for the instance that may change. + */ +typedef struct +{ + nrf_drv_state_t state; ///< Actual driver state + volatile nrf_drv_twis_substate_t substate; ///< Actual driver substate + nrf_drv_twis_event_handler_t ev_handler; ///< Event handler functiomn + volatile uint32_t error; ///< Internal error flags + /**< Internal copy of hardware errors flags merged + * with specific internal driver errors flags. + * + * @note This value can be changed in the interrupt + * and cleared in the main program. + * Always use Atomic load-store when updating + * this value in main loop. + */ +}nrf_drv_twis_var_inst_t; + + +/** The constant instance part implementation */ +static const nrf_drv_twis_const_inst_t m_const_inst[ENABLED_TWIS_COUNT] = +{ + #define X(n) { .p_reg = NRF_TWIS##n }, + #include "nrf_drv_twis_inst.def" +}; + +/** The variable instance part implementation */ +static nrf_drv_twis_var_inst_t m_var_inst[ENABLED_TWIS_COUNT] = +{ + #define X(n) { .state = NRF_DRV_STATE_UNINITIALIZED, \ + .substate = NRF_DRV_TWIS_SUBSTATE_IDLE, \ + .ev_handler = NULL, \ + .error = 0 }, + #include "nrf_drv_twis_inst.def" +}; + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + #define IRQ_HANDLER_NAME(n) irq_handler_for_instance_##n + #define IRQ_HANDLER(n) static void IRQ_HANDLER_NAME(n)(void) + + #if NRF_MODULE_ENABLED(TWIS0) + IRQ_HANDLER(0); + #endif + #if NRF_MODULE_ENABLED(TWIS1) + IRQ_HANDLER(1); + #endif + static nrf_drv_irq_handler_t const m_irq_handlers[ENABLED_TWIS_COUNT] = { + #if NRF_MODULE_ENABLED(TWIS0) + IRQ_HANDLER_NAME(0), + #endif + #if NRF_MODULE_ENABLED(TWIS1) + IRQ_HANDLER_NAME(1), + #endif + }; +#else + #define IRQ_HANDLER(n) \ + void SPIM##n##_SPIS##n##_TWIM##n##_TWIS##n##_SPI##n##_TWI##n##_IRQHandler(void) +#endif // NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + +/** + * @brief State processing semaphore + * + * There are semaphores used when when working in synchronous mode (without interrupts activated). + * @note + * In synchronous mode before every state checking the state machine is executed. + * But the situation where state checking function is called from main task and in the same from + * interrupt task has to be considered. + * In such a situation the @ref nrf_drv_twis_state_machine function may be interrupted by second + * call to the same function. + * If in this second call any event will be detected it may be lost because new substate would be + * overwritten when interrupted function finishes. + * In the same time information about event would be lost because it is cleared in interrupting + * function. + * @note + * To make situation described above safe, simple semaphore is implemented. + * It is just a binary flag that informs that state machine is actually executing and should not + * be processed in any interrupting function. + * Because of how it is used no atomic instructions are required to support this kind of semaphore. + * It is not waitable semaphore - function executed or not depending of its state. + */ +static uint8_t m_sm_semaphore[ENABLED_TWIS_COUNT]; + +/** + * @brief Used interrupts mask + * + * Mask for all interrupts used by this library + */ +static const uint32_t m_used_ints_mask = + NRF_TWIS_INT_STOPPED_MASK | + NRF_TWIS_INT_ERROR_MASK | + NRF_TWIS_INT_RXSTARTED_MASK | + NRF_TWIS_INT_TXSTARTED_MASK | + NRF_TWIS_INT_WRITE_MASK | + NRF_TWIS_INT_READ_MASK; + + +/** @} */ /* End of lib_driver_twis_slave_ivars */ + +/** + * @internal + * @ingroup lib_twis_drv + * @defgroup lib_twis_drv_ifunc Software controlled TWI Slave auxiliary internal functions + * + * Internal variables for TWIS. + * @{ + */ + +/** + * @brief Clear all events + * + * Function clears all actually pending events + */ +static void nrf_drv_twis_clear_all_events(NRF_TWIS_Type * const p_reg) +{ + /* Clear all events */ + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_STOPPED); + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_ERROR); + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_RXSTARTED); + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_TXSTARTED); + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_WRITE); + nrf_twis_event_clear(p_reg, NRF_TWIS_EVENT_READ); +} + +/** + * @brief Reset all the registers to known state + * + * This function clears all registers that requires it to known state. + * TWIS is left disabled after this function. + * All events are cleared. + * @param[out] p_reg TWIS to reset register address + */ +static inline void nrf_drv_twis_swreset(NRF_TWIS_Type * const p_reg) +{ + /* Disable TWIS */ + nrf_twis_disable(p_reg); + + /* Disconnect pins */ + nrf_twis_pins_set(p_reg, ~0U, ~0U); + + /* Disable interrupt global for the instance */ + nrf_drv_common_irq_disable(nrf_drv_get_IRQn(p_reg)); + + /* Disable interrupts */ + nrf_twis_int_disable(p_reg, ~0U); +} + +/** + * @brief Configure pin + * + * Function configures selected for work as SDA or SCL. + * @param pin Pin number to configure + */ +static inline void nrf_drv_twis_config_pin(uint32_t pin, nrf_gpio_pin_pull_t pull) +{ + nrf_gpio_cfg(pin, + NRF_GPIO_PIN_DIR_INPUT, + NRF_GPIO_PIN_INPUT_DISCONNECT, + pull, + NRF_GPIO_PIN_S0D1, + NRF_GPIO_PIN_NOSENSE); +} + +/** + * @brief Call event handler + * + * Function that calls event handler. + * The event handler would be only called if its value is != NULL. + * @param instNr Driver instance number that has called this runtime. + * @param[in] pev Event structure to pass to event handler + * @note + * Remember about possible multithreading. + * It is acceptable to call old event function if it was already disabled. + * What is unacceptable is jump into NULL pointer. + */ +static void nrf_drv_call_event_handler(uint8_t instNr, nrf_drv_twis_evt_t const * const pev) +{ + nrf_drv_twis_event_handler_t evh = m_var_inst[instNr].ev_handler; + if (NULL != evh) + { + evh(pev); + } +} + +/** + * @brief Auxiliary function for getting event state on right bit possition + * + * This function calls @ref nrf_twis_event_get function but the the result + * is shifted to match INTEN register scheme. + * + * @param[in,out] p_reg TWIS to read event from + * @param ev Event code + * + * @return Selected event state shifted by @ref nrf_drv_event_to_bitpos + * + * @sa nrf_twis_event_get + * @sa nrf_drv_event_to_bitpos + */ +static inline uint32_t nrf_drv_twis_event_bit_get(NRF_TWIS_Type * const p_reg, nrf_twis_event_t ev) +{ + return (uint32_t)nrf_twis_event_get_and_clear(p_reg, ev) << nrf_drv_event_to_bitpos(ev); +} + +/** + * @brief Auxiliary function for checking event bit inside given flags value + * + * Function used here to check presence of the event inside given flags value. + * It transforms given event to bit possition and then checks if in given variable it is cleared. + * + * @param flags Flags to test + * @param ev Event code + * + * @retval true Flag for selected event is set + * @retval false Flag for selected event is cleared + */ +static inline bool nrf_drv_twis_check_bit(uint32_t flags, nrf_twis_event_t ev) +{ + return 0 != (flags & (1U<TXD.PTR, evdata.data.tx_amount * sizeof(p_reg->TXD.PTR)); + nrf_drv_call_event_handler(instNr, &evdata); + /* Go to idle and repeat the state machine if READ or WRITE events detected. + * This time READ or WRITE would be started */ + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + ev = nrf_drv_twis_clear_bit(ev, NRF_TWIS_EVENT_STOPPED); + } + else + { + nrf_drv_twis_process_error(instNr, TWIS_EVT_READ_ERROR, nrf_twis_error_source_get_and_clear(p_reg)); + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + ev = 0; + } + break; + case NRF_DRV_TWIS_SUBSTATE_WRITE_WAITING: + if (nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_RXSTARTED) || + nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_WRITE) || + nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_READ) || + nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_STOPPED)) + { + substate = NRF_DRV_TWIS_SUBSTATE_WRITE_PENDING; + /* Any other bits requires further processing in PENDING substate */ + ev = nrf_drv_twis_clear_bit(ev, NRF_TWIS_EVENT_RXSTARTED); + } + else + { + nrf_drv_twis_process_error(instNr, TWIS_EVT_WRITE_ERROR, nrf_twis_error_source_get_and_clear(p_reg)); + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + ev = 0; + } + break; + case NRF_DRV_TWIS_SUBSTATE_WRITE_PENDING: + if (nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_WRITE)|| + nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_READ) || + nrf_drv_twis_check_bit(ev, NRF_TWIS_EVENT_STOPPED)) + { + evdata.type = TWIS_EVT_WRITE_DONE; + evdata.data.rx_amount = nrf_twis_rx_amount_get(p_reg); + nrf_drv_call_event_handler(instNr, &evdata); + /* Go to idle and repeat the state machine if READ or WRITE events detected. + * This time READ or WRITE would be started */ + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + ev = nrf_drv_twis_clear_bit(ev, NRF_TWIS_EVENT_STOPPED); + } + else + { + nrf_drv_twis_process_error(instNr, TWIS_EVT_WRITE_ERROR, nrf_twis_error_source_get_and_clear(p_reg)); + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + ev = 0; + } + break; + default: + substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + /* Do not clear any events and repeat the machine */ + break; + } + } + + m_var_inst[instNr].substate = substate; + if (!TWIS_NO_SYNC_MODE) + { + m_sm_semaphore[instNr] = 0; + } +} + +/** + * @brief This function + */ +static inline void nrf_drv_twis_preprocess_status(uint8_t instNr) +{ + if (!TWIS_NO_SYNC_MODE) + { + if (NULL == m_var_inst[instNr].ev_handler) + { + nrf_drv_twis_state_machine(instNr); + } + } +} + +/** + * @brief Interrupt service + * + * This function is called by all interrupts runtime for instances enabled in this library. + * @param instNr Driver instance number that has called this runtime. + */ +static inline void nrf_drv_twis_on_ISR(uint8_t instNr) +{ + nrf_drv_twis_state_machine(instNr); +} + +/** @} */ /* End of lib_driver_twis_slave_ifunc */ + + +/* ------------------------------------------------------------------------- + * Implementation of IRQ Handlers + */ +#define X(n) \ + IRQ_HANDLER(n) \ + { \ + nrf_drv_twis_on_ISR(TWIS##n##_INSTANCE_INDEX); \ + } +#include "nrf_drv_twis_inst.def" + +/* ------------------------------------------------------------------------- + * Implementation of interface functions + * + */ + + +ret_code_t nrf_drv_twis_init( + nrf_drv_twis_t const * const p_instance, + nrf_drv_twis_config_t const * p_config, + nrf_drv_twis_event_handler_t const event_handler) +{ + ASSERT(p_config); + ASSERT(p_config->scl != p_config->sda); + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + nrf_twis_config_addr_mask_t addr_mask = (nrf_twis_config_addr_mask_t)0; + ret_code_t err_code; + + if ( m_var_inst[instNr].state != NRF_DRV_STATE_UNINITIALIZED) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + if (nrf_drv_common_per_res_acquire(p_reg, m_irq_handlers[instNr]) != + NRF_SUCCESS) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } +#endif + + if (!TWIS_ASSUME_INIT_AFTER_RESET_ONLY) + { + nrf_drv_twis_swreset(p_reg); + } + + nrf_drv_twis_config_pin(p_config->scl, p_config->scl_pull); + nrf_drv_twis_config_pin(p_config->sda, p_config->sda_pull); + + if (0 == (p_config->addr[0] | p_config->addr[1])) + addr_mask = NRF_TWIS_CONFIG_ADDRESS0_MASK; + else + { + if (0 != p_config->addr[0]) + { + addr_mask |= NRF_TWIS_CONFIG_ADDRESS0_MASK; + } + if (0 != p_config->addr[1]) + { + addr_mask |= NRF_TWIS_CONFIG_ADDRESS1_MASK; + } + } + + /* Peripheral interrupt configure + * (note - interrupts still needs to be configured in INTEN register. + * This is done in enable function) */ + nrf_drv_common_irq_enable(nrf_drv_get_IRQn(p_reg), p_config->interrupt_priority); + + /* Configure */ + nrf_twis_pins_set (p_reg, p_config->scl, p_config->sda); + nrf_twis_address_set (p_reg, 0, p_config->addr[0]); + nrf_twis_address_set (p_reg, 1, p_config->addr[1]); + nrf_twis_config_address_set(p_reg, addr_mask); + + /* Clear semaphore */ + if (!TWIS_NO_SYNC_MODE) + { + m_sm_semaphore[instNr] = 0; + } + /* Set internal instance variables */ + m_var_inst[instNr].substate = NRF_DRV_TWIS_SUBSTATE_IDLE; + m_var_inst[instNr].ev_handler = event_handler; + m_var_inst[instNr].state = NRF_DRV_STATE_INITIALIZED; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +void nrf_drv_twis_uninit(nrf_drv_twis_t const * const p_instance) +{ + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + TWIS_PSEL_Type psel = p_reg->PSEL; + + ASSERT(m_var_inst[instNr].state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_drv_twis_swreset(p_reg); + + /* Clear pins state if */ + if (!(TWIS_PSEL_SCL_CONNECT_Msk & psel.SCL)) + { + nrf_gpio_cfg_default(psel.SCL); + } + if (!(TWIS_PSEL_SDA_CONNECT_Msk & psel.SDA)) + { + nrf_gpio_cfg_default(psel.SDA); + } + +#if NRF_MODULE_ENABLED(PERIPHERAL_RESOURCE_SHARING) + nrf_drv_common_per_res_release(p_reg); +#endif + + /* Clear variables */ + m_var_inst[instNr].ev_handler = NULL; + m_var_inst[instNr].state = NRF_DRV_STATE_UNINITIALIZED; +} + + +void nrf_drv_twis_enable(nrf_drv_twis_t const * const p_instance) +{ + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + nrf_drv_twis_var_inst_t * const p_var_inst = &m_var_inst[instNr]; + + ASSERT(m_var_inst[instNr].state == NRF_DRV_STATE_INITIALIZED); + + nrf_drv_twis_clear_all_events(p_reg); + + /* Enable interrupts */ + if (NULL != p_var_inst->ev_handler) + { + nrf_twis_int_enable(p_reg, m_used_ints_mask); + } + + nrf_twis_enable(p_reg); + p_var_inst->error = 0; + p_var_inst->state = NRF_DRV_STATE_POWERED_ON; + p_var_inst->substate = NRF_DRV_TWIS_SUBSTATE_IDLE; +} + + +void nrf_drv_twis_disable(nrf_drv_twis_t const * const p_instance) +{ + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + + ASSERT(m_var_inst[instNr].state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_twis_int_disable(p_reg, m_used_ints_mask); + + nrf_twis_disable(p_reg); + m_var_inst[instNr].state = NRF_DRV_STATE_INITIALIZED; +} + +/* ARM recommends not using the LDREX and STREX instructions in C code. + * This is because the compiler might generate loads and stores between + * LDREX and STREX, potentially clearing the exclusive monitor set by LDREX. + * This recommendation also applies to the byte, halfword, and doubleword + * variants LDREXB, STREXB, LDREXH, STREXH, LDREXD, and STREXD. + * + * This is the reason for the function below to be implemented in assembly. + */ +//lint -save -e578 +#if defined (__CC_ARM ) +static __ASM uint32_t nrf_drv_twis_error_get_and_clear_internal(uint32_t volatile * const perror) +{ + mov r3, r0 + mov r1, #0 +nrf_drv_twis_error_get_and_clear_internal_try + ldrex r0, [r3] + strex r2, r1, [r3] + cmp r2, r1 /* did this succeed? */ + bne nrf_drv_twis_error_get_and_clear_internal_try /* no – try again */ + bx lr +} +#elif defined ( __GNUC__ ) +static uint32_t nrf_drv_twis_error_get_and_clear_internal(uint32_t volatile * const perror) +{ + uint32_t ret; + uint32_t temp; + __ASM volatile( + " .syntax unified \n" + "nrf_drv_twis_error_get_and_clear_internal_try: \n" + " ldrex %[ret], [%[perror]] \n" + " strex %[temp], %[zero], [%[perror]] \n" + " cmp %[temp], %[zero] \n" + " bne nrf_drv_twis_error_get_and_clear_internal_try \n" + : /* Output */ + [ret]"=&l"(ret), + [temp]"=&l"(temp) + : /* Input */ + [zero]"l"(0), + [perror]"l"(perror) + ); + UNUSED_VARIABLE(temp); + return ret; +} +#elif defined ( __ICCARM__ ) +static uint32_t nrf_drv_twis_error_get_and_clear_internal(uint32_t volatile * const perror) +{ + uint32_t ret; + uint32_t temp; + __ASM volatile( + "1: \n" + " ldrex %[ret], [%[perror]] \n" + " strex %[temp], %[zero], [%[perror]] \n" + " cmp %[temp], %[zero] \n" + " bne.n 1b \n" + : /* Output */ + [ret]"=&l"(ret), + [temp]"=&l"(temp) + : /* Input */ + [zero]"l"(0), + [perror]"l"(perror) + ); + UNUSED_VARIABLE(temp); + return ret; +} +#else + #error Unknown compiler +#endif +//lint -restore + +uint32_t nrf_drv_twis_error_get_and_clear(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_var_inst_t * const p_var_inst = &m_var_inst[p_instance->instNr]; + nrf_drv_twis_preprocess_status(p_instance->instNr); + /* Make sure that access to error member is atomic + * so there is no bit that is cleared if it is not copied to local variable already. */ + return nrf_drv_twis_error_get_and_clear_internal(&p_var_inst->error); +} + + +ret_code_t nrf_drv_twis_tx_prepare( + nrf_drv_twis_t const * const p_instance, + void const * const p_buf, + size_t size) +{ + ret_code_t err_code = NRF_SUCCESS;; + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + nrf_drv_twis_var_inst_t * const p_var_inst = &m_var_inst[instNr]; + + /* Check power state*/ + if (p_var_inst->state != NRF_DRV_STATE_POWERED_ON) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + /* Check data address */ + if (!nrf_drv_is_in_RAM(p_buf)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + /* Check data size */ + if ((size & TWIS_TXD_MAXCNT_MAXCNT_Msk) != size) + { + err_code = NRF_ERROR_INVALID_LENGTH; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + nrf_twis_tx_prepare(p_reg, (uint8_t const *)p_buf, (nrf_twis_amount_t)size); + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + +} + + +size_t nrf_drv_twis_tx_amount(nrf_drv_twis_t const * const p_instance) +{ + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type const * const p_reg = m_const_inst[instNr].p_reg; + + return nrf_twis_tx_amount_get(p_reg); +} + + +ret_code_t nrf_drv_twis_rx_prepare( + nrf_drv_twis_t const * const p_instance, + void * const p_buf, + size_t size) +{ + ret_code_t err_code; + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type * const p_reg = m_const_inst[instNr].p_reg; + nrf_drv_twis_var_inst_t * const p_var_inst = &m_var_inst[instNr]; + + /* Check power state*/ + if (p_var_inst->state != NRF_DRV_STATE_POWERED_ON) + { + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + /* Check data address */ + if (!nrf_drv_is_in_RAM(p_buf)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + /* Check data size */ + if ((size & TWIS_RXD_MAXCNT_MAXCNT_Msk) != size) + { + err_code = NRF_ERROR_INVALID_LENGTH; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + nrf_twis_rx_prepare(p_reg, (uint8_t *)p_buf, (nrf_twis_amount_t)size); + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} + + +size_t nrf_drv_twis_rx_amount(nrf_drv_twis_t const * const p_instance) +{ + uint8_t instNr = p_instance->instNr; + NRF_TWIS_Type const * const p_reg = m_const_inst[instNr].p_reg; + + return nrf_twis_rx_amount_get(p_reg); +} + + +bool nrf_drv_twis_is_busy(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_preprocess_status(p_instance->instNr); + return NRF_DRV_TWIS_SUBSTATE_IDLE != m_var_inst[(p_instance->instNr)].substate; +} + +bool nrf_drv_twis_is_waiting_tx_buff(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_preprocess_status(p_instance->instNr); + return NRF_DRV_TWIS_SUBSTATE_READ_WAITING == m_var_inst[(p_instance->instNr)].substate; +} + +bool nrf_drv_twis_is_waiting_rx_buff(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_preprocess_status(p_instance->instNr); + return NRF_DRV_TWIS_SUBSTATE_WRITE_WAITING == m_var_inst[(p_instance->instNr)].substate; +} + +bool nrf_drv_twis_is_pending_tx(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_preprocess_status(p_instance->instNr); + return NRF_DRV_TWIS_SUBSTATE_READ_PENDING == m_var_inst[(p_instance->instNr)].substate; +} + +bool nrf_drv_twis_is_pending_rx(nrf_drv_twis_t const * const p_instance) +{ + nrf_drv_twis_preprocess_status(p_instance->instNr); + return NRF_DRV_TWIS_SUBSTATE_WRITE_PENDING == m_var_inst[(p_instance->instNr)].substate; +} +#endif // TWIS_COUNT +#endif // NRF_MODULE_ENABLED(TWIS) diff --git a/components/drivers_nrf/twis_slave/nrf_drv_twis.h b/components/drivers_nrf/twis_slave/nrf_drv_twis.h new file mode 100644 index 0000000..9989bfb --- /dev/null +++ b/components/drivers_nrf/twis_slave/nrf_drv_twis.h @@ -0,0 +1,396 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_TWIS_H__ +#define NRF_DRV_TWIS_H__ + +#include "sdk_config.h" +#include "nrf_drv_common.h" +#include "nrf_gpio.h" +#include "sdk_errors.h" +#include "nrf_twis.h" +#include +#include "app_util.h" + +#ifdef __cplusplus +extern "C" { +#endif +/**@file + * @addtogroup nrf_twis Two Wire slave interface (TWIS) + * @ingroup nrf_drivers + * @brief Two Wire slave interface (TWIS) APIs. + * + * + * @defgroup nrf_drv_twis TWIS driver + * @{ + * @ingroup nrf_twis + * @brief TWI slave APIs. + */ + +/** + * @brief Event callback function event definitions. + */ +typedef enum +{ + TWIS_EVT_READ_REQ, ///< Read request detected + /**< If there is no buffer prepared, buf_req flag in the even will be set. + Call then @ref nrf_drv_twis_tx_prepare to give parameters for buffer. + */ + TWIS_EVT_READ_DONE, ///< Read request has finished - free any data + TWIS_EVT_READ_ERROR, ///< Read request finished with error + TWIS_EVT_WRITE_REQ, ///< Write request detected + /**< If there is no buffer prepared, buf_req flag in the even will be set. + Call then @ref nrf_drv_twis_rx_prepare to give parameters for buffer. + */ + TWIS_EVT_WRITE_DONE, ///< Write request has finished - process data + TWIS_EVT_WRITE_ERROR, ///< Write request finished with error + TWIS_EVT_GENERAL_ERROR ///< Error that happens not inside WRITE or READ transaction +} nrf_drv_twis_evt_type_t; + +/** + * @brief TWIS driver instance structure + * + * @note We only need instance number here so we could really use just a number + * that would be send to every driver function. + * But for compatibility reason this number is inserted into the structure. + */ +typedef struct +{ + uint8_t instNr; /**< Instance number */ +}nrf_drv_twis_t; + +/** + * @brief TWIS driver event structure + */ +typedef struct +{ + nrf_drv_twis_evt_type_t type; ///< Event type + union + { + bool buf_req; ///< Flag for @ref TWIS_EVT_READ_REQ and @ref TWIS_EVT_WRITE_REQ + /**< Information if transmission buffer requires to be prepared */ + uint32_t tx_amount; ///< Data for @ref TWIS_EVT_READ_DONE + uint32_t rx_amount; ///< Data for @ref TWIS_EVT_WRITE_DONE + uint32_t error; ///< Data for @ref TWIS_EVT_GENERAL_ERROR + }data; +}nrf_drv_twis_evt_t; + +/** + * @brief TWI slave event callback function type. + * + * @param[in] p_event Event information structure. + */ +typedef void (*nrf_drv_twis_event_handler_t)(nrf_drv_twis_evt_t const * const p_event); + +/** + * @brief Structure for TWIS configuration + */ +typedef struct +{ + uint32_t addr[2]; //!< Set addresses that this slave should respond. Set 0 to disable. + uint32_t scl; //!< SCL pin number + nrf_gpio_pin_pull_t scl_pull; //!< SCL pin pull + uint32_t sda; //!< SDA pin number + nrf_gpio_pin_pull_t sda_pull; //!< SDA pin pull + uint8_t interrupt_priority; //!< The priority of interrupt for the module to set +}nrf_drv_twis_config_t; + +/** + * @brief Possible error sources + * + * This is flag enum - values from this enum can be connected using logical or operator. + * @note + * We could use directly @ref nrf_twis_error_t. Error type enum is redefined here becouse + * of possible future extension (eg. supporting timeouts and synchronous mode). + */ +typedef enum +{ + NRF_DRV_TWIS_ERROR_OVERFLOW = NRF_TWIS_ERROR_OVERFLOW, /**< RX buffer overflow detected, and prevented */ + NRF_DRV_TWIS_ERROR_DATA_NACK = NRF_TWIS_ERROR_DATA_NACK, /**< NACK sent after receiving a data byte */ + NRF_DRV_TWIS_ERROR_OVERREAD = NRF_TWIS_ERROR_OVERREAD, /**< TX buffer over-read detected, and prevented */ + NRF_DRV_TWIS_ERROR_UNEXPECTED_EVENT = 1 << 8 /**< Unexpected event detected by state machine */ +}nrf_drv_twis_error_t; + +/** + * @internal + * @brief Internal macro for creating TWIS driver instance + * + * Second level of indirection in creating the instance. + * Do not use this macro directly. + * Use @ref NRF_DRV_TWIS_INSTANCE instead. + */ +#define NRF_DRV_TWIS_INSTANCE_x(id) \ + { \ + TWIS##id##_INSTANCE_INDEX \ + } + +/** + * @brief Macro for creating TWIS driver instance + * + * @param[in] id Instance index. Use 0 for TWIS0 and 1 for TWIS1 + */ +#define NRF_DRV_TWIS_INSTANCE(id) NRF_DRV_TWIS_INSTANCE_x(id) + +#define TWIS0_INSTANCE_INDEX 0 +#define TWIS1_INSTANCE_INDEX TWIS0_INSTANCE_INDEX+TWIS0_ENABLED + +/** + * @brief Generate default configuration for TWIS driver instance + */ +#define NRF_DRV_TWIS_DEFAULT_CONFIG \ +{ \ + .addr = { TWIS_DEFAULT_CONFIG_ADDR0, TWIS_DEFAULT_CONFIG_ADDR1 }, \ + .scl = 31, \ + .scl_pull = (nrf_gpio_pin_pull_t)TWIS_DEFAULT_CONFIG_SCL_PULL, \ + .sda = 31, \ + .sda_pull = (nrf_gpio_pin_pull_t)TWIS_DEFAULT_CONFIG_SDA_PULL, \ + .interrupt_priority = TWIS_DEFAULT_CONFIG_IRQ_PRIORITY \ +} + +/** + * @brief Function for initializing the TWIS driver instance. + * + * Function initializes and enables TWIS driver. + * @attention After driver initialization enable it by @ref nrf_drv_twis_enable + * + * @param[in] p_instance Pointer to the driver instance structure. + * @attention @em p_instance has to be global object. + * It would be used by interrupts so make it sure that object + * would not be destroyed when function is leaving. + * @param[in] p_config Initial configuration. + * @param[in] event_handler Event handler provided by the user. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_INVALID_STATE If the driver is already initialized. + * @retval NRF_ERROR_BUSY If some other peripheral with the same + * instance ID is already in use. This is + * possible only if PERIPHERAL_RESOURCE_SHARING_ENABLED + * is set to a value other than zero. + */ +ret_code_t nrf_drv_twis_init( + nrf_drv_twis_t const * const p_instance, + nrf_drv_twis_config_t const * p_config, + nrf_drv_twis_event_handler_t const event_handler); + +/** + * @brief Function for uninitializing the TWIS driver instance. + * + * Function initializes the peripheral and resets all registers to default values. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @note + * It is safe to call nrf_drv_twis_uninit even before initialization. + * Actually @ref nrf_drv_twis_init function calls this function to + * make sure that TWIS state is known. + * @note + * If TWIS driver was in uninitialized state before calling this function, + * selected pins would not be reset to default configuration. + */ +void nrf_drv_twis_uninit(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Enable TWIS instance + * + * This function enables TWIS instance. + * Function defined if there is needs for dynamically enabling and disabling the peripheral. + * Use @ref nrf_drv_twis_enable and @ref nrf_drv_twis_disable functions. + * They do not change any configuration registers. + * + * @param p_instance Pointer to the driver instance structure. + */ +void nrf_drv_twis_enable(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Disable TWIS instance + * + * Disabling TWIS instance gives possibility to turn off the TWIS while + * holding configuration done by @ref nrf_drv_twis_init + * + * @param p_instance Pointer to the driver instance structure. + */ +void nrf_drv_twis_disable(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Get and clear last error flags + * + * Function gets information about errors. + * This is also the only possibility to exit from error substate of the internal state machine. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @return Error flags defined in @ref nrf_drv_twis_error_t + * @attention + * This function clears error state and flags. + */ +uint32_t nrf_drv_twis_error_get_and_clear(nrf_drv_twis_t const * const p_instance); + + +/** + * @brief Prepare data for sending + * + * This function should be used in response for @ref TWIS_EVT_READ_REQ event. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_buf Transmission buffer + * @attention Transmission buffer has to be placed in RAM. + * @param size Maximum number of bytes that master may read from buffer given. + * + * @retval NRF_SUCCESS Preparation finished properly + * @retval NRF_ERROR_INVALID_ADDR Given @em p_buf is not placed inside the RAM + * @retval NRF_ERROR_INVALID_LENGTH Wrong value in @em size parameter + * @retval NRF_ERROR_INVALID_STATE Module not initialized or not enabled + */ +ret_code_t nrf_drv_twis_tx_prepare( + nrf_drv_twis_t const * const p_instance, + void const * const p_buf, + size_t size); + +/** + * @brief Get number of transmitted bytes + * + * Function returns number of bytes sent. + * This function may be called after @ref TWIS_EVT_READ_DONE or @ref TWIS_EVT_READ_ERROR events. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @return Number of bytes sent. + */ +size_t nrf_drv_twis_tx_amount(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Prepare data for receiving + * + * This function should be used in response for @ref TWIS_EVT_WRITE_REQ event. + * + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_buf Buffer that would be filled with received data + * @attention Receiving buffer has to be placed in RAM. + * @param size Size of the buffer (maximum amount of data to receive) + * + * @retval NRF_SUCCESS Preparation finished properly + * @retval NRF_ERROR_INVALID_ADDR Given @em p_buf is not placed inside the RAM + * @retval NRF_ERROR_INVALID_LENGTH Wrong value in @em size parameter + * @retval NRF_ERROR_INVALID_STATE Module not initialized or not enabled + */ +ret_code_t nrf_drv_twis_rx_prepare( + nrf_drv_twis_t const * const p_instance, + void * const p_buf, + size_t size); + +/** + * @brief Get number of received bytes + * + * Function returns number of bytes received. + * This function may be called after @ref TWIS_EVT_WRITE_DONE or @ref TWIS_EVT_WRITE_ERROR events. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @return Number of bytes received. + */ +size_t nrf_drv_twis_rx_amount(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Function checks if driver is busy right now + * + * Actual driver substate is tested. + * If driver is in any other state than IDLE or ERROR this function returns true. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true Driver is in state other than ERROR or IDLE + * @retval false There is no transmission pending. + */ +bool nrf_drv_twis_is_busy(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Function checks if driver is waiting for tx buffer + * + * If this function returns true, it means that driver is stalled expecting + * of the @ref nrf_drv_twis_tx_prepare function call. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true Driver waits for @ref nrf_drv_twis_tx_prepare + * @retval false Driver is not in the state where it waits for preparing tx buffer. + */ +bool nrf_drv_twis_is_waiting_tx_buff(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Function checks if driver is waiting for rx buffer + * + * If this function returns true, it means that driver is staled expecting + * of the @ref nrf_drv_twis_rx_prepare function call. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true Driver waits for @ref nrf_drv_twis_rx_prepare + * @retval false Driver is not in the state where it waits for preparing rx buffer. + */ +bool nrf_drv_twis_is_waiting_rx_buff(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Check if driver is sending data + * + * If this function returns true, it means that there is ongoing output transmission. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true There is ongoing output transmission. + * @retval false Driver is in other state. + */ +bool nrf_drv_twis_is_pending_tx(nrf_drv_twis_t const * const p_instance); + +/** + * @brief Check if driver is receiving data + * + * If this function returns true, it means that there is ongoing input transmission. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true There is ongoing input transmission. + * @retval false Driver is in other state. + */ +bool nrf_drv_twis_is_pending_rx(nrf_drv_twis_t const * const p_instance); + +/** @} */ /* End of lib_twis_drv group */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_DRV_TWIS_H__ */ diff --git a/components/drivers_nrf/twis_slave/nrf_drv_twis_inst.def b/components/drivers_nrf/twis_slave/nrf_drv_twis_inst.def new file mode 100644 index 0000000..be40002 --- /dev/null +++ b/components/drivers_nrf/twis_slave/nrf_drv_twis_inst.def @@ -0,0 +1,20 @@ +/** + * @file + * @brief Xmacro file with contains enumeration of TWIS instances to implement + * + * Use this file everywhere where anything has to be generated for all active TWIS instances. + * Xmacro format: + * + * @code + X(n) + * @endcode + * + * Where @em n is number of the instance itself (0 for NRF_TWIS0). + */ +#if (TWIS0_ENABLED == 1) + X(0) +#endif +#if (TWIS1_ENABLED == 1) + X(1) +#endif +#undef X diff --git a/components/drivers_nrf/uart/nrf_drv_uart.c b/components/drivers_nrf/uart/nrf_drv_uart.c index 164259c..bbaeda3 100644 --- a/components/drivers_nrf/uart/nrf_drv_uart.c +++ b/components/drivers_nrf/uart/nrf_drv_uart.c @@ -1,56 +1,83 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(UART) #include "nrf_drv_uart.h" #include "nrf_assert.h" -#include "nordic_common.h" #include "nrf_drv_common.h" #include "nrf_gpio.h" #include "app_util_platform.h" -// This set of macros makes it possible to exclude parts of code, when one type -// of supported peripherals is not used. -#ifdef NRF51 -#define UART_IN_USE -#elif defined(NRF52) -#if (UART_EASY_DMA_SUPPORT == 1) -#define UARTE_IN_USE -#endif -#if (UART_LEGACY_SUPPORT == 1) -#define UART_IN_USE -#endif -#endif +#define NRF_LOG_MODULE_NAME "UART" +#if UART_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL UART_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR UART_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR UART_CONFIG_DEBUG_COLOR +#define EVT_TO_STR(event) (event == NRF_UART_EVENT_ERROR ? "NRF_UART_EVENT_ERROR" : "UNKNOWN EVENT") +#else //UART_CONFIG_LOG_ENABLED +#define EVT_TO_STR(event) "" +#define NRF_LOG_LEVEL 0 +#endif //UART_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" #if (defined(UARTE_IN_USE) && defined(UART_IN_USE)) // UARTE and UART combined - #define CODE_FOR_UARTE(code) if (m_cb.use_easy_dma) { code } + #define CODE_FOR_UARTE(code) if (m_cb[p_instance->drv_inst_idx].use_easy_dma) { code } + #define CODE_FOR_UARTE_INT(idx, code) if (m_cb[idx].use_easy_dma) { code } #define CODE_FOR_UART(code) else { code } #elif (defined(UARTE_IN_USE) && !defined(UART_IN_USE)) // UARTE only #define CODE_FOR_UARTE(code) { code } + #define CODE_FOR_UARTE_INT(idx, code) { code } #define CODE_FOR_UART(code) #elif (!defined(UARTE_IN_USE) && defined(UART_IN_USE)) // UART only #define CODE_FOR_UARTE(code) + #define CODE_FOR_UARTE_INT(idx, code) #define CODE_FOR_UART(code) { code } #else #error "Wrong configuration." #endif -#ifndef IS_EASY_DMA_RAM_ADDRESS - #define IS_EASY_DMA_RAM_ADDRESS(addr) (((uint32_t)addr & 0xFFFF0000) == 0x20000000) -#endif - #define TX_COUNTER_ABORT_REQ_VALUE 256 typedef struct @@ -59,9 +86,11 @@ typedef struct nrf_uart_event_handler_t handler; uint8_t const * p_tx_buffer; uint8_t * p_rx_buffer; + uint8_t * p_rx_secondary_buffer; volatile uint16_t tx_counter; uint8_t tx_buffer_length; uint8_t rx_buffer_length; + uint8_t rx_secondary_buffer_length; volatile uint8_t rx_counter; bool rx_enabled; nrf_drv_state_t state; @@ -70,77 +99,107 @@ typedef struct #endif } uart_control_block_t; -static uart_control_block_t m_cb; -static const nrf_drv_uart_config_t m_default_config = NRF_DRV_UART_DEFAULT_CONFIG; +static uart_control_block_t m_cb[UART_ENABLED_COUNT]; -__STATIC_INLINE void apply_config(nrf_drv_uart_config_t const * p_config) +__STATIC_INLINE void apply_config(nrf_drv_uart_t const * p_instance, nrf_drv_uart_config_t const * p_config) { - nrf_gpio_cfg_output(p_config->pseltxd); - nrf_gpio_pin_set(p_config->pseltxd); - nrf_gpio_cfg_input(p_config->pselrxd, NRF_GPIO_PIN_NOPULL); + if (p_config->pseltxd != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_pin_set(p_config->pseltxd); + nrf_gpio_cfg_output(p_config->pseltxd); + } + if (p_config->pselrxd != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_input(p_config->pselrxd, NRF_GPIO_PIN_NOPULL); + } - CODE_FOR_UARTE( - nrf_uarte_baudrate_set(NRF_UARTE0, (nrf_uarte_baudrate_t)p_config->baudrate); - nrf_uarte_configure(NRF_UARTE0, (nrf_uarte_parity_t)p_config->parity, + CODE_FOR_UARTE + ( + nrf_uarte_baudrate_set(p_instance->reg.p_uarte, (nrf_uarte_baudrate_t)p_config->baudrate); + nrf_uarte_configure(p_instance->reg.p_uarte, (nrf_uarte_parity_t)p_config->parity, (nrf_uarte_hwfc_t)p_config->hwfc); - nrf_uarte_txrx_pins_set(NRF_UARTE0, p_config->pseltxd, p_config->pselrxd); + nrf_uarte_txrx_pins_set(p_instance->reg.p_uarte, p_config->pseltxd, p_config->pselrxd); if (p_config->hwfc == NRF_UART_HWFC_ENABLED) { - nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL); - nrf_gpio_cfg_output(p_config->pselrts); - nrf_gpio_pin_set(p_config->pselrts); - nrf_uarte_hwfc_pins_set(NRF_UARTE0, p_config->pselrts, p_config->pselcts); + if (p_config->pselcts != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL); + } + if (p_config->pselrts != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_pin_set(p_config->pselrts); + nrf_gpio_cfg_output(p_config->pselrts); + } + nrf_uarte_hwfc_pins_set(p_instance->reg.p_uarte, p_config->pselrts, p_config->pselcts); } ) - CODE_FOR_UART( - nrf_uart_baudrate_set(NRF_UART0, p_config->baudrate); - nrf_uart_configure(NRF_UART0, p_config->parity, p_config->hwfc); - nrf_uart_txrx_pins_set(NRF_UART0, p_config->pseltxd, p_config->pselrxd); + CODE_FOR_UART + ( + nrf_uart_baudrate_set(p_instance->reg.p_uart, p_config->baudrate); + nrf_uart_configure(p_instance->reg.p_uart, p_config->parity, p_config->hwfc); + nrf_uart_txrx_pins_set(p_instance->reg.p_uart, p_config->pseltxd, p_config->pselrxd); if (p_config->hwfc == NRF_UART_HWFC_ENABLED) { - nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL); - nrf_gpio_cfg_output(p_config->pselrts); - nrf_gpio_pin_set(p_config->pselrts); - nrf_uart_hwfc_pins_set(NRF_UART0, p_config->pselrts, p_config->pselcts); + if (p_config->pselcts != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_input(p_config->pselcts, NRF_GPIO_PIN_NOPULL); + } + if (p_config->pselrts != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_pin_set(p_config->pselrts); + nrf_gpio_cfg_output(p_config->pselrts); + } + nrf_uart_hwfc_pins_set(p_instance->reg.p_uart, p_config->pselrts, p_config->pselcts); } ) } -__STATIC_INLINE void interrupts_enable(uint8_t interrupt_priority) +__STATIC_INLINE void interrupts_enable(const nrf_drv_uart_t * p_instance, uint8_t interrupt_priority) { - CODE_FOR_UARTE( - nrf_uarte_int_enable(NRF_UARTE0, NRF_UARTE_INT_ENDRX_MASK | + CODE_FOR_UARTE + ( + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDTX); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ERROR); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_RXTO); + nrf_uarte_int_enable(p_instance->reg.p_uarte, NRF_UARTE_INT_ENDRX_MASK | NRF_UARTE_INT_ENDTX_MASK | NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_RXTO_MASK); + nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uarte), interrupt_priority); ) - CODE_FOR_UART( - nrf_uart_int_enable(NRF_UART0, NRF_UART_INT_MASK_TXDRDY | + CODE_FOR_UART + ( + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY); + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_RXTO); + nrf_uart_int_enable(p_instance->reg.p_uart, NRF_UART_INT_MASK_TXDRDY | NRF_UART_INT_MASK_RXTO); + nrf_drv_common_irq_enable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uart), interrupt_priority); ) - nrf_drv_common_irq_enable(UART0_IRQn, interrupt_priority); } -__STATIC_INLINE void interrupts_disable(void) +__STATIC_INLINE void interrupts_disable(const nrf_drv_uart_t * p_instance) { CODE_FOR_UARTE ( - nrf_uarte_int_disable(NRF_UARTE0, NRF_UARTE_INT_ENDRX_MASK | + nrf_uarte_int_disable(p_instance->reg.p_uarte, NRF_UARTE_INT_ENDRX_MASK | NRF_UARTE_INT_ENDTX_MASK | NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_RXTO_MASK); + nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uarte)); ) CODE_FOR_UART ( - nrf_uart_int_disable(NRF_UART0, NRF_UART_INT_MASK_RXDRDY | + nrf_uart_int_disable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_TXDRDY | NRF_UART_INT_MASK_ERROR | NRF_UART_INT_MASK_RXTO); + nrf_drv_common_irq_disable(nrf_drv_get_IRQn((void *)p_instance->reg.p_uart)); ) - nrf_drv_common_irq_disable(UART0_IRQn); + } -__STATIC_INLINE void pins_to_default(void) +__STATIC_INLINE void pins_to_default(const nrf_drv_uart_t * p_instance) { /* Reset pins to default states */ uint32_t txd; @@ -150,25 +209,32 @@ __STATIC_INLINE void pins_to_default(void) CODE_FOR_UARTE ( - txd = nrf_uarte_tx_pin_get(NRF_UARTE0); - rxd = nrf_uarte_rx_pin_get(NRF_UARTE0); - rts = nrf_uarte_rts_pin_get(NRF_UARTE0); - cts = nrf_uarte_cts_pin_get(NRF_UARTE0); - nrf_uarte_txrx_pins_disconnect(NRF_UARTE0); - nrf_uarte_hwfc_pins_disconnect(NRF_UARTE0); + txd = nrf_uarte_tx_pin_get(p_instance->reg.p_uarte); + rxd = nrf_uarte_rx_pin_get(p_instance->reg.p_uarte); + rts = nrf_uarte_rts_pin_get(p_instance->reg.p_uarte); + cts = nrf_uarte_cts_pin_get(p_instance->reg.p_uarte); + nrf_uarte_txrx_pins_disconnect(p_instance->reg.p_uarte); + nrf_uarte_hwfc_pins_disconnect(p_instance->reg.p_uarte); ) CODE_FOR_UART ( - txd = nrf_uart_tx_pin_get(NRF_UART0); - rxd = nrf_uart_rx_pin_get(NRF_UART0); - rts = nrf_uart_rts_pin_get(NRF_UART0); - cts = nrf_uart_cts_pin_get(NRF_UART0); - nrf_uart_txrx_pins_disconnect(NRF_UART0); - nrf_uart_hwfc_pins_disconnect(NRF_UART0); + txd = nrf_uart_tx_pin_get(p_instance->reg.p_uart); + rxd = nrf_uart_rx_pin_get(p_instance->reg.p_uart); + rts = nrf_uart_rts_pin_get(p_instance->reg.p_uart); + cts = nrf_uart_cts_pin_get(p_instance->reg.p_uart); + nrf_uart_txrx_pins_disconnect(p_instance->reg.p_uart); + nrf_uart_hwfc_pins_disconnect(p_instance->reg.p_uart); ) - nrf_gpio_cfg_default(txd); - nrf_gpio_cfg_default(rxd); + if (txd != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_default(txd); + } + + if (rxd != NRF_UART_PSEL_DISCONNECTED) + { + nrf_gpio_cfg_default(rxd); + } if (cts != NRF_UART_PSEL_DISCONNECTED) { @@ -182,502 +248,727 @@ __STATIC_INLINE void pins_to_default(void) } -__STATIC_INLINE void uart_enable(void) +__STATIC_INLINE void uart_enable(const nrf_drv_uart_t * p_instance) { - CODE_FOR_UARTE(nrf_uarte_enable(NRF_UARTE0);) - CODE_FOR_UART(nrf_uart_enable(NRF_UART0);); + CODE_FOR_UARTE(nrf_uarte_enable(p_instance->reg.p_uarte);) + CODE_FOR_UART(nrf_uart_enable(p_instance->reg.p_uart);); } -__STATIC_INLINE void uart_disable(void) +__STATIC_INLINE void uart_disable(const nrf_drv_uart_t * p_instance) { - CODE_FOR_UARTE(nrf_uarte_disable(NRF_UARTE0);) - CODE_FOR_UART(nrf_uart_disable(NRF_UART0);); + CODE_FOR_UARTE(nrf_uarte_disable(p_instance->reg.p_uarte);) + CODE_FOR_UART(nrf_uart_disable(p_instance->reg.p_uart);); } -ret_code_t nrf_drv_uart_init(nrf_drv_uart_config_t const * p_config, - nrf_uart_event_handler_t event_handler) +ret_code_t nrf_drv_uart_init(const nrf_drv_uart_t * p_instance, nrf_drv_uart_config_t const * p_config, + nrf_uart_event_handler_t event_handler) { - if (m_cb.state != NRF_DRV_STATE_UNINITIALIZED) - { - return NRF_ERROR_INVALID_STATE; - } + ASSERT(p_config); + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ret_code_t err_code = NRF_SUCCESS; - if (p_config == NULL) + if (p_cb->state != NRF_DRV_STATE_UNINITIALIZED) { - p_config = &m_default_config; + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } -#ifdef NRF52 - m_cb.use_easy_dma = p_config->use_easy_dma; + +#if (defined(UARTE_IN_USE) && defined(UART_IN_USE)) + p_cb->use_easy_dma = p_config->use_easy_dma; #endif - apply_config(p_config); + apply_config(p_instance, p_config); - m_cb.handler = event_handler; - m_cb.p_context = p_config->p_context; + p_cb->handler = event_handler; + p_cb->p_context = p_config->p_context; - if (m_cb.handler) + if (p_cb->handler) { - interrupts_enable(p_config->interrupt_priority); + interrupts_enable(p_instance, p_config->interrupt_priority); } - uart_enable(); - m_cb.rx_buffer_length = 0; - m_cb.tx_buffer_length = 0; - m_cb.state = NRF_DRV_STATE_INITIALIZED; - m_cb.rx_enabled = false; - return NRF_SUCCESS; + uart_enable(p_instance); + p_cb->rx_buffer_length = 0; + p_cb->rx_secondary_buffer_length = 0; + p_cb->tx_buffer_length = 0; + p_cb->state = NRF_DRV_STATE_INITIALIZED; + p_cb->rx_enabled = false; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } -void nrf_drv_uart_uninit(void) +void nrf_drv_uart_uninit(const nrf_drv_uart_t * p_instance) { - uart_disable(); + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - if (m_cb.handler) + uart_disable(p_instance); + + if (p_cb->handler) { - interrupts_disable(); + interrupts_disable(p_instance); } - pins_to_default(); + pins_to_default(p_instance); - m_cb.state = NRF_DRV_STATE_UNINITIALIZED; - m_cb.handler = NULL; + p_cb->state = NRF_DRV_STATE_UNINITIALIZED; + p_cb->handler = NULL; + NRF_LOG_INFO("Instance uninitialized: %d.\r\n", p_instance->drv_inst_idx); } -__STATIC_INLINE void tx_byte(void) +#if defined(UART_IN_USE) +__STATIC_INLINE void tx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb) { - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_TXDRDY); - uint8_t txd = m_cb.p_tx_buffer[m_cb.tx_counter]; - m_cb.tx_counter++; - nrf_uart_txd_set(NRF_UART0, txd); + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY); + uint8_t txd = p_cb->p_tx_buffer[p_cb->tx_counter]; + p_cb->tx_counter++; + nrf_uart_txd_set(p_uart, txd); } -#include "nrf_gpio.h" -ret_code_t nrf_drv_uart_tx(uint8_t const * const p_data, uint8_t length) +__STATIC_INLINE ret_code_t nrf_drv_uart_tx_for_uart(const nrf_drv_uart_t * p_instance) { - ASSERT(m_cb.state == NRF_DRV_STATE_INITIALIZED); - ASSERT(length>0); - ASSERT(p_data); - + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; ret_code_t err_code = NRF_SUCCESS; - //critical section begin - if (m_cb.tx_buffer_length != 0) - { - return NRF_ERROR_BUSY; - } - //critical section end - m_cb.tx_buffer_length = length; - m_cb.p_tx_buffer = p_data; - m_cb.tx_counter = 0; + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY); + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STARTTX); - CODE_FOR_UARTE - ( - // EasyDMA requires that transfer buffers are placed in DataRAM, - // signal error if the are not. - if (!IS_EASY_DMA_RAM_ADDRESS(p_data)) - { - return NRF_ERROR_INVALID_ADDR; - } - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ENDTX); - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_TXSTOPPED); - nrf_uarte_tx_buffer_set(NRF_UARTE0, p_data, length); - nrf_uarte_task_trigger(NRF_UARTE0, NRF_UARTE_TASK_STARTTX); + tx_byte(p_instance->reg.p_uart, p_cb); - if (m_cb.handler == NULL) + if (p_cb->handler == NULL) + { + while (p_cb->tx_counter < (uint16_t) p_cb->tx_buffer_length) { - bool endtx; - bool txstopped; - do { - endtx = nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_ENDTX); - txstopped = nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_TXSTOPPED); - }while ((endtx == false) && (txstopped == false)); - - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ENDTX); - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_TXSTOPPED); - if (txstopped) + while (!nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY) && + p_cb->tx_counter != TX_COUNTER_ABORT_REQ_VALUE) { - err_code = NRF_ERROR_FORBIDDEN; } - m_cb.tx_buffer_length = 0; + if (p_cb->tx_counter != TX_COUNTER_ABORT_REQ_VALUE) + { + tx_byte(p_instance->reg.p_uart, p_cb); + } } - ) - CODE_FOR_UART - ( - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_TXDRDY); - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STARTTX); - tx_byte(); - - if (m_cb.handler == NULL) + if (p_cb->tx_counter == TX_COUNTER_ABORT_REQ_VALUE) { - while ((uint16_t) m_cb.tx_buffer_length > m_cb.tx_counter) { - while (!nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY) && - m_cb.tx_counter != TX_COUNTER_ABORT_REQ_VALUE) {} - if (m_cb.tx_counter != TX_COUNTER_ABORT_REQ_VALUE) - { - tx_byte(); - } - } - - if (m_cb.tx_counter == TX_COUNTER_ABORT_REQ_VALUE) - { - err_code = NRF_ERROR_FORBIDDEN; - } - else + err_code = NRF_ERROR_FORBIDDEN; + } + else + { + while (!nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_TXDRDY)) { - while (!nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY)) {} - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STOPTX); } - m_cb.tx_buffer_length = 0; + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPTX); } - ) + p_cb->tx_buffer_length = 0; + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); return err_code; } +#endif -__STATIC_INLINE void rx_byte(void) +#if defined(UARTE_IN_USE) +__STATIC_INLINE ret_code_t nrf_drv_uart_tx_for_uarte(const nrf_drv_uart_t * p_instance) { - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXDRDY); - m_cb.p_rx_buffer[m_cb.rx_counter] = nrf_uart_rxd_get(NRF_UART0); - m_cb.rx_counter++; -} + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ret_code_t err_code = NRF_SUCCESS; -__STATIC_INLINE void rx_enable(void) -{ - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR); - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXDRDY); - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STARTRX); -} -ret_code_t nrf_drv_uart_rx(uint8_t * p_data, uint8_t length) -{ - ASSERT(m_cb.state == NRF_DRV_STATE_INITIALIZED); - ASSERT(length>0); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDTX); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED); + nrf_uarte_tx_buffer_set(p_instance->reg.p_uarte, p_cb->p_tx_buffer, p_cb->tx_buffer_length); + nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STARTTX); - //critical section begin - if (m_cb.rx_buffer_length != 0) + if (p_cb->handler == NULL) { - return NRF_ERROR_BUSY; + bool endtx; + bool txstopped; + do + { + endtx = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDTX); + txstopped = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED); + } + while ((!endtx) && (!txstopped)); + + if (txstopped) + { + err_code = NRF_ERROR_FORBIDDEN; + } + p_cb->tx_buffer_length = 0; } - //critical section end - m_cb.rx_buffer_length = length; - m_cb.p_rx_buffer = p_data; - m_cb.rx_counter = 0; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} +#endif + +ret_code_t nrf_drv_uart_tx(const nrf_drv_uart_t * p_instance, uint8_t const * const p_data, uint8_t length) +{ + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + ASSERT(p_cb->state == NRF_DRV_STATE_INITIALIZED); + ASSERT(length>0); + ASSERT(p_data); + + ret_code_t err_code; + CODE_FOR_UARTE ( // EasyDMA requires that transfer buffers are placed in DataRAM, // signal error if the are not. - if (!IS_EASY_DMA_RAM_ADDRESS(p_data)) + if (!nrf_drv_is_in_RAM(p_data)) { - return NRF_ERROR_INVALID_ADDR; + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ENDRX); - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_RXTO); - nrf_uarte_rx_buffer_set(NRF_UARTE0, p_data, length); - nrf_uarte_task_trigger(NRF_UARTE0, NRF_UARTE_TASK_STARTRX); + ) - if (m_cb.handler == NULL) - { - bool endrx; - bool rxto; - bool error; - do { - endrx = nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_ENDRX); - rxto = nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_RXTO); - error = nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_ERROR); - }while ((endrx == false) && (rxto == false) && (error == false)); - - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ENDRX); - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_RXTO); - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ERROR); - m_cb.rx_buffer_length = 0; - - if (error) - { - return NRF_ERROR_INTERNAL; - } + if (nrf_drv_uart_tx_in_progress(p_instance)) + { + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + p_cb->tx_buffer_length = length; + p_cb->p_tx_buffer = p_data; + p_cb->tx_counter = 0; - if (rxto) - { - return NRF_ERROR_FORBIDDEN; - } - } + NRF_LOG_INFO("Transfer tx_len: %d.\r\n", p_cb->tx_buffer_length); + NRF_LOG_DEBUG("Tx data:\r\n"); + NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_cb->p_tx_buffer, p_cb->tx_buffer_length * sizeof(p_cb->p_tx_buffer)); + + CODE_FOR_UARTE + ( + return nrf_drv_uart_tx_for_uarte(p_instance); ) CODE_FOR_UART ( - if (!m_cb.rx_enabled) - { - rx_enable(); - } - if (m_cb.handler == NULL) - { - bool rxrdy; - bool rxto; - bool error; - do { - do - { - error = nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_ERROR); - rxrdy = nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY); - rxto = nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXTO); - } while ((rxrdy == false) && (rxto == false) && (error == false)); + return nrf_drv_uart_tx_for_uart(p_instance); + ) +} - if (error || rxto) - { - break; - } - rx_byte(); - } while (m_cb.rx_buffer_length > m_cb.rx_counter); +bool nrf_drv_uart_tx_in_progress(const nrf_drv_uart_t * p_instance) +{ + return (m_cb[p_instance->drv_inst_idx].tx_buffer_length != 0); +} - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXTO); - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR); +#if defined(UART_IN_USE) +__STATIC_INLINE void rx_enable(const nrf_drv_uart_t * p_instance) +{ + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_ERROR); + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_RXDRDY); + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STARTRX); +} - m_cb.rx_buffer_length = 0; - if (error) - { - return NRF_ERROR_INTERNAL; - } +__STATIC_INLINE void rx_byte(NRF_UART_Type * p_uart, uart_control_block_t * p_cb) +{ + if (!p_cb->rx_buffer_length) + { + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY); + // Byte received when buffer is not set - data lost. + (void) nrf_uart_rxd_get(p_uart); + return; + } + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXDRDY); + p_cb->p_rx_buffer[p_cb->rx_counter] = nrf_uart_rxd_get(p_uart); + p_cb->rx_counter++; +} - if (rxto) - { - return NRF_ERROR_FORBIDDEN; - } +__STATIC_INLINE ret_code_t nrf_drv_uart_rx_for_uart(const nrf_drv_uart_t * p_instance, uint8_t * p_data, uint8_t length, bool second_buffer) +{ + ret_code_t err_code; + + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; - if (m_cb.rx_enabled) + if ((!p_cb->rx_enabled) && (!second_buffer)) + { + rx_enable(p_instance); + } + + if (p_cb->handler == NULL) + { + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_RXTO); + + bool rxrdy; + bool rxto; + bool error; + do + { + do { - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STARTRX); - } - else + error = nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_ERROR); + rxrdy = nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_RXDRDY); + rxto = nrf_uart_event_check(p_instance->reg.p_uart, NRF_UART_EVENT_RXTO); + } while ((!rxrdy) && (!rxto) && (!error)); + + if (error || rxto) { - // Skip stopping RX if driver is forced to be enabled. - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STOPRX); + break; } + rx_byte(p_instance->reg.p_uart, p_cb); + } while (p_cb->rx_buffer_length > p_cb->rx_counter); + + p_cb->rx_buffer_length = 0; + if (error) + { + err_code = NRF_ERROR_INTERNAL; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + if (rxto) + { + err_code = NRF_ERROR_FORBIDDEN; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + + if (p_cb->rx_enabled) + { + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STARTRX); } else { - nrf_uart_int_enable(NRF_UART0, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + // Skip stopping RX if driver is forced to be enabled. + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPRX); } - ) + } + else + { + nrf_uart_int_enable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + } + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; +} +#endif - return NRF_SUCCESS; +#if defined(UARTE_IN_USE) +__STATIC_INLINE ret_code_t nrf_drv_uart_rx_for_uarte(const nrf_drv_uart_t * p_instance, uint8_t * p_data, uint8_t length, bool second_buffer) +{ + ret_code_t err_code = NRF_SUCCESS; + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_RXTO); + nrf_uarte_rx_buffer_set(p_instance->reg.p_uarte, p_data, length); + if (!second_buffer) + { + nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STARTRX); + } + else + { + nrf_uarte_shorts_enable(p_instance->reg.p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX); + } + + if (m_cb[p_instance->drv_inst_idx].handler == NULL) + { + bool endrx; + bool rxto; + bool error; + do { + endrx = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ENDRX); + rxto = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_RXTO); + error = nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ERROR); + }while ((!endrx) && (!rxto) && (!error)); + + m_cb[p_instance->drv_inst_idx].rx_buffer_length = 0; + + if (error) + { + err_code = NRF_ERROR_INTERNAL; + } + + if (rxto) + { + err_code = NRF_ERROR_FORBIDDEN; + } + } + else + { + nrf_uarte_int_enable(p_instance->reg.p_uarte, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK); + } + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } +#endif -void nrf_drv_uart_rx_enable(void) +ret_code_t nrf_drv_uart_rx(const nrf_drv_uart_t * p_instance, uint8_t * p_data, uint8_t length) { - //Easy dma mode does not support enabling receiver without setting up buffer. + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + + ASSERT(m_cb[p_instance->drv_inst_idx].state == NRF_DRV_STATE_INITIALIZED); + ASSERT(length>0); + + ret_code_t err_code; + CODE_FOR_UARTE ( - ASSERT(!m_cb.use_easy_dma); + // EasyDMA requires that transfer buffers are placed in DataRAM, + // signal error if the are not. + if (!nrf_drv_is_in_RAM(p_data)) + { + err_code = NRF_ERROR_INVALID_ADDR; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } ) - if (!m_cb.rx_enabled) + bool second_buffer = false; + + if (p_cb->handler) + { + CODE_FOR_UARTE + ( + nrf_uarte_int_disable(p_instance->reg.p_uarte, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK); + ) + CODE_FOR_UART + ( + nrf_uart_int_disable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + ) + } + if (p_cb->rx_buffer_length != 0) + { + if (p_cb->rx_secondary_buffer_length != 0) + { + if (p_cb->handler) + { + CODE_FOR_UARTE + ( + nrf_uarte_int_enable(p_instance->reg.p_uarte, NRF_UARTE_INT_ERROR_MASK | NRF_UARTE_INT_ENDRX_MASK); + ) + CODE_FOR_UART + ( + nrf_uart_int_enable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + ) + } + err_code = NRF_ERROR_BUSY; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; + } + second_buffer = true; + } + + if (!second_buffer) + { + p_cb->rx_buffer_length = length; + p_cb->p_rx_buffer = p_data; + p_cb->rx_counter = 0; + p_cb->rx_secondary_buffer_length = 0; + } + else { - rx_enable(); - m_cb.rx_enabled = true; + p_cb->p_rx_secondary_buffer = p_data; + p_cb->rx_secondary_buffer_length = length; } + + NRF_LOG_INFO("Transfer rx_len: %d.\r\n", length); + + + CODE_FOR_UARTE + ( + return nrf_drv_uart_rx_for_uarte(p_instance, p_data, length, second_buffer); + ) + CODE_FOR_UART + ( + return nrf_drv_uart_rx_for_uart(p_instance, p_data, length, second_buffer); + ) } -void nrf_drv_uart_rx_disable(void) +void nrf_drv_uart_rx_enable(const nrf_drv_uart_t * p_instance) { //Easy dma mode does not support enabling receiver without setting up buffer. CODE_FOR_UARTE ( - ASSERT(!m_cb.use_easy_dma); + ASSERT(false); ) + CODE_FOR_UART + ( + if (!m_cb[p_instance->drv_inst_idx].rx_enabled) + { + rx_enable(p_instance); + m_cb[p_instance->drv_inst_idx].rx_enabled = true; + } + ) +} - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STOPRX); - m_cb.rx_enabled = false; +void nrf_drv_uart_rx_disable(const nrf_drv_uart_t * p_instance) +{ + //Easy dma mode does not support enabling receiver without setting up buffer. + CODE_FOR_UARTE + ( + ASSERT(false); + ) + CODE_FOR_UART + ( + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPRX); + m_cb[p_instance->drv_inst_idx].rx_enabled = false; + ) } -uint32_t nrf_drv_uart_errorsrc_get(void) +uint32_t nrf_drv_uart_errorsrc_get(const nrf_drv_uart_t * p_instance) { uint32_t errsrc; CODE_FOR_UARTE ( - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ERROR); - errsrc = nrf_uarte_errorsrc_get_and_clear(NRF_UARTE0); + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_ERROR); + errsrc = nrf_uarte_errorsrc_get_and_clear(p_instance->reg.p_uarte); ) CODE_FOR_UART ( - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR); - errsrc = nrf_uart_errorsrc_get_and_clear(NRF_UART0); + nrf_uart_event_clear(p_instance->reg.p_uart, NRF_UART_EVENT_ERROR); + errsrc = nrf_uart_errorsrc_get_and_clear(p_instance->reg.p_uart); ) return errsrc; } -__STATIC_INLINE void rx_done_event(uint8_t bytes) +__STATIC_INLINE void rx_done_event(uart_control_block_t * p_cb, uint8_t bytes, uint8_t * p_data) { nrf_drv_uart_event_t event; event.type = NRF_DRV_UART_EVT_RX_DONE; event.data.rxtx.bytes = bytes; - event.data.rxtx.p_data = m_cb.p_rx_buffer; - - m_cb.rx_buffer_length = 0; + event.data.rxtx.p_data = p_data; - m_cb.handler(&event,m_cb.p_context); + p_cb->handler(&event, p_cb->p_context); } -__STATIC_INLINE void tx_done_event(uint8_t bytes) +__STATIC_INLINE void tx_done_event(uart_control_block_t * p_cb, uint8_t bytes) { nrf_drv_uart_event_t event; event.type = NRF_DRV_UART_EVT_TX_DONE; event.data.rxtx.bytes = bytes; - event.data.rxtx.p_data = (uint8_t *)m_cb.p_tx_buffer; + event.data.rxtx.p_data = (uint8_t *)p_cb->p_tx_buffer; - m_cb.tx_buffer_length = 0; + p_cb->tx_buffer_length = 0; - m_cb.handler(&event,m_cb.p_context); + p_cb->handler(&event, p_cb->p_context); } -void nrf_drv_uart_tx_abort(void) +void nrf_drv_uart_tx_abort(const nrf_drv_uart_t * p_instance) { - CODE_FOR_UARTE( - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_TXSTOPPED); - nrf_uarte_task_trigger(NRF_UARTE0, NRF_UARTE_TASK_STOPTX); - if (m_cb.handler == NULL) + uart_control_block_t * p_cb = &m_cb[p_instance->drv_inst_idx]; + + CODE_FOR_UARTE + ( + nrf_uarte_event_clear(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED); + nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STOPTX); + if (p_cb->handler == NULL) { - while(!nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_TXSTOPPED)); + while (!nrf_uarte_event_check(p_instance->reg.p_uarte, NRF_UARTE_EVENT_TXSTOPPED)); } ) - CODE_FOR_UART( - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STOPTX); - if (m_cb.handler) + CODE_FOR_UART + ( + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPTX); + if (p_cb->handler) { - tx_done_event(m_cb.tx_counter); + tx_done_event(p_cb, p_cb->tx_counter); } else { - m_cb.tx_counter = TX_COUNTER_ABORT_REQ_VALUE; + p_cb->tx_counter = TX_COUNTER_ABORT_REQ_VALUE; } ) + NRF_LOG_INFO("TX transaction aborted.\r\n"); } -void nrf_drv_uart_rx_abort(void) +void nrf_drv_uart_rx_abort(const nrf_drv_uart_t * p_instance) { - CODE_FOR_UARTE( - nrf_uarte_task_trigger(NRF_UARTE0, NRF_UARTE_TASK_STOPRX); + CODE_FOR_UARTE + ( + nrf_uarte_task_trigger(p_instance->reg.p_uarte, NRF_UARTE_TASK_STOPRX); ) - CODE_FOR_UART( - nrf_uart_int_disable(NRF_UART0, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STOPRX); + CODE_FOR_UART + ( + nrf_uart_int_disable(p_instance->reg.p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + nrf_uart_task_trigger(p_instance->reg.p_uart, NRF_UART_TASK_STOPRX); ) + NRF_LOG_INFO("RX transaction aborted.\r\n"); } -void UART0_IRQHandler(void) + +#if defined(UART_IN_USE) +__STATIC_INLINE void uart_irq_handler(NRF_UART_Type * p_uart, uart_control_block_t * p_cb) { - CODE_FOR_UARTE - ( - if (nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_ERROR)) + if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_ERROR) && + nrf_uart_event_check(p_uart, NRF_UART_EVENT_ERROR)) + { + nrf_drv_uart_event_t event; + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_ERROR); + NRF_LOG_DEBUG("Event: %s.\r\n", (uint32_t)EVT_TO_STR(NRF_UART_EVENT_ERROR)); + nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + if (!p_cb->rx_enabled) { - nrf_drv_uart_event_t event; - - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ERROR); - - event.type = NRF_DRV_UART_EVT_ERROR; - event.data.error.error_mask = nrf_uarte_errorsrc_get_and_clear(NRF_UARTE0); - event.data.error.rxtx.bytes = nrf_uarte_rx_amount_get(NRF_UARTE0); - event.data.error.rxtx.p_data = m_cb.p_rx_buffer; + nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX); + } + event.type = NRF_DRV_UART_EVT_ERROR; + event.data.error.error_mask = nrf_uart_errorsrc_get_and_clear(p_uart); + event.data.error.rxtx.bytes = p_cb->rx_buffer_length; + event.data.error.rxtx.p_data = p_cb->p_rx_buffer; - //abort transfer - m_cb.rx_buffer_length = 0; + //abort transfer + p_cb->rx_buffer_length = 0; + p_cb->rx_secondary_buffer_length = 0; - m_cb.handler(&event,m_cb.p_context); - } - else if (nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_ENDRX)) + p_cb->handler(&event,p_cb->p_context); + } + else if (nrf_uart_int_enable_check(p_uart, NRF_UART_INT_MASK_RXDRDY) && + nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXDRDY)) + { + rx_byte(p_uart, p_cb); + if (p_cb->rx_buffer_length == p_cb->rx_counter) { - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ENDRX); - uint8_t amount = nrf_uarte_rx_amount_get(NRF_UARTE0); - if (amount == m_cb.rx_buffer_length) + if (p_cb->rx_secondary_buffer_length) { - rx_done_event(amount); + uint8_t * p_data = p_cb->p_rx_buffer; + uint8_t rx_counter = p_cb->rx_counter; + + //Switch to secondary buffer. + p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length; + p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer; + p_cb->rx_secondary_buffer_length = 0; + p_cb->rx_counter = 0; + rx_done_event(p_cb, rx_counter, p_data); } - } - - if (nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_RXTO)) - { - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_RXTO); - if (m_cb.rx_buffer_length) + else { - rx_done_event(nrf_uarte_rx_amount_get(NRF_UARTE0)); + if (!p_cb->rx_enabled) + { + nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STOPRX); + } + nrf_uart_int_disable(p_uart, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); + p_cb->rx_buffer_length = 0; + rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer); } } + } - if (nrf_uarte_event_check(NRF_UARTE0, NRF_UARTE_EVENT_ENDTX)) + if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_TXDRDY)) + { + if (p_cb->tx_counter < (uint16_t) p_cb->tx_buffer_length) { - nrf_uarte_event_clear(NRF_UARTE0, NRF_UARTE_EVENT_ENDTX); - if (m_cb.tx_buffer_length) - { - tx_done_event(nrf_uarte_tx_amount_get(NRF_UARTE0)); - } + tx_byte(p_uart, p_cb); } - ) - CODE_FOR_UART( - if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_ERROR) && - nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_ERROR)) + else { - nrf_drv_uart_event_t event; - - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_ERROR); - nrf_uart_int_disable(NRF_UART0, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); - if (!m_cb.rx_enabled) + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_TXDRDY); + if (p_cb->tx_buffer_length) { - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STOPRX); + tx_done_event(p_cb, p_cb->tx_buffer_length); } - event.type = NRF_DRV_UART_EVT_ERROR; - event.data.error.error_mask = nrf_uart_errorsrc_get_and_clear(NRF_UART0); - event.data.error.rxtx.bytes = m_cb.rx_buffer_length; - event.data.error.rxtx.p_data = m_cb.p_rx_buffer; - - //abort transfer - m_cb.rx_buffer_length = 0; + } + } - m_cb.handler(&event,m_cb.p_context); + if (nrf_uart_event_check(p_uart, NRF_UART_EVENT_RXTO)) + { + nrf_uart_event_clear(p_uart, NRF_UART_EVENT_RXTO); + // RXTO event may be triggered as a result of abort call. In th + if (p_cb->rx_enabled) + { + nrf_uart_task_trigger(p_uart, NRF_UART_TASK_STARTRX); } - else if (nrf_uart_int_enable_check(NRF_UART0, NRF_UART_INT_MASK_RXDRDY) && - nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXDRDY)) + if (p_cb->rx_buffer_length) { - rx_byte(); - if (m_cb.rx_buffer_length == m_cb.rx_counter) - { - if (!m_cb.rx_enabled) - { - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STOPRX); - } - nrf_uart_int_disable(NRF_UART0, NRF_UART_INT_MASK_RXDRDY | NRF_UART_INT_MASK_ERROR); - rx_done_event(m_cb.rx_counter); - } + p_cb->rx_buffer_length = 0; + rx_done_event(p_cb, p_cb->rx_counter, p_cb->p_rx_buffer); } + } +} +#endif + +#if defined(UARTE_IN_USE) +__STATIC_INLINE void uarte_irq_handler(NRF_UARTE_Type * p_uarte, uart_control_block_t * p_cb) +{ + if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ERROR)) + { + nrf_drv_uart_event_t event; + + nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ERROR); + + event.type = NRF_DRV_UART_EVT_ERROR; + event.data.error.error_mask = nrf_uarte_errorsrc_get_and_clear(p_uarte); + event.data.error.rxtx.bytes = nrf_uarte_rx_amount_get(p_uarte); + event.data.error.rxtx.p_data = p_cb->p_rx_buffer; - if (nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_TXDRDY)) + //abort transfer + p_cb->rx_buffer_length = 0; + p_cb->rx_secondary_buffer_length = 0; + + p_cb->handler(&event, p_cb->p_context); + } + else if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDRX)) + { + nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDRX); + uint8_t amount = nrf_uarte_rx_amount_get(p_uarte); + // If the transfer was stopped before completion, amount of transfered bytes + // will not be equal to the buffer length. Interrupted trunsfer is ignored. + if (amount == p_cb->rx_buffer_length) { - if ((m_cb.tx_buffer_length > m_cb.tx_counter)) + if (p_cb->rx_secondary_buffer_length) { - tx_byte(); + uint8_t * p_data = p_cb->p_rx_buffer; + nrf_uarte_shorts_disable(p_uarte, NRF_UARTE_SHORT_ENDRX_STARTRX); + p_cb->rx_buffer_length = p_cb->rx_secondary_buffer_length; + p_cb->p_rx_buffer = p_cb->p_rx_secondary_buffer; + p_cb->rx_secondary_buffer_length = 0; + rx_done_event(p_cb, amount, p_data); } else { - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_TXDRDY); - if (m_cb.tx_buffer_length) - { - tx_done_event(m_cb.tx_buffer_length); - } + p_cb->rx_buffer_length = 0; + rx_done_event(p_cb, amount, p_cb->p_rx_buffer); } } - if (nrf_uart_event_check(NRF_UART0, NRF_UART_EVENT_RXTO)) + } + + if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_RXTO)) + { + nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_RXTO); + if (p_cb->rx_buffer_length) { - nrf_uart_event_clear(NRF_UART0, NRF_UART_EVENT_RXTO); + p_cb->rx_buffer_length = 0; + rx_done_event(p_cb, nrf_uarte_rx_amount_get(p_uarte), p_cb->p_rx_buffer); + } + } - // RXTO event may be triggered as a result of abort call. In th - if (m_cb.rx_enabled) - { - nrf_uart_task_trigger(NRF_UART0, NRF_UART_TASK_STARTRX); - } - if (m_cb.rx_buffer_length) - { - rx_done_event(m_cb.rx_counter); - } + if (nrf_uarte_event_check(p_uarte, NRF_UARTE_EVENT_ENDTX)) + { + nrf_uarte_event_clear(p_uarte, NRF_UARTE_EVENT_ENDTX); + if (p_cb->tx_buffer_length) + { + tx_done_event(p_cb, nrf_uarte_tx_amount_get(p_uarte)); } + } +} +#endif + +#if UART0_ENABLED +void UART0_IRQHandler(void) +{ + CODE_FOR_UARTE_INT + ( + UART0_INSTANCE_INDEX, + uarte_irq_handler(NRF_UARTE0, &m_cb[UART0_INSTANCE_INDEX]); + ) + CODE_FOR_UART + ( + uart_irq_handler(NRF_UART0, &m_cb[UART0_INSTANCE_INDEX]); + ) +} +#endif + +#if UART1_ENABLED +void UARTE1_IRQHandler(void) +{ + CODE_FOR_UARTE_INT + ( + UART1_INSTANCE_INDEX, + uarte_irq_handler(NRF_UARTE1, &m_cb[UART1_INSTANCE_INDEX]); + ) + CODE_FOR_UART + ( + uart_irq_handler(NRF_UART1, &m_cb[UART1_INSTANCE_INDEX]); ) } +#endif +#endif //NRF_MODULE_ENABLED(UART) diff --git a/components/drivers_nrf/uart/nrf_drv_uart.h b/components/drivers_nrf/uart/nrf_drv_uart.h index b5be64b..6b573ac 100644 --- a/components/drivers_nrf/uart/nrf_drv_uart.h +++ b/components/drivers_nrf/uart/nrf_drv_uart.h @@ -1,20 +1,48 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @addtogroup nrf_uart UART driver and HAL * @ingroup nrf_drivers * @brief UART API. - * @details The UART driver provides APIs for utilizing UART peripheral. + * @details The UART driver provides APIs for utilizing the UART peripheral. * * @defgroup nrf_drv_uart UART driver * @{ @@ -27,12 +55,84 @@ #define NRF_DRV_UART_H #include "nrf_uart.h" -#ifdef NRF52 +#ifdef UARTE_PRESENT #include "nrf_uarte.h" #endif #include "sdk_errors.h" -#include "nrf_drv_config.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef UART1_ENABLED +#define UART1_ENABLED 0 +#endif + +#ifndef UART0_ENABLED +#define UART0_ENABLED 0 +#endif + +#define UART0_INSTANCE_INDEX 0 +#define UART1_INSTANCE_INDEX UART0_ENABLED +#define UART_ENABLED_COUNT UART0_ENABLED + UART1_ENABLED + +#if defined(UARTE_PRESENT) + #define NRF_DRV_UART_PERIPHERAL(id) \ + (CONCAT_3(UART, id, _CONFIG_USE_EASY_DMA) == 1 ? \ + (void *)CONCAT_2(NRF_UARTE, id) \ + : (void *)CONCAT_2(NRF_UART, id)) +#else + #define NRF_DRV_UART_PERIPHERAL(id) (void *)CONCAT_2(NRF_UART, id) +#endif + +// This set of macros makes it possible to exclude parts of code, when one type +// of supported peripherals is not used. + +#if defined(UARTE_PRESENT) + +#if (UART_EASY_DMA_SUPPORT == 1) +#define UARTE_IN_USE +#endif + +#if (UART_LEGACY_SUPPORT == 1) +#define UART_IN_USE +#endif + +#if (UART_ENABLED == 1) && ((!defined(UARTE_IN_USE) && !defined(UART_IN_USE)) || ((UART_EASY_DMA_SUPPORT == 0) && (UART_LEGACY_SUPPORT == 0))) +#error "Illegal settings in uart module!" +#endif + +#elif defined(UART_PRESENT) +#define UART_IN_USE +#endif + +/** + * @brief Structure for the UART driver instance. + */ +typedef struct +{ + union + { +#if (defined(UARTE_IN_USE)) + NRF_UARTE_Type * p_uarte; ///< Pointer to a structure with UARTE registers. +#endif +#if (defined(UART_IN_USE) || (UART_ENABLED == 0)) + NRF_UART_Type * p_uart; ///< Pointer to a structure with UART registers. +#endif + } reg; + uint8_t drv_inst_idx; ///< Driver instance index. +} nrf_drv_uart_t; + +/** + * @brief Macro for creating an UART driver instance. + */ +#define NRF_DRV_UART_INSTANCE(id) \ +{ \ + .reg = {NRF_DRV_UART_PERIPHERAL(id)}, \ + .drv_inst_idx = CONCAT_3(UART, id, _INSTANCE_INDEX),\ +} /** * @brief Types of UART driver events. @@ -56,38 +156,45 @@ typedef struct nrf_uart_parity_t parity; ///< Parity configuration. nrf_uart_baudrate_t baudrate; ///< Baudrate. uint8_t interrupt_priority; ///< Interrupt priority. -#ifdef NRF52 +#ifdef UARTE_PRESENT bool use_easy_dma; #endif } nrf_drv_uart_config_t; /**@brief UART default configuration. */ -#ifdef NRF52 +#ifdef UARTE_PRESENT +#if !UART_LEGACY_SUPPORT +#define DEFAULT_CONFIG_USE_EASY_DMA true +#elif !UART_EASY_DMA_SUPPORT +#define DEFAULT_CONFIG_USE_EASY_DMA false +#else +#define DEFAULT_CONFIG_USE_EASY_DMA UART0_USE_EASY_DMA +#endif #define NRF_DRV_UART_DEFAULT_CONFIG \ { \ - .pseltxd = UART0_CONFIG_PSEL_TXD, \ - .pselrxd = UART0_CONFIG_PSEL_RXD, \ - .pselcts = UART0_CONFIG_PSEL_CTS, \ - .pselrts = UART0_CONFIG_PSEL_RTS, \ + .pseltxd = NRF_UART_PSEL_DISCONNECTED, \ + .pselrxd = NRF_UART_PSEL_DISCONNECTED, \ + .pselcts = NRF_UART_PSEL_DISCONNECTED, \ + .pselrts = NRF_UART_PSEL_DISCONNECTED, \ .p_context = NULL, \ - .hwfc = UART0_CONFIG_HWFC, \ - .parity = UART0_CONFIG_PARITY, \ - .baudrate = UART0_CONFIG_BAUDRATE, \ - .interrupt_priority = UART0_CONFIG_IRQ_PRIORITY, \ - .use_easy_dma = UART0_CONFIG_USE_EASY_DMA \ + .hwfc = (nrf_uart_hwfc_t)UART_DEFAULT_CONFIG_HWFC, \ + .parity = (nrf_uart_parity_t)UART_DEFAULT_CONFIG_PARITY, \ + .baudrate = (nrf_uart_baudrate_t)UART_DEFAULT_CONFIG_BAUDRATE, \ + .interrupt_priority = UART_DEFAULT_CONFIG_IRQ_PRIORITY, \ + .use_easy_dma = true \ } #else #define NRF_DRV_UART_DEFAULT_CONFIG \ { \ - .pseltxd = UART0_CONFIG_PSEL_TXD, \ - .pselrxd = UART0_CONFIG_PSEL_RXD, \ - .pselcts = UART0_CONFIG_PSEL_CTS, \ - .pselrts = UART0_CONFIG_PSEL_RTS, \ + .pseltxd = NRF_UART_PSEL_DISCONNECTED, \ + .pselrxd = NRF_UART_PSEL_DISCONNECTED, \ + .pselcts = NRF_UART_PSEL_DISCONNECTED, \ + .pselrts = NRF_UART_PSEL_DISCONNECTED, \ .p_context = NULL, \ - .hwfc = UART0_CONFIG_HWFC, \ - .parity = UART0_CONFIG_PARITY, \ - .baudrate = UART0_CONFIG_BAUDRATE, \ - .interrupt_priority = UART0_CONFIG_IRQ_PRIORITY \ + .hwfc = (nrf_uart_hwfc_t)UART_DEFAULT_CONFIG_HWFC, \ + .parity = (nrf_uart_parity_t)UART_DEFAULT_CONFIG_PARITY, \ + .baudrate = (nrf_uart_baudrate_t)UART_DEFAULT_CONFIG_BAUDRATE, \ + .interrupt_priority = UART_DEFAULT_CONFIG_IRQ_PRIORITY, \ } #endif @@ -119,9 +226,9 @@ typedef struct /** * @brief UART interrupt event handler. * - * @param[in] p_event Pointer to event structure. Event is allocated on the stack so it is available - * only within the context of the event handler. - * @param[in] p_context Context passed to interrupt handler, set on initialization. + * @param[in] p_event Pointer to event structure. Event is allocated on the stack so it is available + * only within the context of the event handler. + * @param[in] p_context Context passed to interrupt handler, set on initialization. */ typedef void (*nrf_uart_event_handler_t)(nrf_drv_uart_event_t * p_event, void * p_context); @@ -130,38 +237,45 @@ typedef void (*nrf_uart_event_handler_t)(nrf_drv_uart_event_t * p_event, void * * * This function configures and enables UART. After this function GPIO pins are controlled by UART. * - * @param[in] p_config Initial configuration. Default configuration used if NULL. - * @param[in] event_handler Event handler provided by the user. If not provided driver works in - * blocking mode. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_config Initial configuration. Default configuration used if NULL. + * @param[in] event_handler Event handler provided by the user. If not provided driver works in + * blocking mode. * * @retval NRF_SUCCESS If initialization was successful. * @retval NRF_ERROR_INVALID_STATE If driver is already initialized. */ -ret_code_t nrf_drv_uart_init(nrf_drv_uart_config_t const * p_config, +ret_code_t nrf_drv_uart_init(nrf_drv_uart_t const * p_instance, + nrf_drv_uart_config_t const * p_config, nrf_uart_event_handler_t event_handler); /** * @brief Function for uninitializing the UART driver. + * @param[in] p_instance Pointer to the driver instance structure. */ -void nrf_drv_uart_uninit(void); +void nrf_drv_uart_uninit(nrf_drv_uart_t const * p_instance); /** * @brief Function for getting the address of a specific UART task. * - * @param[in] task Task. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] task Task. * - * @retval Task address. + * @return Task address. */ -__STATIC_INLINE uint32_t nrf_drv_uart_task_address_get(nrf_uart_task_t task); +__STATIC_INLINE uint32_t nrf_drv_uart_task_address_get(nrf_drv_uart_t const * p_instance, + nrf_uart_task_t task); /** * @brief Function for getting the address of a specific UART event. * - * @param[in] event Event. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] event Event. * - * @retval Event address. + * @return Event address. */ -__STATIC_INLINE uint32_t nrf_drv_uart_event_address_get(nrf_uart_event_t event); +__STATIC_INLINE uint32_t nrf_drv_uart_event_address_get(nrf_drv_uart_t const * p_instance, + nrf_uart_event_t event); /** * @brief Function for sending data over UART. @@ -176,15 +290,28 @@ __STATIC_INLINE uint32_t nrf_drv_uart_event_address_get(nrf_uart_event_t event); * are placed in the Data RAM region. If they are not and UARTE instance is * used, this function will fail with error code NRF_ERROR_INVALID_ADDR. * - * @param[in] p_data Pointer to data. - * @param[in] length Number of bytes to send. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_data Pointer to data. + * @param[in] length Number of bytes to send. * * @retval NRF_SUCCESS If initialization was successful. * @retval NRF_ERROR_BUSY If driver is already transferring. + * @retval NRF_ERROR_FORBIDDEN If the transfer was aborted from a different context + * (blocking mode only, also see @ref nrf_drv_uart_rx_disable). * @retval NRF_ERROR_INVALID_ADDR If p_data does not point to RAM buffer (UARTE only). - * @retval NRF_ERROR_FORBIDDEN If transfer was aborted (blocking mode only). */ -ret_code_t nrf_drv_uart_tx(uint8_t const * const p_data, uint8_t length); +ret_code_t nrf_drv_uart_tx(nrf_drv_uart_t const * p_instance, + uint8_t const * const p_data, uint8_t length); + +/** + * @brief Function for checking if UART is currently transmitting. + * + * @param[in] p_instance Pointer to the driver instance structure. + * + * @retval true If UART is transmitting. + * @retval false If UART is not transmitting. + */ +bool nrf_drv_uart_tx_in_progress(nrf_drv_uart_t const * p_instance); /** * @brief Function for aborting any ongoing transmission. @@ -192,30 +319,43 @@ ret_code_t nrf_drv_uart_tx(uint8_t const * const p_data, uint8_t length); * contain number of bytes sent until abort was called. If Easy DMA is not used event will be * called from the function context. If Easy DMA is used it will be called from UART interrupt * context. + * + * @param[in] p_instance Pointer to the driver instance structure. */ -void nrf_drv_uart_tx_abort(void); +void nrf_drv_uart_tx_abort(nrf_drv_uart_t const * p_instance); /** * @brief Function for receiving data over UART. * - * If an event handler was provided in nrf_drv_uart_init() call, this function + * If an event handler was provided in the nrf_drv_uart_init() call, this function * returns immediately and the handler is called when the transfer is done. * Otherwise, the transfer is performed in blocking mode, i.e. this function * returns when the transfer is finished. Blocking mode is not using interrupt so * there is no context switching inside the function. + * The receive buffer pointer is double buffered in non-blocking mode. The secondary + * buffer can be set immediately after starting the transfer and will be filled + * when the primary buffer is full. The double buffering feature allows + * receiving data continuously. * * @note Peripherals using EasyDMA (i.e. UARTE) require that the transfer buffers - * are placed in the Data RAM region. If they are not and UARTE instance is - * used, this function will fail with error code NRF_ERROR_INVALID_ADDR. - * @param[in] p_data Pointer to data. - * @param[in] length Number of bytes to receive. + * are placed in the Data RAM region. If they are not and UARTE driver instance + * is used, this function will fail with error code NRF_ERROR_INVALID_ADDR. * - * @retval NRF_SUCCESS If initialization was successful. - * @retval NRF_ERROR_BUSY If driver is already receiving. + * @param[in] p_instance Pointer to the driver instance structure. + * @param[in] p_data Pointer to data. + * @param[in] length Number of bytes to receive. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_BUSY If the driver is already receiving + * (and the secondary buffer has already been set + * in non-blocking mode). + * @retval NRF_ERROR_FORBIDDEN If the transfer was aborted from a different context + * (blocking mode only, also see @ref nrf_drv_uart_rx_disable). + * @retval NRF_ERROR_INTERNAL If UART peripheral reported an error. * @retval NRF_ERROR_INVALID_ADDR If p_data does not point to RAM buffer (UARTE only). - * @retval NRF_ERROR_FORBIDDEN If transfer was aborted (blocking mode only). */ -ret_code_t nrf_drv_uart_rx(uint8_t * p_data, uint8_t length); +ret_code_t nrf_drv_uart_rx(nrf_drv_uart_t const * p_instance, + uint8_t * p_data, uint8_t length); /** * @brief Function for enabling receiver. @@ -224,8 +364,10 @@ ret_code_t nrf_drv_uart_rx(uint8_t * p_data, uint8_t length); * UART receive function before FIFO is filled, overrun error will encounter. Enabling receiver * without specifying RX buffer is supported only in UART mode (without Easy DMA). Receiver must be * explicitly closed by the user @sa nrf_drv_uart_rx_disable. Function asserts if mode is wrong. + * + * @param[in] p_instance Pointer to the driver instance structure. */ -void nrf_drv_uart_rx_enable(void); +void nrf_drv_uart_rx_enable(nrf_drv_uart_t const * p_instance); /** * @brief Function for disabling receiver. @@ -233,37 +375,57 @@ void nrf_drv_uart_rx_enable(void); * Function must be called to close the receiver after it has been explicitly enabled by * @sa nrf_drv_uart_rx_enable. Feature is supported only in UART mode (without Easy DMA). Function * asserts if mode is wrong. + * + * @param[in] p_instance Pointer to the driver instance structure. */ -void nrf_drv_uart_rx_disable(void); +void nrf_drv_uart_rx_disable(nrf_drv_uart_t const * p_instance); /** * @brief Function for aborting any ongoing reception. - * @note @ref NRF_DRV_UART_EVT_RX_DONE event will be generated in non-blocking mode. Event will - * contain number of bytes received until abort was called. If Easy DMA is not used event will be - * called from the function context. If Easy DMA is used it will be called from UART interrupt + * @note @ref NRF_DRV_UART_EVT_RX_DONE event will be generated in non-blocking mode. The event will + * contain the number of bytes received until abort was called. The event is called from UART interrupt * context. + * + * @param[in] p_instance Pointer to the driver instance structure. */ -void nrf_drv_uart_rx_abort(void); +void nrf_drv_uart_rx_abort(nrf_drv_uart_t const * p_instance); /** * @brief Function for reading error source mask. Mask contains values from @ref nrf_uart_error_mask_t. * @note Function should be used in blocking mode only. In case of non-blocking mode error event is * generated. Function clears error sources after reading. * + * @param[in] p_instance Pointer to the driver instance structure. + * * @retval Mask of reported errors. */ -uint32_t nrf_drv_uart_errorsrc_get(void); +uint32_t nrf_drv_uart_errorsrc_get(nrf_drv_uart_t const * p_instance); #ifndef SUPPRESS_INLINE_IMPLEMENTATION -__STATIC_INLINE uint32_t nrf_drv_uart_task_address_get(nrf_uart_task_t task) +__STATIC_INLINE uint32_t nrf_drv_uart_task_address_get(nrf_drv_uart_t const * p_instance, + nrf_uart_task_t task) { - return nrf_uart_task_address_get(NRF_UART0, task); +#ifdef UART_IN_USE + return nrf_uart_task_address_get(p_instance->reg.p_uart, task); +#else + return nrf_uarte_task_address_get(p_instance->reg.p_uarte, (nrf_uarte_task_t)task); +#endif } -__STATIC_INLINE uint32_t nrf_drv_uart_event_address_get(nrf_uart_event_t event) +__STATIC_INLINE uint32_t nrf_drv_uart_event_address_get(nrf_drv_uart_t const * p_instance, + nrf_uart_event_t event) { - return nrf_uart_event_address_get(NRF_UART0, event); +#ifdef UART_IN_USE + return nrf_uart_event_address_get(p_instance->reg.p_uart, event); +#else + return nrf_uarte_event_address_get(p_instance->reg.p_uarte, (nrf_uarte_event_t)event); +#endif } #endif //SUPPRESS_INLINE_IMPLEMENTATION + +#ifdef __cplusplus +} +#endif + #endif //NRF_DRV_UART_H /** @} */ diff --git a/components/drivers_nrf/usbd/nrf_drv_usbd.c b/components/drivers_nrf/usbd/nrf_drv_usbd.c new file mode 100644 index 0000000..63d268b --- /dev/null +++ b/components/drivers_nrf/usbd/nrf_drv_usbd.c @@ -0,0 +1,1709 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if USBD_ENABLED +#include "nrf_drv_usbd.h" +#include "nrf.h" +#include "nordic_common.h" +#include "nrf_drv_common.h" +#include "nrf_atomic.h" +#include "nrf_delay.h" +#include "nrf_drv_clock.h" +#include "app_util_platform.h" + +#include +#include + +#define NRF_LOG_MODULE_NAME "" +#if NRF_USBD_DRV_LOG_ENABLED +#else //NRF_USBD_DRV_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //NRF_USBD_DRV_LOG_ENABLED +#include "nrf_log.h" + +#ifndef NRF_DRV_USBD_EARLY_DMA_PROCESS +/* Try to process DMA request when endpoint transmission has been detected + * and just after last EasyDMA has been processed. + * It speeds up the transmission a little (about 10% measured) + * with a cost of more CPU power used. + */ +#define NRF_DRV_USBD_EARLY_DMA_PROCESS 1 +#endif + +#ifndef NRF_DRV_USBD_PROTO1_FIX +/* Fix event system */ +#define NRF_DRV_USBD_PROTO1_FIX 1 +#endif + +//#define NRF_DRV_USBD_PROTO1_FIX_DEBUG +#ifdef NRF_DRV_USBD_PROTO1_FIX_DEBUG +#include "nrf_log.h" +#define NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(...) NRF_LOG_DEBUG(__VA_ARGS__) +#else +#define NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(...) do {} while (0) +#endif + +#ifndef NRF_DRV_USBD_STARTED_EV_ENABLE +#define NRF_DRV_USBD_STARTED_EV_ENABLE 1 +#endif + +#if NRF_DRV_USBD_PROTO1_FIX +#include "nrf_drv_systick.h" +#endif + +/** + * @defgroup nrf_usbdraw_drv_int USB Device driver internal part + * @internal + * @ingroup nrf_usbdraw_drv + * + * This part contains auxiliary internal macros, variables and functions. + * @{ + */ + +/** + * @brief Assert endpoint number validity + * + * Internal macro to be used during program creation in debug mode. + * Generates assertion if endpoint number is not valid. + * + * @param ep Endpoint number to validity check + */ +#define USBD_ASSERT_EP_VALID(ep) ASSERT( \ + ((NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT )) \ + || \ + (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT))) \ +); + +/** + * @brief Lowest position of bit for IN endpoint + * + * The first bit position corresponding to IN endpoint. + * @sa ep2bit bit2ep + */ +#define USBD_EPIN_BITPOS_0 0 + +/** + * @brief Lowest position of bit for OUT endpoint + * + * The first bit position corresponding to OUT endpoint + * @sa ep2bit bit2ep + */ +#define USBD_EPOUT_BITPOS_0 16 + +/** + * @brief Input endpoint bits mask + */ +#define USBD_EPIN_BIT_MASK (0xFFFFU << USBD_EPIN_BITPOS_0) + +/** + * @brief Output endpoint bits mask + */ +#define USBD_EPOUT_BIT_MASK (0xFFFFU << USBD_EPOUT_BITPOS_0) + +/** + * @brief Auxiliary macro to change EP number into bit position + * + * This macro is used by @ref ep2bit function but also for statically check + * the bitpos values integrity during compilation. + * + * @param[in] ep Endpoint number. + * @return Endpoint bit position. + */ +#define USBD_EP_BITPOS(ep) ((NRF_USBD_EPIN_CHECK(ep) ? USBD_EPIN_BITPOS_0 : USBD_EPOUT_BITPOS_0) + NRF_USBD_EP_NR_GET(ep)) + +/* Check it the bit positions values match defined DATAEPSTATUS bit positions */ +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN1) == USBD_EPDATASTATUS_EPIN1_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN2) == USBD_EPDATASTATUS_EPIN2_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN3) == USBD_EPDATASTATUS_EPIN3_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN4) == USBD_EPDATASTATUS_EPIN4_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN5) == USBD_EPDATASTATUS_EPIN5_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN6) == USBD_EPDATASTATUS_EPIN6_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN7) == USBD_EPDATASTATUS_EPIN7_Pos ); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT1) == USBD_EPDATASTATUS_EPOUT1_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT2) == USBD_EPDATASTATUS_EPOUT2_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT3) == USBD_EPDATASTATUS_EPOUT3_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT4) == USBD_EPDATASTATUS_EPOUT4_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT5) == USBD_EPDATASTATUS_EPOUT5_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT6) == USBD_EPDATASTATUS_EPOUT6_Pos); +STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Pos); + + +/** + * @name Internal auxiliary definitions for SETUP packet + * + * Definitions used to take out the information about last SETUP packet direction + * from @c bmRequestType. + * @{ + */ +/** The position of DIR bit in bmRequestType inside SETUP packet */ +#define USBD_DRV_REQUESTTYPE_DIR_BITPOS 7 +/** The mask of DIR bit in bmRequestType inside SETUP packet */ +#define USBD_DRV_REQUESTTYPE_DIR_MASK (1U << USBD_DRV_REQUESTTYPE_DIR_BITPOS) +/** The value of DIR bit for OUT direction (Host -> Device) */ +#define USBD_DRV_REQUESTTYPE_DIR_OUT (0U << USBD_DRV_REQUESTTYPE_DIR_BITPOS) +/** The value of DIR bit for IN direction (Device -> Host) */ +#define USBD_DRV_REQUESTTYPE_DIR_IN (1U << USBD_DRV_REQUESTTYPE_DIR_BITPOS) +/** @} */ + +/** + * @brief Current driver state + */ +static nrf_drv_state_t m_drv_state = NRF_DRV_STATE_UNINITIALIZED; + +/** + * @brief Event handler for the library + * + * Event handler that would be called on events. + * + * @note Currently it cannot be null if any interrupt is activated. + */ +static nrf_drv_usbd_event_handler_t m_event_handler; + +/** + * @brief Direction of last received Setup transfer + * + * This variable is used to redirect internal setup data event + * into selected endpoint (IN or OUT). + */ +static nrf_drv_usbd_ep_t m_last_setup_dir; + +/** + * @brief Mark endpoint readiness for DMA transfer + * + * Bits in this variable are cleared and set in interrupts. + * 1 means that endpoint is ready for DMA transfer. + * 0 means that DMA transfer cannot be performed on selected endpoint. + */ +static uint32_t m_ep_ready; + +/** + * @brief Mark endpoint with prepared data to transfer by DMA + * + * This variable can be from any place in the code (interrupt or main thread). + * It would be cleared only from USBD interrupt. + * + * Mask prepared USBD data for transmission. + * It is cleared when no more data to transmit left. + */ +static uint32_t m_ep_dma_waiting; + +/** + * @brief Current EasyDMA state + * + * Single flag, updated only inside interrupts, that marks current EasyDMA state. + * In USBD there is only one DMA channel working in background, and new transfer + * cannot be started when there is ongoing transfer on any other channel. + */ +static uint8_t m_dma_pending; + +#if NRF_DRV_USBD_PROTO1_FIX +static uint32_t m_simulated_events; +static uint32_t m_simulated_dataepstatus; +#endif + +/** + * @brief The structure that would hold transfer configuration to every endpoint + * + * The structure that holds all the data required by the endpoint to proceed + * with LIST functionality and generate quick callback directly when data + * buffer is ready. + */ +typedef struct +{ + nrf_drv_usbd_transfer_handler_desc_t handler_desc; //!< Handler for current transfer, function pointer and context + nrf_drv_usbd_transfer_t transfer_set; //!< Last configured transfer + nrf_drv_usbd_transfer_t transfer_left; //!< Current on-going transfer status + uint16_t max_packet_size; //!< Configured endpoint size + nrf_drv_usbd_ep_status_t status; //!< NRF_SUCCESS or error code, never NRF_ERROR_BUSY - this one is calculated +}usbd_drv_ep_state_t; + +/** + * @brief The array of transfer configurations for the endpoints. + * + * The status of the transfer on each endpoint. + */ +static struct +{ + usbd_drv_ep_state_t ep_out[NRF_USBD_EPOUT_CNT]; //!< Status for OUT endpoints. + usbd_drv_ep_state_t ep_in [NRF_USBD_EPIN_CNT ]; //!< Status for IN endpoints. +}m_ep_state; + +/** + * @brief Buffer used to send data directly from FLASH + * + * This is internal buffer that would be used to emulate the possibility + * to transfer data directly from FLASH. + * We do not have to care about the source of data when calling transfer functions. + * + * We do not need more buffers that one, because only one transfer can be pending + * at once. + */ +static uint32_t m_tx_buffer[CEIL_DIV(NRF_DRV_USBD_EPSIZE, sizeof(uint32_t))]; + + +#if NRF_DRV_USBD_PROTO1_FIX +static inline nrf_usbd_event_t nrf_drv_usbd_ep_to_endevent(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + + static const nrf_usbd_event_t epin_endev[] = + { + NRF_USBD_EVENT_ENDEPIN0, + NRF_USBD_EVENT_ENDEPIN1, + NRF_USBD_EVENT_ENDEPIN2, + NRF_USBD_EVENT_ENDEPIN3, + NRF_USBD_EVENT_ENDEPIN4, + NRF_USBD_EVENT_ENDEPIN5, + NRF_USBD_EVENT_ENDEPIN6, + NRF_USBD_EVENT_ENDEPIN7, + NRF_USBD_EVENT_ENDISOIN0 + }; + static const nrf_usbd_event_t epout_endev[] = + { + NRF_USBD_EVENT_ENDEPOUT0, + NRF_USBD_EVENT_ENDEPOUT1, + NRF_USBD_EVENT_ENDEPOUT2, + NRF_USBD_EVENT_ENDEPOUT3, + NRF_USBD_EVENT_ENDEPOUT4, + NRF_USBD_EVENT_ENDEPOUT5, + NRF_USBD_EVENT_ENDEPOUT6, + NRF_USBD_EVENT_ENDEPOUT7, + NRF_USBD_EVENT_ENDISOOUT0 + }; + + return (NRF_USBD_EPIN_CHECK(ep) ? epin_endev : epout_endev)[NRF_USBD_EP_NR_GET(ep)]; +} +#endif + +static void usbd_dmareq_process(void); + +/** + * @brief Get interrupt mask for selected endpoint + * + * + */ +static inline uint32_t nrf_drv_usbd_ep_to_int(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + + static const uint8_t epin_bitpos[] = + { + USBD_INTEN_ENDEPIN0_Pos, + USBD_INTEN_ENDEPIN1_Pos, + USBD_INTEN_ENDEPIN2_Pos, + USBD_INTEN_ENDEPIN3_Pos, + USBD_INTEN_ENDEPIN4_Pos, + USBD_INTEN_ENDEPIN5_Pos, + USBD_INTEN_ENDEPIN6_Pos, + USBD_INTEN_ENDEPIN7_Pos, + USBD_INTEN_ENDISOIN_Pos + }; + static const uint8_t epout_bitpos[] = + { + USBD_INTEN_ENDEPOUT0_Pos, + USBD_INTEN_ENDEPOUT1_Pos, + USBD_INTEN_ENDEPOUT2_Pos, + USBD_INTEN_ENDEPOUT3_Pos, + USBD_INTEN_ENDEPOUT4_Pos, + USBD_INTEN_ENDEPOUT5_Pos, + USBD_INTEN_ENDEPOUT6_Pos, + USBD_INTEN_ENDEPOUT7_Pos, + USBD_INTEN_ENDISOOUT_Pos + }; + + return 1UL << (NRF_USBD_EPIN_CHECK(ep) ? epin_bitpos : epout_bitpos)[NRF_USBD_EP_NR_GET(ep)]; +} + +/** + * @brief Change Driver endpoint number to HAL endpoint number + * + * @param ep Driver endpoint identifier + * + * @return Endpoint identifier in HAL + * + * @sa nrf_drv_usbd_ep_from_hal + */ +static inline uint8_t ep_to_hal(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + return (uint8_t)ep; +} + +/** + * @brief Generate start task number for selected endpoint index + * + * @param ep Endpoint number + * + * @return Task for starting EasyDMA transfer on selected endpoint. + */ +static inline nrf_usbd_task_t task_start_ep(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + return (nrf_usbd_task_t)( + (NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_TASK_STARTEPIN0 : NRF_USBD_TASK_STARTEPOUT0) + + (NRF_USBD_EP_NR_GET(ep) * sizeof(uint32_t))); +} + +/** + * @brief Access selected endpoint state structure + * + * Function used to change or just read the state of selected endpoint. + * It is used for internal transmission state. + * + * @param ep Endpoint number + */ +static inline usbd_drv_ep_state_t* ep_state_access(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + return ((NRF_USBD_EPIN_CHECK(ep) ? m_ep_state.ep_in : m_ep_state.ep_out) + NRF_USBD_EP_NR_GET(ep)); +} + +/** + * @brief Change endpoint number to bit position + * + * Bit positions are defined the same way as they are placed in DATAEPSTATUS register, + * but bits for endpoint 0 are included. + * + * @param ep Endpoint number + * + * @return Bit position related to the given endpoint number + * + * @sa bit2ep + */ +static inline uint8_t ep2bit(nrf_drv_usbd_ep_t ep) +{ + USBD_ASSERT_EP_VALID(ep); + return USBD_EP_BITPOS(ep); +} + +/** + * @brief Change bit position to endpoint number + * + * @param bitpos Bit position + * + * @return Endpoint number corresponding to given bit position. + * + * @sa ep2bit + */ +static inline nrf_drv_usbd_ep_t bit2ep(uint8_t bitpos) +{ + STATIC_ASSERT(USBD_EPOUT_BITPOS_0 > USBD_EPIN_BITPOS_0); + return (nrf_drv_usbd_ep_t)((bitpos >= USBD_EPOUT_BITPOS_0) ? NRF_USBD_EPOUT(bitpos - USBD_EPOUT_BITPOS_0) : NRF_USBD_EPIN(bitpos)); +} + +/** + * @brief Start selected EasyDMA transmission + * + * This is internal auxiliary function. + * No checking is made if EasyDMA is ready for new transmission. + * + * @param[in] ep Number of endpoint for transmission. + * If it is OUT endpoint transmission would be directed from endpoint to RAM. + * If it is in endpoint transmission would be directed from RAM to endpoint. + */ +static inline void usbd_dma_start(nrf_drv_usbd_ep_t ep) +{ + nrf_usbd_task_trigger(task_start_ep(ep)); +} + +/** + * @brief Abort pending transfer on selected endpoint + * + * @param ep Endpoint number. + * + * @note + * This function locks interrupts that may be costly. + * It is good idea to test if the endpoint is still busy before calling this function: + * @code + (m_ep_dma_waiting & (1U << ep2bit(ep))) + * @endcode + * This function would check it again, but it makes it inside critical section. + */ +static inline void usbd_ep_abort(nrf_drv_usbd_ep_t ep) +{ + CRITICAL_REGION_ENTER(); + + usbd_drv_ep_state_t * p_state = ep_state_access(ep); + + if(NRF_USBD_EPOUT_CHECK(ep)) + { + /* Host -> Device */ + if((~m_ep_dma_waiting) & (1U<transfer_left.size = 0; + p_state->transfer_set.size = 0; + m_ep_dma_waiting &= ~(1U<status = NRF_USBD_EP_ABORTED; + } + else + { + if((m_ep_dma_waiting | (~m_ep_ready)) & (1U< Host */ + m_ep_dma_waiting &= ~(1U<transfer_left.size = 0; + p_state->transfer_set.size = 0; + p_state->status = NRF_USBD_EP_ABORTED; + NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_ABORTED); + m_event_handler(&evt); + } + } + CRITICAL_REGION_EXIT(); +} + +void usbd_drv_ep_abort(nrf_drv_usbd_ep_t ep) +{ + usbd_ep_abort(ep); +} + + +/** + * @brief Abort all pending endpoints + * + * Function aborts all pending endpoint transfers. + */ +static void usbd_ep_abort_all(void) +{ + uint32_t ep_waiting = m_ep_dma_waiting | (m_ep_ready & USBD_EPOUT_BIT_MASK); + while(0 != ep_waiting) + { + uint8_t bitpos = __CLZ(__RBIT(ep_waiting)); + usbd_ep_abort(bit2ep(bitpos)); + ep_waiting &= ~(1U << bitpos); + } + + m_ep_ready = (((1U<handler_desc.handler) + return false; + bool ret; + ret = p_state->handler_desc.handler(&(p_state->transfer_set), p_state->handler_desc.p_context); + if(ret) + { + p_state->transfer_left = p_state->transfer_set; + } + return ret; +} + +/** + * @name Auxiliary functions for global interrupt state + * + * This functions are manipulating interrupt state on NVIC level. + * In the target USBD API there would be only one interrupt. + * So for RawIP we can only enable all interrupts or disable them. + * @{ + */ + + /** + * Enable USBD interrupt + */ + static inline void usbd_int_enable(void) + { + NVIC_EnableIRQ(USBD_IRQn); + } + + /** + * Disable USBD interrupt + */ + static inline void usbd_int_disable(void) + { + NVIC_DisableIRQ(USBD_IRQn); + } + + /** + * Get current USBD interrupt state + */ + static inline bool usbd_int_state(void) + { + return nrf_drv_common_irq_enable_check(USBD_IRQn); + } + + /** + * @brief Force the USBD interrupt into pending state + * + * This function is used to force USBD interrupt to be processed right now. + * It makes it possible to process all EasyDMA access on one thread priority level. + */ + static inline void usbd_int_rise(void) + { + NVIC_SetPendingIRQ(USBD_IRQn); + } + +/** @} */ + +/** + * @name USBD interrupt runtimes + * + * Interrupt runtimes that would be vectorized using @ref m_ivec_isr + * @{ + */ + +static void USBD_ISR_Usbreset(void) +{ + m_last_setup_dir = NRF_DRV_USBD_EPOUT0; + usbd_ep_abort_all(); + + const nrf_drv_usbd_evt_t evt = { + .type = NRF_DRV_USBD_EVT_RESET + }; + + m_event_handler(&evt); +} + +static void USBD_ISR_Started(void) +{ +#if NRF_DRV_USBD_STARTED_EV_ENABLE + uint32_t epstatus = nrf_usbd_epstatus_get_and_clear(); + + /* All finished endpoint have to be marked as busy */ + // #warning Check this one + // ASSERT(epstatus == ((~m_ep_ready) & epstatus)); + while (epstatus) + { + uint8_t bitpos = __CLZ(__RBIT(epstatus)); + nrf_drv_usbd_ep_t ep = bit2ep(bitpos); + epstatus &= ~(1UL << bitpos); + + UNUSED_VARIABLE(ep); + } +#endif +} + +/** + * @brief Handler for EasyDMA event without endpoint clearing. + * + * This handler would be called when EasyDMA transfer for endpoints that does not require clearing. + * All in endpoints are cleared automatically when new EasyDMA transfer is initialized. + * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler + * + * @param[in] ep Endpoint number + */ +static inline void nrf_usbd_ep0in_dma_handler(void) +{ + NRF_LOG_DEBUG("USB event: DMA ready IN0\r\n"); + m_dma_pending = 0; + + usbd_drv_ep_state_t * p_state = ep_state_access(NRF_DRV_USBD_EPIN0); + + nrf_drv_usbd_setup_data_clear(); + + if(0 == p_state->transfer_left.size) + { + /* Check if there is any new data from callback function */ + if(!usbd_next_transfer_safe_call(p_state)) + { + /* End of transfer */ + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<transfer_left.size) + { + /* Check if there is any new data from callback function */ + if(!usbd_next_transfer_safe_call(p_state)) + { + /* End of transfer */ + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<transfer_left.size == 0) + { + /* Check if there is any new data from callback function */ + if(!usbd_next_transfer_safe_call(p_state)) + { + /* End of transfer */ + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep)))); + + /* Send event to the user - for ISO endpoint the whole transfer is finished in this moment */ + NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK); + m_event_handler(&evt); + } + } +} + +/** + * @brief Handler for EasyDMA event for OUT endpoint 0. + * + * EP0 OUT have to be cleared automatically in special way - only in the middle of the transfer. + * It cannot be cleared when required transfer is finished because it means the same that accepting the comment. + */ +static inline void nrf_usbd_ep0out_dma_handler(void) +{ + NRF_LOG_DEBUG("USB event: DMA ready OUT0\r\n"); + m_dma_pending = 0; + + usbd_drv_ep_state_t * p_state = ep_state_access(NRF_DRV_USBD_EPOUT0); + + if (p_state->transfer_left.size == 0) + { + /* Check if there is any new data buffer from callback function */ + if(!usbd_next_transfer_safe_call(p_state)) + { + /* End of transfer */ + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<status) + { + /* Nothing to do - just ignore */ + } + else if (p_state->transfer_left.size == 0) + { + /* Check if there is any new data buffer from callback function */ + if(!usbd_next_transfer_safe_call(p_state)) + { + NRF_LOG_DEBUG("USBD drv: epout_dma_handler ep: %02x, NRF_USBD_EP_OK\r\n", ep); + /* End of transfer */ + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<status) + { + /* Nothing to do - just ignore */ + } + else if (p_state->transfer_left.size == 0) + { + /* Check if there is any new data buffer from callback function */ + if(!usbd_next_transfer_safe_call(p_state)) + { + /* End of transfer */ + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U< Host) */ + if(0 == (m_ep_dma_waiting & (1U< Device) */ + if(0 == (m_ep_dma_waiting & (1U<transfer_left); + + uint32_t data_addr; /* The address used for transmission */ + size_t size = p_transfer->size; + + if(NRF_USBD_EPIN_CHECK(ep)) + { + if(NRF_USBD_EPISO_CHECK(ep)) + { + /* Isochronous endpoints supports only one transfer per frame + * and have to fit in the buffer */ + ASSERT(size <= usbd_ep_iso_capacity(ep)); + } + else + { + /* Bulk transfers can be split to multiple transfers */ + uint16_t max_packet_size = nrf_drv_usbd_ep_max_packet_size_get(ep); + if(size > max_packet_size) + { + size = max_packet_size; + } + } + } + else + { + /* Host -> Device */ + if(size != 0) + { + ASSERT(nrf_drv_is_in_RAM((const void*)(p_transfer->p_data.ptr))); + uint16_t rx_size = nrf_drv_usbd_epout_size_get(ep); + if(rx_size > size) + { + ep_state_access(ep)->status = NRF_USBD_EP_OVERLOAD; + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U<p_data.ptr))) + { + data_addr = p_transfer->p_data.ptr; + } + else + { + /* Size of FLASH transfer is limited to the buffer size - this is also the limit for ISO endpoint */ + ASSERT(size <= sizeof(m_tx_buffer)); + /* Only IN endpoints supports FLASH transfers */ + ASSERT(NRF_USBD_EPIN_CHECK(ep)); + /* Copy data into internal buffer */ + data_addr = (uint32_t)m_tx_buffer; + memcpy(m_tx_buffer, (const void *)(p_transfer->p_data.ptr), size); + } + + m_dma_pending = 1; + m_ep_ready &= ~(1U << pos); + + NRF_LOG_DEBUG("USB dma process: Starting transfer on EP: %x, size: %u\r\n", ep, size); + + nrf_usbd_ep_easydma_set(ep, data_addr, size); +#if NRF_DRV_USBD_PROTO1_FIX + uint32_t cnt_end = (uint32_t)(-1); + do + { + uint32_t cnt = (uint32_t)(-1); + do + { + nrf_usbd_event_clear(NRF_USBD_EVENT_STARTED); + usbd_dma_start(ep); + nrf_drv_systick_delay_us(2); + ++cnt; + }while(!nrf_usbd_event_check(NRF_USBD_EVENT_STARTED)); + if(cnt) + { + NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" DMA restarted: %u times\r\n", cnt); + } + + nrf_drv_systick_delay_us(20); + while(0 == (0x20 & *((volatile uint32_t *)(NRF_USBD_BASE + 0x474)))) + { + nrf_drv_systick_delay_us(2); + } + nrf_drv_systick_delay_us(1); + + ++cnt_end; + } while(!nrf_usbd_event_check(nrf_drv_usbd_ep_to_endevent(ep))); + if(cnt_end) + { + NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" DMA full restarted: %u times\r\n", cnt_end); + } +#else + usbd_dma_start(ep); +#endif + + /* Prepare next transfer */ + p_transfer->p_data.ptr += size; + p_transfer->size -= size; + + /* Transfer started - exit the loop */ + break; + } + } +} +/** @} */ + +typedef void (*nrf_drv_usbd_isr_t)(void); + +/** + * @brief USBD interrupt service runtimes + * + */ +static const nrf_drv_usbd_isr_t m_isr[] = +{ + [USBD_INTEN_USBRESET_Pos ] = USBD_ISR_Usbreset, + [USBD_INTEN_STARTED_Pos ] = USBD_ISR_Started, + [USBD_INTEN_ENDEPIN0_Pos ] = USBD_ISR_dma_epin0, + [USBD_INTEN_ENDEPIN1_Pos ] = USBD_ISR_dma_epin1, + [USBD_INTEN_ENDEPIN2_Pos ] = USBD_ISR_dma_epin2, + [USBD_INTEN_ENDEPIN3_Pos ] = USBD_ISR_dma_epin3, + [USBD_INTEN_ENDEPIN4_Pos ] = USBD_ISR_dma_epin4, + [USBD_INTEN_ENDEPIN5_Pos ] = USBD_ISR_dma_epin5, + [USBD_INTEN_ENDEPIN6_Pos ] = USBD_ISR_dma_epin6, + [USBD_INTEN_ENDEPIN7_Pos ] = USBD_ISR_dma_epin7, + [USBD_INTEN_EP0DATADONE_Pos] = USBD_ISR_SetupData, + [USBD_INTEN_ENDISOIN_Pos ] = USBD_ISR_dma_epin8, + [USBD_INTEN_ENDEPOUT0_Pos ] = USBD_ISR_dma_epout0, + [USBD_INTEN_ENDEPOUT1_Pos ] = USBD_ISR_dma_epout1, + [USBD_INTEN_ENDEPOUT2_Pos ] = USBD_ISR_dma_epout2, + [USBD_INTEN_ENDEPOUT3_Pos ] = USBD_ISR_dma_epout3, + [USBD_INTEN_ENDEPOUT4_Pos ] = USBD_ISR_dma_epout4, + [USBD_INTEN_ENDEPOUT5_Pos ] = USBD_ISR_dma_epout5, + [USBD_INTEN_ENDEPOUT6_Pos ] = USBD_ISR_dma_epout6, + [USBD_INTEN_ENDEPOUT7_Pos ] = USBD_ISR_dma_epout7, + [USBD_INTEN_ENDISOOUT_Pos ] = USBD_ISR_dma_epout8, + [USBD_INTEN_SOF_Pos ] = USBD_ISR_Sof, + [USBD_INTEN_USBEVENT_Pos ] = USBD_ISR_Event, + [USBD_INTEN_EP0SETUP_Pos ] = USBD_ISR_Setup, + [USBD_INTEN_EPDATA_Pos ] = USBD_ISR_EpDataStatus, + [USBD_INTEN_ACCESSFAULT_Pos] = USBD_ISR_AccessFault +}; + +/** + * @name Interrupt handlers + * + * @{ + */ +void USBD_IRQHandler(void) +{ + const uint32_t enabled = nrf_usbd_int_enable_get(); + uint32_t to_process = enabled; + uint32_t active = 0; + + /* Check all enabled interrupts */ + while(to_process) + { + uint8_t event_nr = __CLZ(__RBIT(to_process)); + if(nrf_usbd_event_get_and_clear((nrf_usbd_event_t)nrf_drv_bitpos_to_event(event_nr))) + { + active |= 1UL << event_nr; + } + to_process &= ~(1UL << event_nr); + } + +#if NRF_DRV_USBD_PROTO1_FIX + do { + active |= enabled & m_simulated_events; + m_simulated_events = 0; +#endif +#if NRF_DRV_USBD_PROTO1_FIX + /* Event correcting */ + if((0 == m_dma_pending) && (0 != (active & (USBD_INTEN_SOF_Msk)))) + { + uint8_t usbi, uoi, uii; + /* Testing */ + *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9; + uii = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + if(0 != uii) + { + uii &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + } + + *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA; + uoi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + if(0 != uoi) + { + uoi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + } + *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB; + usbi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + if(0 != usbi) + { + usbi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804))); + } + /* Processing */ + *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AC; + uii &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)); + if(0 != uii) + { + uint8_t rb; + m_simulated_dataepstatus |= ((uint32_t)uii)<= USBD_INTEN_SOF_Pos) + { + /* Get back the EP0Data done event */ + event_nr = USBD_INTEN_EP0DATADONE_Pos; + } + } + } + #endif + + + m_isr[event_nr](); + active &= ~(1UL << event_nr); + } + + usbd_dmareq_process(); +#if NRF_DRV_USBD_PROTO1_FIX + } while(0 != (enabled & m_simulated_events)); +#endif +} + +/** @} */ +/** @} */ + +ret_code_t nrf_drv_usbd_init(nrf_drv_usbd_event_handler_t const event_handler) +{ + UNUSED_VARIABLE(usbd_ep_iso_capacity); + +#if NRF_DRV_USBD_PROTO1_FIX + nrf_drv_systick_init(); +#endif + if(NULL == event_handler) + { + return NRF_ERROR_INVALID_PARAM; + } + if( m_drv_state != NRF_DRV_STATE_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + nrf_drv_clock_hfclk_request(NULL); + while (!nrf_drv_clock_hfclk_is_running()) + { + /* Just waiting */ + } + + m_event_handler = event_handler; + m_drv_state = NRF_DRV_STATE_INITIALIZED; + + uint8_t n; + for(n=0; nstatus = NRF_USBD_EP_OK; + p_state->transfer_left.size = 0; + p_state->transfer_set.size = 0; + } + for(n=0; nstatus = NRF_USBD_EP_OK; + p_state->transfer_left.size = 0; + p_state->transfer_set.size = 0; + } + + return NRF_SUCCESS; +} + +ret_code_t nrf_drv_usbd_uninit(void) +{ + if( m_drv_state != NRF_DRV_STATE_INITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + + nrf_drv_clock_lfclk_release(); + m_event_handler = NULL; + m_drv_state = NRF_DRV_STATE_UNINITIALIZED; + return NRF_SUCCESS; +} + +void nrf_drv_usbd_enable(void) +{ + ASSERT(m_drv_state == NRF_DRV_STATE_INITIALIZED); + + /* Prepare for READY event receiving */ + nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK); + /* Enable the peripheral */ + nrf_usbd_enable(); + /* Waiting for peripheral to enable, this should take a few us */ + while(0 == (NRF_USBD_EVENTCAUSE_READY_MASK & nrf_usbd_eventcause_get())) + { + /* Empty loop */ + } + nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK); + + nrf_usbd_isosplit_set(NRF_USBD_ISOSPLIT_Half); + + m_ep_ready = (((1U<= NRF_DRV_STATE_INITIALIZED); +} + +bool nrf_drv_usbd_is_enabled(void) +{ + return (m_drv_state >= NRF_DRV_STATE_POWERED_ON); +} + +bool nrf_drv_usbd_is_started(void) +{ + return (nrf_drv_usbd_is_enabled() && usbd_int_state()); +} + +void nrf_drv_usbd_ep_max_packet_size_set(nrf_drv_usbd_ep_t ep, uint16_t size) +{ + /* Only power of 2 size allowed */ + ASSERT((size != 0) && (size & (size - 1)) == 0); + /* Packet size cannot be higher than maximum buffer size */ + ASSERT( ( NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep))) + || + ((!NRF_USBD_EPISO_CHECK(ep)) && (size <= NRF_DRV_USBD_EPSIZE))); + + usbd_drv_ep_state_t * p_state = ep_state_access(ep); + p_state->max_packet_size = size; +} + +uint16_t nrf_drv_usbd_ep_max_packet_size_get(nrf_drv_usbd_ep_t ep) +{ + usbd_drv_ep_state_t const * p_state = ep_state_access(ep); + return p_state->max_packet_size; +} + +void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep) +{ + nrf_usbd_ep_enable(ep_to_hal(ep)); + nrf_usbd_int_enable(nrf_drv_usbd_ep_to_int(ep)); + + if((NRF_USBD_EP_NR_GET(ep) != 0) && NRF_USBD_EPOUT_CHECK(ep)) + { + CRITICAL_REGION_ENTER(); + + m_ep_ready |= 1U<status = NRF_USBD_EP_ABORTED; + + CRITICAL_REGION_EXIT(); + } +} + +void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep) +{ + nrf_usbd_ep_disable(ep_to_hal(ep)); + nrf_usbd_int_disable(nrf_drv_usbd_ep_to_int(ep)); +} + +ret_code_t nrf_drv_usbd_ep_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer, + nrf_drv_usbd_transfer_handler_desc_t const * const p_handler) +{ + uint8_t ep_bitpos = ep2bit(ep); + ret_code_t ret; + ASSERT(NULL != p_transfer); + + NRF_LOG_DEBUG("USB drv: Transfer called on endpoint %x, size: %u\r\n", ep, p_transfer->size); + CRITICAL_REGION_ENTER(); + /* Setup data transaction can go only in one direction at a time */ + if((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir)) + { + ret = NRF_ERROR_INVALID_ADDR; + } + else if((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos)) + { + /* IN (Device -> Host) transfer has to be transmitted out to allow new transmission */ + ret = NRF_ERROR_BUSY; + } + else if(nrf_usbd_ep_is_stall(ep)) + { + ret = NRF_ERROR_FORBIDDEN; + } + else + { + /* We can configure the transfer now */ + usbd_drv_ep_state_t * p_state = ep_state_access(ep); + if(NULL != p_handler) + { + p_state->handler_desc = *p_handler; + } + else + { + p_state->handler_desc.handler = NULL; + } + + p_state->transfer_set = *p_transfer; + p_state->transfer_left = *p_transfer; + p_state->status = NRF_USBD_EP_OK; + m_ep_dma_waiting |= 1U << ep_bitpos; + + ret = NRF_SUCCESS; + usbd_int_rise(); + } + + CRITICAL_REGION_EXIT(); + return ret; +} + +ret_code_t nrf_drv_usbd_ep_status_get(nrf_drv_usbd_ep_t ep, nrf_drv_usbd_transfer_t * p_transfer) +{ + ret_code_t ret; + + CRITICAL_REGION_ENTER(); + if(m_ep_dma_waiting & (1U << ep2bit(ep))) + { + ret = NRF_ERROR_BUSY; + } + else + { + usbd_drv_ep_state_t * p_state = ep_state_access(ep); + p_transfer->p_data = p_state->transfer_set.p_data; + p_transfer->size = p_state->transfer_set.size - p_state->transfer_left.size; + ret = p_state->status; + } + + CRITICAL_REGION_EXIT(); + return ret; +} + +size_t nrf_drv_usbd_epout_size_get(nrf_drv_usbd_ep_t ep) +{ + return nrf_usbd_epout_size_get(ep_to_hal(ep)); +} + +bool nrf_drv_usbd_ep_is_busy(nrf_drv_usbd_ep_t ep) +{ + return (0 != (m_ep_dma_waiting & (1UL << ep2bit(ep)))); +} + +void nrf_drv_usbd_ep_stall(nrf_drv_usbd_ep_t ep) +{ + NRF_LOG_DEBUG("USB: EP %x stalled.\r\n", ep); + nrf_usbd_ep_stall(ep_to_hal(ep)); +} + +void nrf_drv_usbd_ep_stall_clear(nrf_drv_usbd_ep_t ep) +{ + nrf_usbd_ep_unstall(ep_to_hal(ep)); +} + +bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep) +{ + return nrf_usbd_ep_is_stall(ep_to_hal(ep)); +} + +void nrf_drv_usbd_setup_get(nrf_drv_usbd_setup_t * const p_setup) +{ + memset(p_setup, 0, sizeof(nrf_drv_usbd_setup_t)); + p_setup->bmRequestType = nrf_usbd_setup_bmrequesttype_get(); + p_setup->bmRequest = nrf_usbd_setup_brequest_get(); + p_setup->wValue = nrf_usbd_setup_wvalue_get(); + p_setup->wIndex = nrf_usbd_setup_windex_get(); + p_setup->wLength = nrf_usbd_setup_wlength_get(); +} + +void nrf_drv_usbd_setup_data_clear(void) +{ + nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT); +} + +void nrf_drv_usbd_setup_clear(void) +{ + nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT); + nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS); +} + +void nrf_drv_usbd_setup_stall(void) +{ + NRF_LOG_DEBUG("Setup stalled.\r\n"); + nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STALL); +} + +nrf_drv_usbd_ep_t nrf_drv_usbd_last_setup_dir_get(void) +{ + return m_last_setup_dir; +} + +void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep) +{ + ASSERT(NRF_USBD_EPOUT_CHECK(ep)); + + if(m_ep_ready & (1U << ep2bit(ep))) + { + if (!NRF_USBD_EPISO_CHECK(ep)) + { + ret_code_t ret; + NRF_DRV_USBD_TRANSFER_OUT(transfer, 0, 0); + ret = nrf_drv_usbd_ep_transfer(ep, &transfer, NULL); + ASSERT(ret == NRF_SUCCESS); + UNUSED_VARIABLE(ret); + } + } +} + +#endif // USBD_ENABLED diff --git a/components/drivers_nrf/usbd/nrf_drv_usbd.h b/components/drivers_nrf/usbd/nrf_drv_usbd.h new file mode 100644 index 0000000..9ba7b41 --- /dev/null +++ b/components/drivers_nrf/usbd/nrf_drv_usbd.h @@ -0,0 +1,659 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_DRV_USBD_H__ +#define NRF_DRV_USBD_H__ + +#include "nrf_drv_common.h" +#include "sdk_errors.h" +#include "nrf_usbd.h" +#include +#include +#include "app_util.h" +/** + * @defgroup nrf_drv_usbd USB Device raw IP HAL and driver + * @ingroup nrf_drivers + * @brief @tagAPI52840 USB Device APIs. + * @details The USB Device HAL provides basic APIs for accessing + * the registers of the USBD. + * The USB Device driver provides APIs on a higher level. + */ + +/** + * @ingroup nrf_drv_usbd + * @defgroup nrf_usbdraw_drv USB Device raw IP driver + * + * @brief @tagAPI52840 USB Device raw IP driver. + * @{ + */ + +/** + * @name Possible schemes of DMA scheduling + * + * Definition of available configuration constants used by DMA scheduler + * @{ + */ + /** + * @brief Highly prioritized access + * + * Endpoint with lower number has always higher priority and its data would + * be transfered first. + * OUT endpoints ale processed before IN endpoints + */ + #define NRF_DRV_USBD_DMASCHEDULER_PRIORITIZED 0 + + /** + * @brief Round robin scheme + * + * All endpoints are processed in round-robin scheme. + * It means that when one endpoint is processed next in order would be + * the nearest with lower number. + * When no endpoints with lower number requires processing - then + * all endpoints from 0 are tested. + */ + #define NRF_DRV_USBD_DMASCHEDULER_ROUNDROBIN 1 + +/** @} */ + +/** + * @brief Number of bytes in the endpoint + * + * Constant that informs about endpoint size + */ +#define NRF_DRV_USBD_EPSIZE 64 + +/** + * @brief Number of bytes for isochronous endpoints + * + * Number of bytes for isochronous endpoints in total. + * This number would be shared between IN and OUT endpoint. + * It may be also assigned totaly to one endpoint. + * @sa nrf_usbd_isosplit_set + * @sa nrf_usbd_isosplit_get + */ +#define NRF_DRV_USBD_ISOSIZE 1024 + +/** + * @name Macros for creating endpoint identifiers + * + * Auxiliary macros to be used to create Endpoint identifier that is compatible + * with USB specification. + * @{ + */ + + /** + * @brief Create identifier for IN endpoint + * + * Simple macro to create IN endpoint identifier for given endpoint number. + * + * @param[in] n Endpoint number. + * + * @return Endpoint identifier that connects endpoint number and endpoint direction. + */ + #define NRF_DRV_USBD_EPIN(n) ((nrf_drv_usbd_ep_t)NRF_USBD_EPIN(n)) + /** + * @brief Create identifier for OUT endpoint + * + * Simple macro to create OUT endpoint identifier for given endpoint number. + * + * @param[in] n Endpoint number. + * + * @return Endpoint identifier that connects endpoint number and endpoint direction. + */ + #define NRF_DRV_USBD_EPOUT(n) ((nrf_drv_usbd_ep_t)NRF_USBD_EPOUT(n)) + +/** @} */ + +/** + * @brief Endpoint identifier + * + * Endpoint identifier used in the driver. + * This endpoint number is consistent with USB 2.0 specification. + */ +typedef enum +{ + NRF_DRV_USBD_EPOUT0 = NRF_USBD_EPOUT(0), /**< Endpoint OUT 0 */ + NRF_DRV_USBD_EPOUT1 = NRF_USBD_EPOUT(1), /**< Endpoint OUT 1 */ + NRF_DRV_USBD_EPOUT2 = NRF_USBD_EPOUT(2), /**< Endpoint OUT 2 */ + NRF_DRV_USBD_EPOUT3 = NRF_USBD_EPOUT(3), /**< Endpoint OUT 3 */ + NRF_DRV_USBD_EPOUT4 = NRF_USBD_EPOUT(4), /**< Endpoint OUT 4 */ + NRF_DRV_USBD_EPOUT5 = NRF_USBD_EPOUT(5), /**< Endpoint OUT 5 */ + NRF_DRV_USBD_EPOUT6 = NRF_USBD_EPOUT(6), /**< Endpoint OUT 6 */ + NRF_DRV_USBD_EPOUT7 = NRF_USBD_EPOUT(7), /**< Endpoint OUT 7 */ + NRF_DRV_USBD_EPOUT8 = NRF_USBD_EPOUT(8), /**< Endpoint OUT 8 */ + + NRF_DRV_USBD_EPIN0 = NRF_USBD_EPIN(0), /**< Endpoint IN 0 */ + NRF_DRV_USBD_EPIN1 = NRF_USBD_EPIN(1), /**< Endpoint IN 1 */ + NRF_DRV_USBD_EPIN2 = NRF_USBD_EPIN(2), /**< Endpoint IN 2 */ + NRF_DRV_USBD_EPIN3 = NRF_USBD_EPIN(3), /**< Endpoint IN 3 */ + NRF_DRV_USBD_EPIN4 = NRF_USBD_EPIN(4), /**< Endpoint IN 4 */ + NRF_DRV_USBD_EPIN5 = NRF_USBD_EPIN(5), /**< Endpoint IN 5 */ + NRF_DRV_USBD_EPIN6 = NRF_USBD_EPIN(6), /**< Endpoint IN 6 */ + NRF_DRV_USBD_EPIN7 = NRF_USBD_EPIN(7), /**< Endpoint IN 7 */ + NRF_DRV_USBD_EPIN8 = NRF_USBD_EPIN(8), /**< Endpoint IN 8 */ +}nrf_drv_usbd_ep_t; + +/** + * @brief Events generated by the library + * + * Enumeration of possible events that may be generated by the library. + */ +typedef enum +{ + NRF_DRV_USBD_EVT_SOF, /**< Start Of Frame event on USB bus detected */ + NRF_DRV_USBD_EVT_RESET, /**< Reset condition on USB bus detected */ + NRF_DRV_USBD_EVT_SUSPEND, /**< This device should go to suspend mode now */ + NRF_DRV_USBD_EVT_RESUME, /**< This device should resume from suspend now */ + NRF_DRV_USBD_EVT_SETUP, /**< Setup frame received and decoded */ + NRF_DRV_USBD_EVT_EPTRANSFER, /**< + * For Rx (OUT: Host->Device): + * 1. The packet has been received but there is no buffer prepared for transfer already. + * 2. Whole transfer has been finished + * + * For Tx (IN: Device->Host): + * The last packet from requested transfer has been transfered over USB bus and acknowledged + */ + NRF_DRV_USBD_EVT_CNT /**< Number of defined events */ +}nrf_drv_usbd_event_type_t; + +/** + * @brief Possible endpoint error codes + * + * Error codes that may be returned with @ref NRF_DRV_USBD_EVT_EPTRANSFER + */ +typedef enum +{ + NRF_USBD_EP_OK, /**< No error */ + NRF_USBD_EP_WAITING, /**< Data received, no buffer prepared already - waiting for configured transfer */ + NRF_USBD_EP_OVERLOAD, /**< Received number of bytes cannot fit given buffer + * This error would also be returned when next_transfer function has been defined + * but currently received data cannot fit completely in current buffer. + * No data split from single endpoint transmission is supported. + * + * When this error is reported - data is left inside endpoint buffer. + * Clear endpoint or prepare new buffer and read it. + */ + NRF_USBD_EP_ABORTED, /**< EP0 transfer can be aborted when new setup comes. + * Any other transfer can be aborted by USB reset or library stopping. + */ +}nrf_drv_usbd_ep_status_t; + + +/** + * @brief Event structure + * + * Structure passed to event handler + */ +typedef struct +{ + nrf_drv_usbd_event_type_t type; + union + { + struct{ + uint16_t framecnt; //!< Current value of frame counter + }sof; //!< Data aviable for @ref NRF_DRV_USBD_EVT_SOF + struct{ + nrf_drv_usbd_ep_t ep; //!< Endpoint number + }isocrc; + struct{ + nrf_drv_usbd_ep_t ep; //!< Endpoint number + nrf_drv_usbd_ep_status_t status; //!< Status for the endpoint + }eptransfer; + }data; +}nrf_drv_usbd_evt_t; + +/** + * @brief Helper macro to create endpoint transfer event + */ +#define NRF_DRV_USBD_EP_TRANSFER_EVENT(name, endpont, ep_stat) \ + nrf_drv_usbd_evt_t name = { \ + NRF_DRV_USBD_EVT_EPTRANSFER, \ + .data = { \ + .eptransfer = { \ + .ep = endpont, \ + .status = ep_stat \ + } \ + } \ + } + +/** + * @brief USBD event callback function type. + * + * @param[in] p_event Event information structure. + */ +typedef void (*nrf_drv_usbd_event_handler_t)(nrf_drv_usbd_evt_t const * const p_event); + +/** + * @brief The structure to be filled with the information about next transfer + * + * When the next transfer is set as a buffer it would get a pointer to this + * structure to fill it with required transfer data. + */ +typedef struct +{ + union + { + void const * tx; //!< Constant tx buffer pointer + void * rx; //!< Writable rx buffer pointer + uint32_t ptr; //!< Numeric value used internally by the library + }p_data; //!< Union with available data pointers used by the library + size_t size; //!< Size of the requested transfer +}nrf_drv_usbd_transfer_t; + +/** + * @brief Helper macro for declaring IN transfer item (@ref nrf_drv_usbd_transfer_t) + * + * @param name Instance name + * @param tx_buff Buffer to transfer + * @param tx_size Transfer size + * */ +#define NRF_DRV_USBD_TRANSFER_IN(name, tx_buff, tx_size) \ + nrf_drv_usbd_transfer_t name = { \ + .p_data = { .tx = (tx_buff) }, \ + .size = (tx_size), \ + } + +/** + * @brief Helper macro for declaring OUT transfer item (@ref nrf_drv_usbd_transfer_t) + * + * @param name Instance name + * @param rx_buff Buffer to transfer + * @param rx_size Transfer size + * */ +#define NRF_DRV_USBD_TRANSFER_OUT(name, rx_buff, rx_size) \ + nrf_drv_usbd_transfer_t name = { \ + .p_data = { .rx = (rx_buff) }, \ + .size = (rx_size), \ + } + +/** + * @brief USBD event callback for the endpoint + * + * @param[out] p_next Structure with the data for the next transfer to be filled. + * Required only if the function returns true. + * @param[in] p_contex Contex variable configured with the endpoint. + * + * @retval false Nothing more to transfer + * @retval true Settings to the next transfer filled into @c p_next. + */ +typedef bool (*nrf_drv_usbd_next_transfer_handler_t)(nrf_drv_usbd_transfer_t * p_next, void * p_context); + +/** + * @brief USBD transfer callback structure + * + * Structure used to setup the callback for any type of the transfer + */ +typedef struct +{ + nrf_drv_usbd_next_transfer_handler_t handler; //!< The event handler to be called when buffer is ready. + void * p_context; //!< Context pointer to be send to every called event. +}nrf_drv_usbd_transfer_handler_desc_t; + + +/** + * @brief Setup packet structure + * + * Structure that contains interpreted SETUP packet. + */ +typedef struct +{ + uint8_t bmRequestType; //!< byte 0 + uint8_t bmRequest; //!< byte 1 + uint16_t wValue; //!< byte 2 + uint16_t wIndex; //!< byte 4, 5 + uint16_t wLength; //!< byte 6, 7 +}nrf_drv_usbd_setup_t; + +/** + * @brief Library initialization + * + * @param[in] event_handler Event handler provided by the user. + */ +ret_code_t nrf_drv_usbd_init(nrf_drv_usbd_event_handler_t const event_handler); + +/** + * @brief Library deinitialization + */ +ret_code_t nrf_drv_usbd_uninit(void); + +/** + * @brief Enable the USBD port + * + * After calling this function USBD peripheral would be enabled. + * It means that High Frequency clock would be requested and USB LDO would be enabled. + * + * In normal situation this function should be called in reaction to USBDETECTED + * event from POWER peripheral. + * + * Interrupts and USB pins pull-up would stay disabled until @ref nrf_drv_usbd_start + * function is called. + */ +void nrf_drv_usbd_enable(void); + +/** + * @brief Disable the USBD port + * + * After calling this function USBD peripheral would be disabled. + * No events would be detected or processed by the library. + * Clock for the peripheral would be disconnected. + */ +void nrf_drv_usbd_disable(void); + +/** + * @brief Start USB functionality + * + * After calling this function USBD peripheral should be fully functional + * and all new incoming events / interrupts would be processed by the library. + * + * Also only after calling this function host sees new connected device. + * + * Call this function when USBD power LDO regulator is ready - on USBPWRRDY event + * from POWER peripheral. + * + * @param enable_sof The flag that is used to enable SOF processing. + * If it is false, SOF interrupt is left disabled and will not be generated. + * This improves power saving if SOF is not required. + * + * @note If the isochronous endpoints are going to be used, + * it is required to enable the SOF. + * In other case any isochronous endpoint would stay busy + * after first transmission. + */ +void nrf_drv_usbd_start(bool enable_sof); + +/** + * @brief Stop USB functionality + * + * This function disables USBD pull-up and interrupts. + * + * @note + * This function can also be used to logically disconnect USB from the HOST that + * would force it to enumerate device after calling @ref nrf_drv_usbd_start. + */ +void nrf_drv_usbd_stop(void); + +/** + * @brief Check if driver is initialized + * + * @retval false Driver is not initialized + * @retval true Driver is initialized + */ +bool nrf_drv_usbd_is_initialized(void); + +/** + * @brief Check if driver is enabled + * + * @retval false Driver is disabled + * @retval true Driver is enabled + */ +bool nrf_drv_usbd_is_enabled(void); + +/** + * @brief Check if driver is started + * + * @retval false Driver is not started + * @retval true Driver is started (fully functional) + * @note The USBD peripheral interrupt state is checked + */ +bool nrf_drv_usbd_is_started(void); + +/** + * @brief Configure packet size that should be supported by the endpoint + * + * The real endpoint buffer size is always the same. + * This value sets max packet size that would be transmitted over the endpoint. + * This is required by the library + * + * @param[in] ep Endpoint number + * @param[in] size Required maximum packet size + * + * @note Endpoint size is always set to @ref NRF_DRV_USBD_EPSIZE or @ref NRF_DRV_USBD_ISOSIZE / 2 + * when @ref nrf_drv_usbd_ep_enable function is called. + */ +void nrf_drv_usbd_ep_max_packet_size_set(nrf_drv_usbd_ep_t ep, uint16_t size); + +/** + * @brief Get configured endpoint packet size + * + * Function to get configured endpoint size on the buffer. + * + * @param[in] ep Endpoint number + * + * @return Maximum pocket size configured on selected endpoint + */ +uint16_t nrf_drv_usbd_ep_max_packet_size_get(nrf_drv_usbd_ep_t ep); + +/** + * @brief Enable selected endpoint + * + * This function enables endpoint itself and its interrupts. + * @param ep Endpoint number to enable + * + * @note + * Max packet size is set to endpoint default maximum value. + * + * @sa nrf_drv_usbd_ep_max_packet_size_set + */ +void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep); + +/** + * @brief Disable selected endpoint + * + * This function disables endpoint itself and its interrupts. + * @param ep Endpoint number to disable + */ +void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep); + +/** + * @brief Start sending data over endpoint + * + * Function initializes endpoint transmission. + * This is asynchronous function - it finishes immediately after configuration + * for transmission is prepared. + * + * @note Data buffer pointed by p_data have to be kept active till + * @ref NRF_DRV_USBD_EVT_EPTRANSFER event is generated. + * + * @param[in] ep Endpoint number. + * For IN endpoint sending would be initiated. + * For OUT endpoint receiving would be initiated. + * @param[in] p_transfer + * @param[in] p_handler Description of transfer handler to be called when buffer is ready. + * Can be NULL when not required by the caller. + * + * @retval NRF_ERROR_BUSY Selected endpoint is pending. + * @retval NRF_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0. + * @retval NRF_ERROR_FORBIDDEN Endpoint stalled. + * @retval NRF_SUCCESS Transfer queued or started. + */ +ret_code_t nrf_drv_usbd_ep_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer, + nrf_drv_usbd_transfer_handler_desc_t const * const p_handler); + +/** + * @brief Get the information about last finished transfer + * + * Function returns the status of the last buffer set for transfer on selected endpoint. + * The status considers last buffer set by @ref nrf_drv_usbd_ep_transfer function or + * by transfer callback function. + * + * @param[in] ep Endpoint number. + * @param[out] p_transfer Structure that would be filled by transfer details: buffer pointer and number of bytes received. + * + * @retval NRF_SUCCESS Transfer already finished + * @retval NRF_ERROR_BUSY Ongoing transfer + * @retval NRF_ERROR_DATA_SIZE Too much of data received that cannot fit into buffer and cannot be splited into chunks. + * This may happen if buffer size is not a multiplication of endpoint buffer size. + */ +ret_code_t nrf_drv_usbd_ep_status_get(nrf_drv_usbd_ep_t ep, nrf_drv_usbd_transfer_t * p_transfer); + +/** + * @brief Get number of received bytes + * + * Get the number of received bytes. + * The function behavior is undefined when called on IN endpoint. + * + * @param ep Endpoint number. + * + * @return Number of received bytes + */ +size_t nrf_drv_usbd_epout_size_get(nrf_drv_usbd_ep_t ep); + +/** + * @brief Check if endpoint buffer is ready or is under USB IP control + * + * Function to test if endpoint is busy. + * Endpoint that is busy cannot be accessed by MCU. + * It means that: + * - OUT (TX) endpoint: Last uploaded data is still in endpoint and is waiting + * to be received by the host. + * - IN (RX) endpoint: Endpoint is ready to receive data from the host + * and the endpoint does not have any data. + * When endpoint is not busy: + * - OUT (TX) endpoint: New data can be uploaded. + * - IN (RX) endpoint: New data can be downloaded using @ref nrf_drv_usbd_ep_transfer + * function. + */ +bool nrf_drv_usbd_ep_is_busy(nrf_drv_usbd_ep_t ep); + +/** + * @brief Stall endpoint + * + * Stall endpoit to send error information during next transfer request from + * the host. + * + * @note To stall endpoint it is safer to use @ref nrf_drv_usbd_setup_stall + * @note Stalled endpoint would not be cleared when DMA transfer finishes. + * + * @param ep Endpoint number to stall + * + */ +void nrf_drv_usbd_ep_stall(nrf_drv_usbd_ep_t ep); + +/** + * @brief Clear stall flag on endpoint + * + * This function clears endpoint that is stalled. + * @note + * If it is OUT endpoint (receiving) it would be also prepared for reception. + * It means that busy flag would be set. + * @note + * In endpoint (transmitting) would not be cleared - it gives possibility to + * write new data before transmitting. + */ +void nrf_drv_usbd_ep_stall_clear(nrf_drv_usbd_ep_t ep); + +/** + * @brief Check if endpoint is stalled + * + * This function gets stall state of selected endpoint + * + * @param ep Endpoint number to check + */ +bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep); + +/** + * @brief Get parsed setup data + * + * Function fills the parsed setup data structure. + * + * @param[out] p_setup Pointer to data structure that would be filled by + * parsed data. + */ +void nrf_drv_usbd_setup_get(nrf_drv_usbd_setup_t * const p_setup); + +/** + * @brief Clear only for data transmission on setup endpoint + * + * This function may be called if any more data in control write transfer is expected. + * Clears only OUT endpoint to be able to take another OUT data token. + * It does not allow STATUS stage. + * @sa nrf_drv_usbd_setup_clear + */ +void nrf_drv_usbd_setup_data_clear(void); + +/** + * @brief Clear setup endpoint + * + * This function acknowledges setup when SETUP command was received and processed. + * It has to be called if no data respond for the SETUP command is sent. + * + * When there is any data transmission after SETUP command the data transmission + * itself would clear the endpoint. + */ +void nrf_drv_usbd_setup_clear(void); + +/** + * @brief Stall setup endpoint + * + * Mark and error on setup endpoint. + */ +void nrf_drv_usbd_setup_stall(void); + +/** +* @note +* This function locks interrupts that may be costly. +* It is good idea to test if the endpoint is still busy before calling this function: +* @code + (m_ep_dma_waiting & (1U << ep2bit(ep))) +* @endcode +* This function would check it again, but it makes it inside critical section. +*/ +void usbd_drv_ep_abort(nrf_drv_usbd_ep_t ep); + +/** + * @brief Get the information about expected transfer SETUP data direction + * + * Function returns the information about last expected transfer direction. + * + * @retval NRF_DRV_USBD_EPOUT0 Expecting OUT (Host->Device) direction or no data + * @retval NRF_DRV_USBD_EPIN0 Expecting IN (Device->Host) direction + */ +nrf_drv_usbd_ep_t nrf_drv_usbd_last_setup_dir_get(void); + +/** + * @brief Drop transfer on OUT endpoint + * + * @param[in] ep OUT endpoint ID + */ +void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep); + +/** @} */ +#endif /* NRF_DRV_USBD_H__ */ diff --git a/components/drivers_nrf/wdt/nrf_drv_wdt.c b/components/drivers_nrf/wdt/nrf_drv_wdt.c index 7f021b6..9dd72e3 100644 --- a/components/drivers_nrf/wdt/nrf_drv_wdt.c +++ b/components/drivers_nrf/wdt/nrf_drv_wdt.c @@ -1,15 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(WDT) #include "nrf_drv_wdt.h" #include "nrf_drv_common.h" #include "nrf_error.h" @@ -19,6 +49,19 @@ #include #include +#define NRF_LOG_MODULE_NAME "WDT" + +#if WDT_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL WDT_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR WDT_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR WDT_CONFIG_DEBUG_COLOR +#else //WDT_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //WDT_CONFIG_LOG_ENABLED +#include "nrf_log.h" +#include "nrf_log_ctrl.h" + + /**@brief WDT event handler. */ static nrf_wdt_event_handler_t m_wdt_event_handler; @@ -45,6 +88,7 @@ ret_code_t nrf_drv_wdt_init(nrf_drv_wdt_config_t const * p_config, nrf_wdt_event_handler_t wdt_event_handler) { ASSERT(wdt_event_handler != NULL); + ret_code_t err_code; m_wdt_event_handler = wdt_event_handler; if (m_state == NRF_DRV_STATE_UNINITIALIZED) @@ -53,7 +97,9 @@ ret_code_t nrf_drv_wdt_init(nrf_drv_wdt_config_t const * p_config, } else { - return NRF_ERROR_INVALID_STATE; // WDT already initialized + err_code = NRF_ERROR_INVALID_STATE; + NRF_LOG_WARNING("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } if (p_config == NULL) @@ -62,11 +108,20 @@ ret_code_t nrf_drv_wdt_init(nrf_drv_wdt_config_t const * p_config, } nrf_wdt_behaviour_set(p_config->behaviour); + + + + + + + nrf_wdt_reload_value_set((p_config->reload_value * 32768) / 1000); nrf_drv_common_irq_enable(WDT_IRQn, p_config->interrupt_priority); - return NRF_SUCCESS; + err_code = NRF_SUCCESS; + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(err_code)); + return err_code; } @@ -77,13 +132,14 @@ void nrf_drv_wdt_enable(void) nrf_wdt_int_enable(NRF_WDT_INT_TIMEOUT_MASK); nrf_wdt_task_trigger(NRF_WDT_TASK_START); m_state = NRF_DRV_STATE_POWERED_ON; + NRF_LOG_INFO("Enabled.\r\n"); } void nrf_drv_wdt_feed(void) { ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); - for(uint32_t i = 0; i < m_alloc_index; i++) + for (uint32_t i = 0; i < m_alloc_index; i++) { nrf_wdt_reload_request_set((nrf_wdt_rr_register_t)(NRF_WDT_RR0 + i)); } @@ -108,6 +164,7 @@ ret_code_t nrf_drv_wdt_channel_alloc(nrf_drv_wdt_channel_id * p_channel_id) result = NRF_ERROR_NO_MEM; } CRITICAL_REGION_EXIT(); + NRF_LOG_INFO("Function: %s, error code: %s.\r\n", (uint32_t)__func__, (uint32_t)ERR_TO_STR(result)); return result; } @@ -116,3 +173,4 @@ void nrf_drv_wdt_channel_feed(nrf_drv_wdt_channel_id channel_id) ASSERT(m_state == NRF_DRV_STATE_POWERED_ON); nrf_wdt_reload_request_set(channel_id); } +#endif //NRF_MODULE_ENABLED(WDT) diff --git a/components/drivers_nrf/wdt/nrf_drv_wdt.h b/components/drivers_nrf/wdt/nrf_drv_wdt.h index 194b40b..b7e250c 100644 --- a/components/drivers_nrf/wdt/nrf_drv_wdt.h +++ b/components/drivers_nrf/wdt/nrf_drv_wdt.h @@ -1,23 +1,54 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @addtogroup nrf_wdt WDT HAL and driver * @ingroup nrf_drivers - * @defgroup lib_driver_wdt WDT driver + * @brief Watchdog timer (WDT) APIs. + * @details The WDT HAL provides basic APIs for accessing the registers of the watchdog timer. + * The WDT driver provides APIs on a higher level. + * @defgroup nrf_drv_wdt WDT driver * @{ * @ingroup nrf_wdt * - * @brief WDT driver. + * @brief Driver for managing the watchdog timer (WDT). */ #ifndef NRF_DRV_WDT_H__ @@ -27,7 +58,11 @@ #include #include "sdk_errors.h" #include "nrf_wdt.h" -#include "nrf_drv_config.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif /**@brief Struct for WDT initialization. */ typedef struct @@ -43,11 +78,11 @@ typedef void (*nrf_wdt_event_handler_t)(void); /**@brief WDT channel id type. */ typedef nrf_wdt_rr_register_t nrf_drv_wdt_channel_id; -#define NRF_DRV_WDT_DEAFULT_CONFIG \ - { \ - .behaviour = WDT_CONFIG_BEHAVIOUR, \ - .reload_value = WDT_CONFIG_RELOAD_VALUE, \ - .interrupt_priority = WDT_CONFIG_IRQ_PRIORITY, \ +#define NRF_DRV_WDT_DEAFULT_CONFIG \ + { \ + .behaviour = (nrf_wdt_behaviour_t)WDT_CONFIG_BEHAVIOUR, \ + .reload_value = WDT_CONFIG_RELOAD_VALUE, \ + .interrupt_priority = WDT_CONFIG_IRQ_PRIORITY, \ } /** * @brief This function initializes watchdog. @@ -57,7 +92,7 @@ typedef nrf_wdt_rr_register_t nrf_drv_wdt_channel_id; * * @note Function asserts if wdt_event_handler is NULL. * - * @return NRF_SUCCESS on success, NRF_ERROR_INVALID_STATE if module ws already initialized. + * @return NRF_SUCCESS on success, otherwise an error code. */ ret_code_t nrf_drv_wdt_init(nrf_drv_wdt_config_t const * p_config, nrf_wdt_event_handler_t wdt_event_handler); @@ -116,6 +151,11 @@ __STATIC_INLINE uint32_t nrf_drv_wdt_ppi_event_addr(nrf_wdt_event_t event) { return nrf_wdt_event_address_get(event); } + +#ifdef __cplusplus +} +#endif + #endif /** @} */ diff --git a/components/libraries/ant_fs/crc.c b/components/libraries/ant_fs/crc.c deleted file mode 100644 index cdc2bc3..0000000 --- a/components/libraries/ant_fs/crc.c +++ /dev/null @@ -1,55 +0,0 @@ -/* -This software is subject to the license described in the license.txt file included with this software distribution. -You may not use this file except in compliance with this license. -Copyright © Dynastream Innovations Inc. 2012 -All rights reserved. -*/ - -#include "crc.h" -#include "compiler_abstraction.h" - - -/**@brief Function for updating the current CRC-16 value for a single byte input. - * - * @param[in] current_crc The current calculated CRC-16 value. - * @param[in] byte The input data byte for the computation. - * - * @return The updated CRC-16 value, based on the input supplied. - */ -static __INLINE uint16_t crc16_get(uint16_t current_crc, uint8_t byte) -{ - static const uint16_t crc16_table[16] = - { - 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, - 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 - }; - - uint16_t temp; - - // Compute checksum of lower four bits of a byte. - temp = crc16_table[current_crc & 0xF]; - current_crc = (current_crc >> 4u) & 0x0FFFu; - current_crc = current_crc ^ temp ^ crc16_table[byte & 0xF]; - - // Now compute checksum of upper four bits of a byte. - temp = crc16_table[current_crc & 0xF]; - current_crc = (current_crc >> 4u) & 0x0FFFu; - current_crc = current_crc ^ temp ^ crc16_table[(byte >> 4u) & 0xF]; - - return current_crc; -} - - -uint16_t crc_crc16_update(uint16_t current_crc, const volatile void * p_data, uint32_t size) -{ - uint8_t * p_block = (uint8_t *)p_data; - - while (size != 0) - { - current_crc = crc16_get(current_crc, *p_block); - p_block++; - size--; - } - - return current_crc; -} diff --git a/components/libraries/ant_fs/crc.h b/components/libraries/ant_fs/crc.h deleted file mode 100644 index fa1297b..0000000 --- a/components/libraries/ant_fs/crc.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -This software is subject to the license described in the license.txt file included with this software distribution. -You may not use this file except in compliance with this license. -Copyright © Dynastream Innovations Inc. 2012 -All rights reserved. -*/ - -/** @file - * @brief The CRC-16 interface. - * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012 - * @defgroup ant_fs_client_main ANT-FS client device simulator - * @{ - * @ingroup nrf_ant_fs_client - * - * @brief The ANT-FS client device simulator. - * - */ - -#ifndef CRC_H__ -#define CRC_H__ - -#include - -/**@brief Function for calculating CRC-16 in blocks. - * - * Feed each consecutive data block into this function, along with the current value of current_crc - * as returned by the previous call of this function. The first call of this function should pass - * the initial value (usually 0) of the crc in current_crc. - - * @param[in] current_crc The current calculated CRC-16 value. - * @param[in] p_data The input data block for computation. - * @param[in] size The size of the input data block in bytes. - * - * @return The updated CRC-16 value, based on the input supplied. - */ -uint16_t crc_crc16_update(uint16_t current_crc, const volatile void * p_data, uint32_t size); - -#endif // CRC_H__ - -/** - *@} - **/ diff --git a/components/libraries/ant_fs/defines.h b/components/libraries/ant_fs/defines.h deleted file mode 100644 index 1cb4a70..0000000 --- a/components/libraries/ant_fs/defines.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -This software is subject to the license described in the license.txt file included with this software distribution. -You may not use this file except in compliance with this license. -Copyright © Dynastream Innovations Inc. 2012 -All rights reserved. -*/ - -/**@file - * @brief Definitions. - * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012 - * @defgroup ant_fs_client_main ANT-FS client device simulator - * @{ - * @ingroup nrf_ant_fs_client - * - * @brief The ANT-FS client device simulator. - * - */ - -#ifndef DEFINES_H__ -#define DEFINES_H__ - -#include - -#define MAX_ULONG 0xFFFFFFFFu /**< The Max value for the type. */ - -/**@brief uint16_t type presentation as an union. */ -typedef union -{ - uint16_t data; /**< The data content. */ - - struct - { - uint8_t low; /**< The low byte of the data content. */ - uint8_t high; /**< The high byte of the data content. */ - } bytes; -} ushort_union_t; - -/**@brief uint32_t type presentation as an union. */ -typedef union -{ - uint32_t data; /**< The data content as a single variable. */ - uint8_t data_bytes[sizeof(uint32_t)]; /**< The data content as a byte array. */ - - struct - { - // The least significant byte of the uint32_t in this structure is referenced by byte0. - uint8_t byte0; /**< Byte 0 of the data content. */ - uint8_t byte1; /**< Byte 1 of the data content. */ - uint8_t byte2; /**< Byte 2 of the data content. */ - uint8_t byte3; /**< Byte 3 of the data content. */ - } bytes; -} ulong_union_t; - -#define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ - -#endif // DEFINES_H__ - -/** - *@} - **/ diff --git a/components/libraries/atomic/nrf_atomic.h b/components/libraries/atomic/nrf_atomic.h new file mode 100644 index 0000000..232517e --- /dev/null +++ b/components/libraries/atomic/nrf_atomic.h @@ -0,0 +1,349 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup nrf_atomic Atomic operations API + * @ingroup app_atfifo + * @{ + * + * @brief @tagAPI52 This module implements C11 stdatomic.h simplified API. + At this point only Cortex-M3/M4 cores are supported (LDREX/STREX instructions). + * Atomic types are limited to @ref nrf_atomic_u32_t and @ref nrf_atomic_flag_t. + */ + +#ifndef NRF_ATOMIC_H__ +#define NRF_ATOMIC_H__ + +#include "sdk_common.h" +#include "nrf_atomic_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Stores value to an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value to store + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_store_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value); + + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Stores value to an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value to store + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value); + + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/** + * @brief Logical OR operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand OR operation + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_or_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Logical OR operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand OR operation + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/** + * @brief Logical AND operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand AND operation + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_and_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(and, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Logical AND operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand AND operation + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(and, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/** + * @brief Logical XOR operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand XOR operation + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_xor_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Logical XOR operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand XOR operation + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/** + * @brief Arithmetic ADD operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand ADD operation + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_add_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(add, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Arithmetic ADD operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand ADD operation + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(add, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/** + * @brief Arithmetic SUB operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand SUB operation + * + * @return Old value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_sub_fetch(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return old_val; +} + +/** + * @brief Arithmetic SUB operation on an atomic object + * + * @param[in] p_data Atomic memory pointer + * @param[in] value Value of second operand SUB operation + * + * @return New value stored into atomic object + * */ +static inline uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value) +{ + uint32_t old_val; + uint32_t new_val; + + NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value); + UNUSED_PARAMETER(old_val); + UNUSED_PARAMETER(new_val); + return new_val; +} + +/**************************************************************************************************/ + +/** + * @brief Logic one bit flag set operation on an atomic object + * + * @param[in] p_data Atomic flag memory pointer + * + * @return Old flag value + * */ +static inline uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data) +{ + return nrf_atomic_u32_or_fetch(p_data, 1); +} + +/** + * @brief Logic one bit flag set operation on an atomic object + * + * @param[in] p_data Atomic flag memory pointer + * + * @return New flag value + * */ +static inline uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data) +{ + return nrf_atomic_u32_or(p_data, 1); +} + +/** + * @brief Logic one bit flag clear operation on an atomic object + * + * @param[in] p_data Atomic flag memory pointer + * + * @return Old flag value + * */ +static inline uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data) +{ + return nrf_atomic_u32_and_fetch(p_data, 0); +} + +/** + * @brief Logic one bit flag clear operation on an atomic object + * + * @param[in] p_data Atomic flag memory pointer + * + * @return New flag value + * */ +static inline uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data) +{ + return nrf_atomic_u32_and(p_data, 0); +} + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_ATOMIC_H__ */ + +/** @} */ diff --git a/components/libraries/atomic/nrf_atomic_internal.h b/components/libraries/atomic/nrf_atomic_internal.h new file mode 100644 index 0000000..11e2bab --- /dev/null +++ b/components/libraries/atomic/nrf_atomic_internal.h @@ -0,0 +1,245 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_ATOMIC_INTERNAL_H__ +#define NRF_ATOMIC_INTERNAL_H__ + +#include "sdk_common.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * + * @defgroup nrf_atomic_internal Atomic operations internals + * @ingroup nrf_atomic + * @{ + * + */ + +/* Only Cortex M cores > 3 support LDREX/STREX instructions*/ +#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0 +#error "Unsupported core version" +#endif + +/** + * @brief Atomic 32 bit unsigned type + * */ +typedef volatile uint32_t nrf_atomic_u32_t; + +/** + * @brief Atomic 1 bit flag type (technically 32 bit) + * */ +typedef volatile uint32_t nrf_atomic_flag_t; + +#if defined ( __CC_ARM ) +static __asm uint32_t nrf_atomic_internal_mov(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + /* The base standard provides for passing arguments in core registers (r0-r3) and on the stack. + * Registers r4 and r5 have to be saved on stack. Note that only even number of register push are + * allowed. This is a requirement of the Procedure Call Standard for the ARM Architecture [AAPCS]. + * */ + push {r4, r5} + mov r4, r0 + +loop_mov + ldrex r0, [r4] + mov r5, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_mov + + str r5, [r2] + pop {r4, r5} + bx lr +} + + +static __asm uint32_t nrf_atomic_internal_orr(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + push {r4, r5} + mov r4, r0 + +loop_orr + ldrex r0, [r4] + orr r5, r0, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_orr + + str r5, [r2] + pop {r4, r5} + bx lr +} + +static __asm uint32_t nrf_atomic_internal_and(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + push {r4, r5} + mov r4, r0 + +loop_and + ldrex r0, [r4] + and r5, r0, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_and + + str r5, [r2] + pop {r4, r5} + bx lr +} + +static __asm uint32_t nrf_atomic_internal_eor(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + push {r4, r5} + mov r4, r0 + +loop_eor + ldrex r0, [r4] + eor r5, r0, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_eor + + str r5, [r2] + pop {r4, r5} + bx lr +} + +static __asm uint32_t nrf_atomic_internal_add(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + push {r4, r5} + mov r4, r0 + +loop_add + ldrex r0, [r4] + add r5, r0, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_add + + str r5, [r2] + pop {r4, r5} + bx lr +} + +static __asm uint32_t nrf_atomic_internal_sub(nrf_atomic_u32_t * p_ptr, + uint32_t value, + uint32_t * p_new) +{ + push {r4, r5} + mov r4, r0 + +loop_sub + ldrex r0, [r4] + sub r5, r0, r1 + strex r3, r5, [r4] + cmp r3, #0 + bne loop_sub + + str r5, [r2] + pop {r4, r5} + bx lr +} + + +#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \ + old_val = nrf_atomic_internal_##asm_op(ptr, value, &new_val) + +#elif defined ( __ICCARM__ ) || defined ( __GNUC__ ) + +/** + * @brief Atomic operation generic macro + * @param[in] asm_op operation: mov, orr, and, eor, add, sub + * @param[out] old_val atomic object output (uint32_t), value before operation + * @param[out] new_val atomic object output (uint32_t), value after operation + * @param[in] value atomic operation operand + * */ +#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \ +{ \ + uint32_t str_res; \ + __ASM volatile( \ + "1: ldrex %["#old_val"], [%["#ptr"]]\n" \ + NRF_ATOMIC_OP_##asm_op(new_val, old_val, value) \ + " strex %[str_res], %["#new_val"], [%["#ptr"]]\n" \ + " teq %[str_res], #0\n" \ + " bne.n 1b" \ + : \ + [old_val]"=&r" (old_val), \ + [new_val]"=&r" (new_val), \ + [str_res]"=&r" (str_res) \ + : \ + [ptr]"r" (ptr), \ + [value]"r" (value) \ + : "cc"); \ + UNUSED_PARAMETER(str_res); \ +} + +#define NRF_ATOMIC_OP_mov(new_val, old_val, value) "mov %["#new_val"], %["#value"]\n" +#define NRF_ATOMIC_OP_orr(new_val, old_val, value) "orr %["#new_val"], %["#old_val"], %["#value"]\n" +#define NRF_ATOMIC_OP_and(new_val, old_val, value) "and %["#new_val"], %["#old_val"], %["#value"]\n" +#define NRF_ATOMIC_OP_eor(new_val, old_val, value) "eor %["#new_val"], %["#old_val"], %["#value"]\n" +#define NRF_ATOMIC_OP_add(new_val, old_val, value) "add %["#new_val"], %["#old_val"], %["#value"]\n" +#define NRF_ATOMIC_OP_sub(new_val, old_val, value) "sub %["#new_val"], %["#old_val"], %["#value"]\n" + +#else +#error "Unsupported compiler" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_ATOMIC_INTERNAL_H__ */ + +/** @} */ diff --git a/components/libraries/atomic/nrf_atomic_sanity_check.h b/components/libraries/atomic/nrf_atomic_sanity_check.h new file mode 100644 index 0000000..683ef04 --- /dev/null +++ b/components/libraries/atomic/nrf_atomic_sanity_check.h @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_ATOMIC_SANITY_CHECK_H__ +#define NRF_ATOMIC_SANITY_CHECK_H__ + +#include "nrf_atomic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Quick sanity check of nrf_atomic API + * */ +static inline void nrf_atomic_sanity_check(void) +{ +#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) + nrf_atomic_u32_t val; + nrf_atomic_u32_t flag; + + /*Fetch version tests*/ + val = 0; + ASSERT(nrf_atomic_u32_store_fetch(&val, 10) == 0); + ASSERT(nrf_atomic_u32_store_fetch(&val, 0) == 10); + + val = 0; + ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 16) == 0); + ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 5) == ((1 << 16))); + ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 5) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or_fetch(&val, 0) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or_fetch(&val, 0xFFFFFFFF) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or_fetch(&val, 0xFFFFFFFF) == (0xFFFFFFFF)); + + val = 0xFFFFFFFF; + ASSERT(nrf_atomic_u32_and_fetch(&val, ~(1 << 16)) == 0xFFFFFFFF); + ASSERT(nrf_atomic_u32_and_fetch(&val, ~(1 << 5)) == (0xFFFFFFFF & ~((1 << 16)))); + ASSERT(nrf_atomic_u32_and_fetch(&val, 0) == (0xFFFFFFFF & ~(((1 << 16) | (1 << 5))))); + ASSERT(nrf_atomic_u32_and_fetch(&val, 0xFFFFFFFF) == (0)); + + val = 0; + ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 16)) == 0); + ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 5)) == ((1 << 16))); + ASSERT(nrf_atomic_u32_xor_fetch(&val, 0) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 16) | (1 << 5)) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_xor_fetch(&val, 0) == (0)); + + val = 0; + ASSERT(nrf_atomic_u32_add_fetch(&val, 100) == 0); + ASSERT(nrf_atomic_u32_add_fetch(&val, 100) == 100); + ASSERT(nrf_atomic_u32_add_fetch(&val, 1 << 24) == 200); + ASSERT(nrf_atomic_u32_add_fetch(&val, 0) == (200 + (1 << 24))); + ASSERT(nrf_atomic_u32_add_fetch(&val, 0xFFFFFFFF) == (200 + (1 << 24))); + ASSERT(nrf_atomic_u32_add_fetch(&val, 0) == (200 - 1 + (1 << 24))); + + val = 1000; + ASSERT(nrf_atomic_u32_sub_fetch(&val, 100) == 1000); + ASSERT(nrf_atomic_u32_sub_fetch(&val, 100) == 900); + ASSERT(nrf_atomic_u32_sub_fetch(&val, 0) == 800); + ASSERT(nrf_atomic_u32_sub_fetch(&val, 0xFFFFFFFF) == 800); + ASSERT(nrf_atomic_u32_sub_fetch(&val, 0) == 801); + + flag = 0; + ASSERT(nrf_atomic_flag_set_fetch(&flag) == 0); + ASSERT(nrf_atomic_flag_set_fetch(&flag) == 1); + ASSERT(nrf_atomic_flag_clear_fetch(&flag) == 1); + ASSERT(nrf_atomic_flag_clear_fetch(&flag) == 0); + + /*No fetch version tests*/ + val = 0; + ASSERT(nrf_atomic_u32_store(&val, 10) == 10); + ASSERT(nrf_atomic_u32_store(&val, 0) == 0); + + val = 0; + ASSERT(nrf_atomic_u32_or(&val, 1 << 16) == 1 << 16); + ASSERT(nrf_atomic_u32_or(&val, 1 << 5) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or(&val, 1 << 5) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or(&val, 0) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_or(&val, 0xFFFFFFFF) == 0xFFFFFFFF); + + val = 0xFFFFFFFF; + ASSERT(nrf_atomic_u32_and(&val, ~(1 << 16)) == (0xFFFFFFFF & ~((1 << 16)))); + ASSERT(nrf_atomic_u32_and(&val, ~(1 << 5)) == (0xFFFFFFFF & ~(((1 << 16) | (1 << 5))))); + ASSERT(nrf_atomic_u32_and(&val, 0) == 0); + + val = 0; + ASSERT(nrf_atomic_u32_xor(&val, (1 << 16)) == ((1 << 16))); + ASSERT(nrf_atomic_u32_xor(&val, (1 << 5)) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_xor(&val, 0) == ((1 << 16) | (1 << 5))); + ASSERT(nrf_atomic_u32_xor(&val, (1 << 16) | (1 << 5)) == 0); + + val = 0; + ASSERT(nrf_atomic_u32_add(&val, 100) == 100); + ASSERT(nrf_atomic_u32_add(&val, 100) == 200); + ASSERT(nrf_atomic_u32_add(&val, 1 << 24) == (200 + (1 << 24))); + ASSERT(nrf_atomic_u32_add(&val, 0) == (200 + (1 << 24))); + ASSERT(nrf_atomic_u32_add(&val, 0xFFFFFFFF) == (200 - 1 + (1 << 24))); + + val = 1000; + ASSERT(nrf_atomic_u32_sub(&val, 100) == 900); + ASSERT(nrf_atomic_u32_sub(&val, 100) == 800); + ASSERT(nrf_atomic_u32_sub(&val, 0) == 800); + ASSERT(nrf_atomic_u32_sub(&val, 0xFFFFFFFF) == 801); + + flag = 0; + ASSERT(nrf_atomic_flag_set(&flag) == 1); + ASSERT(nrf_atomic_flag_set(&flag) == 1); + ASSERT(nrf_atomic_flag_clear(&flag) == 0); + ASSERT(nrf_atomic_flag_clear(&flag) == 0); +#endif +} + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_ATOMIC_SANITY_CHECK_H__ */ diff --git a/components/libraries/atomic_fifo/app_atfifo.c b/components/libraries/atomic_fifo/app_atfifo.c new file mode 100644 index 0000000..f700bec --- /dev/null +++ b/components/libraries/atomic_fifo/app_atfifo.c @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_atfifo.h" +#include "app_atfifo_internal.h" +#include +#include "app_util.h" + + +/* Unions testing */ +STATIC_ASSERT(sizeof(nrf_atfifo_postag_t) == sizeof(uint32_t)); + + +ret_code_t app_atfifo_init(app_atfifo_t * const p_fifo, void * p_buf, uint16_t buf_size, uint16_t item_size) +{ + if(NULL == p_buf) + { + return NRF_ERROR_NULL; + } + if(0 != (buf_size % item_size)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_fifo->p_buf = p_buf; + p_fifo->tail.tag = 0; + p_fifo->head.tag = 0; + p_fifo->buf_size = buf_size; + p_fifo->item_size = item_size; + + return NRF_SUCCESS; +} + + +ret_code_t app_atfifo_clear(app_atfifo_t * const p_fifo) +{ + bool resleased = app_atfifo_space_clear(p_fifo); + return resleased ? NRF_SUCCESS : NRF_ERROR_BUSY; +} + + +ret_code_t app_atfifo_put(app_atfifo_t * const p_fifo, void const * p_var, size_t size, bool * const p_visible) +{ + app_atfifo_wcontext_t context; + bool visible; + void * p_d = app_atfifo_wopen(p_fifo, &context, size); + if(NULL == p_d) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_d, p_var, size); + + visible = app_atfifo_wcommit(p_fifo, &context); + if(NULL != p_visible) + { + *p_visible = visible; + } + return NRF_SUCCESS; +} + + +void * app_atfifo_wopen_internal(app_atfifo_t * const p_fifo, app_atfifo_wcontext_t * p_context) +{ + if(app_atfifo_wspace_req(p_fifo, &(p_context->last_tail))) + { + return ((uint8_t*)(p_fifo->p_buf)) + p_context->last_tail.pos.wr; + } + return NULL; +} + + +bool app_atfifo_wcommit(app_atfifo_t * const p_fifo, app_atfifo_wcontext_t * p_context) +{ + if((p_context->last_tail.pos.wr) == (p_context->last_tail.pos.rd)) + { + app_atfifo_wspace_close(p_fifo); + return true; + } + return false; +} + + +ret_code_t app_atfifo_get(app_atfifo_t * const p_fifo, void * const p_var, size_t size, bool * p_released) +{ + app_atfifo_rcontext_t context; + bool released; + void const * p_s = app_atfifo_ropen(p_fifo, &context, size); + if(NULL == p_s) + { + return NRF_ERROR_NOT_FOUND; + } + + memcpy(p_var, p_s, size); + + released = app_atfifo_rflush(p_fifo, &context); + if(NULL != p_released) + { + *p_released = released; + } + return NRF_SUCCESS; +} + + +void const * app_atfifo_ropen_internal(app_atfifo_t * const p_fifo, app_atfifo_rcontext_t * p_context) +{ + if(app_atfifo_rspace_req(p_fifo, &(p_context->last_head))) + { + return ((uint8_t*)(p_fifo->p_buf)) + p_context->last_head.pos.rd; + } + return NULL; +} + + +bool app_atfifo_rflush(app_atfifo_t * const p_fifo, app_atfifo_rcontext_t * p_context) +{ + if((p_context->last_head.pos.wr) == (p_context->last_head.pos.rd)) + { + app_atfifo_rspace_close(p_fifo); + return true; + } + return false; +} diff --git a/components/libraries/atomic_fifo/app_atfifo.h b/components/libraries/atomic_fifo/app_atfifo.h new file mode 100644 index 0000000..1f7d5a8 --- /dev/null +++ b/components/libraries/atomic_fifo/app_atfifo.h @@ -0,0 +1,448 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_ATFIFO_H__ +#define APP_ATFIFO_H__ + +#include +#include "nordic_common.h" +#include "nrf_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup app_atfifo Atomic FIFO implementation + * @ingroup app_common + * + * @brief @tagAPI52 FIFO implementation that allows for making atomic transactions without + * locking interrupts. + * + * @details There are two types of functions to prepare FIFO writing: + * - Single function for simple access: + * @code + * if(NRF_SUCCESS != nrf_atfifo_put(&my_fifo, &data, NULL)) + * { + * // Error handling + * } + * @endcode + * - Function pair to limit data coping: + * @code + * struct point3d + * { + * int x, y, z; + * }point3d_t; + * nrf_atfifo_context_t context; + * point3d_t * point; + * + * if(NULL != (point = nrf_atfifo_wopen(&my_fifo, &context))) + * { + * ret_code_t ret; + * point->x = a; + * point->y = b; + * point->z = c; + * if(nrf_atfifo_wcommit(&my_fifo, &context)) + * { + * // Send an information to the rest of the system + * // that there is new data in the FIFO available to read. + * } + * } + * else + * { + * // Error handling + * } + * + * @endcode + * @note + * This Atomic FIFO implementation requires that the operation that was + * opened last would be finished (committed/flushed) first. + * This is typical for operations performed from the interrupt runtime + * when the other operation is performed from main thread. + * + * This implementation does not support typical multithreading operating system + * access where operations can be started and finished in totally unrelated order. + * + * @{ + */ + +/** + * @brief Read and write position structure + * + * A structure that holds read and write position used by fifo head and tail. + */ +typedef struct nrf_atfifo_postag_pos_s +{ + uint16_t wr; //!< First free space to write a data + uint16_t rd; //!< A place after the last data to read +}nrf_atfifo_postag_pos_t; + +/** + * @brief End data index tag + * + * A tag used to mark end of data. + * To properly realize atomic data committing the whole variable has to be + * accessed atomically. + */ +typedef union nrf_atfifo_postag_u +{ + uint32_t tag; //!< Whole tag, used for atomic, 32 bit access + nrf_atfifo_postag_pos_t pos; //! Structure that holds reading and writing position separately +}nrf_atfifo_postag_t; + +/** + * @brief The FIFO instance + * + * The instance of atomic FIFO. + * Used with all FIFO functions. + */ +typedef struct app_atfifo_s +{ + void * p_buf; //!< Pointer to the data buffer + nrf_atfifo_postag_t tail; //!< Read and write tail position tag + nrf_atfifo_postag_t head; //!< Read and write head position tag + uint16_t buf_size; //!< FIFO size in number of bytes (has to be divisible by @c item_size) + uint16_t item_size; //!< Size of single FIFO item +}app_atfifo_t; + +/** + * @brief FIFO write operation context + * + * Context structure used to mark opened commit. + * All the data required to properly access the data and then commit it after writing. + */ +typedef struct app_atfifo_wcontext_s +{ + nrf_atfifo_postag_t last_tail; //!< Tail tag value that was here when opening FIFO to write +}app_atfifo_wcontext_t; + + +/** + * @brief FIFO read operation context + * + * Context structure used to mark opened read operation. + * All the data required to properly flush the accessed data after accessing. + */ +typedef struct app_atfifo_rcontext_s +{ + nrf_atfifo_postag_t last_head; //!< Head tag value that was here when opening FIFO to read +}app_atfifo_rcontext_t; + + +/** + * @defgroup app_atfifo_instmacros FIFO instance macros + * + * A group of macros helpful for FIFO instance creation and initialization. + * They may be used to create and initialize instances for most use cases. + * + * FIFO may also be created and initialized directly using + * @ref app_atfifo_init function. + * @{ + */ + /** + * @brief Macro to generate the name for data buffer + * + * The name of the data buffer that would be created by + * @ref APP_ATFIFO_DEF macro. + * + * @param[in] fifo_id The identifier of the FIFO object. + * + * @return The name of the buffer variable. + */ + #define APP_ATFIFO_BUF_NAME(fifo_id) CONCAT_2(fifo_id, _data) + + /** + * @brief Macro to generate the name for FIFO instance + * + * The name of instance variable that would be created by + * @ref APP_ATFIFO_DEF macro. + * + * @param[in] fifo_id The identifier of the FIFO object. + * + * @return The name of the instance variable. + */ + #define APP_ATFIFO_INST_NAME(fifo_id) CONCAT_2(fifo_id, _inst) + + /** + * @brief Instance creation macro + * + * Creates FIFO object variable itself and + * + * Use example: + * @code + * APP_ATFIFO_DEF(my_fifo, uint16_t, 12); + * APP_ATFIFO_INIT(my_fifo); + * + * uint16_t some_val = 45; + * app_atfifo_put(my_fifo, &some_val, sizeof(some_val), NULL); + * app_atfifo_get(my_fifo, &some_val, sizeof(some_val), NULL); + * @endcode + * + * @param[in] fifo_id The identifier of FIFO object. + * This identifier would be a pointer to the instance. + * It makes it possible to use this directly for the functions + * that operates on the FIFO. + * Because it is static const object, it should be optimized by the compiler. + * @param[in] storage_type The type of data that would be stored in the FIFO. + * @param[in] item_cnt The capacity of created FIFO in maximum number of items that may be stored. + * The phisical size of the buffer would be 1 element bigger. + */ + #define APP_ATFIFO_DEF(fifo_id, storage_type, item_cnt) \ + static storage_type APP_ATFIFO_BUF_NAME(fifo_id)[(item_cnt)+1]; \ + static app_atfifo_t APP_ATFIFO_INST_NAME(fifo_id); \ + static app_atfifo_t * const fifo_id = &APP_ATFIFO_INST_NAME(fifo_id) + + /** + * @brief Use this macro to initialize FIFO declared previously by the macro + * + * Use this macro to simplify FIFO initialization. + * + * @note + * This macro can be only used on FIFO object defined by @ref APP_ATFIFO_DEF macro. + * + * @param[in] fifo_id The identifier of the FIFO object. + * + * @return The value from @ref app_atfifo_init function. + */ + #define APP_ATFIFO_INIT(fifo_id) \ + app_atfifo_init( \ + fifo_id, \ + &APP_ATFIFO_BUF_NAME(fifo_id), \ + sizeof(APP_ATFIFO_BUF_NAME(fifo_id)), \ + sizeof(APP_ATFIFO_BUF_NAME(fifo_id)[0]) \ + ) + +/** @} */ + +/** + * @brief Initializing the FIFO + * + * Preparing FIFO instance to work. + * + * @param[out] p_fifo FIFO object to initialize. + * @param[in,out] p_buf FIFO buffer for storing data. + * @param[in] buf_size Total buffer size (has to be divisible by @c item_size). + * @param[in] item_size Size of single item hold inside the FIFO. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_NULL If a NULL pointer is provided as buffer. + * @retval NRF_ERROR_INVALID_LENGTH If size of buffer provided is divisible by @c item_size. + * + * @note + * Buffer size has to be able to fit 1 element more than designed FIFO capacity. + * This one, empty element is used for overflow checking. + */ +ret_code_t app_atfifo_init(app_atfifo_t * const p_fifo, void * p_buf, uint16_t buf_size, uint16_t item_size); + +/** + * @brief Clear the FIFO + * + * Clearing the FIFO. + * + * If this function is called during some opened and uncommitted write operation, + * the FIFO would be cleared up to the currently ongoing commit. + * There is no possibility to cancel ongoing commit. + * + * If this function is called during some opened and unflushed read operation, + * the read position in head would be set, but copying it into write head position + * would be left to read closing operation. + * + * This way there would be no more data to read, but the memory would be released + * in the moment when it is safe. + * + * @param[in,out] p_fifo FIFO object. + * + * @retval NRF_SUCCESS FIFO totally cleared + * @retval NRF_ERROR_BUSY Function called in the middle of writing or reading operation. + * If we are in the middle of writing operation, + * FIFO was cleared up to the already started, and uncommitted write. + * If we are in the middle of write operation, + * write head was only moved. It would be copied into read tail when reading operation + * would be flushed. + */ +ret_code_t app_atfifo_clear(app_atfifo_t * const p_fifo); + +/** + * @brief Put data into FIFO + * + * Function to that puts data into the FIFO atomically. + * + * @param[in,out] p_fifo FIFO object. + * @param[in] p_var Variable to copy. + * @param[in] size Size of the variable to copy. + * Can be smaller or equal to the FIFO item size. + * @param[out] p_visible See value returned by @ref app_atfifo_wcommit. + * If may be NULL if the caller does not care about current operation status. + * + * @retval NRF_SUCCESS If an element has been successfully added to the FIFO. + * @retval NRF_ERROR_NO_MEM If the FIFO is full. + * + * @note + * To avoid data copying one may use @ref app_atfifo_wopen and @ref app_atfifo_wcommit + * functions pair. + */ +ret_code_t app_atfifo_put(app_atfifo_t * const p_fifo, void const * const p_var, size_t size, bool * const p_visible); + +/** + * @brief Open FIFO for writing, internal function + * + * Function called to start FIFO write operation and access the given FIFO buffer directly. + * + * @param[in,out] p_fifo FIFO object. + * @param[out] p_context The operation context, required by @ref app_atfifo_wcommit. + * + * @return Pointer to the space where variable data may be stored. + * NULL if there is no space in the buffer. + * + * @note + * Do not use this function directly. + * Use @ref app_atfifo_wopen instead. + */ +void * app_atfifo_wopen_internal(app_atfifo_t * const p_fifo, app_atfifo_wcontext_t * p_context); + +/** + * @brief Open FIFO for writing + * + * Function called to start FIFO write operation and access the given FIFO buffer directly. + * + * @param[in,out] p_fifo FIFO object. + * @param[out] p_context The operation context, required by @ref app_atfifo_wcommit. + * @param[in] size Requested size of the buffer. Currently used only for integrity checking when debugging. + * + * @return Pointer to the space where variable data may be stored. + * NULL if there is no space in the buffer. + * + * @note Always finish writing operation by @ref app_atfifo_wcommit + */ +static inline void * app_atfifo_wopen(app_atfifo_t * const p_fifo, app_atfifo_wcontext_t * p_context, size_t size) +{ + ASSERT(size <= p_fifo->item_size); + UNUSED_PARAMETER(size); + return app_atfifo_wopen_internal(p_fifo, p_context); +} + +/** + * @brief Close the writing operation + * + * Function need to be called to finally commit opened write operation. + * It sets all the buffers and finally mark the data to be visible to read. + * + * @param[in,out] p_fifo FIFO object. + * @param[in] p_context Operation context, filled by the @ref app_atfifo_wopen function. + * + * @retval true The data is actually ready and would be visible to read. + * @retval false The internal commit was marked, but the writing operation interrupted another writing operation. + * The data would be available to read when the interrupted operation would be committed. + */ +bool app_atfifo_wcommit(app_atfifo_t * const p_fifo, app_atfifo_wcontext_t * p_context); + +/** + * @brief Get single value from the FIFO + * + * Function gets the value from the top from the FIFO. + * The value is removed from the FIFO memory. + * + * @param[in,out] p_fifo FIFO object. + * @param[out] p_var Pointer to the variable to store data. + * @param[in] size Size of the data we are going to load. + * @param[out] p_released See the values returned by @ref app_atfifo_rflush. + * + * @retval NRF_SUCCESS Element was successfully copied from FIFO memory. + * @retval NRF_ERROR_NOT_FOUND No data in the FIFO. + */ +ret_code_t app_atfifo_get(app_atfifo_t * const p_fifo, void * const p_var, size_t size, bool * p_released); + +/** + * @brief Open FIFO for reading, internal function + * + * Function called to start FIFO read operation and access the given FIFO buffer directly. + * + * @param[in,out] p_fifo FIFO object. + * @param[out] p_context The operation context, required by @ref app_atfifo_rflush + * + * @return Pointer to data buffer or NULL if there is no data in the FIFO. + * + * @note + * Do not use this function directly. + * Use @ref app_atfifo_ropen instead. + */ +void const * app_atfifo_ropen_internal(app_atfifo_t * const p_fifo, app_atfifo_rcontext_t * p_context); + + +/** + * @brief Open FIFO for reading + * + * Function called to start FIFO read operation and access the FIFO buffer directly. + * + * @param[in,out] p_fifo FIFO object. + * @param[out] p_context The operation context, required by @ref app_atfifo_rflush + * @param[in] size Requested size of the buffer. Currently used only for integrity checking when debugging. + * + * @return Pointer to data buffer or NULL if there is no data in the FIFO. + */ +static inline void const * app_atfifo_ropen(app_atfifo_t * const p_fifo, app_atfifo_rcontext_t * p_context, size_t size) +{ + ASSERT(size <= p_fifo->item_size); + UNUSED_PARAMETER(size); + return app_atfifo_ropen_internal(p_fifo, p_context); +} + +/** + * @brief Close reading operation + * + * Function used to finish reading operation. + * If this reading operation did not interrupt another reading operation the head write buffer is moved. + * If this reading operation was placed in the middle of another reading, the new read pointer is only written. + * + * @param[in,out] p_fifo FIFO object. + * @param[in] p_context Context of the reading operation that we are going to close. + * + * @retval true This operation is not generated in the middle of another read operation and the write head would be updated to read head (space is released). + * @retval false This operation was performed in the middle of another read operation and the write buffer head was not moved (no space is released). + */ +bool app_atfifo_rflush(app_atfifo_t * const p_fifo, app_atfifo_rcontext_t * p_context); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_ATFIFO_H__ */ diff --git a/components/libraries/atomic_fifo/app_atfifo_internal.h b/components/libraries/atomic_fifo/app_atfifo_internal.h new file mode 100644 index 0000000..4f7439b --- /dev/null +++ b/components/libraries/atomic_fifo/app_atfifo_internal.h @@ -0,0 +1,576 @@ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * @brief Atomic FIFO internal file + * + * This file should be included only by app_atfifo internally. + * Needs app_atfifo.h included first. + */ +#ifndef APP_ATFIFO_H__ +#error This is internal file. Do not include this file in your program. +#endif + +#ifndef APP_ATFIFO_INTERNAL_H__ +#define APP_ATFIFO_INTERNAL_H__ +#include +#include "nrf.h" +#include "app_util.h" +#include "nordic_common.h" + +#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0 +#error Unsupported core version +#endif + +/* + * Make sure that rd and wr pos in a tag are aligned like expected + * Changing this would require changes inside assembly code! + */ +STATIC_ASSERT(offsetof(nrf_atfifo_postag_pos_t, wr) == 0); +STATIC_ASSERT(offsetof(nrf_atfifo_postag_pos_t, rd) == 2); + +/** + * @brief Atomically reserve space for new write + * + * @param[in,out] p_fifo FIFO object. + * @param[out] old_tail Tail position tag before new space was reserved + * + * @retval true Space available + * @retval false Memory full + * + * @sa app_atfifo_wspace_close + */ +static bool app_atfifo_wspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail); + +/** + * @brief Atomically mark all written data available + * + * This function marks all data available for reading. + * This marking is done by copying tail.pos.wr into tail.pos.rd. + * + * It has to be called only when closing the first write. + * It cannot be called if some write access was interrupted. + * See the code below: + * @code + * if(old_tail.pos.wr == old_tail.pos.rd) + * { + * app_atfifo_wspace_close(my_fifo); + * return true; + * } + * return false; + * @endcode + * + * @param[in,out] p_fifo FIFO object. + * + * @sa app_atfifo_wspace_req + */ +static void app_atfifo_wspace_close(app_atfifo_t * const p_fifo); + +/** + * @brief Atomically get part of the buffer to read data + * + * @param[in,out] p_fifo FIFO object. + * @param[out] old_head Head position tag before data buffer was read + * + * @retval true Data available for reading + * @retval false No data in the buffer + * + * @sa app_atfifo_rspace_close + */ +static bool app_atfifo_rspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head); + +/** + * @brief Atomically release all read data + * + * This function marks all data that was actually read as free space, + * available for writing. + * This marking is done by copying head.pos.rd into head.pos.wr. + * + * It has to be called only when closing the first read. + * It cannot be called when current read access interrupted some other read access. + * See code below: + * @code + * if(old_head.pos.wr == old_head.pos.rd) + * { + * app_atfifo_rspace_close(my_fifo); + * return true; + * } + * return false; + * @endcode + * + * @param[in,out] p_fifo FIFO object. + * + * @sa app_atfifo_rspace_req + */ +static void app_atfifo_rspace_close(app_atfifo_t * const p_fifo); + +/** + * @brief Safely clear the FIFO, internal function + * + * This function realizes the functionality required by @ref app_atfifo_clear. + * + * @param[in,out] p_fifo FIFO object. + * + * @retval true All the data was released + * @retval false All the data available for releasing was released, but there is some pending transfer. + */ +static bool app_atfifo_space_clear(app_atfifo_t * const p_fifo); + + +/* --------------------------------------------------------------------------- + * Implementation starts here + */ + +#if defined ( __CC_ARM ) + + +__ASM bool app_atfifo_wspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail) +{ + /* Registry usage: + * R0 - p_fifo + * R1 - p_old_tail + * R2 - internal variable old_tail (saved by caller) + * R3 - internal variable new_tail (saved by caller) + * R4 - internal temporary register (saved by this function) + * R5 - not used stored to keep the stack aligned to 8 bytes + * Returned value: + * R0 (bool - 32 bits) + */ + push {r4, r5} +app_atfifo_wspace_req_repeat + /* Load tail tag and set memory monitor !!! R2 - old tail !!! */ + ldrex r2, [r0, #__cpp(offsetof(app_atfifo_t, tail))] + /* Extract write position !!! R3 !!! */ + uxth r3, r2 + /* Increment address with overload support !!! R4 used temporary !!! */ + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, item_size))] + add r3, r4 + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, buf_size))] + cmp r3, r4 + it hs + subhs r3, r3, r4 + + /* Check if FIFO would overload after making this increment !!! R4 used temporary !!! */ + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr))] + cmp r3, r4 + ittt eq + clrexeq + moveq r0, #__cpp(false) + beq app_atfifo_wspace_req_exit + + /* Pack everything back !!! R3 - new tail !!! */ + /* Copy lower byte from new_tail, and higher byte is a value from the top of old_tail */ + pkhbt r3, r3, r2 + + /* Store new value clearing memory monitor !!! R4 used temporary !!! */ + strex r4, r3, [r0, #__cpp(offsetof(app_atfifo_t, tail))] + cmp r4, #0 + bne app_atfifo_wspace_req_repeat + + /* Return true */ + mov r0, #__cpp(true) +app_atfifo_wspace_req_exit + /* Save old tail */ + str r2, [r1] + pop {r4, r5} + bx lr +} + + +__ASM void app_atfifo_wspace_close(app_atfifo_t * const p_fifo) +{ + /* Registry usage: + * R0 - p_fifo + * R1 - internal temporary register + * R2 - new_tail + */ +app_atfifo_wspace_close_repeat + ldrex r2, [r0, #__cpp(offsetof(app_atfifo_t, tail))] + /* Copy from lower byte to higher */ + pkhbt r2, r2, r2, lsl #16 + + strex r1, r2, [r0, #__cpp(offsetof(app_atfifo_t, tail))] + cmp r1, #0 + bne app_atfifo_wspace_close_repeat + bx lr +} + + +__ASM bool app_atfifo_rspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head) +{ + /* Registry usage: + * R0 - p_fifo + * R1 - p_old_head + * R2 - internal variable old_head (saved by caller) + * R3 - internal variable new_head (saved by caller) + * R4 - internal temporary register (saved by this function) + * R5 - not used stored to keep the stack aligned to 8 bytes + * Returned value: + * R0 (bool - 32 bits) + */ + push {r4, r5} +app_atfifo_rspace_req_repeat + /* Load tail tag and set memory monitor !!! R2 - old tail !!! */ + ldrex r2, [r0, #__cpp(offsetof(app_atfifo_t, head))] + /* Extract read position !!! R3 !!! */ + uxth r3, r2, ror #16 + + /* Check if we have any data !!! R4 used temporary !!! */ + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd))] + cmp r3, r4 + ittt eq + clrexeq + moveq r0, #__cpp(false) + beq app_atfifo_rspace_req_exit + + /* Increment address with overload support !!! R4 used temporary !!! */ + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, item_size))] + add r3, r4 + ldrh r4, [r0, #__cpp(offsetof(app_atfifo_t, buf_size))] + cmp r3, r4 + it hs + subhs r3, r3, r4 + + /* Pack everything back !!! R3 - new tail !!! */ + /* Copy lower byte from old_head, and higher byte is a value from write_pos */ + pkhbt r3, r2, r3, lsl #16 + + /* Store new value clearing memory monitor !!! R4 used temporary !!! */ + strex r4, r3, [r0, #__cpp(offsetof(app_atfifo_t, head))] + cmp r4, #0 + bne app_atfifo_rspace_req_repeat + + /* Return true */ + mov r0, #__cpp(true) +app_atfifo_rspace_req_exit + /* Save old head */ + str r2, [r1] + pop {r4, r5} + bx lr +} + + +__ASM void app_atfifo_rspace_close(app_atfifo_t * const p_fifo) +{ + /* Registry usage: + * R0 - p_fifo + * R1 - internal temporary register + * R2 - new_tail + */ +app_atfifo_rspace_close_repeat + ldrex r2, [r0, #__cpp(offsetof(app_atfifo_t, head))] + /* Copy from higher byte to lower */ + pkhtb r2, r2, r2, asr #16 + + strex r1, r2, [r0, #__cpp(offsetof(app_atfifo_t, head))] + cmp r1, #0 + bne app_atfifo_rspace_close_repeat + bx lr +} + + +__ASM bool app_atfifo_space_clear(app_atfifo_t * const p_fifo) +{ + /* Registry usage: + * R0 - p_fifo as input, bool output after + * R1 - tail, rd pointer, new_head + * R2 - head_old, destroyed when creating new_head + * R3 - p_fifo - copy + */ + mov r3, r0 +app_atfifo_space_clear_repeat + /* Load old head in !!! R2 register !!! and read pointer of tail in !!! R1 register !!! */ + ldrex r2, [r3, #__cpp(offsetof(app_atfifo_t, head))] + ldrh r1, [r3, #__cpp(offsetof(app_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd))] + cmp r2, r2, ror #16 + /* Return false as default */ + mov r0, #__cpp(false) + /* Create new head in !!! R1 register !!! Data in !!! R2 register broken !!! */ + itett ne + uxthne r2, r2 + orreq r1, r1, r1, lsl #16 + orrne r1, r2, r1, lsl #16 + + /* Skip header test */ + bne app_atfifo_space_clear_head_test_skip + + /* Load whole tail and test it !!! R2 used !!! */ + ldr r2, [r3, #__cpp(offsetof(app_atfifo_t, tail))] + cmp r2, r2, ror #16 + /* Return true if equal */ + it eq + moveq r0, #__cpp(true) + +app_atfifo_space_clear_head_test_skip + /* Store and test if success !!! R2 used temporary !!! */ + strex r2, r1, [r3, #__cpp(offsetof(app_atfifo_t, head))] + cmp r2, #0 + bne app_atfifo_space_clear_repeat + bx lr +} + +#elif defined ( __ICCARM__ ) || defined ( __GNUC__ ) + +bool app_atfifo_wspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail) +{ + volatile bool ret; + volatile uint32_t old_tail; + uint32_t new_tail; + uint32_t temp; + + __ASM volatile( + /* For more comments see Keil version above */ + "1: \n" + " ldrex %[old_tail], [%[p_fifo], %[offset_tail]] \n" + " uxth %[new_tail], %[old_tail] \n" + " \n" + " ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n" + " add %[new_tail], %[temp] \n" + " ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n" + " cmp %[new_tail], %[temp] \n" + " it hs \n" + " subhs %[new_tail], %[new_tail], %[temp] \n" + " \n" + " ldrh %[temp], [%[p_fifo], %[offset_head_wr]] \n" + " cmp %[new_tail], %[temp] \n" + " ittt eq \n" + " clrexeq \n" + " moveq %[ret], %[false_val] \n" + " beq.n 2f \n" + " \n" + " pkhbt %[new_tail], %[new_tail], %[old_tail] \n" + " \n" + " strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n" + " cmp %[temp], #0 \n" + " bne.n 1b \n" + " \n" + " mov %[ret], %[true_val] \n" + "2: \n" + : /* Output operands */ + [ret] "=r"(ret), + [temp] "=&r"(temp), + [old_tail]"=&r"(old_tail), + [new_tail]"=&r"(new_tail) + : /* Input operands */ + [p_fifo] "r"(p_fifo), + [offset_tail] "J"(offsetof(app_atfifo_t, tail)), + [offset_head_wr] "J"(offsetof(app_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr)), + [offset_item_size]"J"(offsetof(app_atfifo_t, item_size)), + [offset_buf_size] "J"(offsetof(app_atfifo_t, buf_size)), + [true_val] "I"(true), + [false_val] "I"(false) + : /* Clobbers */ + "cc"); + + p_old_tail->tag = old_tail; + UNUSED_VARIABLE(new_tail); + UNUSED_VARIABLE(temp); + return ret; +} + + +void app_atfifo_wspace_close(app_atfifo_t * const p_fifo) +{ + uint32_t temp; + uint32_t new_tail; + + __ASM volatile( + /* For more comments see Keil version above */ + "1: \n" + " ldrex %[new_tail], [%[p_fifo], %[offset_tail]] \n" + " pkhbt %[new_tail],%[new_tail], %[new_tail], lsl #16 \n" + " \n" + " strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n" + " cmp %[temp], #0 \n" + " bne.n 1b \n" + : /* Output operands */ + [temp] "=&r"(temp), + [new_tail] "=&r"(new_tail) + : /* Input operands */ + [p_fifo] "r"(p_fifo), + [offset_tail] "J"(offsetof(app_atfifo_t, tail)) + : /* Clobbers */ + "cc"); + + UNUSED_VARIABLE(temp); + UNUSED_VARIABLE(new_tail); +} + + +bool app_atfifo_rspace_req(app_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head) +{ + volatile bool ret; + volatile uint32_t old_head; + uint32_t new_head; + uint32_t temp; + + __ASM volatile( + /* For more comments see Keil version above */ + "1: \n" + " ldrex %[old_head], [%[p_fifo], %[offset_head]] \n" + " uxth %[new_head], %[old_head], ror #16 \n" + " \n" + " ldrh %[temp], [%[p_fifo], %[offset_tail_rd]] \n" + " cmp %[new_head], %[temp] \n" + " ittt eq \n" + " clrexeq \n" + " moveq %[ret], %[false_val] \n" + " beq.n 2f \n" + " \n" + " ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n" + " add %[new_head], %[temp] \n" + " ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n" + " cmp %[new_head], %[temp] \n" + " it hs \n" + " subhs %[new_head], %[new_head], %[temp] \n" + " \n" + " pkhbt %[new_head], %[old_head], %[new_head], lsl #16 \n" + " \n" + " strex %[temp], %[new_head], [%[p_fifo], %[offset_head]] \n" + " cmp %[temp], #0 \n" + " bne.n 1b \n" + " \n" + " mov %[ret], %[true_val] \n" + "2: \n" + : /* Output operands */ + [ret] "=r"(ret), + [temp] "=&r"(temp), + [old_head]"=&r"(old_head), + [new_head]"=&r"(new_head) + : /* Input operands */ + [p_fifo] "r"(p_fifo), + [offset_head] "J"(offsetof(app_atfifo_t, head)), + [offset_tail_rd] "J"(offsetof(app_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd)), + [offset_item_size]"J"(offsetof(app_atfifo_t, item_size)), + [offset_buf_size] "J"(offsetof(app_atfifo_t, buf_size)), + [true_val] "I"(true), + [false_val] "I"(false) + : /* Clobbers */ + "cc"); + + p_old_head->tag = old_head; + UNUSED_VARIABLE(new_head); + UNUSED_VARIABLE(temp); + return ret; +} + + +void app_atfifo_rspace_close(app_atfifo_t * const p_fifo) +{ + uint32_t temp; + uint32_t new_head; + + __ASM volatile( + /* For more comments see Keil version above */ + "1: \n" + " ldrex %[new_head], [%[p_fifo], %[offset_head]] \n" + " pkhtb %[new_head],%[new_head], %[new_head], asr #16 \n" + " \n" + " strex %[temp], %[new_head], [%[p_fifo], %[offset_head]] \n" + " cmp %[temp], #0 \n" + " bne.n 1b \n" + : /* Output operands */ + [temp] "=&r"(temp), + [new_head] "=&r"(new_head) + : /* Input operands */ + [p_fifo] "r"(p_fifo), + [offset_head] "J"(offsetof(app_atfifo_t, head)) + : /* Clobbers */ + "cc"); + + UNUSED_VARIABLE(temp); + UNUSED_VARIABLE(new_head); +} + + +bool app_atfifo_space_clear(app_atfifo_t * const p_fifo) +{ + volatile bool ret; + uint32_t old_head; /* This variable is left broken after assembly code finishes */ + uint32_t new_head; + + __ASM volatile( + "1: \n" + " ldrex %[old_head], [%[p_fifo], %[offset_head]] \n" + " ldrh %[new_head], [%[p_fifo], %[offset_tail_rd]] \n" + " cmp %[old_head], %[old_head], ror #16 \n" + " \n" + " mov %[ret], %[false_val] \n" + " \n" + " itett ne \n" + " uxthne %[old_head], %[old_head] \n" + " orreq %[new_head], %[new_head], %[new_head], lsl #16 \n" + " orrne %[new_head], %[old_head], %[new_head], lsl #16 \n" + " \n" + " bne.n 2f \n" + " \n" + " ldr %[old_head], [%[p_fifo], %[offset_tail]] \n" + " cmp %[old_head], %[old_head], ror #16 \n" + " it eq \n" + " moveq %[ret], %[true_val] \n" + " \n" + "2: \n" + " strex %[old_head], %[new_head], [%[p_fifo], %[offset_head]] \n" + " cmp %[old_head], #0 \n" + " bne.n 1b \n" + : /* Output operands */ + [ret] "=&r"(ret), + [old_head] "=&r"(old_head), + [new_head] "=&r"(new_head) + : /* Input operands */ + [p_fifo] "r"(p_fifo), + [offset_head] "J"(offsetof(app_atfifo_t, head)), + [offset_tail] "J"(offsetof(app_atfifo_t, tail)), + [offset_tail_rd] "J"(offsetof(app_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd)), + [true_val] "I"(true), + [false_val] "I"(false) + : /* Clobbers */ + "cc"); + + UNUSED_VARIABLE(old_head); + UNUSED_VARIABLE(new_head); + return ret; +} + +#else +#error Unsupported compiler +#endif + +#endif /* APP_ATFIFO_INTERNAL_H__ */ diff --git a/components/libraries/balloc/nrf_balloc.c b/components/libraries/balloc/nrf_balloc.c new file mode 100644 index 0000000..b25b51b --- /dev/null +++ b/components/libraries/balloc/nrf_balloc.c @@ -0,0 +1,323 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + + #include "sdk_common.h" + #if NRF_MODULE_ENABLED(NRF_BALLOC) + +#include "nrf_balloc.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "NRF_BALLOC" +#if NRF_BALLOC_CONFIG_LOG_ENABLED + #define NRF_LOG_LEVEL NRF_BALLOC_CONFIG_LOG_LEVEL + #define NRF_LOG_INFO_COLOR NRF_BALLOC_CONFIG_INFO_COLOR + #define NRF_LOG_DEBUG_COLOR NRF_BALLOC_CONFIG_DEBUG_COLOR +#else + #define NRF_LOG_LEVEL 0 +#endif // NRF_BALLOC_CONFIG_LOG_ENABLED +#include "nrf_log.h" + +#define HEAD_GUARD_FILL 0xBAADF00D /**< Magic number used to mark head guard.*/ +#define TAIL_GUARD_FILL 0xBAADCAFE /**< Magic number used to mark tail guard.*/ +#define FREE_MEM_FILL 0xBAADBAAD /**< Magic number used to mark free memory.*/ + +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED +/**@brief Validate block memory, prepare block guards, and calculate pointer to the element. + * + * @param[in] p_pool Pointer to the memory pool. + * @param[in] p_head Pointer to the beginning of the block. + * + * @return Pointer to the element. + */ +__STATIC_INLINE void * nrf_balloc_block_unwrap(nrf_balloc_t const * p_pool, void * p_head) +{ + ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0)); + ASSERT((p_head != NULL) && (((uint32_t)(p_head) % sizeof(uint32_t)) == 0)); + + uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags); + uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags); + + uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size); + uint32_t * p_element = (uint32_t *)p_head + head_words; + + if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags)) + { + for (uint32_t * ptr = p_head; ptr < p_tail; ptr++) + { + if (*ptr != FREE_MEM_FILL) + { + NRF_LOG_ERROR("Detected free memory corruption at %p (%p != %p, pool: %p)\r\n", + (uint32_t)ptr, *ptr, FREE_MEM_FILL, (uint32_t)p_pool); + APP_ERROR_CHECK_BOOL(false); + } + } + } + + for (uint32_t * ptr = p_head; ptr < p_element; ptr++) + { + *ptr = HEAD_GUARD_FILL; + } + + for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++) + { + *ptr = TAIL_GUARD_FILL; + } + + return p_element; +} + +/**@brief Calculate pointer to the block, validate block guards, and mark block memory as free. + * + * @param[in] p_pool Pointer to the memory pool. + * @param[in] p_element Pointer to the element. + * + * @return Pointer to the beginning of the block. + */ +__STATIC_INLINE void * nrf_balloc_element_wrap(nrf_balloc_t const * p_pool, void * p_element) +{ + ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0)); + ASSERT((p_element != NULL) && (((uint32_t)(p_element) % sizeof(uint32_t)) == 0)); + + uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags); + uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags); + + uint32_t * p_head = (uint32_t *)p_element - head_words; + uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size); + + for (uint32_t * ptr = p_head; ptr < (uint32_t *)p_element; ptr++) + { + if (*ptr != HEAD_GUARD_FILL) + { + NRF_LOG_ERROR("Detected Head Guard corruption at %p (%p != %p, pool: %p)\r\n", + (uint32_t)ptr, *ptr, HEAD_GUARD_FILL, (uint32_t)p_pool); + APP_ERROR_CHECK_BOOL(false); + } + } + + for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++) + { + if (*ptr != TAIL_GUARD_FILL) + { + NRF_LOG_ERROR("Detected Tail Guard corruption at %p (%p != %p, pool: %p)\r\n", + (uint32_t)ptr, *ptr, TAIL_GUARD_FILL, (uint32_t)p_pool); + APP_ERROR_CHECK_BOOL(false); + } + } + + if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags)) + { + for (uint32_t * ptr = p_head; ptr < p_tail; ptr++) + { + *ptr = FREE_MEM_FILL; + } + } + + return p_head; +} + +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + +/**@brief Convert block index to a pointer. + * + * @param[in] p_pool Pointer to the memory pool. + * @param[in] idx Index of the block. + * + * @return Pointer to the beginning of the block. + */ +static void * nrf_balloc_idx2block(nrf_balloc_t const * p_pool, uint8_t idx) +{ + ASSERT(p_pool != NULL); + return (uint8_t *)(p_pool->p_memory_begin) + ((size_t)(idx) * p_pool->block_size); +} + +/**@brief Convert block pointer to index. + * + * @param[in] p_pool Pointer to the memory pool. + * @param[in] p_block Pointer to the beginning of the block. + * + * @return Index of the block. + */ +static uint8_t nrf_balloc_block2idx(nrf_balloc_t const * p_pool, void const * p_block) +{ + ASSERT(p_pool != NULL); + return ((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) / p_pool->block_size; +} + +ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool) +{ + VERIFY_PARAM_NOT_NULL(p_pool); + + ASSERT(p_pool->p_cb); + ASSERT(p_pool->p_stack_base); + ASSERT(p_pool->p_stack_limit); + ASSERT(p_pool->p_memory_begin); + ASSERT(p_pool->block_size); + + NRF_LOG_INFO("Init\r\n"); + +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + ASSERT(p_pool->p_memory_end); + + if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags)) + { + for (uint32_t * ptr = p_pool->p_memory_begin; ptr < (uint32_t *)(p_pool->p_memory_end); ptr++) + { + *ptr = FREE_MEM_FILL; + } + } +#endif + + p_pool->p_cb->p_stack_pointer = p_pool->p_stack_base; + uint8_t pool_size = p_pool->p_stack_limit - p_pool->p_stack_base; + while (pool_size--) + { + *(p_pool->p_cb->p_stack_pointer)++ = pool_size; + } + + p_pool->p_cb->max_utilization = 0; + + return NRF_SUCCESS; +} + +void * nrf_balloc_alloc(nrf_balloc_t const * p_pool) +{ + ASSERT(p_pool != NULL); + + void * p_block = NULL; + + CRITICAL_REGION_ENTER(); + + if (p_pool->p_cb->p_stack_pointer > p_pool->p_stack_base) + { + // Allocate block. + p_block = nrf_balloc_idx2block(p_pool, *--(p_pool->p_cb->p_stack_pointer)); + + // Update utilization statistics. + uint8_t utilization = p_pool->p_stack_limit - p_pool->p_cb->p_stack_pointer; + if (p_pool->p_cb->max_utilization < utilization) + { + p_pool->p_cb->max_utilization = utilization; + } + } + + CRITICAL_REGION_EXIT(); + +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + if (p_block != NULL) + { + p_block = nrf_balloc_block_unwrap(p_pool, p_block); + } +#endif + + NRF_LOG_DEBUG("nrf_balloc_alloc(p_pool: %p, p_element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_block); + return p_block; +} + +void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element) +{ + ASSERT(p_pool != NULL); + ASSERT(p_element != NULL) + NRF_LOG_DEBUG("nrf_balloc_free(p_pool: %p, p_element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_element); + +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + void * p_block = nrf_balloc_element_wrap(p_pool, p_element); + + // These checks could be done outside critical region as they use only pool configuration data. + if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags)) + { + // Check if the element belongs to this pool. + if ((p_block < p_pool->p_memory_begin) || (p_block >= p_pool->p_memory_end)) + { + NRF_LOG_ERROR("Attempted to free element that does belong to the pool (pool: %p, element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_element); + APP_ERROR_CHECK_BOOL(false); + } + + // Check if the pointer is valid. + if ((((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) % p_pool->block_size) != 0) + { + NRF_LOG_ERROR("Atempted to free corrupted element address (pool: %p, element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_element); + APP_ERROR_CHECK_BOOL(false); + } + } +#else + void * p_block = p_element; +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + + CRITICAL_REGION_ENTER(); + +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + // These checks have to be done in critical region as they use p_pool->p_stack_pointer. + if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags)) + { + // Check for allocated/free ballance. + if (p_pool->p_cb->p_stack_pointer >= p_pool->p_stack_limit) + { + NRF_LOG_ERROR("Attempted to free an element while the pool is full (pool: %p, element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_element); + APP_ERROR_CHECK_BOOL(false); + } + } + + if (NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(p_pool->debug_flags)) + { + // Check for double free. + for (uint8_t * p_idx = p_pool->p_stack_base; p_idx < p_pool->p_cb->p_stack_pointer; p_idx++) + { + if (nrf_balloc_idx2block(p_pool, *p_idx) == p_block) + { + NRF_LOG_ERROR("Attempted to double-free an element (pool: %p, element: %p)\r\n", + (uint32_t)p_pool, (uint32_t)p_element); + APP_ERROR_CHECK_BOOL(false); + } + } + } +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + + // Free the element. + *(p_pool->p_cb->p_stack_pointer)++ = nrf_balloc_block2idx(p_pool, p_block); + + CRITICAL_REGION_EXIT(); +} + +#endif // NRF_MODULE_ENABLED(NRF_BALLOC) diff --git a/components/libraries/balloc/nrf_balloc.h b/components/libraries/balloc/nrf_balloc.h new file mode 100644 index 0000000..fbfcbbb --- /dev/null +++ b/components/libraries/balloc/nrf_balloc.h @@ -0,0 +1,298 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + + /** + * @defgroup nrf_balloc Block memory allocator + * @{ + * @ingroup app_common + * @brief This module handles block memory allocator features. + */ + + +#ifndef NRF_BALLOC_H__ +#define NRF_BALLOC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdk_errors.h" +#include "sdk_config.h" +#include "app_util_platform.h" + +/**@defgroup NRF_BALLOC_DEBUG Macros for preparing debug flags for block allocator module. + * @{ */ +#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(words) (((words) & 0xFF) << 0) +#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(flags) (((flags) >> 0) & 0xFF) +#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(words) (((words) & 0xFF) << 8) +#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(flags) (((flags) >> 8) & 0xFF) + +#define NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(enable) (!!(enable) << 16) +#define NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(flags) (flags & (1 << 16)) +#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(enable) (!!(enable) << 17) +#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(flags) (flags & (1 << 17)) +#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(enable) (!!(enable) << 18) +#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(flags) (flags & (1 << 18)) +/**@} */ + +/**@brief Default debug flags for @ref nrf_balloc. This is used by the @ref NRF_BALLOC_DEF macro. + * Flags can be changed in @ref sdk_config. + */ +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + #define NRF_BALLOC_DEFAULT_DEBUG_FLAGS \ + ( \ + NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS) | \ + NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_TAIL_WORDS) | \ + NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED) | \ + NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED) | \ + NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED) \ + ) +#else + #define NRF_BALLOC_DEFAULT_DEBUG_FLAGS 0 +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + +/**@brief Block memory allocator control block.*/ +typedef struct +{ + uint8_t * p_stack_pointer; //!< Current allocation stack pointer. + uint8_t max_utilization; //!< Maximum utilization of the memory pool. +} nrf_balloc_cb_t; + +/**@brief Block memory allocator pool instance. The pool is made of elements of the same size. */ +typedef struct +{ + nrf_balloc_cb_t * p_cb; //!< Pointer to the instance control block. + uint8_t * p_stack_base; //!< Base of the allocation stack. + /**< + * Stack is used to store handlers to not allocated elements. + */ + uint8_t * p_stack_limit; //!< Maximum possible value of the allocation stack pointer. + void * p_memory_begin; //!< Pointer to the start of the memory pool. + /**< + * Memory is used as a heap for blocks. + */ +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + void * p_memory_end; //!< Pointer to the end of the memory pool. + uint32_t debug_flags; //!< Debugging settings. + /**< + * Debug flag should be created by @ref NRF_BALLOC_DEBUG. + */ +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + uint16_t block_size; //!< Size of the allocated block (including debug overhead). + /**< + * Single block contains user element with header and tail + * words. + */ +} nrf_balloc_t; + +/**@brief Get total memory consumed by single block (element size with overhead caused by debug + * flags). + * + * @param[in] _element_size Size of an element. + * @param[in] _debug_flags Debug flags. + */ +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + #define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \ + ( \ + (sizeof(uint32_t) * NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(_debug_flags)) + \ + ALIGN_NUM(sizeof(uint32_t), (_element_size)) + \ + (sizeof(uint32_t) * NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(_debug_flags)) \ + ) +#else + #define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \ + ALIGN_NUM(sizeof(uint32_t), (_element_size)) +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + +/**@brief Create a block allocator instance with custom debug flags. + * + * @note This macro reserves memory for the given block allocator instance. + * + * @param[in] _name Name of the allocator. + * @param[in] _element_size Size of one element. + * @param[in] _pool_size Size of the pool. + * @param[in] _debug_flags Debug flags (@ref NRF_BALLOC_DEBUG). + */ +#if NRF_BALLOC_CONFIG_DEBUG_ENABLED + #define NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, _debug_flags) \ + STATIC_ASSERT((_pool_size) <= UINT8_MAX); \ + static uint8_t _name##_nrf_balloc_pool_stack[(_pool_size)]; \ + static uint32_t _name##_nrf_balloc_pool_mem \ + [NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) * (_pool_size) / sizeof(uint32_t)]; \ + static nrf_balloc_cb_t _name##_nrf_balloc_cb; \ + static const nrf_balloc_t _name = \ + { \ + .p_cb = &_name##_nrf_balloc_cb, \ + .p_stack_base = _name##_nrf_balloc_pool_stack, \ + .p_stack_limit = _name##_nrf_balloc_pool_stack + (_pool_size), \ + .p_memory_begin = _name##_nrf_balloc_pool_mem, \ + .block_size = NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags), \ + .p_memory_end = (uint8_t *)_name##_nrf_balloc_pool_mem \ + + NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) * (_pool_size),\ + .debug_flags = (_debug_flags), \ + } +#else + #define NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, _debug_flags) \ + STATIC_ASSERT((_pool_size) <= UINT8_MAX); \ + static uint8_t _name##_nrf_balloc_pool_stack[(_pool_size)]; \ + static uint32_t _name##_nrf_balloc_pool_mem \ + [NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) * (_pool_size) / sizeof(uint32_t)]; \ + static nrf_balloc_cb_t _name##_nrf_balloc_cb; \ + static const nrf_balloc_t _name = \ + { \ + .p_cb = &_name##_nrf_balloc_cb, \ + .p_stack_base = _name##_nrf_balloc_pool_stack, \ + .p_stack_limit = _name##_nrf_balloc_pool_stack + (_pool_size), \ + .p_memory_begin = _name##_nrf_balloc_pool_mem, \ + .block_size = NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags), \ + } +#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED + +/**@brief Create a block allocator instance. + * + * @note This macro reserves memory for the given block allocator instance. + * + * @param[in] _name Name of the allocator. + * @param[in] _element_size Size of one element. + * @param[in] _pool_size Size of the pool. + */ +#define NRF_BALLOC_DEF(_name, _element_size, _pool_size) \ + NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, NRF_BALLOC_DEFAULT_DEBUG_FLAGS) + +/**@brief Create a block allocator interface. + * + * @param[in] _type Type which is allocated. + * @param[in] _name Name of the allocator. + */ +#define NRF_BALLOC_INTERFACE_DEC(_type, _name) \ + _type * _name##_alloc(void); \ + void _name##_free(_type * p_element); \ + uint8_t _name##_max_utilization_get(void) + +/**@brief Define a custom block allocator interface. + * + * @param[in] _attr Function attribute that will be added to allocator function definition. + * @param[in] _type Type which is allocated. + * @param[in] _name Name of the allocator. + * @param[in] _p_pool Pool from which data will be allocated. + */ +#define NRF_BALLOC_INTERFACE_CUSTOM_DEF(_attr, _type, _name, _p_pool) \ + _attr _type * _name##_alloc(void) \ + { \ + ASSERT((_p_pool) != NULL); \ + ASSERT((_p_pool)->block_size >= \ + NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \ + return (_type *)(nrf_balloc_alloc(_p_pool)); \ + } \ + \ + _attr void _name##_free(_type * p_element) \ + { \ + ASSERT((_p_pool) != NULL); \ + ASSERT((_p_pool)->block_size >= \ + NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \ + nrf_balloc_free((_p_pool), p_element); \ + } \ + \ + _attr uint8_t _name##_max_utilization_get(void) \ + { \ + ASSERT((_p_pool) != NULL); \ + return nrf_balloc_max_utilization_get((_p_pool)); \ + } + +/**@brief Define block allocator interface. + * + * @param[in] _type Type which is allocated. + * @param[in] _name Name of the allocator. + * @param[in] _p_pool Pool from which data will be allocated. + */ +#define NRF_BALLOC_INTERFACE_DEF(_type, _name, _p_pool) \ + NRF_BALLOC_INTERFACE_CUSTOM_DEF(/* empty */, _type, _name, _p_pool) + +/**@brief Define a local block allocator interface. + * + * @param[in] _type Type which is allocated. + * @param[in] _name Name of the allocator. + * @param[in] _p_pool Pool from which data will be allocated. + */ +#define NRF_BALLOC_INTERFACE_LOCAL_DEF(_type, _name, _p_pool) \ + NRF_BALLOC_INTERFACE_CUSTOM_DEF(static, _type, _name, _p_pool) + +/**@brief Function for initializing a block memory allocator pool. + * + * @param[out] p_pool Pointer to the pool that is to be initialized. + * + * @return NRF_SUCCESS on success, otherwise error code. + */ +ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool); + +/**@brief Function for allocating an element from the pool. + * + * @note This module guarantees that the returned memory is aligned to 4. + * + * @param[in] p_pool Pointer to the memory pool from which the element will be allocated. + * + * @return Allocated element or NULL if the specified pool is empty. + */ +void * nrf_balloc_alloc(nrf_balloc_t const * p_pool); + +/**@brief Function for freeing an element back to the pool. + * + * @param[in] p_pool Pointer to the memory pool. + * @param[in] p_element Element to be freed. + */ +void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element); + +/**@brief Function for getting maximum memory pool utilization. + * + * @param[in] p_pool Pointer to the memory pool instance. + * + * @return Maximum number of elements allocated from the pool. + */ +__STATIC_INLINE uint8_t nrf_balloc_max_utilization_get(nrf_balloc_t const * p_pool) +{ + ASSERT(p_pool != NULL); + return p_pool->p_cb->max_utilization; +} + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BALLOC_H__ +/** @} */ diff --git a/components/libraries/block_dev/empty/nrf_block_dev_empty.c b/components/libraries/block_dev/empty/nrf_block_dev_empty.c new file mode 100644 index 0000000..3ee50f5 --- /dev/null +++ b/components/libraries/block_dev/empty/nrf_block_dev_empty.c @@ -0,0 +1,211 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_block_dev_empty.h" + +/**@file + * + * @ingroup nrf_block_dev + * @{ + * + * @brief This module implements block device API. It would behave like: + * - /dev/empty for write operations + * - /dev/zero for read operations + */ + +static ret_code_t block_dev_empty_init(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context) +{ + ASSERT(p_blk_dev); + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work; + + /* Calculate block device geometry.... */ + p_work->geometry.blk_size = p_empty_dev->empty_config.block_size; + p_work->geometry.blk_count = p_empty_dev->empty_config.block_count; + p_work->p_context = p_context; + p_work->ev_handler = ev_handler; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_INIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_empty_uninit(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_UNINIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + memset(p_work, 0, sizeof(nrf_block_dev_empty_work_t)); + return NRF_SUCCESS; +} + +static ret_code_t block_dev_empty_read_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work; + + memset(p_blk->p_buff, 0, p_empty_dev->p_work->geometry.blk_size * p_blk->blk_count); + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, + NRF_BLOCK_DEV_RESULT_SUCCESS, + p_blk, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_empty_write_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, + NRF_BLOCK_DEV_RESULT_SUCCESS, + p_blk, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_empty_ioctl(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, void * p_data) +{ + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + switch (req) + { + case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH: + { + bool * p_flushing = p_data; + if (p_flushing) + { + *p_flushing = false; + } + return NRF_SUCCESS; + } + case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS: + { + if (p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_block_dev_info_strings_t const * * pp_strings = p_data; + *pp_strings = &p_empty_dev->info_strings; + return NRF_SUCCESS; + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +static nrf_block_dev_geometry_t const * block_dev_empty_geometry(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_empty_t const * p_empty_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev); + nrf_block_dev_empty_work_t const * p_work = p_empty_dev->p_work; + + return &p_work->geometry; +} + +const nrf_block_dev_ops_t nrf_block_device_empty_ops = { + .init = block_dev_empty_init, + .uninit = block_dev_empty_uninit, + .read_req = block_dev_empty_read_req, + .write_req = block_dev_empty_write_req, + .ioctl = block_dev_empty_ioctl, + .geometry = block_dev_empty_geometry, +}; + diff --git a/components/libraries/block_dev/empty/nrf_block_dev_empty.h b/components/libraries/block_dev/empty/nrf_block_dev_empty.h new file mode 100644 index 0000000..b7667f4 --- /dev/null +++ b/components/libraries/block_dev/empty/nrf_block_dev_empty.h @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_BLOCK_DEV_EMPTY_H__ +#define NRF_BLOCK_DEV_EMPTY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_block_dev.h" + + +/**@file + * + * @defgroup nrf_block_dev_empty Empty implementation + * @ingroup nrf_block_dev + * + * This module implements block device API. It works like: + * - /dev/empty for write operations + * - /dev/zero for read operations + * @{ + * + */ + +/** + * @brief EMPTY block device operations + * */ +extern const nrf_block_dev_ops_t nrf_block_device_empty_ops; + +/** + * @brief Work structure of EMPTY block device. + */ +typedef struct { + nrf_block_dev_geometry_t geometry; //!< Block device geometry + nrf_block_dev_ev_handler ev_handler; //!< Block device event handler + void const * p_context; //!< Context handle passed to event handler +} nrf_block_dev_empty_work_t; + + +/** + * @brief EMPTY block device config initializer (@ref nrf_block_dev_empty_config_t) + * + * @param blk_size Block size + * @param blk_count Block count + * */ +#define NRF_BLOCK_DEV_EMPTY_CONFIG(blk_size, blk_count) { \ + .block_size = (blk_size), \ + .block_count = (blk_count) \ +} + +/** + * @brief EMPTY block device config + */ +typedef struct { + uint32_t block_size; //!< Desired block size + uint32_t block_count; //!< Desired block count +} nrf_block_dev_empty_config_t; + +/** + * @brief EMPTY block device + * */ +typedef struct { + nrf_block_dev_t block_dev; //!< Block device + nrf_block_dev_info_strings_t info_strings; //!< Block device information strings + nrf_block_dev_empty_config_t empty_config; //!< EMPTY block device config + nrf_block_dev_empty_work_t * p_work; //!< EMPTY block device work structure +} nrf_block_dev_empty_t; + +/** + * @brief Defines a EMPTY block device. + * + * @param name Instance name + * @param config Configuration @ref nrf_block_dev_empty_config_t + * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG + * */ +#define NRF_BLOCK_DEV_EMPTY_DEFINE(name, config, info) \ + static nrf_block_dev_empty_work_t CONCAT_2(name, _work); \ + static const nrf_block_dev_empty_t name = { \ + .block_dev = { .p_ops = &nrf_block_device_empty_ops }, \ + .info_strings = BRACKET_EXTRACT(info), \ + .empty_config = config, \ + .p_work = &CONCAT_2(name, _work), \ + } + +/** + * @brief Returns block device API handle from EMPTY block device. + * + * @param[in] p_blk_empty EMPTY block device + * @return Block device handle + */ +static inline nrf_block_dev_t const * +nrf_block_dev_empty_ops_get(nrf_block_dev_empty_t const * p_blk_empty) +{ + return &p_blk_empty->block_dev; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_BLOCK_DEV_EMPTY_H__ */ diff --git a/components/libraries/block_dev/nrf_block_dev.h b/components/libraries/block_dev/nrf_block_dev.h new file mode 100644 index 0000000..4581d5c --- /dev/null +++ b/components/libraries/block_dev/nrf_block_dev.h @@ -0,0 +1,353 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_BLOCK_DEV_H__ +#define NRF_BLOCK_DEV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdk_common.h" +#include "nrf_assert.h" + +#include + +/**@file + * + * @defgroup nrf_block_dev Block device + * @{ + * @ingroup app_common + * + * @brief This module implements unified block device API. It could used as a middle layer between + * filesystems and memories. + */ + +/** + * @brief Block device request descriptor item. + */ +typedef struct { + uint32_t blk_id; //!< Block ID + uint32_t blk_count; //!< Block count + void * p_buff; //!< Data buffer +} nrf_block_req_t; + + +/** + * @brief Helper macro to create block device read/write request item + * + * @param name Instance name + * @param block_start Block number start + * @param block_count Number of blocks + * @param buff Buffer to read/write + */ +#define NRF_BLOCK_DEV_REQUEST(name, block_start, block_count, buff) \ + nrf_block_req_t name = { \ + .blk_id = block_start, \ + .blk_count = block_count, \ + .p_buff = buff, \ + } +/** + * @brief Block device events. + * + * Events are propagated when event handler is defined (@ref nrf_blk_dev_init) + * + */ +typedef enum { + NRF_BLOCK_DEV_EVT_INIT, /**< Passed to event handler when init is done*/ + NRF_BLOCK_DEV_EVT_UNINIT, /**< Passed to event handler when uninit is done*/ + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, /**< Passed to event handler block read operation is done*/ + NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, /**< Passed to event handler block write operation is done*/ +} nrf_block_dev_event_type_t; + +typedef enum { + NRF_BLOCK_DEV_RESULT_SUCCESS = 0, /**< Operation completed succsefully*/ + NRF_BLOCK_DEV_RESULT_IO_ERROR, /**< I/O error*/ + NRF_BLOCK_DEV_RESULT_TIMEOUT, /**< Device timeout*/ +} nrf_block_dev_result_t; + +/** + * @brief Block device event + * */ +typedef struct { + nrf_block_dev_event_type_t ev_type; //!< Event type + nrf_block_dev_result_t result; //!< Operation status + nrf_block_req_t const * p_blk_req; //!< Block request + void const * p_context; //!< Event context +} nrf_block_dev_event_t; + +struct nrf_block_dev_s; + +/** + * @brief Block device event handler. + * + * @param[in] p_blk_dev Block device handle + * @param[in] p_event Block device event + */ +typedef void (* nrf_block_dev_ev_handler)(struct nrf_block_dev_s const * p_blk_dev, + nrf_block_dev_event_t const * p_event); + +/** + * @brief Block device geometry + */ +typedef struct { + uint32_t blk_count; //!< Block count + uint32_t blk_size; //!< Block size +} nrf_block_dev_geometry_t; + +/** + * @brief Block device information strings + */ +typedef struct { + const char * p_vendor; //!< Vendor string + const char * p_product; //!< Product string + const char * p_revision; //!< Revision string +} nrf_block_dev_info_strings_t; + +/** + * @brief Block device information config + * + * @param vendor Vendor string + * @param product Product string + * @param revision Revision string + * */ +#define NFR_BLOCK_DEV_INFO_CONFIG(vendor, product, revision) ( { \ + .p_vendor = vendor, \ + .p_product = product, \ + .p_revision = revision, \ +}) + +/** + * @brief Empty info string initializer + * */ +#define NFR_BLOCK_DEV_INFO_CONFIG_EMPTY \ + NFR_BLOCK_DEV_INFO_CONFIG(NULL, NULL, NULL) + +/** + * @brief Block device IOCTL requests + */ +typedef enum { + NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH = 0, /**< Cache flush IOCTL request*/ + NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS, /**< Get info strings IOCTL request*/ +} nrf_block_dev_ioctl_req_t; + + +/** + * @brief Helper macro to get block device address from specific instance + * + * @param instance Block device instance + * @param member Block device member name + * */ +#define NRF_BLOCKDEV_BASE_ADDR(instance, member) &(instance).member + +/** + * @brief Block device API + * */ +typedef struct nrf_block_dev_s { + struct nrf_block_dev_ops_s { + /** + * @brief @ref nrf_blk_dev_init + */ + ret_code_t (*init)(struct nrf_block_dev_s const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context); + + /** + * @brief @ref nrf_blk_dev_uninit + */ + ret_code_t (*uninit)(struct nrf_block_dev_s const * p_blk_dev); + + /** + * @brief @ref nrf_blk_dev_read_req + */ + ret_code_t (*read_req)(struct nrf_block_dev_s const * p_blk_dev, + nrf_block_req_t const * p_blk); + + /** + * @brief @ref nrf_blk_dev_write_req + */ + ret_code_t (*write_req)(struct nrf_block_dev_s const * p_blk_dev, + nrf_block_req_t const * p_blk); + + /** + * @brief @ref nrf_blk_dev_ioctl + */ + ret_code_t (*ioctl)(struct nrf_block_dev_s const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, + void * p_data); + + /** + * @brief @ref nrf_blk_dev_geometry + */ + nrf_block_dev_geometry_t const * (*geometry)(struct nrf_block_dev_s const * p_blk_dev); + } const * p_ops; +} nrf_block_dev_t; + +/** + * @brief Internals of @ref nrf_block_dev_t + * */ +typedef struct nrf_block_dev_ops_s nrf_block_dev_ops_t; + +/** + * @brief Initializes a block device. + * + * @param[in] p_blk_dev Block device handle + * @param[in] ev_handler Event handler (pass NULL to work in synchronous mode) + * @param[in] p_context Context passed to event handler + * + * @return Standard error code + */ +static inline ret_code_t nrf_blk_dev_init(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context) +{ + ASSERT(p_blk_dev->p_ops->init); + return p_blk_dev->p_ops->init(p_blk_dev, ev_handler, p_context); +} + +/** + * @brief Un-initializes a block device. + * + * @param[in] p_blk_dev Block device handle + * + * @return Standard error code + */ +static inline ret_code_t nrf_blk_dev_uninit(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev->p_ops->uninit); + return p_blk_dev->p_ops->uninit(p_blk_dev); +} + +/** + * @brief Block read request. + * + * In synchronous mode this function will execute the read operation + * and wait for its completion. In asynchronous mode the function will only request + * the operation and return immediately. Then, the @ref NRF_BLOCK_DEV_EVT_BLK_READ_DONE + * event will signal that operation has been completed and the specified buffer contains + * valid data. + * + * @param[in] p_blk_dev Block device handle + * @param[in] p_blk Block device request + * + * @return Standard error code + */ +static inline ret_code_t nrf_blk_dev_read_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev->p_ops->read_req); + ASSERT(p_blk_dev->p_ops->geometry); + + if (p_blk->blk_id >= p_blk_dev->p_ops->geometry(p_blk_dev)->blk_count) + { + return NRF_ERROR_INVALID_PARAM; + } + + return p_blk_dev->p_ops->read_req(p_blk_dev, p_blk); +} + +/** + * @brief Block write request. + * + * In synchronous mode this function will execute the write operation + * and wait for its completion. In asynchronous mode the function will only request + * the operation and return immediately. Then, the @ref NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE + * event will signal that operation has been completed and the specified buffer + * can be freed. + * + * @param[in] p_blk_dev Block device handle + * @param[in] p_blk Block device request + * + * @return Standard error code + */ +static inline ret_code_t nrf_blk_dev_write_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev->p_ops->write_req); + ASSERT(p_blk_dev->p_ops->geometry); + + if (p_blk->blk_id >= p_blk_dev->p_ops->geometry(p_blk_dev)->blk_count) + { + return NRF_ERROR_INVALID_PARAM; + } + + return p_blk_dev->p_ops->write_req(p_blk_dev, p_blk); +} + +/** + * @brief IO control function. + * + * @param[in] p_blk_dev Block device handle + * @param[in] req Block device ioctl request + * @param[in] p_data Block device ioctl data + * + * @return Standard error code + * */ +static inline ret_code_t nrf_blk_dev_ioctl(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, + void * p_data) +{ + ASSERT(p_blk_dev->p_ops->ioctl); + return p_blk_dev->p_ops->ioctl(p_blk_dev, req, p_data); +} + +/** + * @brief Return a geometry of a block device. + * + * @param[in] p_blk_dev Block device handle + * + * @return Block size and count @ref nrf_block_dev_geometry_t + */ +static inline nrf_block_dev_geometry_t const * +nrf_blk_dev_geometry(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev->p_ops->geometry); + return p_blk_dev->p_ops->geometry(p_blk_dev); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_BLOCK_DEV_H__ */ + + diff --git a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c b/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c new file mode 100644 index 0000000..0144a1f --- /dev/null +++ b/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c @@ -0,0 +1,758 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_serial_flash_params.h" +#include "nrf_block_dev_qspi.h" + +/**@file + * + * @ingroup nrf_block_dev_qspi + * @{ + * + * @brief This module implements block device API. It should be used as a reference block device. + */ + +#define QSPI_STD_CMD_WRSR 0x01 /**< Write status register command*/ +#define QSPI_STD_CMD_RSTEN 0x66 /**< Reset enable command*/ +#define QSPI_STD_CMD_RST 0x99 /**< Reset command*/ +#define QSPI_STD_CMD_READ_ID 0x9F /**< Read ID command*/ + +#define BD_PAGE_PROGRAM_SIZE 256 /**< Page program size (minimum block size)*/ + +#define BD_ERASE_UNIT_INVALID_ID 0xFFFFFFFF /**< Invalid erase unit number*/ +#define BD_ERASE_UNIT_ERASE_VAL 0xFFFFFFFF /**< Erased memory value*/ + +/** + * @brief Block to erase unit translation + * + * @param blk_id Block index + * @param blk_size Block size + * */ +#define BD_BLOCK_TO_ERASEUNIT(blk_id, blk_size) \ + ((blk_id) * (blk_size)) / (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) + +/** + * @brief Blocks per erase unit + * + * @param blk_size Block size + * */ +#define BD_BLOCKS_PER_ERASEUNIT(blk_size) \ + (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE / (blk_size)) + + +static ret_code_t block_dev_qspi_eunit_write(nrf_block_dev_qspi_t const * p_qspi_dev, + nrf_block_req_t * p_blk_left); + + +static void block_dev_qspi_read_from_eunit(nrf_block_dev_qspi_t const * p_qspi_dev) +{ + nrf_block_dev_qspi_work_t const * p_work = p_qspi_dev->p_work; + + /*In write-back mode data that we read might not be the same as in erase unit buffer*/ + uint32_t eunit_start = BD_BLOCK_TO_ERASEUNIT(p_work->req.blk_id, + p_work->geometry.blk_size); + + uint32_t eunit_end = BD_BLOCK_TO_ERASEUNIT(p_work->req.blk_id + p_work->req.blk_count, + p_work->geometry.blk_size); + + if ((eunit_start > p_work->erase_unit_idx) || (eunit_end < p_work->erase_unit_idx)) + { + /*Do nothing. Read request doesn't hit current cached erase unit*/ + return; + } + + /*Case 1: Copy data from start erase unit*/ + if (eunit_start == p_work->erase_unit_idx) + { + size_t blk = p_work->req.blk_id % + BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size); + size_t cnt = BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - blk; + size_t off = p_work->geometry.blk_size * blk; + + if (cnt > p_work->req.blk_count) + { + cnt = p_work->req.blk_count; + } + + memcpy(p_work->req.p_buff, + p_work->p_erase_unit_buff + off, + cnt * p_work->geometry.blk_size); + + return; + } + + /*Case 2: Copy data from end erase unit*/ + if (eunit_end == p_work->erase_unit_idx) + { + size_t cnt = (p_work->req.blk_id + p_work->req.blk_count) % + BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size); + size_t off = (p_work->erase_unit_idx * BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - + p_work->req.blk_id) * p_work->geometry.blk_size; + + if (cnt > p_work->req.blk_count) + { + cnt = p_work->req.blk_count; + } + + memcpy((uint8_t *)p_work->req.p_buff + off, + p_work->p_erase_unit_buff, + cnt * p_work->geometry.blk_size); + + return; + } + + /*Case 3: Copy data from eunit_start < p_work->erase_unit_idx < eunit_end*/ + size_t off = (p_work->erase_unit_idx * BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - + p_work->req.blk_id) * p_work->geometry.blk_size; + + memcpy((uint8_t *)p_work->req.p_buff + off, + p_work->p_erase_unit_buff, + NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE); +} + +/** + * @brief Active QSPI block device handle. Only one instance. + * */ +static nrf_block_dev_qspi_t const * m_active_qspi_dev; + +static void qspi_handler(nrf_drv_qspi_evt_t event, void * p_context) +{ + if (m_active_qspi_dev != p_context) + { + return; + } + + nrf_block_dev_qspi_t const * p_qspi_dev = p_context; + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + nrf_block_req_t * p_blk_left = &p_work->left_req; + + switch (p_work->state) + { + case NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC: + { + if (p_work->writeback_mode) + { + block_dev_qspi_read_from_eunit(p_qspi_dev); + } + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + if (p_work->ev_handler) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, + NRF_BLOCK_DEV_RESULT_SUCCESS, + &p_work->req, + p_work->p_context + }; + + p_work->ev_handler(&p_qspi_dev->block_dev, &ev); + } + + break; + } + case NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD: + { + ret_code_t ret; + uint32_t erase_unit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id, + p_work->geometry.blk_size); + UNUSED_VARIABLE(erase_unit); + ASSERT(erase_unit == p_work->erase_unit_idx); + + /* Check if block is in erase unit buffer*/ + ret = block_dev_qspi_eunit_write(p_qspi_dev, p_blk_left); + ASSERT(ret == NRF_SUCCESS); + UNUSED_VARIABLE(ret); + break; + } + case NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE: + case NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC: + { + /*Clear last programmed block*/ + uint32_t block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks)); + + if (p_work->state == NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC) + { + p_work->erase_unit_dirty_blocks ^= 1u << block_to_program; + } + + if (p_work->erase_unit_dirty_blocks == 0) + { + if (p_work->left_req.blk_count) + { + /*Load next erase unit*/ + ret_code_t ret; + uint32_t eunit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id, + p_work->geometry.blk_size); + + p_work->erase_unit_idx = eunit; + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD; + + ret = nrf_drv_qspi_read(p_work->p_erase_unit_buff, + NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE, + p_work->erase_unit_idx * + NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE); + UNUSED_VARIABLE(ret); + + break; + } + + /*All blocks are programmed. Call event handler if required.*/ + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + if (p_work->ev_handler && !p_work->cache_flushing) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, + NRF_BLOCK_DEV_RESULT_SUCCESS, + &p_work->req, + p_work->p_context + }; + + p_work->ev_handler(&p_qspi_dev->block_dev, &ev); + } + + p_work->cache_flushing = false; + break; + } + + /*Get next block to program from program mask*/ + block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks)); + uint32_t dst_address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) + + (block_to_program * p_work->geometry.blk_size); + + const void * p_src_address = p_work->p_erase_unit_buff + + block_to_program * p_work->geometry.blk_size; + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC; + ret_code_t ret = nrf_drv_qspi_write(p_src_address, + p_work->geometry.blk_size, + dst_address); + UNUSED_VARIABLE(ret); + break; + } + default: + ASSERT(0); + break; + } +} + +static void wait_for_idle(nrf_block_dev_qspi_t const * p_qspi_dev) +{ + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + while (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE) + { + __WFI(); + } +} + +static ret_code_t block_dev_qspi_init(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context) +{ + ASSERT(p_blk_dev); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + nrf_drv_qspi_config_t const * p_qspi_cfg = &p_qspi_dev->qspi_bdev_config.qspi_config; + + ret_code_t ret = NRF_SUCCESS; + + if (p_qspi_dev->qspi_bdev_config.block_size % BD_PAGE_PROGRAM_SIZE) + { + /*Unsupported block size*/ + return NRF_ERROR_NOT_SUPPORTED; + } + + if (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE % p_qspi_dev->qspi_bdev_config.block_size) + { + /*Unsupported block size*/ + return NRF_ERROR_NOT_SUPPORTED; + } + + if (m_active_qspi_dev) + { + /* QSPI instance is BUSY*/ + return NRF_ERROR_BUSY; + } + + ret = nrf_drv_qspi_init(p_qspi_cfg, qspi_handler, (void *)p_blk_dev); + if (ret != NRF_SUCCESS) + { + return ret; + } + + nrf_qspi_cinstr_conf_t cinstr_cfg = { + .opcode = QSPI_STD_CMD_RSTEN, + .length = NRF_QSPI_CINSTR_LEN_1B, + .io2_level = true, + .io3_level = true, + .wipwait = true, + .wren = true + }; + + /* Send reset enable */ + ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + /* Send reset command */ + cinstr_cfg.opcode = QSPI_STD_CMD_RST; + ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL); + if (ret != NRF_SUCCESS) + { + return ret; + } + + /* Get 3 byte identification value */ + uint8_t rdid_buf[3] = {0, 0, 0}; + cinstr_cfg.opcode = QSPI_STD_CMD_READ_ID; + cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_4B; + ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, rdid_buf); + if (ret != NRF_SUCCESS) + { + return ret; + } + + nrf_serial_flash_params_t const * serial_flash_id = nrf_serial_flash_params_get(rdid_buf); + + if (!serial_flash_id) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (serial_flash_id->erase_size != NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + /* Calculate block device geometry.... */ + uint32_t blk_size = p_qspi_dev->qspi_bdev_config.block_size; + uint32_t blk_count = serial_flash_id->size / p_qspi_dev->qspi_bdev_config.block_size; + + if (!blk_count || (blk_count % BD_BLOCKS_PER_ERASEUNIT(blk_size))) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + p_work->geometry.blk_size = blk_size; + p_work->geometry.blk_count = blk_count; + p_work->p_context = p_context; + p_work->ev_handler = ev_handler; + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + p_work->erase_unit_idx = BD_ERASE_UNIT_INVALID_ID; + p_work->writeback_mode = (p_qspi_dev->qspi_bdev_config.flags & + NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK) != 0; + m_active_qspi_dev = p_qspi_dev; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_INIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_qspi_uninit(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + if (m_active_qspi_dev != p_qspi_dev) + { + /* QSPI instance is BUSY*/ + return NRF_ERROR_BUSY; + } + + if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE) + { + /* Previous asynchronous operation in progress*/ + return NRF_ERROR_BUSY; + } + + if (p_work->ev_handler) + { + /*Asynchronous operation*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_UNINIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_DISABLED; + nrf_drv_qspi_uninit(); + + memset(p_work, 0, sizeof(nrf_block_dev_qspi_work_t)); + m_active_qspi_dev = NULL; + return NRF_SUCCESS; +} + +static ret_code_t block_dev_qspi_read_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + ret_code_t ret = NRF_SUCCESS; + + if (m_active_qspi_dev != p_qspi_dev) + { + /* QSPI instance is BUSY*/ + return NRF_ERROR_BUSY; + } + + if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE) + { + /* Previous asynchronous operation in progress*/ + return NRF_ERROR_BUSY; + } + + p_work->left_req = *p_blk; + p_work->req = *p_blk; + nrf_block_req_t * p_blk_left = &p_work->left_req; + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC; + ret = nrf_drv_qspi_read(p_blk_left->p_buff, + p_blk_left->blk_count * p_work->geometry.blk_size, + p_blk_left->blk_id * p_work->geometry.blk_size); + + if (ret != NRF_SUCCESS) + { + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + return ret; + } + + p_blk_left->p_buff = NULL; + p_blk_left->blk_count = 0; + + if (!p_work->ev_handler && (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)) + { + /*Synchronous operation*/ + wait_for_idle(p_qspi_dev); + } + + return ret; +} + +static bool block_dev_qspi_update_eunit(nrf_block_dev_qspi_t const * p_qspi_dev, + size_t off, + const void * p_src, + size_t len) +{ + ASSERT((len % sizeof(uint32_t)) == 0) + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + uint32_t * p_dst32 = (uint32_t *)(p_work->p_erase_unit_buff + off); + const uint32_t * p_src32 = p_src; + + bool erase_required = false; + len /= sizeof(uint32_t); + + /*Do normal copying until erase unit is not required*/ + do + { + if (*p_dst32 != *p_src32) + { + if (*p_dst32 != BD_ERASE_UNIT_ERASE_VAL) + { + erase_required = true; + } + + /*Mark block as dirty*/ + p_work->erase_unit_dirty_blocks |= 1u << (off / p_work->geometry.blk_size); + } + + *p_dst32++ = *p_src32++; + off += sizeof(uint32_t); + } while (--len); + + return erase_required; +} + +static ret_code_t block_dev_qspi_write_start(nrf_block_dev_qspi_t const * p_qspi_dev) +{ + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + if (!p_work->erase_required) + { + /*Get first block to program from program mask*/ + uint32_t block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks)); + uint32_t dst_address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) + + (block_to_program * p_work->geometry.blk_size); + + const void * p_src_address = p_work->p_erase_unit_buff + + block_to_program * p_work->geometry.blk_size; + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC; + return nrf_drv_qspi_write(p_src_address, + p_work->geometry.blk_size, + dst_address); + } + + /*Erase is required*/ + uint32_t address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE); + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE; + p_work->erase_required = false; + + return nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address); +} + +static ret_code_t block_dev_qspi_eunit_write(nrf_block_dev_qspi_t const * p_qspi_dev, + nrf_block_req_t * p_blk_left) +{ + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + size_t blk = p_blk_left->blk_id % + BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size); + size_t cnt = BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - blk; + size_t off = p_work->geometry.blk_size * blk; + + if (cnt > p_blk_left->blk_count) + { + cnt = p_blk_left->blk_count; + } + + bool erase_required = block_dev_qspi_update_eunit(p_qspi_dev, + off, + p_blk_left->p_buff, + cnt * p_work->geometry.blk_size); + if (erase_required) + { + p_work->erase_required = true; + } + + p_blk_left->blk_count -= cnt; + p_blk_left->blk_id += cnt; + p_blk_left->p_buff = (uint8_t *)p_blk_left->p_buff + cnt * p_work->geometry.blk_size; + + if (p_work->erase_required) + { + uint32_t blk_size = p_work->geometry.blk_size; + p_work->erase_unit_dirty_blocks |= (1u << BD_BLOCKS_PER_ERASEUNIT(blk_size)) - 1; + } + + if (p_work->erase_unit_dirty_blocks == 0 || p_work->writeback_mode) + { + /*No dirty blocks detected. Write end.*/ + if (p_work->ev_handler && p_blk_left->blk_count == 0) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, + NRF_BLOCK_DEV_RESULT_SUCCESS, + &p_work->req, + p_work->p_context + }; + + + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + p_work->ev_handler(&p_qspi_dev->block_dev, &ev); + return NRF_SUCCESS; + } + } + + return block_dev_qspi_write_start(p_qspi_dev); +} + +static ret_code_t block_dev_qspi_write_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + ret_code_t ret = NRF_SUCCESS; + + if (m_active_qspi_dev != p_qspi_dev) + { + /* QSPI instance is BUSY*/ + return NRF_ERROR_BUSY; + } + + if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE) + { + /* Previous asynchronous operation in progress*/ + return NRF_ERROR_BUSY; + } + + p_work->left_req = *p_blk; + p_work->req = *p_blk; + + nrf_block_req_t * p_blk_left = &p_work->left_req; + + uint32_t erase_unit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id, + p_work->geometry.blk_size); + + /* Check if block is in erase unit buffer*/ + if (erase_unit == p_work->erase_unit_idx) + { + ret = block_dev_qspi_eunit_write(p_qspi_dev, p_blk_left); + } + else + { + if (p_work->writeback_mode) + { + ret = block_dev_qspi_write_start(p_qspi_dev); + } + else + { + p_work->erase_unit_idx = erase_unit; + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD; + + ret = nrf_drv_qspi_read(p_work->p_erase_unit_buff, + NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE, + erase_unit * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE); + } + } + + if (ret != NRF_SUCCESS) + { + p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE; + return ret; + } + + if (!p_work->ev_handler && (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)) + { + /*Synchronous operation*/ + wait_for_idle(p_qspi_dev); + } + + return ret; +} + +static ret_code_t block_dev_qspi_ioctl(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, + void * p_data) +{ + ASSERT(p_blk_dev); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work; + + switch (req) + { + case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH: + { + bool * p_flushing = p_data; + if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE) + { + return NRF_ERROR_BUSY; + } + + if (!p_work->writeback_mode || p_work->erase_unit_dirty_blocks == 0) + { + if (p_flushing) + { + *p_flushing = false; + } + + return NRF_SUCCESS; + } + + ret_code_t ret = block_dev_qspi_write_start(p_qspi_dev); + if (ret == NRF_SUCCESS) + { + if (p_flushing) + { + *p_flushing = true; + } + p_work->cache_flushing = true; + } + + return ret; + } + case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS: + { + if (p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_block_dev_info_strings_t const * * pp_strings = p_data; + *pp_strings = &p_qspi_dev->info_strings; + return NRF_SUCCESS; + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +static nrf_block_dev_geometry_t const * block_dev_qspi_geometry(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_qspi_t const * p_qspi_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev); + nrf_block_dev_qspi_work_t const * p_work = p_qspi_dev->p_work; + + return &p_work->geometry; +} + +const nrf_block_dev_ops_t nrf_block_device_qspi_ops = { + .init = block_dev_qspi_init, + .uninit = block_dev_qspi_uninit, + .read_req = block_dev_qspi_read_req, + .write_req = block_dev_qspi_write_req, + .ioctl = block_dev_qspi_ioctl, + .geometry = block_dev_qspi_geometry, +}; + + +/** @} */ diff --git a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h b/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h new file mode 100644 index 0000000..d006d7d --- /dev/null +++ b/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h @@ -0,0 +1,173 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_BLOCK_DEV_QSPI_H__ +#define NRF_BLOCK_DEV_QSPI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_block_dev.h" +#include "nrf_drv_qspi.h" + +/**@file + * + * @defgroup nrf_block_dev_qspi QSPI implementation + * @ingroup nrf_block_dev + * @{ + * + */ + +/** + * @brief QSPI block device operations + * */ +extern const nrf_block_dev_ops_t nrf_block_device_qspi_ops; + +/** + * @brief QSPI block device internal erase unit buffer size + * */ +#define NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE (4096) + +/** + * @brief Internal Block device state + */ +typedef enum { + NRF_BLOCK_DEV_QSPI_STATE_DISABLED = 0, /**< QSPI block device state DISABLED */ + NRF_BLOCK_DEV_QSPI_STATE_IDLE, /**< QSPI block device state IDLE */ + NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC, /**< QSPI block device state READ_EXEC */ + NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD, /**< QSPI block device state EUNIT_LOAD */ + NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE, /**< QSPI block device state WRITE_ERASE */ + NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC, /**< QSPI block device state WRITE_EXEC */ +} nrf_block_dev_qspi_state_t; + +/** + * @brief Work structure of QSPI block device + */ +typedef struct { + volatile nrf_block_dev_qspi_state_t state; //!< QSPI block device state + + nrf_block_dev_geometry_t geometry; //!< Block device geometry + nrf_block_dev_ev_handler ev_handler; //!< Block device event handler + void const * p_context; //!< Context handle passed to event handler + nrf_block_req_t req; //!< Block READ/WRITE request: original value + nrf_block_req_t left_req; //!< Block READ/WRITE request: left value + + bool cache_flushing; //!< QSPI cache flush in progress flag + bool writeback_mode; //!< QSPI write-back mode flag + bool erase_required; //!< QSPI erase required flag + uint32_t erase_unit_idx; //!< QSPI erase unit index + uint32_t erase_unit_dirty_blocks; //!< QSPI erase unit dirty blocks mask + uint8_t p_erase_unit_buff[NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE]; //!< QSPI erase unit buffer (fixed value) +} nrf_block_dev_qspi_work_t; + +/** + * @brief QSPI block device flags*/ +typedef enum { + NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK = (1u << 0) //!< Cache write-back mode enable flag +} nrf_block_dev_qspi_flag_t; + +/** + * @brief QSPI block device config initializer (@ref nrf_block_dev_qspi_config_t) + * + * @param blk_size Block size + * @param blk_flags Block device flags, @ref nrf_block_dev_qspi_flag_t + * @param qspi_drv_config QPSI driver config + * */ +#define NRF_BLOCK_DEV_QSPI_CONFIG(blk_size, blk_flags, qspi_drv_config) { \ + .block_size = (blk_size), \ + .flags = (blk_flags), \ + .qspi_config = qspi_drv_config \ +} + +/** + * @brief QSPI block device config + */ +typedef struct { + uint32_t block_size; //!< Desired block size + uint32_t flags; //!< QSPI block device flags + nrf_drv_qspi_config_t qspi_config; //!< QSPI configuration +} nrf_block_dev_qspi_config_t; + +/** + * @brief QSPI block device + * */ +typedef struct { + nrf_block_dev_t block_dev; //!< Block device + nrf_block_dev_info_strings_t info_strings; //!< Block device information strings + nrf_block_dev_qspi_config_t qspi_bdev_config; //!< QSPI block device config + nrf_block_dev_qspi_work_t * p_work; //!< QSPI block device work structure +} nrf_block_dev_qspi_t; + +/** + * @brief Defines a QSPI block device. + * + * @param name Instance name + * @param config Configuration @ref nrf_block_dev_qspi_config_t + * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG + * */ +#define NRF_BLOCK_DEV_QSPI_DEFINE(name, config, info) \ + static nrf_block_dev_qspi_work_t CONCAT_2(name, _work); \ + static const nrf_block_dev_qspi_t name = { \ + .block_dev = { .p_ops = &nrf_block_device_qspi_ops }, \ + .info_strings = BRACKET_EXTRACT(info), \ + .qspi_bdev_config = config, \ + .p_work = &CONCAT_2(name, _work), \ + } + +/** + * @brief Returns block device API handle from QSPI block device. + * + * @param[in] p_blk_qspi QSPI block device + * @return Block device handle + */ +static inline nrf_block_dev_t const * +nrf_block_dev_qspi_ops_get(nrf_block_dev_qspi_t const * p_blk_qspi) +{ + return &p_blk_qspi->block_dev; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_BLOCK_DEV_QSPI_H__ */ diff --git a/components/libraries/block_dev/qspi/nrf_serial_flash_params.c b/components/libraries/block_dev/qspi/nrf_serial_flash_params.c new file mode 100644 index 0000000..e59d061 --- /dev/null +++ b/components/libraries/block_dev/qspi/nrf_serial_flash_params.c @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_serial_flash_params.h" + +static const nrf_serial_flash_params_t m_sflash_params[] = { + { /*MXIC MX25R6435F*/ + .read_id = { 0xC2, 0x28, 0x17 }, + .capabilities = 0x00, + .size = 8 * 1024 * 1024, + .erase_size = 4 * 1024, + .program_size = 256, + } +}; + +nrf_serial_flash_params_t const * nrf_serial_flash_params_get(const uint8_t * p_read_id) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(m_sflash_params); ++i) + { + if (memcmp(m_sflash_params[i].read_id, p_read_id, sizeof(m_sflash_params[i].read_id)) == 0) + { + return &m_sflash_params[i]; + } + } + + return NULL; +} diff --git a/components/libraries/block_dev/qspi/nrf_serial_flash_params.h b/components/libraries/block_dev/qspi/nrf_serial_flash_params.h new file mode 100644 index 0000000..bb051bb --- /dev/null +++ b/components/libraries/block_dev/qspi/nrf_serial_flash_params.h @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SERIAL_FLASH_PARAMS_H__ +#define NRF_SERIAL_FLASH_PARAMS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdk_common.h" + +/**@file + * + * @defgroup nrf_serial_flash_params Serial flash memory parameters + * @ingroup nrf_block_dev + * @{ + * + */ + +/** + * @brief Serial flash memory parameters + * */ +typedef struct { + uint8_t read_id[3]; //!< Read identification command (0x9F) result + uint8_t capabilities; //!< Serial flash memory capabilities + uint32_t size; //!< Serial flash memory size (bytes) + uint32_t erase_size; //!< Serial flash memory erase unit size (bytes) + uint32_t program_size; //!< Serial flash memory program size (bytes) +} nrf_serial_flash_params_t; + + +/** + * @brief Returns serial flash memory identification descriptor + * + * @param p_read_params Memory read identification command result + * + * @return Serial flash memory descriptor (NULL if not found) + * */ +nrf_serial_flash_params_t const * nrf_serial_flash_params_get(const uint8_t * p_read_params); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SERIAL_FLASH_PARAMS_H__ */ diff --git a/components/libraries/block_dev/ram/nrf_block_dev_ram.c b/components/libraries/block_dev/ram/nrf_block_dev_ram.c new file mode 100644 index 0000000..229da89 --- /dev/null +++ b/components/libraries/block_dev/ram/nrf_block_dev_ram.c @@ -0,0 +1,206 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_block_dev_ram.h" + +/**@file + * + * @ingroup nrf_block_dev + * @{ + * + * @brief This module implements block device API. It should be used as a reference block device. + */ + +static ret_code_t block_dev_ram_init(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context) +{ + ASSERT(p_blk_dev); + nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev); + nrf_block_dev_ram_work_t * p_work = p_ram_dev->p_work; + + /* Calculate block device geometry.... */ + p_work->geometry.blk_size = p_ram_dev->ram_config.block_size; + p_work->geometry.blk_count = p_ram_dev->ram_config.size / + p_ram_dev->ram_config.block_size; + p_work->p_context = p_context; + p_work->ev_handler = ev_handler; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_INIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_ram_uninit(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev); + nrf_block_dev_ram_work_t * p_work = p_ram_dev->p_work; + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_UNINIT, + NRF_BLOCK_DEV_RESULT_SUCCESS, + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + memset(p_work, 0, sizeof(nrf_block_dev_ram_work_t)); + return NRF_SUCCESS; +} + +static ret_code_t block_dev_ram_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk, + nrf_block_dev_event_type_t event) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev); + nrf_block_dev_ram_config_t const * p_ram_config = &p_ram_dev->ram_config; + nrf_block_dev_ram_work_t const * p_work = p_ram_dev->p_work; + + /*Synchronous operation*/ + uint8_t * p_buff = p_ram_config->p_work_buffer; + p_buff += p_blk->blk_id * p_work->geometry.blk_size; + + const void * p_src = (event == NRF_BLOCK_DEV_EVT_BLK_READ_DONE) ? p_buff : p_blk->p_buff; + void * p_dst = (event == NRF_BLOCK_DEV_EVT_BLK_READ_DONE) ? p_blk->p_buff : p_buff; + + memcpy(p_dst, p_src, p_work->geometry.blk_size * p_blk->blk_count); + + if (p_work->ev_handler) + { + /*Asynchronous operation (simulation)*/ + const nrf_block_dev_event_t ev = { + event, + NRF_BLOCK_DEV_RESULT_SUCCESS, + p_blk, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return NRF_SUCCESS; +} + +static ret_code_t block_dev_ram_read_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + return block_dev_ram_req(p_blk_dev, p_blk, NRF_BLOCK_DEV_EVT_BLK_READ_DONE); +} + +static ret_code_t block_dev_ram_write_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + return block_dev_ram_req(p_blk_dev, p_blk, NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE); +} + +static ret_code_t block_dev_ram_ioctl(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, + void * p_data) +{ + nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev); + switch (req) + { + case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH: + { + bool * p_flushing = p_data; + if (p_flushing) + { + *p_flushing = false; + } + return NRF_SUCCESS; + } + case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS: + { + if (p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_block_dev_info_strings_t const * * pp_strings = p_data; + *pp_strings = &p_ram_dev->info_strings; + return NRF_SUCCESS; + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + + +static nrf_block_dev_geometry_t const * block_dev_ram_geometry(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev); + nrf_block_dev_ram_work_t const * p_work = p_ram_dev->p_work; + + return &p_work->geometry; +} + +const nrf_block_dev_ops_t nrf_block_device_ram_ops = { + .init = block_dev_ram_init, + .uninit = block_dev_ram_uninit, + .read_req = block_dev_ram_read_req, + .write_req = block_dev_ram_write_req, + .ioctl = block_dev_ram_ioctl, + .geometry = block_dev_ram_geometry, +}; + + +/** @} */ diff --git a/components/libraries/block_dev/ram/nrf_block_dev_ram.h b/components/libraries/block_dev/ram/nrf_block_dev_ram.h new file mode 100644 index 0000000..9cb017e --- /dev/null +++ b/components/libraries/block_dev/ram/nrf_block_dev_ram.h @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_BLOCK_DEV_RAM_H__ +#define NRF_BLOCK_DEV_RAM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_block_dev.h" + +/**@file + * + * @defgroup nrf_block_dev_ram RAM implementation + * @ingroup nrf_block_dev + * @{ + + * + * @brief This module implements block device API. It should be used as a reference block device. + */ + +/** + * @brief RAM block device operations + * */ +extern const nrf_block_dev_ops_t nrf_block_device_ram_ops; + +/** + * @brief Work structure of RAM block device + */ +typedef struct { + nrf_block_dev_geometry_t geometry; //!< Block device geometry + nrf_block_dev_ev_handler ev_handler; //!< Block device event handler + void const * p_context; //!< Context handle passed to event handler +} nrf_block_dev_ram_work_t; + + +/** + * @brief RAM block device config initializer (@ref nrf_block_dev_ram_config_t) + * + * @param blk_size Block size + * @param buffer RAM work buffer + * @param buffer_size RAM work buffer size + * */ +#define NRF_BLOCK_DEV_RAM_CONFIG(blk_size, buffer, buffer_size) { \ + .block_size = (blk_size), \ + .p_work_buffer = (buffer), \ + .size = (buffer_size), \ +} + +/** + * @brief Ram block device config + */ +typedef struct { + uint32_t block_size; //!< Desired block size + void * p_work_buffer; //!< Ram work buffer + size_t size; //!< Ram work buffer size +} nrf_block_dev_ram_config_t; + +/** + * @brief Ram block device + * */ +typedef struct { + nrf_block_dev_t block_dev; //!< Block device + nrf_block_dev_info_strings_t info_strings; //!< Block device information strings + nrf_block_dev_ram_config_t ram_config; //!< Ram block device config + nrf_block_dev_ram_work_t * p_work; //!< Ram block device work structure +} nrf_block_dev_ram_t; + +/** + * @brief Defines a RAM block device. + * + * @param name Instance name + * @param config Configuration @ref nrf_block_dev_ram_config_t + * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG + * */ +#define NRF_BLOCK_DEV_RAM_DEFINE(name, config, info) \ + static nrf_block_dev_ram_work_t CONCAT_2(name, _work); \ + static const nrf_block_dev_ram_t name = { \ + .block_dev = { .p_ops = &nrf_block_device_ram_ops }, \ + .info_strings = BRACKET_EXTRACT(info), \ + .ram_config = config, \ + .p_work = &CONCAT_2(name, _work), \ + } + +/** + * @brief Returns block device API handle from RAM block device. + * + * @param[in] p_blk_ram Ram block device + * @return Block device handle + */ +static inline nrf_block_dev_t const * +nrf_block_dev_ram_ops_get(nrf_block_dev_ram_t const * p_blk_ram) +{ + return &p_blk_ram->block_dev; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_BLOCK_DEV_RAM_H__ */ diff --git a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c b/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c new file mode 100644 index 0000000..c37f5dd --- /dev/null +++ b/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c @@ -0,0 +1,393 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_block_dev_sdc.h" + +/**@file + * + * @ingroup nrf_block_dev_sdc + * @{ + * + * @brief This module implements block device API. It should be used as a reference block device. + */ + + +static volatile sdc_result_t m_last_result; + + +/** + * @brief Active SDC block device handle. Only one instance. + * */ +static nrf_block_dev_sdc_t const * m_active_sdc_dev; + + + +static void wait_func(void) +{ +} + +static void sdc_wait() +{ + while (app_sdc_busy_check()) + { + wait_func(); + } +} + + +static void sdc_handler(sdc_evt_t const * p_event) +{ + m_last_result = p_event->result; + nrf_block_dev_sdc_t const * p_sdc_dev = m_active_sdc_dev; + nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work; + + switch (p_event->type) + { + case SDC_EVT_INIT: + { + p_work->geometry.blk_count = app_sdc_info_get()->num_blocks; + p_work->geometry.blk_size = SDC_SECTOR_SIZE; + if (m_active_sdc_dev->p_work->ev_handler) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_INIT, + ((p_event->result == SDC_SUCCESS) ? \ + NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR), + NULL, + p_work->p_context + }; + p_work->ev_handler(&p_sdc_dev->block_dev, &ev); + } + } + break; + + case SDC_EVT_READ: + if (m_active_sdc_dev->p_work->ev_handler) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, + ((p_event->result == SDC_SUCCESS) ? \ + NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR), + &p_work->req, + p_work->p_context + }; + p_work->ev_handler(&p_sdc_dev->block_dev, &ev); + } + break; + + case SDC_EVT_WRITE: + if (m_active_sdc_dev->p_work->ev_handler) + { + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, + ((p_event->result == SDC_SUCCESS) ? \ + NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR), + &p_work->req, + p_work->p_context + }; + p_work->ev_handler(&p_sdc_dev->block_dev, &ev); + } + break; + + default: + APP_ERROR_CHECK(NRF_ERROR_INTERNAL); + return; + } +} + + +static ret_code_t block_dev_sdc_init(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ev_handler ev_handler, + void const * p_context) +{ + ASSERT(p_blk_dev); + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work; + + if (p_sdc_dev->sdc_bdev_config.block_size != SDC_SECTOR_SIZE) + { + /* Unsupported block size. */ + return NRF_ERROR_NOT_SUPPORTED; + } + + if (m_active_sdc_dev) + { + /* SDC instance is busy. */ + return NRF_ERROR_BUSY; + } + + p_work->p_context = p_context; + p_work->ev_handler = ev_handler; + m_active_sdc_dev = p_sdc_dev; + + ret_code_t err_code = NRF_SUCCESS; + + err_code = app_sdc_init(&p_sdc_dev->sdc_bdev_config.sdc_config, sdc_handler); + if (err_code == NRF_SUCCESS) + { + if (!ev_handler) + { + /* Synchronous mode - wait for the card. */ + sdc_wait(); + err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT); + } + } + + if (err_code != NRF_SUCCESS) + { + m_active_sdc_dev = NULL; + + if (ev_handler) + { + /* Call the user handler with an error status. */ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_INIT, + NRF_BLOCK_DEV_RESULT_IO_ERROR, + NULL, + p_work->p_context + }; + p_work->ev_handler(p_blk_dev, &ev); + } + } + + return err_code; +} + +static ret_code_t block_dev_sdc_uninit(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work; + + if (m_active_sdc_dev != p_sdc_dev) + { + /* SDC instance is busy. */ + return NRF_ERROR_BUSY; + } + + if (app_sdc_busy_check()) + { + /* Previous asynchronous operation in progress. */ + return NRF_ERROR_BUSY; + } + + ret_code_t err_code = app_sdc_uninit(); + if (err_code == NRF_SUCCESS) + { + /* Free the instance on success. */ + m_active_sdc_dev = NULL; + } + + if (p_work->ev_handler) + { + /* SDC uninitialization is a synchronous operation. Call event handler. */ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_UNINIT, + ((err_code == NRF_SUCCESS) ? \ + NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR), + NULL, + p_work->p_context + }; + + p_work->ev_handler(p_blk_dev, &ev); + } + + return err_code; +} + +static ret_code_t block_dev_sdc_read_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work; + + ret_code_t err_code = NRF_SUCCESS; + + if (m_active_sdc_dev != p_sdc_dev) + { + /* SDC instance is busy. */ + return NRF_ERROR_BUSY; + } + + if (app_sdc_busy_check()) + { + /* Previous asynchronous operation in progress. */ + return NRF_ERROR_BUSY; + } + + p_work->req = *p_blk; + err_code = app_sdc_block_read(p_blk->p_buff, p_blk->blk_id, p_blk->blk_count); + if (err_code == NRF_SUCCESS) + { + if (!p_work->ev_handler) + { + /* Synchronous mode - wait for the card. */ + sdc_wait(); + err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT); + } + } + + if ((p_work->ev_handler) && (err_code != NRF_SUCCESS)) + { + /* Call the user handler with an error status. */ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, + NRF_BLOCK_DEV_RESULT_IO_ERROR, + &p_work->req, + p_work->p_context + }; + p_work->ev_handler(p_blk_dev, &ev); + } + + return err_code; +} + +static ret_code_t block_dev_sdc_write_req(nrf_block_dev_t const * p_blk_dev, + nrf_block_req_t const * p_blk) +{ + ASSERT(p_blk_dev); + ASSERT(p_blk); + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work; + + ret_code_t err_code = NRF_SUCCESS; + + if (m_active_sdc_dev != p_sdc_dev) + { + /* SDC instance is busy. */ + return NRF_ERROR_BUSY; + } + + if (app_sdc_busy_check()) + { + /* Previous asynchronous operation in progress. */ + return NRF_ERROR_BUSY; + } + + p_work->req = *p_blk; + err_code = app_sdc_block_write(p_blk->p_buff, p_blk->blk_id, p_blk->blk_count); + if (err_code == NRF_SUCCESS) + { + if (!p_work->ev_handler) + { + /* Synchronous mode - wait for the card. */ + sdc_wait(); + err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT); + } + } + + if ((p_work->ev_handler) && (err_code != NRF_SUCCESS)) + { + /* Call the user handler with an error status. */ + const nrf_block_dev_event_t ev = { + NRF_BLOCK_DEV_EVT_BLK_READ_DONE, + NRF_BLOCK_DEV_RESULT_IO_ERROR, + &p_work->req, + p_work->p_context + }; + p_work->ev_handler(p_blk_dev, &ev); + } + + return err_code; +} + +static ret_code_t block_dev_sdc_ioctl(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_ioctl_req_t req, + void * p_data) +{ + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + switch (req) + { + case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH: + { + bool * p_flushing = p_data; + if (p_flushing) + { + *p_flushing = false; + } + return NRF_SUCCESS; + } + case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS: + { + if (p_data == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + nrf_block_dev_info_strings_t const * * pp_strings = p_data; + *pp_strings = &p_sdc_dev->info_strings; + return NRF_SUCCESS; + } + default: + break; + } + + + return NRF_ERROR_NOT_SUPPORTED; +} + +static nrf_block_dev_geometry_t const * block_dev_sdc_geometry(nrf_block_dev_t const * p_blk_dev) +{ + ASSERT(p_blk_dev); + nrf_block_dev_sdc_t const * p_sdc_dev = + CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev); + nrf_block_dev_sdc_work_t const * p_work = p_sdc_dev->p_work; + + return &p_work->geometry; +} + +const nrf_block_dev_ops_t nrf_block_device_sdc_ops = { + .init = block_dev_sdc_init, + .uninit = block_dev_sdc_uninit, + .read_req = block_dev_sdc_read_req, + .write_req = block_dev_sdc_write_req, + .ioctl = block_dev_sdc_ioctl, + .geometry = block_dev_sdc_geometry, +}; + + +/** @} */ diff --git a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h b/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h new file mode 100644 index 0000000..e77e039 --- /dev/null +++ b/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup nrf_block_dev_sdc SDC implementation + * @ingroup nrf_block_dev + * @{ + * + */ + + +#ifndef NRF_BLOCK_DEV_SDC_H__ +#define NRF_BLOCK_DEV_SDC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_block_dev.h" +#include "app_sdcard.h" + +/** + * @brief SDC block device operations + * */ +extern const nrf_block_dev_ops_t nrf_block_device_sdc_ops; + +/** + * @brief Work structure of SDC block device + */ +typedef struct { + nrf_block_dev_geometry_t geometry; //!< Block device geometry + nrf_block_dev_ev_handler ev_handler; //!< Block device event handler + nrf_block_req_t req; //!< Block READ/WRITE request + void const * p_context; //!< Context handle passed to event handler +} nrf_block_dev_sdc_work_t; + +/** + * @brief SDC block device config initializer (@ref nrf_block_dev_sdc_config_t) + * + * @param blk_size Block size + * @param sdc_lib_config SDC library config (@ref app_sdc_config_t) + * */ +#define NRF_BLOCK_DEV_SDC_CONFIG(blk_size, sdc_lib_config) \ +{ \ + .block_size = (blk_size), \ + .sdc_config = sdc_lib_config \ +} + + +/** + * @brief SDC block device config + */ +typedef struct { + uint32_t block_size; //!< Desired block size + app_sdc_config_t sdc_config; //!< SDC library configuration +} nrf_block_dev_sdc_config_t; + +/** + * @brief SDC block device + * */ +typedef struct { + nrf_block_dev_t block_dev; //!< Block device + nrf_block_dev_info_strings_t info_strings; //!< Block device information strings + nrf_block_dev_sdc_config_t sdc_bdev_config; //!< SDC block device config + nrf_block_dev_sdc_work_t * p_work; //!< SDC block device work structure +} nrf_block_dev_sdc_t; + +/** + * @brief Defines a SDC block device. + * + * @param name Instance name + * @param config Configuration @ref nrf_block_dev_sdc_config_t + * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG + * */ +#define NRF_BLOCK_DEV_SDC_DEFINE(name, config, info) \ + static nrf_block_dev_sdc_work_t CONCAT_2(name, _work); \ + static const nrf_block_dev_sdc_t name = { \ + .block_dev = { .p_ops = &nrf_block_device_sdc_ops }, \ + .info_strings = BRACKET_EXTRACT(info), \ + .sdc_bdev_config = config, \ + .p_work = &CONCAT_2(name, _work), \ + } + +/** + * @brief Returns block device API handle from SDC block device. + * + * @param[in] p_blk_sdc SDC block device + * @return Block device handle + */ +static inline nrf_block_dev_t const * +nrf_block_dev_sdc_ops_get(nrf_block_dev_sdc_t const * p_blk_sdc) +{ + return &p_blk_sdc->block_dev; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_BLOCK_DEV_SDC_H__ */ diff --git a/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.c b/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.c new file mode 100644 index 0000000..9c1003c --- /dev/null +++ b/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.c @@ -0,0 +1,1021 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_ble_dfu.h" + +#include +#include "sdk_common.h" +#include "nrf_dfu_req_handler.h" +#include "nrf_dfu_transport.h" +#include "nrf_dfu_mbr.h" +#include "nrf_bootloader_info.h" +#include "ble_conn_params.h" +#include "boards.h" +#include "nrf_log.h" +#include "ble_hci.h" +#include "app_timer.h" +#include "softdevice_handler_appsh.h" +#include "nrf_log.h" +#include "nrf_delay.h" + +#define ADVERTISING_LED_PIN_NO BSP_LED_0 /**< Is on when device is advertising. */ +#define CONNECTED_LED_PIN_NO BSP_LED_1 /**< Is on when device has connected. */ + +#define DEVICE_NAME "DfuTarg" /**< Name of device. Will be included in the advertising data. */ +#define MANUFACTURER_NAME "NordicSemiconductor" /**< Manufacturer. Will be passed to Device Information Service. */ + +#define MIN_CONN_INTERVAL (uint16_t)(MSEC_TO_UNITS(15, UNIT_1_25_MS)) /**< Minimum acceptable connection interval. */ +#define MAX_CONN_INTERVAL_MS 30 /**< Maximum acceptable connection interval in milliseconds. */ +#define MAX_CONN_INTERVAL (uint16_t)(MSEC_TO_UNITS(MAX_CONN_INTERVAL_MS, UNIT_1_25_MS)) /**< Maximum acceptable connection interval . */ +#define SLAVE_LATENCY 0 /**< Slave latency. */ +#define CONN_SUP_TIMEOUT (4 * 100) /**< Connection supervisory timeout (4 seconds). */ + +#define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ + +#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(100, APP_TIMER_PRESCALER) /**< Time from the Connected event to first time sd_ble_gap_conn_param_update is called (100 milliseconds). */ +#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(500, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (500 milliseconds). */ +#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ + +#define MAX_ADV_DATA_LENGTH 20 /**< Maximum length of advertising data. */ + +#define APP_ADV_INTERVAL MSEC_TO_UNITS(25, UNIT_0_625_MS) /**< The advertising interval (25 ms.). */ +#define APP_ADV_TIMEOUT_IN_SECONDS BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED /**< The advertising timeout in units of seconds. This is set to @ref BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED so that the advertisement is done as long as there there is a call to @ref dfu_transport_close function.*/ + +#define APP_FEATURE_NOT_SUPPORTED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2 /**< Reply when unsupported features are requested. */ + +#define MAX_DFU_PKT_LEN (20) /**< Maximum length (in bytes) of the DFU Packet characteristic. */ +#define PKT_CREATE_PARAM_LEN (6) /**< Length (in bytes) of the parameters for Create Object request. */ +#define PKT_SET_PRN_PARAM_LEN (3) /**< Length (in bytes) of the parameters for Set Packet Receipt Notification request. */ +#define PKT_READ_OBJECT_INFO_PARAM_LEN (2) /**< Length (in bytes) of the parameters for Read Object Info request. */ +#define MAX_RESPONSE_LEN (15) /**< Maximum length (in bytes) of the response to a Control Point command. */ + + +#if (NRF_SD_BLE_API_VERSION == 3) +#define NRF_BLE_MAX_MTU_SIZE GATT_MTU_SIZE_DEFAULT /**< MTU size used in the softdevice enabling and to reply to a BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. */ +#endif + + +static ble_dfu_t m_dfu; /**< Structure used to identify the Device Firmware Update service. */ +static uint16_t m_pkt_notif_target; /**< Number of packets of firmware data to be received before transmitting the next Packet Receipt Notification to the DFU Controller. */ +static uint16_t m_pkt_notif_target_cnt; /**< Number of packets of firmware data received after sending last Packet Receipt Notification or since the receipt of a @ref BLE_DFU_PKT_RCPT_NOTIF_ENABLED event from the DFU service, which ever occurs later.*/ +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */ + +#define DFU_BLE_FLAG_NONE (0) +#define DFU_BLE_FLAG_SERVICE_INITIALIZED (1 << 0) /**< Flag to check if the DFU service was initialized by the application.*/ +#define DFU_BLE_FLAG_IS_ADVERTISING (1 << 1) /**< Flag to indicate if advertising is ongoing.*/ +#define DFU_BLE_FLAG_TEAR_DOWN_IN_PROGRESS (1 << 2) /**< Flag to indicate whether a tear down is in progress. A tear down could be because the application has initiated it or the peer has disconnected. */ + +static uint32_t m_flags; + +static uint8_t m_notif_buffer[MAX_RESPONSE_LEN]; /**< Buffer used for sending notifications to peer. */ + +//lint -save -e545 -esym(526, dfu_trans) -esym(528, dfu_trans) +DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const dfu_trans) = +{ + .init_func = ble_dfu_transport_init, + .close_func = ble_dfu_transport_close +}; +//lint -restore + + +/**@brief Function for handling a Connection Parameters error. + * + * @param[in] nrf_error Error code. + */ +static void conn_params_error_handler(uint32_t nrf_error) +{ + APP_ERROR_HANDLER(nrf_error); +} + + +/**@brief Function for initializing the Connection Parameters module. + */ +static uint32_t conn_params_init(void) +{ + ble_conn_params_init_t cp_init = {0}; + + cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; + cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; + cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; + cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; + cp_init.disconnect_on_fail = false; + cp_init.error_handler = conn_params_error_handler; + + return ble_conn_params_init(&cp_init); +} + + +/**@brief Function for the Advertising functionality initialization. + * + * @details Encodes the required advertising data and passes it to the stack. + * The advertising data encoded here is specific for DFU. + * Setting advertising data can by done by calling @ref ble_advdata_set. + */ +static uint32_t advertising_init(uint8_t adv_flags) +{ + uint32_t err_code; + uint16_t len_advdata = 9; + uint16_t max_device_name_length = MAX_ADV_DATA_LENGTH - len_advdata; + uint16_t actual_device_name_length = max_device_name_length; + + uint8_t p_encoded_advdata[MAX_ADV_DATA_LENGTH]; + + // Encode flags. + p_encoded_advdata[0] = 0x2; + p_encoded_advdata[1] = BLE_GAP_AD_TYPE_FLAGS; + p_encoded_advdata[2] = adv_flags; + + // Encode 'more available' uuid list. + p_encoded_advdata[3] = 0x3; + p_encoded_advdata[4] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE; + p_encoded_advdata[5] = LSB_16(BLE_DFU_SERVICE_UUID); + p_encoded_advdata[6] = MSB_16(BLE_DFU_SERVICE_UUID); + + // Get GAP device name and length + err_code = sd_ble_gap_device_name_get(&p_encoded_advdata[9], &actual_device_name_length); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Set GAP device in advertising data. + if (actual_device_name_length <= max_device_name_length) + { + p_encoded_advdata[7] = actual_device_name_length + 1; // (actual_length + ADV_AD_TYPE_FIELD_SIZE(1)) + p_encoded_advdata[8] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME; + len_advdata += actual_device_name_length; + } + else + { + // Must use a shorter advertising name than the actual name of the device + p_encoded_advdata[7] = max_device_name_length + 1; // (length + ADV_AD_TYPE_FIELD_SIZE(1)) + p_encoded_advdata[8] = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME; + len_advdata = MAX_ADV_DATA_LENGTH; + } + return sd_ble_gap_adv_data_set(p_encoded_advdata, len_advdata, NULL, 0); +} + + +/**@brief Function for starting advertising. + */ +static uint32_t advertising_start(void) +{ + uint32_t err_code; + ble_gap_adv_params_t adv_params; + + if ((m_flags & DFU_BLE_FLAG_IS_ADVERTISING) != 0) + { + return NRF_SUCCESS; + } + + // Initialize advertising parameters (used when starting advertising). + memset(&adv_params, 0, sizeof(adv_params)); + + err_code = advertising_init(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); + VERIFY_SUCCESS(err_code); + + adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; + adv_params.p_peer_addr = NULL; + adv_params.fp = BLE_GAP_ADV_FP_ANY; + adv_params.interval = APP_ADV_INTERVAL; + adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS; + + err_code = sd_ble_gap_adv_start(&adv_params); + VERIFY_SUCCESS(err_code); + + nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); + nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); + + m_flags |= DFU_BLE_FLAG_IS_ADVERTISING; + return NRF_SUCCESS; +} + + +/**@brief Function for stopping advertising. + */ +static uint32_t advertising_stop(void) +{ + uint32_t err_code; + + if ((m_flags & DFU_BLE_FLAG_IS_ADVERTISING) == 0) + { + return NRF_SUCCESS; + } + + err_code = sd_ble_gap_adv_stop(); + VERIFY_SUCCESS(err_code); + + nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); + + m_flags |= DFU_BLE_FLAG_IS_ADVERTISING; + return NRF_SUCCESS; +} + + +static bool is_cccd_configured(ble_dfu_t * p_dfu) +{ + uint8_t cccd_val_buf[BLE_CCCD_VALUE_LEN]; + ble_gatts_value_t gatts_value = {0}; + + gatts_value.len = BLE_CCCD_VALUE_LEN; + gatts_value.p_value = cccd_val_buf; + + // Check the CCCD Value of DFU Control Point. + uint32_t err_code = sd_ble_gatts_value_get(m_conn_handle, + p_dfu->dfu_ctrl_pt_handles.cccd_handle, + &gatts_value); + VERIFY_SUCCESS(err_code); + + return ble_srv_is_notification_enabled(cccd_val_buf); +} + + +static uint32_t send_hvx(uint16_t conn_handle, uint16_t value_handle, uint16_t len) +{ + ble_gatts_hvx_params_t hvx_params = {0}; + + hvx_params.handle = value_handle; + hvx_params.type = BLE_GATT_HVX_NOTIFICATION; + hvx_params.p_len = &len; + hvx_params.p_data = m_notif_buffer; + + return sd_ble_gatts_hvx(conn_handle, &hvx_params); +} + + +static uint32_t response_send(ble_dfu_t * p_dfu, + uint8_t op_code, + nrf_dfu_res_code_t resp_val) +{ + uint16_t index = 0; + + NRF_LOG_INFO("Sending Response: [0x%01x, 0x%01x]\r\n", op_code, resp_val); + +#ifndef NRF51 + if (p_dfu == NULL) + { + return NRF_ERROR_NULL; + } +#endif + + if ((m_conn_handle == BLE_CONN_HANDLE_INVALID) || (m_flags & DFU_BLE_FLAG_SERVICE_INITIALIZED) == 0) + { + return NRF_ERROR_INVALID_STATE; + } + + m_notif_buffer[index++] = BLE_DFU_OP_CODE_RESPONSE; + + // Encode the Request Op code + m_notif_buffer[index++] = op_code; + + // Encode the Response Value. + m_notif_buffer[index++] = (uint8_t)resp_val; + + return send_hvx(m_conn_handle, p_dfu->dfu_ctrl_pt_handles.value_handle, index); +} + + +static uint32_t response_crc_cmd_send(ble_dfu_t * p_dfu, + uint32_t offset, + uint32_t crc) +{ + uint16_t index = 0; + + NRF_LOG_INFO("Sending CRC: [0x60, 0x03, 0x01, 0:x%08x, CRC:0x%08x]\r\n", offset, crc); + +#ifndef NRF51 + if (p_dfu == NULL) + { + return NRF_ERROR_NULL; + } +#endif + + if ((m_conn_handle == BLE_CONN_HANDLE_INVALID) || (m_flags & DFU_BLE_FLAG_SERVICE_INITIALIZED) == 0) + { + return NRF_ERROR_INVALID_STATE; + } + + m_notif_buffer[index++] = BLE_DFU_OP_CODE_RESPONSE; + + // Encode the Request Op code + m_notif_buffer[index++] = BLE_DFU_OP_CODE_CALCULATE_CRC; + + // Encode the Response Value. + m_notif_buffer[index++] = (uint8_t)NRF_DFU_RES_CODE_SUCCESS; + + // Encode the Offset Value. + index += uint32_encode(offset, &m_notif_buffer[index]); + + // Encode the Crc Value. + index += uint32_encode(crc, &m_notif_buffer[index]); + + return send_hvx(m_conn_handle, p_dfu->dfu_ctrl_pt_handles.value_handle, index); +} + + +static uint32_t response_select_object_cmd_send(ble_dfu_t * p_dfu, + uint32_t max_size, + uint32_t offset, + uint32_t crc) +{ + uint16_t index = 0; + + NRF_LOG_INFO("Sending Object Info: [0x60, 0x06, 0x01 max: 0:x%08x 0:x%08x, CRC:0x%08x]\r\n", max_size, offset, crc); +#ifndef NRF51 + if (p_dfu == NULL) + { + return NRF_ERROR_NULL; + } +#endif + + if ((m_conn_handle == BLE_CONN_HANDLE_INVALID) || (m_flags & DFU_BLE_FLAG_SERVICE_INITIALIZED) == 0) + { + return NRF_ERROR_INVALID_STATE; + } + + m_notif_buffer[index++] = BLE_DFU_OP_CODE_RESPONSE; + + // Encode the Request Op code + m_notif_buffer[index++] = BLE_DFU_OP_CODE_SELECT_OBJECT; + + // Encode the Success Response Value. + m_notif_buffer[index++] = (uint8_t)NRF_DFU_RES_CODE_SUCCESS; + + // Encode the Max Size Value. + index += uint32_encode(max_size, &m_notif_buffer[index]); + + // Encode the Offset Value. + index += uint32_encode(offset, &m_notif_buffer[index]); + + // Encode the Crc Value. + index += uint32_encode(crc, &m_notif_buffer[index]); + + return send_hvx(m_conn_handle, p_dfu->dfu_ctrl_pt_handles.value_handle, index); +} + + +/**@brief Function for handling a Write event on the Control Point characteristic. + * + * @param[in] p_dfu DFU Service Structure. + * @param[in] p_ble_write_evt Pointer to the write event received from BLE stack. + * + * @return NRF_SUCCESS on successful processing of control point write. Otherwise an error code. + */ +static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t * p_ble_write_evt) +{ + nrf_dfu_res_code_t res_code; + nrf_dfu_req_t dfu_req; + nrf_dfu_res_t dfu_res = {{{0}}}; + + memset(&dfu_req, 0, sizeof(nrf_dfu_req_t)); + + switch (p_ble_write_evt->data[0]) + { + case BLE_DFU_OP_CODE_CREATE_OBJECT: + + if (p_ble_write_evt->len != PKT_CREATE_PARAM_LEN) + { + return response_send(p_dfu, + BLE_DFU_OP_CODE_CREATE_OBJECT, + NRF_DFU_RES_CODE_INVALID_PARAMETER); + } + + NRF_LOG_INFO("Received create object\r\n"); + + // Reset the packet receipt notification on create object + m_pkt_notif_target_cnt = m_pkt_notif_target; + + // Get type parameter + //lint -save -e415 + dfu_req.obj_type = p_ble_write_evt->data[1]; + //lint -restore + + // Get length value + //lint -save -e416 + dfu_req.object_size = uint32_decode(&(p_ble_write_evt->data[2])); + //lint -restore + + // Set req type + dfu_req.req_type = NRF_DFU_OBJECT_OP_CREATE; + + res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + return response_send(p_dfu, BLE_DFU_OP_CODE_CREATE_OBJECT, res_code); + + case BLE_DFU_OP_CODE_EXECUTE_OBJECT: + NRF_LOG_INFO("Received execute object\r\n"); + + // Set req type + dfu_req.req_type = NRF_DFU_OBJECT_OP_EXECUTE; + + res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + return response_send(p_dfu, BLE_DFU_OP_CODE_EXECUTE_OBJECT, res_code); + + case BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF: + NRF_LOG_INFO("Set receipt notif\r\n"); + if (p_ble_write_evt->len != PKT_SET_PRN_PARAM_LEN) + { + return (response_send(p_dfu, + BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF, + NRF_DFU_RES_CODE_INVALID_PARAMETER)); + } + + //lint -save -e415 + m_pkt_notif_target = uint16_decode(&(p_ble_write_evt->data[1])); + //lint -restore + m_pkt_notif_target_cnt = m_pkt_notif_target; + + return response_send(p_dfu, BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF, NRF_DFU_RES_CODE_SUCCESS); + + case BLE_DFU_OP_CODE_CALCULATE_CRC: + NRF_LOG_INFO("Received calculate CRC\r\n"); + + dfu_req.req_type = NRF_DFU_OBJECT_OP_CRC; + + res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + if (res_code == NRF_DFU_RES_CODE_SUCCESS) + { + return response_crc_cmd_send(p_dfu, dfu_res.offset, dfu_res.crc); + } + else + { + return response_send(p_dfu, BLE_DFU_OP_CODE_CALCULATE_CRC, res_code); + } + + case BLE_DFU_OP_CODE_SELECT_OBJECT: + + NRF_LOG_INFO("Received select object\r\n"); + if (p_ble_write_evt->len != PKT_READ_OBJECT_INFO_PARAM_LEN) + { + return response_send(p_dfu, + BLE_DFU_OP_CODE_SELECT_OBJECT, + NRF_DFU_RES_CODE_INVALID_PARAMETER); + } + + // Set object type to read info about + //lint -save -e415 + dfu_req.obj_type = p_ble_write_evt->data[1]; + //lint -restore + + dfu_req.req_type = NRF_DFU_OBJECT_OP_SELECT; + + res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + if (res_code == NRF_DFU_RES_CODE_SUCCESS) + { + return response_select_object_cmd_send(p_dfu, dfu_res.max_size, dfu_res.offset, dfu_res.crc); + } + else + { + return response_send(p_dfu, BLE_DFU_OP_CODE_SELECT_OBJECT, res_code); + } + + default: + NRF_LOG_INFO("Received unsupported OP code\r\n"); + // Unsupported op code. + return response_send(p_dfu, + p_ble_write_evt->data[0], + NRF_DFU_RES_CODE_INVALID_PARAMETER); + } +} + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the + * SoftDevice. + * + * @param[in] p_dfu DFU Service Structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static bool on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + ble_gatts_rw_authorize_reply_params_t auth_reply = {0}; + ble_gatts_evt_rw_authorize_request_t * p_authorize_request; + ble_gatts_evt_write_t * p_ble_write_evt; + + p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request); + p_ble_write_evt = &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write); + + if ((p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && + (p_authorize_request->request.write.handle == p_dfu->dfu_ctrl_pt_handles.value_handle) && + (p_authorize_request->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) && + (p_authorize_request->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) && + (p_authorize_request->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL) ) + { + auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + auth_reply.params.write.update = 1; + auth_reply.params.write.offset = p_ble_write_evt->offset; + auth_reply.params.write.len = p_ble_write_evt->len; + auth_reply.params.write.p_data = p_ble_write_evt->data; + + if (!is_cccd_configured(p_dfu)) + { + // Send an error response to the peer indicating that the CCCD is improperly configured. + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR; + + // Ignore response of auth reply + (void)sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply); + return false; + } + + auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + err_code = sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply); + return err_code == NRF_SUCCESS ? true: false; + } + else + { + return false; + } +} + + +/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the SoftDevice. + * + * @param[in] p_dfu DFU Service Structure. + * @param[in] p_ble_evt Pointer to the event received from BLE stack. + */ +static void on_write(ble_dfu_t * p_dfu, ble_evt_t * p_ble_evt) +{ + if (p_ble_evt->evt.gatts_evt.params.write.handle == p_dfu->dfu_pkt_handles.value_handle) + { + nrf_dfu_res_code_t res_code; + nrf_dfu_req_t dfu_req; + nrf_dfu_res_t dfu_res = {{{0}}}; + + memset(&dfu_req, 0, sizeof(nrf_dfu_req_t)); + + // Set req type + dfu_req.req_type = NRF_DFU_OBJECT_OP_WRITE; + + // Set data and length + dfu_req.p_req = p_ble_evt->evt.gatts_evt.params.write.data; + dfu_req.req_len = p_ble_evt->evt.gatts_evt.params.write.len; + + res_code = nrf_dfu_req_handler_on_req(NULL, &dfu_req, &dfu_res); + if(res_code != NRF_DFU_RES_CODE_SUCCESS) + { + NRF_LOG_INFO("Failure to run packet write\r\n"); + } + + // Check if a packet receipt notification is needed to be sent. + if (m_pkt_notif_target != 0 && --m_pkt_notif_target_cnt == 0) + { + (void)response_crc_cmd_send(p_dfu, dfu_res.offset, dfu_res.crc); + + // Reset the counter for the number of firmware packets. + m_pkt_notif_target_cnt = m_pkt_notif_target; + } + } +} + + +/**@brief Function for the Application's SoftDevice event handler. + * + * @param[in] p_ble_evt SoftDevice event. + */ +static void on_ble_evt(ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); + nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); + + m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; + m_flags &= ~DFU_BLE_FLAG_IS_ADVERTISING; + break; + + case BLE_GAP_EVT_DISCONNECTED: + // Restart advertising so that the DFU Controller can reconnect if possible. + err_code = advertising_start(); + APP_ERROR_CHECK(err_code); + + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + break; + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + { + err_code = sd_ble_gap_sec_params_reply(m_conn_handle, + BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, + NULL, + NULL); + APP_ERROR_CHECK(err_code); + } + break; + + case BLE_GATTS_EVT_TIMEOUT: + if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL) + { + err_code = sd_ble_gap_disconnect(m_conn_handle, + BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + APP_ERROR_CHECK(err_code); + } + break; + + case BLE_EVT_USER_MEM_REQUEST: + err_code = sd_ble_user_mem_reply(m_conn_handle, NULL); + APP_ERROR_CHECK(err_code); + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + if (p_ble_evt->evt.gatts_evt.params.authorize_request.type + != BLE_GATTS_AUTHORIZE_TYPE_INVALID) + { + if (on_rw_authorize_req(&m_dfu, p_ble_evt)) + { + err_code = on_ctrl_pt_write(&m_dfu, + &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write)); +#ifdef NRF_DFU_DEBUG_VERSION + if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("Could not handle on_ctrl_pt_write. err_code: 0x%04x\r\n", err_code); + } +#else + // Swallow result + (void) err_code; +#endif + } + } + break; + + case BLE_GAP_EVT_SEC_INFO_REQUEST: + err_code = sd_ble_gap_sec_info_reply(p_ble_evt->evt.gap_evt.conn_handle, NULL, NULL, NULL); + APP_ERROR_CHECK(err_code); + break; + + case BLE_GATTS_EVT_SYS_ATTR_MISSING: + err_code = sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gap_evt.conn_handle, NULL, 0, 0); + APP_ERROR_CHECK(err_code); + break; + + case BLE_GATTS_EVT_WRITE: + on_write(&m_dfu, p_ble_evt); + break; + +#if (NRF_SD_BLE_API_VERSION == 3) + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + err_code = sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle, + NRF_BLE_MAX_MTU_SIZE); + APP_ERROR_CHECK(err_code); + break; // BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST +#endif + + default: + // No implementation needed. + break; + } +} + + +/**@brief Function for dispatching a SoftDevice event. + * + * @details This function is called from the SoftDevice event interrupt handler after a + * SoftDevice event has been received. + * + * @param[in] p_ble_evt SoftDevice event. + */ +static void ble_evt_dispatch(ble_evt_t * p_ble_evt) +{ + ble_conn_params_on_ble_evt(p_ble_evt); + on_ble_evt(p_ble_evt); +} + + +/**@brief Function for the LEDs initialization. + * + * @details Initializes all LEDs used by this application. + */ +static void leds_init(void) +{ + nrf_gpio_cfg_output(ADVERTISING_LED_PIN_NO); + nrf_gpio_cfg_output(CONNECTED_LED_PIN_NO); + nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); + nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); +} + + +static uint32_t gap_address_change(void) +{ + uint32_t err_code; + ble_gap_addr_t addr; + +#ifdef NRF51 + err_code = sd_ble_gap_address_get(&addr); +#elif NRF52 + err_code = sd_ble_gap_addr_get(&addr); +#else + +#endif + + VERIFY_SUCCESS(err_code); + + // Increase the BLE address by one when advertising openly. + addr.addr[0] += 1; + +#ifdef NRF51 + err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr); +#elif NRF52 + err_code = sd_ble_gap_addr_set(&addr); +#else + +#endif + + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + + +/**@brief Function for the GAP initialization. + * + * @details This function will setup all the necessary GAP (Generic Access Profile) parameters of + * the device. It also sets the permissions and appearance. + */ +static uint32_t gap_params_init(void) +{ + uint32_t err_code; + ble_gap_conn_params_t gap_conn_params = {0}; + ble_gap_conn_sec_mode_t sec_mode; + + + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); + + err_code = gap_address_change(); + VERIFY_SUCCESS(err_code); + + err_code = sd_ble_gap_device_name_set(&sec_mode, + (const uint8_t *)DEVICE_NAME, + strlen(DEVICE_NAME)); + VERIFY_SUCCESS(err_code); + + gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; + gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; + gap_conn_params.slave_latency = SLAVE_LATENCY; + gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; + + err_code = sd_ble_gap_ppcp_set(&gap_conn_params); + return err_code; +} + + +static uint32_t ble_stack_init(bool init_softdevice) +{ + uint32_t err_code; + nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC; + + if (init_softdevice) + { + err_code = nrf_dfu_mbr_init_sd(); + VERIFY_SUCCESS(err_code); + } + + NRF_LOG_INFO("vector table: 0x%08x\r\n", BOOTLOADER_START_ADDR); + err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_START_ADDR); + VERIFY_SUCCESS(err_code); + + SOFTDEVICE_HANDLER_APPSH_INIT(&clock_lf_cfg, true); + + ble_enable_params_t ble_enable_params; + // Only one connection as a central is used when performing dfu. + err_code = softdevice_enable_get_default_config(1, 1, &ble_enable_params); + VERIFY_SUCCESS(err_code); + +#if (NRF_SD_BLE_API_VERSION == 3) + ble_enable_params.gatt_enable_params.att_mtu = NRF_BLE_MAX_MTU_SIZE; +#endif + + // Enable BLE stack. + err_code = softdevice_enable(&ble_enable_params); + return err_code; +} + + +/**@brief Function for adding DFU Packet characteristic to the BLE Stack. + * + * @param[in] p_dfu DFU Service structure. + * + * @return NRF_SUCCESS on success. Otherwise an error code. + */ +static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu) +{ + ble_gatts_char_md_t char_md = {{0}}; + ble_gatts_attr_t attr_char_value = {0}; + ble_gatts_attr_md_t attr_md = {{0}}; + ble_uuid_t char_uuid; + + char_md.char_props.write_wo_resp = 1; + + char_uuid.type = p_dfu->uuid_type; + char_uuid.uuid = BLE_DFU_PKT_CHAR_UUID; + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.vlen = 1; + + attr_char_value.p_uuid = &char_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.max_len = MAX_DFU_PKT_LEN; + attr_char_value.p_value = NULL; + + return sd_ble_gatts_characteristic_add(p_dfu->service_handle, + &char_md, + &attr_char_value, + &p_dfu->dfu_pkt_handles); +} + + +/**@brief Function for adding DFU Control Point characteristic to the BLE Stack. + * + * @param[in] p_dfu DFU Service structure. + * + * @return NRF_SUCCESS on success. Otherwise an error code. + */ +static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu) +{ + ble_gatts_char_md_t char_md = {{0}}; + ble_gatts_attr_t attr_char_value = {0}; + ble_gatts_attr_md_t attr_md = {{0}}; + ble_uuid_t char_uuid; + + char_md.char_props.write = 1; + char_md.char_props.notify = 1; + + char_uuid.type = p_dfu->uuid_type; + char_uuid.uuid = BLE_DFU_CTRL_PT_UUID; + + BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm); + BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm); + + attr_md.vloc = BLE_GATTS_VLOC_STACK; + attr_md.wr_auth = 1; + attr_md.vlen = 1; + + attr_char_value.p_uuid = &char_uuid; + attr_char_value.p_attr_md = &attr_md; + attr_char_value.max_len = BLE_L2CAP_MTU_DEF; + attr_char_value.p_value = NULL; + + return sd_ble_gatts_characteristic_add(p_dfu->service_handle, + &char_md, + &attr_char_value, + &p_dfu->dfu_ctrl_pt_handles); +} + + +/**@brief Function for checking if the CCCD of DFU Control point is configured for Notification. + * + * @details This function checks if the CCCD of DFU Control Point characteristic is configured + * for Notification by the DFU Controller. + * + * @param[in] p_dfu DFU Service structure. + * + * @return True if the CCCD of DFU Control Point characteristic is configured for Notification. + * False otherwise. + */ +uint32_t ble_dfu_init(ble_dfu_t * p_dfu) +{ + ble_uuid_t service_uuid; + uint32_t err_code; + +#ifndef NRF51 + if (p_dfu == NULL) + { + return NRF_ERROR_NULL; + } +#endif + + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID); + + err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, + &service_uuid, + &(p_dfu->service_handle)); + VERIFY_SUCCESS(err_code); + + const ble_uuid128_t base_uuid128 = + { + { + 0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F, + 0x60, 0x4F, 0x15, 0xF3, 0x00, 0x00, 0xC9, 0x8E + } + }; + err_code = sd_ble_uuid_vs_add(&base_uuid128, &p_dfu->uuid_type); + VERIFY_SUCCESS(err_code); + + err_code = dfu_pkt_char_add(p_dfu); + VERIFY_SUCCESS(err_code); + + err_code = dfu_ctrl_pt_add(p_dfu); + VERIFY_SUCCESS(err_code); + + m_flags |= DFU_BLE_FLAG_SERVICE_INITIALIZED; + + return NRF_SUCCESS; +} + + +uint32_t ble_dfu_transport_init(void) +{ + uint32_t err_code; + + m_flags &= ~DFU_BLE_FLAG_NONE; + + leds_init(); + + err_code = ble_stack_init(true); + VERIFY_SUCCESS(err_code); + + err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch); + VERIFY_SUCCESS(err_code); + + err_code = gap_params_init(); + VERIFY_SUCCESS(err_code); + + // Initialize the Device Firmware Update Service. + err_code = ble_dfu_init(&m_dfu); + VERIFY_SUCCESS(err_code); + + err_code = conn_params_init(); + VERIFY_SUCCESS(err_code); + + err_code = advertising_start(); + VERIFY_SUCCESS(err_code); + + return NRF_SUCCESS; +} + + +uint32_t ble_dfu_transport_close(void) +{ + uint32_t err_code = NRF_SUCCESS; + + if ((m_flags & DFU_BLE_FLAG_TEAR_DOWN_IN_PROGRESS) != 0) + { + return NRF_SUCCESS; + } + + m_flags |= DFU_BLE_FLAG_TEAR_DOWN_IN_PROGRESS; + + NRF_LOG_INFO("Waiting for buffers to be cleared before disconnect\r\n"); + nrf_delay_ms(MAX_CONN_INTERVAL_MS*4); + NRF_LOG_INFO("Disconnecting\r\n"); + + if (m_conn_handle != BLE_CONN_HANDLE_INVALID) + { + // Disconnect from peer. + err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + VERIFY_SUCCESS(err_code); + } + else if ((m_flags & DFU_BLE_FLAG_IS_ADVERTISING) != 0) + { + // If not connected, then the device will be advertising. Hence stop the advertising. + err_code = advertising_stop(); + VERIFY_SUCCESS(err_code); + } + + // Stop the timer, disregard the result. + (void)ble_conn_params_stop(); + return err_code; +} diff --git a/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.h b/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.h new file mode 100644 index 0000000..a6a4c8a --- /dev/null +++ b/components/libraries/bootloader/ble_dfu/nrf_ble_dfu.h @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup nrf_ble_dfu DFU BLE Service + * @{ + * @ingroup sdk_nrf_bootloader + * @brief Device Firmware Update (DFU) transport layer for Bluetooth low energy. + * + * @details The Device Firmware Update (DFU) Service is a GATT-based service that can be used for + * performing firmware updates over BLE. Note that this implementation uses + * vendor-specific UUIDs for the service and characteristics and is intended to demonstrate + * firmware updates over BLE. See @ref lib_dfu_transport_ble "DFU Transport: BLE" for more information on the service and the profile. + */ + +#ifndef NRF_BLE_DFU_H__ +#define NRF_BLE_DFU_H__ + +#include +#include "ble_gatts.h" +#include "ble.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +// This is a 16-bit UUID. +#define BLE_DFU_SERVICE_UUID 0xFE59 //!< The UUID of the DFU Service. + +// These UUIDs are used with the Nordic base address to create a 128-bit UUID (0x8EC9XXXXF3154F609FB8838830DAEA50). +#define BLE_DFU_CTRL_PT_UUID 0x0001 //!< The UUID of the DFU Control Point. +#define BLE_DFU_PKT_CHAR_UUID 0x0002 //!< The UUID of the DFU Packet Characteristic. + + +/**@brief BLE DFU opcodes. + * + * @details These types of opcodes are used in control point access. + */ +typedef enum +{ + BLE_DFU_OP_CODE_CREATE_OBJECT = 0x01, /**< Value of the opcode field for a 'Create object' request. */ + BLE_DFU_OP_CODE_SET_RECEIPT_NOTIF = 0x02, /**< Value of the opcode field for a 'Set Packet Receipt Notification' request. */ + BLE_DFU_OP_CODE_CALCULATE_CRC = 0x03, /**< Value of the opcode field for a 'Calculating checksum' request. */ + BLE_DFU_OP_CODE_EXECUTE_OBJECT = 0x04, /**< Value of the opcode field for an 'Initialize DFU parameters' request. */ + BLE_DFU_OP_CODE_SELECT_OBJECT = 0x06, /**< Value of the opcode field for a 'Select object' request. */ + BLE_DFU_OP_CODE_RESPONSE = 0x60 /**< Value of the opcode field for a response.*/ +} ble_dfu_op_code_t; + + +/**@brief DFU Service. + * + * @details This structure contains status information related to the service. + */ +typedef struct +{ + uint16_t service_handle; /**< Handle of the DFU Service (as provided by the SoftDevice). */ + uint8_t uuid_type; /**< UUID type assigned to the DFU Service by the SoftDevice. */ + ble_gatts_char_handles_t dfu_pkt_handles; /**< Handles related to the DFU Packet Characteristic. */ + ble_gatts_char_handles_t dfu_ctrl_pt_handles; /**< Handles related to the DFU Control Point Characteristic. */ +} ble_dfu_t; + + +/**@brief Function for initializing the DFU Service. + * + * @retval NRF_SUCCESS If the DFU Service and its characteristics were successfully added to the + * SoftDevice. Otherwise, an error code is returned. + */ +uint32_t ble_dfu_transport_init(void); + + +/**@brief Function for closing down the DFU Service and disconnecting from the host. + * + * @retval NRF_SUCCESS If the DFU Service was correctly closed down. + */ +uint32_t ble_dfu_transport_close(void); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BLE_DFU_H__ + +/** @} */ diff --git a/components/libraries/bootloader/dfu/nrf_dfu.c b/components/libraries/bootloader/dfu/nrf_dfu.c new file mode 100644 index 0000000..1de9ebc --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu.c @@ -0,0 +1,177 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_dfu.h" +#include "nrf_dfu_transport.h" +#include "nrf_dfu_utils.h" +#include "nrf_bootloader_app_start.h" +#include "nrf_dfu_settings.h" +#include "nrf_gpio.h" +#include "app_scheduler.h" +#include "app_timer_appsh.h" +#include "nrf_log.h" +#include "boards.h" +#include "nrf_bootloader_info.h" +#include "nrf_dfu_req_handler.h" + +#define SCHED_MAX_EVENT_DATA_SIZE MAX(APP_TIMER_SCHED_EVT_SIZE, 0) /**< Maximum size of scheduler events. */ + +#define SCHED_QUEUE_SIZE 20 /**< Maximum number of events in the scheduler queue. */ + +#define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ +#define APP_TIMER_OP_QUEUE_SIZE 4 /**< Size of timer operation queues. */ + +// Weak function implementation + +/** @brief Weak implemenation of nrf_dfu_check_enter. + * + * @note This function must be overridden to enable entering DFU mode at will. + * Default behaviour is to enter DFU when BOOTLOADER_BUTTON is pressed. + */ +__WEAK bool nrf_dfu_enter_check(void) +{ + if (nrf_gpio_pin_read(BOOTLOADER_BUTTON) == 0) + { + return true; + } + + if (s_dfu_settings.enter_buttonless_dfu == 1) + { + s_dfu_settings.enter_buttonless_dfu = 0; + APP_ERROR_CHECK(nrf_dfu_settings_write(NULL)); + return true; + } + return false; +} + + +// Internal Functions + +/**@brief Function for initializing the timer handler module (app_timer). + */ +static void timers_init(void) +{ + // Initialize timer module, making it use the scheduler. + APP_TIMER_APPSH_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, true); +} + + +/** @brief Function for event scheduler initialization. + */ +static void scheduler_init(void) +{ + APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE); +} + + +static void wait_for_event() +{ + // Transport is waiting for event? + while(true) + { + // Can't be emptied like this because of lack of static variables + app_sched_execute(); + } +} + + +void nrf_dfu_wait() +{ + app_sched_execute(); +} + + +uint32_t nrf_dfu_init() +{ + uint32_t ret_val = NRF_SUCCESS; + uint32_t enter_bootloader_mode = 0; + + NRF_LOG_INFO("In real nrf_dfu_init\r\n"); + + nrf_dfu_settings_init(); + + // Continue ongoing DFU operations + // Note that this part does not rely on SoftDevice interaction + ret_val = nrf_dfu_continue(&enter_bootloader_mode); + if(ret_val != NRF_SUCCESS) + { + NRF_LOG_INFO("Could not continue DFU operation: 0x%08x\r\n"); + enter_bootloader_mode = 1; + } + + // Check if there is a reason to enter DFU mode + // besides the effect of the continuation + if (nrf_dfu_enter_check()) + { + NRF_LOG_INFO("Application sent bootloader request\n"); + enter_bootloader_mode = 1; + } + + if(enter_bootloader_mode != 0 || !nrf_dfu_app_is_valid()) + { + timers_init(); + scheduler_init(); + + // Initializing transports + ret_val = nrf_dfu_transports_init(); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_INFO("Could not initalize DFU transport: 0x%08x\r\n"); + return ret_val; + } + + (void)nrf_dfu_req_handler_init(); + + // This function will never return + NRF_LOG_INFO("Waiting for events\r\n"); + wait_for_event(); + NRF_LOG_INFO("After waiting for events\r\n"); + } + + if (nrf_dfu_app_is_valid()) + { + NRF_LOG_INFO("Jumping to: 0x%08x\r\n", MAIN_APPLICATION_START_ADDR); + nrf_bootloader_app_start(MAIN_APPLICATION_START_ADDR); + } + + // Should not be reached! + NRF_LOG_INFO("After real nrf_dfu_init\r\n"); + return NRF_SUCCESS; +} diff --git a/components/libraries/bootloader/dfu/nrf_dfu.h b/components/libraries/bootloader/dfu/nrf_dfu.h new file mode 100644 index 0000000..e7f934f --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu.h @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup sdk_nrf_dfu DFU bootloader + * @{ + * @ingroup sdk_nrf_bootloader + * @brief Bootloader with Device Firmware Update (DFU) functionality. + * + * The DFU bootloader module, in combination with the @ref sdk_bootloader module, + * can be used to implement a bootloader that supports Device Firmware Updates. + */ + + +#ifndef NRF_DFU_H__ +#define NRF_DFU_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BOOTLOADER_BUTTON (BSP_BUTTON_3) /**< Button for entering DFU mode. */ + +/** @brief Function for initializing a DFU operation. + * + * This function initializes a DFU operation and any transports that are registered + * in the system. + * + * @retval NRF_SUCCESS If the DFU operation was successfully initialized. + */ +uint32_t nrf_dfu_init(void); + + +/** @brief Function for checking if DFU mode should be entered. + * + * This function checks whether DFU mode is required. + * + * @retval true If DFU mode must be entered. + * @retval false If there is no need to enter DFU mode. + */ +bool nrf_dfu_enter_check(void); + + +/** @brief Function for checking if DFU should be reset (failsafe). + * + * This function will check if DFU should be reset (failsafe). + * + * If this returns true, DFU mode will be entered and DFU will be reset. + * + * @retval true If DFU must be reset (failsafe). + * @retval false If there is no need to reset DFU. + */ +bool nrf_dfu_check_failsafe_reset(void); + + +/** @brief Function for blocking until an event (i.e. incoming BLE packet) arrives. + */ +void nrf_dfu_wait(void); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_H__ + +/** @} */ diff --git a/components/libraries/bootloader/dfu/nrf_dfu_flash.c b/components/libraries/bootloader/dfu/nrf_dfu_flash.c new file mode 100644 index 0000000..e10cc6f --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_flash.c @@ -0,0 +1,317 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_dfu_flash.h" +#include "nrf_dfu_types.h" +#include "softdevice_handler.h" +#include "nrf_nvmc.h" +#include "nrf_log.h" + +#ifdef SOFTDEVICE_PRESENT +// Only include fstorage if SD interaction is required +#include "fstorage.h" +#endif + +#define FLASH_FLAG_NONE (0) +#define FLASH_FLAG_OPER (1<<0) +#define FLASH_FLAG_FAILURE_SINCE_LAST (1<<1) +#define FLASH_FLAG_SD_ENABLED (1<<2) + +static uint32_t m_flags; + +#ifdef BLE_STACK_SUPPORT_REQD + +// Function prototypes +static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result); + +FS_REGISTER_CFG(fs_config_t fs_dfu_config) = +{ + .callback = fs_evt_handler, // Function for event callbacks. + .p_start_addr = (uint32_t*)MBR_SIZE, + .p_end_addr = (uint32_t*)BOOTLOADER_SETTINGS_ADDRESS + CODE_PAGE_SIZE +}; + + +static void fs_evt_handler(fs_evt_t const * const evt, fs_ret_t result) +{ + // Clear the operation flag + m_flags &= ~FLASH_FLAG_OPER; + + if (result == FS_SUCCESS) + { + // Clear flag for ongoing operation and failure since last + m_flags &= ~FLASH_FLAG_FAILURE_SINCE_LAST; + } + else + { + NRF_LOG_INFO("Generating failure\r\n"); + m_flags |= FLASH_FLAG_FAILURE_SINCE_LAST; + } + + if (evt->p_context) + { + //lint -e611 + ((dfu_flash_callback_t)evt->p_context)(evt, result); + } +} + +#endif + + +uint32_t nrf_dfu_flash_init(bool sd_enabled) +{ + uint32_t err_code = NRF_SUCCESS; + +#ifdef BLE_STACK_SUPPORT_REQD + // Only run this initialization if SD is enabled + if(sd_enabled) + { + NRF_LOG_INFO("------- nrf_dfu_flash_init-------\r\n"); + if (fs_fake_init() != FS_SUCCESS) + { + NRF_LOG_INFO("Not initializing the thing\r\n"); + return NRF_ERROR_INVALID_STATE; + } + + // Enable access to the whole range + + + err_code = softdevice_sys_evt_handler_set(fs_sys_event_handler); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_INFO("Not initializing the thing 2\r\n"); + return NRF_ERROR_INVALID_STATE; + } + + // Setting flag to indicate that SD is enabled to ensure fstorage is use in calls + // to do flash operations. + m_flags = FLASH_FLAG_SD_ENABLED; + } + else +#endif + { + m_flags = FLASH_FLAG_NONE; + } + + return err_code; +} + + +fs_ret_t nrf_dfu_flash_store(uint32_t const * p_dest, uint32_t const * const p_src, uint32_t len_words, dfu_flash_callback_t callback) +{ + fs_ret_t ret_val = FS_SUCCESS; + +#ifdef BLE_STACK_SUPPORT_REQD + if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0) + { + // Check if there is a pending error + if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0) + { + NRF_LOG_INFO("Flash: Failure since last\r\n"); + return FS_ERR_FAILURE_SINCE_LAST; + } + + // Set the flag to indicate ongoing operation + m_flags |= FLASH_FLAG_OPER; + //lint -e611 + ret_val = fs_store(&fs_dfu_config, p_dest, p_src, len_words, (void*)callback); + + if (ret_val != FS_SUCCESS) + { + NRF_LOG_INFO("Flash: failed %d\r\n", ret_val); + return ret_val; + } + + // Set the flag to indicate ongoing operation + m_flags |= FLASH_FLAG_OPER; + } + else +#endif + { + +#ifndef NRF51 + if ((p_src == NULL) || (p_dest == NULL)) + { + return FS_ERR_NULL_ARG; + } + + // Check that both pointers are word aligned. + if (((uint32_t)p_src & 0x03) || + ((uint32_t)p_dest & 0x03)) + { + return FS_ERR_UNALIGNED_ADDR; + } + + if (len_words == 0) + { + NRF_LOG_INFO("Flash: Invallid length (NVMC)\r\n"); + return FS_ERR_INVALID_ARG; + } +#endif + + nrf_nvmc_write_words((uint32_t)p_dest, p_src, len_words); + + #if (__LINT__ != 1) + if (callback) + { + fs_evt_t evt = + { + .id = FS_EVT_STORE, + .p_context = (void*)callback, + .store = + { + .length_words = len_words, + .p_data = p_dest + } + }; + callback(&evt, FS_SUCCESS); + } + #endif + } + + return ret_val; +} + + +/** @brief Internal function to initialize DFU BLE transport + */ +fs_ret_t nrf_dfu_flash_erase(uint32_t const * p_dest, uint32_t num_pages, dfu_flash_callback_t callback) +{ + fs_ret_t ret_val = FS_SUCCESS; + NRF_LOG_INFO("Erasing: 0x%08x, num: %d\r\n", (uint32_t)p_dest, num_pages); + +#ifdef BLE_STACK_SUPPORT_REQD + + if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0) + { + // Check if there is a pending error + if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0) + { + NRF_LOG_INFO("Erase: Failure since last\r\n"); + return FS_ERR_FAILURE_SINCE_LAST; + } + + m_flags |= FLASH_FLAG_OPER; + ret_val = fs_erase(&fs_dfu_config, p_dest, num_pages, (void*)callback); + + if (ret_val != FS_SUCCESS) + { + NRF_LOG_INFO("Erase failed: %d\r\n", ret_val); + m_flags &= ~FLASH_FLAG_OPER; + return ret_val; + } + + // Set the flag to indicate ongoing operation + m_flags |= FLASH_FLAG_OPER; + } + else +#endif + { +#ifndef NRF51 + // Softdevice is not present or activated. Run the NVMC instead + if (((uint32_t)p_dest & (CODE_PAGE_SIZE-1)) != 0) + { + NRF_LOG_INFO("Invalid address\r\n"); + return FS_ERR_UNALIGNED_ADDR; + } +#endif + + uint16_t first_page = ((uint32_t)p_dest / CODE_PAGE_SIZE); + do + { + nrf_nvmc_page_erase((uint32_t)p_dest); + p_dest += CODE_PAGE_SIZE/sizeof(uint32_t); + } + while(--num_pages > 0); + + + if (callback) + { + #if (__LINT__ != 1) + fs_evt_t evt = + { + .id = FS_EVT_ERASE, + .p_context = (void*)callback, + .erase = + { + .first_page = first_page, + .last_page = ((uint32_t)p_dest / CODE_PAGE_SIZE) + } + }; + callback(&evt, FS_SUCCESS); + #else + (void)first_page; + #endif + } + } + + return ret_val; +} + + +void nrf_dfu_flash_error_clear(void) +{ + m_flags &= ~FLASH_FLAG_FAILURE_SINCE_LAST; +} + + +fs_ret_t nrf_dfu_flash_wait(void) +{ + NRF_LOG_INFO("Waiting for finished...\r\n"); + +#ifdef BLE_STACK_SUPPORT_REQD + if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0) + { + while ((m_flags & FLASH_FLAG_OPER) != 0) + { + (void)sd_app_evt_wait(); + } + + if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0) + { + NRF_LOG_INFO("Failure since last\r\n"); + return FS_ERR_FAILURE_SINCE_LAST; + } + } +#endif + + NRF_LOG_INFO("After wait!\r\n"); + return FS_SUCCESS; +} diff --git a/components/libraries/bootloader/dfu/nrf_dfu_flash.h b/components/libraries/bootloader/dfu/nrf_dfu_flash.h new file mode 100644 index 0000000..19c1c4a --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_flash.h @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup sdk_nrf_dfu_flash Flash operations + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_FLASH_H__ +#define NRF_DFU_FLASH_H__ + +#include +#include +#include "fstorage.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief fstorage event handler function for DFU fstorage operations. + * + * This function is intended to be registered to the fstorage module as the event handler for all DFU flash operations. + * When each flash operation has completed or failed this function will be called. + * + * See ::fs_cb_t for implementation details. + */ +typedef fs_cb_t dfu_flash_callback_t; + +/**@brief Function for initializing the flash module. + * + * You can use this module with or without a SoftDevice: + * - If the module is initialized with the SoftDevice enabled flag set, the @ref fstorage + * module is used as back end for all flash operations. Flash storage calls + * are asynchronous; the SoftDevice manages when the actual operation in + * flash is done. + * - If the module is initialized with the SoftDevice enabled flag not set, + * the non-volatile memory controller (NVMC) driver handles the flash operations + * by directly accessing flash. These operations are synchronous. + * + * @param[in] sd_enabled Set the flash handling to run with or without the SoftDevice enabled. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_STATE If the fstorage module could not be initiated or the SoftDevice could not set the event handler. + */ +uint32_t nrf_dfu_flash_init(bool sd_enabled); + + +/**@brief Function for storing data to flash (with or without the SoftDevice enabled). + * + * @warning The content to be stored must be kept at @p p_src until the operation is + * complete. Without SoftDevice, the operation is complete when the function + * returns. With SoftDevice, the operation is complete when the fstorage event is received. + * + * @param[in] p_dest Pointer to the address where the data should be stored. + * @param[in] p_src Pointer to the address where the data should be copied from. + * This address can be in flash or RAM. + * @param[in] len_words The number of words to be copied from @p p_src to @p p_dest. + * @param[in] callback Pointer to the callback function. + * + * @retval FS_SUCCESS If the operation was successful. + * @retval FS_ERR_FAILURE_SINCE_LAST If an error occurred in another transaction and fstorage cannot continue before + * the event has been dealt with. + * @retval FS_ERR_UNALIGNED_ADDR If @p p_src or @p p_dest is not word-aligned. Ensure that the address pointed to is divisible by four. + * @retval FS_ERR_INVALID_ARG If @p len_words is zero. It is not possible to write zero words. + * @retval FS_ERR_NULL_ARG If @p p_src or @p p_dest is NULL. + * + * @retval FS_ERR_NOT_INITIALIZED If the fstorage module is not initialized. + * @retval FS_ERR_INVALID_CFG If the initialization of the fstorage module is invalid. + * @retval FS_ERR_QUEUE_FULL If the internal operation queue of the fstorage module is full. + */ +fs_ret_t nrf_dfu_flash_store(uint32_t const * p_dest, uint32_t const * const p_src, uint32_t len_words, dfu_flash_callback_t callback); + + +/**@brief Function for erasing data from flash (with or without the SoftDevice enabled). + * + * @param[in] p_dest The address of the first byte to be deleted. + * @param[in] num_pages The number of flash pages to be deleted. + * @param[in] callback Pointer to the callback function. + * + * @retval FS_SUCCESS If the operation was successful. + * @retval FS_ERR_UNALIGNED_ADDR If @p p_dest is not aligned to a page boundary. + * @retval FS_ERR_INVALID_ADDR If @p p_dest does not point to the start of a flash page or the operation would + * go beyond the flash memory boundary. + * @retval FS_ERR_NOT_INITIALIZED If the fstorage module is not initialized. + * @retval FS_ERR_INVALID_CFG If the initialization of the fstorage module is invalid. + * @retval FS_ERR_NULL_ARG If @p p_dest is NULL. + * @retval FS_ERR_INVALID_ARG If @p num_pages is zero. + * @retval FS_ERR_QUEUE_FULL If the internal operation queue of the fstorage module is full. + */ +fs_ret_t nrf_dfu_flash_erase(uint32_t const * p_dest, uint32_t num_pages, dfu_flash_callback_t callback); + + +/**@brief Function for clearing an error that has occurred during fstorage operations. + */ +void nrf_dfu_flash_error_clear(void); + + +/**@brief Function for waiting for an event from fstorage. + * + * This function halts execution until an event is received from the SoftDevice. + * You can use this function to halt execution until a flash operation has completed, to prevent + * tampering with the source data until fstorage is done with it. + * + * @retval FS_SUCCESS If the operation was successful. + * @retval FS_ERR_FAILURE_SINCE_LAST If an error has occurred in another transaction and fstorage cannot continue before + * the event has been dealt with. + */ +fs_ret_t nrf_dfu_flash_wait(void); + + +#ifdef __cplusplus +} +#endif + + +#endif // NRF_DFU_FLASH_H__ +/** @} */ diff --git a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c b/components/libraries/bootloader/dfu/nrf_dfu_mbr.c new file mode 100644 index 0000000..85ebc13 --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_mbr.c @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_dfu_mbr.h" +#include "nrf_mbr.h" +#include "nrf_dfu_types.h" +#include "nrf_log.h" + +uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len) +{ + uint32_t ret_val; + uint32_t const len_words = len / sizeof(uint32_t); + + sd_mbr_command_t command = + { + .command = SD_MBR_COMMAND_COPY_BL, + .params.copy_bl.bl_src = p_src, + .params.copy_bl.bl_len = len_words + }; + + ret_val = sd_mbr_command(&command); + + return ret_val; +} + + +uint32_t nrf_dfu_mbr_copy_sd(uint32_t * p_dst, uint32_t * p_src, uint32_t len) +{ + uint32_t ret_val; + uint32_t const len_words = len / sizeof(uint32_t); + + if((len_words & (CODE_PAGE_SIZE / sizeof(uint32_t) - 1)) != 0) + return NRF_ERROR_INVALID_LENGTH; + + sd_mbr_command_t command = + { + .command = SD_MBR_COMMAND_COPY_SD, + .params.copy_sd.src = p_src, + .params.copy_sd.dst = p_dst, + .params.copy_sd.len = len_words + }; + + ret_val = sd_mbr_command(&command); + + return ret_val; +} + + +uint32_t nrf_dfu_mbr_init_sd(void) +{ + uint32_t ret_val; + + sd_mbr_command_t command = + { + .command = SD_MBR_COMMAND_INIT_SD + }; + + ret_val = sd_mbr_command(&command); + + return ret_val; +} + + +uint32_t nrf_dfu_mbr_compare(uint32_t * p_ptr1, uint32_t * p_ptr2, uint32_t len) +{ + uint32_t ret_val; + uint32_t const len_words = len / sizeof(uint32_t); + + sd_mbr_command_t command = + { + .command = SD_MBR_COMMAND_COMPARE, + .params.compare.ptr1 = p_ptr1, + .params.compare.ptr2 = p_ptr2, + .params.compare.len = len_words + }; + + ret_val = sd_mbr_command(&command); + + return ret_val; +} + + +uint32_t nrf_dfu_mbr_vector_table_set(uint32_t address) +{ + uint32_t ret_val; + + NRF_LOG_INFO("running vector table set\r\n"); + sd_mbr_command_t command = + { + .command = SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, + .params.base_set.address = address + }; + + ret_val = sd_mbr_command(&command); + NRF_LOG_INFO("After running vector table set\r\n"); + + return ret_val; +} diff --git a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h b/components/libraries/bootloader/dfu/nrf_dfu_mbr.h new file mode 100644 index 0000000..4694159 --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_mbr.h @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup sdk_nrf_dfu_mbr MBR functions + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_MBR_H__ +#define NRF_DFU_MBR_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for copying the bootloader using an MBR command. + * + * @param[in] p_src Source address of the bootloader data to copy. + * @param[in] len Length of the data to copy in bytes. + * + * @return This function will return only if the command request could not be run. + * See @ref sd_mbr_command_copy_bl_t for possible return values. + */ +uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len); + + +/** @brief Function for copying the SoftDevice using an MBR command. + * + * @param[in] p_dst Target of the SoftDevice copy. + * @param[in] p_src Source address of the SoftDevice image to copy. + * @param[in] len Length of the data to copy in bytes. + * + * @retval NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. + * @retval NRF_ERROR_INVALID_LENGTH Invalid len + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. + * @retval NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + */ +uint32_t nrf_dfu_mbr_copy_sd(uint32_t * p_dst, uint32_t * p_src, uint32_t len); + + +/** @brief Function for initializing the SoftDevice using an MBR command. + * + * @retval NRF_SUCCESS If the SoftDevice was copied successfully. + * Any other return value indicates that the SoftDevice + * could not be copied. + */ +uint32_t nrf_dfu_mbr_init_sd(void); + + +/** @brief Function for comparing source and target using an MBR command. + * + * @param[in] p_ptr1 First pointer to data to compare. + * @param[in] p_ptr2 Second pointer to data to compare. + * @param[in] len Length of the data to compare in bytes. + * + * @retval NRF_SUCCESS If the content of both memory blocks is equal. + * @retval NRF_ERROR_NULL If the content of the memory blocks differs. + */ +uint32_t nrf_dfu_mbr_compare(uint32_t * p_ptr1, uint32_t * p_ptr2, uint32_t len); + + +/** @brief Function for setting the address of the vector table using an MBR command. + * + * @param[in] address Address of the new vector table. + * + * @retval NRF_SUCCESS If the address of the new vector table was set. Any other + * return value indicates that the address could not be set. + */ +uint32_t nrf_dfu_mbr_vector_table_set(uint32_t address); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_MBR_H__ + +/** @} */ diff --git a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h b/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h new file mode 100644 index 0000000..8e656ef --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h @@ -0,0 +1,204 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup sdk_nrf_dfu_req_handler Request handling + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_REQ_HANDLER_H__ +#define NRF_DFU_REQ_HANDLER_H__ + +#include +#include +#include "nrf_dfu_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/**@brief DFU object types. + */ +typedef enum +{ + NRF_DFU_OBJ_TYPE_INVALID, /**< Invalid object type.*/ + NRF_DFU_OBJ_TYPE_COMMAND, /**< Command object packet.*/ + NRF_DFU_OBJ_TYPE_DATA, /**< Data object.*/ +} nrf_dfu_obj_type_t; + + +/**@brief DFU request operation codes. + * + * @details The DFU transport layer creates request events of these types. The implementation of @ref nrf_dfu_req_handler_on_req handles requests of these types. + */ +typedef enum +{ + + NRF_DFU_OBJECT_OP_NONE = 0, /**< No operation set. */ + NRF_DFU_OBJECT_OP_CREATE = 1, /**< Create operation. The length of the request indicates the required size. When called, the created object is selected. */ + NRF_DFU_OBJECT_OP_WRITE = 2, /**< Write operation. When called, offset and CRC of the selected object are reported back. */ + NRF_DFU_OBJECT_OP_EXECUTE = 3, /**< Execute operation. When called, the selected object is executed. */ + NRF_DFU_OBJECT_OP_CRC = 4, /**< Calculate checksum operation. When called, offset and CRC of the selected object are reported back. */ + NRF_DFU_OBJECT_OP_SELECT = 6, /**< Select operation. When called, the object of the given type is selected, and information about the object is reported back. */ + NRF_DFU_OBJECT_OP_OTHER = 7, /**< A user-defined DFU request type. The application must define how to interpret the request. */ +} nrf_dfu_req_op_t; + + +/**@brief DFU request result codes. + * + * @details The DFU transport layer creates request events of types @ref nrf_dfu_req_op_t, + * which are handled by @ref nrf_dfu_req_handler_on_req. That functions returns one of these result codes. + */ +typedef enum +{ + NRF_DFU_RES_CODE_INVALID = 0x00, /**< Invalid opcode. */ + NRF_DFU_RES_CODE_SUCCESS = 0x01, /**< Operation successful. */ + NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED = 0x02, /**< Opcode not supported. */ + NRF_DFU_RES_CODE_INVALID_PARAMETER = 0x03, /**< Missing or invalid parameter value. */ + NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES = 0x04, /**< Not enough memory for the data object. */ + NRF_DFU_RES_CODE_INVALID_OBJECT = 0x05, /**< Data object does not match the firmware and hardware requirements, the signature is missing, or parsing the command failed. */ + NRF_DFU_RES_CODE_UNSUPPORTED_TYPE = 0x07, /**< Not a valid object type for a Create request. */ + NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED = 0x08, /**< The state of the DFU process does not allow this operation. */ + NRF_DFU_RES_CODE_OPERATION_FAILED = 0x0A, /**< Operation failed. */ + NRF_DFU_RES_CODE_EXT_ERROR = 0x0B, /**< Extended error. */ +} nrf_dfu_res_code_t; + + +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + // Anonymous unions are enabled by default. +#endif + + +/** @brief Definition of a DFU request sent from the transport layer. + * + * @details When the transport layer gets a DFU event, it calls the function @ref nrf_dfu_req_handler_on_req to handle the DFU request. + */ +typedef struct +{ + nrf_dfu_req_op_t req_type; /**< Request operation type. */ + + union + { + struct + { + uint32_t obj_type; /**< Object type of the object to be created for a request of type @ref NRF_DFU_OBJECT_OP_CREATE. */ + uint32_t object_size; /**< Size of the object to be created for a request of type @ref NRF_DFU_OBJECT_OP_CREATE. Note that the object size is not the same as the size of the firmware. */ + }; + + struct + { + uint8_t * p_req; /**< Pointer to an array holding the serialized version of the request. */ + uint32_t req_len; /**< Length of the request array. */ + }; + }; +} nrf_dfu_req_t; + + +/** @brief Response used during DFU operations. + */ +typedef struct +{ + union + { + struct + { + uint8_t * p_res; /**< Pointer to an array holding the serialized version of the response. */ + uint32_t res_len; /**< Length of the response array. */ + }; + + struct + { + uint32_t max_size; /**< Maximum size of the object of a given type. */ + uint32_t offset; /**< Current offset. */ + uint32_t crc; /**< Current CRC. */ + }; + }; +} nrf_dfu_res_t; + +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + // Leave anonymous unions enabled. +#elif defined(__GNUC__) + // Anonymous unions are enabled by default. +#endif + + +/** @brief Function for initializing the request handling module. + * + * @details This function initializes the flash with or without the SoftDevice, depending on the project configuration. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_STATE If the fstorage module could not be initiated or the SoftDevice could not set the event handler. + */ +uint32_t nrf_dfu_req_handler_init(void); + + +/** @brief Function type for handling a DFU request. + * + * @param[in,out] p_context Pointer to context-specific RAM required for + * running the command request. + * This value may be NULL if the command request + * does not require context-specific RAM. + * @param[in,out] p_req Pointer to the structure holding the DFU request. + * @param[in,out] p_res Pointer to the structure holding the DFU response. + * + * @retval NRF_DFU_RES_CODE_SUCCESS If the command request was executed successfully. + * Any other error code indicates that the request + * could not be handled. + */ +nrf_dfu_res_code_t nrf_dfu_req_handler_on_req(void * p_context, nrf_dfu_req_t * p_req, nrf_dfu_res_t * p_res); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_REQ_HANDLER_H__ + +/** @} */ diff --git a/components/libraries/bootloader/dfu/nrf_dfu_settings.c b/components/libraries/bootloader/dfu/nrf_dfu_settings.c new file mode 100644 index 0000000..ca7d308 --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_settings.c @@ -0,0 +1,260 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_dfu_settings.h" +#include "nrf_dfu_flash.h" +#include "nrf_log.h" +#include "crc32.h" +#include +#include "app_scheduler.h" +#include "nrf_delay.h" + +/** @brief This variable reserves a codepage for bootloader specific settings, + * to ensure the compiler doesn't locate any code or variables at his location. + */ +#if defined (__CC_ARM ) + + uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS))) + __attribute__((used)); + +#elif defined ( __GNUC__ ) + + uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE] __attribute__ ((section(".bootloaderSettings"))) + __attribute__((used)); + +#elif defined ( __ICCARM__ ) + + __no_init __root uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE] @ BOOTLOADER_SETTINGS_ADDRESS; + +#else + + #error Not a valid compiler/linker for m_dfu_settings placement. + +#endif + + +#if defined ( NRF52 ) + +/**@brief This variable reserves a codepage for mbr parameters, to ensure the compiler doesn't + * locate any code or variables at his location. + */ +#if defined ( __CC_ARM ) + + uint8_t m_mbr_params_page[CODE_PAGE_SIZE] __attribute__((at(NRF_MBR_PARAMS_PAGE_ADDRESS))) __attribute__((used)); + +#elif defined ( __GNUC__ ) + + uint8_t m_mbr_params_page[CODE_PAGE_SIZE] __attribute__ ((section(".mbrParamsPage"))); + +#elif defined ( __ICCARM__ ) + + __no_init uint8_t m_mbr_params_page[CODE_PAGE_SIZE] @ NRF_MBR_PARAMS_PAGE_ADDRESS; + +#else + + #error Not a valid compiler/linker for m_mbr_params_page placement. + +#endif + + +/**@brief This variable makes the linker script write the mbr parameters page address to the + * UICR register. This value will be written in the HEX file and thus written to the + * UICR when the bootloader is flashed into the chip. + */ +#if defined ( __CC_ARM ) + uint32_t m_uicr_mbr_params_page_address __attribute__((at(NRF_UICR_MBR_PARAMS_PAGE_ADDRESS))) + = NRF_MBR_PARAMS_PAGE_ADDRESS; + +#elif defined ( __GNUC__ ) + volatile uint32_t m_uicr_mbr_params_page_address __attribute__ ((section(".uicrMbrParamsPageAddress"))) + = NRF_MBR_PARAMS_PAGE_ADDRESS; +#elif defined ( __ICCARM__ ) + + __root const uint32_t m_uicr_mbr_params_page_address @ NRF_UICR_MBR_PARAMS_PAGE_ADDRESS + = NRF_MBR_PARAMS_PAGE_ADDRESS; + +#else + + #error Not a valid compiler/linker for m_mbr_params_page placement. + +#endif + +#endif // defined ( NRF52 ) + +nrf_dfu_settings_t s_dfu_settings; + +//lint -save -esym(551, flash_operation_pending) +static bool flash_operation_pending; // barrier for reading flash +//lint -restore + +static dfu_flash_callback_t m_callback; + + +static void dfu_settings_write_callback(fs_evt_t const * const evt, fs_ret_t result) +{ + if (result == FS_SUCCESS) + { + flash_operation_pending = false; + } + if (m_callback != NULL) + { + m_callback(evt, result); + } +} + +static void delay_operation(void) +{ + nrf_delay_ms(100); + app_sched_execute(); +} + +static void wait_for_pending(void) +{ + while (flash_operation_pending == true) + { + NRF_LOG_INFO("Waiting for other flash operation to finish.\r\n"); + delay_operation(); + } +} + +static void wait_for_queue(void) +{ + while (fs_queue_is_full()) + { + NRF_LOG_INFO("Waiting for available space on flash queue.\r\n"); + delay_operation(); + } +} + + +uint32_t nrf_dfu_settings_calculate_crc(void) +{ + // the crc is calculated from the s_dfu_settings struct, except the crc itself and the init command + return crc32_compute((uint8_t*)&s_dfu_settings + 4, sizeof(nrf_dfu_settings_t) - 4 - sizeof(s_dfu_settings.init_command), NULL); +} + + +void nrf_dfu_settings_init(void) +{ + NRF_LOG_INFO("running nrf_dfu_settings_init\r\n"); + + uint32_t crc; + + flash_operation_pending = false; + + // Copy the DFU settings out of flash and into a buffer in RAM. + memcpy((void*)&s_dfu_settings, &m_dfu_settings_buffer[0], sizeof(nrf_dfu_settings_t)); + + if(s_dfu_settings.crc != 0xFFFFFFFF) + { + // CRC is set. Content must be valid + crc = nrf_dfu_settings_calculate_crc(); + if(crc == s_dfu_settings.crc) + { + return; + } + } + + // Reached if nothing is configured or if CRC was wrong + NRF_LOG_INFO("!!!!!!!!!!!!!!! Resetting bootloader settings !!!!!!!!!!!\r\n"); + memset(&s_dfu_settings, 0x00, sizeof(nrf_dfu_settings_t)); + s_dfu_settings.settings_version = NRF_DFU_SETTINGS_VERSION; + APP_ERROR_CHECK(nrf_dfu_settings_write(NULL)); +} + + +ret_code_t nrf_dfu_settings_write(dfu_flash_callback_t callback) +{ + ret_code_t err_code = FS_SUCCESS; + NRF_LOG_INFO("Erasing old settings at: 0x%08x\r\n", (uint32_t)&m_dfu_settings_buffer[0]); + + // Wait for any ongoing operation (because of multiple calls to nrf_dfu_settings_write) + wait_for_pending(); + + flash_operation_pending = true; + m_callback = callback; + + do + { + wait_for_queue(); + + // Not setting the callback function because ERASE is required before STORE + // Only report completion on successful STORE. + err_code = nrf_dfu_flash_erase((uint32_t*)&m_dfu_settings_buffer[0], 1, NULL); + + } while (err_code == FS_ERR_QUEUE_FULL); + + + if (err_code != FS_SUCCESS) + { + NRF_LOG_ERROR("Erasing from flash memory failed.\r\n"); + flash_operation_pending = false; + return NRF_ERROR_INTERNAL; + } + + s_dfu_settings.crc = nrf_dfu_settings_calculate_crc(); + + NRF_LOG_INFO("Writing 0x%08x words\r\n", sizeof(nrf_dfu_settings_t)/4); + + static nrf_dfu_settings_t temp_dfu_settings; + memcpy(&temp_dfu_settings, &s_dfu_settings, sizeof(nrf_dfu_settings_t)); + + do + { + wait_for_queue(); + + err_code = nrf_dfu_flash_store((uint32_t*)&m_dfu_settings_buffer[0], + (uint32_t*)&temp_dfu_settings, + sizeof(nrf_dfu_settings_t)/4, + dfu_settings_write_callback); + + } while (err_code == FS_ERR_QUEUE_FULL); + + if (err_code != FS_SUCCESS) + { + NRF_LOG_ERROR("Storing to flash memory failed.\r\n"); + flash_operation_pending = false; + return NRF_ERROR_INTERNAL; + } + + NRF_LOG_INFO("Writing settings...\r\n"); + return NRF_SUCCESS; +} + diff --git a/components/libraries/bootloader/dfu/nrf_dfu_settings.h b/components/libraries/bootloader/dfu/nrf_dfu_settings.h new file mode 100644 index 0000000..19c144f --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_settings.h @@ -0,0 +1,89 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup nrf_dfu_settings DFU settings + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_SETTINGS_H__ +#define NRF_DFU_SETTINGS_H__ + +#include +#include "app_util_platform.h" +#include "nrf_dfu_types.h" +#include "nrf_dfu_flash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Global DFU settings. + * + * @note Using this variable is not thread-safe. + * + */ +extern nrf_dfu_settings_t s_dfu_settings; + + +/** @brief Function for writing DFU settings to flash. + * + * @param[in] callback Pointer to a function that is called after completing the write operation. + * + * @retval NRF_SUCCESS If the write process was successfully initiated. + * @retval NRF_ERROR_INTERNAL If a flash error occurred. + */ +ret_code_t nrf_dfu_settings_write(dfu_flash_callback_t callback); + + +/** @brief Function for initializing the DFU settings module. + */ +void nrf_dfu_settings_init(void); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_SETTINGS_H__ + +/**@} */ diff --git a/components/libraries/bootloader/dfu/nrf_dfu_transport.c b/components/libraries/bootloader/dfu/nrf_dfu_transport.c new file mode 100644 index 0000000..1f73f70 --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_transport.c @@ -0,0 +1,99 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_dfu_transport.h" +#include "nrf_log.h" + + +#define DFU_TRANS_SECTION_VARS_GET(i) NRF_SECTION_VARS_GET((i), nrf_dfu_transport_t, dfu_trans) +#define DFU_TRANS_SECTION_VARS_COUNT NRF_SECTION_VARS_COUNT(nrf_dfu_transport_t, dfu_trans) + + //lint -save -e19 -e526 +NRF_SECTION_VARS_CREATE_SECTION(dfu_trans, const nrf_dfu_transport_t); +//lint -restore + +uint32_t nrf_dfu_transports_init(void) +{ + uint32_t const num_transports = DFU_TRANS_SECTION_VARS_COUNT; + uint32_t ret_val = NRF_SUCCESS; + + NRF_LOG_INFO("In nrf_dfu_transports_init\r\n"); + + NRF_LOG_INFO("num transports: %d\r\n", num_transports); + + for (uint32_t i = 0; i < num_transports; i++) + { + nrf_dfu_transport_t * const trans = DFU_TRANS_SECTION_VARS_GET(i); + ret_val = trans->init_func(); + if (ret_val != NRF_SUCCESS) + { + break; + } + } + + NRF_LOG_INFO("After nrf_dfu_transports_init\r\n"); + + return ret_val; +} + + +uint32_t nrf_dfu_transports_close(void) +{ + uint32_t const num_transports = DFU_TRANS_SECTION_VARS_COUNT; + uint32_t ret_val = NRF_SUCCESS; + + NRF_LOG_INFO("In nrf_dfu_transports_close\r\n"); + + NRF_LOG_INFO("num transports: %d\r\n", num_transports); + + for (uint32_t i = 0; i < num_transports; i++) + { + nrf_dfu_transport_t * const trans = DFU_TRANS_SECTION_VARS_GET(i); + ret_val = trans->close_func(); + if (ret_val != NRF_SUCCESS) + { + break; + } + } + + NRF_LOG_INFO("After nrf_dfu_transports_init\r\n"); + + return ret_val; +} diff --git a/components/libraries/bootloader/dfu/nrf_dfu_transport.h b/components/libraries/bootloader/dfu/nrf_dfu_transport.h new file mode 100644 index 0000000..b0d9117 --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_transport.h @@ -0,0 +1,126 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup sdk_nrf_dfu_transport DFU transport + * @{ + * @ingroup sdk_nrf_bootloader + * @brief Generic Device Firmware Update (DFU) transport interface. + * + * @details The DFU transport module defines a generic interface that must + * be implemented for each transport layer. + */ + +#ifndef NRF_DFU_TRANSPORT_H__ +#define NRF_DFU_TRANSPORT_H__ + +#include +#include "section_vars.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Function type for initializing a DFU transport. + * + * @details This function initializes a DFU transport. The implementation + * of the function must initialize DFU mode and stay in service + * until either the device is reset or the DFU operation is finalized. + * When the DFU transport receives requests, it should call @ref nrf_dfu_req_handler_on_req for handling the requests. + * + * @retval NRF_SUCCESS If initialization was successful for the transport. Any other return code indicates that the DFU transport could not be initialized. + */ +typedef uint32_t (*nrf_dfu_init_fn_t)(void); + + +/** @brief Function type for closing down a DFU transport. + * + * @details This function closes down a DFU transport in a gentle way. + * + * @retval NRF_SUCCESS If closing was successful for the transport. Any other return code indicates that the DFU transport could not be closed closed down. + */ +typedef uint32_t (*nrf_dfu_disconnect_fn_t)(void); + + +/** @brief DFU transport registration. + * + * @details Every DFU transport must provide a registration of the initialization function. + */ +typedef struct +{ + nrf_dfu_init_fn_t init_func; /**< Registration of the init function to run to initialize a DFU transport. */ + nrf_dfu_disconnect_fn_t close_func; /**< Registration of the close function to close down a DFU transport. */ +} nrf_dfu_transport_t; + + +/** @brief Function for initializing all the registered DFU transports. + * + * @retval NRF_SUCCESS If all DFU transport were initialized successfully. + * Any other error code indicates that at least one DFU + * transport could not be initialized. + */ +uint32_t nrf_dfu_transports_init(void); + +/** @brief Function for closing down all the registered DFU transports. + * + * @retval NRF_SUCCESS If all DFU transport were closed down successfully. + * Any other error code indicates that at least one DFU + * transport could not be closed down. + */ +uint32_t nrf_dfu_transports_close(void); + + +/** @brief Macro for registering a DFU transport by using section variables. + * + * @details This macro places a variable in a section named "dfu_trans", which + * is initialized by @ref nrf_dfu_transports_init. + */ +#define DFU_TRANSPORT_REGISTER(trans_var) NRF_SECTION_VARS_REGISTER_VAR(dfu_trans, trans_var) + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_TRANSPORT_H__ + +/** @} */ diff --git a/components/libraries/bootloader/dfu/nrf_dfu_types.h b/components/libraries/bootloader/dfu/nrf_dfu_types.h new file mode 100644 index 0000000..11eaabb --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_types.h @@ -0,0 +1,237 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup sdk_nrf_dfu_types DFU types + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_TYPES_H__ +#define NRF_DFU_TYPES_H__ + +#include +#include +#include "nrf_mbr.h" +#include "nrf_sdm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define INIT_COMMAND_MAX_SIZE 256 /**< Maximum size of the init command stored in dfu_settings. */ + + +/** @brief Size of a flash codepage. This value is used for calculating the size of the reserved + * flash space in the bootloader region. It is checked against NRF_UICR->CODEPAGESIZE + * at run time to ensure that the region is correct. + */ +#if defined(NRF51) + #define CODE_PAGE_SIZE (PAGE_SIZE_IN_WORDS*sizeof(uint32_t)) +#elif defined(NRF52) + #define CODE_PAGE_SIZE (MBR_PAGE_SIZE_IN_WORDS*sizeof(uint32_t)) +#else + #error "Architecture not set." +#endif + + +/** @brief Maximum size of a data object.*/ +#ifdef NRF51 + + #define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE * 4) + +#elif NRF52 + + #define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE) + +#else + + #error "Architecture not set." + +#endif + +/** @brief Page location of the bootloader settings address. + */ + +#if defined (NRF51 ) + + #define BOOTLOADER_SETTINGS_ADDRESS (0x0003FC00UL) + +#elif defined ( NRF52 ) + + #define BOOTLOADER_SETTINGS_ADDRESS (0x0007F000UL) + +#else + + #error No valid target set for BOOTLOADER_SETTINGS_ADDRESS. + +#endif + + + +#if defined(NRF52) + +/** + * @brief MBR parameters page in UICR. + * + * Register location in UICR where the page address of the MBR parameters page is stored (only used by the nRF52 MBR). + * + * @note If the value at the given location is 0xFFFFFFFF, no MBR parameters page is set. + */ +#define NRF_UICR_MBR_PARAMS_PAGE_ADDRESS (NRF_UICR_BASE + 0x18) + + +/** @brief Page location of the MBR parameters page address. + * + */ +#define NRF_MBR_PARAMS_PAGE_ADDRESS (0x0007E000UL) + +#endif + +/** @brief Size of the flash space reserved for application data. + */ +#ifndef DFU_APP_DATA_RESERVED +#define DFU_APP_DATA_RESERVED CODE_PAGE_SIZE * 3 +#endif + + +/** @brief Total size of the region between the SoftDevice and the bootloader. + */ +#define DFU_REGION_TOTAL_SIZE ((* (uint32_t *)NRF_UICR_BOOTLOADER_START_ADDRESS) - CODE_REGION_1_START) + + +/** @brief Start address of the SoftDevice (excluding the area for the MBR). + */ +#define SOFTDEVICE_REGION_START MBR_SIZE + + +/** @brief Size of the Code Region 0, found in the UICR.CLEN0 register. + * + * @details This value is identical to the start of Code Region 1. This value is used for + * compilation safety, because the linker will fail if the application expands + * into the bootloader. At run time, the bootloader uses the value found in UICR.CLEN0. + */ + +#ifndef CODE_REGION_1_START +#define CODE_REGION_1_START SD_SIZE_GET(MBR_SIZE) +#endif + +#define NRF_DFU_CURRENT_BANK_0 0x00 +#define NRF_DFU_CURRENT_BANK_1 0x01 + +#define NRF_DFU_BANK_LAYOUT_DUAL 0x00 +#define NRF_DFU_BANK_LAYOUT_SINGLE 0x01 + + +/** @brief DFU bank state codes. + * + * @details The DFU bank state indicates the content of a bank: + * A valid image of a certain type or an invalid image. + */ + +#define NRF_DFU_BANK_INVALID 0x00 /**< Invalid image. */ +#define NRF_DFU_BANK_VALID_APP 0x01 /**< Valid application. */ +#define NRF_DFU_BANK_VALID_SD 0xA5 /**< Valid SoftDevice. */ +#define NRF_DFU_BANK_VALID_BL 0xAA /**< Valid bootloader. */ +#define NRF_DFU_BANK_VALID_SD_BL 0xAC /**< Valid SoftDevice and bootloader. */ + + +/** @brief Description of a single bank. */ +#pragma pack(4) +typedef struct +{ + uint32_t image_size; /**< Size of the image in the bank. */ + uint32_t image_crc; /**< CRC of the image. If set to 0, the CRC is ignored. */ + uint32_t bank_code; /**< Identifier code for the bank. */ +} nrf_dfu_bank_t; + +/**@brief DFU progress. + * + * Be aware of the difference between objects and firmware images. A firmware image consists of multiple objects, each of a maximum size @ref DATA_OBJECT_MAX_SIZE. + */ +typedef struct +{ + uint32_t command_size; /**< The size of the current init command stored in the DFU settings. */ + uint32_t command_offset; /**< The offset of the currently received init command data. The offset will increase as the init command is received. */ + uint32_t command_crc; /**< The calculated CRC of the init command (calculated after the transfer is completed). */ + + uint32_t data_object_size; /**< The size of the last object created. Note that this size is not the size of the whole firmware image.*/ + + uint32_t firmware_image_crc; /**< CRC value of the current firmware (continuously calculated as data is received). */ + uint32_t firmware_image_crc_last; /**< The CRC of the last executed object. */ + uint32_t firmware_image_offset; /**< The offset of the current firmware image being transferred. Note that this offset is the offset in the entire firmware image and not only the current object. */ + uint32_t firmware_image_offset_last;/**< The offset of the last executed object from the start of the firmware image. */ +} dfu_progress_t; + + +/**@brief DFU settings for application and bank data. + */ +typedef struct +{ + uint32_t crc; /**< CRC for the stored DFU settings, not including the CRC itself. If 0xFFFFFFF, the CRC has never been calculated. */ + uint32_t settings_version; /**< Version of the currect dfu settings struct layout.*/ + uint32_t app_version; /**< Version of the last stored application. */ + uint32_t bootloader_version; /**< Version of the last stored bootloader. */ + + uint32_t bank_layout; /**< Bank layout: single bank or dual bank. This value can change. */ + uint32_t bank_current; /**< The bank that is currently used. */ + + nrf_dfu_bank_t bank_0; /**< Bank 0. */ + nrf_dfu_bank_t bank_1; /**< Bank 1. */ + + uint32_t write_offset; /**< Write offset for the current operation. */ + uint32_t sd_size; /**< SoftDevice size (if combined BL and SD). */ + + dfu_progress_t progress; /**< Current DFU progress. */ + + uint32_t enter_buttonless_dfu; + uint8_t init_command[INIT_COMMAND_MAX_SIZE]; /**< Buffer for storing the init command. */ +} nrf_dfu_settings_t; +#pragma pack() // revert pack settings + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_TYPES_H__ + +/** @} */ diff --git a/components/libraries/bootloader/dfu/nrf_dfu_utils.c b/components/libraries/bootloader/dfu/nrf_dfu_utils.c new file mode 100644 index 0000000..6bd4102 --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_utils.c @@ -0,0 +1,574 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_dfu_utils.h" + +#include +#include "nrf_dfu_settings.h" +#include "nrf_dfu_mbr.h" +#include "nrf_bootloader_app_start.h" +#include "nrf_bootloader_info.h" +#include "crc32.h" +#include "nrf_log.h" + + +static uint32_t align_to_page(uint32_t val, uint32_t page_size) +{ + return ((val + page_size - 1 ) &~ (page_size - 1)); +} + + +static void nrf_dfu_invalidate_bank(nrf_dfu_bank_t * p_bank) +{ + // Set the bank-code to invalid, and reset size/CRC + memset(p_bank, 0, sizeof(nrf_dfu_bank_t)); + + // Reset write pointer after completed operation + s_dfu_settings.write_offset = 0; + + // Reset SD size + s_dfu_settings.sd_size = 0; + + // Promote dual bank layout + s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL; + + // Signify that bank 0 is empty + s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_0; +} + + +/** @brief Function to continue App update + * + * @details This function will be called after reset if there is a valid application in Bank1 + * required to be copied down to bank0. + * + * @param[in] src_addr Source address of the application to copy from Bank1 to Bank0. + * + * @retval NRF_SUCCESS Continuation was successful. + * @retval NRF_ERROR_NULL Invalid data during compare. + * @retval FS_ERR_UNALIGNED_ADDR A call to fstorage was not aligned to a page boundary or the address was not word aliged. + * @retval FS_ERR_INVALID_ADDR The destination of a call to fstorage does not point to + * the start of a flash page or the operation would + * go beyond the flash memory boundary. + * @retval FS_ERR_NOT_INITIALIZED The fstorage module is not initialized. + * @retval FS_ERR_INVALID_CFG The initialization of the fstorage module is invalid. + * @retval FS_ERR_NULL_ARG A call to fstorage had an invalid NULL argument. + * @retval FS_ERR_INVALID_ARG A call to fstorage had invalid arguments. + * @retval FS_ERR_QUEUE_FULL If the internal operation queue of the fstorage module is full. + * @retval FS_ERR_FAILURE_SINCE_LAST If an error occurred in another transaction and fstorage cannot continue before + * the event has been dealt with. + */ +static uint32_t nrf_dfu_app_continue(uint32_t src_addr) +{ + // This function only in use when new app is present in bank 1 + uint32_t const image_size = s_dfu_settings.bank_1.image_size; + uint32_t const split_size = CODE_PAGE_SIZE; // Arbitrary number that must be page aligned + + uint32_t ret_val = NRF_SUCCESS; + uint32_t target_addr = MAIN_APPLICATION_START_ADDR + s_dfu_settings.write_offset; + uint32_t length_left = (image_size - s_dfu_settings.write_offset); + uint32_t cur_len; + uint32_t crc; + + NRF_LOG_INFO("Enter nrf_dfu_app_continue\r\n"); + + // Copy the application down safely + do + { + cur_len = (length_left > split_size) ? split_size : length_left; + + // Erase the target page + ret_val = nrf_dfu_flash_erase((uint32_t*) target_addr, split_size / CODE_PAGE_SIZE, NULL); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + // Flash one page + ret_val = nrf_dfu_flash_store((uint32_t*)target_addr, (uint32_t*)src_addr, cur_len, NULL); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + ret_val = nrf_dfu_mbr_compare((uint32_t*)target_addr, (uint32_t*)src_addr, cur_len); + if (ret_val != NRF_SUCCESS) + { + // We will not retry the copy + NRF_LOG_INFO("Invalid data during compare: target: 0x%08x, src: 0x%08x\r\n", target_addr, src_addr); + return ret_val; + } + + // Erase the head (to handle growing bank 0) + ret_val = nrf_dfu_flash_erase((uint32_t*) src_addr, split_size / CODE_PAGE_SIZE, NULL); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_INFO("App update: Failure erasing page at addr: 0x%08x\r\n", src_addr); + return ret_val; + } + + s_dfu_settings.write_offset += cur_len; + ret_val = nrf_dfu_settings_write(NULL); + + target_addr += cur_len; + src_addr += cur_len; + + length_left -= cur_len; + } + while(length_left > 0); + + // Check the crc of the copied data. Enable if so. + crc = crc32_compute((uint8_t*)MAIN_APPLICATION_START_ADDR, image_size, NULL); + + if (crc == s_dfu_settings.bank_1.image_crc) + { + NRF_LOG_INFO("Setting app as valid\r\n"); + s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_VALID_APP; + s_dfu_settings.bank_0.image_crc = crc; + s_dfu_settings.bank_0.image_size = image_size; + } + else + { + NRF_LOG_INFO("CRC computation failed for copied app: src crc: 0x%08x, res crc: 0x08x\r\n", s_dfu_settings.bank_1.image_crc, crc); + } + + nrf_dfu_invalidate_bank(&s_dfu_settings.bank_1); + ret_val = nrf_dfu_settings_write(NULL); + + return ret_val; +} + +/** @brief Function to execute the continuation of a SoftDevice update. + * + * @param[in] src_addr Source address of the SoftDevice to copy from. + * @param[in] p_bank Pointer to the bank where the SoftDevice resides. + * + * @retval NRF_SUCCESS Continuation was successful. + * @retval NRF_ERROR_INVALID_LENGTH Invalid len + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. + * @retval NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + * @retval NRF_ERROR_NULL If the content of the memory blocks differs after copying. + */ +static uint32_t nrf_dfu_sd_continue_impl(uint32_t src_addr, + nrf_dfu_bank_t * p_bank) +{ + uint32_t ret_val = NRF_SUCCESS; + uint32_t target_addr = SOFTDEVICE_REGION_START + s_dfu_settings.write_offset; + uint32_t length_left = align_to_page(s_dfu_settings.sd_size - s_dfu_settings.write_offset, CODE_PAGE_SIZE); + uint32_t split_size = align_to_page(length_left / 4, CODE_PAGE_SIZE); + + NRF_LOG_INFO("Enter nrf_bootloader_dfu_sd_continue\r\n"); + + // This can be a continuation due to a power failure + src_addr += s_dfu_settings.write_offset; + + if (s_dfu_settings.sd_size != 0 && s_dfu_settings.write_offset == s_dfu_settings.sd_size) + { + NRF_LOG_INFO("SD already copied\r\n"); + return NRF_SUCCESS; + } + + NRF_LOG_INFO("Updating SD. Old SD ver: 0x%04x\r\n", SD_FWID_GET(MBR_SIZE)); + + do + { + NRF_LOG_INFO("Copying [0x%08x-0x%08x] to [0x%08x-0x%08x]: Len: 0x%08x\r\n", src_addr, src_addr + split_size, target_addr, target_addr + split_size, split_size); + + // Copy a chunk of the SD. Size in words + ret_val = nrf_dfu_mbr_copy_sd((uint32_t*)target_addr, (uint32_t*)src_addr, split_size); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_INFO("Failed to copy SD: target: 0x%08x, src: 0x%08x, len: 0x%08x\r\n", target_addr, src_addr, split_size); + return ret_val; + } + + NRF_LOG_INFO("Finished copying [0x%08x-0x%08x] to [0x%08x-0x%08x]: Len: 0x%08x\r\n", src_addr, src_addr + split_size, target_addr, target_addr + split_size, split_size); + + // Validate copy. Size in words + ret_val = nrf_dfu_mbr_compare((uint32_t*)target_addr, (uint32_t*)src_addr, split_size); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_INFO("Failed to Compare SD: target: 0x%08x, src: 0x%08x, len: 0x%08x\r\n", target_addr, src_addr, split_size); + return ret_val; + } + + NRF_LOG_INFO("Validated 0x%08x-0x%08x to 0x%08x-0x%08x: Size: 0x%08x\r\n", src_addr, src_addr + split_size, target_addr, target_addr + split_size, split_size); + + target_addr += split_size; + src_addr += split_size; + + if (split_size > length_left) + { + length_left = 0; + } + else + { + length_left -= split_size; + } + + NRF_LOG_INFO("Finished with the SD update.\r\n"); + + // Save the updated point of writes in case of power loss + s_dfu_settings.write_offset = s_dfu_settings.sd_size - length_left; + ret_val = nrf_dfu_settings_write(NULL); + } + while (length_left > 0); + + return ret_val; +} + + +/** @brief Function to continue SoftDevice update + * + * @details This function will be called after reset if there is a valid SoftDevice in Bank0 or Bank1 + * required to be relocated and activated through MBR commands. + * + * @param[in] src_addr Source address of the SoftDevice to copy from. + * @param[in] p_bank Pointer to the bank where the SoftDevice resides. + * + * @retval NRF_SUCCESS Continuation was successful. + * @retval NRF_ERROR_INVALID_LENGTH Invalid len + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. + * @retval NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + * @retval NRF_ERROR_NULL If the content of the memory blocks differs after copying. + */ +static uint32_t nrf_dfu_sd_continue(uint32_t src_addr, + nrf_dfu_bank_t * p_bank) +{ + uint32_t ret_val; + + ret_val = nrf_dfu_sd_continue_impl(src_addr, p_bank); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_INFO("SD update continuation failed\r\n"); + return ret_val; + } + + nrf_dfu_invalidate_bank(p_bank); + ret_val = nrf_dfu_settings_write(NULL); + + return ret_val; +} + + +/** @brief Function to continue Bootloader update + * + * @details This function will be called after reset if there is a valid Bootloader in Bank0 or Bank1 + * required to be relocated and activated through MBR commands. + * + * @param[in] src_addr Source address of the BL to copy from. + * @param[in] p_bank Pointer to the bank where the SoftDevice resides. + * + * @return This fucntion will not return if the bootloader is copied succesfully. + * After the copy is verified the device will reset and start the new bootloader. + * + * @retval NRF_SUCCESS Continuation was successful. + * @retval NRF_ERROR_INVALID_LENGTH Invalid length of flash operation. + * @retval NRF_ERROR_NO_MEM if no parameter page is provided (see sds for more info). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. + * @retval NRF_ERROR_INTERNAL internal error that should not happen. + * @retval NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. + */ +static uint32_t nrf_dfu_bl_continue(uint32_t src_addr, nrf_dfu_bank_t * p_bank) +{ + uint32_t ret_val = NRF_SUCCESS; + uint32_t const len = (p_bank->image_size - s_dfu_settings.sd_size); + + // if the update is a combination of BL + SD, offset with SD size to get BL start address + src_addr += s_dfu_settings.sd_size; + + NRF_LOG_INFO("Verifying BL: Addr: 0x%08x, Src: 0x%08x, Len: 0x%08x\r\n", MAIN_APPLICATION_START_ADDR, src_addr, len); + + + // If the bootloader is the same as the banked version, the copy is finished + ret_val = nrf_dfu_mbr_compare((uint32_t*)BOOTLOADER_START_ADDR, (uint32_t*)src_addr, len); + if (ret_val == NRF_SUCCESS) + { + NRF_LOG_INFO("Bootloader was verified\r\n"); + + // Invalidate bank, marking completion + nrf_dfu_invalidate_bank(p_bank); + ret_val = nrf_dfu_settings_write(NULL); + } + else + { + NRF_LOG_INFO("Bootloader not verified, copying: Src: 0x%08x, Len: 0x%08x\r\n", src_addr, len); + // Bootloader is different than the banked version. Continue copy + // Note that if the SD and BL was combined, then the split point between them is in s_dfu_settings.sd_size + ret_val = nrf_dfu_mbr_copy_bl((uint32_t*)src_addr, len); + if(ret_val != NRF_SUCCESS) + { + NRF_LOG_INFO("Request to copy BL failed\r\n"); + } + } + + return ret_val; +} + + +/** @brief Function to continue combined Bootloader and SoftDevice update + * + * @details This function will be called after reset if there is a valid Bootloader and SoftDevice in Bank0 or Bank1 + * required to be relocated and activated through MBR commands. + * + * @param[in] src_addr Source address of the combined Bootloader and SoftDevice to copy from. + * @param[in] p_bank Pointer to the bank where the SoftDevice resides. + * + * @retval NRF_SUCCESS Continuation was successful. + * @retval NRF_ERROR_INVALID_LENGTH Invalid len + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. + * @retval NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. + * @retval NRF_ERROR_NULL If the content of the memory blocks differs after copying. + * @retval NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. + */ +static uint32_t nrf_dfu_sd_bl_continue(uint32_t src_addr, nrf_dfu_bank_t * p_bank) +{ + uint32_t ret_val = NRF_SUCCESS; + + NRF_LOG_INFO("Enter nrf_dfu_sd_bl_continue\r\n"); + + ret_val = nrf_dfu_sd_continue_impl(src_addr, p_bank); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_INFO("SD+BL: SD copy failed\r\n"); + return ret_val; + } + + ret_val = nrf_dfu_bl_continue(src_addr, p_bank); + if (ret_val != NRF_SUCCESS) + { + NRF_LOG_INFO("SD+BL: BL copy failed\r\n"); + return ret_val; + } + + return ret_val; +} + + +static uint32_t nrf_dfu_continue_bank(nrf_dfu_bank_t * p_bank, uint32_t src_addr, uint32_t * p_enter_dfu_mode) +{ + uint32_t ret_val = NRF_SUCCESS; + + switch (p_bank->bank_code) + { + case NRF_DFU_BANK_VALID_APP: + NRF_LOG_INFO("Valid App\r\n"); + if(s_dfu_settings.bank_current == NRF_DFU_CURRENT_BANK_1) + { + // Only continue copying if valid app in bank1 + ret_val = nrf_dfu_app_continue(src_addr); + } + break; + + case NRF_DFU_BANK_VALID_SD: + NRF_LOG_INFO("Valid SD\r\n"); + // There is a valid SD that needs to be copied (or continued) + ret_val = nrf_dfu_sd_continue(src_addr, p_bank); + (*p_enter_dfu_mode) = 1; + break; + + case NRF_DFU_BANK_VALID_BL: + NRF_LOG_INFO("Valid BL\r\n"); + // There is a valid BL that must be copied (or continued) + ret_val = nrf_dfu_bl_continue(src_addr, p_bank); + break; + + case NRF_DFU_BANK_VALID_SD_BL: + NRF_LOG_INFO("Single: Valid SD + BL\r\n"); + // There is a valid SD + BL that must be copied (or continued) + ret_val = nrf_dfu_sd_bl_continue(src_addr, p_bank); + // Set the bank-code to invalid, and reset size/CRC + (*p_enter_dfu_mode) = 1; + break; + + case NRF_DFU_BANK_INVALID: + default: + NRF_LOG_INFO("Single: Invalid bank\r\n"); + break; + } + + return ret_val; +} + + +uint32_t nrf_dfu_continue(uint32_t * p_enter_dfu_mode) +{ + uint32_t ret_val; + nrf_dfu_bank_t * p_bank; + uint32_t src_addr = CODE_REGION_1_START; + + NRF_LOG_INFO("Enter nrf_dfu_continue\r\n"); + + if (s_dfu_settings.bank_layout == NRF_DFU_BANK_LAYOUT_SINGLE ) + { + p_bank = &s_dfu_settings.bank_0; + } + else if(s_dfu_settings.bank_current == NRF_DFU_CURRENT_BANK_0) + { + p_bank = &s_dfu_settings.bank_0; + } + else + { + p_bank = &s_dfu_settings.bank_1; + src_addr += align_to_page(s_dfu_settings.bank_0.image_size, CODE_PAGE_SIZE); + } + + ret_val = nrf_dfu_continue_bank(p_bank, src_addr, p_enter_dfu_mode); + return ret_val; +} + + +bool nrf_dfu_app_is_valid(void) +{ + NRF_LOG_INFO("Enter nrf_dfu_app_is_valid\r\n"); + if (s_dfu_settings.bank_0.bank_code != NRF_DFU_BANK_VALID_APP) + { + // Bank 0 has no valid app. Nothing to boot + NRF_LOG_INFO("Return false in valid app check\r\n"); + return false; + } + + // If CRC == 0, this means CRC check is skipped. + if (s_dfu_settings.bank_0.image_crc != 0) + { + uint32_t crc = crc32_compute((uint8_t*) CODE_REGION_1_START, + s_dfu_settings.bank_0.image_size, + NULL); + + if (crc != s_dfu_settings.bank_0.image_crc) + { + // CRC does not match with what is stored. + NRF_LOG_INFO("Return false in CRC\r\n"); + return false; + } + } + + NRF_LOG_INFO("Return true. App was valid\r\n"); + return true; +} + + +uint32_t nrf_dfu_find_cache(uint32_t size_req, bool dual_bank_only, uint32_t * p_address) +{ + // TODO: Prevalidate p_address and p_bank + + uint32_t free_size = DFU_REGION_TOTAL_SIZE - DFU_APP_DATA_RESERVED; + nrf_dfu_bank_t * p_bank; + + NRF_LOG_INFO("Enter nrf_dfu_find_cache\r\n"); + + // Simple check if size requirement can me met + if(free_size < size_req) + { + NRF_LOG_INFO("No way to fit the new firmware on device\r\n"); + return NRF_ERROR_NO_MEM; + } + + NRF_LOG_INFO("Bank content\r\n"); + NRF_LOG_INFO("Bank type: %d\r\n", s_dfu_settings.bank_layout); + NRF_LOG_INFO("Bank 0 code: 0x%02x: Size: %d\r\n", s_dfu_settings.bank_0.bank_code, s_dfu_settings.bank_0.image_size); + NRF_LOG_INFO("Bank 1 code: 0x%02x: Size: %d\r\n", s_dfu_settings.bank_1.bank_code, s_dfu_settings.bank_1.image_size); + + // Setting bank_0 as candidate + p_bank = &s_dfu_settings.bank_0; + + // Setting candidate address + (*p_address) = MAIN_APPLICATION_START_ADDR; + + // Calculate free size + if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP) + { + // Valid app present. + + NRF_LOG_INFO("free_size before bank select: %d\r\n", free_size); + + free_size -= align_to_page(p_bank->image_size, CODE_PAGE_SIZE); + + NRF_LOG_INFO("free_size: %d, size_req: %d\r\n", free_size, size_req); + + // Check if we can fit the new in the free space or if removal of old app is required. + if(size_req > free_size) + { + // Not enough room in free space (bank_1) + if ((dual_bank_only)) + { + NRF_LOG_INFO("Failure: dual bank restriction\r\n"); + return NRF_ERROR_NO_MEM; + } + + // Can only support single bank update, clearing old app. + s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_SINGLE; + s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_0; + p_bank = &s_dfu_settings.bank_0; + NRF_LOG_INFO("Enforcing single bank\r\n"); + } + else + { + // Room in bank_1 for update + // Ensure we are using dual bank layout + s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL; + s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1; + p_bank = &s_dfu_settings.bank_1; + // Set to first free page boundry after previous app + (*p_address) += align_to_page(s_dfu_settings.bank_0.image_size, CODE_PAGE_SIZE); + NRF_LOG_INFO("Using second bank\r\n"); + } + } + else + { + // No valid app present. Promoting dual bank. + s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL; + s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_0; + + p_bank = &s_dfu_settings.bank_0; + NRF_LOG_INFO("No previous, using bank 0\r\n"); + } + + // Set the bank-code to invalid, and reset size/CRC + memset(p_bank, 0, sizeof(nrf_dfu_bank_t)); + + // Store the Firmware size in the bank for continuations + p_bank->image_size = size_req; + return NRF_SUCCESS; +} + diff --git a/components/libraries/bootloader/dfu/nrf_dfu_utils.h b/components/libraries/bootloader/dfu/nrf_dfu_utils.h new file mode 100644 index 0000000..3f4351e --- /dev/null +++ b/components/libraries/bootloader/dfu/nrf_dfu_utils.h @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup sdk_nrf_dfu_utils DFU utilities + * @{ + * @ingroup sdk_nrf_dfu + */ + +#ifndef NRF_DFU_UTILS_H__ +#define NRF_DFU_UTILS_H__ + +#include +#include +#include "nrf_dfu_types.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + +/** @brief Function for continuing an ongoing DFU operation. + * + * @details This function initiates or continues the DFU copy-back + * routines. These routines are fail-safe operations to activate + * either a new SoftDevice, Bootloader, combination of SoftDevice and + * Bootloader, or a new application. + * + * @details This function relies on accessing MBR commands through supervisor calls. + * It does not rely on the SoftDevice for flash operations. + * + * @note When updating the bootloader or both bootloader and SoftDevice in combination, + * this function does not return, but rather initiate a reboot to activate + * the new bootloader. + * + * @param[in,out] p_enter_dfu_mode True if the continuation failed or the update requires DFU mode. + * + * @retval NRF_SUCCESS If the DFU operation was continued successfully. + * Any other error code indicates that the DFU operation could + * not be continued. + */ +uint32_t nrf_dfu_continue(uint32_t * p_enter_dfu_mode); + + +/** @brief Function for checking if the main application is valid. + * + * @details This function checks if there is a valid application + * located at Bank 0. + * + * @retval true If a valid application has been detected. + * @retval false If there is no valid application. + */ +bool nrf_dfu_app_is_valid(void); + + +/** @brief Function for finding a cache write location for the DFU process. + * + * @details This function checks the size requirements and selects a location for + * placing the cache of the DFU images. + * The function tries to find enough space in Bank 1. If there is not enough space, + * the present application is erased. + * + * @param[in] size_req Requirements for the size of the new image. + * @param[in] dual_bank_only True to enforce dual-bank updates. In this case, if there + * is not enough space for caching the DFU image, the existing + * application is retained and the function returns an error. + * @param[out] p_address Updated to the cache address if a cache location is found. + * + * @retval NRF_SUCCESS If a cache location was found for the DFU process. + * @retval NRF_ERROR_NO_MEM If there is no space available on the device to continue the DFU process. + */ +uint32_t nrf_dfu_find_cache(uint32_t size_req, bool dual_bank_only, uint32_t * p_address); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_DFU_UTILS_H__ + +/** @} */ diff --git a/components/libraries/bootloader/nrf_bootloader.c b/components/libraries/bootloader/nrf_bootloader.c new file mode 100644 index 0000000..b67d953 --- /dev/null +++ b/components/libraries/bootloader/nrf_bootloader.c @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_bootloader.h" + +#include "compiler_abstraction.h" +#include "nrf.h" +#include "nrf_bootloader_app_start.h" +#include "nrf_log.h" +#include "nrf_dfu.h" +#include "nrf_error.h" + + +/** @brief Weak implemenation of nrf_dfu_init + * + * @note This function will be overridden if nrf_dfu.c is + * compiled and linked with the project + */ + #if (__LINT__ != 1) +__WEAK uint32_t nrf_dfu_init(void) +{ + NRF_LOG_INFO("in weak nrf_dfu_init\r\n"); + return NRF_SUCCESS; +} +#endif + + +/** @brief Weak implementation of nrf_dfu_init + * + * @note This function must be overridden in application if + * user-specific initialization is needed. + */ +__WEAK uint32_t nrf_dfu_init_user(void) +{ + NRF_LOG_INFO("in weak nrf_dfu_init_user\r\n"); + return NRF_SUCCESS; +} + + +uint32_t nrf_bootloader_init(void) +{ + NRF_LOG_INFO("In nrf_bootloader_init\r\n"); + + uint32_t ret_val = NRF_SUCCESS; + + #if 0 + // Call user-defined init function if implemented + ret_val = nrf_dfu_init_user(); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + #endif + + // Call DFU init function if implemented + ret_val = nrf_dfu_init(); + if (ret_val != NRF_SUCCESS) + { + return ret_val; + } + + NRF_LOG_INFO("After nrf_bootloader_init\r\n"); + return ret_val; +} diff --git a/components/libraries/bootloader/nrf_bootloader.h b/components/libraries/bootloader/nrf_bootloader.h new file mode 100644 index 0000000..284827e --- /dev/null +++ b/components/libraries/bootloader/nrf_bootloader.h @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup sdk_nrf_bootloader Bootloader modules + * @ingroup app_common + * @brief Modules for creating a bootloader. + * + * @defgroup sdk_bootloader Bootloader + * @{ + * @ingroup sdk_nrf_bootloader + * @brief Basic bootloader. + * + * The bootloader module can be used to implement a basic bootloader that + * can be extended with, for example, Device Firmware Update (DFU) support + * or custom functionality. + */ + +#ifndef NRF_BOOTLOADER_H__ +#define NRF_BOOTLOADER_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for initializing the bootloader. + * + * @details This function is the entry point of all bootloader operations. + * If DFU functionality is compiled in, the DFU process is initialized + * when running this function. + * + * @retval NRF_SUCCESS If the bootloader was successfully initialized. + * Any other return code indicates that the operation failed. + */ +uint32_t nrf_bootloader_init(void); + + +/** @brief Function for customizing the bootloader initialization. + * + * @details This function is called during the initialization of the bootloader. + * It is implemented as weak function that can be overridden in the main file of the application. + * + * @retval NRF_SUCCESS If the user initialization was run successfully. + */ +uint32_t nrf_bootloader_user_init(void); + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_BOOTLOADER_H__ +/** @} */ diff --git a/components/libraries/bootloader_dfu/bootloader_util.c b/components/libraries/bootloader/nrf_bootloader_app_start.c similarity index 71% rename from components/libraries/bootloader_dfu/bootloader_util.c rename to components/libraries/bootloader/nrf_bootloader_app_start.c index afcdcec..2e53970 100644 --- a/components/libraries/bootloader_dfu/bootloader_util.c +++ b/components/libraries/bootloader/nrf_bootloader_app_start.c @@ -1,36 +1,52 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -#include "bootloader_util.h" #include -#include - +#include "nrf_bootloader_app_start.h" +#include "compiler_abstraction.h" +#include "nrf_log.h" +#include "nrf_dfu_mbr.h" +#include "nrf_sdm.h" -/** - * @brief Function for aborting current application/bootloader jump to to other app/bootloader. - * - * @details This functions will use the address provide to swap the stack pointer and then load - * the address of the reset handler to be executed. It will check current system mode - * (thread/handler) and if in thread mode it will reset into other application. - * If in handler mode \ref isr_abort will be executed to ensure correct exit of handler - * mode and jump into reset handler of other application. - * - * @param[in] start_addr Start address of other application. This address must point to the - initial stack pointer of the application. - * - * @note This function will never return but issue a reset into provided application. - */ #if defined ( __CC_ARM ) -__asm static void bootloader_util_reset(uint32_t start_addr) +__ASM static void nrf_bootloader_app_start_impl(uint32_t start_addr) { LDR R5, [R0] ; Get App initial MSP for bootloader. MSR MSP, R5 ; Set the main stack pointer to the applications MSP. @@ -64,10 +80,12 @@ isr_abort BX R0 ; No return - Handler mode will be exited. Stack will be popped and execution will continue in reset handler initializing other application. ALIGN } + #elif defined ( __GNUC__ ) -static inline void bootloader_util_reset(uint32_t start_addr) + +static void __attribute__ ((noinline)) nrf_bootloader_app_start_impl(uint32_t start_addr) { - __asm volatile( + __ASM volatile( "ldr r0, [%0]\t\n" // Get App initial MSP for bootloader. "msr msp, r0\t\n" // Set the main stack pointer to the applications MSP. "ldr r0, [%0, #0x04]\t\n" // Load Reset handler into R0. @@ -104,19 +122,21 @@ static inline void bootloader_util_reset(uint32_t start_addr) : "r0", "r4", "r5", "r6", "r7" // List of register maintained manually. ); } + #elif defined ( __ICCARM__ ) -static inline void bootloader_util_reset(uint32_t start_addr) + +static inline void nrf_bootloader_app_start_impl(uint32_t start_addr) { - asm("ldr r5, [%0]\n" // Get App initial MSP for bootloader. + __ASM("ldr r5, [%0]\n" // Get App initial MSP for bootloader. "msr msp, r5\n" // Set the main stack pointer to the applications MSP. "ldr r0, [%0, #0x04]\n" // Load Reset handler into R0. "movs r4, #0x00\n" // Load zero into R4. "mvns r4, r4\n" // Invert R4 to ensure it contain ones. - "mrs r5, IPSR\n" // Load IPSR to R5 to check for handler or thread mode + "mrs r5, IPSR\n" // Load IPSR to R5 to check for handler or thread mode "cmp r5, #0x00\n" // Compare, if 0 then we are in thread mode and can continue to reset handler of bootloader. - "bne isr_abort\n" // If not zero we need to exit current ISR and jump to reset handler of bootloader. + "bne.n isr_abort\n" // If not zero we need to exit current ISR and jump to reset handler of bootloader. "mov lr, r4\n" // Clear the link register and set to ones to ensure no return. "bx r0\n" // Branch to reset handler of bootloader. @@ -141,12 +161,51 @@ static inline void bootloader_util_reset(uint32_t start_addr) :: "r" (start_addr) // Argument list for the IAR assembly. start_addr is %0. : "r0", "r4", "r5", "r6", "r7"); // List of register maintained manually. } + #else + #error Compiler not supported. + #endif -void bootloader_util_app_start(uint32_t start_addr) +void nrf_bootloader_app_start(uint32_t start_addr) { - bootloader_util_reset(start_addr); + NRF_LOG_INFO("Running nrf_bootloader_app_start with address: 0x%08x\r\n", start_addr); + +#ifdef BLE_STACK_SUPPORT_REQD + uint32_t err_code; + + //NRF_LOG_INFO("Initializing SD in mbr\r\n"); + err_code = nrf_dfu_mbr_init_sd(); + if(err_code != NRF_SUCCESS) + { + NRF_LOG_INFO("Failed running nrf_dfu_mbr_init_sd\r\n"); + return; + } + +#endif + + // Disable interrupts + NRF_LOG_INFO("Disabling interrupts\r\n"); + + NVIC->ICER[0]=0xFFFFFFFF; +#if defined(__NRF_NVIC_ISER_COUNT) && __NRF_NVIC_ISER_COUNT == 2 + NVIC->ICER[1]=0xFFFFFFFF; +#endif + +#ifdef BLE_STACK_SUPPORT_REQD + // Set the sd softdevice vector table base address + NRF_LOG_INFO("Setting SD vector table base: 0x%08x\r\n", start_addr); + err_code = sd_softdevice_vector_table_base_set(start_addr); + if(err_code != NRF_SUCCESS) + { + NRF_LOG_INFO("Failed running sd_softdevice_vector_table_base_set\r\n"); + return; + } +#endif + + // Run application + nrf_bootloader_app_start_impl(start_addr); } + diff --git a/components/libraries/bootloader/nrf_bootloader_app_start.h b/components/libraries/bootloader/nrf_bootloader_app_start.h new file mode 100644 index 0000000..b78a07f --- /dev/null +++ b/components/libraries/bootloader/nrf_bootloader_app_start.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup sdk_bootloader_app Application start + * @{ + * @ingroup sdk_bootloader + */ + +#ifndef NRF_BOOTLOADER_APP_START_H__ +#define NRF_BOOTLOADER_APP_START_H__ + +#include + +/**@brief Function for starting another application (and aborting the current one). + * + * @details This function uses the provided address to swap the stack pointer and then load + * the address of the reset handler to be executed. It checks the current system mode + * (thread/handler). If in thread mode, it resets into the other application. + * If in handler mode, isr_abort is executed to ensure that handler mode is left correctly. + * It then jumps into the reset handler of the other application. + * + * @note This function will never return, but issues a reset into the provided application. + * + * @param[in] start_addr Start address of the other application. This address must point to the + initial stack pointer of the application. + * + */ +void nrf_bootloader_app_start(uint32_t start_addr); + +#endif // NRF_BOOTLOADER_APP_START_H__ + +/** @} */ diff --git a/components/libraries/bootloader/nrf_bootloader_info.c b/components/libraries/bootloader/nrf_bootloader_info.c new file mode 100644 index 0000000..84fd23b --- /dev/null +++ b/components/libraries/bootloader/nrf_bootloader_info.c @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_bootloader_info.h" + + +/** @brief This variable ensures that the linker script will write the bootloader start address + * to the UICR register. This value will be written in the HEX file and thus written to + * UICR when the bootloader is flashed into the chip. + */ +#if defined (__CC_ARM ) + #pragma push + #pragma diag_suppress 1296 + uint32_t m_uicr_bootloader_start_address __attribute__((at(NRF_UICR_BOOTLOADER_START_ADDRESS))) + = BOOTLOADER_START_ADDR; + #pragma pop +#elif defined ( __GNUC__ ) + volatile uint32_t m_uicr_bootloader_start_address __attribute__ ((section(".uicrBootStartAddress"))) + = BOOTLOADER_START_ADDR; +#elif defined ( __ICCARM__ ) + __root const uint32_t m_uicr_bootloader_start_address @ NRF_UICR_BOOTLOADER_START_ADDRESS + = BOOTLOADER_START_ADDR; +#endif diff --git a/components/libraries/bootloader/nrf_bootloader_info.h b/components/libraries/bootloader/nrf_bootloader_info.h new file mode 100644 index 0000000..f9d1e76 --- /dev/null +++ b/components/libraries/bootloader/nrf_bootloader_info.h @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup sdk_bootloader_info Information + * @{ + * @ingroup sdk_bootloader + */ + +#ifndef NRF_BOOTLOADER_INFO_H__ +#define NRF_BOOTLOADER_INFO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf.h" + +#ifdef SOFTDEVICE_PRESENT +#include "nrf_sdm.h" +#endif + +/** @brief External definitions of symbols for the start of the application image. + */ +#if (__LINT__ == 1) + // No implementation +#elif defined ( __CC_ARM ) + extern uint32_t* Image$$ER_IROM1$$Base __attribute__((used)); +#elif defined ( __GNUC__ ) + extern uint32_t * __isr_vector; +#elif defined ( __ICCARM__ ) + extern void * __vector_table; +#else + #error Not a valid compiler/linker for application image symbols. +#endif + + +/** @brief Macro for getting the start address of the application image. + * + * This macro is valid only when absolute placement is used for the application + * image. The macro is not a compile time symbol. It cannot be used as a + * constant expression, for example, inside a static assert or linker script + * at-placement. + */ +#if (__LINT__ == 1) + #define BOOTLOADER_START_ADDR (0x3AC00) +#elif BOOTLOADER_START_ADDR + // Bootloader start address is defined at project level +#elif defined (__CC_ARM) + #define BOOTLOADER_START_ADDR (uint32_t)&Image$$ER_IROM1$$Base +#elif defined (__GNUC__) + #define BOOTLOADER_START_ADDR (uint32_t)&__isr_vector +#elif defined (__ICCARM__) + #define BOOTLOADER_START_ADDR (uint32_t)&__vector_table +#else + #error Not a valid compiler/linker for BOOTLOADER_START_ADDR. +#endif + + +/** + * @brief Bootloader start address in UICR. + * + * Register location in UICR where the bootloader start address is stored. + * + * @note If the value at the given location is 0xFFFFFFFF, the bootloader address is not set. + */ +#define NRF_UICR_BOOTLOADER_START_ADDRESS (NRF_UICR_BASE + 0x14) + + +#ifndef MAIN_APPLICATION_START_ADDR + + +#ifdef SOFTDEVICE_PRESENT + +/** @brief Main application start address (if the project uses a SoftDevice). + * + * @note The start address is equal to the end address of the SoftDevice. + */ +#define MAIN_APPLICATION_START_ADDR (SD_SIZE_GET(MBR_SIZE)) + +#else + +/** @brief Main application start address if the project does not use a SoftDevice. + * + * @note The MBR is required for the @ref sdk_bootloader to function. + */ +#define MAIN_APPLICATION_START_ADDR (MBR_SIZE) + +#endif + +#endif // #ifndef MAIN_APPLICATION_START_ADDR + + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef NRF_BOOTLOADER_INFO_H__ +/** @} */ diff --git a/components/libraries/bootloader_dfu/ble_transport/hci_mem_pool_internal.h b/components/libraries/bootloader_dfu/ble_transport/hci_mem_pool_internal.h deleted file mode 100644 index 2e3e4fc..0000000 --- a/components/libraries/bootloader_dfu/ble_transport/hci_mem_pool_internal.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/** @file - * - * @defgroup memory_pool_internal Memory Pool Internal - * @{ - * @ingroup memory_pool - * - * @brief Memory pool internal definitions - */ - -#ifndef MEM_POOL_INTERNAL_H__ -#define MEM_POOL_INTERNAL_H__ - -#define TX_BUF_SIZE 4u /**< TX buffer size in bytes. */ -#define RX_BUF_SIZE 32u /**< RX buffer size in bytes. */ - -#define RX_BUF_QUEUE_SIZE 8u /**< RX buffer element size. */ - -#endif // MEM_POOL_INTERNAL_H__ - -/** @} */ diff --git a/components/libraries/bootloader_dfu/bootloader.c b/components/libraries/bootloader_dfu/bootloader.c deleted file mode 100644 index e40ca76..0000000 --- a/components/libraries/bootloader_dfu/bootloader.c +++ /dev/null @@ -1,387 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "bootloader.h" -#include -#include "bootloader_types.h" -#include "bootloader_util.h" -#include "bootloader_settings.h" -#include "dfu.h" -#include "dfu_transport.h" -#include "nrf.h" -#include "app_error.h" -#include "nrf_sdm.h" -#include "nordic_common.h" -#include "crc16.h" -#include "pstorage.h" -#include "app_scheduler.h" -#include "nrf_delay.h" - -#define IRQ_ENABLED 0x01 /**< Field identifying if an interrupt is enabled. */ -#define MAX_NUMBER_INTERRUPTS 32 /**< Maximum number of interrupts available. */ - -/**@brief Enumeration for specifying current bootloader status. - */ -typedef enum -{ - BOOTLOADER_UPDATING, /**< Bootloader status for indicating that an update is in progress. */ - BOOTLOADER_SETTINGS_SAVING, /**< Bootloader status for indicating that saving of bootloader settings is in progress. */ - BOOTLOADER_COMPLETE, /**< Bootloader status for indicating that all operations for the update procedure has completed and it is safe to reset the system. */ - BOOTLOADER_TIMEOUT, /**< Bootloader status field for indicating that a timeout has occured and current update process should be aborted. */ - BOOTLOADER_RESET, /**< Bootloader status field for indicating that a reset has been requested and current update process should be aborted. */ -} bootloader_status_t; - -static pstorage_handle_t m_bootsettings_handle; /**< Pstorage handle to use for registration and identifying the bootloader module on subsequent calls to the pstorage module for load and store of bootloader setting in flash. */ -static bootloader_status_t m_update_status; /**< Current update status for the bootloader module to ensure correct behaviour when updating settings and when update completes. */ - -/**@brief Function for handling callbacks from pstorage module. - * - * @details Handles pstorage results for clear and storage operation. For detailed description of - * the parameters provided with the callback, please refer to \ref pstorage_ntf_cb_t. - */ -static void pstorage_callback_handler(pstorage_handle_t * p_handle, - uint8_t op_code, - uint32_t result, - uint8_t * p_data, - uint32_t data_len) -{ - // If we are in BOOTLOADER_SETTINGS_SAVING state and we receive an PSTORAGE_STORE_OP_CODE - // response then settings has been saved and update has completed. - if ((m_update_status == BOOTLOADER_SETTINGS_SAVING) && (op_code == PSTORAGE_STORE_OP_CODE)) - { - m_update_status = BOOTLOADER_COMPLETE; - } - - APP_ERROR_CHECK(result); -} - - -/**@brief Function for waiting for events. - * - * @details This function will place the chip in low power mode while waiting for events from - * the SoftDevice or other peripherals. When interrupted by an event, it will call the - * @ref app_sched_execute function to process the received event. This function will return - * when the final state of the firmware update is reached OR when a tear down is in - * progress. - */ -static void wait_for_events(void) -{ - for (;;) - { - // Wait in low power state for any events. - uint32_t err_code = sd_app_evt_wait(); - APP_ERROR_CHECK(err_code); - - // Event received. Process it from the scheduler. - app_sched_execute(); - - if ((m_update_status == BOOTLOADER_COMPLETE) || - (m_update_status == BOOTLOADER_TIMEOUT) || - (m_update_status == BOOTLOADER_RESET)) - { - // When update has completed or a timeout/reset occured we will return. - return; - } - } -} - - -bool bootloader_app_is_valid(uint32_t app_addr) -{ - const bootloader_settings_t * p_bootloader_settings; - - // There exists an application in CODE region 1. - if (*((uint32_t *)app_addr) == EMPTY_FLASH_MASK) - { - return false; - } - - bool success = false; - - bootloader_util_settings_get(&p_bootloader_settings); - - // The application in CODE region 1 is flagged as valid during update. - if (p_bootloader_settings->bank_0 == BANK_VALID_APP) - { - uint16_t image_crc = 0; - - // A stored crc value of 0 indicates that CRC checking is not used. - if (p_bootloader_settings->bank_0_crc != 0) - { - image_crc = crc16_compute((uint8_t *)DFU_BANK_0_REGION_START, - p_bootloader_settings->bank_0_size, - NULL); - } - - success = (image_crc == p_bootloader_settings->bank_0_crc); - } - - return success; -} - - -static void bootloader_settings_save(bootloader_settings_t * p_settings) -{ - uint32_t err_code = pstorage_clear(&m_bootsettings_handle, sizeof(bootloader_settings_t)); - APP_ERROR_CHECK(err_code); - - err_code = pstorage_store(&m_bootsettings_handle, - (uint8_t *)p_settings, - sizeof(bootloader_settings_t), - 0); - APP_ERROR_CHECK(err_code); -} - - -void bootloader_dfu_update_process(dfu_update_status_t update_status) -{ - static bootloader_settings_t settings; - const bootloader_settings_t * p_bootloader_settings; - - bootloader_util_settings_get(&p_bootloader_settings); - - if (update_status.status_code == DFU_UPDATE_APP_COMPLETE) - { - settings.bank_0_crc = update_status.app_crc; - settings.bank_0_size = update_status.app_size; - settings.bank_0 = BANK_VALID_APP; - settings.bank_1 = BANK_INVALID_APP; - - m_update_status = BOOTLOADER_SETTINGS_SAVING; - bootloader_settings_save(&settings); - } - else if (update_status.status_code == DFU_UPDATE_SD_COMPLETE) - { - settings.bank_0_crc = update_status.app_crc; - settings.bank_0_size = update_status.sd_size + - update_status.bl_size + - update_status.app_size; - settings.bank_0 = BANK_VALID_SD; - settings.bank_1 = BANK_INVALID_APP; - settings.sd_image_size = update_status.sd_size; - settings.bl_image_size = update_status.bl_size; - settings.app_image_size = update_status.app_size; - settings.sd_image_start = update_status.sd_image_start; - - m_update_status = BOOTLOADER_SETTINGS_SAVING; - bootloader_settings_save(&settings); - } - else if (update_status.status_code == DFU_UPDATE_BOOT_COMPLETE) - { - settings.bank_0 = p_bootloader_settings->bank_0; - settings.bank_0_crc = p_bootloader_settings->bank_0_crc; - settings.bank_0_size = p_bootloader_settings->bank_0_size; - settings.bank_1 = BANK_VALID_BOOT; - settings.sd_image_size = update_status.sd_size; - settings.bl_image_size = update_status.bl_size; - settings.app_image_size = update_status.app_size; - - m_update_status = BOOTLOADER_SETTINGS_SAVING; - bootloader_settings_save(&settings); - } - else if (update_status.status_code == DFU_UPDATE_SD_SWAPPED) - { - if (p_bootloader_settings->bank_0 == BANK_VALID_SD) - { - settings.bank_0_crc = 0; - settings.bank_0_size = 0; - settings.bank_0 = BANK_INVALID_APP; - } - // This handles cases where SoftDevice was not updated, hence bank0 keeps its settings. - else - { - settings.bank_0 = p_bootloader_settings->bank_0; - settings.bank_0_crc = p_bootloader_settings->bank_0_crc; - settings.bank_0_size = p_bootloader_settings->bank_0_size; - } - - settings.bank_1 = BANK_INVALID_APP; - settings.sd_image_size = 0; - settings.bl_image_size = 0; - settings.app_image_size = 0; - - m_update_status = BOOTLOADER_SETTINGS_SAVING; - bootloader_settings_save(&settings); - } - else if (update_status.status_code == DFU_TIMEOUT) - { - // Timeout has occurred. Close the connection with the DFU Controller. - uint32_t err_code = dfu_transport_close(); - APP_ERROR_CHECK(err_code); - - m_update_status = BOOTLOADER_TIMEOUT; - } - else if (update_status.status_code == DFU_BANK_0_ERASED) - { - settings.bank_0_crc = 0; - settings.bank_0_size = 0; - settings.bank_0 = BANK_INVALID_APP; - settings.bank_1 = p_bootloader_settings->bank_1; - - bootloader_settings_save(&settings); - } - else if (update_status.status_code == DFU_RESET) - { - m_update_status = BOOTLOADER_RESET; - } - else - { - // No implementation needed. - } -} - - -uint32_t bootloader_init(void) -{ - uint32_t err_code; - pstorage_module_param_t storage_params = {.cb = pstorage_callback_handler}; - - err_code = pstorage_init(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - m_bootsettings_handle.block_id = BOOTLOADER_SETTINGS_ADDRESS; - err_code = pstorage_register(&storage_params, &m_bootsettings_handle); - - return err_code; -} - - -uint32_t bootloader_dfu_start(void) -{ - uint32_t err_code; - - // Clear swap if banked update is used. - err_code = dfu_init(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = dfu_transport_update_start(); - - wait_for_events(); - - return err_code; -} - - -/**@brief Function for disabling all interrupts before jumping from bootloader to application. - */ -static void interrupts_disable(void) -{ - uint32_t interrupt_setting_mask; - uint32_t irq = 0; // We start from first interrupt, i.e. interrupt 0. - - // Fetch the current interrupt settings. - interrupt_setting_mask = NVIC->ISER[0]; - - for (; irq < MAX_NUMBER_INTERRUPTS; irq++) - { - if (interrupt_setting_mask & (IRQ_ENABLED << irq)) - { - // The interrupt was enabled, and hence disable it. - NVIC_DisableIRQ((IRQn_Type)irq); - } - } -} - - -void bootloader_app_start(uint32_t app_addr) -{ - // If the applications CRC has been checked and passed, the magic number will be written and we - // can start the application safely. - uint32_t err_code = sd_softdevice_disable(); - APP_ERROR_CHECK(err_code); - - interrupts_disable(); - - err_code = sd_softdevice_vector_table_base_set(CODE_REGION_1_START); - APP_ERROR_CHECK(err_code); - - bootloader_util_app_start(CODE_REGION_1_START); -} - - -bool bootloader_dfu_sd_in_progress(void) -{ - const bootloader_settings_t * p_bootloader_settings; - - bootloader_util_settings_get(&p_bootloader_settings); - - if (p_bootloader_settings->bank_0 == BANK_VALID_SD || - p_bootloader_settings->bank_1 == BANK_VALID_BOOT) - { - return true; - } - - return false; -} - - -uint32_t bootloader_dfu_sd_update_continue(void) -{ - uint32_t err_code; - - if ((dfu_sd_image_validate() == NRF_SUCCESS) && - (dfu_bl_image_validate() == NRF_SUCCESS)) - { - return NRF_SUCCESS; - } - - // Ensure that flash operations are not executed within the first 100 ms seconds to allow - // a debugger to be attached. - nrf_delay_ms(100); - - err_code = dfu_sd_image_swap(); - APP_ERROR_CHECK(err_code); - - err_code = dfu_sd_image_validate(); - APP_ERROR_CHECK(err_code); - - err_code = dfu_bl_image_swap(); - APP_ERROR_CHECK(err_code); - - return err_code; -} - - -uint32_t bootloader_dfu_sd_update_finalize(void) -{ - dfu_update_status_t update_status = {DFU_UPDATE_SD_SWAPPED, }; - - bootloader_dfu_update_process(update_status); - - wait_for_events(); - - return NRF_SUCCESS; -} - - -void bootloader_settings_get(bootloader_settings_t * const p_settings) -{ - const bootloader_settings_t * p_bootloader_settings; - - bootloader_util_settings_get(&p_bootloader_settings); - - p_settings->bank_0 = p_bootloader_settings->bank_0; - p_settings->bank_0_crc = p_bootloader_settings->bank_0_crc; - p_settings->bank_0_size = p_bootloader_settings->bank_0_size; - p_settings->bank_1 = p_bootloader_settings->bank_1; - p_settings->sd_image_size = p_bootloader_settings->sd_image_size; - p_settings->bl_image_size = p_bootloader_settings->bl_image_size; - p_settings->app_image_size = p_bootloader_settings->app_image_size; - p_settings->sd_image_start = p_bootloader_settings->sd_image_start; -} - diff --git a/components/libraries/bootloader_dfu/bootloader.h b/components/libraries/bootloader_dfu/bootloader.h deleted file mode 100644 index aa61258..0000000 --- a/components/libraries/bootloader_dfu/bootloader.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup nrf_bootloader Bootloader API. - * @{ - * - * @brief Bootloader module interface. - */ - -#ifndef BOOTLOADER_H__ -#define BOOTLOADER_H__ - -#include -#include -#include "bootloader_types.h" -#include - -/**@brief Function for initializing the Bootloader. - * - * @retval NRF_SUCCESS If bootloader was succesfully initialized. - */ -uint32_t bootloader_init(void); - -/**@brief Function for validating application region in flash. - * - * @param[in] app_addr Address to the region in flash where the application is stored. - * - * @retval true If Application region is valid. - * @retval false If Application region is not valid. - */ -bool bootloader_app_is_valid(uint32_t app_addr); - -/**@brief Function for starting the Device Firmware Update. - * - * @retval NRF_SUCCESS If new application image was successfully transferred. - */ -uint32_t bootloader_dfu_start(void); - -/**@brief Function for exiting bootloader and booting into application. - * - * @details This function will disable SoftDevice and all interrupts before jumping to application. - * The SoftDevice vector table base for interrupt forwarding will be set the application - * address. - * - * @param[in] app_addr Address to the region where the application is stored. - */ -void bootloader_app_start(uint32_t app_addr); - -/**@brief Function for retrieving the bootloader settings. - * - * @param[out] p_settings A copy of the current bootloader settings is returned in the structure - * provided. - */ -void bootloader_settings_get(bootloader_settings_t * const p_settings); - -/**@brief Function for processing DFU status update. - * - * @param[in] update_status DFU update status. - */ -void bootloader_dfu_update_process(dfu_update_status_t update_status); - -/**@brief Function getting state of SoftDevice update in progress. - * After a successfull SoftDevice transfer the system restarts in orderto disable SoftDevice - * and complete the update. - * - * @retval true A SoftDevice update is in progress. This indicates that second stage - * of a SoftDevice update procedure can be initiated. - * @retval false No SoftDevice update is in progress. - */ -bool bootloader_dfu_sd_in_progress(void); - -/**@brief Function for continuing the Device Firmware Update of a SoftDevice. - * - * @retval NRF_SUCCESS If the final stage of SoftDevice update was successful. - */ -uint32_t bootloader_dfu_sd_update_continue(void); - -/**@brief Function for finalizing the Device Firmware Update of a SoftDevice. - * - * @retval NRF_SUCCESS If the final stage of SoftDevice update was successful. - */ -uint32_t bootloader_dfu_sd_update_finalize(void); - -#endif // BOOTLOADER_H__ - -/**@} */ diff --git a/components/libraries/bootloader_dfu/bootloader_settings.c b/components/libraries/bootloader_dfu/bootloader_settings.c deleted file mode 100644 index a5e7759..0000000 --- a/components/libraries/bootloader_dfu/bootloader_settings.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "bootloader_settings.h" -#include -#include - -#if defined ( __CC_ARM ) -uint8_t m_boot_settings[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS))) __attribute__((used)); /**< This variable reserves a codepage for bootloader specific settings, to ensure the compiler doesn't locate any code or variables at his location. */ -uint32_t m_uicr_bootloader_start_address __attribute__((at(NRF_UICR_BOOT_START_ADDRESS))) = BOOTLOADER_REGION_START; /**< This variable ensures that the linker script will write the bootloader start address to the UICR register. This value will be written in the HEX file and thus written to UICR when the bootloader is flashed into the chip. */ -#elif defined ( __GNUC__ ) -__attribute__ ((section(".bootloaderSettings"))) uint8_t m_boot_settings[CODE_PAGE_SIZE]; /**< This variable reserves a codepage for bootloader specific settings, to ensure the compiler doesn't locate any code or variables at his location. */ -__attribute__ ((section(".uicrBootStartAddress"))) volatile uint32_t m_uicr_bootloader_start_address = BOOTLOADER_REGION_START; /**< This variable ensures that the linker script will write the bootloader start address to the UICR register. This value will be written in the HEX file and thus written to UICR when the bootloader is flashed into the chip. */ -#elif defined ( __ICCARM__ ) -__no_init uint8_t m_boot_settings[CODE_PAGE_SIZE] @ 0x0003FC00; /**< This variable reserves a codepage for bootloader specific settings, to ensure the compiler doesn't locate any code or variables at his location. */ -__root const uint32_t m_uicr_bootloader_start_address @ 0x10001014 = BOOTLOADER_REGION_START; /**< This variable ensures that the linker script will write the bootloader start address to the UICR register. This value will be written in the HEX file and thus written to UICR when the bootloader is flashed into the chip. */ -#endif - - -void bootloader_util_settings_get(const bootloader_settings_t ** pp_bootloader_settings) -{ - // Read only pointer to bootloader settings in flash. - bootloader_settings_t const * const p_bootloader_settings = - (bootloader_settings_t *)&m_boot_settings[0]; - - *pp_bootloader_settings = p_bootloader_settings; -} diff --git a/components/libraries/bootloader_dfu/bootloader_settings.h b/components/libraries/bootloader_dfu/bootloader_settings.h deleted file mode 100644 index 645b7f4..0000000 --- a/components/libraries/bootloader_dfu/bootloader_settings.h +++ /dev/null @@ -1,35 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - - /**@file - * - * @defgroup nrf_bootloader_settings Bootloader settings API. - * @{ - * - * @brief Bootloader settings module interface. - */ - -#ifndef BOOTLOADER_SETTINGS_H__ -#define BOOTLOADER_SETTINGS_H__ - -#include -#include "bootloader_types.h" - -/**@brief Function for getting the bootloader settings. - * - * @param[out] pp_bootloader_settings Bootloader settings. - */ -void bootloader_util_settings_get(const bootloader_settings_t ** pp_bootloader_settings); - -#endif // BOOTLOADER_SETTINGS_H__ - -/**@} */ diff --git a/components/libraries/bootloader_dfu/bootloader_types.h b/components/libraries/bootloader_dfu/bootloader_types.h deleted file mode 100644 index da3ce2c..0000000 --- a/components/libraries/bootloader_dfu/bootloader_types.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup nrf_bootloader_types Types and definitions. - * @{ - * - * @ingroup nrf_bootloader - * - * @brief Bootloader module type and definitions. - */ - -#ifndef BOOTLOADER_TYPES_H__ -#define BOOTLOADER_TYPES_H__ - -#include - -#define BOOTLOADER_DFU_START 0xB1 - -#define BOOTLOADER_SVC_APP_DATA_PTR_GET 0x02 - -/**@brief DFU Bank state code, which indicates wether the bank contains: A valid image, invalid image, or an erased flash. - */ -typedef enum -{ - BANK_VALID_APP = 0x01, - BANK_VALID_SD = 0xA5, - BANK_VALID_BOOT = 0xAA, - BANK_ERASED = 0xFE, - BANK_INVALID_APP = 0xFF, -} bootloader_bank_code_t; - -/**@brief Structure holding bootloader settings for application and bank data. - */ -typedef struct -{ - bootloader_bank_code_t bank_0; /**< Variable to store if bank 0 contains a valid application. */ - uint16_t bank_0_crc; /**< If bank is valid, this field will contain a valid CRC of the total image. */ - bootloader_bank_code_t bank_1; /**< Variable to store if bank 1 has been erased/prepared for new image. Bank 1 is only used in Banked Update scenario. */ - uint32_t bank_0_size; /**< Size of active image in bank0 if present, otherwise 0. */ - uint32_t sd_image_size; /**< Size of SoftDevice image in bank0 if bank_0 code is BANK_VALID_SD. */ - uint32_t bl_image_size; /**< Size of Bootloader image in bank0 if bank_0 code is BANK_VALID_SD. */ - uint32_t app_image_size; /**< Size of Application image in bank0 if bank_0 code is BANK_VALID_SD. */ - uint32_t sd_image_start; /**< Location in flash where SoftDevice image is stored for SoftDevice update. */ -} bootloader_settings_t; - -#endif // BOOTLOADER_TYPES_H__ - -/**@} */ diff --git a/components/libraries/bootloader_dfu/bootloader_util.h b/components/libraries/bootloader_dfu/bootloader_util.h deleted file mode 100644 index 1e09e2d..0000000 --- a/components/libraries/bootloader_dfu/bootloader_util.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - - /**@file - * - * @defgroup nrf_bootloader_util Bootloader util API. - * @{ - * - * @brief Bootloader util module interface. - */ - -#ifndef BOOTLOADER_UTIL_H__ -#define BOOTLOADER_UTIL_H__ - -#include -#include "bootloader_types.h" - -/**@brief Function for starting the application (or bootloader) at the provided address. - * - * @param[in] start_addr Start address. - * - * @note This function will never retrun. Instead it will reset into the application of the - * provided address. - */ -void bootloader_util_app_start(uint32_t start_addr); - -#endif // BOOTLOADER_UTIL_H__ - -/**@} */ diff --git a/components/libraries/bootloader_dfu/dfu.h b/components/libraries/bootloader_dfu/dfu.h deleted file mode 100644 index 9832180..0000000 --- a/components/libraries/bootloader_dfu/dfu.h +++ /dev/null @@ -1,134 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup nrf_dfu Device Firmware Update API. - * @{ - * - * @brief Device Firmware Update module interface. - */ - -#ifndef DFU_H__ -#define DFU_H__ - -#include -#include -#include - - -/**@brief DFU event callback for asynchronous calls. - * - * @param[in] packet Packet type for which this callback is related. START_PACKET, DATA_PACKET. - * @param[in] result Operation result code. NRF_SUCCESS when a queued operation was successful. - * @param[in] p_data Pointer to the data to which the operation is related. - */ -typedef void (*dfu_callback_t)(uint32_t packet, uint32_t result, uint8_t * p_data); - -/**@brief Function for initializing the Device Firmware Update module. - * - * @return NRF_SUCCESS on success, an error_code otherwise. - */ -uint32_t dfu_init(void); - -/**@brief Function for registering a callback listener for \ref dfu_data_pkt_handle callbacks. - * - * @param[in] callback_handler Callback handler for receiving DFU events on completed operations - * of DFU packets. - */ -void dfu_register_callback(dfu_callback_t callback_handler); - -/**@brief Function for setting the DFU image size. - * - * @details Function sets the DFU image size. This function must be called when an update is started - * in order to notify the DFU of the new image size. If multiple images are to be - * transferred within the same update context then this function must be called with size - * information for each image being transfered. - * If an image type is not being transfered, e.g. SoftDevice but no Application , then the - * image size for application must be zero. - * - * @param[in] p_packet Pointer to the DFU packet containing information on DFU update process to - * be started. - * - * @return NRF_SUCCESS on success, an error_code otherwise. - */ -uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet); - -/**@brief Function for handling DFU data packets. - * - * @param[in] p_packet Pointer to the DFU packet. - * - * @return NRF_SUCCESS on success, an error_code otherwise. - */ -uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet); - -/**@brief Function for handling DFU init packets. - * - * @return NRF_SUCCESS on success, an error_code otherwise. - */ -uint32_t dfu_init_pkt_handle(dfu_update_packet_t * p_packet); - -/**@brief Function for validating a transferred image after the transfer has completed. - * - * @return NRF_SUCCESS on success, an error_code otherwise. - */ -uint32_t dfu_image_validate(void); - -/**@brief Function for activating the transfered image after validation has successfully completed. - * - * @return NRF_SUCCESS on success, an error_code otherwise. - */ -uint32_t dfu_image_activate(void); - -/**@brief Function for reseting the current update procedure and return to initial state. - * - * @details This function call will result in a system reset to ensure correct system behavior. - * The reset will might be scheduled to execute at a later point in time to ensure pending - * flash operations has completed. - */ -void dfu_reset(void); - -/**@brief Function for validating that new bootloader has been correctly installed. - * - * @return NRF_SUCCESS if install was successful. NRF_ERROR_NULL if the images differs. - */ -uint32_t dfu_bl_image_validate(void); - -/**@brief Function for validating that new SoftDevicehas been correctly installed. - * - * @return NRF_SUCCESS if install was successful. NRF_ERROR_NULL if the images differs. - */ -uint32_t dfu_sd_image_validate(void); - -/**@brief Function for swapping existing bootloader with newly received. - * - * @return NRF_SUCCESS on succesfull swapping. For error code please refer to - * \ref sd_mbr_command_copy_bl_t. - */ -uint32_t dfu_bl_image_swap(void); - -/**@brief Function for swapping existing SoftDevice with newly received. - * - * @return NRF_SUCCESS on succesfull swapping. For error code please refer to - * \ref sd_mbr_command_copy_sd_t. - */ -uint32_t dfu_sd_image_swap(void); - -/**@brief Function for handling DFU init packet complete. - * - * @return NRF_SUCCESS on success, an error_code otherwise. - */ -uint32_t dfu_init_pkt_complete(void); - -#endif // DFU_H__ - -/** @} */ diff --git a/components/libraries/bootloader_dfu/dfu_app_handler.c b/components/libraries/bootloader_dfu/dfu_app_handler.c deleted file mode 100644 index 2a644e4..0000000 --- a/components/libraries/bootloader_dfu/dfu_app_handler.c +++ /dev/null @@ -1,192 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "dfu_app_handler.h" -#include -#include "bootloader_util.h" -#include "nrf.h" -#include "nrf_sdm.h" -#include "ble_gatt.h" -#include "ble_gatts.h" -#include "app_error.h" -#include "dfu_ble_svc.h" -#include "device_manager.h" -#include "nrf_delay.h" - -#define IRQ_ENABLED 0x01 /**< Field that identifies if an interrupt is enabled. */ -#define MAX_NUMBER_INTERRUPTS 32 /**< Maximum number of interrupts available. */ - -static void dfu_app_reset_prepare(void); /**< Forward declaration of default reset handler. */ -static dfu_app_reset_prepare_t m_reset_prepare = dfu_app_reset_prepare; /**< Callback function to application to prepare for system reset. Allows application to clean up service and memory before reset. */ -static dfu_ble_peer_data_t m_peer_data; /**< Peer data to be used for data exchange when resetting into DFU mode. */ -static dm_handle_t m_dm_handle; /**< Device Manager handle with instance IDs of current BLE connection. */ - - -/**@brief Function for reset_prepare handler if the application has not registered a handler. - */ -static void dfu_app_reset_prepare(void) -{ - // Reset prepare should be handled by application. - // This function can be extended to include default handling if application does not implement - // own handler. -} - - -/**@brief Function for disabling all interrupts before jumping from bootloader to application. - */ -static void interrupts_disable(void) -{ - uint32_t interrupt_setting_mask; - uint32_t irq; - - // Fetch the current interrupt settings. - interrupt_setting_mask = NVIC->ISER[0]; - - // Loop from interrupt 0 for disabling of all interrupts. - for (irq = 0; irq < MAX_NUMBER_INTERRUPTS; irq++) - { - if (interrupt_setting_mask & (IRQ_ENABLED << irq)) - { - // The interrupt was enabled, hence disable it. - NVIC_DisableIRQ((IRQn_Type)irq); - } - } -} - - -/**@brief Function for providing peer information to DFU for re-establishing a bonded connection in - * DFU mode. - * - * @param[in] conn_handle Connection handle for the connection requesting DFU mode. - */ -static void dfu_app_peer_data_set(uint16_t conn_handle) -{ - uint32_t err_code; - dm_sec_keyset_t key_set; - uint32_t app_context_data = 0; - dm_application_context_t app_context; - - -/** [DFU bond sharing] */ - err_code = dm_handle_get(conn_handle, &m_dm_handle); - if (err_code == NRF_SUCCESS) - { - err_code = dm_distributed_keys_get(&m_dm_handle, &key_set); - if (err_code == NRF_SUCCESS) - { - APP_ERROR_CHECK(err_code); - - m_peer_data.addr = key_set.keys_central.p_id_key->id_addr_info; - m_peer_data.irk = key_set.keys_central.p_id_key->id_info; - m_peer_data.enc_key.enc_info = key_set.keys_periph.enc_key.p_enc_key->enc_info; - m_peer_data.enc_key.master_id = key_set.keys_periph.enc_key.p_enc_key->master_id; - - err_code = dfu_ble_svc_peer_data_set(&m_peer_data); - APP_ERROR_CHECK(err_code); - - app_context_data = (DFU_APP_ATT_TABLE_CHANGED << DFU_APP_ATT_TABLE_POS); - app_context.len = sizeof(app_context_data); - app_context.p_data = (uint8_t *)&app_context_data; - app_context.flags = 0; - - err_code = dm_application_context_set(&m_dm_handle, &app_context); - APP_ERROR_CHECK(err_code); - } - else - { - // Keys were not available, thus we have a non-encrypted connection. - err_code = dm_peer_addr_get(&m_dm_handle, &m_peer_data.addr); - APP_ERROR_CHECK(err_code); - - err_code = dfu_ble_svc_peer_data_set(&m_peer_data); - APP_ERROR_CHECK(err_code); - } - } -/** [DFU bond sharing] */ -} - - -/**@brief Function for preparing the reset, disabling SoftDevice, and jumping to the bootloader. - * - * @param[in] conn_handle Connection handle for peer requesting to enter DFU mode. - */ -static void bootloader_start(uint16_t conn_handle) -{ - uint32_t err_code; - uint16_t sys_serv_attr_len = sizeof(m_peer_data.sys_serv_attr); - - err_code = sd_ble_gatts_sys_attr_get(conn_handle, - m_peer_data.sys_serv_attr, - &sys_serv_attr_len, - BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS); - if (err_code != NRF_SUCCESS) - { - // Any error at this stage means the system service attributes could not be fetched. - // This means the service changed indication cannot be sent in DFU mode, but connection - // is still possible to establish. - } - - m_reset_prepare(); - - err_code = sd_power_gpregret_set(BOOTLOADER_DFU_START); - APP_ERROR_CHECK(err_code); - - err_code = sd_softdevice_disable(); - APP_ERROR_CHECK(err_code); - - err_code = sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR); - APP_ERROR_CHECK(err_code); - - dfu_app_peer_data_set(conn_handle); - - NVIC_ClearPendingIRQ(SWI2_IRQn); - interrupts_disable(); - bootloader_util_app_start(NRF_UICR->BOOTLOADERADDR); -} - - -void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) -{ - switch (p_evt->ble_dfu_evt_type) - { - case BLE_DFU_START: - // Starting the bootloader - will cause reset. - bootloader_start(p_dfu->conn_handle); - break; - - default: - { - // Unsupported event received from DFU Service. - // Send back BLE_DFU_RESP_VAL_NOT_SUPPORTED message to peer. - uint32_t err_code = ble_dfu_response_send(p_dfu, - BLE_DFU_START_PROCEDURE, - BLE_DFU_RESP_VAL_NOT_SUPPORTED); - APP_ERROR_CHECK(err_code); - } - break; - } -} - - -void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func) -{ - m_reset_prepare = reset_prepare_func; -} - - -void dfu_app_dm_appl_instance_set(dm_application_instance_t app_instance) -{ - uint32_t err_code; - - err_code = dm_application_instance_set(&app_instance, &m_dm_handle); - APP_ERROR_CHECK(err_code); -} diff --git a/components/libraries/bootloader_dfu/dfu_app_handler.h b/components/libraries/bootloader_dfu/dfu_app_handler.h deleted file mode 100644 index e923186..0000000 --- a/components/libraries/bootloader_dfu/dfu_app_handler.h +++ /dev/null @@ -1,86 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/** @file - * - * @defgroup nrf_dfu_app_handler DFU BLE packet handling in application - * @{ - * - * @brief Handling of DFU BLE packets in the application. - * - * @details This module implements the handling of DFU packets for switching - * from an application to the bootloader and start DFU mode. The DFU - * packets are transmitted over BLE. - * This module handles only the StartDFU packet, which allows a BLE - * application to expose support for the DFU Service. - * The actual DFU Service runs in a dedicated environment after a BLE - * disconnect and reset of the \nRFXX device. - * The host must reconnect and continue the update procedure with - * access to the full DFU Service. - * - * @note The application must propagate DFU events to this module by calling - * @ref dfu_app_on_dfu_evt from the @ref ble_dfu_evt_handler_t callback. - */ - -#ifndef DFU_APP_HANDLER_H__ -#define DFU_APP_HANDLER_H__ - -#include "ble_dfu.h" -#include "nrf_svc.h" -#include "bootloader_types.h" -#include "device_manager.h" - -#define DFU_APP_ATT_TABLE_POS 0 /**< Position for the ATT table changed setting. */ -#define DFU_APP_ATT_TABLE_CHANGED 1 /**< Value indicating that the ATT table might have changed. This value will be set in the application-specific context in Device Manager when entering DFU mode. */ - -/**@brief DFU application reset_prepare function. This function is a callback that allows the - * application to prepare for an upcoming application reset. - */ -typedef void (*dfu_app_reset_prepare_t)(void); - -/**@brief Function for handling events from the DFU Service. - * - * @details The application must inject this function into the DFU Service or propagate DFU events - * to the dfu_app_handler module by calling this function in the application-specific DFU event - * handler. - * - * @param[in] p_dfu Pointer to the DFU Service structure to which the include event relates. - * @param[in] p_evt Pointer to the DFU event. - */ -void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt); - -/**@brief Function for registering a function to prepare a reset. - * - * @details The provided function is executed before resetting the system into bootloader/DFU - * mode. By registering this function, the caller is notified before the reset and can - * thus prepare the application for reset. For example, the application can gracefully - * disconnect any peers on BLE, turn of LEDS, ensure that all pending flash operations - * have completed, and so on. - * - * @param[in] reset_prepare_func Function to be executed before a reset. - */ -void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func); - -/**@brief Function for setting the Device Manager application instance. - * - * @details This function allows to set the @ref dm_application_instance_t value that is returned by the - * Device Manager when the application registers using @ref dm_register. - * If this function is not called, it is not be possible to share bonding information - * from the application to the bootloader/DFU when entering DFU mode. - * - * @param[in] app_instance Value for the application instance in use. - */ -void dfu_app_dm_appl_instance_set(dm_application_instance_t app_instance); - -#endif // DFU_APP_HANDLER_H__ - -/** @} */ diff --git a/components/libraries/bootloader_dfu/dfu_bank_internal.h b/components/libraries/bootloader_dfu/dfu_bank_internal.h deleted file mode 100644 index ac2b520..0000000 --- a/components/libraries/bootloader_dfu/dfu_bank_internal.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup dfu_bank_internal Device Firmware Update internal header for bank handling in DFU. - * @{ - * - * @brief Device Firmware Update Bank handling module interface. - * - * @details This header is intended for shared definition and functions between single and dual bank - * implementations used for DFU support. It is not supposed to be used for external access - * to the DFU module. - * - */ -#ifndef DFU_BANK_INTERNAL_H__ -#define DFU_BANK_INTERNAL_H__ - -#include - -/**@brief States of the DFU state machine. */ -typedef enum -{ - DFU_STATE_INIT_ERROR, /**< State for: dfu_init(...) error. */ - DFU_STATE_IDLE, /**< State for: idle. */ - DFU_STATE_PREPARING, /**< State for: preparing, indicates that the flash is being erased and no data packets can be processed. */ - DFU_STATE_RDY, /**< State for: ready. */ - DFU_STATE_RX_INIT_PKT, /**< State for: receiving initialization packet. */ - DFU_STATE_RX_DATA_PKT, /**< State for: receiving data packet. */ - DFU_STATE_VALIDATE, /**< State for: validate. */ - DFU_STATE_WAIT_4_ACTIVATE /**< State for: waiting for dfu_image_activate(). */ -} dfu_state_t; - -#define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ -#define DFU_TIMEOUT_INTERVAL APP_TIMER_TICKS(120000, APP_TIMER_PRESCALER) /**< DFU timeout interval in units of timer ticks. */ - -#define IS_UPDATING_SD(START_PKT) ((START_PKT).dfu_update_mode & DFU_UPDATE_SD) /**< Macro for determining if a SoftDevice update is ongoing. */ -#define IS_UPDATING_BL(START_PKT) ((START_PKT).dfu_update_mode & DFU_UPDATE_BL) /**< Macro for determining if a Bootloader update is ongoing. */ -#define IS_UPDATING_APP(START_PKT) ((START_PKT).dfu_update_mode & DFU_UPDATE_APP) /**< Macro for determining if a Application update is ongoing. */ -#define IMAGE_WRITE_IN_PROGRESS() (m_data_received > 0) /**< Macro for determining if an image write is in progress. */ -#define IS_WORD_SIZED(SIZE) ((SIZE & (sizeof(uint32_t) - 1)) == 0) /**< Macro for checking that the provided is word sized. */ - -/**@cond NO_DOXYGEN */ -static uint32_t m_data_received; /**< Amount of received data. */ -/**@endcond */ - -/**@brief Type definition of function used for preparing of the bank before receiving of a - * software image. - * - * @param[in] image_size Size of software image being received. - */ -typedef void (*dfu_bank_prepare_t)(uint32_t image_size); - -/**@brief Type definition of function used for handling clear complete of the bank before - * receiving of a software image. - */ -typedef void (*dfu_bank_cleared_t)(void); - -/**@brief Type definition of function used for activating of the software image received. - * - * @return NRF_SUCCESS If the image has been successfully activated any other NRF_ERROR code in - * case of a failure. - */ -typedef uint32_t (*dfu_bank_activate_t)(void); - -/**@brief Structure for holding of function pointers for needed prepare and activate procedure for - * the requested update procedure. - */ -typedef struct -{ - dfu_bank_prepare_t prepare; /**< Function pointer to the prepare function called on start of update procedure. */ - dfu_bank_cleared_t cleared; /**< Function pointer to the cleared function called after prepare function completes. */ - dfu_bank_activate_t activate; /**< Function pointer to the activate function called on finalizing the update procedure. */ -} dfu_bank_func_t; - -#endif // DFU_BANK_INTERNAL_H__ - -/** @} */ diff --git a/components/libraries/bootloader_dfu/dfu_ble_svc.h b/components/libraries/bootloader_dfu/dfu_ble_svc.h deleted file mode 100644 index e05508f..0000000 --- a/components/libraries/bootloader_dfu/dfu_ble_svc.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/** @file - * - * @defgroup nrf_dfu_ble_svc DFU BLE SVC - * @{ - * - * @brief DFU BLE SVC in bootloader. The DFU BLE SuperVisor Calls allow an application to execute - * functions in the installed bootloader. - * - * @details This module implements handling of SuperVisor Calls in the bootloader. - * SuperVisor Calls allow for an application to execute calls into the bootloader. - * Currently, it is possible to exchange bonding information (like keys) from the - * application to a bootloader supporting DFU OTA using BLE, so the update process can be - * done through an already existing bond. - * - * @note The application must make sure that all SuperVisor Calls (SVC) are forwarded to the - * bootloader to ensure correct behavior. Forwarding of SVCs to the bootloader is - * done using the SoftDevice SVC @ref sd_softdevice_vector_table_base_set with the value - * present in @c NRF_UICR->BOOTLOADERADDR. - */ - -#ifndef DFU_BLE_SVC_H__ -#define DFU_BLE_SVC_H__ - -#include "nrf_svc.h" -#include -#include "ble_gap.h" -#include "nrf.h" -#include "nrf_soc.h" -#include "nrf_error_sdm.h" - -#define BOOTLOADER_SVC_BASE 0x0 /**< The number of the lowest SVC number reserved for the bootloader. */ -#define SYSTEM_SERVICE_ATT_SIZE 8 /**< Size of the system service attribute length including CRC-16 at the end. */ - -/**@brief The SVC numbers used by the SVC functions in the SoC library. */ -enum BOOTLOADER_SVCS -{ - DFU_BLE_SVC_PEER_DATA_SET = BOOTLOADER_SVC_BASE, /**< SVC number for the setting of peer data call. */ - BOOTLOADER_SVC_LAST -}; - -/**@brief DFU Peer data structure. - * - * @details This structure contains peer data needed for connection to a bonded device during DFU. - * The peer data must be provided by the application to the bootloader during buttonless - * update. See @ref dfu_ble_svc_peer_data_set. It contains bond information about the - * desired DFU peer. - */ -typedef struct -{ - ble_gap_addr_t addr; /**< BLE GAP address of the device that initiated the DFU process. */ - ble_gap_irk_t irk; /**< IRK of the device that initiated the DFU process if this device uses Private Resolvable Addresses. */ - ble_gap_enc_key_t enc_key; /**< Encryption key structure containing encrypted diversifier and LTK for re-establishing the bond. */ - uint8_t sys_serv_attr[SYSTEM_SERVICE_ATT_SIZE]; /**< System service attributes for restoring of Service Changed Indication setting in DFU mode. */ -} dfu_ble_peer_data_t; - -/**@brief SVC Function for setting peer data containing address, IRK, and LTK to establish bonded - * connection in DFU mode. - * - * @param[in] p_peer_data Pointer to the peer data containing keys for the connection. - * - * @retval NRF_ERROR_NULL If a NULL pointer was provided as argument. - * @retval NRF_SUCCESS If the function completed successfully. - */ -SVCALL(DFU_BLE_SVC_PEER_DATA_SET, uint32_t, dfu_ble_svc_peer_data_set(dfu_ble_peer_data_t * p_peer_data)); - -#endif // DFU_BLE_SVC_H__ - -/** @} */ diff --git a/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h b/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h deleted file mode 100644 index 6f05fbf..0000000 --- a/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/** @file - * - * @defgroup nrf_dfu_ble_svc_internal DFU BLE SVC internal - * @{ - * - * @brief DFU BLE SVC internal functions in bootloader. The DFU BLE SuperVisor Calls allow an - * application to execute functions in the installed bootloader. This interface provides - * internal Bootloader DFU functions for retrieving data exchanged through SuperVisor Calls. - * - */ - -#ifndef DFU_BLE_SVC_INTERNAL_H__ -#define DFU_BLE_SVC_INTERNAL_H__ - -#include -#include "dfu_ble_svc.h" -#include "ble_gap.h" - -/**@brief Internal bootloader/DFU function for retrieving peer data provided from application. - * - * @param[out] p_peer_data Peer data set by application to be used for DFU connection. - * - * @retval NRF_SUCCESS If peer data is valid and can be used for connection. - * @retval NRF_ERROR_NULL If p_peer_data is a NULL pointer. - * @retval NRF_ERROR_INVALID_DATA If peer data is not available or invalid. - */ -uint32_t dfu_ble_peer_data_get(dfu_ble_peer_data_t * p_peer_data); - -#endif // DFU_BLE_SVC_INTERNAL_H__ - -/** @} */ diff --git a/components/libraries/bootloader_dfu/dfu_dual_bank.c b/components/libraries/bootloader_dfu/dfu_dual_bank.c deleted file mode 100644 index 5426f67..0000000 --- a/components/libraries/bootloader_dfu/dfu_dual_bank.c +++ /dev/null @@ -1,869 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include -#include -#include "dfu.h" -#include -#include "dfu_bank_internal.h" -#include "nrf.h" -#include "nrf.h" -#include "app_util.h" -#include "nrf_sdm.h" -#include "app_error.h" -#include "nrf_error.h" -#include "app_timer.h" -#include "app_error.h" -#include "nordic_common.h" -#include "bootloader.h" -#include "bootloader_types.h" -#include "pstorage.h" -#include "nrf_mbr.h" -#include "dfu_init.h" - -static dfu_state_t m_dfu_state; /**< Current DFU state. */ -static uint32_t m_image_size; /**< Size of the image that will be transmitted. */ - -static dfu_start_packet_t m_start_packet; /**< Start packet received for this update procedure. Contains update mode and image sizes information to be used for image transfer. */ -static uint8_t m_init_packet[128]; /**< Init packet, can hold CRC, Hash, Signed Hash and similar, for image validation, integrety check and authorization checking. */ -static uint8_t m_init_packet_length; /**< Length of init packet received. */ -static uint16_t m_image_crc; /**< Calculated CRC of the image received. */ - -APP_TIMER_DEF(m_dfu_timer_id); /**< Application timer id. */ -static bool m_dfu_timed_out = false; /**< Boolean flag value for tracking DFU timer timeout state. */ - -static pstorage_handle_t m_storage_handle_swap; /**< Pstorage handle for the swap area (bank 1). Bank used when updating an application or bootloader without SoftDevice. */ -static pstorage_handle_t m_storage_handle_app; /**< Pstorage handle for the application area (bank 0). Bank used when updating a SoftDevice w/wo bootloader. Handle also used when swapping received application from bank 1 to bank 0. */ -static pstorage_handle_t * mp_storage_handle_active; /**< Pointer to the pstorage handle for the active bank for receiving of data packets. */ - -static dfu_callback_t m_data_pkt_cb; /**< Callback from DFU Bank module for notification of asynchronous operation such as flash prepare. */ -static dfu_bank_func_t m_functions; /**< Structure holding operations for the selected update process. */ - - -/**@brief Function for handling callbacks from pstorage module. - * - * @details Handles pstorage results for clear and storage operation. For detailed description of - * the parameters provided with the callback, please refer to \ref pstorage_ntf_cb_t. - */ -static void pstorage_callback_handler(pstorage_handle_t * p_handle, - uint8_t op_code, - uint32_t result, - uint8_t * p_data, - uint32_t data_len) -{ - switch (op_code) - { - case PSTORAGE_STORE_OP_CODE: - if ((m_dfu_state == DFU_STATE_RX_DATA_PKT) && (m_data_pkt_cb != NULL)) - { - m_data_pkt_cb(DATA_PACKET, result, p_data); - } - break; - - case PSTORAGE_CLEAR_OP_CODE: - if (m_dfu_state == DFU_STATE_PREPARING) - { - m_functions.cleared(); - m_dfu_state = DFU_STATE_RDY; - if (m_data_pkt_cb != NULL) - { - m_data_pkt_cb(START_PACKET, result, p_data); - } - } - break; - - default: - break; - } - APP_ERROR_CHECK(result); -} - - -/**@brief Function for handling the DFU timeout. - * - * @param[in] p_context The timeout context. - */ -static void dfu_timeout_handler(void * p_context) -{ - UNUSED_PARAMETER(p_context); - dfu_update_status_t update_status; - - m_dfu_timed_out = true; - update_status.status_code = DFU_TIMEOUT; - - bootloader_dfu_update_process(update_status); -} - - -/**@brief Function for restarting the DFU Timer. - * - * @details This function will stop and restart the DFU timer. This function will be called by the - * functions handling any DFU packet received from the peer that is transferring a firmware - * image. - */ -static uint32_t dfu_timer_restart(void) -{ - if (m_dfu_timed_out) - { - // The DFU timer had already timed out. - return NRF_ERROR_INVALID_STATE; - } - - uint32_t err_code = app_timer_stop(m_dfu_timer_id); - APP_ERROR_CHECK(err_code); - - err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL); - APP_ERROR_CHECK(err_code); - - return err_code; -} - - -/**@brief Function for preparing of flash before receiving SoftDevice image. - * - * @details This function will erase current application area to ensure sufficient amount of - * storage for the SoftDevice image. Upon erase complete a callback will be done. - * See \ref dfu_bank_prepare_t for further details. - */ -static void dfu_prepare_func_app_erase(uint32_t image_size) -{ - uint32_t err_code; - - mp_storage_handle_active = &m_storage_handle_app; - - // Doing a SoftDevice update thus current application must be cleared to ensure enough space - // for new SoftDevice. - m_dfu_state = DFU_STATE_PREPARING; - err_code = pstorage_clear(&m_storage_handle_app, m_image_size); - APP_ERROR_CHECK(err_code); -} - - -/**@brief Function for preparing swap before receiving application or bootloader image. - * - * @details This function will erase current swap area to ensure flash is ready for storage of the - * Application or Bootloader image. Upon erase complete a callback will be done. - * See \ref dfu_bank_prepare_t for further details. - */ -static void dfu_prepare_func_swap_erase(uint32_t image_size) -{ - uint32_t err_code; - - mp_storage_handle_active = &m_storage_handle_swap; - - m_dfu_state = DFU_STATE_PREPARING; - err_code = pstorage_clear(&m_storage_handle_swap, DFU_IMAGE_MAX_SIZE_BANKED); - APP_ERROR_CHECK(err_code); -} - - -/**@brief Function for handling behaviour when clear operation has completed. - */ -static void dfu_cleared_func_swap(void) -{ - // Do nothing. -} - - -/**@brief Function for handling behaviour when clear operation has completed. - */ -static void dfu_cleared_func_app(void) -{ - dfu_update_status_t update_status = {DFU_BANK_0_ERASED, }; - bootloader_dfu_update_process(update_status); -} - - -/**@brief Function for calculating storage offset for receiving SoftDevice image. - * - * @details When a new SoftDevice is received it will be temporary stored in flash before moved to - * address 0x0. In order to succesfully validate transfer and relocation it is important - * that temporary image and final installed image does not ovwerlap hence an offset must - * be calculated in case new image is larger than currently installed SoftDevice. - */ -uint32_t offset_calculate(uint32_t sd_image_size) -{ - uint32_t offset = 0; - - if (m_start_packet.sd_image_size > DFU_BANK_0_REGION_START) - { - uint32_t page_mask = (CODE_PAGE_SIZE - 1); - uint32_t diff = m_start_packet.sd_image_size - DFU_BANK_0_REGION_START; - - offset = diff & ~page_mask; - - // Align offset to next page if image size is not page sized. - if ((diff & page_mask) > 0) - { - offset += CODE_PAGE_SIZE; - } - } - - return offset; -} - - -/**@brief Function for activating received SoftDevice image. - * - * @note This function will not move the SoftDevice image. - * The bootloader settings will be marked as SoftDevice update complete and the swapping of - * current SoftDevice will occur after system reset. - * - * @return NRF_SUCCESS on success. - */ -static uint32_t dfu_activate_sd(void) -{ - dfu_update_status_t update_status; - - update_status.status_code = DFU_UPDATE_SD_COMPLETE; - update_status.app_crc = m_image_crc; - update_status.sd_image_start = DFU_BANK_0_REGION_START; - update_status.sd_size = m_start_packet.sd_image_size; - update_status.bl_size = m_start_packet.bl_image_size; - update_status.app_size = m_start_packet.app_image_size; - - bootloader_dfu_update_process(update_status); - - return NRF_SUCCESS; -} - - -/**@brief Function for activating received Application image. - * - * @details This function will move the received application image fram swap (bank 1) to - * application area (bank 0). - * - * @return NRF_SUCCESS on success. Error code otherwise. - */ -static uint32_t dfu_activate_app(void) -{ - uint32_t err_code; - - // Erase BANK 0. - err_code = pstorage_clear(&m_storage_handle_app, m_start_packet.app_image_size); - APP_ERROR_CHECK(err_code); - - err_code = pstorage_store(&m_storage_handle_app, - (uint8_t *)m_storage_handle_swap.block_id, - m_start_packet.app_image_size, - 0); - - if (err_code == NRF_SUCCESS) - { - dfu_update_status_t update_status; - - memset(&update_status, 0, sizeof(dfu_update_status_t )); - update_status.status_code = DFU_UPDATE_APP_COMPLETE; - update_status.app_crc = m_image_crc; - update_status.app_size = m_start_packet.app_image_size; - - bootloader_dfu_update_process(update_status); - } - - return err_code; -} - - -/**@brief Function for activating received Bootloader image. - * - * @note This function will not move the bootloader image. - * The bootloader settings will be marked as Bootloader update complete and the swapping of - * current bootloader will occur after system reset. - * - * @return NRF_SUCCESS on success. - */ -static uint32_t dfu_activate_bl(void) -{ - dfu_update_status_t update_status; - - update_status.status_code = DFU_UPDATE_BOOT_COMPLETE; - update_status.app_crc = m_image_crc; - update_status.sd_size = m_start_packet.sd_image_size; - update_status.bl_size = m_start_packet.bl_image_size; - update_status.app_size = m_start_packet.app_image_size; - - bootloader_dfu_update_process(update_status); - - return NRF_SUCCESS; -} - - -uint32_t dfu_init(void) -{ - uint32_t err_code; - pstorage_module_param_t storage_module_param = {.cb = pstorage_callback_handler}; - - m_init_packet_length = 0; - m_image_crc = 0; - - err_code = pstorage_register(&storage_module_param, &m_storage_handle_app); - if (err_code != NRF_SUCCESS) - { - m_dfu_state = DFU_STATE_INIT_ERROR; - return err_code; - } - - m_storage_handle_app.block_id = DFU_BANK_0_REGION_START; - m_storage_handle_swap = m_storage_handle_app; - m_storage_handle_swap.block_id = DFU_BANK_1_REGION_START; - - // Create the timer to monitor the activity by the peer doing the firmware update. - err_code = app_timer_create(&m_dfu_timer_id, - APP_TIMER_MODE_SINGLE_SHOT, - dfu_timeout_handler); - APP_ERROR_CHECK(err_code); - - // Start the DFU timer. - err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL); - APP_ERROR_CHECK(err_code); - - m_data_received = 0; - m_dfu_state = DFU_STATE_IDLE; - - return NRF_SUCCESS; -} - - -void dfu_register_callback(dfu_callback_t callback_handler) -{ - m_data_pkt_cb = callback_handler; -} - - -uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet) -{ - uint32_t err_code; - - m_start_packet = *(p_packet->params.start_packet); - - // Check that the requested update procedure is supported. - // Currently the following combinations are allowed: - // - Application - // - SoftDevice - // - Bootloader - // - SoftDevice with Bootloader - if (IS_UPDATING_APP(m_start_packet) && - (IS_UPDATING_SD(m_start_packet) || IS_UPDATING_BL(m_start_packet))) - { - // App update is only supported independently. - return NRF_ERROR_NOT_SUPPORTED; - } - - if (!(IS_WORD_SIZED(m_start_packet.sd_image_size) && - IS_WORD_SIZED(m_start_packet.bl_image_size) && - IS_WORD_SIZED(m_start_packet.app_image_size))) - { - // Image_sizes are not a multiple of 4 (word size). - return NRF_ERROR_NOT_SUPPORTED; - } - - m_image_size = m_start_packet.sd_image_size + m_start_packet.bl_image_size + - m_start_packet.app_image_size; - - if (m_start_packet.bl_image_size > DFU_BL_IMAGE_MAX_SIZE) - { - return NRF_ERROR_DATA_SIZE; - } - - if (IS_UPDATING_SD(m_start_packet)) - { - if (m_image_size > (DFU_IMAGE_MAX_SIZE_FULL)) - { - return NRF_ERROR_DATA_SIZE; - } - m_functions.prepare = dfu_prepare_func_app_erase; - m_functions.cleared = dfu_cleared_func_app; - m_functions.activate = dfu_activate_sd; - } - else - { - if (m_image_size > DFU_IMAGE_MAX_SIZE_BANKED) - { - return NRF_ERROR_DATA_SIZE; - } - - m_functions.prepare = dfu_prepare_func_swap_erase; - m_functions.cleared = dfu_cleared_func_swap; - if (IS_UPDATING_BL(m_start_packet)) - { - m_functions.activate = dfu_activate_bl; - } - else - { - m_functions.activate = dfu_activate_app; - } - } - - switch (m_dfu_state) - { - case DFU_STATE_IDLE: - // Valid peer activity detected. Hence restart the DFU timer. - err_code = dfu_timer_restart(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - m_functions.prepare(m_image_size); - - break; - - default: - err_code = NRF_ERROR_INVALID_STATE; - break; - } - - return err_code; -} - - -uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet) -{ - uint32_t data_length; - uint32_t err_code; - uint32_t * p_data; - - if (p_packet == NULL) - { - return NRF_ERROR_NULL; - } - - // Check pointer alignment. - if (!is_word_aligned(p_packet->params.data_packet.p_data_packet)) - { - // The p_data_packet is not word aligned address. - return NRF_ERROR_INVALID_ADDR; - } - - switch (m_dfu_state) - { - case DFU_STATE_RDY: - case DFU_STATE_RX_INIT_PKT: - return NRF_ERROR_INVALID_STATE; - - case DFU_STATE_RX_DATA_PKT: - data_length = p_packet->params.data_packet.packet_length * sizeof(uint32_t); - - if ((m_data_received + data_length) > m_image_size) - { - // The caller is trying to write more bytes into the flash than the size provided to - // the dfu_image_size_set function. This is treated as a serious error condition and - // an unrecoverable one. Hence point the variable mp_app_write_address to the top of - // the flash area. This will ensure that all future application data packet writes - // will be blocked because of the above check. - m_data_received = 0xFFFFFFFF; - - return NRF_ERROR_DATA_SIZE; - } - - // Valid peer activity detected. Hence restart the DFU timer. - err_code = dfu_timer_restart(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - p_data = (uint32_t *)p_packet->params.data_packet.p_data_packet; - - err_code = pstorage_store(mp_storage_handle_active, - (uint8_t *)p_data, - data_length, - m_data_received); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - m_data_received += data_length; - - if (m_data_received != m_image_size) - { - // The entire image is not received yet. More data is expected. - err_code = NRF_ERROR_INVALID_LENGTH; - } - else - { - // The entire image has been received. Return NRF_SUCCESS. - err_code = NRF_SUCCESS; - } - break; - - default: - err_code = NRF_ERROR_INVALID_STATE; - break; - } - - return err_code; -} - - -uint32_t dfu_init_pkt_complete(void) -{ - uint32_t err_code = NRF_ERROR_INVALID_STATE; - - // DFU initialization has been done and a start packet has been received. - if (IMAGE_WRITE_IN_PROGRESS()) - { - // Image write is already in progress. Cannot handle an init packet now. - return NRF_ERROR_INVALID_STATE; - } - - if (m_dfu_state == DFU_STATE_RX_INIT_PKT) - { - err_code = dfu_init_prevalidate(m_init_packet, m_init_packet_length); - if (err_code == NRF_SUCCESS) - { - m_dfu_state = DFU_STATE_RX_DATA_PKT; - } - else - { - m_init_packet_length = 0; - } - } - return err_code; -} - - -uint32_t dfu_init_pkt_handle(dfu_update_packet_t * p_packet) -{ - uint32_t err_code = NRF_SUCCESS; - uint32_t length; - - switch (m_dfu_state) - { - case DFU_STATE_RDY: - m_dfu_state = DFU_STATE_RX_INIT_PKT; - // When receiving init packet in state ready just update and fall through this case. - - case DFU_STATE_RX_INIT_PKT: - // DFU initialization has been done and a start packet has been received. - if (IMAGE_WRITE_IN_PROGRESS()) - { - // Image write is already in progress. Cannot handle an init packet now. - return NRF_ERROR_INVALID_STATE; - } - - // Valid peer activity detected. Hence restart the DFU timer. - err_code = dfu_timer_restart(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - length = p_packet->params.data_packet.packet_length * sizeof(uint32_t); - if ((m_init_packet_length + length) > sizeof(m_init_packet)) - { - return NRF_ERROR_INVALID_LENGTH; - } - - memcpy(&m_init_packet[m_init_packet_length], - &p_packet->params.data_packet.p_data_packet[0], - length); - m_init_packet_length += length; - break; - - default: - // Either the start packet was not received or dfu_init function was not called before. - err_code = NRF_ERROR_INVALID_STATE; - break; - } - - return err_code; -} - - -uint32_t dfu_image_validate() -{ - uint32_t err_code; - - switch (m_dfu_state) - { - case DFU_STATE_RX_DATA_PKT: - // Check if the application image write has finished. - if (m_data_received != m_image_size) - { - // Image not yet fully transfered by the peer or the peer has attempted to write - // too much data. Hence the validation should fail. - err_code = NRF_ERROR_INVALID_STATE; - } - else - { - m_dfu_state = DFU_STATE_VALIDATE; - - // Valid peer activity detected. Hence restart the DFU timer. - err_code = dfu_timer_restart(); - if (err_code == NRF_SUCCESS) - { - err_code = dfu_init_postvalidate((uint8_t *)mp_storage_handle_active->block_id, - m_image_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - m_dfu_state = DFU_STATE_WAIT_4_ACTIVATE; - } - } - break; - - default: - err_code = NRF_ERROR_INVALID_STATE; - break; - } - - return err_code; -} - - -uint32_t dfu_image_activate() -{ - uint32_t err_code; - - switch (m_dfu_state) - { - case DFU_STATE_WAIT_4_ACTIVATE: - - // Stop the DFU Timer because the peer activity need not be monitored any longer. - err_code = app_timer_stop(m_dfu_timer_id); - APP_ERROR_CHECK(err_code); - - err_code = m_functions.activate(); - break; - - default: - err_code = NRF_ERROR_INVALID_STATE; - break; - } - - return err_code; -} - - -void dfu_reset(void) -{ - dfu_update_status_t update_status; - - update_status.status_code = DFU_RESET; - - bootloader_dfu_update_process(update_status); -} - - -static uint32_t dfu_compare_block(uint32_t * ptr1, uint32_t * ptr2, uint32_t len) -{ - sd_mbr_command_t sd_mbr_cmd; - - sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE; - sd_mbr_cmd.params.compare.ptr1 = ptr1; - sd_mbr_cmd.params.compare.ptr2 = ptr2; - sd_mbr_cmd.params.compare.len = len / sizeof(uint32_t); - - return sd_mbr_command(&sd_mbr_cmd); -} - - -static uint32_t dfu_copy_sd(uint32_t * src, uint32_t * dst, uint32_t len) -{ - sd_mbr_command_t sd_mbr_cmd; - - sd_mbr_cmd.command = SD_MBR_COMMAND_COPY_SD; - sd_mbr_cmd.params.copy_sd.src = src; - sd_mbr_cmd.params.copy_sd.dst = dst; - sd_mbr_cmd.params.copy_sd.len = len / sizeof(uint32_t); - - return sd_mbr_command(&sd_mbr_cmd); -} - - -static uint32_t dfu_sd_img_block_swap(uint32_t * src, - uint32_t * dst, - uint32_t len, - uint32_t block_size) -{ - // It is neccesarry to swap the new SoftDevice in 3 rounds to ensure correct copy of data - // and verifucation of data in case power reset occurs during write to flash. - // To ensure the robustness of swapping the images are compared backwards till start of - // image swap. If the back is identical everything is swapped. - uint32_t err_code = dfu_compare_block(src, dst, len); - if (err_code == NRF_SUCCESS) - { - return err_code; - } - - if ((uint32_t)dst > SOFTDEVICE_REGION_START) - { - err_code = dfu_sd_img_block_swap((uint32_t *)((uint32_t)src - block_size), - (uint32_t *)((uint32_t)dst - block_size), - block_size, - block_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - } - - err_code = dfu_copy_sd(src, dst, len); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - return dfu_compare_block(src, dst, len); -} - - -uint32_t dfu_sd_image_swap(void) -{ - bootloader_settings_t boot_settings; - - bootloader_settings_get(&boot_settings); - - if (boot_settings.sd_image_size == 0) - { - return NRF_SUCCESS; - } - - if ((SOFTDEVICE_REGION_START + boot_settings.sd_image_size) > boot_settings.sd_image_start) - { - uint32_t err_code; - uint32_t sd_start = SOFTDEVICE_REGION_START; - uint32_t block_size = (boot_settings.sd_image_start - sd_start) / 2; - uint32_t image_end = boot_settings.sd_image_start + boot_settings.sd_image_size; - - uint32_t img_block_start = boot_settings.sd_image_start + 2 * block_size; - uint32_t sd_block_start = sd_start + 2 * block_size; - - if (SD_SIZE_GET(MBR_SIZE) < boot_settings.sd_image_size) - { - // This will clear a page thus ensuring the old image is invalidated before swapping. - err_code = dfu_copy_sd((uint32_t *)(sd_start + block_size), - (uint32_t *)(sd_start + block_size), - sizeof(uint32_t)); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = dfu_copy_sd((uint32_t *)sd_start, (uint32_t *)sd_start, sizeof(uint32_t)); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - } - - return dfu_sd_img_block_swap((uint32_t *)img_block_start, - (uint32_t *)sd_block_start, - image_end - img_block_start, - block_size); - } - else - { - if (boot_settings.sd_image_size != 0) - { - return dfu_copy_sd((uint32_t *)boot_settings.sd_image_start, - (uint32_t *)SOFTDEVICE_REGION_START, - boot_settings.sd_image_size); - } - } - - return NRF_SUCCESS; -} - - -uint32_t dfu_bl_image_swap(void) -{ - bootloader_settings_t bootloader_settings; - sd_mbr_command_t sd_mbr_cmd; - - bootloader_settings_get(&bootloader_settings); - - if (bootloader_settings.bl_image_size != 0) - { - uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ? - DFU_BANK_1_REGION_START : - bootloader_settings.sd_image_start + - bootloader_settings.sd_image_size; - - sd_mbr_cmd.command = SD_MBR_COMMAND_COPY_BL; - sd_mbr_cmd.params.copy_bl.bl_src = (uint32_t *)(bl_image_start); - sd_mbr_cmd.params.copy_bl.bl_len = bootloader_settings.bl_image_size / sizeof(uint32_t); - - return sd_mbr_command(&sd_mbr_cmd); - } - return NRF_SUCCESS; -} - - -uint32_t dfu_bl_image_validate(void) -{ - bootloader_settings_t bootloader_settings; - sd_mbr_command_t sd_mbr_cmd; - - bootloader_settings_get(&bootloader_settings); - - if (bootloader_settings.bl_image_size != 0) - { - uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ? - DFU_BANK_1_REGION_START : - bootloader_settings.sd_image_start + - bootloader_settings.sd_image_size; - - sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE; - sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START; - sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)(bl_image_start); - sd_mbr_cmd.params.compare.len = bootloader_settings.bl_image_size / sizeof(uint32_t); - - return sd_mbr_command(&sd_mbr_cmd); - } - return NRF_SUCCESS; -} - - -uint32_t dfu_sd_image_validate(void) -{ - bootloader_settings_t bootloader_settings; - sd_mbr_command_t sd_mbr_cmd; - - bootloader_settings_get(&bootloader_settings); - - if (bootloader_settings.sd_image_size == 0) - { - return NRF_SUCCESS; - } - - if ((SOFTDEVICE_REGION_START + bootloader_settings.sd_image_size) > bootloader_settings.sd_image_start) - { - uint32_t sd_start = SOFTDEVICE_REGION_START; - uint32_t block_size = (bootloader_settings.sd_image_start - sd_start) / 2; - uint32_t image_end = bootloader_settings.sd_image_start + - bootloader_settings.sd_image_size; - - uint32_t img_block_start = bootloader_settings.sd_image_start + 2 * block_size; - uint32_t sd_block_start = sd_start + 2 * block_size; - - if (SD_SIZE_GET(MBR_SIZE) < bootloader_settings.sd_image_size) - { - return NRF_ERROR_NULL; - } - - return dfu_sd_img_block_swap((uint32_t *)img_block_start, - (uint32_t *)sd_block_start, - image_end - img_block_start, - block_size); - } - - sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE; - sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)SOFTDEVICE_REGION_START; - sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)bootloader_settings.sd_image_start; - sd_mbr_cmd.params.compare.len = bootloader_settings.sd_image_size / sizeof(uint32_t); - - return sd_mbr_command(&sd_mbr_cmd); -} diff --git a/components/libraries/bootloader_dfu/dfu_init.h b/components/libraries/bootloader_dfu/dfu_init.h deleted file mode 100644 index 33a85f2..0000000 --- a/components/libraries/bootloader_dfu/dfu_init.h +++ /dev/null @@ -1,134 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup nrf_dfu_init Init packet handling in DFU - * @{ - * - * @brief Device Firmware Update module type and function declaration for init packet handling. - * - * @details This header contains basic functionality for performing safety checks on software - * updates for \nRFXX based devices. It provides a skeleton for pre-checking an init packet - * to ensure the following image is compatible with this device. A safety check should - * always be performed to prevent accidental flashing of unsupported applications or a - * wrong combination of application and SoftDevice. - * The device information contains information such as: - * - Device type (2 bytes), for example Heart Rate. The device type is a number defined by - * the customer. It can be located in UICR or FICR. - * - Device revision (2 bytes), for example major revision 1, minor revision 0. The device - * revision is a number defined by the customer. It can be located in UICR or FICR. - * - List of SoftDevices supported by this application, for example - * 0x0049 = S110v6_0_0 - * 0xFFFE = S110 development (any SoftDevice accepted), - * - CRC or hash of firmware image - * - * @note This module does not support security features such as image signing, but the corresponding - * implementation allows for such extensions. - * If the init packet is signed by a trusted source, it must be decrypted before it can be - * processed. - */ - -#ifndef DFU_INIT_H__ -#define DFU_INIT_H__ - -#include -#include "nrf.h" - -/**@brief Structure contained in an init packet. Contains information on device type, revision, and - * supported SoftDevices. - */ -typedef struct -{ - uint16_t device_type; /**< Device type (2 bytes), for example Heart Rate. This number must be defined by the customer before production. It can be located in UICR or FICR. */ - uint16_t device_rev; /**< Device revision (2 bytes), for example major revision 1, minor revision 0. This number must be defined by the customer before production. It can be located in UICR or FICR. */ - uint32_t app_version; /**< Application version for the image software. This field allows for additional checking, for example ensuring that a downgrade is not allowed. */ - uint16_t softdevice_len; /**< Number of different SoftDevice revisions compatible with this application. The list of SoftDevice firmware IDs is defined in @ref softdevice. */ - uint16_t softdevice[1]; /**< Variable length array of SoftDevices compatible with this application. The length of the array is specified in the length field. SoftDevice firmware id 0xFFFE indicates any SoftDevice. */ -} dfu_init_packet_t; - -/**@brief Structure holding basic device information settings. - */ -typedef struct -{ - uint16_t device_type; /**< Device type (2 bytes), for example Heart Rate. This number must be defined by the customer before production. It can be located in UICR or FICR. */ - uint16_t device_rev; /**< Device revision (2 bytes), for example major revision 1, minor revision 0. This number must be defined by the customer before production. It can be located in UICR or FICR. */ -} dfu_device_info_t; - -/** The device info offset can be modified to place the device info settings at a different location. - * If the customer reserved UICR location is used for other application specific data, the offset - * must be updated to avoid collision with that data. - */ -/** [DFU UICR DEV offset] */ -#define UICR_CUSTOMER_DEVICE_INFO_OFFSET 0x0 /**< Device info offset inside the customer UICR reserved area. Customers may change this value to place the device information in a user-preferred location. */ -/** [DFU UICR DEV offset] */ - -#define UICR_CUSTOMER_RESERVED_OFFSET 0x80 /**< Customer reserved area in the UICR. The area from UICR + 0x80 is reserved for customer usage. */ -#define DFU_DEVICE_INFO_BASE (NRF_UICR_BASE + \ - UICR_CUSTOMER_RESERVED_OFFSET + \ - UICR_CUSTOMER_DEVICE_INFO_OFFSET) /**< The device information base address inside of UICR. */ -#define DFU_DEVICE_INFO ((dfu_device_info_t *)DFU_DEVICE_INFO_BASE) /**< The memory mapped structure for device information data. */ - -#define DFU_DEVICE_TYPE_EMPTY ((uint16_t)0xFFFF) /**< Mask indicating no device type is present in UICR. 0xFFFF is default flash pattern when not written with data. */ -#define DFU_DEVICE_REVISION_EMPTY ((uint16_t)0xFFFF) /**< Mask indicating no device revision is present in UICR. 0xFFFF is default flash pattern when not written with data. */ -#define DFU_SOFTDEVICE_ANY ((uint16_t)0xFFFE) /**< Mask indicating that any SoftDevice is allowed for updating this application. Allows for easy development. Not to be used in production images. */ - - -/**@brief DFU prevalidate call for pre-checking the received init packet. - * - * @details Pre-validation will safety check the firmware image to be transfered in second stage. - * The function currently checks the device type, device revision, application firmware - * version, and supported SoftDevices. More checks should be added according to - * customer-specific requirements. - * - * @param[in] p_init_data Pointer to the init packet. If the init packet is encrypted or signed, - * it must first be decrypted before being checked. - * @param[in] init_data_len Length of the init data. - * - * @retval NRF_SUCCESS If the pre-validation succeeded, that means the image is - * supported by the device and it is considered to come from a - * trusted source (signing). - * @retval NRF_ERROR_INVALID_DATA If the pre-validation failed, that means the image is not - * supported by the device or comes from an un-trusted source - * (signing). - * @retval NRF_ERROR_INVALID_LENGTH If the size of the init packet is not within the limits of - * the init packet handler. - */ -uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len); - -/**@brief DFU postvalidate call for post-checking the received image using the init packet. - * - * @details Post-validation can verify the integrity check the firmware image received before - * activating the image. - * Checks performed can be: - * - A simple CRC as shown in the corresponding implementation of this API in the file - * dfu_init_template.c - * - A hash for better verification of the image. - * - A signature to ensure the image originates from a trusted source. - * Checks are intended to be expanded for customer-specific requirements. - * - * @param[in] p_image Pointer to the received image. The init data provided in the call - * \ref dfu_init_prevalidate will be used for validating the image. - * @param[in] image_len Length of the image data. - * - * @retval NRF_SUCCESS If the post-validation succeeded, that meant the integrity of the - * image has been verified and the image originates from a trusted - * source (signing). - * @retval NRF_ERROR_INVALID_DATA If the post-validation failed, that meant the post check of the - * image failed such as the CRC is not matching the image transfered - * or the verification of the image fails (signing). - */ -uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len); - -#endif // DFU_INIT_H__ - -/**@} */ diff --git a/components/libraries/bootloader_dfu/dfu_init_template.c b/components/libraries/bootloader_dfu/dfu_init_template.c deleted file mode 100644 index 598340c..0000000 --- a/components/libraries/bootloader_dfu/dfu_init_template.c +++ /dev/null @@ -1,155 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup nrf_dfu_init_template Template file with an DFU init packet handling example. - * @{ - * - * @ingroup nrf_dfu - * - * @brief This file contains a template on how to implement DFU init packet handling. - * - * @details The template shows how device type and revision can be used for a safety check of the - * received image. It shows how validation can be performed in two stages: - * - Stage 1: Pre-check of firmware image before transfer to ensure the firmware matches: - * - Device Type. - * - Device Revision. - * Installed SoftDevice. - * This template can be extended with additional checks according to needs. - * For example, such a check could be the origin of the image (trusted source) - * based on a signature scheme. - * - Stage 2: Post-check of the image after image transfer but before installing firmware. - * For example, such a check could be an integrity check in form of hashing or - * verification of a signature. - * In this template, a simple CRC check is carried out. - * The CRC check can be replaced with other mechanisms, like signing. - * - * @note This module does not support security features such as image signing, but the - * implementation allows for such extension. - * If the init packet is signed by a trusted source, it must be decrypted before it can be - * processed. - */ - -#include "dfu_init.h" -#include -#include -#include -#include "nrf_error.h" -#include "crc16.h" - -#define DFU_INIT_PACKET_EXT_LENGTH_MIN 2 //< Minimum length of the extended init packet. The extended init packet may contain a CRC, a HASH, or other data. This value must be changed according to the requirements of the system. The template uses a minimum value of two in order to hold a CRC. */ -#define DFU_INIT_PACKET_EXT_LENGTH_MAX 10 //< Maximum length of the extended init packet. The extended init packet may contain a CRC, a HASH, or other data. This value must be changed according to the requirements of the system. The template uses a maximum value of 10 in order to hold a CRC and any padded data on transport layer without overflow. */ - -static uint8_t m_extended_packet[DFU_INIT_PACKET_EXT_LENGTH_MAX]; //< Data array for storage of the extended data received. The extended data follows the normal init data of type \ref dfu_init_packet_t. Extended data can be used for a CRC, hash, signature, or other data. */ -static uint8_t m_extended_packet_length; //< Length of the extended data received with init packet. */ - - -uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len) -{ - uint32_t i = 0; - - // In order to support signing or encryption then any init packet decryption function / library - // should be called from here or implemented at this location. - - // Length check to ensure valid data are parsed. - if (init_data_len < sizeof(dfu_init_packet_t)) - { - return NRF_ERROR_INVALID_LENGTH; - } - - // Current template uses clear text data so they can be casted for pre-check. - dfu_init_packet_t * p_init_packet = (dfu_init_packet_t *)p_init_data; - - m_extended_packet_length = ((uint32_t)p_init_data + init_data_len) - - (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len]; - if (m_extended_packet_length < DFU_INIT_PACKET_EXT_LENGTH_MIN) - { - return NRF_ERROR_INVALID_LENGTH; - } - - if (((uint32_t)p_init_data + init_data_len) < - (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len]) - { - return NRF_ERROR_INVALID_LENGTH; - } - - memcpy(m_extended_packet, - &p_init_packet->softdevice[p_init_packet->softdevice_len], - m_extended_packet_length); - -/** [DFU init application version] */ - // To support application versioning, this check should be updated. - // This template allows for any application to be installed. However, - // customers can place a revision number at the bottom of the application - // to be verified by the bootloader. This can be done at a location - // relative to the application, for example the application start - // address + 0x0100. -/** [DFU init application version] */ - - // First check to verify the image to be transfered matches the device type. - // If no Device type is present in DFU_DEVICE_INFO then any image will be accepted. - if ((DFU_DEVICE_INFO->device_type != DFU_DEVICE_TYPE_EMPTY) && - (p_init_packet->device_type != DFU_DEVICE_INFO->device_type)) - { - return NRF_ERROR_INVALID_DATA; - } - - // Second check to verify the image to be transfered matches the device revision. - // If no Device revision is present in DFU_DEVICE_INFO then any image will be accepted. - if ((DFU_DEVICE_INFO->device_rev != DFU_DEVICE_REVISION_EMPTY) && - (p_init_packet->device_rev != DFU_DEVICE_INFO->device_rev)) - { - return NRF_ERROR_INVALID_DATA; - } - - // Third check: Check the array of supported SoftDevices by this application. - // If the installed SoftDevice does not match any SoftDevice in the list then an - // error is returned. - while (i < p_init_packet->softdevice_len) - { - if (p_init_packet->softdevice[i] == DFU_SOFTDEVICE_ANY || - p_init_packet->softdevice[i++] == SD_FWID_GET(MBR_SIZE)) - { - return NRF_SUCCESS; - } - } - - // No matching SoftDevice found - Return NRF_ERROR_INVALID_DATA. - return NRF_ERROR_INVALID_DATA; -} - - -uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len) -{ - uint16_t image_crc; - uint16_t received_crc; - - // In order to support hashing (and signing) then the (decrypted) hash should be fetched and - // the corresponding hash should be calculated over the image at this location. - // If hashing (or signing) is added to the system then the CRC validation should be removed. - - // calculate CRC from active block. - image_crc = crc16_compute(p_image, image_len, NULL); - - // Decode the received CRC from extended data. - received_crc = uint16_decode((uint8_t *)&m_extended_packet[0]); - - // Compare the received and calculated CRC. - if (image_crc != received_crc) - { - return NRF_ERROR_INVALID_DATA; - } - - return NRF_SUCCESS; -} - diff --git a/components/libraries/bootloader_dfu/dfu_single_bank.c b/components/libraries/bootloader_dfu/dfu_single_bank.c deleted file mode 100644 index 1f0d01b..0000000 --- a/components/libraries/bootloader_dfu/dfu_single_bank.c +++ /dev/null @@ -1,818 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include -#include -#include "dfu.h" -#include -#include "dfu_bank_internal.h" -#include "nrf.h" -#include "nrf.h" -#include "app_util.h" -#include "nrf_sdm.h" -#include "app_error.h" -#include "nrf_error.h" -#include "app_timer.h" -#include "app_error.h" -#include "nordic_common.h" -#include "bootloader.h" -#include "bootloader_types.h" -#include "pstorage.h" -#include "nrf_mbr.h" -#include "dfu_init.h" - -static dfu_state_t m_dfu_state; /**< Current DFU state. */ -static uint32_t m_image_size; /**< Size of the image that will be transmitted. */ - -static dfu_start_packet_t m_start_packet; /**< Start packet received for this update procedure. Contains update mode and image sizes information to be used for image transfer. */ -static uint8_t m_init_packet[64]; /**< Init packet, can hold CRC, Hash, Signed Hash and similar, for image validation, integrety check and authorization checking. */ -static uint8_t m_init_packet_length; /**< Length of init packet received. */ -static uint16_t m_image_crc; /**< Calculated CRC of the image received. */ - -APP_TIMER_DEF(m_dfu_timer_id); /**< Application timer id. */ -static bool m_dfu_timed_out = false; /**< Boolean flag value for tracking DFU timer timeout state. */ - -static pstorage_handle_t m_storage_handle_app; /**< Pstorage handle for the application area (bank 0). Bank used when updating a SoftDevice w/wo bootloader. Handle also used when swapping received application from bank 1 to bank 0. */ -static pstorage_handle_t * mp_storage_handle_active; /**< Pointer to the pstorage handle for the active bank for receiving of data packets. */ - -static dfu_callback_t m_data_pkt_cb; /**< Callback from DFU Bank module for notification of asynchronous operation such as flash prepare. */ -static dfu_bank_func_t m_functions; /**< Structure holding operations for the selected update process. */ - - -/**@brief Function for handling callbacks from pstorage module. - * - * @details Handles pstorage results for clear and storage operation. For detailed description of - * the parameters provided with the callback, please refer to \ref pstorage_ntf_cb_t. - */ -static void pstorage_callback_handler(pstorage_handle_t * p_handle, - uint8_t op_code, - uint32_t result, - uint8_t * p_data, - uint32_t data_len) -{ - switch (op_code) - { - case PSTORAGE_STORE_OP_CODE: - if ((m_dfu_state == DFU_STATE_RX_DATA_PKT) && (m_data_pkt_cb != NULL)) - { - m_data_pkt_cb(DATA_PACKET, result, p_data); - } - break; - - case PSTORAGE_CLEAR_OP_CODE: - if (m_dfu_state == DFU_STATE_PREPARING) - { - m_functions.cleared(); - m_dfu_state = DFU_STATE_RDY; - if (m_data_pkt_cb != NULL) - { - m_data_pkt_cb(START_PACKET, result, p_data); - } - } - break; - - default: - break; - } - APP_ERROR_CHECK(result); -} - - -/**@brief Function for handling the DFU timeout. - * - * @param[in] p_context The timeout context. - */ -static void dfu_timeout_handler(void * p_context) -{ - UNUSED_PARAMETER(p_context); - dfu_update_status_t update_status; - - m_dfu_timed_out = true; - update_status.status_code = DFU_TIMEOUT; - - bootloader_dfu_update_process(update_status); -} - - -/**@brief Function for restarting the DFU Timer. - * - * @details This function will stop and restart the DFU timer. This function will be called by the - * functions handling any DFU packet received from the peer that is transferring a firmware - * image. - */ -static uint32_t dfu_timer_restart(void) -{ - if (m_dfu_timed_out) - { - // The DFU timer had already timed out. - return NRF_ERROR_INVALID_STATE; - } - - uint32_t err_code = app_timer_stop(m_dfu_timer_id); - APP_ERROR_CHECK(err_code); - - err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL); - APP_ERROR_CHECK(err_code); - - return err_code; -} - - -/**@brief Function for preparing of flash before receiving SoftDevice image. - * - * @details This function will erase current application area to ensure sufficient amount of - * storage for the SoftDevice image. Upon erase complete a callback will be done. - * See \ref dfu_bank_prepare_t for further details. - */ -static void dfu_prepare_func_app_erase(uint32_t image_size) -{ - uint32_t err_code; - - mp_storage_handle_active = &m_storage_handle_app; - - // Doing a SoftDevice update thus current application must be cleared to ensure enough space - // for new SoftDevice. - m_dfu_state = DFU_STATE_PREPARING; - err_code = pstorage_clear(&m_storage_handle_app, m_image_size); - APP_ERROR_CHECK(err_code); -} - - -/**@brief Function for handling behaviour when clear operation has completed. - */ -static void dfu_cleared_func_app(void) -{ - dfu_update_status_t update_status = {DFU_BANK_0_ERASED, }; - bootloader_dfu_update_process(update_status); -} - - -/**@brief Function for calculating storage offset for receiving SoftDevice image. - * - * @details When a new SoftDevice is received it will be temporary stored in flash before moved to - * address 0x0. In order to succesfully validate transfer and relocation it is important - * that temporary image and final installed image does not ovwerlap hence an offset must - * be calculated in case new image is larger than currently installed SoftDevice. - */ -uint32_t offset_calculate(uint32_t sd_image_size) -{ - uint32_t offset = 0; - - if (m_start_packet.sd_image_size > DFU_BANK_0_REGION_START) - { - uint32_t page_mask = (CODE_PAGE_SIZE - 1); - uint32_t diff = m_start_packet.sd_image_size - DFU_BANK_0_REGION_START; - - offset = diff & ~page_mask; - - // Align offset to next page if image size is not page sized. - if ((diff & page_mask) > 0) - { - offset += CODE_PAGE_SIZE; - } - } - - return offset; -} - - -/**@brief Function for activating received SoftDevice image. - * - * @note This function will not move the SoftDevice image. - * The bootloader settings will be marked as SoftDevice update complete and the swapping of - * current SoftDevice will occur after system reset. - * - * @return NRF_SUCCESS on success. - */ -static uint32_t dfu_activate_sd(void) -{ - dfu_update_status_t update_status; - - update_status.status_code = DFU_UPDATE_SD_COMPLETE; - update_status.app_crc = m_image_crc; - update_status.sd_image_start = DFU_BANK_0_REGION_START; - update_status.sd_size = m_start_packet.sd_image_size; - update_status.bl_size = m_start_packet.bl_image_size; - update_status.app_size = m_start_packet.app_image_size; - - bootloader_dfu_update_process(update_status); - - return NRF_SUCCESS; -} - - -/**@brief Function for activating received Application image. - * - * @details This function will move the received application image fram swap (bank 1) to - * application area (bank 0). - * - * @return NRF_SUCCESS on success. Error code otherwise. - */ -static uint32_t dfu_activate_app(void) -{ - uint32_t err_code = NRF_SUCCESS; - dfu_update_status_t update_status; - - memset(&update_status, 0, sizeof(dfu_update_status_t )); - update_status.status_code = DFU_UPDATE_APP_COMPLETE; - update_status.app_crc = m_image_crc; - update_status.app_size = m_start_packet.app_image_size; - - bootloader_dfu_update_process(update_status); - - return err_code; -} - - -/**@brief Function for activating received Bootloader image. - * - * @note This function will not move the bootloader image. - * The bootloader settings will be marked as Bootloader update complete and the swapping of - * current bootloader will occur after system reset. - * - * @return NRF_SUCCESS on success. - */ -static uint32_t dfu_activate_bl(void) -{ - dfu_update_status_t update_status; - - update_status.status_code = DFU_UPDATE_BOOT_COMPLETE; - update_status.app_crc = m_image_crc; - update_status.sd_size = m_start_packet.sd_image_size; - update_status.bl_size = m_start_packet.bl_image_size; - update_status.app_size = m_start_packet.app_image_size; - - bootloader_dfu_update_process(update_status); - - return NRF_SUCCESS; -} - - -uint32_t dfu_init(void) -{ - uint32_t err_code; - pstorage_module_param_t storage_module_param = {.cb = pstorage_callback_handler}; - - m_init_packet_length = 0; - m_image_crc = 0; - - err_code = pstorage_register(&storage_module_param, &m_storage_handle_app); - if (err_code != NRF_SUCCESS) - { - m_dfu_state = DFU_STATE_INIT_ERROR; - return err_code; - } - - m_storage_handle_app.block_id = DFU_BANK_0_REGION_START; - - // Create the timer to monitor the activity by the peer doing the firmware update. - err_code = app_timer_create(&m_dfu_timer_id, - APP_TIMER_MODE_SINGLE_SHOT, - dfu_timeout_handler); - APP_ERROR_CHECK(err_code); - - // Start the DFU timer. - err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL); - APP_ERROR_CHECK(err_code); - - m_data_received = 0; - m_dfu_state = DFU_STATE_IDLE; - - return NRF_SUCCESS; -} - - -void dfu_register_callback(dfu_callback_t callback_handler) -{ - m_data_pkt_cb = callback_handler; -} - - -uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet) -{ - uint32_t err_code; - - m_start_packet = *(p_packet->params.start_packet); - - // Check that the requested update procedure is supported. - // Currently the following combinations are allowed: - // - Application - // - SoftDevice - // - Bootloader - // - SoftDevice with Bootloader - if (IS_UPDATING_APP(m_start_packet) && - (IS_UPDATING_SD(m_start_packet) || IS_UPDATING_BL(m_start_packet))) - { - // App update is only supported independently. - return NRF_ERROR_NOT_SUPPORTED; - } - - if (!(IS_WORD_SIZED(m_start_packet.sd_image_size) && - IS_WORD_SIZED(m_start_packet.bl_image_size) && - IS_WORD_SIZED(m_start_packet.app_image_size))) - { - // Image_sizes are not a multiple of 4 (word size). - return NRF_ERROR_NOT_SUPPORTED; - } - - m_image_size = m_start_packet.sd_image_size + m_start_packet.bl_image_size + - m_start_packet.app_image_size; - - if (m_start_packet.bl_image_size > DFU_BL_IMAGE_MAX_SIZE) - { - return NRF_ERROR_DATA_SIZE; - } - - if (m_image_size > (DFU_IMAGE_MAX_SIZE_FULL)) - { - return NRF_ERROR_DATA_SIZE; - } - m_functions.prepare = dfu_prepare_func_app_erase; - m_functions.cleared = dfu_cleared_func_app; - - if (IS_UPDATING_SD(m_start_packet)) - { - m_functions.activate = dfu_activate_sd; - } - else if (IS_UPDATING_BL(m_start_packet)) - { - m_functions.activate = dfu_activate_bl; - } - else - { - m_functions.activate = dfu_activate_app; - } - - switch (m_dfu_state) - { - case DFU_STATE_IDLE: - // Valid peer activity detected. Hence restart the DFU timer. - err_code = dfu_timer_restart(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - m_functions.prepare(m_image_size); - - break; - - default: - err_code = NRF_ERROR_INVALID_STATE; - break; - } - - return err_code; -} - - -uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet) -{ - uint32_t data_length; - uint32_t err_code; - uint32_t * p_data; - - if (p_packet == NULL) - { - return NRF_ERROR_NULL; - } - - // Check pointer alignment. - if (!is_word_aligned(p_packet->params.data_packet.p_data_packet)) - { - // The p_data_packet is not word aligned address. - return NRF_ERROR_INVALID_ADDR; - } - - switch (m_dfu_state) - { - case DFU_STATE_RDY: - case DFU_STATE_RX_INIT_PKT: - return NRF_ERROR_INVALID_STATE; - - case DFU_STATE_RX_DATA_PKT: - data_length = p_packet->params.data_packet.packet_length * sizeof(uint32_t); - - if ((m_data_received + data_length) > m_image_size) - { - // The caller is trying to write more bytes into the flash than the size provided to - // the dfu_image_size_set function. This is treated as a serious error condition and - // an unrecoverable one. Hence point the variable mp_app_write_address to the top of - // the flash area. This will ensure that all future application data packet writes - // will be blocked because of the above check. - m_data_received = 0xFFFFFFFF; - - return NRF_ERROR_DATA_SIZE; - } - - // Valid peer activity detected. Hence restart the DFU timer. - err_code = dfu_timer_restart(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - p_data = (uint32_t *)p_packet->params.data_packet.p_data_packet; - - err_code = pstorage_store(mp_storage_handle_active, - (uint8_t *)p_data, - data_length, - m_data_received); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - m_data_received += data_length; - - if (m_data_received != m_image_size) - { - // The entire image is not received yet. More data is expected. - err_code = NRF_ERROR_INVALID_LENGTH; - } - else - { - // The entire image has been received. Return NRF_SUCCESS. - err_code = NRF_SUCCESS; - } - break; - - default: - err_code = NRF_ERROR_INVALID_STATE; - break; - } - - return err_code; -} - - -uint32_t dfu_init_pkt_complete(void) -{ - uint32_t err_code = NRF_ERROR_INVALID_STATE; - - // DFU initialization has been done and a start packet has been received. - if (IMAGE_WRITE_IN_PROGRESS()) - { - // Image write is already in progress. Cannot handle an init packet now. - return NRF_ERROR_INVALID_STATE; - } - - if (m_dfu_state == DFU_STATE_RX_INIT_PKT) - { - err_code = dfu_init_prevalidate(m_init_packet, m_init_packet_length); - if (err_code == NRF_SUCCESS) - { - m_dfu_state = DFU_STATE_RX_DATA_PKT; - } - else - { - m_init_packet_length = 0; - } - } - return err_code; -} - - -uint32_t dfu_init_pkt_handle(dfu_update_packet_t * p_packet) -{ - uint32_t err_code = NRF_SUCCESS; - uint32_t length; - - switch (m_dfu_state) - { - case DFU_STATE_RDY: - m_dfu_state = DFU_STATE_RX_INIT_PKT; - // When receiving init packet in state ready just update and fall through this case. - - case DFU_STATE_RX_INIT_PKT: - // DFU initialization has been done and a start packet has been received. - if (IMAGE_WRITE_IN_PROGRESS()) - { - // Image write is already in progress. Cannot handle an init packet now. - return NRF_ERROR_INVALID_STATE; - } - - // Valid peer activity detected. Hence restart the DFU timer. - err_code = dfu_timer_restart(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - length = p_packet->params.data_packet.packet_length * sizeof(uint32_t); - if ((m_init_packet_length + length) > sizeof(m_init_packet)) - { - return NRF_ERROR_INVALID_LENGTH; - } - - memcpy(&m_init_packet[m_init_packet_length], - &p_packet->params.data_packet.p_data_packet[0], - length); - m_init_packet_length += length; - break; - - default: - // Either the start packet was not received or dfu_init function was not called before. - err_code = NRF_ERROR_INVALID_STATE; - break; - } - - return err_code; -} - - -uint32_t dfu_image_validate() -{ - uint32_t err_code; - - switch (m_dfu_state) - { - case DFU_STATE_RX_DATA_PKT: - // Check if the application image write has finished. - if (m_data_received != m_image_size) - { - // Image not yet fully transfered by the peer or the peer has attempted to write - // too much data. Hence the validation should fail. - err_code = NRF_ERROR_INVALID_STATE; - } - else - { - m_dfu_state = DFU_STATE_VALIDATE; - - // Valid peer activity detected. Hence restart the DFU timer. - err_code = dfu_timer_restart(); - if (err_code == NRF_SUCCESS) - { - err_code = dfu_init_postvalidate((uint8_t *)mp_storage_handle_active->block_id, - m_image_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - m_dfu_state = DFU_STATE_WAIT_4_ACTIVATE; - } - } - break; - - default: - err_code = NRF_ERROR_INVALID_STATE; - break; - } - - return err_code; -} - - -uint32_t dfu_image_activate() -{ - uint32_t err_code; - - switch (m_dfu_state) - { - case DFU_STATE_WAIT_4_ACTIVATE: - - // Stop the DFU Timer because the peer activity need not be monitored any longer. - err_code = app_timer_stop(m_dfu_timer_id); - APP_ERROR_CHECK(err_code); - - err_code = m_functions.activate(); - break; - - default: - err_code = NRF_ERROR_INVALID_STATE; - break; - } - - return err_code; -} - - -void dfu_reset(void) -{ - dfu_update_status_t update_status; - - update_status.status_code = DFU_RESET; - - bootloader_dfu_update_process(update_status); -} - - -static uint32_t dfu_compare_block(uint32_t * ptr1, uint32_t * ptr2, uint32_t len) -{ - sd_mbr_command_t sd_mbr_cmd; - - sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE; - sd_mbr_cmd.params.compare.ptr1 = ptr1; - sd_mbr_cmd.params.compare.ptr2 = ptr2; - sd_mbr_cmd.params.compare.len = len / sizeof(uint32_t); - - return sd_mbr_command(&sd_mbr_cmd); -} - - -static uint32_t dfu_copy_sd(uint32_t * src, uint32_t * dst, uint32_t len) -{ - sd_mbr_command_t sd_mbr_cmd; - - sd_mbr_cmd.command = SD_MBR_COMMAND_COPY_SD; - sd_mbr_cmd.params.copy_sd.src = src; - sd_mbr_cmd.params.copy_sd.dst = dst; - sd_mbr_cmd.params.copy_sd.len = len / sizeof(uint32_t); - - return sd_mbr_command(&sd_mbr_cmd); -} - - -static uint32_t dfu_sd_img_block_swap(uint32_t * src, - uint32_t * dst, - uint32_t len, - uint32_t block_size) -{ - // It is neccesarry to swap the new SoftDevice in 3 rounds to ensure correct copy of data - // and verifucation of data in case power reset occurs during write to flash. - // To ensure the robustness of swapping the images are compared backwards till start of - // image swap. If the back is identical everything is swapped. - uint32_t err_code = dfu_compare_block(src, dst, len); - if (err_code == NRF_SUCCESS) - { - return err_code; - } - - if ((uint32_t)dst > SOFTDEVICE_REGION_START) - { - err_code = dfu_sd_img_block_swap((uint32_t *)((uint32_t)src - block_size), - (uint32_t *)((uint32_t)dst - block_size), - block_size, - block_size); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - } - - err_code = dfu_copy_sd(src, dst, len); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - return dfu_compare_block(src, dst, len); -} - - -uint32_t dfu_sd_image_swap(void) -{ - bootloader_settings_t boot_settings; - - bootloader_settings_get(&boot_settings); - - if (boot_settings.sd_image_size == 0) - { - return NRF_SUCCESS; - } - - if ((SOFTDEVICE_REGION_START + boot_settings.sd_image_size) > boot_settings.sd_image_start) - { - uint32_t err_code; - uint32_t sd_start = SOFTDEVICE_REGION_START; - uint32_t block_size = (boot_settings.sd_image_start - sd_start) / 2; - uint32_t image_end = boot_settings.sd_image_start + boot_settings.sd_image_size; - - uint32_t img_block_start = boot_settings.sd_image_start + 2 * block_size; - uint32_t sd_block_start = sd_start + 2 * block_size; - - if (SD_SIZE_GET(MBR_SIZE) < boot_settings.sd_image_size) - { - // This will clear a page thus ensuring the old image is invalidated before swapping. - err_code = dfu_copy_sd((uint32_t *)(sd_start + block_size), - (uint32_t *)(sd_start + block_size), - sizeof(uint32_t)); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = dfu_copy_sd((uint32_t *)sd_start, (uint32_t *)sd_start, sizeof(uint32_t)); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - } - - return dfu_sd_img_block_swap((uint32_t *)img_block_start, - (uint32_t *)sd_block_start, - image_end - img_block_start, - block_size); - } - else - { - if (boot_settings.sd_image_size != 0) - { - return dfu_copy_sd((uint32_t *)boot_settings.sd_image_start, - (uint32_t *)SOFTDEVICE_REGION_START, - boot_settings.sd_image_size); - } - } - - return NRF_SUCCESS; -} - - -uint32_t dfu_bl_image_swap(void) -{ - bootloader_settings_t bootloader_settings; - sd_mbr_command_t sd_mbr_cmd; - - bootloader_settings_get(&bootloader_settings); - - if (bootloader_settings.bl_image_size != 0) - { - uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ? - DFU_BANK_0_REGION_START : - bootloader_settings.sd_image_start + - bootloader_settings.sd_image_size; - - sd_mbr_cmd.command = SD_MBR_COMMAND_COPY_BL; - sd_mbr_cmd.params.copy_bl.bl_src = (uint32_t *)(bl_image_start); - sd_mbr_cmd.params.copy_bl.bl_len = bootloader_settings.bl_image_size / sizeof(uint32_t); - - return sd_mbr_command(&sd_mbr_cmd); - } - return NRF_SUCCESS; -} - - -uint32_t dfu_bl_image_validate(void) -{ - bootloader_settings_t bootloader_settings; - sd_mbr_command_t sd_mbr_cmd; - - bootloader_settings_get(&bootloader_settings); - - if (bootloader_settings.bl_image_size != 0) - { - uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ? - DFU_BANK_0_REGION_START : - bootloader_settings.sd_image_start + - bootloader_settings.sd_image_size; - - sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE; - sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START; - sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)(bl_image_start); - sd_mbr_cmd.params.compare.len = bootloader_settings.bl_image_size / sizeof(uint32_t); - - return sd_mbr_command(&sd_mbr_cmd); - } - return NRF_SUCCESS; -} - - -uint32_t dfu_sd_image_validate(void) -{ - bootloader_settings_t bootloader_settings; - sd_mbr_command_t sd_mbr_cmd; - - bootloader_settings_get(&bootloader_settings); - - if (bootloader_settings.sd_image_size == 0) - { - return NRF_SUCCESS; - } - - if ((SOFTDEVICE_REGION_START + bootloader_settings.sd_image_size) > bootloader_settings.sd_image_start) - { - uint32_t sd_start = SOFTDEVICE_REGION_START; - uint32_t block_size = (bootloader_settings.sd_image_start - sd_start) / 2; - uint32_t image_end = bootloader_settings.sd_image_start + - bootloader_settings.sd_image_size; - - uint32_t img_block_start = bootloader_settings.sd_image_start + 2 * block_size; - uint32_t sd_block_start = sd_start + 2 * block_size; - - if (SD_SIZE_GET(MBR_SIZE) < bootloader_settings.sd_image_size) - { - return NRF_ERROR_NULL; - } - - return dfu_sd_img_block_swap((uint32_t *)img_block_start, - (uint32_t *)sd_block_start, - image_end - img_block_start, - block_size); - } - - sd_mbr_cmd.command = SD_MBR_COMMAND_COMPARE; - sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)SOFTDEVICE_REGION_START; - sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)bootloader_settings.sd_image_start; - sd_mbr_cmd.params.compare.len = bootloader_settings.sd_image_size / sizeof(uint32_t); - - return sd_mbr_command(&sd_mbr_cmd); -} diff --git a/components/libraries/bootloader_dfu/dfu_transport.h b/components/libraries/bootloader_dfu/dfu_transport.h deleted file mode 100644 index 130beb3..0000000 --- a/components/libraries/bootloader_dfu/dfu_transport.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup nrf_dfu_transport DFU transport API. - * @{ - * - * @brief DFU transport module interface. - */ - -#ifndef DFU_TRANSPORT_H__ -#define DFU_TRANSPORT_H__ - -#include - -/**@brief Function for starting the update of Device Firmware. - * - * @retval NRF_SUCCESS Operation success. - */ -uint32_t dfu_transport_update_start(void); - -/**@brief Function for closing the transport layer. - * - * @retval NRF_SUCCESS Operation success. - */ -uint32_t dfu_transport_close(void); - -#endif // DFU_TRANSPORT_H__ - -/**@} */ diff --git a/components/libraries/bootloader_dfu/dfu_transport_ble.c b/components/libraries/bootloader_dfu/dfu_transport_ble.c deleted file mode 100644 index ac6bbbd..0000000 --- a/components/libraries/bootloader_dfu/dfu_transport_ble.c +++ /dev/null @@ -1,1109 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "dfu_transport.h" -#include "dfu.h" -#include -#include -#include -#include "boards.h" -#include "nrf.h" -#include "nrf_sdm.h" -#include "nrf_gpio.h" -#include "app_util.h" -#include "app_error.h" -#include "softdevice_handler.h" -#include "ble_stack_handler_types.h" -#include "ble_advdata.h" -#include "ble_l2cap.h" -#include "ble_gap.h" -#include "ble_gatt.h" -#include "ble_hci.h" -#include "ble_dfu.h" -#include "nordic_common.h" -#include "app_timer.h" -#include "ble_conn_params.h" -#include "hci_mem_pool.h" -#include "bootloader.h" -#include "dfu_ble_svc_internal.h" -#include "nrf_delay.h" - -#define DFU_REV_MAJOR 0x00 /** DFU Major revision number to be exposed. */ -#define DFU_REV_MINOR 0x08 /** DFU Minor revision number to be exposed. */ -#define DFU_REVISION ((DFU_REV_MAJOR << 8) | DFU_REV_MINOR) /** DFU Revision number to be exposed. Combined of major and minor versions. */ -#define ADVERTISING_LED_PIN_NO BSP_LED_0 /**< Is on when device is advertising. */ -#define CONNECTED_LED_PIN_NO BSP_LED_1 /**< Is on when device has connected. */ -#define DFU_SERVICE_HANDLE 0x000C /**< Handle of DFU service when DFU service is first service initialized. */ -#define BLE_HANDLE_MAX 0xFFFF /**< Max handle value is BLE. */ - -#define DEVICE_NAME "DfuTarg" /**< Name of device. Will be included in the advertising data. */ -#define MANUFACTURER_NAME "NordicSemiconductor" /**< Manufacturer. Will be passed to Device Information Service. */ - -#define MIN_CONN_INTERVAL (uint16_t)(MSEC_TO_UNITS(15, UNIT_1_25_MS)) /**< Minimum acceptable connection interval (11.25 milliseconds). */ -#define MAX_CONN_INTERVAL (uint16_t)(MSEC_TO_UNITS(30, UNIT_1_25_MS)) /**< Maximum acceptable connection interval (15 milliseconds). */ -#define SLAVE_LATENCY 0 /**< Slave latency. */ -#define CONN_SUP_TIMEOUT (4 * 100) /**< Connection supervisory timeout (4 seconds). */ - -#define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ - -#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(100, APP_TIMER_PRESCALER) /**< Time from the Connected event to first time sd_ble_gap_conn_param_update is called (100 milliseconds). */ -#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(500, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (500 milliseconds). */ -#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ - -#define APP_ADV_INTERVAL MSEC_TO_UNITS(25, UNIT_0_625_MS) /**< The advertising interval (25 ms.). */ -#define APP_ADV_TIMEOUT_IN_SECONDS BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED /**< The advertising timeout in units of seconds. This is set to @ref BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED so that the advertisement is done as long as there there is a call to @ref dfu_transport_close function.*/ -#define APP_DIRECTED_ADV_TIMEOUT 50 /**< number of direct advertisement (each lasting 1.28seconds). */ -#define PEER_ADDRESS_TYPE_INVALID 0xFF /**< Value indicating that no valid peer address exists. This will be the case when a private resolvable address is used in which case there is no address available but instead an IRK is present. */ -#define PEER_ADDRESS_TYPE_INVALID 0xFF /**< Value indicating that no valid peer address exists. This will be the case when a private resolvable address is used in which case there is no address available but instead an IRK is present. */ - -#define SEC_PARAM_TIMEOUT 30 /**< Timeout for Pairing Request or Security Request (in seconds). */ -#define SEC_PARAM_BOND 0 /**< Perform bonding. */ -#define SEC_PARAM_MITM 0 /**< Man In The Middle protection not required. */ -#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */ -#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */ -#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */ -#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */ - -#define MAX_SIZE_OF_BLE_STACK_EVT (sizeof(ble_evt_t) + BLE_L2CAP_MTU_DEF) /**< Maximum size (in bytes) of the event received from S110 SoftDevice.*/ -#define NUM_WORDS_RESERVED_FOR_BLE_EVENTS CEIL_DIV(MAX_SIZE_OF_BLE_STACK_EVT, sizeof(uint32_t)) /**< Size of the memory (in words) reserved for receiving S110 SoftDevice events. */ - -#define IS_CONNECTED() (m_conn_handle != BLE_CONN_HANDLE_INVALID) /**< Macro to determine if the device is in connected state. */ - -#define APP_FEATURE_NOT_SUPPORTED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2 /**< Reply when unsupported features are requested. */ -#define SD_IMAGE_SIZE_OFFSET 0 /**< Offset in start packet for the size information for SoftDevice. */ -#define BL_IMAGE_SIZE_OFFSET 4 /**< Offset in start packet for the size information for bootloader. */ -#define APP_IMAGE_SIZE_OFFSET 8 /**< Offset in start packet for the size information for application. */ - - -/**@brief Packet type enumeration. - */ -typedef enum -{ - PKT_TYPE_INVALID, /**< Invalid packet type. Used for initialization purpose.*/ - PKT_TYPE_START, /**< Start packet.*/ - PKT_TYPE_INIT, /**< Init packet.*/ - PKT_TYPE_FIRMWARE_DATA /**< Firmware data packet.*/ -} pkt_type_t; - -static ble_gap_sec_params_t m_sec_params; /**< Security requirements for this application. */ -static ble_gap_adv_params_t m_adv_params; /**< Parameters to be passed to the stack when starting advertising. */ -static ble_dfu_t m_dfu; /**< Structure used to identify the Device Firmware Update service. */ -static pkt_type_t m_pkt_type; /**< Type of packet to be expected from the DFU Controller. */ -static uint8_t m_update_mode; /**< Type of update mode specified by the DFU Controller. */ -static uint32_t m_num_of_firmware_bytes_rcvd; /**< Cumulative number of bytes of firmware data received. */ -static uint16_t m_pkt_notif_target; /**< Number of packets of firmware data to be received before transmitting the next Packet Receipt Notification to the DFU Controller. */ -static uint16_t m_pkt_notif_target_cnt; /**< Number of packets of firmware data received after sending last Packet Receipt Notification or since the receipt of a @ref BLE_DFU_PKT_RCPT_NOTIF_ENABLED event from the DFU service, which ever occurs later.*/ -static uint8_t * mp_rx_buffer; /**< Pointer to a RX buffer.*/ -static bool m_tear_down_in_progress = false; /**< Variable to indicate whether a tear down is in progress. A tear down could be because the application has initiated it or the peer has disconnected. */ -static bool m_pkt_rcpt_notif_enabled = false; /**< Variable to denote whether packet receipt notification has been enabled by the DFU controller.*/ -static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */ -static bool m_is_advertising = false; /**< Variable to indicate if advertising is ongoing.*/ -static dfu_ble_peer_data_t m_ble_peer_data; /**< BLE Peer data exchanged from application on buttonless update mode. */ -static bool m_ble_peer_data_valid = false; /**< True if BLE Peer data has been exchanged from application. */ -static uint32_t m_direct_adv_cnt = APP_DIRECTED_ADV_TIMEOUT; /**< Counter of direct advertisements. */ -static uint8_t * mp_final_packet; /**< Pointer to final data packet received. When callback for succesful packet handling is received from dfu bank handling a transfer complete response can be sent to peer. */ - - -/**@brief Function updating Service Changed CCCD and indicate a service change to peer. - * - * @details This function will verify the CCCD setting provided with \ref m_ble_peer_data and - * update the system attributes accordingly. If Service Change CCCD is set to indicate - * then a service change indication will be send to the peer. - * - * @retval NRF_INVALID_STATE if no connection has been established to a central. - * @return Any error code returned by SoftDevice function calls. - */ -static uint32_t service_change_indicate() -{ - uint32_t err_code; - - if (m_conn_handle == BLE_CONN_HANDLE_INVALID) - { - return NRF_ERROR_INVALID_STATE; - } - - if (m_ble_peer_data_valid) - { - err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, - m_ble_peer_data.sys_serv_attr, - sizeof(m_ble_peer_data.sys_serv_attr), - BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, - NULL, - 0, - BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = sd_ble_gatts_service_changed(m_conn_handle, DFU_SERVICE_HANDLE, BLE_HANDLE_MAX); - if ((err_code == BLE_ERROR_INVALID_CONN_HANDLE) || - (err_code == NRF_ERROR_INVALID_STATE) || - (err_code == BLE_ERROR_NO_TX_BUFFERS)) - { - // Those errors can be expected when sending trying to send Service Changed Indication - // if the CCCD is not set to indicate. Thus set the returning error code to success. - err_code = NRF_SUCCESS; - } - } - else - { - err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); - } - - return err_code; -} - - -/**@brief Function to convert an nRF51 error code to a DFU Response Value. - * - * @details This function will convert a given nRF51 error code to a DFU Response Value. The - * result of this function depends on the current DFU procedure in progress, given as - * input in current_dfu_proc parameter. - * - * @param[in] err_code The nRF51 error code to be converted. - * @param[in] current_dfu_proc Current DFU procedure in progress. - * - * @return Converted Response Value. - */ -static ble_dfu_resp_val_t nrf_err_code_translate(uint32_t err_code, - const ble_dfu_procedure_t current_dfu_proc) -{ - switch (err_code) - { - case NRF_SUCCESS: - return BLE_DFU_RESP_VAL_SUCCESS; - - case NRF_ERROR_INVALID_STATE: - return BLE_DFU_RESP_VAL_INVALID_STATE; - - case NRF_ERROR_NOT_SUPPORTED: - return BLE_DFU_RESP_VAL_NOT_SUPPORTED; - - case NRF_ERROR_DATA_SIZE: - return BLE_DFU_RESP_VAL_DATA_SIZE; - - case NRF_ERROR_INVALID_DATA: - if (current_dfu_proc == BLE_DFU_VALIDATE_PROCEDURE) - { - // When this error is received in Validation phase, then it maps to a CRC Error. - // Refer dfu_image_validate function for more information. - return BLE_DFU_RESP_VAL_CRC_ERROR; - } - return BLE_DFU_RESP_VAL_OPER_FAILED; - - default: - return BLE_DFU_RESP_VAL_OPER_FAILED; - } -} - - -/**@brief Function for handling the callback events from the dfu module. - * Callbacks are expected when \ref dfu_data_pkt_handle has been executed. - * - * @param[in] packet Packet type for which this callback is related. - * @param[in] result Operation result code. NRF_SUCCESS when a queued operation was successful. - * @param[in] p_data Pointer to the data to which the operation is related. - */ -static void dfu_cb_handler(uint32_t packet, uint32_t result, uint8_t * p_data) -{ - switch (packet) - { - ble_dfu_resp_val_t resp_val; - uint32_t err_code; - - case DATA_PACKET: - if (result != NRF_SUCCESS) - { - // Disconnect from peer. - if (IS_CONNECTED()) - { - err_code = sd_ble_gap_disconnect(m_conn_handle, - BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); - APP_ERROR_CHECK(err_code); - } - } - else - { - err_code = hci_mem_pool_rx_consume(p_data); - APP_ERROR_CHECK(err_code); - - // If the callback matches final data packet received then the peer is notified. - if (mp_final_packet == p_data) - { - // Notify the DFU Controller about the success of the procedure. - err_code = ble_dfu_response_send(&m_dfu, - BLE_DFU_RECEIVE_APP_PROCEDURE, - BLE_DFU_RESP_VAL_SUCCESS); - APP_ERROR_CHECK(err_code); - } - } - break; - - case START_PACKET: - // Translate the err_code returned by the above function to DFU Response Value. - resp_val = nrf_err_code_translate(result, BLE_DFU_START_PROCEDURE); - - err_code = ble_dfu_response_send(&m_dfu, - BLE_DFU_START_PROCEDURE, - resp_val); - APP_ERROR_CHECK(err_code); - break; - - default: - // ignore. - break; - } -} - - -/**@brief Function for notifying a DFU Controller about error conditions in the DFU module. - * This function also ensures that an error is translated from nrf_errors to DFU Response - * Value. - * - * @param[in] p_dfu DFU Service Structure. - * @param[in] err_code Nrf error code that should be translated and send to the DFU Controller. - */ -static void dfu_error_notify(ble_dfu_t * p_dfu, uint32_t err_code) -{ - // An error has occurred. Notify the DFU Controller about this error condition. - // Translate the err_code returned to DFU Response Value. - ble_dfu_resp_val_t resp_val; - - resp_val = nrf_err_code_translate(err_code, BLE_DFU_RECEIVE_APP_PROCEDURE); - - err_code = ble_dfu_response_send(p_dfu, BLE_DFU_RECEIVE_APP_PROCEDURE, resp_val); - APP_ERROR_CHECK(err_code); -} - - -/**@brief Function for processing start data written by the peer to the DFU Packet - * Characteristic. - * - * @param[in] p_dfu DFU Service Structure. - * @param[in] p_evt Pointer to the event received from the S110 SoftDevice. - */ -static void start_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) -{ - uint32_t err_code; - - dfu_start_packet_t start_packet = {.dfu_update_mode = m_update_mode}; - dfu_update_packet_t update_packet = - { - .packet_type = START_PACKET, - .params.start_packet = &start_packet - }; - - uint32_t length = p_evt->evt.ble_dfu_pkt_write.len; - - // Verify that the data is exactly three * four bytes (three words) long. - if (length != (3 * sizeof(uint32_t))) - { - err_code = ble_dfu_response_send(p_dfu, - BLE_DFU_START_PROCEDURE, - BLE_DFU_RESP_VAL_NOT_SUPPORTED); - APP_ERROR_CHECK(err_code); - } - else - { - // Extract the size of from the DFU Packet Characteristic. - uint8_t * p_length_data = p_evt->evt.ble_dfu_pkt_write.p_data; - - start_packet.sd_image_size = uint32_decode(p_length_data + SD_IMAGE_SIZE_OFFSET); - start_packet.bl_image_size = uint32_decode(p_length_data + BL_IMAGE_SIZE_OFFSET); - start_packet.app_image_size = uint32_decode(p_length_data + APP_IMAGE_SIZE_OFFSET); - - err_code = dfu_start_pkt_handle(&update_packet); - if (err_code != NRF_SUCCESS) - { - // Translate the err_code returned by the above function to DFU Response Value. - ble_dfu_resp_val_t resp_val; - - resp_val = nrf_err_code_translate(err_code, BLE_DFU_START_PROCEDURE); - err_code = ble_dfu_response_send(p_dfu, BLE_DFU_START_PROCEDURE, resp_val); - } - - APP_ERROR_CHECK(err_code); - } -} - - -/**@brief Function for processing initialization data written by the peer to the DFU Packet - * Characteristic. - * - * @param[in] p_dfu DFU Service Structure. - * @param[in] p_evt Pointer to the event received from the S110 SoftDevice. - */ -static void init_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) -{ - uint32_t err_code; - dfu_update_packet_t dfu_pkt; - - // The DFU module accepts the dfu_pkt.packet_length to be in 'number of words'. And so if the - // received data does not have a size which is a multiple of four, it should be padded with - // zeros and the packet_length should be incremented accordingly before calling - // dfu_init_pkt_handle. - if ((p_evt->evt.ble_dfu_pkt_write.len & (sizeof(uint32_t) - 1)) != 0) - { - uint32_t padding; - uint32_t i; - uint8_t pkt_length = p_evt->evt.ble_dfu_pkt_write.len; - - // Find out the number of bytes to be padded. - padding = sizeof(uint32_t) - (pkt_length & (sizeof(uint32_t) - 1)); - - for (i = 0; i < padding; i++) - { - p_evt->evt.ble_dfu_pkt_write.p_data[pkt_length++] = 0; - } - - p_evt->evt.ble_dfu_pkt_write.len = pkt_length; - } - - dfu_pkt.packet_type = INIT_PACKET; - - dfu_pkt.params.data_packet.p_data_packet = (uint32_t *)p_evt->evt.ble_dfu_pkt_write.p_data; - dfu_pkt.params.data_packet.packet_length = p_evt->evt.ble_dfu_pkt_write.len / sizeof(uint32_t); - - err_code = dfu_init_pkt_handle(&dfu_pkt); - - // Translate the err_code returned by the above function to DFU Response Value. - if (err_code != NRF_SUCCESS) - { - ble_dfu_resp_val_t resp_val = nrf_err_code_translate(err_code, BLE_DFU_INIT_PROCEDURE); - - err_code = ble_dfu_response_send(p_dfu, BLE_DFU_INIT_PROCEDURE, resp_val); - APP_ERROR_CHECK(err_code); - } -} - - -/**@brief Function for processing application data written by the peer to the DFU Packet - * Characteristic. - * - * @param[in] p_dfu DFU Service Structure. - * @param[in] p_evt Pointer to the event received from the S110 SoftDevice. - */ -static void app_data_process(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) -{ - uint32_t err_code; - - if ((p_evt->evt.ble_dfu_pkt_write.len & (sizeof(uint32_t) - 1)) != 0) - { - // Data length is not a multiple of 4 (word size). - err_code = ble_dfu_response_send(p_dfu, - BLE_DFU_RECEIVE_APP_PROCEDURE, - BLE_DFU_RESP_VAL_NOT_SUPPORTED); - APP_ERROR_CHECK(err_code); - return; - } - - uint32_t length = p_evt->evt.ble_dfu_pkt_write.len; - - err_code = hci_mem_pool_rx_produce(length, (void **) &mp_rx_buffer); - if (err_code != NRF_SUCCESS) - { - dfu_error_notify(p_dfu, err_code); - return; - } - - uint8_t * p_data_packet = p_evt->evt.ble_dfu_pkt_write.p_data; - - memcpy(mp_rx_buffer, p_data_packet, length); - - err_code = hci_mem_pool_rx_data_size_set(length); - if (err_code != NRF_SUCCESS) - { - dfu_error_notify(p_dfu, err_code); - return; - } - - err_code = hci_mem_pool_rx_extract(&mp_rx_buffer, &length); - if (err_code != NRF_SUCCESS) - { - dfu_error_notify(p_dfu, err_code); - return; - } - - dfu_update_packet_t dfu_pkt; - - dfu_pkt.packet_type = DATA_PACKET; - dfu_pkt.params.data_packet.packet_length = length / sizeof(uint32_t); - dfu_pkt.params.data_packet.p_data_packet = (uint32_t *)mp_rx_buffer; - - err_code = dfu_data_pkt_handle(&dfu_pkt); - - if (err_code == NRF_SUCCESS) - { - m_num_of_firmware_bytes_rcvd += p_evt->evt.ble_dfu_pkt_write.len; - - // All the expected firmware data has been received and processed successfully. - // Response will be sent when flash operation for final packet is completed. - mp_final_packet = mp_rx_buffer; - } - else if (err_code == NRF_ERROR_INVALID_LENGTH) - { - // Firmware data packet was handled successfully. And more firmware data is expected. - m_num_of_firmware_bytes_rcvd += p_evt->evt.ble_dfu_pkt_write.len; - - // Check if a packet receipt notification is needed to be sent. - if (m_pkt_rcpt_notif_enabled) - { - // Decrement the counter for the number firmware packets needed for sending the - // next packet receipt notification. - m_pkt_notif_target_cnt--; - - if (m_pkt_notif_target_cnt == 0) - { - err_code = ble_dfu_pkts_rcpt_notify(p_dfu, m_num_of_firmware_bytes_rcvd); - APP_ERROR_CHECK(err_code); - - // Reset the counter for the number of firmware packets. - m_pkt_notif_target_cnt = m_pkt_notif_target; - } - } - } - else - { - uint32_t hci_error = hci_mem_pool_rx_consume(mp_rx_buffer); - if (hci_error != NRF_SUCCESS) - { - dfu_error_notify(p_dfu, hci_error); - } - - dfu_error_notify(p_dfu, err_code); - } -} - - -/**@brief Function for processing data written by the peer to the DFU Packet Characteristic. - * - * @param[in] p_dfu DFU Service Structure. - * @param[in] p_evt Pointer to the event received from the S110 SoftDevice. - */ -static void on_dfu_pkt_write(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) -{ - // The peer has written to the DFU Packet characteristic. Depending on the value of - // the current value of the DFU Control Point, the appropriate action is taken. - switch (m_pkt_type) - { - case PKT_TYPE_START: - // The peer has written a start packet to the DFU Packet characteristic. - start_data_process(p_dfu, p_evt); - break; - - case PKT_TYPE_INIT: - // The peer has written an init packet to the DFU Packet characteristic. - init_data_process(p_dfu, p_evt); - break; - - case PKT_TYPE_FIRMWARE_DATA: - app_data_process(p_dfu, p_evt); - break; - - default: - // It is not possible to find out what packet it is. Ignore. There is no - // mechanism to notify the DFU Controller about this error condition. - break; - } -} - - -/**@brief Function for handling a Connection Parameters error. - * - * @param[in] nrf_error Error code. - */ -static void conn_params_error_handler(uint32_t nrf_error) -{ - APP_ERROR_HANDLER(nrf_error); -} - - -/**@brief Function for initializing the Connection Parameters module. - */ -static void conn_params_init(void) -{ - uint32_t err_code; - ble_conn_params_init_t cp_init; - - memset(&cp_init, 0, sizeof(cp_init)); - - cp_init.p_conn_params = NULL; - cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; - cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; - cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; - cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; - cp_init.disconnect_on_fail = false; - cp_init.evt_handler = NULL; - cp_init.error_handler = conn_params_error_handler; - - err_code = ble_conn_params_init(&cp_init); - APP_ERROR_CHECK(err_code); -} - - -/**@brief Function for the Device Firmware Update Service event handler. - * - * @details This function will be called for all Device Firmware Update Service events which - * are passed to the application. - * - * @param[in] p_dfu Device Firmware Update Service structure. - * @param[in] p_evt Event received from the Device Firmware Update Service. - */ -static void on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt) -{ - uint32_t err_code; - ble_dfu_resp_val_t resp_val; - - switch (p_evt->ble_dfu_evt_type) - { - case BLE_DFU_VALIDATE: - err_code = dfu_image_validate(); - - // Translate the err_code returned by the above function to DFU Response Value. - resp_val = nrf_err_code_translate(err_code, BLE_DFU_VALIDATE_PROCEDURE); - - err_code = ble_dfu_response_send(p_dfu, BLE_DFU_VALIDATE_PROCEDURE, resp_val); - APP_ERROR_CHECK(err_code); - break; - - case BLE_DFU_ACTIVATE_N_RESET: - err_code = dfu_transport_close(); - APP_ERROR_CHECK(err_code); - - // With the S110 Flash API it is safe to initiate the activate before connection is - // fully closed. - err_code = dfu_image_activate(); - if (err_code != NRF_SUCCESS) - { - dfu_reset(); - } - break; - - case BLE_DFU_SYS_RESET: - err_code = dfu_transport_close(); - APP_ERROR_CHECK(err_code); - - dfu_reset(); - break; - - case BLE_DFU_START: - m_pkt_type = PKT_TYPE_START; - m_update_mode = (uint8_t)p_evt->evt.ble_dfu_pkt_write.p_data[0]; - break; - - case BLE_DFU_RECEIVE_INIT_DATA: - m_pkt_type = PKT_TYPE_INIT; - if ((uint8_t)p_evt->evt.ble_dfu_pkt_write.p_data[0] == DFU_INIT_COMPLETE) - { - err_code = dfu_init_pkt_complete(); - - // Translate the err_code returned by the above function to DFU Response Value. - resp_val = nrf_err_code_translate(err_code, BLE_DFU_INIT_PROCEDURE); - - err_code = ble_dfu_response_send(p_dfu, BLE_DFU_INIT_PROCEDURE, resp_val); - APP_ERROR_CHECK(err_code); - } - break; - - case BLE_DFU_RECEIVE_APP_DATA: - m_pkt_type = PKT_TYPE_FIRMWARE_DATA; - break; - - case BLE_DFU_PACKET_WRITE: - on_dfu_pkt_write(p_dfu, p_evt); - break; - - case BLE_DFU_PKT_RCPT_NOTIF_ENABLED: - m_pkt_rcpt_notif_enabled = true; - m_pkt_notif_target = p_evt->evt.pkt_rcpt_notif_req.num_of_pkts; - m_pkt_notif_target_cnt = p_evt->evt.pkt_rcpt_notif_req.num_of_pkts; - break; - - case BLE_DFU_PKT_RCPT_NOTIF_DISABLED: - m_pkt_rcpt_notif_enabled = false; - m_pkt_notif_target = 0; - break; - - case BLE_DFU_BYTES_RECEIVED_SEND: - err_code = ble_dfu_bytes_rcvd_report(p_dfu, m_num_of_firmware_bytes_rcvd); - APP_ERROR_CHECK(err_code); - break; - - default: - // Unsupported event received from DFU Service. Ignore. - break; - } -} - - -/**@brief Function for the Advertising functionality initialization. - * - * @details Encodes the required advertising data and passes it to the stack. - * Also builds a structure to be passed to the stack when starting advertising. - */ -static void advertising_init(uint8_t adv_flags) -{ - uint32_t err_code; - ble_advdata_t advdata; - ble_uuid_t service_uuid; - - service_uuid.type = m_dfu.uuid_type; - service_uuid.uuid = BLE_DFU_SERVICE_UUID; - - // Build and set advertising data. - memset(&advdata, 0, sizeof(advdata)); - - advdata.name_type = BLE_ADVDATA_FULL_NAME; - advdata.include_appearance = false; - advdata.flags = adv_flags; - advdata.uuids_more_available.uuid_cnt = 1; - advdata.uuids_more_available.p_uuids = &service_uuid; - - err_code = ble_advdata_set(&advdata, NULL); - APP_ERROR_CHECK(err_code); -} - - -/**@brief Function for starting advertising. - */ -static void advertising_start(void) -{ - if (!m_is_advertising) - { - uint32_t err_code; - - // Initialize advertising parameters (used when starting advertising). - memset(&m_adv_params, 0, sizeof(m_adv_params)); - - if (m_ble_peer_data_valid) - { - ble_gap_irk_t empty_irk = {{0}}; - - if (memcmp(m_ble_peer_data.irk.irk, empty_irk.irk, sizeof(empty_irk.irk)) == 0) - { - advertising_init(BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE); - m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND; - m_adv_params.p_peer_addr = &m_ble_peer_data.addr; - m_adv_params.fp = BLE_GAP_ADV_FP_ANY; - m_adv_params.interval = 0; - m_adv_params.timeout = 0; - } - else - { - ble_gap_irk_t * p_irk[1]; - ble_gap_addr_t * p_addr[1]; - - p_irk[0] = &m_ble_peer_data.irk; - p_addr[0] = &m_ble_peer_data.addr; - - ble_gap_whitelist_t whitelist; - whitelist.addr_count = 1; - whitelist.pp_addrs = p_addr; - whitelist.irk_count = 1; - whitelist.pp_irks = p_irk; - - advertising_init(BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED); - m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; - m_adv_params.fp = BLE_GAP_ADV_FP_FILTER_CONNREQ; - m_adv_params.p_whitelist = &whitelist; - m_adv_params.interval = APP_ADV_INTERVAL; - m_adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS; - } - } - else - { - advertising_init(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); - m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; - m_adv_params.p_peer_addr = NULL; - m_adv_params.fp = BLE_GAP_ADV_FP_ANY; - m_adv_params.interval = APP_ADV_INTERVAL; - m_adv_params.timeout = APP_ADV_TIMEOUT_IN_SECONDS; - } - - err_code = sd_ble_gap_adv_start(&m_adv_params); - APP_ERROR_CHECK(err_code); - - nrf_gpio_pin_clear(ADVERTISING_LED_PIN_NO); - - m_is_advertising = true; - } -} - - -/**@brief Function for stopping advertising. - */ -static void advertising_stop(void) -{ - if (m_is_advertising) - { - uint32_t err_code; - - err_code = sd_ble_gap_adv_stop(); - APP_ERROR_CHECK(err_code); - - nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); - - m_is_advertising = false; - } -} - - -/**@brief Function for the Application's S110 SoftDevice event handler. - * - * @param[in] p_ble_evt S110 SoftDevice event. - */ -static void on_ble_evt(ble_evt_t * p_ble_evt) -{ - uint32_t err_code; - ble_gatts_rw_authorize_reply_params_t auth_reply; - - switch (p_ble_evt->header.evt_id) - { - case BLE_GAP_EVT_CONNECTED: - nrf_gpio_pin_clear(CONNECTED_LED_PIN_NO); - nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); - - m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; - m_is_advertising = false; - break; - - case BLE_GAP_EVT_DISCONNECTED: - { - uint8_t sys_attr[128]; - uint16_t sys_attr_len = 128; - - m_direct_adv_cnt = APP_DIRECTED_ADV_TIMEOUT; - nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); - - err_code = sd_ble_gatts_sys_attr_get(m_conn_handle, - sys_attr, - &sys_attr_len, - BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS); - APP_ERROR_CHECK(err_code); - - } - if (!m_tear_down_in_progress) - { - // The Disconnected event is because of an external event. (Link loss or - // disconnect triggered by the DFU Controller before the firmware update was - // complete). - // Restart advertising so that the DFU Controller can reconnect if possible. - advertising_start(); - } - - m_conn_handle = BLE_CONN_HANDLE_INVALID; - - break; - - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - { - ble_gap_sec_keyset_t keys; - ble_gap_enc_key_t enc_key; - ble_gap_id_key_t id_key; - - id_key.id_addr_info = m_ble_peer_data.addr; - id_key.id_info = m_ble_peer_data.irk; - enc_key = m_ble_peer_data.enc_key; - - keys.keys_central.p_id_key = &id_key; - keys.keys_central.p_enc_key = &enc_key; - - err_code = sd_ble_gap_sec_params_reply(m_conn_handle, - BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, - &m_sec_params, - &keys); - APP_ERROR_CHECK(err_code); - } - break; - - case BLE_GATTS_EVT_TIMEOUT: - if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL) - { - err_code = sd_ble_gap_disconnect(m_conn_handle, - BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); - APP_ERROR_CHECK(err_code); - } - break; - - case BLE_GAP_EVT_TIMEOUT: - if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) - { - m_is_advertising = false; - m_direct_adv_cnt--; - if (m_direct_adv_cnt == 0) - { - dfu_update_status_t update_status = {.status_code = DFU_TIMEOUT}; - bootloader_dfu_update_process(update_status); - } - else - { - advertising_start(); - } - } - break; - - case BLE_EVT_USER_MEM_REQUEST: - err_code = sd_ble_user_mem_reply(m_conn_handle, NULL); - APP_ERROR_CHECK(err_code); - break; - - case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: - if (p_ble_evt->evt.gatts_evt.params.authorize_request.type - != BLE_GATTS_AUTHORIZE_TYPE_INVALID) - { - if ((p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op - == BLE_GATTS_OP_PREP_WRITE_REQ) - || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op - == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) - || (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op - == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) - { - if (p_ble_evt->evt.gatts_evt.params.authorize_request.type - == BLE_GATTS_AUTHORIZE_TYPE_WRITE) - { - auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; - } - else - { - auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; - } - auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; - - err_code = sd_ble_gatts_rw_authorize_reply(m_conn_handle,&auth_reply); - APP_ERROR_CHECK(err_code); - } - } - break; - - case BLE_GAP_EVT_SEC_INFO_REQUEST: - { - ble_gap_enc_info_t * p_enc_info = NULL; - - // If there is a match in diversifier then set the correct keys. - if (p_ble_evt->evt.gap_evt.params.sec_info_request.master_id.ediv == - m_ble_peer_data.enc_key.master_id.ediv) - { - p_enc_info = &m_ble_peer_data.enc_key.enc_info; - } - - err_code = sd_ble_gap_sec_info_reply(p_ble_evt->evt.gap_evt.conn_handle, - p_enc_info, - &m_ble_peer_data.irk, - NULL); - APP_ERROR_CHECK(err_code); - } - break; - - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - case BLE_GAP_EVT_CONN_SEC_UPDATE: - err_code = service_change_indicate(); - APP_ERROR_CHECK(err_code); - break; - - case BLE_GAP_EVT_AUTH_STATUS: - // No implementation needed. - break; - - default: - // No implementation needed. - break; - } -} - - -/**@brief Function for dispatching a S110 SoftDevice event to all modules with a S110 - * SoftDevice event handler. - * - * @details This function is called from the S110 SoftDevice event interrupt handler after a - * S110 SoftDevice event has been received. - * - * @param[in] p_ble_evt S110 SoftDevice event. - */ -static void ble_evt_dispatch(ble_evt_t * p_ble_evt) -{ - ble_conn_params_on_ble_evt(p_ble_evt); - ble_dfu_on_ble_evt(&m_dfu, p_ble_evt); - on_ble_evt(p_ble_evt); -} - - -/**@brief Function for the LEDs initialization. - * - * @details Initializes all LEDs used by this application. - */ -static void leds_init(void) -{ - nrf_gpio_cfg_output(ADVERTISING_LED_PIN_NO); - nrf_gpio_cfg_output(CONNECTED_LED_PIN_NO); - nrf_gpio_pin_set(ADVERTISING_LED_PIN_NO); - nrf_gpio_pin_set(CONNECTED_LED_PIN_NO); -} - - -/**@brief Function for the GAP initialization. - * - * @details This function will setup all the necessary GAP (Generic Access Profile) parameters of - * the device. It also sets the permissions and appearance. - */ -static void gap_params_init(void) -{ - uint32_t err_code; - ble_gap_conn_params_t gap_conn_params; - ble_gap_conn_sec_mode_t sec_mode; - - BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); - - err_code = sd_ble_gap_device_name_set(&sec_mode, - (const uint8_t *)DEVICE_NAME, - strlen(DEVICE_NAME)); - APP_ERROR_CHECK(err_code); - - memset(&gap_conn_params, 0, sizeof(gap_conn_params)); - - gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; - gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; - gap_conn_params.slave_latency = SLAVE_LATENCY; - gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; - - err_code = sd_ble_gap_ppcp_set(&gap_conn_params); - APP_ERROR_CHECK(err_code); -} - - -/**@brief Function for handling Service errors. - * - * @details A pointer to this function will be passed to the DFU service which may need to inform - * the application about an error. - * - * @param[in] nrf_error Error code containing information about what went wrong. - */ -static void service_error_handler(uint32_t nrf_error) -{ - APP_ERROR_HANDLER(nrf_error); -} - - -/**@brief Function for initializing services that will be used by the application. - */ -static void services_init(void) -{ - uint32_t err_code; - ble_dfu_init_t dfu_init_obj; - - // Initialize the Device Firmware Update Service. - memset(&dfu_init_obj, 0, sizeof(dfu_init_obj)); - - dfu_init_obj.revision = DFU_REVISION; - dfu_init_obj.evt_handler = on_dfu_evt; - dfu_init_obj.error_handler = service_error_handler; - - err_code = ble_dfu_init(&m_dfu, &dfu_init_obj); - - APP_ERROR_CHECK(err_code); -} - - -/**@brief Function for initializing security parameters. - */ -static void sec_params_init(void) -{ - m_sec_params.bond = SEC_PARAM_BOND; - m_sec_params.mitm = SEC_PARAM_MITM; - m_sec_params.io_caps = SEC_PARAM_IO_CAPABILITIES; - m_sec_params.oob = SEC_PARAM_OOB; - m_sec_params.min_key_size = SEC_PARAM_MIN_KEY_SIZE; - m_sec_params.max_key_size = SEC_PARAM_MAX_KEY_SIZE; -} - - -uint32_t dfu_transport_update_start(void) -{ - uint32_t err_code; - - m_tear_down_in_progress = false; - m_pkt_type = PKT_TYPE_INVALID; - - leds_init(); - - err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - dfu_register_callback(dfu_cb_handler); - - err_code = hci_mem_pool_open(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = dfu_ble_peer_data_get(&m_ble_peer_data); - if (err_code == NRF_SUCCESS) - { - m_ble_peer_data_valid = true; - } - else - { - ble_gap_addr_t addr; - - err_code = sd_ble_gap_address_get(&addr); - APP_ERROR_CHECK(err_code); - - // Increase the BLE address by one when advertising openly. - addr.addr[0] += 1; - - err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &addr); - APP_ERROR_CHECK(err_code); - } - - gap_params_init(); - services_init(); - conn_params_init(); - sec_params_init(); - advertising_start(); - - return NRF_SUCCESS; -} - - -uint32_t dfu_transport_close() -{ - uint32_t err_code; - - m_tear_down_in_progress = true; - - if (IS_CONNECTED()) - { - // Disconnect from peer. - err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); - APP_ERROR_CHECK(err_code); - } - else - { - // If not connected, then the device will be advertising. Hence stop the advertising. - advertising_stop(); - } - - err_code = ble_conn_params_stop(); - APP_ERROR_CHECK(err_code); - - return NRF_SUCCESS; -} diff --git a/components/libraries/bootloader_dfu/dfu_transport_serial.c b/components/libraries/bootloader_dfu/dfu_transport_serial.c deleted file mode 100644 index 51ef4e1..0000000 --- a/components/libraries/bootloader_dfu/dfu_transport_serial.c +++ /dev/null @@ -1,306 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "dfu_transport.h" -#include -#include "dfu.h" -#include -#include "app_error.h" -#include "app_util.h" -#include "hci_transport.h" -#include "app_timer.h" -#include "app_scheduler.h" - -#define MAX_BUFFERS 4u /**< Maximum number of buffers that can be received queued without being consumed. */ - -/** - * defgroup Data Packet Queue Access Operation Macros - * @{ - */ - -/** Provides status showing if the queue is full or not. */ -#define DATA_QUEUE_FULL() \ - (((MAX_BUFFERS -1) == m_data_queue.count) ? true : false) - -/** Provides status showing if the queue is empty or not */ -#define DATA_QUEUE_EMPTY() \ - ((0 == m_data_queue.count) ? true : false) - -/** Initializes an element of the data queue. */ -#define DATA_QUEUE_ELEMENT_INIT(i) \ - m_data_queue.data_packet[(i)].packet_type = INVALID_PACKET - -/** Sets the packet type of an element of the data queue. */ -#define DATA_QUEUE_ELEMENT_SET_PTYPE(i, t) \ - m_data_queue.data_packet[(i)].packet_type = (t) - -/** Copies a data packet pointer of an element of the data queue. */ -#define DATA_QUEUE_ELEMENT_COPY_PDATA(i, dp) \ - m_data_queue.data_packet[(i)].params.data_packet.p_data_packet = (uint32_t *)(dp) - -/** Sets the packet length of an element in the data queue. */ -#define DATA_QUEUE_ELEMENT_SET_PLEN(i, l) \ - m_data_queue.data_packet[(i)].params.data_packet.packet_length = (l) - -/** Gets a data packet pointer of an element in the data queue. */ -#define DATA_QUEUE_ELEMENT_GET_PDATA(i) \ - (m_data_queue.data_packet[(i)].params.data_packet.p_data_packet) - -/** Gets the packet type of an element in the data queue. */ -#define DATA_QUEUE_ELEMENT_GET_PTYPE(i) \ - m_data_queue.data_packet[(i)].packet_type - -/* @} */ - -/** Abstracts data packet queue */ -typedef struct -{ - dfu_update_packet_t data_packet[MAX_BUFFERS]; /**< Bootloader data packets used when processing data from the UART. */ - volatile uint8_t count; /**< Counter to maintain number of elements in the queue. */ -} dfu_data_queue_t; - -static dfu_data_queue_t m_data_queue; /**< Received-data packet queue. */ - -/**@brief Initializes an element of the data buffer queue. - * - * @param[in] element_index index of the element. - */ -static void data_queue_element_init (uint8_t element_index) -{ - DATA_QUEUE_ELEMENT_INIT(element_index); - DATA_QUEUE_ELEMENT_SET_PTYPE(element_index, INVALID_PACKET); - DATA_QUEUE_ELEMENT_COPY_PDATA(element_index, NULL); - DATA_QUEUE_ELEMENT_SET_PLEN(element_index, 0); -} - -/** Initializes data buffer queue */ -static void data_queue_init(void) -{ - uint32_t index; - - m_data_queue.count = 0; - - for (index = 0; index < MAX_BUFFERS; index++) - { - data_queue_element_init(index); - } -} - -/**@brief Function for freeing an element. - * - * @param[in] element_index index of the element. - */ -static uint32_t data_queue_element_free(uint8_t element_index) -{ - uint8_t * p_data; - uint32_t retval; - - retval = NRF_ERROR_INVALID_PARAM; - - if (MAX_BUFFERS > element_index) - { - p_data = (uint8_t *)DATA_QUEUE_ELEMENT_GET_PDATA(element_index); - if (INVALID_PACKET != DATA_QUEUE_ELEMENT_GET_PTYPE(element_index)) - { - m_data_queue.count--; - data_queue_element_init (element_index); - retval = hci_transport_rx_pkt_consume((p_data - 4)); - APP_ERROR_CHECK(retval); - } - } - else - { - return NRF_ERROR_INVALID_PARAM; - } - - return NRF_SUCCESS; -} - -/**@brief Function for Allocating element. - * - * @param[in] packet_type packet type. - * @param[out] p_element_index index of the element. - */ -static uint32_t data_queue_element_alloc(uint8_t * p_element_index, uint8_t packet_type) -{ - uint32_t retval; - uint32_t index; - - retval = NRF_ERROR_NO_MEM; - - if (INVALID_PACKET == packet_type) - { - retval = NRF_ERROR_INVALID_PARAM; - } - else if (true == DATA_QUEUE_FULL()) - { - retval = NRF_ERROR_NO_MEM; - } - else - { - for (index = 0; index < MAX_BUFFERS; index++) - { - if (INVALID_PACKET == DATA_QUEUE_ELEMENT_GET_PTYPE(index)) - { - // Found a free element: allocate, and end search. - *p_element_index = index; - DATA_QUEUE_ELEMENT_SET_PTYPE(index, packet_type); - retval = NRF_SUCCESS; - m_data_queue.count++; - break; - } - } - } - - return retval; -} - -// Flush everything on disconnect or stop. -static void data_queue_flush(void) -{ - uint32_t index; - - for (index = 0; index < MAX_BUFFERS; index++) - { - // In this case it does not matter if free succeeded or not as data packets are being flushed because DFU Trnsport was closed - (void)data_queue_element_free(index); - } -} - - -/**@brief Function for handling the callback events from the dfu module. - * Callbacks are expected when \ref dfu_data_pkt_handle has been executed. - * - * @param[in] packet Packet type for which this callback is related. START_PACKET, DATA_PACKET. - * @param[in] result Operation result code. NRF_SUCCESS when a queued operation was successful. - * @param[in] p_data Pointer to the data to which the operation is related. - */ -static void dfu_cb_handler(uint32_t packet, uint32_t result, uint8_t * p_data) -{ - APP_ERROR_CHECK(result); -} - - -static void process_dfu_packet(void * p_event_data, uint16_t event_size) -{ - uint32_t retval; - uint32_t index; - dfu_update_packet_t * packet; - - while (false == DATA_QUEUE_EMPTY()) - { - // Fetch the element to be processed. - for (index = 0; index < MAX_BUFFERS ; index++) - { - packet = &m_data_queue.data_packet[index]; - if (INVALID_PACKET != packet->packet_type) - { - - switch (DATA_QUEUE_ELEMENT_GET_PTYPE(index)) - { - case DATA_PACKET: - (void)dfu_data_pkt_handle(packet); - break; - - case START_PACKET: - packet->params.start_packet = - (dfu_start_packet_t*)packet->params.data_packet.p_data_packet; - retval = dfu_start_pkt_handle(packet); - APP_ERROR_CHECK(retval); - break; - - case INIT_PACKET: - (void)dfu_init_pkt_handle(packet); - retval = dfu_init_pkt_complete(); - APP_ERROR_CHECK(retval); - break; - - case STOP_DATA_PACKET: - (void)dfu_image_validate(); - (void)dfu_image_activate(); - - // Break the loop by returning. - return; - - default: - // No implementation needed. - break; - } - - // Free the processed element. - retval = data_queue_element_free(index); - APP_ERROR_CHECK(retval); - } - } - } -} - - -void rpc_transport_event_handler(hci_transport_evt_t event) -{ - uint32_t retval; - uint16_t rpc_cmd_length_read; - uint8_t * p_rpc_cmd_buffer; - uint8_t element_index; - - retval = hci_transport_rx_pkt_extract(&p_rpc_cmd_buffer, &rpc_cmd_length_read); - if (NRF_SUCCESS == retval) - { - // Verify if the data queue can buffer the packet. - retval = data_queue_element_alloc(&element_index, p_rpc_cmd_buffer[0]); - if (NRF_SUCCESS == retval) - { - //subtract 1 since we are interested in payload length and not the type field. - DATA_QUEUE_ELEMENT_SET_PLEN(element_index,(rpc_cmd_length_read / sizeof(uint32_t)) - 1); - DATA_QUEUE_ELEMENT_COPY_PDATA(element_index, &p_rpc_cmd_buffer[4]); - retval = app_sched_event_put(NULL, 0, process_dfu_packet); - } - } - - if (NRF_SUCCESS != retval) - { - // Free the packet that could not be processed. - retval = hci_transport_rx_pkt_consume(p_rpc_cmd_buffer); - APP_ERROR_CHECK(retval); - } -} - - -uint32_t dfu_transport_update_start(void) -{ - uint32_t err_code; - - // Initialize data buffer queue. - data_queue_init(); - - dfu_register_callback(dfu_cb_handler); - - // Open transport layer. - err_code = hci_transport_open(); - APP_ERROR_CHECK(err_code); - - // Register callback to be run when commands have been received by the transport layer. - err_code = hci_transport_evt_handler_reg(rpc_transport_event_handler); - APP_ERROR_CHECK(err_code); - - return NRF_SUCCESS; -} - - -uint32_t dfu_transport_close(void) -{ - // Remove all buffered packets. - data_queue_flush(); - - return hci_transport_close(); -} - diff --git a/components/libraries/bootloader_dfu/dfu_types.h b/components/libraries/bootloader_dfu/dfu_types.h deleted file mode 100644 index c02f2d5..0000000 --- a/components/libraries/bootloader_dfu/dfu_types.h +++ /dev/null @@ -1,147 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup nrf_dfu_types Types and definitions. - * @{ - * - * @ingroup nrf_dfu - * - * @brief Device Firmware Update module type and definitions. - */ - -#ifndef DFU_TYPES_H__ -#define DFU_TYPES_H__ - -#include -#include "nrf_sdm.h" -#include "nrf.h" -#include "app_util.h" - -#define NRF_UICR_BOOT_START_ADDRESS (NRF_UICR_BASE + 0x14) /**< Register where the bootloader start address is stored in the UICR register. */ - -#define CODE_REGION_1_START SD_SIZE_GET(MBR_SIZE) /**< This field should correspond to the size of Code Region 0, (which is identical to Start of Code Region 1), found in UICR.CLEN0 register. This value is used for compile safety, as the linker will fail if application expands into bootloader. Runtime, the bootloader will use the value found in UICR.CLEN0. */ -#define SOFTDEVICE_REGION_START MBR_SIZE /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */ - -#ifdef NRF51 -#ifdef SIGNING -#define BOOTLOADER_REGION_START 0x00039C00 /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */ -#define BOOTLOADER_SETTINGS_ADDRESS 0x0003D800 /**< The field specifies the page location of the bootloader settings address. */ -#else -#define BOOTLOADER_REGION_START 0x0003C000 /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */ -#define BOOTLOADER_SETTINGS_ADDRESS 0x0003FC00 /**< The field specifies the page location of the bootloader settings address. */ -#endif - -#define CODE_PAGE_SIZE 0x0400 /**< Size of a flash codepage. Used for size of the reserved flash space in the bootloader region. Will be runtime checked against NRF_UICR->CODEPAGESIZE to ensure the region is correct. */ -#elif NRF52 -#define BOOTLOADER_REGION_START 0x0007B000 /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register. This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value. The value is used to determine max application size for updating. */ -#define BOOTLOADER_SETTINGS_ADDRESS 0x0007F000 /**< The field specifies the page location of the bootloader settings address. */ -#define CODE_PAGE_SIZE 0x1000 /**< Size of a flash codepage. Used for size of the reserved flash space in the bootloader region. Will be runtime checked against NRF_UICR->CODEPAGESIZE to ensure the region is correct. */ -#else -#error No target defined -#endif - -#define DFU_REGION_TOTAL_SIZE (BOOTLOADER_REGION_START - CODE_REGION_1_START) /**< Total size of the region between SD and Bootloader. */ - -#define DFU_APP_DATA_RESERVED 0x0000 /**< Size of Application Data that must be preserved between application updates. This value must be a multiple of page size. Page size is 0x400 (1024d) bytes, thus this value must be 0x0000, 0x0400, 0x0800, 0x0C00, 0x1000, etc. */ -#define DFU_BANK_PADDING (DFU_APP_DATA_RESERVED % (2 * CODE_PAGE_SIZE)) /**< Padding to ensure that image size banked is always page sized. */ -#define DFU_IMAGE_MAX_SIZE_FULL (DFU_REGION_TOTAL_SIZE - DFU_APP_DATA_RESERVED) /**< Maximum size of an application, excluding save data from the application. */ -#define DFU_IMAGE_MAX_SIZE_BANKED ((DFU_REGION_TOTAL_SIZE - \ - DFU_APP_DATA_RESERVED - \ - DFU_BANK_PADDING) / 2) /**< Maximum size of an application, excluding save data from the application. */ - -#define DFU_BL_IMAGE_MAX_SIZE (BOOTLOADER_SETTINGS_ADDRESS - BOOTLOADER_REGION_START) /**< Maximum size of a bootloader, excluding save data from the current bootloader. */ - -#define DFU_BANK_0_REGION_START CODE_REGION_1_START /**< Bank 0 region start. */ -#define DFU_BANK_1_REGION_START (DFU_BANK_0_REGION_START + DFU_IMAGE_MAX_SIZE_BANKED) /**< Bank 1 region start. */ - -#define EMPTY_FLASH_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */ - -#define INVALID_PACKET 0x00 /**< Invalid packet identifies. */ -#define INIT_PACKET 0x01 /**< Packet identifies for initialization packet. */ -#define STOP_INIT_PACKET 0x02 /**< Packet identifies for stop initialization packet. Used when complete init packet has been received so that the init packet can be used for pre validaiton. */ -#define START_PACKET 0x03 /**< Packet identifies for the Data Start Packet. */ -#define DATA_PACKET 0x04 /**< Packet identifies for a Data Packet. */ -#define STOP_DATA_PACKET 0x05 /**< Packet identifies for the Data Stop Packet. */ - -#define DFU_UPDATE_SD 0x01 /**< Bit field indicating update of SoftDevice is ongoing. */ -#define DFU_UPDATE_BL 0x02 /**< Bit field indicating update of bootloader is ongoing. */ -#define DFU_UPDATE_APP 0x04 /**< Bit field indicating update of application is ongoing. */ - -#define DFU_INIT_RX 0x00 /**< Op Code identifies for receiving init packet. */ -#define DFU_INIT_COMPLETE 0x01 /**< Op Code identifies for transmission complete of init packet. */ - -// Safe guard to ensure during compile time that the DFU_APP_DATA_RESERVED is a multiple of page size. -STATIC_ASSERT((((DFU_APP_DATA_RESERVED) & (CODE_PAGE_SIZE - 1)) == 0x00)); - -/**@brief Structure holding a start packet containing update mode and image sizes. - */ -typedef struct -{ - uint8_t dfu_update_mode; /**< Packet type, used to identify the content of the received packet referenced by data packet. */ - uint32_t sd_image_size; /**< Size of the SoftDevice image to be transferred. Zero if no SoftDevice image will be transfered. */ - uint32_t bl_image_size; /**< Size of the Bootloader image to be transferred. Zero if no Bootloader image will be transfered. */ - uint32_t app_image_size; /**< Size of the application image to be transmitted. Zero if no Bootloader image will be transfered. */ -} dfu_start_packet_t; - -/**@brief Structure holding a bootloader init/data packet received. - */ -typedef struct -{ - uint32_t packet_length; /**< Packet length of the data packet. Each data is word size, meaning length of 4 is 4 words, not bytes. */ - uint32_t * p_data_packet; /**< Data Packet received. Each data is a word size entry. */ -} dfu_data_packet_t; - -/**@brief Structure for holding dfu update packet. Packet type indicate the type of packet. - */ -typedef struct -{ - uint32_t packet_type; /**< Packet type, used to identify the content of the received packet referenced by data packet. */ - union - { - dfu_data_packet_t data_packet; /**< Used when packet type is INIT_PACKET or DATA_PACKET. Packet contains data received for init or data. */ - dfu_start_packet_t * start_packet; /**< Used when packet type is START_DATA_PACKET. Will contain information on software to be updtaed, i.e. SoftDevice, Bootloader and/or Application along with image sizes. */ - } params; -} dfu_update_packet_t; - -/**@brief DFU status error codes. -*/ -typedef enum -{ - DFU_UPDATE_APP_COMPLETE, /**< Status update of application complete.*/ - DFU_UPDATE_SD_COMPLETE, /**< Status update of SoftDevice update complete. Note that this solely indicates that a new SoftDevice has been received and stored in bank 0 and 1. */ - DFU_UPDATE_SD_SWAPPED, /**< Status update of SoftDevice update complete. Note that this solely indicates that a new SoftDevice has been received and stored in bank 0 and 1. */ - DFU_UPDATE_BOOT_COMPLETE, /**< Status update complete.*/ - DFU_BANK_0_ERASED, /**< Status bank 0 erased.*/ - DFU_TIMEOUT, /**< Status timeout.*/ - DFU_RESET /**< Status Reset to indicate current update procedure has been aborted and system should reset. */ -} dfu_update_status_code_t; - -/**@brief Structure holding DFU complete event. -*/ -typedef struct -{ - dfu_update_status_code_t status_code; /**< Device Firmware Update status. */ - uint16_t app_crc; /**< CRC of the recieved application. */ - uint32_t sd_size; /**< Size of the recieved SoftDevice. */ - uint32_t bl_size; /**< Size of the recieved BootLoader. */ - uint32_t app_size; /**< Size of the recieved Application. */ - uint32_t sd_image_start; /**< Location in flash where the received SoftDevice image is stored. */ -} dfu_update_status_t; - -/**@brief Update complete handler type. */ -typedef void (*dfu_complete_handler_t)(dfu_update_status_t dfu_update_status); - -#endif // DFU_TYPES_H__ - -/**@} */ diff --git a/components/libraries/bootloader_dfu/experimental/dfu_init_template_signing.c b/components/libraries/bootloader_dfu/experimental/dfu_init_template_signing.c deleted file mode 100644 index cb91cd4..0000000 --- a/components/libraries/bootloader_dfu/experimental/dfu_init_template_signing.c +++ /dev/null @@ -1,210 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup nrf_dfu_init_template Template file with an DFU init packet handling example. - * @{ - * - * @ingroup nrf_dfu - * - * @brief This file contains a template on how to implement DFU init packet handling. - * - * @details The template shows how device type and revision can be used for a safety check of the - * received image. It shows how validation can be performed in two stages: - * - Stage 1: Pre-check of firmware image before transfer to ensure the firmware matches: - * - Device Type. - * - Device Revision. - * Installed SoftDevice. - * This template can be extended with additional checks according to needs. - * For example, such a check could be the origin of the image (trusted source) - * based on a signature scheme. - * - Stage 2: Post-check of the image after image transfer but before installing firmware. - * For example, such a check could be an integrity check in form of hashing or - * verification of a signature. - * In this template, a simple CRC check is carried out. - * The CRC check can be replaced with other mechanisms, like signing. - * - * @note This module does not support security features such as image signing, but the - * implementation allows for such extension. - * If the init packet is signed by a trusted source, it must be decrypted before it can be - * processed. - */ - -#include "dfu_init.h" -#include -#include -#include -#include "nrf_sec.h" -#include "nrf_error.h" -#include "crc16.h" - -// The following is the layout of the extended init packet if using image length and sha256 to validate image -// and NIST P-256 + SHA256 to sign the init_package including the extended part -#define DFU_INIT_PACKET_POS_EXT_IDENTIFIER 0 //< Position of the identifier for the ext package -#define DFU_INIT_PACKET_POS_EXT_IMAGE_LENGTH 4 //< Position of the image length -#define DFU_INIT_PACKET_POS_EXT_IMAGE_HASH256 8 //< Position of the 256 -#define DFU_INIT_PACKET_POS_EXT_INIT_SIGNATURE_R 40 //< Position of the Signature R -#define DFU_INIT_PACKET_POS_EXT_INIT_SIGNATURE_S 72 //< Position of the Signature S -#define DFU_INIT_PACKET_EXT_LENGTH_SIGNED 40 //< Length of the extended init packet that is part of the signed data -#define DFU_INIT_PACKET_EXT_BEGIN - -#define DFU_INIT_PACKET_EXT_LENGTH_MIN 6 //< Minimum length of the extended init packet. Init packet and CRC16 -#define DFU_INIT_PACKET_EXT_LENGTH_MAX 104 //< Identifier (4 bytes) + Image length (4 bytes) + SHA-256 digest (32 bytes) + NIST P-256 using SHA-256 (64 bytes) - -#define DFU_SHA256_DIGEST_LENGTH 32 //< Length of SHA-256 digest -#define DFU_SIGNATURE_R_LENGTH 32 //< Length of the signature part r -#define DFU_SIGNATURE_S_LENGTH 32 //< Length of the signature part s - -static uint8_t m_extended_packet[DFU_INIT_PACKET_EXT_LENGTH_MAX]; //< Data array for storage of the extended data received. The extended data follows the normal init data of type \ref dfu_init_packet_t. Extended data can be used for a CRC, hash, signature, or other data. */ -static uint8_t m_extended_packet_length; //< Length of the extended data received with init packet. */ - - #define DFU_INIT_PACKET_USES_CRC16 (0) - #define DFU_INIT_PACKET_USES_HASH (1) - #define DFU_INIT_PACKET_USES_ECDS (2) - - -/** @snippet [DFU BLE Signing public key curve points] */ -static uint8_t Qx[] = { 0x39, 0xb0, 0x58, 0x3d, 0x27, 0x07, 0x91, 0x38, 0x6a, 0xa3, 0x36, 0x0f, 0xa2, 0xb5, 0x86, 0x7e, 0xae, 0xba, 0xf7, 0xa3, 0xf4, 0x81, 0x5f, 0x78, 0x02, 0xf2, 0xa1, 0x21, 0xd5, 0x21, 0x84, 0x12 }; -static uint8_t Qy[] = { 0x4a, 0x0d, 0xfe, 0xa4, 0x77, 0x50, 0xb1, 0xb5, 0x26, 0xc0, 0x9d, 0xdd, 0xf0, 0x24, 0x90, 0x57, 0x6c, 0x64, 0x3b, 0xd3, 0xdf, 0x92, 0x3b, 0xb3, 0x47, 0x97, 0x83, 0xd4, 0xfc, 0x76, 0xf5, 0x9d }; -/** @snippet [DFU BLE Signing public key curve points] */ - -static nrf_sec_ecc_point_t Q = {.p_x = Qx, - .x_len = sizeof(Qx), - .p_y = Qy, - .y_len = sizeof(Qy)}; - -uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len) -{ - uint32_t i = 0; - static uint32_t err_code; - nrf_sec_data_t init_data; - nrf_sec_ecc_signature_t signature; - - // In order to support encryption then any init packet decryption function / library - // should be called from here or implemented at this location. - - // Length check to ensure valid data are parsed. - if (init_data_len < sizeof(dfu_init_packet_t)) - { - return NRF_ERROR_INVALID_LENGTH; - } - - // Current template uses clear text data so they can be casted for pre-check. - dfu_init_packet_t * p_init_packet = (dfu_init_packet_t *)p_init_data; - - - m_extended_packet_length = ((uint32_t)p_init_data + init_data_len) - - (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len]; - - if (m_extended_packet_length < DFU_INIT_PACKET_EXT_LENGTH_MIN) - { - return NRF_ERROR_INVALID_LENGTH; - } - - if (((uint32_t)p_init_data + init_data_len) < - (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len]) - { - return NRF_ERROR_INVALID_LENGTH; - } - - memcpy(&m_extended_packet, - &p_init_packet->softdevice[p_init_packet->softdevice_len], - m_extended_packet_length); - -/** [DFU init application version] */ - // To support application versioning, this check should be updated. - // This template allows for any application to be installed. However, - // customers can place a revision number at the bottom of the application - // to be verified by the bootloader. This can be done at a location - // relative to the application, for example the application start - // address + 0x0100. -/** [DFU init application version] */ - - // First check to verify the image to be transfered matches the device type. - // If no Device type is present in DFU_DEVICE_INFO then any image will be accepted. - if ((DFU_DEVICE_INFO->device_type != DFU_DEVICE_TYPE_EMPTY) && - (p_init_packet->device_type != DFU_DEVICE_INFO->device_type)) - { - return NRF_ERROR_INVALID_DATA; - } - - // Second check to verify the image to be transfered matches the device revision. - // If no Device revision is present in DFU_DEVICE_INFO then any image will be accepted. - if ((DFU_DEVICE_INFO->device_rev != DFU_DEVICE_REVISION_EMPTY) && - (p_init_packet->device_rev != DFU_DEVICE_INFO->device_rev)) - { - return NRF_ERROR_INVALID_DATA; - } - - // Third check: Check the array of supported SoftDevices by this application. - // If the installed SoftDevice does not match any SoftDevice in the list then an - // error is returned. - while (i < p_init_packet->softdevice_len) - { - if (p_init_packet->softdevice[i] == DFU_SOFTDEVICE_ANY || - p_init_packet->softdevice[i++] == SD_FWID_GET(MBR_SIZE)) - { - // Found a match. Break the loop. - break; - } - // No matching SoftDevice found - Return NRF_ERROR_INVALID_DATA. - return NRF_ERROR_INVALID_DATA; - } - - // Check that we have the correct identifier indicating that ECDS is used - if(*(uint32_t*)&m_extended_packet[DFU_INIT_PACKET_POS_EXT_IDENTIFIER] != DFU_INIT_PACKET_USES_ECDS) - { - return NRF_ERROR_INVALID_DATA; - } - - // init_data consists of the regular init-packet and all the extended packet data excluding the signing key - init_data.length = (init_data_len - m_extended_packet_length) + DFU_INIT_PACKET_EXT_LENGTH_SIGNED; - init_data.p_data = p_init_data; - - signature.p_r = &m_extended_packet[DFU_INIT_PACKET_POS_EXT_INIT_SIGNATURE_R]; - signature.r_len = DFU_SIGNATURE_R_LENGTH; - signature.p_s = &m_extended_packet[DFU_INIT_PACKET_POS_EXT_INIT_SIGNATURE_S]; - signature.s_len = DFU_SIGNATURE_S_LENGTH; - - err_code = nrf_sec_svc_verify(&init_data, &Q ,&signature, NRF_SEC_NIST256_SHA256); - return err_code; -} - -uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len) -{ - uint8_t image_digest[DFU_SHA256_DIGEST_LENGTH]; - uint8_t * received_digest; - - nrf_sec_data_t data = {.p_data = p_image, - .length = image_len}; - - - // Compare image size received with signed init_packet data - if(image_len != *(uint32_t*)&m_extended_packet[DFU_INIT_PACKET_POS_EXT_IMAGE_LENGTH]) - { - return NRF_ERROR_INVALID_DATA; - } - - // Calculate digest from active block. - nrf_sec_svc_hash(&data, image_digest, NRF_SEC_SHA256); - - received_digest = &m_extended_packet[DFU_INIT_PACKET_POS_EXT_IMAGE_HASH256]; - - // Compare the received and calculated digests. - if (memcmp(&image_digest[0], received_digest, DFU_SHA256_DIGEST_LENGTH) != 0) - { - return NRF_ERROR_INVALID_DATA; - } - - return NRF_SUCCESS; -} diff --git a/components/libraries/bootloader_dfu/experimental/nrf_sec.h b/components/libraries/bootloader_dfu/experimental/nrf_sec.h deleted file mode 100644 index 5fc2fcc..0000000 --- a/components/libraries/bootloader_dfu/experimental/nrf_sec.h +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_SEC_H__ -#define NRF_SEC_H__ - -#include "nrf_svc.h" -#include - -#define NRF_SEC_SVC_BASE 0x8 /**< The lowest SVC number reserved for the nRF Security library. */ - -/**@brief The SVC numbers used by the SVC functions in the security library. */ -enum NRF_SEC_SVCS -{ - NRF_SEC_SVC_HASH = NRF_SEC_SVC_BASE, /**< SVC number for generating a digest using a hash function over a dataset. */ - NRF_SEC_SVC_VERIFY, /**< SVC number for veryfying a signature for a given dataset using provided keys and signature. */ - NRF_SEC_SVC_LAST -}; - -/**@brief Enumeration containing list of supported ECC curve and hash functions in the nRF Security library. - */ -typedef enum -{ - NRF_SEC_NIST256_SHA256 = 0x00, /**< Selection of NIST P-256 curve with SHA-256 digest for verification of signature. */ - NRF_SEC_ALGO_LAST /**< Last element in enumeration closing valid algorithm list. */ -}nrf_sec_algo_t; - -/**@brief Enumeration containing list of supported hash functions in the nRF Security library. - */ -typedef enum -{ - NRF_SEC_SHA256 = 0x00, /**< Selection of SHA-256 hash function. */ - NRF_SEC_HASH_FUNC_LAST /**< Last element in enumeration closing valid hash function list. */ -}nrf_sec_hash_func_t; - -/**@brief Structure with length of data and pointer to data for signing or verification. - */ -typedef struct -{ - uint32_t length; /**< Length of data pointed to by @ref p_data. */ - uint8_t * p_data; /**< Pointer to data to be used. */ -} nrf_sec_data_t; - -/**@brief Structure with pointers to X and Y coordinates of a point on the curve. - */ -typedef struct -{ - uint8_t * p_x; /**< Pointer to X coordinate of point. */ - uint32_t x_len; /**< Length of data pointed to by p_x. */ - uint8_t * p_y; /**< Pointer to X coordinate of point. */ - uint32_t y_len; /**< Length of data pointed to by p_x. */ -} nrf_sec_ecc_point_t; - -/**@brief Structure with pointers to r and s parts of the ecc signature. - */ -typedef struct -{ - uint8_t * p_r; /**< Pointer to R part of signature */ - uint32_t r_len; /**< Length of data pointed to by p_r */ - uint8_t * p_s; /**< Pointer to S part of signature */ - uint32_t s_len; /**< Length to data pointed to by p_s */ -} nrf_sec_ecc_signature_t; - -/**@brief SVC Function for verifying a signature over a given dataset. - * - * @param[in] p_data Pointer to the data which must be verified. - * @param[in] p_Q Pointer to the public key, Q. - * @param[in] p_signature Pointer to the signature (r and s). - * @param[in] algorithm Curve and hash algorithm to be used for verifying the signature, for - example NIST P-256 with SHA-256. - * - * @retval NRF_ERROR_INVALID_DATA If the signature does not match the dataset provided. - * @retval NRF_ERROR_NOT_SUPPORTED If the selected algorithm is not supported in this version of - the library. - * @retval NRF_SUCCESS If the signature matches the dataset provided. - */ -SVCALL(NRF_SEC_SVC_VERIFY, uint32_t, nrf_sec_svc_verify (nrf_sec_data_t * p_data, - nrf_sec_ecc_point_t * p_Q, - nrf_sec_ecc_signature_t * p_signature, - nrf_sec_algo_t algorithm)); - -/**@brief SVC Function for generating a signature over a given dataset. - * - * @param[in] p_data Pointer to the data which must be verified. - * @param[out] p_digest Pointer to memory where generated digest shall be stored. Ensure - * sufficient memory is available, that is for a SHA-256 there must - * be at least 256 bits (8 words) available. - * @param[in] hash_func Type of fash function to use when generating the digest - * - * @retval NRF_ERROR_NULL If a null pointer is provided as data or hash. - * @retval NRF_ERROR_NOT_SUPPORTED If the selected hash functions is not supported in this version - * of the library. - * @retval NRF_SUCCESS If generation of a digest was successful. - */ -SVCALL(NRF_SEC_SVC_HASH, uint32_t, nrf_sec_svc_hash(nrf_sec_data_t * p_data, - uint8_t * p_digest, - nrf_sec_hash_func_t hash_func)); - -#endif // NRF_SEC_H__ diff --git a/components/libraries/bootloader_dfu/hci_transport/hci_mem_pool_internal.h b/components/libraries/bootloader_dfu/hci_transport/hci_mem_pool_internal.h deleted file mode 100644 index f5c9638..0000000 --- a/components/libraries/bootloader_dfu/hci_transport/hci_mem_pool_internal.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/** @file - * - * @defgroup memory_pool_internal Memory Pool Internal - * @{ - * @ingroup memory_pool - * - * @brief Memory pool internal definitions - */ - -#ifndef MEM_POOL_INTERNAL_H__ -#define MEM_POOL_INTERNAL_H__ - -#define TX_BUF_SIZE 32u /**< TX buffer size in bytes. */ -#define RX_BUF_SIZE 600u /**< RX buffer size in bytes. */ - -#define RX_BUF_QUEUE_SIZE 2u /**< RX buffer element size. */ - -#endif // MEM_POOL_INTERNAL_H__ - -/** @} */ diff --git a/components/libraries/bootloader_dfu/hci_transport/hci_transport_config.h b/components/libraries/bootloader_dfu/hci_transport/hci_transport_config.h deleted file mode 100644 index 748b1ce..0000000 --- a/components/libraries/bootloader_dfu/hci_transport/hci_transport_config.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup ble_sdk_bootloader_hci_congfig HCI Transport Layer Configuration - * @{ - * @ingroup dfu_bootloader_api - * @brief Definition of HCI Transport Layer configurable parameters - */ - -#ifndef HCI_TRANSPORT_CONFIG_H__ -#define HCI_TRANSPORT_CONFIG_H__ - -#include "boards.h" /**< Default include for boards.h which means that default pin numbers will be used for RX, TX, CTS, and RTS on the UART. Other pin number can be used if desired. */ - -/** This section covers configurable parameters for the HCI Transport SLIP layer. */ -#define HCI_SLIP_UART_RX_PIN_NUMBER RX_PIN_NUMBER /**< Defines the UART RX pin number. The default pin for the board is chosen, but can be overwritten. */ - -#define HCI_SLIP_UART_TX_PIN_NUMBER TX_PIN_NUMBER /**< Defines the UART TX pin number. The default pin for the board is chosen, but can be overwritten. */ - -#define HCI_SLIP_UART_RTS_PIN_NUMBER RTS_PIN_NUMBER /**< Defines the UART RTS pin number. The default pin for the board is chosen, but can be overwritten. */ - -#define HCI_SLIP_UART_CTS_PIN_NUMBER CTS_PIN_NUMBER /**< Defines the UART CTS pin number. The default pin for the board is chosen, but can be overwritten. */ - -#define HCI_SLIP_UART_MODE APP_UART_FLOW_CONTROL_DISABLED /**< Defines the UART mode to be used. Use UART Low Power with Flow Control - Valid values are defined in \ref app_uart_flow_control_t. For further information on the UART Low Power mode, please refer to: \ref app_uart . */ - -#define HCI_SLIP_UART_BAUDRATE UART_BAUDRATE_BAUDRATE_Baud38400 /**< Defines the UART Baud rate. Default is 38400 baud. */ - -/** This section covers configurable parameters for the HCI Transport layer that are used for calculating correct value for the retransmission timer timeout. */ -#define MAX_PACKET_SIZE_IN_BITS 8000u /**< Maximum size of a single application packet in bits. */ -#define USED_BAUD_RATE 38400u /**< The used uart baudrate. */ - -#endif // HCI_TRANSPORT_CONFIG_H__ - -/** @} */ diff --git a/components/libraries/bsp/bsp.c b/components/libraries/bsp/bsp.c new file mode 100644 index 0000000..497ca42 --- /dev/null +++ b/components/libraries/bsp/bsp.c @@ -0,0 +1,610 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "bsp.h" +#include +#include +#include "nordic_common.h" +#include "nrf.h" +#include "nrf_gpio.h" +#include "nrf_error.h" +#include "bsp_config.h" +#include "boards.h" + +#ifndef BSP_SIMPLE +#include "app_timer.h" +#include "app_button.h" +#endif // BSP_SIMPLE + +#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) +static bsp_indication_t m_stable_state = BSP_INDICATE_IDLE; +static bool m_leds_clear = false; +static uint32_t m_app_ticks_per_100ms = 0; +static uint32_t m_indication_type = 0; +APP_TIMER_DEF(m_leds_timer_id); +APP_TIMER_DEF(m_alert_timer_id); +#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + +#if BUTTONS_NUMBER > 0 +#ifndef BSP_SIMPLE +static bsp_event_callback_t m_registered_callback = NULL; +static bsp_button_event_cfg_t m_events_list[BUTTONS_NUMBER] = {{BSP_EVENT_NOTHING, BSP_EVENT_NOTHING}}; +APP_TIMER_DEF(m_button_timer_id); +static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action); +#endif // BSP_SIMPLE + +#ifndef BSP_SIMPLE +static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] = +{ + #ifdef BSP_BUTTON_0 + {BSP_BUTTON_0, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_0 + + #ifdef BSP_BUTTON_1 + {BSP_BUTTON_1, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_1 + + #ifdef BSP_BUTTON_2 + {BSP_BUTTON_2, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_2 + + #ifdef BSP_BUTTON_3 + {BSP_BUTTON_3, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_3 + + #ifdef BSP_BUTTON_4 + {BSP_BUTTON_4, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_4 + + #ifdef BSP_BUTTON_5 + {BSP_BUTTON_5, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_5 + + #ifdef BSP_BUTTON_6 + {BSP_BUTTON_6, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_6 + + #ifdef BSP_BUTTON_7 + {BSP_BUTTON_7, false, BUTTON_PULL, bsp_button_event_handler}, + #endif // BUTTON_7 + +}; +#endif // BSP_SIMPLE +#endif // BUTTONS_NUMBER > 0 + +#if (BUTTONS_NUMBER > 0) +bool bsp_button_is_pressed(uint32_t button) +{ + return bsp_board_button_state_get(button); +} +#endif + +#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) +/**@brief Function for handling button events. + * + * @param[in] pin_no The pin number of the button pressed. + * @param[in] button_action Action button. + */ +static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action) +{ + bsp_event_t event = BSP_EVENT_NOTHING; + uint32_t button = 0; + uint32_t err_code; + static uint8_t current_long_push_pin_no; /**< Pin number of a currently pushed button, that could become a long push if held long enough. */ + static bsp_event_t release_event_at_push[BUTTONS_NUMBER]; /**< Array of what the release event of each button was last time it was pushed, so that no release event is sent if the event was bound after the push of the button. */ + + button = bsp_board_pin_to_button_idx(pin_no); + + if (button < BUTTONS_NUMBER) + { + switch (button_action) + { + case APP_BUTTON_PUSH: + event = m_events_list[button].push_event; + if (m_events_list[button].long_push_event != BSP_EVENT_NOTHING) + { + err_code = app_timer_start(m_button_timer_id, BSP_MS_TO_TICK(BSP_LONG_PUSH_TIMEOUT_MS), (void*)¤t_long_push_pin_no); + if (err_code == NRF_SUCCESS) + { + current_long_push_pin_no = pin_no; + } + } + release_event_at_push[button] = m_events_list[button].release_event; + break; + case APP_BUTTON_RELEASE: + (void)app_timer_stop(m_button_timer_id); + if (release_event_at_push[button] == m_events_list[button].release_event) + { + event = m_events_list[button].release_event; + } + break; + case BSP_BUTTON_ACTION_LONG_PUSH: + event = m_events_list[button].long_push_event; + } + } + + if ((event != BSP_EVENT_NOTHING) && (m_registered_callback != NULL)) + { + m_registered_callback(event); + } +} + +/**@brief Handle events from button timer. + * + * @param[in] p_context parameter registered in timer start function. + */ +static void button_timer_handler(void * p_context) +{ + bsp_button_event_handler(*(uint8_t *)p_context, BSP_BUTTON_ACTION_LONG_PUSH); +} + + +#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) + +#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) +/**@brief Configure leds to indicate required state. + * @param[in] indicate State to be indicated. + */ +static uint32_t bsp_led_indication(bsp_indication_t indicate) +{ + uint32_t err_code = NRF_SUCCESS; + uint32_t next_delay = 0; + + if(m_leds_clear) + { + m_leds_clear = false; + bsp_board_leds_off(); + } + + switch (indicate) + { + case BSP_INDICATE_IDLE: + bsp_board_leds_off(); + m_stable_state = indicate; + break; + + case BSP_INDICATE_SCANNING: + case BSP_INDICATE_ADVERTISING: + // in advertising blink LED_0 + if (bsp_board_led_state_get(BSP_LED_INDICATE_INDICATE_ADVERTISING)) + { + bsp_board_led_off(BSP_LED_INDICATE_INDICATE_ADVERTISING); + next_delay = indicate == + BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_OFF_INTERVAL : + ADVERTISING_SLOW_LED_OFF_INTERVAL; + } + else + { + bsp_board_led_on(BSP_LED_INDICATE_INDICATE_ADVERTISING); + next_delay = indicate == + BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_ON_INTERVAL : + ADVERTISING_SLOW_LED_ON_INTERVAL; + } + + m_stable_state = indicate; + err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(next_delay), NULL); + break; + + case BSP_INDICATE_ADVERTISING_WHITELIST: + // in advertising quickly blink LED_0 + if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_WHITELIST)) + { + bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_WHITELIST); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_WHITELIST ? + ADVERTISING_WHITELIST_LED_OFF_INTERVAL : + ADVERTISING_SLOW_LED_OFF_INTERVAL; + } + else + { + bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_WHITELIST); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_WHITELIST ? + ADVERTISING_WHITELIST_LED_ON_INTERVAL : + ADVERTISING_SLOW_LED_ON_INTERVAL; + } + m_stable_state = indicate; + err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(next_delay), NULL); + break; + + case BSP_INDICATE_ADVERTISING_SLOW: + // in advertising slowly blink LED_0 + if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_SLOW)) + { + bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_SLOW); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_OFF_INTERVAL : + ADVERTISING_SLOW_LED_OFF_INTERVAL; + } + else + { + bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_SLOW); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_ON_INTERVAL : + ADVERTISING_SLOW_LED_ON_INTERVAL; + } + m_stable_state = indicate; + err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(next_delay), NULL); + break; + + case BSP_INDICATE_ADVERTISING_DIRECTED: + // in advertising very quickly blink LED_0 + if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_DIRECTED)) + { + bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_DIRECTED); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_DIRECTED ? + ADVERTISING_DIRECTED_LED_OFF_INTERVAL : + ADVERTISING_SLOW_LED_OFF_INTERVAL; + } + else + { + bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_DIRECTED); + next_delay = indicate == + BSP_INDICATE_ADVERTISING_DIRECTED ? + ADVERTISING_DIRECTED_LED_ON_INTERVAL : + ADVERTISING_SLOW_LED_ON_INTERVAL; + } + m_stable_state = indicate; + err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(next_delay), NULL); + break; + + case BSP_INDICATE_BONDING: + // in bonding fast blink LED_0 + bsp_board_led_invert(BSP_LED_INDICATE_BONDING); + + m_stable_state = indicate; + err_code = + app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(BONDING_INTERVAL), NULL); + break; + + case BSP_INDICATE_CONNECTED: + bsp_board_led_on(BSP_LED_INDICATE_CONNECTED); + m_stable_state = indicate; + break; + + case BSP_INDICATE_SENT_OK: + // when sending shortly invert LED_1 + m_leds_clear = true; + bsp_board_led_invert(BSP_LED_INDICATE_SENT_OK); + err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(SENT_OK_INTERVAL), NULL); + break; + + case BSP_INDICATE_SEND_ERROR: + // on receving error invert LED_1 for long time + m_leds_clear = true; + bsp_board_led_invert(BSP_LED_INDICATE_SEND_ERROR); + err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(SEND_ERROR_INTERVAL), NULL); + break; + + case BSP_INDICATE_RCV_OK: + // when receving shortly invert LED_1 + m_leds_clear = true; + bsp_board_led_invert(BSP_LED_INDICATE_RCV_OK); + err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(RCV_OK_INTERVAL), NULL); + break; + + case BSP_INDICATE_RCV_ERROR: + // on receving error invert LED_1 for long time + m_leds_clear = true; + bsp_board_led_invert(BSP_LED_INDICATE_RCV_ERROR); + err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(RCV_ERROR_INTERVAL), NULL); + break; + + case BSP_INDICATE_FATAL_ERROR: + // on fatal error turn on all leds + bsp_board_leds_on(); + m_stable_state = indicate; + break; + + case BSP_INDICATE_ALERT_0: + case BSP_INDICATE_ALERT_1: + case BSP_INDICATE_ALERT_2: + case BSP_INDICATE_ALERT_3: + case BSP_INDICATE_ALERT_OFF: + err_code = app_timer_stop(m_alert_timer_id); + next_delay = (uint32_t)BSP_INDICATE_ALERT_OFF - (uint32_t)indicate; + + // a little trick to find out that if it did not fall through ALERT_OFF + if (next_delay && (err_code == NRF_SUCCESS)) + { + if (next_delay > 1) + { + err_code = app_timer_start(m_alert_timer_id, + BSP_MS_TO_TICK((next_delay * ALERT_INTERVAL)), + NULL); + } + bsp_board_led_on(BSP_LED_ALERT); + } + else + { + bsp_board_led_off(BSP_LED_ALERT); + } + break; + + case BSP_INDICATE_USER_STATE_OFF: + bsp_board_leds_off(); + m_stable_state = indicate; + break; + + case BSP_INDICATE_USER_STATE_0: + bsp_board_leds_off(); + bsp_board_led_on(BSP_LED_INDICATE_USER_LED1); + m_stable_state = indicate; + break; + + case BSP_INDICATE_USER_STATE_1: + bsp_board_leds_off(); + bsp_board_led_on(BSP_LED_INDICATE_USER_LED2); + m_stable_state = indicate; + break; + + case BSP_INDICATE_USER_STATE_2: + bsp_board_leds_off(); + bsp_board_led_on(BSP_LED_INDICATE_USER_LED1); + bsp_board_led_on(BSP_LED_INDICATE_USER_LED2); + m_stable_state = indicate; + break; + + case BSP_INDICATE_USER_STATE_3: + + case BSP_INDICATE_USER_STATE_ON: + bsp_board_leds_on(); + m_stable_state = indicate; + break; + + default: + break; + } + + return err_code; +} + + +/**@brief Handle events from leds timer. + * + * @note Timer handler does not support returning an error code. + * Errors from bsp_led_indication() are not propagated. + * + * @param[in] p_context parameter registered in timer start function. + */ +static void leds_timer_handler(void * p_context) +{ + UNUSED_PARAMETER(p_context); + + if (m_indication_type & BSP_INIT_LED) + { + UNUSED_VARIABLE(bsp_led_indication(m_stable_state)); + } +} + + +/**@brief Handle events from alert timer. + * + * @param[in] p_context parameter registered in timer start function. + */ +static void alert_timer_handler(void * p_context) +{ + UNUSED_PARAMETER(p_context); + bsp_board_led_invert(BSP_LED_ALERT); +} +#endif // #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + + +/**@brief Configure indicators to required state. + */ +uint32_t bsp_indication_set(bsp_indication_t indicate) +{ + uint32_t err_code = NRF_SUCCESS; + +#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + + if (m_indication_type & BSP_INIT_LED) + { + err_code = bsp_led_indication(indicate); + } + +#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + return err_code; +} + + +uint32_t bsp_init(uint32_t type, uint32_t ticks_per_100ms, bsp_event_callback_t callback) +{ + uint32_t err_code = NRF_SUCCESS; + +#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + m_app_ticks_per_100ms = ticks_per_100ms; + m_indication_type = type; +#else + UNUSED_VARIABLE(ticks_per_100ms); +#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + +#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) + m_registered_callback = callback; + + // BSP will support buttons and generate events + if (type & BSP_INIT_BUTTONS) + { + uint32_t num; + + for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++) + { + err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT); + } + + if (err_code == NRF_SUCCESS) + { + err_code = app_button_init((app_button_cfg_t *)app_buttons, + BUTTONS_NUMBER, + ticks_per_100ms / 2); + } + + if (err_code == NRF_SUCCESS) + { + err_code = app_button_enable(); + } + + if (err_code == NRF_SUCCESS) + { + err_code = app_timer_create(&m_button_timer_id, + APP_TIMER_MODE_SINGLE_SHOT, + button_timer_handler); + } + } +#elif (BUTTONS_NUMBER > 0) && (defined BSP_SIMPLE) + + if (type & BSP_INIT_BUTTONS) + { + bsp_board_buttons_init(); + } +#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) + +#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + + if (type & BSP_INIT_LED) + { + bsp_board_leds_init(); + } + + // timers module must be already initialized! + if (err_code == NRF_SUCCESS) + { + err_code = + app_timer_create(&m_leds_timer_id, APP_TIMER_MODE_SINGLE_SHOT, leds_timer_handler); + } + + if (err_code == NRF_SUCCESS) + { + err_code = + app_timer_create(&m_alert_timer_id, APP_TIMER_MODE_REPEATED, alert_timer_handler); + } +#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) + + return err_code; +} + + +#ifndef BSP_SIMPLE +/**@brief Assign specific event to button. + */ +uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event) +{ + uint32_t err_code = NRF_SUCCESS; + +#if BUTTONS_NUMBER > 0 + if (button < BUTTONS_NUMBER) + { + if (event == BSP_EVENT_DEFAULT) + { + // Setting default action: BSP_EVENT_KEY_x for PUSH actions, BSP_EVENT_NOTHING for RELEASE and LONG_PUSH actions. + event = (action == BSP_BUTTON_ACTION_PUSH) ? (bsp_event_t)(BSP_EVENT_KEY_0 + button) : BSP_EVENT_NOTHING; + } + switch (action) + { + case BSP_BUTTON_ACTION_PUSH: + m_events_list[button].push_event = event; + break; + case BSP_BUTTON_ACTION_LONG_PUSH: + m_events_list[button].long_push_event = event; + break; + case BSP_BUTTON_ACTION_RELEASE: + m_events_list[button].release_event = event; + break; + default: + err_code = NRF_ERROR_INVALID_PARAM; + break; + } + } + else + { + err_code = NRF_ERROR_INVALID_PARAM; + } +#else + err_code = NRF_ERROR_INVALID_PARAM; +#endif // BUTTONS_NUMBER > 0 + + return err_code; +} + +#endif // BSP_SIMPLE + + +uint32_t bsp_buttons_enable() +{ +#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) + return app_button_enable(); +#else + return NRF_ERROR_NOT_SUPPORTED; +#endif +} + +uint32_t bsp_buttons_disable() +{ +#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) + return app_button_disable(); +#else + return NRF_ERROR_NOT_SUPPORTED; +#endif +} + +uint32_t bsp_wakeup_button_enable(uint32_t button_idx) +{ +#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) + nrf_gpio_cfg_sense_set(bsp_board_button_idx_to_pin(button_idx), + BUTTONS_ACTIVE_STATE ? NRF_GPIO_PIN_SENSE_HIGH :NRF_GPIO_PIN_SENSE_LOW); + return NRF_SUCCESS; +#else + UNUSED_PARAMETER(button_idx); + return NRF_ERROR_NOT_SUPPORTED; +#endif +} + +uint32_t bsp_wakeup_button_disable(uint32_t button_idx) +{ +#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) + nrf_gpio_cfg_sense_set(bsp_board_button_idx_to_pin(button_idx), + NRF_GPIO_PIN_NOSENSE); + return NRF_SUCCESS; +#else + UNUSED_PARAMETER(button_idx); + return NRF_ERROR_NOT_SUPPORTED; +#endif +} diff --git a/components/libraries/bsp/bsp.h b/components/libraries/bsp/bsp.h new file mode 100644 index 0000000..c356e27 --- /dev/null +++ b/components/libraries/bsp/bsp.h @@ -0,0 +1,316 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup bsp Board Support Package + * @{ + * @ingroup app_common + * + * @brief BSP module. + * @details This module provides a layer of abstraction from the board. + * It allows the user to indicate certain states on LEDs in a simple way. + * Module functionality can be modified by additional defines: + * - BSP_SIMPLE reduces functionality of this module to enable + * and read state of the buttons + * - BSP_UART_SUPPORT enables support for UART + */ + +#ifndef BSP_H__ +#define BSP_H__ + +#include +#include +#include "boards.h" + +#define BSP_INIT_NONE 0 /**< This define specifies the type of initialization without support for LEDs and buttons (@ref bsp_init).*/ +#define BSP_INIT_LED (1 << 0) /**< This bit enables LEDs during initialization (@ref bsp_init).*/ +#define BSP_INIT_BUTTONS (1 << 1) /**< This bit enables buttons during initialization (@ref bsp_init).*/ + +#if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE) +#include "app_button.h" + +#define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */ +#define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */ +#define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */ + +#endif + +/* BSP_UART_SUPPORT + * This define enables UART support module. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t bsp_button_action_t; /**< The different actions that can be performed on a button. */ + +#define BSP_INDICATIONS_LIST { \ + "BSP_INDICATE_IDLE", \ + "BSP_INDICATE_SCANNING", \ + "BSP_INDICATE_ADVERTISING", \ + "BSP_INDICATE_ADVERTISING_WHITELIST", \ + "BSP_INDICATE_ADVERTISING_SLOW", \ + "BSP_INDICATE_ADVERTISING_DIRECTED", \ + "BSP_INDICATE_BONDING", \ + "BSP_INDICATE_CONNECTED", \ + "BSP_INDICATE_SENT_OK", \ + "BSP_INDICATE_SEND_ERROR", \ + "BSP_INDICATE_RCV_OK", \ + "BSP_INDICATE_RCV_ERROR", \ + "BSP_INDICATE_FATAL_ERROR", \ + "BSP_INDICATE_ALERT_0", \ + "BSP_INDICATE_ALERT_1", \ + "BSP_INDICATE_ALERT_2", \ + "BSP_INDICATE_ALERT_3", \ + "BSP_INDICATE_ALERT_OFF", \ + "BSP_INDICATE_USER_STATE_OFF", \ + "BSP_INDICATE_USER_STATE_0", \ + "BSP_INDICATE_USER_STATE_1", \ + "BSP_INDICATE_USER_STATE_2", \ + "BSP_INDICATE_USER_STATE_3", \ + "BSP_INDICATE_USER_STATE_ON" \ +} /**< See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle.*/ + + +/**@brief BSP indication states. + * + * @details See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle. + */ +typedef enum +{ + BSP_INDICATE_FIRST = 0, + BSP_INDICATE_IDLE = BSP_INDICATE_FIRST, /**< See \ref BSP_INDICATE_IDLE.*/ + BSP_INDICATE_SCANNING, /**< See \ref BSP_INDICATE_SCANNING.*/ + BSP_INDICATE_ADVERTISING, /**< See \ref BSP_INDICATE_ADVERTISING.*/ + BSP_INDICATE_ADVERTISING_WHITELIST, /**< See \ref BSP_INDICATE_ADVERTISING_WHITELIST.*/ + BSP_INDICATE_ADVERTISING_SLOW, /**< See \ref BSP_INDICATE_ADVERTISING_SLOW.*/ + BSP_INDICATE_ADVERTISING_DIRECTED, /**< See \ref BSP_INDICATE_ADVERTISING_DIRECTED.*/ + BSP_INDICATE_BONDING, /**< See \ref BSP_INDICATE_BONDING.*/ + BSP_INDICATE_CONNECTED, /**< See \ref BSP_INDICATE_CONNECTED.*/ + BSP_INDICATE_SENT_OK, /**< See \ref BSP_INDICATE_SENT_OK.*/ + BSP_INDICATE_SEND_ERROR, /**< See \ref BSP_INDICATE_SEND_ERROR.*/ + BSP_INDICATE_RCV_OK, /**< See \ref BSP_INDICATE_RCV_OK.*/ + BSP_INDICATE_RCV_ERROR, /**< See \ref BSP_INDICATE_RCV_ERROR.*/ + BSP_INDICATE_FATAL_ERROR, /**< See \ref BSP_INDICATE_FATAL_ERROR.*/ + BSP_INDICATE_ALERT_0, /**< See \ref BSP_INDICATE_ALERT_0.*/ + BSP_INDICATE_ALERT_1, /**< See \ref BSP_INDICATE_ALERT_1.*/ + BSP_INDICATE_ALERT_2, /**< See \ref BSP_INDICATE_ALERT_2.*/ + BSP_INDICATE_ALERT_3, /**< See \ref BSP_INDICATE_ALERT_3.*/ + BSP_INDICATE_ALERT_OFF, /**< See \ref BSP_INDICATE_ALERT_OFF.*/ + BSP_INDICATE_USER_STATE_OFF, /**< See \ref BSP_INDICATE_USER_STATE_OFF.*/ + BSP_INDICATE_USER_STATE_0, /**< See \ref BSP_INDICATE_USER_STATE_0.*/ + BSP_INDICATE_USER_STATE_1, /**< See \ref BSP_INDICATE_USER_STATE_1.*/ + BSP_INDICATE_USER_STATE_2, /**< See \ref BSP_INDICATE_USER_STATE_2.*/ + BSP_INDICATE_USER_STATE_3, /**< See \ref BSP_INDICATE_USER_STATE_3.*/ + BSP_INDICATE_USER_STATE_ON, /**< See \ref BSP_INDICATE_USER_STATE_ON.*/ + BSP_INDICATE_LAST = BSP_INDICATE_USER_STATE_ON +} bsp_indication_t; + +/**@brief BSP events. + * + * @note Events from BSP_EVENT_KEY_0 to BSP_EVENT_KEY_LAST are by default assigned to buttons. + */ +typedef enum +{ + BSP_EVENT_NOTHING = 0, /**< Assign this event to an action to prevent the action from generating an event (disable the action). */ + BSP_EVENT_DEFAULT, /**< Assign this event to an action to assign the default event to the action. */ + BSP_EVENT_CLEAR_BONDING_DATA, /**< Persistent bonding data should be erased. */ + BSP_EVENT_CLEAR_ALERT, /**< An alert should be cleared. */ + BSP_EVENT_DISCONNECT, /**< A link should be disconnected. */ + BSP_EVENT_ADVERTISING_START, /**< The device should start advertising. */ + BSP_EVENT_ADVERTISING_STOP, /**< The device should stop advertising. */ + BSP_EVENT_WHITELIST_OFF, /**< The device should remove its advertising whitelist. */ + BSP_EVENT_BOND, /**< The device should bond to the currently connected peer. */ + BSP_EVENT_RESET, /**< The device should reset. */ + BSP_EVENT_SLEEP, /**< The device should enter sleep mode. */ + BSP_EVENT_WAKEUP, /**< The device should wake up from sleep mode. */ + BSP_EVENT_SYSOFF, /**< The device should enter system off mode (without wakeup). */ + BSP_EVENT_DFU, /**< The device should enter DFU mode. */ + BSP_EVENT_KEY_0, /**< Default event of the push action of BSP_BUTTON_0 (only if this button is present). */ + BSP_EVENT_KEY_1, /**< Default event of the push action of BSP_BUTTON_1 (only if this button is present). */ + BSP_EVENT_KEY_2, /**< Default event of the push action of BSP_BUTTON_2 (only if this button is present). */ + BSP_EVENT_KEY_3, /**< Default event of the push action of BSP_BUTTON_3 (only if this button is present). */ + BSP_EVENT_KEY_4, /**< Default event of the push action of BSP_BUTTON_4 (only if this button is present). */ + BSP_EVENT_KEY_5, /**< Default event of the push action of BSP_BUTTON_5 (only if this button is present). */ + BSP_EVENT_KEY_6, /**< Default event of the push action of BSP_BUTTON_6 (only if this button is present). */ + BSP_EVENT_KEY_7, /**< Default event of the push action of BSP_BUTTON_7 (only if this button is present). */ + BSP_EVENT_KEY_LAST = BSP_EVENT_KEY_7, +} bsp_event_t; + + +typedef struct +{ + bsp_event_t push_event; /**< The event to fire on regular button press. */ + bsp_event_t long_push_event; /**< The event to fire on long button press. */ + bsp_event_t release_event; /**< The event to fire on button release. */ +} bsp_button_event_cfg_t; + +/**@brief BSP module event callback function type. + * + * @details Upon an event in the BSP module, this callback function will be called to notify + * the application about the event. + * + * @param[in] bsp_event_t BSP event type. + */ +typedef void (* bsp_event_callback_t)(bsp_event_t); + + +/**@brief Function for initializing BSP. + * + * @details The function initializes the board support package to allow state indication and + * button reaction. Default events are assigned to buttons. + * @note Before calling this function, you must initiate the following required modules: + * - @ref app_timer for LED support + * - @ref app_gpiote for button support + * - @ref app_uart for UART support + * + * @param[in] type Type of peripherals used. + * @param[in] ticks_per_100ms Number of RTC ticks for 100 ms. + * @param[in] callback Function to be called when button press/event is detected. + * + * @retval NRF_SUCCESS If the BSP module was successfully initialized. + * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized. + * @retval NRF_ERROR_NO_MEM If the maximum number of timers has already been reached. + * @retval NRF_ERROR_INVALID_PARAM If GPIOTE has too many users. + * @retval NRF_ERROR_INVALID_STATE If button or GPIOTE has not been initialized. + */ +uint32_t bsp_init(uint32_t type, uint32_t ticks_per_100ms, bsp_event_callback_t callback); + + +/**@brief Function for checking button states. + * + * @details This function checks if the button is pressed. If the button ID is out of range, + * the function returns false. + * + * @param[in] button Button ID to check. + * + * @retval true If the button is pressed. + * @retval false If the button is not pressed. + */ +bool bsp_button_is_pressed(uint32_t button); + + +/**@brief Function for assigning a specific event to a button. + * + * @details This function allows redefinition of standard events assigned to buttons. + * To unassign events, provide the event @ref BSP_EVENT_NOTHING. + * + * @param[in] button Button ID to be redefined. + * @param[in] action Button action to assign event to. + * @param[in] event Event to be assigned to button. + * + * @retval NRF_SUCCESS If the event was successfully assigned to button. + * @retval NRF_ERROR_INVALID_PARAM If the button ID or button action was invalid. + */ +uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event); + + +/**@brief Function for configuring indicators to required state. + * + * @details This function indicates the required state by means of LEDs (if enabled). + * + * @note Alerts are indicated independently. + * + * @param[in] indicate State to be indicated. + * + * @retval NRF_SUCCESS If the state was successfully indicated. + * @retval NRF_ERROR_NO_MEM If the internal timer operations queue was full. + * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized, + * or internal timer has not been created. + */ +uint32_t bsp_indication_set(bsp_indication_t indicate); + + +/**@brief Function for enabling all buttons. + * + * @details After calling this function, all buttons will generate events when pressed, and + * all buttons will be able to wake the system up from sleep mode. + * + * @retval NRF_SUCCESS If the buttons were successfully enabled. + * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. + * @return A propagated error. + */ +uint32_t bsp_buttons_enable(void); + + +/**@brief Function for disabling all buttons. + * + * @details After calling this function, no buttons will generate events when pressed, and + * no buttons will be able to wake the system up from sleep mode. + * + * @retval NRF_SUCCESS If the buttons were successfully disabled. + * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. + * @return A propagated error. + */ +uint32_t bsp_buttons_disable(void); + + +/**@brief Function for enabling wakeup from SYSTEM OFF for given button. + * + * @details After calling this function, button can be used to wake up the chip. + * This function should only be called immediately before going into sleep. + * + * @param[in] button_idx Index of the button. + * + * @retval NRF_SUCCESS If the button was successfully enabled. + * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. + */ +uint32_t bsp_wakeup_button_enable(uint32_t button_idx); + + +/**@brief Function for disabling wakeup for the given button. + * + * @param[in] button_idx index of the button. + * + * @retval NRF_SUCCESS If the button was successfully disabled. + * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. + */ +uint32_t bsp_wakeup_button_disable(uint32_t button_idx); + + +#ifdef __cplusplus +} +#endif + +#endif // BSP_H__ + +/** @} */ diff --git a/components/libraries/bsp/bsp_btn_ant.c b/components/libraries/bsp/bsp_btn_ant.c new file mode 100644 index 0000000..d92c515 --- /dev/null +++ b/components/libraries/bsp/bsp_btn_ant.c @@ -0,0 +1,172 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "bsp_btn_ant.h" +#include +#include "bsp.h" +#include "ant_stack_handler_types.h" +#include "ant_parameters.h" + +#define BTN_ID_WAKEUP 3 /**< ID of button used to wake up the application. */ +#define BTN_ID_SLEEP 3 /**< ID of button used to put the application into sleep mode. */ + +#define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */ + + + /**@brief This macro will return from the current function if err_code + * is not NRF_SUCCESS or NRF_ERROR_INVALID_PARAM. + */ +#define RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code) \ +do \ +{ \ + if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_INVALID_PARAM)) \ + { \ + return err_code; \ + } \ +} \ +while (0) + + +/**@brief This macro will return from the current function if err_code + * is not NRF_SUCCESS or NRF_ERROR_NOT_SUPPORTED. + */ +#define RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code) \ +do \ +{ \ + if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_NOT_SUPPORTED)) \ + { \ + return err_code; \ + } \ +} \ +while (0) + + +static bool m_connected = false; /**< Notify if channel is connected. */ + + + /**@brief Function for configuring the buttons for connection. + * + * @retval NRF_SUCCESS Configured successfully. + * @return A propagated error code. + */ +static uint32_t connection_buttons_configure(void) +{ + uint32_t err_code; + + err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP, + BTN_ACTION_SLEEP, + BSP_EVENT_DEFAULT); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + return NRF_SUCCESS; +} + + +/**@brief Function for configuring the buttons for searching. + * + * @retval NRF_SUCCESS Configured successfully. + * @return A propagated error code. + */ +static uint32_t searching_buttons_configure(void) +{ + uint32_t err_code; + + err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP, + BTN_ACTION_SLEEP, + BSP_EVENT_SLEEP); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + return NRF_SUCCESS; +} + + +uint32_t bsp_btn_ant_sleep_mode_prepare(void) +{ + uint32_t err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP); + RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code); + + return NRF_SUCCESS; +} + + +void bsp_btn_ant_on_ant_evt(ant_evt_t * p_ant_evt) +{ + uint32_t err_code; + + switch (p_ant_evt->event) + { + case EVENT_RX: + if (!m_connected) + { + err_code = connection_buttons_configure(); + APP_ERROR_CHECK(err_code); + } + + m_connected = true; + break; + + case EVENT_RX_FAIL_GO_TO_SEARCH: + m_connected = false; + + err_code = searching_buttons_configure(); + APP_ERROR_CHECK(err_code); + break; + + default: + break; + } +} + + +uint32_t bsp_btn_ant_init(void) +{ + uint32_t err_code = NRF_SUCCESS; + + if (!m_connected) + { + err_code = searching_buttons_configure(); + } + else + { + err_code = connection_buttons_configure(); + } + + return err_code; +} diff --git a/components/libraries/bsp/bsp_btn_ant.h b/components/libraries/bsp/bsp_btn_ant.h new file mode 100644 index 0000000..cc2d447 --- /dev/null +++ b/components/libraries/bsp/bsp_btn_ant.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup bsp_btn_ant BSP: ANT Button Module + * @{ + * @ingroup bsp + * + * @brief Module for controlling ANT behavior through button actions. + * + * @details The application must propagate ANT events to the ANT Button Module. + * Based on these events, the ANT Button Module configures the Board Support Package + * to generate BSP events for certain button actions. These BSP events should then be + * handled by the application's BSP event handler. + * + */ + +#ifndef BSP_BTN_ANT_H__ +#define BSP_BTN_ANT_H__ + +#include +#include "ant_stack_handler_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /**@brief Function for initializing the ANT Button Module. + * + * Before calling this function, the BSP module must be initialized with buttons. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error code is + * returned. + */ +uint32_t bsp_btn_ant_init(void); + +/**@brief Function for setting up wakeup buttons before going into sleep mode. + * + * @retval NRF_SUCCESS If the buttons were prepared successfully. Otherwise, a propagated error + * code is returned. + */ +uint32_t bsp_btn_ant_sleep_mode_prepare(void); + +/**@brief Function for handling the application's ANT stack events. + * + * @details This function handles all events from the ANT stack that are of interest to this module. + * + * @param[in] p_ant_evt ANT stack event. + */ +void bsp_btn_ant_on_ant_evt(ant_evt_t * p_ant_evt); + + +#ifdef __cplusplus +} +#endif + +#endif /* BSP_BTN_ANT_H__ */ + +/** @} */ diff --git a/components/libraries/bsp/bsp_btn_ble.c b/components/libraries/bsp/bsp_btn_ble.c new file mode 100644 index 0000000..a1ab55e --- /dev/null +++ b/components/libraries/bsp/bsp_btn_ble.c @@ -0,0 +1,265 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + + +#include "bsp_btn_ble.h" +#include +#include +#include +#include "ble.h" +#include "bsp.h" + + +#define BTN_ID_WAKEUP 0 /**< ID of button used to wake up the application. */ +#define BTN_ID_SLEEP 0 /**< ID of button used to put the application into sleep mode. */ +#define BTN_ID_DISCONNECT 0 /**< ID of button used to gracefully terminate a connection on long press. */ +#define BTN_ID_WAKEUP_BOND_DELETE 1 /**< ID of button used to wake up the application and delete all bonding information. */ +#define BTN_ID_WHITELIST_OFF 1 /**< ID of button used to turn off usage of the whitelist. */ + +#define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */ +#define BTN_ACTION_DISCONNECT BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to gracefully terminate a connection on long press. */ +#define BTN_ACTION_WHITELIST_OFF BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to turn off usage of the whitelist. */ + + + +/**@brief This macro will return from the current function if err_code + * is not NRF_SUCCESS. + */ +#define RETURN_ON_ERROR(err_code) \ +do \ +{ \ + if ((err_code) != NRF_SUCCESS) \ + { \ + return err_code; \ + } \ +} \ +while (0) + + +/**@brief This macro will return from the current function if err_code + * is not NRF_SUCCESS or NRF_ERROR_INVALID_PARAM. + */ +#define RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code) \ +do \ +{ \ + if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_INVALID_PARAM)) \ + { \ + return err_code; \ + } \ +} \ +while (0) + + +/**@brief This macro will return from the current function if err_code + * is not NRF_SUCCESS or NRF_ERROR_NOT_SUPPORTED. + */ +#define RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code) \ +do \ +{ \ + if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_NOT_SUPPORTED)) \ + { \ + return err_code; \ + } \ +} \ +while (0) + + +/**@brief This macro will call the registered error handler if err_code + * is not NRF_SUCCESS and the error handler is not NULL. + */ +#define CALL_HANDLER_ON_ERROR(err_code) \ +do \ +{ \ + if (((err_code) != NRF_SUCCESS) && (m_error_handler != NULL)) \ + { \ + m_error_handler(err_code); \ + } \ +} \ +while (0) + + +static bsp_btn_ble_error_handler_t m_error_handler = NULL; /**< Error handler registered by the user. */ +static uint32_t m_num_connections = 0; /**< Number of connections the device is currently in. */ + + +/**@brief Function for configuring the buttons for connection. + * + * @retval NRF_SUCCESS Configured successfully. + * @return A propagated error code. + */ +static uint32_t connection_buttons_configure() +{ + uint32_t err_code; + + err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP, + BTN_ACTION_SLEEP, + BSP_EVENT_DEFAULT); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF, + BTN_ACTION_WHITELIST_OFF, + BSP_EVENT_WHITELIST_OFF); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT, + BTN_ACTION_DISCONNECT, + BSP_EVENT_DISCONNECT); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + return NRF_SUCCESS; +} + + +/**@brief Function for configuring the buttons for advertisement. + * + * @retval NRF_SUCCESS Configured successfully. + * @return A propagated error code. + */ +static uint32_t advertising_buttons_configure() +{ + uint32_t err_code; + + err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT, + BTN_ACTION_DISCONNECT, + BSP_EVENT_DEFAULT); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF, + BTN_ACTION_WHITELIST_OFF, + BSP_EVENT_WHITELIST_OFF); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP, + BTN_ACTION_SLEEP, + BSP_EVENT_SLEEP); + RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); + + return NRF_SUCCESS; +} + + +/**@brief Function for extracting the BSP event valid at startup. + * + * @details When a button was used to wake up the device, the button press will not generate an + * interrupt. This function reads which button was pressed at startup, and returns the + * appropriate BSP event. + * + * @param[out] p_startup_event Where to put the extracted BSP event. + */ +static void startup_event_extract(bsp_event_t * p_startup_event) +{ + // React to button states + if (bsp_button_is_pressed(BTN_ID_WAKEUP_BOND_DELETE)) + { + *p_startup_event = BSP_EVENT_CLEAR_BONDING_DATA; + } + else if (bsp_button_is_pressed(BTN_ID_WAKEUP)) + { + *p_startup_event = BSP_EVENT_WAKEUP; + } + else + { + *p_startup_event = BSP_EVENT_NOTHING; + } +} + + +uint32_t bsp_btn_ble_sleep_mode_prepare(void) +{ + uint32_t err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP); + RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code); + + err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP_BOND_DELETE); + RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code); + + return NRF_SUCCESS; +} + + +void bsp_btn_ble_on_ble_evt(ble_evt_t * p_ble_evt) +{ + uint32_t err_code; + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + if (m_num_connections == 0) + { + err_code = connection_buttons_configure(); + CALL_HANDLER_ON_ERROR(err_code); + } + + m_num_connections++; + break; + + case BLE_GAP_EVT_DISCONNECTED: + m_num_connections--; + + if (m_num_connections == 0) + { + err_code = advertising_buttons_configure(); + CALL_HANDLER_ON_ERROR(err_code); + } + break; + + default: + break; + } +} + + +uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt) +{ + uint32_t err_code = NRF_SUCCESS; + + m_error_handler = error_handler; + + if (p_startup_bsp_evt != NULL) + { + startup_event_extract(p_startup_bsp_evt); + } + + if (m_num_connections == 0) + { + err_code = advertising_buttons_configure(); + } + + return err_code; +} diff --git a/components/libraries/bsp/bsp_btn_ble.h b/components/libraries/bsp/bsp_btn_ble.h new file mode 100644 index 0000000..531c148 --- /dev/null +++ b/components/libraries/bsp/bsp_btn_ble.h @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup bsp_btn_ble BSP: BLE Button Module + * @{ + * @ingroup bsp + * + * @brief Module for controlling BLE behavior through button actions. + * + * @details The application must propagate BLE events to the BLE Button Module. + * Based on these events, the BLE Button Module configures the Board Support Package + * to generate BSP events for certain button actions. These BSP events should then be + * handled by the application's BSP event handler. + * + */ + +#ifndef BSP_BTN_BLE_H__ +#define BSP_BTN_BLE_H__ + +#include +#include "ble.h" +#include "bsp.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief BLE Button Module error handler type. */ +typedef void (*bsp_btn_ble_error_handler_t) (uint32_t nrf_error); + +/**@brief Function for initializing the BLE Button Module. + * + * Before calling this function, the BSP module must be initialized with buttons. + * + * @param[out] error_handler Error handler to call in case of internal errors in BLE Button + * Module. + * @param[out] p_startup_bsp_evt If not a NULL pointer, the value is filled with an event + * (or BSP_EVENT_NOTHING) derived from the buttons pressed on + * startup. For example, if the bond delete wakeup button was pressed + * to wake up the device, *p_startup_bsp_evt is set to + * @ref BSP_EVENT_CLEAR_BONDING_DATA. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error code is + * returned. + */ +uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt); + +/**@brief Function for setting up wakeup buttons before going into sleep mode. + * + * @retval NRF_SUCCESS If the buttons were prepared successfully. Otherwise, a propagated error + * code is returned. + */ +uint32_t bsp_btn_ble_sleep_mode_prepare(void); + +/**@brief Function for handling the application's BLE stack events. + * + * @details This function handles all events from the BLE stack that are of interest to this module. + * + * @param[in] p_ble_evt BLE stack event. + */ +void bsp_btn_ble_on_ble_evt(ble_evt_t * p_ble_evt); + + +#ifdef __cplusplus +} +#endif + +#endif /* BSP_BTN_BLE_H__ */ + +/** @} */ diff --git a/components/libraries/bsp/bsp_config.h b/components/libraries/bsp/bsp_config.h new file mode 100644 index 0000000..3dcf195 --- /dev/null +++ b/components/libraries/bsp/bsp_config.h @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup bsp Board Support Package + * @{ + * @ingroup app_common + * + * @brief BSP module. + * @details This module provides a layer of abstraction from the board. + * It allows the user to indicate certain states on LEDs in a simple way. + * Module functionality can be modified by additional defines: + * - BSP_SIMPLE - reduces functionality of this module to enable + * and read state of the buttons. + * - BSP_UART_SUPPORT - enables support for UART. + */ + +#ifndef BSP_CONFIG_H__ +#define BSP_CONFIG_H__ + +#include +#include +#include "boards.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE) +#include "app_button.h" + +#define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */ +#define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */ +#define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */ +#endif + +#define BSP_MS_TO_TICK(MS) (m_app_ticks_per_100ms * (MS / 100)) + + +#define BUTTON_ERASE_BONDING BSP_BUTTON_0_MASK +#define BUTTON_ERASE_ALL BSP_BUTTON_1_MASK +#define BUTTON_ADVERTISE BSP_BUTTON_0_MASK +#define BUTTON_CLEAR_EVT BSP_BUTTON_1_MASK +#define BUTTON_CAPSLOCK BSP_BUTTON_2_MASK +#define BSP_BUTTONS_ALL 0xFFFFFFFF +#define BSP_BUTTONS_NONE 0 + +#define BSP_LONG_PUSH_TIMEOUT_MS (1000) /**< The time to hold for a long push (in milliseconds). */ +/**@brief Types of BSP initialization. + */ + +#define ADVERTISING_LED_ON_INTERVAL 200 +#define ADVERTISING_LED_OFF_INTERVAL 1800 + +#define ADVERTISING_DIRECTED_LED_ON_INTERVAL 200 +#define ADVERTISING_DIRECTED_LED_OFF_INTERVAL 200 + +#define ADVERTISING_WHITELIST_LED_ON_INTERVAL 200 +#define ADVERTISING_WHITELIST_LED_OFF_INTERVAL 800 + +#define ADVERTISING_SLOW_LED_ON_INTERVAL 400 +#define ADVERTISING_SLOW_LED_OFF_INTERVAL 4000 + +#define BONDING_INTERVAL 100 + +#define SENT_OK_INTERVAL 100 +#define SEND_ERROR_INTERVAL 500 + +#define RCV_OK_INTERVAL 100 +#define RCV_ERROR_INTERVAL 500 + +#define ALERT_INTERVAL 200 + +#define BSP_LED_INDICATE_SENT_OK BSP_BOARD_LED_1 +#define BSP_LED_INDICATE_SEND_ERROR BSP_BOARD_LED_1 +#define BSP_LED_INDICATE_RCV_OK BSP_BOARD_LED_1 +#define BSP_LED_INDICATE_RCV_ERROR BSP_BOARD_LED_1 +#define BSP_LED_INDICATE_CONNECTED BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_BONDING BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_ADVERTISING_DIRECTED BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_ADVERTISING_SLOW BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_ADVERTISING_WHITELIST BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_INDICATE_ADVERTISING BSP_BOARD_LED_0 + +#define BSP_LED_INDICATE_USER_LED1 BSP_BOARD_LED_0 +#define BSP_LED_INDICATE_USER_LED2 BSP_BOARD_LED_1 +#define BSP_LED_INDICATE_USER_LED3 BSP_BOARD_LED_2 +#define BSP_LED_INDICATE_USER_LED4 BSP_BOARD_LED_3 + +#define BSP_LED_ALERT BSP_BOARD_LED_2 + +#ifdef __cplusplus +} +#endif + +#endif // BSP_CONFIG_H__ + +/** @} */ diff --git a/components/libraries/bsp/bsp_nfc.c b/components/libraries/bsp/bsp_nfc.c new file mode 100644 index 0000000..61760bd --- /dev/null +++ b/components/libraries/bsp/bsp_nfc.c @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "bsp_nfc.h" +#include "bsp.h" +#include "nrf_peripherals.h" + +#ifndef BSP_SIMPLE +#define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */ + +ret_code_t bsp_nfc_btn_init(uint32_t sleep_button) +{ + uint32_t err_code = bsp_event_to_button_action_assign(sleep_button, + BTN_ACTION_SLEEP, + BSP_EVENT_SLEEP); + return err_code; +} + +ret_code_t bsp_nfc_btn_deinit(uint32_t sleep_button) +{ + uint32_t err_code = bsp_event_to_button_action_assign(sleep_button, + BTN_ACTION_SLEEP, + BSP_EVENT_DEFAULT); + return err_code; +} + +ret_code_t bsp_nfc_sleep_mode_prepare(void) +{ +#if defined(NFCT_PRESENT) + NRF_NFCT->TASKS_SENSE = 1; + return NRF_SUCCESS; +#else + return NRF_ERROR_NOT_SUPPORTED; +#endif +} +#endif //BSP_SIMPLE diff --git a/components/libraries/bsp/bsp_nfc.h b/components/libraries/bsp/bsp_nfc.h new file mode 100644 index 0000000..227c859 --- /dev/null +++ b/components/libraries/bsp/bsp_nfc.h @@ -0,0 +1,108 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup bsp_nfc NFC BSP Module + * @{ + * @ingroup bsp + * + * @brief Module for setting the NFCT peripheral as a wakeup source. + * + * @details The application must notify this module before going into System OFF mode. + * Based on this notification, the NFC BSP Module sets the NFCT peripheral as a wakeup source + * through the Board Support Package. Additionally, any BSP Button can be configured to + * generate BSP sleep events. This module is applicable only if NFCT is used exclusively for + * wakeup. If NFCT is used for a different purpose, this module cannot be used. + */ + +#ifndef BSP_NFC_H__ +#define BSP_NFC_H__ + +#include +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for initializing the NFC Button Module. + * + * Before calling this function, the BSP module must be initialized with buttons. The chosen + * button is used to generate @ref BSP_EVENT_SLEEP events. + * + * @param[in] sleep_button Button ID used to generate @ref BSP_EVENT_SLEEP event. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error + * code is returned. + */ +ret_code_t bsp_nfc_btn_init(uint32_t sleep_button); + +/**@brief Function for deinitializing the NFC Button Module. + * + * Before calling this function, the BSP module must be initialized with buttons. The chosen + * button is used to generate default @ref BSP_EVENT_DEFAULT events. + * + * @param[in] sleep_button Button ID used to restore default event generation. + * + * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error + * code is returned. + */ +ret_code_t bsp_nfc_btn_deinit(uint32_t sleep_button); + +/**@brief Function for setting up NFCT peripheral as wake-up source. + * + * This function must be called before going into System OFF mode. + * + * @note This function is only applicable if NFCT is used exclusively for wakeup. + * If NFCT is used for a different purpose, this function cannot be used. + * + * @retval NRF_SUCCESS If NFCT peripheral was prepared successfully. Otherwise, + * a propagated error code is returned. + */ +ret_code_t bsp_nfc_sleep_mode_prepare(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BSP_NFC_H__ */ + +/** @} */ diff --git a/components/libraries/button/app_button.c b/components/libraries/button/app_button.c index 4b00b96..9cc9000 100644 --- a/components/libraries/button/app_button.c +++ b/components/libraries/button/app_button.c @@ -1,25 +1,52 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(BUTTON) #include "app_button.h" -#include -#include "nordic_common.h" -#include "app_util.h" #include "app_timer.h" #include "app_error.h" #include "nrf_drv_gpiote.h" #include "nrf_assert.h" -static app_button_cfg_t * mp_buttons = NULL; /**< Button configuration. */ + +static app_button_cfg_t const * mp_buttons = NULL; /**< Button configuration. */ static uint8_t m_button_count; /**< Number of configured buttons. */ static uint32_t m_detection_delay; /**< Delay before a button is reported as pushed. */ APP_TIMER_DEF(m_detection_delay_timer_id); /**< Polling timer id. */ @@ -43,11 +70,11 @@ static uint32_t m_pin_transition; static void detection_delay_timeout_handler(void * p_context) { uint8_t i; - + // Pushed button(s) detected, execute button handler(s). for (i = 0; i < m_button_count; i++) { - app_button_cfg_t * p_btn = &mp_buttons[i]; + app_button_cfg_t const * p_btn = &mp_buttons[i]; uint32_t btn_mask = 1 << p_btn->pin_no; if (btn_mask & m_pin_transition) { @@ -108,12 +135,12 @@ static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t } } -uint32_t app_button_init(app_button_cfg_t * p_buttons, +uint32_t app_button_init(app_button_cfg_t const * p_buttons, uint8_t button_count, uint32_t detection_delay) { uint32_t err_code; - + if (detection_delay < APP_TIMER_MIN_TIMEOUT_TICKS) { return NRF_ERROR_INVALID_PARAM; @@ -122,10 +149,7 @@ uint32_t app_button_init(app_button_cfg_t * p_buttons, if (!nrf_drv_gpiote_is_init()) { err_code = nrf_drv_gpiote_init(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } // Save configuration. @@ -135,19 +159,16 @@ uint32_t app_button_init(app_button_cfg_t * p_buttons, m_pin_state = 0; m_pin_transition = 0; - + while (button_count--) { - app_button_cfg_t * p_btn = &p_buttons[button_count]; + app_button_cfg_t const * p_btn = &p_buttons[button_count]; nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); config.pull = p_btn->pull_cfg; - + err_code = nrf_drv_gpiote_in_init(p_btn->pin_no, &config, gpiote_event_handler); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); } // Create polling timer. @@ -185,15 +206,14 @@ uint32_t app_button_disable(void) } -uint32_t app_button_is_pushed(uint8_t button_id, bool * p_is_pushed) +bool app_button_is_pushed(uint8_t button_id) { ASSERT(button_id <= m_button_count); ASSERT(mp_buttons != NULL); - app_button_cfg_t * p_btn = &mp_buttons[button_id]; + app_button_cfg_t const * p_btn = &mp_buttons[button_id]; bool is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no); - *p_is_pushed = !(is_set^(p_btn->active_state == APP_BUTTON_ACTIVE_HIGH)); - - return NRF_SUCCESS; + return !(is_set ^ (p_btn->active_state == APP_BUTTON_ACTIVE_HIGH)); } +#endif //NRF_MODULE_ENABLED(BUTTON) diff --git a/components/libraries/button/app_button.h b/components/libraries/button/app_button.h index 727d3e2..c407704 100644 --- a/components/libraries/button/app_button.h +++ b/components/libraries/button/app_button.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -42,6 +70,10 @@ #include "app_error.h" #include "nrf_gpio.h" +#ifdef __cplusplus +extern "C" { +#endif + #define APP_BUTTON_PUSH 1 /**< Indicates that a button is pushed. */ #define APP_BUTTON_RELEASE 0 /**< Indicates that a button is released. */ #define APP_BUTTON_ACTIVE_HIGH 1 /**< Indicates that a button is active high. */ @@ -65,7 +97,7 @@ typedef struct uint32_t high_to_low; /**Pin went from high to low */ uint32_t low_to_high; /**Pin went from low to high */ } pin_transition_t; - + /**@brief Function for initializing the Buttons. * * @details This function will initialize the specified pins as buttons, and configure the Button @@ -73,7 +105,7 @@ typedef struct * * @note Normally initialization should be done using the APP_BUTTON_INIT() macro * - * @note app_button_enable() function must be called in order to enable the button detection. + * @note app_button_enable() function must be called in order to enable the button detection. * * @param[in] p_buttons Array of buttons to be used (NOTE: Must be static!). * @param[in] button_count Number of buttons. @@ -81,7 +113,7 @@ typedef struct * * @return NRF_SUCCESS on success, otherwise an error code. */ -uint32_t app_button_init(app_button_cfg_t * p_buttons, +uint32_t app_button_init(app_button_cfg_t const * p_buttons, uint8_t button_count, uint32_t detection_delay); @@ -100,12 +132,15 @@ uint32_t app_button_disable(void); /**@brief Function for checking if a button is currently being pushed. * * @param[in] button_id Button index (in the app_button_cfg_t array given to app_button_init) to be checked. - * @param[out] p_is_pushed Button state. - * - * @retval NRF_SUCCESS State successfully read. - * @retval NRF_ERROR_INVALID_PARAM Invalid button index. + * + * @return Button state. */ -uint32_t app_button_is_pushed(uint8_t button_id, bool * p_is_pushed); +bool app_button_is_pushed(uint8_t button_id); + + +#ifdef __cplusplus +} +#endif #endif // APP_BUTTON_H__ diff --git a/components/libraries/console/console.c b/components/libraries/console/console.c deleted file mode 100644 index b6fe73a..0000000 --- a/components/libraries/console/console.c +++ /dev/null @@ -1,504 +0,0 @@ -/* Copyright (c) 2007 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - - -/** \file - * - * Implementation of console.h. - * - */ -#include "console.h" -#include "uart_legacy.h" - -static const uint8_t newline_input[] = CONSOLE_NEWLINE_INPUT; /*!< Needed to compare input against to find end of line */ -#define NEWLINE_INPUT_LEN (sizeof CONSOLE_NEWLINE_INPUT - 1) /*!< Subtract one for the zero termination */ - -static const char hex_tab[] = "0123456789ABCDEF"; /*!< Table of ASCII hexadecimal digits */ - -// static uint8_t m_IEN_status; // not referenced - -/** Console init - */ -static enum -{ - CONSOLE_UNINIT = 0, - CONSOLE_AVAILABLE -} m_console = CONSOLE_UNINIT; - -void console_init(void) -{ - hal_uart_init(UART_BAUD_19K2); - m_console = CONSOLE_AVAILABLE; -} - -bool console_available(void) -{ - if ( m_console == CONSOLE_AVAILABLE ) - { - return (true); - } - else - { - return (false); - } -} - -void console_put_string(uint8_t const * string) -{ - if ( m_console == CONSOLE_AVAILABLE ) - { - while (*string != 0) - { - hal_uart_putchar(*string++); - } - } -} - - -void console_put_line(uint8_t const * string) -{ - if ( m_console == CONSOLE_AVAILABLE ) - { - while (*string != 0) - { - hal_uart_putchar(*string++); - } - console_put_string((uint8_t *)CONSOLE_NEWLINE_OUTPUT); - } -} - - -void console_put_newline(void) -{ - if ( m_console == CONSOLE_AVAILABLE ) - { - console_put_string((uint8_t *)CONSOLE_NEWLINE_OUTPUT); - } -} - - -void console_put_chars(uint8_t const * chars, uint8_t num_chars) -{ - if ( m_console == CONSOLE_AVAILABLE ) - { - for ( ; num_chars > 0; num_chars--) - { - hal_uart_putchar(*chars++); - } - } -} - - -void console_get_string(uint8_t * string, uint8_t num_chars) -{ - if ( m_console == CONSOLE_AVAILABLE ) - { - for ( ; num_chars > 0; num_chars--) - { - *string++ = hal_uart_getchar(); - #ifdef CONSOLE_ENABLE_ECHO - hal_uart_putchar(*(string-1)); - #endif - } - *string = 0; /* Add zero terminator */ - } -} - -void console_get_line(uint8_t * string, uint8_t max_len) -{ - uint8_t c, k, m; - - if ( m_console == CONSOLE_AVAILABLE ) - { - c = '\0'; - for ( k = 0; k < max_len - 1 ; k++ ) - { - c = hal_uart_getchar(); - if (c == newline_input[0]) - { - break; - } - string[k] = c; - #ifdef CONSOLE_ENABLE_ECHO - hal_uart_putchar(c); - #endif - } - string[k] = 0; - /* Read (and discard) also rest of newline sequence if we found the start of if */ - /* This is were we may discard characters we should not, se the comments in the header file. */ - /* NOTE: We really should check what we read, and notify the caller if it is not really the newline sequence. */ - if ( c == newline_input[0] ) - { - for( m = 0; m < NEWLINE_INPUT_LEN - 1; m++) /* We have already read the first character */ - { - c = hal_uart_getchar(); - } - #ifdef CONSOLE_ENABLE_ECHO - /* We have read a newline, and since echo is enabled, we should also echo back a newline. */ - /* But this should be the output newline, which may differ from the input newline we read. */ - console_put_string((uint8_t *)CONSOLE_NEWLINE_OUTPUT - #endif - } - } -} //lint !e438 Last value assigned to 'c' not used - -bool console_chars_available(void) -{ - return(hal_uart_chars_available()); -} - -void console_get_chars(uint8_t * chars, uint8_t num_chars) -{ - if ( m_console == CONSOLE_AVAILABLE ) - { - for ( ; num_chars > 0; num_chars--) - { - *chars++ = hal_uart_getchar(); - #ifdef CONSOLE_ENABLE_ECHO - hal_uart_putchar(*(chars-1)); - #endif - } - } -} - - -void console_put_char(uint8_t ch) -{ - if ( m_console == CONSOLE_AVAILABLE ) - { - hal_uart_putchar(ch); - } -} - - -uint8_t console_get_char(void) -{ - uint8_t ch = '\0'; - - if ( m_console == CONSOLE_AVAILABLE ) - { - ch = hal_uart_getchar(); - #ifdef CONSOLE_ENABLE_ECHO - hal_uart_putchar(ch); - #endif - } - return ch; -} - -void console_put_decbyte(uint8_t b) // b is in the range [0 255] -{ - uint8_t b0; - uint8_t b1; - - if ( m_console == CONSOLE_AVAILABLE ) - { - b0 = (b % 10); // Remainder of b when divided by 10 - b /= 10; // forces w into the range [0 25] - - b1 = (b % 10); // Remainder of b when divided by 10 - b /= 10; // forces w into the range [0 2] - - if (b != 0) - { - hal_uart_putchar(b + '0'); - hal_uart_putchar(b1 + '0'); - hal_uart_putchar(b0 + '0'); - } - else if (b1 != 0) - { - hal_uart_putchar(b1 + '0'); - hal_uart_putchar(b0 + '0'); - } - else - { - hal_uart_putchar(b0 + '0'); - } - } -} - -void console_put_decword(uint16_t w) // w is in the range [0 65535] -{ - uint8_t w0; - uint8_t w1; - uint8_t w2; - uint8_t w3; - - if ( m_console == CONSOLE_AVAILABLE ) - { - w0 = (w % 10); // Remainder of w when divided by 10 - w /= 10; // forces w into the range [0 6553] - - w1 = (w % 10); // Remainder of w when divided by 10 - w /= 10; // forces w into the range [0 655] - - w2 = (w % 10); // Remainder of w when divided by 10 - w /= 10; // forces w into the range [0 65] - - w3 = (w % 10); // Remainder of w when divided by 10 - w /= 10; // forces w into the range [0 6] - - if (w != 0) - { - hal_uart_putchar((uint8_t)w + '0'); /* We may safely cast w to the smaller type, as we have */ - /* made sure (above) that its value will fit. */ - hal_uart_putchar(w3 + '0'); - hal_uart_putchar(w2 + '0'); - hal_uart_putchar(w1 + '0'); - hal_uart_putchar(w0 + '0'); - } - else if (w3 != 0) - { - hal_uart_putchar(w3 + '0'); - hal_uart_putchar(w2 + '0'); - hal_uart_putchar(w1 + '0'); - hal_uart_putchar(w0 + '0'); - } - else if (w2 != 0) - { - hal_uart_putchar(w2 + '0'); - hal_uart_putchar(w1 + '0'); - hal_uart_putchar(w0 + '0'); - } - else if (w1 != 0) - { - hal_uart_putchar(w1 + '0'); - hal_uart_putchar(w0 + '0'); - } - else - { - hal_uart_putchar(w0 + '0'); - } - } -} - - -void console_put_dec32bit(uint32_t ww) // ww is in the range [0 4294967295] -{ - uint8_t ww0; - uint8_t ww1; - uint8_t ww2; - uint8_t ww3; - uint8_t ww4; - uint8_t ww5; - uint8_t ww6; - uint8_t ww7; - uint8_t ww8; - - if ( m_console == CONSOLE_AVAILABLE ) - { - ww0 = (ww % 10); // Remainder of ww when divided by 10 - ww /= 10; // forces ww into the range [0 429496729] - - ww1 = (ww % 10); // Remainder of ww when divided by 10 - ww /= 10; // forces ww into the range [0 42949672] - - ww2 = (ww % 10); // Remainder of ww when divided by 10 - ww /= 10; // forces ww into the range [0 4294967] - - ww3 = (ww % 10); // Remainder of ww when divided by 10 - ww /= 10; // forces ww into the range [0 429496] - - ww4 = (ww % 10); // Remainder of ww when divided by 10 - ww /= 10; // forces ww into the range [0 42949] - - ww5 = (ww % 10); // Remainder of ww when divided by 10 - ww /= 10; // forces ww into the range [0 4294] - - ww6 = (ww % 10); // Remainder of ww when divided by 10 - ww /= 10; // forces ww into the range [0 429] - - ww7 = (ww % 10); // Remainder of ww when divided by 10 - ww /= 10; // forces ww into the range [0 42] - - ww8 = (ww % 10); // Remainder of ww when divided by 10 - ww /= 10; // forces ww into the range [0 4] - - - if (ww != 0) - { - hal_uart_putchar((uint8_t)ww + '0'); /* We may safely cast ww to the smaller type, as we have */ - /* made sure (above) that its value will fit. */ - hal_uart_putchar(ww8 + '0'); - hal_uart_putchar(ww7 + '0'); - hal_uart_putchar(ww6 + '0'); - hal_uart_putchar(ww5 + '0'); - hal_uart_putchar(ww4 + '0'); - hal_uart_putchar(ww3 + '0'); - hal_uart_putchar(ww2 + '0'); - hal_uart_putchar(ww1 + '0'); - hal_uart_putchar(ww0 + '0'); - } - else if (ww8 != 0) - { - hal_uart_putchar(ww8 + '0'); - hal_uart_putchar(ww7 + '0'); - hal_uart_putchar(ww6 + '0'); - hal_uart_putchar(ww5 + '0'); - hal_uart_putchar(ww4 + '0'); - hal_uart_putchar(ww3 + '0'); - hal_uart_putchar(ww2 + '0'); - hal_uart_putchar(ww1 + '0'); - hal_uart_putchar(ww0 + '0'); - } - else if (ww7 != 0) - { - hal_uart_putchar(ww7 + '0'); - hal_uart_putchar(ww6 + '0'); - hal_uart_putchar(ww5 + '0'); - hal_uart_putchar(ww4 + '0'); - hal_uart_putchar(ww3 + '0'); - hal_uart_putchar(ww2 + '0'); - hal_uart_putchar(ww1 + '0'); - hal_uart_putchar(ww0 + '0'); - } - else if (ww6 != 0) - { - hal_uart_putchar(ww6 + '0'); - hal_uart_putchar(ww5 + '0'); - hal_uart_putchar(ww4 + '0'); - hal_uart_putchar(ww3 + '0'); - hal_uart_putchar(ww2 + '0'); - hal_uart_putchar(ww1 + '0'); - hal_uart_putchar(ww0 + '0'); - } - else if (ww5 != 0) - { - hal_uart_putchar(ww5 + '0'); - hal_uart_putchar(ww4 + '0'); - hal_uart_putchar(ww3 + '0'); - hal_uart_putchar(ww2 + '0'); - hal_uart_putchar(ww1 + '0'); - hal_uart_putchar(ww0 + '0'); - } - else if (ww4 != 0) - { - hal_uart_putchar(ww4 + '0'); - hal_uart_putchar(ww3 + '0'); - hal_uart_putchar(ww2 + '0'); - hal_uart_putchar(ww1 + '0'); - hal_uart_putchar(ww0 + '0'); - } - else if (ww3 != 0) - { - hal_uart_putchar(ww3 + '0'); - hal_uart_putchar(ww2 + '0'); - hal_uart_putchar(ww1 + '0'); - hal_uart_putchar(ww0 + '0'); - } - else if (ww2 != 0) - { - hal_uart_putchar(ww2 + '0'); - hal_uart_putchar(ww1 + '0'); - hal_uart_putchar(ww0 + '0'); - } - else if (ww1 != 0) - { - hal_uart_putchar(ww1 + '0'); - hal_uart_putchar(ww0 + '0'); - } - else - { - hal_uart_putchar(ww0 + '0'); - } - } -} - - -void console_put_hexnybble(uint8_t n) -{ - if ( m_console == CONSOLE_AVAILABLE ) - { - hal_uart_putchar((uint8_t)hex_tab[n & 0x0f]); - } -} - - -void console_put_hexbyte(uint8_t b) -{ - console_put_hexnybble(b >> 4); - console_put_hexnybble(b & 0x0f); -} - - -void console_put_hexword(uint16_t w) -{ - console_put_hexbyte((uint8_t)(w >> 8)); - console_put_hexbyte(w & 0xff); -} - -void console_put_hexbytearray(uint8_t * p, uint8_t n) -{ - uint8_t i; - if (n > 0) - { - console_put_hexbyte(p[0]); - } - for (i = 1; i < n; ++i) - { - console_put_string((uint8_t *)"-"); - console_put_hexbyte(p[i]); - } -} - -uint8_t console_get_hexnybble(void) -{ - uint8_t c; - if ( m_console == CONSOLE_AVAILABLE ) - { - c = hal_uart_getchar(); - #ifdef CONSOLE_ENABLE_ECHO - hal_uart_putchar(c); - #endif - - if (c >= '0' && c <= '9') - { - return c - '0'; - } - else if (c >= 'a' && c <= 'f') - { - return (c - 'a') + 10; - } - else if (c >= 'A' && c <= 'F') - { - return (c - 'A') + 10; - } - else - { - /** @note We have encountered something that is not a hexadecimal digit. - * This is an error, and it is not reported. An ASSERT(false) would be suitable here. */ - return 0; - } - - return 0; // @note This may not be the correct value, what should be returned if m_console != CONSOLE_AVAILABLE ? -} - - -uint8_t console_get_hexbyte(void) -{ - uint8_t nh = console_get_hexnybble(); - return (uint8_t)((nh << 4) | console_get_hexnybble()); -} - - -uint16_t console_get_hexword(void) -{ - uint16_t bh = console_get_hexbyte(); - return (bh << 8) | console_get_hexbyte(); -} -/* -bool console_tx_completed(void) -{ - return hal_uart_tx_buf_empty(); -} -*/ - - diff --git a/components/libraries/console/console.h b/components/libraries/console/console.h deleted file mode 100644 index 947ae94..0000000 --- a/components/libraries/console/console.h +++ /dev/null @@ -1,343 +0,0 @@ -/* Copyright (c) 2007 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - - -/** \file - * - * \section console_description Description - * - * Higher-level functions for writing to, and reading from, the UART. - * - * Lower-level functions are provided by hal_uart.h and its implementations, - * which this module uses to obtain hardware indpendency. - * - * Before the other functions of this module is used, the module must be initialized - * by calling console_init(). - * Also, the interrupt used by the UART must be enabled. - * - * Functions for writing to the UART have a "put" infix, functions for reading - * from he UART a "get" infix. - * - * The newline problem is of interest. See e.g. - * . - * The newline style used by default by this module is ASCII CR and LF (x0D x0A). - * The module may be configured to use other newline styles, including setting different - * newline styles for input and output, see the section on configuration further below. - * - * To print a newline only, call console_put_newline(), or console_put_line() with a - * properly casted empty string as argument: - * - console_put_newline() - * - console_put_line((uint8_t *)"") - * - * The newline solution is not completely general, see the comments to console_get_line(). - * - * End-of-file and end-of-file representation may also be of concern. This has not been - * dealt with in any way in this module. - * - * This module provides optional echo of input to output. This may e.g. be used to enable - * the other part to see what is sent from that side (if other part does not have local echo) - * or to ensure that the UART communication is working. See the configuration section for - * info on how to turn on this feature. - * - * A note on input-to-output echo and newline: If echo is enabled and an input newline is read, - * an output newline, which may be different (dependent upon module configuration), is echoed - * back. - * - * A note on terminology: In this file, what is meant by a "string" is a zero-terminated - * sequence (an array) of characters (or octets). This as opposed to a sequence of characters - * without such termination. - * - * String constants (like "this one") are (per the C standard) of type "array of character". - * Therefore, Lint may complain if string constants are used as arguments to the functions - * in this module. To avoid this, cast the string to uint8_t like this: - * console_put_string((uint8_t *)"this one"). - * - * \section console_configuration Configuration - * - * The module may be configured by the use of suitable defines. To change the newline style - * used, define CONSOLE_NEWLINE_INPUT and CONSOLE_NEWLINE_OUTPUT to suitable values. (See - * this file (console.h) for possible values.) To enable echoing of input to output, define - * CONSOLE_ENABLE_ECHO. - * - * \section console_note Note - * - * The console functions that access the UART driver will enable the rewired - * interrupts for the driver. This ensures that the driver will not stall and - * lock the program. The interrupts will be restored to their former value - * before returning to the caller in each instance that this is used. - * - */ - -#ifndef CONSOLE_H__ -#define CONSOLE_H__ - -#include -#include - -/* Newline character sequences */ -#define CONSOLE_NEWLINE_CRLF "\r\n" //!< CRLF newline -#define CONSOLE_NEWLINE_CR "\r" //!< CR newline -#define CONSOLE_NEWLINE_LF "\n" //!< LF newline -#define CONSOLE_NEWLINE_CRLF_NUMERIC "\x0D\x0A" //!< Hardcoded ASCII values for CRLF -#define CONSOLE_NEWLINE_CR_NUMERIC "\x0D" //!< It is possible, though unlikely, that -#define CONSOLE_NEWLINE_LF_NUMERIC "\x0A" //!< CR and LF do not equal these values. - -#define CONSOLE_NEWLINE_DEFAULT CONSOLE_NEWLINE_CRLF_NUMERIC /*!< Default newline style */ - -/* Newline style for input */ -#ifndef CONSOLE_NEWLINE_INPUT - /* CONSOLE_NEWLINE_INPUT was not defined in console_config.h */ - #define CONSOLE_NEWLINE_INPUT CONSOLE_NEWLINE_DEFAULT //!< Newline style for input -#endif - -/* Newline style for output */ -#ifndef CONSOLE_NEWLINE_OUTPUT - /* CONSOLE_NEWLINE_OUTPUT was not defined in console_config.h */ - #define CONSOLE_NEWLINE_OUTPUT CONSOLE_NEWLINE_DEFAULT //!< Newline style for output -#endif - -/** - * @brief Function for initializing the console. - * Init must be called prior to any other console functions. - * The success of init() can be tested using the console_available() function. - * console_init() is idempotent (can be called multiple times) - * \post Interrupts required for the console I/O device (UART) are enabled. -*/ -void console_init(void); - -/** \brief Function for testing if the console is available. - * - * \return true if console is initialised and I/O peripheral is initialised - * \return false if console is not initialised or I/O peripheral init failed. -*/ -bool console_available(void); - - -/** \brief Function for printing a string. - * - * Print a zero-terminated string of characters (octets). - * - * \param[in] string Pointer to the string. - * \pre only works if init() previously called - */ -void console_put_string(uint8_t const * string); - - -/** \brief Function for printing a string and newline. - * - * Print a zero-terminated string of characters (octets) - * and thereafter the output newline sequence. - * - * \param[in] string Pointer to the string. - * \pre only works if init() previously called - */ -void console_put_line(uint8_t const * string); - - -/** \brief Function for printing a newline (the newline output sequence). - * \pre only works if init() previously called - */ -void console_put_newline(void); - - -/** \brief Function for printing a number of characters (octets). - * - * \param[in] chars Pointer to the characters - * \param[in] num_chars Number of characters to print - * \pre only works if init() previously called - */ -void console_put_chars(uint8_t const * chars, uint8_t num_chars); - - -/** \brief Function for reading a number of characters (octets) and append zero-termination. - * - * \param[out] string Pointer to characters - * \param[in] num_chars Number of characters to read. - * \warning: Note that due to the appended zero termination, there must - * be room for num_chars + 1 octets in the space pointed to by argument chars. - * \pre only works if init() previously called - */ -void console_get_string(uint8_t * string, uint8_t num_chars); - -/** \brief Function for reading a line. - * - * Read characters until end of line or until a maximum number - * of characters have been read, whatever comes first. - * The characters read are returned as a zero-terminated string - * (withouth the newline). - * - * \warning The function has a limitation in that it assumes that if the - * start of a newline sequence is found, the rest of the newline sequence must - * follow. The consequence of this is that if a leading part of the newline - * sequence (the "leading part") is found in the input, followed by something - * that is not the rest of the newline sequence, both the leading part and - * the first part of what follows will be silently discarded. - * (The practical reason for this behaviour is the limitation on string length - * given by the max_len parameter combined with the fact that hal_uart does not - * provide a means of "putting back" already read characters. It is - * possible to implement the function is such a way that this limitation would - * apply only when the string is too full to fit a number of characters equal to - * the number of characters in a newline sequence. Letting it apply all the time - * seems more consistent, though.) - * - * \param[out] string Pointer to the string - * \param[in] max_len Maximum length of string, including zero terminator. - * Note that max_len must be at least two (max_len >= 2). - * \pre only works if init() previously called - */ -void console_get_line(uint8_t * string, uint8_t max_len); - -/** \brief Function for getting number of characters sent to console. - * - * - * \return Number of characters (0..255) -*/ -bool console_chars_available(void); - -/** \brief Function for reading a number of characters (octets). - * - * \param[out] chars Pointer to characters - * \param[in] num_chars Number of characters to read - * \pre only works if init() previously called - */ -void console_get_chars(uint8_t * chars, uint8_t num_chars); - - -/** \brief Function for writing a single character (octet). - * - * This function is nothing but a direct wrapper for hal_uart_putchar(). - * It is provided here for completeness only. You may consider to use - * hal_uart_putchar() directly instead. - * \param ch Character to write - * \pre only works if init() previously called - */ -void console_put_char(uint8_t ch); - - -/** \brief Function for reading a single character (octet). - * - * This function is a wrapper for hal_uart_getchar(), with the additional opption - * of echo of input to output (if the console module is so configured, see the - * module documentation). - * \pre only works if init() previously called - * \return Read character - */ -uint8_t console_get_char(void); - - -/** \brief Function for printing the decimal ASCII representation of an 8-bit number. - * - * \warning: This function is larger and more complex than the corresponding - * functions to write hexadecimal representations. - * - * \param b Number in the range [0 255] - * \pre only works if init() previously called - */ -void console_put_decbyte(uint8_t b); - - -/** \brief Function for printing the decimal ASCII representation of a 16-bit number. - * - * \warning: This function is larger and more complex than the corresponding - * functions to write hexadecimal representations. - * - * \param w Number in the range [0 65535] - * \pre only works if init() previously called - */ -void console_put_decword(uint16_t w); - - -/** \brief Function for printing the decimal ASCII representation of a 32-bit number. - * - * \warning: This function is larger and more complex than the corresponding - * functions to write hexadecimal representations. - * - * \param ww Number in the range [0 4294967295] - * \pre only works if init() previously called - */ -void console_put_dec32bit(uint32_t ww); - - -/** \brief Function for printing the hexadecimal ASCII representation of a nibble (half an octet, four bits). - * - * Four bits (a nibble) equals one hexadecimal digit. - * - * \param n A number from zero to 15, both inclusive - * \pre only works if init() previously called - */ -void console_put_hexnybble(uint8_t n); - - -/** \brief Function for printing the hexadecimal ASCII representation of a byte (an octet). - * - * \param b A byte (an octet) - */ -void console_put_hexbyte(uint8_t b); - - -/** \brief Function for printing the hexadecimal ASCII representation of a word (two octets). - * - * \param w A word (sixten-bits, two octets) - */ -void console_put_hexword(uint16_t w); - -/** \brief Function for printing a string of hexbytes. - * - * \param p a pointer to the first element - * \param n the length of the array - */ -void console_put_hexbytearray(uint8_t* p, uint8_t n); - -/** \brief Function for reading one hexadecimal digit. - * - * Read the hexadecimal ASCII representation of a nibble (half an octet, four bits) - * - * \warning: The function returns zero on invalid input (i.e. input that is not an - * hexadecimal digit). - * - * \return A number from zero to 15, both inclusive - * \pre only works if init() previously called - */ -uint8_t console_get_hexnybble(void); - - -/** \brief Function for reading two hexadecimal digits. - * - * Read the hexadecimal ASCII representation of a byte (an octet) - * - * \warning: Invalid input: Input characters that are not hexadecimal digits - * are treated as the hexadecimal digit zero. - * - * \return A number from zero to 255, both inclusive - */ -uint8_t console_get_hexbyte(void); - - -/** \brief Function for reading four hexadecimal digits. - * - * Read the hexadecimal ASCII representation of a word (16 bits) - * - * \warning: Invalid input: Input characters that are not hexadecimal digits - * are treated as the hexadecimal digit zero. - * - * \return A number from zero to 65535, both inclusive - */ -uint16_t console_get_hexword(void); - -/** \brief Function for checking if the last tx is completed. - * - * \return TRUE, if the tx is completed, FALSE, is the Tx is in progress - */ -bool console_tx_completed(void); - -#endif - diff --git a/components/libraries/crc16/crc16.c b/components/libraries/crc16/crc16.c index 24669b1..59fcc2e 100644 --- a/components/libraries/crc16/crc16.c +++ b/components/libraries/crc16/crc16.c @@ -1,31 +1,61 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(CRC16) #include "crc16.h" -#include -uint16_t crc16_compute(const uint8_t * p_data, uint32_t size, const uint16_t * p_crc) +#include + +uint16_t crc16_compute(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc) { - uint32_t i; - uint16_t crc = (p_crc == NULL) ? 0xffff : *p_crc; + uint16_t crc = (p_crc == NULL) ? 0xFFFF : *p_crc; - for (i = 0; i < size; i++) + for (uint32_t i = 0; i < size; i++) { - crc = (unsigned char)(crc >> 8) | (crc << 8); + crc = (uint8_t)(crc >> 8) | (crc << 8); crc ^= p_data[i]; - crc ^= (unsigned char)(crc & 0xff) >> 4; + crc ^= (uint8_t)(crc & 0xFF) >> 4; crc ^= (crc << 8) << 4; - crc ^= ((crc & 0xff) << 4) << 1; + crc ^= ((crc & 0xFF) << 4) << 1; } return crc; } +#endif //NRF_MODULE_ENABLED(CRC16) diff --git a/components/libraries/crc16/crc16.h b/components/libraries/crc16/crc16.h index 1ecd012..628c218 100644 --- a/components/libraries/crc16/crc16.h +++ b/components/libraries/crc16/crc16.h @@ -1,43 +1,81 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup crc_compute CRC compute + * @defgroup crc16 CRC16 compute * @{ * @ingroup hci_transport * - * @brief This module implements the CRC-16 calculation in the blocks. + * @brief This module implements CRC-16-CCITT (polynomial 0x1021) with 0xFFFF initial value. + * The data can be passed in multiple blocks. */ - + #ifndef CRC16_H__ #define CRC16_H__ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Function for calculating CRC-16 in blocks. * - * Feed each consecutive data block into this function, along with the current value of p_crc as - * returned by the previous call of this function. The first call of this function should pass NULL + * Feed each consecutive data block into this function, along with the current value of p_crc as + * returned by the previous call of this function. The first call of this function should pass NULL * as the initial value of the crc in p_crc. * * @param[in] p_data The input data block for computation. * @param[in] size The size of the input data block in bytes. - * @param[in] p_crc The previous calculated CRC-16 value or NULL if first call. + * @param[in] p_crc The previous calculated CRC-16 value or NULL if first call. * * @return The updated CRC-16 value, based on the input supplied. */ -uint16_t crc16_compute(const uint8_t * p_data, uint32_t size, const uint16_t * p_crc); +uint16_t crc16_compute(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc); + + +#ifdef __cplusplus +} +#endif #endif // CRC16_H__ - + /** @} */ diff --git a/components/libraries/crc32/crc32.c b/components/libraries/crc32/crc32.c new file mode 100644 index 0000000..5bc7a71 --- /dev/null +++ b/components/libraries/crc32/crc32.c @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(CRC32) +#include "crc32.h" + +#include + +uint32_t crc32_compute(uint8_t const * p_data, uint32_t size, uint32_t const * p_crc) +{ + uint32_t crc; + + crc = (p_crc == NULL) ? 0xFFFFFFFF : ~(*p_crc); + for (uint32_t i = 0; i < size; i++) + { + crc = crc ^ p_data[i]; + for (uint32_t j = 8; j > 0; j--) + { + crc = (crc >> 1) ^ (0xEDB88320U & ((crc & 1) ? 0xFFFFFFFF : 0)); + } + } + return ~crc; +} +#endif //NRF_MODULE_ENABLED(CRC32) diff --git a/components/libraries/crc32/crc32.h b/components/libraries/crc32/crc32.h new file mode 100644 index 0000000..3521e54 --- /dev/null +++ b/components/libraries/crc32/crc32.h @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup crc32 CRC32 compute + * @{ + * @ingroup hci_transport + * + * @brief This module implements the CRC-32 calculation in the blocks. + */ + +#ifndef CRC32_H__ +#define CRC32_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Function for calculating CRC-32 in blocks. + * + * Feed each consecutive data block into this function, along with the current value of p_crc as + * returned by the previous call of this function. The first call of this function should pass NULL + * as the initial value of the crc in p_crc. + * + * @param[in] p_data The input data block for computation. + * @param[in] size The size of the input data block in bytes. + * @param[in] p_crc The previous calculated CRC-32 value or NULL if first call. + * + * @return The updated CRC-32 value, based on the input supplied. + */ +uint32_t crc32_compute(uint8_t const * p_data, uint32_t size, uint32_t const * p_crc); + + +#ifdef __cplusplus +} +#endif + +#endif // CRC32_H__ + +/** @} */ diff --git a/components/libraries/crypto/nrf_crypto.c b/components/libraries/crypto/nrf_crypto.c new file mode 100644 index 0000000..90d3baa --- /dev/null +++ b/components/libraries/crypto/nrf_crypto.c @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_error.h" +#include "sdk_common.h" +#include "ecc.h" +#include "sha256.h" +#include "nrf_crypto.h" + +uint32_t nrf_crypto_init(void) +{ + ecc_init(false); + + return NRF_SUCCESS; +} + + +uint32_t nrf_crypto_public_key_compute(uint32_t curve, + nrf_crypto_key_t const *p_sk, + nrf_crypto_key_t *p_pk) +{ + if(curve != NRF_CRYPTO_CURVE_SECP256R1) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if(p_sk->len != ECC_P256_SK_LEN || p_pk->len != ECC_P256_PK_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return ecc_p256_public_key_compute(p_sk->p_le_data, p_pk->p_le_data); +} + + +uint32_t nrf_crypto_shared_secret_compute(uint32_t curve, + nrf_crypto_key_t const *p_sk, + nrf_crypto_key_t const *p_pk, + nrf_crypto_key_t *p_ss) +{ + if(curve != NRF_CRYPTO_CURVE_SECP256R1) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if(p_sk->len != ECC_P256_SK_LEN || p_pk->len != ECC_P256_PK_LEN || p_ss->len != ECC_P256_SK_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return ecc_p256_shared_secret_compute(p_sk->p_le_data, p_pk->p_le_data, p_ss->p_le_data); +} + +uint32_t nrf_crypto_sign(uint32_t curve, + nrf_crypto_key_t const *p_sk, + nrf_crypto_key_t const *p_hash, + nrf_crypto_key_t *p_sig) +{ + if(curve != NRF_CRYPTO_CURVE_SECP256R1) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if(p_sk->len != ECC_P256_SK_LEN || p_sig->len != ECC_P256_PK_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + return ecc_p256_sign(p_sk->p_le_data, p_hash->p_le_data, p_hash->len, p_sig->p_le_data); +} + +uint32_t nrf_crypto_verify(uint32_t curve, + nrf_crypto_key_t const *p_pk, + nrf_crypto_key_t const *p_hash, + nrf_crypto_key_t const *p_sig) +{ + if(curve != NRF_CRYPTO_CURVE_SECP256R1) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if(p_pk->len != ECC_P256_PK_LEN || p_sig->len != ECC_P256_PK_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return ecc_p256_verify(p_pk->p_le_data, p_hash->p_le_data, p_hash->len, p_sig->p_le_data); +} + + +uint32_t nrf_crypto_hash_compute(uint32_t hash_alg, + uint8_t const *p_data, + uint32_t len, + nrf_crypto_key_t *p_hash) +{ + ret_code_t err_code; + sha256_context_t ctx; + + if(hash_alg != NRF_CRYPTO_HASH_ALG_SHA256) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if(p_hash->len != (256 >> 3)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + err_code = sha256_init(&ctx); + VERIFY_SUCCESS(err_code); + + err_code = sha256_update(&ctx, p_data, len); + VERIFY_SUCCESS(err_code); + + err_code = sha256_final(&ctx, p_hash->p_le_data, 1); + VERIFY_SUCCESS(err_code); + + p_hash->len = (256 >> 3); + + return NRF_SUCCESS; +} + + diff --git a/components/libraries/crypto/nrf_crypto.h b/components/libraries/crypto/nrf_crypto.h new file mode 100644 index 0000000..bad1991 --- /dev/null +++ b/components/libraries/crypto/nrf_crypto.h @@ -0,0 +1,253 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_CRYPTO_H__ +#define NRF_CRYPTO_H__ + +#include +#include "nrf_svci.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup nrf_crypto Cryptography library + * @ingroup app_common + * @{ + * + * @brief Cryptography library (nrf_crypto). + * + * @details The cryptography library provides functions to compute keys, shared secrets, and hashes, + * and to sign and verify data using digital signatures. + */ + +#define NRF_CRYPTO_SVCI_BASE 0 //!< Base SVCI number for the nrf_crypto module. + +/** @brief SVCIs for the nrf_crypto module. */ +enum NRF_CRYPTO_SVCIS +{ + NRF_CRYPTO_SVCI_INIT = NRF_CRYPTO_SVCI_BASE, /**< Initialize the nrf_crypto module. */ + NRF_CRYPTO_SVCI_PUBLIC_KEY_COMPUTE, /**< Compute a public key from a private key. */ + NRF_CRYPTO_SVCI_SHARED_SECRET_COMPUTE, /**< Compute a shared secret from a key pair. */ + NRF_CRYPTO_SVCI_SIGN, /**< Compute a signature from a private key and a hash. */ + NRF_CRYPTO_SVCI_VERIFY, /**< Verify a signature with a public key and a hash. */ + NRF_CRYPTO_SVCI_HASH_COMPUTE, /**< Compute a digest from data. */ +}; + +/**@brief Cryptographic key. + * + * @details This structure is a generic container for a cryptographic key, shared secret, + * hash, or signature. The data is contained in raw bytes in little-endian format. + * If more than one array is present in the data (for example, multiple point + * coordinates), those must be placed consecutively in memory. + * + * For ECC, the key length depends on the length of the ECC curve: + * Key type | Key length + * --------------|--------------------- + * Public key | 2 * curve length + * Private key | 1 * curve length + * Shared secret | 2 * curve length + * Signature | 2 * curve length + */ +typedef struct +{ + uint8_t *p_le_data; /**< Pointer to the key data in little-endian format. */ + uint32_t len; /**< Length of the key data in bytes. */ +} nrf_crypto_key_t; + + +/**@defgroup NRF_CRYPTO_CURVES Cryptographic curves + * @brief Cryptographic curves that are available to the application. Currently, the nrf_crypto library supports only NIST p-256. + * @{ */ +#define NRF_CRYPTO_CURVE_INVALID 0x00 //!< Invalid curve. +#define NRF_CRYPTO_CURVE_SECP160R1 0x01 //!< NIST 160-bit. +#define NRF_CRYPTO_CURVE_SECP192R1 0x02 //!< NIST 192-bit. +#define NRF_CRYPTO_CURVE_SECP224R1 0x03 //!< NIST 224-bit. +#define NRF_CRYPTO_CURVE_SECP256R1 0x04 //!< NIST 256-bit. +#define NRF_CRYPTO_CURVE_SECP384R1 0x05 //!< NIST 384-bit. +#define NRF_CRYPTO_CURVE_SECP521R1 0x06 //!< NIST 521-bit. +#define NRF_CRYPTO_CURVE_SECP192K1 0x07 //!< Koblitz 192-bit. +#define NRF_CRYPTO_CURVE_SECP224K1 0x08 //!< Koblitz 224-bit. +#define NRF_CRYPTO_CURVE_SECP256K1 0x09 //!< Koblitz 256-bit. +#define NRF_CRYPTO_CURVE_CURVE25519 0x0A //!< Curve 25519. +/** @} */ + +/**@defgroup NRF_CRYPTO_HASH_ALGS Hashing algorithms + * @brief Hashing algorithms that are available to the application. Currently, the nrf_crypto library supports only SHA-256. + * @{ */ +#define NRF_CRYPTO_HASH_ALG_INVALID 0x00 //!< Invalid hashing algorithm. +#define NRF_CRYPTO_HASH_ALG_MD5 0x01 //!< MD5. +#define NRF_CRYPTO_HASH_ALG_SHA0 0x02 //!< SHA-0. +#define NRF_CRYPTO_HASH_ALG_SHA1 0x03 //!< SHA-1. +#define NRF_CRYPTO_HASH_ALG_SHA224 0x04 //!< SHA-224 (SHA-2). +#define NRF_CRYPTO_HASH_ALG_SHA256 0x05 //!< SHA-256 (SHA-2). +#define NRF_CRYPTO_HASH_ALG_SHA384 0x06 //!< SHA-384 (SHA-2). +#define NRF_CRYPTO_HASH_ALG_SHA512 0x07 //!< SHA-512 (SHA-2). +/** @} */ + + +/**@brief Function for initializing the cryptography library. + */ +#ifdef SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION + uint32_t nrf_crypto_init(void); +#else +SVCI(NRF_CRYPTO_SVCI_INIT, uint32_t, nrf_crypto_init); +#endif + +/**@brief Function for computing a public key from a private key. + * + * @param[in] curve Elliptic curve to use (see @ref NRF_CRYPTO_CURVES). + * @param[in] p_sk Private key (see @ref nrf_crypto_key_t). + * @param[out] p_pk Public key (see @ref nrf_crypto_key_t). + * + * @retval NRF_SUCCESS If the public key was computed successfully. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected curve is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers is invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the length of the provided private key is invalid or the public key is bigger than the size of the provided buffer. + */ +#ifdef SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION + uint32_t nrf_crypto_public_key_compute(uint32_t curve, nrf_crypto_key_t const *p_sk, nrf_crypto_key_t *p_pk); +#else +SVCI(NRF_CRYPTO_SVCI_PUBLIC_KEY_COMPUTE, uint32_t,\ + nrf_crypto_public_key_compute, uint32_t, curve, \ + nrf_crypto_key_t const *, p_sk, \ + nrf_crypto_key_t *, p_pk); +#endif + + +/**@brief Function for computing a shared secret from a key pair. + * + * @param[in] curve Elliptic curve to use (see @ref NRF_CRYPTO_CURVES). + * @param[in] p_sk Private key (see @ref nrf_crypto_key_t). + * @param[in] p_pk Public key (see @ref nrf_crypto_key_t). + * @param[out] p_ss Shared secret (see @ref nrf_crypto_key_t). + * + * @retval NRF_SUCCESS If the shared secret was computed successfully. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected curve is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers is invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the length of any of the provided keys is invalid or the shared secret is bigger than the size of the provided buffer. + */ +#ifdef SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION + uint32_t nrf_crypto_shared_secret_compute(uint32_t curve, nrf_crypto_key_t const *p_sk, nrf_crypto_key_t const *p_pk, nrf_crypto_key_t *p_ss); +#else +SVCI(NRF_CRYPTO_SVCI_SHARED_SECRET_COMPUTE, uint32_t, \ + nrf_crypto_shared_secret_compute, uint32_t, curve, \ + nrf_crypto_key_t const *, p_sk, \ + nrf_crypto_key_t const *, p_pk, \ + nrf_crypto_key_t *, p_ss); +#endif + +/**@brief Function for signing a hash or a digest using a private key. + * + * @param[in] curve Elliptic curve to use (see @ref NRF_CRYPTO_CURVES). + * @param[in] p_sk Private key (see @ref nrf_crypto_key_t). + * @param[in] p_hash Hash or digest to sign (see @ref nrf_crypto_key_t). + * @param[out] p_sig Signature (see @ref nrf_crypto_key_t). + * + * @retval NRF_SUCCESS If the signature was created successfully. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected curve is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers is invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the length of the provided private key or hash is invalid or the signature is bigger than the size of the provided buffer. + */ +#ifdef SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION + uint32_t nrf_crypto_sign(uint32_t curve, nrf_crypto_key_t const *p_sk, nrf_crypto_key_t const *p_hash, nrf_crypto_key_t *p_sig); +#else +SVCI(NRF_CRYPTO_SVCI_SIGN, uint32_t, \ + nrf_crypto_sign, uint32_t, curve, \ + nrf_crypto_key_t const *, p_sk, \ + nrf_crypto_key_t const *, p_hash, \ + nrf_crypto_key_t *, p_sig); +#endif + +/**@brief Function for verifying the signature of a hash or a digest using a public key. + * + * @param[in] curve Elliptic curve to use (see @ref NRF_CRYPTO_CURVES). + * @param[in] p_pk Public key (see @ref nrf_crypto_key_t). + * @param[in] p_hash Hash or digest to compare to (see @ref nrf_crypto_key_t). + * @param[in] p_sig Signature (see @ref nrf_crypto_key_t). + * + * @retval NRF_SUCCESS If the signature was verified and is valid. + * @retval NRF_ERROR_INVALID_DATA If the signature did not match the provided hash or digest. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected curve is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers is invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the length of the provided public key, hash, or signature is invalid. + */ +#ifdef SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION +uint32_t nrf_crypto_verify(uint32_t curve, nrf_crypto_key_t const *p_pk, nrf_crypto_key_t const *p_hash, nrf_crypto_key_t const *p_sig); +#else +SVCI(NRF_CRYPTO_SVCI_VERIFY, uint32_t, \ + nrf_crypto_verify, uint32_t, curve, \ + nrf_crypto_key_t const *, p_pk, \ + nrf_crypto_key_t const *, p_hash, \ + nrf_crypto_key_t const *, p_sig); +#endif + +/**@brief Function for computing a hash or a digest from arbitrary data. + * + * @param[in] hash_alg Hashing algorithm to use (see @ref NRF_CRYPTO_HASH_ALGS). + * @param[in] p_data Data to be hashed. + * @param[in] len Length of the data to be hashed. + * @param[out] p_hash Hash or digest (see @ref nrf_crypto_key_t). + * + * @retval NRF_SUCCESS If the hash was computed successfully. + * @retval NRF_ERROR_NOT_SUPPORTED If the selected hashing algorithm is not supported. + * @retval NRF_ERROR_INVALID_ADDR If any of the provided pointers is invalid. + * @retval NRF_ERROR_INVALID_LENGTH If the hash is bigger than the size of the provided buffer. + */ +#ifdef SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION +uint32_t nrf_crypto_hash_compute(uint32_t hash_alg, uint8_t const *p_data, uint32_t len, nrf_crypto_key_t *p_hash); + +#else +SVCI(NRF_CRYPTO_SVCI_HASH_COMPUTE, uint32_t, \ + nrf_crypto_hash_compute, uint32_t, hash_alg, \ + uint8_t const *, p_data, \ + uint32_t, len, \ + nrf_crypto_key_t *, p_hash); +#endif + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif // NRF_CRYPTO_H__ + diff --git a/components/libraries/crypto/nrf_crypto_svc.c b/components/libraries/crypto/nrf_crypto_svc.c new file mode 100644 index 0000000..bc66261 --- /dev/null +++ b/components/libraries/crypto/nrf_crypto_svc.c @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_svc_function.h" +#include "nrf_error.h" +#include "sdk_common.h" + +/* use direct calls */ +#define SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION +#include "nrf_crypto.h" + +#ifndef NRF51 + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_init) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_INIT, + .func_ptr = (nrf_svc_func_t)&nrf_crypto_init +}; + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_public_key_compute) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_PUBLIC_KEY_COMPUTE, + .func_ptr = (nrf_svc_func_t)&nrf_crypto_public_key_compute +}; + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_shared_secret_compute) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_SHARED_SECRET_COMPUTE, + .func_ptr = (nrf_svc_func_t)&nrf_crypto_shared_secret_compute +}; + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_sign) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_SIGN, + .func_ptr = (nrf_svc_func_t)&nrf_crypto_sign +}; + +#endif + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_verify) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_VERIFY, + .func_ptr = (nrf_svc_func_t)&nrf_crypto_verify +}; + +SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_hash_compute) = +{ + .svc_num = NRF_SVCI_SVC_NUM, + .svci_num = NRF_CRYPTO_SVCI_HASH_COMPUTE, + .func_ptr = &nrf_crypto_hash_compute +}; diff --git a/components/libraries/csense/nrf_csense.c b/components/libraries/csense/nrf_csense.c new file mode 100644 index 0000000..267a75b --- /dev/null +++ b/components/libraries/csense/nrf_csense.c @@ -0,0 +1,658 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_CSENSE) +#include "nrf_csense.h" +#include "nrf_peripherals.h" +#include "string.h" +#include "nrf_assert.h" + +#if defined(__CORTEX_M) && (__CORTEX_M < 4) +#ifndef ARM_MATH_CM0PLUS +#define ARM_MATH_CM0PLUS +#endif +/*lint -save -e689 */ +#include "arm_math.h" +/*lint -restore */ +#endif + +APP_TIMER_DEF(nrf_csense_timer); + +typedef struct +{ + nrf_csense_event_handler_t event_handler; //!< Event handler for module. + nrf_drv_state_t state; //!< State of module. + uint32_t ticks; //!< Timeout ticks of app_timer instance controlling csense module. + uint16_t raw_analog_values[MAX_ANALOG_INPUTS]; //!< Raw values of measurements. + uint8_t enabled_analog_channels_mask; //!< Mask of enabled channels. +}nrf_csense_t; + +/* Module instance. */ +static nrf_csense_t m_nrf_csense; + +/* First of touch elements instances that creates linked list. */ +static nrf_csense_instance_t * mp_nrf_csense_instance_head; + +/* Buffer for values got from measurements. */ +static uint16_t m_values_buffer[NRF_CSENSE_MAX_PADS_NUMBER]; + +/** + * @brief Function for handling time-outs. + * + * @param[in] p_context General purpose pointer. Will be passed to the time-out handler + * when the timer expires. + */ +static void csense_timer_handler(void * p_context) +{ + if (m_nrf_csense.state != NRF_DRV_STATE_POWERED_ON) + { + return; + } + + if (nrf_drv_csense_sample() == NRF_ERROR_BUSY) + { + return; + } +} + + +/** + * @brief Function for updating maximum or minimum value. + * + * @param [in] p_instance Pointer to csense instance. + * @param [in] p_pad Pointer to pad which should be checked for minimum or maximum value. + */ +__STATIC_INLINE void min_or_max_update(nrf_csense_instance_t const * p_instance, + nrf_csense_pad_t * p_pad) +{ + uint16_t val = m_nrf_csense.raw_analog_values[p_pad->analog_input_number]; + + if (p_instance->min_max[p_pad->pad_index].min_value > val) + { + p_instance->min_max[p_pad->pad_index].min_value = val; + } + + if (p_instance->min_max[p_pad->pad_index].max_value < val) + { + p_instance->min_max[p_pad->pad_index].max_value = val; + } +} + + +/** + * @brief Function for calculating proportions on slider pad. + * + * @note This function help to self calibrate the pads. + * + * @param [in] p_instance Pointer to csense instance. + * @param [in] p_pad Pointer to pad to calculate ratio for. + * + * @return Difference between maximum and minimum values read on pads or 0 if minimum is bigger than maximum. + * + */ +__STATIC_INLINE uint16_t ratio_calculate(nrf_csense_instance_t const * p_instance, + nrf_csense_pad_t * p_pad) +{ + if (p_instance->min_max[p_pad->pad_index].max_value > p_instance->min_max[p_pad->pad_index].min_value) + { + uint16_t scale; + scale = (uint16_t)(p_instance->min_max[p_pad->pad_index].max_value - + p_instance->min_max[p_pad->pad_index].min_value); + return scale; + } + else + { + return 0; + } +} + + +/** + * @brief Function for calculating step. + * + * Function calculates step for slider basing on index of touched pads and values measured on them and neighboring pads. + * + * @param[in] p_instance Pointer to csense instance. + * @param[in] pad_index_1 Index of first pad. + * @param[in] pad_index_1 Index of second pad if 2 were touched. + * + * @return Detected touched step. + */ +static uint16_t calculate_step(nrf_csense_instance_t * p_instance, + uint8_t pad_index) +{ + uint16_t step = 0; + uint32_t values_sum; + uint32_t values_product; + + pad_index += 1; + + values_sum = m_values_buffer[pad_index] + m_values_buffer[pad_index - 1] + + m_values_buffer[pad_index + 1]; + values_product = (uint32_t)(p_instance->steps-1) * + (m_values_buffer[pad_index - 1] * (pad_index - 2) + + m_values_buffer[pad_index] * (pad_index - 1) + + m_values_buffer[pad_index + 1] * (pad_index)); + step = 1 + ROUNDED_DIV(values_product, (values_sum * (p_instance->number_of_pads - 1))); // Add 1 to the result of the division + // to get the appropriate range of values. + memset((void*)m_values_buffer, 0, sizeof(m_values_buffer)); + + return step; +} + + +/** + * @brief Function for finding mask of touched pads. + * + * @param [in] p_instance Pointer to csense instance. + * + * @return Mask of touched pads. + */ +static uint32_t find_touched_mask(nrf_csense_instance_t const * p_instance) +{ + uint32_t touched_mask = 0; + uint16_t max_value = 0; + uint16_t ratio; + nrf_csense_pad_t * p_pad; + + for (p_pad = p_instance->p_nrf_csense_pad; NULL != p_pad; p_pad = p_pad->p_next_pad) // run through all pads and look for those with biggest value + { + min_or_max_update(p_instance, p_pad); + + ratio = ratio_calculate(p_instance, p_pad); + if (ratio == 0) + { + return 0; + } + uint16_t val = + (uint16_t)(((uint32_t)(m_nrf_csense.raw_analog_values[p_pad->analog_input_number] - + p_instance->min_max[p_pad->pad_index].min_value) * + NRF_CSENSE_MAX_VALUE) / ratio); + m_values_buffer[p_pad->pad_index+1] = val; + + if (val > max_value) + { + max_value = val; + touched_mask = (1UL << (p_pad->pad_index)); + } + else if (val == max_value) + { + max_value = val; + touched_mask |= (1UL << (p_pad->pad_index)); + } + } + + return touched_mask; +} + + +/** + * @brief Function for finding touched pad. + * + * If there is more than one pad connected to an analog channel this functions which one was actually touched. This is done by + * comparing values of neighboring pads. + * + * @param [in] instance Pointer to csense instance. + * @param [in] touched_mask Mask of touched pads. + * + * @return Touched pad. + */ +static uint16_t find_touched_pad(nrf_csense_instance_t const * p_instance, + uint32_t touched_mask) +{ + uint8_t i; + uint8_t biggest_deviation = 0; + uint8_t temp_biggest = 0; + uint16_t pad = UINT16_MAX; + static uint16_t previous_pad = 0; + + for (i = 0; i < (p_instance->number_of_pads); i++) + { + if ((1UL << i) & touched_mask) + { + temp_biggest = m_values_buffer[i]; + temp_biggest += m_values_buffer[i + 2]; + + if ((i != 0) && (i != ((p_instance->number_of_pads-1)))) + { + temp_biggest /= 2; + } + + if ((temp_biggest > NRF_CSENSE_PAD_DEVIATION) && + (temp_biggest > biggest_deviation)) + { + biggest_deviation = temp_biggest; + pad = i; + } + } + } + + if (pad == UINT16_MAX) + { + pad = previous_pad; + } + else + { + previous_pad = pad; + } + + return pad; +} + + +/** + * @brief Function for finding touched step. + * + * @param [in] instance Pointer to csense instance. + * + * @return Detected touched step. + */ +static uint16_t find_touched_step(nrf_csense_instance_t * p_instance) +{ + uint32_t touched_mask = 0; + uint16_t pad = 0; + uint16_t step; + + touched_mask = find_touched_mask(p_instance); + + if (touched_mask == 0) + { + return UINT16_MAX; + } + + if ((touched_mask & (-(int32_t)touched_mask)) == touched_mask) // Check if there is only one pad with greatest value. + { + pad = 31 - __CLZ(touched_mask); + } + else + { + pad = find_touched_pad(p_instance, touched_mask); + } + + step = calculate_step(p_instance, pad); + return step; +} + + +/** + * @brief Event handler for csense. + * + * param [in] p_event_struct Pointer to event structure. + */ +static void csense_event_handler(nrf_drv_csense_evt_t * p_event_struct) +{ + nrf_csense_evt_t event; + static uint16_t prev_analog_values[MAX_ANALOG_INPUTS]; + bool touched = false; + nrf_csense_instance_t * instance; + uint8_t i; + + if ((m_nrf_csense.enabled_analog_channels_mask & (1UL << (p_event_struct->analog_channel))) == 0) + { + return; + } + + m_nrf_csense.raw_analog_values[p_event_struct->analog_channel] = p_event_struct->read_value; + + if (nrf_drv_csense_is_busy()) + { + return; + } + + for (instance = mp_nrf_csense_instance_head; instance != NULL; + instance = instance->p_next_instance) // run through all instances + { + if (instance->is_active) + { + event.p_instance = instance; + nrf_csense_pad_t * p_pad = instance->p_nrf_csense_pad; + + for (i = 0; i < MAX_ANALOG_INPUTS; i++) + { + if ((m_nrf_csense.raw_analog_values[i] < + (prev_analog_values[i] - NRF_CSENSE_PAD_HYSTERESIS)) || + (m_nrf_csense.raw_analog_values[i] > + (prev_analog_values[i] + NRF_CSENSE_PAD_HYSTERESIS))) + { + touched = true; + break; + } + } + + if (touched) + { + touched = false; + + for (p_pad = instance->p_nrf_csense_pad; p_pad != NULL; + p_pad = p_pad->p_next_pad) + { + if (m_nrf_csense.raw_analog_values[p_pad->analog_input_number] > + p_pad->threshold) + { + touched = true; + break; + } + } + } + else + { + continue; + } + + // Specify the event + if ((instance->is_touched) && touched) + { + // dragged + if (instance->number_of_pads > 1) + { + event.params.slider.step = find_touched_step(instance); + event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_DRAGGED; + + m_nrf_csense.event_handler(&event); + } + } + else if ((!(instance->is_touched)) && touched) + { + // pressed + if (instance->number_of_pads > 1) + { + event.params.slider.step = find_touched_step(instance); + event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_PRESSED; + } + else + { + event.nrf_csense_evt_type = NRF_CSENSE_BTN_EVT_PRESSED; + } + instance->is_touched = true; + + m_nrf_csense.event_handler(&event); + } + else if ((instance->is_touched) && (!touched)) + { + // released + if (instance->number_of_pads > 1) + { + event.params.slider.step = find_touched_step(instance); + event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_RELEASED; + } + else + { + event.nrf_csense_evt_type = NRF_CSENSE_BTN_EVT_RELEASED; + } + instance->is_touched = false; + + m_nrf_csense.event_handler(&event); + } + else + { + // nothing changed + } + } + + touched = false; + } + + memset(m_values_buffer, 0, sizeof(m_values_buffer)); + memcpy(prev_analog_values, m_nrf_csense.raw_analog_values, + sizeof(m_nrf_csense.raw_analog_values)); +} + + +ret_code_t nrf_csense_init(nrf_csense_event_handler_t event_handler, + uint32_t ticks) +{ + ASSERT(event_handler != NULL); + ASSERT(m_nrf_csense.state == NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + + static const nrf_drv_csense_config_t m_csense_config = + { + .output_pin = NRF_CSENSE_OUTPUT_PIN + }; + + m_nrf_csense.event_handler = event_handler; + m_nrf_csense.ticks = ticks; + mp_nrf_csense_instance_head = NULL; + + err_code = app_timer_create(&nrf_csense_timer, APP_TIMER_MODE_REPEATED, csense_timer_handler); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = nrf_drv_csense_init(&m_csense_config, csense_event_handler); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + m_nrf_csense.state = NRF_DRV_STATE_INITIALIZED; + + return NRF_SUCCESS; +} + + +ret_code_t nrf_csense_uninit(void) +{ + ASSERT(m_nrf_csense.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + nrf_csense_instance_t ** pp_instance = &mp_nrf_csense_instance_head; + + err_code = nrf_drv_csense_uninit(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (m_nrf_csense.enabled_analog_channels_mask != 0) + { + err_code = app_timer_stop(nrf_csense_timer); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + while ((*pp_instance) != NULL) + { + nrf_csense_instance_t ** pp_instance_next = (&(*pp_instance)->p_next_instance); + (*pp_instance) = NULL; + pp_instance = pp_instance_next; + } + + memset((void *)&m_nrf_csense, 0, sizeof(nrf_csense_t)); + + m_nrf_csense.state = NRF_DRV_STATE_UNINITIALIZED; + + + return NRF_SUCCESS; +} + +ret_code_t nrf_csense_add(nrf_csense_instance_t * const p_instance) +{ + ASSERT(m_nrf_csense.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_instance->p_next_instance == NULL); + ASSERT(p_instance != NULL); + + ret_code_t err_code; + + nrf_csense_instance_t ** pp_instance = &mp_nrf_csense_instance_head; + + while ((*pp_instance) != NULL) + { + ASSERT((*pp_instance) != p_instance); + pp_instance = &((*pp_instance)->p_next_instance); + } + + *pp_instance = p_instance; + + err_code = nrf_csense_enable(p_instance); + return err_code; +} + +ret_code_t nrf_csense_enable(nrf_csense_instance_t * const p_instance) +{ + ASSERT(m_nrf_csense.state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_instance != NULL); + + ret_code_t err_code; + nrf_csense_pad_t const * p_pad; + uint8_t analog_channels_mask = 0; + + if (m_nrf_csense.enabled_analog_channels_mask == 0) + { + err_code = app_timer_start(nrf_csense_timer, m_nrf_csense.ticks, NULL); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + p_instance->is_active = true; + + for (p_pad = p_instance->p_nrf_csense_pad; p_pad != NULL; p_pad = p_pad->p_next_pad) + { + p_instance->min_max[p_pad->pad_index].min_value = UINT16_MAX; + + if ((m_nrf_csense.enabled_analog_channels_mask & (1UL << (p_pad->analog_input_number))) == 0) // If channel was already enabled skip it. + { + analog_channels_mask |= (1UL << (p_pad->analog_input_number)); + m_nrf_csense.enabled_analog_channels_mask |= (1UL << (p_pad->analog_input_number)); + } + } + + m_nrf_csense.state = NRF_DRV_STATE_POWERED_ON; + nrf_drv_csense_channels_enable(analog_channels_mask); + + return NRF_SUCCESS; +} + + +ret_code_t nrf_csense_disable(nrf_csense_instance_t * const p_instance) +{ + ASSERT(m_nrf_csense.state == NRF_DRV_STATE_POWERED_ON); + + ret_code_t err_code; + nrf_csense_instance_t * p_instance_temp = mp_nrf_csense_instance_head; + nrf_csense_pad_t const * p_pad; + uint8_t channels_mask = 0; + uint8_t instance_channels_mask = 0; + + for (p_instance_temp = mp_nrf_csense_instance_head; p_instance_temp != NULL; + p_instance_temp = p_instance_temp->p_next_instance) + { + for (p_pad = p_instance_temp->p_nrf_csense_pad; p_pad != NULL; p_pad = p_pad->p_next_pad) + { + if (p_instance_temp == p_instance) + { + instance_channels_mask |= (1UL << (p_pad->analog_input_number)); + p_instance->is_active = false; + } + else + { + channels_mask |= (1UL << (p_pad->analog_input_number)); + } + } + } + + nrf_drv_csense_channels_disable((~channels_mask) & instance_channels_mask); + + m_nrf_csense.enabled_analog_channels_mask = channels_mask; + + if (m_nrf_csense.enabled_analog_channels_mask == 0) + { + err_code = app_timer_stop(nrf_csense_timer); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + m_nrf_csense.state = NRF_DRV_STATE_INITIALIZED; + } + + return NRF_SUCCESS; +} + + +ret_code_t nrf_csense_ticks_set(uint32_t ticks) +{ + ASSERT(m_nrf_csense.state != NRF_DRV_STATE_UNINITIALIZED); + + ret_code_t err_code; + + if (nrf_drv_csense_is_busy()) + { + return NRF_ERROR_BUSY; + } + + m_nrf_csense.ticks = ticks; + + if (m_nrf_csense.state == NRF_DRV_STATE_POWERED_ON) + { + err_code = app_timer_stop(nrf_csense_timer); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = app_timer_start(nrf_csense_timer, ticks, NULL); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +ret_code_t nrf_csense_steps_set(nrf_csense_instance_t * const p_instance, uint16_t steps) +{ + if (p_instance->is_active) + { + return NRF_ERROR_INVALID_STATE; + } + + p_instance->steps = steps; + + return NRF_SUCCESS; +} +#endif //NRF_MODULE_ENABLED(NRF_CSENSE) diff --git a/components/libraries/csense/nrf_csense.h b/components/libraries/csense/nrf_csense.h new file mode 100644 index 0000000..ed72b22 --- /dev/null +++ b/components/libraries/csense/nrf_csense.h @@ -0,0 +1,345 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_CSENSE_H__ +#define NRF_CSENSE_H__ + +#include +#include "nrf.h" +#include "sdk_errors.h" +#include "app_timer.h" +#include "nrf_drv_csense.h" +#include "nrf_csense_macros.h" +#include "app_util.h" + +/** @file + * + * @defgroup nrf_csense Capacitive Sensor Library + * @{ + * @ingroup app_common + * + * @brief Module for using the capacitive sensor library with support for many instances of sliders, wheels, and buttons. + */ + +/** + * @brief Macro for returning the address of a variable. + */ +#define NRF_CSENSE_GET_INSTANCE_ID(instance) (&instance) + +/** + * @brief Statically allocate memory for the instance of a capacitive sensor. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_BUTTON_DEF(name, p1) NRF_CSENSE_INTERNAL_BUTTON_DEF(name, p1) + +/** + * @brief Macro for creating a 2-pads slider instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_SLIDER_2_DEF(name, steps_no, p1, p2) NRF_CSENSE_INTERNAL_SLIDER_2_DEF(name, steps_no, p1, p2) + +/** + * @brief Macro for creating a 3-pads slider instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_SLIDER_3_DEF(name, steps_no, p1, p2, p3) NRF_CSENSE_INTERNAL_SLIDER_3_DEF(name, steps_no, p1, p2, p3) + +/** + * @brief Macro for creating a 4-pads slider instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4) NRF_CSENSE_INTERNAL_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4) + +/** + * @brief Macro for creating a 5-pads slider instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p5 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5) NRF_CSENSE_INTERNAL_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5) + +/** + * @brief Macro for creating a 3-pads wheel instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_WHEEL_3_DEF(name, steps_no, p1, p2, p3) NRF_CSENSE_INTERNAL_WHEEL_3_DEF(name, steps_no, p1, p2, p3) + +/** + * @brief Macro for creating a 4-pads wheel instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4) NRF_CSENSE_INTERNAL_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4) + +/** + * @brief Macro for creating a 5-pads wheel instance. + * + * @param[in,out] name Name of the capacitive sensor instance that will be created. + * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + * @param[in] p5 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold). + */ +#define NRF_CSENSE_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5) NRF_CSENSE_INTERNAL_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5) + +/** + * @cond (NODOX) + * @defgroup nrf_csense_internal Auxiliary internal types declarations + * @brief Module for internal usage inside the library only. + * @details These definitions are available to the user, but they should not + * be accessed directly. Use the API to access them. + * @{ + * + */ + + /* + * @brief Forward declaration of capacitive sensor instance. + */ + typedef struct nrf_csense_instance_s nrf_csense_instance_t; + + /* + * @brief Forward declaration of a capacitive sensor pad. + */ + typedef struct nrf_csense_pad_s nrf_csense_pad_t; + + /** + * @brief Structure with pointer to min and max values measured on pads. + */ + typedef struct + { + uint16_t max_value; //!< Max value measured on pads. + uint16_t min_value; //!< Min value measured on pads. + }nrf_csense_min_max_t; + + /** + * @brief Structure with single instance parameters. This can be either a slider or a button. + */ + struct nrf_csense_instance_s + { + nrf_csense_instance_t * p_next_instance; //!< Pointer to the next instance. + nrf_csense_pad_t * p_nrf_csense_pad; //!< Pointer to the first pad of the module. + nrf_csense_min_max_t * min_max; //!< Structure with pointers to min and max values measured on pads. + uint16_t steps; //!< Number of relative pads. It means that the slider in its handler will give values (1, steps_no). + uint8_t number_of_pads; //!< Number of pads that the instance is using. + bool is_active; //!< Flag to indicate if the instance is active. + bool is_touched; //!< Flag to indicate if the instance is touched. + void * p_context; //!< General purpose pointer. + }; + + /* Structure with single pad parameters used for initialization. */ + struct nrf_csense_pad_s + { + nrf_csense_pad_t * p_next_pad; //!< Pointer to the next pad. + uint16_t threshold; //!< Threshold voltage on pad/time of charging to decide if the pad was touched. + uint8_t pad_index; //!< Index of the pad. + uint8_t analog_input_number; //!< Analog input connected to the pad. + }; + +/** @} + * @endcond + */ + +/** + * @brief Enum for nrf_csense events. + */ +typedef enum +{ + NRF_CSENSE_BTN_EVT_PRESSED, //!< Event for pad pressed. + NRF_CSENSE_BTN_EVT_RELEASED, //!< Event for pad released. + NRF_CSENSE_SLIDER_EVT_PRESSED, //!< Event for pad pressed. + NRF_CSENSE_SLIDER_EVT_RELEASED, //!< Event for pad released. + NRF_CSENSE_SLIDER_EVT_DRAGGED, //!< Event for pad dragged. +}nrf_csense_evt_type_t; + +/** + * @brief Structure with slider event data including the measured step. + */ +typedef struct +{ + uint16_t step; //!< Measured step. +} nrf_csense_slider_evt_t; + +/** + * @brief Event data union for nrf_csense events. + */ +typedef union +{ + nrf_csense_slider_evt_t slider; //!< Structure with slider event data including the measured step. +} nrf_csense_evt_param_t; + +/** + * @brief Structure with event parameters. + */ +typedef struct +{ + nrf_csense_evt_type_t nrf_csense_evt_type; //!< Type of event. + nrf_csense_instance_t * p_instance; //!< Pointer to instance. + nrf_csense_evt_param_t params; //!< Event data union for nrf_csense events. +}nrf_csense_evt_t; + +/** + * @brief Capacitive sensor handler type. + */ +typedef void (* nrf_csense_event_handler_t)(nrf_csense_evt_t * p_evt); + +/** + * @brief Function for setting a handler of the instance. + * + * @param [in] p_instance Pointer to the instance whose steps are going to be changed. + * @param [in] p_context General purpose pointer. Will be passed to the callback function. + */ +__STATIC_INLINE void nrf_csense_instance_context_set(nrf_csense_instance_t * const p_instance, void * p_context) +{ + p_instance->p_context = p_context; +} + +/** + * @brief Function for initializing the module. After initialization, no instances are enabled. + * + * @param [in] event_handler Event handler for the Capacitive Sensor module. + * @param [in] ticks Time in app_timer ticks between next conversions. + * + * @retval NRF_ERROR_INVALID_PARAM If invalid parameter was provided. + * @retval NRF_ERROR_INVALID_STATE If one of the used modules is in invalid state. + * @retval NRF_ERROR_INTERNAL If an error occured while initializing one of the modules used by the capacitive sensor library. + * @retval NRF_SUCCESS If the module was initialized successfully. + */ +ret_code_t nrf_csense_init(nrf_csense_event_handler_t event_handler, uint32_t ticks); + +/** + * @brief Function for uninitializing the module. + * + * @return Values returned by @ref nrf_drv_csense_uninit and @ref app_timer_stop. + */ +ret_code_t nrf_csense_uninit(void); + +/** + * @brief Function for adding an instance of capacitive sensor to a linked list. + * + * The function calls @ref nrf_csense_enable to enable the instance that was added to the linked list. + * + * @param [in] p_instance Pointer to the capacitive sensor instance. It is saved by the module and is used whenever the instance is referred. + * + * @return Values returned by @ref nrf_csense_enable. + */ +ret_code_t nrf_csense_add(nrf_csense_instance_t * const p_instance); + +/** + * @brief Function for enabling a single instance. + * + * @param [in,out] p_instance Pointer to the capacitive sensor instance. It is saved by the module and is used whenever the instance is referred. + * + * @return Values returned by @ref app_timer_start. + */ +ret_code_t nrf_csense_enable(nrf_csense_instance_t * const p_instance); + +/** + * @brief Function for disabling an instance. + * + * @param [in] p_instance Pointer to the instance to be disabled. + * + * @retval NRF_ERROR_INVALID_PARAM If the instance was already disabled. + * @retval NRF_SUCCESS If the instance was disabled successfully. + */ +ret_code_t nrf_csense_disable(nrf_csense_instance_t * const p_instance); + +/** + * @brief Function for setting ticks between next measurements. + * + * @param [in] ticks New time between conversions in app_timer ticks. + * + * @retval NRF_ERROR_BUSY If the capacitive sensor was busy. + * @retval NRF_ERROR_INVALID_PARAM If an invalid parameter was provided. + * @retval NRF_ERROR_INVALID_STATE If app_timer was in invalid state. + * @retval NRF_SUCCESS If ticks were set successfully. + */ +ret_code_t nrf_csense_ticks_set(uint32_t ticks); + +/** + * @brief Function for setting steps of an instance. + * + * Note that you have do disable the instance before you can change its number of steps. + * + * @param [in] p_instance Pointer to the instance whose steps are going to be changed. + * @param [in] steps New steps value. + * + * @retval NRF_ERROR_BUSY If the capacitive sensor was busy. + * @retval NRF_SUCCESS If steps were set successfully. + */ +ret_code_t nrf_csense_steps_set(nrf_csense_instance_t * const p_instance, uint16_t steps); + + +/** @} */ + +#endif //NRF_CSENSE_H__ diff --git a/components/libraries/csense/nrf_csense_macros.h b/components/libraries/csense/nrf_csense_macros.h new file mode 100644 index 0000000..06744c5 --- /dev/null +++ b/components/libraries/csense/nrf_csense_macros.h @@ -0,0 +1,360 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_CSENSE_MACROS_H__ +#define NRF_CSENSE_MACROS_H__ + +/** @file + * + * @defgroup nrf_csense_macros Capacitive Sensor + * @{ + * @ingroup nrf_csense + * + * @brief A set of macros to facilitate creation of a new capacitive sensor instance. + */ + +#define NRF_CSENSE_INTERNAL_BUTTON_DEF(name, p1) \ + static nrf_csense_pad_t CONCAT_2(name, _pad) = \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }; \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax); \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = &CONCAT_2(name, _pad), \ + .min_max = &CONCAT_2(name, _minmax), \ + .steps = 1, \ + .number_of_pads = 1, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_SLIDER_2_DEF(name, steps_no, p1, p2) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[2] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[2]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 2, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_SLIDER_3_DEF(name, steps_no, p1, p2, p3) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[3] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[3]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 3, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[4] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[3], \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p4, \ + .pad_index = 3, \ + .analog_input_number = GET_ARG_1 p4 \ + } \ + }; \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[4]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 4, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[5] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[3], \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[4], \ + .threshold = GET_ARG_2 p4, \ + .pad_index = 3, \ + .analog_input_number = GET_ARG_1 p4 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p5, \ + .pad_index = 4, \ + .analog_input_number = GET_ARG_1 p5 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[5]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 5, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_WHEEL_3_DEF(name, steps_no, p1, p2, p3) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[4] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[3], \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 3, \ + .analog_input_number = GET_ARG_1 p1 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[4]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 4, \ + .is_active = false, \ + .is_touched = false \ + }; + + +#define NRF_CSENSE_INTERNAL_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4) \ + static nrf_csense_pad_t CONCAT_2(name, _pad)[5] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[3], \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[4], \ + .threshold = GET_ARG_2 p4, \ + .pad_index = 3, \ + .analog_input_number = GET_ARG_1 p4 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 4, \ + .analog_input_number = GET_ARG_1 p1 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[5]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 5, \ + .is_active = false, \ + .is_touched = false \ + }; + +#define NRF_CSENSE_INTERNAL_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5)\ + static nrf_csense_pad_t CONCAT_2(name, _pad)[6] = \ + { \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[1], \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 0, \ + .analog_input_number = GET_ARG_1 p1 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[2], \ + .threshold = GET_ARG_2 p2, \ + .pad_index = 1, \ + .analog_input_number = GET_ARG_1 p2 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[3], \ + .threshold = GET_ARG_2 p3, \ + .pad_index = 2, \ + .analog_input_number = GET_ARG_1 p3 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[4], \ + .threshold = GET_ARG_2 p4, \ + .pad_index = 3, \ + .analog_input_number = GET_ARG_1 p4 \ + }, \ + { \ + .p_next_pad = &CONCAT_2(name, _pad)[5], \ + .threshold = GET_ARG_2 p5, \ + .pad_index = 4, \ + .analog_input_number = GET_ARG_1 p5 \ + }, \ + { \ + .p_next_pad = NULL, \ + .threshold = GET_ARG_2 p1, \ + .pad_index = 5, \ + .analog_input_number = GET_ARG_1 p1 \ + } \ + }; \ + \ + static nrf_csense_min_max_t CONCAT_2(name, _minmax)[6]; \ + static nrf_csense_instance_t name = \ + { \ + .p_nrf_csense_pad = CONCAT_2(name, _pad), \ + .min_max = CONCAT_2(name, _minmax), \ + .steps = steps_no, \ + .number_of_pads = 6, \ + .is_active = false, \ + .is_touched = false \ + }; + +/** @} */ + +#endif // NRF_CSENSE_MACROS_H__ diff --git a/components/libraries/csense_drv/nrf_drv_csense.c b/components/libraries/csense_drv/nrf_drv_csense.c new file mode 100644 index 0000000..93447cc --- /dev/null +++ b/components/libraries/csense_drv/nrf_drv_csense.c @@ -0,0 +1,537 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_DRV_CSENSE) +#include "nrf_drv_csense.h" +#include "nrf_peripherals.h" +#include "nrf_gpio.h" +#include "app_error.h" +#include "app_util_platform.h" +#include "nrf_assert.h" +#include "string.h" +#include + +#if defined(__CORTEX_M) && (__CORTEX_M < 4) +#ifndef ARM_MATH_CM0PLUS +#define ARM_MATH_CM0PLUS +#endif +/*lint -save -e689 */ +#include "arm_math.h" +/*lint -restore */ +#endif + +#ifdef COMP_PRESENT +#include "nrf_drv_comp.h" +#include "nrf_drv_ppi.h" +#include "nrf_drv_timer.h" +#endif //COMP_PRESENT + +#ifndef COMP_PRESENT +#include "nrf_drv_adc.h" + +/** + * @defgroup adc_defines ADC defines to count input voltage. + * @{ + */ +#define ADC_RES_10BIT 1024 +#define ADC_INPUT_PRESCALER 3 +#define ADC_REF_VBG_VOLTAGE 1.2 +/* @} */ + +/* ADC channel used to call conversion. */ +static nrf_drv_adc_channel_t adc_channel = NRF_DRV_ADC_DEFAULT_CHANNEL(0); +#endif //COMP_PRESENT + +#ifdef COMP_PRESENT +/* Number of channels required by PPI. */ +#define PPI_REQUIRED_CHANNELS 3 + +/* Array of PPI channels. */ +static nrf_ppi_channel_t m_ppi_channels[PPI_REQUIRED_CHANNELS]; + + +/** + * @defgroup timer_instances Timer instances. + * @{ + */ +static const nrf_drv_timer_t m_timer0 = NRF_DRV_TIMER_INSTANCE(TIMER0_FOR_CSENSE); +static const nrf_drv_timer_t m_timer1 = NRF_DRV_TIMER_INSTANCE(TIMER1_FOR_CSENSE); +/* @} */ +#endif //COMP_PRESENT + +/* Configuration of the capacitive sensor module. */ +typedef struct +{ + volatile nrf_drv_state_t module_state; /**< State of the module. */ + nrf_drv_csense_event_handler_t event_handler; /**< Event handler for capacitor sensor events. */ + uint16_t analog_values[MAX_ANALOG_INPUTS]; /**< Array containing analog values measured on the corresponding COMP/ADC channel. */ + volatile bool busy; /**< Indicates state of module - busy if there are ongoing conversions. */ + volatile uint8_t cur_chann_idx; /**< Current channel to be read if enabled. */ + volatile uint8_t adc_channels_input_mask; /**< Enabled channels. */ + uint8_t output_pin; /**< Pin to generate signal charging capacitors. */ + uint8_t channels_to_read; /**< Mask of channels remaining to be read in the current measurement. */ + volatile bool timers_powered_on; /**< Flag to indicate if timers were already started. */ +}csense_t; + +static csense_t m_csense; + +/** + * @brief Function for determining the next analog channel to be read. + */ +__STATIC_INLINE void calculate_next_channel(void) +{ + m_csense.cur_chann_idx = 31 - __CLZ(m_csense.channels_to_read); +} + +/** + * @brief Function for handling conversion values. + * + * @param[in] val Value received from ADC or COMP. + */ +static void conversion_handler(uint16_t val) +{ + nrf_drv_csense_evt_t event_struct; + +#ifndef COMP_PRESENT + nrf_gpio_pin_set(m_csense.output_pin); +#endif //COMP_PRESENT + + m_csense.analog_values[m_csense.cur_chann_idx] = val; + + event_struct.read_value = val; + event_struct.analog_channel = m_csense.cur_chann_idx; + + m_csense.channels_to_read &= ~(1UL< 0) // Start new conversion. + { + ret_code_t err_code; + calculate_next_channel(); + err_code = nrf_drv_csense_sample(); + if(err_code != NRF_SUCCESS) + { + return; + } + } +} + +#ifdef COMP_PRESENT +/** + * @brief Timer0 interrupt handler. + * + * @param[in] event_type Timer event. + * @param[in] p_context General purpose parameter set during initialization of + * the timer. This parameter can be used to pass + * additional information to the handler function, for + * example, the timer ID. + */ +static void counter_compare_handler(nrf_timer_event_t event_type, void* p_context) +{ + if(event_type == NRF_TIMER_EVENT_COMPARE0) + { + uint16_t val = nrf_drv_timer_capture_get(&m_timer1, NRF_TIMER_CC_CHANNEL1); + nrf_drv_timer_pause(&m_timer1); + nrf_drv_timer_clear(&m_timer1); + + /* Handle finished measurement. */ + conversion_handler(val); + } +} + +/** + * @brief Dummy handler. + * + * @param[in] event_type Timer event. + * @param[in] p_context General purpose parameter set during initialization of + * the timer. This parameter can be used to pass + * additional information to the handler function, for + * example, the timer ID. + */ +static void dummy_handler(nrf_timer_event_t event_type, void* p_context){} + +/** + * @brief Function for initializing timers. + * + * @retval NRF_ERROR_INTERNAL If there were error initializing timers. + * @retval NRF_SUCCESS If timers were initialized successfully. + */ +static ret_code_t timer_init(void) +{ + ret_code_t err_code; + + //set first timer in timer mode to get period of relaxation oscillator + nrf_drv_timer_config_t timer_config = NRF_DRV_TIMER_DEFAULT_CONFIG; + timer_config.mode = NRF_TIMER_MODE_TIMER; + err_code = nrf_drv_timer_init(&m_timer1, &timer_config, dummy_handler); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + //set second timer in counter mode and generate event on tenth period + timer_config.mode = NRF_TIMER_MODE_COUNTER; + err_code = nrf_drv_timer_init(&m_timer0, &timer_config, counter_compare_handler); + if (err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + nrf_drv_timer_extended_compare(&m_timer0, NRF_TIMER_CC_CHANNEL0, MEASUREMENT_PERIOD, (nrf_timer_short_mask_t)(NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK | NRF_TIMER_SHORT_COMPARE0_STOP_MASK), true); + + return NRF_SUCCESS; +} + +/** + * @brief Function for initializing and enabling PPI channels. + * + * @retval NRF_ERROR_INTERNAL If there were error initializing or enabling PPI channels. + * @retval NRF_SUCCESS If PPI channels were initialized and enabled successfully. + */ +static ret_code_t ppi_init(void) +{ + ret_code_t err_code; + uint8_t i; + + err_code = nrf_drv_ppi_init(); + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED)) + { + return NRF_ERROR_INTERNAL; + } + + for(i = 0; i < PPI_REQUIRED_CHANNELS ; i++) + { + err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channels[i]); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + } + + err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[0], nrf_drv_comp_event_address_get(NRF_COMP_EVENT_CROSS), nrf_drv_timer_task_address_get(&m_timer0, NRF_TIMER_TASK_COUNT)); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[1], nrf_drv_timer_event_address_get(&m_timer0, NRF_TIMER_EVENT_COMPARE0), nrf_drv_timer_task_address_get(&m_timer1, NRF_TIMER_TASK_CAPTURE1)); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + err_code = nrf_drv_ppi_channel_fork_assign(m_ppi_channels[1], nrf_drv_comp_task_address_get(NRF_COMP_TASK_STOP)); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[2], nrf_drv_comp_event_address_get(NRF_COMP_EVENT_READY), nrf_drv_timer_task_address_get(&m_timer0, NRF_TIMER_TASK_CLEAR)); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + err_code = nrf_drv_ppi_channel_fork_assign(m_ppi_channels[2], nrf_drv_timer_task_address_get(&m_timer1, NRF_TIMER_TASK_CLEAR)); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + + for(i = 0; i < PPI_REQUIRED_CHANNELS ; i++) + { + err_code = nrf_drv_ppi_channel_enable(m_ppi_channels[i]); + if (NRF_SUCCESS != err_code) + { + return NRF_ERROR_INTERNAL; + } + } + + return NRF_SUCCESS; +} + +/** + * @brief Dummy handler for COMP events. + * + * @param[in] event COMP event. + */ +static void comp_event_handler(nrf_comp_event_t event){} + +/** + * @brief Function for initializing COMP module in relaxation oscillator mode. + * + * @note The frequency of the oscillator depends on threshold voltages, current source and capacitance of pad and can be calculated as f_OSC = I_SOURCE / (2C·(VUP-VDOWN) ). + * + * @retval NRF_ERROR_INTERNAL If there were error while initializing COMP driver. + * @retval NRF_SUCCESS If the COMP driver initialization was successful. + */ +static ret_code_t comp_init(void) +{ + ret_code_t err_code; + nrf_drv_comp_config_t m_comp_config = NRF_DRV_COMP_DEFAULT_CONFIG(NRF_COMP_INPUT_0); + + /* Workaround for Errata 12 "COMP: Reference ladder is not correctly calibrated" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + *(volatile uint32_t *)0x40013540 = (*(volatile uint32_t *)0x10000324 & 0x00001F00) >> 8; + + m_comp_config.isource = NRF_COMP_ISOURCE_Ien10uA; + + err_code = nrf_drv_comp_init(&m_comp_config, comp_event_handler); + if(err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + return NRF_SUCCESS; +} +#endif //COMP_PRESENT + +#ifndef COMP_PRESENT +/** + * @brief ADC handler. + * + * @param[in] p_event Pointer to analog-to-digital converter driver event. + */ +void adc_handler(nrf_drv_adc_evt_t const * p_event) +{ + nrf_gpio_pin_set(m_csense.output_pin); + uint16_t val; + val = (uint16_t)(p_event->data.sample.sample*ADC_REF_VBG_VOLTAGE*1000*ADC_INPUT_PRESCALER/ADC_RES_10BIT); + conversion_handler(val); +} + +/** + * @brief Function for initializing ADC. + */ +static ret_code_t adc_init(void) +{ + ret_code_t err_code; + + adc_channel.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD; + + nrf_drv_adc_config_t adc_config = NRF_DRV_ADC_DEFAULT_CONFIG; + err_code = nrf_drv_adc_init(&adc_config, adc_handler); + if(err_code != NRF_SUCCESS) + { + return NRF_ERROR_INTERNAL; + } + + nrf_gpio_pin_set(m_csense.output_pin); + + return NRF_SUCCESS; +} +#endif //COMP_PRESENT + +ret_code_t nrf_drv_csense_init(nrf_drv_csense_config_t const * p_config, nrf_drv_csense_event_handler_t event_handler) +{ + ASSERT(m_csense.module_state == NRF_DRV_STATE_UNINITIALIZED); + ASSERT(p_config->output_pin <= NUMBER_OF_PINS); + + ret_code_t err_code; + + if(p_config == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + if(event_handler == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + +#ifndef COMP_PRESENT + m_csense.output_pin = p_config->output_pin; + nrf_gpio_cfg_output(m_csense.output_pin); + nrf_gpio_pin_set(m_csense.output_pin); +#endif //COMP_PRESENT + + m_csense.event_handler = event_handler; + +#ifndef COMP_PRESENT + err_code = adc_init(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } +#else + err_code = comp_init(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } + err_code = timer_init(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } + err_code = ppi_init(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } +#endif //COMP_PRESENT + + m_csense.module_state = NRF_DRV_STATE_INITIALIZED; + + return NRF_SUCCESS; +} + +ret_code_t nrf_drv_csense_uninit(void) +{ + ASSERT(m_csense.module_state != NRF_DRV_STATE_UNINITIALIZED); + + nrf_drv_csense_channels_disable(0xFF); + +#ifndef COMP_PRESENT + nrf_drv_adc_uninit(); +#else + ret_code_t err_code; + uint8_t i; + + nrf_drv_timer_uninit(&m_timer0); + nrf_drv_timer_uninit(&m_timer1); + nrf_drv_comp_uninit(); + for(i =0; i < 3; i++) + { + err_code = nrf_drv_ppi_channel_free(m_ppi_channels[i]); + if(err_code != NRF_SUCCESS) + { + return err_code; + } + } + err_code = nrf_drv_ppi_uninit(); + if(err_code != NRF_SUCCESS) + { + return err_code; + } +#endif //COMP_PRESENT + + m_csense.module_state = NRF_DRV_STATE_UNINITIALIZED; + + memset((void*)&m_csense, 0, sizeof(m_csense)); + + return NRF_SUCCESS; +} + +void nrf_drv_csense_channels_enable(uint8_t channels_mask) +{ + ASSERT(m_csense.module_state != NRF_DRV_STATE_UNINITIALIZED); + + m_csense.busy = true; + + m_csense.module_state = NRF_DRV_STATE_POWERED_ON; + + m_csense.adc_channels_input_mask |= channels_mask; + + m_csense.busy = false; +} + +void nrf_drv_csense_channels_disable(uint8_t channels_mask) +{ + ASSERT(m_csense.module_state == NRF_DRV_STATE_POWERED_ON); + + m_csense.adc_channels_input_mask &= ~channels_mask; + + if(m_csense.adc_channels_input_mask == 0) + { + m_csense.module_state = NRF_DRV_STATE_INITIALIZED; + } +} + +uint16_t nrf_drv_csense_channel_read(uint8_t csense_channel) +{ + return m_csense.analog_values[csense_channel]; +} + +ret_code_t nrf_drv_csense_sample(void) +{ + ASSERT(m_csense.module_state == NRF_DRV_STATE_POWERED_ON); + + if(m_csense.adc_channels_input_mask != 0) + { + if(m_csense.channels_to_read == 0) + { + if(nrf_drv_csense_is_busy() == true) + { + return NRF_ERROR_BUSY; + } + m_csense.busy = true; + m_csense.channels_to_read = m_csense.adc_channels_input_mask; + calculate_next_channel(); + } + +#ifndef COMP_PRESENT + ret_code_t err_code; + + adc_channel.config.config.ain = (nrf_adc_config_input_t)(1< +#include "sdk_errors.h" +#include "app_timer.h" +#include "nrf_drv_common.h" + +/** @file + * + * @defgroup nrf_drv_csense Capacitive sensor support + * @{ + * @ingroup app_common + * + * @brief Module for using a capacitive sensor on low-energy level. + */ + +/** @brief Maximum number of analog inputs. */ +#define MAX_ANALOG_INPUTS 8 + +/** + * @brief Module initializing structure. + */ +typedef struct +{ + uint8_t output_pin; /**< Pin where to generate a voltage for charging capacitors. */ +}nrf_drv_csense_config_t; + +/** + * @brief Structure holding event parameters. + */ +typedef struct +{ + uint16_t read_value; /**< Value which was read on analog channel. It is voltage in millivolts for NRF51 or time in ticks of 10 periods of relaxation + oscillator for NRF52. Voltage corresponds to capacitance of pad attached to analog channel and gets bigger once it + is touched. Period of relaxation also corresponds to pad capacitance and increases its value when capacitance getting + bigger. */ + uint8_t analog_channel; /**< Index of analog channel from which value was read. */ +}nrf_drv_csense_evt_t; + +/** + * @brief Csense events handler. Called from conversion handler. + * + * @param[in] event_struct Structure holding event parameters. + */ +typedef void (* nrf_drv_csense_event_handler_t) (nrf_drv_csense_evt_t * p_event_struct); + +/** + * @brief Function for initializing the module. + * + * After calling function module is in initialized state and all channels are disabled, @ref nrf_drv_csense_channels_enable + * function needs to be called. Initializes all modules needed by capacitive sensor library: ADC for NRF51 or TIMERs, PPIs and COMP for NRF52. + * + * @param[in] p_config Structure for initializing module. + * @param[in] event_handler Event handler for capacitor sensor events. + * + * @retval NRF_ERROR_INVALID_PARAM Invalid parameter. + * @retval NRF_ERROR_NO_MEM Timer operations queue was full. + * @retval NRF_ERROR_INTERNAL Error occurred during timers, PPI's or COMP initialization. + * @retval NRF_SUCCESS Module was initialized successfully. + * + * @sa nrf_drv_csense_channels_enable + */ +ret_code_t nrf_drv_csense_init(nrf_drv_csense_config_t const * p_config, nrf_drv_csense_event_handler_t event_handler); + +/** + * @brief Function for unintializing the capacitive sensor. Clears mask of enabled channels. + * + * @return Values returned by @ref nrf_drv_ppi_channel_free. + */ +ret_code_t nrf_drv_csense_uninit(void); + +/** + * @brief Function for enabling analog channels for the capacitive sensor. + * + * @param[in] channels_mask Mask of analog channels to be enabled. + */ +void nrf_drv_csense_channels_enable(uint8_t channels_mask); + +/** + * @brief Function for disabling analog channels of the capacitive sensor. + * + * @param[in] channels_mask Mask of analog channels to be enabled. + */ +void nrf_drv_csense_channels_disable(uint8_t channels_mask); + +/** + * @brief Function for getting last read value from an analog channel. + * + * @param[in] csense_channel Number of the channel to get value from. + * + * @return Analog value measured on the channel. + */ +uint16_t nrf_drv_csense_channel_read(uint8_t csense_channel); + +/** + * @brief Function for triggering a measurement on all enabled analog channels. Handler will be called on every completed measurement. + * + * @retval NRF_ERROR_BUSY If module was busy or ADC module is in use and was busy. + * @retval NRF_SUCCESS If measurement was triggered successfully. + */ +ret_code_t nrf_drv_csense_sample(void); + +/** + * @brief Function for checking if module is busy. + * + * @return True if busy or false if not busy. + */ +bool nrf_drv_csense_is_busy(void); + +/** @} */ + +#endif //NRF_DRV_CSENSE_H__ diff --git a/components/libraries/ecc/ecc.c b/components/libraries/ecc/ecc.c new file mode 100644 index 0000000..c42cbf4 --- /dev/null +++ b/components/libraries/ecc/ecc.c @@ -0,0 +1,207 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @brief Elliptic Curve Cryptography Interface + * + */ + +#include +#include +#include +#include "nordic_common.h" +#include "app_timer.h" +#include "app_util.h" +#include "nrf_log.h" +#include "nrf_drv_rng.h" +#include "ecc.h" + +#include "uECC.h" + + +static int ecc_rng(uint8_t *dest, unsigned size) +{ + nrf_drv_rng_block_rand(dest, (uint32_t) size); + return 1; +} + +void ecc_init(bool rng) +{ + if(rng) + { + uECC_set_rng(ecc_rng); + } +} + +ret_code_t ecc_p256_keypair_gen(uint8_t *p_le_sk, uint8_t *p_le_pk) +{ + const struct uECC_Curve_t * p_curve; + + if (!p_le_sk || !p_le_pk) + { + return NRF_ERROR_NULL; + } + + if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk)) + { + return NRF_ERROR_INVALID_ADDR; + } + + p_curve = uECC_secp256r1(); + + int ret = uECC_make_key((uint8_t *) p_le_pk, (uint8_t *) p_le_sk, p_curve); + if (!ret) + { + return NRF_ERROR_INTERNAL; + } + + return NRF_SUCCESS; +} + +ret_code_t ecc_p256_public_key_compute(uint8_t const *p_le_sk, uint8_t *p_le_pk) +{ + const struct uECC_Curve_t * p_curve; + + if (!p_le_sk || !p_le_pk) + { + return NRF_ERROR_NULL; + } + + if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk)) + { + return NRF_ERROR_INVALID_ADDR; + } + + p_curve = uECC_secp256r1(); + + //NRF_LOG_INFO("uECC_compute_public_key\r\n"); + int ret = uECC_compute_public_key((uint8_t *) p_le_sk, (uint8_t *) p_le_pk, p_curve); + if (!ret) + { + return NRF_ERROR_INTERNAL; + } + + //NRF_LOG_INFO("uECC_compute_public_key complete: %d\r\n", ret); + return NRF_SUCCESS; +} + +ret_code_t ecc_p256_shared_secret_compute(uint8_t const *p_le_sk, uint8_t const *p_le_pk, uint8_t *p_le_ss) +{ + const struct uECC_Curve_t * p_curve; + + if (!p_le_sk || !p_le_pk || !p_le_ss) + { + return NRF_ERROR_NULL; + } + + if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk) || !is_word_aligned(p_le_ss)) + { + return NRF_ERROR_INVALID_ADDR; + } + + p_curve = uECC_secp256r1(); + + //NRF_LOG_INFO("uECC_shared_secret\r\n"); + int ret = uECC_shared_secret((uint8_t *) p_le_pk, (uint8_t *) p_le_sk, p_le_ss, p_curve); + if (!ret) + { + return NRF_ERROR_INTERNAL; + } + + //NRF_LOG_INFO("uECC_shared_secret complete: %d\r\n", ret); + return NRF_SUCCESS; +} + +ret_code_t ecc_p256_sign(uint8_t const *p_le_sk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t *p_le_sig) +{ + const struct uECC_Curve_t * p_curve; + + if (!p_le_sk || !p_le_hash || !p_le_sig) + { + return NRF_ERROR_NULL; + } + + if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_hash) || !is_word_aligned(p_le_sig)) + { + return NRF_ERROR_INVALID_ADDR; + } + + p_curve = uECC_secp256r1(); + + //NRF_LOG_INFO("uECC_sign\r\n"); + int ret = uECC_sign((const uint8_t *) p_le_sk, (const uint8_t *) p_le_hash, (unsigned) hlen, (uint8_t *) p_le_sig, p_curve); + if (!ret) + { + return NRF_ERROR_INTERNAL; + } + + //NRF_LOG_INFO("uECC_sign complete: %d\r\n", ret); + return NRF_SUCCESS; +} + +ret_code_t ecc_p256_verify(uint8_t const *p_le_pk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t const *p_le_sig) +{ + const struct uECC_Curve_t * p_curve; + + if (!p_le_pk || !p_le_hash || !p_le_sig) + { + return NRF_ERROR_NULL; + } + + if (!is_word_aligned(p_le_pk) || !is_word_aligned(p_le_hash) || !is_word_aligned(p_le_sig)) + { + return NRF_ERROR_INVALID_ADDR; + } + + p_curve = uECC_secp256r1(); + + //NRF_LOG_INFO("uECC_verify\r\n"); + int ret = uECC_verify((const uint8_t *) p_le_pk, (const uint8_t *) p_le_hash, (unsigned) hlen, (uint8_t *) p_le_sig, p_curve); + if (!ret) + { + return NRF_ERROR_INVALID_DATA; + } + + //NRF_LOG_INFO("uECC_verify complete: %d\r\n", ret); + return NRF_SUCCESS; + +} + + diff --git a/components/libraries/ecc/ecc.h b/components/libraries/ecc/ecc.h new file mode 100644 index 0000000..5b149d8 --- /dev/null +++ b/components/libraries/ecc/ecc.h @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @defgroup ecc Elliptic Curve Cryptography interface + * @{ + * @ingroup app_common + * @brief Elliptic Curve Cryptography interface + */ + +#ifndef ECC_H__ +#define ECC_H__ + +#include +#include "nordic_common.h" +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ECC_P256_SK_LEN 32 +#define ECC_P256_PK_LEN 64 + +/**@brief Initialize the ECC module. + * + * @param[in] rng Use a random number generator. + * + * */ +void ecc_init(bool rng); + +/**@brief Create a public/private key pair. + * + * @param[out] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary. + * @param[out] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary. + * + * @retval NRF_SUCCESS Key pair successfuly created. + * @retval NRF_ERROR_NULL NULL pointer provided. + * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided. + * @retval NRF_ERROR_INTERNAL Internal error during key generation. + */ +ret_code_t ecc_p256_keypair_gen(uint8_t *p_le_sk, uint8_t* p_le_pk); + +/**@brief Create a public key from a provided private key. + * + * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary. + * @param[out] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary. + * + * @retval NRF_SUCCESS Public key successfuly created. + * @retval NRF_ERROR_NULL NULL pointer provided. + * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided. + * @retval NRF_ERROR_INTERNAL Internal error during key generation. + */ +ret_code_t ecc_p256_public_key_compute(uint8_t const *p_le_sk, uint8_t* p_le_pk); + +/**@brief Create a shared secret from a provided public/private key pair. + * + * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary. + * @param[in] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary. + * @param[out] p_le_ss Shared secret. Pointer must be aligned to a 4-byte boundary. + * + * @retval NRF_SUCCESS Shared secret successfuly created. + * @retval NRF_ERROR_NULL NULL pointer provided. + * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided. + * @retval NRF_ERROR_INTERNAL Internal error during key generation. + */ +ret_code_t ecc_p256_shared_secret_compute(uint8_t const *p_le_sk, uint8_t const * p_le_pk, uint8_t *p_le_ss); + +/**@brief Sign a hash or digest using a private key. + * + * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary. + * @param[in] p_le_hash Hash. Pointer must be aligned to a 4-byte boundary. + * @param[in] hlen Hash length in bytes. + * @param[out] p_le_sig Signature. Pointer must be aligned to a 4-byte boundary. + * + * @retval NRF_SUCCESS Signature successfuly created. + * @retval NRF_ERROR_NULL NULL pointer provided. + * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided. + * @retval NRF_ERROR_INTERNAL Internal error during signature generation. + */ +ret_code_t ecc_p256_sign(uint8_t const *p_le_sk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t *p_le_sig); + +/**@brief Verify a signature using a public key. + * + * @param[in] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary. + * @param[in] p_le_hash Hash. Pointer must be aligned to a 4-byte boundary. + * @param[in] hlen Hash length in bytes. + * @param[in] p_le_sig Signature. Pointer must be aligned to a 4-byte boundary. + * + * @retval NRF_SUCCESS Signature verified. + * @retval NRF_ERROR_INVALID_DATA Signature failed verification. + * @retval NRF_ERROR_NULL NULL pointer provided. + * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided. + * @retval NRF_ERROR_INTERNAL Internal error during signature verification. + */ +ret_code_t ecc_p256_verify(uint8_t const *p_le_pk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t const *p_le_sig); + + +#ifdef __cplusplus +} +#endif + +#endif // ECC_H__ + +/** @} */ diff --git a/components/libraries/eddystone/es.h b/components/libraries/eddystone/es.h new file mode 100644 index 0000000..47086b9 --- /dev/null +++ b/components/libraries/eddystone/es.h @@ -0,0 +1,199 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_H__ +#define ES_H__ + +#include +#include "app_util_platform.h" + +/** + * @file + * + * @defgroup eddystone_types Frame types and data formats + * @brief Definitions specific to Eddystone frame types and data formats. + * @ingroup eddystone + * @{ + */ + +/** @brief Swap 2 bytes. + */ +#define BYTES_SWAP_16BIT(x) (x << 8 | x >> 8) + +/** @brief Reverse 4 bytes. + */ +#define BYTES_REVERSE_32BIT(x) \ + ((x << 24 | ((x << 8) & 0x00FF0000)) | (((x >> 8) & 0x0000FF00) | x >> 24)) + +/** @brief Check if the error code is equal to NRF_SUCCESS. If it is not, return the error code. + */ +#define RETURN_IF_ERROR(PARAM) \ + if ((PARAM) != NRF_SUCCESS) \ + { \ + return (PARAM); \ + } + +#define ES_UUID 0xFEAA //!< UUID for Eddystone beacons according to specification. + +#define ES_UID_FRAME_TYPE 0x00 //!< UID frame type (fixed at 0x00). +#define ES_UID_RFU 0x00, 0x00 //!< Reserved for future use according to specification. + +#define ES_URL_FRAME_TYPE 0x10 //!< URL frame type (fixed at 0x10). +#define ES_URL_SCHEME 0x00 //!< URL prefix scheme according to specification (0x00 = "http://www"). + +#define ES_TLM_FRAME_TYPE 0x20 //!< TLM frame type (fixed at 0x20). +#define ES_EID_FRAME_TYPE 0x30 //!< EID frame type (fixed at 0x30). + +#define ES_FRAME_TYPE_LENGTH (1) //!< Length of a frame type field. + +#define ES_UID_LENGTH (20) //!< Length of a UID frame. +#define ES_UID_NAMESPACE_LENGTH (10) //!< Length of a UID frame namespace field. +#define ES_UID_INSTANCE_LENGTH (6) //!< Length of a UID frame instance field. +#define ES_UID_RFU_LENGTH (2) //!< Length of a UID frame RFU field. + +#define ES_URL_LENGTH (20) //!< Length of a URL frame. +#define ES_URL_URL_SCHEME_LENGTH (1) //!< Length of a URL frame URL scheme field. +#define ES_URL_ENCODED_URL_LENGTH (17) //!< Maximum length of a URL frame encoded URL field. + +#define ES_TLM_LENGTH (14) //!< Length of a TLM frame. +#define ES_TLM_VBATT_LENGTH (2) //!< Length of a TLM frame VBATT field. +#define ES_TLM_TEMP_LENGTH (2) //!< Length of a TLM frame TEMP field. +#define ES_TLM_ADV_CNT_LENGTH (4) //!< Length of a TLM frame ADV count field. +#define ES_TLM_SEC_CNT_LENGTH (4) //!< Length of a TLM frame seconds field. + +#define ES_EID_LENGTH (10) //!< Length of an EID frame. +#define ES_EID_ID_LENGTH (8) //!< Length of an EID frame ephemeral ID field. +#define ES_EID_GATTS_READ_LENGTH (14) +#define ES_EID_GATTS_READ_FRAME_TYPE_IDX (0) +#define ES_EID_GATTS_READ_EXPONENT_IDX (1) +#define ES_EID_GATTS_READ_CLCK_VALUE_IDX (2) +#define ES_EID_GATTS_READ_EID_IDX (6) + +#define ES_ETLM_LENGTH (18) //!< Length of an eTLM frame. +#define ES_ETLM_ECRYPTED_LENGTH (ES_TLM_VBATT_LENGTH + \ + ES_TLM_TEMP_LENGTH + \ + ES_TLM_ADV_CNT_LENGTH + \ + ES_TLM_SEC_CNT_LENGTH) //!< Length of an eTLM frame encrypted TLM field. + +#define ES_ETLM_RFU (0x00) //!< eTLM frame RFU field value. +#define ES_SPEC_VERSION_BYTE (0x00) //!< eTLM frame specification version field value. + +/** @brief Eddystone frame type values. These values are advertised as frame types. */ +typedef enum +{ + ES_FRAME_TYPE_UID = ES_UID_FRAME_TYPE, /**< UID frame type. */ + ES_FRAME_TYPE_URL = ES_URL_FRAME_TYPE, /**< URL frame type. */ + ES_FRAME_TYPE_TLM = ES_TLM_FRAME_TYPE, /**< TLM frame type. */ + ES_FRAME_TYPE_EID = ES_EID_FRAME_TYPE /**< EID frame type. */ +} es_frame_type_t; + +/** @brief TLM version values. */ +typedef enum +{ + ES_TLM_VERSION_TLM = 0x00, /**< TLM. */ + ES_TLM_VERSION_ETLM = 0x01 /**< Encrypted TLM (eTLM). */ +} es_tlm_version_t; + +/** @brief UID frame data representation. + * @note This is a packed structure. Therefore, you should not change it. + */ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t). + int8_t ranging_data; //!< Calibrated TX power at 0 m. + int8_t namespace[ES_UID_NAMESPACE_LENGTH]; //!< UID namespace. + int8_t instance[ES_UID_INSTANCE_LENGTH]; //!< UID instance. + int8_t rfu[ES_UID_RFU_LENGTH]; //!< RFU. +} es_uid_frame_t; + + +/** @brief URL frame data representation. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t). + int8_t ranging_data; //!< Calibrated TX power at 0 m. + uint8_t url_scheme; //!< URL scheme. + uint8_t encoded_url[ES_URL_ENCODED_URL_LENGTH]; //!< Encoded URL (variable length). +} es_url_frame_t; + + +/** @brief TLM frame data representation. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t). + es_tlm_version_t version; //!< TLM version (see @ref es_tlm_version_t). + int8_t vbatt[ES_TLM_VBATT_LENGTH]; //!< Battery voltage (in 1 mV units). + int8_t temp[ES_TLM_TEMP_LENGTH]; //!< Beacon temperature. + int8_t adv_cnt[ES_TLM_ADV_CNT_LENGTH]; //!< Advertising PDU count. + int8_t sec_cnt[ES_TLM_SEC_CNT_LENGTH]; //!< Time since power-on or reboot. +} es_tlm_frame_t; + +/** @brief EID frame data representation. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t). + int8_t ranging_data; //!< Calibrated TX power at 0 m. + int8_t eid[ES_EID_ID_LENGTH]; //!< 8-byte ephemeral identifier. +} es_eid_frame_t; + + +/** @brief eTLM frame data representation. + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t). + es_tlm_version_t version; //!< TLM version (see @ref es_tlm_version_t). + int8_t encrypted_tlm[ES_ETLM_ECRYPTED_LENGTH]; //!< Encrypted TLM data. + int16_t random_salt; //!< Salt + int16_t msg_integrity_check; //!< Message integrity check. +} es_etlm_frame_t; + +/** + * @} + */ + +#endif // ES_H__ diff --git a/components/libraries/eddystone/es_adv.c b/components/libraries/eddystone/es_adv.c new file mode 100644 index 0000000..225c7ce --- /dev/null +++ b/components/libraries/eddystone/es_adv.c @@ -0,0 +1,309 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_adv.h" +#include "app_error.h" +#include "es_adv_frame.h" +#include "es_adv_timing.h" +#include "es_tlm.h" +#include "es_slot.h" + +static es_adv_evt_handler_t m_adv_evt_handler; //!< Eddystone advertisement event handler. +static bool m_is_connected = false; //!< Is the Eddystone beacon in a connected state. +static bool m_remain_connectable = false; //!< Should the Eddystone beacon remain connectable. +static uint8_t m_ecs_uuid_type = 0; //!< UUID type of the Eddystone Configuration Service. +static uint16_t m_adv_interval = APP_CFG_NON_CONN_ADV_INTERVAL_MS; //!< Current advertisement interval. + +/**@brief Function for invoking registered callback. + * + * @param[in] evt Event to issue to callback. + */ +static void invoke_callback(es_adv_evt_t evt) +{ + if (m_adv_evt_handler != NULL) + { + m_adv_evt_handler(evt); + } +} + +/**@brief Starting advertising. + * @param[in] p_adv_params Advertisement parameters to use. + */ +static void adv_start(ble_gap_adv_params_t * p_adv_params) +{ + ret_code_t err_code = NRF_SUCCESS; + + es_tlm_adv_cnt_inc(); + + err_code = sd_ble_gap_adv_start(p_adv_params); + + if (err_code != NRF_ERROR_BUSY && err_code != NRF_SUCCESS) + { + APP_ERROR_CHECK(err_code); + } +} + + +/**@brief Given state of Eddystone beacon, get advertisement parameters. */ +static void get_adv_params(ble_gap_adv_params_t * p_adv_params, + bool non_connectable, + bool remain_connectable) +{ + // Initialize advertising parameters (used when starting advertising). + memset(p_adv_params, 0, sizeof(ble_gap_adv_params_t)); + + // Non-connectable + p_adv_params->type = + non_connectable ? BLE_GAP_ADV_TYPE_ADV_NONCONN_IND : BLE_GAP_ADV_TYPE_ADV_IND; + p_adv_params->p_peer_addr = NULL; // Undirected advertisement. + p_adv_params->fp = BLE_GAP_ADV_FP_ANY; + p_adv_params->interval = non_connectable ? BLE_GAP_ADV_INTERVAL_MAX : 1000; + p_adv_params->timeout = non_connectable + ? APP_CFG_NON_CONN_ADV_TIMEOUT + : (remain_connectable ? 0 : APP_CFG_CONNECTABLE_ADV_TIMEOUT); +} + + +/**@brief Update advertisement data and start connectable advertisements. */ +static void connectable_adv_start(void) +{ + ble_gap_adv_params_t connectable_adv_params; + ble_advdata_t scrsp_data; + ble_uuid_t scrp_uuids[] = {{BLE_UUID_ESCS_SERVICE, m_ecs_uuid_type}}; + + memset(&scrsp_data, 0, sizeof(scrsp_data)); + scrsp_data.name_type = BLE_ADVDATA_FULL_NAME; + scrsp_data.include_appearance = false; + scrsp_data.uuids_complete.uuid_cnt = sizeof(scrp_uuids) / sizeof(scrp_uuids[0]); + scrsp_data.uuids_complete.p_uuids = scrp_uuids; + + // As the data to be written does not depend on the slot_no, we can safely send + es_adv_frame_fill_connectable_adv_data(&scrsp_data); + + get_adv_params(&connectable_adv_params, false, m_remain_connectable); + adv_start(&connectable_adv_params); + + invoke_callback(ES_ADV_EVT_CONNECTABLE_ADV_STARTED); +} + + +static void adv_stop(void) +{ + ret_code_t err_code; + + err_code = sd_ble_gap_adv_stop(); + if (err_code != NRF_ERROR_INVALID_STATE) + { + APP_ERROR_CHECK(err_code); + } + + es_adv_timing_stop(); +} + + +static void adv_restart(void) +{ + if (!m_remain_connectable) + { + es_adv_start_non_connctable_adv(); + } + + else + { + connectable_adv_start(); + } +} + + +/**@brief Function handling events from @ref es_adv_timing.c. + * + * @param[in] p_evt Advertisement timing event. + */ +static void adv_timing_callback(const es_adv_timing_evt_t * p_evt) +{ + ret_code_t err_code; + ble_gap_adv_params_t non_connectable_adv_params; + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + // As new advertisement data will be loaded, stop advertising. + err_code = sd_ble_gap_adv_stop(); + if (err_code != NRF_ERROR_INVALID_STATE) + { + APP_ERROR_CHECK(err_code); + } + + // If a non-eTLM frame is to be advertised. + if (p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_SLOT) + { + err_code = sd_ble_gap_tx_power_set(p_reg->slots[p_evt->slot_no].radio_tx_pwr); + APP_ERROR_CHECK(err_code); + + es_adv_frame_fill_non_connectable_adv_data(p_evt->slot_no, false); + } + + // If an eTLM frame is to be advertised + else if (p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_ETLM) + { + err_code = sd_ble_gap_tx_power_set(p_reg->slots[p_reg->tlm_slot].radio_tx_pwr); + APP_ERROR_CHECK(err_code); + + es_adv_frame_fill_non_connectable_adv_data(p_evt->slot_no, true); + } + + invoke_callback(ES_ADV_EVT_NON_CONN_ADV); + + get_adv_params(&non_connectable_adv_params, true, m_remain_connectable); + adv_start(&non_connectable_adv_params); +} + + +void es_adv_start_connectable_adv(void) +{ + if (!m_is_connected) + { + adv_stop(); + + connectable_adv_start(); + } +} + + +void es_adv_start_non_connctable_adv(void) +{ + es_adv_timing_start(m_adv_interval); +} + + +void es_adv_remain_connectable_set(bool remain_connectable) +{ + m_remain_connectable = remain_connectable; +} + + +bool es_adv_remain_connectable_get(void) +{ + return m_remain_connectable; +} + + +void es_adv_on_ble_evt(ble_evt_t * p_ble_evt) +{ + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + m_is_connected = true; + + // The beacon must provide these advertisements for the client to see updated values + // during the connection. + es_adv_start_non_connctable_adv(); + break; + + case BLE_GAP_EVT_DISCONNECTED: + m_is_connected = false; + + // Stop all advertising to give some time for writing to flash. + adv_stop(); + adv_restart(); + break; + + case BLE_GAP_EVT_TIMEOUT: + if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING && + !m_is_connected) + { + adv_restart(); + } + break; + + default: + break; + } +} + + +void es_adv_interval_set(nrf_ble_escs_adv_interval_t interval) +{ + const es_slot_reg_t * p_reg = es_slot_get_registry(); + uint16_t min_valid_adv_interval; + + bool eTLM_required = (p_reg->num_configured_eid_slots > 0) && (p_reg->tlm_configured); + + min_valid_adv_interval = eTLM_required ? \ + p_reg->num_configured_slots * (APP_CONFIG_ADV_FRAME_SPACING_MS_MIN + \ + APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS) \ + : \ + p_reg->num_configured_slots * APP_CONFIG_ADV_FRAME_SPACING_MS_MIN; + + m_adv_interval = (interval > min_valid_adv_interval) ? interval : min_valid_adv_interval; + +#ifdef APP_CONFIG_ADV_INTERVAL_MS_MAX + if (m_adv_interval > APP_CONFIG_ADV_INTERVAL_MS_MAX) + { + m_adv_interval = APP_CONFIG_ADV_INTERVAL_MS_MAX; + } +#endif // APP_CONFIG_ADV_INTERVAL_MS_MAX +} + + +nrf_ble_escs_adv_interval_t es_adv_interval_get(void) +{ + return m_adv_interval; +} + + +void es_adv_init(uint8_t ecs_uuid_type, + es_adv_evt_handler_t adv_event_handler, + nrf_ble_escs_adv_interval_t adv_interval, + bool remain_connectable) +{ + m_ecs_uuid_type = ecs_uuid_type; + m_adv_evt_handler = adv_event_handler; + m_is_connected = false; + m_remain_connectable = remain_connectable; + m_adv_interval = adv_interval; + + es_tlm_init(); + + es_adv_timing_init(adv_timing_callback); +} + +void es_adv_timers_init(void) +{ + es_adv_timing_timers_init(); +} diff --git a/components/libraries/eddystone/es_adv.h b/components/libraries/eddystone/es_adv.h new file mode 100644 index 0000000..4b2bcf5 --- /dev/null +++ b/components/libraries/eddystone/es_adv.h @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_ADV_H__ +#define ES_ADV_H__ + +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_adv Eddystone advertising module + * @brief Types and functions for handling advertising in Eddystone beacons. + * @ingroup eddystone + * @{ + */ + +/** @brief Eddystone Advertiser events. */ +typedef enum +{ + ES_ADV_EVT_NON_CONN_ADV, + ES_ADV_EVT_CONNECTABLE_ADV_STARTED, +} es_adv_evt_t; + +/** @brief Eddystone Advertiser event handler. */ +typedef void (*es_adv_evt_handler_t)(es_adv_evt_t evt); + +/** @brief Function for initializing the module. + * + * @param[in] ecs_uuid_type ECS UUID type used for advertising the Eddystone Configuration Service UUID. + * @param[in] adv_event_handler Eddystone advertiser event handler. + * @param[in] adv_interval Advertisement interval to use. + * @param[in] remain_connectable Flag that specifies if advertisements should remain connectable. + */ +void es_adv_init(uint8_t ecs_uuid_type, + es_adv_evt_handler_t adv_event_handler, + nrf_ble_escs_adv_interval_t adv_interval, + bool remain_connectable); + +/** @brief Function for passing BLE events to this module. + * + * @param[in] p_ble_evt Pointer to the BLE evt. + */ +void es_adv_on_ble_evt(ble_evt_t * p_ble_evt); + +/** @brief Function for starting the advertisements. + */ +void es_adv_start_non_connctable_adv(void); + +/** @brief Function for specifying if the beacon should remain connectable. + * + * @param[in] remain_connectable Value to be set. + */ +void es_adv_remain_connectable_set(bool remain_connectable); + +/** @brief Function for starting connectable advertisements. + */ +void es_adv_start_connectable_adv(void); + +/** @brief Function for setting the base advertisement interval for non-connectable advertisements. + * + * The minimum allowed advertisement interval is calculated based on the configured minimum advertisement + * frame spacings and the number of configured slots. If eTLM slots are configured a separate minimum + * advertisement frame spacing is used for those. If @p interval is outside of range, the closest valid value + * is set. + * + * @param interval The new advertisement interval. + */ +void es_adv_interval_set(nrf_ble_escs_adv_interval_t interval); + +/** @brief Function for getting a pointer to the current advertisement interval. + * + * @retval Pointer to the current advertisement interval. + */ +nrf_ble_escs_adv_interval_t es_adv_interval_get(void); + +/** @brief Function for getting the value of the 'remain_connectable' field. + * + * @retval Value of 'remain_connectable'. + */ +bool es_adv_remain_connectable_get(void); + +/** @brief Function for initializing the Eddystone advertisement timers. + */ +void es_adv_timers_init(void); + +/** + * @} + */ + +#endif // ES_ADV_H__ diff --git a/components/libraries/eddystone/es_adv_frame.c b/components/libraries/eddystone/es_adv_frame.c new file mode 100644 index 0000000..a4bf40b --- /dev/null +++ b/components/libraries/eddystone/es_adv_frame.c @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_adv_frame.h" +#include "es_slot.h" + + +/**@brief Function for setting advertisement data, using 'ble_advdata_set'. + * + * @param[in] p_scrsp_data Scan response data. + * @param[in] p_es_data_array Eddystone service data array. + */ +static void fill_adv_data(ble_advdata_t * p_scrsp_data, uint8_array_t * p_es_data_array) +{ + ble_advdata_t adv_data; + ret_code_t err_code; + ble_uuid_t adv_uuids[] = {{ES_UUID, BLE_UUID_TYPE_BLE}}; + uint8_array_t es_data_array = {0}; + + ble_advdata_service_data_t service_data; // Structure to hold Service Data. + + service_data.service_uuid = APP_ES_UUID; // Eddystone UUID to allow discoverability on iOS devices. + + service_data.data = (p_es_data_array != NULL) ? *p_es_data_array : es_data_array; + + // Build and set advertising data. + memset(&adv_data, 0, sizeof(ble_advdata_t)); + + adv_data.name_type = BLE_ADVDATA_NO_NAME; + adv_data.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; + adv_data.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]); + adv_data.uuids_complete.p_uuids = adv_uuids; + adv_data.p_service_data_array = &service_data; + adv_data.service_data_count = (p_es_data_array != NULL) ? 1 : 0; + + err_code = ble_advdata_set(&adv_data, p_scrsp_data); + APP_ERROR_CHECK(err_code); +} + + +void es_adv_frame_fill_connectable_adv_data(ble_advdata_t * p_scrsp_data) +{ + fill_adv_data(p_scrsp_data, NULL); +} + + +void es_adv_frame_fill_non_connectable_adv_data(uint8_t slot_no, bool etlm) +{ + uint8_array_t es_data_array = {0}; + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + if (etlm) + { + es_slot_etlm_update(slot_no); + + // If eTLM, the incoming slot_no points to the corresponding EID slot, update to point to TLM slot. + slot_no = p_reg->tlm_slot; + } + + // If TLM, update the TLM data. + else if (p_reg->slots[slot_no].adv_frame.type == ES_FRAME_TYPE_TLM) + { + es_slot_tlm_update(); + } + + es_data_array.p_data = (uint8_t *)&p_reg->slots[slot_no].adv_frame.frame; + es_data_array.size = p_reg->slots[slot_no].adv_frame.length; + + fill_adv_data(NULL, &es_data_array); +} diff --git a/components/libraries/eddystone/es_adv_frame.h b/components/libraries/eddystone/es_adv_frame.h new file mode 100644 index 0000000..199ffcb --- /dev/null +++ b/components/libraries/eddystone/es_adv_frame.h @@ -0,0 +1,72 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_ADV_FRAME_H__ +#define ES_ADV_FRAME_H__ + +#include +#include "ble_advdata.h" + +/** + * @file + * @addtogroup eddystone_adv + * @{ + */ + +/**@brief Function for setting up connectable advertisement data using @ref + * ble_advdata_set. + * + * @param[in] p_scrsp_data Pointer to the scan response data. + */ +void es_adv_frame_fill_connectable_adv_data(ble_advdata_t * p_scrsp_data); + +/**@brief Function for setting up non-connectable advertisement data using @ref + * ble_advdata_set. + * + * @param[in] slot_no Slot to fill in data for. + * @param[in] etlm Flag that specifies if Eddystone-TLM is required. + */ +void es_adv_frame_fill_non_connectable_adv_data(uint8_t slot_no, bool etlm); + +/** + * @} + */ + +#endif // ES_ADV_FRAME_H__ diff --git a/components/libraries/eddystone/es_adv_timing.c b/components/libraries/eddystone/es_adv_timing.c new file mode 100644 index 0000000..ac47626 --- /dev/null +++ b/components/libraries/eddystone/es_adv_timing.c @@ -0,0 +1,221 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "app_timer.h" +#include "es_adv_timing.h" +#include "es_adv_timing_resolver.h" +#include "es_slot.h" + + +APP_TIMER_DEF(m_es_adv_interval_timer); //!< Timer for advertising the set of slots. +APP_TIMER_DEF(m_es_slot_timer); //!< Timer for advertising individual slots. + +static nrf_ble_escs_adv_interval_t m_current_adv_interval; //!< Current advertisement interval. +static es_adv_timing_callback_t m_timing_mgr_callback; //!< Registered callback. +static es_adv_timing_resolver_result_t m_adv_timing_result; //!< Current advertising timing result. +static bool m_non_conn_adv_active; //!< Is the beacon advertising non-conn advertisements? + +/**@brief Function for invoking registered callback. + * + * @param[in] p_evt Event to issue to callback. + */ +static void invoke_callback(const es_adv_timing_evt_t * p_evt) +{ + if (m_timing_mgr_callback != NULL && m_non_conn_adv_active) + { + m_timing_mgr_callback(p_evt); + } +} + + +#if APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1 +static bool frame_to_adv_is_tlm(const es_adv_timing_evt_t * p_evt) +{ + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + return (p_reg->tlm_configured && + (p_evt->slot_no == p_reg->tlm_slot || p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_ETLM)); +} + + +static bool tlm_should_be_advertised(uint32_t adv_event_cnt) +{ + return (adv_event_cnt % APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO) == 0; +} +#endif // APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1 + + +/**@brief Timeout handler for the advertisement slot timer. */ +static void adv_slot_timeout(void * p_context) +{ + + ret_code_t err_code; + uint32_t active_slot_index = (uint32_t)p_context; + + es_adv_timing_evt_t evt; + + evt.slot_no = m_adv_timing_result.timing_results[active_slot_index].slot_no; + + evt.evt_id = m_adv_timing_result.timing_results[active_slot_index].is_etlm + ? ES_ADV_TIMING_EVT_ADV_ETLM + : ES_ADV_TIMING_EVT_ADV_SLOT; + + // Trigger an event for the next slot if this slot is not the last to be advertised in this event. + // Note: since we check 'm_adv_timing_result.len_timing_results > 1' we can safely cast the result of + // the subtraction to a uint32. + if (m_non_conn_adv_active && \ + m_adv_timing_result.len_timing_results > 1 && \ + active_slot_index < (uint32_t)(m_adv_timing_result.len_timing_results - 1)) + { + err_code = app_timer_start( m_es_slot_timer, + APP_TIMER_TICKS(m_adv_timing_result.timing_results[active_slot_index].delay_ms, + APP_TIMER_PRESCALER), + (void*)(active_slot_index + 1)); + APP_ERROR_CHECK(err_code); + } + +#if APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1 + static uint32_t adv_event_cnt = 0; + + if (active_slot_index == 0) + { + adv_event_cnt++; + } + + if (frame_to_adv_is_tlm(&evt) && !tlm_should_be_advertised(adv_event_cnt)) + { + return; + } +#endif // APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1 + + invoke_callback(&evt); +} + + +/**@brief Timeout handler for the advertisement interval timer. */ +static void adv_interval_timeout(void * p_context) +{ + if (es_slot_get_registry()->num_configured_slots > 0) + { + // Trigger slot timeout for advertising the first slot. + // Note: The slot number is not the index in the slot registry, it is the index of the active slots. + adv_slot_timeout(NULL); + } + + if(m_non_conn_adv_active) + { + uint32_t err_code = app_timer_start(m_es_adv_interval_timer, + APP_TIMER_TICKS(m_current_adv_interval, APP_TIMER_PRESCALER), + NULL); + APP_ERROR_CHECK(err_code); + } +} + + +void es_adv_timing_timers_init(void) +{ + ret_code_t err_code; + + err_code = app_timer_create(&m_es_adv_interval_timer, + APP_TIMER_MODE_SINGLE_SHOT, + adv_interval_timeout); + APP_ERROR_CHECK(err_code); + + err_code = app_timer_create(&m_es_slot_timer, + APP_TIMER_MODE_SINGLE_SHOT, + adv_slot_timeout); + APP_ERROR_CHECK(err_code); +} + + +/**@brief Function for finding and setting advertisement timing configuration. */ +static void adv_timing_set(void) +{ + ret_code_t err_code; + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + es_adv_timing_resolver_input_t resolver_input = { + .adv_interval = m_current_adv_interval, + .p_result = &m_adv_timing_result, + .num_slots_configured = p_reg->num_configured_slots, + .p_slots_configured = p_reg->slots_configured, + .num_eid_slots_configured = p_reg->num_configured_eid_slots, + .p_eid_slots_configured = p_reg->eid_slots_configured, + .tlm_configured = p_reg->tlm_configured, + .tlm_slot = p_reg->tlm_slot}; + + err_code = es_adv_timing_resolve(&resolver_input); + APP_ERROR_CHECK(err_code); +} + + +void es_adv_timing_start(uint16_t adv_interval) +{ + ret_code_t err_code; + + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + m_non_conn_adv_active = true; + + if (p_reg->num_configured_slots > 0) + { + m_current_adv_interval = adv_interval; + + err_code = app_timer_start(m_es_adv_interval_timer, + APP_TIMER_TICKS(m_current_adv_interval, APP_TIMER_PRESCALER), + NULL); + APP_ERROR_CHECK(err_code); + + adv_timing_set(); + } +} + + +void es_adv_timing_stop(void) +{ + m_non_conn_adv_active = false; // Stops timers from being re-fired. +} + + +void es_adv_timing_init(es_adv_timing_callback_t p_handler) +{ + m_non_conn_adv_active = false; + m_timing_mgr_callback = p_handler; + memset(&m_adv_timing_result, 0, sizeof(m_adv_timing_result)); +} diff --git a/components/libraries/eddystone/es_adv_timing.h b/components/libraries/eddystone/es_adv_timing.h new file mode 100644 index 0000000..9d224c1 --- /dev/null +++ b/components/libraries/eddystone/es_adv_timing.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_ADV_TIMING_H__ +#define ES_ADV_TIMING_H__ + +#include + +/** + * @file + * @defgroup eddystone_adv_timing Timing + * @brief Events and functions for advertisement timing. + * @ingroup eddystone_adv + * @{ + */ + +/**@brief Eddystone advertisement timing event types. */ +typedef enum +{ + ES_ADV_TIMING_EVT_ADV_SLOT, //!< Advertising non-eTLM slot. + ES_ADV_TIMING_EVT_ADV_ETLM //!< Advertising eTLM slot. +} es_adv_timing_evt_id_t; + +/**@brief Eddystone advertisement timing event. */ +typedef struct +{ + es_adv_timing_evt_id_t evt_id; //!< Event type ID. + uint8_t slot_no; /**< @brief Slot number. + * @details For non-eTLM events: The slot number to advertise. + * + * For eTLM events: The slot number of the corresponding EID slot. */ +} es_adv_timing_evt_t; + +/**@brief Eddystone advertisement timing event callback. + * + * @param[in] p_evt Pointer to the Eddystone advertisement timing event. + */ +typedef void (*es_adv_timing_callback_t)(const es_adv_timing_evt_t * p_evt); + +/**@brief Function for starting Eddystone advertisement timing event generation. */ +void es_adv_timing_start(uint16_t adv_interval); + + +/**@brief Function for stopping Eddystone advertisement timing event generation. */ +void es_adv_timing_stop(void); + +/**@brief Function for initializing the Eddystone advertisement timers. + */ +void es_adv_timing_timers_init(void); + +/**@brief Function for initializing the Eddystone advertisement timing module. + * + * @param[in] handler Eddystone advertisement timing event handler to register. + */ +void es_adv_timing_init(es_adv_timing_callback_t handler); + +/** + * @} + */ + +#endif // ES_ADV_TIMING_H__ diff --git a/components/libraries/eddystone/es_adv_timing_resolver.c b/components/libraries/eddystone/es_adv_timing_resolver.c new file mode 100644 index 0000000..5506b7a --- /dev/null +++ b/components/libraries/eddystone/es_adv_timing_resolver.c @@ -0,0 +1,145 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_adv_timing_resolver.h" +#include "sdk_macros.h" + +/**@brief Function for finding delay to use after each non-eTLM advertisement. + * + * @param[in] adv_interval Configured advertisement interval. + * @param[in] num_slots_configured Number of configured slots. + * @param[in] eTLM_required Is there an eTLM slot. + */ +static uint16_t get_adv_delay(uint16_t adv_interval, + uint8_t num_slots_configured, + bool eTLM_required) +{ + // If eTLM is required, don't count this when calculating delay. + return adv_interval / (num_slots_configured - (eTLM_required ? 1 : 0)); +} + + +/**@brief Function for checking if given slot_no is an EID slot. + * + * @param[in] slot_no Slot number to check. + * @param[in] p_eid_slots_configured Pointer to list of configured EID slots. + * @param[in] num_eid_slots_configured Number of EID slots configured. + */ +static bool is_eid(uint8_t slot_no, const uint8_t * p_eid_slots_configured, uint8_t num_eid_slots_configured) +{ + for (uint32_t i = 0; i < num_eid_slots_configured; ++i) + { + if (slot_no == p_eid_slots_configured[i]) + { + return true; + } + } + + return false; +} + +ret_code_t es_adv_timing_resolve(es_adv_timing_resolver_input_t * p_input) +{ + VERIFY_PARAM_NOT_NULL(p_input); + + uint8_t result_index = 0; + bool eTLM_required = p_input->tlm_configured && p_input->num_eid_slots_configured > 0; + uint16_t base_delay; + + if (p_input->num_slots_configured == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + + base_delay = get_adv_delay(p_input->adv_interval, p_input->num_slots_configured, eTLM_required); + + for (uint32_t i = 0; i < p_input->num_slots_configured; ++i) + { + uint8_t slot_no = p_input->p_slots_configured[i]; + + if (!(eTLM_required && slot_no == p_input->tlm_slot)) + { + es_adv_timing_resolver_adv_timing_t * p_current_result = &p_input->p_result->timing_results[result_index]; + p_current_result->slot_no = slot_no; + p_current_result->is_etlm = false; + + // If an eTLM is to be advertised for this frame, this value will be changed. + p_current_result->delay_ms = base_delay; + + result_index++; + + if (eTLM_required && + is_eid(slot_no, p_input->p_eid_slots_configured, p_input->num_eid_slots_configured)) + { + es_adv_timing_resolver_adv_timing_t * p_eTLM_timing_result = + &p_input->p_result->timing_results[result_index]; + + p_current_result->delay_ms = APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS; // Update delay from EID to eTLM frame. + + p_eTLM_timing_result->slot_no = slot_no; // Point to EID slot-no, as this will be + // used for finding the correct EIK. + p_eTLM_timing_result->is_etlm = true; // Configure as eTLM frame. + + if (base_delay > APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS) + { + p_eTLM_timing_result->delay_ms = + base_delay - + APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS; // Set delay of eTLM frame. + } + + else + { + p_eTLM_timing_result->delay_ms = APP_CONFIG_ADV_FRAME_SPACING_MS_MIN; + } + + result_index++; + } + } + } + + p_input->p_result->len_timing_results = result_index; // Note: index has been increased to equal length of result. + + if(p_input->p_result->len_timing_results > 0) + { + p_input->p_result->timing_results[p_input->p_result->len_timing_results - 1].delay_ms = 0; // Last Slot does not need delay. + } + + return NRF_SUCCESS; +} diff --git a/components/libraries/eddystone/es_adv_timing_resolver.h b/components/libraries/eddystone/es_adv_timing_resolver.h new file mode 100644 index 0000000..20f272e --- /dev/null +++ b/components/libraries/eddystone/es_adv_timing_resolver.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_ADV_TIMING_RESOLVER_H__ +#define ES_ADV_TIMING_RESOLVER_H__ + +#include +#include +#include "es_app_config.h" + +/** + * @file + * @addtogroup eddystone_adv_timing + * @{ + */ + +/** @brief Timing parameters for a single slot. */ +typedef struct +{ + bool is_etlm; //!< Flag that specifies if the slot is an eTLM. + uint8_t slot_no; /**< @brief Slot number. @details + * For non-eTLM slots: The slot number of the given frame. + * + * For eTLM slots: The slot number of the corresponding EID frame. */ + uint16_t delay_ms; //!< Delay from this frame to the next. +} es_adv_timing_resolver_adv_timing_t; + +/**@brief Results of calculating advertisement delays. */ +typedef struct +{ + es_adv_timing_resolver_adv_timing_t timing_results[APP_MAX_ADV_SLOTS - APP_MAX_EID_SLOTS + + (APP_MAX_EID_SLOTS * 2)]; //!< List of timing results. + uint8_t len_timing_results; //!< Length of results. +} es_adv_timing_resolver_result_t; + +/**@brief Input to the timing resolver. */ +typedef struct +{ + uint16_t adv_interval; //!< Global advertisement interval. + uint8_t num_slots_configured; //!< Number of configured slots. + const uint8_t * p_slots_configured; //!< Pointer to the list of configured slots. + uint8_t num_eid_slots_configured; //!< Number of configured EID slots. + const uint8_t * p_eid_slots_configured; //!< Pointer to the list of configured EID slots. + bool tlm_configured; //!< Flag that specifies if TLM slot is configured. + uint8_t tlm_slot; //!< Slot number of the TLM slot (if @p tlm_configured is true). + es_adv_timing_resolver_result_t * p_result; //!< Output result. +} es_adv_timing_resolver_input_t; + +/**@brief Function for getting the input for advertisement interval calculation. + * + * @param[in,out] p_input Input to advertisement interval calculation (see @ref es_adv_timing_resolver_input_t). + * @retval NRF_SUCCESS If the operation was successful. Otherwise, an error code is returned. + */ +ret_code_t es_adv_timing_resolve(es_adv_timing_resolver_input_t * p_input); + +/** + * @} + */ + +#endif // ES_ADV_TIMING_RESOLVER_H__ diff --git a/components/libraries/eddystone/es_battery_voltage.h b/components/libraries/eddystone/es_battery_voltage.h new file mode 100644 index 0000000..7ba2575 --- /dev/null +++ b/components/libraries/eddystone/es_battery_voltage.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_BATTERY_VOLTAGE_H__ +#define ES_BATTERY_VOLTAGE_H__ + +#include + +/** + * @file + * + * @addtogroup eddystone_tlm + * @{ + */ + +/**@brief Function for initializing the battery voltage module. + */ +void es_battery_voltage_init(void); + +/**@brief Function for reading the battery voltage. + * + * @param[out] p_vbatt Pointer to the battery voltage value. + */ +void es_battery_voltage_get(uint16_t * p_vbatt); + +/** + * @} + */ + +#endif // ES_BATTERY_VOLTAGE_H__ diff --git a/components/libraries/eddystone/es_battery_voltage_adc.c b/components/libraries/eddystone/es_battery_voltage_adc.c new file mode 100644 index 0000000..03e939f --- /dev/null +++ b/components/libraries/eddystone/es_battery_voltage_adc.c @@ -0,0 +1,100 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "app_error.h" +#include "es_battery_voltage.h" +#include "nrf_drv_adc.h" + +static uint16_t m_batt_lvl_in_milli_volts; + +#define ADC_REF_VOLTAGE_IN_MILLIVOLTS 600 // /< Reference voltage (in milli volts) used by ADC while doing conversion. +#define DIODE_FWD_VOLT_DROP_MILLIVOLTS 270 // /< Typical forward voltage drop of the diode (Part no: SD103ATW-7-F) that is connected in series with the voltage supply. This is the voltage drop when the forward current is 1mA. Source: Data sheet of 'SURFACE MOUNT SCHOTTKY BARRIER DIODE ARRAY' available at www.diodes.com. +#define ADC_RES_10BIT 1024 // /< Maximum digital value for 10-bit ADC conversion. +#define ADC_PRE_SCALING_COMPENSATION 6 // /< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage. +#define ADC_REF_VBG_VOLTAGE_IN_MILLIVOLTS 1200 // /< Value in millivolts for voltage used as reference in ADC conversion on NRF51. +#define ADC_INPUT_PRESCALER 3 // /< Input prescaler for ADC convestion on NRF51. + +static nrf_adc_value_t adc_buf[1]; +#define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE) \ + ((((ADC_VALUE) *ADC_REF_VBG_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_INPUT_PRESCALER) + +static void adc_event_handler(nrf_drv_adc_evt_t const * p_event) +{ + if (p_event->type == NRF_DRV_ADC_EVT_DONE) + { + nrf_adc_value_t adc_result; + ret_code_t err_code; + + adc_result = p_event->data.done.p_buffer[0]; + + err_code = nrf_drv_adc_buffer_convert(p_event->data.done.p_buffer, 1); + APP_ERROR_CHECK(err_code); + + m_batt_lvl_in_milli_volts = + ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS; + } +} + + +void es_battery_voltage_init(void) +{ + ret_code_t err_code = nrf_drv_adc_init(NULL, adc_event_handler); + + APP_ERROR_CHECK(err_code); + + static nrf_drv_adc_channel_t channel = + NRF_DRV_ADC_DEFAULT_CHANNEL(NRF_ADC_CONFIG_INPUT_DISABLED); + channel.config.config.input = (uint32_t)NRF_ADC_CONFIG_SCALING_SUPPLY_ONE_THIRD; + nrf_drv_adc_channel_enable(&channel); + + err_code = nrf_drv_adc_buffer_convert(&adc_buf[0], 1); + APP_ERROR_CHECK(err_code); + nrf_drv_adc_sample(); +} + + +void es_battery_voltage_get(uint16_t * p_vbatt) +{ + *p_vbatt = m_batt_lvl_in_milli_volts; + if (!nrf_adc_is_busy()) + { + nrf_drv_adc_sample(); + } +} diff --git a/components/libraries/eddystone/es_battery_voltage_saadc.c b/components/libraries/eddystone/es_battery_voltage_saadc.c new file mode 100644 index 0000000..b7d25a2 --- /dev/null +++ b/components/libraries/eddystone/es_battery_voltage_saadc.c @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_battery_voltage.h" +#include "nrf_drv_saadc.h" +#include "sdk_macros.h" + +#define ADC_REF_VOLTAGE_IN_MILLIVOLTS 600 //!< Reference voltage (in milli volts) used by ADC while doing conversion. +#define DIODE_FWD_VOLT_DROP_MILLIVOLTS 270 //!< Typical forward voltage drop of the diode (Part no: SD103ATW-7-F) that is connected in series with the voltage supply. This is the voltage drop when the forward current is 1mA. Source: Data sheet of 'SURFACE MOUNT SCHOTTKY BARRIER DIODE ARRAY' available at www.diodes.com. +#define ADC_RES_10BIT 1024 //!< Maximum digital value for 10-bit ADC conversion. +#define ADC_PRE_SCALING_COMPENSATION 6 //!< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage. +#define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE) \ + ((((ADC_VALUE) *ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION) + +static nrf_saadc_value_t adc_buf; //!< Buffer used for storing ADC value. +static uint16_t m_batt_lvl_in_milli_volts; //!< Current battery level. + +/**@brief Function handling events from 'nrf_drv_saadc.c'. + * + * @param[in] p_evt SAADC event. + */ +static void saadc_event_handler(nrf_drv_saadc_evt_t const * p_evt) +{ + if (p_evt->type == NRF_DRV_SAADC_EVT_DONE) + { + nrf_saadc_value_t adc_result; + + adc_result = p_evt->data.done.p_buffer[0]; + + m_batt_lvl_in_milli_volts = + ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS; + } +} + + +void es_battery_voltage_init(void) +{ + ret_code_t err_code = nrf_drv_saadc_init(NULL, saadc_event_handler); + + APP_ERROR_CHECK(err_code); + + nrf_saadc_channel_config_t config = + NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD); + err_code = nrf_drv_saadc_channel_init(0, &config); + APP_ERROR_CHECK(err_code); + + err_code = nrf_drv_saadc_buffer_convert(&adc_buf, 1); + APP_ERROR_CHECK(err_code); + + err_code = nrf_drv_saadc_sample(); + APP_ERROR_CHECK(err_code); +} + + +void es_battery_voltage_get(uint16_t * p_vbatt) +{ + VERIFY_PARAM_NOT_NULL_VOID(p_vbatt); + + *p_vbatt = m_batt_lvl_in_milli_volts; + if (!nrf_drv_saadc_is_busy()) + { + ret_code_t err_code = nrf_drv_saadc_buffer_convert(&adc_buf, 1); + APP_ERROR_CHECK(err_code); + + err_code = nrf_drv_saadc_sample(); + APP_ERROR_CHECK(err_code); + } +} diff --git a/components/libraries/eddystone/es_flash.c b/components/libraries/eddystone/es_flash.c new file mode 100644 index 0000000..2c5c7fe --- /dev/null +++ b/components/libraries/eddystone/es_flash.c @@ -0,0 +1,350 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "es_flash.h" +#include "es_util.h" +#include "app_scheduler.h" +#include "ble_hci.h" +#include "fds.h" +#include "nrf_nvic.h" + +#define SIZE_OF_PRIV_KEY ESCS_ECDH_KEY_SIZE //!< Size of ECDH private key. +#define SIZE_OF_PUB_KEY ESCS_ECDH_KEY_SIZE //!< Size of ECDH public key. +#define SIZE_OF_LOCK_KEY ESCS_AES_KEY_SIZE //!< Size of lock key. +#define FILE_ID_ES_FLASH 0x1337 //!< File ID used for all flash access EXCEPT lock code. +#define FILE_ID_ES_FLASH_LOCK_KEY 0x1338 //!< File ID used for lock code flash access. +#define RECORD_KEY_FLAGS 0x1 //!< File record for flash flags. +#define RECORD_KEY_PRIV_KEY 0x2 //!< File record for private key. +#define RECORD_KEY_PUB_KEY 0x3 //!< File record for public key. +#define RECORD_KEY_LOCK_KEY 0x4 //!< File record for lock key. +#define RECORD_KEY_BEACON_CONFIG 0x5 //!< File record for lock key. + +static uint16_t RECORD_KEY_SLOTS[5] = {0x6, 0x7, 0x8, 0x9, 0xa}; //!< File record for slots. + +/**@brief Structure used for invoking flash access function. */ +typedef struct +{ + uint16_t record_key; + uint16_t file_id; + uint8_t * p_chunk_buf; + uint8_t * p_data; + uint16_t size_bytes; + es_flash_access_t access_type; +} flash_access_params_t; + +static volatile uint32_t m_num_pending_ops; //!< Current number of outstanding FDS operations. +static volatile bool m_factory_reset; //!< Should factory reset be performed. +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; //!< Current connection handle. + + +#if APP_MAX_ADV_SLOTS > 32 +#error "APP_MAX_ADV_SLOTS must be <= 32" +#endif + +#define SLOT_DECL(i, _) __ALIGN(4) static uint8_t slot## i ##_buf[sizeof(es_slot_t)]; + +//lint -save -e123 +EVAL(REPEAT(APP_MAX_ADV_SLOTS, SLOT_DECL, ~)) + +#define SLOT(i, _) slot## i ##_buf, +static uint8_t * slots_buf_p[APP_MAX_ADV_SLOTS] = { + EVAL(REPEAT(APP_MAX_ADV_SLOTS, SLOT, ~)) +}; +//lint -restore + +__ALIGN(4) static uint8_t lock_key_buf[SIZE_OF_LOCK_KEY]; //!< Buffer for lock key flash access. + +__ALIGN(4) static uint8_t flash_flags_buf[sizeof(es_flash_flags_t)]; //!< Buffer for flash flags flash access. +__ALIGN(4) static uint8_t beacon_config_buf[sizeof(es_flash_beacon_config_t)]; //!< Buffer for beacon config flash access. + +/**@brief Function handling scheduled FDS garbage collection. */ +static void fds_gc_event(void * p_event_data, uint16_t event_size) +{ + ret_code_t fds_err_code; + + fds_err_code = fds_gc(); + if (fds_err_code != FDS_SUCCESS) + APP_ERROR_CHECK_BOOL(NRF_ERROR_INTERNAL); + m_num_pending_ops++; +} + + +/**@brief Function handling FDS events. + * + * @param[in] p_evt FDS event. + */ +static void fds_cb(fds_evt_t const * const p_evt) +{ + ret_code_t err_code; + + switch (p_evt->id) + { + case FDS_EVT_INIT: + m_num_pending_ops = 0; + break; + + case FDS_EVT_DEL_FILE: + case FDS_EVT_DEL_RECORD: + // Schedule garbage collection + err_code = app_sched_event_put(NULL, 0, fds_gc_event); + APP_ERROR_CHECK(err_code); + break; + + case FDS_EVT_GC: + if (m_factory_reset && m_conn_handle != BLE_CONN_HANDLE_INVALID) + { + err_code = + sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); + APP_ERROR_CHECK(err_code); + } + + // Fall through: + case FDS_EVT_UPDATE: + case FDS_EVT_WRITE: + if (m_num_pending_ops > 0) + { + m_num_pending_ops--; + } + break; + } +} + + +/**@brief Function performing flash access (read/write/clear). + * + * @param[in] p_params Flash access parameters. + */ +static ret_code_t access_flash_data(const flash_access_params_t * p_params) +{ + ret_code_t err_code; + fds_record_chunk_t chunk = {.p_data = p_params->p_chunk_buf}; + fds_record_t record_to_write = {.data.p_chunks = &chunk, .file_id = p_params->file_id}; + fds_flash_record_t record = {0}; + fds_record_desc_t desc = {0}; + fds_find_token_t ft = {0}; + + err_code = fds_record_find_by_key(p_params->record_key, &desc, &ft); + + // If its a read or clear, we can not accept errors on lookup + if (p_params->access_type == ES_FLASH_ACCESS_READ) + { + RETURN_IF_ERROR(err_code); + } + + if (p_params->access_type == ES_FLASH_ACCESS_CLEAR && err_code == FDS_ERR_NOT_FOUND) + { + return NRF_SUCCESS; + } + + switch (p_params->access_type) + { + case ES_FLASH_ACCESS_READ: + err_code = fds_record_open(&desc, &record); + RETURN_IF_ERROR(err_code); + + memcpy(p_params->p_data, record.p_data, p_params->size_bytes); + + err_code = fds_record_close(&desc); + RETURN_IF_ERROR(err_code); + + break; + + case ES_FLASH_ACCESS_WRITE: + // Note chunk.p_data points to p_params->p_chunk_buf + memcpy(p_params->p_chunk_buf, p_params->p_data, p_params->size_bytes); + + chunk.length_words = p_params->size_bytes / 4; + + if (p_params->size_bytes % 4 != 0) + { + chunk.length_words++; + } + + record_to_write.key = p_params->record_key; + + record_to_write.data.num_chunks = 1; + + if (err_code == FDS_ERR_NOT_FOUND) + { + err_code = fds_record_write(&desc, &record_to_write); + } + + else + { + err_code = fds_record_update(&desc, &record_to_write); + } + + RETURN_IF_ERROR(err_code); + m_num_pending_ops++; + break; + + case ES_FLASH_ACCESS_CLEAR: + err_code = fds_record_delete(&desc); + RETURN_IF_ERROR(err_code); + m_num_pending_ops++; + break; + + default: + break; + } + return NRF_SUCCESS; +} + + +ret_code_t es_flash_access_lock_key(uint8_t * p_lock_key, es_flash_access_t access_type) +{ + flash_access_params_t params = {.record_key = RECORD_KEY_LOCK_KEY, + .file_id = FILE_ID_ES_FLASH_LOCK_KEY, + .p_chunk_buf = lock_key_buf, + .p_data = (uint8_t *)p_lock_key, + .size_bytes = SIZE_OF_LOCK_KEY, + .access_type = access_type}; + + return access_flash_data(¶ms); +} + + +ret_code_t es_flash_access_beacon_config(es_flash_beacon_config_t * p_config, + es_flash_access_t access_type) +{ + ret_code_t err_code; + + flash_access_params_t params = {.record_key = RECORD_KEY_BEACON_CONFIG, + .file_id = FILE_ID_ES_FLASH, + .p_chunk_buf = beacon_config_buf, + .p_data = (uint8_t *)p_config, + .size_bytes = sizeof(es_flash_beacon_config_t), + .access_type = access_type}; + + err_code = access_flash_data(¶ms); + + return err_code; +} + + +ret_code_t es_flash_access_slot_configs(uint8_t slot_no, + es_slot_t * p_slot, + es_flash_access_t access_type) +{ + if (slot_no >= APP_MAX_ADV_SLOTS) + { + return NRF_ERROR_INVALID_PARAM; + } + + flash_access_params_t params = {.record_key = RECORD_KEY_SLOTS[slot_no], + .file_id = FILE_ID_ES_FLASH, + .p_chunk_buf = slots_buf_p[slot_no], + .p_data = (uint8_t *)p_slot, + .size_bytes = sizeof(es_slot_t), + .access_type = access_type}; + + return access_flash_data(¶ms); +} + + +ret_code_t es_flash_access_flags(es_flash_flags_t * p_flags, es_flash_access_t access_type) +{ + flash_access_params_t params = {.record_key = RECORD_KEY_FLAGS, + .file_id = FILE_ID_ES_FLASH, + .p_chunk_buf = flash_flags_buf, + .p_data = (uint8_t *)p_flags, + .size_bytes = sizeof(es_flash_flags_t), + .access_type = access_type}; + + return access_flash_data(¶ms); +} + + +ret_code_t es_flash_factory_reset(void) +{ + // Delete everything except the lock key: + ret_code_t ret_code = fds_file_delete(FILE_ID_ES_FLASH); + + if (ret_code == FDS_SUCCESS) + m_factory_reset = true; + return ret_code; +} + + +uint32_t es_flash_num_pending_ops(void) +{ + return m_num_pending_ops; +} + + +void es_flash_on_ble_evt(ble_evt_t * p_evt) +{ + switch (p_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + m_conn_handle = p_evt->evt.common_evt.conn_handle; + break; + + case BLE_GAP_EVT_DISCONNECTED: + m_conn_handle = BLE_CONN_HANDLE_INVALID; + if (m_factory_reset) + { + (void)sd_nvic_SystemReset(); + } + break; + } +} + + +ret_code_t es_flash_init(void) +{ + ret_code_t err_code; + + m_num_pending_ops = 1; // Will be set to 0 when getting FDS_EVT_INIT event + + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + m_factory_reset = false; + + err_code = fds_register(fds_cb); + RETURN_IF_ERROR(err_code); + + err_code = fds_init(); + RETURN_IF_ERROR(err_code); + + return NRF_SUCCESS; +} + diff --git a/components/libraries/eddystone/es_flash.h b/components/libraries/eddystone/es_flash.h new file mode 100644 index 0000000..9e9eefe --- /dev/null +++ b/components/libraries/eddystone/es_flash.h @@ -0,0 +1,178 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_FLASH_H__ +#define ES_FLASH_H__ + +#include +#include +#include "es_slot.h" + + +/** + * @file + * @defgroup eddystone_flash Flash access + * @brief Types and functions to access the flash of the Eddystone beacon. + * @ingroup eddystone + * @{ + */ + +#define WORD_SIZE 4 + +#define FLASH_ACCES_ERROR_CHECK_ALLOW_NOT_FOUND(err_code) \ + if (err_code != (FDS_ERR_NOT_FOUND)) \ + APP_ERROR_CHECK(err_code); + +#define FLASH_OP_WAIT() \ + uint32_t pending_ops = es_flash_num_pending_ops(); \ + while (pending_ops != 0) \ + { \ + pending_ops = es_flash_num_pending_ops(); \ + } + +/**@brief Beacon configuration. */ +typedef struct +{ + nrf_ble_escs_adv_interval_t adv_interval; //!< Advertising interval. + bool remain_connectable; //!< Flag that specifies if the beacon should remain connectable. +} es_flash_beacon_config_t; + +/**@brief Structure for keeping track of which slot has a configuration that must be restored upon reboot. + * @details The size of this structure must be word aligned and match the flash block size of 32 bytes. + */ +typedef struct +{ + bool slot_is_empty[APP_MAX_ADV_SLOTS]; //!< Flag that indicates whether the slot is empty. + uint8_t padding[WORD_SIZE - ((APP_MAX_ADV_SLOTS + 1) % WORD_SIZE)]; //!< Padding used to ensure word alignment. +} es_flash_flags_t; + +/**@brief Flash access types. + */ +typedef enum +{ + ES_FLASH_ACCESS_READ, //!< Read data. + ES_FLASH_ACCESS_WRITE, //!< Write data. + ES_FLASH_ACCESS_CLEAR //!< Clear data. +} es_flash_access_t; + +/**@brief Function for accessing beacon configurations. + * + * @param[out,in] p_config Pointer to the beacon configuration buffer. + * @param[in] access_type Access type (see @ref es_flash_access_t). + * @return For possible return values, see: + * - @ref fds_record_find_by_key + * - @ref fds_record_open + * - @ref fds_record_close + * - @ref fds_record_write + * - @ref fds_record_update + * - @ref fds_record_delete + */ +ret_code_t es_flash_access_beacon_config(es_flash_beacon_config_t * p_config, + es_flash_access_t access_type); + +/**@brief Function for accessing slot configuration from flash. + * + * @param[in] slot_no Slot index. + * @param[out,in] p_slot Pointer to the slot configuration buffer. + * @param[in] access_type Access type (see @ref es_flash_access_t). + * @return For possible return values, see: + * - @ref fds_record_find_by_key + * - @ref fds_record_open + * - @ref fds_record_close + * - @ref fds_record_write + * - @ref fds_record_update + * - @ref fds_record_delete + */ +ret_code_t es_flash_access_slot_configs(uint8_t slot_no, + es_slot_t * p_slot, + es_flash_access_t access_type); + + +/**@brief Function for accessing the beacon lock key from flash. + * + * @param[out,in] p_lock_key Pointer to the lock key buffer. + * @param[in] access_type Access type (see @ref es_flash_access_t). + * @return For possible return values, see: + * - @ref fds_record_find_by_key + * - @ref fds_record_open + * - @ref fds_record_close + * - @ref fds_record_write + * - @ref fds_record_update + * - @ref fds_record_delete + */ +ret_code_t es_flash_access_lock_key(uint8_t * p_lock_key, es_flash_access_t access_type); + +/**@brief Function for accessing the flash configuration flag from flash. + * + * @param[out,in] p_flags Pointer to the flag buffer. + * @param[in] access_type Access type (see @ref es_flash_access_t). + * @return For possible return values, see: + * - @ref fds_record_find_by_key + * - @ref fds_record_open + * - @ref fds_record_close + * - @ref fds_record_write + * - @ref fds_record_update + * - @ref fds_record_delete + */ +ret_code_t es_flash_access_flags(es_flash_flags_t * p_flags, es_flash_access_t access_type); + +/**@brief Function for retrieving the number of queued operations. + * @return The number of operations that are queued. + */ +uint32_t es_flash_num_pending_ops(void); + +/**@brief Function for performing a factory reset. + * @return FDS return code. + */ +ret_code_t es_flash_factory_reset(void); + +void es_flash_on_ble_evt(ble_evt_t * p_evt); + +/**@brief Function for initializing the flash module. + * + * @return See @ref fds_init for possible return values. + */ +ret_code_t es_flash_init(void); + +/** + * @} + */ + +#endif // ES_FLASH_H__ diff --git a/components/libraries/eddystone/es_gatts.c b/components/libraries/eddystone/es_gatts.c new file mode 100644 index 0000000..a2a5b81 --- /dev/null +++ b/components/libraries/eddystone/es_gatts.c @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_gatts.h" +#include "es_gatts_read.h" +#include "es_gatts_write.h" +#include "es_slot.h" + +static nrf_ble_escs_lock_state_read_t m_lock_state; +static uint8_t m_active_slot; + +/**@brief Function checking if beacon is unlocked. + * + * @param[in] p_escs Pointer to Eddystone Configuration Service. + * + * @retval true If beacon is unlocked. + * @retval false If beacon is locked. + */ +static bool is_beacon_unlocked(const nrf_ble_escs_t * p_escs) +{ + return m_lock_state != NRF_BLE_ESCS_LOCK_STATE_LOCKED; +} + + +ret_code_t es_gatts_send_reply(nrf_ble_escs_t * p_escs, + ble_gatts_rw_authorize_reply_params_t * p_reply) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_reply); + + if (p_escs->conn_handle != BLE_CONN_HANDLE_INVALID) + { + return sd_ble_gatts_rw_authorize_reply(p_escs->conn_handle, p_reply); + } + + return NRF_ERROR_INVALID_STATE; +} + + +ret_code_t es_gatts_send_op_not_permitted(nrf_ble_escs_t * p_escs, bool read) +{ + ble_gatts_rw_authorize_reply_params_t reply = {0}; + + VERIFY_PARAM_NOT_NULL(p_escs); + + if (read) + { + reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; + reply.params.read.gatt_status = BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED; + } + + else + { + reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED; + } + + return es_gatts_send_reply(p_escs, &reply); +} + + + +void es_gatts_handle_write(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t * p_data, + uint16_t length) +{ + ret_code_t err_code; + + if (is_beacon_unlocked(p_escs)) + { + if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR) + { + err_code = es_gatts_send_op_not_permitted(p_escs, false); + APP_ERROR_CHECK(err_code); + } + + else + { + err_code = es_gatts_write_handle_unlocked_write( + p_escs, uuid, val_handle, p_data, length, m_active_slot); + APP_ERROR_CHECK(err_code); + } + } + + else + { + if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR) + { + err_code = es_gatts_write_handle_unlock(p_escs, p_data, length, val_handle); + APP_ERROR_CHECK(err_code); + } + + else + { + err_code = es_gatts_send_op_not_permitted(p_escs, false); + APP_ERROR_CHECK(err_code); + } + } +} + + +void es_gatts_handle_read(nrf_ble_escs_t * p_escs, uint16_t uuid, uint16_t val_handle) +{ + ret_code_t err_code; + + if (is_beacon_unlocked(p_escs)) + { + if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR) + { + err_code = es_gatts_send_op_not_permitted(p_escs, true); + APP_ERROR_CHECK(err_code); + } + + else + { + err_code = es_gatts_read_handle_unlocked_read(p_escs, uuid, val_handle, m_active_slot, m_lock_state); + APP_ERROR_CHECK(err_code); + } + } + + else // Beacon is locked. + { + if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR) + { + err_code = es_gatts_read_handle_unlock(p_escs); + APP_ERROR_CHECK(err_code); + } + + else + { + err_code = es_gatts_read_handle_locked_read(p_escs, uuid, m_lock_state); + APP_ERROR_CHECK(err_code); + } + } +} + + +ret_code_t es_gatts_init(nrf_ble_escs_t * p_ble_escs) +{ + VERIFY_PARAM_NOT_NULL(p_ble_escs); + + m_active_slot = 0; + m_lock_state = NRF_BLE_ESCS_LOCK_STATE_LOCKED; + + p_ble_escs->p_active_slot = &m_active_slot; + p_ble_escs->p_lock_state = &m_lock_state; + + return NRF_SUCCESS; +} diff --git a/components/libraries/eddystone/es_gatts.h b/components/libraries/eddystone/es_gatts.h new file mode 100644 index 0000000..760f40e --- /dev/null +++ b/components/libraries/eddystone/es_gatts.h @@ -0,0 +1,109 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_GATTS_H__ +#define ES_GATTS_H__ + +#include +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_gatts GATTS + * @brief Functions for handling GATTS write and read requests. + * @ingroup eddystone + * @{ + */ + +ret_code_t es_gatts_init(nrf_ble_escs_t * p_ble_escs); + +/**@brief Function for handling all write requests from the Central. + * + * @param[in] p_escs Pointer to the Eddystone Configuration Service. + * @param[in] uuid The UUID of the characteristic that is being written to. + * @param[in] val_handle Value handle field of the characteristic handle of the characteristic that is being written to. + * @param[in] p_data Pointer to the data to be written. + * @param[in] length Length of the data to be written. + * + */ +void es_gatts_handle_write(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t * p_data, + uint16_t length); + + +/**@brief Function for handling all read requests from the Central. + * + * @param[in] p_escs Pointer to the Eddystone Configuration Service. + * @param[in] uuid The UUID of the characteristic that is being read from. + * @param[in] val_handle Value handle field of the characteristic handle of the characteristic that is being read from. + * + */ +void es_gatts_handle_read(nrf_ble_escs_t * p_escs, uint16_t uuid, uint16_t val_handle); + +/**@brief Function for sending an RW-authorization reply. + * + * @param[in] p_escs Pointer to the Eddystone Configuration Service. + * @param[in] p_reply Pointer to the reply to send. + * + * @retval NRF_SUCCESS If the reply was successfully issued to the SoftDevice. + * @retval NRF_ERROR_NULL If either of the pointers @p p_escs or @p p_reply is NULL. + * @retval NRF_ERROR_INVALID_STATE If the connection handle of @p p_escs is invalid. + * @return Otherwise, an error code from sd_ble_gatts_rw_authorize_reply() is returned. + */ +ret_code_t es_gatts_send_reply(nrf_ble_escs_t * p_escs, ble_gatts_rw_authorize_reply_params_t * p_reply); + +/**@brief Function for sending an RW-authorization reply with status 'Operation not permitted'. + * + * @param[in] p_escs Pointer to the Eddystone Configuration Service. + * @param[in] op_is_read Flag that specifies if the operation being responded to is a 'read' operation. + If false, a 'write' operation is assumed. + * + * @retval NRF_ERROR_NULL If @p p_escs is NULL. + * @return Otherwise, the error code from es_gatts_send_reply() is returned. + */ +ret_code_t es_gatts_send_op_not_permitted(nrf_ble_escs_t * p_escs, bool op_is_read); + +/** + * @} + */ + +#endif // ES_GATTS_H__ diff --git a/components/libraries/eddystone/es_gatts_read.c b/components/libraries/eddystone/es_gatts_read.c new file mode 100644 index 0000000..80b2977 --- /dev/null +++ b/components/libraries/eddystone/es_gatts_read.c @@ -0,0 +1,246 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_gatts_read.h" +#include "es_adv.h" +#include "es_gatts.h" +#include "es_security.h" +#include "es_slot.h" + +static ret_code_t send_read_reply(nrf_ble_escs_t * p_escs, ble_gatts_rw_authorize_reply_params_t * p_reply) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_reply); + + p_reply->type = BLE_GATTS_AUTHORIZE_TYPE_READ; + p_reply->params.read.update = 1; + p_reply->params.read.offset = 0; + + return es_gatts_send_reply(p_escs, p_reply); +} + + +static ret_code_t read_value(nrf_ble_escs_t * p_escs, uint8_t length, const void * p_value) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_value); + + ble_gatts_rw_authorize_reply_params_t reply = {0}; + reply.params.read.len = length; + reply.params.read.p_data = p_value; + reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS; + + return send_read_reply(p_escs, &reply); +} + + +static ret_code_t read_from_gattdb(nrf_ble_escs_t * p_escs, uint16_t val_handle) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + + ret_code_t err_code; + + // Go straight to the characteristic + uint8_t value_buffer[ESCS_ADV_SLOT_CHAR_LENGTH_MAX] = {0}; + ble_gatts_value_t value = {.len = sizeof(value_buffer), + .offset = 0, + .p_value = &(value_buffer[0])}; + + err_code = sd_ble_gatts_value_get(p_escs->conn_handle, val_handle, &value); + RETURN_IF_ERROR(err_code); + + return read_value(p_escs, value.len, value.p_value); +} + + +static ret_code_t read_adv_slot(nrf_ble_escs_t * p_escs, uint8_t active_slot, const es_slot_reg_t * p_reg) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + + ble_gatts_rw_authorize_reply_params_t reply = {0}; + uint8_t eid_buf[14]; + + // If an EID slot is read, load scaler, clock value and ephemeral ID. + if (p_reg->slots[active_slot].adv_frame.type == ES_FRAME_TYPE_EID) + { + /*lint -save -e666 */ + uint32_t clock_value = es_security_clock_get(active_slot); + clock_value = BYTES_REVERSE_32BIT(clock_value); + /*lint -restore */ + + reply.params.read.len = ES_EID_GATTS_READ_LENGTH; + + // Fill EID buffer with data + eid_buf[ES_EID_GATTS_READ_FRAME_TYPE_IDX] = ES_FRAME_TYPE_EID; + eid_buf[ES_EID_GATTS_READ_EXPONENT_IDX] = es_security_scaler_get(active_slot); + + memcpy(&eid_buf[ES_EID_GATTS_READ_CLCK_VALUE_IDX], &clock_value, sizeof(clock_value)); + /*lint -save -e545 */ + memcpy(&eid_buf[ES_EID_GATTS_READ_EID_IDX], + &p_reg->slots[active_slot].adv_frame.frame.eid.eid, + ES_EID_ID_LENGTH); + /*lint -restore */ + reply.params.read.p_data = eid_buf; + } + + // Otherwise, simply load the contents of the frame. + else + { + // Check if slot being read is an eTLM slot. + if ((p_reg->num_configured_eid_slots > 0) && p_reg->tlm_configured && (p_reg->tlm_slot == active_slot)) + { + // Fill eTLM slot using EID key from first EID slot. + es_slot_etlm_update(p_reg->eid_slots_configured[0]); + } + reply.params.read.len = p_reg->slots[active_slot].adv_frame.length; + reply.params.read.p_data = (uint8_t *)&p_reg->slots[active_slot].adv_frame.frame; + } + + reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS; + + return send_read_reply(p_escs, &reply); +} + + +ret_code_t es_gatts_read_handle_locked_read(nrf_ble_escs_t * p_escs, uint16_t uuid, uint8_t lock_state) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + + if (uuid == BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR) + { + uint8_t retval = APP_IS_REMAIN_CONNECTABLE_SUPPORTED; + return read_value(p_escs, sizeof(retval), &retval); + } + + else if (uuid == BLE_UUID_ESCS_LOCK_STATE_CHAR) + { + return read_value(p_escs, sizeof(lock_state), &lock_state); + } + + else + { + return es_gatts_send_op_not_permitted(p_escs, true); + } +} + + +ret_code_t es_gatts_read_handle_unlock(nrf_ble_escs_t * p_escs) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + + ret_code_t err_code; + uint8_t key_buff[ESCS_AES_KEY_SIZE]; + + err_code = es_security_random_challenge_generate(key_buff); + RETURN_IF_ERROR(err_code); + + es_security_unlock_prepare(key_buff); + + return read_value(p_escs, ESCS_AES_KEY_SIZE, key_buff); +} + + +ret_code_t es_gatts_read_handle_unlocked_read(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t active_slot, + uint8_t lock_state) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + switch (uuid) + { + case BLE_UUID_ESCS_BROADCAST_CAP_CHAR: + case BLE_UUID_ESCS_UNLOCK_CHAR: + case BLE_UUID_ESCS_PUBLIC_ECDH_KEY_CHAR: + case BLE_UUID_ESCS_ACTIVE_SLOT_CHAR: + return read_from_gattdb(p_escs, val_handle); + + case BLE_UUID_ESCS_LOCK_STATE_CHAR: + return read_value(p_escs, sizeof(lock_state), &lock_state); + + case BLE_UUID_ESCS_ADV_INTERVAL_CHAR: + { + nrf_ble_escs_adv_interval_t adv_interval = es_adv_interval_get(); + adv_interval = BYTES_SWAP_16BIT(adv_interval); + return read_value(p_escs, sizeof(adv_interval), &adv_interval); + } + + case BLE_UUID_ESCS_RADIO_TX_PWR_CHAR: + return read_value(p_escs, + sizeof(nrf_ble_escs_radio_tx_pwr_t), + &p_reg->slots[active_slot].radio_tx_pwr); + + case BLE_UUID_ESCS_ADV_TX_PWR_CHAR: + return read_value(p_escs, + sizeof(nrf_ble_escs_radio_tx_pwr_t), + p_reg->slots[active_slot].adv_custom_tx_power + ? (uint8_t *)(&p_reg->slots[active_slot].custom_tx_power) + : (uint8_t *)(&p_reg->slots[active_slot].radio_tx_pwr)); + + case BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR: + { + uint8_t retval = APP_IS_REMAIN_CONNECTABLE_SUPPORTED; + return read_value(p_escs, sizeof(retval), &retval); + } + + case BLE_UUID_ESCS_EID_ID_KEY_CHAR: + if (p_reg->slots[active_slot].configured && + (p_reg->slots[active_slot].adv_frame.type == ES_FRAME_TYPE_EID)) + { + return read_value(p_escs, + sizeof(nrf_ble_escs_eid_id_key_t), + &p_reg->slots[active_slot].encrypted_eid_id_key); + } + + else + { + return es_gatts_send_op_not_permitted(p_escs, true); + } + + case BLE_UUID_ESCS_RW_ADV_SLOT_CHAR: + return read_adv_slot(p_escs, active_slot, p_reg); + + default: + return NRF_ERROR_INVALID_PARAM; + } +} diff --git a/components/libraries/eddystone/es_gatts_read.h b/components/libraries/eddystone/es_gatts_read.h new file mode 100644 index 0000000..bacd519 --- /dev/null +++ b/components/libraries/eddystone/es_gatts_read.h @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_GATTS_READ_H__ +#define ES_GATTS_READ_H__ + +#include +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_gatts_read GATTS read + * @brief Functions for handling GATTS read requests. + * @ingroup eddystone_gatts + * @{ + */ + +ret_code_t es_gatts_read_send_not_permitted(nrf_ble_escs_t * p_escs); + +ret_code_t es_gatts_read_handle_unlocked_read(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t active_slot, + uint8_t lock_state); + +ret_code_t es_gatts_read_handle_unlock(nrf_ble_escs_t * p_escs); + +ret_code_t es_gatts_read_handle_locked_read(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint8_t lock_state); + +/** + * @} + */ + +#endif // ES_GATTS_READ_H__ diff --git a/components/libraries/eddystone/es_gatts_write.c b/components/libraries/eddystone/es_gatts_write.c new file mode 100644 index 0000000..986e388 --- /dev/null +++ b/components/libraries/eddystone/es_gatts_write.c @@ -0,0 +1,254 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_gatts_write.h" +#include "es_adv.h" +#include "es_flash.h" +#include "es_gatts.h" +#include "es_security.h" + + +static ret_code_t send_write_reply(nrf_ble_escs_t * p_escs, ble_gatts_rw_authorize_reply_params_t * p_reply) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_reply); + + p_reply->type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; + p_reply->params.write.update = 1; + p_reply->params.write.offset = 0; + + return es_gatts_send_reply(p_escs, p_reply); +} + + +/**@brief Function checking if length of event is correct, given the frame data. + * + * @param[in] p_data Written ADV Slot data. + * @param[in] length Written length. + * + * @retval true If length is valid. + * @retval false If length is not valid. + */ +static bool length_is_valid(uint8_t * p_data, uint8_t length) +{ + if (length == 0 || (length == 1 && p_data[0] == 0)) + { + return true; + } + + else + { + switch ((es_frame_type_t)p_data[0]) + { + case ES_FRAME_TYPE_UID: + return length == ESCS_UID_WRITE_LENGTH; + + case ES_FRAME_TYPE_URL: + return ((length >= ESCS_URL_MIN_WRITE_LENGTH) && (length <= ESCS_URL_WRITE_LENGTH)); + + case ES_FRAME_TYPE_TLM: + return (length == ESCS_TLM_WRITE_LENGTH); + + case ES_FRAME_TYPE_EID: + return ((length == ESCS_EID_WRITE_ECDH_LENGTH) || + (length == ESCS_EID_WRITE_IDK_LENGTH)); + + default: + return false; + } + } +} + + +ret_code_t es_gatts_write_handle_unlocked_write(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t * p_data, + uint16_t length, + uint8_t active_slot) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_data); + + ret_code_t err_code; + ble_gatts_rw_authorize_reply_params_t reply = {0}; + bool long_write = false; + + reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + + switch (uuid) + { + case BLE_UUID_ESCS_ACTIVE_SLOT_CHAR: + if (*p_data > APP_MAX_ADV_SLOTS - 1) + { + // Invalid Attribute Length: for an attempt to write illegal values. + // The beacon will list the total number of available slots in the + // max_supported_total_slots field in the Capabilities characteristic. + reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH; + length = 0; + } + break; + + case BLE_UUID_ESCS_ADV_INTERVAL_CHAR: + es_adv_interval_set(BYTES_SWAP_16BIT(*(nrf_ble_escs_adv_interval_t *)p_data)); + break; + + case BLE_UUID_ESCS_RADIO_TX_PWR_CHAR: + es_slot_radio_tx_pwr_set(active_slot, *(nrf_ble_escs_radio_tx_pwr_t *)(p_data)); + break; + + case BLE_UUID_ESCS_ADV_TX_PWR_CHAR: + // Update slot info so that ADV data will only be read from what is written by client. + es_slot_set_adv_custom_tx_power(active_slot, *(nrf_ble_escs_radio_tx_pwr_t *)(p_data)); + break; + + case BLE_UUID_ESCS_LOCK_STATE_CHAR: + if (length == 1 && (*p_data == NRF_BLE_ESCS_LOCK_BYTE_LOCK || + *p_data == NRF_BLE_ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK)) + { + // Do nothing special, allow the write. + } + else if (length == ESCS_LOCK_STATE_NEW_LOCK_CODE_WRITE_LENGTH && + *p_data == NRF_BLE_ESCS_LOCK_BYTE_LOCK) + { + // 0x00 + key[16] : transition to lock state and update the lock code. + err_code = es_security_lock_code_update((p_data) + 1); + RETURN_IF_ERROR(err_code); + + // Only write the lock byte (0x00) to the characteristic, so set length to 1. + length = 1; + } + else + { + // Any invalid values locks the characteristic by default. + *p_data = NRF_BLE_ESCS_LOCK_BYTE_LOCK; + length = 1; + } + break; + + case BLE_UUID_ESCS_RW_ADV_SLOT_CHAR: + if (length > 20) + { + long_write = true; + } + reply.params.write.gatt_status = length_is_valid(p_data, length) + ? BLE_GATT_STATUS_SUCCESS + : BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH; + + if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) + { + es_slot_on_write(active_slot, length, p_data); + es_adv_interval_set(es_adv_interval_get()); // Ensure that valid advertisement interval is used. + } + break; + + case BLE_UUID_ESCS_FACTORY_RESET_CHAR: + if (*p_data == 0x0B) + { + err_code = es_flash_factory_reset(); + RETURN_IF_ERROR(err_code); + } + break; + + case BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR: +#if APP_IS_REMAIN_CONNECTABLE_SUPPORTED == ESCS_FUNCT_REMAIN_CONNECTABLE_SUPPORTED_Yes + if (*p_data != 0) + { + es_adv_remain_connectable_set(true); + } + + else + { + es_adv_remain_connectable_set(false); + } +#endif + break; + + default: + break; + } + reply.params.write.len = length; + reply.params.write.p_data = p_data; + + if (!long_write) + { + return send_write_reply(p_escs, &reply); + } + + else + { + return NRF_SUCCESS; + } +} + + +ret_code_t es_gatts_write_handle_unlock(nrf_ble_escs_t * p_escs, + uint8_t * p_data, + uint16_t length, + uint16_t val_handle) +{ + VERIFY_PARAM_NOT_NULL(p_escs); + VERIFY_PARAM_NOT_NULL(p_data); + + ret_code_t err_code; + ble_gatts_rw_authorize_reply_params_t reply = {0}; + ble_gatts_value_t value = {.len = length, .offset = 0, .p_value = p_data}; + + if (length == ESCS_AES_KEY_SIZE) + { + err_code = sd_ble_gatts_value_set(p_escs->conn_handle, val_handle, &value); + + if (err_code == NRF_SUCCESS) + { + reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS; + es_security_unlock_verify((value.p_value)); + } + + else + { + reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED; + } + } + + reply.params.write.len = length; + reply.params.write.p_data = (const uint8_t *)value.p_value; + + return send_write_reply(p_escs, &reply); +} diff --git a/components/libraries/eddystone/es_gatts_write.h b/components/libraries/eddystone/es_gatts_write.h new file mode 100644 index 0000000..fc69b9e --- /dev/null +++ b/components/libraries/eddystone/es_gatts_write.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_GATTS_WRITE_H__ +#define ES_GATTS_WRITE_H__ + +#include +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_gatts_write GATTS write + * @brief Functions for handling GATTS write requests. + * @ingroup eddystone_gatts + * @{ + */ + +ret_code_t es_gatts_write_handle_unlocked_write(nrf_ble_escs_t * p_escs, + uint16_t uuid, + uint16_t val_handle, + uint8_t * p_data, + uint16_t length, + uint8_t active_slot); + +ret_code_t es_gatts_write_handle_unlock(nrf_ble_escs_t * p_escs, + uint8_t * p_data, + uint16_t length, + uint16_t val_handle); + +/** + * @} + */ + +#endif // ES_GATTS_WRITE_H__ diff --git a/components/libraries/eddystone/es_security.c b/components/libraries/eddystone/es_security.c new file mode 100644 index 0000000..899efbf --- /dev/null +++ b/components/libraries/eddystone/es_security.c @@ -0,0 +1,531 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "es_security.h" +#include "aes.h" +#include "app_timer.h" +#include "cifra_eax_aes.h" +#include "es_flash.h" +#include "es_stopwatch.h" +#include "fds.h" +#include "modes.h" +#include "occ_curve25519.h" +#include "occ_hmac_sha256.h" + +#define TK_ROLLOVER 0x10000 + +#define NONCE_SIZE (6) +#define TAG_SIZE (2) +#define SALT_SIZE (2) +#define TLM_DATA_SIZE (ES_TLM_LENGTH - 2) +#define EIK_SIZE (ESCS_AES_KEY_SIZE) + +/**@brief Timing structure. */ +typedef struct +{ + uint32_t time_counter; + uint8_t k_scaler; +} es_security_timing_t; + +/**@brief Security slot structure. */ +typedef struct +{ + nrf_ecb_hal_data_t aes_ecb_ik; + nrf_ecb_hal_data_t aes_ecb_tk; + uint8_t eid[ES_EID_ID_LENGTH]; + es_security_timing_t timing; + bool is_occupied; +} es_security_slot_t; + +/**@brief Key pair structure. */ +typedef struct +{ + uint8_t private[ESCS_ECDH_KEY_SIZE]; + uint8_t public[ESCS_ECDH_KEY_SIZE]; +} ecdh_key_pair_t; + +/**@brief ECDH structure. */ +typedef struct +{ + ecdh_key_pair_t ecdh_key_pair; +} es_security_ecdh_t; + +static nrf_ecb_hal_data_t m_aes_ecb_lk; +static es_security_slot_t m_security_slot[APP_MAX_EID_SLOTS]; +static es_security_ecdh_t m_ecdh; +static es_security_msg_cb_t m_security_callback; +static es_stopwatch_id_t m_seconds_passed_sw_id; + +/**@brief Generates a EID with the Temporary Key*/ +static void eid_generate(uint8_t slot_no) +{ + memset(m_security_slot[slot_no].aes_ecb_tk.cleartext, 0, ESCS_AES_KEY_SIZE); + m_security_slot[slot_no].aes_ecb_tk.cleartext[11] = m_security_slot[slot_no].timing.k_scaler; + + uint32_t k_bits_cleared_time = + (m_security_slot[slot_no].timing.time_counter >> m_security_slot[slot_no].timing.k_scaler) + << m_security_slot[slot_no].timing.k_scaler; + + m_security_slot[slot_no].aes_ecb_tk.cleartext[12] = + (uint8_t)((k_bits_cleared_time >> 24) & 0xff); + m_security_slot[slot_no].aes_ecb_tk.cleartext[13] = + (uint8_t)((k_bits_cleared_time >> 16) & 0xff); + m_security_slot[slot_no].aes_ecb_tk.cleartext[14] = (uint8_t)((k_bits_cleared_time >> 8) & 0xff); + m_security_slot[slot_no].aes_ecb_tk.cleartext[15] = (uint8_t)((k_bits_cleared_time) & 0xff); + + AES128_ECB_encrypt(m_security_slot[slot_no].aes_ecb_tk.cleartext, + m_security_slot[slot_no].aes_ecb_tk.key, + m_security_slot[slot_no].aes_ecb_tk.ciphertext); + + memcpy(m_security_slot[slot_no].eid, + m_security_slot[slot_no].aes_ecb_tk.ciphertext, + ES_EID_ID_LENGTH); + + m_security_callback(slot_no, ES_SECURITY_MSG_EID); +} + + +/**@brief Generates a temporary key with the Identity key. */ +static void temp_key_generate(uint8_t slot_no) +{ + memset(m_security_slot[slot_no].aes_ecb_ik.cleartext, 0, ESCS_AES_KEY_SIZE); + m_security_slot[slot_no].aes_ecb_ik.cleartext[11] = 0xFF; + m_security_slot[slot_no].aes_ecb_ik.cleartext[14] = + (uint8_t)((m_security_slot[slot_no].timing.time_counter >> 24) & 0xff); + m_security_slot[slot_no].aes_ecb_ik.cleartext[15] = + (uint8_t)((m_security_slot[slot_no].timing.time_counter >> 16) & 0xff); + + AES128_ECB_encrypt(m_security_slot[slot_no].aes_ecb_ik.cleartext, + m_security_slot[slot_no].aes_ecb_ik.key, + m_security_slot[slot_no].aes_ecb_ik.ciphertext); + + memcpy(m_security_slot[slot_no].aes_ecb_tk.key, + m_security_slot[slot_no].aes_ecb_ik.ciphertext, + ESCS_AES_KEY_SIZE); +} + + +static void check_rollovers_and_update_eid(uint8_t slot_no) +{ + if (m_security_slot[slot_no].timing.time_counter % TK_ROLLOVER == 0) + { + temp_key_generate(slot_no); + } + /*lint -save -e573 */ + if ((m_security_slot[slot_no].timing.time_counter % + (2 << (m_security_slot[slot_no].timing.k_scaler - 1))) == 0) + { + eid_generate(slot_no); + } + /*lint -restore */ +} + + +/**@brief Initialize lock code from flash. If it does not exist, copy from APP_CONFIG_LOCK_CODE. + */ +static void lock_code_init(uint8_t * p_lock_buff) +{ + ret_code_t err_code; + + err_code = es_flash_access_lock_key(p_lock_buff, ES_FLASH_ACCESS_READ); + FLASH_ACCES_ERROR_CHECK_ALLOW_NOT_FOUND(err_code); + + // If no lock keys exist, then generate one and copy it to buffer. + if (err_code == FDS_ERR_NOT_FOUND) + { + uint8_t lock_code[16] = APP_CONFIG_LOCK_CODE; + + memcpy(p_lock_buff, lock_code, sizeof(lock_code)); + + err_code = es_flash_access_lock_key(p_lock_buff, ES_FLASH_ACCESS_WRITE); + APP_ERROR_CHECK(err_code); + } +} + + +/**@brief Generates a the private/public ECDH key pair. + * + * @param[out] p_priv_buffer buffer of size 32 bytes to hold the private key. + * @param[out] p_pub_buffer buffer of size 32 bytes to hold the public key. + */ +static void es_beacon_ecdh_pair_generate(uint8_t * p_priv_buffer, uint8_t * p_pub_buffer) +{ + // Generate random beacon private key. + uint8_t pool_size; + uint8_t bytes_available; + + (void)sd_rand_application_pool_capacity_get(&pool_size); + (void)sd_rand_application_bytes_available_get(&bytes_available); + + while (bytes_available < pool_size) + { + // wait for SD to acquire enough RNs. + (void)sd_rand_application_bytes_available_get(&bytes_available); + } + + (void)sd_rand_application_vector_get(p_priv_buffer, pool_size); + + if (pool_size < ESCS_ECDH_KEY_SIZE) + { + (void)sd_rand_application_bytes_available_get(&bytes_available); + + while (bytes_available < (ESCS_ECDH_KEY_SIZE - pool_size)) + { + // Wait for SD to acquire enough RNs. + (void)sd_rand_application_bytes_available_get(&bytes_available); + } + (void)sd_rand_application_vector_get(p_priv_buffer + pool_size, + ESCS_ECDH_KEY_SIZE - pool_size); + } + + // Create beacon public 32-byte ECDH key from private 32-byte ECDH key. + occ_curve25519_scalarmult_base(p_pub_buffer, p_priv_buffer); +} + + +void es_security_update_time(void) +{ + static uint32_t timer_persist; + uint32_t second_since_last_invocation = es_stopwatch_check(m_seconds_passed_sw_id); + + if (second_since_last_invocation > 0) + { + for (uint32_t i = 0; i < APP_MAX_EID_SLOTS; ++i) + { + if (m_security_slot[i].is_occupied) + { + m_security_slot[i].timing.time_counter += second_since_last_invocation; + check_rollovers_and_update_eid(i); + } + } + + // Every 24 hr, write the new EID timer to flash. + timer_persist += second_since_last_invocation; + const uint32_t TWENTY_FOUR_HOURS = 60 * 60 * 24; + if (timer_persist >= TWENTY_FOUR_HOURS) + { + for (uint32_t i = 0; i < APP_MAX_EID_SLOTS; ++i) + { + if (m_security_slot[i].is_occupied) + { + m_security_callback(i, ES_SECURITY_MSG_STORE_TIME); + } + } + timer_persist = 0; + } + } +} + + +void es_security_eid_slots_restore(uint8_t slot_no, + uint8_t k_scaler, + uint32_t time_counter, + const uint8_t * p_ik) +{ + m_security_slot[slot_no].timing.k_scaler = k_scaler; + m_security_slot[slot_no].timing.time_counter = time_counter; + memcpy(m_security_slot[slot_no].aes_ecb_ik.key, p_ik, ESCS_AES_KEY_SIZE); + m_security_slot[slot_no].is_occupied = true; + m_security_callback(slot_no, ES_SECURITY_MSG_IK); + temp_key_generate(slot_no); + eid_generate(slot_no); +} + + +ret_code_t es_security_lock_code_update(uint8_t * p_ecrypted_key) +{ + uint8_t temp_buff[ESCS_AES_KEY_SIZE] = {0}; + + AES128_ECB_decrypt(p_ecrypted_key, m_aes_ecb_lk.key, temp_buff); + + memcpy(m_aes_ecb_lk.key, temp_buff, ESCS_AES_KEY_SIZE); + return es_flash_access_lock_key(m_aes_ecb_lk.key, ES_FLASH_ACCESS_WRITE); +} + + +void es_security_unlock_prepare(uint8_t * p_challenge) +{ + memcpy(m_aes_ecb_lk.cleartext, p_challenge, ESCS_AES_KEY_SIZE); + AES128_ECB_encrypt(m_aes_ecb_lk.cleartext, m_aes_ecb_lk.key, m_aes_ecb_lk.ciphertext); +} + + +void es_security_unlock_verify(uint8_t * p_unlock_token) +{ + if (memcmp(p_unlock_token, m_aes_ecb_lk.ciphertext, ESCS_AES_KEY_SIZE) == 0) + { + m_security_callback(0, ES_SECURITY_MSG_UNLOCKED); + } +} + + +ret_code_t es_security_random_challenge_generate(uint8_t * p_rand_chlg_buff) +{ + return sd_rand_application_vector_get(p_rand_chlg_buff, ESCS_AES_KEY_SIZE); +} + + +void es_security_shared_ik_receive(uint8_t slot_no, uint8_t * p_encrypted_ik, uint8_t scaler_k) +{ + m_security_slot[slot_no].is_occupied = true; + m_security_slot[slot_no].timing.k_scaler = scaler_k; + m_security_slot[slot_no].timing.time_counter = APP_CONFIG_TIMING_INIT_VALUE; + + AES128_ECB_decrypt(p_encrypted_ik, m_aes_ecb_lk.key, m_security_slot[slot_no].aes_ecb_ik.key); + + temp_key_generate(slot_no); + eid_generate(slot_no); + + m_security_callback(slot_no, ES_SECURITY_MSG_IK); +} + + +void es_security_client_pub_ecdh_receive(uint8_t slot_no, uint8_t * p_pub_ecdh, uint8_t scaler_k) +{ + static uint8_t attempt_counter = 0; + + m_security_slot[slot_no].is_occupied = true; + m_security_slot[slot_no].timing.k_scaler = scaler_k; + m_security_slot[slot_no].timing.time_counter = APP_CONFIG_TIMING_INIT_VALUE; + + uint8_t beacon_private[ESCS_ECDH_KEY_SIZE]; // Beacon private ECDH key + uint8_t beacon_public[ESCS_ECDH_KEY_SIZE]; // Beacon public ECDH key + uint8_t phone_public[ESCS_ECDH_KEY_SIZE]; // Phone public ECDH key + uint8_t shared[ESCS_ECDH_KEY_SIZE]; // Shared secret ECDH key + const uint8_t salt[1] = {0x01}; // Salt + uint8_t identity_key[ESCS_AES_KEY_SIZE]; // Identity Key + + // Get public 32-byte service ECDH key from phone. + memcpy(phone_public, p_pub_ecdh, ESCS_ECDH_KEY_SIZE); + + // Generate new set of keys for use with this EID slot. + es_beacon_ecdh_pair_generate(beacon_private, beacon_public); + memcpy(m_ecdh.ecdh_key_pair.private, beacon_private, ESCS_ECDH_KEY_SIZE); + memcpy(m_ecdh.ecdh_key_pair.public, beacon_public, ESCS_ECDH_KEY_SIZE); + + // Generate shared 32-byte ECDH secret from beacon private service ECDH key and phone public ECDH key. + occ_curve25519_scalarmult(shared, beacon_private, phone_public); + + // Generate key material using shared ECDH secret as salt and public_keys as key material. RFC 2104 HMAC-SHA256. + uint8_t digest[64]; + uint8_t public_keys[64]; + memcpy(public_keys, phone_public, 32); + memcpy(public_keys + 32, beacon_public, 32); + + occ_hmac_sha256(digest, public_keys, 64, shared, 32); + + // Zero check of the shared secret becoming zero, try generating a new key pair if so. Max attempt limit twice. + uint8_t empty_check[32] = {0}; + + if (memcmp(empty_check, shared, 32) == 0) + { + if (attempt_counter < 2) + { + attempt_counter++; + es_beacon_ecdh_pair_generate(beacon_private, beacon_public); + } + } + else + { + attempt_counter = 0; + } + + // Generate 16-byte Identity Key from shared ECDH secret using RFC 2104 HMAC-SHA256 and salt. + uint8_t digest_salted[64]; + occ_hmac_sha256(digest_salted, digest, 32, salt, 1); + + memcpy(identity_key, digest_salted, ESCS_AES_KEY_SIZE); + + memcpy(m_security_slot[slot_no].aes_ecb_ik.key, identity_key, ESCS_AES_KEY_SIZE); + + temp_key_generate(slot_no); + eid_generate(slot_no); + + m_security_callback(slot_no, ES_SECURITY_MSG_ECDH); + m_security_callback(slot_no, ES_SECURITY_MSG_IK); +} + + +void es_security_pub_ecdh_get(uint8_t slot_no, uint8_t * p_edch_buffer) +{ + memcpy(p_edch_buffer, m_ecdh.ecdh_key_pair.public, ESCS_ECDH_KEY_SIZE); +} + + +uint32_t es_security_clock_get(uint8_t slot_no) +{ + return m_security_slot[slot_no].timing.time_counter; +} + + +void es_security_eid_slot_destroy(uint8_t slot_no) +{ + memset(&m_security_slot[slot_no], 0, sizeof(es_security_slot_t)); +} + + +uint8_t es_security_scaler_get(uint8_t slot_no) +{ + return m_security_slot[slot_no].timing.k_scaler; +} + + +void es_security_eid_get(uint8_t slot_no, uint8_t * p_eid_buffer) +{ + memcpy(p_eid_buffer, m_security_slot[slot_no].eid, ES_EID_ID_LENGTH); +} + + +void es_security_encrypted_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer) +{ + memcpy(m_aes_ecb_lk.cleartext, m_security_slot[slot_no].aes_ecb_ik.key, ESCS_AES_KEY_SIZE); + AES128_ECB_encrypt(m_aes_ecb_lk.cleartext, m_aes_ecb_lk.key, m_aes_ecb_lk.ciphertext); + memcpy(p_key_buffer, m_aes_ecb_lk.ciphertext, ESCS_AES_KEY_SIZE); +} + + +void es_security_plain_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer) +{ + memcpy(p_key_buffer, m_security_slot[slot_no].aes_ecb_ik.key, ESCS_AES_KEY_SIZE); +} + + +void es_security_tlm_to_etlm(uint8_t ik_slot_no, es_tlm_frame_t * p_tlm, es_etlm_frame_t * p_etlm) +{ + cf_prp prp; // Describe the block cipher to use. + + uint8_t plain[TLM_DATA_SIZE] = {0}; // Plaintext tlm, without the frame byte and version. + size_t nplain = TLM_DATA_SIZE; // Length of message plaintext. + + /*lint -save -e420 */ + memcpy(plain, &p_tlm->vbatt[0], sizeof(plain)); + + const uint8_t header = 0; // Additionally authenticated data (AAD). + size_t nheader = 0; // Length of header (AAD). May be zero. + + uint8_t key[EIK_SIZE] = {0}; // Encryption/decryption key: EIK. + size_t nkey = EIK_SIZE; // Length of encryption/decryption key. + + memcpy(key, &m_security_slot[ik_slot_no].aes_ecb_ik.key[0], EIK_SIZE); + /*lint -restore */ + + uint8_t nonce[NONCE_SIZE] = {0}; // Nonce. This must not repeat for a given key. + size_t nnonce = NONCE_SIZE; // Length of nonce.First 4 bytes are beacon time base with k-bits cleared. + // Last two bits are randomly generated + + // Take the current timestamp and clear the lowest K bits, use it as nonce. + uint32_t k_bits_cleared_time = (m_security_slot[ik_slot_no].timing.time_counter + >> m_security_slot[ik_slot_no].timing.k_scaler) + << m_security_slot[ik_slot_no].timing.k_scaler; + + + nonce[0] = (uint8_t)((k_bits_cleared_time >> 24) & 0xff); + nonce[1] = (uint8_t)((k_bits_cleared_time >> 16) & 0xff); + nonce[2] = (uint8_t)((k_bits_cleared_time >> 8) & 0xff); + nonce[3] = (uint8_t)((k_bits_cleared_time) & 0xff); + + // Generate random salt. + uint8_t salt[SALT_SIZE] = {0}; + (void)sd_rand_application_vector_get(salt, SALT_SIZE); + memcpy(&nonce[4], salt, SALT_SIZE); + + uint8_t cipher[ES_ETLM_ECRYPTED_LENGTH]; // Ciphertext output. nplain bytes are written. + uint8_t tag[TAG_SIZE] = {0}; // Authentication tag. ntag bytes are written. + size_t ntag = TAG_SIZE; // Length of authentication tag. + + // Encryption + // -------------------------------------------------------------------------- + cf_aes_context ctx; + cf_aes_init(&ctx, key, nkey); + + prp.encrypt = (cf_prp_block)cf_aes_encrypt; // Encryption context + prp.decrypt = (cf_prp_block)cf_aes_decrypt; // Decryption context + prp.blocksz = ESCS_AES_KEY_SIZE; + + cf_eax_encrypt(&prp, + &ctx, + plain, // Plaintext input, aka TLM + nplain, // Length of TLM + &header, // Empty + nheader, // Empty + nonce, // Nonce input + nnonce, // Length of nonce + cipher, // Encrypted output + tag, // Authentication tag output + ntag // Length of authentication tag + ); + + // Construct the eTLM. + // -------------------------------------------------------------------------- + p_etlm->frame_type = p_tlm->frame_type; + p_etlm->version = ES_TLM_VERSION_ETLM; + memcpy(p_etlm->encrypted_tlm, cipher, ES_ETLM_ECRYPTED_LENGTH); + memcpy((uint8_t *)&p_etlm->random_salt, salt, SALT_SIZE); + memcpy((uint8_t *)&p_etlm->msg_integrity_check, tag, TAG_SIZE); +} + + +ret_code_t es_security_init(es_security_msg_cb_t security_callback) +{ + ret_code_t err_code; + + if (security_callback == NULL) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Get lock code from 'es_app_config.h', or fetch it from flash if exists. + lock_code_init(m_aes_ecb_lk.key); + + m_security_callback = security_callback; + + memset(&m_ecdh, 0, sizeof(es_security_ecdh_t)); + + for (uint32_t i = 0; i < APP_MAX_EID_SLOTS; ++i) + { + m_security_slot[i].timing.time_counter = APP_CONFIG_TIMING_INIT_VALUE; + } + err_code = es_stopwatch_create(&m_seconds_passed_sw_id, APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER)); + APP_ERROR_CHECK(err_code); + + return NRF_SUCCESS; +} diff --git a/components/libraries/eddystone/es_security.h b/components/libraries/eddystone/es_security.h new file mode 100644 index 0000000..51032fe --- /dev/null +++ b/components/libraries/eddystone/es_security.h @@ -0,0 +1,239 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_SECURITY_H__ +#define ES_SECURITY_H__ + +#include "app_error.h" +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_security Security + * @brief Types and functions for dealing with security of Eddystone beacons. + * @ingroup eddystone + * @{ + */ + +/**@brief Security events. + */ +typedef enum +{ + ES_SECURITY_MSG_UNLOCKED, //!< Beacon is unlocked. + ES_SECURITY_MSG_EID, //!< EID has been generated. + ES_SECURITY_MSG_IK, //!< IK has been generated. + ES_SECURITY_MSG_ECDH, //!< Public ECDH has been generated. + ES_SECURITY_MSG_STORE_TIME //!< EID slot time must be stored. +} es_security_msg_t; + +/* @brief Callback for security events. */ +typedef void (*es_security_msg_cb_t)(uint8_t slot_no, es_security_msg_t msg_type); + +/**@brief EID configuration. + * + * @details This structure is used to preserve or restore an EID slot. + * + * @note This is a packed structure. Therefore, you should not change it. +*/ +typedef PACKED_STRUCT +{ + es_frame_type_t frame_type; + uint8_t k_scaler; + uint32_t time_counter; + uint8_t ik[ESCS_AES_KEY_SIZE]; +} es_eid_config_t; + +/**@brief Eddystone beacon lock state. + */ +typedef nrf_ble_escs_lock_state_read_t es_security_lock_state_t; + +/**@brief Function for initializing the security module. + * + * @param[in] msg_cb Callback function. + * + * @return See @ref app_timer_start for possible return values. + */ +ret_code_t es_security_init(es_security_msg_cb_t msg_cb); + +/**@brief Function for updating the lock code and storing it to flash. + * + * @param[in] p_encrypted_key Pointer to the new lock code. + * + * @return See @ref es_flash_access_lock_key for possible return values. + */ +ret_code_t es_security_lock_code_update(uint8_t * p_encrypted_key); + +/**@brief Function for reading the challenge and encrypting it with AES_ECB. + * + * @details The result of the encryption is compared with the provided unlock token + * in @ref es_security_unlock_verify. + * + * @param[in] p_challenge Pointer to the challenge buffer. + * + * @return See @ref sd_ecb_block_encrypt for possible return values. + */ +void es_security_unlock_prepare(uint8_t * p_challenge); + +/**@brief Function for unlocking the beacon. + * + * @details This function compares the result from @ref es_security_unlock_prepare to the input + * unlock token and unlocks the beacon if matching. + * + * @param[in] p_unlock_token The unlock token written by the client. + */ +void es_security_unlock_verify(uint8_t * p_unlock_token); + +/**@brief Function for generating a random challenge for the unlock characteristic. + * + * @param[out] p_rand_chlg_buff Pointer to a buffer to which the random challenge is copied. + * + * @return See @ref sd_rand_application_vector_get for possible return values. + */ +ret_code_t es_security_random_challenge_generate(uint8_t * p_rand_chlg_buff); + +/**@brief Function for storing the public ECDH key from the client in the beacon registration process. + * + * @details This function starts a series of cryptographic activities, including the generation of temporary keys and EIDs. + * + * @param[in] slot_no The index of the slot whose public ECDH key is retrieved. + * @param[in] p_pub_ecdh Pointer to the public ECDH. + * @param[in] scaler_k K rotation scaler. + */ +void es_security_client_pub_ecdh_receive(uint8_t slot_no, uint8_t * p_pub_ecdh, uint8_t scaler_k); + + +/**@brief Function for storing the shared IK from the client in the beacon registration process. + * + * @details This function starts a series of cryptographic activities, including the generation of temporary keys and EIDs. + * + * @param[in] slot_no The index of the slot whose public ECDH key is retrieved. + * @param[in] p_encrypted_ik Pointer to the received IK. + * @param[in] scaler_k K rotation scaler. + */ +void es_security_shared_ik_receive(uint8_t slot_no, uint8_t * p_encrypted_ik, uint8_t scaler_k); + +/**@brief Function for copying the 32-byte ECDH key into the provided buffer. + * + * @param[in] slot_no The index of the slot whose public ECDH key is retrieved. + * @param[out] p_edch_buffer Pointer to the buffer. + */ +void es_security_pub_ecdh_get(uint8_t slot_no, uint8_t * p_edch_buffer); + +/**@brief Function for returning the beacon clock value (in little endian). + * + * @param[in] slot_no The index of the slot. + * + * @return 32-bit clock value. + */ +uint32_t es_security_clock_get(uint8_t slot_no); + +/**@brief Function for updating the beacon time counter. + * + * @details This function checks how much time has passed since the last + * invocation and, if required, updates the EID, the temporary key, or both. + * The function generates an @ref ES_SECURITY_MSG_STORE_TIME event + * for each active security slot every 24 hours. + */ +void es_security_update_time(void); + +/**@brief Function for returning the rotation exponent scaler value. + * + * @param[in] slot_no The index of the slot. + * + * @return K rotation scaler. + */ +uint8_t es_security_scaler_get(uint8_t slot_no); + +/**@brief Function for copying the 8-byte EID into the provided buffer. + * + * @param[in] slot_no The index of the slot whose EID is retrieved. + * @param[out] p_eid_buffer Pointer to the buffer. + */ +void es_security_eid_get(uint8_t slot_no, uint8_t * p_eid_buffer); + +/**@brief Function for restoring an EID slot. + * + * @param[in] slot_no The index of the slot to restore. + * @param[in] k_scaler K rotation scaler. + * @param[in] time_counter EID slot time counter value (in seconds). + * @param[in] p_ik Pointer to the identity key of the specified slot. + */ +void es_security_eid_slots_restore(uint8_t slot_no, + uint8_t k_scaler, + uint32_t time_counter, + const uint8_t * p_ik); + +/**@brief Function for destroying stored EID states. + * + * @details This function should be called when the slot is either overwritten as another slot or + * cleared by writing an empty byte or a single 0. + * + * @param[in] slot_no The index of the slot to destroy. + */ +void es_security_eid_slot_destroy(uint8_t slot_no); + +/**@brief Function for copying the 16-byte EID ID key into the provided buffer. + * + * @param[in] slot_no The index of the EID slot whose IK is retrieved. + * @param[out] p_key_buffer Buffer for the key. + */ +void es_security_plain_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer); + +/**@brief Function for copying the 16-byte LK encrypted EID ID key into the provided buffer. + * + * @param[in] slot_no The index of the EID slot whose encrypted IK is retrieved. + * @param[out] p_key_buffer Buffer for the key. + */ +void es_security_encrypted_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer); + + +/**@brief Function for converting a TLM frame into an eTLM frame using the EIK of the specified slot. + * + * @param[in] ik_slot_no The index of the EID slot whose IK is paired with the eTLM. + * @param[in] p_tlm Pointer to the TLM frame buffer. + * @param[out] p_etlm Pointer to the eTLM frame buffer. + */ +void es_security_tlm_to_etlm(uint8_t ik_slot_no, es_tlm_frame_t * p_tlm, es_etlm_frame_t * p_etlm); + +/** + * @} + */ + +#endif // ES_SECURITY_H__ diff --git a/components/libraries/eddystone/es_security_timing.c b/components/libraries/eddystone/es_security_timing.c new file mode 100644 index 0000000..8c9d2c8 --- /dev/null +++ b/components/libraries/eddystone/es_security_timing.c @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "app_timer.h" +#include "es_app_config.h" + +#define TICKS_1_SECOND APP_TIMER_TICKS(1000, APP_TIMER_PRESCALER) + +static uint32_t m_ticks_last_returned_second = 0; //!< Tick count at last second returned from 'es_security_timing_seconds_passed'. + + +uint32_t es_security_timing_seconds_passed(void) +{ + uint32_t ticks_current = app_timer_cnt_get(); + uint32_t ticks_diff; + uint32_t err_code; + + err_code = app_timer_cnt_diff_compute(ticks_current, m_ticks_last_returned_second, &ticks_diff); + APP_ERROR_CHECK(err_code); + + if(ticks_diff > TICKS_1_SECOND) + { + // Update 'm_ticks_last_returned_second' so it points to the last 'whole second' as it is this point we are referring to when + // returning the number of seconds passed since last invocation. + // I.E. if this function is called after 1.5 seconds and 2.0 seconds, 'm_ticks_last_returned_second' must point to 1.0 seconds + // after the first invocation in order to return '1' upon the second invocation. + uint32_t current_second_ms = (ticks_current / TICKS_1_SECOND) * 1000; + + m_ticks_last_returned_second = APP_TIMER_TICKS(current_second_ms, APP_TIMER_PRESCALER); + + return ticks_diff / TICKS_1_SECOND; + } + + return 0; +} + + +void es_security_timing_init(void) +{ + m_ticks_last_returned_second = 0; +} diff --git a/components/libraries/eddystone/es_security_timing.h b/components/libraries/eddystone/es_security_timing.h new file mode 100644 index 0000000..675a50f --- /dev/null +++ b/components/libraries/eddystone/es_security_timing.h @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_SECURITY_TIMING_H__ +#define ES_SECURITY_TIMING_H__ + +#include + +/** + * @file + * @addtogroup eddystone_security + * @{ + */ + +/**@brief Function for getting the number of seconds passed since the last invocation. + * @details If the function returns zero, the 'last time called' state is not updated. If a non-zero value + * is returned, the 'last time called' state will point to the last whole second. + * @return Number of seconds passed since the last invocation. + */ +uint32_t es_security_timing_seconds_passed(void); + + +/**@brief Function for initializing the security timing module. + */ +void es_security_timing_init(void); + +/** + * @} + */ + +#endif // ES_SECURITY_TIMING_H__ diff --git a/components/libraries/eddystone/es_slot.c b/components/libraries/eddystone/es_slot.c new file mode 100644 index 0000000..fc77674 --- /dev/null +++ b/components/libraries/eddystone/es_slot.c @@ -0,0 +1,441 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "es_slot.h" +#include "es_flash.h" +#include "es_security.h" +#include "es_slot_reg.h" +#include "es_tlm.h" +#include "fds.h" + +static es_slot_reg_t m_reg; //!< Slot registry. +static bool m_eid_loaded_from_flash; //!< Set to true if EID slot has been loaded from flash. + +#define RANGING_DATA_INDEX (1) //!< Index of ranging data within frames that contain ranging data. +#define RANGING_DATA_LENGTH (1) //!< Length of ranging data. + +/**@brief Enforce legal slot number. + * + * @param[in] p_slot Pointer to the slot number variable to check. + */ +static void slot_boundary_check(uint8_t * p_slot) +{ + if (*p_slot > (APP_MAX_ADV_SLOTS - 1)) + { + *p_slot = (APP_MAX_ADV_SLOTS - 1); + } +} + + +/**@brief Function loading slot data from flash. + * + * @param[in] slot_no Slot number to be used. + */ +static void load_slot_from_flash(uint8_t slot_no) +{ + ret_code_t err_code; + + err_code = es_flash_access_slot_configs(slot_no, &m_reg.slots[slot_no], ES_FLASH_ACCESS_READ); + if (err_code != FDS_ERR_NOT_FOUND) + { + APP_ERROR_CHECK(err_code); + + if (m_reg.slots[slot_no].adv_frame.type == ES_FRAME_TYPE_EID) + { + m_eid_loaded_from_flash = true; + + es_security_eid_slots_restore(slot_no, + m_reg.slots[slot_no].k_scaler, + m_reg.slots[slot_no].seconds, + (const uint8_t *)m_reg.slots[slot_no].ik); + } + + else + { + // If a non-EID slot has been loaded, update the state of m_reg immediately. + es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, m_reg.slots[slot_no].adv_frame.type, true); + } + } +} + + +/**@brief Function for setting the ranging data field to be broadcast in the frame. + * + * @param[in] slot_no The slot index. + * @param[in] tx_power The radio tx power to be calibrated to ranging data. + */ +static void set_ranging_data_for_slot(uint8_t slot_no, nrf_ble_escs_radio_tx_pwr_t tx_power) +{ + int8_t ranging_data_array[ESCS_NUM_OF_SUPPORTED_TX_POWER] = APP_CONFIG_CALIBRATED_RANGING_DATA; + nrf_ble_escs_radio_tx_pwr_t supported_tx[ESCS_NUM_OF_SUPPORTED_TX_POWER] = + ESCS_SUPPORTED_TX_POWER; + + int8_t ranging_data = 0; + + if (m_reg.slots[slot_no].adv_custom_tx_power) + { + ranging_data = m_reg.slots[slot_no].custom_tx_power; + } + + else + { + for (uint32_t i = 0; i < ESCS_NUM_OF_SUPPORTED_TX_POWER; ++i) + { + if (supported_tx[i] >= tx_power) + { + ranging_data = ranging_data_array[i]; + break; + } + } + } + es_adv_frame_t * frame = &m_reg.slots[slot_no].adv_frame; + switch (frame->type) + { + case ES_FRAME_TYPE_UID: + { + es_uid_frame_t * uid = &frame->frame.uid; + uid->ranging_data = ranging_data; + break; + } + + case ES_FRAME_TYPE_URL: + { + es_url_frame_t * url = &frame->frame.url; + url->ranging_data = ranging_data; + break; + } + + case ES_FRAME_TYPE_EID: + { + es_eid_frame_t * eid = &frame->frame.eid; + eid->ranging_data = ranging_data; + break; + } + + case ES_FRAME_TYPE_TLM: + APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM); + break; + } +} + + +/**@brief Function configuring a non-EID slot. + * + * @param[in] slot_no Slot number to be used. + * @param[in] length Length of write operation. + * @param[in] p_frame_data Pointer to written data. + */ +static void configure_slot(uint8_t slot_no, uint8_t length, uint8_t * p_frame_data) +{ + // If a TLM slot is being configured and there already exists a TLM. + if ((es_frame_type_t)p_frame_data[0] == ES_FRAME_TYPE_TLM && m_reg.tlm_configured) + { + return; // Silently ignore any attempts to create more than one TLM slot as there is no point. + } + + es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, (es_frame_type_t)p_frame_data[0], false); + + // For convenience, frame_type is stored in two places, set both. + m_reg.slots[slot_no].adv_frame.type = (es_frame_type_t)p_frame_data[0]; + memcpy(&m_reg.slots[slot_no].adv_frame.frame, &m_reg.slots[slot_no].adv_frame.type, 1); + + uint8_t * p_data_after_ranging_data = ((uint8_t *)(&m_reg.slots[slot_no].adv_frame.frame) + + RANGING_DATA_INDEX + RANGING_DATA_LENGTH); + + switch (m_reg.slots[slot_no].adv_frame.type) + { + case ES_FRAME_TYPE_UID: + // Fall through. + case ES_FRAME_TYPE_URL: + memcpy(p_data_after_ranging_data, &p_frame_data[1], length); + set_ranging_data_for_slot(slot_no, APP_CFG_DEFAULT_RADIO_TX_POWER); + m_reg.slots[slot_no].adv_frame.length = length + 1; // + 1 for ranging data + break; + + case ES_FRAME_TYPE_TLM: + es_tlm_tlm_get(&m_reg.slots[slot_no].adv_frame.frame.tlm); + m_reg.slots[slot_no].adv_frame.length = ES_TLM_LENGTH; + break; + + default: + break; + } +} + + +/**@brief Function configuring an EID slot. + * + * @param[in] slot_no Slot number to be used. + * @param[in] length Length of write operation. + * @param[in] p_frame_data Pointer to written data. + */ +static void configure_eid_slot(uint8_t slot_no, uint8_t length, uint8_t * p_frame_data) +{ + bool clear_eid_slot = false; + + // Do not update slot count, as this will be done when in the callback invoked when the EID data + // is ready. + // As it takes a while to do the calculation, temporarily remove the slot being overwritten. + // The slot will be re-added in the callback invoked when the EID data is ready. + clear_eid_slot = es_slot_reg_clear_slot(&m_reg, slot_no); + + if (clear_eid_slot) + { + es_security_eid_slot_destroy(slot_no); + } + + if (p_frame_data[0] != ES_FRAME_TYPE_EID) + { + APP_ERROR_CHECK(NRF_ERROR_INVALID_STATE); + } + + if (length == ESCS_EID_WRITE_ECDH_LENGTH) + { + es_security_client_pub_ecdh_receive(slot_no, + &p_frame_data[ESCS_EID_WRITE_PUB_KEY_INDEX], + p_frame_data[ESCS_EID_WRITE_ECDH_LENGTH -1]); + } + + else if (length == ESCS_EID_WRITE_IDK_LENGTH) + { + es_security_shared_ik_receive(slot_no, + &p_frame_data[ESCS_EID_WRITE_ENC_ID_KEY_INDEX], + p_frame_data[ESCS_EID_WRITE_IDK_LENGTH - 1]); + } + + else + { + // Invalid length being written. + APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM); + } +} + + +ret_code_t es_slot_write_to_flash(uint8_t slot_no) +{ + if (m_reg.slots[slot_no].configured) + { + // If its an EID, we need to store some metadata in order to re-initialize the EID. + if (m_reg.slots[slot_no].adv_frame.type == ES_FRAME_TYPE_EID) + { + m_reg.slots[slot_no].seconds = es_security_clock_get(slot_no); + m_reg.slots[slot_no].k_scaler = es_security_scaler_get(slot_no); + es_security_plain_eid_id_key_get(slot_no, m_reg.slots[slot_no].ik); + } + return es_flash_access_slot_configs(slot_no, &m_reg.slots[slot_no], ES_FLASH_ACCESS_WRITE); + } + + else + { + return es_flash_access_slot_configs(slot_no, NULL, ES_FLASH_ACCESS_CLEAR); + } +} + + +void es_slot_radio_tx_pwr_set(uint8_t slot_no, nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr) +{ + slot_boundary_check(&slot_no); + + m_reg.slots[slot_no].radio_tx_pwr = radio_tx_pwr; + + if (!m_reg.slots[slot_no].adv_custom_tx_power) // Only update TX power in ADV if custom TX power is not set + { + set_ranging_data_for_slot(slot_no, radio_tx_pwr); + } +} + + +void es_slot_set_adv_custom_tx_power(uint8_t slot_no, nrf_ble_escs_adv_tx_pwr_t tx_pwr) +{ + slot_boundary_check(&slot_no); + + m_reg.slots[slot_no].adv_custom_tx_power = true; + m_reg.slots[slot_no].custom_tx_power = tx_pwr; + set_ranging_data_for_slot(slot_no, tx_pwr); +} + + +void es_slot_on_write(uint8_t slot_no, uint8_t length, uint8_t * p_frame_data) +{ + slot_boundary_check(&slot_no); + + if (p_frame_data == NULL) + { + APP_ERROR_CHECK(NRF_ERROR_NULL); + } + + // Cleared + if (length == 0 || (length == 1 && p_frame_data[0] == 0)) + { + (void)es_slot_reg_clear_slot(&m_reg, slot_no); + } + // EID slot being configured + else if (p_frame_data[0] == ES_FRAME_TYPE_EID && + (length == ESCS_EID_WRITE_ECDH_LENGTH || length == ESCS_EID_WRITE_IDK_LENGTH)) + { + if (m_reg.slots[slot_no].configured) + (void)es_slot_reg_clear_slot(&m_reg, slot_no); + configure_eid_slot(slot_no, length, p_frame_data); + } + // Non-EID slot configured. + else + { + if (m_reg.slots[slot_no].configured) + (void)es_slot_reg_clear_slot(&m_reg, slot_no); + configure_slot(slot_no, length, p_frame_data); + } +} + + +void es_slot_encrypted_eid_id_key_set(uint8_t slot_no, nrf_ble_escs_eid_id_key_t * p_eid_id_key) +{ + slot_boundary_check(&slot_no); + if (p_eid_id_key != NULL) + { + memcpy(&(m_reg.slots[slot_no].encrypted_eid_id_key), p_eid_id_key, + sizeof(nrf_ble_escs_eid_id_key_t)); + } +} + + +void es_slot_eid_ready(uint8_t slot_no) +{ + m_reg.slots[slot_no].adv_frame.type = ES_FRAME_TYPE_EID; + m_reg.slots[slot_no].adv_frame.length = ES_EID_LENGTH; + es_security_eid_get(slot_no, (uint8_t *)m_reg.slots[slot_no].adv_frame.frame.eid.eid); + m_reg.slots[slot_no].adv_frame.frame.eid.frame_type = ES_FRAME_TYPE_EID; + set_ranging_data_for_slot(slot_no, m_reg.slots[slot_no].radio_tx_pwr); + + if (m_eid_loaded_from_flash) + { + es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, ES_FRAME_TYPE_EID, true); + m_eid_loaded_from_flash = false; + } + + else + { + es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, ES_FRAME_TYPE_EID, false); + } +} + + +static bool slot_is_eid(uint8_t eid_slot_no) +{ + for (uint32_t i = 0; i < m_reg.num_configured_eid_slots; ++i) + { + if (m_reg.eid_slots_configured[i] == eid_slot_no) + { + return true; + } + } + + return false; +} + + +void es_slot_tlm_update(void) +{ + if (m_reg.tlm_configured) + { + es_tlm_tlm_get(&m_reg.slots[m_reg.tlm_slot].adv_frame.frame.tlm); + } +} + + +void es_slot_etlm_update(uint8_t eid_slot_no) +{ + es_tlm_frame_t tlm; + es_etlm_frame_t etlm; + + // Ignore the request if eTLM is not required or slot no does not correspond to an EID slot. + if (!es_slot_reg_etlm_required(&m_reg) || !slot_is_eid(eid_slot_no)) + { + return; + } + + es_tlm_tlm_get(&tlm); + + es_security_tlm_to_etlm(eid_slot_no, &tlm, &etlm); + + memcpy(&m_reg.slots[m_reg.tlm_slot].adv_frame.frame.etlm, &etlm, sizeof(es_etlm_frame_t)); + m_reg.slots[m_reg.tlm_slot].adv_frame.length = sizeof(es_etlm_frame_t); +} + + +const es_slot_reg_t * es_slot_get_registry(void) +{ + return (const es_slot_reg_t *)&m_reg; +} + + +void es_slots_init(const es_slot_t * p_default_slot) +{ + ret_code_t err_code; + es_flash_flags_t flash_flags = {{0}}; + + es_slot_reg_init(&m_reg); + + m_eid_loaded_from_flash = false; + + // Read the flash flags to see if there are any previously stored slot configs + err_code = es_flash_access_flags(&flash_flags, ES_FLASH_ACCESS_READ); + + if (err_code == FDS_ERR_NOT_FOUND) + { + // Factory reset or initial boot, load default data + memcpy(&m_reg.slots[0], p_default_slot, sizeof(*p_default_slot)); + es_slot_reg_update_slot_list_info_on_add(&m_reg, 0, p_default_slot->adv_frame.type, true); + } + + else + { + APP_ERROR_CHECK(err_code); + + for (uint32_t i = 0; i < APP_MAX_ADV_SLOTS; ++i) + { + if (!flash_flags.slot_is_empty[i]) + { + load_slot_from_flash(i); + } + } + } +} diff --git a/components/libraries/eddystone/es_slot.h b/components/libraries/eddystone/es_slot.h new file mode 100644 index 0000000..ac4bb8a --- /dev/null +++ b/components/libraries/eddystone/es_slot.h @@ -0,0 +1,203 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_SLOT_H__ +#define ES_SLOT_H__ + +#include +#include "es_app_config.h" +#include "nrf_ble_escs.h" + +/** + * @file + * @defgroup eddystone_slot Slots + * @brief Types and functions for handling Eddystone slots. + * @ingroup eddystone + * @{ + */ + +/**@brief Advertisable frame types that can be passed in to the advertising + * data during non-connectable slot advertising. */ + +typedef struct +{ + union + { + es_uid_frame_t uid; //!< UID frame. + es_url_frame_t url; //!< URL frame. + es_tlm_frame_t tlm; //!< TLM frame. + es_eid_frame_t eid; //!< EID frame. + es_etlm_frame_t etlm; //!< eTLM frame. + } frame; + es_frame_type_t type; //!< Type defined twice for convenience (because the other one is inside a union). + uint8_t length; +}es_adv_frame_t; + +/**@brief Slot. */ +typedef struct +{ + uint8_t slot_no; //!< Identifier for the slot, indexed at 0. + nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr; //!< Radio TX power (in dB). + nrf_ble_escs_eid_id_key_t encrypted_eid_id_key; //!< EID key for the slot. + es_adv_frame_t adv_frame; //!< Frame structure to be passed in for advertising data. + bool adv_custom_tx_power; //!< Flag that specifies if the client has written to the 'Advertised TX Power' field of this slot. + nrf_ble_escs_radio_tx_pwr_t custom_tx_power; //!< Custom TX power to advertise (only if @ref adv_custom_tx_power is true). + bool configured; //!< Is this slot configured and active. + uint8_t k_scaler; + uint32_t seconds; + uint8_t ik[ESCS_AES_KEY_SIZE]; +} es_slot_t; + +/**@brief Slot registry. */ +typedef struct +{ + es_slot_t slots[APP_MAX_ADV_SLOTS]; + uint8_t num_configured_slots; + uint8_t num_configured_eid_slots; + uint8_t slots_configured[APP_MAX_ADV_SLOTS]; + uint8_t eid_slots_configured[APP_MAX_EID_SLOTS]; + uint8_t tlm_slot; + bool tlm_configured; + uint8_t scaler_k; + uint8_t enc_key[ESCS_AES_KEY_SIZE]; +} es_slot_reg_t; + +/**@brief Function for initializing the Eddystone slots with default values. + * + * @details This function synchronizes all slots with the initial values. + * + * @param[in] p_default_slot Pointer to the default parameters for a slot. + */ +void es_slots_init(const es_slot_t * p_default_slot); + +/**@brief Function for setting the advertising interval of the specified slot. + * + * For compatibility with the Eddystone specifications, @p p_adv_interval must point to + * a 16-bit big endian value (coming from the characteristic write request), + * which is then converted to a little endian value inside the function before + * it is written into the variable in the slot. + * + * @parameternoteslot + * @parameternoteadv + * + * @param[in] slot_no The index of the slot. + * @param[in,out] p_adv_interval Pointer to the advertisement interval (in ms) to set. + * @param[in] global Flag that should be set if the beacon does not support variable advertising intervals. + */ +void es_slot_adv_interval_set(uint8_t slot_no, + nrf_ble_escs_adv_interval_t * p_adv_interval, + bool global); + +/**@brief Function for setting the TX power of the specified slot. + * + * @parameternoteslot + * @parameternotetxpower + * + * @param[in] slot_no The index of the slot. + * @param[in,out] radio_tx_pwr TX power value to set. + */ +void es_slot_radio_tx_pwr_set(uint8_t slot_no, nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr); + +/**@brief Function for setting the R/W ADV of the specified slot. + * + * @parameternoteslot + * + * @param[in] slot_no The index of the slot. + * @param[in,out] length The length of the data written or read. + * @param[in,out] p_frame_data Pointer to the data. + * + */ +void es_slot_on_write(uint8_t slot_no, uint8_t length, uint8_t * p_frame_data); + +/**@brief Function for writing the slot's configuration to flash. + * + * @param[in] slot_no The index of the slot. + */ +ret_code_t es_slot_write_to_flash(uint8_t slot_no); + +/**@brief Function for setting the slot's encrypted EID Identity Key to be displayed in the EID Identity Key characteristic. + * + * @parameternoteslot + * + * @param[in] slot_no The index of the slot. + * @param[in,out] p_eid_id_key Pointer to a @ref nrf_ble_escs_eid_id_key_t structure from where the key will be written. + */ +void es_slot_encrypted_eid_id_key_set(uint8_t slot_no, nrf_ble_escs_eid_id_key_t * p_eid_id_key); + +/**@brief Function for marking an EID slot as ready for populating. + * + * @details Call this function when an EID has been generated and the advertisement frame can be populated with the EID. + * + * @param[in] slot_no The index of the slot. + */ +void es_slot_eid_ready(uint8_t slot_no); + +/**@brief Function for updating the TLM slot with updated data. */ +void es_slot_tlm_update(void); + +/**@brief Function for updating the TLM slot with eTLM data. + * + * @details This function uses the EID identity key from the given EID slot number to update the TLM slot. + * + * @param[in] eid_slot_no EID slot to get EID identity key from. + */ +void es_slot_etlm_update(uint8_t eid_slot_no); + +/**@brief Function for getting a pointer to the slot registry. + * + * @return A pointer to the slot registry. + */ +const es_slot_reg_t * es_slot_get_registry(void); + +/**@brief Function for setting a custom advertisement TX power for a given slot. + * + * @parameternoteslot + * @parameternotetxpower + * + * @param[in] slot_no The index of the slot. + * @param[in] tx_pwr Advertised TX power to be set. + */ +void es_slot_set_adv_custom_tx_power(uint8_t slot_no, nrf_ble_escs_adv_tx_pwr_t tx_pwr); + +/** + * @} + */ + +#endif // ES_SLOT_H__ diff --git a/components/libraries/eddystone/es_slot_reg.c b/components/libraries/eddystone/es_slot_reg.c new file mode 100644 index 0000000..0e9d4e3 --- /dev/null +++ b/components/libraries/eddystone/es_slot_reg.c @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "es_slot_reg.h" + +#define ES_SLOT_NOT_CONFIGURED 0xab /** Value set in configured lists to indicate not configured slot. */ + +/**@brief Function updating 'tlm_configured' property of slot registry when slot is being cleared. + * + * @param[in] p_reg Pointer to slot registry. + * @param[in] slot_no Slot number to be used. + */ +static void update_tlm_configured_on_clearing(es_slot_reg_t * p_reg, uint8_t slot_no) +{ + if (p_reg->tlm_configured && slot_no == p_reg->tlm_slot) + { + p_reg->tlm_configured = false; + } +} + + +/**@brief Function updating 'num_configured_slots' and 'slots_configured' properties of slot registry when slot is being cleared. + * + * @param[in] p_configured Pointer to list of configured slots. + * @param[in] p_num_configured_slots Pointer to number of configured slots. + * @param[in] slot_no Slot number to clear. + */ +static void configured_slots_on_clear_update(uint8_t * p_configured, uint8_t * p_num_configured_slots, uint8_t slot_no) +{ + uint8_t index_of_last_configured_slot = *p_num_configured_slots - 1; + + for (uint32_t i = 0; i < APP_MAX_ADV_SLOTS; ++i) + { + if (p_configured[i] == slot_no) + { + // Copy all values 'to the right' of the cleared slot one step to the left. + if (i < index_of_last_configured_slot) + { + for (uint32_t j = i; j < index_of_last_configured_slot; ++j) + { + p_configured[j] = p_configured[j + 1]; + } + // Write ES_SLOT_NOT_CONFIGURED to all rightmost not configured indexes. + memset(&p_configured[index_of_last_configured_slot], + ES_SLOT_NOT_CONFIGURED, + APP_MAX_ADV_SLOTS - index_of_last_configured_slot); + } + + else + { + // There are no values 'to the right', simply overwrite with ES_SLOT_NOT_CONFIGURED + p_configured[i] = ES_SLOT_NOT_CONFIGURED; + } + + *p_num_configured_slots -= 1; + + return; + } + } +} + + +bool es_slot_reg_etlm_required(const es_slot_reg_t * p_reg) +{ + return (p_reg->num_configured_eid_slots > 0 && p_reg->tlm_configured); +} + + +bool es_slot_reg_clear_slot(es_slot_reg_t * p_reg, uint8_t slot_no) +{ + bool eid_has_been_cleared = false; + + if (p_reg->slots[slot_no].configured) + { + update_tlm_configured_on_clearing(p_reg, slot_no); + + configured_slots_on_clear_update(p_reg->slots_configured, + &p_reg->num_configured_slots, + slot_no); + + if (p_reg->slots[slot_no].adv_frame.type == ES_FRAME_TYPE_EID) + { + configured_slots_on_clear_update(p_reg->eid_slots_configured, + &p_reg->num_configured_eid_slots, + slot_no); + + eid_has_been_cleared = true; + } + + p_reg->slots[slot_no].configured = false; + } + + memset(&p_reg->slots[slot_no], 0, sizeof(p_reg->slots[slot_no])); + + return eid_has_been_cleared; +} + + +void es_slot_reg_update_slot_list_info_on_add(es_slot_reg_t * p_reg, + uint8_t slot_no, + es_frame_type_t frame_type, + bool init) +{ + if (frame_type == ES_FRAME_TYPE_TLM) + { + p_reg->tlm_configured = true; + p_reg->tlm_slot = slot_no; + } + + if (!p_reg->slots[slot_no].configured || init) + { + p_reg->slots[slot_no].configured = true; + + // Note, we use 'num_configured_slots' before incrementing it, so it is pointing to the correct index. + p_reg->slots_configured[p_reg->num_configured_slots] = slot_no; + + p_reg->num_configured_slots++; + + if (frame_type == ES_FRAME_TYPE_EID) + { + p_reg->eid_slots_configured[p_reg->num_configured_eid_slots] = slot_no; + + p_reg->num_configured_eid_slots++; + } + } + + // If an already configured slot has changed from anything TO an EID slot. + else if (frame_type == ES_FRAME_TYPE_EID && + p_reg->slots[slot_no].adv_frame.type != ES_FRAME_TYPE_EID) + { + p_reg->eid_slots_configured[p_reg->num_configured_eid_slots] = slot_no; + + p_reg->num_configured_eid_slots++; + } +} + + +void es_slot_reg_init(es_slot_reg_t * p_reg) +{ + p_reg->tlm_configured = false; + memset(p_reg->slots_configured, ES_SLOT_NOT_CONFIGURED, APP_MAX_ADV_SLOTS); + memset(p_reg->eid_slots_configured, ES_SLOT_NOT_CONFIGURED, APP_MAX_EID_SLOTS); + p_reg->num_configured_eid_slots = 0; + p_reg->num_configured_slots = 0; +} diff --git a/components/libraries/eddystone/es_slot_reg.h b/components/libraries/eddystone/es_slot_reg.h new file mode 100644 index 0000000..1640c19 --- /dev/null +++ b/components/libraries/eddystone/es_slot_reg.h @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_SLOT_REG_H__ +#define ES_SLOT_REG_H__ + +#include +#include "es_slot.h" + +/** + * @file + * @addtogroup eddystone_slot + * @{ + */ + +/** @brief Function for checking if an eTLM frame is required. + * + * @param[in] p_reg Pointer to the slot registry. + * + * @retval true If an eTLM frame is required. + * @retval false Otherwise. + */ +bool es_slot_reg_etlm_required(const es_slot_reg_t * p_reg); + +/** @brief Function for clearing a slot. + * + * @param[in] p_reg Pointer to the slot registry. + * @param[in] slot_no The slot number to clear. + * + * @retval true If an EID slot was cleared. + */ +bool es_slot_reg_clear_slot(es_slot_reg_t * p_reg, uint8_t slot_no); + +/** @brief Function for updating the state of the slot registry after adding a slot. + * + * @param[in] p_reg Pointer to the slot registry. + * @param[in] slot_no The slot number that was added. + * @param[in] frame_type The frame type that was added. + * @param[in] init Information if the data is loaded during initialization. Set this + * parameter to false if the call is a result of a write to the Eddystone Configuration Service. + */ +void es_slot_reg_update_slot_list_info_on_add(es_slot_reg_t * p_reg, uint8_t slot_no, es_frame_type_t frame_type, bool init); + +/** @brief Function for initializing the slot registry. + * + * @param[in] p_reg Pointer to the slot registry to initialize. + */ +void es_slot_reg_init(es_slot_reg_t * p_reg); + +/** + * @} + */ + +#endif // ES_SLOT_REG_H__ diff --git a/components/libraries/eddystone/es_stopwatch.c b/components/libraries/eddystone/es_stopwatch.c new file mode 100644 index 0000000..d7925d4 --- /dev/null +++ b/components/libraries/eddystone/es_stopwatch.c @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include +#include "es_stopwatch.h" +#include "sdk_macros.h" +#include "app_timer.h" +#include "es_app_config.h" + +static uint32_t m_ticks_last_returned[ES_STOPWATCH_MAX_USERS]; +static uint32_t m_ids_ticks_wrap[ES_STOPWATCH_MAX_USERS]; +static uint8_t m_nof_ids = 0; +static bool m_initialized = false; + +uint32_t es_stopwatch_check(es_stopwatch_id_t id) +{ + uint32_t ticks_current = app_timer_cnt_get(); + uint32_t ticks_diff; + + if (m_ids_ticks_wrap[id] == 0) + { + APP_ERROR_CHECK(NRF_ERROR_INVALID_STATE); + } + + (void) app_timer_cnt_diff_compute(ticks_current, m_ticks_last_returned[id], &ticks_diff); + + if (ticks_diff >= m_ids_ticks_wrap[id]) + { + m_ticks_last_returned[id] = (ticks_current / m_ids_ticks_wrap[id]) * m_ids_ticks_wrap[id]; + + return ticks_diff / m_ids_ticks_wrap[id]; + } + + return 0; +} + +ret_code_t es_stopwatch_create(es_stopwatch_id_t * p_sw_id, uint32_t ticks_wrap) +{ + VERIFY_PARAM_NOT_NULL(p_sw_id); + + if (m_nof_ids == ES_STOPWATCH_MAX_USERS) + { + return NRF_ERROR_INVALID_STATE; + } + + if (!m_initialized) + { + return NRF_ERROR_MODULE_NOT_INITIALZED; + } + + *p_sw_id = m_nof_ids; + + m_ids_ticks_wrap[m_nof_ids] = ticks_wrap; + + m_nof_ids++; + + return NRF_SUCCESS; +} + + +void es_stopwatch_init(void) +{ + m_nof_ids = 0; + memset(m_ticks_last_returned, 0, sizeof(m_ticks_last_returned)); + memset(m_ids_ticks_wrap, 0, sizeof(m_ids_ticks_wrap)); + m_initialized = true; +} diff --git a/components/libraries/eddystone/es_stopwatch.h b/components/libraries/eddystone/es_stopwatch.h new file mode 100644 index 0000000..ade07c8 --- /dev/null +++ b/components/libraries/eddystone/es_stopwatch.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_SECURITY_TIMING_H__ +#define ES_SECURITY_TIMING_H__ + +#include +#include "app_error.h" + +/** + * @file + * @addtogroup eddystone_security + * @{ + */ + +typedef uint8_t es_stopwatch_id_t; + +/**@brief Function for getting the number of seconds passed since the last invocation. + * @details If the function returns zero, the 'last time called' state is not updated. If a non-zero value + * is returned, the 'last time called' state will point to the last whole second. + * @return Number of seconds passed since the last invocation. + */ +uint32_t es_stopwatch_check(es_stopwatch_id_t id); + +ret_code_t es_stopwatch_create(es_stopwatch_id_t * p_sw_id, uint32_t ticks_wrap); + +/**@brief Function for initializing the security timing module. + */ +void es_stopwatch_init(void); + +/** + * @} + */ + +#endif // ES_SECURITY_TIMING_H__ diff --git a/components/libraries/eddystone/es_tlm.c b/components/libraries/eddystone/es_tlm.c new file mode 100644 index 0000000..2251474 --- /dev/null +++ b/components/libraries/eddystone/es_tlm.c @@ -0,0 +1,141 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "app_timer.h" +#include "es_tlm.h" +#include "es_app_config.h" +#include "es_battery_voltage.h" +#include "es_stopwatch.h" +#include "nrf_soc.h" + +#define TICKS_100_MS APP_TIMER_TICKS(100, APP_TIMER_PRESCALER) //!< Tick count for 100ms. + +static es_tlm_frame_t m_tlm; +static uint32_t m_le_adv_cnt; +static es_stopwatch_id_t m_time_sec_sw_id; +static es_stopwatch_id_t m_tlm_refresh_sw_id; + +/**@brief Function for updating the ADV_SEC field of TLM*/ +static void update_time(void) +{ + static uint32_t time_total_100_ms = 0; + uint32_t be_time_100_ms; // Big endian version of 0.1 second counter. + + time_total_100_ms += es_stopwatch_check(m_time_sec_sw_id); + + be_time_100_ms = BYTES_REVERSE_32BIT(time_total_100_ms); + + memcpy(m_tlm.sec_cnt, &be_time_100_ms, ES_TLM_SEC_CNT_LENGTH); +} + + +/**@brief Function for updating the TEMP field of TLM*/ +static void update_temp(void) +{ + int32_t temp; // variable to hold temp reading + (void)sd_temp_get(&temp); // get new temperature + int16_t temp_new = (int16_t) temp; // convert from int32_t to int16_t + m_tlm.temp[0] = (uint8_t)((temp_new >> 2) & 0xFFUL); // Right-shift by two to remove decimal part + m_tlm.temp[1] = (uint8_t)((temp_new << 6) & 0xFFUL); // Left-shift 6 to get fractional part with 0.25 degrees C resolution +} + + +/**@brief Function for updating the VBATT field of TLM*/ +static void update_vbatt(void) +{ + uint16_t vbatt; // Variable to hold voltage reading + es_battery_voltage_get(&vbatt); // Get new battery voltage + m_tlm.vbatt[0] = (uint8_t)(vbatt >> 8); + m_tlm.vbatt[1] = (uint8_t)vbatt; +} + + +static void update_adv_cnt(void) +{ + uint32_t be_adv_cnt = BYTES_REVERSE_32BIT(m_le_adv_cnt); + memcpy(m_tlm.adv_cnt, (uint8_t *)(&be_adv_cnt), ES_TLM_ADV_CNT_LENGTH); +} + + +void es_tlm_tlm_get(es_tlm_frame_t * p_tlm_frame) +{ + // Note that frame type and TLM version fields are set in initialization. + update_time(); + update_adv_cnt(); + + if (es_stopwatch_check(m_tlm_refresh_sw_id) > 0) + { + update_temp(); + update_vbatt(); + } + + memcpy(p_tlm_frame, &m_tlm, sizeof(es_tlm_frame_t)); +} + + +void es_tlm_adv_cnt_inc(void) +{ + m_le_adv_cnt++; +} + + +void es_tlm_init(void) +{ + ret_code_t err_code; + + memset(&m_tlm, 0, sizeof(m_tlm)); + m_tlm.frame_type = ES_FRAME_TYPE_TLM; + m_tlm.version = ES_TLM_VERSION_TLM; + m_le_adv_cnt = 0; + + update_time(); + update_vbatt(); + update_temp(); + + err_code = es_stopwatch_create(&m_time_sec_sw_id, APP_TIMER_TICKS(100, APP_TIMER_PRESCALER)); + APP_ERROR_CHECK(err_code); + + err_code = es_stopwatch_create( + &m_tlm_refresh_sw_id, + APP_TIMER_TICKS(APP_CONFIG_TLM_TEMP_VBATT_UPDATE_INTERVAL_SECONDS * 1000, + APP_TIMER_PRESCALER)); + APP_ERROR_CHECK(err_code); +} diff --git a/components/libraries/eddystone/es_tlm.h b/components/libraries/eddystone/es_tlm.h new file mode 100644 index 0000000..dbc9952 --- /dev/null +++ b/components/libraries/eddystone/es_tlm.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ES_TLM_H__ +#define ES_TLM_H__ + +#include "es.h" + +/** + * @file + * @defgroup eddystone_tlm TLM + * @brief Functions for the Eddystone telemetry (TLM) manager. + * @ingroup eddystone_adv + * @{ + */ + +/**@brief Function for initializing the TLM manager. + * + * @return See @ref app_timer_start for possible return values. + */ +void es_tlm_init(void); + +/**@brief Function for getting the current TLM. + * + * @param[in] p_tlm_frame Pointer to the TLM frame to which the frame is retrieved. + */ +void es_tlm_tlm_get(es_tlm_frame_t * p_tlm_frame); + +/**@brief Function for incrementing the ADV_CNT field of the TLM frame. + * + * @details This function should be called every time a frame is advertised. + * + */ +void es_tlm_adv_cnt_inc(void); + +/** + * @} + */ + +#endif // ES_TLM_H__ diff --git a/components/libraries/eddystone/es_util.h b/components/libraries/eddystone/es_util.h new file mode 100644 index 0000000..3db1302 --- /dev/null +++ b/components/libraries/eddystone/es_util.h @@ -0,0 +1,137 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +// See https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms + +#ifndef ES_UTIL_H__ +#define ES_UTIL_H__ + +#define BOOL(x) COMPL(NOT(x)) +#define IF(c) IIF(BOOL(c)) + +#define CHECK_N(x, n, ...) n +#define CHECK(...) CHECK_N(__VA_ARGS__, 0,) +#define PROBE(x) x, 1, + +#define EAT(...) +#define EXPAND(...) __VA_ARGS__ +#define WHEN(c) IF(c)(EXPAND, EAT) + +#define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x)) +#define NOT_0 PROBE(~) + +#define COMPL(b) PRIMITIVE_CAT(COMPL_, b) +#define COMPL_0 1 +#define COMPL_1 0 + +#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__) +#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__ + +#define IIF(c) PRIMITIVE_CAT(IIF_, c) +#define IIF_0(t, ...) __VA_ARGS__ +#define IIF_1(t, ...) t + +#define DEC(x) PRIMITIVE_CAT(DEC_, x) +#define DEC_0 0 +#define DEC_1 0 +#define DEC_2 1 +#define DEC_3 2 +#define DEC_4 3 +#define DEC_5 4 +#define DEC_6 5 +#define DEC_7 6 +#define DEC_8 7 +#define DEC_9 8 +#define DEC_10 9 +#define DEC_11 10 +#define DEC_12 11 +#define DEC_13 12 +#define DEC_14 13 +#define DEC_15 14 +#define DEC_16 15 +#define DEC_17 16 +#define DEC_18 17 +#define DEC_19 18 +#define DEC_20 19 +#define DEC_21 20 +#define DEC_22 21 +#define DEC_23 22 +#define DEC_24 23 +#define DEC_25 24 +#define DEC_26 25 +#define DEC_27 26 +#define DEC_28 27 +#define DEC_29 28 +#define DEC_30 29 +#define DEC_31 30 +#define DEC_32 31 + +#define EMPTY() +#define DEFER(id) id EMPTY() +#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)() +#define EXPAND(...) __VA_ARGS__ + +#define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) +#define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) +#define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) +#define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__))) +#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__))) +#define EVAL5(...) __VA_ARGS__ + +#define REPEAT(count, macro, ...) \ + WHEN(count) \ + ( \ + OBSTRUCT(REPEAT_INDIRECT) () \ + ( \ + DEC(count), macro, __VA_ARGS__ \ + ) \ + OBSTRUCT(macro) \ + ( \ + DEC(count), __VA_ARGS__ \ + ) \ + ) +#define REPEAT_INDIRECT() REPEAT + + +/** + * @} + */ + +#endif // ES_UTIL_H__ diff --git a/components/libraries/eddystone/nrf_ble_es.c b/components/libraries/eddystone/nrf_ble_es.c new file mode 100644 index 0000000..cf8a0db --- /dev/null +++ b/components/libraries/eddystone/nrf_ble_es.c @@ -0,0 +1,429 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "nrf_ble_es.h" +#include "app_error.h" +#include "fds.h" +#include "es_adv.h" +#include "es_battery_voltage.h" +#include "es_flash.h" +#include "es_gatts.h" +#include "es_security.h" +#include "es_slot.h" +#include "es_stopwatch.h" +#include "escs_defs.h" + +static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; //!< Connection handle. +static nrf_ble_escs_t m_ble_ecs; //!< Struct identifying the Eddystone Config Service. +static nrf_ble_es_evt_handler_t m_evt_handler; //!< Event handler. + +/**@brief Function for invoking registered callback. + * + * @param[in] evt Event to issue to callback. + */ +static void handle_evt(nrf_ble_es_evt_t evt) +{ + if (m_evt_handler != NULL) + { + m_evt_handler(evt); + } +} + + +/**@brief Function resetting MAC address. Will resume advertisement. */ +static void new_address_set(void) +{ + + ret_code_t err_code; + uint8_t bytes_available; + ble_gap_addr_t new_address; + + new_address.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC; + + // Randomize the MAC address on every EID generation + (void)sd_rand_application_bytes_available_get(&bytes_available); + + while (bytes_available < BLE_GAP_ADDR_LEN) + { + // wait for SD to acquire enough RNs + (void)sd_rand_application_bytes_available_get(&bytes_available); + } + + (void)sd_rand_application_vector_get(new_address.addr, BLE_GAP_ADDR_LEN); + + // Stop advertising to ensure that it is possible to change the address. + (void)sd_ble_gap_adv_stop(); + + do + { +#if NRF_SD_BLE_API_VERSION >= 3 + err_code = sd_ble_gap_addr_set(&new_address); +#else + err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &new_address); +#endif // NRF_SD_BLE_API_VERSION + }while(err_code == NRF_ERROR_INVALID_STATE); + + APP_ERROR_CHECK(err_code); + + if(es_adv_remain_connectable_get()) + { + es_adv_start_connectable_adv(); + } + else + { + es_adv_start_non_connctable_adv(); + } +} + + +/**@brief Function updating MAC address if required. + * + * @param[in] demand_new_mac If 'true', mac address will be updated on next invocation when not connected. + * If 'false', simply check if we have an outstanding demand for new MAC and update if not connected. + */ +static void check_and_update_mac_address(bool demand_new_mac) +{ + static bool reset_mac_address = false; + + if (demand_new_mac) + { + reset_mac_address = true; + } + + // Not possible to update MAC address while in a connection + if (m_conn_handle != BLE_CONN_HANDLE_INVALID) + { + return; + } + + else if (reset_mac_address) + { + reset_mac_address = false; + + new_address_set(); + } +} + + +/**@brief Function to lock the beacon (change lock state characteristic to LOCKED) + */ +static void lock_beacon(void) +{ + *(m_ble_ecs.p_lock_state) = NRF_BLE_ESCS_LOCK_STATE_LOCKED; +} + + +/**@brief Function for handling BLE event from the SoftDevice. + * + * @param[in] p_ble_evt Pointer to BLE event. + */ +static void on_ble_evt(ble_evt_t * p_ble_evt) +{ + ret_code_t err_code; + es_flash_flags_t flash_flag = {{0}}; + const es_slot_reg_t * p_reg = es_slot_get_registry(); + + switch (p_ble_evt->header.evt_id) + { + case BLE_GAP_EVT_CONNECTED: + m_conn_handle = p_ble_evt->evt.common_evt.conn_handle; + *(m_ble_ecs.p_active_slot) = 0; + break; + + case BLE_GAP_EVT_DISCONNECTED: + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + for (uint32_t i = 0; i < APP_MAX_ADV_SLOTS; ++i) + { + err_code = es_slot_write_to_flash(i); + APP_ERROR_CHECK(err_code); + + flash_flag.slot_is_empty[i] = !p_reg->slots[i].configured; + } + + err_code = es_flash_access_flags(&flash_flag, ES_FLASH_ACCESS_WRITE); + APP_ERROR_CHECK(err_code); + + es_flash_beacon_config_t beacon_config; + beacon_config.adv_interval = es_adv_interval_get(); + beacon_config.remain_connectable = es_adv_remain_connectable_get(); + + err_code = es_flash_access_beacon_config(&beacon_config, ES_FLASH_ACCESS_WRITE); + APP_ERROR_CHECK(err_code); + + if (*m_ble_ecs.p_lock_state == NRF_BLE_ESCS_LOCK_STATE_UNLOCKED) + { + lock_beacon(); + } + + check_and_update_mac_address(false); + + break; + + default: + // No implementation needed. + break; + } +} + + +/**@brief Callback function to receive messages from the security module + * + * @details Need to be passed in during es_security_init(). The security + * module will callback anytime a particular security process is completed + * + * @params[in] slot_no Index of the slot + * @params[in] msg_type Message type corersponding to different security components + */ +static void nrf_ble_escs_security_cb(uint8_t slot_no, es_security_msg_t msg_type) +{ + nrf_ble_escs_eid_id_key_t encrypted_id_key; + nrf_ble_escs_public_ecdh_key_t pub_ecdh_key; + + ret_code_t err_code; + static ble_gatts_value_t value; + + switch (msg_type) + { + case ES_SECURITY_MSG_UNLOCKED: + *(m_ble_ecs.p_lock_state) = NRF_BLE_ESCS_LOCK_STATE_UNLOCKED; + break; + + case ES_SECURITY_MSG_EID: + es_slot_eid_ready(slot_no); +#ifdef MAC_RANDOMIZED + check_and_update_mac_address(true); +#endif // MAC_RANDOMIZED + break; + + case ES_SECURITY_MSG_IK: + es_security_encrypted_eid_id_key_get(slot_no, (uint8_t *)encrypted_id_key.key); + // Set the EID ID key in the slot so it can be exposed in the characteristic + es_slot_encrypted_eid_id_key_set(slot_no, &encrypted_id_key); + break; + + case ES_SECURITY_MSG_ECDH: + es_security_pub_ecdh_get(slot_no, (uint8_t *)pub_ecdh_key.key); + + // Set the characteristic to the ECDH key value + value.len = sizeof(nrf_ble_escs_public_ecdh_key_t); + value.offset = 0; + value.p_value = (uint8_t *)pub_ecdh_key.key; + + if (m_conn_handle != BLE_CONN_HANDLE_INVALID) + { + err_code = sd_ble_gatts_value_set(m_ble_ecs.conn_handle, + m_ble_ecs.pub_ecdh_key_handles.value_handle, + &value); + if (err_code != NRF_SUCCESS) + { + APP_ERROR_CHECK(err_code); + } + } + break; + + case ES_SECURITY_MSG_STORE_TIME: + // Every 24 hours any EID slots time is stored to flash to allow for power lock_state_handles + // recovery. Only time needs to be stored, but just store the entire slot anyway for API simplicity. + err_code = es_slot_write_to_flash(slot_no); + APP_ERROR_CHECK(err_code); + + break; + + default: + APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM); // Should never happen + break; + } +} + + +/**@brief Function for handling advertisement events from 'es_adv'. + * + * @param[in] evt Advertisement event to handle. + */ +static void adv_evt_handler(es_adv_evt_t evt) +{ + switch (evt) + { + case ES_ADV_EVT_NON_CONN_ADV: + handle_evt(NRF_BLE_ES_EVT_ADVERTISEMENT_SENT); + es_security_update_time(); + break; + + case ES_ADV_EVT_CONNECTABLE_ADV_STARTED: + handle_evt(NRF_BLE_ES_EVT_CONNECTABLE_ADV_STARTED); + break; + } +} + + +/**@brief Initialize the ECS with initial values for the characteristics and other necessary modules */ +static void ble_escs_init(void) +{ + ret_code_t err_code; + nrf_ble_escs_init_t ecs_init; + nrf_ble_escs_init_params_t init_params; + int8_t tx_powers[ESCS_NUM_OF_SUPPORTED_TX_POWER] = ESCS_SUPPORTED_TX_POWER; + + /*Init the broadcast capabilities characteristic*/ + memset(&init_params.broadcast_cap, 0, sizeof(init_params.broadcast_cap)); + init_params.broadcast_cap.vers_byte = ES_SPEC_VERSION_BYTE; + init_params.broadcast_cap.max_supp_total_slots = APP_MAX_ADV_SLOTS; + init_params.broadcast_cap.max_supp_eid_slots = APP_MAX_EID_SLOTS; + init_params.broadcast_cap.cap_bitfield = ( (APP_IS_VARIABLE_ADV_SUPPORTED << ESCS_BROADCAST_VAR_ADV_SUPPORTED_Pos) + | (APP_IS_VARIABLE_TX_POWER_SUPPORTED << ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Pos)) + & (ESCS_BROADCAST_VAR_RFU_MASK); + init_params.broadcast_cap.supp_frame_types = ( (APP_IS_URL_SUPPORTED << ESCS_FRAME_TYPE_URL_SUPPORTED_Pos) + | (APP_IS_UID_SUPPORTED << ESCS_FRAME_TYPE_UID_SUPPORTED_Pos) + | (APP_IS_TLM_SUPPORTED << ESCS_FRAME_TYPE_TLM_SUPPORTED_Pos) + | (APP_IS_EID_SUPPORTED << ESCS_FRAME_TYPE_EID_SUPPORTED_Pos)) + & (ESCS_FRAME_TYPE_RFU_MASK); + memcpy(init_params.broadcast_cap.supp_radio_tx_power, tx_powers, ESCS_NUM_OF_SUPPORTED_TX_POWER); + + init_params.adv_interval = APP_CFG_NON_CONN_ADV_INTERVAL_MS; + init_params.adv_tx_pwr = APP_CFG_DEFAULT_RADIO_TX_POWER; + init_params.radio_tx_pwr = 0x00; + init_params.factory_reset = 0; + init_params.remain_connectable.r_is_non_connectable_supported = APP_IS_REMAIN_CONNECTABLE_SUPPORTED; + + // Initialize evt handlers and the service + memset(&ecs_init, 0, sizeof(ecs_init)); + ecs_init.write_evt_handler = es_gatts_handle_write; + ecs_init.read_evt_handler = es_gatts_handle_read; + ecs_init.p_init_vals = &(init_params); + + err_code = nrf_ble_escs_init(&m_ble_ecs, &ecs_init); + APP_ERROR_CHECK(err_code); +} + + +/**@brief Function for initializing 'es_adv' module. */ +static void adv_init(void) +{ + ret_code_t err_code; + es_flash_beacon_config_t beacon_config; + + err_code = es_flash_access_beacon_config(&beacon_config, ES_FLASH_ACCESS_READ); + + if (err_code == FDS_ERR_NOT_FOUND) + { + beacon_config.adv_interval = APP_CFG_NON_CONN_ADV_INTERVAL_MS; + beacon_config.remain_connectable = false; + } + + else + { + APP_ERROR_CHECK(err_code); + } + + es_adv_init(m_ble_ecs.uuid_type, + adv_evt_handler, + beacon_config.adv_interval, + beacon_config.remain_connectable); +} + + +/**@brief Function for initializing es_slots module. */ +static void adv_slots_init(void) +{ + uint8_t default_frame_data[DEFAULT_FRAME_LENGTH] = DEFAULT_FRAME_DATA; + + es_slot_t default_adv_slot = {.slot_no = 0, + .radio_tx_pwr = 0, + .adv_frame.type = DEFAULT_FRAME_TYPE, + .adv_frame.length = DEFAULT_FRAME_LENGTH, + .adv_custom_tx_power = false, + .configured = true}; + + memcpy(&default_adv_slot.adv_frame.frame, default_frame_data, DEFAULT_FRAME_LENGTH); + + es_slots_init(&default_adv_slot); +} + + +void nrf_ble_es_on_ble_evt(ble_evt_t * p_ble_evt) +{ + ret_code_t err_code; + + es_adv_on_ble_evt(p_ble_evt); + err_code = nrf_ble_escs_on_ble_evt(&m_ble_ecs, p_ble_evt); + APP_ERROR_CHECK(err_code); + on_ble_evt(p_ble_evt); + es_flash_on_ble_evt(p_ble_evt); +} + + +void nrf_ble_es_on_start_connectable_advertising(void) +{ + es_adv_start_connectable_adv(); +} + + +void nrf_ble_es_init(nrf_ble_es_evt_handler_t evt_handler) +{ + ret_code_t err_code; + + m_evt_handler = evt_handler; + m_conn_handle = BLE_CONN_HANDLE_INVALID; + + es_stopwatch_init(); + + err_code = es_gatts_init(&m_ble_ecs); + APP_ERROR_CHECK(err_code); + + err_code = es_flash_init(); + APP_ERROR_CHECK(err_code); + + while (es_flash_num_pending_ops() > 0) + { + ; // Busy wait while initialization of FDS module completes + } + + err_code = es_security_init(nrf_ble_escs_security_cb); + APP_ERROR_CHECK(err_code); + + es_adv_timers_init(); + ble_escs_init(); + adv_slots_init(); + es_battery_voltage_init(); + adv_init(); + es_adv_start_non_connctable_adv(); +} diff --git a/components/libraries/eddystone/nrf_ble_es.h b/components/libraries/eddystone/nrf_ble_es.h new file mode 100644 index 0000000..b668cca --- /dev/null +++ b/components/libraries/eddystone/nrf_ble_es.h @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_ES_H__ +#define NRF_ES_H__ + +#include +#include "ble.h" + +/** + * @file + * @defgroup eddystone Eddystone library + * @ingroup app_common + * @{ + * + * @brief Library for Eddystone beacons. This library is used in the @ref ble_sdk_app_es. + * + * @note The API documentation is provided for reference only. You should + * not modify this library, and you should not use any functions + * except for the main level functions defined in @c nrf_ble_es.h + * in different contexts. + */ + +/** @brief Eddystone event types. */ +typedef enum { + NRF_BLE_ES_EVT_ADVERTISEMENT_SENT, //!< A non-connectable Eddystone frame advertisement was sent. + NRF_BLE_ES_EVT_CONNECTABLE_ADV_STARTED, //!< Advertising in connectable mode was started. +}nrf_ble_es_evt_t; + +/**@brief Eddystone event handler type. */ +typedef void (*nrf_ble_es_evt_handler_t)(nrf_ble_es_evt_t evt); + +/**@brief Function for handling the application's BLE stack events. + * + * @details This function handles all events from the BLE stack that are of + * interest to the Eddystone library. It must be called from the @ref + * softdevice_handler callback for all BLE events that are received from the + * SoftDevice. + * + * @param[in] p_ble_evt Event received from the BLE stack. + */ +void nrf_ble_es_on_ble_evt(ble_evt_t * p_ble_evt); + +/**@brief Function for putting the beacon in connectable mode. + * + * @details This function makes the beacon advertise connectable advertisements. + * If the beacon is in a connected state, the request is ignored. + */ +void nrf_ble_es_on_start_connectable_advertising(void); + +/** @brief Function for initializing the Eddystone library. + * + * @param[in] evt_handler Event handler to be called for handling BLE events. + */ +void nrf_ble_es_init(nrf_ble_es_evt_handler_t evt_handler); + +/** + * @} + */ + +#endif diff --git a/components/libraries/experimental_section_vars/section_vars.h b/components/libraries/experimental_section_vars/section_vars.h index 4d7f0e2..b103a3d 100644 --- a/components/libraries/experimental_section_vars/section_vars.h +++ b/components/libraries/experimental_section_vars/section_vars.h @@ -1,291 +1,285 @@ -#ifndef SECTION_VARS_H__ -#define SECTION_VARS_H__ - -#include "app_util.h" +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ -#if defined __ICC_ARM__ -// turn on language extensions for iar -#pragma language=extended +#ifndef SECTION_VARS_H__ +#define SECTION_VARS_H__ +#ifdef __cplusplus +extern "C" { #endif + /** * @defgroup section_vars Section variables * @ingroup app_common * @{ - * @brief Section variables. - */ - -/**@brief Macro to delay macro expression of pragma * + * @brief Section variables. */ -#define NRF_PRAGMA(x) _Pragma(#x) - - -/**@brief Macro to register section by name in code - * - * @param[in] section_name Name of the section to register - **/ -#if defined __CC_ARM - -// Not required by this compiler -#define NRF_SECTION_VARS_REGISTER_SECTION(section_name) - -#elif defined __GNUC__ -// Not required by this compiler -#define NRF_SECTION_VARS_REGISTER_SECTION(section_name) -#elif defined __ICCARM__ +#if defined(__ICCARM__) +// Enable IAR language extensions +#pragma language=extended +#endif -#define NRF_SECTION_VARS_REGISTER_SECTION(section_name) NRF_PRAGMA(section = ## #section_name ) -#else +// Macro to delay macro expansion. +#define NRF_PRAGMA(x) _Pragma(#x) -#error TODO -#endif +//lint -save -e27 Illegal character (0x24) -/*lint -save -e27 */ -/**@brief Macro for accessing start of a named data section by symbol +/**@brief Macro to obtain the symbol marking the beginning of a given section. * - * @details The symbol that this macro resolves to is used to access the section - * by start address. + * @details The symbol that this macro resolves to is used to obtain a section start address. * - * @param[in] section_name Name of the section + * @param[in] section_name Name of the section. */ -#if defined __CC_ARM +#if defined(__CC_ARM) #define NRF_SECTION_VARS_START_SYMBOL(section_name) section_name ## $$Base -#elif defined __GNUC__ +#elif defined(__GNUC__) #define NRF_SECTION_VARS_START_SYMBOL(section_name) __start_ ## section_name -#elif defined __ICCARM__ +#elif defined(__ICCARM__) #define NRF_SECTION_VARS_START_SYMBOL(section_name) __section_begin(#section_name) -#else - -#error TODO - #endif -/**@brief Macro for accessing end of a named data section by symbol +/**@brief Macro to obtain the symbol marking the end of a given section. * - * @details The symbol that this macro resolves to is used to access the section - * by end address. + * @details The symbol that this macro resolves to is used to obtain a section stop address. * - * @param[in] section_name Name of the section + * @param[in] section_name Name of the section. */ -#if defined __CC_ARM +#if defined(__CC_ARM) #define NRF_SECTION_VARS_END_SYMBOL(section_name) section_name ## $$Limit -#elif defined __GNUC__ +#elif defined(__GNUC__) #define NRF_SECTION_VARS_END_SYMBOL(section_name) __stop_ ## section_name -#elif defined __ICCARM__ +#elif defined(__ICCARM__) #define NRF_SECTION_VARS_END_SYMBOL(section_name) __section_end(#section_name) #endif -/*lint -restore */ +//lint -restore -/**@brief Macro for accessing Length of a named section - * - * @details This macro is used to get the size of a named section. + +/**@brief Macro for retrieving the length of a given section, in bytes. * - * @param[in] section_name Name of the section + * @param[in] section_name Name of the section. */ - -#if defined __CC_ARM +#if defined(__CC_ARM) #define NRF_SECTION_VARS_LENGTH(section_name) \ ((uint32_t)&NRF_SECTION_VARS_END_SYMBOL(section_name) - (uint32_t)&NRF_SECTION_VARS_START_SYMBOL(section_name)) -#elif defined __GNUC__ +#elif defined(__GNUC__) #define NRF_SECTION_VARS_LENGTH(section_name) \ ((uint32_t)&NRF_SECTION_VARS_END_SYMBOL(section_name) - (uint32_t)&NRF_SECTION_VARS_START_SYMBOL(section_name)) -#elif defined __ICCARM__ +#elif defined(__ICCARM__) #define NRF_SECTION_VARS_LENGTH(section_name) \ ((uint32_t)NRF_SECTION_VARS_END_SYMBOL(section_name) - (uint32_t)NRF_SECTION_VARS_START_SYMBOL(section_name)) -#else - -#error TODO - #endif - -/**@brief Macro for accessing the start address of a named section + +/**@brief Macro to obtain the address of the beginning of a section. * - * param[in] section_name Name of the section to get the start address from + * param[in] section_name Name of the section. */ -#if defined __CC_ARM +#if defined(__CC_ARM) #define NRF_SECTION_VARS_START_ADDR(section_name) (uint32_t)&NRF_SECTION_VARS_START_SYMBOL(section_name) - -#elif defined __GNUC__ - + +#elif defined(__GNUC__) + #define NRF_SECTION_VARS_START_ADDR(section_name) (uint32_t)&NRF_SECTION_VARS_START_SYMBOL(section_name) - -#elif defined __ICCARM__ - + +#elif defined(__ICCARM__) + #define NRF_SECTION_VARS_START_ADDR(section_name) (uint32_t)iar_ ## section_name ## _start -#else - -#error TODO - #endif - -/*@brief Macro for accessing the end address of a named section + +/**@brief Macro to obtain the address of end of a section. * - * @param[in] section_name Name of the section to get end address from + * @param[in] section_name Name of the section. */ -#if defined __CC_ARM +#if defined(__CC_ARM) #define NRF_SECTION_VARS_END_ADDR(section_name) (uint32_t)&NRF_SECTION_VARS_END_SYMBOL(section_name) - -#elif defined __GNUC__ + +#elif defined(__GNUC__) #define NRF_SECTION_VARS_END_ADDR(section_name) (uint32_t)&NRF_SECTION_VARS_END_SYMBOL(section_name) - -#elif defined __ICCARM__ + +#elif defined(__ICCARM__) #define NRF_SECTION_VARS_END_ADDR(section_name) (uint32_t)iar_ ## section_name ## _end -#else - -#error TODO - #endif -/**@brief Macro for declaring symbols for named sections +//lint -save -e19 -esym(526, fs_dataBase) -esym(526, fs_dataLimit) -esym(526, dfu_transBase) -esym(526, dfu_transLimit) + +/**@brief Macro to create a section to register variables in. * - * @note These external declarations of section specific symbols are required for the linker in GCC and Keil (not IAR) + * @param[in] data_type The data type of the variables to be registered in the section. + * @param[in] section_name Name of the section. * - * @param[in] type_name Name of the type stored in the section - * @param[in] section_name Name of the section + * @warning The data type must be word aligned to prevent padding. */ -#if defined __CC_ARM +#if defined(__CC_ARM) -#define NRF_SECTION_VARS_REGISTER_SYMBOLS(type_name, section_name) \ - extern type_name* NRF_SECTION_VARS_START_SYMBOL(section_name); \ - extern void* NRF_SECTION_VARS_END_SYMBOL(section_name) +#define NRF_SECTION_VARS_CREATE_SECTION(section_name, data_type) \ + extern data_type * NRF_SECTION_VARS_START_SYMBOL(section_name); \ + extern void * NRF_SECTION_VARS_END_SYMBOL(section_name) -#elif defined __GNUC__ +#elif defined(__GNUC__) -#define NRF_SECTION_VARS_REGISTER_SYMBOLS(type_name, section_name) \ - extern type_name* NRF_SECTION_VARS_START_SYMBOL(section_name); \ - extern void* NRF_SECTION_VARS_END_SYMBOL(section_name) +#define NRF_SECTION_VARS_CREATE_SECTION(section_name, data_type) \ + extern data_type * NRF_SECTION_VARS_START_SYMBOL(section_name); \ + extern void * NRF_SECTION_VARS_END_SYMBOL(section_name) -#elif defined __ICCARM__ +#elif defined(__ICCARM__) -// No symbol registration required for IAR -#define NRF_SECTION_VARS_REGISTER_SYMBOLS(type_name, section_name) \ - extern void* iar_ ## section_name ## _start = __section_begin(#section_name); \ - extern void* iar_ ## section_name ## _end = __section_end(#section_name) - -#else - -#error TODO +// No symbol registration required for IAR. +#define NRF_SECTION_VARS_CREATE_SECTION(section_name, data_type) \ + NRF_PRAGMA(section = #section_name); \ + extern void * iar_ ## section_name ## _start = __section_begin(#section_name); \ + extern void * iar_ ## section_name ## _end = __section_end(#section_name) #endif +//lint -restore -/**@brief Macro to add symbols to a named section - * - * @details The symbols are placed in a named section. All calls to this macro - * will result in symbols being placed in a contiguous manner in the named section. - * This macro ensures that the symbol is not removed because of optimization level. + +/**@brief Macro to declare a variable and register it in a section. * - * @warning There is no guarantee for ordering of placement. If ordering is required + * @details Declares a variable and registers it in a named section. This macro ensures that the + * variable is not stripped away when using optimizations. * - * @warning The symbols added in the named section must be word aligned to - * ensure that compilers do not pad the section during symbol placement. + * @note The order with which variables are placed in a section is dependant on the order with + * which the linker encouters the variables during linking. * - * @param[in] section_name Name of the section - * @param[in] type_def Datatype of the symbol to place in the given section + * @param[in] section_name Name of the section. + * @param[in] section_var The variable to register in the given section. */ -#if defined __CC_ARM - -#define NRF_SECTION_VARS_ADD(section_name, type_def) \ - static type_def __attribute__((section( #section_name ))) __attribute__((used)) +#if defined(__CC_ARM) -#elif defined __GNUC__ +#define NRF_SECTION_VARS_REGISTER_VAR(section_name, section_var) \ + static section_var __attribute__ ((section(#section_name))) __attribute__((used)) -#define NRF_SECTION_VARS_ADD(section_name, type_def) \ - static type_def __attribute__ ((section( #section_name ))) __attribute__ ((used)) +#elif defined(__GNUC__) -#elif defined __ICCARM__ +#define NRF_SECTION_VARS_REGISTER_VAR(section_name, section_var) \ + static section_var __attribute__ ((section("."#section_name))) __attribute__((used)) -#define NRF_SECTION_VARS_ADD(section_name, type_def) \ - __root type_def @ #section_name +#elif defined(__ICCARM__) -#else - -#error TODO - -#endif +#define NRF_SECTION_VARS_REGISTER_VAR(section_name, section_var) \ + __root section_var @ #section_name - -/**@brief Macro to get symbol from named section +#endif + + +/**@brief Macro to retrieve a variable from a section. * - * @warning The stored symbol can only be resolved using this macro if the - * type of the data is word aligned. The operation of acquiring - * the stored symbol relies on sizeof of the stored type, no - * padding can exist in the named section in between individual + * @warning The stored symbol can only be resolved using this macro if the + * type of the data is word aligned. The operation of acquiring + * the stored symbol relies on sizeof of the stored type, no + * padding can exist in the named section in between individual * stored items or this macro will fail. * - * @param[in] i Index of item in section - * @param[in] type_name Type name of item in section - * @param[in] section_name Name of the section + * @param[in] i Index of the variable in section. + * @param[in] data_type Data type of the variable. + * @param[in] section_name Name of the section. */ - -#if defined __CC_ARM +#if defined(__CC_ARM) -#define NRF_SECTION_VARS_GET(i, type_name, section_name) \ - (type_name*)(NRF_SECTION_VARS_START_ADDR(section_name) + i * sizeof(type_name)) - -#elif defined __GNUC__ +#define NRF_SECTION_VARS_GET(i, data_type, section_name) \ + (data_type*)(NRF_SECTION_VARS_START_ADDR(section_name) + i * sizeof(data_type)) -#define NRF_SECTION_VARS_GET(i, type_name, section_name) \ - (type_name*)(NRF_SECTION_VARS_START_ADDR(section_name) + i * sizeof(type_name)) - -#elif defined __ICCARM__ +#elif defined(__GNUC__) -#define NRF_SECTION_VARS_GET(i, type_name, section_name) \ - (type_name*)iar_ ## section_name ## _start + (i * sizeof(type_name)) +#define NRF_SECTION_VARS_GET(i, data_type, section_name) \ + (data_type*)(NRF_SECTION_VARS_START_ADDR(section_name) + i * sizeof(data_type)) -#else +#elif defined(__ICCARM__) -#error TODO +#define NRF_SECTION_VARS_GET(i, data_type, section_name) \ + (data_type*)(NRF_SECTION_VARS_START_ADDR(section_name) + i * sizeof(data_type)) #endif -/**@brief Macro to get number of items in named section +/**@brief Macro to get number of variables registered in a section. * - * @param[in] type_name Type name of item in section - * @param[in] section_name Name of the section + * @param[in] data_type Data type of the variables in the section. + * @param[in] section_name Name of the section. */ -#define NRF_SECTION_VARS_COUNT(type_name, section_name) \ - NRF_SECTION_VARS_LENGTH(section_name) / sizeof(type_name) +#define NRF_SECTION_VARS_COUNT(data_type, section_name) \ + NRF_SECTION_VARS_LENGTH(section_name) / sizeof(data_type) /** @} */ + +#ifdef __cplusplus +} +#endif + #endif // SECTION_VARS_H__ diff --git a/components/libraries/fds/fds.c b/components/libraries/fds/fds.c index 0a019b2..7c0a944 100644 --- a/components/libraries/fds/fds.c +++ b/components/libraries/fds/fds.c @@ -1,2070 +1,2104 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(FDS) #include "fds.h" +#include "fds_internal_defs.h" + #include #include #include -#include "fds_config.h" -#include "fds_types_internal.h" #include "fstorage.h" #include "nrf_error.h" -#include "app_util.h" - - -/** Our fstorage configuration. - * The other fields will be assigned automatically during compilation. */ -FS_SECTION_VARS_ADD(fs_config_t fs_config) = { .cb = fs_callback, .num_pages = FDS_MAX_PAGES }; -static uint32_t const fds_page_tag_swap[] = {FDS_PAGE_TAG_WORD_0_SWAP, FDS_PAGE_TAG_WORD_1, - FDS_PAGE_TAG_WORD_2, FDS_PAGE_TAG_WORD_3}; - -static uint32_t const fds_page_tag_valid[] = {FDS_PAGE_TAG_WORD_0_VALID, FDS_PAGE_TAG_WORD_1, - FDS_PAGE_TAG_WORD_2, FDS_PAGE_TAG_WORD_3}; - -static uint32_t const fds_page_tag_gc = FDS_PAGE_TAG_WORD_3_GC; +#if defined(FDS_CRC_ENABLED) + #include "crc16.h" +#endif -static fds_tl_t const m_fds_tl_invalid = { .type = FDS_TYPE_ID_INVALID, - .length_words = 0xFFFF }; -/**@brief Internal status flags. */ -static uint8_t volatile m_flags; +static void fs_event_handler(fs_evt_t const * const evt, fs_ret_t result); -static uint8_t m_users; -static fds_cb_t m_cb_table[FDS_MAX_USERS]; +// Our fstorage configuration. +FS_REGISTER_CFG(fs_config_t fs_config) = +{ + .callback = fs_event_handler, + .num_pages = FDS_PHY_PAGES, + // We register with the highest priority in order to be assigned + // the pages with the highest memory address (closest to the bootloader). + .priority = 0xFF +}; -/**@brief The last record ID. Setup page by page_scan() during pages_init(). */ -static fds_record_id_t m_last_rec_id; +// Used to flag a record as dirty, i.e. ready for garbage collection. +// Must be statically allocated since it will be written to flash. +__ALIGN(4) static fds_tl_t const m_fds_tl_dirty = +{ + .record_key = FDS_RECORD_KEY_DIRTY, + .length_words = 0xFFFF // Leave the record length field unchanged in flash. +}; -/**@brief The internal queues. */ -static fds_cmd_queue_t m_cmd_queue; -static fds_chunk_queue_t m_chunk_queue; +// Internal status flags. +static uint8_t m_flags; -/**@brief Holds the state of pages. Setup by fds_init(). */ -static fds_page_t m_pages[FDS_MAX_PAGES]; -static bool m_swap_page_avail = false; +// The number of registered users and their callback functions. +static uint8_t m_users; +static fds_cb_t m_cb_table[FDS_MAX_USERS]; -static fds_gc_data_t m_gc; -static uint16_t m_gc_runs; +// The latest (largest) record ID written so far. +static uint32_t m_latest_rec_id; -static uint8_t volatile m_counter; +// The internal queues. +static fds_op_queue_t m_op_queue; +static fds_chunk_queue_t m_chunk_queue; +// Structures used to hold informations about virtual pages. +static fds_page_t m_pages[FDS_MAX_PAGES]; +static fds_swap_page_t m_swap_page; -static void app_notify(ret_code_t result, - fds_cmd_id_t cmd, - fds_record_id_t record_id, - fds_record_key_t record_key) -{ - for (uint8_t user = 0; user < FDS_MAX_USERS; user++) - { - if (m_cb_table[user] != NULL) - { - m_cb_table[user](result, cmd, record_id, record_key); - } - } -} +// Garbage collection data. +static fds_gc_data_t m_gc; -static void atomic_counter_inc() +static void flag_set(fds_flags_t flag) { CRITICAL_SECTION_ENTER(); - m_counter++; + m_flags |= flag; CRITICAL_SECTION_EXIT(); } -static void atomic_counter_dec() +static void flag_clear(fds_flags_t flag) { CRITICAL_SECTION_ENTER(); - m_counter--; + m_flags &= ~(flag); CRITICAL_SECTION_EXIT(); } -static bool atomic_counter_is_zero() +static bool flag_is_set(fds_flags_t flag) { - bool ret; - CRITICAL_SECTION_ENTER(); - ret = (m_counter == 0); - CRITICAL_SECTION_EXIT(); - return ret; + return (m_flags & flag); } -static void flag_set(fds_flags_t flag) +static void event_send(fds_evt_t const * const p_evt) { - CRITICAL_SECTION_ENTER(); - m_flags |= flag; - CRITICAL_SECTION_EXIT(); + for (uint32_t user = 0; user < FDS_MAX_USERS; user++) + { + if (m_cb_table[user] != NULL) + { + m_cb_table[user](p_evt); + } + } } -static void flag_clear(fds_flags_t flag) +static void event_prepare(fds_op_t const * const p_op, fds_evt_t * const p_evt) { - CRITICAL_SECTION_ENTER(); - m_flags &= ~(flag); - CRITICAL_SECTION_EXIT(); -} + switch (p_op->op_code) + { + case FDS_OP_INIT: + p_evt->id = FDS_EVT_INIT; + break; + case FDS_OP_WRITE: + p_evt->id = FDS_EVT_WRITE; + p_evt->write.file_id = p_op->write.header.ic.file_id; + p_evt->write.record_key = p_op->write.header.tl.record_key; + p_evt->write.record_id = p_op->write.header.record_id; + break; -static bool flag_is_set(fds_flags_t flag) -{ - bool ret; - CRITICAL_SECTION_ENTER(); - ret = (m_flags & flag); - CRITICAL_SECTION_EXIT(); - return ret; -} + case FDS_OP_UPDATE: + p_evt->id = FDS_EVT_UPDATE; + p_evt->write.file_id = p_op->write.header.ic.file_id; + p_evt->write.record_key = p_op->write.header.tl.record_key; + p_evt->write.record_id = p_op->write.header.record_id; + p_evt->write.is_record_updated = (p_op->write.step == FDS_OP_WRITE_DONE); + break; + case FDS_OP_DEL_RECORD: + p_evt->id = FDS_EVT_DEL_RECORD; + p_evt->del.file_id = p_op->del.file_id; + p_evt->del.record_key = p_op->del.record_key; + p_evt->del.record_id = p_op->del.record_to_delete; + break; -/**@brief Function to check if a header has valid information. */ -static __INLINE bool header_is_valid(fds_header_t const * const p_header) -{ - return ((p_header->tl.type != FDS_TYPE_ID_INVALID) && - (p_header->ic.instance != FDS_INSTANCE_ID_INVALID)); + case FDS_OP_DEL_FILE: + p_evt->id = FDS_EVT_DEL_FILE; + p_evt->del.file_id = p_op->del.file_id; + p_evt->del.record_key = FDS_RECORD_KEY_DIRTY; + break; + + case FDS_OP_GC: + p_evt->id = FDS_EVT_GC; + break; + + default: + // Should not happen. + break; + } } -static bool address_within_page_bounds(uint32_t const * const p_addr) +static bool header_is_valid(fds_header_t const * const p_header) { - return (p_addr >= fs_config.p_start_addr) && - (p_addr <= fs_config.p_end_addr) && - (is_word_aligned(p_addr)); + return ((p_header->ic.file_id != FDS_FILE_ID_INVALID) && + (p_header->tl.record_key != FDS_RECORD_KEY_DIRTY)); } -/**@brief Internal function to identify the page type. */ -static fds_page_type_t page_identify(uint16_t page_number) +static bool address_is_valid(uint32_t const * const p_addr) { - uint32_t const * const p_page_addr = m_pages[page_number].start_addr; + return ((p_addr != NULL) && + (p_addr >= fs_config.p_start_addr) && + (p_addr <= fs_config.p_end_addr) && + (is_word_aligned(p_addr))); +} - uint32_t const word0 = *(p_page_addr); - uint32_t const word1 = *(p_page_addr + 1); - uint32_t const word2 = *(p_page_addr + 2); - uint32_t const word3 = *(p_page_addr + 3); - if (word1 != FDS_PAGE_TAG_WORD_1) +static bool chunk_is_aligned(fds_record_chunk_t const * const p_chunk, uint32_t num_chunks) +{ + for (uint32_t i = 0; i < num_chunks; i++) { - return FDS_PAGE_UNDEFINED; + if (!is_word_aligned(p_chunk[i].p_data)) + { + return false; + } } + return true; +} + - if (word2 != FDS_PAGE_TAG_WORD_2) +// Reads a page tag, and determines if the page is used to store data or as swap. +static fds_page_type_t page_identify(uint32_t const * const p_page_addr) +{ + if (p_page_addr[FDS_PAGE_TAG_WORD_0] != FDS_PAGE_TAG_MAGIC) { return FDS_PAGE_UNDEFINED; } - if (word3 == FDS_PAGE_TAG_WORD_3) + switch (p_page_addr[FDS_PAGE_TAG_WORD_1]) { - if (word0 == FDS_PAGE_TAG_WORD_0_SWAP) - { + case FDS_PAGE_TAG_SWAP: return FDS_PAGE_SWAP; - } - if (word0 == FDS_PAGE_TAG_WORD_0_VALID) - { - return FDS_PAGE_VALID; - } + case FDS_PAGE_TAG_DATA: + return FDS_PAGE_DATA; + + default: + return FDS_PAGE_UNDEFINED; } - else if (word3 == FDS_PAGE_TAG_WORD_3_GC) +} + + +static bool page_is_erased(uint32_t const * const p_page_addr) +{ + for (uint32_t i = 0; i < FDS_PAGE_SIZE; i++) { - if (word0 == FDS_PAGE_TAG_WORD_0_SWAP || word0 == FDS_PAGE_TAG_WORD_0_VALID) + if (*(p_page_addr + i) != FDS_ERASED_WORD) { - return FDS_PAGE_GC; + return false; } } - return FDS_PAGE_UNDEFINED; + return true; } -static uint16_t page_by_addr(uint32_t const * const p_addr) +// NOTE: Must be called from within a critical section. +static bool page_has_space(uint16_t page, uint16_t length_words) { - if (p_addr == NULL) - { - return 0; - } - - // Compute the BYTES offset from the beginning of the first page. - uint32_t const byte_offset = (uint32_t)p_addr - (uint32_t)m_pages[0].start_addr; - -// See nrf.h. -#if defined (NRF51) - return byte_offset >> 10; // Divide by page size (1024). -#elif defined (NRF52) - return byte_offset >> 12; // Divide by page size (4096). -#else - #error "Device family must be defined. See nrf.h." -#endif + length_words += m_pages[page].write_offset; + length_words += m_pages[page].words_reserved; + return (length_words < FDS_PAGE_SIZE); } -// NOTE: depends on m_pages.write_offset to function. -static bool page_has_space(uint16_t page, fds_length_t length_words) +// Given a pointer to a record, find the index of the page on which it is stored. +// Returns FDS_SUCCESS if the page is found, FDS_ERR_NOT_FOUND otherwise. +static ret_code_t page_from_record(uint16_t * const p_page, uint32_t const * const p_rec) { - if (page >= FDS_MAX_PAGES) - { - return false; - } + ret_code_t ret = FDS_ERR_NOT_FOUND; CRITICAL_SECTION_ENTER(); - length_words += m_pages[page].write_offset; - length_words += m_pages[page].words_reserved; + for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) + { + if ((p_rec > m_pages[i].p_addr) && + (p_rec < m_pages[i].p_addr + FDS_PAGE_SIZE)) + { + ret = FDS_SUCCESS; + *p_page = i; + break; + } + } CRITICAL_SECTION_EXIT(); - return (length_words < FS_PAGE_SIZE_WORDS); + return ret; } -/**@brief This function scans a page to determine how many words have - * been written to it. This information is used to set the page - * write offset during initialization (mount). Additionally, this - * function will update the last known record ID as it proceeds. - */ -static void page_scan(uint16_t page, uint16_t volatile * words_written) +// Scan a page to determine how many words have been written to it. +// This information is used to set the page write offset during initialization. +// Additionally, this function updates the latest record ID as it proceeds. +// If an invalid record header is found, the can_gc argument is set to true. +static void page_scan(uint32_t const * p_addr, + uint16_t * const words_written, + bool * const can_gc) { - uint32_t const * p_addr = (m_pages[page].start_addr + FDS_PAGE_TAG_SIZE); + uint32_t const * const p_end_addr = p_addr + FDS_PAGE_SIZE; + bool dirty_record_found = false; - *words_written = FDS_PAGE_TAG_SIZE; + p_addr += FDS_PAGE_TAG_SIZE; + *words_written = FDS_PAGE_TAG_SIZE; - // A corrupt TL might cause problems. - while ((p_addr < m_pages[page].start_addr + FS_PAGE_SIZE_WORDS) && - (*p_addr != FDS_ERASED_WORD)) + while ((p_addr < p_end_addr) && (*p_addr != FDS_ERASED_WORD)) { + // NOTE: Skip records with a dirty key or with a missing file ID. fds_header_t const * const p_header = (fds_header_t*)p_addr; - /** Note: DO NOT check for the validity of the header using - * header_is_valid() here. If an header has an invalid type (0x0000) - * or a missing instance (0xFFFF) then we WANT to skip it. - */ + if (!header_is_valid(p_header)) + { + dirty_record_found = true; + } + else + { + // Update the latest (largest) record ID. + if (p_header->record_id > m_latest_rec_id) + { + m_latest_rec_id = p_header->record_id; + } + } - // Update the last known record id. - if (p_header->id > m_last_rec_id) - { - m_last_rec_id = p_header->id; - } + // Jump to the next record. + p_addr += (FDS_HEADER_SIZE + p_header->tl.length_words); + *words_written += (FDS_HEADER_SIZE + p_header->tl.length_words); + } - // Jump to the next record. - p_addr += (FDS_HEADER_SIZE + p_header->tl.length_words); - *words_written += (FDS_HEADER_SIZE + p_header->tl.length_words); + if (can_gc != NULL) + { + *can_gc = dirty_record_found; } } -static bool page_is_empty(uint16_t page) +static void page_offsets_update(fds_page_t * const p_page, uint16_t length_words) { - uint32_t const * const p_addr = m_pages[page].start_addr; + p_page->write_offset += (FDS_HEADER_SIZE + length_words); + p_page->words_reserved -= (FDS_HEADER_SIZE + length_words); +} - for (uint16_t i = 0; i < FS_PAGE_SIZE_WORDS; i++) - { - if (*(p_addr + i) != FDS_ERASED_WORD) - { - return false; - } - } - return true; +// Tags a page as swap, i.e., reserved for GC. +static ret_code_t page_tag_write_swap() +{ + // Needs to be statically allocated since it will be written to flash. + static uint32_t const page_tag_swap[] = {FDS_PAGE_TAG_MAGIC, FDS_PAGE_TAG_SWAP}; + return fs_store(&fs_config, m_swap_page.p_addr, page_tag_swap, FDS_PAGE_TAG_SIZE, NULL); } -static ret_code_t page_id_from_virtual_id(uint16_t vpage_id, uint16_t * p_page_id) +// Tags a page as data, i.e, ready for storage. +static ret_code_t page_tag_write_data(uint32_t const * const p_page_addr) { - for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) - { - if (m_pages[i].vpage_id == vpage_id) - { - *p_page_id = i; - return NRF_SUCCESS; - } - } - - return NRF_ERROR_NOT_FOUND; + // Needs to be statically allocated since it will be written to flash. + static uint32_t const page_tag_data[] = {FDS_PAGE_TAG_MAGIC, FDS_PAGE_TAG_DATA}; + return fs_store(&fs_config, p_page_addr, page_tag_data, FDS_PAGE_TAG_SIZE, NULL); } -static ret_code_t page_from_virtual_id(uint16_t vpage_id, fds_page_t ** p_page) +// Reserve space on a page. +// NOTE: this function takes into the account the space required for the record header. +static ret_code_t write_space_reserve(uint16_t length_words, uint16_t * p_page) { - for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) + bool space_reserved = false; + uint16_t const total_len_words = length_words + FDS_HEADER_SIZE; + + if (total_len_words >= FDS_PAGE_SIZE - FDS_PAGE_TAG_SIZE) { - if (m_pages[i].vpage_id == vpage_id) - { - *p_page = &m_pages[i]; - return NRF_SUCCESS; - } + return FDS_ERR_RECORD_TOO_LARGE; } - return NRF_ERROR_NOT_FOUND; -} - - -static uint32_t record_id_new() -{ - return ++m_last_rec_id; -} + CRITICAL_SECTION_ENTER(); + for (uint16_t page = 0; page < FDS_MAX_PAGES; page++) + { + if ((m_pages[page].page_type == FDS_PAGE_DATA) && + (page_has_space(page, total_len_words))) + { + space_reserved = true; + *p_page = page; + m_pages[page].words_reserved += total_len_words; + break; + } + } + CRITICAL_SECTION_EXIT(); -/**@brief Tags a page as swap, i.e., reserved for GC. */ -static ret_code_t page_tag_write_swap(uint16_t page) -{ - return fs_store(&fs_config, - m_pages[page].start_addr, - (uint32_t const *)&fds_page_tag_swap, - FDS_PAGE_TAG_SIZE); + return (space_reserved) ? FDS_SUCCESS : FDS_ERR_NO_SPACE_IN_FLASH; } -/**@brief Tags a page as valid, i.e, ready for storage. */ -static ret_code_t page_tag_write_valid(uint16_t page) +// Undo a write_space_reserve() call. +// NOTE: Must be called within a critical section. +static void write_space_free(uint16_t length_words, uint16_t page) { - return fs_store(&fs_config, - m_pages[page].start_addr, - (uint32_t const *)&fds_page_tag_valid, - FDS_PAGE_TAG_SIZE); + m_pages[page].words_reserved -= (length_words + FDS_HEADER_SIZE); } -/**@brief Tags a valid page as being garbage collected. */ -static ret_code_t page_tag_write_gc(uint16_t page) +static uint32_t record_id_new(void) { - return fs_store(&fs_config, - m_pages[page].start_addr + 3, - (uint32_t const *)&fds_page_tag_gc, - 1 /*Words*/); + CRITICAL_SECTION_ENTER(); + m_latest_rec_id++; + CRITICAL_SECTION_EXIT(); + return m_latest_rec_id; } -/**@brief Given a page and a record, finds the next valid record. */ -static ret_code_t scan_next_valid(uint16_t page, uint32_t const ** p_record) +// Given a page and a record, finds the next valid record on that page. If p_record is NULL, +// search from the beginning of the page, otherwise, resume searching from the address +// pointed by p_record. Returns true if a record is found, returns false otherwise. +// If no record is found, p_record is unchanged. +static bool record_find_next(uint16_t page, uint32_t const ** p_record) { - uint32_t const * p_next_rec = (*p_record); + fds_header_t const * p_header; + uint32_t const * p_next_rec = (*p_record); - if (p_next_rec == NULL) + // If this is not the first invocation on this page, then jump to the next record. + // Otherwise, start searching from the beginning of the page. + if (p_next_rec != NULL) { - // This if the first invocation on this page, start from the beginning. - p_next_rec = m_pages[page].start_addr + FDS_PAGE_TAG_SIZE; + p_header = ((fds_header_t*)p_next_rec); + p_next_rec += (FDS_HEADER_SIZE + p_header->tl.length_words); } else { - // Jump to the next record. - p_next_rec += (FDS_HEADER_SIZE + ((fds_header_t*)(*p_record))->tl.length_words); + p_next_rec = m_pages[page].p_addr + FDS_PAGE_TAG_SIZE; } - // Scan until we find a valid record or until the end of the page. - - /** README: We might seek until the write_offset is reached, but it might not - * known at this point. */ - while ((p_next_rec < (m_pages[page].start_addr + FS_PAGE_SIZE_WORDS)) && - (*p_next_rec != FDS_ERASED_WORD)) // Did we jump to an erased word? + // Read records from the page, until a valid record is found or the end of the page is + // reached. The argument p_record is only updated if a valid record is found. + while ((p_next_rec < (m_pages[page].p_addr + FDS_PAGE_SIZE) && + *p_next_rec != FDS_ERASED_WORD)) { - fds_header_t const * const p_header = (fds_header_t*)p_next_rec; + p_header = (fds_header_t*)p_next_rec; if (header_is_valid(p_header)) { - // Bingo! *p_record = p_next_rec; - return NRF_SUCCESS; + return true; } else { - // The item is not valid, jump to the next. + // The record is not valid, jump to the next. p_next_rec += (FDS_HEADER_SIZE + (p_header->tl.length_words)); } } - return NRF_ERROR_NOT_FOUND; + // No more valid records on this page. + return false; } -static ret_code_t seek_record(fds_record_desc_t * const p_desc) +// Find a record given its descriptor and retrive the page in which the record is stored. +// NOTE: Do not pass NULL as an argument for p_page. +static bool record_find_by_desc(fds_record_desc_t * const p_desc, uint16_t * const p_page) { - uint32_t const * p_record; - uint16_t page; - bool seek_all_pages = false; + // If the gc_run_count field in the descriptor matches our counter, then the record has + // not been moved. If the address is valid, and the record ID matches, there is no need + // to find the record again. Only lookup the page in which the record is stored. - if ((p_desc->ptr_magic == FDS_MAGIC_HWORD) && - (p_desc->gc_magic == m_gc_runs)) + if ((address_is_valid(p_desc->p_record)) && + (p_desc->gc_run_count == m_gc.run_count) && + (p_desc->record_id == ((fds_header_t*)p_desc->p_record)->record_id)) { - // No need to seek the file. - return NRF_SUCCESS; + return (page_from_record(p_page, p_desc->p_record) == FDS_SUCCESS); } - /** The pointer in the descriptor is not initialized, or GC - * has been run since the last time it was retrieved. - * We must seek the record again. */ - - // Obtain the physical page ID. - if (page_id_from_virtual_id(p_desc->vpage_id, &page) != NRF_SUCCESS) + // Otherwise, find the record in flash. + for (*p_page = 0; *p_page < FDS_MAX_PAGES; (*p_page)++) { - page = 0; - seek_all_pages = true; - } - - do { - // Let's find the address from where we should start seeking the record. - p_record = m_pages[page].start_addr + FDS_PAGE_TAG_SIZE; + // Set p_record to NULL to make record_find_next() search from the beginning of the page. + uint32_t const * p_record = NULL; - /** Seek for a record with matching ID. - * We might get away with seeking to the page write offset, if it is known. */ - - while ((p_record < (m_pages[page].start_addr + FS_PAGE_SIZE_WORDS)) && - (*p_record != FDS_ERASED_WORD)) + while (record_find_next(*p_page, &p_record)) { fds_header_t const * const p_header = (fds_header_t*)p_record; - - if ((p_header->id != p_desc->record_id) || - (!header_is_valid(p_header))) - { - // ID doesnt't match or the record has been cleared. Jump to the next record. - p_record += FDS_HEADER_SIZE + p_header->tl.length_words; - } - else + if (p_header->record_id == p_desc->record_id) { - // Update the pointer in the descriptor. - p_desc->p_rec = p_record; - p_desc->ptr_magic = FDS_MAGIC_HWORD; - p_desc->gc_magic = m_gc_runs; - - return NRF_SUCCESS; + p_desc->p_record = p_record; + p_desc->gc_run_count = m_gc.run_count; + return true; } } - } while (seek_all_pages ? page++ < FDS_MAX_PAGES : 0); + } - return NRF_ERROR_NOT_FOUND; + return false; } -static ret_code_t find_record(fds_type_id_t const * const p_type, - fds_instance_id_t const * const p_inst, +// Search for a record and return its descriptor. +// If p_file_id is NULL, only the record key will be used for matching. +// If p_record_key is NULL, only the file ID will be used for matching. +// If both are NULL, it will iterate through all records. +static ret_code_t record_find(uint16_t const * const p_file_id, + uint16_t const * const p_record_key, fds_record_desc_t * const p_desc, fds_find_token_t * const p_token) { if (!flag_is_set(FDS_FLAG_INITIALIZED)) { - return NRF_ERROR_INVALID_STATE; + return FDS_ERR_NOT_INITIALIZED; } - // Here we distinguish between the first invocation and the and the others. - if ((p_token->magic != FDS_MAGIC_WORD) || - !address_within_page_bounds(p_token->p_addr)) // Is the address is really okay? - { - // Initialize the token. - p_token->magic = FDS_MAGIC_WORD; - p_token->vpage_id = 0; - p_token->p_addr = NULL; - } - else + if (p_desc == NULL || p_token == NULL) { - // Look past the last record address. - p_token->p_addr += (FDS_HEADER_SIZE + ((fds_header_t*)p_token->p_addr)->tl.length_words); + return FDS_ERR_NULL_ARG; } // Begin (or resume) searching for a record. - for (; p_token->vpage_id < FDS_MAX_PAGES; p_token->vpage_id++) + for (; p_token->page < FDS_MAX_PAGES; p_token->page++) { - uint16_t page = 0; - - // Obtain the physical page ID. - page_id_from_virtual_id(p_token->vpage_id, &page); - - if (m_pages[page].page_type != FDS_PAGE_VALID) + if (m_pages[p_token->page].page_type != FDS_PAGE_DATA) { // Skip this page. continue; } - if (p_token->p_addr == NULL) - { - // If it's the first time the function is run, initialize the pointer. - p_token->p_addr = m_pages[page].start_addr + FDS_PAGE_TAG_SIZE; - } - - // Seek a valid record on this page, starting from the address stored in the token. - while ((p_token->p_addr < (m_pages[page].start_addr + FS_PAGE_SIZE_WORDS)) && - (*p_token->p_addr != FDS_ERASED_WORD)) // Did we jump to an erased word? + while (record_find_next(p_token->page, &p_token->p_addr)) { fds_header_t const * const p_header = (fds_header_t*)p_token->p_addr; - if (header_is_valid(p_header)) + // A valid record was found, check its header for a match. + if ((p_file_id != NULL) && + (p_header->ic.file_id != *p_file_id)) { - // A valid record was found, check its header for a match. - bool item_match = false; - - if (p_type != NULL) - { - if (p_header->tl.type == *p_type) - { - item_match = true; - } - } - - if (p_inst != NULL) - { - if (p_header->ic.instance == *p_inst) - { - item_match = (p_type == NULL) ? true : item_match && true; - } - else - { - item_match = false; - } - } + continue; + } - if (item_match) - { - // We found the record! Update the descriptor. - p_desc->vpage_id = m_pages[page].vpage_id; - p_desc->record_id = p_header->id; + if ((p_record_key != NULL) && + (p_header->tl.record_key != *p_record_key)) + { + continue; + } - p_desc->p_rec = p_token->p_addr; - p_desc->ptr_magic = FDS_MAGIC_HWORD; - p_desc->gc_magic = m_gc_runs; + // Record found; update the descriptor. + p_desc->record_id = p_header->record_id; + p_desc->p_record = p_token->p_addr; + p_desc->gc_run_count = m_gc.run_count; - return NRF_SUCCESS; - } - } - // Jump to the next record. - p_token->p_addr += (FDS_HEADER_SIZE + (p_header->tl.length_words)); + return FDS_SUCCESS; } - /** We have seeked an entire page. Set the address in the token to NULL - * so that it will be set again on the next iteration. */ + // We have scanned an entire page. Set the address in the token to NULL + // so that it will be updated in the next iteration. p_token->p_addr = NULL; } - /** If we couldn't find the record, zero the token structure - * so that it can be reused. */ - p_token->magic = 0x00; - - return NRF_ERROR_NOT_FOUND; -} - - -static void gc_init() -{ - // Set which pages to GC. - for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) - { - m_gc.do_gc_page[i] = (m_pages[i].page_type == FDS_PAGE_VALID); - } + return FDS_ERR_NOT_FOUND; } -static void gc_reset() +// Retrieve basic statistics about dirty records on a page. +static void dirty_records_stat(uint16_t page, + uint16_t * const p_dirty_records, + uint16_t * const p_word_count) { - m_gc.state = BEGIN; - m_gc.cur_page = 0; - m_gc.p_scan_addr = NULL; -} - + fds_header_t const * p_header; + uint32_t const * p_rec; -static void gc_set_state(fds_gc_state_t new_state) -{ - m_gc.state = new_state; -} + p_rec = m_pages[page].p_addr + FDS_PAGE_TAG_SIZE; + while ((p_rec < (m_pages[page].p_addr + FDS_PAGE_SIZE)) && + (*p_rec != FDS_ERASED_WORD)) + { + p_header = (fds_header_t*)p_rec; -static ret_code_t gc_get_next_page(uint16_t * const next_page) -{ - for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) - { - if (m_gc.do_gc_page[i]) + if (!header_is_valid(p_header)) { - uint16_t records_open; - - CRITICAL_SECTION_ENTER(); - records_open = m_pages[i].records_open; - CRITICAL_SECTION_EXIT(); - - // Do not attempt to GC this page anymore. - m_gc.do_gc_page[i] = false; - - // Only GC pages with no open records. - if (records_open == 0) - { - *next_page = i; - return NRF_SUCCESS; - } + (*p_dirty_records) += 1; + (*p_word_count) += FDS_HEADER_SIZE + p_header->tl.length_words; } - } - return NRF_ERROR_NOT_FOUND; + p_rec += (FDS_HEADER_SIZE + (p_header->tl.length_words)); + } } -static ret_code_t gc_page() +// Advances one position in the queue. +// Returns true if the queue is not empty. +static bool queue_advance(void) { - ret_code_t ret; - - ret = gc_get_next_page(&m_gc.cur_page); - - // No pages left to GC. GC has terminated. Reset GC data. - if (ret != NRF_SUCCESS) - { - gc_reset(); - - return COMMAND_COMPLETED; - } - - // Prepare to GC the page. - gc_set_state(GC_PAGE); - - // Flag the page as being garbage collected. - ret = page_tag_write_gc(m_gc.cur_page); + // Reset the current element. + memset(&m_op_queue.op[m_op_queue.rp], 0x00, sizeof(fds_op_t)); - if (ret != NRF_SUCCESS) + if (m_op_queue.count != 0) { - return ret; + // Advance in the queue, wrapping around if necessary. + m_op_queue.rp = (m_op_queue.rp + 1) % FDS_OP_QUEUE_SIZE; + m_op_queue.count--; } - return COMMAND_EXECUTING; + return (m_op_queue.count != 0); } -static ret_code_t gc_copy_record() +// Given a pointer to an element in the chunk queue, computes the pointer to +// the next element in the queue. Handles wrap around. +void chunk_queue_next(fds_record_chunk_t ** pp_chunk) { - ret_code_t fs_ret; - - // We have found a record to copy. - fds_record_t const * const p_record = (fds_record_t*)m_gc.p_scan_addr; - - gc_set_state(COPY_RECORD); - - // Copy the item to swap. - fs_ret = fs_store(&fs_config, - m_pages[m_gc.swap_page].start_addr + m_pages[m_gc.swap_page].write_offset, - (uint32_t*)p_record, - FDS_HEADER_SIZE + p_record->header.tl.length_words); - - if (fs_ret != NRF_SUCCESS) + if ((*pp_chunk) != &m_chunk_queue.chunk[FDS_CHUNK_QUEUE_SIZE - 1]) { - // Oops :( - // This is an error. Can we recover? + (*pp_chunk)++; + return; } - // Remember to update the swap page write offset. - m_pages[m_gc.swap_page].write_offset += (FDS_HEADER_SIZE + p_record->header.tl.length_words); - - return COMMAND_EXECUTING; + *pp_chunk = &m_chunk_queue.chunk[0]; } -static ret_code_t gc_ready_swap_page() +// Retrieve the current chunk, and advance the queue. +static void chunk_queue_get_and_advance(fds_record_chunk_t ** pp_chunk) { - ret_code_t fs_ret; - - /** A page has been scanned through. All valid records found were copied to swap. - * The swap page can now be flagged as a valid page. */ - gc_set_state(READY_SWAP); - - fs_ret = page_tag_write_valid(m_gc.swap_page); - if (fs_ret != NRF_SUCCESS) + if (m_chunk_queue.count != 0) { - return fs_ret; - } + // Point to the current chunk and advance the queue. + *pp_chunk = &m_chunk_queue.chunk[m_chunk_queue.rp]; - /** Do not update the page type in the internal page structure (m_pages) - * right away. (why?) */ - return COMMAND_EXECUTING; + m_chunk_queue.rp = (m_chunk_queue.rp + 1) % FDS_CHUNK_QUEUE_SIZE; + m_chunk_queue.count--; + } } -static ret_code_t gc_seek_record() +static void chunk_queue_skip(fds_op_t const * const p_op) { - // Let's find a valid record which has not been copied yet. - if (scan_next_valid(m_gc.cur_page, &m_gc.p_scan_addr) == NRF_SUCCESS) - { - /** The record is guaranteed to fit in the destination page, - * so we don't need to check its size. */ - return gc_copy_record(); - } - else + if ((p_op->op_code == FDS_OP_WRITE) || + (p_op->op_code == FDS_OP_UPDATE)) { - /** No more (uncopied) records left on this page. - * The swap page can now be marked as a valid page. */ - return gc_ready_swap_page(); + m_chunk_queue.rp += p_op->write.chunk_count; + m_chunk_queue.count -= p_op->write.chunk_count; } } -static ret_code_t gc_new_swap_page() +// Enqueue an operation. +static bool op_enqueue(fds_op_t const * const p_op, + uint32_t num_chunks, + fds_record_chunk_t const * const p_chunk) { - ret_code_t fs_ret; - uint16_t vpage_id; + uint32_t idx; + bool ret = false; - gc_set_state(NEW_SWAP); + CRITICAL_SECTION_ENTER(); + if ((m_op_queue.count <= FDS_OP_QUEUE_SIZE - 1) && + (m_chunk_queue.count <= FDS_CHUNK_QUEUE_SIZE - num_chunks)) + { + idx = (m_op_queue.count + m_op_queue.rp) % FDS_OP_QUEUE_SIZE; - // Save the swap page virtual page ID. - vpage_id = m_pages[m_gc.swap_page].vpage_id; + m_op_queue.op[idx] = *p_op; + m_op_queue.count++; - /** The swap page has been marked as valid in Flash. We copy the GC'ed page - * write_offset and virtual page ID. */ - m_pages[m_gc.swap_page].page_type = FDS_PAGE_VALID; - m_pages[m_gc.swap_page].vpage_id = m_pages[m_gc.cur_page].vpage_id; - m_pages[m_gc.swap_page].words_reserved = m_pages[m_gc.cur_page].words_reserved; + if (num_chunks != 0) + { + idx = (m_chunk_queue.count + m_chunk_queue.rp) % FDS_CHUNK_QUEUE_SIZE; - // The new swap page is now the page we just GC. - m_gc.swap_page = m_gc.cur_page; + fds_record_chunk_t * p_chunk_dst; + p_chunk_dst = &m_chunk_queue.chunk[idx]; - // Update the write_offset, words_reserved and vpage_id fields for the new swap page. - m_pages[m_gc.swap_page].page_type = FDS_PAGE_SWAP; - m_pages[m_gc.swap_page].vpage_id = vpage_id; - m_pages[m_gc.swap_page].write_offset = FDS_PAGE_TAG_SIZE; - m_pages[m_gc.swap_page].words_reserved = 0; + for (uint32_t i = 0; i < num_chunks; i++) + { + *p_chunk_dst = p_chunk[i]; + chunk_queue_next(&p_chunk_dst); + } - /** Finally, erase the new swap page. Remember we still have to flag this - * new page as swap, but we'll wait the callback for this operation to do so. */ - fs_ret = fs_erase(&fs_config, - (uint32_t*)m_pages[m_gc.swap_page].start_addr, - FS_PAGE_SIZE_WORDS); + m_chunk_queue.count += num_chunks; + } - if (fs_ret != NRF_SUCCESS) - { - return fs_ret; + ret = true; } + CRITICAL_SECTION_EXIT(); - return COMMAND_EXECUTING; + return ret; } -static ret_code_t gc_new_swap_page_init() +// This function is called during initialization to setup the page structure (m_pages) and +// provide additional information regarding eventual further initialization steps. +static fds_init_opts_t pages_init() { - ret_code_t fs_ret; - - gc_set_state(INIT_SWAP); + uint32_t ret = NO_PAGES; + // The index of the page being initialized in m_pages[]. + uint16_t page = 0; + bool swap_set_but_not_found = false; - fs_ret = page_tag_write_swap(m_gc.swap_page); - if (fs_ret != NRF_SUCCESS) + for (uint16_t i = 0; i < FDS_VIRTUAL_PAGES; i++) { - return fs_ret; - } + uint32_t const * const p_page_addr = fs_config.p_start_addr + (i * FDS_PAGE_SIZE); + fds_page_type_t const page_type = page_identify(p_page_addr); - return COMMAND_EXECUTING; -} + switch (page_type) + { + case FDS_PAGE_UNDEFINED: + if (page_is_erased(p_page_addr)) + { + if (m_swap_page.p_addr != NULL) + { + // If a swap page is already set, flag the page as erased (in m_pages) + // and try to tag it as data (in flash) later on during initialization. + m_pages[page].page_type = FDS_PAGE_ERASED; + m_pages[page].p_addr = p_page_addr; + m_pages[page].write_offset = FDS_PAGE_TAG_SIZE; + + // This is a candidate for a potential new swap page, in case the + // current swap is going to be promoted to complete a GC instance. + m_gc.cur_page = page; + page++; + } + else + { + // If there is no swap page yet, use this one. + m_swap_page.p_addr = p_page_addr; + m_swap_page.write_offset = FDS_PAGE_TAG_SIZE; + swap_set_but_not_found = true; + } + ret |= PAGE_ERASED; + } + else + { + // Do not initialize or use this page. + m_pages[page++].page_type = FDS_PAGE_UNDEFINED; + } + break; -static ret_code_t gc_execute(uint32_t result) -{ - // TODO: Handle resuming GC. - - ret_code_t ret; + case FDS_PAGE_DATA: + m_pages[page].page_type = FDS_PAGE_DATA; + m_pages[page].p_addr = p_page_addr; + // Scan the page to compute its write offset and determine whether or not the page + // can be garbage collected. Additionally, update the latest kwown record ID. + page_scan(p_page_addr, &m_pages[page].write_offset, &m_pages[page].can_gc); - if (result != NRF_SUCCESS) - { - // An operation failed. Report to the application. - return result; - } + ret |= PAGE_DATA; + page++; - switch (m_gc.state) - { - case BEGIN: - { - // Increment the number of times the GC has been run. - m_gc_runs++; - // Sets up a list of pages to GC. - gc_init(); - // Go ! - ret = gc_page(); - } break; - - case GC_PAGE: - /** A page has been successfully flagged as being GC. - * Look for valid records to copy. */ - ret = gc_seek_record(); - break; + break; - case COPY_RECORD: - /** A record has been copied to swap. - * Look for more records to copy. */ - ret = gc_seek_record(); - break; + case FDS_PAGE_SWAP: + if (swap_set_but_not_found) + { + m_pages[page].page_type = FDS_PAGE_ERASED; + m_pages[page].p_addr = m_swap_page.p_addr; + m_pages[page].write_offset = FDS_PAGE_TAG_SIZE; - case READY_SWAP: - /** The swap page has been flagged as 'valid' (ready). - * Let's prepare a new swap page. */ - ret = gc_new_swap_page(); - break; + page++; + } - case NEW_SWAP: - // A new swap page has been prepared. Let's flag it as swap. - ret = gc_new_swap_page_init(); - break; + m_swap_page.p_addr = p_page_addr; + // If the swap is promoted, this offset should be kept, otherwise, + // it should be set to FDS_PAGE_TAG_SIZE. + page_scan(p_page_addr, &m_swap_page.write_offset, NULL); - case INIT_SWAP: - /** The swap was flagged as swap in flash. Let's compress another page. - * Be sure to update the address where to scan from. */ - m_gc.p_scan_addr = NULL; - ret = gc_page(); - break; + ret |= (m_swap_page.write_offset == FDS_PAGE_TAG_SIZE) ? + PAGE_SWAP_CLEAN : PAGE_SWAP_DIRTY; + break; - default: - // Should really not happen. - ret = NRF_ERROR_INTERNAL; - break; + default: + // Shouldn't happen. + break; + } } - return ret; + return (fds_init_opts_t)ret; } -/**@brief Function for initializing the command queue. */ -static void queues_init(void) +// Write the first part of a record header (the key and length). +static ret_code_t record_header_write_begin(fds_op_t * const p_op, uint32_t * const p_addr) { - memset(&m_cmd_queue, 0, sizeof(fds_cmd_queue_t)); - memset(&m_chunk_queue, 0, sizeof(fds_chunk_queue_t)); + ret_code_t ret; + ret = fs_store(&fs_config, p_addr + FDS_OFFSET_TL, + (uint32_t*)&p_op->write.header.tl, FDS_HEADER_SIZE_TL, NULL); + + // Write the record ID next. + p_op->write.step = FDS_OP_WRITE_RECORD_ID; + + return (ret == FS_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY; } -void cmd_queue_next(fds_cmd_t ** pp_cmd) +static ret_code_t record_header_write_id(fds_op_t * const p_op, uint32_t * const p_addr) { - if (*pp_cmd != &m_cmd_queue.cmd[FDS_CMD_QUEUE_SIZE - 1]) - { - (*pp_cmd)++; - return; - } + ret_code_t ret; + ret = fs_store(&fs_config, p_addr + FDS_OFFSET_ID, + (uint32_t*)&p_op->write.header.record_id, FDS_HEADER_SIZE_ID, NULL); + + // If this record has zero chunk, write the last part of the header directly. + // Otherwise, write the record chunks next. + p_op->write.step = (p_op->write.chunk_count != 0) ? FDS_OP_WRITE_CHUNKS : + FDS_OP_WRITE_HEADER_FINALIZE; - *pp_cmd = &m_cmd_queue.cmd[0]; + return (ret == FS_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY; } -void chunk_queue_next(fds_record_chunk_t ** pp_chunk) +static ret_code_t record_header_write_finalize(fds_op_t * const p_op, uint32_t * const p_addr) { - if ((*pp_chunk) != &m_chunk_queue.chunk[FDS_CHUNK_QUEUE_SIZE - 1]) - { - (*pp_chunk)++; - return; - } + ret_code_t ret; + ret = fs_store(&fs_config, p_addr + FDS_OFFSET_IC, + (uint32_t*)&p_op->write.header.ic, FDS_HEADER_SIZE_IC, NULL); - *pp_chunk = &m_chunk_queue.chunk[0]; + // If this is a simple write operation, then this is the last step. + // If this is an update instead, delete the old record next. + p_op->write.step = (p_op->op_code == FDS_OP_UPDATE) ? FDS_OP_WRITE_FLAG_DIRTY : + FDS_OP_WRITE_DONE; + + return (ret == FS_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY; } -/**@brief Advances one position in the command queue. Returns true if the queue is not empty. */ -static bool cmd_queue_advance(void) +static ret_code_t record_header_flag_dirty(uint32_t * const p_record, uint16_t page_to_gc) { - // Reset the current element. - memset(&m_cmd_queue.cmd[m_cmd_queue.rp], 0, sizeof(fds_cmd_t)); + // Flag the record as dirty. + fs_ret_t ret = fs_store(&fs_config, p_record, + (uint32_t*)&m_fds_tl_dirty, FDS_HEADER_SIZE_TL, NULL); - CRITICAL_SECTION_ENTER(); - if (m_cmd_queue.count != 0) + if (ret != FS_SUCCESS) { - // Advance in the queue, wrapping around if necessary. - m_cmd_queue.rp = (m_cmd_queue.rp + 1) % FDS_CMD_QUEUE_SIZE; - m_cmd_queue.count--; + return FDS_ERR_BUSY; } - CRITICAL_SECTION_EXIT(); - return m_cmd_queue.count != 0; + m_pages[page_to_gc].can_gc = true; + + return FDS_SUCCESS; } -/**@brief Returns the current chunk, and advances to the next in the queue. */ -static bool chunk_queue_get_and_advance(fds_record_chunk_t ** pp_chunk) +static ret_code_t record_find_and_delete(fds_op_t * const p_op) { - bool chunk_popped = false; + ret_code_t ret; + uint16_t page; + fds_record_desc_t desc = {0}; - CRITICAL_SECTION_ENTER(); - if (m_chunk_queue.count != 0) + desc.record_id = p_op->del.record_to_delete; + + if (record_find_by_desc(&desc, &page)) { - // Point to the current chunk and advance the queue. - *pp_chunk = &m_chunk_queue.chunk[m_chunk_queue.rp]; + fds_header_t const * const p_header = (fds_header_t const *)desc.p_record; - m_chunk_queue.rp = (m_chunk_queue.rp + 1) % FDS_CHUNK_QUEUE_SIZE; - m_chunk_queue.count--; + // Copy the record key and file ID, so that they can be returned in the event. + // In case this function is run as part of an update, there is no need to copy + // the file ID and record key since they are present in the header stored + // in the queue element. + + p_op->del.file_id = p_header->ic.file_id; + p_op->del.record_key = p_header->tl.record_key; - chunk_popped = true; + // Flag the record as dirty. + ret = record_header_flag_dirty((uint32_t*)desc.p_record, page); + } + else + { + // The record never existed, or it has already been deleted. + ret = FDS_ERR_NOT_FOUND; } - CRITICAL_SECTION_EXIT(); - return chunk_popped; + return ret; } -static bool chunk_queue_skip(uint8_t num_op) +// Finds a record within a file and flags it as dirty. +static ret_code_t file_find_and_delete(fds_op_t * const p_op) { - bool chunk_skipped = false; + ret_code_t ret; + fds_record_desc_t desc; - CRITICAL_SECTION_ENTER(); - if (num_op <= m_chunk_queue.count) + // This token must persist across calls. + static fds_find_token_t tok = {0}; + + // Pass NULL to ignore the record key. + ret = record_find(&p_op->del.file_id, NULL, &desc, &tok); + + if (ret == FDS_SUCCESS) { - m_chunk_queue.count -= num_op; - chunk_skipped = true; + // A record was found: flag it as dirty. + ret = record_header_flag_dirty((uint32_t*)desc.p_record, tok.page); + } + else // FDS_ERR_NOT_FOUND + { + // No more records were found. Zero the token, so that it can be reused. + memset(&tok, 0x00, sizeof(fds_find_token_t)); } - CRITICAL_SECTION_EXIT(); - return chunk_skipped; + return ret; } -/**@brief Reserves resources on both queues. */ -static ret_code_t queue_reserve(uint8_t num_cmd, - uint8_t num_chunks, - fds_cmd_t ** pp_cmd, - fds_record_chunk_t ** pp_chunk) +// Writes a record chunk to flash and advances the chunk queue. Additionally, decrements +// the number of chunks left to write for this operation and accumulates the offset. +static ret_code_t record_write_chunk(fds_op_t * const p_op, uint32_t * const p_addr) { - uint8_t cmd_index; - uint8_t chunk_index; + ret_code_t ret; + fds_record_chunk_t * p_chunk = NULL; - // This is really just being safe. - if (pp_cmd == NULL || ((pp_chunk == NULL) && (num_chunks != 0))) - { - return NRF_ERROR_NULL; - } + // Retrieve the next chunk to be written. + chunk_queue_get_and_advance(&p_chunk); - if (num_cmd == 0) - { - return NRF_ERROR_INVALID_DATA; - } + ret = fs_store(&fs_config, p_addr + p_op->write.chunk_offset, + p_chunk->p_data, p_chunk->length_words, NULL); - CRITICAL_SECTION_ENTER(); + // Accumulate the offset. + p_op->write.chunk_offset += p_chunk->length_words; - // Ensure there is enough space in the queues. - if ((m_cmd_queue.count > FDS_CMD_QUEUE_SIZE - num_cmd) || - (m_chunk_queue.count > FDS_CHUNK_QUEUE_SIZE - num_chunks)) + // Decrement the number of chunks left to write. + // NOTE: If chunk_count is initially zero, this function is not called + // because this step is skipped entirely. See record_header_write_id(). + p_op->write.chunk_count--; + + if (p_op->write.chunk_count == 0) { - CRITICAL_SECTION_EXIT(); - return NRF_ERROR_BUSY; + // All record chunks have been written; write the last part of + // the record header to finalize the write operation. + p_op->write.step = FDS_OP_WRITE_HEADER_FINALIZE; } - // Find the write position in the commands queue. - cmd_index = m_cmd_queue.count; - cmd_index += m_cmd_queue.rp; - cmd_index = cmd_index % FDS_CMD_QUEUE_SIZE; + return (ret == NRF_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY; +} - *pp_cmd = &m_cmd_queue.cmd[cmd_index]; - m_cmd_queue.count += num_cmd; - /* If no operations are associated with the command, such as is the case - * for initialization and compression, pp_chunk can be NULL. */ - if (num_chunks != 0) - { - chunk_index = m_chunk_queue.count; - chunk_index += m_chunk_queue.rp; - chunk_index = chunk_index % FDS_CHUNK_QUEUE_SIZE; +#if defined(FDS_CRC_ENABLED) - *pp_chunk = &m_chunk_queue.chunk[chunk_index]; - m_chunk_queue.count += num_chunks; - } +static bool crc_verify_success(uint16_t crc, uint16_t len_words, uint32_t const * const p_data) +{ + uint16_t computed_crc; - CRITICAL_SECTION_EXIT(); + // The CRC is computed on the entire record, except the CRC field itself. + // The record header is 12 bytes, out of these we have to skip bytes 6 to 8 where the + // CRC itself is stored. Then we compute the CRC for the rest of the record, from byte 8 of + // the header (where the record ID begins) to the end of the record data. + computed_crc = crc16_compute((uint8_t const *)p_data, 6, NULL); + computed_crc = crc16_compute((uint8_t const *)p_data + 8, + (FDS_HEADER_SIZE_ID + len_words) * sizeof(uint32_t), + &computed_crc); - return NRF_SUCCESS; + return (computed_crc == crc); } +#endif + -/**@brief Cancel the reservation on resources on queues. */ -static void queue_reserve_cancel(uint8_t num_cmd, uint8_t num_chunks) +static void gc_init(void) { - CRITICAL_SECTION_ENTER(); - m_cmd_queue.count -= num_cmd; - m_chunk_queue.count -= num_chunks; - CRITICAL_SECTION_EXIT(); + m_gc.run_count++; + m_gc.cur_page = 0; + m_gc.resume = false; + + // Setup which pages to GC. Defer checking for open records and the can_gc flag, + // as other operations might change those while GC is running. + for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) + { + m_gc.do_gc_page[i] = (m_pages[i].page_type == FDS_PAGE_DATA); + } } -static void pages_init(uint16_t * const p_pages_avail, - bool * const p_write_page_tag, - bool * const p_resume_comp) +// Obtain the next page to be garbage collected. +// Returns true if there are pages left to garbage collect, returns false otherwise. +static bool gc_page_next(uint16_t * const p_next_page) { - *p_pages_avail = 0; - *p_write_page_tag = false; - *p_resume_comp = false; + bool ret = false; - /** Scan pages and setup page data. - * This function does NOT perform write operations in flash. */ for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) { - // Initialize page data. Note that start_addr must be set BEFORE invoking page_identify(). - m_pages[i].start_addr = fs_config.p_start_addr + (i * FS_PAGE_SIZE_WORDS); - m_pages[i].write_offset = FDS_PAGE_TAG_SIZE; - m_pages[i].vpage_id = i; - m_pages[i].records_open = 0; - m_pages[i].words_reserved = 0; - - m_pages[i].page_type = page_identify(i); - - switch (m_pages[i].page_type) + if (m_gc.do_gc_page[i]) { - case FDS_PAGE_UNDEFINED: - { - if (page_is_empty(i)) - { - /* We have found an erased page, which can be initialized. - * This will require a write in flash. */ - m_pages[i].page_type = FDS_PAGE_ERASED; - *p_write_page_tag = true; - } - } break; - - case FDS_PAGE_VALID: - { - /** If a page is valid, we update its write offset. - * Additionally, page_scan will update the last known record ID. */ - page_scan(i, &m_pages[i].write_offset); - (*p_pages_avail)++; - } break; - - case FDS_PAGE_SWAP: - { - m_gc.swap_page = i; - m_swap_page_avail = true; - } break; + // Do not attempt to GC this page again. + m_gc.do_gc_page[i] = false; - case FDS_PAGE_GC: + // Only GC pages with no open records and with some records which have been deleted. + if ((m_pages[i].records_open == 0) && (m_pages[i].can_gc == true)) { - /** There is an ongoing garbage collection. - * We should resume the operation, which we don't yet. */ - m_gc.cur_page = i; - m_gc.state = GC_PAGE; - *p_resume_comp = true; - } break; - - default: + *p_next_page = i; + ret = true; break; + } } } + + return ret; +} + + +static ret_code_t gc_swap_erase(void) +{ + m_gc.state = GC_DISCARD_SWAP; + m_swap_page.write_offset = FDS_PAGE_TAG_SIZE; + + return fs_erase(&fs_config, m_swap_page.p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL); } -// NOTE: Adds FDS_HEADER_SIZE automatically. -static ret_code_t write_space_reserve(uint16_t length_words, uint16_t * vpage_id) +// Erase the page being garbage collected, or erase the swap in case there are any open +// records on the page being garbage collected. +static ret_code_t gc_page_erase(void) { - bool space_reserved = false; - uint16_t total_len_words = length_words + FDS_HEADER_SIZE; + uint32_t ret; + uint16_t const gc = m_gc.cur_page; - if (total_len_words >= FS_PAGE_SIZE_WORDS - FDS_PAGE_TAG_SIZE) + if (m_pages[gc].records_open == 0) { - return NRF_ERROR_INVALID_LENGTH; + ret = fs_erase(&fs_config, m_pages[gc].p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL); + m_gc.state = GC_ERASE_PAGE; } - - for (uint16_t page = 0; page < FDS_MAX_PAGES; page++) + else { - if ((m_pages[page].page_type == FDS_PAGE_VALID) && - (page_has_space(page, total_len_words))) - { - space_reserved = true; - *vpage_id = m_pages[page].vpage_id; - - CRITICAL_SECTION_ENTER(); - m_pages[page].words_reserved += total_len_words; - CRITICAL_SECTION_EXIT(); - - break; - } + // If there are open records, stop garbage collection on this page. + // Discard the swap and try to garbage collect another page. + ret = gc_swap_erase(); } - return space_reserved ? NRF_SUCCESS : NRF_ERROR_NO_MEM; + return ret; } -static bool chunk_is_aligned(fds_record_chunk_t const * const p_chunk, uint8_t num_parts) +// Copy the current record to swap. +static ret_code_t gc_record_copy(void) { - for (uint8_t i = 0; i < num_parts; i++) - { - if (!is_word_aligned(p_chunk[i].p_data)) - { - return false; - } - } + fds_header_t const * const p_header = (fds_header_t*)m_gc.p_record_src; + uint32_t const * const p_dest = m_swap_page.p_addr + m_swap_page.write_offset; + uint16_t const record_len = FDS_HEADER_SIZE + p_header->tl.length_words; - return true; + m_gc.state = GC_COPY_RECORD; + + // Copy the record to swap; it is guaranteed to fit in the destination page, + // so there is no need to check its size. This will either succeed or timeout. + return fs_store(&fs_config, p_dest, m_gc.p_record_src, record_len, NULL); } -static ret_code_t init_execute(uint32_t result, uint32_t const * p_page_addr) +static ret_code_t gc_record_find_next(void) { - uint16_t cur_page; - bool page_tag_written = false; + ret_code_t ret; - if (result != NRF_SUCCESS) + // Find the next valid record to copy. + if (record_find_next(m_gc.cur_page, &m_gc.p_record_src)) { - // Oops. Error. - return result; + ret = gc_record_copy(); } - - // Here we just distinguish between the first invocation and the others. - cur_page = p_page_addr == NULL ? 0 : page_by_addr(p_page_addr) + 1; - - if (cur_page == FDS_MAX_PAGES) + else { - // We have finished. We'd need to set some flags. - flag_set(FDS_FLAG_INITIALIZED); - flag_clear(FDS_FLAG_INITIALIZING); - - return COMMAND_COMPLETED; + // No more records left to copy on this page; swap pages. + ret = gc_page_erase(); } - while (cur_page < FDS_MAX_PAGES && !page_tag_written) - { - if (m_pages[cur_page].page_type == FDS_PAGE_ERASED) - { - page_tag_written = true; + return ret; +} - if (m_swap_page_avail) - { - if (page_tag_write_valid(cur_page) != NRF_SUCCESS) - { - // Oops. Error. - } - // Update the page type. - m_pages[cur_page].page_type = FDS_PAGE_VALID; - } - else - { - if (page_tag_write_swap(cur_page) != NRF_SUCCESS) - { - // Oops. Error. - } - // Update the page type. - m_pages[cur_page].page_type = FDS_PAGE_SWAP; - /** Update compression data. We set this information in init_pages - * if it is available, otherwise, we should set it here. */ - m_swap_page_avail = true; - m_gc.swap_page = cur_page; - } - } +// Promote the swap by tagging it as a data page. +static ret_code_t gc_swap_promote(void) +{ + m_gc.state = GC_PROMOTE_SWAP; + return page_tag_write_data(m_pages[m_gc.cur_page].p_addr); +} - cur_page++; - } - if (!page_tag_written) +// Tag the page just garbage collected as swap. +static ret_code_t gc_tag_new_swap(void) +{ + m_gc.state = GC_TAG_NEW_SWAP; + m_gc.p_record_src = NULL; + return page_tag_write_swap(); +} + + +static ret_code_t gc_next_page(void) +{ + if (!gc_page_next(&m_gc.cur_page)) { - if (m_swap_page_avail) - { - return COMMAND_COMPLETED; - } - else - { - // There is no empty space to use as swap. - // Notify user that no compression is available? - } + // No pages left to GC; GC has terminated. Reset the state. + m_gc.state = GC_BEGIN; + m_gc.cur_page = 0; + m_gc.p_record_src = NULL; + + return FDS_OP_COMPLETED; } - return COMMAND_EXECUTING; + return gc_record_find_next(); } -/**@brief Function to execute write and update commands. - * - */ -static ret_code_t store_execute(uint32_t result, fds_cmd_t * const p_cmd) +// Update the swap page offeset after a record has been successfully copied to it. +static void gc_update_swap_offset(void) { - ret_code_t fs_ret; - fds_record_chunk_t * p_chunk = NULL; - fds_page_t * p_page = NULL; - uint32_t * p_write_addr; + fds_header_t const * const p_header = (fds_header_t*)m_gc.p_record_src; + uint16_t const record_len = FDS_HEADER_SIZE + p_header->tl.length_words; - // Using virtual page IDs allows other operations to be queued even if GC has been requested. - page_from_virtual_id(p_cmd->vpage_id, &p_page); + m_swap_page.write_offset += record_len; +} - if (result != NRF_SUCCESS) - { - // The previous operation has failed, update the page data. - p_page->write_offset += (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA)); - p_page->words_reserved -= (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA)); - return result; - } +static void gc_swap_pages(void) +{ + // The page being garbage collected will be the new swap page, + // and the current swap will be used as a data page (promoted). + uint32_t const * const p_addr = m_swap_page.p_addr; - // Compute the write address (just syntatic sugar). - p_write_addr = (uint32_t*)(p_page->start_addr + p_page->write_offset); + m_swap_page.p_addr = m_pages[m_gc.cur_page].p_addr; + m_pages[m_gc.cur_page].p_addr = p_addr; - // Execute the operation. - switch (p_cmd->op_code) + // Keep the offset for this page, but reset it for the swap. + m_pages[m_gc.cur_page].write_offset = m_swap_page.write_offset; + m_swap_page.write_offset = FDS_PAGE_TAG_SIZE; +} + + +static void gc_state_advance(void) +{ + switch (m_gc.state) { - case FDS_OP_WRITE_TL: - { - fs_ret = fs_store(&fs_config, - p_write_addr + FDS_WRITE_OFFSET_TL, - (uint32_t*)&p_cmd->record_header.tl, - FDS_HEADER_SIZE_TL /*Words*/); + case GC_BEGIN: + gc_init(); + m_gc.state = GC_NEXT_PAGE; + break; - // Set the next operation to be executed. - p_cmd->op_code = FDS_OP_WRITE_ID; + // A record was successfully copied. + case GC_COPY_RECORD: + gc_update_swap_offset(); + m_gc.state = GC_FIND_NEXT_RECORD; + break; - } break; + // A page was successfully erased. Prepare to promote the swap. + case GC_ERASE_PAGE: + gc_swap_pages(); + m_gc.state = GC_PROMOTE_SWAP; + break; - case FDS_OP_WRITE_ID: - { - fs_ret = fs_store(&fs_config, - p_write_addr + FDS_WRITE_OFFSET_ID, - (uint32_t*)&p_cmd->record_header.id, - FDS_HEADER_SIZE_ID /*Words*/); + // Swap was discarded because the page being GC'ed had open records. + case GC_DISCARD_SWAP: + // Swap was sucessfully promoted. + case GC_PROMOTE_SWAP: + // Prepare to tag the page just GC'ed as swap. + m_gc.state = GC_TAG_NEW_SWAP; + break; - p_cmd->op_code = FDS_OP_WRITE_CHUNK; + case GC_TAG_NEW_SWAP: + m_gc.state = GC_NEXT_PAGE; + break; - } break; + default: + // Should not happen. + break; + } +} - case FDS_OP_WRITE_CHUNK: - { - // Decrement the number of chunks left to write. - p_cmd->num_chunks--; - // Retrieve the chunk to be written. - chunk_queue_get_and_advance(&p_chunk); +// Initialize the filesystem. +static ret_code_t init_execute(uint32_t prev_ret, fds_op_t * const p_op) +{ + ret_code_t ret = FDS_ERR_INTERNAL; - fs_ret = fs_store(&fs_config, - p_write_addr + p_cmd->chunk_offset, - p_chunk->p_data, - p_chunk->length_words); + if (prev_ret != FS_SUCCESS) + { + // A previous operation has timed out. + flag_clear(FDS_FLAG_INITIALIZING); + return FDS_ERR_OPERATION_TIMEOUT; + } - // Accumulate the offset. - p_cmd->chunk_offset += p_chunk->length_words; + switch (p_op->init.step) + { + case FDS_OP_INIT_TAG_SWAP: + // The page write offset was determined previously by pages_init(). + ret = page_tag_write_swap(); + p_op->init.step = FDS_OP_INIT_TAG_DATA; + break; - if (p_cmd->num_chunks == 0) + case FDS_OP_INIT_TAG_DATA: + { + // Tag remaining erased pages as data. + bool write_reqd = false; + for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) + { + if (m_pages[i].page_type == FDS_PAGE_ERASED) + { + ret = page_tag_write_data(m_pages[i].p_addr); + m_pages[i].page_type = FDS_PAGE_DATA; + write_reqd = true; + break; + } + } + if (!write_reqd) { - /** We have written all the record chunks; we'll write - * IC last as a mean to 'validate' the record. */ - p_cmd->op_code = FDS_OP_WRITE_IC; + flag_set(FDS_FLAG_INITIALIZED); + flag_clear(FDS_FLAG_INITIALIZING); + return FDS_OP_COMPLETED; } + } + break; - } break; + case FDS_OP_INIT_ERASE_SWAP: + ret = fs_erase(&fs_config, m_swap_page.p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL); + // If the swap is going to be discarded then reset its write_offset. + m_swap_page.write_offset = FDS_PAGE_TAG_SIZE; + p_op->init.step = FDS_OP_INIT_TAG_SWAP; + break; - case FDS_OP_WRITE_IC: + case FDS_OP_INIT_PROMOTE_SWAP: { - fs_ret = fs_store(&fs_config, - p_write_addr + FDS_WRITE_OFFSET_IC, - (uint32_t*)&p_cmd->record_header.ic, - FDS_HEADER_SIZE_IC /*Words*/); + // When promoting the swap, keep the write_offset set by pages_init(). + ret = page_tag_write_data(m_swap_page.p_addr); - // This is the final operation. - p_cmd->op_code = FDS_OP_DONE; + uint16_t const gc = m_gc.cur_page; + uint32_t const * const p_old_swap = m_swap_page.p_addr; - } break; - - case FDS_OP_DONE: - { - // We have successfully written down the IC. The command has completed successfully. - p_page->write_offset += (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA)); - p_page->words_reserved -= (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA)); + // Execute the swap. + m_swap_page.p_addr = m_pages[gc].p_addr; + m_pages[gc].p_addr = p_old_swap; - return COMMAND_COMPLETED; + // Copy the offset from the swap to the new page. + m_pages[gc].write_offset = m_swap_page.write_offset; + m_swap_page.write_offset = FDS_PAGE_TAG_SIZE; - }; + m_pages[gc].page_type = FDS_PAGE_DATA; + p_op->init.step = FDS_OP_INIT_TAG_SWAP; + } + break; default: - fs_ret = NRF_ERROR_INTERNAL; + // Should not happen. break; } - // If fs_store did not succeed, the command has failed. - if (fs_ret != NRF_SUCCESS) + if (ret != FDS_SUCCESS) { - /** We're not going to receive a callback from fstorage - * so we update the page data right away. */ - p_page->write_offset += (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA)); - p_page->words_reserved -= (FDS_HEADER_SIZE + (p_cmd->chunk_offset - FDS_WRITE_OFFSET_DATA)); - - // We should propagate the error from fstorage. - return fs_ret; + // fstorage queue was full. + flag_clear(FDS_FLAG_INITIALIZING); + return FDS_ERR_BUSY; } - // An operation has successfully been executed. Wait for the callback. - return COMMAND_EXECUTING; + return FDS_OP_EXECUTING; } -static ret_code_t clear_execute(ret_code_t result, fds_cmd_t * const p_cmd) +// Executes write and update operations. +static ret_code_t write_execute(uint32_t prev_ret, fds_op_t * const p_op) { - ret_code_t ret; - fds_record_desc_t desc; + ret_code_t ret; + uint32_t * p_write_addr; + fds_page_t * const p_page = &m_pages[p_op->write.page]; // This must persist across calls. - static fds_find_token_t tok; + static fds_record_desc_t desc = {0}; + // When a record is updated, this variable will hold the page where the old + // copy was stored. This will be used to set the can_gc flag when the header is + // invalidated (FDS_OP_WRITE_FLAG_DIRTY). + static uint16_t page; - if (result != NRF_SUCCESS) + if (prev_ret != FS_SUCCESS) { - // A previous operation has failed. Propagate the error. - return result; + // The previous operation has timed out, update offsets. + page_offsets_update(p_page, p_op->write.header.tl.length_words); + return FDS_ERR_OPERATION_TIMEOUT; } - switch (p_cmd->op_code) + // Compute the address where to write data. + p_write_addr = (uint32_t*)(p_page->p_addr + p_page->write_offset); + + // Execute the current step of the operation, and set one to be executed next. + switch (p_op->write.step) { - case FDS_OP_CLEAR_TL: + case FDS_OP_WRITE_FIND_RECORD: { - // We were provided a descriptor for the record. - desc.vpage_id = p_cmd->vpage_id; - desc.record_id = p_cmd->record_header.id; - - /** Unfortunately, we always seek the record in this case, - * because we don't buffer an entire record descriptor in the - * fds_cmd_t structure. Keep in mind though, that we will - * seek one page at most. */ - if (seek_record(&desc) != NRF_SUCCESS) + // The first step of updating a record constists of locating the copy to be deleted. + // If the old copy couldn't be found for any reason then the update should fail. + // This prevents duplicates when queuing multiple updates of the same record. + desc.p_record = NULL; + desc.record_id = p_op->write.record_to_delete; + + if (!record_find_by_desc(&desc, &page)) { - // The record never existed, or it is already cleared. - ret = NRF_ERROR_NOT_FOUND; + return FDS_ERR_NOT_FOUND; } - else + // Setting the step is redundant since we are falling through. + } + // Fallthrough to FDS_OP_WRITE_HEADER_BEGIN. + + case FDS_OP_WRITE_HEADER_BEGIN: + ret = record_header_write_begin(p_op, p_write_addr); + break; + + case FDS_OP_WRITE_RECORD_ID: + ret = record_header_write_id(p_op, p_write_addr); + break; + + case FDS_OP_WRITE_CHUNKS: + ret = record_write_chunk(p_op, p_write_addr); + break; + + case FDS_OP_WRITE_HEADER_FINALIZE: + ret = record_header_write_finalize(p_op, p_write_addr); + break; + + case FDS_OP_WRITE_FLAG_DIRTY: + ret = record_header_flag_dirty((uint32_t*)desc.p_record, page); + p_op->write.step = FDS_OP_WRITE_DONE; + break; + + case FDS_OP_WRITE_DONE: + ret = FDS_OP_COMPLETED; + +#if defined(FDS_CRC_ENABLED) + if (flag_is_set(FDS_FLAG_VERIFY_CRC)) { - // Copy the record key, so that it may be returned in the callback. - p_cmd->record_header.tl.type = ((fds_header_t*)desc.p_rec)->tl.type; - p_cmd->record_header.ic.instance = ((fds_header_t*)desc.p_rec)->ic.instance; - - ret = fs_store(&fs_config, - desc.p_rec, - (uint32_t*)&m_fds_tl_invalid, - FDS_HEADER_SIZE_TL); + if (!crc_verify_success(p_op->write.header.ic.crc16, + p_op->write.header.tl.length_words, + p_write_addr)) + { + ret = FDS_ERR_CRC_CHECK_FAILED; + } } +#endif + break; - p_cmd->op_code = FDS_OP_DONE; + default: + ret = FDS_ERR_INTERNAL; + break; + } - } break; + // An operation has either completed or failed. It may have failed because fstorage + // ran out of memory, or because the user tried to delete a record which did not exist. + if (ret != FDS_OP_EXECUTING) + { + // There won't be another callback for this operation, so update the page offset now. + page_offsets_update(p_page, p_op->write.header.tl.length_words); + } - case FDS_OP_CLEAR_INSTANCE: - { - if (find_record(NULL, &p_cmd->record_header.ic.instance, - &desc, &tok) != NRF_SUCCESS) - { - // No more records to be found. - p_cmd->op_code = FDS_OP_DONE; + return ret; +} - // Zero the token, so that we may reuse it. - memset(&tok, 0, sizeof(fds_find_token_t)); - /** We won't receive a callback, since no flash operation - * was initiated. The command has finished. */ - ret = COMMAND_COMPLETED; - } - else +static ret_code_t delete_execute(uint32_t prev_ret, fds_op_t * const p_op) +{ + ret_code_t ret; + + if (prev_ret != FS_SUCCESS) + { + return FDS_ERR_OPERATION_TIMEOUT; + } + + switch (p_op->del.step) + { + case FDS_OP_DEL_RECORD_FLAG_DIRTY: + ret = record_find_and_delete(p_op); + p_op->del.step = FDS_OP_DEL_DONE; + break; + + case FDS_OP_DEL_FILE_FLAG_DIRTY: + ret = file_find_and_delete(p_op); + if (ret == FDS_ERR_NOT_FOUND) { - ret = fs_store(&fs_config, - desc.p_rec, - (uint32_t*)&m_fds_tl_invalid, - FDS_HEADER_SIZE_TL); + // No more records could be found. + // There won't be another callback for this operation, so return now. + ret = FDS_OP_COMPLETED; } - } break; + break; - case FDS_OP_DONE: - { - /** The last operation completed successfully. - * The command has finished. Return. */ - ret = COMMAND_COMPLETED; - } break; + case FDS_OP_DEL_DONE: + ret = FDS_OP_COMPLETED; + break; default: - ret = NRF_ERROR_INVALID_DATA; + ret = FDS_ERR_INTERNAL; break; } - // Await for the operation result. return ret; } -static ret_code_t cmd_queue_process(void) +static ret_code_t gc_execute(uint32_t prev_ret) { - ret_code_t ret; - fds_cmd_t * const p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; + ret_code_t ret; + + if (prev_ret != FS_SUCCESS) + { + return FDS_ERR_OPERATION_TIMEOUT; + } + + if (m_gc.resume) + { + m_gc.resume = false; + } + else + { + gc_state_advance(); + } - switch (p_cmd->id) + switch (m_gc.state) { - case FDS_CMD_INIT: - ret = init_execute(NRF_SUCCESS, NULL); + case GC_NEXT_PAGE: + ret = gc_next_page(); break; - case FDS_CMD_WRITE: - case FDS_CMD_UPDATE: - ret = store_execute(NRF_SUCCESS, p_cmd); + case GC_FIND_NEXT_RECORD: + ret = gc_record_find_next(); break; - case FDS_CMD_CLEAR: - case FDS_CMD_CLEAR_INST: - ret = clear_execute(NRF_SUCCESS, p_cmd); + case GC_COPY_RECORD: + ret = gc_record_copy(); break; - case FDS_CMD_GC: - ret = gc_execute(NRF_SUCCESS); + case GC_ERASE_PAGE: + ret = gc_page_erase(); break; - default: - ret = NRF_ERROR_FORBIDDEN; + case GC_PROMOTE_SWAP: + ret = gc_swap_promote(); break; - } - - if ((ret == COMMAND_EXECUTING) || (ret == COMMAND_COMPLETED)) - { - return NRF_SUCCESS; - } - - // This is an error. - return ret; -} - - -static ret_code_t cmd_queue_process_start(void) -{ - bool start_processing = false; - if (!flag_is_set(FDS_FLAG_PROCESSING)) - { - flag_set(FDS_FLAG_PROCESSING); - start_processing = true; - } + case GC_TAG_NEW_SWAP: + ret = gc_tag_new_swap(); + break; - if (!start_processing) - { - // We are awaiting a callback, so there is no need to manually start queue processing. - return NRF_SUCCESS; + default: + // Should not happen. + ret = FDS_ERR_INTERNAL; + break; } - return cmd_queue_process(); + // Either FDS_OP_EXECUTING, FDS_OP_COMPLETED, FDS_ERR_BUSY or FDS_ERR_INTERNAL. + return ret; } -static void fs_callback(uint8_t op_code, - uint32_t result, - uint32_t const * p_data, - fs_length_t length) +static void queue_process(fs_ret_t result) { ret_code_t ret; - fds_cmd_t * p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - fds_record_key_t record_key; + fds_op_t * const p_op = &m_op_queue.op[m_op_queue.rp]; - switch (p_cmd->id) + switch (p_op->op_code) { - case FDS_CMD_INIT: - ret = init_execute(result, p_data); + case FDS_OP_INIT: + ret = init_execute(result, p_op); break; - case FDS_CMD_WRITE: - case FDS_CMD_UPDATE: - ret = store_execute(result, p_cmd); + case FDS_OP_WRITE: + case FDS_OP_UPDATE: + ret = write_execute(result, p_op); break; - case FDS_CMD_CLEAR: - case FDS_CMD_CLEAR_INST: - ret = clear_execute(result, p_cmd); + case FDS_OP_DEL_RECORD: + case FDS_OP_DEL_FILE: + ret = delete_execute(result, p_op); break; - case FDS_CMD_GC: + case FDS_OP_GC: ret = gc_execute(result); break; default: - // Should not happen. - ret = NRF_ERROR_INTERNAL; + ret = FDS_ERR_INTERNAL; break; } - if (ret == COMMAND_EXECUTING /*=NRF_SUCCESS*/) + if (ret != FDS_OP_EXECUTING) { - /** The current command is still being processed. - * The command queue does not need to advance. */ - return; - } + fds_evt_t evt; - // Initialize the fds_record_key_t structure needed for the callback. - record_key.type = p_cmd->record_header.tl.type; - record_key.instance = p_cmd->record_header.ic.instance; + if (ret == FDS_OP_COMPLETED) + { + evt.result = FDS_SUCCESS; + } + else + { + // Either FDS_ERR_BUSY, FDS_ERR_OPERATION_TIMEOUT, + // FDS_ERR_CRC_CHECK_FAILED or FDS_ERR_NOT_FOUND. + evt.result = ret; - // The command has either completed or an operation (and thus the command) has failed. - if (ret == COMMAND_COMPLETED) - { - // The command has completed successfully. Notify the application. - app_notify(NRF_SUCCESS, p_cmd->id, p_cmd->record_header.id, record_key); - } - else - { - /** An operation has failed. This is fatal for the execution of a command. - * Skip other operations associated with the current command. - * Notify the user of the failure. */ - chunk_queue_skip(p_cmd->num_chunks); - app_notify(ret /*=result*/, p_cmd->id, p_cmd->record_header.id, record_key); - } + // If this operation had any chunks in the queue, skip them. + chunk_queue_skip(p_op); + } - // Advance the command queue, and if there is still something in the queue, process it. - if (cmd_queue_advance()) - { - /** Only process the queue if there are no pending commands being queued, since they - * will begin to process the queue on their own. Be sure to clear - * the flag FDS_FLAG_PROCESSING though ! */ - if (atomic_counter_is_zero()) + event_prepare(p_op, &evt); + event_send(&evt); + + // Advance the queue, and if there are any queued operations, process them. + if (queue_advance()) { - cmd_queue_process(); + queue_process(FS_SUCCESS); } else { + // No more elements in the queue. Clear the FDS_FLAG_PROCESSING flag, + // so that new operation can start processing the queue. flag_clear(FDS_FLAG_PROCESSING); } } - else +} + + +static void queue_start(void) +{ + if (!flag_is_set(FDS_FLAG_PROCESSING)) { - /** No more elements in the queue. Clear the FDS_FLAG_PROCESSING flag, - * so that new commands can start the queue processing. */ - flag_clear(FDS_FLAG_PROCESSING); + flag_set(FDS_FLAG_PROCESSING); + queue_process(FS_SUCCESS); } } -ret_code_t fds_init() +static void fs_event_handler(fs_evt_t const * const p_evt, fs_ret_t result) { - ret_code_t fs_ret; - fds_cmd_t * p_cmd; - uint16_t pages_avail; - bool write_page_tag; - bool resume_compression; + queue_process(result); +} - fds_record_key_t const dummy_key = {.type = FDS_TYPE_ID_INVALID, - .instance = FDS_INSTANCE_ID_INVALID}; - if (flag_is_set(FDS_FLAG_INITIALIZED)) - { - // Notify immediately. - app_notify(NRF_SUCCESS, FDS_CMD_INIT, 0 /*unused*/, dummy_key /*unused*/); - return NRF_SUCCESS; - } +// Enqueues write and update operations. +static ret_code_t write_enqueue(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record, + fds_reserve_token_t const * const p_tok, + fds_op_code_t op_code) +{ + ret_code_t ret; + fds_op_t op; + uint16_t page; + uint16_t crc = 0; + uint16_t length_words = 0; - if (flag_is_set(FDS_FLAG_INITIALIZING)) + if (!flag_is_set(FDS_FLAG_INITIALIZED)) { - return NRF_ERROR_INVALID_STATE; + return FDS_ERR_NOT_INITIALIZED; } - fs_ret = fs_init(); - if (fs_ret != NRF_SUCCESS) + if (p_record == NULL) { - // fs_init() failed, propagate the error. - return fs_ret; + return FDS_ERR_NULL_ARG; } - queues_init(); - - /** Initialize the last known record to zero. - * Its value will be updated by page_scan() called in pages_init(). */ - m_last_rec_id = 0; - - // Initialize the page table containing all info on pages (address, type etc). - pages_init(&pages_avail, &write_page_tag, &resume_compression); - - if (pages_avail == 0 && !write_page_tag) + if ((p_record->file_id == FDS_FILE_ID_INVALID) || + (p_record->key == FDS_RECORD_KEY_DIRTY)) { - return NRF_ERROR_NO_MEM; + return FDS_ERR_INVALID_ARG; } - /** This flag means fds_init() has been called. However, - * the module is NOT yet initialized. */ - flag_set(FDS_FLAG_INITIALIZING); - - if (resume_compression) + if (!chunk_is_aligned(p_record->data.p_chunks, + p_record->data.num_chunks)) { - return NRF_SUCCESS; + return FDS_ERR_UNALIGNED_ADDR; } - if (write_page_tag) + // No space was previously reserved for this operation. + if (p_tok == NULL) { - if (queue_reserve(FDS_CMD_QUEUE_SIZE_INIT, 0, &p_cmd, NULL) != NRF_SUCCESS) + // Compute the total length of the record. + for (uint32_t i = 0; i < p_record->data.num_chunks; i++) { - // Should never happen. - return NRF_ERROR_BUSY; + length_words += p_record->data.p_chunks[i].length_words; } - // Initialize the command in the queue. - p_cmd->id = FDS_CMD_INIT; + // Find a page where to write data. + ret = write_space_reserve(length_words, &page); - return cmd_queue_process_start(); + if (ret != FDS_SUCCESS) + { + // There is either not enough flash space available (FDS_ERR_NO_SPACE_IN_FLASH) or + // the record exceeds the virtual page size (FDS_ERR_RECORD_TOO_LARGE). + return ret; + } } else { - /* No flash operation is necessary for initialization. - * We can notify the application immediately. */ - flag_set (FDS_FLAG_INITIALIZED); - flag_clear(FDS_FLAG_INITIALIZING); - app_notify(NRF_SUCCESS, FDS_CMD_INIT, 0 /*unused*/, dummy_key /*unused*/); + page = p_tok->page; + length_words = p_tok->length_words; } - return NRF_SUCCESS; -} - + // Initialize the operation. + op.op_code = op_code; + op.write.step = FDS_OP_WRITE_HEADER_BEGIN; + op.write.page = page; + op.write.chunk_count = p_record->data.num_chunks; + op.write.chunk_offset = FDS_OFFSET_DATA; + op.write.header.record_id = record_id_new(); + op.write.header.ic.file_id = p_record->file_id; + op.write.header.tl.record_key = p_record->key; + op.write.header.tl.length_words = length_words; -ret_code_t fds_open(fds_record_desc_t * const p_desc, - fds_record_t * const p_record) -{ - uint16_t page; - - if (p_desc == NULL || p_record == NULL) + if (op_code == FDS_OP_UPDATE) { - return NRF_ERROR_NULL; + op.write.step = FDS_OP_WRITE_FIND_RECORD; + // Save the record ID of the record to be updated. + op.write.record_to_delete = p_desc->record_id; } - if (page_id_from_virtual_id(p_desc->vpage_id, &page) != NRF_SUCCESS) +#if defined (FDS_CRC_ENABLED) + // First, compute the CRC for the first 6 bytes of the header which contain the + // record key, length and file ID, then, compute the CRC of the record ID (4 bytes). + crc = crc16_compute((uint8_t*)&op.write.header, 6, NULL); + crc = crc16_compute((uint8_t*)&op.write.header.record_id, 4, &crc); + + for (uint32_t i = 0; i < p_record->data.num_chunks; i++) { - // Should not happen. - return NRF_ERROR_INVALID_DATA; + // Compute the CRC for the record data. + crc = crc16_compute((uint8_t*)p_record->data.p_chunks[i].p_data, + p_record->data.p_chunks[i].length_words * sizeof(uint32_t), &crc); } +#endif + + op.write.header.ic.crc16 = crc; - // Seek the record if necessary. - if (seek_record(p_desc) == NRF_SUCCESS) + // Attempt to enqueue the operation. + if (!op_enqueue(&op, p_record->data.num_chunks, p_record->data.p_chunks)) { - if (header_is_valid((fds_header_t*)p_desc->p_rec)) - { - CRITICAL_SECTION_ENTER(); - m_pages[page].records_open++; - CRITICAL_SECTION_EXIT(); + // No space availble in the queues. Cancel the reservation of flash space. + CRITICAL_SECTION_ENTER(); + write_space_free(length_words, page); + CRITICAL_SECTION_EXIT(); - p_record->header = *((fds_header_t*)p_desc->p_rec); - p_record->p_data = (p_desc->p_rec + FDS_HEADER_SIZE); + return FDS_ERR_NO_SPACE_IN_QUEUES; + } - return NRF_SUCCESS; - } + // Initialize the record descriptor, if provided. + if (p_desc != NULL) + { + p_desc->p_record = NULL; + // Don't invoke record_id_new() again ! + p_desc->record_id = op.write.header.record_id; + p_desc->record_is_open = false; + p_desc->gc_run_count = m_gc.run_count; } - /** The record could not be found. - * It either never existed or it has been cleared. */ - return NRF_ERROR_NOT_FOUND; + // Start processing the queue, if necessary. + queue_start(); + + return FDS_SUCCESS; } -ret_code_t fds_close(fds_record_desc_t const * const p_desc) +ret_code_t fds_register(fds_cb_t cb) { - uint16_t page; + ret_code_t ret; - if (p_desc == NULL) + CRITICAL_SECTION_ENTER(); + if (m_users == FDS_MAX_USERS) { - return NRF_ERROR_NULL; + ret = FDS_ERR_USER_LIMIT_REACHED; } - - if (page_id_from_virtual_id(p_desc->vpage_id, &page) != NRF_SUCCESS) + else { - return NRF_ERROR_INVALID_DATA; - } + m_cb_table[m_users] = cb; + m_users++; - CRITICAL_SECTION_ENTER(); - m_pages[page].records_open--; + ret = FDS_SUCCESS; + } CRITICAL_SECTION_EXIT(); - return NRF_SUCCESS; + return ret; } -static ret_code_t write_enqueue(fds_record_desc_t * const p_desc, - fds_record_key_t key, - uint8_t num_chunks, - fds_record_chunk_t chunks[], - fds_write_token_t const * const p_tok, - bool do_update) +ret_code_t fds_init(void) { - ret_code_t ret; - fds_cmd_t * p_cmd; - fds_record_chunk_t * p_chunk = NULL; - uint16_t vpage_id; - uint16_t length_words = 0; - uint8_t cmd_queue_elems; + fds_evt_t const evt_success = + { + .id = FDS_EVT_INIT, + .result = FDS_SUCCESS + }; - if (!flag_is_set(FDS_FLAG_INITIALIZED)) + // No initialization is necessary. Notify the application immediately. + if (flag_is_set(FDS_FLAG_INITIALIZED)) { - return NRF_ERROR_INVALID_STATE; + event_send(&evt_success); + return FDS_SUCCESS; } - if ((key.type == FDS_TYPE_ID_INVALID) || - (key.instance == FDS_INSTANCE_ID_INVALID)) + if (flag_is_set(FDS_FLAG_INITIALIZING)) { - return NRF_ERROR_INVALID_DATA; + return FDS_SUCCESS; } - if (!chunk_is_aligned(chunks, num_chunks)) + flag_set(FDS_FLAG_INITIALIZING); + + (void)fs_init(); + + // Initialize the page structure (m_pages), and determine which + // initialization steps are required given the current state of the filesystem. + fds_op_t op; + op.op_code = FDS_OP_INIT; + + fds_init_opts_t init_opts = pages_init(); + + switch (init_opts) { - return NRF_ERROR_INVALID_ADDR; + case NO_PAGES: + case NO_SWAP: + return FDS_ERR_NO_PAGES; + + case ALREADY_INSTALLED: + // No initialization is necessary. Notify the application immediately. + flag_set(FDS_FLAG_INITIALIZED); + flag_clear(FDS_FLAG_INITIALIZING); + event_send(&evt_success); + return FDS_SUCCESS; + + case FRESH_INSTALL: + case TAG_SWAP: + op.init.step = FDS_OP_INIT_TAG_SWAP; + break; + + case PROMOTE_SWAP: + case PROMOTE_SWAP_INST: + op.init.step = FDS_OP_INIT_PROMOTE_SWAP; + break; + + case DISCARD_SWAP: + op.init.step = FDS_OP_INIT_ERASE_SWAP; + break; + + case TAG_DATA: + case TAG_DATA_INST: + op.init.step = FDS_OP_INIT_TAG_DATA; + break; + + default: + // Should not happen. + break; } - cmd_queue_elems = do_update ? FDS_CMD_QUEUE_SIZE_UPDATE : FDS_CMD_QUEUE_SIZE_WRITE; + // This cannot fail since it will be the first operation in the queue. + (void)op_enqueue(&op, 0, NULL); + + queue_start(); + + return FDS_SUCCESS; +} + - // Reserve space on both queues, and obtain pointers to the first elements reserved. - ret = queue_reserve(cmd_queue_elems, - num_chunks, - &p_cmd, - &p_chunk); +ret_code_t fds_record_open(fds_record_desc_t * const p_desc, + fds_flash_record_t * const p_flash_rec) +{ + uint16_t page; - if (ret != NRF_SUCCESS) + if ((p_desc == NULL) || (p_flash_rec == NULL)) { - return ret; + return FDS_ERR_NULL_ARG; } - // No space was previously reserved for this operation. - if (p_tok == NULL) + // Find the record if necessary. + if (record_find_by_desc(p_desc, &page)) { - // Compute the total length of the record. - for (uint8_t i = 0; i < num_chunks; i++) - { - length_words += chunks[i].length_words; - } + fds_header_t const * const p_header = (fds_header_t*)p_desc->p_record; - /** Find a page where we can write the data. Reserve the space necessary - * to write the metadata as well. */ - ret = write_space_reserve(length_words, &vpage_id); - if (ret != NRF_SUCCESS) +#if defined(FDS_CRC_ENABLED) + if (!crc_verify_success(p_header->ic.crc16, + p_header->tl.length_words, + p_desc->p_record)) { - // If there is no space available, cancel the queue reservation. - queue_reserve_cancel(cmd_queue_elems, num_chunks); - return ret; + return FDS_ERR_CRC_CHECK_FAILED; } +#endif + + CRITICAL_SECTION_ENTER(); + m_pages[page].records_open++; + CRITICAL_SECTION_EXIT(); + + // Initialize p_flash_rec. + p_flash_rec->p_header = p_header; + p_flash_rec->p_data = (p_desc->p_record + FDS_HEADER_SIZE); + + // Set the record as open in the descriptor. + p_desc->record_is_open = true; + + return FDS_SUCCESS; } - else - { - length_words = p_tok->length_words; - vpage_id = p_tok->vpage_id; - } - // Initialize the command. - p_cmd->id = do_update ? FDS_CMD_UPDATE : FDS_CMD_WRITE; - p_cmd->op_code = FDS_OP_WRITE_TL; - p_cmd->num_chunks = num_chunks; - p_cmd->chunk_offset = FDS_WRITE_OFFSET_DATA; - p_cmd->vpage_id = vpage_id; + // The record could not be found. + // It either never existed or it has been deleted. + return FDS_ERR_NOT_FOUND; +} + - // Fill in the header information. - p_cmd->record_header.id = record_id_new(); - p_cmd->record_header.tl.type = key.type; - p_cmd->record_header.tl.length_words = length_words; - p_cmd->record_header.ic.instance = key.instance; - p_cmd->record_header.ic.checksum = 0; +ret_code_t fds_record_close(fds_record_desc_t * const p_desc) +{ + ret_code_t ret; + uint16_t page; - // Buffer the record chunks in the queue. - for (uint8_t i = 0; i < num_chunks; i++) + if (p_desc == NULL) { - p_chunk->p_data = chunks[i].p_data; - p_chunk->length_words = chunks[i].length_words; - chunk_queue_next(&p_chunk); + return FDS_ERR_NULL_ARG; } - if (do_update) + if (record_find_by_desc((fds_record_desc_t*)p_desc, &page)) { - // Clear - cmd_queue_next(&p_cmd); - p_cmd->id = FDS_CMD_CLEAR; - p_cmd->op_code = FDS_OP_CLEAR_TL; + CRITICAL_SECTION_ENTER(); + if ((m_pages[page].records_open > 0) && (p_desc->record_is_open)) + { - p_cmd->vpage_id = p_desc->vpage_id; - p_cmd->record_header.id = p_desc->record_id; - } + m_pages[page].records_open--; + p_desc->record_is_open = false; - // Initialize the record descriptor, if provided. - if (p_desc != NULL) + ret = FDS_SUCCESS; + } + else + { + ret = FDS_ERR_NO_OPEN_RECORDS; + } + CRITICAL_SECTION_EXIT(); + } + else { - p_desc->vpage_id = vpage_id; - // Don't invoke record_id_new() again. - p_desc->record_id = p_cmd->record_header.id; + ret = FDS_ERR_NOT_FOUND; } - return cmd_queue_process_start(); + return ret; } -ret_code_t fds_reserve(fds_write_token_t * const p_tok, uint16_t length_words) +ret_code_t fds_reserve(fds_reserve_token_t * const p_tok, uint16_t length_words) { - uint16_t vpage_id; + ret_code_t ret; + uint16_t page; if (!flag_is_set(FDS_FLAG_INITIALIZED)) { - return NRF_ERROR_INVALID_STATE; + return FDS_ERR_NOT_INITIALIZED; } if (p_tok == NULL) { - return NRF_ERROR_NULL; + return FDS_ERR_NULL_ARG; } - // Reserve space on the page. write_space_reserve() accounts for the header. - if (write_space_reserve(length_words, &vpage_id) == NRF_SUCCESS) + ret = write_space_reserve(length_words, &page); + + if (ret == FDS_SUCCESS) { - p_tok->vpage_id = vpage_id; + p_tok->page = page; p_tok->length_words = length_words; - - return NRF_SUCCESS; } - return NRF_ERROR_NO_MEM; + return ret; } -ret_code_t fds_reserve_cancel(fds_write_token_t * const p_tok) +ret_code_t fds_reserve_cancel(fds_reserve_token_t * const p_tok) { - fds_page_t * p_page; + ret_code_t ret; if (!flag_is_set(FDS_FLAG_INITIALIZED)) { - return NRF_ERROR_INVALID_STATE; + return FDS_ERR_NOT_INITIALIZED; } if (p_tok == NULL) { - return NRF_ERROR_NULL; + return FDS_ERR_NULL_ARG; } - if (page_from_virtual_id(p_tok->vpage_id, &p_page) != NRF_SUCCESS) + if (p_tok->page > FDS_MAX_PAGES) { - // Could not find the virtual page. This shouldn't happen. - return NRF_ERROR_INVALID_DATA; + // The page does not exist. This shouldn't happen. + return FDS_ERR_INVALID_ARG; } - if ((p_page->words_reserved - p_tok->length_words) < 0) + fds_page_t const * const p_page = &m_pages[p_tok->page]; + + CRITICAL_SECTION_ENTER(); + if (p_page->words_reserved - (FDS_HEADER_SIZE + p_tok->length_words) >= 0) + { + // Free reserved space. + write_space_free(p_tok->length_words, p_tok->page); + + // Clean the token. + p_tok->page = 0; + p_tok->length_words = 0; + ret = FDS_SUCCESS; + } + else { - /** We are trying to cancel a reservation for more words than how many are - * currently reserved on the page. This is shouldn't happen. */ - return NRF_ERROR_INVALID_DATA; + // We are trying to cancel a reservation of more words than how many are + // currently reserved on the page. Clearly, this shouldn't happen. + ret = FDS_ERR_INVALID_ARG; } + CRITICAL_SECTION_EXIT(); - // Free the space which had been reserved. - p_page->words_reserved -= p_tok->length_words; + return ret; +} - // Clean the token. - p_tok->vpage_id = 0; - p_tok->length_words = 0; - return NRF_SUCCESS; +ret_code_t fds_record_write(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record) +{ + return write_enqueue(p_desc, p_record, NULL, FDS_OP_WRITE); } -ret_code_t fds_write(fds_record_desc_t * const p_desc, - fds_record_key_t key, - uint8_t num_chunks, - fds_record_chunk_t chunks[]) +ret_code_t fds_record_write_reserved(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record, + fds_reserve_token_t const * const p_tok) { - ret_code_t ret; - atomic_counter_inc(); - ret = write_enqueue(p_desc, key, num_chunks, chunks, NULL, false /*not an update*/); - atomic_counter_dec(); - return ret; + // A NULL token is not allowed when writing to a reserved space. + if (p_tok == NULL) + { + return FDS_ERR_NULL_ARG; + } + + return write_enqueue(p_desc, p_record, p_tok, FDS_OP_WRITE); } -ret_code_t fds_write_reserved(fds_write_token_t const * const p_tok, - fds_record_desc_t * const p_desc, - fds_record_key_t key, - uint8_t num_chunks, - fds_record_chunk_t chunks[]) +ret_code_t fds_record_update(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record) { - ret_code_t ret; - atomic_counter_inc(); - ret = write_enqueue(p_desc, key, num_chunks, chunks, p_tok, false /*not an update*/); - atomic_counter_dec(); - return ret; + // A NULL descriptor is not allowed when updating a record. + if (p_desc == NULL) + { + return FDS_ERR_NULL_ARG; + } + + return write_enqueue(p_desc, p_record, NULL, FDS_OP_UPDATE); } -static ret_code_t clear_enqueue(fds_record_desc_t * const p_desc) +ret_code_t fds_record_delete(fds_record_desc_t * const p_desc) { - ret_code_t ret; - fds_cmd_t * p_cmd; + fds_op_t op; if (!flag_is_set(FDS_FLAG_INITIALIZED)) { - return NRF_ERROR_INVALID_STATE; + return FDS_ERR_NOT_INITIALIZED; } if (p_desc == NULL) { - return NRF_ERROR_NULL; + return FDS_ERR_NULL_ARG; } - ret = queue_reserve(FDS_CMD_QUEUE_SIZE_CLEAR, 0, &p_cmd, NULL); + op.op_code = FDS_OP_DEL_RECORD; + op.del.step = FDS_OP_DEL_RECORD_FLAG_DIRTY; + op.del.record_to_delete = p_desc->record_id; - if (ret != NRF_SUCCESS) + if (op_enqueue(&op, 0, NULL)) { - return ret; + queue_start(); + return FDS_SUCCESS; } - // Initialize the command. - p_cmd->id = FDS_CMD_CLEAR; - p_cmd->op_code = FDS_OP_CLEAR_TL; - - p_cmd->record_header.id = p_desc->record_id; - p_cmd->vpage_id = p_desc->vpage_id; - - return cmd_queue_process_start(); + return FDS_ERR_NO_SPACE_IN_QUEUES; } -ret_code_t fds_clear(fds_record_desc_t * const p_desc) +ret_code_t fds_file_delete(uint16_t file_id) { - ret_code_t ret; - atomic_counter_inc(); - ret = clear_enqueue(p_desc); - atomic_counter_dec(); - return ret; -} - - -static ret_code_t clear_by_instance_enqueue(fds_instance_id_t instance) -{ - ret_code_t ret; - fds_cmd_t * p_cmd; + fds_op_t op; if (!flag_is_set(FDS_FLAG_INITIALIZED)) { - return NRF_ERROR_INVALID_STATE; + return FDS_ERR_NOT_INITIALIZED; } - ret = queue_reserve(FDS_CMD_QUEUE_SIZE_CLEAR, 0, &p_cmd, NULL); - - if (ret != NRF_SUCCESS) + if (file_id == FDS_FILE_ID_INVALID) { - return ret; + return FDS_ERR_INVALID_ARG; } - p_cmd->id = FDS_CMD_CLEAR_INST; - p_cmd->op_code = FDS_OP_CLEAR_INSTANCE; - - p_cmd->record_header.ic.instance = instance; - - return cmd_queue_process_start(); -} - -ret_code_t fds_clear_by_instance(fds_instance_id_t instance) -{ - ret_code_t ret; - atomic_counter_inc(); - ret = clear_by_instance_enqueue(instance); - atomic_counter_dec(); - return ret; -} + op.op_code = FDS_OP_DEL_FILE; + op.del.step = FDS_OP_DEL_FILE_FLAG_DIRTY; + op.del.file_id = file_id; + if (op_enqueue(&op, 0, NULL)) + { + queue_start(); + return FDS_SUCCESS; + } -ret_code_t fds_update(fds_record_desc_t * const p_desc, - fds_record_key_t key, - uint8_t num_chunks, - fds_record_chunk_t chunks[]) -{ - ret_code_t ret; - atomic_counter_inc(); - ret = write_enqueue(p_desc, key, num_chunks, chunks, NULL, true /*update*/); - atomic_counter_dec(); - return ret; + return FDS_ERR_NO_SPACE_IN_QUEUES; } -static ret_code_t gc_enqueue() +ret_code_t fds_gc(void) { - ret_code_t ret; - fds_cmd_t * p_cmd; + fds_op_t op; if (!flag_is_set(FDS_FLAG_INITIALIZED)) { - return NRF_ERROR_INVALID_STATE; + return FDS_ERR_NOT_INITIALIZED; } - ret = queue_reserve(FDS_CMD_QUEUE_SIZE_GC, 0, &p_cmd, NULL); - if (ret != NRF_SUCCESS) + op.op_code = FDS_OP_GC; + + if (op_enqueue(&op, 0, NULL)) { - return ret; + if (m_gc.state != GC_BEGIN) + { + // Resume GC by retrying the last step. + m_gc.resume = true; + } + + queue_start(); + return FDS_SUCCESS; } - p_cmd->id = FDS_CMD_GC; + return FDS_ERR_NO_SPACE_IN_QUEUES; +} - // Set compression parameters. - m_gc.state = BEGIN; - return cmd_queue_process_start(); +ret_code_t fds_record_iterate(fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token) +{ + return record_find(NULL, NULL, p_desc, p_token); } -ret_code_t fds_gc() +ret_code_t fds_record_find(uint16_t file_id, + uint16_t record_key, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token) { - ret_code_t ret; - atomic_counter_inc(); - ret = gc_enqueue(); - atomic_counter_dec(); - return ret; + return record_find(&file_id, &record_key, p_desc, p_token); } -ret_code_t fds_find(fds_type_id_t type, - fds_instance_id_t instance, - fds_record_desc_t * const p_desc, - fds_find_token_t * const p_token) +ret_code_t fds_record_find_by_key(uint16_t record_key, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token) { - if (p_desc == NULL || p_token == NULL) - { - return NRF_ERROR_NULL; - } - - return find_record(&type, &instance, p_desc, p_token); + return record_find(NULL, &record_key, p_desc, p_token); } -ret_code_t fds_find_by_type(fds_type_id_t type, - fds_record_desc_t * const p_desc, - fds_find_token_t * const p_token) +ret_code_t fds_record_find_in_file(uint16_t file_id, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token) { - if (p_desc == NULL || p_token == NULL) - { - return NRF_ERROR_NULL; - } - - return find_record(&type, NULL, p_desc, p_token); + return record_find(&file_id, NULL, p_desc, p_token); } -ret_code_t fds_find_by_instance(fds_instance_id_t instance, - fds_record_desc_t * const p_desc, - fds_find_token_t * const p_token) +ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc, + uint32_t record_id) { - if (p_desc == NULL || p_token == NULL) + if (p_desc == NULL) { - return NRF_ERROR_NULL; + return FDS_ERR_NULL_ARG; } - return find_record(NULL, &instance, p_desc, p_token); + // Zero the descriptor and set the record_id field. + memset(p_desc, 0x00, sizeof(fds_record_desc_t)); + p_desc->record_id = record_id; + + return FDS_SUCCESS; } -ret_code_t fds_register(fds_cb_t cb) +ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc, + uint32_t * const p_record_id) { - if (m_users == FDS_MAX_USERS) + if ((p_desc == NULL) || (p_record_id == NULL)) { - return NRF_ERROR_NO_MEM; + return FDS_ERR_NULL_ARG; } - m_cb_table[m_users] = cb; - m_users++; + *p_record_id = p_desc->record_id; - return NRF_SUCCESS; + return FDS_SUCCESS; } -bool fds_descriptor_match(fds_record_desc_t const * const p_desc1, - fds_record_desc_t const * const p_desc2) +ret_code_t fds_stat(fds_stat_t * const p_stat) { - if ((p_desc1 == NULL) || (p_desc2 == NULL)) + uint16_t const words_in_page = FDS_PAGE_SIZE; + // The largest number of free contiguous words on any page. + uint16_t contig_words = 0; + + if (!flag_is_set(FDS_FLAG_INITIALIZED)) { - return false; + return FDS_ERR_NOT_INITIALIZED; } - return (p_desc1->record_id == p_desc2->record_id); -} + if (p_stat == NULL) + { + return FDS_ERR_NULL_ARG; + } + memset(p_stat, 0x00, sizeof(fds_stat_t)); -ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc, - fds_record_id_t record_id) -{ - if (p_desc == NULL) + for (uint16_t i = 0; i < FDS_MAX_PAGES; i++) { - return NRF_ERROR_NULL; - } + uint32_t const * p_record = NULL; + uint16_t const words_used = m_pages[i].write_offset + m_pages[i].words_reserved; - p_desc->record_id = record_id; - p_desc->vpage_id = FDS_VPAGE_ID_UNKNOWN; + p_stat->open_records += m_pages[i].records_open; + p_stat->words_reserved += m_pages[i].words_reserved; + p_stat->words_used += words_used; + contig_words = (words_in_page - words_used); + + if (contig_words > p_stat->largest_contig) + { + p_stat->largest_contig = contig_words; + } + + while (record_find_next(i, &p_record)) + { + p_stat->valid_records++; + } + + dirty_records_stat(i, &p_stat->dirty_records, &p_stat->freeable_words); + } - return NRF_SUCCESS; + return FDS_SUCCESS; } -ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc, - fds_record_id_t * const p_record_id) + +#if defined(FDS_CRC_ENABLED) + +ret_code_t fds_verify_crc_on_writes(bool enable) { - if (p_desc == NULL || p_record_id == NULL) + if (enable) { - return NRF_ERROR_NULL; + flag_set(FDS_FLAG_VERIFY_CRC); + } + else + { + flag_clear(FDS_FLAG_VERIFY_CRC); } - *p_record_id = p_desc->record_id; - - return NRF_SUCCESS; + return FDS_SUCCESS; } +#endif +#endif //NRF_MODULE_ENABLED(FDS) diff --git a/components/libraries/fds/fds.h b/components/libraries/fds/fds.h index 3d4a561..f81cb44 100644 --- a/components/libraries/fds/fds.h +++ b/components/libraries/fds/fds.h @@ -1,546 +1,761 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 FDS_H__ #define FDS_H__ /** - * @defgroup flash_data_storage Flash Data Storage + * @defgroup fds Flash Data Storage * @ingroup app_common * @{ - * @brief Flash Data Storage (FDS). * - * @details Flash Data Storage (FDS) is a minimalistic filesystem for the on-chip flash. - * It can be used to manipulate @e records, which consist of a piece of data, made up - * of one or more chunks, and an associated key pair. + * @brief Flash Data Storage (FDS). + * + * @details Flash Data Storage is a minimalistic, record-oriented file system for the on-chip + * flash. Files are stored as a collection of records of variable length. FDS supports + * synchronous read operations and asynchronous write operations (write, update, + * and delete). FDS can be used from multiple threads. */ #include #include #include "sdk_errors.h" +#include "app_util_platform.h" +#ifdef __cplusplus +extern "C" { +#endif -/**@brief */ -#define SIZEOF_WORDS(val) (sizeof(val) / 4) -/**@brief Reserved type key used to flag cleared records. - * May not be used as a record key by the application. */ -#define FDS_TYPE_ID_INVALID (0x0000) -/**@brief Reserved instance key used to check for missing or corrupted metadata. - * May not be used as a record key by the application. */ -#define FDS_INSTANCE_ID_INVALID (0xFFFF) +/**@brief Invalid file ID. + * + * This value must not be used as a file ID by the application. + */ +#define FDS_FILE_ID_INVALID (0xFFFF) -typedef uint32_t fds_record_id_t; -typedef uint16_t fds_type_id_t; -typedef uint16_t fds_length_t; -typedef uint16_t fds_instance_id_t; -typedef uint16_t fds_checksum_t; +/**@brief Record key for deleted records. + * + * This key is used to flag a record as "dirty", which means that it should be removed during + * the next garbage collection. This value must not be used as a record key by the application. + */ +#define FDS_RECORD_KEY_DIRTY (0x0000) -/**@brief A piece of a record metadata, keeping information about one of its keys (type) and its - * lenght, expressed in 4 byte words. */ -typedef struct +/**@brief FDS return values. + */ +enum +{ + FDS_SUCCESS = NRF_SUCCESS, //!< The operation completed successfully. + FDS_ERR_OPERATION_TIMEOUT, //!< Error. The operation timed out. + FDS_ERR_NOT_INITIALIZED, //!< Error. The module has not been initialized. + FDS_ERR_UNALIGNED_ADDR, //!< Error. The input data is not aligned to a word boundary. + FDS_ERR_INVALID_ARG, //!< Error. The parameter contains invalid data. + FDS_ERR_NULL_ARG, //!< Error. The parameter is NULL. + FDS_ERR_NO_OPEN_RECORDS, //!< Error. The record is not open, so it cannot be closed. + FDS_ERR_NO_SPACE_IN_FLASH, //!< Error. There is no space in flash memory. + FDS_ERR_NO_SPACE_IN_QUEUES, //!< Error. There is no space in the internal queues. + FDS_ERR_RECORD_TOO_LARGE, //!< Error. The record exceeds the maximum allowed size. + FDS_ERR_NOT_FOUND, //!< Error. The record was not found. + FDS_ERR_NO_PAGES, //!< Error. No flash pages are available. + FDS_ERR_USER_LIMIT_REACHED, //!< Error. The maximum number of users has been reached. + FDS_ERR_CRC_CHECK_FAILED, //!< Error. The CRC check failed. + FDS_ERR_BUSY, //!< Error. The underlying flash subsystem was busy. + FDS_ERR_INTERNAL, //!< Error. An internal error occurred. +}; + + +/**@brief Part of the record metadata. + * + * Contains the record key and the length of the record data. + */ +typedef struct { - fds_type_id_t type; /**< The record type ID. */ - fds_length_t length_words; /**< Length of the record's data, in 4 byte words. */ + uint16_t record_key; //!< The record key (must be in the range 0x0001 - 0xBFFF). + uint16_t length_words; //!< The length of the record data (in 4-byte words). } fds_tl_t; -/**@brief A piece of a record metadata, keeping information about one of its keys (instance) and - * its checksum. */ +/**@brief Part of the record metadata. + * + * Contains the ID of the file that the record belongs to and the CRC16 check value of the record. + */ typedef struct { - fds_instance_id_t instance; /**< The record instance ID. */ - fds_checksum_t checksum; /**< Checksum of the entire record, including the metadata. */ + uint16_t file_id; //!< The ID of the file that the record belongs to. + + /**@brief CRC16 check value. + * + * The CRC is calculated over the entire record as stored in flash (including the record + * metadata except the CRC field itself). The CRC standard employed is CRC-16-CCITT. + */ + uint16_t crc16; } fds_ic_t; -/**@brief The record metadata. */ +/**@brief The record metadata as stored in flash. + */ typedef struct { - fds_tl_t tl; /**< See @ref fds_tl_t. */ - fds_ic_t ic; /**< See @ref fds_ic_t. */ - fds_record_id_t id; /**< The unique record ID (32 bits). */ + fds_tl_t tl; //!< See @ref fds_tl_t. + fds_ic_t ic; //!< See @ref fds_ic_t. + uint32_t record_id; //!< The unique record ID (32 bits). } fds_header_t; -typedef fds_header_t fds_record_header_t; - -/**@brief The record descriptor structure, used to manipulate a record. - * @note This structure is meant to be opaque to the user, who does not need to access - * any of its fields. - * @note This structure does not need special initialization. - * @warning Do not reuse the same descriptor for different records. If you do, be sure to set - * its fields to zero. */ +/**@brief The record descriptor structure that is used to manipulate records. + * + * This structure is used by the FDS module. You must provide the descriptor to the module when + * you manipulate existing records. However, you should never modify it or use any of its fields. + * + * @note Never reuse the same descriptor for different records. + */ typedef struct { - uint32_t record_id; /**< The unique record ID. */ - uint32_t const * p_rec; /**< The last known record address in flash. */ - uint16_t vpage_id; /**< The virtual page ID in which the record is stored. */ - uint16_t gc_magic; /**< Number of times the GC algorithm has been run. */ - uint16_t ptr_magic; /**< Used to verify the validity of p_rec. */ + uint32_t record_id; //!< The unique record ID. + uint32_t const * p_record; //!< The last known location of the record in flash. + uint16_t gc_run_count; //!< Number of times garbage collection has been run. + bool record_is_open; //!< Whether the record is currently open. } fds_record_desc_t; -/**@brief The record key, used to lookup records. - * @note The uniqueness of either field is not enforced by the system. */ +/**@brief Structure that can be used to read the contents of a record stored in flash. + * + * This structure does not reflect the physical layout of a record in flash, but it points + * to the locations where the record header (metadata) and the record data are stored. + */ typedef struct { - uint16_t type; - uint16_t instance; -} fds_record_key_t; + fds_header_t const * p_header; //!< Location of the record header in flash. + void const * p_data; //!< Location of the record data in flash. +} fds_flash_record_t; -/**@brief Structure used for reading a record back from flash memory. */ +/**@brief A chunk of record data to be written to flash. + * + * @p p_data must be aligned to a word boundary. Make sure to keep it in + * memory until the operation has completed, which is indicated by the respective FDS event. + */ typedef struct { - // TODO: the header should be a pointer. - fds_header_t header; /**< The record header (metadata), as stored in flash. */ - uint32_t const * p_data; /**< The record data. */ -} fds_record_t; + void const * p_data; //!< Pointer to the data to store. Must be word-aligned. + uint16_t length_words; //!< Length of data pointed to by @p p_data (in 4-byte words). +} fds_record_chunk_t; -/**@brief A record chunk, containing a piece of data to be stored in a record. - * - * @note p_data must be aligned on a (4 bytes) word boundary. +/**@brief A record to be written to flash. */ typedef struct { - void const * p_data; /**< Pointer to the data to store. Must be word aligned. */ - fds_length_t length_words; /**< Length of data pointed by p_data, in 4 byte words. */ -} fds_record_chunk_t; + uint16_t file_id; //!< The ID of the file that the record belongs to. + uint16_t key; //!< The record key. + struct + { + fds_record_chunk_t const * p_chunks; //!< The chunks that make up the record data. + uint16_t num_chunks; //!< The number of chunks that make up the data. + } data; +} fds_record_t; -/**@brief A token to a reserved space in flash, created by @ref fds_reserve. - * Use @ref fds_write_reserved to write the record in the reserved space, - * or @ref fds_reserve_cancel to cancel the reservation. +/**@brief A token to a reserved space in flash, created by @ref fds_reserve. + * + * This token can be used to write the record in the reserved space (@ref fds_record_write_reserved) + * or to cancel the reservation (@ref fds_reserve_cancel). */ typedef struct { - uint16_t vpage_id; /**< The virtual ID of the page where space was reserved. */ - fds_length_t length_words; /**< The amount of space reserved, in 4 byte words. */ -} fds_write_token_t; - - -/**@brief A token to keep information about the progress of @ref fds_find, @ref fds_find_by_type - * and @ref fds_find_by_instance operations. - * @note This structure is meant to be opaque to the user, who does not need to access any of its - * fields. - * @note The token does not need special initialization. - * @warning Do not reuse the same token to search for different records. If you do, be sure to set - * its fields to zero. */ + uint16_t page; //!< The logical ID of the page where space was reserved. + uint16_t length_words; //!< The amount of space reserved (in 4-byte words). +} fds_reserve_token_t; + + +/**@brief A token to keep information about the progress of @ref fds_record_find, + * @ref fds_record_find_by_key, and @ref fds_record_find_in_file. + * + * @note Always zero-initialize the token before using it for the first time. + * @note Never reuse the same token to search for different records. + */ typedef struct { uint32_t const * p_addr; - uint32_t magic; - uint16_t vpage_id; + uint16_t page; } fds_find_token_t; +/**@brief FDS event IDs. + */ typedef enum { - FDS_CMD_NONE, /**< No command. */ - FDS_CMD_INIT, /**< Module initialization commnad. Used in @ref fds_init */ - FDS_CMD_WRITE, /**< Write command. Used in @ref fds_write and @ref fds_write_reserved. */ - FDS_CMD_UPDATE, /**< Update command. Used in @ref fds_update. */ - FDS_CMD_CLEAR, /**< Clear record command. Used in @ref fds_clear and @ref fds_update. */ - FDS_CMD_CLEAR_INST, /**< Clear instance command. Used in @ref fds_clear_by_instance. */ - FDS_CMD_GC /**< Garbage collection. Used in @ref fds_gc. */ -} fds_cmd_id_t; - - -/**@brief Flash data storage callback function. - * - * @param result Result of the command. - * @param cmd The command associated with the callback. - * @param record_id The unique ID of the record associated with the callback. - * @param record_key The key pair of the record associated with the callback. - */ -typedef void (*fds_cb_t)(ret_code_t result, - fds_cmd_id_t cmd, - fds_record_id_t record_id, - fds_record_key_t record_key); - - -/**@brief Function to register a callback for the module events. - * @details The maximum amount of callback which can be registered can be configured by - * changing the FDS_MAX_USERS macro in fds_config.h. - * - * @param[in] cb The callback function. + FDS_EVT_INIT, //!< Event for @ref fds_init. + FDS_EVT_WRITE, //!< Event for @ref fds_record_write and @ref fds_record_write_reserved. + FDS_EVT_UPDATE, //!< Event for @ref fds_record_update. + FDS_EVT_DEL_RECORD, //!< Event for @ref fds_record_delete. + FDS_EVT_DEL_FILE, //!< Event for @ref fds_file_delete. + FDS_EVT_GC //!< Event for @ref fds_gc. +} fds_evt_id_t; + + +ANON_UNIONS_ENABLE + +/**@brief An FDS event. + */ +typedef struct +{ + fds_evt_id_t id; //!< The event ID. See @ref fds_evt_id_t. + ret_code_t result; //!< The result of the operation related to this event. + union + { + struct + { + /* Currently not used. */ + uint16_t pages_not_mounted; + } init; + struct + { + uint32_t record_id; + uint16_t file_id; + uint16_t record_key; + bool is_record_updated; + } write; //!< Information for @ref FDS_EVT_WRITE and @ref FDS_EVT_UPDATE events. + struct + { + uint32_t record_id; + uint16_t file_id; + uint16_t record_key; + uint16_t records_deleted_count; + } del; //!< Information for @ref FDS_EVT_DEL_RECORD and @ref FDS_EVT_DEL_FILE events. + struct + { + /* Currently not used. */ + uint16_t pages_skipped; + uint16_t space_reclaimed; + } gc; + }; +} fds_evt_t; + +ANON_UNIONS_DISABLE + + +/**@brief File system statistics. */ +typedef struct +{ + uint16_t open_records; //!< The number of open records. + uint16_t valid_records; //!< The number of valid records. + uint16_t dirty_records; //!< The number of deleted ("dirty") records. + uint16_t words_reserved; //!< The number of words reserved by @ref fds_reserve(). + + /**@brief The number of words written to flash, including those reserved for future writes. + */ + uint16_t words_used; + + /**@brief The largest number of free contiguous words in the file system. + * + * This number determines the largest record that can be stored by FDS. + * It takes into account all reservations for future writes. + */ + uint16_t largest_contig; + + /**@brief The largest number of words that can be reclaimed by garbage collection. + * + * The actual amount of space freed by garbage collection might be less than this value if + * records are open while garbage collection is run. + */ + uint16_t freeable_words; +} fds_stat_t; + + +/**@brief FDS event handler function prototype. + * + * @param p_evt The event. + */ +typedef void (*fds_cb_t)(fds_evt_t const * const p_evt); + + +/**@brief Function for registering an FDS event handler. + * + * The maximum amount of handlers that can be registered can be configured by changing the value + * of @ref FDS_MAX_USERS in fds_config.h. * + * @param[in] cb The event handler function. * - * @retval NRF_SUCCESS Success. - * @retval NRF_ERROR_NO_MEM Error. Maximum number of registered callbacks reached. + * @retval FDS_SUCCESS If the event handler was registered successfully. + * @retval FDS_ERR_USER_LIMIT_REACHED If the maximum number of registered callbacks is reached. */ ret_code_t fds_register(fds_cb_t cb); -/**@brief Function to initialize the module. +/**@brief Function for initializing the module. * - * @details This function initializes the module and installs the filesystem, if it is not - * installed yet. + * This function initializes the module and installs the file system (unless it is installed + * already). * - * @note This function is asynchronous. Completion is reported with a callback through the - * registered event handler. To be able to receive such callback, be sure to call - * @ref fds_register before calling @ref fds_init. + * This function is asynchronous. Completion is reported through an event. Make sure to call + * @ref fds_register before calling @ref fds_init so that you receive the completion event. * - * @retval NRF_SUCCESS Success. The command was queued. - * @retval NRF_ERROR_INVALID_STATE Error. The module is currently undergoing initialization. - * @retval NRF_ERROR_NO_MEM Error. Insufficient space to install the filesystem, or - * insufficient resources to perform the installation. + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NO_PAGES If there is no space available in flash memory to install the + * file system. */ ret_code_t fds_init(void); -/**@brief Function to write a record to flash. - * - * @details This function can be used to write a record to flash. A record data consists of - * multiple chunks and is supplied to the function as an array of fds_record_chunk_t - * structures. The maximum lenght of a record data may not exceed the size of one flash - * page minus FDS_HEADER_SIZE words. - * - * @note This function is asynchronous, therefore, completion is reported with a callback - * through the registered event handler. - * - * @note The record data must be aligned on a 4 byte boundary, and because it is not buffered - * internally, it must be kept in memory by the application until the callback for the - * command has been received, i.e., the command completed. - * - * @param[out] p_desc The record descriptor. It may be NULL. - * @param[in] key The record key pair. - * @param[in] num_chunks The number of elements in the chunks array. - * @param[in] chunks An array of chunks making up the record data. - * - * @retval NRF_SUCCESS Success. The command was queued. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_INVALID_DATA Error. The key contains an invalid type or instance. - * @retval NRF_ERROR_INVALID_ADDR Error. The record data is not aligned on a 4 byte boundary. - * @retval NRF_ERROR_INVALID_LENGTH Error. The record length exceeds the maximum lenght. - * @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation. - * @retval NRF_ERROR_NO_MEM Error. No flash space available to store the record. +/**@brief Function for writing a record to flash. + * + * There are no restrictions on the file ID and the record key, except that the record key must be + * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from + * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of + * the file ID or the record key. All records with the same file ID are grouped into one file. + * If no file with the specified ID exists, it is created. There can be multiple records with the + * same record key in a file. + * + * Some modules need exclusive use of certain file IDs and record keys. See @ref lib_fds_functionality_keys + * for details. + * + * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and + * because it is not buffered internally, it must be kept in memory until the callback for the + * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE + * words minus 14 bytes. + * + * This function is asynchronous. Completion is reported through an event that is sent to + * the registered event handler function. + * + * @param[out] p_desc The descriptor of the record that was written. Pass NULL if you do not + * need the descriptor. + * @param[in] p_record The record to be written to flash. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_record is NULL. + * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid. + * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary. + * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record + * chunks than can be buffered. + * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the + * record. */ -ret_code_t fds_write(fds_record_desc_t * const p_desc, - fds_record_key_t key, - uint8_t num_chunks, - fds_record_chunk_t chunks[]); +ret_code_t fds_record_write(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record); -/**@brief Function to reserve space for a record. +/**@brief Function for reserving space in flash. + * + * This function can be used to reserve space in flash memory. To write a record into the reserved + * space, use @ref fds_record_write_reserved. Alternatively, use @ref fds_reserve_cancel to cancel + * a reservation. * - * @details This function can be used to reserve flash space to store a record, which can be - * later written down using @ref fds_write_reserved. It is possible to cancel a - * reservation by using @ref fds_reserve_cancel. + * Note that this function does not write any data to flash. * - * @param[out] p_tok A token which can be used to write a record in the reserved space - * using @ref fds_write_reserved. - * @param[in] length_words The lenght of the record data, in 4 byte words. + * @param[out] p_token A token that can be used to write a record in the reserved space or + * cancel the reservation. + * @param[in] length_words The length of the record data (in 4-byte words). * - * @retval NRF_SUCCESS Success. Flash space was successfully reserved. - * @retval NRF_ERROR_NULL Error. p_tok is NULL. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_NO_MEM Error. Insufficient space. + * @retval FDS_SUCCESS If the flash space was reserved successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address. + * @retval FDS_ERR_RECORD_TOO_LARGE If the record length exceeds the maximum length. + * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the + * record. */ -ret_code_t fds_reserve(fds_write_token_t * const p_tok, uint16_t length_words); +ret_code_t fds_reserve(fds_reserve_token_t * const p_token, uint16_t length_words); -/**@brief Function to cancel a space reservation. +/**@brief Function for canceling an @ref fds_reserve operation. * - * @param[in] p_tok The token produced by @ref fds_reserve, identifying the reservation to cancel. + * @param[in] p_token The token that identifies the reservation, produced by @ref fds_reserve. * - * @retval NRF_SUCCESS Success. The reservation was canceled. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_NULL Error. p_tok is NULL. - * @retval NRF_ERROR_INVALID_DATA Error. p_tok contains invalid data. + * @retval FDS_SUCCESS If the reservation was canceled. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address. + * @retval FDS_ERR_INVALID_ARG If @p p_token contains invalid data. + */ +ret_code_t fds_reserve_cancel(fds_reserve_token_t * const p_token); + + +/**@brief Function for writing a record to a space in flash that was reserved using + * @ref fds_reserve. + * + * There are no restrictions on the file ID and the record key, except that the record key must be + * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from + * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of + * the file ID or the record key. All records with the same file ID are grouped into one file. + * If no file with the specified ID exists, it is created. There can be multiple records with the + * same record key in a file. + * + * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and + * because it is not buffered internally, it must be kept in memory until the callback for the + * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE + * words minus 14 bytes. + * + * This function is asynchronous. Completion is reported through an event that is sent to the + * registered event handler function. + * + * @note + * This function behaves similarly to @ref fds_record_write, with the exception that it never + * fails with the error @ref FDS_ERR_NO_SPACE_IN_FLASH. + * + * @param[out] p_desc The descriptor of the record that was written. Pass NULL if you do not + * need the descriptor. + * @param[in] p_record The record to be written to flash. + * @param[in] p_token The token that identifies the space reserved in flash. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address. + * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid. + * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary. + * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record + * chunks than can be buffered. */ -ret_code_t fds_reserve_cancel(fds_write_token_t * const p_tok); +ret_code_t fds_record_write_reserved(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record, + fds_reserve_token_t const * const p_token); -/**@brief Function to write a record to flash, the space for which has been previously reserved - * using @ref fds_reserve. +/**@brief Function for deleting a record. * - * @details This function behaves similarly to @ref fds_write, with the exception that it never - * fails with NRF_ERROR_NO_MEM. + * Deleted records cannot be located using @ref fds_record_find, @ref fds_record_find_by_key, or + * @ref fds_record_find_in_file. Additionally, they can no longer be opened using + * @ref fds_record_open. * - * @note This function is asynchronous, therefore, completion is reported with a callback - * through the registered event handler. + * Note that deleting a record does not free the space it occupies in flash memory. + * To reclaim flash space used by deleted records, call @ref fds_gc to run garbage collection. * - * @note The record data must be aligned on a 4 byte boundary, and because it is not buffered - * internally, it must be kept in memory by the application until the callback for the - * command has been received, i.e., the command completed. + * This function is asynchronous. Completion is reported through an event that is sent to the + * registered event handler function. * - * @param[in] p_tok The token return by @ref fds_reserve. - * @param[out] p_desc The record descriptor. It may be NULL. - * @param[in] key The record key pair. - * @param[in] num_chunks The number of elements in the chunks array. - * @param[in] chunks An array of chunks making up the record data. + * @param[in] p_desc The descriptor of the record that should be deleted. * - * @retval NRF_SUCCESS Success. The command was queued. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_INVALID_DATA Error. The key contains an invalid type or instance. - * @retval NRF_ERROR_INVALID_ADDR Error. The record data is not aligned on a 4 byte boundary. - * @retval NRF_ERROR_INVALID_LENGTH Error. The record length exceeds the maximum lenght. - * @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation. + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If the specified record descriptor @p p_desc is NULL. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full. */ -ret_code_t fds_write_reserved(fds_write_token_t const * const p_tok, - fds_record_desc_t * const p_desc, - fds_record_key_t key, - uint8_t num_chunks, - fds_record_chunk_t chunks[]); +ret_code_t fds_record_delete(fds_record_desc_t * const p_desc); -/**@brief Function to clear a record. +/**@brief Function for deleting all records in a file. * - * @details Clearing a record has the effect of preventing the system from retrieving the record - * descriptor using the @ref fds_find, @ref fds_find_by_type and @ref fds_find_by_instance - * functions. Additionally, @ref fds_open calls shall fail when supplied a descritpor for - * a record which has been cleared. Clearing a record does not free the space it occupies - * in flash. The reclaim flash space used by cleared records, use @ref fds_gc. + * This function deletes a file, including all its records. Deleted records cannot be located + * using @ref fds_record_find, @ref fds_record_find_by_key, or @ref fds_record_find_in_file. + * Additionally, they can no longer be opened using @ref fds_record_open. * - * @note This function is asynchronous, therefore, completion is reported with a callback - * through the registered event handler. + * Note that deleting records does not free the space they occupy in flash memory. + * To reclaim flash space used by deleted records, call @ref fds_gc to run garbage collection. * - * @param[in] p_desc The descriptor of the record to clear. + * This function is asynchronous. Completion is reported through an event that is sent to the + * registered event handler function. * - * @retval NRF_SUCCESS Success. The command was queued. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_NULL Error. p_desc is NULL. - * @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation. + * @param[in] file_id The ID of the file to be deleted. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_INVALID_ARG If the specified @p file_id is invalid. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full. + */ +ret_code_t fds_file_delete(uint16_t file_id); + + +/**@brief Function for updating a record. + * + * Updating a record first writes a new record (@p p_record) to flash and then deletes the + * old record (identified by @p p_desc). + * + * There are no restrictions on the file ID and the record key, except that the record key must be + * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from + * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of + * the file ID or the record key. All records with the same file ID are grouped into one file. + * If no file with the specified ID exists, it is created. There can be multiple records with the + * same record key in a file. + * + * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and + * because it is not buffered internally, it must be kept in memory until the callback for the + * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE + * words minus 14 bytes. + * + * This function is asynchronous. Completion is reported through an event that is sent to the + * registered event handler function. + * + * @param[in, out] p_desc The descriptor of the record to update. When the function + * returns with FDS_SUCCESS, this parameter contains the + * descriptor of the newly written record. + * @param[in] p_record The updated record to be written to flash. + * + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid. + * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary. + * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record + * chunks than can be buffered. + * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the + * updated record. */ -ret_code_t fds_clear(fds_record_desc_t * const p_desc); +ret_code_t fds_record_update(fds_record_desc_t * const p_desc, + fds_record_t const * const p_record); -/**@brief Function to clear all records with a given instance. +/**@brief Function for iterating through all records in flash. * - * @details Clearing a record has the effect of preventing the system from retrieving the record - * descriptor using the @ref fds_find, @ref fds_find_by_type and @ref fds_find_by_instance - * functions. Additionally, @ref fds_open calls shall fail when supplied a descritpor for - * a record which has been cleared. Clearing a record does not free the space it occupies - * in flash. The reclaim flash space used by cleared records, use @ref fds_gc. + * To search for the next record, call the function again and supply the same @ref fds_find_token_t + * structure to resume searching from the last record that was found. * - * @note This function is asynchronous, therefore, completion is reported with a callback - * through the registered event handler. Only one callback will be issued. The record - * instance ID in the key parameter of the callback will contain the instance ID passed as - * parameter to this function. The record ID parameter will be zero, and the type ID equal - * to FDS_TYPE_ID_INVALID. + * Note that the order with which records are iterated is not defined. * - * @param[in] instance The instance ID of the records to clear. + * @param[out] p_desc The descriptor of the record that was found. + * @param[out] p_token A token containing information about the progress of the operation. * - * @retval NRF_SUCCESS Success. The command was queued. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_NULL Error. p_desc is NULL. - * @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation. + * @retval FDS_SUCCESS If a record was found. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL. + * @retval FDS_ERR_NOT_FOUND If no matching record was found. */ -ret_code_t fds_clear_by_instance(fds_instance_id_t instance); +ret_code_t fds_record_iterate(fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token); -/**@brief Function to update an existing record. +/**@brief Function for searching for records with a given record key in a file. * - * @details Updating a record writes a new record with the given key and data in flash, and then - * clears the old record. + * This function finds the first record in a file that has the given record key. To search for the + * next record with the same key in the file, call the function again and supply the same + * @ref fds_find_token_t structure to resume searching from the last record that was found. * - * @note This function is asynchronous, therefore, completion is reported with a callback - * through the registered event handler. Two callbacks will be issued, one to signal that - * the updated record has been written down, and another to signal that the old one has been - * cleared. - * - * @note The record data must be aligned on a 4 byte boundary, and because it is not buffered - * internally, it must be kept in memory by the application until the callback for the - * command has been received, i.e., the command completed. - * - * @param[in, out] p_desc The descriptor of the record to update. The descriptor of the updated - * record, after the function has returned with NRF_SUCCESS. - * @param[in] key The record new key pair. - * @param[in] num_chunks The number of elements in the chunks array. - * @param[in] chunks An array of chunks making up the record new data. + * @param[in] file_id The file ID. + * @param[in] record_key The record key. + * @param[out] p_desc The descriptor of the record that was found. + * @param[out] p_token A token containing information about the progress of the operation. * - * @retval NRF_SUCCESS Success. The command was queued. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_INVALID_DATA Error. The key contains an invalid type or instance. - * @retval NRF_ERROR_INVALID_ADDR Error. The record data is not aligned on a 4 byte boundary. - * @retval NRF_ERROR_INVALID_LENGTH Error. The record length exceeds the maximum lenght. - * @retval NRF_ERROR_BUSY Error. Insufficient internal resources to queue the operation. - * @retval NRF_ERROR_NO_MEM Error. No flash space available to store the record. + * @retval FDS_SUCCESS If a record was found. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL. + * @retval FDS_ERR_NOT_FOUND If no matching record was found. */ -ret_code_t fds_update(fds_record_desc_t * const p_desc, - fds_record_key_t key, - uint8_t num_chunks, - fds_record_chunk_t chunks[]); +ret_code_t fds_record_find(uint16_t file_id, + uint16_t record_key, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token); -/**@brief Function to search for records with a given key pair. +/**@brief Function for searching for records with a given record key. * - * @details Because types are not unique, to search for the next record with the given key call - * the function again and supply the same fds_find_token_t structure to resume searching - * from the last record found. + * This function finds the first record with a given record key, independent of the file it + * belongs to. To search for the next record with the same key, call the function again and supply + * the same @ref fds_find_token_t structure to resume searching from the last record that was found. * - * @param[in] type The record type ID. - * @param[in] instance The record instance ID. - * @param[out] p_desc The descriptor of the record found. - * @param[out] p_token A token containing information about the progress of the operation. + * @param[in] record_key The record key. + * @param[out] p_desc The descriptor of the record that was found. + * @param[out] p_token A token containing information about the progress of the operation. * - * @retval NRF_SUCCESS Success. A record was found. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_NULL Error. Either p_desc or p_token are NULL. - * @retval NRF_ERROR_NOT_FOUND Error. No record with the given key pair was found. + * @retval FDS_SUCCESS If a record was found. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL. + * @retval FDS_ERR_NOT_FOUND If no record with the given key was found. */ -ret_code_t fds_find(fds_type_id_t type, - fds_instance_id_t instance, - fds_record_desc_t * const p_desc, - fds_find_token_t * const p_token); +ret_code_t fds_record_find_by_key(uint16_t record_key, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token); -/**@brief Function to search for records with a given type. +/**@brief Function for searching for any record in a file. * - * @details Because types are not unique, to search for the next record with the given key call - * the function again and supply the same fds_find_token_t structure to resume searching - * from the last record found. + * This function finds the first record in a file, independent of its record key. + * To search for the next record in the same file, call the function again and supply the same + * @ref fds_find_token_t structure to resume searching from the last record that was found. * - * @param[in] type The type ID in the record key. - * @param[out] p_desc The descriptor of the record found. - * @param[out] p_token A token containing information about the progress of the operation. + * @param[in] file_id The file ID. + * @param[out] p_desc The descriptor of the record that was found. + * @param[out] p_token A token containing information about the progress of the operation. * - * @retval NRF_SUCCESS Success. A record was found. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_NULL Error. Either p_desc or p_token are NULL. - * @retval NRF_ERROR_NOT_FOUND Error. No record with the given type was found. + * @retval FDS_SUCCESS If a record was found. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL. + * @retval FDS_ERR_NOT_FOUND If no matching record was found. */ - ret_code_t fds_find_by_type(fds_type_id_t type, - fds_record_desc_t * const p_desc, - fds_find_token_t * const p_token); +ret_code_t fds_record_find_in_file(uint16_t file_id, + fds_record_desc_t * const p_desc, + fds_find_token_t * const p_token); -/**@brief Function to search for records with a given instance. +/**@brief Function for opening a record for reading. + * + * This function opens a record that is stored in flash, so that it can be read. The function + * initializes an @ref fds_flash_record_t structure, which can be used to access the record data as + * well as its associated metadata. The pointers provided in the @ref fds_flash_record_t structure + * are pointers to flash memory. + * + * Opening a record with @ref fds_record_open prevents garbage collection to run on the virtual + * flash page in which record is stored, so that the contents of the memory pointed by fields in + * @ref fds_flash_record_t are guaranteed to remain unmodified as long as the record is kept open. * - * @details Because types are not unique, to search for the next record with the given key call - * the function again and supply the same fds_find_token_t structure to resume searching - * from the last record found. + * When you are done reading a record, call @ref fds_record_close to close it. Garbage collection + * can then reclaim space on the virtual page where the record is stored. Note that you must + * provide the same descriptor for @ref fds_record_close as you did for this function. * - * @param[in] instance The instance ID in the record key. - * @param[out] p_desc The descriptor of the record found. - * @param[out] p_token A token containing information about the progress of the operation. + * @param[in] p_desc The descriptor of the record to open. + * @param[out] p_flash_record The record, as stored in flash. * - * @retval NRF_SUCCESS Success. A record was found. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_NULL Error. Either p_desc or p_token are NULL. - * @retval NRF_ERROR_NOT_FOUND Error. No record with the given instance was found. + * @retval FDS_SUCCESS If the record was opened successfully. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_flash_record is NULL. + * @retval FDS_ERR_NOT_FOUND If the record was not found. It might have been deleted, or + * it might not have been written yet. + * @retval FDS_ERR_CRC_CHECK_FAILED If the CRC check for the record failed. */ -ret_code_t fds_find_by_instance(fds_instance_id_t instance, - fds_record_desc_t * const p_desc, - fds_find_token_t * const p_token); +ret_code_t fds_record_open(fds_record_desc_t * const p_desc, + fds_flash_record_t * const p_flash_record); -/**@brief Function to open a record for reading. +/**@brief Function for closing a record. * - * @details Function to read a record which has been written to flash. This function initializes - * a fds_record_t structure which can be used to access the record data as well as - * its associated metadata. The pointers provided in the fds_record_t structure are - * pointers to flash memory. Opening a record with @ref fds_open prevents the garbage - * collection to run on the flash page in which record is stored, therefore the contents - * of the memory pointed by the fds_record_t p_data field is guaranteed to remain - * unmodified, as long as the record is kept open. + * Closing a record allows garbage collection to run on the virtual page in which the record is + * stored (if no other records remain open on that page). The descriptor passed as an argument + * must be the same as the one used to open the record using @ref fds_record_open. * - * @note When you are done reading a record, close it using @ref fds_close so that successive - * garbage collections can reclaim space on the page where the record is stored, if necessary. + * Note that closing a record does not invalidate its descriptor. You can still supply the + * descriptor to all functions that accept a record descriptor as a parameter. * - * @param[in] p_desc The descriptor of the record to open. - * @param[out] p_record The record data and metadata, as stored in flash. + * @param[in] p_desc The descriptor of the record to close. * - * @retval NRF_SUCCESS Success. The record was opened. - * @retval NRF_ERROR_NOT_FOUND Error. The record was not found. It may have been cleared, or it - * may have not been written yet. - * @retval NRF_ERROR_INVALID_DATA Error. The descriptor contains invalid data. - * @retval NRF_ERROR_NULL Error. Either p_desc or p_record are NULL. + * @retval FDS_SUCCESS If the record was closed successfully. + * @retval FDS_ERR_NULL_ARG If @p p_desc is NULL. + * @retval FDS_ERR_NO_OPEN_RECORDS If the record is not open. + * @retval FDS_ERR_NOT_FOUND If the record could not be found. */ -ret_code_t fds_open(fds_record_desc_t * const p_desc, - fds_record_t * const p_record); +ret_code_t fds_record_close(fds_record_desc_t * const p_desc); -/**@brief Function to close a record, after its contents have been read. +/**@brief Function for running garbage collection. * - * @details Closing a record allows garbage collection to be run on the page in which the - * record being closed is stored (if no other records remain open on that page). + * Garbage collection reclaims the flash space that is occupied by records that have been deleted, + * or that failed to be completely written due to, for example, a power loss. * - * @note Closing a record, does NOT invalidate its descriptor, which can be safely supplied to - * all functions which accept a descriptor as a parameter. + * This function is asynchronous. Completion is reported through an event that is sent to the + * registered event handler function. * - * @param[in] p_desc The descriptor of the record to close. - * - * @retval NRF_SUCCESS Success. The record was closed. - * @retval NRF_ERROR_NULL Error. p_desc is NULL. - * @retval NRF_ERROR_INVALID_DATA Error. The descriptor contains invalid data. + * @retval FDS_SUCCESS If the operation was queued successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full. */ -ret_code_t fds_close(fds_record_desc_t const * const p_desc); +ret_code_t fds_gc(void); -/**@brief Function to perform a garbage collection. +/**@brief Function for obtaining a descriptor from a record ID. + * + * This function can be used to reconstruct a descriptor from a record ID, like the one that is + * passed to the callback function. * - * @details Garbage collection reclaims the flash space occupied by records which have been cleared - * using @ref fds_clear. + * @note + * This function does not check whether a record with the given record ID exists. + * If a non-existing record ID is supplied, the resulting descriptor is invalid and will cause + * other functions to fail when it is supplied as parameter. * - * @note This function is asynchronous, therefore, completion is reported with a callback - * through the registered event handler. + * @param[out] p_desc The descriptor of the record with the given record ID. + * @param[in] record_id The record ID for which a descriptor should be returned. + * + * @retval FDS_SUCCESS If a descriptor was returned. + * @retval FDS_ERR_NULL_ARG If @p p_desc is NULL. */ -ret_code_t fds_gc(void); +ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc, + uint32_t record_id); -/**@brief Function to compare two record descriptors. +/**@brief Function for obtaining a record ID from a record descriptor. + * + * This function can be used to extract a record ID from a descriptor. For example, you could use + * it in the callback function to compare the record ID of an event to the record IDs of the + * records for which you have a descriptor. + * + * @warning + * This function does not check whether the record descriptor is valid. If the descriptor is not + * initialized or has been tampered with, the resulting record ID might be invalid. * - * @param[in] p_desc_one First descriptor. - * @param[in] p_desc_two Second descriptor. + * @param[in] p_desc The descriptor from which the record ID should be extracted. + * @param[out] p_record_id The record ID that is contained in the given descriptor. * - * @retval true If the descriptors identify the same record. - * @retval false Otherwise. + * @retval FDS_SUCCESS If a record ID was returned. + * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_record_id is NULL. */ -bool fds_descriptor_match(fds_record_desc_t const * const p_desc_one, - fds_record_desc_t const * const p_desc_two); +ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc, + uint32_t * const p_record_id); -/**@brief Function to obtain a descriptor from a record ID. - * - * @details This function can be used to reconstruct a descriptor from a record ID, such as the - * one passed to the callback function. +/**@brief Function for retrieving file system statistics. * - * @warning This function does not check if a record with the given record ID exists or not. If a - * non-existing record ID is supplied, the resulting descriptor will cause other functions - * to fail when used as parameter. + * This function retrieves file system statistics, such as the number of open records, the space + * that can be reclaimed by garbage collection, and others. * - * @param[out] p_desc The descriptor of the record with given record ID. - * @param[in] record_id The record ID for which to provide a descriptor. + * @param[out] p_stat File system statistics. * - * @retval NRF_SUCCESS Success. - * @retval NRF_ERROR_NULL Error. p_desc is NULL. + * @retval FDS_SUCCESS If the statistics were returned successfully. + * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FDS_ERR_NULL_ARG If @p p_stat is NULL. */ -ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc, - fds_record_id_t record_id); +ret_code_t fds_stat(fds_stat_t * const p_stat); + + +#if defined(FDS_CRC_ENABLED) -/**@brief Function to obtain a record ID from a record descriptor. +/**@brief Function for enabling and disabling CRC verification for write operations. * - * @details This function can be used to extract a record ID from a descriptor. It may be used - * in the callback function to determine which record the callback is associated to, if - * you have its descriptor. + * CRC verification ensures that data that is queued for writing does not change before the write + * actually happens. Use this function to enable or disable CRC verification. If verification is + * enabled, the error @ref FDS_ERR_CRC_CHECK_FAILED is returned in the event for + * @ref fds_record_write, @ref fds_record_write_reserved, or @ref fds_record_update if + * verification fails. * - * @warning This function does not check the record descriptor sanity. If the descriptor is - * uninitialized, or has been tampered with, the resulting record ID may be invalid. + * @note + * CRC verification is enabled or disabled globally, thus for all users of the FDS module. * - * @param[in] p_desc The descriptor from which to extract the record ID. - * @param[out] p_record_id The record ID contained in the given descriptor. + * @param[in] enabled 1 to enable CRC verification. 0 to disable CRC verification. * - * @retval NRF_SUCCESS Success. - * @retval NRF_ERROR_NULL Error. Either p_desc is NULL or p_record_id is NULL. + * @retval FDS_SUCCESS If CRC verification was enabled or disabled successfully. */ -ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc, - fds_record_id_t * const p_record_id); +ret_code_t fds_verify_crc_on_writes(bool enabled); + +#endif /** @} */ - + + +#ifdef __cplusplus +} +#endif + #endif // FDS_H__ diff --git a/components/libraries/fds/fds_config.h b/components/libraries/fds/fds_config.h deleted file mode 100644 index d038948..0000000 --- a/components/libraries/fds/fds_config.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 FDS_CONFIG_H__ -#define FDS_CONFIG_H__ - - /** - * @file fds_config.h - * - * @addtogroup flash_data_storage - * @{ - */ - -/**@brief Configures the size of the internal queue. */ -#define FDS_CMD_QUEUE_SIZE (8) -/**@brief Determines how many @ref fds_record_chunk_t structures can be buffered at any time. */ -#define FDS_CHUNK_QUEUE_SIZE (8) - -/**@brief Configures the number of physical flash pages to use. Out of the total, one is reserved - * for garbage collection, hence, two pages is the minimum: one for the application data - * and one for the system. */ -#define FDS_MAX_PAGES (2) -/**@brief Configures the maximum number of callbacks which can be registred. */ -#define FDS_MAX_USERS (10) - -/** Page tag definitions. */ -#define FDS_PAGE_TAG_WORD_0_SWAP (0xA5A5A5A5) -#define FDS_PAGE_TAG_WORD_0_VALID (0xA4A4A4A4) -#define FDS_PAGE_TAG_WORD_1 (0xAABBCCDD) -#define FDS_PAGE_TAG_WORD_2 (0xAABB01DD) /**< Includes version. */ -#define FDS_PAGE_TAG_WORD_3 (0x1CEB00DA) -#define FDS_PAGE_TAG_WORD_3_GC (0x1CEB00D8) - -/** @} */ - -#endif // FDS_CONFIG_H__ diff --git a/components/libraries/fds/fds_internal_defs.h b/components/libraries/fds/fds_internal_defs.h new file mode 100644 index 0000000..efa1613 --- /dev/null +++ b/components/libraries/fds/fds_internal_defs.h @@ -0,0 +1,345 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 FDS_INTERNAL_DEFS_H__ +#define FDS_INTERNAL_DEFS_H__ +#include "sdk_config.h" +#include +#include + +#if defined (FDS_THREADS) + #include "nrf_soc.h" + #include "app_util_platform.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define FDS_PAGE_TAG_SIZE (2) // Page tag size, in 4-byte words. +#define FDS_PAGE_TAG_WORD_0 (0) // Offset of the first word in the page tag from the page address. +#define FDS_PAGE_TAG_WORD_1 (1) // Offset of the second word in the page tag from the page address. + +// Page tag constants +#define FDS_PAGE_TAG_MAGIC (0xDEADC0DE) +#define FDS_PAGE_TAG_SWAP (0xF11E01FF) +#define FDS_PAGE_TAG_DATA (0xF11E01FE) + +#define FDS_ERASED_WORD (0xFFFFFFFF) + +#define FDS_OFFSET_TL (0) // Offset of TL from the record base address, in 4-byte words. +#define FDS_OFFSET_IC (1) // Offset of IC from the record base address, in 4-byte words. +#define FDS_OFFSET_ID (2) // Offset of ID from the record base address, in 4-byte words. +#define FDS_OFFSET_DATA (3) // Offset of the data (chunks) from the record base address, in 4-byte words. + +#define FDS_HEADER_SIZE_TL (1) // Size of the TL part of the header, in 4-byte words. +#define FDS_HEADER_SIZE_IC (1) // Size of the IC part of the header, in 4-byte words. +#define FDS_HEADER_SIZE_ID (1) // Size of the record ID in the header, in 4-byte words. +#define FDS_HEADER_SIZE (3) // Size of the whole header, in 4-byte words. + +#define FDS_OP_EXECUTING (FS_SUCCESS) +#define FDS_OP_COMPLETED (0x1D1D) + +// The size of a physical page, in 4-byte words. +#if defined(NRF51) + #define FDS_PHY_PAGE_SIZE (256) + #elif (defined(NRF52) || defined(NRF52840_XXAA)) + #define FDS_PHY_PAGE_SIZE (1024) +#endif + +// The number of physical pages to be used. This value is configured indirectly. +#define FDS_PHY_PAGES ((FDS_VIRTUAL_PAGES * FDS_VIRTUAL_PAGE_SIZE) / FDS_PHY_PAGE_SIZE) + +// The size of a virtual page, in number of physical pages. +#define FDS_PHY_PAGES_IN_VPAGE (FDS_VIRTUAL_PAGE_SIZE / FDS_PHY_PAGE_SIZE) + +// The number of pages available to store data; which is the total minus one (the swap). +#define FDS_MAX_PAGES (FDS_VIRTUAL_PAGES - 1) + + // Just a shorter name for the size, in words, of a virtual page. +#define FDS_PAGE_SIZE (FDS_VIRTUAL_PAGE_SIZE) + + +#if (FDS_VIRTUAL_PAGE_SIZE % FDS_PHY_PAGE_SIZE != 0) + #error "FDS_VIRTUAL_PAGE_SIZE must be a multiple of the size of a physical page." +#endif + +#if (FDS_VIRTUAL_PAGES < 2) + #error "FDS requires at least two virtual pages." +#endif + + +// FDS internal status flags. +typedef enum +{ + FDS_FLAG_INITIALIZING = (1 << 0), // The module is initializing. + FDS_FLAG_INITIALIZED = (1 << 1), // The module is initialized. + FDS_FLAG_PROCESSING = (1 << 2), // The queue is being processed. + FDS_FLAG_VERIFY_CRC = (1 << 3), // Verify CRC upon writing a record. +} fds_flags_t; + + +// Page types. +typedef enum +{ + FDS_PAGE_DATA, // Page is ready for storage. + FDS_PAGE_SWAP, // Page is reserved for garbage collection. + FDS_PAGE_ERASED, // Page is erased. + FDS_PAGE_UNDEFINED, // Undefined page type. +} fds_page_type_t; + + +typedef struct +{ + fds_page_type_t page_type; // The page type. + uint32_t const * p_addr; // The address of the page. + uint16_t write_offset; // The page write offset, in 4-byte words. + uint16_t words_reserved; // The amount of words reserved by fds_write_reserve(). + uint16_t records_open; // The number of records opened using fds_open(). + bool can_gc; // Indicates that there are some records that have been deleted. +} fds_page_t; + + +typedef struct +{ + uint32_t const * p_addr; + uint16_t write_offset; +} fds_swap_page_t; + + +// FDS op-codes. +typedef enum +{ + FDS_OP_NONE, + FDS_OP_INIT, // Initialize the module. + FDS_OP_WRITE, // Write a record to flash. + FDS_OP_UPDATE, // Update a record. + FDS_OP_DEL_RECORD, // Delete a record. + FDS_OP_DEL_FILE, // Delete a file. + FDS_OP_GC // Run garbage collection. +} fds_op_code_t; + + +typedef enum +{ + FDS_OP_INIT_TAG_SWAP, + FDS_OP_INIT_TAG_DATA, + FDS_OP_INIT_ERASE_SWAP, + FDS_OP_INIT_PROMOTE_SWAP, +} fds_init_step_t; + + +typedef enum +{ + FDS_OP_WRITE_HEADER_BEGIN, // Write the record key and length. + FDS_OP_WRITE_HEADER_FINALIZE, // Write the file ID and CRC. + FDS_OP_WRITE_RECORD_ID, // Write the record ID. + FDS_OP_WRITE_CHUNKS, // Write the record data. + FDS_OP_WRITE_FIND_RECORD, + FDS_OP_WRITE_FLAG_DIRTY, // Flag a record as dirty (as part of an update operation). + FDS_OP_WRITE_DONE, +} fds_write_step_t; + + +typedef enum +{ + FDS_OP_DEL_RECORD_FLAG_DIRTY, // Flag a record as dirty. + FDS_OP_DEL_FILE_FLAG_DIRTY, // Flag multiple records as dirty. + FDS_OP_DEL_DONE, +} fds_delete_step_t; + + +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + // anonymous unions are enabled by default +#endif + +typedef struct +{ + fds_op_code_t op_code; // The opcode for the operation. + union + { + struct + { + fds_init_step_t step; // The current step the operation is at. + } init; + struct + { + fds_header_t header; + fds_write_step_t step; // The current step the operation is at. + uint16_t page; // The page the flash space for this command was reserved. + uint16_t chunk_offset; // Offset used for writing record chunks, in 4-byte words. + uint8_t chunk_count; // Number of chunks to be written. + uint32_t record_to_delete; // The record to delete in case this is an update. + } write; + struct + { + fds_delete_step_t step; + uint16_t file_id; + uint16_t record_key; + uint32_t record_to_delete; + } del; + }; +} fds_op_t; + +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + // leave anonymous unions enabled +#elif defined(__GNUC__) + // anonymous unions are enabled by default +#endif + + +typedef struct +{ + fds_op_t op[FDS_OP_QUEUE_SIZE]; // Queued flash operations. + uint32_t rp; // The index of the command being executed. + uint32_t count; // Number of elements in the queue. +} fds_op_queue_t; + + +typedef struct +{ + fds_record_chunk_t chunk[FDS_CHUNK_QUEUE_SIZE]; + uint32_t rp; + uint32_t count; +} fds_chunk_queue_t; + + +enum +{ + PAGE_ERASED = 0x1, // One or more erased pages found. + PAGE_DATA = 0x2, // One or more data pages found. + PAGE_SWAP_CLEAN = 0x4, // A clean (empty) swap page was found. + PAGE_SWAP_DIRTY = 0x8, // A dirty (non-empty) swap page was found. +}; + + +typedef enum +{ + // No erased pages or FDS pages found. + // This is a fatal error. + NO_PAGES, + + // The filesystem can not be garbage collected. + // This is a fatal error. + NO_SWAP = (PAGE_DATA), + + // Perform a fresh installation. + FRESH_INSTALL = (PAGE_ERASED), + + // Tag an erased page as swap. + TAG_SWAP = (PAGE_ERASED | PAGE_DATA), + + // Tag all erased pages as data. + TAG_DATA = (PAGE_ERASED | PAGE_SWAP_CLEAN), + + // Tag all remaining erased pages as data. + TAG_DATA_INST = (PAGE_ERASED | PAGE_DATA | PAGE_SWAP_CLEAN), + + // The swap is dirty, likely because the device powered off during GC. + // Because there is also an erased page, assume that that page has been garbage collected. + // Hence, tag the swap as data (promote), an erased page as swap and remaining pages as data. + PROMOTE_SWAP = (PAGE_ERASED | PAGE_SWAP_DIRTY), + + // Tag the swap as data (promote), an erased page as swap and remaining pages as data. + PROMOTE_SWAP_INST = (PAGE_ERASED | PAGE_DATA | PAGE_SWAP_DIRTY), + + // The swap is dirty (written) and there are no erased pages. It is likely that the device + // powered off during GC. It is safe to discard (erase) the swap, since data that was + // swapped out still lies in one of the valid pages. + DISCARD_SWAP = (PAGE_DATA | PAGE_SWAP_DIRTY), + + // Do nothing. + ALREADY_INSTALLED = (PAGE_DATA | PAGE_SWAP_CLEAN), + +} fds_init_opts_t; + + +typedef enum +{ + GC_BEGIN, // Begin GC. + GC_NEXT_PAGE, // GC a page. + GC_FIND_NEXT_RECORD, // Find a valid record to copy. + GC_COPY_RECORD, // Copy a valid record to swap. + GC_ERASE_PAGE, // Erase the page being garbage collected. + GC_DISCARD_SWAP, // Erase (discard) the swap page. + GC_PROMOTE_SWAP, // Tag the swap as valid. + GC_TAG_NEW_SWAP // Tag a freshly erased (GCed) page as swap. +} fds_gc_state_t; + + +// Holds garbage collection status and related data. +typedef struct +{ + fds_gc_state_t state; // The current GC step. + uint16_t cur_page; // The current page being garbage collected. + uint32_t const * p_record_src; // The current record being copied to swap. + uint16_t run_count; // Total number of times GC was run. + bool do_gc_page[FDS_MAX_PAGES]; // Controls which pages to garbage collect. + bool resume; // Whether or not GC should be resumed. +} fds_gc_data_t; + + +// Macros to enable and disable application interrupts. +#if defined (FDS_THREADS) + + #define CRITICAL_SECTION_ENTER() CRITICAL_REGION_ENTER() + #define CRITICAL_SECTION_EXIT() CRITICAL_REGION_EXIT() + +#else + + #define CRITICAL_SECTION_ENTER() + #define CRITICAL_SECTION_EXIT() + +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif // FDS_INTERNAL_DEFS_H__ diff --git a/components/libraries/fds/fds_types_internal.h b/components/libraries/fds/fds_types_internal.h deleted file mode 100644 index 50287dd..0000000 --- a/components/libraries/fds/fds_types_internal.h +++ /dev/null @@ -1,158 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 FDS_TYPES_INTERNAL__ -#define FDS_TYPES_INTERNAL__ - -#include "fds.h" -#include -#include -#include "nrf_soc.h" - - -#define COMMAND_EXECUTING (NRF_SUCCESS) -#define COMMAND_COMPLETED (0x1234) -//#define COMMAND_FAILED (0x1236) - -#define FDS_MAGIC_HWORD (0xF11E) -#define FDS_MAGIC_WORD (0x15ABE11A) -#define FDS_ERASED_WORD (0xFFFFFFFF) - -#define FDS_PAGE_TAG_SIZE (4) /**< Page tag size, in 4 byte words. */ - -#define FDS_VPAGE_ID_UNKNOWN (0xFFFF) - -#define FDS_WRITE_OFFSET_TL (0) /**< Offset of TL from the record base address, in 4 byte words. */ -#define FDS_WRITE_OFFSET_IC (1) /**< Offset of IC from the record base address, in 4 byte words. */ -#define FDS_WRITE_OFFSET_ID (2) /**< Offset of ID from the record base address, in 4 byte words. */ -#define FDS_WRITE_OFFSET_DATA (3) /**< Offset of the data (chunks) from the record base address, in 4 byte words. */ - -#define FDS_HEADER_SIZE_TL (1) /**< Size of the TL part of the header, in 4 byte words. */ -#define FDS_HEADER_SIZE_ID (1) /**< Size of the IC part of the header, in 4 byte words. */ -#define FDS_HEADER_SIZE_IC (1) /**< Size of the IC part of the header, in 4 byte words. */ -#define FDS_HEADER_SIZE (3) /**< Size of the whole header, in 4 byte words. */ - -#define FDS_CMD_QUEUE_SIZE_INIT (1) -#define FDS_CMD_QUEUE_SIZE_WRITE (1) -#define FDS_CMD_QUEUE_SIZE_CLEAR (1) -#define FDS_CMD_QUEUE_SIZE_UPDATE (2) -#define FDS_CMD_QUEUE_SIZE_GC (1) - - -static uint8_t m_nested_critical; - -/** Macros to enable and disable application interrupts. */ -#define CRITICAL_SECTION_ENTER() //sd_nvic_critical_region_enter(&m_nested_critical) -#define CRITICAL_SECTION_EXIT() //sd_nvic_critical_region_exit ( m_nested_critical) - -/**@brief Page types. */ -typedef enum -{ - FDS_PAGE_UNDEFINED, /**< Undefined page type. */ - FDS_PAGE_ERASED, /**< Page is erased. */ - FDS_PAGE_VALID, /**< Page is ready for storage. */ - FDS_PAGE_SWAP, /**< Page is reserved for GC. */ - FDS_PAGE_GC /**< Page is being garbage collected. */ -} fds_page_type_t; - - -typedef enum -{ - FDS_OP_NONE = 0x00, /**< No operation. */ - FDS_OP_WRITE_TL, /**< Write the type and length. */ - FDS_OP_WRITE_ID, /**< Write the record ID. */ - FDS_OP_WRITE_CHUNK, /**< Write the record value. */ - FDS_OP_WRITE_IC, /**< Write the instance and checksum. */ - FDS_OP_CLEAR_TL, - FDS_OP_CLEAR_INSTANCE, - FDS_OP_DONE, -} fds_opcode_t; - - -typedef enum -{ - FDS_FLAG_INITIALIZING = (1 << 0), /**< TODO: Not really needed atm? */ - FDS_FLAG_INITIALIZED = (1 << 1), /**< Flag indicating that flash data storage has been initialized. */ - FDS_FLAG_PROCESSING = (1 << 2), /**< Flag indicating that queue is being processed. */ - FDS_FLAG_CAN_GC = (1 << 3), /**< Flag indicating that fds can regain data by performing garbage collection. */ -} fds_flags_t; - - -typedef struct -{ - uint32_t const * start_addr; - uint16_t vpage_id; /**< The page logical ID. */ - uint16_t volatile write_offset; /**< The page write offset, in 4 bytes words. */ - uint16_t volatile words_reserved; /**< The amount of words reserved by fds_write_reserve() on this page. */ - uint16_t volatile records_open; - fds_page_type_t page_type : 4; /**< The page type. */ -} fds_page_t; - - -typedef struct -{ - fds_cmd_id_t id : 4; /**< The ID of the command. */ - fds_opcode_t op_code : 4; - uint8_t num_chunks; /**< Number of operations this command has left in the operation queue. */ - uint16_t chunk_offset; /**< Offset used for writing the record value(s), in 4 byte words. */ - uint16_t vpage_id; /**< The virtual page ID where we reserved the flash space for this command. */ - fds_record_header_t record_header; -} fds_cmd_t; - - -/**@brief Defines command queue, an element is free if the op_code field is not invalid. - * - * @details Defines commands enqueued for flash access. At any point in time, this queue has one or - * more flash access operations pending if the count field is not zero. When the queue is - * not empty, the rp (read pointer) field points to the flash access command in progress - * or, if none is in progress, the command to be requested next. The queue implements a - * simple first in first out algorithm. Data addresses are assumed to be resident. - */ -typedef struct -{ - fds_cmd_t cmd[FDS_CMD_QUEUE_SIZE]; /**< Array to maintain flash access operation details. */ - uint8_t volatile rp; /**< The index of the command being executed. */ - uint8_t volatile count; /**< Number of elements in the queue. */ -} fds_cmd_queue_t; - - -typedef struct -{ - fds_record_chunk_t chunk[FDS_CHUNK_QUEUE_SIZE]; - uint8_t volatile rp; - uint8_t volatile count; -} fds_chunk_queue_t; - - -typedef enum -{ - NONE, - BEGIN, - RESUME, - GC_PAGE, - COPY_RECORD, - READY_SWAP, - NEW_SWAP, - INIT_SWAP -} fds_gc_state_t; - - -typedef struct -{ - uint16_t cur_page; - uint16_t swap_page; - uint32_t const * p_scan_addr; - fds_gc_state_t state; - bool do_gc_page[FDS_MAX_PAGES]; -} fds_gc_data_t; - -#endif // FDS_TYPES_INTERNAL__ diff --git a/components/libraries/fifo/app_fifo.c b/components/libraries/fifo/app_fifo.c index 44b7157..26c49bc 100644 --- a/components/libraries/fifo/app_fifo.c +++ b/components/libraries/fifo/app_fifo.c @@ -1,37 +1,54 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_fifo.h" -#include "nrf_error.h" -#include "app_util.h" - /** - * @brief Verify NULL parameters are not passed to an API by application. + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -#define NULL_PARAM_CHECK(PARAM) \ - if ((PARAM) == NULL) \ - { \ - return (NRF_ERROR_NULL); \ - } - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_FIFO) +#include "app_fifo.h" static __INLINE uint32_t fifo_length(app_fifo_t * p_fifo) { - uint32_t tmp = p_fifo->read_pos; - return p_fifo->write_pos - tmp; + uint32_t tmp = p_fifo->read_pos; + return p_fifo->write_pos - tmp; } -#define FIFO_LENGTH fifo_length(p_fifo) /**< Macro for calculating the FIFO length. */ +#define FIFO_LENGTH() fifo_length(p_fifo) /**< Macro for calculating the FIFO length. */ /**@brief Put one byte to the FIFO. */ @@ -42,11 +59,18 @@ static __INLINE void fifo_put(app_fifo_t * p_fifo, uint8_t byte) } -/**@brief Get one byte to the FIFO. */ +/**@brief Look at one byte in the FIFO. */ +static __INLINE void fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte) +{ + *p_byte = p_fifo->p_buf[(p_fifo->read_pos + index) & p_fifo->buf_size_mask]; +} + + +/**@brief Get one byte from the FIFO. */ static __INLINE void fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte) { - *p_byte = p_fifo->p_buf[p_fifo->read_pos & p_fifo->buf_size_mask]; - p_fifo->read_pos++; + fifo_peek(p_fifo, 0, p_byte); + p_fifo->read_pos++; } @@ -75,7 +99,7 @@ uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size) uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte) { - if (FIFO_LENGTH <= p_fifo->buf_size_mask) + if (FIFO_LENGTH() <= p_fifo->buf_size_mask) { fifo_put(p_fifo, byte); return NRF_SUCCESS; @@ -87,7 +111,7 @@ uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte) uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte) { - if (FIFO_LENGTH != 0) + if (FIFO_LENGTH() != 0) { fifo_get(p_fifo, p_byte); return NRF_SUCCESS; @@ -98,6 +122,18 @@ uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte) } +uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte) +{ + if (FIFO_LENGTH() > index) + { + fifo_peek(p_fifo, index, p_byte); + return NRF_SUCCESS; + } + + return NRF_ERROR_NOT_FOUND; +} + + uint32_t app_fifo_flush(app_fifo_t * p_fifo) { p_fifo->read_pos = p_fifo->write_pos; @@ -107,45 +143,34 @@ uint32_t app_fifo_flush(app_fifo_t * p_fifo) uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size) { - NULL_PARAM_CHECK(p_fifo); - NULL_PARAM_CHECK(p_size); - + VERIFY_PARAM_NOT_NULL(p_fifo); + VERIFY_PARAM_NOT_NULL(p_size); + const uint32_t byte_count = fifo_length(p_fifo); const uint32_t requested_len = (*p_size); uint32_t index = 0; - uint32_t read_size = 0; - + uint32_t read_size = MIN(requested_len, byte_count); + (*p_size) = byte_count; - + // Check if the FIFO is empty. if (byte_count == 0) { - return NRF_ERROR_NOT_FOUND; + return NRF_ERROR_NOT_FOUND; } - + // Check if application has requested only the size. if (p_byte_array == NULL) { - (*p_size) = byte_count; return NRF_SUCCESS; - } - - // Check is available bytes in FIFO less than requested. - if (requested_len < byte_count) - { - read_size = requested_len; - } - else - { - read_size = byte_count; } - + // Fetch bytes from the FIFO. - do + while (index < read_size) { fifo_get(p_fifo, &p_byte_array[index++]); - } while (index < read_size); - + } + (*p_size) = read_size; return NRF_SUCCESS; @@ -154,46 +179,36 @@ uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size) { - NULL_PARAM_CHECK(p_fifo); - NULL_PARAM_CHECK(p_size); - + VERIFY_PARAM_NOT_NULL(p_fifo); + VERIFY_PARAM_NOT_NULL(p_size); + const uint32_t available_count = p_fifo->buf_size_mask - fifo_length(p_fifo) + 1; const uint32_t requested_len = (*p_size); uint32_t index = 0; - uint32_t write_size = 0; - + uint32_t write_size = MIN(requested_len, available_count); + (*p_size) = available_count; - + // Check if the FIFO is FULL. if (available_count == 0) { - return NRF_ERROR_NO_MEM; + return NRF_ERROR_NO_MEM; } - + // Check if application has requested only the size. if (p_byte_array == NULL) { - (*p_size) = available_count; return NRF_SUCCESS; - } - - // Check is available bytes in FIFO less than requested. - if (requested_len < available_count) - { - write_size = requested_len; } - else - { - write_size = available_count; - } - + //Fetch bytes from the FIFO. - do + while (index < write_size) { fifo_put(p_fifo, p_byte_array[index++]); - } while (index < write_size); - + } + (*p_size) = write_size; return NRF_SUCCESS; } +#endif //NRF_MODULE_ENABLED(APP_FIFO) diff --git a/components/libraries/fifo/app_fifo.h b/components/libraries/fifo/app_fifo.h index ff9315b..941d4c2 100644 --- a/components/libraries/fifo/app_fifo.h +++ b/components/libraries/fifo/app_fifo.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -25,7 +53,11 @@ #include #include -/**@brief A FIFO instance structure. +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A FIFO instance structure. * @details Keeps track of which bytes to read and write next. * Also, it keeps the information about which memory is allocated for the buffer * and its size. This structure must be initialized by app_fifo_init() before use. @@ -70,6 +102,18 @@ uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte); */ uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte); +/**@brief Function for looking at an element in the FIFO, without consuming it. + * + * @param[in] p_fifo Pointer to the FIFO. + * @param[in] index Which element to look at. The lower the index, the earlier it was put. + * @param[out] p_byte Byte fetched from the FIFO. + * + * @retval NRF_SUCCESS If an element was returned. + * @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue, or the index was + * too large. + */ +uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte); + /**@brief Function for flushing the FIFO. * * @param[in] p_fifo Pointer to the FIFO. @@ -78,7 +122,7 @@ uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte); */ uint32_t app_fifo_flush(app_fifo_t * p_fifo); -/**@brief Function for reading bytes from the FIFO. +/**@brief Function for reading bytes from the FIFO. * * This function can also be used to get the number of bytes in the FIFO. * @@ -89,14 +133,14 @@ uint32_t app_fifo_flush(app_fifo_t * p_fifo); * @param[inout] p_size Address to memory indicating the maximum number of bytes to be read. * The provided memory is overwritten with the actual number of bytes * read if the procedure was successful. This field must not be NULL. - * If p_byte_array is set to NULL by the application, this parameter + * If p_byte_array is set to NULL by the application, this parameter * returns the number of bytes in the FIFO. * * @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes read might * be less than the requested maximum, depending on how many elements exist * in the FIFO. Even if less bytes are returned, the procedure is considered * successful. - * @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not + * @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not * be NULL. * @retval NRF_ERROR_NOT_FOUND If the FIFO is empty. */ @@ -108,7 +152,7 @@ uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p * * @param[in] p_fifo Pointer to the FIFO. Must not be NULL. * @param[in] p_byte_array Memory pointer containing the bytes to be written to the FIFO. - * Can be NULL. If NULL, this function returns the number of bytes + * Can be NULL. If NULL, this function returns the number of bytes * that can be written to the FIFO. * @param[inout] p_size Address to memory indicating the maximum number of bytes to be written. * The provided memory is overwritten with the number of bytes that were actually @@ -118,8 +162,8 @@ uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p * * @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes written might * be less than the requested maximum, depending on how much room there is in - * the FIFO. Even if less bytes are written, the procedure is considered - * successful. If the write was partial, the application should use + * the FIFO. Even if less bytes are written, the procedure is considered + * successful. If the write was partial, the application should use * subsequent calls to attempt writing the data again. * @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not * be NULL. @@ -128,6 +172,11 @@ uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p */ uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size); + +#ifdef __cplusplus +} +#endif + #endif // APP_FIFO_H__ /** @} */ diff --git a/components/libraries/fstorage/fstorage.c b/components/libraries/fstorage/fstorage.c index 592cf37..63dc46c 100644 --- a/components/libraries/fstorage/fstorage.c +++ b/components/libraries/fstorage/fstorage.c @@ -1,549 +1,561 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(FSTORAGE) #include "fstorage.h" -#include +#include "fstorage_internal_defs.h" + +#include #include #include -#include "fstorage_config.h" #include "nrf_error.h" #include "nrf_soc.h" -#define FS_FLAG_INIT (1 << 0) /**< fstorage has been initialized. */ -#define FS_FLAG_PROCESSING (1 << 1) /**< fstorage is executing queued flash operations. */ -#define FS_FLAG_FLASH_REQ_PENDING (1 << 2) /**< fstorage is waiting for a flash operation initiated by another module to complete. */ - - -/**@brief Macro invocation that registers section fs_data. - * - * @details Required for compilation. - */ -NRF_SECTION_VARS_REGISTER_SECTION(fs_data); - - -/**@brief Macro invocation that declares symbols used to find the beginning and end of the section fs_data. - * - * @details Required for compilation. - */ -NRF_SECTION_VARS_REGISTER_SYMBOLS(fs_config_t, fs_data); - - -/**@defgroup Section vars helper macros. - * - * @details Macros used to manipulate registered section variables. - */ - /**@brief Get section variable with fstorage configuration by index. */ -#define FS_SECTION_VARS_GET(i) NRF_SECTION_VARS_GET(i, fs_config_t, fs_data) - /**@brief Get the number of registered section variables. */ -#define FS_SECTION_VARS_COUNT NRF_SECTION_VARS_COUNT(fs_config_t, fs_data) - /**@brief Get the start address of the registered section variables. */ -#define FS_SECTION_VARS_START_ADDR NRF_SECTION_VARS_START_ADDR(fs_data) - /**@brief Get the end address of the registered section variables. */ -#define FS_SECTION_VARS_END_ADDR NRF_SECTION_VARS_END_ADDR(fs_data) - -/** @} */ - +static uint8_t m_flags; // fstorage status flags. +static fs_op_queue_t m_queue; // Queue of requested operations. +static uint8_t m_retry_count; // Number of times the last flash operation was retried. -/**@brief The command queue element. - * - * @details Encapsulate details of a command requested to this module. - */ -typedef struct -{ - fs_config_t const * p_config; /**< The configuration of the user who requested the operation. */ - uint8_t op_code; /**< Operation code. */ - uint32_t const * p_src; /**< Pointer to the data to be written to flash. The data must be kept in memory until the operation has finished. */ - uint32_t const * p_addr; /**< Destination of the data in flash. */ - fs_length_t length_words; /**< Length of the operation */ - fs_length_t offset; /**< Offset of the operation if operation is done in chunks */ -} fs_cmd_t; - - -/**@brief Structure that defines the command queue - * - * @details This queue holds flash operations requested to the module. - * The data to be written must be kept in memory until the write operation is completed, - * i.e., a callback indicating completion is received by the application. - */ -typedef struct +// Sends events to the application. +static void send_event(fs_op_t const * const p_op, fs_ret_t result) { - uint8_t rp; /**< The current element being processed. */ - uint8_t count; /**< Number of elements in the queue. */ - fs_cmd_t cmd[FS_CMD_QUEUE_SIZE]; /**< Array to maintain flash access operation details. */ -} fs_cmd_queue_t; - - -static uint8_t m_flags; /**< FStorage status flags. */ -static fs_cmd_queue_t m_cmd_queue; /**< Flash operation request queue. */ -static uint16_t m_retry_count = 0; /**< Number of times a single flash operation was retried. */ + fs_evt_t evt; + memset(&evt, 0x00, sizeof(fs_evt_t)); + switch (p_op->op_code) + { + case FS_OP_STORE: + evt.id = FS_EVT_STORE; + evt.store.p_data = p_op->store.p_dest; + evt.store.length_words = p_op->store.length_words; + break; -// Function prototypes -static ret_code_t queue_process(void); -static ret_code_t queue_process_impl(void); -static void app_notify(uint32_t result, fs_cmd_t const * p_cmd); + case FS_OP_ERASE: + evt.id = FS_EVT_ERASE; + evt.erase.first_page = p_op->erase.page - p_op->erase.pages_erased; + evt.erase.last_page = p_op->erase.page; + break; + default: + // Should not happen. + break; + } + evt.p_context = p_op->p_context; -/**@brief Macro to check that the configuration is non-NULL and within -* valid section variable memory bounds. - * - * @param[in] config Configuration to check. - */ -#define FS_CHECK_CONFIG(config) \ - ((FS_SECTION_VARS_START_ADDR < config) && (config < FS_SECTION_VARS_END_ADDR)) + p_op->p_config->callback(&evt, result); +} -/**@brief Function to check that the configuration is non-NULL and within -* valid section variable memory bounds. - * - * @param[in] config Configuration to check. - */ +// Checks that a configuration is non-NULL and within section variable bounds. static bool check_config(fs_config_t const * const config) { - if (config == NULL) +#ifndef DFU_SUPPORT_SIGNING + if ((config != NULL) && + (FS_SECTION_VARS_START_ADDR <= (uint32_t)config) && + (FS_SECTION_VARS_END_ADDR > (uint32_t)config)) { - return false; + return true; } - if ((FS_SECTION_VARS_START_ADDR <= (uint32_t)config) && ((uint32_t)config < FS_SECTION_VARS_END_ADDR)) + return false; +#else + return true; +#endif +} + + +// Executes a store operation. +static uint32_t store_execute(fs_op_t const * const p_op) +{ + uint16_t chunk_len; + + if ((p_op->store.length_words - p_op->store.offset) < FS_MAX_WRITE_SIZE_WORDS) { - return true; + chunk_len = p_op->store.length_words - p_op->store.offset; } else { - return false; + chunk_len = FS_MAX_WRITE_SIZE_WORDS; } + + return sd_flash_write((uint32_t*)p_op->store.p_dest + p_op->store.offset, + (uint32_t*)p_op->store.p_src + p_op->store.offset, + chunk_len); } -/**@brief Function to initialize the queue. */ -static void queue_init(void) +// Executes an erase operation. +static uint32_t erase_execute(fs_op_t const * const p_op) { - memset(&m_cmd_queue, 0, sizeof(fs_cmd_queue_t)); + return sd_flash_page_erase(p_op->erase.page); } -/**@brief Function to reset a queue item to its default values. - * - * @param index Index of the queue element. - */ -static void cmd_reset(uint32_t index) +// Advances the queue, wrapping around if necessary. +// If no elements are left in the queue, clears the FS_FLAG_PROCESSING flag. +static void queue_advance(void) { - memset(&m_cmd_queue.cmd[index], 0, sizeof(fs_cmd_t)); + if (--m_queue.count == 0) + { + m_flags &= ~FS_FLAG_PROCESSING; + } + + if (++m_queue.rp == FS_QUEUE_SIZE) + { + m_queue.rp = 0; + } } -/**@brief Function to enqueue flash access command - * - * @param[in] config Registered configuration. - * @param[in] op_code Operation code. - * @param[in] address Destination of the data. - * @param[in] p_src Source of data or NULL if n/a. - * @param[in] length Length of the data, in 4 byte words. - * - * @retval NRF_SUCCESS Success. Command enqueued. - * @retval NRF_ERROR_NO_MEM Error. Queue is full. - * @retval Any error returned by the SoftDevice flash API. - */ -static ret_code_t cmd_enqueue(fs_config_t const * p_config, - uint8_t op_code, - uint32_t const * p_addr, - uint32_t const * p_src, - fs_length_t length_words) +// Processes the current element in the queue. If the queue is empty, does nothing. +static void queue_process(void) { - fs_cmd_t * p_cmd; - uint8_t write_pos; + uint32_t ret; + fs_op_t * const p_op = &m_queue.op[m_queue.rp]; - if (m_cmd_queue.count == FS_CMD_QUEUE_SIZE - 1) + if (m_queue.count > 0) { - return NRF_ERROR_NO_MEM; - } + switch (p_op->op_code) + { + case FS_OP_STORE: + ret = store_execute(p_op); + break; - write_pos = (m_cmd_queue.rp + m_cmd_queue.count) % FS_CMD_QUEUE_SIZE; + case FS_OP_ERASE: + ret = erase_execute(p_op); + break; - p_cmd = &m_cmd_queue.cmd[write_pos]; + default: + ret = FS_ERR_INTERNAL; + break; + } - p_cmd->p_config = p_config; - p_cmd->op_code = op_code; - p_cmd->p_src = p_src; - p_cmd->p_addr = p_addr; - p_cmd->length_words = length_words; + // There is a pending flash operation which was not initiated by this module. + // Stop processing the queue and wait for a system event. + if (ret == NRF_ERROR_BUSY) + { + m_flags &= ~FS_FLAG_PROCESSING; + m_flags |= FS_FLAG_FLASH_REQ_PENDING; + } + else if (ret != NRF_SUCCESS) + { + // An error has occurred. + send_event(p_op, FS_ERR_INTERNAL); + } + else + { + // Operation is executing. + } + } +} - m_cmd_queue.count++; - return queue_process(); +// Starts processing the queue if there are no pending flash operations, both inside and +// outside this module. Returns immediately otherwise. +static void queue_start(void) +{ + if (!(m_flags & FS_FLAG_PROCESSING) && + !(m_flags & FS_FLAG_FLASH_REQ_PENDING)) + { + m_flags |= FS_FLAG_PROCESSING; + queue_process(); + } } -/**@brief Function to consume queue item and notify the return value of the operation. - * - * @details This function will report the result and remove the command from the queue after - * notification. - */ -static void cmd_consume(uint32_t result, const fs_cmd_t * p_cmd) +// Flash operation success callback handler. Keeps track of the progress of an operation. +// If it has finished, advances the queue and notifies the application. +static void on_operation_success(fs_op_t * const p_op) { - // Consume the current item on the queue. - uint8_t rp = m_cmd_queue.rp; + m_retry_count = 0; - m_cmd_queue.count--; - if (m_cmd_queue.count == 0) + switch (p_op->op_code) { - // There are no elements left. Stop processing the queue. - m_flags &= ~FS_FLAG_PROCESSING; - } + case FS_OP_STORE: + { + uint16_t chunk_len; - if (++(m_cmd_queue.rp) == FS_CMD_QUEUE_SIZE) - { - m_cmd_queue.rp = 0; - } + if ((p_op->store.length_words - p_op->store.offset) < FS_MAX_WRITE_SIZE_WORDS) + { + chunk_len = p_op->store.length_words - p_op->store.offset; + } + else + { + chunk_len = FS_MAX_WRITE_SIZE_WORDS; + } - // Notify upon successful operation. - app_notify(result, p_cmd); + p_op->store.offset += chunk_len; - // Reset the queue element. - cmd_reset(rp); -} + if (p_op->store.offset == p_op->store.length_words) + { + // The operation has finished. + send_event(p_op, FS_SUCCESS); + queue_advance(); + } + } + break; + case FS_OP_ERASE: + { + p_op->erase.page++; + p_op->erase.pages_erased++; -/**@brief Function to store data to flash. - * - * @param[in] p_cmd The queue element associated with the operation. - * - * @retval NRF_SUCCESS Success. The request was sent to the SoftDevice. - * @retval Any error returned by the SoftDevice flash API. - */ -static __INLINE uint32_t store_execute(fs_cmd_t const * const p_cmd) -{ - // Write in chunks if write-size is larger than FS_MAX_WRITE_SIZE. - fs_length_t const length = ((p_cmd->length_words - p_cmd->offset) < FS_MAX_WRITE_SIZE_WORDS) ? - (p_cmd->length_words - p_cmd->offset) : FS_MAX_WRITE_SIZE_WORDS; + if (p_op->erase.pages_erased == p_op->erase.pages_to_erase) + { + send_event(p_op, FS_SUCCESS); + queue_advance(); + } + } + break; - return sd_flash_write((uint32_t*)p_cmd->p_addr + p_cmd->offset /* destination */, - (uint32_t*)p_cmd->p_src + p_cmd->offset /* source */, - length); + default: + // Should not happen. + break; + } } -/**@brief Function to erase a page. - * - * @param[in] p_cmd The queue element associated with the operation. - * - * @retval NRF_SUCCESS Success. The request was sent to the SoftDevice. - * @retval Any error returned by the SoftDevice flash API. - */ -static __INLINE uint32_t erase_execute(fs_cmd_t const * const p_cmd) +// Flash operation failure callback handler. If the maximum number of retries has +// been reached, notifies the application and advances the queue. +static void on_operation_failure(fs_op_t const * const p_op) { - // Erase the page. - return sd_flash_page_erase((uint32_t)(p_cmd->p_addr + p_cmd->offset) / FS_PAGE_SIZE); + if (++m_retry_count > FS_OP_MAX_RETRIES) + { + m_retry_count = 0; + + send_event(p_op, FS_ERR_OPERATION_TIMEOUT); + queue_advance(); + } } -/**@brief Function to process the current element in the queue and return the result. - * - * @retval NRF_SUCCESS Success. - * @retval NRF_ERROR_FORBIDDEN Error. Undefined command. - * @retval Any error returned by the SoftDevice flash API. - */ -static uint32_t queue_process_impl(void) +// Retrieves a pointer to the next free element in the queue. +// Additionally, increases the number of elements stored in the queue. +static bool queue_get_next_free(fs_op_t ** p_op) { - uint32_t ret; - - fs_cmd_t const * const p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; + uint32_t idx; - switch (p_cmd->op_code) + if (m_queue.count == FS_QUEUE_SIZE) { - case FS_OP_STORE: - ret = store_execute(p_cmd); - break; + return false; + } - case FS_OP_ERASE: - ret = erase_execute(p_cmd); - break; + idx = ((m_queue.rp + m_queue.count) < FS_QUEUE_SIZE) ? + (m_queue.rp + m_queue.count) : ((m_queue.rp + m_queue.count)-FS_QUEUE_SIZE); - case FS_OP_NONE: - ret = NRF_SUCCESS; - break; + m_queue.count++; - default: - ret = NRF_ERROR_FORBIDDEN; - break; - } + // Zero the element so that unassigned fields will be zero. + memset(&m_queue.op[idx], 0x00, sizeof(fs_op_t)); + + *p_op = &m_queue.op[idx]; - return ret; + return true; } -/**@brief Starts processing the queue if there are no pending flash operations - * for which we are awaiting a callback. - */ -static ret_code_t queue_process(void) +fs_ret_t fs_init(void) { - ret_code_t ret = NRF_SUCCESS; + uint32_t const total_users = FS_SECTION_VARS_COUNT; + uint32_t configs_to_init = FS_SECTION_VARS_COUNT; + uint32_t const * p_current_end = FS_PAGE_END_ADDR; - /** If the queue is not being processed, and there are still - * some elements in it, then start processing. */ - if ( !(m_flags & FS_FLAG_PROCESSING) && - (m_cmd_queue.count > 0)) + if (m_flags & FS_FLAG_INITIALIZED) { - m_flags |= FS_FLAG_PROCESSING; + return FS_SUCCESS; + } - ret = queue_process_impl(); + // Each fstorage user has registered one configuration. + // The total number of users (and thus the total number of configurations) is + // kept in total_users. Some of these users might have specified their flash + // boundaries in their configurations. This function sets the flash boundaries + // for the remaining user configurations without further user interaction. - /** There is ongoing flash-operation which was not - * initiated by fstorage. */ - if (ret == NRF_ERROR_BUSY) - { - // Wait for a system callback. - m_flags |= FS_FLAG_FLASH_REQ_PENDING; + // First, determine how many user configurations this function has to initialize, + // out of the total. This number will be kept in configs_to_init. - // Stop processing the queue. - m_flags &= ~FS_FLAG_PROCESSING; + for (uint32_t i = 0; i < total_users; i++) + { + fs_config_t const * const p_config = FS_SECTION_VARS_GET(i); - ret = NRF_SUCCESS; - } - else if (ret != NRF_SUCCESS) + if ((p_config->p_start_addr != NULL) && + (p_config->p_end_addr != NULL)) { - // Another error has occurred. - app_notify(ret, &m_cmd_queue.cmd[m_cmd_queue.rp]); + configs_to_init--; } } - // If we are already processing the queue, return immediately. - return ret; -} - + // For each configuration to initialize, assign flash space based on the priority + // specified. Higher priority means a higher memory address. -/**@brief Flash operation success callback handler. - * - * @details This function updates read/write pointers. - * This function resets retry count. - */ -static __INLINE void on_operation_success(void) -{ - fs_cmd_t * const p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; + for (uint32_t i = 0; i < configs_to_init; i++) + { + fs_config_t * p_config_i = FS_SECTION_VARS_GET(i); + uint8_t max_priority = 0; + uint8_t max_index = i; - m_retry_count = 0; + for (uint32_t j = 0; j < total_users; j++) + { + fs_config_t const * const p_config_j = FS_SECTION_VARS_GET(j); - switch (p_cmd->op_code) - { - case FS_OP_STORE: - // Update the offset on successful write. - p_cmd->offset += FS_MAX_WRITE_SIZE_WORDS; - break; + #if 0 + if (p_config_j->priority == p_config_i->priority) + { + // Duplicated priorities are not allowed. + return FS_ERR_INVALID_CFG; + } + #endif - case FS_OP_ERASE: - // Update the offset to correspond to the page that has been erased. - p_cmd->offset += FS_PAGE_SIZE_WORDS; - break; - } + if ((p_config_j->p_start_addr != NULL) && + (p_config_j->p_end_addr != NULL)) + { + // When calculating the configuration with the next highest priority + // skip configurations which were already set during a previous iteration. + // This check needs to be here to prevent re-using the configurations + // with higher priorities which we used in previous iterations. + continue; + } - // If offset is equal to or larger than length, then the operation has finished. - if (p_cmd->offset >= p_cmd->length_words) - { - cmd_consume(NRF_SUCCESS, p_cmd); - } + if (p_config_j->priority > max_priority) + { + max_priority = p_config_j->priority; + max_index = j; + } + } - queue_process(); -} + p_config_i = FS_SECTION_VARS_GET(max_index); + p_config_i->p_end_addr = p_current_end; + p_config_i->p_start_addr = p_current_end - (p_config_i->num_pages * FS_PAGE_SIZE_WORDS); -/**@brief Flash operation failure callback handler. - * - * @details Function to keep track of retries and notify failures. - */ -static __INLINE void on_operation_failure(uint32_t sys_evt) -{ - const fs_cmd_t * p_cmd; - - if (++m_retry_count > FS_CMD_MAX_RETRIES) - { - p_cmd = &m_cmd_queue.cmd[m_cmd_queue.rp]; - cmd_consume(NRF_ERROR_TIMEOUT, p_cmd); + p_current_end = p_config_i->p_start_addr; } - queue_process(); + m_flags |= FS_FLAG_INITIALIZED; + + return FS_SUCCESS; } -/**@brief Function to notify users. - * - * @param[in] result Result of the flash operation. - * @param[in] p_cmd The command associated with the callback. - */ -static void app_notify(uint32_t result, fs_cmd_t const * const p_cmd) +fs_ret_t fs_fake_init(void) { - p_cmd->p_config->cb(p_cmd->op_code, result, p_cmd->p_addr, p_cmd->length_words); + m_flags |= FS_FLAG_INITIALIZED; + return FS_SUCCESS; } -ret_code_t fs_init(void) +fs_ret_t fs_store(fs_config_t const * const p_config, + uint32_t const * const p_dest, + uint32_t const * const p_src, + uint16_t const length_words, + void * p_context) { - uint16_t lowest_index = 0; - uint16_t lowest_order = 0xFFFF; - uint32_t * current_end = (uint32_t*)FS_PAGE_END_ADDR; - uint32_t num_left = FS_SECTION_VARS_COUNT; + fs_op_t * p_op; - queue_init(); + if (!(m_flags & FS_FLAG_INITIALIZED)) + { + return FS_ERR_NOT_INITIALIZED; + } - /** Assign pages to registered users, beginning with the ones with the lowest - * order, which will be assigned pages with the lowest memory address. */ - do + if (!check_config(p_config)) { - fs_config_t * p_config; - for (uint16_t i = 0; i < FS_SECTION_VARS_COUNT; i++) - { - p_config = FS_SECTION_VARS_GET(i); + return FS_ERR_INVALID_CFG; + } - // Skip the ones which have the end-address already set. - if (p_config->p_end_addr != NULL) - continue; + if ((p_src == NULL) || (p_dest == NULL)) + { + return FS_ERR_NULL_ARG; + } - if (p_config->page_order < lowest_order) - { - lowest_order = p_config->page_order; - lowest_index = i; - } - } + // Check that both pointers are word aligned. + if (((uint32_t)p_src & 0x03) || + ((uint32_t)p_dest & 0x03)) + { + return FS_ERR_UNALIGNED_ADDR; + } - p_config = FS_SECTION_VARS_GET(lowest_index); + // Check that the operation doesn't go outside the client's memory boundaries. + if ((p_config->p_start_addr > p_dest) || + (p_config->p_end_addr < (p_dest + length_words))) + { + return FS_ERR_INVALID_ADDR; + } - p_config->p_end_addr = current_end; - p_config->p_start_addr = p_config->p_end_addr - (p_config->num_pages * FS_PAGE_SIZE_WORDS); + if (length_words == 0) + { + return FS_ERR_INVALID_ARG; + } - current_end = p_config->p_start_addr; - lowest_order = 0xFFFF; + if (!queue_get_next_free(&p_op)) + { + return FS_ERR_QUEUE_FULL; + } - } while ( --num_left > 0 ); + // Initialize the operation. + p_op->p_context = p_context; + p_op->p_config = p_config; + p_op->op_code = FS_OP_STORE; + p_op->store.p_src = p_src; + p_op->store.p_dest = p_dest; + p_op->store.length_words = length_words; - m_flags |= FS_FLAG_INIT; + queue_start(); - return NRF_SUCCESS; + return FS_SUCCESS; } -ret_code_t fs_store(fs_config_t const * p_config, - uint32_t const * p_addr, - uint32_t const * const p_data, - fs_length_t length_words) +fs_ret_t fs_erase(fs_config_t const * const p_config, + uint32_t const * const p_page_addr, + uint16_t const num_pages, + void * p_context) { - if ((m_flags & FS_FLAG_INIT) == 0) + fs_op_t * p_op; + + if (!(m_flags & FS_FLAG_INITIALIZED)) { - return NRF_ERROR_INVALID_STATE; + return FS_ERR_NOT_INITIALIZED; } if (!check_config(p_config)) { - return NRF_ERROR_FORBIDDEN; + return FS_ERR_INVALID_CFG; } - if (!is_word_aligned(p_addr)) + if (p_page_addr == NULL) { - return NRF_ERROR_INVALID_ADDR; + return FS_ERR_NULL_ARG; } - // Check that the erase operation is on pages owned by this user (configuration). - if ((p_addr < p_config->p_start_addr) || ((p_addr + length_words) > p_config->p_end_addr)) + // Check that the page is aligned to a page boundary. + if (((uint32_t)p_page_addr & (FS_PAGE_SIZE-1)) != 0) { - return NRF_ERROR_INVALID_ADDR; + return FS_ERR_UNALIGNED_ADDR; } - return cmd_enqueue(p_config, FS_OP_STORE, p_addr, p_data, length_words); -} - - -ret_code_t fs_erase(fs_config_t const * p_config, - uint32_t * const p_addr, - fs_length_t const length_words) -{ - if ((m_flags & FS_FLAG_INIT) == 0) + // Check that the operation doesn't go outside the client's memory boundaries. + if ((p_page_addr < p_config->p_start_addr) || + (p_page_addr + (FS_PAGE_SIZE_WORDS * num_pages) > p_config->p_end_addr)) { - return NRF_ERROR_INVALID_STATE; + return FS_ERR_INVALID_ADDR; } - if (!check_config(p_config)) + if (num_pages == 0) { - return NRF_ERROR_FORBIDDEN; + return FS_ERR_INVALID_ARG; } - /** Check that the address is aligned on a page boundary and the length to erase - * is a multiple of the page size. */ - if (((uint32_t)p_addr & (FS_PAGE_SIZE - 1)) || - (length_words & (FS_PAGE_SIZE_WORDS - 1))) + if (!queue_get_next_free(&p_op)) { - return NRF_ERROR_INVALID_ADDR; + return FS_ERR_QUEUE_FULL; } - // Check that the erase operation is on pages owned by this user (configuration). - if ((p_addr < p_config->p_start_addr) || ((p_addr + length_words) > p_config->p_end_addr)) + // Initialize the operation. + p_op->p_context = p_context; + p_op->p_config = p_config; + p_op->op_code = FS_OP_ERASE; + p_op->erase.page = ((uint32_t)p_page_addr / FS_PAGE_SIZE); + p_op->erase.pages_to_erase = num_pages; + + queue_start(); + + return FS_SUCCESS; +} + + +fs_ret_t fs_queued_op_count_get(uint32_t * const p_op_count) +{ + if (p_op_count == NULL) { - return NRF_ERROR_INVALID_ADDR; + return FS_ERR_NULL_ARG; } - return cmd_enqueue(p_config, FS_OP_ERASE, p_addr, NULL, length_words); + *p_op_count = m_queue.count; + + return FS_SUCCESS; } -/**@brief Function to handle system events from the SoftDevice. - * - * @details This function should be dispatched system events if any of the modules used by - * the application rely on FStorage. Examples include @ref Peer Manager and - * @ref Flash Data Storage. - * - * @param[in] sys_evt System Event received. - */ void fs_sys_event_handler(uint32_t sys_evt) { + fs_op_t * const p_op = &m_queue.op[m_queue.rp]; + if (m_flags & FS_FLAG_PROCESSING) { - /** A flash operation was initiated by this module. - * Handle its result. */ + // A flash operation was initiated by this module. Handle the result. switch (sys_evt) { case NRF_EVT_FLASH_OPERATION_SUCCESS: - on_operation_success(); + on_operation_success(p_op); break; case NRF_EVT_FLASH_OPERATION_ERROR: - on_operation_failure(sys_evt); + on_operation_failure(p_op); break; } } else if ((m_flags & FS_FLAG_FLASH_REQ_PENDING)) { - /** A flash operation was initiated outside this module. - * We have now receveid a callback which indicates it has - * finished. Clear the FS_FLAG_FLASH_REQ_PENDING flag. */ - m_flags &= ~FS_FLAG_FLASH_REQ_PENDING; + // A flash operation was initiated outside this module. + // A callback which indicates that it has finished was received. + m_flags &= ~FS_FLAG_FLASH_REQ_PENDING; - // Resume processing the queue, if necessary. - queue_process(); + // If there are any elements left in the queue, set FS_FLAG_PROCESSING. + if (m_queue.count > 0) + { + m_flags |= FS_FLAG_PROCESSING; + } } -} + // Resume processing the queue, if necessary. + queue_process(); +} -// Just for testing out section vars (across many compilers). -void fs_debug_print() +bool fs_queue_is_full(void) { - printf("fs start address: 0x%08lx\r\n", (unsigned long)FS_SECTION_VARS_START_ADDR); - printf("fs end address: 0x%08lx\r\n", (unsigned long)FS_SECTION_VARS_END_ADDR); - printf("Num items: 0x%08lx\r\n", (unsigned long)FS_SECTION_VARS_COUNT); - printf("===== ITEMS %lu =====\r\n", (unsigned long)FS_SECTION_VARS_COUNT); + return (m_queue.count == FS_QUEUE_SIZE); +} - for(int i = 0; i < FS_SECTION_VARS_COUNT; i++) - { - fs_config_t* config = FS_SECTION_VARS_GET(i); - printf( "Address: 0x%08lx, CB: 0x%08lx\r\n", - (unsigned long)config, (unsigned long)config->cb ); - } - printf("\r\n"); +bool fs_queue_is_empty(void) +{ + return (m_queue.count == 0); } + +#endif //NRF_MODULE_ENABLED(FSTORAGE) diff --git a/components/libraries/fstorage/fstorage.h b/components/libraries/fstorage/fstorage.h index aad4b96..22c5f95 100644 --- a/components/libraries/fstorage/fstorage.h +++ b/components/libraries/fstorage/fstorage.h @@ -1,156 +1,298 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 FSTORAGE_H__ +#define FSTORAGE_H__ -#ifndef FS_H__ -#define FS_H__ - - /** @file - * - * @defgroup fstorage FStorage - * @{ +/** + * @defgroup fstorage fstorage * @ingroup app_common - * @brief Module which provides low level functionality to store data to flash. + * @{ * + * @brief Module which provides functionality to store data to flash and erase flash pages. */ - #include +#include #include "section_vars.h" -#include "fstorage_config.h" -#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif -typedef uint16_t fs_length_t; +/**@brief fstorage return values. */ +typedef enum +{ + FS_SUCCESS, + FS_ERR_NOT_INITIALIZED, //!< Error. The module is not initialized. + FS_ERR_INVALID_CFG, //!< Error. Invalid fstorage configuration. + FS_ERR_NULL_ARG, //!< Error. Argument is NULL. + FS_ERR_INVALID_ARG, //!< Error. Argument contains invalid data. + FS_ERR_INVALID_ADDR, //!< Error. Address out of bounds. + FS_ERR_UNALIGNED_ADDR, //!< Error. Unaligned address. + FS_ERR_QUEUE_FULL, //!< Error. Queue is full. + FS_ERR_OPERATION_TIMEOUT, //!< Error. The operation has timed out. + FS_ERR_INTERNAL, //!< Error. Internal error. + FS_ERR_FAILURE_SINCE_LAST //!< Error. Uncleared error since last call +} fs_ret_t; +/**@brief fstorage event IDs. */ typedef enum { - FS_OP_NONE = 0, - FS_OP_STORE = 1, - FS_OP_ERASE = 2 -} fs_oper_t; + FS_EVT_STORE, //!< Event for @ref fs_store. + FS_EVT_ERASE //!< Event for @ref fs_erase. +} fs_evt_id_t; -/**@brief Callback for flash operations. - * - * @param[in] op_code Flash access operation code. - * @param[in] result Result of the operation. - * @param[in] data Pointer to resulting data (or NULL if not in use). - * @param[in] length_words Length of data in words. - */ -typedef void (*fs_cb_t)(uint8_t op_code, - uint32_t result, - uint32_t const * p_data, - fs_length_t length_words); +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#endif + +/**@brief An fstorage event. */ +typedef struct +{ + fs_evt_id_t id; //!< The event ID. + void * p_context; //!< User-defined context passed to the interrupt handler. + union + { + struct + { + uint32_t const * p_data; //!< Pointer to the data stored in flash. + uint16_t length_words; //!< Length of the data, in 4-byte words. + } store; + struct + { + uint16_t first_page; //!< First page erased. + uint16_t last_page; //!< Last page erased. + } erase; + }; +} fs_evt_t; +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + /* leave anonymous unions enabled */ +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#endif -/**@brief Function prototype for a callback handler. - * - * @details This function is expected to be implemented by the module that - * registers for fstorage usage. Its usage is described - * in the function pointer type fs_cb_t. + +/**@brief fstorage event handler function prototype. * - * @param[in] op_code Flash operation code. - * @param[in] result Result of the flash operation. - * @param[in] p_data Pointer to the resulting data (or NULL if not in use). - * @param[in] length_words Length of data in words. + * @param[in] evt The event. + * @param[in] result The result of the operation. */ -static void fs_callback(uint8_t op_code, - uint32_t result, - uint32_t const * p_data, - fs_length_t length_words); +typedef void (*fs_cb_t)(fs_evt_t const * const evt, fs_ret_t result); -/**@brief Flash storage config variable. +/**@brief fstorage application-specific configuration. + * + * @details Specifies the callback to invoke when an operation completes, the number of flash pages + * requested by the application and the priority with which these are to be assigned, with + * respect to other applications. Additionally, the configuration specifies the boundaries + * of the flash space assigned to an application. The configuration must be provided as an + * argument when invoking @ref fs_store and @ref fs_erase. * - * @details The fstorage module will update the start_addr and end_address according to - * ordering rules and the number of pages requested by the fstorage module user. + * @note The fields @p p_start_addr and @p p_end_address are set by @ref fs_init, based on the + * value of the field @p priority. */ typedef struct { - const fs_cb_t cb; /**< Callback to run when flash operation has completed. */ - const uint8_t num_pages; /**< The number of pages to reserve for flash storage. */ - const uint8_t page_order; /**< The order used to allocate pages. */ - uint32_t * p_start_addr; /**< Pointer to the start address of the allocated flash storage. Set by running @ref fs_init. */ - uint32_t * p_end_addr; /**< Pointer to the end address of the allcoated flash storage. Set by running @ref fs_init. */ + /**@brief The beginning of the flash space assigned to the application which registered this + * configuration. This field is set by @ref fs_init. It can also be set manually. + */ + uint32_t const * p_start_addr; + + /**@brief The end of the flash space assigned to the application which registered this + * configuration. This field is set by @ref fs_init. It can also be set manually. + */ + uint32_t const * p_end_addr; + + fs_cb_t const callback; //!< Callback to run when a flash operation has completed. + uint8_t const num_pages; //!< The number of flash pages requested. + + /**@brief The priority with which fstorage should assign flash pages to this application, + * with respect to other applications. Applications with higher priority will be + * assigned flash pages with a higher memory address. The highest priority is + * reserved. Must be unique among configurations. + */ + uint8_t const priority; } fs_config_t; -/**@brief Macro for registering of flash storage configuration variable. +/**@brief Macro for registering an fstorage configuration variable. + * Applications which use fstorage must register with the module using this macro. + * Registering involves defining a variable which holds the configuration of fstorage + * specific to the application which invokes the macro. * - * @details This macro is expected to be invoked in the code unit that that require - * flash storage. Invoking this places the registered configuration variable - * in a section named "fs_data" that the fstorage module uses during initialization - * and regular operation. + * @details This macro places the configuration variable in a section named "fs_data" that + * fstorage uses during initialization and regular operation. + * + * @param[in] cfg_var A @e definition of a @ref fs_config_t variable. */ -#define FS_SECTION_VARS_ADD(type_def) NRF_SECTION_VARS_ADD(fs_data, type_def) +#define FS_REGISTER_CFG(cfg_var) NRF_SECTION_VARS_REGISTER_VAR(fs_data, cfg_var) -/**@brief Function to initialize FStorage. +/**@brief Function for initializing the module. + * + * @details This functions assigns pages in flash according to all registered configurations. * - * @details This function allocates flash data pages according to the - * number requested in the config variable. The data used to initialize. - * the fstorage is section placed variables in the data section "fs_data". + * @retval FS_SUCCESS If the module was successfully initialized. */ -ret_code_t fs_init(void); +fs_ret_t fs_init(void); + +fs_ret_t fs_fake_init(void); -/**@brief Function to store data in flash. + +/**@brief Function for storing data in flash. + * + * @details Copies @p length_words words from @p p_src to the location pointed by @p p_dest. + * If the length of the data exceeds @ref FS_MAX_WRITE_SIZE_WORDS, the data will be + * written down in several chunks, as necessary. Only one event will be sent to the + * application upon completion. Both the source and the destination of the data must be + * word aligned. This function is asynchronous, completion is reported via an event sent + * the the callback function specified in the supplied configuration. * * @warning The data to be written to flash has to be kept in memory until the operation has - * terminated, i.e., a callback is received. + * terminated, i.e., an event is received. + * + * @param[in] p_config fstorage configuration registered by the application. + * @param[in] p_dest The address in flash memory where to store the data. + * @param[in] p_src Pointer to the data to store in flash. + * @param[in] length_words Length of the data to store, in words. + * @param[in] p_context User-defined context passed to the interrupt handler. + * + * @retval FS_SUCCESS If the operation was queued successfully. + * @retval FS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FS_ERR_INVALID_CFG If @p p_config is NULL or contains invalid data. + * @retval FS_ERR_NULL_ARG If @p p_dest or @p p_src are NULL. + * @retval FS_ERR_INVALID_ARG If @p length_words is zero. + * @retval FS_ERR_INVALID_ADDR If @p p_dest or @p p_src are outside of the flash memory + * boundaries specified in @p p_config. + * @retval FS_ERR_UNALIGNED_ADDR If @p p_dest or @p p_src are not aligned to a word boundary. + * @retval FS_ERR_QUEUE_FULL If the internal operation queue is full. + */ +fs_ret_t fs_store(fs_config_t const * const p_config, + uint32_t const * const p_dest, + uint32_t const * const p_src, + uint16_t length_words, + void * p_context); + + +/**@brief Function for erasing flash pages. + * + * @details Starting from the page at @p p_page_addr, erases @p num_pages flash pages. + * @p p_page_addr must be aligned to a page boundary. All pages to be erased must be + * within the bounds specified in the supplied fstorage configuration. + * This function is asynchronous. Completion is reported via an event. * - * @param[in] p_config Const pointer to configiguration of module user that requests a store operation. - * @param[in] p_addr Write address of store operation. - * @param[in] p_data Pointer to the data to store. - * @param[in] length_words Length of the data to store. + * @param[in] p_config fstorage configuration registered by the application. + * @param[in] p_page_addr Address of the page to erase. Must be aligned to a page boundary. + * @param[in] num_pages Number of pages to erase. May not be zero. + * @param[in] p_context User-defined context passed to the interrupt handler. * - * @retval NRF_SUCCESS Success. Command queued. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_INVALID_ADDR Error. Data is unaligned or invalid configuration. - * @retval Any error returned by the SoftDevice flash API. + * @retval FS_SUCCESS If the operation was queued successfully. + * @retval FS_ERR_NOT_INITIALIZED If the module is not initialized. + * @retval FS_ERR_INVALID_CFG If @p p_config is NULL or contains invalid data. + * @retval FS_ERR_NULL_ARG If @p p_page_addr is NULL. + * @retval FS_ERR_INVALID_ARG If @p num_pages is zero. + * @retval FS_ERR_INVALID_ADDR If the operation would go beyond the flash memory boundaries + * specified in @p p_config. + * @retval FS_ERR_UNALIGNED_ADDR If @p p_page_addr is not aligned to a page boundary. + * @retval FS_ERR_QUEUE_FULL If the internal operation queue is full. */ -ret_code_t fs_store(fs_config_t const * p_config, - uint32_t const * p_addr, - uint32_t const * const p_data, - fs_length_t length_words); +fs_ret_t fs_erase(fs_config_t const * const p_config, + uint32_t const * const p_page_addr, + uint16_t num_pages, + void * p_context); -/** Function to erase a page in flash. +/**@brief Function for retrieving the number of queued flash operations. * - * @note The erase address must be aligned on a page boundary. The length in words must be - * equivalent to the page size. + * @param[out] p_op_count The number of queued flash operations. * - * @param[in] p_config Pointer to the configuration of the user that requests the operation. - * @param[in] p_addr Address of page to erase (the same as first word in the page). - * @param[in] length_words Length (in 4 byte words) of the area to erase. + * @retval FS_SUCCESS If the number of queued operations was retrieved successfully. + * @retval FS_ERR_NULL_ARG If @p p_op_count is NULL. + */ +fs_ret_t fs_queued_op_count_get(uint32_t * const p_op_count); + + +/**@brief Function for checking if the queue for flash operations is full. * - * @retval NRF_SUCCESS Success. Command queued. - * @retval NRF_ERROR_INVALID_STATE Error. The module is not initialized. - * @retval NRF_ERROR_INVALID_ADDR Error. Data is unaligned or invalid configuration. - * @retval Any error returned by the SoftDevice flash API. + * @retval true If the queue is full. + * @retval false If there is space for more operations in the queue. */ -ret_code_t fs_erase(fs_config_t const * p_config, - uint32_t * const p_addr, - fs_length_t length_words); +bool fs_queue_is_full(void); -/**@brief Function to call to handle events from the SoftDevice +/**@brief Function for checking if the queue for flash operations is empty. * - * @param sys_evt System event from the SoftDevice + * @retval true If the queue is empty. + * @retval false If there are flash operations in the queue. + */ +bool fs_queue_is_empty(void); + + +/**@brief Function for handling system events from the SoftDevice. + * + * @details If any of the modules used by the application rely on fstorage, the application should + * dispatch system events to fstorage using this function. + * + * @param[in] sys_evt System event from the SoftDevice. */ void fs_sys_event_handler(uint32_t sys_evt); + /** @} */ -#endif // FS_H__ + +#ifdef __cplusplus +} +#endif + +#endif // FSTORAGE_H__ diff --git a/components/libraries/fstorage/fstorage_config.h b/components/libraries/fstorage/fstorage_config.h deleted file mode 100644 index e222f9b..0000000 --- a/components/libraries/fstorage/fstorage_config.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef FS_CONFIG_H__ -#define FS_CONFIG_H__ - -#include -#include "nrf.h" - -/** - * @defgroup fstorage_config FStorage configuration - * @ingroup fstorage - * @{ - * @brief FStorage configuration. - */ - - -/**@brief Macro for max number of operations in the fs cmd queue. - */ -#define FS_CMD_QUEUE_SIZE (8) - - -/**@brief Macro for max number of retries for a flash command before it notifies as failed. - */ -#define FS_CMD_MAX_RETRIES (3) - - -/**@brief Macro for the content of a flash address that has not been written to. - */ -#define FS_EMPTY_MASK (0xFFFFFFFF) - - -/**@brief Macro for flash page size according to chip family - */ -#if defined (NRF51) - #define FS_PAGE_SIZE (1024) -#elif defined (NRF52) - #define FS_PAGE_SIZE (4096) -#else - #error "Device family must be defined. See nrf.h." -#endif - - -/*@brief Macro for flash page size according to chip family -*/ -#define FS_PAGE_SIZE_WORDS (FS_PAGE_SIZE/4) - - -/**@brief Static inline function that provides last page address - * - * @note If there is a bootloader present the bootloader address read from UICR - * will act as the page beyond the end of the available flash storage - */ -static __INLINE uint32_t fs_flash_page_end_addr() -{ - uint32_t const bootloader_addr = NRF_UICR->NRFFW[0]; - return ((bootloader_addr != FS_EMPTY_MASK) ? - bootloader_addr : NRF_FICR->CODESIZE * FS_PAGE_SIZE); -} - - -/**@brief Macro for last page address - * - * @note If there is a bootloader present the bootloader address read from UICR - * will act as the page beyond the end of the available flash storage - */ -#define FS_PAGE_END_ADDR fs_flash_page_end_addr() - - -/**@brief Macro to describe the write - * - */ -#if defined (NRF51) - #define FS_MAX_WRITE_SIZE_WORDS (256) -#elif defined (NRF52) - #define FS_MAX_WRITE_SIZE_WORDS (1024) -#else - #error "Device family must be defined. see nrf.h" -#endif - -/** @} */ - -#endif // FS_CONFIG_H__ - diff --git a/components/libraries/fstorage/fstorage_internal_defs.h b/components/libraries/fstorage/fstorage_internal_defs.h new file mode 100644 index 0000000..fc914b7 --- /dev/null +++ b/components/libraries/fstorage/fstorage_internal_defs.h @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 FSTORAGE_INTERNAL_DEFS_H__ +#define FSTORAGE_INTERNAL_DEFS_H__ + +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define FS_FLAG_INITIALIZED (1 << 0) // The module has been initialized. +#define FS_FLAG_PROCESSING (1 << 1) // The module is processing flash operations. +// The module is waiting for a flash operation initiated by another module to complete. +#define FS_FLAG_FLASH_REQ_PENDING (1 << 2) + +#define FS_ERASED_WORD (0xFFFFFFFF) + +// Helper macros for section variables. +#define FS_SECTION_VARS_GET(i) NRF_SECTION_VARS_GET((i), fs_config_t, fs_data) +#define FS_SECTION_VARS_COUNT NRF_SECTION_VARS_COUNT(fs_config_t, fs_data) +#define FS_SECTION_VARS_START_ADDR NRF_SECTION_VARS_START_ADDR(fs_data) +#define FS_SECTION_VARS_END_ADDR NRF_SECTION_VARS_END_ADDR(fs_data) + + +// Create section 'fs_data'. +NRF_SECTION_VARS_CREATE_SECTION(fs_data, fs_config_t); + + +// fstorage op-codes. +typedef enum +{ + FS_OP_NONE, // No operation. + FS_OP_STORE, // Store data. + FS_OP_ERASE // Erase one or more flash pages. +} fs_op_code_t; + + +#if defined(__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined(__ICCARM__) + #pragma language=extended +#elif defined(__GNUC__) + // anonymous unions are enabled by default. +#endif + +// fstorage operation. +// Encapsulates details of a flash operation to be executed by this module. +typedef struct +{ + fs_config_t const * p_config; // Application-specific fstorage configuration. + void * p_context; // User-defined context passed to the interrupt handler. + fs_op_code_t op_code; // ID of the operation. + union + { + struct + { + uint32_t const * p_src; // Pointer to the data to be written to flash. + uint32_t const * p_dest; // Destination of the data in flash. + uint16_t length_words; // Length of the data to be written, in words. + uint16_t offset; // Write offset. + } store; + struct + { + uint16_t page; + uint16_t pages_erased; + uint16_t pages_to_erase; + } erase; + }; +} fs_op_t; + +#if defined(__CC_ARM) + #pragma pop +#elif defined(__ICCARM__) + // leave anonymous unions enabled. +#elif defined(__GNUC__) + // anonymous unions are enabled by default. +#endif + + +// Queue of requested operations. +// This queue holds flash operations requested to the module. +// The data to be written to flash must be kept in memory until the write operation +// is completed, i.e., an event indicating completion is received. +typedef struct +{ + fs_op_t op[FS_QUEUE_SIZE]; // Queue elements. + uint32_t rp; // Index of the operation being processed. + uint32_t count; // Number of elements in the queue. +} fs_op_queue_t; + + +// Size of a flash page in bytes. +#if defined (NRF51) + #define FS_PAGE_SIZE (1024) +#elif (defined (NRF52) || defined(NRF52840_XXAA)) + #define FS_PAGE_SIZE (4096) +#endif + + +// Size of a flash page in words. +#define FS_PAGE_SIZE_WORDS (FS_PAGE_SIZE / sizeof(uint32_t)) + + +// Function to obtain the end of the flash space available to fstorage. +static uint32_t const * fs_flash_page_end_addr() +{ + uint32_t const bootloader_addr = NRF_UICR->NRFFW[0]; + + return (uint32_t*)((bootloader_addr != FS_ERASED_WORD) ? bootloader_addr : + NRF_FICR->CODESIZE * FS_PAGE_SIZE); +} + + +// Macro to obtain the address of the last page. +// If there is a bootloader present the bootloader address read from UICR +// will act as the page beyond the end of the available flash storage. +#define FS_PAGE_END_ADDR (fs_flash_page_end_addr()) + + + +#ifdef __cplusplus +} +#endif + +#endif //__FSTORAGE_INTERNAL_DEFS_H diff --git a/components/libraries/fstorage/fstorage_nosd.c b/components/libraries/fstorage/fstorage_nosd.c index e69de29..cd6f4db 100644 --- a/components/libraries/fstorage/fstorage_nosd.c +++ b/components/libraries/fstorage/fstorage_nosd.c @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ \ No newline at end of file diff --git a/components/libraries/gpiote/app_gpiote.c b/components/libraries/gpiote/app_gpiote.c index a0e00e5..6544e66 100644 --- a/components/libraries/gpiote/app_gpiote.c +++ b/components/libraries/gpiote/app_gpiote.c @@ -1,29 +1,58 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_GPIOTE) #include "app_gpiote.h" #include "nrf_drv_gpiote.h" -#include -#include -#include +#include "nrf_bitmask.h" +#define MODULE_INITIALIZED (mp_users != NULL) /**< Macro designating whether the module has been initialized properly. */ + /**@brief GPIOTE user type. */ typedef struct { - uint32_t pins_mask; /**< Mask defining which pins user wants to monitor. */ - uint32_t pins_low_to_high_mask; /**< Mask defining which pins will generate events to this user when toggling low->high. */ - uint32_t pins_high_to_low_mask; /**< Mask defining which pins will generate events to this user when toggling high->low. */ - uint32_t sense_high_pins; /**< Mask defining which pins are configured to generate GPIOTE interrupt on transition to high level. */ - app_gpiote_event_handler_t event_handler; /**< Pointer to function to be executed when an event occurs. */ - bool enabled; /**< Flag indicating whether user is enabled. */ + uint32_t pins_mask[GPIO_COUNT]; /**< Mask defining which pins user wants to monitor. */ + uint32_t pins_low_to_high_mask[GPIO_COUNT]; /**< Mask defining which pins will generate events to this user when toggling low->high. */ + uint32_t pins_high_to_low_mask[GPIO_COUNT]; /**< Mask defining which pins will generate events to this user when toggling high->low. */ + uint32_t sense_high_pins[GPIO_COUNT]; /**< Mask defining which pins are configured to generate GPIOTE interrupt on transition to high level. */ + app_gpiote_event_handler_t event_handler; /**< Pointer to function to be executed when an event occurs. */ + bool enabled; /**< Flag indicating whether user is enabled. */ } gpiote_user_t; STATIC_ASSERT(sizeof(gpiote_user_t) <= GPIOTE_USER_NODE_SIZE); @@ -32,27 +61,33 @@ STATIC_ASSERT(sizeof(gpiote_user_t) % 4 == 0); static uint8_t m_user_array_size; /**< Size of user array. */ static uint8_t m_user_count; /**< Number of registered users. */ static gpiote_user_t * mp_users = NULL; /**< Array of GPIOTE users. */ -static uint32_t m_pins; /**< Mask of initialized pins. */ -static uint32_t m_last_pins_state; /**< Most recent state of pins. */ +static uint32_t m_pins[GPIO_COUNT]; /**< Mask of initialized pins. */ +static uint32_t m_last_pins_state[GPIO_COUNT]; /**< Most recent state of pins. */ void gpiote_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { int i; - uint32_t pin_mask = 1 << pin; - bool hitolo = (m_last_pins_state & pin_mask) ? true : false; - m_last_pins_state = nrf_gpio_pins_read(); + uint32_t pin_mask[GPIO_COUNT] = {0}; + uint32_t empty_pin_mask[GPIO_COUNT] = {0}; + nrf_bitmask_bit_set(pin, pin_mask); + bool hitolo = nrf_bitmask_bit_is_set(pin, m_last_pins_state); + nrf_gpio_ports_read(0, GPIO_COUNT, m_last_pins_state); for (i = 0; i < m_user_count; i++) { - if (mp_users[i].enabled && (pin_mask & mp_users[i].pins_mask)) + if (mp_users[i].enabled && nrf_bitmask_bit_is_set(pin, mp_users[i].pins_mask)) { - if ((pin_mask & mp_users[i].pins_high_to_low_mask) && hitolo) + if ( + nrf_bitmask_bit_is_set(pin, mp_users[i].pins_high_to_low_mask) + && hitolo) { - mp_users[i].event_handler(0,pin_mask); + mp_users[i].event_handler(empty_pin_mask,pin_mask); } - else if ((pin_mask & mp_users[i].pins_low_to_high_mask) && !hitolo) + else if ( + nrf_bitmask_bit_is_set(pin, mp_users[i].pins_low_to_high_mask) + && !hitolo) { - mp_users[i].event_handler(pin_mask,0); + mp_users[i].event_handler(pin_mask,empty_pin_mask); } } } @@ -77,7 +112,7 @@ uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer) mp_users = (gpiote_user_t *)p_buffer; m_user_array_size = max_users; m_user_count = 0; - m_pins = 0; + memset(m_pins,0, sizeof(m_pins)); memset(mp_users, 0, m_user_array_size * sizeof(gpiote_user_t)); @@ -90,17 +125,16 @@ uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer) } uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id, - uint32_t pins_low_to_high_mask, - uint32_t pins_high_to_low_mask, + uint32_t const * p_pins_low_to_high_mask, + uint32_t const * p_pins_high_to_low_mask, app_gpiote_event_handler_t event_handler) { - uint32_t user_pin_mask; + uint32_t user_pin_mask[GPIO_COUNT]; uint32_t ret_val = NRF_SUCCESS; + // Check state and parameters. - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } + VERIFY_MODULE_INITIALIZED(); + if (event_handler == NULL) { return NRF_ERROR_INVALID_PARAM; @@ -110,31 +144,33 @@ uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id, return NRF_ERROR_NO_MEM; } - user_pin_mask = pins_low_to_high_mask | pins_high_to_low_mask; + nrf_bitmask_masks_or(p_pins_low_to_high_mask, p_pins_high_to_low_mask, + user_pin_mask, sizeof(user_pin_mask)); // Allocate new user. - mp_users[m_user_count].pins_mask = user_pin_mask; - mp_users[m_user_count].pins_low_to_high_mask = pins_low_to_high_mask; - mp_users[m_user_count].pins_high_to_low_mask = pins_high_to_low_mask; + memcpy(mp_users[m_user_count].pins_mask, + user_pin_mask, sizeof(mp_users[m_user_count].pins_mask)); + memcpy(mp_users[m_user_count].pins_low_to_high_mask, + p_pins_low_to_high_mask, sizeof(mp_users[m_user_count].pins_low_to_high_mask)); + memcpy(mp_users[m_user_count].pins_high_to_low_mask, + p_pins_high_to_low_mask, sizeof(mp_users[m_user_count].pins_high_to_low_mask)); mp_users[m_user_count].event_handler = event_handler; mp_users[m_user_count].enabled = false; *p_user_id = m_user_count++; - uint32_t mask = 1; uint32_t i; const nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); - for (i = 0; i < 32; i++) + + uint32_t num_of_pins = NUMBER_OF_PINS ; + for (i = 0; i < num_of_pins; i++) { - if ((mask & user_pin_mask) & ~m_pins) + if (nrf_bitmask_bit_is_set(i, user_pin_mask) && + !nrf_bitmask_bit_is_set(i, m_pins)) { ret_val = nrf_drv_gpiote_in_init(i, &config, gpiote_handler); - if (ret_val != NRF_SUCCESS) - { - return ret_val; - } - m_pins |= mask; + VERIFY_SUCCESS(ret_val); + nrf_bitmask_bit_set(i, m_pins); } - mask <<= 1; } return ret_val; } @@ -142,10 +178,8 @@ uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id, __STATIC_INLINE uint32_t error_check(app_gpiote_user_id_t user_id) { // Check state and parameters. - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } + VERIFY_MODULE_INITIALIZED(); + if (user_id >= m_user_count) { return NRF_ERROR_INVALID_PARAM; @@ -162,12 +196,12 @@ __STATIC_INLINE uint32_t error_check(app_gpiote_user_id_t user_id) static void pin_event_enable(uint32_t pin, bool enable) { uint32_t i; - uint32_t pin_mask = 1UL << pin; bool enabled = false; //search if any user already enabled given pin for (i = 0; i < m_user_count; i++) { - if (mp_users[i].enabled && (mp_users[i].pins_mask & pin_mask)) + if (mp_users[i].enabled && + nrf_bitmask_bit_is_set(pin, mp_users[i].pins_mask)) { enabled = true; break; @@ -177,7 +211,7 @@ static void pin_event_enable(uint32_t pin, bool enable) { if (enable) { - m_last_pins_state = nrf_gpio_pins_read(); + nrf_gpio_ports_read(0, GPIO_COUNT, m_last_pins_state); nrf_drv_gpiote_in_event_enable(pin, true); } else @@ -203,14 +237,12 @@ static uint32_t user_enable(app_gpiote_user_id_t user_id, bool enable) if (ret_code == NRF_SUCCESS) { uint32_t i; - uint32_t mask = 1UL; - for (i = 0; i < 32; i++) + for (i = 0; i < NUMBER_OF_PINS; i++) { - if (mp_users[user_id].pins_mask & mask) + if (nrf_bitmask_bit_is_set(i, mp_users[user_id].pins_mask)) { pin_event_enable(i, enable); } - mask <<= 1; } } return ret_code; @@ -223,15 +255,10 @@ uint32_t app_gpiote_user_enable(app_gpiote_user_id_t user_id) if (mp_users[user_id].enabled == false) { ret_code = user_enable(user_id, true); - if (ret_code != NRF_SUCCESS) - { - return ret_code; - } - else - { - mp_users[user_id].enabled = true; - return ret_code; - } + VERIFY_SUCCESS(ret_code); + + mp_users[user_id].enabled = true; + return ret_code; } else { @@ -260,9 +287,10 @@ uint32_t app_gpiote_pins_state_get(app_gpiote_user_id_t user_id, uint32_t * p_pi if (ret_code == NRF_SUCCESS) { p_user = &mp_users[user_id]; - // Get pins. - *p_pins = nrf_gpio_pins_read() & p_user->pins_mask; + nrf_gpio_ports_read(0, GPIO_COUNT, p_pins); + nrf_bitmask_masks_and(p_pins, p_user->pins_mask, p_pins, sizeof(p_user->pins_mask)); } return ret_code; } +#endif //NRF_MODULE_ENABLED(APP_GPIOTE) diff --git a/components/libraries/gpiote/app_gpiote.h b/components/libraries/gpiote/app_gpiote.h index a063d5b..5f60a47 100644 --- a/components/libraries/gpiote/app_gpiote.h +++ b/components/libraries/gpiote/app_gpiote.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -46,8 +74,11 @@ #include "app_error.h" #include "app_util.h" -#define GPIOTE_USER_NODE_SIZE 24 /**< Size of app_gpiote.gpiote_user_t (only for use inside APP_GPIOTE_BUF_SIZE()). */ -#define NO_OF_PINS 32 /**< Number of GPIO pins on the \nRFXX chip. */ +#ifdef __cplusplus +extern "C" { +#endif + +#define GPIOTE_USER_NODE_SIZE ((4*sizeof(uint32_t)*GPIO_COUNT)+8) /**< Size of app_gpiote.gpiote_user_t (only for use inside APP_GPIOTE_BUF_SIZE()). */ /**@brief Compute number of bytes required to hold the GPIOTE data structures. * @@ -60,8 +91,8 @@ typedef uint8_t app_gpiote_user_id_t; /**@brief GPIOTE event handler type. */ -typedef void (*app_gpiote_event_handler_t)(uint32_t event_pins_low_to_high, - uint32_t event_pins_high_to_low); +typedef void (*app_gpiote_event_handler_t)(uint32_t const * p_event_pins_low_to_high, + uint32_t const * p_event_pins_high_to_low); /**@brief GPIOTE input event handler type. */ typedef void (*app_gpiote_input_event_handler_t)(void); @@ -93,7 +124,7 @@ typedef void (*app_gpiote_input_event_handler_t)(void); * @param[in] max_users Maximum number of GPIOTE users. * @param[in] p_buffer Pointer to memory buffer for internal use in the app_gpiote * module. The size of the buffer can be computed using the - * APP_GPIOTE_BUF_SIZE() macro. The buffer must be aligned to + * APP_GPIOTE_BUF_SIZE() macro. The buffer must be aligned to * a 4 byte boundary. * * @retval NRF_SUCCESS Successful initialization. @@ -105,10 +136,14 @@ uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer); /**@brief Function for registering a GPIOTE user. * * @param[out] p_user_id Id for the new GPIOTE user. - * @param[in] pins_low_to_high_mask Mask defining which pins will generate events to this user - * when state is changed from low->high. - * @param[in] pins_high_to_low_mask Mask defining which pins will generate events to this user - * when state is changed from high->low. + * @param[in] p_pins_low_to_high_mask Pointer to word array with mask defining which pins + * will generate events to this user when state is changed + * from low->high. Size of array depends on number of ports + * in the device. + * @param[in] p_pins_high_to_low_mask Pointer to word array with mask defining which pins + * will generate events to this user when state is changed + * from high->low. Size of array depends on number of ports + * in the device. * @param[in] event_handler Pointer to function to be executed when an event occurs. * * @retval NRF_SUCCESS Successful initialization. @@ -120,8 +155,8 @@ uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer); * @ref app_gpiote_init. */ uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id, - uint32_t pins_low_to_high_mask, - uint32_t pins_high_to_low_mask, + uint32_t const * p_pins_low_to_high_mask, + uint32_t const * p_pins_high_to_low_mask, app_gpiote_event_handler_t event_handler); /**@brief Function for informing the GPIOTE module that the specified user wants to use the GPIOTE module. @@ -149,9 +184,11 @@ uint32_t app_gpiote_user_disable(app_gpiote_user_id_t user_id); /**@brief Function for getting the state of the pins which are registered for the specified user. * * @param[in] user_id Id of user to check. - * @param[out] p_pins Bit mask corresponding to the pins configured to generate events to - * the specified user. All bits corresponding to pins in the state - * 'high' will have value '1', all others will have value '0'. + * @param[out] p_pins Pointer to array of words with bit mask corresponding to the pins + * configured to generate events to the specified user. All bits + * corresponding to pins in the state 'high' will have value '1', + * all others will have value '0'. Size of array depends on number + * of ports in the device. * * @retval NRF_SUCCESS On success. * @retval NRF_ERROR_INVALID_PARAM Invalid user_id provided, No a valid user. @@ -160,59 +197,9 @@ uint32_t app_gpiote_user_disable(app_gpiote_user_id_t user_id); */ uint32_t app_gpiote_pins_state_get(app_gpiote_user_id_t user_id, uint32_t * p_pins); -/**@brief Function for registering event handlers for GPIOTE IN events. - * - * @param[in] channel GPIOTE channel [0..3]. - * @param[in] pin Pins associated with GPIOTE channel. Changes on following pins will generate events. - * @param[in] polarity Specify operation on input that shall trigger IN event. - * @param[in] event_handler Event handler invoked on the IN event in the GPIOTE interrupt. - * - * @retval NRF_SUCCESS On success. - * @retval NRF_ERROR_INVALID_PARAM Invalid channel or pin number. - * @retval NRF_ERROR_NOT_SUPPORTED Driver doesn't support IN events. - */ -uint32_t app_gpiote_input_event_handler_register(const uint8_t channel, - const uint32_t pin, - const uint32_t polarity, - app_gpiote_input_event_handler_t event_handler); - -/**@brief Function for unregistering event handlers for GPIOTE IN events. - * - * @retval NRF_SUCCESS On success. - * @retval NRF_ERROR_NOT_SUPPORTED Driver doesn't support IN events. - */ -uint32_t app_gpiote_input_event_handler_unregister(const uint8_t channel); - -/**@brief Function for registering event handler invoked at the end of a GPIOTE interrupt. - * - * @param[in] event_handler Event handler invoked at the end of the GPIOTE interrupt. - * - * @retval NRF_SUCCESS On success. - * @retval NRF_ERROR_NOT_SUPPORTED Driver doesn't support IN events. - */ -uint32_t app_gpiote_end_irq_event_handler_register(app_gpiote_input_event_handler_t event_handler); - -/**@brief Function for unregistering event handler invoked at the end of a GPIOTE interrupt. - * - * @retval NRF_SUCCESS On success. - * @retval NRF_ERROR_NOT_SUPPORTED Driver doesn't support IN events. - */ -uint32_t app_gpiote_end_irq_event_handler_unregister(void); - -/**@brief Function for enabling interrupts in the GPIOTE driver. - * - * @retval NRF_SUCCESS On success. - * @retval NRF_ERROR_NOT_SUPPORTED Driver doesn't support. - */ -uint32_t app_gpiote_enable_interrupts(void); - -/**@brief Function for disabling interrupts in the GPIOTE driver. - * - * @retval NRF_SUCCESS On success. - * @retval NRF_ERROR_NOT_SUPPORTED Driver doesn't support. - */ -uint32_t app_gpiote_disable_interrupts(void); - +#ifdef __cplusplus +} +#endif #endif // APP_GPIOTE_H__ diff --git a/components/libraries/gpiote/app_gpiote_fast_detect.c b/components/libraries/gpiote/app_gpiote_fast_detect.c deleted file mode 100644 index acec54e..0000000 --- a/components/libraries/gpiote/app_gpiote_fast_detect.c +++ /dev/null @@ -1,539 +0,0 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_gpiote.h" -#include -#include -#include "app_util.h" -#include "app_util_platform.h" -#include "nrf_error.h" -#include "nrf_gpio.h" - -#define NRF51_GPIOTE_CHANNEL 4 -#define NRF51_PINS 31 - -#ifdef NRF51 -#define SWI_IRQHandler SWI1_IRQHandler -#define SWI_IRQn SWI1_IRQn -#elif defined NRF52 -#define SWI_IRQHandler SWI1_EGU1_IRQHAndler -#define SWI_IRQn SWI1_EGU1_IRQn -#endif - -/**@brief GPIOTE user type. */ -typedef struct -{ - uint32_t pins_mask; /**< Mask defining which pins user wants to monitor. */ - uint32_t pins_low_to_high_mask; /**< Mask defining which pins will generate events to this user when toggling low->high. */ - uint32_t pins_high_to_low_mask; /**< Mask defining which pins will generate events to this user when toggling high->low. */ - uint32_t sense_high_pins; /**< Mask defining which pins are configured to generate GPIOTE interrupt on transition to high level. */ - app_gpiote_event_handler_t event_handler; /**< Pointer to function to be executed when an event occurs. */ -} gpiote_user_t; - -STATIC_ASSERT(sizeof (gpiote_user_t) <= GPIOTE_USER_NODE_SIZE); -STATIC_ASSERT(sizeof (gpiote_user_t) % 4 == 0); - -static uint32_t m_enabled_users_mask; /**< Mask for tracking which users are enabled. */ -static uint8_t m_user_array_size; /**< Size of user array. */ -static uint8_t m_user_count; /**< Number of registered users. */ -static gpiote_user_t * mp_users = NULL; /**< Array of GPIOTE users. */ - - -static app_gpiote_input_event_handler_t m_app_gpiote_input_event_handlers[4] = {0}; - -static app_gpiote_input_event_handler_t m_app_gpiote_end_irq_event_handler = NULL; - -/**@brief Function for toggling sense level for specified pins. - * - * @param[in] p_user Pointer to user structure. - * @param[in] pins Bitmask specifying for which pins the sense level is to be toggled. - */ -static void sense_level_toggle(gpiote_user_t * p_user, uint32_t pins) -{ - uint32_t pin_no; - - for (pin_no = 0; pin_no < NO_OF_PINS; pin_no++) - { - uint32_t pin_mask = (1 << pin_no); - - if ((pins & pin_mask) != 0) - { - uint32_t sense; - - //Invert sensing. - if ((p_user->sense_high_pins & pin_mask) == 0) - { - sense = GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; - p_user->sense_high_pins |= pin_mask; - } - else - { - sense = GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; - p_user->sense_high_pins &= ~pin_mask; - } - - NRF_GPIO->PIN_CNF[pin_no] &= ~GPIO_PIN_CNF_SENSE_Msk; - NRF_GPIO->PIN_CNF[pin_no] |= sense; - } - } -} - - -/**@brief Function for handling the GPIOTE interrupt. - */ -void GPIOTE_IRQHandler(void) -{ - bool gpiote_in_evt = false; - bool gpiote_port_evt = false; - - if ((NRF_GPIOTE->EVENTS_IN[0] == 1) && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk)) - { - NRF_GPIOTE->EVENTS_IN[0] = 0; - gpiote_in_evt = true; - - if (m_app_gpiote_input_event_handlers[0]) - { - m_app_gpiote_input_event_handlers[0](); - } - } - - if ((NRF_GPIOTE->EVENTS_IN[1] == 1) && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN1_Msk)) - { - NRF_GPIOTE->EVENTS_IN[1] = 0; - gpiote_in_evt = true; - - if (m_app_gpiote_input_event_handlers[1]) - { - m_app_gpiote_input_event_handlers[1](); - } - } - - if ((NRF_GPIOTE->EVENTS_IN[2] == 1) && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN2_Msk)) - { - NRF_GPIOTE->EVENTS_IN[2] = 0; - gpiote_in_evt = true; - - if (m_app_gpiote_input_event_handlers[2]) - { - m_app_gpiote_input_event_handlers[2](); - } - } - - if ((NRF_GPIOTE->EVENTS_IN[3] == 1) && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN3_Msk)) - { - NRF_GPIOTE->EVENTS_IN[3] = 0; - gpiote_in_evt = true; - - if (m_app_gpiote_input_event_handlers[3]) - { - m_app_gpiote_input_event_handlers[3](); - } - } - - if ((NRF_GPIOTE->EVENTS_PORT == 1) && (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_PORT_Msk)) - { - //Clear event. - NRF_GPIOTE->EVENTS_PORT = 0; - - gpiote_port_evt = true; - } - - if (m_app_gpiote_end_irq_event_handler && gpiote_in_evt) - { - m_app_gpiote_end_irq_event_handler(); - } - - if (gpiote_port_evt) - { - NVIC_SetPendingIRQ(SWI_IRQn); - } -} - - -/**@brief Function for handling the SWI1 interrupt. - */ -void SWI_IRQHandler(void) -{ - uint8_t i; - uint32_t pins_changed; - uint32_t pins_state = NRF_GPIO->IN; - - //Check all users. - for (i = 0; i < m_user_count; i++) - { - gpiote_user_t * p_user = &mp_users[i]; - - //Check if user is enabled. - if (((1 << i) & m_enabled_users_mask) != 0) - { - uint32_t transition_pins; - uint32_t event_low_to_high; - uint32_t event_high_to_low; - - //Find set of pins on which there has been a transition. - transition_pins = (pins_state ^ ~p_user->sense_high_pins) & p_user->pins_mask; - - //Toggle SENSE level for all pins that have changed state. - sense_level_toggle(p_user, transition_pins); - - //Second read after setting sense. - //Check if any pins have changed while serving this interrupt. - pins_changed = NRF_GPIO->IN ^ pins_state; - - if (pins_changed) - { - //Transition pins detected in late stage. - uint32_t late_transition_pins; - - pins_state |= pins_changed; - - //Find set of pins on which there has been a transition. - late_transition_pins = (pins_state ^ ~p_user->sense_high_pins) & p_user->pins_mask; - - //Toggle SENSE level for all pins that have changed state in last phase. - sense_level_toggle(p_user, late_transition_pins); - - //Update pins that has changed state since the interrupt occurred. - transition_pins |= late_transition_pins; - } - - //Call user event handler if an event has occurred. - event_high_to_low = (~pins_state & p_user->pins_high_to_low_mask) & transition_pins; - event_low_to_high = (pins_state & p_user->pins_low_to_high_mask) & transition_pins; - - if ((event_low_to_high | event_high_to_low) != 0) - { - p_user->event_handler(event_low_to_high, event_high_to_low); - } - } - } -} - - -/**@brief Function for enabling interrupt SWI1. - */ -static void app_gpiote_swi1_enable_irq(void) -{ - NVIC_ClearPendingIRQ(SWI_IRQn); - NVIC_SetPriority(SWI_IRQn, APP_IRQ_PRIORITY_LOW); - NVIC_EnableIRQ(SWI_IRQn); -} - -/**@brief Function for disabling interrupt SWI1. - */ -static void app_gpiote_swi1_disable_irq(void) -{ - NVIC_DisableIRQ(SWI_IRQn); -} - -/**@brief Function for sense disabling for all pins for specified user. - * - * @param[in] user_id User id. - */ -static void pins_sense_disable(app_gpiote_user_id_t user_id) -{ - uint32_t pin_no; - - for (pin_no = 0; pin_no < 32; pin_no++) - { - if ((mp_users[user_id].pins_mask & (1 << pin_no)) != 0) - { - NRF_GPIO->PIN_CNF[pin_no] &= ~GPIO_PIN_CNF_SENSE_Msk; - NRF_GPIO->PIN_CNF[pin_no] |= GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos; - } - } -} - - -uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer) -{ - if (p_buffer == NULL) - { - return NRF_ERROR_INVALID_PARAM; - } - - //Check that buffer is correctly aligned. - if (!is_word_aligned(p_buffer)) - { - return NRF_ERROR_INVALID_PARAM; - } - - //Initialize file globals. - mp_users = (gpiote_user_t *)p_buffer; - m_user_array_size = max_users; - m_user_count = 0; - m_enabled_users_mask = 0; - - memset(mp_users, 0, m_user_array_size * sizeof (gpiote_user_t)); - - (void)app_gpiote_enable_interrupts(); - - return NRF_SUCCESS; -} - -uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id, - uint32_t pins_low_to_high_mask, - uint32_t pins_high_to_low_mask, - app_gpiote_event_handler_t event_handler) -{ - //Check state and parameters. - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } - - if (event_handler == NULL) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (m_user_count >= m_user_array_size) - { - return NRF_ERROR_NO_MEM; - } - - //Allocate new user. - mp_users[m_user_count].pins_mask = pins_low_to_high_mask | pins_high_to_low_mask; - mp_users[m_user_count].pins_low_to_high_mask = pins_low_to_high_mask; - mp_users[m_user_count].pins_high_to_low_mask = pins_high_to_low_mask; - mp_users[m_user_count].event_handler = event_handler; - - *p_user_id = m_user_count++; - - //Make sure SENSE is disabled for all pins. - pins_sense_disable(*p_user_id); - - return NRF_SUCCESS; -} - -uint32_t app_gpiote_enable_interrupts(void) -{ - NVIC_ClearPendingIRQ(GPIOTE_IRQn); - NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH); - NVIC_EnableIRQ(GPIOTE_IRQn); - - //Enable interrupt SWI1. - app_gpiote_swi1_enable_irq(); - - return NRF_SUCCESS; -} - -uint32_t app_gpiote_disable_interrupts(void) -{ - NVIC_DisableIRQ(GPIOTE_IRQn); - - //Disable interrupt SWI1. - app_gpiote_swi1_disable_irq(); - - return NRF_SUCCESS; -} - -uint32_t app_gpiote_input_event_handler_register(const uint8_t channel, - const uint32_t pin, - const uint32_t polarity, - app_gpiote_input_event_handler_t event_handler) -{ - if (channel < NRF51_GPIOTE_CHANNEL && pin < NRF51_PINS) - { - NRF_GPIOTE->CONFIG[channel] = (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos) | - (pin << GPIOTE_CONFIG_PSEL_Pos) | - (polarity << GPIOTE_CONFIG_POLARITY_Pos); - - switch (channel) - { - case 0: - NRF_GPIOTE->INTENSET |= (GPIOTE_INTENSET_IN0_Enabled << GPIOTE_INTENSET_IN0_Pos); - break; - - case 1: - NRF_GPIOTE->INTENSET |= (GPIOTE_INTENSET_IN1_Enabled << GPIOTE_INTENSET_IN1_Pos); - break; - - case 2: - NRF_GPIOTE->INTENSET |= (GPIOTE_INTENSET_IN2_Enabled << GPIOTE_INTENSET_IN2_Pos); - break; - - case 3: - NRF_GPIOTE->INTENSET |= (GPIOTE_INTENSET_IN3_Enabled << GPIOTE_INTENSET_IN3_Pos); - break; - - default: - break; - } - - m_app_gpiote_input_event_handlers[channel] = event_handler; - - return NRF_SUCCESS; - } - - return NRF_ERROR_INVALID_PARAM; -} - -uint32_t app_gpiote_input_event_handler_unregister(const uint8_t channel) -{ - if (channel < NRF51_GPIOTE_CHANNEL) - { - const uint32_t pin_not_connected = 31UL; - - NRF_GPIOTE->CONFIG[channel] = (GPIOTE_CONFIG_MODE_Disabled << GPIOTE_CONFIG_MODE_Pos) | - (pin_not_connected << GPIOTE_CONFIG_PSEL_Pos) | - (GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos); - - switch (channel) - { - case 0: - NRF_GPIOTE->INTENSET |= (GPIOTE_INTENSET_IN0_Disabled << GPIOTE_INTENSET_IN0_Pos); - break; - - case 1: - NRF_GPIOTE->INTENSET |= (GPIOTE_INTENSET_IN1_Disabled << GPIOTE_INTENSET_IN1_Pos); - break; - - case 2: - NRF_GPIOTE->INTENSET |= (GPIOTE_INTENSET_IN2_Disabled << GPIOTE_INTENSET_IN2_Pos); - break; - - case 3: - NRF_GPIOTE->INTENSET |= (GPIOTE_INTENSET_IN3_Disabled << GPIOTE_INTENSET_IN3_Pos); - break; - - default: - break; - } - - m_app_gpiote_input_event_handlers[channel] = NULL; - - return NRF_SUCCESS; - } - - return NRF_ERROR_INVALID_PARAM; -} - -uint32_t app_gpiote_end_irq_event_handler_register(app_gpiote_input_event_handler_t event_handler) -{ - m_app_gpiote_end_irq_event_handler = event_handler; - return NRF_SUCCESS; -} - -uint32_t app_gpiote_end_irq_event_handler_unregister(void) -{ - m_app_gpiote_end_irq_event_handler = NULL; - return NRF_SUCCESS; -} - -uint32_t app_gpiote_user_enable(app_gpiote_user_id_t user_id) -{ - uint32_t pin_no; - uint32_t pins_state; - - //Check state and parameters. - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } - - if (user_id >= m_user_count) - { - return NRF_ERROR_INVALID_PARAM; - } - - //Clear any pending event. - NRF_GPIOTE->EVENTS_PORT = 0; - pins_state = NRF_GPIO->IN; - - //Enable user. - if (m_enabled_users_mask == 0) - { - NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk; - } - m_enabled_users_mask |= (1 << user_id); - - //Enable sensing for all pins for specified user. - mp_users[user_id].sense_high_pins = 0; - - for (pin_no = 0; pin_no < 32; pin_no++) - { - uint32_t pin_mask = (1 << pin_no); - - if ((mp_users[user_id].pins_mask & pin_mask) != 0) - { - uint32_t sense; - - if ((pins_state & pin_mask) != 0) - { - sense = GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; - } - else - { - sense = GPIO_PIN_CNF_SENSE_High << - GPIO_PIN_CNF_SENSE_Pos; - mp_users[user_id].sense_high_pins |= pin_mask; - } - - NRF_GPIO->PIN_CNF[pin_no] &= ~GPIO_PIN_CNF_SENSE_Msk; - NRF_GPIO->PIN_CNF[pin_no] |= sense; - } - } - - return NRF_SUCCESS; -} - - -uint32_t app_gpiote_user_disable(app_gpiote_user_id_t user_id) -{ - //Check state and parameters. - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } - - if (user_id >= m_user_count) - { - return NRF_ERROR_INVALID_PARAM; - } - - //Disable sensing for all pins for specified user. - pins_sense_disable(user_id); - - //Disable user. - m_enabled_users_mask &= ~(1UL << user_id); - - if (m_enabled_users_mask == 0) - { - NRF_GPIOTE->INTENCLR = GPIOTE_INTENSET_PORT_Msk; - } - - return NRF_SUCCESS; -} - - -uint32_t app_gpiote_pins_state_get(app_gpiote_user_id_t user_id, uint32_t * p_pins) -{ - gpiote_user_t * p_user; - - //Check state and parameters. - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } - - if (user_id >= m_user_count) - { - return NRF_ERROR_INVALID_PARAM; - } - - //Get pins. - p_user = &mp_users[user_id]; - *p_pins = NRF_GPIO->IN & p_user->pins_mask; - - return NRF_SUCCESS; -} diff --git a/components/libraries/hardfault/hardfault.h b/components/libraries/hardfault/hardfault.h new file mode 100644 index 0000000..9a081ac --- /dev/null +++ b/components/libraries/hardfault/hardfault.h @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 HARDFAULT_H__ +#define HARDFAULT_H__ +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @defgroup hardfault_default HardFault exception + * @{ + * @brief Default HardFault exception implementation. + * @ingroup app_common + */ + +/** + * @brief Contents of the stack. + * + * This structure is used to re-create the stack layout after a HardFault exception was raised. + */ +typedef struct HardFault_stack +{ + uint32_t r0; ///< R0 register. + uint32_t r1; ///< R1 register. + uint32_t r2; ///< R2 register. + uint32_t r3; ///< R3 register. + uint32_t r12; ///< R12 register. + uint32_t lr; ///< Link register. + uint32_t pc; ///< Program counter. + uint32_t psr; ///< Program status register. +} HardFault_stack_t; + +/** + * @brief Function for processing HardFault exceptions. + * + * An application that needs to process HardFault exceptions should provide an implementation of this function. + * It will be called from the HardFault handler. + * If no implementation is provided, the library uses a default one, which just restarts the MCU. + * + * @note If the DEBUG_NRF macro is defined, the software breakpoint is set just before the call + * to this function. + * + * @param p_stack Pointer to the stack bottom. + * This pointer might be NULL if the HardFault was called when the main stack was + * the active stack and a stack overrun is detected. + * In such a situation, the stack pointer is reinitialized to the default position, + * and the stack content is lost. + */ +void HardFault_process(HardFault_stack_t * p_stack); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* HARDFAULT_H__ */ diff --git a/components/libraries/hardfault/hardfault_implementation.c b/components/libraries/hardfault/hardfault_implementation.c new file mode 100644 index 0000000..dd3175e --- /dev/null +++ b/components/libraries/hardfault/hardfault_implementation.c @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include "hardfault.h" +#include "nrf.h" +#include "compiler_abstraction.h" +#include "app_util_platform.h" +#ifdef SOFTDEVICE_PRESENT +#include "nrf_soc.h" +#endif +#define NRF_LOG_MODULE_NAME "HARDFAULT" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +#if defined(DEBUG_NRF) +/** + * @brief Pointer to the last received stack pointer. + * + * This pointer is set in the debug version of the HardFault handler. + * It helps to debug HardFault reasons. + */ +volatile HardFault_stack_t * HardFault_p_stack; +#endif + +/*lint -save -e14 */ +__WEAK void HardFault_process(HardFault_stack_t * p_stack) +{ + // Restart the system by default + NVIC_SystemReset(); +} +/*lint -restore */ + +void HardFault_c_handler(uint32_t * p_stack_address) +{ + NRF_LOG_ERROR("Hardfault PC:%x\r\n", ((HardFault_stack_t *)p_stack_address)->pc); + NRF_LOG_FINAL_FLUSH(); +#if defined(DEBUG_NRF) + HardFault_p_stack = (HardFault_stack_t *)p_stack_address; + (void)HardFault_p_stack; + + // Debugger detection is only possible on NRF52 (Cortex-M4), on NRF51 + // (Cortex-M0) the processor has no access to CoreDebug registers. + #if __CORTEX_M == 0x04 + // C_DEBUGEN == 1 -> Debugger Connected + if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) + { + /* Generate breakpoint if debugger is connected */ + NRF_BREAKPOINT; + } + #endif // __CORTEX_M == 0x04 +#endif // DEBUG_NRF + HardFault_process((HardFault_stack_t *)p_stack_address); +} +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c b/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c new file mode 100644 index 0000000..dca1ddd --- /dev/null +++ b/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + +void HardFault_Handler(void) __attribute__(( naked )); + +void HardFault_Handler(void) +{ + __ASM volatile( + " .syntax unified \n" + + " ldr r0, =0xFFFFFFFD \n" + " cmp r0, lr \n" + " bne HardFault_Handler_ChooseMSP \n" + /* Reading PSP into R0 */ + " mrs r0, PSP \n" + " b HardFault_Handler_Continue \n" + "HardFault_Handler_ChooseMSP: \n" + /* Reading MSP into R0 */ + " mrs r0, MSP \n" + /* ----------------------------------------------------------------- + * If we have selected MSP check if we may use stack safetly. + * If not - reset the stack to the initial value. */ + " ldr r1, =__StackTop \n" + " ldr r2, =__StackLimit \n" + + /* MSP is in the range of the stack area */ + " cmp r0, r1 \n" + " bhi HardFault_MoveSP \n" + " cmp r0, r2 \n" + " bhi HardFault_Handler_Continue \n" + /* ----------------------------------------------------------------- */ + "HardFault_MoveSP: \n" + " mov SP, r1 \n" + " movs r0, #0 \n" + + "HardFault_Handler_Continue: \n" + " ldr r3, =HardFault_c_handler \n" + " bx r3 \n" + + " .align \n" + ); +} +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c b/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c new file mode 100644 index 0000000..8ac8f47 --- /dev/null +++ b/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c @@ -0,0 +1,98 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + +#pragma section = "CSTACK" +extern void HardFault_c_handler( uint32_t * ); + +__stackless void HardFault_Handler(void); + +__stackless void HardFault_Handler(void) +{ + __ASM volatile( + " ldr r0, 100f \n" + " cmp r0, lr \n" + " bne 1f \n" + /* Reading PSP into R0 */ + " mrs r0, PSP \n" + " b 3f \n" + "1: \n" + /* Reading MSP into R0 */ + " mrs r0, MSP \n" + /* ----------------------------------------------------------------- + * If we have selected MSP check if we may use stack safetly. + * If not - reset the stack to the initial value. */ + " ldr r1, 101f \n" + " ldr r2, 102f \n" + + /* MSP is in the range of the stack area */ + " cmp r0, r1 \n" + " bhi 2f \n" + " cmp r0, r2 \n" + " bhi 3f \n" + /* ----------------------------------------------------------------- */ + "2: \n" + " mov SP, r1 \n" + " movs r0, #0 \n" + + "3: \n" + " ldr r3, 103f \n" + " bx r3 \n" + + "DATA \n" + "100: \n" + " DC32 0xFFFFFFFD \n" + "101: \n" + " DC32 %c0 \n" + "102: \n" + " DC32 %c1 \n" + "103: \n" + " DC32 %c2 \n" + : /* Outputs */ + : /* Inputs */ + "i"(__section_end("CSTACK")), + "i"(__section_begin("CSTACK")), + "i"(&HardFault_c_handler) + ); +} +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c b/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c new file mode 100644 index 0000000..721e8af --- /dev/null +++ b/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + + +//lint -save -e27 + +__ASM void HardFault_Handler(void) +{ + PRESERVE8 + EXTERN HardFault_c_handler + EXTERN |STACK$$Base| + EXTERN |STACK$$Limit| + + ldr r0, =0xFFFFFFFD + cmp r0, lr + bne HardFault_Handler_ChooseMSP + /* Reading PSP into R0 */ + mrs r0, PSP + b HardFault_Handler_Continue +HardFault_Handler_ChooseMSP + /* Reading MSP into R0 */ + mrs r0, MSP + /* ----------------------------------------------------------------- + * If we have selected MSP, check if we may use stack safely. + * If not - reset the stack to the initial value. */ + ldr r1, =|STACK$$Limit| + ldr r2, =|STACK$$Base| + + /* MSP is in the range of the stack area */ + cmp r0, r1 + bhi HardFault_MoveSP + cmp r0, r2 + bhi HardFault_Handler_Continue + /* ----------------------------------------------------------------- */ +HardFault_MoveSP + mov SP, r1 + movs r0, #0 + +HardFault_Handler_Continue + ldr r3, =HardFault_c_handler + bx r3 + + ALIGN +} + +//lint -restore +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c b/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c new file mode 100644 index 0000000..7ee4ef6 --- /dev/null +++ b/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + +void HardFault_Handler(void) __attribute__(( naked )); + +void HardFault_Handler(void) +{ + __ASM volatile( + " ldr r3, =HardFault_c_handler \n" + " tst lr, #4 \n" + + /* PSP is quite simple and does not require additional handler */ + " itt ne \n" + " mrsne r0, psp \n" + /* Jump to the handler, do not store LR - returning from handler just exits exception */ + " bxne r3 \n" + + /* Processing MSP requires stack checking */ + " mrs r0, msp \n" + + " ldr r1, =__StackTop \n" + " ldr r2, =__StackLimit \n" + + /* MSP is in the range of the stack area */ + " cmp r0, r1 \n" + " bhi HardFault_MoveSP \n" + " cmp r0, r2 \n" + " bhi HardFault_Handler_Continue \n" + + "HardFault_MoveSP: \n" + " mov sp, r1 \n" + " mov r0, #0 \n" + + "HardFault_Handler_Continue: \n" + " bx r3 \n" + + " .align \n" + ); +} +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c b/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c new file mode 100644 index 0000000..a0547fd --- /dev/null +++ b/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + +#pragma section = "CSTACK" +extern void HardFault_c_handler( uint32_t * ); + +__stackless void HardFault_Handler(void); + +__stackless void HardFault_Handler(void) +{ + __ASM volatile( + " ldr.n r3, 103f \n" + " tst lr, #4 \n" + + /* PSP is quite simple and does not require additional handler */ + " itt ne \n" + " mrsne r0, psp \n" + /* Jump to the handler, do not store LR - returning from handler just exits exception */ + " bxne r3 \n" + + /* Processing MSP requires stack checking */ + " mrs r0, msp \n" + + " ldr.n r1, 101f \n" + " ldr.n r2, 102f \n" + + /* MSP is in the range of the stack area */ + " cmp r0, r1 \n" + " bhi.n 1f \n" + " cmp r0, r2 \n" + " bhi.n 2f \n" + + "1: \n" + " mov sp, r1 \n" + " mov r0, #0 \n" + + "2: \n" + " bx r3 \n" + /* Data alignment if required */ + " nop \n" + + "DATA \n" + "101: \n" + " DC32 %c0 \n" + "102: \n" + " DC32 %c1 \n" + "103: \n" + " DC32 %c2 \n" + : /* Outputs */ + : /* Inputs */ + "i"(__section_end("CSTACK")), + "i"(__section_begin("CSTACK")), + "i"(&HardFault_c_handler) + ); +} +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c b/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c new file mode 100644 index 0000000..c9437ce --- /dev/null +++ b/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER) +#include +#include "compiler_abstraction.h" + + +//lint -save -e27 + +__ASM void HardFault_Handler(void) +{ + PRESERVE8 + EXTERN HardFault_c_handler + EXTERN |STACK$$Base| + EXTERN |STACK$$Limit| + + ldr r3, =HardFault_c_handler + tst lr, #4 + + /* PSP is quite simple and does not require additional handler */ + itt ne + mrsne r0, psp + /* Jump to the handler, do not store LR - returning from handler just exits exception */ + bxne r3 + + /* Processing MSP requires stack checking */ + mrs r0, msp + + ldr r1, =|STACK$$Limit| + ldr r2, =|STACK$$Base| + + /* MSP is in the range of the stack area */ + cmp r0, r1 + bhi HardFault_MoveSP + cmp r0, r2 + bhi HardFault_Handler_Continue + +HardFault_MoveSP + mov sp, r1 + mov r0, #0 + +HardFault_Handler_Continue + bx r3 + + ALIGN +} + +//lint -restore +#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER) diff --git a/components/libraries/hci/config/hci_mem_pool_internal.h b/components/libraries/hci/config/hci_mem_pool_internal.h deleted file mode 100644 index f1fa77f..0000000 --- a/components/libraries/hci/config/hci_mem_pool_internal.h +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/** @file - * - * @defgroup memory_pool_internal Memory Pool Internal - * @{ - * @ingroup memory_pool - * - * @brief Memory pool internal definitions - */ - -#ifndef MEM_POOL_INTERNAL_H__ -#define MEM_POOL_INTERNAL_H__ - -#define TX_BUF_SIZE 600u /**< TX buffer size in bytes. */ -#define RX_BUF_SIZE TX_BUF_SIZE /**< RX buffer size in bytes. */ - -#define RX_BUF_QUEUE_SIZE 4u /**< RX buffer element size. */ - -#endif // MEM_POOL_INTERNAL_H__ - -/** @} */ diff --git a/components/libraries/hci/config/hci_transport_config.h b/components/libraries/hci/config/hci_transport_config.h deleted file mode 100644 index 86a55e3..0000000 --- a/components/libraries/hci/config/hci_transport_config.h +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/** @file - * - * @brief Definition of HCI Transport Layer configurable parameters - */ - -#ifndef HCI_TRANSPORT_CFG_H__ -#define HCI_TRANSPORT_CFG_H__ - -/** This section covers configurable parameters for the HCI Transport SLIP layer. */ -#define HCI_SLIP_UART_RX_PIN_NUMBER 1 /**< Defines the UART RX pin number. The default pin for the board is chosen, but can be overwritten. */ - -#define HCI_SLIP_UART_TX_PIN_NUMBER 2 /**< Defines the UART TX pin number. The default pin for the board is chosen, but can be overwritten. */ - -#define HCI_SLIP_UART_RTS_PIN_NUMBER 3 /**< Defines the UART RTS pin number. The default pin for the board is chosen, but can be overwritten. */ - -#define HCI_SLIP_UART_CTS_PIN_NUMBER 4 /**< Defines the UART CTS pin number. The default pin for the board is chosen, but can be overwritten. */ - -#define HCI_SLIP_UART_MODE APP_UART_FLOW_CONTROL_ENABLED /**< Defines the UART mode to be used. Use UART Low Power with Flow Control - Valid values are defined in \ref app_uart_flow_control_t. For further information on the UART Low Power mode, please refer to: \ref app_uart . */ - -#define HCI_SLIP_UART_BAUDRATE UART_BAUDRATE_BAUDRATE_Baud38400 /**< Defines the UART Baud rate. Default is 38400 baud. */ - -/** This section covers configurable parameters for the HCI Transport layer that are used for calculating correct value for the retransmission timer timeout. */ -#define MAX_PACKET_SIZE_IN_BITS 8000u /**< Maximum size of a single application packet in bits. */ -#define USED_BAUD_RATE 38400u /**< The used uart baudrate. */ - -#endif // HCI_TRANSPORT_CFG_H__ - -/** @} */ diff --git a/components/libraries/hci/hci_mem_pool.c b/components/libraries/hci/hci_mem_pool.c index 5213f32..8c686e7 100644 --- a/components/libraries/hci/hci_mem_pool.c +++ b/components/libraries/hci/hci_mem_pool.c @@ -1,80 +1,108 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HCI_MEM_POOL) #include "hci_mem_pool.h" -#include "hci_mem_pool_internal.h" #include #include -/**@brief RX buffer element instance structure. +/**@brief RX buffer element instance structure. */ -typedef struct +typedef struct { - uint8_t rx_buffer[RX_BUF_SIZE]; /**< RX buffer memory array. */ + uint8_t rx_buffer[HCI_RX_BUF_SIZE]; /**< RX buffer memory array. */ uint32_t length; /**< Length of the RX buffer memory array. */ } rx_buffer_elem_t; -/**@brief RX buffer queue element instance structure. +/**@brief RX buffer queue element instance structure. */ -typedef struct +typedef struct { rx_buffer_elem_t * p_buffer; /**< Pointer to RX buffer element. */ uint32_t free_window_count; /**< Free space element count. */ uint32_t free_available_count; /**< Free area element count. */ uint32_t read_available_count; /**< Read area element count. */ - uint32_t write_index; /**< Write position index. */ - uint32_t read_index; /**< Read position index. */ - uint32_t free_index; /**< Free position index. */ + uint32_t write_index; /**< Write position index. */ + uint32_t read_index; /**< Read position index. */ + uint32_t free_index; /**< Free position index. */ } rx_buffer_queue_t; static bool m_is_tx_allocated; /**< Boolean value to determine if the TX buffer is allocated. */ -static rx_buffer_elem_t m_rx_buffer_elem_queue[RX_BUF_QUEUE_SIZE]; /**< RX buffer element instances. */ +static rx_buffer_elem_t m_rx_buffer_elem_queue[HCI_RX_BUF_QUEUE_SIZE]; /**< RX buffer element instances. */ static rx_buffer_queue_t m_rx_buffer_queue; /**< RX buffer queue element instance. */ uint32_t hci_mem_pool_open(void) { - m_is_tx_allocated = false; + m_is_tx_allocated = false; m_rx_buffer_queue.p_buffer = m_rx_buffer_elem_queue; - m_rx_buffer_queue.free_window_count = RX_BUF_QUEUE_SIZE; + m_rx_buffer_queue.free_window_count = HCI_RX_BUF_QUEUE_SIZE; m_rx_buffer_queue.free_available_count = 0; m_rx_buffer_queue.read_available_count = 0; - m_rx_buffer_queue.write_index = 0; - m_rx_buffer_queue.read_index = 0; - m_rx_buffer_queue.free_index = 0; - + m_rx_buffer_queue.write_index = 0; + m_rx_buffer_queue.read_index = 0; + m_rx_buffer_queue.free_index = 0; + return NRF_SUCCESS; } uint32_t hci_mem_pool_close(void) -{ +{ return NRF_SUCCESS; } uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer) { - static uint8_t tx_buffer[TX_BUF_SIZE]; + static uint8_t tx_buffer[HCI_TX_BUF_SIZE]; uint32_t err_code; - + if (pp_buffer == NULL) { return NRF_ERROR_NULL; } - + if (!m_is_tx_allocated) - { + { m_is_tx_allocated = true; *pp_buffer = tx_buffer; err_code = NRF_SUCCESS; @@ -83,7 +111,7 @@ uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer) { err_code = NRF_ERROR_NO_MEM; } - + return err_code; } @@ -91,51 +119,51 @@ uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer) uint32_t hci_mem_pool_tx_free(void) { m_is_tx_allocated = false; - + return NRF_SUCCESS; } uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer) { - uint32_t err_code; + uint32_t err_code; if (pp_buffer == NULL) { return NRF_ERROR_NULL; - } + } *pp_buffer = NULL; - + if (m_rx_buffer_queue.free_window_count != 0) - { - if (length <= RX_BUF_SIZE) - { - --(m_rx_buffer_queue.free_window_count); - ++(m_rx_buffer_queue.read_available_count); + { + if (length <= HCI_RX_BUF_SIZE) + { + --(m_rx_buffer_queue.free_window_count); + ++(m_rx_buffer_queue.read_available_count); - *pp_buffer = + *pp_buffer = m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.write_index].rx_buffer; m_rx_buffer_queue.free_index |= (1u << m_rx_buffer_queue.write_index); - // @note: Adjust the write_index making use of the fact that the buffer size is of - // power of two and two's complement arithmetic. For details refer example to book + // @note: Adjust the write_index making use of the fact that the buffer size is of + // power of two and two's complement arithmetic. For details refer example to book // "Making embedded systems: Elicia White". - m_rx_buffer_queue.write_index = - (m_rx_buffer_queue.write_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); - + m_rx_buffer_queue.write_index = + (m_rx_buffer_queue.write_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u); + err_code = NRF_SUCCESS; } else { - err_code = NRF_ERROR_DATA_SIZE; - } + err_code = NRF_ERROR_DATA_SIZE; + } } else { - err_code = NRF_ERROR_NO_MEM; + err_code = NRF_ERROR_NO_MEM; } - + return err_code; } @@ -145,16 +173,16 @@ uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer) uint32_t err_code; uint32_t consume_index; uint32_t start_index; - + if (m_rx_buffer_queue.free_available_count != 0) { // Find the buffer that has been freed - // Start at read_index minus free_available_count and then increment until read index. err_code = NRF_ERROR_INVALID_ADDR; - consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) & - (RX_BUF_QUEUE_SIZE - 1u); + consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) & + (HCI_RX_BUF_QUEUE_SIZE - 1u); start_index = consume_index; - + do { if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer) @@ -165,36 +193,36 @@ uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer) } else { - consume_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); + consume_index = (consume_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u); } } while (consume_index != m_rx_buffer_queue.read_index); - while (!(m_rx_buffer_queue.free_index & (1 << start_index)) && + while (!(m_rx_buffer_queue.free_index & (1 << start_index)) && (m_rx_buffer_queue.free_available_count != 0)) { --(m_rx_buffer_queue.free_available_count); - ++(m_rx_buffer_queue.free_window_count); - start_index = (consume_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); + ++(m_rx_buffer_queue.free_window_count); + start_index = (consume_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u); } } else { err_code = NRF_ERROR_NO_MEM; } - - return err_code; + + return err_code; } uint32_t hci_mem_pool_rx_data_size_set(uint32_t length) { // @note: Adjust the write_index making use of the fact that the buffer size is of power - // of two and two's complement arithmetic. For details refer example to book + // of two and two's complement arithmetic. For details refer example to book // "Making embedded systems: Elicia White". - const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (RX_BUF_QUEUE_SIZE - 1u); - m_rx_buffer_queue.p_buffer[index].length = length; - + const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u); + m_rx_buffer_queue.p_buffer[index].length = length; + return NRF_SUCCESS; } @@ -202,34 +230,35 @@ uint32_t hci_mem_pool_rx_data_size_set(uint32_t length) uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length) { uint32_t err_code; - + if ((pp_buffer == NULL) || (p_length == NULL)) { return NRF_ERROR_NULL; } - + if (m_rx_buffer_queue.read_available_count != 0) { --(m_rx_buffer_queue.read_available_count); - ++(m_rx_buffer_queue.free_available_count); - - *pp_buffer = + ++(m_rx_buffer_queue.free_available_count); + + *pp_buffer = m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].rx_buffer; - *p_length = + *p_length = m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].length; - + // @note: Adjust the write_index making use of the fact that the buffer size is of power - // of two and two's complement arithmetic. For details refer example to book - // "Making embedded systems: Elicia White". - m_rx_buffer_queue.read_index = - (m_rx_buffer_queue.read_index + 1u) & (RX_BUF_QUEUE_SIZE - 1u); - + // of two and two's complement arithmetic. For details refer example to book + // "Making embedded systems: Elicia White". + m_rx_buffer_queue.read_index = + (m_rx_buffer_queue.read_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u); + err_code = NRF_SUCCESS; } else { - err_code = NRF_ERROR_NO_MEM; + err_code = NRF_ERROR_NO_MEM; } - + return err_code; } +#endif //NRF_MODULE_ENABLED(HCI_MEM_POOL) diff --git a/components/libraries/hci/hci_mem_pool.h b/components/libraries/hci/hci_mem_pool.h index bc178d0..3cd8d84 100644 --- a/components/libraries/hci/hci_mem_pool.h +++ b/components/libraries/hci/hci_mem_pool.h @@ -1,30 +1,58 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup memory_pool Memory pool + * @defgroup hci_mem_pool Memory pool * @{ * @ingroup app_common * * @brief Memory pool implementation * - * Memory pool implementation, based on circular buffer data structure, which supports asynchronous + * Memory pool implementation, based on circular buffer data structure, which supports asynchronous * processing of RX data. The current default implementation supports 1 TX buffer and 4 RX buffers. - * The memory managed by the pool is allocated from static storage instead of heap. The internal - * design of the circular buffer implementing the RX memory layout is illustrated in the picture - * below. + * The memory managed by the pool is allocated from static storage instead of heap. The internal + * design of the circular buffer implementing the RX memory layout is illustrated in the picture + * below. * - * @image html memory_pool.png "Circular buffer design" + * @image html memory_pool.svg "Circular buffer design" * * The expected call order for the RX APIs is as follows: * - hci_mem_pool_rx_produce @@ -37,26 +65,30 @@ * \par Component specific configuration options * * The following compile time configuration options are available to suit various implementations: - * - TX_BUF_SIZE TX buffer size in bytes. - * - RX_BUF_SIZE RX buffer size in bytes. + * - TX_BUF_SIZE TX buffer size in bytes. + * - RX_BUF_SIZE RX buffer size in bytes. * - RX_BUF_QUEUE_SIZE RX buffer element size. */ - + #ifndef HCI_MEM_POOL_H__ #define HCI_MEM_POOL_H__ #include #include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Function for opening the module. * - * @retval NRF_SUCCESS Operation success. + * @retval NRF_SUCCESS Operation success. */ uint32_t hci_mem_pool_open(void); /**@brief Function for closing the module. * - * @retval NRF_SUCCESS Operation success. + * @retval NRF_SUCCESS Operation success. */ uint32_t hci_mem_pool_close(void); @@ -66,37 +98,37 @@ uint32_t hci_mem_pool_close(void); * * @retval NRF_SUCCESS Operation success. Memory was allocated. * @retval NRF_ERROR_NO_MEM Operation failure. No memory available for allocation. - * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. */ uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer); - + /**@brief Function for freeing previously allocated TX memory. * - * @note Memory management follows the FIFO principle meaning that free() order must match the - * alloc(...) order, which is the reason for omitting exact memory block identifier as an + * @note Memory management follows the FIFO principle meaning that free() order must match the + * alloc(...) order, which is the reason for omitting exact memory block identifier as an * input parameter. * * @retval NRF_SUCCESS Operation success. Memory was freed. */ uint32_t hci_mem_pool_tx_free(void); - + /**@brief Function for producing a free RX memory block for usage. * - * @note Upon produce request amount being 0, NRF_SUCCESS is returned. + * @note Upon produce request amount being 0, NRF_SUCCESS is returned. * * @param[in] length Amount, in bytes, of free memory to be produced. * @param[out] pp_buffer Pointer to the allocated memory. * * @retval NRF_SUCCESS Operation success. Free RX memory block produced. * @retval NRF_ERROR_NO_MEM Operation failure. No suitable memory available for allocation. - * @retval NRF_ERROR_DATA_SIZE Operation failure. Request size exceeds limit. - * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Operation failure. Request size exceeds limit. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. */ uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer); /**@brief Function for setting the length of the last produced RX memory block. * - * @warning If call to this API is omitted the end result is that the following call to + * @warning If call to this API is omitted the end result is that the following call to * mem_pool_rx_extract will return incorrect data in the p_length output parameter. * * @param[in] length Amount, in bytes, of actual memory used. @@ -104,29 +136,34 @@ uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer); * @retval NRF_SUCCESS Operation success. Length was set. */ uint32_t hci_mem_pool_rx_data_size_set(uint32_t length); - -/**@brief Function for extracting a packet, which has been filled with read data, for further + +/**@brief Function for extracting a packet, which has been filled with read data, for further * processing. * * @param[out] pp_buffer Pointer to the packet data. - * @param[out] p_length Length of packet data in bytes. + * @param[out] p_length Length of packet data in bytes. * - * @retval NRF_SUCCESS Operation success. + * @retval NRF_SUCCESS Operation success. * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to extract. - * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. */ uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length); - + /**@brief Function for freeing previously extracted packet, which has been filled with read data. * * @param[in] p_buffer Pointer to consumed buffer. * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to free. - * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer. + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to free. + * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer. */ uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer); - + + +#ifdef __cplusplus +} +#endif + #endif // HCI_MEM_POOL_H__ - + /** @} */ diff --git a/components/libraries/hci/hci_slip.c b/components/libraries/hci/hci_slip.c index 2ef69c3..ca32633 100644 --- a/components/libraries/hci/hci_slip.c +++ b/components/libraries/hci/hci_slip.c @@ -1,18 +1,46 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HCI_SLIP) #include "hci_slip.h" #include -#include "hci_transport_config.h" #include "app_uart.h" #include "nrf_error.h" @@ -121,7 +149,7 @@ static uint32_t send_tx_byte_encoded(void) { uint32_t err_code; - switch(mp_tx_buffer[m_tx_buffer_index]) + switch (mp_tx_buffer[m_tx_buffer_index]) { case APP_SLIP_END: err_code = app_uart_put(APP_SLIP_ESC_END); @@ -333,19 +361,19 @@ static uint32_t slip_uart_open(void) app_uart_comm_params_t comm_params = { - HCI_SLIP_UART_RX_PIN_NUMBER, - HCI_SLIP_UART_TX_PIN_NUMBER, - HCI_SLIP_UART_RTS_PIN_NUMBER, - HCI_SLIP_UART_CTS_PIN_NUMBER, - HCI_SLIP_UART_MODE, + HCI_UART_RX_PIN, + HCI_UART_TX_PIN, + HCI_UART_RTS_PIN, + HCI_UART_CTS_PIN, + (app_uart_flow_control_t)HCI_UART_FLOW_CONTROL, false, - HCI_SLIP_UART_BAUDRATE + HCI_UART_BAUDRATE }; err_code = app_uart_init(&comm_params, NULL, slip_uart_eventhandler, - APP_IRQ_PRIORITY_LOW); + APP_IRQ_PRIORITY_LOWEST); if (err_code == NRF_SUCCESS) { @@ -426,3 +454,4 @@ uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length) handle_rx_byte = handle_rx_byte_wait_start; return NRF_SUCCESS; } +#endif //NRF_MODULE_ENABLED(HCI_SLIP) diff --git a/components/libraries/hci/hci_slip.h b/components/libraries/hci/hci_slip.h index ad26f3b..6cf0181 100644 --- a/components/libraries/hci/hci_slip.h +++ b/components/libraries/hci/hci_slip.h @@ -1,15 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * * @defgroup hci_slip SLIP module @@ -33,6 +61,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Event types from the SLIP Layer. */ typedef enum { @@ -59,7 +91,7 @@ typedef void (*hci_slip_event_handler_t)(hci_slip_evt_t event); /**@brief Function for registering the event handler provided as parameter and this event handler * will be used by SLIP layer to send events described in \ref hci_slip_evt_type_t. * - * @note Multiple registration requests will overwrite any existing registration. + * @note Multiple registration requests will overwrite any existing registration. * * @param[in] event_handler This function is called by the SLIP layer upon an event. * @@ -70,8 +102,8 @@ uint32_t hci_slip_evt_handler_register(hci_slip_event_handler_t event_handler); /**@brief Function for opening the SLIP layer. This function must be called before * \ref hci_slip_write and before any data can be received. * - * @note Can be called multiple times. - * + * @note Can be called multiple times. + * * @retval NRF_SUCCESS Operation success. * * The SLIP layer module will propagate errors from underlying sub-modules. @@ -84,8 +116,8 @@ uint32_t hci_slip_open(void); * transmitted or received in this layer. * * @note This function can be called multiple times and also for an unopened channel. - * - * @retval NRF_SUCCESS Operation success. + * + * @retval NRF_SUCCESS Operation success. */ uint32_t hci_slip_close(void); @@ -95,8 +127,8 @@ uint32_t hci_slip_close(void); * @param[in] p_buffer Pointer to the packet to transmit. * @param[in] length Packet length, in bytes. * - * @retval NRF_SUCCESS Operation success. Packet was encoded and added to the - * transmission queue and an event will be sent upon transmission + * @retval NRF_SUCCESS Operation success. Packet was encoded and added to the + * transmission queue and an event will be sent upon transmission * completion. * @retval NRF_ERROR_NO_MEM Operation failure. Transmission queue is full and packet was not * added to the transmission queue. Application shall wait for @@ -120,10 +152,15 @@ uint32_t hci_slip_write(const uint8_t * p_buffer, uint32_t length); * will be placed in this buffer. * @param[in] length Buffer length, in bytes. * - * @retval NRF_SUCCESS Operation success. + * @retval NRF_SUCCESS Operation success. */ uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length); - + + +#ifdef __cplusplus +} +#endif + #endif // HCI_SLIP_H__ - + /** @} */ diff --git a/components/libraries/hci/hci_transport.c b/components/libraries/hci/hci_transport.c index 0d68fd4..192d17b 100644 --- a/components/libraries/hci/hci_transport.c +++ b/components/libraries/hci/hci_transport.c @@ -1,28 +1,51 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - -#include "hci_transport_config.h" +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(HCI_TRANSPORT) #include "hci_transport.h" #include "hci_slip.h" #include "crc16.h" #include "hci_mem_pool.h" -#include "hci_mem_pool_internal.h" -#include "nordic_common.h" -#include "compiler_abstraction.h" -#include "app_util.h" #include "app_timer.h" #include "app_error.h" #include -#include #define PKT_HDR_SIZE 4u /**< Packet header size in number of bytes. */ #define PKT_CRC_SIZE 2u /**< Packet CRC size in number of bytes. */ @@ -33,17 +56,20 @@ #define INITIAL_ACK_NUMBER_EXPECTED 1u /**< Initial acknowledge number expected. */ #define INITIAL_ACK_NUMBER_TX INITIAL_ACK_NUMBER_EXPECTED /**< Initial acknowledge number transmitted. */ #define INVALID_PKT_TYPE 0xFFFFFFFFu /**< Internal invalid packet type value. */ -#define MAX_TRANSMISSION_TIME (ROUNDED_DIV((MAX_PACKET_SIZE_IN_BITS * 1000u), USED_BAUD_RATE)) /**< Max transmission time of a single application packet over UART in units of mseconds. */ -#define RETRANSMISSION_TIMEOUT_IN_MS (3u * MAX_TRANSMISSION_TIME) /**< Retransmission timeout for application packet in units of mseconds. */ +#define HCI_UART_REG_VALUE_TO_BAUDRATE(BAUDRATE) ((BAUDRATE)/268) /**< Estimated relation between UART baudrate register value and actual baudrate */ +#define MAX_TRANSMISSION_TIME \ + (ROUNDED_DIV((HCI_MAX_PACKET_SIZE_IN_BITS * 1000u), \ + HCI_UART_REG_VALUE_TO_BAUDRATE(HCI_UART_BAUDRATE))) /**< Max transmission time of a single application packet over UART in units of mseconds. */ +#define RETRANSMISSION_TIMEOUT_IN_MS (3u * MAX_TRANSMISSION_TIME) /**< Retransmission timeout for application packet in units of mseconds. */ #define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ -#define RETRANSMISSION_TIMEOUT_IN_TICKS APP_TIMER_TICKS(RETRANSMISSION_TIMEOUT_IN_MS, APP_TIMER_PRESCALER) /**< Retransmission timeout for application packet in units of timer ticks. */ +#define RETRANSMISSION_TIMEOUT_IN_TICKS APP_TIMER_TICKS(RETRANSMISSION_TIMEOUT_IN_MS, APP_TIMER_PRESCALER) /**< Retransmission timeout for application packet in units of timer ticks. */ #define MAX_RETRY_COUNT 5u /**< Max retransmission retry count for application packets. */ #define ACK_BUF_SIZE 5u /**< Length of module internal RX buffer which is big enough to hold an acknowledgement packet. */ /**@brief States of the TX state machine. */ typedef enum { - TX_STATE_IDLE, /**< State for: no application transmission packet processing in progress. */ + TX_STATE_IDLE, /**< State for: no application transmission packet processing in progress. */ TX_STATE_PENDING, /**< State for: TX in progress in slip layer and TX-done event is waited for to signal the end of transmission. */ TX_STATE_ACTIVE /**< State for: application packet has been delivered to slip for transmission and peer transport entity acknowledgement packet is waited for. */ } tx_state_t; @@ -51,7 +77,7 @@ typedef enum /**@brief TX state machine events. */ typedef enum { - TX_EVENT_STATE_ENTRY, /**< Event for: state entry use case. */ + TX_EVENT_STATE_ENTRY, /**< Event for: state entry use case. */ TX_EVENT_SLIP_TX_DONE, /**< Event for: HCI_SLIP_TX_DONE event use case. */ TX_EVENT_TIMEOUT, /**< Event for: retransmission timeout use case. */ TX_EVENT_VALID_RX_ACK /**< Event for: valid acknowledgement received for TX packet use case. */ @@ -63,8 +89,8 @@ static tx_state_t m_tx_state; /**< Curren static hci_transport_tx_done_handler_t m_transport_tx_done_handle; /**< TX done event callback function. */ static hci_transport_event_handler_t m_transport_event_handle; /**< Event handler callback function. */ static uint8_t * mp_slip_used_rx_buffer; /**< Reference to RX buffer used by the slip layer. */ -static uint32_t m_packet_expected_seq_number; /**< Sequence number counter of the packet expected to be received . */ -static uint32_t m_packet_transmit_seq_number; /**< Sequence number counter of the transmitted packet for which acknowledgement packet is waited for. */ +static uint32_t m_packet_expected_seq_number; /**< Sequence number counter of the packet expected to be received . */ +static uint32_t m_packet_transmit_seq_number; /**< Sequence number counter of the transmitted packet for which acknowledgement packet is waited for. */ static uint8_t * mp_tx_buffer; /**< Pointer to TX application buffer to be transmitted. */ static uint32_t m_tx_buffer_length; /**< Length of application TX packet data to be transmitted in bytes. */ static bool m_is_slip_decode_ready; /**< Boolean to determine has slip decode been completed or not. */ @@ -77,12 +103,12 @@ static uint8_t m_rx_ack_buffer[ACK_BUF_SIZE];/**< RX buf /**@brief Function for validating a received packet. * * @param[in] p_buffer Pointer to the packet data. - * @param[in] length Length of packet data in bytes. + * @param[in] length Length of packet data in bytes. * * @return true if received packet is valid, false in other case. */ static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length) -{ +{ // Executed packet filtering algorithm order: // - verify packet overall length // - verify data integrity bit set @@ -93,38 +119,38 @@ static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length) // - verify CRC if (length <= PKT_HDR_SIZE) { - return false; + return false; } - + if (!(p_buffer[0] & DATA_INTEGRITY_MASK)) { return false; - } - + } + if (!(p_buffer[0] & RELIABLE_PKT_MASK)) { return false; - } - + } + if ((p_buffer[1] & 0x0Fu) != PKT_TYPE_VENDOR_SPECIFIC) - { - return false; + { + return false; } - - const uint32_t expected_checksum = + + const uint32_t expected_checksum = ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu; if (expected_checksum != 0) - { + { return false; } - + const uint16_t crc_calculated = crc16_compute(p_buffer, (length - PKT_CRC_SIZE), NULL); const uint16_t crc_received = uint16_decode(&p_buffer[length - PKT_CRC_SIZE]); if (crc_calculated != crc_received) { return false; } - + return true; } @@ -134,7 +160,7 @@ static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length) * @return sequence number of the next reliable packet expected. */ static __INLINE uint8_t packet_number_expected_get(void) -{ +{ return (uint8_t) m_packet_expected_seq_number; } @@ -149,13 +175,13 @@ static uint8_t header_checksum_calculate(const uint8_t * p_hdr) { // @note: no pointer validation check needed as already checked by calling function. uint32_t checksum; - - checksum = p_hdr[0]; - checksum += p_hdr[1]; - checksum += p_hdr[2]; + + checksum = p_hdr[0]; + checksum += p_hdr[1]; + checksum += p_hdr[2]; checksum &= 0xFFu; checksum = (~checksum + 1u); - + return (uint8_t)checksum; } @@ -165,31 +191,31 @@ static uint8_t header_checksum_calculate(const uint8_t * p_hdr) static void ack_transmit(void) { static uint8_t ack_packet[PKT_HDR_SIZE]; - + // TX ACK packet format: // - Unreliable Packet type // - Payload Length set to 0 // - Sequence Number set to 0 // - Header checksum calculated - // - Acknowledge Number set correctly + // - Acknowledge Number set correctly ack_packet[0] = (packet_number_expected_get() << 3u); - ack_packet[1] = 0; - ack_packet[2] = 0; - ack_packet[3] = header_checksum_calculate(ack_packet); + ack_packet[1] = 0; + ack_packet[2] = 0; + ack_packet[3] = header_checksum_calculate(ack_packet); - // @note: no return value check needed for hci_slip_write(...) call as acknowledgement packets - // are considered to be from system design point of view unreliable packets.Use case where + // @note: no return value check needed for hci_slip_write(...) call as acknowledgement packets + // are considered to be from system design point of view unreliable packets.Use case where // underlying slip layer does not accept a packet for transmission is managed either by: - // - acknowledged by possible future application packet as acknowledgement number header field - // is included - // - protocol peer entity will retransmit the packet - UNUSED_VARIABLE(hci_slip_write(ack_packet, sizeof(ack_packet))); + // - acknowledged by possible future application packet as acknowledgement number header field + // is included + // - protocol peer entity will retransmit the packet + UNUSED_VARIABLE(hci_slip_write(ack_packet, sizeof(ack_packet))); } /**@brief Function for validating a received packet. * - * @param[in] p_buffer Pointer to the packet data. + * @param[in] p_buffer Pointer to the packet data. * * @return sequence number field of the packet header with unrelated data masked out. */ @@ -204,14 +230,14 @@ static __INLINE uint8_t packet_seq_nmbr_extract(const uint8_t * p_buffer) static __INLINE void packet_number_expected_inc(void) { ++m_packet_expected_seq_number; - m_packet_expected_seq_number &= 0x07u; + m_packet_expected_seq_number &= 0x07u; } /**@brief Function for decoding a packet type field. * - * @param[in] p_buffer Pointer to the packet data. - * @param[in] length Length of packet data in bytes. + * @param[in] p_buffer Pointer to the packet data. + * @param[in] length Length of packet data in bytes. * * @return Packet type field or INVALID_PKT_TYPE in case of decode error. */ @@ -219,30 +245,30 @@ static __INLINE uint32_t packet_type_decode(const uint8_t * p_buffer, uint32_t l { // @note: no pointer validation check needed as allready checked by calling function. uint32_t return_value; - + if (length >= PKT_HDR_SIZE) { return_value = (p_buffer[1] & 0x0Fu); - } + } else { return_value = INVALID_PKT_TYPE; - } - + } + return return_value; } /**@brief Function for processing a received vendor specific packet. * - * @param[in] p_buffer Pointer to the packet data. - * @param[in] length Length of packet data in bytes. + * @param[in] p_buffer Pointer to the packet data. + * @param[in] length Length of packet data in bytes. */ static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_t length) { // @note: no pointer validation check needed as allready checked by calling function. uint32_t err_code; - + if (is_rx_pkt_valid(p_buffer, length)) { // RX packet is valid: validate sequence number. @@ -250,40 +276,40 @@ static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_ if (packet_number_expected_get() == rx_seq_number) { // Sequence number is valid: transmit acknowledgement. - packet_number_expected_inc(); - ack_transmit(); + packet_number_expected_inc(); + ack_transmit(); + + m_is_slip_decode_ready = true; - m_is_slip_decode_ready = true; - err_code = hci_mem_pool_rx_data_size_set(length); APP_ERROR_CHECK(err_code); - err_code = hci_mem_pool_rx_produce(RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer); + err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer); APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM)); - // If memory pool RX buffer produce succeeded we register that buffer to slip layer - // otherwise we register the internal acknowledgement buffer. + // If memory pool RX buffer produce succeeded we register that buffer to slip layer + // otherwise we register the internal acknowledgement buffer. err_code = hci_slip_rx_buffer_register( - (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer, - (err_code == NRF_SUCCESS) ? RX_BUF_SIZE : ACK_BUF_SIZE); + (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer, + (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE); + + APP_ERROR_CHECK(err_code); - APP_ERROR_CHECK(err_code); - if (m_transport_event_handle != NULL) { // Send application event of RX packet reception. const hci_transport_evt_t evt = {HCI_TRANSPORT_RX_RDY}; m_transport_event_handle(evt); - } + } } else { - // RX packet discarded: sequence number not valid, set the same buffer to slip layer in - // order to avoid buffer overrun. - err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, RX_BUF_SIZE); - APP_ERROR_CHECK(err_code); - - // As packet did not have expected sequence number: send acknowledgement with the + // RX packet discarded: sequence number not valid, set the same buffer to slip layer in + // order to avoid buffer overrun. + err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE); + APP_ERROR_CHECK(err_code); + + // As packet did not have expected sequence number: send acknowledgement with the // current expected sequence number. ack_transmit(); } @@ -291,14 +317,14 @@ static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_ else { // RX packet discarded: reset the same buffer to slip layer in order to avoid buffer - // overrun. - err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, RX_BUF_SIZE); - APP_ERROR_CHECK(err_code); - } + // overrun. + err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE); + APP_ERROR_CHECK(err_code); + } } -/**@brief Function for getting the sequence number of a reliable TX packet for which peer protocol +/**@brief Function for getting the sequence number of a reliable TX packet for which peer protocol * entity acknowledgment is pending. * * @return sequence number of a reliable TX packet for which peer protocol entity acknowledgement @@ -316,43 +342,43 @@ static __INLINE uint8_t packet_number_to_transmit_get(void) */ static __INLINE uint8_t expected_ack_number_get(void) { - uint8_t seq_nmbr = packet_number_to_transmit_get(); + uint8_t seq_nmbr = packet_number_to_transmit_get(); ++seq_nmbr; seq_nmbr &= 0x07u; - + return seq_nmbr; } /**@brief Function for processing a received acknowledgement packet. * - * Verifies does the received acknowledgement packet has the expected acknowledgement number and - * that the header checksum is correct. + * Verifies does the received acknowledgement packet has the expected acknowledgement number and + * that the header checksum is correct. * - * @param[in] p_buffer Pointer to the packet data. + * @param[in] p_buffer Pointer to the packet data. * * @return true if valid acknowledgement packet received. */ static __INLINE bool rx_ack_pkt_type_handle(const uint8_t * p_buffer) { // @note: no pointer validation check needed as allready checked by calling function. - + // Verify header checksum. - const uint32_t expected_checksum = + const uint32_t expected_checksum = ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu; if (expected_checksum != 0) - { + { return false; } - + const uint8_t ack_number = (p_buffer[0] >> 3u) & 0x07u; - + // Verify expected acknowledgment number. return (ack_number == expected_ack_number_get()); } -/**@brief Function for incrementing the sequence number counter of the TX packet. +/**@brief Function for incrementing the sequence number counter of the TX packet. */ static __INLINE void packet_number_tx_inc(void) { @@ -368,84 +394,84 @@ static __INLINE void packet_number_tx_inc(void) static void tx_sm_event_handle(tx_event_t event) { uint32_t err_code; - + switch (m_tx_state) { case TX_STATE_IDLE: if (event == TX_EVENT_STATE_ENTRY) - { + { err_code = app_timer_stop(m_app_timer_id); APP_ERROR_CHECK(err_code); - + // Send TX-done event if registered handler exists. - if (m_transport_tx_done_handle != NULL) + if (m_transport_tx_done_handle != NULL) { m_transport_tx_done_handle(m_tx_done_result_code); - } + } } break; - + case TX_STATE_PENDING: if (event == TX_EVENT_SLIP_TX_DONE) - { - // @note: this call should always succeed as called from HCI_SLIP_TX_DONE context + { + // @note: this call should always succeed as called from HCI_SLIP_TX_DONE context // and error cases are managed by dedicated error event from the slip layer. - err_code = hci_slip_write(mp_tx_buffer, - (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE)); - APP_ERROR_CHECK(err_code); - tx_sm_state_change(TX_STATE_ACTIVE); - } + err_code = hci_slip_write(mp_tx_buffer, + (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE)); + APP_ERROR_CHECK(err_code); + tx_sm_state_change(TX_STATE_ACTIVE); + } break; - + case TX_STATE_ACTIVE: switch (event) { - case TX_EVENT_VALID_RX_ACK: - // Tx sequence number counter incremented as packet transmission + case TX_EVENT_VALID_RX_ACK: + // Tx sequence number counter incremented as packet transmission // acknowledged by peer transport entity. - packet_number_tx_inc(); + packet_number_tx_inc(); tx_sm_state_change(TX_STATE_IDLE); break; - + case TX_EVENT_STATE_ENTRY: m_tx_retry_counter = 0; - err_code = app_timer_start(m_app_timer_id, - RETRANSMISSION_TIMEOUT_IN_TICKS, + err_code = app_timer_start(m_app_timer_id, + RETRANSMISSION_TIMEOUT_IN_TICKS, NULL); APP_ERROR_CHECK(err_code); break; - + case TX_EVENT_TIMEOUT: if (m_tx_retry_counter != MAX_RETRY_COUNT) { ++m_tx_retry_counter; - // @note: no return value check done for hci_slip_write(...) call as current - // system design allows use case where retransmission is not accepted by the - // slip layer due to existing acknowledgement packet transmission in the - // slip layer. - UNUSED_VARIABLE(hci_slip_write(mp_tx_buffer, - (m_tx_buffer_length + - PKT_HDR_SIZE + - PKT_CRC_SIZE))); - } + // @note: no return value check done for hci_slip_write(...) call as current + // system design allows use case where retransmission is not accepted by the + // slip layer due to existing acknowledgement packet transmission in the + // slip layer. + UNUSED_VARIABLE(hci_slip_write(mp_tx_buffer, + (m_tx_buffer_length + + PKT_HDR_SIZE + + PKT_CRC_SIZE))); + } else { - // Application packet retransmission count reached: + // Application packet retransmission count reached: // - set correct TX done event callback function result code - // - execute state change + // - execute state change // @note: m_tx_retry_counter is reset in TX_STATE_ACTIVE state entry. - m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE; + m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE; tx_sm_state_change(TX_STATE_IDLE); - } + } break; - + default: // No implementation needed. break; } break; - - default: + + default: // No implementation needed. break; } @@ -468,73 +494,73 @@ static void tx_sm_state_change(tx_state_t new_state) * @param[in] event The event structure. */ void slip_event_handle(hci_slip_evt_t event) -{ +{ uint32_t return_code; - uint32_t err_code; - + uint32_t err_code; + switch (event.evt_type) { - case HCI_SLIP_TX_DONE: + case HCI_SLIP_TX_DONE: tx_sm_event_handle(TX_EVENT_SLIP_TX_DONE); break; - + case HCI_SLIP_RX_RDY: return_code = packet_type_decode(event.packet, event.packet_length); - + switch (return_code) { case PKT_TYPE_VENDOR_SPECIFIC: rx_vendor_specific_pkt_type_handle(event.packet, event.packet_length); break; - + case PKT_TYPE_ACK: if (rx_ack_pkt_type_handle(event.packet)) { - // Valid expected acknowledgement packet received: set correct TX done event + // Valid expected acknowledgement packet received: set correct TX done event // callback function result code and execute state change. - m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_SUCCESS; + m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_SUCCESS; tx_sm_event_handle(TX_EVENT_VALID_RX_ACK); } - - /* fall-through */ + + /* fall-through */ default: - // RX packet dropped: reset memory buffer to slip in order to avoid RX buffer - // overflow. - // If existing mem pool produced RX buffer exists reuse that one. If existing - // mem pool produced RX buffer does not exist try to produce new one. If - // producing fails use the internal acknowledgement buffer. + // RX packet dropped: reset memory buffer to slip in order to avoid RX buffer + // overflow. + // If existing mem pool produced RX buffer exists reuse that one. If existing + // mem pool produced RX buffer does not exist try to produce new one. If + // producing fails use the internal acknowledgement buffer. if (mp_slip_used_rx_buffer != NULL) { - err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, RX_BUF_SIZE); - APP_ERROR_CHECK(err_code); + err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE); + APP_ERROR_CHECK(err_code); } else { - err_code = hci_mem_pool_rx_produce(RX_BUF_SIZE, - (void **)&mp_slip_used_rx_buffer); - APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || + err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, + (void **)&mp_slip_used_rx_buffer); + APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM)); err_code = hci_slip_rx_buffer_register( - (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer, - (err_code == NRF_SUCCESS) ? RX_BUF_SIZE : ACK_BUF_SIZE); - APP_ERROR_CHECK(err_code); + (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer, + (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE); + APP_ERROR_CHECK(err_code); } break; } break; case HCI_SLIP_RX_OVERFLOW: - err_code = hci_slip_rx_buffer_register(m_rx_ack_buffer, ACK_BUF_SIZE); - APP_ERROR_CHECK(err_code); + err_code = hci_slip_rx_buffer_register(m_rx_ack_buffer, ACK_BUF_SIZE); + APP_ERROR_CHECK(err_code); break; - + case HCI_SLIP_ERROR: APP_ERROR_HANDLER(event.evt_type); break; - + default: - APP_ERROR_HANDLER(event.evt_type); + APP_ERROR_HANDLER(event.evt_type); break; } } @@ -542,36 +568,36 @@ void slip_event_handle(hci_slip_evt_t event) uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler) { - uint32_t err_code; - + uint32_t err_code; + m_transport_event_handle = event_handler; - err_code = hci_slip_evt_handler_register(slip_event_handle); - APP_ERROR_CHECK(err_code); - - return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL; + err_code = hci_slip_evt_handler_register(slip_event_handle); + APP_ERROR_CHECK(err_code); + + return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL; } uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler) { - uint32_t err_code; - + uint32_t err_code; + m_transport_tx_done_handle = event_handler; - err_code = hci_slip_evt_handler_register(slip_event_handle); - APP_ERROR_CHECK(err_code); - - return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL; + err_code = hci_slip_evt_handler_register(slip_event_handle); + APP_ERROR_CHECK(err_code); + + return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL; } /**@brief Function for handling the application packet retransmission timeout. - * - * This function is registered in the @ref app_timer module when a timer is created on - * @ref hci_transport_open. * - * @note This function must be executed in APP-LO context otherwise retransmission behaviour is + * This function is registered in the @ref app_timer module when a timer is created on + * @ref hci_transport_open. + * + * @note This function must be executed in APP-LO context otherwise retransmission behaviour is * undefined, see @ref nrf51_system_integration_serialization. - * + * * @param[in] p_context The timeout context. */ void hci_transport_timeout_handle(void * p_context) @@ -590,38 +616,32 @@ uint32_t hci_transport_open(void) m_packet_expected_seq_number = INITIAL_ACK_NUMBER_EXPECTED; m_packet_transmit_seq_number = INITIAL_ACK_NUMBER_TX; m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE; - - uint32_t err_code = app_timer_create(&m_app_timer_id, - APP_TIMER_MODE_REPEATED, + + uint32_t err_code = app_timer_create(&m_app_timer_id, + APP_TIMER_MODE_REPEATED, hci_transport_timeout_handle); if (err_code != NRF_SUCCESS) - { + { // @note: conduct required interface adjustment. return NRF_ERROR_INTERNAL; } - + err_code = hci_mem_pool_open(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - + VERIFY_SUCCESS(err_code); + err_code = hci_slip_open(); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - err_code = hci_mem_pool_rx_produce(RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer); + VERIFY_SUCCESS(err_code); + + err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer); if (err_code != NRF_SUCCESS) { // @note: conduct required interface adjustment. return NRF_ERROR_INTERNAL; - } - - err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, RX_BUF_SIZE); - - return err_code; + } + + err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE); + + return err_code; } @@ -631,31 +651,31 @@ uint32_t hci_transport_close(void) m_transport_tx_done_handle = NULL; m_transport_event_handle = NULL; - + err_code = hci_mem_pool_close(); - APP_ERROR_CHECK(err_code); + APP_ERROR_CHECK(err_code); err_code = hci_slip_close(); - APP_ERROR_CHECK(err_code); - + APP_ERROR_CHECK(err_code); + // @note: NRF_ERROR_NO_MEM is the only return value which should never be returned. err_code = app_timer_stop(m_app_timer_id); APP_ERROR_CHECK_BOOL(err_code != NRF_ERROR_NO_MEM); - + return NRF_SUCCESS; -} +} uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory) { - const uint32_t err_code = hci_mem_pool_tx_alloc((void **)pp_memory); + const uint32_t err_code = hci_mem_pool_tx_alloc((void **)pp_memory); if (err_code == NRF_SUCCESS) { - // @note: no need to validate pp_memory against null as validation has already been done + // @note: no need to validate pp_memory against null as validation has already been done // by hci_mem_pool_tx_alloc(...) and visible to us from the method return code. - //lint -e(413) "Likely use of null pointer" - *pp_memory += PKT_HDR_SIZE; + //lint -e(413) "Likely use of null pointer" + *pp_memory += PKT_HDR_SIZE; } - + return err_code; } @@ -672,11 +692,11 @@ uint32_t hci_transport_tx_free(void) */ static __INLINE uint8_t tx_packet_byte_zero_construct(void) { - const uint32_t value = DATA_INTEGRITY_MASK | - RELIABLE_PKT_MASK | - (packet_number_expected_get() << 3u) | - packet_number_to_transmit_get(); - + const uint32_t value = DATA_INTEGRITY_MASK | + RELIABLE_PKT_MASK | + (packet_number_expected_get() << 3u) | + packet_number_to_transmit_get(); + return (uint8_t) value; } @@ -684,41 +704,41 @@ static __INLINE uint8_t tx_packet_byte_zero_construct(void) /**@brief Function for handling the application packet write request in tx-idle state. */ static uint32_t pkt_write_handle(void) -{ - uint32_t err_code; - +{ + uint32_t err_code; + // Set packet header fields. mp_tx_buffer -= PKT_HDR_SIZE; mp_tx_buffer[0] = tx_packet_byte_zero_construct(); - - const uint16_t type_and_length_fields = ((m_tx_buffer_length << 4u) | PKT_TYPE_VENDOR_SPECIFIC); + + const uint16_t type_and_length_fields = ((m_tx_buffer_length << 4u) | PKT_TYPE_VENDOR_SPECIFIC); // @note: no use case for uint16_encode(...) return value. UNUSED_VARIABLE(uint16_encode(type_and_length_fields, &(mp_tx_buffer[1]))); mp_tx_buffer[3] = header_checksum_calculate(mp_tx_buffer); - + // Calculate, append CRC to the packet and write it. - + const uint16_t crc = crc16_compute(mp_tx_buffer, (PKT_HDR_SIZE + m_tx_buffer_length), NULL); // @note: no use case for uint16_encode(...) return value. - UNUSED_VARIABLE(uint16_encode(crc, &(mp_tx_buffer[PKT_HDR_SIZE + m_tx_buffer_length]))); - err_code = hci_slip_write(mp_tx_buffer, (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE)); + UNUSED_VARIABLE(uint16_encode(crc, &(mp_tx_buffer[PKT_HDR_SIZE + m_tx_buffer_length]))); + err_code = hci_slip_write(mp_tx_buffer, (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE)); switch (err_code) { case NRF_SUCCESS: tx_sm_state_change(TX_STATE_ACTIVE); break; - + case NRF_ERROR_NO_MEM: - tx_sm_state_change(TX_STATE_PENDING); + tx_sm_state_change(TX_STATE_PENDING); err_code = NRF_SUCCESS; break; - + default: // No implementation needed. break; } - + return err_code; } @@ -726,17 +746,17 @@ static uint32_t pkt_write_handle(void) uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length) { uint32_t err_code; - + if (p_buffer) - { + { switch (m_tx_state) { case TX_STATE_IDLE: mp_tx_buffer = (uint8_t *)p_buffer; - m_tx_buffer_length = length; + m_tx_buffer_length = length; err_code = pkt_write_handle(); break; - + default: err_code = NRF_ERROR_NO_MEM; break; @@ -746,26 +766,26 @@ uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length) { err_code = NRF_ERROR_NULL; } - - return err_code; + + return err_code; } uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length) { uint32_t err_code; - + if (pp_buffer != NULL && p_length != NULL) { - uint32_t length = 0; - + uint32_t length = 0; + if (m_is_slip_decode_ready) { m_is_slip_decode_ready = false; err_code = hci_mem_pool_rx_extract(pp_buffer, &length); length -= (PKT_HDR_SIZE + PKT_CRC_SIZE); - - *p_length = (uint16_t)length; + + *p_length = (uint16_t)length; *pp_buffer += PKT_HDR_SIZE; } else @@ -777,12 +797,13 @@ uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length) { err_code = NRF_ERROR_NULL; } - + return err_code; } uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer) { - return (hci_mem_pool_rx_consume(p_buffer - PKT_HDR_SIZE)); + return (hci_mem_pool_rx_consume(p_buffer - PKT_HDR_SIZE)); } +#endif //NRF_MODULE_ENABLED(HCI_TRANSPORT) diff --git a/components/libraries/hci/hci_transport.h b/components/libraries/hci/hci_transport.h index 965cfd8..a0f6d60 100644 --- a/components/libraries/hci/hci_transport.h +++ b/components/libraries/hci/hci_transport.h @@ -1,15 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * * @defgroup hci_transport HCI Transport @@ -18,7 +46,7 @@ * * @brief HCI transport module implementation. * - * This module implements certain specific features from the three-wire UART transport layer, + * This module implements certain specific features from the three-wire UART transport layer, * defined by the Bluetooth specification version 4.0 [Vol 4] part D. * * \par Features supported @@ -27,7 +55,7 @@ * * \par Features not supported * - Link establishment procedure: defined by chapter 8 of the specification. - * - Low power: defined by chapter 9 of the specification. + * - Low power: defined by chapter 9 of the specification. * * \par Implementation specific behaviour * - As Link establishment procedure is not supported following static link configuration parameters @@ -35,54 +63,58 @@ * + TX window size is 1. * + 16 bit CCITT-CRC must be used. * + Out of frame software flow control not supported. - * + Parameters specific for resending reliable packets are compile time configurable (clarifed + * + Parameters specific for resending reliable packets are compile time configurable (clarifed * later in this document). - * + Acknowledgement packet transmissions are not timeout driven , meaning they are delivered for - * transmission within same context which the corresponding application packet was received. + * + Acknowledgement packet transmissions are not timeout driven , meaning they are delivered for + * transmission within same context which the corresponding application packet was received. * * \par Implementation specific limitations - * Current implementation has the following limitations which will have impact to system wide + * Current implementation has the following limitations which will have impact to system wide * behaviour: - * - Delayed acknowledgement scheduling not implemented: - * There exists a possibility that acknowledgement TX packet and application TX packet will collide - * in the TX pipeline having the end result that acknowledgement packet will be excluded from the TX + * - Delayed acknowledgement scheduling not implemented: + * There exists a possibility that acknowledgement TX packet and application TX packet will collide + * in the TX pipeline having the end result that acknowledgement packet will be excluded from the TX * pipeline which will trigger the retransmission algorithm within the peer protocol entity. - * - Delayed retransmission scheduling not implemented: + * - Delayed retransmission scheduling not implemented: * There exists a possibility that retransmitted application TX packet and acknowledgement TX packet - * will collide in the TX pipeline having the end result that retransmitted application TX packet + * will collide in the TX pipeline having the end result that retransmitted application TX packet * will be excluded from the TX pipeline. * - Processing of the acknowledgement number from RX application packets: - * Acknowledgement number is not processed from the RX application packets having the end result + * Acknowledgement number is not processed from the RX application packets having the end result * that unnecessary application packet retransmissions can occur. * - * The application TX packet processing flow is illustrated by the statemachine below. + * The application TX packet processing flow is illustrated by the statemachine below. * - * @image html hci_transport_tx_sm.png "TX - application packet statemachine" + * @image html hci_transport_tx_sm.svg "TX - application packet statemachine" * * \par Component specific configuration options * - * The following compile time configuration options are available, and used to configure the - * application TX packet retransmission interval, in order to suite various application specific + * The following compile time configuration options are available, and used to configure the + * application TX packet retransmission interval, in order to suite various application specific * implementations: - * - MAC_PACKET_SIZE_IN_BITS Maximum size of a single application packet in bits. - * - USED_BAUD_RATE Used uart baudrate. + * - MAC_PACKET_SIZE_IN_BITS Maximum size of a single application packet in bits. + * - USED_BAUD_RATE Used uart baudrate. * - * The following compile time configuration option is available to configure module specific + * The following compile time configuration option is available to configure module specific * behaviour: * - MAX_RETRY_COUNT Max retransmission retry count for applicaton packets. */ - + #ifndef HCI_TRANSPORT_H__ #define HCI_TRANSPORT_H__ #include #include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Generic event callback function events. */ typedef enum { HCI_TRANSPORT_RX_RDY, /**< An event indicating that RX packet is ready for read. */ - HCI_TRANSPORT_EVT_TYPE_MAX /**< Enumeration upper bound. */ + HCI_TRANSPORT_EVT_TYPE_MAX /**< Enumeration upper bound. */ } hci_transport_evt_type_t; /**@brief Struct containing events from the Transport layer. @@ -94,7 +126,7 @@ typedef struct /**@brief Transport layer generic event callback function type. * - * @param[in] event Transport layer event. + * @param[in] event Transport layer event. */ typedef void (*hci_transport_event_handler_t)(hci_transport_evt_t event); @@ -102,104 +134,104 @@ typedef void (*hci_transport_event_handler_t)(hci_transport_evt_t event); typedef enum { HCI_TRANSPORT_TX_DONE_SUCCESS, /**< Transmission success, peer transport entity has acknowledged the transmission. */ - HCI_TRANSPORT_TX_DONE_FAILURE /**< Transmission failure. */ + HCI_TRANSPORT_TX_DONE_FAILURE /**< Transmission failure. */ } hci_transport_tx_done_result_t; /**@brief Transport layer TX done event callback function type. * - * @param[in] result TX done event result code. + * @param[in] result TX done event result code. */ typedef void (*hci_transport_tx_done_handler_t)(hci_transport_tx_done_result_t result); /**@brief Function for registering a generic event handler. * - * @note Multiple registration requests will overwrite any possible existing registration. + * @note Multiple registration requests will overwrite any possible existing registration. * * @param[in] event_handler The function to be called by the transport layer upon an event. * * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. */ uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler); /**@brief Function for registering a handler for TX done event. * - * @note Multiple registration requests will overwrite any possible existing registration. + * @note Multiple registration requests will overwrite any possible existing registration. * * @param[in] event_handler The function to be called by the transport layer upon TX done * event. * * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. */ uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler); - + /**@brief Function for opening the transport channel and initializing the transport layer. * - * @warning Must not be called for a channel which has been allready opened. - * + * @warning Must not be called for a channel which has been allready opened. + * * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. + * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. */ uint32_t hci_transport_open(void); /**@brief Function for closing the transport channel. * * @note Can be called multiple times and also for not opened channel. - * - * @retval NRF_SUCCESS Operation success. + * + * @retval NRF_SUCCESS Operation success. */ uint32_t hci_transport_close(void); /**@brief Function for allocating tx packet memory. - * + * * @param[out] pp_memory Pointer to the packet data. - * + * * @retval NRF_SUCCESS Operation success. Memory was allocated. * @retval NRF_ERROR_NO_MEM Operation failure. No memory available. - * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. */ uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory); /**@brief Function for freeing tx packet memory. * - * @note Memory management works in FIFO principle meaning that free order must match the alloc + * @note Memory management works in FIFO principle meaning that free order must match the alloc * order. - * - * @retval NRF_SUCCESS Operation success. Memory was freed. + * + * @retval NRF_SUCCESS Operation success. Memory was freed. */ uint32_t hci_transport_tx_free(void); /**@brief Function for writing a packet. * - * @note Completion of this method does not guarantee that actual peripheral transmission would + * @note Completion of this method does not guarantee that actual peripheral transmission would * have completed. * - * @note In case of 0 byte packet length write request, message will consist of only transport - * module specific headers. + * @note In case of 0 byte packet length write request, message will consist of only transport + * module specific headers. * - * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue - * and an event will be send upon transmission completion. + * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue + * and an event will be send upon transmission completion. * @retval NRF_ERROR_NO_MEM Operation failure. Transmission queue is full and packet was not - * added to the transmission queue. User should wait for + * added to the transmission queue. User should wait for * a appropriate event prior issuing this operation again. - * @retval NRF_ERROR_DATA_SIZE Operation failure. Packet size exceeds limit. - * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Operation failure. Packet size exceeds limit. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. * @retval NRF_ERROR_INVALID_STATE Operation failure. Channel is not open. */ uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length); /**@brief Function for extracting received packet. * - * @note Extracted memory can't be reused by the underlying transport layer untill freed by call to + * @note Extracted memory can't be reused by the underlying transport layer untill freed by call to * hci_transport_rx_pkt_consume(). * * @param[out] pp_buffer Pointer to the packet data. - * @param[out] p_length Length of packet data in bytes. + * @param[out] p_length Length of packet data in bytes. * - * @retval NRF_SUCCESS Operation success. Packet was extracted. + * @retval NRF_SUCCESS Operation success. Packet was extracted. * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to extract. - * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. + * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. */ uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length); @@ -209,12 +241,17 @@ uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length) * * @param[in] p_buffer Pointer to the buffer that has been consumed. * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to consume. - * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer. + * @retval NRF_SUCCESS Operation success. + * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to consume. + * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer. */ uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer); + +#ifdef __cplusplus +} +#endif + #endif // HCI_TRANSPORT_H__ /** @} */ diff --git a/components/libraries/ic_info/nrf51_ic_info.c b/components/libraries/ic_info/nrf51_ic_info.c deleted file mode 100644 index b68f9a7..0000000 --- a/components/libraries/ic_info/nrf51_ic_info.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "nrf_ic_info.h" -#include "nrf.h" - -void nrf_ic_info_get(nrf_ic_info_t * p_ic_info) -{ - uint32_t ic_data; - - ic_data = (((*((uint32_t volatile *)0xF0000FE8)) & 0x000000F0) >> 4); - - p_ic_info->ram_size = (uint16_t) NRF_FICR->NUMRAMBLOCK * (NRF_FICR->SIZERAMBLOCKS / 1024); - p_ic_info->flash_size = (uint16_t) NRF_FICR->CODESIZE; - switch (ic_data) - { - /** IC revision 1 */ - case 1: - p_ic_info->ic_revision = IC_REVISION_NRF51_REV1; - break; - - /** IC revision 2 */ - case 4: - p_ic_info->ic_revision = IC_REVISION_NRF51_REV2; - break; - - /** IC revision 3 */ - case 7: - /* fall through */ - case 8: - /* fall through */ - case 9: - p_ic_info->ic_revision = IC_REVISION_NRF51_REV3; - break; - - default: - p_ic_info->ic_revision = IC_REVISION_NRF51_UNKNOWN; - break; - } -} diff --git a/components/libraries/ic_info/nrf_ic_info.c b/components/libraries/ic_info/nrf_ic_info.c new file mode 100644 index 0000000..a54fafc --- /dev/null +++ b/components/libraries/ic_info/nrf_ic_info.c @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_ic_info.h" +#include "nrf.h" + +#define PART_NO_NRF51 0x01 +#define PART_NO_NRF52 0x06 + +void nrf_ic_info_get(nrf_ic_info_t * p_ic_info) +{ + uint32_t ic_data = ((*((uint32_t volatile *)0xF0000FE8)) & 0x000000F0) >> 4; + uint32_t ic_part_no = ((*((uint32_t volatile *)0xF0000FE0)) & 0x000000FF); + + switch (ic_part_no) + { +#if defined(NRF51) + case PART_NO_NRF51: + { + p_ic_info->ram_size = (uint16_t) NRF_FICR->NUMRAMBLOCK; + p_ic_info->ram_size *= (uint16_t) (NRF_FICR->SIZERAMBLOCKS / 1024); + p_ic_info->flash_size = (uint16_t) NRF_FICR->CODESIZE; + + switch (ic_data) + { + /** IC revision 1 */ + case 1: + p_ic_info->ic_revision = IC_REVISION_NRF51_REV1; + break; + + /** IC revision 2 */ + case 4: + p_ic_info->ic_revision = IC_REVISION_NRF51_REV2; + break; + + /** IC revision 3 */ + case 7: + /* fall through */ + case 8: + /* fall through */ + case 9: + p_ic_info->ic_revision = IC_REVISION_NRF51_REV3; + break; + + default: + p_ic_info->ic_revision = IC_REVISION_NRF51_UNKNOWN; + break; + } + break; + } +#endif + default: + p_ic_info->ic_revision = IC_PART_UNKNOWN; + p_ic_info->flash_size = 0; + p_ic_info->ram_size = 0; + break; + } +} diff --git a/components/libraries/ic_info/nrf_ic_info.h b/components/libraries/ic_info/nrf_ic_info.h index a220973..e24e025 100644 --- a/components/libraries/ic_info/nrf_ic_info.h +++ b/components/libraries/ic_info/nrf_ic_info.h @@ -1,12 +1,50 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. + * @defgroup nrf_ic_info IC information + * @{ + * @ingroup app_common * - * 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. + * @brief Library for checking IC information (IC revision, RAM size, FLASH size). * */ @@ -15,13 +53,18 @@ #include -/**@brief Enum identifying the IC revision as described in the nRF51 Series Compatibility Matrix. */ +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Enum identifying the IC revision as described in the Compatibility Matrix. */ typedef enum { - IC_REVISION_NRF51_REV1, /**< IC Revision 1. */ - IC_REVISION_NRF51_REV2, /**< IC Revision 2. */ - IC_REVISION_NRF51_REV3, /**< IC Revision 3. */ - IC_REVISION_NRF51_UNKNOWN /**< IC Revision unknown. */ + IC_PART_UNKNOWN = 0, /**< IC Revision unknown. */ + IC_REVISION_NRF51_REV1, /**< IC Revision 1. */ + IC_REVISION_NRF51_REV2, /**< IC Revision 2. */ + IC_REVISION_NRF51_REV3, /**< IC Revision 3. */ + IC_REVISION_NRF51_UNKNOWN /**< IC Revision unknown. */ } nrf_ic_revision_t; /**@brief IC information struct containing the IC revision, RAM size, and FLASH size. */ @@ -41,4 +84,11 @@ typedef struct void nrf_ic_info_get(nrf_ic_info_t* p_ic_info); + +#ifdef __cplusplus +} +#endif + #endif // NRF51_IC_INFO_H__ + +/** @} */ diff --git a/components/libraries/led_softblink/led_softblink.c b/components/libraries/led_softblink/led_softblink.c index ba7997e..1a43f48 100644 --- a/components/libraries/led_softblink/led_softblink.c +++ b/components/libraries/led_softblink/led_softblink.c @@ -1,14 +1,44 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(LED_SOFTBLINK) #include #include "led_softblink.h" #include "nrf_gpio.h" @@ -47,8 +77,8 @@ static void led_softblink_on_timeout(void * p_context) static int32_t pause_ticks; ASSERT(m_led_sb.led_sb_state != NRF_DRV_STATE_UNINITIALIZED); ret_code_t err_code; - - if(pause_ticks <= 0) + + if (pause_ticks <= 0) { if (m_led_sb.is_counting_up) { @@ -77,27 +107,26 @@ static void led_softblink_on_timeout(void * p_context) { m_led_sb.duty_cycle -= m_led_sb.params.duty_cycle_step; } - } + } } else { pause_ticks -= PWM_PERIOD; } - + err_code = low_power_pwm_duty_set(&m_led_sb.pwm_instance, m_led_sb.duty_cycle); - + APP_ERROR_CHECK(err_code); } -ret_code_t led_softblink_init(led_sb_init_params_t * p_init_params) +ret_code_t led_softblink_init(led_sb_init_params_t const * p_init_params) { ret_code_t err_code; - - ASSERT(m_led_sb.led_sb_state == NRF_DRV_STATE_UNINITIALIZED); + ASSERT(m_led_sb.led_sb_state == NRF_DRV_STATE_UNINITIALIZED); ASSERT(p_init_params); - + if ( (p_init_params->duty_cycle_max == 0) || (p_init_params->duty_cycle_max <= p_init_params->duty_cycle_min) || (p_init_params->duty_cycle_step == 0) || @@ -105,26 +134,27 @@ ret_code_t led_softblink_init(led_sb_init_params_t * p_init_params) { return NRF_ERROR_INVALID_PARAM; } - - - + + + memset(&m_led_sb, 0, sizeof(led_sb_context_t)); memcpy(&m_led_sb.params, p_init_params, sizeof(led_sb_init_params_t)); - + m_led_sb.is_counting_up = true; m_led_sb.duty_cycle = p_init_params->duty_cycle_min + p_init_params->duty_cycle_step; m_led_sb.leds_is_on = false; m_led_sb.bit_mask = p_init_params->leds_pin_bm; - + APP_TIMER_DEF(led_softblink_timer); - + m_led_sb.pwm_config.active_high = m_led_sb.params.active_high; m_led_sb.pwm_config.bit_mask = p_init_params->leds_pin_bm; + m_led_sb.pwm_config.p_port = p_init_params->p_leds_port; m_led_sb.pwm_config.period = PWM_PERIOD; m_led_sb.pwm_config.p_timer_id = &led_softblink_timer; - + err_code = low_power_pwm_init( &m_led_sb.pwm_instance, &m_led_sb.pwm_config, led_softblink_on_timeout); - + if (err_code == NRF_SUCCESS) { m_led_sb.led_sb_state = NRF_DRV_STATE_INITIALIZED; @@ -133,7 +163,7 @@ ret_code_t led_softblink_init(led_sb_init_params_t * p_init_params) { return err_code; } - + err_code = low_power_pwm_duty_set( &m_led_sb.pwm_instance, p_init_params->duty_cycle_min + p_init_params->duty_cycle_step); return err_code; @@ -143,11 +173,11 @@ ret_code_t led_softblink_init(led_sb_init_params_t * p_init_params) ret_code_t led_softblink_start(uint32_t leds_pin_bit_mask) { ret_code_t err_code; - + ASSERT(m_led_sb.led_sb_state == NRF_DRV_STATE_INITIALIZED); - + err_code = low_power_pwm_start(&m_led_sb.pwm_instance, leds_pin_bit_mask); - + return err_code; } @@ -155,9 +185,9 @@ ret_code_t led_softblink_start(uint32_t leds_pin_bit_mask) ret_code_t led_softblink_stop(void) { ret_code_t err_code; - + err_code = low_power_pwm_stop(&m_led_sb.pwm_instance); - + return err_code; } @@ -183,9 +213,9 @@ ret_code_t led_softblink_uninit(void) ASSERT(m_led_sb.led_sb_state != NRF_DRV_STATE_UNINITIALIZED); ret_code_t err_code; - + err_code = led_softblink_stop(); - + if (err_code == NRF_SUCCESS) { m_led_sb.led_sb_state = NRF_DRV_STATE_UNINITIALIZED; @@ -194,8 +224,9 @@ ret_code_t led_softblink_uninit(void) { return err_code; } - + memset(&m_led_sb, 0, sizeof(m_led_sb)); return NRF_SUCCESS; } +#endif //NRF_MODULE_ENABLED(LED_SOFTBLINK) diff --git a/components/libraries/led_softblink/led_softblink.h b/components/libraries/led_softblink/led_softblink.h index 826003a..d070a9c 100644 --- a/components/libraries/led_softblink/led_softblink.h +++ b/components/libraries/led_softblink/led_softblink.h @@ -1,15 +1,43 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * * @defgroup led_softblink LED softblink @@ -20,7 +48,7 @@ * * @details This module provides an LED softblink implementation using timers and GPIO. * - * LED softblink needs one timer. It can use any number of output channels that are available. + * LED softblink needs one timer. It can use any number of output channels that are available. * * Only one instance of LED softblink can run at a time. */ @@ -31,19 +59,25 @@ #include #include #include "sdk_errors.h" +#include "nrf_gpio.h" + +#ifdef __cplusplus +extern "C" { +#endif /** * @brief Structure holding the initialization parameters. */ typedef struct { - bool active_high; /**< Activate negative polarity. */ - uint8_t duty_cycle_max; /**< Maximum impulse width. */ - uint8_t duty_cycle_min; /**< Minimum impulse width. */ - uint8_t duty_cycle_step; /**< Cycle step. */ - uint32_t off_time_ticks; /**< Ticks to stay in low impulse state. */ - uint32_t on_time_ticks; /**< Ticks to stay in high impulse state. */ - uint32_t leds_pin_bm; /**< Mask of used LEDs. */ + bool active_high; /**< Activate negative polarity. */ + uint8_t duty_cycle_max; /**< Maximum impulse width. */ + uint8_t duty_cycle_min; /**< Minimum impulse width. */ + uint8_t duty_cycle_step; /**< Cycle step. */ + uint32_t off_time_ticks; /**< Ticks to stay in low impulse state. */ + uint32_t on_time_ticks; /**< Ticks to stay in high impulse state. */ + uint32_t leds_pin_bm; /**< Mask of used LEDs. */ + NRF_GPIO_Type * p_leds_port; /**< Port of used LEDs mask. */ }led_sb_init_params_t; /** @@ -58,6 +92,7 @@ typedef struct #define LED_SB_INIT_PARAMS_OFF_TIME_TICKS 65536 #define LED_SB_INIT_PARAMS_ON_TIME_TICKS 0 #define LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask) (mask) +#define LED_SB_INIT_PARAMS_LEDS_PORT NRF_GPIO /** @} */ /** @@ -71,23 +106,24 @@ typedef struct .duty_cycle_step = LED_SB_INIT_PARAMS_DUTY_CYCLE_STEP, \ .off_time_ticks = LED_SB_INIT_PARAMS_OFF_TIME_TICKS, \ .on_time_ticks = LED_SB_INIT_PARAMS_ON_TIME_TICKS, \ - .leds_pin_bm = LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask) \ + .leds_pin_bm = LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask), \ + .p_leds_port = LED_SB_INIT_PARAMS_LEDS_PORT \ } /** * @brief Function for initializing LED softblink. * - * @param[in] p_init_params Pointer to the initialization structure. + * @param[in] p_init_params Pointer to the initialization structure. * * @return Values returned by @ref app_timer_create. */ -ret_code_t led_softblink_init(led_sb_init_params_t * p_init_params); +ret_code_t led_softblink_init(led_sb_init_params_t const * p_init_params); /** * @brief Function for starting to blink LEDs. * - * @param[in] leds_pin_bit_mask Bit mask containing the pins for the LEDs to be blinked. - * + * @param[in] leds_pin_bit_mask Bit mask containing the pins for the LEDs to be blinked. + * * @return Values returned by @ref app_timer_start. */ ret_code_t led_softblink_start(uint32_t leds_pin_bit_mask); @@ -104,7 +140,7 @@ ret_code_t led_softblink_stop(void); * * This function configures the time that the LEDs will be off between each blink. * - * @param[in] off_time_ticks Off time in ticks. + * @param[in] off_time_ticks Off time in ticks. * */ void led_softblink_off_time_set(uint32_t off_time_ticks); @@ -114,7 +150,7 @@ void led_softblink_off_time_set(uint32_t off_time_ticks); * * This function configures the time that the LEDs will be on between each blink. * - * @param[in] on_time_ticks On time in ticks. + * @param[in] on_time_ticks On time in ticks. * */ void led_softblink_on_time_set(uint32_t on_time_ticks); @@ -122,9 +158,14 @@ void led_softblink_on_time_set(uint32_t on_time_ticks); /** * @brief Function for uninitializing LED softblink. * - * @retval NRF_SUCCESS If LED softblink was uninitialized successfully. + * @retval NRF_SUCCESS If LED softblink was uninitialized successfully. */ ret_code_t led_softblink_uninit(void); + +#ifdef __cplusplus +} +#endif + #endif // LED_SOFTBLINK_H__ /** @} */ diff --git a/components/libraries/log/nrf_log.h b/components/libraries/log/nrf_log.h new file mode 100644 index 0000000..c05ce3c --- /dev/null +++ b/components/libraries/log/nrf_log.h @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup nrf_log Logger module + * @{ + * @ingroup app_common + * + * @brief The nrf_log module interface. + */ + +#ifndef NRF_LOG_H_ +#define NRF_LOG_H_ + +#include "sdk_config.h" + +/** @brief Default module name prefix. + * + * The prefix can be defined in a module to override the default. + */ +#ifndef NRF_LOG_MODULE_NAME + #define NRF_LOG_MODULE_NAME "" +#endif + +/** @brief Severity level for the module. + * + * The severity level can be defined in a module to override the default. + */ +#ifndef NRF_LOG_LEVEL + #define NRF_LOG_LEVEL NRF_LOG_DEFAULT_LEVEL +#endif + +/** @brief Color prefix of debug logs for the module. + * + * This color prefix can be defined in a module to override the default. + */ +#ifndef NRF_LOG_DEBUG_COLOR + #define NRF_LOG_DEBUG_COLOR NRF_LOG_COLOR_DEFAULT +#endif + +/** @brief Color prefix of info logs for the module. + * + * This color prefix can be defined in a module to override the default. + */ +#ifndef NRF_LOG_INFO_COLOR + #define NRF_LOG_INFO_COLOR NRF_LOG_COLOR_DEFAULT +#endif + +#include "nrf_log_internal.h" + +/** @def NRF_LOG_ERROR + * @brief Macro for logging error messages. It takes a printf-like, formatted + * string with up to seven arguments. + * + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs. + */ + +/** @def NRF_LOG_WARNING + * @brief Macro for logging error messages. It takes a printf-like, formatted + * string with up to seven arguments. + * + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs. + */ + +/** @def NRF_LOG_INFO + * @brief Macro for logging error messages. It takes a printf-like, formatted + * string with up to seven arguments. + * + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs. + */ + +/** @def NRF_LOG_DEBUG + * @brief Macro for logging error messages. It takes a printf-like, formatted + * string with up to seven arguments. + * + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs. + */ + +#define NRF_LOG_ERROR(...) NRF_LOG_INTERNAL_ERROR(__VA_ARGS__) +#define NRF_LOG_WARNING(...) NRF_LOG_INTERNAL_WARNING( __VA_ARGS__) +#define NRF_LOG_INFO(...) NRF_LOG_INTERNAL_INFO( __VA_ARGS__) +#define NRF_LOG_DEBUG(...) NRF_LOG_INTERNAL_DEBUG( __VA_ARGS__) + +/** + * @brief A macro for logging a formatted string without any prefix or timestamp. + */ +#define NRF_LOG_RAW_INFO(...) NRF_LOG_INTERNAL_RAW_INFO( __VA_ARGS__) + +/** @def NRF_LOG_HEXDUMP_ERROR + * @brief Macro for logging raw bytes. + * @details It is compiled in only if @ref NRF_LOG_LEVEL includes error logs. + * + * @param p_data Pointer to data. + * @param len Data length in bytes. + */ +/** @def NRF_LOG_HEXDUMP_WARNING + * @brief Macro for logging raw bytes. + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs. + * + * @param p_data Pointer to data. + * @param len Data length in bytes. + */ +/** @def NRF_LOG_HEXDUMP_INFO + * @brief Macro for logging raw bytes. + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs. + * + * @param p_data Pointer to data. + * @param len Data length in bytes. + */ +/** @def NRF_LOG_HEXDUMP_DEBUG + * @brief Macro for logging raw bytes. + * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs. + * + * @param p_data Pointer to data. + * @param len Data length in bytes. + */ +#define NRF_LOG_HEXDUMP_ERROR(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len) +#define NRF_LOG_HEXDUMP_WARNING(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len) +#define NRF_LOG_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len) +#define NRF_LOG_HEXDUMP_DEBUG(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len) + +/** + * @brief Macro for logging hexdump without any prefix or timestamp. + */ +#define NRF_LOG_RAW_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len) + +/** + * @brief A macro for blocking reading from bidirectional backend used for logging. + * + * Macro call is blocking and returns when single byte is received. + */ +#define NRF_LOG_GETCHAR() NRF_LOG_INTERNAL_GETCHAR() + +/** + * @brief Function for copying a string to the internal logger buffer if logs are deferred. + * + * Use this function to store a string that is volatile (for example allocated + * on stack) or that may change before the deferred logs are processed. Such string is copied + * into the internal logger buffer and is persistent until the log is processed. + * + * @note If the logs are not deferred, then this function returns the input parameter. + * + * @param p_str Pointer to the user string. + * + * @return Address to the location where the string is stored in the internal logger buffer. + */ +uint32_t nrf_log_push(char * const p_str); + +/** + * @brief Macro to be used in a formatted string to a pass float number to the log. + * + * Macro should be used in formatted string instead of the %f specifier together with + * @ref NRF_LOG_FLOAT macro. + * Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f))) + */ +#define NRF_LOG_FLOAT_MARKER "%d.%02d" + +/** + * @brief Macro for dissecting a float number into two numbers (integer and residuum). + */ +#define NRF_LOG_FLOAT(val) (int32_t)(val), \ + (int32_t)(((val > 0) ? (val) - (int32_t)(val) \ + : (int32_t)(val) - (val))*100) + +#endif // NRF_LOG_H_ + +/** @} */ diff --git a/components/libraries/log/nrf_log_backend.h b/components/libraries/log/nrf_log_backend.h new file mode 100644 index 0000000..0dea585 --- /dev/null +++ b/components/libraries/log/nrf_log_backend.h @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * @addtogroup nrf_log Logger module + * @ingroup app_common + * + * @defgroup nrf_log_backend Backend of nrf_log + * @{ + * @ingroup nrf_log + * @brief The nrf_log backend interface. + */ + + +#ifndef NRF_LOG_BACKEND_H__ +#define NRF_LOG_BACKEND_H__ + +#include "nrf_log_ctrl.h" +#include "sdk_errors.h" +#include + +/** + * @brief Function for initializing the logger backend. + * + * param blocking Set true if handler functions should block until completion. + * + * @return NRF_SUCCESS after successful initialization, error code otherwise. + */ +ret_code_t nrf_log_backend_init(bool blocking); + +/** + * @brief Function for returning a pointer to a function for handling standard + * log entries (@ref NRF_LOG_ERROR, etc.). + * + * @return Pointer to a handler. + */ +nrf_log_std_handler_t nrf_log_backend_std_handler_get(void); + +/** + * @brief Function for returning a pointer to a function for handling + * hexdumps (@ref NRF_LOG_HEXDUMP_ERROR, etc.). + * + * @return Pointer to a handler. + */ +nrf_log_hexdump_handler_t nrf_log_backend_hexdump_handler_get(void); + +/** + * @brief Function for blocking reading of a byte from the backend. + * + * @return Byte. + */ +uint8_t nrf_log_backend_getchar(void); +#endif // NRF_LOG_BACKEND_H__ +/** @} */ diff --git a/components/libraries/log/nrf_log_ctrl.h b/components/libraries/log/nrf_log_ctrl.h new file mode 100644 index 0000000..1182e8d --- /dev/null +++ b/components/libraries/log/nrf_log_ctrl.h @@ -0,0 +1,229 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_LOG_CTRL_H +#define NRF_LOG_CTRL_H + +/**@file + * @addtogroup nrf_log Logger module + * @ingroup app_common + * + * @defgroup nrf_log_ctrl Functions for controlling nrf_log + * @{ + * @ingroup nrf_log + * @brief The nrf_log control interface. + */ + +#include "sdk_config.h" +#include "sdk_errors.h" +#include +#include +#include "nrf_log_ctrl_internal.h" +/** + * @brief Timestamp function prototype. + * + * @return Timestamp value. + */ +typedef uint32_t (*nrf_log_timestamp_func_t)(void); + +/**@brief Macro for initializing the logs. + * + * @note If timestamps are disabled in the configuration, then the provided pointer + * can be NULL. Otherwise, it is expected that timestamp_getter is not NULL. + * + * @param timestamp_func Function that returns the timestamp. + * + * @return NRF_SUCCESS after successful initialization, otherwise an error code. + */ +#define NRF_LOG_INIT(timestamp_func) NRF_LOG_INTERNAL_INIT(timestamp_func) + + +/**@brief Macro for processing a single log entry from a queue of deferred logs. + * + * You can call this macro from the main context or from the error handler to process + * log entries one by one. + * + * @note If logs are not deferred, this call has no use and is defined as 'false'. + * + * @retval true There are more logs to process in the buffer. + * @retval false No more logs in the buffer. + */ +#define NRF_LOG_PROCESS() NRF_LOG_INTERNAL_PROCESS() + +/** @brief Macro for processing all log entries from the buffer. + * It blocks until all buffered entries are processed by the backend. + * + * @note If logs are not deferred, this call has no use and is empty. + */ +#define NRF_LOG_FLUSH() NRF_LOG_INTERNAL_FLUSH() + +/** @brief Macro for flushing log data before reset. + * + * @note If logs are not deferred, this call has no use and is empty. + * + * @note If RTT is used, then a breakpoint is hit once flushed. + */ +#define NRF_LOG_FINAL_FLUSH() NRF_LOG_INTERNAL_FINAL_FLUSH() + +/** @brief Macro for changing functions that are used to handle log entries. + * + * @param default_handler Function for handling log entries. + * @param bytes_handler Function for handling hexdump entries. + * + */ +#define NRF_LOG_HANDLERS_SET(default_handler, bytes_handler) \ + NRF_LOG_INTERNAL_HANDLERS_SET(default_handler, bytes_handler) + +/** + * @brief Function prototype for handling a log entry. + * + * The backend must implement such prototype. + * + * @param severity_level Severity level of the entry. + * @param p_timestamp Pointer to the timestamp value. No timestamp if NULL. + * @param p_str Pointer to a formatted string. + * @param p_args Pointer to an array of arguments for a formatted string. + * @param nargs Number of arguments in p_args. + * + * @retval true If entry is successfully processed. + * @retval false If entry is not processed. + */ +typedef bool (*nrf_log_std_handler_t)( + uint8_t severity_level, + const uint32_t * const p_timestamp, + const char * const p_str, + uint32_t * p_args, + uint32_t nargs); + +/** + * @brief Function prototype for handling a bytes-dumping log entry. + * + * The backend must implement such prototype. Two buffers are needed because data + * is stored internally in a circular buffer so it can be fragmented into up to + * two pieces. + * + * @param severity_level Severity level of the entry. + * @param p_timestamp Pointer to a timestamp value. No timestamp if NULL. + * @param p_str Prefix string for the bytes dump. + * @param offset Indication of how many bytes have already been processed. + * @param p_buf0 Pointer to the first part of data. + * @param buf0_length Number of bytes in the first part. + * @param p_buf1 Pointer to the second part of data. Optional. + * @param buf1_length Number of bytes in the second part. + * + * @return Number of bytes processed. If all bytes are processed, it should be a sum of + * buf0_length and buf1_length + */ +typedef uint32_t (*nrf_log_hexdump_handler_t)( + uint8_t severity_level, + const uint32_t * const p_timestamp, + const char * const p_str, + uint32_t offset, + const uint8_t * const p_buf0, + uint32_t buf0_length, + const uint8_t * const p_buf1, + uint32_t buf1_length); + + +/** + * @brief Function for initializing the frontend and the default backend. + * + * @ref NRF_LOG_INIT calls this function to initialize the frontend and the backend. + * If custom backend is used, then @ref NRF_LOG_INIT should not be called. + * Instead, frontend and user backend should be verbosely initialized. + * + * @param timestamp_func Function for getting a 32-bit timestamp. + * + * @return Error status. + * + */ +ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func); + +/** + * @brief Function for reinitializing the backend in blocking mode. + */ +ret_code_t nrf_log_blocking_backend_set(void); + +/** + * @brief Function for initializing the logger frontend. + * + * The frontend is initialized with functions for handling log entries. Those + * functions are provided by the backend. + * + * @note This function needs to be called directly only if the @ref NRF_LOG_INIT macro + * is not used to initialize the logger. + * + * @param std_handler Function for handling standard log entries. + * @param hexdump_handler Function for handling hexdump log entries. + * @param timestamp_func Function for getting a timestamp. It cannot be NULL + * unless timestamping is disabled. + */ +void nrf_log_frontend_init(nrf_log_std_handler_t std_handler, + nrf_log_hexdump_handler_t hexdump_handler, + nrf_log_timestamp_func_t timestamp_func); + +/** + * @brief Function for updating functions that handle log entries. + * + * @note Use this feature to change the log handling behavior in certain + * situations, like in a fault handler. + * + * @param std_handler Function for handling standard log entries. + * @param hexdump_handler Function for handling hexdump log entries. + */ +void nrf_log_handlers_set(nrf_log_std_handler_t std_handler, + nrf_log_hexdump_handler_t hexdump_handler); + +/** + * @brief Function for handling a single log entry. + * + * Use this function only if the logs are buffered. It takes a single entry from the + * buffer and attempts to process it. + * + * @retval true If there are more entries to process. + * @retval false If there are no more entries to process. + */ +bool nrf_log_frontend_dequeue(void); + + +#endif // NRF_LOG_CTRL_H + +/** + *@} + **/ diff --git a/components/libraries/log/src/nrf_log_backend_serial.c b/components/libraries/log/src/nrf_log_backend_serial.c new file mode 100644 index 0000000..194420f --- /dev/null +++ b/components/libraries/log/src/nrf_log_backend_serial.c @@ -0,0 +1,496 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_LOG) +#include "nrf_log_backend.h" +#include "nrf_error.h" +#include +#include +#include +#include + +#if NRF_LOG_BACKEND_SERIAL_USES_RTT +#include +#include +#endif + +#if NRF_LOG_BACKEND_SERIAL_USES_UART +#include "nrf_drv_uart.h" +#endif + +#if NRF_LOG_BACKEND_SERIAL_USES_UART +static char m_uart_buffer[NRF_LOG_BACKEND_MAX_STRING_LENGTH]; +static nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(NRF_LOG_BACKEND_UART_INSTANCE); + +#if !NRF_MODULE_ENABLED(UART) +#error "UART driver must be enabled to use UART in nrf_log." +#endif + +#endif //NRF_LOG_BACKEND_SERIAL_USES_UART + +#define HEXDUMP_BYTES_PER_LINE 16 +#define HEXDUMP_HEXBYTE_AREA 3 // Two bytes for hexbyte and space to separate +#define TIMESTAMP_STR(val) "[%0" NUM_TO_STR(val) "d]" + +#define RTT_RETRY_COUNTER 10 //Number of retries before skipping processing + +#define HEXDUMP_MAX_STR_LEN (NRF_LOG_BACKEND_MAX_STRING_LENGTH - \ + (HEXDUMP_HEXBYTE_AREA*HEXDUMP_BYTES_PER_LINE +\ + NRF_LOG_TIMESTAMP_DIGITS + \ + 4 +/* Color ANSI Escape Code */ \ + 2)) /* Separators */ + +static bool m_initialized = false; +static bool m_blocking_mode = false; +static const char m_default_color[] = "\x1B[0m"; + +#if (NRF_LOG_BACKEND_SERIAL_USES_UART) +static volatile bool m_rx_done = false; +#endif + +#if (NRF_LOG_BACKEND_SERIAL_USES_UART) +static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context) +{ + // Dummy handler since is_busy feature is used for determining readiness. + if (p_event->type == NRF_DRV_UART_EVT_RX_DONE) + { + m_rx_done = true; + } +} +#endif //NRF_LOG_BACKEND_SERIAL_USES_UART + + +ret_code_t nrf_log_backend_init(bool blocking) +{ + + if (m_initialized && (blocking == m_blocking_mode)) + { + return NRF_SUCCESS; + } +#if (NRF_LOG_BACKEND_SERIAL_USES_RTT) + SEGGER_RTT_Init(); +#endif + +#if (NRF_LOG_BACKEND_SERIAL_USES_UART) + uint32_t ret_code; + nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG; + uart_config.hwfc = + (nrf_uart_hwfc_t)NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL; + uart_config.pseltxd = NRF_LOG_BACKEND_SERIAL_UART_TX_PIN; + uart_config.pselrxd = NRF_LOG_BACKEND_SERIAL_UART_RX_PIN; + uart_config.pselrts = NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN; + uart_config.pselcts = NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN; + uart_config.baudrate = + (nrf_uart_baudrate_t)NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE; + nrf_drv_uart_uninit(&m_uart); + ret_code = nrf_drv_uart_init(&m_uart, &uart_config, + blocking ? NULL : uart_event_handler); + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } +#endif //NRF_LOG_BACKEND_SERIAL_USES_UART + + m_initialized = true; + m_blocking_mode = blocking; + return NRF_SUCCESS; +} + + +static bool serial_is_busy(void) +{ + bool res = false; + +#if (NRF_LOG_BACKEND_SERIAL_USES_UART) + res = nrf_drv_uart_tx_in_progress(&m_uart); +#endif + +#if (NRF_LOG_BACKEND_SERIAL_USES_RTT) + +#endif + + return res; +} + + +static bool serial_tx(uint8_t * p_buf, uint32_t len) +{ + bool ret = true; + +#if NRF_LOG_BACKEND_SERIAL_USES_UART + memcpy(m_uart_buffer, p_buf, len); + uint32_t ret_code = nrf_drv_uart_tx(&m_uart, (uint8_t *)m_uart_buffer, len); + if (ret_code != NRF_SUCCESS) + { + ret = false; + } +#endif //NRF_LOG_BACKEND_SERIAL_USES_UART + +#if NRF_LOG_BACKEND_SERIAL_USES_RTT + uint32_t idx = 0; + uint32_t length = len; + uint32_t processed; + uint32_t watchdog_counter = RTT_RETRY_COUNTER; + do + { + processed = SEGGER_RTT_WriteNoLock(0, &p_buf[idx], length); + idx += processed; + length -= processed; + if (processed == 0) + { + // If RTT is not connected then ensure that logger does not block + watchdog_counter--; + if (watchdog_counter == 0) + { + break; + } + } + } while (length); +#endif //NRF_LOG_BACKEND_SERIAL_USES_RTT + return ret; +} + + +static uint8_t serial_get_byte(void) +{ + uint8_t data; +#if NRF_LOG_BACKEND_SERIAL_USES_UART + if (m_blocking_mode) + { + (void)nrf_drv_uart_rx(&m_uart, &data, 1); + } + else + { + m_rx_done = false; + (void)nrf_drv_uart_rx(&m_uart, &data, 1); + while(!m_rx_done); + } +#elif NRF_LOG_BACKEND_SERIAL_USES_RTT + data = (uint8_t)SEGGER_RTT_WaitKey(); +#endif //NRF_LOG_BACKEND_SERIAL_USES_RTT + return data; +} + + +static bool buf_len_update(uint32_t * p_buf_len, int32_t new_len) +{ + bool ret; + if (new_len < 0) + { + ret = false; + } + else + { + *p_buf_len += (uint32_t)new_len; + ret = true; + } + return ret; +} + + +static bool timestamp_process(const uint32_t * const p_timestamp, char * p_str, uint32_t * p_len) +{ + int32_t len = 0; + bool ret = true; + if (p_timestamp) + { +#if NRF_LOG_USES_COLORS + len = sizeof(m_default_color) - 1; + memcpy(p_str, m_default_color, len); + *p_len += len; +#endif //NRF_LOG_USES_COLORS + len = snprintf(&p_str[len],NRF_LOG_BACKEND_MAX_STRING_LENGTH, TIMESTAMP_STR(NRF_LOG_TIMESTAMP_DIGITS), (int)*p_timestamp); + ret = buf_len_update(p_len, len); + } + else + { + *p_len = 0; + } + return ret; +} + + +static bool nrf_log_backend_serial_std_handler( + uint8_t severity_level, + const uint32_t * const p_timestamp, + const char * const p_str, + uint32_t * p_args, + uint32_t nargs) +{ + char str[NRF_LOG_BACKEND_MAX_STRING_LENGTH]; + int32_t tmp_str_len = 0; + uint32_t buffer_len = 0; + bool status = true; + + if (serial_is_busy()) + { + return false; + } + + if (!timestamp_process(p_timestamp, &str[buffer_len], &buffer_len)) + { + return false; + } + + switch (nargs) + { + case 0: + { + tmp_str_len = strlen(p_str); + if ((tmp_str_len + buffer_len) < NRF_LOG_BACKEND_MAX_STRING_LENGTH) + { + memcpy(&str[buffer_len], p_str, tmp_str_len); + } + break; + } + + case 1: + tmp_str_len = snprintf(&str[buffer_len], NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, p_str, p_args[0]); + + break; + + case 2: + tmp_str_len = snprintf(&str[buffer_len], NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, p_str, p_args[0], p_args[1]); + break; + + case 3: + tmp_str_len = snprintf(&str[buffer_len], NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, p_str, p_args[0], p_args[1], p_args[2]); + break; + + case 4: + tmp_str_len = + snprintf(&str[buffer_len], NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, p_str, p_args[0], p_args[1], p_args[2], p_args[3]); + break; + + case 5: + tmp_str_len = + snprintf(&str[buffer_len], + NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, + p_str, + p_args[0], + p_args[1], + p_args[2], + p_args[3], + p_args[4]); + break; + + case 6: + tmp_str_len = + snprintf(&str[buffer_len], + NRF_LOG_BACKEND_MAX_STRING_LENGTH-buffer_len, + p_str, + p_args[0], + p_args[1], + p_args[2], + p_args[3], + p_args[4], + p_args[5]); + break; + + default: + break; + } + status = buf_len_update(&buffer_len, tmp_str_len); + uint32_t full_buff_len = NRF_LOG_USES_COLORS ? + buffer_len + sizeof(m_default_color)-1 : buffer_len; + if (status && (full_buff_len <= NRF_LOG_BACKEND_MAX_STRING_LENGTH)) + { + if (NRF_LOG_USES_COLORS) + { + memcpy(&str[buffer_len], m_default_color, sizeof(m_default_color)-1); + buffer_len = full_buff_len; + } + return serial_tx((uint8_t *)str, buffer_len); + } + else + { + // error, snprintf failed. + return false; + } +} + + +static void byte2hex(const uint8_t c, char * p_out) +{ + uint8_t nibble; + uint32_t i = 2; + + while (i-- != 0) + { + nibble = (c >> (4 * i)) & 0x0F; + p_out[1 - i] = (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble); + } +} + + +static uint32_t nrf_log_backend_serial_hexdump_handler( + uint8_t severity_level, + const uint32_t * const p_timestamp, + const char * const p_str, + uint32_t offset, + const uint8_t * const p_buf0, + uint32_t buf0_length, + const uint8_t * const p_buf1, + uint32_t buf1_length) +{ + char str[NRF_LOG_BACKEND_MAX_STRING_LENGTH]; + uint32_t slen; + char * p_hex_part; + char * p_char_part; + uint8_t c; + uint32_t byte_in_line; + uint32_t buffer_len = 0; + uint32_t byte_cnt = offset; + uint32_t length = buf0_length + buf1_length; + uint32_t timestamp_len = p_timestamp ? + NRF_LOG_TIMESTAMP_DIGITS+2 : 0; //+2 since timestamp is in brackets + + if (serial_is_busy()) + { + return offset; + } + + // If it is the first part of hexdump print the header + if (offset == 0) + { + if (!timestamp_process(p_timestamp, &str[buffer_len], &buffer_len)) + { + return offset; + } + slen = strlen(p_str); + // Saturate string if it's too long. + slen = (slen > HEXDUMP_MAX_STR_LEN) ? HEXDUMP_MAX_STR_LEN : slen; + memcpy(&str[buffer_len], p_str, slen); + buffer_len += slen; + } + + do + { + + uint32_t i; + uint32_t hex_part_offset = buffer_len; + uint32_t char_part_offset = hex_part_offset + + (HEXDUMP_BYTES_PER_LINE * HEXDUMP_HEXBYTE_AREA + 1) + // +1 - separator between hexdump and characters. + timestamp_len; + + p_hex_part = &str[hex_part_offset]; + p_char_part = &str[char_part_offset]; + + // Fill the blanks to align to timestamp print + for (i = 0; i < timestamp_len; i++) + { + *p_hex_part = ' '; + ++p_hex_part; + } + + for (byte_in_line = 0; byte_in_line < HEXDUMP_BYTES_PER_LINE; byte_in_line++) + { + if (byte_cnt >= length) + { + // file the blanks + *p_hex_part++ = ' '; + *p_hex_part++ = ' '; + *p_hex_part++ = ' '; + *p_char_part++ = ' '; + } + else + { + if (byte_cnt < buf0_length) + { + c = p_buf0[byte_cnt]; + } + else + { + c = p_buf1[byte_cnt - buf0_length]; + } + byte2hex(c, p_hex_part); + p_hex_part += 2; // move the pointer since byte in hex was added. + *p_hex_part++ = ' '; + *p_char_part++ = isprint(c) ? c : '.'; + byte_cnt++; + } + } + *p_char_part++ = '\r'; + *p_char_part++ = '\n'; + *p_hex_part++ = ' '; + buffer_len += timestamp_len + + (HEXDUMP_BYTES_PER_LINE * HEXDUMP_HEXBYTE_AREA + 1) + // space for hex dump and separator between hexdump and string + HEXDUMP_BYTES_PER_LINE + // space for stringS dump + 2; // space for new line + if (NRF_LOG_USES_COLORS) + { + memcpy(&str[buffer_len], m_default_color, sizeof(m_default_color)-1); + buffer_len += sizeof(m_default_color)-1; + } + + if (!serial_tx((uint8_t *)str, buffer_len)) + { + return byte_cnt; + } + + if (serial_is_busy()) + { + return byte_cnt; + } + buffer_len = 0; + } + while (byte_cnt < length); + return byte_cnt; +} + + +nrf_log_std_handler_t nrf_log_backend_std_handler_get(void) +{ + return nrf_log_backend_serial_std_handler; +} + + +nrf_log_hexdump_handler_t nrf_log_backend_hexdump_handler_get(void) +{ + return nrf_log_backend_serial_hexdump_handler; +} + + +uint8_t nrf_log_backend_getchar(void) +{ + return serial_get_byte(); +} + +#endif // NRF_MODULE_ENABLED(NRF_LOG) diff --git a/components/libraries/log/src/nrf_log_ctrl_internal.h b/components/libraries/log/src/nrf_log_ctrl_internal.h new file mode 100644 index 0000000..3d6d3e5 --- /dev/null +++ b/components/libraries/log/src/nrf_log_ctrl_internal.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_LOG_CTRL_INTERNAL_H +#define NRF_LOG_CTRL_INTERNAL_H +/** + * @cond (NODOX) + * @defgroup nrf_log_ctrl_internal Auxiliary internal types declarations + * @{ + * @internal + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_LOG) +#include "app_util_platform.h" + +#define NRF_LOG_INTERNAL_INIT(timestamp_func) \ + nrf_log_init(timestamp_func) + +#if (NRF_LOG_DEFERRED == 0) +#define NRF_LOG_INTERNAL_PROCESS() false +#define NRF_LOG_INTERNAL_FLUSH() +#define NRF_LOG_INTERNAL_FINAL_FLUSH() +#else +#define NRF_LOG_INTERNAL_PROCESS() nrf_log_frontend_dequeue() +#define NRF_LOG_INTERNAL_FLUSH() \ + do { \ + while (NRF_LOG_INTERNAL_PROCESS()); \ + } while(0) + +#if NRF_LOG_BACKEND_SERIAL_USES_RTT +#define NRF_LOG_INTERNAL_BACKEND_FINAL NRF_BREAKPOINT_COND +#else +#define NRF_LOG_INTERNAL_BACKEND_FINAL +#endif + +#define NRF_LOG_INTERNAL_FINAL_FLUSH() \ + do { \ + (void)nrf_log_blocking_backend_set(); \ + NRF_LOG_INTERNAL_FLUSH(); \ + NRF_LOG_INTERNAL_BACKEND_FINAL; \ + } while(0) + +#endif + +#define NRF_LOG_INTERNAL_HANDLERS_SET(default_handler, bytes_handler) \ + nrf_log_handlers_set(default_handler, bytes_handler) + +#else // NRF_MODULE_ENABLED(NRF_LOG) +#define NRF_LOG_INTERNAL_PROCESS() false +#define NRF_LOG_INTERNAL_FLUSH() +#define NRF_LOG_INTERNAL_INIT(timestamp_func) NRF_SUCCESS +#define NRF_LOG_INTERNAL_HANDLERS_SET(default_handler, bytes_handler) \ + UNUSED_PARAMETER(default_handler); UNUSED_PARAMETER(bytes_handler) +#define NRF_LOG_INTERNAL_FINAL_FLUSH() +#endif // NRF_MODULE_ENABLED(NRF_LOG) + +/** @} + * @endcond + */ +#endif // NRF_LOG_CTRL_INTERNAL_H diff --git a/components/libraries/log/src/nrf_log_frontend.c b/components/libraries/log/src/nrf_log_frontend.c new file mode 100644 index 0000000..248fdca --- /dev/null +++ b/components/libraries/log/src/nrf_log_frontend.c @@ -0,0 +1,826 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_LOG) +#include "app_util.h" +#include "app_util_platform.h" +#include "nrf_log.h" +#include "nrf_log_internal.h" +#include "nrf_log_backend.h" +#include "nrf_log_ctrl.h" +#include + +#if NRF_LOG_DEFERRED +STATIC_ASSERT((NRF_LOG_DEFERRED_BUFSIZE == 0) || IS_POWER_OF_TWO(NRF_LOG_DEFERRED_BUFSIZE)); +#else +#define NRF_LOG_DEFERRED_BUFSIZE 1 +#endif + +/** + * brief An internal control block of the logger + * + * @note Circular buffer is using never cleared indexes and a mask. It means + * that logger may break when indexes overflows. However, it is quite unlikely. + * With rate of 1000 log entries with 2 parameters per second such situation + * would happen after 12 days. + */ +typedef struct +{ + uint32_t wr_idx; // Current write index (never reset) + uint32_t rd_idx; // Current read index (never_reset) + uint32_t mask; // Size of buffer (must be power of 2) presented as mask + uint32_t buffer[NRF_LOG_DEFERRED_BUFSIZE]; + nrf_log_timestamp_func_t timestamp_func; // A pointer to function that returns timestamp + nrf_log_std_handler_t std_handler; // A handler used for processing standard log calls + nrf_log_hexdump_handler_t hexdump_handler; // A handler for processing hex dumps +} log_data_t; + +static log_data_t m_log_data; +#if (NRF_LOG_DEFERRED == 1) +static const char * m_overflow_info = NRF_LOG_ERROR_COLOR_CODE "Overflow\r\n"; +#endif //(NRF_LOG_DEFERRED == 1) + +/** + * Set of macros for encoding and decoding header for log entries. + * There are 3 types of entries: + * 1. Standard entry (STD) + * An entry consists of header, pointer to string and values. Header contains + * severity leveland determines number of arguments and thus size of the entry. + * Since flash address space starts from 0x00000000 and is limited to kB rather + * than MB 22 bits are used to store the address (4MB). It is used that way to + * save one RAM memory. + * + * -------------------------------- + * |TYPE|SEVERITY|NARGS| P_STR | + * |------------------------------| + * | TIMESTAMP (optional) | + * |------------------------------| + * | ARG0 | + * |------------------------------| + * | .... | + * |------------------------------| + * | ARG(nargs-1) | + * -------------------------------- + * + * 2. Hexdump entry (HEXDUMP) is used for dumping raw data. An entry consists of + * header, optional timestamp, pointer to string and data. A header contains + * length (10bit) and offset which is updated after backend processes part of + * data. + * + * -------------------------------- + * |TYPE|SEVERITY|NARGS|OFFSET|LEN| + * |------------------------------| + * | TIMESTAMP (optional) | + * |------------------------------| + * | P_STR | + * |------------------------------| + * | data | + * |------------------------------| + * | data | dummy | + * -------------------------------- + * + * 3. Pushed string. If string is pushed into the logger internal buffer it is + * stored as PUSHED entry. It consists of header, unused data (optional) and + * string. Unused data is present if string does not not fit into a buffer + * without wrapping (and string cannot be wrapped). In that case header + * contains information about offset. + * + * -------------------------------- + * |TYPE| OFFSET | LEN | + * |------------------------------| + * | OFFSET | + * |------------------------------| + * end| OFFSET | + * 0|------------------------------| + * | STRING | + * |------------------------------| + * | STRING | dummy | + * -------------------------------- + */ +#define HEADER_SIZE ((NRF_LOG_USES_TIMESTAMP) ? 2 : 1) + +#define STD_ADDR_MASK ((uint32_t)(1U << 22) - 1U) +#define HEADER_TYPE_STD 1U +#define HEADER_TYPE_HEXDUMP 2U +#define HEADER_TYPE_PUSHED 0U + +typedef struct +{ + uint32_t type : 2; + uint32_t raw : 1; + uint32_t data : 29; +} nrf_log_generic_header_t; + +typedef struct +{ + uint32_t type : 2; + uint32_t raw : 1; + uint32_t severity : 3; + uint32_t nargs : 4; + uint32_t addr : 22; +} nrf_log_std_header_t; + +typedef struct +{ + uint32_t type : 2; + uint32_t raw : 1; + uint32_t severity : 3; + uint32_t offset : 10; + uint32_t reserved : 6; + uint32_t len : 10; +} nrf_log_hexdump_header_t; + +typedef struct +{ + uint32_t type : 2; + uint32_t reserved0 : 4; + uint32_t offset : 10; + uint32_t reserved1 : 6; + uint32_t len : 10; +} nrf_log_pushed_header_t; + +typedef union +{ + nrf_log_generic_header_t generic; + nrf_log_std_header_t std; + nrf_log_hexdump_header_t hexdump; + nrf_log_pushed_header_t pushed; + uint32_t raw; +} nrf_log_header_t; + +/* IAR does not support initialization with non-constant variables */ +#if defined ( __ICCARM__ ) +#define STD_HEADER_DEF(NAME, P_STR, SEVERITY, NARGS) \ + nrf_log_header_t NAME = { \ + .std = { \ + .type = HEADER_TYPE_STD, \ + } \ + }; \ + NAME.std.type = HEADER_TYPE_STD; \ + NAME.std.raw = ((SEVERITY) & NRF_LOG_RAW); \ + NAME.std.severity = (SEVERITY) & NRF_LOG_LEVEL_MASK; \ + NAME.std.nargs = (NARGS); \ + NAME.std.addr = ((uint32_t)(P_STR) & STD_ADDR_MASK) +#else +#define STD_HEADER_DEF(NAME, P_STR, SEVERITY, NARGS) \ + nrf_log_header_t NAME = { \ + .std = { \ + .type = HEADER_TYPE_STD, \ + .raw = ((SEVERITY) & NRF_LOG_RAW), \ + .severity = (SEVERITY) & NRF_LOG_LEVEL_MASK, \ + .nargs = (NARGS), \ + .addr = ((uint32_t)(P_STR) & STD_ADDR_MASK)\ + } \ + } +#endif + +#if defined ( __ICCARM__ ) +#define HEXDUMP_HEADER_DEF(NAME, SEVERITY, LENGTH) \ + nrf_log_header_t NAME = { \ + .hexdump = { \ + .type = HEADER_TYPE_HEXDUMP, \ + .offset = 0, \ + } \ + }; \ + NAME.hexdump.raw = ((SEVERITY) & NRF_LOG_RAW); \ + NAME.hexdump.severity = (SEVERITY) & NRF_LOG_LEVEL_MASK;\ + NAME.hexdump.len = (LENGTH) + +#else +#define HEXDUMP_HEADER_DEF(NAME, SEVERITY, LENGTH) \ + nrf_log_header_t NAME = { \ + .hexdump = { \ + .type = HEADER_TYPE_HEXDUMP, \ + .raw = ((SEVERITY) & NRF_LOG_RAW), \ + .severity = (SEVERITY) & NRF_LOG_LEVEL_MASK, \ + .offset = 0, \ + .len = LENGTH, \ + } \ + } +#endif + +#if defined ( __ICCARM__ ) +#define PUSHED_HEADER_DEF(NAME, OFFSET, LENGTH) \ + nrf_log_header_t NAME = { \ + .pushed = { \ + .type = HEADER_TYPE_PUSHED, \ + } \ + }; \ + NAME.pushed.offset = (OFFSET); \ + NAME.pushed.len = (LENGTH) + +#else +#define PUSHED_HEADER_DEF(NAME, OFFSET, LENGTH) \ + nrf_log_header_t NAME = { \ + .pushed = { \ + .type = HEADER_TYPE_PUSHED, \ + .offset = (OFFSET), \ + .len = (LENGTH), \ + } \ + } + +#endif + +ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func) +{ + if (NRF_LOG_USES_TIMESTAMP && (timestamp_func == NULL)) + { + return NRF_ERROR_INVALID_PARAM; + } + + ret_code_t err_code = nrf_log_backend_init(NRF_LOG_DEFERRED ? false : true); + + if (err_code == NRF_SUCCESS) + { + nrf_log_frontend_init(nrf_log_backend_std_handler_get(), + nrf_log_backend_hexdump_handler_get(), + timestamp_func); + } + return err_code; +} + + +ret_code_t nrf_log_blocking_backend_set(void) +{ + // Return value is ommited because + return nrf_log_backend_init(true); +} + + +void nrf_log_frontend_init(nrf_log_std_handler_t std_handler, + nrf_log_hexdump_handler_t hexdump_handler, + nrf_log_timestamp_func_t timestamp_func) +{ +#if NRF_LOG_DEFERRED + m_log_data.mask = NRF_LOG_DEFERRED_BUFSIZE - 1; + m_log_data.wr_idx = 0; + m_log_data.rd_idx = 0; +#endif //NRF_LOG_DEFERRED +#if NRF_LOG_USES_TIMESTAMP + m_log_data.timestamp_func = timestamp_func; +#endif //NRF_LOG_USES_TIMESTAMP + nrf_log_handlers_set(std_handler, hexdump_handler); +} + + +void nrf_log_handlers_set(nrf_log_std_handler_t std_handler, + nrf_log_hexdump_handler_t hexdump_handler) +{ + m_log_data.std_handler = std_handler; + m_log_data.hexdump_handler = hexdump_handler; +} + +#if (NRF_LOG_DEFERRED == 1) +/** + * @brief Allocates chunk in a buffer for one entry and injects overflow if + * there is no room for requested entry. + * + * @param nargs Number of 32bit arguments. In case of allocating for hex dump it + * is the size of the buffer in 32bit words (ceiled). + * @param p_wr_idx Pointer to write index. + * + * @return True if successful allocation, false otherwise. + * + */ +static inline bool buf_prealloc(uint32_t nargs, uint32_t * p_wr_idx) +{ + nargs += HEADER_SIZE; + uint32_t ovflw_tag_size = HEADER_SIZE; + bool ret = true; + CRITICAL_REGION_ENTER(); + *p_wr_idx = m_log_data.wr_idx; + uint32_t available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx); + uint32_t required_words = nargs + ovflw_tag_size; // room for current entry and overflow + if (required_words > available_words) + { + if (available_words >= HEADER_SIZE) + { + // Overflow entry is injected + STD_HEADER_DEF(header, m_overflow_info, NRF_LOG_LEVEL_INTERNAL, 0); + m_log_data.buffer[m_log_data.wr_idx++ & m_log_data.mask] = + header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[m_log_data.wr_idx++ & m_log_data.mask] = + m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + } + // overflow case + ret = false; + } + else + { + m_log_data.wr_idx += nargs; + } + CRITICAL_REGION_EXIT(); + return ret; +} + + +/** + * @brief Function for preallocating a continuous chunk of memory from circular buffer. + * + * If buffer does not fit starting from current position it will be allocated at + * the beginning of the circular buffer and offset will be returned indicating + * how much memory has been ommited at the end of the buffer. Function is + * using critical section. + * + * @param len32 Length of buffer to allocate. Given in words. + * @param p_offset Offset of the buffer. + * @param p_wr_idx Pointer to write index. + * + * @return A pointer to the allocated buffer. NULL if allocation failed. + */ +static inline uint32_t * cont_buf_prealloc(uint32_t len32, + uint32_t * p_offset, + uint32_t * p_wr_idx) +{ + uint32_t * p_buf = NULL; + + len32++; // Increment because 32bit header is needed to be stored. + + CRITICAL_REGION_ENTER(); + *p_wr_idx = m_log_data.wr_idx; + uint32_t available_words = (m_log_data.mask + 1) - + (m_log_data.wr_idx & m_log_data.mask); + if (len32 <= available_words) + { + // buffer will fit as is + p_buf = &m_log_data.buffer[(m_log_data.wr_idx + 1) & m_log_data.mask]; + m_log_data.wr_idx += len32; + *p_offset = 0; + } + else if (len32 < (m_log_data.rd_idx & m_log_data.mask)) + { + // wraping to the begining of the buffer + m_log_data.wr_idx += (len32 + available_words - 1); + *p_offset = available_words - 1; + p_buf = m_log_data.buffer; + } + available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx); + // If there is no more room for even overflow tag indicate failed allocation. + if (available_words < HEADER_SIZE) + { + p_buf = NULL; + } + CRITICAL_REGION_EXIT(); + + return p_buf; +} +#endif //(NRF_LOG_DEFERRED == 1) + + +#if (NRF_LOG_DEFERRED == 0) +static inline void nrf_log_direct_feed(uint8_t type, + char const * const p_str, + uint32_t * p_args, + uint32_t nargs) +{ + uint32_t timestamp = 0; + uint32_t * p_timestamp = NRF_LOG_USES_TIMESTAMP ? ×tamp : NULL; + +#if NRF_LOG_USES_TIMESTAMP + timestamp = m_log_data.timestamp_func(); +#else //NRF_LOG_USES_TIMESTAMP + UNUSED_VARIABLE(timestamp); +#endif //NRF_LOG_USES_TIMESTAMP + + UNUSED_VARIABLE + (m_log_data.std_handler(type, p_timestamp, (char *)p_str, p_args, nargs)); + +} +#endif //(NRF_LOG_DEFERRED == 0) + + +uint32_t nrf_log_push(char * const p_str) +{ +#if (NRF_LOG_DEFERRED == 0) + return (uint32_t)p_str; +#else //(NRF_LOG_DEFERRED == 0) + uint32_t mask = m_log_data.mask; + uint32_t slen = strlen(p_str) + 1; + uint32_t buflen = CEIL_DIV(slen, 4); + uint32_t offset = 0; + uint32_t wr_idx; + char * p_dst_str = (char *)cont_buf_prealloc(buflen, &offset, &wr_idx); + if (p_dst_str) + { + PUSHED_HEADER_DEF(header, offset, buflen); + m_log_data.buffer[wr_idx++ & mask] = header.raw; + memcpy(p_dst_str, p_str, slen); + } + return (uint32_t)p_dst_str; +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_0(uint8_t severity, char const * const p_str) +{ +#if (NRF_LOG_DEFERRED == 0) + nrf_log_direct_feed(severity, p_str, NULL, 0); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 0; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_1(uint8_t severity, + char const * const p_str, + uint32_t val0) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 1; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx & mask] = val0; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_2(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0, val1}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 2; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = val0; + m_log_data.buffer[wr_idx & mask] = val1; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_3(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0, val1, val2}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 3; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = val0; + m_log_data.buffer[wr_idx++ & mask] = val1; + m_log_data.buffer[wr_idx & mask] = val2; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_4(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0, val1, val2, val3}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 4; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = val0; + m_log_data.buffer[wr_idx++ & mask] = val1; + m_log_data.buffer[wr_idx++ & mask] = val2; + m_log_data.buffer[wr_idx & mask] = val3; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_5(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3, + uint32_t val4) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0, val1, val2, val3, val4}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 5; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = val0; + m_log_data.buffer[wr_idx++ & mask] = val1; + m_log_data.buffer[wr_idx++ & mask] = val2; + m_log_data.buffer[wr_idx++ & mask] = val3; + m_log_data.buffer[wr_idx & mask] = val4; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_std_6(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3, + uint32_t val4, + uint32_t val5) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t args[] = {val0, val1, val2, val3, val4, val5}; + nrf_log_direct_feed(severity, p_str, args, ARRAY_SIZE(args)); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t nargs = 6; + uint32_t mask = m_log_data.mask; + uint32_t wr_idx; + if (buf_prealloc(nargs, &wr_idx)) + { + // Proceed only if buffer was successfully preallocated. + STD_HEADER_DEF(header, p_str, severity, nargs); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = val0; + m_log_data.buffer[wr_idx++ & mask] = val1; + m_log_data.buffer[wr_idx++ & mask] = val2; + m_log_data.buffer[wr_idx++ & mask] = val3; + m_log_data.buffer[wr_idx++ & mask] = val4; + m_log_data.buffer[wr_idx & mask] = val5; + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +void nrf_log_frontend_hexdump(uint8_t severity, + char const * const p_str, + const void * const p_data, + uint16_t length) +{ +#if (NRF_LOG_DEFERRED == 0) + uint32_t timestamp = 0; +#if NRF_LOG_USES_TIMESTAMP + timestamp = m_log_data.timestamp_func(); +#else //NRF_LOG_USES_TIMESTAMP + (void) timestamp; +#endif //NRF_LOG_USES_TIMESTAMP + + uint32_t curr_offset = 0; + + do + { + curr_offset = m_log_data.hexdump_handler(severity, + NRF_LOG_USES_TIMESTAMP ? ×tamp : NULL, + p_str, + curr_offset, + p_data, + length, + NULL, + 0); + } + while (curr_offset < length); +#else //(NRF_LOG_DEFERRED == 0) + uint32_t mask = m_log_data.mask; + + uint32_t wr_idx; + if (buf_prealloc(CEIL_DIV(length, 4) + 1, &wr_idx)) + { + HEXDUMP_HEADER_DEF(header, severity, length); + m_log_data.buffer[wr_idx++ & mask] = header.raw; +#if NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = m_log_data.timestamp_func(); +#endif //NRF_LOG_USES_TIMESTAMP + m_log_data.buffer[wr_idx++ & mask] = (uint32_t)p_str; + uint32_t space0 = sizeof(uint32_t) * (m_log_data.mask + 1 - (wr_idx & mask)); + if (length <= space0) + { + memcpy(&m_log_data.buffer[wr_idx & mask], p_data, length); + } + else + { + memcpy(&m_log_data.buffer[wr_idx & mask], p_data, space0); + length -= space0; + memcpy(&m_log_data.buffer[0], &((uint8_t *)p_data)[space0], length); + } + } +#endif //(NRF_LOG_DEFERRED == 0) +} + + +bool buffer_is_empty(void) +{ + return (m_log_data.rd_idx == m_log_data.wr_idx); +} + + +bool nrf_log_frontend_dequeue(void) +{ + if (buffer_is_empty()) + { + return false; + } + + uint32_t rd_idx = m_log_data.rd_idx; + uint32_t mask = m_log_data.mask; + uint32_t header_rd_idx = rd_idx; + // uint32_t header = m_log_data.buffer[rd_idx++ & mask]; + nrf_log_header_t header; + header.raw = m_log_data.buffer[rd_idx++ & mask]; + + // Skip any string that is pushed to the circular buffer. + while (header.generic.type == HEADER_TYPE_PUSHED) + { + rd_idx += (header.pushed.len + header.pushed.offset); + header_rd_idx = rd_idx; + header.raw = m_log_data.buffer[rd_idx++ & mask]; + } + + uint32_t * p_timestamp = NRF_LOG_USES_TIMESTAMP ? + &m_log_data.buffer[rd_idx++ & mask] : NULL; + + if (header.generic.raw) + { + p_timestamp = NULL; + } + + bool ret = false; + if (header.generic.type == HEADER_TYPE_HEXDUMP) + { + // buffer + char * p_str = (char *)m_log_data.buffer[rd_idx++ & mask]; + uint32_t length = header.hexdump.len; + uint32_t offset = header.hexdump.offset; + uint32_t space0 = sizeof(uint32_t) * (mask + 1 - (rd_idx & mask)); + if (length > space0) + { + uint8_t * ptr0 = space0 ? + (uint8_t *)&m_log_data.buffer[rd_idx & mask] : + (uint8_t *)&m_log_data.buffer[0]; + uint8_t len0 = space0 ? space0 : length; + uint8_t * ptr1 = space0 ? + (uint8_t *)&m_log_data.buffer[0] : NULL; + uint8_t len1 = space0 ? length - space0 : 0; + + offset = m_log_data.hexdump_handler(header.hexdump.severity, + p_timestamp, p_str, + offset, + ptr0, len0, + ptr1, len1); + } + else + { + offset = m_log_data.hexdump_handler( + header.hexdump.severity, + p_timestamp, + p_str, + offset, + (uint8_t *)&m_log_data.buffer[rd_idx & mask], + length, + NULL, 0); + } + + if (offset == length) + { + rd_idx += CEIL_DIV(length, 4); + ret = true; + } + else + { + // If there is more log to process just updated the offset but + // do not move rd_idx. + header.hexdump.offset = offset; + m_log_data.buffer[header_rd_idx & mask] = header.raw; + } + } + else // standard entry + { + uint32_t args[6]; + uint32_t * p_arg = args; + char * p_str = (char *)((uint32_t)header.std.addr); + uint32_t nargs = header.std.nargs; + + uint32_t i; + + for (i = 0; i < nargs; i++) + { + *p_arg = m_log_data.buffer[rd_idx++ & mask]; + p_arg++; + } + + ret = m_log_data.std_handler(header.std.severity, + p_timestamp, + p_str, args, nargs); + } + if (ret) + { + m_log_data.rd_idx = rd_idx; + } + return buffer_is_empty() ? false : true; + +} + +uint8_t nrf_log_getchar(void) +{ + return nrf_log_backend_getchar(); +} + +#endif // NRF_MODULE_ENABLED(NRF_LOG) diff --git a/components/libraries/log/src/nrf_log_internal.h b/components/libraries/log/src/nrf_log_internal.h new file mode 100644 index 0000000..1e91cda --- /dev/null +++ b/components/libraries/log/src/nrf_log_internal.h @@ -0,0 +1,309 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_LOG_INTERNAL_H__ +#define NRF_LOG_INTERNAL_H__ +#include "sdk_common.h" +#include "nrf.h" +#include "nrf_error.h" +#include "app_util.h" +#include +#include + +#ifndef NRF_LOG_DEFAULT_LEVEL +#define NRF_LOG_DEFAULT_LEVEL 0 +#endif + +#ifndef NRF_LOG_USES_COLORS +#define NRF_LOG_USES_COLORS 0 +#endif + +#define NRF_LOG_LEVEL_ERROR 1U +#define NRF_LOG_LEVEL_WARNING 2U +#define NRF_LOG_LEVEL_INFO 3U +#define NRF_LOG_LEVEL_DEBUG 4U +#define NRF_LOG_LEVEL_INTERNAL 5U +#define NRF_LOG_LEVEL_MASK 0x07 +#define NRF_LOG_RAW_POS 4U +#define NRF_LOG_RAW (1U << NRF_LOG_RAW_POS) +#define NRF_LOG_LEVEL_INFO_RAW (NRF_LOG_RAW | NRF_LOG_LEVEL_INFO) + + +#define NRF_LOG_COLOR_CODE_DEFAULT "\x1B[0m" +#define NRF_LOG_COLOR_CODE_BLACK "\x1B[1;30m" +#define NRF_LOG_COLOR_CODE_RED "\x1B[1;31m" +#define NRF_LOG_COLOR_CODE_GREEN "\x1B[1;32m" +#define NRF_LOG_COLOR_CODE_YELLOW "\x1B[1;33m" +#define NRF_LOG_COLOR_CODE_BLUE "\x1B[1;34m" +#define NRF_LOG_COLOR_CODE_MAGENTA "\x1B[1;35m" +#define NRF_LOG_COLOR_CODE_CYAN "\x1B[1;36m" +#define NRF_LOG_COLOR_CODE_WHITE "\x1B[1;37m" + +#define NRF_LOG_COLOR_0 NRF_LOG_COLOR_CODE_DEFAULT +#define NRF_LOG_COLOR_1 NRF_LOG_COLOR_CODE_BLACK +#define NRF_LOG_COLOR_2 NRF_LOG_COLOR_CODE_RED +#define NRF_LOG_COLOR_3 NRF_LOG_COLOR_CODE_GREEN +#define NRF_LOG_COLOR_4 NRF_LOG_COLOR_CODE_YELLOW +#define NRF_LOG_COLOR_5 NRF_LOG_COLOR_CODE_BLUE +#define NRF_LOG_COLOR_6 NRF_LOG_COLOR_CODE_MAGENTA +#define NRF_LOG_COLOR_7 NRF_LOG_COLOR_CODE_CYAN +#define NRF_LOG_COLOR_8 NRF_LOG_COLOR_CODE_WHITE + +#define NRF_LOG_COLOR_DECODE(N) CONCAT_2(NRF_LOG_COLOR_, N) +#if NRF_LOG_USES_COLORS +#define NRF_LOG_ERROR_COLOR_CODE NRF_LOG_COLOR_DECODE(NRF_LOG_ERROR_COLOR) +#define NRF_LOG_WARNING_COLOR_CODE NRF_LOG_COLOR_DECODE(NRF_LOG_WARNING_COLOR) +#define NRF_LOG_INFO_COLOR_CODE NRF_LOG_COLOR_DECODE(NRF_LOG_INFO_COLOR) +#define NRF_LOG_DEBUG_COLOR_CODE NRF_LOG_COLOR_DECODE(NRF_LOG_DEBUG_COLOR) +#else // NRF_LOG_USES_COLORS +#define NRF_LOG_ERROR_COLOR_CODE +#define NRF_LOG_WARNING_COLOR_CODE +#define NRF_LOG_INFO_COLOR_CODE +#define NRF_LOG_DEBUG_COLOR_CODE +#endif // NRF_LOG_USES_COLORS + +#define LOG_INTERNAL_0(type, prefix, str) \ + nrf_log_frontend_std_0(type, prefix str) +#define LOG_INTERNAL_1(type, prefix, str, arg0) \ + nrf_log_frontend_std_1(type, prefix str, arg0) +#define LOG_INTERNAL_2(type, prefix, str, arg0, arg1) \ + nrf_log_frontend_std_2(type, prefix str, arg0, arg1) +#define LOG_INTERNAL_3(type, prefix, str, arg0, arg1, arg2) \ + nrf_log_frontend_std_3(type, prefix str, arg0, arg1, arg2) +#define LOG_INTERNAL_4(type, prefix, str, arg0, arg1, arg2, arg3) \ + nrf_log_frontend_std_4(type, prefix str, arg0, arg1, arg2, arg3) +#define LOG_INTERNAL_5(type, prefix, str, arg0, arg1, arg2, arg3, arg4) \ + nrf_log_frontend_std_5(type, prefix str, arg0, arg1, arg2, arg3, arg4) +#define LOG_INTERNAL_6(type, prefix, str, arg0, arg1, arg2, arg3, arg4, arg5) \ + nrf_log_frontend_std_6(type, prefix str, arg0, arg1, arg2, arg3, arg4, arg5) + +#define LOG_INTERNAL_X(N, ...) CONCAT_2(LOG_INTERNAL_, N) (__VA_ARGS__) +#define LOG_INTERNAL(type, prefix, ...) LOG_INTERNAL_X(NUM_VA_ARGS_LESS_1( \ + __VA_ARGS__), type, prefix, __VA_ARGS__) + +#define NRF_LOG_BREAK ":" + +#define LOG_ERROR_PREFIX NRF_LOG_ERROR_COLOR_CODE NRF_LOG_MODULE_NAME NRF_LOG_BREAK "ERROR:" +#define LOG_WARNING_PREFIX NRF_LOG_WARNING_COLOR_CODE NRF_LOG_MODULE_NAME NRF_LOG_BREAK "WARNING:" +#define LOG_INFO_PREFIX NRF_LOG_INFO_COLOR_CODE NRF_LOG_MODULE_NAME NRF_LOG_BREAK "INFO:" +#define LOG_DEBUG_PREFIX NRF_LOG_DEBUG_COLOR_CODE NRF_LOG_MODULE_NAME NRF_LOG_BREAK "DEBUG:" + +#define NRF_LOG_INTERNAL_ERROR(...) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_ERROR) && \ + (NRF_LOG_LEVEL_ERROR <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + LOG_INTERNAL(NRF_LOG_LEVEL_ERROR, LOG_ERROR_PREFIX, __VA_ARGS__); \ + } +#define NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_ERROR) && \ + (NRF_LOG_LEVEL_ERROR <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + nrf_log_frontend_hexdump(NRF_LOG_LEVEL_ERROR, LOG_ERROR_PREFIX "\r\n", (p_data), (len)); \ + } + +#define NRF_LOG_INTERNAL_WARNING(...) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_WARNING) && \ + (NRF_LOG_LEVEL_WARNING <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + LOG_INTERNAL(NRF_LOG_LEVEL_WARNING, LOG_WARNING_PREFIX, __VA_ARGS__); \ + } +#define NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_WARNING) && \ + (NRF_LOG_LEVEL_WARNING <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + nrf_log_frontend_hexdump(NRF_LOG_LEVEL_WARNING, LOG_WARNING_PREFIX "\r\n", (p_data), (len)); \ + } + +#define NRF_LOG_INTERNAL_INFO(...) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \ + (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + LOG_INTERNAL(NRF_LOG_LEVEL_INFO, LOG_INFO_PREFIX, __VA_ARGS__); \ + } + +#define NRF_LOG_INTERNAL_RAW_INFO(...) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \ + (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + LOG_INTERNAL(NRF_LOG_LEVEL_INFO | NRF_LOG_RAW, "", __VA_ARGS__); \ + } + +#define NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \ + (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + nrf_log_frontend_hexdump(NRF_LOG_LEVEL_INFO, LOG_INFO_PREFIX "\r\n", (p_data), (len)); \ + } + +#define NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_INFO) && \ + (NRF_LOG_LEVEL_INFO <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + nrf_log_frontend_hexdump(NRF_LOG_LEVEL_INFO | NRF_LOG_RAW, "", (p_data), (len)); \ + } + +#define NRF_LOG_INTERNAL_DEBUG(...) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_DEBUG) && \ + (NRF_LOG_LEVEL_DEBUG <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + LOG_INTERNAL(NRF_LOG_LEVEL_DEBUG, LOG_DEBUG_PREFIX, __VA_ARGS__); \ + } +#define NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len) \ + if ((NRF_LOG_LEVEL >= NRF_LOG_LEVEL_DEBUG) && \ + (NRF_LOG_LEVEL_DEBUG <= NRF_LOG_DEFAULT_LEVEL)) \ + { \ + nrf_log_frontend_hexdump(NRF_LOG_LEVEL_DEBUG, LOG_DEBUG_PREFIX "\r\n", (p_data), (len)); \ + } + +#if NRF_MODULE_ENABLED(NRF_LOG) +#define NRF_LOG_INTERNAL_GETCHAR() nrf_log_getchar() +#else +#define NRF_LOG_INTERNAL_GETCHAR() (void) +#endif + +/** + * @brief A function for logging raw string. + * + * @param severity Severity. + * @param p_str A pointer to a string. + */ +void nrf_log_frontend_std_0(uint8_t severity, char const * const p_str); + +/** + * @brief A function for logging a formatted string with one argument. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0 An argument. + */ +void nrf_log_frontend_std_1(uint8_t severity, + char const * const p_str, + uint32_t val0); + +/** + * @brief A function for logging a formatted string with 2 arguments. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0, val1 Arguments for formatting string. + */ +void nrf_log_frontend_std_2(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1); + +/** + * @brief A function for logging a formatted string with 3 arguments. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0, val1, val2 Arguments for formatting string. + */ +void nrf_log_frontend_std_3(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2); + +/** + * @brief A function for logging a formatted string with 4 arguments. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0, val1, val2, val3 Arguments for formatting string. + */ +void nrf_log_frontend_std_4(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3); + +/** + * @brief A function for logging a formatted string with 5 arguments. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0, val1, val2, val3, val4 Arguments for formatting string. + */ +void nrf_log_frontend_std_5(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3, + uint32_t val4); + +/** + * @brief A function for logging a formatted string with 6 arguments. + * + * @param severity Severity. + * @param p_str A pointer to a formatted string. + * @param val0, val1, val2, val3, val4, val5 Arguments for formatting string. + */ +void nrf_log_frontend_std_6(uint8_t severity, + char const * const p_str, + uint32_t val0, + uint32_t val1, + uint32_t val2, + uint32_t val3, + uint32_t val4, + uint32_t val5); + +/** + * @brief A function for logging raw data. + * + * @param severity Severity. + * @param p_str A pointer to a string which is prefixing the data. + * @param p_data A pointer to data to be dumped. + * @param length Length of data (in bytes). + * + */ +void nrf_log_frontend_hexdump(uint8_t severity, + char const * const p_str, + const void * const p_data, + uint16_t length); + +/** + * @brief A function for reading a byte from log backend. + * + * @return Byte. + */ +uint8_t nrf_log_getchar(void); +#endif // NRF_LOG_INTERNAL_H__ diff --git a/components/libraries/low_power_pwm/low_power_pwm.c b/components/libraries/low_power_pwm/low_power_pwm.c index c776091..2989892 100644 --- a/components/libraries/low_power_pwm/low_power_pwm.c +++ b/components/libraries/low_power_pwm/low_power_pwm.c @@ -1,14 +1,44 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(LOW_POWER_PWM) #include #include "low_power_pwm.h" #include "nrf_gpio.h" @@ -19,18 +49,18 @@ * @brief Function for turning on LEDs. * * Sets the pin high state according to active_high parameter. - * + * * @param[in] p_pwm_instance Pointer to instance of low-power PWM. */ __STATIC_INLINE void led_on(low_power_pwm_t * p_pwm_instance) { if (p_pwm_instance->active_high) { - nrf_gpio_pins_set(p_pwm_instance->bit_mask); + nrf_gpio_port_out_set(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle); } else { - nrf_gpio_pins_clear(p_pwm_instance->bit_mask); + nrf_gpio_port_out_clear(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle); } p_pwm_instance->led_is_on = true; } @@ -47,11 +77,11 @@ __STATIC_INLINE void led_off(low_power_pwm_t * p_pwm_instance) { if (p_pwm_instance->active_high) { - nrf_gpio_pins_clear(p_pwm_instance->bit_mask); + nrf_gpio_port_out_clear(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle); } else { - nrf_gpio_pins_set(p_pwm_instance->bit_mask); + nrf_gpio_port_out_set(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle); } p_pwm_instance->led_is_on = false; } @@ -68,21 +98,21 @@ static void pwm_timeout_handler(void * p_context) { ret_code_t err_code; uint8_t duty_cycle; - + low_power_pwm_t * p_pwm_instance = (low_power_pwm_t *)p_context; - + p_pwm_instance->pwm_state = NRF_DRV_STATE_INITIALIZED; - - if(p_pwm_instance->evt_type == LOW_POWER_PWM_EVENT_PERIOD) - { + + if (p_pwm_instance->evt_type == LOW_POWER_PWM_EVENT_PERIOD) + { if (p_pwm_instance->handler) { p_pwm_instance->handler(p_pwm_instance); } - + duty_cycle = p_pwm_instance->duty_cycle; - - if(duty_cycle == p_pwm_instance->period) // Process duty cycle 100% + + if (duty_cycle == p_pwm_instance->period) // Process duty cycle 100% { led_on(p_pwm_instance); p_pwm_instance->timeout_ticks = p_pwm_instance->period + APP_TIMER_MIN_TIMEOUT_TICKS; @@ -95,7 +125,7 @@ static void pwm_timeout_handler(void * p_context) else // Process any other duty cycle than 0 or 100% { led_on(p_pwm_instance); - p_pwm_instance->timeout_ticks = ((duty_cycle*p_pwm_instance->period)>>8) + + p_pwm_instance->timeout_ticks = ((duty_cycle * p_pwm_instance->period)>>8) + APP_TIMER_MIN_TIMEOUT_TICKS; // setting next state p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_DUTY_CYCLE; @@ -105,12 +135,13 @@ static void pwm_timeout_handler(void * p_context) { led_off(p_pwm_instance); p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_PERIOD; - p_pwm_instance->timeout_ticks = (((p_pwm_instance->period - p_pwm_instance->duty_cycle)*p_pwm_instance->period)>>8) + + p_pwm_instance->timeout_ticks = (((p_pwm_instance->period - p_pwm_instance->duty_cycle) * p_pwm_instance->period)>>8) + APP_TIMER_MIN_TIMEOUT_TICKS; } - + if (p_pwm_instance->pwm_state == NRF_DRV_STATE_INITIALIZED) { + p_pwm_instance->pwm_state = NRF_DRV_STATE_POWERED_ON; err_code = app_timer_start(*p_pwm_instance->p_timer_id, p_pwm_instance->timeout_ticks, p_pwm_instance); APP_ERROR_CHECK(err_code); } @@ -118,24 +149,27 @@ static void pwm_timeout_handler(void * p_context) ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance, low_power_pwm_config_t const * p_pwm_config, app_timer_timeout_handler_t handler) -{ +{ ASSERT(p_pwm_instance->pwm_state == NRF_DRV_STATE_UNINITIALIZED); ASSERT(p_pwm_config->bit_mask != 0); + ASSERT(p_pwm_config->p_port != NULL); ASSERT(p_pwm_config->period != 0); - + ret_code_t err_code; uint32_t bit_mask; uint32_t pin_number = 0; - + p_pwm_instance->handler = handler; - + bit_mask = p_pwm_config->bit_mask; - + p_pwm_instance->active_high = p_pwm_config->active_high; p_pwm_instance->bit_mask = p_pwm_config->bit_mask; + p_pwm_instance->bit_mask_toggle = p_pwm_config->bit_mask; + p_pwm_instance->p_port = p_pwm_config->p_port; p_pwm_instance->period = p_pwm_config->period; p_pwm_instance->p_timer_id = p_pwm_config->p_timer_id; - + err_code = app_timer_create(p_pwm_instance->p_timer_id, APP_TIMER_MODE_SINGLE_SHOT, pwm_timeout_handler); if (err_code != NRF_SUCCESS) @@ -153,9 +187,8 @@ ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance, low_power_pwm_co pin_number++; bit_mask >>= 1UL; } - + led_off(p_pwm_instance); - p_pwm_instance->pwm_state = NRF_DRV_STATE_INITIALIZED; return NRF_SUCCESS; @@ -165,13 +198,18 @@ ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance, low_power_pwm_co ret_code_t low_power_pwm_start(low_power_pwm_t * p_pwm_instance, uint32_t leds_pin_bit_mask) { - ASSERT(p_pwm_instance->pwm_state == NRF_DRV_STATE_INITIALIZED); + ASSERT(p_pwm_instance->pwm_state != NRF_DRV_STATE_UNINITIALIZED); + ASSERT(((p_pwm_instance->bit_mask) & leds_pin_bit_mask) != 0x00); + p_pwm_instance->pwm_state = NRF_DRV_STATE_POWERED_ON; + p_pwm_instance->bit_mask_toggle = leds_pin_bit_mask; + + led_off(p_pwm_instance); + + p_pwm_instance->bit_mask |= leds_pin_bit_mask; p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_PERIOD; pwm_timeout_handler(p_pwm_instance); - p_pwm_instance->pwm_state = NRF_DRV_STATE_POWERED_ON; - return NRF_SUCCESS; } @@ -180,12 +218,12 @@ ret_code_t low_power_pwm_stop(low_power_pwm_t * p_pwm_instance) { ASSERT(p_pwm_instance->pwm_state == NRF_DRV_STATE_POWERED_ON); - ret_code_t err_code; - - led_off(p_pwm_instance); + ret_code_t err_code; err_code = app_timer_stop(*p_pwm_instance->p_timer_id); + led_off(p_pwm_instance); + if (err_code != NRF_SUCCESS) { return err_code; @@ -209,3 +247,4 @@ ret_code_t low_power_pwm_duty_set(low_power_pwm_t * p_pwm_instance, uint8_t duty return NRF_SUCCESS; } +#endif //NRF_MODULE_ENABLED(LOW_POWER_PWM) diff --git a/components/libraries/low_power_pwm/low_power_pwm.h b/components/libraries/low_power_pwm/low_power_pwm.h index b3711c8..8e70328 100644 --- a/components/libraries/low_power_pwm/low_power_pwm.h +++ b/components/libraries/low_power_pwm/low_power_pwm.h @@ -1,15 +1,43 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * * @defgroup low_power_pwm Low-power PWM @@ -18,10 +46,11 @@ * * @brief Module for generating a low-power pulse-width modulated output signal. * - * This module provides a low-power PWM implementation using timers and GPIO. + * This module provides a low-power PWM implementation using app_timers and GPIO. * - * Each low-power PWM instance utilizes one timer. There can be any - * number of output channels per instance. + * Each low-power PWM instance utilizes one app_timer. This means it runs on RTC + * and does not require HFCLK to be running. There can be any number of output + * channels per instance. */ #ifndef LOW_POWER_PWM_H__ @@ -33,12 +62,16 @@ #include "nrf_drv_common.h" #include "sdk_errors.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Event types. */ typedef enum { - LOW_POWER_PWM_EVENT_PERIOD = 0, + LOW_POWER_PWM_EVENT_PERIOD = 0, LOW_POWER_PWM_EVENT_DUTY_CYCLE }low_power_pwm_evt_type_t; @@ -50,10 +83,11 @@ typedef void (*low_power_pwm_timeout_user)(void * p_context, low_power_pwm_evt_t */ typedef struct { - bool active_high; /**< Activate negative polarity. */ - uint8_t period; /**< Width of the low_power_pwm period. */ - uint32_t bit_mask; /**< Pins to be toggled. */ - app_timer_id_t const * p_timer_id; /**< Pointer to the timer ID of low_power_pwm. */ + bool active_high; /**< Activate negative polarity. */ + uint8_t period; /**< Width of the low_power_pwm period. */ + NRF_GPIO_Type * p_port; /**< Port used to work on selected mask. */ + uint32_t bit_mask; /**< Pins to be initialized. */ + app_timer_id_t const * p_timer_id; /**< Pointer to the timer ID of low_power_pwm. */ } low_power_pwm_config_t; @@ -66,23 +100,25 @@ typedef struct */ #define LOW_POWER_PWM_CONFIG_ACTIVE_HIGH false #define LOW_POWER_PWM_CONFIG_PERIOD UINT8_MAX +#define LOW_POWER_PWM_CONFIG_PORT NRF_GPIO #define LOW_POWER_PWM_CONFIG_BIT_MASK(mask) (mask) /** @} */ /** * @brief Low-power PWM default configuration. */ -#define LOW_POWER_PWM_DEFAULT_CONFIG(mask) \ -{ \ - .active_high = LOW_POWER_PWM_CONFIG_ACTIVE_HIGH , \ - .period = LOW_POWER_PWM_CONFIG_PERIOD , \ - .bit_mask = LOW_POWER_PWM_CONFIG_BIT_MASK(mask) \ +#define LOW_POWER_PWM_DEFAULT_CONFIG(mask) \ +{ \ + .active_high = LOW_POWER_PWM_CONFIG_ACTIVE_HIGH , \ + .period = LOW_POWER_PWM_CONFIG_PERIOD , \ + .p_port = LOW_POWER_PWM_CONFIG_PORT, \ + .bit_mask = LOW_POWER_PWM_CONFIG_BIT_MASK(mask) \ } -/** +/** * @cond (NODOX) * @defgroup low_power_pwm_internal Auxiliary internal types declarations * @brief Module for internal usage inside the library only. - * @details These definitions are available to the user, but they should not + * @details These definitions are available to the user, but they should not * be accessed directly. Use @ref low_power_pwm_duty_set instead. * @{ * @@ -98,14 +134,16 @@ typedef struct uint8_t period; /**< Width of the low_power_pwm period. */ uint8_t duty_cycle; /**< Width of high pulse. */ nrf_drv_state_t pwm_state; /**< Indicates the current state of the PWM instance. */ - uint32_t bit_mask; /**< Pins to be toggled. */ + uint32_t bit_mask; /**< Pins to be initialized. */ + uint32_t bit_mask_toggle; /**< Pins to be toggled. */ uint32_t timeout_ticks; /**< Value to start the next app_timer. */ low_power_pwm_evt_type_t evt_type; /**< Slope that triggered time-out. */ app_timer_timeout_handler_t handler; /**< User handler to be called in the time-out handler. */ app_timer_id_t const * p_timer_id; /**< Pointer to the timer ID of low_power_pwm. */ + NRF_GPIO_Type * p_port; /**< Port used with pin bit mask. */ }; -/** @} +/** @} * @endcond */ @@ -114,7 +152,7 @@ typedef struct */ typedef struct low_power_pwm_s low_power_pwm_t; - + /** * @brief Function for initializing a low-power PWM instance. * @@ -124,9 +162,11 @@ typedef struct low_power_pwm_s low_power_pwm_t; * * @return Values returned by @ref app_timer_create. */ -ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance, low_power_pwm_config_t const * p_pwm_config, app_timer_timeout_handler_t handler); - - +ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance, + low_power_pwm_config_t const * p_pwm_config, + app_timer_timeout_handler_t handler); + + /** * @brief Function for starting a low-power PWM instance. * @@ -136,7 +176,8 @@ ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance, low_power_pwm_co * @return Values returned by @ref app_timer_start. */ ret_code_t low_power_pwm_start(low_power_pwm_t * p_pwm_instance, - uint32_t leds_pin_bit_mask); + uint32_t leds_pin_bit_mask); + /** * @brief Function for stopping a low-power PWM instance. @@ -161,6 +202,11 @@ ret_code_t low_power_pwm_stop(low_power_pwm_t * p_pwm_instance); */ ret_code_t low_power_pwm_duty_set(low_power_pwm_t * p_pwm_instance, uint8_t duty_cycle); + +#ifdef __cplusplus +} +#endif + #endif // LOW_POWER_PWM_H__ /** @} */ diff --git a/components/libraries/mailbox/app_mailbox.c b/components/libraries/mailbox/app_mailbox.c index 2d3ff0a..52864d6 100644 --- a/components/libraries/mailbox/app_mailbox.c +++ b/components/libraries/mailbox/app_mailbox.c @@ -1,14 +1,45 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + +#include "sdk_config.h" +#if APP_MAILBOX_ENABLED #include #include #include "app_mailbox.h" @@ -150,3 +181,4 @@ void app_mailbox_mode_set(const app_mailbox_t * p_mailbox, app_mailbox_overflow_ ASSERT(p_mailbox); p_mailbox->p_cb->mode = mode; } +#endif //APP_MAILBOX_ENABLED diff --git a/components/libraries/mailbox/app_mailbox.h b/components/libraries/mailbox/app_mailbox.h index 967e5c3..e040567 100644 --- a/components/libraries/mailbox/app_mailbox.h +++ b/components/libraries/mailbox/app_mailbox.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -39,6 +67,10 @@ typedef enum #include "app_mailbox_local.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Mailbox definition structure. */ @@ -54,7 +86,7 @@ typedef struct * @brief Macro to statically allocate memory for a given mailbox queue. */ #define APP_MAILBOX_DEF(name, QUEUE_SZ, ITEM_SZ) \ -static uint32_t STRING_CONCATENATE(mailbox_items_,name)[(1+CEIL_DIV((ITEM_SZ),4))*(QUEUE_SZ)];\ +static uint32_t STRING_CONCATENATE(mailbox_items_,name)[(1 + CEIL_DIV((ITEM_SZ),4)) * (QUEUE_SZ)];\ static app_mailbox_cb_t STRING_CONCATENATE(mailbox_cb_,name); \ const app_mailbox_t name = \ { \ @@ -139,5 +171,10 @@ uint32_t app_mailbox_length_get (const app_mailbox_t * p_mailbox); */ void app_mailbox_mode_set(const app_mailbox_t * p_mailbox, app_mailbox_overflow_mode_t mode); + +#ifdef __cplusplus +} +#endif + #endif //_APP_MAILBOX_H /** @} */ diff --git a/components/libraries/mailbox/app_mailbox_local.h b/components/libraries/mailbox/app_mailbox_local.h index ed8ddc4..a85690f 100644 --- a/components/libraries/mailbox/app_mailbox_local.h +++ b/components/libraries/mailbox/app_mailbox_local.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -24,18 +52,31 @@ * However, any functions and variables defined here may change at any time * without a warning, so you should not access them directly. */ - /** - * @brief Mailbox handle used for managing a mailbox queue. - */ - typedef struct - { - uint8_t r_idx; /**< Read index for the mailbox queue. */ - uint8_t w_idx; /**< Write index for the mailbox queue. */ - uint8_t len; /**< Number of elements currently in the mailbox queue. */ - app_mailbox_overflow_mode_t mode; /**< Mode of overflow handling. */ - } app_mailbox_cb_t; +#ifndef APP_MAILBOX_LOCAL_H__ +#define APP_MAILBOX_LOCAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * @brief Mailbox handle used for managing a mailbox queue. + */ +typedef struct +{ + uint8_t r_idx; /**< Read index for the mailbox queue. */ + uint8_t w_idx; /**< Write index for the mailbox queue. */ + uint8_t len; /**< Number of elements currently in the mailbox queue. */ + app_mailbox_overflow_mode_t mode; /**< Mode of overflow handling. */ +} app_mailbox_cb_t; + +#ifdef __cplusplus +} +#endif + +#endif // APP_MAILBOX_LOCAL_H__ -/** @} +/** @} * @endcond */ diff --git a/components/libraries/mem_manager/mem_manager.c b/components/libraries/mem_manager/mem_manager.c index 587d985..0cf086c 100644 --- a/components/libraries/mem_manager/mem_manager.c +++ b/components/libraries/mem_manager/mem_manager.c @@ -1,54 +1,48 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -#include "sdk_config.h" #include "sdk_common.h" +#if NRF_MODULE_ENABLED(MEM_MANAGER) #include "mem_manager.h" -#include "app_trace.h" #include "nrf_assert.h" - -/** - * @defgroup mem_manager_log Module's Log Macros - * - * @details Macros used for creating module logs which can be useful in understanding handling - * of events or actions on API requests. These are intended for debugging purposes and - * can be enabled by defining the MEM_MANAGER_ENABLE_LOGS. - * - * @note If ENABLE_DEBUG_LOG_SUPPORT is disabled, having MEM_MANAGER_ENABLE_LOGS has no effect. - * @{ - */ -#if (MEM_MANAGER_ENABLE_LOGS == 1) - -#define MM_LOG app_trace_log /**< Used for logging details. */ -#define MM_ERR app_trace_log /**< Used for logging errors in the module. */ -#define MM_TRC app_trace_log /**< Used for getting trace of execution in the module. */ -#define MM_DUMP app_trace_dump /**< Used for dumping octet information. */ - -#else //MEM_MANAGER_ENABLE_LOGS - -#define MM_DUMP(...) /**< Disables dumping of octet streams. */ -#define MM_LOG(...) /**< Disables detailed logs. */ -#define MM_ERR(...) /**< Disables error logs. */ -#define MM_TRC(...) /**< Disables traces. */ - -#endif //MEM_MANAGER_ENABLE_LOGS -/** @} */ - -#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS -#if (MEM_MANAGER_DIAGNOSTICS_LOGS_ONLY == 1) -#define MMD_LOG app_trace_log /**< Used for logging diagnostic details. */ -#else -#define MMD_LOG MM_LOG /**< Diagnostoc logs same as other module logs, and depend on definition of MEM_MANAGER_ENABLE_LOGS */ -#endif //MEM_MANAGER_DIAGNOSTICS_LOGS_ONLY -#endif //MEM_MANAGER_ENABLE_DIAGNOSTICS +#define NRF_LOG_MODULE_NAME "MEM_MNGR" +#include "nrf_log.h" /** * @defgroup memory_manager_mutex_lock_unlock Module's Mutex Lock/Unlock Macros. @@ -61,6 +55,13 @@ #define MM_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_mm_mutex) /**< Unlock module using mutex. */ /** @} */ +#undef NULL_PARAM_CHECK +#undef NULL_PARAM_CHECK_VOID +#undef VERIFY_MODULE_INITIALIZED +#undef VERIFY_MODULE_INITIALIZED_VOID +#undef VERIFY_REQUESTED_SIZE +#undef VERIFY_REQUESTED_SIZE_VOID + #if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0) /** @@ -69,12 +70,12 @@ * * @param[in] PARAM Parameter checked for NULL. * - * @retval (NRF_ERROR_NULL | MEMORY_MANAGER_ERR_BASE) when @ref PARAM is NULL. + * @retval (NRF_ERROR_NULL | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) when @ref PARAM is NULL. */ #define NULL_PARAM_CHECK(PARAM) \ if ((PARAM) == NULL) \ { \ - return (NRF_ERROR_NULL | MEMORY_MANAGER_ERR_BASE); \ + return (NRF_ERROR_NULL | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \ } /** @@ -93,14 +94,14 @@ * @brief Macro for verifying module's initialization status. * Returning with an appropriate error code on failure. * - * @retval (NRF_ERROR_INVALID_STATE | MEMORY_MANAGER_ERR_BASE) module is uninitialized. + * @retval (NRF_ERROR_INVALID_STATE | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) module is uninitialized. */ #define VERIFY_MODULE_INITIALIZED() \ do \ { \ if (!m_module_initialized) \ { \ - return (NRF_ERROR_INVALID_STATE | MEMORY_MANAGER_ERR_BASE); \ + return (NRF_ERROR_INVALID_STATE | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \ } \ } while (0) @@ -123,7 +124,7 @@ * * @param[in] SIZE Requested size to be allocated. * - * @retval (NRF_ERROR_INVALID_PARAM | MEMORY_MANAGER_ERR_BASE) if requested size is greater + * @retval (NRF_ERROR_INVALID_PARAM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) if requested size is greater * than the largest block size managed by the module. */ #define VERIFY_REQUESTED_SIZE(SIZE) \ @@ -131,7 +132,7 @@ { \ if (((SIZE) == 0) ||((SIZE) > MAX_MEM_SIZE)) \ { \ - return (NRF_ERROR_INVALID_PARAM | MEMORY_MANAGER_ERR_BASE); \ + return (NRF_ERROR_INVALID_PARAM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \ } \ } while (0) @@ -540,8 +541,8 @@ static __INLINE void get_block_coordinates(uint32_t block_index, uint32_t * p_x, { // Determine position of the block in the bitmap. // X determines relevant word for the block. Y determines the actual bit in the word. - const uint32_t x = block_index/BITMAP_SIZE; - const uint32_t y = (block_index - x*BITMAP_SIZE); + const uint32_t x = block_index / BITMAP_SIZE; + const uint32_t y = (block_index - x * BITMAP_SIZE); (*p_x) = x; (*p_y) = y; @@ -624,7 +625,7 @@ static void block_allocate(uint32_t block_index) uint32_t nrf_mem_init(void) { - MM_LOG("[MM]: >> nrf_mem_init.\r\n"); + NRF_LOG_DEBUG("[MM]: >> nrf_mem_init.\r\n"); SDK_MUTEX_INIT(m_mm_mutex); @@ -632,7 +633,7 @@ uint32_t nrf_mem_init(void) uint32_t block_index = 0; - for(block_index = 0; block_index < TOTAL_BLOCK_COUNT; block_index++) + for (block_index = 0; block_index < TOTAL_BLOCK_COUNT; block_index++) { block_init(block_index); } @@ -647,7 +648,7 @@ uint32_t nrf_mem_init(void) MM_MUTEX_UNLOCK(); - MM_LOG("[MM]: << nrf_mem_init.\r\n"); + NRF_LOG_DEBUG("[MM]: << nrf_mem_init.\r\n"); return NRF_SUCCESS; } @@ -663,16 +664,16 @@ uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size) VERIFY_REQUESTED_SIZE(requested_size); - MM_LOG("[MM]: >> nrf_mem_reserve, size 0x%04lX.\r\n", requested_size); + NRF_LOG_DEBUG("[MM]: >> nrf_mem_reserve, size 0x%04lX.\r\n", requested_size); MM_MUTEX_LOCK(); const uint32_t block_cat = get_block_cat(requested_size, TOTAL_BLOCK_COUNT); uint32_t block_index = m_block_start[block_cat]; uint32_t memory_index = m_block_mem_start[block_cat]; - uint32_t err_code = (NRF_ERROR_NO_MEM | MEMORY_MANAGER_ERR_BASE); + uint32_t err_code = (NRF_ERROR_NO_MEM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); - MM_LOG("[MM]: Start index for the pool = 0x%08lX, total block count 0x%08X\r\n", + NRF_LOG_DEBUG("[MM]: Start index for the pool = 0x%08lX, total block count 0x%08X\r\n", block_index, TOTAL_BLOCK_COUNT); @@ -682,7 +683,7 @@ uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size) if (is_block_free(block_index) == true) { - MM_LOG("[MM]: Reserving block 0x%08lX\r\n", block_index); + NRF_LOG_DEBUG("[MM]: Reserving block 0x%08lX\r\n", block_index); // Search succeeded, found free block. err_code = NRF_SUCCESS; @@ -704,9 +705,9 @@ uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size) } if (err_code != NRF_SUCCESS) { - MM_LOG ("[MM]: Memory reservation result %d, memory %p, size %d!", + NRF_LOG_DEBUG ("[MM]: Memory reservation result %d, memory %p, size %d!", err_code, - (*pp_buffer), + (uint32_t)(*pp_buffer), (*p_size)); #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS @@ -716,7 +717,8 @@ uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size) MM_MUTEX_UNLOCK(); - MM_LOG("[MM]: << nrf_mem_reserve %p, result 0x%08lX.\r\n", (*pp_buffer), err_code); + NRF_LOG_DEBUG("[MM]: << nrf_mem_reserve %p, result 0x%08lX.\r\n", + (uint32_t)(*pp_buffer), err_code); return err_code; } @@ -743,17 +745,17 @@ void * nrf_calloc(uint32_t count, uint32_t size) uint8_t * buffer = NULL; uint32_t allocated_size = (size * count); - MM_LOG ("[nrf_calloc]: Requested size %d, count %d\r\n", allocated_size, count); + NRF_LOG_DEBUG ("[nrf_calloc]: Requested size %d, count %d\r\n", allocated_size, count); uint32_t retval = nrf_mem_reserve(&buffer,&allocated_size); if (retval == NRF_SUCCESS) { - MM_LOG ("[nrf_calloc]: buffer %p, total size %d\r\n", buffer, allocated_size); + NRF_LOG_DEBUG ("[nrf_calloc]: buffer %p, total size %d\r\n", (uint32_t)buffer, allocated_size); memset(buffer,0, allocated_size); } else { - MM_LOG("[nrf_calloc]: Failed to allocate memory %d\r\n", allocated_size); + NRF_LOG_DEBUG("[nrf_calloc]: Failed to allocate memory %d\r\n", allocated_size); buffer = NULL; } @@ -766,7 +768,7 @@ void nrf_free(void * p_mem) VERIFY_MODULE_INITIALIZED_VOID(); NULL_PARAM_CHECK_VOID(p_mem); - MM_LOG("[MM]: >> nrf_free %p.\r\n", p_mem); + NRF_LOG_DEBUG("[MM]: >> nrf_free %p.\r\n", (uint32_t)p_mem); MM_MUTEX_LOCK(); @@ -778,7 +780,7 @@ void nrf_free(void * p_mem) if (&m_memory[memory_index] == p_mem) { // Found a free block of memory, assign. - MM_LOG("[MM]: << Freeing block %d.\r\n", index); + NRF_LOG_DEBUG("[MM]: << Freeing block %d.\r\n", index); block_init(index); break; } @@ -787,7 +789,7 @@ void nrf_free(void * p_mem) MM_MUTEX_UNLOCK(); - MM_LOG("[MM]: << nrf_free.\r\n"); + NRF_LOG_DEBUG("[MM]: << nrf_free.\r\n"); return; } @@ -884,7 +886,7 @@ void print_block_info(uint32_t block_cat, uint32_t * p_mem_in_use) } snprintf(&print_buffer[column_end], 2, "|"); - MMD_LOG("%s\r\n", print_buffer); + NRF_LOG_BYTES_DEBUG(print_buffer, strlen(print_buffer)); (*p_mem_in_use) += in_use; } @@ -895,10 +897,10 @@ void nrf_mem_diagnose(void) { uint32_t in_use = 0; - MMD_LOG ("\r\n"); - MMD_LOG ("+------------+------------+------------+------------+------------+------------+\r\n"); - MMD_LOG ("| Block | Size | Total | In Use | Min Alloc | Max Alloc |\r\n"); - MMD_LOG ("+------------+------------+------------+------------+------------+------------+\r\n"); + NRF_LOG_DEBUG ("\r\n"); + NRF_LOG_DEBUG ("+------------+------------+------------+------------+------------+------------+\r\n"); + NRF_LOG_DEBUG ("| Block | Size | Total | In Use | Min Alloc | Max Alloc |\r\n"); + NRF_LOG_DEBUG ("+------------+------------+------------+------------+------------+------------+\r\n"); print_block_info(BLOCK_CAT_XXS, &in_use); print_block_info(BLOCK_CAT_XS, &in_use); @@ -908,11 +910,12 @@ void nrf_mem_diagnose(void) print_block_info(BLOCK_CAT_XL, &in_use); print_block_info(BLOCK_CAT_XXL, &in_use); - MMD_LOG ("+------------+------------+------------+------------+------------+------------+\r\n"); - MMD_LOG ("| Total | %d | %d | %d\r\n", + NRF_LOG_DEBUG ("+------------+------------+------------+------------+------------+------------+\r\n"); + NRF_LOG_DEBUG ("| Total | %d | %d | %d\r\n", TOTAL_MEMORY_SIZE, TOTAL_BLOCK_COUNT,in_use); - MMD_LOG ("+------------+------------+------------+------------+------------+------------+\r\n"); + NRF_LOG_DEBUG ("+------------+------------+------------+------------+------------+------------+\r\n"); } #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS /** @} */ +#endif //NRF_MODULE_ENABLED(MEM_MANAGER) diff --git a/components/libraries/mem_manager/mem_manager.h b/components/libraries/mem_manager/mem_manager.h index c65f7d7..5dee333 100644 --- a/components/libraries/mem_manager/mem_manager.h +++ b/components/libraries/mem_manager/mem_manager.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -36,6 +64,10 @@ #include "sdk_common.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Initializes Memory Manager. * @@ -135,5 +167,10 @@ void nrf_mem_diagnose(void); #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS + +#ifdef __cplusplus +} +#endif + #endif // MEM_MANAGER_H__ /** @} */ diff --git a/components/libraries/pwm/app_pwm.c b/components/libraries/pwm/app_pwm.c index 9ad4a7a..a496920 100644 --- a/components/libraries/pwm/app_pwm.c +++ b/components/libraries/pwm/app_pwm.c @@ -1,15 +1,44 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_PWM) #include "app_pwm.h" #include "nrf_drv_timer.h" #include "nrf_drv_ppi.h" @@ -17,7 +46,6 @@ #include "nrf_drv_gpiote.h" #include "nrf_gpiote.h" #include "nrf_gpio.h" -#include "app_util.h" #include "app_util_platform.h" #include "nrf_assert.h" @@ -30,7 +58,9 @@ #define TIMER_PRESCALER_MAX 9 #define TIMER_MAX_PULSEWIDTH_US_ON_16M 4095 +#ifndef GPIOTE_SET_CLEAR_TASKS #define APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE 2 +#endif #define APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL 2 #define UNALLOCATED 0xFFFFFFFFUL @@ -40,6 +70,11 @@ #define PWM_MAIN_CC_CHANNEL 2 #define PWM_SECONDARY_CC_CHANNEL 3 +#ifdef GPIOTE_SET_CLEAR_TASKS +static bool m_use_ppi_delay_workaround; +#endif + + /** * @brief PWM busy status * @@ -82,6 +117,7 @@ static const app_pwm_t * m_instances[TIMER_COUNT]; //lint -save -e534 + /** * @brief Workaround for PAN-73. * @@ -90,7 +126,7 @@ static const app_pwm_t * m_instances[TIMER_COUNT]; */ static void pan73_workaround(NRF_TIMER_Type * p_timer, bool enable) { -#ifdef NRF51 +#ifndef GPIOTE_SET_CLEAR_TASKS if (p_timer == NRF_TIMER0) { *(uint32_t *)0x40008C0C = (enable ? 1 : 0); @@ -103,11 +139,12 @@ static void pan73_workaround(NRF_TIMER_Type * p_timer, bool enable) { *(uint32_t *)0x4000AC0C = (enable ? 1 : 0); } +#else + UNUSED_PARAMETER(p_timer); + UNUSED_PARAMETER(enable); #endif - return; } - bool app_pwm_busy_check(app_pwm_t const * const p_instance) { uint8_t busy_state = (m_pwm_busy[p_instance->p_timer->instance_id]); @@ -116,7 +153,7 @@ bool app_pwm_busy_check(app_pwm_t const * const p_instance) { if (busy_state != BUSY_STATE_CHANGING) { - if (nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) busy_state) + if (nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) busy_state) == m_pwm_target_value[p_instance->p_timer->instance_id]) { m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; @@ -153,7 +190,7 @@ __STATIC_INLINE void pwm_irq_disable(app_pwm_t const * const p_instance) nrf_drv_timer_compare_int_disable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL); } - +#ifndef GPIOTE_SET_CLEAR_TASKS /** * @brief Function for disabling PWM channel PPI. * @@ -180,7 +217,7 @@ __STATIC_INLINE void pwm_ppi_disable(app_pwm_t const * const p_instance) nrf_drv_ppi_channel_disable(p_cb->ppi_channels[0]); nrf_drv_ppi_channel_disable(p_cb->ppi_channels[1]); } - +#endif /** * @brief This function is called on interrupt after duty set. @@ -192,7 +229,7 @@ void pwm_ready_tick(nrf_timer_event_t event_type, void * p_context) { uint32_t timer_instance_id = (uint32_t)p_context; uint8_t disable = 1; - + for (uint8_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel) { if (m_pwm_ready_counter[timer_instance_id][channel]) @@ -209,7 +246,7 @@ void pwm_ready_tick(nrf_timer_event_t event_type, void * p_context) } } } - + if (disable) { pwm_irq_disable(m_instances[timer_instance_id]); @@ -227,6 +264,9 @@ static void pwm_dealloc(app_pwm_t const * const p_instance) { app_pwm_cb_t * p_cb = p_instance->p_cb; +#ifdef GPIOTE_SET_CLEAR_TASKS + nrf_drv_ppi_channel_free(p_cb->ppi_channel); +#else for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++i) { if (p_cb->ppi_channels[i] != (nrf_ppi_channel_t)(uint8_t)(UNALLOCATED)) @@ -238,7 +278,7 @@ static void pwm_dealloc(app_pwm_t const * const p_instance) { nrf_drv_ppi_group_free(p_cb->ppi_group); } - +#endif //GPIOTE_SET_CLEAR_TASKS for (uint8_t ch = 0; ch < APP_PWM_CHANNELS_PER_INSTANCE; ++ch) { for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL; ++i) @@ -260,7 +300,7 @@ static void pwm_dealloc(app_pwm_t const * const p_instance) return; } - +#ifndef GPIOTE_SET_CLEAR_TASKS /** * @brief PWM state transition from (0%, 100%) to 0% or 100%. * @@ -278,7 +318,7 @@ static void pwm_transition_n_to_0or100(app_pwm_t const * const p_instance, pwm_ppi_disable(p_instance); nrf_drv_ppi_group_clear(p_ppigrp); nrf_drv_ppi_channels_include_in_group( - nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[0]) | + nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[0]) | nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[1]), p_ppigrp); @@ -308,10 +348,10 @@ static void pwm_transition_n_to_0or100(app_pwm_t const * const p_instance, nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL), nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL)); } - + nrf_drv_ppi_channel_enable(p_cb->ppi_channels[0]); nrf_drv_ppi_channel_enable(p_cb->ppi_channels[1]); - + p_ch_cb->pulsewidth = ticks; m_pwm_busy[p_instance->p_timer->instance_id] = PWM_SECONDARY_CC_CHANNEL; } @@ -334,7 +374,7 @@ static void pwm_transition_n_to_m(app_pwm_t const * const p_instance, pwm_ppi_disable(p_instance); nrf_drv_ppi_group_clear(p_ppigrp); nrf_drv_ppi_channels_include_in_group( - nrf_drv_ppi_channel_to_mask(p_cb->ppi_channels[0]) | + nrf_drv_ppi_channel_to_mask(p_cb->ppi_channels[0]) | nrf_drv_ppi_channel_to_mask(p_cb->ppi_channels[1]), p_ppigrp); @@ -342,11 +382,12 @@ static void pwm_transition_n_to_m(app_pwm_t const * const p_instance, nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL), nrf_drv_timer_capture_task_address_get(p_instance->p_timer, channel)); + if (ticks + ((nrf_timer_frequency_get(p_instance->p_timer->p_reg) == NRF_TIMER_FREQ_16MHz) ? 1 : 0) < p_ch_cb->pulsewidth) { // For lower value, we need one more transition. Timer task delay is included. - // If prescaler is enabled, one tick must be added because of 1 PCLK16M clock cycle delay. + // If prescaler is disabled, one tick must be added because of 1 PCLK16M clock cycle delay. nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1], nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL), nrf_drv_gpiote_out_task_addr_get(p_ch_cb->gpio_pin)); @@ -358,7 +399,7 @@ static void pwm_transition_n_to_m(app_pwm_t const * const p_instance, p_ch_cb->pulsewidth = ticks; nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, ticks, false); nrf_drv_ppi_group_enable(p_ppigrp); - + m_pwm_target_value[p_instance->p_timer->instance_id] = ticks; m_pwm_busy[p_instance->p_timer->instance_id] = channel; } @@ -396,12 +437,12 @@ static void pwm_transition_0or100_to_n(app_pwm_t const * const p_instance, nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel), nrf_drv_ppi_task_addr_group_enable_get(p_ppigrp)); nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 0, false); - m_pwm_target_value[p_instance->p_timer->instance_id] = + m_pwm_target_value[p_instance->p_timer->instance_id] = nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) channel); nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1], nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel), nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL)); - + } else { @@ -419,7 +460,7 @@ static void pwm_transition_0or100_to_n(app_pwm_t const * const p_instance, } nrf_drv_ppi_channel_enable(p_cb->ppi_channels[0]); nrf_drv_ppi_channel_enable(p_cb->ppi_channels[1]); - + p_ch_cb->pulsewidth = ticks; m_pwm_busy[p_instance->p_timer->instance_id] = PWM_SECONDARY_CC_CHANNEL; } @@ -454,40 +495,16 @@ static void pwm_transition_0or100_to_0or100(app_pwm_t const * const p_instance, } nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false); p_ch_cb->pulsewidth = ticks; - + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; return; } - -ret_code_t app_pwm_channel_duty_ticks_set(app_pwm_t const * const p_instance, - uint8_t channel, - uint16_t ticks) +static void pwm_transition(app_pwm_t const * const p_instance, + uint8_t channel, uint16_t ticks) { - app_pwm_cb_t * p_cb = p_instance->p_cb; - app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; - - ASSERT(channel < APP_PWM_CHANNELS_PER_INSTANCE); - ASSERT(p_ch_cb->initialized == APP_PWM_CHANNEL_INITIALIZED); - - if (p_cb->state != NRF_DRV_STATE_POWERED_ON) - { - return NRF_ERROR_INVALID_STATE; - } - if (ticks == p_ch_cb->pulsewidth) - { - if (p_cb->p_ready_callback) - { - p_cb->p_ready_callback(p_instance->p_timer->instance_id); - } - return NRF_SUCCESS; // No action required. - } - if (app_pwm_busy_check(p_instance)) - { - return NRF_ERROR_BUSY; // PPI channels for synchronization are still in use. - } - - m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_CHANGING; + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_instance->p_cb->channels_cb[channel]; // Pulse width change sequence: if (!p_ch_cb->pulsewidth || p_ch_cb->pulsewidth >= p_cb->period) @@ -518,6 +535,98 @@ ret_code_t app_pwm_channel_duty_ticks_set(app_pwm_t const * const p_instance, pwm_transition_n_to_m(p_instance, channel, ticks); } } +} +#else //GPIOTE_SET_CLEAR_TASKS +/** + * @brief PWM state transition. + * + * @param[in] p_instance PWM instance. + * @param[in] channel PWM channel number. + * @param[in] ticks Number of clock ticks. + */ +static void pwm_transition(app_pwm_t const * const p_instance, + uint8_t channel, uint16_t ticks) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + nrf_timer_cc_channel_t pwm_ch_cc = (nrf_timer_cc_channel_t)(channel); + + nrf_drv_ppi_channel_disable(p_cb->ppi_channel); + + if (!ticks) + { + nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[1]); + nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[0]); + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + } + else if (ticks >= p_cb->period) + { + ticks = p_cb->period; + nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[0]); + nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[1]); + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + } + else + { + // Set to any other value. + if ((p_ch_cb->pulsewidth != p_cb->period) && (p_ch_cb->pulsewidth != 0) && (ticks < p_ch_cb->pulsewidth)) + { + nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t)PWM_SECONDARY_CC_CHANNEL, p_ch_cb->pulsewidth, false); + nrf_drv_ppi_channel_assign(p_cb->ppi_channel, + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, (nrf_timer_cc_channel_t)PWM_SECONDARY_CC_CHANNEL), + p_ch_cb->polarity ? nrf_drv_gpiote_clr_task_addr_get(p_ch_cb->gpio_pin) : nrf_drv_gpiote_set_task_addr_get(p_ch_cb->gpio_pin)); + nrf_drv_ppi_channel_enable(p_cb->ppi_channel); + m_pwm_busy[p_instance->p_timer->instance_id] = channel; + m_pwm_target_value[p_instance->p_timer->instance_id] = ticks; + } + else + { + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + } + + nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false); + + nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[0]); + nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[1]); + } + p_ch_cb->pulsewidth = ticks; + return; +} +#endif //GPIOTE_SET_CLEAR_TASKS + +ret_code_t app_pwm_channel_duty_ticks_set(app_pwm_t const * const p_instance, + uint8_t channel, + uint16_t ticks) +{ + app_pwm_cb_t * p_cb = p_instance->p_cb; + app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; + + ASSERT(channel < APP_PWM_CHANNELS_PER_INSTANCE); + ASSERT(p_ch_cb->initialized == APP_PWM_CHANNEL_INITIALIZED); + + if (p_cb->state != NRF_DRV_STATE_POWERED_ON) + { + return NRF_ERROR_INVALID_STATE; + } + if (ticks == p_ch_cb->pulsewidth) + { + if (p_cb->p_ready_callback) + { + p_cb->p_ready_callback(p_instance->p_timer->instance_id); + } + return NRF_SUCCESS; // No action required. + } + if (app_pwm_busy_check(p_instance)) + { + return NRF_ERROR_BUSY; // PPI channels for synchronization are still in use. + } + + m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_CHANGING; + + // Set new value. + + pwm_transition(p_instance, channel, ticks); + if (p_instance->p_cb->p_ready_callback) { //PWM ready interrupt handler will be called after one full period. @@ -616,13 +725,25 @@ static ret_code_t app_pwm_channel_init(app_pwm_t const * const p_instance, uint8 nrf_drv_ppi_channel_disable(p_channel_cb->ppi_channels[0]); nrf_drv_ppi_channel_disable(p_channel_cb->ppi_channels[1]); + +#ifdef GPIOTE_SET_CLEAR_TASKS + uint32_t deactivate_task_addr = polarity ? nrf_drv_gpiote_clr_task_addr_get(p_channel_cb->gpio_pin) : nrf_drv_gpiote_set_task_addr_get(p_channel_cb->gpio_pin); + uint32_t activate_task_addr = polarity ? nrf_drv_gpiote_set_task_addr_get(p_channel_cb->gpio_pin) : nrf_drv_gpiote_clr_task_addr_get(p_channel_cb->gpio_pin); + + nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[0], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel), + deactivate_task_addr); + nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[1], + nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL), + activate_task_addr); +#else //GPIOTE_SET_CLEAR_TASKS nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[0], nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel), nrf_drv_gpiote_out_task_addr_get(p_channel_cb->gpio_pin)); nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[1], nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL), nrf_drv_gpiote_out_task_addr_get(p_channel_cb->gpio_pin)); - +#endif //GPIOTE_SET_CLEAR_TASKS p_channel_cb->initialized = APP_PWM_CHANNEL_INITIALIZED; m_pwm_ready_counter[p_instance->p_timer->instance_id][channel] = 0; @@ -637,17 +758,25 @@ static ret_code_t app_pwm_channel_init(app_pwm_t const * const p_instance, uint8 * * @retval Timer frequency. */ -inline nrf_timer_frequency_t pwm_calculate_timer_frequency(uint32_t period_us) +__STATIC_INLINE nrf_timer_frequency_t pwm_calculate_timer_frequency(uint32_t period_us) { - uint32_t f = (uint32_t)NRF_TIMER_FREQ_16MHz; - uint32_t min = (uint32_t)NRF_TIMER_FREQ_31250Hz; + uint32_t f = (uint32_t) NRF_TIMER_FREQ_16MHz; + uint32_t min = (uint32_t) NRF_TIMER_FREQ_31250Hz; while ((period_us > TIMER_MAX_PULSEWIDTH_US_ON_16M) && (f < min)) { period_us >>= 1; ++f; } - return (nrf_timer_frequency_t)f; + +#ifdef GPIOTE_SET_CLEAR_TASKS + if ((m_use_ppi_delay_workaround) && (f == (uint32_t) NRF_TIMER_FREQ_16MHz)) + { + f = (uint32_t) NRF_TIMER_FREQ_8MHz; + } +#endif // GPIOTE_SET_CLEAR_TASKS + + return (nrf_timer_frequency_t) f; } @@ -669,7 +798,7 @@ ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t con } uint32_t err_code = nrf_drv_ppi_init(); - if ((err_code != NRF_SUCCESS) && (err_code != MODULE_ALREADY_INITIALIZED)) + if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED)) { return NRF_ERROR_NO_MEM; } @@ -679,15 +808,30 @@ ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t con { err_code = nrf_drv_gpiote_init(); if (err_code != NRF_SUCCESS) - { - return NRF_ERROR_INTERNAL; - } + { + return NRF_ERROR_INTERNAL; + } + } + +#ifdef GPIOTE_SET_CLEAR_TASKS + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) + { + m_use_ppi_delay_workaround = false; + } + else + { + m_use_ppi_delay_workaround = true; } +#endif // Innitialize resource status: +#ifdef GPIOTE_SET_CLEAR_TASKS + p_cb->ppi_channel = (nrf_ppi_channel_t)UNALLOCATED; +#else p_cb->ppi_channels[0] = (nrf_ppi_channel_t)UNALLOCATED; p_cb->ppi_channels[1] = (nrf_ppi_channel_t)UNALLOCATED; p_cb->ppi_group = (nrf_ppi_channel_group_t)UNALLOCATED; +#endif //GPIOTE_SET_CLEAR_TASKS for (uint8_t i = 0; i < APP_PWM_CHANNELS_PER_INSTANCE; ++i) { @@ -698,20 +842,29 @@ ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t con } // Allocate PPI channels and groups: - for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++i) + +#ifdef GPIOTE_SET_CLEAR_TASKS + if (nrf_drv_ppi_channel_alloc(&p_cb->ppi_channel) != NRF_SUCCESS) { - if (nrf_drv_ppi_channel_alloc(&p_cb->ppi_channels[i]) != NRF_SUCCESS) - { - pwm_dealloc(p_instance); - return NRF_ERROR_NO_MEM; - } + pwm_dealloc(p_instance); + return NRF_ERROR_NO_MEM; } +#else //GPIOTE_SET_CLEAR_TASKS if (nrf_drv_ppi_group_alloc(&p_cb->ppi_group) != NRF_SUCCESS) { pwm_dealloc(p_instance); return NRF_ERROR_NO_MEM; } + for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++i) + { + if (nrf_drv_ppi_channel_alloc(&p_cb->ppi_channels[i]) != NRF_SUCCESS) + { + pwm_dealloc(p_instance); + return NRF_ERROR_NO_MEM; + } + } +#endif //GPIOTE_SET_CLEAR_TASKS // Initialize channels: for (uint8_t i = 0; i < APP_PWM_CHANNELS_PER_INSTANCE; ++i) { @@ -733,7 +886,7 @@ ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t con .frequency = timer_freq, .mode = NRF_TIMER_MODE_TIMER, .bit_width = NRF_TIMER_BIT_WIDTH_16, - .interrupt_priority = APP_IRQ_PRIORITY_LOW, + .interrupt_priority = APP_IRQ_PRIORITY_LOWEST, .p_context = (void *) (uint32_t) p_instance->p_timer->instance_id }; err_code = nrf_drv_timer_init(p_instance->p_timer, &timer_cfg, @@ -778,7 +931,9 @@ void app_pwm_enable(app_pwm_t const * const p_instance) } } m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE; + pan73_workaround(p_instance->p_timer->p_reg, true); + nrf_drv_timer_clear(p_instance->p_timer); nrf_drv_timer_enable(p_instance->p_timer); @@ -795,10 +950,16 @@ void app_pwm_disable(app_pwm_t const * const p_instance) nrf_drv_timer_disable(p_instance->p_timer); pwm_irq_disable(p_instance); + +#ifdef GPIOTE_SET_CLEAR_TASKS + nrf_drv_ppi_channel_disable(p_cb->ppi_channel); +#else for (uint8_t ppi_channel = 0; ppi_channel < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++ppi_channel) { nrf_drv_ppi_channel_disable(p_cb->ppi_channels[ppi_channel]); } +#endif //GPIOTE_SET_CLEAR_TASKS + for (uint8_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel) { app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel]; @@ -818,6 +979,7 @@ void app_pwm_disable(app_pwm_t const * const p_instance) nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[1]); } } + pan73_workaround(p_instance->p_timer->p_reg, false); p_cb->state = NRF_DRV_STATE_INITIALIZED; @@ -845,3 +1007,4 @@ ret_code_t app_pwm_uninit(app_pwm_t const * const p_instance) //lint -restore +#endif //NRF_MODULE_ENABLED(APP_PWM) diff --git a/components/libraries/pwm/app_pwm.h b/components/libraries/pwm/app_pwm.h index 7c619f1..e0bb50f 100644 --- a/components/libraries/pwm/app_pwm.h +++ b/components/libraries/pwm/app_pwm.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -25,7 +53,7 @@ * - 1 PPI group per instance. * - 1 GPIOTE channel per PWM channel. * - * For example, a PWM instance with two channels will consume 2+4 PPI channels, 1 PPI group, and 2 GPIOTE channels. + * For example, a PWM instance with two channels will consume 2 + 4 PPI channels, 1 PPI group, and 2 GPIOTE channels. * * The maximum number of PWM channels per instance is 2. */ @@ -38,7 +66,15 @@ #include "nrf_drv_timer.h" #include "nrf_drv_common.h" #include "nrf_drv_ppi.h" +#include "nrf_peripherals.h" +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(GPIOTE_FEATURE_SET_PRESENT) && defined(GPIOTE_FEATURE_CLR_PRESENT) +#define GPIOTE_SET_CLEAR_TASKS +#endif #define APP_PWM_NOPIN 0xFFFFFFFF @@ -110,9 +146,9 @@ typedef struct * * @brief Module for internal usage inside the library only * - * There are some definitions that must be included in the header file because + * There are some definitions that must be included in the header file because * of the way the library is set up. In this way, the are accessible to the user. - * However, any functions and variables defined here may change at any time + * However, any functions and variables defined here may change at any time * without a warning, so you should not access them directly. */ @@ -140,8 +176,12 @@ typedef struct app_pwm_channel_cb_t channels_cb[APP_PWM_CHANNELS_PER_INSTANCE]; //!< Channels data uint32_t period; //!< Selected period in ticks app_pwm_callback_t p_ready_callback; //!< Callback function called on PWM readiness +#ifdef GPIOTE_SET_CLEAR_TASKS + nrf_ppi_channel_t ppi_channel; //!< PPI channel used temporary while changing duty +#else nrf_ppi_channel_t ppi_channels[2]; //!< PPI channels used temporary while changing duty nrf_ppi_channel_group_t ppi_group; //!< PPI group used to synchronize changes on channels +#endif nrf_drv_state_t state; //!< Current driver status } app_pwm_cb_t; /** @} @@ -290,6 +330,11 @@ app_pwm_duty_t app_pwm_channel_duty_get(app_pwm_t const * const p_instance, uint /** @} */ + +#ifdef __cplusplus +} +#endif + #endif /** @} */ diff --git a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c b/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c new file mode 100644 index 0000000..a2fb4f2 --- /dev/null +++ b/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c @@ -0,0 +1,409 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_PWR_MGMT) + +#include "nrf_pwr_mgmt.h" +#include "nrf.h" +#include "app_error.h" +#include "nrf_assert.h" +#include "nrf_log_ctrl.h" +#include "app_util_platform.h" + +#define NRF_LOG_MODULE_NAME "NRF_PWR_MGMT" +#if NRF_PWR_MGMT_CONFIG_LOG_ENABLED + #define NRF_LOG_LEVEL NRF_PWR_MGMT_CONFIG_LOG_LEVEL + #define NRF_LOG_INFO_COLOR NRF_PWR_MGMT_CONFIG_INFO_COLOR + #define NRF_LOG_DEBUG_COLOR NRF_PWR_MGMT_CONFIG_DEBUG_COLOR +#else + #define NRF_LOG_LEVEL 0 +#endif // NRF_PWR_MGMT_CONFIG_LOG_ENABLED +#include "nrf_log.h" + +#ifdef SOFTDEVICE_PRESENT + #include "nrf_soc.h" +#endif // SOFTDEVICE_PRESENT + +#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER + #if (APP_SCHEDULER_ENABLED != 1) + #error "APP_SCHEDULER is required." + #endif + #include "app_scheduler.h" +#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER + +#if ((NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED == 1) \ + || (NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED == 1) \ + || (NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY == 1)) + #if (APP_TIMER_ENABLED != 1) + #error "APP_TIMER is required." + #endif + #include "app_timer.h" + #define APP_TIMER_REQUIRED 1 +#else + #define APP_TIMER_REQUIRED 0 +#endif + +#if (!defined(__FPU_PRESENT) || (__FPU_PRESENT != 1)) \ + && (NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED == 1) + #error "FPU is required by NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED" +#endif + +#if NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED + #include "nrf_gpio.h" + #define DEBUG_PIN_CONFIG() nrf_gpio_cfg_output(NRF_PWR_MGMT_SLEEP_DEBUG_PIN) + #define DEBUG_PIN_CLEAR() nrf_gpio_pin_clear(NRF_PWR_MGMT_SLEEP_DEBUG_PIN) + #define DEBUG_PIN_SET() nrf_gpio_pin_set(NRF_PWR_MGMT_SLEEP_DEBUG_PIN) + #define DEBUG_PINS_INIT() \ + do { \ + DEBUG_PIN_CLEAR(); \ + DEBUG_PIN_CONFIG(); \ + } while(0) +#else + #define DEBUG_PIN_CLEAR() + #define DEBUG_PIN_SET() + #define DEBUG_PINS_INIT() +#endif + +#if (NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED == 1) \ + || (NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED == 1) + +__STATIC_INLINE void nrf_pwr_mgmt_sleep_init(void) +{ +#ifdef SOFTDEVICE_PRESENT + ASSERT(current_int_priority_get() <= APP_IRQ_PRIORITY_LOW); +#endif + SCB->SCR |= SCB_SCR_SEVONPEND_Msk; +} + + #define SLEEP_INIT() nrf_pwr_mgmt_sleep_init() + #define SLEEP_LOCK() CRITICAL_REGION_ENTER() + #define SLEEP_RELEASE() CRITICAL_REGION_EXIT() +#else + #define SLEEP_INIT() + #define SLEEP_LOCK() + #define SLEEP_RELEASE() +#endif + +// Create section "pwr_mgmt_data". +//lint -esym(526, pwr_mgmt_dataBase) -esym(526, pwr_mgmt_dataLimit) +NRF_SECTION_VARS_CREATE_SECTION(pwr_mgmt_data, nrf_pwr_mgmt_shutdown_handler_t); + +// Helper macros for section variables. +#define PWR_MGMT_SECTION_VARS_GET(i) NRF_SECTION_VARS_GET((i), \ + nrf_pwr_mgmt_shutdown_handler_t, \ + pwr_mgmt_data) +#define PWR_MGMT_SECTION_VARS_COUNT NRF_SECTION_VARS_COUNT(nrf_pwr_mgmt_shutdown_handler_t, \ + pwr_mgmt_data) + +#if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + static uint8_t m_max_cpu_usage; /**< Maximum observed CPU usage (0 - 100%). */ + static uint32_t m_ticks_sleeping; /**< Number of ticks spent in sleep mode (__WFE()). */ + static uint32_t m_ticks_last; /**< Number of ticks from the last CPU usage computation. */ +#endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + + +#if NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED + static uint16_t m_standby_counter; /**< Number of seconds from the last activity + (@ref pwr_mgmt_feed). */ +#endif // NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED + +static nrf_pwr_mgmt_evt_t m_pwr_mgmt_evt; /**< Event type which will be passed to the shutdown + handlers.*/ +static bool m_sysoff_guard; /**< True if application started the shutdown + preparation. */ +static uint8_t m_next_handler; /**< Index of the next executed handler. */ + +#if APP_TIMER_REQUIRED + APP_TIMER_DEF(m_pwr_mgmt_timer); /**< Timer used by this module. */ +#endif // APP_TIMER_REQUIRED + +#if APP_TIMER_REQUIRED +/**@brief Handle events from m_pwr_mgmt_timer. + */ +static void nrf_pwr_mgmt_timeout_handler(void * p_context) +{ +#if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + uint32_t delta; + uint32_t ticks; + uint8_t cpu_usage; + + ticks = app_timer_cnt_get(); + UNUSED_VARIABLE(app_timer_cnt_diff_compute(ticks, m_ticks_last, &delta)); + cpu_usage = 100 * (delta - m_ticks_sleeping) / delta; + + NRF_LOG_DEBUG("CPU Usage: %d%%\r\n", cpu_usage); + if (m_max_cpu_usage < cpu_usage) + { + m_max_cpu_usage = cpu_usage; + } + + m_ticks_last = ticks; + m_ticks_sleeping = 0; +#endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + +#if NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY + if (m_sysoff_guard) + { + // Try to continue the shutdown procedure. + nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_CONTINUE); + return; + } +#endif // NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY + +#if NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED + if (m_standby_counter < NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S) + { + m_standby_counter++; + } + else + { + nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF); + } +#endif // NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED +} +#endif // APP_TIMER_REQUIRED + + +ret_code_t nrf_pwr_mgmt_init(uint32_t ticks_per_1s) +{ + NRF_LOG_INFO("Init\r\n"); + DEBUG_PINS_INIT(); + SLEEP_INIT(); + +#if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + m_max_cpu_usage = 0; + m_ticks_sleeping = 0; + m_ticks_last = 0; +#endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + +#if NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED + m_standby_counter = 0; +#endif // NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED + m_sysoff_guard = false; + m_next_handler = 0; + +#if APP_TIMER_REQUIRED + ret_code_t ret_code = app_timer_create(&m_pwr_mgmt_timer, + APP_TIMER_MODE_REPEATED, + nrf_pwr_mgmt_timeout_handler); + VERIFY_SUCCESS(ret_code); + + return app_timer_start(m_pwr_mgmt_timer, ticks_per_1s, NULL); +#else + return NRF_SUCCESS; +#endif // APP_TIMER_REQUIRED +} + + +void nrf_pwr_mgmt_run(void) +{ +#if NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED + /* + * Clear FPU exceptions. + * Without this step, the FPU interrupt is marked as pending, + * preventing system from sleeping. + */ + uint32_t fpscr = __get_FPSCR(); + __set_FPSCR(fpscr & ~0x9Fu); + __DMB(); + NVIC_ClearPendingIRQ(FPU_IRQn); + + // Assert if a critical FPU exception is signaled. + ASSERT((fpscr & 0x03) == 0); +#endif // NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED + + SLEEP_LOCK(); + +#if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + uint32_t sleep_start; + uint32_t sleep_end; + uint32_t sleep_duration; + + sleep_start = app_timer_cnt_get(); +#endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + + DEBUG_PIN_SET(); + + // Wait for an event. +#ifdef SOFTDEVICE_PRESENT + ret_code_t ret_code = sd_app_evt_wait(); + if (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED) + { + __WFE(); + __SEV(); + __WFE(); + } + else + { + APP_ERROR_CHECK(ret_code); + } +#else + __WFE(); + __SEV(); + __WFE(); +#endif // SOFTDEVICE_PRESENT + + DEBUG_PIN_CLEAR(); + +#if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + sleep_end = app_timer_cnt_get(); + UNUSED_VARIABLE(app_timer_cnt_diff_compute(sleep_end, + sleep_start, + &sleep_duration)); + m_ticks_sleeping += sleep_duration; +#endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + + SLEEP_RELEASE(); +} + + +#if NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED +void nrf_pwr_mgmt_feed(void) +{ + NRF_LOG_DEBUG("Feed\r\n"); + // Once triggered, shutdown is inevitable. + m_standby_counter = 0; +} +#endif // NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED + + +/**@brief Function runs the shutdown procedure. + */ +static void shutdown_process(void) +{ + NRF_LOG_INFO("Shutdown started. Type %d\r\n", m_pwr_mgmt_evt); + // Executing all callbacks. + while (m_next_handler < PWR_MGMT_SECTION_VARS_COUNT) + { + if ((*PWR_MGMT_SECTION_VARS_GET(m_next_handler))(m_pwr_mgmt_evt)) + { + NRF_LOG_INFO("SysOff handler 0x%08X => ready\r\n", + (unsigned int)*PWR_MGMT_SECTION_VARS_GET(m_next_handler)); + } + else + { + // One of the modules is not ready. + NRF_LOG_INFO("SysOff handler 0x%08X => blocking\r\n", + (unsigned int)*PWR_MGMT_SECTION_VARS_GET(m_next_handler)); + return; + } + + // Mark handler as executed. + m_next_handler++; + } + +#if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + NRF_LOG_INFO("Maximum CPU usage: %u%%\r\n", m_max_cpu_usage); +#endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED + NRF_LOG_WARNING("Shutdown\r\n"); + NRF_LOG_FINAL_FLUSH(); + + // Enter System OFF. +#ifdef SOFTDEVICE_PRESENT + ret_code_t ret_code = sd_power_system_off(); + if (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED) + { + NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter; + } + else + { + APP_ERROR_CHECK(ret_code); + } +#else + NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter; +#endif // SOFTDEVICE_PRESENT +} + + +#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER +/**@brief Handle events from app_scheduler. + */ +static void scheduler_shutdown_handler(void * p_event_data, uint16_t event_size) +{ + UNUSED_PARAMETER(p_event_data); + UNUSED_PARAMETER(event_size); + shutdown_process(); +} +#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER + + +/**@brief Function for locking shutdown guard. It prevents a multiple call of @ref pwr_mgmt_shutdown + * and overwriting the shutdown type. + */ +static bool nrf_pwr_mgmt_guard_lock(void) +{ + bool success = false; + + CRITICAL_REGION_ENTER(); + if (m_sysoff_guard == false) + { + m_sysoff_guard = true; + success = true; + } + CRITICAL_REGION_EXIT(); + + return success; +} + + +void nrf_pwr_mgmt_shutdown(nrf_pwr_mgmt_shutdown_t shutdown_type) +{ + if (shutdown_type != NRF_PWR_MGMT_SHUTDOWN_CONTINUE) + { + // Check if shutdown procedure is not started. + if (!nrf_pwr_mgmt_guard_lock()) + { + return; + } + m_pwr_mgmt_evt = (nrf_pwr_mgmt_evt_t)shutdown_type; + } + ASSERT(m_sysoff_guard); + NRF_LOG_INFO("Shutdown request %d\r\n", shutdown_type); + +#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER + ret_code_t ret_code = app_sched_event_put(NULL, 0, scheduler_shutdown_handler); + APP_ERROR_CHECK(ret_code); +#else + shutdown_process(); +#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER +} + +#endif // NRF_MODULE_ENABLED(NRF_PWR_MGMT) diff --git a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h b/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h new file mode 100644 index 0000000..c294f07 --- /dev/null +++ b/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h @@ -0,0 +1,146 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @defgroup nrf_pwr_mgmt Power management + * @ingroup app_common + * @{ + * @brief This module handles power management features. + * + */ +#ifndef NRF_PWR_MGMT_H__ +#define NRF_PWR_MGMT_H__ + +#include +#include +#include +#include "section_vars.h" + +/**@brief Power management shutdown types. */ +typedef enum +{ + NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF, + //!< Go to System OFF. + + NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF, + //!< Go to System OFF and stay there. + /**< + * Useful when battery level is dangerously low, for example. + */ + + NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU, + //!< Go to DFU mode. + + NRF_PWR_MGMT_SHUTDOWN_CONTINUE + //!< Continue shutdown. + /**< + * This should be used by modules that block the shutdown process, when they become ready for + * shutdown. + */ +} nrf_pwr_mgmt_shutdown_t; + +/**@brief Shutdown event types. */ +typedef enum +{ + NRF_PWR_MGMT_EVT_PREPARE_WAKEUP, + //!< Application will prepare the wakeup mechanism. + + NRF_PWR_MGMT_EVT_PREPARE_SYSOFF, + //!< Application will prepare to stay in System OFF state. + + NRF_PWR_MGMT_EVT_PREPARE_DFU + //!< Application will prepare to enter DFU mode. +} nrf_pwr_mgmt_evt_t; + + +/**@brief Shutdown callback. + * @param[in] event Type of shutdown process. + * + * @retval true System OFF / Enter DFU preparation successful. Process will be continued. + * @retval false System OFF / Enter DFU preparation failed. @ref NRF_PWR_MGMT_SHUTDOWN_CONTINUE + * should be used to continue the shutdown process. + */ +typedef bool (*nrf_pwr_mgmt_shutdown_handler_t)(nrf_pwr_mgmt_evt_t event); + + +/**@brief Macro for registering a shutdown handler. Modules that want to get events + * from this module must register the handler using this macro. + * + * @details This macro places the handler in a section named "pwr_mgmt_data". + * + * @param[in] handler Event handler (@ref nrf_pwr_mgmt_shutdown_handler_t). + */ +#define NRF_PWR_MGMT_REGISTER_HANDLER(handler) \ + NRF_SECTION_VARS_REGISTER_VAR(pwr_mgmt_data, \ + nrf_pwr_mgmt_shutdown_handler_t const handler) + +/**@brief Function for initializing power management. + * + * @warning Depending on configuration, this function sets SEVONPEND in System Control Block (SCB). + * This operation is unsafe with the SoftDevice from interrupt priority higher than SVC. + * + * @param[in] ticks_per_1s Number of RTC ticks for 1 s. + * + * @retval NRF_SUCCESS + */ +ret_code_t nrf_pwr_mgmt_init(uint32_t ticks_per_1s); + +/**@brief Function for running power management. Should run in the main loop. + */ +void nrf_pwr_mgmt_run(void); + +/**@brief Function for indicating activity. + * + * @details Call this function whenever doing something that constitutes "activity". + * For example, whenever sending data, call this function to indicate that the application + * is active and should not disconnect any ongoing communication links. + */ +void nrf_pwr_mgmt_feed(void); + +/**@brief Function for shutting down the system. + * + * @param[in] shutdown_type Type of operation. + * + * @details All callbacks will be executed prior to shutdown. + */ +void nrf_pwr_mgmt_shutdown(nrf_pwr_mgmt_shutdown_t shutdown_type); + +#endif // NRF_PWR_MGMT_H__ +/** @} */ diff --git a/components/libraries/queue/nrf_queue.c b/components/libraries/queue/nrf_queue.c new file mode 100644 index 0000000..dd4020b --- /dev/null +++ b/components/libraries/queue/nrf_queue.c @@ -0,0 +1,435 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NRF_QUEUE) +#include "nrf_queue.h" +#include "app_util_platform.h" + +/**@brief Get next element index. + * + * @param[in] p_queue Pointer to the queue instance. + * @param[in] idx Current index. + * + * @return Next element index. + */ +__STATIC_INLINE size_t nrf_queue_next_idx(nrf_queue_t const * p_queue, size_t idx) +{ + ASSERT(p_queue != NULL); + return (idx < p_queue->size) ? (idx + 1) : 0; +} + +/**@brief Get current queue utilization. This function assumes that this process will not be interrupted. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return Current queue utilization. + */ +__STATIC_INLINE size_t queue_utilization_get(nrf_queue_t const * p_queue) +{ + return (p_queue->p_cb->back >= p_queue->p_cb->front) ? + (p_queue->p_cb->back - p_queue->p_cb->front) : + (p_queue->size + 1 - p_queue->p_cb->front + p_queue->p_cb->back); +} + +bool nrf_queue_is_full(nrf_queue_t const * p_queue) +{ + ASSERT(p_queue != NULL); + return (nrf_queue_next_idx(p_queue, p_queue->p_cb->back) == p_queue->p_cb->front); +} + +ret_code_t nrf_queue_push(nrf_queue_t const * p_queue, void const * p_element) +{ + ret_code_t status = NRF_SUCCESS; + + ASSERT(p_queue != NULL); + ASSERT(p_element != NULL); + + CRITICAL_REGION_ENTER(); + bool is_full = nrf_queue_is_full(p_queue); + + if (!is_full || (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW)) + { + // Get write position. + size_t write_pos = p_queue->p_cb->back; + p_queue->p_cb->back = nrf_queue_next_idx(p_queue, p_queue->p_cb->back); + if (is_full) + { + // Overwrite the oldest element. + p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front); + } + + // Write a new element. + switch (p_queue->element_size) + { + case sizeof(uint8_t): + ((uint8_t *)p_queue->p_buffer)[write_pos] = *((uint8_t *)p_element); + break; + + case sizeof(uint16_t): + ((uint16_t *)p_queue->p_buffer)[write_pos] = *((uint16_t *)p_element); + break; + + case sizeof(uint32_t): + ((uint32_t *)p_queue->p_buffer)[write_pos] = *((uint32_t *)p_element); + break; + + case sizeof(uint64_t): + ((uint64_t *)p_queue->p_buffer)[write_pos] = *((uint64_t *)p_element); + break; + + default: + memcpy((void *)((size_t)p_queue->p_buffer + write_pos * p_queue->element_size), + p_element, + p_queue->element_size); + break; + } + + // Update utilization. + size_t utilization = queue_utilization_get(p_queue); + if (p_queue->p_cb->max_utilization < utilization) + { + p_queue->p_cb->max_utilization = utilization; + } + } + else + { + status = NRF_ERROR_NO_MEM; + } + + CRITICAL_REGION_EXIT(); + + return status; +} + +ret_code_t nrf_queue_generic_pop(nrf_queue_t const * p_queue, + void * p_element, + bool just_peek) +{ + ret_code_t status = NRF_SUCCESS; + + ASSERT(p_queue != NULL); + ASSERT(p_element != NULL); + + CRITICAL_REGION_ENTER(); + + if (!nrf_queue_is_empty(p_queue)) + { + // Get read position. + size_t read_pos = p_queue->p_cb->front; + + // Update next read position. + if (!just_peek) + { + p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front); + } + + // Read element. + switch (p_queue->element_size) + { + case sizeof(uint8_t): + *((uint8_t *)p_element) = ((uint8_t *)p_queue->p_buffer)[read_pos]; + break; + + case sizeof(uint16_t): + *((uint16_t *)p_element) = ((uint16_t *)p_queue->p_buffer)[read_pos]; + break; + + case sizeof(uint32_t): + *((uint32_t *)p_element) = ((uint32_t *)p_queue->p_buffer)[read_pos]; + break; + + case sizeof(uint64_t): + *((uint64_t *)p_element) = ((uint64_t *)p_queue->p_buffer)[read_pos]; + break; + + default: + memcpy(p_element, + (void const *)((size_t)p_queue->p_buffer + read_pos * p_queue->element_size), + p_queue->element_size); + break; + } + } + else + { + status = NRF_ERROR_NOT_FOUND; + } + + CRITICAL_REGION_EXIT(); + + return status; +} + +/**@brief Write elements to the queue. This function assumes that there is enough room in the queue + * to write the requested number of elements and that this process will not be interrupted. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[in] p_data Pointer to the buffer with elements to write. + * @param[in] element_count Number of elements to write. + */ +static void queue_write(nrf_queue_t const * p_queue, void const * p_data, uint32_t element_count) +{ + size_t prev_available = nrf_queue_available_get(p_queue); + size_t continuous = p_queue->size + 1 - p_queue->p_cb->back; + void * p_write_ptr = (void *)((size_t)p_queue->p_buffer + + p_queue->p_cb->back * p_queue->element_size); + if (element_count <= continuous) + { + memcpy(p_write_ptr, + p_data, + element_count * p_queue->element_size); + + p_queue->p_cb->back = ((p_queue->p_cb->back + element_count) <= p_queue->size) + ? (p_queue->p_cb->back + element_count) + : 0; + } + else + { + size_t first_write_length = continuous * p_queue->element_size; + memcpy(p_write_ptr, + p_data, + first_write_length); + + size_t elements_left = element_count - continuous; + memcpy(p_queue->p_buffer, + (void const *)((size_t)p_data + first_write_length), + elements_left * p_queue->element_size); + + p_queue->p_cb->back = elements_left; + if (prev_available < element_count) + { + // Overwrite the oldest elements. + p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->back); + } + } + + // Update utilization. + size_t utilization = queue_utilization_get(p_queue); + if (p_queue->p_cb->max_utilization < utilization) + { + p_queue->p_cb->max_utilization = utilization; + } +} + +ret_code_t nrf_queue_write(nrf_queue_t const * p_queue, + void const * p_data, + size_t element_count) +{ + ret_code_t status = NRF_SUCCESS; + + ASSERT(p_queue != NULL); + ASSERT(p_data != NULL); + ASSERT(element_count <= p_queue->size); + + if (element_count == 0) + { + return NRF_SUCCESS; + } + + CRITICAL_REGION_ENTER(); + + if ((nrf_queue_available_get(p_queue) >= element_count) + || (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW)) + { + queue_write(p_queue, p_data, element_count); + } + else + { + status = NRF_ERROR_NO_MEM; + } + + CRITICAL_REGION_EXIT(); + + return status; +} + + +size_t nrf_queue_in(nrf_queue_t const * p_queue, + void * p_data, + size_t element_count) +{ + ASSERT(p_queue != NULL); + ASSERT(p_data != NULL); + + if (element_count == 0) + { + return 0; + } + + CRITICAL_REGION_ENTER(); + + if (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW) + { + element_count = MIN(element_count, p_queue->size); + } + else + { + size_t available = nrf_queue_available_get(p_queue); + element_count = MIN(element_count, available); + } + + queue_write(p_queue, p_data, element_count); + + CRITICAL_REGION_EXIT(); + + return element_count; +} + +/**@brief Read elements from the queue. This function assumes that there are enough elements + * in the queue to read and that this process will not be interrupted. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[out] p_data Pointer to the buffer where elements will be copied. + * @param[in] element_count Number of elements to read. + */ +static void queue_read(nrf_queue_t const * p_queue, void * p_data, uint32_t element_count) +{ + size_t continuous = (p_queue->p_cb->front <= p_queue->p_cb->back) + ? p_queue->p_cb->back - p_queue->p_cb->front + : p_queue->size + 1 - p_queue->p_cb->front; + void const * p_read_ptr = (void const *)((size_t)p_queue->p_buffer + + p_queue->p_cb->front * p_queue->element_size); + + if (element_count <= continuous) + { + memcpy(p_data, + p_read_ptr, + element_count * p_queue->element_size); + + p_queue->p_cb->front = ((p_queue->p_cb->front + element_count) <= p_queue->size) + ? (p_queue->p_cb->front + element_count) + : 0; + } + else + { + size_t first_read_length = continuous * p_queue->element_size; + memcpy(p_data, + p_read_ptr, + first_read_length); + + size_t elements_left = element_count - continuous; + memcpy((void *)((size_t)p_data + first_read_length), + p_queue->p_buffer, + elements_left * p_queue->element_size); + + p_queue->p_cb->front = elements_left; + } +} + +ret_code_t nrf_queue_read(nrf_queue_t const * p_queue, + void * p_data, + size_t element_count) +{ + ret_code_t status = NRF_SUCCESS; + + ASSERT(p_queue != NULL); + ASSERT(p_data != NULL); + + if (element_count == 0) + { + return NRF_SUCCESS; + } + + CRITICAL_REGION_ENTER(); + + if (element_count <= queue_utilization_get(p_queue)) + { + queue_read(p_queue, p_data, element_count); + } + else + { + status = NRF_ERROR_NOT_FOUND; + } + + CRITICAL_REGION_EXIT(); + + return status; +} + +size_t nrf_queue_out(nrf_queue_t const * p_queue, + void * p_data, + size_t element_count) +{ + ASSERT(p_queue != NULL); + ASSERT(p_data != NULL); + + if (element_count == 0) + { + return 0; + } + + CRITICAL_REGION_ENTER(); + + size_t utilization = queue_utilization_get(p_queue); + element_count = MIN(element_count, utilization); + + queue_read(p_queue, p_data, element_count); + + CRITICAL_REGION_EXIT(); + + return element_count; +} + +void nrf_queue_reset(nrf_queue_t const * p_queue) +{ + ASSERT(p_queue != NULL); + + CRITICAL_REGION_ENTER(); + + memset(p_queue->p_cb, 0, sizeof(nrf_queue_cb_t)); + + CRITICAL_REGION_EXIT(); +} + +size_t nrf_queue_utilization_get(nrf_queue_t const * p_queue) +{ + size_t utilization; + ASSERT(p_queue != NULL); + + CRITICAL_REGION_ENTER(); + + utilization = queue_utilization_get(p_queue); + + CRITICAL_REGION_EXIT(); + + return utilization; +} + +#endif // NRF_MODULE_ENABLED(NRF_QUEUE) diff --git a/components/libraries/queue/nrf_queue.h b/components/libraries/queue/nrf_queue.h new file mode 100644 index 0000000..7ff1b35 --- /dev/null +++ b/components/libraries/queue/nrf_queue.h @@ -0,0 +1,402 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + + +/** +* @defgroup nrf_queue Queue module +* @{ +* @ingroup app_common +* @brief Functions that handle the queue instances. +*/ + +#ifndef NRF_QUEUE_H__ +#define NRF_QUEUE_H__ + +#include +#include +#include +#include "nrf_assert.h" +#include "sdk_errors.h" +#include "app_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Queue control block. */ +typedef struct +{ + size_t front; //!< Queue front index. + size_t back; //!< Queue back index. + size_t max_utilization; //!< Maximum utilization of the queue. +} nrf_queue_cb_t; + +/**@brief Supported queue modes. */ +typedef enum +{ + NRF_QUEUE_MODE_OVERFLOW, //!< If the queue is full, new element will not be accepted. + NRF_QUEUE_MODE_NO_OVERFLOW, //!< If the queue is full, new element will overwrite the oldest. +} nrf_queue_mode_t; + +/**@brief Instance of the queue. */ +typedef struct +{ + nrf_queue_cb_t * p_cb; //!< Pointer to the instance control block. + void * p_buffer; //!< Pointer to the memory that is used as storage. + size_t size; //!< Size of the queue. + size_t element_size; //!< Size of one element. + nrf_queue_mode_t mode; //!< Mode of the queue. +} nrf_queue_t; + +/**@brief Create a queue instance. + * + * @note This macro reserves memory for the given queue instance. + * + * @param[in] _type Type which is stored. + * @param[in] _name Name of the queue. + * @param[in] _size Size of the queue. + * @param[in] _mode Mode of the queue. + */ +#define NRF_QUEUE_DEF(_type, _name, _size, _mode) \ + static _type _name##_nrf_queue_buffer[(_size) + 1]; \ + static nrf_queue_cb_t _name##_nrf_queue_cb; \ + static const nrf_queue_t _name = \ + { \ + .p_cb = &_name##_nrf_queue_cb, \ + .p_buffer = _name##_nrf_queue_buffer, \ + .size = (_size), \ + .element_size = sizeof(_type), \ + .mode = _mode, \ + } + +/**@brief Declare a queue interface. + * + * @param[in] _type Type which is stored. + * @param[in] _name Name of the queue. + */ +#define NRF_QUEUE_INTERFACE_DEC(_type, _name) \ + ret_code_t _name##_push(_type const * p_element); \ + ret_code_t _name##_pop(_type * p_element); \ + ret_code_t _name##_peek(_type * p_element); \ + ret_code_t _name##_write(_type const * p_data, \ + size_t element_count); \ + ret_code_t _name##_read(_type * p_data, \ + size_t element_count); \ + size_t _name##_out(_type * p_data, \ + size_t element_count); \ + size_t _name##_in(_type * p_data, \ + size_t element_count); \ + bool _name##_is_full(void); \ + bool _name##_is_empty(void); \ + size_t _name##_utilization_get(void); \ + size_t _name##_available_get(void); \ + size_t _name##_max_utilization_get(void); \ + void _name##_reset(void) + +/**@brief Define a custom queue interface. + * + * @param[in] _attr Function attribute that will be added to the queue function definition. + * @param[in] _type Type which is stored. + * @param[in] _name Name of the queue. + * @param[in] _p_queue Queue instance. + */ +#define NRF_QUEUE_INTERFACE_CUSTOM_DEF(_attr, _type, _name, _p_queue) \ + _attr ret_code_t _name##_push(_type const * p_element) \ + { \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + return nrf_queue_push((_p_queue), p_element); \ + } \ + _attr ret_code_t _name##_pop(_type * p_element) \ + { \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + return nrf_queue_pop((_p_queue), p_element); \ + } \ + _attr ret_code_t _name##_peek(_type * p_element) \ + { \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + return nrf_queue_peek((_p_queue), p_element); \ + } \ + ret_code_t _name##_write(_type const * p_data, \ + size_t element_count) \ + { \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + return nrf_queue_write((_p_queue), p_data, element_count); \ + } \ + ret_code_t _name##_read(_type * p_data, \ + size_t element_count) \ + { \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + return nrf_queue_read((_p_queue), p_data, element_count); \ + } \ + size_t _name##_in(_type * p_data, \ + size_t element_count) \ + { \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + return nrf_queue_in((_p_queue), p_data, element_count); \ + } \ + size_t _name##_out(_type * p_data, \ + size_t element_count) \ + { \ + ASSERT((_p_queue) != NULL); \ + ASSERT((_p_queue)->element_size == sizeof(_type)); \ + return nrf_queue_out((_p_queue), p_data, element_count); \ + } \ + bool _name##_is_full(void) \ + { \ + ASSERT((_p_queue) != NULL); \ + return nrf_queue_is_full(_p_queue); \ + } \ + bool _name##_is_empty(void) \ + { \ + ASSERT((_p_queue) != NULL); \ + return nrf_queue_is_empty(_p_queue); \ + } \ + size_t _name##_utilization_get(void) \ + { \ + ASSERT((_p_queue) != NULL); \ + return nrf_queue_utilization_get(_p_queue); \ + } \ + size_t _name##_available_get(void) \ + { \ + ASSERT((_p_queue) != NULL); \ + return nrf_queue_available_get(_p_queue); \ + } \ + size_t _name##_max_utilization_get(void) \ + { \ + ASSERT((_p_queue) != NULL); \ + return nrf_queue_max_utilization_get(_p_queue); \ + } \ + void _name##_reset(void) \ + { \ + ASSERT((_p_queue) != NULL); \ + nrf_queue_reset(_p_queue); \ + } + +/**@brief Define a queue interface. + * + * @param[in] _type Type which is stored. + * @param[in] _name Name of the queue. + * @param[in] _p_queue Queue instance. + */ +#define NRF_QUEUE_INTERFACE_DEF(_type, _name, _p_queue) \ + NRF_QUEUE_INTERFACE_CUSTOM_DEF(/* empty */, _type, _name, _p_queue) + +/**@brief Define a local queue interface. + * + * @param[in] _type Type which is stored. + * @param[in] _name Name of the queue. + * @param[in] _p_queue Queue instance. + */ +#define NRF_QUEUE_INTERFACE_LOCAL_DEF(_type, _name, _p_queue) \ + NRF_QUEUE_INTERFACE_CUSTOM_DEF(static, _type, _name, _p_queue) + +/**@brief Function for pushing an element to the end of queue. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[in] p_element Pointer to the element that will be stored in the queue. + * + * @return NRF_SUCCESS If an element has been successfully added. + * @return NRF_ERROR_NO_MEM If the queue is full (only in @ref NRF_QUEUE_MODE_NO_OVERFLOW). + */ +ret_code_t nrf_queue_push(nrf_queue_t const * p_queue, void const * p_element); + +/**@brief Generic pop implementation. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[out] p_element Pointer where the element will be copied. + * @param[out] just_peek If true, the returned element will not be removed from queue. + * + * @return NRF_SUCCESS If an element was returned. + * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue. + */ +ret_code_t nrf_queue_generic_pop(nrf_queue_t const * p_queue, + void * p_element, + bool just_peek); + +/**@brief Pop element from the front of the queue. + * + * @param[in] _p_queue Pointer to the nrf_queue_t instance. + * @param[out] _p_element Pointer where the element will be copied. + * + * @return NRF_SUCCESS If an element was returned. + * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue. + */ +#define nrf_queue_pop(_p_queue, _p_element) nrf_queue_generic_pop((_p_queue), (_p_element), false) + +/**@brief Peek element from the front of the queue. + * + * @param[in] _p_queue Pointer to the nrf_queue_t instance. + * @param[out] _p_element Pointer where the element will be copied. + * + * @return NRF_SUCCESS If an element was returned. + * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue. + */ +#define nrf_queue_peek(_p_queue, _p_element) nrf_queue_generic_pop((_p_queue), (_p_element), true) + +/**@brief Function for writing elements to the queue. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[in] p_data Pointer to the buffer with elements to write. + * @param[in] element_count Number of elements to write. + * + * @return NRF_SUCCESS If an element was written. + * @return NRF_ERROR_NO_MEM There is not enough space in the queue. No element was written. + */ +ret_code_t nrf_queue_write(nrf_queue_t const * p_queue, + void const * p_data, + size_t element_count); + +/**@brief Function for writing a portion of elements to the queue. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[in] p_data Pointer to the buffer with elements to write. + * @param[in] element_count Number of elements to write. + * + * @return The number of added elements. + */ +size_t nrf_queue_in(nrf_queue_t const * p_queue, + void * p_data, + size_t element_count); + +/**@brief Function for reading elements from the queue. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[out] p_data Pointer to the buffer where elements will be copied. + * @param[in] element_count Number of elements to read. + * + * @return NRF_SUCCESS If an element was returned. + * @return NRF_ERROR_NOT_FOUND There is not enough elements in the queue. + */ +ret_code_t nrf_queue_read(nrf_queue_t const * p_queue, + void * p_data, + size_t element_count); + +/**@brief Function for reading a portion of elements from the queue. + * + * @param[in] p_queue Pointer to the nrf_queue_t instance. + * @param[out] p_data Pointer to the buffer where elements will be copied. + * @param[in] element_count Number of elements to read. + * + * @return The number of read elements. + */ +size_t nrf_queue_out(nrf_queue_t const * p_queue, + void * p_data, + size_t element_count); + +/**@brief Function for checking if the queue is full. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return True if the queue is full. + */ +bool nrf_queue_is_full(nrf_queue_t const * p_queue); + +/**@brief Function for checking if the queue is empty. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return True if the queue is empty. + */ +__STATIC_INLINE bool nrf_queue_is_empty(nrf_queue_t const * p_queue); + +/**@brief Function for getting the current queue utilization. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return Current queue utilization. + */ +size_t nrf_queue_utilization_get(nrf_queue_t const * p_queue); + +/**@brief Function for getting the size of available space. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return Size of available space. + */ +__STATIC_INLINE size_t nrf_queue_available_get(nrf_queue_t const * p_queue); + +/**@brief Function for getting the maximal queue utilization. + * + * @param[in] p_queue Pointer to the queue instance. + * + * @return Maximal queue utilization. + */ +__STATIC_INLINE size_t nrf_queue_max_utilization_get(nrf_queue_t const * p_queue); + +/**@brief Function for resetting the queue state. + * + * @param[in] p_queue Pointer to the queue instance. + */ +void nrf_queue_reset(nrf_queue_t const * p_queue); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE bool nrf_queue_is_empty(nrf_queue_t const * p_queue) +{ + ASSERT(p_queue != NULL); + return (p_queue->p_cb->front == p_queue->p_cb->back); +} + +__STATIC_INLINE size_t nrf_queue_available_get(nrf_queue_t const * p_queue) +{ + ASSERT(p_queue != NULL); + return p_queue->size - nrf_queue_utilization_get(p_queue); +} + +__STATIC_INLINE size_t nrf_queue_max_utilization_get(nrf_queue_t const * p_queue) +{ + ASSERT(p_queue != NULL); + return p_queue->p_cb->max_utilization; +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +#ifdef __cplusplus +} +#endif + +#endif // NRF_QUEUE_H__ +/** @} */ diff --git a/components/libraries/scheduler/app_scheduler.c b/components/libraries/scheduler/app_scheduler.c index c170a4d..249818f 100644 --- a/components/libraries/scheduler/app_scheduler.c +++ b/components/libraries/scheduler/app_scheduler.c @@ -1,22 +1,50 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_SCHEDULER) #include "app_scheduler.h" #include #include #include #include "nrf_soc.h" #include "nrf_assert.h" -#include "app_util.h" #include "app_util_platform.h" /**@brief Structure for holding a scheduled event header. */ @@ -35,6 +63,15 @@ static volatile uint8_t m_queue_end_index; /**< Index of queue entry at the static uint16_t m_queue_event_size; /**< Maximum event size in queue. */ static uint16_t m_queue_size; /**< Number of queue entries. */ +#if APP_SCHEDULER_WITH_PROFILER +static uint16_t m_max_queue_utilization; /**< Maximum observed queue utilization. */ +#endif + +#if APP_SCHEDULER_WITH_PAUSE +static uint32_t m_scheduler_paused_counter = 0; /**< Counter storing the difference between pausing + and resuming the scheduler. */ +#endif + /**@brief Function for incrementing a queue index, and handle wrap-around. * * @param[in] index Old index. @@ -85,10 +122,45 @@ uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event m_queue_event_size = event_size; m_queue_size = queue_size; +#if APP_SCHEDULER_WITH_PROFILER + m_max_queue_utilization = 0; +#endif + return NRF_SUCCESS; } +uint16_t app_sched_queue_space_get() +{ + uint16_t start = m_queue_start_index; + uint16_t end = m_queue_end_index; + uint16_t free_space = m_queue_size - ((end >= start) ? + (end - start) : (m_queue_size + 1 - start + end)); + return free_space; +} + + +#if APP_SCHEDULER_WITH_PROFILER +static void queue_utilization_check(void) +{ + uint16_t start = m_queue_start_index; + uint16_t end = m_queue_end_index; + uint16_t queue_utilization = (end >= start) ? (end - start) : + (m_queue_size + 1 - start + end); + + if (queue_utilization > m_max_queue_utilization) + { + m_max_queue_utilization = queue_utilization; + } +} + +uint16_t app_sched_queue_utilization_get(void) +{ + return m_max_queue_utilization; +} +#endif // APP_SCHEDULER_WITH_PROFILER + + uint32_t app_sched_event_put(void * p_event_data, uint16_t event_data_size, app_sched_event_handler_t handler) @@ -105,6 +177,12 @@ uint32_t app_sched_event_put(void * p_event_data, { event_index = m_queue_end_index; m_queue_end_index = next_index(m_queue_end_index); + + #if APP_SCHEDULER_WITH_PROFILER + // This function call must be protected with critical region because + // it modifies 'm_max_queue_utilization'. + queue_utilization_check(); + #endif } CRITICAL_REGION_EXIT(); @@ -142,51 +220,69 @@ uint32_t app_sched_event_put(void * p_event_data, } -/**@brief Function for reading the next event from specified event queue. - * - * @param[out] pp_event_data Pointer to pointer to event data. - * @param[out] p_event_data_size Pointer to size of event data. - * @param[out] p_event_handler Pointer to event handler function pointer. - * - * @return NRF_SUCCESS if new event, NRF_ERROR_NOT_FOUND if event queue is empty. - */ -static uint32_t app_sched_event_get(void ** pp_event_data, - uint16_t * p_event_data_size, - app_sched_event_handler_t * p_event_handler) +#if APP_SCHEDULER_WITH_PAUSE +void app_sched_pause(void) { - uint32_t err_code = NRF_ERROR_NOT_FOUND; + CRITICAL_REGION_ENTER(); - if (!APP_SCHED_QUEUE_EMPTY()) + if (m_scheduler_paused_counter < UINT32_MAX) { - uint16_t event_index; - - // NOTE: There is no need for a critical region here, as this function will only be called - // from app_sched_execute() from inside the main loop, so it will never interrupt - // app_sched_event_put(). Also, updating of (i.e. writing to) the start index will be - // an atomic operation. - event_index = m_queue_start_index; - m_queue_start_index = next_index(m_queue_start_index); + m_scheduler_paused_counter++; + } + CRITICAL_REGION_EXIT(); +} - *pp_event_data = &m_queue_event_data[event_index * m_queue_event_size]; - *p_event_data_size = m_queue_event_headers[event_index].event_data_size; - *p_event_handler = m_queue_event_headers[event_index].handler; +void app_sched_resume(void) +{ + CRITICAL_REGION_ENTER(); - err_code = NRF_SUCCESS; + if (m_scheduler_paused_counter > 0) + { + m_scheduler_paused_counter--; } + CRITICAL_REGION_EXIT(); +} +#endif //APP_SCHEDULER_WITH_PAUSE - return err_code; + +/**@brief Function for checking if scheduler is paused which means that should break processing + * events. + * + * @return Boolean value - true if scheduler is paused, false otherwise. + */ +static __INLINE bool is_app_sched_paused(void) +{ +#if APP_SCHEDULER_WITH_PAUSE + return (m_scheduler_paused_counter > 0); +#else + return false; +#endif } void app_sched_execute(void) { - void * p_event_data; - uint16_t event_data_size; - app_sched_event_handler_t event_handler; - - // Get next event (if any), and execute handler - while ((app_sched_event_get(&p_event_data, &event_data_size, &event_handler) == NRF_SUCCESS)) + while (!is_app_sched_paused() && !APP_SCHED_QUEUE_EMPTY()) { + // Since this function is only called from the main loop, there is no + // need for a critical region here, however a special care must be taken + // regarding update of the queue start index (see the end of the loop). + uint16_t event_index = m_queue_start_index; + + void * p_event_data; + uint16_t event_data_size; + app_sched_event_handler_t event_handler; + + p_event_data = &m_queue_event_data[event_index * m_queue_event_size]; + event_data_size = m_queue_event_headers[event_index].event_data_size; + event_handler = m_queue_event_headers[event_index].handler; + event_handler(p_event_data, event_data_size); + + // Event processed, now it is safe to move the queue start index, + // so the queue entry occupied by this event can be used to store + // a next one. + m_queue_start_index = next_index(m_queue_start_index); } } +#endif //NRF_MODULE_ENABLED(APP_SCHEDULER) diff --git a/components/libraries/scheduler/app_scheduler.h b/components/libraries/scheduler/app_scheduler.h index da2fa6c..dcce9c7 100644 --- a/components/libraries/scheduler/app_scheduler.h +++ b/components/libraries/scheduler/app_scheduler.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -44,16 +72,21 @@ * @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard. * @endif * - * @image html scheduler_working.jpg The high level design of the scheduler + * @image html scheduler_working.svg The high level design of the scheduler */ #ifndef APP_SCHEDULER_H__ #define APP_SCHEDULER_H__ +#include "sdk_config.h" #include #include "app_error.h" #include "app_util.h" +#ifdef __cplusplus +extern "C" { +#endif + #define APP_SCHED_EVENT_HEADER_SIZE 8 /**< Size of app_scheduler.event_header_t (only for use inside APP_SCHED_BUF_SIZE()). */ /**@brief Compute number of bytes required to hold the scheduler buffer. @@ -66,7 +99,7 @@ */ #define APP_SCHED_BUF_SIZE(EVENT_SIZE, QUEUE_SIZE) \ (((EVENT_SIZE) + APP_SCHED_EVENT_HEADER_SIZE) * ((QUEUE_SIZE) + 1)) - + /**@brief Scheduler event handler type. */ typedef void (*app_sched_event_handler_t)(void * p_event_data, uint16_t event_size); @@ -123,7 +156,7 @@ void app_sched_execute(void); * @details Puts an event into the event queue. * * @param[in] p_event_data Pointer to event data to be scheduled. - * @param[in] event_size Size of event data to be scheduled. + * @param[in] event_size Size of event data to be scheduled. * @param[in] handler Event handler to receive the event. * * @return NRF_SUCCESS on success, otherwise an error code. @@ -132,12 +165,32 @@ uint32_t app_sched_event_put(void * p_event_data, uint16_t event_size, app_sched_event_handler_t handler); -#ifdef APP_SCHEDULER_WITH_PAUSE +/**@brief Function for getting the maximum observed queue utilization. + * + * Function for tuning the module and determining QUEUE_SIZE value and thus module RAM usage. + * + * @note @ref APP_SCHEDULER_WITH_PROFILER must be enabled to use this functionality. + * + * @return Maximum number of events in queue observed so far. + */ +uint16_t app_sched_queue_utilization_get(void); + +/**@brief Function for getting the current amount of free space in the queue. + * + * @details The real amount of free space may be less if entries are being added from an interrupt. + * To get the sxact value, this function should be called from the critical section. + * + * @return Amount of free space in the queue. + */ +uint16_t app_sched_queue_space_get(void); + /**@brief A function to pause the scheduler. * * @details When the scheduler is paused events are not pulled from the scheduler queue for * processing. The function can be called multiple times. To unblock the scheduler the * function @ref app_sched_resume has to be called the same number of times. + * + * @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality. */ void app_sched_pause(void); @@ -145,9 +198,15 @@ void app_sched_pause(void); * * @details To unblock the scheduler this function has to be called the same number of times as * @ref app_sched_pause function. + * + * @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality. */ void app_sched_resume(void); + +#ifdef __cplusplus +} #endif + #endif // APP_SCHEDULER_H__ /** @} */ diff --git a/components/libraries/scheduler/app_scheduler_serconn.c b/components/libraries/scheduler/app_scheduler_serconn.c index fc3babf..b2164ee 100644 --- a/components/libraries/scheduler/app_scheduler_serconn.c +++ b/components/libraries/scheduler/app_scheduler_serconn.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "app_scheduler.h" @@ -35,6 +63,10 @@ static volatile uint8_t m_queue_end_index; /**< Index of queue entry at the static uint16_t m_queue_event_size; /**< Maximum event size in queue. */ static uint16_t m_queue_size; /**< Number of queue entries. */ +#if APP_SCHEDULER_WITH_PROFILER +static uint16_t m_max_queue_utilization; /**< Maximum observed queue utilization. */ +#endif + static uint32_t m_scheduler_paused_counter = 0; /**< Counter storing the difference between pausing and resuming the scheduler. */ @@ -86,10 +118,45 @@ uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event m_queue_event_size = event_size; m_queue_size = queue_size; +#if APP_SCHEDULER_WITH_PROFILER + m_max_queue_utilization = 0; +#endif + return NRF_SUCCESS; } +uint16_t app_sched_queue_space_get() +{ + uint16_t start = m_queue_start_index; + uint16_t end = m_queue_end_index; + uint16_t free_space = m_queue_size - ((end >= start) ? + (end - start) : (m_queue_size + 1 - start + end)); + return free_space; +} + + +#if APP_SCHEDULER_WITH_PROFILER +static __INLINE void check_queue_utilization(void) +{ + uint16_t start = m_queue_start_index; + uint16_t end = m_queue_end_index; + uint16_t queue_utilization = (end >= start) ? (end - start) : + (m_queue_size + 1 - start + end); + + if (queue_utilization > m_max_queue_utilization) + { + m_max_queue_utilization = queue_utilization; + } +} + +uint16_t app_sched_queue_utilization_get(void) +{ + return m_max_queue_utilization; +} +#endif // APP_SCHEDULER_WITH_PROFILER + + uint32_t app_sched_event_put(void * p_event_data, uint16_t event_data_size, app_sched_event_handler_t handler) @@ -128,6 +195,10 @@ uint32_t app_sched_event_put(void * p_event_data, m_queue_event_headers[event_index].event_data_size = 0; } + #if APP_SCHEDULER_WITH_PROFILER + check_queue_utilization(); + #endif + err_code = NRF_SUCCESS; } else @@ -213,7 +284,6 @@ static __INLINE bool is_app_sched_paused(void) return (m_scheduler_paused_counter > 0); } - void app_sched_execute(void) { void * p_event_data; diff --git a/components/libraries/sdcard/app_sdcard.c b/components/libraries/sdcard/app_sdcard.c new file mode 100644 index 0000000..85906e2 --- /dev/null +++ b/components/libraries/sdcard/app_sdcard.c @@ -0,0 +1,1175 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if APP_SDCARD_ENABLED + +#include "app_sdcard.h" +#include "nrf_gpio.h" +#include "nrf_drv_spi.h" +#include "app_error.h" +#include "nrf_assert.h" + +#include "nrf_pt.h" + +#define CMD_MASK 0x40 +#define ACMD_MASK 0x80 +#define CMD0 (CMD_MASK | 0) /**< SDC/MMC command 0: GO_IDLE_STATE. */ +#define CMD1 (CMD_MASK | 1) /**< SDC/MMC command 1: SEND_OP_COND (MMC). */ +#define CMD8 (CMD_MASK | 8) /**< SDC/MMC command 8: SEND_IF_COND. */ +#define CMD9 (CMD_MASK | 9) /**< SDC/MMC command 9: SEND_CSD. */ +#define CMD10 (CMD_MASK | 10) /**< SDC/MMC command 10: SEND_CID. */ +#define CMD12 (CMD_MASK | 12) /**< SDC/MMC command 12: STOP_TRANSMISSION. */ +#define CMD16 (CMD_MASK | 16) /**< SDC/MMC command 16: SET_BLOCKLEN. */ +#define CMD17 (CMD_MASK | 17) /**< SDC/MMC command 17: READ_SINGLE_BLOCK. */ +#define CMD18 (CMD_MASK | 18) /**< SDC/MMC command 18: READ_MULTIPLE_BLOCK. */ +#define CMD23 (CMD_MASK | 23) /**< SDC/MMC command 23: SET_BLOCK_COUNT (MMC). */ +#define CMD24 (CMD_MASK | 24) /**< SDC/MMC command 24: WRITE_BLOCK. */ +#define CMD25 (CMD_MASK | 25) /**< SDC/MMC command 25: WRITE_MULTIPLE_BLOCK. */ +#define CMD32 (CMD_MASK | 32) /**< SDC/MMC command 32: ERASE_ER_BLK_START. */ +#define CMD33 (CMD_MASK | 33) /**< SDC/MMC command 33: ERASE_ER_BLK_END. */ +#define CMD38 (CMD_MASK | 38) /**< SDC/MMC command 38: ERASE. */ +#define CMD55 (CMD_MASK | 55) /**< SDC/MMC command 55: APP_CMD. */ +#define CMD58 (CMD_MASK | 58) /**< SDC/MMC command 58: READ_OCR. */ +#define ACMD13 (ACMD_MASK | CMD_MASK | 13) /**< SDC application command 13: SD_STATUS. */ +#define ACMD23 (ACMD_MASK | CMD_MASK | 23) /**< SDC application command 23: SET_WR_BLK_ERASE_COUNT. */ +#define ACMD41 (ACMD_MASK | CMD_MASK | 41) /**< SDC application command 41: SEND_OP_COND. */ + +#define IS_ACMD(CMD) ((CMD) & ACMD_MASK) /**< Check if command is an application command (ACMD). */ + +#define SDC_COMMAND_LEN 6 /**< Length of a command structure sent to the card. */ +#define SDC_COMMAND_POS 0 /**< Position of a command field inside the command structure. */ +#define SDC_COMMAND_MASK 0x7F /**< Bit mask of a command field. */ +#define SDC_COMMAND_ARG_POS 1 /**< Position of a 32-bit argument inside the command structure. */ +#define SDC_COMMAND_CRC_POS 5 /**< Position of a CRC field inside the command structure. */ + +#define SDC_MAX_NCR 8 /**< Maximum number of "busy" bytes sent before command response. */ +#define SDC_R1_LEN 1 /**< Length of R1 format response. */ +#define SDC_R3_LEN 5 /**< Length of R3 format response. */ +#define SDC_R7_LEN 5 /**< Length of R7 format response. */ +#define SDC_R_MAX_LEN 5 /**< Maximum length of command response. */ + +#define SDC_FLAG_IN_IDLE_STATE 0x01 /**< R1 response flag bit mask: idle state. */ +#define SDC_FLAG_ERASE_RESET 0x02 /**< R1 response flag bit mask: erase reset. */ +#define SDC_FLAG_ILLEGAL_COMMAND 0x04 /**< R1 response flag bit mask: illegal command. */ +#define SDC_FLAG_COM_CRC_ERROR 0x08 /**< R1 response flag bit mask: CRC error. */ +#define SDC_FLAG_ERASE_SEQUENCE_ERROR 0x10 /**< R1 response flag bit mask: erase sequence error. */ +#define SDC_FLAG_ADDRESS_ERROR 0x20 /**< R1 response flag bit mask: address error. */ +#define SDC_FLAG_PARAMETER_ERROR 0x40 /**< R1 response flag bit mask: parameter error. */ + +#define SDC_HCS_FLAG_MASK (1uL << 30) /**< High capacity support bit mask. */ + +#define SDC_EMPTY_BYTE 0xFF /**< Idle state token. */ +#define SDC_BUSY_BYTE 0x00 /**< Busy byte token. */ +#define SDC_TOKEN_START_BLOCK 0xFE /**< Data block start token. */ +#define SDC_TOKEN_START_BLOCK_MULT 0xFC /**< Data block start token for multiple write operation. */ +#define SDC_TOKEN_DATA_RESP_MASK 0x1F /**< Data response token mask. */ +#define SDC_TOKEN_DATA_RESP_ACCEPTED 0x05 /**< Data response message: accepted. */ +#define SDC_TOKEN_DATA_RESP_CRC_ERR 0x0B /**< Data response message: CRC error. */ +#define SDC_TOKEN_DATA_RESP_DATA_ERR 0x0D /**< Data response message: data error. */ +#define SDC_TOKEN_STOP_TRAN 0xFD /**< Stop transmission token. */ + +#define SDC_MAX_RETRY_COUNT_INIT 2000 /**< Maximum number of retries while card is busy (identification stage). */ +#define SDC_MAX_RETRY_COUNT 20000 /**< Maximum number of retries while card is busy. */ +#define SDC_SPI_MTU 240 /**< Maximum number of bytes in one SPI transaction. */ +#define SDC_CRC_CMD0 0x95 /**< Fixed CRC for reset command. */ +#define SDC_CRC_CMD8 0x87 /**< Fixed CRC for CMD8. */ +#define SDC_CRC_DUMMY 0xFF /**< Dummy CRC value. */ + +#define SDC_CMD_BUF_LEN 16 /**< Size of a buffer for storing SDC commands. */ +#define SDC_WORK_BUF_LEN 16 /**< Size of a working buffer. */ +#define SDC_DATA_WAIT_TX_SIZE 16 /**< Number of bytes sent during data / busy wait. */ + +#define SDC_CS_ASSERT() do { nrf_gpio_pin_clear(m_cb.cs_pin); } while (0) /**< Set CS pin to active state. */ +#define SDC_CS_DEASSERT() do { nrf_gpio_pin_set(m_cb.cs_pin); } while (0) /**< Set CS pin to inactive state. */ + +#define SDC_PT &m_cb.state.pt /**< Macro for getting SDC task structure pointer (Protothread). */ +#define SDC_PT_SUB &m_cb.state.pt_sub /**< Macro for getting SDC sub-task structure pointer (Protothread). */ + +/** Break current task (Protothread). */ +#define SDC_BREAK(PT, EXIT_CODE) do { \ + *p_exit_code = (EXIT_CODE); \ + PT_EXIT(PT); \ + } while(0) + +/**< Check the value of R1 response and break current task on error. */ +#define SDC_RESP_CHECK(PT, R1) do { \ + if ((R1) & ~(SDC_FLAG_IN_IDLE_STATE | SDC_FLAG_ERASE_RESET)) \ + { \ + SDC_BREAK((PT), SDC_ERROR_COMMUNICATION); \ + } \ + } while(0) + +/**< Check the result of an SDC operation and break on failure. */ +#define SDC_RESULT_CHECK(PT, RESULT) do { \ + if ((RESULT) != SDC_SUCCESS) \ + { \ + SDC_BREAK((PT), RESULT); \ + } \ + } while(0); + + +static const nrf_drv_spi_t m_spi = NRF_DRV_SPI_INSTANCE(APP_SDCARD_SPI_INSTANCE); /**< SPI instance. */ + +/** + * @brief SDC response type. + */ +typedef enum { + SDC_RNONE = 0, + SDC_R1, + SDC_R3, + SDC_R7 +} sdc_response_t; + +/** + * @brief SDC operation state. + */ +typedef enum { + SDC_UNINITIALIZED = 0, ///< Card not initialized. + SDC_OP_RESET = 1, ///< Reset state. + SDC_OP_IDENTIFICATION = 2, ///< Identification procedure. + SDC_OP_IDLE = 3, ///< Idle state. + SDC_OP_READ = 4, ///< Data read procedure. + SDC_OP_WRITE = 5 ///< Data write procedure. +} sdc_op_t; + +/** + * @brief SDC data bus state. + */ +typedef enum { + SDC_BUS_IDLE = 0, ///< Idle state, no active transfer. + SDC_BUS_CMD = 1, ///< Command is being transfered. + SDC_BUS_ACMD = 2, ///< Application command header transfer. + SDC_BUS_DATA_WAIT = 3, ///< Data wait state. + SDC_BUS_DATA = 4 ///< Data block transfer in progress. +} sdc_bus_state_t; + +/** + * @brief Current read/write operation state structure. + */ +typedef struct { + uint8_t * buffer; ///< Local data buffer. + uint32_t address; ///< Data block address. + uint16_t block_count; ///< Total number of blocks in read/write operation. + uint16_t blocks_left; ///< Blocks left in current read/write operation. + uint16_t position; ///< Number of blocks left to read/write. +} sdc_rw_op_t; + +/** + * @brief SDC state structure. + */ +typedef struct { + sdc_rw_op_t rw_op; ///< Read/write operation state. + pt_t pt; ///< Current task (Protothread) state. + pt_t pt_sub; ///< Current sub-task (Protothread) state. + uint16_t retry_count; ///< Number of retries left. + volatile sdc_op_t op; ///< Current operation. + sdc_bus_state_t bus_state; ///< Current data bud state. + uint8_t rsp_len; ///< Expected response length. +} sdc_state_t; + +/** + * @beirf SDC control block. + */ +typedef struct { + sdc_event_handler_t handler; ///< Event handler. + app_sdc_info_t info; ///< Card information structure. + sdc_state_t state; ///< Card state structure + uint8_t cmd_buf[SDC_CMD_BUF_LEN]; ///< Command buffer. + uint8_t rsp_buf[SDC_CMD_BUF_LEN]; ///< Card response buffer. + uint8_t work_buf[SDC_WORK_BUF_LEN]; ///< Working buffer + uint8_t cs_pin; ///< Chip select pin number. +} sdc_cb_t; + +static sdc_cb_t m_cb; ///< SDC control block. + + +/** + * @brief Function for requesting the SPI transaction. + * + * The SPI bus must be initialized prior to use of this function. + * + * @param[in] p_txb Pointer to the TX buffer. + * @param[in] tx_len TX buffer length. + * @param[out] p_rxb Pointer to the RX buffer. + * @param[in] tx_len RX buffer length. + */ +__STATIC_INLINE void sdc_spi_transfer(uint8_t const * const p_txb, + uint8_t tx_len, + uint8_t * const p_rxb, + uint8_t rx_len) +{ + SDC_CS_ASSERT(); + ret_code_t err_code = nrf_drv_spi_transfer(&m_spi, p_txb, tx_len, p_rxb, rx_len); + APP_ERROR_CHECK(err_code); +} + + +/** + * @brief Function for switching the SPI clock to high speed mode. + */ +__STATIC_INLINE void sdc_spi_hispeed(void) +{ + nrf_spi_frequency_set((NRF_SPI_Type *)m_spi.p_registers, + (nrf_spi_frequency_t) APP_SDCARD_FREQ_DATA); +} + + +/** + * @brief Function for extracting the number of data block from the CSD structure. + * + * @param[in] p_csd Pointer to the card CSD structure. + * + * @return Number of data blocks or 0 if unsupported / invalid structure was provided. + */ +static uint32_t sdc_calculate_size(uint8_t const * const p_csd) +{ + // Values are calculated as stated in SD Specifications, chapter 5.3. + uint8_t csd_version = p_csd[0] >> 6; + + switch(csd_version) + { + case 0: + case 2: + { + // SD Standard Capacity or MMC. + uint32_t c_size = ((uint32_t) p_csd[8] >> 6) + (((uint32_t) p_csd[7]) << 2) + + ((uint32_t)(p_csd[6] & 0x03) << 10); + uint32_t read_bl_len = p_csd[5] & 0x0F; + uint32_t c_size_mult = ((p_csd[10] & 0x80) >> 7) + ((p_csd[9] & 0x03) << 1); + + // Block size in this implementation is set to 512, so the resulting number of bytes + // is divided by 512 (2^9) + return (c_size + 1) << (read_bl_len + c_size_mult + 2 - 9); + } + case 1: + { + // SD High Capacity. + uint32_t c_size = (uint32_t) p_csd[9] + ((uint32_t) p_csd[8] << 8) + + (((uint32_t) p_csd[7] & 0x3F) << 16); + + // According to SD 2.0 Specifications, capacity = (C_SIZE + 1) * 512KByte. + // Block size is equal to 512, so the result is divided by 512. + return (c_size + 1) * 1024uL; + } + default: + break; + } + return 0; +} + + +/** + * @brief Non-blocking function for sending a command to the card. + * + * @param[in] cmd SDC command ID. + * @param[in] arg 32-bit command argument. + * @param[in] rsp_type Expected command response format. + * + * @retval NRF_SUCCESS If command transmission was started successfully. + * @retval NRF_ERROR_BUSY If the card is not in idle state. + */ +static ret_code_t sdc_cmd(uint8_t cmd, uint32_t arg, sdc_response_t rsp_type) +{ + if (m_cb.state.bus_state != SDC_BUS_IDLE) + { + return NRF_ERROR_BUSY; + } + + uint8_t offset = 0; + + m_cb.state.bus_state = SDC_BUS_CMD; + if (IS_ACMD(cmd)) + { + // ACMD is a combination of CMD55 and the requested command, + // which will be placed next in the command buffer. + offset = SDC_COMMAND_LEN; + m_cb.state.bus_state = SDC_BUS_ACMD; + m_cb.cmd_buf[SDC_COMMAND_POS] = CMD55; + m_cb.cmd_buf[SDC_COMMAND_ARG_POS] = 0; + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 1] = 0; + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 2] = 0; + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 3] = 0; + m_cb.cmd_buf[SDC_COMMAND_CRC_POS] = SDC_CRC_DUMMY; + } + + m_cb.cmd_buf[SDC_COMMAND_POS + offset] = cmd & SDC_COMMAND_MASK; + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + offset] = (uint8_t)(arg >> 24); + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 1 + offset] = (uint8_t)(arg >> 16); + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 2 + offset] = (uint8_t)(arg >> 8); + m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 3 + offset] = (uint8_t)(arg); + + // Use predefined CRC values and omit the crc calculation if not required. + uint8_t crc; + switch (cmd) + { + case CMD0: + crc = SDC_CRC_CMD0; + break; + case CMD8: + crc = SDC_CRC_CMD8; + break; + default: + crc = SDC_CRC_DUMMY; + break; + } + m_cb.cmd_buf[SDC_COMMAND_CRC_POS + offset] = crc; + + switch (rsp_type) + { + case SDC_R3: + m_cb.state.rsp_len = SDC_R3_LEN; + break; + case SDC_R7: + m_cb.state.rsp_len = SDC_R7_LEN; + break; + default: + m_cb.state.rsp_len = SDC_R1_LEN; + break; + } + + uint8_t response_len = (IS_ACMD(cmd)) ? SDC_R1_LEN : m_cb.state.rsp_len; + sdc_spi_transfer(m_cb.cmd_buf, + SDC_COMMAND_LEN, + m_cb.rsp_buf, + SDC_COMMAND_LEN + SDC_MAX_NCR + response_len); + + return NRF_SUCCESS; +} + + +/** + * @brief Data block read subroutine. + * + * @param[in] p_rx_data Pointer to the data received in last transation. + * @param[in] rx_length Received data length. + * @param[in] block_len Size of a data block to read. + * @param[out] p_exit_code Pointer to the subroutine exit code variable. Valid only if the thread has exited. + * + * @return Protothread exit code. Zero if protothread is running and non-zero if exited. + */ +static PT_THREAD(sdc_pt_sub_data_read(uint8_t * p_rx_data, + uint8_t rx_length, + uint16_t block_len, + sdc_result_t * p_exit_code)) +{ + PT_BEGIN(SDC_PT_SUB); + while (1) + { + ASSERT(block_len); + ASSERT(m_cb.state.rw_op.block_count); + + m_cb.state.rw_op.blocks_left = m_cb.state.rw_op.block_count; + + while (m_cb.state.rw_op.blocks_left) + { + m_cb.state.retry_count = 0; + m_cb.cmd_buf[0] = 0xFF; + m_cb.state.rw_op.position = 0; + m_cb.state.bus_state = SDC_BUS_DATA_WAIT; + + while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT) + { + ++m_cb.state.retry_count; + if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT) + { + SDC_BREAK(SDC_PT_SUB, SDC_ERROR_TIMEOUT); + } + + // Search for the first token. + while(rx_length && p_rx_data[0] == SDC_EMPTY_BYTE) + { + ++p_rx_data; + --rx_length; + } + + if (rx_length) + { + // A token has been found. + if (p_rx_data[0] == SDC_TOKEN_START_BLOCK) + { + // Expected data start token found. + // Copy the data bytes left in rx buffer into user buffer. + ++p_rx_data; + --rx_length; + m_cb.state.bus_state = SDC_BUS_DATA; + uint16_t copy_len = (rx_length > block_len) ? block_len : rx_length; + for (uint32_t i = 0; i < copy_len; ++i) + { + m_cb.state.rw_op.buffer[i] = p_rx_data[i]; + } + m_cb.state.rw_op.position = copy_len; + m_cb.state.rw_op.buffer += copy_len; + } + else + { + // Data error. + SDC_BREAK(SDC_PT_SUB, SDC_ERROR_DATA); + } + } + else + { + // Continue transfer until token is received. + sdc_spi_transfer(m_cb.cmd_buf, 1, m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE); + PT_YIELD(SDC_PT_SUB); + } + } + + while (m_cb.state.rw_op.position < block_len) + { + { + uint16_t chunk_size = block_len - m_cb.state.rw_op.position; + if (chunk_size > SDC_SPI_MTU) + { + chunk_size = SDC_SPI_MTU; + } + + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.state.rw_op.buffer, chunk_size); + m_cb.state.rw_op.buffer += chunk_size; + m_cb.state.rw_op.position += chunk_size; + } + PT_YIELD(SDC_PT_SUB); + } + + // Get the CRC. + --m_cb.state.rw_op.blocks_left; + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.rsp_buf, 2); + PT_YIELD(SDC_PT_SUB); + + + + // Set rx length to 0 to force "busy check" transmission before next data block. + rx_length = 0; + } + + // Send padding bytes. + m_cb.cmd_buf[0] = SDC_EMPTY_BYTE; + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.rsp_buf, 2); + PT_YIELD(SDC_PT_SUB); + + m_cb.state.bus_state = SDC_BUS_IDLE; + SDC_BREAK(SDC_PT_SUB, SDC_SUCCESS); + } + PT_END(SDC_PT_SUB) +} + + +/** + * @brief Card identification co-routine. + * + * @param[in] p_rx_data Pointer to the data received in last transation. + * @param[in] rx_length Received data length. + * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited. + * + * @return Protothread exit code. Zero if protothread is running and non-zero if exited. + */ +static PT_THREAD(sdc_pt_identification(uint8_t * p_rx_data, + uint8_t rx_length, + sdc_result_t * p_exit_code)) +{ + uint8_t r1 = p_rx_data[0]; + uint32_t rsp = ((uint32_t)p_rx_data[1] << 24) + | ((uint32_t)p_rx_data[2] << 16) + | ((uint32_t)p_rx_data[3] << 8) + | ((uint32_t)p_rx_data[4]); + uint32_t arg; + ret_code_t err_code; + sdc_result_t sub_exit_code; + + PT_BEGIN(SDC_PT); + while (1) + { + err_code = sdc_cmd(CMD0, 0, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + err_code = sdc_cmd(CMD0, 0, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + + SDC_RESP_CHECK(SDC_PT, r1); + // Send CMD8 with fixed argument - 0x01AA. + err_code = sdc_cmd(CMD8, 0x1AA, SDC_R7); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + + if (!(r1 & SDC_FLAG_ILLEGAL_COMMAND)) + { + // CMD8 was accepted - SD v2 card. + m_cb.info.type.version = SDC_TYPE_SDV2; + SDC_RESP_CHECK(SDC_PT, r1); + } + + m_cb.state.retry_count = 0; + arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0; + err_code = sdc_cmd(ACMD41, arg, SDC_R3); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + + if (r1 & SDC_FLAG_ILLEGAL_COMMAND) + { + // ACMD41 was rejected - MMC card. + m_cb.info.type.version = SDC_TYPE_MMCV3; + r1 &= ~SDC_FLAG_ILLEGAL_COMMAND; + + do + { + ++m_cb.state.retry_count; + if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT) + { + SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT); + } + + err_code = sdc_cmd(CMD1, 0, SDC_R3); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + SDC_RESP_CHECK(SDC_PT, r1); + } + while (r1 & SDC_FLAG_IN_IDLE_STATE); + } + else + { + // SDv1 or SDv2 card. Send CMD58 or retry ACMD41 if not ready. + SDC_RESP_CHECK(SDC_PT, r1); + + while (r1 & SDC_FLAG_IN_IDLE_STATE) + { + ++m_cb.state.retry_count; + if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT) + { + SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT); + } + + arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0; + err_code = sdc_cmd(ACMD41, arg, SDC_R3); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + SDC_RESP_CHECK(SDC_PT, r1); + } + + err_code = sdc_cmd(CMD58, 0, SDC_R3); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + SDC_RESP_CHECK(SDC_PT, r1); + + if (rsp & SDC_HCS_FLAG_MASK) + { + m_cb.info.type.sdhc = 1; + } + } + + if (m_cb.info.type.version != SDC_TYPE_SDV2) + { + // Set block length to 512 (SDv1 and MMC cards only.) + err_code = sdc_cmd(CMD16, SDC_SECTOR_SIZE, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + SDC_RESP_CHECK(SDC_PT, r1); + } + + // Setup the read operation and get the contents of 128-bit CSD register. + m_cb.state.rw_op.buffer = m_cb.work_buf; + m_cb.state.rw_op.block_count = 1; + + err_code = sdc_cmd(CMD9, 0, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + SDC_RESP_CHECK(SDC_PT, r1); + + p_rx_data += SDC_R1_LEN; + rx_length -= SDC_R1_LEN; + PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length, \ + 16, &sub_exit_code)); + SDC_RESULT_CHECK(SDC_PT, sub_exit_code); + + m_cb.info.num_blocks = sdc_calculate_size(m_cb.work_buf); + m_cb.info.block_len = SDC_SECTOR_SIZE; + + SDC_BREAK(SDC_PT, SDC_SUCCESS); + } + PT_END(SDC_PT) +} + + +/** + * @brief Data read co-routine. + * + * @param[in] p_rx_data Pointer to the data received in last transaction. + * @param[in] rx_length Received data length. + * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited. + * + * @return Protothread exit code. Zero if protothread is running and non-zero if exited. + */ +static PT_THREAD(sdc_pt_read(uint8_t * p_rx_data, + uint8_t rx_length, + sdc_result_t * p_exit_code)) +{ + uint8_t r1; + ret_code_t err_code; + sdc_result_t sub_exit_code; + + PT_BEGIN(SDC_PT); + while (1) + { + r1 = p_rx_data[0]; + SDC_RESP_CHECK(SDC_PT, r1); + + p_rx_data += SDC_R1_LEN; + rx_length -= SDC_R1_LEN; + + // Run the block read subroutine. + PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length, + SDC_SECTOR_SIZE, + &sub_exit_code)); + SDC_RESULT_CHECK(SDC_PT, sub_exit_code); + + if (m_cb.state.rw_op.block_count > 1) + { + // Send the STOP_TRANSMISSION command in multiple block read mode. + err_code = sdc_cmd(CMD12, 0, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + } + + SDC_BREAK(SDC_PT, SDC_SUCCESS); + } + PT_END(SDC_PT) +} + + +/** + * @brief Data write co-routine. + * + * @param[in] p_rx_data Pointer to the data received in last transation. + * @param[in] rx_length Received data length. + * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited. + * + * @return Protothread exit code. Zero if protothread is running and non-zero if exited. + */ +static PT_THREAD(sdc_pt_write(uint8_t * rx_data, + uint8_t rx_length, + sdc_result_t * p_exit_code)) +{ + ret_code_t err_code; + PT_BEGIN(SDC_PT); + while (1) + { + uint8_t r1; + r1 = rx_data[0]; + SDC_RESP_CHECK(SDC_PT, r1); + if (m_cb.info.type.version != SDC_TYPE_MMCV3 && m_cb.state.rw_op.block_count > 1) + { + err_code = sdc_cmd(CMD25, m_cb.state.rw_op.address, SDC_R1); + APP_ERROR_CHECK(err_code); + PT_YIELD(SDC_PT); + r1 = rx_data[0]; + SDC_RESP_CHECK(SDC_PT, r1); + } + + m_cb.state.rw_op.blocks_left = m_cb.state.rw_op.block_count; + while (m_cb.state.rw_op.blocks_left) + { + m_cb.state.rw_op.position = 0; + m_cb.state.bus_state = SDC_BUS_DATA; + + // Send block start token. + m_cb.cmd_buf[0] = SDC_EMPTY_BYTE; + m_cb.cmd_buf[1] = (m_cb.state.rw_op.block_count > 1) ? SDC_TOKEN_START_BLOCK_MULT + : SDC_TOKEN_START_BLOCK; + sdc_spi_transfer(m_cb.cmd_buf, 2, m_cb.rsp_buf, 2); + PT_YIELD(SDC_PT); + + // Send the data block. + while (m_cb.state.rw_op.position < SDC_SECTOR_SIZE) + { + { + uint16_t chunk_size = SDC_SECTOR_SIZE - m_cb.state.rw_op.position; + if (chunk_size > SDC_SPI_MTU) + { + chunk_size = SDC_SPI_MTU; + } + sdc_spi_transfer(&m_cb.state.rw_op.buffer[m_cb.state.rw_op.position], + chunk_size, + m_cb.rsp_buf, + 1); + m_cb.state.rw_op.position += chunk_size; + } + PT_YIELD(SDC_PT); + } + m_cb.state.rw_op.buffer += SDC_SECTOR_SIZE; + + // Send the dummy CRC (2 bytes) and receive data response token (1 byte). + m_cb.state.bus_state = SDC_BUS_DATA_WAIT; + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.rsp_buf, 3); + PT_YIELD(SDC_PT); + + { + uint8_t token = m_cb.rsp_buf[2] & SDC_TOKEN_DATA_RESP_MASK; + if (token != SDC_TOKEN_DATA_RESP_ACCEPTED) + { + if (token == SDC_TOKEN_DATA_RESP_CRC_ERR + || token == SDC_TOKEN_DATA_RESP_DATA_ERR) + { + SDC_BREAK(SDC_PT, SDC_ERROR_DATA); + } + else + { + SDC_BREAK(SDC_PT, SDC_ERROR_COMMUNICATION); + } + } + } + + // Wait for the card to complete the write process. + m_cb.state.retry_count = 0; + while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT) + { + ++m_cb.state.retry_count; + if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT) + { + SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT); + } + + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE); + PT_YIELD(SDC_PT); + + for (uint32_t i = 0; i < rx_length; ++i) + { + if (rx_data[i] != 0x00) + { + m_cb.state.bus_state = SDC_BUS_IDLE; + break; + } + } + } + + --m_cb.state.rw_op.blocks_left; + } + + if (m_cb.state.rw_op.block_count > 1) + { + // Send STOP_TRAN token + padding byte when writing multiple blocks. + m_cb.cmd_buf[0] = SDC_EMPTY_BYTE; + m_cb.cmd_buf[1] = SDC_TOKEN_STOP_TRAN; + sdc_spi_transfer(m_cb.cmd_buf, 2, + m_cb.rsp_buf, 3); + PT_YIELD(SDC_PT); + + m_cb.state.retry_count = 0; + m_cb.state.bus_state = SDC_BUS_DATA_WAIT; + + // Wait for the card to complete the write process. + while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT) + { + ++m_cb.state.retry_count; + if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT) + { + SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT); + } + + sdc_spi_transfer(m_cb.cmd_buf, 1, + m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE); + PT_YIELD(SDC_PT); + + for (uint32_t i = 0; i < rx_length; ++i) + { + if (rx_data[i] != 0x00) + { + m_cb.state.bus_state = SDC_BUS_IDLE; + break; + } + } + } + } + + SDC_BREAK(SDC_PT, SDC_SUCCESS); + } + PT_END(SDC_PT) +} + + +/** + * @brief SPI event handler. + * + * @param[in] p_event Pointer to the SPI event structure. + */ +static void spi_handler(nrf_drv_spi_evt_t const * p_event) +{ + uint8_t * rx_data = p_event->data.done.p_rx_buffer; + uint8_t rx_length = p_event->data.done.rx_length; + + if (!m_cb.state.rw_op.blocks_left) + { + // Deassert CS pin if not in active data transfer. + SDC_CS_DEASSERT(); + } + + if (m_cb.state.bus_state == SDC_BUS_ACMD || m_cb.state.bus_state == SDC_BUS_CMD) + { + // Find the beginning of a response. + ASSERT(rx_length > SDC_COMMAND_LEN); + rx_length -= SDC_COMMAND_LEN; + rx_data += SDC_COMMAND_LEN; + + if (p_event->data.done.p_tx_buffer[0] == CMD12) + { + // Ignore the first byte if CMD12 was sent. + if (rx_length) + { + --rx_length; + ++rx_data; + } + } + + while (rx_length && rx_data[0] == SDC_EMPTY_BYTE) + { + --rx_length; + ++rx_data; + } + if (rx_length == 0) + { + if (p_event->data.done.p_tx_buffer[0] == CMD12) + { + // Ignore invalid reply on CMD12. + ++rx_length; + --rx_data; + } + else + { + rx_data = NULL; + } + } + + if (!rx_data && m_cb.state.op != SDC_OP_RESET) + { + // Command response missing. + sdc_evt_t evt; + evt.result = SDC_ERROR_NOT_RESPONDING; + switch(m_cb.state.op) + { + case SDC_OP_RESET: + case SDC_OP_IDENTIFICATION: + evt.type = SDC_EVT_INIT; + m_cb.state.op = SDC_OP_IDLE; + APP_ERROR_CHECK(app_sdc_uninit()); + break; + case SDC_OP_READ: + evt.type = SDC_EVT_READ; + break; + case SDC_OP_WRITE: + evt.type = SDC_EVT_WRITE; + break; + default: + APP_ERROR_CHECK(NRF_ERROR_INTERNAL); + break; + } + + SDC_CS_DEASSERT(); + m_cb.state.op = SDC_OP_IDLE; + m_cb.handler(&evt); + return; + } + + if (m_cb.state.bus_state == SDC_BUS_ACMD) + { + // Check the status of CMD55 and send the scheduled command if no errors has been reported. + m_cb.state.bus_state = SDC_BUS_CMD; + uint8_t r1 = rx_data[0]; + if (!(r1 & (~SDC_FLAG_IN_IDLE_STATE))) + { + sdc_spi_transfer(m_cb.cmd_buf + SDC_COMMAND_LEN, SDC_COMMAND_LEN, + m_cb.rsp_buf, SDC_COMMAND_LEN + SDC_MAX_NCR + m_cb.state.rsp_len); + return; + } + } + m_cb.state.bus_state = SDC_BUS_IDLE; + } + + sdc_result_t exit_code = SDC_ERROR_INTERNAL; + sdc_evt_t evt; + switch(m_cb.state.op) + { + case SDC_OP_RESET: + m_cb.state.op = SDC_OP_IDENTIFICATION; + PT_INIT(SDC_PT); + //lint -e{616} + case SDC_OP_IDENTIFICATION: + if (!PT_SCHEDULE(sdc_pt_identification(rx_data, rx_length, &exit_code))) + { + evt.type = SDC_EVT_INIT; + evt.result = exit_code; + m_cb.state.op = SDC_OP_IDLE; + SDC_CS_DEASSERT(); + if (exit_code != SDC_SUCCESS) + { + // Initialization process failed. Roll back to uninitialized state. + APP_ERROR_CHECK(app_sdc_uninit()); + } + sdc_spi_hispeed(); + m_cb.handler(&evt); + } + break; + case SDC_OP_READ: + if (!PT_SCHEDULE(sdc_pt_read(rx_data, rx_length, &exit_code))) + { + evt.type = SDC_EVT_READ; + evt.result = exit_code; + m_cb.state.op = SDC_OP_IDLE; + m_cb.state.rw_op.block_count = 0; + m_cb.state.rw_op.blocks_left = 0; + m_cb.state.bus_state = SDC_BUS_IDLE; + SDC_CS_DEASSERT(); + m_cb.handler(&evt); + } + break; + case SDC_OP_WRITE: + if (!PT_SCHEDULE(sdc_pt_write(rx_data, rx_length, &exit_code))) + { + evt.type = SDC_EVT_WRITE; + evt.result = exit_code; + m_cb.state.op = SDC_OP_IDLE; + m_cb.state.bus_state = SDC_BUS_IDLE; + m_cb.state.rw_op.block_count = 0; + m_cb.state.rw_op.blocks_left = 0; + SDC_CS_DEASSERT(); + m_cb.handler(&evt); + } + break; + default: + APP_ERROR_CHECK(NRF_ERROR_INTERNAL); + break; + } + + return; +} + + +ret_code_t app_sdc_block_read(uint8_t * p_buf, uint32_t block_address, uint16_t block_count) +{ + ASSERT(p_buf); + + if (m_cb.state.op == SDC_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + if (m_cb.state.op != SDC_OP_IDLE) + { + return NRF_ERROR_BUSY; + } + if (block_count == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + + m_cb.state.op = SDC_OP_READ; + + if (!m_cb.info.type.sdhc) + { + m_cb.state.rw_op.address = block_address * SDC_SECTOR_SIZE; + } + else + { + m_cb.state.rw_op.address = block_address; + } + m_cb.state.rw_op.buffer = p_buf; + m_cb.state.rw_op.block_count = block_count; + m_cb.state.rw_op.blocks_left = block_count; + + PT_INIT(&m_cb.state.pt); + uint8_t command = (block_count > 1) ? CMD18 : CMD17; + ret_code_t err_code = sdc_cmd(command, m_cb.state.rw_op.address, SDC_R1); + APP_ERROR_CHECK(err_code); + + return NRF_SUCCESS; +} + + +ret_code_t app_sdc_block_write(uint8_t const * p_buf, uint32_t block_address, uint16_t block_count) +{ + ASSERT(p_buf); + + if (m_cb.state.op == SDC_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + if (m_cb.state.op != SDC_OP_IDLE) + { + return NRF_ERROR_BUSY; + } + if (block_count == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + m_cb.state.op = SDC_OP_WRITE; + + if (!m_cb.info.type.sdhc) + { + m_cb.state.rw_op.address = block_address * 512uL; + } + else + { + m_cb.state.rw_op.address = block_address; + } + m_cb.state.rw_op.buffer = (uint8_t *) p_buf; + m_cb.state.rw_op.block_count = block_count; + m_cb.state.rw_op.blocks_left = block_count; + + PT_INIT(&m_cb.state.pt); + + ret_code_t err_code; + if (block_count == 1) + { + err_code = sdc_cmd(CMD24, m_cb.state.rw_op.address, SDC_R1); + + APP_ERROR_CHECK(err_code); + return NRF_SUCCESS; + } + + if (m_cb.info.type.version == SDC_TYPE_MMCV3) + { + // Start multiple block write. + err_code = sdc_cmd(CMD25, m_cb.state.rw_op.address, SDC_R1); + } + else + { + // Set pre-erase for SD cards before sending CMD25. + err_code = sdc_cmd(ACMD23, block_count, SDC_R1); + } + + APP_ERROR_CHECK(err_code); + return NRF_SUCCESS; +} + + +ret_code_t app_sdc_init(app_sdc_config_t const * const p_config, sdc_event_handler_t event_handler) +{ + if (m_cb.state.op != SDC_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + if ((!event_handler) + || (p_config->cs_pin == NRF_DRV_SPI_PIN_NOT_USED) + || (p_config->miso_pin == NRF_DRV_SPI_PIN_NOT_USED) + || (p_config->mosi_pin == NRF_DRV_SPI_PIN_NOT_USED) + || (p_config->sck_pin == NRF_DRV_SPI_PIN_NOT_USED)) + { + return NRF_ERROR_INVALID_PARAM; + } + + ret_code_t err_code; + ASSERT(p_config->cs_pin && p_config->miso_pin + && p_config->mosi_pin && p_config->sck_pin); + + // Configure chip select pin. + m_cb.cs_pin = p_config->cs_pin; + nrf_gpio_cfg_output(m_cb.cs_pin); + SDC_CS_DEASSERT(); + + const nrf_drv_spi_config_t spi_cfg = { + .sck_pin = p_config->sck_pin, + .mosi_pin = p_config->mosi_pin, + .miso_pin = p_config->miso_pin, + .ss_pin = NRF_DRV_SPI_PIN_NOT_USED, + .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY, + .orc = 0xFF, + .frequency = (nrf_drv_spi_frequency_t) APP_SDCARD_FREQ_INIT, + .mode = NRF_DRV_SPI_MODE_0, + .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST, + }; + + err_code = nrf_drv_spi_init(&m_spi, &spi_cfg, spi_handler); + APP_ERROR_CHECK(err_code); + + m_cb.handler = event_handler; + m_cb.state.op = SDC_OP_RESET; + m_cb.info.type.version = SDC_TYPE_UNKNOWN; + m_cb.info.type.sdhc = 0; + m_cb.state.bus_state = SDC_BUS_IDLE; + + // Send 80 clocks with CS inactive to switch into SPI mode. + m_cb.cmd_buf[0] = 0xFF; + err_code = nrf_drv_spi_transfer(&m_spi, m_cb.cmd_buf, 1, + m_cb.rsp_buf, 10); + APP_ERROR_CHECK(err_code); + + return NRF_SUCCESS; +} + + +ret_code_t app_sdc_uninit(void) +{ + if (m_cb.state.op == SDC_UNINITIALIZED) + { + return NRF_ERROR_INVALID_STATE; + } + if (m_cb.state.op != SDC_OP_IDLE) + { + return NRF_ERROR_BUSY; + } + + nrf_drv_spi_uninit(&m_spi); + nrf_gpio_cfg_input(m_cb.cs_pin, NRF_GPIO_PIN_NOPULL); + + m_cb.state.bus_state = SDC_BUS_IDLE; + m_cb.state.op = SDC_UNINITIALIZED; + + return NRF_SUCCESS; +} + + +bool app_sdc_busy_check(void) +{ + return ((m_cb.state.op != SDC_OP_IDLE) && (m_cb.state.op != SDC_UNINITIALIZED)); +} + + +app_sdc_info_t const * app_sdc_info_get(void) +{ + if (m_cb.state.op >= SDC_OP_IDLE) + { + return &m_cb.info; + } + return NULL; +} + +#endif //APP_SDCARD_ENABLED diff --git a/components/libraries/sdcard/app_sdcard.h b/components/libraries/sdcard/app_sdcard.h new file mode 100644 index 0000000..bee46c9 --- /dev/null +++ b/components/libraries/sdcard/app_sdcard.h @@ -0,0 +1,211 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup app_sdcard SD card library + * @{ + * @ingroup app_common + * + * @brief Asynchronous Secure Digital card (SDC) and MultiMedia card (MMC) library. + */ + + +#ifndef APP_SDCARD_H_ +#define APP_SDCARD_H_ + +#include "app_util_platform.h" +#include "sdk_config.h" + +#define SDC_SECTOR_SIZE 512 ///< Size of a single SD card block in bytes. + +#define APP_SDCARD_CONFIG(MOSI_PIN, MISO_PIN, SCK_PIN, CS_PIN) { \ + .mosi_pin = MOSI_PIN, \ + .miso_pin = MISO_PIN, \ + .sck_pin = SCK_PIN, \ + .cs_pin = CS_PIN \ + } + +/** + * @brief SDC operation result. + */ +typedef enum { + SDC_SUCCESS = 0, ///< Operation successful. + SDC_ERROR_NOT_RESPONDING, ///< Card is not responding or not present. + SDC_ERROR_TIMEOUT, ///< Card response timeout. + SDC_ERROR_NOT_SUPPORTED, ///< Operation not supported. + SDC_ERROR_COMMUNICATION, ///< Communication error. + SDC_ERROR_DATA, ///< Data read/write error. + SDC_ERROR_INTERNAL, ///< Internal error. +} sdc_result_t; + +/** + * @brief SDC event type. + */ +typedef enum { + SDC_EVT_INIT = 0, ///< Initialization procedure. + SDC_EVT_READ, ///< Data read procedure. + SDC_EVT_WRITE ///< Data write procedure. +} sdc_evt_type_t; + +/** + * @brief SDC event structure. + */ +typedef struct { + sdc_evt_type_t type; ///< Event type. + sdc_result_t result; ///< Operation result. +} sdc_evt_t; + +/** + * @brief SDC type and version. + */ +typedef enum { + SDC_TYPE_UNKNOWN = 0, ///< Unknown / uninitialized card. + SDC_TYPE_MMCV3, ///< MultiMedia card (MMC) version 3. + SDC_TYPE_SDV1, ///< Secure Digital card (SDC) version 1.0. + SDC_TYPE_SDV2 ///< Secure Digital card (SDC) version 2.0. +} sdc_version_t; + +/** + * @brief SDC type information structure. + */ +typedef struct { + sdc_version_t version : 3; ///< Card type and version (SD or MMC). + uint8_t sdhc : 1; ///< Standard Capacity or High Capacity card. +} sdc_type_t; + +/** + * @brief SDC configuration structure. + */ +typedef struct { + uint8_t mosi_pin; ///< Serial data in (MOSI / DI) pin number. + uint8_t miso_pin; ///< Serial data out (MISO / DO) pin number. + uint8_t sck_pin; ///< Serial clock (SCK) pin number. + uint8_t cs_pin; ///< Chip select (CS) pin number. +} app_sdc_config_t; + +/** + * @brief SDC information structure. + */ +typedef struct { + uint32_t num_blocks; ///< Number of available data blocks. + uint16_t block_len; ///< Length (in bytes) of a single data block. + sdc_type_t type; ///< Card type information structure. +} app_sdc_info_t; + +/** + * @brief SDC event handler type. + */ +typedef void (*sdc_event_handler_t)(sdc_evt_t const * p_event); + + +/** + * @brief Function for initializing the card. + * + * @param[in] p_config Pointer to the SDC configuration structure. + * @param[in] event_handler Pointer to the event handler function. + * + * @retval NRF_SUCCESS If initialization process was started succesfully. + * @retval NRF_ERROR_INVALID_STATE If the card is already initialized or the initialization is in progress. + * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified. + */ +ret_code_t app_sdc_init(app_sdc_config_t const * const p_config, sdc_event_handler_t event_handler); + + +/** + * @brief Function for uninitializing the card. + * + * @retval NRF_SUCCESS If card was uninitialized succesfully. + * @retval NRF_ERROR_INVALID_STATE If the card is not initialized. + * @retval NRF_ERROR_BUSY If there is an operation in progress. + */ +ret_code_t app_sdc_uninit(void); + + +/** + * @brief Function for retrieving the card busy state. + * + * @retval true If there is an operation in progress. + * @retval false If the card is in idle state. + */ +bool app_sdc_busy_check(void); + + +/** + * @brief Function for reading the data blocks from the card. + * + * @param[out] p_buf Pointer to the data buffer. Must not be null. + * @param[in] block_address Number of the first block to be read. + * @param[in] block_count Number of blocks to read. Must be greater than 0. + * + * @retval NRF_SUCCESS If block read operation was started succesfully. + * @retval NRF_ERROR_INVALID_STATE If the card is not initialized. + * @retval NRF_ERROR_BUSY If there is already an operation active. + * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified. + */ +ret_code_t app_sdc_block_read(uint8_t * p_buf, uint32_t block_address, uint16_t block_count); + + +/** + * @brief Function for writing the data blocks to the card. + * + * @param[out] p_buf Pointer to the data to be written. Must not be null. + * @param[in] block_address Number of the first block to write. + * @param[in] block_count Number of blocks to write. Must be greater than 0. + * + * @retval NRF_SUCCESS If block write operation was started succesfully. + * @retval NRF_ERROR_INVALID_STATE If the card is not initialized. + * @retval NRF_ERROR_BUSY If there is already an operation active. + * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified. + */ +ret_code_t app_sdc_block_write(uint8_t const * p_buf, uint32_t block_address, uint16_t block_count); + + +/** + * @brief Function for retrieving the card information structure. + * + * @return Pointer to the card information structure or NULL if card is not initialized. + */ +app_sdc_info_t const * app_sdc_info_get(void); + + +#endif //APP_SDC_H_ +/** @} */ diff --git a/components/libraries/sensorsim/sensorsim.c b/components/libraries/sensorsim/sensorsim.c index 7a0b35d..06134bd 100644 --- a/components/libraries/sensorsim/sensorsim.c +++ b/components/libraries/sensorsim/sensorsim.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "sensorsim.h" diff --git a/components/libraries/sensorsim/sensorsim.h b/components/libraries/sensorsim/sensorsim.h index 3d2674b..593dad5 100644 --- a/components/libraries/sensorsim/sensorsim.h +++ b/components/libraries/sensorsim/sensorsim.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -26,6 +54,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Triangular waveform sensor simulator configuration. */ typedef struct { @@ -47,7 +79,7 @@ typedef struct * @param[out] p_state Current state of simulator. * @param[in] p_cfg Simulator configuration. */ -void sensorsim_init(sensorsim_state_t * p_state, +void sensorsim_init(sensorsim_state_t * p_state, const sensorsim_cfg_t * p_cfg); /**@brief Function for generating a simulated sensor measurement using a triangular waveform generator. @@ -80,6 +112,11 @@ void sensorsim_increment(sensorsim_state_t * p_state, void sensorsim_decrement(sensorsim_state_t * p_state, const sensorsim_cfg_t * p_cfg); + +#ifdef __cplusplus +} +#endif + #endif // SENSORSIM_H__ /** @} */ diff --git a/components/libraries/sha256/sha256.c b/components/libraries/sha256/sha256.c index df574c5..492aafd 100644 --- a/components/libraries/sha256/sha256.c +++ b/components/libraries/sha256/sha256.c @@ -1,26 +1,52 @@ - -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include -#include -#include #include "sha256.h" #include "sdk_errors.h" +#include "sdk_common.h" -#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b)))) -#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b)))) +#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) +#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32 - (b)))) #define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z))) #define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) @@ -91,10 +117,7 @@ void sha256_transform(sha256_context_t *ctx, const uint8_t * data) ret_code_t sha256_init(sha256_context_t *ctx) { - if (ctx == NULL) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(ctx); ctx->datalen = 0; ctx->bitlen = 0; @@ -113,7 +136,8 @@ ret_code_t sha256_init(sha256_context_t *ctx) ret_code_t sha256_update(sha256_context_t *ctx, const uint8_t * data, size_t len) { - if ((ctx == NULL) || ((len > 0) && (data == NULL))) + VERIFY_PARAM_NOT_NULL(ctx); + if (((len > 0) && (data == NULL))) { return NRF_ERROR_NULL; } @@ -134,15 +158,13 @@ ret_code_t sha256_update(sha256_context_t *ctx, const uint8_t * data, size_t len } -ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash) +ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash, uint8_t le) { - if ((ctx == NULL) || (hash == NULL)) - { - return NRF_ERROR_NULL; - } - uint32_t i; + VERIFY_PARAM_NOT_NULL(ctx); + VERIFY_PARAM_NOT_NULL(hash); + i = ctx->datalen; // Pad whatever data is left in the buffer. @@ -171,17 +193,34 @@ ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash) ctx->data[56] = ctx->bitlen >> 56; sha256_transform(ctx, ctx->data); - // Since this implementation uses little endian uint8_t ordering and SHA uses big endian, - // reverse all the uint8_ts when copying the final state to the output hash. - for (i = 0; i < 4; ++i) { - hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; - hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; - hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; - hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; - hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; - hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; - hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; - hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; + if(le) + { + for (i = 0; i < 4; ++i) { + hash[i] = (ctx->state[7] >> (i * 8)) & 0x000000ff; + hash[i + 4] = (ctx->state[6] >> (i * 8)) & 0x000000ff; + hash[i + 8] = (ctx->state[5] >> (i * 8)) & 0x000000ff; + hash[i + 12] = (ctx->state[4] >> (i * 8)) & 0x000000ff; + hash[i + 16] = (ctx->state[3] >> (i * 8)) & 0x000000ff; + hash[i + 20] = (ctx->state[2] >> (i * 8)) & 0x000000ff; + hash[i + 24] = (ctx->state[1] >> (i * 8)) & 0x000000ff; + hash[i + 28] = (ctx->state[0] >> (i * 8)) & 0x000000ff; + } + } + else + { + + // Since this implementation uses little endian uint8_t ordering and SHA uses big endian, + // reverse all the uint8_ts when copying the final state to the output hash. + for (i = 0; i < 4; ++i) { + hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; + hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; + hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; + hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; + hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; + hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff; + hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff; + hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff; + } } return NRF_SUCCESS; diff --git a/components/libraries/sha256/sha256.h b/components/libraries/sha256/sha256.h index 56d70d3..0643fe9 100644 --- a/components/libraries/sha256/sha256.h +++ b/components/libraries/sha256/sha256.h @@ -1,14 +1,41 @@ - -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -37,6 +64,10 @@ #include #include "sdk_errors.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Current state of a hash operation. */ @@ -59,7 +90,7 @@ ret_code_t sha256_init(sha256_context_t *ctx); /**@brief Function for calculating the hash of an array of uint8_t data. * - * @details This function can be called multiple times in sequence. This is equivalent to calling + * @details This function can be called multiple times in sequence. This is equivalent to calling * the function once on a concatenation of the data from the different calls. * * @param[in,out] ctx Hash instance. @@ -80,11 +111,17 @@ ret_code_t sha256_update(sha256_context_t *ctx, const uint8_t * data, const size * * @param[in,out] ctx Hash instance. * @param[out] hash Array to hold the extracted hash value (assumed to be 32 bytes long). + * @param[in] le Store the hash in little-endian. * * @retval NRF_SUCCESS If the has value was successfully extracted. * @retval NRF_ERROR_NULL If a parameter was NULL. */ -ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash); +ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash, uint8_t le); + + +#ifdef __cplusplus +} +#endif #endif // SHA256_H diff --git a/components/libraries/simple_timer/app_simple_timer.c b/components/libraries/simple_timer/app_simple_timer.c index 9890fce..69d845f 100644 --- a/components/libraries/simple_timer/app_simple_timer.c +++ b/components/libraries/simple_timer/app_simple_timer.c @@ -1,24 +1,50 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SIMPLE_TIMER) #include "app_simple_timer.h" #include "nrf.h" -#include "nordic_common.h" #include "app_util_platform.h" #include "app_error.h" #include "nrf_timer.h" #include "nrf_drv_timer.h" -#include -#include /**@brief States of simple timer state machine. */ @@ -35,42 +61,14 @@ static app_simple_timer_timeout_handler_t m_timeout_handler = NULL; static void * mp_timeout_handler_context = NULL; /**< Registered time-out handler context. */ static simple_timer_states_t m_simple_timer_state = SIMPLE_TIMER_STATE_IDLE; /**< State machine state. */ -#define APP_SIMPLE_TIMER_INSTANCE 1 - -#if (APP_SIMPLE_TIMER_INSTANCE == 0) - #if (TIMER_CONFIG_MODE(0) != TIMER_MODE_MODE_Timer) - #error "Unsupported timer mode." - #endif - #if (TIMER_CONFIG_BIT_WIDTH(0) != TIMER_BITMODE_BITMODE_16Bit) - #error "Unsupported timer bit width." - #endif - const nrf_drv_timer_t SIMPLE_TIMER = NRF_DRV_TIMER_INSTANCE(0); -#elif (APP_SIMPLE_TIMER_INSTANCE == 1) - #if (TIMER_CONFIG_MODE(1) != TIMER_MODE_MODE_Timer) - #error "Unsupported timer mode." - #endif - #if (TIMER_CONFIG_BIT_WIDTH(1) != TIMER_BITMODE_BITMODE_16Bit) - #error "Unsupported timer bit width." - #endif - const nrf_drv_timer_t SIMPLE_TIMER = NRF_DRV_TIMER_INSTANCE(1); -#elif (APP_SIMPLE_TIMER_INSTANCE == 2) - #if (TIMER_CONFIG_MODE(2) != TIMER_MODE_MODE_Timer) - #error "Unsupported timer mode." - #endif - #if (TIMER_CONFIG_BIT_WIDTH(2) != TIMER_BITMODE_BITMODE_16Bit) - #error "Unsupported timer bit width." - #endif - const nrf_drv_timer_t SIMPLE_TIMER = NRF_DRV_TIMER_INSTANCE(2); -#else - #error "Wrong timer instance id." -#endif +const nrf_drv_timer_t SIMPLE_TIMER = NRF_DRV_TIMER_INSTANCE(SIMPLE_TIMER_CONFIG_INSTANCE); /** * @brief Handler for timer events. */ static void app_simple_timer_event_handler(nrf_timer_event_t event_type, void * p_context) { - switch(event_type) + switch (event_type) { case NRF_TIMER_EVENT_COMPARE0: if (m_mode == APP_SIMPLE_TIMER_MODE_SINGLE_SHOT) @@ -91,10 +89,13 @@ static void app_simple_timer_event_handler(nrf_timer_event_t event_type, void * uint32_t app_simple_timer_init(void) { uint32_t err_code = NRF_SUCCESS; + nrf_drv_timer_config_t t_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; + t_cfg.mode = NRF_TIMER_MODE_TIMER; + t_cfg.bit_width = NRF_TIMER_BIT_WIDTH_16; + t_cfg.frequency = (nrf_timer_frequency_t)SIMPLE_TIMER_CONFIG_FREQUENCY; + err_code = nrf_drv_timer_init(&SIMPLE_TIMER, &t_cfg, app_simple_timer_event_handler); - err_code = nrf_drv_timer_init(&SIMPLE_TIMER, NULL, app_simple_timer_event_handler); - - if(NRF_SUCCESS == err_code) + if (NRF_SUCCESS == err_code) { m_simple_timer_state = SIMPLE_TIMER_STATE_INITIALIZED; } @@ -102,7 +103,7 @@ uint32_t app_simple_timer_init(void) return err_code; } -uint32_t app_simple_timer_start(app_simple_timer_mode_t mode, +uint32_t app_simple_timer_start(app_simple_timer_mode_t mode, app_simple_timer_timeout_handler_t timeout_handler, uint16_t timeout_ticks, void * p_context) @@ -110,16 +111,13 @@ uint32_t app_simple_timer_start(app_simple_timer_mode_t mode, uint32_t err_code = NRF_SUCCESS; nrf_timer_short_mask_t timer_short; - if (NULL == timeout_handler) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(timeout_handler); if (APP_SIMPLE_TIMER_MODE_REPEATED == mode) { timer_short = NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK; } - else if(APP_SIMPLE_TIMER_MODE_SINGLE_SHOT == mode) + else if (APP_SIMPLE_TIMER_MODE_SINGLE_SHOT == mode) { timer_short = NRF_TIMER_SHORT_COMPARE0_STOP_MASK; } @@ -128,18 +126,18 @@ uint32_t app_simple_timer_start(app_simple_timer_mode_t mode, return NRF_ERROR_INVALID_PARAM; } - if(SIMPLE_TIMER_STATE_IDLE == m_simple_timer_state) + if (SIMPLE_TIMER_STATE_IDLE == m_simple_timer_state) { return NRF_ERROR_INVALID_STATE; } - if(SIMPLE_TIMER_STATE_STARTED == m_simple_timer_state) + if (SIMPLE_TIMER_STATE_STARTED == m_simple_timer_state) { err_code = app_simple_timer_stop(); APP_ERROR_CHECK(err_code); } - if(SIMPLE_TIMER_STATE_STOPPED == m_simple_timer_state) + if (SIMPLE_TIMER_STATE_STOPPED == m_simple_timer_state) { nrf_drv_timer_clear(&SIMPLE_TIMER); } @@ -168,7 +166,7 @@ uint32_t app_simple_timer_start(app_simple_timer_mode_t mode, uint32_t app_simple_timer_stop(void) { - if(SIMPLE_TIMER_STATE_STARTED == m_simple_timer_state) + if (SIMPLE_TIMER_STATE_STARTED == m_simple_timer_state) { nrf_drv_timer_pause(&SIMPLE_TIMER); @@ -182,7 +180,7 @@ uint32_t app_simple_timer_uninit(void) { uint32_t err_code = NRF_SUCCESS; - if(SIMPLE_TIMER_STATE_IDLE != m_simple_timer_state) + if (SIMPLE_TIMER_STATE_IDLE != m_simple_timer_state) { nrf_drv_timer_uninit(&SIMPLE_TIMER); m_simple_timer_state = SIMPLE_TIMER_STATE_IDLE; @@ -190,3 +188,4 @@ uint32_t app_simple_timer_uninit(void) return err_code; } +#endif //NRF_MODULE_ENABLED(SIMPLE_TIMER) diff --git a/components/libraries/simple_timer/app_simple_timer.h b/components/libraries/simple_timer/app_simple_timer.h index e8a4377..c6e5ba7 100644 --- a/components/libraries/simple_timer/app_simple_timer.h +++ b/components/libraries/simple_timer/app_simple_timer.h @@ -1,18 +1,46 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup lib_driver_simple_timer Simple Timer + * @defgroup app_simple_timer Simple Timer * @{ * @ingroup app_common * @@ -29,6 +57,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Timer time-out handler type. */ typedef void (*app_simple_timer_timeout_handler_t)(void * p_context); @@ -39,11 +71,9 @@ typedef enum APP_SIMPLE_TIMER_MODE_REPEATED /**< The timer will restart each time it expires. */ } app_simple_timer_mode_t; -/**@brief Function for configuring and setting up the timer hardware. +/**@brief Function for configuring and setting up the timer hardware. * - * @note Configuration parameters should be set in nrf_drv_config.h file. - * The TIMER1_CONFIG_MODE has to be set to NRF_TIMER_MODE_TIMER value. - * The TIMER1_CONFIG_BIT_WIDTH has to be set to NRF_TIMER_BIT_WIDTH_16 value. + * @note Timer frequency is configured statically. * * @retval NRF_SUCCESS If the operation is successful. * @retval NRF_ERROR_INVALID_STATE If the operation fails because the timer is already initialized. @@ -54,23 +84,23 @@ uint32_t app_simple_timer_init(void); /**@brief Function for starting a timer. * - * @note If this function is called for a timer that is already running, the currently running + * @note If this function is called for a timer that is already running, the currently running * timer is stopped before starting the new one. * * @param[in] mode Timer mode (see @ref app_simple_timer_mode_t). - * @param[in] timeout_handler Function to be executed when the timer expires + * @param[in] timeout_handler Function to be executed when the timer expires * (see @ref app_simple_timer_timeout_handler_t). * @param[in] timeout_ticks Number of timer ticks to time-out event. - * @param[in] p_context General purpose pointer. Will be passed to the time-out handler + * @param[in] p_context General purpose pointer. Will be passed to the time-out handler * when the timer expires. - * + * * @retval NRF_SUCCESS If the operation is successful. * @retval NRF_ERROR_INVALID_STATE If the operation fails because @ref app_simple_timer_init has not * been called and the operation is not allowed in this state. * @retval NRF_ERROR_NULL If the operation fails because timeout_handler is NULL. * @retval NRF_ERROR_INVALID_PARAM If the operation fails because "mode" parameter is not valid. */ - + uint32_t app_simple_timer_start(app_simple_timer_mode_t mode, app_simple_timer_timeout_handler_t timeout_handler, uint16_t timeout_ticks, @@ -93,6 +123,11 @@ uint32_t app_simple_timer_stop(void); */ uint32_t app_simple_timer_uninit(void); + +#ifdef __cplusplus +} +#endif + #endif // TIMER_H__ /** @} */ diff --git a/components/libraries/slip/slip.c b/components/libraries/slip/slip.c index 2337b43..e91e631 100644 --- a/components/libraries/slip/slip.c +++ b/components/libraries/slip/slip.c @@ -1,15 +1,44 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(SLIP) #include "slip.h" #include "nrf_error.h" @@ -23,7 +52,7 @@ uint32_t slip_encode(uint8_t * p_output, uint8_t * p_input, uint32_t input_leng { uint32_t input_index; uint32_t output_index; - + for (input_index = 0, output_index = 0; input_index < input_length && output_index < output_buffer_length; input_index++) { switch (p_input[input_index]) @@ -32,25 +61,25 @@ uint32_t slip_encode(uint8_t * p_output, uint8_t * p_input, uint32_t input_leng p_output[output_index++] = SLIP_END; p_output[output_index++] = SLIP_ESC_END; break; - + case SLIP_ESC: p_output[output_index++] = SLIP_ESC; p_output[output_index++] = SLIP_ESC_ESC; break; - + default: p_output[output_index++] = p_input[input_index]; } } p_output[output_index++] = (uint8_t)SLIP_END; p_output[output_index++] = (uint8_t)SLIP_END; // clarify that the packet has ended. - + return output_index; } uint32_t slip_decoding_add_char(uint8_t c, buffer_t * p_buf, slip_state_t * current_state) -{ +{ switch (*current_state) { case SLIP_DECODING: @@ -62,19 +91,19 @@ uint32_t slip_decoding_add_char(uint8_t c, buffer_t * p_buf, slip_state_t * curr { *current_state = SLIP_END_RECEIVED; } - else + else { p_buf->p_buffer[p_buf->current_index++] = c; p_buf->current_length++; } break; - + case SLIP_ESC_RECEIVED: if (c == SLIP_ESC_ESC) { - p_buf->p_buffer[p_buf->current_index++] = SLIP_ESC; - p_buf->current_length++; - *current_state = SLIP_DECODING; + p_buf->p_buffer[p_buf->current_index++] = SLIP_ESC; + p_buf->current_length++; + *current_state = SLIP_DECODING; } else { @@ -83,7 +112,7 @@ uint32_t slip_decoding_add_char(uint8_t c, buffer_t * p_buf, slip_state_t * curr return NRF_ERROR_INVALID_DATA; } break; - + case SLIP_END_RECEIVED: if (c == SLIP_ESC_END) { @@ -91,22 +120,23 @@ uint32_t slip_decoding_add_char(uint8_t c, buffer_t * p_buf, slip_state_t * curr p_buf->current_length++; *current_state = SLIP_DECODING; } - else + else { // packet is finished - *current_state = SLIP_DECODING; + *current_state = SLIP_DECODING; return NRF_SUCCESS; } - break; - + break; + case SLIP_CLEARING_INVALID_PACKET: if (c == SLIP_END) { - *current_state = SLIP_DECODING; + *current_state = SLIP_DECODING; p_buf->current_index = 0; p_buf->current_length = 0; } break; - } + } return NRF_ERROR_BUSY; } +#endif //NRF_MODULE_ENABLED(SLIP) diff --git a/components/libraries/slip/slip.h b/components/libraries/slip/slip.h index f4768a9..7039092 100644 --- a/components/libraries/slip/slip.h +++ b/components/libraries/slip/slip.h @@ -1,21 +1,53 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SLIP_H__ #define SLIP_H__ #include #include "app_fifo.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @file * * @defgroup slip SLIP encoding decoding @@ -26,7 +58,7 @@ * * @details The standard is described in https://tools.ietf.org/html/rfc1055 */ - + typedef enum { SLIP_DECODING, SLIP_END_RECEIVED, @@ -39,28 +71,33 @@ typedef struct { uint32_t current_index; uint32_t current_length; uint32_t len; -} buffer_t; - +} buffer_t; + /**@brief Encodes a slip packet. - * - * @details Note that the encoded output data will be longer than the input data. * - * @retval The length of the encoded packet. If it is smaller than the input length, an error has occurred. + * @details Note that the encoded output data will be longer than the input data. + * + * @retval The length of the encoded packet. If it is smaller than the input length, an error has occurred. */ uint32_t slip_encode(uint8_t * p_output, uint8_t * p_input, uint32_t input_length, uint32_t output_buffer_length); /**@brief Decodes a slip packet. - * + * * @details When decoding a slip packet, a state must be preserved. Initial state must be set to SLIP_DECODING. * * @retval NRF_SUCCESS when a packet is parsed. The length of the packet can be read out from p_buf->current_index * @retval NRF_ERROR_BUSY when packet is not finished parsing - * @retval NRF_ERROR_INVALID_DATA when packet is encoded wrong. + * @retval NRF_ERROR_INVALID_DATA when packet is encoded wrong. This moves the decoding to SLIP_CLEARING_INVALID_PACKET, and will stay in this state until SLIP_END is encountered. */ uint32_t slip_decoding_add_char(uint8_t c, buffer_t * p_buf, slip_state_t * current_state); + +#ifdef __cplusplus +} +#endif + #endif // SLIP_H__ /** @} */ diff --git a/components/libraries/svc/nrf_svc_function.h b/components/libraries/svc/nrf_svc_function.h new file mode 100644 index 0000000..ef9abc3 --- /dev/null +++ b/components/libraries/svc/nrf_svc_function.h @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SVC_FUNCTION_H__ +#define NRF_SVC_FUNCTION_H__ + +#include +#include "section_vars.h" +#include "app_util.h" +#include "nrf_svci.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Function to be called from an SVC handler. + * + * @warning The function prototype must be limited to a maximum of four arguments, due to the nature of SVC calls. + */ +typedef uint32_t (*nrf_svc_func_t)(); + +/** @brief Type holding the SVC number and the pointer to the corresponding function. + * + * Not that the function that is pointed to must not change version. + */ +typedef struct +{ + uint32_t svc_num; /**< Supervisor call number (actually 8-bit, padded for alignment). */ + uint32_t svci_num; /**< Supervisor call indirect number. */ + nrf_svc_func_t func_ptr; +} nrf_svc_func_reg_t; + + +// Verify that the size of nrf_svc_func_t is aligned. +STATIC_ASSERT(sizeof(nrf_svc_func_reg_t) % 4 == 0); + + +/** @brief Macro for registering a structure holding SVC number and function pointer. + * + * @details This macro places the variable in a section named "svc_data" that + the SVC handler uses during regular operation. + */ +#define SVC_REGISTER_FUNCTION(svc_var) NRF_SECTION_VARS_ADD(svc_data, svc_var) + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SVC_FUNCTION_H__ diff --git a/components/libraries/svc/nrf_svc_handler.c b/components/libraries/svc/nrf_svc_handler.c new file mode 100644 index 0000000..f673163 --- /dev/null +++ b/components/libraries/svc/nrf_svc_handler.c @@ -0,0 +1,182 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "nrf_svc_function.h" +#include "nrf_error.h" + +#include "nrf_log.h" + + + //lint -save -e19 -e526 +NRF_SECTION_VARS_CREATE_SECTION(svc_data, const nrf_svc_func_t); +//lint -restore + + +#define SVC_DATA_SECTION_VARS_GET(i) NRF_SECTION_VARS_GET((i), nrf_svc_func_reg_t, svc_data) +#define SVC_DATA_SECTION_VARS_COUNT NRF_SECTION_VARS_COUNT(nrf_svc_func_reg_t, svc_data) + + +/**@brief Function for handling second stage of SuperVisor Calls (SVC). +* +* @details The function will use loop through the registered svc functions stored +* in the named section "svc_data" and will call the registered function +* if the svn_num corresponds with the registration. +* +* @param[in] svc_num SVC number for function to be executed +* @param[in] p_svc_args Argument list for the SVC. +* +* @return This function returns by updating p_svc_arsg[0]. This will be reported back to the caller of SVC +* @ref NRF_ERROR_SVC_HANDLER_MISSING is returned if no SVC handler is implemented for the +* provided svc_num. +*/ +void nrf_svc_handler_c(uint8_t svc_num, uint32_t * p_svc_args) +{ + uint32_t const num_funcs = SVC_DATA_SECTION_VARS_COUNT; + bool handled = false; + uint32_t svci_num = NRF_SVCI_SVC_NUM_INVALID; + + if(svc_num == NRF_SVCI_SVC_NUM) + { + /* load the stacked R12 as the svci_num */ + svci_num = p_svc_args[4]; + } + + for (int i = 0; i < num_funcs; i++) + { + nrf_svc_func_reg_t const * func_reg = SVC_DATA_SECTION_VARS_GET(i); + if (func_reg->svc_num != svc_num) + { + continue; + } + + if(svci_num != NRF_SVCI_SVC_NUM_INVALID && func_reg->svci_num != svci_num) + { + continue; + } + + p_svc_args[0] = func_reg->func_ptr(p_svc_args[0], p_svc_args[1], p_svc_args[2], p_svc_args[3]); + handled = true; + } + + if (handled == false) + { + p_svc_args[0] = NRF_ERROR_SVC_HANDLER_MISSING; + } +} + +/**@brief Function for handling the first stage of SuperVisor Calls (SVC) in assembly. +* +* @details The function will use the link register (LR) to determine the stack (PSP or MSP) to be +* used and then decode the SVC number afterwards. After decoding the SVC number then +* @ref C_SVC_Handler is called for further processing of the SVC. +*/ +#if defined ( __CC_ARM ) +__ASM void SVC_Handler(void) +{ +EXC_RETURN_CMD_PSP EQU 0xFFFFFFFD ; EXC_RETURN using PSP for ARM Cortex.If Link register contains this value it indicates the PSP was used before the SVC, otherwise the MSP was used. + + IMPORT nrf_svc_handler_c + LDR R0, =EXC_RETURN_CMD_PSP ; Load the EXC_RETURN into R0 to be able to compare against LR to determine stack pointer used. + CMP R0, LR ; Compare the link register with R0.If equal then PSP was used, otherwise MSP was used before SVC. + BNE UseMSP ; Branch to code fetching SVC arguments using MSP. + MRS R1, PSP ; Move PSP into R1. + B Call_nrf_svc_handler_c ; Branch to call_nrf_svc_handler_c below. +UseMSP ; + MRS R1, MSP ; MSP was used, therefore Move MSP into R1. +Call_nrf_svc_handler_c ; + LDR R0, [R1, #24] ; The arguments for the SVC was stacked.R1 contains Stack Pointer, the values stacked before SVC are R0, R1, R2, R3, R12, LR, PC(Return address), xPSR. + ; R1 contains current SP so the PC of the stacked frame is at SP + 6 words(24 bytes).We load the PC into R0. + SUBS R0, #2 ; The PC before the SVC is in R0.We subtract 2 to get the address prior to the instruction executed where the SVC number is located. + LDRB R0, [R0] ; SVC instruction low octet : Load the byte at the address before the PC to fetch the SVC number. + LDR R2, =nrf_svc_handler_c ; Load address of C implementation of SVC handler. + BX R2 ; Branch to C implementation of SVC handler.R0 is now the SVC number, R1 is the StackPointer where the arguments(R0 - R3) of the original SVC are located. + ALIGN +} +#elif defined ( __GNUC__ ) +void __attribute__((naked)) SVC_Handler(void) +{ + const uint32_t exc_return = 0xFFFFFFFD; // EXC_RETURN using PSP for ARM Cortex. If Link register contains this value it indicates the PSP was used before the SVC, otherwise the MSP was used. + + __ASM volatile( + "cmp lr, %0\t\n" // Compare the link register with argument 0 (%0), which is exc_return. If equal then PSP was used, otherwise MSP was used before SVC. + "bne UseMSP\t\n" // Branch to code fetching SVC arguments using MSP. + "mrs r1, psp\t\n" // Move PSP into R1. + "b Call_nrf_svc_handler_c\t\n" // Branch to Call_nrf_svc_handler_c below. + "UseMSP:\t\n" // + "mrs r1, msp\t\n" // MSP was used, therefore Move MSP into R1. + "Call_nrf_svc_handler_c:\t\n" // + "ldr r0, [r1, #24]\t\n" // The arguments for the SVC was stacked. R1 contains Stack Pointer, the values stacked before SVC are R0, R1, R2, R3, R12, LR, PC (Return address), xPSR. + // R1 contains current SP so the PC of the stacked frame is at SP + 6 words (24 bytes). We load the PC into R0. + "sub r0, r0, #2\t\n" // The PC before the SVC is in R0. We subtract 2 to get the address prior to the instruction executed where the SVC number is located. + "ldrb r0, [r0]\t\n" // SVC instruction low octet: Load the byte at the address before the PC to fetch the SVC number. + "bx %1\t\n" // Branch to C implementation of SVC handler, argument 1 (%1). R0 is now the SVC number, R1 is the StackPointer where the arguments (R0-R3) of the original SVC are located. + ".align\t\n" // + :: "r" (exc_return), "r" (nrf_svc_handler_c) // Argument list for the gcc assembly. exc_return is %0, nrf_svc_handler_c is %1. + : "r0", "r1" // List of register maintained manually. + ); +} +#elif defined ( __ICCARM__ ) +void SVC_Handler(void) +{ + __ASM("movs r0, #0x02\n" // Load 0x02 into R6 to prepare for exec return test. + "mvns r0, r0\n" // Invert R0 to obtain exec return code using PSP for ARM Cortex. + "cmp lr, r0\n" // Compare the link register with argument 0 (%0), which is exc_return. If equal then PSP was used, otherwise MSP was used before SVC. + "bne.n UseMSP\n" // Branch to code fetching SVC arguments using MSP. + "mrs r1, psp\n" // Move PSP into R1. + "b.n Call_nrf_svc_handler_c\t\n" // Branch to Call_nrf_svc_handler_c below. + "UseMSP: \n" // + "mrs r1, msp\n" // MSP was used, therefore Move MSP into R1. + "Call_nrf_svc_handler_c: \n" // + "ldr r0, [r1, #24]\n" // The arguments for the SVC was stacked. R1 contains Stack Pointer, the values stacked before SVC are R0, R1, R2, R3, R12, LR, PC (Return address), xPSR. + // R1 contains current SP so the PC of the stacked frame is at SP + 6 words (24 bytes). We load the PC into R0. + "subs r0, #0x02\n" // The PC before the SVC is in R0. We subtract 2 to get the address prior to the instruction executed where the SVC number is located. + "ldrb r0, [r0]\n" // SVC instruction low octet: Load the byte at the address before the PC to fetch the SVC number. + "bx %0\n" // Branch to C implementation of SVC handler, argument 1 (%1). R0 is now the SVC number, R1 is the StackPointer where the arguments (R0-R3) of the original SVC are located. + :: "r" (nrf_svc_handler_c) // Argument list for the gcc assembly. nrf_svc_handler_c is %0. + : "r0", "r1" // List of register maintained manually. + ); +} +#else + +#error Compiler not supported. + +#endif diff --git a/components/libraries/svc/nrf_svci.h b/components/libraries/svc/nrf_svci.h new file mode 100644 index 0000000..30c3866 --- /dev/null +++ b/components/libraries/svc/nrf_svci.h @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SVCI_H__ +#define NRF_SVCI_H__ + +#include "stdint.h" +#include "compiler_abstraction.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_SVCI_SVC_NUM 0 /**< SVC number used for all SVCI functions. */ +#define NRF_SVCI_SVC_NUM_INVALID (0xFFFFFFFF) /**< Invalid SVCI number. */ + + +#if defined (__CC_ARM) + + #define SVCI_DECL(svci_num, return_type, function_name, ...) \ + return_type __svc_indirect(NRF_SVCI_SVC_NUM) svci_##function_name(uint32_t _svci_num, ##__VA_ARGS__); + +#elif defined (__GNUC__) + + #ifdef __cplusplus + #define GCC_CAST_CPP (uint8_t) + #else + #define GCC_CAST_CPP + #endif + + #define SVCI_DECL(svci_num, return_type, function_name, ...) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ + __attribute__((naked, unused)) \ + static return_type function_name(uint32_t svci_num, \ + __VA_ARGS__) \ + { \ + __asm __volatile ( \ + "mov r12, %1\n\t" \ + "svc %0\n\t" \ + "bx r14\n\t" \ + : /* no output */ \ + : "I" (GCC_CAST_CPP NRF_SVCI_SVC_NUM), "r" (svci_num) \ + : "r12" /* do we need to clobber? */ \ + ); \ + } \ + _Pragma("GCC diagnostic pop") + +#elif defined (__ICCARM__) + + #define SVCI_DECL(svci_num, return_type, function_name, ...) \ + /* Suppress return value warming. */ \ + _Pragma("diag_suppress=Pe940") \ + static return_type function_name(uint32_t svci_num, \ + __VA_ARGS__) \ + { \ + __asm volatile ( \ + "mov r12, %1\n\t" \ + "svc %0\n\t" \ + "bx r14\n\t" \ + : /* no output */ \ + : "I" (NRF_SVCI_SVC_NUM), "r" (svci_num) \ + : "r12" /* do we need to clobber? */ \ + ); \ + } + +#else + + #define SVCI_DECL(svci_number, return_type, function_name, ...) + +#endif + +#define VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, N, ...) N +#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 4, 4, 3, 3, 2, 2, 1, 1, 0) + +#ifdef SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION + +#define SVCI_0(svci_num, return_type, function_name) \ + return_type function_name(void) +#define SVCI_1(svci_num, return_type, function_name, p0t, p0n) \ + return_type function_name(p0t p0n) +#define SVCI_2(svci_num, return_type, function_name, p0t, p0n, p1t, p1n) \ + return_type function_name(p0t p0n, p1t p1n) +#define SVCI_3(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n) \ + return_type function_name(p0t p0n, p1t p1n, p2t p2n) +#define SVCI_4(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n, p3t, p3n) \ + return_type function_name(p0t p0n, p1t p1n, p2t p2n, p3t p3n) + +#else + +#define SVCI_0(svci_num, return_type, function_name) \ + SVCI_DECL(svci_num, return_type, function_name) \ + static __INLINE return_type function_name(void) {return svci_##function_name(svci_num);} + +#define SVCI_1(svci_num, return_type, function_name, p0t, p0n) \ + SVCI_DECL(svci_num, return_type, function_name, p0t p0n) \ + static __INLINE return_type function_name(p0t p0n) {return svci_##function_name(svci_num, p0n);} + +#define SVCI_2(svci_num, return_type, function_name, p0t, p0n, p1t, p1n) \ + SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n) \ + static __INLINE return_type function_name(p0t p0n, p1t p1n) {return svci_##function_name(svci_num, p0n, p1n);} + +#define SVCI_3(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n) \ + SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n) \ + static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n) {return svci_##function_name(svci_num, p0n, p1n, p2n);} + +#define SVCI_4(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n, p3t, p3n) \ + SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n, p3t p3n) \ + static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n, p3t p3n) {return svci_##function_name(svci_num, p0n, p1n, p2n, p3n);} + +#endif // SVCALL_AS_NORMAL_FUNCTION + +#define SVCI_IMPLI(count, svci_num, return_type, function_name, ...) SVCI##_##count (svci_num, return_type, function_name, ##__VA_ARGS__) +#define SVCI_IMPL(count, svci_num, return_type, function_name, ...) SVCI_IMPLI(count, svci_num, return_type, function_name, ##__VA_ARGS__) +#define SVCI(svci_num, return_type, function_name, ...) SVCI_IMPL(VA_NARGS(__VA_ARGS__), svci_num, return_type, function_name, ##__VA_ARGS__) + + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SVCI_H__ diff --git a/components/libraries/timer/app_timer.c b/components/libraries/timer/app_timer.c index b343184..f33d67c 100644 --- a/components/libraries/timer/app_timer.c +++ b/components/libraries/timer/app_timer.c @@ -1,26 +1,54 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_TIMER) #include "app_timer.h" #include #include "nrf.h" #include "nrf_soc.h" #include "app_error.h" #include "nrf_delay.h" -#include "app_util.h" #include "app_util_platform.h" -#define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOW /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */ -#define SWI_IRQ_PRI APP_IRQ_PRIORITY_LOW /**< Priority of the SWI interrupt (used for updating the timer list). */ +#define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOWEST /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */ +#define SWI_IRQ_PRI APP_IRQ_PRIORITY_LOWEST /**< Priority of the SWI interrupt (used for updating the timer list). */ // The current design assumes that both interrupt handlers run at the same interrupt level. // If this is to be changed, protection must be added to prevent them from interrupting each other @@ -29,21 +57,14 @@ STATIC_ASSERT(RTC1_IRQ_PRI == SWI_IRQ_PRI); #define MAX_RTC_COUNTER_VAL 0x00FFFFFF /**< Maximum value of the RTC counter. */ -#define APP_HIGH_USER_ID 0 /**< User Id for the Application High "user". */ -#define APP_LOW_USER_ID 1 /**< User Id for the Application Low "user". */ -#define THREAD_MODE_USER_ID 2 /**< User Id for the Thread Mode "user". */ - #define RTC_COMPARE_OFFSET_MIN 3 /**< Minimum offset between the current RTC counter value and the Capture Compare register. Although the nRF51 Series User Specification recommends this value to be 2, we use 3 to be safer.*/ #define MAX_RTC_TASKS_DELAY 47 /**< Maximum delay until an RTC task is executed. */ -#ifdef NRF51 #define SWI_IRQn SWI0_IRQn #define SWI_IRQHandler SWI0_IRQHandler -#elif defined NRF52 -#define SWI_IRQn SWI0_EGU0_IRQn -#define SWI_IRQHandler SWI0_EGU0_IRQHandler -#endif + +#define MODULE_INITIALIZED (m_op_queue.p_user_op_queue != NULL) /**< Macro designating whether the module has been initialized properly. */ /**@brief Timer node type. The nodes will be used form a linked list of running timers. */ typedef struct @@ -93,38 +114,24 @@ typedef struct STATIC_ASSERT(sizeof(timer_user_op_t) <= APP_TIMER_USER_OP_SIZE); STATIC_ASSERT(sizeof(timer_user_op_t) % 4 == 0); -/**@brief Structure describing a timer user. +/**@brief Structure describing a timer operations queue. * - * @details For each user of the timer module, there will be a timer operations queue. This queue - * will hold timer operations issued by this user until the timer interrupt handler - * processes these operations. For the current implementation, there will be one user for - * each interrupt level available to the application (APP_HIGH, APP_LOW and THREAD_MODE), - * but the module can easily be modified to e.g. have one queue per process when using an - * RTOS. The purpose of the queues is to be able to have a completely lockless timer - * implementation. + * @details This queue will hold timer operations issued by the application + * until the timer interrupt handler processes these operations. */ typedef struct { uint8_t first; /**< Index of first entry to have been inserted in the queue (i.e. the next entry to be executed). */ uint8_t last; /**< Index of last entry to have been inserted in the queue. */ - uint8_t user_op_queue_size; /**< Queue size. */ + uint8_t size; /**< Queue size. */ timer_user_op_t * p_user_op_queue; /**< Queue buffer. */ -} timer_user_t; - -STATIC_ASSERT(sizeof(timer_user_t) == APP_TIMER_USER_SIZE); -STATIC_ASSERT(sizeof(timer_user_t) % 4 == 0); +} timer_op_queue_t; -/**@brief User id type. - * - * @details In the current implementation, this will automatically be generated from the current - * interrupt level. - */ -typedef uint32_t timer_user_id_t; +STATIC_ASSERT(sizeof(timer_op_queue_t) % 4 == 0); -#define CONTEXT_QUEUE_SIZE_MAX (2) +#define CONTEXT_QUEUE_SIZE_MAX (2) -static uint8_t m_user_array_size; /**< Size of timer user array. */ -static timer_user_t * mp_users = NULL; /**< Array of timer users. */ +static timer_op_queue_t m_op_queue; /**< Timer operations queue. */ static timer_node_t * mp_timer_id_head; /**< First timer in list of running timers. */ static uint32_t m_ticks_latest; /**< Last known RTC counter value. */ static uint32_t m_ticks_elapsed[CONTEXT_QUEUE_SIZE_MAX]; /**< Timer internal elapsed ticks queue. */ @@ -133,7 +140,10 @@ static uint8_t m_ticks_elapsed_q_write_ind; static app_timer_evt_schedule_func_t m_evt_schedule_func; /**< Pointer to function for propagating timeout events to the scheduler. */ static bool m_rtc1_running; /**< Boolean indicating if RTC1 is running. */ static bool m_rtc1_reset; /**< Boolean indicating if RTC1 counter has been reset due to last timer removed from timer list during the timer list handling. */ - + +#if APP_TIMER_WITH_PROFILER +static uint8_t m_max_user_op_queue_utilization; /**< Maximum observed timer user operations queue utilization. */ +#endif /**@brief Function for initializing the RTC1 counter. * @@ -229,7 +239,7 @@ static void timer_list_insert(timer_node_t * p_timer) if (p_timer->ticks_to_expire <= mp_timer_id_head->ticks_to_expire) { mp_timer_id_head->ticks_to_expire -= p_timer->ticks_to_expire; - + p_timer->next = mp_timer_id_head; mp_timer_id_head = p_timer; } @@ -242,7 +252,7 @@ static void timer_list_insert(timer_node_t * p_timer) ticks_to_expire = p_timer->ticks_to_expire; p_previous = mp_timer_id_head; p_current = mp_timer_id_head; - + while ((p_current != NULL) && (ticks_to_expire > p_current->ticks_to_expire)) { ticks_to_expire -= p_current->ticks_to_expire; @@ -276,7 +286,7 @@ static void timer_list_remove(timer_node_t * p_timer) // Find the timer's position in timer list. p_previous = mp_timer_id_head; p_current = p_previous; - + while (p_current != NULL) { if (p_current == p_timer) @@ -361,7 +371,7 @@ static void timeout_handler_exec(timer_node_t * p_timer) */ static void timer_timeouts_check(void) { - // Handle expired of timer + // Handle expired of timer if (mp_timer_id_head != NULL) { timer_node_t * p_timer; @@ -468,50 +478,43 @@ static bool elapsed_ticks_acquire(uint32_t * p_ticks_elapsed) static bool list_deletions_handler(void) { timer_node_t * p_timer_old_head; - uint8_t user_id; + uint8_t user_ops_first = m_op_queue.first; // Remember the old head, so as to decide if new compare needs to be set. p_timer_old_head = mp_timer_id_head; - user_id = m_user_array_size; - while (user_id--) + while (user_ops_first != m_op_queue.last) { - timer_user_t * p_user = &mp_users[user_id]; - uint8_t user_ops_first = p_user->first; - - while (user_ops_first != p_user->last) + timer_user_op_t * p_user_op = &m_op_queue.p_user_op_queue[user_ops_first]; + + // Traverse to next operation in queue. + user_ops_first++; + if (user_ops_first == m_op_queue.size) { - timer_user_op_t * p_user_op = &p_user->p_user_op_queue[user_ops_first]; + user_ops_first = 0; + } - // Traverse to next operation in queue. - user_ops_first++; - if (user_ops_first == p_user->user_op_queue_size) - { - user_ops_first = 0; - } + switch (p_user_op->op_type) + { + case TIMER_USER_OP_TYPE_STOP: + // Delete node if timer is running. + timer_list_remove(p_user_op->p_node); + break; - switch (p_user_op->op_type) - { - case TIMER_USER_OP_TYPE_STOP: - // Delete node if timer is running. - timer_list_remove(p_user_op->p_node); - break; - - case TIMER_USER_OP_TYPE_STOP_ALL: - // Delete list of running timers, and mark all timers as not running. - while (mp_timer_id_head != NULL) - { - timer_node_t * p_head = mp_timer_id_head; - - p_head->is_running = false; - mp_timer_id_head = p_head->next; - } - break; - - default: - // No implementation needed. - break; - } + case TIMER_USER_OP_TYPE_STOP_ALL: + // Delete list of running timers, and mark all timers as not running. + while (mp_timer_id_head != NULL) + { + timer_node_t * p_head = mp_timer_id_head; + + p_head->is_running = false; + mp_timer_id_head = p_head->next; + } + break; + + default: + // No implementation needed. + break; } } @@ -540,7 +543,7 @@ static void expired_timers_handler(uint32_t ticks_elapsed, // Auto variable for current timer node. p_timer = mp_timer_id_head; - // Do nothing if timer did not expire + // Do nothing if timer did not expire if (ticks_elapsed < p_timer->ticks_to_expire) { p_timer->ticks_to_expire -= ticks_elapsed; @@ -579,89 +582,82 @@ static void expired_timers_handler(uint32_t ticks_elapsed, static bool list_insertions_handler(timer_node_t * p_restart_list_head) { timer_node_t * p_timer_id_old_head; - uint8_t user_id; // Remember the old head, so as to decide if new compare needs to be set. p_timer_id_old_head = mp_timer_id_head; - user_id = m_user_array_size; - while (user_id--) + // Handle insertions of timers. + while ((p_restart_list_head != NULL) || (m_op_queue.first != m_op_queue.last)) { - timer_user_t * p_user = &mp_users[user_id]; + timer_node_t * p_timer; - // Handle insertions of timers. - while ((p_restart_list_head != NULL) || (p_user->first != p_user->last)) + if (p_restart_list_head != NULL) { - timer_node_t * p_timer; + p_timer = p_restart_list_head; + p_restart_list_head = p_timer->next; + } + else + { + timer_user_op_t * p_user_op = &m_op_queue.p_user_op_queue[m_op_queue.first]; - if (p_restart_list_head != NULL) + m_op_queue.first++; + if (m_op_queue.first == m_op_queue.size) { - p_timer = p_restart_list_head; - p_restart_list_head = p_timer->next; + m_op_queue.first = 0; } - else - { - timer_user_op_t * p_user_op = &p_user->p_user_op_queue[p_user->first]; - - p_user->first++; - if (p_user->first == p_user->user_op_queue_size) - { - p_user->first = 0; - } - p_timer = p_user_op->p_node; + p_timer = p_user_op->p_node; - if ((p_user_op->op_type != TIMER_USER_OP_TYPE_START) || p_timer->is_running) - { - continue; - } + if ((p_user_op->op_type != TIMER_USER_OP_TYPE_START) || p_timer->is_running) + { + continue; + } - p_timer->ticks_at_start = p_user_op->params.start.ticks_at_start; - p_timer->ticks_first_interval = p_user_op->params.start.ticks_first_interval; - p_timer->ticks_periodic_interval = p_user_op->params.start.ticks_periodic_interval; - p_timer->p_context = p_user_op->params.start.p_context; + p_timer->ticks_at_start = p_user_op->params.start.ticks_at_start; + p_timer->ticks_first_interval = p_user_op->params.start.ticks_first_interval; + p_timer->ticks_periodic_interval = p_user_op->params.start.ticks_periodic_interval; + p_timer->p_context = p_user_op->params.start.p_context; - if (m_rtc1_reset) - { - p_timer->ticks_at_start = 0; - } + if (m_rtc1_reset) + { + p_timer->ticks_at_start = 0; } + } - // Prepare the node to be inserted. - if ( - ((p_timer->ticks_at_start - m_ticks_latest) & MAX_RTC_COUNTER_VAL) - < - (MAX_RTC_COUNTER_VAL / 2) - ) + // Prepare the node to be inserted. + if ( + ((p_timer->ticks_at_start - m_ticks_latest) & MAX_RTC_COUNTER_VAL) + < + (MAX_RTC_COUNTER_VAL / 2) + ) + { + p_timer->ticks_to_expire = ticks_diff_get(p_timer->ticks_at_start, m_ticks_latest) + + p_timer->ticks_first_interval; + } + else + { + uint32_t delta_current_start; + + delta_current_start = ticks_diff_get(m_ticks_latest, p_timer->ticks_at_start); + if (p_timer->ticks_first_interval > delta_current_start) { - p_timer->ticks_to_expire = ticks_diff_get(p_timer->ticks_at_start, m_ticks_latest) + - p_timer->ticks_first_interval; + p_timer->ticks_to_expire = p_timer->ticks_first_interval - delta_current_start; } else { - uint32_t delta_current_start; - - delta_current_start = ticks_diff_get(m_ticks_latest, p_timer->ticks_at_start); - if (p_timer->ticks_first_interval > delta_current_start) - { - p_timer->ticks_to_expire = p_timer->ticks_first_interval - delta_current_start; - } - else - { - p_timer->ticks_to_expire = 0; - } + p_timer->ticks_to_expire = 0; } + } - p_timer->ticks_at_start = 0; - p_timer->ticks_first_interval = 0; - p_timer->is_running = true; - p_timer->next = NULL; + p_timer->ticks_at_start = 0; + p_timer->ticks_first_interval = 0; + p_timer->is_running = true; + p_timer->next = NULL; - // Insert into list - timer_list_insert(p_timer); - } + // Insert into list + timer_list_insert(p_timer); } - + return (mp_timer_id_head != p_timer_id_old_head); } @@ -670,7 +666,7 @@ static bool list_insertions_handler(timer_node_t * p_restart_list_head) */ static void compare_reg_update(timer_node_t * p_timer_id_head_old) { - // Setup the timeout for timers on the head of the list + // Setup the timeout for timers on the head of the list if (mp_timer_id_head != NULL) { uint32_t ticks_to_expire = mp_timer_id_head->ticks_to_expire; @@ -686,7 +682,7 @@ static void compare_reg_update(timer_node_t * p_timer_id_head_old) cc += (ticks_elapsed < ticks_to_expire) ? ticks_to_expire : ticks_elapsed; cc &= MAX_RTC_COUNTER_VAL; - + rtc1_compare0_set(cc); uint32_t post_counter_val = rtc1_counter_get(); @@ -699,7 +695,7 @@ static void compare_reg_update(timer_node_t * p_timer_id_head_old) { // When this happens the COMPARE event may not be triggered by the RTC. // The nRF51 Series User Specification states that if the COUNTER value is N - // (i.e post_counter_val = N), writing N or N+1 to a CC register may not trigger a + // (i.e post_counter_val = N), writing N or N + 1 to a CC register may not trigger a // COMPARE event. Hence the RTC interrupt is forcefully pended by calling the following // function. rtc1_compare0_set(rtc1_counter_get()); // this should prevent CC to fire again in the background while the code is in RTC-ISR @@ -709,8 +705,10 @@ static void compare_reg_update(timer_node_t * p_timer_id_head_old) } else { +#if (APP_TIMER_KEEPS_RTC_ACTIVE == 0) // No timers are running, stop RTC rtc1_stop(); +#endif //(APP_TIMER_KEEPS_RTC_ACTIVE == 0) } } @@ -726,24 +724,38 @@ static void timer_list_handler(void) bool ticks_have_elapsed; bool compare_update; timer_node_t * p_timer_id_head_old; - + +#if APP_TIMER_WITH_PROFILER + { + uint8_t size = m_op_queue.size; + uint8_t first = m_op_queue.first; + uint8_t last = m_op_queue.last; + uint8_t utilization = (first <= last) ? (last - first) : (size + 1 - first + last); + + if (utilization > m_max_user_op_queue_utilization) + { + m_max_user_op_queue_utilization = utilization; + } + } +#endif + // Back up the previous known tick and previous list head ticks_previous = m_ticks_latest; p_timer_id_head_old = mp_timer_id_head; - + // Get number of elapsed ticks ticks_have_elapsed = elapsed_ticks_acquire(&ticks_elapsed); // Handle list deletions compare_update = list_deletions_handler(); - + // Handle expired timers if (ticks_have_elapsed) { expired_timers_handler(ticks_elapsed, ticks_previous, &p_restart_list_head); compare_update = true; } - + // Handle list insertions if (list_insertions_handler(p_restart_list_head)) { @@ -761,49 +773,46 @@ static void timer_list_handler(void) /**@brief Function for enqueueing a new operations queue entry. * - * @param[in] p_user User that the entry is to be enqueued for. * @param[in] last_index Index of the next last index to be enqueued. */ -static void user_op_enque(timer_user_t * p_user, uint8_t last_index) +static void user_op_enque(uint8_t last_index) { - p_user->last = last_index; + m_op_queue.last = last_index; } /**@brief Function for allocating a new operations queue entry. * - * @param[in] p_user User that the entry is to be allocated for. * @param[out] p_last_index Index of the next last index to be enqueued. * * @return Pointer to allocated queue entry, or NULL if queue is full. */ -static timer_user_op_t * user_op_alloc(timer_user_t * p_user, uint8_t * p_last_index) -{ +static timer_user_op_t * user_op_alloc( uint8_t * p_last_index) +{ uint8_t last; timer_user_op_t * p_user_op; - - last = p_user->last + 1; - if (last == p_user->user_op_queue_size) + + last = m_op_queue.last + 1; + if (last == m_op_queue.size) { // Overflow case. last = 0; } - if (last == p_user->first) + if (last == m_op_queue.first) { // Queue is full. return NULL; } - - *p_last_index = last; - p_user_op = &p_user->p_user_op_queue[p_user->last]; - + + *p_last_index = last; + p_user_op = &m_op_queue.p_user_op_queue[m_op_queue.last]; + return p_user_op; } /**@brief Function for scheduling a Timer Start operation. * - * @param[in] user_id Id of user calling this function. * @param[in] timer_id Id of timer to start. * @param[in] timeout_initial Time (in ticks) to first timer expiry. * @param[in] timeout_periodic Time (in ticks) between periodic expiries. @@ -811,89 +820,81 @@ static timer_user_op_t * user_op_alloc(timer_user_t * p_user, uint8_t * p_last_i * the timer expires. * @return NRF_SUCCESS on success, otherwise an error code. */ -static uint32_t timer_start_op_schedule(timer_user_id_t user_id, - timer_node_t * p_node, + +static uint32_t timer_start_op_schedule(timer_node_t * p_node, uint32_t timeout_initial, uint32_t timeout_periodic, void * p_context) { uint8_t last_index; - - timer_user_op_t * p_user_op = user_op_alloc(&mp_users[user_id], &last_index); + uint32_t err_code = NRF_SUCCESS; + + CRITICAL_REGION_ENTER(); + timer_user_op_t * p_user_op = user_op_alloc(&last_index); if (p_user_op == NULL) { - return NRF_ERROR_NO_MEM; + err_code = NRF_ERROR_NO_MEM; + } + else + { + + p_user_op->op_type = TIMER_USER_OP_TYPE_START; + p_user_op->p_node = p_node; + p_user_op->params.start.ticks_at_start = rtc1_counter_get(); + p_user_op->params.start.ticks_first_interval = timeout_initial; + p_user_op->params.start.ticks_periodic_interval = timeout_periodic; + p_user_op->params.start.p_context = p_context; + + user_op_enque(last_index); } - - p_user_op->op_type = TIMER_USER_OP_TYPE_START; - p_user_op->p_node = p_node; - p_user_op->params.start.ticks_at_start = rtc1_counter_get(); - p_user_op->params.start.ticks_first_interval = timeout_initial; - p_user_op->params.start.ticks_periodic_interval = timeout_periodic; - p_user_op->params.start.p_context = p_context; - - user_op_enque(&mp_users[user_id], last_index); - - timer_list_handler_sched(); + CRITICAL_REGION_EXIT(); - return NRF_SUCCESS; + if (err_code == NRF_SUCCESS) + { + timer_list_handler_sched(); + } + + return err_code; } /**@brief Function for scheduling a Timer Stop operation. * - * @param[in] user_id Id of user calling this function. * @param[in] timer_id Id of timer to stop. + * @param[in] op_type Type of stop operation * * @return NRF_SUCCESS on successful scheduling a timer stop operation. NRF_ERROR_NO_MEM when there * is no memory left to schedule the timer stop operation. */ -static uint32_t timer_stop_op_schedule(timer_user_id_t user_id, timer_node_t * p_node) +static uint32_t timer_stop_op_schedule(timer_node_t * p_node, + timer_user_op_type_t op_type) { uint8_t last_index; - - timer_user_op_t * p_user_op = user_op_alloc(&mp_users[user_id], &last_index); + uint32_t err_code = NRF_SUCCESS; + + CRITICAL_REGION_ENTER(); + timer_user_op_t * p_user_op = user_op_alloc(&last_index); if (p_user_op == NULL) { - return NRF_ERROR_NO_MEM; + err_code = NRF_ERROR_NO_MEM; } - - p_user_op->op_type = TIMER_USER_OP_TYPE_STOP; - p_user_op->p_node = p_node; - - user_op_enque(&mp_users[user_id], last_index); - - timer_list_handler_sched(); - - return NRF_SUCCESS; -} + else + { + p_user_op->op_type = op_type; + p_user_op->p_node = p_node; + user_op_enque(last_index); + } + CRITICAL_REGION_EXIT(); -/**@brief Function for scheduling a Timer Stop All operation. - * - * @param[in] user_id Id of user calling this function. - */ -static uint32_t timer_stop_all_op_schedule(timer_user_id_t user_id) -{ - uint8_t last_index; - - timer_user_op_t * p_user_op = user_op_alloc(&mp_users[user_id], &last_index); - if (p_user_op == NULL) + if (err_code == NRF_SUCCESS) { - return NRF_ERROR_NO_MEM; + timer_list_handler_sched(); } - - p_user_op->op_type = TIMER_USER_OP_TYPE_STOP_ALL; - p_user_op->p_node = NULL; - - user_op_enque(&mp_users[user_id], last_index); - timer_list_handler_sched(); - - return NRF_SUCCESS; + return err_code; } - /**@brief Function for handling the RTC1 interrupt. * * @details Checks for timeouts, and executes timeout handlers for expired timers. @@ -924,12 +925,10 @@ void SWI_IRQHandler(void) uint32_t app_timer_init(uint32_t prescaler, - uint8_t op_queues_size, + uint8_t op_queue_size, void * p_buffer, app_timer_evt_schedule_func_t evt_schedule_func) { - int i; - // Check that buffer is correctly aligned if (!is_word_aligned(p_buffer)) { @@ -938,40 +937,28 @@ uint32_t app_timer_init(uint32_t prescaler, // Check for NULL buffer if (p_buffer == NULL) { - mp_users = NULL; return NRF_ERROR_INVALID_PARAM; } - + // Stop RTC to prevent any running timers from expiring (in case of reinitialization) rtc1_stop(); - + m_evt_schedule_func = evt_schedule_func; - - // Initialize users array - m_user_array_size = APP_TIMER_INT_LEVELS; - mp_users = p_buffer; - - // Skip user array - p_buffer = &((uint8_t *)p_buffer)[APP_TIMER_INT_LEVELS * sizeof(timer_user_t)]; - - // Initialize operation queues - for (i = 0; i < APP_TIMER_INT_LEVELS; i++) - { - timer_user_t * p_user = &mp_users[i]; - - p_user->first = 0; - p_user->last = 0; - p_user->user_op_queue_size = op_queues_size; - p_user->p_user_op_queue = p_buffer; - - // Skip operation queue - p_buffer = &((uint8_t *)p_buffer)[op_queues_size * sizeof(timer_user_op_t)]; - } - mp_timer_id_head = NULL; + // Initialize operation queue + m_op_queue.first = 0; + m_op_queue.last = 0; + m_op_queue.size = op_queue_size; + m_op_queue.p_user_op_queue = p_buffer; + + mp_timer_id_head = NULL; m_ticks_elapsed_q_read_ind = 0; m_ticks_elapsed_q_write_ind = 0; +#if APP_TIMER_WITH_PROFILER + m_max_user_op_queue_utilization = 0; +#endif + NVIC_ClearPendingIRQ(SWI_IRQn); NVIC_SetPriority(SWI_IRQn, SWI_IRQ_PRI); NVIC_EnableIRQ(SWI_IRQn); @@ -979,7 +966,7 @@ uint32_t app_timer_init(uint32_t prescaler, rtc1_init(prescaler); m_ticks_latest = rtc1_counter_get(); - + return NRF_SUCCESS; } @@ -989,10 +976,8 @@ uint32_t app_timer_create(app_timer_id_t const * p_timer_id, app_timer_timeout_handler_t timeout_handler) { // Check state and parameters - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } + VERIFY_MODULE_INITIALIZED(); + if (timeout_handler == NULL) { return NRF_ERROR_INVALID_PARAM; @@ -1005,7 +990,7 @@ uint32_t app_timer_create(app_timer_id_t const * p_timer_id, { return NRF_ERROR_INVALID_STATE; } - + timer_node_t * p_node = (timer_node_t *)*p_timer_id; p_node->is_running = false; p_node->mode = mode; @@ -1013,46 +998,14 @@ uint32_t app_timer_create(app_timer_id_t const * p_timer_id, return NRF_SUCCESS; } - -/**@brief Function for creating a timer user id from the current interrupt level. - * - * @return Timer user id. -*/ -static timer_user_id_t user_id_get(void) -{ - timer_user_id_t ret; - - STATIC_ASSERT(APP_TIMER_INT_LEVELS == 3); - - switch (current_int_priority_get()) - { - case APP_IRQ_PRIORITY_HIGH: - ret = APP_HIGH_USER_ID; - break; - - case APP_IRQ_PRIORITY_LOW: - ret = APP_LOW_USER_ID; - break; - - default: - ret = THREAD_MODE_USER_ID; - break; - } - - return ret; -} - - uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context) { uint32_t timeout_periodic; timer_node_t * p_node = (timer_node_t*)timer_id; - + // Check state and parameters - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } + VERIFY_MODULE_INITIALIZED(); + if (timer_id == 0) { return NRF_ERROR_INVALID_STATE; @@ -1065,12 +1018,11 @@ uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * { return NRF_ERROR_INVALID_STATE; } - + // Schedule timer start operation timeout_periodic = (p_node->mode == APP_TIMER_MODE_REPEATED) ? timeout_ticks : 0; - return timer_start_op_schedule(user_id_get(), - p_node, + return timer_start_op_schedule(p_node, timeout_ticks, timeout_periodic, p_context); @@ -1081,36 +1033,31 @@ uint32_t app_timer_stop(app_timer_id_t timer_id) { timer_node_t * p_node = (timer_node_t*)timer_id; // Check state and parameters - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } + VERIFY_MODULE_INITIALIZED(); + if ((timer_id == NULL) || (p_node->p_timeout_handler == NULL)) { return NRF_ERROR_INVALID_STATE; } - + p_node->is_running = false; // Schedule timer stop operation - return timer_stop_op_schedule(user_id_get(), p_node); + return timer_stop_op_schedule(p_node, TIMER_USER_OP_TYPE_STOP); } uint32_t app_timer_stop_all(void) { // Check state - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } - return timer_stop_all_op_schedule(user_id_get()); + VERIFY_MODULE_INITIALIZED(); + + return timer_stop_op_schedule(NULL, TIMER_USER_OP_TYPE_STOP_ALL); } -uint32_t app_timer_cnt_get(uint32_t * p_ticks) +uint32_t app_timer_cnt_get(void) { - *p_ticks = rtc1_counter_get(); - return NRF_SUCCESS; + return rtc1_counter_get(); } @@ -1122,3 +1069,10 @@ uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to, return NRF_SUCCESS; } +#if APP_TIMER_WITH_PROFILER +uint8_t app_timer_op_queue_utilization_get(void) +{ + return m_max_user_op_queue_utilization; +} +#endif +#endif //NRF_MODULE_ENABLED(APP_TIMER) diff --git a/components/libraries/timer/app_timer.h b/components/libraries/timer/app_timer.h index 594cf63..856a2ad 100644 --- a/components/libraries/timer/app_timer.h +++ b/components/libraries/timer/app_timer.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -19,7 +47,7 @@ * @brief Application timer functionality. * * @details This module enables the application to create multiple timer instances based on the RTC1 - * peripheral. Checking for time-outs and invokation of user time-out handlers is performed + * peripheral. Checking for time-outs and invocation of user time-out handlers is performed * in the RTC1 interrupt handler. List handling is done using a software interrupt (SWI0). * Both interrupt handlers are running in APP_LOW priority level. * @@ -32,52 +60,56 @@ * the scheduler. * * @details Use the USE_SCHEDULER parameter of the APP_TIMER_INIT() macro to select if the - * @ref app_scheduler should be used or not. Even if the scheduler is + * @ref app_scheduler should be used or not. Even if the scheduler is * not used, app_timer.h will include app_scheduler.h, so when * compiling, app_scheduler.h must be available in one of the compiler include paths. */ #ifndef APP_TIMER_H__ #define APP_TIMER_H__ - -#include -#include -#include +#include "sdk_config.h" #include "app_error.h" #include "app_util.h" #include "compiler_abstraction.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif #define APP_TIMER_CLOCK_FREQ 32768 /**< Clock frequency of the RTC timer used to implement the app timer module. */ #define APP_TIMER_MIN_TIMEOUT_TICKS 5 /**< Minimum value of the timeout_ticks parameter of app_timer_start(). */ +#ifdef RTX +#define APP_TIMER_NODE_SIZE 40 /**< Size of app_timer.timer_node_t (used to allocate data). */ +#else #define APP_TIMER_NODE_SIZE 32 /**< Size of app_timer.timer_node_t (used to allocate data). */ +#endif // RTX #define APP_TIMER_USER_OP_SIZE 24 /**< Size of app_timer.timer_user_op_t (only for use inside APP_TIMER_BUF_SIZE()). */ -#define APP_TIMER_USER_SIZE 8 /**< Size of app_timer.timer_user_t (only for use inside APP_TIMER_BUF_SIZE()). */ -#define APP_TIMER_INT_LEVELS 3 /**< Number of interrupt levels from where timer operations may be initiated (only for use inside APP_TIMER_BUF_SIZE()). */ /**@brief Compute number of bytes required to hold the application timer data structures. * - * @param[in] OP_QUEUE_SIZE Size of queues holding timer operations that are pending execution. + * @param[in] OP_QUEUE_SIZE Size of the queue holding timer operations that are pending execution. * Note that due to the queue implementation, this size must be one more * than the size that is actually needed. * * @return Required application timer buffer size (in bytes). */ -#define APP_TIMER_BUF_SIZE(OP_QUEUE_SIZE) \ - ( \ - ( \ - APP_TIMER_INT_LEVELS \ - * \ - (APP_TIMER_USER_SIZE + ((OP_QUEUE_SIZE) + 1) * APP_TIMER_USER_OP_SIZE) \ - ) \ +#define APP_TIMER_BUF_SIZE(OP_QUEUE_SIZE) \ + ( \ + ( \ + (((OP_QUEUE_SIZE) + 1) * APP_TIMER_USER_OP_SIZE) \ + ) \ ) /**@brief Convert milliseconds to timer ticks. * * This macro uses 64-bit integer arithmetic, but as long as the macro parameters are * constants (i.e. defines), the computation will be done by the preprocessor. - * - * When using this macro, ensure that the + * + * When using this macro, ensure that the * values provided as input result in an output value that is supported by the * @ref app_timer_start function. For example, when the ticks for 1 ms is needed, the * maximum possible value of PRESCALER must be 6, when @ref APP_TIMER_CLOCK_FREQ is 32768. @@ -86,7 +118,7 @@ * * @param[in] MS Milliseconds. * @param[in] PRESCALER Value of the RTC1 PRESCALER register (must be the same value that was - * passed to APP_TIMER_INIT()). + * passed to APP_TIMER_INIT()). * * @return Number of timer ticks. */ @@ -129,32 +161,32 @@ typedef enum * making sure that the buffer is correctly aligned. It will also connect the timer module * to the scheduler (if specified). * - * @note This module assumes that the LFCLK is already running. If it is not, the module will - * be non-functional, since the RTC will not run. If you do not use a SoftDevice, you - * must start the LFCLK manually. See the rtc_example's lfclk_config() function - * for an example of how to do this. If you use a SoftDevice, the LFCLK is started on - * SoftDevice init. + * @note This module assumes that the LFCLK is already running. If it is not, the module will + * be non-functional, since the RTC will not run. If you do not use a SoftDevice, you + * must start the LFCLK manually. See the rtc_example's lfclk_config() function + * for an example of how to do this. If you use a SoftDevice, the LFCLK is started on + * SoftDevice init. * * * @param[in] PRESCALER Value of the RTC1 PRESCALER register. This will decide the * timer tick rate. Set to 0 for no prescaling. - * @param[in] OP_QUEUES_SIZE Size of queues holding timer operations that are pending execution. + * @param[in] OP_QUEUE_SIZE Size of the queue holding timer operations that are pending execution. * @param[in] SCHEDULER_FUNC Pointer to scheduler event handler * * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it * several times as long as it is from the same location, for example, to do a re-initialization). */ /*lint -emacro(506, APP_TIMER_INIT) */ /* Suppress "Constant value Boolean */ -#define APP_TIMER_INIT(PRESCALER, OP_QUEUES_SIZE, SCHEDULER_FUNC) \ - do \ - { \ - static uint32_t APP_TIMER_BUF[CEIL_DIV(APP_TIMER_BUF_SIZE((OP_QUEUES_SIZE) + 1), \ - sizeof(uint32_t))]; \ - uint32_t ERR_CODE = app_timer_init((PRESCALER), \ - (OP_QUEUES_SIZE) + 1, \ - APP_TIMER_BUF, \ - SCHEDULER_FUNC); \ - APP_ERROR_CHECK(ERR_CODE); \ +#define APP_TIMER_INIT(PRESCALER, OP_QUEUE_SIZE, SCHEDULER_FUNC) \ + do \ + { \ + static uint32_t APP_TIMER_BUF[CEIL_DIV(APP_TIMER_BUF_SIZE(OP_QUEUE_SIZE), \ + sizeof(uint32_t))]; \ + uint32_t ERR_CODE = app_timer_init((PRESCALER), \ + (OP_QUEUE_SIZE) + 1, \ + APP_TIMER_BUF, \ + SCHEDULER_FUNC); \ + APP_ERROR_CHECK(ERR_CODE); \ } while (0) @@ -166,7 +198,7 @@ typedef enum * and take care of connecting the timer module to the scheduler (if specified). * * @param[in] prescaler Value of the RTC1 PRESCALER register. Set to 0 for no prescaling. - * @param[in] op_queues_size Size of queues holding timer operations that are pending + * @param[in] op_queue_size Size of the queue holding timer operations that are pending * execution. Note that due to the queue implementation, this size must * be one more than the size that is actually needed. * @param[in] p_buffer Pointer to memory buffer for internal use in the app_timer @@ -182,8 +214,8 @@ typedef enum * @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid (buffer not aligned to a 4 byte * boundary or NULL). */ -uint32_t app_timer_init(uint32_t prescaler, - uint8_t op_queues_size, +uint32_t app_timer_init(uint32_t prescaler, + uint8_t op_queue_size, void * p_buffer, app_timer_evt_schedule_func_t evt_schedule_func); @@ -254,11 +286,9 @@ uint32_t app_timer_stop_all(void); /**@brief Function for returning the current value of the RTC1 counter. * - * @param[out] p_ticks Current value of the RTC1 counter. - * - * @retval NRF_SUCCESS If the counter was successfully read. + * @return Current value of the RTC1 counter. */ -uint32_t app_timer_cnt_get(uint32_t * p_ticks); +uint32_t app_timer_cnt_get(void); /**@brief Function for computing the difference between two RTC1 counter values. * @@ -272,6 +302,22 @@ uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to, uint32_t ticks_from, uint32_t * p_ticks_diff); + +/**@brief Function for getting the maximum observed operation queue utilization. + * + * Function for tuning the module and determining OP_QUEUE_SIZE value and thus module RAM usage. + * + * @note APP_TIMER_WITH_PROFILER must be enabled to use this functionality. + * + * @return Maximum number of events in queue observed so far. + */ +uint8_t app_timer_op_queue_utilization_get(void); + + +#ifdef __cplusplus +} +#endif + #endif // APP_TIMER_H__ /** @} */ diff --git a/components/libraries/timer/app_timer_appsh.c b/components/libraries/timer/app_timer_appsh.c index e4bf6ed..0afb053 100644 --- a/components/libraries/timer/app_timer_appsh.c +++ b/components/libraries/timer/app_timer_appsh.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "app_timer_appsh.h" @@ -16,7 +44,7 @@ static void app_timer_evt_get(void * p_event_data, uint16_t event_size) { app_timer_event_t * p_timer_event = (app_timer_event_t *)p_event_data; - + APP_ERROR_CHECK_BOOL(event_size == sizeof(app_timer_event_t)); p_timer_event->timeout_handler(p_timer_event->p_context); } @@ -28,7 +56,7 @@ uint32_t app_timer_evt_schedule(app_timer_timeout_handler_t timeout_handler, timer_event.timeout_handler = timeout_handler; timer_event.p_context = p_context; - + return app_sched_event_put(&timer_event, sizeof(timer_event), app_timer_evt_get); } diff --git a/components/libraries/timer/app_timer_appsh.h b/components/libraries/timer/app_timer_appsh.h index a75d70b..e82cfd5 100644 --- a/components/libraries/timer/app_timer_appsh.h +++ b/components/libraries/timer/app_timer_appsh.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_TIMER_APPSH_H @@ -15,6 +43,10 @@ #include "app_timer.h" +#ifdef __cplusplus +extern "C" { +#endif + #define APP_TIMER_SCHED_EVT_SIZE sizeof(app_timer_event_t) /**< Size of button events being passed through the scheduler (is to be used for computing the maximum size of scheduler events). */ /**@brief Macro for initializing the application timer module to use with app_scheduler. @@ -40,5 +72,10 @@ typedef struct uint32_t app_timer_evt_schedule(app_timer_timeout_handler_t timeout_handler, void * p_context); + +#ifdef __cplusplus +} +#endif + #endif // APP_TIMER_APPSH_H - + diff --git a/components/libraries/timer/app_timer_ble_gzll.c b/components/libraries/timer/app_timer_ble_gzll.c index 3f01859..fcf0335 100644 --- a/components/libraries/timer/app_timer_ble_gzll.c +++ b/components/libraries/timer/app_timer_ble_gzll.c @@ -1,26 +1,55 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_TIMER) #include "app_timer.h" #include #include "nrf.h" #include "nrf_soc.h" #include "app_error.h" #include "nrf_delay.h" -#include "app_util.h" #include "app_util_platform.h" -#define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOW /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */ -#define SWI_IRQ_PRI APP_IRQ_PRIORITY_LOW /**< Priority of the SWI interrupt (used for updating the timer list). */ +#define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOWEST /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */ +#define SWI_IRQ_PRI APP_IRQ_PRIORITY_LOWEST /**< Priority of the SWI interrupt (used for updating the timer list). */ // The current design assumes that both interrupt handlers run at the same interrupt level. // If this is to be changed, protection must be added to prevent them from interrupting each other @@ -29,21 +58,14 @@ STATIC_ASSERT(RTC1_IRQ_PRI == SWI_IRQ_PRI); #define MAX_RTC_COUNTER_VAL 0x00FFFFFF /**< Maximum value of the RTC counter. */ -#define APP_HIGH_USER_ID 0 /**< User Id for the Application High "user". */ -#define APP_LOW_USER_ID 1 /**< User Id for the Application Low "user". */ -#define THREAD_MODE_USER_ID 2 /**< User Id for the Thread Mode "user". */ - #define RTC_COMPARE_OFFSET_MIN 3 /**< Minimum offset between the current RTC counter value and the Capture Compare register. Although the nRF51 Series User Specification recommends this value to be 2, we use 3 to be safer.*/ #define MAX_RTC_TASKS_DELAY 47 /**< Maximum delay until an RTC task is executed. */ -#ifdef NRF51 #define SWI_IRQn SWI1_IRQn #define SWI_IRQHandler SWI1_IRQHandler -#elif defined NRF52 -#define SWI_IRQn SWI1_EGU1_IRQn -#define SWI_IRQHandler SWI1_EGU1_IRQHandler -#endif + +#define MODULE_INITIALIZED (m_op_queue.p_user_op_queue != NULL) /**< Macro designating whether the module has been initialized properly. */ /**@brief Timer node type. The nodes will be used form a linked list of running timers. */ typedef struct @@ -93,38 +115,24 @@ typedef struct STATIC_ASSERT(sizeof(timer_user_op_t) <= APP_TIMER_USER_OP_SIZE); STATIC_ASSERT(sizeof(timer_user_op_t) % 4 == 0); -/**@brief Structure describing a timer user. +/**@brief Structure describing a timer operations queue. * - * @details For each user of the timer module, there will be a timer operations queue. This queue - * will hold timer operations issued by this user until the timer interrupt handler - * processes these operations. For the current implementation, there will be one user for - * each interrupt level available to the application (APP_HIGH, APP_LOW and THREAD_MODE), - * but the module can easily be modified to e.g. have one queue per process when using an - * RTOS. The purpose of the queues is to be able to have a completely lockless timer - * implementation. + * @details This queue will hold timer operations issued by the application + * until the timer interrupt handler processes these operations. */ typedef struct { uint8_t first; /**< Index of first entry to have been inserted in the queue (i.e. the next entry to be executed). */ uint8_t last; /**< Index of last entry to have been inserted in the queue. */ - uint8_t user_op_queue_size; /**< Queue size. */ + uint8_t size; /**< Queue size. */ timer_user_op_t * p_user_op_queue; /**< Queue buffer. */ -} timer_user_t; +} timer_op_queue_t; -STATIC_ASSERT(sizeof(timer_user_t) == APP_TIMER_USER_SIZE); -STATIC_ASSERT(sizeof(timer_user_t) % 4 == 0); +STATIC_ASSERT(sizeof(timer_op_queue_t) % 4 == 0); -/**@brief User id type. - * - * @details In the current implementation, this will automatically be generated from the current - * interrupt level. - */ -typedef uint32_t timer_user_id_t; +#define CONTEXT_QUEUE_SIZE_MAX (2) -#define CONTEXT_QUEUE_SIZE_MAX (2) - -static uint8_t m_user_array_size; /**< Size of timer user array. */ -static timer_user_t * mp_users = NULL; /**< Array of timer users. */ +static timer_op_queue_t m_op_queue; /**< Timer operations queue. */ static timer_node_t * mp_timer_id_head; /**< First timer in list of running timers. */ static uint32_t m_ticks_latest; /**< Last known RTC counter value. */ static uint32_t m_ticks_elapsed[CONTEXT_QUEUE_SIZE_MAX]; /**< Timer internal elapsed ticks queue. */ @@ -133,7 +141,10 @@ static uint8_t m_ticks_elapsed_q_write_ind; static app_timer_evt_schedule_func_t m_evt_schedule_func; /**< Pointer to function for propagating timeout events to the scheduler. */ static bool m_rtc1_running; /**< Boolean indicating if RTC1 is running. */ static bool m_rtc1_reset; /**< Boolean indicating if RTC1 counter has been reset due to last timer removed from timer list during the timer list handling. */ - + +#if APP_TIMER_WITH_PROFILER +static uint8_t m_max_user_op_queue_utilization; /**< Maximum observed timer user operations queue utilization. */ +#endif /**@brief Function for initializing the RTC1 counter. * @@ -229,7 +240,7 @@ static void timer_list_insert(timer_node_t * p_timer) if (p_timer->ticks_to_expire <= mp_timer_id_head->ticks_to_expire) { mp_timer_id_head->ticks_to_expire -= p_timer->ticks_to_expire; - + p_timer->next = mp_timer_id_head; mp_timer_id_head = p_timer; } @@ -242,7 +253,7 @@ static void timer_list_insert(timer_node_t * p_timer) ticks_to_expire = p_timer->ticks_to_expire; p_previous = mp_timer_id_head; p_current = mp_timer_id_head; - + while ((p_current != NULL) && (ticks_to_expire > p_current->ticks_to_expire)) { ticks_to_expire -= p_current->ticks_to_expire; @@ -276,7 +287,7 @@ static void timer_list_remove(timer_node_t * p_timer) // Find the timer's position in timer list. p_previous = mp_timer_id_head; p_current = p_previous; - + while (p_current != NULL) { if (p_current == p_timer) @@ -361,7 +372,7 @@ static void timeout_handler_exec(timer_node_t * p_timer) */ static void timer_timeouts_check(void) { - // Handle expired of timer + // Handle expired of timer if (mp_timer_id_head != NULL) { timer_node_t * p_timer; @@ -396,7 +407,11 @@ static void timer_timeouts_check(void) p_timer = p_timer->next; // Execute Task. - timeout_handler_exec(p_previous_timer); + if (p_previous_timer->is_running) + { + p_previous_timer->is_running = false; + timeout_handler_exec(p_previous_timer); + } } // Prepare to queue the ticks expired in the m_ticks_elapsed queue. @@ -464,56 +479,43 @@ static bool elapsed_ticks_acquire(uint32_t * p_ticks_elapsed) static bool list_deletions_handler(void) { timer_node_t * p_timer_old_head; - uint8_t user_id; + uint8_t user_ops_first = m_op_queue.first; // Remember the old head, so as to decide if new compare needs to be set. p_timer_old_head = mp_timer_id_head; - user_id = m_user_array_size; - while (user_id--) + while (user_ops_first != m_op_queue.last) { - timer_user_t * p_user = &mp_users[user_id]; - uint8_t user_ops_first = p_user->first; - - while (user_ops_first != p_user->last) + timer_user_op_t * p_user_op = &m_op_queue.p_user_op_queue[user_ops_first]; + + // Traverse to next operation in queue. + user_ops_first++; + if (user_ops_first == m_op_queue.size) { - timer_node_t * p_timer; - timer_user_op_t * p_user_op = &p_user->p_user_op_queue[user_ops_first]; + user_ops_first = 0; + } - // Traverse to next operation in queue. - user_ops_first++; - if (user_ops_first == p_user->user_op_queue_size) - { - user_ops_first = 0; - } + switch (p_user_op->op_type) + { + case TIMER_USER_OP_TYPE_STOP: + // Delete node if timer is running. + timer_list_remove(p_user_op->p_node); + break; - switch (p_user_op->op_type) - { - case TIMER_USER_OP_TYPE_STOP: - // Delete node if timer is running. - p_timer = p_user_op->p_node; - if (p_timer->is_running) - { - timer_list_remove(p_user_op->p_node); - p_timer->is_running = false; - } - break; - - case TIMER_USER_OP_TYPE_STOP_ALL: - // Delete list of running timers, and mark all timers as not running. - while (mp_timer_id_head != NULL) - { - timer_node_t * p_head = mp_timer_id_head; - - p_head->is_running = false; - mp_timer_id_head = p_head->next; - } - break; - - default: - // No implementation needed. - break; - } + case TIMER_USER_OP_TYPE_STOP_ALL: + // Delete list of running timers, and mark all timers as not running. + while (mp_timer_id_head != NULL) + { + timer_node_t * p_head = mp_timer_id_head; + + p_head->is_running = false; + mp_timer_id_head = p_head->next; + } + break; + + default: + // No implementation needed. + break; } } @@ -542,7 +544,7 @@ static void expired_timers_handler(uint32_t ticks_elapsed, // Auto variable for current timer node. p_timer = mp_timer_id_head; - // Do nothing if timer did not expire + // Do nothing if timer did not expire if (ticks_elapsed < p_timer->ticks_to_expire) { p_timer->ticks_to_expire -= ticks_elapsed; @@ -555,7 +557,6 @@ static void expired_timers_handler(uint32_t ticks_elapsed, // Timer expired, set ticks_to_expire zero. p_timer->ticks_to_expire = 0; - p_timer->is_running = false; // Remove the expired timer from head. p_timer_expired = mp_timer_id_head; @@ -582,89 +583,82 @@ static void expired_timers_handler(uint32_t ticks_elapsed, static bool list_insertions_handler(timer_node_t * p_restart_list_head) { timer_node_t * p_timer_id_old_head; - uint8_t user_id; // Remember the old head, so as to decide if new compare needs to be set. p_timer_id_old_head = mp_timer_id_head; - user_id = m_user_array_size; - while (user_id--) + // Handle insertions of timers. + while ((p_restart_list_head != NULL) || (m_op_queue.first != m_op_queue.last)) { - timer_user_t * p_user = &mp_users[user_id]; + timer_node_t * p_timer; - // Handle insertions of timers. - while ((p_restart_list_head != NULL) || (p_user->first != p_user->last)) + if (p_restart_list_head != NULL) + { + p_timer = p_restart_list_head; + p_restart_list_head = p_timer->next; + } + else { - timer_node_t * p_timer; + timer_user_op_t * p_user_op = &m_op_queue.p_user_op_queue[m_op_queue.first]; - if (p_restart_list_head != NULL) + m_op_queue.first++; + if (m_op_queue.first == m_op_queue.size) { - p_timer = p_restart_list_head; - p_restart_list_head = p_timer->next; + m_op_queue.first = 0; } - else - { - timer_user_op_t * p_user_op = &p_user->p_user_op_queue[p_user->first]; - - p_user->first++; - if (p_user->first == p_user->user_op_queue_size) - { - p_user->first = 0; - } - p_timer = p_user_op->p_node; + p_timer = p_user_op->p_node; - if ((p_user_op->op_type != TIMER_USER_OP_TYPE_START) || p_timer->is_running) - { - continue; - } + if ((p_user_op->op_type != TIMER_USER_OP_TYPE_START) || p_timer->is_running) + { + continue; + } - p_timer->ticks_at_start = p_user_op->params.start.ticks_at_start; - p_timer->ticks_first_interval = p_user_op->params.start.ticks_first_interval; - p_timer->ticks_periodic_interval = p_user_op->params.start.ticks_periodic_interval; - p_timer->p_context = p_user_op->params.start.p_context; + p_timer->ticks_at_start = p_user_op->params.start.ticks_at_start; + p_timer->ticks_first_interval = p_user_op->params.start.ticks_first_interval; + p_timer->ticks_periodic_interval = p_user_op->params.start.ticks_periodic_interval; + p_timer->p_context = p_user_op->params.start.p_context; - if (m_rtc1_reset) - { - p_timer->ticks_at_start = 0; - } + if (m_rtc1_reset) + { + p_timer->ticks_at_start = 0; } + } - // Prepare the node to be inserted. - if ( - ((p_timer->ticks_at_start - m_ticks_latest) & MAX_RTC_COUNTER_VAL) - < - (MAX_RTC_COUNTER_VAL / 2) - ) + // Prepare the node to be inserted. + if ( + ((p_timer->ticks_at_start - m_ticks_latest) & MAX_RTC_COUNTER_VAL) + < + (MAX_RTC_COUNTER_VAL / 2) + ) + { + p_timer->ticks_to_expire = ticks_diff_get(p_timer->ticks_at_start, m_ticks_latest) + + p_timer->ticks_first_interval; + } + else + { + uint32_t delta_current_start; + + delta_current_start = ticks_diff_get(m_ticks_latest, p_timer->ticks_at_start); + if (p_timer->ticks_first_interval > delta_current_start) { - p_timer->ticks_to_expire = ticks_diff_get(p_timer->ticks_at_start, m_ticks_latest) + - p_timer->ticks_first_interval; + p_timer->ticks_to_expire = p_timer->ticks_first_interval - delta_current_start; } else { - uint32_t delta_current_start; - - delta_current_start = ticks_diff_get(m_ticks_latest, p_timer->ticks_at_start); - if (p_timer->ticks_first_interval > delta_current_start) - { - p_timer->ticks_to_expire = p_timer->ticks_first_interval - delta_current_start; - } - else - { - p_timer->ticks_to_expire = 0; - } + p_timer->ticks_to_expire = 0; } + } - p_timer->ticks_at_start = 0; - p_timer->ticks_first_interval = 0; - p_timer->is_running = true; - p_timer->next = NULL; + p_timer->ticks_at_start = 0; + p_timer->ticks_first_interval = 0; + p_timer->is_running = true; + p_timer->next = NULL; - // Insert into list - timer_list_insert(p_timer); - } + // Insert into list + timer_list_insert(p_timer); } - + return (mp_timer_id_head != p_timer_id_old_head); } @@ -673,7 +667,7 @@ static bool list_insertions_handler(timer_node_t * p_restart_list_head) */ static void compare_reg_update(timer_node_t * p_timer_id_head_old) { - // Setup the timeout for timers on the head of the list + // Setup the timeout for timers on the head of the list if (mp_timer_id_head != NULL) { uint32_t ticks_to_expire = mp_timer_id_head->ticks_to_expire; @@ -689,7 +683,7 @@ static void compare_reg_update(timer_node_t * p_timer_id_head_old) cc += (ticks_elapsed < ticks_to_expire) ? ticks_to_expire : ticks_elapsed; cc &= MAX_RTC_COUNTER_VAL; - + rtc1_compare0_set(cc); uint32_t post_counter_val = rtc1_counter_get(); @@ -702,16 +696,20 @@ static void compare_reg_update(timer_node_t * p_timer_id_head_old) { // When this happens the COMPARE event may not be triggered by the RTC. // The nRF51 Series User Specification states that if the COUNTER value is N - // (i.e post_counter_val = N), writing N or N+1 to a CC register may not trigger a + // (i.e post_counter_val = N), writing N or N + 1 to a CC register may not trigger a // COMPARE event. Hence the RTC interrupt is forcefully pended by calling the following // function. + rtc1_compare0_set(rtc1_counter_get()); // this should prevent CC to fire again in the background while the code is in RTC-ISR + nrf_delay_us(MAX_RTC_TASKS_DELAY); timer_timeouts_check_sched(); } } else { +#if (APP_TIMER_KEEPS_RTC_ACTIVE == 0) // No timers are running, stop RTC rtc1_stop(); +#endif //(APP_TIMER_KEEPS_RTC_ACTIVE == 0) } } @@ -727,24 +725,38 @@ static void timer_list_handler(void) bool ticks_have_elapsed; bool compare_update; timer_node_t * p_timer_id_head_old; - + +#if APP_TIMER_WITH_PROFILER + { + uint8_t size = m_op_queue.size; + uint8_t first = m_op_queue.first; + uint8_t last = m_op_queue.last; + uint8_t utilization = (first <= last) ? (last - first) : (size + 1 - first + last); + + if (utilization > m_max_user_op_queue_utilization) + { + m_max_user_op_queue_utilization = utilization; + } + } +#endif + // Back up the previous known tick and previous list head ticks_previous = m_ticks_latest; p_timer_id_head_old = mp_timer_id_head; - + // Get number of elapsed ticks ticks_have_elapsed = elapsed_ticks_acquire(&ticks_elapsed); // Handle list deletions compare_update = list_deletions_handler(); - + // Handle expired timers if (ticks_have_elapsed) { expired_timers_handler(ticks_elapsed, ticks_previous, &p_restart_list_head); compare_update = true; } - + // Handle list insertions if (list_insertions_handler(p_restart_list_head)) { @@ -762,49 +774,46 @@ static void timer_list_handler(void) /**@brief Function for enqueueing a new operations queue entry. * - * @param[in] p_user User that the entry is to be enqueued for. * @param[in] last_index Index of the next last index to be enqueued. */ -static void user_op_enque(timer_user_t * p_user, uint8_t last_index) +static void user_op_enque(uint8_t last_index) { - p_user->last = last_index; + m_op_queue.last = last_index; } /**@brief Function for allocating a new operations queue entry. * - * @param[in] p_user User that the entry is to be allocated for. * @param[out] p_last_index Index of the next last index to be enqueued. * * @return Pointer to allocated queue entry, or NULL if queue is full. */ -static timer_user_op_t * user_op_alloc(timer_user_t * p_user, uint8_t * p_last_index) -{ +static timer_user_op_t * user_op_alloc( uint8_t * p_last_index) +{ uint8_t last; timer_user_op_t * p_user_op; - - last = p_user->last + 1; - if (last == p_user->user_op_queue_size) + + last = m_op_queue.last + 1; + if (last == m_op_queue.size) { // Overflow case. last = 0; } - if (last == p_user->first) + if (last == m_op_queue.first) { // Queue is full. return NULL; } - - *p_last_index = last; - p_user_op = &p_user->p_user_op_queue[p_user->last]; - + + *p_last_index = last; + p_user_op = &m_op_queue.p_user_op_queue[m_op_queue.last]; + return p_user_op; } /**@brief Function for scheduling a Timer Start operation. * - * @param[in] user_id Id of user calling this function. * @param[in] timer_id Id of timer to start. * @param[in] timeout_initial Time (in ticks) to first timer expiry. * @param[in] timeout_periodic Time (in ticks) between periodic expiries. @@ -812,89 +821,81 @@ static timer_user_op_t * user_op_alloc(timer_user_t * p_user, uint8_t * p_last_i * the timer expires. * @return NRF_SUCCESS on success, otherwise an error code. */ -static uint32_t timer_start_op_schedule(timer_user_id_t user_id, - timer_node_t * p_node, + +static uint32_t timer_start_op_schedule(timer_node_t * p_node, uint32_t timeout_initial, uint32_t timeout_periodic, void * p_context) { uint8_t last_index; - - timer_user_op_t * p_user_op = user_op_alloc(&mp_users[user_id], &last_index); + uint32_t err_code = NRF_SUCCESS; + + CRITICAL_REGION_ENTER(); + timer_user_op_t * p_user_op = user_op_alloc(&last_index); if (p_user_op == NULL) { - return NRF_ERROR_NO_MEM; + err_code = NRF_ERROR_NO_MEM; + } + else + { + + p_user_op->op_type = TIMER_USER_OP_TYPE_START; + p_user_op->p_node = p_node; + p_user_op->params.start.ticks_at_start = rtc1_counter_get(); + p_user_op->params.start.ticks_first_interval = timeout_initial; + p_user_op->params.start.ticks_periodic_interval = timeout_periodic; + p_user_op->params.start.p_context = p_context; + + user_op_enque(last_index); } - - p_user_op->op_type = TIMER_USER_OP_TYPE_START; - p_user_op->p_node = p_node; - p_user_op->params.start.ticks_at_start = rtc1_counter_get(); - p_user_op->params.start.ticks_first_interval = timeout_initial; - p_user_op->params.start.ticks_periodic_interval = timeout_periodic; - p_user_op->params.start.p_context = p_context; - - user_op_enque(&mp_users[user_id], last_index); - - timer_list_handler_sched(); + CRITICAL_REGION_EXIT(); - return NRF_SUCCESS; + if (err_code == NRF_SUCCESS) + { + timer_list_handler_sched(); + } + + return err_code; } /**@brief Function for scheduling a Timer Stop operation. * - * @param[in] user_id Id of user calling this function. * @param[in] timer_id Id of timer to stop. + * @param[in] op_type Type of stop operation * * @return NRF_SUCCESS on successful scheduling a timer stop operation. NRF_ERROR_NO_MEM when there * is no memory left to schedule the timer stop operation. */ -static uint32_t timer_stop_op_schedule(timer_user_id_t user_id, timer_node_t * p_node) +static uint32_t timer_stop_op_schedule(timer_node_t * p_node, + timer_user_op_type_t op_type) { uint8_t last_index; - - timer_user_op_t * p_user_op = user_op_alloc(&mp_users[user_id], &last_index); + uint32_t err_code = NRF_SUCCESS; + + CRITICAL_REGION_ENTER(); + timer_user_op_t * p_user_op = user_op_alloc(&last_index); if (p_user_op == NULL) { - return NRF_ERROR_NO_MEM; + err_code = NRF_ERROR_NO_MEM; } - - p_user_op->op_type = TIMER_USER_OP_TYPE_STOP; - p_user_op->p_node = p_node; - - user_op_enque(&mp_users[user_id], last_index); - - timer_list_handler_sched(); - - return NRF_SUCCESS; -} + else + { + p_user_op->op_type = op_type; + p_user_op->p_node = p_node; + user_op_enque(last_index); + } + CRITICAL_REGION_EXIT(); -/**@brief Function for scheduling a Timer Stop All operation. - * - * @param[in] user_id Id of user calling this function. - */ -static uint32_t timer_stop_all_op_schedule(timer_user_id_t user_id) -{ - uint8_t last_index; - - timer_user_op_t * p_user_op = user_op_alloc(&mp_users[user_id], &last_index); - if (p_user_op == NULL) + if (err_code == NRF_SUCCESS) { - return NRF_ERROR_NO_MEM; + timer_list_handler_sched(); } - - p_user_op->op_type = TIMER_USER_OP_TYPE_STOP_ALL; - p_user_op->p_node = NULL; - - user_op_enque(&mp_users[user_id], last_index); - timer_list_handler_sched(); - - return NRF_SUCCESS; + return err_code; } - /**@brief Function for handling the RTC1 interrupt. * * @details Checks for timeouts, and executes timeout handlers for expired timers. @@ -925,12 +926,10 @@ void SWI_IRQHandler(void) uint32_t app_timer_init(uint32_t prescaler, - uint8_t op_queues_size, + uint8_t op_queue_size, void * p_buffer, app_timer_evt_schedule_func_t evt_schedule_func) { - int i; - // Check that buffer is correctly aligned if (!is_word_aligned(p_buffer)) { @@ -939,40 +938,28 @@ uint32_t app_timer_init(uint32_t prescaler, // Check for NULL buffer if (p_buffer == NULL) { - mp_users = NULL; return NRF_ERROR_INVALID_PARAM; } - + // Stop RTC to prevent any running timers from expiring (in case of reinitialization) rtc1_stop(); - + m_evt_schedule_func = evt_schedule_func; - - // Initialize users array - m_user_array_size = APP_TIMER_INT_LEVELS; - mp_users = p_buffer; - - // Skip user array - p_buffer = &((uint8_t *)p_buffer)[APP_TIMER_INT_LEVELS * sizeof(timer_user_t)]; - - // Initialize operation queues - for (i = 0; i < APP_TIMER_INT_LEVELS; i++) - { - timer_user_t * p_user = &mp_users[i]; - - p_user->first = 0; - p_user->last = 0; - p_user->user_op_queue_size = op_queues_size; - p_user->p_user_op_queue = p_buffer; - - // Skip operation queue - p_buffer = &((uint8_t *)p_buffer)[op_queues_size * sizeof(timer_user_op_t)]; - } - mp_timer_id_head = NULL; + // Initialize operation queue + m_op_queue.first = 0; + m_op_queue.last = 0; + m_op_queue.size = op_queue_size; + m_op_queue.p_user_op_queue = p_buffer; + + mp_timer_id_head = NULL; m_ticks_elapsed_q_read_ind = 0; m_ticks_elapsed_q_write_ind = 0; +#if APP_TIMER_WITH_PROFILER + m_max_user_op_queue_utilization = 0; +#endif + NVIC_ClearPendingIRQ(SWI_IRQn); NVIC_SetPriority(SWI_IRQn, SWI_IRQ_PRI); NVIC_EnableIRQ(SWI_IRQn); @@ -980,7 +967,7 @@ uint32_t app_timer_init(uint32_t prescaler, rtc1_init(prescaler); m_ticks_latest = rtc1_counter_get(); - + return NRF_SUCCESS; } @@ -990,10 +977,8 @@ uint32_t app_timer_create(app_timer_id_t const * p_timer_id, app_timer_timeout_handler_t timeout_handler) { // Check state and parameters - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } + VERIFY_MODULE_INITIALIZED(); + if (timeout_handler == NULL) { return NRF_ERROR_INVALID_PARAM; @@ -1006,7 +991,7 @@ uint32_t app_timer_create(app_timer_id_t const * p_timer_id, { return NRF_ERROR_INVALID_STATE; } - + timer_node_t * p_node = (timer_node_t *)*p_timer_id; p_node->is_running = false; p_node->mode = mode; @@ -1014,46 +999,14 @@ uint32_t app_timer_create(app_timer_id_t const * p_timer_id, return NRF_SUCCESS; } - -/**@brief Function for creating a timer user id from the current interrupt level. - * - * @return Timer user id. -*/ -static timer_user_id_t user_id_get(void) -{ - timer_user_id_t ret; - - STATIC_ASSERT(APP_TIMER_INT_LEVELS == 3); - - switch (current_int_priority_get()) - { - case APP_IRQ_PRIORITY_HIGH: - ret = APP_HIGH_USER_ID; - break; - - case APP_IRQ_PRIORITY_LOW: - ret = APP_LOW_USER_ID; - break; - - default: - ret = THREAD_MODE_USER_ID; - break; - } - - return ret; -} - - uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context) { uint32_t timeout_periodic; timer_node_t * p_node = (timer_node_t*)timer_id; - + // Check state and parameters - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } + VERIFY_MODULE_INITIALIZED(); + if (timer_id == 0) { return NRF_ERROR_INVALID_STATE; @@ -1066,12 +1019,11 @@ uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * { return NRF_ERROR_INVALID_STATE; } - + // Schedule timer start operation timeout_periodic = (p_node->mode == APP_TIMER_MODE_REPEATED) ? timeout_ticks : 0; - return timer_start_op_schedule(user_id_get(), - p_node, + return timer_start_op_schedule(p_node, timeout_ticks, timeout_periodic, p_context); @@ -1082,35 +1034,31 @@ uint32_t app_timer_stop(app_timer_id_t timer_id) { timer_node_t * p_node = (timer_node_t*)timer_id; // Check state and parameters - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } + VERIFY_MODULE_INITIALIZED(); + if ((timer_id == NULL) || (p_node->p_timeout_handler == NULL)) { return NRF_ERROR_INVALID_STATE; } - + + p_node->is_running = false; // Schedule timer stop operation - return timer_stop_op_schedule(user_id_get(), p_node); + return timer_stop_op_schedule(p_node, TIMER_USER_OP_TYPE_STOP); } uint32_t app_timer_stop_all(void) { // Check state - if (mp_users == NULL) - { - return NRF_ERROR_INVALID_STATE; - } - return timer_stop_all_op_schedule(user_id_get()); + VERIFY_MODULE_INITIALIZED(); + + return timer_stop_op_schedule(NULL, TIMER_USER_OP_TYPE_STOP_ALL); } -uint32_t app_timer_cnt_get(uint32_t * p_ticks) +uint32_t app_timer_cnt_get(void) { - *p_ticks = rtc1_counter_get(); - return NRF_SUCCESS; + return rtc1_counter_get(); } @@ -1122,3 +1070,10 @@ uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to, return NRF_SUCCESS; } +#if APP_TIMER_WITH_PROFILER +uint8_t app_timer_op_queue_utilization_get(void) +{ + return m_max_user_op_queue_utilization; +} +#endif +#endif //NRF_MODULE_ENABLED(APP_TIMER) diff --git a/components/libraries/timer/app_timer_freertos.c b/components/libraries/timer/app_timer_freertos.c index 78e4645..2de2075 100644 --- a/components/libraries/timer/app_timer_freertos.c +++ b/components/libraries/timer/app_timer_freertos.c @@ -1,15 +1,44 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_TIMER) #include "FreeRTOS.h" #include "task.h" #include "timers.h" @@ -19,8 +48,6 @@ #include #include "nrf.h" #include "app_error.h" -#include "app_util.h" -#include "nordic_common.h" /* Check if RTC FreeRTOS version is used */ #if configTICK_SOURCE != FREERTOS_USE_RTC @@ -83,7 +110,7 @@ static void app_timer_callback(TimerHandle_t xTimer) ASSERT(pinfo->osHandle == xTimer); ASSERT(pinfo->func != NULL); - if(pinfo->active) + if (pinfo->active) pinfo->func(pinfo->argument); } @@ -111,21 +138,21 @@ uint32_t app_timer_create(app_timer_id_t const * p_timer_id, uint32_t err_code = NRF_SUCCESS; unsigned long timer_mode; - if((timeout_handler == NULL) || (p_timer_id == NULL)) + if ((timeout_handler == NULL) || (p_timer_id == NULL)) { return NRF_ERROR_INVALID_PARAM; } - if(pinfo->active) + if (pinfo->active) { return NRF_ERROR_INVALID_STATE; } - if(pinfo->osHandle == NULL) + if (pinfo->osHandle == NULL) { /* New timer is created */ - memset(pinfo, 0, sizeof(pinfo)); + memset(pinfo, 0, sizeof(app_timer_info_t)); - if(mode == APP_TIMER_MODE_SINGLE_SHOT) + if (mode == APP_TIMER_MODE_SINGLE_SHOT) timer_mode = pdFALSE; else timer_mode = pdTRUE; @@ -133,7 +160,7 @@ uint32_t app_timer_create(app_timer_id_t const * p_timer_id, pinfo->func = timeout_handler; pinfo->osHandle = xTimerCreate(" ", 1000, timer_mode, pinfo, app_timer_callback); - if(pinfo->osHandle == NULL) + if (pinfo->osHandle == NULL) err_code = NRF_ERROR_NULL; } else @@ -152,13 +179,13 @@ uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * TimerHandle_t hTimer = pinfo->osHandle; uint32_t rtc_prescaler = portNRF_RTC_REG->PRESCALER + 1; /* Get back the microseconds to wait */ - uint32_t timeout_corrected = ROUNDED_DIV(timeout_ticks*m_prescaler, rtc_prescaler); + uint32_t timeout_corrected = ROUNDED_DIV(timeout_ticks * m_prescaler, rtc_prescaler); - if(hTimer == NULL) + if (hTimer == NULL) { return NRF_ERROR_INVALID_STATE; } - if(pinfo->active && (xTimerIsTimerActive(hTimer) != pdFALSE)) + if (pinfo->active && (xTimerIsTimerActive(hTimer) != pdFALSE)) { // Timer already running - exit silently return NRF_SUCCESS; @@ -166,15 +193,15 @@ uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * pinfo->argument = p_context; - if(__get_IPSR() != 0) + if (__get_IPSR() != 0) { BaseType_t yieldReq = pdFALSE; - if(xTimerChangePeriodFromISR(hTimer, timeout_corrected, &yieldReq) != pdPASS) + if (xTimerChangePeriodFromISR(hTimer, timeout_corrected, &yieldReq) != pdPASS) { return NRF_ERROR_NO_MEM; } - if( xTimerStartFromISR(hTimer, &yieldReq) != pdPASS ) + if ( xTimerStartFromISR(hTimer, &yieldReq) != pdPASS ) { return NRF_ERROR_NO_MEM; } @@ -183,12 +210,12 @@ uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * } else { - if(xTimerChangePeriod(hTimer, timeout_corrected, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS) + if (xTimerChangePeriod(hTimer, timeout_corrected, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS) { return NRF_ERROR_NO_MEM; } - if(xTimerStart(hTimer, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS) + if (xTimerStart(hTimer, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS) { return NRF_ERROR_NO_MEM; } @@ -203,15 +230,15 @@ uint32_t app_timer_stop(app_timer_id_t timer_id) { app_timer_info_t * pinfo = (app_timer_info_t*)(timer_id); TimerHandle_t hTimer = pinfo->osHandle; - if(hTimer == NULL) + if (hTimer == NULL) { return NRF_ERROR_INVALID_STATE; } - if(__get_IPSR() != 0) + if (__get_IPSR() != 0) { BaseType_t yieldReq = pdFALSE; - if(xTimerStopFromISR(timer_id, &yieldReq) != pdPASS) + if (xTimerStopFromISR(timer_id, &yieldReq) != pdPASS) { return NRF_ERROR_NO_MEM; } @@ -219,7 +246,7 @@ uint32_t app_timer_stop(app_timer_id_t timer_id) } else { - if(xTimerStop(timer_id, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS) + if (xTimerStop(timer_id, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS) { return NRF_ERROR_NO_MEM; } @@ -228,3 +255,4 @@ uint32_t app_timer_stop(app_timer_id_t timer_id) pinfo->active = false; return NRF_SUCCESS; } +#endif //NRF_MODULE_ENABLED(APP_TIMER) diff --git a/components/libraries/timer/app_timer_rtx.c b/components/libraries/timer/app_timer_rtx.c index 1c01708..2ce209d 100644 --- a/components/libraries/timer/app_timer_rtx.c +++ b/components/libraries/timer/app_timer_rtx.c @@ -1,10 +1,54 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_TIMER) #include "app_timer.h" #include #include "nrf.h" #include "nrf_soc.h" #include "app_error.h" -#include "app_util.h" #include "cmsis_os.h" +#include "app_util_platform.h" + +#define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOWEST /**< Priority of the RTC1 interrupt. */ #define MAX_RTC_COUNTER_VAL 0x00FFFFFF /**< Maximum value of the RTC counter. */ @@ -12,30 +56,30 @@ typedef struct { osTimerDef_t timerDef; - uint32_t buffer[5]; + uint32_t buffer[6]; osTimerId id; }app_timer_info_t; /**@brief Store an array of timers with configuration. */ typedef struct { - uint8_t max_timers; /**< The maximum number of timers*/ - uint32_t prescaler; - app_timer_info_t * app_timers; /**< Pointer to table of timers*/ + uint8_t max_timers; /**< The maximum number of timers*/ + uint32_t prescaler; + app_timer_info_t * app_timers; /**< Pointer to table of timers*/ }app_timer_control_t; -app_timer_control_t app_timer_control; +app_timer_control_t app_timer_control; /**@brief This structure is defined by RTX. It keeps information about created osTimers. It is used in app_timer_start(). */ -typedef struct os_timer_cb_ -{ - struct os_timer_cb_ * next; - uint8_t state; - uint8_t type; - uint16_t reserved; - uint16_t tcnt; - uint16_t icnt; - void * arg; - const osTimerDef_t * timer; +typedef struct os_timer_cb_ +{ + struct os_timer_cb_ * next; /**< Pointer to next active Timer */ + uint8_t state; /**< Timer State */ + uint8_t type; /**< Timer Type (Periodic/One-shot). */ + uint16_t reserved; /**< Reserved. */ + uint32_t tcnt; /**< Timer Delay Count. */ + uint32_t icnt; /**< Timer Initial Count. */ + void * arg; /**< Timer Function Argument. */ + const osTimerDef_t * timer; /**< Pointer to Timer definition. */ } os_timer_cb; /**@brief This functions are defined by RTX.*/ @@ -43,21 +87,26 @@ typedef struct os_timer_cb_ extern osStatus svcTimerStop(osTimerId timer_id); /**< Used in app_timer_stop(). */ extern osStatus svcTimerStart(osTimerId timer_id, uint32_t millisec); /**< Used in app_timer_start(). */ // lint --restore -static void * rt_id2obj(void *id) /**< Used in app_timer_start(). This function gives information if osTimerID is valid */ +static void * rt_id2obj (void *id) /**< Used in app_timer_start(). This function gives information if osTimerID is valid */ { - - if ((uint32_t)id & 3) - return NULL; + if ((uint32_t)id & 3U) + { + return NULL; + } #ifdef OS_SECTIONS_LINK_INFO - - if ((os_section_id$$Base != 0) && (os_section_id$$Limit != 0)) + + if ((os_section_id$$Base != 0U) && (os_section_id$$Limit != 0U)) { - if (id < (void *)os_section_id$$Base) - return NULL; - - if (id >= (void *)os_section_id$$Limit) - return NULL; + if (id < (void *)os_section_id$$Base) + { + return NULL; + } + + if (id >= (void *)os_section_id$$Limit) + { + return NULL; + } } #endif @@ -65,6 +114,7 @@ static void * rt_id2obj(void *id) /**< U } + uint32_t app_timer_init(uint32_t prescaler, uint8_t op_queues_size, void * p_buffer, @@ -77,6 +127,7 @@ uint32_t app_timer_init(uint32_t prescaler, app_timer_control.prescaler = prescaler; app_timer_control.app_timers = p_buffer; + NVIC_SetPriority(RTC1_IRQn, RTC1_IRQ_PRI); return NRF_SUCCESS; } @@ -217,10 +268,9 @@ uint32_t app_timer_stop_all(void) extern uint32_t os_tick_val(void); -uint32_t app_timer_cnt_get(uint32_t * p_ticks) +uint32_t app_timer_cnt_get(void) { - *p_ticks = os_tick_val(); - return NRF_SUCCESS; + return os_tick_val(); } @@ -231,5 +281,4 @@ uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to, *p_ticks_diff = ((ticks_to - ticks_from) & MAX_RTC_COUNTER_VAL); return NRF_SUCCESS; } - - +#endif //NRF_MODULE_ENABLED(APP_TIMER) diff --git a/components/libraries/trace/app_trace.c b/components/libraries/trace/app_trace.c deleted file mode 100644 index 2ca3a1f..0000000 --- a/components/libraries/trace/app_trace.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include -#include -#include - - -#ifdef ENABLE_DEBUG_LOG_SUPPORT -#include "app_uart.h" -#include "nordic_common.h" -#include "boards.h" -#include "app_trace.h" -#include "app_error.h" - -#ifndef UART_TX_BUF_SIZE - #define UART_TX_BUF_SIZE 1024 /**< UART TX buffer size. */ -#endif -#ifndef UART_RX_BUF_SIZE - #define UART_RX_BUF_SIZE 1 /**< UART RX buffer size. */ -#endif -__WEAK void uart_error_handle(app_uart_evt_t * p_event) -{ - if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR) - { - //Skipping communication errors, they are only for Rx and app_trace is Tx only. - //APP_ERROR_HANDLER(p_event->data.error_communication); - } - else if (p_event->evt_type == APP_UART_FIFO_ERROR) - { - APP_ERROR_HANDLER(p_event->data.error_code); - } -} - -void app_trace_init(void) -{ - uint32_t err_code = NRF_SUCCESS; - const app_uart_comm_params_t comm_params = - { - RX_PIN_NUMBER, - TX_PIN_NUMBER, - RTS_PIN_NUMBER, - CTS_PIN_NUMBER, - APP_UART_FLOW_CONTROL_DISABLED, - false, - UART_BAUDRATE_BAUDRATE_Baud38400 - }; - - APP_UART_FIFO_INIT(&comm_params, - UART_RX_BUF_SIZE, - UART_TX_BUF_SIZE, - uart_error_handle, - APP_IRQ_PRIORITY_LOW, - err_code); - UNUSED_VARIABLE(err_code); -} - -void app_trace_dump(uint8_t * p_buffer, uint32_t len) -{ - app_trace_log("\r\n"); - for (uint32_t index = 0; index < len; index++) - { - app_trace_log("0x%02X ", p_buffer[index]); - } - app_trace_log("\r\n"); -} - -#endif // ENABLE_DEBUG_LOG_SUPPORT - -/** - *@} - **/ - diff --git a/components/libraries/trace/app_trace.h b/components/libraries/trace/app_trace.h deleted file mode 100644 index d138a42..0000000 --- a/components/libraries/trace/app_trace.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __DEBUG_H_ -#define __DEBUG_H_ - -#include -#include - -/** - * @defgroup app_trace Debug Logger - * @ingroup app_common - * @{ - * @brief Enables debug logs/ trace over UART. - * @details Enables debug logs/ trace over UART. Tracing is enabled only if - * ENABLE_DEBUG_LOG_SUPPORT is defined in the project. - */ -#ifdef ENABLE_DEBUG_LOG_SUPPORT -/** - * @brief Module Initialization. - * - * @details Initializes the module to use UART as trace output. - * - * @warning This function will configure UART using default board configuration. - * Do not call this function if UART is configured from a higher level in the application. - */ -void app_trace_init(void); - -/** - * @brief Log debug messages. - * - * @details This API logs messages over UART. The module must be initialized before using this API. - * - * @note Though this is currently a macro, it should be used used and treated as function. - */ -#define app_trace_log printf - -/** - * @brief Dump auxiliary byte buffer to the debug trace. - * - * @details This API logs messages over UART. The module must be initialized before using this API. - * - * @param[in] p_buffer Buffer to be dumped on the debug trace. - * @param[in] len Size of the buffer. - */ -void app_trace_dump(uint8_t * p_buffer, uint32_t len); - -#else // ENABLE_DEBUG_LOG_SUPPORT - -#define app_trace_init(...) -#define app_trace_log(...) -#define app_trace_dump(...) - -#endif // ENABLE_DEBUG_LOG_SUPPORT - -/** @} */ - -#endif //__DEBUG_H_ diff --git a/components/libraries/twi/app_twi.c b/components/libraries/twi/app_twi.c index 5662bfa..0c3f97c 100644 --- a/components/libraries/twi/app_twi.c +++ b/components/libraries/twi/app_twi.c @@ -1,16 +1,44 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - -#include +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_TWI) #include "app_twi.h" #include "nrf_assert.h" #include "app_util_platform.h" @@ -34,7 +62,7 @@ static bool queue_put(app_twi_queue_t * p_queue, // If the queue is already full, we cannot put any more elements into it. if ((write_idx == p_queue->size && p_queue->read_idx == 0) || - write_idx == p_queue->read_idx-1) + write_idx == p_queue->read_idx - 1) { return false; } @@ -71,7 +99,7 @@ static app_twi_transaction_t const * queue_get(app_twi_queue_t * p_queue) } -static ret_code_t start_transfer(app_twi_t const * p_app_twi) +static ret_code_t start_transfer(app_twi_t * p_app_twi) { ASSERT(p_app_twi != NULL); @@ -82,18 +110,45 @@ static ret_code_t start_transfer(app_twi_t const * p_app_twi) &p_app_twi->p_current_transaction->p_transfers[current_transfer_idx]; uint8_t address = APP_TWI_OP_ADDRESS(p_transfer->operation); - if (APP_TWI_IS_READ_OP(p_transfer->operation)) + nrf_drv_twi_xfer_desc_t xfer_desc; + uint32_t flags; + + xfer_desc.address = address; + xfer_desc.p_primary_buf = p_transfer->p_data; + xfer_desc.primary_length = p_transfer->length; + + /* If it is possible try to bind two transfers together. They can be combined if: + * - there is no stop condition after current transfer. + * - current transfer is TX. + * - there is at least one more transfer in the transaction. + * - address of next trnasfer is the same as current transfer. + */ + if ((p_transfer->flags & APP_TWI_NO_STOP) && + !APP_TWI_IS_READ_OP(p_transfer->operation) && + ((current_transfer_idx + 1) < p_app_twi->p_current_transaction->number_of_transfers) && + APP_TWI_OP_ADDRESS(p_transfer->operation) == + APP_TWI_OP_ADDRESS(p_app_twi->p_current_transaction->p_transfers[current_transfer_idx + 1].operation) + ) { - return nrf_drv_twi_rx(&p_app_twi->twi, address, - p_transfer->p_data, p_transfer->length, - (p_transfer->flags & APP_TWI_NO_STOP)); + app_twi_transfer_t const * p_second_transfer = + &p_app_twi->p_current_transaction->p_transfers[current_transfer_idx + 1]; + xfer_desc.p_secondary_buf = p_second_transfer->p_data; + xfer_desc.secondary_length = p_second_transfer->length; + xfer_desc.type = APP_TWI_IS_READ_OP(p_second_transfer->operation) ? NRF_DRV_TWI_XFER_TXRX : + NRF_DRV_TWI_XFER_TXTX; + flags = (p_second_transfer->flags & APP_TWI_NO_STOP) ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0; + p_app_twi->current_transfer_idx++; } else { - return nrf_drv_twi_tx(&p_app_twi->twi, address, - p_transfer->p_data, p_transfer->length, - (p_transfer->flags & APP_TWI_NO_STOP)); + xfer_desc.type = APP_TWI_IS_READ_OP(p_transfer->operation) ? NRF_DRV_TWI_XFER_RX : + NRF_DRV_TWI_XFER_TX; + xfer_desc.p_secondary_buf = NULL; + xfer_desc.secondary_length = 0; + flags = (p_transfer->flags & APP_TWI_NO_STOP) ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0; } + + return nrf_drv_twi_xfer(&p_app_twi->twi, &xfer_desc, flags); } @@ -177,7 +232,7 @@ static void twi_event_handler(nrf_drv_twi_evt_t const * p_event, // This callback should be called only during transaction. ASSERT(p_app_twi->p_current_transaction != NULL); - if (p_event->type != NRF_DRV_TWI_ERROR) + if (p_event->type == NRF_DRV_TWI_EVT_DONE) { result = NRF_SUCCESS; @@ -235,10 +290,8 @@ ret_code_t app_twi_init(app_twi_t * p_app_twi, p_twi_config, twi_event_handler, p_app_twi); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); + nrf_drv_twi_enable(&p_app_twi->twi); p_app_twi->queue.p_buffer = p_queue_buffer; @@ -336,10 +389,7 @@ ret_code_t app_twi_perform(app_twi_t * p_app_twi, .number_of_transfers = number_of_transfers, }; ret_code_t result = app_twi_schedule(p_app_twi, &internal_transaction); - if (result != NRF_SUCCESS) - { - return result; - } + VERIFY_SUCCESS(result); while (p_app_twi->internal_transaction_in_progress) { @@ -352,3 +402,4 @@ ret_code_t app_twi_perform(app_twi_t * p_app_twi, return p_app_twi->internal_transaction_result; } } +#endif //NRF_MODULE_ENABLED(APP_TWI) diff --git a/components/libraries/twi/app_twi.h b/components/libraries/twi/app_twi.h index f21e2b9..6e1f99f 100644 --- a/components/libraries/twi/app_twi.h +++ b/components/libraries/twi/app_twi.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_TWI_H__ @@ -17,6 +45,10 @@ #include "nrf_drv_twi.h" #include "sdk_errors.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @defgroup app_twi TWI transaction manager * @{ @@ -32,7 +64,7 @@ * Use this flag when a stop condition is undesirable between two transfers, * for example, when the first transfer is a write that sets an address in the slave * device and the second one is a read that fetches certain data using this - * address. In this case, the second transfer should follow directly after the + * address. In this case, the second transfer should follow directly after the * first transfer, with a repeated start condition instead of a stop and then * a new start condition. */ @@ -200,7 +232,7 @@ typedef struct { * @anchor app_twi_init_note * @note The queue size is the maximum number of pending transactions * not counting the one that is currently realized. This means that - * for an empty queue with size of, for example, 4 elements, it is + * for an empty queue with size of, for example, 4 elements, it is * possible to schedule up to 5 transactions. * * @param[in] p_app_twi Pointer to the instance to be initialized. @@ -248,7 +280,7 @@ ret_code_t app_twi_schedule(app_twi_t * p_app_twi, /** * @brief Function for scheduling a transaction and waiting until it is finished. * - * This function schedules a transaction that consists of one or more transfers + * This function schedules a transaction that consists of one or more transfers * and waits until it is finished. * * @param[in] p_app_twi Pointer to the TWI transaction manager instance. @@ -287,4 +319,9 @@ __STATIC_INLINE bool app_twi_is_idle(app_twi_t * p_app_twi) *@} **/ + +#ifdef __cplusplus +} +#endif + #endif // APP_TWI_H__ diff --git a/components/libraries/uart/app_uart.c b/components/libraries/uart/app_uart.c index 40c85c8..d987412 100644 --- a/components/libraries/uart/app_uart.c +++ b/components/libraries/uart/app_uart.c @@ -1,31 +1,62 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_UART) #include "app_uart.h" #include "nrf_drv_uart.h" #include "nrf_assert.h" + static uint8_t tx_buffer[1]; static uint8_t rx_buffer[1]; static volatile bool rx_done; static app_uart_event_handler_t m_event_handler; /**< Event handler function. */ +static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE); -void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context) +static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context) { if (p_event->type == NRF_DRV_UART_EVT_RX_DONE) { app_uart_evt_t app_uart_event; app_uart_event.evt_type = APP_UART_DATA; app_uart_event.data.value = p_event->data.rxtx.p_data[0]; - (void)nrf_drv_uart_rx(rx_buffer,1); + (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1); rx_done = true; m_event_handler(&app_uart_event); } @@ -34,7 +65,7 @@ void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context) app_uart_evt_t app_uart_event; app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR; app_uart_event.data.error_communication = p_event->data.error.error_mask; - (void)nrf_drv_uart_rx(rx_buffer,1); + (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1); m_event_handler(&app_uart_event); } else if (p_event->type == NRF_DRV_UART_EVT_TX_DONE) @@ -67,19 +98,25 @@ uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params, rx_done = false; - if (p_comm_params->flow_control == APP_UART_FLOW_CONTROL_LOW_POWER) + uint32_t err_code = nrf_drv_uart_init(&app_uart_inst, &config, uart_event_handler); + VERIFY_SUCCESS(err_code); + + // Turn on receiver if RX pin is connected + if (p_comm_params->rx_pin_no != UART_PIN_DISCONNECTED) { - return NRF_ERROR_NOT_SUPPORTED; - } +#ifdef UARTE_PRESENT + if (!config.use_easy_dma) +#endif + { + nrf_drv_uart_rx_enable(&app_uart_inst); + } - uint32_t err_code = nrf_drv_uart_init(&config, uart_event_handler); - if (err_code != NRF_SUCCESS) + return nrf_drv_uart_rx(&app_uart_inst, rx_buffer,1); + } + else { - return err_code; + return NRF_SUCCESS; } - - nrf_drv_uart_rx_enable(); - return nrf_drv_uart_rx(rx_buffer,1); } @@ -90,6 +127,7 @@ uint32_t app_uart_get(uint8_t * p_byte) if (rx_done) { *p_byte = rx_buffer[0]; + rx_done = false; } else { @@ -101,7 +139,7 @@ uint32_t app_uart_get(uint8_t * p_byte) uint32_t app_uart_put(uint8_t byte) { tx_buffer[0] = byte; - ret_code_t ret = nrf_drv_uart_tx(tx_buffer,1); + ret_code_t ret = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1); if (NRF_ERROR_BUSY == ret) { return NRF_ERROR_NO_MEM; @@ -123,6 +161,7 @@ uint32_t app_uart_flush(void) uint32_t app_uart_close(void) { - nrf_drv_uart_uninit(); + nrf_drv_uart_uninit(&app_uart_inst); return NRF_SUCCESS; } +#endif //NRF_MODULE_ENABLED(APP_UART) diff --git a/components/libraries/uart/app_uart.h b/components/libraries/uart/app_uart.h index 3e1729f..5972a3f 100644 --- a/components/libraries/uart/app_uart.h +++ b/components/libraries/uart/app_uart.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -26,6 +54,10 @@ #include #include "app_util_platform.h" +#ifdef __cplusplus +extern "C" { +#endif + #define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */ /**@brief UART Flow Control modes for the peripheral. @@ -34,17 +66,16 @@ typedef enum { APP_UART_FLOW_CONTROL_DISABLED, /**< UART Hw Flow Control is disabled. */ APP_UART_FLOW_CONTROL_ENABLED, /**< Standard UART Hw Flow Control is enabled. */ - APP_UART_FLOW_CONTROL_LOW_POWER /**< Specialized UART Hw Flow Control is used. The Low Power setting allows the \nRFXX to Power Off the UART module when CTS is in-active, and re-enabling the UART when the CTS signal becomes active. This allows the \nRFXX to safe power by only using the UART module when it is needed by the remote site. */ } app_uart_flow_control_t; /**@brief UART communication structure holding configuration settings for the peripheral. */ typedef struct { - uint8_t rx_pin_no; /**< RX pin number. */ - uint8_t tx_pin_no; /**< TX pin number. */ - uint8_t rts_pin_no; /**< RTS pin number, only used if flow control is enabled. */ - uint8_t cts_pin_no; /**< CTS pin number, only used if flow control is enabled. */ + uint32_t rx_pin_no; /**< RX pin number. */ + uint32_t tx_pin_no; /**< TX pin number. */ + uint32_t rts_pin_no; /**< RTS pin number, only used if flow control is enabled. */ + uint32_t cts_pin_no; /**< CTS pin number, only used if flow control is enabled. */ app_uart_flow_control_t flow_control; /**< Flow control setting, if flow control is used, the system will use low power UART mode, based on CTS signal. */ bool use_parity; /**< Even parity if TRUE, no parity if FALSE. */ uint32_t baud_rate; /**< Baud rate configuration. */ @@ -222,6 +253,11 @@ uint32_t app_uart_flush(void); uint32_t app_uart_close(void); + +#ifdef __cplusplus +} +#endif + #endif //APP_UART_H__ /** @} */ diff --git a/components/libraries/uart/app_uart_fifo.c b/components/libraries/uart/app_uart_fifo.c index 1059100..d8c8eea 100644 --- a/components/libraries/uart/app_uart_fifo.c +++ b/components/libraries/uart/app_uart_fifo.c @@ -1,20 +1,51 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(APP_UART) #include "app_uart.h" #include "app_fifo.h" #include "nrf_drv_uart.h" #include "nrf_assert.h" +static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE); + static __INLINE uint32_t fifo_length(app_fifo_t * const fifo) { uint32_t tmp = fifo->read_pos; @@ -26,8 +57,8 @@ static __INLINE uint32_t fifo_length(app_fifo_t * const fifo) static app_uart_event_handler_t m_event_handler; /**< Event handler function. */ static uint8_t tx_buffer[1]; -static uint8_t tx_tmp; static uint8_t rx_buffer[1]; +static bool m_rx_ovf; static app_fifo_t m_rx_fifo; /**< RX FIFO buffer for storing data received on the UART until the application fetches them using app_uart_get(). */ static app_fifo_t m_tx_fifo; /**< TX FIFO buffer for storing data to be transmitted on the UART when TXD is ready. Data is put to the buffer on using app_uart_put(). */ @@ -35,55 +66,66 @@ static app_fifo_t m_tx_fifo; /**< static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context) { app_uart_evt_t app_uart_event; + uint32_t err_code; - if (p_event->type == NRF_DRV_UART_EVT_RX_DONE) - { - // Write received byte to FIFO - uint32_t err_code = app_fifo_put(&m_rx_fifo, p_event->data.rxtx.p_data[0]); - if (err_code != NRF_SUCCESS) - { - app_uart_event.evt_type = APP_UART_FIFO_ERROR; - app_uart_event.data.error_code = err_code; - m_event_handler(&app_uart_event); - } - // Notify that new data is available if this was first byte put in the buffer. - else if (FIFO_LENGTH(m_rx_fifo) == 1) - { - app_uart_event.evt_type = APP_UART_DATA_READY; - m_event_handler(&app_uart_event); - } - else - { - // Do nothing, only send event if first byte was added or overflow in FIFO occurred. - } - if (FIFO_LENGTH(m_rx_fifo) <= m_rx_fifo.buf_size_mask) - { - (void)nrf_drv_uart_rx(rx_buffer,1); - } - } - else if (p_event->type == NRF_DRV_UART_EVT_ERROR) - { - app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR; - app_uart_event.data.error_communication = p_event->data.error.error_mask; - m_event_handler(&app_uart_event); - } - else if (p_event->type == NRF_DRV_UART_EVT_TX_DONE) + switch (p_event->type) { - // Get next byte from FIFO. - if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS) - { - (void)nrf_drv_uart_tx(tx_buffer,1); - } - if (FIFO_LENGTH(m_tx_fifo) == 0) - { - // Last byte from FIFO transmitted, notify the application. - // Notify that new data is available if this was first byte put in the buffer. - app_uart_event.evt_type = APP_UART_TX_EMPTY; + case NRF_DRV_UART_EVT_RX_DONE: + // Write received byte to FIFO. + err_code = app_fifo_put(&m_rx_fifo, p_event->data.rxtx.p_data[0]); + if (err_code != NRF_SUCCESS) + { + app_uart_event.evt_type = APP_UART_FIFO_ERROR; + app_uart_event.data.error_code = err_code; + m_event_handler(&app_uart_event); + } + // Notify that there are data available. + else if (FIFO_LENGTH(m_rx_fifo) != 0) + { + app_uart_event.evt_type = APP_UART_DATA_READY; + m_event_handler(&app_uart_event); + } + + // Start new RX if size in buffer. + if (FIFO_LENGTH(m_rx_fifo) <= m_rx_fifo.buf_size_mask) + { + (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1); + } + else + { + // Overflow in RX FIFO. + m_rx_ovf = true; + } + + break; + + case NRF_DRV_UART_EVT_ERROR: + app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR; + app_uart_event.data.error_communication = p_event->data.error.error_mask; + (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1); m_event_handler(&app_uart_event); - } + break; + + case NRF_DRV_UART_EVT_TX_DONE: + // Get next byte from FIFO. + if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS) + { + (void)nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1); + } + else + { + // Last byte from FIFO transmitted, notify the application. + app_uart_event.evt_type = APP_UART_TX_EMPTY; + m_event_handler(&app_uart_event); + } + break; + + default: + break; } } + uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params, app_uart_buffers_t * p_buffers, app_uart_event_handler_t event_handler, @@ -100,19 +142,11 @@ uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params, // Configure buffer RX buffer. err_code = app_fifo_init(&m_rx_fifo, p_buffers->rx_buf, p_buffers->rx_buf_size); - if (err_code != NRF_SUCCESS) - { - // Propagate error code. - return err_code; - } + VERIFY_SUCCESS(err_code); // Configure buffer TX buffer. err_code = app_fifo_init(&m_tx_fifo, p_buffers->tx_buf, p_buffers->tx_buf_size); - if (err_code != NRF_SUCCESS) - { - // Propagate error code. - return err_code; - } + VERIFY_SUCCESS(err_code); nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG; config.baudrate = (nrf_uart_baudrate_t)p_comm_params->baud_rate; @@ -125,68 +159,93 @@ uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params, config.pselrxd = p_comm_params->rx_pin_no; config.pseltxd = p_comm_params->tx_pin_no; - err_code = nrf_drv_uart_init(&config, uart_event_handler); + err_code = nrf_drv_uart_init(&app_uart_inst, &config, uart_event_handler); + VERIFY_SUCCESS(err_code); + m_rx_ovf = false; - if (err_code != NRF_SUCCESS) + // Turn on receiver if RX pin is connected + if (p_comm_params->rx_pin_no != UART_PIN_DISCONNECTED) { - return err_code; - } +#ifdef UARTE_PRESENT + if (!config.use_easy_dma) +#endif + { + nrf_drv_uart_rx_enable(&app_uart_inst); + } - nrf_drv_uart_rx_enable(); - return nrf_drv_uart_rx(rx_buffer,1); + return nrf_drv_uart_rx(&app_uart_inst, rx_buffer,1); + } + else + { + return NRF_SUCCESS; + } } + uint32_t app_uart_flush(void) { uint32_t err_code; err_code = app_fifo_flush(&m_rx_fifo); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); err_code = app_fifo_flush(&m_tx_fifo); - if (err_code != NRF_SUCCESS) - { - return err_code; - } + VERIFY_SUCCESS(err_code); return NRF_SUCCESS; } + uint32_t app_uart_get(uint8_t * p_byte) { ASSERT(p_byte); + bool rx_ovf = m_rx_ovf; + + ret_code_t err_code = app_fifo_get(&m_rx_fifo, p_byte); + // If FIFO was full new request to receive one byte was not scheduled. Must be done here. - if (FIFO_LENGTH(m_rx_fifo) == m_rx_fifo.buf_size_mask) + if(rx_ovf) { - uint32_t err_code = nrf_drv_uart_rx(rx_buffer,1); - if (err_code != NRF_SUCCESS) - { - return NRF_ERROR_NOT_FOUND; - } + m_rx_ovf = false; + uint32_t uart_err_code = nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1); + + // RX resume should never fail. + APP_ERROR_CHECK(uart_err_code); } - return app_fifo_get(&m_rx_fifo, p_byte); + + return err_code; } + uint32_t app_uart_put(uint8_t byte) { uint32_t err_code; - - tx_tmp = byte; - err_code = nrf_drv_uart_tx(&tx_tmp, 1); - - if (err_code == NRF_ERROR_BUSY) + err_code = app_fifo_put(&m_tx_fifo, byte); + if (err_code == NRF_SUCCESS) { - err_code = app_fifo_put(&m_tx_fifo, byte); + // The new byte has been added to FIFO. It will be picked up from there + // (in 'uart_event_handler') when all preceding bytes are transmitted. + // But if UART is not transmitting anything at the moment, we must start + // a new transmission here. + if (!nrf_drv_uart_tx_in_progress(&app_uart_inst)) + { + // This operation should be almost always successful, since we've + // just added a byte to FIFO, but if some bigger delay occurred + // (some heavy interrupt handler routine has been executed) since + // that time, FIFO might be empty already. + if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS) + { + err_code = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1); + } + } } - return err_code; } + uint32_t app_uart_close(void) { - nrf_drv_uart_uninit(); + nrf_drv_uart_uninit(&app_uart_inst); return NRF_SUCCESS; } +#endif //NRF_MODULE_ENABLED(APP_UART) diff --git a/components/libraries/uart/retarget.c b/components/libraries/uart/retarget.c index fdfb895..4d921dd 100644 --- a/components/libraries/uart/retarget.c +++ b/components/libraries/uart/retarget.c @@ -1,35 +1,72 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ +#include "sdk_common.h" +/** @file + * + * @defgroup retarget Retarget layer for stdio functions + * @{ + * @ingroup app_common + * @} */ +#if NRF_MODULE_ENABLED(RETARGET) +#if !defined(NRF_LOG_USES_RTT) || NRF_LOG_USES_RTT != 1 +#if !defined(HAS_SIMPLE_UART_RETARGET) -#ifndef NRF_LOG_USES_RTT #include #include #include "app_uart.h" -#include "nordic_common.h" #include "nrf_error.h" -#if !defined(__ICCARM__) -struct __FILE -{ - int handle; -}; -#endif +#if defined(__CC_ARM) + +// This part is taken from MDK-ARM template file and is required here to prevent +// linker from selecting libraries functions that use semihosting and failing +// because of multiple definitions of fgetc() and fputc(). +// Refer to: http://www.keil.com/support/man/docs/gsac/gsac_retargetcortex.htm +// -- BEGIN -- +struct __FILE { int handle; /* Add whatever you need here */ }; FILE __stdout; FILE __stdin; +// --- END --- - -#if defined(__CC_ARM) || defined(__ICCARM__) int fgetc(FILE * p_file) { uint8_t input; @@ -40,7 +77,6 @@ int fgetc(FILE * p_file) return input; } - int fputc(int ch, FILE * p_file) { UNUSED_PARAMETER(p_file); @@ -48,8 +84,8 @@ int fputc(int ch, FILE * p_file) UNUSED_VARIABLE(app_uart_put((uint8_t)ch)); return ch; } -#elif defined(__GNUC__) +#elif defined(__GNUC__) int _write(int file, const char * p_char, int len) { @@ -65,7 +101,6 @@ int _write(int file, const char * p_char, int len) return len; } - int _read(int file, char * p_char, int len) { UNUSED_PARAMETER(file); @@ -76,6 +111,47 @@ int _read(int file, char * p_char, int len) return 1; } + +#elif defined(__ICCARM__) + +size_t __write(int handle, const unsigned char * buffer, size_t size) +{ + int i; + UNUSED_PARAMETER(handle); + for (i = 0; i < size; i++) + { + UNUSED_VARIABLE(app_uart_put(*buffer++)); + } + return size; +} + +size_t __read(int handle, unsigned char * buffer, size_t size) +{ + UNUSED_PARAMETER(handle); + UNUSED_PARAMETER(size); + while (app_uart_get((uint8_t *)buffer) == NRF_ERROR_NOT_FOUND) + { + // No implementation needed. + } + + return 1; +} + +long __lseek(int handle, long offset, int whence) +{ + return -1; +} +int __close(int handle) +{ + return 0; +} +int remove(const char * filename) +{ + return 0; +} + #endif -#endif // #ifndef NRF_LOG_USES_RTT +#endif // !defined(HAS_SIMPLE_UART_RETARGET) +#endif // NRF_LOG_USES_RTT != 1 +#endif //NRF_MODULE_ENABLED(RETARGET) diff --git a/components/libraries/usbd/app_usbd.c b/components/libraries/usbd/app_usbd.c new file mode 100644 index 0000000..d090baa --- /dev/null +++ b/components/libraries/usbd/app_usbd.c @@ -0,0 +1,898 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_ENABLED +#include "sdk_common.h" +#include "app_usbd.h" +#include "app_usbd_core.h" + +/* Base variables tests */ + +/* Check event of app_usbd_event_type_t enumerator */ +STATIC_ASSERT((int32_t)APP_USBD_EVT_FIRST_APP == (int32_t)NRF_DRV_USBD_EVT_CNT); +STATIC_ASSERT(sizeof(app_usbd_event_type_t) == sizeof(nrf_drv_usbd_event_type_t)); + +STATIC_ASSERT(sizeof(app_usbd_descriptor_header_t) == 2); +STATIC_ASSERT(sizeof(app_usbd_descriptor_device_t) == 18); +STATIC_ASSERT(sizeof(app_usbd_descriptor_configuration_t) == 9); +STATIC_ASSERT(sizeof(app_usbd_descriptor_iface_t) == 9); +STATIC_ASSERT(sizeof(app_usbd_descriptor_ep_t) == 7); +STATIC_ASSERT(sizeof(app_usbd_descriptor_iad_t) == 8); + +STATIC_ASSERT(sizeof(app_usbd_setup_t) == sizeof(nrf_drv_usbd_setup_t)); + +/** + * @internal + * @defgroup app_usbd_internals USBD library internals + * @ingroup app_usbd + * + * Internal variables, auxiliary macros and functions of USBD library. + * @{ + */ + +/** + * @brief Variable type for endpoint configuration + * + * Each endpoint would have assigned this type of configuration structure. + */ +typedef struct +{ + /** + * @brief The class instance + * + * The pointer to the class instance that is connected to the endpoint. + */ + app_usbd_class_inst_t const * p_cinst; + + /** + * @brief Endpoint event handler. + * + * Event handler for the endpoint. + * It is set to event handler for the class instance during connection by default, + * but it can be then updated for as a reaction for @ref APP_USBD_EVT_ATTACHED event. + * This way we can speed up the interpretation of endpoint related events. + */ + app_usbd_ep_event_handler_t event_handler; +}app_usbd_ep_conf_t; + +/** + * @brief Instances connected with IN endpoints + * + * Array of instance pointers connected with every IN endpoint. + * @sa m_epout_instances + */ +static app_usbd_ep_conf_t m_epin_conf[NRF_USBD_EPIN_CNT]; + +/** + * @brief Instances connected with OUT endpoints + * + * Array of instance pointers connected with every OUT endpoint. + * @sa m_epin_instances + */ +static app_usbd_ep_conf_t m_epout_conf[NRF_USBD_EPIN_CNT]; + +/** + * @brief Beginning of classes list + * + * All enabled in current configuration instances are connected into + * a single linked list chain. + * This variable points to first element. + * Core class instance (connected to endpoint 0) is not listed here. + */ +static app_usbd_class_inst_t const * m_p_first_cinst; + +/** + * @brief Classes list that requires SOF events + * + * @todo RK Implement and documentation + */ +static app_usbd_class_inst_t const * m_p_first_sof_cinst; + +/** + * @brief Class interface call: event handler + * + * @ref app_usbd_class_interface_t::event_handler + * + * @param[in] p_cinst Class instance + * @param[in] p_event Event passed to class instance + * + * @return Standard error code @ref ret_code_t + * @retval NRF_SUCCESS event handled successfully + * @retval NRF_ERROR_NOT_SUPPORTED unsupported event + * */ +static inline ret_code_t class_event_handler(app_usbd_class_inst_t const * const p_cinst, + app_usbd_complex_evt_t const * const p_event) +{ + ASSERT(p_cinst != NULL); + ASSERT(p_cinst->p_class_methods != NULL); + ASSERT(p_cinst->p_class_methods->event_handler != NULL); + return p_cinst->p_class_methods->event_handler(p_cinst, p_event); +} + +/** + * @brief Class interface call: get descriptors + * + * @ref app_usbd_class_interface_t::get_descriptors + * + * @param[in] p_inst Class instance + * @param[out] p_size Descriptors size + * + * @return Class descriptors start address + * */ +static inline const void * class_get_descriptors(app_usbd_class_inst_t const * const p_cinst, + size_t * p_size) +{ + ASSERT(p_cinst != NULL); + ASSERT(p_cinst->p_class_methods != NULL); + ASSERT(p_cinst->p_class_methods->get_descriptors != NULL); + return p_cinst->p_class_methods->get_descriptors(p_cinst, p_size); +} + +const void * app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst, + uint8_t desc_type, + uint8_t desc_index, + size_t * p_desc_len) +{ + app_usbd_descriptor_header_t const * p_header; + uint8_t const * p_raw = class_get_descriptors(p_cinst, p_desc_len); + if (p_raw == NULL) + { + return NULL; + } + + size_t pos = 0; + uint8_t index = 0; + while (pos < *p_desc_len) + { + p_header = (app_usbd_descriptor_header_t const *)(p_raw + pos); + if (p_header->bDescriptorType == desc_type) + { + if (desc_index == index) + { + *p_desc_len = p_header->bLength; + return p_header; + } + + index++; + } + + pos += p_header->bLength; + } + + return NULL; +} + +/** + * @brief Access into selected endpoint configuration structure + * + * @param ep Endpoint address + * @return A pointer to the endpoint configuration structure + * + * @note This function would assert when endpoint number is not correct and debugging is enabled. + */ +static app_usbd_ep_conf_t * app_usbd_ep_conf_access(nrf_drv_usbd_ep_t ep) +{ + if (NRF_USBD_EPIN_CHECK(ep)) + { + uint8_t nr = NRF_USBD_EP_NR_GET(ep); + ASSERT(nr < NRF_USBD_EPIN_CNT); + return &m_epin_conf[nr]; + } + else + { + uint8_t nr = NRF_USBD_EP_NR_GET(ep); + ASSERT(nr < NRF_USBD_EPOUT_CNT); + return &m_epout_conf[nr]; + } +} + +/** + * @brief Accessing instance connected with selected endpoint + * + * @param ep Endpoint number + * + * @return The pointer to the instance connected with endpoint + */ +static inline app_usbd_class_inst_t const * app_usbd_ep_instance_get(nrf_drv_usbd_ep_t ep) +{ + return app_usbd_ep_conf_access(ep)->p_cinst; +} + +/** + * @brief Connect instance with selected endpoint + * + * This function configures instance connected to endpoint but also sets + * default event handler function pointer. + * + * @param ep Endpoint number + * @param p_cinst The instance to connect into the selected endpoint. + * NULL if endpoint is going to be disconnected. + * + * @note Disconnecting EP0 is not allowed and protected by assertion. + */ +static void app_usbd_ep_instance_set(nrf_drv_usbd_ep_t ep, app_usbd_class_inst_t const * p_cinst) +{ + app_usbd_ep_conf_t * p_ep_conf = app_usbd_ep_conf_access(ep); + /* Set instance and default event handler */ + p_ep_conf->p_cinst = p_cinst; + if (p_cinst == NULL) + { + ASSERT((ep != NRF_DRV_USBD_EPOUT0) && (ep != NRF_DRV_USBD_EPIN0)); /* EP0 should never be disconnected */ + p_ep_conf->event_handler = NULL; + } + else + { + p_ep_conf->event_handler = p_cinst->p_class_methods->event_handler; + } +} + +/** + * @brief Call the core handler + * + * Core instance is special kind of instance that is connected only to endpoint 0. + * It is not present in instance list. + * This auxiliary function makes future changes easier. + * Just call the event instance for core module here. + */ +static inline ret_code_t app_usbd_core_handler_call(nrf_drv_usbd_evt_t const * const p_event) +{ + return m_epout_conf[0].event_handler(m_epout_conf[0].p_cinst, + (app_usbd_complex_evt_t const *)p_event); +} + +/** + * @brief USBD event handler + * + * + */ +static void app_usbd_event_handler(nrf_drv_usbd_evt_t const * const p_event) +{ + ASSERT(NULL != m_p_first_cinst); + + /* Note - there should never be situation that event is generated on disconnected endpoint */ + switch(p_event->type) + { + case NRF_DRV_USBD_EVT_SOF: + { + app_usbd_class_inst_t const * p_inst = app_usbd_class_sof_first_get(); + ASSERT(NULL != p_inst); /* This should not happen - when no SOF instances are in the list, SOF event is disabled */ + + while (NULL != p_inst) + { + ret_code_t r = class_event_handler(p_inst, (app_usbd_complex_evt_t const *)p_event); + UNUSED_VARIABLE(r); + p_inst = app_usbd_class_sof_next_get(p_inst); + } + break; + } + + /* Reset and */ + case NRF_DRV_USBD_EVT_RESET: + case NRF_DRV_USBD_EVT_RESUME: + { + /* Processing core interface (connected only to EP0) and then all instances from the list */ + UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event)); + app_usbd_all_call((app_usbd_complex_evt_t const *)p_event); + break; + } + case NRF_DRV_USBD_EVT_SUSPEND: + { + /* Processing all instances from the list and then core interface (connected only to EP0) */ + app_usbd_all_call((app_usbd_complex_evt_t const *)p_event); + UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event)); + break; + } + + case NRF_DRV_USBD_EVT_SETUP: + { + UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event)); + break; + } + + case NRF_DRV_USBD_EVT_EPTRANSFER: + { + app_usbd_ep_conf_t const * p_ep_conf = + app_usbd_ep_conf_access(p_event->data.eptransfer.ep); + ASSERT(NULL != p_ep_conf->p_cinst); + ASSERT(NULL != p_ep_conf->event_handler); + + if (NRF_SUCCESS != p_ep_conf->event_handler(p_ep_conf->p_cinst, + (app_usbd_complex_evt_t const *)p_event)) + { + /* If error returned, every bulk/interrupt endpoint would be stalled */ + if (!(0 == NRF_USBD_EP_NR_GET(p_event->data.eptransfer.ep) || + NRF_USBD_EPISO_CHECK(p_event->data.eptransfer.ep))) + { + nrf_drv_usbd_ep_stall(p_event->data.eptransfer.ep); + } + } + break; + } + + default: + ASSERT(0); + break; + } +} + +/** @} */ + + +ret_code_t app_usbd_init(void) +{ + ret_code_t ret; + + ret = nrf_drv_usbd_init(app_usbd_event_handler); + if (NRF_SUCCESS != ret) + { + return ret; + } + + /* Clear variables */ + m_p_first_cinst = NULL; + m_p_first_sof_cinst = NULL; + memset(m_epin_conf , 0, sizeof(m_epin_conf )); + memset(m_epout_conf, 0, sizeof(m_epout_conf)); + + /*Pin core class to required endpoints*/ + uint8_t iface_idx; + app_usbd_class_iface_conf_t const * p_iface; + app_usbd_class_inst_t const * const p_inst = app_usbd_core_instance_access(); + iface_idx = 0; + while ((p_iface = app_usbd_class_iface_get(p_inst, iface_idx++)) != NULL) + { + uint8_t ep_idx = 0; + app_usbd_class_ep_conf_t const * p_ep; + while ((p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)) != NULL) + { + app_usbd_ep_instance_set(app_usbd_class_ep_address_get(p_ep), p_inst); + } + } + + /* Successfully attached */ + const app_usbd_evt_t evt_data = { + .type = APP_USBD_EVT_INST_APPEND + }; + + return class_event_handler(p_inst, (app_usbd_complex_evt_t const *)(&evt_data)); +} + + +ret_code_t app_usbd_uninit(void) +{ + ret_code_t ret; + + ret = nrf_drv_usbd_uninit(); + if(NRF_SUCCESS != ret) + return ret; + + /* Unchain instance list */ + app_usbd_class_inst_t const * * pp_inst; + pp_inst = &m_p_first_cinst; + while (NULL != (*pp_inst)) + { + app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_next; + (*pp_inst) = NULL; + pp_inst = pp_next; + } + + /* Unchain SOF list */ + pp_inst = &m_p_first_sof_cinst; + while (NULL != (*pp_inst)) + { + app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_sof_next; + (*pp_inst) = NULL; + pp_inst = pp_next; + } + + /* Clear all endpoints configurations */ + memset(m_epin_conf , 0, sizeof(m_epin_conf )); + memset(m_epout_conf, 0, sizeof(m_epout_conf)); + + return ret; +} + + +void app_usbd_enable(void) +{ + nrf_drv_usbd_enable(); + while (!app_usbd_core_power_regulator_is_ready()) + ; +} + + +void app_usbd_disable(void) +{ + if (nrf_drv_usbd_is_started()) + { + app_usbd_stop(); + } + nrf_drv_usbd_disable(); +} + + +void app_usbd_start(void) +{ + const app_usbd_evt_t evt_data = { + .type = APP_USBD_EVT_START + }; + + /* Enable all connected endpoints */ + uint8_t n; + for (n = 1; n < ARRAY_SIZE(m_epin_conf); ++n) + { + if (NULL != m_epin_conf[n].p_cinst) + { + nrf_drv_usbd_ep_enable(NRF_DRV_USBD_EPIN(n)); + } + } + for (n = 1; n < ARRAY_SIZE(m_epout_conf); ++n) + { + if (NULL != m_epout_conf[n].p_cinst) + { + nrf_drv_usbd_ep_enable(NRF_DRV_USBD_EPOUT(n)); + } + } + + /* Send event to all classes */ + UNUSED_RETURN_VALUE(app_usbd_core_handler_call((nrf_drv_usbd_evt_t const * )&evt_data)); + app_usbd_all_call((app_usbd_complex_evt_t const *)&evt_data); + + nrf_drv_usbd_start(NULL != m_p_first_sof_cinst); +} + + +void app_usbd_stop(void) +{ + const app_usbd_evt_t evt_data = { + .type = APP_USBD_EVT_STOP + }; + + nrf_drv_usbd_stop(); + + /* Send event to all classes */ + app_usbd_all_call((app_usbd_complex_evt_t const * )&evt_data); + UNUSED_RETURN_VALUE(app_usbd_core_handler_call((nrf_drv_usbd_evt_t const *)&evt_data)); +} + + +ret_code_t app_usbd_class_append(app_usbd_class_inst_t const * p_cinst) +{ + ASSERT(NULL != p_cinst); + ASSERT(NULL != p_cinst->p_class_methods); + ASSERT(NULL != p_cinst->p_class_methods->event_handler); + ASSERT(NULL == app_usbd_class_data_access(p_cinst)->p_next); + + /* This should be only called if USBD is disabled + * We simply assume that USBD is enabled if its interrupts are */ + ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized()); + + /* Check if all required endpoints are available + * Checking is splitted from setting to avoid situation that anything + * is modified and then operation finishes with error */ + uint8_t iface_idx; + app_usbd_class_iface_conf_t const * p_iface; + + iface_idx = 0; + while (NULL != (p_iface = app_usbd_class_iface_get(p_cinst, iface_idx++))) + { + uint8_t ep_idx = 0; + app_usbd_class_ep_conf_t const * p_ep; + while (NULL != (p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++))) + { + if (NULL != app_usbd_ep_instance_get(app_usbd_class_ep_address_get(p_ep))) + { + return NRF_ERROR_BUSY; + } + } + } + + /* Connecting all required endpoints */ + iface_idx = 0; + while (NULL != (p_iface = app_usbd_class_iface_get(p_cinst, iface_idx++))) + { + uint8_t ep_idx = 0; + app_usbd_class_ep_conf_t const * p_ep; + while (NULL != (p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++))) + { + app_usbd_ep_instance_set(app_usbd_class_ep_address_get(p_ep), p_cinst); + } + } + + /* Adding pointer to this instance to the end of the chain */ + app_usbd_class_inst_t const * * pp_last = &m_p_first_cinst; + while (NULL != (*pp_last)) + { + ASSERT((*pp_last) != p_cinst); + pp_last = &(app_usbd_class_data_access(*pp_last)->p_next); + } + (*pp_last) = p_cinst; + + /* Successfully attached */ + const app_usbd_evt_t evt_data = {.type = APP_USBD_EVT_INST_APPEND }; + return class_event_handler(p_cinst, (app_usbd_complex_evt_t const *)(&evt_data)); +} + + +ret_code_t app_usbd_class_remove(app_usbd_class_inst_t const * p_cinst) +{ + ASSERT(NULL != p_cinst); + ASSERT(NULL != p_cinst->p_class_methods); + ASSERT(NULL != p_cinst->p_class_methods->event_handler); + /** This function should be only called if USBD is disabled */ + ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized()); + ret_code_t ret; + /* Remove this class from the chain */ + app_usbd_class_inst_t const * * pp_last = &m_p_first_cinst; + while (NULL != (*pp_last)) + { + if ((*pp_last) == p_cinst) + { + /* Inform class instance that removing process is going to be started */ + const app_usbd_evt_t evt_data = { + .type = APP_USBD_EVT_INST_REMOVE + }; + ret = class_event_handler(p_cinst, (app_usbd_complex_evt_t const *)(&evt_data)); + if (ret != NRF_SUCCESS) + { + return ret; + } + + /* Breaking chain */ + (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_next); + app_usbd_class_data_access(p_cinst)->p_next = NULL; + + /* Disconnecting endpoints */ + uint8_t ep_idx; + for (ep_idx = 0; ep_idx < NRF_USBD_EPIN_CNT; ++ep_idx) + { + nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPIN(ep_idx); + if (app_usbd_ep_instance_get(ep) == p_cinst) + { + app_usbd_ep_instance_set(ep, NULL); + } + } + for (ep_idx = 0; ep_idx < NRF_USBD_EPOUT_CNT; ++ep_idx) + { + nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPOUT(ep_idx); + if (app_usbd_ep_instance_get(ep) == p_cinst) + { + app_usbd_ep_instance_set(ep, NULL); + } + } + + return NRF_SUCCESS; + } + pp_last = &(app_usbd_class_data_access(*pp_last)->p_next); + } + + return NRF_ERROR_NOT_FOUND; +} + + +ret_code_t app_usbd_class_remove_all(void) +{ + ret_code_t ret = NRF_SUCCESS; + while (NULL != m_p_first_cinst) + { + ret = app_usbd_class_remove(m_p_first_cinst); + if (ret != NRF_SUCCESS) + { + break; + } + } + + return ret; +} + + +ret_code_t app_usbd_ep_handler_set(app_usbd_class_inst_t const * const p_cinst, + nrf_drv_usbd_ep_t ep, + app_usbd_ep_event_handler_t handler) +{ + ASSERT(NULL != p_cinst); + ASSERT(NULL != handler); + /** This function should be only called if USBD is disabled */ + ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized()); + + if (p_cinst != app_usbd_ep_instance_get(ep)) + { + return NRF_ERROR_INVALID_PARAM; + } + + (app_usbd_ep_conf_access(ep))->event_handler = handler; + return NRF_SUCCESS; +} + + +ret_code_t app_usbd_class_sof_register(app_usbd_class_inst_t const * p_cinst) +{ + ASSERT(NULL != p_cinst); + ASSERT(NULL != p_cinst->p_class_methods); + ASSERT(NULL != p_cinst->p_class_methods->event_handler); + /** This function should be only called if USBD is disabled */ + ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized()); + + /* Next SOF event requiring instance have to be null now */ + ASSERT(NULL == (app_usbd_class_data_access(p_cinst)->p_sof_next)); + + /* Adding pointer to this instance to the end of the chain */ + app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_cinst; + while (NULL != (*pp_last)) + { + + ASSERT((*pp_last) != p_cinst); + pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next); + } + (*pp_last) = p_cinst; + + return NRF_SUCCESS; +} + + +ret_code_t app_usbd_class_sof_unregister(app_usbd_class_inst_t const * p_cinst) +{ + ASSERT(NULL != p_cinst); + /** This function should be only called if USBD is disabled */ + ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized()); + + app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_cinst; + while (NULL != (*pp_last)) + { + if ((*pp_last) == p_cinst) + { + /* Breaking chain */ + (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_sof_next); + app_usbd_class_data_access(p_cinst)->p_sof_next = NULL; + + return NRF_SUCCESS; + } + pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next); + } + return NRF_ERROR_NOT_FOUND; +} + +ret_code_t app_usbd_interface_std_req_handle(app_usbd_class_inst_t const * p_cinst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_GET_STATUS: + { + size_t tx_size; + uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size); + + p_tx_buff[0] = 0; + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint16_t)); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +ret_code_t app_usbd_endpoint_std_req_handle(app_usbd_class_inst_t const * p_cinst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + size_t i; + nrf_drv_usbd_ep_t ep_addr = NRF_DRV_USBD_EPIN0; + for (i = 0; i < app_usbd_class_iface_count_get(p_cinst); ++i) + { + app_usbd_class_iface_conf_t const * p_iface_conf = app_usbd_class_iface_get(p_cinst, i); + const uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface_conf); + + ep_addr = (nrf_drv_usbd_ep_t)(p_setup_ev->setup.wIndex.lb); + uint8_t ep_idx = app_usbd_class_iface_ep_idx_get(p_iface_conf, ep_addr); + if (ep_idx == ep_count) + { + continue; + } + + break; + } + + if (i == app_usbd_class_iface_count_get(p_cinst)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_GET_STATUS: + { + size_t tx_size; + uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size); + + p_tx_buff[0] = nrf_drv_usbd_ep_stall_check(ep_addr) ? 1 : 0; + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint16_t)); + } + case APP_USBD_SETUP_STDREQ_SET_FEATURE: + { + if (p_setup_ev->setup.wValue.w != APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + nrf_drv_usbd_ep_stall(ep_addr); + return NRF_SUCCESS; + } + case APP_USBD_SETUP_STDREQ_CLEAR_FEATURE: + { + if (p_setup_ev->setup.wValue.w != APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (nrf_usbd_dtoggle_get(ep_addr) != NRF_USBD_DTOGGLE_DATA0) + { + nrf_usbd_dtoggle_set(ep_addr, NRF_USBD_DTOGGLE_DATA0); + } + + if (NRF_USBD_EPISO_CHECK(ep_addr) == 0) + { + nrf_drv_usbd_ep_stall_clear(ep_addr); + } + + return NRF_SUCCESS; + } + default: + return NRF_ERROR_NOT_SUPPORTED; + } +} + +ret_code_t app_usbd_req_std_set_interface(app_usbd_class_inst_t const * const p_cinst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + uint8_t iface_count = app_usbd_class_iface_count_get(p_cinst); + + app_usbd_class_iface_conf_t const * p_iface = NULL; + for (uint8_t j = 0; j < iface_count; ++j) + { + p_iface = app_usbd_class_iface_get(p_cinst, j); + if (p_iface->number == p_setup_ev->setup.wIndex.w) + { + break; + } + } + + if (p_iface == NULL) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface); + + for (uint8_t j = 0; j < ep_count; ++j) + { + /*Clear stall for every endpoint*/ + app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, j); + + if (nrf_usbd_dtoggle_get(p_ep->address) != NRF_USBD_DTOGGLE_DATA0) + { + nrf_usbd_dtoggle_set(p_ep->address, NRF_USBD_DTOGGLE_DATA0); + } + + if (NRF_USBD_EPISO_CHECK(p_ep->address) == 0) + { + nrf_drv_usbd_ep_stall_clear(p_ep->address); + } + + } + + return NRF_SUCCESS; +} + +app_usbd_class_inst_t const * app_usbd_class_first_get(void) +{ + return m_p_first_cinst; +} + +app_usbd_class_inst_t const * app_usbd_class_sof_first_get(void) +{ + return m_p_first_sof_cinst; +} + +ret_code_t app_usbd_iface_call(uint8_t iface, app_usbd_complex_evt_t const * const p_event) +{ + ASSERT(NULL != m_p_first_cinst); + /*Iterate over classes*/ + app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get(); + while (p_inst != NULL) + { + uint8_t iface_count = app_usbd_class_iface_count_get(p_inst); + /*Iterate over interfaces*/ + for (uint8_t i = 0; i < iface_count; ++i) + { + app_usbd_class_iface_conf_t const * p_iface; + p_iface = app_usbd_class_iface_get(p_inst, i); + if (app_usbd_class_iface_number_get(p_iface) == iface) + { + return class_event_handler(p_inst, p_event); + } + } + p_inst = app_usbd_class_next_get(p_inst); + } + + return NRF_ERROR_INVALID_ADDR; +} + +ret_code_t app_usbd_ep_call(nrf_drv_usbd_ep_t ep, app_usbd_complex_evt_t const * const p_event) +{ + app_usbd_class_inst_t const * p_inst = app_usbd_ep_conf_access(ep)->p_cinst; + if (p_inst != NULL) + { + return class_event_handler(p_inst, p_event); + } + + return NRF_ERROR_INVALID_ADDR; +} + +void app_usbd_all_call(app_usbd_complex_evt_t const * const p_event) +{ + app_usbd_class_inst_t const * p_inst; + for (p_inst = app_usbd_class_first_get(); NULL != p_inst; + p_inst = app_usbd_class_next_get(p_inst)) + { + UNUSED_RETURN_VALUE(class_event_handler(p_inst, p_event)); + } +} + +ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event) +{ + app_usbd_class_inst_t const * p_inst; + ret_code_t ret = NRF_ERROR_NOT_SUPPORTED; + /* Try to process via every instance */ + for (p_inst = app_usbd_class_first_get(); NULL != p_inst; + p_inst = app_usbd_class_next_get(p_inst)) + { + + ret = class_event_handler(p_inst, p_event); + if (NRF_ERROR_NOT_SUPPORTED != ret) + { + /* Processing finished */ + break; + } + } + + return ret; +} + +#endif // APP_USBD_ENABLED diff --git a/components/libraries/usbd/app_usbd.h b/components/libraries/usbd/app_usbd.h new file mode 100644 index 0000000..861115f --- /dev/null +++ b/components/libraries/usbd/app_usbd.h @@ -0,0 +1,383 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_H__ +#define APP_USBD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf_drv_usbd.h" +#include "app_usbd_types.h" +#include "app_usbd_class_base.h" + +/** + * @defgroup app_usbd USB Device high level library + * @ingroup app_common + * + * @brief @tagAPI52840 Module for easy support for any USB device configuration. + * + * This module manages class instances that would create the USB device, + * manages endpoints and interfaces transactions. + * @{ + */ + +/** + * @brief USB library initialization. + * + * Call this function before any configuration or class attachment. + * USBD peripheral would be ready to accept commands, and library would be ready, + * but it would not be connected to the bus. + * Call @ref app_usbd_enable to enable USBD communication with the host. + */ +ret_code_t app_usbd_init(void); + +/** + * @brief USB library un-initialization + * + * @note Currently not supported + */ +ret_code_t app_usbd_uninit(void); + +/** + * @brief Enable USBD + * + * USBD is enabled and starts requiring High Frequency Clock and power regulator. + */ +void app_usbd_enable(void); + +/** + * @brief Disable USBD + * + * Disabled USDB peripheral cannot be accessed but also stops requesting + * High Frequency clock and releases power regulator. + */ +void app_usbd_disable(void); + +/** + * @brief Start USB to work + * + * Start library to work. + * Enable interrupts. + * Enable USB pull-ups. + * After calling this function USB device is visible to a HOST. + */ +void app_usbd_start(void); + +/** + * @brief Stop USB to work + * + * This function disables interrupts and USB pull-ups. + * The peripheral itself is left enabled so it can be programmed, + * but it a HOST sees it as a peripheral disconnection. + */ +void app_usbd_stop(void); + +/** + * @brief Add class instance + * + * This function connects given instance into internal class instance chain and + * into all required endpoints. + * The instance event handler would be connected into endpoint by default, + * but this can be overwritten by @ref app_usbd_ep_handler_set. + * + * After successful attachment @ref APP_USBD_EVT_INST_APPEND would be passed to class instance. + * + * @note This function can only be called after USBD library is initialized but still disabled. + * Assertion would be generated otherwise. + * + * @param[in,out] p_cinst Instance to connect. Chain data would be written into writable instance data. + */ +ret_code_t app_usbd_class_append(app_usbd_class_inst_t const * p_cinst); + +/** + * @brief Remove class instance + * + * Instance is removed from instance chain. + * Instance and event handlers are removed also from endpoints. + * Endpoints used by by the class instance are left disabled. + * + * @note This function can only be called after USBD library is initialized but still disabled. + * Assertion would be generated otherwise. + * + * @param p_cinst Instance pointer to remove. + * + * @retval NRF_SUCCESS Instance successfully removed. + * @retval NRF_ERROR_NOT_FOUND Instance not found in the instance chain. + */ +ret_code_t app_usbd_class_remove(app_usbd_class_inst_t const * p_cinst); + +/** + * @brief Remove all class instances + * + * This function basically calls @ref app_usbd_class_remove + * on instances chain as long as there is any element left. + * + * @note This function can only be called after USBD library is initialized but still disabled. + * Assertion would be generated otherwise. + * + * @sa app_usbd_class_remove + * + * @return Is should always return @ref NRF_SUCCESS. + * Any error value returned would mean there is an error inside the library. + */ +ret_code_t app_usbd_class_remove_all(void); + +/** + * @brief Change endpoint handler + * + * This function may be called for the endpoint only if the class instance is + * already properly attached by the @ref app_usbd_class_append function. + * + * The endpoint event handler function can be only overwritten by the class instance + * that was connected into the endpoint. + * + * @note This function can only be called after USBD library is initialized but still disabled. + * Assertion would be generated otherwise. + * + * @param[in] p_cinst Instance of a class that wish to set new event handler. + * It has to match currently configured instance for the selected endpoint. + * In other situation error would be returned. + * @param[in] ep Endpoint address to configure. + * @param[in] handler Event handler function to set. + * + * @retval NRF_SUCCESS New handler successfully set + * @retval NRF_ERROR_INVALID_PARAM p_cinst is not the same as currently set for the endpoint + */ +ret_code_t app_usbd_ep_handler_set(app_usbd_class_inst_t const * p_cinst, + nrf_drv_usbd_ep_t ep, + app_usbd_ep_event_handler_t handler); + +/** + * @brief Register class instance as the one that requires SOF events + * + * This function should be called in reaction on APP_USBD_EVT_INST_APPEND event. + * Connect the class instance to the list of instances that requires SOF processing. + * If none of the appended instances requires SOF event - it is disabled. + * + * @param p_cinst Instance that requires SOF event. + * + * @retval NRF_SUCCESS Instance linked into SOF processing list. + * + * @sa app_usbd_class_sof_unregister + */ +ret_code_t app_usbd_class_sof_register(app_usbd_class_inst_t const * p_cinst); + +/** + * @brief Unregister class instance from SOF processing instances list + * + * Every class that calls @ref app_usbd_class_sof_register have to call also unregistering function + * in reaction to @ref APP_USBD_EVT_INST_REMOVE event. + * + * @param p_cinst Instance to be unregistered from SOF event processing list. + * + * @retval NRF_SUCCESS Instance linked into SOF processing list. + * @retval NRF_ERROR_NOT_FOUND Instance not found in the SOF processing list. + * + * @sa app_usbd_class_sof_register + */ +ret_code_t app_usbd_class_sof_unregister(app_usbd_class_inst_t const * p_cinst); + +/** + * @brief Function finds a given descriptor type in class descriptors payload + * + * @param[in] p_cinst Instance of a class + * @param[in] desc_type Descriptor type (@ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR) + * @param[in] desc_index Descriptor index (@ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR) + * @param[out] p_desc_len Descriptor length + * + * @return Address of the descriptor (NULL if not found) + * */ +const void * app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst, + uint8_t desc_type, + uint8_t desc_index, + size_t * p_desc_len); + +/** + * @brief Standard interface request handle + * + * @param[in] p_cinst Instance of a class + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * */ +ret_code_t app_usbd_interface_std_req_handle(app_usbd_class_inst_t const * p_cinst, + app_usbd_setup_evt_t const * p_setup_ev); + +/** + * @brief Standard endpoint request handle + * + * @param[in] p_cinst Instance of a class + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * */ +ret_code_t app_usbd_endpoint_std_req_handle(app_usbd_class_inst_t const * p_cinst, + app_usbd_setup_evt_t const * p_setup_ev); + + +/** + * @brief Standard interface set request handle + * + * @param[in] p_cinst Instance of a class + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * */ +ret_code_t app_usbd_req_std_set_interface(app_usbd_class_inst_t const * const p_cinst, + app_usbd_setup_evt_t const * const p_setup_ev); + +/** + * @name Iterate through classes lists + * + * Functions that helps to iterate through internally chained classes. + * @{ + */ + /** + * @brief Get first class instance in the list + * + * Get first instance from the list of active class instances. + * That instance may be used then in @ref app_usbd_class_next_get function. + * + * @return First instance in the list or NULL if there are no instances available. + */ + app_usbd_class_inst_t const * app_usbd_class_first_get(void); + + /** + * @brief Get next instance in the list + * + * Get the next instance from the list of active instances. + * Used to iterate through all instances. + * + * @param[in] p_cinst The current instance from with next one is required. + * + * @return Next instance to the given one or NULL if there is no more instances in the list. + */ + static inline app_usbd_class_inst_t const * app_usbd_class_next_get( + app_usbd_class_inst_t const * const p_cinst) + { + ASSERT(NULL != p_cinst); + return app_usbd_class_data_access(p_cinst)->p_next; + } + + /** + * @brief Get first instance in SOF list + * + * Start iteration through the list of instances that requires SOF event processing. + * + * @return First instance in the list or NULL if the list is empty + * + * @sa app_usbd_class_first_get + */ + app_usbd_class_inst_t const * app_usbd_class_sof_first_get(void); + + /** + * @brief Get next instance in the SOF list + * + * Get the next instance from the list of instances requiring SOF event processing. + * Used to iterate through all SOF instances. + * + * @param p_cinst The current instance from with next one is required. + * + * @return Next instance to the given one or NULL if there is no more instances in the list. + */ + static inline app_usbd_class_inst_t const * app_usbd_class_sof_next_get( + app_usbd_class_inst_t const * const p_cinst) + { + ASSERT(NULL != p_cinst); + return app_usbd_class_data_access(p_cinst)->p_sof_next; + } +/** @} */ + +/** + * @name Communicate with interfaces, endpoints and instances inside usbd library + * + * @{ + */ + + /** + * @brief Call interface event handler + * + * Call event handler for selected interface. + * @param[in] iface Target interface number + * @param[in] p_event Event structure to send + * + * @return Operation status + */ + ret_code_t app_usbd_iface_call(uint8_t iface, app_usbd_complex_evt_t const * const p_event); + + /** + * @brief Call endpoint event handler + * + * Call event handler for the selected endpoint. + * @param[in] ep Endpoint number + * @param[in] p_event Event structure to send + * + * @return Operation status + */ + ret_code_t app_usbd_ep_call(nrf_drv_usbd_ep_t ep, app_usbd_complex_evt_t const * const p_event); + + /** + * @brief Auxiliary function that process event by every instance in the list + * + * This function ignores the result of called handler. + * + * @param p_event Event to pass to every instance + */ + void app_usbd_all_call(app_usbd_complex_evt_t const * const p_event); + + /** + * @brief Call interface event handlers and stop when served + * + * Call event handlers from instances as long as we get result different than @ref NRF_ERROR_NOT_SUPPORTED + * @param[in] p_event Event structure to send + * + * @return Operation status or @ref NRF_ERROR_NOT_SUPPORTED if none of instances in the list can support given event. + */ + ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event); +/** @} */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_H__ */ diff --git a/components/libraries/usbd/app_usbd_class_base.h b/components/libraries/usbd/app_usbd_class_base.h new file mode 100644 index 0000000..352d2aa --- /dev/null +++ b/components/libraries/usbd/app_usbd_class_base.h @@ -0,0 +1,838 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_CLASS_BASE_H__ +#define APP_USBD_CLASS_BASE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "app_usbd_types.h" +#include "nrf_drv_usbd.h" +#include "nrf_assert.h" +#include "app_util.h" + +/** + * @defgroup app_usbd_class_base USBD Class Base module + * @ingroup app_usbd + * + * @brief @tagAPI52840 The base for any class instance is defined in this module. + * + * @details Any class instance must start from base class instance structure. + * This makes them compatible with USBD library independently of the + * implementation details. + * @{ + */ + +/** + * @brief Endpoint configuration + */ +typedef struct +{ + nrf_drv_usbd_ep_t address; //!< Endpoint address +} app_usbd_class_ep_conf_t; + +/** + * @brief Interface configuration + */ +typedef struct +{ + uint8_t number; //!< Interface number + uint8_t ep_cnt; //!< Endpoint number + uint8_t ep_offset; //!< Offset of the first endpoint + /**< Offset in bytes of the first endpoint. + * The offset is calculated from the address of this interface structure + */ +} app_usbd_class_iface_conf_t; + +/** + * @brief Instance variable data + */ +typedef struct +{ + app_usbd_class_inst_t const * p_next; //!< Pointer to the next instance + app_usbd_class_inst_t const * p_sof_next; //!< Pointer to the next SOF event requiring instance +} app_usbd_class_data_t; + + +/** + * @brief Class interface function set + * */ +typedef struct { + /** + * @brief Instance callback function + * + * The function used by every class instance. + * @param[in,out] p_inst Instance of the class + * @param[in] p_event Event to process + * + * @note If given event is not supported by class, return @ref NRF_ERROR_NOT_SUPPORTED + */ + ret_code_t (* event_handler)(app_usbd_class_inst_t const * const p_inst, + app_usbd_complex_evt_t const * const p_event); + + /** + * @brief Instance get descriptors + * + * The function used by every class instance. + * @param[in,out] p_inst Instance of the class + * @param[out] p_size Descriptor size + * + * @return Class descriptors start address + */ + const void * (* get_descriptors)(app_usbd_class_inst_t const * const p_inst, + size_t * p_size); +} app_usbd_class_methods_t; + +/** + * @brief The instance structure itself + * + * The structure of base class instance + */ +struct app_usbd_class_inst_s +{ + app_usbd_class_data_t * p_data; //!< Pointer to non-constant data + app_usbd_class_methods_t const * p_class_methods; //!< Class interface methods + struct + { + uint8_t cnt; //!< Number of defined interfaces + uint8_t config[]; //!< Interface configuration data followed by endpoint data + } iface; //!< Interface structure +}; + + +/** + * @brief Get total number of interfaces + * + * + */ +static inline uint8_t app_usbd_class_iface_count_get(app_usbd_class_inst_t const * const p_inst) +{ + return p_inst->iface.cnt; +} + +/** + * @brief Interface accessing function + * + * Get interface pointer. + * Interfaces creates continuous array in the memory so it is possible to get + * interface with index 0 and the just iterate to the next one. + * + * @param p_inst Pointer to the class instance + * @param iface_idx Index of the instance to get. + * This is not the interface identifier. + * Technically it is the index of the interface in the class description array. + * @return Pointer to the interface configuration parameters or NULL if given index is out of interface scope for given class. + */ +static inline app_usbd_class_iface_conf_t const * app_usbd_class_iface_get( + app_usbd_class_inst_t const * const p_inst, + uint8_t iface_idx) +{ + ASSERT(NULL != p_inst); + if (iface_idx >= (app_usbd_class_iface_count_get(p_inst))) + { + return NULL; + } + + app_usbd_class_iface_conf_t const * p_interface = + (app_usbd_class_iface_conf_t const * )(p_inst->iface.config); + return &(p_interface[iface_idx]); +} + +/** + * @brief Get interface number + * + * @param p_iface Pointer to interface structure + * + * @return Interface number from interface configuration structure + */ +static inline uint8_t app_usbd_class_iface_number_get( + app_usbd_class_iface_conf_t const * const p_iface) +{ + return p_iface->number; +} + +/** + * @brief Get number of endpoints in interface + * + * @param p_iface Pointer to interface structure + * + * @return Number of endpoints used by given interface + */ +static inline uint8_t app_usbd_class_iface_ep_count_get( + app_usbd_class_iface_conf_t const * const p_iface) +{ + return p_iface->ep_cnt; +} + +/** + * @brief Interface Endpoint accessing function + * + * @param p_iface Interface configuration pointer + * @param ep_idx Endpoint index + * + * @return Endpoint information structure pointer or NULL if given index is outside of endpoints for selected interface. + * + * @sa app_usbd_class_iface_get + */ +static inline app_usbd_class_ep_conf_t const * app_usbd_class_iface_ep_get( + app_usbd_class_iface_conf_t const * const p_iface, + uint8_t ep_idx) +{ + ASSERT(NULL != p_iface); + if (ep_idx >= p_iface->ep_cnt) + { + return NULL; + } + + app_usbd_class_ep_conf_t const * p_ep = + (app_usbd_class_ep_conf_t const * )(((uint8_t const *)p_iface) + p_iface->ep_offset); + return &(p_ep[ep_idx]); +} + +/** + * @brief Translate endpoint address to class index + * + * @param p_iface Interface configuration pointer + * @param ep_address Endpoint address + * + * @return Endpoint index or number of endpoints if not found + * + */ +static inline uint8_t app_usbd_class_iface_ep_idx_get( + app_usbd_class_iface_conf_t const * const p_iface, + nrf_drv_usbd_ep_t ep_address) +{ + ASSERT(NULL != p_iface); + app_usbd_class_ep_conf_t const * p_ep = + (app_usbd_class_ep_conf_t const * )(((uint8_t const *)p_iface) + p_iface->ep_offset); + + uint8_t i; + for (i = 0; i < p_iface->ep_cnt; ++i) + { + if (ep_address == p_ep[i].address) + { + break; + } + } + + return i; +} + +/** + * @brief Get the selected endpoint address + * + * @param p_ep Endpoint configuration structure + * + * @return Endpoint address + */ +static inline nrf_drv_usbd_ep_t app_usbd_class_ep_address_get(app_usbd_class_ep_conf_t const * p_ep) +{ + return (nrf_drv_usbd_ep_t)p_ep->address; +} + +/** + * @brief Get the pointer to the writable instance data + * + * @param p_inst Instance pointer + * @return Pointer to writable instance data + */ +static inline app_usbd_class_data_t * app_usbd_class_data_access( + app_usbd_class_inst_t const * const p_inst) +{ + return p_inst->p_data; +} + +/** + * @name Internal macros for argument mapping + * + * Functions to be used as a mapping macro for @ref MACRO_MAP, @ref MACRO_MAP_FOR or @ref MACRO_MAP_FOR_PARAM + * @{ + */ + /** + * @brief Count the number of endpoints in given configuration + * + * Config should be given as a interface configuration in a brackets: + * @code + * (interface_nr, ep1, ep2, ep3) + * @endcode + * Number of endpoints may vary from 0 to a few (technically up to 16, but it seems not to make sense to use more than 4). + * Interface number is always present. + * + * @param iface_config Single interface configuration (in brackets) + * + * @return Number of endpoints in interface. This is computed value - can be used by compiler but not by preprocessor. + */ + #define APP_USBD_CLASS_CONF_IFACE_EP_COUNT_(iface_config) \ + (NUM_VA_ARGS(BRACKET_EXTRACT(iface_config)) - 1) + + /** + * @brief Adds the number of endpoints in given config to the current value + * + * This is basically @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_ with plus sign added. + * + * @param iface_config See parameters documentation in @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_ + * + * @return Plus sign followed by number of endpoints in interface. + * + * @sa APP_USBD_CLASS_CONF_IFACE_EP_COUNT_ + */ + #define APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_(iface_config) \ + + APP_USBD_CLASS_CONF_IFACE_EP_COUNT_(iface_config) + + /** + * @brief Create variable for endpoint + */ + + /** + * @brief Extract endpoints given interface configuration + * + * This macro gets single endpoint configuration and extracts all the endpoints. + * It also adds comma on the end of extracted endpoints. + * This way when this macro is called few times it generates nice list of all endpoints + * that may be used to array initialization. + * + * @param iface_config Single interface configuration in brackets. + * The format should be similar like described in @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_. + */ + #define APP_USBD_CLASS_IFACE_EP_EXTRACT_(iface_config) \ + CONCAT_2(APP_USBD_CLASS_IFACE_EP_EXTRACT_, \ + NUM_VA_ARGS_IS_MORE_THAN_1(BRACKET_EXTRACT(iface_config))) \ + (BRACKET_EXTRACT(iface_config)) + + /** + * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_EP_EXTRACT_ + * + * This macro is called when interface has no endpoints + */ + #define APP_USBD_CLASS_IFACE_EP_EXTRACT_0(iface_nr) + + /** + * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_EP_EXTRACT_ + * + * This macro is called when interface has at least one endpoint + */ + #define APP_USBD_CLASS_IFACE_EP_EXTRACT_1(...) \ + APP_USBD_CLASS_IFACE_EP_EXTRACT_1_(__VA_ARGS__) + + #define APP_USBD_CLASS_IFACE_EP_EXTRACT_1_(iface_nr, ...) \ + MACRO_MAP_REC(PARAM_CBRACE, __VA_ARGS__) + + /** + * @brief Generate configuration for single interface + * + * This macro extract configuration for single interface. + * The configuration is inside curly brackets and comma is added on the end. + * This mean it can be directly used to init array of interface configurations. + * + * @param iface_config Single interface configuration + * @param N Currently processed configuration + * @param iface_configs All interfaces configuration in brackets + */ + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_(iface_config, N, iface_configs) \ + CONCAT_2(APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_, \ + NUM_VA_ARGS_IS_MORE_THAN_1(BRACKET_EXTRACT(iface_config))) \ + (N, iface_configs, BRACKET_EXTRACT(iface_config)) + + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_x(iface_config, N, iface_configs) \ + [N] = !!!iface_config!!! + /** + * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_ + * + * This macro is called when interface has no endpoints + */ + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0(N, iface_configs, iface_nr) \ + APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0_(N, iface_configs, iface_nr) + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0_(N, iface_configs, iface_nr) \ + { .number = iface_nr, .ep_cnt = 0, .ep_offset = 0 }, + + /** + * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_ + * + * This macro is called when interface has at last one endpoint + */ + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1(N, iface_configs, ...) \ + APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1_(N, iface_configs, __VA_ARGS__) + #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1_(N, iface_configs, iface_nr, ...) \ + { .number = iface_nr, .ep_cnt = NUM_VA_ARGS(__VA_ARGS__), \ + .ep_offset = APP_USBD_CLASS_CONF_TOTAL_EP_COUNT_N(N, iface_configs) * \ + sizeof(app_usbd_class_ep_conf_t) \ + + ((NUM_VA_ARGS(BRACKET_EXTRACT(iface_configs)) - N) * \ + sizeof(app_usbd_class_iface_conf_t)) \ + }, + +/** @} */ + + +/** + * @name Macros that uses mapping macros internally + * + * Auxiliary macros that uses mapping macros to make some calculations or realize other functionality. + * Mapped here for easier unit testing and to hide complex mapping functions calling. + * @{ + */ + +/** + * @brief Count total number of endpoints + * + * @param iface_configs List of interface configurations like explained + * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF + * + * @return The equation to calculate the number of endpoints by compiler. + */ +#define APP_USBD_CLASS_CONF_TOTAL_EP_COUNT(iface_configs) \ + (0 MACRO_MAP(APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_, BRACKET_EXTRACT(iface_configs))) + +/** + * @brief Count total number of endpoint up-to interface index + * + * The version of @ref APP_USBD_CLASS_CONF_TOTAL_EP_COUNT macro witch takes the + * number of interfaces to analyze. + * + * @param N Number of interfaces to analyze + * @param iface_configs List of interface configurations like explained + * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF + * + * @return The equation to calculate the number of endpoints by compiler. + */ +#define APP_USBD_CLASS_CONF_TOTAL_EP_COUNT_N(N, iface_configs) \ + (0 MACRO_MAP_N(N, APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_, BRACKET_EXTRACT(iface_configs))) + +/** + * @brief Extract configurations for interfaces + * + * This macro extracts the configurations for every interface. + * Basically uses the @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_ macro on every + * configuration found. + * + * This should generate interface configuration initialization data + * in comma separated initializers in curly braces. + * + * @param iface_configs List of interface configurations like explained + * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF + * + * @return Comma separated initialization data for all interfaces. + */ +#define APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(iface_configs) \ + MACRO_MAP_FOR_PARAM(iface_configs, \ + APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_, \ + BRACKET_EXTRACT(iface_configs)) + +/** + * @brief Extract all endpoints + * + * Macro that extracts all endpoints from every interface + * + * @param iface_configs List of interface configurations like explained + * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF + * + * @return Comma separated list of endpoints + */ +#define APP_USBD_CLASS_IFACES_EP_EXTRACT(iface_configs) \ + MACRO_MAP(APP_USBD_CLASS_IFACE_EP_EXTRACT_, BRACKET_EXTRACT(iface_configs)) + + +/** @} */ + + +/** + * @brief USBD instance of class mnemonic + * + * Macro that generates mnemonic for the name of the structure that describes instance for selected class. + * + * @param type_name The name of the instance without _t postfix + * + * @return The name with the right postfix to create the name for the type for the class. + */ +#define APP_USBD_CLASS_INSTANCE_TYPE(type_name) CONCAT_2(type_name, _t) + +/** + * @brief USBD data for instance class mnemonic + * + * The mnemonic of the variable type that holds writable part of the class instance. + * + * @param type_name The name of the instance without _t postfix + * + * @return The name with the right postfix to create the name for the data type for the class. + */ +#define APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(type_name, _data_t) + +/** + * @brief Declare class specific member of class instance + * + * @param type Type of the attached class configuration. + * + * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF + */ +#define APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC(type) type class_part; + +/** + * @brief Used if there is no class specific configuration + * + * This constant can be used if there is no specific configuration inside created instance + * + * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF + */ +#define APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE + +/** + * @brief Declare class specific member of class data + * + * @param type Type of the attached class data. + * + * @sa APP_USBD_CLASS_DATA_TYPEDEF + */ +#define APP_USBD_CLASS_DATA_SPECIFIC_DEC(type) APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC(type) + +/** + * @brief Used if there is no class specific data + * + * This constant can be used if there is no specific writable data inside created instance + * + * @sa APP_USBD_CLASS_DATA_TYPEDEF + */ +#define APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE + + + + +/** + * @brief Instance structure declaration + * + * The macro that declares a variable type that would be used to store given class instance. + * Class instance stores all the data from @ref app_usbd_class_inst_t and overlaid data for specified class. + * + * The structure of interface configuration data: + * @code + * ( + * (iface1_nr, (ep1, ep2, ep3)), + (iface2_nr), + (iface3_nr, (ep4)) + * ) + * @endcode + * + * @param type_name The name of the instance without _t postfix. + * @param interfaces_configs List of interface configurations like explained above. + * @param class_config_dec Result of the macro + * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC or + * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE + * + * @return The definition of the structure type that holds all the required data. + * + * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_DATA_TYPEDEF instead. + * + * @note APP_USBD_CLASS_DATA_TYPEDEF has to be called first for the compilation to success. + * + * @sa APP_USBD_CLASS_TYPEDEF + */ +#define APP_USBD_CLASS_INSTANCE_TYPEDEF(type_name, interfaces_configs, class_config_dec) \ + typedef union CONCAT_2(type_name, _u) \ + { \ + app_usbd_class_inst_t base; \ + struct \ + { \ + APP_USBD_CLASS_DATA_TYPE(type_name) * p_data; \ + app_usbd_class_methods_t const * p_class_methods; \ + struct \ + { \ + uint8_t cnt; \ + app_usbd_class_iface_conf_t \ + config[NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs))]; \ + app_usbd_class_ep_conf_t \ + ep[APP_USBD_CLASS_CONF_TOTAL_EP_COUNT(interfaces_configs)]; \ + } iface; \ + class_config_dec \ + } specific; \ + } APP_USBD_CLASS_INSTANCE_TYPE(type_name) + +/** + * @brief Writable data structure declaration + * + * The macro that declares a variable type that would be used to store given class writable data. + * Writable data contains base part of the type @ref app_usbd_class_data_t followed by + * class specific data. + * + * @param type_name The name of the type without _t postfix. + * @param class_data_dec Result of the macro + * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC or + * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE + * + * @return The definition of the structure type that holds all the required writable data + * + * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_DATA_TYPEDEF instead. + * + * @sa APP_USBD_CLASS_TYPEDEF + */ +#define APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec) \ + typedef struct \ + { \ + app_usbd_class_data_t base; \ + class_data_dec \ + }APP_USBD_CLASS_DATA_TYPE(type_name) + + +/** + * @brief Declare all data types required by the class instance + * + * Macro that declares data type first and then instance type. + * + * @param type_name The name of the type without _t postfix. + * @param interface_configs List of interface configurations like in @ref APP_USBD_CLASS_INSTANCE_TYPEDEF. + * @param class_config_dec Result of the macro + * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC or + * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE + * @param class_data_dec Result of the macro + * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC or + * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE + * + * @return Declaration of the data type for the instance and instance itself. + * + * @sa APP_USBD_CLASS_DATA_TYPEDEF + * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF + */ +#define APP_USBD_CLASS_TYPEDEF(type_name, interface_configs, class_config_dec, class_data_dec) \ + APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec); \ + APP_USBD_CLASS_INSTANCE_TYPEDEF(type_name, interface_configs, class_config_dec) + +/** + * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF + * + * @param type_name The name of the type without _t postfix. + * */ +#define APP_USBD_CLASS_FORWARD(type_name) union CONCAT_2(type_name, _u) + +/** + * @brief Generate the initialization data for + * + * Macro that generates the initialization data for instance. + * + * @param p_ram_data Pointer to writable instance data structure + * @param class_methods Class methods + * @param interfaces_configs Exactly the same interface config data that in @ref APP_USBD_CLASS_INSTANCE_TYPEDEF + * @param class_config_part Configuration part. The data should be inside brackets. + * Any data here would be removed from brackets and then put as an initialization + * data for class_part member of instance structure. + * + * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_INST_DEF instead. + */ +#define APP_USBD_CLASS_INSTANCE_INITVAL(p_ram_data, \ + class_methods, \ + interfaces_configs, \ + class_config_part) \ + { \ + .specific = { \ + .p_data = p_ram_data, \ + .p_class_methods = class_methods, \ + .iface = { \ + .cnt = NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs)), \ + .config = { APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(interfaces_configs) }, \ + .ep = { APP_USBD_CLASS_IFACES_EP_EXTRACT(interfaces_configs) } \ + }, \ + BRACKET_EXTRACT(class_config_part) \ + } \ + } + + +/** + * @brief Define the base class instance + * + * Macro that defines whole instance variable and fill it with initialization data. + * + * The tricky part is @c class_config_part. + * The configuration data here has to be placed inside brackets. + * Then any type of values can be used depending on the type used in @ref APP_USBD_CLASS_TYPEDEF. + * If instance does not have any specyfic data, use just empty bracket here. + * @code + * APP_USBD_CLASS_TYPEDEF( + * some_base_class, + * CLASS_BASE_CONFIGURATION, + * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE, + * APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE + * ); + * APP_USBD_CLASS_INST_DEF( + * some_base_class_inst, + * some_base_class, + * base_class_event_handler, + * CLASS_BASE_CONFIGURATION, + * () // Empty configuration + * ); + * @endcode + * + * If the type of instance configuration is simple type, just provide initialization value: + * @code + * APP_USBD_CLASS_TYPEDEF( + * some_base_class, + * CLASS_BASE_CONFIGURATION, + * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE, + * APP_USBD_CLASS_DATA_SPECIFIC_DEC(uint8_t) + * ); + * APP_USBD_CLASS_INST_DEF( + * some_base_class_inst, + * some_base_class, + * base_class_event_handler, + * CLASS_BASE_CONFIGURATION, + * (12) // Example values + * ); + * @endcode + * + * If the type of instance configuration is structure, provide initialization value for the whole structure: + * @code + * typedef structure + * { + * uint32_t p1; + * uint8_t p2; + * }my_config_t; + * + * APP_USBD_CLASS_TYPEDEF( + * some_base_class, + * CLASS_BASE_CONFIGURATION, + * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE, + * APP_USBD_CLASS_DATA_SPECIFIC_DEC(my_config_t) + * ); + * APP_USBD_CLASS_INST_DEF( + * some_base_class_inst, + * some_base_class, + * base_class_event_handler, + * CLASS_BASE_CONFIGURATION, + * ({12, 3}) // Example values + * ); + * @endcode + * + * @param instance_name The name of created instance variable. + * It would be constant variable and its type would be app_usbd_class_inst_t. + * @param type_name The name of the variable type. It has to be the same type that was passed to + * @ref APP_USBD_CLASS_TYPEDEF + * @param class_methods Class unified interface. + * @param interfaces_configs The same configuration data that the one passed to @ref APP_USBD_CLASS_TYPEDEF + * @param class_config_part Configuration data to the type that was declared by class_data_dec when calling + * @ref APP_USBD_CLASS_TYPEDEF. + * Configuration data has to be provided in brackets. + * It would be extracted from brackets and placed in initialization part of configuration structure. + * See detailed description of this macro for more informations. + */ +#define APP_USBD_CLASS_INST_DEF(instance_name, \ + type_name, \ + class_methods, \ + interfaces_configs, \ + class_config_part) \ + static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \ + static const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \ + APP_USBD_CLASS_INSTANCE_INITVAL( \ + &CONCAT_2(instance_name, _data), \ + class_methods, \ + interfaces_configs, \ + class_config_part) + + +/** + * @brief Define the base class instance in global scope + * + * This is the same macro like @ref APP_USBD_CLASS_INST_DEF but it creates the instance + * without static keyword. + * + * @param instance_name See documentation for @ref APP_USBD_CLASS_INST_DEF + * @param type_name See documentation for @ref APP_USBD_CLASS_INST_DEF + * @param class_methods See documentation for @ref APP_USBD_CLASS_INST_DEF + * @param interfaces_configs See documentation for @ref APP_USBD_CLASS_INST_DEF + * @param class_config_part See documentation for @ref APP_USBD_CLASS_INST_DEF + */ +#define APP_USBD_CLASS_INST_GLOBAL_DEF(instance_name, \ + type_name, \ + class_methods, \ + interfaces_configs, \ + class_config_part) \ + static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \ + const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \ + APP_USBD_CLASS_INSTANCE_INITVAL( \ + &CONCAT_2(instance_name, _data), \ + class_methods, \ + interfaces_configs, \ + class_config_part) + +/** + * @brief Access class specific configuration + * + * Macro that returns class specific configuration. + * + * @param[in] p_inst Instance pointer + * + * @return A pointer for class specific part of the instance + * + * @note If macro is used on the instance that has no class specific configuration + * an error would be generated during compilation. + */ +#define APP_USBD_CLASS_GET_SPECIFIC_CONFIG(p_inst) (&((p_inst)->specific.class_part)) + +/** + * @brief Access class specific data + * + * @param[in] p_inst Instance pointer + * + * @return A pointer for class specific part of writable data + * + * @note If macro is used on the instance that has no class specific data + * an error would be generated during compilation. + */ +#define APP_USBD_CLASS_GET_SPECIFIC_DATA(p_inst) (&(((p_inst)->specific.p_data)->class_part)) + +/** + * @brief Macro to get base instance from class specific instance + * + * This macro may be used on class specific instance to get base instance that + * can be processed by base instance access functions. + * Class specific instance can be just casted to class base instance, + * but then we would totally lost type safety. + * + * A little more safe is to use pointer to base member of class instance. + * This would generate an error when used on any variable that have no base member + * and would generate also error if this base member is wrong type. + */ +#define APP_USBD_CLASS_BASE_INSTANCE(p_inst) (&((p_inst)->base)) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_CLASS_BASE_H__ */ diff --git a/components/libraries/usbd/app_usbd_core.c b/components/libraries/usbd/app_usbd_core.c new file mode 100644 index 0000000..3930a4c --- /dev/null +++ b/components/libraries/usbd/app_usbd_core.c @@ -0,0 +1,1180 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_ENABLED +#include "app_usbd_core.h" +#include "app_usbd.h" +#include "app_usbd_request.h" +#include "app_usbd_string_desc.h" +#include "nrf.h" +#include "nrf_atomic.h" +#include "app_util_platform.h" +#include "app_usbd.h" +#include "app_usbd_class_base.h" + +/* Test if VID was configured */ +#ifndef APP_USBD_VID +#error APP_USBD_VID not properly defined. +#endif + +/* USBD device version creating if defined in major/minor form */ +#ifndef APP_USBD_DEVICE_VER + #if defined(APP_USBD_DEVICE_VER_MAJOR) && defined(APP_USBD_DEVICE_VER_MINOR) + #if ((APP_USBD_DEVICE_VER_MAJOR)) > 99 || ((APP_USBD_DEVICE_VER_MINOR) > 99) + #error Major and minor device version value have to be limited to 99. + #endif + #define APP_USBD_DEVICE_VER (((APP_USBD_DEVICE_VER_MAJOR)*100UL) + (APP_USBD_DEVICE_VER_MINOR)) + #else + #error The definition of APP_USBD_DEVICE_VER or a pair APP_USBD_DEVICE_VER_MAJOR and APP_USBD_DEVICE_VER_MINOR required. + #endif +#endif + +/** + * @internal + * @defgroup app_usbd_core_internals USB Device high level library core module internals + * @ingroup app_usbd_core + * + * Internal variables, auxiliary macros and functions of USBD high level core module. + * @{ + */ + +/** @brief Make USB BCD version */ +#define APP_USBD_VERSION_BCD_MAKE(major, minor) (((0x##major) << 8) | (0x##minor)) + +/** @brief Make USB power value */ +#define APP_USBD_POWER_MAKE(ma) (((ma) + 1) / 2) + +/** @brief Convert device version to BCD notation */ +#define APP_USBD_BCD_DEVICE ( \ + ((((APP_USBD_DEVICE_VER) % 10000) / 1000) * 0x1000) + \ + ((((APP_USBD_DEVICE_VER) % 1000) / 100) * 0x100) + \ + ((((APP_USBD_DEVICE_VER) % 100) / 10) * 0x10) + \ + ((((APP_USBD_DEVICE_VER) % 10) / 1) * 0x1) \ + ) + +/** + @brief Default device descriptor initializer @ref app_usbd_descriptor_device_t +* */ +#define APP_USBD_CORE_DEVICE_DESCRIPTOR { \ + .bLength = sizeof(app_usbd_descriptor_device_t), /* descriptor size */ \ + .bDescriptorType = APP_USBD_DESCRIPTOR_DEVICE, /* descriptor type */ \ + .bcdUSB = APP_USBD_VERSION_BCD_MAKE(2,0), /* USB BCD version: 2.0 */ \ + .bDeviceClass = 0, /* device class: 0 - specified by interface */ \ + .bDeviceSubClass = 0, /* device subclass: 0 - specified by interface */ \ + .bDeviceProtocol = 0, /* device protocol: 0 - specified by interface */ \ + .bMaxPacketSize0 = NRF_DRV_USBD_EPSIZE, /* endpoint size: fixed to: NRF_DRV_USBD_EPSIZE*/ \ + .idVendor = APP_USBD_VID, /* Vendor ID*/ \ + .idProduct = APP_USBD_PID, /* Product ID*/ \ + .bcdDevice = APP_USBD_BCD_DEVICE, /* Device version BCD */ \ + .iManufacturer = APP_USBD_STRING_ID_MANUFACTURER, /* String ID: manufacturer */ \ + .iProduct = APP_USBD_STRING_ID_PRODUCT, /* String ID: product */ \ + .iSerialNumber = APP_USBD_STRING_ID_SERIAL, /* String ID: serial */ \ + .bNumConfigurations = 1, /* Fixed value: only one configuration supported*/ \ +} + + +#define APP_USBD_CORE_CONFIGURATION_DESCRIPTOR { \ + .bLength = sizeof(app_usbd_descriptor_configuration_t), \ + .bDescriptorType = APP_USBD_DESCRIPTOR_CONFIGURATION, \ + .wTotalLength = 0, /*Calculated dynamically*/ \ + .bNumInterfaces = 0, /*Calculated dynamically*/ \ + .bConfigurationValue = 1, /*Value passed to set configuration*/ \ + .iConfiguration = 0, /*Configuration ID: fixed to 0*/ \ + .bmAttributes = APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_ALWAYS_SET_MASK | \ + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK, \ + .bMaxPower = APP_USBD_POWER_MAKE(500), \ +} + +/** + * @brief USB descriptors + */ +typedef struct { + app_usbd_descriptor_device_t device; + app_usbd_descriptor_configuration_t * const configuration; +} app_usbd_core_descriptors_t; + +/** + * @brief Configuration descriptor instance. + * + * Not const: some values must be calculated dynamically + */ +static app_usbd_descriptor_configuration_t m_configuration_dsc = + APP_USBD_CORE_CONFIGURATION_DESCRIPTOR; + +/** + * @brief Core descriptors + * + * Descriptors: device, configuration, strings + * + */ +static const app_usbd_core_descriptors_t m_descriptors = { + .device = APP_USBD_CORE_DEVICE_DESCRIPTOR, + .configuration = &m_configuration_dsc, +}; + + +/* Required early declaration of event handler function */ +static ret_code_t app_usbd_core_event_handler(app_usbd_class_inst_t const * const p_inst, + app_usbd_complex_evt_t const * const p_event); + +/** + * @brief Current USB device state + * + * This variable is updated automatically by core library. + */ +static app_usbd_state_t app_usbd_state = APP_USBD_STATE_Disabled; + +/** + * @brief Active device features + * + * @note Only @ref APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP is supported for device + */ +static uint8_t m_device_features_state; + +/** + * @brief Remote wake-up register/unregister + * + * Counter incremented when appended instance required remote wake-up functionality. + * It should be decremented when the class is removed. + * When this counter is not zero, remote wake-up functionality is activated inside core. + */ +static uint8_t m_rwu_counter; + +/** + * @brief Remote wake-up pending flag + */ +static nrf_atomic_flag_t m_rwu_pending; + + +/** + * @brief Core class methods + * + * Base methods interface for core class. + * This is quite specific class - it would be only connected into endpoint 0. + * Not connected into instances list. + */ +static const app_usbd_class_methods_t m_core_methods = { + .event_handler = app_usbd_core_event_handler, + .get_descriptors = NULL, +}; + +/** + * @brief Setup transfer buffer + */ +static uint8_t m_setup_transfer_buff[NRF_DRV_USBD_EPSIZE]; + + +/** + * @brief Handler for outgoing setup data + * + * @todo RK documentation + */ +static app_usbd_core_setup_data_handler_desc_t m_ep0_handler_desc; + +#define APP_USBD_CORE_CLASS_INSTANCE_CONFIG () + + +/*lint -u -save -e26 -e40 -e64 -e123 -e505 -e651*/ + +/** + * @brief Core instance + * + * Create instance that would be connected into endpoints in USBD library. + */ +APP_USBD_CLASS_INST_GLOBAL_DEF( + app_usbd_core_inst, + app_usbd_core, + &m_core_methods, + APP_USBD_CORE_CLASS_CONFIGURATION, + () ); +/*lint -restore*/ + + + +/** + * @brief Check current USBD power connection status + * + */ +static inline bool usbd_core_power_is_detected(void) +{ + return 0 != ( (NRF_POWER->USBREGSTATUS) & POWER_USBREGSTATUS_VBUSDETECT_Msk); +} + + +/** + * @brief Safely call EP0 handler + * + * Function calls EP0 handler only if its pointer is non-zero. + * + * @param status Status to send as a handler parameter. + */ +static inline ret_code_t usbd_core_ep0_handler_call_and_clear(nrf_drv_usbd_ep_status_t status) +{ + app_usbd_core_setup_data_handler_t handler = m_ep0_handler_desc.handler; + if (NULL != handler) + { + m_ep0_handler_desc.handler = NULL; + return handler(status, m_ep0_handler_desc.p_context); + } + + return NRF_ERROR_NULL; +} + +/** + * @brief Check if EP0 handler is configured + * + * EP0 handler is configured is any instance that has processed SETUP command + * expects some incoming / outgoing data. + * + * EP0 handler should be cleared automatically just before it is called + * (see @ref usbd_core_ep0_handler_call_and_clear). + * If instance requires more data - it has to setup EP0 handler once more time + * (see @ref app_usbd_core_setup_data_handler_set). + * + * This function adds small layer of abstraction for checking if EP0 handler + * is already configured. + * + * @retval true EP0 handler is set + * @retval false EP0 handler is cleared + */ +static inline bool usb_core_ep0_handler_check(void) +{ + return (NULL != m_ep0_handler_desc.handler); +} + +/** + * @brief Empty data handler + * + * Data handler used only to mark that there is requested data during SETUP. + * + * @return Always NRF_SUCCESS + * @sa setup_empty_data_handler_desc + */ +static ret_code_t setup_data_handler_empty(nrf_drv_usbd_ep_status_t status, void * p_contex) +{ + UNUSED_PARAMETER(status); + UNUSED_PARAMETER(p_contex); + return NRF_SUCCESS; +} + +/** + * @brief + * + * @todo RK Documentation + */ +static const app_usbd_core_setup_data_handler_desc_t m_setup_data_handler_empty_desc = +{ + .handler = setup_data_handler_empty, + .p_context = NULL +}; + +/** + * @brief Special feeder to generate ZLP + * + * This feeder includes ZLP on the end of the transfer if required. + * The context should be a pointer to the boolean value: true if it ZLP is required, + * false if not. + */ +static bool app_usbd_core_zlp_feeder(nrf_drv_usbd_transfer_t * p_next, void * p_context) +{ + bool * p_generate = p_context; + if(*p_generate) + { + p_next->p_data.tx = NULL; + p_next->size = 0; + *p_generate = false; + return true; + } + return false; +} + +/** + * @todo RK Documentation + * + * @note This variable is used only for ZLP generation in SETUP response + */ +static bool m_setup_zlp_required; + +/** + * @todo RK Documentation + * + * @note This variable is used only for ZLP generation in SETUP response + */ +static const nrf_drv_usbd_transfer_handler_desc_t m_setup_zlp_desc = +{ + .handler = app_usbd_core_zlp_feeder, + .p_context = &m_setup_zlp_required +}; + +/** + * @brief Structure used as a context for descriptor feeder + * + * Structure with all the data required to process instances to generate descriptor + * data chunk. + */ +typedef struct +{ + app_usbd_class_inst_t const * p_cinst; //!< The class instance that is currently processed + const uint8_t * p_desc; //!< Pointer at current descriptor or NULL if finished. + /**< + * If we get NULL on transfer function enter it means that ZLP is required. + * Or it is time to finish the transfer (depending on @c total_left). + */ + size_t desc_left; //!< Number of bytes left in the current class descriptor to send + size_t total_left; //!< Number of bytes left that was requested by the host + uint8_t * p_trans_buff; //!< Currently used transfer buffer + /**< + * This member is used only when function is called first time, + * from function that prepares first transfer. + * If the buffer was partially filled the @c max_size member would contain + * number of bytes left to fill. + * + * This member is automatically cleared inside @ref usbd_descriptor_feeder. + */ + size_t max_size; //!< Size in the buffer left. + /** + * Valid only if @c p_trans_buff is not NULL. + */ +} app_usbd_core_descriptor_conf_feed_data_t; + +/** + * @brief Default data used by the feeder + * + * + */ +static app_usbd_core_descriptor_conf_feed_data_t m_descriptor_conf_feed_data; + +/** + * @brief Descriptor feeder + * + * Descriptor feeder is used as an callback function when descriptors are + * transfered and buffer is ready for next data. + * It prepares next chunk of data to be sent. + * + * @param p_next See @ref nrf_drv_usbd_next_transfer_handler_t documentation. + * @param p_context Pointer to @ref app_usbd_core_descriptor_feed_data_t data type. + * + * @return See @ref nrf_drv_usbd_next_transfer_handler_t documentation. + */ +static bool usbd_descriptor_conf_feeder(nrf_drv_usbd_transfer_t * p_next, void * p_context) +{ + app_usbd_core_descriptor_conf_feed_data_t * p_data = p_context; + if (NULL == p_data->p_cinst) + { + if (0 != p_data->total_left) + { + p_data->total_left = 0; + /* ZLP request */ + p_next->p_data.tx = NULL; + p_next->size = 0; + return true; + } + else + { + return false; + } + } + else + { + size_t max_size; /* Buffer size */ + uint8_t * p_trans_buff; + size_t size = 0; /* Currently added number of bytes */ + size_t tx_size; /* Number of bytes aviable for current transfer */ + + if (NULL == p_data->p_trans_buff) + { + p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size); + } + else + { + p_trans_buff = p_data->p_trans_buff; + max_size = p_data->max_size; + p_data->p_trans_buff = NULL; + } + + tx_size = MIN(max_size, p_data->total_left); + while (0 != tx_size) + { + /* Process transfer */ + if (0 < p_data->desc_left) + { + size_t to_copy = MIN(tx_size, p_data->desc_left); + memcpy(p_trans_buff+size, p_data->p_desc, to_copy); + p_data->desc_left -= to_copy; + p_data->total_left -= to_copy; + tx_size -= to_copy; + size += to_copy; + p_data->p_desc += to_copy; + } + if (0 == p_data->desc_left) + { + /* Get next descriptor */ + p_data->p_cinst = app_usbd_class_next_get(p_data->p_cinst); + if (NULL == p_data->p_cinst) + { + /* No more data - check if ZLP is required */ + if (size > 0) + { + if (0 != (size % nrf_drv_usbd_ep_max_packet_size_get(NRF_DRV_USBD_EPIN0))) + { + /* No ZLP required */ + p_data->total_left = 0; + } + } + + break; + } + else + { + /* Prepare next descriptor */ + p_data->p_desc = + p_data->p_cinst->p_class_methods->get_descriptors(p_data->p_cinst, + &p_data->desc_left); + } + } + } + p_next->p_data.tx = p_trans_buff; + p_next->size = size; + return true; + } +} + +/** + * @brief + * + * @todo RK Documentation + */ +static const nrf_drv_usbd_transfer_handler_desc_t usbd_descriptor_feeder_desc = +{ + .handler = usbd_descriptor_conf_feeder, + .p_context = &m_descriptor_conf_feed_data +}; + +static ret_code_t setup_req_get_status(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + size_t max_size; + uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size); + ASSERT(sizeof(uint16_t) <= max_size); + + memset(p_trans_buff, 0, sizeof(uint16_t)); + if (m_descriptors.configuration->bmAttributes & + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK) + { + SET_BIT(p_trans_buff[0], 0); + } + if (IS_SET(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP)) + { + SET_BIT(p_trans_buff[0], 1); + } + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, sizeof(uint16_t)); +} + +static ret_code_t setup_req_get_descriptor(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + switch (p_setup_ev->setup.wValue.hb) + { + case APP_USBD_DESCRIPTOR_DEVICE: + { + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), + &m_descriptors.device, + sizeof(m_descriptors.device)); + } + case APP_USBD_DESCRIPTOR_CONFIGURATION: + { + /* The size equals the size of configuration descriptor and all classes descriptors */ + size_t size = sizeof(app_usbd_descriptor_configuration_t); + uint8_t iface_count = 0; + + /* Iterate over all registered classes count descriptors and total size */ + app_usbd_class_inst_t const * p_class; + for (p_class = app_usbd_class_first_get(); p_class != NULL; + p_class = app_usbd_class_next_get(p_class)) + { + ASSERT(NULL != (p_class->p_class_methods)); + ASSERT(NULL != (p_class->p_class_methods->get_descriptors)); + size_t dsc_size; + const void * dsc = p_class->p_class_methods->get_descriptors(p_class, &dsc_size); + UNUSED_VARIABLE(dsc); + size += dsc_size; + iface_count += app_usbd_class_iface_count_get(p_class); + } + + m_descriptors.configuration->bNumInterfaces = iface_count; + m_descriptors.configuration->wTotalLength = size; + + if (m_rwu_counter) + { + m_descriptors.configuration->bmAttributes |= + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_REMOTE_WAKEUP_MASK; + } + + /* Access transmission buffer */ + size_t max_size; + uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size); + /* Copy updated configuration descriptor */ + ASSERT(sizeof(m_descriptors.configuration) <= max_size); + memcpy(p_trans_buff, + m_descriptors.configuration, + sizeof(app_usbd_descriptor_configuration_t)); + + /* Fill the structure that allows iteration through all classes */ + memset(&m_descriptor_conf_feed_data, 0, sizeof(m_descriptor_conf_feed_data)); + + nrf_drv_usbd_transfer_t first_tx; + size_t tx_size = MIN(size, p_setup_ev->setup.wLength.w); + if (tx_size > sizeof(app_usbd_descriptor_configuration_t)) + { + p_class = app_usbd_class_first_get(); + m_descriptor_conf_feed_data.p_cinst = p_class; + + ASSERT(NULL != (p_class->p_class_methods)); + ASSERT(NULL != (p_class->p_class_methods->get_descriptors)); + + m_descriptor_conf_feed_data.p_desc = + p_class->p_class_methods->get_descriptors( + p_class, + &(m_descriptor_conf_feed_data.desc_left)); + + size_t dsc_size = sizeof(app_usbd_descriptor_configuration_t); + + m_descriptor_conf_feed_data.total_left = tx_size - dsc_size; + m_descriptor_conf_feed_data.p_trans_buff = p_trans_buff + dsc_size; + m_descriptor_conf_feed_data.max_size = max_size - dsc_size; + + bool tx_ready = usbd_descriptor_conf_feeder(&first_tx, + &m_descriptor_conf_feed_data); + ASSERT(tx_ready); + UNUSED_VARIABLE(tx_ready); + + first_tx.p_data.tx = p_trans_buff; + first_tx.size += sizeof(app_usbd_descriptor_configuration_t); + ASSERT(first_tx.size <= max_size); + } + else + { + m_descriptor_conf_feed_data.p_cinst = NULL; + m_descriptor_conf_feed_data.total_left = 0; + + first_tx.p_data.tx = p_trans_buff; + first_tx.size = tx_size; + } + + /* Start first transfer */ + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPIN0, + &first_tx, + &usbd_descriptor_feeder_desc); + + if (NRF_SUCCESS == ret) + { + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPIN0, + &m_setup_data_handler_empty_desc); + } + CRITICAL_REGION_EXIT(); + + return ret; + } + case APP_USBD_DESCRIPTOR_STRING: + { + app_usbd_string_desc_idx_t id = + (app_usbd_string_desc_idx_t)(p_setup_ev->setup.wValue.lb); + uint16_t langid = p_setup_ev->setup.wIndex.w; + uint16_t const * p_string_dsc = app_usbd_string_desc_get(id, langid); + if (p_string_dsc == NULL) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + p_string_dsc, + app_usbd_string_desc_length(p_string_dsc)); + } + default: + break; + } + + + return NRF_ERROR_NOT_SUPPORTED; +} + +static ret_code_t setup_req_get_configuration(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + size_t max_size; + uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size); + if (APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Configured) + { + p_trans_buff[0] = 1; + } + else if (APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Addressed) + { + p_trans_buff[0] = 0; + } + else + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return app_usbd_core_setup_rsp(&p_setup_ev->setup, p_trans_buff, sizeof(p_trans_buff[0])); +} + +/** + * @brief Internal SETUP standard IN request handler + * @param[in] p_inst Instance of the class + * @param[in] p_setup_ev Setup request + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_GET_STATUS: + { + return setup_req_get_status(p_inst, p_setup_ev); + } + case APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR: + { + return setup_req_get_descriptor(p_inst, p_setup_ev); + } + case APP_USBD_SETUP_STDREQ_GET_CONFIGURATION: + { + return setup_req_get_configuration(p_inst, p_setup_ev); + } + default: + /*Not supported*/ + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + + +static ret_code_t setup_req_std_set_configuration(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + if (!((app_usbd_state == APP_USBD_STATE_Configured) || + (app_usbd_state == APP_USBD_STATE_Addressed))) + { + return NRF_ERROR_INVALID_STATE; + } + + app_usbd_state_t new_state = app_usbd_state; + + if (p_setup_ev->setup.wValue.lb == 0) + { + new_state = APP_USBD_STATE_Addressed; + } + else if (p_setup_ev->setup.wValue.lb == 1) + { + new_state = APP_USBD_STATE_Configured; + /*Clear all bulk/interrupt endpoint status and set toggle to DATA0*/ + + app_usbd_class_inst_t const * p_inst_it = app_usbd_class_first_get(); + while (p_inst_it != NULL) + { + uint8_t iface_count = app_usbd_class_iface_count_get(p_inst_it); + for (uint8_t i = 0; i < iface_count; ++i) + { + app_usbd_class_iface_conf_t const * p_iface; + p_iface = app_usbd_class_iface_get(p_inst_it, i); + uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface); + + for (uint8_t j = 0; j < ep_count; ++j) + { + /*Clear stall for every endpoint*/ + app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, j); + + + if (nrf_usbd_dtoggle_get(p_ep->address) != NRF_USBD_DTOGGLE_DATA0) + { + nrf_usbd_dtoggle_set(p_ep->address, NRF_USBD_DTOGGLE_DATA0); + } + + if (NRF_USBD_EPISO_CHECK(p_ep->address) == 0) + { + nrf_drv_usbd_ep_stall_clear(p_ep->address); + } + + } + } + p_inst_it = p_inst_it->p_data->p_next; + } + + } + else + { + /*In this driver only one configuration is supported.*/ + return NRF_ERROR_INVALID_PARAM; + } + + + + if (app_usbd_state != new_state) + { + app_usbd_state = new_state; + /** @todo RK A way to notify class that state was changed */ + } + + return NRF_SUCCESS; +} + +/** + * @brief Internal SETUP standard OUT request handler + * @param[in] p_inst Instance of the class + * @param[in] p_setup_ev Setup request + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_SET_ADDRESS: + { + if ((app_usbd_state != APP_USBD_STATE_Default) && + (app_usbd_state != APP_USBD_STATE_Addressed) && + (app_usbd_state != APP_USBD_STATE_Configured)) + { + return NRF_ERROR_INVALID_STATE; + } + + app_usbd_state = APP_USBD_STATE_Addressed; + return NRF_SUCCESS; + } + case APP_USBD_SETUP_STDREQ_SET_FEATURE: + { + if (p_setup_ev->setup.wValue.w != APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + SET_BIT(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP); + return NRF_SUCCESS; + } + case APP_USBD_SETUP_STDREQ_CLEAR_FEATURE: + { + if (p_setup_ev->setup.wValue.w != APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + CLR_BIT(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP); + return NRF_SUCCESS; + } + case APP_USBD_SETUP_STDREQ_SET_CONFIGURATION: + { + return setup_req_std_set_configuration(p_inst, p_setup_ev); + } + case APP_USBD_SETUP_STDREQ_SET_DESCRIPTOR: + { + /*Not supported yet.*/ + break; + } + default: + /*Not supported*/ + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP event handler + * @param[in] p_inst Instance of the class + * @param[in] p_setup_ev Setup request + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_device_event_handler(app_usbd_class_inst_t const * const p_inst, + app_usbd_setup_evt_t const * const p_setup_ev) +{ + ASSERT(p_inst != NULL); + ASSERT(p_setup_ev != NULL); + + if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN) + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_in(p_inst, p_setup_ev); + default: + break; + } + } + else /*APP_USBD_SETUP_REQDIR_OUT*/ + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_out(p_inst, p_setup_ev); + default: + break; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Process SETUP command + * + * Auxiliary function for SETUP command processing + */ +static inline ret_code_t app_usbd_core_setup_req_handler(app_usbd_class_inst_t const * const p_inst, + nrf_drv_usbd_evt_t const * const p_event) +{ + app_usbd_setup_evt_t setup_ev; + ret_code_t ret = NRF_ERROR_INTERNAL; /* Final result of request processing function */ + + /* This handler have to be cleared when SETUP is entered */ + // ASSERT(!usb_core_ep0_handler_check()); + + setup_ev.type = APP_USBD_EVT_DRV_SETUP; + nrf_drv_usbd_setup_get((nrf_drv_usbd_setup_t *)&(setup_ev.setup)); + + switch (app_usbd_setup_req_rec(setup_ev.setup.bmRequestType)) + { + case APP_USBD_SETUP_REQREC_DEVICE: + { + /* Endpoint 0 has core instance (that process device requests) connected */ + ret = setup_device_event_handler(p_inst, &setup_ev); + break; + } + case APP_USBD_SETUP_REQREC_INTERFACE: + { + ret = app_usbd_iface_call( + setup_ev.setup.wIndex.lb, + (app_usbd_complex_evt_t const *)&setup_ev); + break; + } + case APP_USBD_SETUP_REQREC_ENDPOINT: + { + nrf_drv_usbd_ep_t ep = (nrf_drv_usbd_ep_t)setup_ev.setup.wIndex.w; + if (ep == NRF_DRV_USBD_EPOUT0) + { + app_usbd_class_inst_t const * const p_core_inst = app_usbd_core_instance_access(); + ret = app_usbd_endpoint_std_req_handle(p_core_inst, &setup_ev); + break; + } + + ret = app_usbd_ep_call( + (nrf_drv_usbd_ep_t)(setup_ev.setup.wIndex.lb), + (app_usbd_complex_evt_t const *)&setup_ev); + break; + } + case APP_USBD_SETUP_REQREC_OTHER: + { + /* Try to process via every instance */ + ret = app_usbd_all_until_served_call((app_usbd_complex_evt_t *)&setup_ev); + break; + } + default: + break; + } + + /* Processing result */ + if (ret == NRF_SUCCESS) + { + if (usb_core_ep0_handler_check()) + { + /* Request processed successfully and requires SETUP data */ + nrf_drv_usbd_setup_data_clear(); + } + else + { + /* Request processed successfully */ + nrf_drv_usbd_setup_clear(); + } + } + else + { + /* Request finished with error */ + nrf_drv_usbd_setup_stall(); + } + return ret; +} + +/** + * @brief Event handler for core module + * + * The event handler that would process all events directed to device. + * + */ +static ret_code_t app_usbd_core_event_handler(app_usbd_class_inst_t const * const p_inst, + app_usbd_complex_evt_t const * const p_event) +{ + ret_code_t ret = NRF_ERROR_NOT_SUPPORTED; + switch(p_event->type) + { + case APP_USBD_EVT_DRV_RESET: + { + app_usbd_state = APP_USBD_STATE_Default; + break; + } + case APP_USBD_EVT_DRV_SUSPEND: + { + ASSERT(app_usbd_state >= APP_USBD_STATE_Unattached); + app_usbd_state |= APP_USBD_STATE_SuspendedMask; + ret = NRF_SUCCESS; + break; + } + case APP_USBD_EVT_DRV_RESUME: + { + if (nrf_atomic_flag_clear_fetch(&m_rwu_pending) != 0) + { + nrf_usbd_task_trigger(NRF_USBD_TASK_NODRIVEDPDM); + } + + ASSERT(APP_USB_STATE_BASE(app_usbd_state) >= APP_USBD_STATE_Unattached); + app_usbd_state &= (app_usbd_state_t)(~APP_USBD_STATE_SuspendedMask); + ret = NRF_SUCCESS; + break; + } + case APP_USBD_EVT_DRV_SETUP: + { + ret = app_usbd_core_setup_req_handler(p_inst, &(p_event->drv_evt)); + break; + } + case APP_USBD_EVT_INST_APPEND: + { + ASSERT(app_usbd_state == APP_USBD_STATE_Disabled); + app_usbd_state = APP_USBD_STATE_Unattached; + ret = NRF_SUCCESS; + break; + } + case APP_USBD_EVT_INST_REMOVE: + { + ASSERT(app_usbd_state == APP_USBD_STATE_Unattached); + app_usbd_state = APP_USBD_STATE_Disabled; + ret = NRF_SUCCESS; + break; + } + case APP_USBD_EVT_START: + { + app_usbd_state = APP_USBD_STATE_Powered; + if (usbd_core_power_is_detected()) + { + app_usbd_state = APP_USBD_STATE_Default; + } + ret = NRF_SUCCESS; + break; + } + case APP_USBD_EVT_STOP: + { + ASSERT(APP_USB_STATE_BASE(app_usbd_state) > APP_USBD_STATE_Powered); + if (app_usbd_state & APP_USBD_STATE_SuspendedMask) + { + app_usbd_state = APP_USBD_STATE_SuspendedPowered; + } + else + { + app_usbd_state = APP_USBD_STATE_Powered; + } + ret = NRF_SUCCESS; + break; + } + /* Data transfer on endpoint 0 */ + case APP_USBD_EVT_DRV_EPTRANSFER: + { + /* This EPTRANSFER event have to be called only for EP0 */ + ASSERT((p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPOUT0) || + (p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPIN0)); + ret = usbd_core_ep0_handler_call_and_clear(p_event->drv_evt.data.eptransfer.status); + /* Processing result */ + if(ret == NRF_SUCCESS) + { + if(usb_core_ep0_handler_check()) + { + /* Request processed successfully and requires SETUP data */ + nrf_drv_usbd_setup_data_clear(); + } + else + { + /* Request processed successfully */ + nrf_drv_usbd_setup_clear(); + } + } + else + { + /* Request finished with error */ + nrf_drv_usbd_setup_stall(); + } + break; + } + default: + break; + } + + return ret; +} + +ret_code_t app_usbd_core_setup_rsp(app_usbd_setup_t const * p_setup, + void const * p_data, + size_t size) +{ + size_t req_size = p_setup->wLength.w; + size_t tx_size = MIN(req_size, size); + bool zlp_required = (size < req_size) && + (0 == (size % nrf_drv_usbd_ep_max_packet_size_get(NRF_DRV_USBD_EPIN0))); + + m_setup_zlp_required = zlp_required; + + NRF_DRV_USBD_TRANSFER_IN(transfer, p_data, tx_size); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPIN0, + &transfer, + &m_setup_zlp_desc); + if (NRF_SUCCESS == ret) + { + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPIN0, + &m_setup_data_handler_empty_desc); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +ret_code_t app_usbd_core_setup_data_handler_set( + nrf_drv_usbd_ep_t ep, + app_usbd_core_setup_data_handler_desc_t const * const p_handler_desc) +{ + if (nrf_drv_usbd_last_setup_dir_get() != ep) + { + return NRF_ERROR_INVALID_ADDR; + } + + m_ep0_handler_desc = *p_handler_desc; + return NRF_SUCCESS; +} + +ret_code_t app_usbd_core_ep_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer, + nrf_drv_usbd_transfer_handler_desc_t const * const p_handler) +{ + if (APP_USB_STATE_BASE(app_usbd_state) != APP_USBD_STATE_Configured) + { + return NRF_ERROR_INVALID_STATE; + } + return nrf_drv_usbd_ep_transfer(ep, p_transfer, p_handler); +} + +ret_code_t app_usbd_core_setup_data_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer, + nrf_drv_usbd_transfer_handler_desc_t const * const p_handler) +{ + ASSERT(0 == NRF_USBD_EP_NR_GET(ep)); + + if (!((APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Configured) || + (APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Addressed ) || + (APP_USB_STATE_BASE(app_usbd_state) == APP_USBD_STATE_Default ) )) + { + return NRF_ERROR_INVALID_STATE; + } + return nrf_drv_usbd_ep_transfer(ep, p_transfer, p_handler); +} + +void * app_usbd_core_setup_transfer_buff_get(size_t * p_size) +{ + if (p_size != NULL) + *p_size = sizeof(m_setup_transfer_buff); + + return m_setup_transfer_buff; +} + +app_usbd_state_t app_usbd_core_state_get(void) +{ + return app_usbd_state; +} + +void app_usbd_core_class_rwu_register(app_usbd_class_inst_t const * const p_inst) +{ + ASSERT(p_inst != NULL); + ++m_rwu_counter; + /*Overflow check*/ + ASSERT(m_rwu_counter != 0); +} + +void app_usbd_core_class_rwu_unregister(app_usbd_class_inst_t const * const p_inst) +{ + ASSERT(p_inst != NULL); + /* Usage validation. If counter is 0 unregister is not possible.*/ + ASSERT(m_rwu_counter != 0); + --m_rwu_counter; +} + +void app_usbd_core_class_rwu_pend(void) +{ + if (m_rwu_counter == 0) + { + /* No class registered on remote wake-up */ + return; + } + + if (IS_SET(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP) == 0) + { + /* Feature remote wake-up hasn't been set by host*/ + return; + } + + if (nrf_atomic_flag_set_fetch(&m_rwu_pending) != 0) + { + /* Remote wake-up pending */ + return; + } + + nrf_usbd_dpdmvalue_set(NRF_USBD_DPDMVALUE_RESUME); + nrf_usbd_task_trigger(NRF_USBD_TASK_DRIVEDPDM); +} + +/** @} */ +#endif // APP_USBD_ENABLED diff --git a/components/libraries/usbd/app_usbd_core.h b/components/libraries/usbd/app_usbd_core.h new file mode 100644 index 0000000..b873a44 --- /dev/null +++ b/components/libraries/usbd/app_usbd_core.h @@ -0,0 +1,276 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_CORE_H__ +#define APP_USBD_CORE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "sdk_common.h" +#include "nrf_drv_usbd.h" +#include "app_usbd_types.h" +#include "app_usbd_class_base.h" + + +/** + * @defgroup app_usbd_core USB Device high level library core module + * @ingroup app_usbd + * + * @brief @tagAPI52840 Core module that manages current USB state and process device requests. + * @{ + */ + +/** + * @brief USB Device state + * + * Possible USB Device states according to specification. + */ +typedef enum +{ + APP_USBD_STATE_Disabled = 0x00, /**< The whole USBD library is disabled */ + APP_USBD_STATE_Unattached = 0x01, /**< Device is currently not connected to the host */ + APP_USBD_STATE_Powered = 0x02, /**< Device is connected to the host but has not been enumerated */ + APP_USBD_STATE_Default = 0x03, /**< USB Reset condition detected, waiting for the address */ + APP_USBD_STATE_Addressed = 0x04, /**< Device has been addressed but have not been configured */ + APP_USBD_STATE_Configured = 0x05, /**< Device is addressed and configured */ + + APP_USBD_STATE_SuspendedMask = 0x10, /**< Mask used to mark suspended state, suspended state remembers also the target state after wake up */ + + APP_USBD_STATE_SuspendedPowered = APP_USBD_STATE_SuspendedMask | APP_USBD_STATE_Powered, /**< Device is Suspended and on wakeup it will return to Powered state */ + APP_USBD_STATE_SuspendedDefault = APP_USBD_STATE_SuspendedMask | APP_USBD_STATE_Default, /**< Device is Suspended and on wakeup it will return to Default state */ + APP_USBD_STATE_SuspendedAddressed = APP_USBD_STATE_SuspendedMask | APP_USBD_STATE_Addressed, /**< Device is Suspended and on wakeup it will return to Addressed state */ + APP_USBD_STATE_SuspendedConfigured = APP_USBD_STATE_SuspendedMask | APP_USBD_STATE_Configured /**< Device is Suspended and on wakeup it will return to Configured state */ +}app_usbd_state_t; + +/** + * @brief Remove @ref APP_USBD_STATE_SuspendedMask bit from core state + */ +#define APP_USB_STATE_BASE(state) ((state) & (~APP_USBD_STATE_SuspendedMask)) + +/** + * @brief Core interface configuration + * + * Core instance would have 2 endpoints (IN0 and OUT0). + * The interface number does not care because it would not be used. + */ +#define APP_USBD_CORE_CLASS_CONFIGURATION ((0, NRF_DRV_USBD_EPOUT0, NRF_DRV_USBD_EPIN0)) + +/** + * @brief EP0 handler function pointer + * + * Type of the variable that would hold the pointer to the handler for + * endpoint 0 messages processing. + * + * @param p_contex Context variable configured with the transmission request. + */ +typedef ret_code_t (*app_usbd_core_setup_data_handler_t)(nrf_drv_usbd_ep_status_t status, + void * p_context); + +/** + * @brief Variable type used to register EP0 transfer handler + * + * EP0 messages are processed by core instance. + * Another class can register itself to receive messages from EP0 when requesting + * for Setup data transfer. + */ +typedef struct +{ + app_usbd_core_setup_data_handler_t handler; //!< Event handler to be called when transmission is ready + void * p_context; //!< Context pointer to be send to every called event. +} app_usbd_core_setup_data_handler_desc_t; + +/*lint -save -e10 -e26 -e93 -e123 -e505 */ +/** + * @brief Declare Core instance type + * + * USBD core instance type definition. + */ +APP_USBD_CLASS_TYPEDEF(app_usbd_core, + APP_USBD_CORE_CLASS_CONFIGURATION, + APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE, + APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE); +/*lint -restore*/ + +/** + * @brief Access to core instance + * + * Function that returns pointer to the USBD core instance. + * + * @return pointer to the core instance + */ +static inline app_usbd_class_inst_t const * app_usbd_core_instance_access(void) +{ + extern const APP_USBD_CLASS_INSTANCE_TYPE(app_usbd_core) app_usbd_core_inst; + return (app_usbd_class_inst_t const *)&app_usbd_core_inst; +} + +/** + * @brief Default simple response to setup command + * + * This function generates default simple response. + * It sends ZLP when required and on takes care on allowing status stage when + * transfer is finished. + * + * @param p_setup Pointer to original setup message + * @param p_data Pointer to the response. This has to be globaly aviable data. + * @param size Total size of the answer - The function takes care about + * limiting the size of transfered data to the size required + * by setup command. + */ +ret_code_t app_usbd_core_setup_rsp(app_usbd_setup_t const * p_setup, + void const * p_data, + size_t size); + +/** + * @brief Configure the handler for the nearest setup data endpoint transfer + * + * This function would be called on incomming setup data. + * The correct place to set the handler for a data is when SETUP command + * was received. + * + * @param ep Endpoint number (only IN0 and OUT0) are supported. + * @param p_handler_desc Descriptor of the handler to be called. + * + * @retval NRF_SUCCESS Successfully configured + * @retval NRF_ERROR_INVALID_ADDR Last received setup direction does not match + * configured endpoint. + */ +ret_code_t app_usbd_core_setup_data_handler_set( + nrf_drv_usbd_ep_t ep, + app_usbd_core_setup_data_handler_desc_t const * const p_handler_desc); + +/** + * @brief Endpoint transfer + * + * @param ep Endpoint number + * @param p_transfer Description of the transfer to be performed. + * The direction of the transfer is determined by the + * endpoint number. + * @param p_handler The transfer handler - function that is called when + * transfer is going to end or overload the buffer. + * This function can prepare another buffer. + * Can be NULL if no such functionality is expected. + * + * @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow + * data transfer on the endpoint. + * + * @return Values returned by @ref nrf_drv_usbd_ep_transfer + * + * @note This function can work only if the USB is in Configured state. + * See @ref app_usbd_core_setup_data_transfer for transfers before + * device configuration is done. + * @sa app_usbd_core_setup_data_transfer + */ +ret_code_t app_usbd_core_ep_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer, + nrf_drv_usbd_transfer_handler_desc_t const * const p_handler); + +/** + * @brief Setup data transfer + * + * Function similar to @ref app_usbd_core_ep_transfer. + * The only technical diference is that it should be used with setup transfers + * that are going to be performed before device is configured. + * + * @param ep See @ref app_usbd_core_ep_transfer. + * @param p_transfer See @ref app_usbd_core_ep_transfer. + * @param p_handler See @ref app_usbd_core_ep_transfer. + * + * @return The same values like @ref app_usbd_core_ep_transfer + */ +ret_code_t app_usbd_core_setup_data_transfer( + nrf_drv_usbd_ep_t ep, + nrf_drv_usbd_transfer_t const * const p_transfer, + nrf_drv_usbd_transfer_handler_desc_t const * const p_handler); + +/** + * @brief Setup data transfer buffer + * + * Returns special internal buffer that can be used in setup transfer. + * @return Internal buffer pointer + */ +void * app_usbd_core_setup_transfer_buff_get(size_t * p_size); + + +/**@brief Return internal USBD core state + * + * @return Check @ref app_usbd_state_t to find possible USBD core states + */ +app_usbd_state_t app_usbd_core_state_get(void); + + +/** + * @brief Check current USBD regulator status + * + * @return true when regulator is ready + */ +static inline bool app_usbd_core_power_regulator_is_ready(void) +{ + return 0 != ( (NRF_POWER->USBREGSTATUS) & POWER_USBREGSTATUS_OUTPUTRDY_Msk); +} + +/** + * @brief Register class on remote wake-up feature + * @param[in] p_inst Instance of the class + */ +void app_usbd_core_class_rwu_register(app_usbd_class_inst_t const * const p_inst); + +/** + * @brief Unregister class from remote wake-up feature + * @param[in] p_inst Instance of the class + */ +void app_usbd_core_class_rwu_unregister(app_usbd_class_inst_t const * const p_inst); + +/** + * @brief Set remote wake-up pending + * */ +void app_usbd_core_class_rwu_pend(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_CORE_H__ */ diff --git a/components/libraries/usbd/app_usbd_descriptor.h b/components/libraries/usbd/app_usbd_descriptor.h new file mode 100644 index 0000000..6df1f1b --- /dev/null +++ b/components/libraries/usbd/app_usbd_descriptor.h @@ -0,0 +1,334 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_DESCRIPTOR_H__ +#define APP_USBD_DESCRIPTOR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "nrf.h" +#include "nrf_drv_usbd.h" +#include "app_usbd_langid.h" +#include "app_util_platform.h" + +/* Compiler support for anonymous unions */ +ANON_UNIONS_ENABLE + +/** + * @defgroup app_usbd_descriptor USB standard descriptors + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with types definitions used for standard descriptors. + * @{ + */ + +/** + * @brief Helper macro for translating unsigned 24 bit value to 2 byte raw descriptor + * */ +#define APP_USBD_U16_TO_RAW_DSC(val) (uint8_t)(val), \ + (uint8_t)(((val) / (256))) + +/** + * @brief Helper macro for translating unsigned 24 bit value to 3 byte raw descriptor + * */ +#define APP_USBD_U24_TO_RAW_DSC(val) (uint8_t)(val), \ + (uint8_t)(((val) / (256))), \ + (uint8_t)(((val) / (256 * 256))) + +/** + * @brief Helper macro for translating unsigned 32 bit value to 4 byte raw descriptor + * */ +#define APP_USBD_U32_TO_RAW_DSC(val) (uint8_t)(val), \ + (uint8_t)(((val) / (256))), \ + (uint8_t)(((val) / (256 * 256))) \ + (uint8_t)(((val) / (256 * 256 * 256))) +/** + * @brief Descriptor types + * + * Descriptor types used in two situations: + * - when processing @ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR SETUP request, + * the required descriptor type may be placed in wValue in HighByte. + * - As a descriptor identifier itself inside descriptor stream. + * + * According to chapter 9.6 of USB 2.0 specification, following descriptors may + * be requested directly by GetDescriptor method: + * - @ref APP_USBD_DESCRIPTOR_DEVICE + * - @ref APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER (not used for FullSpeed only device) + * - @ref APP_USBD_DESCRIPTOR_CONFIGURATION + * - @ref APP_USBD_DESCRIPTOR_STRING + */ +typedef enum +{ + APP_USBD_DESCRIPTOR_DEVICE = 1, /**< Device descriptor. */ + APP_USBD_DESCRIPTOR_CONFIGURATION = 2, /**< + * Specific configuration descriptor. + * Configuration descriptor is always followed by all the related interface + * and endpoints descriptors. + */ + APP_USBD_DESCRIPTOR_STRING = 3, /**< String descriptor. */ + APP_USBD_DESCRIPTOR_INTERFACE = 4, /**< + * Interface descriptor followed by all the related endpoints descriptors. + * + * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION. + * Cannot be accessed by GetDescriptor or SetDescriptor + */ + APP_USBD_DESCRIPTOR_ENDPOINT = 5, /**< + * Endpoint descriptor. + * + * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION. + * Cannot be accessed by GetDescriptor or SetDescriptor + */ + APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER = 6, /**< @note Not supported - used only in HighSpeed capable devices. */ + APP_USBD_DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 7, /**< @note Not supported - our USB implementation supports only one speed. */ + APP_USBD_DESCRIPTOR_INTERFACE_POWER = 8, /**< @note Not supported */ + APP_USBD_DESCRIPTOR_OTG = 9, /**< @note Not supported - Our USB have not OTG functionality */ + APP_USBD_DESCRIPTOR_DEBUG = 10, /**< Debug channel descriptor if available, can be only reached by GetDescriptor */ + APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION = 11 /**< + * Descriptor used to describe that two or more interfaces are associated to the same function. + * + * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION. + * Cannot be accessed by GetDescriptor or SetDescriptor + */ + +} app_usbd_descriptor_t; + +/* Make all descriptors packed */ +#pragma pack(push, 1) + +/** + * @brief Common descriptor header + * + * The header that we can find on the beginning of all descriptors that contains + * the descriptor length and type. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal one of @ref app_usbd_descriptor_t. + /** Class specific descriptors values are defined inside classes. */ +} app_usbd_descriptor_header_t; + +/** + * @brief Device descriptor + * + * Descriptor used for the whole device + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE. + uint16_t bcdUSB; //!< USB Specification Release Number in Binary-Coded Decimal + uint8_t bDeviceClass; //!< Device class code. + /**< If 0, each interface specifies its own class information. + * 0xFF for vendor-specific. + */ + uint8_t bDeviceSubClass; //!< Subclass code. + /**< If bDevice Class is set to value other than 0xFF, + * all values here are reserved for assignment by USB-IF. + */ + uint8_t bDeviceProtocol; //!< Subclass code. + /**< If 0, no specific protocol is defined on device basis. + * Each interface may define its own protocol then. + * If set to 0xFF, vendor-specific protocol is used. + */ + uint8_t bMaxPacketSize0; //!< Maximum packet size for endpoint zero. + uint16_t idVendor; //!< Vendor ID (Assigned by the USB-IF). + uint16_t idProduct; //!< Product ID (assigned by manufacturer). + uint16_t bcdDevice; //!< Device release number in binary-coded decimal. + uint8_t iManufacturer; //!< Index of string descriptor in describing manufacturer. + uint8_t iProduct; //!< Index of string descriptor in describing product. + uint8_t iSerialNumber; //!< Index of string descriptor in describing the device's serial number. + uint8_t bNumConfigurations; //!< Number of possible configurations. +} app_usbd_descriptor_device_t; + +/** + * @brief Attributes masks + * + * Masks used for attributes in configuration. + */ +typedef enum +{ + /** This is reserved descriptor that has always to be set */ + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_ALWAYS_SET_MASK = 1U << 7, + /** Attribute that informs that device is self powered */ + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK = 1U << 6, + /** Attribute that informs that device has Remove Wakeup functionality */ + APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_REMOTE_WAKEUP_MASK = 1U << 5 +} app_usbd_descriptor_configuration_attributes_t; + +/** + * @brief Configuration descriptor + * + * Descriptor used at the beginning of configuration response. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE. + uint16_t wTotalLength; //!< Total length of configuration data, including all descriptors returned after configuration itself. + uint8_t bNumInterfaces; //!< Number of interfaces supportedf by this configuration + uint8_t bConfigurationValue; //!< Value to use as an argument to the SetConfiguration request. + uint8_t iConfiguration; //!< Index of string descriptor describing this configuration. + uint8_t bmAttributes; //!< Configuration characteristics. + uint8_t bMaxPower; //!< Maximum power consumption. Expressed in 2 mA units. +} app_usbd_descriptor_configuration_t; + +/** + * @brief Raw descriptor - String descriptor zero + * + * String descriptor sent only as a response for GetDescriptor. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING. + uint16_t wLANGID[]; //!< The array of LANGID codes supported by the device. +} app_usbd_descriptor_string0_t; + +/** + * @brief Raw descriptor - Any normal string + * + * String descriptor sent only as a response for GetDescriptor. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING. + uint16_t bString[]; //!< UNICODE encoded string. +} app_usbd_descriptor_string_t; + + +/** + * @brief Interface descriptor + * + * Interface descriptor, returned as a part of configuration descriptor. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_INTERFACE. + uint8_t bInterfaceNumber; //!< Number of this interface. + uint8_t bAlternateSetting; //!< Value used to select this alternate setting. + uint8_t bNumEndpoints; //!< Number of endpoints used by this interface. + uint8_t bInterfaceClass; //!< Class code (assigned by the USB-IF). 0xff for vendor specific. + uint8_t bInterfaceSubClass; //!< Subclass code (assigned by the USB-IF). + uint8_t bInterfaceProtocol; //!< Protocol code (assigned by the USB-IF). 0xff for vendor specific. + uint8_t iInterface; //!< Index of string descriptor describing this interface. +} app_usbd_descriptor_iface_t; + +/** Offset of endpoint type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET 0 +/** Mask of endpoint type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET) + +/** Offset of endpoint synchronization type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET 2 +/** Mask of endpoint synchronization type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET) + +/** Offset of endpoint usage type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET 4 +/** Mask of endpoint usage type attribute bits */ +#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET) + +/** + * @brief Endpoint attributes mnemonics + * + * @sa APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK + * @sa APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK + * @sa APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK + */ +typedef enum +{ + APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_CONTROL = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET, + + APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_NONE = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ASYNCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ADAPTIVE = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_SYNCHRONOUS = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET, + + APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_DATA = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_FEEDBACK = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET, + APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_IMPLICIT = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET +} app_usbd_descriptor_ep_attr_bitmap_t; + +/** + * @brief Endpoint descriptor + * + * Endpoint descriptor, returned as a part of configuration descriptor. + */ +typedef struct +{ + uint8_t bLength; //!< Size of the descriptor in bytes. + uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_ENDPOINT. + uint8_t bEndpointAddress; //!< Endpoint address + uint8_t bmAttributes; //!< Endpoint attributes + uint16_t wMaxPacketSize; //!< Maximum packet size this endpoint is capable of handling. + uint8_t bInterval; //!< Interval for pooling endpoint for data transfers. +} app_usbd_descriptor_ep_t; + +/** + * @brief Interface association descriptor + */ +typedef struct +{ + uint8_t bLength; //!< size of this descriptor in bytes + uint8_t bDescriptorType; //!< INTERFACE descriptor type + uint8_t bFirstInterface; //!< Number of interface + uint8_t bInterfaceCount; //!< value to select alternate setting + uint8_t bFunctionClass; //!< Class code assigned by the USB + uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB + uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB + uint8_t iFunction; //!< Index of string descriptor +} app_usbd_descriptor_iad_t; + +#pragma pack(pop) +ANON_UNIONS_DISABLE + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* APP_USBD_DESCRIPTOR_H__ */ diff --git a/components/libraries/usbd/app_usbd_langid.h b/components/libraries/usbd/app_usbd_langid.h new file mode 100644 index 0000000..03c6b3f --- /dev/null +++ b/components/libraries/usbd/app_usbd_langid.h @@ -0,0 +1,285 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_LANGID_H__ +#define APP_USBD_LANGID_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file + * @brief This file contains LANGID variable type with all defined values + * + * This file was created using Language Identifiers (LANGIDs) 3/29/00 Version 1.0, + * available on USB web page: + * http://www.usb.org/developers/docs/USB_LANGIDs.pdf + * + * @note + * Do not include this file directly to the project. + * It is included by @file app_usbd_request.h. + */ + +/** + * Offset of the lowest bit of primary language identifier + * @sa app_usbd_langid_t + */ +#define APP_USB_LANG_OFFSET 0 + +/** + * Bitmask for a primary language identifier + * @sa app_usbd_langid_t + */ +#define APP_USB_LANG_MASK BF_MASK(10, APP_USB_LANG_OFFSET) + +/** + * Offset of the lowest bit of sub-language identifier + * @sa app_usbd_langid_t + */ +#define APP_USB_SUBLANG_OFFSET 10 + +/** + * Bitmask for a sub-language identifier + * @sa app_usbd_langid_t + */ +#define APP_USB_SUBLANG_MASK BF_MASK(6, APP_USB_SUBLANG_OFFSET) + +/** + * @brief Primary language identifiers + * + * Mnemonics for primary language identifiers. + * This mnemonics can be combined using logical OR operator with @ref app_usbd_langid_sub_t. + */ +typedef enum +{ + APP_USBD_LANG_ARABIC = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Arabic */ + APP_USBD_LANG_BULGARIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Bulgarian */ + APP_USBD_LANG_CATALAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Catalan */ + APP_USBD_LANG_CHINESE = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Chinese */ + APP_USBD_LANG_CZECH = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Czech */ + APP_USBD_LANG_DANISH = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Danish */ + APP_USBD_LANG_GERMAN = 0x07U << ( APP_USB_LANG_OFFSET ), /**< German */ + APP_USBD_LANG_GREEK = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Greek */ + APP_USBD_LANG_ENGLISH = 0x09U << ( APP_USB_LANG_OFFSET ), /**< English */ + APP_USBD_LANG_SPANISH = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< Spanish */ + APP_USBD_LANG_FINNISH = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< Finnish */ + APP_USBD_LANG_FRENCH = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< French */ + APP_USBD_LANG_HEBREW = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< Hebrew */ + APP_USBD_LANG_HUNGARIAN = 0x0eU << ( APP_USB_LANG_OFFSET ), /**< Hungarian */ + APP_USBD_LANG_ICELANDIC = 0x0fU << ( APP_USB_LANG_OFFSET ), /**< Icelandic */ + APP_USBD_LANG_ITALIAN = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Italian */ + APP_USBD_LANG_JAPANESE = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Japanese */ + APP_USBD_LANG_KOREAN = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Korean */ + APP_USBD_LANG_DUTCH = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Dutch */ + APP_USBD_LANG_NORWEGIAN = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Norwegian */ + APP_USBD_LANG_POLISH = 0x15U << ( APP_USB_LANG_OFFSET ), /**< Polish */ + APP_USBD_LANG_PORTUGUESE = 0x16U << ( APP_USB_LANG_OFFSET ), /**< Portuguese */ + APP_USBD_LANG_ROMANIAN = 0x18U << ( APP_USB_LANG_OFFSET ), /**< Romanian */ + APP_USBD_LANG_RUSSIAN = 0x19U << ( APP_USB_LANG_OFFSET ), /**< Russian */ + APP_USBD_LANG_CROATIAN = 0x1aU << ( APP_USB_LANG_OFFSET ), /**< Croatian */ + APP_USBD_LANG_SERBIAN = 0x1aU << ( APP_USB_LANG_OFFSET ), /**< Serbian */ + APP_USBD_LANG_SLOVAK = 0x1bU << ( APP_USB_LANG_OFFSET ), /**< Slovak */ + APP_USBD_LANG_ALBANIAN = 0x1cU << ( APP_USB_LANG_OFFSET ), /**< Albanian */ + APP_USBD_LANG_SWEDISH = 0x1dU << ( APP_USB_LANG_OFFSET ), /**< Swedish */ + APP_USBD_LANG_THAI = 0x1eU << ( APP_USB_LANG_OFFSET ), /**< Thai */ + APP_USBD_LANG_TURKISH = 0x1fU << ( APP_USB_LANG_OFFSET ), /**< Turkish */ + APP_USBD_LANG_URDU = 0x20U << ( APP_USB_LANG_OFFSET ), /**< Urdu */ + APP_USBD_LANG_INDONESIAN = 0x21U << ( APP_USB_LANG_OFFSET ), /**< Indonesian */ + APP_USBD_LANG_UKRANIAN = 0x22U << ( APP_USB_LANG_OFFSET ), /**< Ukrainian */ + APP_USBD_LANG_BELARUSIAN = 0x23U << ( APP_USB_LANG_OFFSET ), /**< Belarusian */ + APP_USBD_LANG_SLOVENIAN = 0x24U << ( APP_USB_LANG_OFFSET ), /**< Slovenian */ + APP_USBD_LANG_ESTONIAN = 0x25U << ( APP_USB_LANG_OFFSET ), /**< Estonian */ + APP_USBD_LANG_LATVIAN = 0x26U << ( APP_USB_LANG_OFFSET ), /**< Latvian */ + APP_USBD_LANG_LITHUANIAN = 0x27U << ( APP_USB_LANG_OFFSET ), /**< Lithuanian */ + APP_USBD_LANG_FARSI = 0x29U << ( APP_USB_LANG_OFFSET ), /**< Farsi */ + APP_USBD_LANG_VIETNAMESE = 0x2aU << ( APP_USB_LANG_OFFSET ), /**< Vietnamese */ + APP_USBD_LANG_ARMENIAN = 0x2bU << ( APP_USB_LANG_OFFSET ), /**< Armenian */ + APP_USBD_LANG_AZERI = 0x2cU << ( APP_USB_LANG_OFFSET ), /**< Azeri */ + APP_USBD_LANG_BASQUE = 0x2dU << ( APP_USB_LANG_OFFSET ), /**< Basque */ + APP_USBD_LANG_MACEDONIAN = 0x2fU << ( APP_USB_LANG_OFFSET ), /**< Macedonian */ + APP_USBD_LANG_AFRIKAANS = 0x36U << ( APP_USB_LANG_OFFSET ), /**< Afrikaans */ + APP_USBD_LANG_GEORGIAN = 0x37U << ( APP_USB_LANG_OFFSET ), /**< Georgian */ + APP_USBD_LANG_FAEROESE = 0x38U << ( APP_USB_LANG_OFFSET ), /**< Faeroese */ + APP_USBD_LANG_HINDI = 0x39U << ( APP_USB_LANG_OFFSET ), /**< Hindi */ + APP_USBD_LANG_MALAY = 0x3eU << ( APP_USB_LANG_OFFSET ), /**< Malay */ + APP_USBD_LANG_KAZAK = 0x3fU << ( APP_USB_LANG_OFFSET ), /**< Kazak */ + APP_USBD_LANG_SWAHILI = 0x41U << ( APP_USB_LANG_OFFSET ), /**< Swahili */ + APP_USBD_LANG_UZBEK = 0x43U << ( APP_USB_LANG_OFFSET ), /**< Uzbek */ + APP_USBD_LANG_TATAR = 0x44U << ( APP_USB_LANG_OFFSET ), /**< Tatar */ + APP_USBD_LANG_BENGALI = 0x45U << ( APP_USB_LANG_OFFSET ), /**< Bengali */ + APP_USBD_LANG_PUNJABI = 0x46U << ( APP_USB_LANG_OFFSET ), /**< Punjabi */ + APP_USBD_LANG_GUJARATI = 0x47U << ( APP_USB_LANG_OFFSET ), /**< Gujarati */ + APP_USBD_LANG_ORIYA = 0x48U << ( APP_USB_LANG_OFFSET ), /**< Oriya */ + APP_USBD_LANG_TAMIL = 0x49U << ( APP_USB_LANG_OFFSET ), /**< Tamil */ + APP_USBD_LANG_TELUGU = 0x4aU << ( APP_USB_LANG_OFFSET ), /**< Telugu */ + APP_USBD_LANG_KANNADA = 0x4bU << ( APP_USB_LANG_OFFSET ), /**< Kannada */ + APP_USBD_LANG_MALAYALAM = 0x4cU << ( APP_USB_LANG_OFFSET ), /**< Malayalam */ + APP_USBD_LANG_ASSAMESE = 0x4dU << ( APP_USB_LANG_OFFSET ), /**< Assamese */ + APP_USBD_LANG_MARATHI = 0x4eU << ( APP_USB_LANG_OFFSET ), /**< Marathi */ + APP_USBD_LANG_SANSKRIT = 0x4fU << ( APP_USB_LANG_OFFSET ), /**< Sanskrit */ + APP_USBD_LANG_KONKANI = 0x57U << ( APP_USB_LANG_OFFSET ), /**< Konkani */ + APP_USBD_LANG_MANIPURI = 0x58U << ( APP_USB_LANG_OFFSET ), /**< Manipuri */ + APP_USBD_LANG_SINDHI = 0x59U << ( APP_USB_LANG_OFFSET ), /**< Sindhi */ + APP_USBD_LANG_KASHMIRI = 0x60U << ( APP_USB_LANG_OFFSET ), /**< Kashmiri */ + APP_USBD_LANG_NEPALI = 0x61U << ( APP_USB_LANG_OFFSET ), /**< Nepali */ + APP_USBD_LANG_HID = 0xffU << ( APP_USB_LANG_OFFSET ), /**< Reserved for USB HID Class use */ +}app_usbd_langid_primary_t; + +/** + * @brief Sublanguage identifiers + * + * Mnemonics with sublanguage values. + * Use them in combination with @ref app_usbd_langid_primary_t. + */ +typedef enum +{ + APP_USBD_SUBLANG_ARABIC_SAUDI_ARABIA = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Saudi Arabia) */ + APP_USBD_SUBLANG_ARABIC_IRAQ = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Iraq) */ + APP_USBD_SUBLANG_ARABIC_EGYPT = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Egypt) */ + APP_USBD_SUBLANG_ARABIC_LIBYA = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Libya) */ + APP_USBD_SUBLANG_ARABIC_ALGERIA = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Algeria) */ + APP_USBD_SUBLANG_ARABIC_MOROCCO = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Morocco) */ + APP_USBD_SUBLANG_ARABIC_TUNISIA = 0x07U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Tunisia) */ + APP_USBD_SUBLANG_ARABIC_OMAN = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Oman) */ + APP_USBD_SUBLANG_ARABIC_YEMEN = 0x09U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Yemen) */ + APP_USBD_SUBLANG_ARABIC_SYRIA = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Syria) */ + APP_USBD_SUBLANG_ARABIC_JORDAN = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Jordan) */ + APP_USBD_SUBLANG_ARABIC_LEBANON = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Lebanon) */ + APP_USBD_SUBLANG_ARABIC_KUWAIT = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Kuwait) */ + APP_USBD_SUBLANG_ARABIC_UAE = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Arabic (U.A.E.) */ + APP_USBD_SUBLANG_ARABIC_BAHRAIN = 0x15U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Bahrain) */ + APP_USBD_SUBLANG_ARABIC_QATAR = 0x16U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Qatar) */ + APP_USBD_SUBLANG_AZERI_CYRILLIC = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Azeri (Cyrillic) */ + APP_USBD_SUBLANG_AZERI_LATIN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Azeri (Latin) */ + APP_USBD_SUBLANG_CHINESE_TRADITIONAL = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Traditional) */ + APP_USBD_SUBLANG_CHINESE_SIMPLIFIED = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Simplified) */ + APP_USBD_SUBLANG_CHINESE_HONGKONG = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Hong Kong SAR, PRC) */ + APP_USBD_SUBLANG_CHINESE_SINGAPORE = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Singapore) */ + APP_USBD_SUBLANG_CHINESE_MACAU = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Macau SAR) */ + APP_USBD_SUBLANG_DUTCH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Dutch */ + APP_USBD_SUBLANG_DUTCH_BELGIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Dutch (Belgian) */ + APP_USBD_SUBLANG_ENGLISH_US = 0x01U << ( APP_USB_LANG_OFFSET ), /**< English (US) */ + APP_USBD_SUBLANG_ENGLISH_UK = 0x02U << ( APP_USB_LANG_OFFSET ), /**< English (UK) */ + APP_USBD_SUBLANG_ENGLISH_AUS = 0x03U << ( APP_USB_LANG_OFFSET ), /**< English (Australian) */ + APP_USBD_SUBLANG_ENGLISH_CAN = 0x04U << ( APP_USB_LANG_OFFSET ), /**< English (Canadian) */ + APP_USBD_SUBLANG_ENGLISH_NZ = 0x05U << ( APP_USB_LANG_OFFSET ), /**< English (New Zealand) */ + APP_USBD_SUBLANG_ENGLISH_EIRE = 0x06U << ( APP_USB_LANG_OFFSET ), /**< English (Ireland) */ + APP_USBD_SUBLANG_ENGLISH_SOUTH_AFRICA = 0x07U << ( APP_USB_LANG_OFFSET ), /**< English (South Africa) */ + APP_USBD_SUBLANG_ENGLISH_JAMAICA = 0x08U << ( APP_USB_LANG_OFFSET ), /**< English (Jamaica) */ + APP_USBD_SUBLANG_ENGLISH_CARIBBEAN = 0x09U << ( APP_USB_LANG_OFFSET ), /**< English (Caribbean) */ + APP_USBD_SUBLANG_ENGLISH_BELIZE = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< English (Belize) */ + APP_USBD_SUBLANG_ENGLISH_TRINIDAD = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< English (Trinidad) */ + APP_USBD_SUBLANG_ENGLISH_PHILIPPINES = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< English (Zimbabwe) */ + APP_USBD_SUBLANG_ENGLISH_ZIMBABWE = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< English (Philippines) */ + APP_USBD_SUBLANG_FRENCH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< French */ + APP_USBD_SUBLANG_FRENCH_BELGIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< French (Belgian) */ + APP_USBD_SUBLANG_FRENCH_CANADIAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< French (Canadian) */ + APP_USBD_SUBLANG_FRENCH_SWISS = 0x04U << ( APP_USB_LANG_OFFSET ), /**< French (Swiss) */ + APP_USBD_SUBLANG_FRENCH_LUXEMBOURG = 0x05U << ( APP_USB_LANG_OFFSET ), /**< French (Luxembourg) */ + APP_USBD_SUBLANG_FRENCH_MONACO = 0x06U << ( APP_USB_LANG_OFFSET ), /**< French (Monaco) */ + APP_USBD_SUBLANG_GERMAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< German */ + APP_USBD_SUBLANG_GERMAN_SWISS = 0x02U << ( APP_USB_LANG_OFFSET ), /**< German (Swiss) */ + APP_USBD_SUBLANG_GERMAN_AUSTRIAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< German (Austrian) */ + APP_USBD_SUBLANG_GERMAN_LUXEMBOURG = 0x04U << ( APP_USB_LANG_OFFSET ), /**< German (Luxembourg) */ + APP_USBD_SUBLANG_GERMAN_LIECHTENSTEIN = 0x05U << ( APP_USB_LANG_OFFSET ), /**< German (Liechtenstein) */ + APP_USBD_SUBLANG_ITALIAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Italian */ + APP_USBD_SUBLANG_ITALIAN_SWISS = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Italian (Swiss) */ + APP_USBD_SUBLANG_KASHMIRI_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Kashmiri (India) */ + APP_USBD_SUBLANG_KOREAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Korean */ + APP_USBD_SUBLANG_LITHUANIAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Lithuanian */ + APP_USBD_SUBLANG_MALAY_MALAYSIA = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Malay (Malaysia) */ + APP_USBD_SUBLANG_MALAY_BRUNEI_DARUSSALAM = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Malay (Brunei Darassalam) */ + APP_USBD_SUBLANG_NEPALI_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Nepali (India) */ + APP_USBD_SUBLANG_NORWEGIAN_BOKMAL = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Norwegian (Bokmal) */ + APP_USBD_SUBLANG_NORWEGIAN_NYNORSK = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Norwegian (Nynorsk) */ + APP_USBD_SUBLANG_PORTUGUESE = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Portuguese (Brazilian) */ + APP_USBD_SUBLANG_PORTUGUESE_BRAZILIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Portuguese */ + APP_USBD_SUBLANG_SERBIAN_LATIN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Serbian (Latin) */ + APP_USBD_SUBLANG_SERBIAN_CYRILLIC = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Serbian (Cyrillic) */ + APP_USBD_SUBLANG_SPANISH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Castilian) */ + APP_USBD_SUBLANG_SPANISH_MEXICAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Mexican) */ + APP_USBD_SUBLANG_SPANISH_MODERN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Modern) */ + APP_USBD_SUBLANG_SPANISH_GUATEMALA = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Guatemala) */ + APP_USBD_SUBLANG_SPANISH_COSTA_RICA = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Costa Rica) */ + APP_USBD_SUBLANG_SPANISH_PANAMA = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Panama) */ + APP_USBD_SUBLANG_SPANISH_DOMINICAN_REPUBLIC = 0x07U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Dominican Republic) */ + APP_USBD_SUBLANG_SPANISH_VENEZUELA = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Venezuela) */ + APP_USBD_SUBLANG_SPANISH_COLOMBIA = 0x09U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Colombia) */ + APP_USBD_SUBLANG_SPANISH_PERU = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Peru) */ + APP_USBD_SUBLANG_SPANISH_ARGENTINA = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Argentina) */ + APP_USBD_SUBLANG_SPANISH_ECUADOR = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Ecuador) */ + APP_USBD_SUBLANG_SPANISH_CHILE = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Chile) */ + APP_USBD_SUBLANG_SPANISH_URUGUAY = 0x0eU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Uruguay) */ + APP_USBD_SUBLANG_SPANISH_PARAGUAY = 0x0fU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Paraguay) */ + APP_USBD_SUBLANG_SPANISH_BOLIVIA = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Bolivia) */ + APP_USBD_SUBLANG_SPANISH_EL_SALVADOR = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Spanish (El Salvador) */ + APP_USBD_SUBLANG_SPANISH_HONDURAS = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Honduras) */ + APP_USBD_SUBLANG_SPANISH_NICARAGUA = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Nicaragua) */ + APP_USBD_SUBLANG_SPANISH_PUERTO_RICO = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Puerto Rico) */ + APP_USBD_SUBLANG_SWEDISH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Swedish */ + APP_USBD_SUBLANG_SWEDISH_FINLAND = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Swedish (Finland) */ + APP_USBD_SUBLANG_URDU_PAKISTAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Urdu (Pakistan) */ + APP_USBD_SUBLANG_URDU_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Urdu (India) */ + APP_USBD_SUBLANG_UZBEK_LATIN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Uzbek (Latin) */ + APP_USBD_SUBLANG_UZBEK_CYRILLIC = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Uzbek (Cyrillic) */ + APP_USBD_SUBLANG_HID_USAGE_DATA_DESCRIPTOR = 0x01U << ( APP_USB_LANG_OFFSET ), /**< HID (Usage Data Descriptor) */ + APP_USBD_SUBLANG_HID_VENDOR_DEFINED_1 = 0x3cU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 1) */ + APP_USBD_SUBLANG_HID_VENDOR_DEFINED_2 = 0x3dU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 2) */ + APP_USBD_SUBLANG_HID_VENDOR_DEFINED_3 = 0x3eU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 3) */ + APP_USBD_SUBLANG_HID_VENDOR_DEFINED_4 = 0x3fU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 4) */ +}app_usbd_langid_sub_t; + +/** + * @brief LANGID variable + * + * The LANGID value is composed from: + * - 10-bit (9-0) of Primary Language Identifiers + * - 6-bit (15-10) of Sublanguage Identifiers. + * + * @sa app_usbd_langid_primary_t + * @sa app_usbd_langid_sub_t + */ +typedef uint16_t app_usbd_langid_t; + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_LANGID_H__ */ diff --git a/components/libraries/usbd/app_usbd_request.h b/components/libraries/usbd/app_usbd_request.h new file mode 100644 index 0000000..1ac7591 --- /dev/null +++ b/components/libraries/usbd/app_usbd_request.h @@ -0,0 +1,354 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_REQUEST_H__ +#define APP_USBD_REQUEST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdk_common.h" +#include "nrf.h" +#include "nrf_drv_usbd.h" +#include "app_usbd_descriptor.h" +#include "app_util_platform.h" + +/* Compiler support for anonymous unions */ +ANON_UNIONS_ENABLE + +#pragma pack(push, 1) + +/** + * @defgroup app_usbd_request USB standard requests + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with types definitions used for standard requests processing. + * @{ + */ + +/** + * @brief Recipient bit-field in request type + * + * Bits 4...0 + */ +#define APP_USBD_SETUP_REQ_BF_REC BF_CX(5, 0) + +/** + * @brief Type bit-field in request type + * + * Bits 6...5 + */ +#define APP_USBD_SETUP_REQ_BF_TYP BF_CX(2, 5) + +/** + * @brief Direction bit-field in request type + * + * Bit 7 + */ +#define APP_USBD_SETUP_REQ_BF_DIR BF_CX(1, 7) + +/** + * @brief Recipient enumerator. + * + * @note It is part of @ref app_usbd_setup_reqtype_t variable type. + */ +typedef enum { + APP_USBD_SETUP_REQREC_DEVICE = 0x0, /**< The whole device is a request target */ + APP_USBD_SETUP_REQREC_INTERFACE = 0x1, /**< Selected interface is a request target */ + APP_USBD_SETUP_REQREC_ENDPOINT = 0x2, /**< Selected endpoint is a request target */ + APP_USBD_SETUP_REQREC_OTHER = 0x3 /**< Other element is a request target */ +} app_usbd_setup_reqrec_t; + +/** + * @brief Request type enumerator. + * + * @note It is part of @ref app_usbd_setup_reqtype_t variable type. + */ +typedef enum { + APP_USBD_SETUP_REQTYPE_STD = 0x0, /**< Standard request */ + APP_USBD_SETUP_REQTYPE_CLASS = 0x1, /**< Class specific request */ + APP_USBD_SETUP_REQTYPE_VENDOR = 0x2 /**< Vendor specific request */ +} app_usbd_setup_reqtype_t; + +/** + * @brief Direction of setup command + * + * @note It is part of @ref app_usbd_setup_reqtype_t variable type. + */ +typedef enum { + APP_USBD_SETUP_REQDIR_OUT = 0x0, /**< Host to device */ + APP_USBD_SETUP_REQDIR_IN = 0x1, /**< Device to host */ +} app_usbd_setup_reqdir_t; + + +/** + * @brief Standard requests + * + * Enumerator for standard requests values + */ +typedef enum { + APP_USBD_SETUP_STDREQ_GET_STATUS = 0x00, /**< + * Targets: Device, Interface, Endpoint + * Expected SETUP frame format: + * - wValue: Zero + * - wIndex: Zero, (lb): Interface or Endpoint + * - wLength: 2 + * - Data:2 bytes of data, depending on targets + * - Device: + * - D15..D2: Reserved (Reset to zero) + * - D1: Remove Wakeup + * - D0: Self Powered + * - Interface: + * - D15..D0: Reserved (Reset to zero) + * - Endpoint: + * - D15..D1: Reserved (Reset to zero) + * - D0: Halt + */ + APP_USBD_SETUP_STDREQ_CLEAR_FEATURE = 0x01, /**< + * Targets: Device, Interface, Endpoint + * Expected SETUP frame format: + * - wValue: Feature selector (@ref app_usbd_setup_stdfeature_t) + * - wIndex: Zero, Interface or Endpoint + * - wLength: 0 + * - Data: None + */ + APP_USBD_SETUP_STDREQ_SET_FEATURE = 0x03, /**< + * Targets: Device, Interface, Endpoint + * Expected SETUP frame format: + * - wValue: Feature selector (@ref app_usbd_setup_stdfeature_t) + * - wIndex: Zero, Interface or Endpoint + * - wLength: 0 + * - Data: None + */ + APP_USBD_SETUP_STDREQ_SET_ADDRESS = 0x05, /**< + * @note This SETUP request is processed in hardware. + * Use it only to mark current USB state. + * + * Targets: Device + * Expected SETUP frame format: + * - wValue: New device address + * - wIndex: 0 + * - wLength: 0 + * - Data: None + */ + APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR = 0x06, /**< + * Targets: Device + * - wValue: (hb): Descriptor Type and (lb): Descriptor Index + * - wIndex: Zero of Language ID + * - wLength: Descriptor Length + * - Data: Descriptor + */ + APP_USBD_SETUP_STDREQ_SET_DESCRIPTOR = 0x07, /**< + * Not supported - Stall when called. + */ + APP_USBD_SETUP_STDREQ_GET_CONFIGURATION = 0x08, /**< + * Target: Device + * Expected SETUP frame format: + * - wValue: 0 + * - wIndex: 0 + * - wLength: 1 + * - Data: Configuration value + */ + APP_USBD_SETUP_STDREQ_SET_CONFIGURATION = 0x09, /**< + * Target: Device + * Expected SETUP frame format: + * - wValue: (lb): Configuration value + * - wIndex: 0 + * - wLength: 0 + * - Data: None + */ + APP_USBD_SETUP_STDREQ_GET_INTERFACE = 0x0A, /**< + * Target: Interface + * Expected SETUP frame format: + * - wValue: 0 + * - wIndex: Interface + * - wLength: 1 + * - Data: Alternate setting + */ + APP_USBD_SETUP_STDREQ_SET_INTERFACE = 0x0B, /**< + * Target: Interface + * Expected SETUP frame format: + * - wValue: Alternate setting + * - wIndex: Interface + * - wLength: 0 + * - Data: None + */ + APP_USBD_SETUP_STDREQ_SYNCH_FRAME = 0x0C /**< + * Target: Endpoint + * Expected SETUP frame format: + * - wValue: 0 + * - wIndex: Endpoint + * - wLength: 2 + * - Data: Frame Number + * + * @note + * This request is used only in connection with isochronous endpoints. + * This is rarely used and probably we would not need to support it. + */ +} app_usbd_setup_stdrequest_t; + +/** + * @brief Standard feature selectors + * + * Standard features that may be disabled or enabled by + * @ref APP_USBD_SETUP_STDREQ_CLEAR_FEATURE or @ref APP_USBD_SETUP_STDREQ_SET_FEATURE + */ +typedef enum { + APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP = 1, /**< Remote wakeup feature. + * + * Target: Device only + */ + APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT = 0, /**< Stall or clear the endpoint. + * + * Target: Endpoint different than default (0) + */ + APP_USBD_SETUP_STDFEATURE_TEST_MODE = 2 /**< Upstream port test mode. + * Power has to be cycled to exit test mode. + * This feature cannot be cleared. + * + * Target: Device only + * + * @note + * It should only be supported by HighSpeed capable devices. + * Not supported in this library. + */ +} app_usbd_setup_stdfeature_t; + + +/** + * @brief Universal way to access 16 bit values and its parts + */ +typedef union { + uint16_t w; //!< 16 bit access + struct + { + uint8_t lb; //!< Low byte access + uint8_t hb; //!< High byte access + }; +} app_usbd_setup_w_t; + +/** + * @brief Internal redefinition of setup structure + * + * Redefinition of the structure to simplify changes in the future + * if required - app_usbd API would present setup data using app_usbd_setup_t. + * + * The structure layout is always the same like @ref nrf_drv_usbd_setup_t + */ +typedef struct { + uint8_t bmRequestType; //!< Setup type bitfield + uint8_t bmRequest; //!< One of @ref app_usbd_setup_stdrequest_t values or class dependent one. + app_usbd_setup_w_t wValue; //!< byte 2, 3 + app_usbd_setup_w_t wIndex; //!< byte 4, 5 + app_usbd_setup_w_t wLength; //!< byte 6, 7 +} app_usbd_setup_t; + +#pragma pack(pop) + + +/** + * @brief Extract recipient from request type + * + * @param[in] bmRequestType + * + * @return Extracted recipient field from request type value + */ +static inline app_usbd_setup_reqrec_t app_usbd_setup_req_rec(uint8_t bmRequestType) +{ + return (app_usbd_setup_reqrec_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_REC); +} + +/** + * @brief Extract type from request type + * + * @param[in] bmRequestType + * + * @return Extracted type field from request type value + */ +static inline app_usbd_setup_reqtype_t app_usbd_setup_req_typ(uint8_t bmRequestType) +{ + return (app_usbd_setup_reqtype_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_TYP); +} + + +/** + * @brief Extract direction from request type + * + * @param[in] bmRequestType + * + * @return Extracted direction field from request type value + */ +static inline app_usbd_setup_reqdir_t app_usbd_setup_req_dir(uint8_t bmRequestType) +{ + return (app_usbd_setup_reqdir_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_DIR); +} + +/** + * @brief Make request type value + * + * @param[in] rec Recipient + * @param[in] typ Request type + * @param[in] dir Direction + * + * @return Assembled request type value + */ +static inline uint8_t app_usbd_setup_req_val(app_usbd_setup_reqrec_t rec, + app_usbd_setup_reqtype_t typ, + app_usbd_setup_reqdir_t dir) +{ + uint32_t bmRequestType = ( + BF_CX_VAL(rec, APP_USBD_SETUP_REQ_BF_REC) | + BF_CX_VAL(typ, APP_USBD_SETUP_REQ_BF_TYP) | + BF_CX_VAL(dir, APP_USBD_SETUP_REQ_BF_DIR) + ); + + ASSERT(bmRequestType < 256U); + return (uint8_t)bmRequestType; +} + + +ANON_UNIONS_DISABLE +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_REQUEST_H__ */ diff --git a/components/libraries/usbd/app_usbd_string_desc.c b/components/libraries/usbd/app_usbd_string_desc.c new file mode 100644 index 0000000..f9fad43 --- /dev/null +++ b/components/libraries/usbd/app_usbd_string_desc.c @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_ENABLED +#include "app_usbd_string_desc.h" +#include "app_usbd_langid.h" +#include "app_usbd_core.h" +#include "nordic_common.h" + +/** + * @defgroup app_usbd_string_desc + * @ingroup app_usbd + * + * USBD string descriptors management + * @{ + */ + +/** + * @brief Array with language identifiers + * + * This array would be used to search the proper string for selected language. + */ +static const uint16_t m_langids[] = { APP_USBD_STRINGS_LANGIDS }; + +/** + * @brief Language ID descriptor + * + * Language + */ + + +/** + * @brief Mnemonics for the string positions in the array + * + * The mnemonics for the indexes of the strings inside the string array. + */ +enum { + APP_USBD_STRING_ID_LANGIDS_ARRAY_POS = 0, /**< Supported language identifiers */ + APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS, /**< Manufacturer name */ + APP_USBD_STRING_ID_PRODUCT_ARRAY_POS, /**< Product name */ + APP_USBD_STRING_ID_SERIAL_ARRAY_POS, /**< Serial number */ +#define X(mnemonic, str_idx, ...) CONCAT_2(mnemonic, _ARRAY_POS), + APP_USBD_STRINGS_USER +#undef X +}; + +/** + * @brief String index into internal array index conversion table + * + * The array that transforms the USB string indexes into internal array position. + * @note Value 0 used to mark non-existing string. + */ +static const uint8_t m_string_translation[APP_USBD_STRING_ID_CNT] = +{ + [APP_USBD_STRING_ID_LANGIDS ] = APP_USBD_STRING_ID_LANGIDS_ARRAY_POS, + [APP_USBD_STRING_ID_MANUFACTURER] = APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS, + [APP_USBD_STRING_ID_PRODUCT ] = APP_USBD_STRING_ID_PRODUCT_ARRAY_POS, + [APP_USBD_STRING_ID_SERIAL ] = APP_USBD_STRING_ID_SERIAL_ARRAY_POS, +#define X(mnemonic, str_idx, ...) [mnemonic] = CONCAT_2(mnemonic, _ARRAY_POS), + APP_USBD_STRINGS_USER +#undef X +}; + +#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN +#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0 +#endif + +#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN +#define APP_USBD_STRINGS_PRODUCT_EXTERN 0 +#endif + +#ifndef APP_USBD_STRING_SERIAL_EXTERN +#define APP_USBD_STRING_SERIAL_EXTERN 0 +#endif + +#if APP_USBD_STRINGS_MANUFACTURER_EXTERN +extern uint16_t APP_USBD_STRINGS_MANUFACTURER[]; +#endif + +#if APP_USBD_STRINGS_PRODUCT_EXTERN +extern uint16_t APP_USBD_STRINGS_PRODUCT[]; +#endif + +#if APP_USBD_STRING_SERIAL_EXTERN +extern uint16_t APP_USBD_STRING_SERIAL[]; +#endif + + +/** + * @brief String descriptors table + * */ +static const uint16_t * m_string_dsc[APP_USBD_STRING_ID_CNT][ARRAY_SIZE(m_langids)] = +{ + [APP_USBD_STRING_ID_LANGIDS_ARRAY_POS] = { APP_USBD_STRING_DESC(APP_USBD_STRINGS_LANGIDS) }, + [APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS] = { APP_USBD_STRINGS_MANUFACTURER }, + [APP_USBD_STRING_ID_PRODUCT_ARRAY_POS] = { APP_USBD_STRINGS_PRODUCT }, + [APP_USBD_STRING_ID_SERIAL_ARRAY_POS] = { APP_USBD_STRING_SERIAL }, +#define X(mnemonic, str_idx, ...) [CONCAT_2(mnemonic, _ARRAY_POS)] = { __VA_ARGS__ }, + APP_USBD_STRINGS_USER +#undef X +}; + + + +uint16_t const * app_usbd_string_desc_get(app_usbd_string_desc_idx_t idx, uint16_t langid) +{ + /* LANGID string */ + if (APP_USBD_STRING_ID_LANGIDS == idx) + { + return m_string_dsc[APP_USBD_STRING_ID_LANGIDS_ARRAY_POS][0]; + } + + /* Searching for the language */ + uint8_t lang_idx = 0; + if (ARRAY_SIZE(m_langids) > 1) + { + while(m_langids[lang_idx] != langid) + { + if(++lang_idx >= ARRAY_SIZE(m_langids)) + { + return NULL; + } + } + } + + /* Get the string index in array */ + if (idx >= ARRAY_SIZE(m_string_translation)) + { + return NULL; + } + + uint8_t str_pos = m_string_translation[idx]; + if (str_pos == 0) + { + return NULL; + } + + uint16_t const * p_str = m_string_dsc[str_pos][lang_idx]; + if ((ARRAY_SIZE(m_langids) > 1) && (lang_idx != 0)) + { + if (p_str == NULL) + { + p_str = m_string_dsc[str_pos][0]; + } + } + + return p_str; +} + +/** @} */ +#endif // APP_USBD_ENABLED diff --git a/components/libraries/usbd/app_usbd_string_desc.h b/components/libraries/usbd/app_usbd_string_desc.h new file mode 100644 index 0000000..a0184b8 --- /dev/null +++ b/components/libraries/usbd/app_usbd_string_desc.h @@ -0,0 +1,120 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_STRING_DESC_H__ +#define APP_USBD_STRING_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "sdk_common.h" +#include "app_usbd.h" +#include "app_usbd_string_config.h" + +/** + * @defgroup app_usbd_string_desc USBD string descriptors + * @ingroup app_usbd + * + * @brief @tagAPI52840 USBD string descriptors management. + * @{ + */ + +/** + * @brief USB string initialization + * + * Macro that creates initialization values for USB string. + * The format contains header and string itself. + * The string should be declared as an array of uint16_t type. + * + * @param[in] ... Comma separated string letters or language ID. + * @return String descriptor initialization data. + */ +#define APP_USBD_STRING_DESC(...) (const uint16_t[]){ \ + (0xff & (sizeof((uint16_t[]){__VA_ARGS__}) + 2)) | \ + ((uint16_t)APP_USBD_DESCRIPTOR_STRING) << 8, \ + __VA_ARGS__ } + +/** + * @brief USB string descriptors ID's + */ +typedef enum { + APP_USBD_STRING_ID_LANGIDS = 0, /**< Supported language identifiers */ + APP_USBD_STRING_ID_MANUFACTURER, /**< Manufacturer name */ + APP_USBD_STRING_ID_PRODUCT, /**< Product name */ + APP_USBD_STRING_ID_SERIAL, /**< Serial number */ + +#define X(mnemonic, str_idx, ...) mnemonic str_idx, + APP_USBD_STRINGS_USER +#undef X + + APP_USBD_STRING_ID_CNT /**< Total number of identifiers */ +} app_usbd_string_desc_idx_t; + +/** + * @brief Get string descriptor + * + * @param[in] idx String descriptor index + * @param[in] langid Selected language for the string + * @return String descriptor or NULL if not exist + * */ +uint16_t const * app_usbd_string_desc_get(app_usbd_string_desc_idx_t idx, uint16_t langid); + +/** + * @brief Get string length + * + * Function to get string length from descriptor (descriptor returned by @ref app_usbd_string_desc_get) + * + * @param[in] p_str String descriptor pointer + * @return Total descriptor length in bytes + */ +static inline size_t app_usbd_string_desc_length(uint16_t const * p_str) +{ + return ((const app_usbd_descriptor_string_t *)p_str)->bLength; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_STRING_DESC_H__ */ diff --git a/components/libraries/usbd/app_usbd_types.h b/components/libraries/usbd/app_usbd_types.h new file mode 100644 index 0000000..b17baed --- /dev/null +++ b/components/libraries/usbd/app_usbd_types.h @@ -0,0 +1,174 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_TYPES_H__ +#define APP_USBD_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "sdk_errors.h" +#include "nrf_drv_usbd.h" +#include "app_usbd_request.h" + +/** + * @defgroup app_usbd_types USB Device high level library variable types definition + * @ingroup app_usbd + * + * @brief @tagAPI52840 All types used by @ref app_usbd are defined here. + * This helps to avoid cross referencing into types in different files. + * @{ + */ + +/** + * @brief Events codes + * + * Redefined application event codes + */ +typedef enum +{ + APP_USBD_EVT_DRV_SOF = NRF_DRV_USBD_EVT_SOF, /**< See documentation for @ref NRF_DRV_USBD_EVT_SOF */ + APP_USBD_EVT_DRV_RESET = NRF_DRV_USBD_EVT_RESET, /**< See documentation for @ref NRF_DRV_USBD_EVT_RESET */ + APP_USBD_EVT_DRV_SUSPEND = NRF_DRV_USBD_EVT_SUSPEND, /**< See documentation for @ref NRF_DRV_USBD_EVT_SUSPEND */ + APP_USBD_EVT_DRV_RESUME = NRF_DRV_USBD_EVT_RESUME, /**< See documentation for @ref NRF_DRV_USBD_EVT_RESUME */ + APP_USBD_EVT_DRV_SETUP = NRF_DRV_USBD_EVT_SETUP, /**< This event type has special structure. See @ref app_usbd_setup_evt_t */ + APP_USBD_EVT_DRV_EPTRANSFER = NRF_DRV_USBD_EVT_EPTRANSFER, /**< See documentation for @ref NRF_DRV_USBD_EVT_EPTRANSFER */ + + APP_USBD_EVT_FIRST_APP, /**< First application event code - for internal static assert checking */ + + APP_USBD_EVT_INST_APPEND = APP_USBD_EVT_FIRST_APP, /**< The instance was attached to the library, any configuration action can be done now */ + APP_USBD_EVT_INST_REMOVE, /**< The instance is going to be removed, this event is called just before removing the instance. + * This removing cannot be stopped. */ + APP_USBD_EVT_START, /**< USBD library has just been started and functional - event passed to all instances, before USBD interrupts have been enabled */ + APP_USBD_EVT_STOP, /**< USBD library has just been stopped and is not functional - event passed to all instances, after USBD interrupts have been disabled*/ + APP_USBD_EVT_STATE /**< USBD state has been changed */ +} app_usbd_event_type_t; + +/** + * @brief Specific application event structure + * + * All the data required by the events that comes from the application level + */ +typedef struct +{ + app_usbd_event_type_t type; //!< Event type +} app_usbd_evt_t; + +/** + * @brief Specific application event structure with setup structure included + * + * This event structure would be used when @ref APP_USBD_EVT_DRV_SETUP + * is passed to instance event handler + */ +typedef struct +{ + app_usbd_event_type_t type; //!< Event type + app_usbd_setup_t setup; //!< Setup structure +} app_usbd_setup_evt_t; + + +/** + * @brief Complex event variable type + * + * A variable that can store any kind of event. + */ +typedef union +{ + app_usbd_event_type_t type; //!< Event type + nrf_drv_usbd_evt_t drv_evt; //!< Events that comes directly from the driver. + /**< Use this event structure only for event + * type < @ref APP_USBD_EVT_FIRST_APP + */ + app_usbd_setup_evt_t setup_evt; //!< Event structure with SETUP structure included. + /**< This structure is used in connection with + * @ref APP_USBD_EVT_DRV_SETUP + */ + app_usbd_evt_t app_evt; //!< Events that comes from the application driver. + /**< Use this event structure only for event + * type >= @ref APP_USBD_EVT_FIRST_APP + */ + +} app_usbd_complex_evt_t; + + +#ifdef DOXYGEN +/** + * @brief Base instance of a USBD class + * + * Any USBD class instance have to begin with this instance. + * This may then be followed by any implementation dependent data. + * + * For an instance it should be possible to put whole structure into FLASH. + * + * @note This type is early defined as incomplete type. + * This is required for function declaration that takes the pointer + * to this structure but in second hand - it is also placed inside + * the instance structure. + * @note The structure is defined in @file app_usbd_class_base.h. + */ +typedef struct {} app_usbd_class_inst_t; +#else +typedef struct app_usbd_class_inst_s app_usbd_class_inst_t; +#endif +/** + * @brief Endpoint callback function + * + * The function used by every class instance. + * @param[in,out] p_inst Instance of the class + * @param[in] p_event Event to process + * + * @note If given event is not supported by class, return @ref NRF_ERROR_NOT_SUPPORTED + */ +typedef ret_code_t (*app_usbd_ep_event_handler_t)( + app_usbd_class_inst_t const * const p_inst, + app_usbd_complex_evt_t const * const p_event + ); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_TYPES_H__ */ + diff --git a/components/libraries/usbd/class/audio/app_usbd_audio.c b/components/libraries/usbd/class/audio/app_usbd_audio.c new file mode 100644 index 0000000..cbf6e11 --- /dev/null +++ b/components/libraries/usbd/class/audio/app_usbd_audio.c @@ -0,0 +1,612 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_CLASS_AUDIO_ENABLED +#include "app_usbd_audio.h" +#include "app_util_platform.h" + +/** + * @defgroup app_usbd_audio_internals USBD Audio internals + * @{ + * @ingroup app_usbd_audio + * @internal + */ + +STATIC_ASSERT(sizeof(app_usbd_audio_ac_iface_header_desc_t) == 8); +STATIC_ASSERT(sizeof(app_usbd_audio_input_terminal_desc_t) == 12); +STATIC_ASSERT(sizeof(app_usbd_audio_output_terminal_desc_t) == 9); +STATIC_ASSERT(sizeof(app_usbd_audio_feature_unit_desc_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_audio_as_iface_desc_t) == 7); +STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_one_desc_t) == 8); +STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_two_desc_t) == 9); +STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_three_desc_t) == 8); +STATIC_ASSERT(sizeof(app_usbd_audio_as_endpoint_desc_t) == 7); + +#define APP_USBD_AUDIO_CONTROL_IFACE_IDX 0 /**< Audio class control interface index */ +#define APP_USBD_AUDIO_STREAMING_IFACE_IDX 1 /**< Audio class streaming interface index */ + +#define APP_USBD_CDC_AUDIO_STREAMING_EP_IDX 0 /**< Audio streaming isochronous endpoint index */ + +/** + * @brief Auxiliary function to access audio class instance data + * + * @param[in] p_inst Class instance data + * @return Audio class instance data @ref app_usbd_audio_t + */ +static inline app_usbd_audio_t const * audio_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_audio_t const *)p_inst; +} + +/** + * @brief Auxiliary function to access audio class context data + * + * @param[in] p_audio Audio class instance data + * @return Audio class context data @ref app_usbd_audio_ctx_t + */ +static inline app_usbd_audio_ctx_t * audio_ctx_get(app_usbd_audio_t const * p_audio) +{ + ASSERT(p_audio != NULL); + ASSERT(p_audio->specific.p_data != NULL); + return &p_audio->specific.p_data->ctx; +} + + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] event user Event type @ref app_usbd_audio_user_event_t + * */ +static inline void user_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_audio_user_event_t event) +{ + app_usbd_audio_t const * p_audio = audio_get(p_inst); + if (p_audio->specific.inst.user_ev_handler != NULL) + { + p_audio->specific.inst.user_ev_handler(p_inst, event); + } +} + +/** + * @brief Internal SETUP standard IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR: + { + size_t dsc_len = 0; + + /* Try to find descriptor in class internals*/ + void const * p_dsc = app_usbd_class_descriptor_find(p_inst, + p_setup_ev->setup.wValue.hb, + p_setup_ev->setup.wValue.lb, + &dsc_len); + if (p_dsc != NULL) + { + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_dsc, dsc_len); + } + + break; + } + case APP_USBD_SETUP_STDREQ_GET_INTERFACE: + { + + size_t tx_maxsize; + uint8_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_maxsize); + + p_tx_buff[0] = p_audio_ctx->streaming ? 1 : 0; + + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + p_tx_buff, + sizeof(uint8_t)); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP standard OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_SET_INTERFACE: + { + uint8_t iface_count = app_usbd_class_iface_count_get(p_inst); + app_usbd_class_iface_conf_t const * p_iface = NULL; + for (uint8_t j = 0; j < iface_count; ++j) + { + p_iface = app_usbd_class_iface_get(p_inst, j); + if (p_iface->number == p_setup_ev->setup.wIndex.w) + { + break; + } + } + + if (p_iface == NULL) + { + break; + } + + p_audio_ctx->streaming = (p_iface->ep_cnt > 0) && + (p_setup_ev->setup.wValue.w == 1); + + return app_usbd_req_std_set_interface(p_inst, p_setup_ev); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_AUDIO_REQ_GET_CUR: + case APP_USBD_AUDIO_REQ_GET_MIN: + case APP_USBD_AUDIO_REQ_GET_MAX: + case APP_USBD_AUDIO_REQ_SET_RES: + case APP_USBD_AUDIO_REQ_GET_MEM: + { + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + + + p_audio_ctx->request.req_type = (app_usbd_audio_req_type_t)p_setup_ev->setup.bmRequest; + p_audio_ctx->request.control = p_setup_ev->setup.wValue.hb; + p_audio_ctx->request.channel = p_setup_ev->setup.wValue.lb; + p_audio_ctx->request.interface = p_setup_ev->setup.wIndex.hb; + p_audio_ctx->request.entity = p_setup_ev->setup.wIndex.lb; + + p_audio_ctx->request.length = p_setup_ev->setup.wLength.w; + + p_audio_ctx->request.req_target = APP_USBD_AUDIO_CLASS_REQ_IN; + + app_usbd_setup_reqrec_t rec = app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType); + if (rec == APP_USBD_SETUP_REQREC_ENDPOINT) + { + p_audio_ctx->request.req_target = APP_USBD_AUDIO_EP_REQ_IN; + } + + user_event_handler((app_usbd_class_inst_t const *)p_audio, + APP_USBD_AUDIO_USER_EVT_CLASS_REQ); + + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + p_audio_ctx->request.payload, + p_audio_ctx->request.length); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +static ret_code_t audio_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context) +{ + if(status == NRF_USBD_EP_OK) + { + app_usbd_audio_t const * p_audio = p_context; + + user_event_handler((app_usbd_class_inst_t const *)p_audio, + APP_USBD_AUDIO_USER_EVT_CLASS_REQ); + } + + return NRF_SUCCESS; +} + +static ret_code_t audio_req_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + + + p_audio_ctx->request.req_type = (app_usbd_audio_req_type_t)p_setup_ev->setup.bmRequest; + p_audio_ctx->request.control = p_setup_ev->setup.wValue.hb; + p_audio_ctx->request.channel = p_setup_ev->setup.wValue.lb; + p_audio_ctx->request.interface = p_setup_ev->setup.wIndex.hb; + p_audio_ctx->request.entity = p_setup_ev->setup.wIndex.lb; + + p_audio_ctx->request.length = p_setup_ev->setup.wLength.w; + + p_audio_ctx->request.req_target = APP_USBD_AUDIO_CLASS_REQ_OUT; + if (app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_ENDPOINT) + { + p_audio_ctx->request.req_target = APP_USBD_AUDIO_EP_REQ_OUT; + } + + /*Request setup data*/ + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_audio_ctx->request.payload, p_audio_ctx->request.length); + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPOUT0, &transfer, NULL); + if (ret == NRF_SUCCESS) + { + app_usbd_core_setup_data_handler_desc_t desc = { + .handler = audio_req_out_data_cb, + .p_context = (void*)p_audio + }; + + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +/** + * @brief Internal SETUP class OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_AUDIO_REQ_SET_CUR: + case APP_USBD_AUDIO_REQ_SET_MIN: + case APP_USBD_AUDIO_REQ_SET_MAX: + case APP_USBD_AUDIO_REQ_SET_RES: + case APP_USBD_AUDIO_REQ_SET_MEM: + return audio_req_out(p_inst, p_setup_ev); + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Control endpoint handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + ASSERT(p_inst != NULL); + ASSERT(p_setup_ev != NULL); + + app_usbd_setup_reqrec_t req_rec = app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType); + app_usbd_setup_reqtype_t req_type = app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType); + if (req_rec == APP_USBD_SETUP_REQREC_ENDPOINT && + req_type == APP_USBD_SETUP_REQTYPE_STD) + { + return app_usbd_endpoint_std_req_handle(p_inst, p_setup_ev); + } + + ret_code_t ret = app_usbd_interface_std_req_handle(p_inst, p_setup_ev); + if (ret == NRF_SUCCESS || ret != NRF_ERROR_NOT_SUPPORTED) + { + return ret; + } + + if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN) + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_in(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_in(p_inst, p_setup_ev); + default: + break; + } + } + else /*APP_USBD_SETUP_REQDIR_OUT*/ + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_out(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_out(p_inst, p_setup_ev); + default: + break; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + + +/** + * @brief Endpoint IN event handler + * + * @param[in] p_inst Generic class instance + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst) +{ + user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_TX_DONE); + return NRF_SUCCESS; +} + + +/** + * @brief Endpoint OUT event handler + * + * @param[in] p_inst Generic class instance + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst) +{ + user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_RX_DONE); + return NRF_SUCCESS; +} + +/** +* @brief Auxiliary function to access isochronous endpoint address +* +* @param[in] p_inst Class instance data +* +* @return ISO endpoint address +*/ +static inline nrf_drv_usbd_ep_t ep_iso_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_AUDIO_STREAMING_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_AUDIO_STREAMING_EP_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +static ret_code_t sof_event_handler(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + + nrf_drv_usbd_ep_t ep_addr = ep_iso_addr_get(p_inst); + + if (app_usbd_core_state_get() != APP_USB_STATE_BASE(APP_USBD_STATE_Configured)) + { + return NRF_SUCCESS; + } + + if (!p_audio_ctx->streaming) + { + return NRF_SUCCESS; + } + + /*OUT transfers*/ + if (p_audio_ctx->rx_size && NRF_USBD_EPOUT_CHECK(ep_addr)) + { + + ASSERT(NRF_USBD_EPISO_CHECK(ep_addr)); + + uint32_t isoout = nrf_usbd_epout_size_get(ep_addr); + if (isoout) + { + ASSERT(isoout == p_audio_ctx->rx_size); + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_audio_ctx->p_rx_buff, p_audio_ctx->rx_size); + return app_usbd_core_ep_transfer(ep_addr, &transfer, NULL); + } + } + + /*IN transfers*/ + if (p_audio_ctx->tx_size && NRF_USBD_EPIN_CHECK(ep_addr)) + { + ASSERT(NRF_USBD_EPISO_CHECK(ep_addr)); + NRF_DRV_USBD_TRANSFER_IN(transfer, p_audio_ctx->p_tx_buff, p_audio_ctx->tx_size); + return app_usbd_core_ep_transfer(ep_addr, &transfer, NULL); + } + + return NRF_SUCCESS; +} + + + + +/** + * @brief @ref app_usbd_class_methods_t::event_handler + */ +static ret_code_t audio_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + ret_code_t ret = NRF_SUCCESS; + switch (p_event->app_evt.type) + { + case APP_USBD_EVT_DRV_SOF: + ret = sof_event_handler(p_inst); + break; + case APP_USBD_EVT_DRV_RESET: + break; + case APP_USBD_EVT_DRV_SETUP: + ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event); + break; + case APP_USBD_EVT_DRV_EPTRANSFER: + if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep)) + { + ret = endpoint_in_event_handler(p_inst); + } + else + { + ret = endpoint_out_event_handler(p_inst); + } + break; + case APP_USBD_EVT_DRV_SUSPEND: + user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_SUSPEND); + break; + case APP_USBD_EVT_DRV_RESUME: + user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_RESUME); + break; + case APP_USBD_EVT_INST_APPEND: + { + ret = app_usbd_class_sof_register(p_inst); + break; + } + case APP_USBD_EVT_INST_REMOVE: + { + ret = app_usbd_class_sof_unregister(p_inst); + break; + } + case APP_USBD_EVT_START: + user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_START); + break; + case APP_USBD_EVT_STOP: + user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_STOP); + break; + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + return ret; +} + +/** + * @brief @ref app_usbd_class_methods_t::get_descriptors + */ +static const void * audio_get_descriptors(app_usbd_class_inst_t const * p_inst, + size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_audio_t const * p_audio = audio_get(p_inst); + + *p_size = p_audio->specific.inst.raw_desc_size; + return p_audio->specific.inst.p_raw_desc; +} + +/** @} */ + +const app_usbd_class_methods_t app_usbd_audio_class_methods = { + .event_handler = audio_event_handler, + .get_descriptors = audio_get_descriptors, +}; + +void app_usbd_audio_class_tx_buf_set(app_usbd_class_inst_t const * p_inst, + const void * p_buff, + size_t size) +{ + ASSERT(p_inst != NULL); + + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + CRITICAL_REGION_ENTER(); + + p_audio_ctx->p_tx_buff = p_buff; + p_audio_ctx->tx_size = size; + + CRITICAL_REGION_EXIT(); +} + +void app_usbd_audio_class_rx_buf_set(app_usbd_class_inst_t const * p_inst, + void * p_buff, + size_t size) +{ + ASSERT(p_inst != NULL); + + app_usbd_audio_t const * p_audio = audio_get(p_inst); + app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio); + CRITICAL_REGION_ENTER(); + + p_audio_ctx->p_rx_buff = p_buff; + p_audio_ctx->rx_size = size; + + CRITICAL_REGION_EXIT(); +} + +#endif //APP_USBD_CLASS_AUDIO_ENABLED diff --git a/components/libraries/usbd/class/audio/app_usbd_audio.h b/components/libraries/usbd/class/audio/app_usbd_audio.h new file mode 100644 index 0000000..42e5bb9 --- /dev/null +++ b/components/libraries/usbd/class/audio/app_usbd_audio.h @@ -0,0 +1,208 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_AUDIO_H__ +#define APP_USBD_AUDIO_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_usbd.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_class_base.h" +#include "app_usbd_descriptor.h" + +#include "app_usbd_audio_types.h" +#include "app_usbd_audio_desc.h" +#include "app_usbd_audio_internal.h" + + +/** + * @defgroup app_usbd_audio USB AUDIO class + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with types, definitions, and API used by USB Audio class. + * + * @details Reference specifications: + * - "Universal Serial Bus Device Class Definition for Audio Devices" + * Release 1.0, March 18, 1998. + * - "Universal Serial Bus Device Class Definition for Audio Data Formats" + * Release 1.0, March 18, 1998. + * - "Universal Serial Bus Device Class Definition for Terminal Types" + * Release 1.0, March 18, 1998. + * + * @{ + */ + + +#ifdef DOXYGEN +/** + * @brief Audio class instance type + * + * @ref APP_USBD_CLASS_TYPEDEF + */ +typedef struct { } app_usbd_audio_t; +#else +/*lint -save -e10 -e26 -e123 -e505 */ +APP_USBD_CLASS_TYPEDEF(app_usbd_audio, \ + APP_USBD_AUDIO_CONFIG(0, 1), \ + APP_USBD_AUDIO_INSTANCE_SPECIFIC_DEC, \ + APP_USBD_AUDIO_DATA_SPECIFIC_DEC \ +); +/*lint -restore*/ +#endif + + +/*lint -save -e407 */ + +/** + * @brief Events passed to user event handler + * + * @note Example prototype of user event handler: + * + * @code + void audio_user_ev_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_audio_user_event_t event); + * @endcode + */ +typedef enum app_usbd_audio_user_event_e { + APP_USBD_AUDIO_USER_EVT_SUSPEND = 0, /**< User event SUSPEND */ + APP_USBD_AUDIO_USER_EVT_RESUME, /**< User event RESUME */ + APP_USBD_AUDIO_USER_EVT_START, /**< User event START */ + APP_USBD_AUDIO_USER_EVT_STOP, /**< User event STOP */ + + APP_USBD_AUDIO_USER_EVT_CLASS_REQ, /**< User event CLASS_REQ */ + APP_USBD_AUDIO_USER_EVT_RX_DONE, /**< User event RX_DONE */ + APP_USBD_AUDIO_USER_EVT_TX_DONE, /**< User event TX_DONE */ +} app_usbd_audio_user_event_t; + +/*lint -restore*/ + + +/** + * @brief Global definition of app_usbd_audio_t class instance + * + * @param instance_name Name of global instance + * @param interfaces_configs Interfaces configurations + * @param user_ev_handler User event handler (optional) + * @param raw_descriptors Raw descriptor table + * + * @note This macro is just simplified version of @ref APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL + * + */ +#define APP_USBD_AUDIO_GLOBAL_DEF(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) \ + APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) + +/** + * @@brief Helper function to get class instance from Audio class + * + * @param[in] p_audio Audio class instance (declared by @ref APP_USBD_AUDIO_GLOBAL_DEF) + * @return Base class instance + */ +static inline app_usbd_class_inst_t const * +app_usbd_audio_class_inst_get(app_usbd_audio_t const * p_audio) +{ + return &p_audio->base; +} + +/** + * @brief Helper function to get audio specific request from audio class + * + * @param[in] p_audio Audio class instance (declared by @ref APP_USBD_AUDIO_GLOBAL_DEF) + * @return Audio class specific request + */ +static inline app_usbd_audio_req_t * +app_usbd_audio_class_request_get(app_usbd_audio_t const * p_audio) +{ + return &p_audio->specific.p_data->ctx.request; +} + +/** + * @brief Helper function to get audio from base class instance + * + * @param[in] p_inst Base class instance + * @return Audio class handle + */ +static inline app_usbd_audio_t const * +app_usbd_audio_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_audio_t const *)p_inst; +} + +/** + * @brief Set transmit buffer + * + * @param[in] p_inst Base class instance + * @param[in] p_buff Transmit buffer + * @param[in] size Transmit buffer size + * */ +void app_usbd_audio_class_tx_buf_set(app_usbd_class_inst_t const * p_inst, + const void * p_buff, + size_t size); + +/** + * @brief Set receive buffer + * + * @param[in] p_inst Base class instance + * @param[in] p_buff Receive buffer + * @param[in] size Receive buffer size + * */ +void app_usbd_audio_class_rx_buf_set(app_usbd_class_inst_t const * p_inst, + void * p_buff, + size_t size); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_AUDIO_H__ */ diff --git a/components/libraries/usbd/class/audio/app_usbd_audio_desc.h b/components/libraries/usbd/class/audio/app_usbd_audio_desc.h new file mode 100644 index 0000000..9e7e703 --- /dev/null +++ b/components/libraries/usbd/class/audio/app_usbd_audio_desc.h @@ -0,0 +1,319 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_AUDIO_DESC_H__ +#define APP_USBD_AUDIO_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_usbd_descriptor.h" + +/** + * @defgroup app_usbd_audio_dsc USB Audio descriptors + * @brief @tagAPI52840 Descriptors used in the USB Audio class. + * @ingroup app_usbd_audio + * @{ + */ + +/** + * @brief Initializer of interface descriptor for AUDIO class + * + * @param interface_number Interface number + * @param alt_setting Interface alternate setting + * @param ep_num Number of endpoints + * @param subclass Audio subclass @ref app_usbd_audio_subclass_t + * */ +#define APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, subclass) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \ + /*.bInterfaceNumber = */ (interface_number), \ + /*.bAlternateSetting = */ (alt_setting), \ + /*.bNumEndpoints = */ (ep_num), \ + /*.bInterfaceClass = */ APP_USBD_AUDIO_CLASS, \ + /*.bInterfaceSubClass = */ (subclass), \ + /*.bInterfaceProtocol = */ APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED, \ + /*.iInterface = 0, */ 0x00, \ + +/** + * @brief Initializer of isochronous endpoint descriptors for audio class + * + * @param ep ISO endpoint id: @ref NRF_DRV_USBD_EPIN8, @ref NRF_DRV_USBD_EPOUT8 + * @param ep_size Endpoint size (bytes) + * @param interval Endpoint interval (milliseconds) + * @param refresh Refresh value (usually 0) + * @param synch_addr Synch address (usually 0) + * */ +#define APP_USBD_AUDIO_ISO_EP_DSC(ep, ep_size, interval, refresh, synch_addr) \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t) + 2, \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ ep, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ (interval), \ + /*.bRefresh = */ (refresh), \ + /*.bInterval = */ (synch_addr), \ + +/** + * @brief Simplified version of @ref APP_USBD_AUDIO_ISO_EP_DSC for ISO IN endpoint + */ +#define APP_USBD_AUDIO_ISO_EP_IN_DSC(ep_size) \ + APP_USBD_AUDIO_ISO_EP_DSC(NRF_DRV_USBD_EPIN8, ep_size, 1, 0, 0) + +/** + * @brief Simplified version of @ref APP_USBD_AUDIO_ISO_EP_DSC for ISO OUT endpoint + */ +#define APP_USBD_AUDIO_ISO_EP_OUT_DSC(ep_size) \ + APP_USBD_AUDIO_ISO_EP_DSC(NRF_DRV_USBD_EPOUT8, ep_size, 1, 0, 0) + +/** + * @brief Initializer of @ref app_usbd_audio_ac_iface_header_desc_t + * + * @param descriptor_list Descriptor list following audio interface header descriptor + * @param ... List of interfaces following audio control interface + * */ +#define APP_USBD_AUDIO_AC_IFACE_HEADER_DSC(descriptor_list, ...) \ + /*.bLength = */ sizeof(app_usbd_audio_ac_iface_header_desc_t) + \ + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER, \ + /*.bcdADC = */ APP_USBD_U16_TO_RAW_DSC(0x0100), \ + /*.wTotalLength = */ APP_USBD_U16_TO_RAW_DSC( \ + sizeof((uint8_t[]){BRACKET_EXTRACT(descriptor_list)}) + \ + sizeof(app_usbd_audio_ac_iface_header_desc_t) + \ + (NUM_VA_ARGS(__VA_ARGS__))), \ + /*.bInCollection = */ (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.baInterfaceNr[] = */ __VA_ARGS__, \ + + +/** + * @brief Initializer of @ref app_usbd_audio_input_terminal_desc_t + * + * @param terminal_id Terminal ID + * @param terminal_type Terminal type @ref app_usbd_audio_terminal_type_t + * @param nr_channels Number of channels + * @param ch_config CHannel config bitmask + * */ +#define APP_USBD_AUDIO_INPUT_TERMINAL_DSC(terminal_id, terminal_type, nr_channels, ch_config) \ + /*.bLength = */ sizeof(app_usbd_audio_input_terminal_desc_t), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL, \ + /*.bTerminalID = */ (terminal_id), \ + /*.wTerminalType = */ APP_USBD_U16_TO_RAW_DSC(terminal_type), \ + /*.bAssocTerminal = */ 0, \ + /*.bNrChannels = */ (nr_channels), \ + /*.wChannelConfig = */ APP_USBD_U16_TO_RAW_DSC(ch_config), \ + /*.iChannelNames = */ 0, \ + /*.iTerminal = */ 0, \ + + +/** + * @brief Initializer of @ref app_usbd_audio_output_terminal_desc_t + * + * @param terminal_id Terminal ID + * @param terminal_type Terminal type @ref app_usbd_audio_terminal_type_t + * @param source_id Source ID + * */ +#define APP_USBD_AUDIO_OUTPUT_TERMINAL_DSC(terminal_id, terminal_type, source_id) \ + /*.bLength = */ sizeof(app_usbd_audio_output_terminal_desc_t), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL, \ + /*.bTerminalID = */ (terminal_id), \ + /*.wTerminalType = */ APP_USBD_U16_TO_RAW_DSC(terminal_type), \ + /*.bAssocTerminal = */ 0, \ + /*.bSourceID = */ (source_id), \ + /*.iTerminal = */ 0, \ + + +/** + * @brief Initializer of @ref app_usbd_audio_feature_unit_desc_t + * + * @param unit_id Unit ID + * @param source_id Source ID + * @param ... List of controls + * */ +#define APP_USBD_AUDIO_FEATURE_UNIT_DSC(unit_id, source_id, ...) \ + /*.bLength = */ sizeof(app_usbd_audio_feature_unit_desc_t) + \ + 1 + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT, \ + /*.bUnitID = */ (unit_id), \ + /*.bSourceID = */ (source_id), \ + /*.bControlSize = */ sizeof(uint16_t), \ + /*.bmaControls[] = */ __VA_ARGS__, \ + /*.iFeature = */ 0, \ + + +/** + * @brief Initializer of @ref app_usbd_audio_as_iface_desc_t + * + * @param terminal_link Terminal link + * @param delay Delay + * @param format_tag Format TAG + * */ +#define APP_USBD_AUDIO_AS_IFACE_DSC(terminal_link, delay, format_tag) \ + /*.bLength = */ sizeof(app_usbd_audio_as_iface_desc_t), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL, \ + /*.bTerminalLink = */ (terminal_link), \ + /*.bDelay = */ (delay), \ + /*.wFormatTag = */ APP_USBD_U16_TO_RAW_DSC(format_tag), \ + +/** + * @brief Initializer of @ref app_usbd_audio_as_format_type_one_desc_t + * + * @param nr_channels Number of channels + * @param subframe_size Subframe size + * @param resolution Bit resolution + * @param freq_type Frequency type + * @param ... List of frequencies + * */ +#define APP_USBD_AUDIO_AS_FORMAT_I_DSC(nr_channels, subframe_size, resolution, freq_type, ...) \ + /*.bLength = */ sizeof(app_usbd_audio_as_format_type_one_desc_t) + \ + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \ + /*.bFormatType = */ (1), \ + /*.bNrChannels = */ (nr_channels), \ + /*.bSubframeSize = */ (subframe_size), \ + /*.bBitResolution = */ (resolution), \ + /*.bSamFreqType = */ (freq_type), \ + /*.tSamFreq = */ __VA_ARGS__, \ + +/** + * @brief Initializer of @ref app_usbd_audio_as_format_type_two_desc_t + * + * @param max_bitrate Maximum bitrate + * @param samples_per_frame Samples per frame + * @param freq_type Frequency type + * @param ... List of frequencies + * */ +#define APP_USBD_AUDIO_AS_FORMAT_II_DSC(max_bitrate, samples_per_frame, freq_type, ...) \ + /*.bLength = */ sizeof(app_usbd_audio_as_format_type_two_desc_t) + \ + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \ + /*.bFormatType = */ (2), \ + /*.wMaxBitRate = */ APP_USBD_U16_TO_RAW_DSC(max_bitrate), \ + /*.wSamplesPerFrame = */ APP_USBD_U16_TO_RAW_DSC(samples_per_frame), \ + /*.bSamFreqType = */ (freq_type), \ + /*.tSamFreq = */ __VA_ARGS__, \ + +/** +* @brief Initializer of @ref app_usbd_audio_as_format_type_three_desc_t + * + * @param nr_channels Number of channels + * @param subframe_size Subframe size + * @param resolution Bit resolution + * @param freq_type Frequency type + * @param ... List of frequencies + * */ +#define APP_USBD_AUDIO_AS_FORMAT_III_DSC(nr_channels, subframe_size, resolution, freq_type, ...) \ + /*.bLength = */ sizeof(app_usbd_audio_as_format_type_three_desc_t) + \ + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \ + /*.bFormatType = */ (3), \ + /*.bNrChannels = */ (nr_channels), \ + /*.bSubframeSize = */ (subframe_size), \ + /*.bBitResolution = */ (resolution), \ + /*.bSamFreqType = */ (freq_type), \ + /*.tSamFreq = */ __VA_ARGS__, \ + + +/** + * @brief Initializer of @ref app_usbd_audio_as_endpoint_desc_t + * + * @param attributes Endpoint attributes + * @param lock_delay_units Lock delay units + * @param lock_delay Lock delay + * */ +#define APP_USBD_AUDIO_EP_GENERAL_DSC(attributes, lock_delay_units, lock_delay) \ + /*.bLength = */ sizeof(app_usbd_audio_as_endpoint_desc_t), \ + /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT, \ + /*.bDescriptorSubtype = */ APP_USBD_AUDIO_EP_SUBTYPE_GENERAL, \ + /*.bmAttributes = */ (attributes), \ + /*.bLockDelayUnits = */ (lock_delay_units), \ + /*.wLockDelay = */ APP_USBD_U16_TO_RAW_DSC(lock_delay), \ + +/** + * @brief Macro to configure Audio Class control descriptor + * + * @param interface_number Interface number + * @param descriptor_list List of descriptors after Audio interface header descriptor + * @param interface_list List of interfaces passed to @ref APP_USBD_AUDIO_AC_IFACE_HEADER_DSC + * */ +#define APP_USBD_AUDIO_CONTROL_DSC(interface_number, descriptor_list, interface_list) \ + APP_USBD_AUDIO_INTERFACE_DSC(interface_number, 0, 0, APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL) \ + APP_USBD_AUDIO_AC_IFACE_HEADER_DSC(descriptor_list, BRACKET_EXTRACT(interface_list)) \ + BRACKET_EXTRACT(descriptor_list) + + +/** + * @brief Macro to configure Audio Class streaming descriptor + * + * @param interface_number Interface number + * @param alt_setting Alternate interface setting + * @param ep_num Number of endpoints + */ +#define APP_USBD_AUDIO_STREAMING_DSC(interface_number, alt_setting, ep_num) \ + APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, \ + APP_USBD_AUDIO_SUBCLASS_AUDIOSTREAMING) + +/** + * @brief Macro to configure Audio Class MIDI streaming descriptor + * + * @param interface_number Interface number + * @param alt_setting Alternate interface setting + * @param ep_num Number of endpoints + */ +#define APP_USBD_AUDIO_MIDI_STREAMING_DSC(interface_number, alt_setting, ep_num) \ + APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, \ + APP_USBD_AUDIO_SUBCLASS_MIDISTREAMING) + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_AUDIO_DESC_H__ */ diff --git a/components/libraries/usbd/class/audio/app_usbd_audio_internal.h b/components/libraries/usbd/class/audio/app_usbd_audio_internal.h new file mode 100644 index 0000000..4225945 --- /dev/null +++ b/components/libraries/usbd/class/audio/app_usbd_audio_internal.h @@ -0,0 +1,238 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_AUDIO_INTERNAL_H__ +#define APP_USBD_AUDIO_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup app_usbd_audio_internal USB Audio internals + * @brief @tagAPI52840 USB Audio class internals. + * @ingroup app_usbd_audio + * @{ + */ + +/** + * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF in audio class + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_audio); + +/*lint -save -e165*/ +/** + * @brief Forward declaration of @ref app_usbd_audio_user_event_e + * + */ +enum app_usbd_audio_user_event_e; + +/*lint -restore*/ + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] event User event + * + * */ +typedef void (*app_usbd_audio_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst, + enum app_usbd_audio_user_event_e event); + +/** + * @brief Audio class part of class instance data + */ +typedef struct { + uint8_t const * p_raw_desc; //!< Audio class descriptors + size_t raw_desc_size; //!< Audio class descriptors size + + app_usbd_audio_user_ev_handler_t user_ev_handler; //!< User event handler +} app_usbd_audio_inst_t; + +/** + * @brief Audio class request target + */ +typedef enum { + APP_USBD_AUDIO_CLASS_REQ_IN, /**< Audio class request IN */ + APP_USBD_AUDIO_CLASS_REQ_OUT, /**< Audio class request OUT */ + APP_USBD_AUDIO_EP_REQ_IN, /**< Audio class endpoint request IN */ + APP_USBD_AUDIO_EP_REQ_OUT, /**< Audio class endpoint request OUT */ +} app_usbd_audio_class_req_target_t; + +/** + * @brief Audio class specific request handled via control endpoint + * */ +typedef struct { + app_usbd_audio_class_req_target_t req_target; //!< Request target + app_usbd_audio_req_type_t req_type; //!< Request type + + uint8_t control; //!< Request control field + uint8_t channel; //!< Channel ID + uint8_t interface; //!< Interface ID + uint8_t entity; //!< Entity ID + uint16_t length; //!< Request payload length + + uint8_t payload[64]; //!< Request payload +} app_usbd_audio_req_t; + + +/** + * @brief Audio class context + * + * */ +typedef struct { + app_usbd_audio_req_t request; //!< Audio class request + + const void * p_tx_buff; //!< Transfer buffer (IN endpoint transfers) + void * p_rx_buff; //!< Transfer buffer (OUT endpoint transfers) + + size_t tx_size; //!< Transfer buffer size (IN endpoint transfers) + size_t rx_size; //!< Transfer buffer size (OUT endpoint transfers) + bool streaming; //!< Streaming flag +} app_usbd_audio_ctx_t; + + +/** + * @brief Audio class configuration macro + * + * Used by @ref APP_USBD_AUDIO_GLOBAL_DEF + * + * @param iface_control Interface number of audio control + * @param iface_stream Interface number of audio stream + * */ +#define APP_USBD_AUDIO_CONFIG(iface_control, iface_stream) \ + ((iface_control), \ + (iface_stream, 0)) + +/** + * @brief Only IN audio stream configuration + * + * @param iface_control Interface number of audio control + * @param iface_stream_in Interface number of audio stream on IN endpoint + * */ +#define APP_USBD_AUDIO_CONFIG_IN(iface_control, iface_stream_in) \ + ((iface_control), (iface_stream_in, NRF_DRV_USBD_EPIN8)) + + +/** + * @brief Only OUT audio stream configuration + * + * @param iface_control Interface number of audio control + * @param iface_stream_out Interface number of audio stream on OUT endpoint + * */ +#define APP_USBD_AUDIO_CONFIG_OUT(iface_control, iface_stream_out) \ + ((iface_control), (iface_stream_out, NRF_DRV_USBD_EPOUT8)) + +/** + * @brief Specific class constant data for audio class + * + * @ref app_usbd_audio_inst_t + */ +#define APP_USBD_AUDIO_INSTANCE_SPECIFIC_DEC app_usbd_audio_inst_t inst; + + +/** + * @brief Configures audio class instance + * + * @param descriptors Mass storage class descriptors (raw table) + * @param user_event_handler User event handler + */ +#define APP_USBD_AUDIO_INST_CONFIG(descriptors, user_event_handler) \ + .inst = { \ + .p_raw_desc = descriptors, \ + .raw_desc_size = sizeof(descriptors), \ + .user_ev_handler = user_event_handler, \ + } + +/** + * @brief Specific class data for audio class + * + * @ref app_usbd_audio_ctx_t + * */ +#define APP_USBD_AUDIO_DATA_SPECIFIC_DEC app_usbd_audio_ctx_t ctx; + + +/** + * @brief Audio class descriptors config macro + * + * @param interface_number Interface number + * @param ... Extracted endpoint list + * */ +#define APP_USBD_AUDIO_DSC_CONFIG(interface_number, ...) { \ + APP_USBD_AUDIO_INTERFACE_DSC(interface_number, \ + 0, \ + 0, \ + APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL) \ + } + +/** + * @brief Public audio class interface + * + * */ +extern const app_usbd_class_methods_t app_usbd_audio_class_methods; + +/** + * @brief Global definition of @ref app_usbd_audio_t class + * + */ +#define APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_audio, \ + &app_usbd_audio_class_methods, \ + interfaces_configs, \ + (APP_USBD_AUDIO_INST_CONFIG(raw_descriptors, \ + user_ev_handler)) \ + ) + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_AUDIO_INTERNAL_H__ */ diff --git a/components/libraries/usbd/class/audio/app_usbd_audio_types.h b/components/libraries/usbd/class/audio/app_usbd_audio_types.h new file mode 100644 index 0000000..c7c9a53 --- /dev/null +++ b/components/libraries/usbd/class/audio/app_usbd_audio_types.h @@ -0,0 +1,383 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_AUDIO_TYPES_H__ +#define APP_USBD_AUDIO_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_util.h" + +/** + * @defgroup app_usbd_audio_types USB Audio types + * @brief @tagAPI52840 Type definitions for the USB Audio class. + * @ingroup app_usbd_audio + * @{ + */ + +/** @brief Audio class definition in interface descriptor + * + * Fixed value, @ref app_usbd_descriptor_iface_t::bInterfaceClass + * */ +#define APP_USBD_AUDIO_CLASS 0x01 + +/** @brief Audio class protocol definition in interface descriptor + * + * Fixed value, @ref app_usbd_descriptor_iface_t::bInterfaceProtocol + * */ +#define APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED 0x00 + +/** + * @brief Audio subclass possible values + * + * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass + */ +typedef enum { + APP_USBD_AUDIO_SUBCLASS_UNDEFINED = 0x00, /**< UNDEFINED subclass */ + APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL, /**< AUDIOCONTROL subclass */ + APP_USBD_AUDIO_SUBCLASS_AUDIOSTREAMING, /**< AUDIOSTREAMING subclass */ + APP_USBD_AUDIO_SUBCLASS_MIDISTREAMING /**< MIDISTREAMING subclass */ +} app_usbd_audio_subclass_t; + + +/** + * @brief Audio class specific descriptor types + */ +typedef enum { + APP_USBD_AUDIO_DESCRIPTOR_UNDEFINED = 0x20, /**< UNDEFINED descriptor type */ + APP_USBD_AUDIO_DESCRIPTOR_DEVICE = 0x21, /**< DEVICE descriptor type */ + APP_USBD_AUDIO_DESCRIPTOR_CONFIGURATION = 0x22, /**< CONFIGURATION descriptor type */ + APP_USBD_AUDIO_DESCRIPTOR_STRING = 0x23, /**< STRING descriptor type */ + APP_USBD_AUDIO_DESCRIPTOR_INTERFACE = 0x24, /**< INTERFACE descriptor type */ + APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT = 0x25, /**< ENDPOINT descriptor type */ +} app_usbd_audio_descriptor_type_t; + + +/** + * @brief Audio control interface subtype + */ +typedef enum { + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_UNDEFINED = 0x00, /**< Audio control interface subtype UNDEFINED */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER, /**< Audio control interface subtype HEADER */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL, /**< Audio control interface subtype INPUT_TERMINAL */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL, /**< Audio control interface subtype OUTPUT_TERNINAL */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_MIXER_UNIT, /**< Audio control interface subtype MIXER_UNIT */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_SELECTOR_UNIT, /**< Audio control interface subtype SELECTOR_UNIT */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT, /**< Audio control interface subtype FEATURE_UNIT */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_PROCESSING_UNIT, /**< Audio control interface subtype PROCESSING_UNIT */ + APP_USBD_AUDIO_AC_IFACE_SUBTYPE_EXTENSION_UNIT, /**< Audio control interface subtype EXTENSION_UNIT */ +} app_usbd_audio_ac_iface_subtype_t; + +/** + * @brief Audio streaming interface subtype + */ +typedef enum { + APP_USBD_AUDIO_AS_IFACE_SUBTYPE_UNDEFINED = 0x00, /**< Audio streaming interface subtype UNDEFINED */ + APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL, /**< Audio streaming interface subtype GENERAL */ + APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, /**< Audio streaming interface subtype FORMAT_TYPE */ + APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_SPECIFIC, /**< Audio streaming interface subtype FORMAT_SPECIFIC*/ +} app_usbd_audio_as_iface_subtype_t; + + +/** + * @brief Audio class specific endpoint subtypes + */ +typedef enum { + APP_USBD_AUDIO_EP_SUBTYPE_UNDEFINED = 0x00, /**< APP_USBD_AUDIO_EP_SUBTYPE_UNDEFINED */ + APP_USBD_AUDIO_EP_SUBTYPE_GENERAL, /**< APP_USBD_AUDIO_EP_SUBTYPE_GENERAL */ +} app_usbd_audio_ep_subtype_t; + +/** + * @brief Audio class specific requests + * + * @ref nrf_drv_usbd_setup_t::bmRequestType + */ +typedef enum { + APP_USBD_AUDIO_REQ_UNDEFINED = 0x00, /**< UNDEFINED request*/ + + APP_USBD_AUDIO_REQ_SET_CUR = 0x01, /**< SET_CUR request */ + APP_USBD_AUDIO_REQ_SET_MIN = 0x02, /**< SET_MIN request */ + APP_USBD_AUDIO_REQ_SET_MAX = 0x03, /**< SET_MAX request */ + APP_USBD_AUDIO_REQ_SET_RES = 0x04, /**< SET_RES request */ + APP_USBD_AUDIO_REQ_SET_MEM = 0x05, /**< SET_MEM request */ + + APP_USBD_AUDIO_REQ_GET_CUR = 0x81, /**< GET_CUR request */ + APP_USBD_AUDIO_REQ_GET_MIN = 0x82, /**< GET_MIN request */ + APP_USBD_AUDIO_REQ_GET_MAX = 0x83, /**< GET_MAX request */ + APP_USBD_AUDIO_REQ_GET_RES = 0x84, /**< GET_RES request */ + APP_USBD_AUDIO_REQ_GET_MEM = 0x85, /**< GET_MEM request */ + + APP_USBD_AUDIO_REQ_GET_STAT = 0xFF, /**< GET_STAT request */ +} app_usbd_audio_req_type_t; + +/** + * @brief Audio class terminal types + * */ +typedef enum { + /*USB terminals*/ + APP_USBD_AUDIO_TERMINAL_USB_UNDEFINED = 0x0100, /**< USB_UNDEFINED*/ + APP_USBD_AUDIO_TERMINAL_USB_STREAMING = 0x0101, /**< USB_STREAMING */ + APP_USBD_AUDIO_TERMINAL_USB_VENDOR_SPEC = 0x01FF, /**< USB_VENDOR_SPEC*/ + + /*Input terminals*/ + APP_USBD_AUDIO_TERMINAL_IN_UNDEFINED = 0x0200, /**< UNDEFINED */ + APP_USBD_AUDIO_TERMINAL_IN_MICROPHONE = 0x0201, /**< MICROPHONE */ + APP_USBD_AUDIO_TERMINAL_IN_DESKTOP_MIC = 0x0202, /**< DESKTOP_MIC */ + APP_USBD_AUDIO_TERMINAL_IN_PERSONAL_MIC = 0x0203, /**< PERSONAL_MIC */ + APP_USBD_AUDIO_TERMINAL_IN_OM_DIR_MIC = 0x0204, /**< OM_DIR_MIC */ + APP_USBD_AUDIO_TERMINAL_IN_MIC_ARRAY = 0x0205, /**< MIC_ARRAY */ + APP_USBD_AUDIO_TERMINAL_IN_PROC_MIC_ARRAY = 0x0205, /**< PROC_MIC_ARRAY */ + + /*Output terminals*/ + APP_USBD_AUDIO_TERMINAL_OUT_UNDEFINED = 0x0300, /**< UNDEFINED */ + APP_USBD_AUDIO_TERMINAL_OUT_SPEAKER = 0x0301, /**< SPEAKER */ + APP_USBD_AUDIO_TERMINAL_OUT_HEADPHONES = 0x0302, /**< HEADPHONES */ + APP_USBD_AUDIO_TERMINAL_OUT_HEAD_AUDIO = 0x0303, /**< HEAD_AUDIO */ + APP_USBD_AUDIO_TERMINAL_OUT_DESKTOP_SPEAKER = 0x0304, /**< DESKTOP_SPEAKER */ + APP_USBD_AUDIO_TERMINAL_OUT_ROOM_SPEAKER = 0x0305, /**< ROOM_SPEAKER */ + APP_USBD_AUDIO_TERMINAL_OUT_COMM_SPEAKER = 0x0306, /**< COMM_SPEAKER */ + APP_USBD_AUDIO_TERMINAL_OUT_LOW_FREQ_SPEAKER = 0x0307, /**< LOW_FREQ_SPEAKER */ + + /*Input/Output terminals*/ + APP_USBD_AUDIO_TERMINAL_IO_UNDEFINED = 0x0400, /**< UNDEFINED */ + APP_USBD_AUDIO_TERMINAL_IO_HANDSET = 0x0401, /**< HANDSET */ + APP_USBD_AUDIO_TERMINAL_IO_HEADSET = 0x0402, /**< HEADSET */ + APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_NONE = 0x0403, /**< SPEAKERPHONE_ECHO_NONE */ + APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_SUP = 0x0404, /**< SPEAKERPHONE_ECHO_SUP */ + APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_CAN = 0x0405, /**< SPEAKERPHONE_ECHO_CAN */ +} app_usbd_audio_terminal_type_t; + +/** + * @brief Audio class control interface header descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER + uint8_t bcdADC[2]; //!< BCD ADC + uint8_t wTotalLength[2]; //!< Total interfaces length + uint8_t bInCollection; //!< Input collection + uint8_t baInterfaceNr[]; //!< Interface number list +} app_usbd_audio_ac_iface_header_desc_t; + + +/** + * @brief Possible values of input terminal channel config + * + * @ref app_usbd_audio_input_terminal_desc_t::wChannelConfig + * */ +typedef enum { + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_FRONT = (1u << 0), /**< Channel config bit LEFT_FRONT */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_FRONT = (1u << 1), /**< Channel config bit RIGHT_FRONT */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_CENTER_FRONT = (1u << 2), /**< Channel config bit CENTER_FRONT */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LOW_FREQ_ENH = (1u << 3), /**< Channel config bit LOW_FREQ_ENH */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_SURROUND = (1u << 4), /**< Channel config bit LEFT_SURROUND */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_SURROUND = (1u << 5), /**< Channel config bit RIGHT_SURROUND */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_OF_CENTER = (1u << 6), /**< Channel config bit LEFT_OF_CENTER */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_OF_CENTER = (1u << 7), /**< Channel config bit RIGHT_OF_CENTER */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SURROUND = (1u << 8), /**< Channel config bit SURROUND */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SIDE_LEFT = (1u << 9), /**< Channel config bit SIDE_LEFT */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SIDE_RIGHT = (1u << 10), /**< Channel config bit SIDE_RIGHT */ + APP_USBD_AUDIO_IN_TERM_CH_CONFIG_TOP = (1u << 11), /**< Channel config bit TOP */ +} app_usbd_audio_in_term_ch_config_t; + +/** + * @brief Audio class input terminal descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL + uint8_t bTerminalID; //!< Terminal ID + uint8_t wTerminalType[2]; //!< Terminal type + uint8_t bAssocTerminal; //!< Association terminal + uint8_t bNrChannels; //!< Number of channels + uint8_t wChannelConfig[2]; //!< Channel config + uint8_t iChannelNames; //!< Channel names + uint8_t iTerminal; //!< Terminal string ID +} app_usbd_audio_input_terminal_desc_t; + +/** + * @brief Audio class output terminal descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL + uint8_t bTerminalID; //!< Terminal ID + uint8_t wTerminalType[2]; //!< Terminal type + uint8_t bAssocTerminal; //!< Association terminal + uint8_t bSourceID; //!< Source ID + uint8_t iTerminal; //!< Terminal string ID +} app_usbd_audio_output_terminal_desc_t; + +/** + * @brief Possible values of feature unit control field*/ +typedef enum { + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MUTE = (1u << 0), /**< Feature unit control bit MUTE */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_VOLUME = (1u << 1), /**< Feature unit control bit VOLUME */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_BASS = (1u << 2), /**< Feature unit control bit BASS */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MID = (1u << 3), /**< Feature unit control bit MID */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_TREBLE = (1u << 4), /**< Feature unit control bit TREBLE */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_GRAPH_EQ = (1u << 5), /**< Feature unit control bit GRAPH_EQ */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_AUTO_GAIN = (1u << 6), /**< Feature unit control bit AUTO_GAIN */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_DELAY = (1u << 7), /**< Feature unit control bit DELAY */ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_BASS_BOOST = (1u << 8), /**< Feature unit control bit BASS_BOOST*/ + APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_LOUDNESS = (1u << 9), /**< Feature unit control bit LOUDNESS */ +} app_usbd_audio_feature_unit_control_t; + +/** + * @brief Audio class feature unit descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT + uint8_t bUnitID; //!< Unit ID + uint8_t bSourceID; //!< Source ID + uint8_t bControlSize; //!< Control size + uint8_t bmaControls[]; //!< Controls array +} app_usbd_audio_feature_unit_desc_t; + +/** + * @brief Format tag in audio streaming interface descriptor + * + * @ref app_usbd_audio_as_iface_desc_t::wFormatTag + * */ +typedef enum { + APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_I_UNDEFINED = 0x0000, /**< AS format TYPE_I_UNDEFINED */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_PCM = 0x0001, /**< AS format PCM */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_PCM8 = 0x0002, /**< AS format PCM8 */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEEE_FLOAT = 0x0003, /**< AS format IEEE_FLOAT */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_ALAW = 0x0004, /**< AS format ALAW */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_MULAW = 0x0005, /**< AS format MULAW */ + + APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_II_UNDEFINED = 0x1000, /**< AS format TYPE_II_UNDEFINED */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_MPEG = 0x1001, /**< AS format MPEG */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_AC3 = 0x1002, /**< AS format AC3 */ + + APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_III_UNDEFINED = 0x2000, /**< AS format TYPE_III_UNDEFINED */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_AC_3 = 0x2001, /**< AS format IEC1937_AC_3 */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_1_LAYER1 = 0x2002, /**< AS format IEC1937_MPEG_1_LAYER1 */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_NOEXT = 0x2003, /**< AS format IEC1937_MPEG_2_NOEXT */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_EXT = 0x2004, /**< AS format IEC1937_MPEG_2_EXT */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_LAYER1_LS = 0x2005, /**< AS format IEC1937_MPEG_2_LAYER1_LS */ + APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_LAYER23_LS = 0x2005, /**< AS format IEC1937_MPEG_2_LAYER23_LS */ +} app_usbd_audio_as_iface_format_tag_t; + +/** + * @brief Audio class audio streaming interface descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_ac_iface_subtype_t + uint8_t bTerminalLink; //!< Terminal link + uint8_t bDelay; //!< Delay + uint8_t wFormatTag[2]; //!< Format TAG +} app_usbd_audio_as_iface_desc_t; + +/** + * @brief Audio class audio streaming format type I descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t + uint8_t bFormatType; //!< Format type: fixed value 1 + uint8_t bNrChannels; //!< Number of channels + uint8_t bSubframeSize; //!< Subframe size + uint8_t bBitResolution; //!< Bit resolution + uint8_t bSamFreqType; //!< Number of supported sampling frequencies + uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries) +} app_usbd_audio_as_format_type_one_desc_t; + + +/** + * @brief Audio class audio streaming format type II descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t + uint8_t bFormatType; //!< Format type: fixed value 2 + uint8_t wMaxBitRate[2]; //!< Maximum bitrate + uint8_t wSamplesPerFrame[2]; //!< Samples per frame + uint8_t bSamFreqType; //!< Number of supported sampling frequencies + uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries) +} app_usbd_audio_as_format_type_two_desc_t; + +/** + * @brief Audio class audio streaming format type III descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t + uint8_t bFormatType; //!< Format type: fixed value 1 + uint8_t bNrChannels; //!< Number of channels + uint8_t bSubframeSize; //!< Subframe size + uint8_t bBitResolution; //!< Bit resolution + uint8_t bSamFreqType; //!< Number of supported sampling frequencies + uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries) +} app_usbd_audio_as_format_type_three_desc_t; + +/** + * @brief Audio class audio endpoint descriptor + */ +typedef struct { + uint8_t bLength; //!< Length of the descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT + uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_EP_SUBTYPE_GENERAL + uint8_t bmAttributes; //!< Audio endpoint attributes + uint8_t bLockDelayUnits; //!< Lock delay units + uint8_t wLockDelay[2]; //!< Lock delay value +} app_usbd_audio_as_endpoint_desc_t; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_AUDIO_TYPES_H__ */ + diff --git a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c b/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c new file mode 100644 index 0000000..a19f87c --- /dev/null +++ b/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c @@ -0,0 +1,727 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if APP_USBD_CLASS_CDC_ACM_ENABLED +#include "app_usbd_cdc_acm.h" +#include + +/** + * @defgroup app_usbd_cdc_acm_internal CDC ACM internals + * @{ + * @ingroup app_usbd_cdc + * @internal + */ + + +#define NRF_LOG_MODULE_NAME "CDC_ACM" +#if APP_USBD_CDC_ACM_LOG_ENABLED +#else //APP_USBD_CDC_ACM_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //APP_USBD_CDC_ACM_LOG_ENABLED +#include "nrf_log.h" + + +#define APP_USBD_CDC_ACM_COMM_IFACE_IDX 0 /**< CDC ACM class comm interface index */ +#define APP_USBD_CDC_ACM_DATA_IFACE_IDX 1 /**< CDC ACM class data interface index */ + +#define APP_USBD_CDC_ACM_COMM_EPIN_IDX 0 /**< CDC ACM comm class endpoint IN index */ +#define APP_USBD_CDC_ACM_DATA_EPIN_IDX 0 /**< CDC ACM data class endpoint IN index */ +#define APP_USBD_CDC_ACM_DATA_EPOUT_IDX 1 /**< CDC ACM data class endpoint OUT index */ + +/** + * @brief Auxiliary function to access cdc_acm class instance data + * + * @param[in] p_inst Class instance data + * @return CDC ACM class instance data @ref app_usbd_cdc_acm_t + */ +static inline app_usbd_cdc_acm_t const * cdc_acm_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_cdc_acm_t const *)p_inst; +} + +/** + * @brief Auxiliary function to access cdc_acm class context data + * + * @param[in] p_cdc_acm CDC ACM class instance data + * @return CDC ACM class context data @ref app_usbd_cdc_acm_ctx_t + */ +static inline app_usbd_cdc_acm_ctx_t * cdc_acm_ctx_get(app_usbd_cdc_acm_t const * p_cdc_acm) +{ + ASSERT(p_cdc_acm != NULL); + ASSERT(p_cdc_acm->specific.p_data != NULL); + return &p_cdc_acm->specific.p_data->ctx; +} + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] event user Event type @ref app_usbd_cdc_acm_user_event_t + * */ +static inline void user_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_cdc_acm_user_event_t event) +{ + app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); + if (p_cdc_acm->specific.inst.user_ev_handler != NULL) + { + p_cdc_acm->specific.inst.user_ev_handler(p_inst, event); + } +} + +/** + * @brief Auxiliary function to access CDC ACM COMM IN endpoint address + * + * @param[in] p_inst Class instance data + * + * @return IN endpoint address + */ +static inline nrf_drv_usbd_ep_t comm_ep_in_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_COMM_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_COMM_EPIN_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Auxiliary function to access CDC ACM DATA IN endpoint address + * + * @param[in] p_inst Class instance data + * + * @return IN endpoint address + */ +static inline nrf_drv_usbd_ep_t data_ep_in_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPIN_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Auxiliary function to access CDC ACM DATA OUT endpoint address + * + * @param[in] p_inst Class instance data + * + * @return OUT endpoint address + */ +static inline nrf_drv_usbd_ep_t data_ep_out_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPOUT_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Internal SETUP standard IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR: + { + size_t dsc_len = 0; + + /* Try to find descriptor in class internals*/ + void const * p_dsc = app_usbd_class_descriptor_find(p_inst, + p_setup_ev->setup.wValue.hb, + p_setup_ev->setup.wValue.lb, + &dsc_len); + if (p_dsc != NULL) + { + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_dsc, dsc_len); + } + + break; + } + case APP_USBD_SETUP_STDREQ_GET_INTERFACE: + { + + size_t tx_maxsize; + uint8_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_maxsize); + + p_tx_buff[0] = 0; + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + p_tx_buff, + sizeof(uint8_t)); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP standard OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + + switch (p_setup_ev->setup.bmRequest) + { + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_CDC_REQ_GET_LINE_CODING: + { + if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + &p_cdc_acm_ctx->line_coding, + sizeof(app_usbd_cdc_line_coding_t)); + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +static ret_code_t cdc_acm_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context) +{ + if (status != NRF_USBD_EP_OK) + { + return NRF_ERROR_INTERNAL; + } + + app_usbd_cdc_acm_t const * p_cdc_acm = p_context; + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + switch (p_cdc_acm_ctx->request.type) + { + case APP_USBD_CDC_REQ_SET_LINE_CODING: + { + memcpy(&p_cdc_acm_ctx->line_coding, + &p_cdc_acm_ctx->request.payload.line_coding, + sizeof(app_usbd_cdc_line_coding_t)); + + NRF_LOG_INFO("REQ_SET_LINE_CODING: baudrate: %"PRIu32", databits: %u, " + "format: %u, parity: %u\r\n", + uint32_decode(p_cdc_acm_ctx->line_coding.dwDTERate), + p_cdc_acm_ctx->line_coding.bDataBits, + p_cdc_acm_ctx->line_coding.bCharFormat, + p_cdc_acm_ctx->line_coding.bParityType); + break; + } + default: + return NRF_ERROR_NOT_SUPPORTED; + } + + return NRF_SUCCESS; +} + +static ret_code_t cdc_acm_req_out_datastage(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + p_cdc_acm_ctx->request.type = p_setup_ev->setup.bmRequest; + p_cdc_acm_ctx->request.len = p_setup_ev->setup.wLength.w; + + /*Request setup data*/ + NRF_DRV_USBD_TRANSFER_OUT(transfer, + &p_cdc_acm_ctx->request.payload, + p_cdc_acm_ctx->request.len); + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPOUT0, &transfer, NULL); + if (ret == NRF_SUCCESS) + { + const app_usbd_core_setup_data_handler_desc_t desc = { + .handler = cdc_acm_req_out_data_cb, + .p_context = (void*)p_cdc_acm + }; + + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +/** + * @brief Internal SETUP class OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_CDC_REQ_SET_LINE_CODING: + { + if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return cdc_acm_req_out_datastage(p_inst, p_setup_ev); + } + case APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE: + { + if (p_setup_ev->setup.wLength.w != 0) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + NRF_LOG_INFO("REQ_SET_CONTROL_LINE_STATE: 0x%x\r\n", p_setup_ev->setup.wValue.w); + + bool old_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ? + true : false; + p_cdc_acm_ctx->line_state = p_setup_ev->setup.wValue.w; + + bool new_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ? + true : false; + + if (old_dtr == new_dtr) + { + return NRF_SUCCESS; + } + + const app_usbd_cdc_acm_user_event_t ev = new_dtr ? + APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN : APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE; + + user_event_handler(p_inst, ev); + + if (!new_dtr) + { + /*Abort DATA endpoints on port close */ + nrf_drv_usbd_ep_t ep; + ep = data_ep_in_addr_get(p_inst); + usbd_drv_ep_abort(ep); + ep = data_ep_out_addr_get(p_inst); + usbd_drv_ep_abort(ep); + } + + return NRF_SUCCESS; + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Control endpoint handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + ASSERT(p_inst != NULL); + ASSERT(p_setup_ev != NULL); + + app_usbd_setup_reqrec_t req_rec = app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType); + app_usbd_setup_reqtype_t req_type = app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType); + if (req_rec == APP_USBD_SETUP_REQREC_ENDPOINT && + req_type == APP_USBD_SETUP_REQTYPE_STD) + { + return app_usbd_endpoint_std_req_handle(p_inst, p_setup_ev); + } + + if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN) + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_in(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_in(p_inst, p_setup_ev); + default: + break; + } + } + else /*APP_USBD_SETUP_REQDIR_OUT*/ + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_out(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_out(p_inst, p_setup_ev); + default: + break; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +static ret_code_t cdc_acm_endpoint_ev(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + if (comm_ep_in_addr_get(p_inst) == p_event->drv_evt.data.eptransfer.ep) + { + NRF_LOG_INFO("EPIN_COMM: notify\r\n"); + return NRF_SUCCESS; + } + + if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep)) + { + switch (p_event->drv_evt.data.eptransfer.status) + { + case NRF_USBD_EP_OK: + NRF_LOG_INFO("EPIN_DATA: %02x done\r\n", p_event->drv_evt.data.eptransfer.ep); + user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_TX_DONE); + return NRF_SUCCESS; + case NRF_USBD_EP_ABORTED: + return NRF_SUCCESS; + default: + return NRF_ERROR_INTERNAL; + } + } + + if (NRF_USBD_EPOUT_CHECK(p_event->drv_evt.data.eptransfer.ep)) + { + switch (p_event->drv_evt.data.eptransfer.status) + { + case NRF_USBD_EP_OK: + NRF_LOG_INFO("EPOUT_DATA: %02x done\r\n", p_event->drv_evt.data.eptransfer.ep); + user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE); + return NRF_SUCCESS; + case NRF_USBD_EP_WAITING: + case NRF_USBD_EP_ABORTED: + return NRF_SUCCESS; + default: + return NRF_ERROR_INTERNAL; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + + +/** + * @brief @ref app_usbd_class_methods_t::event_handler + */ +static ret_code_t cdc_acm_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + ret_code_t ret = NRF_SUCCESS; + switch (p_event->app_evt.type) + { + case APP_USBD_EVT_DRV_SOF: + break; + case APP_USBD_EVT_DRV_RESET: + break; + case APP_USBD_EVT_DRV_SETUP: + ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event); + break; + case APP_USBD_EVT_DRV_EPTRANSFER: + ret = cdc_acm_endpoint_ev(p_inst, p_event); + break; + case APP_USBD_EVT_DRV_SUSPEND: + user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_SUSPEND); + break; + case APP_USBD_EVT_DRV_RESUME: + user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RESUME); + break; + case APP_USBD_EVT_INST_APPEND: + { + ret = app_usbd_class_sof_register(p_inst); + break; + } + case APP_USBD_EVT_INST_REMOVE: + { + ret = app_usbd_class_sof_unregister(p_inst); + break; + } + case APP_USBD_EVT_START: + user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_START); + break; + case APP_USBD_EVT_STOP: + user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_STOP); + break; + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + return ret; +} + +/** + * @brief @ref app_usbd_class_methods_t::get_descriptors + */ +static const void * cdc_acm_get_descriptors(app_usbd_class_inst_t const * p_inst, + size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); + + *p_size = p_cdc_acm->specific.inst.raw_desc_size; + return p_cdc_acm->specific.inst.p_raw_desc; +} + +/** + * @brief Public cdc_acm class interface + * + * */ +const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods = { + .event_handler = cdc_acm_event_handler, + .get_descriptors = cdc_acm_get_descriptors, +}; + + +ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm, + const void * p_buf, + size_t length) +{ + app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + bool dtr_state = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ? + true : false; + if (!dtr_state) + { + /*Port is not opened*/ + return NRF_ERROR_INVALID_STATE; + } + + nrf_drv_usbd_ep_t ep = data_ep_in_addr_get(p_inst); + NRF_DRV_USBD_TRANSFER_IN(transfer, p_buf, length); + return app_usbd_core_ep_transfer(ep, &transfer, NULL); +} + +size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm) +{ + app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm); + nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(p_inst); + + nrf_drv_usbd_transfer_t transfer; + ret_code_t ret = nrf_drv_usbd_ep_status_get(ep, &transfer); + if (ret != NRF_SUCCESS) + { + return 0; + } + + return transfer.size; +} + +ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm, + void * p_buf, + size_t length) +{ + ASSERT((length % NRF_DRV_USBD_EPSIZE) == 0); + app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + bool dtr_state = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ? + true : false; + if (!dtr_state) + { + /*Port is not opened*/ + return NRF_ERROR_INVALID_STATE; + } + + nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(p_inst); + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_buf, length); + return app_usbd_core_ep_transfer(ep, &transfer, NULL); +} + +static ret_code_t cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm) +{ + app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm); + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + nrf_drv_usbd_ep_t ep = comm_ep_in_addr_get(p_inst); + + NRF_DRV_USBD_TRANSFER_OUT(transfer, + &p_cdc_acm_ctx->request.payload, + sizeof(app_usbd_cdc_acm_notify_t)); + return app_usbd_core_ep_transfer(ep, &transfer, NULL); +} + +ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm, + app_usbd_cdc_acm_serial_state_t serial_state, + bool value) +{ + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = NRF_SUCCESS; + switch (serial_state) + { + case APP_USBD_CDC_ACM_SERIAL_STATE_DCD: + case APP_USBD_CDC_ACM_SERIAL_STATE_DSR: + case APP_USBD_CDC_ACM_SERIAL_STATE_BREAK: + case APP_USBD_CDC_ACM_SERIAL_STATE_RING: + case APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING: + case APP_USBD_CDC_ACM_SERIAL_STATE_PARITY: + case APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN: + + if (value) + { + p_cdc_acm_ctx->serial_state |= serial_state; + } + else + { + p_cdc_acm_ctx->serial_state &= ~serial_state; + } + + break; + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + if (ret == NRF_SUCCESS) + { + app_usbd_cdc_acm_notify_t * notify = &p_cdc_acm_ctx->request.payload.notify; + notify->cdc_notify.bmRequestType = app_usbd_setup_req_val(APP_USBD_SETUP_REQREC_INTERFACE, + APP_USBD_SETUP_REQTYPE_CLASS, + APP_USBD_SETUP_REQDIR_IN); + notify->cdc_notify.bmRequest = APP_USBD_CDC_NOTIF_SERIAL_STATE; + notify->cdc_notify.wValue = 0; + notify->cdc_notify.wIndex = 0; + notify->cdc_notify.wLength = sizeof(notify->serial_state); + + notify->serial_state = p_cdc_acm_ctx->serial_state; + + ret = cdc_acm_serial_state_notify(p_cdc_acm); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm, + app_usbd_cdc_acm_line_state_t line_state, + uint32_t * value) +{ + app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = NRF_SUCCESS; + switch (line_state) + { + case APP_USBD_CDC_ACM_LINE_STATE_DTR: + case APP_USBD_CDC_ACM_LINE_STATE_RTS: + *value = (p_cdc_acm_ctx->line_state & line_state) != 0; + break; + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +#endif /* APP_USBD_CLASS_CDC_ACM_ENABLED */ + +/** @} */ diff --git a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h b/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h new file mode 100644 index 0000000..4431b13 --- /dev/null +++ b/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h @@ -0,0 +1,299 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_CDC_ACM_H__ +#define APP_USBD_CDC_ACM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_usbd.h" +#include "app_usbd_class_base.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_descriptor.h" + +#include "app_usbd_cdc_desc.h" +#include "app_usbd_cdc_types.h" +#include "app_usbd_cdc_acm_internal.h" + +/** + * @defgroup app_usbd_cdc_acm USB CDC ACM class + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with types, definitions and API used by CDC ACM class. + * + * @details References: + * - "Universal Serial Bus Class Definitions for Communications Devices" + * Revision 1.2, November 3, 2010 + * - "Universal Serial Bus Communications Class Subclass Specification for PSTN Devices" + * Revision 1.2, February 9, 2007 + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief CDC ACM class instance type + * + * @ref APP_USBD_CLASS_TYPEDEF + */ +typedef struct { } app_usbd_cdc_acm_t; +#else +/*lint -save -e10 -e26 -e123 -e505 */ +APP_USBD_CLASS_TYPEDEF(app_usbd_cdc_acm, \ + APP_USBD_CDC_ACM_CONFIG(0, 0, 0, 0, 0), \ + APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC, \ + APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC \ +); +/*lint -restore*/ +#endif + + +/*lint -save -e407 */ + +/** + * @brief Events passed to user event handler + * + * @note Example prototype of user event handler: + * + * @code + void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_cdc_acm_user_event_t event); + * @endcode + */ +typedef enum app_usbd_cdc_acm_user_event_e { + APP_USBD_CDC_ACM_USER_EVT_SUSPEND = 0, /**< User event SUSPEND */ + APP_USBD_CDC_ACM_USER_EVT_RESUME, /**< User event RESUME */ + APP_USBD_CDC_ACM_USER_EVT_START, /**< User event START */ + APP_USBD_CDC_ACM_USER_EVT_STOP, /**< User event STOP */ + + APP_USBD_CDC_ACM_USER_EVT_RX_DONE, /**< User event RX_DONE */ + APP_USBD_CDC_ACM_USER_EVT_TX_DONE, /**< User event TX_DONE */ + + APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN, /**< User event PORT_OPEN */ + APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE, /**< User event PORT_CLOSE */ +} app_usbd_cdc_acm_user_event_t; + +/*lint -restore*/ + +/** + * @brief Default CDC ACM descriptors + * + * @param comm_interface COMM interface number + * @param comm_epin COMM interface IN endpoint + * @param data_interface DATA interface number + * @param data_epin DATA interface IN endpoint + * @param data_epout DATA interface OUT endpoint + */ +#define APP_USBD_CDC_ACM_DEFAULT_DESC(comm_interface, \ + comm_epin, \ + data_interface, \ + data_epin, \ + data_epout) \ + APP_USBD_CDC_IAD_DSC(comm_interface, \ + APP_USBD_CDC_SUBCLASS_ACM, \ + APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \ + APP_USBD_CDC_COMM_INTERFACE_DSC(comm_interface, \ + APP_USBD_CDC_SUBCLASS_ACM, \ + APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \ + APP_USBD_CDC_HEADER_DSC(0x0110) \ + APP_USBD_CDC_CALL_MGMT_DSC(0x03, data_interface) \ + APP_USBD_CDC_ACM_DSC(0x02) \ + APP_USBD_CDC_UNION_DSC(comm_interface, data_interface) \ + APP_USBD_CDC_COM_EP_DSC(comm_epin, NRF_DRV_USBD_EPSIZE) \ + APP_USBD_CDC_DATA_INTERFACE_DSC(data_interface, 0, 0) \ + APP_USBD_CDC_DATA_EP_DSC(data_epin, data_epout, NRF_DRV_USBD_EPSIZE) + +/** + * @brief Global definition of app_usbd_cdc_acm_t class instance + * + * @param instance_name Name of global instance + * @param interfaces_configs Interfaces configurations + * @param user_ev_handler User event handler (optional) + * @param raw_descriptors Raw descriptor table + * + * @note This macro is just simplified version of @ref APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL + * + */ +#define APP_USBD_CDC_ACM_GLOBAL_DEF(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) \ + APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) + +/** + * @@brief Helper function to get class instance from CDC ACM class + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF) + * @return Base class instance + */ +static inline app_usbd_class_inst_t const * +app_usbd_cdc_acm_class_inst_get(app_usbd_cdc_acm_t const * p_cdc_acm) +{ + return &p_cdc_acm->base; +} + +/** + * @brief Helper function to get cdc_acm specific request from cdc_acm class + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF) + * @return CDC ACM class specific request + */ +static inline app_usbd_cdc_acm_req_t * +app_usbd_cdc_acm_class_request_get(app_usbd_cdc_acm_t const * p_cdc_acm) +{ + return &p_cdc_acm->specific.p_data->ctx.request; +} + +/** + * @brief Helper function to get cdc_acm from base class instance + * + * @param[in] p_inst Base class instance + * + * @return CDC ACM class handle + */ +static inline app_usbd_cdc_acm_t const * +app_usbd_cdc_acm_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_cdc_acm_t const *)p_inst; +} + + +/** + * @brief Writes data to CDC ACM serial port. + * + * This is asynchronous call. User should wait for @ref APP_USBD_CDC_ACM_USER_EVT_TX_DONE event + * to be sure that all data has been sent and input buffer could be accessed again. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF) + * @param[in] p_buf Input buffer + * @param[in] length Input buffer length + * + * @return Standard error code + */ +ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm, + const void * p_buf, + size_t length); + +/** + * @brief Returns the amount of data to be read. + * + * This function should be used on @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event to get + * information how many bytes have been transfered. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF) + * + * @return Amount of data transfered. + */ +size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm); + +/** + * @brief Reads data from CDC ACM serial port. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF) + * @param[out] p_buf Output buffer + * @param[in] length Output buffer length (must by multiple of @ref NRF_DRV_USBD_EPSIZE) + * + * @return Standard error code + */ +ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm, + void * p_buf, + size_t length); +/** + * @brief Serial state notifications + * */ +typedef enum { + APP_USBD_CDC_ACM_SERIAL_STATE_DCD = (1u << 0), /**< Notification bit DCD */ + APP_USBD_CDC_ACM_SERIAL_STATE_DSR = (1u << 1), /**< Notification bit DSR */ + APP_USBD_CDC_ACM_SERIAL_STATE_BREAK = (1u << 2), /**< Notification bit BREAK */ + APP_USBD_CDC_ACM_SERIAL_STATE_RING = (1u << 3), /**< Notification bit RING */ + APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING = (1u << 4), /**< Notification bit FRAMING*/ + APP_USBD_CDC_ACM_SERIAL_STATE_PARITY = (1u << 5), /**< Notification bit PARITY */ + APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN = (1u << 6), /**< Notification bit OVERRUN*/ +} app_usbd_cdc_acm_serial_state_t; + +/** + * @brief Serial line state + * */ +typedef enum { + APP_USBD_CDC_ACM_LINE_STATE_DTR = (1u << 0), /**< Line state bit DTR*/ + APP_USBD_CDC_ACM_LINE_STATE_RTS = (1u << 1), /**< Line state bit RTS*/ +} app_usbd_cdc_acm_line_state_t; + +/** + * @brief Serial state notification via IN interrupt endpoint + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF) + * @param[in] serial_state Serial state notification type + * @param[in] value Serial state value + * + * @return Standard error code + */ +ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm, + app_usbd_cdc_acm_serial_state_t serial_state, + bool value); + +/** + * @brief Control line value get. + * + * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF) + * @param[in] line_state Line control value type + * @param[out] value Line control value + * + * @return Standard error code + */ +ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm, + app_usbd_cdc_acm_line_state_t line_state, + uint32_t * value); + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_CDC_ACM_H__ */ diff --git a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h b/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h new file mode 100644 index 0000000..274b75f --- /dev/null +++ b/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h @@ -0,0 +1,218 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_CDC_ACM_INTERNAL_H__ +#define APP_USBD_CDC_ACM_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include "app_util.h" + +/** + * @defgroup app_usbd_cdc_acm_internal USB CDC ACM internals + * @ingroup app_usbd_cdc_acm + * @brief @tagAPI52840 Internals of the USB ACM class implementation. + * @{ + */ + +/** + * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF in cdc_acm class + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_cdc_acm); + +/*lint -save -e165*/ +/** + * @brief Forward declaration of @ref app_usbd_cdc_acm_user_event_e + * + */ +enum app_usbd_cdc_acm_user_event_e; + +/*lint -restore*/ + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] event User event + * + * */ +typedef void (*app_usbd_cdc_acm_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst, + enum app_usbd_cdc_acm_user_event_e event); + +/** + * @brief CDC ACM class part of class instance data + */ +typedef struct { + uint8_t const * p_raw_desc; //!< CDC ACM class descriptors + size_t raw_desc_size; //!< CDC ACM class descriptors size + + app_usbd_cdc_acm_user_ev_handler_t user_ev_handler; //!< User event handler +} app_usbd_cdc_acm_inst_t; + + +/** + * @brief CDC ACM serial state class notify + * */ +typedef struct { + app_usbd_cdc_notify_t cdc_notify; + uint16_t serial_state; +} app_usbd_cdc_acm_notify_t; + +/** + * @brief CDC ACM class specific request handled via control endpoint + * */ +typedef struct { + uint8_t type; //!< Request type + uint8_t len; //!< Request length + + union { + app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding + app_usbd_cdc_acm_notify_t notify; //!< CDC ACM class notify + } payload; +} app_usbd_cdc_acm_req_t; + + +/** + * @brief CDC ACM class context + * */ +typedef struct { + app_usbd_cdc_acm_req_t request; //!< CDC ACM class request + app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding + + uint16_t line_state; //!< CDC ACM line state bitmap, DTE side + uint16_t serial_state; //!< CDC ACM serial state bitmap, DCE side +} app_usbd_cdc_acm_ctx_t; + + +/** + * @brief CDC ACM class configuration macro + * + * Used by @ref APP_USBD_CDC_ACM_GLOBAL_DEF + * + * @param iface_comm Interface number of cdc_acm control + * @param epin_comm COMM subclass IN endpoint + * @param iface_data Interface number of cdc_acm DATA + * @param epin_data COMM subclass IN endpoint + * @param epout_data COMM subclass OUT endpoint + * + * */ +#define APP_USBD_CDC_ACM_CONFIG(iface_comm, epin_comm, iface_data, epin_data, epout_data) \ + ((iface_comm, epin_comm), \ + (iface_data, epin_data, epout_data)) + + +/** + * @brief Specific class constant data for cdc_acm class + * + * @ref app_usbd_cdc_acm_inst_t + */ +#define APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC app_usbd_cdc_acm_inst_t inst; + + +/** + * @brief Configures cdc_acm class instance + * + * @param descriptors Mass storage class descriptors (raw table) + * @param user_event_handler User event handler + */ +#define APP_USBD_CDC_ACM_INST_CONFIG(descriptors, user_event_handler) \ + .inst = { \ + .p_raw_desc = descriptors, \ + .raw_desc_size = sizeof(descriptors), \ + .user_ev_handler = user_event_handler, \ + } + +/** + * @brief Specific class data for cdc_acm class + * + * @ref app_usbd_cdc_acm_ctx_t + * */ +#define APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC app_usbd_cdc_acm_ctx_t ctx; + + +/** + * @brief CDC ACM class descriptors config macro + * + * @param interface_number Interface number + * @param ... Extracted endpoint list + * */ +#define APP_USBD_CDC_ACM_DSC_CONFIG(interface_number, ...) { \ + APP_USBD_CDC_ACM_INTERFACE_DSC(interface_number, \ + 0, \ + 0, \ + APP_USBD_CDC_ACM_SUBCLASS_CDC_ACMCONTROL) \ +} + +/** + * @brief Public cdc_acm class interface + * + * */ +extern const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods; + +/** + * @brief Global definition of @ref app_usbd_cdc_acm_t class + * + */ +#define APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \ + interfaces_configs, \ + user_ev_handler, \ + raw_descriptors) \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_cdc_acm, \ + &app_usbd_cdc_acm_class_methods, \ + interfaces_configs, \ + (APP_USBD_CDC_ACM_INST_CONFIG(raw_descriptors, user_ev_handler)) \ + ) + + +/** @} */ + + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_CDC_ACM_INTERNAL_H__ */ diff --git a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h b/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h new file mode 100644 index 0000000..653f6ed --- /dev/null +++ b/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h @@ -0,0 +1,208 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_CDC_DESC_H__ +#define APP_USBD_CDC_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "app_usbd_descriptor.h" +#include "app_usbd_cdc_types.h" + +/** + * @defgroup app_usbd_cdc_desc CDC class descriptors + * @brief @tagAPI52840 Descriptors used in the USB CDC class implementation. + * @ingroup app_usbd_cdc_acm + * + * A group of macros used to initialize CDC descriptors + * @{ + */ + +/** + * @brief Initializer of IAD descriptor for CDC class + * + * @param interface_number Interface number + * @param subclass Subclass, @ref app_usbd_cdc_subclass_t + * @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t + * */ +#define APP_USBD_CDC_IAD_DSC(interface_number, subclass, protocol) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iad_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION, \ + /*.bFirstInterface = */ interface_number, \ + /*.bInterfaceCount = */ 2, \ + /*.bFunctionClass = */ APP_USBD_CDC_COMM_CLASS, \ + /*.bFunctionSubClass = */ subclass, \ + /*.bFunctionProtocol = */ protocol, \ + /*.iFunction = */ 0, \ + +/** + * @brief Initializer of interface descriptor for CDC COMM class + * + * @param interface_number Interface number + * @param subclass Subclass, @ref app_usbd_cdc_subclass_t + * @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t + * */ +#define APP_USBD_CDC_COMM_INTERFACE_DSC(interface_number, subclass, protocol) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \ + /*.bInterfaceNumber = */ interface_number, \ + /*.bAlternateSetting = */ 0x00, \ + /*.bNumEndpoints = */ 1, \ + /*.bInterfaceClass = */ APP_USBD_CDC_COMM_CLASS, \ + /*.bInterfaceSubClass = */ subclass, \ + /*.bInterfaceProtocol = */ protocol, \ + /*.iInterface = 0, */ 0x00, \ + + +/** + * @brief Initializer of interface descriptor for CDC DATA class + * + * @param interface_number Interface number + * @param subclass Subclass, @ref app_usbd_cdc_subclass_t + * @param protocol Protocol, @ref app_usbd_cdc_data_protocol_t + * */ +#define APP_USBD_CDC_DATA_INTERFACE_DSC(interface_number, subclass, protocol) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \ + /*.bInterfaceNumber = */ interface_number, \ + /*.bAlternateSetting = */ 0x00, \ + /*.bNumEndpoints = */ 2, \ + /*.bInterfaceClass = */ APP_USBD_CDC_DATA_CLASS, \ + /*.bInterfaceSubClass = */ subclass, \ + /*.bInterfaceProtocol = */ protocol, \ + /*.iInterface = 0, */ 0x00, \ + + + +/** + * @brief Initializer of endpoint descriptor for CDC COM class + * + * @param endpoint_in IN endpoint + * @param ep_size Endpoint size + * */ +#define APP_USBD_CDC_COM_EP_DSC(endpoint_in, ep_size) \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint_in, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ 16, \ + +/** + * @brief Initializer of endpoint descriptors for CDC DATA class + * + * @param endpoint_in IN endpoint + * @param endpoint_out OUT endpoint + * @param ep_size Endpoint size + * */ +#define APP_USBD_CDC_DATA_EP_DSC(endpoint_in, endpoint_out, ep_size) \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint_in, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ 0, \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint_out, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ 0, \ + +/** + * @brief Initializer of endpoint descriptors for CDC header descriptor + * + * @param bcd_cdc BCD CDC version + */ +#define APP_USBD_CDC_HEADER_DSC(bcd_cdc) \ + /*.bLength = */ sizeof(app_usbd_cdc_desc_header_t), \ + /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_HEADER, \ + /*.bcdCDC = */ APP_USBD_U16_TO_RAW_DSC(bcd_cdc), \ + +/** + * @brief Initializer of endpoint descriptors for CDC call management descriptor + * + * @param capabilities Capabilities + * @param data_interface Data interface + */ +#define APP_USBD_CDC_CALL_MGMT_DSC(capabilities, data_interface) \ + /*.bLength = */ sizeof(app_usbd_cdc_desc_call_mgmt_t), \ + /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_CALL_MGMT, \ + /*.bmCapabilities = */ capabilities, \ + /*.bDataInterface = */ data_interface, \ + + +/** + * @brief Initializer of endpoint descriptors for CDC DATA class + * + * @param capabilities Capabilities + */ +#define APP_USBD_CDC_ACM_DSC(capabilities) \ + /*.bLength = */ sizeof(app_usbd_cdc_desc_acm_t), \ + /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_ACM, \ + /*.bmCapabilities = */ capabilities, \ + +/** + * @brief Initializer of endpoint descriptors for CDC DATA class + * + * @param control_interface Control interface + * @param ... Subordinate interfaces list + */ +#define APP_USBD_CDC_UNION_DSC(control_interface, ...) \ + /*.bLength = */ sizeof(app_usbd_cdc_desc_union_t) + (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \ + /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_UNION, \ + /*.bControlInterface = */ control_interface, \ + /*.bSubordinateInterface = */ __VA_ARGS__, \ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_CDC_H__ */ diff --git a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h b/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h new file mode 100644 index 0000000..701f1a4 --- /dev/null +++ b/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h @@ -0,0 +1,360 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_CDC_TYPES_H__ +#define APP_USBD_CDC_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + +/** + * @defgroup app_usbd_cdc_types CDC class types + * @ingroup app_usbd_cdc_acm + * + * @brief @tagAPI52840 Variable types used by the CDC class implementation. + * @{ + */ + +/** + * @brief Communications Interface Class code + * + * Used for control interface in communication class. + * @ref app_usbd_descriptor_iface_t::bInterfaceClass + */ +#define APP_USBD_CDC_COMM_CLASS 0x02 + +/** + * @brief Data Class Interface code + * + * Used for data interface in communication class. + * @ref app_usbd_descriptor_iface_t::bInterfaceClass + */ +#define APP_USBD_CDC_DATA_CLASS 0x0A + +/** + * @brief CDC subclass possible values + * + * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass + */ +typedef enum { + APP_USBD_CDC_SUBCLASS_RESERVED = 0x00, /**< Reserved in documentation */ + APP_USBD_CDC_SUBCLASS_DLCM = 0x01, /**< Direct Line Control Model */ + APP_USBD_CDC_SUBCLASS_ACM = 0x02, /**< Abstract Control Model */ + APP_USBD_CDC_SUBCLASS_TCM = 0x03, /**< Telephone Control Model */ + APP_USBD_CDC_SUBCLASS_MCCM = 0x04, /**< Multi-Channel Control Model */ + APP_USBD_CDC_SUBCLASS_CAPI = 0x05, /**< CAPI Control Model */ + APP_USBD_CDC_SUBCLASS_ENCM = 0x06, /**< Ethernet Networking Control Model */ + APP_USBD_CDC_SUBCLASS_ATM = 0x07, /**< ATM Networking Control Model */ + APP_USBD_CDC_SUBCLASS_WHCM = 0x08, /**< Wireless Handset Control Model */ + APP_USBD_CDC_SUBCLASS_DM = 0x09, /**< Device Management */ + APP_USBD_CDC_SUBCLASS_MDLM = 0x0A, /**< Mobile Direct Line Model */ + APP_USBD_CDC_SUBCLASS_OBEX = 0x0B, /**< OBEX */ + APP_USBD_CDC_SUBCLASS_EEM = 0x0C, /**< Ethernet Emulation Model */ + APP_USBD_CDC_SUBCLASS_NCM = 0x0D /**< Network Control Model */ +} app_usbd_cdc_subclass_t; + +/** + * @brief CDC protocol possible values + * + * @ref app_usbd_descriptor_iface_t::bInterfaceProtocol + */ +typedef enum { + APP_USBD_CDC_COMM_PROTOCOL_NONE = 0x00, /**< No class specific protocol required */ + APP_USBD_CDC_COMM_PROTOCOL_AT_V250 = 0x01, /**< AT Commands: V.250 etc */ + APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101 = 0x02, /**< AT Commands defined by PCCA-101 */ + APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101_ANNEXO = 0x03, /**< AT Commands defined by PCCA-101 & Annex O */ + APP_USBD_CDC_COMM_PROTOCOL_AT_GSM707 = 0x04, /**< AT Commands defined by GSM 07.07 */ + APP_USBD_CDC_COMM_PROTOCOL_AT_3GPP_27007 = 0x05, /**< AT Commands defined by 3GPP 27.007 */ + APP_USBD_CDC_COMM_PROTOCOL_AT_CDMA = 0x06, /**< AT Commands defined by TIA for CDMA */ + APP_USBD_CDC_COMM_PROTOCOL_EEM = 0x07, /**< Ethernet Emulation Model */ + APP_USBD_CDC_COMM_PROTOCOL_EXTERNAL = 0xFE, /**< External Protocol: Commands defined by Command Set Functional Descriptor */ + APP_USBD_CDC_COMM_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific */ +} app_usbd_cdc_comm_protocol_t; + +/** + * @brief CDC data interface protocols possible values + */ +typedef enum { + APP_USBD_CDC_DATA_PROTOCOL_NONE = 0x00, /**< No class specific protocol required */ + APP_USBD_CDC_DATA_PROTOCOL_NTB = 0x01, /**< Network Transfer Block */ + APP_USBD_CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, /**< Physical interface protocol for ISDN BRI */ + APP_USBD_CDC_DATA_PROTOCOL_HDLC = 0x31, /**< HDLC */ + APP_USBD_CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, /**< Transparent */ + APP_USBD_CDC_DATA_PROTOCOL_Q921M = 0x50, /**< Management protocol for Q.921 data link protocol */ + APP_USBD_CDC_DATA_PROTOCOL_Q921 = 0x51, /**< Data link protocol for Q.921 */ + APP_USBD_CDC_DATA_PROTOCOL_Q921TM = 0x52, /**< TEI-multiplexor for Q.921 data link protocol */ + APP_USBD_CDC_DATA_PROTOCOL_V42BIS = 0x90, /**< Data compression procedures */ + APP_USBD_CDC_DATA_PROTOCOL_Q931 = 0x91, /**< Euro-ISDN protocol control */ + APP_USBD_CDC_DATA_PROTOCOL_V120 = 0x92, /**< V.24 rate adaptation to ISDN */ + APP_USBD_CDC_DATA_PROTOCOL_CAPI20 = 0x93, /**< CAPI Commands */ + APP_USBD_CDC_DATA_PROTOCOL_HOST = 0xFD, /**< Host based driver. + * @note This protocol code should only be used in messages + * between host and device to identify the host driver portion + * of a protocol stack. + */ + APP_USBD_CDC_DATA_PROTOCOL_EXTERNAL = 0xFE, /**< The protocol(s) are described using a Protocol Unit Functional + * Descriptors on Communications Class Interface + */ + APP_USBD_CDC_DATA_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific */ +} app_usbd_cdc_data_protocol_t; + +/** + * @brief CDC Functional Descriptor types + */ +typedef enum { + APP_USBD_CDC_CS_INTERFACE = 0x24, /**< Class specific interface descriptor type*/ + APP_USBD_CDC_CS_ENDPOINT = 0x25 /**< Class specific endpoint descriptor type*/ +} app_usbd_cdc_func_type_t; + +/** + * @brief CDC Functional Descriptor subtypes + */ +typedef enum { + APP_USBD_CDC_SCS_HEADER = 0x00, /**< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface. */ + APP_USBD_CDC_SCS_CALL_MGMT = 0x01, /**< Call Management Functional Descriptor. */ + APP_USBD_CDC_SCS_ACM = 0x02, /**< Abstract Control Management Functional Descriptor. */ + APP_USBD_CDC_SCS_DLM = 0x03, /**< Direct Line Management Functional Descriptor. */ + APP_USBD_CDC_SCS_TEL_R = 0x04, /**< Telephone Ringer Functional Descriptor. */ + APP_USBD_CDC_SCS_TEL_CAP = 0x05, /**< Telephone Call and Line State Reporting Capabilities Functional Descriptor. */ + APP_USBD_CDC_SCS_UNION = 0x06, /**< Union Functional Descriptor */ + APP_USBD_CDC_SCS_COUNTRY_SEL = 0x07, /**< Country Selection Functional Descriptor */ + APP_USBD_CDC_SCS_TEL_OM = 0x08, /**< Telephone Operational Modes Functional Descriptor */ + APP_USBD_CDC_SCS_USB_TERM = 0x09, /**< USB Terminal Functional Descriptor */ + APP_USBD_CDC_SCS_NCT = 0x0A, /**< Network Channel Terminal Descriptor */ + APP_USBD_CDC_SCS_PU = 0x0B, /**< Protocol Unit Functional Descriptor */ + APP_USBD_CDC_SCS_EU = 0x0C, /**< Extension Unit Functional Descriptor */ + APP_USBD_CDC_SCS_MCM = 0x0D, /**< Multi-Channel Management Functional Descriptor */ + APP_USBD_CDC_SCS_CAPI = 0x0E, /**< CAPI Control Management Functional Descriptor */ + APP_USBD_CDC_SCS_ETH = 0x0F, /**< Ethernet Networking Functional Descriptor */ + APP_USBD_CDC_SCS_ATM = 0x10, /**< ATM Networking Functional Descriptor */ + APP_USBD_CDC_SCS_WHCM = 0x11, /**< Wireless Handset Control Model Functional Descriptor */ + APP_USBD_CDC_SCS_MDLM = 0x12, /**< Mobile Direct Line Model Functional Descriptor */ + APP_USBD_CDC_SCS_MDLM_DET = 0x13, /**< MDLM Detail Functional Descriptor */ + APP_USBD_CDC_SCS_DMM = 0x14, /**< Device Management Model Functional Descriptor */ + APP_USBD_CDC_SCS_OBEX = 0x15, /**< OBEX Functional Descriptor */ + APP_USBD_CDC_SCS_CS = 0x16, /**< Command Set Functional Descriptor */ + APP_USBD_CDC_SCS_CS_DET = 0x17, /**< Command Set Detail Functional Descriptor */ + APP_USBD_CDC_SCS_TEL_CM = 0x18, /**< Telephone Control Model Functional Descriptor */ + APP_USBD_CDC_SCS_OBEX_SI = 0x19, /**< OBEX Service Identifier Functional Descriptor */ + APP_USBD_CDC_SCS_NCM = 0x1A /**< NCM Functional Descriptor */ +} app_usbd_cdc_func_subtype_t; + +/* Make all descriptors packed */ +#pragma pack(push, 1) + +/** + * @brief Header Functional Descriptor + */ +typedef struct { + uint8_t bFunctionLength; /**< Size of this descriptor in bytes. */ + uint8_t bDescriptorType; /**< @ref APP_USBD_CDC_CS_INTERFACE descriptor type. */ + uint8_t bDescriptorSubtype; /**< Descriptor subtype @ref APP_USBD_CDC_SCS_HEADER */ + uint8_t bcdCDC[2]; /**< USB Class Definitions for Communications Devices Specification release number in binary-coded decimal. */ +} app_usbd_cdc_desc_header_t; + +/** + * @brief Call management capabilities + * + * @ref app_usbd_cdc_desc_call_mgmt_t::bmCapabilities bit + * */ +typedef enum { + APP_USBD_CDC_CALL_MGMT_SUPPORTED = (1 << 0), /**< Call management capability bit 0*/ + APP_USBD_CDC_CALL_MGMT_OVER_DCI = (1 << 1), /**< Call management capability bit 1*/ +} app_subd_cdc_call_mgmt_cap_t; + +/** + * @brief CDC Call Management Functional Descriptor + */ +typedef struct { + uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes. + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE + uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_CALL_MGMT + uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_call_mgmt_cap_t + uint8_t bDataInterface; //!< Data interface number +} app_usbd_cdc_desc_call_mgmt_t; + +/** + * @brief ACM capabilities + * + * @ref app_usbd_cdc_desc_acm_t::bmCapabilities bit + * */ +typedef enum { + APP_USBD_CDC_ACM_FEATURE_REQUESTS = (1 << 0), /**< ACM capability bit FEATURE_REQUESTS */ + APP_USBD_CDC_ACM_LINE_REQUESTS = (1 << 1), /**< ACM capability bit LINE_REQUESTS */ + APP_USBD_CDC_ACM_SENDBREAK_REQUESTS = (1 << 2), /**< ACM capability bit SENDBREAK_REQUESTS*/ + APP_USBD_CDC_ACM_NOTIFY_REQUESTS = (1 << 3), /**< ACM capability bit NOTIFY_REQUESTS */ +} app_subd_cdc_acm_cap_t; + +/** + * @brief CDC ACM Functional Descriptor + */ +typedef struct { + uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes. + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE + uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_ACM + uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_acm_cap_t +} app_usbd_cdc_desc_acm_t; + +/** + * @brief Union Functional Descriptor + */ +typedef struct { + uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes. + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE + uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_UNION + uint8_t bControlInterface; //!< The interface number of the Communications or Data Class interface, designated as the controlling interface for the union. + uint8_t bSubordinateInterface[]; //!< Interface number of subordinate interfaces in the union. Number of interfaced depends on descriptor size. +} app_usbd_cdc_desc_union_t; + +/** + * @brief Country Selection Functional Descriptor + */ +typedef struct { + uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes. + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE + uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_COUNTRY_SEL + uint8_t iCountryCodeRelDate; //!< Index of a string giving the release date for the implemented ISO 3166 Country Codes. +} app_usbd_cdc_desc_country_sel_t; + +/** + * @brief CDC Requests + * + */ +typedef enum { + /* CDC General */ + APP_USBD_CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0x00, /**< This request is used to issue a command in the format of the supported control protocol of the Communications Class interface. */ + APP_USBD_CDC_REQ_GET_ENCAPSULATED_RESPONSE = 0x01, /**< This request is used to request a response in the format of the supported control protocol of the Communications Class interface. */ + /* CDC PSTN */ + APP_USBD_CDC_REQ_SET_COMM_FEATURE = 0x02, /**< This request controls the settings for a particular communications feature of a particular target. */ + APP_USBD_CDC_REQ_GET_COMM_FEATURE = 0x03, /**< This request returns the current settings for the communications feature as selected. */ + APP_USBD_CDC_REQ_CLEAR_COMM_FEATURE = 0x04, /**< This request controls the settings for a particular communications feature of a particular target, setting the selected feature to its default state. */ + APP_USBD_CDC_REQ_SET_AUX_LINE_STATE = 0x10, /**< This request is used to connect or disconnect a secondary jack to POTS circuit or CODEC, depending on hook state. */ + APP_USBD_CDC_REQ_SET_HOOK_STATE = 0x11, /**< This request is used to set the necessary PSTN line relay code for on-hook, off-hook, and caller ID states. */ + APP_USBD_CDC_REQ_PULSE_SETUP = 0x12, /**< This request is used to prepare for a pulse-dialing cycle. */ + APP_USBD_CDC_REQ_SEND_PULSE = 0x13, /**< This request is used to generate a specified number of make/break pulse cycles. */ + APP_USBD_CDC_REQ_SET_PULSE_TIME = 0x14, /**< This request sets the timing of the make and break periods for pulse dialing. */ + APP_USBD_CDC_REQ_RING_AUX_JACK = 0x15, /**< This request is used to generate a ring signal on a secondary phone jack. */ + APP_USBD_CDC_REQ_SET_LINE_CODING = 0x20, /**< This request allows the host to specify typical asynchronous line-character formatting properties. */ + APP_USBD_CDC_REQ_GET_LINE_CODING = 0x21, /**< This request allows the host to find out the currently configured line coding. */ + APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE = 0x22, /**< This request generates RS-232/V.24 style control signals. */ + APP_USBD_CDC_REQ_SEND_BREAK = 0x23, /**< This request sends special carrier modulation that generates an RS-232 style break. */ + APP_USBD_CDC_REQ_SET_RINGER_PARMS = 0x30, /**< This request configures the ringer for the communications device. */ + APP_USBD_CDC_REQ_GET_RINGER_PARMS = 0x31, /**< This request returns the ringer capabilities of the device and the current status of the device’s ringer. */ + APP_USBD_CDC_REQ_SET_OPERATION_PARMS = 0x32, /**< Sets the operational mode for the device, between a simple mode, standalone mode and a host centric mode. */ + APP_USBD_CDC_REQ_GET_OPERATION_PARMS = 0x33, /**< This request gets the current operational mode for the device. */ + APP_USBD_CDC_REQ_SET_LINE_PARMS = 0x34, /**< This request is used to change the state of the line, corresponding to the interface or master interface of a union to which the command was sent. */ + APP_USBD_CDC_REQ_GET_LINE_PARMS = 0x35, /**< This request is used to report the state of the line that corresponds to the interface or master interface of a union to which the command was sent. */ + APP_USBD_CDC_REQ_DIAL_DIGITS = 0x36, /**< This request dials the DTMF digits over the specified line. */ +} app_usbd_cdc_req_id_t; + +/** + * @brief CDC Notifications + */ +typedef enum { + /* CDC General */ + APP_USBD_CDC_NOTIF_NETWORK_CONNECTION = 0x00, /**< This notification allows the device to notify the host about network connection status. */ + APP_USBD_CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, /**< This notification allows the device to notify the host that a response is available. + * This response can be retrieved with a subsequent GetEncapsulatedResponse request + _ */ + APP_USBD_CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, /**< This notification allows the device to inform the host-networking driver + * that a change in either the up-link or the down-link bit rate of the connection has occurred. + */ + /* CDC PSTN */ + APP_USBD_CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, /**< (DLM) This notification indicates the loop has changed on the auxiliary phone interface of the USB device. */ + APP_USBD_CDC_NOTIF_RING_DETECT = 0x09, /**< (DLM) This notification indicates ring voltage on the POTS line interface of the USB device. */ + APP_USBD_CDC_NOTIF_SERIAL_STATE = 0x20, /**< (ACM) This notification sends asynchronous notification of UART status. */ + APP_USBD_CDC_NOTIF_CALL_STATE_CHANGE = 0x28, /**< (TCM) This notification identifies that a change has occurred to the state of a call on the line corresponding to the interface or union for the line. */ + APP_USBD_CDC_NOTIF_LINE_STATE_CHANGE = 0x29 /**< (TCM) This notification identifies that a change has occurred to the state of the line corresponding to the interface or master interface of a union sending the notification message. */ +} app_usbd_cdc_notify_id_t; + +/** + * @brief Notification sent via CDC COMM endpoint + * */ +typedef struct { + uint8_t bmRequestType; //!< Request type + uint8_t bmRequest; //!< Request ID @ref app_usbd_cdc_req_id_t + uint16_t wValue; //!< Value field + uint16_t wIndex; //!< Index field + uint16_t wLength; //!< Length of payload following +} app_usbd_cdc_notify_t; + +/** + * @brief CDC line coding structure + */ +typedef struct { + uint8_t dwDTERate[4]; //!< Line baudrate + uint8_t bCharFormat; //!< Character format @ref app_usbd_cdc_line_stopbit_t + uint8_t bParityType; //!< Parity bits @ref app_usbd_cdc_line_parity_t + uint8_t bDataBits; //!< Number of data bits +} app_usbd_cdc_line_coding_t; + +/** + * @brief Possible values of @ref app_usbd_cdc_line_coding_t::bCharFormat + */ +typedef enum { + APP_USBD_CDC_LINE_STOPBIT_1 = 0, /**< 1 stop bit */ + APP_USBD_CDC_LINE_STOPBIT_1_5 = 1, /**< 1.5 stop bits */ + APP_USBD_CDC_LINE_STOPBIT_2 = 2, /**< 2 stop bits */ +} app_usbd_cdc_line_stopbit_t; + +/** + * @brief Possible values of @ref app_usbd_cdc_line_coding_t::bParityType + */ +typedef enum { + APP_USBD_CDC_LINE_PARITY_NONE = 0, /**< No parity */ + APP_USBD_CDC_LINE_PARITY_ODD = 1, /**< Odd parity */ + APP_USBD_CDC_LINE_PARITY_EVEN = 2, /**< Even parity */ + APP_USBD_CDC_LINE_PARITY_MARK = 3, /**< Parity forced to 0 (space) */ + APP_USBD_CDC_LINE_PARITY_SPACE = 4, /**< Parity forced to 1 (mark) */ +} app_usbd_cdc_line_parity_t; + + +#pragma pack(pop) + +/** @} */ +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_TYPES_H__ */ diff --git a/components/libraries/usbd/class/hid/app_usbd_hid.c b/components/libraries/usbd/class/hid/app_usbd_hid.c new file mode 100644 index 0000000..be342ba --- /dev/null +++ b/components/libraries/usbd/class/hid/app_usbd_hid.c @@ -0,0 +1,509 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_CLASS_HID_ENABLED +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_hid.h" + +/** + * @ingroup app_usbd_hid_internals USBD HID internals + * @{ + * @ingroup app_usbd_hid + * @internal + */ + +/** + * @brief Test whether SOF HID transfer is required + * + * This function handles idle period IN transfer + * + * @param[in/out] p_hid_ctx Internal HID context + * @param framecnt SOF event frame counter + * @retval true if Idle transfer is required, false otherwise + * */ +static bool hid_sof_required(app_usbd_hid_ctx_t * p_hid_ctx, uint16_t framecnt) +{ + if (p_hid_ctx->idle_rate == 0) + { + /* Infinite idle rate */ + return false; + } + + /*Idle rate has 4ms units. Every SOF event is generated with 1ms period.*/ + uint16_t rate_ms = p_hid_ctx->idle_rate * 4; + if ((framecnt % rate_ms) != 0) + { + /* Idle transfer not required yet*/ + return false; + } + + if (p_hid_ctx->access_lock) + { + /* Access to internal data locked. Buffer is BUSY. + * Don't send anything. Clear transfer flag. Next transfer will be triggered + * from API context.*/ + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + return false; + } + + if (app_usbd_hid_trans_required(p_hid_ctx)) + { + /*New transfer need to be triggered*/ + return true; + } + + return false; +} + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] p_hinst HID class instance + * @param[in] event user Event type @ref app_usbd_hid_user_event_t + * */ +static inline void user_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_user_event_t event) +{ + ASSERT(p_hinst->user_event_handler != NULL); + if (p_hinst->user_event_handler != NULL) + { + p_hinst->user_event_handler(p_inst, event); + } +} + +/** + * @brief Internal SETUP standard IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_hinst HID class instance + * @param[in/out] p_hid_ctx HID context + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_setup_evt_t const * p_setup_ev) +{ + /*Only Get Descriptor standard IN request is supported by HID class*/ + if (p_setup_ev->setup.bmRequest != APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + + size_t dsc_len = 0; + + /* Try to find descriptor in class internals*/ + void const * p_dsc = app_usbd_class_descriptor_find(p_inst, + p_setup_ev->setup.wValue.hb, + p_setup_ev->setup.wValue.lb, + &dsc_len); + if (p_dsc != NULL) + { + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_dsc, dsc_len); + } + + + /* HID specific descriptors*/ + switch (p_setup_ev->setup.wValue.hb) + { + case APP_USBD_HID_DESCRIPTOR_REPORT: + { + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + p_hinst->p_report_dsc, + p_hinst->report_dsc_size); + } + case APP_USBD_HID_DESCRIPTOR_PHYSICAL: + /*Not supported*/ + break; + default: + /*Not supported*/ + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP standard OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_hinst HID class instance + * @param[in/out] p_hid_ctx HID context + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_setup_evt_t const * p_setup_ev) +{ + /*Only Set Descriptor standard OUT request is supported by HID class. However, it is optional + * and useless in HID cases.*/ + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_hinst HID class instance + * @param[in/out] p_hid_ctx HID context + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_HID_REQ_GET_REPORT: + { + /*Only input report is supported. Same format as over IN pipe.*/ + if (p_setup_ev->setup.wValue.hb != APP_USBD_HID_REPORT_TYPE_INPUT) + { + break; + } + + return p_hinst->p_hid_methods->on_get_report(p_inst, p_setup_ev); + } + case APP_USBD_HID_REQ_GET_IDLE: + { + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + &p_hid_ctx->idle_rate, + sizeof(p_hid_ctx->idle_rate)); + } + case APP_USBD_HID_REQ_GET_PROTOCOL: + { + return app_usbd_core_setup_rsp(&p_setup_ev->setup, + &p_hid_ctx->protocol, + sizeof(p_hid_ctx->protocol)); + } + default: + break; + + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_hinst HID class instance + * @param[in/out] p_hid_ctx HID context + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_setup_evt_t const * p_setup_ev) +{ + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_HID_REQ_SET_REPORT: + if (p_setup_ev->setup.wValue.hb != APP_USBD_HID_REPORT_TYPE_OUTPUT) + { + break; + } + + if (p_hinst->p_hid_methods->on_get_report == NULL) + { + break; + } + + return p_hinst->p_hid_methods->on_set_report(p_inst, p_setup_ev); + case APP_USBD_HID_REQ_SET_IDLE: + p_hid_ctx->idle_rate = p_setup_ev->setup.wValue.hb; + return NRF_SUCCESS; + case APP_USBD_HID_REQ_SET_PROTOCOL: + p_hid_ctx->protocol = p_setup_ev->setup.wValue.w; + return NRF_SUCCESS; + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP event handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_hinst HID class instance + * @param[in/out] p_hid_ctx HID context + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_setup_evt_t const * p_setup_ev) +{ + ASSERT(p_hinst != NULL); + ASSERT(p_hid_ctx != NULL); + ASSERT(p_setup_ev != NULL); + + if (app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_ENDPOINT) + { + return app_usbd_endpoint_std_req_handle(p_inst, p_setup_ev); + } + + ret_code_t ret = app_usbd_interface_std_req_handle(p_inst, p_setup_ev); + if (ret == NRF_SUCCESS || ret != NRF_ERROR_NOT_SUPPORTED) + { + return ret; + } + + if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN) + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_in(p_inst, p_hinst, p_hid_ctx, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_in(p_inst, p_hinst, p_hid_ctx, p_setup_ev); + default: + break; + } + } + else /*APP_USBD_SETUP_REQDIR_OUT*/ + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_out(p_inst, p_hinst, p_hid_ctx, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_out(p_inst, p_hinst, p_hid_ctx, p_setup_ev); + default: + break; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Endpoint IN event handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_hinst HID class instance + * @param[in/out] p_hid_ctx HID context + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_complex_evt_t const * p_event) +{ + + if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OK) + { + /* Notify user about last successful transfer. */ + user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_IN_REPORT_DONE); + } + + if (app_usbd_hid_access_lock_test(p_hid_ctx)) + { + /* Access to internal data locked. Buffer is BUSY. + * Don't send anything. Clear transfer flag. Next transfer will be triggered + * from main loop context.*/ + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + return NRF_SUCCESS; + } + + return p_hinst->p_hid_methods->ep_transfer_in(p_inst); +} + +/** + * @brief Endpoint OUT event handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_hinst HID class instance + * @param[in/out] p_hid_ctx HID context + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_complex_evt_t const * p_event) +{ + if (p_hinst->p_hid_methods->ep_transfer_out == NULL) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OK) + { + /* Notify user about last successful transfer. */ + user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_OUT_REPORT_READY); + } + + return p_hinst->p_hid_methods->ep_transfer_out(p_inst); +} + +/** @} */ + + +ret_code_t app_usbd_hid_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_complex_evt_t const * p_event) +{ + ret_code_t ret = NRF_SUCCESS; + switch (p_event->app_evt.type) + { + case APP_USBD_EVT_DRV_SOF: + if (!hid_sof_required(p_hid_ctx, p_event->drv_evt.data.sof.framecnt)) + { + break; + } + ret = p_hinst->p_hid_methods->ep_transfer_in(p_inst); + break; + case APP_USBD_EVT_DRV_RESET: + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + break; + case APP_USBD_EVT_DRV_SETUP: + ret = setup_event_handler(p_inst, p_hinst, p_hid_ctx, &p_event->setup_evt); + break; + case APP_USBD_EVT_DRV_EPTRANSFER: + if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep)) + { + ret = endpoint_in_event_handler(p_inst, p_hinst, p_hid_ctx, p_event); + } + else + { + ret = endpoint_out_event_handler(p_inst, p_hinst, p_hid_ctx, p_event); + } + break; + case APP_USBD_EVT_DRV_SUSPEND: + app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED); + user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_SUSPEND); + break; + case APP_USBD_EVT_DRV_RESUME: + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED); + user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_RESUME); + + /* Always try to trigger transfer on resume event*/ + ret = p_hinst->p_hid_methods->ep_transfer_in(p_inst); + break; + case APP_USBD_EVT_INST_APPEND: + /*SOF register: GetIdle/SetIdle support*/ + ret = app_usbd_class_sof_register(p_inst); + if (ret != NRF_SUCCESS) + { + break; + } + app_usbd_core_class_rwu_register(p_inst); + app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED); + break; + case APP_USBD_EVT_INST_REMOVE: + /*SOF unregister: GetIdle/SetIdle support*/ + ret = app_usbd_class_sof_unregister(p_inst); + if (ret != NRF_SUCCESS) + { + break; + } + + app_usbd_core_class_rwu_unregister(p_inst); + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED); + break; + case APP_USBD_EVT_START: + app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED); + user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_START); + break; + case APP_USBD_EVT_STOP: + app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED); + user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_STOP); + break; + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + return ret; +} + +app_usbd_hid_report_buffer_t * app_usbd_hid_rep_buff_in_get(app_usbd_hid_inst_t const * p_hinst, + size_t report_id) +{ + ASSERT(p_hinst); + + if (report_id >= p_hinst->rep_buffers_count_in) + { + return NULL; + } + + return &p_hinst->p_rep_buffers_in[report_id]; +} + + +#endif // APP_USBD_CLASS_HID_ENABLED diff --git a/components/libraries/usbd/class/hid/app_usbd_hid.h b/components/libraries/usbd/class/hid/app_usbd_hid.h new file mode 100644 index 0000000..951c1ed --- /dev/null +++ b/components/libraries/usbd/class/hid/app_usbd_hid.h @@ -0,0 +1,446 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_H__ +#define APP_USBD_HID_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "sdk_common.h" +#include "nrf_atomic.h" +#include "app_usbd_hid_types.h" +#include "app_usbd_core.h" + +/** + * @defgroup app_usbd_hid USB HID class + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with generic HID event data processing. + * @{ + */ + +#define APP_USBD_HID_IFACE_IDX 0 /**< HID instance interface index */ +#define APP_USBD_HID_EPIN_IDX 0 /**< HID instance endpoint IN index */ +#define APP_USBD_HID_EPOUT_IDX 1 /**< HID instance endpoint OUT index */ + +/** + * @brief HID context state flags + */ +typedef enum { + APP_USBD_HID_STATE_FLAG_APPENDED = 0, /**< State flag APPENDED */ + APP_USBD_HID_STATE_FLAG_STARTED = 1, /**< State flag STARTED */ + APP_USBD_HID_STATE_FLAG_SUSPENDED = 2, /**< State flag SUSPENDED */ + APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS = 3, /**< State flag TRANS_IN_PROGRESS */ +} app_usbd_hid_state_flag_t; + + +/** + * @brief Events passed to user event handler + * + * @note Example prototype of user event handler: + @code + void hid_user_ev_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_mouse_user_event_t event); + @endcode + */ +typedef enum { + APP_USBD_HID_USER_EVT_SUSPEND = 0, /**< Event SUSPEND */ + APP_USBD_HID_USER_EVT_RESUME, /**< Event RESUME */ + APP_USBD_HID_USER_EVT_START, /**< Event START */ + APP_USBD_HID_USER_EVT_STOP, /**< Event STOP */ + + APP_USBD_HID_USER_EVT_OUT_REPORT_READY, /**< Event OUT_REPORT_READY */ + APP_USBD_HID_USER_EVT_IN_REPORT_DONE, /**< Event IN_REPORT_DONE */ +} app_usbd_hid_user_event_t; + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] event User event + * + * */ +typedef void (*app_usbd_hid_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_user_event_t event); + +/**@brief HID unified interface*/ +typedef struct { + + /** + * @brief Function called on HID specific, GetReport request + * + * This function should trigger data write to control pipe + * + * @param[in] p_inst Class instance + * @param[in] p_setup_ev Setup event + * @return Standard error code + * */ + ret_code_t (*on_get_report)(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev); + + /** + * @brief Function called on HID specific, SetReport request + * + * This function should trigger data read from control pipe. This function is not required and + * NULL could be pinned to this handler when output report is not defined in report descriptor. + * + * @param[in] p_inst Class instance + * @param[in] p_setup_ev Setup event + * @return Standard error code + * */ + ret_code_t (*on_set_report)(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev); + + /** + * @brief Function called on IN endpoint transfer + * + * This function should trigger next endpoint IN transfer if required. + * + * @param[in] p_inst Class instance + * @return Standard error code + * */ + ret_code_t (*ep_transfer_in)(app_usbd_class_inst_t const * p_inst); + + /** + * @brief Function called on OUT endpoint transfer + * + * This function should should read data from OUT endpoint. This function is not required and + * NULL could be pinned to this handler when class doesn't have OUT endpoint. + * + * @param[in] p_inst Class instance + * @return Standard error code + * */ + ret_code_t (*ep_transfer_out)(app_usbd_class_inst_t const * p_inst); +} app_usbd_hid_methods_t; + +/** + * @brief HID report buffers + */ +typedef struct { + uint8_t * p_buff; + size_t size; +} app_usbd_hid_report_buffer_t; + + + +/**@brief Define OUT report buffer structure @ref app_usbd_hid_report_buffer_t + * + * @param name Instance name + * @param rep_size Output report size + */ +#define APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(name, rep_size) \ + static uint8_t CONCAT_2(name, _buf)[(rep_size)]; \ + const app_usbd_hid_report_buffer_t name = { \ + .p_buff = CONCAT_2(name, _buf), \ + .size = sizeof(CONCAT_2(name, _buf)), \ + } + + +/** + * @brief USB HID instance + * */ +typedef struct { + uint8_t const * p_raw_desc; //!< HID class descriptors, raw array + size_t raw_desc_size; //!< HID class descriptors size, raw array size + uint8_t const * p_report_dsc; //!< Report descriptor, raw array + size_t report_dsc_size; //!< Report descriptor, raw array size + + app_usbd_hid_report_buffer_t * p_rep_buffers_in; //!< Report buffers IN + size_t rep_buffers_count_in; //!< Report count IN + app_usbd_hid_report_buffer_t const * p_rep_buffer_out; //!< Report buffer OUT (only one instance) + app_usbd_hid_methods_t const * p_hid_methods; //!< Hid interface methods + app_usbd_hid_user_ev_handler_t user_event_handler; //!< User event handler +} app_usbd_hid_inst_t; + + +/** + * @brief USB HID instance initializer @ref app_usbd_hid_inst_t + * + * @param descriptors Interface, hid, endpoint packed descriptor structure + * @param report_dsc Report descriptor (raw uint8_t array) + * @param report_buff_in Input report buffer list + * @param report_buff_out Output report buffer + * @param user_ev_handler @ref app_usbd_hid_user_ev_handler_t + @param hid_methods @ref app_usbd_hid_methods_t + * */ +#define APP_USBD_HID_INST_CONFIG(descriptors, \ + report_dsc, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + hid_methods) \ + { \ + .p_raw_desc = descriptors, \ + .raw_desc_size = ARRAY_SIZE(descriptors), \ + .p_report_dsc = report_dsc, \ + .report_dsc_size = ARRAY_SIZE(report_dsc), \ + .p_rep_buffers_in = report_buff_in, \ + .rep_buffers_count_in = ARRAY_SIZE(report_buff_in), \ + .p_rep_buffer_out = report_buff_out, \ + .user_event_handler = user_ev_handler, \ + .p_hid_methods = hid_methods, \ + } + +/** + * @brief HID internal context + * */ +typedef struct { + nrf_atomic_u32_t state_flags; //!< HID state flags @ref app_usbd_hid_state_flag_t + nrf_atomic_flag_t access_lock; //!< Lock flag to internal data + uint8_t idle_rate; //!< HID idle rate (4ms units) + uint8_t protocol; //!< HID protocol type +} app_usbd_hid_ctx_t; + + +/** + * @brief Locks internal hid context + * + * Simple semaphore functionality to prevent concurrent access from application and + * interrupt to internal mouse data. + * + * @param[in] p_hid_ctx internal hid context + */ +static inline void app_usbd_hid_access_lock(app_usbd_hid_ctx_t * p_hid_ctx) +{ + UNUSED_RETURN_VALUE(nrf_atomic_flag_set(&p_hid_ctx->access_lock)); + __DSB(); +} + + +/** + * @brief Unlocks internal hid context + * + * Simple semaphore functionality to prevent concurrent access from application and + * interrupt to internal mouse data. + * + * @param[in] p_hid_ctx internal hid context + */ +static inline void app_usbd_hid_access_unlock(app_usbd_hid_ctx_t * p_hid_ctx) +{ + UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_hid_ctx->access_lock)); + __DSB(); +} + +/** + * @brief Tests whether internal lock is acquired + * + * @param[in] p_hid_ctx Internal HID context + * + * @retval true Locked + * @retval false Unlocked + */ +static inline bool app_usbd_hid_access_lock_test(app_usbd_hid_ctx_t * p_hid_ctx) +{ + return p_hid_ctx->access_lock != 0; +} + +/** + * @brief Set one of the HID internal state flags + * + * @param[in] p_hid_ctx Internal HID context + * @param[in] flag Flag to set + */ +static inline void app_usbd_hid_state_flag_set(app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_hid_state_flag_t flag) +{ + UNUSED_RETURN_VALUE(nrf_atomic_u32_or(&p_hid_ctx->state_flags, 1u << flag)); +} + +/** + * @brief Clear one of the HID internal state flags + * + * @param[in] p_hid_ctx Internal HID context + * @param[in] flag Flag to clear + */ +static inline void app_usbd_hid_state_flag_clr(app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_hid_state_flag_t flag) +{ + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&p_hid_ctx->state_flags, ~(1u << flag))); +} + + +/** + * @brief Test one of the HID internal state flags + * + * @param[in] p_hid_ctx Internal HID context + * @param[in] flag Flag to test + */ +static inline bool app_usbd_hid_state_flag_test(app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_hid_state_flag_t flag) +{ + return ((p_hid_ctx->state_flags >> flag) & 1) == 1; +} + +/** + * @brief Checks whether HID endpoint transfer required + * + * @param[in] p_hid_ctx Internal HID context + * + * @retval true Input endpoint transfer required + * @retval false Transfer in progress or not allowed + */ +static inline bool app_usbd_hid_trans_required(app_usbd_hid_ctx_t * p_hid_ctx) +{ + if (app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED) != 0) + { + app_usbd_core_class_rwu_pend(); + return false; + } + + return app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS) == 0; +} + +/** + * @brief Validates internal hid state + * + * HID Mouse has to receive some USBD events before functions from this module could be used. + * + * @param[in] p_hid_ctx Internal hid context + * @retval true State is valid + * @retval false State is invalid + */ +static inline bool app_usbd_hid_state_valid(app_usbd_hid_ctx_t * p_hid_ctx) +{ + /*Check whether internal flags allow to enable mouse*/ + if ((app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED) == 0) || + (app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED) == 0)) + { + return false; + } + + return true; +} + +/** + * @brief HID generic event handler + * + * This handler should process every class event after specific class handler. + * This approach allow to handle some events in the same way in all HID sub-classes. + * + * @param[in] p_inst Generic class instance + * @param[in] p_hinst HID class instance + * @param[in] p_hid_ctx HID context + * @param[in] p_event Complex event structure + * + * @retval NRF_SUCCESS If operation was successful. + * */ +ret_code_t app_usbd_hid_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_hid_inst_t const * p_hinst, + app_usbd_hid_ctx_t * p_hid_ctx, + app_usbd_complex_evt_t const * p_event); + + +/** + * @brief Returns IN report buffer + * + * @param[in] p_hinst HID class instance + * @param[in] report_id Report ID + * + * @return Report buffer or NULL if report doesn't exist + * */ +app_usbd_hid_report_buffer_t * app_usbd_hid_rep_buff_in_get(app_usbd_hid_inst_t const * p_hinst, + size_t report_id); + +/** + * @brief Returns OUT report buffer + * + * Output reports are handled in interrupt handler so only one buffer is required. Buffer returned by + * this function has predefined size, which should be equal (maximum OUTPUT report size + 1). To receive + * OUT report this function should be called on @ref APP_USBD_HID_USER_EVT_OUT_REPORT_READY event. + * + * @param[in] p_hinst HID class instance + * + * @return Report buffer or NULL if report doesn't exist + * */ +static inline app_usbd_hid_report_buffer_t const * +app_usbd_hid_rep_buff_out_get(app_usbd_hid_inst_t const * p_hinst) +{ + ASSERT(p_hinst); + return p_hinst->p_rep_buffer_out; +} + +/** + * @brief Auxiliary function to access to HID IN endpoint address + * + * @param[in] p_inst Class instance data + * + * @return IN endpoint address + */ +static inline nrf_drv_usbd_ep_t app_usbd_hid_epin_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_HID_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_HID_EPIN_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Auxiliary function to access to HID generic OUT endpoint address + * + * @param[in] p_inst Class instance data + * + * @return OUT endpoint address + */ +static inline nrf_drv_usbd_ep_t app_usbd_hid_epout_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_HID_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_HID_EPOUT_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_H__ */ diff --git a/components/libraries/usbd/class/hid/app_usbd_hid_types.h b/components/libraries/usbd/class/hid/app_usbd_hid_types.h new file mode 100644 index 0000000..0d965ed --- /dev/null +++ b/components/libraries/usbd/class/hid/app_usbd_hid_types.h @@ -0,0 +1,273 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_TYPES_H__ +#define APP_USBD_HID_TYPES_H__ + +#include + +#include "sdk_common.h" + +/** + * @defgroup app_usbd_hid_types USB HID class types + * @ingroup app_usbd_hid + * + * @brief @tagAPI52840 Module with types and definitions used by HID modules. + * @{ + */ + +/** @brief HID class definition in interface descriptor + * + * @ref app_usbd_descriptor_iface_t::bInterfaceClass + * */ +#define APP_USBD_HID_CLASS 0x03 + +/** @brief HID subclass definition + * + * @see HID 1.11 specification: Chapter 4.2 Subclass + * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass + * */ +typedef enum { + APP_USBD_HID_SUBCLASS_NONE = 0x00, /**< Undefined subclass*/ + APP_USBD_HID_SUBCLASS_BOOT = 0x01, /**< Boot subclass */ +} app_usbd_hid_subclass_t; + +/** @brief HID descriptor types + * + * Value need to be filled in interface descriptor. + * @ref app_usbd_descriptor_iface_t::bInterfaceProtocol + */ +typedef enum { + APP_USBD_HID_PROTO_GENERIC = 0x00, /**< GENERIC protocol */ + APP_USBD_HID_PROTO_KEYBOARD = 0x01, /**< KEYBOARD protocol */ + APP_USBD_HID_PROTO_MOUSE = 0x02, /**< MOUSE protocol */ + APP_USBD_HID_PROTO_MULTITOUCH = 0x03, /**< MULTITOUCH protocol */ +} app_usbd_hid_protocol_t; + +/** @brief HID protocol types defined by specification + * + */ + +/** @brief HID country code ID + * + * Look into @ref app_usbd_hid_descriptor_t::bCountryCode + */ +typedef enum { + APP_USBD_HID_COUNTRY_NOT_SUPPORTED = 0 , /**< NOT_SUPPORTED */ + APP_USBD_HID_COUNTRY_ARABIC = 1 , /**< ARABIC */ + APP_USBD_HID_COUNTRY_BELGIAN = 2 , /**< BELGIAN */ + APP_USBD_HID_COUNTRY_CANADIAN_BILINGUAL= 3 , /**< CANADIAN_BILINGUAL */ + APP_USBD_HID_COUNTRY_CANADIAN_FRENCH = 4 , /**< CANADIAN_FRENCH */ + APP_USBD_HID_COUNTRY_CZECH_REPUBLIC = 5 , /**< CZECH_REPUBLIC */ + APP_USBD_HID_COUNTRY_DANISH = 6 , /**< DANISH */ + APP_USBD_HID_COUNTRY_FINNISH = 7 , /**< FINNISH */ + APP_USBD_HID_COUNTRY_FRENCH = 8 , /**< FRENCH */ + APP_USBD_HID_COUNTRY_GERMAN = 9 , /**< GERMAN */ + APP_USBD_HID_COUNTRY_GREEK = 10, /**< GREEK */ + APP_USBD_HID_COUNTRY_HEBREW = 11, /**< HEBREW */ + APP_USBD_HID_COUNTRY_HUNGARY = 12, /**< HUNGARY */ + APP_USBD_HID_COUNTRY_INTERNATIONAL_ISO = 13, /**< INTERNATIONAL_ISO */ + APP_USBD_HID_COUNTRY_ITALIAN = 14, /**< ITALIAN */ + APP_USBD_HID_COUNTRY_JAPAN_KATAKANA = 15, /**< JAPAN_KATAKANA */ + APP_USBD_HID_COUNTRY_KOREAN = 16, /**< KOREAN */ + APP_USBD_HID_COUNTRY_LATIN_AMERICAN = 17, /**< LATIN_AMERICAN */ + APP_USBD_HID_COUNTRY_NETHERLANDS_DUTCH = 18, /**< NETHERLANDS_DUTCH */ + APP_USBD_HID_COUNTRY_NORWEGIAN = 19, /**< NORWEGIAN */ + APP_USBD_HID_COUNTRY_PERSIAN_FARSI = 20, /**< PERSIAN_FARSI */ + APP_USBD_HID_COUNTRY_POLAND = 21, /**< POLAND */ + APP_USBD_HID_COUNTRY_PORTUGUESE = 22, /**< PORTUGUESE */ + APP_USBD_HID_COUNTRY_RUSSIA = 23, /**< RUSSIA */ + APP_USBD_HID_COUNTRY_SLOVAKIA = 24, /**< SLOVAKIA */ + APP_USBD_HID_COUNTRY_SPANISH = 25, /**< SPANISH */ + APP_USBD_HID_COUNTRY_SWEDISH = 26, /**< SWEDISH */ + APP_USBD_HID_COUNTRY_SWISS_FRENCH = 27, /**< SWISS_FRENCH */ + APP_USBD_HID_COUNTRY_SWISS_GERMAN = 28, /**< SWISS_GERMAN */ + APP_USBD_HID_COUNTRY_SWITZERLAND = 29, /**< SWITZERLAND */ + APP_USBD_HID_COUNTRY_TAIWAN = 30, /**< TAIWAN */ + APP_USBD_HID_COUNTRY_TURKISH_Q = 31, /**< TURKISH_Q */ + APP_USBD_HID_COUNTRY_UK = 32, /**< UK */ + APP_USBD_HID_COUNTRY_US = 33, /**< US */ + APP_USBD_HID_COUNTRY_YUGOSLAVIA = 34, /**< YUGOSLAVIA */ + APP_USBD_HID_COUNTRY_TURKISH_F = 35, /**< TURKISH_F */ +} app_usbd_hid_country_code_t; + +/** @brief HID descriptor types + * + * @ref app_usbd_hid_descriptor_t::bRDescriptorType + */ +typedef enum { + APP_USBD_HID_DESCRIPTOR_HID = 0x21, /**< HID descriptor */ + APP_USBD_HID_DESCRIPTOR_REPORT = 0x22, /**< REPORT descriptor */ + APP_USBD_HID_DESCRIPTOR_PHYSICAL = 0x23, /**< PHYSICAL descriptor */ +} app_usbd_hid_descriptor_type_t; + +#pragma pack(push, 1) + +/** + * @brief HID report descriptor entry at the end of HID descriptor + * + * @param size Report descriptor size + */ +#define APP_USBD_HID_REPORT_ITEM(size) \ + APP_USBD_HID_DESCRIPTOR_REPORT, ((size) & 0xFF), ((size) / 256) + + +/** + * @brief HID physical descriptor entry at the end of HID descriptor + * + * @param size Physical descriptor size + */ +#define APP_USBD_HID_PHYSICAL_ITEM(size) \ + APP_USBD_HID_DESCRIPTOR_PHYSICAL, ((size) & 0xFF), ((size) / 256) + + +/** + * @brief HID descriptor, binary layout + */ +typedef union { + struct { + uint8_t bLength; //!< Length of descriptor + uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_HID_DESCRIPTOR_HID + uint16_t bcdHID; //!< HID release number (BCD format, little endian) + uint8_t bCountryCode; //!< Country code + uint8_t bNumDescriptors; //!< Number of class descriptors + struct { + uint8_t bRDescriptorType; //!< Class descriptor type + uint16_t wDescriptorLength; //!< Class descriptor length (little endian) + } reports[]; + } raw; +} app_usbd_hid_descriptor_t; + +#pragma pack(pop) + + +/** @brief HID requests defined by specification + * + */ +typedef enum { + APP_USBD_HID_REQ_GET_REPORT = 0x01, /**< REPORT: device -> host (required) */ + APP_USBD_HID_REQ_GET_IDLE = 0x02, /**< IDLE: device -> host (not required) */ + APP_USBD_HID_REQ_GET_PROTOCOL = 0x03, /**< PROTOCOL: device -> host (required for boot protocol) */ + APP_USBD_HID_REQ_SET_REPORT = 0x09, /**< REPORT: host -> device (not required) */ + APP_USBD_HID_REQ_SET_IDLE = 0x0A, /**< IDLE: no data stage (required for boot protocol) */ + APP_USBD_HID_REQ_SET_PROTOCOL = 0x0B, /**< PROTOCOL: no data stage(required for boot protocol) */ +} app_usbd_hid_req_t; + +/** @brief HID report type + * + */ +typedef enum { + APP_USBD_HID_REPORT_TYPE_INPUT = 0x01,/**< INPUT report type */ + APP_USBD_HID_REPORT_TYPE_OUTPUT = 0x02,/**< OUTPUT report type */ + APP_USBD_HID_REPORT_TYPE_FEATURE = 0x03,/**< FEATURE report type */ +} app_usbd_hid_report_type_t; + + + +/** @brief Helper macro for HID BCD release + * + * @param major Hid release number major + * @param minor Hid release number minor + * + * @ref app_usbd_hid_descriptor_t::bcdHID + * @ref APP_USBD_HID_BCD_V1_11 + */ +#define APP_USBD_HID_BCD_MAKE(major, minor) 0x##minor, 0x##major + +/** @brief HID 1.11 BCD value definition + * + * @ref app_usbd_hid_descriptor_t::bcdHID + */ +#define APP_USBD_HID_BCD_V1_11 APP_USBD_HID_BCD_MAKE(1, 11) + +/** + * @brief Initializer of interface descriptor for HID classes + * + * @param interface_number Interface number + * @param endpoints_num Number of endpoints + * @param subclass Subclass type @ref app_usbd_hid_subclass_t + * @param protocol Protocol type @ref app_usbd_hid_protocol_t + * */ +#define APP_USBD_HID_INTERFACE_DSC(interface_number, endpoints_num, subclass, protocol) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \ + /*.bInterfaceNumber = */ interface_number, \ + /*.bAlternateSetting = */ 0x00, \ + /*.bNumEndpoints = */ endpoints_num, \ + /*.bInterfaceClass = */ APP_USBD_HID_CLASS, \ + /*.bInterfaceSubClass = */ subclass, \ + /*.bInterfaceProtocol = */ protocol, \ + /*.iInterface = 0, */ 0x00, \ + + +/** + * @brief Initializer of HID descriptor for HID classes + * + * @param ... Report/physical item list + * */ +#define APP_USBD_HID_HID_DSC(...) \ + /*.bLength = */ sizeof(app_usbd_hid_descriptor_t) + 3 * (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bDescriptorType = */ APP_USBD_HID_DESCRIPTOR_HID, \ + /*.bcdHID = */ APP_USBD_HID_BCD_V1_11, \ + /*.bCountryCode = */ APP_USBD_HID_COUNTRY_NOT_SUPPORTED, \ + /*.bNumDescriptors = */ (NUM_VA_ARGS(__VA_ARGS__)), \ + /*.bRDescriptorType = */ APP_USBD_HID_REPORT_ITEM(sizeof(GET_VA_ARG_1_(__VA_ARGS__))), \ + /*.wDescriptorLength = */ + +/** + * @brief Initializer of endpoint descriptor for HID classes + * + * @param endpoint Endpoint number + * @param ep_size Endpoint size + * @param ep_interval Endpoint interval (milliseconds) + * */ +#define APP_USBD_HID_EP_DSC(endpoint, ep_size, ep_interval) \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ ep_interval, \ + + + +/** @} */ + +#endif /* APP_USBD_HID_TYPES_H__ */ diff --git a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c b/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c new file mode 100644 index 0000000..0db2243 --- /dev/null +++ b/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c @@ -0,0 +1,380 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_HID_GENERIC_ENABLED +#include + +#include "sdk_common.h" +#include "app_usbd_hid_generic.h" +#include "app_util_platform.h" + + + +/** + * @ingroup app_usbd_hid_generic + * + * Module with types, definitions and API used by HID generic + * @{ + */ + + +/** + * @brief Auxiliary function to access HID generic context data + * + * @param[in] p_inst Class instance data + * @return HID generic instance data @ref app_usbd_hid_generic_ctx_t + */ +static inline app_usbd_hid_generic_ctx_t * +hid_generic_ctx_get(app_usbd_hid_generic_t const * p_generic) +{ + ASSERT(p_generic != NULL); + ASSERT(p_generic->specific.p_data != NULL); + return &p_generic->specific.p_data->ctx; +} + +/** + * @brief Auxiliary function to access HID generic instance data + * + * @param[in] p_inst Class instance data + * @return HID generic instance data @ref app_usbd_hid_generic_t + */ +static inline app_usbd_hid_generic_t const * +hid_generic_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_hid_generic_t const *)p_inst; +} + + +/** + * @brief Returns report ID buffer descriptor + * + * @*/ +static inline app_usbd_hid_report_buffer_t const * +hid_generic_rep_buffer_get(app_usbd_hid_generic_t const * p_generic, uint8_t rep_id) +{ + ASSERT(p_generic != NULL); + app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst; + + return app_usbd_hid_rep_buff_in_get(p_hinst, rep_id); +} + +/**@brief Auxiliary function to prepare report transfer buffer to next transfer + * + * @param[in] p_generic_ctx Internal HID generic context + * @retval true if next transfer is required + * @retval false if next transfer is not required + */ +static inline bool hid_generic_transfer_next(app_usbd_hid_generic_ctx_t * p_generic_ctx, + uint8_t rep_id) +{ + ASSERT(rep_id < 32); + return IS_SET(p_generic_ctx->rep_request_mask, rep_id); +} + + +/** + * @brief Triggers IN endpoint transfer + * + * @param[in] p_generic HID generic instance + * @return Standard error code + */ +static inline ret_code_t hid_generic_transfer_set(app_usbd_hid_generic_t const * p_generic, + uint8_t rep_id) +{ + app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_generic; + app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic); + + nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst); + app_usbd_hid_state_flag_clr(&p_generic_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + + if (!hid_generic_transfer_next(p_generic_ctx, rep_id)) + { + /* Transfer buffer hasn't changed since last transfer. No need to setup + * next transfer. + * */ + return NRF_SUCCESS; + } + + app_usbd_hid_report_buffer_t const * p_rep_buff = hid_generic_rep_buffer_get(p_generic, rep_id); + NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buff->p_buff, p_rep_buff->size); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_ep_transfer(ep_addr, &transfer, NULL); + if (ret == NRF_SUCCESS) + { + p_generic_ctx->rep_in_index = rep_id; + app_usbd_hid_state_flag_set(&p_generic_ctx->hid_ctx, + APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +ret_code_t app_usbd_hid_generic_report_in_set(app_usbd_hid_generic_t const * p_generic, + uint8_t rep_id, + const void * p_buff, + size_t size) +{ + app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic); + app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst; + + if (!app_usbd_hid_generic_report_in_done(p_generic, rep_id)) + { + return NRF_ERROR_BUSY; + } + + /* Get HID report buffer */ + app_usbd_hid_report_buffer_t * p_rep_buff = app_usbd_hid_rep_buff_in_get(p_hinst, rep_id); + ASSERT(p_rep_buff != NULL); + + p_rep_buff->p_buff = (uint8_t *)p_buff; + p_rep_buff->size = size; + + /* Set report ID for reports other than default */ + if (rep_id != 0) + { + p_rep_buff->p_buff[0] = rep_id; + } + + (void)nrf_atomic_u32_or(&p_generic_ctx->rep_request_mask, 1u << rep_id); + if (app_usbd_hid_trans_required(&p_generic_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_generic_transfer_set(p_generic, rep_id); + } + + return NRF_SUCCESS; +} + +bool app_usbd_hid_generic_report_in_done(app_usbd_hid_generic_t const * p_generic, uint8_t rep_id) +{ + app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic); + return IS_SET(p_generic_ctx->rep_request_mask, rep_id) == 0; +} + +uint8_t app_usbd_hid_generic_in_report_last_id(app_usbd_hid_generic_t const * p_generic) +{ + app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic); + return p_generic_ctx->rep_in_index; +} + +const void * app_usbd_hid_generic_out_report_get(app_usbd_hid_generic_t const * p_generic, + size_t * p_size) +{ + app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst; + *p_size = p_hinst->p_rep_buffer_out->size; + return p_hinst->p_rep_buffer_out->p_buff; +} + +/** + * @brief @ref app_usbd_hid_interface_t::on_get_report + */ +static ret_code_t hid_generic_on_get_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_generic_rep_buffer_get(p_generic, + p_setup_ev->setup.wValue.lb); + if (p_rep_buffer == NULL) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer->p_buff, p_rep_buffer->size); +} + + +static ret_code_t hid_generic_on_set_report_data_cb(nrf_drv_usbd_ep_status_t status, + void * p_context) +{ + if (status != NRF_USBD_EP_OK) + { + return NRF_ERROR_INTERNAL; + } + + app_usbd_hid_generic_t const * p_generic = (app_usbd_hid_generic_t const *)p_context; + app_usbd_hid_user_ev_handler_t handler = p_generic->specific.inst.hid_inst.user_event_handler; + + handler((app_usbd_class_inst_t const *)(p_generic), APP_USBD_HID_USER_EVT_OUT_REPORT_READY); + return NRF_SUCCESS; +} + + + +/** + * @brief @ref app_usbd_hid_interface_t::on_set_report + */ +static ret_code_t hid_generic_on_set_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + + /*Request setup data*/ + app_usbd_hid_report_buffer_t const * p_rep_buff; + p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_generic->specific.inst.hid_inst); + + p_rep_buff->p_buff[0] = p_setup_ev->setup.wValue.lb; + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff + 1, p_rep_buff->size - 1); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPOUT0, &transfer, NULL); + if (ret == NRF_SUCCESS) + { + app_usbd_core_setup_data_handler_desc_t desc = { + .handler = hid_generic_on_set_report_data_cb, + .p_context = (void*)p_generic + }; + + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +/** + * @brief @ref app_usbd_hid_interface_t::ep_transfer_in + */ +static ret_code_t hid_generic_ep_transfer_in(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic); + + UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&p_generic_ctx->rep_request_mask, + ~(1u << p_generic_ctx->rep_in_index))); + + uint32_t pending_reports = p_generic_ctx->rep_request_mask; + + if (pending_reports == 0) + { + app_usbd_hid_state_flag_clr(&p_generic_ctx->hid_ctx, + APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + return NRF_SUCCESS; + } + + /* Get next report to send */ + uint32_t rep_id = __CLZ(__RBIT(pending_reports)); + return hid_generic_transfer_set((app_usbd_hid_generic_t const *)p_inst, rep_id); +} + +/** + * @brief @ref app_usbd_hid_interface_t::ep_transfer_out + */ +static ret_code_t hid_generic_ep_transfer_out(app_usbd_class_inst_t const * p_inst) +{ + + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epout_addr_get(p_inst); + + /*Request setup data*/ + app_usbd_hid_report_buffer_t const * p_rep_buff; + p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_generic->specific.inst.hid_inst); + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff, p_rep_buff->size); + + return app_usbd_core_ep_transfer(ep_addr, &transfer, NULL); +} + +/** + * @brief @ref app_usbd_class_interface_t::event_handler + */ +static ret_code_t hid_generic_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst; + app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic); + app_usbd_hid_ctx_t * p_hid_ctx = &p_generic_ctx->hid_ctx; + + + ret_code_t ret = NRF_SUCCESS; + + switch (p_event->app_evt.type) + { + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + if (ret != NRF_ERROR_NOT_SUPPORTED) + { + /* Event was processed by specific handler */ + return ret; + } + + /*Try handle event by generic HID event handler*/ + return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event); +} + +/** + * @brief @ref app_usbd_class_interface_t::get_descriptors + */ +static const void * hid_generic_get_descriptors(app_usbd_class_inst_t const * p_inst, + size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst; + + *p_size = p_hinst->raw_desc_size; + return p_hinst->p_raw_desc; +} + +/** @} */ + +const app_usbd_hid_methods_t app_usbd_hid_generic_methods = { + .on_get_report = hid_generic_on_get_report, + .on_set_report = hid_generic_on_set_report, + .ep_transfer_in = hid_generic_ep_transfer_in, + .ep_transfer_out = hid_generic_ep_transfer_out, +}; + +const app_usbd_class_methods_t app_usbd_generic_class_methods = { + .event_handler = hid_generic_event_handler, + .get_descriptors = hid_generic_get_descriptors, +}; + +#endif // APP_USBD_HID_GENERIC_ENABLED diff --git a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h b/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h new file mode 100644 index 0000000..0e80f81 --- /dev/null +++ b/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h @@ -0,0 +1,231 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_GENERIC_H__ +#define APP_USBD_HID_GENERIC_H__ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_usbd.h" +#include "app_usbd_class_base.h" +#include "app_usbd_hid_types.h" +#include "app_usbd_hid.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_descriptor.h" +#include "app_usbd_hid_generic_desc.h" +#include "app_usbd_hid_generic_internal.h" + +/** + * @defgroup app_usbd_hid_generic USB HID generic + * @ingroup app_usbd_hid + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID generic class. + * @{ + */ + + +#ifdef DOXYGEN +/** + * @brief HID generic class instance type + * + * @ref APP_USBD_CLASS_TYPEDEF + */ +typedef struct { } app_usbd_hid_generic_t; +#else +/*lint -save -e10 -e26 -e123 -e505 */ +APP_USBD_CLASS_TYPEDEF(app_usbd_hid_generic, \ + APP_USBD_HID_GENERIC_CONFIG(0, (NRF_DRV_USBD_EPIN1, NRF_DRV_USBD_EPOUT1)), \ + APP_USBD_HID_GENERIC_INSTANCE_SPECIFIC_DEC, \ + APP_USBD_HID_GENERIC_DATA_SPECIFIC_DEC \ +); +/*lint -restore*/ +#endif + +/** + * @brief Global definition of app_usbd_hid_generic_t class + * + * @param instance_name Name of global instance + * @param interface_number Unique interface index + * @param user_ev_handler User event handler (optional) + * @param endpoint_list Input endpoint list (@ref nrf_drv_usbd_ep_t) + * @param hid_dsc_list HID descriptor item list @ref APP_USBD_HID_REPORT_ITEM, @ref APP_USBD_HID_PHYSICAL_ITEM + * @param report_cnt Report count + * @param report_out_maxsize Maximum output report size + * + * @note This macro is just simplified version of @ref APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL + * + * Example class definition: + * @code + + static uint8_t m_generic_rep_dsc[] = APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(2); + + #define HID_DESCRIPTOR_ITEM_LIST \ + ( \ + m_generic_rep_dsc, \ + ) + + #define ENDPOINT_LIST \ + ( \ + NRF_DRV_USBD_EPIN1 \ + ) + + #define REPORT_COUNT 1 + #define REPORT_OUT_MAXSIZE 0 + + APP_USBD_HID_GENERIC_GLOBAL_DEF(m_app_hid_generic, + 0, + hid_user_ev_handler, + ENDPOINT_LIST, + HID_DESCRIPTOR_ITEM_LIST, + REPORT_COUNT, + REPORT_OUT_MAXSIZE); + @endcode + * + */ +#define APP_USBD_HID_GENERIC_GLOBAL_DEF(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + hid_dsc_list, \ + report_cnt, \ + report_out_maxsize) \ + APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + hid_dsc_list, \ + report_cnt, \ + report_out_maxsize) + + +/** + * @brief Helper function to get class instance from HID generic class + * + * @param[in] p_generic HID generic class instance (defined by @ref APP_USBD_HID_GENERIC_GLOBAL_DEF) + * + * @return Base class instance + */ +static inline app_usbd_class_inst_t const * +app_usbd_hid_generic_class_inst_get(app_usbd_hid_generic_t const * p_generic) +{ + return &p_generic->base; +} + +/** + * @brief Helper function to get HID generic from base class instance + * + * @param[in] p_inst Base class instance + * + * @return HID generic class handle + */ +static inline app_usbd_hid_generic_t const * +app_usbd_hid_generic_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_hid_generic_t const *)p_inst; +} + +/** + * @brief New IN report trigger + * + * + * @param[in] p_generic HID generic class instance (defined by @ref APP_USBD_HID_GENERIC_GLOBAL_DEF) + * @param[in] rep_id Input report ID + * @param[in] p_buff Report buffer + * @param[in] size Report size + * + * @return Standard error code + */ +ret_code_t app_usbd_hid_generic_report_in_set(app_usbd_hid_generic_t const * p_generic, + uint8_t rep_id, + const void * p_buff, + size_t size); + + +/** + * @brief Checks whether last IN report transfer has been done + * + * Helper function to check, whether that last IN report transfer is done. + * + * @param[in] p_generic HID generic class instance (defined by @ref APP_USBD_HID_GENERIC_GLOBAL_DEF) + * @param rep_id input Report ID + * + * @return true if transfer done, false otherwise + */ +bool app_usbd_hid_generic_report_in_done(app_usbd_hid_generic_t const * p_generic, uint8_t rep_id); + + +/** + * @brief Returns last successful transfered IN report. + * + * @note Use this call only on @ref APP_USBD_HID_USER_EVT_IN_REPORT_DONE event + * + * @param[in] p_generic HID generic class instance (defined by @ref APP_USBD_HID_GENERIC_GLOBAL_DEF) + * @return Last transfered report ID. + */ +uint8_t app_usbd_hid_generic_in_report_last_id(app_usbd_hid_generic_t const * p_generic); + +/** + * @brief Returns last successful transfered OUT report. + * + * @warning Use this call only on @ref APP_USBD_HID_USER_EVT_OUT_REPORT_READY event. + * + * @param[in] p_generic HID generic class instance (defined by @ref APP_USBD_HID_GENERIC_GLOBAL_DEF) + * @param[out] p_size Last transfered OUT report size. + * @return Last transfered OUT report. + */ +const void * app_usbd_hid_generic_out_report_get(app_usbd_hid_generic_t const * p_generic, + size_t * p_size); + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_GENERIC_H__ */ diff --git a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h b/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h new file mode 100644 index 0000000..8006c4b --- /dev/null +++ b/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_GENERIC_DESC_H__ +#define APP_USBD_HID_GENERIC_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup app_usbd_hid_generic_desc USB HID generic descriptors + * @ingroup app_usbd_hid_generic + * + * @brief @tagAPI52840 Module with descriptors used by the HID generic class. + * @{ + */ + +/** + * @brief Initializer of interface descriptor for HID generic class + * + * @param interface_number Interface number + * @param endpoints_num Endpoint number + * */ +#define APP_USBD_HID_GENERIC_INTERFACE_DSC(interface_number, endpoints_num) \ + APP_USBD_HID_INTERFACE_DSC(interface_number, endpoints_num, \ + APP_USBD_HID_SUBCLASS_NONE, APP_USBD_HID_PROTO_GENERIC) + +/** + * @brief Initializer of HID descriptor for HID generic class + * + * @param ... Report descriptor item + * */ +#define APP_USBD_HID_GENERIC_HID_DSC(...) \ + APP_USBD_HID_HID_DSC(__VA_ARGS__) +/** + * @brief Initializer of endpoint descriptor for HID generic class + * + * @param endpoint Endpoint number + * */ +#define APP_USBD_HID_GENERIC_EP_DSC(endpoint) \ + APP_USBD_HID_EP_DSC(endpoint, NRF_DRV_USBD_EPSIZE, 1) + + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_GENERIC_DESC_H__ */ diff --git a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h b/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h new file mode 100644 index 0000000..6eb7672 --- /dev/null +++ b/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h @@ -0,0 +1,216 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_GENERIC_INTERNAL_H__ +#define APP_USBD_HID_GENERIC_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup app_usbd_hid_generic_internal USB HID generic internals + * @ingroup app_usbd_hid_generic + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID generic protocol. + * @{ + */ + + +/** + * @brief Forward declaration of HID generic class type + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_hid_generic); + +/** + * @brief HID generic part of class instance data + * + */ +typedef struct { + app_usbd_hid_inst_t hid_inst; //!< HID instance data +} app_usbd_hid_generic_inst_t; + +/** + * @brief HID generic context + * + * */ +typedef struct { + app_usbd_hid_ctx_t hid_ctx; //!< HID class context + nrf_atomic_u32_t rep_request_mask; //!< Input report requests + uint8_t rep_in_index; //!< Current IN report ID + uint8_t rep_out_index; //!< Current OUT report ID +} app_usbd_hid_generic_ctx_t; + + +/** + * @brief HID generic configuration macro + * + * Used by @ref APP_USBD_HID_GENERIC_GLOBAL_DEF + * + * @param iface Interface number + * @param endpoints Endpoint list + * */ +#define APP_USBD_HID_GENERIC_CONFIG(iface, endpoints) ((iface, BRACKET_EXTRACT(endpoints))) + + +/** + * @brief Specific class constant data for HID generic class + * */ +#define APP_USBD_HID_GENERIC_INSTANCE_SPECIFIC_DEC app_usbd_hid_generic_inst_t inst; + +/** + * @brief Specific class data for HID generic class + * */ +#define APP_USBD_HID_GENERIC_DATA_SPECIFIC_DEC app_usbd_hid_generic_ctx_t ctx; + + +/** + * @brief HID generic configuration for one endpoint + * + * @ref APP_USBD_HID_GENERIC_DSC_CONFIG + * */ +#define APP_USBD_HID_GENERIC_DSC_CONFIG_1(interface_number, report_list, ...) { \ + APP_USBD_HID_GENERIC_INTERFACE_DSC(interface_number, NUM_VA_ARGS(__VA_ARGS__)) \ + APP_USBD_HID_GENERIC_HID_DSC(BRACKET_EXTRACT(report_list)) \ + APP_USBD_HID_GENERIC_EP_DSC(GET_VA_ARG_1(__VA_ARGS__)) \ +} + +/** + * @brief HID generic configuration for two endpoints + * + * @ref APP_USBD_HID_GENERIC_DSC_CONFIG + * */ +#define APP_USBD_HID_GENERIC_DSC_CONFIG_2(interface_number, report_list, ...) { \ + APP_USBD_HID_GENERIC_INTERFACE_DSC(interface_number, NUM_VA_ARGS(__VA_ARGS__)) \ + APP_USBD_HID_GENERIC_HID_DSC(BRACKET_EXTRACT(report_list)) \ + APP_USBD_HID_GENERIC_EP_DSC(GET_VA_ARG_1(__VA_ARGS__)) \ + APP_USBD_HID_GENERIC_EP_DSC(GET_VA_ARG_1(GET_ARGS_AFTER_1_(__VA_ARGS__))) \ +} + +/** + * @brief HID generic descriptors config macro + * + * @ref app_usbd_hid_generic_inst_t + * + * @param interface_number Interface number + * @param report_list Report list + * @param ... Endpoint list + * + * */ +#define APP_USBD_HID_GENERIC_DSC_CONFIG(interface_number, report_list, ...) \ + CONCAT_2(APP_USBD_HID_GENERIC_DSC_CONFIG_, NUM_VA_ARGS(__VA_ARGS__)) \ + (interface_number, report_list, __VA_ARGS__) + + +/** + * @brief Configure internal part of HID generic instance + * + * @param descriptors Raw descriptors buffer + * @param report_buff_in Input report buffers array + * @param report_buff_out Output report buffer + * @param user_ev_handler User event handler + * @param ... Hid descriptors list + */ +#define APP_USBD_HID_GENERIC_INST_CONFIG(descriptors, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + ...) \ + .inst = { \ + .hid_inst = APP_USBD_HID_INST_CONFIG(descriptors, \ + GET_VA_ARG_1(__VA_ARGS__), \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + &app_usbd_hid_generic_methods), \ + } + +/** + * @brief Public HID generic interface + * */ +extern const app_usbd_hid_methods_t app_usbd_hid_generic_methods; + +/** + * @brief Public HID generic class interface + * */ +extern const app_usbd_class_methods_t app_usbd_generic_class_methods; + +/** + * @brief Global definition of @ref app_usbd_hid_generic_t class + * + * @ref APP_USBD_HID_GENERIC_GLOBAL_DEF + */ +#define APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + hid_dsc_list, \ + report_cnt, \ + report_out_maxsize) \ + static const uint8_t CONCAT_2(instance_name, _dsc)[] = \ + APP_USBD_HID_GENERIC_DSC_CONFIG(interface_number, \ + hid_dsc_list, \ + BRACKET_EXTRACT(endpoint_list)); \ + static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in)[report_cnt]; \ + APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(CONCAT_2(instance_name, _out), \ + report_out_maxsize + 1); \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_hid_generic, \ + &app_usbd_generic_class_methods, \ + APP_USBD_HID_GENERIC_CONFIG(interface_number, endpoint_list), \ + (APP_USBD_HID_GENERIC_INST_CONFIG(CONCAT_2(instance_name, _dsc), \ + CONCAT_2(instance_name, _in), \ + &CONCAT_2(instance_name, _out), \ + user_ev_handler, \ + BRACKET_EXTRACT(hid_dsc_list))) \ + ) + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_GENERIC_INTERNAL_H__ */ diff --git a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c b/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c new file mode 100644 index 0000000..f25c8fc --- /dev/null +++ b/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c @@ -0,0 +1,402 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_HID_KBD_ENABLED +#include + +#include "sdk_common.h" +#include "app_usbd_hid_kbd.h" +#include "app_util_platform.h" + + +/** + * @defgroup app_usbd_hid_kbd_internals USB HID keyboard internals + * @{ + * @ingroup app_usbd_hid_kbd + * @internals + */ + +STATIC_ASSERT(sizeof(app_usbd_hid_descriptor_t) == 6); + +/** + * @brief Auxiliary function to access HID keyboard context data + * + * @param[in] p_inst class instance data + * @return HID keyboard instance data @ref app_usbd_hid_kbd_ctx_t + */ +static inline app_usbd_hid_kbd_ctx_t * hid_kbd_ctx_get(app_usbd_hid_kbd_t const * p_kbd) +{ + ASSERT(p_kbd != NULL); + ASSERT(p_kbd->specific.p_data != NULL); + return &p_kbd->specific.p_data->ctx; +} + +/** + * @brief Auxiliary function to access HID keyboard instance data + * + * @param[in] p_inst class instance data + * @return HID keyboard instance data @ref app_usbd_hid_kbd_t + */ +static inline app_usbd_hid_kbd_t const * hid_kbd_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_hid_kbd_t const *)p_inst; +} + +/** + * @brief Returns keyboard report buffer handle + * + * @param[in] p_kbd HID keyboard instance + * @return HID report buffer @ref app_usbd_hid_report_buffer_t + * */ +static inline +app_usbd_hid_report_buffer_t const * hid_kbd_rep_buffer_get(app_usbd_hid_kbd_t const * p_kbd) +{ + ASSERT(p_kbd != NULL); + app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst; + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + app_usbd_hid_report_buffer_t * p_rep_buff = app_usbd_hid_rep_buff_in_get(p_hinst, 0); + + p_rep_buff->p_buff = p_kbd_ctx->report_buff; + p_rep_buff->size = sizeof(p_kbd_ctx->report_buff); + + /*Keyboard has only one report input/output report buffer */ + return p_rep_buff; +} + + +/**@brief Auxiliary function to prepare report transfer buffer to next transfer + * + * @param[in] p_kbd HID keyboard instance + * + * @retval true if next transfer is required + * @retval false if next transfer is not required + */ +static inline bool hid_kbd_transfer_next(app_usbd_hid_kbd_t const * p_kbd) +{ + /*Send report only when state has changed*/ + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_kbd_rep_buffer_get(p_kbd); + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + + if (memcmp(p_rep_buffer->p_buff, &p_kbd_ctx->rep, p_rep_buffer->size)) + { + memcpy(p_rep_buffer->p_buff, &p_kbd_ctx->rep, p_rep_buffer->size); + return true; + } + + return false; +} + + +/** + * @brief Triggers IN endpoint transfer + * + * @param[in] p_kbd HID keyboard instance + * @return standard error code + */ +static inline ret_code_t hid_kbd_transfer_set(app_usbd_hid_kbd_t const * p_kbd) +{ + app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_kbd; + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + + nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst); + + app_usbd_hid_state_flag_clr(&p_kbd_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + + if (!hid_kbd_transfer_next(p_kbd)) + { + /* Transfer buffer hasn't changed since last transfer. No need to setup + * next transfer. + * */ + return NRF_SUCCESS; + } + + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_kbd_rep_buffer_get(p_kbd); + NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buffer->p_buff, p_rep_buffer->size); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_ep_transfer(ep_addr, &transfer, NULL); + if (ret == NRF_SUCCESS) + { + app_usbd_hid_state_flag_set(&p_kbd_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +ret_code_t app_usbd_hid_kbd_modifier_state_set(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_modifier_t modifier, + bool state) +{ + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + bool actual_state = (p_kbd_ctx->rep.modifier & modifier) != 0; + + if (actual_state == state) + { + /*Modifier has already the same state*/ + return NRF_SUCCESS; + } + + app_usbd_hid_access_lock(&p_kbd_ctx->hid_ctx); + + if (state) + { + p_kbd_ctx->rep.modifier |= modifier; + } + else + { + p_kbd_ctx->rep.modifier &= ~modifier; + } + app_usbd_hid_access_unlock(&p_kbd_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_kbd_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_kbd_transfer_set(p_kbd); + } + + return NRF_SUCCESS; +} + + +ret_code_t app_usbd_hid_kbd_key_control(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_codes_t key, + bool press) +{ + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + uint8_t * destination = NULL; + if (press) + { + for (size_t i = 0; i < ARRAY_SIZE(p_kbd_ctx->rep.key_table); ++i) { + if (p_kbd_ctx->rep.key_table[i] == key) + { + /*Already pressed*/ + return NRF_SUCCESS; + } + + if ((destination == NULL) && (p_kbd_ctx->rep.key_table[i] == 0)) + { + destination = &p_kbd_ctx->rep.key_table[i]; + } + } + + if (destination == NULL) + { + return NRF_ERROR_BUSY; + } + } + else + { + /*Find if key is pressed*/ + for (size_t i = 0; i < ARRAY_SIZE(p_kbd_ctx->rep.key_table); ++i) { + if (p_kbd_ctx->rep.key_table[i] == key) + { + destination = &p_kbd_ctx->rep.key_table[i]; + break; + } + } + + if (destination == NULL) + { + /*Key hasn't been pressed*/ + return NRF_SUCCESS; + } + } + + /*Save destination*/ + app_usbd_hid_access_lock(&p_kbd_ctx->hid_ctx); + *destination = press ? key : 0; + app_usbd_hid_access_unlock(&p_kbd_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_kbd_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_kbd_transfer_set(p_kbd); + } + + return NRF_SUCCESS; +} + +bool app_usbd_hid_kbd_led_state_get(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_led_t led) +{ + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + + return (p_kbd_ctx->leds_state & led) != 0; +} + +/** + * @brief @ref app_usbd_hid_interface_t::on_get_report + */ +static ret_code_t hid_kbd_on_get_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst); + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_kbd_rep_buffer_get(p_kbd); + + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer->p_buff, p_rep_buffer->size); +} + + +static ret_code_t hid_kbd_on_set_report_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context) +{ + if (status != NRF_USBD_EP_OK) + { + return NRF_ERROR_INTERNAL; + } + + app_usbd_hid_kbd_t const * p_kbd = p_context; + app_usbd_hid_report_buffer_t const * p_rep_buff; + p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_kbd->specific.inst.hid_inst); + + /*Update LEDs state*/ + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + p_kbd_ctx->leds_state = p_rep_buff->p_buff[1]; + + app_usbd_hid_user_ev_handler_t handler = p_kbd->specific.inst.hid_inst.user_event_handler; + handler((app_usbd_class_inst_t const *)(p_kbd), APP_USBD_HID_USER_EVT_OUT_REPORT_READY); + return NRF_SUCCESS; +} + +/** + * @brief @ref app_usbd_hid_interface_t::hid_kbd_on_set_report + */ +static ret_code_t hid_kbd_on_set_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst); + + /*Request setup data*/ + app_usbd_hid_report_buffer_t const * p_rep_buff; + p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_kbd->specific.inst.hid_inst); + + p_rep_buff->p_buff[0] = 0; + NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff + 1, p_rep_buff->size - 1); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_setup_data_transfer(NRF_DRV_USBD_EPOUT0, &transfer, NULL); + if (ret == NRF_SUCCESS) + { + app_usbd_core_setup_data_handler_desc_t desc = { + .handler = hid_kbd_on_set_report_data_cb, + .p_context = (void*)p_kbd + }; + + ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +/** + * @brief @ref app_usbd_hid_interface_t::hid_kbd_ep_transfer_in + */ +static ret_code_t hid_kbd_ep_transfer_in(app_usbd_class_inst_t const * p_inst) +{ + return hid_kbd_transfer_set((app_usbd_hid_kbd_t const *)p_inst); +} + +/** + * @brief @ref app_usbd_class_interface_t::event_handler + */ +static ret_code_t hid_kbd_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst; + + app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd); + app_usbd_hid_ctx_t * p_hid_ctx = &p_kbd_ctx->hid_ctx; + + ret_code_t ret = NRF_SUCCESS; + + switch (p_event->app_evt.type) + { + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + if (ret != NRF_ERROR_NOT_SUPPORTED) + { + /* Event was processed by specific handler */ + return ret; + } + + /*Try handle event by generic HID event handler*/ + return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event); +} + +/** + * @brief @ref app_usbd_class_interface_t::get_descriptors + */ +static const void * hid_kbd_get_descriptors(app_usbd_class_inst_t const * p_inst, + size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst; + + *p_size = p_hinst->raw_desc_size; + return p_hinst->p_raw_desc; +} + +/** @} */ + +const app_usbd_hid_methods_t app_usbd_hid_kbd_methods = { + .on_get_report = hid_kbd_on_get_report, + .on_set_report = hid_kbd_on_set_report, + .ep_transfer_in = hid_kbd_ep_transfer_in, + .ep_transfer_out = NULL, +}; + +const app_usbd_class_methods_t app_usbd_hid_kbd_class_methods = { + .event_handler = hid_kbd_event_handler, + .get_descriptors = hid_kbd_get_descriptors, +}; + +#endif // APP_USBD_HID_KBD_ENABLED diff --git a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h b/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h new file mode 100644 index 0000000..2458a26 --- /dev/null +++ b/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h @@ -0,0 +1,300 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_KBD_H__ +#define APP_USBD_HID_KBD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_usbd.h" +#include "app_usbd_class_base.h" +#include "app_usbd_hid_types.h" +#include "app_usbd_hid.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_descriptor.h" +#include "app_usbd_hid_kbd_desc.h" +#include "app_usbd_hid_kbd_internal.h" + + +/** + * @defgroup app_usbd_hid_kbd USB HID keyboard + * @ingroup app_usbd_hid + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class. + * @{ + */ + +/** + * @brief HID keyboard codes + * */ +typedef enum { + APP_USBD_HID_KBD_A = 4, /**base; +} + +/** + * @brief Helper function to get HID keyboard from base class instance + * + * @param[in] p_inst Base class instance + * @return HID keyboard class handle + */ +static inline app_usbd_hid_kbd_t const * +app_usbd_hid_kbd_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_hid_kbd_t const *)p_inst; +} + +/** + * @brief Set HID keyboard modifier state + * + * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF) + * @param[in] modifier Type of modifier + * @param[in] state State, true active, false inactive + * @return Standard error code + * */ +ret_code_t app_usbd_hid_kbd_modifier_state_set(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_modifier_t modifier, + bool state); + + +/** + * @brief Press/release HID keyboard key + * + * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF) + * @param[in] key Keyboard key code + * @param[in] press True -> key press, false -> release + * @return Standard error code + * */ +ret_code_t app_usbd_hid_kbd_key_control(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_codes_t key, + bool press); +/** + * @brief HID Keyboard LEDs state get + * + * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF) + * @param[in] led LED code + * @return true if LED is set, false otherwise + * */ +bool app_usbd_hid_kbd_led_state_get(app_usbd_hid_kbd_t const * p_kbd, + app_usbd_hid_kbd_led_t led); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_KBD_H__ */ diff --git a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h b/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h new file mode 100644 index 0000000..b956b9a --- /dev/null +++ b/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_KBD_DESC_H__ +#define APP_USBD_HID_KBD_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup app_usbd_hid_kbd_desc USB HID keyboard descriptors + * @ingroup app_usbd_hid_kbd + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class. + * @{ + */ + +/** + * @brief Initializer of interface descriptor for HID keyboard class + * + * @param interface_number Interface number + * */ +#define APP_USBD_HID_KBD_INTERFACE_DSC(interface_number) \ + APP_USBD_HID_INTERFACE_DSC(interface_number, \ + 1, \ + APP_USBD_HID_SUBCLASS_BOOT, \ + APP_USBD_HID_PROTO_KEYBOARD) + +/** + * @brief Initializer of HID descriptor for HID keyboard class + * + * @param ... Report descriptor item + * */ +#define APP_USBD_HID_KBD_HID_DSC(...) \ + APP_USBD_HID_HID_DSC(__VA_ARGS__) +/** + * @brief Initializer of endpoint descriptor for HID keyboard class + * + * @param endpoint Endpoint number + * */ +#define APP_USBD_HID_KBD_EP_DSC(endpoint) \ + APP_USBD_HID_EP_DSC(endpoint, 8, 1) + + +/** + * @brief Example of USB HID keyboard report descriptor + * + * */ +#define APP_USBD_HID_KBD_REPORT_DSC() { \ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */\ + 0x09, 0x06, /* USAGE (Keyboard) */\ + 0xa1, 0x01, /* COLLECTION (Application) */\ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */\ + 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */\ + 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, 0x03, /* 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, 0x03, /* OUTPUT (Cnst,Var,Abs) */\ + 0x95, 0x06, /* REPORT_COUNT (6) */\ + 0x75, 0x08, /* REPORT_SIZE (8) */\ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */\ + 0x25, 0x65, /* LOGICAL_MAXIMUM (101) */\ + 0x05, 0x07, /* USAGE_PAGE (Keyboard) */\ + 0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated))*/\ + 0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */\ + 0x81, 0x00, /* INPUT (Data,Ary,Abs) */\ + 0xc0 /* END_COLLECTION */\ +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_KBD_DESC_H__ */ diff --git a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h b/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h new file mode 100644 index 0000000..6f52888 --- /dev/null +++ b/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h @@ -0,0 +1,197 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_KBD_INTERNAL_H__ +#define APP_USBD_HID_KBD_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @defgroup app_usbd_hid_kbd_internal USB HID keyboard internals + * @ingroup app_usbd_hid_kbd + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class. + * @{ + */ + +/** + * @brief Forward declaration of HID keyboard class type + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_hid_kbd); + + +/** + * @brief HID keyboard part of class instance data + * + */ +typedef struct { + app_usbd_hid_inst_t hid_inst; //!< HID instance data +} app_usbd_hid_kbd_inst_t; + +/** + * @brief HID keyboard context + * + * */ +typedef struct { + app_usbd_hid_ctx_t hid_ctx; //!< HID class context + + struct app_usbd_hid_kbd_ctx_internal_s { + uint8_t modifier; //!< Keyboard modifier state @ref app_usbd_hid_kbd_modifier_t + uint8_t reserved; //!< Reserved value + uint8_t key_table[6]; //!< Keyboard keys table @ref app_usbd_hid_kbd_codes_t + } rep; + + uint8_t report_buff[8]; //!< Raw report buffer + uint8_t leds_state; //!< Output report LEDs state + uint8_t set_report; //!< Set report flag +} app_usbd_hid_kbd_ctx_t; + +/** + * @brief HID keyboard configuration macro + * + * Used by @ref APP_USBD_HID_KBD_GLOBAL_DEF + * + * + * */ +#define APP_USBD_HID_KBD_CONFIG(iface, ep) ((iface, ep)) + + +/** + * @brief Specific class constant data for HID keyboard class + * */ +#define APP_USBD_HID_KBD_INSTANCE_SPECIFIC_DEC app_usbd_hid_kbd_inst_t inst; + +/** + * @brief Specific class data for HID keyboard class + * */ +#define APP_USBD_HID_KBD_DATA_SPECIFIC_DEC app_usbd_hid_kbd_ctx_t ctx; + + +/** + * @brief HID keyboard descriptors config macro + * + * @ref app_usbd_hid_kbd_inst_t + * + * @param interface_number Interface number + * @param endpoint Endpoint number + * @param rep_descriptor Keyboard report descriptor + * */ +#define APP_USBD_HID_KBD_DSC_CONFIG(interface_number, endpoint, rep_descriptor) { \ + APP_USBD_HID_KBD_INTERFACE_DSC(interface_number) \ + APP_USBD_HID_KBD_HID_DSC(rep_descriptor) \ + APP_USBD_HID_KBD_EP_DSC(endpoint) \ +} + +/** + * @brief Configure internal part of HID keyboard instance + * + * @param descriptors Raw descriptors buffer + * @param report_desc Report descriptor + * @param report_buff_in Input report buffers array + * @param report_buff_out Output report buffer + * @param user_ev_handler User event handler + */ +#define APP_USBD_HID_KBD_INST_CONFIG(descriptors, \ + report_desc, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler) \ + .inst = { \ + .hid_inst = APP_USBD_HID_INST_CONFIG(descriptors, \ + report_desc, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + &app_usbd_hid_kbd_methods), \ +} + + +/** + * @brief Public HID keyboard interface + * */ +extern const app_usbd_hid_methods_t app_usbd_hid_kbd_methods; + +/** + * @brief Public HID keyboard class interface + * */ +extern const app_usbd_class_methods_t app_usbd_hid_kbd_class_methods; + +/** + * @brief Global definition of @ref app_usbd_hid_kbd_t class + * + * @ref APP_USBD_HID_KBD_GLOBAL_DEF + */ +#define APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + endpoint, \ + user_ev_handler) \ + static const uint8_t CONCAT_2(instance_name, _rep_dsc)[] = \ + APP_USBD_HID_KBD_REPORT_DSC(); \ + static const uint8_t CONCAT_2(instance_name, _dsc)[] = \ + APP_USBD_HID_KBD_DSC_CONFIG(interface_number, \ + endpoint, \ + CONCAT_2(instance_name, _rep_dsc)); \ + APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(CONCAT_2(instance_name, _out), 1 + 1); \ + static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in)[1]; \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_hid_kbd, \ + &app_usbd_hid_kbd_class_methods, \ + APP_USBD_HID_KBD_CONFIG(interface_number, endpoint), \ + (APP_USBD_HID_KBD_INST_CONFIG(CONCAT_2(instance_name, _dsc), \ + CONCAT_2(instance_name, _rep_dsc), \ + CONCAT_2(instance_name, _in), \ + &CONCAT_2(instance_name, _out), \ + user_ev_handler)) \ + ) + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_HID_KBD_INTERNAL_H__ */ diff --git a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c b/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c new file mode 100644 index 0000000..0a83cf5 --- /dev/null +++ b/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c @@ -0,0 +1,461 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_HID_MOUSE_ENABLED +#include + +#include "sdk_common.h" +#include "app_usbd_hid_mouse.h" +#include "app_util_platform.h" + + +/** + * @defgroup app_usbd_hid_mouse_internal USBD HID Mouse internals + * @{ + * @ingroup app_usbd_hid_mouse + * @internal + */ + +/** + * @brief Auxiliary function to access HID mouse context data + * + * @param[in] p_inst class instance data + * @return HID mouse instance data @ref app_usbd_hid_mouse_ctx_t + */ +static inline app_usbd_hid_mouse_ctx_t * hid_mouse_ctx_get(app_usbd_hid_mouse_t const * p_mouse) +{ + ASSERT(p_mouse != NULL); + ASSERT(p_mouse->specific.p_data != NULL); + return &p_mouse->specific.p_data->ctx; +} + +/** + * @brief Auxiliary function to access HID mouse instance data + * + * @param[in] p_inst class instance data + * @return HID mouse instance data @ref app_usbd_hid_mouse_t + */ +static inline app_usbd_hid_mouse_t const * hid_mouse_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_hid_mouse_t const *)p_inst; +} + + /** + * @brief Returns mouse report buffer handle + * + * @param[in] p_kbd HID keyboard instance + * @return HID report buffer @ref app_usbd_hid_report_buffer_t + * */ +static inline +app_usbd_hid_report_buffer_t const * hid_mouse_rep_buffer_get(app_usbd_hid_mouse_t const * p_mouse) +{ + ASSERT(p_mouse != NULL); + app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst; + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + app_usbd_hid_report_buffer_t * p_rep_buff = app_usbd_hid_rep_buff_in_get(p_hinst, 0); + + p_rep_buff->p_buff = p_mouse_ctx->report_buff; + p_rep_buff->size = sizeof(p_mouse_ctx->report_buff); + + /*Mouse has only one report input report buffer */ + return app_usbd_hid_rep_buff_in_get(p_hinst, 0); +} + +/**@brief Auxiliary function to get report value from internal accumulated value + * + * @param[in] acc accumulated XY axis or scroll + * @return Offset value that could be written directly to report buffer + */ +static inline int8_t hid_mouse_axis_acc_get(int16_t acc) +{ + if (acc > INT8_MAX) + { + return INT8_MAX; + } + + if (acc < INT8_MIN) + { + return INT8_MIN; + } + + return acc; +} + +/**@brief Auxiliary function to prepare report transfer buffer to next transfer + * + * @param[in] p_mouse_ctx mouse internal context + * @retval true if next transfer is required + * @retval false if next transfer is not required + */ +static inline bool hid_mouse_transfer_next(app_usbd_hid_mouse_t const * p_mouse) +{ + + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse); + + uint8_t * p_buff = p_rep_buffer->p_buff; + + /*Save last buttons state*/ + uint8_t last_button_state = p_buff[0]; + + /*Button state*/ + p_buff[0] = p_mouse_ctx->button_state; + + /*Axis X*/ + int8_t val_x = hid_mouse_axis_acc_get(p_mouse_ctx->acc_x_axis); + p_mouse_ctx->acc_x_axis -= val_x; + p_buff[1] = val_x; + + /*Axis Y*/ + int8_t val_y = hid_mouse_axis_acc_get(p_mouse_ctx->acc_y_axis); + p_mouse_ctx->acc_y_axis -= val_y; + p_buff[2] = val_y; + + /*Scroll*/ + int8_t val_scroll = hid_mouse_axis_acc_get(p_mouse_ctx->acc_scroll); + p_mouse_ctx->acc_scroll -= val_scroll; + p_buff[3] = val_scroll; + + if (val_x || val_y || val_scroll) + { + /*New transfer is required if any of mouse relative position is not zero*/ + return true; + } + + if (last_button_state != p_buff[0]) + { + /*New transfer is required if button state has changed*/ + return true; + } + + return false; +} + +/** + * @brief Triggers IN endpoint transfer + * + * @param[in] p_mouse HID mouse instance + * @return standard error code + */ +static inline ret_code_t hid_mouse_transfer_set(app_usbd_hid_mouse_t const * p_mouse) +{ + app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_mouse; + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + + nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst); + + app_usbd_hid_state_flag_clr(&p_mouse_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + if (!hid_mouse_transfer_next(p_mouse)) + { + /* Transfer buffer hasn't changed since last transfer. No need to setup + * next transfer. + * */ + return NRF_SUCCESS; + } + + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse); + + NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buffer->p_buff, p_rep_buffer->size); + + ret_code_t ret; + CRITICAL_REGION_ENTER(); + ret = app_usbd_core_ep_transfer(ep_addr, &transfer, NULL); + if (ret == NRF_SUCCESS) + { + app_usbd_hid_state_flag_set(&p_mouse_ctx->hid_ctx, + APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS); + } + CRITICAL_REGION_EXIT(); + + return ret; +} + +/** + * @brief Checks if adding would cause 16 bit signed integer overflow + * + * @param[in] signed 16 bit accumulator to test + * @param[in] value value to add to accumulator + * @return true if overflow detected, false otherwise + */ +static inline bool hid_mouse_acc_overflow_check(int16_t acc, int8_t val) +{ + if (((int32_t)acc + val) > INT16_MAX) + { + return true; + } + + if (((int32_t)acc + val) < INT16_MIN) + { + return true; + } + + return false; +} + +ret_code_t app_usbd_hid_mouse_x_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset) +{ + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (offset == 0) + { + /*No position change*/ + return NRF_SUCCESS; + } + + if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_y_axis, offset)) + { + /*Overflow detected*/ + return NRF_ERROR_BUSY; + } + + app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx); + p_mouse_ctx->acc_x_axis += offset; + app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_mouse_transfer_set(p_mouse); + } + + return NRF_SUCCESS; +} + +ret_code_t app_usbd_hid_mouse_y_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset) +{ + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + + if (offset == 0) + { + /*No position change*/ + return NRF_SUCCESS; + } + + if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_y_axis, offset)) + { + /*Overflow detected*/ + return NRF_ERROR_BUSY; + } + + app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx); + p_mouse_ctx->acc_y_axis += offset; + app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_mouse_transfer_set(p_mouse); + } + + return NRF_SUCCESS; +} + +ret_code_t app_usbd_hid_mouse_scroll_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset) +{ + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (offset == 0) + { + /*No position change*/ + return NRF_SUCCESS; + } + + if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_scroll, offset)) + { + /*Overflow detected*/ + return NRF_ERROR_BUSY; + } + + app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx); + p_mouse_ctx->acc_scroll += offset; + app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_mouse_transfer_set(p_mouse); + } + + return NRF_SUCCESS; +} + +ret_code_t app_usbd_hid_mouse_button_state(app_usbd_hid_mouse_t const * p_mouse, + uint8_t button_id, + bool state) +{ + ASSERT(button_id < 8); + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + + if (button_id >= p_mouse->specific.inst.button_count) + { + return NRF_ERROR_INVALID_PARAM; + } + + if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx)) + { + return NRF_ERROR_INVALID_STATE; + } + + if (IS_SET(p_mouse_ctx->button_state, button_id) == (state ? 1 : 0)) + { + return NRF_SUCCESS; + } + + app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx); + if (state) + { + SET_BIT(p_mouse_ctx->button_state, button_id); + } + else + { + CLR_BIT(p_mouse_ctx->button_state, button_id); + } + app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx); + + if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx)) + { + /*New transfer need to be triggered*/ + return hid_mouse_transfer_set(p_mouse); + } + + return NRF_SUCCESS; +} + +/** + * @brief @ref app_usbd_hid_interface_t::on_get_report + */ +static ret_code_t hid_mouse_on_get_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst); + app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse); + + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer->p_buff, p_rep_buffer->size); +} + +/** + * @brief @ref app_usbd_hid_interface_t::on_set_report + */ +static ret_code_t hid_mouse_on_set_report(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief @ref app_usbd_hid_interface_t::ep_transfer_set + */ +static ret_code_t hid_mouse_ep_transfer_in(app_usbd_class_inst_t const * p_inst) +{ + return hid_mouse_transfer_set((app_usbd_hid_mouse_t const *)p_inst); +} + +/** + * @brief @ref app_usbd_class_interface_t::event_handler + */ +static ret_code_t hid_mouse_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst; + + app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse); + app_usbd_hid_ctx_t * p_hid_ctx = &p_mouse_ctx->hid_ctx; + + + ret_code_t ret = NRF_SUCCESS; + switch (p_event->app_evt.type) + { + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + if (ret != NRF_ERROR_NOT_SUPPORTED) + { + /* Event was processed by specific handler */ + return ret; + } + + /*Try handle event by generic HID event handler*/ + return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event); +} + +/** + * @brief @ref app_usbd_class_interface_t::get_descriptors + */ +static const void * hid_mouse_get_descriptors(app_usbd_class_inst_t const * p_inst, + size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst); + app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst; + + *p_size = p_hinst->raw_desc_size; + return p_hinst->p_raw_desc; +} + +/** @} */ + +const app_usbd_hid_methods_t app_usbd_hid_mouse_methods = { + .on_get_report = hid_mouse_on_get_report, + .on_set_report = hid_mouse_on_set_report, + .ep_transfer_in = hid_mouse_ep_transfer_in, + .ep_transfer_out = NULL, +}; + +const app_usbd_class_methods_t app_usbd_hid_mouse_class_methods = { + .event_handler = hid_mouse_event_handler, + .get_descriptors = hid_mouse_get_descriptors, +}; + +#endif // APP_USBD_HID_MOUSE_ENABLED diff --git a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h b/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h new file mode 100644 index 0000000..c20c23a --- /dev/null +++ b/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h @@ -0,0 +1,179 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_MOUSE_H__ +#define APP_USBD_HID_MOUSE_H__ + +#include +#include + +#include "nrf_drv_usbd.h" +#include "app_usbd_class_base.h" +#include "app_usbd_hid_types.h" +#include "app_usbd_hid.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_descriptor.h" +#include "app_usbd_hid_mouse_desc.h" +#include "app_usbd_hid_mouse_internal.h" + +/** + * @defgroup app_usbd_hid_mouse USB HID mouse + * @ingroup app_usbd_hid + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class. + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief HID mouse class instance type + * + * @ref APP_USBD_CLASS_TYPEDEF + */ +typedef struct { } app_usbd_hid_mouse_t; +#else +/*lint -save -e10 -e26 -e123 -e505 */ +APP_USBD_CLASS_TYPEDEF(app_usbd_hid_mouse, \ + APP_USBD_HID_MOUSE_CONFIG(0, NRF_DRV_USBD_EPIN1), \ + APP_USBD_HID_MOUSE_INSTANCE_SPECIFIC_DEC, \ + APP_USBD_HID_MOUSE_DATA_SPECIFIC_DEC \ +); +/*lint -restore*/ +#endif +/** + * @brief Global definition of app_usbd_hid_mouse_t class + * + * @param instance_name Name of global instance + * @param interface_number Unique interface number + * @param endpoint Input endpoint (@ref nrf_drv_usbd_ep_t) + * @param bcnt Mouse button count (from 1 to 8) + * @param user_ev_handler User event handler (optional) + * + * @note This macro is just simplified version of @ref APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL. + * + * @code + APP_USBD_HID_MOUSE_GLOBAL_DEF(my_awesome_mouse, 0, NRF_DRV_USBD_EPIN1, 3, NULL) + * @endcode + */ +#define APP_USBD_HID_MOUSE_GLOBAL_DEF(instance_name, \ + interface_number, \ + endpoint, \ + bcnt, \ + user_ev_handler) \ + APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + endpoint, \ + bcnt, \ + user_ev_handler) + + +/** + * @brief Helper function to get class instance from HID mouse internals + * + * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF) + * + * @return Base class instance + * */ +static inline app_usbd_class_inst_t const * +app_usbd_hid_mouse_class_inst_get(app_usbd_hid_mouse_t const * p_mouse) +{ + return &p_mouse->base; +} + +/** + * @brief Helper function to get HID mouse from base class instance + * + * @param[in] p_inst Base class instance + * + * @return HID mouse class handle + */ +static inline app_usbd_hid_mouse_t const * +app_usbd_hid_mouse_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_hid_mouse_t const *)p_inst; +} + +/** + * @brief Move mouse X axis + * + * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF) + * @param[in] offset Relative mouse position: allowed full int8_t range + * + * @return Standard error code + * */ +ret_code_t app_usbd_hid_mouse_x_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset); + +/** + * @brief Move mouse Y axis + * + * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF) + * @param[in] offset Relative mouse position: allowed full int8_t range + * + * @return Standard error code + * */ +ret_code_t app_usbd_hid_mouse_y_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset); + +/** + * @brief Move mouse scroll + * + * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF) + * @param[in] offset Relative mouse position: allowed full int8_t range + * + * @return Standard error code + * */ +ret_code_t app_usbd_hid_mouse_scroll_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset); + +/** +* @brief Set mouse button state +* +* @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF) +* @param[in] button_id Button number (0...7) +* @param[in] state Button state: true -> PRESSED, false -> RELEASED +* +* @return Standard error code +* */ +ret_code_t app_usbd_hid_mouse_button_state(app_usbd_hid_mouse_t const * p_mouse, + uint8_t button_id, + bool state); + +/** @} */ + +#endif /* APP_USBD_HID_MOUSE_H__ */ diff --git a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h b/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h new file mode 100644 index 0000000..8e36d7b --- /dev/null +++ b/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_MOUSE_DESC_H__ +#define APP_USBD_HID_MOUSE_DESC_H__ + +/** + * @defgroup app_usbd_hid_mouse_desc USB HID mouse descriptors + * @ingroup app_usbd_hid_mouse + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class. + * @{ + */ + +/** + * @brief Initializer of interface descriptor for HID mouse class + * + * @param interface_number Interface number + * */ +#define APP_USBD_HID_MOUSE_INTERFACE_DSC(interface_number) \ + APP_USBD_HID_INTERFACE_DSC(interface_number, \ + 1, \ + APP_USBD_HID_SUBCLASS_BOOT, \ + APP_USBD_HID_PROTO_MOUSE) + +/** + * @brief Initializer of HID descriptor for HID mouse class + * + * @param ... Descriptor list + * */ +#define APP_USBD_HID_MOUSE_HID_DSC(...) \ + APP_USBD_HID_HID_DSC(__VA_ARGS__) + +/** + * @brief Initializer of endpoint descriptor for HID mouse class + * + * @param endpoint_number Endpoint number + * */ +#define APP_USBD_HID_MOUSE_EP_DSC(endpoint_number) \ + APP_USBD_HID_EP_DSC(endpoint_number, 8, 1) + + + +/** + * @brief Example of USB HID mouse report descriptor for n button mouse + * + * @param bcnt Button count, allowed values from 1 to 8 + * + * */ +#define APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(bcnt) { \ + 0x05, 0x01, /* Usage Page (Generic Desktop), */ \ + 0x09, 0x02, /* Usage (Mouse), */ \ + 0xA1, 0x01, /* Collection (Application), */ \ + 0x09, 0x01, /* Usage (Pointer), */ \ + 0xA1, 0x00, /* Collection (Physical), */ \ + 0x05, 0x09, /* Usage Page (Buttons), */ \ + 0x19, 0x01, /* Usage Minimum (01), */ \ + 0x29, bcnt, /* Usage Maximum (bcnt), */ \ + 0x15, 0x00, /* Logical Minimum (0), */ \ + 0x25, 0x01, /* Logical Maximum (1), */ \ + 0x75, 0x01, /* Report Size (1), */ \ + 0x95, bcnt, /* Report Count (bcnt), */ \ + 0x81, 0x02, /* Input (Data, Variable, Absolute)*/ \ + 0x75, (8-(bcnt)), /* Report Size (8-(bcnt)), */ \ + 0x95, 0x01, /* Report Count (1), */ \ + 0x81, 0x01, /* Input (Constant), */ \ + 0x05, 0x01, /* Usage Page (Generic Desktop), */ \ + 0x09, 0x30, /* Usage (X), */ \ + 0x09, 0x31, /* Usage (Y), */ \ + 0x09, 0x38, /* Usage (Scroll), */ \ + 0x15, 0x81, /* Logical Minimum (-127), */ \ + 0x25, 0x7F, /* Logical Maximum (127), */ \ + 0x75, 0x08, /* Report Size (8), */ \ + 0x95, 0x03, /* Report Count (3), */ \ + 0x81, 0x06, /* Input (Data, Variable, Relative)*/ \ + 0xC0, /* End Collection, */ \ + 0xC0, /* End Collection */ \ +} + + /** @} */ + +#endif /* APP_USBD_HID_MOUSE_DESC_H__ */ diff --git a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h b/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h new file mode 100644 index 0000000..8495734 --- /dev/null +++ b/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h @@ -0,0 +1,186 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_HID_MOUSE_INTERNAL_H__ +#define APP_USBD_HID_MOUSE_INTERNAL_H__ + +/** + * @defgroup app_usbd_hid_mouse_internals USB HID mouse internals + * @ingroup app_usbd_hid_mouse + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class. + * @{ + */ + +/** + * @brief Forward declaration of HID mouse class type + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_hid_mouse); + + +/** + * @brief HID mouse part of class instance data + * + */ +typedef struct { + app_usbd_hid_inst_t hid_inst; //!< HID instance data + const uint8_t button_count; //!< Number of buttons mouse specific +} app_usbd_hid_mouse_inst_t; + +/** + * @brief HID mouse context + * + * */ +typedef struct { + app_usbd_hid_ctx_t hid_ctx; //!< HID class context + + int16_t acc_x_axis; //!< Mouse specific. Accumulated x axis offset + int16_t acc_y_axis; //!< Mouse specific. Accumulated y axis offset + int16_t acc_scroll; //!< Mouse specific. Accumulated scroll offset + uint8_t button_state; //!< Mouse specific. Actual button state. Bitfield of maximum 8 buttons states. + uint8_t report_buff[4]; +} app_usbd_hid_mouse_ctx_t; + + +/** + * @brief HID mouse configuration macro + * + * Used by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF + * + * */ +#define APP_USBD_HID_MOUSE_CONFIG(iface, ep) ((iface, ep)) + + +/** + * @brief Specific class constant data for HID mouse class + * */ +#define APP_USBD_HID_MOUSE_INSTANCE_SPECIFIC_DEC app_usbd_hid_mouse_inst_t inst; + +/** + * @brief Specific class data for HID mouse class + * */ +#define APP_USBD_HID_MOUSE_DATA_SPECIFIC_DEC app_usbd_hid_mouse_ctx_t ctx; + + +/** + * @brief HID mouse descriptors config macro + * + * @ref app_usbd_hid_mouse_inst_t + * + * */ +#define APP_USBD_HID_MOUSE_DSC_CONFIG(interface_number, endpoint, rep_desc) { \ + APP_USBD_HID_MOUSE_INTERFACE_DSC(interface_number) \ + APP_USBD_HID_MOUSE_HID_DSC(rep_desc) \ + APP_USBD_HID_MOUSE_EP_DSC(endpoint) \ +} + + +/** + * @brief Configure internal part of HID mouse instance + * + * @param descriptors Raw descriptors buffer + * @param report_desc Report descriptor + * @param report_buff_in Input report buffers array + * @param report_buff_out Output report buffer + * @param user_ev_handler User event handler + * @param bcnt Mouse button count + */ +#define APP_USBD_HID_MOUSE_INST_CONFIG(descriptors, \ + report_desc, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + bcnt) \ + .inst = { \ + .hid_inst = APP_USBD_HID_INST_CONFIG(descriptors, \ + report_desc, \ + report_buff_in, \ + report_buff_out, \ + user_ev_handler, \ + &app_usbd_hid_mouse_methods), \ + .button_count = bcnt, \ + } + +/** + * @brief Public HID mouse interface + * */ +extern const app_usbd_hid_methods_t app_usbd_hid_mouse_methods; + +/** + * @brief Public HID mouse class interface + * */ +extern const app_usbd_class_methods_t app_usbd_hid_mouse_class_methods; + +/** + * @brief Global definition of app_usbd_hid_mouse_t class + * + * @ref APP_USBD_HID_MOUSE_GLOBAL_DEF + */ +#define APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + endpoint, \ + bcnt, \ + user_ev_handler) \ + static const uint8_t CONCAT_2(instance_name, _rep_dsc)[] = \ + APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(bcnt); \ + static const uint8_t CONCAT_2(instance_name, _dsc)[] = \ + APP_USBD_HID_MOUSE_DSC_CONFIG(interface_number, \ + endpoint, \ + CONCAT_2(instance_name, \ + _rep_dsc)); \ + static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in)[1]; \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_hid_mouse, \ + &app_usbd_hid_mouse_class_methods, \ + APP_USBD_HID_MOUSE_CONFIG(interface_number, endpoint), \ + (APP_USBD_HID_MOUSE_INST_CONFIG(CONCAT_2(instance_name, _dsc), \ + CONCAT_2(instance_name, _rep_dsc), \ + CONCAT_2(instance_name, _in), \ + NULL, \ + user_ev_handler, \ + bcnt)) \ + ) + + +/** @} */ + +#endif /* APP_USBD_HID_MOUSE_INTERNAL_H__ */ diff --git a/components/libraries/usbd/class/msc/app_usbd_msc.c b/components/libraries/usbd/class/msc/app_usbd_msc.c new file mode 100644 index 0000000..8531f8d --- /dev/null +++ b/components/libraries/usbd/class/msc/app_usbd_msc.c @@ -0,0 +1,2059 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if APP_USBD_CLASS_MSC_ENABLED +#include +#include + +#include "app_usbd.h" +#include "sdk_common.h" +#include "app_usbd_msc.h" +#include "app_usbd_string_desc.h" + +/** + * @defgroup app_usbd_msc_internal USBD MSC internals + * @{ + * @ingroup app_usbd_msc + * @internal + */ + +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_requestsense_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_requestsense_resp_t) == 18); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_inquiry_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_inquiry_resp_t) == 36); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_read6_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_write6_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense6_t) == 6); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense6_resp_t) == 4); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_readcapacity10_t) == 10); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_readcapacity10_resp_t) == 8); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_read10_t) == 10); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_write10_t) == 10); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense10_t) == 10); +STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense10_resp_t) == 8); + +STATIC_ASSERT(sizeof(app_usbd_msc_cbw_t) == 31); +STATIC_ASSERT(sizeof(app_usbd_msc_csw_t) == 13); + +#define NRF_LOG_MODULE_NAME "USBD MSC" +#if APP_USBD_MSC_CLASS_LOG_ENABLED +#else //APP_USBD_MSC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif //APP_USBD_MSC_CONFIG_LOG_ENABLED +#include "nrf_log.h" + +#define APP_USBD_MSC_IFACE_IDX 0 /**< Mass storage class interface index */ +#define APP_USBD_MSC_EPIN_IDX 0 /**< Mass storage class endpoint IN index */ +#define APP_USBD_MSC_EPOUT_IDX 1 /**< Mass storage class endpoint OUT index */ + +/** + * @brief Set request buffer busy flag + * + * @param[in] val Bitmask to set + * @param[in] id Buffer id + * */ +#define APP_USBD_MSC_REQ_BUSY_SET(val, id) SET_BIT(val, id) + +/** + * @brief Clear request buffer busy flag + * + * @param[in] val Bitmask to set + * @param[in] id Buffer id + * */ +#define APP_USBD_MSC_REQ_BUSY_CLR(val, id) CLR_BIT(val, id) + +#define APP_USBD_MSC_REQ_BUSY_FULL_MASK (0x03) /**< Request busy mask */ + +static void msc_blockdev_ev_handler(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_event_t const * p_event); + +/** + * @brief Auxiliary function to access MSC instance data + * + * @param[in] p_inst Class instance data + * + * @return MSC instance data @ref app_usbd_msc_t + */ +static inline app_usbd_msc_t const * msc_get(app_usbd_class_inst_t const * p_inst) +{ + ASSERT(p_inst != NULL); + return (app_usbd_msc_t const *)p_inst; +} + +/** + * @brief Auxiliary function to access MSC context data + * + * @param[in] p_msc MSC instance data + * @return MSC context data @ref app_usbd_msc_ctx_t + */ +static inline app_usbd_msc_ctx_t * msc_ctx_get(app_usbd_msc_t const * p_msc) +{ + ASSERT(p_msc != NULL); + ASSERT(p_msc->specific.p_data != NULL); + return &p_msc->specific.p_data->ctx; +} + +/** + * @brief Auxiliary function to access MSC IN endpoint address + * + * @param[in] p_inst Class instance data + * + * @return IN endpoint address + */ +static inline nrf_drv_usbd_ep_t ep_in_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_MSC_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_MSC_EPIN_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Auxiliary function to access MSC OUT endpoint address + * + * @param[in] p_inst Class instance data + * + * @return OUT endpoint address + */ +static inline nrf_drv_usbd_ep_t ep_out_addr_get(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_class_iface_conf_t const * class_iface; + class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_MSC_IFACE_IDX); + + app_usbd_class_ep_conf_t const * ep_cfg; + ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_MSC_EPOUT_IDX); + + return app_usbd_class_ep_address_get(ep_cfg); +} + +/** + * @brief Command Block Wrapper trigger + * + * @param[in] p_inst Generic class instance + * @param[in] state Next state transition + * + * @return Standard error code + * */ +static ret_code_t cbw_wait_start(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst); + + NRF_LOG_DEBUG("cbw_wait_start\r\n"); + memset(&p_msc_ctx->cbw, 0, sizeof(app_usbd_msc_cbw_t)); + NRF_DRV_USBD_TRANSFER_OUT(cbw, &p_msc_ctx->cbw, sizeof(app_usbd_msc_cbw_t)); + ret_code_t ret = app_usbd_core_ep_transfer(ep_addr_out, &cbw, NULL); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->state = APP_USBD_MSC_STATE_CBW; + } + + return ret; +} + +/** + * @brief Command Status Wrapper trigger + * + * @param[in] p_inst Generic class instance + * @param[in] state Next state transition + * + * @return Standard error code + * */ +static ret_code_t csw_wait_start(app_usbd_class_inst_t const * p_inst, uint8_t status) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst); + + memset(&p_msc_ctx->csw, 0, sizeof(app_usbd_msc_csw_t)); + memcpy(p_msc_ctx->csw.signature, APP_USBD_MSC_CSW_SIGNATURE, sizeof(p_msc_ctx->csw.signature)); + memcpy(p_msc_ctx->csw.tag, p_msc_ctx->cbw.tag, sizeof(p_msc_ctx->csw.tag)); + memcpy(p_msc_ctx->csw.residue, &p_msc_ctx->current.residue, sizeof(uint32_t)); + p_msc_ctx->csw.status = status; + + NRF_DRV_USBD_TRANSFER_IN(csw, &p_msc_ctx->csw, sizeof(app_usbd_msc_csw_t)); + ret_code_t ret = app_usbd_core_ep_transfer(ep_addr_in, &csw, NULL); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->state = APP_USBD_MSC_STATE_CSW; + } + + return ret; +} + +/** + * @brief IN transfer trigger + * + * @param[in] p_inst Generic class instance + * @param[in] p_buff IN transfer data buffer + * @param[in] size IN transfer size + * @param[in] state Next state transition + * + * @return Standard error code + * */ +static ret_code_t transfer_in_start(app_usbd_class_inst_t const * p_inst, + void const * p_buff, + size_t size, + app_usbd_msc_state_t state) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + NRF_LOG_DEBUG("transfer_in_start: p_buff: %p, size: %u\r\n", (uint32_t)p_buff, size); + + nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst); + + NRF_DRV_USBD_TRANSFER_IN(resp, p_buff, size); + ret_code_t ret = app_usbd_core_ep_transfer(ep_addr_in, &resp, NULL); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->state = state; + } + return ret; +} + +/** + * @brief MSC reset request handler @ref APP_USBD_MSC_REQ_BULK_RESET + * + * @param[in] p_inst Generic class instance + * + * */ +static void bulk_ep_reset(app_usbd_class_inst_t const * p_inst) +{ + nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst); + nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst); + + usbd_drv_ep_abort(ep_addr_in); + usbd_drv_ep_abort(ep_addr_out); +} + + +/** + * @brief OUT transfer trigger + * + * @param[in] p_inst Generic class instance + * @param[in] p_buff OUT transfer data buffer + * @param[in] size OUT transfer size + * @param[in] state Next state transition + * + * @return Standard error code + * */ +static ret_code_t transfer_out_start(app_usbd_class_inst_t const * p_inst, + void * p_buff, + size_t size, + app_usbd_msc_state_t state) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + NRF_LOG_DEBUG("transfer_out_start: p_buff: %p, size: %u\r\n", (uint32_t)p_buff, size); + nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst); + + NRF_DRV_USBD_TRANSFER_OUT(resp, p_buff, size); + ret_code_t ret = app_usbd_core_ep_transfer(ep_addr_out, &resp, NULL); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->state = state; + } + return ret; +} + +/** + * @brief Start status stage of unsupported SCSI command + * + * @param[in] p_inst Generic class instance + * + * @return Standard error code + * */ +static ret_code_t unsupported_start(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + if (p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN) + { + return transfer_in_start(p_inst, NULL, 0, APP_USBD_MSC_STATE_UNSUPPORTED); + } + + p_msc_ctx->state = APP_USBD_MSC_STATE_UNSUPPORTED; + return NRF_ERROR_NOT_SUPPORTED; +} + + + +/** + * @brief Internal SETUP standard IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + /*Only Get Descriptor standard IN request is supported by MSC class*/ + if (p_setup_ev->setup.bmRequest != APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + size_t dsc_len = 0; + + /* Try to find descriptor in class internals*/ + void const * p_dsc = app_usbd_class_descriptor_find(p_inst, + p_setup_ev->setup.wValue.hb, + p_setup_ev->setup.wValue.lb, + &dsc_len); + if (p_dsc != NULL) + { + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_dsc, dsc_len); + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP standard OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class IN request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_MSC_REQ_GET_MAX_LUN: + { + + if (p_setup_ev->setup.wValue.w != 0) + { + break; + } + + if (p_setup_ev->setup.wLength.w != 1) + { + break; + } + + size_t tx_size; + uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size); + ASSERT(p_msc->specific.inst.block_devs_count != 0); + p_tx_buff[0] = p_msc->specific.inst.block_devs_count - 1; + + ret_code_t ret = cbw_wait_start(p_inst); + UNUSED_VARIABLE(ret); + return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint8_t)); + } + default: + break; + + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Internal SETUP class OUT request handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + switch (p_setup_ev->setup.bmRequest) + { + case APP_USBD_MSC_REQ_BULK_RESET: + { + if (p_setup_ev->setup.wValue.w != 0) + { + break; + } + + if (p_setup_ev->setup.wLength.w != 0) + { + break; + } + + /* + * Reset internal state to be ready for next CBW + */ + NRF_LOG_DEBUG("bulk ep reset\r\n"); + bulk_ep_reset(p_inst); + + if (p_msc_ctx->state == APP_USBD_MSC_STATE_DISABLED) + { + ret_code_t ret = cbw_wait_start(p_inst); + UNUSED_VARIABLE(ret); + } + + return NRF_SUCCESS; + } + default: + break; + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Control endpoint handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_setup_evt_t const * p_setup_ev) +{ + ASSERT(p_inst != NULL); + ASSERT(p_setup_ev != NULL); + + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + app_usbd_setup_reqrec_t req_rec = app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType); + app_usbd_setup_reqtype_t req_type = app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType); + if (req_rec == APP_USBD_SETUP_REQREC_ENDPOINT && + req_type == APP_USBD_SETUP_REQTYPE_STD) + { + + ret_code_t ret = app_usbd_endpoint_std_req_handle(p_inst, p_setup_ev); + if (ret != NRF_SUCCESS) + { + return ret; + } + + if ((p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_CLEAR_FEATURE) && + (p_msc_ctx->state == APP_USBD_MSC_STATE_UNSUPPORTED)) { + + /*Unsupported command handle: status stage*/ + ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL); + } + + return ret; + } + + ret_code_t ret = app_usbd_interface_std_req_handle(p_inst, p_setup_ev); + if (ret == NRF_SUCCESS || ret != NRF_ERROR_NOT_SUPPORTED) + { + return ret; + } + + if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN) + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_in(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_in(p_inst, p_setup_ev); + default: + break; + } + } + else /*APP_USBD_SETUP_REQDIR_OUT*/ + { + switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType)) + { + case APP_USBD_SETUP_REQTYPE_STD: + return setup_req_std_out(p_inst, p_setup_ev); + case APP_USBD_SETUP_REQTYPE_CLASS: + return setup_req_class_out(p_inst, p_setup_ev); + default: + break; + } + } + + return NRF_ERROR_NOT_SUPPORTED; +} + +/** + * @brief Handle read6/read10 command data stage + * + * @param[in] p_inst Generic class instance + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t state_data_in_handle(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + ret_code_t ret = NRF_SUCCESS; + + p_msc_ctx->current.trans_in_progress = false; + APP_USBD_MSC_REQ_BUSY_CLR(p_msc_ctx->current.req_busy_mask, p_msc_ctx->current.trans_req_id); + + if (p_msc_ctx->current.blk_datasize == 0 && p_msc_ctx->current.req_busy_mask == 0) + { + p_msc_ctx->current.blk_idx = p_msc_ctx->current.blk_size = 0; + ret = csw_wait_start(p_inst, p_msc_ctx->current.csw_status); + return ret; + } + + ASSERT(p_msc_ctx->current.blk_size != 0); + + if (p_msc_ctx->current.req_busy_mask == 0) + { + nrf_block_dev_t const * p_blkd = + p_msc->specific.inst.pp_block_devs[p_msc_ctx->current.lun]; + + /*Trigger new block read request*/ + p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size; + uint32_t req_pos = p_msc_ctx->current.workbuff_pos != 0 ? 1 : 0; + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, req_pos); + + NRF_BLOCK_DEV_REQUEST(req, + p_msc_ctx->current.blk_idx, + p_msc_ctx->current.blk_count, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos)); + + NRF_LOG_DEBUG("nrf_blk_dev_read_req 3: id: %u, count: %u, left: %u, ptr: %p\r\n", + req.blk_id, + req.blk_count, + p_msc_ctx->current.blk_datasize, + (uint32_t)req.p_buff); + + ret = nrf_blk_dev_read_req(p_blkd, &req); + NRF_LOG_DEBUG("nrf_blk_dev_read_req 3: ret: %u\r\n", ret); + return ret; + } + + uint32_t blk_size = p_msc_ctx->current.blk_size; + p_msc_ctx->current.trans_req_id ^= 1; + + nrf_block_req_t * p_req = &p_msc_ctx->current.req; + if (p_req->p_buff == NULL) + { + p_msc_ctx->current.trans_req_id ^= 1; + return NRF_SUCCESS; + } + + ret = transfer_in_start(p_inst, + p_req->p_buff, + p_req->blk_count * blk_size, + APP_USBD_MSC_STATE_DATA_IN); + + if (ret == NRF_SUCCESS) + { + /*Clear processed block request.*/ + memset(p_req, 0, sizeof(nrf_block_req_t)); + p_msc_ctx->current.trans_in_progress = true; + } + + return ret; +} + +/** + * @brief Endpoint IN event handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + NRF_LOG_DEBUG("state: %d, ep in event, status: %d\r\n", + p_msc_ctx->state, + p_event->drv_evt.data.eptransfer.status); + + if (p_event->drv_evt.data.eptransfer.status != NRF_USBD_EP_OK) + { + return NRF_SUCCESS; + } + + ret_code_t ret = NRF_SUCCESS; + switch (p_msc_ctx->state) { + case APP_USBD_MSC_STATE_CMD_IN: + { + ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + break; + } + case APP_USBD_MSC_STATE_DATA_IN: + { + CRITICAL_REGION_ENTER(); + ret = state_data_in_handle(p_inst); + CRITICAL_REGION_EXIT(); + + break; + } + case APP_USBD_MSC_STATE_CSW: + { + break; + } + case APP_USBD_MSC_STATE_DATA_OUT: + { + break; + } + case APP_USBD_MSC_STATE_UNSUPPORTED: + { + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + default: + { + ret = NRF_ERROR_INTERNAL; + break; + } + } + + return ret; +} + + +/** + * @brief Helper function to calculate next block transfer block count + * + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * + * @return Blocks to transfer + * */ +static uint32_t next_transfer_blkcnt_calc(app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + uint32_t blkcnt = p_msc->specific.inst.block_buff_size / p_msc_ctx->current.blk_size; + if (blkcnt > (p_msc_ctx->current.blk_datasize / p_msc_ctx->current.blk_size)) + { + blkcnt = p_msc_ctx->current.blk_datasize / p_msc_ctx->current.blk_size; + } + + return blkcnt; +} + +/** + * @brief Helper function to calculate next transfer size + * + * @param[in] p_msc_ctx MSC context + * + * @return Blocks to transfer + * */ +static uint32_t next_transfer_size_calc(app_usbd_msc_ctx_t * p_msc_ctx) +{ + uint32_t blk_cnt = p_msc_ctx->current.blk_count; + uint32_t blk_size = p_msc_ctx->current.blk_size; + + return p_msc_ctx->current.blk_datasize > blk_size * blk_cnt ? + blk_size * blk_cnt : p_msc_ctx->current.blk_datasize; +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_TESTUNITREADY handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_testunitready(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: TESTUNITREADY\r\n"); + if (uint32_decode(p_msc_ctx->cbw.datlen) != 0) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.cdb_length != APP_USBD_SCSI_CMD_TESTUNITREADY_LEN) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_REQUESTSENSE handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_requestsense(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: REQUESTSENSE\r\n"); + app_usbd_scsi_cmd_requestsense_t const * p_reqs = (const void *)p_msc_ctx->cbw.cdb; + UNUSED_VARIABLE(p_reqs); + + if ((p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_requestsense_t))) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->resp_len = MIN(p_msc_ctx->resp_len, + sizeof(app_usbd_scsi_cmd_requestsense_resp_t)); + + if (p_msc_ctx->resp_len == 0) + { + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + } + + memset(&p_msc_ctx->scsi_resp, 0, sizeof(app_usbd_scsi_cmd_requestsense_resp_t)); + p_msc_ctx->scsi_resp.requestsense.code = APP_USBD_SCSI_CMD_REQSENSE_CODE_VALID | + APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENT; + + p_msc_ctx->scsi_resp.requestsense.len = sizeof(app_usbd_scsi_cmd_requestsense_resp_t) - + offsetof(app_usbd_scsi_cmd_requestsense_resp_t, len); + + return transfer_in_start(p_inst, + &p_msc_ctx->scsi_resp, + p_msc_ctx->resp_len, + APP_USBD_MSC_STATE_CMD_IN); +} + + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_FORMAT_UNIT handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_formatunit(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: FORMAT_UNIT\r\n"); + return unsupported_start(p_inst); +} + +static ret_code_t cmd_read_start(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + + p_msc_ctx->current.trans_in_progress = false; + p_msc_ctx->current.req_busy_mask = 0; + p_msc_ctx->current.workbuff_pos = 0; + + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, 0); + NRF_BLOCK_DEV_REQUEST(req, + p_msc_ctx->current.blk_idx, + p_msc_ctx->current.blk_count, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos)); + + NRF_LOG_DEBUG("cmd_read_start\r\n"); + NRF_LOG_DEBUG("nrf_blk_dev_read_req 1: id: %u, count: %u, left: %u, ptr: %p\r\n", + req.blk_id, + req.blk_count, + p_msc_ctx->current.blk_datasize, + (uint32_t)req.p_buff); + + ret_code_t ret = nrf_blk_dev_read_req(p_blkd, &req); + NRF_LOG_DEBUG("nrf_blk_dev_read_req 1: ret: %u\r\n", ret); + + return ret; +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READ6 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_read6(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: READ6\r\n"); + app_usbd_scsi_cmd_read6_t const * p_read6 = (const void *)p_msc_ctx->cbw.cdb; + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_read6_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + + p_msc_ctx->current.lun = p_msc_ctx->cbw.lun; + p_msc_ctx->current.blk_idx = ((p_read6->mslba & 0x1F) << 16) | + uint16_big_decode(p_read6->lslba); + p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size; + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + + if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * p_read6->xfrlen) + { + p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize - + p_msc_ctx->current.blk_size * p_read6->xfrlen; + } + + return cmd_read_start(p_inst, p_msc, p_msc_ctx); +} + +static ret_code_t cmd_write_start(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("cmd_write_start\r\n"); + ret_code_t ret = transfer_out_start(p_inst, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos), + next_transfer_size_calc(p_msc_ctx), + APP_USBD_MSC_STATE_DATA_OUT); + + if (ret == NRF_SUCCESS) + { + p_msc_ctx->current.trans_req_id = 0; + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, + p_msc_ctx->current.trans_req_id); + p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size; + p_msc_ctx->current.trans_in_progress = true; + } + + return ret; +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_WRITE6 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_write6(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: WRITE6\r\n"); + app_usbd_scsi_cmd_write6_t const * p_write6 = (const void *)p_msc_ctx->cbw.cdb; + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_write6_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + + p_msc_ctx->current.lun = p_msc_ctx->cbw.lun; + p_msc_ctx->current.blk_idx = (p_write6->mslba & 0x1F << 16) | + uint16_big_decode(p_write6->lslba); + p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size; + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + + if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * p_write6->xfrlen) + { + p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize - + p_msc_ctx->current.blk_size * p_write6->xfrlen; + } + + return cmd_write_start(p_inst, p_msc, p_msc_ctx); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_INQUIRY handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_inquiry(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: INQUIRY\r\n"); + app_usbd_scsi_cmd_inquiry_t const * p_inq = (const void *)p_msc_ctx->cbw.cdb; + if (p_inq->pagecode != 0) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->resp_len = MIN(p_msc_ctx->resp_len, + sizeof(app_usbd_scsi_cmd_inquiry_resp_t)); + + if (p_msc_ctx->resp_len == 0) + { + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + } + + + p_msc_ctx->scsi_resp.inquiry.qualtype = APP_USBD_MSC_SCSI_INQ_QUAL_CONNECTED | + APP_USBD_MSC_SCSI_INQ_TYPE_DIR_ACCESS; + p_msc_ctx->scsi_resp.inquiry.flags1 = APP_USBD_MSC_SCSI_INQ_FLAG1_RMB; + p_msc_ctx->scsi_resp.inquiry.version = APP_USBD_SCSI_INQ_VER_SPC4; + p_msc_ctx->scsi_resp.inquiry.flags2 = APP_USBD_MSC_SCSI_INQ_FLAG2_RSP_SPC2 | + APP_USBD_MSC_SCSI_INQ_FLAG2_HISUP; + p_msc_ctx->scsi_resp.inquiry.len = sizeof(app_usbd_scsi_cmd_inquiry_resp_t) - + offsetof(app_usbd_scsi_cmd_inquiry_resp_t, len); + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + nrf_block_dev_info_strings_t * p_strings = NULL; + UNUSED_RETURN_VALUE(nrf_blk_dev_ioctl(p_blkd, + NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS, + &p_strings)); + + if (p_strings) + { + UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.vendorid, + p_strings->p_vendor, + sizeof(p_msc_ctx->scsi_resp.inquiry.vendorid))); + + UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.productid, + p_strings->p_product, + sizeof(p_msc_ctx->scsi_resp.inquiry.productid))); + + UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.revision, + p_strings->p_revision, + sizeof(p_msc_ctx->scsi_resp.inquiry.revision))); + } + else { + memset(p_msc_ctx->scsi_resp.inquiry.vendorid, + 0, + sizeof(p_msc_ctx->scsi_resp.inquiry.vendorid)); + memset(p_msc_ctx->scsi_resp.inquiry.productid, + 0, + sizeof(p_msc_ctx->scsi_resp.inquiry.productid)); + memset(p_msc_ctx->scsi_resp.inquiry.revision, + 0, + sizeof(p_msc_ctx->scsi_resp.inquiry.revision)); + } + + return transfer_in_start(p_inst, + &p_msc_ctx->scsi_resp, + p_msc_ctx->resp_len, + APP_USBD_MSC_STATE_CMD_IN); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESELECT6 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_modeselect6(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: MODESELECT6\r\n"); + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESENSE6 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_modesense6(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: MODESENSE6\r\n"); + app_usbd_scsi_cmd_modesense6_t const * p_sense6 = (const void *)p_msc_ctx->cbw.cdb; + UNUSED_VARIABLE(p_sense6); + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_modesense6_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->resp_len = MIN(p_msc_ctx->resp_len, + sizeof(app_usbd_scsi_cmd_modesense6_resp_t)); + + app_usbd_scsi_cmd_modesense6_resp_t * p_resp = &p_msc_ctx->scsi_resp.modesense6; + p_resp->mdlen = sizeof(app_usbd_scsi_cmd_modesense6_resp_t) - 1; + p_resp->type = 0; + p_resp->param = 0; + p_resp->bdlen = 0; + + return transfer_in_start(p_inst, + &p_msc_ctx->scsi_resp, + p_msc_ctx->resp_len, + APP_USBD_MSC_STATE_CMD_IN); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_STARTSTOPUNIT handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_startstopunit(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: STARTSTOPUNIT\r\n"); + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_SENDDIAGNOSTIC handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_senddiagnostic(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: SENDDIAGNOSTIC\r\n"); + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_preventremoval(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: PREVENTMEDIAREMOVAL\r\n"); + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READCAPACITY10 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_readcapacity10(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: READCAPACITY10\r\n"); + + app_usbd_scsi_cmd_readcapacity10_t const * p_cap10 = (const void *)p_msc_ctx->cbw.cdb; + UNUSED_VARIABLE(p_cap10); + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_readcapacity10_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->resp_len = MIN(p_msc_ctx->resp_len, + sizeof(app_usbd_scsi_cmd_readcapacity10_resp_t)); + + if (p_msc_ctx->resp_len == 0) + { + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + } + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + nrf_block_dev_geometry_t const * p_geometry = nrf_blk_dev_geometry(p_blkd); + + (void)uint32_big_encode(p_geometry->blk_count - 1, p_msc_ctx->scsi_resp.readcapacity10.lba); + (void)uint32_big_encode(p_geometry->blk_size, p_msc_ctx->scsi_resp.readcapacity10.blklen); + + return transfer_in_start(p_inst, + &p_msc_ctx->scsi_resp, + p_msc_ctx->resp_len, + APP_USBD_MSC_STATE_CMD_IN); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READ10 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_read10(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: READ10\r\n"); + app_usbd_scsi_cmd_read10_t const * p_read10 = (const void *)p_msc_ctx->cbw.cdb; + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_read10_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + if (uint32_decode(p_msc_ctx->cbw.datlen) == 0) + { + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL); + } + + if ((p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN) == 0) + { + return unsupported_start(p_inst); + } + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + + p_msc_ctx->current.lun = p_msc_ctx->cbw.lun; + p_msc_ctx->current.blk_idx = uint32_big_decode(p_read10->lba); + p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size; + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + + uint16_t blocks = uint16_big_decode(p_read10->xfrlen); + p_msc_ctx->current.csw_status = + uint32_decode(p_msc_ctx->cbw.datlen) < p_msc_ctx->current.blk_size * blocks ? + APP_USBD_MSC_CSW_STATUS_FAIL : APP_USBD_MSC_CSW_STATUS_PASS; + + if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * blocks) + { + p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize - + p_msc_ctx->current.blk_size * blocks; + } + + return cmd_read_start(p_inst, p_msc, p_msc_ctx); +} + + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_WRITE10 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_write10(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: WRITE10\r\n"); + app_usbd_scsi_cmd_write10_t const * p_write10 = (const void *)p_msc_ctx->cbw.cdb; + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_write10_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + if (uint32_decode(p_msc_ctx->cbw.datlen) == 0) + { + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL); + } + + + if ((p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN) != 0) + { + return unsupported_start(p_inst); + } + + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun]; + + p_msc_ctx->current.lun = p_msc_ctx->cbw.lun; + p_msc_ctx->current.blk_idx = uint32_big_decode(p_write10->lba); + p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size; + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + + uint16_t blocks = uint16_big_decode(p_write10->xfrlen); + p_msc_ctx->current.csw_status = + uint32_decode(p_msc_ctx->cbw.datlen) < p_msc_ctx->current.blk_size * blocks ? + APP_USBD_MSC_CSW_STATUS_FAIL : APP_USBD_MSC_CSW_STATUS_PASS; + + if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * blocks) + { + p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize - + p_msc_ctx->current.blk_size * blocks; + } + + return cmd_write_start(p_inst, p_msc, p_msc_ctx); +} + + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESELECT10 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_modeselect10(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: MODESELECT10\r\n"); + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); +} + +/** + * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESENSE10 handle + * + * @param[in] p_inst Generic class instance + * @param[in] p_msc MSC instance + * @param[in] p_msc_ctx MSC context + * @return Standard error code + * */ +static ret_code_t cmd_modesense10(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_t const * p_msc, + app_usbd_msc_ctx_t * p_msc_ctx) +{ + NRF_LOG_DEBUG("CMD: MODESENSE10\r\n"); + app_usbd_scsi_cmd_modesense10_t const * p_sense10 = (const void *)p_msc_ctx->cbw.cdb; + UNUSED_VARIABLE(p_sense10); + if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_modesense10_t)) + { + return unsupported_start(p_inst); + } + + if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count) + { + return unsupported_start(p_inst); + } + + p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen); + p_msc_ctx->resp_len = MIN(p_msc_ctx->resp_len, + sizeof(app_usbd_scsi_cmd_modesense6_resp_t)); + + app_usbd_scsi_cmd_modesense10_resp_t * p_resp = &p_msc_ctx->scsi_resp.modesense10; + + memset(p_resp, 0, sizeof(app_usbd_scsi_cmd_modesense10_resp_t)); + uint16_t len = sizeof(app_usbd_scsi_cmd_modesense10_resp_t) - sizeof(p_resp->mdlen); + p_resp->mdlen[1] = len & 0xff; + p_resp->mdlen[0] = (len >> 8) & 0xff; + + return transfer_in_start(p_inst, + &p_msc_ctx->scsi_resp, + p_msc_ctx->resp_len, + APP_USBD_MSC_STATE_CMD_IN); +} + + +/** + * @brief SCSI Command Block Wrapper handler + * + * @param[in] p_inst Generic class instance + * @return Standard error code + * */ +static ret_code_t state_cbw(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + memset(&p_msc_ctx->current, 0, sizeof(p_msc_ctx->current)); + + /*Verify CBW signature*/ + if (memcmp(p_msc_ctx->cbw.signature, + APP_USBD_MSC_CBW_SIGNATURE, + sizeof(p_msc_ctx->cbw.signature)) != 0) + { + NRF_LOG_DEBUG("CMD: header error: 0x%02x%02x%02x%02x\r\n", + p_msc_ctx->cbw.signature[0], p_msc_ctx->cbw.signature[1], + p_msc_ctx->cbw.signature[2], p_msc_ctx->cbw.signature[3]); + + return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + } + + ret_code_t ret = NRF_SUCCESS; + switch (p_msc_ctx->cbw.cdb[0]) + { + case APP_USBD_SCSI_CMD_TESTUNITREADY: + ret = cmd_testunitready(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_REQUESTSENSE: + ret = cmd_requestsense(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_FORMAT_UNIT: + ret = cmd_formatunit(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_READ6: + ret = cmd_read6(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_WRITE6: + ret = cmd_write6(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_INQUIRY: + ret = cmd_inquiry(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_MODESELECT6: + ret = cmd_modeselect6(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_MODESENSE6: + ret = cmd_modesense6(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_STARTSTOPUNIT: + ret = cmd_startstopunit(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_SENDDIAGNOSTIC: + ret = cmd_senddiagnostic(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL: + ret = cmd_preventremoval(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_READCAPACITY10: + ret = cmd_readcapacity10(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_READ10: + ret = cmd_read10(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_WRITE10: + ret = cmd_write10(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_MODESELECT10: + ret = cmd_modeselect10(p_inst, p_msc, p_msc_ctx); + break; + case APP_USBD_SCSI_CMD_MODESENSE10: + ret = cmd_modesense10(p_inst, p_msc, p_msc_ctx); + break; + default: + NRF_LOG_DEBUG("CMD: UNSUPPORTED\r\n"); + if (uint32_decode(p_msc_ctx->cbw.datlen) != 0) + { + ret = unsupported_start(p_inst); + } + else + { + ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL); + } + break; + } + + return ret; +} + + +/** + * @brief Handle write6/write10 command data stage + * + * @param[in] p_inst Generic class instance + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t state_data_out_handle(app_usbd_class_inst_t const * p_inst) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + ret_code_t ret = NRF_SUCCESS; + uint32_t blk_size = p_msc_ctx->current.blk_size; + + NRF_LOG_DEBUG("APP_USBD_MSC_STATE_DATA_OUT\r\n"); + + p_msc_ctx->current.trans_in_progress = false; + if ((p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK) && + (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_count * blk_size)) + { + size_t size = p_msc_ctx->current.blk_datasize - p_msc_ctx->current.blk_count * blk_size; + if (size > p_msc_ctx->current.blk_count * blk_size) + { + size = p_msc_ctx->current.blk_count * blk_size; + } + + if (size) + { + ret = transfer_out_start(p_inst, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos), + size, + APP_USBD_MSC_STATE_DATA_OUT); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->current.trans_req_id ^= 1; + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, + p_msc_ctx->current.trans_req_id); + p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size; + p_msc_ctx->current.trans_in_progress = true; + } + } + } + + if (!p_msc_ctx->current.block_req_in_progress) + { + nrf_block_dev_t const * p_blkd = + p_msc->specific.inst.pp_block_devs[p_msc_ctx->current.lun]; + + size_t pos = p_msc_ctx->current.workbuff_pos;; + if (p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK) + { + pos ^= p_msc->specific.inst.block_buff_size; + } + + NRF_BLOCK_DEV_REQUEST(req, + p_msc_ctx->current.blk_idx, + p_msc_ctx->current.blk_count, + ((uint8_t *)p_msc->specific.inst.p_block_buff + pos)); + + NRF_LOG_DEBUG("nrf_blk_dev_write_req 1: id: %u, count: %u, left: %u, ptr: %p\r\n", + req.blk_id, + req.blk_count, + p_msc_ctx->current.blk_datasize, + (uint32_t)req.p_buff); + + p_msc_ctx->current.block_req_in_progress = true; + ret = nrf_blk_dev_write_req(p_blkd, &req); + NRF_LOG_DEBUG("nrf_blk_dev_write_req 1: ret: %u\r\n", ret); + } + + return ret; +} + +/** + * @brief Endpoint OUT event handler + * + * @param[in] p_inst Generic class instance + * @param[in] p_setup_ev Setup event + * + * @return Standard error code + * @retval NRF_SUCCESS if request handled correctly + * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported + */ +static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + NRF_LOG_DEBUG("state: %d, ep out event, status: %d\r\n", + p_msc_ctx->state, + p_event->drv_evt.data.eptransfer.status); + + ret_code_t ret = NRF_SUCCESS; + if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_WAITING) + { + if (p_msc_ctx->state == APP_USBD_MSC_STATE_DATA_OUT) + { + NRF_LOG_DEBUG("NRF_USBD_EP_WAITING\r\n"); + } + else if (p_msc_ctx->state == APP_USBD_MSC_STATE_CSW || + p_msc_ctx->state == APP_USBD_MSC_STATE_IDLE) + { + ret = cbw_wait_start(p_inst); + } + + return ret; + } + else if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_ABORTED) + { + p_msc_ctx->state = APP_USBD_MSC_STATE_IDLE; + return NRF_SUCCESS; + } + else if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OVERLOAD) + { + nrf_drv_usbd_transfer_out_drop(p_event->drv_evt.data.eptransfer.ep); + return NRF_SUCCESS; + } + else /*NRF_USBD_EP_OK*/ + { + switch (p_msc_ctx->state) + { + case APP_USBD_MSC_STATE_CBW: + { + ret = state_cbw(p_inst); + break; + } + case APP_USBD_MSC_STATE_CMD_OUT: + { + ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS); + break; + } + case APP_USBD_MSC_STATE_DATA_OUT: + { + CRITICAL_REGION_ENTER(); + ret = state_data_out_handle(p_inst); + CRITICAL_REGION_EXIT(); + break; + } + case APP_USBD_MSC_STATE_UNSUPPORTED: + { + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + case APP_USBD_MSC_STATE_CSW: + break; + default: + { + ASSERT(0); + break; + } + } + } + + return ret; +} + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] p_hinst MSC instance + * @param[in] event user Event type @ref app_usbd_msc_user_event_t + * */ +static inline void user_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_msc_inst_t const * p_msc, + app_usbd_msc_user_event_t event) +{ + if (p_msc->user_ev_handler != NULL) + { + p_msc->user_ev_handler(p_inst, event); + } +} + +/** + * @brief @ref app_usbd_class_methods_t::event_handler + */ +static ret_code_t msc_event_handler(app_usbd_class_inst_t const * p_inst, + app_usbd_complex_evt_t const * p_event) +{ + ASSERT(p_inst != NULL); + ASSERT(p_event != NULL); + + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + UNUSED_VARIABLE(p_msc); + UNUSED_VARIABLE(p_msc_ctx); + + ret_code_t ret = NRF_SUCCESS; + switch (p_event->app_evt.type) + { + case APP_USBD_EVT_DRV_SOF: + break; + case APP_USBD_EVT_DRV_RESET: + break; + case APP_USBD_EVT_DRV_SETUP: + ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event); + break; + case APP_USBD_EVT_DRV_EPTRANSFER: + if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep)) + { + ret = endpoint_in_event_handler(p_inst, p_event); + } + else + { + ret = endpoint_out_event_handler(p_inst, p_event); + } + break; + case APP_USBD_EVT_DRV_SUSPEND: + { + /*Flush all block devices cache on suspend*/ + + for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i) + { + nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[i]; + (void)nrf_blk_dev_ioctl(p_blkd, NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH, NULL); + } + + user_event_handler(p_inst, &p_msc->specific.inst, APP_USBD_MSC_USER_EVT_SUSPEND); + break; + } + case APP_USBD_EVT_DRV_RESUME: + user_event_handler(p_inst, &p_msc->specific.inst, APP_USBD_MSC_USER_EVT_RESUME); + break; + case APP_USBD_EVT_INST_APPEND: + { + /*Verify serial number string*/ + uint16_t const * p_serial_str = app_usbd_string_desc_get(APP_USBD_STRING_ID_SERIAL, 0); + if (p_serial_str == NULL) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + size_t len = app_usbd_string_desc_length(p_serial_str) / sizeof(uint16_t); + if (len < APP_USBD_MSC_MINIMAL_SERIAL_STRING_SIZE) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + for (size_t i = 1; i < len; ++i) + { + if (isxdigit(p_serial_str[i]) == 0) + { + return NRF_ERROR_NOT_SUPPORTED; + } + } + + ret = app_usbd_class_sof_register(p_inst); + if (ret != NRF_SUCCESS) + { + break; + } + + break; + } + case APP_USBD_EVT_INST_REMOVE: + { + ret = app_usbd_class_sof_unregister(p_inst); + break; + } + case APP_USBD_EVT_START: + { + /*Initialize all block devices*/ + ASSERT(p_msc->specific.inst.block_devs_count <= 16); + for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i) + { + nrf_block_dev_t const * p_blk_dev = p_msc->specific.inst.pp_block_devs[i]; + ret = nrf_blk_dev_init(p_blk_dev, msc_blockdev_ev_handler, p_msc); + if (ret != NRF_SUCCESS) + { + continue; + } + + p_msc_ctx->blk_dev_init_mask |= 1u << i; + ASSERT(nrf_blk_dev_geometry(p_blk_dev)->blk_size <= + p_msc->specific.inst.block_buff_size); + } + + user_event_handler(p_inst, &p_msc->specific.inst, APP_USBD_MSC_USER_EVT_START); + break; + } + case APP_USBD_EVT_STOP: + { + /*Un-initialize all block devices*/ + ASSERT(p_msc->specific.inst.block_devs_count <= 16); + size_t i; + for (i = 0; i < p_msc->specific.inst.block_devs_count; ++i) + { + nrf_block_dev_t const * p_blk_dev = p_msc->specific.inst.pp_block_devs[i]; + ret = nrf_blk_dev_uninit(p_blk_dev); + if (ret != NRF_SUCCESS) + { + continue; + } + + p_msc_ctx->blk_dev_init_mask &= ~(1u << i); + } + + user_event_handler(p_inst, &p_msc->specific.inst, APP_USBD_MSC_USER_EVT_STOP); + break; + } + default: + ret = NRF_ERROR_NOT_SUPPORTED; + break; + } + + return ret; +} + +/** + * @brief @ref app_usbd_class_methods_t::get_descriptors + */ +static const void * msc_get_descriptors(app_usbd_class_inst_t const * p_inst, size_t * p_size) +{ + ASSERT(p_size != NULL); + app_usbd_msc_t const * p_msc = msc_get(p_inst); + + *p_size = p_msc->specific.inst.raw_desc_size; + return p_msc->specific.inst.p_raw_desc; +} + +const app_usbd_class_methods_t app_usbd_msc_class_methods = { + .event_handler = msc_event_handler, + .get_descriptors = msc_get_descriptors, +}; + + +/** + * @brief Block device read done event handler. + * + * @ref NRF_BLOCK_DEV_EVT_BLK_READ_DONE + * + * @param p_blk_dev Block device handle + * @param p_event Block device event + * + * */ +static void msc_blockdev_read_done_handler(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_event_t const * p_event) +{ + ret_code_t ret; + + app_usbd_class_inst_t const * p_inst = p_event->p_context; + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + uint32_t blk_cnt = p_msc_ctx->current.blk_count; + uint32_t blk_size = p_msc_ctx->current.blk_size; + + /*Save actual request*/ + size_t req_pos = (p_msc_ctx->current.workbuff_pos != 0) ? 1 : 0; + p_msc_ctx->current.req = *p_event->p_blk_req; + + p_msc_ctx->current.block_req_in_progress = false; + + /*Decrement transfer counter*/ + p_msc_ctx->current.blk_idx += blk_cnt; + if (p_msc_ctx->current.blk_datasize > blk_size * blk_cnt) + { + p_msc_ctx->current.blk_datasize -= blk_size * blk_cnt; + } + else + { + p_msc_ctx->current.blk_datasize = 0; + } + + NRF_LOG_DEBUG("read_done_handler: p_buff: %p, size: %u data size: %u req_pos: %u\r\n", + (uint32_t)p_event->p_blk_req->p_buff, + p_event->p_blk_req->blk_count, + p_msc_ctx->current.blk_datasize, + req_pos); + + /*Calculate next block request size*/ + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + + if (!p_msc_ctx->current.trans_in_progress) + { + /*Trigger new transfer.*/ + p_msc_ctx->current.trans_req_id = req_pos; + nrf_block_req_t * p_req = &p_msc_ctx->current.req; + + ret = transfer_in_start(p_inst, + p_req->p_buff, + p_req->blk_count * blk_size, + APP_USBD_MSC_STATE_DATA_IN); + if (ret != NRF_SUCCESS) + { + UNUSED_RETURN_VALUE(unsupported_start(p_inst)); + } + else + { + /*Clear processed block request.*/ + memset(p_req, 0, sizeof(nrf_block_req_t)); + p_msc_ctx->current.trans_in_progress = true; + } + + } + + if (p_msc_ctx->current.req_busy_mask == APP_USBD_MSC_REQ_BUSY_FULL_MASK) + { + /* No need to perform next block read request. USB transfers need to catch-up + * block device readings */ + return; + } + + if (p_msc_ctx->current.blk_count == 0) + { + /*All data has been read. No need to trigger new block request.*/ + return; + } + + /*Trigger new block read request*/ + p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size; + req_pos = p_msc_ctx->current.workbuff_pos != 0 ? 1 : 0; + + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, req_pos); + + NRF_BLOCK_DEV_REQUEST(req, + p_msc_ctx->current.blk_idx, + p_msc_ctx->current.blk_count, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos)); + + + NRF_LOG_DEBUG("nrf_blk_dev_read_req 2: id: %u, count: %u, left: %u, ptr: %p\r\n", + req.blk_id, + req.blk_count, + p_msc_ctx->current.blk_datasize, + (uint32_t)req.p_buff); + + ret = nrf_blk_dev_read_req(p_blk_dev, &req); + NRF_LOG_DEBUG("nrf_blk_dev_read_req 2: ret: %u\r\n", ret); + + if (ret != NRF_SUCCESS) + { + UNUSED_RETURN_VALUE(unsupported_start(p_inst)); + } +} + +/** + * @brief Block device write done event handler. + * + * @ref NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE + * + * @param p_blk_dev Block device handle + * @param p_event Block device event + * + * */ +static void msc_blockdev_write_done_handler(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_event_t const * p_event) +{ + app_usbd_class_inst_t const * p_inst = p_event->p_context; + app_usbd_msc_t const * p_msc = msc_get(p_inst); + app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc); + + uint32_t blk_cnt = p_msc_ctx->current.blk_count; + uint32_t blk_size = p_msc_ctx->current.blk_size; + + /*Save actual request*/ + size_t req_pos = (p_event->p_blk_req->p_buff == p_msc->specific.inst.p_block_buff) ? 0 : 1; + p_msc_ctx->current.req = *p_event->p_blk_req; + + APP_USBD_MSC_REQ_BUSY_CLR(p_msc_ctx->current.req_busy_mask, req_pos); + p_msc_ctx->current.block_req_in_progress = false; + + p_msc_ctx->current.blk_idx += blk_cnt; + + if (p_msc_ctx->current.blk_datasize > blk_size * blk_cnt) + { + p_msc_ctx->current.blk_datasize -= blk_size * blk_cnt; + } + else + { + p_msc_ctx->current.blk_datasize = 0; + } + + NRF_LOG_DEBUG("write_done_handler: p_buff: %p, size: %u data size: %u req_pos: %u\r\n", + (uint32_t)p_event->p_blk_req->p_buff, + p_event->p_blk_req->blk_count, + p_msc_ctx->current.blk_datasize, + req_pos); + + if (p_msc_ctx->current.blk_datasize == 0) + { + p_msc_ctx ->current.blk_idx = p_msc_ctx ->current.blk_size = 0; + UNUSED_RETURN_VALUE(csw_wait_start(p_inst, p_msc_ctx->current.csw_status)); + return; + } + + if (p_msc_ctx->current.blk_datasize <= p_msc_ctx->current.blk_count * blk_size) + { + size_t pos = p_msc_ctx->current.workbuff_pos;; + if (p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK) + { + pos ^= p_msc->specific.inst.block_buff_size; + } + + NRF_BLOCK_DEV_REQUEST(req, + p_msc_ctx->current.blk_idx, + p_msc_ctx->current.blk_count, + ((uint8_t *)p_msc->specific.inst.p_block_buff + pos)); + + NRF_LOG_DEBUG("nrf_blk_dev_write_req 2: id: %u, count: %u, left: %u, ptr: %p\r\n", + req.blk_id, + req.blk_count, + p_msc_ctx->current.blk_datasize, + (uint32_t)req.p_buff); + + p_msc_ctx->current.block_req_in_progress = true; + ret_code_t ret = nrf_blk_dev_write_req(p_blk_dev, &req); + NRF_LOG_DEBUG("nrf_blk_dev_write_req 2: ret: %u\r\n", ret); + + if (ret != NRF_SUCCESS) + { + UNUSED_RETURN_VALUE(unsupported_start(p_inst)); + } + + return; + } + + if (!p_msc_ctx->current.trans_in_progress && + (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_count * blk_size)) + { + size_t size = p_msc_ctx->current.blk_datasize - p_msc_ctx->current.blk_count * blk_size; + if (size > p_msc_ctx->current.blk_count * blk_size) + { + size = p_msc_ctx->current.blk_count * blk_size; + } + + if (size > 0) + { + /*Trigger new transfer.*/ + p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx); + ret_code_t ret = transfer_out_start(p_inst, + ((uint8_t *)p_msc->specific.inst.p_block_buff + + p_msc_ctx->current.workbuff_pos), + size, + APP_USBD_MSC_STATE_DATA_OUT); + if (ret == NRF_SUCCESS) + { + p_msc_ctx->current.trans_req_id ^= 1; + APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, + p_msc_ctx->current.trans_req_id); + p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size; + p_msc_ctx->current.trans_in_progress = true; + } + else + { + UNUSED_RETURN_VALUE(unsupported_start(p_inst)); + } + } + } +} + + +/** + * @brief Block device event handler. + * + * Mass storage block device event handler. Need to be pined to all block devices + * from initializer list. + * + * @param p_blk_dev Block device handle + * @param p_event Block device event + * + * */ +static void msc_blockdev_ev_handler(nrf_block_dev_t const * p_blk_dev, + nrf_block_dev_event_t const * p_event) +{ + switch (p_event->ev_type) { + case NRF_BLOCK_DEV_EVT_INIT: + break; + case NRF_BLOCK_DEV_EVT_UNINIT: + break; + case NRF_BLOCK_DEV_EVT_BLK_READ_DONE: + CRITICAL_REGION_ENTER(); + msc_blockdev_read_done_handler(p_blk_dev, p_event); + CRITICAL_REGION_EXIT(); + break; + case NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE: + CRITICAL_REGION_ENTER(); + msc_blockdev_write_done_handler(p_blk_dev, p_event); + CRITICAL_REGION_EXIT(); + break; + default: + break; + } +} + +/** @} */ + +#endif // APP_USBD_CLASS_MSC_ENABLED diff --git a/components/libraries/usbd/class/msc/app_usbd_msc.h b/components/libraries/usbd/class/msc/app_usbd_msc.h new file mode 100644 index 0000000..075fe35 --- /dev/null +++ b/components/libraries/usbd/class/msc/app_usbd_msc.h @@ -0,0 +1,187 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_MSC_H__ +#define APP_USBD_MSC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "nrf_drv_usbd.h" +#include "nrf_block_dev.h" +#include "app_usbd_class_base.h" +#include "app_usbd.h" +#include "app_usbd_core.h" +#include "app_usbd_descriptor.h" + +#include "app_usbd_msc_types.h" +#include "app_usbd_msc_desc.h" +#include "app_usbd_msc_scsi.h" +#include "app_usbd_msc_internal.h" + + +/** + * @defgroup app_usbd_msc USB MSC class + * @ingroup app_usbd + * + * @brief @tagAPI52840 Module with types, definitions, and API used by the USB MSC class. + * + * @details References: + * - "Universal Serial Bus Mass Storage Class, Specification Overview," + * Revision 1.2, USB Implementer's Forum, June 23, 2003. + * - "Universal Serial Bus Mass Storage Class, Bulk-Only Transport," + * Revision 1.0, USB Implementer's Forum, September 31, 1999. + * + * @{ + */ + +#ifdef DOXYGEN +/** + * @brief Mass storage class instance type + * + * @ref APP_USBD_CLASS_TYPEDEF + */ +typedef struct { } app_usbd_msc_t; +#else +/*lint -save -e10 -e26 -e123 -e505 */ +APP_USBD_CLASS_TYPEDEF(app_usbd_msc, \ + APP_USBD_MSC_CONFIG(0, (NRF_DRV_USBD_EPIN1, NRF_DRV_USBD_EPOUT1)), \ + APP_USBD_MSC_INSTANCE_SPECIFIC_DEC, \ + APP_USBD_MSC_DATA_SPECIFIC_DEC \ +); +#endif + +/*lint -restore*/ + + +/*lint -save -e407 */ + +/** + * @brief Events passed to user event handler + * + * @note Example prototype of user event handler: + * + * void msc_user_ev_handler(app_usbd_class_inst_t const * p_inst, + * app_usbd_msc_user_event_t event); + */ +typedef enum app_usbd_msc_user_event_e { + APP_USBD_MSC_USER_EVT_SUSPEND = 0, /**< User event SUSPEND (bus state notification) */ + APP_USBD_MSC_USER_EVT_RESUME, /**< User event RESUME (bus state notification) */ + APP_USBD_MSC_USER_EVT_START, /**< User event START (cable connect) */ + APP_USBD_MSC_USER_EVT_STOP, /**< User event STOP (cable disconnect) */ +} app_usbd_msc_user_event_t; + +/*lint -restore*/ + +/** + * @brief Helper macro for defining MSC endpoints + * + * @param in_number Input endpoint number + * @param out_number Output endpoint number + * */ +#define APP_USBD_MSC_ENDPOINT_LIST(in_number, out_number) ( \ + CONCAT_2(NRF_DRV_USBD_EPIN, in_number), \ + CONCAT_2(NRF_DRV_USBD_EPOUT, out_number) \ +) + +/** + * @brief Global definition of app_usbd_msc_t class + * + * @param instance_name Name of global instance + * @param interface_number Unique interface number + * @param user_ev_handler User event handler (optional) + * @param endpoint_list Input endpoint list (@ref nrf_drv_usbd_ep_t) + * @param blockdev_list Block device list + * @param workbuffer_size Work buffer size (need to fit into all block devices from + * block device list) + * + * @note This macro is just simplified version of @ref APP_USBD_MSC_GLOBAL_DEF_INTERNAL + * + */ +#define APP_USBD_MSC_GLOBAL_DEF(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + blockdev_list, \ + workbuffer_size) \ + APP_USBD_MSC_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + blockdev_list, \ + workbuffer_size) + + +/** + * @@brief Helper function to get class instance from MSC + * + * @param[in] p_msc MSC instance (declared by @ref APP_USBD_MSC_GLOBAL_DEF) + * + * @return Base class instance + */ +static inline app_usbd_class_inst_t const * +app_usbd_msc_class_inst_get(app_usbd_msc_t const * p_msc) +{ + return &p_msc->base; +} + +/** + * @brief Helper function to get MSC from base class instance + * + * @param[in] p_inst Base class instance + * + * @return MSC class handle + */ +static inline app_usbd_msc_t const * app_usbd_msc_class_get(app_usbd_class_inst_t const * p_inst) +{ + return (app_usbd_msc_t const *)p_inst; +} + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_MSC_H__ */ diff --git a/components/libraries/usbd/class/msc/app_usbd_msc_desc.h b/components/libraries/usbd/class/msc/app_usbd_msc_desc.h new file mode 100644 index 0000000..4ca1057 --- /dev/null +++ b/components/libraries/usbd/class/msc/app_usbd_msc_desc.h @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_MSC_DESC_H__ +#define APP_USBD_MSC_DESC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_usbd_descriptor.h" + +/** + * @defgroup app_usbd_msc_desc USB MSC descriptors + * @ingroup app_usbd_msc + * + * @brief @tagAPI52840 Descriptors for the USB MSC class. + * @{ + */ + +/** + * @brief Initializer of interface descriptor for MSC class + * + * @param interface_number Interface number + * @param subclass Subclass, @ref app_usbd_msc_subclass_t + * @param protocol Protocol, @ref app_usbd_msc_protocol_t + * */ +#define APP_USBD_MSC_INTERFACE_DSC(interface_number, subclass, protocol) \ + /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \ + /*.bInterfaceNumber = */ interface_number, \ + /*.bAlternateSetting = */ 0x00, \ + /*.bNumEndpoints = */ 2, \ + /*.bInterfaceClass = */ APP_USBD_MSC_CLASS, \ + /*.bInterfaceSubClass = */ subclass, \ + /*.bInterfaceProtocol = */ protocol, \ + /*.iInterface = 0, */ 0x00, \ + + +/** + * @brief Initializer of endpoint descriptors for MSC class + * + * @param endpoint_in IN endpoint + * @param endpoint_out OUT endpoint + * @param ep_size Endpoint size + * */ +#define APP_USBD_MSC_EP_DSC(endpoint_in, endpoint_out, ep_size) \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint_in, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ 0, \ + /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \ + /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \ + /*.bEndpointAddress = */ endpoint_out, \ + /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \ + /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \ + /*.bInterval = */ 0, \ + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_MSC_DESC_H__ */ diff --git a/components/libraries/usbd/class/msc/app_usbd_msc_internal.h b/components/libraries/usbd/class/msc/app_usbd_msc_internal.h new file mode 100644 index 0000000..ddaae8e --- /dev/null +++ b/components/libraries/usbd/class/msc/app_usbd_msc_internal.h @@ -0,0 +1,260 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_MSC_INTERNAL_H__ +#define APP_USBD_MSC_INTERNAL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup app_usbd_msc_internals USB MSC internals + * @ingroup app_usbd_msc + * + * @brief @tagAPI52840 Internals of the USB MSC class. + * @{ + */ + +/** + * @brief Minimal serial string descriptor length + * */ +#define APP_USBD_MSC_MINIMAL_SERIAL_STRING_SIZE (12 + 1) + +/** + * @brief Forward declaration of Mass Storage Class type + * + */ +APP_USBD_CLASS_FORWARD(app_usbd_msc); + +/*lint -save -e165*/ +/** + * @brief Forward declaration of @ref app_usbd_msc_user_event_e + * + */ +enum app_usbd_msc_user_event_e; + +/*lint -restore*/ + +/** + * @brief User event handler + * + * @param[in] p_inst Class instance + * @param[in] event User event + * + * */ +typedef void (*app_usbd_msc_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst, + enum app_usbd_msc_user_event_e event); + +/** + * @brief MSC part of class instance data + */ +typedef struct { + uint8_t const * p_raw_desc; //!< MSC descriptors + size_t raw_desc_size; //!< MSC descriptors size + void * p_block_buff; //!< Block buffer + size_t block_buff_size; //!< Block buffer size (typically 512 bytes) + + nrf_block_dev_t const ** pp_block_devs; //!< Block devices list + size_t block_devs_count; //!< Block device list size + + app_usbd_msc_user_ev_handler_t user_ev_handler; //!< User event handler +} app_usbd_msc_inst_t; + +/** + * @brief Internal module state + */ +typedef enum { + APP_USBD_MSC_STATE_DISABLED, /**< Internal module state DISABLED */ + APP_USBD_MSC_STATE_IDLE, /**< Internal module state IDLE */ + APP_USBD_MSC_STATE_CBW, /**< Internal module state CBW */ + APP_USBD_MSC_STATE_CMD_IN, /**< Internal module state CMD_IN */ + APP_USBD_MSC_STATE_CMD_OUT, /**< Internal module state CMD_OUT */ + APP_USBD_MSC_STATE_DATA_IN, /**< Internal module state DATA_IN */ + APP_USBD_MSC_STATE_DATA_OUT, /**< Internal module state DATA_OUT */ + APP_USBD_MSC_STATE_DATA_OUT_WAIT, /**< Internal module state DATA_OUT_WAIT */ + APP_USBD_MSC_STATE_CSW, /**< Internal module state CSW */ + APP_USBD_MSC_STATE_UNSUPPORTED, /**< Internal module state UNSUPPORTED */ +} app_usbd_msc_state_t; + +/** + * @brief MSC context + * + * */ +typedef struct { + app_usbd_msc_cbw_t cbw; //!< SCSI command block wrapper + app_usbd_msc_csw_t csw; //!< SCSI Command status wrapper + + app_usbd_msc_state_t state; //!< Internal module state + + struct { + uint8_t lun; //!< Current transfer blocks: logical unit + uint8_t csw_status; //!< Current CSW status + uint32_t blk_idx; //!< Current transfer: block index + uint32_t blk_datasize; //!< Current transfer: data size to transfer + uint32_t blk_size; //!< Current transfer: block size + uint32_t blk_count; //!< Current transfer: block count + uint32_t residue; //!< @ref app_usbd_msc_csw_t::residue + + bool trans_in_progress; //!< Transfer in progress flag + bool block_req_in_progress; //!< Block request in progress flag + size_t workbuff_pos; //!< Current buffer offset (double buffering mode) + uint8_t req_busy_mask; //!< Request bust mask (double buffering mode) + uint8_t trans_req_id; //!< Current transfered request (double buffering mode) + + nrf_block_req_t req; //!< Last processed block req (double buffering mode) + } current; + + size_t resp_len; //!< Response length + + /*SCSI response container*/ + union { + app_usbd_scsi_cmd_inquiry_resp_t inquiry; //!< @ref APP_USBD_SCSI_CMD_INQUIRY response + app_usbd_scsi_cmd_requestsense_resp_t requestsense; //!< @ref APP_USBD_SCSI_CMD_REQUESTSENSE response + app_usbd_scsi_cmd_readcapacity10_resp_t readcapacity10; //!< @ref APP_USBD_SCSI_CMD_READCAPACITY10 response + app_usbd_scsi_cmd_modesense6_resp_t modesense6; //!< @ref APP_USBD_SCSI_CMD_MODESENSE6 response + app_usbd_scsi_cmd_modesense10_resp_t modesense10; //!< @ref APP_USBD_SCSI_CMD_MODESENSE10 response + } scsi_resp; + + uint16_t blk_dev_init_mask; //!< Block devices init mask +} app_usbd_msc_ctx_t; + + +/** + * @brief MSC configuration macro + * + * Used by @ref APP_USBD_MSC_GLOBAL_DEF + * + * @param iface Interface number + * @param endpoints Endpoint list + * */ +#define APP_USBD_MSC_CONFIG(iface, endpoints) ((iface, BRACKET_EXTRACT(endpoints))) + + +/** + * @brief Specific class constant data for MSC + * + * @ref app_usbd_msc_inst_t + */ +#define APP_USBD_MSC_INSTANCE_SPECIFIC_DEC app_usbd_msc_inst_t inst; + + +/** + * @brief Configures MSC instance + * + * @param descriptors Mass storage class descriptors (raw table) + * @param block_devs Block devices list + * @param block_buff Block buffer + * @param user_event_handler User event handler + */ +#define APP_USBD_MSC_INST_CONFIG(descriptors, block_devs, block_buff, user_event_handler) \ + .inst = { \ + .p_raw_desc = descriptors, \ + .raw_desc_size = sizeof(descriptors), \ + .pp_block_devs = block_devs, \ + .block_devs_count = ARRAY_SIZE(block_devs), \ + .p_block_buff = block_buff, \ + .block_buff_size = sizeof(block_buff) / 2, \ + .user_ev_handler = user_event_handler, \ + } + +/** + * @brief Specific class data for MSC + * + * @ref app_usbd_msc_ctx_t + * */ +#define APP_USBD_MSC_DATA_SPECIFIC_DEC app_usbd_msc_ctx_t ctx; + + +/** + * @brief MSC descriptors config macro + * + * @param interface_number Interface number + * @param ... Extracted endpoint list + * */ +#define APP_USBD_MSC_DSC_CONFIG(interface_number, ...) { \ + APP_USBD_MSC_INTERFACE_DSC(interface_number, \ + APP_USBD_MSC_SUBCLASS_TRANSPARENT, \ + APP_USBD_MSC_PROTOCOL_BULK) \ + APP_USBD_MSC_EP_DSC(GET_VA_ARG_1(__VA_ARGS__), \ + GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__)), \ + 64) \ +} + +/** + * @brief Public MSC class interface + * + * */ +extern const app_usbd_class_methods_t app_usbd_msc_class_methods; + +/** + * @brief Global definition of mass storage class instance + */ +#define APP_USBD_MSC_GLOBAL_DEF_INTERNAL(instance_name, \ + interface_number, \ + user_ev_handler, \ + endpoint_list, \ + blockdev_list, \ + workbuffer_size) \ + static const uint8_t CONCAT_2(instance_name, _dsc)[] = \ + APP_USBD_MSC_DSC_CONFIG(interface_number, BRACKET_EXTRACT(endpoint_list)); \ + static const nrf_block_dev_t * CONCAT_2(instance_name, _blkdevs)[] = \ + { BRACKET_EXTRACT(blockdev_list) }; \ + static uint32_t CONCAT_2(instance_name, _block)[2 *(workbuffer_size) / sizeof(uint32_t)]; \ + APP_USBD_CLASS_INST_GLOBAL_DEF( \ + instance_name, \ + app_usbd_msc, \ + &app_usbd_msc_class_methods, \ + APP_USBD_MSC_CONFIG(interface_number, endpoint_list), \ + (APP_USBD_MSC_INST_CONFIG(CONCAT_2(instance_name, _dsc), \ + CONCAT_2(instance_name, _blkdevs), \ + CONCAT_2(instance_name, _block), \ + user_ev_handler)) \ + ) + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_MSC_INTERNAL_H__ */ diff --git a/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h b/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h new file mode 100644 index 0000000..fd7e63d --- /dev/null +++ b/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h @@ -0,0 +1,330 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_MSC_SCSI_H__ +#define APP_USBD_MSC_SCSI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_util.h" + +/** + * @defgroup app_usbd_msc_scsi USB MSC SCSI data structures + * @ingroup app_usbd_msc + * + * @brief @tagAPI52840 USB MSC SCSI data structures. + * + * @details Reference specifications: + * - "Reduced Block Commands (Revision 10a)" American National Standard + * for Information Technology, August 18, 1999 + * - "SCSI Primary Commands - 4 (SPC-4)," American National Standard + * for Information Technology, July 19, 2008 + * - "SCSI Block Commands -2 (SBC-2)," American National Standard + * for Information Technology, November 13, 2004 + * - NuttX source code - Real-time Operating System: http://nuttx.org/ + * Gregory Nutt + * + * @{ + */ + +/** + * @brief SCSI command set + * + * Mandatory (and some optional) commands required by SBC-2. + * + */ +typedef enum { + APP_USBD_SCSI_CMD_TESTUNITREADY = 0x00, /**< TESTUNITREADY */ + APP_USBD_SCSI_CMD_REQUESTSENSE = 0x03, /**< REQUESTSENSE */ + APP_USBD_SCSI_CMD_FORMAT_UNIT = 0x04, /**< FORMAT_UNIT */ + APP_USBD_SCSI_CMD_READ6 = 0x08, /**< READ6 */ + APP_USBD_SCSI_CMD_WRITE6 = 0x0a, /**< WRITE6 */ + APP_USBD_SCSI_CMD_INQUIRY = 0x12, /**< INQUIRY */ + APP_USBD_SCSI_CMD_MODESELECT6 = 0x15, /**< MODESELECT6 */ + APP_USBD_SCSI_CMD_MODESENSE6 = 0x1a, /**< MODESENSE6 */ + APP_USBD_SCSI_CMD_STARTSTOPUNIT = 0x1b, /**< STARTSTOPUNIT */ + APP_USBD_SCSI_CMD_SENDDIAGNOSTIC = 0x1d, /**< SENDDIAGNOSTIC */ + APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL = 0x1e, /**< PREVENTMEDIAREMOVAL */ + APP_USBD_SCSI_CMD_READCAPACITY10 = 0x25, /**< READCAPACITY10 */ + APP_USBD_SCSI_CMD_READ10 = 0x28, /**< READ10 */ + APP_USBD_SCSI_CMD_WRITE10 = 0x2a, /**< WRITE10 */ + APP_USBD_SCSI_CMD_MODESELECT10 = 0x55, /**< MODESELECT10 */ + APP_USBD_SCSI_CMD_MODESENSE10 = 0x5a, /**< MODESENSE10 */ +} app_usbd_scsi_cmd_t; + + +#pragma pack(push, 1) + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_REQUESTSENSE command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_REQUESTSENSE + uint8_t flags; //!< Flags + uint8_t reserved[2]; //!< Reserved + uint8_t alloclen; //!< Allocation length + uint8_t control; //!< Control +} app_usbd_scsi_cmd_requestsense_t; + +#define APP_USBD_SCSI_CMD_REQSENSE_CODE_VALID 0x80 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */ +#define APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENT 0x70 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */ +#define APP_USBD_SCSI_CMD_REQSENSE_CODE_DEFERRED 0x71 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */ +#define APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENTDESC 0x72 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */ +#define APP_USBD_SCSI_CMD_REQSENSE_CODE_DEFERREDDESC 0x73 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */ + +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_FILEMARK 0x80 /**< Bits 7 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_EOM 0x40 /**< Bits 6 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ILI 0x20 /**< Bits 5 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_RESERVED 0x10 /**< Bits 4 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ + +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_NOSENSE 0x00 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_RECOVEREDERROR 0x01 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_NOTREADY 0x02 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_MEDIUMERROR 0x03 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_HARDWAREERROR 0x04 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ILLEGALREQUEST 0x05 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_UNITATTENTION 0x06 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_DATAPROTECT 0x07 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_BLANKCHECK 0x08 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_VENDORSPECIFIC 0x09 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ +#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ABORTEDCOMMAND 0x0b /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */ + + +#define APP_USBD_SCSI_CMD_TESTUNITREADY_LEN 6 /**< @ref APP_USBD_SCSI_CMD_TESTUNITREADY command length*/ + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_REQUESTSENSE response + */ +typedef struct { + uint8_t code; //!< Response code: APP_USBD_SCSI_CMD_REQSENSE_CODE_* + uint8_t obsolete; //!< Obsolete + uint8_t flags; //!< APP_USBD_SCSI_CMD_REQSENSE_FLAG_* + uint8_t info[4]; //!< Information + uint8_t len; //!< Additional length + uint8_t cmdinfo[4]; //!< Command-specific information + uint8_t code2; //!< Additional sense code + uint8_t qual2; //!< Additional sense code qualifier + uint8_t fru; //!< Field replacement unit code + uint8_t key[3]; //!< Sense key specific +} app_usbd_scsi_cmd_requestsense_resp_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_INQUIRY command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_INQUIRY + uint8_t flags; //!< Command flags + uint8_t pagecode; //!< Page code + uint8_t alloclen[2]; //!< Allocation length + uint8_t control; //!< Control +} app_usbd_scsi_cmd_inquiry_t; + +#define APP_USBD_MSC_SCSI_INQ_QUAL_CONNECTED 0x00 /**< Peripheral connected */ +#define APP_USBD_MSC_SCSI_INQ_QUAL_NOT_CONN 0x20 /**< Peripheral not connected */ +#define APP_USBD_MSC_SCSI_INQ_QUAL_NOT_SUPP 0x60 /**< Peripheral not supported */ + +#define APP_USBD_MSC_SCSI_INQ_TYPE_DIR_ACCESS 0x00 /**< Direct Access (SBC) */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_SEQ_ACCESS 0x01 /**< Sequential Access */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_PRINTER 0x02 /**< Printer */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_PROCESSOR 0x03 /**< Processor device */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_WRITE_ONCE 0x04 /**< Write-once device */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_CD_DVD 0x05 /**< CD/DVD device */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_OPTICAL 0x07 /**< Optical Memory */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_MC 0x08 /**< Medium Changer */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_ARRAY 0x0c /**< Storage Array Controller */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_ENCLOSURE 0x0d /**< Enclosure Services */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_RBC 0x0e /**< Simplified Direct Access */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_OCRW 0x0f /**< Optical card reader/writer */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_BCC 0x10 /**< Bridge Controller Commands */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_OSD 0x11 /**< Object-based Storage */ +#define APP_USBD_MSC_SCSI_INQ_TYPE_NONE 0x1f /**< No Peripheral */ + + +#define APP_USBD_MSC_SCSI_INQ_FLAG1_RMB 0x80 /**< Removable Medium */ + +#define APP_USBD_SCSI_INQ_VER_NONE 0x00 /**< No standards conformance */ +#define APP_USBD_SCSI_INQ_VER_SPC 0x03 /**< SCSI Primary Commands (link to SBC) */ +#define APP_USBD_SCSI_INQ_VER_SPC2 0x04 /**< SCSI Primary Commands - 2 (link to SBC-2)*/ +#define APP_USBD_SCSI_INQ_VER_SPC3 0x05 /**< SCSI Primary Commands - 3 (link to SBC-2)*/ +#define APP_USBD_SCSI_INQ_VER_SPC4 0x06 /**< SCSI Primary Commands - 4 (link to SBC-3)*/ + +#define APP_USBD_MSC_SCSI_INQ_FLAG2_NORMACA 0x20 /**< Normal ACA Supported */ +#define APP_USBD_MSC_SCSI_INQ_FLAG2_HISUP 0x10 /**< Hierarchal LUN addressing */ +#define APP_USBD_MSC_SCSI_INQ_FLAG2_RSP_SPC2 0x02 /**< SPC-2 / SPC-3 response format*/ +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_INQUIRY response + */ +typedef struct { + uint8_t qualtype; //!< Bits 5-7: Peripheral qualifier; Bits 0-4: Peripheral device type + uint8_t flags1; //!< Flags 1 + uint8_t version; //!< Version + uint8_t flags2; //!< Flags 2 + uint8_t len; //!< Additional length + uint8_t flags3; //!< Flags 3 + uint8_t flags4; //!< Flags 4 + uint8_t flags5; //!< Flags 5 + uint8_t vendorid[8]; //!< T10 Vendor Identification + uint8_t productid[16]; //!< Product Identification + uint8_t revision[4]; //!< Product Revision Level +} app_usbd_scsi_cmd_inquiry_resp_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_READ6 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READ6 + uint8_t mslba; //!< Bits 5-7: reserved; Bits 0-6: MS Logical Block Address (LBA) + uint8_t lslba[2]; //!< LS Logical Block Address (LBA) + uint8_t xfrlen; //!< Transfer length (in contiguous logical blocks) + uint8_t control; //!< Control +} app_usbd_scsi_cmd_read6_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_WRITE6 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_WRITE6 + uint8_t mslba; //!< Bits 5-7: reserved; Bits 0-6: MS Logical Block Address (LBA) + uint8_t lslba[2]; //!< LS Logical Block Address (LBA) + uint8_t xfrlen; //!< Transfer length (in contiguous logical blocks) + uint8_t control; //!< Control +} app_usbd_scsi_cmd_write6_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE6 command + */ +typedef struct { + uint8_t opcode; //!<* @ref APP_USBD_SCSI_CMD_MODESENSE6 + uint8_t flags; //!<* Flags + uint8_t pcpgcode; //!<* Bits 6-7: PC, bits 0-5: page code + uint8_t subpgcode; //!<* subpage code + uint8_t alloclen; //!<* Allocation length + uint8_t control; //!<* Control +} app_usbd_scsi_cmd_modesense6_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE6 response + */ +typedef struct { + uint8_t mdlen; //!< Mode data length + uint8_t type; //!< Medium type + uint8_t param; //!< Device-specific parameter + uint8_t bdlen; //!< Block descriptor length +} app_usbd_scsi_cmd_modesense6_resp_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_READCAPACITY10 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READCAPACITY10 + uint8_t reserved1; //!< Reserved field + uint8_t lba[4]; //!< Logical block address (LBA) + uint8_t reserved2[2]; //!< Reserved field + uint8_t pmi; //!< Bits 1-7 Reserved; Bit 0: PMI + uint8_t control; //!< Control +} app_usbd_scsi_cmd_readcapacity10_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_READCAPACITY10 response + */ +typedef struct { + uint8_t lba[4]; //!< Returned logical block address (LBA) + uint8_t blklen[4]; //!< Logical block length (in bytes) +} app_usbd_scsi_cmd_readcapacity10_resp_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_READ10 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READ10 + uint8_t flags; //!< Command flags + uint8_t lba[4]; //!< Logical Block Address (LBA) + uint8_t groupno; //!< Bits 5-7: reserved; Bits 0-6: group number + uint8_t xfrlen[2]; //!< Transfer length (in contiguous logical blocks) + uint8_t control; //!< Control +} app_usbd_scsi_cmd_read10_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_WRITE10 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_WRITE10 + uint8_t flags; //!< Command flags + uint8_t lba[4]; //!< Logical Block Address (LBA) + uint8_t groupno; //!< Bits 5-7: reserved; Bits 0-6: group number + uint8_t xfrlen[2]; //!< Transfer length (in contiguous logical blocks) + uint8_t control; //!< Control +} app_usbd_scsi_cmd_write10_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE10 command + */ +typedef struct { + uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_MODESENSE10 + uint8_t flags; //!< Flags + uint8_t pcpgcode; //!< Bits 6-7: PC, bits 0-5: page code + uint8_t subpgcode; //!< Subpage code + uint8_t reserved[3]; //!< Reserved + uint8_t alloclen[2]; //!< Allocation length + uint8_t control; //!< Control +} app_usbd_scsi_cmd_modesense10_t; + +/** + * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE10 response + */ +typedef struct { + uint8_t mdlen[2]; //!< Mode data length + uint8_t type; //!< Medium type + uint8_t param; //!< Device-specific parameter + uint8_t reserved[2]; //!< Reserved + uint8_t bdlen[2]; //!< Block descriptor length +} app_usbd_scsi_cmd_modesense10_resp_t; + +#pragma pack(pop) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_MSC_SCSI_H__ */ diff --git a/components/libraries/usbd/class/msc/app_usbd_msc_types.h b/components/libraries/usbd/class/msc/app_usbd_msc_types.h new file mode 100644 index 0000000..c4e7358 --- /dev/null +++ b/components/libraries/usbd/class/msc/app_usbd_msc_types.h @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_MSC_TYPES_H__ +#define APP_USBD_MSC_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "app_util.h" + +/** + * @defgroup app_usbd_msc_types USB MSC types + * @ingroup app_usbd_msc + * + * @brief @tagAPI52840 Types used in the USB MSC class. + * @{ + */ + +/** @brief MSC class definition in interface descriptor + * + * @ref app_usbd_descriptor_iface_t::bInterfaceClass + * */ +#define APP_USBD_MSC_CLASS 0x08 + +/** + * @brief MSC subclass possible value + */ +typedef enum { + APP_USBD_MSC_SUBCLASS_RBC = 0x01, /**< Reduced Block Commands */ + APP_USBD_MSC_SUBCLASS_ATAPI = 0x02, /**< CD/DVD devices */ + APP_USBD_MSC_SUBCLASS_QIC_157 = 0x03, /**< Tape devices */ + APP_USBD_MSC_SUBCLASS_UFI = 0x04, /**< Floppy disk drives */ + APP_USBD_MSC_SUBCLASS_SFF_8070I = 0x05, /**< Floppy disk drives */ + APP_USBD_MSC_SUBCLASS_TRANSPARENT = 0x06, /**< Determined by INQUIRY */ +} app_usbd_msc_subclass_t; + +/** + * @brief MSC protocol possible value + * + * @note The USB Mass Storage Class Control/Bulk/Interrupt (CBI) Transport specification is approved + * for use only with full-speed floppy disk drives. CBI shall not be used in high-speed + * capable devices. + */ +typedef enum { + APP_USBD_MSC_PROTOCOL_CBI = 0x00, /**< Command/Bulk/Interrupt */ + APP_USBD_MSC_PROTOCOL_CBI_ALT = 0x01, /**< W/o command completion */ + APP_USBD_MSC_PROTOCOL_BULK = 0x50, /**< Bulk-only */ +} app_usbd_msc_protocol_t; + +/** + * @brief MSC USB requests @ref nrf_drv_usbd_setup_t::bmRequestType + * + * @note Requests are limited only to @ref APP_USBD_MSC_PROTOCOL_BULK protocol type. + */ +typedef enum { + APP_USBD_MSC_REQ_BULK_RESET = 0xFF, /**< Mass Storage Reset */ + APP_USBD_MSC_REQ_GET_MAX_LUN = 0xFE, /**< Get Max LUN */ +} app_usbd_msc_req_t; + +#pragma pack(push, 1) + +#define APP_USBD_MSC_CBW_SIGNATURE "USBC" /**< CBW signature */ +#define APP_USBD_MSC_CBW_DIRECTION_IN (1u <<7) /**< CBW direction flag */ + +/** + * @brief Command Block Wrapper (CBW) + */ +typedef struct { + uint8_t signature[4]; /**< "USBC" (hex: 0x43425355 little-endian) */ + uint8_t tag[4]; /**< Unique command tag */ + uint8_t datlen[4]; /**< Number of bytes that host expects to transfer */ + uint8_t flags; /**< Bit 7: Direction=IN */ + uint8_t lun; /**< Logical Unit Number, equals to @ref app_usbd_msc_inst_t :: block_devs_count*/ + uint8_t cdb_length; /**< Length of cdb field */ + uint8_t cdb[16]; /**< Command Data Block payload */ +} app_usbd_msc_cbw_t; + +#define APP_USBD_MSC_CSW_SIGNATURE "USBS" /**< CSW signature */ + +#define APP_USBD_MSC_CSW_STATUS_PASS 0x00 /**< CSW status: Command Passed */ +#define APP_USBD_MSC_CSW_STATUS_FAIL 0x01 /**< CSW status: Command Failed */ +#define APP_USBD_MSC_CSW_STATUS_PE 0x02 /**< CSW status: Phase Error */ + +/** + * @brief Command Status Wrapper (CSW) + */ +typedef struct { + uint8_t signature[4]; /**< "USBS" (hex: 0x53425355 little-endian) */ + uint8_t tag[4]; /**< Unique command tag (@ref app_usbd_msc_cbw_t :: tag) */ + uint8_t residue[4]; /**< Amount not transferred */ + uint8_t status; /**< Status of transfer */ +} app_usbd_msc_csw_t; + +#pragma pack(pop) + + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* APP_USBD_MSC_TYPES_H__ */ diff --git a/components/libraries/usbd/config/app_usbd_string_config.h b/components/libraries/usbd/config/app_usbd_string_config.h new file mode 100644 index 0000000..34a815f --- /dev/null +++ b/components/libraries/usbd/config/app_usbd_string_config.h @@ -0,0 +1,131 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_USBD_STRING_CONFIG_H +#define APP_USBD_STRING_CONFIG_H + +/** + * @defgroup app_usbd_string_conf USBD string configuration + * @ingroup app_usbd_string_desc + * + * @brief @tagAPI52840 Configuration of the string module that can be easily affected by the final + * user. + * @{ + */ + +/** + * @brief Supported languages identifiers + * + * Comma separated list of supported languages. + */ +#define APP_USBD_STRINGS_LANGIDS \ + ((uint16_t)APP_USBD_LANG_ENGLISH | (uint16_t)APP_USBD_SUBLANG_ENGLISH_US) + +/** + * @brief Manufacturer name string descriptor + * + * Comma separated list of manufacturer names for each defined language. + * Use @ref APP_USBD_STRING_DESC macro to create string descriptor. + * + * The order of manufacturer names has to be the same like in + * @ref APP_USBD_STRINGS_LANGIDS. + */ +#define APP_USBD_STRINGS_MANUFACTURER \ + APP_USBD_STRING_DESC('N', 'o', 'r', 'd', 'i', 'c', ' ', 'S', 'e', 'm', 'i', 'c', 'o', 'n', 'd', 'u', 'c', 't', 'o', 'r') + +/** + * @brief Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by @ref APP_USBD_STRING_DESC + * or declared as global variable. + * */ +#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0 + +/** + * @brief Product name string descriptor + * + * List of product names defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER + */ +#define APP_USBD_STRINGS_PRODUCT \ + APP_USBD_STRING_DESC('n', 'R', 'F', '5', '2', ' ', 'U', 'S', 'B', ' ', 'D', 'e', 'm', 'o') + + +/** + * @brief Define whether @ref APP_USBD_STRINGS_PRODUCT is created by @ref APP_USBD_STRING_DESC + * or declared as global variable. + * */ +#define APP_USBD_STRINGS_PRODUCT_EXTERN 0 + +/** + * @brief Serial number string descriptor + * + * Create serial number string descriptor using @ref APP_USBD_STRING_DESC, + * or configure it to point to any internal variable pointer filled with descriptor. + * + * @note + * There is only one SERIAL number inside the library and it is Language independent. + */ +#define APP_USBD_STRING_SERIAL \ + APP_USBD_STRING_DESC('0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0') + +/** + * @brief Define whether @ref APP_USBD_STRING_SERIAL is created by @ref APP_USBD_STRING_DESC + * or declared as global variable. + * */ +#define APP_USBD_STRING_SERIAL_EXTERN 0 + +/** + * @brief User strings default values + * + * This value stores all application specific user strings with its default initialization. + * The setup is done by X-macros. + * Expected macro parameters: + * @code + * X(mnemonic, [=str_idx], ...) + * @endcode + * - @c mnemonic: Mnemonic of the string descriptor that would be added to + * @ref app_usbd_string_desc_idx_t enumerator. + * - @c str_idx : String index value, may be set or left empty. + * For example WinUSB driver requires descriptor to be present on 0xEE index. + * Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...))) + * - @c ... : List of string descriptors for each defined language. + */ +#define APP_USBD_STRINGS_USER \ + X(APP_USER_1, , APP_USBD_STRING_DESC('U', 's', 'e', 'r', ' ', '1')) + +/** @} */ +#endif /* APP_USBD_STRING_CONFIG_H */ diff --git a/components/libraries/util/app_error.c b/components/libraries/util/app_error.c index 108ee88..428eba1 100644 --- a/components/libraries/util/app_error.c +++ b/components/libraries/util/app_error.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -20,18 +48,12 @@ */ #include "nrf.h" +#include #include "app_error.h" -#include "compiler_abstraction.h" #include "nordic_common.h" -#ifdef DEBUG -#include "bsp.h" - -/* global error variables - in order to prevent removal by optimizers */ -uint32_t m_error_code; -uint32_t m_line_num; -const uint8_t * m_p_file_name; -#endif - +#include "sdk_errors.h" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" /**@brief Function for error handling, which is called when an error has occurred. * * @warning This handler is an example only and does not fit a final product. You need to analyze @@ -40,48 +62,85 @@ const uint8_t * m_p_file_name; * @param[in] error_code Error code supplied to the handler. * @param[in] line_num Line number where the handler is called. * @param[in] p_file_name Pointer to the file name. - * - * Function is implemented as weak so that it can be overwritten by custom application error handler - * when needed. */ /*lint -save -e14 */ -__WEAK void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name) +void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name) +{ + error_info_t error_info = + { + .line_num = line_num, + .p_file_name = p_file_name, + .err_code = error_code, + }; + app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info)); + + UNUSED_VARIABLE(error_info); +} + +/*lint -save -e14 */ +void app_error_handler_bare(ret_code_t error_code) { - // On assert, the system can only recover with a reset. -#ifndef DEBUG - NVIC_SystemReset(); -#else - -#ifdef BSP_DEFINES_ONLY - LEDS_ON(LEDS_MASK); -#else -// UNUSED_VARIABLE(bsp_indication_set(BSP_INDICATE_FATAL_ERROR)); - // This call can be used for debug purposes during application development. - // @note CAUTION: Activating this code will write the stack to flash on an error. - // This function should NOT be used in a final product. - // It is intended STRICTLY for development/debugging purposes. - // The flash write will happen EVEN if the radio is active, thus interrupting - // any communication. - // Use with care. Uncomment the line below to use. - //ble_debug_assert_handler(error_code, line_num, p_file_name); -#endif // BSP_DEFINES_ONLY + error_info_t error_info = + { + .line_num = 0, + .p_file_name = NULL, + .err_code = error_code, + }; + + app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info)); + + UNUSED_VARIABLE(error_info); +} + + +void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info) +{ + /* static error variables - in order to prevent removal by optimizers */ + static volatile struct + { + uint32_t fault_id; + uint32_t pc; + uint32_t error_info; + assert_info_t * p_assert_info; + error_info_t * p_error_info; + ret_code_t err_code; + uint32_t line_num; + const uint8_t * p_file_name; + } m_error_data = {0}; // The following variable helps Keil keep the call stack visible, in addition, it can be set to // 0 in the debugger to continue executing code after the error check. volatile bool loop = true; UNUSED_VARIABLE(loop); - m_error_code = error_code; - m_line_num = line_num; - m_p_file_name = p_file_name; + m_error_data.fault_id = id; + m_error_data.pc = pc; + m_error_data.error_info = info; + + switch (id) + { + case NRF_FAULT_ID_SDK_ASSERT: + m_error_data.p_assert_info = (assert_info_t *)info; + m_error_data.line_num = m_error_data.p_assert_info->line_num; + m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name; + break; + + case NRF_FAULT_ID_SDK_ERROR: + m_error_data.p_error_info = (error_info_t *)info; + m_error_data.err_code = m_error_data.p_error_info->err_code; + m_error_data.line_num = m_error_data.p_error_info->line_num; + m_error_data.p_file_name = m_error_data.p_error_info->p_file_name; + break; + } - UNUSED_VARIABLE(m_error_code); - UNUSED_VARIABLE(m_line_num); - UNUSED_VARIABLE(m_p_file_name); + UNUSED_VARIABLE(m_error_data); + + // If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger. __disable_irq(); + while (loop); - while(loop); -#endif // DEBUG + __enable_irq(); } + /*lint -restore */ diff --git a/components/libraries/util/app_error.h b/components/libraries/util/app_error.h index 616634c..7b282a0 100644 --- a/components/libraries/util/app_error.h +++ b/components/libraries/util/app_error.h @@ -1,15 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * * @defgroup app_error Common application error handler @@ -23,38 +51,161 @@ #define APP_ERROR_H__ #include +#include #include -#include "nrf_error.h" +#include "nrf.h" +#include "sdk_errors.h" +#include "nordic_common.h" +#include "app_error_weak.h" +#ifdef ANT_STACK_SUPPORT_REQD +#include "ant_error.h" +#endif // ANT_STACK_SUPPORT_REQD + +#ifdef __cplusplus +extern "C" { +#endif -/**@brief Function for error handling, which is called when an error has occurred. +#define NRF_FAULT_ID_SDK_RANGE_START 0x00004000 /**< The start of the range of error IDs defined in the SDK. */ + +/**@defgroup APP_ERROR_FAULT_IDS Fault ID types + * @{ */ +#define NRF_FAULT_ID_SDK_ERROR NRF_FAULT_ID_SDK_RANGE_START + 1 /**< An error stemming from a call to @ref APP_ERROR_CHECK or @ref APP_ERROR_CHECK_BOOL. The info parameter is a pointer to an @ref error_info_t variable. */ +#define NRF_FAULT_ID_SDK_ASSERT NRF_FAULT_ID_SDK_RANGE_START + 2 /**< An error stemming from a call to ASSERT (nrf_assert.h). The info parameter is a pointer to an @ref assert_info_t variable. */ +/**@} */ + +/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ERROR. + */ +typedef struct +{ + uint16_t line_num; /**< The line number where the error occurred. */ + uint8_t const * p_file_name; /**< The file in which the error occurred. */ + uint32_t err_code; /**< The error code representing the error that occurred. */ +} error_info_t; + +/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ASSERT. + */ +typedef struct +{ + uint16_t line_num; /**< The line number where the error occurred. */ + uint8_t const * p_file_name; /**< The file in which the error occurred. */ +} assert_info_t; + +/**@brief Function for error handling, which is called when an error has occurred. * * @param[in] error_code Error code supplied to the handler. * @param[in] line_num Line number where the handler is called. - * @param[in] p_file_name Pointer to the file name. + * @param[in] p_file_name Pointer to the file name. */ void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name); -/**@brief Macro for calling error handler function. +/**@brief Function for error handling, which is called when an error has occurred. + * + * @param[in] error_code Error code supplied to the handler. + */ +void app_error_handler_bare(ret_code_t error_code); + +/**@brief Function for saving the parameters and entering an eternal loop, for debug purposes. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + */ +void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info); + +/**@brief Function for printing all error info (using nrf_log). + * + * @details Nrf_log library must be initialized using NRF_LOG_INIT macro before calling + * this function. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + */ +static __INLINE void app_error_log(uint32_t id, uint32_t pc, uint32_t info) +{ + switch (id) + { + case NRF_FAULT_ID_SDK_ASSERT: + //NRF_LOG_INFO(NRF_LOG_COLOR_RED "\r\n*** ASSERTION FAILED ***\r\n"); + if (((assert_info_t *)(info))->p_file_name) + { + // NRF_LOG_INFO(NRF_LOG_COLOR_WHITE "Line Number: %u\r\n", (unsigned int) ((assert_info_t *)(info))->line_num); + //NRF_LOG_INFO("File Name: %s\r\n", ((assert_info_t *)(info))->p_file_name); + } + //NRF_LOG_INFO(NRF_LOG_COLOR_DEFAULT "\r\n"); + break; + + case NRF_FAULT_ID_SDK_ERROR: + //NRF_LOG_INFO(NRF_LOG_COLOR_RED "\r\n*** APPLICATION ERROR *** \r\n" NRF_LOG_COLOR_WHITE); + if (((error_info_t *)(info))->p_file_name) + { + //NRF_LOG_INFO("Line Number: %u\r\n", (unsigned int) ((error_info_t *)(info))->line_num); + //NRF_LOG_INFO("File Name: %s\r\n", ((error_info_t *)(info))->p_file_name); + } + //NRF_LOG_INFO("Error Code: 0x%X\r\n" NRF_LOG_COLOR_DEFAULT "\r\n", (unsigned int) ((error_info_t *)(info))->err_code); + break; + } +} + +/**@brief Function for printing all error info (using printf). + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. + */ +//lint -save -e438 +static __INLINE void app_error_print(uint32_t id, uint32_t pc, uint32_t info) +{ + unsigned int tmp = id; + printf("app_error_print():\r\n"); + printf("Fault identifier: 0x%X\r\n", tmp); + printf("Program counter: 0x%X\r\n", tmp = pc); + printf("Fault information: 0x%X\r\n", tmp = info); + + switch (id) + { + case NRF_FAULT_ID_SDK_ASSERT: + printf("Line Number: %u\r\n", tmp = ((assert_info_t *)(info))->line_num); + printf("File Name: %s\r\n", ((assert_info_t *)(info))->p_file_name); + break; + + case NRF_FAULT_ID_SDK_ERROR: + printf("Line Number: %u\r\n", tmp = ((error_info_t *)(info))->line_num); + printf("File Name: %s\r\n", ((error_info_t *)(info))->p_file_name); + printf("Error Code: 0x%X\r\n", tmp = ((error_info_t *)(info))->err_code); + break; + } +} +//lint -restore + + +/**@brief Macro for calling error handler function. * * @param[in] ERR_CODE Error code supplied to the error handler. */ #ifdef DEBUG -#define APP_ERROR_HANDLER(ERR_CODE) \ - do \ - { \ +#define APP_ERROR_HANDLER(ERR_CODE) \ + do \ + { \ app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \ } while (0) #else -#define APP_ERROR_HANDLER(ERR_CODE) \ - do \ - { \ - app_error_handler((ERR_CODE), 0, 0); \ +#define APP_ERROR_HANDLER(ERR_CODE) \ + do \ + { \ + app_error_handler_bare((ERR_CODE)); \ } while (0) #endif -/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS. +/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS. * * @param[in] ERR_CODE Error code supplied to the error handler. - */ + */ #define APP_ERROR_CHECK(ERR_CODE) \ do \ { \ @@ -63,9 +214,9 @@ void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p { \ APP_ERROR_HANDLER(LOCAL_ERR_CODE); \ } \ - } while (0) - -/**@brief Macro for calling error handler function if supplied boolean value is false. + } while (0) + +/**@brief Macro for calling error handler function if supplied boolean value is false. * * @param[in] BOOLEAN_VALUE Boolean value to be evaluated. */ @@ -77,7 +228,12 @@ void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p { \ APP_ERROR_HANDLER(0); \ } \ - } while (0) + } while (0) + + +#ifdef __cplusplus +} +#endif #endif // APP_ERROR_H__ diff --git a/components/libraries/util/app_error_weak.c b/components/libraries/util/app_error_weak.c new file mode 100644 index 0000000..9a81ffa --- /dev/null +++ b/components/libraries/util/app_error_weak.c @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "app_error.h" + +#define NRF_LOG_MODULE_NAME "APP_ERROR" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +/*lint -save -e14 */ + +/** + * Function is implemented as weak so that it can be overwritten by custom application error handler + * when needed. + */ +__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) +{ + NRF_LOG_ERROR("Fatal\r\n"); + NRF_LOG_FINAL_FLUSH(); + // On assert, the system can only recover with a reset. +#ifndef DEBUG + NVIC_SystemReset(); +#else + app_error_save_and_stop(id, pc, info); +#endif // DEBUG +} + +/*lint -restore */ + + diff --git a/components/libraries/util/app_error_weak.h b/components/libraries/util/app_error_weak.h new file mode 100644 index 0000000..44c7c0e --- /dev/null +++ b/components/libraries/util/app_error_weak.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_ERROR_WEAK_H__ +#define APP_ERROR_WEAK_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @file + * + * @defgroup app_error Common application error handler + * @{ + * @ingroup app_common + * + * @brief Common application error handler. + */ + +/**@brief Callback function for errors, asserts, and faults. + * + * @details This function is called every time an error is raised in app_error, nrf_assert, or + * in the SoftDevice. Information about the error can be found in the @p info + * parameter. + * + * See also @ref nrf_fault_handler_t for more details. + * + * @note The function is implemented as weak so that it can be redefined by a custom error + * handler when needed. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if + * unavailable. + * @param[in] info Optional additional information regarding the fault. The value of the @p id + * parameter dictates how to interpret this parameter. Refer to the documentation + * for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for + * details about interpreting @p info. + */ +void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info); + + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // APP_ERROR_WEAK_H__ diff --git a/components/libraries/util/app_util.h b/components/libraries/util/app_util.h index 8ed3a44..8202d73 100644 --- a/components/libraries/util/app_util.h +++ b/components/libraries/util/app_util.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -25,6 +53,30 @@ #include #include #include "compiler_abstraction.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +//lint -save -e27 -e10 -e19 +#if defined ( __CC_ARM ) +extern char STACK$$Base; +extern char STACK$$Length; +#define STACK_BASE &STACK$$Base +#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&STACK$$Length)) +#elif defined ( __ICCARM__ ) +extern char CSTACK$$Base; +extern char CSTACK$$Length; +#define STACK_BASE &CSTACK$$Base +#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&CSTACK$$Length)) +#elif defined ( __GNUC__ ) +extern uint32_t __StackTop; +extern uint32_t __StackLimit; +#define STACK_BASE &__StackLimit +#define STACK_TOP &__StackTop +#endif +//lint -restore enum { @@ -52,23 +104,23 @@ enum #define STRING_CONCATENATE(lhs, rhs) STRING_CONCATENATE_IMPL(lhs, rhs) -// Disable lint-warnings/errors for STATIC_ASSERT -//lint --emacro(10,STATIC_ASSERT) -//lint --emacro(18,STATIC_ASSERT) -//lint --emacro(19,STATIC_ASSERT) -//lint --emacro(30,STATIC_ASSERT) -//lint --emacro(37,STATIC_ASSERT) -//lint --emacro(42,STATIC_ASSERT) -//lint --emacro(26,STATIC_ASSERT) -//lint --emacro(102,STATIC_ASSERT) -//lint --emacro(533,STATIC_ASSERT) -//lint --emacro(534,STATIC_ASSERT) -//lint --emacro(132,STATIC_ASSERT) -//lint --emacro(414,STATIC_ASSERT) -//lint --emacro(578,STATIC_ASSERT) -//lint --emacro(628,STATIC_ASSERT) -//lint --emacro(648,STATIC_ASSERT) -//lint --emacro(830,STATIC_ASSERT) +// Disable lint-warnings/errors for STATIC_ASSERT_MSG +//lint --emacro(10, STATIC_ASSERT_MSG) +//lint --emacro(18, STATIC_ASSERT_MSG) +//lint --emacro(19, STATIC_ASSERT_MSG) +//lint --emacro(30, STATIC_ASSERT_MSG) +//lint --emacro(37, STATIC_ASSERT_MSG) +//lint --emacro(42, STATIC_ASSERT_MSG) +//lint --emacro(26, STATIC_ASSERT_MSG) +//lint --emacro(102,STATIC_ASSERT_MSG) +//lint --emacro(533,STATIC_ASSERT_MSG) +//lint --emacro(534,STATIC_ASSERT_MSG) +//lint --emacro(132,STATIC_ASSERT_MSG) +//lint --emacro(414,STATIC_ASSERT_MSG) +//lint --emacro(578,STATIC_ASSERT_MSG) +//lint --emacro(628,STATIC_ASSERT_MSG) +//lint --emacro(648,STATIC_ASSERT_MSG) +//lint --emacro(830,STATIC_ASSERT_MSG) /**@brief Macro for doing static (i.e. compile time) assertion. @@ -78,25 +130,88 @@ enum * @note The output of STATIC_ASSERT_MSG will be different across different compilers. * * @param[in] EXPR Constant expression to be verified. +* @param[in] MSG Name of the static assert. */ -#if defined ( __COUNTER__ ) +#if defined(__COUNTER__) -#define STATIC_ASSERT(EXPR) \ - ;enum { STRING_CONCATENATE(static_assert_, __COUNTER__) = 1/(!!(EXPR)) } + #define STATIC_ASSERT_MSG(EXPR, MSG) \ + ;enum { STRING_CONCATENATE(MSG, __COUNTER__) = 1 / (!!(EXPR)) } #else -#define STATIC_ASSERT(EXPR) \ - ;enum { STRING_CONCATENATE(assert_line_, __LINE__) = 1/(!!(EXPR)) } + #define STATIC_ASSERT_MSG(EXPR, MSG) \ + ;enum { STRING_CONCATENATE(MSG, __LINE__) = 1 / (!!(EXPR)) } #endif +/**@brief Macro for doing static (i.e. compile time) assertion. +* +* @note If the EXPR isn't resolvable, then the error message won't be shown. +* +* @note The output of STATIC_ASSERT will be different across different compilers. +* +* @param[in] EXPR Constant expression to be verified. +*/ +#define STATIC_ASSERT(EXPR) STATIC_ASSERT_MSG((EXPR), static_assert_) + + +/**@brief Implementation details for NUM_VAR_ARGS */ +#define NUM_VA_ARGS_IMPL( \ + _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ + _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ + _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ + _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ + _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ + _61, _62, N, ...) N + + +/**@brief Macro to get the number of arguments in a call variadic macro call + * + * param[in] ... List of arguments + * + * @retval Number of variadic arguments in the argument list + */ +#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__, 63, 62, 61, \ + 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \ + 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \ + 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \ + 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \ + 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \ + 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) + +/**@brief Implementation details for NUM_VAR_ARGS */ +#define NUM_VA_ARGS_LESS_1_IMPL( \ + _ignored, \ + _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ + _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ + _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ + _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ + _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ + _61, _62, N, ...) N + +/**@brief Macro to get the number of arguments in a call variadic macro call. + * First argument is not counted. + * + * param[in] ... List of arguments + * + * @retval Number of variadic arguments in the argument list + */ +#define NUM_VA_ARGS_LESS_1(...) NUM_VA_ARGS_LESS_1_IMPL(__VA_ARGS__, 63, 62, 61, \ + 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \ + 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \ + 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \ + 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \ + 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \ + 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ~) + /**@brief type for holding an encoded (i.e. little endian) 16 bit unsigned integer. */ typedef uint8_t uint16_le_t[2]; -/**@brief type for holding an encoded (i.e. little endian) 32 bit unsigned integer. */ +/**@brief Type for holding an encoded (i.e. little endian) 32 bit unsigned integer. */ typedef uint8_t uint32_le_t[4]; /**@brief Byte array type. */ @@ -105,8 +220,9 @@ typedef struct uint16_t size; /**< Number of array entries. */ uint8_t * p_data; /**< Pointer to array entries. */ } uint8_array_t; - -/**@brief Perform rounded integer division (as opposed to truncating the result). + + +/**@brief Macro for performing rounded integer division (as opposed to truncating the result). * * @param[in] A Numerator. * @param[in] B Denominator. @@ -115,7 +231,8 @@ typedef struct */ #define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B)) -/**@brief Check if the integer provided is a power of two. + +/**@brief Macro for checking if an integer is a power of two. * * @param[in] A Number to be tested. * @@ -124,13 +241,16 @@ typedef struct */ #define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) ) -/**@brief To convert milliseconds to ticks. + +/**@brief Macro for converting milliseconds to ticks. + * * @param[in] TIME Number of milliseconds to convert. * @param[in] RESOLUTION Unit to be converted to in [us/ticks]. */ #define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION)) -/**@brief Perform integer division, making sure the result is rounded up. + +/**@brief Macro for performing integer division, making sure the result is rounded up. * * @details One typical use for this is to compute the number of objects with size B is needed to * hold A number of bytes. @@ -143,13 +263,482 @@ typedef struct #define CEIL_DIV(A, B) \ (((A) + (B) - 1) / (B)) -/**@brief Function for creating a buffer aligned to 4 bytes. + +/**@brief Macro for creating a buffer aligned to 4 bytes. * * @param[in] NAME Name of the buffor. * @param[in] MIN_SIZE Size of this buffor (it will be rounded up to multiples of 4 bytes). */ #define WORD_ALIGNED_MEM_BUFF(NAME, MIN_SIZE) static uint32_t NAME[CEIL_DIV(MIN_SIZE, sizeof(uint32_t))] + +/**@brief Macro for calculating the number of words that are needed to hold a number of bytes. + * + * @details Adds 3 and divides by 4. + * + * @param[in] n_bytes The number of bytes. + * + * @return The number of words that @p n_bytes take up (rounded up). + */ +#define BYTES_TO_WORDS(n_bytes) (((n_bytes) + 3) >> 2) + + +/**@brief The number of bytes in a word. + */ +#define BYTES_PER_WORD (4) + + +/**@brief Macro for increasing a number to the nearest (larger) multiple of another number. + * + * @param[in] alignment The number to align to. + * @param[in] number The number to align (increase). + * + * @return The aligned (increased) @p number. + */ +#define ALIGN_NUM(alignment, number) ((number - 1) + alignment - ((number - 1) % alignment)) + +/**@brief Macro for getting first of 2 parameters. + * + * @param[in] a1 First parameter. + * @param[in] a2 Second parameter. + */ +#define GET_ARG_1(a1, a2) a1 + +/**@brief Macro for getting second of 2 parameters. + * + * @param[in] a1 First parameter. + * @param[in] a2 Second parameter. + */ +#define GET_ARG_2(a1, a2) a2 + + +/**@brief Container of macro (borrowed from Linux kernel). + * + * This macro returns parent structure address basing on child member address. + * + * @param ptr Address of child type. + * @param type Type of parent structure. + * @param member Name of child field in parent structure. + * + * @return Parent structure address. + * */ +#define CONTAINER_OF(ptr, type, member) \ + (type *)((char *)ptr - offsetof(type, member)) + + +/** + * @brief Define Bit-field mask + * + * Macro that defined the mask with selected number of bits set, starting from + * provided bit number. + * + * @param[in] bcnt Number of bits in the bit-field + * @param[in] boff Lowest bit number + */ +#define BF_MASK(bcnt, boff) ( ((1U << (bcnt)) - 1U) << (boff) ) + +/** + * @brief Get bit-field + * + * Macro that extracts selected bit-field from provided value + * + * @param[in] val Value from witch selected bit-field would be extracted + * @param[in] bcnt Number of bits in the bit-field + * @param[in] boff Lowest bit number + * + * @return Value of the selected bits + */ +#define BF_GET(val, bcnt, boff) ( ( (val) & BF_MASK((bcnt), (boff)) ) >> (boff) ) + +/** + * @brief Create bit-field value + * + * Value is masked and shifted to match given bit-field + * + * @param[in] val Value to set on bit-field + * @param[in] bcnt Number of bits for bit-field + * @param[in] boff Offset of bit-field + * + * @return Value positioned of given bit-field. + */ +#define BF_VAL(val, bcnt, boff) ( (((uint32_t)(val)) << (boff)) & BF_MASK(bcnt, boff) ) + +/** + * @name Configuration of complex bit-field + * + * @sa BF_CX + * @{ + */ +/** @brief Position of bit count in complex bit-field value */ +#define BF_CX_BCNT_POS 0U +/** @brief Mask of bit count in complex bit-field value */ +#define BF_CX_BCNT_MASK (0xffU << BF_CX_BCNT_POS) +/** @brief Position of bit position in complex bit-field value */ +#define BF_CX_BOFF_POS 8U +/** @brief Mask of bit position in complex bit-field value */ +#define BF_CX_BOFF_MASK (0xffU << BF_CX_BOFF_POS) +/** @} */ + +/** + * @brief Define complex bit-field + * + * Complex bit-field would contain its position and size in one number. + * @sa BF_CX_MASK + * @sa BF_CX_POS + * @sa BF_CX_GET + * + * @param[in] bcnt Number of bits in the bit-field + * @param[in] boff Lowest bit number + * + * @return The single number that describes the bit-field completely. + */ +#define BF_CX(bcnt, boff) ( ((((uint32_t)(bcnt)) << BF_CX_BCNT_POS) & BF_CX_BCNT_MASK) | ((((uint32_t)(boff)) << BF_CX_BOFF_POS) & BF_CX_BOFF_MASK) ) + +/** + * @brief Get number of bits in bit-field + * + * @sa BF_CX + * + * @param bf_cx Complex bit-field + * + * @return Number of bits in given bit-field + */ +#define BF_CX_BCNT(bf_cx) ( ((bf_cx) & BF_CX_BCNT_MASK) >> BF_CX_BCNT_POS ) + +/** + * @brief Get lowest bit number in the field + * + * @sa BF_CX + * + * @param[in] bf_cx Complex bit-field + * + * @return Lowest bit number in given bit-field + */ +#define BF_CX_BOFF(bf_cx) ( ((bf_cx) & BF_CX_BOFF_MASK) >> BF_CX_BOFF_POS ) + +/** + * @brief Get bit mask of the selected field + * + * @sa BF_CX + * + * @param[in] bf_cx Complex bit-field + * + * @return Mask of given bit-field + */ +#define BF_CX_MASK(bf_cx) BF_MASK(BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx)) + +/** + * @brief Get bit-field + * + * Macro that extracts selected bit-field from provided value. + * Bit-field is given as a complex value. + * + * @sa BF_CX + * @sa BF_GET + * + * @param[in] val Value from witch selected bit-field would be extracted + * @param[in] bf_cx Complex bit-field + * + * @return Value of the selected bits. + */ +#define BF_CX_GET(val, bf_cx) BF_GET(val, BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx)) + +/** + * @brief Create bit-field value + * + * Value is masked and shifted to match given bit-field. + * + * @param[in] val Value to set on bit-field + * @param[in] bf_cx Complex bit-field + * + * @return Value positioned of given bit-field. + */ +#define BF_CX_VAL(val, bf_cx) BF_VAL(val, BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx)) + +/** + * @brief Extracting data from the brackets + * + * This macro get rid of brackets around the argument. + * It can be used to pass multiple arguments in logical one argument to a macro. + * Call it with arguments inside brackets: + * @code + * #define ARGUMENTS (a, b, c) + * BRACKET_EXTRACT(ARGUMENTS) + * @endcode + * It would produce: + * @code + * a, b, c + * @endcode + * + * @param a Argument with anything inside brackets + * @return Anything that appears inside the brackets of the argument + * + * @note + * The argument of the macro have to be inside brackets. + * In other case the compilation would fail. + */ +#define BRACKET_EXTRACT(a) BRACKET_EXTRACT_(a) +#define BRACKET_EXTRACT_(a) BRACKET_EXTRACT__ a +#define BRACKET_EXTRACT__(...) __VA_ARGS__ + + +/** + * @brief Check if number of parameters is more than 1 + * + * @param ... Arguments to count + * + * @return 0 If argument count is <= 1 + * @return 1 If argument count is > 1 + * + * @sa NUM_VA_ARGS + * @sa NUM_IS_MORE_THAN_1 + */ +#define NUM_VA_ARGS_IS_MORE_THAN_1(...) NUM_IS_MORE_THAN_1(NUM_VA_ARGS(__VA_ARGS__)) + +/** + * @brief Check if given numeric value is bigger than 1 + * + * This macro accepts numeric value, that may be the result of argument expansion. + * This numeric value is then converted to 0 if it is lover than 1 or to 1 if + * its value is higher than 1. + * The generated result can be used to glue it into other macro mnemonic name. + * + * @param N Numeric value to check + * + * @return 0 If argument is <= 1 + * @return 1 If argument is > 1 + * + * @note Any existing definition of a form NUM_IS_MORE_THAN_1_PROBE_[N] can + * broke the result of this macro + */ +#define NUM_IS_MORE_THAN_1(N) NUM_IS_MORE_THAN_1_(N) +#define NUM_IS_MORE_THAN_1_(N) NUM_IS_MORE_THAN_1_PROBE_(NUM_IS_MORE_THAN_1_PROBE_ ## N, 1) +#define NUM_IS_MORE_THAN_1_PROBE_(...) GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__)) +#define NUM_IS_MORE_THAN_1_PROBE_0 ~, 0 +#define NUM_IS_MORE_THAN_1_PROBE_1 ~, 0 + +/** + * @brief Get the first argument + * + * @param ... Arguments to select + * + * @return First argument or empty if no arguments are provided + */ +#define GET_VA_ARG_1(...) GET_VA_ARG_1_(__VA_ARGS__, ) // Make sure that also for 1 argument it works +#define GET_VA_ARG_1_(a1, ...) a1 + +/** + * @brief Get all the arguments but the first one + * + * @param ... Arguments to select + * + * @return All arguments after the first one or empty if less than 2 arguments are provided + */ +#define GET_ARGS_AFTER_1(...) GET_ARGS_AFTER_1_(__VA_ARGS__, ) // Make sure that also for 1 argument it works +#define GET_ARGS_AFTER_1_(a1, ...) __VA_ARGS__ + +/** + * @brief Size of a field in declared structure + * + * Macro that returns the size of the structure field. + * @param struct_type Variable type to get the field size from + * @param field Field name to analyze. It can be even field inside field (field.somethingelse.and_another). + * + * @return Size of the field + */ +#define FIELD_SIZE(struct_type, field) sizeof(((struct struct_type*)NULL)->field) + +/** + * @brief Number of elements in field array in declared structure + * + * Macro that returns number of elementy in structure field. + * @param struct_type Variable type to get the field size from + * @param field Field name to analyze. + * + * @return Number of elements in field array + * + * @sa FIELD_SIZE + */ +#define FIELD_ARRAY_SIZE(struct_type, field) (FIELD_SIZE(struct_type, field) / FIELD_SIZE(struct_type, field[0])) + +/** + * @brief Mapping macro + * + * Macro that process all arguments using given macro + * + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument) + * + * @return All arguments processed by given macro + */ +#define MACRO_MAP(...) MACRO_MAP_(__VA_ARGS__) +#define MACRO_MAP_(...) MACRO_MAP_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) // To make sure it works also for 2 arguments in total + +/** + * @brief Mapping macro, recursive version + * + * Can be used in @ref MACRO_MAP macro + */ +#define MACRO_MAP_REC(...) MACRO_MAP_REC_(__VA_ARGS__) +#define MACRO_MAP_REC_(...) MACRO_MAP_REC_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) // To make sure it works also for 2 arguments in total +/** + * @brief Mapping N arguments macro + * + * Macro similar to @ref MACRO_MAP but maps exact number of arguments. + * If there is more arguments given, the rest would be ignored. + * + * @param N Number of arguments to map + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument) + * + * @return Selected number of arguments processed by given macro + */ +#define MACRO_MAP_N(N, ...) MACRO_MAP_N_(N, __VA_ARGS__) +#define MACRO_MAP_N_(N, ...) CONCAT_2(MACRO_MAP_, N)(__VA_ARGS__, ) + +/** + * @brief Mapping N arguments macro, recursive version + * + * Can be used in @ref MACRO_MAP_N macro + */ +#define MACRO_MAP_REC_N(N, ...) MACRO_MAP_REC_N_(N, __VA_ARGS__) +#define MACRO_MAP_REC_N_(N, ...) CONCAT_2(MACRO_MAP_REC_, N)(__VA_ARGS__, ) + +#define MACRO_MAP_0( ...) +#define MACRO_MAP_1( macro, a, ...) macro(a) +#define MACRO_MAP_2( macro, a, ...) macro(a) MACRO_MAP_1 (macro, __VA_ARGS__, ) +#define MACRO_MAP_3( macro, a, ...) macro(a) MACRO_MAP_2 (macro, __VA_ARGS__, ) +#define MACRO_MAP_4( macro, a, ...) macro(a) MACRO_MAP_3 (macro, __VA_ARGS__, ) +#define MACRO_MAP_5( macro, a, ...) macro(a) MACRO_MAP_4 (macro, __VA_ARGS__, ) +#define MACRO_MAP_6( macro, a, ...) macro(a) MACRO_MAP_5 (macro, __VA_ARGS__, ) +#define MACRO_MAP_7( macro, a, ...) macro(a) MACRO_MAP_6 (macro, __VA_ARGS__, ) +#define MACRO_MAP_8( macro, a, ...) macro(a) MACRO_MAP_7 (macro, __VA_ARGS__, ) +#define MACRO_MAP_9( macro, a, ...) macro(a) MACRO_MAP_8 (macro, __VA_ARGS__, ) +#define MACRO_MAP_10(macro, a, ...) macro(a) MACRO_MAP_9 (macro, __VA_ARGS__, ) +#define MACRO_MAP_11(macro, a, ...) macro(a) MACRO_MAP_10(macro, __VA_ARGS__, ) +#define MACRO_MAP_12(macro, a, ...) macro(a) MACRO_MAP_11(macro, __VA_ARGS__, ) +#define MACRO_MAP_13(macro, a, ...) macro(a) MACRO_MAP_12(macro, __VA_ARGS__, ) +#define MACRO_MAP_14(macro, a, ...) macro(a) MACRO_MAP_13(macro, __VA_ARGS__, ) +#define MACRO_MAP_15(macro, a, ...) macro(a) MACRO_MAP_14(macro, __VA_ARGS__, ) + +#define MACRO_MAP_REC_0( ...) +#define MACRO_MAP_REC_1( macro, a, ...) macro(a) +#define MACRO_MAP_REC_2( macro, a, ...) macro(a) MACRO_MAP_REC_1 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_3( macro, a, ...) macro(a) MACRO_MAP_REC_2 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_4( macro, a, ...) macro(a) MACRO_MAP_REC_3 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_5( macro, a, ...) macro(a) MACRO_MAP_REC_4 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_6( macro, a, ...) macro(a) MACRO_MAP_REC_5 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_7( macro, a, ...) macro(a) MACRO_MAP_REC_6 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_8( macro, a, ...) macro(a) MACRO_MAP_REC_7 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_9( macro, a, ...) macro(a) MACRO_MAP_REC_8 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_10(macro, a, ...) macro(a) MACRO_MAP_REC_9 (macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_11(macro, a, ...) macro(a) MACRO_MAP_REC_10(macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_12(macro, a, ...) macro(a) MACRO_MAP_REC_11(macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_13(macro, a, ...) macro(a) MACRO_MAP_REC_12(macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_14(macro, a, ...) macro(a) MACRO_MAP_REC_13(macro, __VA_ARGS__, ) +#define MACRO_MAP_REC_15(macro, a, ...) macro(a) MACRO_MAP_REC_14(macro, __VA_ARGS__, ) + +/** + * @brief Mapping macro with current index + * + * Basically macro similar to @ref MACRO_MAP, but the processing function would get an argument + * and current argument index (beginning from 0). + * + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument, index) + * @return All arguments processed by given macro + */ +#define MACRO_MAP_FOR(...) MACRO_MAP_FOR_(__VA_ARGS__) +#define MACRO_MAP_FOR_N_LIST 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +#define MACRO_MAP_FOR_(...) MACRO_MAP_FOR_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) + +/** + * @brief Mapping N arguments macro with current index + * + * Macro is similar to @ref MACRO_MAP_FOR but maps exact number of arguments. + * If there is more arguments given, the rest would be ignored. + * + * @param N Number of arguments to map + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument, index) + * + * @return Selected number of arguments processed by given macro + */ +#define MACRO_MAP_FOR_N(N, ...) MACRO_MAP_FOR_N_(N, __VA_ARGS__) +#define MACRO_MAP_FOR_N_(N, ...) CONCAT_2(MACRO_MAP_FOR_, N)((MACRO_MAP_FOR_N_LIST), __VA_ARGS__, ) + +#define MACRO_MAP_FOR_0( n_list, ...) +#define MACRO_MAP_FOR_1( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) +#define MACRO_MAP_FOR_2( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_1 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_3( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_2 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_4( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_3 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_5( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_4 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_6( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_5 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_7( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_6 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_8( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_7 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_9( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_8 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_10(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_9 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_11(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_12(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_13(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_14(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_15(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, ) + + +/** + * @brief Mapping macro with current index and parameter + * + * Version of @ref MACRO_MAP_FOR that passes also the same parameter to all macros. + * + * @param param Parameter that would be passed to each macro call during mapping. + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument, index, param) + * + * @return All arguments processed by given macro + */ +#define MACRO_MAP_FOR_PARAM(param, ...) MACRO_MAP_FOR_PARAM_(param, __VA_ARGS__) +#define MACRO_MAP_FOR_PARAM_(param, ...) MACRO_MAP_FOR_PARAM_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), param, __VA_ARGS__) + +/** + * @brief Mapping N arguments macro with with current index and parameter + * + * @param N Number of arguments to map + * @param param Parameter that would be passed to each macro call during mapping. + * @param ... Macro name to be used for argument processing followed by arguments to process. + * Macro should have following form: MACRO(argument, index, param) + * + * @return All arguments processed by given macro + */ +#define MACRO_MAP_FOR_PARAM_N(N, param, ...) MACRO_MAP_FOR_PARAM_N_(N, param, __VA_ARGS__) +#define MACRO_MAP_FOR_PARAM_N_(N, param, ...) CONCAT_2(MACRO_MAP_FOR_PARAM_, N)((MACRO_MAP_FOR_N_LIST), param, __VA_ARGS__, ) + + +#define MACRO_MAP_FOR_PARAM_0( n_list, param, ...) +#define MACRO_MAP_FOR_PARAM_1( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) +#define MACRO_MAP_FOR_PARAM_2( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_1 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_3( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_2 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_4( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_3 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_5( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_4 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_6( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_5 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_7( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_6 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_8( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_7 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_9( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_8 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_10(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_9 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_11(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_12(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_13(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_14(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) +#define MACRO_MAP_FOR_PARAM_15(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, ) + + +/**@brief Adding curly brace to macro parameter + * + * Useful in array of structures initialization. + * + * @param p parameter to put into the curly brace*/ +#define PARAM_CBRACE(p) { p }, + + /**@brief Function for changing the value unit. * * @param[in] value Value to be rescaled. @@ -208,6 +797,24 @@ static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data) return sizeof(uint32_t); } +/**@brief Function for encoding a uint48 value. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data is to be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint48_encode(uint64_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) ((value & 0x0000000000FF) >> 0); + p_encoded_data[1] = (uint8_t) ((value & 0x00000000FF00) >> 8); + p_encoded_data[2] = (uint8_t) ((value & 0x000000FF0000) >> 16); + p_encoded_data[3] = (uint8_t) ((value & 0x0000FF000000) >> 24); + p_encoded_data[4] = (uint8_t) ((value & 0x00FF00000000) >> 32); + p_encoded_data[5] = (uint8_t) ((value & 0xFF0000000000) >> 40); + return 6; +} + /**@brief Function for decoding a uint16 value. * * @param[in] p_encoded_data Buffer where the encoded data is stored. @@ -216,10 +823,22 @@ static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data) */ static __INLINE uint16_t uint16_decode(const uint8_t * p_encoded_data) { - return ( (((uint16_t)((uint8_t *)p_encoded_data)[0])) | + return ( (((uint16_t)((uint8_t *)p_encoded_data)[0])) | (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 )); } +/**@brief Function for decoding a uint16 value in big-endian format. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. + */ +static __INLINE uint16_t uint16_big_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint16_t)((uint8_t *)p_encoded_data)[0]) << 8 ) | + (((uint16_t)((uint8_t *)p_encoded_data)[1])) ); +} + /**@brief Function for decoding a three-byte value. * * @param[in] p_encoded_data Buffer where the encoded data is stored. @@ -247,6 +866,65 @@ static __INLINE uint32_t uint32_decode(const uint8_t * p_encoded_data) (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 )); } +/**@brief Function for decoding a uint32 value in big-endian format. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. + */ +static __INLINE uint32_t uint32_big_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 24) | + (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 16) | + (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 8) | + (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 0) ); +} + +/** + * @brief Function for encoding an uint16 value in big-endian format. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data will be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint16_big_encode(uint16_t value, uint8_t * p_encoded_data) +{ + p_encoded_data[0] = (uint8_t) (value >> 8); + p_encoded_data[1] = (uint8_t) (value & 0xFF); + + return sizeof(uint16_t); +} + +/**@brief Function for encoding a uint32 value in big-endian format. + * + * @param[in] value Value to be encoded. + * @param[out] p_encoded_data Buffer where the encoded data will be written. + * + * @return Number of bytes written. + */ +static __INLINE uint8_t uint32_big_encode(uint32_t value, uint8_t * p_encoded_data) +{ + *(uint32_t *)p_encoded_data = __REV(value); + return sizeof(uint32_t); +} + +/**@brief Function for decoding a uint48 value. + * + * @param[in] p_encoded_data Buffer where the encoded data is stored. + * + * @return Decoded value. (uint64_t) + */ +static __INLINE uint64_t uint48_decode(const uint8_t * p_encoded_data) +{ + return ( (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) | + (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) | + (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) | + (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24) | + (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32) | + (((uint64_t)((uint8_t *)p_encoded_data)[5]) << 40 )); +} + /** @brief Function for converting the input voltage (in milli volts) into percentage of 3.0 Volts. * * @details The calculation is based on a linearized version of the battery's discharge @@ -310,6 +988,31 @@ static __INLINE bool is_word_aligned(void const* p) return (((uintptr_t)p & 0x03) == 0); } +/** + * @brief Function for checking if provided address is located in stack space. + * + * @param[in] ptr Pointer to be checked. + * + * @return true if address is in stack space, false otherwise. + */ +static __INLINE bool is_address_from_stack(void * ptr) +{ + if (((uint32_t)ptr >= (uint32_t)STACK_BASE) && + ((uint32_t)ptr < (uint32_t)STACK_TOP) ) + { + return true; + } + else + { + return false; + } +} + + +#ifdef __cplusplus +} +#endif + #endif // APP_UTIL_H__ /** @} */ diff --git a/components/libraries/util/app_util_bds.h b/components/libraries/util/app_util_bds.h index 50bb30e..f6b10e0 100644 --- a/components/libraries/util/app_util_bds.h +++ b/components/libraries/util/app_util_bds.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -29,7 +57,11 @@ #include "app_util.h" #include "ble_srv_common.h" #include "nordic_common.h" - + +#ifdef __cplusplus +extern "C" { +#endif + typedef uint8_t nibble_t; typedef uint32_t uint24_t; typedef uint64_t uint40_t; @@ -95,7 +127,7 @@ static __INLINE uint8_t bds_uint24_encode(const uint32_t * p_value, uint8_t * p_ return (3); } - + /**@brief Function for encoding a uint32 value. * * @param[in] p_value Value to be encoded. @@ -112,7 +144,7 @@ static __INLINE uint8_t bds_uint32_encode(const uint32_t * p_value, uint8_t * p_ return sizeof(uint32_t); } - + /**@brief Function for encoding a uint40 value. * * @param[in] p_value Value to be encoded. @@ -153,12 +185,12 @@ static __INLINE uint8_t bds_sfloat_encode(const sfloat_t * p_value, uint8_t * p_ * @param[in] p_value Value to be encoded. * @param[out] p_encoded_data Buffer where the encoded data is to be written. */ -static __INLINE uint8_t bds_uint8_array_encode(const uint8_array_t * p_value, +static __INLINE uint8_t bds_uint8_array_encode(const uint8_array_t * p_value, uint8_t * p_encoded_data) { memcpy(p_encoded_data, p_value->p_data, p_value->size); return p_value->size; -} +} /**@brief Function for encoding a utf8_str value. @@ -172,7 +204,7 @@ static __INLINE uint8_t bds_ble_srv_utf8_str_encode(const ble_srv_utf8_str_t * p { memcpy(p_encoded_data, p_value->p_str, p_value->length); return p_value->length; -} +} /**@brief Function for encoding a regcertdatalist value. * @@ -180,12 +212,12 @@ static __INLINE uint8_t bds_ble_srv_utf8_str_encode(const ble_srv_utf8_str_t * p * @param[out] p_encoded_data Buffer where the encoded data is to be written. */ -static __INLINE uint8_t bds_regcertdatalist_encode(const regcertdatalist_t * p_value, +static __INLINE uint8_t bds_regcertdatalist_encode(const regcertdatalist_t * p_value, uint8_t * p_encoded_data) { memcpy(p_encoded_data, p_value->p_list, p_value->list_len); return p_value->list_len; -} +} /**@brief Function for decoding a date_time value. @@ -198,13 +230,13 @@ static __INLINE uint8_t bds_ble_date_time_encode(const ble_date_time_t * p_date_ uint8_t * p_encoded_data) { uint8_t len = bds_uint16_encode(&p_date_time->year, &p_encoded_data[0]); - + p_encoded_data[len++] = p_date_time->month; p_encoded_data[len++] = p_date_time->day; p_encoded_data[len++] = p_date_time->hours; p_encoded_data[len++] = p_date_time->minutes; p_encoded_data[len++] = p_date_time->seconds; - + return len; } @@ -216,12 +248,12 @@ static __INLINE uint8_t bds_ble_date_time_encode(const ble_date_time_t * p_date_ * @param[in] p_decoded_val pointer to the decoded value * @return length of the decoded field. */ -static __INLINE uint8_t bds_uint16_decode(const uint8_t len, - const uint8_t * p_encoded_data, +static __INLINE uint8_t bds_uint16_decode(const uint8_t len, + const uint8_t * p_encoded_data, uint16_t * p_decoded_val) { UNUSED_VARIABLE(len); - *p_decoded_val = (((uint16_t)((uint8_t *)p_encoded_data)[0])) | + *p_decoded_val = (((uint16_t)((uint8_t *)p_encoded_data)[0])) | (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 ); return (sizeof(uint16_t)); } @@ -234,13 +266,15 @@ static __INLINE uint8_t bds_uint16_decode(const uint8_t len, * @param[in] p_decoded_val pointer to the decoded value * @return length of the decoded field. */ -static __INLINE uint8_t bds_int16_decode(const uint8_t len, - const uint8_t * p_encoded_data, +static __INLINE uint8_t bds_int16_decode(const uint8_t len, + const uint8_t * p_encoded_data, int16_t * p_decoded_val) { UNUSED_VARIABLE(len); - uint16_t tmp = *p_decoded_val; - return bds_uint16_decode(len, p_encoded_data, &tmp); + uint16_t tmp = 0; + uint8_t retval = bds_uint16_decode(len, p_encoded_data, &tmp); + *p_decoded_val = (int16_t)tmp; + return retval; } @@ -252,8 +286,8 @@ static __INLINE uint8_t bds_int16_decode(const uint8_t len, * * @return length of the decoded field. */ -static __INLINE uint8_t bds_uint24_decode(const uint8_t len, - const uint8_t * p_encoded_data, +static __INLINE uint8_t bds_uint24_decode(const uint8_t len, + const uint8_t * p_encoded_data, uint32_t * p_decoded_val) { UNUSED_VARIABLE(len); @@ -272,8 +306,8 @@ static __INLINE uint8_t bds_uint24_decode(const uint8_t len, * * @return length of the decoded field. */ -static __INLINE uint8_t bds_uint32_decode(const uint8_t len, - const uint8_t * p_encoded_data, +static __INLINE uint8_t bds_uint32_decode(const uint8_t len, + const uint8_t * p_encoded_data, uint32_t * p_decoded_val) { UNUSED_VARIABLE(len); @@ -293,8 +327,8 @@ static __INLINE uint8_t bds_uint32_decode(const uint8_t len, * * @return length of the decoded field. */ -static __INLINE uint8_t bds_uint40_decode(const uint8_t len, - const uint8_t * p_encoded_data, +static __INLINE uint8_t bds_uint40_decode(const uint8_t len, + const uint8_t * p_encoded_data, uint64_t * p_decoded_val) { UNUSED_VARIABLE(len); @@ -316,11 +350,11 @@ static __INLINE uint8_t bds_uint40_decode(const uint8_t len, * @return length of the decoded field. */ -static __INLINE uint8_t bds_sfloat_decode(const uint8_t len, - const uint8_t * p_encoded_data, +static __INLINE uint8_t bds_sfloat_decode(const uint8_t len, + const uint8_t * p_encoded_data, sfloat_t * p_decoded_val) { - + p_decoded_val->exponent = 0; bds_uint16_decode(len, p_encoded_data, (uint16_t*)&p_decoded_val->mantissa); p_decoded_val->exponent = (uint8_t)((p_decoded_val->mantissa & 0xF000) >> 12); @@ -337,14 +371,14 @@ static __INLINE uint8_t bds_sfloat_decode(const uint8_t len, * * @return length of the decoded field. */ -static __INLINE uint8_t bds_uint8_array_decode(const uint8_t len, +static __INLINE uint8_t bds_uint8_array_decode(const uint8_t len, const uint8_t * p_encoded_data, uint8_array_t * p_decoded_val) { memcpy(p_decoded_val->p_data, p_encoded_data, len); p_decoded_val->size = len; return p_decoded_val->size; -} +} /**@brief Function for decoding a utf8_str value. @@ -355,14 +389,14 @@ static __INLINE uint8_t bds_uint8_array_decode(const uint8_t len, * * @return length of the decoded field. */ -static __INLINE uint8_t bds_ble_srv_utf8_str_decode(const uint8_t len, - const uint8_t * p_encoded_data, +static __INLINE uint8_t bds_ble_srv_utf8_str_decode(const uint8_t len, + const uint8_t * p_encoded_data, ble_srv_utf8_str_t * p_decoded_val) { p_decoded_val->p_str = (uint8_t*)p_encoded_data; p_decoded_val->length = len; return p_decoded_val->length; -} +} /**@brief Function for decoding a regcertdatalist value. @@ -373,14 +407,14 @@ static __INLINE uint8_t bds_ble_srv_utf8_str_decode(const uint8_t len, * * @return length of the decoded field. */ -static __INLINE uint8_t bds_regcertdatalist_decode(const uint8_t len, - const uint8_t * p_encoded_data, +static __INLINE uint8_t bds_regcertdatalist_decode(const uint8_t len, + const uint8_t * p_encoded_data, regcertdatalist_t * p_decoded_val) { memcpy(p_decoded_val->p_list, p_encoded_data, len); p_decoded_val->list_len = len; return p_decoded_val->list_len; -} +} /**@brief Function for decoding a date_time value. @@ -391,8 +425,8 @@ static __INLINE uint8_t bds_regcertdatalist_decode(const uint8_t len, * * @return length of the decoded field. */ -static __INLINE uint8_t bds_ble_date_time_decode(const uint8_t len, - const uint8_t * p_encoded_data, +static __INLINE uint8_t bds_ble_date_time_decode(const uint8_t len, + const uint8_t * p_encoded_data, ble_date_time_t * p_date_time) { UNUSED_VARIABLE(len); @@ -406,6 +440,11 @@ static __INLINE uint8_t bds_ble_date_time_decode(const uint8_t len, return pos; } + +#ifdef __cplusplus +} +#endif + #endif // APP_UTIL_BDS_H__ /** @} */ diff --git a/components/libraries/util/app_util_platform.c b/components/libraries/util/app_util_platform.c index 5555002..6caf659 100644 --- a/components/libraries/util/app_util_platform.c +++ b/components/libraries/util/app_util_platform.c @@ -1,30 +1,93 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "app_util_platform.h" +#ifdef SOFTDEVICE_PRESENT +/* Global nvic state instance, required by nrf_nvic.h */ +nrf_nvic_state_t nrf_nvic_state; +#endif + static uint32_t m_in_critical_region = 0; -void critical_region_enter(void) +void app_util_disable_irq(void) { - __disable_irq(); - m_in_critical_region++; + __disable_irq(); + m_in_critical_region++; } -void critical_region_exit(void) +void app_util_enable_irq(void) { - m_in_critical_region--; + m_in_critical_region--; if (m_in_critical_region == 0) { __enable_irq(); } } + +void app_util_critical_region_enter(uint8_t *p_nested) +{ +#if __CORTEX_M == (0x04U) + ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get()) +#endif + +#if defined(SOFTDEVICE_PRESENT) + /* return value can be safely ignored */ + (void) sd_nvic_critical_region_enter(p_nested); +#else + app_util_disable_irq(); +#endif +} + +void app_util_critical_region_exit(uint8_t nested) +{ +#if __CORTEX_M == (0x04U) + ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get()) +#endif + +#if defined(SOFTDEVICE_PRESENT) + /* return value can be safely ignored */ + (void) sd_nvic_critical_region_exit(nested); +#else + app_util_enable_irq(); +#endif +} + + diff --git a/components/libraries/util/app_util_platform.h b/components/libraries/util/app_util_platform.h index bf25d5c..5aa6595 100644 --- a/components/libraries/util/app_util_platform.h +++ b/components/libraries/util/app_util_platform.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -27,31 +55,109 @@ #include "nrf.h" #ifdef SOFTDEVICE_PRESENT #include "nrf_soc.h" +#include "nrf_nvic.h" +#endif +#include "nrf_assert.h" #include "app_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if __CORTEX_M == (0x00U) +#define _PRIO_SD_HIGH 0 +#define _PRIO_APP_HIGH 1 +#define _PRIO_APP_MID 1 +#define _PRIO_SD_LOW 2 +#define _PRIO_APP_LOW 3 +#define _PRIO_APP_LOWEST 3 +#define _PRIO_THREAD 4 +#elif __CORTEX_M == (0x04U) +#define _PRIO_SD_HIGH 0 +#define _PRIO_SD_MID 1 +#define _PRIO_APP_HIGH 2 +#define _PRIO_APP_MID 3 +#define _PRIO_SD_LOW 4 +#define _PRIO_SD_LOWEST 5 +#define _PRIO_APP_LOW 6 +#define _PRIO_APP_LOWEST 7 +#define _PRIO_THREAD 15 +#else + #error "No platform defined" #endif + + +//lint -save -e113 -e452 /**@brief The interrupt priorities available to the application while the SoftDevice is active. */ typedef enum { #ifndef SOFTDEVICE_PRESENT - APP_IRQ_PRIORITY_HIGHEST = 0, + APP_IRQ_PRIORITY_HIGHEST = _PRIO_SD_HIGH, +#else + APP_IRQ_PRIORITY_HIGHEST = _PRIO_APP_HIGH, #endif - APP_IRQ_PRIORITY_HIGH = 1, + APP_IRQ_PRIORITY_HIGH = _PRIO_APP_HIGH, #ifndef SOFTDEVICE_PRESENT - APP_IRQ_PRIORITY_MID = 2, + APP_IRQ_PRIORITY_MID = _PRIO_SD_LOW, +#else + APP_IRQ_PRIORITY_MID = _PRIO_APP_MID, #endif - APP_IRQ_PRIORITY_LOW = 3 + APP_IRQ_PRIORITY_LOW = _PRIO_APP_LOW, + APP_IRQ_PRIORITY_LOWEST = _PRIO_APP_LOWEST, + APP_IRQ_PRIORITY_THREAD = _PRIO_THREAD /**< "Interrupt level" when running in Thread Mode. */ } app_irq_priority_t; +//lint -restore + -#define NRF_APP_PRIORITY_THREAD 4 /**< "Interrupt level" when running in Thread Mode. */ +/*@brief The privilege levels available to applications in Thread Mode */ +typedef enum +{ + APP_LEVEL_UNPRIVILEGED, + APP_LEVEL_PRIVILEGED +} app_level_t; /**@cond NO_DOXYGEN */ #define EXTERNAL_INT_VECTOR_OFFSET 16 /**@endcond */ +/**@brief Macro for setting a breakpoint. + */ +#if defined(__GNUC__) +#define NRF_BREAKPOINT __builtin_trap() +#else +#define NRF_BREAKPOINT __BKPT(0) +#endif + +/** @brief Macro for setting a breakpoint. + * + * If it is possible to detect debugger presence then it is set only in that case. + * + */ +#if __CORTEX_M == 0x04 +#define NRF_BREAKPOINT_COND do { \ + /* C_DEBUGEN == 1 -> Debugger Connected */ \ + if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) \ + { \ + /* Generate breakpoint if debugger is connected */ \ + NRF_BREAKPOINT; \ + } \ + }while (0) +#else +#define NRF_BREAKPOINT_COND NRF_BREAKPOINT +#endif // __CORTEX_M == 0x04 + +#if defined ( __CC_ARM ) #define PACKED(TYPE) __packed TYPE +#define PACKED_STRUCT PACKED(struct) +#elif defined ( __GNUC__ ) +#define PACKED __attribute__((packed)) +#define PACKED_STRUCT struct PACKED +#elif defined (__ICCARM__) +#define PACKED_STRUCT __packed struct +#endif -void critical_region_enter (void); -void critical_region_exit (void); +void app_util_critical_region_enter (uint8_t *p_nested); +void app_util_critical_region_exit (uint8_t nested); /**@brief Macro for entering a critical region. * @@ -62,22 +168,10 @@ void critical_region_exit (void); #ifdef SOFTDEVICE_PRESENT #define CRITICAL_REGION_ENTER() \ { \ - uint8_t IS_NESTED_CRITICAL_REGION = 0; \ - uint32_t CURRENT_INT_PRI = current_int_priority_get(); \ - if (CURRENT_INT_PRI != APP_IRQ_PRIORITY_HIGH) \ - { \ - uint32_t ERR_CODE = sd_nvic_critical_region_enter(&IS_NESTED_CRITICAL_REGION); \ - if (ERR_CODE == NRF_ERROR_SOFTDEVICE_NOT_ENABLED) \ - { \ - __disable_irq(); \ - } \ - else \ - { \ - APP_ERROR_CHECK(ERR_CODE); \ - } \ - } + uint8_t __CR_NESTED = 0; \ + app_util_critical_region_enter(&__CR_NESTED); #else -#define CRITICAL_REGION_ENTER() critical_region_enter() +#define CRITICAL_REGION_ENTER() app_util_critical_region_enter(NULL) #endif /**@brief Macro for leaving a critical region. @@ -88,21 +182,51 @@ void critical_region_exit (void); */ #ifdef SOFTDEVICE_PRESENT #define CRITICAL_REGION_EXIT() \ - if (CURRENT_INT_PRI != APP_IRQ_PRIORITY_HIGH) \ - { \ - uint32_t ERR_CODE; \ - __enable_irq(); \ - ERR_CODE = sd_nvic_critical_region_exit(IS_NESTED_CRITICAL_REGION); \ - if (ERR_CODE != NRF_ERROR_SOFTDEVICE_NOT_ENABLED) \ - { \ - APP_ERROR_CHECK(ERR_CODE); \ - } \ - } \ + app_util_critical_region_exit(__CR_NESTED); \ } #else -#define CRITICAL_REGION_EXIT() critical_region_exit() -#endif - +#define CRITICAL_REGION_EXIT() app_util_critical_region_exit(0) +#endif + +/* Workaround for Keil 4 */ +#ifndef IPSR_ISR_Msk +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ +#endif + + + +/**@brief Macro to enable anonymous unions from a certain point in the code. + */ +#if defined(__CC_ARM) + #define ANON_UNIONS_ENABLE _Pragma("push") \ + _Pragma("anon_unions") +#elif defined(__ICCARM__) + #define ANON_UNIONS_ENABLE _Pragma("language=extended") +#else + #define ANON_UNIONS_ENABLE + // No action will be taken. + // For GCC anonymous unions are enabled by default. +#endif + +/**@brief Macro to disable anonymous unions from a certain point in the code. + * @note Call only after first calling @ref ANON_UNIONS_ENABLE. + */ +#if defined(__CC_ARM) + #define ANON_UNIONS_DISABLE _Pragma("pop") +#elif defined(__ICCARM__) + #define ANON_UNIONS_DISABLE + // for IAR leave anonymous unions enabled +#else + #define ANON_UNIONS_DISABLE + // No action will be taken. + // For GCC anonymous unions are enabled by default. +#endif + +/* Workaround for Keil 4 */ +#ifndef CONTROL_nPRIV_Msk +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ +#endif + /**@brief Function for finding the current interrupt level. * * @return Current interrupt level. @@ -112,7 +236,7 @@ void critical_region_exit (void); */ static __INLINE uint8_t current_int_priority_get(void) { - uint32_t isr_vector_num = (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk); + uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ; if (isr_vector_num > 0) { int32_t irq_type = ((int32_t)isr_vector_num - EXTERNAL_INT_VECTOR_OFFSET); @@ -120,10 +244,42 @@ static __INLINE uint8_t current_int_priority_get(void) } else { - return NRF_APP_PRIORITY_THREAD; + return APP_IRQ_PRIORITY_THREAD; + } +} + +/**@brief Function for finding out the current privilege level. + * + * @return Current privilege level. + * @retval APP_LEVEL_UNPRIVILEGED We are running in unprivileged level. + * @retval APP_LEVEL_PRIVILEGED We are running in privileged level. + */ +static __INLINE uint8_t privilege_level_get(void) +{ +#if __CORTEX_M == (0x00U) || defined(_WIN32) || defined(__unix) || defined(__APPLE__) + /* the Cortex-M0 has no concept of privilege */ + return APP_LEVEL_PRIVILEGED; +#elif __CORTEX_M == (0x04U) + uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ; + if (0 == isr_vector_num) + { + /* Thread Mode, check nPRIV */ + int32_t control = __get_CONTROL(); + return control & CONTROL_nPRIV_Msk ? APP_LEVEL_UNPRIVILEGED : APP_LEVEL_PRIVILEGED; + } + else + { + /* Handler Mode, always privileged */ + return APP_LEVEL_PRIVILEGED; } +#endif } + +#ifdef __cplusplus +} +#endif + #endif // APP_UTIL_PLATFORM_H__ /** @} */ diff --git a/components/libraries/util/common.h b/components/libraries/util/common.h deleted file mode 100644 index 44abd5b..0000000 --- a/components/libraries/util/common.h +++ /dev/null @@ -1,38 +0,0 @@ - /* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 COMMON_H -#define COMMON_H - -/*lint ++flb "Enter library region" */ - -#include -#include - -/* @file -* @brief Common header file for generic macros and definitions - * - */ - -/* - * GPIO glue macros, this can be used to define a pin number in source/header file and use that macro for pin - * configuration using this expansion. - * example: - * #define RESET_PIN 8 - * NRF_GPIO->PINCNF(RESET_PIN) = XXX ; // Expanded NRF_GPIO->PIN_CNF[8] = XXX - */ -#define PINX_GLUE(x, y, z) x##y##_##z /*!< first level glue for pin macros */ -#define PINCNF(p) PINX_GLUE(PIN,p,CNF) /*!< gpio configure pin number 'p' */ -#define PINOUT(p) PINX_GLUE(PIN,p,OUT) /*!< gpio out pin number 'p' */ - -/*lint --flb "Leave library region" */ -#endif diff --git a/components/libraries/util/nordic_common.h b/components/libraries/util/nordic_common.h index b9e97da..8458319 100644 --- a/components/libraries/util/nordic_common.h +++ b/components/libraries/util/nordic_common.h @@ -1,12 +1,41 @@ -/* Copyright (c) 2008 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. +/** + * Copyright (c) 2008 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -16,11 +45,43 @@ #ifndef NORDIC_COMMON_H__ #define NORDIC_COMMON_H__ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Check if selected module is enabled + * + * This is save function for driver enable checking. + * Correct from Lint point of view (not using default of undefined value). + * + * Usage: + * @code + #if NRF_MODULE_ENABLED(UART) + ... + #endif + * @endcode + * + * @param module The module name. + * + * @retval 1 The macro _ENABLE is defined and is non-zero. + * @retval 0 The macro _ENABLE is not defined or it equals zero. + * + * @note + * This macro intentionally does not implement second expansion level. + * The name of the module to be checked has to be given directly as a parameter. + * And given parameter would be connected with @c _ENABLED postfix directly + * without evaluating its value. + */ +//lint -e491 // Suppers warning 491 "non-standard use of 'defined' preprocessor operator" +#define NRF_MODULE_ENABLED(module) \ + ((defined(module ## _ENABLED) && (module ## _ENABLED)) ? 1 : 0) + /** The upper 8 bits of a 32 bit value */ //lint -emacro(572,MSB) // Suppress warning 572 "Excessive shift value" -#define MSB(a) (((a) & 0xFF000000) >> 24) +#define MSB_32(a) (((a) & 0xFF000000) >> 24) /** The lower 8 bits (of a 32 bit value) */ -#define LSB(a) ((a) & 0x000000FF) +#define LSB_32(a) ((a) & 0x000000FF) /** The upper 8 bits of a 16 bit value */ //lint -emacro(572,MSB_16) // Suppress warning 572 "Excessive shift value" @@ -35,12 +96,51 @@ /*lint -emacro(506, MAX) */ /* Suppress "Constant value Boolean */ #define MAX(a, b) ((a) < (b) ? (b) : (a)) -/** Concatenates two parameters. Useful as a second level of indirection, - * when a parameter can be macro itself. */ -#define CONCAT_2(p1, p2) p1##p2 -/** Concatenates three parameters. Useful as a second level of indirection, - * when a parameter can be macro itself. */ -#define CONCAT_3(p1, p2, p3) p1##p2##p3 +/**@brief Concatenates two parameters. + * + * It realizes two level expansion to make it sure that all the parameters + * are actually expanded before gluing them together. + * + * @param p1 First parameter to concatenating + * @param p2 Second parameter to concatenating + * + * @return Two parameters glued together. + * They have to create correct C mnemonic in other case + * preprocessor error would be generated. + * + * @sa CONCAT_3 + */ +#define CONCAT_2(p1, p2) CONCAT_2_(p1, p2) +/** Auxiliary macro used by @ref CONCAT_2 */ +#define CONCAT_2_(p1, p2) p1##p2 + +/**@brief Concatenates three parameters. + * + * It realizes two level expansion to make it sure that all the parameters + * are actually expanded before gluing them together. + * + * @param p1 First parameter to concatenating + * @param p2 Second parameter to concatenating + * @param p3 Third parameter to concatenating + * + * @return Three parameters glued together. + * They have to create correct C mnemonic in other case + * preprocessor error would be generated. + * + * @sa CONCAT_2 + */ +#define CONCAT_3(p1, p2, p3) CONCAT_3_(p1, p2, p3) +/** Auxiliary macro used by @ref CONCAT_3 */ +#define CONCAT_3_(p1, p2, p3) p1##p2##p3 + +#define NUM_TO_STR_INTERNAL(val) #val +/** Converts numeric value to string. + */ +#define NUM_TO_STR(val) NUM_TO_STR_INTERNAL(val) + +/** Counts number of elements inside the array + */ +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) /**@brief Set a bit in the uint32 word. * @@ -103,5 +203,10 @@ #define UNUSED_VARIABLE(X) ((void)(X)) #define UNUSED_PARAMETER(X) UNUSED_VARIABLE(X) +#define UNUSED_RETURN_VALUE(X) UNUSED_VARIABLE(X) + +#ifdef __cplusplus +} +#endif #endif // NORDIC_COMMON_H__ diff --git a/components/libraries/util/nrf_assert.c b/components/libraries/util/nrf_assert.c index b443bc8..6255ba9 100644 --- a/components/libraries/util/nrf_assert.c +++ b/components/libraries/util/nrf_assert.c @@ -1,22 +1,54 @@ -/* Copyright (c) 2006 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2006 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "nrf_assert.h" +#include "app_error.h" +#include "nordic_common.h" -#if defined(DEBUG_NRF) -void assert_nrf_callback(uint16_t line_num, const uint8_t * file_name) +__WEAK void assert_nrf_callback(uint16_t line_num, const uint8_t * file_name) { - (void) file_name; /* Unused parameter */ - (void) line_num; /* Unused parameter */ - - while (1) ; + assert_info_t assert_info = + { + .line_num = line_num, + .p_file_name = file_name, + }; + app_error_fault_handler(NRF_FAULT_ID_SDK_ASSERT, 0, (uint32_t)(&assert_info)); + + UNUSED_VARIABLE(assert_info); } -#endif /* DEBUG_NRF */ diff --git a/components/libraries/util/nrf_assert.h b/components/libraries/util/nrf_assert.h index a053833..5602d05 100644 --- a/components/libraries/util/nrf_assert.h +++ b/components/libraries/util/nrf_assert.h @@ -1,10 +1,41 @@ -/* - * Copyright (c) 2006 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * +/** + * Copyright (c) 2006 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -15,9 +46,12 @@ #define NRF_ASSERT_H_ #include -#include "compiler_abstraction.h" +#include "nrf.h" +#include "app_error.h" -#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) +#ifdef __cplusplus +extern "C" { +#endif /** @brief Function for handling assertions. * @@ -25,6 +59,10 @@ * @note * This function is called when an assertion has triggered. * + * @note + * This function is deprecated and will be removed in future releases. + * Use app_error_fault_handler instead. + * * * @post * All hardware is put into an idle non-emitting state (in particular the radio is highly @@ -35,25 +73,51 @@ * @param line_num The line number where the assertion is called * @param file_name Pointer to the file name */ +//lint -save -esym(14, assert_nrf_callback) void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name); +//lint -restore -/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ +#if (defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)) +#define NRF_ASSERT_PRESENT 1 +#else +#define NRF_ASSERT_PRESENT 0 +#endif + +//#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) + +/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ /*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \ /** @brief Function for checking intended for production code. * * Check passes if "expr" evaluates to true. */ + +#ifdef _lint #define ASSERT(expr) \ if (expr) \ { \ } \ else \ { \ - assert_nrf_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \ + while(1); \ } -#else -#define ASSERT(expr) //!< Assert empty when disabled -__WEAK void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name); -#endif /* defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) */ +#else //_lint +#define ASSERT(expr) \ +if (NRF_ASSERT_PRESENT) \ +{ \ + if (expr) \ + { \ + } \ + else \ + { \ + assert_nrf_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \ + } \ +} +#endif + + +#ifdef __cplusplus +} +#endif #endif /* NRF_ASSERT_H_ */ diff --git a/components/libraries/util/nrf_bitmask.h b/components/libraries/util/nrf_bitmask.h new file mode 100644 index 0000000..47e1c84 --- /dev/null +++ b/components/libraries/util/nrf_bitmask.h @@ -0,0 +1,149 @@ +/** + * Copyright (c) 2006 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_BITMASK_H +#define NRF_BITMASK_H + +#include "compiler_abstraction.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BITMASK_BYTE_GET(abs_bit) ((abs_bit)/8) +#define BITMASK_RELBIT_GET(abs_bit) ((abs_bit) & 0x00000007) + +/** + * Function for checking if bit in the multi-byte bit mask is set. + * + * @param bit Bit index. + * @param p_mask A pointer to mask with bit fields. + * + * @return 0 if bit is not set, positive value otherwise. + */ +__STATIC_INLINE uint32_t nrf_bitmask_bit_is_set(uint32_t bit, void const * p_mask) +{ + uint8_t const * p_mask8 = (uint8_t const *)p_mask; + uint32_t byte_idx = BITMASK_BYTE_GET(bit); + bit = BITMASK_RELBIT_GET(bit); + return (1 << bit) & p_mask8[byte_idx]; +} + +/** + * Function for setting a bit in the multi-byte bit mask. + * + * @param bit Bit index. + * @param p_mask A pointer to mask with bit fields. + */ +__STATIC_INLINE void nrf_bitmask_bit_set(uint32_t bit, void * p_mask) +{ + uint8_t * p_mask8 = (uint8_t *)p_mask; + uint32_t byte_idx = BITMASK_BYTE_GET(bit); + bit = BITMASK_RELBIT_GET(bit); + p_mask8[byte_idx] |= (1 << bit); +} + +/** + * Function for clearing a bit in the multi-byte bit mask. + * + * @param bit Bit index. + * @param p_mask A pointer to mask with bit fields. + */ +__STATIC_INLINE void nrf_bitmask_bit_clear(uint32_t bit, void * p_mask) +{ + uint8_t * p_mask8 = (uint8_t *)p_mask; + uint32_t byte_idx = BITMASK_BYTE_GET(bit); + bit = BITMASK_RELBIT_GET(bit); + p_mask8[byte_idx] &= ~(1 << bit); +} + +/** + * Function for performing bitwise OR operation on two multi-byte bit masks. + * + * @param p_mask1 A pointer to the first bit mask. + * @param p_mask2 A pointer to the second bit mask. + * @param p_mask_out A pointer to the output bit mask. + * @param length Length of output mask in bytes. + */ +__STATIC_INLINE void nrf_bitmask_masks_or(void const * p_mask1, + void const * p_mask2, + void * p_out_mask, + uint32_t length) +{ + uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1; + uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2; + uint8_t * p_mask8_out = (uint8_t *)p_out_mask; + uint32_t i; + for (i = 0; i < length; i++) + { + p_mask8_out[i] = p_mask8_1[i] | p_mask8_2[i]; + } +} + +/** + * Function for performing bitwise AND operation on two multi-byte bit masks. + * + * @param p_mask1 A pointer to the first bit mask. + * @param p_mask2 A pointer to the second bit mask. + * @param p_mask_out A pointer to the output bit mask. + * @param length Length of output mask in bytes. + */ +__STATIC_INLINE void nrf_bitmask_masks_and(void const * p_mask1, + void const * p_mask2, + void * p_out_mask, + uint32_t length) +{ + uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1; + uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2; + uint8_t * p_mask8_out = (uint8_t *)p_out_mask; + uint32_t i; + for (i = 0; i < length; i++) + { + p_mask8_out[i] = p_mask8_1[i] & p_mask8_2[i]; + } +} + +#ifdef __cplusplus +} +#endif + +#endif //NRF_BITMASK_H diff --git a/components/libraries/util/nrf_log.c b/components/libraries/util/nrf_log.c deleted file mode 100644 index 32016ed..0000000 --- a/components/libraries/util/nrf_log.c +++ /dev/null @@ -1,380 +0,0 @@ -#include "nrf.h" -#include "nrf_log.h" -#include "nrf_error.h" -#include -#include -#include - -#if NRF_LOG_USES_RTT == 1 - -#include -#include - -static char buf_normal_up[BUFFER_SIZE_UP]; -static char buf_down[BUFFER_SIZE_DOWN]; - -uint32_t log_rtt_init(void) -{ - if(SEGGER_RTT_ConfigUpBuffer(LOG_TERMINAL_NORMAL, "Normal", buf_normal_up, BUFFER_SIZE_UP, SEGGER_RTT_MODE_NO_BLOCK_SKIP) != 0) - { - return NRF_ERROR_INVALID_STATE; - } - - if(SEGGER_RTT_ConfigDownBuffer(LOG_TERMINAL_INPUT, "Input", buf_down, BUFFER_SIZE_DOWN, SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL) != 0) - { - return NRF_ERROR_INVALID_STATE; - } - - return NRF_SUCCESS; -} - -// Forward declaration of SEGGER RTT vprintf function -int SEGGER_RTT_vprintf(unsigned BufferIndex, const char * sFormat, va_list * pParamList); - -void log_rtt_printf(int terminal_index, char * format_msg, ...) -{ - va_list p_args = {0}; - //lint -save -e526 -e628 - va_start(p_args, format_msg); - (void)SEGGER_RTT_vprintf(terminal_index, format_msg, &p_args); - va_end(p_args); - //lint -restore -} - -__INLINE void log_rtt_write_string(int terminal_index, int num_args, ...) -{ - const char* msg; - va_list p_args = {0}; - //lint -save -e516 - va_start(p_args, num_args); - //lint -restore - - for(int i = 0; i < num_args; i++) - { - //lint -save -e26 -e10 -e64 -e526 -e628 - msg = va_arg(p_args, const char*); - //lint -restore - (void)SEGGER_RTT_WriteString(terminal_index, msg); - } - va_end(p_args); -} - -void log_rtt_write_hex(int terminal_index, uint32_t value) -{ - char temp[11]; - temp[0] = '0'; - temp[1] = 'x'; - temp[10] = 0; // Null termination - uint8_t nibble; - uint8_t i = 8; - - while(i-- != 0) - { - nibble = (value >> (4 * i)) & 0x0F; - temp[9-i] = (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble); - } - - (void)SEGGER_RTT_WriteString(terminal_index, temp); -} - -void log_rtt_write_hex_char(int terminal_index, uint8_t value) -{ - char temp[3]; - temp[2] = 0; // Null termination - uint8_t nibble; - uint8_t i = 2; - - while(i-- != 0) - { - nibble = (value >> (4 * i)) & 0x0F; - temp[1-i] = (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble); - } - - (void)SEGGER_RTT_WriteString(terminal_index, temp); -} - -__INLINE int log_rtt_has_input() -{ - return SEGGER_RTT_HasKey(); -} - -uint32_t log_rtt_read_input(char * c) -{ - int r; - - r = SEGGER_RTT_Read(LOG_TERMINAL_INPUT, c, 1); - if(r == 1) - return NRF_SUCCESS; - else - return NRF_ERROR_NULL; -} - -#endif // LOG_USES_RTT == 1 - -#if NRF_LOG_USES_UART == 1 - -#include "app_uart.h" -#include "app_error.h" -#include -#include -#include "nrf.h" -#include "bsp.h" - -#define MAX_TEST_DATA_BYTES (15U) /**< max number of test bytes to be used for tx and rx. */ -#define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */ -#define UART_RX_BUF_SIZE 1 /**< UART RX buffer size. */ - -void uart_error_handle(app_uart_evt_t * p_event) -{ - if (p_event->evt_type == APP_UART_COMMUNICATION_ERROR) - { - APP_ERROR_HANDLER(p_event->data.error_communication); - } - else if (p_event->evt_type == APP_UART_FIFO_ERROR) - { - APP_ERROR_HANDLER(p_event->data.error_code); - } -} - -uint32_t log_uart_init() -{ - uint32_t err_code; - const app_uart_comm_params_t comm_params = - { - RX_PIN_NUMBER, - TX_PIN_NUMBER, - RTS_PIN_NUMBER, - CTS_PIN_NUMBER, - APP_UART_FLOW_CONTROL_ENABLED, - false, - UART_BAUDRATE_BAUDRATE_Baud38400 - }; - - APP_UART_FIFO_INIT(&comm_params, - UART_RX_BUF_SIZE, - UART_TX_BUF_SIZE, - uart_error_handle, - APP_IRQ_PRIORITY_LOW, - err_code); - - return err_code; -} - -void log_uart_printf(const char * format_msg, ...) -{ - va_list p_args; - va_start(p_args, format_msg); - vprintf(format_msg, p_args); - va_end(p_args); -} - -__INLINE void log_uart_write_string_many(int num_args, ...) -{ - const char* msg; - va_list p_args; - va_start(p_args, num_args); - - for(int i = 0; i < num_args; i++) - { - msg = va_arg(p_args, const char*); - log_uart_write_string(msg); - } - va_end(p_args); -} - -__INLINE void log_uart_write_string(const char* msg) -{ - while( *msg ) - { - app_uart_put(*msg++); - } -} - -void log_uart_write_hex(uint32_t value) -{ - uint8_t nibble; - uint8_t i = 8; - - app_uart_put('0'); - app_uart_put('x'); - while( i-- != 0 ) - { - nibble = (value >> (4 * i)) & 0x0F; - app_uart_put( (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble) ); - } -} - -void log_uart_write_hex_char(uint8_t c) -{ - uint8_t nibble; - uint8_t i = 2; - - while( i-- != 0 ) - { - nibble = (c >> (4 * i)) & 0x0F; - app_uart_put( (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble) ); - } -} - -__INLINE int log_uart_has_input() -{ - return 0; -} - -uint32_t log_uart_read_input(char * c) -{ - return NRF_ERROR_NULL; -} - -#endif // NRF_LOG_USES_UART == 1 - -#if NRF_LOG_USES_RAW_UART == 1 - -#include "nrf_gpio.h" -#include -#include -#include "bsp.h" - -uint32_t log_raw_uart_init() -{ - // Disable UART - NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Disabled; - - // Configure RX/TX pins - nrf_gpio_cfg_output( TX_PIN_NUMBER ); - nrf_gpio_cfg_input(RX_PIN_NUMBER, NRF_GPIO_PIN_NOPULL); - - // Set a default baud rate of 38400 - NRF_UART0->PSELTXD = TX_PIN_NUMBER; - NRF_UART0->BAUDRATE = UART_BAUDRATE_BAUDRATE_Baud38400; - - NRF_UART0->PSELRTS = 0xFFFFFFFF; - NRF_UART0->PSELCTS = 0xFFFFFFFF; - - // Disable parity and interrupt - NRF_UART0->CONFIG = (UART_CONFIG_PARITY_Excluded << UART_CONFIG_PARITY_Pos ); - NRF_UART0->CONFIG |= (UART_CONFIG_HWFC_Disabled << UART_CONFIG_HWFC_Pos ); - - // Re-enable the UART - NRF_UART0->ENABLE = UART_ENABLE_ENABLE_Enabled; - NRF_UART0->INTENSET = 0; - NRF_UART0->TASKS_STARTTX = 1; - NRF_UART0->TASKS_STARTRX = 1; - - return NRF_SUCCESS; -} - -void log_raw_uart_printf(const char * format_msg, ...) -{ - static char buffer[256]; - - va_list p_args; - va_start(p_args, format_msg); - sprintf(buffer, format_msg, p_args); - va_end(p_args); - - log_raw_uart_write_string(buffer); -} - -__INLINE void log_raw_uart_write_char(const char c) -{ - NRF_UART0->TXD = c; - while( NRF_UART0->EVENTS_TXDRDY != 1 ); - NRF_UART0->EVENTS_TXDRDY = 0; -} - -__INLINE void log_raw_uart_write_string_many(int num_args, ...) -{ - - const char* msg; - va_list p_args; - va_start(p_args, num_args); - - for(int i = 0; i < num_args; i++) - { - msg = va_arg(p_args, const char*); - log_raw_uart_write_string(msg); - } - va_end(p_args); -} - -__INLINE void log_raw_uart_write_string(const char* msg) -{ - while( *msg ) - { - NRF_UART0->TXD = *msg++; - while( NRF_UART0->EVENTS_TXDRDY != 1 ); - NRF_UART0->EVENTS_TXDRDY = 0; - } -} - -void log_raw_uart_write_hex(uint32_t value) -{ - uint8_t nibble; - uint8_t i = 8; - - log_raw_uart_write_string( "0x" ); - while( i-- != 0 ) - { - nibble = (value >> (4 * i)) & 0x0F; - log_raw_uart_write_char( (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble) ); - } -} - -void log_raw_uart_write_hex_char(uint8_t c) -{ - uint8_t nibble; - uint8_t i = 2; - - while( i-- != 0 ) - { - nibble = (c >> (4 * i)) & 0x0F; - log_raw_uart_write_hex( (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble) ); - } -} - -__INLINE int log_raw_uart_has_input() -{ - return 0; -} - -uint32_t log_raw_uart_read_input(char * c) -{ - return NRF_ERROR_NULL; -} - -#endif // NRF_LOG_USES_RAW_UART == 1 - - -const char* log_hex_char(const char c) -{ - static volatile char hex_string[3]; - hex_string[2] = 0; // Null termination - uint8_t nibble; - uint8_t i = 2; - while(i-- != 0) - { - nibble = (c >> (4 * i)) & 0x0F; - hex_string[1-i] = (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble); - } - return (const char*) hex_string; -} - -const char* log_hex(uint32_t value) -{ - static volatile char hex_string[11]; - hex_string[0] = '0'; - hex_string[1] = 'x'; - hex_string[10] = 0; - uint8_t nibble; - uint8_t i = 8; - - while(i-- != 0) - { - nibble = (value >> (4 * i)) & 0x0F; - hex_string[9-i] = (nibble > 9) ? ('A' + nibble - 10) : ('0' + nibble); - } - - return (const char*)hex_string; -} - diff --git a/components/libraries/util/nrf_log.h b/components/libraries/util/nrf_log.h deleted file mode 100644 index 1419cbb..0000000 --- a/components/libraries/util/nrf_log.h +++ /dev/null @@ -1,518 +0,0 @@ -#ifndef NRF_LOG_H_ -#define NRF_LOG_H_ - -#include -#include -#include - -#define NUM_VA_ARGS(...) (sizeof((const char*[]){ 0, ##__VA_ARGS__ })/sizeof(const char*)-1) - -#ifndef NRF_LOG_USES_RTT -#define NRF_LOG_USES_RTT 0 -#endif - -#ifndef NRF_LOG_USES_UART -#define NRF_LOG_USES_UART 0 -#endif - -#ifndef NRF_LOG_USES_RAW_UART -#define NRF_LOG_USES_RAW_UART 0 -#endif - -#if NRF_LOG_USES_RTT == 1 - -#define LOG_TERMINAL_NORMAL (0) -#define LOG_TERMINAL_ERROR (1) -#define LOG_TERMINAL_INPUT (0) - -/**@brief Function to initialize Segger Real-Time Terminal logger - * - * @details The Segger Real-Time Terminal stores I/O data in a ring buffer - * consumable by the onboard JLink debugging probe. - * To learn more about the Segger RTT, please visit the following web-page: - * Segger RTT website - * - * @warning This function is only available when LOG_USES_RTT is defined as 1 - * - * @warning Do not call this function directly. Use the macro NRF_LOG_INIT - * - * @returns NRF_SUCCESS If initialization was successful - * @returns NRF_ERROR - */ -uint32_t log_rtt_init(void); - -/**@brief Function to write printf string using Segger Real-Time Terminal logger - * - * @details The printf implementation is more efficient than the standard implementation - * To learn more about the Segger RTT, please visit the following web-page: - * Segger RTT website - * - * @warning This function is only available when LOG_USES_RTT is defined as 1 - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG/NRF_LOG_DEBUG/NRF_LOG_ERROR - * - * @param terminal_index Segger RTT terminal index to use as output - * format_msg Printf format string - * ... Variable length arguments - */ -void log_rtt_printf(int terminal_index, char * format_msg, ...); - -/**@brief Function to write string using Segger Real-Time Terminal logger - * - * @details The string sent in must be null-terminated but the null-termination will not be stored - * in the ring-buffer. - * The impact of running this application should be very low compared to writing to UART - * To learn more about the Segger RTT, please visit the following web-page: - * Segger RTT website - * - * @warning This function is only available when LOG_USES_RTT is defined as 1 - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG_STR/NRF_LOG_DEBUG_STR/NRF_LOG_ERROR_STR - * - * @param terminal_index Segger RTT terminal index to use as output - * @param num_args Number of arguments - * @param msg Null-terminated character array to use be printed - */ -void log_rtt_write_string(int terminal_index, int num_args, ...); - -/**@brief Function to write integer as hex using Segger Real-Time Terminal logger - * - * @details Insert - * To learn more about the Segger RTT, please visit the following web-page: - * Segger RTT website - * - * @warning This function is only available when LOG_USES_RTT is defined as 1 - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG_HEX/NRF_LOG_DEBUG_HEX/NRF_LOG_ERROR_HEX - * - * @param terminal_index Segger RTT terminal index to use as output - * @param value Integer value to be printed has hex - */ -void log_rtt_write_hex(int terminal_index, uint32_t value); - -/**@brief Function to write character as hex using Segger Real-Time Terminal logger - * - * @details Insert - * To learn more about the Segger RTT, please visit the following web-page: - * Segger RTT website - * - * @warning This function is only available when LOG_USES_RTT is defined as 1 - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG_HEX_CHAR/NRF_LOG_HEX_CHAR_DEBUG/NRF_LOG_HEX_CHAR_ERROR - * - * @param terminal_index Segger RTT terminal index to use as output - * @param value Character to print as hex - */ -void log_rtt_write_hex_char(int terminal_index, uint8_t value); - -/**@brief Function to check if there is available data in the input-buffer - * - * @retval 1 if character(s) available to read - * @retval 0 if no character(s) available to read - */ -int log_rtt_has_input(void); - -/**@brief Function to read one character from the input-buffer - * - * @param[out] pointer to put the character to store - * - * @retval NRF_SUCCESS if character was read out - * @retval NRF_ERROR_INVALID_DATA if a character could not be read - */ -uint32_t log_rtt_read_input(char* p_char); - -#define NRF_LOG_INIT() log_rtt_init() /*!< Initialize the nrf_log submodule*/ - -#define NRF_LOG_PRINTF(...) log_rtt_printf(LOG_TERMINAL_NORMAL, ##__VA_ARGS__) /*!< nrf log utilizing printf*/ -#define NRF_LOG_PRINTF_DEBUG(...) log_rtt_printf(LOG_TERMINAL_NORMAL, ##__VA_ARGS__) /*!< nrf log utilzinging printf. Will only log if DEBUG is set*/ -#define NRF_LOG_PRINTF_ERROR(...) log_rtt_printf(LOG_TERMINAL_ERROR, ##__VA_ARGS__) /*!< nrf log utilizing printf */ - -#define NRF_LOG(...) log_rtt_write_string(LOG_TERMINAL_NORMAL, NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< nrf log for null-terminated strings */ -#define NRF_LOG_DEBUG(...) log_rtt_write_string(LOG_TERMINAL_NORMAL, NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< nrf log for null-terminated strings. Will only log if DEBUG is set*/ -#define NRF_LOG_ERROR(...) log_rtt_write_string(LOG_TERMINAL_ERROR, NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< nrf log for null-terminated strings.*/ - -#define NRF_LOG_HEX(val) log_rtt_write_hex(LOG_TERMINAL_NORMAL, val) /*!< nrf log for integers logged as hex. Formats as 0x89ABCDEF (ex)*/ -#define NRF_LOG_HEX_DEBUG(val) log_rtt_write_hex(LOG_TERMINAL_NORMAL, val) /*!< nrf log for integers logged as hex. Formats as 0x89ABCDEF (ex). Will only log if DEBUG is set*/ -#define NRF_LOG_HEX_ERROR(val) log_rtt_write_hex(LOG_TERMINAL_ERROR, val) /*!< nrf log for integers logged as hex. Formats as 0x89ABCDEF (ex).*/ - -#define NRF_LOG_HEX_CHAR(val) log_rtt_write_hex_char(LOG_TERMINAL_NORMAL, val) /*!< nrf log characters logged as hex. Formats as AA (ex).*/ -#define NRF_LOG_HEX_CHAR_DEBUG(val) log_rtt_write_hex_char(LOG_TERMINAL_NORMAL, val) /*!< nrf log characters logged as hex. Formats as AA (ex).Will only log if DEBUG is set*/ -#define NRF_LOG_HEX_CHAR_ERROR(val) log_rtt_write_hex_char(LOG_TERMINAL_ERROR, val) /*!< nrf log characters logged as hex. Formats as AA (ex).*/ - -#define NRF_LOG_HAS_INPUT() log_rtt_has_input() /*!< Check if input buffer has unconsumed characters */ -#define NRF_LOG_READ_INPUT(p_char) log_rtt_read_input(p_char) /*!< Consume character from input-buffer */ - -#if !defined(DEBUG) && !defined(DOXYGEN) - -#undef NRF_LOG_DEBUG -#define NRF_LOG_DEBUG(...) - -#undef NRF_LOG_STR_DEBUG -#define NRF_LOG_STR_DEBUG(...) - -#undef NRF_LOG_HEX_DEBUG -#define NRF_LOG_HEX_DEBUG(...) - -#undef NRF_LOG_HEX_CHAR_DEBUG -#define NRF_LOG_HEX_CHAR_DEBUG(...) - -#endif // !defined(DEBUG) && !defined(DOXYGEN) - -#elif NRF_LOG_USES_UART == 1 - -/**@brief Function to initialize UART logger - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning Do not call this function directly. Use the macro NRF_LOG_INIT - * - * @returns NRF_SUCCESS If initialization was successful - * @returns NRF_ERROR - */ -uint32_t log_uart_init(void); - -/**@brief Function to log to uart using printf - * - * @details The Segger RTT has its own implementation of printf - * that is more efficient than the standard - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning This function is non-blocking. If too much data is sent to the UART, - * some characters may be skipped - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG/NRF_LOG_DEBUG/NRF_LOG_ERROR - * - * @params format_msg printf format string - * @params ... variable length arguments - */ -void log_uart_printf(const char * format_msg, ...); - -/**@brief Function to log single character - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @params c character - */ -void log_uart_write_char(const char c); - -/**@brief Function to log null-terminated strings - * - * @defails This function is more efficient than using printf - * The null-termination will not be logged - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG/NRF_LOG_DEBUG/NRF_LOG_ERROR - * - * @params str Null-terminated string - */ -void log_uart_write_string_many(int num_args, ...); - - -/**@brief Function to log null-terminated string - * - * @defails This function is more efficient than using printf - * The null-termination will not be logged - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG/NRF_LOG_DEBUG/NRF_LOG_ERROR - * - * @params str Null-terminated string - */ -void log_uart_write_string(const char* msg); - - -/**@brief Function to log integer value as string - * - * @details The formatted data sent on the UART will be formatted as 0x89ABCDEF (example) - * This function is more efficient than printf - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning This function is non-blocking. If too much data is sent to the UART, - * some characters may be skipped - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG_HEX/NRF_LOG_DEBUG_HEX/NRF_LOG_ERROR_HEX - * - * @param value Integer value to be printed as hex - */ -void log_uart_write_hex(uint32_t value); - -/**@brief Function to log single character using hex formatting - * - * @details The formatted string sent on the UART will be formatted as AA (ex.) - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning This function is non-blocking. If too much data is sent to the UART, - * some characters may be skipped - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG_HEX_CHAR/NRF_LOG_DEBUG_HEX_CHAR/NRF_LOG_ERROR_HEX_CHAR - */ -void log_uart_write_hex_char(uint8_t c); - -/**@brief Function to check if there is available data in the input-buffer - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning Do not call this function directly. Use NRF_LOG_HAS_INPUT - * - * @retval 1 if character(s) available to read - * @retval 0 if no character(s) available to read - */ -int log_uart_has_input(void); - -/**@brief Function to read one character from the input-buffer - * - * @param[out] pointer to put the character to store - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning Do not call this function directly. Use NRF_LOG_HAS_INPUT - * - * @retval NRF_SUCCESS if character was read out - * @retval NRF_ERROR_INVALID_DATA if a character could not be read - */ -uint32_t log_uart_read_input(char* p_char); - - -#define NRF_LOG_INIT() log_uart_init() /*!< Initialize the nrf_log submodule*/ - -#define NRF_LOG_PRINTF(...) log_uart_printf(__VA_ARGS__) /*!< nrf log utilizing printf*/ -#define NRF_LOG_PRINTF_DEBUG(...) log_uart_printf(__VA_ARGS__) /*!< nrf log utilzinging printf. Will only log if DEBUG is set*/ -#define NRF_LOG_PRINTF_ERROR(...) log_uart_printf(__VA_ARGS__) /*!< nrf log utilizing printf */ - -#define NRF_LOG(...) log_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< nrf log for null-terminated strings */ -#define NRF_LOG_DEBUG(...) log_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< nrf log for null-terminated strings. Will only log if DEBUG is set*/ -#define NRF_LOG_ERROR(...) log_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< nrf log for null-terminated strings.*/ - -#define NRF_LOG_HEX(val) log_uart_write_hex(val) /*!< nrf log for integers logged as hex. Formats as 0x89ABCDEF (ex)*/ -#define NRF_LOG_HEX_DEBUG(val) log_uart_write_hex(val) /*!< nrf log for integers logged as hex. Formats as 0x89ABCDEF (ex). Will only log if DEBUG is set*/ -#define NRF_LOG_HEX_ERROR(val) log_uart_write_hex(val) /*!< nrf log for integers logged as hex. Formats as 0x89ABCDEF (ex).*/ - -#define NRF_LOG_HEX_CHAR(val) log_uart_write_hex_char(val) /*!< nrf log characters logged as hex. Formats as AA (ex).*/ -#define NRF_LOG_HEX_CHAR_DEBUG(val) log_uart_write_hex_char(val) /*!< nrf log characters logged as hex. Formats as AA (ex).Will only log if DEBUG is set*/ -#define NRF_LOG_HEX_CHAR_ERROR(val) log_uart_write_hex_char(val) /*!< nrf log characters logged as hex. Formats as AA (ex).*/ - -#define NRF_LOG_HAS_INPUT() log_uart_has_input() /*!< Check if input buffer has unconsumed characters */ -#define NRF_LOG_READ_INPUT(p_char) log_uart_read_input(p_char) /*!< Consume character from input-buffer */ - -#if !defined(DEBUG) && !defined(DOXYGEN) - -#undef NRF_LOG_DEBUG -#define NRF_LOG_DEBUG(...) - -#undef NRF_LOG_STR_DEBUG -#define NRF_LOG_STR_DEBUG(...) - -#undef NRF_LOG_HEX_DEBUG -#define NRF_LOG_HEX_DEBUG(...) - -#undef NRF_LOG_HEX_CHAR_DEBUG -#define NRF_LOG_HEX_CHAR_DEBUG(...) - -#endif // !defined(DEBUG) && !defined(DOXYGEN) - -#elif NRF_LOG_USES_RAW_UART - -/**@brief Function to initialize raw UART logger - * - * @warning Do not call this function directly. Use the macro NRF_LOG_INIT - * - * @returns NRF_SUCCESS If initialization was successful - * @returns NRF_ERROR - */ -uint32_t log_raw_uart_init(void); - -/**@brief Function to log to raw uart using printf - * - * @details The Segger RTT has its own implementation of printf - * that is more efficient than the standard - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning This function is non-blocking. If too much data is sent to the UART, - * some characters may be skipped - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG/NRF_LOG_DEBUG/NRF_LOG_ERROR - * - * @params format_msg printf format string - * @params ... variable length arguments - */ -void log_raw_uart_printf(const char * format_msg, ...); - -/**@brief Function to log single character - * - * @params c character - */ -void log_raw_uart_write_char(const char c); - -/**@brief Function to log null-terminated strings - * - * @defails This function is more efficient than using printf - * The null-termination will not be logged - * - * @params str Null-terminated string - */ -void log_raw_uart_write_string_many(int num_args, ...); - - -/**@brief Function to log null-terminated string - * - * @defails This function is more efficient than using printf - * The null-termination will not be logged - * - * @params str Null-terminated string - */ -void log_raw_uart_write_string(const char * str); - -/**@brief Function to log integer value as string - * - * @details The formatted data sent on the UART will be formatted as 0x89ABCDEF (example) - * This function is more efficient than printf - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning This function is non-blocking. If too much data is sent to the UART, - * some characters may be skipped - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG_HEX/NRF_LOG_DEBUG_HEX/NRF_LOG_ERROR_HEX - * - * @param value Integer value to be printed as hex - */ -void log_raw_uart_write_hex(uint32_t value); - -/**@brief Function to log single character using hex formatting - * - * @details The formatted string sent on the UART will be formatted as AA (ex.) - * - * @warning This function is only available when LOG_USES_UART is defined as 1 - * - * @warning This function is non-blocking. If too much data is sent to the UART, - * some characters may be skipped - * - * @warning Do not call this function directly. Use one of the following macros: - * NRF_LOG_HEX_CHAR/NRF_LOG_DEBUG_HEX_CHAR/NRF_LOG_ERROR_HEX_CHAR - */ -void log_raw_uart_write_hex_char(uint8_t c); - -/**@brief Function to check if there is available data in the input-buffer - * - * @retval 1 if character(s) available to read - * @retval 0 if no character(s) available to read - */ -int log_raw_uart_has_input(void); - -/**@brief Function to read one character from the input-buffer - * - * @param[out] pointer to put the character to store - * - * @retval NRF_SUCCESS if character was read out - * @retval NRF_ERROR_INVALID_DATA if a character could not be read - */ -uint32_t log_raw_uart_read_input(char* p_char); - -#define NRF_LOG_INIT() log_raw_uart_init() /*!< Initialize the nrf_log submodule*/ - -#define NRF_LOG_PRINTF(...) log_raw_uart_printf(__VA_ARGS__) /*!< nrf log utilizing printf*/ -#define NRF_LOG_PRINTF_DEBUG(...) log_raw_uart_printf(__VA_ARGS__) /*!< nrf log utilzinging printf. Will only log if DEBUG is set*/ -#define NRF_LOG_PRINTF_ERROR(...) log_raw_uart_printf(__VA_ARGS__) /*!< nrf log utilizing printf */ - -#define NRF_LOG(...) log_raw_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< nrf log for null-terminated strings */ -#define NRF_LOG_DEBUG(...) log_raw_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< nrf log for null-terminated strings. Will only log if DEBUG is set*/ -#define NRF_LOG_ERROR(...) log_raw_uart_write_string_many(NUM_VA_ARGS(__VA_ARGS__), ##__VA_ARGS__) /*!< nrf log for null-terminated strings.*/ - -#define NRF_LOG_HEX(val) log_raw_uart_write_hex(val) /*!< nrf log for integers logged as hex. Formats as 0x89ABCDEF (ex)*/ -#define NRF_LOG_HEX_DEBUG(val) log_raw_uart_write_hex(val) /*!< nrf log for integers logged as hex. Formats as 0x89ABCDEF (ex). Will only log if DEBUG is set*/ -#define NRF_LOG_HEX_ERROR(val) log_raw_uart_write_hex(val) /*!< nrf log for integers logged as hex. Formats as 0x89ABCDEF (ex).*/ - -#define NRF_LOG_HEX_CHAR(val) log_raw_uart_write_hex_char(val) /*!< nrf log characters logged as hex. Formats as AB (ex).*/ -#define NRF_LOG_HEX_CHAR_DEBUG(val) log_raw_uart_write_hex_char(val) /*!< nrf log characters logged as hex. Formats as AB (ex).Will only log if DEBUG is set*/ -#define NRF_LOG_HEX_CHAR_ERROR(val) log_raw_uart_write_hex_char(val) /*!< nrf log characters logged as hex. Formats as AB (ex).*/ - -#define NRF_LOG_HAS_INPUT() log_raw_uart_has_input() /*!< Check if input buffer has unconsumed characters */ -#define NRF_LOG_READ_INPUT(p_char) log_raw_uart_read_input(p_char) /*!< Consume character from input-buffer */ - -#if !defined(DEBUG) && !defined(DOXYGEN) - -#undef NRF_LOG_DEBUG -#define NRF_LOG_DEBUG(...) - -#undef NRF_LOG_STR_DEBUG -#define NRF_LOG_STR_DEBUG(...) - -#undef NRF_LOG_HEX_DEBUG -#define NRF_LOG_HEX_DEBUG(...) - -#undef NRF_LOG_HEX_CHAR_DEBUG -#define NRF_LOG_HEX_CHAR_DEBUG(...) - -#endif // !defined(DEBUG) && !defined(DOXYGEN) - -#else - -#include "nrf_error.h" -#include "nordic_common.h" - -// Empty definitions - -__INLINE int dummy_func(void* ignore) -{ - UNUSED_PARAMETER(ignore); - return NRF_SUCCESS; -} - -#define NRF_LOG_INIT() dummy_func(0) -#define NRF_LOG(...) -#define NRF_LOG_DEBUG(...) -#define NRF_LOG_ERROR(...) - -#define NRF_LOG_PRINTF(...) -#define NRF_LOG_PRINTF_DEBUG(...) -#define NRF_LOG_PRINTF_ERROR(...) - -#define NRF_LOG_HEX(val) -#define NRF_LOG_HEX_DEBUG(val) -#define NRF_LOG_HEX_ERROR(val) - -#define NRF_LOG_HEX_CHAR(val) -#define NRF_LOG_HEX_CHAR_DEBUG(val) -#define NRF_LOG_HEX_CHAR_ERROR(val) - -#define NRF_LOG_HAS_INPUT() 0 -#define NRF_LOG_READ_INPUT(ignore) dummy_func(ignore) - -#endif - -/**@brief Function to write hex-values - * - * @warning This function is by no means tread-safe. It is written for convenience - * If you log from different application-contexts you may get different results - * - * @returns NULL by default - */ -const char* log_hex(uint32_t value); - -/**@brief Function to write hex-char - * - * @warning This function is by no means tread-safe. It is written for convenience - * If you log from different application-contexts you may get different results - * - * @returns NULL by default - */ -const char* log_hex_char(const char value); - -#endif // NRF_LOG_H_ diff --git a/components/libraries/util/sdk_common.h b/components/libraries/util/sdk_common.h index 8e4644c..cd13ab5 100644 --- a/components/libraries/util/sdk_common.h +++ b/components/libraries/util/sdk_common.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @cond */ @@ -15,7 +43,7 @@ * * @ingroup experimental_api * @defgroup sdk_common SDK Common Header - * @breif All common headers needed for SDK examples will be included here so that application + * @brief All common headers needed for SDK examples will be included here so that application * developer does not have to include headers on him/herself. * @{ */ @@ -26,13 +54,25 @@ #include #include #include +#include "sdk_config.h" #include "nordic_common.h" #include "compiler_abstraction.h" #include "sdk_os.h" #include "sdk_errors.h" #include "app_util.h" +#include "sdk_macros.h" + +#ifdef __cplusplus +extern "C" { +#endif + /** @} */ /** @endcond */ + +#ifdef __cplusplus +} +#endif + #endif // SDK_COMMON_H__ diff --git a/components/libraries/util/sdk_errors.c b/components/libraries/util/sdk_errors.c new file mode 100644 index 0000000..8f7031d --- /dev/null +++ b/components/libraries/util/sdk_errors.c @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_errors.h" +#include "nordic_common.h" + +#if defined(NRF_LOG_ENABLED) && NRF_LOG_ENABLED +/** + * @defgroup err_strings Arrays with error codes as strings. + * @{ + */ +const char * m_sdk_errors_name[ERR_NAMES_SIZE] = +{ + "NRF_SUCCESS", + "NRF_ERROR_SVC_HANDLER_MISSING", + "NRF_ERROR_SOFTDEVICE_NOT_ENABLED", + "NRF_ERROR_INTERNAL", + "NRF_ERROR_NO_MEM", + "NRF_ERROR_NOT_FOUND", + "NRF_ERROR_NOT_SUPPORTED", + "NRF_ERROR_INVALID_PARAM", + "NRF_ERROR_INVALID_STATE", + "NRF_ERROR_INVALID_LENGTH", + "NRF_ERROR_INVALID_FLAGS", + "NRF_ERROR_INVALID_DATA", + "NRF_ERROR_DATA_SIZE", + "NRF_ERROR_TIMEOUT", + "NRF_ERROR_NULL", + "NRF_ERROR_FORBIDDEN", + "NRF_ERROR_INVALID_ADDR", + "NRF_ERROR_BUSY" +}; + +const char * m_sdk_errors_name_common[ERR_NAMES_COMMON_SIZE] = +{ + "NRF_ERROR_MODULE_NOT_INITIALZED", + "NRF_ERROR_MUTEX_INIT_FAILED", + "NRF_ERROR_MUTEX_LOCK_FAILED", + "NRF_ERROR_MUTEX_UNLOCK_FAILED", + "NRF_ERROR_MUTEX_COND_INIT_FAILED", + "NRF_ERROR_MODULE_ALREADY_INITIALIZED", + "NRF_ERROR_STORAGE_FULL", + "NRF_ERROR_API_NOT_IMPLEMENTED", + "NRF_ERROR_FEATURE_NOT_ENABLED" +}; + +const char * m_sdk_errors_name_twi[ERR_NAMES_TWI_SIZE] = +{ + "NRF_ERROR_DRV_TWI_ERR_OVERRUN", + "NRF_ERROR_DRV_TWI_ERR_ANACK", + "NRF_ERROR_DRV_TWI_ERR_DNACK" +}; +/* @} */ +#endif // NRF_LOG_ENABLED diff --git a/components/libraries/util/sdk_errors.h b/components/libraries/util/sdk_errors.h index 757c10f..84838e0 100644 --- a/components/libraries/util/sdk_errors.h +++ b/components/libraries/util/sdk_errors.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -21,9 +49,9 @@ * are used to provide the cause or nature of error. Each module is assigned a 16-bit * unsigned integer. Which it will use to identify all errors that occurred in it. 16-bit * LSB range is with module id as the MSB in the 32-bit error code is reserved for the - * module. As an example, if 0x8800 identifies a certain SDK module, all values from + * module. As an example, if 0x8800 identifies a certain SDK module, all values from * 0x88000000 - 0x8800FFFF are reserved for this module. - * It should be noted that common error reasons have been assigned values to make it + * It should be noted that common error reasons have been assigned values to make it * possible to decode error reason easily. As an example, lets module uninitialized has * been assigned an error code 0x000A0. Then, if application encounters an error code * 0xZZZZ00A0, it knows that it accessing a certain module without initializing it. @@ -35,7 +63,7 @@ * A range is reserved for application as well, it can use this range for defining * application specific errors. * - * @note Success code, NRF_SUCCESS, does not include any module identifier. + * @note Success code, NRF_SUCCESS, does not include any module identifier. */ @@ -44,21 +72,27 @@ #include #include "nrf_error.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif /** * @defgroup sdk_err_base Base defined for SDK Modules * @{ */ -#define SDK_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x8000) /**< Base value defined for SDK module identifiers. */ -#define SDK_COMMON_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x0080) /**< Base error value to be used for SDK error values. */ +#define NRF_ERROR_SDK_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x8000) /**< Base value defined for SDK module identifiers. */ +#define NRF_ERROR_SDK_COMMON_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x0080) /**< Base error value to be used for SDK error values. */ /* @} */ /** * @defgroup sdk_module_codes Codes reserved as identification for module where the error occurred. * @{ */ -#define DEVICE_MANAGER_ERR_BASE (0x8000) -#define MEMORY_MANAGER_ERR_BASE (0x8100) +#define NRF_ERROR_MEMORY_MANAGER_ERR_BASE (0x8100) +#define NRF_ERROR_PERIPH_DRIVERS_ERR_BASE (0x8200) +#define NRF_ERROR_GAZELLE_ERR_BASE (0x8300) /* @} */ @@ -66,34 +100,34 @@ * @defgroup sdk_iot_errors Codes reserved as identification for IoT errors. * @{ */ -#define IOT_ERR_BASE_START (0xA000) -#define IOT_ERR_BASE_STOP (0xAFFF) +#define NRF_ERROR_IOT_ERR_BASE_START (0xA000) +#define NRF_ERROR_IOT_ERR_BASE_STOP (0xAFFF) /* @} */ - + /** * @defgroup sdk_common_errors Codes reserved as identification for common errors. * @{ */ -#define MODULE_NOT_INITIALZED (SDK_COMMON_ERROR_BASE + 0x0000) -#define MUTEX_INIT_FAILED (SDK_COMMON_ERROR_BASE + 0x0001) -#define MUTEX_LOCK_FAILED (SDK_COMMON_ERROR_BASE + 0x0002) -#define MUTEX_UNLOCK_FAILED (SDK_COMMON_ERROR_BASE + 0x0003) -#define MUTEX_COND_INIT_FAILED (SDK_COMMON_ERROR_BASE + 0x0004) -#define MODULE_ALREADY_INITIALIZED (SDK_COMMON_ERROR_BASE + 0x0005) -#define API_NOT_IMPLEMENTED (SDK_COMMON_ERROR_BASE + 0x0010) -#define FEATURE_NOT_ENABLED (SDK_COMMON_ERROR_BASE + 0x0011) +#define NRF_ERROR_MODULE_NOT_INITIALZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0000) +#define NRF_ERROR_MUTEX_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0001) +#define NRF_ERROR_MUTEX_LOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0002) +#define NRF_ERROR_MUTEX_UNLOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0003) +#define NRF_ERROR_MUTEX_COND_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0004) +#define NRF_ERROR_MODULE_ALREADY_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0005) +#define NRF_ERROR_STORAGE_FULL (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0006) +#define NRF_ERROR_API_NOT_IMPLEMENTED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0010) +#define NRF_ERROR_FEATURE_NOT_ENABLED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0011) /* @} */ /** - * @defgroup dm_specific_errors Error / status codes specific to device manager. + * @defgroup drv_specific_errors Error / status codes specific to drivers. * @{ */ -#define DM_NO_APP_CONTEXT (DEVICE_MANAGER_ERR_BASE + 0x0040) -#define DM_SERVICE_CONTEXT_NOT_APPLIED (DEVICE_MANAGER_ERR_BASE + 0x0041) -#define DM_CONTEXT_INFO_LOST (DEVICE_MANAGER_ERR_BASE + 0x0042) -#define DM_DEVICE_CONTEXT_FULL (DEVICE_MANAGER_ERR_BASE + 0x0043) +#define NRF_ERROR_DRV_TWI_ERR_OVERRUN (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0000) +#define NRF_ERROR_DRV_TWI_ERR_ANACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0001) +#define NRF_ERROR_DRV_TWI_ERR_DNACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0002) /* @} */ /** @@ -108,8 +142,41 @@ * an indicative of whether the procedure has been requested successfully. */ typedef uint32_t ret_code_t; + +#if defined(NRF_LOG_ENABLED) && NRF_LOG_ENABLED +/** + * @defgroup err_sizes Sizes of error code arrays. + * @{ + */ +#define ERR_NAMES_SIZE 18 +#define ERR_NAMES_COMMON_SIZE 9 +#define ERR_NAMES_TWI_SIZE 3 +/* @} */ + +extern const char * m_sdk_errors_name[ERR_NAMES_SIZE]; +extern const char * m_sdk_errors_name_common[ERR_NAMES_COMMON_SIZE]; +extern const char * m_sdk_errors_name_twi[ERR_NAMES_TWI_SIZE]; + +/** + * @defgroup err_to_string Macros for converting error codes to strings. + * @{ + */ +#define ERR_TO_STR(err_code) m_sdk_errors_name[err_code] +#define ERR_TO_STR_COMMON(err_code) m_sdk_errors_name_common[err_code - NRF_ERROR_SDK_COMMON_ERROR_BASE] +#define ERR_TO_STR_TWI(err_code) m_sdk_errors_name_twi[err_code - NRF_ERROR_PERIPH_DRIVERS_ERR_BASE] +#else +#define ERR_TO_STR(err_code) "" +#define ERR_TO_STR_COMMON(err_code) "" +#define ERR_TO_STR_TWI(err_code) "" +#endif // NRF_LOG_ENABLED + +/* @} */ /** @} */ /** @} */ +#ifdef __cplusplus +} +#endif + #endif // SDK_ERRORS_H__ diff --git a/components/libraries/util/sdk_macros.h b/components/libraries/util/sdk_macros.h new file mode 100644 index 0000000..e228e71 --- /dev/null +++ b/components/libraries/util/sdk_macros.h @@ -0,0 +1,192 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + + * @defgroup sdk_common_macros SDK Common Header + * @ingroup app_common + * @brief Macros for parameter checking and similar tasks + * @{ + */ + +#ifndef SDK_MACROS_H__ +#define SDK_MACROS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +/**@brief Macro for verifying statement to be true. It will cause the exterior function to return + * err_code if the statement is not true. + * + * @param[in] statement Statement to test. + * @param[in] err_code Error value to return if test was invalid. + * + * @retval nothing, but will cause the exterior function to return @p err_code if @p statement + * is false. + */ +#define VERIFY_TRUE(statement, err_code) \ +do \ +{ \ + if (!(statement)) \ + { \ + return err_code; \ + } \ +} while (0) + + +/**@brief Macro for verifying statement to be true. It will cause the exterior function to return + * if the statement is not true. + * + * @param[in] statement Statement to test. + */ +#define VERIFY_TRUE_VOID(statement) VERIFY_TRUE((statement), ) + + +/**@brief Macro for verifying statement to be false. It will cause the exterior function to return + * err_code if the statement is not false. + * + * @param[in] statement Statement to test. + * @param[in] err_code Error value to return if test was invalid. + * + * @retval nothing, but will cause the exterior function to return @p err_code if @p statement + * is true. + */ +#define VERIFY_FALSE(statement, err_code) \ +do \ +{ \ + if ((statement)) \ + { \ + return err_code; \ + } \ +} while (0) + + +/**@brief Macro for verifying statement to be false. It will cause the exterior function to return + * if the statement is not false. + * + * @param[in] statement Statement to test. + */ +#define VERIFY_FALSE_VOID(statement) VERIFY_FALSE((statement), ) + + +/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior + * function to return err_code if the err_code is not @ref NRF_SUCCESS. + * + * @param[in] err_code The error code to check. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_SUCCESS() +#else +#define VERIFY_SUCCESS(err_code) VERIFY_TRUE((err_code) == NRF_SUCCESS, (err_code)) +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior + * function to return if the err_code is not @ref NRF_SUCCESS. + * + * @param[in] err_code The error code to check. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_SUCCESS_VOID() +#else +#define VERIFY_SUCCESS_VOID(err_code) VERIFY_TRUE_VOID((err_code) == NRF_SUCCESS) +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to + * return @ref NRF_ERROR_INVALID_STATE if not. + * + * @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED + * should be true if the module is initialized, false if not. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_MODULE_INITIALIZED() +#else +#define VERIFY_MODULE_INITIALIZED() VERIFY_TRUE((MODULE_INITIALIZED), NRF_ERROR_INVALID_STATE) +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to + * return if not. + * + * @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED + * should be true if the module is initialized, false if not. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_MODULE_INITIALIZED_VOID() +#else +#define VERIFY_MODULE_INITIALIZED_VOID() VERIFY_TRUE_VOID((MODULE_INITIALIZED)) +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to + * return if not. + * + * @param[in] param The variable to check if is NULL. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_PARAM_NOT_NULL() +#else +#define VERIFY_PARAM_NOT_NULL(param) VERIFY_FALSE(((param) == NULL), NRF_ERROR_NULL) +#endif /* DISABLE_PARAM_CHECK */ + + +/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to + * return if not. + * + * @param[in] param The variable to check if is NULL. + */ +#ifdef DISABLE_PARAM_CHECK +#define VERIFY_PARAM_NOT_NULL_VOID() +#else +#define VERIFY_PARAM_NOT_NULL_VOID(param) VERIFY_FALSE_VOID(((param) == NULL)) +#endif /* DISABLE_PARAM_CHECK */ + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // SDK_MACROS_H__ + diff --git a/components/libraries/util/sdk_mapped_flags.c b/components/libraries/util/sdk_mapped_flags.c index 12c20c2..5d1552a 100644 --- a/components/libraries/util/sdk_mapped_flags.c +++ b/components/libraries/util/sdk_mapped_flags.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "sdk_mapped_flags.h" @@ -87,11 +115,11 @@ void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys, { if ((p_keys != NULL) && (p_flags != NULL) && (n_flag_collections > 0)) { - for (int i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) { if (p_keys[i] == key) { - for (int j = 0; j < n_flag_collections; j++) + for (uint32_t j = 0; j < n_flag_collections; j++) { if (value) { @@ -113,7 +141,7 @@ bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, ui { if (p_keys != NULL) { - for (int i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) { if (p_keys[i] == key) { @@ -133,7 +161,7 @@ sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p if (p_keys != NULL) { - for (int i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) { if (sdk_mapped_flags_get_by_index(flags, i)) { @@ -150,7 +178,7 @@ uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags) { uint32_t n_flags_set = 0; - for (int i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) + for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++) { if (sdk_mapped_flags_get_by_index(flags, i)) { diff --git a/components/libraries/util/sdk_mapped_flags.h b/components/libraries/util/sdk_mapped_flags.h index 6007eb2..f1a0a92 100644 --- a/components/libraries/util/sdk_mapped_flags.h +++ b/components/libraries/util/sdk_mapped_flags.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SDK_MAPPED_FLAGS_H__ @@ -18,6 +46,10 @@ #include "app_util.h" #include "compiler_abstraction.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @file * @defgroup sdk_mapped_flags Mapped flags @@ -47,7 +79,7 @@ typedef uint8_t sdk_mapped_flags_t; /**< The bitmap to hold flags. Each flag is // Test whether the flag collection type is large enough to hold all the flags. If this fails, // reduce SDK_MAPPED_FLAGS_N_KEYS or increase the size of sdk_mapped_flags_t. STATIC_ASSERT(( - sizeof(sdk_mapped_flags_t)*SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE) >= SDK_MAPPED_FLAGS_N_KEYS); + sizeof(sdk_mapped_flags_t) * SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE) >= SDK_MAPPED_FLAGS_N_KEYS); /**@brief Type used to present a subset of the registered keys. @@ -150,4 +182,9 @@ static __INLINE bool sdk_mapped_flags_any_set(sdk_mapped_flags_t flags) /** @} */ + +#ifdef __cplusplus +} +#endif + #endif /* SDK_MAPPED_FLAGS_H__ */ diff --git a/components/libraries/util/sdk_os.h b/components/libraries/util/sdk_os.h index ff871cf..d84ee5c 100644 --- a/components/libraries/util/sdk_os.h +++ b/components/libraries/util/sdk_os.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @cond */ @@ -25,6 +53,10 @@ #ifndef SDK_OS_H__ #define SDK_OS_H__ +#ifdef __cplusplus +extern "C" { +#endif + #define SDK_MUTEX_DEFINE(X) #define SDK_MUTEX_INIT(X) #define SDK_MUTEX_LOCK(X) @@ -33,8 +65,13 @@ /** * @defgroup os_data_type Data types. */ - + /** @} */ /** @endcond */ + +#ifdef __cplusplus +} +#endif + #endif // SDK_OS_H__ diff --git a/components/libraries/util/sdk_resources.h b/components/libraries/util/sdk_resources.h index 98d8657..9d9ac53 100644 --- a/components/libraries/util/sdk_resources.h +++ b/components/libraries/util/sdk_resources.h @@ -1,13 +1,42 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @brief Definition file for resource usage by SoftDevice, ESB and Gazell. @@ -17,35 +46,43 @@ #define APP_RESOURCES_H__ #ifdef SOFTDEVICE_PRESENT - #include "nrf_sd_def.h" + #include "nrf_sd_def.h" #else - #define SD_PPI_RESTRICTED 0uL /**< 1 if PPI peripheral is restricted, 0 otherwise. */ - #define SD_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */ - #define SD_PPI_GROUPS_USED 0uL /**< PPI groups utilized by SotfDevice (not available to th spplication). */ - #define SD_TIMERS_USED 0uL /**< Timers used by SoftDevice. */ - #define SD_SWI_USED 0uL /**< Software interrupts used by SoftDevice. */ + #define SD_PPI_RESTRICTED 0uL /**< 1 if PPI peripheral is restricted, 0 otherwise. */ + #define SD_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */ + #define SD_PPI_GROUPS_USED 0uL /**< PPI groups utilized by SotfDevice (not available to th spplication). */ + #define SD_TIMERS_USED 0uL /**< Timers used by SoftDevice. */ + #define SD_SWI_USED 0uL /**< Software interrupts used by SoftDevice. */ #endif #ifdef GAZELL_PRESENT - #include "nrf_gzll_resources.h" + #include "nrf_gzll_resources.h" #else - #define GZLL_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by Gazell (not available to th spplication). */ - #define GZLL_TIMERS_USED 0uL /**< Timers used by Gazell. */ - #define GZLL_SWI_USED 0uL /**< Software interrupts used by Gazell */ + #define GZLL_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by Gazell (not available to th spplication). */ + #define GZLL_TIMERS_USED 0uL /**< Timers used by Gazell. */ + #define GZLL_SWI_USED 0uL /**< Software interrupts used by Gazell */ #endif #ifdef ESB_PRESENT - #include "nrf_esb_resources.h" + #include "nrf_esb_resources.h" + +#ifdef __cplusplus +extern "C" { +#endif #else - #define ESB_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by ESB (not available to th spplication). */ - #define ESB_TIMERS_USED 0uL /**< Timers used by ESB. */ - #define ESB_SWI_USED 0uL /**< Software interrupts used by ESB */ + #define ESB_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by ESB (not available to th spplication). */ + #define ESB_TIMERS_USED 0uL /**< Timers used by ESB. */ + #define ESB_SWI_USED 0uL /**< Software interrupts used by ESB */ #endif - #define NRF_PPI_CHANNELS_USED (SD_PPI_CHANNELS_USED | GZLL_PPI_CHANNELS_USED | ESB_PPI_CHANNELS_USED) #define NRF_PPI_GROUPS_USED (SD_PPI_GROUPS_USED) #define NRF_SWI_USED (SD_SWI_USED | GZLL_SWI_USED | ESB_SWI_USED) #define NRF_TIMERS_USED (SD_TIMERS_USED | GZLL_TIMERS_USED | ESB_TIMERS_USED) + +#ifdef __cplusplus +} +#endif + #endif // APP_RESOURCES_H__ diff --git a/components/nfc/experimental_t4t_lib/hal_t4t/hal_nfc_t4t.c b/components/nfc/experimental_t4t_lib/hal_t4t/hal_nfc_t4t.c new file mode 100644 index 0000000..568c7a9 --- /dev/null +++ b/components/nfc/experimental_t4t_lib/hal_t4t/hal_nfc_t4t.c @@ -0,0 +1,964 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if NFC_HAL_ENABLED + +#include "hal_nfc_t4t.h" +#include +#include +#include "nfc_t4t_lib.h" +#include "nfc_fixes.h" +#include "nrf.h" +#include "app_util_platform.h" +#include "nordic_common.h" +#include "nrf_drv_clock.h" + +#define NRF_LOG_MODULE_NAME "HAL_NFC" +#if HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL HAL_NFC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR HAL_NFC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR HAL_NFC_CONFIG_DEBUG_COLOR +#else // HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // HAL_NFC_CONFIG_LOG_ENABLED +#include "nrf_log.h" + +#if HAL_NFC_CONFIG_DEBUG_PIN_ENABLED + #include "nrf_gpio.h" + + #define HAL_NFC_DEBUG_PIN_CONFIG(pin_num) nrf_gpio_cfg_output(pin_num) + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) nrf_gpio_pin_clear(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) nrf_gpio_pin_set(pin_num) + + #define HAL_NFC_DEBUG_PINS_INITIALIZE() \ + do{ \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + } while(0) +#else + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) + #define HAL_NFC_DEBUG_PINS_INITIALIZE() +#endif // HAL_NFC_DEBUG_PIN_ENABLE + + +/* NFC library version history: + * #define NFC_LIB_VERSION 0x00 first experimental version intended for nRF52840 IC rev. Engineering A (PCA10056, part of nRF52840 Preview Development Kit) + */ + +#define NFC_LIB_VERSION 0x00u /**< Internal: current NFC lib. version */ + +#define T2T_INTERNAL_BYTES_NR 10u /**< Number of internal bytes defined by Type 2 Tag Operation Technical Specification */ +#define T2T_INTERNAL_BYTE_SN0_SHIFT 0u /**< Internal Byte SN0, NRF_FICR->NFC.TAGHEADER0.MFGID which is Manufacturer ID */ +#define T2T_INTERNAL_BYTE_SN1_SHIFT 8u /**< Internal Byte SN1, NRF_FICR->NFC.TAGHEADER0.UID0 */ +#define T2T_INTERNAL_BYTE_SN2_SHIFT 16u /**< Internal Byte SN2, NRF_FICR->NFC.TAGHEADER0.UID1 */ +#define T2T_INTERNAL_BYTE_SN3_SHIFT 0u /**< Internal Byte SN3, NRF_FICR->NFC.TAGHEADER1.UID3 */ +#define T2T_INTERNAL_BYTE_SN4_SHIFT 8u /**< Internal Byte SN4, NRF_FICR->NFC.TAGHEADER1.UID4 */ +#define T2T_INTERNAL_BYTE_SN5_SHIFT 16u /**< Internal Byte SN5, NRF_FICR->NFC.TAGHEADER1.UID5 */ +#define T2T_INTERNAL_BYTE_SN6_SHIFT 24u /**< Internal Byte SN6, NRF_FICR->NFC.TAGHEADER1.UID6 */ +#define CASCADE_TAG_BYTE 0x88u /**< Constant defined by ISO/EIC 14443-3 */ +#define NFCID1_2ND_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_2ND_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_2ND_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFCID1_LAST_BYTE3_SHIFT 24u /**< Shift value for NFC ID byte 3 */ +#define NFCID1_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFC_RX_BUFFER_SIZE 256u /**< NFC Rx data buffer size */ +#define NFC_SLP_REQ_CMD 0x50u /**< NFC SLP_REQ command identifier */ +#define NFC_CRC_SIZE 2u /**< CRC size in bytes */ +#define NFC_T4T_SELRES_PROTOCOL 1u /**< Type 4A Tag PROTOCOL bit setup (b7:b6) for SEL_RES Response frame */ +#define NFC_T4T_SELRES_PROTOCOL_MSK 0x03u /**< PROTOCOL bits mask for SEL_RES Response frame */ +#define NFC_T4T_FWI_MAX 4u /**< Maximum FWI parameter value */ +#define NFC_T4T_RATS_CMD 0xE0u /**< RATS Command Byte */ +#define NFC_T4T_S_DESELECT 0xC2u /**< S(DESELECT) Block identifier */ +#define NFC_T4T_S_WTX 0xF2u /**< S(WTX)Block identifier */ +#define NFC_T4T_I_BLOCK 0x02u /**< I- Block identifier (static bits) */ +#define NFC_T4T_BLOCK_MSK 0xEEu /**< I/R- block mask (DID and NAD not supported, expect these bit equal 0) */ +#define NFC_T4T_R_BLOCK 0xA2u /**< R- Block identifier (static bits) */ +#define NFC_T4T_WTXM_MAX 0x16u /**< WTXM maximum value based on 'NFC Forum Digital Protocol Specification Version 1.1, Requirement 15.2.2.9', and FRAMEDELAYMAX maximum register setting */ +#define NFCT_INTEN_MSK 0x1C5CFFu /**< Mask for all NFCT interrupts */ + + +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#else + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk | \ + NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk | \ + NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + +#define NRF_NFCT_FRAMESTATUS_RX_MSK (NFCT_FRAMESTATUS_RX_OVERRUN_Msk | \ + NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk | \ + NFCT_FRAMESTATUS_RX_CRCERROR_Msk) /**< Mask for clearing all flags in NFCT_FRAMESTATUS_RX register */ +#define NFC_FIELD_ON_MASK NFCT_FIELDPRESENT_LOCKDETECT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD ON. */ +#define NFC_FIELD_OFF_MASK NFCT_FIELDPRESENT_FIELDPRESENT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD OFF. */ + +#define NFC_T4T_FWI_TO_FWT(FWI) (256u * 16u * (1 << (FWI))) /**< Macro for calculating FWT (in number of NFC carrier periods) from FWI parameter. */ + +/* Begin: Bugfix for FTPAN-xx (AUTOCOLRESCONFIG) */ +#define NRF_NFCT_AUTOCOLRESCONFIG (*(uint32_t volatile *)(0x4000559C)) +#define NRF_NFCT_AUTOCOLRESCONFIG_Pos 0 +/* End: Bugfix for FTPAN-xx */ + +typedef enum +{ + NFC_FIELD_STATE_NONE, /**< Initial value indicating no NFCT Field events. */ + NFC_FIELD_STATE_OFF, /**< NFCT FIELDLOST Event has been set. */ + NFC_FIELD_STATE_ON, /**< NFCT FIELDDETECTED Event has been set. */ + NFC_FIELD_STATE_UNKNOWN /**< Both NFCT Field Events have been set - ambiguous state. */ +}nfct_field_sense_state_t; + +/* Static function declarations */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event); +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event); +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state); + +/* Static data */ +static hal_nfc_callback_t m_nfc_lib_callback = (hal_nfc_callback_t) NULL; /**< Callback to nfc_lib layer */ +static void * m_nfc_lib_context; /**< Callback execution context */ +static volatile uint8_t m_nfc_rx_buffer[NFC_RX_BUFFER_SIZE] = {0}; /**< Buffer for NFC Rx data */ +static volatile bool m_slp_req_received = false; /**< Flag indicating that SLP_REQ Command was received */ +static volatile bool m_field_on = false; /**< Flag indicating that NFC Tag field is present */ +static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure */ +static volatile uint8_t m_fwi; /**< FWI parameter */ +static uint8_t m_wtx_data[2]; /**< Tx buffer for an S(WTX) block */ +static volatile bool m_deselect = false; /**< Flag indicating reception of DESELECT command */ +static volatile bool m_swtx_sent = false; /**< Flag indicating that SWTX command has been sended. */ +static volatile bool m_pending_msg = false; /**< Flag signaling pending message during SWTX command execution. */ +static volatile const uint8_t * m_pending_msg_ptr = NULL; /**< Pointer to pending message buffer. */ +static volatile size_t m_pending_data_length = 0; /**< Length of pending message data. */ +static volatile bool m_t4t_tx_waiting = false; /**< Indicates if HAL is waiting for upper layer response to received command */ + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static volatile uint32_t m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; /**< Mask used for NFC Field polling in NFCT_FIELDPRESENT register */ +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +static inline void hal_nfc_re_setup(void); +static void hal_nfc_field_check(void); + +#define NRF_NFCT_POWER (*(uint32_t volatile *)(0x40005FFC)) + +#define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | \ + NFCT_FIELDPRESENT_FIELDPRESENT_Msk) + +#define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << \ + NFCT_FIELDPRESENT_FIELDPRESENT_Pos) | \ + (NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << \ + NFCT_FIELDPRESENT_LOCKDETECT_Pos)) + +static void field_timer_with_callback_config() +{ + NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos; + NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_08Bit << TIMER_BITMODE_BITMODE_Pos; + NRF_TIMER4->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos; + NRF_TIMER4->CC[0] = 100 << TIMER_CC_CC_Pos; + NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; + NRF_TIMER4->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos; + + NVIC_ClearPendingIRQ(TIMER4_IRQn); + NVIC_SetPriority(TIMER4_IRQn, APP_IRQ_PRIORITY_LOW); + NVIC_EnableIRQ(TIMER4_IRQn); +} + + +void TIMER4_IRQHandler(void) +{ + HAL_NFC_DEBUG_PIN_SET(TIMER4_EVENT_PIN); + hal_nfc_field_check(); + NRF_TIMER4->EVENTS_COMPARE[0] = 0; + HAL_NFC_DEBUG_PIN_CLEAR(TIMER4_EVENT_PIN); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +/** + * @brief Common part of setup used for NFCT initialization and reinitialization. + */ +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static void hal_nfc_common_hw_setup(uint8_t * const nfc_internal) +#else +static inline void hal_nfc_common_hw_setup(uint8_t * const nfc_internal) +#endif +{ + uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0; + uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1; + +/* Begin: Bugfix for FTPAN-98 */ +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + *(volatile uint32_t *)0x4000568C = 0x00038148; +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +/* End: Bugfix for FTPAN-98 */ + +/* Begin: Bugfix for FTPAN-17 */ +/* fixed by avoiding usage of FIELDLOST event */ +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos); +#else + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos) | + (NFCT_INTENSET_FIELDLOST_Enabled << NFCT_INTENSET_FIELDLOST_Pos); +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +/* End: Bugfix for FTPAN-17 */ + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMESTART_Enabled << NFCT_INTENSET_TXFRAMESTART_Pos); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_ERROR_Enabled << NFCT_INTENSET_ERROR_Pos) | + (NFCT_INTENSET_SELECTED_Enabled << NFCT_INTENSET_SELECTED_Pos); + + /* According to ISO/IEC 14443-3 */ + nfc_internal[0] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN0_SHIFT)); // SN0 + nfc_internal[1] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN1_SHIFT)); // SN1 + nfc_internal[2] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN2_SHIFT)); // SN2 + nfc_internal[3] = (uint8_t) ((CASCADE_TAG_BYTE) ^ nfc_internal[0] ^ + nfc_internal[1] ^ nfc_internal[2]); // BCC0 = CASCADE_TAG_BYTE ^ SN0 ^ SN1 ^ SN2 + nfc_internal[4] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN3_SHIFT)); // SN3 + nfc_internal[5] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN4_SHIFT)); // SN4 + nfc_internal[6] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN5_SHIFT)); // SN5 + nfc_internal[7] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN6_SHIFT)); // SN6 + nfc_internal[8] = (uint8_t) (nfc_internal[4] ^ nfc_internal[5] ^ + nfc_internal[6] ^ nfc_internal[7]); // BCC1 = SN3 ^ SN4 ^ SN5 ^ SN6 + nfc_internal[9] = (uint8_t) (NFC_LIB_VERSION); // For internal use + + /* MSB of NFCID1_2ND_LAST register is not used - always 0 */ + NRF_NFCT->NFCID1_2ND_LAST = ((uint32_t) nfc_internal[0] << NFCID1_2ND_LAST_BYTE2_SHIFT) | + ((uint32_t) nfc_internal[1] << NFCID1_2ND_LAST_BYTE1_SHIFT) | + ((uint32_t) nfc_internal[2] << NFCID1_2ND_LAST_BYTE0_SHIFT); + + NRF_NFCT->NFCID1_LAST = ((uint32_t) nfc_internal[4] << NFCID1_LAST_BYTE3_SHIFT) | + ((uint32_t) nfc_internal[5] << NFCID1_LAST_BYTE2_SHIFT) | + ((uint32_t) nfc_internal[6] << NFCID1_LAST_BYTE1_SHIFT) | + ((uint32_t) nfc_internal[7] << NFCID1_LAST_BYTE0_SHIFT); + + /* Set FRAMEDELAYMAX to maximum available setting, corresponding to FWI = 4 */ + NRF_NFCT->FRAMEDELAYMAX = NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Msk; + m_fwi = 4; + + /* Set PROTOCOL bits for Type 4A Tag */ + NRF_NFCT->SELRES = + (NFC_T4T_SELRES_PROTOCOL << NFCT_SELRES_PROTOCOL_Pos) & NFCT_SELRES_PROTOCOL_Msk; + + /* Begin: Bugfix for FTPAN-25 (IC-9929) */ + /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used + because it's required to operate with Windows Phone */ + NRF_NFCT->SENSRES = + (NFCT_SENSRES_NFCIDSIZE_NFCID1Double << NFCT_SENSRES_NFCIDSIZE_Pos) | + (NFCT_SENSRES_BITFRAMESDD_SDD00100 << NFCT_SENSRES_BITFRAMESDD_Pos); + /* End: Bugfix for FTPAN-25 (IC-9929)*/ + + m_swtx_sent = false; + m_pending_msg = false; + m_pending_msg_ptr = NULL; + m_pending_data_length = 0; +} + + +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context) +{ + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + m_nfc_lib_callback = callback; + m_nfc_lib_context = p_context; + + hal_nfc_common_hw_setup(nfc_internal); + + /* Initialize SDK Clock module for handling high precission clock requests */ + m_clock_handler_item.event_handler = nrf_nfct_clock_event_handler; + m_clock_handler_item.p_next = NULL; + + ret_code_t err_code = nrf_drv_clock_init(); + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + field_timer_with_callback_config(); +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + NRF_LOG_INFO("Init\r\n"); + HAL_NFC_DEBUG_PINS_INITIALIZE(); + + if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_MODULE_ALREADY_INITIALIZED)) + { + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INTERNAL; + } +} + + +/**@brief Function for clearing an event flag in NRF_NFCT registers. + * + * @param[in] p_event Pointer to event register. + * + */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event) +{ + *p_event = 0; + + /* Perform read to ensure clearing is effective */ + volatile uint32_t dummy = *p_event; + (void)dummy; +} + + +/**@brief Function for handling events from Clock Module. + * + * @param[in] event Clock event. + * + */ +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event) +{ + switch (event) + { + case NRF_DRV_CLOCK_EVT_HFCLK_STARTED: + /* Activate NFCT only when HFXO is running */ + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + NRF_NFCT->TASKS_ACTIVATE = 1; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static inline void nrf_nfct_field_lost_hfclk_handle(void) +{ + /* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + // reset the NFC for release HFCLK + __DMB(); + NRF_NFCT_POWER = 0; + __DMB(); + NRF_NFCT_POWER = 1; + /* END: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +/**@brief Function for evaluating and handling NFC field events. + * + * @param[in] field_state Current field state. + * + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (field_state == NFC_FIELD_STATE_UNKNOWN) + { + /* Probe NFC field */ + uint32_t field_present = NRF_NFCT->FIELDPRESENT; + + if (field_present & m_nfc_fieldpresent_mask) + { + field_state = NFC_FIELD_STATE_ON; + } + else + { + field_state = NFC_FIELD_STATE_OFF; + } + } + + /* Field event service */ + switch (field_state) + { + case NFC_FIELD_STATE_ON: + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + } + m_field_on = true; + break; + + case NFC_FIELD_STATE_OFF: + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + +/* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + *(volatile uint32_t *)0x40005010 = 1; +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +/* END: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + + NRF_NFCT->TASKS_SENSE = 1; + nrf_drv_clock_hfclk_release(); + m_field_on = false; + + NRF_NFCT->INTENCLR = + (NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos) | + (NFCT_INTENCLR_RXERROR_Clear << NFCT_INTENCLR_RXERROR_Pos); + + /* Change mask to FIELD_OFF state - trigger FIELD_ON even if HW has not locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + + /* Re-enable Auto Collision Resolution */ + NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG & + ~(1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos); + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length) +{ + /* Parameter validation is done in upper-layer */ + + if (id == HAL_NFC_PARAM_FWI) + { + /* Update Frame Wait Time setting; possible settings are limited by NFCT hardware */ + m_fwi = *((uint8_t *)p_data); + + if (data_length != sizeof(uint8_t)) + { + return NRF_ERROR_DATA_SIZE; + } + if (m_fwi > NFC_T4T_FWI_MAX) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* Set FRAMEDELAYTIME */ + if (m_fwi == NFC_T4T_FWI_MAX) + { + NRF_NFCT->FRAMEDELAYMAX = NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Msk; + } + else + { + NRF_NFCT->FRAMEDELAYMAX = NFC_T4T_FWI_TO_FWT(m_fwi); + } + } + else if (id == HAL_NFC_PARAM_SELRES) + { + /* Update SEL_RES 'Protocol' bits setting */ + uint8_t sel_res = *((uint8_t *)p_data); + + if (data_length != sizeof(uint8_t)) + { + return NRF_ERROR_DATA_SIZE; + } + if (sel_res > NFC_T4T_SELRES_PROTOCOL_MSK) + { + return NRF_ERROR_INVALID_PARAM; + } + + NRF_NFCT->SELRES = + (sel_res << NFCT_SELRES_PROTOCOL_Pos) & NFCT_SELRES_PROTOCOL_Msk; + } + else + { + /* No implementation needed */ + } + + return NRF_SUCCESS; +} + + +/* This function is used by nfc_lib for unit testing only */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length) +{ + if (*p_max_data_length < 1) + { + *p_max_data_length = 1; + return NRF_ERROR_DATA_SIZE; + } + + if (id == HAL_NFC_PARAM_FWI) + { + *((uint8_t *) p_data) = m_fwi; + *p_max_data_length = sizeof(m_fwi); + } + else if (id == HAL_NFC_PARAM_SELRES) + { + /* Update SEL_RES 'Protocol' bits setting */ + uint8_t sel_res = (NRF_NFCT->SELRES & NFCT_SELRES_PROTOCOL_Msk) >> + NFCT_SELRES_PROTOCOL_Pos; + *((uint8_t *) p_data) = sel_res; + *p_max_data_length = sizeof(sel_res); + } + else + { + /* No implementation needed */ + } + + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_start(void) +{ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + + NVIC_ClearPendingIRQ(NFCT_IRQn); + NVIC_SetPriority(NFCT_IRQn, APP_IRQ_PRIORITY_LOW); + NVIC_EnableIRQ(NFCT_IRQn); + + NRF_NFCT->TASKS_SENSE = 1; + + NRF_LOG_INFO("Start\r\n"); + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length) +{ + if (data_length == 0) + { + return NRF_ERROR_DATA_SIZE; + } + + if(m_swtx_sent) + { + m_pending_msg_ptr = p_data; + m_pending_data_length = data_length; + m_pending_msg = true; + + NRF_LOG_DEBUG("Pending message.\r\n"); + return NRF_SUCCESS; + } + + m_t4t_tx_waiting = false; + + /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); //Moved to the end in T4T to avoid delaying TASKS_STARTX + NRF_NFCT->PACKETPTR = (uint32_t) p_data; + NRF_NFCT->TXD.AMOUNT = (data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + + NRF_LOG_INFO("Send\r\n"); + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_stop(void) +{ + NRF_NFCT->TASKS_DISABLE = 1; + + NRF_LOG_INFO("Stop\r\n"); + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_done(void) +{ + m_nfc_lib_callback = (hal_nfc_callback_t) NULL; + + return NRF_SUCCESS; +} + + +void NFCT_IRQHandler(void) +{ + nfct_field_sense_state_t current_field = NFC_FIELD_STATE_NONE; + + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_NFC_EVENT_DEBUG_PIN); // DEBUG! + + if (NRF_NFCT->EVENTS_FIELDDETECTED && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDDETECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDDETECTED); + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_DETECT_EVENT_DEBUG_PIN); // DEBUG! + current_field = NFC_FIELD_STATE_ON; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); // DEBUG! + + NRF_LOG_DEBUG("Field detected\r\n"); + } + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + if (NRF_NFCT->EVENTS_FIELDLOST && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDLOST_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDLOST); + current_field = + (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN; + + NRF_LOG_DEBUG("Field lost\r\n"); + } +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + /* Perform actions if any FIELD event is active */ + if (current_field != NFC_FIELD_STATE_NONE) + { + nrf_nfct_field_event_handler(current_field); + } + + if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk)) + { + /* Take into account only number of whole bytes */ + uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >> + NFCT_RXD_AMOUNT_RXDATABYTES_Pos) - NFC_CRC_SIZE; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + + /* Look for Tag 4 Type Commands */ + if (m_nfc_rx_buffer[0] == NFC_T4T_RATS_CMD) + { + /* Disable Auto Collision Resolution */ + NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG | + (1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos); + NRF_LOG_DEBUG("RX: T4T Activate\r\n"); + } + else if (m_nfc_rx_buffer[0] == NFC_T4T_S_DESELECT) + { + m_deselect = true; + NRF_LOG_DEBUG("RX: T4T Go to sleep\r\n"); + } + else if (m_swtx_sent && m_nfc_rx_buffer[0] == NFC_T4T_S_WTX) + { + m_swtx_sent = false; + + NRF_LOG_DEBUG("RX: S(WTX) reponse\r\n"); + + if(m_pending_msg) + { + m_pending_msg = false; + + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); + NRF_NFCT->PACKETPTR = (uint32_t) m_pending_msg_ptr; + NRF_NFCT->TXD.AMOUNT = (m_pending_data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + + m_t4t_tx_waiting = false; + NRF_LOG_DEBUG("Sending pending message!\r\n"); + } + } + else if ((m_nfc_rx_buffer[0] & NFC_T4T_BLOCK_MSK) == NFC_T4T_I_BLOCK) + { + /* Set up default transmission of S(WTX) block. Tx will be executed only if FDT timer expires (FrameDelayMode-ExactVal) before + * hal_nfc_send is called */ + m_wtx_data[0] = NFC_T4T_S_WTX; + m_wtx_data[1] = NFC_T4T_WTXM_MAX; + NRF_NFCT->PACKETPTR = (uint32_t) m_wtx_data; + NRF_NFCT->TXD.AMOUNT = (sizeof(m_wtx_data) << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_ExactVal << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + m_t4t_tx_waiting = true; + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); + } + else + { + /* Indicate that SLP_REQ was received - this will cause FRAMEDELAYTIMEOUT error */ + if (m_nfc_rx_buffer[0] == NFC_SLP_REQ_CMD) + { + m_slp_req_received = true; + NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos; // disable RX here (will enable at SELECTED) + } + /* Not a READ Command, so wait for next frame reception */ + NRF_NFCT->TASKS_ENABLERXDATA = 1; + } + + if (m_nfc_lib_callback != NULL) + { + /* This callback should trigger transmission of READ Response */ + m_nfc_lib_callback(m_nfc_lib_context, + HAL_NFC_EVENT_DATA_RECEIVED, + (void *)m_nfc_rx_buffer, + rx_data_size); + } + /* Clear TXFRAMESTART EVENT so it can be checked in hal_nfc_send */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMESTART); + NRF_LOG_DEBUG("Rx fend\r\n"); + } + + if (NRF_NFCT->EVENTS_TXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMEEND_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + /* Disable TX END event to ignore frame transmission other than READ response */ + NRF_NFCT->INTENCLR = (NFCT_INTENCLR_TXFRAMEEND_Clear << NFCT_INTENCLR_TXFRAMEEND_Pos); + + if (m_deselect) + { + /* Re-enable Auto Collision Resolution */ + NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG & + ~(1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos); + NRF_NFCT->TASKS_GOSLEEP = 1; + /* Disable RX here (will be enabled at SELECTED) */ + NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear << + NFCT_INTENCLR_RXFRAMEEND_Pos; + m_deselect = false; + } + else + { + /* Set up for reception */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + NRF_NFCT->INTENSET = + (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) | + (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos); + } + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_DATA_TRANSMITTED, 0, 0); + } + + NRF_LOG_DEBUG("Tx fend\r\n"); + } + + if (NRF_NFCT->EVENTS_SELECTED && (NRF_NFCT->INTEN & NFCT_INTEN_SELECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_SELECTED); + + /* Clear also RX END and RXERROR events because SW does not take care of commands which were received before selecting the tag */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + /* Set up registers for EasyDMA and start receiving packets */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) | + (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos); + + /* At this point any previous error status can be ignored */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + /* Change mask to FIELD_ON state - trigger FIELD_ON only if HW has locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_ON_MASK; +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_ON, 0, 0); + } + + m_swtx_sent = false; + m_pending_msg = false; + m_pending_msg_ptr = NULL; + m_pending_data_length = 0; + + NRF_LOG_DEBUG("Selected\r\n"); + } + + if (NRF_NFCT->EVENTS_RXERROR && (NRF_NFCT->INTEN & NFCT_INTEN_RXERROR_Msk)) + { + uint32_t rx_status = NRF_NFCT->FRAMESTATUS.RX; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + NRF_LOG_DEBUG("Rx error (0x%x)\r\n", (unsigned int) rx_status); + (void) rx_status; + + m_swtx_sent = false; + + if(m_pending_msg) + { + m_pending_msg = false; + m_t4t_tx_waiting = false; + + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); + NRF_NFCT->PACKETPTR = (uint32_t) m_pending_msg_ptr; + NRF_NFCT->TXD.AMOUNT = (m_pending_data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid << + NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos; + NRF_NFCT->TASKS_STARTTX = 1; + + NRF_LOG_DEBUG("Sending pending message!\r\n"); + } + + /* Clear rx frame status */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + } + + if (NRF_NFCT->EVENTS_ERROR && (NRF_NFCT->INTEN & NFCT_INTEN_ERROR_Msk)) + { + uint32_t err_status = NRF_NFCT->ERRORSTATUS; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_ERROR); + + /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received */ + if ((err_status & NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) && m_slp_req_received) + { + NRF_NFCT->ERRORSTATUS = NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + m_slp_req_received = false; + + NRF_LOG_DEBUG("RX: SLP_REQ\r\n"); + } + /* Report any other error */ + err_status &= ~NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + + if (err_status) + { + NRF_LOG_DEBUG("Error (0x%x)\r\n", (unsigned int) err_status); + } + + /* Clear error status */ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + } + + if (NRF_NFCT->EVENTS_TXFRAMESTART && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMESTART_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMESTART); + + if (m_t4t_tx_waiting) + { + m_t4t_tx_waiting = false; + m_swtx_sent = true; + + NRF_LOG_DEBUG("Response timeout, sending WTX!\r\n"); + } + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); // DEBUG! +} + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + #error Wrong workaround combination +#endif + +static uint32_t field_state_cnt = 0; +/** + * @brief Function for evaluating and handling NFC fieldlost event. + */ +static void hal_nfc_field_check(void) +{ + uint32_t nfc_fieldpresen_masked; + + nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK; + + if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST) + { + ++field_state_cnt; + if (field_state_cnt > 7) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + + NRF_TIMER4->TASKS_SHUTDOWN = 1; + + nrf_drv_clock_hfclk_release(); + + nrf_nfct_field_lost_hfclk_handle(); + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + m_field_on = false; + + /* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + // resume the NFCT to initialized state + hal_nfc_re_setup(); + /* End: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG! + } + + return; + } + + field_state_cnt = 0; +} + + +/** + * @brief Function for enablinge hight precision clock and start eveluating fieldlost event. + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + field_state_cnt = 0; + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG! + } + m_field_on = true; +} + + +/** + * @brief Function for resume the NFCT to initialized state after software's reset. + */ +static inline void hal_nfc_re_setup(void) +{ + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + hal_nfc_common_hw_setup(nfc_internal); + + NRF_LOG_INFO("Reinitialize\r\n"); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#endif // NFC_HAL_ENABLED diff --git a/components/nfc/experimental_t4t_lib/hal_t4t/hal_nfc_t4t.h b/components/nfc/experimental_t4t_lib/hal_t4t/hal_nfc_t4t.h new file mode 100644 index 0000000..ef0a307 --- /dev/null +++ b/components/nfc/experimental_t4t_lib/hal_t4t/hal_nfc_t4t.h @@ -0,0 +1,193 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 HAL_NFC_H__ +#define HAL_NFC_H__ + +/** @file + * @defgroup nfc_t4t_hal NFC Type 4 Tag HAL + * @{ + * @ingroup nfc_t4t + * @brief @tagAPI52 Hardware abstraction layer for the NFC Type 4 Tag library. + * + * @note Before the NFCT peripheral enters ACTIVATED state, the HFXO must be running. + * To fulfill this requirement and allow other software modules to also request the HFXO, the NFC Type 4 Tag HAL uses @ref nrf_drv_clock module. + * + */ + +#include +#include +#include + + +/** @brief Events passed to the upper-layer callback function. */ +typedef enum { + HAL_NFC_EVENT_FIELD_ON, ///< Field is detected. + HAL_NFC_EVENT_FIELD_OFF, ///< Field is lost. + HAL_NFC_EVENT_DATA_RECEIVED, ///< Data is received. + HAL_NFC_EVENT_DATA_TRANSMITTED ///< Data is transmitted. +} hal_nfc_event_t; + + +/** @brief Parameter IDs for the set/get function. */ +typedef enum { + HAL_NFC_PARAM_ID_TESTING, ///< Used for unit tests. + HAL_NFC_PARAM_FWI, ///< Frame Wait Time parameter. + HAL_NFC_PARAM_SELRES, ///< Parameter for setting the 'Protocol' bits for SEL_RES packet. + HAL_NFC_PARAM_ID_UNKNOWN +} hal_nfc_param_id_t; + + +/** @brief Callback from HAL_NFC layer into the upper layer. + * + * If event == HAL_NFC_EVENT_DATA_RECEIVED: + * p_data points to the received packet. The memory belongs to the HAL_NFC layer and + * is guaranteed to be valid only until the callback returns. + * + * If event == HAL_NFC_EVENT_DATA_TRANSMITTED: + * p_data points to the transmitted packet. The memory belongs to the application. + * + * If event == \: + * p_data definition is event-specific (to be defined). + * + * @param[in] p_context Context for callback execution. + * @param[in] event The event that occurred. + * @param[in] p_data Received/transmitted data or NULL. + * @param[in] data_length Size of the received/transmitted packet. + */ +typedef void (* hal_nfc_callback_t)(void * p_context, + hal_nfc_event_t event, + const uint8_t * p_data, + size_t data_length); + + +/** @brief Function for initializing the NFC layer. + * + * This function provides a pointer to a callback function and the callback context + * to the NFC layer. + * + * @param[in] callback Pointer to the callback function. + * @param[in] p_context Context of callback. + * + * @retval NRF_SUCCESS If the NFC layer was initialized successfully. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context); + + +/** @brief Function for setting a HAL_NFC parameter. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to the buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments + * was invalid (for example, wrong data length), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length); + + +/** @brief Function for querying a HAL_NFC parameter value. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, p_max_data_length will contain the required buffer size. + * + * @param[in] id ID of the parameter to query. + * @param[in, out] p_data Pointer to a buffer receiving the queried data. + * @param[in, out] p_max_data_length Size of the buffer. It receives the required size if buffer is too small. + * + * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length); + + +/** @brief Function for starting the NFC subsystem. + * + * After this function completes, NFC readers will be able to detect the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was started successfully. If the NFC + * subsystem could not be started, an error code is returned. + */ +ret_code_t hal_nfc_start(void); + + +/** @brief Function for sending a packet to the connected NFC reader. + * + * The provided data buffer belongs to the caller and is guaranteed to be + * valid until the HAL_NFC_EVENT_DATA_TRANSMITTED event is received by the + * callback. + * + * @param[in] p_data The data packet to send. + * @param[in] data_length Size of the packet in bytes. + * + * @retval NRF_SUCCESS If the packet was sent. Otherwise, an error code is returned. + */ +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length); + + +/** @brief Function for stopping the NFC subsystem. + * + * After this function returns, NFC readers will no longer be able to connect + * to the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was stopped. Otherwise, an error code + * is returned. + */ +ret_code_t hal_nfc_stop(void); + + +/** @brief Function for releasing resources. + * + * After this call returns, the callback is considered invalid and no more + * events will be posted to it. + * + * @retval NRF_SUCCESS This function always succeeds. + */ +ret_code_t hal_nfc_done(void); + + +/** @} */ +#endif /* HAL_NFC_H__ */ + diff --git a/components/nfc/experimental_t4t_lib/license.txt b/components/nfc/experimental_t4t_lib/license.txt new file mode 100644 index 0000000..d629f64 --- /dev/null +++ b/components/nfc/experimental_t4t_lib/license.txt @@ -0,0 +1,36 @@ +Copyright (c) 2016 - 2017, Telit Communications Cyprus Ltd + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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. + +3. Neither the name of Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. diff --git a/components/nfc/experimental_t4t_lib/nfc_fixes.h b/components/nfc/experimental_t4t_lib/nfc_fixes.h new file mode 100644 index 0000000..c68505c --- /dev/null +++ b/components/nfc/experimental_t4t_lib/nfc_fixes.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_FIXES_H__ +#define NFC_FIXES_H__ + +#include + +/** @file + * @defgroup nfc_fixes NFC fixes and workarounds + * @{ + * @ingroup nfc_t4t + * @brief @tagAPI52 Fixes for hardware-related anomalies. + * + * If you are using PCA10040 (part of nRF52 Development Kit), + * you must define the macro HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 79. NFCT: A false EVENTS_FIELDDETECTED event occurs after the field is lost. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * + * If you are using PCA10056 (part of nRF52840 Development Kit), + * you must define the macro HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 98. NFCT: The NFCT is not able to communicate with the peer. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * + * The current code contains a patch for anomaly 25 (NFCT: Reset value of + * SENSRES register is incorrect), so that it now works on Windows Phone. + */ + +#ifdef BOARD_PCA10040 // assume nRF52832 chip in IC rev. Engineering B or Engineering C + #define HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +#elif defined(BOARD_PCA10056) // assume nRF52840 chip in IC rev. Engineering A + #define HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +#endif + +/** @} */ +#endif /* NFC_FIXES_H__ */ + diff --git a/components/nfc/experimental_t4t_lib/nfc_t4t_lib.h b/components/nfc/experimental_t4t_lib/nfc_t4t_lib.h new file mode 100644 index 0000000..ef1cc2f --- /dev/null +++ b/components/nfc/experimental_t4t_lib/nfc_t4t_lib.h @@ -0,0 +1,311 @@ +/** + * Copyright (c) 2016 - 2017, Telit Communications Cyprus Ltd + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_T4T_LIB_H__ +#define NFC_T4T_LIB_H__ + +/** @file + * + * @addtogroup nfc_api + * + * @defgroup nfc_t4t NFC Type 4 Tag + * @ingroup nfc_api + * @brief Implementation of NFC Type 4 Tag. + * + * @defgroup nfc_t4t_lib NFC tag 4 type emulation library + * @{ + * @ingroup nfc_t4t + * @brief The T4T emulation library interface + * + * This is the NFC Forum NDEF tag 4 type emulation library. It implements the ISO14443-4A protocol + * (ISO-DEP) and additionally can emulate a read-writable NDEF content. If the emulation of the NDEF + * content is not needed, the library works in a raw mode where all APDUs are delivered to the user, + * who is then responsible to generate a timely RPDU as a response. + * + * The sequence of initializing functions determines whether the NDEF emulation will run or whether + * the raw mode is used. + * + * - E.g. NDEF emulation + * * @ref nfc_t4t_setup + * * @ref nfc_t4t_ndef_rwpayload_set or @ref nfc_t4t_ndef_staticpayload_set + * * @ref nfc_t4t_emulation_start + * * ... running in NDEF emulation mode ... + * - E.g. RAW mode + * * @ref nfc_t4t_setup + * * @ref nfc_t4t_emulation_start + * * ... running in RAW emulation mode ... + */ + +#include +#include +#include +#include "sdk_errors.h" + +#define NFC_T4T_MAX_PAYLOAD_SIZE 0xFFF0U + +/**< @brief Emulation mode. */ +typedef enum +{ + NFC_T4T_EMUMODE_NDEF, ///< Emulated NDEF AID and EF-Files. + NFC_T4T_EMUMODE_PICC ///< Run just ISO-DEP, deliver I-Frames up. +} nfc_t4t_emu_mode_t; + + +/**< @brief Event identifiers used by the @ref nfc_t4t_callback_t */ +typedef enum +{ + NFC_T4T_EVENT_NONE, + ///< This ID is never used. Dummy value for completeness. + + NFC_T4T_EVENT_FIELD_ON, + ///< External Reader polling detected. + + NFC_T4T_EVENT_FIELD_OFF, + ///< External Reader polling ended. + + NFC_T4T_EVENT_NDEF_READ, + ///< External Reader has read static NDEF-Data from Emulation. + /**< + * A Read operation happened on last byte of NDEF-Data. + */ + + NFC_T4T_EVENT_NDEF_UPDATED, + ///< External Reader has written to length information of NDEF-Data from Emulation. + /**< + * The usual behavior of a Reader-Writer that accesses NDEF information for update is to set + * the length to zero at the beginning of the update process. It then writes the content + * of NDEF-Data. When all content is written it will update the length information inside + * the NDEF file. This event will be generated every time an update to the length is happening. + * This length information is residing in the first 2 bytes of the NDEF-Content container and is called 'NLEN'. + * Since this callback is triggered on any access to these bytes the returned data_length + * information might not be consistent (e.g. in case of only a single byte write to the length). + * + * @param[out] data_length Current value of NDEF content length + * information i.e. 'NLEN' field. + */ + + NFC_T4T_EVENT_DATA_TRANSMITTED, + ///< In Raw mode it signals that the data from @ref nfc_t4t_response_pdu_send have been sent out. + + NFC_T4T_EVENT_DATA_IND, + ///< In Raw mode delivers the APDU fragments + /**< + * All @ref NFC_T4T_EVENT_DATA_IND events that have the @ref NFC_T4T_DI_FLAG_MORE flag set + * belong to the same APDU. The first @ref NFC_T4T_EVENT_DATA_IND without @ref NFC_T4T_DI_FLAG_MORE + * flag signals the completeness of the APDU. The Application then has to reply with a call + * to @ref nfc_t4t_response_pdu_send. The library will handle internally the fragmentation of + * the response towards the Reader-Writer. The data of the response PDU must be kept + * valid until the next callback from the library happens (e.g. next @ref NFC_T4T_EVENT_DATA_IND + * or @ref NFC_T4T_EVENT_FIELD_OFF). + * + * @param[out] p_data Pointer to the fragment of APDU. + * @param[out] data_length Length of data. + * @param[out] flags @ref nfc_t4t_data_ind_flags_t. + */ +} nfc_t4t_event_t; + +/**< @brief Flags coming with nfc_t4t_callback_t at @ref NFC_T4T_EVENT_DATA_IND event.*/ +typedef enum +{ + NFC_T4T_DI_FLAG_NONE = 0x00, ///< Dummy value. + NFC_T4T_DI_FLAG_MORE = 0x01 ///< This signals that more data is expected to be received. +} nfc_t4t_data_ind_flags_t; + +/**< @brief Parameter IDs that can be set/get with @ref nfc_t4t_parameter_set or + * @ref nfc_t4t_parameter_get. + */ +typedef enum +{ + NFC_T4T_PARAM_TESTING, ///< Internal usage only for Unit-Testing. + NFC_T4T_PARAM_FWI, ///< Frame Wait Time parameter + NFC_T4T_PARAM_SELRES ///< Parameter for setting 'Protocol' bits for SEL_RES packet +} nfc_t4t_param_id_t; + +/** @brief Callback to pass events from NFCLib to application. + * + * @param[out] p_context Application context for callback execution. + * @param[out] event The event that occurred. see @ref nfc_t4t_event_t. + * @param[out] p_data Data to send to the application (event specific). + * @param[out] data_length Length of the data. In case of @ref NFC_T4T_EVENT_NDEF_UPDATED, this parameter + * contains the value of the 'NLEN' field of the NDEF File; + * if the value is non-zero, it corresponds to the new size of the NDEF Message in the updated NDEF File. + * @param[out] flags Some events deliver flags. see @ref nfc_t4t_event_t for details. + */ +typedef void (*nfc_t4t_callback_t)(void * p_context, + nfc_t4t_event_t event, + const uint8_t * p_data, + size_t data_length, + uint32_t flags); + +/** @brief Register the application callback for event signaling. + * + * The callback will be called by NFCLib to notify the application of relevant events. It will be + * called from the HAL_NFC callback context. The library support 3 different Modes of Emulation: + * - Raw ISO-Dep exchanges. All PDUs are signaled through the callback. + * - Read-Only T4T NDEF-Tag. A static buffer is served. Only Field-Status callbacks. + * - Read-Write T4T NDEF-Tag. A mutable buffer is used. Only Field-Status callbacks. + * + * The default mode is Raw ISO-Dep mode. The two other NDEF T4T modes are activated through + * the corresponding @ref nfc_t4t_ndef_rwpayload_set/ @ref nfc_t4t_ndef_staticpayload_set functions. + * The mode is locked in with a call to @ref nfc_t4t_emulation_start. + * + * @param[in] callback Function pointer to the callback. + * @param[in] p_context Pointer to a memory area used by the callback for execution (optional). + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE If emulation is in running state. + */ +ret_code_t nfc_t4t_setup(nfc_t4t_callback_t callback, void * p_context); + +/** @brief Set emulation buffer and content for a NDEF Tag emulation that is Read/Writable. + * + * The buffer needs to be kept accessible for the lifetime of the emulation. + * If an external Reader-Writer changes the NDEF content it is signaled through the app-callback. + * + * @param[in] p_emulation_buffer Buffer pointer + * @param[in] buffer_length Length of buffer (maximum writable NDEF size) + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + * @retval NRF_ERROR_INVALID_STATE If emulation is in running state. + */ +ret_code_t nfc_t4t_ndef_rwpayload_set(uint8_t * p_emulation_buffer, size_t buffer_length); + +/** @brief Set emulationBuffer and Content for a NDEF Tag emulation that is Read-Only. + * + * The buffer needs to be kept accessible for the lifetime of the emulation. + * Since no write access is done to the buffer, the content could reside in flash memory. + * + * @param[in] p_emulation_buffer Const buffer pointer + * @param[in] buffer_length Length of contained NDEF payload message + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + * @retval NRF_ERROR_INVALID_STATE Emulation is in running stated. + */ +ret_code_t nfc_t4t_ndef_staticpayload_set(const uint8_t * p_emulation_buffer, size_t buffer_length); + +/** @brief Send a raw response PDU after getting a Request PDU callback. + * + * When the library works in raw ISO-DEP mode it will signal request PDUs through the callback. + * The application then has to answer with a response PDU. It will use this function to send back + * the response PDU. This function can not be used in T4T NDEF (RW / STATIC) emulation modes. + * + * The lower ISODEP layer will handle the defragmentation of a long response PDU into smaller + * pieces that the PCD can understand. + * + * @param[in] p_pdu Const PDU pointer. + * @param[in] pdu_length Length of PDU. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + * @retval NRF_ERROR_INVALID_STATE Emulation is in running state. + */ +ret_code_t nfc_t4t_response_pdu_send(const uint8_t * p_pdu, size_t pdu_length); + +/** @brief Set an NFC parameter. + * + * Allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to a buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + */ +ret_code_t nfc_t4t_parameter_set(nfc_t4t_param_id_t id, void * p_data, size_t data_length); + +/** @brief Query an NFC parameter value. + * + * The queried value will be placed into the passed data buffer. + * If the buffer is too small, p_max_data_length will contain the required buffer size. + * If the buffer is big enough, p_max_data_length will contain the actual size of the data. + * + * @param[in] id ID of the parameter to query. + * @param[out] p_data Pointer to a buffer receiving the queried data. + * @param[out] p_max_data_length Size of the buffer, receives actual size of queried data. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length). + * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer). + */ +ret_code_t nfc_t4t_parameter_get(nfc_t4t_param_id_t id, void * p_data, size_t * p_max_data_length); + +/** @brief Activate the NFC frontend. + * + * Only after calling this function, events will be posted to the application callback. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE Already started. + */ +ret_code_t nfc_t4t_emulation_start(void); + +/** + * @brief Deactivate the NFC frontend. + * + * After calling this function, no more events will be posted to the application callback. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_INVALID_STATE Emulation was already stopped + */ +ret_code_t nfc_t4t_emulation_stop(void); + +/** + * @brief Release reference to application callback. + * + * After calling this function, the passed callback pointer is no longer considered valid. + * After calling this function, the passed p_ndef pointer is no longer considered valid. + * + * You need to restart with @ref nfc_t4t_setup to run a new Emulation. + * + * @retval NRF_SUCCESS Always succeeds. + */ +ret_code_t nfc_t4t_done(void); + +/** + @} +*/ + +#endif // NFC_T4T_LIB_H__ diff --git a/components/nfc/experimental_t4t_lib/nfc_t4t_lib_gcc.a b/components/nfc/experimental_t4t_lib/nfc_t4t_lib_gcc.a new file mode 100644 index 0000000000000000000000000000000000000000..efbf12b0ea9985690f015a307ef620733611aaa0 GIT binary patch literal 800914 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

n4A5HD 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

_Ag7w4C#AR?`A|Xd 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 OZLj~Zx9?q`{r?3n9)j8c literal 0 HcmV?d00001 diff --git a/components/nfc/experimental_t4t_lib/nfc_t4t_lib_iar.a b/components/nfc/experimental_t4t_lib/nfc_t4t_lib_iar.a new file mode 100644 index 0000000000000000000000000000000000000000..b6eb9c11af12a25f5707e2a25dc44e982e2680c9 GIT binary patch literal 43694 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

hs&)<)9D+9+*=aRSG|1FK6RW-r*9MF-j;yA z?`itfb!j?%KZ9H%=d~>u1l50~vi|Axy$N!O==+wY54R&CO{eb%kh@j#bz&diO}Noe z_NjY{>Ga(MxkSeISxp~qk3^bI-;W`e$a%M^aMC{9X2tdW205pA&0>}XAlGVUEx*qI z>F3kWLvE)`UrjO)FQ3y@e}YHTD1muddP%T?tZ;C7+-w#uq2%e^99IKJ%(^GY9& zZ=1(m_Fs%|`)>|uo4G%j(Bpt6EmgVFd8cXZ!&Trz3x#hUX#wpoaNt8izEzGM?un+hglLk2oq&rAQn+x7i|}O6?N6Ai;ld zWB{0pxDT_?pKJ>sX&l7H_%8^4xUgrM<>)+LEQH_BzT&Y^$6%ztub^O{zkd)8^!Q^` z>qHC$A30W!dU%M(qZQz3uKC)ttG;k)S5*1Bt0)HL)33bQ;g>F*{8i)vM-2!S94269 zl%ITDJO5D(tABg-lxWnce`Z3&r=mjh^V#@I0U=*cf5#p>zA=inhh%AEUt|#9`mAmC z*3QfyPxwp6@UlPgWq;z!{=|P>fEZ34m;H$^vX}J#sK2H_hfX=+l(@+g;7_=p+vFHd zE^?i4jAV|_nPZ%A-0m13ca#btdtCyXq zS&f|0w8{m^tnkynuPfgia1Ni_oQ%)3J4dpGHs|g5G(4o8V=evp$3)=G^=$hVY&)B)fr2MpiBmaTjl>b2B z`ur^ct0dh{UQ4PwT#? zeM|QwI9(J)O_)d8RX^#}Ud1*Zd($8G#eO-|?;!zwdvS z*|!;^xb4Bs)+y)dIW#_a(p@ua{L^2mPNJH6_#)o-TRM$0jEc>fZGx8(8ue_vm9VNy8LJ}pC+qxOwsb@@fL#X0w|o z+s(nq*hRca5Q7c7u&a3Ef?dTM7c@zJp^r0@sd6%F$-!LHCRxgI{CHwdT(4+@WGu&y zaU8WSNu`{fqnu zASe1*3aR{hDJS|H`9~qA+o$BNm2z@-Dno}W9+#>7HYun2rb<5wC6DEANlaIWgxzS#<)X9qV{a>Ed|33f# literal 0 HcmV?d00001 diff --git a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c b/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c new file mode 100644 index 0000000..bd39e27 --- /dev/null +++ b/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nfc_ac_rec.h" +#include +#include "nrf_error.h" +#include "nrf.h" + +#define AC_REC_CPS_BYTE_SIZE 1 ///< Size of the field with CPS data. +#define AC_REC_DATA_REF_LEN_SIZE 1 ///< Size of the Data Reference Length field. +#define AC_REC_AUX_DATA_REF_COUNT_SIZE 1 ///< Size of the Data Reference Length field. + +const uint8_t nfc_ac_rec_type_field[2] = {'a', 'c'}; ///< Alternative Carrier Record type. + +/** + * @brief Function for calculating the payload length of the NFC NDEF Alternative Carrier record. + */ +static uint32_t nfc_ac_rec_payload_size_get(nfc_ac_rec_payload_desc_t const * p_ac_rec_payload_desc) +{ + int32_t i = 0; + // Initialize with size of byte with CPS. + uint32_t payload_size = AC_REC_CPS_BYTE_SIZE; + + // Add Carrier Data Reference size. + payload_size += p_ac_rec_payload_desc->carrier_data_ref.length + AC_REC_DATA_REF_LEN_SIZE; + + // Add Auxiliary Data Reference Count size. + payload_size += AC_REC_AUX_DATA_REF_COUNT_SIZE; + + for (i = 0; i < p_ac_rec_payload_desc->aux_data_ref_count; i++) + { + // Add Auxiliary Data Reference size. + payload_size += p_ac_rec_payload_desc->p_aux_data_ref[i].length + AC_REC_DATA_REF_LEN_SIZE; + } + + return payload_size; +} + + +ret_code_t nfc_ac_rec_payload_constructor(nfc_ac_rec_payload_desc_t * p_nfc_rec_ac_payload_desc, + uint8_t * p_buff, + uint32_t * p_len) +{ + int32_t i = 0; + uint32_t payload_size = nfc_ac_rec_payload_size_get(p_nfc_rec_ac_payload_desc); + + if (p_buff != NULL) + { + // Not enough space in the buffer, return an error. + if (payload_size > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + // Invalid CPS value. + if ( p_nfc_rec_ac_payload_desc->cps & ~NFC_AC_CPS_MASK ) + { + return NRF_ERROR_INVALID_PARAM; + } + + // Copy CPS. + *p_buff = p_nfc_rec_ac_payload_desc->cps; + p_buff += AC_REC_CPS_BYTE_SIZE; + + // Copy Carrier Data Reference. + *p_buff = p_nfc_rec_ac_payload_desc->carrier_data_ref.length; + p_buff += AC_REC_DATA_REF_LEN_SIZE; + + memcpy( p_buff, + p_nfc_rec_ac_payload_desc->carrier_data_ref.p_data, + p_nfc_rec_ac_payload_desc->carrier_data_ref.length ); + p_buff += p_nfc_rec_ac_payload_desc->carrier_data_ref.length; + + // Copy Auxiliary Data Reference. + *p_buff = p_nfc_rec_ac_payload_desc->aux_data_ref_count; + p_buff += AC_REC_AUX_DATA_REF_COUNT_SIZE; + + for (i = 0; i < p_nfc_rec_ac_payload_desc->aux_data_ref_count; i++) + { + *p_buff = p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length; + p_buff += AC_REC_DATA_REF_LEN_SIZE; + + memcpy( p_buff, + p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].p_data, + p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length ); + p_buff += p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length; + } + } + + // Assign payload size to the return buffer. + *p_len = payload_size; + + return NRF_SUCCESS; +} + + +void nfc_ac_rec_auxiliary_data_ref_clear(nfc_ndef_record_desc_t * p_ac_rec) +{ + nfc_ac_rec_payload_desc_t * p_ac_rec_payload = + (nfc_ac_rec_payload_desc_t*)p_ac_rec->p_payload_descriptor; + + p_ac_rec_payload->aux_data_ref_count = 0; +} + + +ret_code_t nfc_ac_rec_auxiliary_data_ref_add(nfc_ndef_record_desc_t * p_ac_rec, + uint8_t * p_aux_data, + uint8_t aux_length) +{ + nfc_ac_rec_payload_desc_t * p_ac_rec_payload = + (nfc_ac_rec_payload_desc_t *)p_ac_rec->p_payload_descriptor; + + if (p_ac_rec_payload->aux_data_ref_count >= p_ac_rec_payload->max_aux_data_ref) + { + return NRF_ERROR_NO_MEM; + } + + p_ac_rec_payload->p_aux_data_ref[p_ac_rec_payload->aux_data_ref_count].p_data = p_aux_data; + p_ac_rec_payload->p_aux_data_ref[p_ac_rec_payload->aux_data_ref_count].length = aux_length; + p_ac_rec_payload->aux_data_ref_count++; + + return NRF_SUCCESS; +} diff --git a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h b/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h new file mode 100644 index 0000000..03a2061 --- /dev/null +++ b/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h @@ -0,0 +1,196 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_AC_REC_H__ +#define NFC_AC_REC_H__ + +/**@file + * + * @defgroup nfc_ac_rec ac (Alternative carrier) records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF Alternative Carrier records for NDEF messages. + * + */ + +#include +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define AC_REC_CPS_BYTE_SIZE 1 ///< Size of the field with CPS data. +#define AC_REC_DATA_REF_LEN_SIZE 1 ///< Size of the Data Reference Length field. +#define AC_REC_AUX_DATA_REF_COUNT_SIZE 1 ///< Size of the Data Reference Length field. + +/** + * @brief Carrier Power State. + * + * Possible Carrier Power State field values in an Alternative Carrier record. + */ +typedef enum +{ + NFC_AC_CPS_INACTIVE = 0x00, ///< Alternative Carrier inactive. + NFC_AC_CPS_ACTIVE = 0x01, ///< Alternative Carrier active. + NFC_AC_CPS_ACTIVATING = 0x02, ///< Alternative Carrier activating. + NFC_AC_CPS_UNKNOWN = 0x03 ///< Alternative Carrier power status unknown. +} nfc_ac_rec_cps_t; + +#define NFC_AC_CPS_MASK (NFC_AC_CPS_UNKNOWN) ///< Mask of Carrier Power State bits in a first ac record byte. + +/** + * @brief Carrier Data Reference and Auxiliary Data Reference descriptor. + */ +typedef struct +{ + uint8_t length; ///< Length of the data field. + uint8_t * p_data; ///< Pointer to the Data Reference characters. Not relevant if length is 0. +} nfc_ac_rec_data_ref_t; + +/** + * @brief Alternative Carrier record payload descriptor. + */ +typedef struct +{ + nfc_ac_rec_cps_t cps; ///< Carrier Power State value. + nfc_ac_rec_data_ref_t carrier_data_ref; ///< Carrier Data Reference. + uint8_t const max_aux_data_ref; ///< Maximum number of Auxiliary Data Reference fields. + uint8_t aux_data_ref_count; ///< Number of Auxiliary Data Reference fields. + nfc_ac_rec_data_ref_t * p_aux_data_ref; ///< Pointer to the Auxiliary Data Reference fields. +} nfc_ac_rec_payload_desc_t; + + +/** + * @brief Constructor for an NFC NDEF Alternative Carrier record payload. + * + * This function encodes the payload of an Alternative Carrier record as specified in the Connection + * Handover standard. It implements an API compatible with @ref p_payload_constructor_t. + */ +ret_code_t nfc_ac_rec_payload_constructor(nfc_ac_rec_payload_desc_t * p_nfc_rec_ac_payload_desc, + uint8_t * p_buff, + uint32_t * p_len); + +/** + * @brief External reference to the type field of the Alternative Carrier record, defined in the + * file @c nfc_ac_rec.c. It is used in the @ref NFC_NDEF_AC_RECORD_DESC_DEF macro. + */ +extern const uint8_t nfc_ac_rec_type_field[2]; + +/** + * @brief Size of the type field of the Alternative Carrier record, defined in the + * file @c nfc_ac_rec.c. It is used in the @ref NFC_NDEF_AC_RECORD_DESC_DEF macro. + */ +#define NFC_AC_REC_TYPE_LENGTH 2 + +/** + *@brief Macro for creating and initializing an NFC NDEF record descriptor for an Alternative Carrier record. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and + * a static instance of type @ref nfc_ac_rec_payload_desc_t, which together constitute an instance of an Alternative Carrier record. + * + * Use the macro @ref NFC_NDEF_AC_RECORD_DESC to access the NDEF Alternative Carrier record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] CPS Carrier Power State value. + * @param[in] CARR_DATA_REF_LEN Length of the Carrier Data Reference field. + * @param[in] P_CARR_DATA_REF Pointer to the Carrier Data Reference field. + * @param[in] MAX_AUX_DATA_REF Maximum number of Auxiliary Data Reference fields. + */ +#define NFC_NDEF_AC_RECORD_DESC_DEF(NAME, \ + CPS, \ + CARR_DATA_REF_LEN, \ + P_CARR_DATA_REF, \ + MAX_AUX_DATA_REF) \ + static nfc_ac_rec_data_ref_t NAME##_nfc_ac_rec_aux_data_ref_array[MAX_AUX_DATA_REF]; \ + static nfc_ac_rec_payload_desc_t NAME##_nfc_ac_rec_payload_desc = \ + { \ + .cps = CPS, \ + .carrier_data_ref = {CARR_DATA_REF_LEN, P_CARR_DATA_REF}, \ + .max_aux_data_ref = MAX_AUX_DATA_REF, \ + .aux_data_ref_count = 0, \ + .p_aux_data_ref = NAME##_nfc_ac_rec_aux_data_ref_array \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_WELL_KNOWN, \ + 0, \ + 0, \ + nfc_ac_rec_type_field, \ + NFC_AC_REC_TYPE_LENGTH, \ + nfc_ac_rec_payload_constructor, \ + &(NAME##_nfc_ac_rec_payload_desc)) + +/** + * @brief Macro for accessing the NFC NDEF Alternative Carrier record descriptor + * instance that was created with @ref NFC_NDEF_AC_RECORD_DESC_DEF. + */ +#define NFC_NDEF_AC_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** + * @brief Function for clearing an Auxiliary Data Reference in an NFC NDEF Alternative Carrier record. + * + * This function clears the Auxiliary Data References from the Alternative Carrier record. + * + * @param[in, out] p_ac_rec Pointer to the Alternative Carrier record descriptor. + */ +void nfc_ac_rec_auxiliary_data_ref_clear(nfc_ndef_record_desc_t * p_ac_rec); + +/** + * @brief Function for adding an Auxiliary Data Reference to an NFC NDEF Alternative Carrier record. + * + * @param[in, out] p_ac_rec Pointer to an ac record. + * @param[in] p_aux_data Pointer to the Auxiliary Data Reference data buffer. + * @param[in] aux_length Length of the Auxiliary Data Reference data. + * + * @retval NRF_SUCCESS If the Auxiliary Data Reference was added successfully. + * @retval NRF_ERROR_NO_MEM If the record already contains the maximum number of Auxiliary Data References. + */ +ret_code_t nfc_ac_rec_auxiliary_data_ref_add(nfc_ndef_record_desc_t * p_ac_rec, + uint8_t * p_aux_data, + uint8_t aux_length); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_AC_REC_H__ diff --git a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c b/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c new file mode 100644 index 0000000..e7cb102 --- /dev/null +++ b/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c @@ -0,0 +1,393 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nfc_ble_oob_advdata.h" +#include "sdk_common.h" +#include "nfc_ble_pair_msg.h" + +// LESC OOB data AD_TYPE values. +#define BLE_GAP_AD_TYPE_LESC_CONFIRM_VALUE 0x22 +#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 + +/** + * @brief Macro for verifying basic parameters used for encoding single BLE AD Type. + * + * It verifies if provided buffer is NULL and if there is enough space for the encoded data. + * In case of NULL pointer buffer, necessary space for current AD Type is calculated. + * + * @param[in] P_ENCODED_DATA Buffer for the encoded data. + * @param[in] P_OFFSET Pointer to index of the first free cell in the buffer. + * @param[in] AD_TYPE_SIZE Size of the single AD Type. + * @param[in] MAX_SIZE Maximal size of the provided buffer. + */ +#define NFC_BLE_OOB_ADVDATA_INPUT_VERIFY( P_ENCODED_DATA, P_OFFSET, AD_TYPE_SIZE, MAX_SIZE) \ + if ( (P_ENCODED_DATA) == NULL ) \ + { \ + *(P_OFFSET) += (AD_TYPE_SIZE); \ + return NRF_SUCCESS; \ + } \ + if ( *(P_OFFSET) + (AD_TYPE_SIZE) > (MAX_SIZE) ) \ + { \ + return NRF_ERROR_DATA_SIZE; \ + } + +/**@brief Function for encoding data of Security Manager OOB Flags AD Type. + * + * @param[in] oob_flags Security Manager OOB Flags AD Type payload. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + */ +static ret_code_t sec_mgr_oob_flags_encode(uint8_t oob_flags, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_OOB_FLAGS_SIZE, max_size); + + // Encode flags. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + p_encoded_data[*p_offset] = oob_flags; + *p_offset += AD_TYPE_OOB_FLAGS_DATA_SIZE; + + return NRF_SUCCESS; +} + +/**@brief Function for encoding data of Security Manager TK Value AD Type. + * + * @param[in] p_tk_value Security Manager TK Value AD Type payload. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + */ +static ret_code_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + ret_code_t err_code; + + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_TK_VALUE_SIZE, max_size); + + // Encode TK Value. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + + // Remember location of TK in the buffer if this feature was enabled. + err_code = nfc_tk_to_group_add(&p_encoded_data[*p_offset]); + VERIFY_SUCCESS(err_code); + + nfc_tk_value_payload_encode(p_tk_value, &p_encoded_data[*p_offset]); + (*p_offset) += AD_TYPE_TK_VALUE_DATA_SIZE; + + return NRF_SUCCESS; +} + +/**@brief Function for encoding LESC OOB data in the CH NDEF message. + * + * @param[in] p_lesc_value Pointer to the LESC OOB values to be encoded. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + */ +static ret_code_t lesc_value_encode(ble_gap_lesc_oob_data_t * p_lesc_value, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + ret_code_t err_code; + + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_LESC_SIZE, max_size); + + // Encode LESC Confirm Value. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_CONFIRM_VALUE_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LESC_CONFIRM_VALUE; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + + memcpy(&p_encoded_data[*p_offset], p_lesc_value->c, sizeof(p_lesc_value->c)); + + uint8_t *p_confirm = &p_encoded_data[*p_offset]; + + (*p_offset) += AD_TYPE_CONFIRM_VALUE_DATA_SIZE; + + // Encode LESC Random Value. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_RANDOM_VALUE_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + + memcpy(&p_encoded_data[*p_offset], p_lesc_value->r, sizeof(p_lesc_value->r)); + + uint8_t *p_random = &p_encoded_data[*p_offset]; + + (*p_offset) += AD_TYPE_RANDOM_VALUE_DATA_SIZE; + + // Remember location of LESC OOB data in the buffer in case of key changes. + err_code = nfc_lesc_pos_set(p_confirm, p_random); + + return err_code; +} + +/**@brief Function for encoding data of LE Role AD Type. + * + * @param[in] le_role LE Role AD Type payload. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding. + * \c out: Offset of \p p_encoded_data buffer after this AD type encoding. + * @param[in] max_size Size of \p p_encoded_data buffer. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small. + * @retval NRF_ERROR_INVALID_PARAM If \p le_role parameter has invalid value. + */ +static ret_code_t le_role_encode(ble_advdata_le_role_t le_role, + uint8_t * p_encoded_data, + uint16_t * p_offset, + uint16_t max_size) +{ + NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_LE_ROLE_SIZE, max_size); + + // Encode LE Role. + p_encoded_data[*p_offset] = (uint8_t)(ADV_AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE); + *p_offset += ADV_LENGTH_FIELD_SIZE; + p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_ROLE; + *p_offset += ADV_AD_TYPE_FIELD_SIZE; + switch (le_role) + { + case BLE_ADVDATA_ROLE_ONLY_PERIPH: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH; + break; + case BLE_ADVDATA_ROLE_ONLY_CENTRAL: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL; + break; + case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED; + break; + case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED: + p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED; + break; + default: + return NRF_ERROR_INVALID_PARAM; + } + *p_offset += AD_TYPE_LE_ROLE_DATA_SIZE; + + return NRF_SUCCESS; +} + +/**@brief Function for calculating the size of Local Name AD Type. + * + * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data. + * @param[out] p_len Size of the buffer that is necessary to encode Local Name AD Type. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval Other Other error codes might be returned depending on + * @ref sd_ble_gap_device_name_get function. + */ +__STATIC_INLINE ret_code_t nfc_ble_oob_name_size_calc(ble_advdata_t const * const p_advdata, + uint16_t * const p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + uint16_t device_len; + + if (p_advdata->name_type == BLE_ADVDATA_SHORT_NAME) + { + device_len = p_advdata->short_name_len; + } + else + { + err_code = sd_ble_gap_device_name_get(NULL, &device_len); + } + + *p_len += ADV_LENGTH_FIELD_SIZE + ADV_AD_TYPE_FIELD_SIZE + device_len; + return err_code; +} + +/**@brief Function for calculating the size of AD Types which are encoded by @ref adv_data_encode function. + * + * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data. + * @param[out] p_len Size of the buffer that is necessary to encode AD Types. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval Other Other error codes might be returned depending on + * @ref nfc_ble_oob_name_size_calc function. + */ +static ret_code_t nfc_ble_oob_adv_data_size_calc(ble_advdata_t const * const p_advdata, + uint16_t * const p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (p_advdata->include_ble_device_addr) + { + *p_len += AD_TYPE_BLE_DEVICE_ADDR_SIZE; + } + if (p_advdata->include_appearance) + { + *p_len += AD_TYPE_APPEARANCE_SIZE; + } + if (p_advdata->flags != 0) + { + *p_len += AD_TYPE_FLAGS_SIZE; + } + if (p_advdata->name_type != BLE_ADVDATA_NO_NAME) + { + err_code = nfc_ble_oob_name_size_calc(p_advdata, p_len); + } + return err_code; +} + +/**@brief Function for verifying if BLE advertising data structure contains only supported AD Types + * by this encoding module. + * + * @param[in] advdata Structure with BLE advertising data. + * + * @retval NRF_SUCCESS If the verification was successful. + * @retval NRF_ERROR_INVALID_PARAM If there is any AD type which is not supported by this + * module. + */ +static ret_code_t nfc_ble_oob_adv_data_check(ble_advdata_t advdata) +{ + advdata.p_sec_mgr_oob_flags = NULL; + advdata.p_tk_value = NULL; + advdata.le_role = BLE_ADVDATA_ROLE_NOT_PRESENT; + advdata.include_ble_device_addr = false; + advdata.include_appearance = false; + advdata.flags = 0; + advdata.name_type = BLE_ADVDATA_NO_NAME; + advdata.short_name_len = 0; + advdata.p_lesc_data = NULL; + + ble_advdata_t pattern_advdata; + memset(&pattern_advdata, 0, sizeof(ble_advdata_t)); + + if ( memcmp( &pattern_advdata, &advdata, sizeof(ble_advdata_t)) == 0 ) + { + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INVALID_PARAM; + } +} + +ret_code_t nfc_ble_oob_adv_data_encode(ble_advdata_t const * const p_advdata, + uint8_t * const p_encoded_data, + uint16_t * const p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + uint16_t max_size = *p_len; + uint16_t offset = 0; + + // Verify ADV data structure. + err_code = nfc_ble_oob_adv_data_check(*p_advdata); + VERIFY_SUCCESS(err_code); + + // Encode Security Manager OOB Flags. + if (p_advdata->p_sec_mgr_oob_flags != NULL) + { + err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags, + p_encoded_data, + &offset, + max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode LESC keys + if (p_advdata->p_lesc_data != NULL) + { + err_code = lesc_value_encode(p_advdata->p_lesc_data, p_encoded_data, &offset, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode Security Manager TK value. + if (p_advdata->p_tk_value != NULL) + { + err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, &offset, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode LE Role. + if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role) + { + err_code = le_role_encode(p_advdata->le_role, p_encoded_data, &offset, max_size); + VERIFY_SUCCESS(err_code); + } + + // Encode remaining AD Types or precalculate necessary buffer space. + if (p_encoded_data != NULL) + { + uint16_t adv_data_size = max_size - offset; + err_code = adv_data_encode(p_advdata, p_encoded_data + offset, &adv_data_size); + *p_len = offset + adv_data_size; + } + else + { + err_code = nfc_ble_oob_adv_data_size_calc(p_advdata, &offset); + *p_len = offset; + } + + return err_code; +} + +void nfc_tk_value_payload_encode(ble_advdata_tk_value_t * p_tk_value, + uint8_t * p_tk_payload_data) +{ + for (uint8_t i = 0; i < AD_TYPE_TK_VALUE_DATA_SIZE; i++) + { + *(p_tk_payload_data++) = p_tk_value->tk[i]; + } +} diff --git a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h b/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h new file mode 100644 index 0000000..fb168ce --- /dev/null +++ b/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * + * @defgroup nfc_ble_oob_advdata Advertising and Scan Response Data Encoder for NFC OOB pairing + * @{ + * @ingroup nfc_ble_pair_msg + * @brief Function for encoding data in the Advertising and Scan Response Data format, which + * can be used to create payload of NFC message intended for initiating the Out-of-Band + * pairing. + */ + +#ifndef NFC_BLE_OOB_ADVDATA_H__ +#define NFC_BLE_OOB_ADVDATA_H__ + +#include +#include "ble_advdata.h" +#include "app_util.h" +#include "sdk_errors.h" + + +#define AD_TYPE_LE_ROLE_DATA_SIZE 1UL /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */ +#define AD_TYPE_LE_ROLE_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_LE_ROLE_DATA_SIZE) /**< Size (in octets) of the LE Bluetooth Device Address AD type. */ +#define AD_TYPE_TK_VALUE_DATA_SIZE (sizeof(ble_advdata_tk_value_t)) /**< Data size (in octets) of the Security Manager TK value AD type. */ +#define AD_TYPE_TK_VALUE_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_TK_VALUE_DATA_SIZE) /**< Size (in octets) of the Security Manager TK value AD type. */ +#define AD_TYPE_OOB_FLAGS_DATA_SIZE 1UL /**< Data size (in octets) of the Security Manager OOB Flags AD type. */ +#define AD_TYPE_OOB_FLAGS_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_OOB_FLAGS_DATA_SIZE) /**< Size (in octets) of the Security Manager OOB Flags AD type. */ + +#define AD_TYPE_CONFIRM_VALUE_DATA_SIZE 16UL /**< Data size (in octets) of the LESC Confirmation value. */ +#define AD_TYPE_CONFIRM_VALUE_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_CONFIRM_VALUE_DATA_SIZE) /**< Size (in octets) of the LESC Confirmation value AD type. */ +#define AD_TYPE_RANDOM_VALUE_DATA_SIZE 16UL /**< Data size (in octets) of the LESC Random value. */ +#define AD_TYPE_RANDOM_VALUE_SIZE (ADV_AD_DATA_OFFSET + \ + AD_TYPE_RANDOM_VALUE_DATA_SIZE) /**< Size (in octets) of the LESC Random value AD type. */ +#define AD_TYPE_LESC_SIZE (AD_TYPE_RANDOM_VALUE_SIZE + \ + AD_TYPE_CONFIRM_VALUE_SIZE) /**< Size (in octets) of the LESC OOB AD data field in NDEF message. */ + +#define AD_TYPE_SEC_MGR_OOB_FLAG_SET 1U /**< Security Manager OOB Flag set. Flag selection is done using _POS defines */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR 0U /**< Security Manager OOB Flag clear. Flag selection is done using _POS defines */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS 0UL /**< Security Manager OOB Data Present Flag position. */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS 1UL /**< Security Manager OOB Low Energy Supported Flag position. */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS 2UL /**< Security Manager OOB Simultaneous LE and BR/EDR to Same Device Capable Flag position. */ +#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_PUBLIC 0UL /**< Security Manager OOB Public Address type. */ +#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM 1UL /**< Security Manager OOB Random Address type. */ +#define AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS 3UL /**< Security Manager OOB Address type Flag (0 = Public Address, 1 = Random Address) position. */ + +/**@brief Payload field values of LE Role BLE GAP AD Type. Corresponds with @ref ble_advdata_le_role_t enum. */ +typedef enum +{ + NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH = 0, /**< Only Peripheral Role supported. */ + NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL, /**< Only Central Role supported. */ + NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED, /**< Peripheral and Central Role supported. Peripheral Role preferred for connection establishment. */ + NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED /**< Peripheral and Central Role supported. Central Role preferred for connection establishment */ +} nfc_ble_advdata_le_role_encoded_t; + +/**@brief Function for encoding data in the Advertising and Scan Response data format, which + * is used for NFC OOB pairing. + * + * + * @details This function encodes data into the Advertising and Scan Response data format (AD structures). + * Encoding is based on the selections in the supplied structures. This function uses + * @ref adv_data_encode to encode regular data and adds additional AD Structures which are specific + * for NFC OOB pairing: Security Manager TK Value, LESC OOB values, OOB Flags, and LE Role. + * + * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data. + * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in,out] p_len \c in: Size of \p p_encoded_data buffer. + * \c out: Length of encoded data. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata. + * @retval NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could fit into the + * provided buffer or some encoded AD structure is too long and its + * length cannot be encoded with one octet. + */ +ret_code_t nfc_ble_oob_adv_data_encode(ble_advdata_t const * const p_advdata, + uint8_t * const p_encoded_data, + uint16_t * const p_len); + +/**@brief Function for encoding payload field of Security Manager TK Value AD Type. + * + * @param[in] p_tk_value Security Manager TK Value AD Type payload. + * @param[out] p_tk_payload_data Pointer to the buffer where TK payload data will be stored. + * + */ +void nfc_tk_value_payload_encode(ble_advdata_tk_value_t * p_tk_value, + uint8_t * p_tk_payload_data); + +#endif // NFC_BLE_OOB_ADVDATA_H__ + +/** @} */ diff --git a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c b/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c new file mode 100644 index 0000000..44d40a3 --- /dev/null +++ b/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c @@ -0,0 +1,557 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nfc_ble_pair_msg.h" +#include "nfc_hs_rec.h" +#include "nfc_ac_rec.h" +#include "nfc_le_oob_rec.h" +#include "nfc_ep_oob_rec.h" +#include "nfc_ndef_msg.h" +#include "sdk_macros.h" + +/** + * @brief Descriptor of TK value locations in Connection Handover NDEF message. + */ +typedef struct +{ + uint8_t ** pp_tk_group; /**< Pointer to array of pointer with TK locations in CH NDEF message. */ + uint8_t tk_num; /**< Number of valid TK locations. */ + uint8_t tk_max_num; /**< Maximal number of possible TK locations. */ +} nfc_ble_tk_group_t; + +/** + * @brief Descriptor of LESC OOB data in Connection Handover NDEF message. + */ +typedef struct +{ + uint8_t * confirm; /**< Pointer to the LESC OOB confirmation value in the CH NDEF message. */ + uint8_t * random; /**< Pointer to the LESC OOB random value in the CH NDEF message. */ +} nfc_ble_lesc_data_pos_t; + +static nfc_ble_lesc_data_pos_t m_lesc_pos = {NULL, NULL}; /**< Descriptor used to update LESC keys in the NDEF Message */ +static nfc_ble_tk_group_t m_tk_group; /**< Descriptor used to find TK locations in the NDEF Message which require update. */ +static bool m_tk_modifier_on = false; /**< Flag indicating that TK modifier feature is on. */ + +/* Default value for Security Manager Out Of Band Flags field in BLE AD structure */ +/* which is used for EP OOB Record payload */ +static const uint8_t sec_mgr_oob_flags = + (AD_TYPE_SEC_MGR_OOB_FLAG_SET << AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS) | + (AD_TYPE_SEC_MGR_OOB_FLAG_SET << AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS) | + (AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR << AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS) | + (AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM << AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS); + +/**@brief Function for configuring TK group modifier feature. + * + * @details This function configures the structure which is responsible for tracking TK locations. + * These locations can be afterwards easily accessed with @ref nfc_tk_group_modifier_update + * and modified. + * + * @param[in] pp_tk_group Pointer to array of TK locations that should be modified with + * @ref nfc_tk_group_modifier_update function. + * @param[in] max_group_size Maximal number of TK locations that can added to \p pp_tk_group. + */ +__STATIC_INLINE void nfc_tk_group_modifier_config(uint8_t ** pp_tk_group, uint8_t max_group_size) +{ + m_tk_group.pp_tk_group = pp_tk_group; + m_tk_group.tk_num = 0; + m_tk_group.tk_max_num = max_group_size; +} + +/** @brief Function for generating a description of a simplified LE OOB message according to the BLE + * AD structure. + * + * This function declares and initializes a static instance of a simplified LE OOB message + * with Bluetooth Carrier Configuration LE record. Payload of this record can be configured + * via AD structure. + * + * @param[in] p_le_advdata Pointer to the AD for LE OOB record. + * @param[out] pp_le_oob_msg_desc Pointer to pointer to the NDEF message instance. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +static ret_code_t nfc_ble_simplified_le_oob_msg_declare(ble_advdata_t const * const p_le_advdata, + nfc_ndef_msg_desc_t ** pp_le_oob_msg_desc) +{ + ret_code_t err_code; + nfc_ndef_record_desc_t * p_nfc_le_oob_record; + + /* Create NFC NDEF message description, capacity - 1 record */ + NFC_NDEF_MSG_DEF(nfc_le_oob_msg, 1); + + /* The message description is static, therefore */ + /* you must clear the message (needed for supporting multiple calls) */ + nfc_ndef_msg_clear(&NFC_NDEF_MSG(nfc_le_oob_msg)); + + if (p_le_advdata != NULL) + { + /* Create NFC NDEF LE OOB Record description without record ID field */ + p_nfc_le_oob_record = nfc_le_oob_rec_declare(0 , p_le_advdata); + + /* Add LE OOB Record as lone record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_le_oob_msg), p_nfc_le_oob_record); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + *pp_le_oob_msg_desc = &NFC_NDEF_MSG(nfc_le_oob_msg); + + return NRF_SUCCESS; +} + +/** @brief Function for generating a description of a simplified EP OOB message according to the BLE + * AD structure. + * + * This function declares and initializes a static instance of a simplified EP OOB message + * with Bluetooth Carrier Configuration EP record. Payload of this record can be configured + * via AD structure. + * + * @param[in] p_ep_advdata Pointer to the AD structure for EP OOB record. + * @param[out] pp_ep_oob_msg_desc Pointer to pointer to the NDEF message instance. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +static ret_code_t nfc_ble_simplified_ep_oob_msg_declare(ble_advdata_t const * const p_ep_advdata, + nfc_ndef_msg_desc_t ** pp_ep_oob_msg_desc) +{ + ret_code_t err_code; + nfc_ndef_record_desc_t * p_nfc_ep_oob_record; + + /* Create NFC NDEF message description, capacity - 1 record */ + NFC_NDEF_MSG_DEF(nfc_ep_oob_msg, 1); + + /* The message description is static, therefore */ + /* you must clear the message (needed for supporting multiple calls) */ + nfc_ndef_msg_clear(&NFC_NDEF_MSG(nfc_ep_oob_msg)); + + if (p_ep_advdata != NULL) + { + /* Create NFC NDEF EP OOB Record description without record ID field */ + p_nfc_ep_oob_record = nfc_ep_oob_rec_declare(0 , p_ep_advdata); + + /* Add EP OOB Record as lone record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_ep_oob_msg), p_nfc_ep_oob_record); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + *pp_ep_oob_msg_desc = &NFC_NDEF_MSG(nfc_ep_oob_msg); + + return NRF_SUCCESS; +} + +/** @brief Function for generating a description of a Handover Select NDEF message according to + * the BLE AD structures. + * + * This function declares and initializes a static instance of an NFC NDEF message description + * of a Handover Select NDEF message with a Hs record and two OOB records (LE and EP with + * modifications for Windows). Payload of these records can be configured via AD structures. + * + * @warning The order of LE and EP records cannot be changed. Android devices are able to pair + * correctly only when the LE record appears before the EP record. + * + * @param[in] p_le_advdata Pointer to the AD structure for LE OOB record. + * @param[in] p_ep_advdata Pointer to the AD structure for EP OOB record. + * @param[out] pp_bt_oob_full_msg Pointer to a pointer to the NDEF message instance. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +static ret_code_t nfc_ble_full_handover_select_msg_declare(ble_advdata_t const * const p_le_advdata, + ble_advdata_t const * const p_ep_advdata, + nfc_ndef_msg_desc_t ** pp_bt_oob_full_msg) +{ + ret_code_t err_code = NRF_SUCCESS; + + // Carrier reference buffers for ac records. + static uint8_t carrier_le_reference = '0'; + static uint8_t carrier_ep_reference = '1'; + + // Create ac records for both message types. + NFC_NDEF_AC_RECORD_DESC_DEF(ac_rec_le, NFC_AC_CPS_ACTIVE, 1, &carrier_le_reference, 1); + NFC_NDEF_AC_RECORD_DESC_DEF(ac_rec_ep, NFC_AC_CPS_ACTIVE, 1, &carrier_ep_reference, 1); + + // Create a Hs record and assign existing ac records to it. + NFC_NDEF_HS_RECORD_DESC_DEF(hs_rec, 1, 3, 2); + + nfc_ndef_record_desc_t * p_nfc_hs_record = &NFC_NDEF_HS_RECORD_DESC(hs_rec); + + // Clear the record before assigning local records to it (in case this function has already been called). + nfc_hs_rec_local_record_clear(p_nfc_hs_record); + + err_code = nfc_hs_rec_local_record_add(p_nfc_hs_record, &NFC_NDEF_AC_RECORD_DESC(ac_rec_le)); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = nfc_hs_rec_local_record_add(p_nfc_hs_record, &NFC_NDEF_AC_RECORD_DESC(ac_rec_ep)); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Create le and ep records. + nfc_ndef_record_desc_t * p_nfc_le_oob_record = + nfc_le_oob_rec_declare(carrier_le_reference , p_le_advdata); + + nfc_ndef_record_desc_t * p_nfc_ep_oob_record = + nfc_ep_oob_rec_declare(carrier_ep_reference , p_ep_advdata); + + // Create full NDEF Handover Select message for Connection Handover and assign Hs, le and ep records to it. + NFC_NDEF_MSG_DEF(hs_full_msg, 3); + + // Clear the message before assigning records to it (in case this function has already been called). + nfc_ndef_msg_clear(&NFC_NDEF_MSG(hs_full_msg)); + + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(hs_full_msg), p_nfc_hs_record); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(hs_full_msg), p_nfc_le_oob_record); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(hs_full_msg), p_nfc_ep_oob_record); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + *pp_bt_oob_full_msg = &NFC_NDEF_MSG(hs_full_msg); + + return err_code; +} + +/** @brief Function for creating an AD structure with common configuration for EP and LE OOB records. + * + * This function creates an AD structure and initializes its fields with default content. Only + * fields that are common for both EP and LE OOB records are filled. + * + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK field of the returned AD structure is empty. + * @param[out] p_adv_data Pointer to BLE AD structure with common configuration for EP and + * LE OOB records. + */ +static void common_adv_data_create(ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + ble_advdata_t * const p_adv_data) +{ + memset((uint8_t *) p_adv_data, 0, sizeof(ble_advdata_t)); + + /* Set common configuration of AD structure for both Bluetooth EP and LE record */ + p_adv_data->include_appearance = true; + p_adv_data->name_type = BLE_ADVDATA_FULL_NAME; + p_adv_data->p_tk_value = NULL; + if (p_tk_value != NULL) + { + p_adv_data->p_tk_value = p_tk_value; + } + + p_adv_data->p_lesc_data = p_lesc_data; +} + +/** @brief Function for creating an AD structure with default configuration for an LE OOB record. + * + * This function creates an AD structure and initializes its fields with default content for + * LE OOB record payload. + * + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK field of the returned AD structure is empty. + * @param[out] p_le_adv_data Pointer to BLE AD structure with default configuration + * for LE OOB record. + */ +static void le_oob_specific_adv_data_create(ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + ble_advdata_t * const p_le_adv_data) +{ + /* Create default configuration which is common for both EP and LE OOB Records */ + common_adv_data_create(p_tk_value, p_lesc_data, p_le_adv_data); + + /* LE specific configuration */ + p_le_adv_data->include_ble_device_addr = true; + p_le_adv_data->le_role = BLE_ADVDATA_ROLE_ONLY_PERIPH; + p_le_adv_data->flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; +} + +/** @brief Function for creating an AD structure with default configuration for an EP OOB record. + * + * This function creates an AD structure and initializes its fields with default content for + * EP OOB record payload. + * + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK field of the returned AD structure is empty. + * @param[out] p_ep_adv_data Pointer to BLE AD structure with default configuration + * for EP OOB record. + */ +static void ep_oob_specific_adv_data_create(ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + ble_advdata_t * const p_ep_adv_data) +{ + /* Create default configuration which is common for both EP and LE OOB Records */ + common_adv_data_create(p_tk_value, p_lesc_data, p_ep_adv_data); + + /* EP specific configuration */ + p_ep_adv_data->p_sec_mgr_oob_flags = (uint8_t *) &sec_mgr_oob_flags; +} + +ret_code_t nfc_ble_simplified_le_oob_msg_encode(ble_advdata_t const * const p_le_advdata, + uint8_t * p_buf, + uint32_t * p_len) +{ + nfc_ndef_msg_desc_t * p_le_oob_msg_desc; + ret_code_t err_code; + + err_code = nfc_ble_simplified_le_oob_msg_declare(p_le_advdata, &p_le_oob_msg_desc); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!m_tk_modifier_on) + { + nfc_tk_group_modifier_config(NULL, 0); + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_le_oob_msg_desc, + p_buf, + p_len); + + return err_code; +} + +ret_code_t nfc_ble_simplified_ep_oob_msg_encode(ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len) +{ + nfc_ndef_msg_desc_t * p_ep_oob_msg_desc; + ret_code_t err_code; + + err_code = nfc_ble_simplified_ep_oob_msg_declare(p_ep_advdata, &p_ep_oob_msg_desc); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!m_tk_modifier_on) + { + nfc_tk_group_modifier_config(NULL, 0); + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_ep_oob_msg_desc, + p_buf, + p_len); + + return err_code; +} + +ret_code_t nfc_ble_full_handover_select_msg_encode(ble_advdata_t const * const p_le_advdata, + ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len) +{ + nfc_ndef_msg_desc_t * p_full_hs_msg_desc; + ret_code_t err_code; + + err_code = nfc_ble_full_handover_select_msg_declare(p_le_advdata, + p_ep_advdata, + &p_full_hs_msg_desc); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!m_tk_modifier_on) + { + nfc_tk_group_modifier_config(NULL, 0); + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_full_hs_msg_desc, + p_buf, + p_len); + + return err_code; +} + +ret_code_t nfc_ble_pair_default_msg_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len) +{ + ble_advdata_t le_adv_data; + ble_advdata_t ep_adv_data; + ret_code_t err_code = NRF_SUCCESS; + + switch (nfc_ble_pair_type) + { + + case NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT: + le_oob_specific_adv_data_create(p_tk_value, p_lesc_data, &le_adv_data); + err_code = nfc_ble_simplified_le_oob_msg_encode(&le_adv_data, p_buf, p_len); + break; + + case NFC_BLE_PAIR_MSG_BLUETOOTH_EP_SHORT: + ep_oob_specific_adv_data_create(p_tk_value, NULL, &ep_adv_data); + err_code = nfc_ble_simplified_ep_oob_msg_encode(&ep_adv_data, p_buf, p_len); + break; + + case NFC_BLE_PAIR_MSG_FULL: + le_oob_specific_adv_data_create(p_tk_value, p_lesc_data, &le_adv_data); + ep_oob_specific_adv_data_create(p_tk_value, NULL, &ep_adv_data); + err_code = nfc_ble_full_handover_select_msg_encode(&le_adv_data, + &ep_adv_data, + p_buf, + p_len); + break; + + } + + return err_code; +} + +ret_code_t nfc_ble_pair_msg_updatable_tk_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len, + uint8_t ** pp_tk_group, + uint8_t max_group_size) +{ + ret_code_t err_code = NRF_SUCCESS; + + m_tk_modifier_on = true; + nfc_tk_group_modifier_config(pp_tk_group, max_group_size); + err_code = nfc_ble_pair_default_msg_encode(nfc_ble_pair_type, p_tk_value, + p_lesc_data, p_buf, p_len); + m_tk_modifier_on = false; + + return err_code; +} + +ret_code_t nfc_tk_group_modifier_update(ble_advdata_tk_value_t * p_tk_value) +{ + VERIFY_PARAM_NOT_NULL(m_tk_group.pp_tk_group); + for (uint8_t tk_index = 0; tk_index < m_tk_group.tk_num; ++tk_index) + { + uint8_t * p_tk_payload_data = m_tk_group.pp_tk_group[tk_index]; + nfc_tk_value_payload_encode(p_tk_value, p_tk_payload_data); + } + return NRF_SUCCESS; +} + +ret_code_t nfc_tk_to_group_add(uint8_t * p_tk_location) +{ + // Feature was disabled. + if (m_tk_group.pp_tk_group == NULL) + { + return NRF_SUCCESS; + } + + if (m_tk_group.tk_num < m_tk_group.tk_max_num) + { + m_tk_group.pp_tk_group[m_tk_group.tk_num++] = p_tk_location; + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NO_MEM; + } +} + +ret_code_t nfc_lesc_pos_set(uint8_t * p_confirm, uint8_t * p_random) +{ + if((p_confirm != NULL) && (p_random != NULL)) + { + m_lesc_pos.confirm = p_confirm; + m_lesc_pos.random = p_random; + + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NULL; + } +} + +ret_code_t nfc_lesc_data_update(ble_gap_lesc_oob_data_t * ble_lesc_oob_data) +{ + if(ble_lesc_oob_data != NULL) + { + if((ble_lesc_oob_data->c != NULL) && (ble_lesc_oob_data->r != NULL)) + { + memcpy(m_lesc_pos.confirm, ble_lesc_oob_data->c, AD_TYPE_CONFIRM_VALUE_DATA_SIZE); + memcpy(m_lesc_pos.random, ble_lesc_oob_data->r, AD_TYPE_RANDOM_VALUE_DATA_SIZE); + + return NRF_SUCCESS; + } + + return NRF_ERROR_INVALID_STATE; + } + else + { + return NRF_ERROR_NULL; + } +} diff --git a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h b/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h new file mode 100644 index 0000000..18814af --- /dev/null +++ b/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h @@ -0,0 +1,280 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_BLE_PAIR_MSG_H__ +#define NFC_BLE_PAIR_MSG_H__ + +/**@file + * + * @defgroup nfc_modules NDEF message modules + * @ingroup nfc_api + * @brief Implementation of NDEF messages. + * + * @defgroup nfc_ndef_messages Predefined NDEF messages + * @ingroup nfc_modules + * @brief Predefined NDEF messages for standard use. + * + * @defgroup nfc_ble_pair_msg BLE pairing messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages used for BLE pairing. + * + */ + +#include +#include "ble_advdata.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Types of BLE pairing message. + * + * Use one of these values to choose the type of NDEF BLE pairing message. + */ +typedef enum +{ + NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, ///< Simplified LE OOB message. + NFC_BLE_PAIR_MSG_BLUETOOTH_EP_SHORT, ///< Simplified EP OOB message. + NFC_BLE_PAIR_MSG_FULL ///< BLE Handover Select Message. +} nfc_ble_pair_type_t; + +/** @brief Function for encoding simplified LE OOB messages. + * + * This function encodes a simplified LE OOB message into a buffer. The payload of the LE OOB record + * inside the message can be configured via the advertising data structure. + * + * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC" + * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.3.2, + * and according to "Supplement to the Bluetooth Core Specification" (Version 5, adoption date: + * Dec 02 2014). + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] p_le_advdata Pointer to the BLE advertising data structure for the LE OOB record. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_simplified_le_oob_msg_encode(ble_advdata_t const * const p_le_advdata, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding simplified EP OOB messages. + * + * This function encodes a simplified EP OOB message into a buffer. The payload of the EP OOB record + * inside the message can be configured via the advertising data structure. + * + * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC" + * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.3.1, + * and according to "Supplement to the Bluetooth Core Specification" (Version 5, adoption date: + * Dec 02 2014). + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] p_ep_advdata Pointer to the BLE advertising data structure for the EP OOB record. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_simplified_ep_oob_msg_encode(ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding BLE Handover Select Messages. + * + * This function encodes a BLE Handover Select Message into a buffer. The payload of the LE OOB record + * and the EP OOB record inside the message can be configured via the advertising data structures. + * + * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC" + * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.1.1 + * and 4.1.2 (combined), and according to "Supplement to the Bluetooth Core Specification" (Version 5, + * adoption date: Dec 02 2014). + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] p_le_advdata Pointer to the BLE advertising data structure for the LE OOB record. + * @param[in] p_ep_advdata Pointer to the BLE advertising data structure for the EP OOB record. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_full_handover_select_msg_encode(ble_advdata_t const * const p_le_advdata, + ble_advdata_t const * const p_ep_advdata, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding any type of BLE pairing messages with default BLE + * advertising data structures. + * + * This function encodes a BLE pairing message into a buffer. The message can be encoded as + * one of the three message types (using @ref nfc_ble_simplified_le_oob_msg_encode, + * @ref nfc_ble_simplified_ep_oob_msg_encode, or @ref nfc_ble_full_handover_select_msg_encode), + * according to the @p nfc_ble_pair_type parameter. LE and EP OOB records use the default + * advertising data structure configuration. Only one field ('Security Manager TK') in the BLE + * advertising data can be configured for both records by specifying the @p p_tk_value parameter. + * + * For LE OOB records, the default BLE advertising data structure configuration fills the required + * fields 'LE Bluetooth Device Address' and 'LE Role' and the optional fields 'Appearance', + * 'Local Name', and 'Flags'. + * + * For EP OOB records, the default BLE advertising data structure configuration fills the required + * field 'Security Manager Out Of Band Flags' and the optional fields 'Appearance', + * 'Local Name', and 'Flags'. + * + * @note To be able to encode the message, a SoftDevice must be enabled and configured. + * + * @param[in] nfc_ble_pair_type Type of BLE pairing message. + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK value field is not encoded in the NDEF message. + * @param[in] p_lesc_data Pointer to the LESC OOB data. If NULL, LESC OOB fields are + * not encoded in the NDEF message. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_pair_default_msg_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len); + +/** @brief Function for encoding any type of BLE pairing messages with default BLE + * advertising data structures and with TK modifier feature. + * + * This function is very similar to @ref nfc_ble_pair_default_msg_encode function, but + * additionaly it enables to track TK locations which were encoded in Connection Handover + * NDEF message. After using this function, you can update TK value in NDEF by calling + * @ref nfc_tk_group_modifier_update. + * + * @param[in] nfc_ble_pair_type Type of BLE pairing message. + * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL, + * TK value field is not encoded in the NDEF message. + * @param[in] p_lesc_data Pointer to the LESC OOB data. If NULL, LESC OOB values are + * not encoded in the NDEF message. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * @param[in] pp_tk_group Pointer to array of TK locations that should be modified with + * @ref nfc_tk_group_modifier_update function. + * @param[in] max_group_size Maximal number of TK locations that can added to \p pp_tk_group. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +ret_code_t nfc_ble_pair_msg_updatable_tk_encode(nfc_ble_pair_type_t nfc_ble_pair_type, + ble_advdata_tk_value_t * const p_tk_value, + ble_gap_lesc_oob_data_t * const p_lesc_data, + uint8_t * p_buf, + uint32_t * p_len, + uint8_t ** pp_tk_group, + uint8_t max_group_size); + +/**@brief Function for updating the Connection Handover NDEF message with new TK value. + * + * @details This function updates NDEF message with new TK value. This update is applied to all of + * TK locations in the Connection Handover NDEF message. This function can only be used + * after calling @ref nfc_ble_pair_msg_updatable_tk_encode, which is used to encode + * Connection Handover NDEF message. + * + * @param[in] p_tk_value Pointer to the new TK value. The NDEF message will be updated with this + * value. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If pointer to TK locations was NULL. + */ +ret_code_t nfc_tk_group_modifier_update(ble_advdata_tk_value_t * p_tk_value); + +/**@brief Function for adding new location of TK value to the location description structure. + * + * @param[in] p_tk_location New location of TK value in the Connection Handover NDEF message. + * + * @retval NRF_SUCCESS If the operation was successful or if buffer used for holding TK + * locations is NULL. + * @retval NRF_ERROR_NO_MEM If there is no place in the buffer for the new TK value location. + */ +ret_code_t nfc_tk_to_group_add(uint8_t * p_tk_location); + +/**@brief Function for updating the Connection Handover NDEF message with a new LESC OOB values. + * + * @details Updates LESC Confirmation and Random Values based on its locations set by the @ref nfc_lesc_pos_set function. + * + * @param[in] ble_lesc_oob_data Pointer to the new LESC OOB data. The NDEF message will be updated with this data. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If pointer to the new LESC OOB data is NULL. + * @retval NRF_ERROR_INVALID_STATE If pointer to the LESC OOB data location in NDEF message is NULL. + */ +ret_code_t nfc_lesc_data_update(ble_gap_lesc_oob_data_t * ble_lesc_oob_data); + +/**@brief Function for storing pointers to the LESC OOB data inside NDEF message. + * + * @details It allows LESC OOB data update without regenerating entire CH NDEF message. + * + * @param[in] p_confirm Pointer to the LESC Confirmation Value position in the NDEF message. + * @param[in] p_random Pointer to the LESC Random Value position in the NDEF message. + * + * @retval NRF_SUCCESS If the operation was successful. + * @retval NRF_ERROR_NULL If either of pointers is set to NULL. + */ +ret_code_t nfc_lesc_pos_set(uint8_t * p_confirm, uint8_t * p_random); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_BLE_PAIR_MSG_H__ diff --git a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c b/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c new file mode 100644 index 0000000..fc59ab9 --- /dev/null +++ b/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include + +/* Record Payload Type for Bluetooth Carrier Configuration LE record */ +const uint8_t le_oob_rec_type_field[] = +{ + 'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'v', 'n', 'd', '.', + 'b', 'l', 'u', 'e', 't', 'o', 'o', 't', 'h', '.', 'l', 'e', '.', 'o', 'o', 'b' +}; diff --git a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h b/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h new file mode 100644 index 0000000..f4b9aee --- /dev/null +++ b/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include + +/* Record Payload Type for Bluetooth Carrier Configuration LE record */ +extern const uint8_t le_oob_rec_type_field[32]; diff --git a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c b/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c new file mode 100644 index 0000000..6dfc494 --- /dev/null +++ b/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c @@ -0,0 +1,238 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nfc_ep_oob_rec.h" +#include "sdk_errors.h" +#include "ble_gap.h" +#include "app_util.h" + +/* NFC OOB EP definitions */ +#define NFC_EP_OOB_REC_GAP_ADDR_LEN BLE_GAP_ADDR_LEN +#define NFC_EP_OOB_REC_OOB_DATA_LEN_SIZE 2UL +#define NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN (NFC_EP_OOB_REC_GAP_ADDR_LEN + \ + NFC_EP_OOB_REC_OOB_DATA_LEN_SIZE) + +/* Record Payload Type for Bluetooth Carrier Configuration EP record */ +static const uint8_t ep_oob_rec_type_field[] = +{ + 'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'v', 'n', 'd', '.', + 'b', 'l', 'u', 'e', 't', 'o', 'o', 't', 'h', '.', 'e', 'p', '.', 'o', 'o', 'b' +}; + +/** + * @brief Function for validating AD structure content for a Bluetooth Carrier Configuration EP record. + * + * This function validates AD structure content. LE Bluetooth Device Address and LE Role + * fields must not be included. Security Manager OOB Flags structure is required. + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * + * @retval NRF_SUCCESS If the validation was successful. + * @retval NRF_ERROR_INVALID_PARAM Otherwise. + */ +static ret_code_t nfc_ep_oob_adv_data_check(ble_advdata_t const * const p_ble_advdata) +{ + if ((true == p_ble_advdata->include_ble_device_addr) || + (BLE_ADVDATA_ROLE_NOT_PRESENT != p_ble_advdata->le_role) || + (NULL == p_ble_advdata->p_sec_mgr_oob_flags)) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* If Flags field in AD structure is present, the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag + must be set. */ + if ((0 != p_ble_advdata->flags) && + ((p_ble_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)) + { + return NRF_ERROR_INVALID_PARAM; + } + return NRF_SUCCESS; +} + +/** + * @brief Function for encoding device address to Bluetooth Carrier Configuration EP record. + * + * This fuction is used to encode device address to Bluetooth Carrier Configuration EP record. + * + * @param[in] p_encoded_data Pointer to the buffer where encoded data will be returned. + * @param[in] max_len Available memory in the buffer. + * + * @retval NRF_SUCCESS If the encoding was successful. + * @retval NRF_ERROR_NO_MEM If available memory was not enough. + * @retval NRF_ERROR_xxx If any other error occured. + */ +static ret_code_t nfc_ep_oob_bluetooth_device_address_encode(uint8_t * const p_encoded_data, + uint16_t max_len) +{ + ret_code_t err_code = NRF_SUCCESS; + ble_gap_addr_t device_address; + + memset(&device_address, 0x00, sizeof(device_address)); + + if (NFC_EP_OOB_REC_GAP_ADDR_LEN > max_len) + { + return NRF_ERROR_NO_MEM; + } + + /* Get BLE address */ + #if (NRF_SD_BLE_API_VERSION == 2) + err_code = sd_ble_gap_address_get(&device_address); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + #endif + + #if (NRF_SD_BLE_API_VERSION == 3) + err_code = sd_ble_gap_addr_get(&device_address); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + #endif + + /* Encode Bluetooth EP device address */ + memcpy(p_encoded_data, device_address.addr, NFC_EP_OOB_REC_GAP_ADDR_LEN); + + return NRF_SUCCESS; +} + +/** + * @brief Function for constructing the payload for a Bluetooth Carrier Configuration EP record. + * + * This function encodes the record payload according to the BLE AD structure. It implements + * an API compatible with @ref p_payload_constructor_t. + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the record payload was encoded successfully. + * @retval NRF_ERROR_NO_MEM If available memory was not enough for record payload to be encoded. + * @retval Other If any other error occurred during record payload encoding. + */ +static ret_code_t nfc_ep_oob_payload_constructor(ble_advdata_t * p_ble_advdata, + uint8_t * p_buff, + uint32_t * p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + uint8_t * p_ad_data = NULL; + uint16_t payload_len, ad_data_len; + + /* Check correctness of the configuration structure */ + err_code = nfc_ep_oob_adv_data_check(p_ble_advdata); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + + if (p_buff != NULL) + { + /* Validate if there is enough memory for OOB payload length field and BLE device address */ + if (NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + /* Set proper memory offset in payload buffer for AD structure and count available memory. + * Bluetooth EP device address and OOB payload length field must be inserted before the AD payload */ + p_ad_data = (uint8_t *) (p_buff + NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN); + ad_data_len = *p_len - NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN; + if ( *p_len - NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN > UINT16_MAX ) + { + ad_data_len = UINT16_MAX; + } + } + + /* Encode AD structures into NFC record payload */ + err_code = nfc_ble_oob_adv_data_encode(p_ble_advdata, p_ad_data, &ad_data_len); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + + /* Now as the final payload length is known OOB payload length field, and Bluetooth device + * address can be encoded */ + payload_len = ad_data_len + NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN; + if (p_buff != NULL) + { + p_buff += uint16_encode(payload_len, p_buff); + err_code = nfc_ep_oob_bluetooth_device_address_encode(p_buff, p_ad_data - p_buff); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + } + + /* Update total payload length */ + *p_len = payload_len; + + return err_code; +} + + +nfc_ndef_record_desc_t * nfc_ep_oob_rec_declare(uint8_t rec_payload_id, + ble_advdata_t const * const p_ble_advdata) +{ + static uint8_t payload_id = 0; + + NFC_NDEF_GENERIC_RECORD_DESC_DEF( nfc_ep_oob_rec, + TNF_MEDIA_TYPE, + &payload_id, // memory for possible ID value + 0, // no ID by default + (ep_oob_rec_type_field), + sizeof(ep_oob_rec_type_field), + nfc_ep_oob_payload_constructor, + NULL); + + nfc_ndef_record_desc_t * nfc_ep_oob_rec = &NFC_NDEF_GENERIC_RECORD_DESC( nfc_ep_oob_rec); + + /* Update record descriptor */ + nfc_ep_oob_rec->p_payload_descriptor = (void *) p_ble_advdata; + + /* Handle record ID configuration */ + payload_id = rec_payload_id; + nfc_ep_oob_rec->id_length = (rec_payload_id != 0) ? 1 : 0; + + return nfc_ep_oob_rec; +} diff --git a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h b/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h new file mode 100644 index 0000000..90d106b --- /dev/null +++ b/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_EP_OOB_REC_H__ +#define NFC_EP_OOB_REC_H__ + +/**@file + * + * @defgroup nfc_ep_oob_rec EP OOB records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF EP OOB records for NDEF messages. + * + */ + +#include +#include "nfc_ndef_record.h" +#include "nfc_ble_oob_advdata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for generating a description of an NFC NDEF Bluetooth Carrier Configuration EP record. + * + * This function declares and initializes a static instance of an NFC NDEF record description + * for a Bluetooth Carrier Configuration EP record. + * + * @note The record payload data (@p p_ble_advdata) should be declared as static. If it is + * declared as automatic, the NDEF message encoding (see @ref nfc_ble_simplified_ep_oob_msg_encode) + * must be done in the same variable scope. + * + * @param[in] rec_payload_id NDEF record header Payload ID field (limited to one byte). + * If 0, no ID is present in the record description. + * @param[in] p_ble_advdata Pointer to the encoded BLE advertising data structure. This + * data is used to create the record payload. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_ep_oob_rec_declare(uint8_t rec_payload_id, + ble_advdata_t const * const p_ble_advdata); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_EP_OOB_REC_H__ diff --git a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c b/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c new file mode 100644 index 0000000..82b5bbf --- /dev/null +++ b/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nfc_hs_rec.h" +#include "nfc_ac_rec.h" +#include "nrf_error.h" + +#define HS_REC_VERSION_SIZE 1 + +const uint8_t nfc_hs_rec_type_field[] = {'H', 's'}; ///< Handover Select record type. + + +ret_code_t nfc_hs_rec_payload_constructor(nfc_hs_rec_payload_desc_t * p_nfc_hs_rec_payload_desc, + uint8_t * p_buff, + uint32_t * p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + + if (p_buff != NULL) + { + // There must be at least 1 free byte in buffer for version byte. + if (*p_len < HS_REC_VERSION_SIZE) + { + return NRF_ERROR_NO_MEM; + } + + // Major/minor version byte. + *p_buff = ( (p_nfc_hs_rec_payload_desc->major_version << 4) & 0xF0) | + ( p_nfc_hs_rec_payload_desc->minor_version & 0x0F); + p_buff += HS_REC_VERSION_SIZE; + + // Decrement remaining buffer size. + *p_len -= HS_REC_VERSION_SIZE; + } + + // Encode local records encapsulated in a message. + err_code = nfc_ndef_msg_encode(p_nfc_hs_rec_payload_desc->p_local_records, p_buff, p_len); + if (err_code!= NRF_SUCCESS) + { + return err_code; + } + + // Add version byte to the total record size. + *p_len += HS_REC_VERSION_SIZE; + + return NRF_SUCCESS; +} + + +void nfc_hs_rec_local_record_clear(nfc_ndef_record_desc_t * p_hs_rec) +{ + nfc_hs_rec_payload_desc_t* p_hs_payload = + (nfc_hs_rec_payload_desc_t*)p_hs_rec->p_payload_descriptor; + + nfc_ndef_msg_clear(p_hs_payload->p_local_records); +} + + +ret_code_t nfc_hs_rec_local_record_add(nfc_ndef_record_desc_t * p_hs_rec, + nfc_ndef_record_desc_t * p_local_rec) +{ + nfc_hs_rec_payload_desc_t* p_hs_payload = + (nfc_hs_rec_payload_desc_t*)p_hs_rec->p_payload_descriptor; + + return nfc_ndef_msg_record_add(p_hs_payload->p_local_records, p_local_rec); +} diff --git a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h b/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h new file mode 100644 index 0000000..87a0b95 --- /dev/null +++ b/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_HS_REC_H__ +#define NFC_HS_REC_H__ + +/**@file + * + * @defgroup nfc_hs_rec Hs (Handover Select) records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF Handover Select records for NDEF messages. + * + */ + +#include +#include "nfc_ndef_record.h" +#include "nfc_ndef_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Handover Select record payload descriptor. + */ +typedef struct +{ + uint8_t major_version; ///< Major version number of the supported Connection Handover specification. + uint8_t minor_version; ///< Minor version number of the supported Connection Handover specification. + nfc_ndef_msg_desc_t * p_local_records; ///< Pointer to a message encapsulating local records. +} nfc_hs_rec_payload_desc_t; + + +/** + * @brief Constructor for an NFC NDEF Handover Select record payload. + * + * This function encodes the payload of a Handover Select record as specified in the Connection + * Handover standard. It implements an API compatible with @ref p_payload_constructor_t. + */ + +ret_code_t nfc_hs_rec_payload_constructor(nfc_hs_rec_payload_desc_t * p_nfc_hs_rec_payload_desc, + uint8_t * p_buff, + uint32_t * p_len); + +/** + * @brief An external reference to the type field of the Handover Select record, defined in the + * file @c nfc_hs_rec.c. It is used in the @ref NFC_NDEF_HS_RECORD_DESC_DEF macro. + */ +extern const uint8_t nfc_hs_rec_type_field[]; + +/** + * @brief Size of the type field of the Handover Select record, defined in the + * file @c nfc_hs_rec.c. It is used in the @ref NFC_NDEF_HS_RECORD_DESC_DEF macro. + */ +#define NFC_HS_REC_TYPE_LENGTH 2 + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a Handover Select record. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and + * a static instance of type @ref nfc_hs_rec_payload_desc_t, which together constitute an instance of a Handover Select record. + * + * Use the macro @ref NFC_NDEF_HS_RECORD_DESC to access the NDEF Handover Select record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] MAJOR_VERSION Major version number of the supported Connection Handover specification. + * @param[in] MINOR_VERSION Minor version number of the supported Connection Handover specification. + * @param[in] MAX_RECORDS Maximum number of local records (ac records plus optional err record). + */ +#define NFC_NDEF_HS_RECORD_DESC_DEF(NAME, \ + MAJOR_VERSION, \ + MINOR_VERSION, \ + MAX_RECORDS) \ + NFC_NDEF_MSG_DEF(NAME, MAX_RECORDS); \ + static nfc_hs_rec_payload_desc_t NAME##_nfc_hs_rec_payload_desc = \ + { \ + .major_version = MAJOR_VERSION, \ + .minor_version = MINOR_VERSION, \ + .p_local_records = &NFC_NDEF_MSG(NAME) \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_WELL_KNOWN, \ + 0, \ + 0, \ + nfc_hs_rec_type_field , \ + NFC_HS_REC_TYPE_LENGTH, \ + nfc_hs_rec_payload_constructor, \ + &(NAME##_nfc_hs_rec_payload_desc)) + +/** + * @brief Macro for accessing the NFC NDEF Handover Select record descriptor + * instance that was created with @ref NFC_NDEF_HS_RECORD_DESC_DEF. + */ +#define NFC_NDEF_HS_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** + * @brief Function for clearing local records in the NFC NDEF Handover Select record. + * + * This function clears local records from the Handover Select record. + * + * @param[in, out] p_hs_rec Pointer to the Handover Select record descriptor. + */ +void nfc_hs_rec_local_record_clear(nfc_ndef_record_desc_t * p_hs_rec); + +/** + * @brief Function for adding a local record to an NFC NDEF Handover Select record. + * + * @param[in, out] p_hs_rec Pointer to a Handover Select record. + * @param[in] p_local_rec Pointer to a local record to add. + * + * @retval NRF_SUCCESS If the local record was added successfully. + * @retval NRF_ERROR_NO_MEM If the Handover Select record already contains the maximum number of local records. + */ +ret_code_t nfc_hs_rec_local_record_add(nfc_ndef_record_desc_t * p_hs_rec, + nfc_ndef_record_desc_t * p_local_rec); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_HS_REC_H__ diff --git a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c b/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c new file mode 100644 index 0000000..5c757ad --- /dev/null +++ b/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c @@ -0,0 +1,144 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nfc_le_oob_rec.h" +#include "sdk_errors.h" +#include "ble_gap.h" +#include "nfc_ble_pair_common.h" + +/** + * @brief Function for validating AD structure content for a Bluetooth Carrier Configuration LE record. + * + * This function validates AD structure content. LE Bluetooth Device Address and LE Role + * fields are required. Security Manager Out Of Band Flags structure must not be included. + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * + * @retval NRF_SUCCESS If the validation was successful. + * @retval NRF_ERROR_INVALID_PARAM Otherwise. + */ +static ret_code_t nfc_le_oob_adv_data_check(ble_advdata_t const * const p_ble_advdata) +{ + if ((false == p_ble_advdata->include_ble_device_addr) || + (BLE_ADVDATA_ROLE_NOT_PRESENT == p_ble_advdata->le_role) || + (NULL != p_ble_advdata->p_sec_mgr_oob_flags)) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* If Flags field in AD structure is present, the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag + must be set. */ + if ((0 != p_ble_advdata->flags) && + ((p_ble_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0)) + { + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + +/** + * @brief Function for constructing the payload for a Bluetooth Carrier Configuration LE record. + * + * This function encodes the record payload according to the BLE AD structure. It implements + * an API compatible with @ref p_payload_constructor_t + * + * @param[in] p_ble_advdata Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the record payload was encoded successfully. + * @retval Other If the record payload encoding failed. + */ +static ret_code_t nfc_le_oob_payload_constructor(ble_advdata_t * p_ble_advdata, + uint8_t * p_buff, + uint32_t * p_len) +{ + ret_code_t err_code = NRF_SUCCESS; + + /* Check correctness of the configuration structure */ + err_code = nfc_le_oob_adv_data_check(p_ble_advdata); + if (NRF_SUCCESS != err_code) + { + return err_code; + } + + /* Encode AD structures into NFC record payload */ + uint16_t buff_len = *p_len; + if (*p_len > UINT16_MAX) + { + buff_len = UINT16_MAX; + } + err_code = nfc_ble_oob_adv_data_encode(p_ble_advdata, p_buff, &buff_len); + + /* Update total payload length */ + *p_len = (uint32_t) buff_len; + + return err_code; +} + +nfc_ndef_record_desc_t * nfc_le_oob_rec_declare(uint8_t rec_payload_id, + ble_advdata_t const * const p_ble_advdata) +{ + static uint8_t payload_id = 0; + + NFC_NDEF_GENERIC_RECORD_DESC_DEF( nfc_le_oob_rec, + TNF_MEDIA_TYPE, + &payload_id, // memory for possible ID value + 0, // no ID by default + (le_oob_rec_type_field), + sizeof(le_oob_rec_type_field), + nfc_le_oob_payload_constructor, + NULL); + + nfc_ndef_record_desc_t * nfc_le_oob_rec = &NFC_NDEF_GENERIC_RECORD_DESC( nfc_le_oob_rec); + + /* Update record descriptor */ + nfc_le_oob_rec->p_payload_descriptor = (void *) p_ble_advdata; + + /* Handle record ID configuration */ + payload_id = rec_payload_id; + nfc_le_oob_rec->id_length = (rec_payload_id != 0) ? 1 : 0; + + return nfc_le_oob_rec; +} diff --git a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h b/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h new file mode 100644 index 0000000..3957364 --- /dev/null +++ b/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h @@ -0,0 +1,87 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_LE_OOB_REC_H__ +#define NFC_LE_OOB_REC_H__ + +/**@file + * + * @defgroup nfc_le_oob_rec LE OOB records + * @{ + * @ingroup nfc_ble_pair_msg + * + * @brief Generation of NFC NDEF LE OOB records for NDEF messages. + * + */ + +#include +#include "nfc_ndef_record.h" +#include "nfc_ble_oob_advdata.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for generating a description of an NFC NDEF Bluetooth Carrier Configuration LE Record. + * + * This function declares and initializes a static instance of an NFC NDEF record description + * for a Bluetooth Carrier Configuration LE record. + * + * @note The record payload data (@p p_ble_advdata) should be declared as static. If it is + * declared as automatic, the NDEF message encoding (see @ref nfc_ble_simplified_le_oob_msg_encode) + * must be done in the same variable scope. + * + * @param[in] rec_payload_id NDEF record header Payload ID field (Limited to one byte). + * If 0, no ID is present in the record description. + * @param[in] p_ble_advdata Pointer to the encoded BLE advertising data structure. This + * data is used to create the record payload. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_le_oob_rec_declare(uint8_t rec_payload_id, + ble_advdata_t const * const p_ble_advdata); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_LE_OOB_REC_H__ diff --git a/components/nfc/ndef/generic/message/nfc_ndef_msg.c b/components/nfc/ndef/generic/message/nfc_ndef_msg.c new file mode 100644 index 0000000..75ab89f --- /dev/null +++ b/components/nfc/ndef/generic/message/nfc_ndef_msg.c @@ -0,0 +1,186 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if NFC_NDEF_MSG_ENABLED + +#include "app_util.h" +#include "nfc_ndef_msg.h" +#include "nordic_common.h" +#include "nrf.h" + +#define TYPE_4_TAG 4U ///< Type 4 Tag identifier. +#define NLEN_FIELD_SIZE 2U ///< Size of NLEN field, used to encode NDEF message for Type 4 Tag. + +/** + * @brief Resolve the value of record location flags of the NFC NDEF record within an NFC NDEF message. + */ +__STATIC_INLINE nfc_ndef_record_location_t record_location_get(uint32_t index, + uint32_t record_count) +{ + nfc_ndef_record_location_t record_location; + + if (index == 0) + { + if (record_count == 1) + { + record_location = NDEF_LONE_RECORD; + } + else + { + record_location = NDEF_FIRST_RECORD; + } + } + else if (record_count == index + 1) + { + record_location = NDEF_LAST_RECORD; + } + else + { + record_location = NDEF_MIDDLE_RECORD; + } + + return record_location; +} + + +ret_code_t nfc_ndef_msg_encode(nfc_ndef_msg_desc_t const * p_ndef_msg_desc, + uint8_t * p_msg_buffer, + uint32_t * const p_msg_len) +{ + nfc_ndef_record_location_t record_location; + uint32_t temp_len; + uint32_t i; + uint32_t err_code; + + uint32_t sum_of_len = 0; + + if ((p_ndef_msg_desc == NULL) || p_msg_len == NULL) + { + return NRF_ERROR_NULL; + } + + nfc_ndef_record_desc_t * * pp_record_rec_desc = p_ndef_msg_desc->pp_record; + + if (p_ndef_msg_desc->pp_record == NULL) + { + return NRF_ERROR_NULL; + } + +#if NFC_NDEF_MSG_TAG_TYPE == TYPE_4_TAG + uint8_t * p_root_msg_buffer = p_msg_buffer; + + if (p_msg_buffer != NULL) + { + if (*p_msg_len < NLEN_FIELD_SIZE) + { + return NRF_ERROR_NO_MEM; + } + + p_msg_buffer += NLEN_FIELD_SIZE; + } + sum_of_len += NLEN_FIELD_SIZE; +#endif + + for (i = 0; i < p_ndef_msg_desc->record_count; i++) + { + record_location = record_location_get(i, p_ndef_msg_desc->record_count); + + temp_len = *p_msg_len - sum_of_len; + + err_code = nfc_ndef_record_encode(*pp_record_rec_desc, + record_location, + p_msg_buffer, + &temp_len); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + sum_of_len += temp_len; + if (p_msg_buffer != NULL) + { + p_msg_buffer += temp_len; + } + + /* next record */ + pp_record_rec_desc++; + } + +#if NFC_NDEF_MSG_TAG_TYPE == TYPE_4_TAG + if (p_msg_buffer != NULL) + { + if (sum_of_len - NLEN_FIELD_SIZE > UINT16_MAX) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + UNUSED_RETURN_VALUE(uint16_big_encode(sum_of_len - NLEN_FIELD_SIZE, p_root_msg_buffer)); + } +#endif + + *p_msg_len = sum_of_len; + + return NRF_SUCCESS; +} + + +void nfc_ndef_msg_clear(nfc_ndef_msg_desc_t * p_msg) +{ + p_msg->record_count = 0; +} + + +ret_code_t nfc_ndef_msg_record_add(nfc_ndef_msg_desc_t * const p_msg, + nfc_ndef_record_desc_t * const p_record) +{ + if (p_msg->record_count >= p_msg->max_record_count) + { + return NRF_ERROR_NO_MEM; + } + + p_msg->pp_record[p_msg->record_count] = p_record; + p_msg->record_count++; + + return NRF_SUCCESS; +} + +#endif // NFC_NDEF_MSG_ENABLED diff --git a/components/nfc/ndef/generic/message/nfc_ndef_msg.h b/components/nfc/ndef/generic/message/nfc_ndef_msg.h new file mode 100644 index 0000000..f9ab4d2 --- /dev/null +++ b/components/nfc/ndef/generic/message/nfc_ndef_msg.h @@ -0,0 +1,189 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_NDEF_MSG_H__ +#define NFC_NDEF_MSG_H__ + +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif +/**@file + * + * @defgroup nfc_ndef_msg Custom NDEF messages + * @{ + * @ingroup nfc_modules + * + * @brief Generation of NFC NDEF messages for the NFC tag. + * + */ + + /** + * @brief NDEF message descriptor. + */ + typedef struct { + nfc_ndef_record_desc_t ** pp_record; ///< Pointer to an array of pointers to NDEF record descriptors. + uint32_t max_record_count; ///< Number of elements in the allocated pp_record array, which defines the maximum number of records within the NDEF message. + uint32_t record_count; ///< Number of records in the NDEF message. + } nfc_ndef_msg_desc_t; + + /** + * @brief Function for encoding an NDEF message. + * + * This function encodes an NDEF message according to the provided message descriptor. + * + * @note The way of encoding an NDEF message may vary depending on tag's platform, which + * can be chosen with @ref NFC_NDEF_MSG_TAG_TYPE in @c sdk_config.h. + * + * @param[in] p_ndef_msg_desc Pointer to the message descriptor. + * @param[out] p_msg_buffer Pointer to the message destination. If NULL, function will + * calculate the expected size of the message. + * @param[in,out] p_msg_len Size of the available memory for the message as input. Size of + * the generated message as output. + * + * @return Return value from @ref nfc_ndef_record_encode. + */ +ret_code_t nfc_ndef_msg_encode(nfc_ndef_msg_desc_t const * p_ndef_msg_desc, + uint8_t * p_msg_buffer, + uint32_t * const p_msg_len); + +/** + * @brief Function for clearing an NDEF message. + * + * This function clears an NDEF message descriptor, thus empties the NDEF message. + * + * @param[in,out] p_msg Pointer to the message descriptor. + */ +void nfc_ndef_msg_clear( nfc_ndef_msg_desc_t * p_msg); + +/** + * @brief Function for adding a record to an NDEF message. + * + * @param[in] p_record Pointer to the record descriptor. + * @param[in,out] p_msg Pointer to the message descriptor. + * + * @retval NRF_SUCCESS If the record was added successfully. + * @retval NRF_ERROR_NO_MEM If the message already contains the maximum number of records and the operation is not allowed. + */ +ret_code_t nfc_ndef_msg_record_add(nfc_ndef_msg_desc_t * const p_msg, + nfc_ndef_record_desc_t * const p_record); + + +/**@brief Macro for creating and initializing an NFC NDEF message descriptor. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_msg_desc_t + * and a static array of pointers to record descriptors (@ref nfc_ndef_record_desc_t) used + * by the message. + * + * Use the macro @ref NFC_NDEF_MSG to access the NDEF message descriptor instance. + * + * @param[in] NAME Name of the related instance. + * @param[in] MAX_RECORD_CNT Maximal count of records in the message. + */ +#define NFC_NDEF_MSG_DEF(NAME, MAX_RECORD_CNT) \ + static nfc_ndef_record_desc_t * NAME##_nfc_ndef_p_record_desc_array[MAX_RECORD_CNT]; \ + static nfc_ndef_msg_desc_t NAME##_nfc_ndef_msg_desc = \ + { \ + .pp_record = NAME##_nfc_ndef_p_record_desc_array, \ + .record_count = 0, \ + .max_record_count = MAX_RECORD_CNT \ + } + +/** @brief Macro for accessing the NFC NDEF message descriptor instance + * that you created with @ref NFC_NDEF_MSG_DEF. + */ +#define NFC_NDEF_MSG(NAME) (NAME##_nfc_ndef_msg_desc) + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor with an encapsulated NDEF message. + + * This macro creates and initializes a static instance of type + * @ref nfc_ndef_record_desc_t that contains an encapsulated NDEF message as + * payload. @ref nfc_ndef_msg_encode is used as payload constructor to encode + * the message. The encoded message is then used as payload for the record. + * + * Use the macro @ref NFC_NDEF_NESTED_NDEF_MSG_RECORD to access the NDEF record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_NESTED_MESSAGE Pointer to the message descriptor to encapsulate + * as the record's payload. + */ +#define NFC_NDEF_NESTED_NDEF_MSG_RECORD_DEF( NAME, \ + TNF, \ + P_ID, \ + ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_NESTED_MESSAGE ) \ + static nfc_ndef_record_desc_t NAME##_ndef_record_nested_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t)(nfc_ndef_msg_encode), \ + .p_payload_descriptor = (void*) (P_NESTED_MESSAGE) \ + } + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_NESTED_NDEF_MSG_RECORD_DEF. + */ +#define NFC_NDEF_NESTED_NDEF_MSG_RECORD(NAME) (NAME##_ndef_record_nested_desc) + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + #endif + diff --git a/components/nfc/ndef/generic/record/nfc_ndef_record.c b/components/nfc/ndef/generic/record/nfc_ndef_record.c new file mode 100644 index 0000000..7d594fc --- /dev/null +++ b/components/nfc/ndef/generic/record/nfc_ndef_record.c @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "nfc_ndef_record.h" +#include "app_util.h" +#include "nrf.h" + + +/* Sum of sizes of fields: TNF-flags, Type Length, Payload Length in long NDEF record. */ +#define NDEF_RECORD_BASE_LONG_SIZE (2 + NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE) + +__STATIC_INLINE uint32_t record_header_size_calc(nfc_ndef_record_desc_t const * p_ndef_record_desc) +{ + uint32_t len = NDEF_RECORD_BASE_LONG_SIZE; + + len += p_ndef_record_desc->id_length + p_ndef_record_desc->type_length; + + if (p_ndef_record_desc->id_length > 0) + { + len++; + } + + return len; +} + + +ret_code_t nfc_ndef_record_encode(nfc_ndef_record_desc_t const * p_ndef_record_desc, + nfc_ndef_record_location_t record_location, + uint8_t * p_record_buffer, + uint32_t * p_record_len) +{ + uint8_t * p_flags; // use as pointer to TNF + flags field + uint8_t * p_payload_len = NULL; // use as pointer to payload length field + uint32_t record_payload_len; + + if (p_ndef_record_desc == NULL) + { + return NRF_ERROR_NULL; + } + + // count record length without payload + uint32_t record_header_len = record_header_size_calc(p_ndef_record_desc); + uint32_t err_code = NRF_SUCCESS; + + if (p_record_buffer != NULL) + { + /* verify location range */ + if ((record_location & (~NDEF_RECORD_LOCATION_MASK)) != 0x00) + { + return NRF_ERROR_INVALID_PARAM; + } + + /* verify if there is enough available memory */ + if (record_header_len > *p_record_len) + { + return NRF_ERROR_NO_MEM; + } + + p_flags = p_record_buffer; + p_record_buffer++; + + // set location bits and clear other bits in 1st byte. + *p_flags = record_location; + + *p_flags |= p_ndef_record_desc->tnf; + + /* TYPE LENGTH */ + *(p_record_buffer++) = p_ndef_record_desc->type_length; + + // use always long record and remember payload len field memory offset. + p_payload_len = p_record_buffer; + p_record_buffer += NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE; + + /* ID LENGTH - option */ + if (p_ndef_record_desc->id_length > 0) + { + *(p_record_buffer++) = p_ndef_record_desc->id_length; + + /* IL flag */ + *p_flags |= NDEF_RECORD_IL_MASK; + } + + /* TYPE */ + memcpy(p_record_buffer, p_ndef_record_desc->p_type, p_ndef_record_desc->type_length); + p_record_buffer += p_ndef_record_desc->type_length; + + /* ID */ + if (p_ndef_record_desc->id_length > 0) + { + memcpy(p_record_buffer, p_ndef_record_desc->p_id, p_ndef_record_desc->id_length); + p_record_buffer += p_ndef_record_desc->id_length; + } + + // count how much memory is left in record buffer for payload field. + record_payload_len = (*p_record_len - record_header_len); + } + + /* PAYLOAD */ + if (p_ndef_record_desc->payload_constructor != NULL) + { + err_code = + p_ndef_record_desc->payload_constructor(p_ndef_record_desc->p_payload_descriptor, + p_record_buffer, + &record_payload_len); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + return NRF_ERROR_NULL; + } + + if (p_record_buffer != NULL) + { + /* PAYLOAD LENGTH */ + (void) uint32_big_encode(record_payload_len, p_payload_len); + } + + *p_record_len = record_header_len + record_payload_len; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_ndef_bin_payload_memcopy(nfc_ndef_bin_payload_desc_t * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len) +{ + + if (p_buffer != NULL) + { + if ( *p_len < p_payload_descriptor->payload_length) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_buffer, + p_payload_descriptor->p_payload, + p_payload_descriptor->payload_length); + } + + *p_len = p_payload_descriptor->payload_length; + + return NRF_SUCCESS; +} + + diff --git a/components/nfc/ndef/generic/record/nfc_ndef_record.h b/components/nfc/ndef/generic/record/nfc_ndef_record.h new file mode 100644 index 0000000..fc02f47 --- /dev/null +++ b/components/nfc/ndef/generic/record/nfc_ndef_record.h @@ -0,0 +1,306 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_NDEF_RECORD_H__ +#define NFC_NDEF_RECORD_H__ + +#include +#include +#include "compiler_abstraction.h" +#include "sdk_errors.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @defgroup nfc_ndef_record Custom NDEF records + * @{ + * @ingroup nfc_ndef_msg + * + * @brief Generation of NFC NDEF records for NFC messages. + * + */ + + +#define NDEF_RECORD_IL_MASK 0x08 ///< Mask of the ID field presence bit in the flags byte of an NDEF record. +#define NDEF_RECORD_TNF_MASK 0x07 ///< Mask of the TNF value field in the first byte of an NDEF record. +#define NDEF_RECORD_SR_MASK 0x10 ///< Mask of the SR flag. If set, this flag indicates that the PAYLOAD_LENGTH field has a size of 1 byte. Otherwise, PAYLOAD_LENGTH has 4 bytes. +#define NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE 4 ///< Size of the Payload Length field in a long NDEF record. +#define NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE 1 ///< Size of the Payload Length field in a short NDEF record. +#define NDEF_RECORD_ID_LEN_SIZE 1 ///< Size of the ID Length field in an NDEF record. + + +/** + * @brief Payload constructor type. + + * A payload constructor is a function for constructing the payload of an NDEF + * record. + * + * @param[in] p_payload_descriptor Pointer to the input data for the constructor. + * @param[out] p_buffer Pointer to the payload destination. If NULL, function will + * calculate the expected size of the record payload. + * + * @param[in,out] p_len Size of the available memory to write as input. Size of the generated + * record payload as output. The implementation must check if the payload + * will fit in the provided buffer. This must be checked by the caller function. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_xxx If an error occurred. + */ +typedef ret_code_t (* p_payload_constructor_t)(void * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len); + + +/** + * @brief Type Name Format (TNF) Field Values. + * + * Values to specify the TNF of a record. + */ +typedef enum +{ + TNF_EMPTY = 0x00, ///< The value indicates that there is no type or payload associated with this record. + TNF_WELL_KNOWN = 0x01, ///< NFC Forum well-known type [NFC RTD]. + TNF_MEDIA_TYPE = 0x02, ///< Media-type as defined in RFC 2046 [RFC 2046]. + TNF_ABSOLUTE_URI = 0x03, ///< Absolute URI as defined in RFC 3986 [RFC 3986]. + TNF_EXTERNAL_TYPE = 0x04, ///< NFC Forum external type [NFC RTD]. + TNF_UNKNOWN_TYPE = 0x05, ///< The value indicates that there is no type associated with this record. + TNF_UNCHANGED = 0x06, ///< The value is used for the record chunks used in chunked payload. + TNF_RESERVED = 0x07, ///< The value is reserved for future use. +} nfc_ndef_record_tnf_t; + + +/** + * @brief NDEF record descriptor. + */ +typedef struct +{ + nfc_ndef_record_tnf_t tnf; ///< Value of the Type Name Format (TNF) field. + + uint8_t id_length; ///< Length of the ID field. If 0, a record format without ID field is assumed. + uint8_t const * p_id; ///< Pointer to the ID field data. Not relevant if id_length is 0. + + uint8_t type_length; ///< Length of the type field. + uint8_t const * p_type; ///< Pointer to the type field data. Not relevant if type_length is 0. + + p_payload_constructor_t payload_constructor; ///< Pointer to the payload constructor function. + void * p_payload_descriptor; ///< Pointer to the data for the payload constructor function. + +} nfc_ndef_record_desc_t; + +/** + * @brief Record position within the NDEF message. + * + * Values to specify the location of a record within the NDEF message. + */ +typedef enum +{ + NDEF_FIRST_RECORD = 0x80, ///< First record. + NDEF_MIDDLE_RECORD = 0x00, ///< Middle record. + NDEF_LAST_RECORD = 0x40, ///< Last record. + NDEF_LONE_RECORD = 0xC0 ///< Only one record in the message. +} nfc_ndef_record_location_t; + +#define NDEF_RECORD_LOCATION_MASK (NDEF_LONE_RECORD) ///< Mask of the Record Location bits in the NDEF record's flags byte. + +/** + * @brief Binary data descriptor containing the payload for the record. + */ +typedef struct +{ + uint8_t const * p_payload; ///< Pointer to the buffer with the data. + uint32_t payload_length; ///< Length of data in bytes. +} nfc_ndef_bin_payload_desc_t; + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a generic record. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t. + * + * Use the macro @ref NFC_NDEF_GENERIC_RECORD_DESC to access the NDEF record descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_PAYLOAD_CONSTRUCTOR Pointer to the payload constructor function. + * The constructor must be of type @ref p_payload_constructor_t. + * @param[in] P_PAYLOAD_DESCRIPTOR Pointer to the data for the payload constructor. + */ +#define NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF, \ + P_ID, \ + ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_PAYLOAD_CONSTRUCTOR, \ + P_PAYLOAD_DESCRIPTOR) \ + static nfc_ndef_record_desc_t NAME##_ndef_generic_record_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t)P_PAYLOAD_CONSTRUCTOR, \ + .p_payload_descriptor = (void *) P_PAYLOAD_DESCRIPTOR \ + } + + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_GENERIC_RECORD_DESC_DEF. + */ +#define NFC_NDEF_GENERIC_RECORD_DESC(NAME) (NAME##_ndef_generic_record_desc) + +/** + * @brief Macro for creating and initializing an NFC NDEF record descriptor for a record with + * binary payload. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and a binary data descriptor containing the payload data. + * + * Use the macro @ref NFC_NDEF_RECORD_BIN_DATA to access the NDEF record descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] TNF Type Name Format (TNF) value for the record. + * @param[in] P_ID Pointer to the ID string. + * @param[in] ID_LEN Length of the ID string. + * @param[in] P_TYPE Pointer to the type string. + * @param[in] TYPE_LEN Length of the type string. + * @param[in] P_PAYLOAD Pointer to the payload data that will be copied to the payload field. + * @param[in] PAYLOAD_LEN Length of the payload. + */ +#define NFC_NDEF_RECORD_BIN_DATA_DEF(NAME, \ + TNF, \ + P_ID, ID_LEN, \ + P_TYPE, \ + TYPE_LEN, \ + P_PAYLOAD, \ + PAYLOAD_LEN) \ + static nfc_ndef_bin_payload_desc_t NAME##_nfc_ndef_bin_payload_desc = \ + { \ + .p_payload = P_PAYLOAD, \ + .payload_length = PAYLOAD_LEN \ + }; \ + \ + static nfc_ndef_record_desc_t NAME##_nfc_ndef_bin_record_desc = \ + { \ + .tnf = TNF, \ + \ + .id_length = ID_LEN, \ + .p_id = P_ID, \ + \ + .type_length = TYPE_LEN, \ + .p_type = P_TYPE, \ + \ + .payload_constructor = (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy, \ + .p_payload_descriptor = (void *) &NAME##_nfc_ndef_bin_payload_desc \ + } + + +/** @brief Macro for accessing the NFC NDEF record descriptor instance + * that you created with @ref NFC_NDEF_RECORD_BIN_DATA_DEF. + */ +#define NFC_NDEF_RECORD_BIN_DATA(NAME) (NAME##_nfc_ndef_bin_record_desc) + +/** @brief Macro for accessing the binary data descriptor that contains + * the payload of the record that you created with @ref NFC_NDEF_RECORD_BIN_DATA_DEF. + */ +#define NFC_NDEF_BIN_PAYLOAD_DESC(NAME) (NAME##_nfc_ndef_bin_payload_desc) + +/** + * @brief Function for encoding an NDEF record. + * + * This function encodes an NDEF record according to the provided record descriptor. + * + * @param[in] p_ndef_record_desc Pointer to the record descriptor. + * @param[in] record_location Location of the record within the NDEF message. + * @param[out] p_record_buffer Pointer to the record destination. If NULL, function will + * calculate the expected size of the record. + * @param[in,out] p_record_len Size of the available memory for the record as input. Size of the generated + * record as output. + * + * @retval NRF_SUCCESS If the record was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted record size is bigger than the provided buffer space. + * @retval NRF_ERROR_INVALID_PARAM If the location of the record is erroneous. + * @retval Other Other codes might be returned depending on the NDEF record payload constructor implementation. + */ +ret_code_t nfc_ndef_record_encode(nfc_ndef_record_desc_t const * p_ndef_record_desc, + nfc_ndef_record_location_t record_location, + uint8_t * p_record_buffer, + uint32_t * p_record_len); + +/** + * @brief Function for constructing the payload for an NFC NDEF record from binary data. + * + * This function copies data from a binary buffer to the payload field of the NFC NDEF record. + * + * @param[in] p_payload_descriptor Pointer to the descriptor of the binary data location and size. + * + * @param[out] p_buffer Pointer to the payload destination. If NULL, function will + * calculate the expected size of the record payload. + * @param[in,out] p_len Size of the available memory for the payload as input. Size of the copied payload + * as output. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the payload size is bigger than the provided buffer space. + */ +ret_code_t nfc_ndef_bin_payload_memcopy(nfc_ndef_bin_payload_desc_t * p_payload_descriptor, + uint8_t * p_buffer, + uint32_t * p_len); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_RECORD_H__ + diff --git a/components/nfc/ndef/launchapp/nfc_launchapp_msg.c b/components/nfc/ndef/launchapp/nfc_launchapp_msg.c new file mode 100644 index 0000000..2394398 --- /dev/null +++ b/components/nfc/ndef/launchapp/nfc_launchapp_msg.c @@ -0,0 +1,146 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "nfc_launchapp_rec.h" +#include "nfc_launchapp_msg.h" +#include "nrf_error.h" + +/** @brief Function for generating a description of an NFC NDEF launch application message. + * + * This function declares and initializes a static instance of an NFC NDEF message description + * and the NFC NDEF record descriptions that are referenced by this message description. + * + * @param[in] p_android_package_name Pointer to the Android package name string. + * If NULL, the Android Application Record will be skipped. + * @param[in] android_package_name_length Length of the Android package name. + * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID). + * If NULL, the Windows LaunchApp Record will be skipped. + * @param[in] win_app_id_length Length of the Windows application ID. + * @param[out] pp_launchapp_msg_desc Pointer to pointer to the NDEF message description. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If both p_android_package_name and windows_application_id were + * invalid (equal to NULL). + */ +__STATIC_INLINE ret_code_t nfc_launchapp_msg_declare(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + nfc_ndef_msg_desc_t ** pp_launchapp_msg_desc) +{ + + uint32_t err_code; + + nfc_ndef_record_desc_t * p_win_rec, * p_android_rec; + + /* Create NFC NDEF message description, capacity - 2 records */ + NFC_NDEF_MSG_DEF(nfc_launchapp_msg, 2); + + /* The message description is static, therefore you must */ + /* clear the message (needed for supporting multiple calls). */ + nfc_ndef_msg_clear(&NFC_NDEF_MSG(nfc_launchapp_msg)); + + if (p_win_app_id != NULL) + { + /* Create NFC NDEF Windows Phone LaunchApp Record description */ + p_win_rec = nfc_windows_launchapp_rec_declare(p_win_app_id, + win_app_id_length); + + /* Add Windows LaunchApp record as first record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_launchapp_msg), p_win_rec); + + if (err_code != NRF_SUCCESS) + return err_code; + } + + if (p_android_package_name != NULL) + { + /* Create NFC NDEF Android Application Record description */ + p_android_rec = nfc_android_application_rec_declare(p_android_package_name, + android_package_name_length); + + /* Add Android App Record as second record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_launchapp_msg), p_android_rec); + + if (err_code != NRF_SUCCESS) + return err_code; + } + + if (NFC_NDEF_MSG(nfc_launchapp_msg).record_count == 0) + { + return NRF_ERROR_INVALID_PARAM; + } + + *pp_launchapp_msg_desc = &NFC_NDEF_MSG(nfc_launchapp_msg); + + return NRF_SUCCESS; +} + + +ret_code_t nfc_launchapp_msg_encode(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + uint8_t * p_buf, + uint32_t * p_len) +{ + nfc_ndef_msg_desc_t * p_launchapp_msg_desc; + ret_code_t err_code; + + err_code = nfc_launchapp_msg_declare(p_android_package_name, + android_package_name_length, + p_win_app_id, + win_app_id_length, + &p_launchapp_msg_desc); + + if (err_code != NRF_SUCCESS) + return err_code; + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_launchapp_msg_desc, + p_buf, + p_len); + + return err_code; +} + + diff --git a/components/nfc/ndef/launchapp/nfc_launchapp_msg.h b/components/nfc/ndef/launchapp/nfc_launchapp_msg.h new file mode 100644 index 0000000..db9cebe --- /dev/null +++ b/components/nfc/ndef/launchapp/nfc_launchapp_msg.h @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_LAUNCHAPP_MSG_H__ +#define NFC_LAUNCHAPP_MSG_H__ + +/** @file + * + * @defgroup nfc_launch_app_msg Launch app messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages that can be used to launch apps. + * + */ + +#include +#include "nfc_ndef_msg.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/** @brief Function for encoding an NFC NDEF launch app message. + * + * This function encodes an NFC NDEF message into a buffer. + * + * @param[in] p_android_package_name Pointer to the Android package name string. + * If NULL, the Android Application Record will be skipped. + * @param[in] android_package_name_length Length of the Android package name. + * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID). + * If NULL, the Windows LaunchApp record will be skipped. + * @param[in] win_app_id_length Length of the Windows application ID. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If both p_android_package_name and windows_application_id were + * invalid (equal to NULL). + * @retval NRF_ERROR_NO_MEM If the predicted message size is bigger than the provided + * buffer space. + * @retval Other Other codes might be returned depending on + * the function @ref nfc_ndef_msg_encode + */ +ret_code_t nfc_launchapp_msg_encode(uint8_t const * p_android_package_name, + uint8_t android_package_name_length, + uint8_t const * p_win_app_id, + uint8_t win_app_id_length, + uint8_t * p_buf, + uint32_t * p_len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + #endif // NFC_LAUNCHAPP_MSG_H__ + + diff --git a/components/nfc/ndef/launchapp/nfc_launchapp_rec.c b/components/nfc/ndef/launchapp/nfc_launchapp_rec.c new file mode 100644 index 0000000..b49f14e --- /dev/null +++ b/components/nfc/ndef/launchapp/nfc_launchapp_rec.c @@ -0,0 +1,165 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "nrf_error.h" +#include "app_util.h" +#include "nfc_ndef_record.h" + +/** + * @brief Type of description of payload of Windows LaunchApp record. + */ +typedef struct +{ + const uint8_t * platform; + uint8_t platform_length; + const uint8_t * app_id; + uint8_t app_id_length; +} win_launchapp_payload_desc_t; + +/** @brief Description of payload of Windows LaunchApp record. */ +static win_launchapp_payload_desc_t m_win_launchapp_dsc; + +static const uint8_t launchapp_type_str[] = {'a', 'n', 'd', 'r', 'o', 'i', 'd', '.', 'c', 'o', 'm', + ':', 'p', 'k', 'g'}; + +static const uint8_t win_launchapp_type_str[] = {'w', 'i', 'n', 'd', 'o', 'w', 's', '.', 'c', 'o', + 'm', '/', 'L', 'a', 'u', 'n', 'c', 'h', 'A', 'p', + 'p'}; + +static const uint8_t win_phone_str[] = {'W', 'i', 'n', 'd', 'o', 'w', 's', 'P', 'h', 'o', 'n', 'e'}; + +nfc_ndef_record_desc_t * nfc_android_application_rec_declare(uint8_t const * p_package_name, + uint8_t package_name_length) +{ + NFC_NDEF_RECORD_BIN_DATA_DEF(android_app_rec, + TNF_EXTERNAL_TYPE, // tnf <- external + NULL, // no id + 0, // no id + launchapp_type_str, + sizeof(launchapp_type_str), + NULL, + 0); + + NFC_NDEF_BIN_PAYLOAD_DESC(android_app_rec).p_payload = p_package_name; + NFC_NDEF_BIN_PAYLOAD_DESC(android_app_rec).payload_length = package_name_length; + + return &NFC_NDEF_RECORD_BIN_DATA(android_app_rec); +} + +#define WIN_LAUNCHAPP_EMPTY_PARAMETER 0x20 ///< The empty parameter value for the Windows LaunchApp Record. + +/** + * @brief Function for constructing the payload for a Windows LaunchApp record. + * + * This function encodes the payload according to the LaunchApp record definition. It implements an API + * compatible with p_payload_constructor_t. + * + * @param[in] p_input Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the LaunchApp record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS Always success. + */ +static ret_code_t nfc_win_launchapp_payload_constructor(win_launchapp_payload_desc_t * p_input, + uint8_t * p_buff, + uint32_t * p_len) +{ + + win_launchapp_payload_desc_t * launch_desc = (win_launchapp_payload_desc_t *) p_input; + + uint32_t temp_len = (uint32_t)launch_desc->platform_length + launch_desc->app_id_length + 7; + + if (p_buff != NULL) + { + if (temp_len > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + *p_buff++ = 0x00; // platform count: 1 + *p_buff++ = 0x01; // -||- + + *p_buff++ = launch_desc->platform_length; + memcpy(p_buff, launch_desc->platform, launch_desc->platform_length); // platform + p_buff += launch_desc->platform_length; + + + *p_buff++ = launch_desc->app_id_length; + memcpy(p_buff, launch_desc->app_id, launch_desc->app_id_length); + p_buff += launch_desc->app_id_length; + + *p_buff++ = 0x00; // parameters length 1B + *p_buff++ = 0x01; // -||- + *p_buff++ = WIN_LAUNCHAPP_EMPTY_PARAMETER; // empty parameter + } + + *p_len = temp_len; + + return NRF_SUCCESS; +} + + +nfc_ndef_record_desc_t * nfc_windows_launchapp_rec_declare(const uint8_t * p_win_app_id, + uint8_t win_app_id_length) +{ + + NFC_NDEF_GENERIC_RECORD_DESC_DEF(win_launchapp, + TNF_ABSOLUTE_URI, + NULL, + 0, + win_launchapp_type_str, + sizeof(win_launchapp_type_str), + nfc_win_launchapp_payload_constructor, + &m_win_launchapp_dsc); + + m_win_launchapp_dsc.platform = win_phone_str; + m_win_launchapp_dsc.platform_length = sizeof(win_phone_str); + + m_win_launchapp_dsc.app_id = p_win_app_id; + m_win_launchapp_dsc.app_id_length = win_app_id_length; + + return &NFC_NDEF_GENERIC_RECORD_DESC(win_launchapp); +} + + diff --git a/components/nfc/ndef/launchapp/nfc_launchapp_rec.h b/components/nfc/ndef/launchapp/nfc_launchapp_rec.h new file mode 100644 index 0000000..a57de77 --- /dev/null +++ b/components/nfc/ndef/launchapp/nfc_launchapp_rec.h @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_LAUNCHAPP_REC_H__ +#define NFC_LAUNCHAPP_REC_H__ + +/**@file + * + * @defgroup nfc_launch_app_rec Launch app records + * @{ + * @ingroup nfc_launch_app_msg + * + * @brief Generation of NFC NDEF record descriptions that launch apps. + * + */ + +#include +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for generating a description of an NFC NDEF Android Application Record (AAR). + * + * This function declares and initializes a static instance of an NFC NDEF record description + * of an Android Application Record (AAR). + * + * @note The record payload data (@p p_package_name) should be declared as + * static. If it is declared as automatic, the NDEF message encoding + * (see @ref nfc_ndef_msg_encode) must be done in the same variable + * scope. + * + * @param[in] p_package_name Pointer to the Android package name string. + * @param[in] package_name_length Length of the Android package name. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_android_application_rec_declare(uint8_t const * p_package_name, + uint8_t package_name_length); + +/** @brief Function for generating a description of an NFC NDEF Windows LaunchApp record. + * + * This function declares and initializes a static instance of an NFC NDEF record description + * of a Windows LaunchApp record. + * + * @note The record payload data (@p p_win_app_id) should be declared as + * static. If it is declared as automatic, the NDEF message encoding + * (see @ref nfc_ndef_msg_encode) must be done in the same variable + * scope. + * + * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID). + * @param[in] win_app_id_length Length of the Windows application ID. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_windows_launchapp_rec_declare(const uint8_t * p_win_app_id, + uint8_t win_app_id_length); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_LAUNCHAPP_REC diff --git a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c b/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c new file mode 100644 index 0000000..c83ec83 --- /dev/null +++ b/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) + +#include "nfc_ndef_msg_parser.h" +#include "nrf_delay.h" + +#define NRF_LOG_MODULE_NAME "NFC_NDEF_MSG_PARSER" +#if NFC_NDEF_MSG_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_NDEF_MSG_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_NDEF_MSG_PARSER_INFO_COLOR +#else // NFC_NDEF_MSG_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_NDEF_MSG_PARSER_LOG_ENABLED +#include "nrf_log.h" + +ret_code_t ndef_msg_parser(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + uint8_t * const p_nfc_data, + uint32_t * const p_nfc_data_len) +{ + ret_code_t ret_code; + nfc_ndef_parser_memo_desc_t parser_memory_helper; + + ret_code = ndef_parser_memo_resolve(p_result_buf, + p_result_buf_len, + &parser_memory_helper); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + ret_code = internal_ndef_msg_parser(&parser_memory_helper, + p_nfc_data, + p_nfc_data_len); + + return ret_code; +} + + +void ndef_msg_printout(nfc_ndef_msg_desc_t * const p_msg_desc) +{ + uint32_t i; + + nrf_delay_ms(100); + NRF_LOG_INFO("NDEF message contains %d record(s)\r\n\r\n", p_msg_desc->record_count); + + for (i = 0; i < p_msg_desc->record_count; i++) + { + ndef_record_printout(i, p_msg_desc->pp_record[i]); + } +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) diff --git a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h b/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h new file mode 100644 index 0000000..2fdc155 --- /dev/null +++ b/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_NDEF_MSG_PARSER_H__ +#define NFC_NDEF_MSG_PARSER_H__ + +/**@file + * + * @defgroup nfc_ndef_parser NDEF message parser + * @{ + * @ingroup nfc_modules + * + * @brief Parser for NFC NDEF messages and records. + * + * @defgroup nfc_ndef_msg_parser Parser for NDEF messages + * @{ + * @ingroup nfc_ndef_parser + * + * @brief Parser for NFC NDEF messages. + * + */ + +#include +#include "nfc_ndef_msg_parser_local.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Macro for calculating the memory size required for holding the + * description of a message that consists of a certain number of NDEF records. + * + * @param[in] max_count_of_records Maximum number of records to hold. + */ +#define NFC_NDEF_PARSER_REQIRED_MEMO_SIZE_CALC(max_count_of_records) \ + ((uint32_t)(max_count_of_records) <= 1) ? \ + (sizeof(parsed_ndef_msg_1_t) * (uint32_t)(max_count_of_records)) : \ + (sizeof(parsed_ndef_msg_1_t) + ((NFC_PARSER_M_DELTA) *((uint32_t)(max_count_of_records) - 1))) + +/** + * @brief Function for parsing NFC NDEF messages. + * + * This function parses NDEF messages using NDEF binary record descriptors. + * + * @param[out] p_result_buf Pointer to the buffer that will be used to hold + * the NDEF message descriptor. After parsing is completed successfully, the first address + * in the buffer is filled by the NDEF message descriptor + * (@ref nfc_ndef_msg_desc_t), which provides a full description of + * the parsed NDEF message. + * @param[in,out] p_result_buf_len As input: size of the buffer specified by @p p_result_buf. + * As output: size of the reserved (used) part of the buffer specified by + * @p p_result_buf. + * @param[in] p_nfc_data Pointer to the data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. As output: size of the parsed message. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small to hold a one-record message or + * the buffer is too small to hold the actual result of the parsing. + * @retval NRF_ERROR_INVALID_LENGTH If the expected message length is bigger than the amount of the provided input data. + * @retval NRF_ERROR_INVALID_DATA If the message is not a valid NDEF message. + */ +ret_code_t ndef_msg_parser(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + uint8_t * const p_nfc_data, + uint32_t * const p_nfc_data_len); + +/** + * @brief Function for printing the parsed contents of an NDEF message. + * + * @param[in] p_msg_desc Pointer to the descriptor of the message that should be printed. + */ +void ndef_msg_printout(nfc_ndef_msg_desc_t * const p_msg_desc); + +/** + * @} + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_MSG_PARSER_H__ + + diff --git a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c b/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c new file mode 100644 index 0000000..06b1103 --- /dev/null +++ b/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) + +#include "nfc_ndef_msg_parser_local.h" + +ret_code_t internal_ndef_msg_parser(nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc, + uint8_t const * p_nfc_data, + uint32_t * const p_nfc_data_len) +{ + nfc_ndef_record_location_t record_location; + + ret_code_t ret_code; + + uint32_t nfc_data_left = *p_nfc_data_len; + uint32_t temp_nfc_data_len = 0; + + // want to modify -> use local copy + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc = p_parser_memo_desc->p_bin_pay_desc; + nfc_ndef_record_desc_t * p_rec_desc = p_parser_memo_desc->p_rec_desc; + + + while (nfc_data_left > 0) + { + temp_nfc_data_len = nfc_data_left; + + ret_code = ndef_record_parser(p_bin_pay_desc, + p_rec_desc, + &record_location, + p_nfc_data, + &temp_nfc_data_len); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + // verify the records location flags + if (p_parser_memo_desc->p_msg_desc->record_count == 0) + { + if ((record_location != NDEF_FIRST_RECORD) && (record_location != NDEF_LONE_RECORD)) + { + return NRF_ERROR_INVALID_DATA; + } + } + else + { + if ((record_location != NDEF_MIDDLE_RECORD) && (record_location != NDEF_LAST_RECORD)) + { + return NRF_ERROR_INVALID_DATA; + } + } + + ret_code = nfc_ndef_msg_record_add(p_parser_memo_desc->p_msg_desc, p_rec_desc); + + if (ret_code != NRF_SUCCESS) + { + return ret_code; + } + + nfc_data_left -= temp_nfc_data_len; + + if ((record_location == NDEF_LAST_RECORD) || (record_location == NDEF_LONE_RECORD)) + { + *p_nfc_data_len = *p_nfc_data_len - nfc_data_left; + return NRF_SUCCESS; + } + else + { + if (p_parser_memo_desc->p_msg_desc->record_count == + p_parser_memo_desc->p_msg_desc->max_record_count) + { + return NRF_ERROR_NO_MEM; + } + + p_nfc_data += temp_nfc_data_len; + p_bin_pay_desc++; + p_rec_desc++; + } + } + + return NRF_ERROR_INVALID_DATA; + +} + + +ret_code_t ndef_parser_memo_resolve(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc) +{ + + uint32_t max_rec_num; + uint32_t memory_last; + uint8_t * p_end; + nfc_ndef_record_desc_t * * pp_record_desc_array; + + if (*p_result_buf_len < sizeof(parsed_ndef_msg_1_t)) + { + return NRF_ERROR_NO_MEM; + } + + memory_last = (*p_result_buf_len) - sizeof(parsed_ndef_msg_1_t); + max_rec_num = (memory_last / (NFC_PARSER_M_DELTA)) + 1; + + p_parser_memo_desc->p_msg_desc = (nfc_ndef_msg_desc_t *) p_result_buf; + pp_record_desc_array = + (nfc_ndef_record_desc_t * *) &p_parser_memo_desc->p_msg_desc[1]; + p_parser_memo_desc->p_bin_pay_desc = + (nfc_ndef_bin_payload_desc_t *) &pp_record_desc_array[max_rec_num]; + p_parser_memo_desc->p_rec_desc = + (nfc_ndef_record_desc_t *) &p_parser_memo_desc->p_bin_pay_desc[max_rec_num]; + + // initialize message description + p_parser_memo_desc->p_msg_desc->pp_record = pp_record_desc_array; + p_parser_memo_desc->p_msg_desc->max_record_count = max_rec_num; + p_parser_memo_desc->p_msg_desc->record_count = 0; + + p_end = (uint8_t *) &p_parser_memo_desc->p_rec_desc[max_rec_num]; + + *p_result_buf_len = p_end - p_result_buf; + + return NRF_SUCCESS; +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER) diff --git a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h b/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h new file mode 100644 index 0000000..a46b0bc --- /dev/null +++ b/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h @@ -0,0 +1,168 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_NDEF_MSG_PARSER_LOCAL_H__ +#define NFC_NDEF_MSG_PARSER_LOCAL_H__ + +/**@file + * + * @defgroup nfc_ndef_msg_parser_local NDEF message parser (internal) + * @{ + * @ingroup nfc_ndef_msg_parser + * + * @brief Internal part of the parser for NFC NDEF messages. + * + */ + +#include +#include "nfc_ndef_msg.h" +#include "nfc_ndef_record_parser.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type for holding descriptors that are used by the NDEF parser. + */ +typedef struct +{ + nfc_ndef_msg_desc_t * p_msg_desc; ///< Pointer to the message descriptor. + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc; ///< Pointer to the array of binary payload descriptors. + nfc_ndef_record_desc_t * p_rec_desc; ///< Pointer to the array of record descriptors. +} nfc_ndef_parser_memo_desc_t; + +/** + * @brief Memory allocated for a one-record message. + */ +typedef struct +{ + nfc_ndef_msg_desc_t msg_desc; + nfc_ndef_record_desc_t * p_record_desc_array[1]; + nfc_ndef_bin_payload_desc_t bin_pay_desc[1]; + nfc_ndef_record_desc_t rec_desc[1]; +} parsed_ndef_msg_1_t; + +/** + * @brief Memory allocated for a two-record message. + */ +typedef struct +{ + nfc_ndef_msg_desc_t msg_desc; + nfc_ndef_record_desc_t * p_record_desc_array[2]; + nfc_ndef_bin_payload_desc_t bin_pay_desc[2]; + nfc_ndef_record_desc_t rec_desc[2]; +} parsed_ndef_msg_2_t; + +/** + * @brief Amount of memory that is required per record in addition to the memory allocated for the message descriptor. + */ +#define NFC_PARSER_M_DELTA (sizeof(parsed_ndef_msg_2_t) - sizeof(parsed_ndef_msg_1_t)) + + +/** + * @brief Function for resolving data instances in the provided buffer according + * to requirements of the function @ref internal_ndef_msg_parser. + * + * This internal function distributes the provided memory between certain data instances that are required + * by @ref internal_ndef_msg_parser. + * + * This function should not be used directly. + * + * @param[in] p_result_buf Pointer to the buffer that will be used to allocate + * data instances. + * @param[in,out] p_result_buf_len As input: size of the buffer specified by @p p_result_buf. + * As output: size of the reserved (used) part of the buffer specified by + * @p p_result_buf. + * @param[out] p_parser_memo_desc Pointer to the structure for holding descriptors of the allocated data + * instances. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_NO_MEM If the provided buffer is too small to hold a one-record message. + */ +ret_code_t ndef_parser_memo_resolve(uint8_t * const p_result_buf, + uint32_t * const p_result_buf_len, + nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc); + + +/** + * @brief Function for parsing NFC NDEF messages. + * + * This internal function parses NDEF messages into certain data instances. + * + * This function should not be used directly. + * + * @param[in,out] p_parser_memo_desc Pointer to the structure that holds descriptors of the allocated data + * instances for the parser. This structure contains the following fields: @n + * .p_msg_desc Pointer to the message descriptor that will + * be filled with parsed data. @n + * .p_bin_pay_desc Pointer to the array of binary payload + * descriptors that will be filled with parsed + * data. @n + * .p_rec_desc Pointer to the array of record descriptors + * that will be filled with parsed data. @n + * The arrays specified by @p .p_bin_pay_desc and @p .p_rec_desc must not + * contain more elements than the message descriptor + * specified by \p .p_msg_desc can hold. + * + * @param[in] p_nfc_data Pointer to the data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. + * As output: size of the parsed message. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the expected message length is bigger than the amount of provided input data. + * @retval NRF_ERROR_INVALID_DATA If the message is not a valid NDEF message. + * @retval NRF_ERROR_NO_MEM If the provided memory resources are too small to hold the parsing result. + */ +ret_code_t internal_ndef_msg_parser(nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc, + uint8_t const * p_nfc_data, + uint32_t * const p_nfc_data_len); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_MSG_PARSER_LOCAL_H__ diff --git a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c b/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c new file mode 100644 index 0000000..f21f0ff --- /dev/null +++ b/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c @@ -0,0 +1,219 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_NDEF_RECORD_PARSER) + +#include +#include +#include "nfc_ndef_record_parser.h" +#include "app_util.h" +#include "nordic_common.h" +#include "nrf_delay.h" + +#define NRF_LOG_MODULE_NAME "NFC_NDEF_PARSER" +#if NFC_NDEF_RECORD_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_NDEF_RECORD_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_NDEF_RECORD_PARSER_INFO_COLOR +#else // NFC_NDEF_RECORD_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_NDEF_RECORD_PARSER_LOG_ENABLED +#include "nrf_log.h" + +/* Sum of sizes of fields: TNF-flags, Type Length, Payload Length in short NDEF record. */ +#define NDEF_RECORD_BASE_LONG_SHORT (2 + NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE) + + +ret_code_t ndef_record_parser(nfc_ndef_bin_payload_desc_t * p_bin_pay_desc, + nfc_ndef_record_desc_t * p_rec_desc, + nfc_ndef_record_location_t * p_record_location, + uint8_t const * p_nfc_data, + uint32_t * p_nfc_data_len) +{ + uint32_t expected_rec_size = NDEF_RECORD_BASE_LONG_SHORT; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_rec_desc->tnf = (nfc_ndef_record_tnf_t) ((*p_nfc_data) & NDEF_RECORD_TNF_MASK); + + /* An NDEF parser that receives an NDEF record with an unknown or unsupported TNF field value + SHOULD treat it as Unknown. See NFCForum-TS-NDEF_1.0 */ + if (p_rec_desc->tnf == TNF_RESERVED) + { + p_rec_desc->tnf = TNF_UNKNOWN_TYPE; + } + + *p_record_location = (nfc_ndef_record_location_t) ((*p_nfc_data) & NDEF_RECORD_LOCATION_MASK); + + uint8_t flags = *(p_nfc_data++); + + p_rec_desc->type_length = *(p_nfc_data++); + + uint32_t payload_lenght; + + if (flags & NDEF_RECORD_SR_MASK) + { + payload_lenght = *(p_nfc_data++); + } + else + { + expected_rec_size += + NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE - NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + payload_lenght = uint32_big_decode(p_nfc_data); + p_nfc_data += NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE; + } + + if (flags & NDEF_RECORD_IL_MASK) + { + expected_rec_size += NDEF_RECORD_ID_LEN_SIZE; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_rec_desc->id_length = *(p_nfc_data++); + } + else + { + p_rec_desc->id_length = 0; + p_rec_desc->p_id = NULL; + } + + expected_rec_size += p_rec_desc->type_length + p_rec_desc->id_length + payload_lenght; + + if (expected_rec_size > *p_nfc_data_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (p_rec_desc->type_length > 0) + { + p_rec_desc->p_type = p_nfc_data; + + p_nfc_data += p_rec_desc->type_length; + } + else + { + p_rec_desc->p_type = NULL; + } + + if (p_rec_desc->id_length > 0) + { + p_rec_desc->p_id = p_nfc_data; + + p_nfc_data += p_rec_desc->id_length; + } + + if (payload_lenght == 0) + { + p_bin_pay_desc->p_payload = NULL; + } + else + { + p_bin_pay_desc->p_payload = p_nfc_data; + } + + p_bin_pay_desc->payload_length = payload_lenght; + + p_rec_desc->p_payload_descriptor = p_bin_pay_desc; + p_rec_desc->payload_constructor = (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy; + + *p_nfc_data_len = expected_rec_size; + + return NRF_SUCCESS; +} + +char const * const tnf_strings[] = +{ + "Empty\r\n", + "NFC Forum well-known type\r\n", + "Media-type (RFC 2046)\r\n", + "Absolute URI (RFC 3986)\r\n", + "NFC Forum external type (NFC RTD)\r\n", + "Unknown\r\n", + "Unchanged\r\n", + "Reserved\r\n" +}; + +void ndef_record_printout(uint32_t num, nfc_ndef_record_desc_t * const p_rec_desc) +{ + NRF_LOG_INFO("NDEF record %d content:\r\n", num); + NRF_LOG_INFO("TNF: %s",(uint32_t)tnf_strings[p_rec_desc->tnf]); + + if (p_rec_desc->p_id != NULL) + { + NRF_LOG_INFO("ID:\r\n"); + NRF_LOG_HEXDUMP_INFO((uint8_t *)p_rec_desc->p_id, p_rec_desc->id_length); + } + + if (p_rec_desc->p_type != NULL) + { + NRF_LOG_INFO("type:\r\n"); + NRF_LOG_HEXDUMP_INFO((uint8_t *)p_rec_desc->p_type, p_rec_desc->type_length); + } + + if (p_rec_desc->payload_constructor == (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy) + { + nfc_ndef_bin_payload_desc_t * p_bin_pay_desc = p_rec_desc->p_payload_descriptor; + + if (p_bin_pay_desc->p_payload != NULL) + { + NRF_LOG_INFO("Payload data (%d bytes):\r\n", p_bin_pay_desc->payload_length); + NRF_LOG_HEXDUMP_INFO((uint8_t *)p_bin_pay_desc->p_payload, p_bin_pay_desc->payload_length); + } + else + { + NRF_LOG_INFO("No payload\r\n"); + } + } + NRF_LOG_INFO("\r\n\r\n"); +} + +#endif // NRF_MODULE_ENABLED(NFC_NDEF_RECORD_PARSER) diff --git a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h b/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h new file mode 100644 index 0000000..39f2c46 --- /dev/null +++ b/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_NDEF_RECORD_PARSER_H__ +#define NFC_NDEF_RECORD_PARSER_H__ + +#include +#include "sdk_errors.h" +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @defgroup nfc_ndef_record_parser Parser for NDEF records + * @{ + * @ingroup nfc_ndef_parser + * + * @brief Parser for NFC NDEF records. + * + */ + + +/** + * @brief Function for parsing NDEF records. + * + * This parsing implementation uses the binary payload descriptor (@ref nfc_ndef_bin_payload_desc_t) to describe the payload for the record. + * + * @param[out] p_bin_pay_desc Pointer to the binary payload descriptor that will be filled and referenced by the record descriptor. + * @param[out] p_rec_desc Pointer to the record descriptor that will be filled with parsed data. + * @param[out] p_record_location Pointer to the record location. + * @param[in] p_nfc_data Pointer to the raw data to be parsed. + * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. As output: size of the parsed record. + * + * @retval NRF_SUCCESS If the function completed successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the expected record length is bigger than the provided input data amount. + */ +ret_code_t ndef_record_parser(nfc_ndef_bin_payload_desc_t * p_bin_pay_desc, + nfc_ndef_record_desc_t * p_rec_desc, + nfc_ndef_record_location_t * p_record_location, + uint8_t const * p_nfc_data, + uint32_t * p_nfc_data_len); + +/** + * @brief Function for printing the parsed contents of the NDEF record. + * + * @param[in] num Sequence number of the record within the NDEF message. + * @param[in] p_rec_desc Pointer to the descriptor of the record that should be printed. + * + */ +void ndef_record_printout(uint32_t num, nfc_ndef_record_desc_t * const p_rec_desc); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif // NFC_NDEF_RECORD_PARSER_H__ diff --git a/components/nfc/ndef/text/nfc_text_rec.c b/components/nfc/ndef/text/nfc_text_rec.c new file mode 100644 index 0000000..0f7d479 --- /dev/null +++ b/components/nfc/ndef/text/nfc_text_rec.c @@ -0,0 +1,105 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "nfc_text_rec.h" +#include "nrf_error.h" + +#define TEXT_REC_STATUS_SIZE 1 ///< Size of the status. +#define TEXT_REC_STATUS_UTF_POS 7 ///< Position of a character encoding type. +#define TEXT_REC_RESERVED_POS 6 ///< Reserved position. + +const uint8_t nfc_text_rec_type_field[] = {'T'}; + + +/** + * @brief Function for calculating payload size. + */ +__STATIC_INLINE uint32_t nfc_text_rec_payload_size_get(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc) +{ + return (TEXT_REC_STATUS_SIZE + + p_nfc_rec_text_payload_desc->lang_code_len + + p_nfc_rec_text_payload_desc->data_len); +} + +ret_code_t nfc_text_rec_payload_constructor(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc, + uint8_t * p_buff, + uint32_t * p_len) +{ + if ((p_nfc_rec_text_payload_desc->lang_code_len == 0) + || (p_nfc_rec_text_payload_desc->lang_code_len & (1 << TEXT_REC_RESERVED_POS)) + || (p_nfc_rec_text_payload_desc->lang_code_len & (1 << TEXT_REC_STATUS_UTF_POS)) + || (p_nfc_rec_text_payload_desc->p_lang_code == NULL) + || (p_nfc_rec_text_payload_desc->data_len == 0) + || (p_nfc_rec_text_payload_desc->p_data == NULL) + || (p_len == NULL)) + { + return NRF_ERROR_INVALID_PARAM; + } + + uint32_t payload_size = nfc_text_rec_payload_size_get(p_nfc_rec_text_payload_desc); + + if (p_buff != NULL) + { + if (payload_size > *p_len) + { + return NRF_ERROR_NO_MEM; + } + + *p_buff = (p_nfc_rec_text_payload_desc->lang_code_len + + (p_nfc_rec_text_payload_desc->utf << TEXT_REC_STATUS_UTF_POS)); + p_buff += TEXT_REC_STATUS_SIZE; + + memcpy(p_buff, + p_nfc_rec_text_payload_desc->p_lang_code, + p_nfc_rec_text_payload_desc->lang_code_len); + p_buff += p_nfc_rec_text_payload_desc->lang_code_len; + + memcpy(p_buff, + p_nfc_rec_text_payload_desc->p_data, + p_nfc_rec_text_payload_desc->data_len); + } + + *p_len = payload_size; + + return NRF_SUCCESS; +} + + diff --git a/components/nfc/ndef/text/nfc_text_rec.h b/components/nfc/ndef/text/nfc_text_rec.h new file mode 100644 index 0000000..80268ee --- /dev/null +++ b/components/nfc/ndef/text/nfc_text_rec.h @@ -0,0 +1,163 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_TEXT_REC_H__ +#define NFC_TEXT_REC_H__ + +/**@file + * + * @defgroup nfc_text_rec Text records + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF Text record descriptions. + * + */ + +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Type of the Unicode Transformation Format. + * + * Values to specify the type of UTF for an NFC NDEF Text record. + */ +typedef enum +{ + UTF_8 = 0, ///< Unicode Transformation Format 8. + UTF_16 = 1, ///< Unicode Transformation Format 16. +} nfc_text_rec_utf_type_t; + +/** + * @brief Text record payload descriptor. + */ +typedef struct +{ + nfc_text_rec_utf_type_t utf; ///< Type of the Unicode Transformation Format. + + uint8_t const * p_lang_code; ///< Pointer to the IANA language code. + uint8_t lang_code_len; ///< Length of the IANA language code. + + uint8_t const * p_data; ///< Pointer to the user text. + uint32_t data_len; ///< Length of the user text. +} nfc_text_rec_payload_desc_t; + +/** + * @brief Constructor for an NFC NDEF Text record payload. + * + * @param[in] p_nfc_rec_text_payload_desc Pointer to the Text record description. + * @param[out] p_buff Pointer to the payload destination. If NULL, function will + * calculate the expected size of the Text record payload. + * + * @param[in,out] p_len Size of the available memory to write as input. + * Size of the generated record payload as output. + */ +ret_code_t nfc_text_rec_payload_constructor(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc, + uint8_t * p_buff, + uint32_t * p_len); + +/** + * @brief External reference to the type field of the Text record, defined in the + * file @c nfc_text_rec.c. It is used in the @ref NFC_NDEF_TEXT_RECORD_DESC_DEF macro. + */ +extern const uint8_t nfc_text_rec_type_field[]; + +/** + * @brief Size of the type field of the Text record, defined in the + * file @c nfc_text_rec.c. It is used in the @ref NFC_NDEF_TEXT_RECORD_DESC_DEF macro. + */ +#define NFC_TEXT_REC_TYPE_LENGTH 1 + +/** + *@brief Macro for creating and initializing an NFC NDEF record descriptor for a Text record. + * + * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and + * a static instance of type @ref nfc_text_rec_payload_desc_t, which together constitute + * an instance of a Text record. + * + * Use the macro @ref NFC_NDEF_TEXT_RECORD_DESC to access the NDEF Text record descriptor instance. + * + * @param[in] NAME Name of the created record descriptor instance. + * @param[in] UTF Unicode Transformation Format. + * @param[in] P_LANG_CODE Pointer to the IANA language code. + * @param[in] LANG_CODE_LEN Length of the IANA language code. + * @param[in] P_DATA Pointer to the user text. + * @param[in] DATA_LEN Length of the user text. + */ +#define NFC_NDEF_TEXT_RECORD_DESC_DEF(NAME, \ + UTF, \ + P_LANG_CODE, \ + LANG_CODE_LEN, \ + P_DATA, \ + DATA_LEN) \ + static nfc_text_rec_payload_desc_t NAME##_nfc_text_rec_payload_desc; \ + NAME##_nfc_text_rec_payload_desc = (nfc_text_rec_payload_desc_t) \ + { \ + .utf = UTF, \ + .p_lang_code = P_LANG_CODE, \ + .lang_code_len = LANG_CODE_LEN, \ + .p_data = P_DATA, \ + .data_len = DATA_LEN, \ + }; \ + NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \ + TNF_WELL_KNOWN, \ + 0, \ + 0, \ + nfc_text_rec_type_field, \ + NFC_TEXT_REC_TYPE_LENGTH, \ + nfc_text_rec_payload_constructor, \ + &(NAME##_nfc_text_rec_payload_desc)) + +/** + * @brief Macro for accessing the NFC NDEF Text record descriptor + * instance that was created with @ref NFC_NDEF_TEXT_RECORD_DESC_DEF. + */ +#define NFC_NDEF_TEXT_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_TEXT_REC_H__ diff --git a/components/nfc/ndef/uri/nfc_uri_msg.c b/components/nfc/ndef/uri/nfc_uri_msg.c new file mode 100644 index 0000000..22c21e4 --- /dev/null +++ b/components/nfc/ndef/uri/nfc_uri_msg.c @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "nfc_uri_msg.h" + +/** @brief Function for generating a description of an NFC NDEF URI message. + * + * This function declares and initializes a static instance of an NFC NDEF message description + * and NFC NDEF records descriptions. + * + * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI. + * @param[in] p_uri_data Pointer to the URI string. + * This string should not contain the protocol field if the protocol + * was specified in @p uri_id_code + * @param[in] uri_data_len Length of the URI string. + * @param[out] pp_uri_msg_desc Pointer to pointer to the NDEF message description. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If the URI string was invalid (equal to NULL). + */ +static ret_code_t nfc_uri_msg_declare( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + nfc_ndef_msg_desc_t ** pp_uri_msg_desc) +{ + ret_code_t err_code; + nfc_ndef_record_desc_t * p_uri_rec; + + /* Create NFC NDEF message description, capacity - 1 record */ + NFC_NDEF_MSG_DEF(nfc_uri_msg, 1); + + /* The message description is static, therefore */ + /* you must clear the message (needed for supporting multiple calls) */ + nfc_ndef_msg_clear(&NFC_NDEF_MSG(nfc_uri_msg)); + + if (p_uri_data != NULL) + { + /* Create NFC NDEF URI Record description */ + p_uri_rec = nfc_uri_rec_declare(uri_id_code, + p_uri_data, + uri_data_len); + + /* Add URI record as lone record to message */ + err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_uri_msg), p_uri_rec); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + *pp_uri_msg_desc = &NFC_NDEF_MSG(nfc_uri_msg); + + return NRF_SUCCESS; +} + +ret_code_t nfc_uri_msg_encode( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + uint8_t * p_buf, + uint32_t * p_len) +{ + ret_code_t err_code; + nfc_ndef_msg_desc_t * p_uri_msg_desc; + + /* Create NFC NDEF message description with URI record */ + err_code = nfc_uri_msg_declare( uri_id_code, + p_uri_data, + uri_data_len, + &p_uri_msg_desc); + + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + /* Encode whole message into buffer */ + err_code = nfc_ndef_msg_encode(p_uri_msg_desc, + p_buf, + p_len); + + return err_code; +} diff --git a/components/nfc/ndef/uri/nfc_uri_msg.h b/components/nfc/ndef/uri/nfc_uri_msg.h new file mode 100644 index 0000000..5226be2 --- /dev/null +++ b/components/nfc/ndef/uri/nfc_uri_msg.h @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_URI_MSG_H__ +#define NFC_URI_MSG_H__ + +/**@file + * + * @defgroup nfc_uri_msg URI messages + * @{ + * @ingroup nfc_ndef_messages + * + * @brief Generation of NFC NDEF messages with a URI record. + * + */ + +#include "nfc_ndef_msg.h" +#include "nfc_uri_rec.h" +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Function for encoding an NFC NDEF URI message. + * + * This function encodes an NFC NDEF message into a buffer. + * + * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI. + * @param[in] p_uri_data Pointer to the URI string. + * The string should not contain the protocol field if the protocol + * was specified in @p uri_id_code. + * @param[in] uri_data_len Length of the URI string. + * @param[out] p_buf Pointer to the buffer for the message. + * @param[in,out] p_len Size of the available memory for the message as input. + * Size of the generated message as output. + * + * @retval NRF_SUCCESS If the description was successfully created. + * @retval NRF_ERROR_INVALID_PARAM If the URI string was invalid (equal to NULL). + * @retval NRF_ERROR_NO_MEM If the predicted message size is bigger than the provided + * buffer space. + * @retval Other Other codes might be returned depending on + * the function @ref nfc_ndef_msg_encode. + */ +ret_code_t nfc_uri_msg_encode( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len, + uint8_t * p_buf, + uint32_t * p_len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_URI_MSG_H__ diff --git a/components/nfc/ndef/uri/nfc_uri_rec.c b/components/nfc/ndef/uri/nfc_uri_rec.c new file mode 100644 index 0000000..92d3534 --- /dev/null +++ b/components/nfc/ndef/uri/nfc_uri_rec.c @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "nfc_uri_rec.h" +#include "nrf_error.h" + +/** + * @brief Type of description of the payload of a URI record. + */ +typedef struct +{ + nfc_uri_id_t uri_id_code; ///< URI identifier code. + uint8_t const * p_uri_data; ///< Pointer to a URI string. + uint8_t uri_data_len; ///< Length of the URI string. +} uri_payload_desc_t; + +/** + * @brief Function for constructing the payload for a URI record. + * + * This function encodes the payload according to the URI record definition. It implements an API + * compatible with @ref p_payload_constructor_t. + * + * @param[in] p_input Pointer to the description of the payload. + * @param[out] p_buff Pointer to payload destination. If NULL, function will + * calculate the expected size of the URI record payload. + * + * @param[in,out] p_len Size of available memory to write as input. Size of generated + * payload as output. + * + * @retval NRF_SUCCESS If the payload was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted payload size is bigger than the provided buffer space. + */ +static ret_code_t nfc_uri_payload_constructor( uri_payload_desc_t * p_input, + uint8_t * p_buff, + uint32_t * p_len) +{ + if (p_buff != NULL) + { + /* Verify if there is enough available memory */ + if (p_input->uri_data_len >= *p_len) + { + return NRF_ERROR_NO_MEM; + } + + /* Copy descriptor content into the buffer */ + *(p_buff++) = p_input->uri_id_code; + memcpy(p_buff, p_input->p_uri_data, p_input->uri_data_len ); + } + + *p_len = p_input->uri_data_len + 1; + + return NRF_SUCCESS; +} + +nfc_ndef_record_desc_t * nfc_uri_rec_declare( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len) +{ + static uri_payload_desc_t uri_payload_desc; + static const uint8_t static_uri_type = 'U'; + + NFC_NDEF_GENERIC_RECORD_DESC_DEF( uri_rec, + TNF_WELL_KNOWN, // tnf <- well-known + NULL, + 0, // no id + &static_uri_type, + 1, // type size 1B + nfc_uri_payload_constructor, + &uri_payload_desc); + + uri_payload_desc.uri_id_code = uri_id_code; + uri_payload_desc.p_uri_data = p_uri_data; + uri_payload_desc.uri_data_len = uri_data_len; + + return &NFC_NDEF_GENERIC_RECORD_DESC( uri_rec); +} + diff --git a/components/nfc/ndef/uri/nfc_uri_rec.h b/components/nfc/ndef/uri/nfc_uri_rec.h new file mode 100644 index 0000000..aab3d96 --- /dev/null +++ b/components/nfc/ndef/uri/nfc_uri_rec.h @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_URI_REC_H__ +#define NFC_URI_REC_H__ + +/**@file + * + * @defgroup nfc_uri_rec URI records + * @{ + * @ingroup nfc_uri_msg + * + * @brief Generation of NFC NDEF URI record descriptions. + * + */ + +#include "nfc_ndef_record.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @enum nfc_uri_id_t + * @brief URI identifier codes according to "URI Record Type Definition" + * (denotation "NFCForum-TS-RTD_URI_1.0" published on 2006-07-24) chapter 3.2.2. + */ +typedef enum +{ + NFC_URI_NONE = 0x00, /**< No prepending is done. */ + NFC_URI_HTTP_WWW = 0x01, /**< "http://www." */ + NFC_URI_HTTPS_WWW = 0x02, /**< "https://www." */ + NFC_URI_HTTP = 0x03, /**< "http:" */ + NFC_URI_HTTPS = 0x04, /**< "https:" */ + NFC_URI_TEL = 0x05, /**< "tel:" */ + NFC_URI_MAILTO = 0x06, /**< "mailto:" */ + NFC_URI_FTP_ANONYMOUS = 0x07, /**< "ftp://anonymous:anonymous@" */ + NFC_URI_FTP_FTP = 0x08, /**< "ftp://ftp." */ + NFC_URI_FTPS = 0x09, /**< "ftps://" */ + NFC_URI_SFTP = 0x0A, /**< "sftp://" */ + NFC_URI_SMB = 0x0B, /**< "smb://" */ + NFC_URI_NFS = 0x0C, /**< "nfs://" */ + NFC_URI_FTP = 0x0D, /**< "ftp://" */ + NFC_URI_DAV = 0x0E, /**< "dav://" */ + NFC_URI_NEWS = 0x0F, /**< "news:" */ + NFC_URI_TELNET = 0x10, /**< "telnet://" */ + NFC_URI_IMAP = 0x11, /**< "imap:" */ + NFC_URI_RTSP = 0x12, /**< "rtsp://" */ + NFC_URI_URN = 0x13, /**< "urn:" */ + NFC_URI_POP = 0x14, /**< "pop:" */ + NFC_URI_SIP = 0x15, /**< "sip:" */ + NFC_URI_SIPS = 0x16, /**< "sips:" */ + NFC_URI_TFTP = 0x17, /**< "tftp:" */ + NFC_URI_BTSPP = 0x18, /**< "btspp://" */ + NFC_URI_BTL2CAP = 0x19, /**< "btl2cap://" */ + NFC_URI_BTGOEP = 0x1A, /**< "btgoep://" */ + NFC_URI_TCPOBEX = 0x1B, /**< "tcpobex://" */ + NFC_URI_IRDAOBEX = 0x1C, /**< "irdaobex://" */ + NFC_URI_FILE = 0x1D, /**< "file://" */ + NFC_URI_URN_EPC_ID = 0x1E, /**< "urn:epc:id:" */ + NFC_URI_URN_EPC_TAG = 0x1F, /**< "urn:epc:tag:" */ + NFC_URI_URN_EPC_PAT = 0x20, /**< "urn:epc:pat:" */ + NFC_URI_URN_EPC_RAW = 0x21, /**< "urn:epc:raw:" */ + NFC_URI_URN_EPC = 0x22, /**< "urn:epc:" */ + NFC_URI_URN_NFC = 0x23, /**< "urn:nfc:" */ + NFC_URI_RFU = 0xFF /**< No prepending is done. Reserved for future use. */ +} nfc_uri_id_t; + +/** @brief Function for generating a description of a URI record. + * + * This function declares and initializes a static instance of an NFC NDEF record description + * of a URI record. + * + * @note The record payload data (@p uri_id_code, @p p_uri_data, and @p + * uri_data_len) should be declared as static. If it is declared as + * automatic, the NDEF message encoding (see @ref nfc_uri_msg_encode) + * must be done in the same variable scope. + * + * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI. + * @param[in] p_uri_data Pointer to the URI string. + * The string should not contain the protocol field if the protocol + * was specified in @p uri_id_code. + * @param[in] uri_data_len Length of the URI string. + * + * @return Pointer to the description of the record. + */ +nfc_ndef_record_desc_t * nfc_uri_rec_declare( nfc_uri_id_t uri_id_code, + uint8_t const * const p_uri_data, + uint8_t uri_data_len); +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NFC_URI_REC_H__ diff --git a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c b/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c new file mode 100644 index 0000000..d481d43 --- /dev/null +++ b/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c @@ -0,0 +1,733 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if NFC_HAL_ENABLED + +#include "hal_nfc_t2t.h" +#include +#include +#include "nfc_t2t_lib.h" +#include "nfc_fixes.h" +#include "nrf.h" +#include "app_util_platform.h" +#include "nordic_common.h" +#include "nrf_drv_clock.h" + +#define NRF_LOG_MODULE_NAME "HAL_NFC" +#if HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL HAL_NFC_CONFIG_LOG_LEVEL +#define NRF_LOG_INFO_COLOR HAL_NFC_CONFIG_INFO_COLOR +#define NRF_LOG_DEBUG_COLOR HAL_NFC_CONFIG_DEBUG_COLOR +#else // HAL_NFC_CONFIG_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // HAL_NFC_CONFIG_LOG_ENABLED +#include "nrf_log.h" + + +#if HAL_NFC_CONFIG_DEBUG_PIN_ENABLED + #include "nrf_gpio.h" + + #define HAL_NFC_DEBUG_PIN_CONFIG(pin_num) nrf_gpio_cfg_output(pin_num) + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) nrf_gpio_pin_clear(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) nrf_gpio_pin_set(pin_num) + + #define HAL_NFC_DEBUG_PINS_INITIALIZE() \ + do{ \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \ + } while(0) +#else + #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) + #define HAL_NFC_DEBUG_PIN_SET(pin_num) + #define HAL_NFC_DEBUG_PINS_INITIALIZE() +#endif // HAL_NFC_CONFIG_DEBUG_PIN_ENABLED + + +/* NFC library version history: + * #define NFC_LIB_VERSION 0x00 first experimental version intended for nRF52 IC rev. Engineering A (PCA10036, part of nRF52 Preview Development Kit) + * #define NFC_LIB_VERSION 0x01 experimental version intended for nRF52 IC rev. Engineering B (PCA10040, part of nRF52 Development Kit) + * #define NFC_LIB_VERSION 0x02 experimental version intended for fix IC-12826 and fix: not released HFCLK in SENSE mode + * #define NFC_LIB_VERSION 0x03 experimental version intended for support logging module + * #define NFC_LIB_VERSION 0x04 experimental version intended for nRF52840 IC rev. Engineering A (PCA10056, part of nRF52840 Preview Development Kit). Removed PCA10036 support. + */ + +#define NFC_LIB_VERSION 0x03u /**< Internal: current NFC lib. version */ + +#define T2T_INTERNAL_BYTES_NR 10u /**< Number of internal bytes defined by Type 2 Tag Operation Technical Specification */ +#define T2T_INTERNAL_BYTE_SN0_SHIFT 0u /**< Internal Byte SN0, NRF_FICR->NFC.TAGHEADER0.MFGID which is Manufacturer ID */ +#define T2T_INTERNAL_BYTE_SN1_SHIFT 8u /**< Internal Byte SN1, NRF_FICR->NFC.TAGHEADER0.UID0 */ +#define T2T_INTERNAL_BYTE_SN2_SHIFT 16u /**< Internal Byte SN2, NRF_FICR->NFC.TAGHEADER0.UID1 */ +#define T2T_INTERNAL_BYTE_SN3_SHIFT 0u /**< Internal Byte SN3, NRF_FICR->NFC.TAGHEADER1.UID3 */ +#define T2T_INTERNAL_BYTE_SN4_SHIFT 8u /**< Internal Byte SN4, NRF_FICR->NFC.TAGHEADER1.UID4 */ +#define T2T_INTERNAL_BYTE_SN5_SHIFT 16u /**< Internal Byte SN5, NRF_FICR->NFC.TAGHEADER1.UID5 */ +#define T2T_INTERNAL_BYTE_SN6_SHIFT 24u /**< Internal Byte SN6, NRF_FICR->NFC.TAGHEADER1.UID6 */ +#define CASCADE_TAG_BYTE 0x88u /**< Constant defined by ISO/EIC 14443-3 */ + +#define NFCID1_2ND_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_2ND_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_2ND_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ +#define NFCID1_LAST_BYTE3_SHIFT 24u /**< Shift value for NFC ID byte 3 */ +#define NFCID1_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */ +#define NFCID1_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */ +#define NFCID1_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */ + +#define NFC_RX_BUFFER_SIZE 16u /**< NFC Rx data buffer size */ +#define T2T_READ_CMD 0x30u /**< Type 2 Tag Read command identifier */ +#define NFC_SLP_REQ_CMD 0x50u /**< NFC SLP_REQ command identifier */ +#define NFC_CRC_SIZE 2u /**< CRC size in bytes */ + +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#else + #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk | \ + NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk | \ + NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */ +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + +#define NRF_NFCT_FRAMESTATUS_RX_MSK (NFCT_FRAMESTATUS_RX_OVERRUN_Msk | \ + NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk | \ + NFCT_FRAMESTATUS_RX_CRCERROR_Msk) /**< Mask for clearing all flags in NFCT_FRAMESTATUS_RX register */ +#define NFC_FIELD_ON_MASK NFCT_FIELDPRESENT_LOCKDETECT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD ON. */ +#define NFC_FIELD_OFF_MASK NFCT_FIELDPRESENT_FIELDPRESENT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD OFF. */ + +typedef enum +{ + NFC_FIELD_STATE_NONE, /**< Initial value indicating no NFCT Field events. */ + NFC_FIELD_STATE_OFF, /**< NFCT FIELDLOST Event has been set. */ + NFC_FIELD_STATE_ON, /**< NFCT FIELDDETECTED Event has been set. */ + NFC_FIELD_STATE_UNKNOWN /**< Both NFCT Field Events have been set - ambiguous state. */ +}nfct_field_sense_state_t; + +/* Static function declarations */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event); +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event); +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state); + +/* Static data */ +static hal_nfc_callback_t m_nfc_lib_callback = (hal_nfc_callback_t) NULL; /**< Callback to nfc_lib layer */ +static void * m_nfc_lib_context; /**< Callback execution context */ +static volatile uint8_t m_nfc_rx_buffer[NFC_RX_BUFFER_SIZE] = {0}; /**< Buffer for NFC Rx data */ +static volatile bool m_slp_req_received = false; /**< Flag indicating that SLP_REQ Command was received */ +static volatile bool m_field_on = false; /**< Flag indicating that NFC Tag field is present */ +static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure */ + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + static volatile uint32_t m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; /**< Mask used for NFC Field polling in NFCT_FIELDPRESENT register */ +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#define NRF_NFCT_POWER (*(uint32_t volatile *)(0x40005FFC)) + +#define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | \ + NFCT_FIELDPRESENT_FIELDPRESENT_Msk) + +#define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << \ + NFCT_FIELDPRESENT_FIELDPRESENT_Pos) | \ + (NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << \ + NFCT_FIELDPRESENT_LOCKDETECT_Pos)) + +#ifndef HAL_NFC_FIELD_TIMER_PERIOD + #define HAL_NFC_FIELD_TIMER_PERIOD 100 /* unit - us */ +#endif + +static inline void hal_nfc_re_setup(void); +static void hal_nfc_field_check(void); + +static void field_timer_with_callback_config() +{ + NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos; + NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_08Bit << TIMER_BITMODE_BITMODE_Pos; + NRF_TIMER4->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos; + NRF_TIMER4->CC[0] = HAL_NFC_FIELD_TIMER_PERIOD << TIMER_CC_CC_Pos; + NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos; + NRF_TIMER4->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos; + + NVIC_ClearPendingIRQ(TIMER4_IRQn); + NVIC_SetPriority(TIMER4_IRQn, APP_IRQ_PRIORITY_LOW); + NVIC_EnableIRQ(TIMER4_IRQn); +} + +void TIMER4_IRQHandler(void) +{ + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); + hal_nfc_field_check(); + NRF_TIMER4->EVENTS_COMPARE[0] = 0; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +/** + * @brief Common part of setup used for NFCT initialization and reinitialization. + */ +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static void hal_nfc_common_hw_setup(uint8_t * const nfc_internal) +#else +static inline void hal_nfc_common_hw_setup(uint8_t * const nfc_internal) +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +{ + uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0; + uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1; + +/* Begin: Bugfix for FTPAN-98 */ +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + *(volatile uint32_t *)0x4000568C = 0x00038148; +#endif +/* End: Bugfix for FTPAN-98 */ + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos); +#else + NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos) | + (NFCT_INTENSET_FIELDLOST_Enabled << NFCT_INTENSET_FIELDLOST_Pos); +#endif + + NRF_NFCT->INTENSET = (NFCT_INTENSET_ERROR_Enabled << NFCT_INTENSET_ERROR_Pos) | + (NFCT_INTENSET_SELECTED_Enabled << NFCT_INTENSET_SELECTED_Pos); + + /* According to ISO/IEC 14443-3 */ + nfc_internal[0] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN0_SHIFT)); //SN0 + nfc_internal[1] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN1_SHIFT)); //SN1 + nfc_internal[2] = (uint8_t) (LSB_32(nfc_tag_header0 >> T2T_INTERNAL_BYTE_SN2_SHIFT)); //SN2 + nfc_internal[3] = (uint8_t) ((CASCADE_TAG_BYTE) ^ nfc_internal[0] ^ + nfc_internal[1] ^ nfc_internal[2]); //BCC0 = CASCADE_TAG_BYTE ^ SN0 ^ SN1 ^ SN2 + nfc_internal[4] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN3_SHIFT)); //SN3 + nfc_internal[5] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN4_SHIFT)); //SN4 + nfc_internal[6] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN5_SHIFT)); //SN5 + nfc_internal[7] = (uint8_t) (LSB_32(nfc_tag_header1 >> T2T_INTERNAL_BYTE_SN6_SHIFT)); //SN6 + nfc_internal[8] = (uint8_t) (nfc_internal[4] ^ nfc_internal[5] ^ + nfc_internal[6] ^ nfc_internal[7]); //BCC1 = SN3 ^ SN4 ^ SN5 ^ SN6 + nfc_internal[9] = (uint8_t) (NFC_LIB_VERSION); //For internal use + + + /* MSB of NFCID1_2ND_LAST register is not used - always 0 */ + NRF_NFCT->NFCID1_2ND_LAST = ((uint32_t) nfc_internal[0] << NFCID1_2ND_LAST_BYTE2_SHIFT) | + ((uint32_t) nfc_internal[1] << NFCID1_2ND_LAST_BYTE1_SHIFT) | + ((uint32_t) nfc_internal[2] << NFCID1_2ND_LAST_BYTE0_SHIFT); + + NRF_NFCT->NFCID1_LAST = ((uint32_t) nfc_internal[4] << NFCID1_LAST_BYTE3_SHIFT) | + ((uint32_t) nfc_internal[5] << NFCID1_LAST_BYTE2_SHIFT) | + ((uint32_t) nfc_internal[6] << NFCID1_LAST_BYTE1_SHIFT) | + ((uint32_t) nfc_internal[7] << NFCID1_LAST_BYTE0_SHIFT); + + /* Begin: Bugfix for FTPAN-25 (IC-9929) */ + /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used + because it's required to operate with Windows Phone */ + NRF_NFCT->SENSRES = + (NFCT_SENSRES_NFCIDSIZE_NFCID1Double << NFCT_SENSRES_NFCIDSIZE_Pos) | + (NFCT_SENSRES_BITFRAMESDD_SDD00100 << NFCT_SENSRES_BITFRAMESDD_Pos); + /* End: Bugfix for FTPAN-25 (IC-9929)*/ +} + + +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context) +{ + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + m_nfc_lib_callback = callback; + m_nfc_lib_context = p_context; + + hal_nfc_common_hw_setup(nfc_internal); + + (void) nfc_t2t_internal_set((uint8_t *) nfc_internal, sizeof(nfc_internal)); + + /* Initialize SDK Clock module for handling high precission clock requests */ + m_clock_handler_item.event_handler = nrf_nfct_clock_event_handler; + m_clock_handler_item.p_next = NULL; + + ret_code_t err_code = nrf_drv_clock_init(); + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + field_timer_with_callback_config(); +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + NRF_LOG_INFO("Init\r\n"); + HAL_NFC_DEBUG_PINS_INITIALIZE(); + + if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_MODULE_ALREADY_INITIALIZED)) + { + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_INTERNAL; + } +} + +/**@brief Function for clearing an event flag in NRF_NFCT registers. + * + * @param[in] p_event Pointer to event register. + * + */ +static inline void nrf_nfct_event_clear(volatile uint32_t * p_event) +{ + *p_event = 0; + + /* Perform read to ensure clearing is effective */ + volatile uint32_t dummy = *p_event; + (void)dummy; +} + +/**@brief Function for handling events from Clock Module. + * + * @param[in] event Clock event. + * + */ +static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event) +{ + switch(event) + { + case NRF_DRV_CLOCK_EVT_HFCLK_STARTED: + /* Activate NFCT only when HFXO is running */ + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + NRF_NFCT->TASKS_ACTIVATE = 1; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +static inline void nrf_nfct_field_lost_hfclk_handle(void) +{ + /* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + // reset the NFC for release HFCLK + __DMB(); + NRF_NFCT_POWER = 0; + __DMB(); + NRF_NFCT_POWER = 1; + /* END: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +/**@brief Function for evaluating and handling NFC field events. + * + * @param[in] field_state Current field state. + * + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (field_state == NFC_FIELD_STATE_UNKNOWN) + { + /* Probe NFC field */ + uint32_t field_present = NRF_NFCT->FIELDPRESENT; + + if (field_present & m_nfc_fieldpresent_mask) + { + field_state = NFC_FIELD_STATE_ON; + } + else + { + field_state = NFC_FIELD_STATE_OFF; + } + } + + /* Field event service */ + switch(field_state) + { + case NFC_FIELD_STATE_ON: + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + } + m_field_on = true; + break; + + case NFC_FIELD_STATE_OFF: + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + +/* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + *(volatile uint32_t *)0x40005010 = 1; +#endif // HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +/* END: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + + NRF_NFCT->TASKS_SENSE = 1; + nrf_drv_clock_hfclk_release(); + m_field_on = false; + + NRF_NFCT->INTENCLR = + (NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos) | + (NFCT_INTENCLR_RXERROR_Clear << NFCT_INTENCLR_RXERROR_Pos); + + /* Change mask to FIELD_OFF state - trigger FIELD_ON even if HW has not locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; + + if ((m_nfc_lib_callback != NULL) ) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + break; + + default: + /* No implementation required */ + break; + } +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +/* This function is used by nfc_lib for unit testing only */ +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length) +{ + (void)id; + (void)p_data; + (void)data_length; + + return NRF_SUCCESS; +} + +/* This function is used by nfc_lib for unit testing only */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length) +{ + (void)id; + (void)p_data; + (void)p_max_data_length; + + return NRF_SUCCESS; +} + + +ret_code_t hal_nfc_start(void) +{ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + + NVIC_ClearPendingIRQ(NFCT_IRQn); + NVIC_SetPriority(NFCT_IRQn, APP_IRQ_PRIORITY_LOW); + NVIC_EnableIRQ(NFCT_IRQn); + + NRF_NFCT->TASKS_SENSE = 1; + + NRF_LOG_INFO("Start\r\n"); + return NRF_SUCCESS; +} + +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length) +{ + if (data_length == 0) + { + return NRF_ERROR_DATA_SIZE; + } + + /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + NRF_NFCT->PACKETPTR = (uint32_t) p_data; + NRF_NFCT->TXD.AMOUNT = (data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) & + NFCT_TXD_AMOUNT_TXDATABYTES_Msk; + NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); + NRF_NFCT->TASKS_STARTTX = 1; + + NRF_LOG_INFO("Send\r\n"); + return NRF_SUCCESS; +} + +ret_code_t hal_nfc_stop(void) +{ + NRF_NFCT->TASKS_DISABLE = 1; + + NRF_LOG_INFO("Stop\r\n"); + return NRF_SUCCESS; +} + +ret_code_t hal_nfc_done(void) +{ + m_nfc_lib_callback = (hal_nfc_callback_t) NULL; + + return NRF_SUCCESS; +} + +void NFCT_IRQHandler(void) +{ + nfct_field_sense_state_t current_field = NFC_FIELD_STATE_NONE; + + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_NFC_EVENT_DEBUG_PIN); //DEBUG! + + if (NRF_NFCT->EVENTS_FIELDDETECTED && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDDETECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDDETECTED); + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_DETECT_EVENT_DEBUG_PIN); //DEBUG! + current_field = NFC_FIELD_STATE_ON; + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); //DEBUG! + + NRF_LOG_DEBUG("Field detected\r\n"); + } + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + if (NRF_NFCT->EVENTS_FIELDLOST && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDLOST_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDLOST); + current_field = + (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN; + + NRF_LOG_DEBUG("Field lost\r\n"); + } +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + + /* Perform actions if any FIELD event is active */ + if (current_field != NFC_FIELD_STATE_NONE) + { + nrf_nfct_field_event_handler(current_field); + } + + if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk)) + { + /* Take into account only number of whole bytes */ + uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >> + NFCT_RXD_AMOUNT_RXDATABYTES_Pos) - NFC_CRC_SIZE; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + + /* Look for Tag 2 Type READ Command */ + if (m_nfc_rx_buffer[0] == T2T_READ_CMD) + { + if(m_nfc_lib_callback != NULL) + { + /* This callback should trigger transmission of READ Response */ + m_nfc_lib_callback(m_nfc_lib_context, + HAL_NFC_EVENT_DATA_RECEIVED, + (void*)m_nfc_rx_buffer, + rx_data_size); + } + } + else + { + /* Indicate that SLP_REQ was received - this will cause FRAMEDELAYTIMEOUT error */ + if(m_nfc_rx_buffer[0] == NFC_SLP_REQ_CMD) + { + m_slp_req_received = true; + } + /* Not a READ Command, so wait for next frame reception */ + NRF_NFCT->TASKS_ENABLERXDATA = 1; + } + + NRF_LOG_DEBUG("Rx fend\r\n"); + } + + if (NRF_NFCT->EVENTS_TXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMEEND_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND); + + /* Disable TX END event to ignore frame transmission other than READ response */ + NRF_NFCT->INTENCLR = (NFCT_INTENCLR_TXFRAMEEND_Clear << NFCT_INTENCLR_TXFRAMEEND_Pos); + + /* Set up for reception */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_DATA_TRANSMITTED, 0, 0); + } + + NRF_LOG_DEBUG("Tx fend\r\n"); + } + + if (NRF_NFCT->EVENTS_SELECTED && (NRF_NFCT->INTEN & NFCT_INTEN_SELECTED_Msk)) + { + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_SELECTED); + /* Clear also RX END and RXERROR events because SW does not take care of commands which were received before selecting the tag */ + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND); + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + /* Set up registers for EasyDMA and start receiving packets */ + NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer; + NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE; + NRF_NFCT->TASKS_ENABLERXDATA = 1; + + NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) | + (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos); + + /* At this point any previous error status can be ignored */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + +#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + /* Change mask to FIELD_ON state - trigger FIELD_ON only if HW has locked to the field */ + m_nfc_fieldpresent_mask = NFC_FIELD_ON_MASK; +#endif + + if (m_nfc_lib_callback != NULL) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_ON, 0, 0); + } + + NRF_LOG_DEBUG("Selected\r\n"); + } + + if (NRF_NFCT->EVENTS_RXERROR && (NRF_NFCT->INTEN & NFCT_INTEN_RXERROR_Msk)) + { + uint32_t rx_status = NRF_NFCT->FRAMESTATUS.RX; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR); + + NRF_LOG_DEBUG("Rx error (0x%x)\r\n", (unsigned int) rx_status); + (void) rx_status; + + /* Clear rx frame status */ + NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK; + } + + if (NRF_NFCT->EVENTS_ERROR && (NRF_NFCT->INTEN & NFCT_INTEN_ERROR_Msk)) + { + uint32_t err_status = NRF_NFCT->ERRORSTATUS; + nrf_nfct_event_clear(&NRF_NFCT->EVENTS_ERROR); + + /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received */ + if ((err_status & NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) && m_slp_req_received) + { + NRF_NFCT->ERRORSTATUS = NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + m_slp_req_received = false; + + NRF_LOG_DEBUG("Error (SLP_REQ)\r\n"); + } + /* Report any other error */ + err_status &= ~NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk; + if (err_status) + { + NRF_LOG_DEBUG("Error (0x%x)\r\n", (unsigned int) err_status); + } + + /* Clear error status */ + NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL; + } + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); //DEBUG! +} + + +#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#ifdef HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND + #error Wrong workaround combination +#endif + +static uint32_t field_state_cnt = 0; +/** + * @brief Function for evaluating and handling NFC fieldlost event. + */ +static void hal_nfc_field_check(void) +{ + uint32_t nfc_fieldpresen_masked; + + nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK; + + if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST) + { + ++field_state_cnt; + if (field_state_cnt > 7) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + + NRF_TIMER4->TASKS_SHUTDOWN = 1; + + nrf_drv_clock_hfclk_release(); + + nrf_nfct_field_lost_hfclk_handle(); + + if ((m_nfc_lib_callback != NULL)) + { + m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0); + } + m_field_on = false; + + /* Begin: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + // resume the NFCT to initialized state + hal_nfc_re_setup(); + /* End: Bugfix for FTPAN-116 (IC-12886) NFCT won't release HFCLK */ + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG! + } + + return; + } + + field_state_cnt = 0; +} + +/** + * @brief Function for enablinge hight precision clock and start eveluating fieldlost event. + */ +static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state) +{ + if (!m_field_on) + { + HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + nrf_drv_clock_hfclk_request(&m_clock_handler_item); + + NRF_TIMER4->TASKS_CLEAR = 1; + NRF_TIMER4->TASKS_START = 1; + field_state_cnt = 0; + + HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG! + } + m_field_on = true; +} + +/** + * @brief Function for resume the NFCT to initialized state after software's reset. + */ +static inline void hal_nfc_re_setup(void) +{ + uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR]; + + hal_nfc_common_hw_setup(nfc_internal); + + NRF_LOG_INFO("Reinitialize\r\n"); +} +#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND + +#endif // NFC_HAL_ENABLED diff --git a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h b/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h new file mode 100644 index 0000000..607816d --- /dev/null +++ b/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h @@ -0,0 +1,190 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 HAL_NFC_H__ +#define HAL_NFC_H__ + +/** @file + * @defgroup nfc_t2t_hal NFC Type 2 Tag HAL + * @{ + * @ingroup nfc_t2t + * @brief @tagAPI52 Hardware abstraction layer for the NFC Type 2 Tag library. + * + * @note Before the NFCT peripheral enters ACTIVATED state, the HFXO must be running. + * To fulfill this requirement and allow other software modules to also request the HFXO, the NFC Type 4 Tag HAL uses @ref nrf_drv_clock module. + * + */ + +#include +#include +#include + + +/** @brief Events passed to the upper-layer callback function. */ +typedef enum { + HAL_NFC_EVENT_FIELD_ON, ///< Field is detected. + HAL_NFC_EVENT_FIELD_OFF, ///< Field is lost. + HAL_NFC_EVENT_DATA_RECEIVED, ///< Data is received. + HAL_NFC_EVENT_DATA_TRANSMITTED ///< Data is Transmitted. +} hal_nfc_event_t; + + +/** @brief Parameter IDs for set/get function. */ +typedef enum { + HAL_NFC_PARAM_ID_TESTING, ///< Used for unit tests. + HAL_NFC_PARAM_ID_UNKNOWN +} hal_nfc_param_id_t; + + +/** @brief Callback from HAL_NFC layer into the upper layer. + * + * If event == HAL_NFC_EVENT_DATA_RECEIVED: + * p_data points to the received packet. The memory belongs to the HAL_NFC layer and + * is guaranteed to be valid only until the callback returns. + * + * If event == HAL_NFC_EVENT_DATA_TRANSMITTED: + * p_data points to the transmitted packet. The memory belongs to the application. + * + * If event == \: + * p_data definition is event-specific (to be defined). + * + * @param[in] p_context Context for callback execution. + * @param[in] event The event that occurred. + * @param[in] p_data Received/transmitted data or NULL. + * @param[in] data_length Size of the received/transmitted packet. + */ +typedef void (* hal_nfc_callback_t)(void * p_context, + hal_nfc_event_t event, + const uint8_t * p_data, + size_t data_length); + + +/** @brief Function for initializing the NFC layer. + * + * This function provides a pointer to a callback function and the callback context + * to the NFC layer. + * + * @param[in] callback Pointer to the callback function. + * @param[in] p_context Context of callback. + * + * @retval NRF_SUCCESS If the NFC layer was initialized successfully. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context); + + +/** @brief Function for setting a HAL_NFC parameter. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to the buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments + * was invalid (for example, wrong data length), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length); + + +/** @brief Function for querying a HAL_NFC parameter value. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, maxDataLength will contain the required buffer size. + * + * @param[in] id ID of the parameter to query. + * @param[in] p_data Pointer to a buffer receiving the queried data. + * @param[in, out] p_max_data_length Size of the buffer. It receives the required size if buffer is too small. + * + * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length); + + +/** @brief Function for starting the NFC subsystem. + * + * After this function completes, NFC readers will be able to detect the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was started successfully. If the NFC + * subsystem could not be started, an error code is returned. + */ +ret_code_t hal_nfc_start(void); + + +/** @brief Function for sending a packet to the connected NFC reader. + * + * The provided data buffer belongs to the caller and is guaranteed to be + * valid until the HAL_NFC_EVENT_DATA_TRANSMITTED event is received by the + * callback. + * + * @param[in] p_data The data packet to send. + * @param[in] data_length Size of the packet in bytes. + * + * @retval NRF_SUCCESS If the packet was sent. Otherwise, an error code is returned. + */ +ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length); + + +/** @brief Function for stopping the NFC subsystem. + * + * After this function returns, NFC readers will no longer be able to connect + * to the chip. + * + * @retval NRF_SUCCESS If the NFC subsystem was stopped. Otherwise, an error code + * is returned. + */ +ret_code_t hal_nfc_stop(void); + + +/** @brief Function for releasing resources. + * + * After this call returns, the callback is considered invalid and no more + * events will be posted to it. + * + * @retval NRF_SUCCESS This function always succeeds. + */ +ret_code_t hal_nfc_done(void); + +/** @} */ +#endif /* HAL_NFC_H__ */ + diff --git a/components/nfc/t2t_lib/license.txt b/components/nfc/t2t_lib/license.txt new file mode 100644 index 0000000..fb8b852 --- /dev/null +++ b/components/nfc/t2t_lib/license.txt @@ -0,0 +1,36 @@ +Copyright (c) 2015 - 2017, Telit Communications Cyprus Ltd + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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. + +3. Neither the name of Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. diff --git a/components/nfc/t2t_lib/nfc_fixes.h b/components/nfc/t2t_lib/nfc_fixes.h new file mode 100644 index 0000000..1dc7b79 --- /dev/null +++ b/components/nfc/t2t_lib/nfc_fixes.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_FIXES_H__ +#define NFC_FIXES_H__ + +#include + +/** @file + * @defgroup nfc_fixes NFC fixes and workarounds + * @{ + * @ingroup nfc_t2t + * @brief @tagAPI52 Fixes for hardware-related anomalies. + * + * If you are using PCA10040 (part of nRF52 Development Kit), + * you must define the macro HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 79. NFCT: A false EVENTS_FIELDDETECTED event occurs after the field is lost. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * + * If you are using PCA10056 (part of nRF52840 Development Kit), + * you must define the macro HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND in order to apply + * workarounds for the following anomalies: + * - 98. NFCT: The NFCT is not able to communicate with the peer. + * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode. + * + * The current code contains a patch for anomaly 25 (NFCT: Reset value of + * SENSRES register is incorrect), so that it now works on Windows Phone. + */ + +#ifdef BOARD_PCA10040 // assume nRF52832 chip in IC rev. Engineering B or Engineering C + #define HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND +#elif defined(BOARD_PCA10056) // assume nRF52840 chip in IC rev. Engineering A + #define HAL_NFC_NRF52840_ENGINEERING_A_WORKAROUND +#endif + +/** @} */ +#endif /* NFC_FIXES_H__ */ + diff --git a/components/nfc/t2t_lib/nfc_t2t_lib.h b/components/nfc/t2t_lib/nfc_t2t_lib.h new file mode 100644 index 0000000..5544f0a --- /dev/null +++ b/components/nfc/t2t_lib/nfc_t2t_lib.h @@ -0,0 +1,259 @@ +/** + * Copyright (c) 2015 - 2017, Telit Communications Cyprus Ltd + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_T2T_LIB_H__ +#define NFC_T2T_LIB_H__ + +/** @file + * + * @addtogroup nfc_api + * + * @defgroup nfc_t2t NFC Type 2 Tag + * @ingroup nfc_api + * @brief Implementation of NFC Type 2 Tag. + * + * @defgroup nfc_t2t_lib NFC tag 2 type emulation library + * @{ + * @ingroup nfc_t2t + * @brief The T2T emulation library interface. + */ + +#include +#include + +#define NFC_T2T_SIZEOF_INTERNAL_BYTES 10 ///< T2T internal byte size. +#define NFC_T2T_MAX_PAYLOAD_SIZE 988 ///< Maximum NDEF message size. +#define NFC_T2T_MAX_PAYLOAD_SIZE_RAW 1008 ///< No NDEF-TLV and no implicit lock bytes at the end. + +/** @brief Events passed to the callback function. */ +typedef enum +{ + NFC_T2T_EVENT_NONE, + ///< Not used. + + NFC_T2T_EVENT_FIELD_ON, + ///< NFC tag has detected external NFC field and was selected by an NFC polling device. + + NFC_T2T_EVENT_FIELD_OFF, + ///< External NFC field has been removed. + + NFC_T2T_EVENT_DATA_READ, + ///< NFC polling device has read all tag data. + /**< + * Repeated reading in the same session i.e. before @ref NFC_T2T_EVENT_FIELD_OFF event, + * will not trigger another @ref NFC_T2T_EVENT_DATA_READ event. + */ + + NFC_T2T_EVENT_STOPPED + ///< Reference to the application NFC callback has been released using @ref nfc_t2t_done. +} nfc_t2t_event_t; + +typedef enum +{ + NFC_T2T_PARAM_TESTING ///< Used for unit tests. +} nfc_t2t_param_id_t; + +/** @brief Callback to pass events from NFC T2T Library to application. + * + * @param[in] p_context Application context for callback execution. + * @param[in] event The event that occurred. + * @param[in] p_data Data to send to the application (event specific). + * @param[in] data_length Length of the data. + */ +typedef void (*nfc_t2t_callback_t)(void * p_context, + nfc_t2t_event_t event, + const uint8_t * p_data, + size_t data_length); + +/** @brief Function for registering the application callback for event signaling. + * + * The callback will be called by NFC T2T Library to notify the application of relevant + * events. It will be called from the HAL_NFC callback context. + * + * @param[in] callback Function pointer to the callback. + * @param[in] p_context Pointer to a memory area used by the callback for execution (optional). + * + * @retval NRF_SUCCESS If the application callback was registered successfully. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t nfc_t2t_setup(nfc_t2t_callback_t callback, void * p_context); + +/** @brief Function for setting an NFC parameter. + * + * @note Not implemented. For future use. + * + * This function allows to set any parameter defined as available by HAL_NFC. + * + * @param[in] id ID of the parameter to set. + * @param[in] p_data Pointer to a buffer containing the data to set. + * @param[in] data_length Size of the buffer containing the data to set. + * + * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments + * was invalid (for example, a wrong data length), an error code + * is returned. + */ +ret_code_t nfc_t2t_parameter_set(nfc_t2t_param_id_t id, void * p_data, size_t data_length); + +/** @brief Function for querying an NFC parameter value. + * + * @note Not implemented. For future use. + * + * The queried value will be placed into the passed data buffer. If the buffer + * is too small, p_max_data_length will contain the required buffer size. If the + * buffer is big enough, p_max_data_length will contain the actual size of the + * data. + * + * @param[in] id ID of the parameter to query. + * @param[in] p_data Pointer to a buffer receiving the queried data. + * @param[in, out] p_max_data_length Size of the buffer, receives actual size of queried data. + * + * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments + * was invalid (for example, the buffer was too small), an error code + * is returned. + */ +ret_code_t nfc_t2t_parameter_get(nfc_t2t_param_id_t id, void * p_data, size_t * p_max_data_length); + +/** @brief Function for registering the payload to send on reception of a READ request. + * + * The payload is considered to only contain the NDEF message to deliver to a + * reader. The required NDEF TLV will be created implicitly by NFC T2T Library. + * + * The pointer to the payload must stay valid for the duration of the library + * execution, or until it is explicitly released. + * + * If the pointer is not NULL, but the length is zero, the paypload is + * considered to be an empty NDEF message. + * + * If a new payload is registered, the previously registered one is considered + * released. + * + * Passing a NULL pointer releases the current payload without registering a + * new one. + * + * If an invalid size is given (too big), the function returns with an error + * and the currently registered payload is left unchanged. + * + * @param[in] p_payload Pointer to the memory area containing the payload to send. + * @param[in] payload_length Size of the payload in bytes. + * + * @retval NRF_SUCCESS If the operation was successful. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t nfc_t2t_payload_set(const uint8_t * p_payload, size_t payload_length); + +/** @brief Function for registering the raw payload to send on reception of a READ request. + * + * The payload will be delivered directly as-is to the reader, without + * implicitly adding an NDEF TLV container. This can be used if the + * application wants to define the TLVs itself, for example, to provide a different + * memory layout. + * + * The pointer to the payload must stay valid for the duration of the library + * execution, or until it is explicitly released. + * + * If a new payload is registered, the previously registered one is considered + * released. + * + * Passing a NULL pointer releases the current payload, without registering a + * new one. + * + * If an invalid size is given (too big), the function returns with an error + * and the currently registered payload is left unchanged. + * + * @param[in] p_payload Pointer to the memory area containing the payload to send. + * @param[in] payload_length Size of the payload in bytes. + * + * @retval NRF_SUCCESS If the operation was successful. If one + * of the arguments was invalid, an error code is returned. + */ +ret_code_t nfc_t2t_payload_raw_set(const uint8_t * p_payload, size_t payload_length); + +/** @brief Function for registering the sequence of internal bytes. + * + * This refers to the first 10 bytes of the tag memory. The library will set + * a sensible default for these bytes. The application can use this function + * to override the default. + * + * Passing a NULL pointer reverts back to the default sequence. + * The data will be copied by NFC T2T Library, so the memory does not have to remain valid + * after the function returns. + * + * @note When modifying the internal bytes, remember that they must be consistent + * with the NFC hardware register settings (see @ref nfc_t2t_format_internal). + * + * @param[in] p_data Pointer to the memory area containing the data. + * @param[in] data_length Size of the data in bytes. + * + * @retval NRF_SUCCESS If the operation was successful. If the data was not NULL and the + * data length was not 10, an error code is returned. + */ +ret_code_t nfc_t2t_internal_set(const uint8_t * p_data, size_t data_length); + +/** @brief Function for activating the NFC frontend. + * + * You must call this function so that events are posted to the application + * callback. + * + * @retval NRF_SUCCESS If the NFC frontend was activated successfully. If the lower layer + * could not be started, an error code is returned. + */ +ret_code_t nfc_t2t_emulation_start(void); + +/** @brief Function for deactivating the NFC frontend. + * + * After calling this function, no more events will be posted to the + * application callback. + * + * @retval NRF_SUCCESS If the NFC frontend was deactivated successfully. If the lower layer + * could not be stopped, an error code is returned. + */ +ret_code_t nfc_t2t_emulation_stop(void); + +/** @brief Function for releasing the reference to the application callback. + * + * After calling this function, the passed callback pointer is no longer + * considered valid. + * + * @retval NRF_SUCCESS This function always succeeds. + */ +ret_code_t nfc_t2t_done(void); + +/** @} */ +#endif // NFC_T2T_LIB_H__ diff --git a/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a b/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a new file mode 100644 index 0000000000000000000000000000000000000000..c46954d705634b78c0490a3ad99225d9745ced0f GIT binary patch literal 733000 zcmeEvcT`o$v+mCEoU;$+IOd!%J7&yT%sQik3BwpiF^xK+Vgw@?F)~i#!x?|1i#fv+ds;t-I#jDqN?)l&85wN z(St|2j$=A?Z2NDy&46)(TMd{n@;};+uA|0`o6>Q>=mA4rN4bvvkD}Rx@joMbj0far zQMaDW|8?EMb>M`d9mk9wju!kYbaov*xLePE*=|$DcOO1z#J{|A=Uy$lx-{?5xp{k+ zwq3hqwz#WPi?*G!3VJwo?cUPSg@|KTc{k^_9UWb8?dIsxy%&{nMHv#a_+P-)O>lJ+ zY+k#W60=x6tLILwns?92w{~vZxqHj3l5S2;Et+Q)bZ^_SW!Il-G$lW|H6=B&T6OK- z{AZh%9i4yDcWRxLZP~n8R&YIMtvQeO_Jp+ z=++B8*s^txpV|gtbrSyM5W*TH{OPVBtVzO}Sz88SEfUtsCag`u+F6BWH~nO5N`5kQ z?uD;AON*Ubbj-?j?A0SH3-nK|2LE$|F_LPSgTuW3q(c|}#J8={EvxHR&Og=E!ga_` z4;aS0o9n3NW5&5QA30{wh#q4H4{&p3(xq+jv}6?j1u&zB403U+;pT#8c*59!xv>Mr z4H)I><~ok#|BZC$PtqwP#|#*p4Vf+*H(=6F^5LW5bM%0bKM7q&O&B@AZTOhcF5}$> zjQdY@S>>3RGFv)$%xG7Jsg`}(|9KJkFWj%SGDZEhOiv?+4|EwiXi$2!6UMrX9yg?R zjjG+Mj;Zz&WW3p@8QMYFwOO21HI>!Umz&J$u-;^>N04V-iK;s~)}fWChGV@N>5c2J z&1l)770a?%meT)Nrabc>j$vN3Fy&$`layzyjK)Z9<#uv=-$MKyp+QvdIOi|7e|-4< zgFYEfGRXI*|MkD05jk8=59IVfP7mbtKu!(?K#?+x=(kTAW|WBt8D+W^HKR;qZ)XO-p29FX zK4ecg1)nk*JP%5LW7EmM*UaBrsRRk(|0kRyFqt;w#PnC3O6h;(gZ}E`^AoN(1oX-H z%fvZ>{|VO=g3O!DQf!2B*89DI`*nvQ-LIU1BcC1d!9DzYn`7}CGDRTE{L8G1zW>a7 zC7l;={W3wInK+_c7I|tbhVeuDERfmpp{5e0wq^C_(;oGbGUG4PUnc+GQU2dr)3y9h z9?5?ehk)>mn9V{=M-CcY#qg&Je&=q!k^S!~*JyD&x zP#OYS0U!F#N`fB;N@F{d_dvNy7Jfa-)w1w=P_CYZk3hL*7XBj2wX^UKP^Ph->HiJN zzh>d-=ZzX<;R|HrD`exHvhky{@xIykz-;`nYc+NHr_28?~#r7&BpJ|#-Gl{-^#|n&c+LPNVDEw!EAh`Y<#0^e8+5j-)#Jd zZ2Z)0yk|CkM>hUYHvUXDJ|2ALAI&>=vhgpn@t?EtVwNd{>@DCk`-7ezru1OO{B=Z^ zZo~g}W#|VH(@Ul4_Yre`H}T&eQq1|?#LS-6pT=46Lh+kb?D1c4> z1wa=Uu!v;;<+A*2V#ZGsX8*axT$nGk)(n%6Xq)u7ifh3z#ldqeF?A3{d_;d7CKsA& zxV-6cB?lvlnYjGv@e)^nVe$}u|4C6=?fkHi^MbqP7?iYq>N<0E& zRLO9~83s*YxDpK0foMsFaVA=dVY(AVV<94n52t3vLJ%phyFK+fmsmC-Ch3W z#>Mr`C_7g=bg6TSd)GegFMkyBocvfk@8ypQXlYOjXn9aOXl2kmppKvgKx=^(0c{Fe z9JB>!Y0x&H@0=pq*s@INCMBebXFoEDRr?G53&L}~paQTc z42zmU|2b$0Udbr;WC|PTsT&`D@hFB3nQ5?YKBm(;^)sY z94D4?6+z@)Y1qM?eZ(<*liy**38GOP7HMB0aT;Yx$gY7Ok*1Q9Am~9xo&^Cb)iaArUWio)p2cjr$$0Y(Ei7qnPIc*UbnZ$~h_?S&% zu{+(9$TH$nv&^V1(Ihd6rRhXa&ozbSnaL>XA8jN?Og0&d)~$J0Mtp8EcC9%vFH9zn z)~$^*Bfez6!E*uidOz5_GBu^u*E6sweQh%3)q>?vPm0M@R%70YjQGZ69M$Xh0efpQ zwN!Q)?&6)v)KhN{geKKw8fwn1P-z;Qi^JTnwIJrbc?)ecrxsv7m`n%tK@eK-k*y4v zvs$GT?&lNR3QT|1si(k*pV>NK+|)7+(1I_f>-mgMcP}o*h3>-aJDrhVqHK03RcQ)Y zM$eD3%;92cs1{ShGkSH>6v@<3m8M2u^!B8oYAsQGMs*c4nB2pf)HD#@%ETbp&>M;!KmVFqX8d=-yc(IkXm+{AHeDY}+=8 zjI@)!a>iE6j&cB%1zXWKEF%R{SuwggA?dY?$`)JX8DMr(*=|eRh4P;KaFZv!sZ=y? zh+|~(&Ub7MFF^;X!WL5SbBGKlM@HI5_9#|or2SMB45u25bbyMA;Z&26La1mloN6)B zK`Pn}r`n8kh>CfPX7CV7#R5h%cnG6n5u+JA9HwG%qZvFLp<-#H89W@NVtJz(JRGB9 zWurShgj3Pc=nfCZsaVVC4i6`&SkLGV4-r&sXmp2%NGdjE__0p7;gjWX8&BceA2bR7`L2wvPx{vH;=-LRm@H6d<^ogZzamI))3h95wIdU!aJDX>Nsu%kQUw{=^Pq4KD`FPp~_y^xtW|rNdJ;2n4Dd3h}6&p6HP9U;4ttB zd`>dC0)j)OnP~N7lPi)j0H$z3sG+#vFftB4|2AtcAUaH^JDSR!qgxjp^exa$Gj;Vu zhk2y?hr0q@L($=_9W9$->iS~FrG8jEYtnbPb~~rTGQMGFaVZ?&`!>I~F6mYo-&!`;LHAo0DKk6d^0060ZV|4w^|;iMCD(PY}wG%F4UQ&}&QDGdgbS#Ogm4+hg& zACsvJ1{2zECgTVOlj83tQ%g)A1%1UR_^v1BqG`6DscH%azW*?p7GU7p#bnxmf$#n% z(*X>84=@>LFz`LlWV(y#Q^g?hGJN+IbI}Am*i`ig1K+MDGZ+kf4>6fxVBmYG$&3U8 z-@{C1tjOq7;pjhKBXz3zHO^r46{K;;#T+iwiKgZsMh_y*T3qxnD*56I)=yH2)?NJ~ zm1vgGuV|^AZYueh}|c{b}uM{bwhC&v3(2X0XqxD`NR$^ zSOV-~6hny}!4&>j38732nR>g($HlnKI`nLdw6Fl+z?QM))_GfDTaWw>tUdplX4vXu z8?Nh(Aw~3%kKt|g^#*#|+_;qtIT|gpY}?!{WKs#HZSHEgf4MdaxS`yvuERhirD{#L z7Te~o2Z#n%AzeDFmo+Uc8C5`vH9f;zCv#hdIVvY}Bf~s{wF4?<*5r_-Cd?DLveX1N zch!u$C|9s;?&5HjCqp1+3iAF(K>B=DnI;9(Z@gSV66CMSRL||e=8~EgSk;WOA641^ z0RELzqYD-VvMbvoe{a1H3=0uUfONKSt$%x@Nx_D2R3t-yn`%;!@+;{H8S~qrp_Bec zY#32Nk52$TyYShA&t81?;S-5Z<{x3#;7=0~nSJ%NLV*RS~u4PS}`Pcu^WLNyP9{O}&tQ<*iyq!ImLO zXGNCGCP(c99c2(sUs*ebIj+ zQ)Vsp7fc67Dz9x!*L~OUEHe|H5@ugMDktM{6&d$4gzQ-YyACEal&%}|({)5avU+y{ zTMou8j*xXQfx=r6(()W#kM^dk_agGPsx#qz){|u7GxB-OAjuP7lKA#UV8FOxtcgr( z+`h>C?L*fy9mwa{F!E4p4k24zB;=Yv($4#xb8SZagxfXXN9 zQaLSw{BK8SBr>0Sk^KDvx{lpLw%wYL+#`stVXp|e;4$5`YYdf#o~P?Tvsb?*le}96 zvhr?0*CDUzdg?e`J)V+>E<*`l?-#nxNTyoGVcr&*suf7G{tI0zjVI*J8+0wToFvJ} zN{GyLe<~ZT$?EVOx<2RWzS`qe2a##kocu&AB6(Ozvb~ChOk|ooB*~8EbiJC7uA^6y zw`z~5yt^Y^ovM-N9~9a#FYuI$O#P))W+#)Mwjp$F%8*rS9Da$+gD!OK^_h^m3)TB1 zjQq^=pz^sVRPJ}3FjabzpGXfvCMS?&{%I;l?;vkCeh_j z({MdqOPH-?QV8$bnzRRpQn}d{x|aKuFp)2)+-NI#n^c)<`EZKL6JF6Z?+C*9cOqNQ z4TLO_NSNO+Cy7j80g@a><{3}WI+8pcLG7t+&Ivvx$ivM0bnSnTuDcCFzN$su@{cCl zDJRIv!yGMLr;_|pNy4-`Nq)+F`8_Pv?l-4;tA7x9^r?YcN8_4*+9c35!GT)U2OCh4`Q%OIv+b$eMkj5fI^-v;EqOSJ=tg8t zc#(XhIV$1{P`TuM!Y7#{zhW&a=Q~Hpo=H^p-9*=sRSDU05Y=8ijIQ7QAWXjjRCf2H zwx!LY@`z$2-!y|H^FEQJ=pm9c4Wl-cG)R76I$b+0qN^jN4VflO=sIXANeXPIx}JTd z>mBon_+~z>jSiECEmrdRxH@V7NFl5B)k&Uz9$jm=lZTpSpRfvPzYnBq+wCOpTa&H^ zOCC~pko;GP?(XRyB(G#XYZH;^5SiE@^8cwW`7B5&Po~jsvT9|@x0*BgO%KyEVjyJt zhLE< zChe=)Bw4(S$|KB?AD%?WhSv$BO(5GhDbxlDxfOgzzY^XbM^@?@Po_$DeH|NF%$z;2w2VyFUJo3d-%uy^9 z$quo2$Aj=#rcMmXmABAlgAm475f&v9I-y*x0b)C`0;2l_0Qe9kgsMVf52!D z8#D^~6Kv6j*uY<7TTj5!PCm4W#bIHOEsk=b$#E!``2G^9iMoHGEY+*I1F4T+1D@ep zpTTOxHK5eG)bQGGXj`MQ6=BtQlnl>J0u)G^R-^2*Q^PSRH|tj(t>{?20q(ZP+CNb4 z|8*(kBih@6aSNXVtEu}b;_+a=Rs-Y7dQ*^7y&D~wIs zi1r_0&DI@d&E_3r&Gv<}W&@A2W(!ZS)Wq~#jHN&&@5|e8SJ={lZt?dckd(7G$Ux-Z ziU3_K`ZyP=FD1I8T;W<*lxvR;z_p1y3N~$9(g5mK_%zDiYzbOnd{{dzJuBF-NC*Sj z8+$=^vB&%4{&urP4nP;eJ}wFu2ier45FTQW^?@*gt?7+>ie#^~Lsci)qq8Brz!v4e zMYBz2;zlpB9tt4W*>*k<-e4EJ2IMCDn1aQpY%o$RIDdFk4z8cEP4=PMPwcS?AfMTq zL!kS@w!v;*T)>U#3xkDRpAaBDxwgIFYzZ^+{|IHyTBdo1MVglkMyQ^i*ux?;{oUF z3cF-(YkufbxIbP%_=ekj9gs9m+6wLy*WC*9@0?E;YA3&a5QN@*smrK+HD3=wzPOQJ zw+0YD-eVz1ApeX~{JZ$+TR;x+xB9>!ly6MW$SFQwCqPc~jVX%0$_LYJ#`BY2W;`cF z6RSW_BIzEkB_r3uu+*LDxH=BnCZ!LN;w@W1SL(o6NJ|%>IH^oS;LPDuukbeLX0e}R z(6-rZlWEX;usj9ebJ(&wU@?~+cozF1dYmez>_rpW#au0Q(i) zhU*`nB5-wyq$zC`Th@+cgG@`$qc#2|=Xew36*uTtsOJcAKR^P6Wt)N6Bervd?wA#Io?Hskn$$}a(Au5j9HyzpZ`OR)xw(TsA!Gg z*A1Mn5Qd{lah*`;Pe3*Zuhye28wG!wVmApq?aDR_cS=IIRR}o*-d4oG57|zfg70%~{FkGmS2;p(T|2pc65ULe|mq@{Z2InbZY8=REp+jy6qlCM( zTRtbWpN|?Y2vxAgiP6H9e9*-R_3=uA7%SZF4riBz^PgdNMJP;Lig=+|D9AP8i4!0< zgkpC=ZVHul0+JwvBf0_y~IcyWr&N!iaNNZVrPm?mWgWzf%6tU{zfBw z#2GZNuM~SVf^L=QwG?EnxR0VFU-3HpuLXC(flH0MH)mO#Ucg3eHQD}y!1uvyA|ZS z7~K!#huFO^3}#8Q&%oJiX^#bDuJoOd^Q7LB!7Y#~{sHrak}wO^dP#v4=Pi=H&;t}9 zc}{>XQd)BZ+-d1b1?bL5`3VvwU6~HuIq3(E>ck7uD@QnsmP%5v9wXJFon@@lsxNB4 zBz4~e;bmzA&6roEy3Qc+QdCoP)^(|w8@L61uA+Vb?gQ1u@vzNc2A@Mc&k=?CYADoE?Ek!0`8@hIt<(^Y1tr{r$|qOQPCSo zqX7J!^vME}DpjLY%SO56B2?=qr(S`Ghn_{Zo{*dOf_a2|mr^q)<)z~RIVG363vx!b=Y^NE zaL4evV89# zxaab07Or2(e^3q=P6Gf!P$PL z>vrf4D03*RKBU~B)i6{Ui6dh1h*Ix1oE=p*jfFwDvJ;_!cwFgx6SYSul^#JDsW_eo zIi-BY`HFa2$u|NdN@=?Q$aBh@&ZyynvbQaqMJt>3Ko_fg#}-12Q(Dm${fbh4BDkwc z04=81ls{?AUsrM+2J)sdt0x+NOBpy1_1#uBj{x$HQgjBmd&({9mqcYx10WwLU2lUt zRQA)8^H}+|AI_dA(KH=CQ-1FNyJY2lH#mE#)cyeBE2S?j3@J+Gjv#N8h$ukbDJ$dP zB~@`c2JXGm7;ip`9~8&s@cBvE-2~icr9^v>uS#PI0lq2qsrDaAu?Y~mt8vHSY_=LP z3I-l(Ls}H)srw^9=BxiK2gFltzZwuP^%nK#Vl_Dg!X@g)f*{M(_{kv4)uPl+A2ozB zt}E0%)FG?X{cpjoRukvr#@4F)XnpWiF(fcGtDpKqw^41q46Zk+LujwOS*=(aT%;N? z6x>NQfmREQ)qJS-jCwmBT$DO|GwjZ(O(;1Wt>%9RpBL3!J3(UAK?Na5l5Z9_Dw|(wzWFREHbj?yK8%kVk4$ z%AY(|*HF;*RDH1vT#_0?$N->Fqc zflF0iyTbgv+I%5|A5^dDKz>r2MZ(KxwG1t-U)6tFL-U=7YU{4x+_gCBx^%0@hU)x>+!kyZ5cbEri z9Vwr)OPfh?$R2HR3A80h+n67^U~SBKkbT-1de9GOwWk6ZqREs92-S{Kt|d&XK%0o8 z+9Jw)9n-#rq7lb6>l6r2Xft!)pGyP7%;&hBZCcA^mvw9d1^J=CJBfjrhGuLR_Y)^`!ileFrAfIQRQ z{|+zDwNJFZztB$pKn-*Bk~9I%)wj~5I$y7~637Mmi}5h`)I0P9#7qBkGRR_mLr*wc zqMv#V$TIyc?cbN{W9X)R^jYoTbA?`(mZeqtFV7)dtq*t#pKJB4w08LF-V>l(udh#o zZiC*3(i(pHdCHY-()}piwng`#wQ8%r9j7(ocD?0680^rOT2WDeUX$j*K>aKa;ci`_ zoYo$_XCg?j?i~uUPru&_b_aBg@`@pP85&E6^t)@ph3YGgz{_F124&EW=!ZN|(J_6A z584v0D+fVN=*hWY9-%)!0OU#i@=G-7l%DGl49@6<@bZ^ztlM`KR;xhj7#o ztrr^$?xOD44kT8$Q*;rh-^be!;$?k3#k5!SW%S6z>+{yb=QaK89UznRRVs8TdgvwS zzUjYdAm8-~4IuoX|FIF~?iLRRAZJ=S&^$QHveFyovn>tkL+D}IMC;~U%YJ&e=2?0* zhTVKiDo(z|1s1s`3>I3f6n}bJdd8xiUX~#%V7|!G6$vJBsioN|)UeD_Ee&2)Sh~{Q zc%`KW1yQGMuP0?}cn=wG{scPI*i7F{nDLN~H4Ym+l7T*AMEHUnH6GKne$1#e1rEcF zUuuCIH=Jpxo-k@rdm;>fXS65M2pLBBqu_5-}vwuwLdWCe}LUXBQ`I{BO}xf^4Mrw z3IIO%mjT&n4|xDxfc-Ho0D<;Tb0FMhuUZmhx4i)Et@hZL&^i!g zzcmxWz4pt$fCSqQZiDN6_LBbK_S>VH!1V$9j}t(K*pJ@;IcOh8`_V)8Uf)1M?fYp9 z8D@V(S&75;(sZJ7#QuWD;8FYB%J6c`KD-4;xZR6#{>Sa}MgeldJ`E=}W>%?K9PQjH zPMC#jrTl*bTG>KL#40T{l&e0efCg1R<^ZD_`DwYX8SpE#wXWjr6tVXAsnFKDK$+TK zm&Br6zXP39H0aYAl7{CgUD~XzAIi;7c*C|uADXLMjwDH|a*tDVyQ7UDY5%w^ zv>lGsL%E|k6j$d>?V#;au_J2i>PORkw=T4q=-z_E^|!w$jraS8^0*GT@+Xi3R}VmW zP)vE?2UmLo%%8SU$VUvOUF~0Uw&6PNPAT}A{D?N3Qz~pjdB!lj(SW3Gg{u%PWLp~G zJlWotpz>k|&>&vKjtYmH#ca}_;FhqdcHHVxcGM9-ma&r^QQdO(&p1H5*(%cj@nLJV z1_XOlihfqIug*cYimgNkF00uR6l1JmW(A zywWE2JFQ=v*(oz2+``r>i*{~h$3~-~ZEOwN0&Qm>(Ui1SczAUoL$ltu|) zed%;DkbN=^x?SwX2Yxd(RkQBBcJ#TN=#&f{EW!qMO!8g#fbf4I~o* z3zR@SxJ_k%oWtFrl+|2r{dm+ckNZLE;e4*zRhTc}`qcqsA?JS|5Kr#adqBLna@7G@ z#Qk~#!o{3ZGa#36PF27y<=&&l~?eZKheNF+^M}V58@L1V6c~4LaBsc zt|Xn>@8d!SK)0X!AOm@TTelC85H6`KAP2eibR>0%8%b}8gmTvk0usgr=0gpKxtPh& z9pO%whVCfm-5BH;SA8QO;oLa}B!cTU8YGgNz7OOi7o7ldiVN!na+>2s+`}2}>SR=O zmOES+KBKsuC*kEB*O6L%o@+*N!UgW11%O0z33PaWk=w`s62le4+u=yTUup>w$L*tu z=JPC+*(RKUE_WU0(YH5&K7|T=RO8rZgOSlY~~jCARLecuGA1fZgVXt z2)M&-pr!UMSDg}H_c)Hy`ia~w%D&y_I?+gez_G1>e8>$Q0`3u4hgSc`+*3+zKj9+j z5q-w3z6X-bRoesPb8cHMwE6{Cn4;{L+&LOqueeDxC%@+Szky8QuABn$4HtL}khk3O z!QkF;xvl|{%H5s{NE-KG7P$A^fkbd0xKWg)|H#D#gM8vn(l+%o*K;^rf8&Bq0QsGZ zn1lxY;5yTq;m*5Io?s@Q-xbJN{5BoP*}QZR6?yPSDgrWxmo5M@m*;5@I*(7FscSyp z^$Z{jcxQTFX(9jk9PB*#KP!TG@iAV2EaE>?a%(Za|CB>jy#kW2SdJDq!{DKas zXaoP-UR1P^_sR?6#|P3@Z4>`#6Ofzvy0j(P#y{E#vYnqxFZt}?C(MPpKkr!>!kzrc z1t0SfZon>#U(p@pFfY;beuU3WNtL7gVR{MT81GIoXE;CU0ql@UAUE&hnjCqJ}8`_m8kU z$M@|Ga-MfQ3iCMrM{#hM_#0~hxy)Cm#rq0>JQmKb@-Z4nJin7pORn)#F2LYAKcqPz zH~6)*9l6QZr~U9PKE5U(3H(1>0lCfZ>;a#5_yM8d?(!TZYVPr~>0mpNZ_x$@_xXqq zFn`4R)Pn9YKZMdmPxzQ|@bZ*zLyLD3e{mTMp7BFz@lNKe--F$Aeig+bFZc>ofqcmi zrbOv0e!&-Tulc_z2b;q8q1fsT@AVSGw|pxaJ~jnpwa}9? zLTiL>G`p=8rp*P?SMa3V(K?|YrES&=vvGhb`U!y)gKZKxS`;@6eQ2HDBBaiMm#xB; zvS{u$;Y19C+l8vMc<&GnKZb$7ATI-Cr|?@{Kmvp^w;>D^zVrcPmvEUf$Ge3}lqcUK zJgf;4B$TH;_FiGZ2iOG*)7yg_5ZuB+LWFs3U~o`yE{WzI5-MIseW3zRi+7lCkM<0Q zg`Nvh(GfwWfpSz>M%l$hU zJ0*;ah52dW4@ZzF!M`Hx&I!-@fjck6)`r~$0dqAL4Z)B0d>4gdwE2n=d^V$^SfN@Q zK;nda?*O?Zl%xFYWno86K&}XNXcu%{BCB~KzYg4daU?}+3&eUf z<`;^6CPL^bmVb)2c!{6rg|J29KAOZAi#-QGi<@5ovPIlM+0(7!fTnbg*IW=lZA#AJG#U$?%Yz|1Oxc4O>X<{og z1ut4fc=;d}uz-9N>o~#LCvn3jAV1^14UjM5!xA80#foQP_d^`o0mNPMr6Y!!lC}vI z&63pCFrO_Ie+_dFspV=I%#o~3QSDsGm2$rGq%pq%GGFp$VYfgk8vw{cX{rx&p3*Ve z4SGr8Wk425>;lxVSQ@qux+PNCf*?z!2a{mFQu;v0qN}8{m4I9=jamV+Mv`f3vQ|>I z0OBikq1kPnRF7u2_0srNfNYRvI03RzI=CMYKdE+aKsHH7c{tlF4IPgfwn#HCLAO;J zNmI!-X~8l;wo89fwrht}tq(|m^lk`9ptR~AxZWjs)9kiex<|9y9x38EDhiVRqy*Jo zsg?wv!O~uTK=w)9y92Uc%Jl`11JaKzfP_f?G#4C{zH|fRkfiPdBvjf`03=MRGZ8f$ zmKt4z!4WC7DoD80YXo%1rQUU6a6*c?5Az7AGri&!DUG3lc~aU+8}L(-wH?e)OP2S5 zoRPkc1mvt#pT6QK=^ULHoRboM2jslevku4wsh%%th?aVOgTY0qN*9nA=`3xXW2M)$ zIlnB8@dkHA>eB-TSEa=F@DeX=-2m>IG@UYp*CiiXt8PeZ2EyQ`)LB83Zb{360ZEYL zwy5E@^od>sx+7J7h#Kxnxl4fDlh!nWFi|>6Tj%@Io-eR_Aienm>{Xs9- zJeA5!gF%wCWIvoelh(|DL9(>250KBLHX@KOq&svgFQsaf0evN{I0VRRY3uKRq)6Rl zK;B5F==pmqB_=@lPHI*hBvl$Y6S_31*i$t3z4W9R$Ooza4j?~EH@rc0F4b6#ihfAJ8XD*>PoZD`+&J} za{*+YTv|Xy^JSKHU<>3)Q9v$~MVd-HWuJa9SS;73iEN1+{0X|Ha_ROkSSHtXf%$Sd zH;q^ro0a-2gnFoV4@&O&L*UC>Qq3J7kKMJx= zUPkZkte4BtN%RJJB;^J-%6?SCX1V2Qa9iXGYhkxlK1F%(ZSq0NziyYO9EHIS`P)C> z{N=uMNV8M+4MAH1pn<<$kU}o{%3= zHYP&;%^kW(*@uFKlky}wLOCVhp>*nL`Hy1Y&dAs4%=4`5M?*16j&B2UPM$#<#`E&w zc$i<5+tb!0Mo#Ji5-Wf92Z@u%90s{0Ul{;{%d#6qhgamhQ&7=WIi(cZ885GV2kx3& zemo%8Dzodx8vyn|NCC-NFP>Ub)zKM9{n^33{xJd?lP0wh_UG!c;J^2H*6 zypYrAYkVme*bm(+`BQ$7*K#Y$Qm4o>?gH{g9!$xcxAJ*UAk*aCv@pDvzxD(2gFJBr zbRT6KC0;(s>lUJ-&vJ=sfP9hdXW`|me0dZg-{ijw0P^CSc}aCZ+?C{;fXq}1 z`T{abar+9$Y{jP=r2J3c+rn(r5+@Je8)j@Ap#9Jp);! z6o`ayv7*r)c8Ma=9(Jj+zyrEvN?av0ce&D=_ORZ{uD=2CQ7Y3Oc7?KWCdf)<_j=T@ zN*VY&$ZBPK09v+2`9LoXtW_c@IksN8Oz(PaP&{d(-l!}NhZjF3#1-5os{Vs9~q_f)0xU6km7P1uBCdLbyw* z*BWHE($OEtJxXl_Bv|R|2jo7b6wPk?m2s4jIH268j6{g?wJ0D56)#$g4=IZqqn)9O zRta2~vX(a4hm{ydK#nNl4G51aiCq9Wrd*_%FI*Yo3f*y~8$DGgl>HR6MJT710vV}v zegep8r3)pb&M2+uRe-a~8JdZrl%|UzJg3Aap)Kc?>y#?Hpjc;tL@RH|%SB~r6?lnJ z{;rKy$108Pz&uX*o6b=$DfyG3yR5wK1ad_gM(5I3mB$or#Vg0?c<-80cM)9QR$4Ry zxubla3UXK3F%aaQ(%%YaiAs$SRCHe%(GOl8CTfO~MAq%@?5>zUGN1t7^vbJ|@$SH`vhd7=2+0`jFY#DHCj5|ta|jZ)%oAm1vD zDNFoL5lf@Fsfrd2XKBjVWZ1n|YUcy_pbR_?^N-4++JJmgic`+c=~wNHS-Ty^4cc$ugEbqYS` ztCJ~byg+?D2atv8P1=zDO{u`Q{xw_jphTgL~U~o+*0*G7`SC>WO0z? zs_h@xd8@5&!>5m0gkEM^p)U4=m({AzHh5X12D`y-t%}eM>w`LjX4-Y?x4b~ESJ%*c zOB>W%gF!Z`^=PK`Q^RPOZc@`Ie%Y*Ei-VUf>eC5;Y*h!-iNiLv2E}~a)k@_6*`XFV z4T!(Gvkb^i_0kTIU1~}g$ZoZs8+`6j-5h`nQpbhCe6RYZKZL<*97SaN)IOAU-LJ;4 zMYRXi>NJu=)DG)#e+Sk542&2?*Hvu`P zRxJ$I=hag5ykAfiIzx?CFa8N~Q4OG+e~kJn2`!6NtJ2#LacXB^~?*OH`Ei9`@N|asS3MWYKd#8HbFf!4UpSvw{n2oQSCI--c@f+ zhwz?yi-NsGby|KH+*e!D!Px_K(goN(RNqtwd89U53glz8aw^P|)cdr&JX0$@fG}Bg zn+dz;s%Hh*y-@pJhVZ3Yb~uo))OuB6{#rdS8;}&W6D_T8)FrgZeye_+0?0dc8f~&u z)sVLkrm0OSDtWIyqiF4eD$pH$ROe3yWVNQ( z#Z9l#meNttTCMgxKzy}r)arGbYY*71*Y484{oEjU4hO|JJJ!zP1-U#$J?x> z(h0{Ft@!d==Pn&5Y9#VIAU zN4rfEe2^wp2V}3-h9>x6jp+)=J}qwwAp5oZwCg#bb?XEYqPc~jqJvs8_52|%g?c_z z8}AG+N3{9$=H5}Qbz7Jp)B4i{AFlnD55nWx(gZ+GXq{++kI)>dz&uj(+5pH&Z7iM9 zp3=^|0OYjRpfL>2XzTg_a#mYPLqAHJIslM!+Tt{rpVu~=0e3;0mk%Ub3!uk0R{M=6 zk2vjZ69_M9Y(6-Xjz-_H6WtZ=04`>^BSIfHwuJ36*8IVNn3+;LyY7Z#&_(DH?MWHN4S!3DCXOw#)!|rwvX7BvlJ<3GzYvO7rJOt$ITkeA3?0xA|FXKnu|q z?VoPwcy7LwaTEx={U><}e7;ON2mpSayP?YV~pb zHO;0cbdS7%MCf}cER58vP~!8X9y$)XQ@Rij-D#cw737RQl;VQ3`qVE#p4Yq3M*4zY z?l?%aeuj3D7jy9=+9_WKZP|-vEbw5BJ=>;g!`dEKF9grvbJ=#S+)oar(GD%<3ACPDIRoX=+>k*V~ zdaegI1$m+O9Seh(diX^cywZb;g1puX&_T{y{Zd=lz0+3=0y0&1*$*yFKSoD4@Adi$ zgdg<7LtyYxpQgj$lYWGDk)L(_cR;@AjyfP;_3gBa{H9kg2FQ24;v#TA^v}=0xm%vm zkeX>}yAkc2WtlI5%(l!Q3@>vn@f1kRvxHUvnQs{x2D=58eYCS#Xt|*P>1jDav5l9- zw>K(UWQjiq$YP7f7(kX-+zSG-)bb0RMl7?`84k#DOKE!P(c7}?Bx>-n)F=(I!t!P= zAS*2clK@#|!4JjZL9i63a~WStuLmIOEcD|U;(E(VTJ1MjCKW@UZM1~Y_QTIokKRDp zWSL6M`uz2mKnZi zS)j%D0}S?9+#f*~WO=n6$h{UhH*~?4qKDySpXI=5G-0CLcB zpJIkXmH;}$3bmB}1&}aH6kaS64_jDIa7Qc?dINdXGLg>Fk6G#z0SULfrZwQWrFR;* z)0ScsZJ)6e{Q==w%k>7Zi?T430zPLs-yP=XEuj=kU9fzi1Z}h>sXZVUEp@{IiLo>s z21u->OBFbav#@lyaLIxbXFL{`6Lh|E#p3A$gR7Q}AHc<1JbweZW~n_7<~J?vY;b+c zl6(-51WS|7@N(PIj2@Xgmctt$ylZJp`~G{D;fGOCq9v^?boVV)XtX}CY~2gULyL`k zKC*Zp1>~`1VkPLFSc-U}hNqTDT0WC3jdw!#%yL2iNw$m_ii%!Zj+8*{uPove7`(QW z_Jx-e%U?Days>PcKP9F(=4Y=K=X- zsWcSA&z23eHTh!MO<~$si?I-pZx)9Dn18plpajuOYm5fuENiRU(9O2)^at^5-V`=eTWZgsy-(suB zE*OO7Y40f zYn?~AdtdAG&M;qR-4O}MdTYKBfNZc<%LT|r>!ibg_*p|J#l6Wo%Mr-U)`gT|-D0hD z3B9=x7DEh^&V@+h6!iLmmNKZ~^95&$`A9Ug>=PFeq; z9p-6kv6FzDvBprSdDgm;c9>CCk6=K~S!V}Bc;4Ee0LTUFCE6lJTPxi`b1zzjMj$cP zHgw>0$y$n@>C4vfwDw=Iw(bt(RcjX(!gy;RYSK09oB}{zw|=D^<_&8ytsOV5PkBIY zS*y_ckYL?LJIvcwKic2ku`ZzG-(9Qr4ct9zNf(er>w4OE+_$!V0ptVgy$&ErRyRrv zKC{m636g9**bk8B*2FKku@}}2TTtIiD^KI|mGvKbU|(CEXdz0mo~M+_8*6!5h~8S4 z(n9pk+ChbvRO?>a^rl${UIXO4wN3==K3LBc0r$~5;tLEuS-;Xl^40pPFATm}Pt()? z-TJ#9y!^1PpeDK7zR^y2rfs+kGRtPCRM~7>Nm__JZ0l$tnq%ut>CCyd{KpHSY->QG}CI^NLq;2*bdP`wAR+079wBUKw5~_*+w=% zMeA+eeh_Z3ZKdyMqs?;|kbbrRdZS>I&H4@%ZMD^J2yUCL_i#AdZW~Eky&bkw^e%wE z?F5}I?X=nGc?ht*?E_t)?J@?k+!E6n4h%Gp@ry_4F}eEENoY5ft<0O^#Ss% zt=03E&{0M_bwkVn(YvU=kIL>Eg>Il9%S&*_AnffPqx?*(0#T!&H?#iv+V)ot8G?EK)%^7 zMga2N)^jv;KWzWx!QHwWP7P7fOk*QO&9jV6G+)m)?hgdS!&q<%kU7R{3V1w?zJJ4+ zmoZ{D$RcCV9M~;3VgjIBVkoqCT57DGiu+q;cu~x-+}K8YbZ=t=ZM}Sqs`OsT3S-|Q z=vEp(>cL=@;nN2#TW#by1mqecBrnKX!)p=@e2u*H1*|isH-g`R4j8j((GM|B-G$vj;|L|= z4jHcWaD^JLZU7Qy1oi+qY@{Xva>Qss%h^%mIi1)ZGd58S9d3N16WilPYGDXZ81?=^ z4H3pET2mv9Jas`%8l~yP_LQ;y0JyV8xzq3xWgLzN@|>}S_UPx0>q`N-VEn~^L>sSZ z6kIe$&VkPuV|Fz_VvUM)VjE{vpcC6mM$^~ua@laD6Wc3>M>~+KhF>W_;*Bus-D^gp zaj5UQQLq&nf5Ui0lX!yB>lVmuBQylaJ4W5=(A_m^(H`%fah5i{iN=9Su)A+~t%sKf z#z0CoJ~Z~e1muz7OPl(~MyG~=JTXcK0rJ#nSO8p-;YtT%&y3t0kjX~lD3IqyRC$mW z#-B8ZUK`y1;^?~LqPm)>F^NWFbo(x_>;k(i+m|iC7L#a9HKuD~s!6Pg>51u4KtM!_ zg(g)6QHqFwU;(5l3J3xglp;-(Dxd<2z<1`$Kj$|yXJ+nu``*2C=RP7$xI+t`x(w#< zg0KID-^hYVT8Qo~u-gsg{RNL{cl}_2of&?k3tkBWWo*GNx-a7k_Ry>LaDn4HpgdZz zd=xP!7WmWN_wj<+{g5UXyiRk-)B*u5(9;WAH~?=($|AULWxQU7M1G8UkKy3YXr)ia z0vJ3Kq-~6kTEGlsd}@LFc7`|g{DT;Sv`62;m`i=dV8+~=poB1LS3(M9tfVSEjPWdW ztambeW1!r{*g@@v-3Gh4IB6z#+y&IGBeS+A%OQ84{Ydk1}r4qo2hXqyxia44+BZvKg#HQ06fDX%Cyr z;8AzvIAe4@qU15|KZhv!jL>{gPB1z}pqym9-wf##)hv9N-e8b_mKkM)|vddWN1}wFbrw zJHS=OX)B^!W7z1|Y{YQkaGl}u379t+qg0JHF(%f7(#%*#jolVTF)cQ&j8|!~xycBo z#iorh^d~6o3>PO*Iv8UN*g6>p=%lcVu`m%)ZZRCu-*~#4v0x3Dw;66{!0ctLzY6GM zw3oo4pYaCmR|XhawAc(X=FG*A?lQi}f^CR#krta_#`Cn;j4(FPVsnq-M}GGik}|*p z#ztyRk235^KpA5goB-nty)T##8J%4S_J~pZI$(lvGZoh`#rP`@e$$MS_rUaK%4omh z!@Nry4qxUPnr5~#%V@FjV;-f&#-C|VAN&R|83mwhW4^2hC6L*436$;3Isd^H#Pp?) z6?QP~=KzA4)9Vm3gt?&_i9(tEG@per4|&6VH}mI*NV|urx&ZfZ<{A#926`Gn7WIg#4>0821*?B79H}$GfjS=BrtuqLrP?h^&!JP z=Eipc`)mjGKX^YdP~A7{qC z3&>-(W@6O&%yJIk6!XzOz-i_`^q>?l_k07tLZ&b6SBjX+X}@xY8AAJ&VrKa|NF~hQ ze?yc~W(jRn%9vZuL0Qgxhvt{F%&k<8oMT!SfKtKy@@G)aGml-ykS;KPF#;-?x+pkQ zG0z@DqBfevMf{wP_>s!CRnQXMQja z$_-{%Jd{n$ZmM^inLDZR(!#XSQ`gE&*bm!H<_GlDwJ~4WiLtaZJLswFV17t5*e&Kh zCI->X{GE!L+sq(pzTaU6y$!z}rYs(Qz07^&(8qj^?q@&KDF&1Q=I1o(LFRw-j@@Nu zE(K+X=`{ksVdj=ngdSnKp9AwAa~=oE`^+GE>K-sJI|4?T7wD;b$Xw)#n2(qqbhJOg zOp8L4$4t8y;XcWnM;)FirVBOSr$SA*imnl}?e z@@FL|KnY;k^~1J}HL(Z~$g27YlrOivWK;W_J83lkE5VOuzvptlt|VK)1XALexMA|tO2@bds!kaC^4*| z5Kv-SAO8tu9IKF?x_DMe1Z)YcZhGqWv;4df`T(nNAs~rWN6q(S*7y|QAnRQrVy3V@ z&p?zztV0fna+uXW0b43-75%7btjakEmd*-xMX(H(;VWb~!upJ!x=fZYJ#|M}4fNDy zvBK%8JH~pCp1N#S+9QNM&I+dbI*--!K5Y3c%@h)yV7*Mu_meEwWpF>mnn$Nsr&(2T zU>2}e(SuURI!fK%BG$jO8$83hGY`sQR(%2}C9L!Za42OBtpJp<`c6Pu&N9*8sGMaz zL!UdIW1Tt+=>jX67U4=(*;1sfVx6Godo}9@{bCncA=EOdVHHx#q?WavS|*oRN2p~| z#}eHIrJj{fe-zQc>YWA3W!A_MP_D2VlcBuIa-jQijg?LviAGi>HO{WHs;F^xgB7zG z%odiH8kAO6>-UguvNRuq*~Z#I#brC|S(=PHSn|cVhE7%*eIVDx+V>eKw^(_VaOh^e zn-0ot)~oM>a)-5b28Ptb>ZEUfdRhMTT=%i^sp#%!tw;oOfHg1!FvxoQYdDOv(vBe5 zL)L3OpgdwZRX{nxYNQ%$inV<)@=db@eUQA_zqufo54+D7Oh5J`n)3YFS--$NfW48b zl5K1cnv8?kBlJ`4VDFB^AcEPmX?qpIPW=h)JK3r92=8J$(dKS9+j0)>d)QG_Jw>wn z>F6zreQ7r+(d^hhDEG3rP_Q_*{WaL)*oLG%>^l!( z%Vj@B<@s^;`u8B^u}?W7SU$Ug=Cf1mCubw=Y4%DgCkxo`(MGzEy^z-1V)kZg^pvn) zq&<2mdzL$tW$b+ipghMepq6X}ds81`o@d9?Ute5c&!ykJnyq^SaFOjur))LsL$u?o zWgFyxdiJ*KP&TkHQ7L_y{T3bPU11*?fUS|e=x@Mv_O%`)y1`zw1Y>DpzfARYE4#-Y zaFbo!3cogX$Pa*acJ&M}yV&2+p~NkA)M+?$vlG99bep|?J#IlSdm}ybee73GL)p(> zL6h77yTKWLLu_{?D8uZ>)ZH3k&+-A>W4}89+bDaa0=6+W{(1yY7W;A@q=)QZK1Gzr z?31*4on-$=W!e<`^MjD4*#n;B*FwT>-@a^Q-(J|64&iN+T!a3)th>GBR7X~SkqaMPwM{)As z1|^1b!V6L?N3jGD$5C$v#B(musq;S0+-H$tKd0pdzyZz>bv% z=cO+&meU;kMLKsJtuTyh@GvQjUe1PGubX1SrcnGJjAiIGp)# zIL}!|J@E^i4Z9Gmk~4x6yr(a6t{sD|hO?FpsO2my16<-v(&118hy5RdUFPiah4Kn6 z1rAp^34cI&ofG8<0A%`H&2bK2=cln&0{GXS?Z zKJ5tI%}HH`LEPr}P-FKFX9I0l`#5Ls0s1+TC7=v&Dti!RkW;w@X@@!IY3DY=QQSk! zdz_FiQ0{ZQk^y5J2T#B_r|?C%Kja*vH|`PVd74cpInH#dH^q5@_M+3AMmpT{<~o)@ z+RA;D1EwGMBP*`KpX<{C_W5I4*MX$N7(^`h{WXXg$K}$^is$}Gt9=4D zeHZ-pbAzc_e1JO`k6=mMjrmX}bE9)19pXAhKswB=qs?+E_e(0G(zpiNP#xjEZH6+F zyMX4;qukQ>kT#3k{v#lV8*l@*T<(6_s~zV`e+1-l-%?;mC%HYF5&9Ijbr+=5+=Wz! z6mUz%Af4f^qeGBlZc`$nlyFzk`d7+LrRD4_w}<|s@f>$Ct(z5GrZ+O2=booCjVf;6 zZ78d`Pb~rEA~z)pQVrLi7U4SXxmgHS&uz0IbOZOlU7%d%-d_#nHE!Q`fJW}3g@Ef^ z#a86I!To?9uomuf??Bng4Y480P43x2NNwDZX4pEpFOpvuH{eM)+~OWi!C1Pv8}>li z!>tPh^m4za?s6Y@XCtJ3uD1vL?s8vCfi%QDOzq)euCfG_5pEYv7Z12=F2gp;O{a=w zjQcFLCC9n%=Yu)Ly|x0(X|D7QfH&{nSFri;%%=d`c!@MM2l5tCmw!7?N{3iMJTbNY zLwH|MxfRO$tPIRBo{098J9#;@W8cGjVhhrS^Uj38A%e&K7g8i|_chq|^4e$@62o)Y z4rMHFY#*dJ-rBv85_yl6h_a9Od_7Jb~d-xsZ zg;D=Ao%c&Dqzv9T{YB#u-Z6UnGkGagHXY;nS|DZfo|Pg)4zHJXFS)$=vk*F;S5ABF z6Fi9l(n%hR8cU~mc~y`Kc|XvTRm2O?1J3ZS7eHCeyS)SMWjy>p^Dz_gO6f&7%WJ0d z#&f&`T756@@-kto0t9JFZ3=PuJLxz``*aQu7a(JmwO3PGcWWGLbvb?qoB0%BwL|u=k5Lp1MJ|fy#wgv zZFYmQi+6Gnq}x0JJ(zcRF4QCI;Z4&;_wtM{LK@)lJ7F8-$%7H>F7JyBNJG3I7Gg;E zcz?Ttd7mesBI*Heg9^b$dH2_X`H+|90_7v#C-cFa;8|1%_L%qhD8@O>i^_t{n_umN zU_SiWZvcGxD}M+0^WUJJM*v^!4dyofUHZf#kUvRhbvyV%+PDYv%`~@$@Q3KP4dn}_ zVB5uiKv%n)-$8eG4}Wzvq;UQc+Hgeivw2WP^ZlstxtE_54)++oR06+vzRd(%0)N?J z3@MR+a0`_C`0SUUOybYG4P`RF;5-r?&7x9I30$##jngl52PtrGgW&EZ4k*J)%+!IjAPxgjG6@T??Tv#>#xu?Or z$oKUCT;gkJr%}g0Ni#}4UrSR-1OL;`e_umIw z3*YW5WN76dk^^q?_t_zP2Y>q_Kqvn?66&#^cnyrG^CtwQ@JVW1AZWC;$haphV zwh^#h@Dz1;f(1{}vKu0J+6gg31+8@E9VYlu3fL`}kqycoLErPBgbOz9z*r&#@3g@d zEqIewnZ1HLL!iV6>~a9Hg22N_n;>|x8@5D2M;4U(1U0m1>=!(>8jvh#q}TAE;8~hV zQUo=$Yds|RgG$>p!S8hE(*+TYkTL|XHh^+Ou&xtQmLQmpk&X%8pp9R);3jnlas+-S zV9OKiUJGTu-~k=- z9HNv9Y}BwhE12^!l;;Kd9!M7i14>Ahg2%HFtV-|!ojTVDHqmict)QEx%1eST?qe)< zf*)zrmjx$(hV6=g^D%5!1;uNjye8&pr4BT9zm}?nEe7zI!+%D9Hg!6pkRU; zJ$D888!0Sjf|55N-4iTnhTnZb*LQ#if_R#}#|6=6AUzah(<=H%aF7}d69N_+5(U3O_yqwKcxp|@&} zo#%N#xZNo_GmWuJ{S=f~yNGAt9%mQ%7%}7RHr69bg5A5dfc?MO;KFk3V(=Z! z)46t)OQAe&7Zm_yo}F9{=1Ds>?XphUJwrW@({_z?gjQg8@dFI0&@Pc4+G4xL-B6a; zEo6XFYIlY97G-vKXtgM}OU{R~(yrqXq$;})9l@-&`$md<7wsZxEpD*O`yRH-c4JhB zT(L``*Z!(q|Em~8v)zGD0WEer{{W@cP9=tP)2@|D{tml<_YkbpE|?m8U3Td`P~Nih zdK;nd*bUKVXgzi#IzX@8%k;O8eRd!3gl*VvC6#F-cC9xNbKLIi2}lp^#`i&*w)_1& znBMlQXpIZ7zupVmHv1ZCdF`?vp?&dg`x^RH_Siq9N+;aDh8kxP_5swdi?$D?&DLIf zJ8vjs?Cq$B8*6`uCdWAYqF+Htv|mNb**^PsHY4VK`|f%~Ibg4)bBiSVU6rt<*zXyH z!y$WC0N}8F+ZBu~)&4Gh)}Cg+ISZ65du0TqWA7jIehS+e`{@~witP_k-CAP*b|Cyp?e|iv z<*a>lIQ-7pi(ZCbg?;6}$bR1bw@^qI>?g`0)!M&8_xh5(xfRMf`@=NF*4xK~0UGVC zw3Wrbbm)rEH|)){L^j#K?t+-D_S`JMP5ZSvP}=PERF}8gm;Z_=x9u5!LAqn_OP_@I z*bi@lve*7x17OHL^)5y>Y`>b8i4pt%K7#U|eGr|YjM_(B1&rDMM8U@G#qR+g+Lye5 zaXzyD=s8H<4lcBv^KodV&%1mbRwpCFR)=~20sI`Q=rkh8f$=ezI~>+hb2`{Tuon>G zU|R`gsKdJ{V1_&B>F1AdcsmUau@2uHg)PqEIS(-79a?7L!V(;|(i55JP)Da22OJ*I zUlJraT>TEVWQSe!3?6jITnP6R2MrZpha9fb%6!bhm-g@34pnc1nd8v$F{E6F9C|zQ z9T*OP6ApVH!tbQR@pObfU0^)%*CMkU<1gH8;}ghP8N93DHQ84+dDA(?gsQx5O{f1-9s?1#-)_`$Cj z%T{6VG1&ZsUr~R_UwC#Sq67%vng%6Um{|=75k|xULWMn{2o@%sNu|n8VI|f2dxY;q zU=ZQLQTog$Lb!}x-$-F6EoV`}!YDwDuvh?y70Uc!ixWo72QyxnO8toh;on~)%6?(p zTu29m{0#_}BwT$R%4FdMCDI-genxwlbm5c=whUn|t*}Rg8)(wW6n@8oGFO--M26$S zh5w(ng&jQD@`aa&p)3@-B_VB*@B_MMXN1pu23xT(eKw>L;o>8(l?p$l7pP3=a~_Gx zg+F`&%2{FY98k^)ooTkI7DgXJu#3V?ZIEh&`Sj6GtuT;Y^h?6kIwIVJWlPK5nBH;d5=tE2Sr11B>piBwZ zNf2dPcrX@Bf5+?xPzE@vY>>7&MqA()==jnOIBa*^O;tjWU76CK2?M$agJYp0%g2o*&2jSaGdJ~TcYCwdLIrt{zr|16vw|- zK|16prhUL+$A8!2hNL>a5Cbc}=y;eO zlp4pP&B#~l_}7O}UUKZ+0QUyRu}s)5JDR!?`ii5{0=VkvV*};787K)6Sg+TU5Q|}J3jm!$__`jGz{XF~>s1yYkzPQhH_XIDV)G zrO$B*b&&fV?PkDlz_IB#D1(m84`Ca2A%5leE zpM&(!aq448j~o|KDLv`9%Mmc;xPbO!(~c9=C-N4Zr>(+PQGE!&PZUlYMt{*Ov||Vm zjnkh?Z5M?Wz!oIZa*=(9Xk{=$2a9^|!xkp0pn`R$$nXhlyF?495wcsf=`h?QMB^Qh zB1L6%svae(G=UN=ilmdmSW&YGwm8vr974y7PSUP5K~zh1NU|uHewBlw=pay1L~Hw? zJS1}X8)*-Vn1fKJi&knNWr&BQxQ5x^!OP_xuU5T z!8|TnPZe37Xnro3Cq-qiK{_RRzW|ieBB35J3q+d+;8!Rre;*FTqBD0vDG|BM>;%T*zIji%=FqB81^To4t%4XIM3qMksND41G8HKK&qAk~T_&mqwz z(J&oY)QS90LRl|*I}y?q(Koc0xhk^mMU-ozelw4u@gUzFSa^h;knx!#&Xq`ZM_ZqEEC?J`jb{pRA9I4%4>f zq38x}vLA`&R3iI?s6PqJ$07w6FfBSq6^plc`6wtp;Wx7xz$EA0&=)fnSJt4Rzr{#hFKuAxzwS3l2NQk9m-Gi3QKYFG`$x z6AsbhAFo5&E8doiONkLXybfioI4>RU3E~q0@Jkfe?t*fkxb-$*zu1d`CH`rr4Lx4UdX@=@=g3>R}p~7=Oy!BTo2gR8ghNHGy-!i9*^qiGDF?^t`bb6l#QRVb$Bbe1rKU25&qEpx{C~KTHt^l*vX>%E*OHL1t z1FkxCO(4oOr=u}|MyJ8E7{qlaB^7NqoPMMYK$}w*ZTQ=rVm^h`;l%Al%uc5#hX7qp z$EyLioQCLQwmzp02T1)+0y=mYa0++{euGYq`vG^I-kJyZA*bk{Fo;p7Hu~sb%qfTV zK$A`z!;o*v$tMpKKj+_QY4vwDQVV~Fv++YHgPnQ%!QAcq7eH;#T&cEzIuzKeR5tNP2pWTM?x^o6y?M>%i zI>>2rt}_F=on2`ry6ybY81fA`pFRc3pmXpUjBMCBxeL;Wa}{;7A2`R*esk3M>`XX3 zbY4*bc;uYD4>oU?W+yoKxLl-X(9b1tF8usmmj4F`bXgXOMB80Hp`{?$r6Cc1Aud}c zA?Q%wWQcaTLtT|vm#Q*Q;#|_Ghnwh#Y?qNg5iG}L{Z3E{U7jgMlp>eeQ-Cur{XfB0 z?D89Zol@db`8oW`UEZ03@~lhRcL;sXh1CJ5aACW^cHSj<8d0iT`e{L_c3I;9zl$!} zwE3xVd4USST9@BxuB&(1Mg?7iOZ5&YFT2=pg7S*XSR|NNUB3PraNXtYZxH2%%h9J0 zv&m&WRh7*y3u$B2;<8ZyN}G!>Re9~W1qjyRQsV~bbUESx=yF+l9@%fZ@N*F5j>~N7 z3G}!`zXfHli?$t-KS%nO_1Px};=aWYaD?sq*)hNN6+ZBN0*i##d5ChnHI=udD+ENak1o z+ayVUff*<{{v4$35)ls>f+X#m0U;6zb+uK1^B~p4MO4A`zn^mT}GRq}}sq-&DZv@o&D}Ps2eqdHrLVmQ2$e4Q8ll6aUX*>Ow1|2hyQI(1>A-I3w@*SD zA$@)&{34}qh@p&E04__nL}L(Fq>;-3SEWH_D6dIB`w~$ar4MdkNY|xlN|${E>8A7x+WfRh|E6-QU233D0y?A%-U4(=w^FgtB@L_x+>%Zk z5wlzRw*i;ZFD;?g&VcmW-3UD>ok?Hl-<2j(aXBOvb%Hr8l~K_)B0WrX!9A%-2)Hl( zV)P@s zu076Gwg{91t}R>PkmMRbn~GG|zdwPL<{J40@@2X1PKR{Nbw~xjeAf@0k@kdZ_e-#y zbiLIN+bP%JrxB&l)%9;sid>b?K`M70qZ0hA>+Q8ro^yRA6Al%wZ>@u}(sd!#$yKh+ z4p7#){?ZI(z3b#FkQ!XwiZF=Ft{ct(uDSmA7|KT1we-P#tE)FH3^!eKXk**vntmFg z+g-QNPu1lbmj~&VtGfzPpX)+DF#BDfp>kxv^;=rG23>3D|9&y-T2FP)h$}N1%Ezw5 z^?*s&m7_>B<@%@;FzuSQ928#}cMK!jDqHg$g89ilYlqEWwnB`UfwI5oG-A7~g`UqK z*%~fjhis7?exb6WDnOX*?yK~33#qf)geYpk7 zc$soF{1Rk2PeV$Sy<>-b`($k_F!#&eTMa2$w(}`m!$H|(8~jpar)Uy5B$K5;IxKTN z2q|6Gd<~ExYo`M1i0mQNXPGkBuaW(zZ0Rs;*|M=nWXO@_jRJCIriXApE{pgKQl4zt zMlcIxD{O#5*@~@5TO_Mnk3pP~MbH#fEKAx3D3dKLM6hz%LB~JR(J;v-7+ryRJUabOCSx%-j!lV zgEE5wl)JL8--m5T_Ak{o!?KrtL!uGcB3ga#$pmyM_hm1w1?7Q^F$=a)*=;w#W0@x{ z`jfKts{m87K3ZO;Wn=EJdAoH|S?}X^yBp*5b<3QEC|lirq!-W6Z8;y{?>7Dzwg9*1 zQsBPLjYSW8pxZBwux)qyauUiQx8YvE4!6c*um!uBcLPG)HqpDX$L+gSfN-~w0zib@ zTmkY$x&>2LI?heW1;o3}Gr*SM_62>ao9K3nO0j)zb7wab99=N z>Q?duAjeHewN$R#20G3=?)CyLyLoPxiV^dq+o_!x^(i;D6Qt8_Tzd2i+*%hvdB&|O z7w*MwMd7fOxD5#rrPS?GDx#cq^ZOK(b8b0*!lA;=^azymZgm?VRk=MCf^k;6ZKikZ zqT3N_9@V&c?grGkotXt@z1tRgpc~w*^u7LNx97fu!!@^esi13gdydjxcVqe?(G9n; zJ~*_vEzO41>b8bjG&kLZzX00Ybaa`WZu@V-z02)onx$^JRUQO%yKS}u^tj!nFED%E zk~N6Z=N9lUq<*)r=~C{xee8w-4!JG$hWoIaBpWc|R+|Uq1Gfe5K^k=nr5}9E?Mte` z#@$k>PM&fzP`_^4O+ufVdCNbc`OHV2ZA468`EDVY{_>@#0ReKiAHduu=TT=iP`-Z> zL)tD+-vB9CzUFnfhsX_dSQ9FLg#`$cm(p9cQ@)P=oOX}=OaPSO@&c;vBjo&k$@Sj?D&%YzzAkh_h(ilQtm47%0$~E~`Iz(=iM=0TUUH)4iq7tkjE`UfyOm?lb@${ zU%&hrI({0EpQD>RDBt`IU|2rqBq$?t-(E=fZSPoTxyTXBz8N*~3$|3LCp^lyQ~R>kfpC<7GgJSev* zct!*ZR2&?_g>6@)z7AWELirJbg(%);Lkd-_U4#r_ieM^&cPiZIUD>7hnZ6MWS2VT3 zJwlQ88QdckdualUQmmjVC|aTX5>a9m6?T9)#l%)n;uU_s01_0^M+lav_?h0E1Bya= zG?ElEQy?WPJiY+sprUjk5~V0^Qw^P=xV#$D5ry+ggw9k%u%SGv*n1gKvK496Da}!I zcfvha@rb@dI<82Mhw_A?nT}FUDk?q%oKn1I1e{g``~+r^qJS2~Gl~W(x{DRg3t%fz zj6Z`6<%(|V0-RO+MvcgGiiR~{Rw(Y%Ay%cr={P7=iWJ(NRVx_O$+)O^bP;e#@&0^J z>J*phC8<|rzm7x=io5iLTvaTf8ReSd6MEPi71{8gA5#^SmITXx0inpi~>rvQZanE`cuP=hsra^_2re3U2YDfd-Ms{#JXL*yQyoT9O8Q?7auQlN4Mz33zlv~N71Z2lF@BxNb}Lz0y-bb57A`5~3rhn3v( zP^Ky`tcH}PG|*3+uH>ymq73EkK=>V18m~agQlTf3<=b-sdCG+c z0Qt)E`{8~*Ihc z$_yPSSCv0fEp<&fgAOPgl|nk5yRO_sd#7gQg3VyID8JkSN~^M!2kE9Vftn9(%EYfQ z+)m}6^r=Lb^7-%JeoNW(38Zf2pLCONE5~0$uwG@SE3)?~h2-9^+(*;>fYN^ewn60y zns|{8fhOY-xh=U2#Jt=Lizd*P#!B6 zQ*UirIfHuC-YVvGIQXdgt#I&FO+E?bR@F{VK!9o;J)hfD%hmw`RqN#lwq3Qn7|bBm z4mSh~QLUCCSg2|hoe+nqzF>i}Q+4hLY`au@X`T;P<-QLoLiKVXD3L0=SCKDDwVpna ziB?^r!?sw}RjMcARBzE9Azsy=2S`w{=pZ0bHBF~%2URbULyBtc94HT|zJ3Jhu<9ir zK)UMT6+nh+bsB6(R6o$_o2k0C7Ws~;vMMm7Y}NG_Vari@QClQeb)^oJe3cKKWS>xN zqMpD>)w|Dtc}f-K3n)}=q4~NzGhpQazx4NS$iiVg##K&AtSiPN%nRXuTXnwx(jCloK}56Q-Zhp^&tfF zQQxQCi?5nV#ihUcCL0i--b(GhZR!m%fI#&Fn&5Y+7w5wktS)Rtz7X|95`u-Q^MU}o z)EhrWu-)p93qaYU{rk)A`C0+dnbw@JP zm^(0Mse9goEla)aGx!}-?~I0&t!{Gz^SF9~?n|C}WfN@q>L9AmPN=s$3HQ_L5gK5D zI{Yh0h3cd(I25Tf{sg5&oq7mEDpeopfUQiul>ueBdQLQ;Lfu{qzw_$l-@xI5I+?!q zsZ@)o1$9xqV-ix0I)TcOT6O*yqFhop{Rn7KyHCRXvO3{=P_C%sY5#sz-A%oc>*|XZ zzzwyCYUn04pAV^7ZJ`@-Q=Ps6Qk(kmCP2GdNsmp3`qz&Echn)TAWDy#L%pY7^^Jd! zp--JeTa!WcFntepSM5(N*&#I}8p>gH$XO`wt82^Q@Ib9;g>qC~_aR_RE%boxk@|1? zKy^aBeF(uGt9xlCnpDRKkk4B)v;e_;G(X%1#aE-IPR&-$^m#}Dnx#iz+ost?jjTY; zacT%}*SwjEn8BK2Y7>TN!poox)g0BsAxsnIiu`_H9j&VXd+iYO4Q8y7nFUPO*H-P*F5tWQnJRI4qy*zk~bl3 zibmA|?U2|_4+%q)7CIma8xl8SaEX}|_h;mF5+zW?n&689-=V(SB z!y!+jWI@W;d{zeOga-fU5vC{2dRlV|G%wOFt5DOE4EG{ULmb@CXp(7LR;qa?5Q8Yw z^ppb1HPJKSa8~0i%Fr2WAGemk_s zXj>MnJ?R3!5N+AJfSuYkw2JQ13h%Qa?1wT^``t%?D6KzDvC-N?P2P{=WFjM;CDhh*B{E0+Wb{e zp3;WWqFAV%SOC8wZQ);#&S-0?kSNwps=+MN&Y~)>T$_Iya8}!%3^=DXeuL~6w7cp0 zDz#;$U{-0zRs*WFIrL=JYQNl#n3uGFNbsxFX`i6}OTG3%0Bl#Zd#OWrRXZJqeAl!` zFF$ZFDGNc4|+#L)oQOlta3$ zmCzrV+|hoTiwr$lGp&EU+IeZP4QNyTL$E=u(=rU=uC^cuQHHeN9f35e<(-DZnD#l^ z0E}xBX`}g2n@B6{BkiywqD*S-)&ZupUG(-(Yv;^|`caaL#ZMylipAOVb&@s{uo$moKgLRrrC_{AfmVpwgOB@G;>E82)a<}dbP3e1d zTm9h>uKTJSQiSetE~H3Z&Fg@@I;jAOVsxSdaER4aQxP1eTlFJC$Ln69GHstuwhJ-$ z>r$^nI-q;95mJ&aksgg?-3~3_knT(df*sZ+Q&T2Yx0LoyX*v5Ygr$|ER zqdMaigwE2n-h3A)$gJRiB(Wu(v@byp-wkOhwGPhhD2nzqRXc*Layp!-i7U&ZrLBOHR^Jx0&LRV zC#hMNKLuNh?sF!fRcE0u=5OkXw2(SG8g&lh?uhzD~6qFs3_y zANj_0VQ;|pQ0G4b%11gDl}!`6H=l)VN;k6%(zMQPJ;2*NtOq0Waes%33}5$b>ahB| z|8)Tn;QqY~u+6==3uy!0mlwl*yL&?+Zfmf6%h!-X+%5k=3U%Li29z-OI;x3wx~De5 zZ;!hlP3ht8Z_;08M7Ym?hh_nsVNk8`){1|{BofEN7( z_pIGeCcE#YSM8vC<{Jo|?jB6_V1~QwJwUemPtN8Q{UiFG=)8LXZ4ocHC!PYO+TAM)X)n6_(Q8=a z{-FolYu(eRgIw=EcLm%V+?mgSdD)#yrPvks`>{|qx-T68Tz6kjQ^F1RSr$l5?ps$u zYIUDOr_MLsUmk`-n|nRYwC(Quq)6N4KB5NPa?f3ZeBJKe(_r3qAGrxiuY1SSQ1-b8 z&}ntQd(gjN4!FOuAJUNfg#)k+yFc|5m?Q45eGBQH`^5L4jJm6rAkmn6*{`_1arXiv zq=)Xu=ox(MzMF3Hq7V@?lo-88g$%L!l`|p5>D#F=i`RcdN45L(QM5tbua|#~3r)wkBE5`uFK6_=-vNsCy{WjO68)?S z*vj?2G_jo3|Jn`ZIeml|qze6PPYk|NpEL}qO8>`fK(*dN&-F$9h9?1+^p_U^>h$@v zg{s$=#9>Gc`p!B?SM`(B?7yZzOJ5K*>YtAXT-U$#AqLp2_xTLA7JWX=rmgymD{u`r z_2blh@6b=aiYT3WW(3CBr57)N!!3QpE1=xb>wRJC(f{)&q+WeT3v7M*cG|`d>Nn6* za94kx7R4d`s_iqxv&453hM{@H~eu8qxyyvIE?A>uUKMY(a)zTZ$iIiG2pR& z4jpMt>SNylbDJUV1xSGg9+jxu4I60J8e|BjafTSap`KN!Vdy7N!VEj;hU_$SeG5vY zp@){iD8rI%$R2IrI0E(>&c6X=oZ(wqE#eJxUxzZmAg_Tk(cnORlmiA=J|M}EO#9Si zgVQqD4jO)cABhedvd+UH)$q&nfHcEZnu5{|Uw46$X<$&R?5IIg0mw2~zJS9qLj`q| zat*)S0US3xN6nl(!#w&bBHxfh+v-z>jr3NXHVhmD6c{||cP})odmd11SVCWhmly_4 z;C_}G_R*PCnW51O8O|9bp@0g*j3Ow{8&<_mR^FbLk$Z3`uGkh`y+arT@1k!||$R5&TgCq5qCJjFH zicT4P=>_sJeop;lU*m`j%B{xdXfF3NK1p?tzpk z=NaS+Hhw{mcbM_gtAL%xVNb-|WwfWin%ZsrB^}ZpW9D4AM;a5KN1`ZWc`-sq8@;^Y zu-Ev{udu}!IkdjV8}(LXNHG30AIe1I#}jbhXFMc>-+tra=OHB*jpnxjDaIL- zh;qpIBb|&KHd@$VrW=n_M?S;&!c%}F#@JKHmuc*$MgOSL^a7aK#&2j}oMU`E2U4!_ zJcT}PoTL+uJmU+rn?Gs%h~~jl#y_NxP8;W&5xT(GM=kt9V|_CGijA4HjW032`7uUa zYTWDz_cCMkE-1^5>!`I_VO;z@r1Qp7`atJ`vEmNgD~&H)M(8Tz*Eir$V;pdXvexML zDJYkW^;C}38J)c0S8sG!2-_87F7-pM8lRgDziUQg3PLv;Pks;Eb>qx+aJXqK@rBf8 ztUHaE?Zze_NFBzLRQ+}u18LLLZ7kmnxNY><2<07PUJmm07#Gv5(QC|KgU|y;?+r*a zXcSW+c-PoK57Cful8$wTjfd%>y>IMVj0_Kq&t8Rc)cDVzkj9K%^lOeAN2p+(F#1vR z;j!^h3mhhmPf=AeWsISov z1b5&UZE8(K%)O?8pO7KO)JC&Ltf@&4WrFDdwe1p3Wp6^-XNr0cu-_C&yTJpdyl zFwMY!PhU0-EP-^x^x|GnnoKNOBAZP+XeDVe@o4AWX8PuHNbRQFU4RZ#HLXsard^qE z?>4Qi9dOUys9MJ2jr>n0mnTExHr; zJd^s7=)PwLouEGQ?DIi}3D3;K03R<0s=a-^svf{$tJk_^p!j)xNDD)d*PN%}x5KOS zW!QFk*(6}@_9~#J;U2H!w9yRr`Xe8d7_ZDfV2kzonmz-K^ZJqYc=29)d_mdg^#whc z`@L3o0SV7laOk?-u8lY$&1qtW`mcFhI`rTEt+($c)d(j-c_%}eV|rZ+O}C zur+zDreC_*>)du^zv-3!3Y2YL$Ic*8yVoD|F;s__A_&qguV3it>Gn#j2lKX96>S*r zc+H{Zv(M{Is(1Unx=1CoG8Tk&F{VS0# z$=pqKYqEKs67Gl0K_yTgHis8NN;NB9hC`b9W!l6XG1t+Na;Dk&|DUs%XM6)?mifIH zgw8RyE`pS6KKK{>j+;B_Lxw!_x7~0!X^zW8lvC!n2u_<96yw4Q%pGH(oG~Xl!J*i^ zpa9Aea}DiwOU=LbLON^aZ->J<^MOc673R075qaL+zXnicex5F~+I*7UxQph1{YX?} zuGs-wo%wS*iK#cAo(-wN+)I1=%jQ(NpV!Pc`eAD{H+=+$>*hpSG;Ww%UIV4YJVG7o zR`W*cRo*mzPVZ)$dA144PV;wE40V}DsO@^oyu2RJZ7!$#*<=3VBiMS)mU`TRKJ#X( zn)}TqK7hOC%ImNVneWonJZx6j03&7<-OmT+AE?M5HSZfjzA^LWDoEpIGu_WAb2-(m z)8^2V$lz@`y%RPc%RwjDd@VD`=5Hxo1zUiH_XDJDmhB$^0xc^-!Q5^+l7kGvmK9Wx zhgeFcaJ8Y9*)(m3S^j(m%AJ;Q`gnDZW!HQ#!!5zIFhp45Z$TMpsXGcvlqJRo`C=>u zbWRd$IY_O}I7`VXK)mG%Eg-=%x)`DNTkO372P`Y;^f<|Kc{8MBi{DRxgO-1(|8m&E z`G1{dxk+z8n&pq@FwS(#7Wy4BEQ?~`chs_hJ`K*YjMHy>%<_>OkZqYqKSz#5VSz2r zQb!L%zD0Ej4ks*Kzd?D@l0}zt%F@^dheFE$ox~JbA|FF}#mOR=`T(P**vG`TXi?p0wx6GrXh8vbS)Jt!&FxP|9Y?&@Vh8Bw_ zeM-<~;Zw7t-LjdQBpnuq*P5F8+S(S4D0{7T9gt$IQ%`{sYduEaNW@uF)`6L5)h5EW&+6<5=6>t5Nl+fJ zo~PDFl68+1Qi}C-0Vs#8tLTLBu$A>8Y^m07e}FB`%BQvQh&8(jluYaJD%g%%Z_u{@ zS=OB=F~DQiV^lonT63xCbljR-30t0ZO)Ql8R{JXWov?b)QgGV3iN3-pu)b#mv(Wk` zAIc)@<{fZ2V`XK+R%$J~3MjKy(N|^V);m-eoV8ljfOFO$s^BkJU;G~KmDc{H$X;dr z)fvoct8p_Z7p=27kSyNyzXL8?WpoR!S(6R|8m<3Qops&1 zCJonq!}<%&3{BQ_I*4nxzCfGv4(s2CVC%F#^*-FYtPj5h<(5_VC9>bK{+0+zkG1hM zpw~J|jn+PE;94;It@k3qylYLRDsRXdMC<#o)msJSh?P&9^LtiB50sye1(ZED z6YWgHZE3F~bcAgg9au!#=FLRRy|(wM2N7e-q`gzDZ9bmpr{ipU2B3_$Euf-ppRI+K z`TaH_{Q=PdTm5HHCfR;}0#TA}zb%K~AzNn_l!tA@^lGQt;^?-f*=A8oA>Gy)1Y4#p zn9lf)+9dO#%(4~hpgd+fL@n-Y+p?daJZ=+yh(vj|#?^4oxB0FE<%F#?4v9|MWKV!u zU^`4ZqC%VEXGlf1k*6V@vDMs$d$FxL1yY%<)(XFJ+gBNo&e}q0dOBz8-3_V2R!iNA zO4}%v?p3zBpW#<+o1m{ZF51>-L#nZTKpoFITQ@x@^|s2Dur=5oP-FM9Ev_ADuh^=o z`fao&mwz_79z?+_v?+3b@7f8T=OxjU!6H!dL0n+`jN%YS;uV45g2Sb}a1v9|zYR z*M!-GTUTqBt+uwcwzXQTwzYfO?1Vse2mwOKAdH02Y3)$E0Fk8vipo$K$`V1AG6k8+ z5^x|YAjou!3}q?bbKhV0yYbw;N#1dH?+XzSZfE$=@3(_7?`sGn7=NUL+sW8|4wkzZ z<+O=MG92jy+RaEC!DonKXk6ernvwDfgfWbUiy*NKyC_)hW0cZ0L>%LcH=M;YKKmD5 z5*T0q1(L`}P6GTO!;zBbWJbppP*|MNB^JXmi*cwH^}`-hC} zRR}c6xIt;f6k|Va&C`q*D1&&!V9=0!nZFR+kC{Yiwm;K_ngLswgH-niGT*F5*dXSn zh42#0JVULP5ax6Ku-wjU$pdZ&^9)@^g)!S{`weHlNWGF>%q_FPMKTvrS8O-)8TwK8 zFkSv%u`|U~_{A_6RKhZrdF3IT?PGc_0~g2K_!V^V%snqdn85t~Cvb_(P&$^9n5o}j zNXg9C4#H;&b4&zXDzo|@=+c=Zbj%-NezXOFGMJYsami#Zp+7asW*(yf<}l6oAk1Y3 z&>oV`qyCD#0>opq?sA|6i5s6 z{BexsEVD}szy;>_lxDXwW9ZKZFEZbv8>2SnYa8J63UdLvYjfL~TaqE{U|yolqm%h& z1_s~FOrZf@W4=OHMLo>5bRzUJKc{x>0MnJevq9$mDgdrC-+BXIBg~k2AfwC*${EI(8|a2{oOx?M$OQ9Ks(L1wKHeD8 z6!VoI;N>w>TnOC^vwalAm-WGY5I>gEA0|Pp7oUeoFl$vSoQ1H&n?XWZNk)(ztUc63 z4`YSB4=$W_j23JJ>rJ|2k7PYZOLRAD)m!kghvh+ix4o=4XfKapWqbxT5%kmt>N6BM7N$2e`7C#T9fVFcYNFhrT3wROB zi?ZKh)_y7@N?B`ZFE3-+#K7bvYl7xdIV+L!i7M6)w7*odT50Onur|{r$SGDhy#c9X zo$E!sde%q-NCWHivoL97Jsv@XW|o%?e73Mc`oW!LeYgb9&awWXb=%6CPiOc=*00oF zY-6EijO~dfqGYI@Uxl6?*i^RtBn$n8!R@pL2t4a#KQ6p%adlvUDl#w;O?=ImtlKiJ-ZqM9AP!S4csWJ z-v=gRtT|I44_K{~+D@>VN}-!%-F^gaid92bwbQJLX91sKEp)>Gec5AS(D|{;Tfq6V zTUJB2mHn6=N(HjB=ok!QFHc90VcEmqYOTUy&(v$53|oXflFsUw;$XQ_OH|x%U~~~`;{#A zo_e^>X1n!+S&3;%5pY`n7G=&@3J1r14vabw-JHrlh0HBE- zLbK;A+nY+~b8May0O#4i9|pO=jxB+(m3^ZZ+$Huh4TgJ}&HezwEA0K$s%~d*ssp@( zJ#PtocCiOeLfFlYdky3o`#9CNJ?xLu0qiNR&kOAa8}Lv@eZ8TaHKS$YdL=TFsb9L zI{>bplTGcg2F`;62-L_qLMx}4^B&E?7Eas85T51Cy$bFeCzN`J=Q;LN8(!qZGeO!o ze!pT6mpB_J%e%~pT@I5goJ?9rot)33Fo>(1!>d5LI9;^2c5|Mj?e`kzT@S$fIE~Ao z>*tgVLN~xEq%CNW<4g$mhI_fDbs$mP4}O4UG&e015n{OSRKRjS z_i7}#1Kdp+h!DpuHh_!gdguU8;3nJ#ImC^jy(fv=SOk+~?jfoTQ@Bj(j-+xcUIQSL zJ45-)QLg?9xGZkO1aR5h3*46EjVqyseh=3z z6~cb5nCg`Q?q3QFX^{KEMv&{=6iPgAa7Ayx*=?@lE{yCBcLh~vce$5bVRDb#vl+M{ z?uYBZjc{Y>LC`4o@5Qhj5%)VO zd_Lyp1;fOTClrA5=k2F`VhistIxquxf4IPME3cg%od@#*p24U?c;$((4CP(Eh3MOO z`#(Y0?YyJD(1r7+-hwWI$J-9!PF^fMGuXvTvj-Q+8>Ob`Uf!BB5JvI5-vSrSGtdl) z;XV8uxLDqcM(7UkdMLYy+c>3MoGI+IzfXn1PyArOC@)!vSl*POL9ZYh0d0#`A$NP#d0*>+C zQo!|bUV0F?d|pfs;6=O{>WLTg?5Ph{!dr*jZ|(_REX|%$-cib5%6Z%W1y{k#n7eEYJWHLdKn-s zycybN&hl=~hj(cSba#2b%!B29-hV8Z4D$xc5O0L{+*y!OUdKF;F{P~Gga&O_Y6W}F~pI!)I z5dVoWkYN7&J_tkjwLc(GD8GP`wg|ol?WQ~VNp$S);w$W-i{vk+x_>W!g#Lg%ivKj7 z_R;*={V<8)|9u=}Ki?++J`eC!Kf*GO|1q_$;`u{4AP4!5bl-o7-*N)FB>o%!0g%j} zo`-m8{MjYY9p-cL;5wb}K}+oj|GDoG;V3`Z2ri4yq{K6uU$hB;9DY2N5y$vz=@dQA z-{1q2e11d+ga!PK*FcK-Mf44p@V`6>?gW1|9cQKd^1}#Q&i{G?gcbbX=m4wa|FH&K z75`(paX-Zme+t6W{7tmtYWZt^LfATf*IICm{Nt&BpW!Q?0HBFK=Pz*0{KP)!&hc9) zvpUcJ?|Fp1z%QiDzm*?+8J3s$g$v;2GJjJeEU)kf9s<|Sf8`={SNW|C&~@>@`T@Fb zz84*J*Z9xG!K9C`Sr0G${Iq?r9N^ECgADS&)FRMLehOU;-{S9~9pyHE^JgG;_(9Yf zAL8FW58Zu!>1L2&eq$k=jqv$bpnJf#{~cZ)@*Nhy^*FzV4%!KRKGhb}{MV_fd&K{I z79u?6|4a?`8U7**O#B6!GjO&=;9CkW0fL@pa9ah}D4!1&+@K+a2(qag6Dnv)gUL3* z+tg$Z6YSgqUAW-gI#@;sgpCmH6lmT>pxuHVJuLSKE>R-5S5T}4JWB8?Z5OeEU|Qk( z1c9GJw_otU6J8Do?y&(+5M0~^U7{dU1;9Z;asaqPf&iMIDT1?q9TgP*1wfYIN->1Ff*UD}yAOdY77YCgu0*i-37C`#M)M&&DfpS{;&MR`b!{sI$NmAXTEJWeU5y}72EZvn zP#ef;!9}{1s27A$e%&B&rcc`_*hin}jNs%J4C%b!>-WH25InYr&sM?0o4{QZ@csnX zA()>H*PVh>G#Rc6G?a353ErnYt6T6aC9J)I^as%O3C1b+?iZZ@0^ES$?+H-^3$<&tq_p1>v)xn-MHp1)m`{&c6c? zYLl}TCfjU;=`h)D6VrnMhT9A@gNv|9rc`C8%_mQS?6OhOIkv~<0i~~dZO+((MA4S2H+&x8mqHnr2>&f0{2gR!*Ptf0=&C7bu$fV*sSnqI$M zu^FIEyxk`6G~m~4BB@C0vDrKexL%u$q4=`;Y}Q30?4S)V5xDC%5%tjBuz8NU95-$L zJqj{p^9dbN_iYwGgypc!cjtf`v3ciPkWrf$YGF*;^wVKFWwY!70!`aQq3JRAkh!)Ktd=}C+%NO+ApSfN7MdobB1yh0nxPT_0kVX{joJpyNu z!lCa$b_HKOMTP4B>U zu5d0jf%1gQ&w)E8{DDrA0-+0aKnjJMv!E*y-k%TG#loOnASJ?gC~qwjzC=agN#U9} z;L3$Z>4&QjW>YJ$Qm8lsc&%^+oj`TMz4R^B3x8*WYY>jPfiwy;sRz+4bX|wBv+{0uCqOO=^>m%rCj9LRB3u$iMuA)w7SPXsMYu8t!|fJs$p&{# zsHP0QNBAYZKJ68nV_`WU+zVwH>7MXq)ZR>+u=3 z+s+jOu)}sKy*!Gv&6EPL+jibQaC>as?V#Ihdx%c17~4QPwnN7dA<;H=6}%j@T}8WMvaR@MI7_je{|AJrwr(pivNYSKuYfyhtJwu% zmhHe+kZfCjx_imDb-e>zfvtf$3x&2%Qs!7>D_;mwZ2L3a0+-l2&~@wy+hcc+73_IZlq;++V;UNM5whr^ESNH z+4`uVYqs4`0ItQ>k1iK3+PW*iwb>5zK-X!z`U!ZsYAdHww#&9}B?5KZe)|8*4BJM^ z&-!dlp%_`e?Pki^2W(Z}g1cdR_Zr|gZ9jPm&TiS>O$B$`mMsL}p6!-im<-uoFoN8- zU3Uq%VcQD2P#d?sn+D;8?YC4xPukkP58;%pdO5hqw&iy4GGqH`qGh<>&Y$Ms0XwEANSxiP!SESx=Qa&z2klNq0C31o`yWV>-DWFH zlI`-MFr+lQh4eh(u-(#+AxyXHmw+6xJJbT)QM>$Q&}G?;(!rN)cbiVb9J@!9Sryo= z42NZ*-9I}ph$6eYdm%hw=TrkgsomZsAZ2!;3m~kpdz1>U($4K3;8k{BLvVJ=&b=7I z({^X+PcCcio<9Q1Cc95)t8BI_A6Wu#*a5`Ot37FTjo4EuoBa$}XKQw5RR9y$RhT zyTNFX$9A==Fit;_gj!erq6|vfwum;+6b=ymM(Zy~WG}*4f<-H-0Tv<(3IGWe1%$)r z4pG)30K!DQ)S3$yb^H!pglLdfT%>4GK6JZ9qo2ZZkLX{@h4+fgW(Z?MfhusZqP3JR z?-O;=l-e)4`Zk2|qWlSv1d(bToF$6fs26llbm$(0$)Y(i0HlbzsN_x+-K39_Ch|Ol zct=Fc_hFeKT9*Z3rl^+yM@9UfASxGK?VDov_IP4xP$Msz9+gE%Ex z!Ud@l)trK^UgXAru0iwOKdV5IyUIK}?Dg-2s>qF=?FBBG0b@m=W1g-_2M2?%VL!tLUnHi)o8tfdBfn0Vnjke%YS z76^BVpLzy>NHKO9%q;N-v{s_T<+P@w#Y+RKJwsGQ1PXG`v z&bSYFf;fS;l0)LnjUY+l*!>VDi!VF}E=3$ff0maa&Z3hmQ|#;m-BIyQ`p&Y%tQ&Ba zE#9PuNuGG61rd&kk3A39$Hltm0LT}Y-GNDg_(R%Mi^X%OgH<92^OO+ui{GVEVL%*7h0&l` zw*&*cE{>C8NVml2s3N*8j=6xacf`?DY1|e6L^CdFZ8&`pVF$$*;{zejcWBe5R~I$z0N>IwKsK6@WHf630T zpxYu@MX6DML`Wn^Qd$L*V2SJ}a3PY@e_`;UlF~4cZIUipabc2u)b$IOtewP=A|zMo zg~m=vP&jbAB=?>Mw?|^4Z(^^+;EAwN5=A{Mqb0sV=wc)#>tMNG@+m!TIUu=Cjk7q( z^`9Y(myCFWBuI)rhVGE$eKBxJl6N-(mn>QP1Gp5)cXYU=N+fi%oGy8A1>6zITspEc zBz)?QWJ)${1$R{9ya*&mGO-z!xe}!qBu_GDBZhQL@^&pE9G84U)2&eAxD>)7iG}W` zizOTAM=g;I>cO3m{E!cFQnINWq+BBD!vHHJ!W;~#Qlf5!uu4)$13V@9ik`ilmi$Pq z>RO5ZF)ZsO&f5^SUSgnYoimb(CYUryG56!;K&pBs-|()hbz} zgYKea=?VzjB>hi;T$0>-3c_~DBKjFSB(KoJmrhC6Ah@d%Jw5&Ek}RQ)QjesL_MTqJ zR3HF-k_($)*)J)jhW>yg*NWlZko10!KsO~n(lyyF$v$c@+?K2jgzk>y#V>#xl5_+^ zcVBXozL#MMdo9R_WSZ)~QOO0GR zn9N8*K8I^x=|6Oo`$=PI;rUB-R5xywUZNZ&P^zV>HAuShDR9BkO&`J}MB0=GK)AGs z^4$pOD(VF9l$!crvP&xDfJ91%s50Fv{Z0rjN~+@{P_(q0uIyr@%1H=grD-E@eLy<6 z3?qw^zC$T^ymVLvT!J)(s;opQm+HnO=`TlNk}OS321$`h=nF}eKD!5&Y0`hGF?dAk z?f{Y@-7bSJQ|erR4}Da6c?aNG(pmi=xzfi+K=Pzz+n_rp-I)&VxK#Q&0Qu6})DA0> zI@2*9z+IB|J_L7Jy69P$bV$9a^y-v;LX+sKR88Aqmy~}1q+2?h zdR@KJ(+d%{Px`$F2GK8Fy$!+vX)`ss2BjnPP27~$xx@7>X-^<@x24xKaD7MmJvRBseJ4lr5 z9cr#b%id&w?2|Q7XMMkHVhOkdvT^~u#L0T-)Q*?kqt$;Llr6IZxhmWA2go(qXL|wYk!|*c>t5NDuHgD)>#3>MFZ+gywCl2)l&s&7eUOVl zH)VZBkXy1dr7*cI>v#=bhGma~@r8`YG&KNB$YwqPnUvK~{^=`spb70K-|-nZfB7p^ zXl{`&TnJpCeEJ{gg5*6X5FuFpv=Sslewn_I?eY(2!OISLq!c7fo?Z@NxO@d0@LlpB zAA>~72kDU7Eic^$vPYgpFEpa%%jj5&kvDEdgjl)g2H^YTAIHIUoP0jbta$n2+khv? zU!t44MERc;AW8C8+9Q+YBh->jk=Ii}l`0qH!!ljobriZI@*UK^$&e?rKr-cbvY^YB z+seV^$Sw54<;oXQLqAWxnzrqH`FcB$0{PZY;j>V#poLx}54jH4C**D~0aq&5--k(= zyi|!%pOn|qtE5W#EA;NEN6Eo75m`mHUnWa8bU3_K-IDu@7K*MP9HBT)TWj z0EW~dS8f2VQ{MU^xNdoFA-HSuKMTP1$eC1g^~z6`A>M$z(g5M0TuBr2x?K1Vyxfp8 zB>>!(-}Z;)9l7FfguN^Oh~5_7lgH7aKP-Q_7nURPqr1V4%2#y&Fed--I)vkL{a4^7 zr+rc%UL! z1j``Bmy{rfDq_BeaGPQdogLd14qYHS6in)MMJNX8i`=Qm9)+`Aif?EOid6jlFCy$! zc$a~TQnaw(ELxFDw@ERINvg8;D;nvnI-r;-NAx(wqd<^&MHC&o2NlM-2zy8|K$9p* zQBAWaSussTMVg|NI*ErBhbRqASNxlbu^dr6N`UUDA|VMROObgQ5waCku?U-^*hMq> zm|~PNkK>A_MEJ~C_%*?#K(Y5X2#Xcp(?MIJ_>K~u6N;Wl_$*bJ+rd>SLg`$oR^&bj zK$9YJ7?#b7E_(0XqByID?yO?VJovnzxIPVCtKu@X5HBkJ`Uoa%iU(AHUr~Iq8p3u( z8x=nt3fo_S>r`y|4H3E(@0wwGO`%!@(xY&o-K|&gIS-ZtikCNm8&n*ieB!#IXFhN@ z6node=RJjV8-zoOdYWMO6~==g!-@lxEQ~4cR>0WyIlQv4NXX%#8boYQ6H>C*^KIS?g{05DiKdAXX$|}SI%*U>k4HefnJRsKNdN}aNY-oDl=gE$~9N;6fhXO)+z^L0+?B>*|Eym1ooE-2TT z5U5Q#_#=E?Qa(?`>t*FXlq6nJzW)J)?aJ4vpt`CoSdEc&DdQ?2>{f0gFV~dj0O)#@ z|59VHU-{ZikOAfQN{~UN)(Xq(N&|H@Zz%QD;km86{RPM!W#uq*ca_f6FSw^nqq<{A zX*mm@Bg*0z03TKUcpjEx%D}e~_JOjGo^(7^zD?ohW&=L0+)fvbkCe~O z2JW#k&kZI4_A9yYxz%1uTUVg{7)`z)`+FwfcG%;t9ka*&P_E`s@i?C->b+*_3 zExKNdvX7@0)B*d{_aTh4XHdcuZ-03V@C18H9CV5Hw}j9gwATp%KVEbpr5QdjTCidG_18061npME8Hk?eCiq zFW>$t$_ESVm;VM`sr^dIQOfLJ4FPx3KJ`23YV4nofSj^d{R7vH_SdRF&e%J;B0`hB z>;%XK`@h)$wA#;~5BNpUAa%1+{AA&rv52F6dL;IU7M3}TUQ3^0+zxsO&V%q-iwE#S_ z|LGuvzN#oXF#S}nltlTfzNMsXi^`oc>Oj>}%87zh`{>3fSk>bW*C8sAD|FjcC%1#! zp|TB!Nto(gx=IOGjZ;FtOSOtNq)3&DYV_Tzcc_5dqdG^u^k~)JbdJTSdY%Ipt16<& zzE72Q1D1&@JNrQmCr?102DTBV|PSgmR=H5=Kj!Hg=OYD!;++p9tR90aGJ^LLn`8;&gwycB%)0Ee9dtCUadK^+RN(4jjPCPfY|w11v(u%(;HQimtc0Z`>I9s!eT zhYb!OH4gr?Ii7OR(DVB`hpjJxt9N+I2xl!0|7`&|>+q-+qdw=bkha+K4!=^>bJ4+h z0`N8m_C*Lg9ad5rdez}?x?JyaP(=dJ?a=x>$biG?-w<}t;Zi1?-Eml72kx%Jssvb$ zI)wa(agI3*y$Wu|;SOC?`KsT00HL4yS_mxt)o;E4vQ_=$S-=C;F(HT-q_)ycQ?UBN zFm&70f6`>%uFf6+*`byv!7@x;UWe#A)$Kn*xJ%s=f(Vi7S3Uz^xB5xi%cIoG=s<~9 zf9nd%81)t(gpE}%6##xf-AHLuoZ4>^x_EWQ5G)had;W#+kox>Ccu7(ZdTjth zm!kGQ4BcUMQ!Xsi)qhj*b41PG3}J@)G<7_4)fI~%%u}=Ij60@wpiA=O>Lm>5^3_); z@hnnrJq%~X>Sy+Yl&DYpL3cv^(dV!%Rp*2NSFZk-j?W5p{C5yms%xkfU!~qbm0Pvi ziTZV?)x1|>S*yNB1zerF+a9`l^)=eo8q}|T1k$ATTDhp+_z3Veb>eB5TvA`BuF+-nOM%dJs0*h7=v1Ge^Y5zq0p$~2>T@*^ zcB}Uuhe@wGoz_F2`qV>wlzz3?6Yv3b8r>BPsvrHoRi+N4*|HLRXbC-aEVJ1bIHnfnf{d#lb-~Moy2k+cq`KP~CR6IB zPeG>D`h$q>@Ax#$vn`Gbx4<&Maq%g9qOFck(alewV+rN+A&#dyVHxV^d>*)Mj^ENj zwB2z=h6p)l z>5e_tv7KHF?sI%I8H0#(eCYw=#XHX8!ZN{exded{9UE!B9CWO9g=Mm161DA894CGP zm+II{U7R$>z{4Pi9gor3k>R+wAAn59>Sqw)sN*}>i{@rIKDh#}vmNVefXj0XqIGo4 z@y9YaJMOs509?M~0lF+LaJ(=L%VNi0{o%93@xV?9PdILR6@XI57Ail=9GO(oR5*?u z0axiLTMx@B$4f_mt9CpbfCx2?8PpS~b^PQoT-P}+SqHA(aU=a9P=li)2c*$)F1>#_ z=lJ#&0M0uupc|tLj$hEB(duXv!DqW;2AvNbj=pXnJ&xY=VzAfIpURdSj`irq&AsWk zObu?xaaS?OeaHD!xjl4rd%K7eJQ({L@k1UWsE3fI9-#m&%#IQ`fR%TT8u{{q?OR772e?M`mq;C46(>DUc( zdSN5tg*#a&OW)&UN0sSbCn4SAMLEse2WQbvZnV3_IOS5Z9_z%QCshefX;jmMm8RN`w`X~!rrjyYCUAEH=5lD_x z**XZ1IbEi|B0TOi`y~iVoSq)TSWY<2KMStZ>D2}BS>_bT23O(490s7$Y4$T1S(VeV zd{|aHeM{NeX(wkoH*1}8Dp7! zf_v!1pjkKWR7p==rks9y174<`th9V*oNhe^&evHJ4dE8&Tw1;X&O?;VggXC6<<2(e zT001LI(K~!FT0%A)Bjb8bpCZ7aJ!vfIRP(G&fBOCh<3jJ1T15m1(b2dI(PYl9B_WE z5V|<$uSNifcUDmqlHe?DfbNj=$CL-=v=h~ zx)SGADG;7;Ui3alsdE%HcFUZXz6ICS&d<>IQsZnq1;8n1d&){qJ0~6mSMU6AD@cR$ zPmb`?=xn!f%-*doSbly+%rNfz@0+UW>A->7Ez0PeV z;QE|jxD0aB*`*Sex10;NfV=N}u^WJ4=a;EeA93DF?Zr`Nn>uh~&gxmPeBivFx(*MW zlO8}f?mR_JnF;5ktH4b<&l(4ra=uTcm!D?#+Zc<#<}f9*!J33{e6SGB(^`;lO%t7| z5t;?vAbU0S|F4fUXZzsnfJT@Kc$}ua2f9SfQVB+VP~*D-&XP43sbEaeyx#@gVa;8- zcu&_H>I2Et)YZfFQB5TM(m9%Tx=78{d^8);k855mfG%J2nG%*onx3sNDb_^%zXsC8 zQj@t%6GHE1PHGY;gDBSoTfkLm&d`rqtr2s9tI;gY0Pd7VKz}z;r`aJ#gnG@V)WvDg zOxIv!jhX>Zm^5p2l#aA$EcbystKsXwozu)Z1YN6UlFs*w8vl6U+BEOc26#zRp8|Nh z=2g1x>d@$t5usDldk^rdnhmQVyr#K)9=IOO{y30cO#p3xeVUOw&<$#$95L$anosD^ zxS=u7z06I``{zK0Gz<7}c3-oD8v4VUp*1iW(Hy3%WK@$zjq8V+#qVNdykrvFMcl5+hOAG^8PUhx48Jw`bGiHzxNw)k#juQUS+f%+ zdtJVN8_uF!`U*gzUHqv$j&aFr$B<%OV(83CaEYg_E74`I6NCp{y6M{SkjnweZIWE7 z=(DH0ENg-5BQE8(5N5dSrt>J%rH}!V=kg@=Cyu%NL3cf6E?)G(PP&|=?Wx>_e-gL~ zm)U6uTj|22>a514_$PQd03RUj=cg@J&dce(W$a2H(C!$4YH+G!8D=u$?FSwL$syGYMp4?-lx6tBZP6 zYrp>mq(JLi3_zi_if;9av@3su$w}=Qs;oZbh;32(l+kKH_@!UUgk^^|x*EDpZ59>vSG9i@K-Z<+;{;)k z*0BZfUab$6G=194InecM7cYgE0qp?2OSr9FOPT5&ZQB_D?rPbyVRBDfLKniR3y{lTso)zF2wmQg<>)OEN7fNidQ-{50z zcO8BSCgH9{wB1LzZln@pr>iaPt-D-LF9L~leS8RkVqCwZ!adfNMdg2jYXQ}biLUu{ z*_P^>ybva7u1y!f<+@%7gqJ+mxpZH3%+)avfsVW0{Rdp3Yw~tj7P-b!hE(jj?F>kX zE9Vv9%3RM=TjZqc3y~O7xhsRlQsLTh8l>8FSvgE)Qsu9k*`V`{}Ip=!v5V-TM3^N9C(bfAEn6$ZOJ_2{i z_37sUzwEk#zSa)cwecXGuBL4OTy-s_E>4%L!xD_8$Mpre3GH?LEe)j4)$K=k>397! z4Djo&4=Z4D!}TnsF*jY$)WYPJYcx5#>nftO{+_GlUvNXN4xhm1eb=8u5nHCK5(t1srb@grd+*~z)icpPmAP{>&`}SzPg3f67thEodm#N7eg)5 zExHA*h!ChdwiMBWbgL;T4c2`&2f7fQh2A7?*D)wH+M(;CA2m$(khc49-P}<4+@(8P z4tS*QV|Q5Y)}5h?u|2vo9S9q(%jSWL(J@|xNvtmMCy;%*nsIoE)9wENT)ZxG1||u* zuNMQJsGFgNMv|_RlCNalJ5&y&=-!$EN!3+TMxCy+&;XCQCXUR>%GoT%GR2uQ1Mf-2`P%4Z4dCPQALfXuI#zMbc^5uk%|8X9K!JRBsOIej(va zU9Sk_madI@)VFni{s8zL-G_7r+|_+UN63BMej$Xzx}{8TBf3c1>qd3)zQB#?PFbNF z*M*dWOz1XK_k2<}K~>h2ZVBbP(>iMvoXzN#=K$cVUqWeQyQUPPFGAj_3j=J z?$-Zt7h~C@zovw4uYTKUj5GCp3FQlA3S-;H+K#G334}^#HZLR>M>s@G~9MLz-2g%TP(0QAw z|6?bHl&ue(3zDN3(%^ITG5^9#p5Dd|+%f%V5}Xz2=TVkdsJ~4Siu8k2cNFVo^!t_Q z{Zm28^f^>$p49((3-QYJV^mXC=#TvXQmNlJhOjkyp)1HKy;}&poYpr{1y-xCqi?=W zAND&)qkc;g$Qgap9*`#eoP{uH*3Y38*P@U70Nh1=DYY}(^cURV`jXy08|1RS_!|hX z=-sI0)u|890^q8iM>}She$^P_b?ZH^g1e^ws~?tq`nmMI^y`CmLN}oQ{(F3eL4CLu zxa;~jI?8Y93urI6t+$~g`Hp@kJ*>N{FX#cer>{*1d|3arGvFioKaW8;s^3bf*qFXK z4%`F1E!epe`b9=?lls{IpqtXODC3;gPt)!ABmIxT2i0CpJ^wEp%Oe)59JUc)RsoJAR&|Aa}jVbcnb7{mGjc-e38UJ1(shDFqUjWgs= zfr~c`yMaqEJVQIfA;W6QMw1M0#DF9l7O_B547XoGpj5-DNq9*&sA-8FF?i`9%rG=W zfMgnMnlZAYhTlA4l4EG`hDoj=;sW4#hTF7t9W%U0y^`aGR1HiD4PVl=o-o+$f#peq+eaYfhIy1#Rv1>%)3!=O)F}X}4CiQRpEBf7B5~T#aRer{ zhPO)~tTUV$16OZYO4-F3Lw-4MO@`0E#5kJ`8Y-b$4EuKjch*ou$@2xnHhRI=YViCD zfQyFbf&geU#Qz0y$#9J}_;$mql5;#)9iIY!||$$1qBXS+Aj+ zx{Q5>5G$PZ8)g>5WWeyD3jj9^F>k{1rr}C4!rn5t(A2+e$e;_SJBDk?AR~r9k`ZXs zaD!&~m?7?KID25op#?i_SV)QIBg3aH@bcIouZHUx!w+UIEvj4x7N z5Ny2a3zHCI%Lm{>ji-Duh;7E7OF*_8>kDAH!x*pyCSk_!he5)PF0}|7VchW-0DFyQ z0z?_BlVKTcOxTJ*F~)Yv&ti>Pbg8?~IByLA`;BL0fFCg4{R0DxGg<^Ni8spk0G?oM zUk8&!Bl8Ztq#8r)V3}r|7X!<~Mq8S#=|;b2!DSksrefr%(U#!^{o_+%+ zCyf=<6E8O=)4o(?{E|8n)y90<8ETBPZ6G{le8C?+PaCJG{HQf9^aEFC)U<-DH$F?> zQiJiwZSc})yiS#OvvJNSxEA9FuYfyie1UR}bH=M2xIS-OHUV_^=H=2aSJ!4QF?ZSAT_< zyT-w10k~(pPrLq*aRW`$`^FWsVL5EnCV?9_nrUrL82@+{1DrH|@g#gs8N*7zO&jHu zbU!j?`U3FS`13Tl8RJSi4Sn5MhY{A#?RmO}@OSH=11#9B;Tbp!aT{*|33c1{C4}4D ze3pQOxxKg!xNx_CQ~>t4&8NoFUN^oRy8Uin3*qd5+dkUz4!M0!ZNenCee_`FsN2Aw z;IiCmUV~+}oBMO%a@-zK9hd7io4&e2w?-{=MQ)20VerLn%^yKn;#L`icqiP-sOekj zc980hDz_{Fgw<~M8bNB@TxpyQZc}Z5H@aP{2RY+*T@K6hZVq!{a=~rOeZ*^Z+e@c* zyW5)G&~>;4(WpD!Z0JYrb?c&xtj`UZ3f8UL!Xwb#a`UA#;J%w1?UBQ7nwiEu?q;ImV8ZP#P2m~0yZ^w_*R-x4#LrYhmnZ(F ziVEPin*K_{kOEEralr+djPv0o*c5vcfwr04sqouwI`jkpJ4`K4!)KVOf`0I5lbI6h z7*j2^(PB+JY98$~y&MZ?iKcdXo^a5#n5vgUrfa7_l1%<|)Fqp0!(o|bdY$T(!zMpU z0n$zB^nB)sX`?H28K#mY7)zF^RRLkPY5jW`OOENiPDIZ&InWb}Jd;Z)g!!iLngJ*< zeV~HtLethla78AclQ1bZsrvyhH8s;cWtpjJ9{?v!wWmPJO*h_vWrgV<`n0D_AG+rgsm5G?~h%;nr-5r+M9CI}FymXkJq1D)FlJG#Tn!e}+pvx3YtE$`d^95M;nl4b? z(P#RVvY>ubG7VzDRP_ks95k)%1G!_W`VQl~YdTv8?w%?06*wC*i4S394@{3c0eEP7 zrW(3&({HmuCQOz}2&YZ`F(8jjJS_lQ+z-8o2m$Wz(ns0q{xYQif$sJZFbQ#QehNbh zb&v4`Ji`5YDacOuWuegRa{ti;K%~1fO@_Vh8|eZl%6$i26&-NDL`|nS_ivX29`C*u z^JZ>>`|14{Zle2t)F(RVzWpJ%L+zn6;vwz(I729rzf^D+Ur>aL1}WtV&XJqWwqePl4X=AKmpz@U4IJ4~*-2k_wK zhP#^=$W8ZBYPj8TpFIF_*FBV)5BJ=+9DwDJ`_6;r{C5b`JuXohf5c-mRYVycf3AWq%VSMDNVbRLuOK-d zhjU<=>+#8tu*~ytdJ>lT9+O)^3Ovp#5U9|@Kr^ez<3JvS#U9Du0Z{I7{WAb6JOb`Q zSLqRB!f>lR94JSr_SjAfug2rgs}MGLFlaYz^f>7R-5C#o9=IkCJNm_%J&g1vpYuov z1b5z}@CwKUkGZrqTRjXb5bvUghH{$@58hk|J3TU%Vn|m#{DXn(@~GiK*YEM?k01jc zbExe)=+Q~ft*(1~dmPSgdF0XE#BGmmO5}$<4lM^6@knrhaMVNDfFX@}a0Y-I_fSwJ zJmK*rr8qMl*?q9|^?Y+Ly!d&B1;NtaQ&9=B)$^r?7+Ij_0M#qoJ^#%H+2MJ)3M9<) z>uHQ7-18_+ja{CDV)%^ooc$@d7|*Mfa2@NZTnR40b2H@{iJm!TaH*cQcM&hmbIbYM2n}}N6?-1^rm`Z(Fu*&Wzf&*ou4l}8z(+mv@4@w$ zXV+1fJn)>M1nZ&aM@GQMJuOqPeC%0!0Kys1V){f|y_D+^DA21l8Sw31Mr!Qt@aq2q zx=63tqtNa4n!qtSH`XijMVRdK>Y|(8M6V4_5FYdzq`WoF>nED?hrNC-0X)m=g*7nA z_Nw|5T)x-nYlvRp;g_i9*%m;)|@ zY&VZk|8s|VtsY#MIpk}Ygqy<>0pDe|c@4rya~ZWBcbipI9`7-)r~YoVSw)p;jQRd{ zM2Iyj>1^C*R?-0-XTBYULByMbW&lqxpM4)(qWLWm;7R5RB`lN8`Wq0Ym_=cLr<%ok zAxt-iya{r|JSPEOGR%v4&}Etfw*r@KHmktpn7Q^Kx#l1yO!CZL#{tMUms2;Uz?_~7 zU7@*wE_{p3-#!K539~(2)|8rm>VmM${E*Ivlja5G7+Iyc&I??XSwpFNwfPrH)@#fc z=pwbj980@mqdD|daA(W`Z@{F$zthr?Cu~XS>1jzWEPY z)5GS6l%2BdYmzzdlQ_m<)27=6hF(CJs|#; z8R{%-u~gCvjX=wX^f7}hm9%_=Ev<8*3$aYz1}@a{;6+5(VF{#HA7Pd>%Co{Pee|aQ z5td(UVY$V`_FGD6tsJme zeg`hj^1cov-ZF6ufs!pTG{6)~eK+8#mVfAlTbd=C`m~2F*Jv-uvP3L}FxxUO0)QOL zp~C>=T9Rm=&$GNtYwVciLpS&=w*0XV!V*gbo$nQv)#Vs`rRAtSNTa2U^7%8Cmyg1- z$?`Wc~fUpKk`Y)BBGSkX_!t4}(N{tKNX+UhkE3eG%n-V+vnEw6}FP zbTQs4It^pJ=T`!Lz}svOlQ{1=nb5_1hfrT5!TXdexJ2(wv_zA<3+Q=lviHXva4Fs! zsB}*Cp8F9} zfp^P3aE0E3gBqWK*0ppR23enf0)Sv^yC;MpR$posZ?|eFaoJ(rL^W)f)nNjb;nv#A zu-s+6P0tJ>t(#I{x!bBTLb%5oMu$|i^#U#Q7_0U(o51XpYIT?kx*_4fvlM(Z{@TF+R^ zJpgaAs_(+}1?#gt(6w6M{}$Xu>tpH{v{{c(zwVON!2s9oR$&cHI;;)vLDy+b+6Bw2 z)(Bb_UDo3p5wFK;vjvvDRy!+%ebza3FzL5GMayEqIy)H7Zdhm0wZKj5UsUznvaX=9 z+_rv2Y2h8~0-C}@*5db}yKgN|gqLCKFUtWRu@=(qHfjyL4BbQPJ9LFMZhi3*;1gCU zwfiQmHd4T+th?y#)?=%v3&I)ek3-;mecC85_w(67dx*b}g9AvgPwuCHhxjb|9=cGU zU9||b&F2+*BD&ot=O(ytpUy5=M)(v(!epn<`4^$v<T$j`FSD85uf?bB2b1;9__-JJ}fHIj`~FZgh6Ea%%uiJhK7E~-?M=Xd6RusjK9ec-$6-7lsv4Fk%{h#NQd(ORg z@cn+@=TG*|z31Fhp7ZqQIp_YI4DiQiJhKv)CuWSi8Dn{NMramZe{RMK3g54uG4~AI zJwIbIA<;`SrtXN#%QMb86m7mfW6amMyfI_!iKz1CjA_epSvO-M4Qc(1Cy6#U%(&rZ zwDQ4>+6vVCa7OFxxNMp+pXBZ48TC{=ct7m9_n6lVbgPf91Qld!zq1#EIVQ-)ju+-tOP-0nBK9 z|Lg=FZs?yvO#Gexcf)w$z5d5IbklzhiI)%hU(ciL!~We#HTtxF>c^<^S^r&YarwM| zF{wXa^zYJ*yD$6C+#f^wrvHWr?!N8sc@{5x*FWb#Jp8_Y-+y9cM`nA8ERM;}{vR|w zJDWHQ50B06OJRZIvO7&cN5^N+qA>i4**Q<)a#D71XFNPPdk2krZZ^9C@6F4G-bUGJ z+0}=jhtspaAR;*<``BZsa%Q%YBClssFASs2OS6kf*S{jWc6YRLW%jp3aZ9svu0bnT zWxqHbWmjkSdl`4vW@i$DEzkabA3VG+n|=#5ug~^Syzz$Y!fEL5=4>)wBZp~Jc**MEvCpJjhMA1{2K-Su`{zRHdy^W*Dm z;vU=`HE_TKxI22_LE;6+4D3oe(d>am6azbcAbJ_9%o#Yp8jZ~xm`!AV%0Ti?R5@#4 z46)ex1M?@K?EHcI$kJFi@FnGjE*`jl7nCg-xFUw$uN-(IfwH9oi$b_tKCrG1uU|Lt z*J-G7%fRm!p@$U%4^-oF*TCLyq3rH~cYcExRt|Iwps{-f0>oJEA86ecFFY`?`KP#h zaNxd+ad~Lqr=&|gF|adfC94Kf-{S7Yf&ab?mzM^9M`Hfvfx|yUW3LRHH4JyJ4Rj8n zZ0*1UPvY+NftiQk^2We^wRnBQz?U;|d1v5?W6{yO1DBA8b>qOM*#zW)=>)S62S!rn z`=)`9F2}>o18-i1yN?DIO~-p553K(Wn*MCy@fM8i^MPr9!sUyBo@!M2a$rZo)~^O8 zP~`mEf!=FS_T9i?7oyGY2QD9lyCZYoeu~Rcxx3pjq}jRq@@VYXT;-{F@3>r)h~)U( zX0oT}dd26TIJZZG0Qb8|EA#${e^_ZqZ$N)B;xtWoZ0av{#oeMkDz*}1W| zp=?3!FiOrnC$|?VAm``yBl~Y*?)DV!F34Sd1d*3 zcS-Iy#5ga_U0Q+0F3Z)Oi1)6{jU?HzH206=(AZVEPj*I?t8;7az}>Rk?6*;Kd9H6B zF4yHY(crJottTb_hTQb)aCc+wXB0HMC3iSkU@LMroPe6Q=6<#-9^RJQlPsd!b1$z% zWB24vBK*8Jw-a%&`*O?3e|CTFZqo7|${j#MdN}u^-=WGQxqqC6*B{NjMHc20x#Ui$ zvMTo$q3M&kjWnaDaxap(`fTnr^2t4y`}Yh?Wp!?+4{`T=ZpR;?l{LBNh^k)Ay-9-a zwcM;ZxU9{+Opc|ubDvU>V0~`Vr?_m$tvC?~^c$*afbCs38S`KKSlSmx!M55wim z{DJLg?5zCEvvD^+e`ppp&(4o{3jHm}Uwt<&=j1ErqwL)LWt4ezUj8ETT%MmloLJDp ze2~I`7v#4l3|W+)b~JjpF#pFt;^9U4cm9Ki7w7l56GK{@Kkhb^Ey*ADKJG5bUwARP zU7A0Ml;^ARKP4sj>im18sV>WpBMoqQ{vG0c*X7TC9c9<&D=9PXhWx4bqv<>I=gh?A zuKebI;c|EW^S4oDW&W#EQ02b-o7bY1`|~&5js70UfBh%iJ(yoI35`9TUwa*zejg=I0UQpUK}rp@wJkrxDgYmp_(V|Eu$($l`l3f5mKc^iuxiZE^QeV*U% zecXMKU!KF|%lu9=(9u`}3!^DmdO_h;Vo!?- z2a$vJ;=+H(4p>~+nZ((W!k5eO!X<@=|BgXiTIgJbyDJLozQyIrLjBEneQ9CBe7tZ~ z;i9e3%GHIA&rtK)!cRZP!{vpqNZGrtP#`DC^@VNoX!C}`3L4AJh0a<$yroc2y2gsa zhkwL-w-(OdfTnLN45#dyI}39*;qI=&M|m`TcVU|=P-SJ|eA3zPDb)WPy+2gg?Gs!c zE}TJ@{v(BJ_r%?!1!yWzo(sSDAKa}fL`WTZvhY6f-KPpSEJe+y3p@N0O+Qn3dkyYZ z7cTi7syttK{t;YWD4g^%E-x0&rFj2Kg~dnXvZinZsnV|&{)?pAYlX&5=wWT)x(qI_ z7y3@a!*zx0H{kBA!sVn$yj{4BRQ~ma8RO8yhQfT(vo;nwNrQi{@b*SD_I}}aZMb|; z_?|HN!$Ql0sQFQ0Cvt{=TsY!Rlzme8me~ELg(A6cJ}c}>-1N&r-)2<#s_-pg^4Enc z$*B0IkY0+Wzb)KG%>T&2!%6i!YA{N6>d}LHT!p)11{aW)Fnh4#A>5rfxD(maCk?Jk zqLq^exA_Cg<_^}^;d1KWGNR4X2A5rmDyI*=L1D);29H^YZs!j!AlvZl!K-W0%7Vcw zMxpGS!D}wX!}AB@M2!mvvu~j6g28j&!)4Ln`&Z(qaQ6%@qP2Z!@T4T#e0cEI6xw`baO*H$e{}Gv{n6$VgNvWQ zW!2y-B(9$u{1qjatsdO|Dzx(a;J6o1^M%3Vh@4&?Jai4pUKw2bcig=(c*<62^Uc8_ zk}~TCe@f!)t-<;|ZziABQ^iOAiT9o^Zu|fpy-*w=U)PJpi65iNOT{);kc)4S;rDuR)k4&Kqxh>d z?%pg8k}5p7;m+V7{hTw5AB8ZRs_RZhd@y3$_PqOluG zXVD;TD!ua}E;pA_C!>{HO7lsNytDKUStxgvs!u=<_m^HS;_^W0>d*1|gQd5Nlwd98GF3=h|q4%h=tzghb8kMVF_ zX(}b1zg4=F*xK8r2gud=PO14DRC%{__(6EMv2+~?u=h$+?m^jyrQhz07dDkPkUZL4 zdWb~UN2MO}YkX0fdKs#GS=#C&+ClfA5b-iX`Wd*LcEKL{<|6lhDGX3c}}orYywo{r^t+cmMp|v-q9ahWeTu z4B+npUy;je>XqB!dG8;e!Mg{(MHY77Yfs?$j6+AEULI zeBuY;R{E8ejCkA$mqRL5ujidt44gBK2aG4kQpD$45l)%;` z0Zt7(Ns{Wcz{(eKIU{g1(c77UpHM2zS%Ejt!Nd81J$umf*@2aF@$j5Lh`@MmU;)A9 zyujx9xH~_v;yGLv1~7h5ZQ%ALnAwGa)jQ&HQQ-4^Q1jxz^aIe?;=n@6Y`P?{`f!Zw z(!g;9mCFJf_d}J-1NZ$Kmn#B)TZ_xmz^5enuL|rkgql|e8i_9~3(P(TJzNubtrca< z13%gh-Ch^?`tK;aKCmfc`-6XW&nSD|ZEsy9ib84zz!Shbsf8--M>`4b1ukFWeVcy&Ep~2lgUi z_CTOMiJA`ves(Y}4+ma28{>Q=&`J3CXy9|w`yUJZ_X3nX9yntx8e0|k?-(9F8MvN! z##4c(DERwyp!r9*JQHZ8pxkqTmLH+!>Oj-I7|Zj4>j}wT2sBmUy%z)jBy;%Xz(n$^ zzY@5U^o})whc8BzR|A({i7KxJ*2Ho5dZ6<#l)VuMkbU`PpmJYa)&-7w2xV^tE;$f) z>jQg}g|{KlMgf?20ta>C@@`p~Qtvfu~8+ z-yB#)F2j!lZ+(ZFp9Iodq4!S%hdqwVXMrUp)cic~{4`v?3@j(p?yJE1CX{_0*t9EN z|0b{p*%{vk`iRMVANa?eXywS@&Cg>HM+G16!o#D36{Haz6MV0TvSWi?`(k9r1&e3l za(pmPw#1y^ZvCivLNGJ|HBSmYu_uOfa`52)LD}5k1<&I$FSs{3(M|~-ye*nOEjYar z4^I!?KNWXp1S^vm#F@blkH^Eaf}OMxLgt3hSu-O;9XT{dTDU()p+l!;PQW==GDR1TJi9j;F=Rr^V;CVSJ3qG z;LN9Rxi0wQ8uWL4@EanF8-uTI#CtadFC}Z`=HNe93DYr=aH#(SMVxgEGvV*CTseh;A=ah&3l6nvR@(i%U|M!`-3I2K^_cN zQ2P5r!6{vM;o)FC8M%)He_xNgM}tFTU_2f?ZwFkS2>y%^Y*p}JVhK+Mmw$&UPX%8O z;Du*`?L?x_2Cp86{+-pfmhvD*K@F;R2ycFDz{3b64e@(3WmEi1` z@NiA=u_MvuYr*Xg#_MZ?m(IoA>%sO%`D4VO&lMeeg2ocXH_6;ke8V-F_q5JSFr7t?j9y80nO!g__>S<@C_t zyJ+l;&=VJ8Rn7|CM}V9k+Dux=*`e+JhSwK_ZYQnhoY1ieynbHj5z^Jp5AB)9!-b)r ze}ES*2wg*1uqZU|Qj}d33Xsd`;?U;D(8J=;6&K;*lF&M;c}Zx^>$tltG;k5hE)O-3 zntMg)@T+ilW$5CcploSq-br}<>d>bvakngVauSzoLJLT2UmN<(R=6w=t*3|Ahmvoj z<_)2%M&WW}=zt6G@TSo4A7d&vhgK4@uL#Zh7n;5`wCqB3bXzF(I4-w`wx5I-?g$04 zsB%|m<<_{nJM_RD+^r0~M(pCA&>yzN<=)WS^xplUqq=bSKxp(6fXjoSqsbTgP-r`X z%fq2pE<_KHhB}v{=3}A3Aq?X2(CDjB<%!TUpQ3D4sAdk{dn(lbXHoXViQ-bPMr`HKC!;@bJ}8 zDTY>F3r%8oO=!dgsPcMf(k*!J%}`wdck4oPyYa$Xq5H_Bcsn$g)Q$C_I621O2^C2q zyc-%Ej=PPaQMA$Mz0lAmwE2GM{wOXVhNdOa(WX%AL8!Solz9&iKMK7>p|+1hAFfB6 zpN9T503SvM#;|jrc9@z6_mA{^PGhhwq1)--Q0ujrYC{%_BVfE_5-m z=I=wB|BW7w3x7i1vy;N#l74n_c-?SZP79xM35Ilf_=Xp8IV1eL9t{4>@QJKsgnvx_ zfpf!$lQVi@xRXqZ3&O)ld0G^nNinDk!wu_jw>W&$AZjiNzel0&OTtm2+e^dK8qmWP z;aalZuMBS>61^sTBqP(mgBuA!j1RiZdLd%Nz{BYys;9Or@{{$iN>A|pGkJ& zGvNo{L6v92bN`Lkp9_C77k8_}3Gx9vAO83h)O;cQJ-zpGc=J+}y%Ju%KQ3#+Ra>L% z)$j~58(t6JaxSX85nfKthBw0%J-AyJ{))mCZ-wXY^;}5uO3ZK@5rZzKL9hM@EL7 zfy+^miYyvCIx>emPqQOWlKygRlkCEzD@Jr3_(g`h4TUL84& zyl%@P7d(f{HId+AT$V>NWQAWB`56)O^^qOOaeM>LCPWW6MG|$Wa&siT4H~;8^6USg zu@#XK8&LDM$n#__-X5u`N6kATJ1)S(J0nrLyF2nJA^Xb6hr8f%Po!!UF84+*T#Lr; zkF2;5RUU|ZMqbPZBS%so<)O%RJ-9p)NmB~Wqxd#8${vdxdMaLcJTim)$EzauufW46 zBY!4_^i<@(NO5^OvUxjHc{cJhqUq-%Ye%By>c~jaexC>SqUMW{XE&hDmm>2hA>if6 zz9e>Ei3BMTDEP#ARFkd$Oe*5Z%10A zXmbNhD%5-@(m)}>cO(D$7F9Mzb|M^nKk`^7s(cXXBn9Nd$mqM!-=@gCyYTu)k;PBp z@^R!WQffYl{IZBDpGK}AV0|9BetTTLh`iE*k$oAtVKr)g75Qv6UjGKC(c|)MKe`QTg?4K;RAbX^S|UL3uhwwNr5?*1>7T@wAvIy81^^iMb8^~<9FA{x6Q`g3wIUl~2> zIDmC&^rj1Oxhne9FkF^J?|u{ST@zhMZq{p~sn7Ak^61!~;NkVr@9x3F8=@PD0&a{( zNSnDSI;snoTcTSnMVl+4FD}O2tBZRIrRQW^v)$Hdn|e< z=@XAfA6|<#pNPJ_8fB}ZpKL}ePer%-GunJQ+TV{V&qS{#FWy(b@YpUQ04jP z+&`l1h3K${Q1iv;hEwqH<>+NM;_j8`M=xOxYoae6ip#6fML)-7ZS<^TQ04XLU3;U- z8_{Pd?d8pAA7y;K6@BpU=;7_?eDJ`?`snYgP-R2(^kZ>(H@b8T9&U^tOSbQO(Su1t zdO!LGh5bH^{=5;FP0`VhoX>`?3arasDH4^imM_;%N zcV9+}8MOIT^tZpk3tvZn$p{_&o}zKzMbCT*ZGInZ{3|X;4qMTV_l_F&0!7M?8TQXt z@o@IAtx5hJJM0URImZoq?HpX@3|m@(%L&8YN#lhRhh>Q3P8yaZVLEqMk__p2!ww=} z+9|`%r`eu548jnYJZykmA7>1^cRns>4%j z!3uz)A{h938{{A2KRm|2z^GBXivLSf`*)>(x#G0CU8m#+3i(`bZm6{DP(GiXa^U2? zT*d#s>aJ4;N`0kW`*KsVGpF`eOxbO}LNPzRIC-FQT3@!eR5^UsnEDa>P0!7&q}EH7 zlZykDy#ojIPMz92b-&tCV=JqxVs(Qx`{DV>9L6!Sck%&!`^o0^8<;%hz`or7_hw6n zlzw=MQ+p5UoAUqAb++$-{iaWu;+h$zJgP>`@BcHnDk?Csq27TEEo}9uDYWXmJQ<8* z)PcZ@ipD5m zJ*=W)TJPkcnMH03uV>IuX=XvRg;x&1qT>edpeg)7L$ZfNt~68>y~rmmGjnp3@p5RihXv06~kH z$p>H@lcx;z<#VD0gbhGdRD{L`ei8f;2uR)kJrJ55s0{77S2!5DGB^~PIVv0oopbo8 z(44?t?V+Cx%?NF~mvagIWLoIqBc{z9Xa5)Km>4=gFceyML?y13p-o3z5V|g~N9c(o zDtFyAbZuZ%=#?W*-Sv-u{5}4KZbOB8P#}Mnjz)`>p_}p4eZB37qeF}Fd=1K->nMHy z)DcGq|BAVEwlt+P@no_qnMyaLds3N}WJ5>1Io{qdDV^wuclD$*-FZ-LRZshfigb4( z(;Oe4XwGyN(|}QLB3GC>l<6q-qr$9MOHX^{h>F(kL|3Lck<4@_I;-n+AgsGsv}U@J&G@>i>Q6N3DdtAI z>7}-KC;r4-FIYufxu+qSj%N~`X{w)2Wt#g+lMl%DPLCE(@TrD|<|Z0`Ee*d)zD?sxPHg6Xa^x)pDL}(4;(>H@_hh=0T^I-Yit*26ytSq} z6VHhOHBzaBMl6G}L|3O%T+!X!k?Bsw+cQn=rjKlRy>q>^JZ4O6D{ zmIxA_MeRZe*y+$s245Y;r3HsF?gLR%bQm zPs?>5nMv^y#K!b6?`>(pqjXa@q$~6@E~@US$Yk2v8=9JW zIx_L@RHD7B6SxCz+&!`;*4{p@!UyCw^i05~;>koqdzB{cF_pu|(CT+4TQaE$iKao-z zwhBjjsN6xN(w>Sf948 zBm_p27+5v3Q9%em1qXv6Hd8eD_W#_m|4z5oh0>d4gUv6;5M z=?BWCX=*Z1O7I$cU3@ACIJI{*jdQTEDV^?efw{@2hJX>!7}yK;+5${$%QSUL_*Tto z;r|4f367Q~oN=0Oy(kM25@~kW|gP}q{M2|82g6uY#3Ya=8 zKBCALgw-}{bg;2nv@^V#IdSuZbf%@JvndU&Gt=CVZWvE|8*7NJV)Z>0Er}*VgqE&M zOM3%oNcl9{ZQr)d*@_}9-F#-_KJJf=KRZB4n zlu!gGSfXO(PC0jIf~Q*I-spPQyJaeQ8gSq%ux)r9jm#hSq215`&88LZiz2cpNoKQ2 z+0@#4+2z7v@b5E+ZrJ<)i-2mf@K_%I!e+|!E z6|ly5Oo$Au@1}Z84@z*RG8P|MGp44w846%edpq!%y5o|nQJ6$~vZA|d0(2BmNmplM zrmIts3(*_Tk=T@A36NUd$<|KdQ5X$mH&X!gJ!rJaz1t?|rou5&$@lTr9`m7P|C(r} zNK&Xtnj1<*Nm>>$wq003^)<`tGM#y4nDLNpL6kNn77tulDh;V|Sl+hQs^&zhGOh0R zt=fMS9#o_OsJK}C3R;miQmUKdjXkYUGCk{Mm-1Qx+|3P{L}Mb2MX0HEo6Rv(lQF5z z(5(gKX+gX7fc!zdk^_;NqNoyTej+_dav>sh z;GK}EnRGJI+8R&Bn_~)##Hvq7NTo3Y*^>q@cX570L5_DoPK_ren*2#H4ghcPbSXa! z32Xj5sJ9ra9y7~N53u|`b(MlSnMzle=U0|G3D1eSZuW*bf2J#3e;su7C; zXzZ&H7L-F^$tIyNGY-WVG-fNN=SGc`BviLH?dl+z=s%ctXf@LUV8V(|bXE=@$qowj zq+ue^e`ICM)-{Q>I_?tHgAz%Ea!qa3<}Szb$ncR%J4zUw|J=E>UIiNwH)Y3~QD# ztx%Z5)o^45$I;nUm%@~*HeHcKg`FLVcqa>DsqBFYZEI9C&>F)!jCIIcKD8dQ=Rh|o z+N(i(w)D4pbt*CZ?ZMW&M&i~R>J3L4%LLIHJL<@nBpqHc7X8W2Rz*87m6FYqeCfv; zoYKU-jL8JNBoL-D<#;kMp{c9AJ&_{)S6~WjNCpiO>>HapSfew!s@a8JTNVSV6MsqR zwk6BeVt6ZvN=sfE0a9JfWE#?49SJz7;oP4XZ?3E&pPtDx(^CHx;@=#x1PaK*bhVl_ zBzXzuq%m44m5h<_oYz|(G66Qp0h93tUPQ0;S+<%pXZU;NoU2$e`nfYMp&hGZ&)6!^Gk1|TMYSD@xW4yOj@2b z(huyY_KiI$t^5-xVm-=bp=ETU(`^P3C{zTB5SeOl$80=;N+IrttKXS4Lba7Uji^)) zVr*E7@LWrxrK>6vPeZntf|8?XhEq*h$2N={KF8ukvpSb1Mg4+@p$o?wTva1f1`F#% zFpqhH@(5aton1}B;lx;@%@PeN$+KhN*>3L%*8y${ylWSD$HJG!CX_`YCN)*=fmNo| zA*FQR6!?sW%U>Fz>YnEX`;r1iwiJT3%?;J?SScV%5RVbWGY1?p)H@|VQ+eiVdn$-4 zN;|WoX&fAjduPyybq6j*LpllX78IXH3fRKq#>>fUAL?uj= z9e13Cf0;~0Q(G*SNyob@o7(n`#r7YCpY*IwKdTeZ%-KjcwNQMtTB8IT(-+ie8yd8* z!Y_?j1gM{b@PcVD`>|jFb|P>e#x`*{6Bf#Ag(BHQ8IKoWpoZZ0zEfNw3{j0GaOHZk z9qh@Cv9u;hTR;w$Mn1GvBWX*u0tOAJtI>G_VtS4qa#7T&l-Za~oy?ovULz6{$y&G9 zh}~we-7_7qS%DZpiuzb>9Y-#Cp(xA6XQ9*_SQtVFa*07v+)5(IMQdgWlNl3V+oV)F z!+$#SZOF?4b(3d9sV{Is!`h|4T5wa`N%&a3mAG9l1}BySFTmHx7L+h+>}YDOFzL9K z2w1V7EE(@c%oTYYFl5v(gcec*g{<_vaJ6`6Ln8t!@?y(2p9(y9lk&C8hLc=Ob||dYhCoG-NG61D^(?~_E5{!a)#R+Ps1z1i4n$61_xud2~H^%7??^^G0S!C6#GO} z>X%i6qit}GOMORalx7{Jo4fcmBRFMuiDi+&Nf$ZO2sL9w5(C}ae9P=fTEr~o)Mz`$ zcaU{WcC7g8fPzg6-MUgq?dE+%Euoi5(1Hz6+EN_EL4VV;5^&B#@A5$0_A;n3nsZRl zf&xX9=m~oXhc!c7095N(CYCv&8L1j`JIwLo6A_E#Xsh$ffr%lD!1z3odQUOlw0(_o z4OsV7IHjZphp}8DgUMb5T#0=+zZ6##ytZsL&j2)!uuL52AWiTrv$R2!rg}8H-1XuU zWH^b1At6E_Enu}B<6Dvtg87-qJj@h|y;J&1NI})YK#Xk*6?t@oLyA9<*di8XMVYJWJ{@~74RxX;7-4O6%F09@VP-I3aWSPg2&kN)v ze!z)uvmI}_2kcT9a`u2mToWaMvK;D01kG-|OeIeb60_K{0MfJNrIVP5iQon(lmHkz z-AQyxR7)p=bVt;=wFhtnM|7trHmBmyT1{G4fZ)}zlw6aBO~0EGQhve|-Y=ijB&Jds zijfyyNk#{MJryoz#kNdnDqL`iW%3Vunvrre%afJoJQV3=-3hRC)+N;73yWt& zg&6+yM=PhNiuH5{N~*sXLRIiOk(GnIVxAla3?tsG&BagC|BW^)V{_|K}!^|1F&S++Fk+(ZWC#w?bguQAk_Jc^Gk|R7$cN? zxP^+mE;gTla3db=0tI=@n<@385%#Iz+7dVI5^hkiDnfLQNkfvQC{f;wO6zA%Tw17S zY=x4agRCp14oFt)Q-k}{a3oX}aID5Mska3b%2eV8EM)=tqRe2Cvfze7d4#aTAtwIW zn63~|t*j4LNEt>v7``g6Aa))Kf16+cCViUSE2}}ce4%%X%_AlOXp;aDNE>G5YBA8v zUL3zN;V%0K#9{%PNXBq_uDpo!Pvy-hSIyIfHaRgu5+Kt8jF@ z1MaSvSXhJMyI3>hp+IyMZ`auYk_8I5vd~XKv2TRVHBN9Ac2UrRAy$%VYG{XT<@`dB zBLm-?Q*M{9w{Rx{l4sOk5B>!|rF6tPq~PdV&ei4C5om)-|_S0Ro9b zmIJ4(vmWSyiF&MPsb6#O!a)(2Ji;~?M?oM^^7^m_A$Dkices{F*CGxhV@#BPXG1}t zC|Ua0nI|vF-pNx{=+lIf>0wdUekMcvFEdc#N~Da?W>4&%oeF#qFlAW*A6c_EUCLkC z0$0)#F=<(=|4zBdOQ61JLoJh;fNoW$Voyb~5qa62EtL)3K37X?7E0H7lk#iLC@&3)6R$;Nre zyjibO)QFi$mzk~>QaAt{{OQWccc>rRJIMoL)H7kKQ~I{VM2$*l#rBVAx?%T(%A)?i z*vf6~vYn!N2%{`Eia?+k#sQf%srGohn^?2{A=y7OXBkj+b3oRAKti^pC@&dNm8a@r zlJzDH`ln5LEd>oeF0#0Xq$h@*;yLE>Xdzc!@6d#Bq)7dUk&cz!WEb`}@hUT~Odwdy zA!aD#aS`4tyZSZmTmf?oYWS$cAQ7rTa|2W>{NoO}Vewq@U2<6<;e*}dHq6UbGvM9I zn=^#5X-GJJV8Kt4Q(5>aC(Y91%dFEWXPH3&IW|hI`c!x-YLCE(pDQa*k(%C zWbnU zVr2cY5K(04aTeQ4;VJf;3U*CVkHf_tP*%)@fg=P4m^y5Dh9v(e7V|}e2eD$D@{ds} z0jEga+MdN7F>0t z>NX@1ZMbN;Y1ClQ7y^w(C1!0)Q^*x}J~Yyyc?Y5-4e7JXBvYvb>m@GK^cRXop1w(( zN+vqRX2ui^5|Kks(iF$|K>>crHBPz-I0&2UyzRy|HssD;8*IK+7;c=?iwLpYbX++O=4m&}%$#(5(=KenJmsE(#wHx=44G>7VJO~9 z0X&FzH{13UdjMkk9ZYwh>XeDCwUc~e_C#!YbTU*Opb_ykfmb!Qa4fe~8p4LbZI|-c z#E7*JQ(3KA{}ULYq_8k^T!qX=q(4dXY1yk?#yuLVW|D`M+r_!|a$%7U*_cEWtQqWA zAgSJt;J?pbs1869HYiO5kkVe5f*Os?8V0g)Ey~WJs0kAgZOUQC!`SNTnwrtoRWS{-it{YP|y1iX%PBbgHAzX<@Mt%ZRr)F?P>?^6Yq=?GR5#!T|C@d;9CsxGbAxFbu zsp>GirTk`z&hRq?I^9>eGFKg6u_ya=OEtMK;%mq$Q!ai=FH@pH70J{Q#LwEG)C+jl zRFAG7E#RjOZ#(6OC1o7D<)L{Zfad&?VBpQW+TU8Xwi^L~&o%NC3KRilSaUNGLeeWM zI4Vd)QvokA^RudvoB%{|cCe64)f&ZEx9(`r6L3oIY!wbCtBA*I4o7SI!ZD*`wdyTa zM7_y4W)nJOEcl=%1JN|=3u3ps|G^@vCx8x`N!hUrt;IG~lv9a2R@oLvxpghy zbaZ3?B}Pt`9$Hn&`>CE(Hxwz){uI@+;5o(ydr5K1pYKDA%Ac>+RA7%2`}4ZRjcftt zQZ+Jn1zTaT-wT1#F1WMBPPEvl+NxOf*fF*B(E4h}#74(@N7mN0m;or_luF{*($1{` zl00;Y9do&5D3_Ppao{k%kt>n)Wog`-v1(@R3_n;71V1?Ft?W=!9U$QF21<`;7BUoC zxOCoFzq*iu%-V{-S{WP73bl!1N~J`R1d0`qS0?FLX%{fdVj1D}nlf?lENLblafz8= z%T2XAC}EJKzz83b6p2IKT`d4>Cfx>~U|Uyvb7p)s&`soLLmNrZMp;7I)OcEIrZz(z zaTPPd8#I{V#6=q~h#hNXMX3KSv{2+ArLb>I%*jju8)Y)nDc-DeOSYh#&0dWhhhEST z5i&x}$Dtsz(`Rp=qqPwv|2G4MAK2zft_cZ0u{w2wUC|;XM-Z{dRK%oo5J@Z{crFPz zPkOmQ(11m;52BlyDMfPO=Aks&G5e3gFM|~kXvI|Q#W5*Ts#-Ezh*8ivH~=&V6^Z|7 zqeBj#;um7gocRd14P&tFy>_eLzEyaE6^EmtqXSPKsLHh$yqE~A zl20|+h>*X%bZ#VbL)Kf)6L5nKnHkuLjh>`vmBhYHs;{pFxggZ;!Hmuw-d z=8CGBi?0kS;WyAxOjrW~mK zmbwR8R@n)Jt?5ahAkqhE%Qb=}>L!zc&c}yN0sEXpC)>O+D;TTAQz8r{$CeKjY1zsA zyR&&*sulUoj{l&E?FMJ-1TlRV`XZOWJZsOz72qS^qUb_757%5}rB9CqGRxx+oh%2} zzT_%^5DiGmGS^927FycN(7%5j526ZW24m%H4@ZII`Kf&EL}#};CsXKi3X2%z;?y0F zYG_VXDQ-xaa?O>f-BE`42ucQ|udXCcs3fh0`40p!_iY_@h;sv7i6%+_3T*%a(8NVW z%-Dw7kWgy~EsoMa>@o(OA(=4~m1-ayB{U{8a7~G+yk@LbFhGT?NID!@dsSFQD)<;% z1D8wV+V|-OAUB{X5*n>0M_wv9V0MAv=nOStXC4SQs;7KhNJ_ceA6Wywj{4ib|@fvGwGHHsOgFxKj-AyZ6@mBAIuTsF%Udt-IL4rV&MfREr{ z-?|Aft_!klCZH(ORdo*d1)4BF~uYQ9kjHfGLkCahMS+i)bQ~ zZfI>o;wNo~>uHwTNq8Wdoe@fd-3fN)S__l@lwIWxMKSWw?jT?v!kvz8VSq@GjXJTE zp%G&nw_)VDYghX+(rv3TT-sycCN5Xe9^;R>X-M8`9FD15AV$!mXj1 zqgTwB@m8UwL2Ggmz3y4JX02RA;$09Dr8e0}W)<;V$}>f<1uOr?UlB1jviTv8Qw&Y4 zb>c)0sqkrN@x6QCs>XRXiO%*!C(h4QDXFx#o^&-Iw&OgNxf&ACKxf4DI5>r?Ef`Hu z%Ps$`-zaFAmHPsPS)L|%|!>uIJ@d5xwP#p|3@)0wglRGm5 z`Ki6Sc_E8@t8mliI$2nxFvJahI$F%5{g>X_e<&t~c$C?4N-`_dBhh&y+ zM#?OEK~1>nRv5ee$WPKQTc>{I26_5GM<>0)2gm!50iY?)IpD1Nm^{o;Kt28s<(_Cw zr^EpU6qAq&i@S{R!*NU#8&Fw(`s_ zqPBN+b*ET=aiIweW@AG>(gV;bB6&^2r;MnaLWis36g^ArGJwttf8W3nS`Hb{&u>e=|6Lc>#z!C@>;pjt^5T6Yde zFo&0H*&|Oz1GFm_yP$)Zn&OFO>4wqVUhe4hB=?h`67)n1EZpKeaNaJZ_!o<3n|qln zXlTAVgTlv!VO3+8c@fOc*K~-Lmh=b3q+Vc}i=Hu0N0>W8FVsK*1l{l}GcBRu>6`|u zmO4$4)mWtf`0!fKherJCFkt*b#x){DBc{XB(RRFyr&%+?`Z`{?m>VY%LYWKrN8UT* zmi%`f)+WMd^3W`C$br9DmUfpn3qevi>i`t6r<4?yz!dVsQFV~O^oM80#7vM;$}#Kd zLOZjmu}meNB4#MkU1);(hNef_nkTE!NAr;UL><8`59G#4+;y2)J)gxb4=AHdP{t?% zzjN@K$tN{l(p)rNYW^kQF|iqL?@B;q6t3=7AWRhtZ*GF7=D=1U0UWE};QpqMidi)e zlV0*=9p<7cX9KoA+r#wFIkofM%hYkF9O!CJrb(>UO^=RdK_9}9TQda)vF}1d-Y?6~ zuLh%s_9h?!RR7kwKF$*oT==jAeSb)IrO;7}K3S*h!wmp|5*qGQ$TZ?=sLw zNBbC$>0u?Fy4M!wwV7eb?Wt8{grW0)>{VcS!B~u(xiX*7v3Qho3Oo~`c55iRf^Zjh z1@OY7TN9b-$s4;sOa$lny{@G4x9l++d_~Mkh2+r)EBmyrQ#IR`S-3YGi-ISUB%}3m4B7xl484VHA#?-vjjrz=A|Sca^g6rjXPC@ zY|^VO`I#F<&5`KHuS<;bdb7?!yR}qmi?uU`yj)vW1GNJ5ztI_0<#IGA(>PiA@gQui zBvaLh)N&d5g-F4f+lm~0M2ga;h}gikUCBCxZup0t?tGvT+p*2!!*}RtR@E5#mJKP- zk|A|t&p|v*p;G>*v5_Fg-{leH1I5Q+V6>(!iFkW+dzTWpj)p3;h~Pgp{V*<_NhLf9 z=EuV^m)b%)l_4x3>FiLFLN$>a>Mg?KEa9l_VTO-+cm?;x3Cw0!((fXIUYd5y8k)Ws z@09DutRZQf4P{ksIablSJonE~olRz>%(q&n+%$hh7LcvD2y$Qo62+LGTgoIS8oIdH z@)u9WD&xt0WBYUDOp~b4leVz+m)6{=#C<6~DKSxm?U6de;Veho(VJozE>=!c&r`ckw@sc2u;Av+qi_Ta%z^V<~wuStK)*pXt($f zp+O}CJ^n%yFO&v_GsJA*saX>2Au!n23h~8Cpo>Gef{D^4634QDZKtrP_(f)=jb3G| zF#rs5rV*&!Bz6;JDsck_`zQR6>>mrs#(QE)s`@>_JDUo_4y|aF?eiu2CSIULG<@6{UJIXL0 z0X-AHG~dy|WQ)K|r;4&kUDzefHT``Hm%&A$Z+mR~z6P+2gL!r-NR}#+PIP*<2qUWG zd?*$W_!EbS_cP+tOB#eqe{=y*&~;-&Pc!YOfKy5Rm^^c8^%xv)!(y^(bX}7aljhQE zQLse^h2d)>mQ0H;Lt2i1R^fpg3%D|rf9TNsY0@A1I+s{%1#=p*AYax6oM;WH7!9r1wj!@Rxl#dV ze&M@bw8K$;bBx$-nPd(yNJPGL)Cnt183e3{L#$YNAF3+P$cQ;p8alZbv9}yC=X9}e z`t;tSPE;a-7IIYKjE%7@jif=*)ZNyQX~)KN|Dd(Cxkh0npO+xwbClO$ru<+MUw{-Nn>am2_p%ge2e}m@w-fYP=>$q^Mwm zQMQv=uK5YK;C!sZ7rDVnQ^|Ted{0y>PR;L5CpyKc`LuFl%aE?%r+R4&)}-uqb{F&F zvo_`8_DCP_5tmMCC(0S{mH@)!g!U_iqA7s1f&+01?M}&Tc1XEN-c`sQIX(kgD?{65 zfn>tkQWl*oSVB21Gt4jg+4C%0jYnbjBi9_p0@I{NvPl*JKsjGd7OYhdgU;}=S&%I> z;mNT_=P6dOF*XV~TW9QdnR2*m(&U_4+yuqOTe@k>WP1wyTNAArYVbXrjwkP&c;zTY z{;B;|Irl6%Bc&}kr}h}B3(mtWa7Io`RrxNA&je}q+>!x6<~CnxrMyO{$a~$AsCPET zk)Zd%0&A6dl`vC6?$LIJpT9cnNrY!?_kJjdf$dC>slf1s*z3&@a90r^SAIMqCB+Y1 z>XTd+my^m1JgqEfRP_nv7?pSciom5osUa^#zNgslCHR`{`MTahIlo3MR;Sh)wipVP zBxMtppzX7D%I;%JHJw4qr3VFA`>TWyaERa9>+1r)iDJUMg1iOmbiNG9)0H_#)(6`B zSu*S&nz0{C7Dd*!E0w4`+6`p$eWQ{ycQP<36||e;maa(|01)P^NHJ`4Eo9kh+>1E^ zW!2QVHyD=qXX zxmA|WDG^@~HhxN~8!csv95Wqh;;G6D$%&5afgw|nzF*A)S5uQ_prc9Jt6(r7s^Xls zVH1DZYCHtz%YuTCu#(lW+R?RRYU*p<+y6&<>si`Ezf2nlCwh`;T<(=Y;FSIqzkP?Ae}JVA~w zq0?I75pZlyM=3c?iPa_zQ#ud^d3rWb zeXH;gd(O%o6#jXusmCgIhc0G zjom^dP-|-}Z4^ha-`}z~m30kUPnJT^aw&0>SbWJ;!3V6x_rWcn+-pnS(eW32Y)8?w zpDy4Omtn2U=Gdg8QIy$Bj>%9x?3sm2%UpWXJEYtNezMvVJ$KIX=%Ejf^T{9l%SOPm z)jUWjMM`vd{w$2T$bebuqyCk`Hjxa_x$Vd>*m;Gl!I4D z1&)m)ZK1~CSc#sF#>#5za{x|qXHtC(08K05FEu`aF_l%bDB@55kT9!Rr_xH5c-%_L(wx~LWxwGm=9kQ2O6I|2 z<*yAu1@Y_(S0kZrg`Q=tH+5?#i)*@v;Z1|GNK@LtrNh?R%0}D%ojoP`@dNOqYeYbi3_x~kRe19#aCdBjfCz% zkyXTPh$pbZGs)g;eliDx>*ICRwe>Y@kh4+*eM@Uaqp7|Y}MGYc)=uPmrX&PNtVWk~VCI6bLW{_?SVd$E5F zo~+>uB9v8XZh36gUQ{O|OfH?{gCPQPd@wcvm8-?0(Mi)xKFLIDD>9Dp%?7)Pa<#Y# zRuC8?X%zSfD+8R}4<;LtIw;$BHS(M^v)tHcCft465lSoSmIN-Jp^_!U)E&c4tU6;4 zWnw6unzJ%2^x-GcF-W;+j@h7ixeX7O<)A7tI7m7x>L;M8V^i$~_R&Q==Lh=N;Z6+E zCdkVXYJ6`TPh|x1$^cDpUjUs5g;VzY*W2y}+$V*f4r&Bg<9%%A)0ta>;x#W&t4IUnYNycHU?MnV6 z<_Vvh({p@r#Q&rN)hBu0!5_7Tg4V&e%~+4r5~WQm_e0QGi1y^mus6GspG#0FG_2a0 z^N^@&IX4(ig!=?r2MJBM(j@43W*a~JYB1z|gc69>+VrA%vSi3~pqPvOu*D>!7e0w} zzKoeO+>mpovN)KW9OXvsy0;;iK$3fcliV2;hF<6*E{w=Xk#o}K#>J{Z_t-B%M;f#5 z#6L7ryCuhuVqmDmKor}4ps{L%uhDGXC=+$94S`Ahc|H^8%AtYs7?`_sXuYANxfaB> zqu>Hd;=mPsegUnA(rM^@rPDA*iKE~dyarR0QcZlOL30}!)qpkGNEwE1)1Z7k28B&` zNa^AJVGhH)?yy4eV=*qa9n`Y(u<1N4E-ROdrCzn%NrF{_%pHLE`^U@WLrM-~sSGCl zYkO4Ziu3q*=-Q(5O=>qv8A2u^kdg|-lb?`MOxuAIB|2IgAZ_sCgc$)wk0vkOJr=Cg zsTipVU1ST9OjmjRV9oTG$(4yFy@ocHv{^wyK-K;obXSbLRmw`?5oQxy+R8zbyqvy8(gm*w?2G zBOhLDZ@p1ON&MeDCR8GUIB-K_frA=YFNqoz3BiDL!Do$h6@J-8+Wz@oM)Z&^96JtY8l}qZZc?UV-1W`}O{DFuUF0}pmd|Z-Xa4w9 z@Jv}N)tsxLxV5tmiUf(lskJ0-MB*F)TJ6xYxwrI!Q5?hJSfm}WI!s!VGFX9!?h|ql zbVzjo7blknDhS-Q?At-`Bd~w);O+#)ktML2_VQ50C8L{z8Z@@nMZhv zREgYgiLesQ3HlBHRrqEZNUl0OEUlrCR1kvA|Fb)q12~nq0X?upCq99MvGWy05*EDeLIy@tDxTZO-HYPDSs4w8+CefTq>=RcYljk^< zsl*+S%ZNohyy+rYiVvYReMX{K`W&H!I@XSrI1Ou*Wx25kFyGWxb%n6zd>Q48Iy@jp z%_WTW%j5B@!LMqas;je6ewTtH^{I2xG~sM>{%lQHSm@V zbQPZ#uW16q-UV?)j;+6&OD&xv6p2t=NC2)(CC@kv4kRS0^c7g|^U((Ixi)k#mvR#5 zNbS+Xg}lef*WK>S2LC!d5XHZxA}Uiutau$2HMM!attUVw7E=DzoJRMUNva{amd~7> zByJ!8^a!8XtCiw(5T!Dj4Y+*)$|quA5zWHqTLoq-+N)B29d#A&Dhj`s%7%q6S?s%{ zH+X#rjn%HYI1Zq&F-ov09VC|PAdDEEzHS2o6lsbsXqv20dFIDzgoMUQDruQY79OyN z$B^N~$T|@26PweVUrh)0PU-KSTq==glr>@sE^u6MJiZ(X4_jiq=4~Ysck<3`GMTtFW*||uTa};gQm;+BIgJk0TXKaSD?;QMnQ* z_xnsVwe1!IimpT%Puy(KU>wYQRr-xdD#{KXD~Zyu!o?>zAwamY{E!X&|Sd+E6uzYpzgcTMD7;2-9sfIQ2rWAHU$kTRc zUc-eagBXF9GvGl@$w~NHylHwu)?-^(Cx6XUT~zJ_?{@P8YRqFFm8->55pqV41E02; z(2&Gd+xFKUb$LzUo=qt1v%4;r?5=eHs;rAT`N>Z!_+-c1G)zgi!)+#QKSaNVQfb? zv^+7KuF5VW1$Wz8E?1e?!0byhVWEd&{q+fP*bD^h_l*xKT8!2+oQR$v zC-d++!!_8@+2m}BhUB*#Y+9_dZlFYyK}Qg3KX`DfQHP;yzD_iVhf*uz4Oi^vZ$LQ1 zKoX%#xQe+kX#&6mixEN7_k-K}hK920XjI=-^Jb4*C(ofBc==sy4a!Pt?~MEkeNDAU zBv3*|iX0_t*m!Yi{%90RGtZR`Un#692~Q{+j`ZexYaLAAgEHn7eWL+*{B2!cfLMBX zkaz+w5WGjuM+dNy90afs9_ok4F~)8d;)^Eew7*YeQINQI%mMm5H$8C}gTck6bn^%| zv2e-@@Az(+3p#E4Erk(eU=b?Ljn@8AX={|L#b{%46KPQibwp?S`;(#P^X^WP&lWO# zx_iJdRH7hYFHWylcB}i_crnO%#vmmqi2<{t+K`jR>dS3mQgL%JcXf=I3!9n9G?Yop zQ#opuuFN5Iq_-$V+QCtDs-DUnQUA-+oP_!;`4fPiqET5WMNX9!&Vj; z>oYc&CHqls)iZw{)LX2cCAp?6g}Nz?L%>aeB7m4qw4~s>!yo2B9(p7K7C1_fWy8oE zqUj(}P&Lc7q+kz;|5jY-l5_`aaDW0a9!hObYaUc%P?{ejGRp0o8T2o?81p0ZT_v@( zQdS`~W9RI3=a;P+ZlNMCxS{gPuavt8&f>Isj7Y_Ib6Pb>QKU^c4sE#ilq&`y3wb2` zOi271Q?X`sfpL;}rre!pQ=8-EK{=bU^)$k^PhvN)%_scp@K{*GV`%(l==Z{|BVgC zN7N*0d&_wQJUDlLt4O1AXOnEPDmTUkrN&h!56R}OCf;lJxOSFq$vw_)IXgNp-5bpL z6ew)eLGB+02L(X{*|dFXy4LIkBLOaKShEh#P%=0fz@&EN6L36yu?i2$h+yoUq1xu$ zwRq#A3T(|sNHn>3+vMETY;UoW@1c5|4;>mLvXGzCu?KJE1IijabPI))+lbvlis70y z1iAppgiO(%1^1x{jxF9*O!f}W>@5xH^lY;|sqip}WB^=8T?#V>>ruFTX$z58F2JN(mI8w+!z&haglA_naLjdll{q-)>a;IBmyFapb5r#u)F?1>LRxlsi3Qgn)~;_C{8Xp1adRUBoh8|XgGZW^ zdctB-Wdnb@m~kPKX=%ry4bacUSGi-=V=V5ZWsv0z&~XE9OlhJf5Z!aOd8i+udlt#$ z*2;9^Q7A5nLzYqvINoY_L$Wot3;tA(s2qMMowHO^of$%M93nlt;6lZff2-tbBX*|; zNSzzLL#Z@*C{|zj=c-*Q{~W`=>K!U~tK8vl#T_c~@ff^1f^HMI;Td3V%tWnNAS!$I2FW4w>h+0Viq8auQnQHnLd=J$)M+D0J zEU2Ah#W(nD(@kNIwwHbKWSlw-G;_cjd%R8~&0y^87GDEaAj(*K%aCMS6pgj~O+bTFe5&zcrbZiMP+8b`tKjJnoTcQhx)Ly`c_&L?|p zI2$V~oH5!aG2G>Z;p&Uqd`5=mLm~=7uyZVX-VIBsRE{QVRZvHc!I5Aqh2?7TJjrZf zV9AVH0XQ?GRy+~Aur>a>L;^N#DGD(5ju?l!8z;K+`Y?WLl#$yeWgy)|IL*p=b(JDO zgC>hoj#(I&hZK4%cN$Tt%A6EnD)B7* z%IZA27gQ^80t1rR!2ySlteP0>9^E!hUG+vTu{TA<-VE|I4@hxG*G9AX({5m{!RLj3 zs$yO)60n$pPp|sBwo}FVODvjUCSn$f2qcGdoS>q({1UVG1^k*7Bm= zQ^79HkIhCd=Bnn#w8vN4^i@GJmAy2(p~rtSdt<$JUGT|f2;&6R)iy*8)d6;k75{} zO+wU!r-(NRp+p=)V;u78_F}mGo$PT za=Uc_Z#mD;TqP}wghbaY8p=0f5F$TZp9^XO(YFeB@Pm3r4LA{f7LGFSghxn>!*~ikMG>C}sP=d>k7?~BB~Y!m^gu#W^r^%^G*?Bg8dHW^ zRbqxd?`pO#*p)vU03{HxJQldb9$|lblqD%(NTGM+i{phe!*a%25c$)2kI=m{RS>q_ z+&6YJ3lXinii#3#0QuKp_z2o`ecc>3P4>%*V5O2S7e^j)E76Hmg2523UR@{wx0pcB*75XDk+S91Wzf4hoc}^GF@vp0SelcO=H}XC#;+g#=>_ zHc2^EY2(K_h+*a_v&d+H+Oa78ng|BWJ4le; zCC`_o6CJ>AGnz7$xM?s%W0RW$XbmXJxvJ6rvKL=-q~b z!;!vb>NMJHacmYdkIT^~g)*r>_hwUM*=h`Ynz|E4gDF5;jT|{Ej2?!JR0qvuZ_Zye zCn|&sFiM4~!ILtCZhAWR%m{v~4`f-|TsO)lOe z4v2Lp=!=snC@)u&Y8_GB1SEK)D7T<6DwoID<1M7ke|se11srU+LQPucMbb?hGI~5nGX5)7KG95y7V= zS0}OR5GEn6C%J)?v!qA7Y_TejiK5vu=U}wRIWYOC7TefqVIy_9THGk}8DZ{L89Ow9 zJNirJCTb|{8Qx-ho@FX=7Y4(`)?A!cBU4<4 zi&GXP_(=gqUL*DEEQomULm!-J>Fdo-)myLmFOT}$Y8LBaBn*_fQk zB;2?fIBb#FLXzA{Y!HcDPE3z~pc`W|yz86xW|AJ}E3Cviua&4_%|+75KsK)1o8y3s z{fBb@mZDdCoh(x3)e#if&AUn_v>{;uIw~)|{CvC<0Tqm1MAzHgpfnLcscUA)*i;Gp zIHe2G&9fb}WaousJ(;xtwm@z!@=u`S32_m{IMS>TRNG}`RnJC(eM<%! zkQ4Hop|E{FU}M-WNM2DiU9{0VrpgcjVIeS+%xDnYu79T$?yX#rCV*D1i@VlL0WE$V zMTNaaH|Y0?n%jpZf<^uSfYQAO4P=rQLEN4of*ECC><=N{*r)X75JlaFc;9_q~p#aK-)c96p{1 z2;+jcF<)HY!rxWDJD9*P_F?lrC^Q}C*V2svNOir_yK6sw{`6N~VB3EwdqW3A8lujW zwc!-LmYoZx-Pkc^QmzRpVRPzQ8R3$UHw^y{NRDYf%6E=e^W}r1c$g#d#)zW8!_-Ns z{2bH8nU34)Z}N<0Z`wJIU}HTR$ce`3izyG;ywNHRrO_NRZ1E3aN5^0?288s@qN!*! zoyqLhj*bF+vrqIH=^?d106 z5{bQEKm7ASeFa3w;aX`@J?%Z}f+mozv7TEg|E_BpPHC8HIEI3TR=i&M!6ZOuVwRdC z|4H3yJcXz+B;!UMjsgfN)fC~?`wQIJtsk zuV0UL|NeS}`&fkhF`@5*M|9zq9v5+6N#X?;LDn zZRy{`)AWTK74ow8+;|Qh)Z+9g)Vnl=7UXAE-RBe2Own)t=8IsN!3_-n=3~z~i zOyY^{!^-8|5lrL4BM_omg=kczxSb9qP)+;bI`T5G3T0Vp)y)g${tnJvkTCT1a=BTlBMRDuaQND#-HZs;uuhAL} z*M$E30KLx}V%tfG_n{SUCGSJ~u*l0Gz}-nwfzYoiUs8v`G`V{?$4YN&!e!K&V10^; zI23I4jvC>yzn_cL%_0m;;Ds1Cy?N8>PShzroWd`=^pW$00`M$(r$7bCkqkP3_Ji-F zg?Cv6$l5o?V!|skVdvB2!r`Q#7ZFM1rnWM zJ+=>3wF`1{?k^aoRzvXC##po88g$i!r}ETJSs-S^el*MmRi=RV2pdrC+C3s~IiIO- zH;+4M(tF~bjH=c6m8IQViXI^C^w1OHCnsP#@bMfTcwR(07b;-~cD59SSl&g-BKyjnD|yJF|XdLVzpJ?+8jbNC`(?RIT$gMY72otg*KNr^ufi_XQMTeGVBhP z=HhB_gJa&QgOS!h>KP}=42o&)=x^T3QILFh;4B*vM6bvo%jg{aXEf=k_8Q42;mFUE zK-3QMXtO%IKa50G6H3!@o`CS4Krt}mSL?u26ltqG8_$`LgRLq;GXu{`OyQSBvVrlG ztej^m+CYJ6UFOHwg824ewWuP$ZFHtIU_6&T2iZ?v34!w8?nTCDaUKvPikW~+O|T1$ z;1b;EU=#$9-`p);o`caK(Ry=#>OKoaEAKI+>gxLD@^u82bjGlaVal)}x>9VMJ=e1Z1Fsr-C#e|K|oBP@k3tiVf#H3I?^ z`OVjsmODW__cT-iF*}Xm3SmqcaW8FFPJhQ`M-?4Ar&MlsUp3kS~LZol9dpzOOLpo*`@znd>9Am>(Z58D)Bq$Qnq_b1dx_M~rxm3Byhh zn2clcc=5aec;;tp?$?prf+FX>M$~Ruu52okyS!wb9DX28c0NJO&~S?9E{ydsgSR^s z308oR(AL~7but}w;^lmU$^@q4L^fB3h|?F>xr?u3j}4(+PsQTtIG-p)Xv|xizrs9| z+q3JJ=Vs|6=m+!QKYU~z!gPy<2G@+W^}l|-`|$IBBF?$GL=x=DD+qgiw+Z**1irTN zf^-QdMhB@48Q0t$x#hf{*Csa8J@74hgAgC19L7`q;kh=8$6~q}?aiQ4Uu7hM%2Pts z(WgywOgglRmg7b|Xo+@rgS*Vc`d{B)Ezvh39t&sFON2zH&&*U4KAJ{0_UOEUoUZS> zN*=d3t!~i1-{W6)E|8^w@$4rr!v2A(T4SP59;Cc{xA)s{F~v+`;~If~ zAiCJh_>$2cIfXoHdAht@{3Oi3{^h`nh6TU-4X$X&J~U9@bKk8~`LKW-qaB;`i<4Tz6>_zbytvFc0^ibbL4iF!=^L`K+3D;JjZ%w&htxj|+CzCm02*T6}tc|LIF> zZ#=bC*n^(_BnnkGA@llGKDrhZx`SA3aBC-D^Lif;*1N9g%|L6sjr`ZXI9JC~m4vxj1W@MEA!H=JTY7fQ z&6>d2_#R!~O@qerk?Uu@zd!8=_l7zHg_)n?cZ}ipIxUJ}TyrXQ=5}s#!MCXey$1{0 z9W#^s%0OG6F>&2E^61X0Rn)T6-9)#WSeXD7B&%g8Z&3|af!k4bn?~ric92(BereB9 zWST;U%^3mtoLuH2ov!M*F7eHCXBu=Q=icAA0eaRSx>NW{6ElM|Hfac)=>|sMhdgaSbmD!*lJo`+peuQV3K%5gwZw z;JH{Yswj4Zm^HKm1ZqYJFCMRPj5KB&#G0aznu=d4 zZb>sRco2Ss&0c5J_7v!%cY{Dzx{lM)o0*h-PHs0ysD^~M&>ZV#FaqyM3gqLkPR_v? zIiSw3;yo7efcrv#@A6H%hygNhO<(@;{rYTynr`qbg`AsF!x>x_mm2=Rjp-P|mmik$h$%{}y4_z&!7dqF-F zMJuR6^y9d`A;6$}PuT06&Uw$#Afn=bXirhHRe%ssKKl~>AQ5>+DoK7rb zC-hgx!B*e`6jxu{xt!l9+GGSk=kJz-H3y|?FO^5bd0E-rWSFlOTUPuq_tERkzUA?O z$vD3z=g$sepC-M-J`L?aT(VsGOJG^nH+jVB?D7M&)03D`eE{jswZYSsTuZ**Jq4u^ zXdPKg|HH3A*@fQ-hR{XTky=5rrjtjij05QE5?SGktJ~EDVq~j}#U)jDGAK`yazcY2 zZ0nhHU(%KB_0fAj$QYjBkc^0XtlQC8L!DIW3!4jViXlV!ghxZks*f?Rnek(Dn{_WF z=2nR>YLdpnjlg7%%V`S5aRpr#Ymv}-*nx9q65*qI!d-VMg(JHi=6DjnpV7fQSYaOx zP$8yFzHCy2>WX`h!UJS-0$Rt_Cbtli57a#bobsdyIcEIP64H1^ME~aNZOIyl7~X#W z^Z>424_on+1?UW1@!LG%yjOE}sh9i!B9{zLagYt1Bo1WBe`=-;zD<$orAc`_+~fpD z^|io2gDBsiYZK&v|KK7?zY%#5FrfY&xlzdS|M2U(zkG~qgOqz~&g|(i>$d6M?WW}w znFp*KkD`T^E~3O-Zp3Qq0Q)>WzCm@s`A&5rK~#e;(1}z#pu6fXkiWPNcbv%y;avR; zyv?+9Q=U>e0`*58n_QQ`%o((bQosfovl6niq>=JT3_=&1+Ov?pil5_C-u1nj#b{@*rl3*$p0@Gxu%>5n2=xl(8tJP&m%(Qvk zu9f?z7k>Zr-qUhSVLjoVq7z}=H5|oPP0nBAf*+A?_|YVr{6TMJ zP1i6QrPOelFeJ5(?KG1@u$MP1ask#f$^vzYU6VAzZgg(b63Z+KOna&D^K`{)RaY|+ zRzh_yl#B>n;=X16H@;1O+X=GI*B5`1hI95yXffg{cW3#`T<&YQnBrmqVQA<4PJe(& z{z}QISH0Izy(ySg^cX8Se}nv*h6P%NafcYp(kAftt9!I-QY5#8s4Wv`PX=W*EfAH5gOxijef|a?Jm>I`SlNh-3)Fe<8wF!sKT{&YI%-(70rHD2b5B!+}h6e6sSDTzuQWl6-yyc z$iH(@=t0<;3Nc$S_Y|7f;_II0=kX=ry2F06ua4}-oYZ06H5u~@rxf7L2DgoE;NSW6 z>+{Xm&HIO6aAECxQ7=6Ijl6AX`EQl85&6v=l*o?vsOgnLd3{xEEet?phQ$I69e0Vm z-AL8s+gs__xcfXDrly<08gA?`AF0U<+9@zoXr+)fd(8yWF73Ekk~2cY$z5TUx3|u( z^@!$X@qom%!x^fJPn(>2{tc?j}fZ)(}}#HL6}H3L^}*1M-h_IZK`Qm3w@!==DS zJpy%>x}eb+9)#<`jK-Ns1WFu=yhL3s2Qb+%X1=maM%g>ziitcRp`e`Vj61GX5lZDw zv!U`E60p>%01Z#m8|6Kd24zer*zFzI^Hbr1_fED%qx@lYWo$U76Sex>bn>E6^Lgti)nMX9M)evHz zLb!W9Xo+9ftG}dCUTvj{t*Zr&`;cT}euK*-9V&i`03EkJ%5O13<+uxTUz=95HbaTlfT_97*C|@Al%cfio5be<8 z7&b-DE3}>wH8!jP;&m|)?oGsDjb0dJ-9>>{3J8Gq~d23P4UZ4s?E%zw(I3o{i*c9&gnQeI`e4L!-z_P{cNk) zG8^|SvoU{LsR<&vnDus7@A=E!<@HYd@#o$D_+fd??%s=wmE3%UjHg#i^mxH-h;dAD zP|&@m)42Q@ckff0sUv}S6elo~&x3S~El1>KD;igd47rrQh8s>S|Mxi(*gRNB&b|B* zL4{gwos_KA0!_o9Aj`jp&)*sy1XI7cKHi{7F5pWhiD8BsC%ThgT{yo93kgvV_q1+R z3g!|G2lNVNQW@2F4iAYg3KFx`z}0U~hWRClq1x@CDO+3|tp2~-?+^AaFJI;K52Z4# zZf14|z!W)uxa12|3R~OsDg~gdJ91TwW43FQ2xB1t>bg)fw{>fFbSRmihQ&vvKk2G8yrH025!LCWIzz7bnY$ z)7>5a4RqN1L8MdL1vJ-Axy>swS&C<)aw=#*Q7Cx!$e5;nq%jp#{>xbe5}C0wm_cmF zuXl*?{ch~%3CYGKi_Dg^Cp!qH+#=awQ0?q2TgBhx?#jt97bv^O@!y|D*+^tWma(HETKD8s1rU>?p>uqJ^F%r82DyjY_Vq9S z!X06szriypn}CJ#sMYRM5j6I(eBieiT_vjVm@~-fX1mb~lL$XPGpax1pscNqgzmnY>9F7;EB*?W+ zY7)Pi6^Fwv4Z#pfM+^-~t*1Bl$CpcZo1aS`j->KMF>6*X9cxLw;N*6%gLW7%6vkYz z7HIc4Cdt$Q3`fqzU9`7=1up$*1``wwqv#$60?2cavpW#>6O(AF513gbWGxD*60dry zcdZI7Z%o2Q5GRT`2jJ|@)gG+ZqpuaatDoHGaC1clnuR>|Z)EHV4+b39cm&o#3sNy< zd989-g0)54mBq&@1!w9CC&OG^er>olCfRivMuM7zQRNWBDSU+?xHMDKbiao2{Ch-L zl*iEW)p8yN-N4-en!J9Gxp5>bE-GuhEsH{wfs!z%2vYU1^)-Dec`0zEgViw{>%H+g zoWi{)H@GY!%-~M``^f@C#xS}}HwhhWcC@C?H8lC@NpBtLLLjw7o{m{m?{)Gr5=sh# z!(w!XJ=~1pyhU`PWaK`zQQ?@ zsCwZy8Rp?ore=yM{u*&Pucb$o+zx|#)S~Lf!V;r#K9=xSKg!U%=0lvEOq8>m)fEgh z`+)&-7-Y&)Omi0H_JzE$x=wnZKz>G;l2qSX5P4u@MCg976qB;5WQpob-MK@=+|QRR z(j%5=F2h1iba+!1H&Np}j;+>uFyngR^k7}Czy=NsGFaOj9zt+v(S#TR0)MXDb2x=x z4#6ZmBzF?3515_ChsYI9+AQ@cd{k`4Hxjs+5DgM+~~io#kBVD%Pm%KKZR#hx;Yuh zrd?q-ttSY1FpXAevbEJ_^$CQKtbOcX?Qp_+73*>KW94!*4mPFwpz73lBiU*2N3hA~ z&=;edJ)OUsCbZ|N zhsm_oZmLlpl4Ql%)>5?O7cZ(hA-D17^bar|3Mk;!$`Xu;n zn1j_x)Q@GXeK$He%1~8Nr#gv~3?}dl1o>TsAUBm3{^M+<&>td7IS>zN5}zN7jEoH%W9*z%;M8*EN!aXu((h9kOo7CHvn7x_+9;5$wY@7T9j=?_g8TV98`= zCv!zZyVD#dxW);pLy8@!_HbY+&-IjMr-YrB zLBJ}mL*;UfNKgm&`cX|vh6K>ISP@6rD0ZKDwu)Qo zggil0hpTW_?T(B_!m=(Kz%tSWderE2CY5e^So5`ErGRnVfUUVWW(-MNDUNF%O~!op z7@=EwU6OCw@ltvrw3In<$8lRJ=DDwVqx{(TpB5zZ?$>GGvMm$S5xTPs%ByaXsX(Of zW_tL2iW%ye<0!5G8>v0Jvop^K{W?c>9R_yrNa|?^uhbPwI9Z+Cyy|&;et|jNXv_Hm zghY7gq7V$^%VeBz8KIm+CiD&@!dxV4K3P=X0)z=m8wEh15O_j*|LUWA&!-{_Z!XZ}uDq;uySIG|w8W z<%pWHS}|m9mO`f&joyW!9$7_&+S|N|p>=V^(ye_zu(4H@vL6 zd#YeRF^O_X+ZlpHx>?RrU96Z~%AOj-@x#Py^V;I%X=3>5oQuep!AYOz7VzRl=NIgUDNjeg%3yW1bkKOecv_c%jci3j3k?Hu@>UwVGDJSW;d=Xbf~X?uB=p zwtg^7959kx>pqBykzzez)sta@TUaZSq%3Jc(xr0Jg8Z$iGn-Tkg}W(pF;w0j0=p!@ z7n6Rkqgl@;wI3Zd&1Od!wPBpQsH_RT){3o@VSdR9h6AQr_JSdEiZgBe?i@Yw@=Y%X z#=pB!J~6zavb^w$c9^T|OjT~&SvJtV1~d40BB#1&v^5PrAY$L$pw}Bhi(EUgf1G}I zs8wS5D4cdMWZ0wz%H943{|~99MmB}Ej&MP;(8hYno4EwC_2FB39gJJTKVn;FyZTN4 z>iLOWNui*YVnD6Cbti+2|N8Lvi%%cE7SEB#BWSK>zMfS}X&l4NMe3!<)KOM|@Wx17 zYpP>K$(c#qOt2K;*5NUY{7BOsX~k%HE|@mxPOi?B-}avFuK)fI)S>7~&u}YLmO+>3 zk^m<$QUQ9ND#TZ}JfY%?)$Y#4O0v^3#CbTXn+x@5-RMw6FxpTX$UAXDE`gjYOUo}Q zr{wYdZz#}2Y35A*#lbwjW61H{+!bAuhCqJP59em_#2~kq@CrTO`R;Fj`%aZqZ4_c$ zo~C2V(mG{VHblN9K1{4amIiw=XNz7`eMsL5k&cT)Q6j{Z=tuIK5U-h)Jg(4~MxtZ{ zcWOPJ)U1Bfc*ZG$+)3dWAosY>U`Hl0iSU#FId36*eX_WN?LyjdMZFv27s!bW%jFJ1 zx@;jK2^|6_v!lrNn558W4b?NM+*ZpSty~q4s(^tXJ0v+72QuAQ=NvFQk&BPHKGJEz zj^&jkUY~5PZ%#xV<0LfQGrQ<@xSU%G9@u#UJ873ODFfuo2REJOaw{h(T7IFkMX$kcn1g950Jpe0zLgkCy#;Ty zd8d8lT=0C+TC?~ITq+WX0{UEk#_ua6^Af_ME5S1Ym5j;8;v~t+k_-(JjkEv7_sj$k zG6A_5V*MKCzy!y&bz>XHc|Ga-7d1<3$|bYo)@PgD&E zzY-;ra$4`qAL$ClWQJ4t`0l0IC2P!sw}~Ue&dWs;PidbP`KbyY7D^|b^H}?yB)>`R z!{Bl4Q&rl6x41v0!mIgQ1Y$m?$1C~})O@dJ$)`glDNDC%O)lJ3CoM<)icU~H^F zkz2&+Hg@bTRZ4c>OFkR1XB;d2aI2U(l5lg>@{&ttDnKsT0Bzf++wNBB6)=({#9_%^ zp?5-SA)n}3+HGPd3sirdE@gQqpP>yue0>@KeK#;VBVB(I}LW!O&mc&medTM~RHvyJ_KRm}t#DL%h49%6JanlQ)qwf}F^_ z-~&7WFl_}N_5u^&bF=u0fP&!U@8>3VvnHzyM8bhX0mMS57dP2)kd|DC$@iKDK<7om z`2T-SrDweYkO{^;Png8THx+9QBjWPXZr~yWlO>^AR+*w-?|tGPg0DCW(F~csyhVS> zKkx0Mc5-=J*maO`?~=+(Pm?BaH?z~?UXCB?5x!WSY>uFn2~WCQzTMf4u0Ra<_Y9Pr z+X8;hGBYA3|F+@TfT5>x$}2RKrHmNYS17@|JwfZt_8XpH61JVz)y?$cOng-&S;y|?C*&h%mu|5r{`5v4016~?-8AlXrD6GyagNsZGs0zmo;A+ z&SumMlztxM1W>A`CG0~ut5;~!&89oqIefN*rzC(~H(@$22j$^y5+9(1(=~j$Mz2aLc`R;ydbso5$B*B&ZfK^}s7j#9AdU7l>c^K? zD3V6}%6~IJIQ(blaWQ&4o{`Zzk$qHl0Ro?7TDQZcufVoopGryHI8leDffpU%kBd{b zm*j7Ir=P!}p|UBAThs{QU-fz%#Mmd2+{ED++9#$`y?*sOQut zvOIMgDKd+)`l-wG%Vhht_6|wmO!cCr#`)2#Dt|q%z$N;D#SDl5lL&1G$Rw)dEKN=k zfmq8XLCBNUYyLN6BY6S=MkXI@T=T#9ya_^D_KG57lsz}*B9u+;)2-QAG!>4gIrg2w z;kwxi@@UWl_aj1ri({JVw8mjN&P_3uK?BPv6Tafocn-hLP;PYkZ9RWsD6YPJ`t;$` zUk65iXutGxIOS#9G*44;;5cvuJy*^6kGxzVd3kelyQVju z=ghc6eoYQHF}#A z{7=XE$h_LhGMf@c-maW{bFiv8y`hwia(bteC+`duS)B@DDs5qKFQzJ{LrahcZ30xL zGLm5q^CdtAr`LL8ae+z!Gn2SjQMRRP+2#%obO>d9xPvYN8E$sU#gxnA8A}`s2KKJ8 zKRW%!+#6ZIZc$~9;VirjXC4mrI5x-fBO-ZZ(vfOz7J(zDq^giKdw+Q?362%CqZtz< z2#!GzdO3Y00nZ#}Dv)K?$t#|tX>)_ws1TF~i^a5=Y;As5$tK76fut>`K@-;5r zlJ&C|q%AOSJ@^#)ZtLBWaZMg!F=4E4=P~UtQS#6khL@vVz59PYf02lkBbJ#L<2l@; z)^K~^RP)M^**DFZ-ZGI7n!&@~V>3G~tp>U;`&#dU^vOpxG-OQB43g=%V#XxS%oCxFiNiof8t(7idHg-?Qu&M4`1d<| zPiprPbwGAXY+kZzVo+Eu7}rRV?75|jXNg>>T%d%j_~PL0fW~vUxte+`*ZQCtUrW^^&pg|UdP$6_jU>Gi!=>y~-7L>tt=N(LlOxa7mCT;^ia1qwM`?ij? zO#?sVp`yteg6wCVZGm{V@Fy-h^$WdmF}i+pfrg8#A8}2s{Dzh4pG8iZv8I*+bad^c zme1I%5$Yc8lBGN&V}X~#sm@5=#*@1_d$U+w_t2ZP)FU1mmQMx=nvw88;8UcGoSSk6 zQFY9$Gbgo+u|1PxgBkjGm4R?>T(AD5UJiLIx=IwVg^Ug7-@w0}Ch^&>U_j_wi5@GR zf|>{YZ(6^Z*Rb%iUWb=bW{W%T0Z5}JYjG&XDwU0c!obS_JkjG#1T&Q^9l zn!&H;<=S4m_~!-+;fYE_yD;MM_b(2gl(>|8WS)E7DV0gy%<*Q0iUQoHh1Gd)U8Lqp z7M>U_eZdVGVIH1aBzciL6zo`>9pZ*c{UrEc)>>k%#!3x>h7;)`?k?7VnC zdGRs;jg$I=Df0q+R3Tpc@PhwazIb|irtvj+B>cJ0OKsvj*3%w{;h)TyoLKf{g&hVL6BPvX`M7y= zy^-syseP$FyM+G0-|#RWV1Gb)d^2P!J$On><1sovvRVabZ75Lj-itREO-?>lRKy+sc(I|LLhT|#jQY*s>*|?^ESoty zxYFg^ES?;ZsBzPJZ=MfQmp-ZngfQAJQqwvE3ush}BUZ@nEH^L$IeB-9f;IYKo*MyB zYZu!Z$iDmbe(%ao0d?nk6tW<98j?xDPcyiPLNgzb_=l$2%hOwE5j&m?u?u_wuE1FY zWVu@2o!`hsmiv!rb5kwWe;Rw04khC@Mmc6+`sL~rG|!8q%4Or*X7Y%f+*Hc;KEr-A zedVQ)h2m12^9U7(5ghIlqpqFCI+R`5vU8**T^vhW;;wuGDGW#ZqI(sW zd3%p0nhoE>Aw&PD>F#-`0xJy@vM@NIshjBu2hmI13nqUS8_Ha?3_!ct7*I8M4U+bf z;o|*G>wym@a8cP4ARvRQpdQ5t3J0#w(J>9)k6w(Tz=}*vzv2ZZ%|g?XS7ax8bJi+G zhHm9gfm)NYez?U zQ4zqT4eT}>jSF&5pbD-ttbpuCxl{25UA;bAq4NjYN?)CBzC8T(gWOZ~tAAU}WhERJ zpAzB_(Wzu^lqKh11EQWuKoZZDSuFlUkjq*z`|5cl7blC8bGcv#tQWt4Z=WH^*P&{Y zir-iAPtMW&Y53$P3oz$`&&bqa8tNFEaW&bi5-~8{NG%^yWaf$ z^ZN(B^H56%b3(HKkPGH=PNkr%u<@eZ9+>AzXaW8gr0v0bKD<{YiDmA6t}|NVEHY0x z*fhOkW)cx6(R)cMaoc=-e=OY*L{$P;KzHLGsEX|^zkhKAGu`e3my5vVG)>YwPlldZ zad$i?7UGB}ry}>#H=&S;Ci7S?^UC8UIjLj1Q4OML`Un8e?um76!zo-^rx~WZ7~KeE z9_eC@1CVQx{ki6$s)Kyu;CM#|H#?0Fp-OoP?G|@s*^hX$y?QW(Uloh?>>ff-Oc^Op zdYu<;0iu~nd_abGL2*w}XljPwrK=)UqsR|Y90e~yBEy#tPAFwY<2O87pF?Lz=$c+@ z<&a3_^piQ0odi1$_1oZB*5NUC7_7Wjp%$C^HHGYsj|r}^3>8^iqv;^Yx`vzbZJ4pO zsvg)5ZH0opb)1XKPj&C!vz7>=+SELLJNdNJ%=YUf=gFLWg) z@kPk#c#6geDlL`o((TaeG|-v_^7~}U`S8ej{q6urEDh)+1}STVFT~1b^!)e~x4?7) z(mpz2h6C^t%aklP4D1pS0<32DK_c#+ct}D1DdG0US+G3i_y!>EIz?h=*Tu%r(T%0hT#-`Ib)l1MjCOB z#(6>(Wv-Nlr&3O8lx3Ji_Lkc}yl!5jD-cwA0a9;5j=KdA|A3ynKUp=LN!MLuRkbc| zTvKx}Y0(P^kkl!>N&1Q2<4&fZ(rtzJ;!%uCaezJngG<)!R)uO^M_N0GdN+hxn91J?!Zt7k=H1Wv)^vP3lNj!ahmSn zpAnoLa_klRO3)qdIOzhQKGxO4FR=Ch#^8ln>g0)Lshfv!A%$2y51xVOwkUK0JcNzN z^M+$>|1P9eUXFt7$T&u0l9fU#2@JU}X_8Lc{B#)NON9}Hegd!BtMyCROWDLW3;Y~q z9UK00{rMbCb__z&;y#219GlYOuZo7z48B@e_6cf9kI&A}VA;G>-?rS`=Y7u9vVfNl z%)Xa;NC-H)IJ-gXP?S%4RfE0RaKWo1>YRY}BvLMw04pSQlpdA}An_|*T(j0maF)(_ zNf3ywTY>-{ZhBXk_%x$D1Ep`SI5&%nltPgoH&!UJE1DQQH8u3NdieR_!#^VzvEZRI zV)Y5xvS{xZTv$W4&9!?+r^6jr+e$s>nwU)5n(W8iq zpV4$;5*P0poopQ%-E0T9HeS9a-|6YVAE{%Uj*bnWw;lZW0Y7=2XTJBK+m-^m8X}c> z2B|fNj$u6AZ9VsuwA1b#Tx29dpa`v=_hgvcNLT=l>}B!wo8vkBx-5%s9|5LPt$2Rw z_h%;Y0R_{VCA&=}a66Ou=n8@3oUG&IJUUkxZBgO$LOKvF6>hn`2mkFNmnL<(#nIJ7(ChF&>U@I3ruEB0AcKb8jq{LGk~Hc z=-wXHE}(VDlF&XWqwU1!)D2D+5p+*Y*_Y8_QJ-Bs8RlbYR5b25=p4y#Gfru9w|IFD z-|i9~+k5oD4*;qXJU5MRDe^Q@S(x=)s{_mt)+M@Uc;Kv?4o^qQ@xccFx8)q*Kus%` zv=bfU8V0B?!Kg~=^daJ^q!}L~9f|S}oQVg|4^B@_H1LW^lplCM6BYAZHdvPAT3Ay( zU!^W_Fo8?0N5%Z0u8#_5B;$q3wF;||ij8W-y3Z=4R6*@{R>tb=C2^yWOMv-pyc(6~ zSUZTC5V%6l$Z$ zSqf_tFBweUrjF97a81i89oi++OJ#?REFfmdqrHNhCq zkc&Gxe9XpG-dM5-P3G}fsP@Netkb$ey(%sQZ9~K6<4j!)^!_->r+9vN z`1IM~;qJ48XS*+sj`p6)9U7N~x)N1#>mwgSISo%2;9+YlH zgavYL>QLf1Ys)jTtHj4M)+y{z3OJD^uJ;I47=q|+BMfoGxmXfT>U{iq#FP zGyS?71zJQ$d0i|9cm~&H#-Yd(Jh{DKAzH5<4ki$UzC5f=+xi3dnHnap5#}Np)g> zU2jvfi{mIb))9RiLyo0G^nPSk>6e{!&>(6-WEx|G5}vOP$%r>p&kZTIYXrPA8=4A$JqUov6?c7YZki$-3-=(dBQ+*8K3iu>B01J96541;U6t}BQk$$0 zSs)!8dt#OpgNejWTv<-MM9dny9P%FU1@y=-+EFH-i4{Kan$`1|3==+?W2sFDSkZms zR#={4Mhs}IYuD>XB)l@z7Cct!`iQ5gwW5?{i&vHpt2cd5Rqmb+vBV zY1an1WdZg`)oRDVZ-vzj!(q~nFz?D3J%KiEVJ6HCV5MExX85Lr7Y0&0QZ~g1W7Csz zdzmkF%`Gp=g`^tYkdi7v(mUZp=@7bnA5Pj>as&@EI02SYf9GSyCgGgVY?1~tiD@Qr zV=#f+#^;R)9lf?;N6qmfPgGV2Jz&#*+dJ6%yWl7lo+3fOf>h_7s=O{TIr1o@ZluiZ z_IkzKEbflH3puAZ0&M<=kIik?$K6hEUUt|$n!(4a0B`BVi~Cc_2;Ceb&-n1UxJGt= zgDrY+42x9!l$*`X)y_XZe|-1#!^el5P^tu{U1KggqRi+LRuPmhu!caGp(a^RFFz(b zNnEol2mt3|CGdWf+fU9d-GE;`Q@=YqjSm^DOErqedbeiy;`s_y=X>@uo-=v8sP#-; zq|WOb&kM-0d^bR>TNdt4{`twy&pZG2Z#z(?O?ID4eMR`uk55vz8861mvP;$v*(H~s z*ON)`5!sbeIqSSaJ)wW0OHuHbOapE5H_ET31Y*F9-3#Kqms)x`-S(+D{+^#!5bCBlH?9Up2c&1kba6gD!&(Ke$| zBb6RNux=5+n^fyah0@!%PwVGpvU)IqU8Y-K-K^IAgn~A_Y|IYNZ}Gh=U|-` zZuH7F==x1|brQKA`b%7#z%7V&h3Qu=TY0jWZmOPpjvbUCtM4@BBBL=;R8_Es6PwNQ z@{GCsU=-dMs@*ae2&#U!y7*Sizx(;EIBlFSXJ_OJC9DCLo=w-R#J!= zZA1}vyycg`-m6c-O?~Q8?w3#G0tHUF5fVpBA3_B){Di)EE6%XD0Ch48KVF+ue!X{@r2tU;@9$ z^@Iflv#gR_K18=vsQW;1^r#!|oL4Qz{Et*&;D@SkX$mylsdv&?=gyZ{BXpyQ6CgQK zANHP{45T!P4^R{i_H+AtrNn|IKB)lp_?XkW@KL^bxK_UN>2rh*H`Fo7jI;-M~2C#GnIw;Nr3Vi$4D zSSV6x5~mC&8+nX1&9AI^IECv|L;)e=ltTR+D}112d1_v)BZm&D!q@2FXzEFD$~Bdc zuT%qLmPlL#F<}+=RBhfr{PIDHimWhUm}~RA?-h_ApW*=O+c|)OMOVKs&u|lc$(zKX zu98FJ30}aLpa@ms#J2^J7etseh)yo@Q@b5>G zDu^r;X|n$GKYqY(JT2$tvaE~i9_REK8d;OxEgdn29wOgn#*lo{P0D}|2^N;)K-Wo= z0EA)Ods`B}ECB)^+KYVIWb@=+vTl)050$OB-$l$^2o=22}%+9Wt1}cSH1D~kOChH5#MC0oBUX%-vkCBbi#wflS9>M_)qWlu$t;ZA8D&>wvD7S7(d+OC(lVwuHs{#xn>gww0%qba#(3>Q#7K7oXnWfBN$9zrH=7 z@ZH-2XY6%XpJd+@pVZ7GzRm%!c!<1^x|LBa$dT28)R%0V$v0_OPVIZWV_2#m(EPmow?B|n4{ggOw={@2UAi;!I@rUW0LOk(5WP4qe6uwWoBsk zA}N1piy<~zm%eo>Hy|}3smngyB!Nl{E5=Q}~Zbj68@XX|y%A`fw{>7K@d*vw5hkTE(T-qG=(5qrm=GT~Xp zAeAIf1j|oxnfhYuQ%u#O&}^;x(ML;fgYuNjAC6Yv@8X|nQIxQb>2VPwOr*#RLSdBi zg6zhMFaz!+8Jg2qxV$nJW@(&H9?6bWXE=E^>zAaN(-)#zgPH5kx9`4u`1&uy8zp;5 zMV6TT&mX_NAF`Anyq+%vTb6}}AOu6L`_4yeR_Fp(okQ0PeZDxMU|-Y+qyV1~s%Uyl zp{$Ubo5cf~S!$1kRLiz`p~Lb>zU*D-;>&Bc8DIw*s&B(%fC6@cQcW6n!2h4$eR;qB z`tHkDvs^Nchd*h8O!1QCr5iZ82bkxz%ozf$;PUfT+!~xuRr?LV{1C2$>>svX(O@hpS=o zi>j{%JO%8?P^nZP&+|w|+@sTEBlVArRW8-`pd|nhFeXQiSSV*Xy~-Ep2S0x)kf9ON zmK`g{KEYnUnw#aPj(iiw>;T>PMNXZ}R3uRi>0zkQOEv#Jr!5kRrC+HehJcqiDyegA zG=obT94gryeA|R*9uFNK#t-tB;F8gNIl?vUVta8$wHV_o^Eo<2zIXF0?=oofAa*^r&P-a zd=r}j<+0I1enVC!ojHuXr}~J|>2O4yAtJP;#_M!-@fy9q<()KimDG%DSQh}co~*0R zD=T~VdILS~I9T-z@HJ#R`TMpr>SG=LdvYy0H-7rZH)ttzzd0K=mII_s5jeRo6S`Ku zFLUoHlMP$X0e(@{3{#*1ar#(v`+3b>Hi9&7Rlb&jw)FR#d>8jAYHY4Yp1 zpke>mK5U@N?(DLR$RVL7VPc2BsC$r5#58qdmOaHagxyP~!S2d{rsF&r`MA2Fy619P z5rxIVYIGvQ(S)4!=5i@y$vA+A=dZzleXWh&61+7KQ6|#=%E=My)*bPz*(?0_~ zJj`_L<;`V-+F68F!h%pkJMSxDIi`SaS?Nek>VTYIl!70fpaCy7G8BY#mfk(8P7-`H zeoUWv&g7_0n{5zs$rp)>uTzWAnN5L(LrX9!%X2IYK%Kui8~k*( z8bT=n1aeR`X?p)w@E@#Jy;oUKeyUVjK7|vWcwNTA34|LU&y*cHOB+`&FS=iCA)&Fgr#>*>s-Z&&$==}60`FsIU;^?!ffDds6^Baa&02wg1O(l zMRWq!4s_c3JmNgBc;gxaS19iIdET6DY**Ww(--}`=oYrCmHL z*OQ&}k)*Ij8_{SHX7U0xG3{D9Y6Jqiu5pB9-pP*iTDgoIAwo$@4i@@_>Dxk=$M9|O z2`Wc;KGipI;7+RnJtjs($>{m4;lGi{@tL%aFrwMBXsc?oebnRV75j|0mN@dw3nYhg zg%f@o!bJH63=d7J5w%P)QLqQ5kvPBS@h3nm}U;<%{TigfB9-;n1NnG1poHbt9NJ*{ebtVF&B|<+f#0zO9{NFdkJSg^tjR z=ar=5@V{U&>MBshY%&V~2WDc^ViWdd1E&|SH@HUpF~vpRtSPw~$O-$P_Xsh$nJ1c+ z@lpvlQMR?u*;OExgv40@BxR2!v{_Vb?1wjz2rO|;_xz5ix1 zOn5f+RT#(Wtzh?3OGlb}h+oah6d{$Uvk!T|j$E&vRqmNL&|{9Fq9cQA}UWZ4c zQP|s^ZJy=SbTm2IjQplz(^27wpU11TbTPC(sh6|f+??GKv@a@YP5@9^2-^Mj{{&n~yn6in+%^Fz5ufuQaI zuW<8>T6o?nKXiU$YWBnkP^t~BUd#Ee@1QPsh*rP==9sM?ffyJOGl@kaIR_K%!cqTG>WiYbnWo=^>ekyF}$YtzT7k!ccae9`jZW{yUFO+2!C+ z&MW;TfOOqX)spBTCMSclwc zeS?m7pU+HHH>{LU8TbSI2#uxk@1hl(E>FdviSAH#bRp8^d)lQX(n4fX%V3FgJ6n!0 zD?KZjM=iN_I-MbUD(N2gO1eZY$0mPLD=HEEBvY)8k)ZNRJqkomfpb&7QN%#)63;i1 zY2#)S+~ont0}p{GhwAe)=aXgq0<7U}-Xbo*1!bD1*gGx>wBV%cOT{L`+zvnWz}PJs zgl%rWef;?CA7$}a~(`lOuy~&_2SZ^kmaCItM&SW9`qIqYKpw8e@RJlN{ z9zX#)f*N;zb9uUXy@$8}LxWA&$QE0cdq(qlV4>w*<(gZkaz%ZtW|ZF^CgjOaC%AAY z(oHqWW$6&A%w`0vOPR;gn#mUowa;c5vBRfCB6UiyuEFcICA44+I-By9JO-mKBocId za0`IU{h7k{jfw3i9+pC)@|spVR)xyR`QD*dhwU9|d05gliP2W*Da)Vw!^qtr@X3zc zrJ*k;?1df$%N^{Vvjx{6BEeEh$j(DdsKPJ~?C3;u?)v<>tsu`;8kSW5|aX zI&mynUpAhji%#*PNRrCDR5L=5rXIh@yMYKucAg}RV5su@+k2{1)EuFAQ7INN&5{FT zqzSJlJ3W<9}RFy!S8{<}PJreKif#~qMhC>V4i52MMIfO%bLDLv1 z7Cgk**p%Q_%O>wAfcx-(eCoP--9@|cTjbpMTZ?d8b5fdp~Nd4bSZ}{Dm2Juw@pB!E45qpy`F!4{QT*!J8_Msz$Sy%0z4XTLzqfQHNwfV z9@dOiW@lPeE#a-OsFdFG{*2)A4!O{e=%uhgcX~Q+{AYVKed5(HZ-aSb8E0H%Am?s{ zjJsPX?Aa{nd%hAg$a}%VM7@~YY|?^(DvZ0QaW#s$YTpxtt2^40IgB5O|ecoSX4qu zH>v8xa0=h(`+1h{7oQJgpPciCa&a3wt8EN8efr3PO@1}2pu&2$)sNKW{mx`Aw6Hj1 zofAi3ha%(aM4FVrxITMvdU2EQGP6cmDc2<1S}jw*m0^hSY*}2m&`03y8W>Im)tSR1 znM~noGMSgyH?$3vwIf(e0#Ag6YYd|3E-inRW`u^?yob6pz>xNtt8bq^eSr8;&s_)2 zXH_q1`aHIZt#^8S-bJK|6t4}MifxwKp5*91e!y=mQjAO0tC{@r0OSehkSe z>cTTXs3T>4UP}tbgL#TNz)azhN(`?YuK}ybx@{&GL$Co~MB$j!aCU?I0=2`b z`^sLMQqe|NA@T_dU=hJcwua4kuRELBJdH{XqJ=k~>uTm>-_NRvSZWv=5EVICVKY08 ztK>~DmSSfoY9DbpoOEv>%fT6K5UiYO*Zz<+m2l45(Zu2 zRo2IXPEClme;?kx|Ccd<%*NzvR%Tw$d}b1lG!hc|ZBI!2Bb=i6JTev}`lYq$UT3+) zlui&=WVugx<@E7w_%U8>v zoK!>^Q4L^b9w8^b{%|LN(DV+$su2k8LTxt06$LtDt^95IjoZ9s=Juvgpy~174_p21 zU{Ds{hp&^m!Kx>htA}1>>hg10Fd|Xa_FHDGQT@4XX zwW?^TYqp+daQT`9Bv>S z?pAYIZ1MQ`j3jrER~{AdjS;3#%`OaN19qIi?{~TUBSKTsA*@j7ximtM#p<3MnohGq{a07JY`PyP7L&t-Ow4z&f zWS(LGR)0(ICPx#OrII|*GB{+JL~@f5W97e}F*#dBG%9P|0s+59MUjzPg+ty%=--r> zo;HwYsM8z_KsRd8)KC2&^%%qMlT(-cp!}GeozOHiZ$&XlHeX3dEbRnl#817r9?BFJ zx=fmwb!KEV->oD*H;eE$bNJ|4*_K&hgpE5};N4yyZ^;xxL%^DSS(q{Gg2s%s_$o5d z4)WS5l66bUCREThWLA%*Tr?TVm99@B{xPp#Z#g)})LBPOeJaL324O|{nJMY!SY@NzAWt4Vqi&n@LlPadI z-XeO`5n7{I+_=8HJiSC1IGF_#?uAT|%(K(kKtmcSaP3nIoxGHT#AMlUJ4yYZAfRQL zsUi>&CL*8&(BRW58nr%)cWKHCCXFUD6(@}b9F96!gcVSa0bLL(d7otLsBeQjg^o{+ z@5?eKHeu2Jz&6fj=7k0kl8&9>D0ZN+4%23FU&Ow6nx9oM zN}Z04dHHQTO^L|MHx@vvz(dsZw7n+O(KVx-ci9pbfAsznI*zaa@a>lN2kalj?dKSu>ruW6gpxumx(ao?lvPa&mtTs>Mg~ib*rmb75?^EJ= ztSuzv9uV(gieK?o$=Xbud0OpM(Rb@qZbI0i%rc)XzmT1_{6M|7EaFJ5QTs+<)A0nR zC^zaITz-af{s=OYLU4>NyMem#`LoI8V`er-(XL$9H!d9%&-ySv+&*-jM5fw(*X?-q z11oja4yslpw5@~c0CAL74M!SlK}#xx78lo>;}0I`%*;~5AWVkqc#Pm9)KCZn7^CZR zG&VAwjYe34A$H{etOzom!*d(@In;OFpW)W2e3+P1LFU-4{9RWvn!>IGR;PIJy#) zDajcWGF_@*DFg{_YF-O6jh)dG4mmVxT?myE+41i`{};qJiM?ZDxLWP%Vp57bGl@IQ z?+;PYmzB7ZXlxYDZG0C-2ah_^xJX5+i&Y&WL($k6p&0Iop5UGu!SOBXsYFa35%9as z`Hm*{Hm@i;=QpNqgd?P+@~%-5|7H^bQv|dzFk%Ff>RFF0uUKs|cmt^rx*tNcO7jI? zoxBp+&3`qyYiDj$uemL<)BwVVy9)!xH(L+weE0F=cV)KOBWh8H2i9~C&>@G69<_soGz>E^SuY| zA~D%AJsDb@rZ#SHCkf*If#?c$svi?Wu#UBTs8tFIZFxD0z~q2Jz^w+NGQrttd^jC< zlBIun0ppzibOK?>i0PZIy}=yZG-10mnoM`lnAYH_evxt{XXH7`*_<{Tz-296Z<<{! zrCV`0zojkAHJ>8?+&FVpg#>#hrWv*8Zob3;5?GRDs!SYMHEG3hiKd_3U!SmT@af`i z@%n0U2OC-*1Ur;3jDv!xf~P~@K|{#M+}KwV&GjH>r|}>&_&nrOylYgYv=3FEEtw4O z#O!-%K~!li&)RRV(4d@t$h{Z1l~@a^!~P{|t}b4_T%u7QLT+i_dC3G3PO0O74RTOQ zE@8k;n*EJt5FqL3sP3U{`mt1C)3BY`Xxy(L)nA< zIR5slrl^X21k6vvQje&yMm%aee!GsGFx(nc)18*A*oTu`(|@_ z2_7z`*GS4oF5Rvwk;zxlU2pG%K#qVy{CZgZC{HO}P_#I|q*+o= zbY{|I;m!ysBt1@>4>Ivq^8c2$lSDjm-|e|d?k$X)Y8Sb8ZG4sA6*^krr{&GfOyX{m zPzGX+OTGQjP15e>vcM$QK*9S^L>wAu0)uj*J+q7}Ud&G8LWB=k8kmIs*D5sd4mvw*W-_o*Sp*H>tYsm?KY$d*v3f>r00 zB^Xc;`XMV{tX0B@Cdj#VGOs+%ZCDCiTVsGz7*_^o#rN51#0YYzX~i}-#W1q6U0kLs z9p~4tE^ar{+QaE{XEK~e3okUGA4>dyd&d+mZHwOFVLhUrGTB!65AOmj;^Uw0{BTG_ zjVmeF`27MR;-8fnaY5xox}xQ#=y2IJT{dDX#;#kR8+ixnSi1^%}vWn_Egx^_`e>t|j1QJ5D1iYz@@@Yym_c>aAme zb9DHaq!VvXdH6jw?V@`zCstfkWe@NyOm#CJ&Bci)_yYo1=-RDP}&6BQ0 z0$PjJQ=L;+`-nhj9Gff*au9|S2@F&IB;KMT&OY$J zYc#s4U?4pp$Y_};HpkFN0?`Wd77&@7!%m~U)0`H0PUlSyq94wInELX;C4W+`c~*9v z#bt*rv(pGC5iY^{Rmf~fgqQcUN&0|X*cWg-nu+SinYZyrBMk=a-b90`TyD!mE`?Qc zCTQLOWALGAHW`?1LXpXO=B8l>FGHHiz7vi?5;Kk=-7QX(W8}vt3l?&+b=FY5CP00B zlDsY29%675gS&xY^jL+y@bot*+Q6;18oo0LmEtAD3#8CCNRZ_}-}&xufBP<9>@abP zR`3z<$v0X{+PCv8X8p+5h5T*E0mDABS55-nvE&`&Puwozi;TX&&xFKW$4cyVy& zy=jBPDO`k$MiJz_Nzg6bqt_MAVtyI}!fk7VU@b9?`y9e&GOVy+1p@2$HC?SSF8kwH*eu-EJU0VuYYWQ@kRz9*1=B5>LjzdG9lkh4D*C)^eQ=? z>@=t2{8~OZV~Ui>?#ay9EoIo!soYc_6GU<_JXSd~VHrYYp&es)y6-g%nYL zdHD6=(^nIuA*Og(%O3%SKJc7mEybV|5fC~30vAb7UfkVWU7R4)BOTz|b#{=gUbU`h8_php!>Q0{Bl z`SmL+vOj$K_~FyTqo|G9tCcc)(@Ghm6Ggd*i-a8na}mz?RTSg>$ zOycwNUQHelJ6sXTx`wBtJdIWqcD}8?5S_|@*n4(#_~P*3X!rU4{{Hi4M-Sg0JU^SM zsk8H>8e4Q82t5t(AlfHnmDk}p1sF2xg4N1F)<%(H2qs`jj5rg2nng%B76QL}sqEBD zvnS_^B>i4E)F8`f=HeG=s=mHmw!|hFh!VyA-Rb>OdpA?JqCZ#?NcLKCrTCuyVG+A+ zj838jiunEm-yC=lGH$sp((xT4=dON8wgWCNcSS*sf~U2W*zYaB-#a=zElPAS2(mwa zK}PPF0WKgbOl{89D~IC07Hk}%+vMh@8>1OjHZ9)8t13%5oBpyR! zRRqyJ5C^*DKw{=7BbyrD>xq5xJlD0tq{P6z4smt63 zlVL7?^yW!lA?JL8hhXMv#A}bbgoCpCuFK4rXQ;Rxy_q9y9Kbs&wWDamSSNH_2l}pN z-B-%2q>|?BD>{CxzkdFQ1Hjag#;aq3o*%v_`sOK$4gZufS3-}GFLo37MJ`9N6Vdgw z6y;UC$|@2uicVxhe99O`DWz}(s5WezTiOjtdi??!Oi|qC>b7bhbqe2|DbO`YIuVTx4qU#%`5#k^LQz$JBlcfG|L_ z4&10J<$Z77{qy1M^OwJyf7Mfg)<0dJxLNFrP1%9HyTjoiXAb7$m1Egbzmv|hJ*5pM zOtxXcN!5mNELuAe*#IeHpk3QLkeRbG2@^OdnJ~;vMY=WGQjI5;Fsgv%0ks;Ta$9|& z0q7#`b8q}5b2ryupY+5*7lB>Hw2TMP~Ms=#X96=h{8Gh*bM(J+LJR6Do>tbEt(x$UxVMjygTn? zT|dfAX{cv+a~!178gZmC&J|)^y*<7^JCpq5tJ}Muc6NU|S}cy_KhLzqP0!3y_Mg`e ze|`S`81%mT+Ziu-CGG|Cv|C&RI@T7;Z|b5dyt%$Xjic_x&UZA<6*^xaQ-CjqS|bBF zDze56T3+n$d50Eh&qD9alN^9JIbXopehCB8f4O}4#ocEaofFMO(!_}DTlzoPj8u0Q zoN3|36tBvN6XC@+UXX)q1Y||C(B1L*0g-Yry;$CDDiyU&r!W?`6^;(Y-Ti0U5TBj4 z&1RPe{-KLD;P}oB%tql*1OX&&swl(rZCJ%2@i$jPaxh^Vxq74u+}l$n=;)x-G{#&j<-j z8RuHqY}Mi3?)vZl_-M2sPp8vfqEApm6dywoRIN%gUs^gGG(oYE(T)UNaaKQm+Tm|d zFZ9nxQxT+>R(7D7n>NMiW>>a8Y(p^w=azeV3pc4Ca(2?}nOcra7HkGkz7jcOgA2Y1 zGT1{UKLJ(TQ{$n1=+Y81pLtT{d$Zp2`C4jZ#6AbyIHnMGo#q1B+*}MKqvoh@zg+<; zyT8#}Z_8&7lr7{{nyV$ei-T3hlnEUuO9mlCh;#7uG>H$;zsK@$?@D%KiH1aH z65@FB{=u%tE6{cGIB&n{f2RD{?GqGF!8zaU z7PoLO)jsm}(d2;+*5|#uQB;5|EhNWUbO3!Tk0%V}H#cG@^H^*@-4I`!4

D)HU4` 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 YHVlO2(c&ylkdK~ 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 literal 0 HcmV?d00001 diff --git a/components/nfc/t2t_parser/nfc_t2t_parser.c b/components/nfc/t2t_parser/nfc_t2t_parser.c new file mode 100644 index 0000000..6b448c5 --- /dev/null +++ b/components/nfc/t2t_parser/nfc_t2t_parser.c @@ -0,0 +1,679 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_common.h" +#if NRF_MODULE_ENABLED(NFC_T2T_PARSER) + +#include +#include +#include "nrf_delay.h" +#include "nfc_t2t_parser.h" + +#define NRF_LOG_MODULE_NAME "NFC_T2T_PARSER" +#if NFC_T2T_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T2T_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T2T_PARSER_INFO_COLOR +#else // NFC_T2T_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_T2T_PARSER_LOG_ENABLED +#include "nrf_log.h" + +/// Gets least significant nibble (a 4-bit value) from a byte. +#define LSN_GET(val) (val & 0x0F) + +/// Gets most significant nibble (a 4-bit value) from a byte. +#define MSN_GET(val) ((val >> 4) & 0x0F) + +/** + * @brief Function for inserting the TLV block into a @ref type_2_tag_t structure. + * + * The content of a TLV block structure pointed by the p_tlv_block is copied into a TLV block + * array within the structure pointed by the p_type_2_tag. + * + * @param[in,out] p_type_2_tag Pointer to the structure that contains the TLV blocks array. + * @param[in] p_tlv_block Pointer to the TLV block to insert. + * + * @retval NRF_SUCCESS If the block was inserted successfully. + * @retval NRF_ERROR_NO_MEM If there is already maximum number of blocks stored in the array. + * + */ +static ret_code_t type_2_tag_tlv_block_insert(type_2_tag_t * p_type_2_tag, + tlv_block_t * p_tlv_block) +{ + if (p_type_2_tag->tlv_count == p_type_2_tag->max_tlv_blocks) + { + return NRF_ERROR_NO_MEM; + } + + // Copy contents of the source block. + p_type_2_tag->p_tlv_block_array[p_type_2_tag->tlv_count] = *p_tlv_block; + p_type_2_tag->tlv_count++; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for checking if the TLV block length is correct. + * + * Some TLV block has predefined length: + * TLV_NULL and TLV_TERMINATOR always have a length of 1 byte. + * TLV_LOCK_CONTROL and TLV_MEMORY_CONTROL always have a length of 3 bytes. + * + * @param[in] p_block_to_check Pointer to the structure that contains the TLV block length. + * + * @retval TRUE If the length is correct. + * @retval FALSE Otherwise. + * + */ +static bool tlv_block_is_data_length_correct(tlv_block_t * p_block_to_check) +{ + switch (p_block_to_check->tag) + { + case TLV_NULL: + case TLV_TERMINATOR: + if (p_block_to_check->length != TLV_NULL_TERMINATOR_LEN) + { + return false; + } + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + if (p_block_to_check->length != TLV_LOCK_MEMORY_CTRL_LEN) + { + return false; + } + break; + + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Any length will do. + break; + } + + return true; +} + +/** + * @brief Function for checking if the end of the tag data area was reached. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the data area size. + * @param[in] offset Current byte offset. + * + * @retval TRUE If the offset indicates the end of the data area. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_end_reached(type_2_tag_t * p_type_2_tag, uint16_t offset) +{ + return offset == (p_type_2_tag->cc.data_area_size + T2T_FIRST_DATA_BLOCK_OFFSET); +} + + +/** + * @brief Function for checking if version of Type 2 Tag specification read from a tag is supported. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the tag version. + * + * @retval TRUE If the version is supported and tag data can be parsed. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_version_supported(type_2_tag_t * p_type_2_tag) +{ + // Simple check atm, as only 1 major version has been issued so far, so no backward compatibility + // is needed, tags with newer version implemented shall be rejected according to the doc. + return p_type_2_tag->cc.major_version == T2T_SUPPORTED_MAJOR_VERSION; +} + + +/** + * @brief Function for checking if the field fits into the data area specified in + * the Capability Container. + * + * @param[in] p_type_2_tag Pointer to the structure that contains the data area size. + * @param[in] offset As Offset of the field to check. + * @param[in] field_length Length of the field to check. + * + * @retval TRUE If the field fits into the data area. + * @retval FALSE If the field exceeds the data area. + * + */ +static bool type_2_tag_is_field_within_data_range(type_2_tag_t * p_type_2_tag, + uint16_t offset, + uint16_t field_length) +{ + // Invalid argument, return false. + if (field_length == 0) + { + return false; + } + return ( (offset + field_length - 1) < + (p_type_2_tag->cc.data_area_size + T2T_FIRST_DATA_BLOCK_OFFSET) ) + && ( offset >= T2T_FIRST_DATA_BLOCK_OFFSET ); +} + + +/** + * @brief Function for reading the tag field of a TLV block from the p_raw_data buffer. + * + * This function reads the tag field containing a TLV block type and inserts its value into + * a structure pointed by the p_tlv_buf pointer. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_t_offset As input: offset of the tag field to read. As output: offset of + * the first byte after the tag field. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the tag type will be + * inserted. + * + * @retval NRF_SUCCESS If the tag field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the tag field at specified offset exceeds the data + * area specified in the Capability Container. + * + */ +static ret_code_t type_2_tag_type_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_t_offset, + tlv_block_t * p_tlv_buf) +{ + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_t_offset, TLV_T_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->tag = p_raw_data[*p_t_offset]; + *p_t_offset += TLV_T_LENGTH; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading the length field of a TLV block from the p_raw_data buffer. + * + * This function reads the length field of a TLV block and inserts its value into a structure + * pointed by the p_tlv_buf pointer. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_l_offset As input: offset of the length field to read. As output: offset of + * the first byte after the length field. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the length will be + * inserted. + * + * @retval NRF_SUCCESS If the length field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the length field at specified offset exceeds the data + * area specified in the Capability Container or has + * incorrect format. + * + */ +static ret_code_t type_2_tag_length_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_l_offset, + tlv_block_t * p_tlv_buf) +{ + uint16_t length; + + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_l_offset, TLV_L_SHORT_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + length = p_raw_data[*p_l_offset]; + + if (length == TLV_L_FORMAT_FLAG) + { + // Check another two bytes. + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_l_offset, TLV_L_LONG_LENGTH)) + { + return NRF_ERROR_INVALID_DATA; + } + + length = uint16_big_decode(&p_raw_data[*p_l_offset + 1]); + + // Long length value cannot be lower than 0xFF. + if (length < 0xFF) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->length = length; + *p_l_offset += TLV_L_LONG_LENGTH; + + } + else + { + p_tlv_buf->length = length; + *p_l_offset += TLV_L_SHORT_LENGTH; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading a pointer to the value field of a TLV block from the p_raw_data buffer. + * + * This function reads a pointer to the value field of a TLV block and inserts it into + * a structure pointed by the p_tlv_buf pointer. If there is no value field present in the + * TLV block, NULL is inserted. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_v_offset As input: offset of the value field to read. As output: offset of + * the first byte after the value field. + * @param[in,out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the value field + * pointer will be inserted. + * + * @retval NRF_SUCCESS If the value field at specified offset is correct. + * @retval NRF_ERROR_INVALID_DATA If the value field at specified offset exceeds the data + * area specified in the Capability Container. + * + */ +static ret_code_t type_2_tag_value_ptr_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_v_offset, + tlv_block_t * p_tlv_buf) +{ + if (p_tlv_buf->length == 0) + { + // Clear the value pointer, don't touch the offset. + p_tlv_buf->p_value = NULL; + } + else + { + if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_v_offset, p_tlv_buf->length)) + { + return NRF_ERROR_INVALID_DATA; + } + + p_tlv_buf->p_value = p_raw_data + *p_v_offset; + *p_v_offset += p_tlv_buf->length; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for reading a single TLV block from the p_raw_data buffer. + * + * This function reads a single TLV block from the p_raw_data buffer and stores its contents in a + * structure pointed by the p_tlv_buf. + * + * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far. + * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag. + * @param[in,out] p_tlv_offset As input: offset of the TLV block to read. As output: offset of the + * next TLV block, 0 if it was the last block. + * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure that will be filled with + * the data read. + * + * @retval NRF_SUCCESS If the parsing operation of the block succeeded. Otherwise, an error + * code is returned. + * + */ +static ret_code_t type_2_tag_tlv_block_extract(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_offset, + tlv_block_t * p_tlv_buf) +{ + ret_code_t err_code; + memset(p_tlv_buf, 0, sizeof(tlv_block_t)); + + // TLV Tag field. + err_code = type_2_tag_type_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + // Further processing depends on tag field value. + switch (p_tlv_buf->tag) + { + case TLV_NULL: + // Simply ignore NULL blocks, leave the incremented offset. + break; + + case TLV_TERMINATOR: + // Write 0 to the offset variable, indicating that last TLV block was found. + *p_offset = 0; + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Unknown blocks should also be extracted. + err_code = type_2_tag_length_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (p_tlv_buf->length > 0) + { + err_code = type_2_tag_value_ptr_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + break; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for checking the checksum bytes of the UID stored in internal area. + * + * This function calculates the block check character (BCC) bytes based on the parsed serial number + * and compares them with bytes read from the Type 2 Tag. + * + * @param[in] p_sn Pointer to the @ref type_2_tag_serial_number_t structure to check. + * + * @retval TRUE If the calculated BCC matched the BCC from the tag. + * @retval FALSE Otherwise. + * + */ +static bool type_2_tag_is_bcc_correct(type_2_tag_serial_number_t * p_sn) +{ + uint8_t bcc1 = (uint8_t)T2T_UID_BCC_CASCADE_BYTE ^ + (uint8_t)p_sn->manufacturer_id ^ + (uint8_t)((p_sn->serial_number_part_1 >> 8) & 0xFF) ^ + (uint8_t)(p_sn->serial_number_part_1 & 0xFF); + + uint8_t bcc2 = (uint8_t)((p_sn->serial_number_part_2 >> 24) & 0xFF) ^ + (uint8_t)((p_sn->serial_number_part_2 >> 16) & 0xFF) ^ + (uint8_t)((p_sn->serial_number_part_2 >> 8) & 0xFF) ^ + (uint8_t)( p_sn->serial_number_part_2 & 0xFF); + + return (bcc1 == p_sn->check_byte_0) && (bcc2 == p_sn->check_byte_1); +} + + +/** + * @brief Function for parsing an internal area of a Type 2 Tag. + * + * This function reads data from an internal area in the raw data buffer and fills the + * @ref type_2_tag_serial_number_t structure within @ref type_2_tag_t. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * + * @retval NRF_SUCCESS If the parsing operation of the internal area succeeded. + * Otherwise, an error code is returned. + * + */ +static ret_code_t type_2_tag_internal_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + p_type_2_tag->sn.manufacturer_id = p_raw_data[0]; + p_type_2_tag->sn.serial_number_part_1 = uint16_big_decode(&p_raw_data[1]); + p_type_2_tag->sn.check_byte_0 = p_raw_data[3]; + p_type_2_tag->sn.serial_number_part_2 = uint32_big_decode(&p_raw_data[4]); + p_type_2_tag->sn.check_byte_1 = p_raw_data[8]; + p_type_2_tag->sn.internal = p_raw_data[9]; + + p_type_2_tag->lock_bytes = uint16_big_decode(&p_raw_data[10]); + + if (!type_2_tag_is_bcc_correct(&p_type_2_tag->sn)) + { + NRF_LOG_WARNING("Warning! BCC of the serial number is not correct!\r\n"); + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for parsing a Capabiliy Container area of a Type 2 Tag. + * + * This function reads data from a Capability Container area in the raw data buffer and fills the + * @ref type_2_tag_capability_container_t structure within @ref type_2_tag_t. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * + * @retval NRF_SUCCESS If the parsing operation of the Capability Container succeeded. + * Otherwise, an error code is returned. + * + */ +static ret_code_t type_2_tag_cc_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + uint8_t * p_cc_block = p_raw_data + T2T_CC_BLOCK_OFFSET; + + if (p_cc_block[0] != T2T_NFC_FORUM_DEFINED_DATA) + { + return NRF_ERROR_INVALID_DATA; + } + + p_type_2_tag->cc.major_version = MSN_GET(p_cc_block[1]); + p_type_2_tag->cc.minor_version = LSN_GET(p_cc_block[1]); + p_type_2_tag->cc.data_area_size = p_cc_block[2] * 8; + p_type_2_tag->cc.read_access = MSN_GET(p_cc_block[3]); + p_type_2_tag->cc.write_access = LSN_GET(p_cc_block[3]); + + return NRF_SUCCESS; +} + + +/** + * @brief Function for parsing a single TLV block. + * + * This function reads a single TLV block from the raw data buffer, from the position indicated by + * the p_tlv_offset, and adds it to the @ref type_2_tag_t structure. + * + * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag. + * @param[in,out] p_tlv_offset As input: offset of the TLV block to parse. As output: offset of the + * next TLV block, 0 if it was the last block. + * + * @retval NRF_SUCCESS If the parsing operation of the block succeeded. Otherwise, an error + * code is returned. + * + */ +static ret_code_t type_2_tag_tlv_parse(type_2_tag_t * p_type_2_tag, + uint8_t * p_raw_data, + uint16_t * p_tlv_offset) +{ + ret_code_t err_code; + tlv_block_t new_block; + + // Get tag field. + err_code = type_2_tag_tlv_block_extract(p_type_2_tag, p_raw_data, p_tlv_offset, &new_block); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!tlv_block_is_data_length_correct(&new_block)) + { + return NRF_ERROR_INVALID_DATA; + } + + // Further action depends on tag type. + switch (new_block.tag) + { + case TLV_NULL: + case TLV_TERMINATOR: + // Ignore them. + break; + + case TLV_LOCK_CONTROL: + case TLV_MEMORY_CONTROL: + case TLV_NDEF_MESSAGE: + case TLV_PROPRIETARY: + default: + // Unknown tag types are also added. + err_code = type_2_tag_tlv_block_insert(p_type_2_tag, &new_block); + if (err_code != NRF_SUCCESS) + { + NRF_LOG_WARNING("Warning! Not enough memory to insert all of the blocks!\r\n"); + return err_code; + } + break; + } + + return NRF_SUCCESS; +} + + +void type_2_tag_clear(type_2_tag_t * p_type_2_tag) +{ + p_type_2_tag->tlv_count = 0; + memset(&p_type_2_tag->cc, 0, sizeof(p_type_2_tag->cc)); + memset(&p_type_2_tag->sn, 0, sizeof(p_type_2_tag->sn)); +} + + +ret_code_t type_2_tag_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data) +{ + ret_code_t err_code; + + type_2_tag_clear(p_type_2_tag); + + err_code = type_2_tag_internal_parse(p_type_2_tag, p_raw_data); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + err_code = type_2_tag_cc_parse(p_type_2_tag, p_raw_data); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + + if (!type_2_tag_is_version_supported(p_type_2_tag)) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint16_t offset = T2T_FIRST_DATA_BLOCK_OFFSET; + + while (offset > 0) + { + // Check if end of tag is reached (no terminator block was present). + if (type_2_tag_is_end_reached(p_type_2_tag, offset)) + { + NRF_LOG_DEBUG("No terminator block was found in the tag!\r\n"); + break; + } + + err_code = type_2_tag_tlv_parse(p_type_2_tag, p_raw_data, &offset); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + return NRF_SUCCESS; +} + + +void type_2_tag_printout(type_2_tag_t * p_type_2_tag) +{ + uint32_t i; + NRF_LOG_INFO("Type 2 Tag contents:\r\n\r\n"); + NRF_LOG_INFO("Number of TLV blocks: %d\r\n\r\n", p_type_2_tag->tlv_count); + + NRF_LOG_INFO("Internal data:\r\n"); + NRF_LOG_INFO(" Manufacturer ID: 0x%02x\r\n", p_type_2_tag->sn.manufacturer_id); + NRF_LOG_INFO(" Serial number part 1: 0x%04x\r\n", p_type_2_tag->sn.serial_number_part_1); + NRF_LOG_INFO(" Check byte 0: 0x%02x\r\n", p_type_2_tag->sn.check_byte_0); + NRF_LOG_INFO(" Serial number part 2: 0x%08lx\r\n", p_type_2_tag->sn.serial_number_part_2); + NRF_LOG_INFO(" Check byte 1: 0x%02x\r\n", p_type_2_tag->sn.check_byte_1); + NRF_LOG_INFO(" Internal byte: 0x%02x\r\n", p_type_2_tag->sn.internal); + NRF_LOG_INFO(" Lock bytes: 0x%04x\r\n\r\n", p_type_2_tag->lock_bytes); + + NRF_LOG_INFO("Capability Container data:\r\n"); + NRF_LOG_INFO(" Major version number: %d\r\n", p_type_2_tag->cc.major_version); + NRF_LOG_INFO(" Minor version number: %d\r\n", p_type_2_tag->cc.minor_version); + NRF_LOG_INFO(" Data area size: %d\r\n", p_type_2_tag->cc.data_area_size); + NRF_LOG_INFO(" Read access: 0x%02X\r\n", p_type_2_tag->cc.read_access); + NRF_LOG_INFO(" Write access: 0x%02X\r\n\r\n", p_type_2_tag->cc.write_access); + + for (i = 0; i < p_type_2_tag->tlv_count; i++) + { + NRF_LOG_INFO("TLV block 0x%02X: \r\n", p_type_2_tag->p_tlv_block_array[i].tag); + switch (p_type_2_tag->p_tlv_block_array[i].tag) + { + case TLV_LOCK_CONTROL: + NRF_LOG_INFO("Lock Control\r\n\r\n"); + break; + case TLV_MEMORY_CONTROL: + NRF_LOG_INFO("Memory Control\r\n\r\n"); + break; + case TLV_NDEF_MESSAGE: + NRF_LOG_INFO("NDEF Message\r\n\r\n"); + break; + case TLV_PROPRIETARY: + NRF_LOG_INFO("Proprietary\r\n\r\n"); + break; + case TLV_NULL: + NRF_LOG_INFO("Null\r\n\r\n"); + break; + case TLV_TERMINATOR: + NRF_LOG_INFO("Terminator\r\n\r\n"); + break; + default: + NRF_LOG_INFO("Unknown\r\n\r\n"); + break; + } + + NRF_LOG_INFO(" Length: %d\r\n", p_type_2_tag->p_tlv_block_array[i].length); + + if (p_type_2_tag->p_tlv_block_array[i].length > 0) + { + NRF_LOG_INFO(" Data:\r\n"); + NRF_LOG_HEXDUMP_INFO(p_type_2_tag->p_tlv_block_array[i].p_value, + p_type_2_tag->p_tlv_block_array[i].length); + } + NRF_LOG_INFO("\r\n\r\n"); + } +} + +#endif // NRF_MODULE_ENABLED(NFC_T2T_PARSER) diff --git a/components/nfc/t2t_parser/nfc_t2t_parser.h b/components/nfc/t2t_parser/nfc_t2t_parser.h new file mode 100644 index 0000000..d59e211 --- /dev/null +++ b/components/nfc/t2t_parser/nfc_t2t_parser.h @@ -0,0 +1,196 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_TYPE_2_TAG_PARSER_H__ +#define NFC_TYPE_2_TAG_PARSER_H__ + +#include +#include "nfc_tlv_block.h" +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nfc_type_2_tag Type 2 Tag + * @{ + * @ingroup nfc_type_2_tag_parser + * + * @brief Descriptor for a Type 2 Tag. + * + */ + +/** + * @brief Descriptor for the internal bytes of a Type 2 Tag. + */ +typedef struct +{ + uint8_t manufacturer_id; ///< Manufacturer ID (the most significant byte of the UID/serial number). + uint16_t serial_number_part_1; ///< Bytes 5-4 of the tag UID. + uint8_t check_byte_0; ///< First block check character byte (XOR of the cascade tag byte, manufacturer ID byte, and the serial_number_part_1 bytes). + uint32_t serial_number_part_2; ///< Bytes 3-0 of the tag UID. + uint8_t check_byte_1; ///< Second block check character byte (XOR of the serial_number_part_2 bytes). + uint8_t internal; ///< Tag internal bytes. +} type_2_tag_serial_number_t; + +/** + * @brief Descriptor for the Capability Container (CC) bytes of a Type 2 Tag. + */ +typedef struct +{ + uint8_t major_version; ///< Major version of the supported Type 2 Tag specification. + uint8_t minor_version; ///< Minor version of the supported Type 2 Tag specification. + uint16_t data_area_size; ///< Size of the data area in bytes. + uint8_t read_access; ///< Read access for the data area. + uint8_t write_access; ///< Write access for the data area. +} type_2_tag_capability_container_t; + +/** + * @brief Type 2 Tag descriptor. + */ +typedef struct +{ + type_2_tag_serial_number_t sn; ///< Values within the serial number area of the tag. + uint16_t lock_bytes; ///< Value of the lock bytes. + type_2_tag_capability_container_t cc; ///< Values within the Capability Container area of the tag. + + uint16_t const max_tlv_blocks; ///< Maximum number of TLV blocks that can be stored. + tlv_block_t * p_tlv_block_array; ///< Pointer to the array for TLV blocks. + uint16_t tlv_count; ///< Number of TLV blocks stored in the Type 2 Tag. + +} type_2_tag_t; + +/** + * @brief Macro for creating and initializing a Type 2 Tag descriptor. + * + * This macro creates and initializes a static instance of a @ref type_2_tag_t structure and + * an array of @ref tlv_block_t descriptors. + * + * Use the macro @ref NFC_TYPE_2_TAG_DESC to access the Type 2 Tag descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] MAX_BLOCKS Maximum number of @ref tlv_block_t descriptors that can be stored in the array. + * + */ +#define NFC_TYPE_2_TAG_DESC_DEF(NAME, MAX_BLOCKS) \ + static tlv_block_t NAME##_tlv_block_array[MAX_BLOCKS]; \ + static type_2_tag_t NAME##_type_2_tag = \ + { \ + .max_tlv_blocks = MAX_BLOCKS, \ + .p_tlv_block_array = NAME##_tlv_block_array, \ + .tlv_count = 0 \ + } + +/** + * @brief Macro for accessing the @ref type_2_tag_t instance that was created + * with @ref NFC_TYPE_2_TAG_DESC_DEF. + */ +#define NFC_TYPE_2_TAG_DESC(NAME) (NAME##_type_2_tag) + + +#define T2T_NFC_FORUM_DEFINED_DATA 0xE1 ///< Value indicating that the Type 2 Tag contains NFC Forum defined data. +#define T2T_UID_BCC_CASCADE_BYTE 0x88 ///< Value used for calculating the first BCC byte of a Type 2 Tag serial number. + +#define T2T_SUPPORTED_MAJOR_VERSION 1 ///< Supported major version of the Type 2 Tag specification. +#define T2T_SUPPORTED_MINOR_VERSION 2 ///< Supported minor version of the Type 2 Tag specification. + +#define T2T_BLOCK_SIZE 4 ///< Type 2 Tag block size in bytes. + +#define T2T_CC_BLOCK_OFFSET 12 ///< Offset of the Capability Container area in the Type 2 Tag. +#define T2T_FIRST_DATA_BLOCK_OFFSET 16 ///< Offset of the data area in the Type 2 Tag. + +/** + * @} + */ + + +/** + * @defgroup nfc_type_2_tag_parser NFC Type 2 Tag parser + * @{ + * @ingroup nfc_t2t + * + * @brief Parser for Type 2 Tag data. + * + */ + +/** + * @brief Function for clearing the @ref type_2_tag_t structure. + * + * @param[in,out] p_type_2_tag Pointer to the structure that should be cleared. + * + */ +void type_2_tag_clear(type_2_tag_t * p_type_2_tag); + +/** + * @brief Function for parsing raw data read from a Type 2 Tag. + * + * This function parses the header and the following TLV blocks of a Type 2 Tag. The data is read + * from a buffer and stored in a @ref type_2_tag_t structure. + * + * @param[out] p_type_2_tag Pointer to the structure that will be filled with parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data from the tag (should + * point at the first byte of the first block of the tag). + * + * @retval NRF_SUCCESS If the data was parsed successfully. + * @retval NRF_ERROR_NO_MEM If there is not enough memory to store all of the TLV blocks. + * @retval Other If an error occurred during the parsing operation. + * + */ +ret_code_t type_2_tag_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data); + +/** + * @brief Function for printing parsed contents of the Type 2 Tag. + * + * @param[in] p_type_2_tag Pointer to the structure that should be printed. + * + */ +void type_2_tag_printout(type_2_tag_t * p_type_2_tag); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_TYPE_2_TAG_PARSER_H__ */ diff --git a/components/nfc/t2t_parser/nfc_tlv_block.h b/components/nfc/t2t_parser/nfc_tlv_block.h new file mode 100644 index 0000000..f399e63 --- /dev/null +++ b/components/nfc/t2t_parser/nfc_tlv_block.h @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_TLV_BLOCK_H__ +#define NFC_TLV_BLOCK_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@file + * + * @defgroup nfc_type_2_tag_tlv_block Type 2 Tag TLV blocks + * @{ + * @ingroup nfc_type_2_tag_parser + * + * @brief Descriptor for a Type 2 Tag TLV block. + * + */ + +/** + * @brief Tag field values. + * + * Possible values for the tag field in a TLV block. + */ +typedef enum +{ + TLV_NULL = 0x00, ///< Might be used for padding of memory areas. + TLV_LOCK_CONTROL = 0x01, ///< Defines details of the lock bits. + TLV_MEMORY_CONTROL = 0x02, ///< Identifies reserved memory areas. + TLV_NDEF_MESSAGE = 0x03, ///< Contains an NDEF message. + TLV_PROPRIETARY = 0xFD, ///< Tag proprietary information. + TLV_TERMINATOR = 0xFE ///< Last TLV block in the data area. +} tlv_block_types_t; + +/** + * @brief TLV block descriptor. + */ +typedef struct +{ + uint8_t tag; ///< Type of the TLV block. + uint16_t length; ///< Length of the value field. + uint8_t * p_value; ///< Pointer to the value field (NULL if no value field is present in the block). +} tlv_block_t; + +#define TLV_T_LENGTH 1 ///< Length of a tag field. + +#define TLV_L_SHORT_LENGTH 1 ///< Length of a short length field. +#define TLV_L_LONG_LENGTH 3 ///< Length of an extended length field. +#define TLV_L_FORMAT_FLAG 0xFF ///< Value indicating the use of an extended length field. + +#define TLV_NULL_TERMINATOR_LEN 0 ///< Predefined length of the NULL and TERMINATOR TLV blocks. +#define TLV_LOCK_MEMORY_CTRL_LEN 3 ///< Predefined length of the LOCK CONTROL and MEMORY CONTROL blocks. + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_TLV_BLOCK_H__ */ diff --git a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c b/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c new file mode 100644 index 0000000..4119dbd --- /dev/null +++ b/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c @@ -0,0 +1,260 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if NFC_T4T_APDU_ENABLED + +#include "nfc_t4t_apdu.h" +#include "sdk_macros.h" +#include "nordic_common.h" +#include "app_util.h" + +#define NRF_LOG_MODULE_NAME "NFC_T4T_APDU" +#if NFC_T4T_APDU_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_APDU_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_APDU_LOG_COLOR +#else // NFC_T4T_APDU_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_T4T_APDU_LOG_ENABLED +#include "nrf_log.h" + +/** + * @brief Field sizes that can be present in CAPDU. + */ +#define CLASS_TYPE_SIZE 1U +#define INSTRUCTION_TYPE_SIZE 1U +#define PARAMETER_SIZE 2U +#define LC_SHORT_FORMAT_SIZE 1U +#define LC_LONG_FORMAT_SIZE 3U +#define LE_SHORT_FORMAT_SIZE 1U +#define LE_LONG_FORMAT_SIZE 2U + +/** + * @brief Values used to encode Lc field in CAPDU. + */ +#define LC_LONG_FORMAT_TOKEN 0x00 +#define LC_LONG_FORMAT_THR 0xFF + +/** + * @brief Values used to encode Le field in CAPDU. + */ +#define LE_FIELD_ABSENT 0U +#define LE_LONG_FORMAT_THR 0x0100 +#define LE_ENCODED_VAL_256 0x00 + + +#define STATUS_SIZE 2U ///< Size of Status field contained in RAPDU. + +/** + * @brief Function for calculating size of CAPDU. + */ +__STATIC_INLINE uint16_t nfc_t4t_comm_apdu_size_calc(nfc_t4t_comm_apdu_t const * const p_cmd_apdu) +{ + uint16_t res = CLASS_TYPE_SIZE + INSTRUCTION_TYPE_SIZE + PARAMETER_SIZE; + if (p_cmd_apdu->data.p_buff != NULL) + { + if (p_cmd_apdu->data.len > LC_LONG_FORMAT_THR) + { + res += LC_LONG_FORMAT_SIZE; + } + else + { + res += LC_SHORT_FORMAT_SIZE; + } + } + res += p_cmd_apdu->data.len; + if (p_cmd_apdu->resp_len != LE_FIELD_ABSENT) + { + if (p_cmd_apdu->resp_len > LE_LONG_FORMAT_THR) + { + res += LE_LONG_FORMAT_SIZE; + } + else + { + res += LE_SHORT_FORMAT_SIZE; + } + } + return res; +} + + +/** + * @brief Function for validating arguments used by CAPDU encoding procedure. + */ +__STATIC_INLINE ret_code_t nfc_t4t_comm_apdu_args_validate(nfc_t4t_comm_apdu_t const * const p_cmd_apdu, + uint8_t * p_raw_data, + uint16_t * const p_len) +{ + if((p_cmd_apdu == NULL) || (p_raw_data == NULL) || (p_len == NULL)) + { + return NRF_ERROR_NULL; + } + + if ((p_cmd_apdu->data.p_buff != NULL) && (p_cmd_apdu->data.len == 0)) + { + return NRF_ERROR_INVALID_PARAM; + } + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_comm_apdu_encode(nfc_t4t_comm_apdu_t const * const p_cmd_apdu, + uint8_t * p_raw_data, + uint16_t * const p_len) +{ + // Validate passed arguments. + ret_code_t err_code = nfc_t4t_comm_apdu_args_validate(p_cmd_apdu, p_raw_data, p_len); + VERIFY_SUCCESS(err_code); + + // Check if there is enough memory in the provided buffer to store described CAPDU. + uint16_t comm_apdu_len = nfc_t4t_comm_apdu_size_calc(p_cmd_apdu); + if (comm_apdu_len > *p_len) + { + return NRF_ERROR_NO_MEM; + } + *p_len = comm_apdu_len; + + // Start to encode described CAPDU in the buffer. + *p_raw_data++ = p_cmd_apdu->class_byte; + *p_raw_data++ = p_cmd_apdu->instruction; + *p_raw_data++ = MSB_16(p_cmd_apdu->parameter); + *p_raw_data++ = LSB_16(p_cmd_apdu->parameter); + + // Check if optional data field should be included. + if (p_cmd_apdu->data.p_buff != NULL) + { + if (p_cmd_apdu->data.len > LC_LONG_FORMAT_THR) // Use long data length encoding. + { + *p_raw_data++ = LC_LONG_FORMAT_TOKEN; + *p_raw_data++ = MSB_16(p_cmd_apdu->data.len); + *p_raw_data++ = LSB_16(p_cmd_apdu->data.len); + } + else // Use short data length encoding. + { + *p_raw_data++ = LSB_16(p_cmd_apdu->data.len); + } + memcpy(p_raw_data, p_cmd_apdu->data.p_buff, p_cmd_apdu->data.len); + p_raw_data += p_cmd_apdu->data.len; + } + + // Check if optional response length field present (Le) should be included. + if (p_cmd_apdu->resp_len != LE_FIELD_ABSENT) + { + if (p_cmd_apdu->resp_len > LE_LONG_FORMAT_THR) // Use long response length encoding. + { + *p_raw_data++ = MSB_16(p_cmd_apdu->resp_len); + *p_raw_data++ = LSB_16(p_cmd_apdu->resp_len); + } + else // Use short response length encoding. + { + if (p_cmd_apdu->resp_len == LE_LONG_FORMAT_THR) + { + *p_raw_data++ = LE_ENCODED_VAL_256; + } + else + { + *p_raw_data++ = LSB_16(p_cmd_apdu->resp_len); + } + } + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for validating arguments used by RAPDU decoding procedure. + */ +__STATIC_INLINE ret_code_t nfc_t4t_resp_apdu_args_validate(nfc_t4t_resp_apdu_t const * const p_resp_apdu, + uint8_t const * const p_raw_data, + uint16_t len) +{ + if ((p_resp_apdu == NULL) || (p_raw_data == NULL)) + { + return NRF_ERROR_NULL; + } + + if (len < STATUS_SIZE) + { + return NRF_ERROR_INVALID_LENGTH; + } + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_resp_apdu_decode(nfc_t4t_resp_apdu_t * const p_resp_apdu, + uint8_t const * const p_raw_data, + uint16_t len) +{ + // Validate passed arguments. + ret_code_t err_code = nfc_t4t_resp_apdu_args_validate(p_resp_apdu, p_raw_data, len); + VERIFY_SUCCESS(err_code); + + nfc_t4t_resp_apdu_clear(p_resp_apdu); + if (len != STATUS_SIZE) // Optional data field is present in RAPDU. + { + p_resp_apdu->data.len = len - STATUS_SIZE; + p_resp_apdu->data.p_buff = (uint8_t *) p_raw_data; + } + p_resp_apdu->status = uint16_big_decode(p_raw_data + p_resp_apdu->data.len); + + return NRF_SUCCESS; +} + + +void nfc_t4t_resp_apdu_printout(nfc_t4t_resp_apdu_t * p_resp_apdu) +{ + NRF_LOG_INFO("R-APDU status: %4X \r\n", p_resp_apdu->status); + if (p_resp_apdu->data.p_buff != NULL) + { + NRF_LOG_INFO("R-APDU data: \r\n"); + NRF_LOG_HEXDUMP_INFO(p_resp_apdu->data.p_buff, p_resp_apdu->data.len); + } + else + { + NRF_LOG_INFO("R-APDU no data field present.\r\n"); + } +} + + +#endif // NFC_T4T_APDU_ENABLED + diff --git a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h b/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h new file mode 100644 index 0000000..0ab72c7 --- /dev/null +++ b/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h @@ -0,0 +1,222 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_T4T_APDU_H__ +#define NFC_T4T_APDU_H__ + +/**@file + * + * @defgroup nfc_t4t_apdu APDU reader/writer + * @{ + * @ingroup nfc_t4t_parser + * + * @brief APDU reader/writer for Type 4 Tag communication. + * + */ + +#include +#include +#include "sdk_errors.h" +#include "nrf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CLASS_BYTE_NO_SECURE_MSG 0x00 ///< Class byte indicating no secure messaging, used in C-APDU. + +/** + * @name Parameters used when selecting instruction code in C-APDU. + * @{ + */ +#define SELECT_BY_FILE_ID 0x000C ///< Select by file identifier, first or only occurence. +#define SELECT_BY_NAME 0x0400 ///< Select by name, first or only occurence. +/** @} */ + +/** + * @name Status codes contained in R-APDU. + * @{ + */ +#define RAPDU_STATUS_CMD_COMPLETED 0x9000 ///< Command completed successfully. +#define RAPDU_STATUS_SEL_ITEM_NOT_FOUND 0x6A82 ///< Selected item has not been found. +/** @} */ + +/** + * @brief Possible instruction codes in C-APDU. + */ +typedef enum +{ + NFC_T4T_CAPDU_SELECT_INS = 0xA4, ///< Code used for selecting EF or NDEF application. + NFC_T4T_CAPDU_READ_INS = 0xB0, ///< Code used for selecting EF or NDEF application. + NFC_T4T_CAPDU_UPDATE_INS = 0xD6 ///< Code used for selecting EF or NDEF application. +} nfc_t4t_comm_apdu_ins_type_t; + +/** + * @brief APDU data field descriptor. + */ +typedef struct +{ + uint16_t len; ///< Data field length. + uint8_t * p_buff; ///< Pointer to data field. +} nfc_t4t_apdu_data_t; + +/** + * @brief Command Application Protocol Data Unit (C-APDU) descriptor. + */ +typedef struct +{ + uint8_t class_byte; ///< Class byte. + nfc_t4t_comm_apdu_ins_type_t instruction; ///< The chosen code of instruction. + uint16_t parameter; ///< Parameters associated with the instruction code. + nfc_t4t_apdu_data_t data; ///< Optional data fields (Lc + data bytes). + uint16_t resp_len; ///< Optional response length field (Le). +} nfc_t4t_comm_apdu_t; + +/** + * @brief Response Application Protocol Data Unit (R-APDU) descriptor. + */ +typedef struct +{ + uint16_t status; ///< Mandatory status field. + nfc_t4t_apdu_data_t data; ///< Optional data field. +} nfc_t4t_resp_apdu_t; + +/** + * @brief Macro for verifying R-APDU descriptor status. + * + * This macro verifies R-APDU descriptor status. It will cause the exterior + * function to return nrf_error translated from R-APDU status, if the status is + * not equal to @ref RAPDU_STATUS_CMD_COMPLETED. + * + * @param[in] P_RAPDU Pointer to R-APDU descriptor. + * + * @retval NRF_ERROR_NOT_FOUND If C-APDU select command could not find the selected item. + * @retval NRF_ERROR_INTERNAL Unknown R-APDU error. + */ +#define VERIFY_RAPDU_SUCCESS(P_RAPDU) \ + if (P_RAPDU->status == RAPDU_STATUS_SEL_ITEM_NOT_FOUND) \ + { \ + return NRF_ERROR_NOT_FOUND; \ + } \ + if (P_RAPDU->status != RAPDU_STATUS_CMD_COMPLETED) \ + { \ + return NRF_ERROR_INTERNAL; \ + } + +/** + * @brief Function for clearing C-APDU descriptor and restoring its default values. + * + * @param[in] p_cmd_apdu Pointer to C-APDU descriptor. + */ +__STATIC_INLINE void nfc_t4t_comm_apdu_clear(nfc_t4t_comm_apdu_t * const p_cmd_apdu); + +/** + * @brief Function for clearing R-APDU descriptor and restoring its default values. + * + * @param[in] p_resp_apdu Pointer to R-APDU descriptor. + */ +__STATIC_INLINE void nfc_t4t_resp_apdu_clear(nfc_t4t_resp_apdu_t * const p_resp_apdu); + +/** + * @brief Function for encoding C-APDU. + * + * This function encodes C-APDU according to the provided descriptor. + * + * @param[in] p_cmd_apdu Pointer to the C-APDU descriptor. + * @param[out] p_raw_data Pointer to the buffer with encoded C-APDU. + * @param[in,out] p_len Size of the available memory for the C-APDU as input. + * Size of the generated C-APDU as output. + * + * @retval NRF_SUCCESS If C-APDU was encoded successfully. + * @retval NRF_ERROR_NO_MEM If the predicted C-APDU size is bigger than the provided buffer space. + * @retval NRF_ERROR_INVALID_PARAM If C-APDU descriptor is invalid. + * @retval NRF_ERROR_NULL If any passed argument is NULL. + */ +ret_code_t nfc_t4t_comm_apdu_encode(nfc_t4t_comm_apdu_t const * const p_cmd_apdu, + uint8_t * p_raw_data, + uint16_t * const p_len); + +/** + * @brief Function for decoding R-APDU. + * + * This function decodes buffer with encoded R-APDU and stores results in the R-APDU descriptor. + * + * @param[out] p_resp_apdu Pointer to the R-APDU descriptor. + * @param[in] p_raw_data Pointer to the buffer with encoded R-APDU. + * @param[in] len Size of of the buffer with encoded R-APDU. + * + * @retval NRF_SUCCESS If R-APDU was encoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH If the buffer is too small to hold a valid R-APDU. + * @retval NRF_ERROR_NULL If any passed argument is NULL. + */ +ret_code_t nfc_t4t_resp_apdu_decode(nfc_t4t_resp_apdu_t * const p_resp_apdu, + uint8_t const * const p_raw_data, + uint16_t len); + +/** + * @brief Function for printing a R-APDU descriptor. + * + * This function prints a R-APDU descriptor. + * + * @param[in] p_resp_apdu Pointer to the R-APDU descriptor. + */ +void nfc_t4t_resp_apdu_printout(nfc_t4t_resp_apdu_t * p_resp_apdu); + +#ifndef SUPPRESS_INLINE_IMPLEMENTATION + +__STATIC_INLINE void nfc_t4t_comm_apdu_clear(nfc_t4t_comm_apdu_t * const p_cmd_apdu) +{ + memset(p_cmd_apdu, 0, sizeof(nfc_t4t_comm_apdu_t)); +} + +__STATIC_INLINE void nfc_t4t_resp_apdu_clear(nfc_t4t_resp_apdu_t * const p_resp_apdu) +{ + memset(p_resp_apdu, 0, sizeof(nfc_t4t_resp_apdu_t)); +} + +#endif // SUPPRESS_INLINE_IMPLEMENTATION + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_APDU_H__ */ diff --git a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c b/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c new file mode 100644 index 0000000..4b7d811 --- /dev/null +++ b/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c @@ -0,0 +1,266 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "sdk_config.h" +#if NFC_T4T_CC_FILE_PARSER_ENABLED + +#include +#include "nfc_t4t_cc_file.h" +#include "sdk_macros.h" +#include "nordic_common.h" +#include "app_util.h" + +#define NRF_LOG_MODULE_NAME "NFC_T4T_CC_FILE_PARSER" +#if NFC_T4T_CC_FILE_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_CC_FILE_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_CC_FILE_PARSER_INFO_COLOR +#else // NFC_T4T_CC_FILE_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_T4T_CC_FILE_PARSER_LOG_ENABLED +#include "nrf_log.h" + +/** + * @brief Valid value range for CCLEN field. + */ +#define CC_LEN_MIN_VALUE 0x000F +#define CC_LEN_MAX_VALUE 0xFFFE + +/** + * @brief Valid major versions of Type 4 Tag specification. + */ +#define NFC_T4T_EXTENDED_MAJOR_VER 0x03 ///< Major version number allowing first TLV block to be Extended NDEF File Control TLV +#define NFC_T4T_REGULAR_MAJOR_VER 0x02 ///< Major version number allowing first TLV block to be NDEF File Control TLV + +/** + * @brief Valid value range for MLe field. + */ +#define MLE_LEN_MIN_VALUE 0x000F +#define MLE_LEN_MAX_VALUE 0xFFFF + +/** + * @brief Valid value range for MLc field. + */ +#define MLC_LEN_MIN_VALUE 0x0001 +#define MLC_LEN_MAX_VALUE 0xFFFF + +/** + * @brief Field sizes that are present in CC file. + */ +#define CC_LEN_FIELD_SIZE 2U +#define MAP_VER_FIELD_SIZE 1U +#define MLE_FIELD_SIZE 2U +#define MLC_FIELD_SIZE 2U + +/// Gets least significant nibble (a 4-bit value) from a byte. +#define LSN_GET(val) (val & 0x0F) + +/// Gets most significant nibble (a 4-bit value) from a byte. +#define MSN_GET(val) ((val >> 4) & 0x0F) + +/** + * @brief Function for validating arguments used by CC file parsing procedure. + */ +__STATIC_INLINE ret_code_t nfc_t4t_cc_args_validate(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint8_t * p_raw_data, + uint16_t len) +{ + if ( (p_t4t_cc_file == NULL) + || (p_t4t_cc_file->p_tlv_block_array == NULL) + || (p_raw_data == NULL) ) + { + return NRF_ERROR_NULL; + } + + if ( (len < CC_LEN_MIN_VALUE) || (len > CC_LEN_MAX_VALUE) ) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (p_t4t_cc_file->max_tlv_blocks == 0) + { + return NRF_ERROR_NO_MEM; + } + + return NRF_SUCCESS; +} + + +/** + * @brief Function for validating CC file descriptor content. + */ +__STATIC_INLINE ret_code_t nfc_t4t_cc_file_validate(nfc_t4t_capability_container_t * p_t4t_cc_file) +{ + uint16_t type = p_t4t_cc_file->p_tlv_block_array[0].type; + + if ( (p_t4t_cc_file->major_version == NFC_T4T_EXTENDED_MAJOR_VER + && type == EXTENDED_NDEF_FILE_CONTROL_TLV) || + (p_t4t_cc_file->major_version == NFC_T4T_REGULAR_MAJOR_VER + && type == NDEF_FILE_CONTROL_TLV) ) + { + return NRF_SUCCESS; + } + + return NRF_ERROR_INVALID_DATA; +} + + +/** + * @brief Function for clearing all TLV blocks from CC file descriptor. + */ +__STATIC_INLINE void nfc_t4t_cc_file_clear(nfc_t4t_capability_container_t * p_t4t_cc_file) +{ + p_t4t_cc_file->tlv_count = 0; +} + + +/** + * @brief Function for adding a TLV block to the CC file descriptor. + */ +static ret_code_t nfc_t4t_tlv_block_insert(nfc_t4t_capability_container_t * p_t4t_cc_file, + nfc_t4t_tlv_block_t * p_tlv_block) +{ + if (p_t4t_cc_file->tlv_count == p_t4t_cc_file->max_tlv_blocks) + { + return NRF_ERROR_NO_MEM; + } + + // Copy contents of the source block. + p_t4t_cc_file->p_tlv_block_array[p_t4t_cc_file->tlv_count] = *p_tlv_block; + p_t4t_cc_file->tlv_count++; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_cc_file_parse(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint8_t * p_raw_data, + uint16_t len) +{ + ret_code_t err_code = nfc_t4t_cc_args_validate(p_t4t_cc_file, p_raw_data, len); + VERIFY_SUCCESS(err_code); + + uint8_t * p_offset = p_raw_data; + nfc_t4t_cc_file_clear(p_t4t_cc_file); + + p_t4t_cc_file->len = uint16_big_decode(p_offset); + p_offset += CC_LEN_FIELD_SIZE; + + p_t4t_cc_file->major_version = MSN_GET(*p_offset); + p_t4t_cc_file->minor_version = LSN_GET(*p_offset); + p_offset += MAP_VER_FIELD_SIZE; + + p_t4t_cc_file->max_rapdu_size = uint16_big_decode(p_offset); + p_offset += MLE_FIELD_SIZE; + + p_t4t_cc_file->max_capdu_size = uint16_big_decode(p_offset); + p_offset += MLC_FIELD_SIZE; + + nfc_t4t_tlv_block_t new_block; + len -= (p_offset - p_raw_data); + while (len > 0) + { + uint16_t tlv_len = len; + err_code = nfc_t4t_file_control_tlv_parse(&new_block, p_offset, &tlv_len); + VERIFY_SUCCESS(err_code); + p_offset += tlv_len; + len -= tlv_len; + + err_code = nfc_t4t_tlv_block_insert(p_t4t_cc_file, &new_block); + VERIFY_SUCCESS(err_code); + } + + return nfc_t4t_cc_file_validate(p_t4t_cc_file); +} + + +nfc_t4t_tlv_block_t * nfc_t4t_file_content_get(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint16_t file_id) +{ + nfc_t4t_tlv_block_t * p_tlv_array = p_t4t_cc_file->p_tlv_block_array; + for (uint8_t i = 0; i < p_t4t_cc_file->tlv_count; i++) + { + nfc_t4t_file_control_val_t * p_tlv_value = &p_tlv_array[i].value; + if (p_tlv_value->file_id == file_id) + { + return (p_tlv_array + i); + } + } + return NULL; +} + + +ret_code_t nfc_t4t_file_content_set(nfc_t4t_capability_container_t * p_t4t_cc_file, + nfc_t4t_file_t file, + uint16_t file_id) +{ + nfc_t4t_tlv_block_t * p_tlv_block; + + p_tlv_block = nfc_t4t_file_content_get(p_t4t_cc_file, file_id); + if (p_tlv_block != NULL) + { + p_tlv_block->value.file = file; + return NRF_SUCCESS; + } + return NRF_ERROR_NOT_FOUND; +} + + +void nfc_t4t_cc_file_printout(nfc_t4t_capability_container_t * p_t4t_cc_file) +{ + NRF_LOG_INFO("Capability Container File content: \r\n") + NRF_LOG_INFO("CCLEN: %d \r\n", p_t4t_cc_file->len); + NRF_LOG_INFO("Mapping Version: %d.%d \r\n", + p_t4t_cc_file->major_version, + p_t4t_cc_file->minor_version); + NRF_LOG_INFO("MLe: %d \r\n", p_t4t_cc_file->max_rapdu_size) + NRF_LOG_INFO("MLc: %d \r\n\r\n", p_t4t_cc_file->max_capdu_size) + + NRF_LOG_INFO("Capability Container File contains %d File Control TLV block(s).\r\n", + p_t4t_cc_file->tlv_count); + for (uint8_t i = 0; i < p_t4t_cc_file->tlv_count; i++) + { + nfc_t4t_file_control_tlv_printout(i, &p_t4t_cc_file->p_tlv_block_array[i]); + } + NRF_LOG_RAW_INFO("\r\n"); +} + + +#endif // NFC_T4T_CC_FILE_PARSER_ENABLED + diff --git a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h b/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h new file mode 100644 index 0000000..ec90764 --- /dev/null +++ b/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h @@ -0,0 +1,178 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_T4T_CC_FILE_H__ +#define NFC_T4T_CC_FILE_H__ + +/**@file + * + * @defgroup nfc_t4t_cc_file CC file parser + * @{ + * @ingroup nfc_t4t_parser + * + * @brief Capability Container file parser for Type 4 Tag. + * + */ + +#include +#include "sdk_errors.h" +#include "nfc_t4t_tlv_block.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Descriptor for the Capability Container (CC) file of Type 4 Tag. + */ +typedef struct +{ + nfc_t4t_tlv_block_t * p_tlv_block_array; ///< Pointer to the array for TLV blocks. + uint16_t tlv_count; ///< Number of TLV blocks stored in the Type 4 Tag. + uint16_t const max_tlv_blocks; ///< Maximum number of TLV blocks. + uint16_t len; ///< Size (bytes) of a Capability Container including this field. + uint16_t max_rapdu_size; ///< MLe field - maximum R-APDU data size (bytes). + uint16_t max_capdu_size; ///< MLc field - maximum C-APDU data size (bytes). + uint8_t major_version; ///< Major version of the supported Type 4 Tag specification. + uint8_t minor_version; ///< Minor version of the supported Type 4 Tag specification. +} nfc_t4t_capability_container_t; + +/** + * @brief Macro for creating and initializing a Type 4 Tag Capability Container descriptor. + * + * This macro creates and initializes a static instance of a @ref nfc_t4t_capability_container_t + * structure and an array of @ref nfc_t4t_tlv_block_t descriptors. + * + * Use the macro @ref NFC_T4T_CC_DESC to access the Type 4 Tag descriptor instance. + * + * @param[in] NAME Name of the created descriptor instance. + * @param[in] MAX_BLOCKS Maximum number of @ref nfc_t4t_tlv_block_t descriptors that can be + * stored in the array. + * + */ +#define NFC_T4T_CC_DESC_DEF(NAME, MAX_BLOCKS) \ + static nfc_t4t_tlv_block_t NAME##_tlv_block_array[MAX_BLOCKS]; \ + static nfc_t4t_capability_container_t NAME##_type_4_tag = \ + { \ + .max_tlv_blocks = MAX_BLOCKS, \ + .p_tlv_block_array = NAME##_tlv_block_array, \ + .tlv_count = 0 \ + } + +/** + * @brief Macro for accessing the @ref nfc_t4t_capability_container_t instance that was created + * with @ref NFC_T4T_CC_DESC_DEF. + * + * @param[in] NAME Name of the created descriptor instance. + */ +#define NFC_T4T_CC_DESC(NAME) (NAME##_type_4_tag) + +/** + * @brief Function for parsing raw data of a CC file, read from a Type 4 Tag. + * + * This function parses raw data of a Capability Container file and stores the results in its + * descriptor. + * + * @param[in,out] p_t4t_cc_file Pointer to the CC file descriptor that will be filled with + * parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw data. + * @param[in] len Buffer length. + * + * @retval NRF_SUCCESS If operation was successful. + * @retval NRF_ERROR_NULL If any of the provided pointer arguments is NULL. + * @retval NRF_ERROR_INVALID_LENGTH If provided buffer exceeds a valid CC file length range. + * @retval NRF_ERROR_INVALID_DATA If mapping version of Type 4 Tag specification is not a + * compatible CC file structure. + * @retval Other Other error codes might be returned depending on + * @ref nfc_t4t_file_control_tlv_parse function. + */ +ret_code_t nfc_t4t_cc_file_parse(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint8_t * p_raw_data, + uint16_t len); + +/** + * @brief Function for finding File Control TLV block within the CC file descriptor. + * + * This function finds File Control TLV block that matches + * the specified file ID within the CC file descriptor. + * + * @param[in] p_t4t_cc_file Pointer to the CC file descriptor. + * @param[in] file_id File identifier. + * + * @retval TLV Pointer to the File Control TLV. + * @retval NULL If TLV with the specified File ID was not found. + */ +nfc_t4t_tlv_block_t * nfc_t4t_file_content_get(nfc_t4t_capability_container_t * p_t4t_cc_file, + uint16_t file_id); + +/** + * @brief Function for binding a file with its File Control TLV block. + * + * This function binds file content with its File Control TLV block, in which + * maximal file size and access conditions are stored. + * + * @param[in,out] p_t4t_cc_file Pointer to the CC file descriptor. + * @param[in] file File descriptor. + * @param[in] file_id File identifier. + * + * @retval NRF_SUCCESS If operation was successful. + * @retval NRF_ERROR_NOT_FOUND If the provided file ID does not match any ID stored in TLV blocks + * of the CC file. + */ +ret_code_t nfc_t4t_file_content_set(nfc_t4t_capability_container_t * p_t4t_cc_file, + nfc_t4t_file_t file, + uint16_t file_id); + +/** + * @brief Function for printing the CC file descriptor. + * + * This function prints the CC file descriptor. + * + * @param[in] p_t4t_cc_file Pointer to the CC file. + */ +void nfc_t4t_cc_file_printout(nfc_t4t_capability_container_t * p_t4t_cc_file); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_CC_FILE_H__ */ diff --git a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c b/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c new file mode 100644 index 0000000..baf4452 --- /dev/null +++ b/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c @@ -0,0 +1,399 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED + +#include "nfc_t4t_hl_detection_procedures.h" +#include "nfc_t4t_apdu.h" +#include "adafruit_pn532.h" +#include "sdk_macros.h" +#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "NFC_T4T_HL_DETECTION_PROCEDURES" +#if NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR +#else // NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED +#include "nrf_log.h" + +#define CC_FILE_ID 0xE103 ///< File Identifier of Capability Container. +#define FILE_ID_SIZE 2 ///< Size of File Identifier field in CC file. +#define MIN_MAX_RAPDU_SIZE 0x0F ///< Minimal value of maximal RAPDU data field size. +#define NDEF_FILE_NLEN_FIELD_SIZE 2 ///< Size of NLEN field in NDEF file. +#define NDEF_APP_PROC_RESP_LEN 256 ///< Maximal size of RAPDU data in the NDEF Tag Application Select Procedure. + +// Adafruit library limitations. +#define MAX_ADAFRUIT_RAPDU_SIZE 242 ///< Maximal value of RAPDU data field size +#define MAX_ADAFRUIT_CAPDU_SIZE 56 ///< Maximal value of CAPDU data field size + +static uint8_t m_file_id[FILE_ID_SIZE]; ///< Buffer for selected EF ID storage. +static const uint8_t m_nfc_t4t_select_ndef_app_data[] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01}; ///< NDEF Tag Application name. +static const uint8_t m_nlen_update_value[] = {0x00, 0x00}; ///< NLEN value used in NDEF Update Procedure. + +/** + * @brief Function for performing APDU exchanges with Adafruit library. + */ +static ret_code_t nfc_t4t_apdu_exchange(nfc_t4t_comm_apdu_t * const p_capdu, + nfc_t4t_resp_apdu_t * const p_rapdu, + uint8_t * const p_apdu_buff, + uint8_t resp_len) +{ + if (resp_len > APDU_BUFF_SIZE) + { + return NRF_ERROR_NO_MEM; + } + + uint16_t apdu_buff_len = APDU_BUFF_SIZE; + ret_code_t err_code = nfc_t4t_comm_apdu_encode(p_capdu, + p_apdu_buff, + &apdu_buff_len); + VERIFY_SUCCESS(err_code); + + err_code = adafruit_pn532_in_data_exchange(p_apdu_buff, apdu_buff_len, p_apdu_buff, &resp_len); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_resp_apdu_decode(p_rapdu, p_apdu_buff, resp_len); + VERIFY_SUCCESS(err_code); + + nfc_t4t_resp_apdu_printout(p_rapdu); + VERIFY_RAPDU_SUCCESS(p_rapdu); + + return err_code; +} + +/** + * @brief Function for performing APDU exchanges with Adafruit library with default response length. + */ +static ret_code_t nfc_t4t_apdu_default_exchange(nfc_t4t_comm_apdu_t * const p_capdu, + nfc_t4t_resp_apdu_t * const p_rapdu, + uint8_t * const p_apdu_buff) +{ + if (p_capdu->resp_len + sizeof(p_rapdu->status) > UINT8_MAX) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + uint8_t resp_len = (uint8_t) (p_capdu->resp_len + sizeof(p_rapdu->status)); + ret_code_t err_code = nfc_t4t_apdu_exchange(p_capdu, p_rapdu, p_apdu_buff, resp_len); + + return err_code; +} + + +/** + * @brief Function for saving part of EF (contained in RAPDU) in storage buffer. + */ +static ret_code_t nfc_t4t_file_chunk_save(nfc_t4t_resp_apdu_t const * const p_rapdu, + uint8_t * const p_storage_buff, + uint16_t storage_buff_len, + uint16_t * const p_file_offset) +{ + if (p_rapdu->data.p_buff == NULL) + { + return NRF_ERROR_NULL; + } + if ((*p_file_offset) + p_rapdu->data.len > storage_buff_len) + { + return NRF_ERROR_NO_MEM; + } + + memcpy(p_storage_buff + (*p_file_offset), p_rapdu->data.p_buff, p_rapdu->data.len); + *p_file_offset += p_rapdu->data.len; + + return NRF_SUCCESS; +} + + +/** + * @brief Function for updating the remaining length of the read file. + */ +static ret_code_t nfc_t4t_file_len_update(nfc_t4t_resp_apdu_t const * const p_rapdu, + uint16_t * const p_len) +{ + if (*p_len < p_rapdu->data.len) + { + return NRF_ERROR_INVALID_DATA; + } + *p_len -= p_rapdu->data.len; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_ndef_tag_app_select(void) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + NRF_LOG_INFO("NDEF Tag Application Select Procedure \r\n"); + + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_SELECT_INS; + capdu.parameter = SELECT_BY_NAME; + capdu.data.p_buff = (uint8_t *) m_nfc_t4t_select_ndef_app_data; + capdu.data.len = sizeof(m_nfc_t4t_select_ndef_app_data); + capdu.resp_len = NDEF_APP_PROC_RESP_LEN; + + err_code = nfc_t4t_apdu_exchange(&capdu, &rapdu, apdu_buff, sizeof(rapdu.status)); + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_file_select(uint16_t file_id) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + if (file_id != CC_FILE_ID) + { + NRF_LOG_INFO("File (ID = %4X) Select Procedure \r\n", file_id); + } + UNUSED_RETURN_VALUE(uint16_big_encode(file_id, m_file_id)); + + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_SELECT_INS; + capdu.parameter = SELECT_BY_FILE_ID; + capdu.data.p_buff = m_file_id; + capdu.data.len = sizeof(m_file_id); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_cc_select(void) +{ + NRF_LOG_INFO("Capability Container Select Procedure \r\n"); + + return nfc_t4t_file_select(CC_FILE_ID); +} + + +ret_code_t nfc_t4t_cc_read(nfc_t4t_capability_container_t * const p_cc_file) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint16_t clen; + uint16_t file_offset = 0; + uint8_t storage_buff[CC_STORAGE_BUFF_SIZE]; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + NRF_LOG_INFO("Capability Container Read Procedure \r\n"); + + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_READ_INS; + capdu.parameter = file_offset; + capdu.resp_len = MIN_MAX_RAPDU_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, storage_buff, CC_STORAGE_BUFF_SIZE, &file_offset); + VERIFY_SUCCESS(err_code); + + clen = uint16_big_decode(storage_buff); + err_code = nfc_t4t_file_len_update(&rapdu, &clen); + VERIFY_SUCCESS(err_code); + + while (clen > 0) + { + capdu.parameter = file_offset; + capdu.resp_len = MIN(MIN_MAX_RAPDU_SIZE, MIN(clen, MAX_ADAFRUIT_RAPDU_SIZE)); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, storage_buff, CC_STORAGE_BUFF_SIZE, &file_offset); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_len_update(&rapdu, &clen); + VERIFY_SUCCESS(err_code); + } + + err_code = nfc_t4t_cc_file_parse(p_cc_file, storage_buff, file_offset); + + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_ndef_read(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint16_t len; + uint16_t file_offset = 0; + uint8_t apdu_buff[APDU_BUFF_SIZE]; + + NRF_LOG_INFO("NDEF Read Procedure \r\n"); + + // Read the NLEN (NDEF length) field of NDEF file. + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_READ_INS; + capdu.parameter = file_offset; + capdu.resp_len = NDEF_FILE_NLEN_FIELD_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, p_ndef_file_buff, ndef_file_buff_len, &file_offset); + VERIFY_SUCCESS(err_code); + + len = uint16_big_decode(p_ndef_file_buff) + NDEF_FILE_NLEN_FIELD_SIZE; + err_code = nfc_t4t_file_len_update(&rapdu, &len); + VERIFY_SUCCESS(err_code); + + // Read the NDEF message. + while (len > 0) + { + capdu.parameter = file_offset; + capdu.resp_len = MIN(len, MIN(p_cc_file->max_rapdu_size, MAX_ADAFRUIT_RAPDU_SIZE)); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_chunk_save(&rapdu, p_ndef_file_buff, ndef_file_buff_len, &file_offset); + VERIFY_SUCCESS(err_code); + + err_code = nfc_t4t_file_len_update(&rapdu, &len); + VERIFY_SUCCESS(err_code); + } + + // Bind NDEF File Control TLV with NDEF file. + nfc_t4t_file_t file = + { + .p_content = p_ndef_file_buff, + .len = file_offset + }; + uint16_t file_id = uint16_big_decode(m_file_id); + err_code = nfc_t4t_file_content_set(p_cc_file, file, file_id); + + NRF_LOG_RAW_INFO("\r\n"); + return err_code; +} + + +ret_code_t nfc_t4t_ndef_update(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len) +{ + ret_code_t err_code; + nfc_t4t_comm_apdu_t capdu; + nfc_t4t_resp_apdu_t rapdu; + uint16_t len; + uint16_t file_offset = 0; + uint16_t file_id = uint16_big_decode(m_file_id); + uint8_t apdu_buff[APDU_BUFF_SIZE]; + nfc_t4t_tlv_block_t * p_tlv_block; + + NRF_LOG_INFO("NDEF Update Procedure \r\n"); + + if (ndef_file_buff_len < NDEF_FILE_NLEN_FIELD_SIZE) + { + return NRF_ERROR_INVALID_DATA; + } + + // Check if selected NDEF file is registered in CC file descriptor. + p_tlv_block = nfc_t4t_file_content_get(p_cc_file, file_id); + if (p_tlv_block == NULL) + { + return NRF_ERROR_NULL; + } + + // Check NDEF file capacity before writing anything to it. + len = uint16_big_decode(p_ndef_file_buff); + if ((len + NDEF_FILE_NLEN_FIELD_SIZE != ndef_file_buff_len) || + (ndef_file_buff_len > p_tlv_block->value.max_file_size)) + { + return NRF_ERROR_INVALID_LENGTH; + } + + // Write the value 0000h in the NLEN field. + nfc_t4t_comm_apdu_clear(&capdu); + capdu.instruction = NFC_T4T_CAPDU_UPDATE_INS; + capdu.parameter = file_offset; + capdu.data.p_buff = (uint8_t *) m_nlen_update_value; + capdu.data.len = NDEF_FILE_NLEN_FIELD_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + file_offset += NDEF_FILE_NLEN_FIELD_SIZE; + + // Write the NDEF message in the NDEF message field. + while (len > 0) + { + capdu.parameter = file_offset; + capdu.data.p_buff = p_ndef_file_buff + file_offset; + capdu.data.len = MIN(len, MIN(p_cc_file->max_capdu_size, MAX_ADAFRUIT_CAPDU_SIZE)); + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + file_offset += capdu.data.len; + len -= capdu.data.len; + } + + // Write the length of the NDEF message in the NLEN field. + capdu.parameter = 0; + capdu.data.p_buff = p_ndef_file_buff; + capdu.data.len = NDEF_FILE_NLEN_FIELD_SIZE; + + err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff); + VERIFY_SUCCESS(err_code); + + NRF_LOG_RAW_INFO("\r\n"); + return NRF_SUCCESS; +} + + +#endif // NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED + diff --git a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h b/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h new file mode 100644 index 0000000..a685e9f --- /dev/null +++ b/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h @@ -0,0 +1,185 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_T4T_HL_DETECTION_PROCEDURES_H__ +#define NFC_T4T_HL_DETECTION_PROCEDURES_H__ + +/**@file + * + * @defgroup nfc_t4t_parser NFC Type 4 Tag parser + * @ingroup nfc_t4t + * @brief Parser for Type 4 Tag data. + * + * @defgroup nfc_t4t_hl_detection_procedures High-level NDEF Detection Procedure + * @{ + * @ingroup nfc_t4t_parser + * + * @brief High-level NDEF Detection Procedure for Type 4 Tag communication. + * + */ + +#include +#include "sdk_errors.h" +#include "nfc_t4t_cc_file.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Function for performing NDEF Tag Application Select Procedure. + * + * This function performs NDEF Tag Application Select Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.2. + * + * @retval NRF_SUCCESS If NDEF Tag Application was successfully selected. + * @retval NRF_ERROR_NOT_FOUND If NDEF Tag Application was not found. + * @retval NRF_ERROR_NO_MEM If the APDU buffer is too small. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu + * module functions. + */ +ret_code_t nfc_t4t_ndef_tag_app_select(void); + +/** + * @brief Function for performing Capability Container Select Procedure. + * + * This function performs Capability Container Select Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.3. + * + * @retval NRF_SUCCESS If the Capability Container file was successfully selected. + * @retval NRF_ERROR_NOT_FOUND If the Capability Container file was not found. + * @retval NRF_ERROR_NO_MEM If the APDU buffer is too small. + * @retval Other Other error codes might be returned depending on function + * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu + * module functions. + */ +ret_code_t nfc_t4t_cc_select(void); + +/** + * @brief Function for performing Capability Container Read Procedure. + * + * This function performs Capability Container Read Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.4. + * + * @param[out] p_cc_file Pointer to the Capability Container descriptor. + * + * @retval NRF_SUCCESS If Capability Container file was successfully read. + * @retval NRF_ERROR_NO_MEM If APDU buffer or CC file storage buffer is too small. + * @retval NRF_ERROR_NOT_SUPPORTED If the requested response length in C-APDU is too big. + * @retval NRF_ERROR_NULL If R-APDU did not return any data bytes. + * @retval NRF_ERROR_INVALID_DATA If CCLEN field is not coherent with R-APDU data length. + * @retval Other Other error codes may be returned depending on functions + * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_cc_file_parse, + * and on @ref nfc_t4t_apdu module functions. + */ +ret_code_t nfc_t4t_cc_read(nfc_t4t_capability_container_t * const p_cc_file); + +/** + * @brief Function for performing NDEF Select Procedure. + * + * This function performs NDEF Select Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.5. + * + * @param[in] file_id File Identifier to choose the correct file. + * + * @retval NRF_SUCCESS If NDEF file was successfully selected. + * @retval NRF_ERROR_NOT_FOUND If NDEF file was not found. + * @retval NRF_ERROR_NO_MEM If APDU buffer is too small. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu + * module functions. + */ +ret_code_t nfc_t4t_file_select(uint16_t file_id); + +/** + * @brief Function for performing NDEF Read Procedure. + * + * This function performs NDEF Read Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.6. + * + * @param[in,out] p_cc_file Pointer to the Capability Container descriptor. + * @param[out] p_ndef_file_buff Pointer to the buffer where the NDEF file will be stored. + * @param[in] ndef_file_buff_len Length of the provided NDEF file buffer. + * + * @retval NRF_SUCCESS If NDEF file was successfully read. + * @retval NRF_ERROR_NO_MEM If APDU buffer or NDEF file buffer is too small. + * @retval NRF_ERROR_NOT_SUPPORTED If requested response length in C-APDU is too big. + * @retval NRF_ERROR_NULL If R-APDU did not return any data bytes. + * @retval NRF_ERROR_INVALID_DATA If NLEN field is not coherent with R-APDU data length. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_file_content_set, + * and on @ref nfc_t4t_apdu module functions. + */ +ret_code_t nfc_t4t_ndef_read(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len); + +/** + * @brief Function for performing NDEF Update Procedure. + * + * This function performs NDEF Update Procedure according to "Type 4 Tag Operation" + * (Version 3.0 published on 2014-07-30) chapter 5.5.7. + * + * @param[in] p_cc_file Pointer to the Capability Container descriptor. + * @param[in] p_ndef_file_buff Pointer to the buffer with NDEF file. + * @param[in] ndef_file_buff_len Length of the provided NDEF file. + * + * @retval NRF_SUCCESS If NDEF file was successfully updated. + * @retval NRF_ERROR_NO_MEM If APDU buffer or NDEF file buffer is too small. + * @retval NRF_ERROR_NOT_SUPPORTED If the requested response length in C-APDU is too big. + * @retval NRF_ERROR_INVALID_DATA If NDEF file buffer is smaller than NLEN field size. + * @retval NRF_ERROR_INVALID_LENGTH If NLEN value is not coherent with NDEF file buffer length + * or if buffer length is bigger than maximal file size. + * @retval Other Other error codes may be returned depending on function + * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_file_content_get, + * and on @ref nfc_t4t_apdu module functions. + */ +ret_code_t nfc_t4t_ndef_update(nfc_t4t_capability_container_t * const p_cc_file, + uint8_t * p_ndef_file_buff, + uint8_t ndef_file_buff_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_HL_DETECTION_PROCEDURES_H__ */ diff --git a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c b/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c new file mode 100644 index 0000000..7f0ca69 --- /dev/null +++ b/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c @@ -0,0 +1,326 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "sdk_config.h" +#if NFC_T4T_TLV_BLOCK_PARSER_ENABLED + +#include +#include "nfc_t4t_tlv_block.h" +#include "app_util.h" +#include "sdk_macros.h" +#include "nordic_common.h" + +#define NRF_LOG_MODULE_NAME "NFC_T4T_TLV_BLOCK_PARSER" +#if NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL +#define NRF_LOG_INFO_COLOR NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR +#else // NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED +#define NRF_LOG_LEVEL 0 +#endif // NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED +#include "nrf_log.h" + +#define TLV_TYPE_FIELD_LEN 1U ///< Length of a type field. + +/** + * @brief TLV length field related defines. + */ +#define TLV_LEN_SHORT_FIELD_LEN 1U ///< Length of a short length field. +#define TLV_LEN_LONG_FIELD_LEN 3U ///< Length of an extended length field. +#define TLV_LEN_LONG_FORMAT_TOKEN 0xFF ///< Value indicating the use of an extended length field. +#define TLV_LEN_LONG_FORMAT_TOKEN_SIZE 1U ///< Size of long format token. +#define TLV_LEN_LONG_FORMAT_MIN_VALUE 0xFF ///< The minimal value of length field that can be used in long format. + +/** + * @brief Possible sizes of TLV block. + */ +#define TLV_MIN_TL_FIELD_LEN (TLV_TYPE_FIELD_LEN + TLV_LEN_SHORT_FIELD_LEN) +#define TLV_MIN_LONG_FORMAT_TL_FIELD_LEN (TLV_TYPE_FIELD_LEN + TLV_LEN_LONG_FIELD_LEN) +#define TLV_MIN_VALUE_FIELD_SIZE 6U + +/** + * @brief Field sizes that are present in TLV block. + */ +#define FILE_CONTROL_FILE_ID_FIELD_SIZE 2U +#define FILE_CONTROL_READ_ACCESS_FIELD_SIZE 1U +#define FILE_CONTROL_WRITE_ACCESS_FIELD_SIZE 1U +#define FILE_CONTROL_COMMON_FIELDS_SIZE (FILE_CONTROL_FILE_ID_FIELD_SIZE \ + + FILE_CONTROL_READ_ACCESS_FIELD_SIZE \ + + FILE_CONTROL_WRITE_ACCESS_FIELD_SIZE) + +/** + * @brief Invalid values for File Identifier field. + */ +#define FILE_ID_INVALID_VALUE_0 0x0000 +#define FILE_ID_INVALID_VALUE_1 0xE102 +#define FILE_ID_INVALID_VALUE_2 0xE103 +#define FILE_ID_INVALID_VALUE_3 0x3F00 +#define FILE_ID_INVALID_VALUE_4 0x3FFF +#define FILE_ID_INVALID_VALUE_5 0xFFFF + +/** + * @brief NDEF file related defines. + */ +#define NDEF_FILE_MAX_SIZE_FIELD_SIZE 2U +#define NDEF_FILE_MAX_SIZE_MIN_VAL 0x0005 +#define NDEF_FILE_MAX_SIZE_MAX_VAL 0xFFFE +#define NDEF_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \ + + NDEF_FILE_MAX_SIZE_FIELD_SIZE) + +/** + * @brief Proprietary file related defines. + */ +#define PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE 2U +#define PROPRIETARY_FILE_MAX_SIZE_MIN_VAL 0x0003 +#define PROPRIETARY_FILE_MAX_SIZE_MAX_VAL 0xFFFE +#define PROPRIETARY_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \ + + PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE) + +/** + * @brief Extended NDEF file related defines. + */ +#define EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE 4U +#define EXTENDED_NDEF_FILE_MAX_SIZE_MIN_VAL 0x0000FFFF +#define EXTENDED_NDEF_FILE_MAX_SIZE_MAX_VAL 0xFFFFFFFE +#define EXTENDED_NDEF_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \ + + EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE) + +/** + * @brief Validates maximum file size field range. This field is present in every File Control TLV. + */ +#define NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(VALUE, MIN, MAX) \ + if ( ( (VALUE) < (MIN) ) || ( (VALUE) > (MAX) ) ) \ + { \ + return NRF_ERROR_INVALID_DATA; \ + } + + +/** + * @brief Function for validating all possible types of File Control TLV. + */ +__STATIC_INLINE ret_code_t nfc_t4t_file_control_tl_validate(nfc_t4t_tlv_block_t * p_file_control_tlv) +{ + switch (p_file_control_tlv->type) + { + case NDEF_FILE_CONTROL_TLV: + VERIFY_TRUE(p_file_control_tlv->length == NDEF_FILE_CONTROL_TLV_LEN, + NRF_ERROR_INVALID_DATA); + return NRF_SUCCESS; + + case PROPRIETARY_FILE_CONTROL_TLV: + VERIFY_TRUE(p_file_control_tlv->length == PROPRIETARY_FILE_CONTROL_TLV_LEN, + NRF_ERROR_INVALID_DATA); + return NRF_SUCCESS; + + case EXTENDED_NDEF_FILE_CONTROL_TLV: + VERIFY_TRUE(p_file_control_tlv->length == EXTENDED_NDEF_FILE_CONTROL_TLV_LEN, + NRF_ERROR_INVALID_DATA); + return NRF_SUCCESS; + + default: + return NRF_ERROR_INVALID_DATA; + } +} + + +/** + * @brief Function for parsing value field of File Control TLV. + */ +static ret_code_t nfc_t4t_file_control_value_parse(nfc_t4t_tlv_block_t * p_file_control_tlv, + uint8_t * p_value_buff) +{ + nfc_t4t_file_control_val_t * p_control_tlv_val; + + // Handle File Identifier field. + p_control_tlv_val = &p_file_control_tlv->value; + p_control_tlv_val->file_id = uint16_big_decode(p_value_buff); + p_value_buff += FILE_CONTROL_FILE_ID_FIELD_SIZE; + + switch (p_control_tlv_val->file_id) + { + case FILE_ID_INVALID_VALUE_0: + case FILE_ID_INVALID_VALUE_1: + case FILE_ID_INVALID_VALUE_2: + case FILE_ID_INVALID_VALUE_3: + case FILE_ID_INVALID_VALUE_4: + case FILE_ID_INVALID_VALUE_5: + return NRF_ERROR_INVALID_DATA; + + default: + break; + } + + // Handle Max file size field. + switch (p_file_control_tlv->type) + { + case NDEF_FILE_CONTROL_TLV: + p_control_tlv_val->max_file_size = uint16_big_decode(p_value_buff); + p_value_buff += NDEF_FILE_MAX_SIZE_FIELD_SIZE; + NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size, + NDEF_FILE_MAX_SIZE_MIN_VAL, + NDEF_FILE_MAX_SIZE_MAX_VAL); + break; + + case PROPRIETARY_FILE_CONTROL_TLV: + p_control_tlv_val->max_file_size = uint16_big_decode(p_value_buff); + p_value_buff += PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE; + NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size, + PROPRIETARY_FILE_MAX_SIZE_MIN_VAL, + PROPRIETARY_FILE_MAX_SIZE_MAX_VAL); + break; + + case EXTENDED_NDEF_FILE_CONTROL_TLV: + p_control_tlv_val->max_file_size = uint32_big_decode(p_value_buff); + p_value_buff += EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE; + NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size, + EXTENDED_NDEF_FILE_MAX_SIZE_MIN_VAL, + EXTENDED_NDEF_FILE_MAX_SIZE_MAX_VAL); + break; + } + + // Handle read access condition field. + p_control_tlv_val->read_access = *p_value_buff; + p_value_buff += FILE_CONTROL_READ_ACCESS_FIELD_SIZE; + + // Handle write access condition field. + p_control_tlv_val->write_access = *p_value_buff; + + return NRF_SUCCESS; +} + + +ret_code_t nfc_t4t_file_control_tlv_parse(nfc_t4t_tlv_block_t * p_file_control_tlv, + uint8_t * p_raw_data, + uint16_t * p_len) +{ + ret_code_t err_code; + uint8_t * p_offset = p_raw_data; + + if (*p_len < TLV_MIN_TL_FIELD_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + memset(p_file_control_tlv, 0, sizeof(nfc_t4t_tlv_block_t)); + + // Handle type field of TLV block. + p_file_control_tlv->type = *p_offset; + p_offset += TLV_TYPE_FIELD_LEN; + + // Handle length field of TLV block. + if (*p_offset == TLV_LEN_LONG_FORMAT_TOKEN) + { + if (*p_len < TLV_MIN_LONG_FORMAT_TL_FIELD_LEN) + { + return NRF_ERROR_INVALID_LENGTH; + } + + p_file_control_tlv->length = uint16_big_decode(p_offset + TLV_LEN_LONG_FORMAT_TOKEN_SIZE); + p_offset += TLV_LEN_LONG_FIELD_LEN; + + if (p_file_control_tlv->length < TLV_LEN_LONG_FORMAT_MIN_VALUE) + { + return NRF_ERROR_INVALID_DATA; + } + } + else + { + p_file_control_tlv->length = *p_offset; + p_offset += TLV_LEN_SHORT_FIELD_LEN; + } + + // Calculate the total TLV block size. + uint16_t tlv_block_len = (p_offset - p_raw_data) + p_file_control_tlv->length; + if (*p_len < tlv_block_len) + { + return NRF_ERROR_INVALID_LENGTH; + } + *p_len = tlv_block_len; + + // Validate if type and length fields contain values supported by Type 4 Tag. + err_code = nfc_t4t_file_control_tl_validate(p_file_control_tlv); + VERIFY_SUCCESS(err_code); + + // Handle value field of TLV block. + err_code = nfc_t4t_file_control_value_parse(p_file_control_tlv, p_offset); + return err_code; +} + + +void nfc_t4t_file_control_tlv_printout(uint8_t num, nfc_t4t_tlv_block_t * p_t4t_tlv_block) +{ + NRF_LOG_INFO("%d file Control TLV\r\n", num); + switch (p_t4t_tlv_block->type) + { + case NDEF_FILE_CONTROL_TLV: + NRF_LOG_INFO("Type: NDEF File Control (0x%02x)\r\n", p_t4t_tlv_block->type); + break; + + case PROPRIETARY_FILE_CONTROL_TLV: + NRF_LOG_INFO("Type: Proprietary File Control (0x%02x)\r\n", p_t4t_tlv_block->type); + break; + + case EXTENDED_NDEF_FILE_CONTROL_TLV: + NRF_LOG_INFO("Type: Extended NDEF File Control (0x%02x)\r\n", p_t4t_tlv_block->type); + break; + + default: + NRF_LOG_INFO("Type: Unknown (0x%02x)\r\n", p_t4t_tlv_block->type); + } + NRF_LOG_INFO("Length (in bytes): %d\r\n", p_t4t_tlv_block->length); + + nfc_t4t_file_control_val_t * p_tlv_val = &p_t4t_tlv_block->value; + NRF_LOG_INFO("File Identifier: 0x%04X \r\n", p_tlv_val->file_id); + NRF_LOG_INFO("Maximum file size: %d \r\n", p_tlv_val->max_file_size); + NRF_LOG_INFO("Read access condition: 0x%02X \r\n", p_tlv_val->read_access); + NRF_LOG_INFO("Write access condition: 0x%02x \r\n\r\n", p_tlv_val->write_access); + + if (p_tlv_val->file.p_content != NULL) + { + NRF_LOG_INFO("NDEF file content present. Length: %d \r\n", p_tlv_val->file.len); + NRF_LOG_HEXDUMP_INFO(p_tlv_val->file.p_content, p_tlv_val->file.len); + } + else + { + NRF_LOG_INFO("NDEF file content is not present \r\n"); + } + NRF_LOG_RAW_INFO("\r\n"); +} + + +#endif // NFC_T4T_TLV_BLOCK_PARSER_ENABLED + diff --git a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h b/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h new file mode 100644 index 0000000..973994b --- /dev/null +++ b/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NFC_T4T_TLV_BLOCK_H__ +#define NFC_T4T_TLV_BLOCK_H__ + +/**@file + * + * @defgroup nfc_t4t_tlv_block File Control TLV block parser for Type 4 Tag. + * @{ + * @ingroup nfc_t4t_cc_file + * + * @brief File Control TLV block parser for Type 4 Tag (T4T). + * + */ + +#include +#include "sdk_errors.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CONTROL_FILE_READ_ACCESS_GRANTED 0x00 ///< Read access granted without any security. + +/** + * @name Possible values of file write access condition field. + * @{ + */ +#define CONTROL_FILE_WRITE_ACCESS_GRANTED 0x00 ///< Write access granted without any security. +#define CONTROL_FILE_WRITE_ACCESS_DISABLED 0xFF ///< No write access granted without any security (read-only). +/** @} */ + +/** + * @brief Possible types of File Control TLV for Type 4 Tag. + */ +typedef enum +{ + NDEF_FILE_CONTROL_TLV = 0x04, ///< Control information concerning the EF file with short NDEF message. + PROPRIETARY_FILE_CONTROL_TLV = 0x05, ///< Control information concerning the Proprietary file with proprietary data. + EXTENDED_NDEF_FILE_CONTROL_TLV = 0x06 ///< Control information concerning the EF file with long NDEF message. +} nfc_t4t_tlv_block_types_t; + +/** + * @brief File content descriptor. + */ +typedef struct +{ + uint8_t * p_content; ///< Pointer to the file content. + uint16_t len; ///< Length of file content. +} nfc_t4t_file_t; + +/** + * @brief Extended NDEF/NDEF/Proprietary File Control Value descriptor. + */ +typedef struct +{ + nfc_t4t_file_t file; ///< Pointer to the described file content. + uint32_t max_file_size; ///< Maximum size (in bytes) of the file. + uint16_t file_id; ///< File identifier. + uint8_t read_access; ///< File read access condition. + uint8_t write_access; ///< File write access condition. +} nfc_t4t_file_control_val_t; + +/** + * @brief File Control TLV block descriptor. + */ +typedef struct +{ + nfc_t4t_file_control_val_t value; ///< Value field descriptor. + uint16_t length; ///< Length of the value field. + uint8_t type; ///< Type of the TLV block. +} nfc_t4t_tlv_block_t; + +/** + * @brief Function for parsing raw data of File Control TLV, read from a Type 4 Tag. + * + * This function parses raw data of File Control TLV and stores the results in its + * descriptor. + * + * @param[in,out] p_file_control_tlv Pointer to the File Control TLV that will be filled with + * parsed data. + * @param[in] p_raw_data Pointer to the buffer with raw TLV data. + * @param[in,out] p_len In: Buffer length with TLV blocks. + * Out: Total length of first identified TLV within the buffer. + * + * @retval NRF_SUCCESS If operation was successful. + * @retval NRF_ERROR_INVALID_LENGTH If provided buffer length is too small for TLV block. + * @retval NRF_ERROR_INVALID_DATA If any TLV block field contains invalid data. + */ +ret_code_t nfc_t4t_file_control_tlv_parse(nfc_t4t_tlv_block_t * p_file_control_tlv, + uint8_t * p_raw_data, + uint16_t * p_len); + +/** + * @brief Function for printing TLV block descriptor. + * + * This function prints TLV block descriptor. + * + * @param[in] num TLV block number. + * @param[in] p_t4t_tlv_block Pointer to the TLV block descriptor. + */ +void nfc_t4t_file_control_tlv_printout(uint8_t num, nfc_t4t_tlv_block_t * p_t4t_tlv_block); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* NFC_T4T_TLV_BLOCK_H__ */ diff --git a/components/properitary_rf/esb/arm/esb_arm.lib b/components/properitary_rf/esb/arm/esb_arm.lib deleted file mode 100644 index d88c7ce2b1d0f7c4eb39d396ac789f2b50575b41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80618 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 diff --git a/components/properitary_rf/esb/arm/esb_sd_resources_arm.lib b/components/properitary_rf/esb/arm/esb_sd_resources_arm.lib deleted file mode 100644 index 7dbdf5cf37a9ce7d0e0ac8b7a11a48a34bb9e149..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81270 zcmeEv3w%^po&ULaCdnkcLcliA6ekcMP@qW&uZlW(Fw8)B6ljZz&YdI!Gd3jCJRsDz z21?ts_ODp0wpv~4)^4k)viv!b-P>bMz;#aLoJO8q`ps8y*~dToQB*ZTG8Zlzwy^|dFJ8teLppDXppxc=`xr7qyI3cjTN zzr1R0QkK3Vk!a7(NF-8M8|m!c9%+k5J3C_?k)6@b=#E%-q%E?vt}WJDw|yC8BAZrS zUAt7hQZJiBN~_)(NpvQ9(@3m8*4Eb>i}WNqcXY%ey@|GKNAO7ONmB)j^mX}`KUYT^Ht1~iIa64kX z5jPlE)VYJ6OqI)99xC`-+{|MHeL%GPJaJu_C zSv0yrZ|~Thc?gMs)opTIu&$)eFCa|P2+zIIo@*nC9#nQjJJzn&Zwf}JC)piKM!RE? zwrEF3j)qu2YJW7@+Xp5+=P>D$J|eMQs4i+tc-^W^HIeY9D?`!F_KsM0CR6Gpvl2U# z(T*tcFcz&@R=)zz_J~%g_S}-l5Gd(DCiKR-JEI*awC?Cm-NXpPRO61eE~cidb9-Wk z_7Uyb)7d7qTxaEuWTFe%(Au{nl0>7iyE|d>SgYZK-Q5=Hh;{Dh)paRNM_z4D^ha9v zPsDW0K3-+0~v!Nw-jv4f)yGp6JQVUp_dRmK7kMvs|sCv~;3Bzoio*TRP+%P-;qx2)Q{WyAWGx1>kPx(v`@cEol> zb!Vi--H}EY8ty3j8Of`3nBC|f(wt;B`gsIz`sqX`+Q>}}&EXB%V~k7;Sw(b*i^|Wp z3O8r#mP*cccJ(HLS&$3tKkGZ!qyFmq(?q6_^s7X?B%L>#T z+ZhGBb4R2H)jkH%NKX8&>x=cp)aGl#wb_YHr$`U|%>$Ep-CNwgVp(iE2Gk?da$!D@ zieyeIfN`jijPB{^;#eCGiu zO0?n26&=BoB#p(DjOo=4LneCN>FDK;4NQVfsRQ~`!%KG#)6HUJ5tRpFh)3!10}2$rd0S$>%j*z+^zJrE95bjq~iH) zizhnSNY=F0)y9^?0y3h`Uzi6}dDu`)47GCf9Wn;i16y#@^_-H3eJ9_GL{?G@YIb!P z!9b(8Yoz!{CB~+bPO(mKtfv*pTwGHZYpY!`N;1zOg|tO`P{+}!%e#5H_rn`2GnuNH zo^)58P0V`%a%FS6K9`7Lh`h6>dq0;k)*#E}r-#li!HhmsPHWiKnvQO|DCi+;$WAo7 zcOs6~CVS{c5}M(x)+f8wAQ!I;Xe3PQw7t6vPe9f%oDwW&_o*~;8MB8g;I>nv3XFWv zBxD*b#tJRxJ$j}hw7#JQk6$-!Cm4~Vx85D? zZdWCj=S@VNZyu_)cA1%}a!S~wxvw;4q_n8(av|rmF?l@m?B-E*|6n>FS500*NiMlO zJBo-)?cxLry43GqQn$3;ojLpUhD}YDWnltMJ4^Xg22<+T zWT6+-3#e9QYLc>X@52@N+vMtFxJr+Bl|3{VdimGCd-=AIs`NUyg)FDRDLr~is3C5@ zK3vh@l*OmS?``y*QnQ*ID;}<}oK5lfH>y(}C%IZx*QL%Lxqi)**IyjJGF}n4sw+|x z%S(enXLh_MI4?-OU!B$+`b?w8DL7RbZ;Wr6-ss%X_}i1wct_|xjowo>D7H|}9t~Gq z>GCW`PjEzm@<;kPUpFDc@$b_Jp;|)Fp zxpm?*v|%~)0zbJ%@Kqt|wN5?MSab^T&iG|{;24O#r zurCvA4s!lsg#87C4S2ExVN)V7y?NT=xIZ{Oe&zJNjo*LfE%ES-E1P`Kl{_-7W%ldm z#r+6x5L%~;p6YmId>|g!mOP454wfQjIp-7v9if+|u)R*_xg z@p*j(zCvG-&*v-lmH5ULjrU<5cYKxthVzHeQJohLd(?R7@Gnf(CvhEH)@S=N={u*a z&l)K^H7gIM-F0@DcoC5vk6{e4Mvk}-d+zq++A z(b4X&Uop?W1=CPh_)!ySH1WS}NlkrCP5p|uE0?lxA^MWuM6|=daA9YcjQzS}9bIib zeD&+YMBR40LbPkLyy%=GlUap}_fIuP5E zeQ#{)>h6v8FI-mxd^_;XUE6!F4sHadd-^vn+7^-6ZsWM8BZ0woJ6~_R`d~}x**0p= z1kby+$2hoqqnKPuRJapEYv#sIPRd=ORI;vq`NGA&Pkv$6I5)dU$WLhP(we#jwKdBY zgLCfGMw4wlZ@gT_5WBm&ug%=SC-S`=(+=%1zrX2#y9WI7}L3pXJ1H_%+{Ul?ArXj}R}+}YOA*B)cN8l96(#akcd-O?1?pd{AD5*^#{ zm~Gp1_2SxX;q^^<?1DMd?Zt(67n#*s7YUq}N)(Y)~F{P^TFg zTYXb`5VlfZ_XEYR|uM9E`N$BQ1(vzszNX;L1R+ZNu=Z!m{N0< zy2vCslMjrDxS8<8d@89@$|0Ps)He+7g%s&i4Qw%RpMeJqe8#{R4ZH~9(BA?;8{_&K z1D8XujWu-a(;2AX;|yM`)MKQ-PN~NUCn@!`!BYnRp23F={*u9&Z+!9uQvDs zgNF>xbWlES@D79TH~65z?=$#8gFj;MLk2%?@Dm1Ci_rEg!uxf1q7}=Cdeowx-fqm_ z0mj`s^wo>>6#aJ0^2gL7642rHLTJxU5ym_cdquSfU48`pW+aXkA(((!#5Zbs*afSK z_JaG`rTSjABwDMgHpO6M@9C|olHo!t-*{uu)P{-x0_aZgnI23V z4c%2lBbf5CZ_LbYyO+C+h{g%m`{)v*=tu{iv+!!H6;tP019d?PMh$MPRaH3}%?g3M zwP5Z7GZ9TIcd4T-I}_8OYc0OeC2=r9yizZ+iVoE`vZFg0$*!SQOB4+RFs_=VC%PIo za=_YKG*+qAY>qsxGXTBXd#;{%6A7 zjFEu}I5$jpc;Z%2V>%h5>mKXb#0Y@H9J%r}jiIWl9m=8|^2k@UtEyhr5J7V%PqVVn zhpB+F7Xo;^s;O>K%~Dm69=WT+@x|6;tIVEiUu>0I)2!*%4BM`RFuJ7?VicNY&G60u z9~D5^>}DZ2(JHgpS~G+)v~aJ^<$A>1({<>Xz3c%pj_*`R4;XM+9%7mzM06pp)8fF` ze?X)~1|GP#)B#t<T#XVtZ!qJd9=G1JuB01;EB+=5mNHG~-Fc(XgVH7WW8-fD zZF;=a)0u8(tBO= zb^EV7ex0|wxqE;2@osNVbI<;s<2~Nq=HC6i$9uhf&3*g(j`w+YHSgNL>-aA3?&jV5 zcOT#Fukj|s70t=Qd8bZ&HeBfUIms{5D*2hPsw#=A`Lk08)Th>ddfl<|f#t`$HqH3j zjuJ;zs`=yoX;59d^^=XBp-+mPZQ^ja;;F;$Z~Wz{kHP*rbLN_+Ddm6JSePQUaNdic z(uV2}CSm3Ka7#hZA1|!7Pu(Nb%DD2sf4!PF?w|Il!&^TEod=B0K*h1cgU~sc*7@ly zop)%R@%`ZeRkIZq!_=*YvRCzO3{?0XZ6k%%aGrf?KzRLOc#Z%XbR9v;MnODAXo2Po}$?^VGO&y`j$_L9= z^*^e%UD@2joShh8@E_~*hz6EkEq#*3)1a~CP!Tvo>@M)O;t}x zjrTVmcKdF zxJ}LXrN+~0K>vU$-CBxpOOL*A-Zh&iyLXdf8ey|&nhfRUvPVL7lpXe$`?i%HJ&`5LhLv_nOYG0MfurvK ze{9C*vjb<_xwU<{LQ<)J_5(CbxpBYe7W-Dq4op$UzxHG~XzXCf+a~;s9o6LxgWj3P zqh9)3k3zUpc)9jl*Y7`rAIkGP)%cx>#+3Q*+ME4`z6tbUp}#9*Uv8MvZ||J)u4>S; z%j;aWb%x_Q#>WlkmFO7nDgbl`EU!gdu8nF+;JdZXl|QD{ zH(f3lZ0Z#sf41+Q!@kQLlGi!OsFjBPEIi`#j)N4*{Lb!k5yb!GaVI=y*# zL7x92@y|9)yP`aPvGCpYiDUI#{gYIER(P}xR~sB7di0Q(kITXJ+ZMxW7Cv7ewbS@G z<;m0c!HgHYwOA?_x7GWy_#T9KX%+JymaYX>Rvj`B8((IFk(Sj{ooNY~L& zEe%_}q}ekS=IHT`SSz1d3;emk3*n!1 z+HwisWZ+v3++`qbw&ZgTSLC6c@Er!;WZ>flK55{vfrUs1UsS<}TIAmx38;4deHt$8IO2AqPI8XSX4j-6~wB0Gc_c-&y{0fXOT@cRt@n86=6 z_;(EcjKNWJMBlFr&haw!k0*qFR5(T3MLppq2A^Z_OF?{(#?L&KcrppK;34(aid3b_tRE z712T*Wofw3jpcV#n`}CEG?C}zU?g&W51Dn;IbIDi>UXgDU(w2{W@8t2P0i=~CijBm zV294DAY;TfPbw!RV`Rb-cM64-=6}YJ{J++K%_@~WHW}-gan00(;wRhFC`Rd4G#R-@ zX|^yPZ$VMb8lqpI#23|HldHZ%B<<2F@vNO)IME`fyZc7oh-u& z@R9fJ;!%G5t%d4oC_~pKp7XrAsCTl$0vtMdY5gf~;N7Dx7n+-h$p!7Yo14$yY;%^mx7idIHPLJC;j1gHH@DZL4dX^9Qg^7FPgl-fWVaiF&FvLm6 zu(-v<%%{fBG7}Y4p+nVLCNNI)@kI&O2f4I^E-VVjiW23tH<9tmB!x+Xj)*1s_%vo0 z;JzonBYr%((9_XW52ZyslT;g!abo5YDrL1iZahh$;YTd~(kq)?6*#Yuo>Rao=uy{4 z*DN(Fs-2Sat&hGzr!zgL@H+ioku#?dn4!Kr`rj{xxGpw%Bp$M6uX4WT>{zd=9&@&b zR^bZ7RkfXpiTzXg+r!722Ay`SxAppKqHS1LTaawV+{57OqG6xID|z(lu!R|fZLs_L zl30)X*rt$G+2DM|Q8TXzUDML&G$zN{vz&cND_M$JhD{;WpIp5$6u|GVj}!$}mE~U> zR^HbI2c5O+5A`$j79INK_K;rDoRm0)gjyZk?O1bHu2a?ilvQ1wva737O~Sb%^!cQ! zv>fZ+X!-4j=Q)ewb>R)pPOJ>3&Nqn6gN>6~!hW4*Uh11f-5vp@ha0JwzD!_Bzg3p&|9M9hAmhI>Ho!?g?7?YKUQ z>kzJ|aE0Lar+}`j!A-X9^N+Q@`S*>-45XtvFD>V?5(Al<8b}O!{artpIOnLWyYdy^ExToxXT)S|wr*ZKc4DJV{+lPzt zFnecg;I=d6U7)#sf@r{4J6wE?!QHshHorx5WNi9CUz2N@x2N0l3$bC>E?fMkZN!!Y z*0D0^x8HQ`yz1KV2Ux+JQ$`nV&vxVfXPfr9Y}zK5^lPA-WgHZZbW>!o<R?uzq-v;+ddi`l`ei4ZkTpn7T$ICkYSu9qik!2!e|#pT>1;qHj7)YRUtw!+>#?v;T*e;?U!kt zhBDFRRsV{mVOom4nI2@@>K~K}d&^wY?lsEKD4a0r3b}mRt9DCR_D7}rf(k79K@b## z`S|#)9ObA4?m<}%Bea*|>&f)4MdreT7o8H8B-5V061HiwE;5nSF#=&Gb-KxBIhUYg zzt6x24Loe%(*`1~BDWMCDIYiR7$DaZF9)Bi;t;B`@p>URUc>~)tCHa8zy-%^5nnrL zbA6l;Zw4uYf5+g%27lh*FBzN>r@Yu|;a}D<1Fs+*xZm&t25&a_MuTrLxMT2kgTGpv z?klsz#&))5RwZBf3grtk$Bx{GO}}jEJ>l{;ZOdkj*zAqrjk!Hs{$6s~nnr9q*VCJ| zH63iBS-aNdtlGVhE%DN}(erJem$lpFx%4vPS^M~nY7<_f%+4o~wpO(}n&{;hV%Q`N zOP6J*yVvAGUw15#-`_1dZ}rZxoVvYczM4@is1Ba~Tnp+#P`m{fXg)=YhbGxG_PSnJ zm$dzqHd9Kb7xp5IS71GbZ|zp1g=VwOSBi{z3~kM*j*@i37bGB_x{O~o(xT5OXpRXX z`$wy=G99$ExLTr}z%on1YqHV(-sORI-3YyK`L2^tI z49NglI_!!;7X+Wrk#P01H#5%DPdV2piT=hoSJa>fU3xm!Uf8FFD1D#H4!SqYMRpm+ z@$LaBC?OoAS@1FRCfb#vOMyZ1O$NOJ4jpAFC8@!6povGXJGgoT9G@;6SB929y5jMmk3$qpP^GSZQS}72YXjioEg`4ve+$$+8T&Br(rb#bL&EREq2Awx*IZjxQf9Ad zQ`N<=nU%n1HaX>~E>HbNY*VF2L)V7d_-oB9Z3?x$>_36aS5r6~y4DuT3!xKjFN6j~ z#v_!Ufuj7RoIT>JZaDdqHD%@gy2;)9ioQGX<(Y>A|Jd}NqHh#EJE?5qN3AJMYl==z z+GI^{8VAZH)_uWm7Ct-a`|3UTy-%&h@7vT<#op@ggeIO0ymNWreWze9rfk9sEh) z+ErridY6pI@ zcxF@YC7%eqtzvT1vxmKxJ#*@jkk$GEY?v=R_L;Ene5lyZ>d*rTl${&w<=DdHyQu|BJ`@<*NER@!*El%S0*9|r~Q73_FZw*|^ zyGfPB-od6?J5cUK4<@Y2aN%InLEME)eFCxg-uBm!@^WRdP2Npm8&*)R**+7!A@or6 zCg)v}r|$}fobJ&5iN<#`KKC}2c_%mBAH^qz?<@(H&;70{555pMcKDW}<3&H4R5kHY zYj#sJ^0wVt&{P1*Lg2@dr_ZYeO}7;OY|^6&e97YlO~;D;O<%m^U|>^))pYW(cm6Y{ zHX{eF2{pY_`R(98sA<7}3p{oB>7qFk@08N3Z(3jU;-p>HoTl+odi71;DtvL$i>kiq zy?~!nbDCO2bA8iO#g$DrTyj4&`;6w5>#AD=uyof<^Vg{BeGAr~yuauv)Ydx!C!4$r zW}UqDol^qWwmwlbW#T^6*Sk<(n^0fhhWcv*F9ZHn)YWIzl%{=!CntSaHR5-ZdVSLs zNJVMWU?A~MUsJqw&hV$9=hGLg=PreC}5zF!VgsY7bu|dEZ{)Tky$e$G7-z zIO8}sB(5zkDYg@MlAG`(H{(fe!IQixRVcCtZP|@p)GBtZD)_huZ_2T<#ha7s}ku)%W+0pkB8bm51K8spM}n}{VY^C z9KY5h_`d^J{)gHgJgxlHcSiJ`Hu@}~{YYrfhf3R?4{by!rAJsVOOO6A?Ax7OJsb}0 zO0NEwun)iA4~K5%yu-8M@2wehruIL()?Q$zHsL!4PwGUx+~KT){w;m%WcbvY6OcKX zma$WsH)tfkfx4bteIgvf^Y+4#udl!PP)+}J{ez9kl&ZFd7>8s(X2+^$40-%dgq1xg z&x=*j>xIk_DXSx)<|rwTt$TFC0;j`S z5Pih?sZ-N$LBd8mT`^3qs(xL{)mAE$heHdZ-XwV*lt#Y(ntsND^CeSK_lABGx13~u zP0~9j9#pdnlhy|d_O9ByO1>ST2FuSGjQ54U0J)!>ei@}fy!41wx%Zc)gM;Cc{(X%F zsZcU>ld3LANqqbR;FKQa{n^uJj}!(iq1@P_W;;ob-=F+sGUj~J`Q+Xo?VXKb?Cf1P zgkrl2oK?;(m}e@8_HHQXJL=phc~&ENq_y&Qx!^tF>p~@Q_E#m29cRmQN0aSzhV1wq zO;+XYo)Ta>%*uXiUO~!9I*6T<6}!e6Z&~m4*F}@NTSGOit)V2Y)0I~D6O|3!U#;BR zeZ2B3-CwJ;dY-Io==pl(-kuYcU+F36wJRHXk?!8L{=Voj^`B5%*>BIYQ=G-APn8Cj zJEg(H4k^*Nnzt}@g;VNJ-fa16b|rTyf6Z>DAmOiZ94Wz|l(98Re#CZB^5x1mhpbx5 z341K(7Ubx{&{@gTkDWdgf9mvdCv`e`q`HMEtB^W3XWc`Hhdop$dgF3mBlnVjDDy>v zDL-+`??@>8YDDMN>p~4Tsd--IL;fiBWEn#rli}D=hd(e*Hm1m;huo=Lv$sKCTwrs z0T{ux9hZfWeeQV&bhHBx9M&XAkA4>_mPKOyxWA*Rhc#FSWBwZX!-Fm5{C znw_hgSY8Yd5e$3p@9@{1E6 zzMgqP{C+v4q<1RCcSGY^kuJ@j{S_jjRNoMuOtbMollgaV1=>cgSHyOXOA zg?(tV{u=woCs#izdmlX#I))vPJ{20k@57y39_ky;faTFtj;-Nx%Ox%#Y4e zXz4z<&QrA@sj5D>MqM`5xhAzgzAyfb*1Oht9=7gM?|&k0&8kE@NPP-(wia@YbGM%A z4XHarYll7eFbB=oT}H|tx=rF3kJ~f%-iS7Aj-9kVRJb>|w>h~t`J}|HX87GAvp{PY zx=}Dw26$qw&(h%ecsyt))vR|0tq)DvyBS)nxqFje7d_*Lm0un31nr;|v<@(qY^$#o z-_aI7p17hEo~yoi$RG9ktCQoX^rcJ&WW5ju{l{{B!P^iQW>I8qzBi(0K+S6RTCtUu% zW;?khnZ&!T#QVU5xBuvNiCb`7D1n{FZoY9+(sQr%e&tUDmkhHV`7PQ3x(19*Lb$@X zq-_E1MchlfGF1gQra4hitRBbp1zbmQ9mDk%T;Ik;cb9pHgSRw^(f?o>-3oDlo=@$q>9Z*p&<3OA1v?pR^Nzc>RlrLEv__}XQje3 z8XQY{GvdXf)f*g;mdn-o+4!$c^Ilb#p&!^4=e?6SgdN#*3*;oMnYGh(8x)H&7Jm4@ z3D0pkp5u3=J|}sRyveG5VaSgZ{7m}EpA1=Zzg(oMJ0N#$>N6rkztpZno103$MA~h&!|@*^en6Rm1E09vd)E(d_uNG+5uB7PK)p!>y&oyr>-or zc{A3ykhT}&!o8sra(`o3kNP~rUmE_4;ol8EIc!yTOBiPoLq#JDO&qG(%QSS zw09Wo*Fw7*zDi0kju7G|gmx2xRUI>WBdG-r-%|D+iM4O$#PoC0WkbcY5W0iX9$GQxDEBR$rzbNUg zdAF)wh&oPQ%wcV0i-8F$v<-A@bJ!lOGx%0-vFgUfcE=st%m9z?PbFwqsK=`Q=d|vj zAFZq01)B|{C-q@xJE%C&`##yIcKg?%$9-iH~np;Jg z)(u}k&U%FMxMNjCLhUnDzc-y584dQSw@4^)SszM7sZ%IN)`h|? zfp`F|c>(%0(hs8a4(?TRLgAX=`e-P;20K4qHJuzM@eta92GPmVn>SsrrrI9m2$K?4 zwcpf9JEgxTRx@W*>e1>Fj3-p}#Gxfz7ZwFJ({}b1Om^J0X%^a~mn4OyM{AB$t-JY9 z9M8`iOfFc}a_`I5ide)iiZ5rwXLrU-O+jizw6q3Z8dmb zRen;-ggQA*wS+oRs1rlJwuzyTmc}Cl$N1&Fx4UEc(Z=tLA8Y(nTz1&kYlly8SJbpF z^2g!AlqbJ+zQN^@&dCGXLak6Bhfag&#X=uQ(`$hLZ&+_uofnVHTCtJqw8oarUjOxn z+k4Yzjf_LKrQAl`SxyUZ@xC3G`yFzHp>GGgOX#`ZQ2RmKit8+{R$S>dXSZ2h^6~c9 zb(vF!-%pJt!}w6bmRLi80~$KcjN1(>${+H634~Amxuo_ z4?kmYhRb;T9C(%J#k#n4B}hucxJLZC{4y-tPV-wdzX^Odyrtl0hriO`Ec*qx8iBtk z`m??tZ^ZZGT_scA)i7=~7ty(CTn5>gElW+^cQKpZvTjH(`7U4Mb4I;t(e%s#9bQK0 zUo?h%;~4U5#-MK+gZ@^~SuXkMx)t>7c)I!W5zv`0E`HG9ZhkxnoaNx^OP2}gI^Q#8 z;_7%lPv=jvaHvu*WZ^8U7xVC!@^J2`lpRN39zN0FZk(qA&yKSjuLXJj>hkdAd3xRi z97|NvX|Klp0$eSiS4(}(sq;zuHmUQW>^k3z&cUCh!_B|DLGKrOCja;xQvY~F_|}p7 zciBfpzf9Ot?k;pNcX%1Utat>c^llTeg#2!m-?z)JCukAs<}5PqDj{AkzY=FRZWU!p zt;vg^?KoSB>m{kfmvd;(JAL%J$28_-e!bef=^4uf_c^-1*@PSxvlr zas8k4ju=c|9qK{$y!orH6@P$r#93u?!K;XkpFgi5KF1njoky}1%4Am?AO8{V6YQYU z&QiI!orinWUr-)>hISs|yPueG2?zO0IdBoD`Hy7b)7IAU%<5@WQ!Ssq7kNN=cjPvH<1$pT!lK8XV(5@(tUo3pK|JoJj@y7|D?X-5| z^7s?-_!IK@lk)hJ^5R>ry0g;5_1D`C&LZLZ>$m3Me2dYp8NieE;hx4Pt2gH9`*u37 z;lZ|4E^e!*viMxjeN7gwu+VKO@KYFj@Lh%bCeH`nWXAZ!F9JRR<;(F2@d?0pm@xry zzVse3V*%p-W$Hq&#NV42o>#p9ejGfCaXXKn7$TG_DuS0~ z)jj$z%JW~O?l$@%4t{YSzgXRn!ylK&AE#P#_!IK@6V#d<{-ivOkA6C4!$ciiL4Xb65^!o`;iPZbxcvO+P(cx-mp0NLN)EwvsGHRe>LbUZ|Eq0M+Ziffbag0*`v5vJ2&9P5rP83(v7(`1~^B zNbw4O%lZU@MO^J|9#Frm4ttqMXe z%V}UY@NsKBW-(U&17GKpXyFd-n`KkEX$lti)guM)_Af%7s)}tNcbJ(q1*+$QR))vS zr#!{-#8KwgW%lKGOP*S+eB8-il{FQ^KPW)HjBf!{u@4B8`iij2%tux6X8HoN7(yOZ z#>(>YE80nck5Wi-w6H~lXO}U>a7B203L#p=cdat@R}k`yFP@`*@nx0} zQdP#6HtxR8Li-VL*sORQh=NdjMQ7(l_o5(c5vJ(AJ_ zR7Q_l%-HS%5#O7yaBz=6pt-D>o(m=dd$X?eD6%qE_v&iYX+CfW&{M{zw5(703+xa6 zmeDIyUcTL7E#`zW&okZ+@ZP=yKWoa=rHA3gs~-l^(e~k?LViuq%XM3nKF0}LD{+r{ zS*B^-#3V9p1?;i1NFR_Y-3J0f-fzO1r^ zhG4>`6uzvH1PV#(l-;ZFV&we~El2{0pUe2@&t>2|tE&t_bf#`V9SqfhP@oj_`J+W}=g!zaZiDN_~hB z`TjXW{~{s6dD7rNBt&`q#NcNQ{2d|WeB%J2Z$2U9RuV#A(9l~6QT`o-2yej9KV;~i zAw<3SoPoy-|4G8TQC|qrC8P}hpAG-V2EIsm56XuS&BYaHW=harG!sJadP2nS9R_l| z%lLE>q8<(s-Va+J;V1OF9?SJH;Dj8H6P_Ss{WthoLiRxu0MRv80W$py2%(Sf9n|+$ zLvJTUJmQ46;(deg4t$+Ki1>bsa6jq?;e6yb;Rlf}L!UEI)9VQ5V(&Xb)XO!5(0euE z&Dh_=;CCB%A0g6vkP!LtI3dz~oDlImNr-s9K#2ICB}9IXM~72#8`=Rv)SDTEi0@3o z&tQuQLd?!S>NdpH6;r~uT_`lo0gM{$^2qFAGP6+?U2;u*P zfhP%(f8Qg7o->4uzkz(Eq#hq3^h_m$o(e+fsWNa8;Xb^Y5Tc$fC%hB!Cq%w(B}BQj z5<+e}A@uYcI6w$}g9aWXME*Zw_+KIqRFmm9d!z-GcjXdeu|m9QH14UqbhgwS^w%-;eOOVLg@cn zgC8SAI-fT1IYPw$$ApmkPeR1|cZAS0wM@eWgm_Magpk`r2)TC{ew>i;AUuqAixB+% zgwXRD!uO%P2_g3lLd5quLg;&*@GgW)h{!_z$!QdF4i+m{|;#*;Gzrp2vC-|>1_*TQ;X7HrJdkucT;CCDR5rZEx_;G`u zF!*;2{*1w&H~1NYi(Lod%UBulo9fZ=EhhxNz~D6oZ#H&8~mWbA29eKgFj~QV+KEN@MjFpd3(l}^YcvaPYuqq zN{GK?a9@GO#}ihez8k#C;4KEu}|0~~bm9slN`n0f4evL23P0O4Q zsPdt_k>FmYBPFsA0n71fPR$Zc$(@njc&s}XN%TaLOu1~l$`esrV-XzBxhv5Y(`SQ2 zQa;tEnCsOLx-$gCq-fo7)O_{fV1Ihp)0qDIpwqV7p+k~@iH%#CJt_GWT!EG{!7+1s7X&TP-hl$xAR z=U4uYw}_`~sOu)m)uf4e8G$26vx`YkQ%IdzRR{M>MR#mx6j{epZc+TG3Z0Rhv(Rxc zUY|}jJVe`db?9j8LaosipexD4auZ#h5-H6=j3CN0a&d-kZ(BTzg_Cn}5^pRrnzwWj zYAtf;Esl)siMDp=C~yagu{N7H-@X#8iu5mu?(57{0+&eGhBNOYv0XezFk61ab{J%~ z#m{q?-}#T~ODCARvg_2VI2bV7yE!dQ(m>Ut9hEogjvg1btq4;ut*K;UWP4vHcFka8 zfkuOsFSCDho|Ky`U3FBnXHRFFejNEU$2w8asEPUXXj^Y$S1gBWTB`0?TMVrB93CEg zK5#e>GT9MB|B#L?bEvz9QON2 zc6B7$_GF|a_OVEJPfsF4WRN?fh)_oddK_u(aL^@AHtyBWdZtgp!M;5mUA<_CW8J7) z(az3TM`U+A))~P8(vdE72FR;i#cpnn;s;Oh*zyb_(WRf{bOez9+?~2dmx5{bb@8#4 z7?aBswnlr9eddAhh;{Dh)lYm{xs-E9Vtb5H&Llz}5R+7#;b|W7v@bLj+Y|kf);;-! zs3Tg-j%ry>;2G77mh84&Glsy(rc=Tl+03S+bB-oEErWcL_M8uf>HgBZQ92~y;lRS& zZZJbN>N3g7@ApJBzkd{BeivetvR99dctWL`;+*kJKo}92hBvF8WH-g4PuKY@U!4iv za0-{j%hSsqO#!9O-K0=rWK%?{ zJAlg1TJp~MoKfJMHQp8IiJbGv5wX#pJTkHd)@)XHBojE(J=WT{13`C2c6TT6sE)CX ze7YH?9y|+r2!0{L>2de@gjtO*STluRk>;$lOZCp`y_6oX-gJvLMhMEDTcz3I$gC#_7vx}&gAGG@&B3|ed{5wOcUFM#>A`iH z?^OXqcv7WRxLylk95t@F-`x1HlIDx%9=5BDCr$e$K`(!%D9_JmMa_3cIRkU`OsC8v zA}FhXaK}8Nqu9XlOgw<5NQblTMsg(1hW#lsDGHi+rwz8!c=4N49Mole59K;jiF%@4>>!ecA z)nsUQpL>Ilv9%Xsv&B#z($H1t7Nt&<$%rdl-GZKM)US}R zBHrk_VD#|egu^_qb_;x4o+x(_z+xl*pr%nl$6`#B`HX)dgP@&P-GLQZc%G?GbRw`` z^3nmgHIebWLHqKlaf>^7s~Z9>v7gKPgd)@lUJ1mgsn;I)d#Ap|L>}E@qn;bkWp;;4 z$B!bV#lE|l3D^~G7IC@zt#`*8{_0j(hTYg`3F#6KEYV5mEf$w%_ z;49*alqFwI*GGRDT9EWQ%Ksm7UdDgG@2?z>Kc1|2>Z85f-Kp9GAoaZv zcdAjTGY z$;r>Jz2f@m&VOD11onFIr8YVnv3tdYq2gig3Gr;|A5UK?6fgFyQNw!Ah=)Uau5WNY zgEN!4g9!G1S?C%1T=>DhxE*pV?4fcN@%>~=Q83p3sc^LwEO&0?z9V|a2p#)JB&L>M zRbq>#KF`9Elj?G7s200y*b6PBr(o#N_5P$i{Ffqkw+U$yLYgr2QS4k2D6qeyPbB{! z_c6iVFdr33oY9S)^==K_wxKZLnYnkZn!UGWMci71I4%mMK44_La|)BUCU#Za8lCR! zUTe>s?)=D^?O=~9r+bZW)@G;pMm4WAHMst>@qrC{`<6>+`egDSMLSV@2BQP^7aQ&sr*f4yh^ zn}@!EUD8&jtjj$q`|`_EPUt7YIFTj6{b$}G^0t3@@(YP@#TTM)2#VC;Fzf1NJ@6olXiVxncy*sc*)y$~a}sz3cjlwRW{Q8F-Uu6O*u#(~7ox|IQ2Y#T2F?5x^@UT)ZfFWN1EolHv2v5Wu zCcqk!0Kfg`UU|Q&mJA}Wg-8&aChK99;Ter-=ezohd`^& zqPzN1pdAu=?zjIge*gt{{V06CQY^srTkzRmy7Dgpr_TKNx%{Ugd=ajEKI4{M2QKux zRmOwvwfGHa)|lu*J_D_-sjvBy{ti?USSQsXZ^-zn>&GA9YtYn=`i=$~t$wA1__X5oL86JCMJ z#S8QBqP*~mB|Nu%WAB;ke-if-Pdk1$$#rLRi~_%#jOXCCdWXTW84oN&Z^(E-7{7S=@7eIX4qs8^;&vYHNuQ%bFZ{CYsvQ4bbqVnQHvI=JW9%pB zs&MhU$6WaWHO}xke(=C*l*=!azKQzls0YK$aKras*4b#lTJjuQzbez+nS<{uAZjX<#SeCFXk+ z3`G3MRJ#)E?+8&^T!%<`nk$%}D+ysj5`2omQC5OaH8{)}+bCD1ltT!M$PES`F!

Gf{z{A7OR$z+8&NhrM}%3W!P*;%v5NSCcUXZjkO=}gy&5o4fNcG^%z z&j>}M%zw6_!O5NfWP9W-D7@ek+h;=loJS5(K#pvmU?gSwlZX!H70i7WqK!whN%xQj znQ0z_1DJzx0%;0-vA?}f6WsYTV%hh^MR_yt@S&3i>MnYR6Ir(Es$KCTNO2mPI2l?l z@X5%B;nQIRv;`lvAd}6cn9%oWCV$cU(G_UGUv^07`*PiWD1;0G76tr?QUa$qWjpk5 zn9i6iAGc|GX+$7qtC^W2+}&>ef@3{k*v%LgWH~noOPz5i{j%emmgJf0bdoz5QHUeb zY#6FgScYSOr9H8m7H4FVE^hP{WxTE=3%*R1Fgd96=6Tnf5%;PMhEn8mT&N}R>&586 zbwS*?l4np1M){juJ|Qe+#?4hPDQ6nT+_aLJL(g&N6aF^&Ro+SL>giG%kSi)?VFZH` zL%Gnqb_>Xo6p9+MK`6$~7i7Rkp7W8`V&-@$ZB$7BTDDY87~mb^!=N)$W+cK3HEUlJ zwJ&Ha)pORFcu~yvJ^sRZ9uvSEAsi_1$)4|TT;~l|!y0W5y-_5uSf7lSV9$TOi|(1O@s**b zhH3tO-*rxZ=(>abgVzoBpSaG64?6za2lqO+pV*s>2P%@znXW*^nH^`kN~*0>%712u z<-bhANFJRHTWm?CZ~C#roXex`4#KTV`Qr>DFwNdmi}Pb9H#P2gdDbO% znSF25^uXk%eS2_^bA5RK#GZ-v(vr!A6PxzN_uYQ%_75Lc-l8Ta9+=@^?gH}(_|@V2 zky@Sxa#{R}U`_Cz)lZ(*IPCm5jY_|F4j`{+JFf@6gf!T?Ye34j5&p64#MOE6IG3$* zY}t|fwoYZ5jjIC8-d~br(%OZd*&lH{a5j*GxOiWIi|%e*>>Kj!tmM5GZKXM%aO{kB zMt8)z7j<2b*|e_hPuy(E1lF-)$WVRsoO;!@<_};&9X&=Uy9+j^j;i6$cGYv(RY%J) zc`F!=F{-r{_9S;aC3VZn!|goWqxc=KY=9;59(6Fszc&x}skSUW?UC0Q9HSug^Ojnh zgJ*=Bh3}3<^+1&N!|Y8{sP6$iu9Mg(*zR(1TYWr>PkZWuEL>r4u(<|j+e~|BF5ipA zoLV)1X>X+auGiAXXY1&CKaNP5m}B`THR)lVZs9GCXM{hfs$}D#b}W+Mwq&!Z>~`#8 z)xusuYY-D22ZSH=>~m>m>lYaKw9`?tXA<+_qTP&b17W~Gu|pvmehBkaZ?TKPd`#8c zze{j**@9!-w~chz(Huh9)p`xyZ}0;KXP-s>L4!YF@c&`EmbO%N$9Dap51Zb6O}IAO zJVk@X@AHu%{Az2HED6sx4%ICc=c7f8Z#Z4V~1kdQ2A z(bk~UF*KiYvlYKyt+!OYiL@drm0c`lS1yrC|CI8M+2gw6^ju)I7uj)!bXmyj3J}gJ z%PK3vvMadVgm^FwSEL|BRGZc2(bjo=r(uu>ma>hdMEeCbcSw4Gqt=yrnT zHFfn``22Q)W9U=i(sqK2v1p!=W7=Iifj;+5&3v)t*Xv7zR^bPf)pW_Ud!ti=1%+17 zw|HLD$JD}U4@d7WAE@;ue;~hyw&3jA`Dae~la6!H8Fu{9e+xTNU+`fm1*RXF}a`g}8d=~eN)Y2oq8m_P7T2T#?N1nmCbXTxHByC_S|!#jrQFJB)c)xzniSiD-!jw@6XQ#T{;smqU3k}Q1+l0Q0)<# z9;~1)56&X=2i9c-NL z)H$95Z%;LBIE%P47cKt}Pp=leD?^pRV_m*l`~5m6z0kQVY|TBfLm{u#J<9{?fV%w6 zDf^zisy0+y?zv|$>brMR;}V=?s@|@uYg3ss99M`&joSwlPA|9anH^-V7o=w5yh}IV zUmsTfu;l!u$oYx)+V}XJiTCovJEp!`w5ZC9LiTLyDtmZ#=*834Y;2WUJu_gh096N)--!XZu=Aoj`pkKsfqj%<5n<&eyW!=!1YzMN>AZB zjq4>`Hg-k!;Oer+{BO9M#a5pYhz&T-(ogZ$xTEQDFz3qd%;3!{7>$>@eJTtpt4zbY{oP<+Xyx^2+A9`rZrPXk~HF z81zr%(HT$begyRFd^>FLvFcorb?(z&kTu4=7Hz|3@03?&6<)G*`JeV;S|%`K70%D2 zKc+o6KQ6Dt5}fDv&o-;pElQExH$-4LSPIG68Ln+=~a;kwvdeu26oOP_`QrXmaH z`5(FR9FcjE$e-Yymlk4E5S&-XhVa<+{&5h6JXw9_Zc6&p2RsG(4ccVRI0q7-=v5BT z!odo^LWh0GQwm;kXJbuTp8pToxZ_fhgv9Kl`|zzur%vd<~5w0*lohhoacp$v#y8H~^>Ch1b1 z)wW(~fP)z5UhgSH$kotb+xEo>7UK>H4DUg3wtV7?;JtR+wa6<5#L=)Abr?Q;kam8L?R}#fXrpg0y`Xbvrj&T!r#f&V z1U$i!a<8SUMH$Xw@URg6k{q0IpsZ#Hz^^@DJ*pSx{EY|xBvqw6EToL~` z2!Fpa^m=3${U-?_H(=nM20moqVM4_G34?!!un|uVVKw4~h|xa|&k(%E;8zeLysHUU zVh*1W)r<9p;mZ1D`1=rXz@Hn)eQ6oqQjeAk5P}~hY{b6Ogb4RmL;nOJ()%PK^m89s z^4Yf9SO{~5@M0{qF}Um}3wjOO2lAH!mb@9}OanI(HsNi95PEhQI7s+L>~~JsjJE|s z#OFanXIo8uUo`L-A;Mjb{I;>O9a*68DywnK_Xv(PGlQhVqIV}D9@Pg7{*b{RGdLS0 z@{b$*gu%aO@L_|qe5voO!N;SVh?f$=KhLWq&UrcFvR^Xr7K6tPzr*0NUo!YN7<|z1 z?=<*52EWhXj~V=NgFkKXl);}j_!)!yP~MEsctXU7Z%4#szhvO7PsHmDzs2Ai4IVeR zv`3I1F!+AMzsKPB8T^pJA2awdgC93I-_UKpSzkUK$p7^Ea_s8K4VSR%9(S_ibeY}@ zl>3aD1?I1A-&j#I%ATu+j_v03z(y88=rFOz;0PM_Sk0%Umw$^dZZc(tNNrtx?w*<4 z&y<|ZetDzIdW4g544dx2GZ}yEo*bLMCZC}l$qZ3l@hY>UdjbpvbSypNcITyUcX>aztmV#Hd7IK^v$IOx1f9dp+6y;tzuBHxw7V@H!IuHtg*IKi z&33|W(oFO+y9tlj1<`~$%8rWQj8eHlz3|P9r7)NQ(LEhqd>)Vp?mWte5Q?OlkFmm^ z;bfAP`_vlmlC^o7;mwqp`-wwcjXd+_;V`e`n7>}!zG7Kydn`8cJBJJOAv?jHE1F}Z zY)N*j^BSAo&Mk$}U;Zv+MmtZ>=!!;}#g3xC$(_Z%929P^_6M5BM#naC9vh<)9mXq~ z$%dzl<1X^9)040q-*CN77DEeQTx8~>19;8jtBdQ7FDH*avWPB|(A&&k%&Zc?VMr(L zZUX^)O5F@lAWR@6WL!os?rsDfau^zoPrp1C$X*SgNf1$T#hIy7db)l8BsxLa=g7izxtsIUpxx`dda4{FILQV><|~&0Lqj(`2?LXOa6W!t!uc6E3Qpw>eIDZt4#bflcyHV^zH6$3=~;;MrwOhApky3( zIf2V6Xywu6CKW0P-X*wXhcpjvNXT|nvQHB(U$!_sAJ3cf&B@o-thnH{`@X!j`%{qP zEI($XJ11Wn9!!RkzGQMWR`CaItjC`qGlV6f=49#7Vwuw`3JvrpR~Lo?`1OXY{=LbD zek(bsJYnBfwOXfRKE5e-%TiPHx61#!XT?U&UR5LV*>QGfx<;FI7)y4vSur-ou48p& zWn6&Ey?1A{D2FFTKD%NY>*7_o&&KCx;nahwo;EMM7Uw-U{KDq3(YAP^6Z@)N$YS{I zHGkS`;hDZVR11z<^RnlUIpdKRl~*$1k?Zx(^Bw1y@5sq28K~w^MxE`TjV|LXIU_uS z+j+Q0{RZ-lX#tP=S&n~i9_~|L%Hngb;;_NlZ*Z>S!5lmz+${V|Z>#Y_^{$Kv`kr6B zJRu9G)jSu+amiVH&Q-u_opG?~zt7-ob2(R$%lE2XS@K-tZZYC&6&hYKZd+h;d_*fR zns?IJ`Ll(e3~iV`fb*jB_5N1IZwE7`(&?FmfQ2#30< z!Wo`lh6ZC220C_Ym`>u9G@M1I4Ktx=hD;r1JWYlPMU)KX_xtwSckjJ> zXDOL5L+Y+{Z{PQ4zy14m_w9b)K8{ftOm$h_)Q#V*KC|t$*?EL_^Wr-5$HU<< zBR#3`=M+Ap@Y4!kQ26T#R}_9p;dzB$RrnpR<=Mj>N`>(yo*Gf_9Wnmk2ll&iT)Tbp z_#qYdnFG6kBRzA3Bj!^pOJ5+v`Rc(hKmp`ZNc{Jsa8AS_J1p1%BK(OONwOnwX{}a> zETi~Ylh3A18GFKeP@TVXi!6kMdLQcX4|R1Gy1P1S*FlyR;HnDzQm@z88b_#rV>|qM zt#{+bef!)mEG1S<%=!l3n8WKE|39_#wP!nsUMYVWu>8)2*))`fKCt&Yf-ogucKP*t9H5K z7C9=>XY_9p=1Rhs4y>O)MqvjA_WvLD11JLy@s@mQ68H`z4nbDCd(+0d9_q~Z;RZv8 z6=*yc3q)%n**AIe!(pe70%?BG0Y+~VN3H~;tAa$qVV4UoX&!T> zV25WZ7h8%y6b^f7HcxOb4z6fgX5>bTTJHS|3WftrVQL7cNZTa@f9;?-q8bZuh zIhQ|^$Wiw=fge^MDz68$oGHo6EnGIa@8gtclWS^UIhQbpdz%mMT>U$}$!tSY^D?YD z6WVI~x-=z`rUs-5r$*znSe_A$RL-aTbn{ec zoFa>#JwMvadp?bM`UZ5=duH7E($DohR!popA{yw7Vd0r%s`dKMoPF*rc7{E(>Z|wd z*xq=@-nniw-D?h;)t~D1ZoKuLm3@EHXEr2{r1Lnhd5xJjYdS?Aetq7iwFBDk8==vE z=H7Jv)+0NoUu^pR`&h280grR7Hzrk28z&5`u_17`0kV)2)7DYE9$N0#gU_qX_C3Dc zyEH2$YPF?Z9L`@jPst1CPYTb%`Oo(K;4)9l{sV!Z+?n{9CwE;O_*T)hcT`Mn_D0ctcV%{Gert~{*`LiDDMf27V6PTq+W|JMk$U6;Kd0|) z{h)^Ta!ISx?N6-f>sfvtmJm1tqImZYpLy&|W8OP?bN)u;9u^O`x4&$|uC3UdC);nH zb9e8bBMoQrReri??pTGhmseLFkQ{Hw&$fDhNa`DB*QkE^`zq#ZiM9r4xZ`83xDHGw zV13}t4@~!@d(1%b)yumjtfdy8S(U#In(8+8Y{lGugVq;pWGl0+EtR#?pKoo?cMXuk zway}B7th<1FnAX(1?Ks}S@H+(+WX8guG$fwXm7&P(}X&@RnpRy$8(nZ@5_nYf8og? zhlkVBllZ0ZTPHjoTC6)Io%bttK0ms1#;oVr>AqaxU0RkcLO13~D2+UbUn_oe>)Rj#x*URpK(X8ZEWLVHW)EtFxWlp)g* zEW;$=6n+i(HR5Mwnf46&lniPpRmsJcz2j>FA5L6H|MQbRAA3I5AgwZJ+p|h2tl|FP~Ksw>H}z$zOHNw|0G)b0X)cMzVdy%u(px`+Ek&ZHU45 z0>^mVI);#wq@JpdLItGcXP;< znBU~VA7^>+0BCV(q7GRcUe3-GS>d|k8MB0KgJn#;;@vT2ycSdXxH8@aeB5&|0z7wTU7fmo z9tD1R4F2~bc&6`H@H+)O)cgGXm$QIbestI3{))V3EM-@vvt#q{kG3%hGuR~!!G8gJ z$8F+WI8n&e%#sffVt^m-oz&YqadkQ@H5|G;;W_}pCQKOiB5=|?4u1Ov&j3lGKkiGk z^e&9Q)>(RY0A_fn;^4xw-*^0^pF_Xo;E#vWmoi~EZAJrh?w9OSm?F9VvL^&%z*g5Q zbUz|lY~mS1JrQ|xvf847u>BE+J@Z0<&i$7M0 zqoS-uO<;^ zynp`)EJCuB)I^PI^DoAG1QV`LaODk_>j?O_B!c|M;PUbWZcKv&h8go9iUkz{nG8!? z6EmDOO`yWC#5|nDJ{6o$liALUjq_j=B>e^j$Vi_23G!!IUKH*n*M9O(Fm%IcM1*D= zUt^9irNF5F58qUC3lNiM83g&h-1u35uj7+tY+DwGYrZLI9u>P5R8S+Pov^?$=3W4; z9@vuEG0bqVIxbMf8~q@I2Lk4()=z`)&TfR&q5*+LGvRJ zh37Ajh*|SIu(*LW2BO3-{bjrT&zx0w>`gk>8V7-F5wS-{;3ml>Ys`B8X)cO5$P9_*E3mQXSTBq<}aTz zDf=ERl>)*s(3mTRgF8%SrZj6tg9KpjSBmgSfRyPG00b+*yWJNA8Lh;NgY6U@j$m*o zi7#pX6Ii)*c$1u$_E+j}kb8Zf+y6nO#;BGBa+i-U;s` z9)0nw(!WUm5KY?Pe+=JdpkI^`!DL|HwF@PY`4H-u{x9I03krXn{(bmHrQ%Q1hy16M z{#T0sD*bz5%R?V|rHu^vUZG#W!-EVmp7+y7ygB+v$8GeHt}gmWFE{6zkGtq2f4%hY zSDUL38pD14%pPcw(nl}EQvw)YQSsA?|0DXpgcG6Z58=ch`u)ayg+3a|i}aDcm+9YQ zuy6|>eMSZk6Y;I|!M}k%daJwWgRhr9%ZWbt_R$}LEf{_9%Qq_a8XT|!7$e`~^dE#x z7=7@crjG~vD+=?Zg3Pa4o30Eh?SBZDP%r3nG9N)Y;M3-+O?~;+#Vy7Rkd6VjO#h?C z9HCz}=C|k%px)_Yv+qyo4;piUK023g(0>5=raz4M=p$XZ2Kd(VtfR2uy0WqP@{(teZZXw!qMbUvjL3h!5VRN=D1Z0F=Z zuJ8$kPbtiHPx?89FDU$y!ff}XUs3oCg)tA3^tI3jy-neq!rcmQRd|oWdlep4cwFHl z3UeKa@=hxJIfc(CjA2pe7ZrX%;g=PDMPadZM0vfbFrO2aXA6C%SK*w()W0WvtHQK} zB)nJQQH949o>ur#h2OD$O}Q{#HXEl7Pm~9T3_gi5F;RdW*~Y=rME{|YLjP!CaDSoX z>{8y=p_NsGo2r%#v{a@ir-u87%l4ZlRKAJ@zdH|U4n2L1hP^~-Umr=fJ^< zp+c#Da)f0W>VO!MN`i}XF_EQ0xiolSYGMq{u`oVZEqaQmOJqn}95Co~52l|+2CYwJ zSnY@rHr#i+v|o+R@S$g+GZb+hQcb9i`k|_%noxo6+0~H$@H<3Yh15PzPiEIzib}TK_4XjKN5uv(^6gBCwPYDS%&lHi7j?_isKdaKCQO6Q? z>)K6N+j?gqQT}ukG)m8n)v|y{8 z?`cI>yb8i$0uQ$p?_uIn25;Hw8r@C6CwroROAnC&E6&CR z^I5#;p5b(BNjo!a4Hp*VaQ3+)ucp5}u_L*=a zE+o%440Ycy!*Y+N(DKoClgZC(XgxW4nGb?4Zr0$7NN@q=RIIY&O%lb>O2S<^Cz%iz zvcB#?e^tunG&D*xM8l=AUy(86xLZeAwpgJ%nigv8WgWsQ`B7nLls#_II89lNSSp`# z3jm7?zMyr!uoMK$Hf!0VfPbA72Jvgou}W3|@C>e~!%_wv7E+Hh%Sn9XsAy4INGgqc zVJtOQKX+`g+Nf50HDLR?C0>7ZQ`hDW%e%P#>PnkTUw`!m?B=6Vq!4`DS3MWH1Nirv ze$z^%**R9M({~{5TGUU7OuCn50ou7~-R|EF~$NhijEZktYzv3L_aoyT?*zgL&p6us1I`s|wX$z6q zrTv;C!sj>DF+kuG;t+b=j#D4j?J4gW z)9LQIb4y{;UOUx{W&hM(8c6Y_?$^E@BJF>1Fa= zI_T)9AgktsJ$RH5K{oX40kxPDrICkYLj_(aCd^9=a$`$8NNi#&MoBBD$h-lK?7fa>qLlK0sTB%!f;P8>==|gfOPa~)2%4H0@0C2 z*|~9)a5I0>^1MLAURw4`{h?@X~;KVZoiUnCkgXCdr;oi-wga06(jP z&+w$8$MXD{FlZVP$OZrsve#MKId}~cv%d8RT8K6|64wio8j_lkuVzB%(djh17I=m4 oKL*?G&NbroDUexx+Yu@P?%)kJxgjd~s0$JjD9ECp?!?Le1;v!OPyhe` diff --git a/components/properitary_rf/esb/gcc/esb_gcc.a b/components/properitary_rf/esb/gcc/esb_gcc.a deleted file mode 100644 index ea813f82ea70ac47a0f0262a2b7998a5ca0a4897..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50420 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 diff --git a/components/properitary_rf/esb/iar/esb_iar.a b/components/properitary_rf/esb/iar/esb_iar.a deleted file mode 100644 index 0d573431b83db4b0ad2d123be56f9e8ff81182e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 128574 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 Y^=@t_K7PDcAlHPS@OU{IC%nr42NMtB9RL6T diff --git a/components/properitary_rf/esb/iar/esb_sd_resource_iar.a b/components/properitary_rf/esb/iar/esb_sd_resource_iar.a deleted file mode 100644 index 1397662eb93566df80a5c16a447823616838af8b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129064 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 Lm%oY&&qn`0O><@X diff --git a/components/properitary_rf/gzll/config/nrf_gzp_config.h b/components/properitary_rf/gzll/config/nrf_gzp_config.h deleted file mode 100644 index 35f5b2d..0000000 --- a/components/properitary_rf/gzll/config/nrf_gzp_config.h +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright (c) 2008 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - * $LastChangedRevision: 25419 $ - */ - - -#ifndef __GZP_CONFIG_H -#define __GZP_CONFIG_H - - -/** - * Definition of "secret key" used during "Host ID exchange". - */ - -#define GZP_SECRET_KEY {1, 23, 45, 57, 26, 68, 12, 64, 13, 73, 13, 62, 26, 45, 12, 77} - -//----------------------------------------------------------------------------- - -/** - Definition of the first static selected pairing channel. Should be located in - the lower Nth of the channel range, where N is the size if the channel subset - selected by the application. -*/ -#define GZP_CHANNEL_LOW 2 - -/** - Definition of the second static selected pairing channel. Should be located in - the upper Nth of the channel range, where N is the size if the channel subset - selected by the application. -*/ -#define GZP_CHANNEL_HIGH 79 - -/** - Definition of the static "global" pairing address. -*/ -#define GZP_ADDRESS 4, 6, 8, 10 - -/** - Reduced TX power for use during close proximity pairing. - */ -#define GZP_POWER NRF_GZLL_TX_POWER_N16_DBM - -/** - Definition of pairing request timeout. -*/ -#define GZP_REQ_TX_TIMEOUT 200 - -/** - Definition of the maximimum number of "backoff" packets (step 0) to be transmitted. -*/ -#define GZP_MAX_BACKOFF_PACKETS 100 - -/** - Definition of the period a device shall wait before attempting to send the packet for - fetching the pairing response (step 1). -*/ -#define GZP_TX_ACK_WAIT_TIMEOUT (GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT + 50) - -/** - Definition of the period a device in close proximity shall back off on the pairing - address after a backoff packet has been received. -*/ -#define GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT ((GZP_REQ_TX_TIMEOUT / 2) + 50) - -/** - Definition of the period a device NOT in close proximity shall back off on the pairing - address after a backoff packet has been received. -*/ -#define GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT (GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT + GZP_STEP1_RX_TIMEOUT) - -/** - Definition of the time the host waits for a device to complete - transmission of the pairing request step 1 packet. -*/ -#define GZP_STEP1_RX_TIMEOUT (((GZP_REQ_TX_TIMEOUT / 2) + GZP_TX_ACK_WAIT_TIMEOUT) + 50) - -/** - Definition of the lowest boundary for the channel range to be used. -*/ -#define GZP_CHANNEL_MIN 2 - -/** - Definition of the upper boundary for the channel range to be used. -*/ -#define GZP_CHANNEL_MAX 80 - -/** - Definition of the minimum channel spacing for the channel subset generated - during pairing. -*/ -#define GZP_CHANNEL_SPACING_MIN 5 - -/** - Non volatile memory (Flash or OTP) storage address. A device will - require GZP_DEVICE_PARAMS_STORAGE_SIZE bytes of memory, and - Host 11 bytes. -*/ -#define GZP_PARAMS_STORAGE_ADR 0x00001000 - -/** - Number of bytes available for parameter storage in Device. -*/ -#define GZP_DEVICE_PARAMS_STORAGE_SIZE 1024 - -/** - Maximum Device TX payload length [bytes]. - */ -#define GZP_MAX_FW_PAYLOAD_LENGTH 17 - -/** - Maximum Host ACK payload length [bytes]. - */ -#define GZP_MAX_ACK_PAYLOAD_LENGTH 10 - - -#endif diff --git a/components/properitary_rf/gzll/gcc/gzll_sd_resources_gcc.a b/components/properitary_rf/gzll/gcc/gzll_sd_resources_gcc.a deleted file mode 100644 index 31c116656c48ad5ce1ddb1adfe845d216a0e100d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53732 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 - -#ifndef GAZELL_ALTERNATIVE_RESOURCES - #define GZLL_PPI_CHANNELS_USED 0x00000007uL /**< PPI channels utilized by Gazell (not available to th spplication). */ - #define GZLL_TIMERS_USED 0x00000004uL /**< Timers used by Gazell. */ - #define GZLL_SWI_USED 0x00000001uL /**< Software interrupts used by Gazell */ -#else - #define GZLL_PPI_CHANNELS_USED 0x00000700uL /**< PPI channels utilized by Gazell (not available to th spplication). */ - #define GZLL_TIMERS_USED 0x00000001uL /**< Timers used by Gazell. */ - #define GZLL_SWI_USED 0x00000002uL /**< Software interrupts used by Gazell */ -#endif - - - -#endif /* NRF_GZLL_RESOURCES_H__ */ diff --git a/components/properitary_rf/gzll/nrf_gzp_host_nrf51.c b/components/properitary_rf/gzll/nrf_gzp_host_nrf51.c deleted file mode 100644 index e2a7ebe..0000000 --- a/components/properitary_rf/gzll/nrf_gzp_host_nrf51.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic - * Semiconductor ASA.Terms and conditions of usage are described in detail - * in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRENTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - * $LastChangedRevision: 133 $ - */ - - -#include "nrf_gzp.h" -#include "nrf_nvmc.h" - -/** - * @file - * @brief Implementation of Gazell Pairing Library (gzp), nRF51 specific Host functions. - * @defgroup gzp_source_host_nrf51 Gazell Pairing Host nRF51 specific implementation - * @{ - * @ingroup gzp_04_source - */ - - -void gzp_host_chip_id_read(uint8_t *dst, uint8_t n) -{ - uint8_t i; - uint8_t random_number; - - if( *((uint8_t*)(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1)) == 0xff) - { - nrf_nvmc_write_byte((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1) , 0x00); - - for(i = 0; i < n; i++) - { - gzp_random_numbers_generate(&random_number, 1); - nrf_nvmc_write_byte((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i) , random_number); - } - } - - for(i = 0; i < n; i++) - { - *(dst++) = *((uint8_t*)(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i)); - } -} - -/** @} */ diff --git a/components/proprietary_rf/esb/nrf_esb.c b/components/proprietary_rf/esb/nrf_esb.c new file mode 100644 index 0000000..04d110b --- /dev/null +++ b/components/proprietary_rf/esb/nrf_esb.c @@ -0,0 +1,1299 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_error.h" +#include "nrf_esb.h" +#include "nrf_esb_error_codes.h" +#include "nrf_gpio.h" +#include +#include +#include "sdk_common.h" +#include "sdk_macros.h" +#include "app_util.h" +#include "nrf_log.h" + +#define BIT_MASK_UINT_8(x) (0xFF >> (8 - (x))) +#define NRF_ESB_PIPE_COUNT 9 + +// Constant parameters +#define RX_WAIT_FOR_ACK_TIMEOUT_US_2MBPS (48) /**< 2 Mb RX wait for acknowledgment time-out value. Smallest reliable value - 43. */ +#define RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS (64) /**< 1 Mb RX wait for acknowledgment time-out value. Smallest reliable value - 59. */ +#define RX_WAIT_FOR_ACK_TIMEOUT_US_250KBPS (250) /**< 250 Kb RX wait for acknowledgment time-out value. */ +#define RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS_BLE (64) /**< 1 Mb RX wait for acknowledgment time-out (combined with BLE). */ + +// Interrupt flags +#define NRF_ESB_INT_TX_SUCCESS_MSK 0x01 /**< Interrupt mask value for TX success. */ +#define NRF_ESB_INT_TX_FAILED_MSK 0x02 /**< Interrupt mask value for TX failure. */ +#define NRF_ESB_INT_RX_DATA_RECEIVED_MSK 0x04 /**< Interrupt mask value for RX_DR. */ + +#define NRF_ESB_PID_RESET_VALUE 0xFF /**< Invalid PID value which is guaranteed to not collide with any valid PID value. */ +#define NRF_ESB_PID_MAX 3 /**< Maximum value for PID. */ +#define NRF_ESB_CRC_RESET_VALUE 0xFFFF /**< CRC reset value. */ + +// Internal Enhanced ShockBurst module state. +typedef enum { + NRF_ESB_STATE_IDLE, /**< Module idle. */ + NRF_ESB_STATE_PTX_TX, /**< Module transmitting without acknowledgment. */ + NRF_ESB_STATE_PTX_TX_ACK, /**< Module transmitting with acknowledgment. */ + NRF_ESB_STATE_PTX_RX_ACK, /**< Module transmitting with acknowledgment and reception of payload with the acknowledgment response. */ + NRF_ESB_STATE_PRX, /**< Module receiving packets without acknowledgment. */ + NRF_ESB_STATE_PRX_SEND_ACK, /**< Module transmitting acknowledgment in RX mode. */ +} nrf_esb_mainstate_t; + + +#define DISABLE_RF_IRQ() NVIC_DisableIRQ(RADIO_IRQn) +#define ENABLE_RF_IRQ() NVIC_EnableIRQ(RADIO_IRQn) + +#define RADIO_SHORTS_COMMON ( RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | \ + RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_DISABLED_RSSISTOP_Msk ) + +#define VERIFY_PAYLOAD_LENGTH(p) \ +do \ +{ \ + if (p->length == 0 || \ + p->length > NRF_ESB_MAX_PAYLOAD_LENGTH || \ + (m_config_local.protocol == NRF_ESB_PROTOCOL_ESB && \ + p->length > m_config_local.payload_length)) \ + { \ + return NRF_ERROR_INVALID_LENGTH; \ + } \ +}while (0) + + +/* @brief Structure holding pipe info PID and CRC and acknowledgment payload. */ +typedef struct +{ + uint16_t crc; /**< CRC value of the last received packet (Used to detect retransmits). */ + uint8_t pid; /**< Packet ID of the last received packet (Used to detect retransmits). */ + bool ack_payload; /**< Flag indicating the state of the transmission of acknowledgment payloads. */ +} pipe_info_t; + + +/* @brief First-in, first-out queue of payloads to be transmitted. */ +typedef struct +{ + nrf_esb_payload_t * p_payload[NRF_ESB_TX_FIFO_SIZE]; /**< Pointer to the actual queue. */ + uint32_t entry_point; /**< Current start of queue. */ + uint32_t exit_point; /**< Current end of queue. */ + uint32_t count; /**< Current number of elements in the queue. */ +} nrf_esb_payload_tx_fifo_t; + + +/* @brief First-in, first-out queue of received payloads. */ +typedef struct +{ + nrf_esb_payload_t * p_payload[NRF_ESB_RX_FIFO_SIZE]; /**< Pointer to the actual queue. */ + uint32_t entry_point; /**< Current start of queue. */ + uint32_t exit_point; /**< Current end of queue. */ + uint32_t count; /**< Current number of elements in the queue. */ +} nrf_esb_payload_rx_fifo_t; + + +/**@brief Enhanced ShockBurst address. + * + * Enhanced ShockBurst addresses consist of a base address and a prefix + * that is unique for each pipe. See @ref esb_addressing in the ESB user + * guide for more information. +*/ +typedef struct +{ + uint8_t base_addr_p0[4]; /**< Base address for pipe 0 encoded in big endian. */ + uint8_t base_addr_p1[4]; /**< Base address for pipe 1-7 encoded in big endian. */ + uint8_t pipe_prefixes[8]; /**< Address prefix for pipe 0 to 7. */ + uint8_t num_pipes; /**< Number of pipes available. */ + uint8_t addr_length; /**< Length of the address including the prefix. */ + uint8_t rx_pipes_enabled; /**< Bitfield for enabled pipes. */ + uint8_t rf_channel; /**< Channel to use (must be between 0 and 125). */ +} nrf_esb_address_t; + + +// Module state +static bool m_esb_initialized = false; +static nrf_esb_mainstate_t m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; +static nrf_esb_payload_t * mp_current_payload; + +static nrf_esb_event_handler_t m_event_handler; + +// Address parameters +static nrf_esb_address_t m_esb_addr = NRF_ESB_ADDR_DEFAULT; + +// RF parameters +static nrf_esb_config_t m_config_local; + +// TX FIFO +static nrf_esb_payload_t m_tx_fifo_payload[NRF_ESB_TX_FIFO_SIZE]; +static nrf_esb_payload_tx_fifo_t m_tx_fifo; + +// RX FIFO +static nrf_esb_payload_t m_rx_fifo_payload[NRF_ESB_RX_FIFO_SIZE]; +static nrf_esb_payload_rx_fifo_t m_rx_fifo; + +// Payload buffers +static uint8_t m_tx_payload_buffer[NRF_ESB_MAX_PAYLOAD_LENGTH + 2]; +static uint8_t m_rx_payload_buffer[NRF_ESB_MAX_PAYLOAD_LENGTH + 2]; + +// Run time variables +static volatile uint32_t m_interrupt_flags = 0; +static uint8_t m_pids[NRF_ESB_PIPE_COUNT]; +static pipe_info_t m_rx_pipe_info[NRF_ESB_PIPE_COUNT]; +static volatile uint32_t m_retransmits_remaining; +static volatile uint32_t m_last_tx_attempts; +static volatile uint32_t m_wait_for_ack_timeout_us; + +// These function pointers are changed dynamically, depending on protocol configuration and state. +static void (*on_radio_disabled)(void) = 0; +static void (*on_radio_end)(void) = 0; +static void (*update_rf_payload_format)(uint32_t payload_length) = 0; + + +// The following functions are assigned to the function pointers above. +static void on_radio_disabled_tx_noack(void); +static void on_radio_disabled_tx(void); +static void on_radio_disabled_tx_wait_for_ack(void); +static void on_radio_disabled_rx(void); +static void on_radio_disabled_rx_ack(void); + + +#define NRF_ESB_ADDR_UPDATE_MASK_BASE0 (1 << 0) /*< Mask value to signal updating BASE0 radio address. */ +#define NRF_ESB_ADDR_UPDATE_MASK_BASE1 (1 << 1) /*< Mask value to signal updating BASE1 radio address. */ +#define NRF_ESB_ADDR_UPDATE_MASK_PREFIX (1 << 2) /*< Mask value to signal updating radio prefixes. */ + + +// Function to do bytewise bit-swap on an unsigned 32-bit value +static uint32_t bytewise_bit_swap(uint8_t const * p_inp) +{ + uint32_t inp = (*(uint32_t*)p_inp); +#if __CORTEX_M == (0x04U) + return __REV((uint32_t)__RBIT(inp)); //lint -esym(628, __rev) -esym(526, __rev) -esym(628, __rbit) -esym(526, __rbit) */ +#else + inp = (inp & 0xF0F0F0F0) >> 4 | (inp & 0x0F0F0F0F) << 4; + inp = (inp & 0xCCCCCCCC) >> 2 | (inp & 0x33333333) << 2; + inp = (inp & 0xAAAAAAAA) >> 1 | (inp & 0x55555555) << 1; + return inp; +#endif +} + + +// Internal function to convert base addresses from nRF24L type addressing to nRF51 type addressing +static uint32_t addr_conv(uint8_t const* p_addr) +{ + return __REV(bytewise_bit_swap(p_addr)); //lint -esym(628, __rev) -esym(526, __rev) */ +} + + +static void update_rf_payload_format_esb_dpl(uint32_t payload_length) +{ +#if (NRF_ESB_MAX_PAYLOAD_LENGTH <= 32) + // Using 6 bits for length + NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) | + (6 << RADIO_PCNF0_LFLEN_Pos) | + (3 << RADIO_PCNF0_S1LEN_Pos) ; +#else + // Using 8 bits for length + NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) | + (8 << RADIO_PCNF0_LFLEN_Pos) | + (3 << RADIO_PCNF0_S1LEN_Pos) ; +#endif + NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | + (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | + ((m_esb_addr.addr_length - 1) << RADIO_PCNF1_BALEN_Pos) | + (0 << RADIO_PCNF1_STATLEN_Pos) | + (NRF_ESB_MAX_PAYLOAD_LENGTH << RADIO_PCNF1_MAXLEN_Pos); +} + + +static void update_rf_payload_format_esb(uint32_t payload_length) +{ + NRF_RADIO->PCNF0 = (1 << RADIO_PCNF0_S0LEN_Pos) | + (0 << RADIO_PCNF0_LFLEN_Pos) | + (1 << RADIO_PCNF0_S1LEN_Pos); + + NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) | + (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) | + ((m_esb_addr.addr_length - 1) << RADIO_PCNF1_BALEN_Pos) | + (payload_length << RADIO_PCNF1_STATLEN_Pos) | + (payload_length << RADIO_PCNF1_MAXLEN_Pos); +} + + +static void update_radio_addresses(uint8_t update_mask) +{ + if ((update_mask & NRF_ESB_ADDR_UPDATE_MASK_BASE0) != 0) + { + NRF_RADIO->BASE0 = addr_conv(m_esb_addr.base_addr_p0); + } + + if ((update_mask & NRF_ESB_ADDR_UPDATE_MASK_BASE1) != 0) + { + NRF_RADIO->BASE1 = addr_conv(m_esb_addr.base_addr_p1); + } + + if ((update_mask & NRF_ESB_ADDR_UPDATE_MASK_PREFIX) != 0) + { + NRF_RADIO->PREFIX0 = bytewise_bit_swap(&m_esb_addr.pipe_prefixes[0]); + NRF_RADIO->PREFIX1 = bytewise_bit_swap(&m_esb_addr.pipe_prefixes[4]); + } +} + + +static void update_radio_tx_power() +{ + NRF_RADIO->TXPOWER = m_config_local.tx_output_power << RADIO_TXPOWER_TXPOWER_Pos; +} + + +static void update_radio_bitrate() +{ + NRF_RADIO->MODE = m_config_local.bitrate << RADIO_MODE_MODE_Pos; + + switch (m_config_local.bitrate) + { + case NRF_ESB_BITRATE_2MBPS: + m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_2MBPS; + break; + + case NRF_ESB_BITRATE_1MBPS: + m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS; + break; + + case NRF_ESB_BITRATE_250KBPS: + m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_250KBPS; + break; + + case NRF_ESB_BITRATE_1MBPS_BLE: + m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS_BLE; + break; + + default: + // Should not be reached + break; + } +} + + +static void update_radio_protocol() +{ + switch (m_config_local.protocol) + { + case NRF_ESB_PROTOCOL_ESB_DPL: + update_rf_payload_format = update_rf_payload_format_esb_dpl; + break; + + case NRF_ESB_PROTOCOL_ESB: + update_rf_payload_format = update_rf_payload_format_esb; + break; + + default: + // Should not be reached + break; + } +} + + +static void update_radio_crc() +{ + NRF_RADIO->CRCCNF = m_config_local.crc << RADIO_CRCCNF_LEN_Pos; + + if (m_config_local.crc == RADIO_CRCCNF_LEN_Two) + { + NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value + NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16+x^12^x^5+1 + } + else if (m_config_local.crc == RADIO_CRCCNF_LEN_One) + { + NRF_RADIO->CRCINIT = 0xFFUL; // Initial value + NRF_RADIO->CRCPOLY = 0x107UL; // CRC poly: x^8+x^2^x^1+1 + } +} + + +static void update_radio_parameters() +{ + update_radio_tx_power(); + update_radio_bitrate(); + update_radio_protocol(); + update_radio_crc(); + update_rf_payload_format(m_config_local.payload_length); +} + + +static void reset_fifos() +{ + m_tx_fifo.entry_point = 0; + m_tx_fifo.exit_point = 0; + m_tx_fifo.count = 0; + + m_rx_fifo.entry_point = 0; + m_rx_fifo.exit_point = 0; + m_rx_fifo.count = 0; +} + + +static void initialize_fifos() +{ + reset_fifos(); + + for (int i = 0; i < NRF_ESB_TX_FIFO_SIZE; i++) + { + m_tx_fifo.p_payload[i] = &m_tx_fifo_payload[i]; + } + + for (int i = 0; i < NRF_ESB_RX_FIFO_SIZE; i++) + { + m_rx_fifo.p_payload[i] = &m_rx_fifo_payload[i]; + } +} + + +static void tx_fifo_remove_last() +{ + if (m_tx_fifo.count > 0) + { + DISABLE_RF_IRQ(); + + m_tx_fifo.count--; + if (++m_tx_fifo.exit_point >= NRF_ESB_TX_FIFO_SIZE) + { + m_tx_fifo.exit_point = 0; + } + + ENABLE_RF_IRQ(); + } +} + +/** @brief Function to push the content of the rx_buffer to the RX FIFO. + * + * The module will point the register NRF_RADIO->PACKETPTR to a buffer for receiving packets. + * After receiving a packet the module will call this function to copy the received data to + * the RX FIFO. + * + * @param pipe Pipe number to set for the packet. + * @param pid Packet ID. + * + * @retval true Operation successful. + * @retval false Operation failed. + */ +static bool rx_fifo_push_rfbuf(uint8_t pipe, uint8_t pid) +{ + if (m_rx_fifo.count < NRF_ESB_RX_FIFO_SIZE) + { + if (m_config_local.protocol == NRF_ESB_PROTOCOL_ESB_DPL) + { + if (m_rx_payload_buffer[0] > NRF_ESB_MAX_PAYLOAD_LENGTH) + { + return false; + } + + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length = m_rx_payload_buffer[0]; + } + else if (m_config_local.mode == NRF_ESB_MODE_PTX) + { + // Received packet is an acknowledgment + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length = 0; + } + else + { + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length = m_config_local.payload_length; + } + + memcpy(m_rx_fifo.p_payload[m_rx_fifo.entry_point]->data, &m_rx_payload_buffer[2], + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length); + + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->pipe = pipe; + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->rssi = NRF_RADIO->RSSISAMPLE; + m_rx_fifo.p_payload[m_rx_fifo.entry_point]->pid = pid; + if (++m_rx_fifo.entry_point >= NRF_ESB_RX_FIFO_SIZE) + { + m_rx_fifo.entry_point = 0; + } + m_rx_fifo.count++; + + return true; + } + + return false; +} + + +static void sys_timer_init() +{ + // Configure the system timer with a 1 MHz base frequency + NRF_ESB_SYS_TIMER->PRESCALER = 4; + NRF_ESB_SYS_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit; + NRF_ESB_SYS_TIMER->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Msk | TIMER_SHORTS_COMPARE1_STOP_Msk; +} + + +static void ppi_init() +{ + NRF_PPI->CH[NRF_ESB_PPI_TIMER_START].EEP = (uint32_t)&NRF_RADIO->EVENTS_READY; + NRF_PPI->CH[NRF_ESB_PPI_TIMER_START].TEP = (uint32_t)&NRF_ESB_SYS_TIMER->TASKS_START; + + NRF_PPI->CH[NRF_ESB_PPI_TIMER_STOP].EEP = (uint32_t)&NRF_RADIO->EVENTS_ADDRESS; + NRF_PPI->CH[NRF_ESB_PPI_TIMER_STOP].TEP = (uint32_t)&NRF_ESB_SYS_TIMER->TASKS_STOP; + + NRF_PPI->CH[NRF_ESB_PPI_RX_TIMEOUT].EEP = (uint32_t)&NRF_ESB_SYS_TIMER->EVENTS_COMPARE[0]; + NRF_PPI->CH[NRF_ESB_PPI_RX_TIMEOUT].TEP = (uint32_t)&NRF_RADIO->TASKS_DISABLE; + + NRF_PPI->CH[NRF_ESB_PPI_TX_START].EEP = (uint32_t)&NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1]; + NRF_PPI->CH[NRF_ESB_PPI_TX_START].TEP = (uint32_t)&NRF_RADIO->TASKS_TXEN; +} + + +static void start_tx_transaction() +{ + bool ack; + + m_last_tx_attempts = 1; + // Prepare the payload + mp_current_payload = m_tx_fifo.p_payload[m_tx_fifo.exit_point]; + + + switch (m_config_local.protocol) + { + case NRF_ESB_PROTOCOL_ESB: + update_rf_payload_format(mp_current_payload->length); + m_tx_payload_buffer[0] = mp_current_payload->pid; + m_tx_payload_buffer[1] = 0; + memcpy(&m_tx_payload_buffer[2], mp_current_payload->data, mp_current_payload->length); + + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; + NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk | RADIO_INTENSET_READY_Msk; + + // Configure the retransmit counter + m_retransmits_remaining = m_config_local.retransmit_count; + on_radio_disabled = on_radio_disabled_tx; + m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK; + break; + + case NRF_ESB_PROTOCOL_ESB_DPL: + ack = !mp_current_payload->noack || !m_config_local.selective_auto_ack; + m_tx_payload_buffer[0] = mp_current_payload->length; + m_tx_payload_buffer[1] = mp_current_payload->pid << 1; + m_tx_payload_buffer[1] |= ack ? 0x00 : 0x01; + memcpy(&m_tx_payload_buffer[2], mp_current_payload->data, mp_current_payload->length); + + // Handling ack if noack is set to false or if selective auto ack is turned off + if (ack) + { + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; + NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk | RADIO_INTENSET_READY_Msk; + + // Configure the retransmit counter + m_retransmits_remaining = m_config_local.retransmit_count; + on_radio_disabled = on_radio_disabled_tx; + m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK; + } + else + { + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON; + NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk; + on_radio_disabled = on_radio_disabled_tx_noack; + m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX; + } + break; + + default: + // Should not be reached + break; + } + + NRF_RADIO->TXADDRESS = mp_current_payload->pipe; + NRF_RADIO->RXADDRESSES = 1 << mp_current_payload->pipe; + + NRF_RADIO->FREQUENCY = m_esb_addr.rf_channel; + NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer; + + NVIC_ClearPendingIRQ(RADIO_IRQn); + NVIC_EnableIRQ(RADIO_IRQn); + + NRF_RADIO->EVENTS_ADDRESS = 0; + NRF_RADIO->EVENTS_PAYLOAD = 0; + NRF_RADIO->EVENTS_DISABLED = 0; + + DEBUG_PIN_SET(DEBUGPIN4); + NRF_RADIO->TASKS_TXEN = 1; +} + + +static void on_radio_disabled_tx_noack() +{ + m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK; + tx_fifo_remove_last(); + + if (m_tx_fifo.count == 0) + { + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + } + else + { + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + start_tx_transaction(); + } +} + + +static void on_radio_disabled_tx() +{ + // Remove the DISABLED -> RXEN shortcut, to make sure the radio stays + // disabled after the RX window + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON; + + // Make sure the timer is started the next time the radio is ready, + // and that it will disable the radio automatically if no packet is + // received by the time defined in m_wait_for_ack_timeout_us + NRF_ESB_SYS_TIMER->CC[0] = m_wait_for_ack_timeout_us; + NRF_ESB_SYS_TIMER->CC[1] = m_config_local.retransmit_delay - 130; + NRF_ESB_SYS_TIMER->TASKS_CLEAR = 1; + NRF_ESB_SYS_TIMER->EVENTS_COMPARE[0] = 0; + NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1] = 0; + + NRF_PPI->CHENSET = (1 << NRF_ESB_PPI_TIMER_START) | + (1 << NRF_ESB_PPI_RX_TIMEOUT) | + (1 << NRF_ESB_PPI_TIMER_STOP); + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START); + NRF_RADIO->EVENTS_END = 0; + + if (m_config_local.protocol == NRF_ESB_PROTOCOL_ESB) + { + update_rf_payload_format(0); + } + + NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; + on_radio_disabled = on_radio_disabled_tx_wait_for_ack; + m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_RX_ACK; +} + + +static void on_radio_disabled_tx_wait_for_ack() +{ + // This marks the completion of a TX_RX sequence (TX with ACK) + + // Make sure the timer will not deactivate the radio if a packet is received + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TIMER_START) | + (1 << NRF_ESB_PPI_RX_TIMEOUT) | + (1 << NRF_ESB_PPI_TIMER_STOP); + + // If the radio has received a packet and the CRC status is OK + if (NRF_RADIO->EVENTS_END && NRF_RADIO->CRCSTATUS != 0) + { + NRF_ESB_SYS_TIMER->TASKS_STOP = 1; + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START); + m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK; + m_last_tx_attempts = m_config_local.retransmit_count - m_retransmits_remaining + 1; + + tx_fifo_remove_last(); + + if (m_config_local.protocol != NRF_ESB_PROTOCOL_ESB && m_rx_payload_buffer[0] > 0) + { + if (rx_fifo_push_rfbuf((uint8_t)NRF_RADIO->TXADDRESS, 0)) + { + m_interrupt_flags |= NRF_ESB_INT_RX_DATA_RECEIVED_MSK; + } + } + + if ((m_tx_fifo.count == 0) || (m_config_local.tx_mode == NRF_ESB_TXMODE_MANUAL)) + { + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + } + else + { + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + start_tx_transaction(); + } + } + else + { + if (m_retransmits_remaining-- == 0) + { + NRF_ESB_SYS_TIMER->TASKS_STOP = 1; + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START); + // All retransmits are expended, and the TX operation is suspended + m_last_tx_attempts = m_config_local.retransmit_count + 1; + m_interrupt_flags |= NRF_ESB_INT_TX_FAILED_MSK; + + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + } + else + { + // There are still more retransmits left, TX mode should be + // entered again as soon as the system timer reaches CC[1]. + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; + update_rf_payload_format(mp_current_payload->length); + NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer; + on_radio_disabled = on_radio_disabled_tx; + m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK; + NRF_ESB_SYS_TIMER->TASKS_START = 1; + NRF_PPI->CHENSET = (1 << NRF_ESB_PPI_TX_START); + if (NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1]) + { + NRF_RADIO->TASKS_TXEN = 1; + } + } + } +} + +static void clear_events_restart_rx(void) +{ + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON; + update_rf_payload_format(m_config_local.payload_length); + NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; + NRF_RADIO->EVENTS_DISABLED = 0; + NRF_RADIO->TASKS_DISABLE = 1; + + while (NRF_RADIO->EVENTS_DISABLED == 0); + + NRF_RADIO->EVENTS_DISABLED = 0; + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_TXEN_Msk; + NRF_RADIO->TASKS_RXEN = 1; +} + +static void on_radio_disabled_rx(void) +{ + bool ack = false; + bool retransmit_payload = false; + bool send_rx_event = true; + pipe_info_t * p_pipe_info; + + if (NRF_RADIO->CRCSTATUS == 0) + { + clear_events_restart_rx(); + return; + } + + if (m_rx_fifo.count >= NRF_ESB_RX_FIFO_SIZE) + { + clear_events_restart_rx(); + return; + } + + p_pipe_info = &m_rx_pipe_info[NRF_RADIO->RXMATCH]; + if (NRF_RADIO->RXCRC == p_pipe_info->crc && + (m_rx_payload_buffer[1] >> 1) == p_pipe_info->pid + ) + { + retransmit_payload = true; + send_rx_event = false; + } + + p_pipe_info->pid = m_rx_payload_buffer[1] >> 1; + p_pipe_info->crc = NRF_RADIO->RXCRC; + + if (m_config_local.selective_auto_ack == false || ((m_rx_payload_buffer[1] & 0x01) == 0)) + { + ack = true; + } + + if (ack) + { + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_RXEN_Msk; + + switch (m_config_local.protocol) + { + case NRF_ESB_PROTOCOL_ESB_DPL: + { + if (m_tx_fifo.count > 0 && + (m_tx_fifo.p_payload[m_tx_fifo.exit_point]->pipe == NRF_RADIO->RXMATCH) + ) + { + // Pipe stays in ACK with payload until TX FIFO is empty + // Do not report TX success on first ack payload or retransmit + if (p_pipe_info->ack_payload == true && !retransmit_payload) + { + if (++m_tx_fifo.exit_point >= NRF_ESB_TX_FIFO_SIZE) + { + m_tx_fifo.exit_point = 0; + } + + m_tx_fifo.count--; + + // ACK payloads also require TX_DS + // (page 40 of the 'nRF24LE1_Product_Specification_rev1_6.pdf'). + m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK; + } + + p_pipe_info->ack_payload = true; + + mp_current_payload = m_tx_fifo.p_payload[m_tx_fifo.exit_point]; + + update_rf_payload_format(mp_current_payload->length); + m_tx_payload_buffer[0] = mp_current_payload->length; + memcpy(&m_tx_payload_buffer[2], + mp_current_payload->data, + mp_current_payload->length); + } + else + { + p_pipe_info->ack_payload = false; + update_rf_payload_format(0); + m_tx_payload_buffer[0] = 0; + } + + m_tx_payload_buffer[1] = m_rx_payload_buffer[1]; + } + break; + + case NRF_ESB_PROTOCOL_ESB: + { + update_rf_payload_format(0); + m_tx_payload_buffer[0] = m_rx_payload_buffer[0]; + m_tx_payload_buffer[1] = 0; + } + break; + } + + m_nrf_esb_mainstate = NRF_ESB_STATE_PRX_SEND_ACK; + NRF_RADIO->TXADDRESS = NRF_RADIO->RXMATCH; + NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer; + on_radio_disabled = on_radio_disabled_rx_ack; + } + else + { + clear_events_restart_rx(); + } + + if (send_rx_event) + { + // Push the new packet to the RX buffer and trigger a received event if the operation was + // successful. + if (rx_fifo_push_rfbuf(NRF_RADIO->RXMATCH, p_pipe_info->pid)) + { + m_interrupt_flags |= NRF_ESB_INT_RX_DATA_RECEIVED_MSK; + NVIC_SetPendingIRQ(ESB_EVT_IRQ); + } + } +} + + +static void on_radio_disabled_rx_ack(void) +{ + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_TXEN_Msk; + update_rf_payload_format(m_config_local.payload_length); + + NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; + on_radio_disabled = on_radio_disabled_rx; + + m_nrf_esb_mainstate = NRF_ESB_STATE_PRX; +} + + +/**@brief Function for clearing pending interrupts. + * + * @param[in,out] p_interrupts Pointer to the value that holds the current interrupts. + * + * @retval NRF_SUCCESS If the interrupts were cleared successfully. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + * @retval NRF_INVALID_STATE If the module is not initialized. + */ +static uint32_t nrf_esb_get_clear_interrupts(uint32_t * p_interrupts) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + VERIFY_PARAM_NOT_NULL(p_interrupts); + + DISABLE_RF_IRQ(); + + *p_interrupts = m_interrupt_flags; + m_interrupt_flags = 0; + + ENABLE_RF_IRQ(); + + return NRF_SUCCESS; +} + + +void RADIO_IRQHandler() +{ + if (NRF_RADIO->EVENTS_READY && (NRF_RADIO->INTENSET & RADIO_INTENSET_READY_Msk)) + { + NRF_RADIO->EVENTS_READY = 0; + DEBUG_PIN_SET(DEBUGPIN1); + } + + if (NRF_RADIO->EVENTS_END && (NRF_RADIO->INTENSET & RADIO_INTENSET_END_Msk)) + { + NRF_RADIO->EVENTS_END = 0; + DEBUG_PIN_SET(DEBUGPIN2); + + // Call the correct on_radio_end function, depending on the current protocol state + if (on_radio_end) + { + on_radio_end(); + } + } + + if (NRF_RADIO->EVENTS_DISABLED && (NRF_RADIO->INTENSET & RADIO_INTENSET_DISABLED_Msk)) + { + NRF_RADIO->EVENTS_DISABLED = 0; + DEBUG_PIN_SET(DEBUGPIN3); + + // Call the correct on_radio_disable function, depending on the current protocol state + if (on_radio_disabled) + { + on_radio_disabled(); + } + } + + DEBUG_PIN_CLR(DEBUGPIN1); + DEBUG_PIN_CLR(DEBUGPIN2); + DEBUG_PIN_CLR(DEBUGPIN3); + DEBUG_PIN_CLR(DEBUGPIN4); +} + + +uint32_t nrf_esb_init(nrf_esb_config_t const * p_config) +{ + uint32_t err_code; + + VERIFY_PARAM_NOT_NULL(p_config); + + if (m_esb_initialized) + { + err_code = nrf_esb_disable(); + if (err_code != NRF_SUCCESS) + { + return err_code; + } + } + + m_event_handler = p_config->event_handler; + + memcpy(&m_config_local, p_config, sizeof(nrf_esb_config_t)); + + m_interrupt_flags = 0; + + memset(m_rx_pipe_info, 0, sizeof(m_rx_pipe_info)); + memset(m_pids, 0, sizeof(m_pids)); + + update_radio_parameters(); + + initialize_fifos(); + + sys_timer_init(); + + ppi_init(); + + NVIC_SetPriority(RADIO_IRQn, m_config_local.radio_irq_priority & 0x03); + NVIC_SetPriority(ESB_EVT_IRQ, m_config_local.event_irq_priority & 0x03); + NVIC_EnableIRQ(ESB_EVT_IRQ); + + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + m_esb_initialized = true; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_suspend(void) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + + // Clear PPI + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TIMER_START) | + (1 << NRF_ESB_PPI_TIMER_STOP) | + (1 << NRF_ESB_PPI_RX_TIMEOUT) | + (1 << NRF_ESB_PPI_TX_START); + + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_disable(void) +{ + // Clear PPI + NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TIMER_START) | + (1 << NRF_ESB_PPI_TIMER_STOP) | + (1 << NRF_ESB_PPI_RX_TIMEOUT) | + (1 << NRF_ESB_PPI_TX_START); + + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + + reset_fifos(); + + memset(m_rx_pipe_info, 0, sizeof(m_rx_pipe_info)); + memset(m_pids, 0, sizeof(m_pids)); + + // Disable the radio + NVIC_DisableIRQ(ESB_EVT_IRQ); + NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos | + RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos; + + return NRF_SUCCESS; +} + + +bool nrf_esb_is_idle(void) +{ + return m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE; +} + + +void ESB_EVT_IRQHandler(void) +{ + ret_code_t err_code; + uint32_t interrupts; + nrf_esb_evt_t event; + + event.tx_attempts = m_last_tx_attempts; + + err_code = nrf_esb_get_clear_interrupts(&interrupts); + if (err_code == NRF_SUCCESS && m_event_handler != 0) + { + if (interrupts & NRF_ESB_INT_TX_SUCCESS_MSK) + { + event.evt_id = NRF_ESB_EVENT_TX_SUCCESS; + m_event_handler(&event); + } + if (interrupts & NRF_ESB_INT_TX_FAILED_MSK) + { + event.evt_id = NRF_ESB_EVENT_TX_FAILED; + m_event_handler(&event); + } + if (interrupts & NRF_ESB_INT_RX_DATA_RECEIVED_MSK) + { + event.evt_id = NRF_ESB_EVENT_RX_RECEIVED; + m_event_handler(&event); + } + } +} + +uint32_t nrf_esb_write_payload(nrf_esb_payload_t const * p_payload) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + VERIFY_PARAM_NOT_NULL(p_payload); + VERIFY_PAYLOAD_LENGTH(p_payload); + VERIFY_FALSE(m_tx_fifo.count >= NRF_ESB_TX_FIFO_SIZE, NRF_ERROR_NO_MEM); + + if (m_config_local.mode == NRF_ESB_MODE_PTX && + p_payload->noack && !m_config_local.selective_auto_ack ) + { + return NRF_ERROR_NOT_SUPPORTED; + } + + DISABLE_RF_IRQ(); + + memcpy(m_tx_fifo.p_payload[m_tx_fifo.entry_point], p_payload, sizeof(nrf_esb_payload_t)); + + m_pids[p_payload->pipe] = (m_pids[p_payload->pipe] + 1) % (NRF_ESB_PID_MAX + 1); + m_tx_fifo.p_payload[m_tx_fifo.entry_point]->pid = m_pids[p_payload->pipe]; + + if (++m_tx_fifo.entry_point >= NRF_ESB_TX_FIFO_SIZE) + { + m_tx_fifo.entry_point = 0; + } + + m_tx_fifo.count++; + + ENABLE_RF_IRQ(); + + + if (m_config_local.mode == NRF_ESB_MODE_PTX && + m_config_local.tx_mode == NRF_ESB_TXMODE_AUTO && + m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE) + { + start_tx_transaction(); + } + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_read_rx_payload(nrf_esb_payload_t * p_payload) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + VERIFY_PARAM_NOT_NULL(p_payload); + + if (m_rx_fifo.count == 0) + { + return NRF_ERROR_NOT_FOUND; + } + + DISABLE_RF_IRQ(); + + p_payload->length = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->length; + p_payload->pipe = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->pipe; + p_payload->rssi = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->rssi; + p_payload->pid = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->pid; + memcpy(p_payload->data, m_rx_fifo.p_payload[m_rx_fifo.exit_point]->data, p_payload->length); + + if (++m_rx_fifo.exit_point >= NRF_ESB_RX_FIFO_SIZE) + { + m_rx_fifo.exit_point = 0; + } + + m_rx_fifo.count--; + + ENABLE_RF_IRQ(); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_start_tx(void) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + + if (m_tx_fifo.count == 0) + { + return NRF_ERROR_BUFFER_EMPTY; + } + + start_tx_transaction(); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_start_rx(void) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + + NRF_RADIO->INTENCLR = 0xFFFFFFFF; + NRF_RADIO->EVENTS_DISABLED = 0; + on_radio_disabled = on_radio_disabled_rx; + + NRF_RADIO->SHORTS = RADIO_SHORTS_COMMON | RADIO_SHORTS_DISABLED_TXEN_Msk; + NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk; + m_nrf_esb_mainstate = NRF_ESB_STATE_PRX; + + NRF_RADIO->RXADDRESSES = m_esb_addr.rx_pipes_enabled; + NRF_RADIO->FREQUENCY = m_esb_addr.rf_channel; + NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; + + NVIC_ClearPendingIRQ(RADIO_IRQn); + NVIC_EnableIRQ(RADIO_IRQn); + + NRF_RADIO->EVENTS_ADDRESS = 0; + NRF_RADIO->EVENTS_PAYLOAD = 0; + NRF_RADIO->EVENTS_DISABLED = 0; + + NRF_RADIO->TASKS_RXEN = 1; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_stop_rx(void) +{ + if (m_nrf_esb_mainstate == NRF_ESB_STATE_PRX) + { + NRF_RADIO->SHORTS = 0; + NRF_RADIO->INTENCLR = 0xFFFFFFFF; + on_radio_disabled = NULL; + NRF_RADIO->EVENTS_DISABLED = 0; + NRF_RADIO->TASKS_DISABLE = 1; + while (NRF_RADIO->EVENTS_DISABLED == 0); + m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE; + + return NRF_SUCCESS; + } + + return NRF_ESB_ERROR_NOT_IN_RX_MODE; +} + + +uint32_t nrf_esb_flush_tx(void) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + + DISABLE_RF_IRQ(); + + m_tx_fifo.count = 0; + m_tx_fifo.entry_point = 0; + m_tx_fifo.exit_point = 0; + + ENABLE_RF_IRQ(); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_pop_tx(void) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + VERIFY_TRUE(m_tx_fifo.count > 0, NRF_ERROR_BUFFER_EMPTY); + + DISABLE_RF_IRQ(); + + if (++m_tx_fifo.entry_point >= NRF_ESB_TX_FIFO_SIZE) + { + m_tx_fifo.entry_point = 0; + } + m_tx_fifo.count--; + + ENABLE_RF_IRQ(); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_flush_rx(void) +{ + VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE); + + DISABLE_RF_IRQ(); + + m_rx_fifo.count = 0; + m_rx_fifo.entry_point = 0; + m_rx_fifo.exit_point = 0; + + memset(m_rx_pipe_info, 0, sizeof(m_rx_pipe_info)); + + ENABLE_RF_IRQ(); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_address_length(uint8_t length) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_TRUE(length > 2 && length < 6, NRF_ERROR_INVALID_PARAM); + + m_esb_addr.addr_length = length; + + update_rf_payload_format(m_config_local.payload_length); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_base_address_0(uint8_t const * p_addr) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_PARAM_NOT_NULL(p_addr); + + memcpy(m_esb_addr.base_addr_p0, p_addr, 4); + + update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_BASE0); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_base_address_1(uint8_t const * p_addr) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_PARAM_NOT_NULL(p_addr); + + memcpy(m_esb_addr.base_addr_p1, p_addr, 4); + + update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_BASE1); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_prefixes(uint8_t const * p_prefixes, uint8_t num_pipes) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_PARAM_NOT_NULL(p_prefixes); + VERIFY_TRUE(num_pipes < 9, NRF_ERROR_INVALID_PARAM); + + memcpy(m_esb_addr.pipe_prefixes, p_prefixes, num_pipes); + m_esb_addr.num_pipes = num_pipes; + m_esb_addr.rx_pipes_enabled = BIT_MASK_UINT_8(num_pipes); + + update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_PREFIX); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_update_prefix(uint8_t pipe, uint8_t prefix) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_TRUE(pipe < 8, NRF_ERROR_INVALID_PARAM); + + m_esb_addr.pipe_prefixes[pipe] = prefix; + + update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_PREFIX); + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_enable_pipes(uint8_t enable_mask) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + + m_esb_addr.rx_pipes_enabled = enable_mask; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_rf_channel(uint32_t channel) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + VERIFY_TRUE(channel <= 125, NRF_ERROR_INVALID_PARAM); + + m_esb_addr.rf_channel = channel; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_get_rf_channel(uint32_t * p_channel) +{ + VERIFY_PARAM_NOT_NULL(p_channel); + + *p_channel = m_esb_addr.rf_channel; + + return NRF_SUCCESS; +} + + +uint32_t nrf_esb_set_tx_power(nrf_esb_tx_power_t tx_output_power) +{ + VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY); + + if ( m_config_local.tx_output_power != tx_output_power ) + { + m_config_local.tx_output_power = tx_output_power; + update_radio_tx_power(); + } + + return NRF_SUCCESS; +} diff --git a/components/proprietary_rf/esb/nrf_esb.h b/components/proprietary_rf/esb/nrf_esb.h new file mode 100644 index 0000000..1ddf26b --- /dev/null +++ b/components/proprietary_rf/esb/nrf_esb.h @@ -0,0 +1,526 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 __NRF_ESB_H +#define __NRF_ESB_H + +#include +#include +#include "nrf.h" +#include "app_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup nrf_esb Enhanced ShockBurst + * @{ + * @ingroup proprietary_api + * + * @brief Enhanced ShockBurst (ESB) is a basic protocol that supports two-way data + * packet communication including packet buffering, packet acknowledgment, + * and automatic retransmission of lost packets. + */ + +#define DEBUGPIN1 12 +#define DEBUGPIN2 13 +#define DEBUGPIN3 14 +#define DEBUGPIN4 15 + + +#ifdef NRF_ESB_DEBUG +#define DEBUG_PIN_SET(a) (NRF_GPIO->OUTSET = (1 << (a))) +#define DEBUG_PIN_CLR(a) (NRF_GPIO->OUTCLR = (1 << (a))) +#else +#define DEBUG_PIN_SET(a) +#define DEBUG_PIN_CLR(a) +#endif + + +// Hardcoded parameters - change if necessary +#ifndef NRF_ESB_MAX_PAYLOAD_LENGTH +#define NRF_ESB_MAX_PAYLOAD_LENGTH 32 /**< The maximum size of the payload. Valid values are 1 to 252. */ +#endif + +#define NRF_ESB_TX_FIFO_SIZE 8 /**< The size of the transmission first-in, first-out buffer. */ +#define NRF_ESB_RX_FIFO_SIZE 8 /**< The size of the reception first-in, first-out buffer. */ + +// 252 is the largest possible payload size according to the nRF5 architecture. +STATIC_ASSERT(NRF_ESB_MAX_PAYLOAD_LENGTH <= 252); + +#define NRF_ESB_SYS_TIMER NRF_TIMER2 /**< The timer that is used by the module. */ +#define NRF_ESB_SYS_TIMER_IRQ_Handler TIMER2_IRQHandler /**< The handler that is used by @ref NRF_ESB_SYS_TIMER. */ + +#define NRF_ESB_PPI_TIMER_START 10 /**< The PPI channel used for timer start. */ +#define NRF_ESB_PPI_TIMER_STOP 11 /**< The PPI channel used for timer stop. */ +#define NRF_ESB_PPI_RX_TIMEOUT 12 /**< The PPI channel used for RX time-out. */ +#define NRF_ESB_PPI_TX_START 13 /**< The PPI channel used for starting TX. */ + +// Interrupt flags +#define NRF_ESB_INT_TX_SUCCESS_MSK 0x01 /**< The flag used to indicate a success since the last event. */ +#define NRF_ESB_INT_TX_FAILED_MSK 0x02 /**< The flag used to indicate a failure since the last event. */ +#define NRF_ESB_INT_RX_DR_MSK 0x04 /**< The flag used to indicate that a packet was received since the last event. */ + +#define NRF_ESB_PID_RESET_VALUE 0xFF /**< Invalid PID value that is guaranteed to not collide with any valid PID value. */ +#define NRF_ESB_PID_MAX 3 /**< The maximum value for PID. */ +#define NRF_ESB_CRC_RESET_VALUE 0xFFFF /**< The CRC reset value. */ + +#define ESB_EVT_IRQ SWI0_IRQn /**< The ESB event IRQ number when running on an nRF5x device. */ +#define ESB_EVT_IRQHandler SWI0_IRQHandler /**< The handler for @ref ESB_EVT_IRQ when running on an nRF5x device. */ + +/** Default address configuration for ESB. Roughly equal to the nRF24Lxx default (except for the number of pipes, because more pipes are supported). */ +#define NRF_ESB_ADDR_DEFAULT \ +{ \ + .base_addr_p0 = { 0xE7, 0xE7, 0xE7, 0xE7 }, \ + .base_addr_p1 = { 0xC2, 0xC2, 0xC2, 0xC2 }, \ + .pipe_prefixes = { 0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8 }, \ + .addr_length = 5, \ + .num_pipes = 8, \ + .rf_channel = 2, \ + .rx_pipes_enabled = 0xFF \ +} + + +/** Default radio parameters. Roughly equal to the nRF24Lxx default parameters (except for CRC, which is set to 16 bit, and protocol, which is set to DPL). */ +#define NRF_ESB_DEFAULT_CONFIG {.protocol = NRF_ESB_PROTOCOL_ESB_DPL, \ + .mode = NRF_ESB_MODE_PTX, \ + .event_handler = 0, \ + .bitrate = NRF_ESB_BITRATE_2MBPS, \ + .crc = NRF_ESB_CRC_16BIT, \ + .tx_output_power = NRF_ESB_TX_POWER_0DBM, \ + .retransmit_delay = 250, \ + .retransmit_count = 3, \ + .tx_mode = NRF_ESB_TXMODE_AUTO, \ + .radio_irq_priority = 1, \ + .event_irq_priority = 2, \ + .payload_length = 32, \ + .selective_auto_ack = false \ +} + + +/** Default legacy radio parameters, identical to the nRF24Lxx defaults. */ +#define NRF_ESB_LEGACY_CONFIG {.protocol = NRF_ESB_PROTOCOL_ESB, \ + .mode = NRF_ESB_MODE_PTX, \ + .event_handler = 0, \ + .bitrate = NRF_ESB_BITRATE_2MBPS, \ + .crc = NRF_ESB_CRC_8BIT, \ + .tx_output_power = NRF_ESB_TX_POWER_0DBM, \ + .retransmit_delay = 600, \ + .retransmit_count = 3, \ + .tx_mode = NRF_ESB_TXMODE_AUTO, \ + .radio_irq_priority = 1, \ + .event_irq_priority = 2, \ + .payload_length = 32, \ + .selective_auto_ack = false \ +} + + +/**Macro to create an initializer for a TX data packet. + * + * @details This macro generates an initializer. Using the initializer is more efficient + * than setting the individual parameters dynamically. + * + * @param[in] _pipe The pipe to use for the data packet. + * @param[in] ... Comma separated list of character data to put in the TX buffer. + * Supported values consist of 1 to 63 characters. + * + * @return Initializer that sets up the pipe, length, and byte array for content of the TX data. + */ +#define NRF_ESB_CREATE_PAYLOAD(_pipe, ...) \ + {.pipe = _pipe, .length = NUM_VA_ARGS(__VA_ARGS__), .data = {__VA_ARGS__}}; \ + STATIC_ASSERT(NUM_VA_ARGS(__VA_ARGS__) > 0 && NUM_VA_ARGS(__VA_ARGS__) <= 63) + + +/**@brief Enhanced ShockBurst protocols. */ +typedef enum { + NRF_ESB_PROTOCOL_ESB, /*< Enhanced ShockBurst with fixed payload length. */ + NRF_ESB_PROTOCOL_ESB_DPL /*< Enhanced ShockBurst with dynamic payload length. */ +} nrf_esb_protocol_t; + + +/**@brief Enhanced ShockBurst modes. */ +typedef enum { + NRF_ESB_MODE_PTX, /*< Primary transmitter mode. */ + NRF_ESB_MODE_PRX /*< Primary receiver mode. */ +} nrf_esb_mode_t; + + +/**@brief Enhanced ShockBurst bitrate modes. */ +typedef enum { + NRF_ESB_BITRATE_2MBPS = RADIO_MODE_MODE_Nrf_2Mbit, /**< 2 Mb radio mode. */ + NRF_ESB_BITRATE_1MBPS = RADIO_MODE_MODE_Nrf_1Mbit, /**< 1 Mb radio mode. */ + NRF_ESB_BITRATE_250KBPS = RADIO_MODE_MODE_Nrf_250Kbit, /**< 250 Kb radio mode. */ + NRF_ESB_BITRATE_1MBPS_BLE = RADIO_MODE_MODE_Ble_1Mbit /**< 1 Mb radio mode using @e Bluetooth low energy radio parameters. */ +} nrf_esb_bitrate_t; + + +/**@brief Enhanced ShockBurst CRC modes. */ +typedef enum { + NRF_ESB_CRC_16BIT = RADIO_CRCCNF_LEN_Two, /**< Use two-byte CRC. */ + NRF_ESB_CRC_8BIT = RADIO_CRCCNF_LEN_One, /**< Use one-byte CRC. */ + NRF_ESB_CRC_OFF = RADIO_CRCCNF_LEN_Disabled /**< Disable CRC. */ +} nrf_esb_crc_t; + + +/**@brief Enhanced ShockBurst radio transmission power modes. */ +typedef enum { + NRF_ESB_TX_POWER_4DBM = RADIO_TXPOWER_TXPOWER_Pos4dBm, /**< 4 dBm radio transmit power. */ + NRF_ESB_TX_POWER_0DBM = RADIO_TXPOWER_TXPOWER_0dBm, /**< 0 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG4DBM = RADIO_TXPOWER_TXPOWER_Neg4dBm, /**< -4 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG8DBM = RADIO_TXPOWER_TXPOWER_Neg8dBm, /**< -8 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG12DBM = RADIO_TXPOWER_TXPOWER_Neg12dBm, /**< -12 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG16DBM = RADIO_TXPOWER_TXPOWER_Neg16dBm, /**< -16 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG20DBM = RADIO_TXPOWER_TXPOWER_Neg20dBm, /**< -20 dBm radio transmit power. */ + NRF_ESB_TX_POWER_NEG30DBM = RADIO_TXPOWER_TXPOWER_Neg30dBm /**< -30 dBm radio transmit power. */ +} nrf_esb_tx_power_t; + + +/**@brief Enhanced ShockBurst transmission modes. */ +typedef enum { + NRF_ESB_TXMODE_AUTO, /*< Automatic TX mode: When the TX FIFO contains packets and the radio is idle, packets are sent automatically. */ + NRF_ESB_TXMODE_MANUAL, /*< Manual TX mode: Packets are not sent until @ref nrf_esb_start_tx is called. This mode can be used to ensure consistent packet timing. */ + NRF_ESB_TXMODE_MANUAL_START /*< Manual start TX mode: Packets are not sent until @ref nrf_esb_start_tx is called. Then, transmission continues automatically until the TX FIFO is empty. */ +} nrf_esb_tx_mode_t; + + +/**@brief Enhanced ShockBurst event IDs used to indicate the type of the event. */ +typedef enum +{ + NRF_ESB_EVENT_TX_SUCCESS, /**< Event triggered on TX success. */ + NRF_ESB_EVENT_TX_FAILED, /**< Event triggered on TX failure. */ + NRF_ESB_EVENT_RX_RECEIVED /**< Event triggered on RX received. */ +} nrf_esb_evt_id_t; + + +/**@brief Enhanced ShockBurst payload. + * + * @details The payload is used both for transmissions and for acknowledging a + * received packet with a payload. +*/ +typedef struct +{ + uint8_t length; /**< Length of the packet (maximum value is NRF_ESB_MAX_PAYLOAD_LENGTH). */ + uint8_t pipe; /**< Pipe used for this payload. */ + int8_t rssi; /**< RSSI for the received packet. */ + uint8_t noack; /**< Flag indicating that this packet will not be acknowledged. */ + uint8_t pid; /**< PID assigned during communication. */ + uint8_t data[NRF_ESB_MAX_PAYLOAD_LENGTH]; /**< The payload data. */ +} nrf_esb_payload_t; + + +/**@brief Enhanced ShockBurst event. */ +typedef struct +{ + nrf_esb_evt_id_t evt_id; /**< Enhanced ShockBurst event ID. */ + uint32_t tx_attempts; /**< Number of TX retransmission attempts. */ +} nrf_esb_evt_t; + + +/**@brief Definition of the event handler for the module. */ +typedef void (* nrf_esb_event_handler_t)(nrf_esb_evt_t const * p_event); + + +/**@brief Main configuration structure for the module. */ +typedef struct +{ + nrf_esb_protocol_t protocol; /**< Enhanced ShockBurst protocol. */ + nrf_esb_mode_t mode; /**< Enhanced ShockBurst mode. */ + nrf_esb_event_handler_t event_handler; /**< Enhanced ShockBurst event handler. */ + + // General RF parameters + nrf_esb_bitrate_t bitrate; /**< Enhanced ShockBurst bitrate mode. */ + nrf_esb_crc_t crc; /**< Enhanced ShockBurst CRC modes. */ + + nrf_esb_tx_power_t tx_output_power; /**< Enhanced ShockBurst radio transmission power mode.*/ + + uint16_t retransmit_delay; /**< The delay between each retransmission of unacknowledged packets. */ + uint16_t retransmit_count; /**< The number of retransmissions attempts before transmission fail. */ + + // Control settings + nrf_esb_tx_mode_t tx_mode; /**< Enhanced ShockBurst transmission mode. */ + + uint8_t radio_irq_priority; /**< nRF radio interrupt priority. */ + uint8_t event_irq_priority; /**< ESB event interrupt priority. */ + uint8_t payload_length; /**< Length of the payload (maximum length depends on the platforms that are used on each side). */ + + bool selective_auto_ack; /**< Enable or disable selective auto acknowledgment. */ +} nrf_esb_config_t; + + +/**@brief Function for initializing the Enhanced ShockBurst module. + * + * @param p_config Parameters for initializing the module. + * + * @retval NRF_SUCCESS If initialization was successful. + * @retval NRF_ERROR_NULL If the @p p_config argument was NULL. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_init(nrf_esb_config_t const * p_config); + + +/**@brief Function for suspending the Enhanced ShockBurst module. + * + * Calling this function stops ongoing communications without changing the queues. + * + * @retval NRF_SUCCESS If Enhanced ShockBurst was suspended. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_suspend(void); + + +/**@brief Function for disabling the Enhanced ShockBurst module. + * + * Calling this function disables the Enhanced ShockBurst module immediately. + * Doing so might stop ongoing communications. + * + * @note All queues are flushed by this function. + * + * @retval NRF_SUCCESS If Enhanced ShockBurst was disabled. + */ +uint32_t nrf_esb_disable(void); + + +/**@brief Function for checking if the Enhanced ShockBurst module is idle. + * + * @retval true If the module is idle. + * @retval false If the module is busy. + */ +bool nrf_esb_is_idle(void); + + +/**@brief Function for writing a payload for transmission or acknowledgment. + * + * This function writes a payload that is added to the queue. When the module is in PTX mode, the + * payload is queued for a regular transmission. When the module is in PRX mode, the payload + * is queued for when a packet is received that requires an acknowledgment with payload. + * + * @param[in] p_payload Pointer to the structure that contains information and state of the payload. + * + * @retval NRF_SUCCESS If the payload was successfully queued for writing. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + * @retval NRF_INVALID_STATE If the module is not initialized. + * @retval NRF_ERROR_NOT_SUPPORTED If @p p_payload->noack was false, but selective acknowledgment is not enabled. + * @retval NRF_ERROR_NO_MEM If the TX FIFO is full. + * @retval NRF_ERROR_INVALID_LENGTH If the payload length was invalid (zero or larger than the allowed maximum). + */ +uint32_t nrf_esb_write_payload(nrf_esb_payload_t const * p_payload); + + +/**@brief Function for reading an RX payload. + * + * @param[in,out] p_payload Pointer to the structure that contains information and state of the payload. + * + * @retval NRF_SUCCESS If the data was read successfully. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + * @retval NRF_INVALID_STATE If the module is not initialized. + */ +uint32_t nrf_esb_read_rx_payload(nrf_esb_payload_t * p_payload); + + +/**@brief Function for starting transmission. + * + * @retval NRF_SUCCESS If the TX started successfully. + * @retval NRF_ERROR_BUFFER_EMPTY If the TX does not start because the FIFO buffer is empty. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_start_tx(void); + + +/**@brief Function for starting to transmit data from the FIFO buffer. + * + * @retval NRF_SUCCESS If the transmission was started successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_start_rx(void); + + +/** @brief Function for stopping data reception. + * + * @retval NRF_SUCCESS If data reception was stopped successfully. + * @retval NRF_ESB_ERROR_NOT_IN_RX_MODE If the function failed because the module is not in RX mode. + */ +uint32_t nrf_esb_stop_rx(void); + + +/**@brief Function for removing remaining items from the TX buffer. + * + * This function clears the TX FIFO buffer. + * + * @retval NRF_SUCCESS If pending items in the TX buffer were successfully cleared. + * @retval NRF_INVALID_STATE If the module is not initialized. + */ +uint32_t nrf_esb_flush_tx(void); + + +/**@brief Function for removing the first item from the TX buffer. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_INVALID_STATE If the module is not initialized. + * @retval NRF_ERROR_BUFFER_EMPTY If there are no items in the queue to remove. + */ +uint32_t nrf_esb_pop_tx(void); + + +/**@brief Function for removing remaining items from the RX buffer. + * + * @retval NRF_SUCCESS If the pending items in the RX buffer were successfully cleared. + * @retval NRF_INVALID_STATE If the module is not initialized. + */ +uint32_t nrf_esb_flush_rx(void); + + + +/**@brief Function for setting the length of the address. + * + * @param[in] length Length of the ESB address (in bytes). + * + * @retval NRF_SUCCESS If the address length was set successfully. + * @retval NRF_ERROR_INVALID_PARAM If the address length was invalid. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_set_address_length(uint8_t length); + + +/**@brief Function for setting the base address for pipe 0. + * + * @param[in] p_addr Pointer to the address data. + * + * @retval NRF_SUCCESS If the base address was set successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + */ +uint32_t nrf_esb_set_base_address_0(uint8_t const * p_addr); + + +/**@brief Function for setting the base address for pipe 1 to pipe 7. + * + * @param[in] p_addr Pointer to the address data. + * + * @retval NRF_SUCCESS If the base address was set successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + */ +uint32_t nrf_esb_set_base_address_1(uint8_t const * p_addr); + + +/**@brief Function for setting the number of pipes and the pipe prefix addresses. + * + * This function configures the number of available pipes, enables the pipes, + * and sets their prefix addresses. + * + * @param[in] p_prefixes Pointer to a char array that contains the prefix for each pipe. + * @param[in] num_pipes Number of pipes. + * + * @retval NRF_SUCCESS If the prefix addresses were set successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + * @retval NRF_ERROR_NULL If a required parameter was NULL. + * @retval NRF_ERROR_INVALID_PARAM If an invalid number of pipes was given. + */ +uint32_t nrf_esb_set_prefixes(uint8_t const * p_prefixes, uint8_t num_pipes); + + +/**@brief Function for enabling pipes. + * + * The @p enable_mask parameter must contain the same number of pipes as has been configured + * with @ref nrf_esb_set_prefixes. + * + * @param enable_mask Bitfield mask to enable or disable pipes. Setting a bit to + * 0 disables the pipe. Setting a bit to 1 enables the pipe. + * + * @retval NRF_SUCCESS If the pipes were enabled and disabled successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_enable_pipes(uint8_t enable_mask); + + +/**@brief Function for updating the prefix for a pipe. + * + * @param pipe Pipe for which to set the prefix. + * @param prefix Prefix to set for the pipe. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + * @retval NRF_ERROR_INVALID_PARAM If the given pipe number was invalid. + */ +uint32_t nrf_esb_update_prefix(uint8_t pipe, uint8_t prefix); + + +/** @brief Function for setting the channel to use for the radio. + * + * The module must be in an idle state to call this function. As a PTX, the + * application must wait for an idle state and as a PRX, the application must stop RX + * before changing the channel. After changing the channel, operation can be resumed. + * + * @param[in] channel Channel to use for radio. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_INVALID_STATE If the module is not initialized. + * @retval NRF_ERROR_BUSY If the module was not in idle state. + * @retval NRF_ERROR_INVALID_PARAM If the channel is invalid (larger than 125). + */ +uint32_t nrf_esb_set_rf_channel(uint32_t channel); + + +/**@brief Function for getting the current radio channel. + * + * @param[in, out] p_channel Pointer to the channel data. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_ERROR_NULL If the required parameter was NULL. + */ +uint32_t nrf_esb_rf_channel_get(uint32_t * p_channel); + + +/**@brief Function for setting the radio output power. + * + * @param[in] tx_output_power Output power. + * + * @retval NRF_SUCCESS If the operation completed successfully. + * @retval NRF_ERROR_BUSY If the function failed because the radio is busy. + */ +uint32_t nrf_esb_set_tx_power(nrf_esb_tx_power_t tx_output_power); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_ESB diff --git a/components/proprietary_rf/esb/nrf_esb_error_codes.h b/components/proprietary_rf/esb/nrf_esb_error_codes.h new file mode 100644 index 0000000..c594151 --- /dev/null +++ b/components/proprietary_rf/esb/nrf_esb_error_codes.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 __NRF_ESB_ERROR_CODES_H__ +#define __NRF_ESB_ERROR_CODES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define NRF_ERROR_BUFFER_EMPTY (0x0100) + +#define NRF_ESB_ERROR_NOT_IN_RX_MODE (0x0101) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/proprietary_rf/esb/nrf_esb_resources.h b/components/proprietary_rf/esb/nrf_esb_resources.h new file mode 100644 index 0000000..35050c7 --- /dev/null +++ b/components/proprietary_rf/esb/nrf_esb_resources.h @@ -0,0 +1,73 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_ESB_RESOURCES_H__ +#define NRF_ESB_RESOURCES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup nrf_esb_resources ESB resources + * @{ + * @ingroup nrf_esb + */ + +#ifndef ESB_ALTERNATIVE_RESOURCES + #define ESB_PPI_CHANNELS_USED 0x00000007uL /**< PPI channels used by ESB (not available to the application). */ + #define ESB_TIMERS_USED 0x00000004uL /**< Timers used by ESB. */ + #define ESB_SWI_USED 0x00000001uL /**< Software interrupts used by ESB. */ +#else + #define ESB_PPI_CHANNELS_USED 0x00000700uL /**< PPI channels used by ESB (not available to the application). */ + #define ESB_TIMERS_USED 0x00000001uL /**< Timers used by ESB. */ + #define ESB_SWI_USED 0x00000002uL /**< Software interrupts used by ESB. */ +#endif + +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_ESB_RESOURCES_H__ */ diff --git a/components/proprietary_rf/gzll/arm/license.txt b/components/proprietary_rf/gzll/arm/license.txt new file mode 100644 index 0000000..3a9e590 --- /dev/null +++ b/components/proprietary_rf/gzll/arm/license.txt @@ -0,0 +1,37 @@ +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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. + +3. Neither the name of Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + diff --git a/components/proprietary_rf/gzll/config/nrf_gzp_config.h b/components/proprietary_rf/gzll/config/nrf_gzp_config.h new file mode 100644 index 0000000..bf3dcda --- /dev/null +++ b/components/proprietary_rf/gzll/config/nrf_gzp_config.h @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2008 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 __GZP_CONFIG_H +#define __GZP_CONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Definition of "secret key" used during "Host ID exchange". + */ + +#define GZP_SECRET_KEY {1, 23, 45, 57, 26, 68, 12, 64, 13, 73, 13, 62, 26, 45, 12, 77} + +//----------------------------------------------------------------------------- + +/** + Definition of the first static selected pairing channel. Should be located in + the lower Nth of the channel range, where N is the size if the channel subset + selected by the application. +*/ +#define GZP_CHANNEL_LOW 2 + +/** + Definition of the second static selected pairing channel. Should be located in + the upper Nth of the channel range, where N is the size if the channel subset + selected by the application. +*/ +#define GZP_CHANNEL_HIGH 79 + +/** + Definition of the static "global" pairing address. +*/ +#define GZP_ADDRESS 4, 6, 8, 10 + +/** + Reduced TX power for use during close proximity pairing. + */ +#define GZP_POWER NRF_GZLL_TX_POWER_N16_DBM + +/** + Definition of pairing request timeout. +*/ +#define GZP_REQ_TX_TIMEOUT 200 + +/** + Definition of the maximimum number of "backoff" packets (step 0) to be transmitted. +*/ +#define GZP_MAX_BACKOFF_PACKETS 100 + +/** + Definition of the period a device shall wait before attempting to send the packet for + fetching the pairing response (step 1). +*/ +#define GZP_TX_ACK_WAIT_TIMEOUT (GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT + 50) + +/** + Definition of the period a device in close proximity shall back off on the pairing + address after a backoff packet has been received. +*/ +#define GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT ((GZP_REQ_TX_TIMEOUT / 2) + 50) + +/** + Definition of the period a device NOT in close proximity shall back off on the pairing + address after a backoff packet has been received. +*/ +#define GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT (GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT + GZP_STEP1_RX_TIMEOUT) + +/** + Definition of the time the host waits for a device to complete + transmission of the pairing request step 1 packet. +*/ +#define GZP_STEP1_RX_TIMEOUT (((GZP_REQ_TX_TIMEOUT / 2) + GZP_TX_ACK_WAIT_TIMEOUT) + 50) + +/** + Definition of the lowest boundary for the channel range to be used. +*/ +#define GZP_CHANNEL_MIN 2 + +/** + Definition of the upper boundary for the channel range to be used. +*/ +#define GZP_CHANNEL_MAX 80 + +/** + Definition of the minimum channel spacing for the channel subset generated + during pairing. +*/ +#define GZP_CHANNEL_SPACING_MIN 5 + +/** + Non volatile memory (Flash or OTP) storage address. A device will + require GZP_DEVICE_PARAMS_STORAGE_SIZE bytes of memory, and + Host 11 bytes. When using flash memory, storage address should + be a multiple of chip page size. +*/ +#define GZP_PARAMS_STORAGE_ADR 0x00001000 + +/** + Number of bytes available for parameter storage in Device. + It is equal to flash page size on nRF5x chips. +*/ +#if defined (NRF51) + #define GZP_DEVICE_PARAMS_STORAGE_SIZE 1024 +#elif defined (NRF52) + #define GZP_DEVICE_PARAMS_STORAGE_SIZE 4096 +#endif + +/** + Maximum Device TX payload length [bytes]. + */ +#define GZP_MAX_FW_PAYLOAD_LENGTH 17 + +/** + Maximum Host ACK payload length [bytes]. + */ +#define GZP_MAX_ACK_PAYLOAD_LENGTH 10 + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/properitary_rf/gzll/gcc/gzll_gcc.a b/components/proprietary_rf/gzll/gcc/gzll_nrf51_gcc.a similarity index 100% rename from components/properitary_rf/gzll/gcc/gzll_gcc.a rename to components/proprietary_rf/gzll/gcc/gzll_nrf51_gcc.a diff --git a/components/proprietary_rf/gzll/gcc/gzll_nrf51_sd_resources_gcc.a b/components/proprietary_rf/gzll/gcc/gzll_nrf51_sd_resources_gcc.a new file mode 100644 index 0000000000000000000000000000000000000000..1956f281b30def2393c89a44f51b2ac333d3072b GIT binary patch literal 53688 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 literal 0 HcmV?d00001 diff --git a/components/proprietary_rf/gzll/gcc/gzll_nrf52_gcc.a b/components/proprietary_rf/gzll/gcc/gzll_nrf52_gcc.a new file mode 100644 index 0000000000000000000000000000000000000000..f1d603c4f71fc0f2c6a74d076c5041e6d6926889 GIT binary patch literal 53628 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 z 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 Hs)7Drp|vzh literal 0 HcmV?d00001 diff --git a/components/proprietary_rf/gzll/gcc/license.txt b/components/proprietary_rf/gzll/gcc/license.txt new file mode 100644 index 0000000..3a9e590 --- /dev/null +++ b/components/proprietary_rf/gzll/gcc/license.txt @@ -0,0 +1,37 @@ +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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. + +3. Neither the name of Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + diff --git a/components/properitary_rf/gzll/iar/gzll_iar.a b/components/proprietary_rf/gzll/iar/gzll_nrf51_iar.a similarity index 100% rename from components/properitary_rf/gzll/iar/gzll_iar.a rename to components/proprietary_rf/gzll/iar/gzll_nrf51_iar.a diff --git a/components/properitary_rf/gzll/iar/gzll_sd_resource_iar.a b/components/proprietary_rf/gzll/iar/gzll_nrf51_sd_resource_iar.a similarity index 100% rename from components/properitary_rf/gzll/iar/gzll_sd_resource_iar.a rename to components/proprietary_rf/gzll/iar/gzll_nrf51_sd_resource_iar.a diff --git a/components/proprietary_rf/gzll/iar/gzll_nrf52_iar.a b/components/proprietary_rf/gzll/iar/gzll_nrf52_iar.a new file mode 100644 index 0000000000000000000000000000000000000000..743ab9f2e71e2eb9aa56ef3db2cebacd912fe5cd GIT binary patch literal 131304 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 F{|gX6+Drfd literal 0 HcmV?d00001 diff --git a/components/proprietary_rf/gzll/iar/license.txt b/components/proprietary_rf/gzll/iar/license.txt new file mode 100644 index 0000000..3a9e590 --- /dev/null +++ b/components/proprietary_rf/gzll/iar/license.txt @@ -0,0 +1,37 @@ +Copyright (c) 2010 - 2017, Nordic Semiconductor ASA + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form, except as embedded into a Nordic + Semiconductor ASA integrated circuit in a product or a software update for + such product, 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. + +3. Neither the name of Nordic Semiconductor ASA nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +4. This software, with or without modification, must only be used with a + Nordic Semiconductor ASA integrated circuit. + +5. Any software provided in binary form under this license must not be reverse + engineered, decompiled, modified and/or disassembled. + +THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + diff --git a/components/properitary_rf/gzll/nrf_gzll.h b/components/proprietary_rf/gzll/nrf_gzll.h similarity index 84% rename from components/properitary_rf/gzll/nrf_gzll.h rename to components/proprietary_rf/gzll/nrf_gzll.h index 80a3e35..71de57e 100644 --- a/components/properitary_rf/gzll/nrf_gzll.h +++ b/components/proprietary_rf/gzll/nrf_gzll.h @@ -1,14 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - * $LastChangedRevision: 39629 $ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ @@ -20,10 +47,14 @@ #ifndef NRF_GZLL_H__ #define NRF_GZLL_H__ -#include "stdbool.h" +#include #include "nrf.h" #include "nrf_gzll_constants.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @defgroup gzll_02_api Application Programming Interface (API) @@ -47,7 +78,7 @@ typedef enum /** * @enum nrf_gzll_device_channel_selection_policy_t - * @brief Enumerator used for selecting Gazell Device channel + * @brief Enumerator used for selecting Gazell Device channel * selection policy. */ typedef enum @@ -108,7 +139,7 @@ typedef enum NRF_GZLL_ERROR_CODE_FAILED_TO_INITIALIZE = 1, ///< The function NRF_GZLL_init failed. NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_CONFIGURE_WHEN_ENABLED = 2, - ///< A call to a configuration 'set' function was made while Gazell was + ///< A call to a configuration 'set' function was made while Gazell was ///< enabled. NRF_GZLL_ERROR_CODE_POINTER_IS_NULL = 3, ///< A null pointer was given as an input to a function. @@ -116,13 +147,13 @@ typedef enum ///< An invalid pipe number was given as an input to a function. NRF_GZLL_ERROR_CODE_INVALID_MODE = 5, ///< An invalid value for the nrf_gzll_mode_t enumerator was given as input - ///< to a function. + ///< to a function. NRF_GZLL_ERROR_CODE_INVALID_PAYLOAD_LENGTH = 6, ///< An invalid payload length was given as an input to a function. NRF_GZLL_ERROR_CODE_INVALID_CHANNEL_TABLE_SIZE = 7, ///< An invalid channel table size was given as an input to a function. NRF_GZLL_ERROR_CODE_INSUFFICIENT_PACKETS_AVAILABLE = 8, - ///< There are insufficient packets in the Gazell memory pool to + ///< There are insufficient packets in the Gazell memory pool to ///< successfully execute the operation. NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_ADD_TO_FULL_FIFO = 9, ///< There is insufficient space in the TX FIFO for the data packet. @@ -145,12 +176,12 @@ typedef enum /** * @struct nrf_gzll_device_tx_info_t; - * @brief Data structure containing information about the last packet + * @brief Data structure containing information about the last packet * transmission. */ typedef struct { - bool payload_received_in_ack; + bool payload_received_in_ack; ///< A payload was received in the ACK. uint16_t num_tx_attempts; ///< Number of attempts used on previous Device packet transmission. @@ -162,7 +193,7 @@ typedef struct /** * @struct nrf_gzll_host_rx_info_t; - * @brief Data structure containing information about the last packet + * @brief Data structure containing information about the last packet * received. */ typedef struct @@ -185,8 +216,8 @@ typedef struct /** * @brief Initialize Gazell. * - * @param mode The mode to initialize Gazell in. - * + * @param mode The mode to initialize Gazell in. + * * @retval true if Gazell initialized. * @retval false if Gazell failed to initialize. */ @@ -197,9 +228,9 @@ bool nrf_gzll_init(nrf_gzll_mode_t mode); * @brief Enable Gazell. * * When enabled the behaviour described for the current Gazell Link Layer mode - * will apply. + * will apply. * - * @retval false if nrf_gzll_init has not previously been called. + * @retval false if nrf_gzll_init has not previously been called. */ bool nrf_gzll_enable(void); @@ -234,32 +265,32 @@ bool nrf_gzll_is_enabled(void); /******************************************************************************/ -/** - * @brief ACK received callback (Device mode only). - * - * This callback is made when the Device receives an ACK (acknowledgement) - * packet. +/** + * @brief ACK received callback (Device mode only). + * + * This callback is made when the Device receives an ACK (acknowledgement) + * packet. * @sa nrf_gzll_ack_payload_received. * * @param pipe is the pipe on which an ACK packet was received. * @param tx_info struct used to indicate whether a payload was received in the - * ack, as well as the number of TX attempts and channel switches required. + * ack, as well as the number of TX attempts and channel switches required. */ void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info); -/** +/** * @brief Transmission failed callback (Device mode only). - * + * * This callback is made when a packet does not receive an ACK after * nrf_gzll_max_retries is reached. The packet is deleted by Gazell. * * @param pipe is the pipe on which the transmission failed. - * @param tx_info struct used to indicate whether a payload was received - * in the ack, as well as RSSI and the number of TX attempts and - * channel switches required. + * @param tx_info struct used to indicate whether a payload was received + * in the ack, as well as RSSI and the number of TX attempts and + * channel switches required. */ -void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info); +void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info); /** @} */ @@ -270,11 +301,11 @@ void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) /** @name Host mode callback functions * @{ */ /******************************************************************************/ - -/** - * @brief Data packet received callback (Host mode only). - * - * This callback is made when a Host receives a data packet from a Device. + +/** + * @brief Data packet received callback (Host mode only). + * + * This callback is made when a Host receives a data packet from a Device. * * @param pipe is the pipe on which the data packet was received. * @param rx_info struct used to indicate whether a payload was removed from the @@ -291,19 +322,19 @@ void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info) /******************************************************************************/ -/** - * @brief Disabled callback. - * - * This is called after Gazell enters the disabled state. - * There is no further CPU use by Gazell, the radio is disabled and the timer is +/** + * @brief Disabled callback. + * + * This is called after Gazell enters the disabled state. + * There is no further CPU use by Gazell, the radio is disabled and the timer is * powered down. */ void nrf_gzll_disabled(void); -/** - * @brief Mode changed callbackl. - * +/** + * @brief Mode changed callbackl. + * * This function is called after the Gazell mode has been changed. * This function can only be called when Gazell is enabled. */ @@ -319,32 +350,32 @@ void nrf_gzll_mode_changed(void); /******************************************************************************/ /** - * @brief Add a packet to the tail of the TX FIFO. + * @brief Add a packet to the tail of the TX FIFO. * - * In Device mode, the packet will be added. - * In Host mode, the payload will be piggybacked onto an ACK. + * In Device mode, the packet will be added. + * In Host mode, the payload will be piggybacked onto an ACK. * * @param pipe Pipe to which to add the payload. This value must be < NRF_GZLL_CONST_PIPE_COUNT. - * @param payload Pointer to the payload. - * @param length Number of bytes of the payload to transmit + * @param payload Pointer to the payload. + * @param length Number of bytes of the payload to transmit * (0 to NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH). * * @retval true if the packet was successfully added to the TX FIFO. - * @retval false if unsuccessful, check nrf_gzll_error_code_t for more information. + * @retval false if unsuccessful, check nrf_gzll_error_code_t for more information. */ bool nrf_gzll_add_packet_to_tx_fifo(uint32_t pipe, uint8_t * payload, uint32_t length); /** - * @brief Fetch a packet from the head of the RX FIFO. + * @brief Fetch a packet from the head of the RX FIFO. * * @param pipe Pipe from which to fetch the payload. This value must be < NRF_GZLL_CONST_PIPE_COUNT. - * @param payload Pointer to copy the payload to. + * @param payload Pointer to copy the payload to. * @param length Length must be at least as large as the the number of bytes - * in the received payload length. + * in the received payload length. * * @retval true If the fetch was successful. - * @retval false If unsuccessful, check nrf_gzll_error_code_t for more information. + * @retval false If unsuccessful, check nrf_gzll_error_code_t for more information. */ bool nrf_gzll_fetch_packet_from_rx_fifo(uint32_t pipe, uint8_t * payload, uint32_t* length); @@ -397,7 +428,7 @@ bool nrf_gzll_ok_to_add_packet_to_tx_fifo(uint32_t pipe); /** * @brief Flush the RX FIFO for a specific pipe. * - * Delete all the packets and free the memory of the TX FIFO for a + * Delete all the packets and free the memory of the TX FIFO for a * specific pipe. * * Note that it is not allowed to flush a TX FIFO when @@ -413,7 +444,7 @@ bool nrf_gzll_flush_tx_fifo(uint32_t pipe); /** * @brief Flush the RX FIFO for a specific pipe. * - * Delete all the packets and free the memory of the RX FIFO for a + * Delete all the packets and free the memory of the RX FIFO for a * specific pipe. * * @param pipe is the pipe for which to flush. This value must be < NRF_GZLL_CONST_PIPE_COUNT. @@ -428,10 +459,10 @@ bool nrf_gzll_flush_rx_fifo(uint32_t pipe); /******************************************************************************/ /** @name Configuration functions - * - * Configuration 'set' functions may only be called while Gazell is disabled. The + * + * Configuration 'set' functions may only be called while Gazell is disabled. The * new parameter comes into effect when Gazell is enabled again. - * + * * Configuration 'get' functions may be called at any time. * * @{ */ @@ -441,15 +472,15 @@ bool nrf_gzll_flush_rx_fifo(uint32_t pipe); /** * @brief Set the mode. * - * @param mode The mode to be used. - * See nrf_gzll_mode_t for a list of valid modes. - * + * @param mode The mode to be used. + * See nrf_gzll_mode_t for a list of valid modes. + * * It is allowed to change mode when Gazell is enabled. If the mode is - * being changed while Gazell is enabled, the mode will not change right away. + * being changed while Gazell is enabled, the mode will not change right away. * In this case the callback function nrf_gzll_mode_changed() will be called * after the mdoe has changed. * - * @retval true If the parameter was set. + * @retval true If the parameter was set. */ bool nrf_gzll_set_mode(nrf_gzll_mode_t mode); @@ -468,9 +499,9 @@ nrf_gzll_mode_t nrf_gzll_get_mode(void); * The full on-air address for each pipe is composed of a multi-byte base address * prepended to a prefix byte. * - * For packets to be received correctly, the most significant byte of - * the base address should not be an alternating sequence of 0s and 1s i.e. - * it should not be 0x55 or 0xAA. + * For packets to be received correctly, the most significant byte of + * the base address should not be an alternating sequence of 0s and 1s i.e. + * it should not be 0x55 or 0xAA. * * @param base_address The 4 byte base address. All bytes are used. * @@ -512,10 +543,10 @@ uint32_t nrf_gzll_get_base_address_1(void); /** * @brief Set the address prefix byte for a specific pipe. * - * Each pipe should have its own unique prefix byte. + * Each pipe should have its own unique prefix byte. * * @param pipe The pipe that the address should apply to. - * This value must be < NRF_GZLL_CONST_PIPE_COUNT. + * This value must be < NRF_GZLL_CONST_PIPE_COUNT. * @param address_prefix_byte The address prefix byte. * * @retval true If the parameter was set. @@ -529,11 +560,11 @@ bool nrf_gzll_set_address_prefix_byte(uint32_t pipe, uint8_t address_prefix_byte * * @param pipe The pipe for which to get the address. * This value must be < NRF_GZLL_CONST_PIPE_COUNT. - * @param out_address_prefix_byte The pointer in which to return the + * @param out_address_prefix_byte The pointer in which to return the * address prefix byte. - * + * * @retval true If the parameter was returned. - * @retval false If Gazell was enabled, the pipe was invalid or + * @retval false If Gazell was enabled, the pipe was invalid or * out_address was a NULL pointer. */ bool nrf_gzll_get_address_prefix_byte(uint32_t pipe, uint8_t* out_address_prefix_byte); @@ -543,7 +574,7 @@ bool nrf_gzll_get_address_prefix_byte(uint32_t pipe, uint8_t* out_address_prefix * @brief Set which pipes shall listen for packets in Host mode. * * This value is a bitmap, and each bit corresponds to a given pipe number. - * Bit 0 set to "1" enables pipes 0, bit 1 set to "1" enables pipe 1 + * Bit 0 set to "1" enables pipes 0, bit 1 set to "1" enables pipe 1 * and so forth. * The maximum number of pipes is defined by NRF_GZLL_CONST_PIPE_COUNT. * @@ -566,9 +597,9 @@ uint32_t nrf_gzll_get_rx_pipes_enabled(void); /** * @brief Set the timeslot period. * - * The length in microseconds of a Gazell link layer timeslot. + * The length in microseconds of a Gazell link layer timeslot. * - * The minimum value of the timeslot period is dependent of the + * The minimum value of the timeslot period is dependent of the * radio data rate (@sa nrf_gzll_set_datarate()). * * - For NRF_GZLL_DATARATE_2MBIT the timeslot period must be >= 600 us. @@ -599,14 +630,14 @@ uint32_t nrf_gzll_get_timeslot_period(void); * * @param policy The channel selection policy. * - * @arg NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL specifies - * that a new packet transmission always shall use the previous - * successful channel from the channel table. If Gazell is "in sync", Gazell - * will wait until this channel is being monitored by the Host before starting + * @arg NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL specifies + * that a new packet transmission always shall use the previous + * successful channel from the channel table. If Gazell is "in sync", Gazell + * will wait until this channel is being monitored by the Host before starting * the transmission. * - * @arg NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT specifies that - * Gazell shall transmit on the channel that is currently being monitored by the + * @arg NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT specifies that + * Gazell shall transmit on the channel that is currently being monitored by the * Host. This parameter is only used when Gazell is "in sync". When "out of" sync, * Gazell will always start using the "previous successful" channel. * @@ -629,17 +660,17 @@ nrf_gzll_device_channel_selection_policy_t nrf_gzll_get_device_channel_selection * reside on a single channel before switching to another channel. * * This parameter applies in Host mode and for a Device that is - * in the "in sync" state. + * in the "in sync" state. * - * Since the Device and Host can not be in perfect synchronization, a - * transmission should overlap to adjacent timeslots on the Host. + * Since the Device and Host can not be in perfect synchronization, a + * transmission should overlap to adjacent timeslots on the Host. * Therefore this value should be at least 2. * - * @sa nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync + * @sa nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync * * @param timeslots The number of timeslots to reside on * each channel before channel switch. - * + * * @retval true If the parameter was set. * @retval false If Gazell was enabled. */ @@ -656,11 +687,11 @@ uint32_t nrf_gzll_get_timeslots_per_channel(void); /** * @brief Set the number of timeslots that a Gazell shall - * reside on a single channel before switching to another channel when - * in the "out of sync" state. + * reside on a single channel before switching to another channel when + * in the "out of sync" state. * * This value should be set so that the Device transmits on one channel - * while the Host goes through a full channel rotation, i.e., + * while the Host goes through a full channel rotation, i.e., * channel_table_size*timeslots_per_channel. * This ensures that the channels on the Device and Host will coincide * at some point. @@ -677,7 +708,7 @@ bool nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync(uint32_t timeslo /** - * @brief Get function counterpart to + * @brief Get function counterpart to * nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync(). * * @return The current number of timeslots. @@ -686,12 +717,12 @@ uint32_t nrf_gzll_get_timeslots_per_channel_when_device_out_of_sync(void); /** - * @brief Set the number of timeslots after a successful - * reception of a Device or Host packet that the Gazell Link Layer shall assume - * that the link is synchronized. A value of 0 implies that the + * @brief Set the number of timeslots after a successful + * reception of a Device or Host packet that the Gazell Link Layer shall assume + * that the link is synchronized. A value of 0 implies that the * link is always out of sync. - * - * @param lifetime The sync lifetime in number of timeslots. + * + * @param lifetime The sync lifetime in number of timeslots. * * @retval true If the sync lifetime was set. * @retval false If Gazell was enabled. @@ -702,21 +733,21 @@ bool nrf_gzll_set_sync_lifetime(uint32_t lifetime); /** * @brief Get function counterpart to nrf_gzll_set_sync_lifetime(). * - * @return The sync lifetime measured in number of timeslots. + * @return The sync lifetime measured in number of timeslots. */ uint32_t nrf_gzll_get_sync_lifetime(void); /** * @brief Set the maximum number of TX attempts - * that can be used for a single packet. - * - * After the maximum number of attempts have been spent without - * receiving any ACK from the Host, the transmission will be terminated + * that can be used for a single packet. + * + * After the maximum number of attempts have been spent without + * receiving any ACK from the Host, the transmission will be terminated * and the nrf_gzll_device_tx_failed() callback will be called. * * @param max_tx_attempts The maximum number of TX attempts. - * + * * @retval true If the parameter was set. * @retval false If Gazell was enabled. */ @@ -728,18 +759,18 @@ bool nrf_gzll_set_max_tx_attempts(uint16_t max_tx_attempts); * * @return The current max Device TX attempts. */ -uint16_t nrf_gzll_get_max_tx_attempts(void); +uint16_t nrf_gzll_get_max_tx_attempts(void); /** * @brief Set the table of Radio Frequency (RF) channels. - * - * The valid channels are in the range 0 <= channel <= 125, where the + * + * The valid channels are in the range 0 <= channel <= 125, where the * actual centre frequency is (2400 + channel) MHz. - * The maximum channel table size is defined by + * The maximum channel table size is defined by * NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE. * - * @param channel_table Pointer to the channel table. + * @param channel_table Pointer to the channel table. * @param size The size of the channel table. * * @retval true If the channel table was set. @@ -751,7 +782,7 @@ bool nrf_gzll_set_channel_table(uint8_t* channel_table, uint32_t size); /** * @brief Get the table of Radio Frequency (RF) channels. - * + * * @param channel_table Pointer to copy the channel table to. * @param size Pointer to copy the size of the channel table to. * The value already at size must be at least the size @@ -805,7 +836,7 @@ bool nrf_gzll_set_datarate(nrf_gzll_datarate_t data_rate); /** * @brief Get function counterpart to nrf_gzll_set_datarate(). * - * @return The current datarate. + * @return The current datarate. */ nrf_gzll_datarate_t nrf_gzll_get_datarate(void); @@ -850,7 +881,7 @@ void nrf_gzll_set_auto_disable(uint32_t num_ticks); /** - * @brief Get the number of timeslot ticks that have occurred since + * @brief Get the number of timeslot ticks that have occurred since * nrf_gzll_init() was called. * * @return Number of timeslot ticks. @@ -878,7 +909,7 @@ void nrf_gzll_clear_tick_count(void); /** * @brief Gets the Gazell error code. * - * @return The current error code. + * @return The current error code. */ nrf_gzll_error_code_t nrf_gzll_get_error_code(void); @@ -893,4 +924,9 @@ void nrf_gzll_reset_error_code(void); /** @} */ /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/properitary_rf/gzll/nrf_gzll_constants.h b/components/proprietary_rf/gzll/nrf_gzll_constants.h similarity index 75% rename from components/properitary_rf/gzll/nrf_gzll_constants.h rename to components/proprietary_rf/gzll/nrf_gzll_constants.h index e6babc4..809d397 100644 --- a/components/properitary_rf/gzll/nrf_gzll_constants.h +++ b/components/proprietary_rf/gzll/nrf_gzll_constants.h @@ -1,14 +1,41 @@ -/* Copyright (c) 2011 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - * $LastChangedRevision: 32956 $ +/** + * Copyright (c) 2011 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ @@ -22,13 +49,17 @@ #ifndef NRF_GZLL_CONSTANTS_H__ #define NRF_GZLL_CONSTANTS_H__ +#ifdef __cplusplus +extern "C" { +#endif + /** * @addtogroup gzll_02_api * @{ */ - + /*****************************************************************************/ /** @name Hardware resources used by Gazell */ /*****************************************************************************/ @@ -42,12 +73,12 @@ #define NRF_GZLL_TIMER NRF_TIMER2 ///< Timer to be used as flywheel timer. #define NRF_GZLL_TIMER_PERPOWER_Msk POWER_PERPOWER_TIMER2_Msk ///< PERPOWER mask for the timer. #define NRF_GZLL_TIMER_IRQn TIMER2_IRQn ///< Interrupt # for the timer. -#define NRF_GZLL_TIMER_IRQ_HANDLER TIMER2_IRQHandler ///< Interrupt handler for the timer. +#define NRF_GZLL_TIMER_IRQ_HANDLER TIMER2_IRQHandler ///< Interrupt handler for the timer. // In addition, Gazell uses the radio peripheral and radio interrupts. - + /* - * PPI configuration + * PPI configuration */ #define NRF_GZLL_PPI_EEP0 (NRF_PPI -> CH0_EEP) ///< Gazell PPI event endpoint 0 #define NRF_GZLL_PPI_TEP0 (NRF_PPI -> CH0_TEP) ///< Gazell PPI task endpoint 0 @@ -67,12 +98,12 @@ #define NRF_GZLL_TIMER NRF_TIMER0 ///< Timer to be used as flywheel timer. #define NRF_GZLL_TIMER_PERPOWER_Msk POWER_PERPOWER_TIMER0_Msk ///< PERPOWER mask for the timer. #define NRF_GZLL_TIMER_IRQn TIMER0_IRQn ///< Interrupt # for the timer. -#define NRF_GZLL_TIMER_IRQ_HANDLER TIMER0_IRQHandler ///< Interrupt handler for the timer. +#define NRF_GZLL_TIMER_IRQ_HANDLER TIMER0_IRQHandler ///< Interrupt handler for the timer. // In addition, Gazell uses the radio peripheral and radio interrupts. - + /* - * PPI configuration + * PPI configuration */ #define NRF_GZLL_PPI_EEP0 (NRF_PPI -> CH8_EEP) ///< Gazell PPI event endpoint 0 #define NRF_GZLL_PPI_TEP0 (NRF_PPI -> CH8_TEP) ///< Gazell PPI task endpoint 0 @@ -89,19 +120,19 @@ #define NRF_GZLL_CONST_PIPE_COUNT 8 ///< Number of TX pipes (at least one for each Device-Host pairs). #define NRF_GZLL_CONST_FIFO_LENGTH 3 ///< Maximum number of packets allowed in a TX or RX FIFO. #define NRF_GZLL_CONST_MAX_TOTAL_PACKETS 6 ///< Maximum number of packets available for reservation at any one time. -#define NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH 32 ///< Maximum allowed payload length in bytes. +#define NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH 32 ///< Maximum allowed payload length in bytes. #define NRF_GZLL_CONST_CALLBACK_QUEUE_LENGTH 10 ///< Maximum number of notifications allowed in the callback queue. /** @} */ - + /*****************************************************************************/ /** @name Constant pipe and FIFO configuration */ /*****************************************************************************/ #define NRF_GZLL_CONST_PIPE_COUNT 8 ///< Number of TX pipes (at least one for each Device-Host pairs). #define NRF_GZLL_CONST_FIFO_LENGTH 3 ///< Maximum number of packets allowed in a TX or RX FIFO. #define NRF_GZLL_CONST_MAX_TOTAL_PACKETS 6 ///< Maximum number of packets available for reservation at any one time. -#define NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH 32 ///< Maximum allowed payload length in bytes. +#define NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH 32 ///< Maximum allowed payload length in bytes. #define NRF_GZLL_CONST_CALLBACK_QUEUE_LENGTH 10 ///< Maximum number of notifications allowed in the callback queue. /** @} */ @@ -123,17 +154,17 @@ /*****************************************************************************/ /* Corresponds to Legacy nRFgo SDK Gazell config: -#define GZLL_DEFAULT_ADDRESS_PIPE0 {0x01, 0x04, 0x07, 0x0A, 0x0D} // {1, 4, 7, 10, 13} -#define GZLL_DEFAULT_ADDRESS_PIPE1 {0x02, 0x05, 0x08, 0x0B, 0x0E} // {2, 5, 8, 11, 14} -#define GZLL_DEFAULT_ADDRESS_PIPE2 3 -#define GZLL_DEFAULT_ADDRESS_PIPE3 4 -#define GZLL_DEFAULT_ADDRESS_PIPE4 5 +#define GZLL_DEFAULT_ADDRESS_PIPE0 {0x01, 0x04, 0x07, 0x0A, 0x0D} // {1, 4, 7, 10, 13} +#define GZLL_DEFAULT_ADDRESS_PIPE1 {0x02, 0x05, 0x08, 0x0B, 0x0E} // {2, 5, 8, 11, 14} +#define GZLL_DEFAULT_ADDRESS_PIPE2 3 +#define GZLL_DEFAULT_ADDRESS_PIPE3 4 +#define GZLL_DEFAULT_ADDRESS_PIPE4 5 #define GZLL_DEFAULT_ADDRESS_PIPE5 6 */ #define NRF_GZLL_DEFAULT_FULL_ADDRESS_PIPE0 {0x01, 0x04, 0x07, 0x0A, 0x0D} ///< Corresponding legacy Gazell pipe 0 address. #define NRF_GZLL_DEFAULT_BASE_ADDRESS_0 0x0D0A0704 ///< Default base address 0. #define NRF_GZLL_DEFAULT_BASE_ADDRESS_1 0x0E0B0805 ///< Default base address 1. -#define NRF_GZLL_DEFAULT_PREFIX_BYTE_0 1 ///< Default prefix address pipe 0. +#define NRF_GZLL_DEFAULT_PREFIX_BYTE_0 1 ///< Default prefix address pipe 0. #define NRF_GZLL_DEFAULT_PREFIX_BYTE_1 2 ///< Default prefix address pipe 1. #define NRF_GZLL_DEFAULT_PREFIX_BYTE_2 3 ///< Default prefix address pipe 2. #define NRF_GZLL_DEFAULT_PREFIX_BYTE_3 4 ///< Default prefix address pipe 3. @@ -154,12 +185,17 @@ Corresponds to Legacy nRFgo SDK Gazell config: #define NRF_GZLL_DEFAULT_TIMESLOT_PERIOD 600 ///< Default timeslot period. #define NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL 2 ///< Timeslots use by the Host and by the Device when communication is in sync. #define NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL_WHEN_DEVICE_OUT_OF_SYNC 15 ///< Timeslots use by the Device before communication is in sync. -#define NRF_GZLL_DEFAULT_SYNC_LIFETIME (3*NRF_GZLL_DEFAULT_CHANNEL_TABLE_SIZE*NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL) ///< Number of timeslots to keep the timer running so that communication remains synchronized. +#define NRF_GZLL_DEFAULT_SYNC_LIFETIME (3 * NRF_GZLL_DEFAULT_CHANNEL_TABLE_SIZE * NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL) ///< Number of timeslots to keep the timer running so that communication remains synchronized. #define NRF_GZLL_DEFAULT_DEVICE_CHANNEL_SELECTION_POLICY NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL ///< Default channel Gazell Device channel selection policy -#define NRF_GZLL_DEFAULT_MAX_TX_ATTEMPTS 0 ///< Default maximum TX attempts for each packet. A value of zero implies maximum +#define NRF_GZLL_DEFAULT_MAX_TX_ATTEMPTS 0 ///< Default maximum TX attempts for each packet. A value of zero implies maximum #define NRF_GZLL_DEFAULT_XOSC_CTL NRF_GZLL_XOSC_CTL_AUTO ///< Deafult setting for controlling the XOSC /** @} */ /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/proprietary_rf/gzll/nrf_gzll_error.h b/components/proprietary_rf/gzll/nrf_gzll_error.h new file mode 100644 index 0000000..13bd7a6 --- /dev/null +++ b/components/proprietary_rf/gzll/nrf_gzll_error.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 + * @brief Gazell error API. + */ + +#ifndef NRF_GZLL_ERROR_H__ +#define NRF_GZLL_ERROR_H__ + +#include "sdk_errors.h" +#include "nrf_gzll.h" +#include "app_error.h" + +#define GAZELLE_ERROR_CODE_CHECK(GZLL_RESULT) \ + do \ + { \ + if((GZLL_RESULT) == false) \ + { \ + nrf_gzll_error_code_t gzll_error_code = nrf_gzll_get_error_code(); \ + ret_code_t error_code = gzll_error_code + NRF_ERROR_GAZELLE_ERR_BASE; \ + APP_ERROR_HANDLER(error_code); \ + } \ + } while(0) + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/proprietary_rf/gzll/nrf_gzll_resources.h b/components/proprietary_rf/gzll/nrf_gzll_resources.h new file mode 100644 index 0000000..0ae0f68 --- /dev/null +++ b/components/proprietary_rf/gzll/nrf_gzll_resources.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_GZLL_RESOURCES_H__ +#define NRF_GZLL_RESOURCES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef GAZELL_ALTERNATIVE_RESOURCES + #define GZLL_PPI_CHANNELS_USED 0x00000007uL /**< PPI channels utilized by Gazell (not available to th spplication). */ + #define GZLL_TIMERS_USED 0x00000004uL /**< Timers used by Gazell. */ + #define GZLL_SWI_USED 0x00000001uL /**< Software interrupts used by Gazell */ +#else + #define GZLL_PPI_CHANNELS_USED 0x00000700uL /**< PPI channels utilized by Gazell (not available to th spplication). */ + #define GZLL_TIMERS_USED 0x00000001uL /**< Timers used by Gazell. */ + #define GZLL_SWI_USED 0x00000002uL /**< Software interrupts used by Gazell */ +#endif + + + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_GZLL_RESOURCES_H__ */ diff --git a/components/properitary_rf/gzll/nrf_gzp.c b/components/proprietary_rf/gzll/nrf_gzp.c similarity index 67% rename from components/properitary_rf/gzll/nrf_gzp.c rename to components/proprietary_rf/gzll/nrf_gzp.c index 6ab5f59..5e0ba33 100644 --- a/components/properitary_rf/gzll/nrf_gzp.c +++ b/components/proprietary_rf/gzll/nrf_gzp.c @@ -1,18 +1,45 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic - * Semiconductor ASA.Terms and conditions of usage are described in detail - * in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRENTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - * $LastChangedRevision: 25890 $ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @brief Implementation of Gazell Pairing Library (gzp), Common functions. * @defgroup gzp_source_common Gazell Pairing common functions implementation @@ -35,28 +62,28 @@ * @{ */ /******************************************************************************/ -/** - * Constant holding base address part of the pairing address. +/** + * Constant holding base address part of the pairing address. */ -static const uint8_t pairing_base_address[4] = { GZP_ADDRESS }; +static const uint8_t pairing_base_address[4] = { GZP_ADDRESS }; /** * Constant holding prefix byte of the pairing address. */ -static const uint8_t pairing_address_prefix_byte = 0; +static const uint8_t pairing_address_prefix_byte = 0; -/** - * Constant holding pre-defined "validation ID". +/** + * Constant holding pre-defined "validation ID". */ static const uint8_t gzp_validation_id[GZP_VALIDATION_ID_LENGTH] = GZP_VALIDATION_ID; -/** - * Constant holding pre-defined "secret key". +/** + * Constant holding pre-defined "secret key". */ static const uint8_t gzp_secret_key[16] = GZP_SECRET_KEY; -/** - * Variable used for AES key selection +/** + * Variable used for AES key selection */ static gzp_key_select_t gzp_key_select; @@ -89,19 +116,19 @@ bool gzp_update_radio_params(const uint8_t* system_address) gzll_enabled_state = nrf_gzll_is_enabled(); // Configure "global" pairing address - pairing_base_address_32 = (pairing_base_address[0]) + + pairing_base_address_32 = (pairing_base_address[0]) + ((uint32_t)pairing_base_address[1] << 8) + ((uint32_t)pairing_base_address[2] << 16) + ((uint32_t)pairing_base_address[3] << 24) ; - if(system_address != NULL) + if (system_address != NULL) { - system_address_32 = (system_address[0]) + + system_address_32 = (system_address[0]) + ((uint32_t)system_address[1] << 8) + ((uint32_t)system_address[2] << 16) + ((uint32_t)system_address[3] << 24) ; } else - { + { return false; } @@ -111,7 +138,7 @@ bool gzp_update_radio_params(const uint8_t* system_address) update_ok = update_ok && nrf_gzll_set_base_address_1(system_address_32); // Configure address for pipe 1 - 5. Address byte set to equal pipe number. - for(i = 1; i < NRF_GZLL_CONST_PIPE_COUNT; i++) + for (i = 1; i < NRF_GZLL_CONST_PIPE_COUNT; i++) { update_ok = update_ok && nrf_gzll_set_address_prefix_byte(i,i); } @@ -119,9 +146,9 @@ bool gzp_update_radio_params(const uint8_t* system_address) channel_table_size = nrf_gzll_get_channel_table_size(); gzp_generate_channels(&channels[0], system_address, channel_table_size); - // Write generated channel subset to Gazell Link Layer + // Write generated channel subset to Gazell Link Layer update_ok = update_ok && nrf_gzll_set_channel_table(&channels[0], channel_table_size); - if(gzll_enabled_state) + if (gzll_enabled_state) { update_ok = update_ok && nrf_gzll_enable(); } @@ -137,32 +164,32 @@ void gzp_generate_channels(uint8_t* ch_dst, const uint8_t* system_address, uint8 ch_dst[0] = GZP_CHANNEL_LOW; ch_dst[channel_tab_size - 1] = GZP_CHANNEL_HIGH; - if(system_address != NULL) + if (system_address != NULL) { - for(i = 1; i < (channel_tab_size - 1); i++) + for (i = 1; i < (channel_tab_size - 1); i++) { - ch_dst[i] = (binsize * i) + (system_address[i % 4] % binsize); + ch_dst[i] = (binsize * i) + (system_address[i % 4] % binsize); } } // If channels are too close, shift them to better positions - for(i = 1; i < channel_tab_size; i++) + for (i = 1; i < channel_tab_size; i++) { - spacing = (ch_dst[i] - ch_dst[i - 1]); - if(spacing < GZP_CHANNEL_SPACING_MIN) + spacing = (ch_dst[i] - ch_dst[i - 1]); + if (spacing < GZP_CHANNEL_SPACING_MIN) { - ch_dst[i] += (GZP_CHANNEL_SPACING_MIN - spacing); + ch_dst[i] += (GZP_CHANNEL_SPACING_MIN - spacing); } } } __INLINE void nrf_gzp_disable_gzll(void) { - if(nrf_gzll_is_enabled()) + if (nrf_gzll_is_enabled()) { nrf_gzll_disable(); __WFI(); - while(nrf_gzll_is_enabled()) + while (nrf_gzll_is_enabled()) { } } @@ -174,7 +201,7 @@ void gzp_xor_cipher(uint8_t* dst, const uint8_t* src, const uint8_t* pad, uint8_ { uint8_t i; - for(i = 0; i < length; i++) + for (i = 0; i < length; i++) { *dst = *src ^ *pad; dst++; @@ -190,7 +217,7 @@ bool gzp_validate_id(const uint8_t* id) void gzp_add_validation_id(uint8_t* dst) { - memcpy(dst, (void const*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH); + memcpy(dst, (void const*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH); } void gzp_crypt_set_session_token(const uint8_t * token) @@ -200,7 +227,7 @@ void gzp_crypt_set_session_token(const uint8_t * token) void gzp_crypt_set_dyn_key(const uint8_t* key) { - memcpy(gzp_dyn_key, (void const*)key, GZP_DYN_KEY_LENGTH); + memcpy(gzp_dyn_key, (void const*)key, GZP_DYN_KEY_LENGTH); } void gzp_crypt_get_session_token(uint8_t * dst_token) @@ -210,7 +237,7 @@ void gzp_crypt_get_session_token(uint8_t * dst_token) void gzp_crypt_get_dyn_key(uint8_t* dst_key) { - memcpy(dst_key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH); + memcpy(dst_key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH); } void gzp_crypt_select_key(gzp_key_select_t key_select) @@ -226,7 +253,7 @@ void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length) // Build AES key based on "gzp_key_select" - switch(gzp_key_select) + switch (gzp_key_select) { case GZP_ID_EXCHANGE: memcpy(key, (void const*)gzp_secret_key, 16); @@ -241,12 +268,12 @@ void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length) break; default: return; - } + } // Build init vector from "gzp_session_token" - for(i = 0; i < 16; i++) + for (i = 0; i < 16; i++) { - if(i < GZP_SESSION_TOKEN_LENGTH) + if (i < GZP_SESSION_TOKEN_LENGTH) { iv[i] = gzp_session_token[i]; } @@ -275,9 +302,9 @@ void gzp_random_numbers_generate(uint8_t * dst, uint8_t n) NRF_RNG->EVENTS_VALRDY=0; NRF_RNG->TASKS_START = 1; - for(i = 0; i < n; i++) + for (i = 0; i < n; i++) { - while(NRF_RNG->EVENTS_VALRDY==0) + while (NRF_RNG->EVENTS_VALRDY==0) {} dst[i] = (uint8_t)NRF_RNG->VALUE; NRF_RNG->EVENTS_VALRDY=0; @@ -293,7 +320,7 @@ void gzp_random_numbers_generate(uint8_t * dst, uint8_t n) /** * @brief Function for setting the Primask variable. Only necessary if ARMCC -* compiler skips __set_PRIMASK at high optimization levels. +* compiler skips __set_PRIMASK at high optimization levels. * * @param primask The primask value. 1 to disable interrupts, 0 otherwise. */ @@ -315,7 +342,7 @@ void nrf_gzp_flush_rx_fifo(uint32_t pipe) uint32_t length; nrf_gzp_set_primask(1); - while(nrf_gzll_get_rx_fifo_packet_count(pipe) >0) + while (nrf_gzll_get_rx_fifo_packet_count(pipe) >0) { length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; (void)nrf_gzll_fetch_packet_from_rx_fifo(pipe,dummy_packet,&length); diff --git a/components/properitary_rf/gzll/nrf_gzp.h b/components/proprietary_rf/gzll/nrf_gzp.h similarity index 83% rename from components/properitary_rf/gzll/nrf_gzp.h rename to components/proprietary_rf/gzll/nrf_gzp.h index a771cda..def609d 100644 --- a/components/properitary_rf/gzll/nrf_gzp.h +++ b/components/proprietary_rf/gzll/nrf_gzp.h @@ -1,21 +1,48 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. -* -* The information contained herein is property of Nordic Semiconductor ASA. -* Terms and conditions of usage are described in detail in NORDIC -* 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. -* -* $LastChangedRevision: 25678 $ -*/ +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @brief Gazell Pairing API */ - + #ifndef __GZP_H #define __GZP_H @@ -23,6 +50,10 @@ #include "nrf_gzp_config.h" #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @defgroup gzp_02_api Application Programming Interface (API) @@ -68,7 +99,7 @@ #define GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_REQ_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Host ID request" payload length #if (GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH > 17) -#error GZP_SESSION_TOKEN_LENGTH too long. +#error GZP_SESSION_TOKEN_LENGTH too long. #endif @@ -76,9 +107,9 @@ #define GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_FETCH_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Host ID fetch" payload length #if (GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH > 17) -#error GZP_VALIDATION_ID_LENGTH set too long. +#error GZP_VALIDATION_ID_LENGTH set too long. #endif - + #define GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH 1 ///< "Key update prepare" payload length #define GZP_CMD_KEY_UPDATE_VALIDATION_ID 1 ///< "Key update" packet, validation ID position @@ -86,7 +117,7 @@ #define GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH (GZP_CMD_KEY_UPDATE_NEW_KEY + GZP_DYN_KEY_LENGTH) ///< "Key update" packet, payload length #if (GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH > 17) -#error Sum (GZP_VALIDATION_ID_LENGTH + GZP_DYN_KEY_LENGTH) too high. +#error Sum (GZP_VALIDATION_ID_LENGTH + GZP_DYN_KEY_LENGTH) too high. #endif @@ -95,7 +126,7 @@ #define GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD ( GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Encrypted user data" packet, packet overhead length #define GZP_ENCRYPTED_USER_DATA_MAX_LENGTH (17 - GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD) ///< "Encrypted user data" packet, max payload length -#if(GZP_MAX_FW_PAYLOAD_LENGTH < 17) +#if (GZP_MAX_FW_PAYLOAD_LENGTH < 17) #error GZP_MAX_FW_PAYLOAD_LENGTH must be greater or equal to 17. #endif @@ -113,7 +144,7 @@ #define GZP_CMD_HOST_ADDRESS_RESP_ADDRESS 1 ///< "Host address fetch" response packet, address position #define GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH (GZP_CMD_HOST_ADDRESS_RESP_ADDRESS + GZP_SYSTEM_ADDRESS_WIDTH) ///< ///< "Host address fetch" response packet, payload length -#if(GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH) +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH) #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH. #endif @@ -123,7 +154,7 @@ #define GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID (GZP_CMD_HOST_ID_FETCH_RESP_STATUS + 1) ///< "Host ID fetch" response packet, Host ID position #define GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID + GZP_HOST_ID_LENGTH) ///< "Host ID fetch" response packet, payload length -#if(GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH) +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH) #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH. #endif @@ -131,24 +162,24 @@ #define GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN 1 ///< "Key update prepare" response packet, session token position #define GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH (GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Key update prepare" response packet, payload length position -#if(GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH) +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH) #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH. #endif - + #define GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN 1 ///< "Encrypted user data" response packet, session token position #define GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID (GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Encrypted user data" response packet, validation ID position #define GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH (GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Encrypted user data" response packet, payload length position -#if(GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH) +#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH) #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH. #endif -#if(GZP_VALIDATION_ID_LENGTH > GZP_HOST_ID_LENGTH) +#if (GZP_VALIDATION_ID_LENGTH > GZP_HOST_ID_LENGTH) #error GZP_HOST_ID_LENGTH should be greater or equal to GZP_VALIDATION_ID_LENGTH. #endif -#if(GZP_SESSION_TOKEN_LENGTH != GZP_HOST_ID_LENGTH) +#if (GZP_SESSION_TOKEN_LENGTH != GZP_HOST_ID_LENGTH) #error GZP_SESSION_TOKEN_LENGTH must equal GZP_HOST_ID_LENGTH. #endif @@ -180,7 +211,7 @@ typedef enum /** * @enum gzp_cmd_t - * @brief Enumerator used in the first payload byte of each packet to + * @brief Enumerator used in the first payload byte of each packet to * indicate the packet type. */ typedef enum @@ -195,14 +226,14 @@ typedef enum GZP_CMD_FETCH_RESP, ///< Fetch response GZP_CMD_HOST_ADDRESS_RESP, ///< Host address response GZP_CMD_HOST_ID_FETCH_RESP, ///< Host ID fetch response - GZP_CMD_KEY_UPDATE_PREPARE_RESP, ///< Key update prepare + GZP_CMD_KEY_UPDATE_PREPARE_RESP, ///< Key update prepare GZP_CMD_ENCRYPTED_USER_DATA_RESP, ///< Encrypted user data response } gzp_cmd_t; /** * @enum gzp_id_req_res_t - * @brief Enumerator used to identify the state of the current + * @brief Enumerator used to identify the state of the current * Host ID request. */ typedef enum @@ -281,7 +312,7 @@ void gzp_crypt_select_key(gzp_key_select_t key_select); /** - * Encypt / decrypt data. + * Encypt / decrypt data. * * The current "session token" will be used as initialization vector (IV). * The AES key to be used is selected by gzp_crypt_select_key(). @@ -300,8 +331,8 @@ void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length); * * @param src_id Pointer to the source validation ID to compare to. * - * @retval true If *src_id equals the pre-defined ID. - * @retval false If *src_id does not equal the pre-defined ID. + * @retval true If *src_id equals the pre-defined ID. + * @retval false If *src_id does not equal the pre-defined ID. */ bool gzp_validate_id(const uint8_t *src_id); @@ -328,13 +359,13 @@ void gzp_random_numbers_generate(uint8_t *dst, uint8_t n); * Update the channel table and the system address. * * The channel table is updated to pseudo-random set generated using the - * system address. The channel table still includes GZP_CHANNEL_MAX and + * system address. The channel table still includes GZP_CHANNEL_MAX and * GZP_CHANNEL_MIN. * The system address is applied to base address 1 and therefore applies - * to pipes 1-7. + * to pipes 1-7. * * @param system_address Pointer to the system_address to set. - * + * * @retval true If theradio parameters were updated successfully. * @retval false If there was an error updated the radio parameters. */ @@ -344,9 +375,9 @@ bool gzp_update_radio_params(const uint8_t *system_address); /** * Generate a set of channels from a 4 byte address. * - * @param ch_dst Destination to write the channel set to. The channel set + * @param ch_dst Destination to write the channel set to. The channel set * includes GZP_CHANNEL_MAX and GZP_CHANNEL_MIN. - * @param address Four byte address to generate the channel set from. + * @param address Four byte address to generate the channel set from. * @param channel_set_size Size of the channel set to generate. */ void gzp_generate_channels(uint8_t *ch_dst, const uint8_t * address, uint8_t channel_set_size); @@ -357,23 +388,23 @@ void gzp_generate_channels(uint8_t *ch_dst, const uint8_t * address, uint8_t cha * * @param dst Destination to write the result to. Should be of size length. * @param src - * @param pad - * @param length Number of bytes to perform the XOR operation on. + * @param pad + * @param length Number of bytes to perform the XOR operation on. */ void gzp_xor_cipher(uint8_t* dst, const uint8_t* src, const uint8_t* pad, uint8_t length); /******************************************************************************/ -/** @name Common Device and Host functions +/** @name Common Device and Host functions * @{ */ /******************************************************************************/ /** * Initialization function. This function initializes the Gazell Pairing Library. - - * This function must be called before any of the other Gazell Pairing Library functions are - * used and must be called @b after gzll_init() is called. + + * This function must be called before any of the other Gazell Pairing Library functions are + * used and must be called @b after gzll_init() is called. * */ void gzp_init(void); @@ -391,7 +422,7 @@ void nrf_gzp_disable_gzll(void); /** Function for cancelling an ongoing (pending) "Host ID request". - After calling this function the "Host ID request" status will go to + After calling this function the "Host ID request" status will go to "ID request Idle". */ void gzp_id_req_cancel(void); @@ -424,7 +455,7 @@ bool nrf_gzp_tx_complete(void); bool nrf_gzp_tx_success(void); /** - * Reset tx_complete status. + * Reset tx_complete status. */ void nrf_gzp_reset_tx_complete(void); @@ -434,7 +465,7 @@ void nrf_gzp_reset_tx_complete(void); void nrf_gzp_reset_tx_success(void); /** -* Function to check whether a Device has existing pairing data, implying that it is +* Function to check whether a Device has existing pairing data, implying that it is * paired to a Host. * * @retval -2 The pairing database is empty. @@ -446,9 +477,9 @@ int8_t gzp_get_pairing_status(void); /** Function for sending a "system address" request to a Host. - When calling this function the Device will attempt acquiring the "system address" from + When calling this function the Device will attempt acquiring the "system address" from any Host within close proximity. - + If a host is located within close proximity and pairing is enabled in the Host, a "system address" will be sent in return to the Device. @@ -457,8 +488,8 @@ int8_t gzp_get_pairing_status(void); Note. Using OTP devices limits the number of times a new "system address" can be stored in NV memory. - - @return + + @return @retval true if new "system address" was received from a Host. @retval false if no "system address" was received from a Host. @@ -468,13 +499,13 @@ bool gzp_address_req_send(void); /** Function for sending a "Host ID request" to a Host. - The "Host ID" is needed to be able to send encrypted data using + The "Host ID" is needed to be able to send encrypted data using gzp_crypt_data_send(). The request will be sent using the "system address" previously received using gzp_address_req_send(). - It is not required that the Host is within close proximity in order to acquire the + It is not required that the Host is within close proximity in order to acquire the "Host ID". The new "Host ID" will apply immediately for the Device, and the new "Host ID" @@ -483,21 +514,21 @@ bool gzp_address_req_send(void); Note. Using OTP devices limits the number of times a new "Host ID" can be stored in NV memory. - @return - + @return + @retval GZP_ID_RESP_PENDING if a "Host ID request" has been sent to the Host, but the Host application has not yet decided whether to Grant or Reject the "ID request". - @retval GZP_ID_RESP_GRANTED if the "Host ID" has been received from the Host. The received "Host ID" will be stored - in non volatile memory. + @retval GZP_ID_RESP_GRANTED if the "Host ID" has been received from the Host. The received "Host ID" will be stored + in non volatile memory. @retval GZP_ID_RESP_REJECTED if the Host application has rejected the "Host ID request". - @retval GZP_ID_RESP_FAILED if failing to send a request or receive a response from the Host. + @retval GZP_ID_RESP_FAILED if failing to send a request or receive a response from the Host. */ gzp_id_req_res_t gzp_id_req_send(void); /** Function for sending encrypted user data to the Host. - Before any data can be sent the Device must acquire both the Host's + Before any data can be sent the Device must acquire both the Host's "system address" by using gzp_address_req_send() and the "Host ID" by using gzp_id_req_send(). @@ -520,14 +551,14 @@ bool gzp_crypt_data_send(const uint8_t *src, uint8_t length); Function for enabling/disabling pairing in a host. When pairing is enabled the host will be monitoring for "system address" and "Host ID" requests from Devices. - A "system address request" received from a Device will always be granted. - When a "host ID request" has been received, the Host application have to grant, + A "system address request" received from a Device will always be granted. + When a "host ID request" has been received, the Host application have to grant, reject or cancel this by using one of the following functions: - gzp_id_req_grant() - gzp_id_req_reject() - - gzp_id_req_cancel() - + - gzp_id_req_cancel() + @param enable @arg true enables pairing. @arg false disables pairing. @@ -536,62 +567,62 @@ void gzp_pairing_enable(bool enable); /** * Execute the Gazell Pairing Library Host operation. - * + * * This function must be called regularly by the Host application. */ void gzp_host_execute(void); /** * Address exchanged check. - * - * @retval true If a "system address" was delivered to a requesting Device during the - * previous call to gzp_host_execute(); + * + * @retval true If a "system address" was delivered to a requesting Device during the + * previous call to gzp_host_execute(); * @retval false Otherwise. */ bool gzp_address_exchanged(void); /** Function for checking if a "Host ID request" has been received from a Device. - + If a request has been received, the Pairing library will enter "ID request pending" state. - - The application is responsible for responding to this request by calling + + The application is responsible for responding to this request by calling one of the following functions: - + - gzp_id_req_grant() - gzp_id_req_reject() - - gzp_id_req_cancel() - - @retval true if a "Host ID request" has been received (internal state is "ID request pending") - @retval false if no "Host ID request" has been received (internal state is "ID request idle") + - gzp_id_req_cancel() + + @retval true if a "Host ID request" has been received (internal state is "ID request pending") + @retval false if no "Host ID request" has been received (internal state is "ID request idle") */ bool gzp_id_req_received(void); /** Function for rejecting the previously received "Host ID request". This function should be called - only when a "Host ID request" has been received (internal state is "ID request pending"). - + only when a "Host ID request" has been received (internal state is "ID request pending"). + The internal state of the Pairing library will remain "ID request pending" until the a "reject" message - has been successfully transmitted to the requesting Device. After this the internal state will - change to "ID request idle". + has been successfully transmitted to the requesting Device. After this the internal state will + change to "ID request idle". */ void gzp_id_req_reject(void); /** * Function for granting the previously received "Host ID request". This function should be called - only when a "Host ID request" has been received (internal state is "ID request pending"). - - The internal state of the Pairing library will remain "ID request pending" until the "Host ID" has - been successfully transmitted to the requesting Device. After this the internal state will - change to "ID request idle". + only when a "Host ID request" has been received (internal state is "ID request pending"). + + The internal state of the Pairing library will remain "ID request pending" until the "Host ID" has + been successfully transmitted to the requesting Device. After this the internal state will + change to "ID request idle". */ void gzp_id_req_grant(void); /** * Check if user data has been received. - * + * * @retval true If encrypted user data has been received. * @retval false Otherwise. */ @@ -607,7 +638,7 @@ bool gzp_crypt_user_data_received(void); @param length* is a pointer for returning the number of bytes received. Only 1 byte will be writtem to length*. - @return + @return @retval true if data has been received and is written to dst* @retval false if no data has been received. */ @@ -615,9 +646,9 @@ bool gzp_crypt_user_data_read(uint8_t* dst, uint8_t* length); /** - Function emulating behavior of gzll_rx_start() in legeacy nRF24xx Gaell + Function emulating behavior of gzll_rx_start() in legeacy nRF24xx Gaell linbrary. - + This functions sets Gazell in Host mode and starts reception (enable). */ void gzll_rx_start(void); @@ -627,4 +658,9 @@ void gzll_rx_start(void); /** @} */ /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/properitary_rf/gzll/nrf_gzp_device.c b/components/proprietary_rf/gzll/nrf_gzp_device.c similarity index 82% rename from components/properitary_rf/gzll/nrf_gzp_device.c rename to components/proprietary_rf/gzll/nrf_gzp_device.c index c42870e..21676f0 100644 --- a/components/properitary_rf/gzll/nrf_gzp_device.c +++ b/components/proprietary_rf/gzll/nrf_gzp_device.c @@ -1,18 +1,45 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic - * Semiconductor ASA.Terms and conditions of usage are described in detail - * in NORDIC 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. - * - * $LastChangedRevision: 29442 $ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @brief Implementation of Gazell Pairing Library (gzp), Device functions. * @defgroup gzp_source_device Gazell Pairing Device implementation. @@ -56,9 +83,9 @@ #define GZP_INDEX_DB_ADR (GZP_PARAMS_STORAGE_ADR + GZP_PARAMS_DB_SIZE) ///< #define GZP_INDEX_DB_SIZE (GZP_DEVICE_PARAMS_STORAGE_SIZE - GZP_PARAMS_DB_SIZE) ///< -#if(GZP_DEVICE_PARAMS_STORAGE_SIZE < GZP_PARAMS_DB_SIZE) +#if (GZP_DEVICE_PARAMS_STORAGE_SIZE < GZP_PARAMS_DB_SIZE) #error GZP_DEVICE_PARAMS_STORAGE_SIZE must be greater or equal to GZP_PAIRING_PARAMS_DB_SIZE -#elif(GZP_DEVICE_PARAMS_STORAGE_SIZE == GZP_PARAMS_DB_SIZE ) +#elif (GZP_DEVICE_PARAMS_STORAGE_SIZE == GZP_PARAMS_DB_SIZE ) #warning GZP_DEVICE_PARAMS_STORAGE_SIZE to low to be able store any pairing parameters NV memory #endif /** @} */ @@ -76,8 +103,8 @@ typedef enum { GZP_TX_RX_SUCCESS, ///< ACK received. Transaction successful. - GZP_TX_RX_FAILED_TO_SEND, ///< - GZP_TX_RX_NO_RESPONSE ///< + GZP_TX_RX_FAILED_TO_SEND, ///< + GZP_TX_RX_NO_RESPONSE ///< } gzp_tx_rx_trans_result_t; /** @} */ @@ -104,11 +131,11 @@ static bool gzp_id_req_pending = false; * Function for sending an encrypted packet. * * The function waits for the transmission to complete. - * + * * @param tx_packet Pointer to the packet to be sent. * @param length Length of the packet to be sent. * @param pipe Pipe on which the packet should be sent. - * + * * @retval true If the transmission succeeded. * @retval false If the transmission failed (timed out). */ @@ -117,7 +144,7 @@ static bool gzp_tx_packet(const uint8_t* tx_packet, uint8_t length, uint8_t pipe /** * Function sending the packet *tx_packet and a subsequent packet fetching the response * to *tx_packet. - * + * * @param tx_packet is a pointer to the packet to be sent. * @param tx_length is the length of the packet to be sent. * @param rx_dst is a pointer to where the received response packet should be stored. @@ -204,7 +231,7 @@ static bool gzp_index_db_empty(void); /** * Function returning @b true if array contains only 1s (0xff). - * + * * @param *src is a pointer to the array to be evaluated. * @param length is the length of the array to be evaluated. * @@ -249,7 +276,7 @@ void gzp_delay_rx_periods(uint32_t rx_periods); void gzp_tick_sleep_rx_periods(uint32_t rx_periods); /* - * Print debug string. By default does nothing. + * Print debug string. By default does nothing. * * If GZP_DEBUG is defined then the print string function is required to * be implemented. @@ -277,18 +304,18 @@ static bool tx_success; ///< Flag to indicate whether a GZLL TX attempt was suc #error #endif #else -static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] __attribute__((at(GZP_PARAMS_DB_ADR))) +static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE / 4] __attribute__((at(GZP_PARAMS_DB_ADR))) #endif = { -0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, -0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, -0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, @@ -322,7 +349,7 @@ void gzp_init() void gzp_erase_pairing_data(void) { - // Erase database flash page so that it can be later written to. + // Erase database flash page so that it can be later written to. nrf_nvmc_page_erase((uint32_t)database); } @@ -357,10 +384,10 @@ bool gzp_address_req_send() // Send a number of packets in order to broadcast that devices not within // close proximity must back off. - for(i = 0; i < GZP_MAX_BACKOFF_PACKETS; i++) + for (i = 0; i < GZP_MAX_BACKOFF_PACKETS; i++) { - success = gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, GZP_PAIRING_PIPE); - if(success) + success = gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, GZP_PAIRING_PIPE); + if (success) { nrf_gzp_flush_rx_fifo(GZP_PAIRING_PIPE); } @@ -375,15 +402,15 @@ bool gzp_address_req_send() address_req[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_FETCH; success = gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, GZP_PAIRING_PIPE); - if(success && latest_tx_info.payload_received_in_ack) + if (success && latest_tx_info.payload_received_in_ack) { // If pairing response received - if(nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE) > 0) + if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE) > 0) { rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; //dummy placeholder - if(nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, rx_payload, &rx_payload_length)) + if (nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, rx_payload, &rx_payload_length)) { - if(rx_payload[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_RESP) + if (rx_payload[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_RESP) { memcpy(gzp_system_address, &rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); gzll_update_ok &= gzp_update_radio_params(&rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS]); @@ -409,10 +436,10 @@ bool gzp_address_req_send() gzll_update_ok &= nrf_gzll_set_tx_power(temp_power); gzll_update_ok &= nrf_gzll_enable(); - if(!gzll_update_ok) + if (!gzll_update_ok) { /* - The update of the Gazell parameters failed. Use nrf_gzll_get_error_code() + The update of the Gazell parameters failed. Use nrf_gzll_get_error_code() to investigate the cause. */ } @@ -430,7 +457,7 @@ gzp_id_req_res_t gzp_id_req_send() gzp_tx_rx_trans_result_t trans_result; // If no ID request is pending, send new "ID request" - if(!gzp_id_req_pending) + if (!gzp_id_req_pending) { // Build "Host ID request packet" tx_packet[0] = (uint8_t)GZP_CMD_HOST_ID_REQ; @@ -439,7 +466,7 @@ gzp_id_req_res_t gzp_id_req_send() gzp_random_numbers_generate(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH); // Send "Host ID request" - if(gzp_tx_packet(tx_packet, GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH, GZP_DATA_PIPE)) + if (gzp_tx_packet(tx_packet, GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH, GZP_DATA_PIPE)) { // Update session token if "Host ID request" was successfully transmitted gzp_crypt_set_session_token(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]); @@ -460,15 +487,15 @@ gzp_id_req_res_t gzp_id_req_send() trans_result = gzp_tx_rx_transaction(tx_packet, GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE); // If packet was successfully sent AND a response packet was received - if(trans_result == GZP_TX_RX_SUCCESS) + if (trans_result == GZP_TX_RX_SUCCESS) { // Validate response packet - if(rx_packet[0] == (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP) + if (rx_packet[0] == (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP) { gzp_crypt(&rx_packet[1], &rx_packet[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1); - if(gzp_validate_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID])) + if (gzp_validate_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID])) { - switch(rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS]) + switch (rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS]) { case GZP_ID_RESP_PENDING: break; @@ -510,9 +537,9 @@ void gzp_id_req_cancel() bool gzp_crypt_data_send(const uint8_t *src, uint8_t length) { - if(length <= GZP_ENCRYPTED_USER_DATA_MAX_LENGTH) + if (length <= GZP_ENCRYPTED_USER_DATA_MAX_LENGTH) { - if(gzp_crypt_tx_transaction(src, length)) + if (gzp_crypt_tx_transaction(src, length)) { return true; } @@ -521,10 +548,10 @@ bool gzp_crypt_data_send(const uint8_t *src, uint8_t length) //print_string("GZP_CRYPT_TX failed\r\n"); // Attempt key update if user data transmission failed // during normal operation (!gzp_id_req_pending) - if(!gzp_id_req_pending) + if (!gzp_id_req_pending) { //print_string("KEY UPDATE\r\n"); - if(gzp_key_update()) + if (gzp_key_update()) { return gzp_crypt_tx_transaction(src, length); } @@ -551,9 +578,9 @@ static bool gzp_tx_packet(const uint8_t* tx_packet, uint8_t length, uint8_t pipe tx_complete = false; tx_success = false; - if(nrf_gzll_add_packet_to_tx_fifo(pipe,(uint8_t *)tx_packet, length)) + if (nrf_gzll_add_packet_to_tx_fifo(pipe,(uint8_t *)tx_packet, length)) { - while(tx_complete == false) + while (tx_complete == false) { __WFI(); } @@ -578,17 +605,17 @@ static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, nrf_gzp_flush_rx_fifo(pipe); retval = GZP_TX_RX_FAILED_TO_SEND; - + (void)nrf_gzll_disable(); - while(nrf_gzll_is_enabled()) + while (nrf_gzll_is_enabled()) {} temp_lifetime = nrf_gzll_get_sync_lifetime(); (void)nrf_gzll_set_sync_lifetime(GZP_TX_RX_TRANS_DELAY * 3); // 3 = RXPERIOD * 2 + margin (void)nrf_gzll_enable(); - + tx_packet_success = gzp_tx_packet(tx_packet, tx_length, pipe); - - if(tx_packet_success) + + if (tx_packet_success) { retval = GZP_TX_RX_NO_RESPONSE; @@ -597,12 +624,12 @@ static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, fetch_packet[0] = (uint8_t)GZP_CMD_FETCH_RESP; gzp_tick_sleep_rx_periods(GZP_TX_RX_TRANS_DELAY); - + tx_packet_success = gzp_tx_packet(fetch_packet, GZP_CMD_FETCH_RESP_PAYLOAD_LENGTH, pipe); - if(tx_packet_success) + if (tx_packet_success) { - if(nrf_gzll_get_rx_fifo_packet_count(pipe)) + if (nrf_gzll_get_rx_fifo_packet_count(pipe)) { local_rx_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; fetch_success = nrf_gzll_fetch_packet_from_rx_fifo(pipe, rx_dst, &local_rx_length); @@ -612,7 +639,7 @@ static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, fetch_success = false; } - if(fetch_success) + if (fetch_success) { retval = GZP_TX_RX_SUCCESS; } @@ -626,13 +653,13 @@ static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, //print_string("GZP_TX_FETCH_NO_ACK\r\n"); } } - + (void)nrf_gzll_disable(); - while(nrf_gzll_is_enabled()) + while (nrf_gzll_is_enabled()) {} (void)nrf_gzll_set_sync_lifetime(temp_lifetime); (void)nrf_gzll_enable(); - + return retval; } @@ -654,7 +681,7 @@ static bool gzp_crypt_tx_transaction(const uint8_t *src, uint8_t length) memcpy(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], (uint8_t*)src, length); // Encrypt tx packet - if(gzp_id_req_pending) + if (gzp_id_req_pending) { gzp_crypt_select_key(GZP_ID_EXCHANGE); } @@ -666,17 +693,17 @@ static bool gzp_crypt_tx_transaction(const uint8_t *src, uint8_t length) // If packet was successfully sent AND a response packet was received result = gzp_tx_rx_transaction(tx_packet, tx_packet_length, rx_packet, NULL, GZP_DATA_PIPE); - if(result == GZP_TX_RX_SUCCESS) + if (result == GZP_TX_RX_SUCCESS) { - if(rx_packet[0] == (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA_RESP) + if (rx_packet[0] == (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA_RESP) { gzp_crypt(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], &rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], GZP_VALIDATION_ID_LENGTH); // Validate response in order to know whether packet was correctly decrypted by host - if(gzp_validate_id(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID])) + if (gzp_validate_id(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID])) { // Update session token if normal operation (!gzp_id_req_pending) - if(!gzp_id_req_pending) + if (!gzp_id_req_pending) { gzp_crypt_set_session_token(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]); } @@ -709,9 +736,9 @@ static bool gzp_key_update(void) tx_packet[0] = (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE; // If packet was successfully sent AND a response packet was received - if(gzp_tx_rx_transaction(tx_packet, GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE) == GZP_TX_RX_SUCCESS) + if (gzp_tx_rx_transaction(tx_packet, GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE) == GZP_TX_RX_SUCCESS) { - if(rx_packet[0] == (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE_RESP) + if (rx_packet[0] == (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE_RESP) { gzp_crypt_set_session_token(&rx_packet[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]); @@ -726,7 +753,7 @@ static bool gzp_key_update(void) gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1); // Send "key update" packet - if(gzp_tx_packet(tx_packet, GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH, GZP_DATA_PIPE)) + if (gzp_tx_packet(tx_packet, GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH, GZP_DATA_PIPE)) { return true; } @@ -767,20 +794,20 @@ static void gzp_index_db_add(uint8_t val) uint32_t addr; // Search for unwritten loacation in index DB - for(i = 0; i < GZP_INDEX_DB_SIZE; i++) + for (i = 0; i < GZP_INDEX_DB_SIZE; i++) { temp_val = *(uint8_t*)(GZP_INDEX_DB_ADR + i); // Lower nibble - if(i != (GZP_INDEX_DB_SIZE - 1)) + if (i != (GZP_INDEX_DB_SIZE - 1)) { - if((temp_val & 0x0f) == 0x0f) + if ((temp_val & 0x0f) == 0x0f) { temp_val = (temp_val & 0xf0) | val; break; } // Upper nibble - else if((temp_val & 0xf0) == 0xf0) + else if ((temp_val & 0xf0) == 0xf0) { temp_val = (temp_val & 0x0f) | (val << 4); break; @@ -804,21 +831,21 @@ static uint8_t gzp_index_db_read() int16_t i; // Search for previously written location - for(i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--) + for (i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--) { retval = *(uint8_t*)(GZP_INDEX_DB_ADR + i); - if(retval != 0xff) + if (retval != 0xff) { break; } } - if(retval == 0xff) + if (retval == 0xff) { retval = GZP_PARAMS_DB_MAX_ENTRIES; // index db empty } - else if((retval & 0xf0) != 0xf0) + else if ((retval & 0xf0) != 0xf0) { retval >>= 4; } @@ -837,25 +864,25 @@ int8_t gzp_get_pairing_status(void) int16_t i; uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE]; uint8_t default_host_id[GZP_HOST_ID_LENGTH]; - + db_index = -2; - + // Populate default Host ID with F's. - for(i=0; i< GZP_HOST_ID_LENGTH; i++) + for (i=0; i< GZP_HOST_ID_LENGTH; i++) { default_host_id[i] = 0xFF; } - + // Search for previously written location - for(i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--) + for (i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--) { db_byte = *(uint8_t*)(GZP_INDEX_DB_ADR + i); - + // Check if idx has been written to - if(db_byte != 0xff) + if (db_byte != 0xff) { // Convert 4-bit nibble to index - if((db_byte & 0xf0) != 0xf0) + if ((db_byte & 0xf0) != 0xf0) { db_byte = (db_byte >> 4) & 0x0f; } @@ -863,14 +890,14 @@ int8_t gzp_get_pairing_status(void) { db_byte = db_byte & 0x0f; } - + // Retrieve database entry gzp_params_db_read(temp_element, db_byte); - + // Check if database entry is all F's - if( memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], default_host_id, GZP_HOST_ID_LENGTH) != 0) - { - + if ( memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], default_host_id, GZP_HOST_ID_LENGTH) != 0) + { + db_index = db_byte; } else @@ -903,15 +930,15 @@ static bool gzp_index_db_empty() return true; #endif } -//lint -restore +//lint -restore static bool gzp_array_is_set(const uint8_t* src, uint8_t length) { uint8_t i; - for(i = 0; i < length; i++) + for (i = 0; i < length; i++) { - if(*(src++) != 0xff) + if (*(src++) != 0xff) { return false; } @@ -928,14 +955,14 @@ static bool gzp_params_store(bool store_all) uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE]; // Search param DB to see if current setup exists - if(store_all) + if (store_all) { // Search for: Current system address and host ID exists - for(i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) { gzp_params_db_read(temp_element, i); - if(((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && ((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH)) == 0)) + if (((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && ((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH)) == 0)) { write_index_db = true; new_db_index = i; @@ -944,13 +971,13 @@ static bool gzp_params_store(bool store_all) } // Search for: Current system address and cleared host ID - if(!write_index_db) + if (!write_index_db) { - for(i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) { gzp_params_db_read(temp_element, i); - if(((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && \ + if (((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && \ (gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], GZP_HOST_ID_LENGTH))) { memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH); @@ -963,13 +990,13 @@ static bool gzp_params_store(bool store_all) } // Search for: Cleared system address and cleared host ID - if(!write_index_db) + if (!write_index_db) { - for(i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) { gzp_params_db_read(temp_element, i); - if(gzp_array_is_set(temp_element, GZP_PARAMS_DB_ELEMENT_SIZE)) + if (gzp_array_is_set(temp_element, GZP_PARAMS_DB_ELEMENT_SIZE)) { memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH); memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH); @@ -984,11 +1011,11 @@ static bool gzp_params_store(bool store_all) else { // Search for: System address + any host ID - for(i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) { gzp_params_db_read(temp_element, i); - if((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) + if ((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) { //memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH); write_index_db = true; @@ -998,13 +1025,13 @@ static bool gzp_params_store(bool store_all) } // Search for: System address cleared - if(!write_index_db) + if (!write_index_db) { - for(i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) + for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++) { gzp_params_db_read(temp_element, i); - if(gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH)) + if (gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH)) { memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH); write_index_db = true; @@ -1016,14 +1043,14 @@ static bool gzp_params_store(bool store_all) } } - if(write_param_db) + if (write_param_db) { gzp_params_db_add(temp_element, new_db_index); } - if(write_index_db) + if (write_index_db) { - if(!gzp_index_db_full() && (new_db_index != gzp_index_db_read()) && (new_db_index != GZP_PARAMS_DB_MAX_ENTRIES)) + if (!gzp_index_db_full() && (new_db_index != gzp_index_db_read()) && (new_db_index != GZP_PARAMS_DB_MAX_ENTRIES)) { gzp_index_db_add(new_db_index); return true; @@ -1038,11 +1065,11 @@ static bool gzp_params_restore(void) uint8_t i; uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE]; - if(!gzp_index_db_full() && !gzp_index_db_empty()) + if (!gzp_index_db_full() && !gzp_index_db_empty()) { i = gzp_index_db_read(); - if(i < GZP_PARAMS_DB_MAX_ENTRIES) + if (i < GZP_PARAMS_DB_MAX_ENTRIES) { gzp_params_db_read(temp_element, i); memcpy(gzp_system_address, &temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); @@ -1056,14 +1083,14 @@ static bool gzp_params_restore(void) void gzp_delay_rx_periods(uint32_t rx_periods) { - nrf_delay_us(rx_periods*2*nrf_gzll_get_timeslot_period()); + nrf_delay_us(rx_periods * 2 * nrf_gzll_get_timeslot_period()); } void gzp_tick_sleep_rx_periods(uint32_t rx_periods) { nrf_gzll_clear_tick_count(); - while(nrf_gzll_get_tick_count() < 2*rx_periods) + while (nrf_gzll_get_tick_count() < 2 * rx_periods) { __WFI(); } @@ -1087,12 +1114,12 @@ void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info) } bool nrf_gzp_tx_complete(void) -{ +{ return tx_complete; } bool nrf_gzp_tx_success(void) -{ +{ return tx_success; } diff --git a/components/properitary_rf/gzll/nrf_gzp_host.c b/components/proprietary_rf/gzll/nrf_gzp_host.c similarity index 79% rename from components/properitary_rf/gzll/nrf_gzp_host.c rename to components/proprietary_rf/gzll/nrf_gzp_host.c index 6171d43..abee102 100644 --- a/components/properitary_rf/gzll/nrf_gzp_host.c +++ b/components/proprietary_rf/gzll/nrf_gzp_host.c @@ -1,18 +1,45 @@ -/* Copyright (c) 2009 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic - * Semiconductor ASA.Terms and conditions of usage are described in detail - * in NORDIC SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. - * - * Licensees are granted free, non-transferable use of the information. NO - * WARRENTY of ANY KIND is provided. This heading must NOT be removed from - * the file. - * - * $LastChangedRevision: 230 $ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * @brief Implementation of Gazell Pairing Library (gzp), Host functions. * @defgroup gzp_source_host Gazell Pairing Host implementation @@ -20,12 +47,12 @@ * @ingroup gzp_04_source */ - + #include "nrf_gzp.h" #include "nrf_gzll.h" -#include "string.h" -#include "stdint.h" -#include "stdbool.h" +#include +#include +#include #include "nrf_assert.h" #include "nrf_ecb.h" #include "nrf_nvmc.h" @@ -74,7 +101,7 @@ static void gzp_get_session_counter(uint8_t* dst); /** * Function processing received "system address request" from Device. - * + * * @param gzp_req Pointer to RX payload containing system address request. */ static void gzp_process_address_req(uint8_t* gzp_req); @@ -112,7 +139,7 @@ static void gzp_process_key_update_prepare(void); /** * Function to process Key Update packet. * - * Device requests a Key Update and sends a new Dynamic Key. The Dynamic Key is + * Device requests a Key Update and sends a new Dynamic Key. The Dynamic Key is * updated on the Host. * * @param rx_payload Pointer to rx_payload containing Key Update request. @@ -142,11 +169,11 @@ static void gzp_preload_ack(uint8_t* src, uint8_t length, uint8_t pipe); /** * Function for reading the Chip ID from non-volatile memory. * - * The chip ID is used for the system address. - * + * The chip ID is used for the system address. + * * If the Chip ID is not yet created a random Chip ID is created and * written to non-volatile memory. Note that the term chip ID is used as - * the factory programmed chip sequence number was used for the system + * the factory programmed chip sequence number was used for the system * address in nRF24LU ICs. * * @param dst Address to copy Host ID to. @@ -164,20 +191,20 @@ void gzp_host_chip_id_read(uint8_t *dst, uint8_t n); static void gzp_set_host_id(const uint8_t* src); -/** +/** * Function to request disabling of Gazell and wait for it to be disabled. - * + * * Emulates legacy gzll_goto_idle(). - */ + */ static void gzll_goto_idle(void); /** * Flush all TX FIFOs. - * + * * Emulates legacy gzll_tx_fifo_flush(). */ -static void gzll_tx_fifo_flush(void); +static void gzll_tx_fifo_flush(void); /** @@ -185,7 +212,7 @@ static void gzll_tx_fifo_flush(void); * * Emulates legacy gzll_rx_fifo_flush(). */ -static void gzll_rx_fifo_flush(void); +static void gzll_rx_fifo_flush(void); /** @@ -193,9 +220,9 @@ static void gzll_rx_fifo_flush(void); * * Emulates legacy Gazell function: gzll_set_param(GZLL_PARAM_RX_TIMEOUT, x). * - * @param timeout Timeout in number of legacy "RX periods" + * @param timeout Timeout in number of legacy "RX periods" * (1 RX period = 2 timeslot periods). - */ + */ static void gzll_set_rx_timeout(uint32_t timeout); /** @} */ @@ -236,32 +263,32 @@ void gzp_init() (void)gzp_update_radio_params(system_address); // Only "data pipe" enabled by default - + (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_DATA_PIPE)); - + gzp_pairing_enabled_f = false; gzp_address_exchanged_f = false; gzp_id_req_stat = GZP_ID_REQ_IDLE; gzp_encrypted_user_data_length = 0; - + // Infinite RX timeout gzll_set_rx_timeout(0); } void gzp_pairing_enable(bool enable) { - if(gzp_pairing_enabled_f != enable) + if (gzp_pairing_enabled_f != enable) { gzll_goto_idle(); - - if(enable) + + if (enable) { (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_PAIRING_PIPE)); } else { (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() & ~(1 << GZP_PAIRING_PIPE)); - + gzp_id_req_stat = GZP_ID_REQ_IDLE; } @@ -279,23 +306,23 @@ void gzp_host_execute() gzp_address_exchanged_f = false; - if(nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE) > 0) - { + if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE) > 0) + { gzp_packet_received = nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, rx_payload, &payload_length); } - - if(!gzp_packet_received && (gzp_encrypted_user_data_length == 0)) + + if (!gzp_packet_received && (gzp_encrypted_user_data_length == 0)) { - if(nrf_gzll_get_rx_fifo_packet_count(GZP_DATA_PIPE) > 0) - { - gzp_packet_received = nrf_gzll_fetch_packet_from_rx_fifo(GZP_DATA_PIPE, rx_payload, &payload_length); + if (nrf_gzll_get_rx_fifo_packet_count(GZP_DATA_PIPE) > 0) + { + gzp_packet_received = nrf_gzll_fetch_packet_from_rx_fifo(GZP_DATA_PIPE, rx_payload, &payload_length); } } - - if(gzp_packet_received) + + if (gzp_packet_received) { //lint -save -esym(644,rx_payload) //may not have been initialized - switch(rx_payload[0]) + switch (rx_payload[0]) { case GZP_CMD_HOST_ADDRESS_REQ: gzp_process_address_req(rx_payload); @@ -328,15 +355,15 @@ void gzp_host_execute() } // Restart reception if "not proximity backoff" period has elapsed - if(!nrf_gzll_is_enabled()) + if (!nrf_gzll_is_enabled()) { gzll_set_rx_timeout(0); - - if(gzp_pairing_enabled_f) + + if (gzp_pairing_enabled_f) { (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_PAIRING_PIPE)); } - + gzll_rx_start(); } @@ -347,15 +374,15 @@ void gzp_host_execute() void gzll_rx_start(void) { - if(nrf_gzll_get_mode() != NRF_GZLL_MODE_HOST) + if (nrf_gzll_get_mode() != NRF_GZLL_MODE_HOST) { gzll_goto_idle(); - (void)nrf_gzll_set_mode(NRF_GZLL_MODE_HOST); + (void)nrf_gzll_set_mode(NRF_GZLL_MODE_HOST); } - - if(!nrf_gzll_is_enabled()) - { - (void)nrf_gzll_enable(); + + if (!nrf_gzll_is_enabled()) + { + (void)nrf_gzll_enable(); } } @@ -366,7 +393,7 @@ bool gzp_id_req_received() void gzp_id_req_reject() { - if(gzp_id_req_received()) + if (gzp_id_req_received()) { gzp_id_req_stat = GZP_ID_REQ_PENDING_AND_REJECTED; } @@ -374,7 +401,7 @@ void gzp_id_req_reject() void gzp_id_req_grant() { - if(gzp_id_req_received()) + if (gzp_id_req_received()) { gzp_id_req_stat = GZP_ID_REQ_PENDING_AND_GRANTED; } @@ -382,7 +409,7 @@ void gzp_id_req_grant() void gzp_id_req_cancel() { - if(gzp_id_req_received()) + if (gzp_id_req_received()) { gzp_id_req_stat = GZP_ID_REQ_IDLE; } @@ -402,29 +429,29 @@ static void gzp_process_address_req(uint8_t* gzp_req) gzll_goto_idle(); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); - + temp_rx_pipes = nrf_gzll_get_rx_pipes_enabled(); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); // If requesting Device within close proximity - if(prev_gzp_rx_info.rssi >= GZP_HOST_RX_POWER_THRESHOLD) + if (prev_gzp_rx_info.rssi >= GZP_HOST_RX_POWER_THRESHOLD) { (void)nrf_gzll_set_rx_pipes_enabled(0); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); - + gzll_set_rx_timeout(GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); - + gzll_rx_fifo_flush(); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); - + // Start "proximity" back off period gzll_rx_start(); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); - while(nrf_gzll_is_enabled()) + while (nrf_gzll_is_enabled()) {} - + // Build pairing response packet pairing_resp[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_RESP; gzp_host_chip_id_read(&pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH); @@ -432,42 +459,42 @@ static void gzp_process_address_req(uint8_t* gzp_req) (void)nrf_gzll_add_packet_to_tx_fifo(0, &pairing_resp[0], GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); gzll_set_rx_timeout(GZP_STEP1_RX_TIMEOUT); - + // Enable only pairing pipe when waiting for pairing request step 1 (void)nrf_gzll_set_rx_pipes_enabled((1 << GZP_PAIRING_PIPE)); - - gzll_rx_start(); - - while(nrf_gzll_is_enabled()) + + gzll_rx_start(); + + while (nrf_gzll_is_enabled()) { - if(nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE)) + if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE)) { (void)nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, &gzp_req[0], &rx_payload_length); - + // Validate step 1 of pairing request - if(gzp_req[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_FETCH) + if (gzp_req[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_FETCH) { gzp_address_exchanged_f = true; } } } - + gzll_tx_fifo_flush(); gzll_rx_fifo_flush(); - + gzll_set_rx_timeout(0); - + (void)nrf_gzll_set_rx_pipes_enabled(temp_rx_pipes); - + // Return to normal operation gzll_rx_start(); } else { (void)nrf_gzll_set_rx_pipes_enabled(temp_rx_pipes & ~(1 << GZP_PAIRING_PIPE)); - + gzll_set_rx_timeout(GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT); - + // Start "not proximity" backoff period gzll_rx_start(); } @@ -476,16 +503,16 @@ static void gzp_process_address_req(uint8_t* gzp_req) static void gzp_preload_ack(uint8_t* src, uint8_t length, uint8_t pipe) { gzll_goto_idle(); - + gzll_tx_fifo_flush(); - + (void)nrf_gzll_add_packet_to_tx_fifo(pipe, src, length); - + gzll_rx_start(); } static void gzll_set_rx_timeout(uint32_t timeout) -{ +{ timeout *= 2; // * 2 as gzll_set_rx_timeout() takes RX_PERIODS as input, which equals 2 timeslots. nrf_gzll_set_auto_disable(timeout); } @@ -504,11 +531,11 @@ bool gzp_crypt_user_data_received() bool gzp_crypt_user_data_read(uint8_t* dst, uint8_t* length) { - if(gzp_encrypted_user_data_length > 0) + if (gzp_encrypted_user_data_length > 0) { memcpy(dst, (void*)gzp_encrypted_user_data, gzp_encrypted_user_data_length); - if(length != NULL) + if (length != NULL) { *length = gzp_encrypted_user_data_length; } @@ -526,10 +553,10 @@ static void gzp_session_counter_inc() { uint8_t i; - for(i = 0; i < GZP_SESSION_TOKEN_LENGTH; i++) + for (i = 0; i < GZP_SESSION_TOKEN_LENGTH; i++) { gzp_session_counter[i]++; - if(gzp_session_counter[i] != 0) + if (gzp_session_counter[i] != 0) { break; } @@ -543,11 +570,11 @@ static void gzp_get_session_counter(uint8_t* dst) static void gzp_set_host_id(const uint8_t* src) { - if(*((uint8_t*)GZP_PARAMS_STORAGE_ADR) == 0xff) + if (*((uint8_t*)GZP_PARAMS_STORAGE_ADR) == 0xff) { nrf_nvmc_write_bytes(GZP_PARAMS_STORAGE_ADR + 1, src, GZP_HOST_ID_LENGTH); nrf_nvmc_write_byte(GZP_PARAMS_STORAGE_ADR, 0x00); - } + } } void gzp_get_host_id(uint8_t *dst) @@ -560,39 +587,34 @@ static void gzp_process_id_req(uint8_t* rx_payload) int i; uint8_t temp_host_id[GZP_HOST_ID_LENGTH]; - if(gzp_pairing_enabled_f) + if (gzp_pairing_enabled_f) { - if(!gzp_id_req_received()) + if (!gzp_id_req_received()) { gzp_crypt_set_session_token(&rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]); gzp_id_req_stat = GZP_ID_REQ_PENDING; } gzp_get_host_id(temp_host_id); - + // Added: - for(i = 0; i < GZP_HOST_ID_LENGTH; i++) + for (i = 0; i < GZP_HOST_ID_LENGTH; i++) { - if(temp_host_id[i] != 0xFF) + if (temp_host_id[i] != 0xFF) { - break; + break; } } - - if(i == GZP_HOST_ID_LENGTH) // If host not generated yet + + if (i == GZP_HOST_ID_LENGTH) // If host not generated yet { gzp_get_session_counter(temp_host_id); - - //lint -save -e506 Constantvalue Boolean - if(GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH) - { - //lint -restore - gzp_xor_cipher(temp_host_id, temp_host_id, &rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH); - } - else - { - gzp_xor_cipher(temp_host_id, temp_host_id, &rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_HOST_ID_LENGTH); - } + +#if (GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH) + gzp_xor_cipher(temp_host_id, temp_host_id, &rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH); +#else //(GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH) + gzp_xor_cipher(temp_host_id, temp_host_id, &rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_HOST_ID_LENGTH); +#endif //(GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH) gzp_set_host_id(temp_host_id); } @@ -603,13 +625,13 @@ static void gzp_process_id_fetch(uint8_t* rx_payload) { uint8_t tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH]; - if(gzp_id_req_received()) + if (gzp_id_req_received()) { gzp_crypt_select_key(GZP_ID_EXCHANGE); gzp_crypt(&rx_payload[1], &rx_payload[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1); - if(gzp_validate_id(&rx_payload[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID])) + if (gzp_validate_id(&rx_payload[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID])) { - switch(gzp_id_req_stat) + switch (gzp_id_req_stat) { case GZP_ID_REQ_PENDING_AND_GRANTED: tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_GRANTED; @@ -629,7 +651,7 @@ static void gzp_process_id_fetch(uint8_t* rx_payload) tx_payload[0] = (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP; gzp_add_validation_id(&tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID]); gzp_crypt(&tx_payload[1], &tx_payload[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1); - + ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); gzp_preload_ack(tx_payload, GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE); ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR); @@ -646,7 +668,7 @@ static void gzp_process_key_update_prepare() gzp_get_session_counter(&tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]); // Update session token if no ID request is pending - if(!gzp_id_req_received()) + if (!gzp_id_req_received()) { gzp_crypt_set_session_token(&tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]); } @@ -659,7 +681,7 @@ static void gzp_process_key_update(uint8_t* rx_payload) { gzp_crypt_select_key(GZP_KEY_EXCHANGE); gzp_crypt(&rx_payload[1], &rx_payload[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1); - if(gzp_validate_id(&rx_payload[GZP_CMD_KEY_UPDATE_VALIDATION_ID])) + if (gzp_validate_id(&rx_payload[GZP_CMD_KEY_UPDATE_VALIDATION_ID])) { gzp_crypt_set_dyn_key(&rx_payload[GZP_CMD_KEY_UPDATE_NEW_KEY]); } @@ -669,7 +691,7 @@ static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length) { uint8_t tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH]; - if(gzp_id_req_received()) + if (gzp_id_req_received()) { gzp_crypt_select_key(GZP_ID_EXCHANGE); } @@ -679,7 +701,7 @@ static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length) } gzp_crypt(&rx_payload[1], &rx_payload[1], length - 1); - if(gzp_validate_id(&rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID])) + if (gzp_validate_id(&rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID])) { gzp_encrypted_user_data_length = length - GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD; memcpy((void*)gzp_encrypted_user_data, &rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], gzp_encrypted_user_data_length); @@ -692,7 +714,7 @@ static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length) gzp_get_session_counter(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]); // Update "session token" only if no ID request is pending - if(!gzp_id_req_received()) + if (!gzp_id_req_received()) { gzp_crypt_set_session_token(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]); } @@ -709,28 +731,28 @@ static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length) static void gzll_goto_idle() { nrf_gzll_disable(); - while(nrf_gzll_is_enabled()) + while (nrf_gzll_is_enabled()) {} } static void gzll_tx_fifo_flush(void) { int i; - - for(i = 0; i < NRF_GZLL_CONST_PIPE_COUNT; i++) + + for (i = 0; i < NRF_GZLL_CONST_PIPE_COUNT; i++) { (void)nrf_gzll_flush_tx_fifo(i); - } + } } static void gzll_rx_fifo_flush(void) { int i; - - for(i = 0; i < NRF_GZLL_CONST_PIPE_COUNT; i++) + + for (i = 0; i < NRF_GZLL_CONST_PIPE_COUNT; i++) { (void)nrf_gzll_flush_rx_fifo(i); - } + } } @@ -755,7 +777,7 @@ void nrf_gzll_disabled(void) void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info) { - if(pipe == GZP_PAIRING_PIPE) + if (pipe == GZP_PAIRING_PIPE) { prev_gzp_rx_info = rx_info; } diff --git a/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c b/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c new file mode 100644 index 0000000..2c17777 --- /dev/null +++ b/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2009 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + + +#include "nrf_gzp.h" +#include "nrf_nvmc.h" + +/** + * @file + * @brief Implementation of Gazell Pairing Library (gzp), nRF5x specific Host functions. + * @defgroup gzp_source_host_nrf5x Gazell Pairing Host nRF5x specific implementation + * @{ + * @ingroup gzp_04_source + */ + + +void gzp_host_chip_id_read(uint8_t *dst, uint8_t n) +{ + uint8_t i; + uint8_t random_number; + + if ( *((uint8_t*)(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1)) == 0xff) + { + nrf_nvmc_write_byte((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1) , 0x00); + + for (i = 0; i < n; i++) + { + gzp_random_numbers_generate(&random_number, 1); + nrf_nvmc_write_byte((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i) , random_number); + } + } + + for (i = 0; i < n; i++) + { + *(dst++) = *((uint8_t*)(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i)); + } +} + +/** @} */ diff --git a/components/sdk_validation.h b/components/sdk_validation.h new file mode 100644 index 0000000..9385097 --- /dev/null +++ b/components/sdk_validation.h @@ -0,0 +1,306 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SDK_VALIDATION_H +#define SDK_VALIDATION_H + +#include "nrf_peripherals.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// Validate peripheral availibility + +#if ((defined(SAADC_ENABLED)) && (SAADC_ENABLED > 0) && (!defined(SAADC_PRESENT))) +#error "SAADC not present in selected MCU." +#endif + +#if ((defined(ADC_ENABLED)) && (ADC_ENABLED > 0) && (!defined(ADC_PRESENT))) +#error "SAADC not present in selected MCU." +#endif + +#if ((defined(I2S_ENABLED)) && (I2S_ENABLED > 0) && (!defined(I2S_PRESENT))) +#error "I2S not present in selected MCU." +#endif + +#if ((defined(COMP_ENABLED)) && (COMP_ENABLED > 0) && (!defined(COMP_PRESENT))) +#error "COMP not present in selected MCU." +#endif + +#if ((defined(LPCOMP_ENABLED)) && (LPCOMP_ENABLED > 0) && (!defined(LPCOMP_PRESENT))) +#error "LPCOMP not present in selected MCU." +#endif + +#if ((defined(SPIS0_ENABLED)) && (SPIS0_ENABLED > 0) && (!defined(SPIS_PRESENT))) +#error "SPIS0 instance not present in selected MCU." +#endif + +#if ((defined(EGU_ENABLED)) && (EGU_ENABLED > 0) && (!defined(EGU_PRESENT))) +#error "EGU instance not present in selected MCU." +#endif + +#if ((defined(NFC_HAL_ENABLED)) && (NFC_HAL_ENABLED > 0) && (!defined(NFCT_PRESENT))) +#error "NFC TAG not present in selected MCU." +#endif + +// Validate count of instances + +#if ((defined(RTC2_ENABLED)) && (RTC2_ENABLED > 0) && (RTC_COUNT < 2)) +#error "RTC2 not present in selected MCU." +#endif + +#if ((defined(TWIS0_ENABLED) || defined(TWIS1_ENABLED)) &&\ + ((TWIS0_ENABLED + TWIS1_ENABLED) > 0) &&\ + (!defined(TWIS_PRESENT))) +#error "TWIS not present in selected MCU." +#endif + +#if ((defined(SPIS2_ENABLED)) && (SPIS2_ENABLED > 0) && (SPIS_COUNT < 2)) +#error "SPI2/SPIS2 instance not present in selected MCU." +#endif + +#if ((defined(TIMER3_ENABLED) || defined(TIMER4_ENABLED)) &&\ + ((TIMER3_ENABLED + TIMER4_ENABLED ) > 0) &&\ + (TIMER_COUNT < 5)) +#error "TIMER3 and TIMER4 not present in selected MCU." +#endif + +// Validate peripheral sharing feature +#if ((defined(PERIPHERAL_RESOURCE_SHARING_ENABLED)) && (!PERIPHERAL_RESOURCE_SHARING_ENABLED)) + +#if ((defined(TWIM0_ENABLED) && defined(TWIS0_ENABLED)) &&\ + ((TWIM0_ENABLED + TWIS0_ENABLED) > 1)) +#error "Peripherals overlap. TWIM0, TWIS0 - only one of these can be enabled." +#endif + +#if ((defined(TWIM0_ENABLED) && defined(SPIM0_ENABLED)) &&\ + ((TWIM0_ENABLED + SPIM0_ENABLED) > 1)) +#error "Peripherals overlap. TWIM0, SPIM0 - only one of these can be enabled." +#endif + +#if ((defined(TWIM0_ENABLED) && defined(SPIS0_ENABLED)) &&\ + ((TWIM0_ENABLED + SPIS0_ENABLED) > 1)) +#error "Peripherals overlap. TWIM0, SPIS0 - only one of these can be enabled." +#endif + +#if ((defined(TWIM0_ENABLED) && defined(SPI0_ENABLED)) &&\ + ((TWIM0_ENABLED + SPI0_ENABLED) > 1)) +#error "Peripherals overlap. TWIM0, SPI0 - only one of these can be enabled." +#endif + +#if ((defined(TWIM0_ENABLED) && defined(TWI0_ENABLED)) &&\ + ((TWIM0_ENABLED + TWI0_ENABLED) > 1)) +#error "Peripherals overlap. TWIM0, TWI0 - only one of these can be enabled." +#endif + +#if ((defined(TWIS0_ENABLED) && defined(SPIM0_ENABLED)) &&\ + ((TWIS0_ENABLED + SPIM0_ENABLED) > 1)) +#error "Peripherals overlap. TWIS0, SPIM0 - only one of these can be enabled." +#endif + +#if ((defined(TWIS0_ENABLED) && defined(SPIS0_ENABLED)) &&\ + ((TWIS0_ENABLED + SPIS0_ENABLED) > 1)) +#error "Peripherals overlap. TWIS0, SPIS0 - only one of these can be enabled." +#endif + +#if ((defined(TWIS0_ENABLED) && defined(SPI0_ENABLED)) &&\ + ((TWIS0_ENABLED + SPI0_ENABLED) > 1)) +#error "Peripherals overlap. TWIS0, SPI0 - only one of these can be enabled." +#endif + +#if ((defined(TWIS0_ENABLED) && defined(TWI0_ENABLED)) &&\ + ((TWIS0_ENABLED + TWI0_ENABLED) > 1)) +#error "Peripherals overlap. TWIS0, TWI0 - only one of these can be enabled." +#endif + +#if ((defined(SPIM0_ENABLED) && defined(SPIS0_ENABLED)) &&\ + ((SPIM0_ENABLED + SPIS0_ENABLED) > 1)) +#error "Peripherals overlap. SPIM0, SPIS0 - only one of these can be enabled." +#endif + +#if ((defined(SPIM0_ENABLED) && defined(SPI0_ENABLED)) &&\ + ((SPIM0_ENABLED + SPI0_ENABLED) > 1)) +#error "Peripherals overlap. SPIM0, SPI0 - only one of these can be enabled." +#endif + +#if ((defined(SPIM0_ENABLED) && defined(TWI0_ENABLED)) &&\ + ((SPIM0_ENABLED + TWI0_ENABLED) > 1)) +#error "Peripherals overlap. SPIM0, TWI0 - only one of these can be enabled." +#endif + +#if ((defined(SPIS0_ENABLED) && defined(SPI0_ENABLED)) &&\ + ((SPIS0_ENABLED + SPI0_ENABLED) > 1)) +#error "Peripherals overlap. SPIS0, SPI0 - only one of these can be enabled." +#endif + +#if ((defined(SPIS0_ENABLED) && defined(TWI0_ENABLED)) &&\ + ((SPIS0_ENABLED + TWI0_ENABLED) > 1)) +#error "Peripherals overlap. SPIS0, TWI0 - only one of these can be enabled." +#endif + +#if ((defined(SPI0_ENABLED) && defined(TWI0_ENABLED)) &&\ + ((SPI0_ENABLED + TWI0_ENABLED) > 1)) +#error "Peripherals overlap. SPI0, TWI0 - only one of these can be enabled." +#endif + +#if ((defined(TWIM1_ENABLED) && defined(TWIS1_ENABLED)) &&\ + ((TWIM1_ENABLED + TWIS1_ENABLED) > 1)) +#error "Peripherals overlap. TWIM1, TWIS1 - only one of these can be enabled." +#endif + +#if ((defined(TWIM1_ENABLED) && defined(SPIM1_ENABLED)) &&\ + ((TWIM1_ENABLED + SPIM1_ENABLED) > 1)) +#error "Peripherals overlap. TWIM1, SPIM1 - only one of these can be enabled." +#endif + +#if ((defined(TWIM1_ENABLED) && defined(SPIS1_ENABLED)) &&\ + ((TWIM1_ENABLED + SPIS1_ENABLED) > 1)) +#error "Peripherals overlap. TWIM1, SPIS1 - only one of these can be enabled." +#endif + +#if ((defined(TWIM1_ENABLED) && defined(SPI1_ENABLED)) &&\ + ((TWIM1_ENABLED + SPI1_ENABLED) > 1)) +#error "Peripherals overlap. TWIM1, SPI1 - only one of these can be enabled." +#endif + +#if ((defined(TWIM1_ENABLED) && defined(TWI1_ENABLED)) &&\ + ((TWIM1_ENABLED + TWI1_ENABLED) > 1)) +#error "Peripherals overlap. TWIM1, TWI1 - only one of these can be enabled." +#endif + +#if ((defined(TWIS1_ENABLED) && defined(SPIM1_ENABLED)) &&\ + ((TWIS1_ENABLED + SPIM1_ENABLED) > 1)) +#error "Peripherals overlap. TWIS1, SPIM1 - only one of these can be enabled." +#endif + +#if ((defined(TWIS1_ENABLED) && defined(SPIS1_ENABLED)) &&\ + ((TWIS1_ENABLED + SPIS1_ENABLED) > 1)) +#error "Peripherals overlap. TWIS1, SPIS1 - only one of these can be enabled." +#endif + +#if ((defined(TWIS1_ENABLED) && defined(SPI1_ENABLED)) &&\ + ((TWIS1_ENABLED + SPI1_ENABLED) > 1)) +#error "Peripherals overlap. TWIS1, SPI1 - only one of these can be enabled." +#endif + +#if ((defined(TWIS1_ENABLED) && defined(TWI1_ENABLED)) &&\ + ((TWIS1_ENABLED + TWI1_ENABLED) > 1)) +#error "Peripherals overlap. TWIS1, TWI1 - only one of these can be enabled." +#endif + +#if ((defined(SPIM1_ENABLED) && defined(SPIS1_ENABLED)) &&\ + ((SPIM1_ENABLED + SPIS1_ENABLED) > 1)) +#error "Peripherals overlap. SPIM1, SPIS1 - only one of these can be enabled." +#endif + +#if ((defined(SPIM1_ENABLED) && defined(SPI1_ENABLED)) &&\ + ((SPIM1_ENABLED + SPI1_ENABLED) > 1)) +#error "Peripherals overlap. SPIM1, SPI1 - only one of these can be enabled." +#endif + +#if ((defined(SPIM1_ENABLED) && defined(TWI1_ENABLED)) &&\ + ((SPIM1_ENABLED + TWI1_ENABLED) > 1)) +#error "Peripherals overlap. SPIM1, TWI1 - only one of these can be enabled." +#endif + +#if ((defined(SPIS1_ENABLED) && defined(SPI1_ENABLED)) &&\ + ((SPIS1_ENABLED + SPI1_ENABLED) > 1)) +#error "Peripherals overlap. SPIS1, SPI1 - only one of these can be enabled." +#endif + +#if ((defined(SPIS1_ENABLED) && defined(TWI1_ENABLED)) &&\ + ((SPIS1_ENABLED + TWI1_ENABLED) > 1)) +#error "Peripherals overlap. SPIS1, TWI1 - only one of these can be enabled." +#endif + +#if ((defined(SPI1_ENABLED) && defined(TWI1_ENABLED)) &&\ + ((SPI1_ENABLED + TWI1_ENABLED) > 1)) +#error "Peripherals overlap. SPI1, TWI1 - only one of these can be enabled." +#endif + +#if ((defined(SPI2_ENABLED) && defined(SPIS2_ENABLED)) &&\ + ((SPI2_ENABLED + SPIS2_ENABLED) > 1)) +#error "Peripherals overlap. SPI2, SPIS2 - only one of these can be enabled." +#endif + +#if ((defined(SPIM2_ENABLED) && defined(SPIS2_ENABLED)) &&\ + ((SPI2_ENABLED + SPIS2_ENABLED) > 1)) +#error "Peripherals overlap. SPIM2, SPIS2 - only one of these can be enabled." +#endif + +#if ((defined(SPIM2_ENABLED) && defined(SPI2_ENABLED)) &&\ + ((SPI2_ENABLED + SPIS2_ENABLED) > 1)) +#error "Peripherals overlap. SPIM2, SPI2 - only one of these can be enabled." +#endif + +#endif + +#ifdef NFCT_PRESENT + +#if ((defined(NFC_HAL_ENABLED) && defined(CLOCK_ENABLED)) &&\ + ((NFC_HAL_ENABLED) && (!CLOCK_ENABLED))) +#error "NFC_HAL requires CLOCK to work. NFC_HAL can not be enabled without CLOCK." +#endif + +#if ((defined(NFC_HAL_ENABLED) && defined(TIMER4_ENABLED)) &&\ + ((NFC_HAL_ENABLED + TIMER4_ENABLED) > 1)) +#error "TIMER4 is used by NFC_HAL. NFC_HAL, TIMER4 - only one of these can be enabled." +#endif + +#endif +// Complex driver validation +#ifdef LPCOMP_PRESENT + +#if ((defined(COMP_ENABLED) && defined(LPCOMP_ENABLED)) &&\ + (!PERIPHERAL_RESOURCE_SHARING_ENABLED) && \ + ((COMP_ENABLED + LPCOMP_ENABLED) > 1)) +#error "Peripherals overlap. SPIM2, SPI2 - only one of these can be enabled." +#endif + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // SDK_VALIDATION_H diff --git a/components/serialization/application/codecs/common/ble_dtm_app.c b/components/serialization/application/codecs/common/ble_dtm_app.c index e58198a..9b50efb 100644 --- a/components/serialization/application/codecs/common/ble_dtm_app.c +++ b/components/serialization/application/codecs/common/ble_dtm_app.c @@ -1,15 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - + #include #include "app_error.h" #include "ble_dtm_app.h" @@ -37,10 +65,10 @@ uint32_t ble_dtm_init(app_uart_stream_comm_params_t * p_uart_comm_params) { return NRF_ERROR_NULL; } - + uint32_t err_code = NRF_SUCCESS; uint32_t index = 0; - + uint8_t * p_tx_buf = NULL; uint32_t tx_buf_len = 0; diff --git a/components/serialization/application/codecs/common/ble_dtm_app.h b/components/serialization/application/codecs/common/ble_dtm_app.h index b3c0423..f2903a1 100644 --- a/components/serialization/application/codecs/common/ble_dtm_app.h +++ b/components/serialization/application/codecs/common/ble_dtm_app.h @@ -1,21 +1,50 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_DTM_APP_H__ #define BLE_DTM_APP_H__ /** * @addtogroup ser_codecs Serialization codecs * @ingroup ble_sdk_lib_serialization + * @brief @tagAPI52832 Application and Connectivity codecs. */ /** @@ -34,15 +63,19 @@ #include "dtm_uart_params.h" -/**@brief Encodes @ref ble_dtm_init command request. +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Encodes the @ref ble_dtm_init command request. * - * @sa @ref nrf51_dtm_init_encoding_sec for packet format, + * @sa @ref encoding_data for packet format, * @ref ble_dtm_init_rsp_dec for command response decoder. * - * @param[in] p_uart_comm_params Pointer to UART configuration parameters. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] p_uart_comm_params Pointer to the UART configuration parameters. + * @param[in] p_buf Pointer to the buffer where encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * \c out: Length of the encoded command packet. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -53,25 +86,25 @@ uint32_t ble_dtm_init_req_enc(app_uart_stream_comm_params_t const * const p_uart uint32_t * const p_buf_len); -/**@brief Decodes response @ref ble_dtm_init command. +/**@brief Decodes the response @ref ble_dtm_init command. * - * @sa @ref nrf51_dtm_init_encoding_sec for packet format, + * @sa @ref encoding_data for packet format, * @ref ble_dtm_init_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. * @param[out] p_result_code Command result code. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. */ -uint32_t ble_dtm_init_rsp_dec(uint8_t const * const p_buf, +uint32_t ble_dtm_init_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, uint32_t * const p_result_code); -/**@brief Function to initializing DTM mode. +/**@brief Function to initializing the DTM mode. * * @param[in] p_uart_comm_params Pointer to the DTM UART configuration parameters. * @@ -81,4 +114,9 @@ uint32_t ble_dtm_init_rsp_dec(uint8_t const * const p_buf, uint32_t ble_dtm_init(app_uart_stream_comm_params_t * p_uart_comm_params); /** @} */ + +#ifdef __cplusplus +} +#endif + #endif // BLE_DTM_APP_H__ diff --git a/components/serialization/application/codecs/common/ble_dtm_init.c b/components/serialization/application/codecs/common/ble_dtm_init.c index 9d6f4e6..7922125 100644 --- a/components/serialization/application/codecs/common/ble_dtm_init.c +++ b/components/serialization/application/codecs/common/ble_dtm_init.c @@ -1,15 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - + #include "ble_dtm_app.h" #include "ble_serialization.h" #include "nrf_error.h" diff --git a/components/serialization/application/codecs/common/conn_systemreset.c b/components/serialization/application/codecs/common/conn_systemreset.c index 509e3f1..c3387cb 100644 --- a/components/serialization/application/codecs/common/conn_systemreset.c +++ b/components/serialization/application/codecs/common/conn_systemreset.c @@ -1,15 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - + #include #include "ble_serialization.h" #include "ser_hal_transport.h" diff --git a/components/serialization/application/codecs/common/conn_systemreset.h b/components/serialization/application/codecs/common/conn_systemreset.h index f573418..c39ed79 100644 --- a/components/serialization/application/codecs/common/conn_systemreset.h +++ b/components/serialization/application/codecs/common/conn_systemreset.h @@ -1,18 +1,50 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 CONN_SYSTEMRESET_H__ #define CONN_SYSTEMRESET_H__ +#ifdef __cplusplus +extern "C" { +#endif + /** * @addtogroup ser_codecs Serialization codecs * @ingroup ble_sdk_lib_serialization @@ -25,7 +57,7 @@ /**@file * - * @defgroup conn_systemreset Connectivity chip reset command request encoder. + * @defgroup conn_systemreset Connectivity chip reset command request encoder * @{ * @ingroup ser_app_common_codecs * @@ -40,4 +72,9 @@ uint32_t conn_systemreset(void); /** @} */ + +#ifdef __cplusplus +} +#endif + #endif // CONN_SYSTEMRESET_H__ diff --git a/components/serialization/application/codecs/s110/middleware/app_mw_ble.c b/components/serialization/application/codecs/s110/middleware/app_mw_ble.c deleted file mode 100644 index 51c73c3..0000000 --- a/components/serialization/application/codecs/s110/middleware/app_mw_ble.c +++ /dev/null @@ -1,501 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include -#include "ble_app.h" -#include "ser_sd_transport.h" -#include "app_error.h" -#include "app_ble_user_mem.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -/**@brief Structure containing @ref sd_ble_uuid_encode output parameters. */ -typedef struct -{ - uint8_t * p_uuid_le_len; /**< @ref sd_ble_uuid_encode appearance p_uuid_le_len output parameter. */ - uint8_t * p_uuid_le; /**< @ref sd_ble_uuid_encode appearance p_uuid_le output parameter. */ -} ble_uuid_encode_out_params_t; - -/**@brief Structure containing @ref sd_ble_tx_buffer_count_get output parameters. */ -typedef struct -{ - uint8_t * p_count; /**< @ref sd_ble_tx_buffer_count_get p_count output parameter. */ -} ble_tx_buffer_count__get_out_params_t; - -/**@brief Structure containing @ref sd_ble_user_mem_reply output parameters. */ -typedef struct -{ - uint16_t conn_handle; /**< @ref sd_ble_user_mem_reply conn_handle. */ - uint8_t context_allocated; /**< @ref sd_ble_user_mem_reply user memory context allocated flag. */ -} ble_user_mem_reply_out_params_t; - -/**@brief Union containing BLE command output parameters. */ -typedef union -{ - ble_uuid_encode_out_params_t ble_uuid_encode_out_params; /**< @ref sd_ble_uuid_encode output parameters. */ - ble_tx_buffer_count__get_out_params_t ble_tx_buffer_count_get_out_params; /**< @ref sd_ble_uuid_encode output parameters. */ - ble_user_mem_reply_out_params_t ble_user_mem_reply_out_params; /**< @ref sd_ble_user_mem_reply output parameters. */ -} ble_command_output_params_t; - -static ble_command_output_params_t m_output_params; /**< BLE command output parameters. */ - -static void * mp_out_params[3]; -static uint32_t m_uint32_param; - -static void tx_buf_alloc(uint8_t * * p_data, uint32_t * p_len) -{ - uint32_t err_code; - uint16_t len16; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, &len16); - } - while (err_code != NRF_SUCCESS); - - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len = (uint32_t)len16 - 1; -} - -/**@brief Command response callback function for @ref sd_ble_uuid_encode BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t uuid_encode_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_uuid_encode_rsp_dec(p_buffer, - length, - m_output_params.ble_uuid_encode_out_params.p_uuid_le_len, - m_output_params.ble_uuid_encode_out_params.p_uuid_le, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - return result_code; -} - - -uint32_t sd_ble_uuid_encode(ble_uuid_t const * const p_uuid, - uint8_t * const p_uuid_le_len, - uint8_t * const p_uuid_le) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - - m_output_params.ble_uuid_encode_out_params.p_uuid_le_len = p_uuid_le_len; - m_output_params.ble_uuid_encode_out_params.p_uuid_le = p_uuid_le; - - uint32_t err_code = ble_uuid_encode_req_enc(p_uuid, - p_uuid_le_len, - p_uuid_le, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - uuid_encode_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_tx_buffer_count_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t tx_buffer_count_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_tx_buffer_count_get_rsp_dec(p_buffer, - length, - (uint8_t * *)&mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_tx_buffer_count_get(uint8_t * p_count) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_count; - - const uint32_t err_code = ble_tx_buffer_count_get_req_enc(p_count, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - tx_buffer_count_get_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_uuid_vs_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t uuid_vs_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_uuid_vs_add_rsp_dec(p_buffer, - length, - (uint8_t * *)&mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_uuid_vs_add(ble_uuid128_t const * const p_vs_uuid, uint8_t * const p_uuid_type) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_uuid_type; - - const uint32_t err_code = ble_uuid_vs_add_req_enc(p_vs_uuid, p_uuid_type, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - uuid_vs_add_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_uuid_decode BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t uuid_decode_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_uuid_decode_rsp_dec(p_buffer, - length, - (ble_uuid_t * *)&mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_uuid_decode(uint8_t uuid_le_len, - uint8_t const * const p_uuid_le, - ble_uuid_t * const p_uuid) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_uuid; - - const uint32_t err_code = ble_uuid_decode_req_enc(uuid_le_len, p_uuid_le, p_uuid, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - uuid_decode_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_version_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t version_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_version_get_rsp_dec(p_buffer, - length, - (ble_version_t *)mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_version_get(ble_version_t * p_version) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_version; - - const uint32_t err_code = ble_version_get_req_enc(p_version, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - version_get_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_opt_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t opt_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - uint32_t uint32_param; - - uint32_t err_code = ble_opt_get_rsp_dec(p_buffer, - length, - &uint32_param, - (ble_opt_t *)mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - if (m_uint32_param != uint32_param) // decoded id should be the same as encoded one - { - err_code = NRF_ERROR_INVALID_PARAM; - } - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_opt; - m_uint32_param = opt_id; - - const uint32_t err_code = ble_opt_get_req_enc(opt_id, - p_opt, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - opt_get_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_opt_set BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t opt_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_opt_set_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - - const uint32_t err_code = ble_opt_set_req_enc(opt_id, - p_opt, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - opt_set_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_enable BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t enable_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_enable_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_enable(ble_enable_params_t * p_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_params; - - const uint32_t err_code = ble_enable_req_enc(p_params, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - enable_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_user_mem_reply BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t user_mem_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - uint32_t err_code = ble_user_mem_reply_rsp_dec(p_buffer, - length, - &result_code); - APP_ERROR_CHECK(err_code); - - if ((result_code != NRF_SUCCESS) && - (m_output_params.ble_user_mem_reply_out_params.context_allocated)) - { - err_code = app_ble_user_mem_context_destroy( - m_output_params.ble_user_mem_reply_out_params.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - return result_code; -} - -uint32_t sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block) -{ - uint8_t * p_buffer; - uint32_t buffer_length, user_mem_table_index; - uint32_t err_code = NRF_SUCCESS; - - tx_buf_alloc(&p_buffer, &buffer_length); - - // Prepare User Memory Block context for later synchronization when SoftDevice updates - // the data in the memory block - if(p_block != NULL) - { - err_code = app_ble_user_mem_context_create(conn_handle, &user_mem_table_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - m_app_user_mem_table[user_mem_table_index].mem_block.len = p_block->len; - m_app_user_mem_table[user_mem_table_index].mem_block.p_mem = p_block->p_mem; - // Save connection handle and context allocation flag for case if context destroy was needed - m_output_params.ble_user_mem_reply_out_params.conn_handle = conn_handle; - m_output_params.ble_user_mem_reply_out_params.context_allocated = 1; - } - else - { - m_output_params.ble_user_mem_reply_out_params.context_allocated = 0; - } - - err_code = ble_user_mem_reply_req_enc(conn_handle, - p_block, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - user_mem_reply_rsp_dec); -} diff --git a/components/serialization/application/codecs/s110/middleware/app_mw_ble_gap.c b/components/serialization/application/codecs/s110/middleware/app_mw_ble_gap.c deleted file mode 100644 index 9fc4660..0000000 --- a/components/serialization/application/codecs/s110/middleware/app_mw_ble_gap.c +++ /dev/null @@ -1,1286 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap.h" -#include -#include -#include "ble_serialization.h" -#include "ser_sd_transport.h" -#include "ser_config.h" -#include "ble_gap_app.h" -#include "app_error.h" -#include "app_ble_gap_sec_keys.h" - -extern ser_ble_gap_app_keyset_t m_app_keys_table[SER_MAX_CONNECTIONS]; -/**@brief Structure containing @ref sd_ble_gap_device_name_get output parameters. */ -typedef struct -{ - uint8_t * p_dev_name; /**< @ref sd_ble_gap_device_name_get p_dev_name output parameter. */ - uint16_t * p_len; /**< @ref sd_ble_gap_device_name_get p_len output parameter. */ -} gap_device_name_get_output_params_t; - -/**@brief Structure containing @ref sd_ble_gap_appearance_get output parameters. */ -typedef struct -{ - uint16_t * p_appearance; /**< @ref sd_ble_gap_appearance_get p_appearance output parameter. */ -} gap_appearance_get_output_params_t; - -/**@brief Structure containing @ref sd_ble_gap_ppcp_get output parameters. */ -typedef struct -{ - ble_gap_conn_params_t * p_conn_params; /**< @ref sd_ble_gap_ppcp_get p_conn_params output parameter. */ -} gap_ppcp_get_out_params_t; - -/**@brief Structure containing @ref sd_ble_gap_sec_params_reply output parameters. */ -typedef struct -{ - ble_gap_sec_keyset_t const * p_sec_keyset; /**< @ref sd_ble_gap_sec_params_reply p_sec_keyset output parameter. */ - uint16_t conn_handle; /**< @ref sd_ble_gap_sec_params_reply p_conn_handle output parameter. */ -} gap_sec_params_reply_out_params_t; - -/**@brief Union containing BLE command output parameters. */ -typedef union -{ - gap_device_name_get_output_params_t gap_device_name_get_out_params; /**< @ref sd_ble_gap_device_name_get output parameters. */ - gap_appearance_get_output_params_t gap_appearance_get_out_params; /**< @ref sd_ble_gap_appearance_get output parameters. */ - gap_ppcp_get_out_params_t gap_ppcp_get_out_params; /**< @ref sd_ble_gap_ppcp_get output parameters. */ - gap_sec_params_reply_out_params_t gap_sec_params_reply_out_params;/**< @ref sd_ble_sec_params_reply output parameters. */ -} gap_command_output_params_t; - -static gap_command_output_params_t m_output_params; /**< BLE command output parameters. */ - -static void * mp_out_params[1]; - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} -/**@brief Command response callback function for @ref sd_ble_gap_adv_start BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_adv_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_adv_start_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_adv_start(ble_gap_adv_params_t const * const p_adv_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gap_adv_start_req_enc(p_adv_params, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_adv_start_rsp_dec); -} - - -/**@brief Command response callback function for @ref ble_gap_device_name_get_req_enc BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_device_name_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_gap_device_name_get_rsp_dec(p_buffer, - length, - m_output_params.gap_device_name_get_out_params.p_dev_name, - m_output_params.gap_device_name_get_out_params.p_len, - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_device_name_get(uint8_t * const p_dev_name, uint16_t * const p_len) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - m_output_params.gap_device_name_get_out_params.p_dev_name = p_dev_name; - m_output_params.gap_device_name_get_out_params.p_len = p_len; - - const uint32_t err_code = ble_gap_device_name_get_req_enc(p_dev_name, - p_len, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_device_name_get_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_appearance_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_appearance_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_gap_appearance_get_rsp_dec(p_buffer, - length, - m_output_params.gap_appearance_get_out_params.p_appearance, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_appearance_get(uint16_t * const p_appearance) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - m_output_params.gap_appearance_get_out_params.p_appearance = p_appearance; - - const uint32_t err_code = ble_gap_appearance_get_req_enc(p_appearance, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_appearance_get_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_device_name_set BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_device_name_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_device_name_set_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const * const p_write_perm, - uint8_t const * const p_dev_name, - uint16_t len) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_device_name_set_req_enc(p_write_perm, - p_dev_name, - len, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_device_name_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_appearance_set BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_appearance_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_appearance_set_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_appearance_set(uint16_t appearance) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_appearance_set_req_enc(appearance, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_appearance_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_ppcp_set BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_ppcp_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_ppcp_set_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - return result_code; -} - - -uint32_t sd_ble_gap_ppcp_set(ble_gap_conn_params_t const * const p_conn_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_ppcp_set_req_enc(p_conn_params, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_ppcp_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_adv_data_set BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_adv_data_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_adv_data_set_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_adv_data_set(uint8_t const * const p_data, - uint8_t dlen, - uint8_t const * const p_sr_data, - uint8_t srdlen) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_adv_data_set_req_enc(p_data, - dlen, - p_sr_data, - srdlen, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_adv_data_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_conn_param_update BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_conn_param_update_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_conn_param_update_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_conn_param_update(uint16_t conn_handle, - ble_gap_conn_params_t const * const p_conn_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_conn_param_update_req_enc(conn_handle, - p_conn_params, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_conn_param_update_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_disconnect BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_disconnect_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_disconnect_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_disconnect_req_enc(conn_handle, - hci_status_code, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_disconnect_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_sec_info_reply BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_sec_info_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_sec_info_reply_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_gap_sec_info_reply(uint16_t conn_handle, - ble_gap_enc_info_t const * p_enc_info, - ble_gap_irk_t const * p_id_info, - ble_gap_sign_info_t const * p_sign_info) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_sec_info_reply_req_enc(conn_handle, - p_enc_info, - p_id_info, - p_sign_info, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_sec_info_reply_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_sec_params_reply BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_sec_params_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - uint32_t err_code = ble_gap_sec_params_reply_rsp_dec(p_buffer, length, - m_output_params.gap_sec_params_reply_out_params.p_sec_keyset, &result_code); - APP_ERROR_CHECK(err_code); - - // If soft device returned error free security context - if (result_code) - { - err_code = app_ble_gap_sec_context_destroy(m_output_params.gap_sec_params_reply_out_params.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - return result_code; -} - - -uint32_t sd_ble_gap_sec_params_reply(uint16_t conn_handle, - uint8_t sec_status, - ble_gap_sec_params_t const * p_sec_params, - ble_gap_sec_keyset_t const * p_sec_keyset) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - uint32_t sec_tab_index = 0; - uint32_t err_code = NRF_SUCCESS; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - m_output_params.gap_sec_params_reply_out_params.p_sec_keyset = p_sec_keyset; - m_output_params.gap_sec_params_reply_out_params.conn_handle = conn_handle; - - // First allocate security context for serialization - if (p_sec_keyset) - { - err_code = app_ble_gap_sec_context_create(conn_handle, &sec_tab_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - memcpy(&(m_app_keys_table[sec_tab_index].keyset), p_sec_keyset, sizeof(ble_gap_sec_keyset_t)); - } - - err_code = ble_gap_sec_params_reply_req_enc(conn_handle, - sec_status, - p_sec_params, - p_sec_keyset, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_sec_params_reply_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_ppcp_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_ppcp_get_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_ppcp_get_rsp_dec( - p_buffer, - length, - m_output_params.gap_ppcp_get_out_params. - p_conn_params, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_ppcp_get(ble_gap_conn_params_t * const p_conn_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - m_output_params.gap_ppcp_get_out_params.p_conn_params = p_conn_params; - - const uint32_t err_code = ble_gap_ppcp_get_req_enc(p_conn_params, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_ppcp_get_reply_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_address_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_address_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_address_get_rsp_dec(p_buffer, - length, - (ble_gap_addr_t *)mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_address_get(ble_gap_addr_t * const p_addr) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_addr; - - const uint32_t err_code = ble_gap_address_get_req_enc(p_addr, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - - gap_address_get_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_address_set BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_address_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_address_set_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_address_set(uint8_t addr_cycle_mode, ble_gap_addr_t const * const p_addr) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_address_set_req_enc(addr_cycle_mode, - p_addr, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_address_set_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_adv_stop BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_adv_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_adv_stop_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_adv_stop(void) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_adv_stop_req_enc(&(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_adv_stop_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_auth_key_reply BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_auth_key_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_auth_key_reply_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_auth_key_reply(uint16_t conn_handle, - uint8_t key_type, - uint8_t const * const key) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_auth_key_reply_req_enc(conn_handle, key_type, key, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_auth_key_reply_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_authenticate BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_authenticate_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_authenticate_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_authenticate(uint16_t conn_handle, - ble_gap_sec_params_t const * const p_sec_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_authenticate_req_enc(conn_handle, p_sec_params, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_authenticate_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_conn_sec_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_conn_sec_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_conn_sec_get_rsp_dec( - p_buffer, - length, - (ble_gap_conn_sec_t * *)&mp_out_params[0 - ], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t * const p_conn_sec) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_conn_sec; - - const uint32_t err_code = ble_gap_conn_sec_get_req_enc(conn_handle, p_conn_sec, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_conn_sec_get_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_rssi_start BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_rssi_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_rssi_start_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_rssi_start_req_enc(conn_handle, - threshold_dbm, - skip_count, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_rssi_start_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_rssi_stop BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_rssi_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_rssi_stop_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_rssi_stop(uint16_t conn_handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_rssi_stop_req_enc(conn_handle, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_rssi_stop_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_tx_power_set BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_tx_power_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_tx_power_set_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_tx_power_set(int8_t tx_power) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_tx_power_set_req_enc(tx_power, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_tx_power_set_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_connect BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_connect_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_connect_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_connect(ble_gap_addr_t const * const p_addr, - ble_gap_scan_params_t const * const p_scan_params, - ble_gap_conn_params_t const * const p_conn_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_connect_req_enc(p_addr, - p_scan_params, - p_conn_params, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_connect_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_connect_cancel BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_connect_cancel_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_connect_cancel_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_connect_cancel(void) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_connect_cancel_req_enc(&(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_connect_cancel_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_encrypt BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_encrypt_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_encrypt_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_encrypt( uint16_t conn_handle, - ble_gap_master_id_t const * p_master_id, - ble_gap_enc_info_t const * p_enc_info) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_encrypt_req_enc( conn_handle, p_master_id, p_enc_info, &(p_buffer[1]), &buffer_length ); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_encrypt_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_rssi_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_rssi_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_rssi_get_rsp_dec(p_buffer, - length, - (int8_t *) mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_rssi_get(uint16_t conn_handle, - int8_t * p_rssi) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_rssi; - - const uint32_t err_code = ble_gap_rssi_get_req_enc(conn_handle, p_rssi, &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_rssi_get_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_scan_start BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_scan_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_scan_start_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_scan_start(ble_gap_scan_params_t const * const p_scan_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_scan_start_req_enc(p_scan_params, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_scan_start_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_scan_stop BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_scan_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_scan_stop_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_scan_stop(void) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_scan_stop_req_enc(&(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_scan_stop_rsp_dec); -} - diff --git a/components/serialization/application/codecs/s110/middleware/app_mw_ble_gattc.c b/components/serialization/application/codecs/s110/middleware/app_mw_ble_gattc.c deleted file mode 100644 index 26cfab9..0000000 --- a/components/serialization/application/codecs/s110/middleware/app_mw_ble_gattc.c +++ /dev/null @@ -1,426 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_gattc.h" -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "ser_sd_transport.h" -#include "app_error.h" - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} -/**@brief Command response callback function for @ref sd_ble_gattc_primary_services_discover BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_primary_services_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_primary_services_discover_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_primary_services_discover(uint16_t conn_handle, - uint16_t start_handle, - ble_uuid_t const * const p_srvc_uuid) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_primary_services_discover_req_enc(conn_handle, - start_handle, - p_srvc_uuid, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_primary_services_discover_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_relationships_discover BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_relationships_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_relationships_discover_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_relationships_discover(uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_relationships_discover_req_enc(conn_handle, - p_handle_range, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_relationships_discover_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_characteristics_discover BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_characteristics_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_characteristics_discover_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_characteristics_discover( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const - p_handle_range) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_characteristics_discover_req_enc(conn_handle, - p_handle_range, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_characteristics_discover_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_descriptors_discover BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_descriptors_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_descriptors_discover_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_descriptors_discover(uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_descriptors_discover_req_enc(conn_handle, - p_handle_range, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_descriptors_discover_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_char_value_by_uuid_read BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_char_value_by_uuid_read_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_char_value_by_uuid_read_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, - ble_uuid_t const * const p_uuid, - ble_gattc_handle_range_t const * const p_handle_range) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_char_value_by_uuid_read_req_enc(conn_handle, - p_uuid, - p_handle_range, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_char_value_by_uuid_read_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_read BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_read_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_read_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_read(uint16_t conn_handle, - uint16_t handle, - uint16_t offset) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_read_req_enc(conn_handle, - handle, - offset, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_read_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_char_values_read BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_char_values_read_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_char_values_read_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_char_values_read(uint16_t conn_handle, - uint16_t const * const p_handles, - uint16_t handle_count) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_char_values_read_req_enc(conn_handle, - p_handles, - handle_count, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_char_values_read_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_write BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_write_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_write_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_write(uint16_t conn_handle, - ble_gattc_write_params_t const * const p_write_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_write_req_enc(conn_handle, - p_write_params, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_write_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_hv_confirm BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_hv_confirm_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_hv_confirm_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_hv_confirm(uint16_t conn_handle, - uint16_t handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_hv_confirm_req_enc(conn_handle, - handle, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_hv_confirm_rsp_dec); -} diff --git a/components/serialization/application/codecs/s110/middleware/app_mw_ble_l2cap.c b/components/serialization/application/codecs/s110/middleware/app_mw_ble_l2cap.c deleted file mode 100644 index 436d5a2..0000000 --- a/components/serialization/application/codecs/s110/middleware/app_mw_ble_l2cap.c +++ /dev/null @@ -1,165 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap.h" -#include -#include "ble_serialization.h" -#include "ser_sd_transport.h" -#include "ble_l2cap_app.h" -#include "app_error.h" - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} -/**@brief Command response callback function for @ref ble_l2cap_cid_register_req_enc BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t l2cap_cid_register_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_l2cap_cid_register_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_l2cap_cid_register(uint16_t cid) -{ - - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_l2cap_cid_register_req_enc(cid, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - l2cap_cid_register_rsp_dec); -} - -/**@brief Command response callback function for @ref ble_l2cap_cid_unregister_req_enc BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t l2cap_cid_unregister_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_l2cap_cid_unregister_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_l2cap_cid_unregister(uint16_t cid) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_l2cap_cid_unregister_req_enc(cid, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - l2cap_cid_unregister_rsp_dec); -} - -/**@brief Command response callback function for @ref ble_l2cap_tx_req_enc BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t l2cap_tx_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_l2cap_tx_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_l2cap_tx(uint16_t conn_handle, - ble_l2cap_header_t const * const p_header, - uint8_t const * const p_data) -{ - - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_l2cap_tx_req_enc(conn_handle, p_header, p_data, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - l2cap_tx_rsp_dec); -} - diff --git a/components/serialization/application/codecs/s110/middleware/app_mw_nrf_soc.c b/components/serialization/application/codecs/s110/middleware/app_mw_nrf_soc.c deleted file mode 100644 index 6a636c8..0000000 --- a/components/serialization/application/codecs/s110/middleware/app_mw_nrf_soc.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "nrf_soc.h" -#include -#include -#include "ser_sd_transport.h" -#include "nrf_soc_app.h" -#include "nrf_error_soc.h" -#include "app_error.h" -#include "ble_serialization.h" - -#include "ser_app_power_system_off.h" - -static void * mp_out_param; - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} - - -uint32_t sd_power_system_off(void) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = power_system_off_req_enc(&(p_buffer[1]), &buffer_length); - APP_ERROR_CHECK(err_code); - - ser_app_power_system_off_set(); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - NULL); -} - - -/**@brief Command response callback function for @ref sd_temp_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ - -static uint32_t mw_temp_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = temp_get_rsp_dec(p_buffer, - length, - &result_code, - (int32_t *)mp_out_param); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_temp_get(int32_t * p_temp) -{ - mp_out_param = p_temp; - - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = temp_get_req_enc(p_temp, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - mw_temp_get_rsp_dec); -} diff --git a/components/serialization/application/codecs/s110/serializers/app_ble_gap_sec_keys.c b/components/serialization/application/codecs/s110/serializers/app_ble_gap_sec_keys.c deleted file mode 100644 index 59bbdae..0000000 --- a/components/serialization/application/codecs/s110/serializers/app_ble_gap_sec_keys.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_ble_gap_sec_keys.h" -#include "ser_config.h" -#include "nrf_error.h" -#include - -ser_ble_gap_app_keyset_t m_app_keys_table[SER_MAX_CONNECTIONS]; - -uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -/**@brief GAP connection - keyset mapping structure. - * - * @note This structure is used to map keysets to connection instances, and will be stored in a static table. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that keys for this connection are used by soft device. 0: keys used; 1: keys not used*/ - ble_gap_sec_keyset_t keyset; /**< Keyset structure, see @ref ble_gap_sec_keyset_t.*/ -} ser_ble_gap_app_keyset_t; - -/**@brief allocates instance in m_app_keys_table[] for storage of encryption keys. - * - * @param[in] conn_handle conn_handle - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS Context allocated. - * @retval NRF_ERROR_NO_MEM No free instance available. - */ -uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_gap_sec_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_app_keys_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_APP_BLE_GAP_SEC_KEYS_H diff --git a/components/serialization/application/codecs/s110/serializers/app_ble_user_mem.c b/components/serialization/application/codecs/s110/serializers/app_ble_user_mem.c deleted file mode 100644 index c476020..0000000 --- a/components/serialization/application/codecs/s110/serializers/app_ble_user_mem.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_ble_user_mem.h" -#include "ser_config.h" -#include "nrf_error.h" -#include - -ser_ble_user_mem_t m_app_user_mem_table[SER_MAX_CONNECTIONS]; - -uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -/**@brief Connection - user memory mapping structure. - * - * @note This structure is used to map user memory to connection instances, and will be stored in a static table. - */ -//lint -esym(452,ser_ble_user_mem_t) -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that user memory for this connection is used by soft device. 0: memory used; 1: memory not used*/ - ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t.*/ -} ser_ble_user_mem_t; - -/**@brief allocates instance in m_user_mem_table[] for storage. - * - * @param[in] conn_handle conn_handle - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS Context allocated. - * @retval NRF_ERROR_NO_MEM No free instance available. - */ -uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_user_mem_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_user_mem_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_APP_BLE_USER_MEM_H diff --git a/components/serialization/application/codecs/s110/serializers/ble_app.h b/components/serialization/application/codecs/s110/serializers/ble_app.h deleted file mode 100644 index c9852b0..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_app.h +++ /dev/null @@ -1,445 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_APP_H__ -#define BLE_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_app Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief Application command request encoders and command response decoders. - */ -#include "ble.h" -/** - * @brief Encodes @ref sd_ble_tx_buffer_count_get command request. - * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format, - * @ref ble_tx_buffer_count_get_rsp_dec for command response decoder. - * - * @param[in] p_count Pointer to count value to be filled. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_count will not be updated by the command - * request encoder. Updated values are set by @ref ble_tx_buffer_count_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_tx_buffer_count_get_req_enc(uint8_t const * const p_count, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_tx_buffer_count_get command. - * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format, - * @ref ble_tx_buffer_count_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_count Pointer to pointer to count value. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_tx_buffer_count_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * const pp_count, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_uuid_encode command request. - * - * @sa @ref nrf51_uuid_encode_encoding for packet format, - * @ref ble_uuid_encode_rsp_dec for command response decoder. - * - * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. - * @param[in] p_uuid_le_len Size of \p p_uuid_le if \p p_uuid_le is not NULL - * @param[in] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes(2 or 16) - * will be stored. Can be NULL to calculate required size. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_uuid_le_len and \p p_uuid_le will not be updated by the command - * request encoder. Updated values are set by @ref ble_uuid_encode_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, - uint8_t const * const p_uuid_le_len, - uint8_t const * const p_uuid_le, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_uuid_encode command. - * - * @sa @ref nrf51_uuid_encode_encoding for packet format, - * @ref ble_uuid_encode_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in,out] p_uuid_le_len \c in: Size (in bytes) of \p p_uuid_le buffer. - * \c out: Length of decoded contents of \p p_uuid_le. - * @param[out] p_uuid_le Pointer to a buffer where the encoded UUID will be stored. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Length of \p p_uuid_le is too small to hold decoded - * value from response. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_uuid_le_len, - uint8_t * const p_uuid_le, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_uuid_decode command request. - * - * @sa @ref nrf51_uuid_decode_encoding for packet format, - * @ref ble_uuid_decode_rsp_dec for command response decoder. - * - * @param[in] uuid_le_len Size of \p p_uuid_le if \p p_uuid_le is not NULL - * @param[in] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes(2 or 16) - * is stored. - * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure were raw UUID will be decoded. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_uuid will not be updated by the command request encoder. - * Updated values are set by @ref ble_uuid_decode_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len, - uint8_t const * const p_uuid_le, - ble_uuid_t * const p_uuid, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_uuid_decode command. - * - * @sa @ref nrf51_uuid_decode_encoding for packet format, - * @ref ble_uuid_decode_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_uuid Pointer to a buffer where the decoded UUID will be stored. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_uuid_t * * const p_uuid, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_uuid_vs_add command request. - * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format, - * @ref ble_uuid_vs_add_rsp_dec for command response decoder. - * - * @param[in] p_vs_uuid Pointer to a @ref ble_uuid128_t structure. - * @param[in] p_uuid_type Pointer to uint8_t where UUID type will be returned. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_uuid_type will not be updated by the command request encoder. - * Updated values are set by @ref ble_uuid_vs_add_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid, - uint8_t * const p_uuid_type, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_uuid_vs_add command. - * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format, - * @ref ble_uuid_vs_add_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] pp_uuid_type Pointer to a pointer to uint8_t where the decoded UUID type will be stored. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * * const pp_uuid_type, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_version_get command request. - * - * @sa @ref nrf51_version_get_encoding for packet format, - * @ref ble_version_get_rsp_dec for command response decoder. - * - * @param[in] p_version Pointer to a @ref ble_version_t structure to be filled by the response. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_version_get_req_enc(ble_version_t const * const p_version, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_version_get command. - * - * @sa @ref nrf51_version_get_encoding for packet format, - * @ref ble_version_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_version Pointer to a @ref ble_version_t where decoded version will be stored. - * @param[out] p_result_code Command result code. - * - * @return NRF_SUCCESS Version information stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_version_t * p_version, - uint32_t * const p_result_code); - - -/**@brief Encodes @ref sd_ble_opt_set command request. - * - * @sa @ref nrf51_opt_set_encoding for packet format, - * @ref ble_opt_set_rsp_dec for command response decoder. - * - * @param[in] opt_id Identifies type of parameter in ble_opt_t union. - * @param[in] p_opt Pointer to ble_opt_t union. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. - */ -uint32_t ble_opt_set_req_enc(uint32_t const opt_id, - ble_opt_t const * const p_opt, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_opt_set command. - * - * @sa @ref nrf51_opt_set_encoding for packet format, - * @ref ble_opt_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @return NRF_SUCCESS Version information stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_enable command request. - * - * @sa @ref nrf51_enable_encoding for packet format, - * @ref ble_enable_rsp_dec for command response decoder. - * - * @param[in] p_ble_enable_params Pointer to a @ref ble_enable_params_t structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_enable command. - * - * @sa @ref nrf51_enable_encoding for packet format, - * @ref ble_enable_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @return NRF_SUCCESS Success. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - - -/**@brief Encodes @ref sd_ble_opt_get command request. - * - * @sa @ref nrf51_opt_get_encoding for packet format, - * @ref ble_opt_get_rsp_dec for command response decoder. - * - * @param[in] opt_id Identifies type of parameter in ble_opt_t union. - * @param[in] p_opt Pointer to a @ref ble_opt_t union to be filled by the response. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. - */ -uint32_t ble_opt_get_req_enc(uint32_t opt_id, - ble_opt_t const * const p_opt, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_opt_get command. - * - * @sa @ref nrf51_opt_get_encoding for packet format, - * @ref ble_opt_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_opt_id Pointer to a decoded opt_id - * @param[out] p_opt Pointer to a decoded @ref ble_opt_t union - * @param[out] p_result_code Command result code. - * - * @return NRF_SUCCESS Opt stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. - */ -uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t * const p_opt, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_user_mem_reply command request. - * - * @sa @ref nrf51_user_mem_reply_encoding for packet format, - * @ref ble_user_mem_reply_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection Handle. - * @param[in] p_block Pointer to a @ref ble_user_mem_block_t structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. - */ -uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle, - ble_user_mem_block_t const * p_block, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_user_mem_reply command. - * - * @sa @ref nrf51_user_mem_reply_encoding for packet format, - * @ref ble_user_mem_reply_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @return NRF_SUCCESS Opt stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. - */ -uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Event decoding dispatcher. - * - * The event decoding dispatcher will route the event packet to the correct decoder which in turn - * decodes the contents of the event and updates the \p p_event struct. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to beginning of event packet. - * @param[in] packet_len Length (in bytes) of event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - * @retval NRF_ERROR_NOT_FOUND Decoding failure. No event decoder is available. - */ -uint32_t ble_event_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s110/serializers/ble_enable.c b/components/serialization/application/codecs/s110/serializers/ble_enable.c deleted file mode 100644 index c49d68a..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_enable.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include -#include "ble_app.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - p_buf[index++] = SD_BLE_ENABLE; - - err_code = cond_field_enc(p_ble_enable_params, p_buf, *p_buf_len, &index, ble_enable_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_ENABLE, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_event.c b/components/serialization/application/codecs/s110/serializers/ble_event.c deleted file mode 100644 index 72bc67e..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_event.c +++ /dev/null @@ -1,238 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include "ble_evt_app.h" -#include "ble_gap_evt_app.h" -#include "ble_gattc_evt_app.h" -#include "ble_gatts_evt_app.h" -#include "ble_l2cap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_event_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE, packet_len); - - - const uint16_t event_id = uint16_decode(&p_buf[SER_EVT_ID_POS]); - const uint8_t * p_sub_buffer = &p_buf[SER_EVT_HEADER_SIZE]; - const uint32_t sub_packet_len = packet_len - SER_EVT_HEADER_SIZE; - - if (p_event) - { - SER_ASSERT_LENGTH_LEQ(sizeof (ble_evt_hdr_t), *p_event_len); - *p_event_len -= sizeof (ble_evt_hdr_t); - } - - switch (event_id) - { - case BLE_EVT_TX_COMPLETE: - err_code = ble_evt_tx_complete_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_EVT_USER_MEM_REQUEST: - err_code = ble_evt_user_mem_request_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_EVT_USER_MEM_RELEASE: - err_code = ble_evt_user_mem_release_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_PASSKEY_DISPLAY: - err_code = ble_gap_evt_passkey_display_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_AUTH_KEY_REQUEST: - err_code = ble_gap_evt_auth_key_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE: - err_code = ble_gap_evt_conn_param_update_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: - err_code = ble_gap_evt_conn_param_update_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONN_SEC_UPDATE: - err_code = ble_gap_evt_conn_sec_update_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONNECTED: - err_code = ble_gap_evt_connected_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_DISCONNECTED: - err_code = ble_gap_evt_disconnected_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GAP_EVT_TIMEOUT: - err_code = ble_gap_evt_timeout_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_RSSI_CHANGED: - err_code = ble_gap_evt_rssi_changed_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GAP_EVT_SEC_INFO_REQUEST: - err_code = ble_gap_evt_sec_info_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - err_code = ble_gap_evt_sec_params_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_AUTH_STATUS: - err_code = ble_gap_evt_auth_status_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - err_code = ble_gattc_evt_char_disc_rsp_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: - err_code = ble_gattc_evt_char_val_by_uuid_read_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_DESC_DISC_RSP: - err_code = ble_gattc_evt_desc_disc_rsp_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - err_code = ble_gattc_evt_prim_srvc_disc_rsp_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_READ_RSP: - err_code = ble_gattc_evt_read_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_HVX: - err_code = ble_gattc_evt_hvx_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTC_EVT_TIMEOUT: - err_code = ble_gattc_evt_timeout_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTC_EVT_WRITE_RSP: - err_code = ble_gattc_evt_write_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_CHAR_VALS_READ_RSP: - err_code = ble_gattc_evt_char_vals_read_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_REL_DISC_RSP: - err_code = ble_gattc_evt_rel_disc_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTS_EVT_WRITE: - err_code = ble_gatts_evt_write_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTS_EVT_TIMEOUT: - err_code = ble_gatts_evt_timeout_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTS_EVT_SC_CONFIRM: - err_code = ble_gatts_evt_sc_confirm_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTS_EVT_HVC: - err_code = ble_gatts_evt_hvc_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - err_code = ble_gatts_evt_sys_attr_missing_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: - err_code = ble_gatts_evt_rw_authorize_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_L2CAP_EVT_RX: - err_code = ble_l2cap_evt_rx_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_ADV_REPORT: - err_code = ble_gap_evt_adv_report_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_SCAN_REQ_REPORT: - err_code = ble_gap_evt_scan_req_report_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_SEC_REQUEST: - err_code = ble_gap_evt_sec_request_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - default: - err_code = NRF_ERROR_NOT_FOUND; - break; - } - - if (p_event != NULL) - { - p_event->header.evt_id = (err_code == NRF_SUCCESS) ? event_id : 0; - p_event->header.evt_len = (err_code == NRF_SUCCESS) ? - (uint16_t)*p_event_len : 0; - } - *p_event_len += sizeof(ble_evt_hdr_t); - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_evt_app.h b/components/serialization/application/codecs/s110/serializers/ble_evt_app.h deleted file mode 100644 index e607fd4..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_evt_app.h +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_EVT_APP_H__ -#define BLE_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_evt_app Application event decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_evt_tx_complete event. - * - * @sa @ref nrf51_evt_tx_complete_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_evt_user_mem_request event. - * - * @sa @ref nrf51_evt_user_mem_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ - uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_evt_user_mem_release event. - * - * @sa @ref nrf51_evt_user_mem_release_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ - uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s110/serializers/ble_evt_tx_complete.c b/components/serialization/application/codecs/s110/serializers/ble_evt_tx_complete.c deleted file mode 100644 index 4abf73c..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_evt_tx_complete.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_evt_app.h" -#include "ble_serialization.h" - - -uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_evt_tx_complete_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_EVT_TX_COMPLETE; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.common_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.common_evt.params.tx_complete.count); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_evt_user_mem_release.c b/components/serialization/application/codecs/s110/serializers/ble_evt_user_mem_release.c deleted file mode 100644 index aab4fa5..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_evt_user_mem_release.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" -#include "ble_evt_app.h" -#include "app_ble_user_mem.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.common_evt.params.user_mem_release)) + - sizeof (ble_evt_user_mem_release_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - p_event->header.evt_id = BLE_EVT_USER_MEM_RELEASE; - p_event->header.evt_len = event_len; - ble_evt_user_mem_release_t * p_user_mem_rel = &(p_event->evt.common_evt.params.user_mem_release); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.common_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_user_mem_rel->type)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - // Decoding order of mem block is different than structure elements order - length is decoded first - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_user_mem_rel->mem_block.len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - // Using connection handle find which mem block to release in Application Processor - uint32_t user_mem_table_index; - err_code = app_ble_user_mem_context_find(p_event->evt.common_evt.conn_handle, &user_mem_table_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_user_mem_rel->mem_block.p_mem = m_app_user_mem_table[user_mem_table_index].mem_block.p_mem; - } - else - { - p_user_mem_rel->mem_block.p_mem = NULL; - } - - // Now user memory context can be released - err_code = app_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_evt_user_mem_request.c b/components/serialization/application/codecs/s110/serializers/ble_evt_user_mem_request.c deleted file mode 100644 index 9ba8b1b..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_evt_user_mem_request.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" -#include "ble_evt_app.h" - -uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.common_evt.params.user_mem_request)) + - sizeof (ble_evt_user_mem_request_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - p_event->header.evt_id = BLE_EVT_USER_MEM_REQUEST; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.common_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_event->evt.common_evt.params.user_mem_request.type)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_address_get.c b/components/serialization/application/codecs/s110/serializers/ble_gap_address_get.c deleted file mode 100644 index 4af2bc4..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_address_get.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_address_get_req_enc(ble_gap_addr_t const * const p_address, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_ADDRESS_GET; - p_buf[index++] = (p_address == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_address_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * const p_address, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GAP_ADDRESS_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 1 + BLE_GAP_ADDR_LEN, packet_len); - SER_ASSERT_NOT_NULL(p_address); - - p_address->addr_type = p_buf[index++]; - memcpy(p_address->addr, &p_buf[index], BLE_GAP_ADDR_LEN); - index += BLE_GAP_ADDR_LEN; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_address_set.c b/components/serialization/application/codecs/s110/serializers/ble_gap_address_set.c deleted file mode 100644 index 0f0b396..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_address_set.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_address_set_req_enc(uint8_t addr_cycle_mode, - ble_gap_addr_t const * const p_addr, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_ADDRESS_SET; - p_buf[index++] = addr_cycle_mode; - p_buf[index++] = (p_addr == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_addr != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + BLE_GAP_ADDR_LEN, *p_buf_len); - p_buf[index++] = p_addr->addr_type; - memcpy(&p_buf[index], p_addr->addr, BLE_GAP_ADDR_LEN); - index += BLE_GAP_ADDR_LEN; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_address_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADDRESS_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_adv_data_set.c b/components/serialization/application/codecs/s110/serializers/ble_gap_adv_data_set.c deleted file mode 100644 index a59f271..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_adv_data_set.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data, - uint8_t dlen, - uint8_t const * const p_sr_data, - uint8_t srdlen, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint8_t opcode = SD_BLE_GAP_ADV_DATA_SET; - uint32_t err_code; - err_code = uint8_t_enc(&opcode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len8data_enc(p_data, dlen, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len8data_enc(p_sr_data, srdlen, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADV_DATA_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_adv_start.c b/components/serialization/application/codecs/s110/serializers/ble_gap_adv_start.c deleted file mode 100644 index 115a447..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_adv_start.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - -uint32_t ble_gap_adv_start_req_enc(ble_gap_adv_params_t const * const p_adv_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 2, total_len); - p_buf[index++] = SD_BLE_GAP_ADV_START; - p_buf[index++] = (p_adv_params == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_adv_params != NULL) - { - err_code = uint8_t_enc(&(p_adv_params->type), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_adv_params->p_peer_addr, p_buf, total_len, &index, ble_gap_addr_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&(p_adv_params->fp), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_adv_params->p_whitelist, p_buf, total_len, &index, ble_gap_whitelist_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_adv_params->interval), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_adv_params->timeout), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_adv_ch_mask_t_enc(&(p_adv_params->channel_mask), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADV_START, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_adv_stop.c b/components/serialization/application/codecs/s110/serializers/ble_gap_adv_stop.c deleted file mode 100644 index c633a4b..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_adv_stop.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" - -uint32_t ble_gap_adv_stop_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_ADV_STOP; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADV_STOP, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_app.h b/components/serialization/application/codecs/s110/serializers/ble_gap_app.h deleted file mode 100644 index 13c4fd1..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_app.h +++ /dev/null @@ -1,1158 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GAP_APP_H__ -#define BLE_GAP_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gap_app GAP Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief GAP Application command request encoders and command response decoders. - */ -#include "ble.h" -#include "ble_gap.h" - -/** - * @brief Encodes @ref sd_ble_gap_address_get command request. - * - * @sa @ref nrf51_address_get_encoding for packet format, - * @ref ble_gap_address_get_rsp_dec for command response decoder. - * - * @param[in] p_address Pointer to address. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_address will not be updated by the command - * request encoder. Updated values are set by @ref ble_gap_address_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_get_req_enc(ble_gap_addr_t const * const p_address, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_address_get command. - * - * @sa @ref nrf51_address_get_encoding for packet format, - * @ref ble_gap_address_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_address Pointer to address. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_address_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * const p_address, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_address_set command request. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format, - * @ref ble_gap_address_set_rsp_dec for command response decoder. - * - * @param[in] addr_cycle_mode Address cycle mode. - * @param[in] p_addr Pointer to address structure. - * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_set_req_enc(uint8_t addr_cycle_mode, - ble_gap_addr_t const * const p_addr, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_address_set command. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format, - * @ref ble_gap_address_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_address_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_adv_data_set command request. - * - * @sa @ref nrf51_adv_set_encoding for packet format, - * @ref ble_gap_adv_data_set_rsp_dec for command response decoder. - * - * @param[in] p_data Raw data to be placed in advertisement packet. If NULL, no changes - * are made to the current advertisement packet data. - * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. - * Should be 0 if p_data is NULL, can be 0 if p_data is not NULL. - * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, - * no changes are made to the current scan response packet data. - * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. - * Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data, - uint8_t dlen, - uint8_t const * const p_sr_data, - uint8_t srdlen, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_adv_data_set command. - * - * @sa @ref nrf51_adv_set_encoding for packet format, - * @ref ble_gap_adv_data_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_adv_start command request. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_gap_adv_start_rsp_dec for command response decoder. - * - * @param[in] p_adv_params Pointer to advertising parameters structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_start_req_enc(ble_gap_adv_params_t const * const p_adv_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_adv_start command. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_gap_adv_start_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_tx_power_set command request. - * - * @sa @ref nrf51_tx_power_set_encoding for packet format, - * @ref ble_gap_tx_power_set_rsp_dec for command response decoder. - * - * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm). - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_tx_power_set_req_enc(int8_t tx_power, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_tx_power_set command. - * - * @sa @ref nrf51_tx_power_set_encoding for packet format, - * @ref ble_gap_tx_power_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_appearance_get command request. - * - * @sa @ref nrf51_appearance_get_encoding for packet format, - * @ref ble_gap_appearance_get_rsp_dec for command response decoder. - * - * @param[in] p_appearance Appearance (16-bit), see @ref BLE_APPEARANCES - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_appearance will not be updated by the command - * request encoder. Updated values are set by @ref ble_gap_appearance_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_appearance_get command. - * - * @sa @ref nrf51_appearance_get_encoding for packet format, - * @ref ble_gap_appearance_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_appearance Appearance (16-bit), see @ref BLE_APPEARANCES. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_appearance, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_appearance_set command request. - * - * @sa @ref nrf51_appearance_set_encoding for packet format, - * @ref ble_gap_appearance_set_rsp_dec for command response decoder. - * - * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_appearance_set command. - * - * @sa @ref nrf51_appearance_set_encoding for packet format, - * @ref ble_gap_appearance_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_device_name_get command request. - * - * @sa @ref nrf51_device_name_get_encoding for packet format, - * @ref ble_gap_device_name_get_rsp_dec for command response decoder. - * - * @param[in] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated - * string will be placed. Set to NULL to obtain the complete device - * name length. - * @param[in] p_dev_name_len Length of the buffer pointed by p_dev_name. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_dev_name and \p p_len will not be updated by the command - * request encoder. Updated values are set by @ref ble_gap_device_name_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name, - uint16_t const * const p_dev_name_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_device_name_get command. - * - * @sa @ref nrf51_device_name_get_encoding for packet format, - * @ref ble_gap_device_name_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 - * non NULL-terminated string will be placed. - * @param[in,out] p_dev_name_len Length of the buffer pointed by p_dev_name, complete device name - * length on output. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_dev_name, - uint16_t * const p_dev_name_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_device_name_set command request. - * - * @sa @ref nrf51_device_name_set_encoding for packet format, - * @ref ble_gap_device_name_set_rsp_dec for command response decoder. - * - * @param[in] p_write_perm Write permissions for the Device Name characteristic see - * @ref ble_gap_conn_sec_mode_t. - * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. - * @param[in] len Length of the UTF-8, non NULL-terminated string pointed - * to by p_dev_name in octets (must be smaller or equal - * than @ref BLE_GAP_DEVNAME_MAX_LEN). - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p_write_perm, - uint8_t const * const p_dev_name, - uint16_t len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_device_name_set command. - * - * @sa @ref nrf51_device_name_set_encoding for packet format, - * @ref ble_gap_device_name_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_ppcp_set command request. - * - * @sa @ref nrf51_ppcp_set_encoding for packet format, - * @ref ble_gap_ppcp_set_rsp_dec for command response decoder. - * - * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the - * desired parameters. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_ppcp_set command. - * - * @sa @ref nrf51_ppcp_set_encoding for packet format, - * @ref ble_gap_ppcp_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_conn_param_update command request. - * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format, - * @ref ble_gap_conn_param_update_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_conn_params Pointer to desired connection parameters.. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_conn_param_update_req_enc(uint16_t conn_handle, - ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_conn_param_update command. - * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format, - * @ref ble_gap_conn_param_update_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_disconnect command request. - * - * @sa @ref nrf51_disconnect_encoding for packet format, - * @ref ble_gap_disconnect_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle, - uint8_t hci_status_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_disconnect command. - * - * @sa @ref nrf51_disconnect_encoding for packet format, - * @ref ble_gap_disconnect_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - - -/**@brief Encodes @ref sd_ble_gap_rssi_stop command request. - * - * @sa @ref nrf51_rssi_stop_encoding for packet format, - * @ref ble_gap_rssi_stop_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_rssi_stop command. - * - * @sa @ref nrf51_rssi_stop_encoding for packet format, - * @ref ble_gap_rssi_stop_rsp_dec for command response decoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - - - - -/**@brief Encodes @ref sd_ble_gap_ppcp_get command request. - * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format, - * @ref ble_gap_ppcp_get_rsp_dec for command response decoder. - * - * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the - * parameters will be stored. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_conn_params will not be updated by the command request encoder. Updated values are - * set by @ref ble_gap_ppcp_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_ppcp_get command. - * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format, - * @ref ble_gap_ppcp_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters - * will be stored. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_params_t * const p_conn_params, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_auth_key_reply command request. - * - * @sa @ref nrf51_auth_key_reply_encoding for packet format, - * @ref ble_gap_auth_key_reply_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] key_type Key type which defines length of key data as defined for - * @ref sd_ble_gap_auth_key_reply . - * @param[in] p_key Pointer to a buffer which contains key - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect param provided (key_type). - */ -uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle, - uint8_t key_type, - uint8_t const * const p_key, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_auth_key_reply command. - * - * @sa @ref nrf51_auth_key_reply_encoding for packet format, - * @ref ble_gap_auth_key_reply_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_sec_info_reply command request. - * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format, - * @ref ble_gap_sec_info_reply_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information - * structure. - * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t id information - * structure. - * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information - * structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle, - ble_gap_enc_info_t const * p_enc_info, - ble_gap_irk_t const * p_id_info, - ble_gap_sign_info_t const * p_sign_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_sec_info_reply command. - * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format, - * @ref ble_gap_sec_info_reply_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_sec_params_reply command request. - * - * @sa @ref nrf51_sec_params_reply_encoding for packet format, - * @ref ble_gap_sec_params_reply_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. - * @param[in] p_sec_params Pointer to @ref ble_gap_sec_params_t security parameters - * structure. - * @param[in] p_sec_keyset Pointer to @ref ble_gap_sec_keyset_t security keys - * structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_sec_params_reply_req_enc(uint16_t conn_handle, - uint8_t sec_status, - ble_gap_sec_params_t const * const p_sec_params, - ble_gap_sec_keyset_t const * const p_sec_keyset, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_sec_params_reply command. - * - * @sa @ref nrf51_sec_params_reply_encoding for packet format, - * @ref ble_gap_sec_params_reply_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] p_sec_keyset Pointer to @ref ble_gap_sec_keyset_t security keys - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_sec_keyset_t const * const p_sec_keyset, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_authenticate command request. - * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format, - * @ref ble_gap_authenticate_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters - * structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle, - ble_gap_sec_params_t const * const p_sec_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_authenticate command. - * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format, - * @ref ble_gap_authenticate_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_adv_stop command request. - * - * @sa @ref nrf51_sd_ble_gap_adv_stop for packet format, - * @ref ble_gap_adv_stop_rsp_dec for command response decoder. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_stop_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_adv_stop command. - * - * @sa @ref nrf51_sd_ble_gap_adv_stop for packet format, - * @ref ble_gap_adv_stop_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_conn_sec_get command request. - * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format, - * @ref ble_gap_conn_sec_get_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_conn_sec Pointer to \ref ble_gap_conn_sec_t which will be filled in - * response. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_handle, - ble_gap_conn_sec_t const * const p_conn_sec, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_conn_sec_get command. - * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format, - * @ref ble_gap_conn_sec_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_conn_sec Pointer to pointer to \ref ble_gap_conn_sec_t which will be filled by - * the decoded data (if present). - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_sec_t * * const pp_conn_sec, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_rssi_start command request. - * - * @sa @ref nrf51_rssi_start_encoding for packet format, - * @ref ble_gap_rssi_start_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] threshold_dbm Threshold in dBm. - * @param[in] skip_count Sample skip count. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle, - uint8_t threshold_dbm, - uint8_t skip_count, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_rssi_start command. - * - * @sa @ref nrf51_rssi_start_encoding for packet format, - * @ref ble_gap_rssi_start_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_encrypt command request. - * - * @sa @ref nrf51_gap_encrypt_encoding for packet format, - * @ref ble_gap_encrypt_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_master_id Pointer to a master identification structure. - * @param[in] p_enc_info Pointer to desired connection parameters. - * @param[in] p_buf Pointer to a ble_gap_enc_info_t encryption information structure. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_gap_encrypt_req_enc( uint16_t conn_handle, - ble_gap_master_id_t const * const p_master_id, - ble_gap_enc_info_t const * const p_enc_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - - -/**@brief Decodes response to @ref sd_ble_gap_encrypt command. - * - * @sa @ref nrf51_gap_encrypt_encoding for packet format, - * @ref ble_gap_encrypt_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_rssi_get command request. - * - * @sa @ref nrf51_rssi_get_encoding for packet format, - * @ref ble_gap_rssi_get_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_rssi Pointer to the rssi value. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle, - int8_t const * const p_rssi, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_rssi_get command. - * - * @sa @ref nrf51_rssi_get_encoding for packet format, - * @ref ble_gap_rssi_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_rssi Pointer to rssi value. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - int8_t * const p_rssi, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_connect command request. - * - * @sa @ref nrf51_connect_encoding for packet format, - * @ref ble_gap_connect_rsp_dec for command response decoder. - * - * @param[in] p_peer_addr Pointer to peer address. - * @param[in] p_scan_params Pointer to scan params structure. - * @param[in] p_conn_params Pointer to desired connection parameters. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr, - ble_gap_scan_params_t const * const p_scan_params, - ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_connect command. - * - * @sa @ref nrf51_connect_encoding for packet format, - * @ref ble_gap_connect_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_connect_cancel command request. - * - * @sa @ref nrf51_connect_cancel_encoding for packet format, - * @ref ble_gap_connect_cancel_rsp_dec for command response decoder. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_connect_cancel command. - * - * @sa @ref nrf51_connect_cancel_encoding for packet format, - * @ref ble_gap_connect_cancel_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_scan_start command request. - * - * @sa @ref nrf51_scan_start_encoding for packet format, - * @ref ble_gap_scan_start_rsp_dec for command response decoder. - * - * @param[in] p_scan_params Pointer to scan params structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_scan_start command. - * - * @sa @ref nrf51_scan_start_encoding for packet format, - * @ref ble_gap_scan_start_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_scan_stop command request. - * - * @sa @ref nrf51_scan_stop_encoding for packet format, - * @ref ble_gap_scan_stop_rsp_dec for command response decoder. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_scan_stop command. - * - * @sa @ref nrf51_scan_stop_encoding for packet format, - * @ref ble_gap_scan_stop_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_appearance_get.c b/components/serialization/application/codecs/s110/serializers/ble_gap_appearance_get.c deleted file mode 100644 index cc55dd6..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_appearance_get.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_APPEARANCE_GET; - p_buf[index++] = (p_appearance == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_appearance, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_APPEARANCE_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + sizeof (uint16_t), packet_len); - - uint16_dec(p_buf, packet_len, &index, p_appearance); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_appearance_set.c b/components/serialization/application/codecs/s110/serializers/ble_gap_appearance_set.c deleted file mode 100644 index 8038b76..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_appearance_set.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_APPEARANCE_SET; - index += uint16_encode(appearance, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_APPEARANCE_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_auth_key_reply.c b/components/serialization/application/codecs/s110/serializers/ble_gap_auth_key_reply.c deleted file mode 100644 index 58861e0..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_auth_key_reply.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle, - uint8_t key_type, - uint8_t const * const p_key, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_GAP_AUTH_KEY_REPLY; - uint32_t err_code = NRF_SUCCESS; - uint8_t key_len; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&key_type, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - switch (key_type) - { - case BLE_GAP_AUTH_KEY_TYPE_NONE: - key_len = 0; - break; - - case BLE_GAP_AUTH_KEY_TYPE_PASSKEY: - key_len = 6; - break; - - case BLE_GAP_AUTH_KEY_TYPE_OOB: - key_len = 16; - break; - - default: - return NRF_ERROR_INVALID_PARAM; - } - - err_code = buf_enc(p_key, key_len, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_AUTH_KEY_REPLY, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_authenticate.c b/components/serialization/application/codecs/s110/serializers/ble_gap_authenticate.c deleted file mode 100644 index 028b3f0..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_authenticate.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle, - ble_gap_sec_params_t const * const p_sec_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_AUTHENTICATE; - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_params, p_buf, *p_buf_len, &index, ble_gap_sec_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_AUTHENTICATE, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_conn_param_update.c b/components/serialization/application/codecs/s110/serializers/ble_gap_conn_param_update.c deleted file mode 100644 index 3d81edf..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_conn_param_update.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_conn_param_update_req_enc(uint16_t conn_handle, - ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_CONN_PARAM_UPDATE; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_conn_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_conn_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 * 4, *p_buf_len); - index += uint16_encode(p_conn_params->min_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->max_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->slave_latency, &p_buf[index]); - index += uint16_encode(p_conn_params->conn_sup_timeout, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_CONN_PARAM_UPDATE, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_conn_sec_get.c b/components/serialization/application/codecs/s110/serializers/ble_gap_conn_sec_get.c deleted file mode 100644 index b3850b1..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_conn_sec_get.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_handle, - ble_gap_conn_sec_t const * const p_conn_sec, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint8_t opcode = SD_BLE_GAP_CONN_SEC_GET; - - - err_code = uint8_t_enc(&opcode, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_conn_sec, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_sec_t * * const pp_conn_sec, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - uint32_t index = 0; - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_CONN_SEC_GET, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_conn_sec, - ble_gap_conn_sec_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_connect.c b/components/serialization/application/codecs/s110/serializers/ble_gap_connect.c deleted file mode 100644 index 5f13670..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_connect.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr, - ble_gap_scan_params_t const * const p_scan_params, - ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_CONNECT; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_peer_addr, p_buf, buf_len, &index, ble_gap_addr_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_scan_params, p_buf, buf_len, &index, ble_gap_scan_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_conn_params, p_buf, buf_len, &index, ble_gap_conn_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_CONNECT, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_connect_cancel.c b/components/serialization/application/codecs/s110/serializers/ble_gap_connect_cancel.c deleted file mode 100644 index 0730ade..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_connect_cancel.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_CONNECT_CANCEL; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_CONNECT_CANCEL, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_device_name_get.c b/components/serialization/application/codecs/s110/serializers/ble_gap_device_name_get.c deleted file mode 100644 index 0d12b4a..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_device_name_get.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name, - uint16_t const * const p_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_DEVICE_NAME_GET; - p_buf[index++] = (p_len != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - index += uint16_encode(*p_len, &p_buf[index]); - } - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_dev_name != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_dev_name, - uint16_t * const p_dev_name_len, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - uint32_t index = 0; - uint32_t status_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_DEVICE_NAME_GET, - p_result_code); - - if (status_code != NRF_SUCCESS) - { - return status_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_dev_name_len); - status_code = len16data_dec(p_buf, packet_len, &index, (uint8_t * *)&p_dev_name, p_dev_name_len); - - if (status_code != NRF_SUCCESS) - { - return status_code; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return status_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_device_name_set.c b/components/serialization/application/codecs/s110/serializers/ble_gap_device_name_set.c deleted file mode 100644 index c265c4f..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_device_name_set.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p_write_perm, - uint8_t const * const p_dev_name, - uint16_t len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(2, *p_buf_len); - p_buf[index++] = SD_BLE_GAP_DEVICE_NAME_SET; - - p_buf[index++] = (p_write_perm != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_write_perm != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (uint8_t) ((p_write_perm->sm) | (p_write_perm->lv << 4)); - } - - SER_ERROR_CHECK(len <= BLE_GAP_DEVNAME_MAX_LEN, NRF_ERROR_INVALID_PARAM); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - index += uint16_encode(len, &p_buf[index]); - - p_buf[index++] = (p_dev_name != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_dev_name != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + len, *p_buf_len); - memcpy(&p_buf[index], p_dev_name, len); - index += len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_DEVICE_NAME_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_disconnect.c b/components/serialization/application/codecs/s110/serializers/ble_gap_disconnect.c deleted file mode 100644 index d3064d6..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_disconnect.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle, - uint8_t hci_status_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 4, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_DISCONNECT; - index += uint16_encode(conn_handle, &p_buf[index]); - p_buf[index++] = hci_status_code; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_DISCONNECT, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_encrypt.c b/components/serialization/application/codecs/s110/serializers/ble_gap_encrypt.c deleted file mode 100644 index 0abf029..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_encrypt.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_encrypt_req_enc( uint16_t conn_handle, - ble_gap_master_id_t const * const p_master_id, - ble_gap_enc_info_t const * const p_enc_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_ENCRYPT; - index += uint16_encode(conn_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_master_id != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_master_id != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_RAND_LEN + 2, *p_buf_len); - index += uint16_encode(p_master_id->ediv, &p_buf[index]); - memcpy(&p_buf[index], p_master_id->rand, BLE_GAP_SEC_RAND_LEN); - index += BLE_GAP_SEC_RAND_LEN; - } - - p_buf[index++] = (p_enc_info != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_enc_info != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_KEY_LEN + 1, *p_buf_len); - memcpy(&p_buf[index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); - index += BLE_GAP_SEC_KEY_LEN; - p_buf[index++] = (p_enc_info->auth | (p_enc_info->ltk_len << 1)); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ENCRYPT, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_adv_report.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_adv_report.c deleted file mode 100644 index 256919b..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_adv_report.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE+7+1+1, packet_len); // assumed size(data) = 0 - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.adv_report)) + - sizeof (ble_gap_evt_adv_report_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_ADV_REPORT; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.adv_report.peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.adv_report.rssi)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_event->evt.gap_evt.params.adv_report.scan_rsp = byte & 0x01; - p_event->evt.gap_evt.params.adv_report.type = (byte >> 1) & 0x03; - p_event->evt.gap_evt.params.adv_report.dlen = (byte >> 3) & 0x1F; - - err_code = uint8_vector_dec(p_buf, packet_len, &index, - p_event->evt.gap_evt.params.adv_report.data, (uint16_t)(p_event->evt.gap_evt.params.adv_report.dlen)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_app.h b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_app.h deleted file mode 100644 index 287dc93..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_app.h +++ /dev/null @@ -1,411 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GAP_EVT_APP_H__ -#define BLE_GAP_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gap_evt_app GAP Application event decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief GAP Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_gap_evt_auth_key_request event. - * - * @sa @ref nrf51_evt_auth_key_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_auth_status event. - * - * @sa @ref nrf51_evt_auth_status_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_conn_param_update event. - * - * @sa @ref nrf51_evt_conn_param_update_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_adv_report event. - * - * @sa @ref nrf51_evt_adv_report_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_conn_param_update_request event. - * - * @sa @ref nrf51_evt_conn_param_update_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_conn_sec_update event. - * - * @sa @ref nrf51_evt_conn_sec_update_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_connected event. - * - * @sa @ref nrf51_evt_connected_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_disconnected event. - * - * @sa @ref nrf51_evt_disconnected_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_passkey_display event. - * - * @sa @ref nrf51_evt_passkey_display for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_rssi_changed event. - * - * @sa @ref nrf51_evt_rssi_changed_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_sec_info_request event. - * - * @sa @ref nrf51_evt_sec_info_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_sec_params_request event. - * - * @sa @ref nrf51_evt_sec_param_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_timeout event. - * - * @sa @ref nrf51_evt_timeout_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_scan_req_report event. - * - * @sa @ref nrf51_evt_scan_req_report_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_sec_request event. - * - * @sa @ref nrf51_evt_sec_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_auth_key_request.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_auth_key_request.c deleted file mode 100644 index 090b431..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_auth_key_request.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + 1; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_AUTH_KEY_REQUEST; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.auth_key_request.key_type); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_auth_status.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_auth_status.c deleted file mode 100644 index 6f54d6a..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_auth_status.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" -#include "app_ble_gap_sec_keys.h" - -extern ser_ble_gap_app_keyset_t m_app_keys_table[]; - -uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint32_t conn_index; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 6, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.auth_status)) + - sizeof (ble_gap_evt_adv_report_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - p_event->header.evt_id = BLE_GAP_EVT_AUTH_STATUS; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_auth_status_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.auth_status)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - // keyset is an extension of standard event data - used to synchronize keys at application - err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keyset_t_dec(p_buf, packet_len, &index, &(m_app_keys_table[conn_index].keyset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = app_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_param_update.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_param_update.c deleted file mode 100644 index 33cacdc..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_param_update.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.conn_param_update)) + - sizeof (ble_gap_evt_conn_param_update_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_CONN_PARAM_UPDATE; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.min_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.max_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.slave_latency); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.conn_sup_timeout); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_param_update_request.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_param_update_request.c deleted file mode 100644 index 7bede0f..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_param_update_request.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.conn_param_update_request)) + - sizeof (ble_gap_evt_conn_param_update_request_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.min_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.max_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.slave_latency); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.conn_sup_timeout); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_sec_update.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_sec_update.c deleted file mode 100644 index 6802173..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_conn_sec_update.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.conn_sec_update)) + - sizeof (ble_gap_evt_conn_sec_update_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_CONN_SEC_UPDATE; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - p_event->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm = p_buf[index] & 0x0F; - p_event->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv = (p_buf[index] >> 4) & 0x0F; - index++; - - uint8_dec(p_buf, packet_len, - &index, &p_event->evt.gap_evt.params.conn_sec_update.conn_sec.encr_key_size); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_connected.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_connected.c deleted file mode 100644 index 0dfcd5a..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_connected.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t event_len = sizeof (ble_gap_evt_connected_t) + - sizeof (p_event->evt.gap_evt.conn_handle); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_connected_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.connected)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_disconnected.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_disconnected.c deleted file mode 100644 index fa29107..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_disconnected.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_disconnected_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_DISCONNECTED; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.disconnected.reason); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_passkey_display.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_passkey_display.c deleted file mode 100644 index 7a2f155..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_passkey_display.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey) - - -uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + PASSKEY_LEN, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_passkey_display_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_PASSKEY_DISPLAY; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - memcpy(p_event->evt.gap_evt.params.passkey_display.passkey, &p_buf[index], PASSKEY_LEN); - index += PASSKEY_LEN; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} - diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_rssi_changed.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_rssi_changed.c deleted file mode 100644 index b7de4cc..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_rssi_changed.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_rssi_changed_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_RSSI_CHANGED; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - int8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.rssi_changed.rssi); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} - diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_scan_req_report.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_scan_req_report.c deleted file mode 100644 index 118fcf2..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_scan_req_report.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.scan_req_report)) + - sizeof (ble_gap_evt_scan_req_report_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_SCAN_REQ_REPORT; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.scan_req_report.peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.scan_req_report.rssi)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_info_request.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_info_request.c deleted file mode 100644 index ff3d0af..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_info_request.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.sec_info_request)) + - sizeof (ble_gap_evt_sec_info_request_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_SEC_INFO_REQUEST; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - err_code = ble_gap_evt_sec_info_request_t_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.sec_info_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_params_request.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_params_request.c deleted file mode 100644 index beaa49a..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_params_request.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(7, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_sec_params_request_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - p_event->header.evt_id = BLE_GAP_EVT_SEC_PARAMS_REQUEST; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_params_request_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.sec_params_request)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_request.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_request.c deleted file mode 100644 index f080405..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_sec_request.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gap_evt_app.h" -#include "ble_gap_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - uint32_t event_len = sizeof (ble_gap_evt_sec_request_t) + - sizeof (p_event->evt.gap_evt.conn_handle); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - ble_gap_evt_sec_request_t * p_decoded_evt = &(p_event->evt.gap_evt.params.sec_request); - - uint32_t err_code = ble_gap_evt_sec_request_t_dec(p_buf, packet_len, &index, p_decoded_evt); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_timeout.c b/components/serialization/application/codecs/s110/serializers/ble_gap_evt_timeout.c deleted file mode 100644 index 8fdb83b..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_evt_timeout.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_EQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_timeout_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_TIMEOUT; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.timeout.src); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_ppcp_get.c b/components/serialization/application/codecs/s110/serializers/ble_gap_ppcp_get.c deleted file mode 100644 index e3c8b07..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_ppcp_get.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" - - -uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_PPCP_GET; - p_buf[index++] = (p_conn_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_params_t * const p_conn_params, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_PPCP_GET, p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_conn_params); - - SER_ASSERT_LENGTH_LEQ(index + 8, packet_len); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->min_conn_interval); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->max_conn_interval); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->slave_latency); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->conn_sup_timeout); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return decode_result; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_ppcp_set.c b/components/serialization/application/codecs/s110/serializers/ble_gap_ppcp_set.c deleted file mode 100644 index 15e5528..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_ppcp_set.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "nrf_error.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_PPCP_SET; - p_buf[index++] = (p_conn_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_conn_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 8, *p_buf_len); - index += uint16_encode(p_conn_params->min_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->max_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->slave_latency, &p_buf[index]); - index += uint16_encode(p_conn_params->conn_sup_timeout, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_PPCP_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_rssi_get.c b/components/serialization/application/codecs/s110/serializers/ble_gap_rssi_get.c deleted file mode 100644 index 24b4b2c..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_rssi_get.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle, - int8_t const * const p_rssi, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - SER_ASSERT_LENGTH_LEQ(index + 1, total_len); - - p_buf[index++] = SD_BLE_GAP_RSSI_GET; - - err_code = uint16_t_enc(&conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_rssi, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - int8_t * const p_rssi, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GAP_RSSI_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - decode_result = uint8_t_dec(p_buf, packet_len, &index, (uint8_t *) p_rssi); - SER_ASSERT(decode_result == NRF_SUCCESS, decode_result); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return decode_result; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_rssi_start.c b/components/serialization/application/codecs/s110/serializers/ble_gap_rssi_start.c deleted file mode 100644 index 539b8b6..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_rssi_start.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle, - uint8_t threshold_dbm, - uint8_t skip_count, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_RSSI_START; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&threshold_dbm, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&skip_count, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_RSSI_START, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_rssi_stop.c b/components/serialization/application/codecs/s110/serializers/ble_gap_rssi_stop.c deleted file mode 100644 index 49ef65e..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_rssi_stop.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - uint8_t op_code = SD_BLE_GAP_RSSI_STOP; - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_RSSI_STOP, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_scan_start.c b/components/serialization/application/codecs/s110/serializers/ble_gap_scan_start.c deleted file mode 100644 index a92ab3b..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_scan_start.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "cond_field_serialization.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SCAN_START; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = cond_field_enc(p_scan_params, p_buf, buf_len, &index, ble_gap_scan_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_SCAN_START, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_scan_stop.c b/components/serialization/application/codecs/s110/serializers/ble_gap_scan_stop.c deleted file mode 100644 index 72e7c4a..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_scan_stop.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" - -uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SCAN_STOP; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_SCAN_STOP, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_sec_info_reply.c b/components/serialization/application/codecs/s110/serializers/ble_gap_sec_info_reply.c deleted file mode 100644 index 0739b31..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_sec_info_reply.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gap.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle, - ble_gap_enc_info_t const * p_enc_info, - ble_gap_irk_t const * p_id_info, - ble_gap_sign_info_t const * p_sign_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SEC_INFO_REPLY; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - p_buf[index++] = (p_enc_info != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_enc_info != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_KEY_LEN + 1, buf_len); - memcpy(&p_buf[index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); - index += BLE_GAP_SEC_KEY_LEN; - p_buf[index++] = (p_enc_info->auth | (p_enc_info->ltk_len << 1)); - } - - err_code = cond_field_enc(p_id_info, p_buf, buf_len, &index, ble_gap_irk_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - p_buf[index++] = (p_sign_info != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_sign_info != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_KEY_LEN, buf_len); - memcpy(&p_buf[index], p_sign_info->csrk, BLE_GAP_SEC_KEY_LEN); - index += BLE_GAP_SEC_KEY_LEN; - } - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_SEC_INFO_REPLY, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_sec_params_reply.c b/components/serialization/application/codecs/s110/serializers/ble_gap_sec_params_reply.c deleted file mode 100644 index d04189d..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_sec_params_reply.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_sec_params_reply_req_enc(uint16_t conn_handle, - uint8_t sec_status, - ble_gap_sec_params_t const * const p_sec_params, - ble_gap_sec_keyset_t const * const p_sec_keyset, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SEC_PARAMS_REPLY; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&sec_status, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_params, p_buf, buf_len, &index, ble_gap_sec_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_keyset, p_buf, buf_len, &index, ble_gap_sec_keyset_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_sec_keyset_t const * const p_sec_keyset, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, SD_BLE_GAP_SEC_PARAMS_REPLY, p_result_code); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_sec_keyset); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **)&p_sec_keyset, ble_gap_sec_keyset_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gap_tx_power_set.c b/components/serialization/application/codecs/s110/serializers/ble_gap_tx_power_set.c deleted file mode 100644 index 807eb78..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gap_tx_power_set.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_tx_power_set_req_enc(int8_t tx_power, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_TX_POWER_SET; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&tx_power, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_TX_POWER_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_app.h b/components/serialization/application/codecs/s110/serializers/ble_gattc_app.h deleted file mode 100644 index c7bbf9a..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_app.h +++ /dev/null @@ -1,406 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_APP_H__ -#define BLE_GATTC_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gattc_app GATTC Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief GATTC Application command request encoders and command response decoders. - */ -#include "ble_gattc.h" -#include "ble.h" - -/**@brief Encodes @ref sd_ble_gattc_primary_services_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] start_handle Handle to start searching from. - * @param[in] p_srvc_uuid Pointer to a @ref ble_uuid_t which indicates the service UUID to - * be found. If it is NULL, all primary services will be returned. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle, - uint16_t start_handle, - ble_uuid_t const * const p_srvc_uuid, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_primary_services_discover command. - * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_descriptors_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format, - * @ref ble_gattc_descriptors_discover_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform - * this procedure on. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_descriptors_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len); - - -/**@brief Decodes response to @ref sd_ble_gattc_descriptors_discover command. - * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_relationships_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format, - * @ref ble_gattc_relationships_discover_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform - * this procedure on. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_relationships_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_relationships_discover command. - * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format, - * @ref ble_gattc_relationships_discover_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_characteristics_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format, - * @ref ble_gattc_characteristics_discover_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform - * this procedure on. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_characteristics_discover_req_enc - (uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_characteristics_discover command. - * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format, - * @ref ble_gattc_read_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] handle The handle of the attribute to be read. - * @param[in] offset Offset into the attribute value to be read. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_read_req_enc(uint16_t conn_handle, - uint16_t handle, - uint16_t offset, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_read command. - * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format, - * @ref ble_gattc_read_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_char_values_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format, - * @ref ble_gattc_char_values_read_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. - * @param[in] handle_count The number of handles in p_handles. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle, - uint16_t const * const p_handles, - uint16_t handle_count, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_char_values_read command. - * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format, - * @ref ble_gattc_char_values_read_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_write command request. - * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format, - * @ref ble_gattc_write_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_write_params Pointer to \ref sd_ble_gattc_write params. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_write_req_enc(uint16_t conn_handle, - ble_gattc_write_params_t const * const p_write_params, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_write command. - * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format, - * @ref ble_gattc_write_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_hv_confirm command request. - * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format, - * @ref ble_gattc_hv_confirm_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] handle Handle of the attribute in the indication. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle, - uint16_t handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_hv_confirm command. - * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format, - * @ref ble_gattc_hv_confirm_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Pointer to command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_char_value_by_uuid_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format, - * @ref ble_gattc_char_value_by_uuid_read_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_uuid Pointer to a characteristic value UUID to read. - * @param[in] p_handle_range Pointer to the range of handles to perform this procedure on. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_char_value_by_uuid_read_req_enc - (uint16_t conn_handle, - ble_uuid_t const * const p_uuid, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_char_value_by_uuid_read command. - * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format, - * @ref ble_gattc_char_value_by_uuid_read_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Pointer to command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); -/** @} */ -#endif - - diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_char_value_by_uuid_read.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_char_value_by_uuid_read.c deleted file mode 100644 index 7b75815..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_char_value_by_uuid_read.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "cond_field_serialization.h" -#include "ble_types.h" -#include - -uint32_t ble_gattc_char_value_by_uuid_read_req_enc - (uint16_t conn_handle, - ble_uuid_t const * const p_uuid, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code; - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_uuid, p_buf, buf_len, &index, ble_uuid_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_handle_range, p_buf, buf_len, &index, ble_gattc_handle_range_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, - packet_len, - SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, - p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_char_values_read.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_char_values_read.c deleted file mode 100644 index 6dc1e17..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_char_values_read.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle, - uint16_t const * const p_handles, - uint16_t handle_count, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint32_t err_code; - uint8_t opCode = SD_BLE_GATTC_CHAR_VALUES_READ; - - err_code = uint8_t_enc(&opCode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = count16_cond_data16_enc(p_handles, handle_count, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - *p_buf_len = index; - return err_code; -} - - -uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_CHAR_VALUES_READ, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_characteristics_discover.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_characteristics_discover.c deleted file mode 100644 index b98d142..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_characteristics_discover.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_characteristics_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_CHARACTERISTICS_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_handle_range != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_handle_range != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, *p_buf_len); - - index += uint16_encode(p_handle_range->start_handle, &p_buf[index]); - index += uint16_encode(p_handle_range->end_handle, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, - p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_descriptors_discover.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_descriptors_discover.c deleted file mode 100644 index 28e1a21..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_descriptors_discover.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_descriptors_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_DESCRIPTORS_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - p_buf[index++] = (p_handle_range == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_handle_range != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, *p_buf_len); - index += uint16_encode(p_handle_range->start_handle, &p_buf[index]); - index += uint16_encode(p_handle_range->end_handle, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_DESCRIPTORS_DISCOVER, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_app.h b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_app.h deleted file mode 100644 index 8ec3f63..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_app.h +++ /dev/null @@ -1,286 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_EVT_APP_H__ -#define BLE_GATTC_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gattc_evt_app GATTC Application event decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief GATTC Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_gattc_evt_char_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_disc_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_char_val_by_uuid_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_val_by_uuid_read_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_char_vals_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_vals_read_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_desc_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_desc_disc_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_hvx event. - * - * @sa @ref nrf51_gattc_evt_hvx_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_prim_srvc_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_prim_srvc_disc_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_read_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_rel_disc_rsp_dec event. - * - * @sa @ref nrf51_gattc_evt_rel_disc_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_timeout event. - * - * @sa @ref nrf51_gattc_evt_timeout_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_write_rsp event. - * - * @sa @ref nrf51_gattc_evt_write_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_disc_rsp.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_disc_rsp.c deleted file mode 100644 index cdc6532..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_disc_rsp.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "nordic_common.h" - - -uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(2 + 2 + 2 + 2, packet_len); - - uint16_t tmp_conn_handle; - uint16_t tmp_gatt_status; - uint16_t tmp_error_handle; - uint16_t tmp_service_count; - uint16_dec(p_buf, packet_len, &index, &tmp_conn_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_gatt_status); - uint16_dec(p_buf, packet_len, &index, &tmp_error_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_service_count); - - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.char_disc_rsp) + - sizeof (uint16_t) + tmp_service_count * sizeof (ble_gattc_char_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_CHAR_DISC_RSP; - p_event->header.evt_len = event_len; - p_event->evt.gattc_evt.conn_handle = tmp_conn_handle; - p_event->evt.gattc_evt.gatt_status = tmp_gatt_status; - p_event->evt.gattc_evt.error_handle = tmp_error_handle; - p_event->evt.gattc_evt.params.char_disc_rsp.count = tmp_service_count; - - SER_ASSERT_LENGTH_LEQ(index + (tmp_service_count * 9), packet_len); - - for (uint16_t i = 0; i < tmp_service_count; i++) - { - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.uuid); - uint8_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.type); - - uint8_t characteristic_props; - uint8_dec(p_buf, packet_len, &index, &characteristic_props); - - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.broadcast = - !!(characteristic_props & BIT_0); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.read = - !!(characteristic_props & BIT_1); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.write_wo_resp = - !!(characteristic_props & BIT_2); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.write = - !!(characteristic_props & BIT_3); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.notify = - !!(characteristic_props & BIT_4); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.indicate = - !!(characteristic_props & BIT_5); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.auth_signed_wr = - !!(characteristic_props & BIT_6); - - uint8_t characteristic_ext_props; - uint8_dec(p_buf, packet_len, &index, &characteristic_ext_props); - - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_ext_props = - characteristic_ext_props & BIT_0; - - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_decl); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_value); - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c deleted file mode 100644 index 93d89dc..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_util.h" -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_gattc_evt_app.h" - - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code; - uint16_t conn_handle; - uint16_t gatt_status; - uint16_t error_handle; - - SER_ASSERT_LENGTH_LEQ(6, packet_len - index); - - uint32_t in_event_len = *p_event_len; - - *p_event_len = (offsetof(ble_evt_t, evt.gattc_evt.params)) - sizeof (ble_evt_hdr_t); - - uint16_dec(p_buf, packet_len, &index, &conn_handle); - uint16_dec(p_buf, packet_len, &index, &gatt_status); - uint16_dec(p_buf, packet_len, &index, &error_handle); - - void * p_data = NULL; - - if (p_event) - { - SER_ASSERT_LENGTH_LEQ(*p_event_len, in_event_len); - - p_event->header.evt_id = BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP; - p_event->evt.gattc_evt.conn_handle = conn_handle; - p_event->evt.gattc_evt.gatt_status = gatt_status; - p_event->evt.gattc_evt.error_handle = error_handle; - - p_data = &p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp; - } - else - { - p_data = NULL; - } - - //call struct decoder with remaining size of event struct - uint32_t temp_event_len = in_event_len - *p_event_len; - err_code = ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(p_buf, packet_len, &index, - &temp_event_len, p_data); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - //update event length with the amount processed by struct decoder - *p_event_len += temp_event_len; - - if (p_event) - { - p_event->header.evt_len = *p_event_len; - } - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_vals_read_rsp.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_vals_read_rsp.c deleted file mode 100644 index 4e99a17..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_char_vals_read_rsp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_gattc_struct_serialization.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -#define BLE_GATTC_EVT_CHAR_VALS_READ_RSP_LEN_POSITION 6 - - -uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len = 0; - - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(10, packet_len); - - event_len = (uint16_t) (offsetof(ble_evt_t, evt.gattc_evt.params.char_vals_read_rsp.values)) - - sizeof (ble_evt_hdr_t) + - uint16_decode(&p_buf[BLE_GATTC_EVT_CHAR_VALS_READ_RSP_LEN_POSITION]); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - else - { - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - *p_event_len = event_len; - } - - p_event->header.evt_id = BLE_GATTC_EVT_CHAR_VALS_READ_RSP; - - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - - //Event structure for BLE_GATTC_EVT_CHAR_VALS_READ_RSP - error_code = - ble_gattc_evt_char_vals_read_rsp_t_dec(p_buf, packet_len, &index, - &(p_event->evt.gattc_evt.params.char_vals_read_rsp)); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return error_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_desc_disc_rsp.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_desc_disc_rsp.c deleted file mode 100644 index 6e44502..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_desc_disc_rsp.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 6, packet_len); - - uint16_t tmp_conn_handle; - uint16_t tmp_gatt_status; - uint16_t tmp_error_handle; - uint16_t tmp_service_count; - uint16_dec(p_buf, packet_len, &index, &tmp_conn_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_gatt_status); - uint16_dec(p_buf, packet_len, &index, &tmp_error_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_service_count); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.desc_disc_rsp) + - sizeof (uint16_t) + tmp_service_count * sizeof (ble_gattc_desc_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_DESC_DISC_RSP; - p_event->header.evt_len = event_len; - p_event->evt.gattc_evt.conn_handle = tmp_conn_handle; - p_event->evt.gattc_evt.gatt_status = tmp_gatt_status; - p_event->evt.gattc_evt.error_handle = tmp_error_handle; - p_event->evt.gattc_evt.params.desc_disc_rsp.count = tmp_service_count; - - SER_ASSERT_LENGTH_LEQ(index + (tmp_service_count * 5), packet_len); - - for (uint16_t i = 0; i < tmp_service_count; i++) - { - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].handle); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.uuid); - uint8_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.type); - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_hvx.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_hvx.c deleted file mode 100644 index f20f499..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_hvx.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint16_t tmp_attr_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(11, packet_len); - - tmp_attr_len = uint16_decode(&(p_buf[9])); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.hvx) + - sizeof (ble_gattc_evt_hvx_t) - 1 + tmp_attr_len; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_HVX; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.handle)); - uint8_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.type)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.len)); - - SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); - - if (tmp_attr_len > 0) - { - memcpy(&(p_event->evt.gattc_evt.params.hvx.data[0]), &(p_buf[index]), tmp_attr_len); - index += tmp_attr_len; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c deleted file mode 100644 index 85d43c0..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 6, packet_len); - - uint16_t tmp_conn_handle; - uint16_t tmp_gatt_status; - uint16_t tmp_error_handle; - uint16_t tmp_service_count; - uint16_dec(p_buf, packet_len, &index, &tmp_conn_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_gatt_status); - uint16_dec(p_buf, packet_len, &index, &tmp_error_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_service_count); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp) + - sizeof (uint16_t) + tmp_service_count * sizeof (ble_gattc_service_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP; - p_event->header.evt_len = event_len; - p_event->evt.gattc_evt.conn_handle = tmp_conn_handle; - p_event->evt.gattc_evt.gatt_status = tmp_gatt_status; - p_event->evt.gattc_evt.error_handle = tmp_error_handle; - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.count = tmp_service_count; - - SER_ASSERT_LENGTH_LEQ(index + (tmp_service_count * 7), packet_len); - - for (uint16_t i = 0; i < tmp_service_count; i++) - { - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.uuid); - uint8_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.type); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - start_handle); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - end_handle); - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_read_rsp.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_read_rsp.c deleted file mode 100644 index a851447..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_read_rsp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint16_t tmp_attr_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(12, packet_len); - - tmp_attr_len = uint16_decode(&(p_buf[10])); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.read_rsp) + - sizeof (ble_gattc_evt_read_rsp_t) - 1 + tmp_attr_len; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_READ_RSP; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.read_rsp.handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.read_rsp.offset)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.read_rsp.len)); - - SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); - - if (tmp_attr_len > 0) - { - memcpy(&(p_event->evt.gattc_evt.params.read_rsp.data[0]), &(p_buf[index]), tmp_attr_len); - index += tmp_attr_len; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_rel_disc_rsp.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_rel_disc_rsp.c deleted file mode 100644 index 7f0bd9f..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_rel_disc_rsp.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - -#define BLE_GATTC_EVT_REL_DISC_RSP_COUNT_POSITION 6 - - -uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len = 0; - uint16_t include_count = 0; - - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(8, packet_len); - - include_count = uint16_decode(&p_buf[BLE_GATTC_EVT_REL_DISC_RSP_COUNT_POSITION]); - event_len = (uint16_t) (offsetof(ble_evt_t, evt.gattc_evt.params.rel_disc_rsp.includes)) - - sizeof (ble_evt_hdr_t) + (include_count * sizeof (ble_gattc_include_t)); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_REL_DISC_RSP; - error_code = - uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = - ble_gattc_evt_rel_disc_rsp_t_dec(p_buf, packet_len, &index, - &(p_event->evt.gattc_evt.params.rel_disc_rsp)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return error_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_timeout.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_timeout.c deleted file mode 100644 index 8f831d3..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_timeout.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - event_len = offsetof(ble_evt_t, evt.gattc_evt.params.timeout) + - sizeof (ble_gattc_evt_timeout_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_TIMEOUT; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gattc_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gattc_evt.params.timeout.src); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_write_rsp.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_write_rsp.c deleted file mode 100644 index bfed5e2..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_evt_write_rsp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(13, packet_len); - - uint16_t tmp_attr_len = uint16_decode(&(p_buf[11])); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.write_rsp) + - sizeof (ble_gattc_evt_write_rsp_t) - 1 + tmp_attr_len; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_WRITE_RSP; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.handle)); - uint8_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.write_op)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.offset)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.len)); - - SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); - - if (tmp_attr_len > 0) - { - memcpy(&(p_event->evt.gattc_evt.params.write_rsp.data[0]), &(p_buf[index]), tmp_attr_len); - index += tmp_attr_len; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_hv_confirm.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_hv_confirm.c deleted file mode 100644 index f745640..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_hv_confirm.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle, - uint16_t handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GATTC_HV_CONFIRM; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - -uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_HV_CONFIRM, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_primary_services_discover.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_primary_services_discover.c deleted file mode 100644 index 762508b..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_primary_services_discover.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle, - uint16_t start_handle, - ble_uuid_t const * const p_srvc_uuid, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 5, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - index += uint16_encode(start_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - - p_buf[index++] = (p_srvc_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_srvc_uuid != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - index += uint16_encode(p_srvc_uuid->uuid, &p_buf[index]); - p_buf[index++] = p_srvc_uuid->type; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, - p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_read.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_read.c deleted file mode 100644 index 1d4b5ec..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_read.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_read_req_enc(uint16_t conn_handle, - uint16_t handle, - uint16_t offset, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 7, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_READ; - index += uint16_encode(conn_handle, &p_buf[index]); - index += uint16_encode(handle, &p_buf[index]); - index += uint16_encode(offset, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_READ, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_relationships_discover.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_relationships_discover.c deleted file mode 100644 index 943457e..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_relationships_discover.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_relationships_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_RELATIONSHIPS_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_handle_range != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_handle_range != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 4, *p_buf_len); - - index += uint16_encode(p_handle_range->start_handle, &p_buf[index]); - index += uint16_encode(p_handle_range->end_handle, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, - p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gattc_write.c b/components/serialization/application/codecs/s110/serializers/ble_gattc_write.c deleted file mode 100644 index edfe93a..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gattc_write.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_write_req_enc(uint16_t conn_handle, - ble_gattc_write_params_t const * const p_write_params, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 4, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_WRITE; - index += uint16_encode(conn_handle, &p_buf[index]); - p_buf[index++] = (p_write_params == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_write_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 9, *p_buf_len); - p_buf[index++] = p_write_params->write_op; - p_buf[index++] = p_write_params->flags; - index += uint16_encode(p_write_params->handle, &p_buf[index]); - index += uint16_encode(p_write_params->offset, &p_buf[index]); - index += uint16_encode(p_write_params->len, &p_buf[index]); - - SER_ERROR_CHECK(p_write_params->len <= BLE_GATTC_WRITE_P_VALUE_LEN_MAX, - NRF_ERROR_INVALID_PARAM); - - p_buf[index++] = (p_write_params->p_value == NULL) ? - SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_write_params->p_value != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + p_write_params->len, *p_buf_len); - memcpy(&p_buf[index], p_write_params->p_value, p_write_params->len); - index += p_write_params->len; - } - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_WRITE, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_app.h b/components/serialization/application/codecs/s110/serializers/ble_gatts_app.h deleted file mode 100644 index ab889d7..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_app.h +++ /dev/null @@ -1,554 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_APP_H__ -#define BLE_GATTS_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gatts_app GATTS Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief GATTS Application command request encoders and command response decoders. - */ -#include "ble_gatts.h" -#include "ble.h" - -/**@brief Encodes @ref sd_ble_gatts_value_get command request. - * - * @sa @ref nrf51_gatts_value_get_encoding for packet format, - * @ref ble_gatts_value_get_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] handle Attribute handle. - * @param[in] p_value Pointer to attribute value information. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_data_len and \p p_data will not be updated by the command - * request encoder. Updated values are set by @ref ble_gatts_value_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t const * const p_value, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_value_get command. - * - * @sa @ref nrf51_gatts_value_get_encoding for packet format, - * @ref ble_gatts_value_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_value Pointer to structure where the attribute value will be stored. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Length of \p p_value is too small to hold decoded - * value from response. - */ -uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gatts_value_t * const p_value, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_hvx command request. - * - * @sa @ref nrf51_gatts_hvx_encoding for packet format, - * @ref ble_gatts_hvx_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_hvx_params Pointer to an HVx parameters structure to be encoded. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_hvx_params will not be updated by the command - * request encoder. Updated values are set by @ref ble_gatts_hvx_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle, - ble_gatts_hvx_params_t const * const p_hvx_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_hvx command. - * - * @sa @ref nrf51_gatts_hvx_encoding for packet format, - * @ref ble_gatts_hvx_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * @param[out] pp_bytes_written Pointer to pointer to location where number of bytes is written. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - uint16_t * * const pp_bytes_written); - -/**@brief Encodes @ref sd_ble_gatts_characteristic_add command request. - * - * @sa @ref nrf51_characteristics_add_encoding for packet format, - * @ref ble_gatts_characteristic_add_rsp_dec for command response decoder. - * - * @param[in] service_handle Handle of the service where the characteristic is to be placed. - * If @ref BLE_GATT_HANDLE_INVALID is used, it will be placed - * sequentially. - * @param[in] p_char_md Pointer to a @ref ble_gatts_char_md_t structure, characteristic - * metadata. - * @param[in] p_attr_char_value Pointer to a @ref ble_gatts_attr_t structure, corresponding to - * the characteristic value. - * @param[in] p_handles Pointer to a @ref ble_gatts_char_handles_t structure, where the - * assigned handles will be stored. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_handles will not be updated by the command - * request encoder. Updated values are set by @ref ble_gatts_characteristic_add_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_characteristic_add_req_enc - (uint16_t service_handle, - ble_gatts_char_md_t const * const p_char_md, - ble_gatts_attr_t const * const p_attr_char_value, - ble_gatts_char_handles_t const * const p_handles, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_characteristic_add command. - * - * @sa @ref nrf51_characteristics_add_encoding for packet format, - * @ref ble_gatts_characteristic_add_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_handles Pointer to pointer to location where handles should be decoded. - * @param[out] p_result_code Pointer to command result code decode location. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * * const pp_handles, - uint32_t * const p_result_code); - - -/**@brief Encodes @ref sd_ble_gatts_service_add command request. - * - * @sa @ref nrf51_gatts_service_add_encoding for packet format, - * @ref ble_gatts_service_add_rsp_dec for command response decoder. - * - * @param[in] type Toggles between primary and secondary services, - * see @ref BLE_GATTS_SRVC_TYPES. - * @param[in] p_uuid Pointer to service UUID. - * @param[in] p_conn_handle Pointer to a 16-bit word where the assigned handle will be stored. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_conn_handle will not be updated by the command - * request encoder. Updated values are set by @ref ble_gatts_service_add_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_service_add_req_enc(uint8_t type, - ble_uuid_t const * const p_uuid, - uint16_t const * const p_conn_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_service_add command. - * - * @sa @ref nrf51_gatts_service_add_encoding for packet format, - * @ref ble_gatts_service_add_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Connection handle. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_sys_attr_set command request. - * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format, - * @ref ble_gatts_sys_attr_set_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_sys_attr_data Pointer to a buffer (at least \p sys_attr_data_len bytes long) - * containing the attribute value to write. - * @param[in] sys_attr_data_len Length (in bytes) of \p p_sys_attr_data. - * @param[in] flags Optional additional flags. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t sys_attr_data_len, - uint32_t flags, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_sys_attr_set command. - * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format, - * @ref ble_gatts_sys_attr_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_value_set command request. - * - * @sa @ref nrf51_gatts_value_set_encoding for packet format, - * @ref ble_gatts_value_set_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] handle Attribute handle. - * @param[in] p_value Pointer to attribute value information. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t * p_value, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_value_set command. - * - * @sa @ref nrf51_gatts_value_set_encoding for packet format, - * @ref ble_gatts_value_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_value Pointer to attribute value information.. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gatts_value_t * const p_value, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_sys_attr_get command request. - * - * @sa @ref nrf51_gatts_sys_attr_get_encoding for packet format, - * @ref ble_gatts_sys_attr_get_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_sys_attr_data Pointer to buffer where updated information about system - * attributes will be stored. Can be NULL to calculate required - * size. - * @param[in] p_sys_attr_data_len Size of p_sys_attr_data buffer if \p p_sys_attr_data is - * not NULL. - * @param[in] flags Additional optional flags. - * @param[in,out] p_buf Pointer to buffer where encoded data command will - * be returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_sys_attr_data and \p p_sys_attr_data_len will not be updated by the command - * request encoder. Updated values are set by @ref ble_gatts_sys_attr_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t const * const p_sys_attr_data_len, - uint32_t flags, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_sys_attr_get command. - * - * @sa @ref nrf51_gatts_sys_attr_get_encoding for packet format, - * @ref ble_gatts_sys_attr_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system - * attributes will be stored. - * @param[in,out] p_sys_attr_data_len \c in: Size (in bytes) of \p p_sys_attr_data buffer. - * \c out: Length of decoded contents of \p p_sys_attr_data. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Length of \p p_sys_attr_data is too small to hold decoded - * value from response. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_sys_attr_data, - uint16_t * const p_sys_attr_data_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_descriptor_add command request. - * - * @sa @ref nrf51_descriptor_add_encoding for packet format, - * @ref ble_gatts_descriptor_add_rsp_dec for command response decoder. - * - * @param[in] char_handle Handle of the characteristic where the description is to be placed. - * If @ref BLE_GATT_HANDLE_INVALID is used, it will be placed - * sequentially. - * @param[in] p_attr Pointer to a @ref ble_gatts_attr_t structure, characteristic - * metadata. - * @param[in] p_handle Pointer to a @ref ble_gatts_char_handles_t structure, where the - * assigned handles will be stored. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_handle, - ble_gatts_attr_t const * const p_attr, - uint16_t * const p_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_descriptor_add command. - * - * @sa @ref nrf51_descriptor_add_encoding for packet format, - * @ref ble_gatts_descriptor_add_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_handle Pointer to bufer where descriptor handle will be - returned. - * @param[out] p_result_code Pointer to command result code decode location. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_handle, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_include_add command request. - * - * @sa @ref nrf51_gatts_include_add_encoding for packet format, - * @ref ble_gatts_include_add_rsp_dec for command response decoder. - * - * @param[in] service_handle Handle of the service where the included service is to be placed. - * @param[in] inc_srvc_handle Handle of the included service - * @param[in] p_include_handle Pointer to Pointer to a 16-bit word where the assigned handle will be stored. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle, - uint16_t inc_srvc_handle, - uint16_t * const p_include_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_include_add command. - * - * @sa @ref nrf51_gatts_include_add_encoding for packet format, - * @ref ble_gatts_include_add_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. - * @param[out] p_result_code Pointer to command result code decode location. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_include_handle, - uint32_t * const p_result_code); - - -/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command request. - * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format, - * @ref ble_gatts_rw_authorize_reply_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_reply_params Pointer to \ref ble_gatts_rw_authorize_reply_params_t - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params. - */ -uint32_t ble_gatts_rw_authorize_reply_req_enc( - uint16_t conn_handle, - ble_gatts_rw_authorize_reply_params_t const * const - p_reply_params, - uint8_t * const - p_buf, - uint32_t * const - p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_rw_authorize_reply command. - * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format, - * @ref ble_gatts_rw_authorize_reply_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_service_changed command request. - * - * @sa @ref nrf51_service_changed_encoding for packet format, - * @ref ble_gatts_service_changed_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] start_handle Start of affected attribute handle range. - * @param[in] end_handle End of affected attribute handle range. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params. - */ -uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_service_changed command. - * - * @sa @ref nrf51_service_changed_encoding for packet format, - * @ref ble_gatts_service_changed_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** @} */ -#endif //BLE_GATTS_APP_H__ - - diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_characteristic_add.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_characteristic_add.c deleted file mode 100644 index 75e164d..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_characteristic_add.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - -uint32_t ble_gatts_characteristic_add_req_enc( - uint16_t service_handle, - ble_gatts_char_md_t const * const p_char_md, - ble_gatts_attr_t const * const p_attr_char_value, - ble_gatts_char_handles_t const * const p_handles, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint8_t opcode = SD_BLE_GATTS_CHARACTERISTIC_ADD; - uint32_t buf_len = *p_buf_len; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&service_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md, p_buf, buf_len, &index, ble_gatts_char_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_attr_char_value, p_buf, buf_len, &index, ble_gatts_attr_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_handles, p_buf, buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * * const pp_handles, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, buf_len, - SD_BLE_GATTS_CHARACTERISTIC_ADD, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, buf_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, - buf_len, - &index, - (void * *)pp_handles, - ble_gatts_char_handles_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_descriptor_add.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_descriptor_add.c deleted file mode 100644 index ea895bb..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_descriptor_add.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - - -#include "ble_gatts_app.h" -#include -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - - -uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_handle, - ble_gatts_attr_t const * const p_attr, - uint16_t * const p_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - p_buf[index++] = SD_BLE_GATTS_DESCRIPTOR_ADD; - - uint32_t err_code = uint16_t_enc(&char_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_attr, - p_buf, - *p_buf_len, - &index, - ble_gatts_attr_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_handle != NULL) ? SER_FIELD_PRESENT : - SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_handle, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_DESCRIPTOR_ADD, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - SER_ASSERT_NOT_NULL(p_handle); - - uint16_dec(p_buf, packet_len, &index, p_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_app.h b/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_app.h deleted file mode 100644 index 7ea133e..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_app.h +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_EVT_APP_H__ -#define BLE_GATTS_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gatts_evt_app GATTS Application event decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief GATTS Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_gatts_evt_hvc event. - * - * @sa @ref nrf51_gatts_evt_hvc_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gatts_evt_rw_authorize_request event. - * - * @sa @ref nrf51_evt_rw_authorize_request for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gatts_evt_sc_confirm event. - * - * @sa @ref nrf51_gatts_evt_sc_confirm_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gatts_evt_sys_attr_missing event. - * - * @sa @ref nrf51_evt_sys_attr_missing_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gatts_evt_timeout event. - * - * @sa @ref nrf51_gatts_evt_timeout_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gatts_evt_write event. - * - * @sa @ref nrf51_evt_write_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_hvc.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_hvc.c deleted file mode 100644 index 2c1c5aa..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_hvc.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gatts_evt_hvc_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_HVC; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.conn_handle); - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.params.hvc.handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_rw_authorize_request.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_rw_authorize_request.c deleted file mode 100644 index 86f1b35..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_rw_authorize_request.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t in_event_len = *p_event_len; - - *p_event_len = offsetof(ble_evt_t, evt.gatts_evt.params) - sizeof (ble_evt_hdr_t); - - uint16_t conn_handle; - err_code = uint16_t_dec(p_buf, packet_len, &index, &conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - void * p_void_authorize_request = NULL; - - if (p_event != NULL) - { - SER_ASSERT_LENGTH_LEQ(*p_event_len, in_event_len); - - p_event->header.evt_id = BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST; - p_event->evt.gatts_evt.conn_handle = conn_handle; - - p_void_authorize_request = &(p_event->evt.gatts_evt.params.authorize_request); - } - uint32_t tmp_event_len = in_event_len - *p_event_len; - err_code = ble_gatts_evt_rw_authorize_request_t_dec(p_buf, - packet_len, - &index, - &tmp_event_len, - p_void_authorize_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_event_len += tmp_event_len; - - if(p_event != NULL) - { - if((p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)) - { - uint32_t conn_index; - - if(app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_dec(p_buf, packet_len, &index, &m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_sc_confirm.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_sc_confirm.c deleted file mode 100644 index d8d440f..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_sc_confirm.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_SC_CONFIRM; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.conn_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_sys_attr_missing.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_sys_attr_missing.c deleted file mode 100644 index 8b17268..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_sys_attr_missing.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gatts_evt.params.sys_attr_missing)) + - sizeof (ble_gatts_evt_sys_attr_missing_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_SYS_ATTR_MISSING; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.params.sys_attr_missing.hint); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_timeout.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_timeout.c deleted file mode 100644 index fba0b11..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_timeout.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gatts_evt_timeout_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_TIMEOUT; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.params.timeout.src); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_write.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_write.c deleted file mode 100644 index d6e7918..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_evt_write.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - uint32_t in_event_len = *p_event_len; - - *p_event_len = offsetof(ble_evt_t, evt.gatts_evt.params) - sizeof (ble_evt_hdr_t); - - uint16_t conn_handle; - err_code = uint16_t_dec(p_buf, packet_len, &index, &conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - void * p_void_write = NULL; - - if (p_event != NULL) - { - SER_ASSERT_LENGTH_LEQ(*p_event_len, in_event_len); - p_event->evt.gatts_evt.conn_handle = conn_handle; - - p_void_write = &(p_event->evt.gatts_evt.params.write); - } - - uint32_t tmp_struct_len = in_event_len - *p_event_len; - err_code = ble_gatts_evt_write_t_dec(p_buf, - packet_len, - &index, - &tmp_struct_len, - p_void_write); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_event_len += tmp_struct_len; - - if(p_event != NULL) - { - if(p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) - { - uint32_t conn_index; - - if(app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_dec(p_buf, packet_len, &index, &m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_hvx.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_hvx.c deleted file mode 100644 index 4682af8..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_hvx.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle, - ble_gatts_hvx_params_t const * const p_hvx_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT(p_hvx_params == NULL || - !(p_hvx_params->p_len == NULL && p_hvx_params->p_data != NULL), NRF_ERROR_NULL); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTS_HVX; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_hvx_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_hvx_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2 + 1 + 2 + 2, *p_buf_len); - index += uint16_encode(p_hvx_params->handle, &p_buf[index]); - p_buf[index++] = p_hvx_params->type; - index += uint16_encode(p_hvx_params->offset, &p_buf[index]); - - if (p_hvx_params->p_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - SER_ERROR_CHECK(*p_hvx_params->p_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, - NRF_ERROR_INVALID_PARAM); - p_buf[index++] = SER_FIELD_PRESENT; - index += uint16_encode(*(p_hvx_params->p_len), &p_buf[index]); - - if (p_hvx_params->p_data != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + *(p_hvx_params->p_len), *p_buf_len); - p_buf[index++] = SER_FIELD_PRESENT; - memcpy(&(p_buf[index]), p_hvx_params->p_data, *(p_hvx_params->p_len)); - index += *(p_hvx_params->p_len); - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - uint16_t * * const pp_bytes_written) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code; - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_HVX, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_bytes_written, uint16_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_include_add.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_include_add.c deleted file mode 100644 index cb991a8..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_include_add.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle, - uint16_t inc_srvc_handle, - uint16_t * const p_include_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_LENGTH_LEQ(6, *p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint32_t err_code; - uint8_t opCode = SD_BLE_GATTS_INCLUDE_ADD; - uint8_t presenceFlag; - - err_code = uint8_t_enc(&opCode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = uint16_t_enc(&service_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = uint16_t_enc(&inc_srvc_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - presenceFlag = (p_include_handle != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - err_code = uint8_t_enc(&presenceFlag, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - *p_buf_len = index; - return err_code; - -} - - -uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_include_handle, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - uint32_t err_code; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GATTS_INCLUDE_ADD, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - SER_ASSERT_NOT_NULL(p_include_handle); - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - err_code = uint16_t_dec(p_buf, packet_len, &index, p_include_handle); - SER_ASSERT_LENGTH_EQ(index, packet_len); - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_rw_authorize_reply.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_rw_authorize_reply.c deleted file mode 100644 index f792b7e..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_rw_authorize_reply.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - -uint32_t ble_gatts_rw_authorize_reply_req_enc( - uint16_t conn_handle, - ble_gatts_rw_authorize_reply_params_t const * const - p_reply_params, - uint8_t * const - p_buf, - uint32_t * const - p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_GATTS_RW_AUTHORIZE_REPLY; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_reply_params, p_buf, buf_len, &index, - ble_gatts_rw_authorize_reply_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_RW_AUTHORIZE_REPLY, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_service_add.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_service_add.c deleted file mode 100644 index 443c660..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_service_add.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_service_add_req_enc(uint8_t type, - ble_uuid_t const * const p_uuid, - uint16_t const * const p_conn_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1 + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTS_SERVICE_ADD; - p_buf[index++] = type; - - p_buf[index++] = (p_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_uuid != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - index += uint16_encode(p_uuid->uuid, &p_buf[index]); - p_buf[index++] = p_uuid->type; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_conn_handle != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GATTS_SERVICE_ADD, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_conn_handle); - - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return decode_result; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_service_changed.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_service_changed.c deleted file mode 100644 index aba707e..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_service_changed.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code; - uint8_t opcode = SD_BLE_GATTS_SERVICE_CHANGED; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - err_code = uint8_t_enc(&opcode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&start_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&end_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_SERVICE_CHANGED, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_sys_attr_get.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_sys_attr_get.c deleted file mode 100644 index 6f36b20..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_sys_attr_get.c +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t const * const p_sys_attr_data_len, - uint32_t flags, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1 + 4, *p_buf_len); - p_buf[index++] = SD_BLE_GATTS_SYS_ATTR_GET; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_sys_attr_data_len != NULL) ? SER_FIELD_PRESENT : - SER_FIELD_NOT_PRESENT; - - if (p_sys_attr_data_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - index += uint16_encode(*p_sys_attr_data_len, &p_buf[index]); - } - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_sys_attr_data != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - err_code = uint32_t_enc(&flags, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_sys_attr_data, - uint16_t * const p_sys_attr_data_len, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_SYS_ATTR_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 2 + 1, packet_len); - - uint16_t sys_attr_len; - uint16_dec(p_buf, packet_len, &index, &sys_attr_len); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - SER_ASSERT_NOT_NULL(p_sys_attr_data); - SER_ASSERT_NOT_NULL(p_sys_attr_data_len); - SER_ASSERT(sys_attr_len <= *p_sys_attr_data_len, NRF_ERROR_DATA_SIZE); - - SER_ASSERT_LENGTH_LEQ(index + sys_attr_len, packet_len); - memcpy(p_sys_attr_data, &p_buf[index], sys_attr_len); - *p_sys_attr_data_len = sys_attr_len; - index += sys_attr_len; - } - else - { - if (p_sys_attr_data_len != NULL) - { - *p_sys_attr_data_len = sys_attr_len; - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_sys_attr_set.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_sys_attr_set.c deleted file mode 100644 index b8830a6..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_sys_attr_set.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t sys_attr_data_len, - uint32_t flags, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 8, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTS_SYS_ATTR_SET; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_sys_attr_data != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_sys_attr_data != NULL) - { - //lint -save -esym(670,memcpy) - SER_ERROR_CHECK(sys_attr_data_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); - SER_ASSERT_LENGTH_LEQ(index + 2 + sys_attr_data_len + 4, *p_buf_len); - index += uint16_encode(sys_attr_data_len, &p_buf[index]); - memcpy(&(p_buf[index]), p_sys_attr_data, sys_attr_data_len); - //lint -restore - index += sys_attr_data_len; - } - - err_code = uint32_t_enc(&flags, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_SYS_ATTR_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_value_get.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_value_get.c deleted file mode 100644 index 54d5844..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_value_get.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - -uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t const * const p_value, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(1 + 2 + 2 + 1, total_len); - p_buf[index++] = SD_BLE_GATTS_VALUE_GET; - - err_code = uint16_t_enc(&conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_value != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - err_code = uint16_t_enc(&(p_value->len), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_value->offset), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, total_len - index); - if (p_value->p_value != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gatts_value_t * const p_value, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - SER_ASSERT_NOT_NULL(p_value); - - uint32_t err_code; - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, - packet_len, SD_BLE_GATTS_VALUE_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = ble_gatts_value_t_dec(p_buf, packet_len, &index, p_value); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_gatts_value_set.c b/components/serialization/application/codecs/s110/serializers/ble_gatts_value_set.c deleted file mode 100644 index e11cffc..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_gatts_value_set.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "nrf_error.h" -#include "cond_field_serialization.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t * p_value, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1 + 2 + 2, *p_buf_len); - p_buf[index++] = SD_BLE_GATTS_VALUE_SET; - index += uint16_encode(conn_handle, &p_buf[index]); - index += uint16_encode(handle, &p_buf[index]); - - if(p_value != NULL) - { - SER_ERROR_CHECK(p_value->len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); - } - err_code = cond_field_enc(p_value, p_buf, *p_buf_len, &index, ble_gatts_value_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gatts_value_t * const p_value, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_VALUE_SET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = ble_gatts_value_t_dec(p_buf, packet_len, &index, p_value); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_l2cap_app.h b/components/serialization/application/codecs/s110/serializers/ble_l2cap_app.h deleted file mode 100644 index 9a20fae..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_l2cap_app.h +++ /dev/null @@ -1,163 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * - */ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_l2cap_app L2CAP Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief L2CAP Application command request encoders and command response decoders. - */ - -#ifndef BLE_L2CAP_APP_H__ -#define BLE_L2CAP_APP_H__ - -#include "ble.h" -#include "ble_types.h" -#include "ble_ranges.h" -#include "ble_err.h" -#include "ble_l2cap.h" - -/**@brief Register a CID with L2CAP. - * - * @details This registers a higher protocol layer with the L2CAP multiplexer, and is requried prior to all operations on the CID. - * - * @param[in] cid L2CAP CID. - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_l2cap_cid_register command. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_l2cap_cid_register_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Unregister a CID with L2CAP. - * - * @details This unregisters a previously registered higher protocol layer with the L2CAP multiplexer. - * - * @param[in] cid L2CAP CID. - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_l2cap_cid_unregister command. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_l2cap_cid_unregister_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Transmit an L2CAP packet. - * - * @note It is important to note that a call to this function will consume an application buffer, and will therefore - * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. - * Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. - * - * @param[in] conn_handle Connection Handle. - * @param[in] p_l2cap_header Pointer to a packet header containing length and CID. - * @param[in] p_data Pointer to the data to be transmitted. - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @return @ref NRF_SUCCESS Successfully queued an L2CAP packet for transmission. - * @return @ref NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @return @ref NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register. - * @return @ref NRF_ERROR_NOT_FOUND CID not found. - * @return @ref NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @return @ref BLE_ERROR_NO_TX_BUFFERS Not enough application buffers available. - * @return @ref NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF. - */ -uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle, - ble_l2cap_header_t const * const p_l2cap_header, - uint8_t const * const p_data, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_l2cap_tx command. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_l2cap_tx_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - - -#endif //BLE_L2CAP_APP_H__ - -/** - @} - */ diff --git a/components/serialization/application/codecs/s110/serializers/ble_l2cap_cid_register.c b/components/serialization/application/codecs/s110/serializers/ble_l2cap_cid_register.c deleted file mode 100644 index de597fe..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_l2cap_cid_register.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - -uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - p_buf[index++] = SD_BLE_L2CAP_CID_REGISTER; - err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_REGISTER, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_l2cap_cid_unregister.c b/components/serialization/application/codecs/s110/serializers/ble_l2cap_cid_unregister.c deleted file mode 100644 index cd6e65a..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_l2cap_cid_unregister.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - -uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - p_buf[index++] = SD_BLE_L2CAP_CID_UNREGISTER; - err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_UNREGISTER, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_l2cap_evt_app.h b/components/serialization/application/codecs/s110/serializers/ble_l2cap_evt_app.h deleted file mode 100644 index 8076030..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_l2cap_evt_app.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_L2CAP_EVT_APP_H__ -#define BLE_L2CAP_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_l2cap_evt_app L2CAP Application event decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief L2CAP Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_l2cap_evt_rx event. - * - * @sa @ref nrf51_l2cap_evt_rx_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s110/serializers/ble_l2cap_evt_rx.c b/components/serialization/application/codecs/s110/serializers/ble_l2cap_evt_rx.c deleted file mode 100644 index d54682a..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_l2cap_evt_rx.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" -#include "ble_l2cap_evt_app.h" - -uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t in_event_len = *p_event_len; - - *p_event_len = offsetof(ble_l2cap_evt_t, params); - - uint16_t evt_id; - - uint32_t err_code = uint16_t_dec(p_buf, packet_len, &index, &evt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - void * p_rx = NULL; - - if (p_event) - { - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.l2cap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_rx = &(p_event->evt.l2cap_evt.params.rx); - } - - uint32_t struct_len = in_event_len - *p_event_len; - err_code = ble_l2cap_evt_rx_t_dec(p_buf, packet_len, &index, &struct_len, p_rx); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_event_len += struct_len; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_l2cap_tx.c b/components/serialization/application/codecs/s110/serializers/ble_l2cap_tx.c deleted file mode 100644 index 83baa90..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_l2cap_tx.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_l2cap_app.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gap.h" -#include "app_util.h" -#include "cond_field_serialization.h" - -uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle, - ble_l2cap_header_t const * const p_l2cap_header, - uint8_t const * const p_data, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - p_buf[index++] = SD_BLE_L2CAP_TX; - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_l2cap_header, p_buf, *p_buf_len, &index, ble_l2cap_header_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_l2cap_header != NULL) - { - err_code = buf_enc(p_data, p_l2cap_header->len, p_buf, *p_buf_len, &index); - } - else - { - err_code = buf_enc(NULL, 0, p_buf, *p_buf_len, &index); - } - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_TX, p_result_code); -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_opt_get.c b/components/serialization/application/codecs/s110/serializers/ble_opt_get.c deleted file mode 100644 index 7728d66..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_opt_get.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_get_req_enc(uint32_t opt_id, - ble_opt_t const * const p_opt, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_LENGTH_LEQ(1+4+1, *p_buf_len); // [OPCODE][OP_ID][PRESENT] - SER_ASSERT(((opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (opt_id == BLE_GAP_OPT_CH_MAP) || - (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (opt_id == BLE_GAP_OPT_PASSKEY) || - (opt_id == BLE_GAP_OPT_PRIVACY) || - (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (opt_id == BLE_GAP_OPT_COMPAT_MODE)) , NRF_ERROR_INVALID_PARAM); - - p_buf[index++] = SD_BLE_OPT_GET; - - err_code = uint32_t_enc(&opt_id, p_buf, *p_buf_len, &index); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - p_buf[index++] = (p_opt == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - -uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t * const p_opt, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_NOT_NULL(p_opt); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_OPT_GET, - p_result_code); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - (void) uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (*p_opt_id == BLE_GAP_OPT_CH_MAP) || - (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (*p_opt_id == BLE_GAP_OPT_PASSKEY) || - (*p_opt_id == BLE_GAP_OPT_PRIVACY) || - (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - switch (*p_opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->common_opt.radio_cpu_mutex)); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.ch_map)); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.local_conn_latency)); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.passkey)); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.privacy)); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.scan_req_report)); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.compat_mode)); - break; - } - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - diff --git a/components/serialization/application/codecs/s110/serializers/ble_opt_set.c b/components/serialization/application/codecs/s110/serializers/ble_opt_set.c deleted file mode 100644 index d6772b0..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_opt_set.c +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_opt_set_req_enc(uint32_t const opt_id, - ble_opt_t const * const p_opt, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t initial_buf_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(1 + 4 + 1, initial_buf_len); - - SER_ASSERT(((opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (opt_id == BLE_GAP_OPT_CH_MAP) || - (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (opt_id == BLE_GAP_OPT_PASSKEY) || - (opt_id == BLE_GAP_OPT_PRIVACY) || - (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - p_buf[index++] = SD_BLE_OPT_SET; - - err_code = uint32_t_enc(&opt_id, p_buf, initial_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_opt != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - - switch(opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_enc(&(p_opt->common_opt.radio_cpu_mutex),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_enc(&(p_opt->gap_opt.ch_map),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_enc(&(p_opt->gap_opt.local_conn_latency),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_enc(&(p_opt->gap_opt.passkey),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_enc(&(p_opt->gap_opt.privacy),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_enc(&(p_opt->gap_opt.scan_req_report),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_enc(&(p_opt->gap_opt.compat_mode),p_buf, initial_buf_len, &index); - break; - } - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - uint32_t error_code; - - error_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_OPT_SET, p_result_code); - - if (error_code != NRF_SUCCESS) - { - return error_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_tx_buffer_count_get.c b/components/serialization/application/codecs/s110/serializers/ble_tx_buffer_count_get.c deleted file mode 100644 index 944fe63..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_tx_buffer_count_get.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" - -uint32_t ble_tx_buffer_count_get_req_enc(uint8_t const * const p_count, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint8_t opcode = SD_BLE_TX_BUFFER_COUNT_GET; - uint32_t err_code; - uint32_t total_len = *p_buf_len; - - err_code = uint8_t_enc(&opcode, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_count, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_tx_buffer_count_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * const pp_count, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_TX_BUFFER_COUNT_GET, p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_count, uint8_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_user_mem_reply.c b/components/serialization/application/codecs/s110/serializers/ble_user_mem_reply.c deleted file mode 100644 index ce19d40..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_user_mem_reply.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle, - ble_user_mem_block_t const * p_block, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - p_buf[index++] = SD_BLE_USER_MEM_REPLY; - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len - index); - if(p_block != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - - // Encoding order is different than structure elements order because - // mem block length should be sent first - err_code = uint16_t_enc(&(p_block->len), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_block->p_mem, p_buf, *p_buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_USER_MEM_REPLY, p_result_code); -} - - diff --git a/components/serialization/application/codecs/s110/serializers/ble_uuid_decode.c b/components/serialization/application/codecs/s110/serializers/ble_uuid_decode.c deleted file mode 100644 index 5c3e006..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_uuid_decode.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len, - uint8_t const * const p_uuid_le, - ble_uuid_t * const p_uuid, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code; - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_UUID_DECODE; - - err_code = uint8_t_enc((void *)&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len8data_enc(p_uuid_le, uuid_le_len, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_uuid, p_buf, buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - ble_uuid_t * * const pp_uuid, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code; - uint32_t index = 0; - - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - buf_len, - SD_BLE_UUID_DECODE, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, buf_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_uuid_encode.c b/components/serialization/application/codecs/s110/serializers/ble_uuid_encode.c deleted file mode 100644 index 5eb8099..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_uuid_encode.c +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, - uint8_t const * const p_uuid_le_len, - uint8_t const * const p_uuid_le, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_UUID_ENCODE; - - p_buf[index++] = (p_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_uuid != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - index += uint16_encode(p_uuid->uuid, &p_buf[index]); - p_buf[index++] = p_uuid->type; - } - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - p_buf[index++] = (p_uuid_le_len == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - p_buf[index++] = (p_uuid_le == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_uuid_le_len, - uint8_t * const p_uuid_le, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - uint32_t error_code; - - error_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_UUID_ENCODE, p_result_code); - - if (error_code != NRF_SUCCESS) - { - return error_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, packet_len); - uint8_t uuid_le_len = p_buf[index++]; - - if (p_uuid_le_len != NULL) - { - if (p_uuid_le != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + uuid_le_len, packet_len); - memcpy(p_uuid_le, &(p_buf[index]), uuid_le_len); - index += uuid_le_len; - } - *p_uuid_le_len = uuid_le_len; - } - - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_uuid_vs_add.c b/components/serialization/application/codecs/s110/serializers/ble_uuid_vs_add.c deleted file mode 100644 index 0f686f1..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_uuid_vs_add.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid, - uint8_t * const p_uuid_type, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code; - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_UUID_VS_ADD; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_vs_uuid, p_buf, buf_len, &index, ble_uuid128_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_uuid_type, p_buf, buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * * const pp_uuid_type, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - SER_ASSERT_NOT_NULL(pp_uuid_type); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - buf_len, - SD_BLE_UUID_VS_ADD, - p_result_code); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, buf_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid_type, uint8_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s110/serializers/ble_version_get.c b/components/serialization/application/codecs/s110/serializers/ble_version_get.c deleted file mode 100644 index 0485b4f..0000000 --- a/components/serialization/application/codecs/s110/serializers/ble_version_get.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_version_get_req_enc(ble_version_t const * const p_version, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_VERSION_GET; - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - - p_buf[index++] = (p_version == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - -uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_version_t * p_version, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t status_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_VERSION_GET, - p_result_code); - - if (status_code != NRF_SUCCESS) - { - return status_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - uint8_dec(p_buf, packet_len, &index, &(p_version->version_number)); - uint16_dec(p_buf, packet_len, &index, &(p_version->company_id)); - uint16_dec(p_buf, packet_len, &index, &p_version->subversion_number); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return status_code; -} - - diff --git a/components/serialization/application/codecs/s110/serializers/nrf_soc_app.h b/components/serialization/application/codecs/s110/serializers/nrf_soc_app.h deleted file mode 100644 index 1f89530..0000000 --- a/components/serialization/application/codecs/s110/serializers/nrf_soc_app.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s110_codecs Application s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup soc_app SOC Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s110_codecs - * - * @brief SOC Application command request encoders and command response decoders. - */ - -#ifndef NRF_SOC_APP_H__ -#define NRF_SOC_APP_H__ - -#include - -/**@brief Encodes @ref sd_power_system_off command request. - * - * @sa @ref nrf51_sd_power_off for packet format. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); - - -/**@brief Encodes @ref sd_temp_get command request. - * - * @sa @ref nrf51_sd_temp_get for packet format. - @ref temp_get_rsp_dec for command response decoder. - * - * @param[in] p_temp Pointer to result of temperature measurement. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t temp_get_req_enc(int32_t const * const p_temp, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_temp_get command. - * - * @sa @ref nrf51_sd_temp_get for packet format, - * @ref temp_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * @param[out] p_temp Pointer to result of temperature measurement. - * - * @return NRF_SUCCESS Version information stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t temp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - int32_t * const p_temp); - -/** @} */ - -#endif // NRF_SOC_APP_H__ diff --git a/components/serialization/application/codecs/s110/serializers/power_system_off.c b/components/serialization/application/codecs/s110/serializers/power_system_off.c deleted file mode 100644 index c81b1ca..0000000 --- a/components/serialization/application/codecs/s110/serializers/power_system_off.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "nrf_soc_app.h" -#include "ble_serialization.h" -#include "nrf_soc.h" - - -uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - - p_buf[index++] = SD_POWER_SYSTEM_OFF; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s110/serializers/temp_get.c b/components/serialization/application/codecs/s110/serializers/temp_get.c deleted file mode 100644 index e50a799..0000000 --- a/components/serialization/application/codecs/s110/serializers/temp_get.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "nrf_soc.h" -#include "nrf_error.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" - -uint32_t temp_get_req_enc(int32_t const * const p_temp, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(1, total_len); - p_buf[index++] = SD_TEMP_GET; - - err_code = cond_field_enc(p_temp, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t temp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - int32_t * const p_temp) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - SER_ASSERT_NOT_NULL(p_temp); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_TEMP_GET, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_temp); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/middleware/app_mw_ble.c b/components/serialization/application/codecs/s120/middleware/app_mw_ble.c deleted file mode 100644 index 51c73c3..0000000 --- a/components/serialization/application/codecs/s120/middleware/app_mw_ble.c +++ /dev/null @@ -1,501 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include -#include "ble_app.h" -#include "ser_sd_transport.h" -#include "app_error.h" -#include "app_ble_user_mem.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -/**@brief Structure containing @ref sd_ble_uuid_encode output parameters. */ -typedef struct -{ - uint8_t * p_uuid_le_len; /**< @ref sd_ble_uuid_encode appearance p_uuid_le_len output parameter. */ - uint8_t * p_uuid_le; /**< @ref sd_ble_uuid_encode appearance p_uuid_le output parameter. */ -} ble_uuid_encode_out_params_t; - -/**@brief Structure containing @ref sd_ble_tx_buffer_count_get output parameters. */ -typedef struct -{ - uint8_t * p_count; /**< @ref sd_ble_tx_buffer_count_get p_count output parameter. */ -} ble_tx_buffer_count__get_out_params_t; - -/**@brief Structure containing @ref sd_ble_user_mem_reply output parameters. */ -typedef struct -{ - uint16_t conn_handle; /**< @ref sd_ble_user_mem_reply conn_handle. */ - uint8_t context_allocated; /**< @ref sd_ble_user_mem_reply user memory context allocated flag. */ -} ble_user_mem_reply_out_params_t; - -/**@brief Union containing BLE command output parameters. */ -typedef union -{ - ble_uuid_encode_out_params_t ble_uuid_encode_out_params; /**< @ref sd_ble_uuid_encode output parameters. */ - ble_tx_buffer_count__get_out_params_t ble_tx_buffer_count_get_out_params; /**< @ref sd_ble_uuid_encode output parameters. */ - ble_user_mem_reply_out_params_t ble_user_mem_reply_out_params; /**< @ref sd_ble_user_mem_reply output parameters. */ -} ble_command_output_params_t; - -static ble_command_output_params_t m_output_params; /**< BLE command output parameters. */ - -static void * mp_out_params[3]; -static uint32_t m_uint32_param; - -static void tx_buf_alloc(uint8_t * * p_data, uint32_t * p_len) -{ - uint32_t err_code; - uint16_t len16; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, &len16); - } - while (err_code != NRF_SUCCESS); - - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len = (uint32_t)len16 - 1; -} - -/**@brief Command response callback function for @ref sd_ble_uuid_encode BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t uuid_encode_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_uuid_encode_rsp_dec(p_buffer, - length, - m_output_params.ble_uuid_encode_out_params.p_uuid_le_len, - m_output_params.ble_uuid_encode_out_params.p_uuid_le, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - return result_code; -} - - -uint32_t sd_ble_uuid_encode(ble_uuid_t const * const p_uuid, - uint8_t * const p_uuid_le_len, - uint8_t * const p_uuid_le) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - - m_output_params.ble_uuid_encode_out_params.p_uuid_le_len = p_uuid_le_len; - m_output_params.ble_uuid_encode_out_params.p_uuid_le = p_uuid_le; - - uint32_t err_code = ble_uuid_encode_req_enc(p_uuid, - p_uuid_le_len, - p_uuid_le, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - uuid_encode_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_tx_buffer_count_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t tx_buffer_count_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_tx_buffer_count_get_rsp_dec(p_buffer, - length, - (uint8_t * *)&mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_tx_buffer_count_get(uint8_t * p_count) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_count; - - const uint32_t err_code = ble_tx_buffer_count_get_req_enc(p_count, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - tx_buffer_count_get_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_uuid_vs_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t uuid_vs_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_uuid_vs_add_rsp_dec(p_buffer, - length, - (uint8_t * *)&mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_uuid_vs_add(ble_uuid128_t const * const p_vs_uuid, uint8_t * const p_uuid_type) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_uuid_type; - - const uint32_t err_code = ble_uuid_vs_add_req_enc(p_vs_uuid, p_uuid_type, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - uuid_vs_add_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_uuid_decode BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t uuid_decode_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_uuid_decode_rsp_dec(p_buffer, - length, - (ble_uuid_t * *)&mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_uuid_decode(uint8_t uuid_le_len, - uint8_t const * const p_uuid_le, - ble_uuid_t * const p_uuid) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_uuid; - - const uint32_t err_code = ble_uuid_decode_req_enc(uuid_le_len, p_uuid_le, p_uuid, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - uuid_decode_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_version_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t version_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_version_get_rsp_dec(p_buffer, - length, - (ble_version_t *)mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_version_get(ble_version_t * p_version) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_version; - - const uint32_t err_code = ble_version_get_req_enc(p_version, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - version_get_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_opt_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t opt_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - uint32_t uint32_param; - - uint32_t err_code = ble_opt_get_rsp_dec(p_buffer, - length, - &uint32_param, - (ble_opt_t *)mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - if (m_uint32_param != uint32_param) // decoded id should be the same as encoded one - { - err_code = NRF_ERROR_INVALID_PARAM; - } - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_opt; - m_uint32_param = opt_id; - - const uint32_t err_code = ble_opt_get_req_enc(opt_id, - p_opt, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - opt_get_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_opt_set BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t opt_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_opt_set_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - - const uint32_t err_code = ble_opt_set_req_enc(opt_id, - p_opt, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - opt_set_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_enable BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t enable_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_enable_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_enable(ble_enable_params_t * p_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length; - - tx_buf_alloc(&p_buffer, &buffer_length); - mp_out_params[0] = p_params; - - const uint32_t err_code = ble_enable_req_enc(p_params, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - enable_rsp_dec); - -} - -/**@brief Command response callback function for @ref sd_ble_user_mem_reply BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t user_mem_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - uint32_t err_code = ble_user_mem_reply_rsp_dec(p_buffer, - length, - &result_code); - APP_ERROR_CHECK(err_code); - - if ((result_code != NRF_SUCCESS) && - (m_output_params.ble_user_mem_reply_out_params.context_allocated)) - { - err_code = app_ble_user_mem_context_destroy( - m_output_params.ble_user_mem_reply_out_params.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - return result_code; -} - -uint32_t sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block) -{ - uint8_t * p_buffer; - uint32_t buffer_length, user_mem_table_index; - uint32_t err_code = NRF_SUCCESS; - - tx_buf_alloc(&p_buffer, &buffer_length); - - // Prepare User Memory Block context for later synchronization when SoftDevice updates - // the data in the memory block - if(p_block != NULL) - { - err_code = app_ble_user_mem_context_create(conn_handle, &user_mem_table_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - m_app_user_mem_table[user_mem_table_index].mem_block.len = p_block->len; - m_app_user_mem_table[user_mem_table_index].mem_block.p_mem = p_block->p_mem; - // Save connection handle and context allocation flag for case if context destroy was needed - m_output_params.ble_user_mem_reply_out_params.conn_handle = conn_handle; - m_output_params.ble_user_mem_reply_out_params.context_allocated = 1; - } - else - { - m_output_params.ble_user_mem_reply_out_params.context_allocated = 0; - } - - err_code = ble_user_mem_reply_req_enc(conn_handle, - p_block, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - user_mem_reply_rsp_dec); -} diff --git a/components/serialization/application/codecs/s120/middleware/app_mw_ble_gap.c b/components/serialization/application/codecs/s120/middleware/app_mw_ble_gap.c deleted file mode 100644 index c3fcb9e..0000000 --- a/components/serialization/application/codecs/s120/middleware/app_mw_ble_gap.c +++ /dev/null @@ -1,1285 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap.h" -#include -#include -#include "ble_serialization.h" -#include "ser_sd_transport.h" -#include "ble_gap_app.h" -#include "app_error.h" -#include "app_ble_gap_sec_keys.h" - -extern ser_ble_gap_app_keyset_t m_app_keys_table[SER_MAX_CONNECTIONS]; - -/**@brief Structure containing @ref sd_ble_gap_device_name_get output parameters. */ -typedef struct -{ - uint8_t * p_dev_name; /**< @ref sd_ble_gap_device_name_get p_dev_name output parameter. */ - uint16_t * p_len; /**< @ref sd_ble_gap_device_name_get p_len output parameter. */ -} gap_device_name_get_output_params_t; - -/**@brief Structure containing @ref sd_ble_gap_appearance_get output parameters. */ -typedef struct -{ - uint16_t * p_appearance; /**< @ref sd_ble_gap_appearance_get p_appearance output parameter. */ -} gap_appearance_get_output_params_t; - -/**@brief Structure containing @ref sd_ble_gap_ppcp_get output parameters. */ -typedef struct -{ - ble_gap_conn_params_t * p_conn_params; /**< @ref sd_ble_gap_ppcp_get p_conn_params output parameter. */ -} gap_ppcp_get_out_params_t; - -/**@brief Structure containing @ref sd_ble_gap_sec_params_reply output parameters. */ -typedef struct -{ - ble_gap_sec_keyset_t const * p_sec_keyset; /**< @ref sd_ble_gap_sec_params_reply p_sec_keyset output parameter. */ - uint16_t conn_handle; /**< @ref sd_ble_gap_sec_params_reply p_conn_handle output parameter. */ -} gap_sec_params_reply_out_params_t; - -/**@brief Union containing BLE command output parameters. */ -typedef union -{ - gap_device_name_get_output_params_t gap_device_name_get_out_params; /**< @ref sd_ble_gap_device_name_get output parameters. */ - gap_appearance_get_output_params_t gap_appearance_get_out_params; /**< @ref sd_ble_gap_appearance_get output parameters. */ - gap_ppcp_get_out_params_t gap_ppcp_get_out_params; /**< @ref sd_ble_gap_ppcp_get output parameters. */ - gap_sec_params_reply_out_params_t gap_sec_params_reply_out_params;/**< @ref sd_ble_sec_params_reply output parameters. */ -} gap_command_output_params_t; - -static gap_command_output_params_t m_output_params; /**< BLE command output parameters. */ - -static void * mp_out_params[1]; - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} -/**@brief Command response callback function for @ref sd_ble_gap_adv_start BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_adv_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_adv_start_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_adv_start(ble_gap_adv_params_t const * const p_adv_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gap_adv_start_req_enc(p_adv_params, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_adv_start_rsp_dec); -} - - -/**@brief Command response callback function for @ref ble_gap_device_name_get_req_enc BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_device_name_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_gap_device_name_get_rsp_dec(p_buffer, - length, - m_output_params.gap_device_name_get_out_params.p_dev_name, - m_output_params.gap_device_name_get_out_params.p_len, - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_device_name_get(uint8_t * const p_dev_name, uint16_t * const p_len) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - m_output_params.gap_device_name_get_out_params.p_dev_name = p_dev_name; - m_output_params.gap_device_name_get_out_params.p_len = p_len; - - const uint32_t err_code = ble_gap_device_name_get_req_enc(p_dev_name, - p_len, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_device_name_get_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_appearance_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_appearance_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_gap_appearance_get_rsp_dec(p_buffer, - length, - m_output_params.gap_appearance_get_out_params.p_appearance, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_appearance_get(uint16_t * const p_appearance) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - m_output_params.gap_appearance_get_out_params.p_appearance = p_appearance; - - const uint32_t err_code = ble_gap_appearance_get_req_enc(p_appearance, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_appearance_get_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_device_name_set BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_device_name_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_device_name_set_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const * const p_write_perm, - uint8_t const * const p_dev_name, - uint16_t len) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_device_name_set_req_enc(p_write_perm, - p_dev_name, - len, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_device_name_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_appearance_set BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_appearance_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_appearance_set_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_appearance_set(uint16_t appearance) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_appearance_set_req_enc(appearance, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_appearance_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_ppcp_set BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_ppcp_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_ppcp_set_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - return result_code; -} - - -uint32_t sd_ble_gap_ppcp_set(ble_gap_conn_params_t const * const p_conn_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_ppcp_set_req_enc(p_conn_params, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_ppcp_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_adv_data_set BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_adv_data_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_adv_data_set_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_adv_data_set(uint8_t const * const p_data, - uint8_t dlen, - uint8_t const * const p_sr_data, - uint8_t srdlen) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_adv_data_set_req_enc(p_data, - dlen, - p_sr_data, - srdlen, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_adv_data_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_conn_param_update BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_conn_param_update_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_conn_param_update_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_conn_param_update(uint16_t conn_handle, - ble_gap_conn_params_t const * const p_conn_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_conn_param_update_req_enc(conn_handle, - p_conn_params, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_conn_param_update_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_disconnect BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_disconnect_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_disconnect_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_disconnect_req_enc(conn_handle, - hci_status_code, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_disconnect_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_sec_info_reply BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_sec_info_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gap_sec_info_reply_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_ble_gap_sec_info_reply(uint16_t conn_handle, - ble_gap_enc_info_t const * p_enc_info, - ble_gap_irk_t const * p_id_info, - ble_gap_sign_info_t const * p_sign_info) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_sec_info_reply_req_enc(conn_handle, - p_enc_info, - p_id_info, - p_sign_info, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_sec_info_reply_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_sec_params_reply BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_sec_params_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - uint32_t err_code = ble_gap_sec_params_reply_rsp_dec(p_buffer, length, - m_output_params.gap_sec_params_reply_out_params.p_sec_keyset, &result_code); - APP_ERROR_CHECK(err_code); - - // If soft device returned error free security context - if (result_code) - { - err_code = app_ble_gap_sec_context_destroy(m_output_params.gap_sec_params_reply_out_params.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - return result_code; -} - - -uint32_t sd_ble_gap_sec_params_reply(uint16_t conn_handle, - uint8_t sec_status, - ble_gap_sec_params_t const * p_sec_params, - ble_gap_sec_keyset_t const * p_sec_keyset) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - uint32_t sec_tab_index = 0; - uint32_t err_code = NRF_SUCCESS; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - m_output_params.gap_sec_params_reply_out_params.p_sec_keyset = p_sec_keyset; - m_output_params.gap_sec_params_reply_out_params.conn_handle = conn_handle; - - // First allocate security context for serialization - if (p_sec_keyset) - { - err_code = app_ble_gap_sec_context_create(conn_handle, &sec_tab_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - memcpy(&(m_app_keys_table[sec_tab_index].keyset), p_sec_keyset, sizeof(ble_gap_sec_keyset_t)); - } - - err_code = ble_gap_sec_params_reply_req_enc(conn_handle, - sec_status, - p_sec_params, - p_sec_keyset, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_sec_params_reply_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gap_ppcp_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_ppcp_get_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_ppcp_get_rsp_dec( - p_buffer, - length, - m_output_params.gap_ppcp_get_out_params. - p_conn_params, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_ppcp_get(ble_gap_conn_params_t * const p_conn_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - m_output_params.gap_ppcp_get_out_params.p_conn_params = p_conn_params; - - const uint32_t err_code = ble_gap_ppcp_get_req_enc(p_conn_params, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_ppcp_get_reply_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_address_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_address_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_address_get_rsp_dec(p_buffer, - length, - (ble_gap_addr_t *)mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_address_get(ble_gap_addr_t * const p_addr) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_addr; - - const uint32_t err_code = ble_gap_address_get_req_enc(p_addr, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - - gap_address_get_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_address_set BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_address_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_address_set_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_address_set(uint8_t addr_cycle_mode, ble_gap_addr_t const * const p_addr) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_address_set_req_enc(addr_cycle_mode, - p_addr, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_address_set_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_adv_stop BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_adv_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_adv_stop_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_adv_stop(void) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_adv_stop_req_enc(&(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_adv_stop_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_auth_key_reply BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_auth_key_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_auth_key_reply_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_auth_key_reply(uint16_t conn_handle, - uint8_t key_type, - uint8_t const * const key) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_auth_key_reply_req_enc(conn_handle, key_type, key, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_auth_key_reply_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_authenticate BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_authenticate_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_authenticate_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_authenticate(uint16_t conn_handle, - ble_gap_sec_params_t const * const p_sec_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_authenticate_req_enc(conn_handle, p_sec_params, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_authenticate_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_conn_sec_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_conn_sec_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_conn_sec_get_rsp_dec( - p_buffer, - length, - (ble_gap_conn_sec_t * *)&mp_out_params[0 - ], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t * const p_conn_sec) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_conn_sec; - - const uint32_t err_code = ble_gap_conn_sec_get_req_enc(conn_handle, p_conn_sec, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_conn_sec_get_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_rssi_start BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_rssi_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_rssi_start_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_rssi_start_req_enc(conn_handle, - threshold_dbm, - skip_count, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_rssi_start_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_rssi_stop BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_rssi_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_rssi_stop_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_rssi_stop(uint16_t conn_handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_rssi_stop_req_enc(conn_handle, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_rssi_stop_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_tx_power_set BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_tx_power_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_tx_power_set_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_tx_power_set(int8_t tx_power) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_tx_power_set_req_enc(tx_power, - &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_tx_power_set_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_scan_stop BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_scan_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_scan_stop_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_scan_stop(void) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_scan_stop_req_enc(&(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_scan_stop_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_connect BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_connect_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_connect_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_connect(ble_gap_addr_t const * const p_addr, - ble_gap_scan_params_t const * const p_scan_params, - ble_gap_conn_params_t const * const p_conn_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_connect_req_enc(p_addr, - p_scan_params, - p_conn_params, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_connect_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_connect_cancel BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_connect_cancel_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_connect_cancel_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_connect_cancel(void) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_connect_cancel_req_enc(&(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_connect_cancel_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_scan_start BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_scan_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_scan_start_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_scan_start(ble_gap_scan_params_t const * const p_scan_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_scan_start_req_enc(p_scan_params, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_scan_start_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_encrypt BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_encrypt_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_encrypt_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_encrypt( uint16_t conn_handle, - ble_gap_master_id_t const * p_master_id, - ble_gap_enc_info_t const * p_enc_info) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_encrypt_req_enc( conn_handle, p_master_id, p_enc_info, &(p_buffer[1]), &buffer_length ); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_encrypt_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_rssi_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_rssi_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_rssi_get_rsp_dec(p_buffer, - length, - (int8_t *) mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gap_rssi_get(uint16_t conn_handle, - int8_t * p_rssi) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_rssi; - - const uint32_t err_code = ble_gap_rssi_get_req_enc(conn_handle, p_rssi, &(p_buffer[1]), &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_rssi_get_rsp_dec); -} diff --git a/components/serialization/application/codecs/s120/middleware/app_mw_ble_gattc.c b/components/serialization/application/codecs/s120/middleware/app_mw_ble_gattc.c deleted file mode 100644 index 26cfab9..0000000 --- a/components/serialization/application/codecs/s120/middleware/app_mw_ble_gattc.c +++ /dev/null @@ -1,426 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_gattc.h" -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "ser_sd_transport.h" -#include "app_error.h" - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} -/**@brief Command response callback function for @ref sd_ble_gattc_primary_services_discover BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_primary_services_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_primary_services_discover_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_primary_services_discover(uint16_t conn_handle, - uint16_t start_handle, - ble_uuid_t const * const p_srvc_uuid) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_primary_services_discover_req_enc(conn_handle, - start_handle, - p_srvc_uuid, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_primary_services_discover_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_relationships_discover BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_relationships_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_relationships_discover_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_relationships_discover(uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_relationships_discover_req_enc(conn_handle, - p_handle_range, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_relationships_discover_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_characteristics_discover BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_characteristics_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_characteristics_discover_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_characteristics_discover( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const - p_handle_range) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_characteristics_discover_req_enc(conn_handle, - p_handle_range, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_characteristics_discover_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_descriptors_discover BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_descriptors_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_descriptors_discover_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_descriptors_discover(uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_descriptors_discover_req_enc(conn_handle, - p_handle_range, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_descriptors_discover_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_char_value_by_uuid_read BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_char_value_by_uuid_read_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_char_value_by_uuid_read_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, - ble_uuid_t const * const p_uuid, - ble_gattc_handle_range_t const * const p_handle_range) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_char_value_by_uuid_read_req_enc(conn_handle, - p_uuid, - p_handle_range, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_char_value_by_uuid_read_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_read BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_read_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_read_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_read(uint16_t conn_handle, - uint16_t handle, - uint16_t offset) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_read_req_enc(conn_handle, - handle, - offset, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_read_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_char_values_read BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_char_values_read_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_char_values_read_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_char_values_read(uint16_t conn_handle, - uint16_t const * const p_handles, - uint16_t handle_count) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_char_values_read_req_enc(conn_handle, - p_handles, - handle_count, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_char_values_read_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_write BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_write_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_write_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_write(uint16_t conn_handle, - ble_gattc_write_params_t const * const p_write_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_write_req_enc(conn_handle, - p_write_params, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_write_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gattc_hv_confirm BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gattc_hv_confirm_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gattc_hv_confirm_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gattc_hv_confirm(uint16_t conn_handle, - uint16_t handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gattc_hv_confirm_req_enc(conn_handle, - handle, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gattc_hv_confirm_rsp_dec); -} diff --git a/components/serialization/application/codecs/s120/middleware/app_mw_ble_gatts.c b/components/serialization/application/codecs/s120/middleware/app_mw_ble_gatts.c deleted file mode 100644 index abc1120..0000000 --- a/components/serialization/application/codecs/s120/middleware/app_mw_ble_gatts.c +++ /dev/null @@ -1,571 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts.h" -#include -#include "ble_serialization.h" -#include "ser_sd_transport.h" -#include "ble_gatts_app.h" -#include "app_error.h" - - -//Pointer for sd calls output params -static void * mp_out_params[3]; - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} - -/**@brief Command response callback function for @ref sd_ble_gatts_sys_attr_set BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_sys_attr_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_sys_attr_set_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gatts_sys_attr_set(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t len, - uint32_t flags) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gatts_sys_attr_set_req_enc(conn_handle, - p_sys_attr_data, - len, - flags, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_sys_attr_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gatts_hvx BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_hvx_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_hvx_rsp_dec(p_buffer, length, &result_code, - (uint16_t * *)&mp_out_params[0]); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const * const p_hvx_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = (p_hvx_params) ? p_hvx_params->p_len : NULL; - - const uint32_t err_code = ble_gatts_hvx_req_enc(conn_handle, - p_hvx_params, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_hvx_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gatts_service_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_service_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_gatts_service_add_rsp_dec(p_buffer, - length, - (uint16_t *)mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gatts_service_add(uint8_t type, - ble_uuid_t const * const p_uuid, - uint16_t * const p_handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_handle; - - const uint32_t err_code = ble_gatts_service_add_req_enc(type, - p_uuid, - p_handle, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_service_add_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_service_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_service_changed_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = NRF_SUCCESS; - - const uint32_t err_code = ble_gatts_service_changed_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gatts_service_changed(uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gatts_service_changed_req_enc(conn_handle, - start_handle, - end_handle, - &(p_buffer[1]), - &buffer_length); - - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_service_changed_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_include_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_include_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = NRF_SUCCESS; - - const uint32_t err_code = - ble_gatts_include_add_rsp_dec(p_buffer, - length, - (uint16_t *) mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gatts_include_add(uint16_t service_handle, - uint16_t inc_serv_handle, - uint16_t * const p_include_handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_include_handle; - - const uint32_t err_code = ble_gatts_include_add_req_enc(service_handle, - inc_serv_handle, - p_include_handle, - &(p_buffer[1]), - &buffer_length); - - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_include_add_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_characteristic_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_characteristic_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_characteristic_add_rsp_dec( - p_buffer, - length, - (uint16_t * *)&mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gatts_characteristic_add(uint16_t service_handle, - ble_gatts_char_md_t const * const p_char_md, - ble_gatts_attr_t const * const p_attr_char_value, - ble_gatts_char_handles_t * const p_handles) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_handles; - - const uint32_t err_code = ble_gatts_characteristic_add_req_enc(service_handle, - p_char_md, - p_attr_char_value, - p_handles, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_characteristic_add_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_descriptor_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_descriptor_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = NRF_SUCCESS; - - const uint32_t err_code = - ble_gatts_descriptor_add_rsp_dec(p_buffer, - length, - (uint16_t *) mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gatts_descriptor_add(uint16_t char_handle, - ble_gatts_attr_t const * const p_attr, - uint16_t * const p_handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_handle; - - const uint32_t err_code = ble_gatts_descriptor_add_req_enc(char_handle, - p_attr, - p_handle, - &(p_buffer[1]), - &buffer_length); - - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_descriptor_add_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_rw_authorize_reply BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_rw_authorize_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = NRF_SUCCESS; - - const uint32_t err_code = ble_gatts_rw_authorize_reply_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gatts_rw_authorize_reply( - uint16_t conn_handle, - ble_gatts_rw_authorize_reply_params_t const * const - p_rw_authorize_reply_params) -{ - - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gatts_rw_authorize_reply_req_enc(conn_handle, - p_rw_authorize_reply_params, - &(p_buffer[1]), - &buffer_length); - - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_rw_authorize_reply_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_value_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_value_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_value_get_rsp_dec(p_buffer, - length, - (ble_gatts_value_t *)mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gatts_value_get(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t * p_value) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_value; - - const uint32_t err_code = ble_gatts_value_get_req_enc(conn_handle, - handle, - p_value, - &(p_buffer[1]), - &buffer_length); - - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_value_get_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_value_set BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_value_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_value_set_rsp_dec( - p_buffer, - length, - (ble_gatts_value_t *)mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gatts_value_set(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t * p_value) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_value; - - const uint32_t err_code = ble_gatts_value_set_req_enc(conn_handle, - handle, - p_value, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_value_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gatts_sys_attr_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_sys_attr_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_sys_attr_get_rsp_dec( - p_buffer, - length, - (uint8_t *) mp_out_params[0], - (uint16_t *) mp_out_params[1], - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gatts_sys_attr_get(uint16_t conn_handle, - uint8_t * const p_sys_attr_data, - uint16_t * const p_len, - uint32_t flags) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_sys_attr_data; - mp_out_params[1] = p_len; - - const uint32_t err_code = ble_gatts_sys_attr_get_req_enc(conn_handle, - p_sys_attr_data, - p_len, - flags, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_sys_attr_get_rsp_dec); -} diff --git a/components/serialization/application/codecs/s120/middleware/app_mw_ble_l2cap.c b/components/serialization/application/codecs/s120/middleware/app_mw_ble_l2cap.c deleted file mode 100644 index 436d5a2..0000000 --- a/components/serialization/application/codecs/s120/middleware/app_mw_ble_l2cap.c +++ /dev/null @@ -1,165 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap.h" -#include -#include "ble_serialization.h" -#include "ser_sd_transport.h" -#include "ble_l2cap_app.h" -#include "app_error.h" - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} -/**@brief Command response callback function for @ref ble_l2cap_cid_register_req_enc BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t l2cap_cid_register_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_l2cap_cid_register_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_l2cap_cid_register(uint16_t cid) -{ - - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_l2cap_cid_register_req_enc(cid, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - l2cap_cid_register_rsp_dec); -} - -/**@brief Command response callback function for @ref ble_l2cap_cid_unregister_req_enc BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t l2cap_cid_unregister_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_l2cap_cid_unregister_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_l2cap_cid_unregister(uint16_t cid) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_l2cap_cid_unregister_req_enc(cid, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - l2cap_cid_unregister_rsp_dec); -} - -/**@brief Command response callback function for @ref ble_l2cap_tx_req_enc BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t l2cap_tx_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_l2cap_tx_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_l2cap_tx(uint16_t conn_handle, - ble_l2cap_header_t const * const p_header, - uint8_t const * const p_data) -{ - - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_l2cap_tx_req_enc(conn_handle, p_header, p_data, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - l2cap_tx_rsp_dec); -} - diff --git a/components/serialization/application/codecs/s120/middleware/app_mw_nrf_soc.c b/components/serialization/application/codecs/s120/middleware/app_mw_nrf_soc.c deleted file mode 100644 index 6a636c8..0000000 --- a/components/serialization/application/codecs/s120/middleware/app_mw_nrf_soc.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "nrf_soc.h" -#include -#include -#include "ser_sd_transport.h" -#include "nrf_soc_app.h" -#include "nrf_error_soc.h" -#include "app_error.h" -#include "ble_serialization.h" - -#include "ser_app_power_system_off.h" - -static void * mp_out_param; - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} - - -uint32_t sd_power_system_off(void) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = power_system_off_req_enc(&(p_buffer[1]), &buffer_length); - APP_ERROR_CHECK(err_code); - - ser_app_power_system_off_set(); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - NULL); -} - - -/**@brief Command response callback function for @ref sd_temp_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ - -static uint32_t mw_temp_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = temp_get_rsp_dec(p_buffer, - length, - &result_code, - (int32_t *)mp_out_param); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_temp_get(int32_t * p_temp) -{ - mp_out_param = p_temp; - - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = temp_get_req_enc(p_temp, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - mw_temp_get_rsp_dec); -} diff --git a/components/serialization/application/codecs/s120/serializers/app_ble_gap_sec_keys.c b/components/serialization/application/codecs/s120/serializers/app_ble_gap_sec_keys.c deleted file mode 100644 index 066deb3..0000000 --- a/components/serialization/application/codecs/s120/serializers/app_ble_gap_sec_keys.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_ble_gap_sec_keys.h" -#include "nrf_error.h" -#include - -ser_ble_gap_app_keyset_t m_app_keys_table[SER_MAX_CONNECTIONS]; - -uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -#define SER_MAX_CONNECTIONS 2 - -/**@brief GAP connection - keyset mapping structure. - * - * @note This structure is used to map keysets to connection instances, and will be stored in a static table. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that keys for this connection are used by soft device. 0: keys used; 1: keys not used*/ - ble_gap_sec_keyset_t keyset; /**< Keyset structure, see @ref ble_gap_sec_keyset_t.*/ -} ser_ble_gap_app_keyset_t; - -/**@brief allocates instance in m_app_keys_table[] for storage of encryption keys. - * - * @param[in] conn_handle conn_handle - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS Context allocated. - * @retval NRF_ERROR_NO_MEM No free instance available. - */ -uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_gap_sec_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_app_keys_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_APP_BLE_GAP_SEC_KEYS_H diff --git a/components/serialization/application/codecs/s120/serializers/app_ble_user_mem.c b/components/serialization/application/codecs/s120/serializers/app_ble_user_mem.c deleted file mode 100644 index c476020..0000000 --- a/components/serialization/application/codecs/s120/serializers/app_ble_user_mem.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_ble_user_mem.h" -#include "ser_config.h" -#include "nrf_error.h" -#include - -ser_ble_user_mem_t m_app_user_mem_table[SER_MAX_CONNECTIONS]; - -uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -/**@brief Connection - user memory mapping structure. - * - * @note This structure is used to map user memory to connection instances, and will be stored in a static table. - */ -//lint -esym(452,ser_ble_user_mem_t) -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that user memory for this connection is used by soft device. 0: memory used; 1: memory not used*/ - ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t.*/ -} ser_ble_user_mem_t; - -/**@brief allocates instance in m_user_mem_table[] for storage. - * - * @param[in] conn_handle conn_handle - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS Context allocated. - * @retval NRF_ERROR_NO_MEM No free instance available. - */ -uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_user_mem_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_user_mem_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_APP_BLE_USER_MEM_H diff --git a/components/serialization/application/codecs/s120/serializers/ble_app.h b/components/serialization/application/codecs/s120/serializers/ble_app.h deleted file mode 100644 index 9346002..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_app.h +++ /dev/null @@ -1,445 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_APP_H__ -#define BLE_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_app Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief Application command request encoders and command response decoders. - */ -#include "ble.h" -/** - * @brief Encodes @ref sd_ble_tx_buffer_count_get command request. - * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format, - * @ref ble_tx_buffer_count_get_rsp_dec for command response decoder. - * - * @param[in] p_count Pointer to count value to be filled. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_count will not be updated by the command - * request encoder. Updated values are set by @ref ble_tx_buffer_count_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_tx_buffer_count_get_req_enc(uint8_t const * const p_count, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_tx_buffer_count_get command. - * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format, - * @ref ble_tx_buffer_count_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_count Pointer to pointer to count value. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_tx_buffer_count_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * const pp_count, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_uuid_encode command request. - * - * @sa @ref nrf51_uuid_encode_encoding for packet format, - * @ref ble_uuid_encode_rsp_dec for command response decoder. - * - * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. - * @param[in] p_uuid_le_len Size of \p p_uuid_le if \p p_uuid_le is not NULL - * @param[in] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes(2 or 16) - * will be stored. Can be NULL to calculate required size. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_uuid_le_len and \p p_uuid_le will not be updated by the command - * request encoder. Updated values are set by @ref ble_uuid_encode_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, - uint8_t const * const p_uuid_le_len, - uint8_t const * const p_uuid_le, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_uuid_encode command. - * - * @sa @ref nrf51_uuid_encode_encoding for packet format, - * @ref ble_uuid_encode_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in,out] p_uuid_le_len \c in: Size (in bytes) of \p p_uuid_le buffer. - * \c out: Length of decoded contents of \p p_uuid_le. - * @param[out] p_uuid_le Pointer to a buffer where the encoded UUID will be stored. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Length of \p p_uuid_le is too small to hold decoded - * value from response. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_uuid_le_len, - uint8_t * const p_uuid_le, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_uuid_decode command request. - * - * @sa @ref nrf51_uuid_decode_encoding for packet format, - * @ref ble_uuid_decode_rsp_dec for command response decoder. - * - * @param[in] uuid_le_len Size of \p p_uuid_le if \p p_uuid_le is not NULL - * @param[in] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes(2 or 16) - * is stored. - * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure were raw UUID will be decoded. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_uuid will not be updated by the command request encoder. - * Updated values are set by @ref ble_uuid_decode_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len, - uint8_t const * const p_uuid_le, - ble_uuid_t * const p_uuid, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_uuid_decode command. - * - * @sa @ref nrf51_uuid_decode_encoding for packet format, - * @ref ble_uuid_decode_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_uuid Pointer to a buffer where the decoded UUID will be stored. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_uuid_t * * const p_uuid, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_uuid_vs_add command request. - * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format, - * @ref ble_uuid_vs_add_rsp_dec for command response decoder. - * - * @param[in] p_vs_uuid Pointer to a @ref ble_uuid128_t structure. - * @param[in] p_uuid_type Pointer to uint8_t where UUID type will be returned. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_uuid_type will not be updated by the command request encoder. - * Updated values are set by @ref ble_uuid_vs_add_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid, - uint8_t * const p_uuid_type, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_uuid_vs_add command. - * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format, - * @ref ble_uuid_vs_add_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] pp_uuid_type Pointer to a pointer to uint8_t where the decoded UUID type will be stored. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * * const pp_uuid_type, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_version_get command request. - * - * @sa @ref nrf51_version_get_encoding for packet format, - * @ref ble_version_get_rsp_dec for command response decoder. - * - * @param[in] p_version Pointer to a @ref ble_version_t structure to be filled by the response. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_version_get_req_enc(ble_version_t const * const p_version, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_version_get command. - * - * @sa @ref nrf51_version_get_encoding for packet format, - * @ref ble_version_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_version Pointer to a @ref ble_version_t where decoded version will be stored. - * @param[out] p_result_code Command result code. - * - * @return NRF_SUCCESS Version information stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_version_t * p_version, - uint32_t * const p_result_code); - - -/**@brief Encodes @ref sd_ble_opt_set command request. - * - * @sa @ref nrf51_opt_set_encoding for packet format, - * @ref ble_opt_set_rsp_dec for command response decoder. - * - * @param[in] opt_id Identifies type of parameter in ble_opt_t union. - * @param[in] p_opt Pointer to ble_opt_t union. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. - */ -uint32_t ble_opt_set_req_enc(uint32_t const opt_id, - ble_opt_t const * const p_opt, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_opt_set command. - * - * @sa @ref nrf51_opt_set_encoding for packet format, - * @ref ble_opt_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @return NRF_SUCCESS Version information stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_enable command request. - * - * @sa @ref nrf51_enable_encoding for packet format, - * @ref ble_enable_rsp_dec for command response decoder. - * - * @param[in] p_ble_enable_params Pointer to a @ref ble_enable_params_t structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_enable command. - * - * @sa @ref nrf51_enable_encoding for packet format, - * @ref ble_enable_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @return NRF_SUCCESS Success. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_opt_get command request. - * - * @sa @ref nrf51_opt_get_encoding for packet format, - * @ref ble_opt_get_rsp_dec for command response decoder. - * - * @param[in] opt_id Identifies type of parameter in ble_opt_t union. - * @param[in] p_opt Pointer to a @ref ble_opt_t union to be filled by the response. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. - */ -uint32_t ble_opt_get_req_enc(uint32_t opt_id, - ble_opt_t const * const p_opt, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_opt_get command. - * - * @sa @ref nrf51_opt_get_encoding for packet format, - * @ref ble_opt_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_opt_id Pointer to a decoded opt_id - * @param[out] p_opt Pointer to a decoded @ref ble_opt_t union - * @param[out] p_result_code Command result code. - * - * @return NRF_SUCCESS Opt stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. - */ - -uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t * const p_opt, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_user_mem_reply command request. - * - * @sa @ref nrf51_user_mem_reply_encoding for packet format, - * @ref ble_user_mem_reply_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection Handle. - * @param[in] p_block Pointer to a @ref ble_user_mem_block_t structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. - */ -uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle, - ble_user_mem_block_t const * p_block, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_user_mem_reply command. - * - * @sa @ref nrf51_user_mem_reply_encoding for packet format, - * @ref ble_user_mem_reply_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @return NRF_SUCCESS Opt stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. - */ -uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Event decoding dispatcher. - * - * The event decoding dispatcher will route the event packet to the correct decoder which in turn - * decodes the contents of the event and updates the \p p_event struct. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to beginning of event packet. - * @param[in] packet_len Length (in bytes) of event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - * @retval NRF_ERROR_NOT_FOUND Decoding failure. No event decoder is available. - */ -uint32_t ble_event_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s120/serializers/ble_enable.c b/components/serialization/application/codecs/s120/serializers/ble_enable.c deleted file mode 100644 index 09db16a..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_enable.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include -#include "ble_app.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_ENABLE; - - err_code = cond_field_enc(p_ble_enable_params, p_buf, *p_buf_len, &index, ble_enable_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_ENABLE, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_event.c b/components/serialization/application/codecs/s120/serializers/ble_event.c deleted file mode 100644 index 6573cd6..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_event.c +++ /dev/null @@ -1,241 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include "ble_evt_app.h" -#include "ble_gap_evt_app.h" -#include "ble_gattc_evt_app.h" -#include "ble_gatts_evt_app.h" -#include "ble_l2cap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_event_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE, packet_len); - - - const uint16_t event_id = uint16_decode(&p_buf[SER_EVT_ID_POS]); - const uint8_t * p_sub_buffer = &p_buf[SER_EVT_HEADER_SIZE]; - const uint32_t sub_packet_len = packet_len - SER_EVT_HEADER_SIZE; - - if (p_event) - { - SER_ASSERT_LENGTH_LEQ(sizeof (ble_evt_hdr_t), *p_event_len); - *p_event_len -= sizeof (ble_evt_hdr_t); - } - - switch (event_id) - { - case BLE_EVT_TX_COMPLETE: - err_code = ble_evt_tx_complete_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_EVT_USER_MEM_REQUEST: - err_code = ble_evt_user_mem_request_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_EVT_USER_MEM_RELEASE: - err_code = ble_evt_user_mem_release_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_PASSKEY_DISPLAY: - err_code = ble_gap_evt_passkey_display_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_AUTH_KEY_REQUEST: - err_code = ble_gap_evt_auth_key_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE: - err_code = ble_gap_evt_conn_param_update_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: - err_code = ble_gap_evt_conn_param_update_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONN_SEC_UPDATE: - err_code = ble_gap_evt_conn_sec_update_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONNECTED: - err_code = ble_gap_evt_connected_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_DISCONNECTED: - err_code = ble_gap_evt_disconnected_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GAP_EVT_TIMEOUT: - err_code = ble_gap_evt_timeout_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_RSSI_CHANGED: - err_code = ble_gap_evt_rssi_changed_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GAP_EVT_SEC_INFO_REQUEST: - err_code = ble_gap_evt_sec_info_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - err_code = ble_gap_evt_sec_params_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_AUTH_STATUS: - err_code = ble_gap_evt_auth_status_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GAP_EVT_SEC_REQUEST: - err_code = ble_gap_evt_sec_request_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - err_code = ble_gattc_evt_char_disc_rsp_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: - err_code = ble_gattc_evt_char_val_by_uuid_read_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_DESC_DISC_RSP: - err_code = ble_gattc_evt_desc_disc_rsp_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - err_code = ble_gattc_evt_prim_srvc_disc_rsp_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_READ_RSP: - err_code = ble_gattc_evt_read_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_HVX: - err_code = ble_gattc_evt_hvx_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTC_EVT_TIMEOUT: - err_code = ble_gattc_evt_timeout_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTC_EVT_WRITE_RSP: - err_code = ble_gattc_evt_write_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_CHAR_VALS_READ_RSP: - err_code = ble_gattc_evt_char_vals_read_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_REL_DISC_RSP: - err_code = ble_gattc_evt_rel_disc_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTS_EVT_WRITE: - err_code = ble_gatts_evt_write_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTS_EVT_TIMEOUT: - err_code = ble_gatts_evt_timeout_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTS_EVT_SC_CONFIRM: - err_code = ble_gatts_evt_sc_confirm_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTS_EVT_HVC: - err_code = ble_gatts_evt_hvc_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - err_code = ble_gatts_evt_sys_attr_missing_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: - err_code = ble_gatts_evt_rw_authorize_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_L2CAP_EVT_RX: - err_code = ble_l2cap_evt_rx_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_ADV_REPORT: - err_code = ble_gap_evt_adv_report_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_SCAN_REQ_REPORT: - err_code = ble_gap_evt_scan_req_report_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - default: - err_code = NRF_ERROR_NOT_FOUND; - break; - } - - if (p_event != NULL) - { - p_event->header.evt_id = (err_code == NRF_SUCCESS) ? event_id : 0; - p_event->header.evt_len = (err_code == NRF_SUCCESS) ? - (uint16_t)*p_event_len : 0; - } - *p_event_len += sizeof(ble_evt_hdr_t); - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_evt_app.h b/components/serialization/application/codecs/s120/serializers/ble_evt_app.h deleted file mode 100644 index 887d44f..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_evt_app.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_EVT_APP_H__ -#define BLE_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_evt_app Application event decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_evt_tx_complete event. - * - * @sa @ref nrf51_evt_tx_complete_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_evt_user_mem_request event. - * - * @sa @ref nrf51_evt_user_mem_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ - uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_evt_user_mem_release event. - * - * @sa @ref nrf51_evt_user_mem_release_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ - uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s120/serializers/ble_evt_tx_complete.c b/components/serialization/application/codecs/s120/serializers/ble_evt_tx_complete.c deleted file mode 100644 index 4abf73c..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_evt_tx_complete.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_evt_app.h" -#include "ble_serialization.h" - - -uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_evt_tx_complete_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_EVT_TX_COMPLETE; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.common_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.common_evt.params.tx_complete.count); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_evt_user_mem_release.c b/components/serialization/application/codecs/s120/serializers/ble_evt_user_mem_release.c deleted file mode 100644 index 54efc5f..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_evt_user_mem_release.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" -#include "ble_evt_app.h" -#include "app_ble_user_mem.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.common_evt.params.user_mem_release)) + - sizeof (ble_evt_user_mem_release_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - p_event->header.evt_id = BLE_EVT_USER_MEM_RELEASE; - p_event->header.evt_len = event_len; - ble_evt_user_mem_release_t * p_user_mem_rel = &(p_event->evt.common_evt.params.user_mem_release); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.common_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_user_mem_rel->type)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - // Decoding order of mem block is different than structure elements order - length is decoded first - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_user_mem_rel->mem_block.len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - // Using connection handle find which mem block to release in Application Processor - uint32_t user_mem_table_index; - err_code = app_ble_user_mem_context_find(p_event->evt.common_evt.conn_handle, &user_mem_table_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_user_mem_rel->mem_block.p_mem = m_app_user_mem_table[user_mem_table_index].mem_block.p_mem; - } - else - { - p_user_mem_rel->mem_block.p_mem = NULL; - } - - // Now user memory context can be released - err_code = app_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_evt_user_mem_request.c b/components/serialization/application/codecs/s120/serializers/ble_evt_user_mem_request.c deleted file mode 100644 index 891f759..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_evt_user_mem_request.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" -#include "ble_evt_app.h" - -uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.common_evt.params.user_mem_request)) + - sizeof (ble_evt_user_mem_request_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - p_event->header.evt_id = BLE_EVT_USER_MEM_REQUEST; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.common_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_event->evt.common_evt.params.user_mem_request.type)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_address_get.c b/components/serialization/application/codecs/s120/serializers/ble_gap_address_get.c deleted file mode 100644 index 4af2bc4..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_address_get.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_address_get_req_enc(ble_gap_addr_t const * const p_address, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_ADDRESS_GET; - p_buf[index++] = (p_address == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_address_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * const p_address, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GAP_ADDRESS_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 1 + BLE_GAP_ADDR_LEN, packet_len); - SER_ASSERT_NOT_NULL(p_address); - - p_address->addr_type = p_buf[index++]; - memcpy(p_address->addr, &p_buf[index], BLE_GAP_ADDR_LEN); - index += BLE_GAP_ADDR_LEN; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_address_set.c b/components/serialization/application/codecs/s120/serializers/ble_gap_address_set.c deleted file mode 100644 index 8acaa61..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_address_set.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_address_set_req_enc(uint8_t addr_cycle_mode, - ble_gap_addr_t const * const p_addr, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_ADDRESS_SET; - - err_code = uint8_t_enc(&addr_cycle_mode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_buf[index++] = (p_addr == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_addr != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + BLE_GAP_ADDR_LEN, *p_buf_len); - p_buf[index++] = p_addr->addr_type; - memcpy(&p_buf[index], p_addr->addr, BLE_GAP_ADDR_LEN); - index += BLE_GAP_ADDR_LEN; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_address_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADDRESS_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_adv_data_set.c b/components/serialization/application/codecs/s120/serializers/ble_gap_adv_data_set.c deleted file mode 100644 index a59f271..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_adv_data_set.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data, - uint8_t dlen, - uint8_t const * const p_sr_data, - uint8_t srdlen, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint8_t opcode = SD_BLE_GAP_ADV_DATA_SET; - uint32_t err_code; - err_code = uint8_t_enc(&opcode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len8data_enc(p_data, dlen, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len8data_enc(p_sr_data, srdlen, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADV_DATA_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_adv_start.c b/components/serialization/application/codecs/s120/serializers/ble_gap_adv_start.c deleted file mode 100644 index 115a447..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_adv_start.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - -uint32_t ble_gap_adv_start_req_enc(ble_gap_adv_params_t const * const p_adv_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 2, total_len); - p_buf[index++] = SD_BLE_GAP_ADV_START; - p_buf[index++] = (p_adv_params == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_adv_params != NULL) - { - err_code = uint8_t_enc(&(p_adv_params->type), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_adv_params->p_peer_addr, p_buf, total_len, &index, ble_gap_addr_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&(p_adv_params->fp), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_adv_params->p_whitelist, p_buf, total_len, &index, ble_gap_whitelist_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_adv_params->interval), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_adv_params->timeout), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_adv_ch_mask_t_enc(&(p_adv_params->channel_mask), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADV_START, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_adv_stop.c b/components/serialization/application/codecs/s120/serializers/ble_gap_adv_stop.c deleted file mode 100644 index c633a4b..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_adv_stop.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" - -uint32_t ble_gap_adv_stop_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_ADV_STOP; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADV_STOP, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_app.h b/components/serialization/application/codecs/s120/serializers/ble_gap_app.h deleted file mode 100644 index 433fbfa..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_app.h +++ /dev/null @@ -1,1159 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GAP_APP_H__ -#define BLE_GAP_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gap_app GAP Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief GAP Application command request encoders and command response decoders. - */ -#include "ble.h" -#include "ble_gap.h" - -/** - * @brief Encodes @ref sd_ble_gap_address_get command request. - * - * @sa @ref nrf51_address_get_encoding for packet format, - * @ref ble_gap_address_get_rsp_dec for command response decoder. - * - * @param[in] p_address Pointer to address. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_address will not be updated by the command - * request encoder. Updated values are set by @ref ble_gap_address_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_get_req_enc(ble_gap_addr_t const * const p_address, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_address_get command. - * - * @sa @ref nrf51_address_get_encoding for packet format, - * @ref ble_gap_address_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_address Pointer to address. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_address_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * const p_address, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_address_set command request. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format, - * @ref ble_gap_address_set_rsp_dec for command response decoder. - * - * @param[in] addr_cycle_mode Address cycle mode. - * @param[in] p_addr Pointer to address structure. - * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_set_req_enc(uint8_t addr_cycle_mode, - ble_gap_addr_t const * const p_addr, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_address_set command. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format, - * @ref ble_gap_address_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_address_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_adv_data_set command request. - * - * @sa @ref nrf51_adv_set_encoding for packet format, - * @ref ble_gap_adv_data_set_rsp_dec for command response decoder. - * - * @param[in] p_data Raw data to be placed in advertisement packet. If NULL, no changes - * are made to the current advertisement packet data. - * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. - * Should be 0 if p_data is NULL, can be 0 if p_data is not NULL. - * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, - * no changes are made to the current scan response packet data. - * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. - * Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data, - uint8_t dlen, - uint8_t const * const p_sr_data, - uint8_t srdlen, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_adv_data_set command. - * - * @sa @ref nrf51_adv_set_encoding for packet format, - * @ref ble_gap_adv_data_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_adv_start command request. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_gap_adv_start_rsp_dec for command response decoder. - * - * @param[in] p_adv_params Pointer to advertising parameters structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_start_req_enc(ble_gap_adv_params_t const * const p_adv_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_adv_start command. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_gap_adv_start_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_tx_power_set command request. - * - * @sa @ref nrf51_tx_power_set_encoding for packet format, - * @ref ble_gap_tx_power_set_rsp_dec for command response decoder. - * - * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm). - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_tx_power_set_req_enc(int8_t tx_power, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_tx_power_set command. - * - * @sa @ref nrf51_tx_power_set_encoding for packet format, - * @ref ble_gap_tx_power_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_appearance_get command request. - * - * @sa @ref nrf51_appearance_get_encoding for packet format, - * @ref ble_gap_appearance_get_rsp_dec for command response decoder. - * - * @param[in] p_appearance Appearance (16-bit), see @ref BLE_APPEARANCES - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_appearance will not be updated by the command - * request encoder. Updated values are set by @ref ble_gap_appearance_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_appearance_get command. - * - * @sa @ref nrf51_appearance_get_encoding for packet format, - * @ref ble_gap_appearance_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_appearance Appearance (16-bit), see @ref BLE_APPEARANCES. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_appearance, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_appearance_set command request. - * - * @sa @ref nrf51_appearance_set_encoding for packet format, - * @ref ble_gap_appearance_set_rsp_dec for command response decoder. - * - * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_appearance_set command. - * - * @sa @ref nrf51_appearance_set_encoding for packet format, - * @ref ble_gap_appearance_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_device_name_get command request. - * - * @sa @ref nrf51_device_name_get_encoding for packet format, - * @ref ble_gap_device_name_get_rsp_dec for command response decoder. - * - * @param[in] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated - * string will be placed. Set to NULL to obtain the complete device - * name length. - * @param[in] p_dev_name_len Length of the buffer pointed by p_dev_name. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_dev_name and \p p_len will not be updated by the command - * request encoder. Updated values are set by @ref ble_gap_device_name_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name, - uint16_t const * const p_dev_name_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_device_name_get command. - * - * @sa @ref nrf51_device_name_get_encoding for packet format, - * @ref ble_gap_device_name_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 - * non NULL-terminated string will be placed. - * @param[in,out] p_dev_name_len Length of the buffer pointed by p_dev_name, complete device name - * length on output. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_dev_name, - uint16_t * const p_dev_name_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_device_name_set command request. - * - * @sa @ref nrf51_device_name_set_encoding for packet format, - * @ref ble_gap_device_name_set_rsp_dec for command response decoder. - * - * @param[in] p_write_perm Write permissions for the Device Name characteristic see - * @ref ble_gap_conn_sec_mode_t. - * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. - * @param[in] len Length of the UTF-8, non NULL-terminated string pointed - * to by p_dev_name in octets (must be smaller or equal - * than @ref BLE_GAP_DEVNAME_MAX_LEN). - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p_write_perm, - uint8_t const * const p_dev_name, - uint16_t len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_device_name_set command. - * - * @sa @ref nrf51_device_name_set_encoding for packet format, - * @ref ble_gap_device_name_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_ppcp_set command request. - * - * @sa @ref nrf51_ppcp_set_encoding for packet format, - * @ref ble_gap_ppcp_set_rsp_dec for command response decoder. - * - * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the - * desired parameters. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_ppcp_set command. - * - * @sa @ref nrf51_ppcp_set_encoding for packet format, - * @ref ble_gap_ppcp_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_conn_param_update command request. - * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format, - * @ref ble_gap_conn_param_update_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_conn_params Pointer to desired connection parameters.. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_conn_param_update_req_enc(uint16_t conn_handle, - ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_conn_param_update command. - * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format, - * @ref ble_gap_conn_param_update_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_disconnect command request. - * - * @sa @ref nrf51_disconnect_encoding for packet format, - * @ref ble_gap_disconnect_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle, - uint8_t hci_status_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_disconnect command. - * - * @sa @ref nrf51_disconnect_encoding for packet format, - * @ref ble_gap_disconnect_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - - -/**@brief Encodes @ref sd_ble_gap_rssi_stop command request. - * - * @sa @ref nrf51_rssi_stop_encoding for packet format, - * @ref ble_gap_rssi_stop_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_rssi_stop command. - * - * @sa @ref nrf51_rssi_stop_encoding for packet format, - * @ref ble_gap_rssi_stop_rsp_dec for command response decoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - - - - -/**@brief Encodes @ref sd_ble_gap_ppcp_get command request. - * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format, - * @ref ble_gap_ppcp_get_rsp_dec for command response decoder. - * - * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the - * parameters will be stored. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_conn_params will not be updated by the command request encoder. Updated values are - * set by @ref ble_gap_ppcp_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_ppcp_get command. - * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format, - * @ref ble_gap_ppcp_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters - * will be stored. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_params_t * const p_conn_params, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_auth_key_reply command request. - * - * @sa @ref nrf51_auth_key_reply_encoding for packet format, - * @ref ble_gap_auth_key_reply_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] key_type Key type which defines length of key data as defined for - * @ref sd_ble_gap_auth_key_reply . - * @param[in] p_key Pointer to a buffer which contains key - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect param provided (key_type). - */ -uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle, - uint8_t key_type, - uint8_t const * const p_key, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_auth_key_reply command. - * - * @sa @ref nrf51_auth_key_reply_encoding for packet format, - * @ref ble_gap_auth_key_reply_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_sec_info_reply command request. - * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format, - * @ref ble_gap_sec_info_reply_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information - * structure. - * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t id information - * structure. - * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information - * structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle, - ble_gap_enc_info_t const * p_enc_info, - ble_gap_irk_t const * p_id_info, - ble_gap_sign_info_t const * p_sign_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_sec_info_reply command. - * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format, - * @ref ble_gap_sec_info_reply_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_sec_params_reply command request. - * - * @sa @ref nrf51_sec_params_reply_encoding for packet format, - * @ref ble_gap_sec_params_reply_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. - * @param[in] p_sec_params Pointer to @ref ble_gap_sec_params_t security parameters - * structure. - * @param[in] p_sec_keyset Pointer to @ref ble_gap_sec_keyset_t security keys - * structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_sec_params_reply_req_enc(uint16_t conn_handle, - uint8_t sec_status, - ble_gap_sec_params_t const * const p_sec_params, - ble_gap_sec_keyset_t const * const p_sec_keyset, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_sec_params_reply command. - * - * @sa @ref nrf51_sec_params_reply_encoding for packet format, - * @ref ble_gap_sec_params_reply_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] p_sec_keyset Pointer to @ref ble_gap_sec_keyset_t security keys - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_sec_keyset_t const * const p_sec_keyset, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_authenticate command request. - * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format, - * @ref ble_gap_authenticate_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters - * structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle, - ble_gap_sec_params_t const * const p_sec_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_authenticate command. - * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format, - * @ref ble_gap_authenticate_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_adv_stop command request. - * - * @sa @ref nrf51_sd_ble_gap_adv_stop for packet format, - * @ref ble_gap_adv_stop_rsp_dec for command response decoder. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_stop_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_adv_stop command. - * - * @sa @ref nrf51_sd_ble_gap_adv_stop for packet format, - * @ref ble_gap_adv_stop_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_conn_sec_get command request. - * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format, - * @ref ble_gap_conn_sec_get_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_conn_sec Pointer to \ref ble_gap_conn_sec_t which will be filled in - * response. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_handle, - ble_gap_conn_sec_t const * const p_conn_sec, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_conn_sec_get command. - * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format, - * @ref ble_gap_conn_sec_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_conn_sec Pointer to pointer to \ref ble_gap_conn_sec_t which will be filled by - * the decoded data (if present). - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_sec_t * * const pp_conn_sec, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_rssi_start command request. - * - * @sa @ref nrf51_rssi_start_encoding for packet format, - * @ref ble_gap_rssi_start_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] threshold_dbm Threshold in dBm. - * @param[in] skip_count Sample skip count. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle, - uint8_t threshold_dbm, - uint8_t skip_count, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_rssi_start command. - * - * @sa @ref nrf51_rssi_start_encoding for packet format, - * @ref ble_gap_rssi_start_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_scan_stop command request. - * - * @sa @ref nrf51_scan_stop_encoding for packet format, - * @ref ble_gap_scan_stop_rsp_dec for command response decoder. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_scan_stop command. - * - * @sa @ref nrf51_scan_stop_encoding for packet format, - * @ref ble_gap_scan_stop_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_scan_start command request. - * - * @sa @ref nrf51_scan_start_encoding for packet format, - * @ref ble_gap_scan_start_rsp_dec for command response decoder. - * - * @param[in] p_scan_params Pointer to scan params structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_scan_start command. - * - * @sa @ref nrf51_scan_start_encoding for packet format, - * @ref ble_gap_scan_start_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_connect command request. - * - * @sa @ref nrf51_connect_encoding for packet format, - * @ref ble_gap_connect_rsp_dec for command response decoder. - * - * @param[in] p_peer_addr Pointer to peer address. - * @param[in] p_scan_params Pointer to scan params structure. - * @param[in] p_conn_params Pointer to desired connection parameters. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr, - ble_gap_scan_params_t const * const p_scan_params, - ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_connect command. - * - * @sa @ref nrf51_connect_encoding for packet format, - * @ref ble_gap_connect_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_connect_cancel command request. - * - * @sa @ref nrf51_connect_cancel_encoding for packet format, - * @ref ble_gap_connect_cancel_rsp_dec for command response decoder. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_connect_cancel command. - * - * @sa @ref nrf51_connect_cancel_encoding for packet format, - * @ref ble_gap_connect_cancel_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - - -/**@brief Encodes @ref sd_ble_gap_encrypt command request. - * - * @sa @ref nrf51_gap_encrypt_encoding for packet format, - * @ref ble_gap_encrypt_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_master_id Pointer to a master identification structure. - * @param[in] p_enc_info Pointer to desired connection parameters. - * @param[in] p_buf Pointer to a ble_gap_enc_info_t encryption information structure. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_gap_encrypt_req_enc( uint16_t conn_handle, - ble_gap_master_id_t const * const p_master_id, - ble_gap_enc_info_t const * const p_enc_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - - -/**@brief Decodes response to @ref sd_ble_gap_encrypt command. - * - * @sa @ref nrf51_gap_encrypt_encoding for packet format, - * @ref ble_gap_encrypt_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gap_rssi_get command request. - * - * @sa @ref nrf51_rssi_get_encoding for packet format, - * @ref ble_gap_rssi_get_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_rssi Pointer to the rssi value. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle, - int8_t const * const p_rssi, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gap_rssi_get command. - * - * @sa @ref nrf51_rssi_get_encoding for packet format, - * @ref ble_gap_rssi_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_rssi Pointer to rssi value. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - int8_t * const p_rssi, - uint32_t * const p_result_code); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_appearance_get.c b/components/serialization/application/codecs/s120/serializers/ble_gap_appearance_get.c deleted file mode 100644 index cc55dd6..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_appearance_get.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_APPEARANCE_GET; - p_buf[index++] = (p_appearance == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_appearance, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_APPEARANCE_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + sizeof (uint16_t), packet_len); - - uint16_dec(p_buf, packet_len, &index, p_appearance); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_appearance_set.c b/components/serialization/application/codecs/s120/serializers/ble_gap_appearance_set.c deleted file mode 100644 index 8038b76..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_appearance_set.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_APPEARANCE_SET; - index += uint16_encode(appearance, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_APPEARANCE_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_auth_key_reply.c b/components/serialization/application/codecs/s120/serializers/ble_gap_auth_key_reply.c deleted file mode 100644 index 58861e0..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_auth_key_reply.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle, - uint8_t key_type, - uint8_t const * const p_key, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_GAP_AUTH_KEY_REPLY; - uint32_t err_code = NRF_SUCCESS; - uint8_t key_len; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&key_type, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - switch (key_type) - { - case BLE_GAP_AUTH_KEY_TYPE_NONE: - key_len = 0; - break; - - case BLE_GAP_AUTH_KEY_TYPE_PASSKEY: - key_len = 6; - break; - - case BLE_GAP_AUTH_KEY_TYPE_OOB: - key_len = 16; - break; - - default: - return NRF_ERROR_INVALID_PARAM; - } - - err_code = buf_enc(p_key, key_len, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_AUTH_KEY_REPLY, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_authenticate.c b/components/serialization/application/codecs/s120/serializers/ble_gap_authenticate.c deleted file mode 100644 index 1f93c74..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_authenticate.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle, - ble_gap_sec_params_t const * const p_sec_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_AUTHENTICATE; - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_params, p_buf, *p_buf_len, &index, ble_gap_sec_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_AUTHENTICATE, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_conn_param_update.c b/components/serialization/application/codecs/s120/serializers/ble_gap_conn_param_update.c deleted file mode 100644 index 3d81edf..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_conn_param_update.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_conn_param_update_req_enc(uint16_t conn_handle, - ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_CONN_PARAM_UPDATE; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_conn_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_conn_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 * 4, *p_buf_len); - index += uint16_encode(p_conn_params->min_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->max_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->slave_latency, &p_buf[index]); - index += uint16_encode(p_conn_params->conn_sup_timeout, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_CONN_PARAM_UPDATE, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_conn_sec_get.c b/components/serialization/application/codecs/s120/serializers/ble_gap_conn_sec_get.c deleted file mode 100644 index b3850b1..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_conn_sec_get.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_handle, - ble_gap_conn_sec_t const * const p_conn_sec, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint8_t opcode = SD_BLE_GAP_CONN_SEC_GET; - - - err_code = uint8_t_enc(&opcode, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_conn_sec, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_sec_t * * const pp_conn_sec, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - uint32_t index = 0; - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_CONN_SEC_GET, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_conn_sec, - ble_gap_conn_sec_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_connect.c b/components/serialization/application/codecs/s120/serializers/ble_gap_connect.c deleted file mode 100644 index 5f13670..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_connect.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr, - ble_gap_scan_params_t const * const p_scan_params, - ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_CONNECT; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_peer_addr, p_buf, buf_len, &index, ble_gap_addr_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_scan_params, p_buf, buf_len, &index, ble_gap_scan_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_conn_params, p_buf, buf_len, &index, ble_gap_conn_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_CONNECT, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_connect_cancel.c b/components/serialization/application/codecs/s120/serializers/ble_gap_connect_cancel.c deleted file mode 100644 index 0730ade..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_connect_cancel.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_CONNECT_CANCEL; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_CONNECT_CANCEL, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_device_name_get.c b/components/serialization/application/codecs/s120/serializers/ble_gap_device_name_get.c deleted file mode 100644 index 0d12b4a..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_device_name_get.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name, - uint16_t const * const p_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_DEVICE_NAME_GET; - p_buf[index++] = (p_len != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - index += uint16_encode(*p_len, &p_buf[index]); - } - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_dev_name != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_dev_name, - uint16_t * const p_dev_name_len, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - uint32_t index = 0; - uint32_t status_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_DEVICE_NAME_GET, - p_result_code); - - if (status_code != NRF_SUCCESS) - { - return status_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_dev_name_len); - status_code = len16data_dec(p_buf, packet_len, &index, (uint8_t * *)&p_dev_name, p_dev_name_len); - - if (status_code != NRF_SUCCESS) - { - return status_code; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return status_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_device_name_set.c b/components/serialization/application/codecs/s120/serializers/ble_gap_device_name_set.c deleted file mode 100644 index c265c4f..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_device_name_set.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p_write_perm, - uint8_t const * const p_dev_name, - uint16_t len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(2, *p_buf_len); - p_buf[index++] = SD_BLE_GAP_DEVICE_NAME_SET; - - p_buf[index++] = (p_write_perm != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_write_perm != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (uint8_t) ((p_write_perm->sm) | (p_write_perm->lv << 4)); - } - - SER_ERROR_CHECK(len <= BLE_GAP_DEVNAME_MAX_LEN, NRF_ERROR_INVALID_PARAM); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - index += uint16_encode(len, &p_buf[index]); - - p_buf[index++] = (p_dev_name != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_dev_name != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + len, *p_buf_len); - memcpy(&p_buf[index], p_dev_name, len); - index += len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_DEVICE_NAME_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_disconnect.c b/components/serialization/application/codecs/s120/serializers/ble_gap_disconnect.c deleted file mode 100644 index d3064d6..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_disconnect.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle, - uint8_t hci_status_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 4, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_DISCONNECT; - index += uint16_encode(conn_handle, &p_buf[index]); - p_buf[index++] = hci_status_code; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_DISCONNECT, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_encrypt.c b/components/serialization/application/codecs/s120/serializers/ble_gap_encrypt.c deleted file mode 100644 index 0abf029..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_encrypt.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_encrypt_req_enc( uint16_t conn_handle, - ble_gap_master_id_t const * const p_master_id, - ble_gap_enc_info_t const * const p_enc_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_ENCRYPT; - index += uint16_encode(conn_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_master_id != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_master_id != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_RAND_LEN + 2, *p_buf_len); - index += uint16_encode(p_master_id->ediv, &p_buf[index]); - memcpy(&p_buf[index], p_master_id->rand, BLE_GAP_SEC_RAND_LEN); - index += BLE_GAP_SEC_RAND_LEN; - } - - p_buf[index++] = (p_enc_info != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_enc_info != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_KEY_LEN + 1, *p_buf_len); - memcpy(&p_buf[index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); - index += BLE_GAP_SEC_KEY_LEN; - p_buf[index++] = (p_enc_info->auth | (p_enc_info->ltk_len << 1)); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ENCRYPT, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_adv_report.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_adv_report.c deleted file mode 100644 index 256919b..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_adv_report.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE+7+1+1, packet_len); // assumed size(data) = 0 - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.adv_report)) + - sizeof (ble_gap_evt_adv_report_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_ADV_REPORT; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.adv_report.peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.adv_report.rssi)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_event->evt.gap_evt.params.adv_report.scan_rsp = byte & 0x01; - p_event->evt.gap_evt.params.adv_report.type = (byte >> 1) & 0x03; - p_event->evt.gap_evt.params.adv_report.dlen = (byte >> 3) & 0x1F; - - err_code = uint8_vector_dec(p_buf, packet_len, &index, - p_event->evt.gap_evt.params.adv_report.data, (uint16_t)(p_event->evt.gap_evt.params.adv_report.dlen)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_app.h b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_app.h deleted file mode 100644 index 736e228..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_app.h +++ /dev/null @@ -1,409 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GAP_EVT_APP_H__ -#define BLE_GAP_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gap_evt_app GAP Application event decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief GAP Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_gap_evt_auth_key_request event. - * - * @sa @ref nrf51_evt_auth_key_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_auth_status event. - * - * @sa @ref nrf51_evt_auth_status_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_conn_param_update event. - * - * @sa @ref nrf51_evt_conn_param_update_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_conn_sec_update event. - * - * @sa @ref nrf51_evt_conn_sec_update_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_connected event. - * - * @sa @ref nrf51_evt_connected_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_disconnected event. - * - * @sa @ref nrf51_evt_disconnected_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_passkey_display event. - * - * @sa @ref nrf51_evt_passkey_display for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_rssi_changed event. - * - * @sa @ref nrf51_evt_rssi_changed_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_sec_info_request event. - * - * @sa @ref nrf51_evt_sec_info_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_sec_params_request event. - * - * @sa @ref nrf51_evt_sec_param_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_timeout event. - * - * @sa @ref nrf51_evt_timeout_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_sec_request event. - * - * @sa @ref nrf51_evt_sec_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_conn_param_update_request event. - * - * @sa @ref nrf51_evt_conn_param_update_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); -/** - * @brief Decodes ble_gap_evt_adv_report event. - * - * @sa @ref nrf51_evt_adv_report_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gap_evt_scan_req_report event. - * - * @sa @ref nrf51_evt_scan_req_report_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_auth_key_request.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_auth_key_request.c deleted file mode 100644 index 090b431..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_auth_key_request.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + 1; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_AUTH_KEY_REQUEST; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.auth_key_request.key_type); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_auth_status.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_auth_status.c deleted file mode 100644 index 6f54d6a..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_auth_status.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" -#include "app_ble_gap_sec_keys.h" - -extern ser_ble_gap_app_keyset_t m_app_keys_table[]; - -uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint32_t conn_index; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 6, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.auth_status)) + - sizeof (ble_gap_evt_adv_report_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - p_event->header.evt_id = BLE_GAP_EVT_AUTH_STATUS; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_auth_status_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.auth_status)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - // keyset is an extension of standard event data - used to synchronize keys at application - err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keyset_t_dec(p_buf, packet_len, &index, &(m_app_keys_table[conn_index].keyset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = app_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_param_update.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_param_update.c deleted file mode 100644 index 33cacdc..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_param_update.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.conn_param_update)) + - sizeof (ble_gap_evt_conn_param_update_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_CONN_PARAM_UPDATE; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.min_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.max_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.slave_latency); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.conn_sup_timeout); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_param_update_request.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_param_update_request.c deleted file mode 100644 index 7bede0f..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_param_update_request.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.conn_param_update_request)) + - sizeof (ble_gap_evt_conn_param_update_request_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.min_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.max_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.slave_latency); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.conn_sup_timeout); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_sec_update.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_sec_update.c deleted file mode 100644 index 6802173..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_conn_sec_update.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.conn_sec_update)) + - sizeof (ble_gap_evt_conn_sec_update_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_CONN_SEC_UPDATE; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - p_event->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm = p_buf[index] & 0x0F; - p_event->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv = (p_buf[index] >> 4) & 0x0F; - index++; - - uint8_dec(p_buf, packet_len, - &index, &p_event->evt.gap_evt.params.conn_sec_update.conn_sec.encr_key_size); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_connected.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_connected.c deleted file mode 100644 index 0dfcd5a..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_connected.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t event_len = sizeof (ble_gap_evt_connected_t) + - sizeof (p_event->evt.gap_evt.conn_handle); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_connected_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.connected)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_disconnected.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_disconnected.c deleted file mode 100644 index fa29107..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_disconnected.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_disconnected_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_DISCONNECTED; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.disconnected.reason); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_passkey_display.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_passkey_display.c deleted file mode 100644 index 7a2f155..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_passkey_display.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey) - - -uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + PASSKEY_LEN, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_passkey_display_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_PASSKEY_DISPLAY; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - memcpy(p_event->evt.gap_evt.params.passkey_display.passkey, &p_buf[index], PASSKEY_LEN); - index += PASSKEY_LEN; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} - diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_rssi_changed.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_rssi_changed.c deleted file mode 100644 index b7de4cc..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_rssi_changed.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_rssi_changed_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_RSSI_CHANGED; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - int8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.rssi_changed.rssi); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} - diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_scan_req_report.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_scan_req_report.c deleted file mode 100644 index 118fcf2..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_scan_req_report.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.scan_req_report)) + - sizeof (ble_gap_evt_scan_req_report_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_SCAN_REQ_REPORT; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.scan_req_report.peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.scan_req_report.rssi)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_info_request.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_info_request.c deleted file mode 100644 index ff3d0af..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_info_request.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.sec_info_request)) + - sizeof (ble_gap_evt_sec_info_request_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_SEC_INFO_REQUEST; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - err_code = ble_gap_evt_sec_info_request_t_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.sec_info_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_params_request.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_params_request.c deleted file mode 100644 index 0386291..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_params_request.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(7, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_sec_params_request_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - p_event->header.evt_id = BLE_GAP_EVT_SEC_PARAMS_REQUEST; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_params_request_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.sec_params_request)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_request.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_request.c deleted file mode 100644 index f080405..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_sec_request.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gap_evt_app.h" -#include "ble_gap_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - uint32_t event_len = sizeof (ble_gap_evt_sec_request_t) + - sizeof (p_event->evt.gap_evt.conn_handle); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - ble_gap_evt_sec_request_t * p_decoded_evt = &(p_event->evt.gap_evt.params.sec_request); - - uint32_t err_code = ble_gap_evt_sec_request_t_dec(p_buf, packet_len, &index, p_decoded_evt); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_timeout.c b/components/serialization/application/codecs/s120/serializers/ble_gap_evt_timeout.c deleted file mode 100644 index 8fdb83b..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_evt_timeout.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_EQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_timeout_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_TIMEOUT; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.timeout.src); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_ppcp_get.c b/components/serialization/application/codecs/s120/serializers/ble_gap_ppcp_get.c deleted file mode 100644 index e3c8b07..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_ppcp_get.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" - - -uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_PPCP_GET; - p_buf[index++] = (p_conn_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_params_t * const p_conn_params, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_PPCP_GET, p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_conn_params); - - SER_ASSERT_LENGTH_LEQ(index + 8, packet_len); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->min_conn_interval); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->max_conn_interval); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->slave_latency); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->conn_sup_timeout); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return decode_result; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_ppcp_set.c b/components/serialization/application/codecs/s120/serializers/ble_gap_ppcp_set.c deleted file mode 100644 index 15e5528..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_ppcp_set.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "nrf_error.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_PPCP_SET; - p_buf[index++] = (p_conn_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_conn_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 8, *p_buf_len); - index += uint16_encode(p_conn_params->min_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->max_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->slave_latency, &p_buf[index]); - index += uint16_encode(p_conn_params->conn_sup_timeout, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_PPCP_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_rssi_get.c b/components/serialization/application/codecs/s120/serializers/ble_gap_rssi_get.c deleted file mode 100644 index 24b4b2c..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_rssi_get.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle, - int8_t const * const p_rssi, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - SER_ASSERT_LENGTH_LEQ(index + 1, total_len); - - p_buf[index++] = SD_BLE_GAP_RSSI_GET; - - err_code = uint16_t_enc(&conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_rssi, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - int8_t * const p_rssi, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GAP_RSSI_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - decode_result = uint8_t_dec(p_buf, packet_len, &index, (uint8_t *) p_rssi); - SER_ASSERT(decode_result == NRF_SUCCESS, decode_result); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return decode_result; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_rssi_start.c b/components/serialization/application/codecs/s120/serializers/ble_gap_rssi_start.c deleted file mode 100644 index 539b8b6..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_rssi_start.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle, - uint8_t threshold_dbm, - uint8_t skip_count, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_RSSI_START; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&threshold_dbm, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&skip_count, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_RSSI_START, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_rssi_stop.c b/components/serialization/application/codecs/s120/serializers/ble_gap_rssi_stop.c deleted file mode 100644 index 49ef65e..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_rssi_stop.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - uint8_t op_code = SD_BLE_GAP_RSSI_STOP; - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_RSSI_STOP, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_scan_start.c b/components/serialization/application/codecs/s120/serializers/ble_gap_scan_start.c deleted file mode 100644 index a92ab3b..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_scan_start.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "cond_field_serialization.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SCAN_START; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = cond_field_enc(p_scan_params, p_buf, buf_len, &index, ble_gap_scan_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_SCAN_START, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_scan_stop.c b/components/serialization/application/codecs/s120/serializers/ble_gap_scan_stop.c deleted file mode 100644 index 72e7c4a..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_scan_stop.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" - -uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SCAN_STOP; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_SCAN_STOP, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_sec_info_reply.c b/components/serialization/application/codecs/s120/serializers/ble_gap_sec_info_reply.c deleted file mode 100644 index 0739b31..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_sec_info_reply.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gap.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle, - ble_gap_enc_info_t const * p_enc_info, - ble_gap_irk_t const * p_id_info, - ble_gap_sign_info_t const * p_sign_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SEC_INFO_REPLY; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - p_buf[index++] = (p_enc_info != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_enc_info != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_KEY_LEN + 1, buf_len); - memcpy(&p_buf[index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); - index += BLE_GAP_SEC_KEY_LEN; - p_buf[index++] = (p_enc_info->auth | (p_enc_info->ltk_len << 1)); - } - - err_code = cond_field_enc(p_id_info, p_buf, buf_len, &index, ble_gap_irk_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - p_buf[index++] = (p_sign_info != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_sign_info != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_KEY_LEN, buf_len); - memcpy(&p_buf[index], p_sign_info->csrk, BLE_GAP_SEC_KEY_LEN); - index += BLE_GAP_SEC_KEY_LEN; - } - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_SEC_INFO_REPLY, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_sec_params_reply.c b/components/serialization/application/codecs/s120/serializers/ble_gap_sec_params_reply.c deleted file mode 100644 index d04189d..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_sec_params_reply.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_sec_params_reply_req_enc(uint16_t conn_handle, - uint8_t sec_status, - ble_gap_sec_params_t const * const p_sec_params, - ble_gap_sec_keyset_t const * const p_sec_keyset, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SEC_PARAMS_REPLY; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&sec_status, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_params, p_buf, buf_len, &index, ble_gap_sec_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_keyset, p_buf, buf_len, &index, ble_gap_sec_keyset_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_sec_keyset_t const * const p_sec_keyset, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, SD_BLE_GAP_SEC_PARAMS_REPLY, p_result_code); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_sec_keyset); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **)&p_sec_keyset, ble_gap_sec_keyset_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gap_tx_power_set.c b/components/serialization/application/codecs/s120/serializers/ble_gap_tx_power_set.c deleted file mode 100644 index 807eb78..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gap_tx_power_set.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_tx_power_set_req_enc(int8_t tx_power, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_TX_POWER_SET; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&tx_power, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_TX_POWER_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_app.h b/components/serialization/application/codecs/s120/serializers/ble_gattc_app.h deleted file mode 100644 index 5ec92e8..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_app.h +++ /dev/null @@ -1,406 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_APP_H__ -#define BLE_GATTC_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gattc_app GATTC Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief GATTC Application command request encoders and command response decoders. - */ -#include "ble_gattc.h" -#include "ble.h" - -/**@brief Encodes @ref sd_ble_gattc_primary_services_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] start_handle Handle to start searching from. - * @param[in] p_srvc_uuid Pointer to a @ref ble_uuid_t which indicates the service UUID to - * be found. If it is NULL, all primary services will be returned. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle, - uint16_t start_handle, - ble_uuid_t const * const p_srvc_uuid, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_primary_services_discover command. - * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_descriptors_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format, - * @ref ble_gattc_descriptors_discover_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform - * this procedure on. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_descriptors_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len); - - -/**@brief Decodes response to @ref sd_ble_gattc_descriptors_discover command. - * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_relationships_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format, - * @ref ble_gattc_relationships_discover_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform - * this procedure on. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_relationships_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_relationships_discover command. - * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format, - * @ref ble_gattc_relationships_discover_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_characteristics_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format, - * @ref ble_gattc_characteristics_discover_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform - * this procedure on. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_characteristics_discover_req_enc - (uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_characteristics_discover command. - * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format, - * @ref ble_gattc_read_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] handle The handle of the attribute to be read. - * @param[in] offset Offset into the attribute value to be read. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_read_req_enc(uint16_t conn_handle, - uint16_t handle, - uint16_t offset, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_read command. - * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format, - * @ref ble_gattc_read_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_char_values_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format, - * @ref ble_gattc_char_values_read_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. - * @param[in] handle_count The number of handles in p_handles. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle, - uint16_t const * const p_handles, - uint16_t handle_count, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_char_values_read command. - * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format, - * @ref ble_gattc_char_values_read_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_write command request. - * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format, - * @ref ble_gattc_write_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_write_params Pointer to \ref sd_ble_gattc_write params. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_write_req_enc(uint16_t conn_handle, - ble_gattc_write_params_t const * const p_write_params, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_write command. - * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format, - * @ref ble_gattc_write_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_hv_confirm command request. - * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format, - * @ref ble_gattc_hv_confirm_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] handle Handle of the attribute in the indication. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle, - uint16_t handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_hv_confirm command. - * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format, - * @ref ble_gattc_hv_confirm_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Pointer to command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gattc_char_value_by_uuid_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format, - * @ref ble_gattc_char_value_by_uuid_read_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_uuid Pointer to a characteristic value UUID to read. - * @param[in] p_handle_range Pointer to the range of handles to perform this procedure on. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_char_value_by_uuid_read_req_enc - (uint16_t conn_handle, - ble_uuid_t const * const p_uuid, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gattc_char_value_by_uuid_read command. - * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format, - * @ref ble_gattc_char_value_by_uuid_read_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Pointer to command response result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected - * operation code. - */ -uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); -/** @} */ -#endif - - diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_char_value_by_uuid_read.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_char_value_by_uuid_read.c deleted file mode 100644 index 7b75815..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_char_value_by_uuid_read.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "cond_field_serialization.h" -#include "ble_types.h" -#include - -uint32_t ble_gattc_char_value_by_uuid_read_req_enc - (uint16_t conn_handle, - ble_uuid_t const * const p_uuid, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code; - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_uuid, p_buf, buf_len, &index, ble_uuid_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_handle_range, p_buf, buf_len, &index, ble_gattc_handle_range_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, - packet_len, - SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, - p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_char_values_read.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_char_values_read.c deleted file mode 100644 index 6dc1e17..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_char_values_read.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle, - uint16_t const * const p_handles, - uint16_t handle_count, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint32_t err_code; - uint8_t opCode = SD_BLE_GATTC_CHAR_VALUES_READ; - - err_code = uint8_t_enc(&opCode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = count16_cond_data16_enc(p_handles, handle_count, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - *p_buf_len = index; - return err_code; -} - - -uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_CHAR_VALUES_READ, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_characteristics_discover.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_characteristics_discover.c deleted file mode 100644 index b98d142..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_characteristics_discover.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_characteristics_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_CHARACTERISTICS_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_handle_range != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_handle_range != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, *p_buf_len); - - index += uint16_encode(p_handle_range->start_handle, &p_buf[index]); - index += uint16_encode(p_handle_range->end_handle, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, - p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_descriptors_discover.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_descriptors_discover.c deleted file mode 100644 index 28e1a21..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_descriptors_discover.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_descriptors_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_DESCRIPTORS_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - p_buf[index++] = (p_handle_range == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_handle_range != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, *p_buf_len); - index += uint16_encode(p_handle_range->start_handle, &p_buf[index]); - index += uint16_encode(p_handle_range->end_handle, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_DESCRIPTORS_DISCOVER, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_app.h b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_app.h deleted file mode 100644 index f8ed84b..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_app.h +++ /dev/null @@ -1,286 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_EVT_APP_H__ -#define BLE_GATTC_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gattc_evt_app GATTC Application event decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief GATTC Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_gattc_evt_char_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_disc_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_char_val_by_uuid_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_val_by_uuid_read_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_char_vals_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_vals_read_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_desc_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_desc_disc_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_hvx event. - * - * @sa @ref nrf51_gattc_evt_hvx_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_prim_srvc_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_prim_srvc_disc_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_read_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_rel_disc_rsp_dec event. - * - * @sa @ref nrf51_gattc_evt_rel_disc_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_timeout event. - * - * @sa @ref nrf51_gattc_evt_timeout_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gattc_evt_write_rsp event. - * - * @sa @ref nrf51_gattc_evt_write_rsp_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_disc_rsp.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_disc_rsp.c deleted file mode 100644 index cdc6532..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_disc_rsp.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "nordic_common.h" - - -uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(2 + 2 + 2 + 2, packet_len); - - uint16_t tmp_conn_handle; - uint16_t tmp_gatt_status; - uint16_t tmp_error_handle; - uint16_t tmp_service_count; - uint16_dec(p_buf, packet_len, &index, &tmp_conn_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_gatt_status); - uint16_dec(p_buf, packet_len, &index, &tmp_error_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_service_count); - - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.char_disc_rsp) + - sizeof (uint16_t) + tmp_service_count * sizeof (ble_gattc_char_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_CHAR_DISC_RSP; - p_event->header.evt_len = event_len; - p_event->evt.gattc_evt.conn_handle = tmp_conn_handle; - p_event->evt.gattc_evt.gatt_status = tmp_gatt_status; - p_event->evt.gattc_evt.error_handle = tmp_error_handle; - p_event->evt.gattc_evt.params.char_disc_rsp.count = tmp_service_count; - - SER_ASSERT_LENGTH_LEQ(index + (tmp_service_count * 9), packet_len); - - for (uint16_t i = 0; i < tmp_service_count; i++) - { - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.uuid); - uint8_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.type); - - uint8_t characteristic_props; - uint8_dec(p_buf, packet_len, &index, &characteristic_props); - - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.broadcast = - !!(characteristic_props & BIT_0); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.read = - !!(characteristic_props & BIT_1); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.write_wo_resp = - !!(characteristic_props & BIT_2); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.write = - !!(characteristic_props & BIT_3); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.notify = - !!(characteristic_props & BIT_4); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.indicate = - !!(characteristic_props & BIT_5); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.auth_signed_wr = - !!(characteristic_props & BIT_6); - - uint8_t characteristic_ext_props; - uint8_dec(p_buf, packet_len, &index, &characteristic_ext_props); - - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_ext_props = - characteristic_ext_props & BIT_0; - - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_decl); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_value); - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c deleted file mode 100644 index 93d89dc..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_util.h" -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_gattc_evt_app.h" - - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code; - uint16_t conn_handle; - uint16_t gatt_status; - uint16_t error_handle; - - SER_ASSERT_LENGTH_LEQ(6, packet_len - index); - - uint32_t in_event_len = *p_event_len; - - *p_event_len = (offsetof(ble_evt_t, evt.gattc_evt.params)) - sizeof (ble_evt_hdr_t); - - uint16_dec(p_buf, packet_len, &index, &conn_handle); - uint16_dec(p_buf, packet_len, &index, &gatt_status); - uint16_dec(p_buf, packet_len, &index, &error_handle); - - void * p_data = NULL; - - if (p_event) - { - SER_ASSERT_LENGTH_LEQ(*p_event_len, in_event_len); - - p_event->header.evt_id = BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP; - p_event->evt.gattc_evt.conn_handle = conn_handle; - p_event->evt.gattc_evt.gatt_status = gatt_status; - p_event->evt.gattc_evt.error_handle = error_handle; - - p_data = &p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp; - } - else - { - p_data = NULL; - } - - //call struct decoder with remaining size of event struct - uint32_t temp_event_len = in_event_len - *p_event_len; - err_code = ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(p_buf, packet_len, &index, - &temp_event_len, p_data); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - //update event length with the amount processed by struct decoder - *p_event_len += temp_event_len; - - if (p_event) - { - p_event->header.evt_len = *p_event_len; - } - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_vals_read_rsp.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_vals_read_rsp.c deleted file mode 100644 index 4e99a17..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_char_vals_read_rsp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_gattc_struct_serialization.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -#define BLE_GATTC_EVT_CHAR_VALS_READ_RSP_LEN_POSITION 6 - - -uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len = 0; - - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(10, packet_len); - - event_len = (uint16_t) (offsetof(ble_evt_t, evt.gattc_evt.params.char_vals_read_rsp.values)) - - sizeof (ble_evt_hdr_t) + - uint16_decode(&p_buf[BLE_GATTC_EVT_CHAR_VALS_READ_RSP_LEN_POSITION]); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - else - { - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - *p_event_len = event_len; - } - - p_event->header.evt_id = BLE_GATTC_EVT_CHAR_VALS_READ_RSP; - - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - - //Event structure for BLE_GATTC_EVT_CHAR_VALS_READ_RSP - error_code = - ble_gattc_evt_char_vals_read_rsp_t_dec(p_buf, packet_len, &index, - &(p_event->evt.gattc_evt.params.char_vals_read_rsp)); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return error_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_desc_disc_rsp.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_desc_disc_rsp.c deleted file mode 100644 index 6e44502..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_desc_disc_rsp.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 6, packet_len); - - uint16_t tmp_conn_handle; - uint16_t tmp_gatt_status; - uint16_t tmp_error_handle; - uint16_t tmp_service_count; - uint16_dec(p_buf, packet_len, &index, &tmp_conn_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_gatt_status); - uint16_dec(p_buf, packet_len, &index, &tmp_error_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_service_count); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.desc_disc_rsp) + - sizeof (uint16_t) + tmp_service_count * sizeof (ble_gattc_desc_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_DESC_DISC_RSP; - p_event->header.evt_len = event_len; - p_event->evt.gattc_evt.conn_handle = tmp_conn_handle; - p_event->evt.gattc_evt.gatt_status = tmp_gatt_status; - p_event->evt.gattc_evt.error_handle = tmp_error_handle; - p_event->evt.gattc_evt.params.desc_disc_rsp.count = tmp_service_count; - - SER_ASSERT_LENGTH_LEQ(index + (tmp_service_count * 5), packet_len); - - for (uint16_t i = 0; i < tmp_service_count; i++) - { - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].handle); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.uuid); - uint8_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.type); - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_hvx.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_hvx.c deleted file mode 100644 index f20f499..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_hvx.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint16_t tmp_attr_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(11, packet_len); - - tmp_attr_len = uint16_decode(&(p_buf[9])); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.hvx) + - sizeof (ble_gattc_evt_hvx_t) - 1 + tmp_attr_len; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_HVX; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.handle)); - uint8_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.type)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.len)); - - SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); - - if (tmp_attr_len > 0) - { - memcpy(&(p_event->evt.gattc_evt.params.hvx.data[0]), &(p_buf[index]), tmp_attr_len); - index += tmp_attr_len; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c deleted file mode 100644 index 85d43c0..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 6, packet_len); - - uint16_t tmp_conn_handle; - uint16_t tmp_gatt_status; - uint16_t tmp_error_handle; - uint16_t tmp_service_count; - uint16_dec(p_buf, packet_len, &index, &tmp_conn_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_gatt_status); - uint16_dec(p_buf, packet_len, &index, &tmp_error_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_service_count); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp) + - sizeof (uint16_t) + tmp_service_count * sizeof (ble_gattc_service_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP; - p_event->header.evt_len = event_len; - p_event->evt.gattc_evt.conn_handle = tmp_conn_handle; - p_event->evt.gattc_evt.gatt_status = tmp_gatt_status; - p_event->evt.gattc_evt.error_handle = tmp_error_handle; - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.count = tmp_service_count; - - SER_ASSERT_LENGTH_LEQ(index + (tmp_service_count * 7), packet_len); - - for (uint16_t i = 0; i < tmp_service_count; i++) - { - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.uuid); - uint8_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.type); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - start_handle); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - end_handle); - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_read_rsp.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_read_rsp.c deleted file mode 100644 index a851447..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_read_rsp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint16_t tmp_attr_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(12, packet_len); - - tmp_attr_len = uint16_decode(&(p_buf[10])); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.read_rsp) + - sizeof (ble_gattc_evt_read_rsp_t) - 1 + tmp_attr_len; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_READ_RSP; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.read_rsp.handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.read_rsp.offset)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.read_rsp.len)); - - SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); - - if (tmp_attr_len > 0) - { - memcpy(&(p_event->evt.gattc_evt.params.read_rsp.data[0]), &(p_buf[index]), tmp_attr_len); - index += tmp_attr_len; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_rel_disc_rsp.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_rel_disc_rsp.c deleted file mode 100644 index 7f0bd9f..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_rel_disc_rsp.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - -#define BLE_GATTC_EVT_REL_DISC_RSP_COUNT_POSITION 6 - - -uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len = 0; - uint16_t include_count = 0; - - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(8, packet_len); - - include_count = uint16_decode(&p_buf[BLE_GATTC_EVT_REL_DISC_RSP_COUNT_POSITION]); - event_len = (uint16_t) (offsetof(ble_evt_t, evt.gattc_evt.params.rel_disc_rsp.includes)) - - sizeof (ble_evt_hdr_t) + (include_count * sizeof (ble_gattc_include_t)); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_REL_DISC_RSP; - error_code = - uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = - ble_gattc_evt_rel_disc_rsp_t_dec(p_buf, packet_len, &index, - &(p_event->evt.gattc_evt.params.rel_disc_rsp)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return error_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_timeout.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_timeout.c deleted file mode 100644 index 8f831d3..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_timeout.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - event_len = offsetof(ble_evt_t, evt.gattc_evt.params.timeout) + - sizeof (ble_gattc_evt_timeout_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_TIMEOUT; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gattc_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gattc_evt.params.timeout.src); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_write_rsp.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_write_rsp.c deleted file mode 100644 index bfed5e2..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_evt_write_rsp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(13, packet_len); - - uint16_t tmp_attr_len = uint16_decode(&(p_buf[11])); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.write_rsp) + - sizeof (ble_gattc_evt_write_rsp_t) - 1 + tmp_attr_len; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_WRITE_RSP; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.handle)); - uint8_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.write_op)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.offset)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.len)); - - SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); - - if (tmp_attr_len > 0) - { - memcpy(&(p_event->evt.gattc_evt.params.write_rsp.data[0]), &(p_buf[index]), tmp_attr_len); - index += tmp_attr_len; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_hv_confirm.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_hv_confirm.c deleted file mode 100644 index f745640..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_hv_confirm.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle, - uint16_t handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GATTC_HV_CONFIRM; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - -uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_HV_CONFIRM, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_primary_services_discover.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_primary_services_discover.c deleted file mode 100644 index 762508b..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_primary_services_discover.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle, - uint16_t start_handle, - ble_uuid_t const * const p_srvc_uuid, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 5, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - index += uint16_encode(start_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - - p_buf[index++] = (p_srvc_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_srvc_uuid != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - index += uint16_encode(p_srvc_uuid->uuid, &p_buf[index]); - p_buf[index++] = p_srvc_uuid->type; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, - p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_read.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_read.c deleted file mode 100644 index 1d4b5ec..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_read.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_read_req_enc(uint16_t conn_handle, - uint16_t handle, - uint16_t offset, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 7, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_READ; - index += uint16_encode(conn_handle, &p_buf[index]); - index += uint16_encode(handle, &p_buf[index]); - index += uint16_encode(offset, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_READ, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_relationships_discover.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_relationships_discover.c deleted file mode 100644 index 943457e..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_relationships_discover.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_relationships_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_RELATIONSHIPS_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_handle_range != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_handle_range != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 4, *p_buf_len); - - index += uint16_encode(p_handle_range->start_handle, &p_buf[index]); - index += uint16_encode(p_handle_range->end_handle, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, - p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gattc_write.c b/components/serialization/application/codecs/s120/serializers/ble_gattc_write.c deleted file mode 100644 index edfe93a..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gattc_write.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_write_req_enc(uint16_t conn_handle, - ble_gattc_write_params_t const * const p_write_params, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 4, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_WRITE; - index += uint16_encode(conn_handle, &p_buf[index]); - p_buf[index++] = (p_write_params == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_write_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 9, *p_buf_len); - p_buf[index++] = p_write_params->write_op; - p_buf[index++] = p_write_params->flags; - index += uint16_encode(p_write_params->handle, &p_buf[index]); - index += uint16_encode(p_write_params->offset, &p_buf[index]); - index += uint16_encode(p_write_params->len, &p_buf[index]); - - SER_ERROR_CHECK(p_write_params->len <= BLE_GATTC_WRITE_P_VALUE_LEN_MAX, - NRF_ERROR_INVALID_PARAM); - - p_buf[index++] = (p_write_params->p_value == NULL) ? - SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_write_params->p_value != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + p_write_params->len, *p_buf_len); - memcpy(&p_buf[index], p_write_params->p_value, p_write_params->len); - index += p_write_params->len; - } - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_WRITE, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_app.h b/components/serialization/application/codecs/s120/serializers/ble_gatts_app.h deleted file mode 100644 index 7b837b1..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_app.h +++ /dev/null @@ -1,554 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_APP_H__ -#define BLE_GATTS_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gatts_app GATTS Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief GATTS Application command request encoders and command response decoders. - */ -#include "ble_gatts.h" -#include "ble.h" - -/**@brief Encodes @ref sd_ble_gatts_value_get command request. - * - * @sa @ref nrf51_gatts_value_get_encoding for packet format, - * @ref ble_gatts_value_get_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] handle Attribute handle. - * @param[in] p_value Pointer to attribute value information. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_data_len and \p p_data will not be updated by the command - * request encoder. Updated values are set by @ref ble_gatts_value_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t const * const p_value, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_value_get command. - * - * @sa @ref nrf51_gatts_value_get_encoding for packet format, - * @ref ble_gatts_value_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_value Pointer to structure where the attribute value will be stored. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Length of \p p_value is too small to hold decoded - * value from response. - */ -uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gatts_value_t * const p_value, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_hvx command request. - * - * @sa @ref nrf51_gatts_hvx_encoding for packet format, - * @ref ble_gatts_hvx_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_hvx_params Pointer to an HVx parameters structure to be encoded. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_hvx_params will not be updated by the command - * request encoder. Updated values are set by @ref ble_gatts_hvx_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle, - ble_gatts_hvx_params_t const * const p_hvx_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_hvx command. - * - * @sa @ref nrf51_gatts_hvx_encoding for packet format, - * @ref ble_gatts_hvx_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * @param[out] pp_bytes_written Pointer to pointer to location where number of bytes is written. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - uint16_t * * const pp_bytes_written); - -/**@brief Encodes @ref sd_ble_gatts_characteristic_add command request. - * - * @sa @ref nrf51_characteristics_add_encoding for packet format, - * @ref ble_gatts_characteristic_add_rsp_dec for command response decoder. - * - * @param[in] service_handle Handle of the service where the characteristic is to be placed. - * If @ref BLE_GATT_HANDLE_INVALID is used, it will be placed - * sequentially. - * @param[in] p_char_md Pointer to a @ref ble_gatts_char_md_t structure, characteristic - * metadata. - * @param[in] p_attr_char_value Pointer to a @ref ble_gatts_attr_t structure, corresponding to - * the characteristic value. - * @param[in] p_handles Pointer to a @ref ble_gatts_char_handles_t structure, where the - * assigned handles will be stored. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_handles will not be updated by the command - * request encoder. Updated values are set by @ref ble_gatts_characteristic_add_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_characteristic_add_req_enc - (uint16_t service_handle, - ble_gatts_char_md_t const * const p_char_md, - ble_gatts_attr_t const * const p_attr_char_value, - ble_gatts_char_handles_t const * const p_handles, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_characteristic_add command. - * - * @sa @ref nrf51_characteristics_add_encoding for packet format, - * @ref ble_gatts_characteristic_add_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_handles Pointer to pointer to location where handles should be decoded. - * @param[out] p_result_code Pointer to command result code decode location. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * * const pp_handles, - uint32_t * const p_result_code); - - -/**@brief Encodes @ref sd_ble_gatts_service_add command request. - * - * @sa @ref nrf51_gatts_service_add_encoding for packet format, - * @ref ble_gatts_service_add_rsp_dec for command response decoder. - * - * @param[in] type Toggles between primary and secondary services, - * see @ref BLE_GATTS_SRVC_TYPES. - * @param[in] p_uuid Pointer to service UUID. - * @param[in] p_conn_handle Pointer to a 16-bit word where the assigned handle will be stored. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_conn_handle will not be updated by the command - * request encoder. Updated values are set by @ref ble_gatts_service_add_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_service_add_req_enc(uint8_t type, - ble_uuid_t const * const p_uuid, - uint16_t const * const p_conn_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_service_add command. - * - * @sa @ref nrf51_gatts_service_add_encoding for packet format, - * @ref ble_gatts_service_add_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Connection handle. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_sys_attr_set command request. - * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format, - * @ref ble_gatts_sys_attr_set_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_sys_attr_data Pointer to a buffer (at least \p sys_attr_data_len bytes long) - * containing the attribute value to write. - * @param[in] sys_attr_data_len Length (in bytes) of \p p_sys_attr_data. - * @param[in] flags Optional additional flags. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t sys_attr_data_len, - uint32_t flags, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_sys_attr_set command. - * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format, - * @ref ble_gatts_sys_attr_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_value_set command request. - * - * @sa @ref nrf51_gatts_value_set_encoding for packet format, - * @ref ble_gatts_value_set_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] handle Attribute handle. - * @param[in] p_value Pointer to attribute value information. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t * p_value, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_value_set command. - * - * @sa @ref nrf51_gatts_value_set_encoding for packet format, - * @ref ble_gatts_value_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_value Pointer to attribute value information.. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gatts_value_t * const p_value, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_sys_attr_get command request. - * - * @sa @ref nrf51_gatts_sys_attr_get_encoding for packet format, - * @ref ble_gatts_sys_attr_get_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_sys_attr_data Pointer to buffer where updated information about system - * attributes will be stored. Can be NULL to calculate required - * size. - * @param[in] p_sys_attr_data_len Size of p_sys_attr_data buffer if \p p_sys_attr_data is - * not NULL. - * @param[in] flags Additional optional flags. - * @param[in,out] p_buf Pointer to buffer where encoded data command will - * be returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_sys_attr_data and \p p_sys_attr_data_len will not be updated by the command - * request encoder. Updated values are set by @ref ble_gatts_sys_attr_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t const * const p_sys_attr_data_len, - uint32_t flags, - uint8_t * const p_buf, - uint32_t * p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_sys_attr_get command. - * - * @sa @ref nrf51_gatts_sys_attr_get_encoding for packet format, - * @ref ble_gatts_sys_attr_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system - * attributes will be stored. - * @param[in,out] p_sys_attr_data_len \c in: Size (in bytes) of \p p_sys_attr_data buffer. - * \c out: Length of decoded contents of \p p_sys_attr_data. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Length of \p p_sys_attr_data is too small to hold decoded - * value from response. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_sys_attr_data, - uint16_t * const p_sys_attr_data_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_descriptor_add command request. - * - * @sa @ref nrf51_descriptor_add_encoding for packet format, - * @ref ble_gatts_descriptor_add_rsp_dec for command response decoder. - * - * @param[in] char_handle Handle of the characteristic where the description is to be placed. - * If @ref BLE_GATT_HANDLE_INVALID is used, it will be placed - * sequentially. - * @param[in] p_attr Pointer to a @ref ble_gatts_attr_t structure, characteristic - * metadata. - * @param[in] p_handle Pointer to a @ref ble_gatts_char_handles_t structure, where the - * assigned handles will be stored. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_handle, - ble_gatts_attr_t const * const p_attr, - uint16_t * const p_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_descriptor_add command. - * - * @sa @ref nrf51_descriptor_add_encoding for packet format, - * @ref ble_gatts_descriptor_add_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_handle Pointer to bufer where descriptor handle will be - returned. - * @param[out] p_result_code Pointer to command result code decode location. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_handle, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_include_add command request. - * - * @sa @ref nrf51_gatts_include_add_encoding for packet format, - * @ref ble_gatts_include_add_rsp_dec for command response decoder. - * - * @param[in] service_handle Handle of the service where the included service is to be placed. - * @param[in] inc_srvc_handle Handle of the included service - * @param[in] p_include_handle Pointer to Pointer to a 16-bit word where the assigned handle will be stored. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle, - uint16_t inc_srvc_handle, - uint16_t * const p_include_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_include_add command. - * - * @sa @ref nrf51_gatts_include_add_encoding for packet format, - * @ref ble_gatts_include_add_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. - * @param[out] p_result_code Pointer to command result code decode location. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_include_handle, - uint32_t * const p_result_code); - - -/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command request. - * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format, - * @ref ble_gatts_rw_authorize_reply_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_reply_params Pointer to \ref ble_gatts_rw_authorize_reply_params_t - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params. - */ -uint32_t ble_gatts_rw_authorize_reply_req_enc( - uint16_t conn_handle, - ble_gatts_rw_authorize_reply_params_t const * const - p_reply_params, - uint8_t * const - p_buf, - uint32_t * const - p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_rw_authorize_reply command. - * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format, - * @ref ble_gatts_rw_authorize_reply_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_gatts_service_changed command request. - * - * @sa @ref nrf51_service_changed_encoding for packet format, - * @ref ble_gatts_service_changed_rsp_dec for command response decoder. - * - * @param[in] conn_handle Connection handle. - * @param[in] start_handle Start of affected attribute handle range. - * @param[in] end_handle End of affected attribute handle range. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params. - */ -uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_ble_gatts_service_changed command. - * - * @sa @ref nrf51_service_changed_encoding for packet format, - * @ref ble_gatts_service_changed_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/** @} */ -#endif //BLE_GATTS_APP_H__ - - diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_characteristic_add.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_characteristic_add.c deleted file mode 100644 index 75e164d..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_characteristic_add.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - -uint32_t ble_gatts_characteristic_add_req_enc( - uint16_t service_handle, - ble_gatts_char_md_t const * const p_char_md, - ble_gatts_attr_t const * const p_attr_char_value, - ble_gatts_char_handles_t const * const p_handles, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint8_t opcode = SD_BLE_GATTS_CHARACTERISTIC_ADD; - uint32_t buf_len = *p_buf_len; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&service_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md, p_buf, buf_len, &index, ble_gatts_char_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_attr_char_value, p_buf, buf_len, &index, ble_gatts_attr_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_handles, p_buf, buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * * const pp_handles, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, buf_len, - SD_BLE_GATTS_CHARACTERISTIC_ADD, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, buf_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, - buf_len, - &index, - (void * *)pp_handles, - ble_gatts_char_handles_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_descriptor_add.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_descriptor_add.c deleted file mode 100644 index ea895bb..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_descriptor_add.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - - -#include "ble_gatts_app.h" -#include -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - - -uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_handle, - ble_gatts_attr_t const * const p_attr, - uint16_t * const p_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - p_buf[index++] = SD_BLE_GATTS_DESCRIPTOR_ADD; - - uint32_t err_code = uint16_t_enc(&char_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_attr, - p_buf, - *p_buf_len, - &index, - ble_gatts_attr_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_handle != NULL) ? SER_FIELD_PRESENT : - SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_handle, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_DESCRIPTOR_ADD, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - SER_ASSERT_NOT_NULL(p_handle); - - uint16_dec(p_buf, packet_len, &index, p_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_app.h b/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_app.h deleted file mode 100644 index 537e92b..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_app.h +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_EVT_APP_H__ -#define BLE_GATTS_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gatts_evt_app GATTS Application event decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief GATTS Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_gatts_evt_hvc event. - * - * @sa @ref nrf51_gatts_evt_hvc_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gatts_evt_rw_authorize_request event. - * - * @sa @ref nrf51_evt_rw_authorize_request for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gatts_evt_sc_confirm event. - * - * @sa @ref nrf51_gatts_evt_sc_confirm_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gatts_evt_sys_attr_missing event. - * - * @sa @ref nrf51_evt_sys_attr_missing_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gatts_evt_timeout event. - * - * @sa @ref nrf51_gatts_evt_timeout_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_gatts_evt_write event. - * - * @sa @ref nrf51_evt_write_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_hvc.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_hvc.c deleted file mode 100644 index 2c1c5aa..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_hvc.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gatts_evt_hvc_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_HVC; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.conn_handle); - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.params.hvc.handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_rw_authorize_request.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_rw_authorize_request.c deleted file mode 100644 index 86f1b35..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_rw_authorize_request.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t in_event_len = *p_event_len; - - *p_event_len = offsetof(ble_evt_t, evt.gatts_evt.params) - sizeof (ble_evt_hdr_t); - - uint16_t conn_handle; - err_code = uint16_t_dec(p_buf, packet_len, &index, &conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - void * p_void_authorize_request = NULL; - - if (p_event != NULL) - { - SER_ASSERT_LENGTH_LEQ(*p_event_len, in_event_len); - - p_event->header.evt_id = BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST; - p_event->evt.gatts_evt.conn_handle = conn_handle; - - p_void_authorize_request = &(p_event->evt.gatts_evt.params.authorize_request); - } - uint32_t tmp_event_len = in_event_len - *p_event_len; - err_code = ble_gatts_evt_rw_authorize_request_t_dec(p_buf, - packet_len, - &index, - &tmp_event_len, - p_void_authorize_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_event_len += tmp_event_len; - - if(p_event != NULL) - { - if((p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)) - { - uint32_t conn_index; - - if(app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_dec(p_buf, packet_len, &index, &m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_sc_confirm.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_sc_confirm.c deleted file mode 100644 index d8d440f..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_sc_confirm.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_SC_CONFIRM; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.conn_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_sys_attr_missing.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_sys_attr_missing.c deleted file mode 100644 index 8b17268..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_sys_attr_missing.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gatts_evt.params.sys_attr_missing)) + - sizeof (ble_gatts_evt_sys_attr_missing_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_SYS_ATTR_MISSING; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.params.sys_attr_missing.hint); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_timeout.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_timeout.c deleted file mode 100644 index fba0b11..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_timeout.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gatts_evt_timeout_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_TIMEOUT; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.params.timeout.src); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_write.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_write.c deleted file mode 100644 index d6e7918..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_evt_write.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - uint32_t in_event_len = *p_event_len; - - *p_event_len = offsetof(ble_evt_t, evt.gatts_evt.params) - sizeof (ble_evt_hdr_t); - - uint16_t conn_handle; - err_code = uint16_t_dec(p_buf, packet_len, &index, &conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - void * p_void_write = NULL; - - if (p_event != NULL) - { - SER_ASSERT_LENGTH_LEQ(*p_event_len, in_event_len); - p_event->evt.gatts_evt.conn_handle = conn_handle; - - p_void_write = &(p_event->evt.gatts_evt.params.write); - } - - uint32_t tmp_struct_len = in_event_len - *p_event_len; - err_code = ble_gatts_evt_write_t_dec(p_buf, - packet_len, - &index, - &tmp_struct_len, - p_void_write); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_event_len += tmp_struct_len; - - if(p_event != NULL) - { - if(p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) - { - uint32_t conn_index; - - if(app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_dec(p_buf, packet_len, &index, &m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_hvx.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_hvx.c deleted file mode 100644 index 4682af8..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_hvx.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle, - ble_gatts_hvx_params_t const * const p_hvx_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT(p_hvx_params == NULL || - !(p_hvx_params->p_len == NULL && p_hvx_params->p_data != NULL), NRF_ERROR_NULL); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTS_HVX; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_hvx_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_hvx_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2 + 1 + 2 + 2, *p_buf_len); - index += uint16_encode(p_hvx_params->handle, &p_buf[index]); - p_buf[index++] = p_hvx_params->type; - index += uint16_encode(p_hvx_params->offset, &p_buf[index]); - - if (p_hvx_params->p_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - SER_ERROR_CHECK(*p_hvx_params->p_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, - NRF_ERROR_INVALID_PARAM); - p_buf[index++] = SER_FIELD_PRESENT; - index += uint16_encode(*(p_hvx_params->p_len), &p_buf[index]); - - if (p_hvx_params->p_data != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + *(p_hvx_params->p_len), *p_buf_len); - p_buf[index++] = SER_FIELD_PRESENT; - memcpy(&(p_buf[index]), p_hvx_params->p_data, *(p_hvx_params->p_len)); - index += *(p_hvx_params->p_len); - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - uint16_t * * const pp_bytes_written) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code; - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_HVX, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_bytes_written, uint16_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_include_add.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_include_add.c deleted file mode 100644 index cb991a8..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_include_add.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle, - uint16_t inc_srvc_handle, - uint16_t * const p_include_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_LENGTH_LEQ(6, *p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint32_t err_code; - uint8_t opCode = SD_BLE_GATTS_INCLUDE_ADD; - uint8_t presenceFlag; - - err_code = uint8_t_enc(&opCode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = uint16_t_enc(&service_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = uint16_t_enc(&inc_srvc_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - presenceFlag = (p_include_handle != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - err_code = uint8_t_enc(&presenceFlag, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - *p_buf_len = index; - return err_code; - -} - - -uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_include_handle, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - uint32_t err_code; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GATTS_INCLUDE_ADD, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - SER_ASSERT_NOT_NULL(p_include_handle); - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - err_code = uint16_t_dec(p_buf, packet_len, &index, p_include_handle); - SER_ASSERT_LENGTH_EQ(index, packet_len); - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_rw_authorize_reply.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_rw_authorize_reply.c deleted file mode 100644 index f792b7e..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_rw_authorize_reply.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - -uint32_t ble_gatts_rw_authorize_reply_req_enc( - uint16_t conn_handle, - ble_gatts_rw_authorize_reply_params_t const * const - p_reply_params, - uint8_t * const - p_buf, - uint32_t * const - p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_GATTS_RW_AUTHORIZE_REPLY; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_reply_params, p_buf, buf_len, &index, - ble_gatts_rw_authorize_reply_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_RW_AUTHORIZE_REPLY, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_service_add.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_service_add.c deleted file mode 100644 index 443c660..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_service_add.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_service_add_req_enc(uint8_t type, - ble_uuid_t const * const p_uuid, - uint16_t const * const p_conn_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1 + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTS_SERVICE_ADD; - p_buf[index++] = type; - - p_buf[index++] = (p_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_uuid != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - index += uint16_encode(p_uuid->uuid, &p_buf[index]); - p_buf[index++] = p_uuid->type; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_conn_handle != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GATTS_SERVICE_ADD, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_conn_handle); - - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return decode_result; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_service_changed.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_service_changed.c deleted file mode 100644 index aba707e..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_service_changed.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code; - uint8_t opcode = SD_BLE_GATTS_SERVICE_CHANGED; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - err_code = uint8_t_enc(&opcode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&start_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&end_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_SERVICE_CHANGED, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_sys_attr_get.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_sys_attr_get.c deleted file mode 100644 index 6f36b20..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_sys_attr_get.c +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t const * const p_sys_attr_data_len, - uint32_t flags, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1 + 4, *p_buf_len); - p_buf[index++] = SD_BLE_GATTS_SYS_ATTR_GET; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_sys_attr_data_len != NULL) ? SER_FIELD_PRESENT : - SER_FIELD_NOT_PRESENT; - - if (p_sys_attr_data_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - index += uint16_encode(*p_sys_attr_data_len, &p_buf[index]); - } - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_sys_attr_data != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - err_code = uint32_t_enc(&flags, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_sys_attr_data, - uint16_t * const p_sys_attr_data_len, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_SYS_ATTR_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 2 + 1, packet_len); - - uint16_t sys_attr_len; - uint16_dec(p_buf, packet_len, &index, &sys_attr_len); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - SER_ASSERT_NOT_NULL(p_sys_attr_data); - SER_ASSERT_NOT_NULL(p_sys_attr_data_len); - SER_ASSERT(sys_attr_len <= *p_sys_attr_data_len, NRF_ERROR_DATA_SIZE); - - SER_ASSERT_LENGTH_LEQ(index + sys_attr_len, packet_len); - memcpy(p_sys_attr_data, &p_buf[index], sys_attr_len); - *p_sys_attr_data_len = sys_attr_len; - index += sys_attr_len; - } - else - { - if (p_sys_attr_data_len != NULL) - { - *p_sys_attr_data_len = sys_attr_len; - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_sys_attr_set.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_sys_attr_set.c deleted file mode 100644 index b8830a6..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_sys_attr_set.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t sys_attr_data_len, - uint32_t flags, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 8, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTS_SYS_ATTR_SET; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_sys_attr_data != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_sys_attr_data != NULL) - { - //lint -save -esym(670,memcpy) - SER_ERROR_CHECK(sys_attr_data_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); - SER_ASSERT_LENGTH_LEQ(index + 2 + sys_attr_data_len + 4, *p_buf_len); - index += uint16_encode(sys_attr_data_len, &p_buf[index]); - memcpy(&(p_buf[index]), p_sys_attr_data, sys_attr_data_len); - //lint -restore - index += sys_attr_data_len; - } - - err_code = uint32_t_enc(&flags, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_SYS_ATTR_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_value_get.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_value_get.c deleted file mode 100644 index 54d5844..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_value_get.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - -uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t const * const p_value, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(1 + 2 + 2 + 1, total_len); - p_buf[index++] = SD_BLE_GATTS_VALUE_GET; - - err_code = uint16_t_enc(&conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_value != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - err_code = uint16_t_enc(&(p_value->len), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_value->offset), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, total_len - index); - if (p_value->p_value != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gatts_value_t * const p_value, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - SER_ASSERT_NOT_NULL(p_value); - - uint32_t err_code; - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, - packet_len, SD_BLE_GATTS_VALUE_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = ble_gatts_value_t_dec(p_buf, packet_len, &index, p_value); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_gatts_value_set.c b/components/serialization/application/codecs/s120/serializers/ble_gatts_value_set.c deleted file mode 100644 index e11cffc..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_gatts_value_set.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "nrf_error.h" -#include "cond_field_serialization.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t * p_value, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1 + 2 + 2, *p_buf_len); - p_buf[index++] = SD_BLE_GATTS_VALUE_SET; - index += uint16_encode(conn_handle, &p_buf[index]); - index += uint16_encode(handle, &p_buf[index]); - - if(p_value != NULL) - { - SER_ERROR_CHECK(p_value->len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); - } - err_code = cond_field_enc(p_value, p_buf, *p_buf_len, &index, ble_gatts_value_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gatts_value_t * const p_value, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_VALUE_SET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = ble_gatts_value_t_dec(p_buf, packet_len, &index, p_value); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_l2cap_app.h b/components/serialization/application/codecs/s120/serializers/ble_l2cap_app.h deleted file mode 100644 index f10d577..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_l2cap_app.h +++ /dev/null @@ -1,163 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * - */ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_l2cap_app L2CAP Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief L2CAP Application command request encoders and command response decoders. - */ - -#ifndef BLE_L2CAP_APP_H__ -#define BLE_L2CAP_APP_H__ - -#include "ble.h" -#include "ble_types.h" -#include "ble_ranges.h" -#include "ble_err.h" -#include "ble_l2cap.h" - -/**@brief Register a CID with L2CAP. - * - * @details This registers a higher protocol layer with the L2CAP multiplexer, and is requried prior to all operations on the CID. - * - * @param[in] cid L2CAP CID. - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_l2cap_cid_register command. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_l2cap_cid_register_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Unregister a CID with L2CAP. - * - * @details This unregisters a previously registered higher protocol layer with the L2CAP multiplexer. - * - * @param[in] cid L2CAP CID. - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_l2cap_cid_unregister command. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_l2cap_cid_unregister_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - -/**@brief Transmit an L2CAP packet. - * - * @note It is important to note that a call to this function will consume an application buffer, and will therefore - * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. - * Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. - * - * @param[in] conn_handle Connection Handle. - * @param[in] p_l2cap_header Pointer to a packet header containing length and CID. - * @param[in] p_data Pointer to the data to be transmitted. - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @return @ref NRF_SUCCESS Successfully queued an L2CAP packet for transmission. - * @return @ref NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @return @ref NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register. - * @return @ref NRF_ERROR_NOT_FOUND CID not found. - * @return @ref NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @return @ref BLE_ERROR_NO_TX_BUFFERS Not enough application buffers available. - * @return @ref NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF. - */ -uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle, - ble_l2cap_header_t const * const p_l2cap_header, - uint8_t const * const p_data, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_l2cap_tx command. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_l2cap_tx_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); - - -#endif //BLE_L2CAP_APP_H__ - -/** - @} - */ diff --git a/components/serialization/application/codecs/s120/serializers/ble_l2cap_cid_register.c b/components/serialization/application/codecs/s120/serializers/ble_l2cap_cid_register.c deleted file mode 100644 index de597fe..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_l2cap_cid_register.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - -uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - p_buf[index++] = SD_BLE_L2CAP_CID_REGISTER; - err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_REGISTER, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_l2cap_cid_unregister.c b/components/serialization/application/codecs/s120/serializers/ble_l2cap_cid_unregister.c deleted file mode 100644 index cd6e65a..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_l2cap_cid_unregister.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - -uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - p_buf[index++] = SD_BLE_L2CAP_CID_UNREGISTER; - err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_UNREGISTER, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_l2cap_evt_app.h b/components/serialization/application/codecs/s120/serializers/ble_l2cap_evt_app.h deleted file mode 100644 index cde00e3..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_l2cap_evt_app.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_L2CAP_EVT_APP_H__ -#define BLE_L2CAP_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_l2cap_evt_app L2CAP Application event decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief L2CAP Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_l2cap_evt_rx event. - * - * @sa @ref nrf51_l2cap_evt_rx_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s120/serializers/ble_l2cap_evt_rx.c b/components/serialization/application/codecs/s120/serializers/ble_l2cap_evt_rx.c deleted file mode 100644 index d54682a..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_l2cap_evt_rx.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" -#include "ble_l2cap_evt_app.h" - -uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t in_event_len = *p_event_len; - - *p_event_len = offsetof(ble_l2cap_evt_t, params); - - uint16_t evt_id; - - uint32_t err_code = uint16_t_dec(p_buf, packet_len, &index, &evt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - void * p_rx = NULL; - - if (p_event) - { - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.l2cap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_rx = &(p_event->evt.l2cap_evt.params.rx); - } - - uint32_t struct_len = in_event_len - *p_event_len; - err_code = ble_l2cap_evt_rx_t_dec(p_buf, packet_len, &index, &struct_len, p_rx); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_event_len += struct_len; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_l2cap_tx.c b/components/serialization/application/codecs/s120/serializers/ble_l2cap_tx.c deleted file mode 100644 index 83baa90..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_l2cap_tx.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_l2cap_app.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gap.h" -#include "app_util.h" -#include "cond_field_serialization.h" - -uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle, - ble_l2cap_header_t const * const p_l2cap_header, - uint8_t const * const p_data, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - p_buf[index++] = SD_BLE_L2CAP_TX; - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_l2cap_header, p_buf, *p_buf_len, &index, ble_l2cap_header_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_l2cap_header != NULL) - { - err_code = buf_enc(p_data, p_l2cap_header->len, p_buf, *p_buf_len, &index); - } - else - { - err_code = buf_enc(NULL, 0, p_buf, *p_buf_len, &index); - } - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_TX, p_result_code); -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_opt_get.c b/components/serialization/application/codecs/s120/serializers/ble_opt_get.c deleted file mode 100644 index 7728d66..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_opt_get.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_get_req_enc(uint32_t opt_id, - ble_opt_t const * const p_opt, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_LENGTH_LEQ(1+4+1, *p_buf_len); // [OPCODE][OP_ID][PRESENT] - SER_ASSERT(((opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (opt_id == BLE_GAP_OPT_CH_MAP) || - (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (opt_id == BLE_GAP_OPT_PASSKEY) || - (opt_id == BLE_GAP_OPT_PRIVACY) || - (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (opt_id == BLE_GAP_OPT_COMPAT_MODE)) , NRF_ERROR_INVALID_PARAM); - - p_buf[index++] = SD_BLE_OPT_GET; - - err_code = uint32_t_enc(&opt_id, p_buf, *p_buf_len, &index); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - p_buf[index++] = (p_opt == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - -uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t * const p_opt, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_NOT_NULL(p_opt); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_OPT_GET, - p_result_code); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - (void) uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (*p_opt_id == BLE_GAP_OPT_CH_MAP) || - (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (*p_opt_id == BLE_GAP_OPT_PASSKEY) || - (*p_opt_id == BLE_GAP_OPT_PRIVACY) || - (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - switch (*p_opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->common_opt.radio_cpu_mutex)); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.ch_map)); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.local_conn_latency)); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.passkey)); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.privacy)); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.scan_req_report)); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.compat_mode)); - break; - } - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - diff --git a/components/serialization/application/codecs/s120/serializers/ble_opt_set.c b/components/serialization/application/codecs/s120/serializers/ble_opt_set.c deleted file mode 100644 index d6772b0..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_opt_set.c +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_opt_set_req_enc(uint32_t const opt_id, - ble_opt_t const * const p_opt, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t initial_buf_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(1 + 4 + 1, initial_buf_len); - - SER_ASSERT(((opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (opt_id == BLE_GAP_OPT_CH_MAP) || - (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (opt_id == BLE_GAP_OPT_PASSKEY) || - (opt_id == BLE_GAP_OPT_PRIVACY) || - (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - p_buf[index++] = SD_BLE_OPT_SET; - - err_code = uint32_t_enc(&opt_id, p_buf, initial_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_opt != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - - switch(opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_enc(&(p_opt->common_opt.radio_cpu_mutex),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_enc(&(p_opt->gap_opt.ch_map),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_enc(&(p_opt->gap_opt.local_conn_latency),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_enc(&(p_opt->gap_opt.passkey),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_enc(&(p_opt->gap_opt.privacy),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_enc(&(p_opt->gap_opt.scan_req_report),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_enc(&(p_opt->gap_opt.compat_mode),p_buf, initial_buf_len, &index); - break; - } - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - uint32_t error_code; - - error_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_OPT_SET, p_result_code); - - if (error_code != NRF_SUCCESS) - { - return error_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_tx_buffer_count_get.c b/components/serialization/application/codecs/s120/serializers/ble_tx_buffer_count_get.c deleted file mode 100644 index 944fe63..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_tx_buffer_count_get.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" - -uint32_t ble_tx_buffer_count_get_req_enc(uint8_t const * const p_count, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint8_t opcode = SD_BLE_TX_BUFFER_COUNT_GET; - uint32_t err_code; - uint32_t total_len = *p_buf_len; - - err_code = uint8_t_enc(&opcode, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_count, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_tx_buffer_count_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * const pp_count, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_TX_BUFFER_COUNT_GET, p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_count, uint8_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_user_mem_reply.c b/components/serialization/application/codecs/s120/serializers/ble_user_mem_reply.c deleted file mode 100644 index 7a39b6b..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_user_mem_reply.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle, - ble_user_mem_block_t const * p_block, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - p_buf[index++] = SD_BLE_USER_MEM_REPLY; - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if(p_block != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - - // Encoding order is different than structure elements order because - // mem block length should be sent first - err_code = uint16_t_enc(&(p_block->len), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_block->p_mem, p_buf, *p_buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_USER_MEM_REPLY, p_result_code); -} - - diff --git a/components/serialization/application/codecs/s120/serializers/ble_uuid_decode.c b/components/serialization/application/codecs/s120/serializers/ble_uuid_decode.c deleted file mode 100644 index 5c3e006..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_uuid_decode.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len, - uint8_t const * const p_uuid_le, - ble_uuid_t * const p_uuid, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code; - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_UUID_DECODE; - - err_code = uint8_t_enc((void *)&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len8data_enc(p_uuid_le, uuid_le_len, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_uuid, p_buf, buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - ble_uuid_t * * const pp_uuid, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code; - uint32_t index = 0; - - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - buf_len, - SD_BLE_UUID_DECODE, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, buf_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_uuid_encode.c b/components/serialization/application/codecs/s120/serializers/ble_uuid_encode.c deleted file mode 100644 index 5eb8099..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_uuid_encode.c +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, - uint8_t const * const p_uuid_le_len, - uint8_t const * const p_uuid_le, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_UUID_ENCODE; - - p_buf[index++] = (p_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_uuid != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - index += uint16_encode(p_uuid->uuid, &p_buf[index]); - p_buf[index++] = p_uuid->type; - } - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - p_buf[index++] = (p_uuid_le_len == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - p_buf[index++] = (p_uuid_le == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_uuid_le_len, - uint8_t * const p_uuid_le, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - uint32_t error_code; - - error_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_UUID_ENCODE, p_result_code); - - if (error_code != NRF_SUCCESS) - { - return error_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, packet_len); - uint8_t uuid_le_len = p_buf[index++]; - - if (p_uuid_le_len != NULL) - { - if (p_uuid_le != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + uuid_le_len, packet_len); - memcpy(p_uuid_le, &(p_buf[index]), uuid_le_len); - index += uuid_le_len; - } - *p_uuid_le_len = uuid_le_len; - } - - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_uuid_vs_add.c b/components/serialization/application/codecs/s120/serializers/ble_uuid_vs_add.c deleted file mode 100644 index 0f686f1..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_uuid_vs_add.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid, - uint8_t * const p_uuid_type, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code; - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_UUID_VS_ADD; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_vs_uuid, p_buf, buf_len, &index, ble_uuid128_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_uuid_type, p_buf, buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * * const pp_uuid_type, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - SER_ASSERT_NOT_NULL(pp_uuid_type); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - buf_len, - SD_BLE_UUID_VS_ADD, - p_result_code); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, buf_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid_type, uint8_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s120/serializers/ble_version_get.c b/components/serialization/application/codecs/s120/serializers/ble_version_get.c deleted file mode 100644 index 0485b4f..0000000 --- a/components/serialization/application/codecs/s120/serializers/ble_version_get.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_version_get_req_enc(ble_version_t const * const p_version, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_VERSION_GET; - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - - p_buf[index++] = (p_version == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - -uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_version_t * p_version, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t status_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_VERSION_GET, - p_result_code); - - if (status_code != NRF_SUCCESS) - { - return status_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - uint8_dec(p_buf, packet_len, &index, &(p_version->version_number)); - uint16_dec(p_buf, packet_len, &index, &(p_version->company_id)); - uint16_dec(p_buf, packet_len, &index, &p_version->subversion_number); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return status_code; -} - - diff --git a/components/serialization/application/codecs/s120/serializers/nrf_soc_app.h b/components/serialization/application/codecs/s120/serializers/nrf_soc_app.h deleted file mode 100644 index 4b2cbcc..0000000 --- a/components/serialization/application/codecs/s120/serializers/nrf_soc_app.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s120_codecs Application s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup soc_app SOC Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s120_codecs - * - * @brief SOC Application command request encoders and command response decoders. - */ - -#ifndef NRF_SOC_APP_H__ -#define NRF_SOC_APP_H__ - -#include - -/**@brief Encodes @ref sd_power_system_off command request. - * - * @sa @ref nrf51_sd_power_off for packet format. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); - - -/**@brief Encodes @ref sd_temp_get command request. - * - * @sa @ref nrf51_sd_temp_get for packet format. - @ref temp_get_rsp_dec for command response decoder. - * - * @param[in] p_temp Pointer to result of temperature measurement. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t temp_get_req_enc(int32_t const * const p_temp, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_temp_get command. - * - * @sa @ref nrf51_sd_temp_get for packet format, - * @ref temp_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * @param[out] p_temp Pointer to result of temperature measurement. - * - * @return NRF_SUCCESS Version information stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t temp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - int32_t * const p_temp); - -/** @} */ - -#endif // NRF_SOC_APP_H__ diff --git a/components/serialization/application/codecs/s120/serializers/power_system_off.c b/components/serialization/application/codecs/s120/serializers/power_system_off.c deleted file mode 100644 index c81b1ca..0000000 --- a/components/serialization/application/codecs/s120/serializers/power_system_off.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "nrf_soc_app.h" -#include "ble_serialization.h" -#include "nrf_soc.h" - - -uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - - p_buf[index++] = SD_POWER_SYSTEM_OFF; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s120/serializers/temp_get.c b/components/serialization/application/codecs/s120/serializers/temp_get.c deleted file mode 100644 index e50a799..0000000 --- a/components/serialization/application/codecs/s120/serializers/temp_get.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "nrf_soc.h" -#include "nrf_error.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" - -uint32_t temp_get_req_enc(int32_t const * const p_temp, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(1, total_len); - p_buf[index++] = SD_TEMP_GET; - - err_code = cond_field_enc(p_temp, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t temp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - int32_t * const p_temp) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - SER_ASSERT_NOT_NULL(p_temp); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_TEMP_GET, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_temp); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/middleware/app_mw_ble_gatts.c b/components/serialization/application/codecs/s130/middleware/app_mw_ble_gatts.c deleted file mode 100644 index abc1120..0000000 --- a/components/serialization/application/codecs/s130/middleware/app_mw_ble_gatts.c +++ /dev/null @@ -1,571 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts.h" -#include -#include "ble_serialization.h" -#include "ser_sd_transport.h" -#include "ble_gatts_app.h" -#include "app_error.h" - - -//Pointer for sd calls output params -static void * mp_out_params[3]; - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} - -/**@brief Command response callback function for @ref sd_ble_gatts_sys_attr_set BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_sys_attr_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_sys_attr_set_rsp_dec(p_buffer, length, &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gatts_sys_attr_set(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t len, - uint32_t flags) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gatts_sys_attr_set_req_enc(conn_handle, - p_sys_attr_data, - len, - flags, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_sys_attr_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gatts_hvx BLE command. - * - * Callback for decoding the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_hvx_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_hvx_rsp_dec(p_buffer, length, &result_code, - (uint16_t * *)&mp_out_params[0]); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const * const p_hvx_params) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = (p_hvx_params) ? p_hvx_params->p_len : NULL; - - const uint32_t err_code = ble_gatts_hvx_req_enc(conn_handle, - p_hvx_params, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_hvx_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gatts_service_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_service_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = - ble_gatts_service_add_rsp_dec(p_buffer, - length, - (uint16_t *)mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gatts_service_add(uint8_t type, - ble_uuid_t const * const p_uuid, - uint16_t * const p_handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_handle; - - const uint32_t err_code = ble_gatts_service_add_req_enc(type, - p_uuid, - p_handle, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_service_add_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_service_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_service_changed_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = NRF_SUCCESS; - - const uint32_t err_code = ble_gatts_service_changed_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gatts_service_changed(uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gatts_service_changed_req_enc(conn_handle, - start_handle, - end_handle, - &(p_buffer[1]), - &buffer_length); - - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_service_changed_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_include_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_include_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = NRF_SUCCESS; - - const uint32_t err_code = - ble_gatts_include_add_rsp_dec(p_buffer, - length, - (uint16_t *) mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gatts_include_add(uint16_t service_handle, - uint16_t inc_serv_handle, - uint16_t * const p_include_handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_include_handle; - - const uint32_t err_code = ble_gatts_include_add_req_enc(service_handle, - inc_serv_handle, - p_include_handle, - &(p_buffer[1]), - &buffer_length); - - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_include_add_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_characteristic_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_characteristic_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_characteristic_add_rsp_dec( - p_buffer, - length, - (uint16_t * *)&mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gatts_characteristic_add(uint16_t service_handle, - ble_gatts_char_md_t const * const p_char_md, - ble_gatts_attr_t const * const p_attr_char_value, - ble_gatts_char_handles_t * const p_handles) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_handles; - - const uint32_t err_code = ble_gatts_characteristic_add_req_enc(service_handle, - p_char_md, - p_attr_char_value, - p_handles, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_characteristic_add_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_descriptor_add BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_descriptor_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = NRF_SUCCESS; - - const uint32_t err_code = - ble_gatts_descriptor_add_rsp_dec(p_buffer, - length, - (uint16_t *) mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gatts_descriptor_add(uint16_t char_handle, - ble_gatts_attr_t const * const p_attr, - uint16_t * const p_handle) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_handle; - - const uint32_t err_code = ble_gatts_descriptor_add_req_enc(char_handle, - p_attr, - p_handle, - &(p_buffer[1]), - &buffer_length); - - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_descriptor_add_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_rw_authorize_reply BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_rw_authorize_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = NRF_SUCCESS; - - const uint32_t err_code = ble_gatts_rw_authorize_reply_rsp_dec(p_buffer, - length, - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gatts_rw_authorize_reply( - uint16_t conn_handle, - ble_gatts_rw_authorize_reply_params_t const * const - p_rw_authorize_reply_params) -{ - - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = ble_gatts_rw_authorize_reply_req_enc(conn_handle, - p_rw_authorize_reply_params, - &(p_buffer[1]), - &buffer_length); - - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_rw_authorize_reply_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_value_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_value_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_value_get_rsp_dec(p_buffer, - length, - (ble_gatts_value_t *)mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - -uint32_t sd_ble_gatts_value_get(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t * p_value) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_value; - - const uint32_t err_code = ble_gatts_value_get_req_enc(conn_handle, - handle, - p_value, - &(p_buffer[1]), - &buffer_length); - - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_value_get_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gatts_value_set BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_value_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_value_set_rsp_dec( - p_buffer, - length, - (ble_gatts_value_t *)mp_out_params[0], - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gatts_value_set(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t * p_value) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_value; - - const uint32_t err_code = ble_gatts_value_set_req_enc(conn_handle, - handle, - p_value, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_value_set_rsp_dec); -} - - -/**@brief Command response callback function for @ref sd_ble_gatts_sys_attr_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gatts_sys_attr_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = ble_gatts_sys_attr_get_rsp_dec( - p_buffer, - length, - (uint8_t *) mp_out_params[0], - (uint16_t *) mp_out_params[1], - &result_code); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - - -uint32_t sd_ble_gatts_sys_attr_get(uint16_t conn_handle, - uint8_t * const p_sys_attr_data, - uint16_t * const p_len, - uint32_t flags) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_sys_attr_data; - mp_out_params[1] = p_len; - - const uint32_t err_code = ble_gatts_sys_attr_get_req_enc(conn_handle, - p_sys_attr_data, - p_len, - flags, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gatts_sys_attr_get_rsp_dec); -} diff --git a/components/serialization/application/codecs/s130/middleware/app_mw_nrf_soc.c b/components/serialization/application/codecs/s130/middleware/app_mw_nrf_soc.c deleted file mode 100644 index 6a636c8..0000000 --- a/components/serialization/application/codecs/s130/middleware/app_mw_nrf_soc.c +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "nrf_soc.h" -#include -#include -#include "ser_sd_transport.h" -#include "nrf_soc_app.h" -#include "nrf_error_soc.h" -#include "app_error.h" -#include "ble_serialization.h" - -#include "ser_app_power_system_off.h" - -static void * mp_out_param; - -static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) -{ - uint32_t err_code; - - do - { - err_code = ser_sd_transport_tx_alloc(p_data, p_len); - } - while (err_code != NRF_SUCCESS); - *p_data[0] = SER_PKT_TYPE_CMD; - *p_len -= 1; -} - - -uint32_t sd_power_system_off(void) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = power_system_off_req_enc(&(p_buffer[1]), &buffer_length); - APP_ERROR_CHECK(err_code); - - ser_app_power_system_off_set(); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - NULL); -} - - -/**@brief Command response callback function for @ref sd_temp_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ - -static uint32_t mw_temp_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code; - - const uint32_t err_code = temp_get_rsp_dec(p_buffer, - length, - &result_code, - (int32_t *)mp_out_param); - - APP_ERROR_CHECK(err_code); - - return result_code; -} - -uint32_t sd_temp_get(int32_t * p_temp) -{ - mp_out_param = p_temp; - - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - - const uint32_t err_code = temp_get_req_enc(p_temp, - &(p_buffer[1]), - &buffer_length); - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - mw_temp_get_rsp_dec); -} diff --git a/components/serialization/application/codecs/s130/serializers/app_ble_gap_sec_keys.c b/components/serialization/application/codecs/s130/serializers/app_ble_gap_sec_keys.c deleted file mode 100644 index 066deb3..0000000 --- a/components/serialization/application/codecs/s130/serializers/app_ble_gap_sec_keys.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_ble_gap_sec_keys.h" -#include "nrf_error.h" -#include - -ser_ble_gap_app_keyset_t m_app_keys_table[SER_MAX_CONNECTIONS]; - -uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -#define SER_MAX_CONNECTIONS 2 - -/**@brief GAP connection - keyset mapping structure. - * - * @note This structure is used to map keysets to connection instances, and will be stored in a static table. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that keys for this connection are used by soft device. 0: keys used; 1: keys not used*/ - ble_gap_sec_keyset_t keyset; /**< Keyset structure, see @ref ble_gap_sec_keyset_t.*/ -} ser_ble_gap_app_keyset_t; - -/**@brief allocates instance in m_app_keys_table[] for storage of encryption keys. - * - * @param[in] conn_handle conn_handle - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS Context allocated. - * @retval NRF_ERROR_NO_MEM No free instance available. - */ -uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_gap_sec_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_app_keys_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_APP_BLE_GAP_SEC_KEYS_H diff --git a/components/serialization/application/codecs/s130/serializers/app_ble_user_mem.c b/components/serialization/application/codecs/s130/serializers/app_ble_user_mem.c deleted file mode 100644 index c476020..0000000 --- a/components/serialization/application/codecs/s130/serializers/app_ble_user_mem.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_ble_user_mem.h" -#include "ser_config.h" -#include "nrf_error.h" -#include - -ser_ble_user_mem_t m_app_user_mem_table[SER_MAX_CONNECTIONS]; - -uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -/**@brief Connection - user memory mapping structure. - * - * @note This structure is used to map user memory to connection instances, and will be stored in a static table. - */ -//lint -esym(452,ser_ble_user_mem_t) -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that user memory for this connection is used by soft device. 0: memory used; 1: memory not used*/ - ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t.*/ -} ser_ble_user_mem_t; - -/**@brief allocates instance in m_user_mem_table[] for storage. - * - * @param[in] conn_handle conn_handle - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS Context allocated. - * @retval NRF_ERROR_NO_MEM No free instance available. - */ -uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_user_mem_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_user_mem_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t app_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_APP_BLE_USER_MEM_H diff --git a/components/serialization/application/codecs/s130/serializers/ble_enable.c b/components/serialization/application/codecs/s130/serializers/ble_enable.c deleted file mode 100644 index 09db16a..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_enable.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include -#include "ble_app.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_ENABLE; - - err_code = cond_field_enc(p_ble_enable_params, p_buf, *p_buf_len, &index, ble_enable_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_ENABLE, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_event.c b/components/serialization/application/codecs/s130/serializers/ble_event.c deleted file mode 100644 index 6573cd6..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_event.c +++ /dev/null @@ -1,241 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include "ble_evt_app.h" -#include "ble_gap_evt_app.h" -#include "ble_gattc_evt_app.h" -#include "ble_gatts_evt_app.h" -#include "ble_l2cap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_event_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE, packet_len); - - - const uint16_t event_id = uint16_decode(&p_buf[SER_EVT_ID_POS]); - const uint8_t * p_sub_buffer = &p_buf[SER_EVT_HEADER_SIZE]; - const uint32_t sub_packet_len = packet_len - SER_EVT_HEADER_SIZE; - - if (p_event) - { - SER_ASSERT_LENGTH_LEQ(sizeof (ble_evt_hdr_t), *p_event_len); - *p_event_len -= sizeof (ble_evt_hdr_t); - } - - switch (event_id) - { - case BLE_EVT_TX_COMPLETE: - err_code = ble_evt_tx_complete_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_EVT_USER_MEM_REQUEST: - err_code = ble_evt_user_mem_request_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_EVT_USER_MEM_RELEASE: - err_code = ble_evt_user_mem_release_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_PASSKEY_DISPLAY: - err_code = ble_gap_evt_passkey_display_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_AUTH_KEY_REQUEST: - err_code = ble_gap_evt_auth_key_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE: - err_code = ble_gap_evt_conn_param_update_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: - err_code = ble_gap_evt_conn_param_update_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONN_SEC_UPDATE: - err_code = ble_gap_evt_conn_sec_update_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_CONNECTED: - err_code = ble_gap_evt_connected_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_DISCONNECTED: - err_code = ble_gap_evt_disconnected_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GAP_EVT_TIMEOUT: - err_code = ble_gap_evt_timeout_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_RSSI_CHANGED: - err_code = ble_gap_evt_rssi_changed_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GAP_EVT_SEC_INFO_REQUEST: - err_code = ble_gap_evt_sec_info_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - err_code = ble_gap_evt_sec_params_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GAP_EVT_AUTH_STATUS: - err_code = ble_gap_evt_auth_status_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GAP_EVT_SEC_REQUEST: - err_code = ble_gap_evt_sec_request_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - err_code = ble_gattc_evt_char_disc_rsp_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: - err_code = ble_gattc_evt_char_val_by_uuid_read_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_DESC_DISC_RSP: - err_code = ble_gattc_evt_desc_disc_rsp_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - err_code = ble_gattc_evt_prim_srvc_disc_rsp_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_READ_RSP: - err_code = ble_gattc_evt_read_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_HVX: - err_code = ble_gattc_evt_hvx_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTC_EVT_TIMEOUT: - err_code = ble_gattc_evt_timeout_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTC_EVT_WRITE_RSP: - err_code = ble_gattc_evt_write_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_CHAR_VALS_READ_RSP: - err_code = ble_gattc_evt_char_vals_read_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTC_EVT_REL_DISC_RSP: - err_code = ble_gattc_evt_rel_disc_rsp_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTS_EVT_WRITE: - err_code = ble_gatts_evt_write_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTS_EVT_TIMEOUT: - err_code = ble_gatts_evt_timeout_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTS_EVT_SC_CONFIRM: - err_code = ble_gatts_evt_sc_confirm_dec(p_sub_buffer, - sub_packet_len, - p_event, - p_event_len); - break; - - case BLE_GATTS_EVT_HVC: - err_code = ble_gatts_evt_hvc_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - err_code = ble_gatts_evt_sys_attr_missing_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: - err_code = ble_gatts_evt_rw_authorize_request_dec(p_sub_buffer, sub_packet_len, p_event, - p_event_len); - break; - - case BLE_L2CAP_EVT_RX: - err_code = ble_l2cap_evt_rx_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_ADV_REPORT: - err_code = ble_gap_evt_adv_report_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - case BLE_GAP_EVT_SCAN_REQ_REPORT: - err_code = ble_gap_evt_scan_req_report_dec(p_sub_buffer, sub_packet_len, p_event, p_event_len); - break; - - default: - err_code = NRF_ERROR_NOT_FOUND; - break; - } - - if (p_event != NULL) - { - p_event->header.evt_id = (err_code == NRF_SUCCESS) ? event_id : 0; - p_event->header.evt_len = (err_code == NRF_SUCCESS) ? - (uint16_t)*p_event_len : 0; - } - *p_event_len += sizeof(ble_evt_hdr_t); - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_evt_app.h b/components/serialization/application/codecs/s130/serializers/ble_evt_app.h deleted file mode 100644 index 318a91a..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_evt_app.h +++ /dev/null @@ -1,111 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_EVT_APP_H__ -#define BLE_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s130_codecs Application s130 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_evt_app Application event decoders - * @{ - * @ingroup ser_app_s130_codecs - * - * @brief Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_evt_tx_complete event. - * - * @sa @ref nrf51_evt_tx_complete_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_evt_user_mem_request event. - * - * @sa @ref nrf51_evt_user_mem_request_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ - uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** - * @brief Decodes ble_evt_user_mem_release event. - * - * @sa @ref nrf51_evt_user_mem_release_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ - uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s130/serializers/ble_evt_tx_complete.c b/components/serialization/application/codecs/s130/serializers/ble_evt_tx_complete.c deleted file mode 100644 index 4abf73c..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_evt_tx_complete.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_evt_app.h" -#include "ble_serialization.h" - - -uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_evt_tx_complete_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_EVT_TX_COMPLETE; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.common_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.common_evt.params.tx_complete.count); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_evt_user_mem_release.c b/components/serialization/application/codecs/s130/serializers/ble_evt_user_mem_release.c deleted file mode 100644 index 54efc5f..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_evt_user_mem_release.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" -#include "ble_evt_app.h" -#include "app_ble_user_mem.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.common_evt.params.user_mem_release)) + - sizeof (ble_evt_user_mem_release_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - p_event->header.evt_id = BLE_EVT_USER_MEM_RELEASE; - p_event->header.evt_len = event_len; - ble_evt_user_mem_release_t * p_user_mem_rel = &(p_event->evt.common_evt.params.user_mem_release); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.common_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_user_mem_rel->type)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - // Decoding order of mem block is different than structure elements order - length is decoded first - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_user_mem_rel->mem_block.len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - // Using connection handle find which mem block to release in Application Processor - uint32_t user_mem_table_index; - err_code = app_ble_user_mem_context_find(p_event->evt.common_evt.conn_handle, &user_mem_table_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_user_mem_rel->mem_block.p_mem = m_app_user_mem_table[user_mem_table_index].mem_block.p_mem; - } - else - { - p_user_mem_rel->mem_block.p_mem = NULL; - } - - // Now user memory context can be released - err_code = app_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_evt_user_mem_request.c b/components/serialization/application/codecs/s130/serializers/ble_evt_user_mem_request.c deleted file mode 100644 index 891f759..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_evt_user_mem_request.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" -#include "ble_evt_app.h" - -uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.common_evt.params.user_mem_request)) + - sizeof (ble_evt_user_mem_request_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - p_event->header.evt_id = BLE_EVT_USER_MEM_REQUEST; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.common_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_event->evt.common_evt.params.user_mem_request.type)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_address_get.c b/components/serialization/application/codecs/s130/serializers/ble_gap_address_get.c deleted file mode 100644 index 4af2bc4..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_address_get.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_address_get_req_enc(ble_gap_addr_t const * const p_address, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_ADDRESS_GET; - p_buf[index++] = (p_address == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_address_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * const p_address, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GAP_ADDRESS_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 1 + BLE_GAP_ADDR_LEN, packet_len); - SER_ASSERT_NOT_NULL(p_address); - - p_address->addr_type = p_buf[index++]; - memcpy(p_address->addr, &p_buf[index], BLE_GAP_ADDR_LEN); - index += BLE_GAP_ADDR_LEN; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_address_set.c b/components/serialization/application/codecs/s130/serializers/ble_gap_address_set.c deleted file mode 100644 index 8acaa61..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_address_set.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_address_set_req_enc(uint8_t addr_cycle_mode, - ble_gap_addr_t const * const p_addr, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_ADDRESS_SET; - - err_code = uint8_t_enc(&addr_cycle_mode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_buf[index++] = (p_addr == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_addr != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + BLE_GAP_ADDR_LEN, *p_buf_len); - p_buf[index++] = p_addr->addr_type; - memcpy(&p_buf[index], p_addr->addr, BLE_GAP_ADDR_LEN); - index += BLE_GAP_ADDR_LEN; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_address_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADDRESS_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_adv_data_set.c b/components/serialization/application/codecs/s130/serializers/ble_gap_adv_data_set.c deleted file mode 100644 index a59f271..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_adv_data_set.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data, - uint8_t dlen, - uint8_t const * const p_sr_data, - uint8_t srdlen, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint8_t opcode = SD_BLE_GAP_ADV_DATA_SET; - uint32_t err_code; - err_code = uint8_t_enc(&opcode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len8data_enc(p_data, dlen, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len8data_enc(p_sr_data, srdlen, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADV_DATA_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_adv_start.c b/components/serialization/application/codecs/s130/serializers/ble_gap_adv_start.c deleted file mode 100644 index 115a447..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_adv_start.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - -uint32_t ble_gap_adv_start_req_enc(ble_gap_adv_params_t const * const p_adv_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 2, total_len); - p_buf[index++] = SD_BLE_GAP_ADV_START; - p_buf[index++] = (p_adv_params == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_adv_params != NULL) - { - err_code = uint8_t_enc(&(p_adv_params->type), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_adv_params->p_peer_addr, p_buf, total_len, &index, ble_gap_addr_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&(p_adv_params->fp), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_adv_params->p_whitelist, p_buf, total_len, &index, ble_gap_whitelist_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_adv_params->interval), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_adv_params->timeout), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_adv_ch_mask_t_enc(&(p_adv_params->channel_mask), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADV_START, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_adv_stop.c b/components/serialization/application/codecs/s130/serializers/ble_gap_adv_stop.c deleted file mode 100644 index c633a4b..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_adv_stop.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" - -uint32_t ble_gap_adv_stop_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_ADV_STOP; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ADV_STOP, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_appearance_get.c b/components/serialization/application/codecs/s130/serializers/ble_gap_appearance_get.c deleted file mode 100644 index cc55dd6..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_appearance_get.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_APPEARANCE_GET; - p_buf[index++] = (p_appearance == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_appearance, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_APPEARANCE_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + sizeof (uint16_t), packet_len); - - uint16_dec(p_buf, packet_len, &index, p_appearance); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_appearance_set.c b/components/serialization/application/codecs/s130/serializers/ble_gap_appearance_set.c deleted file mode 100644 index 8038b76..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_appearance_set.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_APPEARANCE_SET; - index += uint16_encode(appearance, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_APPEARANCE_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_auth_key_reply.c b/components/serialization/application/codecs/s130/serializers/ble_gap_auth_key_reply.c deleted file mode 100644 index 58861e0..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_auth_key_reply.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle, - uint8_t key_type, - uint8_t const * const p_key, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_GAP_AUTH_KEY_REPLY; - uint32_t err_code = NRF_SUCCESS; - uint8_t key_len; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&key_type, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - switch (key_type) - { - case BLE_GAP_AUTH_KEY_TYPE_NONE: - key_len = 0; - break; - - case BLE_GAP_AUTH_KEY_TYPE_PASSKEY: - key_len = 6; - break; - - case BLE_GAP_AUTH_KEY_TYPE_OOB: - key_len = 16; - break; - - default: - return NRF_ERROR_INVALID_PARAM; - } - - err_code = buf_enc(p_key, key_len, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_AUTH_KEY_REPLY, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_authenticate.c b/components/serialization/application/codecs/s130/serializers/ble_gap_authenticate.c deleted file mode 100644 index 1f93c74..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_authenticate.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle, - ble_gap_sec_params_t const * const p_sec_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_AUTHENTICATE; - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_params, p_buf, *p_buf_len, &index, ble_gap_sec_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_AUTHENTICATE, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_conn_param_update.c b/components/serialization/application/codecs/s130/serializers/ble_gap_conn_param_update.c deleted file mode 100644 index 3d81edf..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_conn_param_update.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_conn_param_update_req_enc(uint16_t conn_handle, - ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_CONN_PARAM_UPDATE; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_conn_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_conn_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 * 4, *p_buf_len); - index += uint16_encode(p_conn_params->min_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->max_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->slave_latency, &p_buf[index]); - index += uint16_encode(p_conn_params->conn_sup_timeout, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_CONN_PARAM_UPDATE, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_conn_sec_get.c b/components/serialization/application/codecs/s130/serializers/ble_gap_conn_sec_get.c deleted file mode 100644 index b3850b1..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_conn_sec_get.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_handle, - ble_gap_conn_sec_t const * const p_conn_sec, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint8_t opcode = SD_BLE_GAP_CONN_SEC_GET; - - - err_code = uint8_t_enc(&opcode, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_conn_sec, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_sec_t * * const pp_conn_sec, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - uint32_t index = 0; - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_CONN_SEC_GET, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_conn_sec, - ble_gap_conn_sec_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_connect.c b/components/serialization/application/codecs/s130/serializers/ble_gap_connect.c deleted file mode 100644 index 5f13670..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_connect.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr, - ble_gap_scan_params_t const * const p_scan_params, - ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_CONNECT; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_peer_addr, p_buf, buf_len, &index, ble_gap_addr_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_scan_params, p_buf, buf_len, &index, ble_gap_scan_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_conn_params, p_buf, buf_len, &index, ble_gap_conn_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_CONNECT, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_connect_cancel.c b/components/serialization/application/codecs/s130/serializers/ble_gap_connect_cancel.c deleted file mode 100644 index 0730ade..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_connect_cancel.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_CONNECT_CANCEL; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_CONNECT_CANCEL, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_device_name_get.c b/components/serialization/application/codecs/s130/serializers/ble_gap_device_name_get.c deleted file mode 100644 index 0d12b4a..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_device_name_get.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name, - uint16_t const * const p_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_DEVICE_NAME_GET; - p_buf[index++] = (p_len != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - index += uint16_encode(*p_len, &p_buf[index]); - } - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_dev_name != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_dev_name, - uint16_t * const p_dev_name_len, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - uint32_t index = 0; - uint32_t status_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_DEVICE_NAME_GET, - p_result_code); - - if (status_code != NRF_SUCCESS) - { - return status_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_dev_name_len); - status_code = len16data_dec(p_buf, packet_len, &index, (uint8_t * *)&p_dev_name, p_dev_name_len); - - if (status_code != NRF_SUCCESS) - { - return status_code; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return status_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_device_name_set.c b/components/serialization/application/codecs/s130/serializers/ble_gap_device_name_set.c deleted file mode 100644 index c265c4f..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_device_name_set.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p_write_perm, - uint8_t const * const p_dev_name, - uint16_t len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(2, *p_buf_len); - p_buf[index++] = SD_BLE_GAP_DEVICE_NAME_SET; - - p_buf[index++] = (p_write_perm != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_write_perm != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (uint8_t) ((p_write_perm->sm) | (p_write_perm->lv << 4)); - } - - SER_ERROR_CHECK(len <= BLE_GAP_DEVNAME_MAX_LEN, NRF_ERROR_INVALID_PARAM); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - index += uint16_encode(len, &p_buf[index]); - - p_buf[index++] = (p_dev_name != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_dev_name != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + len, *p_buf_len); - memcpy(&p_buf[index], p_dev_name, len); - index += len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_DEVICE_NAME_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_disconnect.c b/components/serialization/application/codecs/s130/serializers/ble_gap_disconnect.c deleted file mode 100644 index d3064d6..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_disconnect.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle, - uint8_t hci_status_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 4, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_DISCONNECT; - index += uint16_encode(conn_handle, &p_buf[index]); - p_buf[index++] = hci_status_code; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_DISCONNECT, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_encrypt.c b/components/serialization/application/codecs/s130/serializers/ble_gap_encrypt.c deleted file mode 100644 index 0abf029..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_encrypt.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gap_encrypt_req_enc( uint16_t conn_handle, - ble_gap_master_id_t const * const p_master_id, - ble_gap_enc_info_t const * const p_enc_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_ENCRYPT; - index += uint16_encode(conn_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_master_id != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_master_id != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_RAND_LEN + 2, *p_buf_len); - index += uint16_encode(p_master_id->ediv, &p_buf[index]); - memcpy(&p_buf[index], p_master_id->rand, BLE_GAP_SEC_RAND_LEN); - index += BLE_GAP_SEC_RAND_LEN; - } - - p_buf[index++] = (p_enc_info != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_enc_info != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_KEY_LEN + 1, *p_buf_len); - memcpy(&p_buf[index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); - index += BLE_GAP_SEC_KEY_LEN; - p_buf[index++] = (p_enc_info->auth | (p_enc_info->ltk_len << 1)); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_ENCRYPT, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_adv_report.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_adv_report.c deleted file mode 100644 index 256919b..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_adv_report.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE+7+1+1, packet_len); // assumed size(data) = 0 - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.adv_report)) + - sizeof (ble_gap_evt_adv_report_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_ADV_REPORT; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.adv_report.peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.adv_report.rssi)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_event->evt.gap_evt.params.adv_report.scan_rsp = byte & 0x01; - p_event->evt.gap_evt.params.adv_report.type = (byte >> 1) & 0x03; - p_event->evt.gap_evt.params.adv_report.dlen = (byte >> 3) & 0x1F; - - err_code = uint8_vector_dec(p_buf, packet_len, &index, - p_event->evt.gap_evt.params.adv_report.data, (uint16_t)(p_event->evt.gap_evt.params.adv_report.dlen)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_auth_key_request.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_auth_key_request.c deleted file mode 100644 index 090b431..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_auth_key_request.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + 1; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_AUTH_KEY_REQUEST; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.auth_key_request.key_type); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_auth_status.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_auth_status.c deleted file mode 100644 index 6f54d6a..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_auth_status.c +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" -#include "app_ble_gap_sec_keys.h" - -extern ser_ble_gap_app_keyset_t m_app_keys_table[]; - -uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint32_t conn_index; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 6, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.auth_status)) + - sizeof (ble_gap_evt_adv_report_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - p_event->header.evt_id = BLE_GAP_EVT_AUTH_STATUS; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_auth_status_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.auth_status)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - // keyset is an extension of standard event data - used to synchronize keys at application - err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keyset_t_dec(p_buf, packet_len, &index, &(m_app_keys_table[conn_index].keyset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = app_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_param_update.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_param_update.c deleted file mode 100644 index 33cacdc..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_param_update.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.conn_param_update)) + - sizeof (ble_gap_evt_conn_param_update_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_CONN_PARAM_UPDATE; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.min_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.max_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.slave_latency); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update.conn_params.conn_sup_timeout); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_param_update_request.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_param_update_request.c deleted file mode 100644 index 7bede0f..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_param_update_request.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.conn_param_update_request)) + - sizeof (ble_gap_evt_conn_param_update_request_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.min_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.max_conn_interval); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.slave_latency); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gap_evt.params.conn_param_update_request.conn_params.conn_sup_timeout); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_sec_update.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_sec_update.c deleted file mode 100644 index 6802173..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_conn_sec_update.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.conn_sec_update)) + - sizeof (ble_gap_evt_conn_sec_update_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_CONN_SEC_UPDATE; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - p_event->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.sm = p_buf[index] & 0x0F; - p_event->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv = (p_buf[index] >> 4) & 0x0F; - index++; - - uint8_dec(p_buf, packet_len, - &index, &p_event->evt.gap_evt.params.conn_sec_update.conn_sec.encr_key_size); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_connected.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_connected.c deleted file mode 100644 index 0dfcd5a..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_connected.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t event_len = sizeof (ble_gap_evt_connected_t) + - sizeof (p_event->evt.gap_evt.conn_handle); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_connected_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.connected)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_disconnected.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_disconnected.c deleted file mode 100644 index fa29107..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_disconnected.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_disconnected_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_DISCONNECTED; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.disconnected.reason); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_passkey_display.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_passkey_display.c deleted file mode 100644 index 7a2f155..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_passkey_display.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey) - - -uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + PASSKEY_LEN, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_passkey_display_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_PASSKEY_DISPLAY; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - memcpy(p_event->evt.gap_evt.params.passkey_display.passkey, &p_buf[index], PASSKEY_LEN); - index += PASSKEY_LEN; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} - diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_rssi_changed.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_rssi_changed.c deleted file mode 100644 index b7de4cc..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_rssi_changed.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_rssi_changed_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_RSSI_CHANGED; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - int8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.rssi_changed.rssi); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} - diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_scan_req_report.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_scan_req_report.c deleted file mode 100644 index 118fcf2..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_scan_req_report.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.scan_req_report)) + - sizeof (ble_gap_evt_scan_req_report_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_SCAN_REQ_REPORT; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.scan_req_report.peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.scan_req_report.rssi)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_info_request.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_info_request.c deleted file mode 100644 index ff3d0af..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_info_request.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 2, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gap_evt.params.sec_info_request)) + - sizeof (ble_gap_evt_sec_info_request_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_SEC_INFO_REQUEST; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - err_code = ble_gap_evt_sec_info_request_t_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.sec_info_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_params_request.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_params_request.c deleted file mode 100644 index 0386291..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_params_request.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(7, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_sec_params_request_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - p_event->header.evt_id = BLE_GAP_EVT_SEC_PARAMS_REQUEST; - p_event->header.evt_len = event_len; - - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_params_request_t_dec(p_buf, packet_len, &index, &(p_event->evt.gap_evt.params.sec_params_request)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_request.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_request.c deleted file mode 100644 index f080405..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_sec_request.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gap_evt_app.h" -#include "ble_gap_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - uint32_t event_len = sizeof (ble_gap_evt_sec_request_t) + - sizeof (p_event->evt.gap_evt.conn_handle); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - - ble_gap_evt_sec_request_t * p_decoded_evt = &(p_event->evt.gap_evt.params.sec_request); - - uint32_t err_code = ble_gap_evt_sec_request_t_dec(p_buf, packet_len, &index, p_decoded_evt); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_timeout.c b/components/serialization/application/codecs/s130/serializers/ble_gap_evt_timeout.c deleted file mode 100644 index 8fdb83b..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_timeout.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_EQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gap_evt_timeout_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GAP_EVT_TIMEOUT; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.params.timeout.src); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_ppcp_get.c b/components/serialization/application/codecs/s130/serializers/ble_gap_ppcp_get.c deleted file mode 100644 index e3c8b07..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_ppcp_get.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" - - -uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_PPCP_GET; - p_buf[index++] = (p_conn_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_params_t * const p_conn_params, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GAP_PPCP_GET, p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_conn_params); - - SER_ASSERT_LENGTH_LEQ(index + 8, packet_len); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->min_conn_interval); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->max_conn_interval); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->slave_latency); - uint16_dec(p_buf, packet_len, &index, &p_conn_params->conn_sup_timeout); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return decode_result; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_ppcp_set.c b/components/serialization/application/codecs/s130/serializers/ble_gap_ppcp_set.c deleted file mode 100644 index 15e5528..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_ppcp_set.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "nrf_error.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GAP_PPCP_SET; - p_buf[index++] = (p_conn_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_conn_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 8, *p_buf_len); - index += uint16_encode(p_conn_params->min_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->max_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->slave_latency, &p_buf[index]); - index += uint16_encode(p_conn_params->conn_sup_timeout, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_PPCP_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_rssi_get.c b/components/serialization/application/codecs/s130/serializers/ble_gap_rssi_get.c deleted file mode 100644 index 24b4b2c..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_rssi_get.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle, - int8_t const * const p_rssi, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - SER_ASSERT_LENGTH_LEQ(index + 1, total_len); - - p_buf[index++] = SD_BLE_GAP_RSSI_GET; - - err_code = uint16_t_enc(&conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_rssi, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - int8_t * const p_rssi, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GAP_RSSI_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - decode_result = uint8_t_dec(p_buf, packet_len, &index, (uint8_t *) p_rssi); - SER_ASSERT(decode_result == NRF_SUCCESS, decode_result); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return decode_result; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_rssi_start.c b/components/serialization/application/codecs/s130/serializers/ble_gap_rssi_start.c deleted file mode 100644 index 539b8b6..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_rssi_start.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle, - uint8_t threshold_dbm, - uint8_t skip_count, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_RSSI_START; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&threshold_dbm, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&skip_count, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_RSSI_START, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_rssi_stop.c b/components/serialization/application/codecs/s130/serializers/ble_gap_rssi_stop.c deleted file mode 100644 index 49ef65e..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_rssi_stop.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - uint8_t op_code = SD_BLE_GAP_RSSI_STOP; - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_RSSI_STOP, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_scan_start.c b/components/serialization/application/codecs/s130/serializers/ble_gap_scan_start.c deleted file mode 100644 index a92ab3b..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_scan_start.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "cond_field_serialization.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" - -uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SCAN_START; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = cond_field_enc(p_scan_params, p_buf, buf_len, &index, ble_gap_scan_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_SCAN_START, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_scan_stop.c b/components/serialization/application/codecs/s130/serializers/ble_gap_scan_stop.c deleted file mode 100644 index 72e7c4a..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_scan_stop.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" - -uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SCAN_STOP; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_SCAN_STOP, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_sec_info_reply.c b/components/serialization/application/codecs/s130/serializers/ble_gap_sec_info_reply.c deleted file mode 100644 index 0739b31..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_sec_info_reply.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gap.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle, - ble_gap_enc_info_t const * p_enc_info, - ble_gap_irk_t const * p_id_info, - ble_gap_sign_info_t const * p_sign_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SEC_INFO_REPLY; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - p_buf[index++] = (p_enc_info != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_enc_info != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_KEY_LEN + 1, buf_len); - memcpy(&p_buf[index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); - index += BLE_GAP_SEC_KEY_LEN; - p_buf[index++] = (p_enc_info->auth | (p_enc_info->ltk_len << 1)); - } - - err_code = cond_field_enc(p_id_info, p_buf, buf_len, &index, ble_gap_irk_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - p_buf[index++] = (p_sign_info != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_sign_info != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + BLE_GAP_SEC_KEY_LEN, buf_len); - memcpy(&p_buf[index], p_sign_info->csrk, BLE_GAP_SEC_KEY_LEN); - index += BLE_GAP_SEC_KEY_LEN; - } - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_SEC_INFO_REPLY, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_sec_params_reply.c b/components/serialization/application/codecs/s130/serializers/ble_gap_sec_params_reply.c deleted file mode 100644 index d04189d..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_sec_params_reply.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_sec_params_reply_req_enc(uint16_t conn_handle, - uint8_t sec_status, - ble_gap_sec_params_t const * const p_sec_params, - ble_gap_sec_keyset_t const * const p_sec_keyset, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_SEC_PARAMS_REPLY; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&sec_status, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_params, p_buf, buf_len, &index, ble_gap_sec_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_keyset, p_buf, buf_len, &index, ble_gap_sec_keyset_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_sec_keyset_t const * const p_sec_keyset, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, SD_BLE_GAP_SEC_PARAMS_REPLY, p_result_code); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_sec_keyset); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **)&p_sec_keyset, ble_gap_sec_keyset_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_tx_power_set.c b/components/serialization/application/codecs/s130/serializers/ble_gap_tx_power_set.c deleted file mode 100644 index 807eb78..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_tx_power_set.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_tx_power_set_req_enc(int8_t tx_power, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GAP_TX_POWER_SET; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&tx_power, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GAP_TX_POWER_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_char_value_by_uuid_read.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_char_value_by_uuid_read.c deleted file mode 100644 index 7b75815..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_char_value_by_uuid_read.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "cond_field_serialization.h" -#include "ble_types.h" -#include - -uint32_t ble_gattc_char_value_by_uuid_read_req_enc - (uint16_t conn_handle, - ble_uuid_t const * const p_uuid, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code; - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_uuid, p_buf, buf_len, &index, ble_uuid_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_handle_range, p_buf, buf_len, &index, ble_gattc_handle_range_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, - packet_len, - SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, - p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_char_values_read.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_char_values_read.c deleted file mode 100644 index 6dc1e17..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_char_values_read.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle, - uint16_t const * const p_handles, - uint16_t handle_count, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint32_t err_code; - uint8_t opCode = SD_BLE_GATTC_CHAR_VALUES_READ; - - err_code = uint8_t_enc(&opCode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = count16_cond_data16_enc(p_handles, handle_count, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - *p_buf_len = index; - return err_code; -} - - -uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_CHAR_VALUES_READ, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_characteristics_discover.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_characteristics_discover.c deleted file mode 100644 index b98d142..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_characteristics_discover.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_characteristics_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_CHARACTERISTICS_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_handle_range != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_handle_range != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, *p_buf_len); - - index += uint16_encode(p_handle_range->start_handle, &p_buf[index]); - index += uint16_encode(p_handle_range->end_handle, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, - p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_descriptors_discover.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_descriptors_discover.c deleted file mode 100644 index 28e1a21..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_descriptors_discover.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_descriptors_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_DESCRIPTORS_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - p_buf[index++] = (p_handle_range == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_handle_range != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, *p_buf_len); - index += uint16_encode(p_handle_range->start_handle, &p_buf[index]); - index += uint16_encode(p_handle_range->end_handle, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_DESCRIPTORS_DISCOVER, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_disc_rsp.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_disc_rsp.c deleted file mode 100644 index cdc6532..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_disc_rsp.c +++ /dev/null @@ -1,103 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "nordic_common.h" - - -uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(2 + 2 + 2 + 2, packet_len); - - uint16_t tmp_conn_handle; - uint16_t tmp_gatt_status; - uint16_t tmp_error_handle; - uint16_t tmp_service_count; - uint16_dec(p_buf, packet_len, &index, &tmp_conn_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_gatt_status); - uint16_dec(p_buf, packet_len, &index, &tmp_error_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_service_count); - - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.char_disc_rsp) + - sizeof (uint16_t) + tmp_service_count * sizeof (ble_gattc_char_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_CHAR_DISC_RSP; - p_event->header.evt_len = event_len; - p_event->evt.gattc_evt.conn_handle = tmp_conn_handle; - p_event->evt.gattc_evt.gatt_status = tmp_gatt_status; - p_event->evt.gattc_evt.error_handle = tmp_error_handle; - p_event->evt.gattc_evt.params.char_disc_rsp.count = tmp_service_count; - - SER_ASSERT_LENGTH_LEQ(index + (tmp_service_count * 9), packet_len); - - for (uint16_t i = 0; i < tmp_service_count; i++) - { - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.uuid); - uint8_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.type); - - uint8_t characteristic_props; - uint8_dec(p_buf, packet_len, &index, &characteristic_props); - - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.broadcast = - !!(characteristic_props & BIT_0); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.read = - !!(characteristic_props & BIT_1); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.write_wo_resp = - !!(characteristic_props & BIT_2); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.write = - !!(characteristic_props & BIT_3); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.notify = - !!(characteristic_props & BIT_4); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.indicate = - !!(characteristic_props & BIT_5); - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_props.auth_signed_wr = - !!(characteristic_props & BIT_6); - - uint8_t characteristic_ext_props; - uint8_dec(p_buf, packet_len, &index, &characteristic_ext_props); - - p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].char_ext_props = - characteristic_ext_props & BIT_0; - - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_decl); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_value); - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c deleted file mode 100644 index 93d89dc..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_util.h" -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_gattc_evt_app.h" - - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code; - uint16_t conn_handle; - uint16_t gatt_status; - uint16_t error_handle; - - SER_ASSERT_LENGTH_LEQ(6, packet_len - index); - - uint32_t in_event_len = *p_event_len; - - *p_event_len = (offsetof(ble_evt_t, evt.gattc_evt.params)) - sizeof (ble_evt_hdr_t); - - uint16_dec(p_buf, packet_len, &index, &conn_handle); - uint16_dec(p_buf, packet_len, &index, &gatt_status); - uint16_dec(p_buf, packet_len, &index, &error_handle); - - void * p_data = NULL; - - if (p_event) - { - SER_ASSERT_LENGTH_LEQ(*p_event_len, in_event_len); - - p_event->header.evt_id = BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP; - p_event->evt.gattc_evt.conn_handle = conn_handle; - p_event->evt.gattc_evt.gatt_status = gatt_status; - p_event->evt.gattc_evt.error_handle = error_handle; - - p_data = &p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp; - } - else - { - p_data = NULL; - } - - //call struct decoder with remaining size of event struct - uint32_t temp_event_len = in_event_len - *p_event_len; - err_code = ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(p_buf, packet_len, &index, - &temp_event_len, p_data); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - //update event length with the amount processed by struct decoder - *p_event_len += temp_event_len; - - if (p_event) - { - p_event->header.evt_len = *p_event_len; - } - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_vals_read_rsp.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_vals_read_rsp.c deleted file mode 100644 index 4e99a17..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_char_vals_read_rsp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_gattc_struct_serialization.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -#define BLE_GATTC_EVT_CHAR_VALS_READ_RSP_LEN_POSITION 6 - - -uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len = 0; - - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(10, packet_len); - - event_len = (uint16_t) (offsetof(ble_evt_t, evt.gattc_evt.params.char_vals_read_rsp.values)) - - sizeof (ble_evt_hdr_t) + - uint16_decode(&p_buf[BLE_GATTC_EVT_CHAR_VALS_READ_RSP_LEN_POSITION]); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - else - { - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - *p_event_len = event_len; - } - - p_event->header.evt_id = BLE_GATTC_EVT_CHAR_VALS_READ_RSP; - - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - - //Event structure for BLE_GATTC_EVT_CHAR_VALS_READ_RSP - error_code = - ble_gattc_evt_char_vals_read_rsp_t_dec(p_buf, packet_len, &index, - &(p_event->evt.gattc_evt.params.char_vals_read_rsp)); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return error_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_desc_disc_rsp.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_desc_disc_rsp.c deleted file mode 100644 index 6e44502..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_desc_disc_rsp.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 6, packet_len); - - uint16_t tmp_conn_handle; - uint16_t tmp_gatt_status; - uint16_t tmp_error_handle; - uint16_t tmp_service_count; - uint16_dec(p_buf, packet_len, &index, &tmp_conn_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_gatt_status); - uint16_dec(p_buf, packet_len, &index, &tmp_error_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_service_count); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.desc_disc_rsp) + - sizeof (uint16_t) + tmp_service_count * sizeof (ble_gattc_desc_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_DESC_DISC_RSP; - p_event->header.evt_len = event_len; - p_event->evt.gattc_evt.conn_handle = tmp_conn_handle; - p_event->evt.gattc_evt.gatt_status = tmp_gatt_status; - p_event->evt.gattc_evt.error_handle = tmp_error_handle; - p_event->evt.gattc_evt.params.desc_disc_rsp.count = tmp_service_count; - - SER_ASSERT_LENGTH_LEQ(index + (tmp_service_count * 5), packet_len); - - for (uint16_t i = 0; i < tmp_service_count; i++) - { - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].handle); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.uuid); - uint8_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.type); - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_hvx.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_hvx.c deleted file mode 100644 index f20f499..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_hvx.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint16_t tmp_attr_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(11, packet_len); - - tmp_attr_len = uint16_decode(&(p_buf[9])); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.hvx) + - sizeof (ble_gattc_evt_hvx_t) - 1 + tmp_attr_len; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_HVX; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.handle)); - uint8_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.type)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.hvx.len)); - - SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); - - if (tmp_attr_len > 0) - { - memcpy(&(p_event->evt.gattc_evt.params.hvx.data[0]), &(p_buf[index]), tmp_attr_len); - index += tmp_attr_len; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c deleted file mode 100644 index 85d43c0..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 6, packet_len); - - uint16_t tmp_conn_handle; - uint16_t tmp_gatt_status; - uint16_t tmp_error_handle; - uint16_t tmp_service_count; - uint16_dec(p_buf, packet_len, &index, &tmp_conn_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_gatt_status); - uint16_dec(p_buf, packet_len, &index, &tmp_error_handle); - uint16_dec(p_buf, packet_len, &index, &tmp_service_count); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp) + - sizeof (uint16_t) + tmp_service_count * sizeof (ble_gattc_service_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP; - p_event->header.evt_len = event_len; - p_event->evt.gattc_evt.conn_handle = tmp_conn_handle; - p_event->evt.gattc_evt.gatt_status = tmp_gatt_status; - p_event->evt.gattc_evt.error_handle = tmp_error_handle; - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.count = tmp_service_count; - - SER_ASSERT_LENGTH_LEQ(index + (tmp_service_count * 7), packet_len); - - for (uint16_t i = 0; i < tmp_service_count; i++) - { - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.uuid); - uint8_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.type); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - start_handle); - uint16_dec(p_buf, packet_len, &index, - &p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - end_handle); - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_read_rsp.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_read_rsp.c deleted file mode 100644 index a851447..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_read_rsp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint16_t tmp_attr_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(12, packet_len); - - tmp_attr_len = uint16_decode(&(p_buf[10])); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.read_rsp) + - sizeof (ble_gattc_evt_read_rsp_t) - 1 + tmp_attr_len; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_READ_RSP; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.read_rsp.handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.read_rsp.offset)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.read_rsp.len)); - - SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); - - if (tmp_attr_len > 0) - { - memcpy(&(p_event->evt.gattc_evt.params.read_rsp.data[0]), &(p_buf[index]), tmp_attr_len); - index += tmp_attr_len; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_rel_disc_rsp.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_rel_disc_rsp.c deleted file mode 100644 index 7f0bd9f..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_rel_disc_rsp.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - -#define BLE_GATTC_EVT_REL_DISC_RSP_COUNT_POSITION 6 - - -uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len = 0; - uint16_t include_count = 0; - - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(8, packet_len); - - include_count = uint16_decode(&p_buf[BLE_GATTC_EVT_REL_DISC_RSP_COUNT_POSITION]); - event_len = (uint16_t) (offsetof(ble_evt_t, evt.gattc_evt.params.rel_disc_rsp.includes)) - - sizeof (ble_evt_hdr_t) + (include_count * sizeof (ble_gattc_include_t)); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_REL_DISC_RSP; - error_code = - uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = - ble_gattc_evt_rel_disc_rsp_t_dec(p_buf, packet_len, &index, - &(p_event->evt.gattc_evt.params.rel_disc_rsp)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return error_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_timeout.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_timeout.c deleted file mode 100644 index 8f831d3..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_timeout.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - */ - -#include "ble_gattc_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - uint32_t event_len; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - event_len = offsetof(ble_evt_t, evt.gattc_evt.params.timeout) + - sizeof (ble_gattc_evt_timeout_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_TIMEOUT; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gattc_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gattc_evt.params.timeout.src); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_write_rsp.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_write_rsp.c deleted file mode 100644 index bfed5e2..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_write_rsp.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(13, packet_len); - - uint16_t tmp_attr_len = uint16_decode(&(p_buf[11])); - - uint32_t event_len = offsetof(ble_evt_t, evt.gattc_evt.params.write_rsp) + - sizeof (ble_gattc_evt_write_rsp_t) - 1 + tmp_attr_len; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTC_EVT_WRITE_RSP; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.conn_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.gatt_status)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.error_handle)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.handle)); - uint8_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.write_op)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.offset)); - uint16_dec(p_buf, packet_len, &index, &(p_event->evt.gattc_evt.params.write_rsp.len)); - - SER_ASSERT_LENGTH_LEQ(index + tmp_attr_len, packet_len); - - if (tmp_attr_len > 0) - { - memcpy(&(p_event->evt.gattc_evt.params.write_rsp.data[0]), &(p_buf[index]), tmp_attr_len); - index += tmp_attr_len; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_hv_confirm.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_hv_confirm.c deleted file mode 100644 index f745640..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_hv_confirm.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle, - uint16_t handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint8_t op_code = SD_BLE_GATTC_HV_CONFIRM; - uint32_t err_code = NRF_SUCCESS; - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - - err_code = uint8_t_enc(&op_code, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - -uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_HV_CONFIRM, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_primary_services_discover.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_primary_services_discover.c deleted file mode 100644 index 762508b..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_primary_services_discover.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle, - uint16_t start_handle, - ble_uuid_t const * const p_srvc_uuid, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 5, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - index += uint16_encode(start_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - - p_buf[index++] = (p_srvc_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_srvc_uuid != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - index += uint16_encode(p_srvc_uuid->uuid, &p_buf[index]); - p_buf[index++] = p_srvc_uuid->type; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, - p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_read.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_read.c deleted file mode 100644 index 1d4b5ec..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_read.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_read_req_enc(uint16_t conn_handle, - uint16_t handle, - uint16_t offset, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 7, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_READ; - index += uint16_encode(conn_handle, &p_buf[index]); - index += uint16_encode(handle, &p_buf[index]); - index += uint16_encode(offset, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_READ, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_relationships_discover.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_relationships_discover.c deleted file mode 100644 index 943457e..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_relationships_discover.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_relationships_discover_req_enc( - uint16_t conn_handle, - ble_gattc_handle_range_t const * const p_handle_range, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_RELATIONSHIPS_DISCOVER; - index += uint16_encode(conn_handle, &p_buf[index]); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_handle_range != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_handle_range != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 4, *p_buf_len); - - index += uint16_encode(p_handle_range->start_handle, &p_buf[index]); - index += uint16_encode(p_handle_range->end_handle, &p_buf[index]); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, - p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_write.c b/components/serialization/application/codecs/s130/serializers/ble_gattc_write.c deleted file mode 100644 index edfe93a..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_write.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_write_req_enc(uint16_t conn_handle, - ble_gattc_write_params_t const * const p_write_params, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 4, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTC_WRITE; - index += uint16_encode(conn_handle, &p_buf[index]); - p_buf[index++] = (p_write_params == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_write_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 9, *p_buf_len); - p_buf[index++] = p_write_params->write_op; - p_buf[index++] = p_write_params->flags; - index += uint16_encode(p_write_params->handle, &p_buf[index]); - index += uint16_encode(p_write_params->offset, &p_buf[index]); - index += uint16_encode(p_write_params->len, &p_buf[index]); - - SER_ERROR_CHECK(p_write_params->len <= BLE_GATTC_WRITE_P_VALUE_LEN_MAX, - NRF_ERROR_INVALID_PARAM); - - p_buf[index++] = (p_write_params->p_value == NULL) ? - SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - if (p_write_params->p_value != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + p_write_params->len, *p_buf_len); - memcpy(&p_buf[index], p_write_params->p_value, p_write_params->len); - index += p_write_params->len; - } - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTC_WRITE, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_characteristic_add.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_characteristic_add.c deleted file mode 100644 index 75e164d..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_characteristic_add.c +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - -uint32_t ble_gatts_characteristic_add_req_enc( - uint16_t service_handle, - ble_gatts_char_md_t const * const p_char_md, - ble_gatts_attr_t const * const p_attr_char_value, - ble_gatts_char_handles_t const * const p_handles, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint8_t opcode = SD_BLE_GATTS_CHARACTERISTIC_ADD; - uint32_t buf_len = *p_buf_len; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&service_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md, p_buf, buf_len, &index, ble_gatts_char_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_attr_char_value, p_buf, buf_len, &index, ble_gatts_attr_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_handles, p_buf, buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * * const pp_handles, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, buf_len, - SD_BLE_GATTS_CHARACTERISTIC_ADD, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, buf_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, - buf_len, - &index, - (void * *)pp_handles, - ble_gatts_char_handles_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_descriptor_add.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_descriptor_add.c deleted file mode 100644 index ea895bb..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_descriptor_add.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - - -#include "ble_gatts_app.h" -#include -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - - -uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_handle, - ble_gatts_attr_t const * const p_attr, - uint16_t * const p_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - p_buf[index++] = SD_BLE_GATTS_DESCRIPTOR_ADD; - - uint32_t err_code = uint16_t_enc(&char_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_attr, - p_buf, - *p_buf_len, - &index, - ble_gatts_attr_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_handle != NULL) ? SER_FIELD_PRESENT : - SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_handle, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_DESCRIPTOR_ADD, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - SER_ASSERT_NOT_NULL(p_handle); - - uint16_dec(p_buf, packet_len, &index, p_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_hvc.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_hvc.c deleted file mode 100644 index 2c1c5aa..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_hvc.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gatts_evt_hvc_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_HVC; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.conn_handle); - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.params.hvc.handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_rw_authorize_request.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_rw_authorize_request.c deleted file mode 100644 index 86f1b35..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_rw_authorize_request.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t in_event_len = *p_event_len; - - *p_event_len = offsetof(ble_evt_t, evt.gatts_evt.params) - sizeof (ble_evt_hdr_t); - - uint16_t conn_handle; - err_code = uint16_t_dec(p_buf, packet_len, &index, &conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - void * p_void_authorize_request = NULL; - - if (p_event != NULL) - { - SER_ASSERT_LENGTH_LEQ(*p_event_len, in_event_len); - - p_event->header.evt_id = BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST; - p_event->evt.gatts_evt.conn_handle = conn_handle; - - p_void_authorize_request = &(p_event->evt.gatts_evt.params.authorize_request); - } - uint32_t tmp_event_len = in_event_len - *p_event_len; - err_code = ble_gatts_evt_rw_authorize_request_t_dec(p_buf, - packet_len, - &index, - &tmp_event_len, - p_void_authorize_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_event_len += tmp_event_len; - - if(p_event != NULL) - { - if((p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)) - { - uint32_t conn_index; - - if(app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_dec(p_buf, packet_len, &index, &m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_sc_confirm.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_sc_confirm.c deleted file mode 100644 index d8d440f..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_sc_confirm.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE; - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_SC_CONFIRM; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.conn_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_sys_attr_missing.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_sys_attr_missing.c deleted file mode 100644 index 8b17268..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_sys_attr_missing.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - uint32_t event_len = (uint16_t) (offsetof(ble_evt_t, evt.gatts_evt.params.sys_attr_missing)) + - sizeof (ble_gatts_evt_sys_attr_missing_t) - - sizeof (ble_evt_hdr_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_SYS_ATTR_MISSING; - p_event->header.evt_len = event_len; - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gap_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.params.sys_attr_missing.hint); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_timeout.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_timeout.c deleted file mode 100644 index fba0b11..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_timeout.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_CONN_HANDLE_SIZE + 1, packet_len); - - uint32_t event_len = SER_EVT_CONN_HANDLE_SIZE + sizeof (ble_gatts_evt_timeout_t); - - if (p_event == NULL) - { - *p_event_len = event_len; - return NRF_SUCCESS; - } - - SER_ASSERT(event_len <= *p_event_len, NRF_ERROR_DATA_SIZE); - - p_event->header.evt_id = BLE_GATTS_EVT_TIMEOUT; - p_event->header.evt_len = event_len; - - uint16_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.conn_handle); - uint8_dec(p_buf, packet_len, &index, &p_event->evt.gatts_evt.params.timeout.src); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - *p_event_len = event_len; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_write.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_write.c deleted file mode 100644 index d6e7918..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_write.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_app.h" -#include -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_app_user_mem_table[]; - -uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - uint32_t in_event_len = *p_event_len; - - *p_event_len = offsetof(ble_evt_t, evt.gatts_evt.params) - sizeof (ble_evt_hdr_t); - - uint16_t conn_handle; - err_code = uint16_t_dec(p_buf, packet_len, &index, &conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - void * p_void_write = NULL; - - if (p_event != NULL) - { - SER_ASSERT_LENGTH_LEQ(*p_event_len, in_event_len); - p_event->evt.gatts_evt.conn_handle = conn_handle; - - p_void_write = &(p_event->evt.gatts_evt.params.write); - } - - uint32_t tmp_struct_len = in_event_len - *p_event_len; - err_code = ble_gatts_evt_write_t_dec(p_buf, - packet_len, - &index, - &tmp_struct_len, - p_void_write); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_event_len += tmp_struct_len; - - if(p_event != NULL) - { - if(p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) - { - uint32_t conn_index; - - if(app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_dec(p_buf, packet_len, &index, &m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_hvx.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_hvx.c deleted file mode 100644 index 4682af8..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_hvx.c +++ /dev/null @@ -1,115 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle, - ble_gatts_hvx_params_t const * const p_hvx_params, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT(p_hvx_params == NULL || - !(p_hvx_params->p_len == NULL && p_hvx_params->p_data != NULL), NRF_ERROR_NULL); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTS_HVX; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_hvx_params != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_hvx_params != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2 + 1 + 2 + 2, *p_buf_len); - index += uint16_encode(p_hvx_params->handle, &p_buf[index]); - p_buf[index++] = p_hvx_params->type; - index += uint16_encode(p_hvx_params->offset, &p_buf[index]); - - if (p_hvx_params->p_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1, *p_buf_len); - - SER_ERROR_CHECK(*p_hvx_params->p_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, - NRF_ERROR_INVALID_PARAM); - p_buf[index++] = SER_FIELD_PRESENT; - index += uint16_encode(*(p_hvx_params->p_len), &p_buf[index]); - - if (p_hvx_params->p_data != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 1 + *(p_hvx_params->p_len), *p_buf_len); - p_buf[index++] = SER_FIELD_PRESENT; - memcpy(&(p_buf[index]), p_hvx_params->p_data, *(p_hvx_params->p_len)); - index += *(p_hvx_params->p_len); - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - uint16_t * * const pp_bytes_written) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code; - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_HVX, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_bytes_written, uint16_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_include_add.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_include_add.c deleted file mode 100644 index cb991a8..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_include_add.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle, - uint16_t inc_srvc_handle, - uint16_t * const p_include_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_LENGTH_LEQ(6, *p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint32_t err_code; - uint8_t opCode = SD_BLE_GATTS_INCLUDE_ADD; - uint8_t presenceFlag; - - err_code = uint8_t_enc(&opCode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = uint16_t_enc(&service_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = uint16_t_enc(&inc_srvc_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - presenceFlag = (p_include_handle != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - err_code = uint8_t_enc(&presenceFlag, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - *p_buf_len = index; - return err_code; - -} - - -uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_include_handle, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - uint32_t err_code; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GATTS_INCLUDE_ADD, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - SER_ASSERT_NOT_NULL(p_include_handle); - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - err_code = uint16_t_dec(p_buf, packet_len, &index, p_include_handle); - SER_ASSERT_LENGTH_EQ(index, packet_len); - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_rw_authorize_reply.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_rw_authorize_reply.c deleted file mode 100644 index f792b7e..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_rw_authorize_reply.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - -uint32_t ble_gatts_rw_authorize_reply_req_enc( - uint16_t conn_handle, - ble_gatts_rw_authorize_reply_params_t const * const - p_reply_params, - uint8_t * const - p_buf, - uint32_t * const - p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_GATTS_RW_AUTHORIZE_REPLY; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_reply_params, p_buf, buf_len, &index, - ble_gatts_rw_authorize_reply_params_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_RW_AUTHORIZE_REPLY, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_service_add.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_service_add.c deleted file mode 100644 index 443c660..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_service_add.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_service_add_req_enc(uint8_t type, - ble_uuid_t const * const p_uuid, - uint16_t const * const p_conn_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 1 + 1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTS_SERVICE_ADD; - p_buf[index++] = type; - - p_buf[index++] = (p_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_uuid != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - index += uint16_encode(p_uuid->uuid, &p_buf[index]); - p_buf[index++] = p_uuid->type; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_conn_handle != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_GATTS_SERVICE_ADD, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_conn_handle); - - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return decode_result; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_service_changed.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_service_changed.c deleted file mode 100644 index aba707e..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_service_changed.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle, - uint16_t start_handle, - uint16_t end_handle, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code; - uint8_t opcode = SD_BLE_GATTS_SERVICE_CHANGED; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - err_code = uint8_t_enc(&opcode, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&start_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&end_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_SERVICE_CHANGED, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_sys_attr_get.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_sys_attr_get.c deleted file mode 100644 index 6f36b20..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_sys_attr_get.c +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t const * const p_sys_attr_data_len, - uint32_t flags, - uint8_t * const p_buf, - uint32_t * p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 1 + 2 + 1 + 4, *p_buf_len); - p_buf[index++] = SD_BLE_GATTS_SYS_ATTR_GET; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_sys_attr_data_len != NULL) ? SER_FIELD_PRESENT : - SER_FIELD_NOT_PRESENT; - - if (p_sys_attr_data_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - index += uint16_encode(*p_sys_attr_data_len, &p_buf[index]); - } - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - p_buf[index++] = (p_sys_attr_data != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - err_code = uint32_t_enc(&flags, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_sys_attr_data, - uint16_t * const p_sys_attr_data_len, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_SYS_ATTR_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 2 + 1, packet_len); - - uint16_t sys_attr_len; - uint16_dec(p_buf, packet_len, &index, &sys_attr_len); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - SER_ASSERT_NOT_NULL(p_sys_attr_data); - SER_ASSERT_NOT_NULL(p_sys_attr_data_len); - SER_ASSERT(sys_attr_len <= *p_sys_attr_data_len, NRF_ERROR_DATA_SIZE); - - SER_ASSERT_LENGTH_LEQ(index + sys_attr_len, packet_len); - memcpy(p_sys_attr_data, &p_buf[index], sys_attr_len); - *p_sys_attr_data_len = sys_attr_len; - index += sys_attr_len; - } - else - { - if (p_sys_attr_data_len != NULL) - { - *p_sys_attr_data_len = sys_attr_len; - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_sys_attr_set.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_sys_attr_set.c deleted file mode 100644 index b8830a6..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_sys_attr_set.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle, - uint8_t const * const p_sys_attr_data, - uint16_t sys_attr_data_len, - uint32_t flags, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 8, *p_buf_len); - - p_buf[index++] = SD_BLE_GATTS_SYS_ATTR_SET; - index += uint16_encode(conn_handle, &p_buf[index]); - - p_buf[index++] = (p_sys_attr_data != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_sys_attr_data != NULL) - { - //lint -save -esym(670,memcpy) - SER_ERROR_CHECK(sys_attr_data_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); - SER_ASSERT_LENGTH_LEQ(index + 2 + sys_attr_data_len + 4, *p_buf_len); - index += uint16_encode(sys_attr_data_len, &p_buf[index]); - memcpy(&(p_buf[index]), p_sys_attr_data, sys_attr_data_len); - //lint -restore - index += sys_attr_data_len; - } - - err_code = uint32_t_enc(&flags, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_SYS_ATTR_SET, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_value_get.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_value_get.c deleted file mode 100644 index 54d5844..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_value_get.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - */ - -#include "ble_gatts_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" - -uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t const * const p_value, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(1 + 2 + 2 + 1, total_len); - p_buf[index++] = SD_BLE_GATTS_VALUE_GET; - - err_code = uint16_t_enc(&conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_value != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - err_code = uint16_t_enc(&(p_value->len), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_value->offset), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, total_len - index); - if (p_value->p_value != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gatts_value_t * const p_value, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - SER_ASSERT_NOT_NULL(p_value); - - uint32_t err_code; - uint32_t index = 0; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, - packet_len, SD_BLE_GATTS_VALUE_GET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = ble_gatts_value_t_dec(p_buf, packet_len, &index, p_value); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_value_set.c b/components/serialization/application/codecs/s130/serializers/ble_gatts_value_set.c deleted file mode 100644 index e11cffc..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_value_set.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_app.h" -#include -#include "nrf_error.h" -#include "cond_field_serialization.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle, - uint16_t handle, - ble_gatts_value_t * p_value, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1 + 2 + 2, *p_buf_len); - p_buf[index++] = SD_BLE_GATTS_VALUE_SET; - index += uint16_encode(conn_handle, &p_buf[index]); - index += uint16_encode(handle, &p_buf[index]); - - if(p_value != NULL) - { - SER_ERROR_CHECK(p_value->len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); - } - err_code = cond_field_enc(p_value, p_buf, *p_buf_len, &index, ble_gatts_value_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gatts_value_t * const p_value, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_BLE_GATTS_VALUE_SET, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - err_code = ble_gatts_value_t_dec(p_buf, packet_len, &index, p_value); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_l2cap_cid_register.c b/components/serialization/application/codecs/s130/serializers/ble_l2cap_cid_register.c deleted file mode 100644 index de597fe..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_l2cap_cid_register.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - -uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - p_buf[index++] = SD_BLE_L2CAP_CID_REGISTER; - err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_REGISTER, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_l2cap_cid_unregister.c b/components/serialization/application/codecs/s130/serializers/ble_l2cap_cid_unregister.c deleted file mode 100644 index cd6e65a..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_l2cap_cid_unregister.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap.h" -#include "app_util.h" - -uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - - p_buf[index++] = SD_BLE_L2CAP_CID_UNREGISTER; - err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_UNREGISTER, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_l2cap_evt_app.h b/components/serialization/application/codecs/s130/serializers/ble_l2cap_evt_app.h deleted file mode 100644 index cb7b22c..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_l2cap_evt_app.h +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_L2CAP_EVT_APP_H__ -#define BLE_L2CAP_EVT_APP_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s130_codecs Application s130 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_l2cap_evt_app L2CAP Application event decoders - * @{ - * @ingroup ser_app_s130_codecs - * - * @brief L2CAP Application event decoders. - */ -#include "ble.h" - -/** - * @brief Decodes ble_l2cap_evt_rx event. - * - * @sa @ref nrf51_l2cap_evt_rx_encoding for packet format. - * - * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. - * - * @param[in] p_buf Pointer to the beginning of an event packet. - * @param[in] packet_len Length (in bytes) of the event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. - * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len); - -/** @} */ -#endif diff --git a/components/serialization/application/codecs/s130/serializers/ble_l2cap_evt_rx.c b/components/serialization/application/codecs/s130/serializers/ble_l2cap_evt_rx.c deleted file mode 100644 index d54682a..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_l2cap_evt_rx.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" -#include "ble_l2cap_evt_app.h" - -uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_evt_t * const p_event, - uint32_t * const p_event_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_event_len); - - uint32_t index = 0; - uint32_t in_event_len = *p_event_len; - - *p_event_len = offsetof(ble_l2cap_evt_t, params); - - uint16_t evt_id; - - uint32_t err_code = uint16_t_dec(p_buf, packet_len, &index, &evt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - void * p_rx = NULL; - - if (p_event) - { - err_code = uint16_t_dec(p_buf, packet_len, &index, &(p_event->evt.l2cap_evt.conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_rx = &(p_event->evt.l2cap_evt.params.rx); - } - - uint32_t struct_len = in_event_len - *p_event_len; - err_code = ble_l2cap_evt_rx_t_dec(p_buf, packet_len, &index, &struct_len, p_rx); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_event_len += struct_len; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_l2cap_tx.c b/components/serialization/application/codecs/s130/serializers/ble_l2cap_tx.c deleted file mode 100644 index 83baa90..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_l2cap_tx.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_l2cap_app.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gap.h" -#include "app_util.h" -#include "cond_field_serialization.h" - -uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle, - ble_l2cap_header_t const * const p_l2cap_header, - uint8_t const * const p_data, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - p_buf[index++] = SD_BLE_L2CAP_TX; - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_l2cap_header, p_buf, *p_buf_len, &index, ble_l2cap_header_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_l2cap_header != NULL) - { - err_code = buf_enc(p_data, p_l2cap_header->len, p_buf, *p_buf_len, &index); - } - else - { - err_code = buf_enc(NULL, 0, p_buf, *p_buf_len, &index); - } - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_TX, p_result_code); -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_opt_get.c b/components/serialization/application/codecs/s130/serializers/ble_opt_get.c deleted file mode 100644 index 7728d66..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_opt_get.c +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_get_req_enc(uint32_t opt_id, - ble_opt_t const * const p_opt, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_LENGTH_LEQ(1+4+1, *p_buf_len); // [OPCODE][OP_ID][PRESENT] - SER_ASSERT(((opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (opt_id == BLE_GAP_OPT_CH_MAP) || - (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (opt_id == BLE_GAP_OPT_PASSKEY) || - (opt_id == BLE_GAP_OPT_PRIVACY) || - (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (opt_id == BLE_GAP_OPT_COMPAT_MODE)) , NRF_ERROR_INVALID_PARAM); - - p_buf[index++] = SD_BLE_OPT_GET; - - err_code = uint32_t_enc(&opt_id, p_buf, *p_buf_len, &index); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - p_buf[index++] = (p_opt == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - -uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t * const p_opt, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_NOT_NULL(p_opt); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_OPT_GET, - p_result_code); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - (void) uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (*p_opt_id == BLE_GAP_OPT_CH_MAP) || - (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (*p_opt_id == BLE_GAP_OPT_PASSKEY) || - (*p_opt_id == BLE_GAP_OPT_PRIVACY) || - (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - switch (*p_opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->common_opt.radio_cpu_mutex)); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.ch_map)); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.local_conn_latency)); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.passkey)); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.privacy)); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.scan_req_report)); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_dec( p_buf, packet_len, &index, (void *)&(p_opt->gap_opt.compat_mode)); - break; - } - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - diff --git a/components/serialization/application/codecs/s130/serializers/ble_opt_set.c b/components/serialization/application/codecs/s130/serializers/ble_opt_set.c deleted file mode 100644 index d6772b0..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_opt_set.c +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_opt_set_req_enc(uint32_t const opt_id, - ble_opt_t const * const p_opt, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t initial_buf_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(1 + 4 + 1, initial_buf_len); - - SER_ASSERT(((opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (opt_id == BLE_GAP_OPT_CH_MAP) || - (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (opt_id == BLE_GAP_OPT_PASSKEY) || - (opt_id == BLE_GAP_OPT_PRIVACY) || - (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - p_buf[index++] = SD_BLE_OPT_SET; - - err_code = uint32_t_enc(&opt_id, p_buf, initial_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_opt != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - - switch(opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_enc(&(p_opt->common_opt.radio_cpu_mutex),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_enc(&(p_opt->gap_opt.ch_map),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_enc(&(p_opt->gap_opt.local_conn_latency),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_enc(&(p_opt->gap_opt.passkey),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_enc(&(p_opt->gap_opt.privacy),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_enc(&(p_opt->gap_opt.scan_req_report),p_buf, initial_buf_len, &index); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_enc(&(p_opt->gap_opt.compat_mode),p_buf, initial_buf_len, &index); - break; - } - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - uint32_t error_code; - - error_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_OPT_SET, p_result_code); - - if (error_code != NRF_SUCCESS) - { - return error_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_tx_buffer_count_get.c b/components/serialization/application/codecs/s130/serializers/ble_tx_buffer_count_get.c deleted file mode 100644 index 944fe63..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_tx_buffer_count_get.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" - -uint32_t ble_tx_buffer_count_get_req_enc(uint8_t const * const p_count, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint8_t opcode = SD_BLE_TX_BUFFER_COUNT_GET; - uint32_t err_code; - uint32_t total_len = *p_buf_len; - - err_code = uint8_t_enc(&opcode, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_count, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_tx_buffer_count_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * const pp_count, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t index = 0; - uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_TX_BUFFER_COUNT_GET, p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_count, uint8_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_user_mem_reply.c b/components/serialization/application/codecs/s130/serializers/ble_user_mem_reply.c deleted file mode 100644 index 7a39b6b..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_user_mem_reply.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle, - ble_user_mem_block_t const * p_block, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - p_buf[index++] = SD_BLE_USER_MEM_REPLY; - - err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if(p_block != NULL) - { - p_buf[index++] = SER_FIELD_PRESENT; - - // Encoding order is different than structure elements order because - // mem block length should be sent first - err_code = uint16_t_enc(&(p_block->len), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_block->p_mem, p_buf, *p_buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - p_buf[index++] = SER_FIELD_NOT_PRESENT; - } - - *p_buf_len = index; - - return err_code; -} - -uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code) -{ - return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_USER_MEM_REPLY, p_result_code); -} - - diff --git a/components/serialization/application/codecs/s130/serializers/ble_uuid_decode.c b/components/serialization/application/codecs/s130/serializers/ble_uuid_decode.c deleted file mode 100644 index 5c3e006..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_uuid_decode.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len, - uint8_t const * const p_uuid_le, - ble_uuid_t * const p_uuid, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code; - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_UUID_DECODE; - - err_code = uint8_t_enc((void *)&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len8data_enc(p_uuid_le, uuid_le_len, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_uuid, p_buf, buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - ble_uuid_t * * const pp_uuid, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t err_code; - uint32_t index = 0; - - uint32_t decode_result = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - buf_len, - SD_BLE_UUID_DECODE, - p_result_code); - - if (decode_result != NRF_SUCCESS) - { - return decode_result; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, buf_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_uuid_encode.c b/components/serialization/application/codecs/s130/serializers/ble_uuid_encode.c deleted file mode 100644 index 5eb8099..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_uuid_encode.c +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, - uint8_t const * const p_uuid_le_len, - uint8_t const * const p_uuid_le, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1 + 1, *p_buf_len); - - p_buf[index++] = SD_BLE_UUID_ENCODE; - - p_buf[index++] = (p_uuid != NULL) ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - if (p_uuid != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); - index += uint16_encode(p_uuid->uuid, &p_buf[index]); - p_buf[index++] = p_uuid->type; - } - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - p_buf[index++] = (p_uuid_le_len == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - p_buf[index++] = (p_uuid_le == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - - -uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_uuid_le_len, - uint8_t * const p_uuid_le, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - uint32_t error_code; - - error_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_UUID_ENCODE, p_result_code); - - if (error_code != NRF_SUCCESS) - { - return error_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, packet_len); - uint8_t uuid_le_len = p_buf[index++]; - - if (p_uuid_le_len != NULL) - { - if (p_uuid_le != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + uuid_le_len, packet_len); - memcpy(p_uuid_le, &(p_buf[index]), uuid_le_len); - index += uuid_le_len; - } - *p_uuid_le_len = uuid_le_len; - } - - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_uuid_vs_add.c b/components/serialization/application/codecs/s130/serializers/ble_uuid_vs_add.c deleted file mode 100644 index 0f686f1..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_uuid_vs_add.c +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid, - uint8_t * const p_uuid_type, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code; - uint32_t index = 0; - uint32_t buf_len = *p_buf_len; - uint8_t opcode = SD_BLE_UUID_VS_ADD; - - err_code = uint8_t_enc(&opcode, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_vs_uuid, p_buf, buf_len, &index, ble_uuid128_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_uuid_type, p_buf, buf_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - - -uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * * const pp_uuid_type, - uint32_t * const p_result_code) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - SER_ASSERT_NOT_NULL(pp_uuid_type); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - buf_len, - SD_BLE_UUID_VS_ADD, - p_result_code); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, buf_len); - return NRF_SUCCESS; - } - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid_type, uint8_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/serializers/ble_version_get.c b/components/serialization/application/codecs/s130/serializers/ble_version_get.c deleted file mode 100644 index 0485b4f..0000000 --- a/components/serialization/application/codecs/s130/serializers/ble_version_get.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_app.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_version_get_req_enc(ble_version_t const * const p_version, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + 2, *p_buf_len); - - p_buf[index++] = SD_BLE_VERSION_GET; - - SER_ASSERT_LENGTH_LEQ(index + 1, *p_buf_len); - - p_buf[index++] = (p_version == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; - - *p_buf_len = index; - - return NRF_SUCCESS; -} - -uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_version_t * p_version, - uint32_t * const p_result_code) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - - uint32_t status_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, - SD_BLE_VERSION_GET, - p_result_code); - - if (status_code != NRF_SUCCESS) - { - return status_code; - } - - if (*p_result_code != NRF_SUCCESS) - { - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; - } - uint8_dec(p_buf, packet_len, &index, &(p_version->version_number)); - uint16_dec(p_buf, packet_len, &index, &(p_version->company_id)); - uint16_dec(p_buf, packet_len, &index, &p_version->subversion_number); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return status_code; -} - - diff --git a/components/serialization/application/codecs/s130/serializers/nrf_soc_app.h b/components/serialization/application/codecs/s130/serializers/nrf_soc_app.h deleted file mode 100644 index 0131837..0000000 --- a/components/serialization/application/codecs/s130/serializers/nrf_soc_app.h +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_app_s130_codecs Application s130 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup soc_app SOC Application command request encoders and command response decoders - * @{ - * @ingroup ser_app_s130_codecs - * - * @brief SOC Application command request encoders and command response decoders. - */ - -#ifndef NRF_SOC_APP_H__ -#define NRF_SOC_APP_H__ - -#include - -/**@brief Encodes @ref sd_power_system_off command request. - * - * @sa @ref nrf51_sd_power_off for packet format. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); - - -/**@brief Encodes @ref sd_temp_get command request. - * - * @sa @ref nrf51_sd_temp_get for packet format. - @ref temp_get_rsp_dec for command response decoder. - * - * @param[in] p_temp Pointer to result of temperature measurement. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t temp_get_req_enc(int32_t const * const p_temp, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes response to @ref sd_temp_get command. - * - * @sa @ref nrf51_sd_temp_get for packet format, - * @ref temp_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * @param[out] p_temp Pointer to result of temperature measurement. - * - * @return NRF_SUCCESS Version information stored successfully. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. - */ -uint32_t temp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - int32_t * const p_temp); - -/** @} */ - -#endif // NRF_SOC_APP_H__ diff --git a/components/serialization/application/codecs/s130/serializers/power_system_off.c b/components/serialization/application/codecs/s130/serializers/power_system_off.c deleted file mode 100644 index c81b1ca..0000000 --- a/components/serialization/application/codecs/s130/serializers/power_system_off.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "nrf_soc_app.h" -#include "ble_serialization.h" -#include "nrf_soc.h" - - -uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); - - p_buf[index++] = SD_POWER_SYSTEM_OFF; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/application/codecs/s130/serializers/temp_get.c b/components/serialization/application/codecs/s130/serializers/temp_get.c deleted file mode 100644 index e50a799..0000000 --- a/components/serialization/application/codecs/s130/serializers/temp_get.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "nrf_soc.h" -#include "nrf_error.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" - -uint32_t temp_get_req_enc(int32_t const * const p_temp, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(1, total_len); - p_buf[index++] = SD_TEMP_GET; - - err_code = cond_field_enc(p_temp, p_buf, total_len, &index, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} - -uint32_t temp_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code, - int32_t * const p_temp) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_result_code); - SER_ASSERT_NOT_NULL(p_temp); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, - &index, - packet_len, - SD_TEMP_GET, - p_result_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*p_result_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_temp); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} diff --git a/components/serialization/application/codecs/s130/middleware/app_mw_ble.c b/components/serialization/application/codecs/s132/middleware/app_mw_ble.c similarity index 79% rename from components/serialization/application/codecs/s130/middleware/app_mw_ble.c rename to components/serialization/application/codecs/s132/middleware/app_mw_ble.c index 51c73c3..6e95d4d 100644 --- a/components/serialization/application/codecs/s130/middleware/app_mw_ble.c +++ b/components/serialization/application/codecs/s132/middleware/app_mw_ble.c @@ -1,15 +1,44 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + #include "ble.h" #include "ble_serialization.h" #include @@ -27,12 +56,6 @@ typedef struct uint8_t * p_uuid_le; /**< @ref sd_ble_uuid_encode appearance p_uuid_le output parameter. */ } ble_uuid_encode_out_params_t; -/**@brief Structure containing @ref sd_ble_tx_buffer_count_get output parameters. */ -typedef struct -{ - uint8_t * p_count; /**< @ref sd_ble_tx_buffer_count_get p_count output parameter. */ -} ble_tx_buffer_count__get_out_params_t; - /**@brief Structure containing @ref sd_ble_user_mem_reply output parameters. */ typedef struct { @@ -44,7 +67,6 @@ typedef struct typedef union { ble_uuid_encode_out_params_t ble_uuid_encode_out_params; /**< @ref sd_ble_uuid_encode output parameters. */ - ble_tx_buffer_count__get_out_params_t ble_tx_buffer_count_get_out_params; /**< @ref sd_ble_uuid_encode output parameters. */ ble_user_mem_reply_out_params_t ble_user_mem_reply_out_params; /**< @ref sd_ble_user_mem_reply output parameters. */ } ble_command_output_params_t; @@ -93,8 +115,10 @@ static uint32_t uuid_encode_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } - -uint32_t sd_ble_uuid_encode(ble_uuid_t const * const p_uuid, +#ifndef _sd_ble_uuid_encode +#define _sd_ble_uuid_encode sd_ble_uuid_encode +#endif +uint32_t _sd_ble_uuid_encode(ble_uuid_t const * const p_uuid, uint8_t * const p_uuid_le_len, uint8_t * const p_uuid_le) { @@ -121,7 +145,7 @@ uint32_t sd_ble_uuid_encode(ble_uuid_t const * const p_uuid, } -/**@brief Command response callback function for @ref sd_ble_tx_buffer_count_get BLE command. +/**@brief Command response callback function for @ref sd_ble_tx_packet_count_get BLE command. * * Callback for decoding the output parameters and the command response return code. * @@ -130,11 +154,11 @@ uint32_t sd_ble_uuid_encode(ble_uuid_t const * const p_uuid, * * @return Decoded command response return code. */ -static uint32_t tx_buffer_count_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +static uint32_t tx_packet_count_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) { uint32_t result_code; - const uint32_t err_code = ble_tx_buffer_count_get_rsp_dec(p_buffer, + const uint32_t err_code = ble_tx_packet_count_get_rsp_dec(p_buffer, length, (uint8_t * *)&mp_out_params[0], &result_code); @@ -145,7 +169,10 @@ static uint32_t tx_buffer_count_get_rsp_dec(const uint8_t * p_buffer, uint16_t l return result_code; } -uint32_t sd_ble_tx_buffer_count_get(uint8_t * p_count) +#ifndef _sd_ble_tx_packet_count_get +#define _sd_ble_tx_packet_count_get sd_ble_tx_packet_count_get +#endif +uint32_t _sd_ble_tx_packet_count_get(uint16_t conn_handle, uint8_t * p_count) { uint8_t * p_buffer; uint32_t buffer_length; @@ -153,7 +180,8 @@ uint32_t sd_ble_tx_buffer_count_get(uint8_t * p_count) tx_buf_alloc(&p_buffer, &buffer_length); mp_out_params[0] = p_count; - const uint32_t err_code = ble_tx_buffer_count_get_req_enc(p_count, + const uint32_t err_code = ble_tx_packet_count_get_req_enc(conn_handle, + p_count, &(p_buffer[1]), &buffer_length); APP_ERROR_CHECK(err_code); @@ -161,7 +189,7 @@ uint32_t sd_ble_tx_buffer_count_get(uint8_t * p_count) //@note: Increment buffer length as internally managed packet type field must be included. return ser_sd_transport_cmd_write(p_buffer, (++buffer_length), - tx_buffer_count_get_rsp_dec); + tx_packet_count_get_rsp_dec); } @@ -189,7 +217,10 @@ static uint32_t uuid_vs_add_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } -uint32_t sd_ble_uuid_vs_add(ble_uuid128_t const * const p_vs_uuid, uint8_t * const p_uuid_type) +#ifndef _sd_ble_uuid_vs_add +#define _sd_ble_uuid_vs_add sd_ble_uuid_vs_add +#endif +uint32_t _sd_ble_uuid_vs_add(ble_uuid128_t const * const p_vs_uuid, uint8_t * const p_uuid_type) { uint8_t * p_buffer; uint32_t buffer_length; @@ -232,7 +263,10 @@ static uint32_t uuid_decode_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } -uint32_t sd_ble_uuid_decode(uint8_t uuid_le_len, +#ifndef _sd_ble_uuid_decode +#define _sd_ble_uuid_decode sd_ble_uuid_decode +#endif +uint32_t _sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const * const p_uuid_le, ble_uuid_t * const p_uuid) { @@ -277,7 +311,10 @@ static uint32_t version_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } -uint32_t sd_ble_version_get(ble_version_t * p_version) +#ifndef _sd_ble_version_get +#define _sd_ble_version_get sd_ble_version_get +#endif +uint32_t _sd_ble_version_get(ble_version_t * p_version) { uint8_t * p_buffer; uint32_t buffer_length; @@ -310,7 +347,6 @@ static uint32_t opt_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) { uint32_t result_code; uint32_t uint32_param; - uint32_t err_code = ble_opt_get_rsp_dec(p_buffer, length, &uint32_param, @@ -318,7 +354,7 @@ static uint32_t opt_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) &result_code); APP_ERROR_CHECK(err_code); - if (m_uint32_param != uint32_param) // decoded id should be the same as encoded one + if ((result_code == NRF_SUCCESS) && (m_uint32_param != uint32_param)) // decoded id should be the same as encoded one { err_code = NRF_ERROR_INVALID_PARAM; } @@ -327,7 +363,10 @@ static uint32_t opt_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } -uint32_t sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt) +#ifndef _sd_ble_opt_get +#define _sd_ble_opt_get sd_ble_opt_get +#endif +uint32_t _sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt) { uint8_t * p_buffer; uint32_t buffer_length; @@ -371,7 +410,10 @@ static uint32_t opt_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } -uint32_t sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt) +#ifndef _sd_ble_opt_set +#define _sd_ble_opt_set sd_ble_opt_set +#endif +uint32_t _sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt) { uint8_t * p_buffer; uint32_t buffer_length; @@ -414,11 +456,17 @@ static uint32_t enable_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } -uint32_t sd_ble_enable(ble_enable_params_t * p_params) +#ifndef _sd_ble_enable +#define _sd_ble_enable sd_ble_enable +#endif +uint32_t _sd_ble_enable(ble_enable_params_t * p_params, uint32_t * p_app_ram_base) { uint8_t * p_buffer; uint32_t buffer_length; + //Ignore ram_base parameter + (void)p_app_ram_base; + tx_buf_alloc(&p_buffer, &buffer_length); mp_out_params[0] = p_params; @@ -452,7 +500,7 @@ static uint32_t user_mem_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length &result_code); APP_ERROR_CHECK(err_code); - if ((result_code != NRF_SUCCESS) && + if ((result_code != NRF_SUCCESS) && (m_output_params.ble_user_mem_reply_out_params.context_allocated)) { err_code = app_ble_user_mem_context_destroy( @@ -463,7 +511,10 @@ static uint32_t user_mem_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length return result_code; } -uint32_t sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block) +#ifndef _sd_ble_user_mem_reply +#define _sd_ble_user_mem_reply sd_ble_user_mem_reply +#endif +uint32_t _sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block) { uint8_t * p_buffer; uint32_t buffer_length, user_mem_table_index; @@ -471,9 +522,9 @@ uint32_t sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const tx_buf_alloc(&p_buffer, &buffer_length); - // Prepare User Memory Block context for later synchronization when SoftDevice updates + // Prepare User Memory Block context for later synchronization when SoftDevice updates // the data in the memory block - if(p_block != NULL) + if (p_block != NULL) { err_code = app_ble_user_mem_context_create(conn_handle, &user_mem_table_index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); @@ -489,7 +540,7 @@ uint32_t sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const } err_code = ble_user_mem_reply_req_enc(conn_handle, - p_block, + p_block, &(p_buffer[1]), &buffer_length); APP_ERROR_CHECK(err_code); diff --git a/components/serialization/application/codecs/s130/middleware/app_mw_ble_gap.c b/components/serialization/application/codecs/s132/middleware/app_mw_ble_gap.c similarity index 67% rename from components/serialization/application/codecs/s130/middleware/app_mw_ble_gap.c rename to components/serialization/application/codecs/s132/middleware/app_mw_ble_gap.c index 27f95ba..3a6a1e8 100644 --- a/components/serialization/application/codecs/s130/middleware/app_mw_ble_gap.c +++ b/components/serialization/application/codecs/s132/middleware/app_mw_ble_gap.c @@ -1,15 +1,44 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + #include "ble_gap.h" #include #include @@ -92,8 +121,10 @@ static uint32_t gap_adv_start_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } - -uint32_t sd_ble_gap_adv_start(ble_gap_adv_params_t const * const p_adv_params) +#ifndef _sd_ble_gap_adv_start +#define _sd_ble_gap_adv_start sd_ble_gap_adv_start +#endif +uint32_t _sd_ble_gap_adv_start(ble_gap_adv_params_t const * const p_adv_params) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -137,8 +168,10 @@ static uint32_t gap_device_name_get_rsp_dec(const uint8_t * p_buffer, uint16_t l return result_code; } - -uint32_t sd_ble_gap_device_name_get(uint8_t * const p_dev_name, uint16_t * const p_len) +#ifndef _sd_ble_gap_device_name_get +#define _sd_ble_gap_device_name_get sd_ble_gap_device_name_get +#endif +uint32_t _sd_ble_gap_device_name_get(uint8_t * const p_dev_name, uint16_t * const p_len) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -186,8 +219,10 @@ static uint32_t gap_appearance_get_rsp_dec(const uint8_t * p_buffer, uint16_t le return result_code; } - -uint32_t sd_ble_gap_appearance_get(uint16_t * const p_appearance) +#ifndef _sd_ble_gap_appearance_get +#define _sd_ble_gap_appearance_get sd_ble_gap_appearance_get +#endif +uint32_t _sd_ble_gap_appearance_get(uint16_t * const p_appearance) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -228,8 +263,10 @@ static uint32_t gap_device_name_set_rsp_dec(const uint8_t * p_buffer, uint16_t l return result_code; } - -uint32_t sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const * const p_write_perm, +#ifndef _sd_ble_gap_device_name_set +#define _sd_ble_gap_device_name_set sd_ble_gap_device_name_set +#endif +uint32_t _sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const * const p_write_perm, uint8_t const * const p_dev_name, uint16_t len) { @@ -272,8 +309,10 @@ static uint32_t gap_appearance_set_rsp_dec(const uint8_t * p_buffer, uint16_t le return result_code; } - -uint32_t sd_ble_gap_appearance_set(uint16_t appearance) +#ifndef _sd_ble_gap_appearance_set +#define _sd_ble_gap_appearance_set sd_ble_gap_appearance_set +#endif +uint32_t _sd_ble_gap_appearance_set(uint16_t appearance) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -313,8 +352,10 @@ static uint32_t gap_ppcp_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } - -uint32_t sd_ble_gap_ppcp_set(ble_gap_conn_params_t const * const p_conn_params) +#ifndef _sd_ble_gap_ppcp_set +#define _sd_ble_gap_ppcp_set sd_ble_gap_ppcp_set +#endif +uint32_t _sd_ble_gap_ppcp_set(ble_gap_conn_params_t const * const p_conn_params) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -353,8 +394,10 @@ static uint32_t gap_adv_data_set_rsp_dec(const uint8_t * p_buffer, uint16_t leng return result_code; } - -uint32_t sd_ble_gap_adv_data_set(uint8_t const * const p_data, +#ifndef _sd_ble_gap_adv_data_set +#define _sd_ble_gap_adv_data_set sd_ble_gap_adv_data_set +#endif +uint32_t _sd_ble_gap_adv_data_set(uint8_t const * const p_data, uint8_t dlen, uint8_t const * const p_sr_data, uint8_t srdlen) @@ -398,8 +441,10 @@ static uint32_t gap_conn_param_update_rsp_dec(const uint8_t * p_buffer, uint16_t return result_code; } - -uint32_t sd_ble_gap_conn_param_update(uint16_t conn_handle, +#ifndef _sd_ble_gap_conn_param_update +#define _sd_ble_gap_conn_param_update sd_ble_gap_conn_param_update +#endif +uint32_t _sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const * const p_conn_params) { uint8_t * p_buffer; @@ -439,8 +484,10 @@ static uint32_t gap_disconnect_rsp_dec(const uint8_t * p_buffer, uint16_t length return result_code; } - -uint32_t sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code) +#ifndef _sd_ble_gap_disconnect +#define _sd_ble_gap_disconnect sd_ble_gap_disconnect +#endif +uint32_t _sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -480,7 +527,10 @@ static uint32_t gap_sec_info_reply_rsp_dec(const uint8_t * p_buffer, uint16_t le return result_code; } -uint32_t sd_ble_gap_sec_info_reply(uint16_t conn_handle, +#ifndef _sd_ble_gap_sec_info_reply +#define _sd_ble_gap_sec_info_reply sd_ble_gap_sec_info_reply +#endif +uint32_t _sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const * p_enc_info, ble_gap_irk_t const * p_id_info, ble_gap_sign_info_t const * p_sign_info) @@ -531,8 +581,10 @@ static uint32_t gap_sec_params_reply_rsp_dec(const uint8_t * p_buffer, uint16_t return result_code; } - -uint32_t sd_ble_gap_sec_params_reply(uint16_t conn_handle, +#ifndef _sd_ble_gap_sec_params_reply +#define _sd_ble_gap_sec_params_reply sd_ble_gap_sec_params_reply +#endif +uint32_t _sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const * p_sec_params, ble_gap_sec_keyset_t const * p_sec_keyset) @@ -592,13 +644,13 @@ static uint32_t gap_ppcp_get_reply_rsp_dec(const uint8_t * p_buffer, uint16_t le //@note: Should never fail. APP_ERROR_CHECK(err_code); - - return result_code; } - -uint32_t sd_ble_gap_ppcp_get(ble_gap_conn_params_t * const p_conn_params) +#ifndef _sd_ble_gap_ppcp_get +#define _sd_ble_gap_ppcp_get sd_ble_gap_ppcp_get +#endif +uint32_t _sd_ble_gap_ppcp_get(ble_gap_conn_params_t * const p_conn_params) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -618,98 +670,6 @@ uint32_t sd_ble_gap_ppcp_get(ble_gap_conn_params_t * const p_conn_params) gap_ppcp_get_reply_rsp_dec); } -/**@brief Command response callback function for @ref sd_ble_gap_address_get BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_address_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_address_get_rsp_dec(p_buffer, - length, - (ble_gap_addr_t *)mp_out_params[0], - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_address_get(ble_gap_addr_t * const p_addr) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - mp_out_params[0] = p_addr; - - const uint32_t err_code = ble_gap_address_get_req_enc(p_addr, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - - gap_address_get_rsp_dec); -} - -/**@brief Command response callback function for @ref sd_ble_gap_address_set BLE command. - * - * Callback for decoding the output parameters and the command response return code. - * - * @param[in] p_buffer Pointer to begin of command response buffer. - * @param[in] length Length of data in bytes. - * - * @return Decoded command response return code. - */ -static uint32_t gap_address_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) -{ - uint32_t result_code = 0; - - const uint32_t err_code = ble_gap_address_set_rsp_dec(p_buffer, - length, - &result_code); - - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - - - return result_code; -} - - -uint32_t sd_ble_gap_address_set(uint8_t addr_cycle_mode, ble_gap_addr_t const * const p_addr) -{ - uint8_t * p_buffer; - uint32_t buffer_length = 0; - - tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_address_set_req_enc(addr_cycle_mode, - p_addr, - &(p_buffer[1]), - &buffer_length); - //@note: Should never fail. - APP_ERROR_CHECK(err_code); - - //@note: Increment buffer length as internally managed packet type field must be included. - return ser_sd_transport_cmd_write(p_buffer, - (++buffer_length), - gap_address_set_rsp_dec); -} /**@brief Command response callback function for @ref sd_ble_gap_adv_stop BLE command. * @@ -731,13 +691,13 @@ static uint32_t gap_adv_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) //@note: Should never fail. APP_ERROR_CHECK(err_code); - - return result_code; } - -uint32_t sd_ble_gap_adv_stop(void) +#ifndef _sd_ble_gap_adv_stop +#define _sd_ble_gap_adv_stop sd_ble_gap_adv_stop +#endif +uint32_t _sd_ble_gap_adv_stop(void) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -780,7 +740,10 @@ static uint32_t gap_auth_key_reply_rsp_dec(const uint8_t * p_buffer, uint16_t le } -uint32_t sd_ble_gap_auth_key_reply(uint16_t conn_handle, +#ifndef _sd_ble_gap_auth_key_reply +#define _sd_ble_gap_auth_key_reply sd_ble_gap_auth_key_reply +#endif +uint32_t _sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const * const key) { @@ -824,8 +787,10 @@ static uint32_t gap_authenticate_rsp_dec(const uint8_t * p_buffer, uint16_t leng return result_code; } - -uint32_t sd_ble_gap_authenticate(uint16_t conn_handle, +#ifndef _sd_ble_gap_authenticate +#define _sd_ble_gap_authenticate sd_ble_gap_authenticate +#endif +uint32_t _sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const * const p_sec_params) { uint8_t * p_buffer; @@ -871,8 +836,10 @@ static uint32_t gap_conn_sec_get_rsp_dec(const uint8_t * p_buffer, uint16_t leng return result_code; } - -uint32_t sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t * const p_conn_sec) +#ifndef _sd_ble_gap_conn_sec_get +#define _sd_ble_gap_conn_sec_get sd_ble_gap_conn_sec_get +#endif +uint32_t _sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t * const p_conn_sec) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -916,15 +883,17 @@ static uint32_t gap_rssi_start_rsp_dec(const uint8_t * p_buffer, uint16_t length return result_code; } - -uint32_t sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count) +#ifndef _sd_ble_gap_rssi_start +#define _sd_ble_gap_rssi_start sd_ble_gap_rssi_start +#endif +uint32_t _sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count) { uint8_t * p_buffer; uint32_t buffer_length = 0; tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); - const uint32_t err_code = ble_gap_rssi_start_req_enc(conn_handle, - threshold_dbm, + const uint32_t err_code = ble_gap_rssi_start_req_enc(conn_handle, + threshold_dbm, skip_count, &(p_buffer[1]), &buffer_length); //@note: Should never fail. @@ -961,8 +930,10 @@ static uint32_t gap_rssi_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } - -uint32_t sd_ble_gap_rssi_stop(uint16_t conn_handle) +#ifndef _sd_ble_gap_rssi_stop +#define _sd_ble_gap_rssi_stop sd_ble_gap_rssi_stop +#endif +uint32_t _sd_ble_gap_rssi_stop(uint16_t conn_handle) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -1004,8 +975,10 @@ static uint32_t gap_tx_power_set_rsp_dec(const uint8_t * p_buffer, uint16_t leng return result_code; } - -uint32_t sd_ble_gap_tx_power_set(int8_t tx_power) +#ifndef _sd_ble_gap_tx_power_set +#define _sd_ble_gap_tx_power_set sd_ble_gap_tx_power_set +#endif +uint32_t _sd_ble_gap_tx_power_set(int8_t tx_power) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -1047,8 +1020,10 @@ static uint32_t gap_scan_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } - -uint32_t sd_ble_gap_scan_stop(void) +#ifndef _sd_ble_gap_scan_stop +#define _sd_ble_gap_scan_stop sd_ble_gap_scan_stop +#endif +uint32_t _sd_ble_gap_scan_stop(void) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -1090,8 +1065,10 @@ static uint32_t gap_connect_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } - -uint32_t sd_ble_gap_connect(ble_gap_addr_t const * const p_addr, +#ifndef _sd_ble_gap_connect +#define _sd_ble_gap_connect sd_ble_gap_connect +#endif +uint32_t _sd_ble_gap_connect(ble_gap_addr_t const * const p_addr, ble_gap_scan_params_t const * const p_scan_params, ble_gap_conn_params_t const * const p_conn_params) { @@ -1138,8 +1115,10 @@ static uint32_t gap_connect_cancel_rsp_dec(const uint8_t * p_buffer, uint16_t le return result_code; } - -uint32_t sd_ble_gap_connect_cancel(void) +#ifndef _sd_ble_gap_connect_cancel +#define _sd_ble_gap_connect_cancel sd_ble_gap_connect_cancel +#endif +uint32_t _sd_ble_gap_connect_cancel(void) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -1179,8 +1158,10 @@ static uint32_t gap_scan_start_rsp_dec(const uint8_t * p_buffer, uint16_t length return result_code; } - -uint32_t sd_ble_gap_scan_start(ble_gap_scan_params_t const * const p_scan_params) +#ifndef _sd_ble_gap_scan_start +#define _sd_ble_gap_scan_start sd_ble_gap_scan_start +#endif +uint32_t _sd_ble_gap_scan_start(ble_gap_scan_params_t const * const p_scan_params) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -1221,8 +1202,10 @@ static uint32_t gap_encrypt_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } - -uint32_t sd_ble_gap_encrypt( uint16_t conn_handle, +#ifndef _sd_ble_gap_encrypt +#define _sd_ble_gap_encrypt sd_ble_gap_encrypt +#endif +uint32_t _sd_ble_gap_encrypt( uint16_t conn_handle, ble_gap_master_id_t const * p_master_id, ble_gap_enc_info_t const * p_enc_info) { @@ -1264,8 +1247,10 @@ static uint32_t gap_rssi_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } - -uint32_t sd_ble_gap_rssi_get(uint16_t conn_handle, +#ifndef _sd_ble_gap_rssi_get +#define _sd_ble_gap_rssi_get sd_ble_gap_rssi_get +#endif +uint32_t _sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t * p_rssi) { uint8_t * p_buffer; @@ -1283,3 +1268,444 @@ uint32_t sd_ble_gap_rssi_get(uint16_t conn_handle, (++buffer_length), gap_rssi_get_rsp_dec); } + +/**@brief Command response callback function for @ref sd_ble_gap_keypress_notify BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_keypress_notify_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_keypress_notify_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_keypress_notify +#define _sd_ble_gap_keypress_notify sd_ble_gap_keypress_notify +#endif +uint32_t _sd_ble_gap_keypress_notify( uint16_t conn_handle, uint8_t kp_not) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_keypress_notify_req_enc( conn_handle, kp_not, &p_buffer[1], &buffer_length ); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_keypress_notify_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_lesc_dhkey_reply BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_lesc_dhkey_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_lesc_dhkey_reply_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_lesc_dhkey_reply +#define _sd_ble_gap_lesc_dhkey_reply sd_ble_gap_lesc_dhkey_reply +#endif +uint32_t _sd_ble_gap_lesc_dhkey_reply( uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_lesc_dhkey_reply_req_enc( conn_handle, p_dhkey, &(p_buffer[1]), &buffer_length ); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_lesc_dhkey_reply_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_lesc_oob_data_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_lesc_oob_data_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_lesc_oob_data_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_lesc_oob_data_set +#define _sd_ble_gap_lesc_oob_data_set sd_ble_gap_lesc_oob_data_set +#endif +uint32_t _sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, + ble_gap_lesc_oob_data_t const *p_oobd_own, + ble_gap_lesc_oob_data_t const *p_oobd_peer) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_lesc_oob_data_set_req_enc(conn_handle, p_oobd_own, p_oobd_peer, + &(p_buffer[1]), &buffer_length ); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_lesc_oob_data_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_lesc_oob_data_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_lesc_oob_data_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_lesc_oob_data_get_rsp_dec(p_buffer, + length, + (ble_gap_lesc_oob_data_t **) &mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gap_lesc_oob_data_get +#define _sd_ble_gap_lesc_oob_data_get sd_ble_gap_lesc_oob_data_get +#endif +uint32_t _sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, + ble_gap_lesc_p256_pk_t const *p_pk_own, + ble_gap_lesc_oob_data_t *p_oobd_own) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_oobd_own; + const uint32_t err_code = ble_gap_lesc_oob_data_get_req_enc(conn_handle, p_pk_own, p_oobd_own, + &(p_buffer[1]), &buffer_length ); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_lesc_oob_data_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_addr_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_addr_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_addr_get_rsp_dec(p_buffer, + length, + (ble_gap_addr_t *)mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_addr_get +#define _sd_ble_gap_addr_get sd_ble_gap_addr_get +#endif +uint32_t _sd_ble_gap_addr_get(ble_gap_addr_t * const p_addr) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_addr; + + const uint32_t err_code = ble_gap_addr_get_req_enc(p_addr, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_addr_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_addr_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_addr_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_addr_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_addr_set +#define _sd_ble_gap_addr_set sd_ble_gap_addr_set +#endif +uint32_t _sd_ble_gap_addr_set(ble_gap_addr_t const * const p_addr) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = ble_gap_addr_set_req_enc(p_addr, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_addr_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_privacy_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_privacy_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_privacy_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_privacy_set +#define _sd_ble_gap_privacy_set sd_ble_gap_privacy_set +#endif +uint32_t _sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gap_privacy_set_req_enc(p_privacy_params, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_privacy_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_privacy_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_privacy_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_privacy_get_rsp_dec(p_buffer, + length, + (ble_gap_privacy_params_t *)mp_out_params[0], + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_privacy_get +#define _sd_ble_gap_privacy_get sd_ble_gap_privacy_get +#endif +uint32_t _sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_privacy_params; + + const uint32_t err_code = ble_gap_privacy_get_req_enc(p_privacy_params, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_privacy_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_whitelist_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_whitelist_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_whitelist_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_whitelist_set +#define _sd_ble_gap_whitelist_set sd_ble_gap_whitelist_set +#endif +uint32_t _sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gap_whitelist_set_req_enc(pp_wl_addrs, len, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_whitelist_set_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gap_device_identities_set BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gap_device_identities_set_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code = 0; + + const uint32_t err_code = ble_gap_device_identities_set_rsp_dec(p_buffer, + length, + &result_code); + + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gap_device_identities_set +#define _sd_ble_gap_device_identities_set sd_ble_gap_device_identities_set +#endif +uint32_t _sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gap_device_identities_set_req_enc(pp_id_keys, + pp_local_irks, + len, + &(p_buffer[1]), &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gap_device_identities_set_rsp_dec); +} diff --git a/components/serialization/application/codecs/s130/middleware/app_mw_ble_gattc.c b/components/serialization/application/codecs/s132/middleware/app_mw_ble_gattc.c similarity index 67% rename from components/serialization/application/codecs/s130/middleware/app_mw_ble_gattc.c rename to components/serialization/application/codecs/s132/middleware/app_mw_ble_gattc.c index 26cfab9..a89dee2 100644 --- a/components/serialization/application/codecs/s130/middleware/app_mw_ble_gattc.c +++ b/components/serialization/application/codecs/s132/middleware/app_mw_ble_gattc.c @@ -1,15 +1,44 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + #include #include "ble_gattc.h" #include "ble_gattc_app.h" @@ -53,7 +82,10 @@ static uint32_t gattc_primary_services_discover_rsp_dec(const uint8_t * p_buffer return result_code; } -uint32_t sd_ble_gattc_primary_services_discover(uint16_t conn_handle, +#ifndef _sd_ble_gattc_primary_services_discover +#define _sd_ble_gattc_primary_services_discover sd_ble_gattc_primary_services_discover +#endif +uint32_t _sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const * const p_srvc_uuid) { @@ -99,7 +131,10 @@ static uint32_t gattc_relationships_discover_rsp_dec(const uint8_t * p_buffer, u return result_code; } -uint32_t sd_ble_gattc_relationships_discover(uint16_t conn_handle, +#ifndef _sd_ble_gattc_relationships_discover +#define _sd_ble_gattc_relationships_discover sd_ble_gattc_relationships_discover +#endif +uint32_t _sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * const p_handle_range) { uint8_t * p_buffer; @@ -143,7 +178,10 @@ static uint32_t gattc_characteristics_discover_rsp_dec(const uint8_t * p_buffer, return result_code; } -uint32_t sd_ble_gattc_characteristics_discover( +#ifndef _sd_ble_gattc_characteristics_discover +#define _sd_ble_gattc_characteristics_discover sd_ble_gattc_characteristics_discover +#endif +uint32_t _sd_ble_gattc_characteristics_discover( uint16_t conn_handle, ble_gattc_handle_range_t const * const p_handle_range) @@ -187,7 +225,10 @@ static uint32_t gattc_descriptors_discover_rsp_dec(const uint8_t * p_buffer, uin return result_code; } -uint32_t sd_ble_gattc_descriptors_discover(uint16_t conn_handle, +#ifndef _sd_ble_gattc_descriptors_discover +#define _sd_ble_gattc_descriptors_discover sd_ble_gattc_descriptors_discover +#endif +uint32_t _sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * const p_handle_range) { uint8_t * p_buffer; @@ -231,7 +272,10 @@ static uint32_t gattc_char_value_by_uuid_read_rsp_dec(const uint8_t * p_buffer, return result_code; } -uint32_t sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, +#ifndef _sd_ble_gattc_char_value_by_uuid_read +#define _sd_ble_gattc_char_value_by_uuid_read sd_ble_gattc_char_value_by_uuid_read +#endif +uint32_t _sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const * const p_uuid, ble_gattc_handle_range_t const * const p_handle_range) { @@ -275,7 +319,10 @@ static uint32_t gattc_read_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } -uint32_t sd_ble_gattc_read(uint16_t conn_handle, +#ifndef _sd_ble_gattc_read +#define _sd_ble_gattc_read sd_ble_gattc_read +#endif +uint32_t _sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset) { @@ -319,7 +366,10 @@ static uint32_t gattc_char_values_read_rsp_dec(const uint8_t * p_buffer, uint16_ return result_code; } -uint32_t sd_ble_gattc_char_values_read(uint16_t conn_handle, +#ifndef _sd_ble_gattc_char_values_read +#define _sd_ble_gattc_char_values_read sd_ble_gattc_char_values_read +#endif +uint32_t _sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const * const p_handles, uint16_t handle_count) { @@ -363,7 +413,10 @@ static uint32_t gattc_write_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } -uint32_t sd_ble_gattc_write(uint16_t conn_handle, +#ifndef _sd_ble_gattc_write +#define _sd_ble_gattc_write sd_ble_gattc_write +#endif +uint32_t _sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const * const p_write_params) { uint8_t * p_buffer; @@ -405,7 +458,10 @@ static uint32_t gattc_hv_confirm_rsp_dec(const uint8_t * p_buffer, uint16_t leng return result_code; } -uint32_t sd_ble_gattc_hv_confirm(uint16_t conn_handle, +#ifndef _sd_ble_gattc_hv_confirm +#define _sd_ble_gattc_hv_confirm sd_ble_gattc_hv_confirm +#endif +uint32_t _sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle) { uint8_t * p_buffer; @@ -424,3 +480,89 @@ uint32_t sd_ble_gattc_hv_confirm(uint16_t conn_handle, (++buffer_length), gattc_hv_confirm_rsp_dec); } + + +/**@brief Command response callback function for @ref sd_ble_gattc_info_discover BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_attr_info_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_attr_info_discover_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gattc_attr_info_discover +#define _sd_ble_gattc_attr_info_discover sd_ble_gattc_attr_info_discover +#endif +uint32_t _sd_ble_gattc_attr_info_discover(uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_attr_info_discover_req_enc(conn_handle, + p_handle_range, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_attr_info_discover_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gattc_write BLE command. + * + * Callback for decoding the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gattc_exchange_mtu_request_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gattc_exchange_mtu_request_rsp_dec(p_buffer, length, &result_code); + + APP_ERROR_CHECK(err_code); + return result_code; +} + +#ifndef _sd_ble_gattc_exchange_mtu_request +#define _sd_ble_gattc_exchange_mtu_request sd_ble_gattc_exchange_mtu_request +#endif +uint32_t _sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, + uint16_t client_rx_mtu) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gattc_exchange_mtu_request_req_enc(conn_handle, + client_rx_mtu, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gattc_exchange_mtu_request_rsp_dec); +} diff --git a/components/serialization/application/codecs/s110/middleware/app_mw_ble_gatts.c b/components/serialization/application/codecs/s132/middleware/app_mw_ble_gatts.c similarity index 67% rename from components/serialization/application/codecs/s110/middleware/app_mw_ble_gatts.c rename to components/serialization/application/codecs/s132/middleware/app_mw_ble_gatts.c index abc1120..5115afc 100644 --- a/components/serialization/application/codecs/s110/middleware/app_mw_ble_gatts.c +++ b/components/serialization/application/codecs/s132/middleware/app_mw_ble_gatts.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_gatts.h" @@ -56,8 +84,10 @@ static uint32_t gatts_sys_attr_set_rsp_dec(const uint8_t * p_buffer, uint16_t le return result_code; } - -uint32_t sd_ble_gatts_sys_attr_set(uint16_t conn_handle, +#ifndef _sd_ble_gatts_sys_attr_set +#define _sd_ble_gatts_sys_attr_set sd_ble_gatts_sys_attr_set +#endif +uint32_t _sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const * const p_sys_attr_data, uint16_t len, uint32_t flags) @@ -102,8 +132,10 @@ static uint32_t gatts_hvx_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } - -uint32_t sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const * const p_hvx_params) +#ifndef _sd_ble_gatts_hvx +#define _sd_ble_gatts_hvx sd_ble_gatts_hvx +#endif +uint32_t _sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const * const p_hvx_params) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -150,8 +182,10 @@ static uint32_t gatts_service_add_rsp_dec(const uint8_t * p_buffer, uint16_t len return result_code; } - -uint32_t sd_ble_gatts_service_add(uint8_t type, +#ifndef _sd_ble_gatts_service_add +#define _sd_ble_gatts_service_add sd_ble_gatts_service_add +#endif +uint32_t _sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const * const p_uuid, uint16_t * const p_handle) { @@ -198,7 +232,10 @@ static uint32_t gatts_service_changed_rsp_dec(const uint8_t * p_buffer, uint16_t return result_code; } -uint32_t sd_ble_gatts_service_changed(uint16_t conn_handle, +#ifndef _sd_ble_gatts_service_changed +#define _sd_ble_gatts_service_changed sd_ble_gatts_service_changed +#endif +uint32_t _sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle) { @@ -246,7 +283,10 @@ static uint32_t gatts_include_add_rsp_dec(const uint8_t * p_buffer, uint16_t len return result_code; } -uint32_t sd_ble_gatts_include_add(uint16_t service_handle, +#ifndef _sd_ble_gatts_include_add +#define _sd_ble_gatts_include_add sd_ble_gatts_include_add +#endif +uint32_t _sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_serv_handle, uint16_t * const p_include_handle) { @@ -294,8 +334,10 @@ static uint32_t gatts_characteristic_add_rsp_dec(const uint8_t * p_buffer, uint1 return result_code; } - -uint32_t sd_ble_gatts_characteristic_add(uint16_t service_handle, +#ifndef _sd_ble_gatts_characteristic_add +#define _sd_ble_gatts_characteristic_add sd_ble_gatts_characteristic_add +#endif +uint32_t _sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const * const p_char_md, ble_gatts_attr_t const * const p_attr_char_value, ble_gatts_char_handles_t * const p_handles) @@ -346,7 +388,10 @@ static uint32_t gatts_descriptor_add_rsp_dec(const uint8_t * p_buffer, uint16_t return result_code; } -uint32_t sd_ble_gatts_descriptor_add(uint16_t char_handle, +#ifndef _sd_ble_gatts_descriptor_add +#define _sd_ble_gatts_descriptor_add sd_ble_gatts_descriptor_add +#endif +uint32_t _sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const * const p_attr, uint16_t * const p_handle) { @@ -394,7 +439,10 @@ static uint32_t gatts_rw_authorize_reply_rsp_dec(const uint8_t * p_buffer, uint1 return result_code; } -uint32_t sd_ble_gatts_rw_authorize_reply( +#ifndef _sd_ble_gatts_rw_authorize_reply +#define _sd_ble_gatts_rw_authorize_reply sd_ble_gatts_rw_authorize_reply +#endif +uint32_t _sd_ble_gatts_rw_authorize_reply( uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const * const p_rw_authorize_reply_params) @@ -443,7 +491,10 @@ static uint32_t gatts_value_get_rsp_dec(const uint8_t * p_buffer, uint16_t lengt return result_code; } -uint32_t sd_ble_gatts_value_get(uint16_t conn_handle, +#ifndef _sd_ble_gatts_value_get +#define _sd_ble_gatts_value_get sd_ble_gatts_value_get +#endif +uint32_t _sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t * p_value) { @@ -491,8 +542,10 @@ static uint32_t gatts_value_set_rsp_dec(const uint8_t * p_buffer, uint16_t lengt return result_code; } - -uint32_t sd_ble_gatts_value_set(uint16_t conn_handle, +#ifndef _sd_ble_gatts_value_set +#define _sd_ble_gatts_value_set sd_ble_gatts_value_set +#endif +uint32_t _sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t * p_value) { @@ -501,7 +554,7 @@ uint32_t sd_ble_gatts_value_set(uint16_t conn_handle, tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); mp_out_params[0] = p_value; - + const uint32_t err_code = ble_gatts_value_set_req_enc(conn_handle, handle, p_value, @@ -533,8 +586,8 @@ static uint32_t gatts_sys_attr_get_rsp_dec(const uint8_t * p_buffer, uint16_t le const uint32_t err_code = ble_gatts_sys_attr_get_rsp_dec( p_buffer, length, - (uint8_t *) mp_out_params[0], - (uint16_t *) mp_out_params[1], + (uint8_t * *) &mp_out_params[0], + (uint16_t * *) &mp_out_params[1], &result_code); APP_ERROR_CHECK(err_code); @@ -542,8 +595,10 @@ static uint32_t gatts_sys_attr_get_rsp_dec(const uint8_t * p_buffer, uint16_t le return result_code; } - -uint32_t sd_ble_gatts_sys_attr_get(uint16_t conn_handle, +#ifndef _sd_ble_gatts_sys_attr_get +#define _sd_ble_gatts_sys_attr_get sd_ble_gatts_sys_attr_get +#endif +uint32_t _sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t * const p_sys_attr_data, uint16_t * const p_len, uint32_t flags) @@ -569,3 +624,151 @@ uint32_t sd_ble_gatts_sys_attr_get(uint16_t conn_handle, (++buffer_length), gatts_sys_attr_get_rsp_dec); } + +/**@brief Command response callback function for @ref sd_ble_gatts_attr_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_attr_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_attr_get_rsp_dec( + p_buffer, + length, + (ble_uuid_t **)&mp_out_params[0], + (ble_gatts_attr_md_t **)&mp_out_params[1], + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gatts_attr_get +#define _sd_ble_gatts_attr_get sd_ble_gatts_attr_get +#endif +uint32_t _sd_ble_gatts_attr_get(uint16_t handle, + ble_uuid_t * p_uuid, + ble_gatts_attr_md_t * p_md) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_uuid; + mp_out_params[1] = p_md; + + const uint32_t err_code = ble_gatts_attr_get_req_enc(handle, + p_uuid, + p_md, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_attr_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_initial_user_handle_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_initial_user_handle_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_initial_user_handle_get_rsp_dec( + p_buffer, + length, + (uint16_t **)&mp_out_params[0], + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gatts_initial_user_handle_get +#define _sd_ble_gatts_initial_user_handle_get sd_ble_gatts_initial_user_handle_get +#endif +uint32_t _sd_ble_gatts_initial_user_handle_get(uint16_t * p_handle) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_params[0] = p_handle; + + const uint32_t err_code = ble_gatts_initial_user_handle_get_req_enc(p_handle, + &(p_buffer[1]), + &buffer_length); + //@note: Should never fail. + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_initial_user_handle_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ble_gatts_exchange_mtu_reply BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ +static uint32_t gatts_exchange_mtu_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ble_gatts_exchange_mtu_reply_rsp_dec( + p_buffer, + length, + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +#ifndef _sd_ble_gatts_exchange_mtu_reply +#define _sd_ble_gatts_exchange_mtu_reply sd_ble_gatts_exchange_mtu_reply +#endif +uint32_t _sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu) +{ + + + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + + const uint32_t err_code = ble_gatts_exchange_mtu_reply_req_enc(conn_handle, + server_rx_mtu, + &(p_buffer[1]), + &buffer_length); + + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + gatts_exchange_mtu_reply_rsp_dec); +} diff --git a/components/serialization/application/codecs/s130/middleware/app_mw_ble_l2cap.c b/components/serialization/application/codecs/s132/middleware/app_mw_ble_l2cap.c similarity index 65% rename from components/serialization/application/codecs/s130/middleware/app_mw_ble_l2cap.c rename to components/serialization/application/codecs/s132/middleware/app_mw_ble_l2cap.c index 436d5a2..28540a4 100644 --- a/components/serialization/application/codecs/s130/middleware/app_mw_ble_l2cap.c +++ b/components/serialization/application/codecs/s132/middleware/app_mw_ble_l2cap.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_gap.h" @@ -52,8 +80,10 @@ static uint32_t l2cap_cid_register_rsp_dec(const uint8_t * p_buffer, uint16_t le return result_code; } - -uint32_t sd_ble_l2cap_cid_register(uint16_t cid) +#ifndef _sd_ble_l2cap_cid_register +#define _sd_ble_l2cap_cid_register sd_ble_l2cap_cid_register +#endif +uint32_t _sd_ble_l2cap_cid_register(uint16_t cid) { uint8_t * p_buffer; @@ -97,8 +127,10 @@ static uint32_t l2cap_cid_unregister_rsp_dec(const uint8_t * p_buffer, uint16_t return result_code; } - -uint32_t sd_ble_l2cap_cid_unregister(uint16_t cid) +#ifndef _sd_ble_l2cap_cid_unregister +#define _sd_ble_l2cap_cid_unregister sd_ble_l2cap_cid_unregister +#endif +uint32_t _sd_ble_l2cap_cid_unregister(uint16_t cid) { uint8_t * p_buffer; uint32_t buffer_length = 0; @@ -141,8 +173,10 @@ static uint32_t l2cap_tx_rsp_dec(const uint8_t * p_buffer, uint16_t length) return result_code; } - -uint32_t sd_ble_l2cap_tx(uint16_t conn_handle, +#ifndef _sd_ble_l2cap_tx +#define _sd_ble_l2cap_tx sd_ble_l2cap_tx +#endif +uint32_t _sd_ble_l2cap_tx(uint16_t conn_handle, ble_l2cap_header_t const * const p_header, uint8_t const * const p_data) { diff --git a/components/serialization/application/codecs/s132/middleware/app_mw_nrf_soc.c b/components/serialization/application/codecs/s132/middleware/app_mw_nrf_soc.c new file mode 100644 index 0000000..1c09d5e --- /dev/null +++ b/components/serialization/application/codecs/s132/middleware/app_mw_nrf_soc.c @@ -0,0 +1,172 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_soc.h" +#include +#include +#include "ser_sd_transport.h" +#include "nrf_soc_app.h" +#include "nrf_error_soc.h" +#include "app_error.h" +#include "ble_serialization.h" + +#include "ser_app_power_system_off.h" + +static void * mp_out_param; + +static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len) +{ + uint32_t err_code; + + do + { + err_code = ser_sd_transport_tx_alloc(p_data, p_len); + } + while (err_code != NRF_SUCCESS); + *p_data[0] = SER_PKT_TYPE_CMD; + *p_len -= 1; +} + + +uint32_t sd_power_system_off(void) +{ + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + const uint32_t err_code = power_system_off_req_enc(&(p_buffer[1]), &buffer_length); + APP_ERROR_CHECK(err_code); + + ser_app_power_system_off_set(); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + NULL); +} + + +/**@brief Command response callback function for @ref sd_temp_get BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ + +static uint32_t mw_temp_get_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = temp_get_rsp_dec(p_buffer, + length, + &result_code, + (int32_t * *) &mp_out_param); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_temp_get(int32_t * p_temp) +{ + + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_param = p_temp; + + const uint32_t err_code = temp_get_req_enc(p_temp, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + mw_temp_get_rsp_dec); +} + +/**@brief Command response callback function for @ref sd_ecb_block_encrypt BLE command. + * + * Callback for decoding the output parameters and the command response return code. + * + * @param[in] p_buffer Pointer to begin of command response buffer. + * @param[in] length Length of data in bytes. + * + * @return Decoded command response return code. + */ + +static uint32_t mw_ecb_block_encrypt_rsp_dec(const uint8_t * p_buffer, uint16_t length) +{ + uint32_t result_code; + + const uint32_t err_code = ecb_block_encrypt_rsp_dec(p_buffer, + length, + (nrf_ecb_hal_data_t * *)&mp_out_param, + &result_code); + + APP_ERROR_CHECK(err_code); + + return result_code; +} + +uint32_t sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data) +{ + + uint8_t * p_buffer; + uint32_t buffer_length = 0; + + tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length); + mp_out_param = p_ecb_data; + + const uint32_t err_code = ecb_block_encrypt_req_enc(p_ecb_data, + &(p_buffer[1]), + &buffer_length); + APP_ERROR_CHECK(err_code); + + //@note: Increment buffer length as internally managed packet type field must be included. + return ser_sd_transport_cmd_write(p_buffer, + (++buffer_length), + mw_ecb_block_encrypt_rsp_dec); +} diff --git a/components/serialization/application/codecs/s132/serializers/app_ble_gap_sec_keys.c b/components/serialization/application/codecs/s132/serializers/app_ble_gap_sec_keys.c new file mode 100644 index 0000000..b098403 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/app_ble_gap_sec_keys.c @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "app_ble_gap_sec_keys.h" +#include "nrf_error.h" +#include + +ser_ble_gap_app_keyset_t m_app_keys_table[SER_MAX_CONNECTIONS]; + +uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index) +{ + uint32_t err_code = NRF_ERROR_NO_MEM; + uint32_t i; + + for (i=0; i + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SER_MAX_CONNECTIONS +#define SER_MAX_CONNECTIONS 2 +#endif +/**@brief GAP connection - keyset mapping structure. + * + * @note This structure is used to map keysets to connection instances and store them in a static table. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection handle.*/ + uint8_t conn_active; /**< Indication that keys for this connection are used by the SoftDevice. 0: keys used; 1: keys not used. */ + ble_gap_sec_keyset_t keyset; /**< Keyset structure, see @ref ble_gap_sec_keyset_t.*/ +} ser_ble_gap_app_keyset_t; + +/**@brief Allocates the instance in m_app_keys_table[] for storage of encryption keys. + * + * @param[in] conn_handle conn_handle + * @param[out] p_index Pointer to the index of the allocated instance. + * + * @retval NRF_SUCCESS Context allocated. + * @retval NRF_ERROR_NO_MEM No free instance available. + */ +uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index); + +/**@brief Release the instance identified by a connection handle. + * + * @param[in] conn_handle conn_handle + * + * @retval NRF_SUCCESS Context released. + * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found. + */ +uint32_t app_ble_gap_sec_context_destroy(uint16_t conn_handle); + +/**@brief Finds index of instance identified by a connection handle in m_app_keys_table[]. + * + * @param[in] conn_handle conn_handle + * + * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle. + * + * @retval NRF_SUCCESS Context found. + * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found. + */ +uint32_t app_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif //_APP_BLE_GAP_SEC_KEYS_H diff --git a/components/serialization/application/codecs/s132/serializers/app_ble_user_mem.c b/components/serialization/application/codecs/s132/serializers/app_ble_user_mem.c new file mode 100644 index 0000000..dbb8a87 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/app_ble_user_mem.c @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "app_ble_user_mem.h" +#include "ser_config.h" +#include "nrf_error.h" +#include + +ser_ble_user_mem_t m_app_user_mem_table[SER_MAX_CONNECTIONS]; + +uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index) +{ + uint32_t err_code = NRF_ERROR_NO_MEM; + uint32_t i; + + for (i=0; i + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Connection - user memory mapping structure. + * + * @note This structure is used to map user memory to connection instances and store it in a static table. + */ +//lint -esym(452,ser_ble_user_mem_t) +typedef struct +{ + uint16_t conn_handle; /**< Connection handle. */ + uint8_t conn_active; /**< Indication that user memory for this connection is used by the SoftDevice. 0: memory used; 1: memory not used. */ + ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t. */ +} ser_ble_user_mem_t; + +/**@brief Allocates instance in m_user_mem_table[] for storage. + * + * @param[in] conn_handle conn_handle + * @param[out] p_index Pointer to the index of the allocated instance. + * + * @retval NRF_SUCCESS Context allocated. + * @retval NRF_ERROR_NO_MEM No free instance available. + */ +uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index); + +/**@brief Release instance identified by a connection handle. + * + * @param[in] conn_handle conn_handle + * + * @retval NRF_SUCCESS Context released. + * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found. + */ +uint32_t app_ble_user_mem_context_destroy(uint16_t conn_handle); + +/**@brief Finds index of the instance identified by a connection handle in m_user_mem_table[]. + * + * @param[in] conn_handle conn_handle + * + * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle. + * + * @retval NRF_SUCCESS Context found. + * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found. + */ +uint32_t app_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif //_APP_BLE_USER_MEM_H diff --git a/components/serialization/application/codecs/s132/serializers/ble_app.c b/components/serialization/application/codecs/s132/serializers/ble_app.c new file mode 100644 index 0000000..3d909b9 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_app.c @@ -0,0 +1,411 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ble_app.h" +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + + +uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_ENABLE); + SER_PUSH_COND(p_ble_enable_params, ble_enable_params_t_enc); + SER_REQ_ENC_END; +} + + +uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_ENABLE); +} + +uint32_t ble_opt_get_req_enc(uint32_t opt_id, + ble_opt_t const * const p_opt, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_OPT_GET); + + SER_ASSERT(((opt_id == BLE_COMMON_OPT_CONN_BW) || + (opt_id == BLE_COMMON_OPT_PA_LNA) || + (opt_id == BLE_COMMON_OPT_CONN_EVT_EXT) || + (opt_id == BLE_GAP_OPT_CH_MAP) || + (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || + (opt_id == BLE_GAP_OPT_PASSKEY) || + (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || + (opt_id == BLE_GAP_OPT_COMPAT_MODE) || + (opt_id == BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT) || + (opt_id == BLE_GAP_OPT_EXT_LEN)), NRF_ERROR_INVALID_PARAM); + + SER_PUSH_uint32(&opt_id); + SER_PUSH_COND(p_opt, NULL); + + SER_REQ_ENC_END; +} + +uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_opt_id, + ble_opt_t * const p_opt, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_OPT_GET); + + SER_PULL_uint32(p_opt_id); + SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_CONN_BW) || + (*p_opt_id == BLE_COMMON_OPT_PA_LNA) || + (*p_opt_id == BLE_COMMON_OPT_CONN_EVT_EXT) || + (*p_opt_id == BLE_GAP_OPT_CH_MAP) || + (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || + (*p_opt_id == BLE_GAP_OPT_PASSKEY) || + (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || + (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE) || + (*p_opt_id == BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT) || + (*p_opt_id == BLE_GAP_OPT_EXT_LEN)), NRF_ERROR_INVALID_PARAM); + + field_decoder_handler_t fp_decoder = NULL; + void * p_struct = NULL; + + switch (*p_opt_id) + { + case BLE_COMMON_OPT_CONN_BW: + fp_decoder = ble_common_opt_conn_bw_t_dec; + p_struct = &(p_opt->common_opt.conn_bw); + break; + case BLE_COMMON_OPT_PA_LNA: + fp_decoder = ble_common_opt_pa_lna_t_dec; + p_struct = &(p_opt->common_opt.pa_lna); + break; + case BLE_COMMON_OPT_CONN_EVT_EXT: + fp_decoder = ble_common_opt_conn_evt_ext_t_dec; + p_struct = &(p_opt->common_opt.conn_evt_ext); + break; + case BLE_GAP_OPT_CH_MAP: + fp_decoder = ble_gap_opt_ch_map_t_dec; + p_struct =&(p_opt->gap_opt.ch_map); + break; + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + fp_decoder = ble_gap_opt_local_conn_latency_t_dec; + p_struct = &(p_opt->gap_opt.local_conn_latency); + break; + case BLE_GAP_OPT_PASSKEY: + fp_decoder = ble_gap_opt_passkey_t_dec; + p_struct = &(p_opt->gap_opt.passkey); + break; + case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT: + fp_decoder = ble_gap_opt_auth_payload_timeout_t_dec; + p_struct = &(p_opt->gap_opt.auth_payload_timeout); + break; + case BLE_GAP_OPT_EXT_LEN: + fp_decoder = ble_gap_opt_ext_len_t_dec; + p_struct = &(p_opt->gap_opt.ext_len); + break; + case BLE_GAP_OPT_SCAN_REQ_REPORT: + fp_decoder = ble_gap_opt_scan_req_report_t_dec; + p_struct = &(p_opt->gap_opt.scan_req_report); + break; + case BLE_GAP_OPT_COMPAT_MODE: + fp_decoder = ble_gap_opt_compat_mode_t_dec; + p_struct = &(p_opt->gap_opt.compat_mode); + break; + default: + SER_ASSERT(NRF_ERROR_INVALID_PARAM, NRF_ERROR_INVALID_PARAM); + break; + } + + SER_PULL_FIELD(p_struct, fp_decoder); + + SER_RSP_DEC_END; +} + + + +uint32_t ble_opt_set_req_enc(uint32_t const opt_id, + ble_opt_t const * const p_opt, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_OPT_SET); + + SER_ASSERT(((opt_id == BLE_COMMON_OPT_CONN_BW) || + (opt_id == BLE_COMMON_OPT_PA_LNA) || + (opt_id == BLE_COMMON_OPT_CONN_EVT_EXT) || + (opt_id == BLE_GAP_OPT_CH_MAP) || + (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || + (opt_id == BLE_GAP_OPT_PASSKEY) || + (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || + (opt_id == BLE_GAP_OPT_COMPAT_MODE) || + (opt_id == BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT) || + (opt_id == BLE_GAP_OPT_EXT_LEN)), NRF_ERROR_INVALID_PARAM); + + SER_PUSH_uint32(&opt_id); + + field_encoder_handler_t fp_encoder = NULL; + void const * p_struct = NULL; + + SER_PUSH_COND(p_opt, NULL); + if (p_opt) + { + switch(opt_id) + { + case BLE_COMMON_OPT_CONN_BW: + fp_encoder = ble_common_opt_conn_bw_t_enc; + p_struct = &(p_opt->common_opt.conn_bw); + break; + case BLE_COMMON_OPT_PA_LNA: + fp_encoder = ble_common_opt_pa_lna_t_enc; + p_struct = &(p_opt->common_opt.pa_lna); + break; + case BLE_COMMON_OPT_CONN_EVT_EXT: + fp_encoder = ble_common_opt_conn_evt_ext_t_enc; + p_struct = &(p_opt->common_opt.conn_evt_ext); + break; + case BLE_GAP_OPT_CH_MAP: + fp_encoder = ble_gap_opt_ch_map_t_enc; + p_struct = &(p_opt->gap_opt.ch_map); + break; + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + fp_encoder = ble_gap_opt_local_conn_latency_t_enc; + p_struct = &(p_opt->gap_opt.local_conn_latency); + break; + case BLE_GAP_OPT_PASSKEY: + fp_encoder = ble_gap_opt_passkey_t_enc; + p_struct = &(p_opt->gap_opt.passkey); + break; + case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT: + fp_encoder = ble_gap_opt_auth_payload_timeout_t_enc; + p_struct = &(p_opt->gap_opt.auth_payload_timeout); + break; + case BLE_GAP_OPT_EXT_LEN: + fp_encoder = ble_gap_opt_ext_len_t_enc; + p_struct = &(p_opt->gap_opt.ext_len); + break; + case BLE_GAP_OPT_SCAN_REQ_REPORT: + fp_encoder = ble_gap_opt_scan_req_report_t_enc; + p_struct = &(p_opt->gap_opt.scan_req_report); + break; + case BLE_GAP_OPT_COMPAT_MODE: + fp_encoder = ble_gap_opt_compat_mode_t_enc; + p_struct = &(p_opt->gap_opt.compat_mode); + break; + default: + SER_ASSERT(NRF_ERROR_INVALID_PARAM,NRF_ERROR_INVALID_PARAM); + break; + } + + SER_PUSH_FIELD(p_struct, fp_encoder); + } + + SER_REQ_ENC_END; +} + + +uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_OPT_SET); +} + +uint32_t ble_tx_packet_count_get_req_enc(uint16_t conn_handle, + uint8_t const * const p_count, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_count, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_tx_packet_count_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_count, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET); + SER_PULL_COND(pp_count, uint8_t_dec); + SER_RSP_DEC_END; +} + +uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle, + ble_user_mem_block_t const * p_block, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_USER_MEM_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_block, ble_user_mem_block_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_USER_MEM_REPLY); +} + + + +uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len, + uint8_t const * const p_uuid_le, + ble_uuid_t * const p_uuid, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_UUID_DECODE); + + SER_PUSH_len8data(p_uuid_le, uuid_le_len); + SER_PUSH_COND(p_uuid, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_uuid_t * * const pp_uuid, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_UUID_DECODE); + SER_PULL_COND(pp_uuid, ble_uuid_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, + uint8_t const * const p_uuid_le_len, + uint8_t const * const p_uuid_le, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_UUID_ENCODE); + + SER_PUSH_COND(p_uuid, ble_uuid_t_enc); + SER_PUSH_COND(p_uuid_le_len, NULL); + SER_PUSH_COND(p_uuid_le, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_uuid_le_len, + uint8_t * const p_uuid_le, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_UUID_ENCODE); + + uint8_t uuid_le_len; + SER_PULL_uint8(&uuid_le_len); + if (p_uuid_le_len) + { + *p_uuid_le_len = uuid_le_len; + if (p_uuid_le) + { + SER_PULL_uint8array(p_uuid_le, uuid_le_len); + } + } + + SER_RSP_DEC_END; +} + +uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid, + uint8_t * const p_uuid_type, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_UUID_VS_ADD); + + SER_PUSH_COND(p_vs_uuid, ble_uuid128_t_enc); + SER_PUSH_COND(p_uuid_type, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_uuid_type, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_UUID_VS_ADD); + + SER_ASSERT_NOT_NULL(pp_uuid_type); + SER_PULL_COND(pp_uuid_type, uint8_t_dec); + + SER_RSP_DEC_END; +} + +uint32_t ble_version_get_req_enc(ble_version_t const * const p_version, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_VERSION_GET); + SER_PUSH_COND(p_version, NULL); + SER_REQ_ENC_END; +} + +uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_version_t * p_version, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_VERSION_GET); + SER_PULL_FIELD(p_version, ble_version_t_dec); + SER_RSP_DEC_END; +} + diff --git a/components/serialization/application/codecs/s130/serializers/ble_app.h b/components/serialization/application/codecs/s132/serializers/ble_app.h similarity index 58% rename from components/serialization/application/codecs/s130/serializers/ble_app.h rename to components/serialization/application/codecs/s132/serializers/ble_app.h index 5bce44c..acb353e 100644 --- a/components/serialization/application/codecs/s130/serializers/ble_app.h +++ b/components/serialization/application/codecs/s132/serializers/ble_app.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_APP_H__ #define BLE_APP_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_app_s130_codecs Application s130 codecs + * @addtogroup ser_app_s130_codecs Application S132 codecs * @ingroup ser_codecs */ @@ -31,37 +60,41 @@ * @brief Application command request encoders and command response decoders. */ #include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif /** - * @brief Encodes @ref sd_ble_tx_buffer_count_get command request. + * @brief Encodes @ref sd_ble_tx_packet_count_get command request. * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format, - * @ref ble_tx_buffer_count_get_rsp_dec for command response decoder. + * @sa @ref ble_tx_packet_count_get_rsp_dec for command response decoder. * + * @param[in] conn_handle Connection handle. * @param[in] p_count Pointer to count value to be filled. * @param[in] p_buf Pointer to buffer where encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * \c out: Length of the encoded command packet. * - * @note \p p_count will not be updated by the command - * request encoder. Updated values are set by @ref ble_tx_buffer_count_get_rsp_dec. + * @note \p p_count will not be updated by the command + * request encoder. Updated values are set by @ref ble_tx_packet_count_get_rsp_dec. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. */ -uint32_t ble_tx_buffer_count_get_req_enc(uint8_t const * const p_count, +uint32_t ble_tx_packet_count_get_req_enc(uint16_t conn_handle, + uint8_t const * const p_count, uint8_t * const p_buf, uint32_t * const p_buf_len); /** - * @brief Decodes response to @ref sd_ble_tx_buffer_count_get command. + * @brief Decodes a response to @ref sd_ble_tx_packet_count_get command. * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format, - * @ref ble_tx_buffer_count_get_req_enc for command request encoder. + * @sa @ref ble_tx_packet_count_get_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_count Pointer to pointer to count value. + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] pp_count Pointer to the pointer to count value. * @param[out] p_result_code Command result code. * * @retval NRF_SUCCESS Decoding success. @@ -70,23 +103,22 @@ uint32_t ble_tx_buffer_count_get_req_enc(uint8_t const * const p_count, * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match * expected operation code. */ -uint32_t ble_tx_buffer_count_get_rsp_dec(uint8_t const * const p_buf, +uint32_t ble_tx_packet_count_get_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, uint8_t * * const pp_count, uint32_t * const p_result_code); -/**@brief Encodes @ref sd_ble_uuid_encode command request. +/**@brief Encodes the @ref sd_ble_uuid_encode command request. * - * @sa @ref nrf51_uuid_encode_encoding for packet format, - * @ref ble_uuid_encode_rsp_dec for command response decoder. + * @sa @ref ble_uuid_encode_rsp_dec for command response decoder. * * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. - * @param[in] p_uuid_le_len Size of \p p_uuid_le if \p p_uuid_le is not NULL + * @param[in] p_uuid_le_len Size of \p p_uuid_le, if \p p_uuid_le is not NULL * @param[in] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes(2 or 16) - * will be stored. Can be NULL to calculate required size. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * will be stored. Can be NULL to calculate the required size. + * @param[in] p_buf Pointer to a buffer where the encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * \c out: Length of the encoded command packet. * * @note \p p_uuid_le_len and \p p_uuid_le will not be updated by the command * request encoder. Updated values are set by @ref ble_uuid_encode_rsp_dec. @@ -101,13 +133,12 @@ uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, uint8_t * const p_buf, uint32_t * const p_buf_len); -/**@brief Decodes response to @ref sd_ble_uuid_encode command. +/**@brief Decodes a response to the @ref sd_ble_uuid_encode command. * - * @sa @ref nrf51_uuid_encode_encoding for packet format, - * @ref ble_uuid_encode_req_enc for command request encoder. + * @sa @ref ble_uuid_encode_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of a response packet. * @param[in,out] p_uuid_le_len \c in: Size (in bytes) of \p p_uuid_le buffer. * \c out: Length of decoded contents of \p p_uuid_le. * @param[out] p_uuid_le Pointer to a buffer where the encoded UUID will be stored. @@ -116,9 +147,9 @@ uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid, * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_DATA_SIZE Length of \p p_uuid_le is too small to hold decoded + * @retval NRF_ERROR_DATA_SIZE Length of \p p_uuid_le is too small to hold the decoded * value from response. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match the expected * operation code. */ uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf, @@ -129,16 +160,15 @@ uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_uuid_decode command request. * - * @sa @ref nrf51_uuid_decode_encoding for packet format, - * @ref ble_uuid_decode_rsp_dec for command response decoder. + * @sa @ref ble_uuid_decode_rsp_dec for command response decoder. * - * @param[in] uuid_le_len Size of \p p_uuid_le if \p p_uuid_le is not NULL + * @param[in] uuid_le_len Size of \p p_uuid_le if \p p_uuid_le is not NULL. * @param[in] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes(2 or 16) - * is stored. - * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure were raw UUID will be decoded. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * are stored. + * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure were the raw UUID will be decoded. + * @param[in] p_buf Pointer to the buffer where encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * \c out: Length of the encoded command packet. * * @note \p p_uuid will not be updated by the command request encoder. * Updated values are set by @ref ble_uuid_decode_rsp_dec. @@ -153,20 +183,19 @@ uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len, uint8_t * const p_buf, uint32_t * const p_buf_len); -/**@brief Decodes response to @ref sd_ble_uuid_decode command. +/**@brief Decodes a response to the @ref sd_ble_uuid_decode command. * - * @sa @ref nrf51_uuid_decode_encoding for packet format, - * @ref ble_uuid_decode_req_enc for command request encoder. + * @sa @ref ble_uuid_decode_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_uuid Pointer to a buffer where the decoded UUID will be stored. + * @param[in] p_buf Pointer to the beginning of command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_uuid Pointer to a buffer where the decoded UUID will be stored. * @param[out] p_result_code Command result code. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match the expected * operation code. */ uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf, @@ -174,14 +203,13 @@ uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf, ble_uuid_t * * const p_uuid, uint32_t * const p_result_code); -/**@brief Encodes @ref sd_ble_uuid_vs_add command request. +/**@brief Encodes the @ref sd_ble_uuid_vs_add command request. * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format, - * @ref ble_uuid_vs_add_rsp_dec for command response decoder. + * @sa @ref ble_uuid_vs_add_rsp_dec for command response decoder. * * @param[in] p_vs_uuid Pointer to a @ref ble_uuid128_t structure. * @param[in] p_uuid_type Pointer to uint8_t where UUID type will be returned. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] p_buf Pointer to buffer where the encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. * \c out: Length of encoded command packet. * @@ -197,13 +225,12 @@ uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid, uint8_t * const p_buf, uint32_t * const p_buf_len); -/**@brief Decodes response to @ref sd_ble_uuid_vs_add command. +/**@brief Decodes response to the @ref sd_ble_uuid_vs_add command. * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format, - * @ref ble_uuid_vs_add_req_enc for command request encoder. + * @sa @ref ble_uuid_vs_add_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] buf_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to the beginning of command response packet. + * @param[in] packet_len Length (in bytes) of a response packet. * @param[out] pp_uuid_type Pointer to a pointer to uint8_t where the decoded UUID type will be stored. * @param[out] p_result_code Command result code. * @@ -214,17 +241,16 @@ uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid, * operation code. */ uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf, - uint32_t buf_len, + uint32_t packet_len, uint8_t * * const pp_uuid_type, uint32_t * const p_result_code); -/**@brief Encodes @ref sd_ble_version_get command request. +/**@brief Encodes the @ref sd_ble_version_get command request. * - * @sa @ref nrf51_version_get_encoding for packet format, - * @ref ble_version_get_rsp_dec for command response decoder. + * @sa @ref ble_version_get_rsp_dec for command response decoder. * * @param[in] p_version Pointer to a @ref ble_version_t structure to be filled by the response. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] p_buf Pointer to a buffer where the encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. * \c out: Length of encoded command packet. * @@ -236,20 +262,19 @@ uint32_t ble_version_get_req_enc(ble_version_t const * const p_version, uint8_t * const p_buf, uint32_t * const p_buf_len); -/**@brief Decodes response to @ref sd_ble_version_get command. +/**@brief Decodes response to the @ref sd_ble_version_get command. * - * @sa @ref nrf51_version_get_encoding for packet format, - * @ref ble_version_get_req_enc for command request encoder. + * @sa @ref ble_version_get_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_version Pointer to a @ref ble_version_t where decoded version will be stored. - * @param[out] p_result_code Command result code. + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_version Pointer to a @ref ble_version_t where the decoded version will be stored. + * @param[out] p_result_code Command result code. * * @return NRF_SUCCESS Version information stored successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. + * hold the decoded event. */ uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, @@ -257,16 +282,15 @@ uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf, uint32_t * const p_result_code); -/**@brief Encodes @ref sd_ble_opt_set command request. +/**@brief Encodes the @ref sd_ble_opt_set command request. * - * @sa @ref nrf51_opt_set_encoding for packet format, - * @ref ble_opt_set_rsp_dec for command response decoder. + * @sa @ref ble_opt_set_rsp_dec for command response decoder. * * @param[in] opt_id Identifies type of parameter in ble_opt_t union. - * @param[in] p_opt Pointer to ble_opt_t union. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] p_opt Pointer to the ble_opt_t union. + * @param[in] p_buf Pointer to a buffer where the encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * \c out: Length of the encoded command packet. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -278,13 +302,12 @@ uint32_t ble_opt_set_req_enc(uint32_t const opt_id, uint8_t * const p_buf, uint32_t * const p_buf_len); -/**@brief Decodes response to @ref sd_ble_opt_set command. +/**@brief Decodes response to the @ref sd_ble_opt_set command. * - * @sa @ref nrf51_opt_set_encoding for packet format, - * @ref ble_opt_set_req_enc for command request encoder. + * @sa @ref ble_opt_set_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. * @param[out] p_result_code Command result code. * * @return NRF_SUCCESS Version information stored successfully. @@ -294,15 +317,14 @@ uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, uint32_t * const p_result_code); -/**@brief Encodes @ref sd_ble_enable command request. +/**@brief Encodes the @ref sd_ble_enable command request. * - * @sa @ref nrf51_enable_encoding for packet format, - * @ref ble_enable_rsp_dec for command response decoder. + * @sa @ref ble_enable_rsp_dec for command response decoder. * - * @param[in] p_ble_enable_params Pointer to a @ref ble_enable_params_t structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * @param[in] p_ble_enable_params Pointer to the @ref ble_enable_params_t structure. + * @param[in] p_buf Pointer to the buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of the encoded command packet. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -312,34 +334,32 @@ uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params, uint8_t * const p_buf, uint32_t * const p_buf_len); -/**@brief Decodes response to @ref sd_ble_enable command. +/**@brief Decodes response to the @ref sd_ble_enable command. * - * @sa @ref nrf51_enable_encoding for packet format, - * @ref ble_enable_req_enc for command request encoder. + * @sa @ref ble_enable_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. * @param[out] p_result_code Command result code. * * @return NRF_SUCCESS Success. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. + * hold the decoded event. */ uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, uint32_t * const p_result_code); - -/**@brief Encodes @ref sd_ble_opt_get command request. + +/**@brief Encodes the @ref sd_ble_opt_get command request. * - * @sa @ref nrf51_opt_get_encoding for packet format, - * @ref ble_opt_get_rsp_dec for command response decoder. + * @sa @ref ble_opt_get_rsp_dec for command response decoder. * - * @param[in] opt_id Identifies type of parameter in ble_opt_t union. - * @param[in] p_opt Pointer to a @ref ble_opt_t union to be filled by the response. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] opt_id Identifies the type of parameter in the ble_opt_t union. + * @param[in] p_opt Pointer to the @ref ble_opt_t union to be filled by the response. + * @param[in] p_buf Pointer to the buffer where the encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * \c out: Length of the encoded command packet. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -351,21 +371,20 @@ uint32_t ble_opt_get_req_enc(uint32_t opt_id, uint8_t * const p_buf, uint32_t * const p_buf_len); -/**@brief Decodes response to @ref sd_ble_opt_get command. +/**@brief Decodes response to the @ref sd_ble_opt_get command. * - * @sa @ref nrf51_opt_get_encoding for packet format, - * @ref ble_opt_get_req_enc for command request encoder. + * @sa @ref ble_opt_get_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_opt_id Pointer to a decoded opt_id - * @param[out] p_opt Pointer to a decoded @ref ble_opt_t union - * @param[out] p_result_code Command result code. + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_opt_id Pointer to the decoded opt_id. + * @param[out] p_opt Pointer to the decoded @ref ble_opt_t union. + * @param[out] p_result_code Command result code. * * @return NRF_SUCCESS Opt stored successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. + * hold the decoded event. * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. */ @@ -375,16 +394,15 @@ uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf, ble_opt_t * const p_opt, uint32_t * const p_result_code); -/**@brief Encodes @ref sd_ble_user_mem_reply command request. +/**@brief Encodes the @ref sd_ble_user_mem_reply command request. * - * @sa @ref nrf51_user_mem_reply_encoding for packet format, - * @ref ble_user_mem_reply_rsp_dec for command response decoder. + * @sa @ref ble_user_mem_reply_rsp_dec for command response decoder. * - * @param[in] conn_handle Connection Handle. - * @param[in] p_block Pointer to a @ref ble_user_mem_block_t structure. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] conn_handle Connection handle. + * @param[in] p_block Pointer to the @ref ble_user_mem_block_t structure. + * @param[in] p_buf Pointer to the buffer where the encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * \c out: Length of the encoded command packet. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -396,19 +414,18 @@ uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle, uint8_t * const p_buf, uint32_t * const p_buf_len); -/**@brief Decodes response to @ref sd_ble_user_mem_reply command. +/**@brief Decodes response to the @ref sd_ble_user_mem_reply command. * - * @sa @ref nrf51_user_mem_reply_encoding for packet format, - * @ref ble_user_mem_reply_req_enc for command request encoder. + * @sa @ref ble_user_mem_reply_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. + * @param[in] p_buf Pointer to the beginning of a command response packet. + * @param[in] packet_len Length (in bytes) of the response packet. + * @param[out] p_result_code Command result code. * * @return NRF_SUCCESS Opt stored successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. + * hold the decoded event. * @retval NRF_ERROR_INVALID_PARAM Invalid opt id. */ uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf, @@ -417,23 +434,23 @@ uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf, /**@brief Event decoding dispatcher. * - * The event decoding dispatcher will route the event packet to the correct decoder which in turn + * The event decoding dispatcher will route the event packet to the correct decoder, which in turn * decodes the contents of the event and updates the \p p_event struct. * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * - * @param[in] p_buf Pointer to beginning of event packet. - * @param[in] packet_len Length (in bytes) of event packet. - * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be - * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. - * \c out: Length of decoded contents of \p p_event. + * \c out: Length of the decoded contents of \p p_event. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to - * hold decoded event. + * hold the decoded event. * @retval NRF_ERROR_NOT_FOUND Decoding failure. No event decoder is available. */ uint32_t ble_event_dec(uint8_t const * const p_buf, @@ -442,4 +459,9 @@ uint32_t ble_event_dec(uint8_t const * const p_buf, uint32_t * const p_event_len); /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/application/codecs/s132/serializers/ble_event.c b/components/serialization/application/codecs/s132/serializers/ble_event.c new file mode 100644 index 0000000..c0ac41f --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_event.c @@ -0,0 +1,255 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_serialization.h" +#include "ble_app.h" +#include "ble_evt_app.h" +#include "ble_gap_evt_app.h" +#include "ble_gattc_evt_app.h" +#include "ble_gatts_evt_app.h" +#include "ble_l2cap_evt_app.h" +#include "app_util.h" + +uint32_t ble_event_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + uint32_t err_code; + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_event_len); + SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE, packet_len); + SER_ASSERT_NOT_NULL(p_event); + SER_ASSERT_LENGTH_LEQ(sizeof (ble_evt_hdr_t), *p_event_len); + *p_event_len -= sizeof (ble_evt_hdr_t); + + const uint16_t event_id = uint16_decode(&p_buf[SER_EVT_ID_POS]); + const uint8_t * p_sub_buffer = &p_buf[SER_EVT_HEADER_SIZE]; + const uint32_t sub_packet_len = packet_len - SER_EVT_HEADER_SIZE; + + uint32_t (*fp_event_decoder)(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) = NULL; + + switch (event_id) + { + case BLE_EVT_TX_COMPLETE: + fp_event_decoder = ble_evt_tx_complete_dec; + break; + + case BLE_EVT_USER_MEM_REQUEST: + fp_event_decoder = ble_evt_user_mem_request_dec; + break; + + case BLE_EVT_USER_MEM_RELEASE: + fp_event_decoder = ble_evt_user_mem_release_dec; + break; + + case BLE_EVT_DATA_LENGTH_CHANGED: + fp_event_decoder = ble_evt_data_length_changed_dec; + break; + + case BLE_GAP_EVT_PASSKEY_DISPLAY: + fp_event_decoder = ble_gap_evt_passkey_display_dec; + break; + + case BLE_GAP_EVT_AUTH_KEY_REQUEST: + fp_event_decoder = ble_gap_evt_auth_key_request_dec; + break; + + case BLE_GAP_EVT_CONN_PARAM_UPDATE: + fp_event_decoder = ble_gap_evt_conn_param_update_dec; + break; + + case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: + fp_event_decoder = ble_gap_evt_conn_param_update_request_dec; + break; + + case BLE_GAP_EVT_CONN_SEC_UPDATE: + fp_event_decoder = ble_gap_evt_conn_sec_update_dec; + break; + + case BLE_GAP_EVT_CONNECTED: + fp_event_decoder = ble_gap_evt_connected_dec; + break; + + case BLE_GAP_EVT_DISCONNECTED: + fp_event_decoder = ble_gap_evt_disconnected_dec; + break; + + case BLE_GAP_EVT_TIMEOUT: + fp_event_decoder = ble_gap_evt_timeout_dec; + break; + + case BLE_GAP_EVT_RSSI_CHANGED: + fp_event_decoder = ble_gap_evt_rssi_changed_dec; + break; + + case BLE_GAP_EVT_SEC_INFO_REQUEST: + fp_event_decoder = ble_gap_evt_sec_info_request_dec; + break; + + case BLE_GAP_EVT_SEC_PARAMS_REQUEST: + fp_event_decoder = ble_gap_evt_sec_params_request_dec; + break; + + case BLE_GAP_EVT_AUTH_STATUS: + fp_event_decoder = ble_gap_evt_auth_status_dec; + break; + + case BLE_GAP_EVT_SEC_REQUEST: + fp_event_decoder = ble_gap_evt_sec_request_dec; + break; + + case BLE_GAP_EVT_KEY_PRESSED: + fp_event_decoder = ble_gap_evt_key_pressed_dec; + break; + + case BLE_GAP_EVT_LESC_DHKEY_REQUEST: + fp_event_decoder = ble_gap_evt_lesc_dhkey_request_dec; + break; + + case BLE_GATTC_EVT_CHAR_DISC_RSP: + fp_event_decoder = ble_gattc_evt_char_disc_rsp_dec; + break; + + case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: + fp_event_decoder = ble_gattc_evt_char_val_by_uuid_read_rsp_dec; + break; + + case BLE_GATTC_EVT_DESC_DISC_RSP: + fp_event_decoder = ble_gattc_evt_desc_disc_rsp_dec; + break; + + case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: + fp_event_decoder = ble_gattc_evt_prim_srvc_disc_rsp_dec; + break; + + case BLE_GATTC_EVT_READ_RSP: + fp_event_decoder = ble_gattc_evt_read_rsp_dec; + break; + + case BLE_GATTC_EVT_HVX: + fp_event_decoder = ble_gattc_evt_hvx_dec; + break; + + case BLE_GATTC_EVT_TIMEOUT: + fp_event_decoder = ble_gattc_evt_timeout_dec; + break; + + case BLE_GATTC_EVT_WRITE_RSP: + fp_event_decoder = ble_gattc_evt_write_rsp_dec; + break; + + case BLE_GATTC_EVT_CHAR_VALS_READ_RSP: + fp_event_decoder = ble_gattc_evt_char_vals_read_rsp_dec; + break; + + case BLE_GATTC_EVT_REL_DISC_RSP: + fp_event_decoder = ble_gattc_evt_rel_disc_rsp_dec; + break; + + case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP: + fp_event_decoder = ble_gattc_evt_attr_info_disc_rsp_dec; + break; + + case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: + fp_event_decoder = ble_gattc_evt_exchange_mtu_rsp_dec; + break; + + case BLE_GATTS_EVT_WRITE: + fp_event_decoder = ble_gatts_evt_write_dec; + break; + + case BLE_GATTS_EVT_TIMEOUT: + fp_event_decoder = ble_gatts_evt_timeout_dec; + break; + + case BLE_GATTS_EVT_SC_CONFIRM: + fp_event_decoder = ble_gatts_evt_sc_confirm_dec; + break; + + case BLE_GATTS_EVT_HVC: + fp_event_decoder = ble_gatts_evt_hvc_dec; + break; + + case BLE_GATTS_EVT_SYS_ATTR_MISSING: + fp_event_decoder = ble_gatts_evt_sys_attr_missing_dec; + break; + + case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: + fp_event_decoder = ble_gatts_evt_rw_authorize_request_dec; + break; + + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + fp_event_decoder = ble_gatts_evt_exchange_mtu_request_dec; + break; + + case BLE_L2CAP_EVT_RX: + fp_event_decoder = ble_l2cap_evt_rx_dec; + break; + + case BLE_GAP_EVT_ADV_REPORT: + fp_event_decoder = ble_gap_evt_adv_report_dec; + break; + + case BLE_GAP_EVT_SCAN_REQ_REPORT: + fp_event_decoder = ble_gap_evt_scan_req_report_dec; + break; + default: + break; + } + + if (fp_event_decoder) + { + err_code = fp_event_decoder(p_sub_buffer, sub_packet_len, p_event, p_event_len); + } + else + { + err_code = NRF_ERROR_NOT_FOUND; + } + + *p_event_len += offsetof(ble_evt_t, evt); + p_event->header.evt_id = (err_code == NRF_SUCCESS) ? event_id : 0; + p_event->header.evt_len = (err_code == NRF_SUCCESS) ? (uint16_t)*p_event_len : 0; + + return err_code; +} diff --git a/components/serialization/application/codecs/s132/serializers/ble_evt_app.c b/components/serialization/application/codecs/s132/serializers/ble_evt_app.c new file mode 100644 index 0000000..c124049 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_evt_app.c @@ -0,0 +1,128 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "ble_evt_app.h" +#include "app_ble_user_mem.h" + + +// Helper definitions for common event type names to be compliant with +// event serialization macros. +#define ble_common_evt_tx_complete_t ble_evt_tx_complete_t +#define ble_common_evt_user_mem_request_t ble_evt_user_mem_request_t +#define ble_common_evt_user_mem_release_t ble_evt_user_mem_release_t +#define ble_common_evt_data_length_changed_t ble_evt_data_length_changed_t + + +extern ser_ble_user_mem_t m_app_user_mem_table[]; + +uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_EVT_USER_MEM_RELEASE, common, user_mem_release); + + SER_PULL_uint16(&p_event->evt.common_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.common_evt.params.user_mem_release.type); + SER_PULL_uint16(&p_event->evt.common_evt.params.user_mem_release.mem_block.len); + + //Set the memory pointer to not-null value. + p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem = (uint8_t *)~0; + SER_PULL_COND(&p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem, NULL); + if (p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem) + { + // Using connection handle find which mem block to release in Application Processor + uint32_t user_mem_table_index; + err_code = app_ble_user_mem_context_find(p_event->evt.common_evt.conn_handle, &user_mem_table_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem = + m_app_user_mem_table[user_mem_table_index].mem_block.p_mem; + } + + // Now user memory context can be released + err_code = app_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_EVT_DEC_END; +} + +uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_EVT_TX_COMPLETE, common, tx_complete); + + SER_PULL_uint16(&p_event->evt.common_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.common_evt.params.tx_complete.count); + + SER_EVT_DEC_END; +} + + +uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_EVT_USER_MEM_REQUEST, common, user_mem_request); + + SER_PULL_uint16(&p_event->evt.common_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.common_evt.params.user_mem_request.type); + + SER_EVT_DEC_END; +} + +uint32_t ble_evt_data_length_changed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_EVT_DATA_LENGTH_CHANGED, common, data_length_changed); + + SER_PULL_uint16(&p_event->evt.common_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.common_evt.params.data_length_changed, ble_evt_data_length_changed_t_dec); + + SER_EVT_DEC_END; +} diff --git a/components/serialization/application/codecs/s132/serializers/ble_evt_app.h b/components/serialization/application/codecs/s132/serializers/ble_evt_app.h new file mode 100644 index 0000000..62a535f --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_evt_app.h @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_EVT_APP_H__ +#define BLE_EVT_APP_H__ + +/** + * @addtogroup ser_codecs Serialization codecs + * @ingroup ble_sdk_lib_serialization + */ + +/** + * @addtogroup ser_app_s130_codecs Application S132 codecs + * @ingroup ser_codecs + */ + +/**@file + * + * @defgroup ble_evt_app Application event decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief Application event decoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Decodes the ble_evt_tx_complete event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer. + * \c out: Length of the decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + */ +uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes the ble_evt_user_mem_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer. + * \c out: Length of the decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + */ +uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes the ble_evt_user_mem_release event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer. + * \c out: Length of the decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + */ +uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes the ble_evt_data_length_changed event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of the event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, the required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer. + * \c out: Length of the decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold the decoded event. + */ +uint32_t ble_evt_data_length_changed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/serialization/application/codecs/s132/serializers/ble_gap_app.c b/components/serialization/application/codecs/s132/serializers/ble_gap_app.c new file mode 100644 index 0000000..4b01237 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_gap_app.c @@ -0,0 +1,852 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gap_app.h" +#include +#include +#include "ble_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "ble_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + + +uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data, + uint8_t dlen, + uint8_t const * const p_sr_data, + uint8_t srdlen, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADV_DATA_SET); + + SER_PUSH_len8data(p_data, dlen); + SER_PUSH_len8data(p_sr_data, srdlen); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADV_DATA_SET); +} + + +uint32_t ble_gap_adv_start_req_enc(ble_gap_adv_params_t const * const p_adv_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADV_START); + SER_PUSH_COND(p_adv_params, ble_gap_adv_params_t_enc); + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADV_START); +} + + +uint32_t ble_gap_adv_stop_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADV_STOP); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADV_STOP); +} + + + +uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_APPEARANCE_GET); + SER_PUSH_COND(p_appearance, NULL); + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_appearance, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_APPEARANCE_GET); + SER_PULL_COND(&p_appearance, uint16_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_APPEARANCE_SET); + SER_PUSH_uint16(&appearance); + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_APPEARANCE_SET); +} + + +uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle, + uint8_t key_type, + uint8_t const * const p_key, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_AUTH_KEY_REPLY); + + uint8_t key_len; + switch (key_type) + { + case BLE_GAP_AUTH_KEY_TYPE_NONE: + key_len = 0; + break; + + case BLE_GAP_AUTH_KEY_TYPE_PASSKEY: + key_len = 6; + break; + + case BLE_GAP_AUTH_KEY_TYPE_OOB: + key_len = 16; + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint8(&key_type); + SER_PUSH_buf(p_key, key_len); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_AUTH_KEY_REPLY); +} + + + +uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle, + ble_gap_sec_params_t const * const p_sec_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_AUTHENTICATE); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_sec_params, ble_gap_sec_params_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_AUTHENTICATE); +} + + +uint32_t ble_gap_conn_param_update_req_enc(uint16_t conn_handle, + ble_gap_conn_params_t const * const p_conn_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONN_PARAM_UPDATE); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_CONN_PARAM_UPDATE); +} + + +uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_handle, + ble_gap_conn_sec_t const * const p_conn_sec, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONN_SEC_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_conn_sec, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_sec_t * * const pp_conn_sec, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_CONN_SEC_GET); + SER_PULL_COND(pp_conn_sec, ble_gap_conn_sec_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr, + ble_gap_scan_params_t const * const p_scan_params, + ble_gap_conn_params_t const * const p_conn_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONNECT); + + SER_PUSH_COND(p_peer_addr, ble_gap_addr_t_enc); + SER_PUSH_COND(p_scan_params, ble_gap_scan_params_t_enc); + SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_CONNECT); +} + + +uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONNECT_CANCEL); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_CONNECT_CANCEL); +} + + +uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name, + uint16_t const * const p_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET); + + SER_PUSH_COND(p_len, uint16_t_enc); + SER_PUSH_COND(p_dev_name, NULL); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_dev_name, + uint16_t * const p_dev_name_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET); + + SER_PULL_COND(&p_dev_name_len, uint16_t_dec); + if (p_dev_name_len) + { + SER_PULL_uint8array(p_dev_name, *p_dev_name_len); + } + + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p_write_perm, + uint8_t const * const p_dev_name, + uint16_t len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_DEVICE_NAME_SET); + + SER_ERROR_CHECK(len <= BLE_GAP_DEVNAME_MAX_LEN, NRF_ERROR_INVALID_PARAM); + + SER_PUSH_COND(p_write_perm, ble_gap_conn_sec_mode_t_enc); + SER_PUSH_len16data(p_dev_name, len); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_DEVICE_NAME_SET); +} + + +uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle, + uint8_t hci_status_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_DISCONNECT); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint8(&hci_status_code); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_DISCONNECT); +} + + +uint32_t ble_gap_encrypt_req_enc(uint16_t conn_handle, + ble_gap_master_id_t const * const p_master_id, + ble_gap_enc_info_t const * const p_enc_info, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ENCRYPT); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_master_id, ble_gap_master_id_t_enc); + SER_PUSH_COND(p_enc_info, ble_gap_enc_info_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ENCRYPT); +} + + +uint32_t ble_gap_keypress_notify_req_enc(uint16_t conn_handle, + uint8_t kp_not, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_KEYPRESS_NOTIFY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint8(&kp_not); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_keypress_notify_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_KEYPRESS_NOTIFY); +} + + +uint32_t ble_gap_lesc_dhkey_reply_req_enc(uint16_t conn_handle, + ble_gap_lesc_dhkey_t const *p_dhkey, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_LESC_DHKEY_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_dhkey, ble_gap_lesc_dhkey_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_lesc_dhkey_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_LESC_DHKEY_REPLY); +} + + +uint32_t ble_gap_lesc_oob_data_get_req_enc(uint16_t conn_handle, + ble_gap_lesc_p256_pk_t const *p_pk_own, + ble_gap_lesc_oob_data_t *p_oobd_own, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_pk_own, ble_gap_lesc_p256_pk_t_enc); + SER_PUSH_COND(p_oobd_own, NULL); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_lesc_oob_data_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_lesc_oob_data_t * *pp_oobd_own, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET); + SER_PULL_COND(pp_oobd_own, ble_gap_lesc_oob_data_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_lesc_oob_data_set_req_enc(uint16_t conn_handle, + ble_gap_lesc_oob_data_t const *p_oobd_own, + ble_gap_lesc_oob_data_t const *p_oobd_peer, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_SET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_oobd_own, ble_gap_lesc_oob_data_t_enc); + SER_PUSH_COND(p_oobd_peer, ble_gap_lesc_oob_data_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_lesc_oob_data_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_LESC_OOB_DATA_SET); +} + + +uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_PPCP_GET); + SER_PUSH_COND(p_conn_params, NULL); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_params_t * const p_conn_params, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_PPCP_GET); + SER_PULL_COND(&p_conn_params, ble_gap_conn_params_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_PPCP_SET); + SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc); + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_PPCP_SET); +} + +uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle, + int8_t const * const p_rssi, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_RSSI_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_rssi, NULL); + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + int8_t * const p_rssi, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_RSSI_GET); + SER_PULL_uint8(p_rssi); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle, + uint8_t threshold_dbm, + uint8_t skip_count, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_RSSI_START); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint8(&threshold_dbm); + SER_PUSH_uint8(&skip_count); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_RSSI_START); +} + + +uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_RSSI_STOP); + SER_PUSH_uint16(&conn_handle); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_RSSI_STOP); +} + + +uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_SCAN_START); + SER_PUSH_COND(p_scan_params, ble_gap_scan_params_t_enc); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_SCAN_START); +} + + +uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_SCAN_STOP); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_SCAN_STOP); +} + + +uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle, + ble_gap_enc_info_t const * p_enc_info, + ble_gap_irk_t const * p_id_info, + ble_gap_sign_info_t const * p_sign_info, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_SEC_INFO_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_enc_info, ble_gap_enc_info_t_enc); + SER_PUSH_COND(p_id_info, ble_gap_irk_t_enc); + SER_PUSH_COND(p_sign_info, ble_gap_sign_info_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_SEC_INFO_REPLY); +} + + +uint32_t ble_gap_sec_params_reply_req_enc(uint16_t conn_handle, + uint8_t sec_status, + ble_gap_sec_params_t const * const p_sec_params, + ble_gap_sec_keyset_t const * const p_sec_keyset, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint8(&sec_status); + SER_PUSH_COND(p_sec_params, ble_gap_sec_params_t_enc); + SER_PUSH_COND(p_sec_keyset, ble_gap_sec_keyset_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_sec_keyset_t const * const p_sec_keyset, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY); + SER_PULL_COND(&p_sec_keyset, ble_gap_sec_keyset_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gap_tx_power_set_req_enc(int8_t tx_power, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_TX_POWER_SET); + SER_PUSH_int8(&tx_power); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_TX_POWER_SET); +} + +uint32_t ble_gap_addr_get_req_enc(ble_gap_addr_t const * const p_address, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADDR_GET); + SER_PUSH_COND(p_address, NULL); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_addr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * const p_address, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_ADDR_GET); + SER_PULL_FIELD(p_address, ble_gap_addr_t_dec); + SER_RSP_DEC_END; +} + +uint32_t ble_gap_addr_set_req_enc(ble_gap_addr_t const * const p_addr, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADDR_SET); + SER_PUSH_COND(p_addr, ble_gap_addr_t_enc); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_addr_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADDR_SET); +} + +uint32_t ble_gap_privacy_set_req_enc(ble_gap_privacy_params_t const * p_privacy_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_PRIVACY_SET); + SER_PUSH_COND(p_privacy_params, ble_gap_privacy_params_t_enc); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_privacy_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_PRIVACY_SET); +} + + +uint32_t ble_gap_privacy_get_req_enc(ble_gap_privacy_params_t const * const p_privacy_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_PRIVACY_GET); + SER_PUSH_COND(p_privacy_params, ble_gap_privacy_params_t_enc); + SER_REQ_ENC_END; +} + +uint32_t ble_gap_privacy_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_privacy_params_t const * const p_privacy_params, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GAP_PRIVACY_GET); + SER_PULL_COND((void **)&p_privacy_params, ble_gap_privacy_params_t_dec); + SER_RSP_DEC_END; +} + +uint32_t ble_gap_whitelist_set_req_enc(ble_gap_addr_t const * const * const pp_wl_addrs, + uint8_t const len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_WHITELIST_SET); + + uint8_t presence; + SER_PUSH_uint8(&len); + + if (pp_wl_addrs) + { + presence = SER_FIELD_PRESENT; + SER_PUSH_uint8(&presence); + + for (uint32_t i = 0; i < len; ++i) + { + SER_PUSH_COND(pp_wl_addrs[i], ble_gap_addr_t_enc); + } + } + else + { + presence = SER_FIELD_NOT_PRESENT; + SER_PUSH_uint8(&presence); + } + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_whitelist_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_WHITELIST_SET); +} + +uint32_t ble_gap_device_identities_set_req_enc(ble_gap_id_key_t const * const * const pp_id_keys, + ble_gap_irk_t const * const * const pp_local_irks, + uint8_t const len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GAP_DEVICE_IDENTITIES_SET); + uint8_t presence; + SER_PUSH_uint8(&len); + + if (pp_id_keys) + { + presence = SER_FIELD_PRESENT; + SER_PUSH_uint8(&presence); + + for (uint32_t i = 0; i < len; ++i) + { + SER_PUSH_COND(pp_id_keys[i], ble_gap_id_key_t_enc); + } + } + else + { + presence = SER_FIELD_NOT_PRESENT; + SER_PUSH_uint8(&presence); + } + + if (pp_local_irks) + { + presence = SER_FIELD_PRESENT; + SER_PUSH_uint8(&presence); + + for (uint32_t i = 0; i < len; ++i) + { + SER_PUSH_COND(pp_local_irks[i], ble_gap_irk_t_enc); + } + } + else + { + presence = SER_FIELD_NOT_PRESENT; + SER_PUSH_uint8(&presence); + } + + SER_REQ_ENC_END; +} + +uint32_t ble_gap_device_identities_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_DEVICE_IDENTITIES_SET); +} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_app.h b/components/serialization/application/codecs/s132/serializers/ble_gap_app.h similarity index 63% rename from components/serialization/application/codecs/s130/serializers/ble_gap_app.h rename to components/serialization/application/codecs/s132/serializers/ble_gap_app.h index 56b936a..2c7c6dd 100644 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_app.h +++ b/components/serialization/application/codecs/s132/serializers/ble_gap_app.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GAP_APP_H__ #define BLE_GAP_APP_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_app_s130_codecs Application s130 codecs + * @addtogroup ser_app_s130_codecs Application S132 codecs * @ingroup ser_codecs */ @@ -33,96 +62,14 @@ #include "ble.h" #include "ble_gap.h" -/** - * @brief Encodes @ref sd_ble_gap_address_get command request. - * - * @sa @ref nrf51_address_get_encoding for packet format, - * @ref ble_gap_address_get_rsp_dec for command response decoder. - * - * @param[in] p_address Pointer to address. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @note \p p_address will not be updated by the command - * request encoder. Updated values are set by @ref ble_gap_address_get_rsp_dec. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_get_req_enc(ble_gap_addr_t const * const p_address, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_address_get command. - * - * @sa @ref nrf51_address_get_encoding for packet format, - * @ref ble_gap_address_get_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_address Pointer to address. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_address_get_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * const p_address, - uint32_t * const p_result_code); - -/** - * @brief Encodes @ref sd_ble_gap_address_set command request. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format, - * @ref ble_gap_address_set_rsp_dec for command response decoder. - * - * @param[in] addr_cycle_mode Address cycle mode. - * @param[in] p_addr Pointer to address structure. - * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_set_req_enc(uint8_t addr_cycle_mode, - ble_gap_addr_t const * const p_addr, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Decodes response to @ref sd_ble_gap_address_set command. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format, - * @ref ble_gap_address_set_req_enc for command request encoder. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_result_code Command result code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match - * expected operation code. - */ -uint32_t ble_gap_address_set_rsp_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint32_t * const p_result_code); +#ifdef __cplusplus +extern "C" { +#endif /** * @brief Encodes @ref sd_ble_gap_adv_data_set command request. * - * @sa @ref nrf51_adv_set_encoding for packet format, - * @ref ble_gap_adv_data_set_rsp_dec for command response decoder. + * @sa @ref ble_gap_adv_data_set_rsp_dec for command response decoder. * * @param[in] p_data Raw data to be placed in advertisement packet. If NULL, no changes * are made to the current advertisement packet data. @@ -150,8 +97,7 @@ uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data, /** * @brief Decodes response to @ref sd_ble_gap_adv_data_set command. * - * @sa @ref nrf51_adv_set_encoding for packet format, - * @ref ble_gap_adv_data_set_req_enc for command request encoder. + * @sa @ref ble_gap_adv_data_set_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -170,8 +116,7 @@ uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf, /** * @brief Encodes @ref sd_ble_gap_adv_start command request. * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_gap_adv_start_rsp_dec for command response decoder. + * @sa @ref ble_gap_adv_start_rsp_dec for command response decoder. * * @param[in] p_adv_params Pointer to advertising parameters structure. * @param[in] p_buf Pointer to buffer where encoded data command will be returned. @@ -189,8 +134,7 @@ uint32_t ble_gap_adv_start_req_enc(ble_gap_adv_params_t const * const p_adv_para /** * @brief Decodes response to @ref sd_ble_gap_adv_start command. * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_gap_adv_start_req_enc for command request encoder. + * @sa @ref ble_gap_adv_start_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -209,8 +153,7 @@ uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf, /** * @brief Encodes @ref sd_ble_gap_tx_power_set command request. * - * @sa @ref nrf51_tx_power_set_encoding for packet format, - * @ref ble_gap_tx_power_set_rsp_dec for command response decoder. + * @sa @ref ble_gap_tx_power_set_rsp_dec for command response decoder. * * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm). * @param[in] p_buf Pointer to buffer where encoded data command will be returned. @@ -228,8 +171,7 @@ uint32_t ble_gap_tx_power_set_req_enc(int8_t tx_power, /** * @brief Decodes response to @ref sd_ble_gap_tx_power_set command. * - * @sa @ref nrf51_tx_power_set_encoding for packet format, - * @ref ble_gap_tx_power_set_req_enc for command request encoder. + * @sa @ref ble_gap_tx_power_set_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -248,15 +190,14 @@ uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf, /** * @brief Encodes @ref sd_ble_gap_appearance_get command request. * - * @sa @ref nrf51_appearance_get_encoding for packet format, - * @ref ble_gap_appearance_get_rsp_dec for command response decoder. + * @sa @ref ble_gap_appearance_get_rsp_dec for command response decoder. * - * @param[in] p_appearance Appearance (16-bit), see @ref BLE_APPEARANCES + * @param[in] p_appearance Appearance (16 bit), see @ref BLE_APPEARANCES. * @param[in] p_buf Pointer to buffer where encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. * \c out: Length of encoded command packet. * - * @note \p p_appearance will not be updated by the command + * @note \p p_appearance will not be updated by the command * request encoder. Updated values are set by @ref ble_gap_appearance_get_rsp_dec. * * @retval NRF_SUCCESS Encoding success. @@ -270,12 +211,11 @@ uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance, /** * @brief Decodes response to @ref sd_ble_gap_appearance_get command. * - * @sa @ref nrf51_appearance_get_encoding for packet format, - * @ref ble_gap_appearance_get_req_enc for command request encoder. + * @sa @ref ble_gap_appearance_get_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_appearance Appearance (16-bit), see @ref BLE_APPEARANCES. + * @param[out] p_appearance Appearance (16 bit), see @ref BLE_APPEARANCES. * @param[out] p_result_code Command result code. * * @retval NRF_SUCCESS Decoding success. @@ -292,10 +232,9 @@ uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf, /** * @brief Encodes @ref sd_ble_gap_appearance_set command request. * - * @sa @ref nrf51_appearance_set_encoding for packet format, - * @ref ble_gap_appearance_set_rsp_dec for command response decoder. + * @sa @ref ble_gap_appearance_set_rsp_dec for command response decoder. * - * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. + * @param[in] appearance Appearance (16 bit), see @ref BLE_APPEARANCES. * @param[in] p_buf Pointer to buffer where encoded data command will be returned. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. * \c out: Length of encoded command packet. @@ -311,8 +250,7 @@ uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance, /** * @brief Decodes response to @ref sd_ble_gap_appearance_set command. * - * @sa @ref nrf51_appearance_set_encoding for packet format, - * @ref ble_gap_appearance_set_req_enc for command request encoder. + * @sa @ref ble_gap_appearance_set_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -331,16 +269,15 @@ uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf, /** * @brief Encodes @ref sd_ble_gap_device_name_get command request. * - * @sa @ref nrf51_device_name_get_encoding for packet format, - * @ref ble_gap_device_name_get_rsp_dec for command response decoder. + * @sa @ref ble_gap_device_name_get_rsp_dec for command response decoder. * - * @param[in] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated - * string will be placed. Set to NULL to obtain the complete device - * name length. - * @param[in] p_dev_name_len Length of the buffer pointed by p_dev_name. - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * @param[in] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated + * string will be placed. Set to NULL to obtain the complete device + * name length. + * @param[in] p_dev_name_len Length of the buffer pointed by p_dev_name. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. * * @note \p p_dev_name and \p p_len will not be updated by the command * request encoder. Updated values are set by @ref ble_gap_device_name_get_rsp_dec. @@ -357,16 +294,15 @@ uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name, /** * @brief Decodes response to @ref sd_ble_gap_device_name_get command. * - * @sa @ref nrf51_device_name_get_encoding for packet format, - * @ref ble_gap_device_name_get_req_enc for command request encoder. + * @sa @ref ble_gap_device_name_get_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 - * non NULL-terminated string will be placed. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 + * non NULL-terminated string will be placed. * @param[in,out] p_dev_name_len Length of the buffer pointed by p_dev_name, complete device name - * length on output. - * @param[out] p_result_code Command result code. + * length on output. + * @param[out] p_result_code Command result code. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. @@ -383,10 +319,9 @@ uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf, /** * @brief Encodes @ref sd_ble_gap_device_name_set command request. * - * @sa @ref nrf51_device_name_set_encoding for packet format, - * @ref ble_gap_device_name_set_rsp_dec for command response decoder. + * @sa @ref ble_gap_device_name_set_rsp_dec for command response decoder. * - * @param[in] p_write_perm Write permissions for the Device Name characteristic see + * @param[in] p_write_perm Write permissions for the Device Name characteristic, see * @ref ble_gap_conn_sec_mode_t. * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. * @param[in] len Length of the UTF-8, non NULL-terminated string pointed @@ -409,8 +344,7 @@ uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p /** * @brief Decodes response to @ref sd_ble_gap_device_name_set command. * - * @sa @ref nrf51_device_name_set_encoding for packet format, - * @ref ble_gap_device_name_set_req_enc for command request encoder. + * @sa @ref ble_gap_device_name_set_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -429,8 +363,7 @@ uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf, /** * @brief Encodes @ref sd_ble_gap_ppcp_set command request. * - * @sa @ref nrf51_ppcp_set_encoding for packet format, - * @ref ble_gap_ppcp_set_rsp_dec for command response decoder. + * @sa @ref ble_gap_ppcp_set_rsp_dec for command response decoder. * * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the * desired parameters. @@ -449,8 +382,7 @@ uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_par /** * @brief Decodes response to @ref sd_ble_gap_ppcp_set command. * - * @sa @ref nrf51_ppcp_set_encoding for packet format, - * @ref ble_gap_ppcp_set_req_enc for command request encoder. + * @sa @ref ble_gap_ppcp_set_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -468,11 +400,10 @@ uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_conn_param_update command request. * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format, - * @ref ble_gap_conn_param_update_rsp_dec for command response decoder. + * @sa @ref ble_gap_conn_param_update_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. - * @param[in] p_conn_params Pointer to desired connection parameters.. + * @param[in] p_conn_params Pointer to desired connection parameters. * @param[in] p_buf Pointer to buffer where encoded data command will be returned. * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. * \c out: Length of encoded command packet. @@ -488,11 +419,10 @@ uint32_t ble_gap_conn_param_update_req_enc(uint16_t c /**@brief Decodes response to @ref sd_ble_gap_conn_param_update command. * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format, - * @ref ble_gap_conn_param_update_req_enc for command request encoder. + * @sa @ref ble_gap_conn_param_update_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -507,8 +437,7 @@ uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_disconnect command request. * - * @sa @ref nrf51_disconnect_encoding for packet format, - * @ref ble_gap_disconnect_rsp_dec for command response decoder. + * @sa @ref ble_gap_disconnect_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES. @@ -527,11 +456,10 @@ uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gap_disconnect command. * - * @sa @ref nrf51_disconnect_encoding for packet format, - * @ref ble_gap_disconnect_req_enc for command request encoder. + * @sa @ref ble_gap_disconnect_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -547,8 +475,7 @@ uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_rssi_stop command request. * - * @sa @ref nrf51_rssi_stop_encoding for packet format, - * @ref ble_gap_rssi_stop_rsp_dec for command response decoder. + * @sa @ref ble_gap_rssi_stop_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_buf Pointer to buffer where encoded data command will be returned. @@ -565,11 +492,10 @@ uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gap_rssi_stop command. * - * @sa @ref nrf51_rssi_stop_encoding for packet format, - * @ref ble_gap_rssi_stop_rsp_dec for command response decoder. + * @sa @ref ble_gap_rssi_stop_rsp_dec for command response decoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -587,8 +513,7 @@ uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_ppcp_get command request. * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format, - * @ref ble_gap_ppcp_get_rsp_dec for command response decoder. + * @sa @ref ble_gap_ppcp_get_rsp_dec for command response decoder. * * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the * parameters will be stored. @@ -609,13 +534,12 @@ uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_par /**@brief Decodes response to @ref sd_ble_gap_ppcp_get command. * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format, - * @ref ble_gap_ppcp_get_req_enc for command request encoder. + * @sa @ref ble_gap_ppcp_get_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters - * will be stored. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters + * will be stored. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -631,8 +555,7 @@ uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_auth_key_reply command request. * - * @sa @ref nrf51_auth_key_reply_encoding for packet format, - * @ref ble_gap_auth_key_reply_rsp_dec for command response decoder. + * @sa @ref ble_gap_auth_key_reply_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] key_type Key type which defines length of key data as defined for @@ -655,11 +578,10 @@ uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gap_auth_key_reply command. * - * @sa @ref nrf51_auth_key_reply_encoding for packet format, - * @ref ble_gap_auth_key_reply_req_enc for command request encoder. + * @sa @ref ble_gap_auth_key_reply_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -674,8 +596,7 @@ uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_sec_info_reply command request. * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format, - * @ref ble_gap_sec_info_reply_rsp_dec for command response decoder. + * @sa @ref ble_gap_sec_info_reply_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information @@ -694,18 +615,17 @@ uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf, */ uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle, ble_gap_enc_info_t const * p_enc_info, - ble_gap_irk_t const * p_id_info, + ble_gap_irk_t const * p_id_info, ble_gap_sign_info_t const * p_sign_info, uint8_t * const p_buf, uint32_t * const p_buf_len); /**@brief Decodes response to @ref sd_ble_gap_sec_info_reply command. * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format, - * @ref ble_gap_sec_info_reply_req_enc for command request encoder. + * @sa @ref ble_gap_sec_info_reply_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -720,8 +640,7 @@ uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_sec_params_reply command request. * - * @sa @ref nrf51_sec_params_reply_encoding for packet format, - * @ref ble_gap_sec_params_reply_rsp_dec for command response decoder. + * @sa @ref ble_gap_sec_params_reply_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. @@ -746,12 +665,11 @@ uint32_t ble_gap_sec_params_reply_req_enc(uint16_t con /**@brief Decodes response to @ref sd_ble_gap_sec_params_reply command. * - * @sa @ref nrf51_sec_params_reply_encoding for packet format, - * @ref ble_gap_sec_params_reply_req_enc for command request encoder. + * @sa @ref ble_gap_sec_params_reply_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] p_sec_keyset Pointer to @ref ble_gap_sec_keyset_t security keys + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_sec_keyset Pointer to @ref ble_gap_sec_keyset_t security keys * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -767,8 +685,7 @@ uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_authenticate command request. * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format, - * @ref ble_gap_authenticate_rsp_dec for command response decoder. + * @sa @ref ble_gap_authenticate_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters @@ -788,11 +705,10 @@ uint32_t ble_gap_authenticate_req_enc(uint16_t conn_ha /**@brief Decodes response to @ref sd_ble_gap_authenticate command. * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format, - * @ref ble_gap_authenticate_req_enc for command request encoder. + * @sa @ref ble_gap_authenticate_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -807,8 +723,7 @@ uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_adv_stop command request. * - * @sa @ref nrf51_sd_ble_gap_adv_stop for packet format, - * @ref ble_gap_adv_stop_rsp_dec for command response decoder. + * @sa @ref ble_gap_adv_stop_rsp_dec for command response decoder. * * @param[in] p_buf Pointer to buffer where encoded data command will be returned. * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. @@ -822,11 +737,10 @@ uint32_t ble_gap_adv_stop_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_ /**@brief Decodes response to @ref sd_ble_gap_adv_stop command. * - * @sa @ref nrf51_sd_ble_gap_adv_stop for packet format, - * @ref ble_gap_adv_stop_req_enc for command request encoder. + * @sa @ref ble_gap_adv_stop_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -841,8 +755,7 @@ uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_conn_sec_get command request. * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format, - * @ref ble_gap_conn_sec_get_rsp_dec for command response decoder. + * @sa @ref ble_gap_conn_sec_get_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_conn_sec Pointer to \ref ble_gap_conn_sec_t which will be filled in @@ -862,13 +775,12 @@ uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_hand /**@brief Decodes response to @ref sd_ble_gap_conn_sec_get command. * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format, - * @ref ble_gap_conn_sec_get_req_enc for command request encoder. + * @sa @ref ble_gap_conn_sec_get_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_conn_sec Pointer to pointer to \ref ble_gap_conn_sec_t which will be filled by - * the decoded data (if present). + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_conn_sec Pointer to pointer to \ref ble_gap_conn_sec_t which will be filled by + * the decoded data (if present). * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -884,8 +796,7 @@ uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_rssi_start command request. * - * @sa @ref nrf51_rssi_start_encoding for packet format, - * @ref ble_gap_rssi_start_rsp_dec for command response decoder. + * @sa @ref ble_gap_rssi_start_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] threshold_dbm Threshold in dBm. @@ -906,11 +817,10 @@ uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gap_rssi_start command. * - * @sa @ref nrf51_rssi_start_encoding for packet format, - * @ref ble_gap_rssi_start_req_enc for command request encoder. + * @sa @ref ble_gap_rssi_start_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -925,8 +835,7 @@ uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_scan_stop command request. * - * @sa @ref nrf51_scan_stop_encoding for packet format, - * @ref ble_gap_scan_stop_rsp_dec for command response decoder. + * @sa @ref ble_gap_scan_stop_rsp_dec for command response decoder. * * @param[in] p_buf Pointer to buffer where encoded data command will be returned. * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. @@ -940,11 +849,10 @@ uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf, uint32_t * const p_buf /**@brief Decodes response to @ref sd_ble_gap_scan_stop command. * - * @sa @ref nrf51_scan_stop_encoding for packet format, - * @ref ble_gap_scan_stop_req_enc for command request encoder. + * @sa @ref ble_gap_scan_stop_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -959,8 +867,7 @@ uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_scan_start command request. * - * @sa @ref nrf51_scan_start_encoding for packet format, - * @ref ble_gap_scan_start_rsp_dec for command response decoder. + * @sa @ref ble_gap_scan_start_rsp_dec for command response decoder. * * @param[in] p_scan_params Pointer to scan params structure. * @param[in] p_buf Pointer to buffer where encoded data command will be returned. @@ -977,11 +884,10 @@ uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params /**@brief Decodes response to @ref sd_ble_gap_scan_start command. * - * @sa @ref nrf51_scan_start_encoding for packet format, - * @ref ble_gap_scan_start_req_enc for command request encoder. + * @sa @ref ble_gap_scan_start_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -996,8 +902,7 @@ uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_connect command request. * - * @sa @ref nrf51_connect_encoding for packet format, - * @ref ble_gap_connect_rsp_dec for command response decoder. + * @sa @ref ble_gap_connect_rsp_dec for command response decoder. * * @param[in] p_peer_addr Pointer to peer address. * @param[in] p_scan_params Pointer to scan params structure. @@ -1018,11 +923,10 @@ uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr /**@brief Decodes response to @ref sd_ble_gap_connect command. * - * @sa @ref nrf51_connect_encoding for packet format, - * @ref ble_gap_connect_req_enc for command request encoder. + * @sa @ref ble_gap_connect_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -1037,8 +941,7 @@ uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_connect_cancel command request. * - * @sa @ref nrf51_connect_cancel_encoding for packet format, - * @ref ble_gap_connect_cancel_rsp_dec for command response decoder. + * @sa @ref ble_gap_connect_cancel_rsp_dec for command response decoder. * * @param[in] p_buf Pointer to buffer where encoded data command will be returned. * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. @@ -1053,11 +956,10 @@ uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf, /**@brief Decodes response to @ref sd_ble_gap_connect_cancel command. * - * @sa @ref nrf51_connect_cancel_encoding for packet format, - * @ref ble_gap_connect_cancel_req_enc for command request encoder. + * @sa @ref ble_gap_connect_cancel_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -1073,8 +975,7 @@ uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_encrypt command request. * - * @sa @ref nrf51_gap_encrypt_encoding for packet format, - * @ref ble_gap_encrypt_rsp_dec for command response decoder. + * @sa @ref ble_gap_encrypt_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle. * @param[in] p_master_id Pointer to a master identification structure. @@ -1088,20 +989,19 @@ uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf, * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. */ -uint32_t ble_gap_encrypt_req_enc( uint16_t conn_handle, - ble_gap_master_id_t const * const p_master_id, - ble_gap_enc_info_t const * const p_enc_info, - uint8_t * const p_buf, - uint32_t * const p_buf_len); +uint32_t ble_gap_encrypt_req_enc(uint16_t conn_handle, + ble_gap_master_id_t const * const p_master_id, + ble_gap_enc_info_t const * const p_enc_info, + uint8_t * const p_buf, + uint32_t * const p_buf_len); /**@brief Decodes response to @ref sd_ble_gap_encrypt command. * - * @sa @ref nrf51_gap_encrypt_encoding for packet format, - * @ref ble_gap_encrypt_req_enc for command request encoder. + * @sa @ref ble_gap_encrypt_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -1116,11 +1016,10 @@ uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_rssi_get command request. * - * @sa @ref nrf51_rssi_get_encoding for packet format, - * @ref ble_gap_rssi_get_rsp_dec for command response decoder. + * @sa @ref ble_gap_rssi_get_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle. - * @param[in] p_rssi Pointer to the rssi value. + * @param[in] p_rssi Pointer to the RSSI value. * @param[in] p_buf Pointer to buffer where encoded data command will be returned. * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. * \c out: Length of encoded command packet. @@ -1136,12 +1035,11 @@ uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gap_rssi_get command. * - * @sa @ref nrf51_rssi_get_encoding for packet format, - * @ref ble_gap_rssi_get_req_enc for command request encoder. + * @sa @ref ble_gap_rssi_get_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_rssi Pointer to rssi value. + * @param[out] p_rssi Pointer to RSSI value. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -1155,5 +1053,398 @@ uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf, int8_t * const p_rssi, uint32_t * const p_result_code); +/**@brief Encodes @ref sd_ble_gap_keypress_notify command request. + * + * @sa @ref ble_gap_keypress_notify_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] kp_not See @ref sd_ble_gap_keypress_notify. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_keypress_notify_req_enc(uint16_t conn_handle, + uint8_t kp_not, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_keypress_notify command. + * + * @sa @ref ble_gap_keypress_notify_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_keypress_notify_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_lesc_dhkey_reply command request. + * + * @sa @ref ble_gap_lesc_dhkey_reply_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dhkey See @ref sd_ble_gap_lesc_dhkey_reply. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_dhkey_reply_req_enc(uint16_t conn_handle, + ble_gap_lesc_dhkey_t const *p_dhkey, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_lesc_dhkey_reply command. + * + * @sa @ref ble_gap_lesc_dhkey_reply_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_lesc_dhkey_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_set command request. + * + * @sa @ref ble_gap_lesc_oob_data_set_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_oobd_own See @ref sd_ble_gap_lesc_oob_data_set. + * @param[in] p_oobd_peer See @ref sd_ble_gap_lesc_oob_data_set. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_oob_data_set_req_enc(uint16_t conn_handle, + ble_gap_lesc_oob_data_t const *p_oobd_own, + ble_gap_lesc_oob_data_t const *p_oobd_peer, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_lesc_oob_data_set command. + * + * @sa @ref ble_gap_lesc_oob_data_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_lesc_oob_data_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_get command request. + * + * @sa @ref ble_gap_lesc_oob_data_get_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] p_pk_own See @ref sd_ble_gap_lesc_oob_data_get. + * @param[in] p_oobd_own See @ref sd_ble_gap_lesc_oob_data_get. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_oob_data_get_req_enc(uint16_t conn_handle, + ble_gap_lesc_p256_pk_t const *p_pk_own, + ble_gap_lesc_oob_data_t *p_oobd_own, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gap_lesc_oob_data_get command. + * + * @sa @ref ble_gap_lesc_oob_data_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_oobd_own Pointer to pointer to location where OOB data is decoded. + * @param[out] p_result_code Command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gap_lesc_oob_data_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_lesc_oob_data_t * *pp_oobd_own, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_addr_get command request. + * + * @sa @ref ble_gap_addr_get_rsp_dec for command response decoder. + * + * @param[in] p_address Pointer to address. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @note \p p_address will not be updated by the command + * request encoder. Updated values are set by @ref ble_gap_addr_get_rsp_dec. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_addr_get_req_enc(ble_gap_addr_t const * const p_address, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_addr_get command. + * + * @sa @ref ble_gap_addr_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_address Pointer to address. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_addr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * const p_address, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_addr_set command request. + * + * @sa @ref ble_gap_addr_set_rsp_dec for command response decoder. + * + * @param[in] p_addr Pointer to address structure. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_addr_set_req_enc(ble_gap_addr_t const * const p_addr, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_addr_set command. + * + * @sa @ref ble_gap_addr_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_addr_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_privacy_set command request. + * + * @sa @ref ble_gap_privacy_set_rsp_dec for command response decoder. + * + * @param[in] p_privacy_params Pointer to privacy settings structure. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_set_req_enc(ble_gap_privacy_params_t const * p_privacy_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_privacy_set command. + * + * @sa @ref ble_gap_privacy_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_privacy_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_privacy_get command request. + * + * @sa @ref ble_gap_privacy_get_rsp_dec for command response decoder. + * + * @param[in] p_privacy_params Pointer to privacy settings structure. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_get_req_enc(ble_gap_privacy_params_t const * const p_privacy_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_privacy_get command. + * + * @sa @ref ble_gap_privacy_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_privacy_params Pointer to privacy settings structure. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_privacy_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_privacy_params_t const * const p_privacy_params, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_whitelist_set command request. + * + * @sa @ref ble_gap_whitelist_set_rsp_dec for command response decoder. + * + * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses. + * @param[out] len Pointer to a length of the whitelist. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_whitelist_set_req_enc(ble_gap_addr_t const * const * const pp_wl_addrs, + uint8_t const len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Decodes response to @ref sd_ble_gap_whitelist_set command. + * + * @sa @ref ble_gap_whitelist_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_whitelist_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/** + * @brief Encodes @ref sd_ble_gap_device_identities_set command request. + * + * @sa @ref ble_gap_device_identities_set_rsp_dec for command response decoder. + * + * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs. + * @param[in] pp_local_irks Pointer to an array of local IRKs. + * @param[out] len Pointer to a length of the device identity list. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_identities_set_req_enc(ble_gap_id_key_t const * const * const pp_id_keys, + ble_gap_irk_t const * const * const pp_local_irks, + uint8_t const len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); +/** + * @brief Decodes response to @ref sd_ble_gap_device_identities_set command. + * + * @sa @ref ble_gap_device_identities_set_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gap_device_identities_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/application/codecs/s132/serializers/ble_gap_evt_app.c b/components/serialization/application/codecs/s132/serializers/ble_gap_evt_app.c new file mode 100644 index 0000000..465d407 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_gap_evt_app.c @@ -0,0 +1,312 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gap_evt_app.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "app_ble_gap_sec_keys.h" +#include "ble_gap_struct_serialization.h" +#include "cond_field_serialization.h" +#include + +extern ser_ble_gap_app_keyset_t m_app_keys_table[]; + + +uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_ADV_REPORT, gap, adv_report); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.adv_report, ble_gap_evt_adv_report_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_AUTH_KEY_REQUEST, gap, auth_key_request); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.gap_evt.params.auth_key_request.key_type); + + SER_EVT_DEC_END; +} + + +extern ser_ble_gap_app_keyset_t m_app_keys_table[]; + +uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_AUTH_STATUS, gap, auth_status); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.auth_status, ble_gap_evt_auth_status_t_dec); + + // keyset is an extension of standard event data - used to synchronize keys at application + uint32_t conn_index; + err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); + if (err_code == NRF_SUCCESS) + { + SER_PULL_FIELD(&(m_app_keys_table[conn_index].keyset), ble_gap_sec_keyset_t_dec); + + err_code = app_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE, gap, conn_param_update); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.conn_param_update, ble_gap_evt_conn_param_update_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, gap, conn_param_update_request); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.conn_param_update_request, + ble_gap_evt_conn_param_update_request_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, gap, conn_sec_update); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.conn_sec_update, ble_gap_evt_conn_sec_update_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONNECTED, gap, connected); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.connected, ble_gap_evt_connected_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_DISCONNECTED, gap, disconnected); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.disconnected, ble_gap_evt_disconnected_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_key_pressed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_KEY_PRESSED, gap, key_pressed); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.gap_evt.params.key_pressed.kp_not); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_lesc_dhkey_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_LESC_DHKEY_REQUEST, gap, lesc_dhkey_request); + + uint8_t ser_data; + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + + // keyset is an extension of standard event data - used to synchronize keys at application + uint32_t conn_index; + err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer = m_app_keys_table[conn_index].keyset.keys_peer.p_pk; + SER_PULL_COND(&p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer, ble_gap_lesc_p256_pk_t_dec); + + SER_PULL_uint8(&ser_data); + p_event->evt.gap_evt.params.lesc_dhkey_request.oobd_req = ser_data & 0x01; + + SER_EVT_DEC_END; +} + + +#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey) + + +uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_PASSKEY_DISPLAY, gap, passkey_display); + + uint8_t ser_data; + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_uint8array(p_event->evt.gap_evt.params.passkey_display.passkey, BLE_GAP_PASSKEY_LEN); + SER_PULL_uint8(&ser_data); + p_event->evt.gap_evt.params.passkey_display.match_request = (ser_data & 0x01); + + SER_EVT_DEC_END; +} + + + +uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_RSSI_CHANGED, gap, rssi_changed); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_int8(&p_event->evt.gap_evt.params.rssi_changed.rssi); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SCAN_REQ_REPORT, gap, scan_req_report); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.scan_req_report.peer_addr, ble_gap_addr_t_dec); + SER_PULL_int8(&p_event->evt.gap_evt.params.scan_req_report.rssi); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SEC_INFO_REQUEST, gap, sec_info_request); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.sec_info_request, ble_gap_evt_sec_info_request_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SEC_PARAMS_REQUEST, gap, sec_params_request); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.sec_params_request, ble_gap_evt_sec_params_request_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SEC_REQUEST, gap, sec_request); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gap_evt.params.sec_request, ble_gap_evt_sec_request_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GAP_EVT_TIMEOUT, gap, timeout); + + SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PULL_uint8(&p_event->evt.gap_evt.params.timeout.src); + + SER_EVT_DEC_END; +} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_app.h b/components/serialization/application/codecs/s132/serializers/ble_gap_evt_app.h similarity index 80% rename from components/serialization/application/codecs/s130/serializers/ble_gap_evt_app.h rename to components/serialization/application/codecs/s132/serializers/ble_gap_evt_app.h index 1e97446..cb3b5d2 100644 --- a/components/serialization/application/codecs/s130/serializers/ble_gap_evt_app.h +++ b/components/serialization/application/codecs/s132/serializers/ble_gap_evt_app.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GAP_EVT_APP_H__ #define BLE_GAP_EVT_APP_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_app_s130_codecs Application s130 codecs + * @addtogroup ser_app_s130_codecs Application S132 codecs * @ingroup ser_codecs */ @@ -32,11 +61,13 @@ */ #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Decodes ble_gap_evt_auth_key_request event. * - * @sa @ref nrf51_evt_auth_key_request_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -60,8 +91,6 @@ uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_auth_status event. * - * @sa @ref nrf51_evt_auth_status_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -85,8 +114,6 @@ uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_conn_param_update event. * - * @sa @ref nrf51_evt_conn_param_update_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -110,8 +137,6 @@ uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_conn_sec_update event. * - * @sa @ref nrf51_evt_conn_sec_update_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -135,8 +160,6 @@ uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_connected event. * - * @sa @ref nrf51_evt_connected_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -160,8 +183,6 @@ uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_disconnected event. * - * @sa @ref nrf51_evt_disconnected_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -185,8 +206,6 @@ uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_passkey_display event. * - * @sa @ref nrf51_evt_passkey_display for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -210,8 +229,6 @@ uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_rssi_changed event. * - * @sa @ref nrf51_evt_rssi_changed_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -235,8 +252,6 @@ uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_sec_info_request event. * - * @sa @ref nrf51_evt_sec_info_request_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -260,8 +275,6 @@ uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_sec_params_request event. * - * @sa @ref nrf51_evt_sec_param_request_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -285,8 +298,6 @@ uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_timeout event. * - * @sa @ref nrf51_evt_timeout_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -310,8 +321,6 @@ uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_sec_request event. * - * @sa @ref nrf51_evt_sec_request_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -335,8 +344,6 @@ uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_conn_param_update_request event. * - * @sa @ref nrf51_evt_conn_param_update_request_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -359,8 +366,6 @@ uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_adv_report event. * - * @sa @ref nrf51_evt_adv_report_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -384,8 +389,6 @@ uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gap_evt_scan_req_report event. * - * @sa @ref nrf51_evt_scan_req_report_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -405,5 +408,55 @@ uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf, uint32_t packet_len, ble_evt_t * const p_event, uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gap_evt_key_pressed event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_key_pressed_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); +/** + * @brief Decodes ble_gap_evt_lesc_dhkey_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gap_evt_lesc_dhkey_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/application/codecs/s132/serializers/ble_gattc_app.c b/components/serialization/application/codecs/s132/serializers/ble_gattc_app.c new file mode 100644 index 0000000..3a88e94 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_gattc_app.c @@ -0,0 +1,287 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gattc_app.h" +#include +#include "ble_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "ble_struct_serialization.h" +#include "ble_types.h" + +uint32_t ble_gattc_attr_info_discover_req_enc(uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_ATTR_INFO_DISCOVER); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_attr_info_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_ATTR_INFO_DISCOVER); +} + +uint32_t ble_gattc_char_value_by_uuid_read_req_enc(uint16_t conn_handle, + ble_uuid_t const * const p_uuid, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_uuid, ble_uuid_t_enc); + SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc); + + SER_REQ_ENC_END; +} + +uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ); +} + +uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle, + uint16_t const * const p_handles, + uint16_t handle_count, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_CHAR_VALUES_READ); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_len16data16(p_handles, handle_count); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUES_READ); +} + +uint32_t ble_gattc_characteristics_discover_req_enc( + uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER); +} + +uint32_t ble_gattc_descriptors_discover_req_enc( + uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_DESCRIPTORS_DISCOVER); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_DESCRIPTORS_DISCOVER); +} + +uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle, + uint16_t handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_HV_CONFIRM); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&handle); + + SER_REQ_ENC_END; +} + +uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_HV_CONFIRM); +} + +uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle, + uint16_t start_handle, + ble_uuid_t const * const p_srvc_uuid, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&start_handle); + SER_PUSH_COND(p_srvc_uuid, ble_uuid_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER); +} + +uint32_t ble_gattc_read_req_enc(uint16_t conn_handle, + uint16_t handle, + uint16_t offset, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_READ); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&handle); + SER_PUSH_uint16(&offset); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_READ); +} + +uint32_t ble_gattc_relationships_discover_req_enc( + uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER); +} + +uint32_t ble_gattc_write_req_enc(uint16_t conn_handle, + ble_gattc_write_params_t const * const p_write_params, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_WRITE); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_write_params, ble_gattc_write_params_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_WRITE); +} + +uint32_t ble_gattc_exchange_mtu_request_req_enc(uint16_t conn_handle, + uint16_t client_rx_mtu, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&client_rx_mtu); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gattc_exchange_mtu_request_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST); +} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_app.h b/components/serialization/application/codecs/s132/serializers/ble_gattc_app.h similarity index 67% rename from components/serialization/application/codecs/s130/serializers/ble_gattc_app.h rename to components/serialization/application/codecs/s132/serializers/ble_gattc_app.h index d6e1bba..4e2d3e3 100644 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_app.h +++ b/components/serialization/application/codecs/s132/serializers/ble_gattc_app.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATTC_APP_H__ #define BLE_GATTC_APP_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_app_s130_codecs Application s130 codecs + * @addtogroup ser_app_s130_codecs Application S132 codecs * @ingroup ser_codecs */ @@ -33,10 +62,13 @@ #include "ble_gattc.h" #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Encodes @ref sd_ble_gattc_primary_services_discover command request. * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_dec for command response decoder. + * @sa @ref ble_gattc_primary_services_discover_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] start_handle Handle to start searching from. @@ -58,11 +90,10 @@ uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t co /**@brief Decodes response to @ref sd_ble_gattc_primary_services_discover command. * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_req_enc for command request encoder. + * @sa @ref ble_gattc_primary_services_discover_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -77,8 +108,7 @@ uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf /**@brief Encodes @ref sd_ble_gattc_descriptors_discover command request. * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format, - * @ref ble_gattc_descriptors_discover_rsp_dec for command response decoder. + * @sa @ref ble_gattc_descriptors_discover_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_handle_range A pointer to the range of handles of the Service to perform @@ -100,11 +130,10 @@ uint32_t ble_gattc_descriptors_discover_req_enc( /**@brief Decodes response to @ref sd_ble_gattc_descriptors_discover command. * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder. + * @sa @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -119,8 +148,7 @@ uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_relationships_discover command request. * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format, - * @ref ble_gattc_relationships_discover_rsp_dec for command response decoder. + * @sa @ref ble_gattc_relationships_discover_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_handle_range A pointer to the range of handles of the Service to perform @@ -141,11 +169,10 @@ uint32_t ble_gattc_relationships_discover_req_enc( /**@brief Decodes response to @ref sd_ble_gattc_relationships_discover command. * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format, - * @ref ble_gattc_relationships_discover_req_enc for command request encoder. + * @sa @ref ble_gattc_relationships_discover_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -160,8 +187,7 @@ uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_characteristics_discover command request. * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format, - * @ref ble_gattc_characteristics_discover_rsp_dec for command response decoder. + * @sa @ref ble_gattc_characteristics_discover_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_handle_range A pointer to the range of handles of the Service to perform @@ -182,11 +208,10 @@ uint32_t ble_gattc_characteristics_discover_req_enc /**@brief Decodes response to @ref sd_ble_gattc_characteristics_discover command. * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder. + * @sa @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -201,8 +226,7 @@ uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_read command request. * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format, - * @ref ble_gattc_read_rsp_dec for command response decoder. + * @sa @ref ble_gattc_read_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] handle The handle of the attribute to be read. @@ -223,11 +247,10 @@ uint32_t ble_gattc_read_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gattc_read command. * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format, - * @ref ble_gattc_read_req_enc for command request encoder. + * @sa @ref ble_gattc_read_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -242,8 +265,7 @@ uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_char_values_read command request. * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format, - * @ref ble_gattc_char_values_read_rsp_dec for command response decoder. + * @sa @ref ble_gattc_char_values_read_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. @@ -264,11 +286,10 @@ uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gattc_char_values_read command. * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format, - * @ref ble_gattc_char_values_read_req_enc for command request encoder. + * @sa @ref ble_gattc_char_values_read_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -283,8 +304,7 @@ uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_write command request. * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format, - * @ref ble_gattc_write_rsp_dec for command response decoder. + * @sa @ref ble_gattc_write_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_write_params Pointer to \ref sd_ble_gattc_write params. @@ -303,11 +323,10 @@ uint32_t ble_gattc_write_req_enc(uint16_t conn_han /**@brief Decodes response to @ref sd_ble_gattc_write command. * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format, - * @ref ble_gattc_write_req_enc for command request encoder. + * @sa @ref ble_gattc_write_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -322,8 +341,7 @@ uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_hv_confirm command request. * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format, - * @ref ble_gattc_hv_confirm_rsp_dec for command response decoder. + * @sa @ref ble_gattc_hv_confirm_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] handle Handle of the attribute in the indication. @@ -342,11 +360,10 @@ uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gattc_hv_confirm command. * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format, - * @ref ble_gattc_hv_confirm_req_enc for command request encoder. + * @sa @ref ble_gattc_hv_confirm_req_enc for command request encoder. * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_result_code Pointer to command response result code. * * @retval NRF_SUCCESS Decoding success. @@ -361,8 +378,7 @@ uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_char_value_by_uuid_read command request. * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format, - * @ref ble_gattc_char_value_by_uuid_read_rsp_dec for command response decoder. + * @sa @ref ble_gattc_char_value_by_uuid_read_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_uuid Pointer to a characteristic value UUID to read. @@ -384,8 +400,7 @@ uint32_t ble_gattc_char_value_by_uuid_read_req_enc /**@brief Decodes response to @ref sd_ble_gattc_char_value_by_uuid_read command. * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format, - * @ref ble_gattc_char_value_by_uuid_read_req_enc for command request encoder. + * @sa @ref ble_gattc_char_value_by_uuid_read_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -400,7 +415,88 @@ uint32_t ble_gattc_char_value_by_uuid_read_req_enc uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_attr_info_discover command request. + * + * @sa @ref ble_gattc_attr_info_discover_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] p_handle_range Pointer to the range of handles + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_attr_info_discover_req_enc(uint16_t conn_handle, + ble_gattc_handle_range_t const * const p_handle_range, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_attr_info_discover command. + * + * @sa @ref ble_gattc_attr_info_discover_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Pointer to command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_attr_info_discover_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gattc_exchange_mtu_request command request. + * + * @sa @ref ble_gattc_exchange_mtu_request_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle of the connection. + * @param[in] client_rx_mtu Client MTU Size. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_exchange_mtu_request_req_enc(uint16_t conn_handle, + uint16_t client_rx_mtu, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gattc_exchange_mtu_request command. + * + * @sa @ref ble_gattc_exchange_mtu_request_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Pointer to command response result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected + * operation code. + */ +uint32_t ble_gattc_exchange_mtu_request_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/application/codecs/s132/serializers/ble_gattc_evt_app.c b/components/serialization/application/codecs/s132/serializers/ble_gattc_evt_app.c new file mode 100644 index 0000000..80f760b --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_gattc_evt_app.c @@ -0,0 +1,247 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gattc_evt_app.h" +#include +#include "ble_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "app_util.h" + +uint32_t ble_gattc_evt_attr_info_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, gattc, attr_info_disc_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.attr_info_disc_rsp, + ble_gattc_evt_attr_info_disc_rsp_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_CHAR_DISC_RSP, gattc, char_disc_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.char_disc_rsp, + ble_gattc_evt_char_disc_rsp_t_dec); + + SER_EVT_DEC_END; +} + + + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, gattc, char_val_by_uuid_read_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp, + ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_CHAR_VALS_READ_RSP, gattc, char_vals_read_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.char_vals_read_rsp, + ble_gattc_evt_char_vals_read_rsp_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_DESC_DISC_RSP, gattc, desc_disc_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.desc_disc_rsp, + ble_gattc_evt_desc_disc_rsp_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_HVX, gattc, hvx); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.hvx, + ble_gattc_evt_hvx_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP, gattc, prim_srvc_disc_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.prim_srvc_disc_rsp, + ble_gattc_evt_prim_srvc_disc_rsp_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_READ_RSP, gattc, read_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.read_rsp, + ble_gattc_evt_read_rsp_t_dec); + + SER_EVT_DEC_END; +} + + +#define BLE_GATTC_EVT_REL_DISC_RSP_COUNT_POSITION 6 + + +uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_READ_RSP, gattc, rel_disc_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.rel_disc_rsp, + ble_gattc_evt_rel_disc_rsp_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_TIMEOUT, gattc, timeout); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD(&p_event->evt.gattc_evt.params.timeout, + ble_gattc_evt_timeout_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_WRITE_RSP, gattc, write_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.write_rsp, + ble_gattc_evt_write_rsp_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gattc_evt_exchange_mtu_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_EXCHANGE_MTU_RSP, gattc, exchange_mtu_rsp); + + SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PULL_FIELD(&p_event->evt.gattc_evt.params.exchange_mtu_rsp, + ble_gattc_evt_exchange_mtu_rsp_t_dec); + + SER_EVT_DEC_END; +} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_app.h b/components/serialization/application/codecs/s132/serializers/ble_gattc_evt_app.h similarity index 73% rename from components/serialization/application/codecs/s130/serializers/ble_gattc_evt_app.h rename to components/serialization/application/codecs/s132/serializers/ble_gattc_evt_app.h index fba9e82..2ad8202 100644 --- a/components/serialization/application/codecs/s130/serializers/ble_gattc_evt_app.h +++ b/components/serialization/application/codecs/s132/serializers/ble_gattc_evt_app.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATTC_EVT_APP_H__ #define BLE_GATTC_EVT_APP_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_app_s130_codecs Application s130 codecs + * @addtogroup ser_app_s130_codecs Application S132 codecs * @ingroup ser_codecs */ @@ -32,11 +61,13 @@ */ #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Decodes ble_gattc_evt_char_disc_rsp event. * - * @sa @ref nrf51_gattc_evt_char_disc_rsp_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -60,8 +91,6 @@ uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gattc_evt_char_val_by_uuid_read_rsp event. * - * @sa @ref nrf51_gattc_evt_char_val_by_uuid_read_rsp_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -85,8 +114,6 @@ uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf /** * @brief Decodes ble_gattc_evt_char_vals_read_rsp event. * - * @sa @ref nrf51_gattc_evt_char_vals_read_rsp_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -110,8 +137,6 @@ uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gattc_evt_desc_disc_rsp event. * - * @sa @ref nrf51_gattc_evt_desc_disc_rsp_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -135,8 +160,6 @@ uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gattc_evt_hvx event. * - * @sa @ref nrf51_gattc_evt_hvx_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -160,8 +183,6 @@ uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gattc_evt_prim_srvc_disc_rsp event. * - * @sa @ref nrf51_gattc_evt_prim_srvc_disc_rsp_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -185,8 +206,6 @@ uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gattc_evt_read_rsp event. * - * @sa @ref nrf51_gattc_evt_read_rsp_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -210,8 +229,6 @@ uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gattc_evt_rel_disc_rsp_dec event. * - * @sa @ref nrf51_gattc_evt_rel_disc_rsp_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -235,8 +252,6 @@ uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gattc_evt_timeout event. * - * @sa @ref nrf51_gattc_evt_timeout_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -260,8 +275,6 @@ uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gattc_evt_write_rsp event. * - * @sa @ref nrf51_gattc_evt_write_rsp_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -282,5 +295,56 @@ uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf, ble_evt_t * const p_event, uint32_t * const p_event_len); +/** + * @brief Decodes ble_gattc_evt_attr_info_disc_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_attr_info_disc_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** + * @brief Decodes ble_gattc_evt_exchange_mtu_rsp event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gattc_evt_exchange_mtu_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/application/codecs/s132/serializers/ble_gatts_app.c b/components/serialization/application/codecs/s132/serializers/ble_gatts_app.c new file mode 100644 index 0000000..3fd9f91 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_gatts_app.c @@ -0,0 +1,440 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gatts_app.h" +#include +#include +#include "ble_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "ble_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + + +uint32_t ble_gatts_attr_get_req_enc(uint16_t handle, + ble_uuid_t * p_uuid, + ble_gatts_attr_md_t * p_md, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_ATTR_GET); + + SER_PUSH_uint16(&handle); + SER_PUSH_COND(p_uuid, NULL); + SER_PUSH_COND(p_md, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_attr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_uuid_t ** pp_uuid, + ble_gatts_attr_md_t ** pp_md, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_ATTR_GET); + SER_PULL_COND(pp_uuid, ble_uuid_t_dec); + SER_PULL_COND(pp_md, ble_gatts_attr_md_t_dec); + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_characteristic_add_req_enc( + uint16_t service_handle, + ble_gatts_char_md_t const * const p_char_md, + ble_gatts_attr_t const * const p_attr_char_value, + ble_gatts_char_handles_t const * const p_handles, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD); + + SER_PUSH_uint16(&service_handle); + SER_PUSH_COND(p_char_md, ble_gatts_char_md_t_enc); + SER_PUSH_COND(p_attr_char_value, ble_gatts_attr_t_enc); + SER_PUSH_COND(p_handles, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * * const pp_handles, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD); + + SER_PULL_COND(pp_handles, ble_gatts_char_handles_t_dec); + + SER_RSP_DEC_END; +} + + + +uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_handle, + ble_gatts_attr_t const * const p_attr, + uint16_t * const p_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD); + + SER_PUSH_uint16(&char_handle); + SER_PUSH_COND(p_attr, ble_gatts_attr_t_enc); + SER_PUSH_COND(p_handle, NULL); + + SER_REQ_ENC_END; +} + +uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_handle, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD); + + SER_PULL_COND(&p_handle, uint16_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle, + ble_gatts_hvx_params_t const * const p_hvx_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_HVX); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_hvx_params, ble_gatts_hvx_params_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code, + uint16_t * * const pp_bytes_written) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_HVX); + + SER_PULL_COND(pp_bytes_written, uint16_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle, + uint16_t inc_srvc_handle, + uint16_t * const p_include_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD); + + SER_PUSH_uint16(&service_handle); + SER_PUSH_uint16(&inc_srvc_handle); + SER_PUSH_COND(p_include_handle, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_include_handle, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD); + + SER_PULL_COND(&p_include_handle, uint16_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_initial_user_handle_get_req_enc(uint16_t * p_handle, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET); + + SER_PUSH_COND(p_handle, NULL); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_initial_user_handle_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t ** pp_handle, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET); + + SER_PULL_COND(pp_handle, uint16_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_rw_authorize_reply_req_enc(uint16_t conn_handle, + ble_gatts_rw_authorize_reply_params_t const * const p_reply_params, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_RW_AUTHORIZE_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_reply_params, ble_gatts_rw_authorize_reply_params_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTS_RW_AUTHORIZE_REPLY); +} + + +uint32_t ble_gatts_service_add_req_enc(uint8_t type, + ble_uuid_t const * const p_uuid, + uint16_t const * const p_conn_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SERVICE_ADD); + + SER_PUSH_uint8(&type); + SER_PUSH_COND(p_uuid, ble_uuid_t_enc); + SER_PUSH_COND(p_conn_handle, NULL); + + SER_REQ_ENC_END; +} + +uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_SERVICE_ADD); + + SER_PULL_COND(&p_conn_handle, uint16_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle, + uint16_t start_handle, + uint16_t end_handle, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SERVICE_CHANGED); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&start_handle); + SER_PUSH_uint16(&end_handle); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTS_SERVICE_CHANGED); +} + + +uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle, + uint8_t const * const p_sys_attr_data, + uint16_t const * const p_sys_attr_data_len, + uint32_t flags, + uint8_t * const p_buf, + uint32_t * p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_COND(p_sys_attr_data_len, uint16_t_enc); + SER_PUSH_COND(p_sys_attr_data, NULL); + SER_PUSH_uint32(&flags); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_sys_attr_data, + uint16_t * * const pp_sys_attr_data_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET); + + SER_PULL_COND(pp_sys_attr_data_len, uint16_t_dec); + if (*pp_sys_attr_data_len) + { + SER_PULL_buf(pp_sys_attr_data, **pp_sys_attr_data_len, **pp_sys_attr_data_len); + } + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle, + uint8_t const * const p_sys_attr_data, + uint16_t sys_attr_data_len, + uint32_t flags, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SYS_ATTR_SET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_len16data(p_sys_attr_data, sys_attr_data_len); + SER_PUSH_uint32(&flags); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_SYS_ATTR_SET, p_result_code); +} + + +uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle, + uint16_t handle, + ble_gatts_value_t const * const p_value, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_VALUE_GET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&handle); + + //Special case: skip the data. + SER_PUSH_COND(p_value, NULL); + if (p_value) + { + SER_PUSH_uint16(&p_value->offset); + SER_PUSH_uint16(&p_value->len); + SER_PUSH_COND(p_value->p_value, NULL); + } + + SER_REQ_ENC_END; +} + +uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gatts_value_t * const p_value, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_VALUE_GET); + + SER_PULL_COND(&p_value, ble_gatts_value_t_dec); + + SER_RSP_DEC_END; +} + + +uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle, + uint16_t handle, + ble_gatts_value_t * p_value, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_VALUE_SET); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&handle); + SER_PUSH_COND(p_value, ble_gatts_value_t_enc); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gatts_value_t * const p_value, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_BLE_GATTS_VALUE_SET); + + SER_PULL_COND(&p_value, ble_gatts_value_t_dec); + + SER_RSP_DEC_END; +} + +uint32_t ble_gatts_exchange_mtu_reply_req_enc(uint16_t conn_handle, + uint16_t server_rx_mtu, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_BLE_GATTS_EXCHANGE_MTU_REPLY); + + SER_PUSH_uint16(&conn_handle); + SER_PUSH_uint16(&server_rx_mtu); + + SER_REQ_ENC_END; +} + + +uint32_t ble_gatts_exchange_mtu_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTS_EXCHANGE_MTU_REPLY); +} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_app.h b/components/serialization/application/codecs/s132/serializers/ble_gatts_app.h similarity index 71% rename from components/serialization/application/codecs/s130/serializers/ble_gatts_app.h rename to components/serialization/application/codecs/s132/serializers/ble_gatts_app.h index 54b41a0..4bc13ad 100644 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_app.h +++ b/components/serialization/application/codecs/s132/serializers/ble_gatts_app.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATTS_APP_H__ #define BLE_GATTS_APP_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_app_s130_codecs Application s130 codecs + * @addtogroup ser_app_s130_codecs Application S132 codecs * @ingroup ser_codecs */ @@ -33,10 +62,13 @@ #include "ble_gatts.h" #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Encodes @ref sd_ble_gatts_value_get command request. * - * @sa @ref nrf51_gatts_value_get_encoding for packet format, - * @ref ble_gatts_value_get_rsp_dec for command response decoder. + * @sa @ref ble_gatts_value_get_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle. * @param[in] handle Attribute handle. @@ -60,8 +92,7 @@ uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle /**@brief Decodes response to @ref sd_ble_gatts_value_get command. * - * @sa @ref nrf51_gatts_value_get_encoding for packet format, - * @ref ble_gatts_value_get_req_enc for command request encoder. + * @sa @ref ble_gatts_value_get_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -81,8 +112,7 @@ uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_hvx command request. * - * @sa @ref nrf51_gatts_hvx_encoding for packet format, - * @ref ble_gatts_hvx_rsp_dec for command response decoder. + * @sa @ref ble_gatts_hvx_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle. * @param[in] p_hvx_params Pointer to an HVx parameters structure to be encoded. @@ -104,8 +134,7 @@ uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gatts_hvx command. * - * @sa @ref nrf51_gatts_hvx_encoding for packet format, - * @ref ble_gatts_hvx_req_enc for command request encoder. + * @sa @ref ble_gatts_hvx_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -125,8 +154,7 @@ uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_characteristic_add command request. * - * @sa @ref nrf51_characteristics_add_encoding for packet format, - * @ref ble_gatts_characteristic_add_rsp_dec for command response decoder. + * @sa @ref ble_gatts_characteristic_add_rsp_dec for command response decoder. * * @param[in] service_handle Handle of the service where the characteristic is to be placed. * If @ref BLE_GATT_HANDLE_INVALID is used, it will be placed @@ -158,8 +186,7 @@ uint32_t ble_gatts_characteristic_add_req_enc /**@brief Decodes response to @ref sd_ble_gatts_characteristic_add command. * - * @sa @ref nrf51_characteristics_add_encoding for packet format, - * @ref ble_gatts_characteristic_add_req_enc for command request encoder. + * @sa @ref ble_gatts_characteristic_add_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -180,8 +207,7 @@ uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_service_add command request. * - * @sa @ref nrf51_gatts_service_add_encoding for packet format, - * @ref ble_gatts_service_add_rsp_dec for command response decoder. + * @sa @ref ble_gatts_service_add_rsp_dec for command response decoder. * * @param[in] type Toggles between primary and secondary services, * see @ref BLE_GATTS_SRVC_TYPES. @@ -206,8 +232,7 @@ uint32_t ble_gatts_service_add_req_enc(uint8_t type, /**@brief Decodes response to @ref sd_ble_gatts_service_add command. * - * @sa @ref nrf51_gatts_service_add_encoding for packet format, - * @ref ble_gatts_service_add_req_enc for command request encoder. + * @sa @ref ble_gatts_service_add_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -227,8 +252,7 @@ uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_sys_attr_set command request. * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format, - * @ref ble_gatts_sys_attr_set_rsp_dec for command response decoder. + * @sa @ref ble_gatts_sys_attr_set_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle. * @param[in] p_sys_attr_data Pointer to a buffer (at least \p sys_attr_data_len bytes long) @@ -252,8 +276,7 @@ uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gatts_sys_attr_set command. * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format, - * @ref ble_gatts_sys_attr_set_req_enc for command request encoder. + * @sa @ref ble_gatts_sys_attr_set_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -271,8 +294,7 @@ uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_value_set command request. * - * @sa @ref nrf51_gatts_value_set_encoding for packet format, - * @ref ble_gatts_value_set_rsp_dec for command response decoder. + * @sa @ref ble_gatts_value_set_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle. * @param[in] handle Attribute handle. @@ -287,18 +309,17 @@ uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf, */ uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle, uint16_t handle, - ble_gatts_value_t * p_value, + ble_gatts_value_t * p_value, uint8_t * const p_buf, uint32_t * const p_buf_len); /**@brief Decodes response to @ref sd_ble_gatts_value_set command. * - * @sa @ref nrf51_gatts_value_set_encoding for packet format, - * @ref ble_gatts_value_set_req_enc for command request encoder. + * @sa @ref ble_gatts_value_set_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_value Pointer to attribute value information.. + * @param[out] p_value Pointer to attribute value information. * @param[out] p_result_code Command result code. * * @retval NRF_SUCCESS Decoding success. @@ -314,8 +335,7 @@ uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_sys_attr_get command request. * - * @sa @ref nrf51_gatts_sys_attr_get_encoding for packet format, - * @ref ble_gatts_sys_attr_get_rsp_dec for command response decoder. + * @sa @ref ble_gatts_sys_attr_get_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle of the connection. * @param[in] p_sys_attr_data Pointer to buffer where updated information about system @@ -345,14 +365,13 @@ uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gatts_sys_attr_get command. * - * @sa @ref nrf51_gatts_sys_attr_get_encoding for packet format, - * @ref ble_gatts_sys_attr_get_req_enc for command request encoder. + * @sa @ref ble_gatts_sys_attr_get_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system + * @param[out] pp_sys_attr_data Pointer to a buffer where updated information about system * attributes will be stored. - * @param[in,out] p_sys_attr_data_len \c in: Size (in bytes) of \p p_sys_attr_data buffer. + * @param[in,out] pp_sys_attr_data_len \c in: Size (in bytes) of \p p_sys_attr_data buffer. * \c out: Length of decoded contents of \p p_sys_attr_data. * @param[out] p_result_code Command result code. * @@ -366,19 +385,18 @@ uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle, */ uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, - uint8_t * const p_sys_attr_data, - uint16_t * const p_sys_attr_data_len, + uint8_t * * const pp_sys_attr_data, + uint16_t * * const pp_sys_attr_data_len, uint32_t * const p_result_code); /**@brief Encodes @ref sd_ble_gatts_descriptor_add command request. * - * @sa @ref nrf51_descriptor_add_encoding for packet format, - * @ref ble_gatts_descriptor_add_rsp_dec for command response decoder. + * @sa @ref ble_gatts_descriptor_add_rsp_dec for command response decoder. * * @param[in] char_handle Handle of the characteristic where the description is to be placed. * If @ref BLE_GATT_HANDLE_INVALID is used, it will be placed * sequentially. - * @param[in] p_attr Pointer to a @ref ble_gatts_attr_t structure, characteristic + * @param[in] p_attr Pointer to a @ref ble_gatts_attr_t structure, characteristic * metadata. * @param[in] p_handle Pointer to a @ref ble_gatts_char_handles_t structure, where the * assigned handles will be stored. @@ -398,8 +416,7 @@ uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_ha /**@brief Decodes response to @ref sd_ble_gatts_descriptor_add command. * - * @sa @ref nrf51_descriptor_add_encoding for packet format, - * @ref ble_gatts_descriptor_add_req_enc for command request encoder. + * @sa @ref ble_gatts_descriptor_add_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -420,8 +437,7 @@ uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_include_add command request. * - * @sa @ref nrf51_gatts_include_add_encoding for packet format, - * @ref ble_gatts_include_add_rsp_dec for command response decoder. + * @sa @ref ble_gatts_include_add_rsp_dec for command response decoder. * * @param[in] service_handle Handle of the service where the included service is to be placed. * @param[in] inc_srvc_handle Handle of the included service @@ -442,8 +458,7 @@ uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle, /**@brief Decodes response to @ref sd_ble_gatts_include_add command. * - * @sa @ref nrf51_gatts_include_add_encoding for packet format, - * @ref ble_gatts_include_add_req_enc for command request encoder. + * @sa @ref ble_gatts_include_add_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -464,8 +479,7 @@ uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command request. * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format, - * @ref ble_gatts_rw_authorize_reply_rsp_dec for command response decoder. + * @sa @ref ble_gatts_rw_authorize_reply_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle. * @param[in] p_reply_params Pointer to \ref ble_gatts_rw_authorize_reply_params_t @@ -489,8 +503,7 @@ uint32_t ble_gatts_rw_authorize_reply_req_enc( /**@brief Decodes response to @ref sd_ble_gatts_rw_authorize_reply command. * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format, - * @ref ble_gatts_rw_authorize_reply_req_enc for command request encoder. + * @sa @ref ble_gatts_rw_authorize_reply_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -508,8 +521,7 @@ uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_service_changed command request. * - * @sa @ref nrf51_service_changed_encoding for packet format, - * @ref ble_gatts_service_changed_rsp_dec for command response decoder. + * @sa @ref ble_gatts_service_changed_rsp_dec for command response decoder. * * @param[in] conn_handle Connection handle. * @param[in] start_handle Start of affected attribute handle range. @@ -531,8 +543,7 @@ uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle, /**@brief Decodes response to @ref sd_ble_gatts_service_changed command. * - * @sa @ref nrf51_service_changed_encoding for packet format, - * @ref ble_gatts_service_changed_req_enc for command request encoder. + * @sa @ref ble_gatts_service_changed_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -548,7 +559,130 @@ uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, uint32_t * const p_result_code); +/**@brief Encodes @ref sd_ble_gatts_attr_get command request. + * + * @sa @ref ble_gatts_attr_get_rsp_dec for command response decoder. + * + * @param[in] handle See @ref sd_ble_gatts_attr_get. + * @param[in] p_uuid See @ref sd_ble_gatts_attr_get. + * @param[out] p_md See @ref sd_ble_gatts_attr_get. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_attr_get_req_enc(uint16_t handle, + ble_uuid_t * p_uuid, + ble_gatts_attr_md_t * p_md, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_attr_get command. + * + * @sa @ref ble_gatts_attr_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_uuid Pointer to address where to put output data. + * @param[out] pp_md Pointer to address where to put output data. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_attr_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_uuid_t ** pp_uuid, + ble_gatts_attr_md_t ** pp_md, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_initial_user_handle_get command request. + * + * @sa @ref ble_gatts_initial_user_handle_get_rsp_dec for command response decoder. + * + * @param[out] p_handle See @ref sd_ble_gatts_initial_user_handle_get. + * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_initial_user_handle_get_req_enc(uint16_t * p_handle, + uint8_t * const p_buf, + uint32_t * p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_initial_user_handle_get command. + * + * @sa @ref ble_gatts_initial_user_handle_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_handle Pointer to address where to put output data. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_initial_user_handle_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t ** pp_handle, + uint32_t * const p_result_code); + +/**@brief Encodes @ref sd_ble_gatts_exchange_mtu_reply command request. + * + * @sa @ref ble_gatts_exchange_mtu_reply_rsp_dec for command response decoder. + * + * @param[in] conn_handle Connection handle. + * @param[in] server_rx_mtu Server MTU Size. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params. + */ +uint32_t ble_gatts_exchange_mtu_reply_req_enc(uint16_t conn_handle, + uint16_t server_rx_mtu, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ble_gatts_exchange_mtu_reply command. + * + * @sa @ref ble_gatts_exchange_mtu_reply_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match + * expected operation code. + */ +uint32_t ble_gatts_exchange_mtu_reply_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif //BLE_GATTS_APP_H__ diff --git a/components/serialization/application/codecs/s132/serializers/ble_gatts_evt_app.c b/components/serialization/application/codecs/s132/serializers/ble_gatts_evt_app.c new file mode 100644 index 0000000..24c1d50 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_gatts_evt_app.c @@ -0,0 +1,176 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gatts_evt_app.h" +#include "ble_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "app_ble_user_mem.h" +#include "app_util.h" + +extern ser_ble_user_mem_t m_app_user_mem_table[]; + +uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_HVC, gatts, hvc); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gatts_evt.params.hvc, + ble_gatts_evt_hvc_t_dec); + + SER_EVT_DEC_END; +} + +uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_HVC, gatts, rw_authorize_request); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gatts_evt.params.authorize_request, ble_gatts_evt_rw_authorize_request_t_dec); + + //Correct event length / memory sync. + if (p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_READ) + { + evt_struct_len = offsetof(ble_evt_t, evt.gatts_evt.params.authorize_request.request.read) + - offsetof(ble_evt_t, evt) + + sizeof(ble_gatts_evt_read_t); + } + else if ((p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && + ( (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || + (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ))) + { + uint32_t conn_index; + if(app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) + { + SER_PULL_len16data(&m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len); + } + } + + SER_EVT_DEC_END; +} + + +uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN_NO_STRUCT(BLE_GATTS_EVT_SC_CONFIRM, gatts); + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_EVT_DEC_END; +} + + +uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_SYS_ATTR_MISSING, gatts, sys_attr_missing); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gatts_evt.params.sys_attr_missing, + ble_gatts_evt_sys_attr_missing_t_dec); + + SER_EVT_DEC_END; +} + + +uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_TIMEOUT, gatts, timeout); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gatts_evt.params.timeout, + ble_gatts_evt_timeout_t_dec); + + SER_EVT_DEC_END; +} + + + + +uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_WRITE, gatts, write); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.gatts_evt.params.write, ble_gatts_evt_write_t_dec); + + if(p_event != NULL) + { + if(p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) + { + uint32_t conn_index; + if(app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) + { + SER_PULL_len16data(&m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + } + } + + SER_EVT_DEC_END; +} + + +uint32_t ble_gatts_evt_exchange_mtu_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, gatts, exchange_mtu_request); + + SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PULL_FIELD(&p_event->evt.gatts_evt.params.exchange_mtu_request, ble_gatts_evt_exchange_mtu_request_t_dec); + + SER_EVT_DEC_END; +} diff --git a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_app.h b/components/serialization/application/codecs/s132/serializers/ble_gatts_evt_app.h similarity index 70% rename from components/serialization/application/codecs/s130/serializers/ble_gatts_evt_app.h rename to components/serialization/application/codecs/s132/serializers/ble_gatts_evt_app.h index d7c3fff..e254b53 100644 --- a/components/serialization/application/codecs/s130/serializers/ble_gatts_evt_app.h +++ b/components/serialization/application/codecs/s132/serializers/ble_gatts_evt_app.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATTS_EVT_APP_H__ #define BLE_GATTS_EVT_APP_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_app_s130_codecs Application s130 codecs + * @addtogroup ser_app_s130_codecs Application S132 codecs * @ingroup ser_codecs */ @@ -32,11 +61,13 @@ */ #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Decodes ble_gatts_evt_hvc event. * - * @sa @ref nrf51_gatts_evt_hvc_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -60,8 +91,6 @@ uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gatts_evt_rw_authorize_request event. * - * @sa @ref nrf51_evt_rw_authorize_request for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -85,8 +114,6 @@ uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gatts_evt_sc_confirm event. * - * @sa @ref nrf51_gatts_evt_sc_confirm_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -110,8 +137,6 @@ uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gatts_evt_sys_attr_missing event. * - * @sa @ref nrf51_evt_sys_attr_missing_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -135,8 +160,6 @@ uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gatts_evt_timeout event. * - * @sa @ref nrf51_gatts_evt_timeout_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -160,8 +183,6 @@ uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf, /** * @brief Decodes ble_gatts_evt_write event. * - * @sa @ref nrf51_evt_write_encoding for packet format. - * * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. * * @param[in] p_buf Pointer to the beginning of an event packet. @@ -182,5 +203,33 @@ uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf, ble_evt_t * const p_event, uint32_t * const p_event_len); +/** + * @brief Decodes ble_gatts_evt_exchange_mtu_request event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_gatts_evt_exchange_mtu_request_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/application/codecs/s132/serializers/ble_l2cap_app.c b/components/serialization/application/codecs/s132/serializers/ble_l2cap_app.c new file mode 100644 index 0000000..d8ce568 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_l2cap_app.c @@ -0,0 +1,146 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ble_l2cap_app.h" +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gap.h" +#include "app_util.h" +#include "cond_field_serialization.h" + +uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); + + p_buf[index++] = SD_BLE_L2CAP_CID_REGISTER; + err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_REGISTER, p_result_code); +} + +uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len); + + p_buf[index++] = SD_BLE_L2CAP_CID_UNREGISTER; + err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + *p_buf_len = index; + + return err_code; +} + +uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_UNREGISTER, p_result_code); +} + + +uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle, + ble_l2cap_header_t const * const p_l2cap_header, + uint8_t const * const p_data, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_buf_len); + + SER_ASSERT_LENGTH_LEQ(1, *p_buf_len); + p_buf[index++] = SD_BLE_L2CAP_TX; + + err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = cond_field_enc(p_l2cap_header, p_buf, *p_buf_len, &index, ble_l2cap_header_t_enc); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (p_l2cap_header != NULL) + { + err_code = buf_enc(p_data, p_l2cap_header->len, p_buf, *p_buf_len, &index); + } + else + { + err_code = buf_enc(NULL, 0, p_buf, *p_buf_len, &index); + } + + *p_buf_len = index; + + return err_code; +} + +uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code) +{ + return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_TX, p_result_code); +} diff --git a/components/serialization/application/codecs/s130/serializers/ble_l2cap_app.h b/components/serialization/application/codecs/s132/serializers/ble_l2cap_app.h similarity index 64% rename from components/serialization/application/codecs/s130/serializers/ble_l2cap_app.h rename to components/serialization/application/codecs/s132/serializers/ble_l2cap_app.h index 626ccc4..4042437 100644 --- a/components/serialization/application/codecs/s130/serializers/ble_l2cap_app.h +++ b/components/serialization/application/codecs/s132/serializers/ble_l2cap_app.h @@ -1,9 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -12,7 +44,7 @@ */ /** - * @addtogroup ser_app_s130_codecs Application s130 codecs + * @addtogroup ser_app_s130_codecs Application S132 codecs * @ingroup ser_codecs */ @@ -34,14 +66,18 @@ #include "ble_err.h" #include "ble_l2cap.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Register a CID with L2CAP. * - * @details This registers a higher protocol layer with the L2CAP multiplexer, and is requried prior to all operations on the CID. + * @details This registers a higher protocol layer with the L2CAP multiplexer, and is required prior to all operations on the CID. * - * @param[in] cid L2CAP CID. + * @param[in] cid L2CAP CID. * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -54,8 +90,7 @@ uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid, /** * @brief Decodes response to @ref sd_ble_l2cap_cid_register command. * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_l2cap_cid_register_req_enc for command request encoder. + * @sa @ref ble_l2cap_cid_register_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -75,8 +110,8 @@ uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf, * * @details This unregisters a previously registered higher protocol layer with the L2CAP multiplexer. * - * @param[in] cid L2CAP CID. - * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] cid L2CAP CID. + * @param[in] p_buf Pointer to beginning of command response packet. * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. * \c out: Length of encoded command packet. * @@ -91,8 +126,7 @@ uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid, /** * @brief Decodes response to @ref sd_ble_l2cap_cid_unregister command. * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_l2cap_cid_unregister_req_enc for command request encoder. + * @sa @ref ble_l2cap_cid_unregister_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -112,21 +146,20 @@ uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf, * * @note It is important to note that a call to this function will consume an application buffer, and will therefore * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. - * Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. + * See the documentation of @ref sd_ble_tx_packet_count_get for more details. * - * @param[in] conn_handle Connection Handle. + * @param[in] conn_handle Connection handle. * @param[in] p_l2cap_header Pointer to a packet header containing length and CID. - * @param[in] p_data Pointer to the data to be transmitted. - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. - * \c out: Length of encoded command packet. + * @param[in] p_data Pointer to the data to be transmitted. + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer. + * \c out: Length of encoded command packet. * * @return @ref NRF_SUCCESS Successfully queued an L2CAP packet for transmission. * @return @ref NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @return @ref NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register. * @return @ref NRF_ERROR_NOT_FOUND CID not found. * @return @ref NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @return @ref BLE_ERROR_NO_TX_BUFFERS Not enough application buffers available. * @return @ref NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF. */ uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle, @@ -138,8 +171,7 @@ uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle, /** * @brief Decodes response to @ref sd_ble_l2cap_tx command. * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_l2cap_tx_req_enc for command request encoder. + * @sa @ref ble_l2cap_tx_req_enc for command request encoder. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -156,6 +188,11 @@ uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf, uint32_t * const p_result_code); + +#ifdef __cplusplus +} +#endif + #endif //BLE_L2CAP_APP_H__ /** diff --git a/components/serialization/application/codecs/s132/serializers/ble_l2cap_evt_app.c b/components/serialization/application/codecs/s132/serializers/ble_l2cap_evt_app.c new file mode 100644 index 0000000..38e9d82 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_l2cap_evt_app.c @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "app_util.h" +#include "ble_l2cap_evt_app.h" + +uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len) +{ + SER_EVT_DEC_BEGIN(BLE_L2CAP_EVT_RX, l2cap, rx); + + SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle); + SER_PULL_FIELD_EXTENDED(&p_event->evt.l2cap_evt.params.rx, ble_l2cap_evt_rx_t_dec); + + SER_EVT_DEC_END; +} diff --git a/components/serialization/application/codecs/s132/serializers/ble_l2cap_evt_app.h b/components/serialization/application/codecs/s132/serializers/ble_l2cap_evt_app.h new file mode 100644 index 0000000..6228804 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/ble_l2cap_evt_app.h @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_L2CAP_EVT_APP_H__ +#define BLE_L2CAP_EVT_APP_H__ + +/** + * @addtogroup ser_codecs Serialization codecs + * @ingroup ble_sdk_lib_serialization + */ + +/** + * @addtogroup ser_app_s130_codecs Application S132 codecs + * @ingroup ser_codecs + */ + +/**@file + * + * @defgroup ble_l2cap_evt_app L2CAP Application event decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief L2CAP Application event decoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Decodes ble_l2cap_evt_rx event. + * + * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len. + * + * @param[in] p_buf Pointer to the beginning of an event packet. + * @param[in] packet_len Length (in bytes) of the event packet. + * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be + * stored. If NULL, required length will be returned in \p p_event_len. + * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer. + * \c out: Length of decoded contents of \p p_event. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_evt_t * const p_event, + uint32_t * const p_event_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/serialization/application/codecs/s132/serializers/nrf_soc_app.c b/components/serialization/application/codecs/s132/serializers/nrf_soc_app.c new file mode 100644 index 0000000..93fd314 --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/nrf_soc_app.c @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_soc_app.h" +#include "nrf_soc.h" +#include +#include +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "nrf_soc_struct_serialization.h" +#include "app_util.h" + + +uint32_t ecb_block_encrypt_req_enc(nrf_ecb_hal_data_t * p_ecb_data, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_ECB_BLOCK_ENCRYPT); + SER_PUSH_COND(p_ecb_data, nrf_ecb_hal_data_t_in_enc); + SER_REQ_ENC_END; +} + + +uint32_t ecb_block_encrypt_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + nrf_ecb_hal_data_t * * const pp_ecb_data, + uint32_t * const p_result_code) +{ + SER_RSP_DEC_BEGIN(SD_ECB_BLOCK_ENCRYPT); + SER_PULL_COND(pp_ecb_data, nrf_ecb_hal_data_t_out_dec); + SER_RSP_DEC_END; +} + + +uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_POWER_SYSTEM_OFF); + SER_REQ_ENC_END; +} + + +uint32_t temp_get_req_enc(int32_t const * const p_temp, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_REQ_ENC_BEGIN(SD_TEMP_GET); + SER_PUSH_COND(p_temp, NULL); + SER_REQ_ENC_END; +} + +uint32_t temp_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code, + int32_t * * const pp_temp) +{ + SER_RSP_DEC_BEGIN(SD_TEMP_GET); + SER_PULL_COND(pp_temp, uint32_t_dec); + SER_RSP_DEC_END; +} diff --git a/components/serialization/application/codecs/s132/serializers/nrf_soc_app.h b/components/serialization/application/codecs/s132/serializers/nrf_soc_app.h new file mode 100644 index 0000000..6fdad6e --- /dev/null +++ b/components/serialization/application/codecs/s132/serializers/nrf_soc_app.h @@ -0,0 +1,158 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +/** + * @addtogroup ser_codecs Serialization codecs + * @ingroup ble_sdk_lib_serialization + */ + +/** + * @addtogroup ser_app_s130_codecs Application S132 codecs + * @ingroup ser_codecs + */ + +/**@file + * + * @defgroup soc_app SOC Application command request encoders and command response decoders + * @{ + * @ingroup ser_app_s130_codecs + * + * @brief SOC Application command request encoders and command response decoders. + */ + +#ifndef NRF_SOC_APP_H__ +#define NRF_SOC_APP_H__ + +#include +#include "nrf_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif +/**@brief Encodes @ref sd_power_system_off command request. + * + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len); + + +/**@brief Encodes @ref sd_temp_get command request. + * + * @sa @ref temp_get_rsp_dec for command response decoder. + * + * @param[in] p_temp Pointer to result of temperature measurement. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t temp_get_req_enc(int32_t const * const p_temp, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_temp_get command. + * + * @sa @ref temp_get_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_result_code Command result code. + * @param[out] pp_temp Pointer to result of temperature measurement. + * + * @return NRF_SUCCESS Version information stored successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t temp_get_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint32_t * const p_result_code, + int32_t * * const pp_temp); + +/**@brief Encodes @ref sd_ecb_block_encrypt command request. + * + * @sa @ref ecb_block_encrypt_rsp_dec for command response decoder. + * + * @param[in] p_ecb_data Pointer to ECB data. + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ecb_block_encrypt_req_enc(nrf_ecb_hal_data_t * p_ecb_data, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes response to @ref sd_ecb_block_encrypt command. + * + * @sa @ref ecb_block_encrypt_req_enc for command request encoder. + * + * @param[in] p_buf Pointer to beginning of command response packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_ecb_data Pointer to ECB data. + * @param[out] p_result_code Command result code. + * + * @return NRF_SUCCESS Version information stored successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to + * hold decoded event. + */ +uint32_t ecb_block_encrypt_rsp_dec(uint8_t const * const p_buf, + uint32_t packet_len, + nrf_ecb_hal_data_t * * const p_ecb_data, + uint32_t * const p_result_code); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SOC_APP_H__ diff --git a/components/serialization/application/hal/arm_startup_nrf51.s b/components/serialization/application/hal/arm_startup_nrf51.s index ccab7fc..5b1ab68 100644 --- a/components/serialization/application/hal/arm_startup_nrf51.s +++ b/components/serialization/application/hal/arm_startup_nrf51.s @@ -1,20 +1,20 @@ ; Copyright (c) 2013, Nordic Semiconductor ASA ; 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 Nordic Semiconductor ASA 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 @@ -25,8 +25,8 @@ ; 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. - -; NOTE: Template files (including this one) are application specific and therefore + +; NOTE: Template files (including this one) are application specific and therefore ; expected to be copied into the application project folder prior to its use! ; Description message @@ -215,7 +215,7 @@ SWI5_IRQHandler ; User Initial Stack & Heap IF :DEF:__MICROLIB - + EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit diff --git a/components/serialization/application/hal/ser_app_hal.h b/components/serialization/application/hal/ser_app_hal.h index 894a613..a4f716f 100644 --- a/components/serialization/application/hal/ser_app_hal.h +++ b/components/serialization/application/hal/ser_app_hal.h @@ -1,76 +1,117 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 * - * @defgroup ser_app_hal Serialization Application Hardware Abstraction Layer + * @defgroup ser_app_hal Serialization Application Hardware Abstraction Layer (HAL) * @{ * @ingroup ble_sdk_lib_serialization * - * @brief Functions which set up hardware on Application board and perform the reset of the Connectivity Board. + * @brief @tagAPI52832 Functions that set up hardware on Application Board and perform the reset of the Connectivity Board. */ #ifndef SER_APP_HAL_H_ #define SER_APP_HAL_H_ #include -/**@brief Function for initializing hw modules. +#include + +#ifdef __cplusplus +extern "C" { +#endif +typedef void (*ser_app_hal_flash_op_done_handler_t)(bool success); +/**@brief Function for initializing hardware modules. * - * @details Function can initilize can hardware modules on application processor. It is optional to - * implement. It is called one connectivity chip is initialized. + * @details Function can initialize hardware modules on the Application Chip. It is optional to + * implement. It is called once the Connectivity Chip is initialized. + * + * @param handler Flash operation event handler. * * @return @ref NRF_SUCCESS HAL initialized successfully. * @return @ref nrf_error "NRF_ERROR_..." HAL initialization failed. * */ -uint32_t ser_app_hal_hw_init(void); +uint32_t ser_app_hal_hw_init(ser_app_hal_flash_op_done_handler_t handler); -/**@brief Function for waiting for given amount of time. +/**@brief Function for waiting for a given amount of time. * * @param[in] ms Number of milliseconds to wait. * */ void ser_app_hal_delay(uint32_t ms); -/**@brief Function for clearing connectivity chip reset pin +/**@brief Function for clearing the Connectivity Chip reset pin. * */ void ser_app_hal_nrf_reset_pin_clear(void); -/**@brief Function for setting connectivity chip reset pin +/**@brief Function for setting the Connectivity Chip reset pin. * */ void ser_app_hal_nrf_reset_pin_set(void); -/**@brief Function for setting softdevice event interrupt priority which is serving events incoming - * from connectivity chip. +/**@brief Function for setting the SoftDevice event interrupt priority that serves the events incoming + * from the Connectivity Chip. * - * @note Serialization solution on application side mimics SoC solution where events are handled in - * the interrupt context in two ways: or directly in the interrupt context or message is posted to - * the scheduler. However, it is possible that application processor is not using dedicated interrupt - * for connectivity events. In that case this function can be left empty and + * @note Serialization solution on the application side mimics a SoC solution where events are handled in + * the interrupt context in two ways: either directly in the interrupt context or with a message being posted to + * the scheduler. However, it is possible that the Application Chip does not use a dedicated interrupt + * for connectivity events. In that case, this function can be left empty and * \ref ser_app_hal_nrf_evt_pending will directly call an interrupt handler function. */ void ser_app_hal_nrf_evt_irq_priority_set(void); -/**@brief Function for setting pending interrupt for serving events incoming from connectivity chip. +/**@brief Function for setting a pending interrupt for serving events incoming from the Connectivity Chip. * - * @note The interrupt used for event from connectivity chip mimics behavior of SoC and it is not + * @note The interrupt used for event from the Connectivity Chip mimics behavior of SoC and it is not * intended to be triggered by any hardware event. This function should be the only source of * interrupt triggering. */ void ser_app_hal_nrf_evt_pending(void); + +#ifdef __cplusplus +} +#endif + #endif /* SER_APP_HAL_H_ */ /** @} */ diff --git a/components/serialization/application/hal/ser_app_hal_nrf51.c b/components/serialization/application/hal/ser_app_hal_nrf51.c deleted file mode 100644 index ebbba67..0000000 --- a/components/serialization/application/hal/ser_app_hal_nrf51.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_util_platform.h" -#include "ser_app_hal.h" -#include "nrf.h" -#include "nrf_gpio.h" -#include "nrf_soc.h" -#include "nrf_delay.h" -#include "boards.h" -#include "ser_phy.h" -#include "ser_phy_config_app_nrf51.h" - -#ifdef NRF51 -#define SOFTDEVICE_EVT_IRQ SD_EVT_IRQn /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ -#elif defined NRF52 -#define SOFTDEVICE_EVT_IRQ SWI2_EGU2_IRQn -#endif /* NRF51 */ - -uint32_t ser_app_hal_hw_init() -{ - nrf_gpio_cfg_output(CONN_CHIP_RESET_PIN_NO); - - NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; - NRF_CLOCK->TASKS_LFCLKSTART = 1; - - while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) - { - //No implementation needed. - } - - NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; - - return NRF_SUCCESS; -} - -void ser_app_hal_delay(uint32_t ms) -{ - nrf_delay_ms(ms); -} - -void ser_app_hal_nrf_reset_pin_clear() -{ - nrf_gpio_pin_clear(CONN_CHIP_RESET_PIN_NO); -} - -void ser_app_hal_nrf_reset_pin_set() -{ - nrf_gpio_pin_set(CONN_CHIP_RESET_PIN_NO); -} - -void ser_app_hal_nrf_evt_irq_priority_set() -{ - NVIC_SetPriority(SOFTDEVICE_EVT_IRQ, APP_IRQ_PRIORITY_LOW); -} - -void ser_app_hal_nrf_evt_pending() -{ - NVIC_SetPendingIRQ(SOFTDEVICE_EVT_IRQ); -} - -uint32_t sd_ppi_channel_enable_get(uint32_t * p_channel_enable) -{ - *p_channel_enable = NRF_PPI->CHEN; - return NRF_SUCCESS; -} - -uint32_t sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk) -{ - NRF_PPI->CHEN = channel_enable_set_msk; - return NRF_SUCCESS; -} - -uint32_t sd_ppi_channel_assign(uint8_t channel_num, - const volatile void * evt_endpoint, - const volatile void * task_endpoint) -{ - NRF_PPI->CH[channel_num].TEP = (uint32_t)task_endpoint; - NRF_PPI->CH[channel_num].EEP = (uint32_t)evt_endpoint; - return NRF_SUCCESS; -} diff --git a/components/serialization/application/hal/ser_app_hal_nrf5x.c b/components/serialization/application/hal/ser_app_hal_nrf5x.c new file mode 100644 index 0000000..5bf2b40 --- /dev/null +++ b/components/serialization/application/hal/ser_app_hal_nrf5x.c @@ -0,0 +1,161 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "app_util_platform.h" +#include "ser_app_hal.h" +#include "nrf.h" +#include "nrf_gpio.h" +#include "nrf_soc.h" +#include "nrf_delay.h" +#include "nrf_nvmc.h" +#include "boards.h" +#include "ser_phy.h" +#include "ser_phy_config_app.h" + +#define SOFTDEVICE_EVT_IRQ SD_EVT_IRQn /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define FLASH_WRITE_MAX_LENGTH ((uint16_t)NRF_FICR->CODEPAGESIZE) +#define BLE_FLASH_PAGE_SIZE ((uint16_t)NRF_FICR->CODEPAGESIZE) /**< Size of one flash page. */ + +static ser_app_hal_flash_op_done_handler_t m_flash_op_handler; +uint32_t ser_app_hal_hw_init(ser_app_hal_flash_op_done_handler_t handler) +{ + nrf_gpio_cfg_output(CONN_CHIP_RESET_PIN_NO); + + NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos); + NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; + NRF_CLOCK->TASKS_LFCLKSTART = 1; + + while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) + { + //No implementation needed. + } + + NRF_CLOCK->EVENTS_LFCLKSTARTED = 0; + m_flash_op_handler = handler; + return NRF_SUCCESS; +} + +void ser_app_hal_delay(uint32_t ms) +{ + nrf_delay_ms(ms); +} + +void ser_app_hal_nrf_reset_pin_clear() +{ + nrf_gpio_pin_clear(CONN_CHIP_RESET_PIN_NO); +} + +void ser_app_hal_nrf_reset_pin_set() +{ + nrf_gpio_pin_set(CONN_CHIP_RESET_PIN_NO); +} + +void ser_app_hal_nrf_evt_irq_priority_set() +{ + NVIC_SetPriority(SOFTDEVICE_EVT_IRQ, APP_IRQ_PRIORITY_LOWEST); +} + +void ser_app_hal_nrf_evt_pending() +{ + NVIC_SetPendingIRQ(SOFTDEVICE_EVT_IRQ); +} + +uint32_t sd_ppi_channel_enable_get(uint32_t * p_channel_enable) +{ + *p_channel_enable = NRF_PPI->CHEN; + return NRF_SUCCESS; +} + +uint32_t sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk) +{ + NRF_PPI->CHEN = channel_enable_set_msk; + return NRF_SUCCESS; +} + +uint32_t sd_ppi_channel_assign(uint8_t channel_num, + const volatile void * evt_endpoint, + const volatile void * task_endpoint) +{ + NRF_PPI->CH[channel_num].TEP = (uint32_t)task_endpoint; + NRF_PPI->CH[channel_num].EEP = (uint32_t)evt_endpoint; + return NRF_SUCCESS; +} +/** + * @brief Check if given address is in device FLASH range. + * + * @param[in] ptr Address to check. + * @retval true Given address is located in FLASH. + * @retval false Given address is not located in FLASH. + */ +__STATIC_INLINE bool addr_is_in_FLASH(void const * const ptr) +{ + return ((((uintptr_t)ptr) & 0xFF000000u) == 0x00000000u); +} + +uint32_t sd_flash_page_erase(uint32_t page_number) +{ + uint32_t * p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_number); + + if (!addr_is_in_FLASH(p_page)) + { + return NRF_ERROR_INVALID_ADDR; + } + + nrf_nvmc_page_erase((uint32_t) p_page); + m_flash_op_handler(true); + return NRF_SUCCESS; +} + +uint32_t sd_flash_write(uint32_t * const p_dst, uint32_t const * const p_src, uint32_t size) +{ + if (size > FLASH_WRITE_MAX_LENGTH) + { + return NRF_ERROR_INVALID_LENGTH; + } + + if (!addr_is_in_FLASH(p_dst)) + { + return NRF_ERROR_INVALID_ADDR; + } + + nrf_nvmc_write_words((uint32_t) p_dst, p_src, size); + m_flash_op_handler(true); + return NRF_SUCCESS; +} diff --git a/components/serialization/application/hal/ser_app_power_system_off.c b/components/serialization/application/hal/ser_app_power_system_off.c index 90f1ba8..2fd4842 100644 --- a/components/serialization/application/hal/ser_app_power_system_off.c +++ b/components/serialization/application/hal/ser_app_power_system_off.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "nrf.h" @@ -15,7 +43,7 @@ static bool m_power_system_off = false; - + void ser_app_power_system_off_set(void) { m_power_system_off = true; @@ -31,5 +59,5 @@ void ser_app_power_system_off_enter(void) NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter; /*Only for debugging purpose, will not be reached without connected debugger*/ - while(1); + while (1); } diff --git a/components/serialization/application/hal/ser_app_power_system_off.h b/components/serialization/application/hal/ser_app_power_system_off.h index 08db7f0..c5ca3d6 100644 --- a/components/serialization/application/hal/ser_app_power_system_off.h +++ b/components/serialization/application/hal/ser_app_power_system_off.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 APP_POWER_SYSTEM_OFF_H @@ -15,10 +43,19 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + void ser_app_power_system_off_set(void); bool ser_app_power_system_off_get(void); void ser_app_power_system_off_enter(void); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/application/transport/ser_sd_transport.c b/components/serialization/application/transport/ser_sd_transport.c index b06898a..da9c1be 100644 --- a/components/serialization/application/transport/ser_sd_transport.c +++ b/components/serialization/application/transport/ser_sd_transport.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include @@ -18,17 +46,11 @@ #include "nrf_error.h" #include "app_error.h" #include "ble_serialization.h" - +#include "ser_dbg_sd_str.h" #include "ser_app_power_system_off.h" - #include "app_util.h" - -#ifdef ENABLE_DEBUG_LOG_SUPPORT -#include "app_trace.h" -#define APPL_LOG app_trace_log /**< Debug logger macro that will be used in this file to do logging of debug information over UART. */ -#else -#define APPL_LOG(...) -#endif //ENABLE_DEBUG_LOG_SUPPORT +#define NRF_LOG_MODULE_NAME "SER_XFER" +#include "nrf_log.h" /** SoftDevice event handler. */ static ser_sd_transport_evt_handler_t m_evt_handler = NULL; @@ -101,7 +123,7 @@ static void ser_sd_transport_rx_packet_handler(uint8_t * p_data, uint16_t length case SER_PKT_TYPE_EVT: /* It is ensured during opening that handler is not NULL. No check needed. */ - APPL_LOG("\r\n[EVT_ID]: 0x%X \r\n", uint16_decode(&p_data[SER_EVT_ID_POS])); // p_data points to EVT_ID + NRF_LOG_DEBUG("[EVT]: %s \r\n", (uint32_t)ser_dbg_sd_evt_str_get(uint16_decode(&p_data[SER_EVT_ID_POS]))); // p_data points to EVT_ID m_evt_handler(p_data, length); break; @@ -132,7 +154,7 @@ static void ser_sd_transport_hal_handler(ser_hal_transport_evt_t event) } break; case SER_HAL_TRANSP_EVT_TX_PKT_SENT: - if(ser_app_power_system_off_get() == true) + if (ser_app_power_system_off_get() == true) { ser_app_power_system_off_enter(); } @@ -254,6 +276,7 @@ uint32_t ser_sd_transport_cmd_write(const uint8_t * p_buffer, { m_rsp_wait = false; } - APPL_LOG("\r\n[SD_CALL_ID]: 0x%X, err_code= 0x%X\r\n", p_buffer[1], err_code); + + NRF_LOG_DEBUG("[SD_CALL]:%s, err_code= 0x%X\r\n", (uint32_t)ser_dbg_sd_call_str_get(p_buffer[1]), err_code); return err_code; } diff --git a/components/serialization/application/transport/ser_sd_transport.h b/components/serialization/application/transport/ser_sd_transport.h index 19d4243..73a7e46 100644 --- a/components/serialization/application/transport/ser_sd_transport.h +++ b/components/serialization/application/transport/ser_sd_transport.h @@ -1,18 +1,47 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** * @addtogroup ser_app Application side code * @ingroup ble_sdk_lib_serialization + * @brief @tagAPI52832 SoftDevice handler and transport on the application side. */ /** @file @@ -27,8 +56,8 @@ * identifiers (typedef enum) used as API of the serialization of SoftDevice. This layer * ensures atomic nature of SoftDevice calls (command and waiting for response). Packet * type field of incoming packets is handled in this layer - responses are handled by - * ser_sd_transport (using response decoder handler provided for each SoftDevice call) but - * events are forwarded to the user so it is user's responsibility to free RX buffer. + * ser_sd_transport (using response decoder handler provided for each SoftDevice call), but + * events are forwarded to the user so it is up to the user to free the RX buffer. * */ #ifndef SER_SD_TRANSPORT_H_ @@ -37,6 +66,10 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + typedef void (*ser_sd_transport_evt_handler_t)(uint8_t * p_buffer, uint16_t length); typedef void (*ser_sd_transport_rsp_wait_handler_t)(void); typedef void (*ser_sd_transport_rsp_set_handler_t)(void); @@ -47,17 +80,17 @@ typedef uint32_t (*ser_sd_transport_rsp_handler_t)(const uint8_t * p_buffer, uin /**@brief Function for opening the module. * * @note 'Wait for response' and 'Response set' callbacks can be set in RTOS environment. - * It enables rescheduling while waiting for connectivity chip response. In nonOS environment - * usually 'Wait for response' will only be used for handling incoming events or force + * It enables rescheduling while waiting for the Connectivity Chip response. In a nonOS environment, + * usually 'Wait for response' will only be used for handling incoming events or forcing the * application to low power mode. * * @param[in] evt_handler Handler to be called when event packet is received. - * @param[in] os_rsp_wait_handler Handler to be called after request is send. It should. - * implement 'Wait for signal' functionality in OS environment. - * @param[in] os_rsp_set_handler Handler to be called after response reception. It should - * implement 'Signal Set' functionality in OS environment - * @param[in] rx_not_handler Handler to be called after transport layer notifies that - * there is incoming rx packet detected. + * @param[in] os_rsp_wait_handler Handler to be called after the request is send. It should + * implement a 'Wait for signal' functionality in an OS environment. + * @param[in] os_rsp_set_handler Handler to be called after response reception. It should + * implement a 'Signal Set' functionality in an OS environment. + * @param[in] rx_not_handler Handler to be called after the transport layer notifies that + * an incoming RX packet is detected. * * @retval NRF_SUCCESS Operation success. * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. @@ -74,13 +107,13 @@ uint32_t ser_sd_transport_open(ser_sd_transport_evt_handler_t evt_ha ser_sd_transport_rsp_set_handler_t os_rsp_set_handler, ser_sd_transport_rx_notification_handler_t rx_not_handler); -/**@brief Function setting 'One Time' handler to be called between sending next request packet and - * receiving response packet. - * @note It is intended to be used in nonOS environment to implement concurrency. - * @note It is 'One Time' handler meaning that it is valid only for next softdevice call processing. +/**@brief Function setting a 'One Time' handler to be called between sending the next request packet and + * receiving the response packet. + * @note It is intended to be used in a nonOS environment to implement concurrency. + * @note It is a 'One Time' handler meaning that it is valid only for the next SoftDevice call processing. * * - * @param[in] wait_handler Handler to be called after request packet is sent. + * @param[in] wait_handler Handler to be called after the request packet is sent. * * @retval NRF_SUCCESS Operation success. */ @@ -93,9 +126,9 @@ uint32_t ser_sd_transport_ot_rsp_wait_handler_set(ser_sd_transport_rsp_wait_hand */ uint32_t ser_sd_transport_close(void); -/**@brief Function for allocating tx packet to be used for request command. +/**@brief Function for allocating a TX packet to be used for request command. * - * @param[out] pp_data Pointer to data pointer to be set to point to allocated buffer. + * @param[out] pp_data Pointer to the data pointer to be set to point to allocated buffer. * @param[out] p_len Pointer to allocated buffer length. * * @retval NRF_SUCCESS Operation success. @@ -103,22 +136,22 @@ uint32_t ser_sd_transport_close(void); uint32_t ser_sd_transport_tx_alloc(uint8_t * * pp_data, uint16_t * p_len); -/**@brief Function for freeing tx packet. +/**@brief Function for freeing a TX packet. * - * @note Function should be called once command is processed. + * @note Function should be called once the command is processed. * - * @param[out] p_data Pointer to allocated tx buffer. + * @param[out] p_data Pointer to the allocated TX buffer. * * @retval NRF_SUCCESS Operation success. */ uint32_t ser_sd_transport_tx_free(uint8_t * p_data); -/**@brief Function for freeing RX event packet. +/**@brief Function for freeing an RX event packet. * - * @note Function should be called once SoftDevice event buffer is processed. + * @note Function should be called once the SoftDevice event buffer is processed. * - * @param[out] p_data Pointer to allocated rx buffer. + * @param[out] p_data Pointer to the allocated RX buffer. * * @retval NRF_SUCCESS Operation success. */ @@ -127,21 +160,21 @@ uint32_t ser_sd_transport_rx_free(uint8_t * p_data); /**@brief Function for checking if module is busy waiting for response from connectivity side. * - * @retval true Module busy. Cannot accept next command. - * @retval false Module not busy. Can accept next command. + * @retval true Module busy. Cannot accept the next command. + * @retval false Module not busy. Can accept next the command. */ bool ser_sd_transport_is_busy(void); -/**@brief Function for handling SoftDevice command. +/**@brief Function for handling a SoftDevice command. * * @note Function blocks task context until response is received and processed. - * @note Non-blocking functionality can be achieved using os handlers or 'One Time' handler - * @warning Function shouldn't be called from interrupt context which would block switching to + * @note Non-blocking functionality can be achieved using OS handlers or a 'One Time' handler + * @warning Function should not be called from interrupt context, which would block switching to * serial port interrupt. * * @param[in] p_buffer Pointer to command. * @param[in] length Pointer to allocated buffer length. - * @param[in] cmd_resp_decode_callback Pointer to function for decoding response packet. + * @param[in] cmd_resp_decode_callback Pointer to a function for decoding the response packet. * * @retval NRF_SUCCESS Operation success. */ @@ -149,5 +182,10 @@ uint32_t ser_sd_transport_cmd_write(const uint8_t * p_buffer, uint16_t length, ser_sd_transport_rsp_handler_t cmd_resp_decode_callback); + +#ifdef __cplusplus +} +#endif + #endif /* SER_SD_TRANSPORT_H_ */ /** @} */ diff --git a/components/serialization/application/transport/ser_softdevice_handler.c b/components/serialization/application/transport/ser_softdevice_handler.c index 284df3b..fd0881e 100644 --- a/components/serialization/application/transport/ser_softdevice_handler.c +++ b/components/serialization/application/transport/ser_softdevice_handler.c @@ -1,18 +1,46 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include #include #include "ble_app.h" -#include "app_mailbox.h" +#include "nrf_queue.h" #include "app_scheduler.h" #include "softdevice_handler.h" #include "ser_sd_transport.h" @@ -34,7 +62,15 @@ typedef struct * Mailbox used for communication between event handler (called from serial stream * interrupt context) and event processing function (called from scheduler or interrupt context). */ -APP_MAILBOX_DEF(sd_ble_evt_mailbox, SD_BLE_EVT_MAILBOX_QUEUE_SIZE, sizeof(ser_sd_handler_evt_data_t)); +NRF_QUEUE_DEF(ser_sd_handler_evt_data_t, + m_sd_ble_evt_mailbox, + SD_BLE_EVT_MAILBOX_QUEUE_SIZE, + NRF_QUEUE_MODE_NO_OVERFLOW); + +NRF_QUEUE_DEF(uint32_t, + m_sd_soc_evt_mailbox, + SD_BLE_EVT_MAILBOX_QUEUE_SIZE, + NRF_QUEUE_MODE_NO_OVERFLOW); /** * @brief Function to be replaced by user implementation if needed. @@ -48,7 +84,7 @@ __WEAK void os_rsp_set_handler(void) static void connectivity_reset_low(void) { - //Signal a reset to the nRF51822 by setting the reset pin on the nRF51822 low. + //Signal a reset to the connectivity chip by setting the reset pin low. ser_app_hal_nrf_reset_pin_clear(); ser_app_hal_delay(CONN_CHIP_RESET_TIME); @@ -60,7 +96,7 @@ static void connectivity_reset_high(void) //Set the reset level to high again. ser_app_hal_nrf_reset_pin_set(); - //Wait for nRF51822 to be ready. + //Wait for connectivity chip to be ready. ser_app_hal_delay(CONN_CHIP_WAKEUP_TIME); } @@ -76,7 +112,18 @@ static void ser_softdevice_evt_handler(uint8_t * p_data, uint16_t length) err_code = ser_sd_transport_rx_free(p_data); APP_ERROR_CHECK(err_code); - err_code = app_mailbox_put(&sd_ble_evt_mailbox, &item); + err_code = nrf_queue_push(&m_sd_ble_evt_mailbox, &item); + APP_ERROR_CHECK(err_code); + + ser_app_hal_nrf_evt_pending(); +} + +void ser_softdevice_flash_operation_success_evt(bool success) +{ + uint32_t evt_type = success ? NRF_EVT_FLASH_OPERATION_SUCCESS : + NRF_EVT_FLASH_OPERATION_ERROR; + + uint32_t err_code = nrf_queue_push(&m_sd_soc_evt_mailbox, &evt_type); APP_ERROR_CHECK(err_code); ser_app_hal_nrf_evt_pending(); @@ -98,16 +145,12 @@ static void ser_sd_rsp_wait(void) uint32_t sd_evt_get(uint32_t * p_evt_id) { - (void)p_evt_id; - //current serialization doesn't support any events other than ble events - return NRF_ERROR_NOT_FOUND; + return nrf_queue_pop(&m_sd_soc_evt_mailbox, p_evt_id); } uint32_t sd_ble_evt_get(uint8_t * p_data, uint16_t * p_len) { - uint32_t err_code; - - err_code = app_mailbox_get(&sd_ble_evt_mailbox, p_data); + uint32_t err_code = nrf_queue_pop(&m_sd_ble_evt_mailbox, p_data); if (err_code == NRF_SUCCESS) //if anything in the mailbox { @@ -130,36 +173,31 @@ uint32_t sd_ble_evt_get(uint8_t * p_data, uint16_t * p_len) uint32_t sd_ble_evt_mailbox_length_get(uint32_t * p_mailbox_length) { - uint32_t err_code = NRF_SUCCESS; - - *p_mailbox_length = app_mailbox_length_get(&sd_ble_evt_mailbox); - - return err_code; + *p_mailbox_length = nrf_queue_utilization_get(&m_sd_ble_evt_mailbox); + return NRF_SUCCESS; } -uint32_t sd_softdevice_enable(nrf_clock_lfclksrc_t clock_source, - softdevice_assertion_handler_t assertion_handler) +uint32_t sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, + nrf_fault_handler_t assertion_handler) { uint32_t err_code; - err_code = ser_app_hal_hw_init(); + err_code = ser_app_hal_hw_init(ser_softdevice_flash_operation_success_evt); if (err_code == NRF_SUCCESS) { connectivity_reset_low(); - err_code = app_mailbox_create(&sd_ble_evt_mailbox); + nrf_queue_reset(&m_sd_soc_evt_mailbox); + nrf_queue_reset(&m_sd_ble_evt_mailbox); + err_code = ser_sd_transport_open(ser_softdevice_evt_handler, + ser_sd_rsp_wait, + os_rsp_set_handler, + NULL); if (err_code == NRF_SUCCESS) { - err_code = ser_sd_transport_open(ser_softdevice_evt_handler, - ser_sd_rsp_wait, - os_rsp_set_handler, - NULL); - if (err_code == NRF_SUCCESS) - { - connectivity_reset_high(); - } + connectivity_reset_high(); } ser_app_hal_nrf_evt_irq_priority_set(); diff --git a/components/serialization/application/transport/ser_softdevice_handler.h b/components/serialization/application/transport/ser_softdevice_handler.h index 93e1e96..5757ed7 100644 --- a/components/serialization/application/transport/ser_softdevice_handler.h +++ b/components/serialization/application/transport/ser_softdevice_handler.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -30,8 +58,12 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif -/**@brief Function for checking if there is any more events in the internal mailbox. + +/**@brief Function for checking if there are any more events in the internal mailbox. * * @param[in] p_mailbox_length Pointer to mailbox length. * @@ -40,5 +72,10 @@ */ uint32_t sd_ble_evt_mailbox_length_get(uint32_t * p_mailbox_length); + +#ifdef __cplusplus +} +#endif + #endif /* SER_SOFTDEVICE_HANDLER_H_ */ /** @} */ diff --git a/components/serialization/common/ble_serialization.c b/components/serialization/common/ble_serialization.c index 2701a3b..1305304 100644 --- a/components/serialization/common/ble_serialization.c +++ b/components/serialization/common/ble_serialization.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_serialization.h" #include "nrf_error.h" @@ -294,7 +322,7 @@ uint32_t count16_cond_data16_enc(uint16_t const * const p_data, if (p_data) { - SER_ASSERT_LENGTH_LEQ((int32_t)(2 * count + 1), ((int32_t)buf_len - (int32_t)*p_index)); + SER_ASSERT_LENGTH_LEQ((int32_t)(2 * count + 1), ((int32_t)buf_len - (int32_t) * p_index)); p_buf[*p_index] = SER_FIELD_PRESENT; *p_index += 1; @@ -344,6 +372,7 @@ uint32_t count16_cond_data16_dec(uint8_t const * const p_buf, if (!is_present) { + *p_count = count; *pp_data = NULL; return NRF_SUCCESS; } diff --git a/components/serialization/common/ble_serialization.h b/components/serialization/common/ble_serialization.h index 4043fb7..d1d8eca 100644 --- a/components/serialization/common/ble_serialization.h +++ b/components/serialization/common/ble_serialization.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_SERIALIZATION_H__ @@ -17,8 +45,13 @@ #include "nrf_error.h" #include #include +#include "cond_field_serialization.h" -/**@brief The types of serialization packets. */ +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Types of serialization packets. */ typedef enum { SER_PKT_TYPE_CMD = 0, /**< Command packet type. */ @@ -86,17 +119,18 @@ typedef enum #define SER_FIELD_NOT_PRESENT 0x00 -/** Enable SER_ASSERT<*> assserts */ +/** Enable SER_ASSERT<*> asserts */ #define SER_ASSERTS_ENABLED 1 /** Returns with error code if expr is not true. It is used for checking error which should be * checked even when SER_ASSERTS_ENABLED is not set. */ #define SER_ERROR_CHECK(expr, error_code) do { if (!(expr)) return (error_code); } while (0) + #ifdef SER_ASSERTS_ENABLED /** Returns with error code if expr is not true. */ #define SER_ASSERT(expr, error_code) SER_ERROR_CHECK(expr, error_code) -/** Returns with if expr is not true. */ +/** Returns if expression is not true. */ #define SER_ASSERT_VOID_RETURN(expr) do { if (!(expr)) return; } while (0) /** Returns with \ref NRF_ERROR_INVALID_LENGTH if len is not less or equal to maxlen. */ #define SER_ASSERT_LENGTH_LEQ(len, maxlen) \ @@ -121,6 +155,385 @@ typedef enum /** See Bluetooth 4.0 spec: 3.4.4.7. */ #define BLE_GATTC_HANDLE_COUNT_LEN_MAX ((GATT_MTU_SIZE_DEFAULT - 1) / 2) +/** Subtract 1 from X if X is greater than 0. */ +#define SUB1(X) (((X)>0) ? ((X)-1) : (X)) + +static inline void static_force_impl_castable_p_void(void const * const p) {} +/** Force the argument to be a double pointer. */ +#define STATIC_FORCE_PP(PP) static_force_impl_castable_p_void(*(PP)) + +/** Field decoder for special structures containing variable length data. */ +typedef uint32_t (*field_ext_decoder_handler_t)(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_length, + void * p_field); + + +/** Push uint8_t field into the output packet. */ +#define SER_PUSH_uint8(P_VAR) do { \ + err_code = uint8_t_enc((P_VAR), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push uint16_t field into the output packet. */ +#define SER_PUSH_uint16(P_VAR) do { \ + err_code = uint16_t_enc((P_VAR), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push uint32_t field into the output packet. */ +#define SER_PUSH_uint32(P_VAR) do { \ + err_code = uint32_t_enc((P_VAR), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push int8_t field into the output packet. */ +#define SER_PUSH_int8(P_VAR) SER_PUSH_uint8(P_VAR) + +/** Push uint16_t field into the output packet. */ +#define SER_PUSH_int16(P_VAR) SER_PUSH_uint16(P_VAR) + +/** Push uint32_t field into the output packet. */ +#define SER_PUSH_int32(P_VAR) SER_PUSH_uint32(P_VAR) + +/** Push a constant length array of bytes into the output packet. */ +#define SER_PUSH_uint8array(P_DATA, LEN) do { \ + err_code = uint8_vector_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push a variable length (8-bit) array of bytes into the output packet. */ +#define SER_PUSH_len8data(P_DATA, LEN) do { \ + err_code = len8data_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push a variable length (16-bit) array of bytes into the output packet. */ +#define SER_PUSH_len16data(P_DATA, LEN) do { \ + err_code = len16data_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push a variable length (16-bit) array of 16-bit words into the output packet. */ +#define SER_PUSH_len16data16(P_DATA, LEN) do { \ + err_code = count16_cond_data16_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push a buffer into the output packet. */ +#define SER_PUSH_buf(P_DATA, LEN) do { \ + err_code = buf_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push a structure into the output packet. */ +#define SER_PUSH_FIELD(P_VAR, P_ENCODER) do { \ + err_code = field_enc((P_VAR), p_buf, buf_len, p_index, (P_ENCODER)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Push an array of structures into the output packet. */ +#define SER_PUSH_FIELD_ARRAY(P_ARRAY, P_ENCODER, COUNT) do { \ + for (uint32_t _idx = 0; _idx < (COUNT); ++_idx) \ + { \ + SER_PUSH_FIELD(&((P_ARRAY)[_idx]),P_ENCODER);\ + } \ + } while (0) + +/** Conditionally push a field if the specified pointer is not null. */ +#define SER_PUSH_COND(P_VAR, P_ENCODER) do { \ + err_code = cond_field_enc((P_VAR), p_buf, buf_len, p_index, (P_ENCODER)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + + +/** Pull a uint8_t field from the input packet. */ +#define SER_PULL_uint8(P_VAR) do { \ + err_code = uint8_t_dec(p_buf, packet_len, p_index, (P_VAR)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a uint16_t field from the input packet. */ +#define SER_PULL_uint16(P_VAR) do { \ + err_code = uint16_t_dec(p_buf, packet_len, p_index, (P_VAR)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a uint32_t field from the input packet. */ +#define SER_PULL_uint32(P_VAR) do { \ + err_code = uint32_t_dec(p_buf, packet_len, p_index, (P_VAR)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull an int8_t field from the input packet. */ +#define SER_PULL_int8(P_VAR) SER_PULL_uint8(P_VAR) + +/** Pull an int16_t field from the input packet. */ +#define SER_PULL_int16(P_VAR) SER_PULL_uint16(P_VAR) + +/** Pull an int32_t field from the input packet. */ +#define SER_PULL_int32(P_VAR) SER_PULL_uint32(P_VAR) + +/** Pull a constant length byte array from the input packet. */ +#define SER_PULL_uint8array(P_DATA, LEN) do { \ + err_code = uint8_vector_dec(p_buf, packet_len, p_index, (P_DATA), (LEN)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a variable length (8-bit) byte array from the input packet. */ +#define SER_PULL_len8data(PP_DATA, LEN) do { \ + STATIC_FORCE_PP(PP_DATA); \ + err_code = len8data_dec(p_buf, packet_len, p_index, (PP_DATA), (LEN)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a variable length (16-bit) byte array from the input packet. */ +#define SER_PULL_len16data(PP_DATA, P_LEN) do { \ + STATIC_FORCE_PP(PP_DATA); \ + err_code = len16data_dec(p_buf, packet_len, p_index, (PP_DATA), (P_LEN)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a variable length (16-bit) word (16-bit) array from the input packet. */ +#define SER_PULL_len16data16(PP_DATA, P_LEN) do { \ + STATIC_FORCE_PP(PP_DATA); \ + err_code = count16_cond_data16_dec(p_buf, packet_len, p_index, (PP_DATA), (P_LEN)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a buffer from the input packet. */ +#define SER_PULL_buf(PP_DATA, OUT_BUF_LEN, LEN) do { \ + STATIC_FORCE_PP(PP_DATA); \ + err_code = buf_dec(p_buf, packet_len, p_index, (PP_DATA), (OUT_BUF_LEN), (LEN)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull a structure from the input packet. */ +#define SER_PULL_FIELD(P_VAR, P_DECODER) do { \ + err_code = field_dec(p_buf, packet_len, p_index, (P_VAR), (P_DECODER)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + +/** Pull an array of structures from the input packet. */ +#define SER_PULL_FIELD_ARRAY(P_ARRAY, P_DECODER, COUNT) do { \ + for (uint32_t _idx = 0; _idx < (COUNT); ++_idx) \ + { \ + SER_PULL_FIELD(&((P_ARRAY)[_idx]),P_DECODER); \ + } \ + } while (0) + +/** Conditionally pull a structure from the input packet. */ +#define SER_PULL_COND(PP_VAR, P_DECODER) do { \ + STATIC_FORCE_PP(PP_VAR); \ + err_code = cond_field_dec(p_buf, packet_len, p_index, (void * *)(PP_VAR), (P_DECODER)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + } while (0) + + +/** Start the encoding of a structure and prepare local variables for the usage of SER_PUSH_ macros. */ +#define SER_STRUCT_ENC_BEGIN(STRUCT_TYPE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_index); \ + SER_ASSERT_NOT_NULL(p_void_struct); \ + STRUCT_TYPE * p_struct = (STRUCT_TYPE *) p_void_struct; \ + uint32_t err_code = NRF_SUCCESS + +/** End the encoding of a structure. */ +#define SER_STRUCT_ENC_END return err_code + +/** Start the decoding of a structure and prepare local variables for the usage of SER_PULL_ macros. */ +#define SER_STRUCT_DEC_BEGIN(STRUCT_TYPE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_index); \ + SER_ASSERT_NOT_NULL(p_void_struct); \ + STRUCT_TYPE * p_struct = (STRUCT_TYPE *) p_void_struct; \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t packet_len = buf_len + +/** End the encoding of a structure. */ +#define SER_STRUCT_DEC_END return err_code + + +/** Start the encoding of command request and prepare local variables for the usage of SER_PUSH_ macros. */ +#define SER_REQ_ENC_BEGIN(OPCODE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_buf_len); \ + \ + uint32_t index = 0; \ + uint32_t * const p_index = &index; \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t buf_len = *p_buf_len; \ + \ + uint8_t opcode = (OPCODE); \ + SER_PUSH_uint8(&opcode) + +/** End the encoding of command request. */ +#define SER_REQ_ENC_END \ + *p_buf_len = index; \ + return NRF_SUCCESS \ + +/** Start the decoding of command response that does not contain any data except the result code. */ +#define SER_RSP_DEC_RESULT_ONLY(OPCODE) \ + return ser_ble_cmd_rsp_dec(p_buf, packet_len, (OPCODE), p_result_code) + +/** Start the decoding of command response and prepare local variables for the usage of SER_PULL_ macros. */ +#define SER_RSP_DEC_BEGIN(OPCODE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_result_code); \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t index = 0; \ + uint32_t * const p_index = &index; \ + /* Decode the result code and exit if decoding has failed or \ + the decoded result is not NRF_SUCCESS. */ \ + err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, (OPCODE), p_result_code); \ + \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + if (*p_result_code != NRF_SUCCESS) \ + { \ + SER_ASSERT_LENGTH_EQ(index, packet_len); \ + return NRF_SUCCESS; \ + } + +/** End the decoding of command response. */ +#define SER_RSP_DEC_END \ + /* Require all data to be pulled. */ \ + SER_ASSERT_LENGTH_EQ(index, packet_len); \ + return err_code + + +/** Start the decoding of command request and prepare local variables for the usage of SER_PULL_ macros. */ +#define SER_REQ_DEC_BEGIN(OPCODE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT(packet_len>0, NRF_ERROR_INVALID_PARAM); \ + uint32_t index = 0; \ + uint32_t * const p_index = &index; \ + uint32_t err_code = NRF_SUCCESS; \ + SER_ASSERT(p_buf[index] == (OPCODE), NRF_ERROR_INVALID_PARAM); \ + (void)err_code; \ + (void)p_index; \ + ++index + +/** End the decoding of command request. */ +#define SER_REQ_DEC_END \ + SER_ASSERT_LENGTH_EQ(index, packet_len); \ + return NRF_SUCCESS + +/** Start the encoding of command response and prepare local variables for the usage of SER_PUSH_ macros. */ +#define SER_RSP_ENC_BEGIN(OPCODE) \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_buf_len); \ + uint32_t index = 0; \ + uint32_t * const p_index = &index; \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t buf_len = *p_buf_len; \ + /* Push the opcode + result and exit if result \ + is not NRF_SUCCESS. */ \ + uint8_t opcode = (OPCODE); \ + SER_PUSH_uint8(&opcode); \ + SER_PUSH_uint32(&return_code); \ + \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + if (return_code != NRF_SUCCESS) \ + { \ + SER_RSP_ENC_END; \ + } + +/** Start the encoding of command response that contains the result code only. */ +#define SER_RSP_ENC_RESULT_ONLY(OPCODE) \ + return ser_ble_cmd_rsp_status_code_enc((OPCODE), return_code, p_buf, p_buf_len) + +/** End the encoding of command response. */ +#define SER_RSP_ENC_END \ + *p_buf_len = index; \ + return NRF_SUCCESS + + +/** Start the encoding of an event and prepare local variables for the usage of SER_PUSH_ macros. */ +#define SER_EVT_ENC_BEGIN(EVT_HEADER) \ + SER_ASSERT_NOT_NULL(p_event); \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_buf_len); \ + SER_ASSERT(p_event->header.evt_id == (EVT_HEADER), NRF_ERROR_INVALID_PARAM); \ + uint32_t index = 0; \ + uint32_t * p_index = &index; \ + uint32_t buf_len = *p_buf_len; \ + uint32_t err_code = NRF_SUCCESS; \ + uint16_t evt_header = (EVT_HEADER); \ + /* Push event header. */ \ + SER_PUSH_uint16(&evt_header) + +/** End the encoding of an event. */ +#define SER_EVT_ENC_END \ + *p_buf_len = index; \ + return err_code + + +/** Start the decoding of an event that has an event-specific data structure + and prepare local variables for the usage of SER_PULL_ macros. */ +#define SER_EVT_DEC_BEGIN(EVT_CODE, EVT_GROUP, EVT_NAME) \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t index = 0; \ + uint32_t * p_index = &index; \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_event_len); \ + /* Calculate the base event structure length */ \ + /* and make sure that there is enough free space */ \ + /* in the output buffer. */ \ + uint32_t evt_struct_len = \ + offsetof(ble_evt_t, evt.EVT_GROUP##_evt.params) \ + - offsetof(ble_evt_t, evt) \ + + sizeof(ble_##EVT_GROUP##_evt_##EVT_NAME##_t); \ + SER_ASSERT_LENGTH_LEQ(evt_struct_len, *p_event_len); \ + *p_event_len -= evt_struct_len; \ + /* Some structures contains variable length arrays */ \ + /* and the overall size may be greater. */ \ + uint32_t evt_extended_len = 0; \ + (void) evt_extended_len; \ + p_event->header.evt_id = EVT_CODE + +/** Start the decoding of an event that has no event-specific data structure. + and prepare local variables for the usage of SER_PULL_ macros. */ +#define SER_EVT_DEC_BEGIN_NO_STRUCT(EVT_CODE, EVT_GROUP) \ + uint32_t err_code = NRF_SUCCESS; \ + uint32_t index = 0; \ + uint32_t * p_index = &index; \ + SER_ASSERT_NOT_NULL(p_buf); \ + SER_ASSERT_NOT_NULL(p_event_len); \ + /* Calculate the base event structure length */ \ + /* and make sure that there is enough free space */ \ + /* in the output buffer. */ \ + uint32_t evt_struct_len = \ + offsetof(ble_evt_t, evt.EVT_GROUP##_evt.params) \ + - offsetof(ble_evt_t, evt) ; \ + SER_ASSERT_LENGTH_LEQ(evt_struct_len, *p_event_len); \ + *p_event_len -= evt_struct_len; \ + /* Some structures contain variable length arrays */ \ + /* and the overall size may be greater. */ \ + uint32_t evt_extended_len = 0; \ + (void) evt_extended_len; \ + p_event->header.evt_id = EVT_CODE + +/** End the decoding of an event. */ +#define SER_EVT_DEC_END \ + SER_ASSERT_LENGTH_EQ(index, packet_len); \ + /*p_event_len = index; */ \ + /*p_event->header.evt_len = index; */ \ + *p_event_len = evt_struct_len + evt_extended_len; \ + return NRF_SUCCESS + +/** Push an event-specific special field that contains variable length fields and get the extended data size. */ +#define SER_PULL_FIELD_EXTENDED(P_VAR, P_DECODER) \ + do \ + { \ + uint32_t field_ext_len = *p_event_len; \ + err_code = field_ext_dec(p_buf, packet_len, p_index, &field_ext_len, (P_VAR), (P_DECODER)); \ + SER_ASSERT(err_code == NRF_SUCCESS, err_code); \ + *p_event_len -= field_ext_len; \ + evt_extended_len += field_ext_len; \ + } while(0) \ + + /** Generic command response status code encoder. */ uint32_t ser_ble_cmd_rsp_status_code_enc(uint8_t op_code, uint32_t command_status, @@ -140,15 +553,101 @@ uint32_t ser_ble_cmd_rsp_dec(uint8_t const * const p_buf, uint8_t op_code, uint32_t * const p_result_code); + + +/**@brief Function for safe field encoding field. + * + * @param[in] p_field Pointer to the input struct. Must not be a null. + * @param[in] p_buf Pointer to the beginning of the output buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. + * \c out: Index in the buffer to the first byte after the encoded data. + * @param[in] fp_field_encoder Pointer to the function that implements fields encoding. + * + * @return NRF_SUCCESS Field encoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_NULL p_field or fp_field_encoder is NULL. + */ +static inline uint32_t field_enc(void const * const p_field, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + field_encoder_handler_t fp_field_encoder) +{ + SER_ASSERT_NOT_NULL(fp_field_encoder); + SER_ASSERT_NOT_NULL(p_field); + + return fp_field_encoder(p_field, p_buf, buf_len, p_index); +} + +/**@brief Function for safe field decoding. + * + * Function checks if conditional field is present in the input buffer and if it is set, it calls + * the provided parser function that attempts to parse the buffer content to the known field. + * + * @param[in] p_buf Pointer to the beginning of the input buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of uint8 value in buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in] p_field Pointer to the output location. + * @param[in] fp_field_decoder Pointer to the function that implements field decoding. + * + * @return NRF_SUCCESS Field decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_NULL p_field or fp_field_decoder is NULL. + */ +static inline uint32_t field_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_field, + field_decoder_handler_t fp_field_decoder) +{ + SER_ASSERT_NOT_NULL(fp_field_decoder); + SER_ASSERT_NOT_NULL(p_field); + + return fp_field_decoder(p_buf, buf_len, p_index, p_field); +} + +/**@brief Function for safe decoding of an event-specific field that contains extended data. + * + * Some event structures contain a variable length array (extended data), + * that may be written next to the event structure. + * + * @param[in] p_buf Pointer to the beginning of the input buffer. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in,out] p_ext_length \c in: Maximum size of extended data. + * \c out: Extended data length in bytes. + * @param[in] p_field Pointer to output location. + * @param[in] fp_field_decoder Pointer to the function that implements field decoding. + * + * @return NRF_SUCCESS Field decoded successfully. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_NULL p_field or fp_field_decoder is NULL. + */ +static inline uint32_t field_ext_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_length, + void * const p_field, + field_ext_decoder_handler_t fp_field_decoder) +{ + SER_ASSERT_NOT_NULL(fp_field_decoder); + SER_ASSERT_NOT_NULL(p_field); + + return fp_field_decoder(p_buf, buf_len, p_index, p_ext_length, p_field); +} + /**@brief Function for safe encoding an uint16 value. * - * Safe decoding of an uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe decoding of a uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * - * @param[in] p_field Uint16 value to be encoded. + * @param[in] p_field A uint16 value to be encoded. * @param[out] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint16 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint16 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -158,29 +657,29 @@ uint32_t uint16_t_enc(const void * const p_field, uint32_t buf_len, uint32_t * const p_index); -/**@brief Function for safe decoding an uint16 value. +/**@brief Function for safe decoding of a uint16 value. * - * Safe decoding of an uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe decoding of a uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * @param[in] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint16 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. - * @param[out] p_field Pointer to the location where uint16 value will be decoded. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint16 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * @param[out] p_field Pointer to the location where the uint16 value will be decoded. */ uint32_t uint16_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * p_field); -/**@brief Function for safe decoding an uint16 value. +/**@brief Function for safe decoding of a uint16 value. * - * Safe decoding of an uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe decoding of a uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * @param[in] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] index \c in: Index to start of uint16 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] index \c in: Index to the start of the uint16 value in buffer. + * \c out: Index in the buffer to the first byte after the decoded value. * @param[out] value Decoded uint16 value. */ void uint16_dec(uint8_t const * const p_buf, @@ -188,14 +687,14 @@ void uint16_dec(uint8_t const * const p_buf, uint32_t * const index, uint16_t * const value); -/**@brief Function for safe encoding an uint18 value. +/**@brief Function for safe encoding of a uint18 value. * - * Safe decoding of an uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * @param[in] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. * @param[out] p_field Pointer to uint8 value to be encoded. * * @return NRF_SUCCESS Fields decoded successfully. @@ -206,14 +705,14 @@ uint32_t uint8_t_enc(const void * const p_field, uint32_t buf_len, uint32_t * const p_index); -/**@brief Function for safe decoding an uint8 value. +/**@brief Function for safe decoding of a uint8 value. * - * Safe decoding of an uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * @param[in] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in buffer. + * \c out: Index in the buffer to the first byte after the decoded value. * @param[out] p_field Pointer to the location for decoded uint8 value. * * @return NRF_SUCCESS Fields decoded successfully. @@ -224,14 +723,14 @@ uint32_t uint8_t_dec(uint8_t const * const p_buf, uint32_t * const p_index, void * p_field); -/**@brief Function for safe decoding an uint8 value. +/**@brief Function for safe decoding of a uint8 value. * - * Safe decoding of an uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * @param[in] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. * @param[out] value Decoded uint8 value. */ void uint8_dec(uint8_t const * const p_buf, @@ -239,14 +738,14 @@ void uint8_dec(uint8_t const * const p_buf, uint32_t * const index, uint8_t * const value); -/**@brief Function for safe decoding an uint18 value. +/**@brief Function for safe decoding of a uint18 value. * - * Safe decoding of an uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * @param[in] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. * @param[out] value Decoded uint8 value. */ void int8_dec(uint8_t const * const p_buf, @@ -254,16 +753,16 @@ void int8_dec(uint8_t const * const p_buf, uint32_t * const index, int8_t * const value); -/**@brief Function for safe encoding variable length field encoded as length(8bit)+data. +/**@brief Function for safe encoding of a variable length field encoded as length(8bit) + data. * - * Safe encoding of an variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * @param[out] p_data Pointer to data to encode. * @param[in] dlen Length of data to encode (0-255). * @param[out] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -274,15 +773,15 @@ uint32_t len8data_enc(uint8_t const * const p_data, uint32_t buf_len, uint32_t * const p_index); -/**@brief Function for safe decoding variable length field encoded as length(8bit)+data. +/**@brief Function for safe decoding of a variable length field encoded as length(8bit) + data. * - * Safe decoding of an variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe decoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * @param[in] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. - * @param[out] pp_data Pointer to pointer to decoded data (p_data is set to NULL in + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. + * @param[out] pp_data Pointer to decoded data (p_data is set to NULL in * case data is not present in the buffer). * @param[out] p_len Decoded length (0-255). * @@ -295,18 +794,18 @@ uint32_t len8data_dec(uint8_t const * const p_buf, uint8_t * * const pp_data, uint8_t * const p_len); -/**@brief Function for safe encoding variable length field encoded as length(16bit)+data. +/**@brief Function for safe encoding of a variable length field encoded as length(16 bit) + data. * - * Safe encoding of an variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. - * It is possible that provided p_data is NULL in that case length is encoded and it's followed by - * SER_FIELD_NOT_PRESENT flag. SER_FIELD_PRESENT flag preceeds data otherwise. + * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * It is possible that provided p_data is NULL. In that case, length is encoded and it is followed by + * SER_FIELD_NOT_PRESENT flag. Otherwise, the SER_FIELD_PRESENT flag precedes the data. * * @param[in] p_data Data to encode. - * @param[in] dlen Input data length (16bit). + * @param[in] dlen Input data length (16 bit). * @param[in] p_buf Pointer to the beginning of the output buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the encoded data. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -317,18 +816,18 @@ uint32_t len16data_enc(uint8_t const * const p_data, uint32_t buf_len, uint32_t * const p_index); -/**@brief Function for safe decoding variable length field encoded as length(16bit)+data. +/**@brief Function for safe decoding of a variable length field encoded as length(16 bit) + data. * - * Safe decoding of an variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. - * Encoded data consist of length field, presence flag and conditional data (present only is presence flag - * is set). p_data pointer is required to be not NULL only is presence flag is set. + * Safe decoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Encoded data consists of a length field, a presence flag, and conditional data (present only if the presence flag + * is set). The p_data pointer cannot be NULL if the presence flag is set. * * @param[in] p_buf Pointer to the beginning of the input buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded data. - * @param[in] pp_data Pointer to pointer to decoded data. - * @param[in] p_dlen data length (16bit). + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in] pp_data Pointer to decoded data. + * @param[in] p_dlen Data length (16 bit). * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -340,18 +839,18 @@ uint32_t len16data_dec(uint8_t const * const p_buf, uint16_t * const p_dlen); -/**@brief Function for safe encoding of uint16 table with a given element count. +/**@brief Function for safe encoding of a uint16 table with a given element count. * - * Safe encoding of an variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. - * It is possible that provided p_data is NULL in that case length is encoded and it's followed by - * SER_FIELD_NOT_PRESENT flag. SER_FIELD_PRESENT flag precedes data otherwise. + * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * It is possible that the provided p_data is NULL. In that case, length is encoded and it is followed by a + * SER_FIELD_NOT_PRESENT flag. Otherwise, the SER_FIELD_PRESENT flag precedes the data. * * @param[in] p_data Data table to encode. * @param[in] count Table element count. * @param[in] p_buf Pointer to the beginning of the output buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the encoded data. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -363,18 +862,18 @@ uint32_t count16_cond_data16_enc(uint16_t const * const p_data, uint32_t buf_len, uint32_t * const p_index); -/**@brief Function for safe decoding of uint16 table with a given element count. +/**@brief Function for safe decoding of a uint16 table with a given element count. * - * Safe encoding of an variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. - * It is possible that provided p_data is NULL in that case length is encoded and it's followed by - * SER_FIELD_NOT_PRESENT flag. SER_FIELD_PRESENT flag precedes data otherwise. + * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * It is possible that the provided p_data is NULL. In that case, length is encoded and it is followed by a + * SER_FIELD_NOT_PRESENT flag. Otherwise, the SER_FIELD_PRESENT flag precedes the data. * * @param[in] p_buf Pointer to the beginning of the output buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the encoded data. - * @param[in] pp_data Pointer to pointer to the table to encode. - * @param[in,out] p_count Pointer to table element count - initialised with max count + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. + * @param[in] pp_data Pointer to the table to encode. + * @param[in,out] p_count Pointer to table element count - initialised with max count. * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -388,18 +887,18 @@ uint32_t count16_cond_data16_dec(uint8_t const * const p_buf, uint16_t * const p_count); -/**@brief Function for safe decoding of variable length field encoded as length(16bit)+data. +/**@brief Function for safe decoding of a variable length field encoded as length(16 bit) + data. * - * Safe decoding of an variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. - * Encoded data consist of presence flag, optional length field, second presence flag and optional data. + * Safe decoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Encoded data consists of a presence flag, an optional length field, a second presence flag, and optional data. * * * @param[in] p_buf Pointer to the beginning of the input buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded data. - * @param[out] pp_data Pointer to decoded data. - * @param[out] pp_len data length (16bit). + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[out] pp_data Pointer to decoded data. + * @param[out] pp_len Data length (16 bit). * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -411,21 +910,20 @@ uint32_t cond_len16_cond_data_dec(uint8_t const * const p_buf, uint8_t * * const pp_data, uint16_t * * const pp_len); - -/**@brief Command response encoder - replacement of - ser_ble_cmd_rsp_status_code_enc - * with layout aligned to the rest of encoder functions +/**@brief Command response encoder - replacement of ser_ble_cmd_rsp_status_code_enc + * with layout aligned to the rest of encoder functions. * - * @param[in] op_code Operation code - see BLE_GAP_SVCS - * @param[in] return_code nRF Error Code. - * @param[in] p_buff pointer to the start of pointer to decoded data. - * @param[in,out] p_buff_len \c in: size of buffer - * \c out: used bytes in buffer - * @param[in,out] p_buff_len \c in: initial offset in buffer - * \c out: final offset in buffer + * @param[in] op_code Operation code - see BLE_GAP_SVCS. + * @param[in] return_code nRF error code. + * @param[in] p_buff Pointer to the start of pointer to decoded data. + * @param[in,out] p_buff_len \c in: Size of the buffer. + * \c out: Used bytes in the buffer. + * @param[in,out] p_buff_len \c in: Initial offset in the buffer. + * \c out: Final offset in the buffer. * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_NULL Invalid pointer + * @retval NRF_ERROR_NULL Invalid pointer. */ uint32_t op_status_enc(uint8_t op_code, uint32_t return_code, @@ -433,20 +931,20 @@ uint32_t op_status_enc(uint8_t op_code, uint32_t * const p_buff_len, uint32_t * const p_index); -/**@brief command response encoder with conditional 16bit field +/**@brief Command response encoder with a conditional 16-bit field. * - * @param[in] op_code Operation code - see BLE_GAP_SVCS - * @param[in] return_code nRF Error Code. - * @param[in] value optional 16bit field encoded for return code == NRF_SUCCESS - * @param[in] p_buff pointer to the start of pointer to decoded data. - * @param[in,out] p_buff_len \c in: size of buffer - * \c out: used bytes in buffer - * @param[in,out] p_buff_len \c in: initial offset in buffer - * \c out: final offset in buffer + * @param[in] op_code Operation code - see BLE_GAP_SVCS. + * @param[in] return_code nRF error code. + * @param[in] value Optional 16-bit field encoded for return code == NRF_SUCCESS. + * @param[in] p_buff Pointer to the start of pointer to decoded data. + * @param[in,out] p_buff_len \c in: Size of the buffer. + * \c out: Used bytes in the buffer. + * @param[in,out] p_buff_len \c in: Initial offset in the buffer. + * \c out: Final offset in the buffer. * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_NULL Invalid pointer + * @retval NRF_ERROR_NULL Invalid pointer. */ uint32_t op_status_cond_uint16_enc(uint8_t op_code, @@ -456,17 +954,17 @@ uint32_t op_status_cond_uint16_enc(uint8_t op_code, uint32_t * const p_buff_len, uint32_t * const p_index); -/**@brief Function for safe encoding a buffer of known size. +/**@brief Function for safe encoding of a buffer of known size. * - * Safe encoding of a buffer. Encoder assumes that size is known to the decoder and it is not + * Safe encoding of a buffer. Encoder assumes that the size is known to the decoder and it is not * encoded here. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * @param[in] p_data Data to encode. - * @param[in] dlen Input data length (16bit). + * @param[in] dlen Input data length (16 bit). * @param[in] p_buf Pointer to the beginning of the output buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the encoded data. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -477,20 +975,20 @@ uint32_t buf_enc(uint8_t const * const p_data, uint32_t buf_len, uint32_t * const p_index); -/**@brief Function for safe decoding a buffer of known size. +/**@brief Function for safe decoding of a buffer of known size. * - * Safe decoding of buffer of known size. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. - * Encoded data consist of presence flag and conditional data (present only is presence flag - * is set). p_data pointer is required to be not NULL only is presence flag is set. Length is provided - * as an input to the function. + * Safe decoding of a buffer of known size. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Encoded data consists of a presence flag and conditional data (present only if the presence flag + * is set). The p_data pointer cannot be NULL only if the presence flag is set. Length is provided + * as input to the function. * * @param[in] p_buf Pointer to the beginning of the input buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded data. - * @param[in] pp_data Pointer to pointer to decoded data. - * @param[in] data_len Length of buffer for decoded data (16bit). - * @param[in] dlen Length of data to decode (16bit). + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in] pp_data Pointer to decoded data. + * @param[in] data_len Length of the buffer for decoded data (16 bit). + * @param[in] dlen Length of the data to decode (16 bit). * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -502,15 +1000,15 @@ uint32_t buf_dec(uint8_t const * const p_buf, uint16_t data_len, uint16_t dlen); -/**@brief Function for safe encoding an uint32 value. +/**@brief Function for safe encoding of a uint32 value. * - * Safe decoding of an uint32 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe decoding of a uint32 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * - * @param[in] p_field uint32 value to be encoded. + * @param[in] p_field A uint32 value to be encoded. * @param[out] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint32 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint32 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -520,14 +1018,14 @@ uint32_t uint32_t_enc(void const * const p_field, uint32_t buf_len, uint32_t * const p_index); -/**@brief Function for safe decoding an uint32 value. +/**@brief Function for safe decoding of a uint32 value. * - * Safe decoding of an uint32 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Safe decoding of a uint32 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * @param[in] p_buf Buffer containing the value. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint32 value in buffer. - * \c out: Index in buffer to first byte after the decoded value. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint32 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded value. * @param[out] value Decoded uint32 value. */ uint32_t uint32_t_dec(uint8_t const * const p_buf, @@ -535,16 +1033,16 @@ uint32_t uint32_t_dec(uint8_t const * const p_buf, uint32_t * const p_index, void * p_field); -/**@brief Function for safe encoding of an uint8 vector. +/**@brief Function for safe encoding of a uint8 vector. * * Range checks will be done if @ref SER_ASSERTS_ENABLED is set. * * * @param[in] p_data Data to encode. - * @param[in] dlen Input data length (16bit). + * @param[in] dlen Input data length (16 bit). * @param[in] p_buf Pointer to the beginning of the output buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the encoded data. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -555,17 +1053,17 @@ uint32_t uint8_vector_enc(uint8_t const * const p_data, uint32_t buf_len, uint32_t * const p_index); -/**@brief Function for safe decoding a an uint8 vector. +/**@brief Function for safe decoding a uint8 vector. * - * Safe decoding of buffer of known size. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. - * Vector length is provided as an input to the function. + * Safe decoding of a buffer of known size. Range checks will be done if @ref SER_ASSERTS_ENABLED is set. + * Vector length is provided as input to the function. * * @param[in] p_buf Pointer to the beginning of the input buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded data. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. * @param[in] p_data Pointer to decoded data. - * @param[in] dlen Length of data to decode (16bit). + * @param[in] dlen Length of data to decode (16 bit). * * @return NRF_SUCCESS Fields decoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. @@ -577,6 +1075,10 @@ uint32_t uint8_vector_dec(uint8_t const * const p_buf, uint16_t dlen); +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/common/cond_field_serialization.c b/components/serialization/common/cond_field_serialization.c index 4aa38f0..ca51f62 100644 --- a/components/serialization/common/cond_field_serialization.c +++ b/components/serialization/common/cond_field_serialization.c @@ -1,3 +1,42 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ #include "nrf_error.h" #include "cond_field_serialization.h" #include "ble_serialization.h" @@ -11,7 +50,7 @@ uint32_t cond_field_enc(void const * const p_field, { uint32_t err_code = NRF_SUCCESS; - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); + SER_ASSERT_LENGTH_LEQ(*p_index + 1, buf_len); p_buf[*p_index] = (p_field == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT; *p_index += 1; @@ -28,7 +67,7 @@ uint32_t cond_field_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * * const pp_field, - field_decoder_handler_t fp_field_parser) + field_decoder_handler_t fp_field_decoder) { uint32_t err_code = NRF_SUCCESS; uint8_t is_present; @@ -41,9 +80,9 @@ uint32_t cond_field_dec(uint8_t const * const p_buf, SER_ASSERT_NOT_NULL(pp_field); SER_ASSERT_NOT_NULL(*pp_field); - if (fp_field_parser != NULL) + if (fp_field_decoder != NULL) { - err_code = fp_field_parser(p_buf, buf_len, p_index, *pp_field); + err_code = fp_field_decoder(p_buf, buf_len, p_index, *pp_field); } } else if (is_present == SER_FIELD_NOT_PRESENT) diff --git a/components/serialization/common/cond_field_serialization.h b/components/serialization/common/cond_field_serialization.h index 5eb2132..a61549f 100644 --- a/components/serialization/common/cond_field_serialization.h +++ b/components/serialization/common/cond_field_serialization.h @@ -1,15 +1,51 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -#include "stdint.h" + +#ifndef COND_FIELD_SERIALIZATION_H__ +#define COND_FIELD_SERIALIZATION_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif typedef uint32_t (*field_encoder_handler_t)(void const * const p_field, uint8_t * const p_buf, @@ -21,37 +57,37 @@ typedef uint32_t (*field_decoder_handler_t)(uint8_t const * const p_buf, uint32_t * const p_index, void * p_field); -/**@brief Function for safe encoding conditional field. +/**@brief Function for safe encoding of a conditional field. * - * Function sets 'presence flag' and checks if conditional field is provided and if it is not NULL - * it calls provided parser function which attempts to encode field content to the buffer stream. + * Function sets a presence flag and checks if conditional field is provided. If the field is not NULL, + * it calls the provided parser function which attempts to encode the field content to the buffer stream. * - * @param[in] p_field Pointer to input struct. + * @param[in] p_field Pointer to the input struct. * @param[in] p_buf Pointer to the beginning of the output buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the encoded data. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the encoded data. * @param[in] fp_field_encoder Pointer to the function which implements fields encoding. * - * @return NRF_SUCCESS Fields decoded successfully. + * @return NRF_SUCCESS Fields encoded successfully. * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. */ uint32_t cond_field_enc(void const * const p_field, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index, - field_encoder_handler_t field_parser); + field_encoder_handler_t fp_field_encoder); -/**@brief Function for safe decoding conditional field. +/**@brief Function for safe decoding of a conditional field. * - * Function checks if conditional field is present in the input buffer and if it is set it calls - * provided parser function which attempts to parse buffer content to the known field. + * Function checks if conditional field is present in the input buffer. If it is set, it calls + * the provided parser function which attempts to parse the buffer content to the known field. * * @param[in] p_buf Pointer to the beginning of the input buffer. - * @param[in] buf_len Size of buffer. - * @param[in,out] p_index \c in: Index to start of uint8 value in buffer. - * \c out: Index in buffer to first byte after the decoded data. - * @param[in] pp_field Pointer to pointer to output location. + * @param[in] buf_len Size of the buffer. + * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer. + * \c out: Index in the buffer to the first byte after the decoded data. + * @param[in] pp_field Pointer to output location. * @param[in] fp_field_decoder Pointer to the function which implements field decoding. * * @return NRF_SUCCESS Fields decoded successfully. @@ -61,4 +97,10 @@ uint32_t cond_field_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * * const pp_field, - field_decoder_handler_t field_parser); + field_decoder_handler_t fp_field_decoder); + +#ifdef __cplusplus +} +#endif + +#endif // COND_FIELD_SERIALIZATION_H__ diff --git a/components/serialization/common/ser_config.h b/components/serialization/common/ser_config.h index 6e36361..1f64748 100644 --- a/components/serialization/common/ser_config.h +++ b/components/serialization/common/ser_config.h @@ -1,13 +1,41 @@ - /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SER_CONFIG_H__ @@ -17,6 +45,10 @@ #include "nrf.h" +#ifdef __cplusplus +extern "C" { +#endif + /***********************************************************************************************//** * General parameters configuration. **************************************************************************************************/ @@ -26,7 +58,7 @@ #define SER_SD_ERROR_CODE (uint32_t)(0xDEADBEEF) /** Value used as error code indicating warning - unusual situation but not critical so system - * should NOT be reseted. */ + * should NOT be reset. */ #define SER_WARNING_CODE (uint32_t)(0xBADDCAFE) /***********************************************************************************************//** @@ -69,7 +101,7 @@ #define SER_PHY_UART_PARITY true #define SER_PHY_UART_BAUDRATE UART_BAUDRATE_BAUDRATE_Baud1M -/** Find UART baudrate value based on chosen register setting. */ +/** Find UART baud rate value based on the chosen register setting. */ #if (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud1200) #define SER_PHY_UART_BAUDRATE_VAL 1200uL #elif (SER_PHY_UART_BAUDRATE == UART_BAUDRATE_BAUDRATE_Baud2400) @@ -104,19 +136,15 @@ #define SER_PHY_UART_BAUDRATE_VAL 1000000uL #endif /* SER_PHY_UART_BAUDRATE */ -/** Configuration timeouts of connectivity MCU */ -#define CONN_CHIP_RESET_TIME 50 /**< The time to keep the reset line to the nRF51822 low (in milliseconds). */ -#define CONN_CHIP_WAKEUP_TIME 500 /**< The time for nRF51822 to reset and become ready to receive serialized commands (in milliseconds). */ - -#ifdef S110 - #define SER_MAX_CONNECTIONS 1 -#else - #ifdef S120 - #define SER_MAX_CONNECTIONS 8 - #endif - #ifdef S130 - #define SER_MAX_CONNECTIONS 1 - #endif +/** Configuration timeouts of connectivity MCU. */ +#define CONN_CHIP_RESET_TIME 50 /**< Time to keep the reset line to the connectivity chip low (in milliseconds). */ +#define CONN_CHIP_WAKEUP_TIME 500 /**< Time for the connectivity chip to reset and become ready to receive serialized commands (in milliseconds). */ + +#define SER_MAX_CONNECTIONS 8 + + +#ifdef __cplusplus +} #endif #endif /* SER_CONFIG_H__ */ diff --git a/components/serialization/common/ser_dbg_sd_str.c b/components/serialization/common/ser_dbg_sd_str.c new file mode 100644 index 0000000..ad67956 --- /dev/null +++ b/components/serialization/common/ser_dbg_sd_str.c @@ -0,0 +1,268 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ +#include "ser_dbg_sd_str.h" +#include "ble_ranges.h" +#include "nrf_soc.h" +#include "nrf_log.h" +#include +#include "sdk_common.h" + +#if NRF_MODULE_ENABLED(NRF_LOG) +static const char * sd_events[] = { + "BLE_EVT_TX_COMPLETE", /*0x01*/ + "BLE_EVT_USER_MEM_REQUEST", /*0x02*/ + "BLE_EVT_USER_MEM_RELEASE", /*0x03*/ + "BLE_EVT_DATA_LENGTH_CHANGED", /*0x04*/ + "SD_EVT_UNKNOWN", /*0x05*/ + "SD_EVT_UNKNOWN", /*0x06*/ + "SD_EVT_UNKNOWN", /*0x07*/ + "SD_EVT_UNKNOWN", /*0x08*/ + "SD_EVT_UNKNOWN", /*0x09*/ + "SD_EVT_UNKNOWN", /*0x0a*/ + "SD_EVT_UNKNOWN", /*0x0b*/ + "SD_EVT_UNKNOWN", /*0x0c*/ + "SD_EVT_UNKNOWN", /*0x0d*/ + "SD_EVT_UNKNOWN", /*0x0e*/ + "SD_EVT_UNKNOWN", /*0x0f*/ + "BLE_GAP_EVT_CONNECTED", /*0x10*/ + "BLE_GAP_EVT_DISCONNECTED", /*0x11*/ + "BLE_GAP_EVT_CONN_PARAM_UPDATE", /*0x12*/ + "BLE_GAP_EVT_SEC_PARAMS_REQUEST", /*0x13*/ + "BLE_GAP_EVT_SEC_INFO_REQUEST", /*0x14*/ + "BLE_GAP_EVT_PASSKEY_DISPLAY", /*0x15*/ + "BLE_GAP_EVT_KEY_PRESxSED", /*0x16*/ + "BLE_GAP_EVT_AUTH_KEY_REQUEST", /*0x17*/ + "BLE_GAP_EVT_LESC_DHKEY_REQUEST", /*0x18*/ + "BLE_GAP_EVT_AUTH_STATUS", /*0x19*/ + "BLE_GAP_EVT_CONN_SEC_UPDATE", /*0x1a*/ + "BLE_GAP_EVT_TIMEOUT", /*0x1b*/ + "BLE_GAP_EVT_RSSI_CHANGED", /*0x1c*/ + "BLE_GAP_EVT_ADV_REPORT", /*0x1d*/ + "BLE_GAP_EVT_SEC_REQUEST", /*0x1e*/ + "BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST", /*0x1f*/ + "BLE_GAP_EVT_SCAN_REQ_REPORT", /*0x20*/ + "SD_EVT_UNKNOWN", /*0x21*/ + "SD_EVT_UNKNOWN", /*0x22*/ + "SD_EVT_UNKNOWN", /*0x23*/ + "SD_EVT_UNKNOWN", /*0x24*/ + "SD_EVT_UNKNOWN", /*0x25*/ + "SD_EVT_UNKNOWN", /*0x26*/ + "SD_EVT_UNKNOWN", /*0x27*/ + "SD_EVT_UNKNOWN", /*0x28*/ + "SD_EVT_UNKNOWN", /*0x29*/ + "SD_EVT_UNKNOWN", /*0x2a*/ + "SD_EVT_UNKNOWN", /*0x2b*/ + "SD_EVT_UNKNOWN", /*0x2c*/ + "SD_EVT_UNKNOWN", /*0x2d*/ + "SD_EVT_UNKNOWN", /*0x2e*/ + "SD_EVT_UNKNOWN", /*0x2f*/ + "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP", /*0x30*/ + "BLE_GATTC_EVT_REL_DISC_RSP", /*0x31*/ + "BLE_GATTC_EVT_CHAR_DISC_RSP", /*0x32*/ + "BLE_GATTC_EVT_DESC_DISC_RSP", /*0x33*/ + "BLE_GATTC_EVT_ATTR_INFO_DISC_RSP", /*0x34*/ + "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP", /*0x35*/ + "BLE_GATTC_EVT_READ_RSP", /*0x36*/ + "BLE_GATTC_EVT_CHAR_VALS_READ_RSP", /*0x37*/ + "BLE_GATTC_EVT_WRITE_RSP", /*0x38*/ + "BLE_GATTC_EVT_HVX", /*0x39*/ + "BLE_GATTC_EVT_EXCHANGE_MTU_RSP", /*0x3a*/ + "BLE_GATTC_EVT_TIMEOUT", /*0x3b*/ + "SD_EVT_UNKNOWN", /*0x3c*/ + "SD_EVT_UNKNOWN", /*0x3d*/ + "SD_EVT_UNKNOWN", /*0x3e*/ + "SD_EVT_UNKNOWN", /*0x3f*/ + "SD_EVT_UNKNOWN", /*0x40*/ + "SD_EVT_UNKNOWN", /*0x41*/ + "SD_EVT_UNKNOWN", /*0x42*/ + "SD_EVT_UNKNOWN", /*0x43*/ + "SD_EVT_UNKNOWN", /*0x44*/ + "SD_EVT_UNKNOWN", /*0x45*/ + "SD_EVT_UNKNOWN", /*0x46*/ + "SD_EVT_UNKNOWN", /*0x47*/ + "SD_EVT_UNKNOWN", /*0x48*/ + "SD_EVT_UNKNOWN", /*0x49*/ + "SD_EVT_UNKNOWN", /*0x4a*/ + "SD_EVT_UNKNOWN", /*0x4b*/ + "SD_EVT_UNKNOWN", /*0x4c*/ + "SD_EVT_UNKNOWN", /*0x4d*/ + "SD_EVT_UNKNOWN", /*0x4e*/ + "SD_EVT_UNKNOWN", /*0x4f*/ + "BLE_GATTS_EVT_WRITE", /*0x50*/ + "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST", /*0x51*/ + "BLE_GATTS_EVT_SYS_ATTR_MISSING", /*0x52*/ + "BLE_GATTS_EVT_HVC", /*0x53*/ + "BLE_GATTS_EVT_SC_CONFIRM", /*0x54*/ + "BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST", /*0x55*/ + "BLE_GATTS_EVT_TIMEOUT", /*0x56*/ +}; + +static const char * sd_functions[] = { + /* 0x60 offset */ + "SD_BLE_ENABLE", /*0x60*/ + "SD_BLE_EVT_GET", /*0x61*/ + "SD_BLE_TX_PACKET_COUNT_GET", /*0x62*/ + "SD_BLE_UUID_VS_ADD", /*0x63*/ + "SD_BLE_UUID_DECODE", /*0x64*/ + "SD_BLE_UUID_ENCODE", /*0x65*/ + "SD_BLE_VERSION_GET", /*0x66*/ + "SD_BLE_USER_MEM_REPLY", /*0x67*/ + "SD_BLE_OPT_SET", /*0x68*/ + "SD_BLE_OPT_GET", /*0x69*/ + "SD_UNKNOWN", /*0x6A*/ + "SD_UNKNOWN", /*0x6B*/ + "SD_BLE_GAP_ADDRESS_SET", /*0x6C*/ + "SD_BLE_GAP_ADDRESS_GET", /*0x6D*/ + "SD_BLE_GAP_WHITELIST_SET", /*0x6E*/ + "SD_BLE_GAP_DEVICE_IDENTITIES_SET", /*0x6F*/ + "SD_BLE_GAP_PRIVACY_SET", /*0x70*/ + "SD_BLE_GAP_PRIVACY_GET", /*0x71*/ + "SD_BLE_GAP_ADV_DATA_SET", /*0x72*/ + "SD_BLE_GAP_ADV_START", /*0x73*/ + "SD_BLE_GAP_ADV_STOP", /*0x74*/ + "SD_BLE_GAP_CONN_PARAM_UPDATE", /*0x75*/ + "SD_BLE_GAP_DISCONNECT", /*0x76*/ + "SD_BLE_GAP_TX_POWER_SET", /*0x77*/ + "SD_BLE_GAP_APPEARANCE_SET", /*0x78*/ + "SD_BLE_GAP_APPEARANCE_GET", /*0x79*/ + "SD_BLE_GAP_PPCP_SET", /*0x7a*/ + "SD_BLE_GAP_PPCP_GET", /*0x7b*/ + "SD_BLE_GAP_DEVICE_NAME_SET", /*0x7c*/ + "SD_BLE_GAP_DEVICE_NAME_GET", /*0x7d*/ + "SD_BLE_GAP_AUTHENTICATE", /*0x7e*/ + "SD_BLE_GAP_SEC_PARAMS_REPLY", /*0x7f*/ + "SD_BLE_GAP_AUTH_KEY_REPLY", /*0x80*/ + "SD_BLE_GAP_LESC_DHKEY_REPLY", /*0x81*/ + "SD_BLE_GAP_KEYPRESS_NOTIFY", /*0x82*/ + "SD_BLE_GAP_LESC_OOB_DATA_GET", /*0x83*/ + "SD_BLE_GAP_LESC_OOB_DATA_SET", /*0x84*/ + "SD_BLE_GAP_ENCRYPT", /*0x85*/ + "SD_BLE_GAP_SEC_INFO_REPLY", /*0x86*/ + "SD_BLE_GAP_CONN_SEC_GET", /*0x87*/ + "SD_BLE_GAP_RSSI_START", /*0x88*/ + "SD_BLE_GAP_RSSI_STOP", /*0x89*/ + "SD_BLE_GAP_SCAN_START", /*0x8a*/ + "SD_BLE_GAP_SCAN_STOP", /*0x8b*/ + "SD_BLE_GAP_CONNECT", /*0x8c*/ + "SD_BLE_GAP_CONNECT_CANCEL", /*0x8d*/ + "SD_BLE_GAP_RSSI_GET", /*0x8e*/ + "SD_UNKNOWN", /*0x8f*/ + "SD_UNKNOWN", /*0x90*/ + "SD_UNKNOWN", /*0x91*/ + "SD_UNKNOWN", /*0x92*/ + "SD_UNKNOWN", /*0x93*/ + "SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER", /*0x94*/ + "SD_BLE_GATTC_RELATIONSHIPS_DISCOVER", /*0x95*/ + "SD_BLE_GATTC_CHARACTERISTICS_DISCOVER", /*0x96*/ + "SD_BLE_GATTC_DESCRIPTORS_DISCOVER", /*0x97*/ + "SD_BLE_GATTC_ATTR_INFO_DISCOVER", /*0x98*/ + "SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ", /*0x99*/ + "SD_BLE_GATTC_READ", /*0x9A*/ + "SD_BLE_GATTC_CHAR_VALUES_READ", /*0x9b*/ + "SD_BLE_GATTC_WRITE", /*0x9c*/ + "SD_BLE_GATTC_HV_CONFIRM", /*0x9d*/ + "SD_BLE_GATTC_EXCHANGE_MTU_REQUEST", /*0x9e*/ + "SD_UNKNOWN", /*0x9F*/ + "SD_BLE_GATTS_SERVICE_ADD", /*0xA0*/ + "SD_BLE_GATTS_INCLUDE_ADD", /*0xA1*/ + "SD_BLE_GATTS_CHARACTERISTIC_ADD", /*0xA2*/ + "SD_BLE_GATTS_DESCRIPTOR_ADD", /*0xA3*/ + "SD_BLE_GATTS_VALUE_SET", /*0xA4*/ + "SD_BLE_GATTS_VALUE_GET", /*0xA5*/ + "SD_BLE_GATTS_HVX", /*0xA6*/ + "SD_BLE_GATTS_SERVICE_CHANGED", /*0xA7*/ + "SD_BLE_GATTS_RW_AUTHORIZE_REPLY", /*0xA8*/ + "SD_BLE_GATTS_SYS_ATTR_SET", /*0xA9*/ + "SD_BLE_GATTS_SYS_ATTR_GET", /*0xAa*/ + "SD_BLE_GATTS_INITIAL_USER_HANDLE_GET", /*0xAb*/ + "SD_BLE_GATTS_ATTR_GET", /*0xAc*/ + "SD_BLE_GATTS_EXCHANGE_MTU_REPLY", /*0xAd*/ +}; +#endif + +const char * ser_dbg_sd_call_str_get(uint8_t opcode) +{ +#if NRF_MODULE_ENABLED(NRF_LOG) + const char * p_str = "SD_CALL_UNKNOWN"; + if (opcode >= BLE_SVC_BASE && opcode <= BLE_GATTS_SVC_LAST) + { + uint32_t idx = opcode-BLE_SVC_BASE; + if (idx < ARRAY_SIZE(sd_functions) ) + { + p_str = sd_functions[idx]; + } + } + else + { + switch (opcode) + { + case SD_ECB_BLOCK_ENCRYPT: + p_str = "SD_ECB_BLOCK_ENCRYPT"; + break; + case SD_TEMP_GET: + p_str = "SD_TEMP_GET"; + break; + default: + break; + } + } + return p_str; +#else + return NULL; +#endif +} + +const char * ser_dbg_sd_evt_str_get(uint16_t opcode) +{ +#if NRF_MODULE_ENABLED(NRF_LOG) + const char * p_str = "SD_EVT_UNKNOWN"; + if (opcode >= BLE_EVT_BASE && opcode <= BLE_GATTS_EVT_LAST) + { + uint32_t idx = opcode - BLE_EVT_BASE; + if (idx < ARRAY_SIZE(sd_events)) + { + p_str = sd_events[idx]; + } + } + return p_str; +#else + return NULL; +#endif +} diff --git a/components/serialization/common/ser_dbg_sd_str.h b/components/serialization/common/ser_dbg_sd_str.h new file mode 100644 index 0000000..8b9bd2f --- /dev/null +++ b/components/serialization/common/ser_dbg_sd_str.h @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SER_DBG_SD_STR_H +#define SER_DBG_SD_STR_H +#include +const char * ser_dbg_sd_call_str_get(uint8_t opcode); +const char * ser_dbg_sd_evt_str_get(uint16_t opcode); +#endif //SER_DBG_SD_STR_H diff --git a/components/serialization/common/struct_ser/s110/ble_gap_struct_serialization.c b/components/serialization/common/struct_ser/s110/ble_gap_struct_serialization.c deleted file mode 100644 index 20beb5f..0000000 --- a/components/serialization/common/struct_ser/s110/ble_gap_struct_serialization.c +++ /dev/null @@ -1,1365 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_struct_serialization.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" -#include "string.h" - -uint32_t ble_gap_irk_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_irk_t * p_gap_irk = (ble_gap_irk_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN, buf_len - *p_index); - - memcpy(&p_buf[*p_index], p_gap_irk->irk, BLE_GAP_SEC_KEY_LEN); - - *p_index += BLE_GAP_SEC_KEY_LEN; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_irk_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - ble_gap_irk_t * p_gap_irk = (ble_gap_irk_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN, buf_len - *p_index); - - memcpy(p_gap_irk->irk, &p_buf[*p_index], BLE_GAP_SEC_KEY_LEN); - - *p_index += BLE_GAP_SEC_KEY_LEN; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_addr_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_addr_t * p_addr = (ble_gap_addr_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(1 + BLE_GAP_ADDR_LEN, buf_len - *p_index); - - p_buf[*p_index] = p_addr->addr_type; - (*p_index)++; - memcpy(&p_buf[*p_index], p_addr->addr, BLE_GAP_ADDR_LEN); - *p_index += BLE_GAP_ADDR_LEN; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_addr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_addr) -{ - ble_gap_addr_t * p_address = (ble_gap_addr_t *) p_addr; - - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_addr_t), buf_len - *p_index); - memcpy(p_address, &p_buf[*p_index], sizeof (ble_gap_addr_t)); - *p_index += sizeof (ble_gap_addr_t); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sec_levels_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_sec_levels_t * p_sec_levels = (ble_gap_sec_levels_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - - p_buf[*p_index] = (p_sec_levels->lv1 << 0) | (p_sec_levels->lv2 << 1) | (p_sec_levels->lv3 << 2); - (*p_index)++; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sec_levels_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - ble_gap_sec_levels_t * p_sec_levels = (ble_gap_sec_levels_t *)p_data; - uint32_t err_code; - uint32_t uint8_temp; - - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_sec_levels_t), buf_len - *p_index); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &(uint8_temp)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_sec_levels->lv1 = uint8_temp & 0x01; - p_sec_levels->lv2 = (uint8_temp >> 1) & 0x01; - p_sec_levels->lv3 = (uint8_temp >> 2) & 0x01; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sec_keys_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_sec_keys_t * p_sec_keys = (ble_gap_sec_keys_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_enc(p_sec_keys->p_enc_key, p_buf, buf_len, p_index, ble_gap_enc_key_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_keys->p_id_key, p_buf, buf_len, p_index, ble_gap_id_key_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_keys->p_sign_key, p_buf, buf_len, p_index, ble_gap_sign_info_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_keys_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - ble_gap_sec_keys_t * p_sec_keys = (ble_gap_sec_keys_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void * *)&(p_sec_keys->p_enc_key), ble_gap_enc_key_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void * *)&(p_sec_keys->p_id_key), ble_gap_id_key_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void * *)&(p_sec_keys->p_sign_key), ble_gap_sign_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -//uint32_t ble_gap_enc_info_enc(void const * const p_data, -// uint8_t * const p_buf, -// uint32_t buf_len, -// uint32_t * const p_index) -//{ -// uint32_t err_code; -// ble_gap_enc_info_t * p_enc_info = (ble_gap_enc_info_t *)p_data; - -// SER_ASSERT_LENGTH_LEQ(2 + BLE_GAP_SEC_KEY_LEN + 1, buf_len - *p_index); - -// err_code = uint16_t_enc(&p_enc_info->div, p_buf, buf_len, p_index); -// SER_ASSERT(err_code == NRF_SUCCESS, err_code); - -// memcpy(&p_buf[*p_index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); -// *p_index += BLE_GAP_SEC_KEY_LEN; - -// p_buf[*p_index] = p_enc_info->auth & 0x01; -// p_buf[*p_index] |= (p_enc_info->ltk_len & 0x7F) << 1; -// (*p_index)++; - -// return err_code; -//} - -//uint32_t ble_gap_enc_info_dec(uint8_t const * const p_buf, -// uint32_t buf_len, -// uint32_t * const p_index, -// void * const p_enc_info) -//{ -// ble_gap_enc_info_t * p_enc_info2 = (ble_gap_enc_info_t *)p_enc_info; - -// SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); -// uint16_dec(p_buf, buf_len, p_index, &p_enc_info2->div); - -// SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN, buf_len - *p_index); -// memcpy(p_enc_info2->ltk, &p_buf[*p_index], BLE_GAP_SEC_KEY_LEN); -// *p_index += BLE_GAP_SEC_KEY_LEN; - -// SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); -// p_enc_info2->auth = p_buf[*p_index] & 0x01; -// p_enc_info2->ltk_len = (p_buf[*p_index] >> 1) & 0x7F; -// *p_index += 1; - -// return NRF_SUCCESS; -//} - -uint32_t ble_gap_sign_info_enc(void const * const p_sign_info, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_sign_info_t), buf_len - *p_index); - memcpy(&p_buf[*p_index], p_sign_info, sizeof (ble_gap_sign_info_t)); - *p_index += sizeof (ble_gap_sign_info_t); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sign_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_sign_info) -{ - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_sign_info_t), buf_len - *p_index); - memcpy(p_sign_info, &p_buf[*p_index], sizeof (ble_gap_sign_info_t)); - *p_index += sizeof (ble_gap_sign_info_t); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - ble_gap_evt_auth_status_t * p_auth_status = (ble_gap_evt_auth_status_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(6, buf_len - *p_index); - - err_code = uint8_t_enc(&(p_auth_status->auth_status), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - byte = (p_auth_status->error_src) | ((p_auth_status->bonded) << 2); - - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_levels_enc(&(p_auth_status->sm1_levels), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_levels_enc(&(p_auth_status->sm2_levels), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc(&(p_auth_status->kdist_periph), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc(&(p_auth_status->kdist_central), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - - ble_gap_evt_auth_status_t * p_auth_status = (ble_gap_evt_auth_status_t *)p_data; - uint32_t err_code; - uint8_t byte; - - SER_ASSERT_LENGTH_LEQ(6, buf_len - *p_index); - SER_ASSERT_NOT_NULL(p_auth_status); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_auth_status->auth_status)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_auth_status->error_src = byte & 0x03; - p_auth_status->bonded = (byte >> 2) & 0x01 ; - - err_code = ble_gap_sec_levels_dec(p_buf, buf_len, p_index, &(p_auth_status->sm1_levels)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_levels_dec(p_buf, buf_len, p_index, &(p_auth_status->sm2_levels)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, &(p_auth_status->kdist_periph)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, &(p_auth_status->kdist_central)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_conn_sec_mode_enc(void const * const p_void_sec_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_conn_sec_mode_t * p_sec_mode = (ble_gap_conn_sec_mode_t *)p_void_sec_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8 = p_sec_mode->sm | (p_sec_mode->lv << 4); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_conn_sec_mode_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_mode) -{ - ble_gap_conn_sec_mode_t * p_sec_mode = (ble_gap_conn_sec_mode_t *)p_void_sec_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &temp8); - - p_sec_mode->sm = temp8; - p_sec_mode->lv = temp8 >> 4; - - return err_code; -} - -uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_conn_sec_update, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_conn_sec_t_enc(p_void_conn_sec_update, p_buf, buf_len, p_index); -} - -uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_conn_sec_update) -{ - return ble_gap_conn_sec_t_dec(p_buf, buf_len, p_index, p_void_conn_sec_update); -} - -uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_sec, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_conn_sec_t * p_conn_sec = (ble_gap_conn_sec_t *)p_void_sec; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_conn_sec_mode_enc(&p_conn_sec->sec_mode, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_conn_sec->encr_key_size, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec) -{ - ble_gap_conn_sec_t * p_conn_sec = (ble_gap_conn_sec_t *)p_void_sec; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_conn_sec->sec_mode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &p_conn_sec->encr_key_size); - - return err_code; -} - -uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_sec_info_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_evt_sec_info_request_t * p_conn_sec = - (ble_gap_evt_sec_info_request_t *)p_void_sec_info_request; - - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_addr_enc(&p_conn_sec->peer_addr, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_enc(&p_conn_sec->master_id, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint8_t temp8 = p_conn_sec->enc_info | - (p_conn_sec->id_info << 1) | - (p_conn_sec->sign_info << 2); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_info_request) -{ - ble_gap_evt_sec_info_request_t * p_conn_sec = (ble_gap_evt_sec_info_request_t *)p_void_sec_info_request; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_conn_sec->peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_dec(p_buf, buf_len, p_index, &(p_conn_sec->master_id)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &temp8); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_conn_sec->enc_info = temp8 & 0x01; - p_conn_sec->id_info = (temp8 >> 1) & 0x01; - p_conn_sec->sign_info = (temp8 >> 2) & 0x01; - - return err_code; -} - -uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_evt_connected_t * p_evt_conn = (ble_gap_evt_connected_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte = 0; - - err_code = ble_gap_addr_enc((void *)&p_evt_conn->peer_addr, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc((void *)&p_evt_conn->own_addr, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - byte = p_evt_conn->irk_match | (p_evt_conn->irk_match_idx << 1); - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_conn_params_t_enc((void *)&p_evt_conn->conn_params, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_connected) -{ - ble_gap_evt_connected_t * p_evt_conn = (ble_gap_evt_connected_t *)p_void_connected; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte = 0; - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_evt_conn->peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_evt_conn->own_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_evt_conn->irk_match = byte & 0x01; - p_evt_conn->irk_match_idx = (byte & 0xFE) >> 1; - - err_code = ble_gap_conn_params_t_dec(p_buf, buf_len, p_index, &(p_evt_conn->conn_params)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_sec_params_t * p_sec_params = (ble_gap_sec_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - temp8 = (p_sec_params->bond & 0x01) | - ((p_sec_params->mitm & 0x01) << 1) | - ((p_sec_params->io_caps & 0x07) << 2) | - ((p_sec_params->oob & 0x01) << 5); - - err_code = uint8_t_enc((void *) &temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *) &(p_sec_params->min_key_size), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *) &(p_sec_params->max_key_size), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc((void *) &(p_sec_params->kdist_periph), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc((void *) &(p_sec_params->kdist_central), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gap_sec_params_t * p_sec_params = (ble_gap_sec_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &temp8); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_sec_params->bond = temp8 & 0x01; - p_sec_params->mitm = (temp8 >> 1) & 0x01; - p_sec_params->io_caps = (temp8 >> 2) & 0x07; - p_sec_params->oob = (temp8 >> 5) & 0x01; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->min_key_size)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->max_key_size)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->kdist_periph)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->kdist_central)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_sec_params_t_enc(p_void_struct, p_buf, buf_len, p_index); -} - -uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - return ble_gap_sec_params_t_dec(p_buf, buf_len, p_index, p_void_struct); -} - -uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_evt_conn_param_update, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_conn_params_t_enc(p_void_evt_conn_param_update, p_buf, buf_len, p_index); -} - -uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_evt_conn_param_update) -{ - return ble_gap_conn_params_t_dec(p_buf, buf_len, p_index, p_void_evt_conn_param_update); -} - -uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_evt_conn_param_update_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_conn_params_t_enc(p_void_evt_conn_param_update_request, p_buf, buf_len, p_index); -} - -uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_evt_conn_param_update_request) -{ - return ble_gap_conn_params_t_dec(p_buf, buf_len, p_index, p_void_evt_conn_param_update_request); -} - -uint32_t ble_gap_conn_params_t_enc(void const * const p_void_conn_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_conn_params_t * p_conn_params = (ble_gap_conn_params_t *)p_void_conn_params; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_conn_params->min_conn_interval, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_conn_params->max_conn_interval, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_conn_params->slave_latency, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_conn_params->conn_sup_timeout, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_conn_params) -{ - ble_gap_conn_params_t * p_conn_params = (ble_gap_conn_params_t *)p_void_conn_params; - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->min_conn_interval); - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->max_conn_interval); - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->slave_latency); - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->conn_sup_timeout); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_disconnected, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_evt_disconnected_t * p_disconnected = (ble_gap_evt_disconnected_t *)p_void_disconnected; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&p_disconnected->reason, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_disconnected) -{ - ble_gap_evt_disconnected_t * p_disconnected = (ble_gap_evt_disconnected_t *)p_void_disconnected; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &p_disconnected->reason); - - return err_code; -} - -uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_ch_map_t * p_gap_opt_ch_map = (ble_gap_opt_ch_map_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_gap_opt_ch_map->conn_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(5, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_gap_opt_ch_map->ch_map, 5); - - *p_index += 5; - - return err_code; -} - -uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_ch_map_t * p_gap_opt_ch_map = (ble_gap_opt_ch_map_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &p_gap_opt_ch_map->conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(5, buf_len - *p_index); - memcpy(p_gap_opt_ch_map->ch_map, &p_buf[*p_index], 5); - - *p_index += 5; - - return err_code; -} - -uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_local_conn_latency, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_local_conn_latency_t * p_latency = - (ble_gap_opt_local_conn_latency_t *)p_void_local_conn_latency; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_latency->conn_handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_latency->requested_latency), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_latency->p_actual_latency, p_buf, buf_len, p_index, uint16_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_local_conn_latency) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_local_conn_latency_t * p_latency = - (ble_gap_opt_local_conn_latency_t *)p_void_local_conn_latency; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_latency->conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_latency->requested_latency)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_latency->p_actual_latency), - uint16_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_passkey, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_passkey_t * p_opt_passkey = (ble_gap_opt_passkey_t *)p_void_passkey; - uint32_t err_code = NRF_SUCCESS; - uint16_t passkey_len = BLE_GAP_PASSKEY_LEN; - - err_code = buf_enc(p_opt_passkey->p_passkey, passkey_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_passkey) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_passkey_t * p_opt_passkey = (ble_gap_opt_passkey_t *)p_void_passkey; - uint32_t err_code = NRF_SUCCESS; - uint16_t passkey_len = BLE_GAP_PASSKEY_LEN; - - err_code = buf_dec(p_buf, buf_len, p_index, &p_opt_passkey->p_passkey, passkey_len, - passkey_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_privacy_t_enc(void const * const p_void_privacy, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_privacy_t * p_privacy = (ble_gap_opt_privacy_t *)p_void_privacy; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_enc(p_privacy->p_irk, p_buf, buf_len, p_index, ble_gap_irk_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_privacy->interval_s), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_privacy_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_privacy) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_privacy_t * p_privacy = (ble_gap_opt_privacy_t *)p_void_privacy; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_privacy->p_irk), ble_gap_irk_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_privacy->interval_s)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_scan_req_report, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_scan_req_report_t * p_scan_req_report = (ble_gap_opt_scan_req_report_t *)p_void_scan_req_report; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_scan_req_report->enable; - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_scan_req_report) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_scan_req_report_t * p_scan_req_report = (ble_gap_opt_scan_req_report_t *)p_void_scan_req_report; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_scan_req_report->enable = byte & 0x01; - - return err_code; -} - -uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_compat_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_compat_mode_t * p_compat_mode = (ble_gap_opt_compat_mode_t *)p_void_compat_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_compat_mode->mode_1_enable; - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_compat_mode) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_compat_mode_t * p_compat_mode = (ble_gap_opt_compat_mode_t *)p_void_compat_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_compat_mode->mode_1_enable = byte & 0x01; - - return err_code; -} - -uint32_t ble_gap_sec_kdist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_kdist_t * p_sec_kdist = (ble_gap_sec_kdist_t *) p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - - p_buf[*p_index] = p_sec_kdist->enc & 0x01; - p_buf[*p_index] |= (p_sec_kdist->id & 0x01) << 1; - p_buf[*p_index] |= (p_sec_kdist->sign & 0x01) << 2; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_kdist_t * p_sec_kdist = (ble_gap_sec_kdist_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_sec_kdist->enc = p_buf[*p_index] & 0x01; - p_sec_kdist->id = (p_buf[*p_index] >> 1) & 0x01; - p_sec_kdist->sign = (p_buf[*p_index] >> 2) & 0x01; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_master_id_t_enc(void const * const p_master_idx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_master_id_t * p_master_id = (ble_gap_master_id_t *) p_master_idx; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_master_id->ediv), p_buf, buf_len, p_index); - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_RAND_LEN, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_master_id->rand, BLE_GAP_SEC_RAND_LEN); - *p_index += BLE_GAP_SEC_RAND_LEN; - - return err_code; -} - -uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_master_idx) -{ - ble_gap_master_id_t *p_master_id = (ble_gap_master_id_t *)p_master_idx; - - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_master_id->ediv)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_RAND_LEN, buf_len - *p_index); - memcpy(p_master_id->rand, &p_buf[*p_index], BLE_GAP_SEC_RAND_LEN); - *p_index += BLE_GAP_SEC_RAND_LEN; - - return err_code; -} - -uint32_t ble_gap_enc_info_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - ble_gap_enc_info_t * p_enc_info = (ble_gap_enc_info_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN + 1, buf_len - *p_index); - - memcpy(&p_buf[*p_index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); - *p_index += BLE_GAP_SEC_KEY_LEN; - - p_buf[*p_index] = p_enc_info->auth & 0x01; - p_buf[*p_index] |= (p_enc_info->ltk_len & 0x7F) << 1; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_enc_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_enc_infox) -{ - ble_gap_enc_info_t * p_enc_info = (ble_gap_enc_info_t *)p_enc_infox; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN, buf_len - *p_index); - memcpy(p_enc_info->ltk, &p_buf[*p_index], BLE_GAP_SEC_KEY_LEN); - *p_index += BLE_GAP_SEC_KEY_LEN; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_enc_info->auth = p_buf[*p_index] & 0x01; - p_enc_info->ltk_len = (p_buf[*p_index] >> 1) & 0x7F; - *p_index += 1; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_enc_key_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_enc_key_t * p_enc_key = (ble_gap_enc_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_enc_info_enc(&(p_enc_key->enc_info), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_enc(&(p_enc_key->master_id), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_enc_key_t * p_enc_key = (ble_gap_enc_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_enc_info_dec(p_buf, buf_len, p_index, &(p_enc_key->enc_info)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_dec(p_buf, buf_len, p_index, &(p_enc_key->master_id)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_id_key_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_id_key_t * p_id_key = (ble_gap_id_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_irk_enc(&(p_id_key->id_info), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc(&(p_id_key->id_addr_info), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_id_key_t * p_id_key = (ble_gap_id_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_irk_dec(p_buf, buf_len, p_index, &(p_id_key->id_info)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_id_key->id_addr_info)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_keyset_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_keyset_t * p_sec_keyset = (ble_gap_sec_keyset_t *) p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_sec_keys_enc(&(p_sec_keyset->keys_periph), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keys_enc(&(p_sec_keyset->keys_central), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_keyset_t * p_sec_keyset = (ble_gap_sec_keyset_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_sec_keys_dec(p_buf, buf_len, p_index, &(p_sec_keyset->keys_periph)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keys_dec(p_buf, buf_len, p_index, &(p_sec_keyset->keys_central)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_whitelist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_whitelist_t *p_whitelist = (ble_gap_whitelist_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - uint32_t i = 0; - - SER_ERROR_CHECK(p_whitelist->addr_count <= BLE_GAP_WHITELIST_ADDR_MAX_COUNT, - NRF_ERROR_INVALID_PARAM); - SER_ERROR_CHECK(p_whitelist->irk_count <= BLE_GAP_WHITELIST_IRK_MAX_COUNT, - NRF_ERROR_INVALID_PARAM); - - err_code = uint8_t_enc(&(p_whitelist->addr_count), p_buf, buf_len, p_index); - - err_code = cond_field_enc(p_whitelist->pp_addrs, p_buf, buf_len, p_index, NULL); - - for (i = 0; i < p_whitelist->addr_count; i++) - { - err_code = cond_field_enc(p_whitelist->pp_addrs[i], p_buf, buf_len, p_index, ble_gap_addr_enc); - } - - err_code = uint8_t_enc(&(p_whitelist->irk_count), p_buf, buf_len, p_index); - - err_code = cond_field_enc(p_whitelist->pp_irks, p_buf, buf_len, p_index, NULL); - - for (i = 0; i < p_whitelist->irk_count; i++) - { - err_code = cond_field_enc(p_whitelist->pp_irks[i], p_buf, buf_len, p_index, ble_gap_irk_enc); - } - - return err_code; -} - -uint32_t ble_gap_whitelist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_whitelist_t * p_whitelist = (ble_gap_whitelist_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - uint32_t i = 0; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_whitelist->addr_count)); - SER_ERROR_CHECK(p_whitelist->addr_count <= BLE_GAP_WHITELIST_ADDR_MAX_COUNT, - NRF_ERROR_INVALID_LENGTH); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_addrs), NULL); - - for (i = 0; i < p_whitelist->addr_count; i++) - { - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_addrs[i]), ble_gap_addr_dec); - } - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_whitelist->irk_count)); - SER_ERROR_CHECK(p_whitelist->irk_count <= BLE_GAP_WHITELIST_IRK_MAX_COUNT, - NRF_ERROR_INVALID_LENGTH); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_irks), NULL); - - for (i = 0; i < p_whitelist->irk_count; i++) - { - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_irks[i]), ble_gap_irk_dec); - } - - return err_code; -} - -uint32_t ble_gap_scan_params_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_scan_params_t * p_scan_params = (ble_gap_scan_params_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[*p_index] = p_scan_params->active & 0x01; - p_buf[*p_index] |= (p_scan_params->selective & 0x7F) << 1; - (*p_index)++; - - err_code = cond_field_enc(p_scan_params->p_whitelist, p_buf, buf_len, p_index, ble_gap_whitelist_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_scan_params->interval), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_scan_params->window), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_scan_params->timeout), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_scan_params_t * p_scan_params = (ble_gap_scan_params_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_scan_params->active = p_buf[*p_index] & 0x01; - p_scan_params->selective = (p_buf[*p_index] >> 1) & 0x7F; - (*p_index)++; - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_scan_params->p_whitelist), ble_gap_whitelist_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_scan_params->interval)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_scan_params->window)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_scan_params->timeout)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_ch_mask, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_adv_ch_mask_t * p_ch_mask = (ble_gap_adv_ch_mask_t *)p_void_ch_mask; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_ch_mask->ch_37_off | - (p_ch_mask->ch_38_off << 1) | - (p_ch_mask->ch_39_off << 2); - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_ch_mask) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_adv_ch_mask_t * p_ch_mask = (ble_gap_adv_ch_mask_t *)p_void_ch_mask; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_ch_mask->ch_37_off = byte & 0x01; - p_ch_mask->ch_38_off = (byte >> 1) & 0x01; - p_ch_mask->ch_39_off = (byte >> 2) & 0x01; - - return err_code; -} - -uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_evt_sec_request_t * p_evt_sec_request = (ble_gap_evt_sec_request_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - - p_buf[*p_index] = p_evt_sec_request->bond & 0x01; - p_buf[*p_index] |= (p_evt_sec_request->mitm & 0x01) << 1; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_evt_sec_request_t * p_sec_request = (ble_gap_evt_sec_request_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_sec_request->bond = p_buf[*p_index] & 0x01; - p_sec_request->mitm = (p_buf[*p_index] >> 1) & 0x01; - *p_index += 1; - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s110/ble_gap_struct_serialization.h b/components/serialization/common/struct_ser/s110/ble_gap_struct_serialization.h deleted file mode 100644 index 000f355..0000000 --- a/components/serialization/common/struct_ser/s110/ble_gap_struct_serialization.h +++ /dev/null @@ -1,352 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap.h" - -uint32_t ble_gap_irk_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_irk_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_addr_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_addr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_addr); - -uint32_t ble_gap_sec_levels_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_levels_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_sec_keys_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_keys_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_enc_info_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_enc_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_enc_info); - -uint32_t ble_gap_sign_info_enc(void const * const p_sign_info, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sign_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_sign_info); - -uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_conn_sec_mode_enc(void const * const p_void_sec_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_conn_sec_mode_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_mode); - -uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_sec, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec); - -uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_conn_sec_update, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_conn_sec_update); - -uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_sec_info_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_info_request); -uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_connected); - -uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gap_conn_params_t_enc(void const * const p_void_conn_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_conn_params); - -uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_evt_conn_param_update, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_evt_conn_param_update); - -uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_evt_conn_param_update_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_evt_conn_param_update_request); - -uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_disconnected, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_disconnected); - -uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_local_conn_latency, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_local_conn_latency); - -uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_passkey, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_passkey); - -uint32_t ble_gap_opt_privacy_t_enc(void const * const p_void_privacy, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_privacy_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_privacy); - -uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_scan_req_report, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_scan_req_report); - -uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_compat_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_compat_mode); - -uint32_t ble_gap_sec_kdist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_master_id_t_enc(void const * const p_master_idx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_master_idx); - -uint32_t ble_gap_enc_info_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_enc_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_enc_info); - -uint32_t ble_gap_enc_key_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_id_key_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_sec_keyset_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_whitelist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_whitelist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * p_data); - -uint32_t ble_gap_scan_params_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_ch_mask, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_ch_mask); - -uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); diff --git a/components/serialization/common/struct_ser/s110/ble_gattc_struct_serialization.c b/components/serialization/common/struct_ser/s110/ble_gattc_struct_serialization.c deleted file mode 100644 index 2a03665..0000000 --- a/components/serialization/common/struct_ser/s110/ble_gattc_struct_serialization.c +++ /dev/null @@ -1,363 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "ble_gattc_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gattc.h" -#include "cond_field_serialization.h" -#include - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gattc_evt_char_val_by_uuid_read_rsp_t * p_read = - (ble_gattc_evt_char_val_by_uuid_read_rsp_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_read->count), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_read->value_len), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t i; - ble_gattc_handle_value_t * p_handle_value = &p_read->handle_value[0]; - - for (i = 0; i < p_read->count; i++) - { - err_code = uint16_t_enc(&(p_handle_value->handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(p_read->value_len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_handle_value->p_value, p_read->value_len); - *p_index += p_read->value_len; - - p_handle_value++; - } - - return err_code; -} - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_size, - void * const p_void_struct) -{ - ble_gattc_evt_char_val_by_uuid_read_rsp_t * p_read = - (ble_gattc_evt_char_val_by_uuid_read_rsp_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint16_t value_len; - uint16_t count; - uint32_t i; - - SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &count); - uint16_dec(p_buf, buf_len, p_index, &value_len); - - uint32_t total_struct_size = *p_struct_size; - - //calculate the size of the struct - *p_struct_size = offsetof(ble_gattc_evt_char_val_by_uuid_read_rsp_t, handle_value[0]); - *p_struct_size += sizeof(((ble_gattc_evt_char_val_by_uuid_read_rsp_t *)0)->handle_value) * count; - *p_struct_size += value_len * count; - - if (p_read) - { - p_read->value_len = value_len; - p_read->count = count; - - ble_gattc_handle_value_t * p_handle_value; - uint8_t * p_value; - - SER_ASSERT_LENGTH_LEQ(*p_struct_size, total_struct_size); - - p_value = (uint8_t *)&p_read->handle_value[count]; - - for (i = 0; i < count; i++) - { - p_handle_value = (ble_gattc_handle_value_t *)&p_read->handle_value[i]; - p_handle_value->p_value = p_value; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_handle_value->handle)); - - SER_ASSERT_LENGTH_LEQ(p_read->value_len, buf_len - *p_index); - memcpy(p_handle_value->p_value, &p_buf[*p_index], p_read->value_len); - *p_index += p_read->value_len; - - p_value += value_len; - } - } - else - { - *p_index += count * (value_len + 2); - } - - return err_code; -} - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gattc_evt_char_vals_read_rsp_t * p_read = - (ble_gattc_evt_char_vals_read_rsp_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - //Encode len - error_code = uint16_t_enc(&(p_read->len), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - //Encode values - SER_ASSERT_LENGTH_LEQ(p_read->len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_read->values, p_read->len); - *p_index += p_read->len; - - return error_code; -} - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gattc_evt_char_vals_read_rsp_t * p_read = - (ble_gattc_evt_char_vals_read_rsp_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - //Decode len - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_read->len)); - - //Decode values - SER_ASSERT_LENGTH_LEQ(p_read->len, buf_len - *p_index); - memcpy(p_read->values, &p_buf[*p_index], p_read->len); - *p_index += p_read->len; - - return error_code; -} - -uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gattc_handle_range_t * p_range = (ble_gattc_handle_range_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_range->start_handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_range->end_handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gattc_handle_range_t * p_range = (ble_gattc_handle_range_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_range->start_handle)); - uint16_dec(p_buf, buf_len, p_index, &(p_range->end_handle)); - - return err_code; -} - - -uint32_t ble_gattc_service_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_service_t * p_service = (ble_gattc_service_t *) p_void_struct; - - error_code = ble_uuid_t_enc(&(p_service->uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_handle_range_t_enc(&(p_service->handle_range), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_service_t * p_service = (ble_gattc_service_t *) p_void_struct; - - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_service->uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_handle_range_t_dec(p_buf, buf_len, p_index, &(p_service->handle_range)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_include_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_void_struct; - - error_code = uint16_t_enc(&(p_include->handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_service_t_enc(&(p_include->included_srvc), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_void_struct; - - error_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_include->handle)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_service_t_dec(p_buf, buf_len, p_index, &(p_include->included_srvc)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - uint32_t i; - ble_gattc_evt_rel_disc_rsp_t * p_rsp = (ble_gattc_evt_rel_disc_rsp_t *) p_void_struct; - - error_code = uint16_t_enc(&(p_rsp->count), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_rsp->includes; - - for (i = 0; i < p_rsp->count; i++) - { - error_code = ble_gattc_include_t_enc(p_include, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - p_include++; - } - - return error_code; -} - -uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_evt_rel_disc_rsp_t * p_rsp = (ble_gattc_evt_rel_disc_rsp_t *) p_void_struct; - uint16_t include_count; - uint32_t i; - - error_code = uint16_t_dec(p_buf, buf_len, p_index, &include_count); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - p_rsp->count = include_count; - - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_rsp->includes; - - for (i = 0; i < include_count; i++) - { - error_code = ble_gattc_include_t_dec(p_buf, buf_len, p_index, p_include); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - p_include++; - } - - return error_code; -} - -uint32_t ble_gattc_write_params_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_void_write); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - uint32_t err_code = NRF_SUCCESS; - - ble_gattc_write_params_t * p_write = (ble_gattc_write_params_t *)p_void_write; - - err_code = uint8_t_enc(&(p_write->write_op), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&(p_write->flags), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_write->handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_write->offset), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len16data_enc(p_write->p_value, p_write->len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_write) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_write); - - uint32_t err_code = NRF_SUCCESS; - - ble_gattc_write_params_t * p_write = (ble_gattc_write_params_t *)p_void_write; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_write->write_op)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_write->flags)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_write->handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_write->offset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len16data_dec(p_buf, buf_len, p_index, &(p_write->p_value), &(p_write->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s110/ble_gattc_struct_serialization.h b/components/serialization/common/struct_ser/s110/ble_gattc_struct_serialization.h deleted file mode 100644 index cbfae81..0000000 --- a/components/serialization/common/struct_ser/s110/ble_gattc_struct_serialization.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_STRUCT_SERIALIZATION_H -#define BLE_GATTC_STRUCT_SERIALIZATION_H - -#include "ble_gattc.h" - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_size, - void * const p_void_struct); - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_service_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_include_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_write_params_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_write); - -#endif /*BLE_GATTC_STRUCT_SERIALIZATION_H*/ diff --git a/components/serialization/common/struct_ser/s110/ble_gatts_struct_serialization.c b/components/serialization/common/struct_ser/s110/ble_gatts_struct_serialization.c deleted file mode 100644 index cec4062..0000000 --- a/components/serialization/common/struct_ser/s110/ble_gatts_struct_serialization.c +++ /dev/null @@ -1,926 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gatts.h" -#include "cond_field_serialization.h" -#include - -uint32_t ser_ble_gatts_char_pf_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_pf) -{ - ble_gatts_char_pf_t * p_char_pf = (ble_gatts_char_pf_t *)p_void_char_pf; - - SER_ASSERT_LENGTH_LEQ(7, buf_len - *p_index); - - uint8_dec(p_buf, buf_len, p_index, &p_char_pf->format); - uint8_dec(p_buf, buf_len, p_index, (uint8_t *)&p_char_pf->exponent); - uint16_dec(p_buf, buf_len, p_index, &p_char_pf->unit); - uint8_dec(p_buf, buf_len, p_index, &p_char_pf->name_space); - uint16_dec(p_buf, buf_len, p_index, &p_char_pf->desc); - - return NRF_SUCCESS; -} - -uint32_t ser_ble_gatts_char_pf_enc(void const * const p_void_char_pf, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_char_pf_t * p_char_pf = (ble_gatts_char_pf_t *)p_void_char_pf; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&p_char_pf->format, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_char_pf->exponent, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_pf->unit, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_char_pf->name_space, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_pf->desc, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_attr_md_enc(void const * const p_void_attr_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_attr_md_t * p_attr_md = (ble_gatts_attr_md_t *)p_void_attr_md; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_conn_sec_mode_enc(&p_attr_md->read_perm, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_conn_sec_mode_enc(&p_attr_md->write_perm, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - /* serializer does not support attributes on stack */ - if (p_attr_md->vloc != BLE_GATTS_VLOC_STACK) - { - err_code = NRF_ERROR_INVALID_PARAM; - } - - uint8_t temp8; - temp8 = p_attr_md->vlen | - (p_attr_md->vloc << 1) | - (p_attr_md->rd_auth << 3) | - (p_attr_md->wr_auth << 4); - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[*p_index] = temp8; - *p_index += 1; - - return err_code; -} - -uint32_t ble_gatts_attr_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_md) -{ - ble_gatts_attr_md_t * p_attr_md = (ble_gatts_attr_md_t *)p_void_attr_md; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_attr_md->read_perm); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_attr_md->write_perm); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &temp8); - - p_attr_md->vlen = temp8; - p_attr_md->vloc = temp8 >> 1; - p_attr_md->rd_auth = temp8 >> 3; - p_attr_md->wr_auth = temp8 >> 4; - - return err_code; -} - -uint32_t ble_gatts_char_md_enc(void const * const p_void_char_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - - ble_gatts_char_md_t * p_char_md = (ble_gatts_char_md_t *)p_void_char_md; - uint8_t temp8; - - temp8 = p_char_md->char_props.broadcast | - (p_char_md->char_props.read << 1) | - (p_char_md->char_props.write_wo_resp << 2) | - (p_char_md->char_props.write << 3) | - (p_char_md->char_props.notify << 4) | - (p_char_md->char_props.indicate << 5) | - (p_char_md->char_props.auth_signed_wr << 6); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - temp8 = p_char_md->char_ext_props.reliable_wr | - (p_char_md->char_ext_props.wr_aux << 1); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_md->char_user_desc_max_size, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ERROR_CHECK(p_char_md->char_user_desc_size <= BLE_GATTS_VAR_ATTR_LEN_MAX, - NRF_ERROR_INVALID_PARAM); - err_code = len16data_enc(p_char_md->p_char_user_desc, p_char_md->char_user_desc_size, p_buf, - buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_char_pf, - p_buf, - buf_len, - p_index, - ser_ble_gatts_char_pf_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_user_desc_md, - p_buf, - buf_len, - p_index, - ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_cccd_md, p_buf, buf_len, p_index, ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_sccd_md, p_buf, buf_len, p_index, ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_char_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_md) -{ - uint32_t err_code = NRF_SUCCESS; - - ble_gatts_char_md_t * p_char_md = (ble_gatts_char_md_t *)p_void_char_md; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint8_t temp8 = p_buf[*p_index]; - - p_char_md->char_props.broadcast = temp8 >> 0; - p_char_md->char_props.read = temp8 >> 1; - p_char_md->char_props.write_wo_resp = temp8 >> 2; - p_char_md->char_props.write = temp8 >> 3; - p_char_md->char_props.notify = temp8 >> 4; - p_char_md->char_props.indicate = temp8 >> 5; - p_char_md->char_props.auth_signed_wr = temp8 >> 6; - - temp8 = p_buf[*p_index + 1]; - p_char_md->char_ext_props.reliable_wr = temp8 >> 0; - p_char_md->char_ext_props.wr_aux = temp8 >> 1; - - *p_index += 2; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_char_md->char_user_desc_max_size); - - err_code = len16data_dec(p_buf, - buf_len, - p_index, - &p_char_md->p_char_user_desc, - &p_char_md->char_user_desc_size); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_char_pf, - ser_ble_gatts_char_pf_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_user_desc_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_cccd_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_sccd_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; - -} - -uint32_t ble_gatts_attr_enc(void const * const p_void_gatts_attr, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - ble_gatts_attr_t * p_gatts_attr = (ble_gatts_attr_t *)p_void_gatts_attr; - - err_code = cond_field_enc((void *)p_gatts_attr->p_uuid, p_buf, buf_len, p_index, ble_uuid_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_gatts_attr->p_attr_md, - p_buf, - buf_len, - p_index, - ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_gatts_attr->init_offs, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_gatts_attr->max_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ERROR_CHECK(p_gatts_attr->init_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); - //init len move just before p_data to be able to use len16data decoder. - err_code = len16data_enc(p_gatts_attr->p_value, p_gatts_attr->init_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_attr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_gatts_attr) -{ - uint32_t err_code = NRF_SUCCESS; - ble_gatts_attr_t * p_gatts_attr = (ble_gatts_attr_t *)p_void_gatts_attr; - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_gatts_attr->p_uuid, - ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_gatts_attr->p_attr_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_gatts_attr->init_offs); - uint16_dec(p_buf, buf_len, p_index, &p_gatts_attr->max_len); - - //init len move just before p_data to be able to use len16data decoder. - err_code = len16data_dec(p_buf, - buf_len, - p_index, - &p_gatts_attr->p_value, - &p_gatts_attr->init_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_char_handles_enc(void const * const p_void_char_handles, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_char_handles_t * p_char_handles = (ble_gatts_char_handles_t *)p_void_char_handles; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_char_handles->value_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_handles->user_desc_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_handles->cccd_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_handles->sccd_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_char_handles_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_handles) -{ - ble_gatts_char_handles_t * p_char_handles = (ble_gatts_char_handles_t *)p_void_char_handles; - - SER_ASSERT_LENGTH_LEQ(8, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_char_handles->value_handle)); - uint16_dec(p_buf, buf_len, p_index, &p_char_handles->user_desc_handle); - uint16_dec(p_buf, buf_len, p_index, &p_char_handles->cccd_handle); - uint16_dec(p_buf, buf_len, p_index, &p_char_handles->sccd_handle); - - return NRF_SUCCESS; -} - -uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_hvx_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_hvx_params_t * p_hvx_params = (ble_gatts_hvx_params_t *)p_void_hvx_params; - - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2 + 1 + 2, buf_len - *p_index); - - err_code = uint16_t_enc(&p_hvx_params->handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_hvx_params->type, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_hvx_params->offset, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_hvx_params->p_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[(*p_index)++] = SER_FIELD_PRESENT; - - err_code = uint16_t_enc(p_hvx_params->p_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - if (p_hvx_params->p_data != NULL) - { - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[(*p_index)++] = SER_FIELD_PRESENT; - - SER_ASSERT_LENGTH_LEQ(*p_hvx_params->p_len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_hvx_params->p_data, *p_hvx_params->p_len); - *p_index += *p_hvx_params->p_len; - } - - return err_code; -} - -uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_hvx_params) -{ - ble_gatts_hvx_params_t * p_hvx_params = (ble_gatts_hvx_params_t *)p_void_hvx_params; - - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2 + 1 + 2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_hvx_params->handle); - uint8_dec(p_buf, buf_len, p_index, &p_hvx_params->type); - uint16_dec(p_buf, buf_len, p_index, &p_hvx_params->offset); - - SER_ASSERT_NOT_NULL(&p_hvx_params->p_len); - err_code = cond_len16_cond_data_dec(p_buf, - buf_len, - p_index, - &p_hvx_params->p_data, - &p_hvx_params->p_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_attr_context_t_enc(void const * const p_void_attr_context, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gatts_attr_context_t * p_context = (ble_gatts_attr_context_t *) p_void_attr_context; - - error_code = ble_uuid_t_enc(&(p_context->srvc_uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_enc(&(p_context->char_uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_enc(&(p_context->desc_uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&(p_context->srvc_handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&(p_context->value_handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint8_t_enc(&(p_context->type), p_buf, buf_len, p_index); - - return error_code; -} - -uint32_t ble_gatts_attr_context_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_context) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gatts_attr_context_t * p_context = (ble_gatts_attr_context_t *) p_void_attr_context; - - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->srvc_uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->char_uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->desc_uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - SER_ASSERT_LENGTH_LEQ(5, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_context->srvc_handle)); - uint16_dec(p_buf, buf_len, p_index, &(p_context->value_handle)); - uint8_dec(p_buf, buf_len, p_index, &(p_context->type)); - return error_code; -} - -uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_evt_write_t * p_write = (ble_gatts_evt_write_t *) p_void_write; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint16_t_enc(&(p_write->handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint8_t_enc(&(p_write->op), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gatts_attr_context_t_enc(&(p_write->context), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&(p_write->offset), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - uint16_t data_len = p_write->len; - error_code = uint16_t_enc(&data_len, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - SER_ASSERT_LENGTH_LEQ(data_len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_write->data, data_len); - *p_index += data_len; - - return error_code; -} - -uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_write) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_struct_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t in_struct_len = *p_struct_len; - - *p_struct_len = offsetof(ble_gatts_evt_write_t, data); - - uint16_t handle; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint8_t op; - err_code = uint8_t_dec(p_buf, buf_len, p_index, &op); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - ble_gatts_attr_context_t context; - err_code = ble_gatts_attr_context_t_dec(p_buf, buf_len, p_index, &context); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint16_t offset; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint16_t len; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_struct_len += len; - - if (p_void_write != NULL) - { - ble_gatts_evt_write_t * p_write = (ble_gatts_evt_write_t *)p_void_write; - - SER_ASSERT_LENGTH_LEQ(*p_struct_len, in_struct_len); - - p_write->handle = handle; - p_write->op = op; - - memcpy(&(p_write->context), &context, sizeof (ble_gatts_attr_context_t)); - - p_write->offset = offset; - p_write->len = len; - - SER_ASSERT_LENGTH_LEQ(p_write->len, buf_len - *p_index); - memcpy(p_write->data, &p_buf[*p_index], p_write->len); - } - - *p_index += len; - - return err_code; -} - -uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_read, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_read); - - ble_gatts_evt_read_t * p_read = (ble_gatts_evt_read_t *)p_void_read; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_read->handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_attr_context_t_enc(&(p_read->context), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_read->offset), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_read) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - uint32_t err_code = NRF_SUCCESS; - uint32_t in_struct_len = *p_struct_len; - - *p_struct_len = sizeof (ble_gatts_evt_read_t); - - uint16_t handle; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - ble_gatts_attr_context_t context; - err_code = ble_gatts_attr_context_t_dec(p_buf, buf_len, p_index, &context); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint16_t offset; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_void_read != NULL) - { - ble_gatts_evt_read_t * p_read = (ble_gatts_evt_read_t *)p_void_read; - - SER_ASSERT_LENGTH_LEQ(*p_struct_len, in_struct_len); - - p_read->handle = handle; - memcpy(&(p_read->context), &context, sizeof (context)); - p_read->offset = offset; - } - - return err_code; -} - -uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_authorize_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_authorize_request); - - ble_gatts_evt_rw_authorize_request_t * p_authorize_request = - (ble_gatts_evt_rw_authorize_request_t *)p_void_authorize_request; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&(p_authorize_request->type), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - switch (p_authorize_request->type) - { - case BLE_GATTS_AUTHORIZE_TYPE_READ: - err_code = ble_gatts_evt_read_t_enc(&(p_authorize_request->request.read), - p_buf, - buf_len, - p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - case BLE_GATTS_AUTHORIZE_TYPE_WRITE: - err_code = ble_gatts_evt_write_t_enc(&(p_authorize_request->request.write), - p_buf, - buf_len, - p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - default: - case BLE_GATTS_AUTHORIZE_TYPE_INVALID: - err_code = NRF_ERROR_INVALID_PARAM; - break; - } - - return err_code; -} - -uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_authorize_request) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_struct_len); - SER_ASSERT_NOT_NULL(p_index); - - uint32_t err_code = NRF_SUCCESS; - - uint8_t type; - err_code = uint8_t_dec(p_buf, buf_len, p_index, &type); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t in_struct_len = *p_struct_len; - - *p_struct_len = offsetof(ble_gatts_evt_rw_authorize_request_t, request); - - ble_gatts_evt_rw_authorize_request_t * p_authorize_request = - (ble_gatts_evt_rw_authorize_request_t *)p_void_authorize_request; - - void * p_void_request = NULL; - - if (p_void_authorize_request != NULL) - { - p_authorize_request->type = type; - - SER_ASSERT_LENGTH_LEQ(*p_struct_len, in_struct_len); - - switch (type) - { - case BLE_GATTS_AUTHORIZE_TYPE_READ: - p_void_request = &(p_authorize_request->request.read); - break; - - case BLE_GATTS_AUTHORIZE_TYPE_WRITE: - p_void_request = &(p_authorize_request->request.write); - break; - - default: - case BLE_GATTS_AUTHORIZE_TYPE_INVALID: - return NRF_ERROR_INVALID_DATA; - } - } - - switch (type) - { - case BLE_GATTS_AUTHORIZE_TYPE_READ: - err_code = ble_gatts_evt_read_t_dec(p_buf, - buf_len, - p_index, - &in_struct_len, - p_void_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - case BLE_GATTS_AUTHORIZE_TYPE_WRITE: - err_code = ble_gatts_evt_write_t_dec(p_buf, - buf_len, - p_index, - &in_struct_len, - p_void_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - default: - case BLE_GATTS_AUTHORIZE_TYPE_INVALID: - return NRF_ERROR_INVALID_DATA; - } - *p_struct_len += in_struct_len; - - return err_code; -} - -uint32_t ble_gatts_read_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_read_authorize_params_t * p_params = - (ble_gatts_read_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint16_t_enc(&(p_params->gatt_status), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - uint8_t temp_val = p_params->update; - error_code = uint8_t_enc(&temp_val, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - error_code = uint16_t_enc(&(p_params->offset), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - error_code = len16data_enc(p_params->p_data, p_params->len, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gatts_read_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_read_authorize_params_t * p_params = - (ble_gatts_read_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_params->gatt_status); - - uint8_t temp_val; - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &temp_val); - p_params->update = temp_val; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_params->offset); - - error_code = len16data_dec(p_buf, buf_len, p_index, &p_params->p_data, &p_params->len); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gatts_write_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_write_authorize_params_t * p_params = - (ble_gatts_write_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint16_t_enc(&(p_params->gatt_status), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gatts_write_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_write_authorize_params_t * p_params = - (ble_gatts_write_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_params->gatt_status); - - return error_code; -} - -uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_rw_authorize_reply_params_t const * const p_params = - (ble_gatts_rw_authorize_reply_params_t * ) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint8_t_enc(&(p_params->type), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_READ) - { - error_code = ble_gatts_read_authorize_params_t_enc(&p_params->params.read, - p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) - { - error_code = ble_gatts_write_authorize_params_t_enc(&p_params->params.write, - p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else - { - return NRF_ERROR_INVALID_PARAM; - } - - return error_code; -} - -uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_rw_authorize_reply_params_t * p_params = - (ble_gatts_rw_authorize_reply_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &(p_params->type)); - - if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_READ) - { - error_code = ble_gatts_read_authorize_params_t_dec(p_buf, buf_len, p_index, - &p_params->params.read); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) - { - error_code = ble_gatts_write_authorize_params_t_dec(p_buf, buf_len, p_index, - &p_params->params.write); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else - { - return NRF_ERROR_INVALID_PARAM; - } - - return error_code; -} - -uint32_t ble_gatts_value_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_value_t * p_value = (ble_gatts_value_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc((void *) &(p_value->len), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *) &(p_value->offset), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = buf_enc(p_value->p_value, p_value->len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_value_t * p_value = (ble_gatts_value_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint16_t total_len = p_value->len; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, (void *) &(p_value->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, (void *) &(p_value->offset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = buf_dec(p_buf, buf_len, p_index, &(p_value->p_value), total_len, p_value->len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s110/ble_gatts_struct_serialization.h b/components/serialization/common/struct_ser/s110/ble_gatts_struct_serialization.h deleted file mode 100644 index f584a96..0000000 --- a/components/serialization/common/struct_ser/s110/ble_gatts_struct_serialization.h +++ /dev/null @@ -1,160 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_STRUCT_SERIALIZATION_H -#define BLE_GATTS_STRUCT_SERIALIZATION_H - -#include "ble_gatts.h" - -uint32_t ser_ble_gatts_char_pf_enc(void const * const p_void_char_pf, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ser_ble_gatts_char_pf_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_pf); - -uint32_t ble_gatts_attr_md_enc(void const * const p_void_attr_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_attr_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_md); - -uint32_t ble_gatts_char_md_enc(void const * const p_void_char_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_char_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_md); - -uint32_t ble_gatts_attr_enc(void const * const p_void_gatts_attr, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_attr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_gatts_attr); - -uint32_t ble_gatts_char_handles_enc(void const * const p_void_char_handles, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_char_handles_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_handles); - -uint32_t ble_gatts_attr_context_t_enc(void const * const p_void_attr_context, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_attr_context_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_context); - -uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_write); - -uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_hvx_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_hvx_params); - -uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_read, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_read); - -uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_authorize_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_size, - void * const p_void_authorize_request); - -uint32_t ble_gatts_read_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_read_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_write_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_write_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_value_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -#endif /* BLE_GATTS_STRUCT_SERIALIZATION_H */ diff --git a/components/serialization/common/struct_ser/s110/ble_struct_serialization.c b/components/serialization/common/struct_ser/s110/ble_struct_serialization.c deleted file mode 100644 index bb019d9..0000000 --- a/components/serialization/common/struct_ser/s110/ble_struct_serialization.c +++ /dev/null @@ -1,271 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_types.h" -#include "ble_l2cap.h" -#include "ble.h" -#include "cond_field_serialization.h" -#include - - -uint32_t ble_uuid_t_enc(void const * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_uuid_t * p_uuid = (ble_uuid_t *)p_void_uuid; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_uuid->uuid, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_uuid->type, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid) -{ - ble_uuid_t * p_uuid = (ble_uuid_t *)p_void_uuid; - - SER_ASSERT_LENGTH_LEQ(3, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_uuid->uuid); - uint8_dec(p_buf, buf_len, p_index, &p_uuid->type); - - return NRF_SUCCESS; -} - -uint32_t ble_uuid128_t_enc(void const * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_uuid128_t * p_uuid = (ble_uuid128_t *)p_void_uuid; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(16, buf_len - *p_index); - - memcpy(&p_buf[*p_index], p_uuid->uuid128, sizeof (p_uuid->uuid128)); - - *p_index += sizeof (p_uuid->uuid128); - - return err_code; -} - -uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid) -{ - ble_uuid128_t * p_uuid = (ble_uuid128_t *)p_void_uuid; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(16, buf_len - *p_index); - - memcpy(p_uuid->uuid128, &p_buf[*p_index], sizeof (p_uuid->uuid128)); - - *p_index += sizeof (p_uuid->uuid128); - - return err_code; -} - -uint32_t ble_l2cap_header_t_enc(void const * const p_void_header, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_header); - - ble_l2cap_header_t * p_header = (ble_l2cap_header_t *)p_void_header; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_header->len), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_header->cid), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_header) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_header); - - ble_l2cap_header_t * p_header = (ble_l2cap_header_t *)p_void_header; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_header->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_header->cid)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_evt_rx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_evt_rx); - - ble_l2cap_evt_rx_t * p_evt_rx = (ble_l2cap_evt_rx_t *)p_void_evt_rx; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_l2cap_header_t_enc(&(p_evt_rx->header), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(p_evt_rx->header.len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_evt_rx->data, p_evt_rx->header.len); - *p_index += p_evt_rx->header.len; - - return err_code; -} - -uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_evt_rx) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_struct_len); - - ble_l2cap_evt_rx_t * p_evt_rx = (ble_l2cap_evt_rx_t *)p_void_evt_rx; - uint32_t err_code = NRF_SUCCESS; - - uint32_t total_struct_len = *p_struct_len; - - /* Get data length */ - uint32_t tmp_index = *p_index; - uint16_t len = 0; - - err_code = uint16_t_dec(p_buf, buf_len, &tmp_index, &len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - /* Update struct length */ - *p_struct_len = offsetof(ble_l2cap_evt_rx_t, data[0]); - *p_struct_len += (uint8_t*)&(p_evt_rx->data[len]) - (uint8_t*)&(p_evt_rx->data[0]); - - - /* Decode header and copy data */ - if (p_void_evt_rx != NULL) - { - SER_ASSERT_LENGTH_LEQ(*p_struct_len, total_struct_len); - - err_code = ble_l2cap_header_t_dec(p_buf, buf_len, p_index, &(p_evt_rx->header)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(p_evt_rx->header.len, buf_len - *p_index); - memcpy(p_evt_rx->data, &p_buf[*p_index], p_evt_rx->header.len); - *p_index += p_evt_rx->header.len; - } - - return err_code; -} - -uint32_t ble_enable_params_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - - ble_enable_params_t * p_enable_params = (ble_enable_params_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - - p_buf[*p_index] = p_enable_params->gatts_enable_params.service_changed; - (*p_index)++; - err_code = uint32_t_enc(&(p_enable_params->gatts_enable_params.attr_tab_size), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - uint32_t err_code = NRF_SUCCESS; - - ble_enable_params_t * p_enable_params = (ble_enable_params_t *) p_data; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_enable_params->gatts_enable_params.service_changed = p_buf[(*p_index)++]; - - err_code = uint32_t_dec(p_buf, buf_len, p_index, &(p_enable_params->gatts_enable_params.attr_tab_size)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} - -uint32_t ble_common_opt_radio_cpu_mutex_t_enc(void const * const p_void_opt_mutex, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_opt_mutex); - - ble_common_opt_radio_cpu_mutex_t * p_radio_cpu_mutex = (ble_common_opt_radio_cpu_mutex_t *)p_void_opt_mutex; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_radio_cpu_mutex->enable; - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_common_opt_radio_cpu_mutex_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_opt_mutex) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_opt_mutex); - - ble_common_opt_radio_cpu_mutex_t * p_radio_cpu_mutex = (ble_common_opt_radio_cpu_mutex_t *)p_void_opt_mutex; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_radio_cpu_mutex->enable = byte & 0x01; - - return err_code; -} - diff --git a/components/serialization/common/struct_ser/s110/ble_struct_serialization.h b/components/serialization/common/struct_ser/s110/ble_struct_serialization.h deleted file mode 100644 index e587300..0000000 --- a/components/serialization/common/struct_ser/s110/ble_struct_serialization.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_types.h" - - -uint32_t ble_uuid_t_enc(void const * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid); - -uint32_t ble_uuid128_t_enc(const void * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid); - -uint32_t ble_l2cap_header_t_enc(void const * const p_void_header, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_header); - -uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_evt_rx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_event_len, - void * const p_void_evt_rx); - -uint32_t ble_enable_params_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_common_opt_radio_cpu_mutex_t_enc(void const * const p_void_opt_mutex, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_common_opt_radio_cpu_mutex_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_opt_mutex); diff --git a/components/serialization/common/struct_ser/s120/ble_gap_struct_serialization.c b/components/serialization/common/struct_ser/s120/ble_gap_struct_serialization.c deleted file mode 100644 index 7cad228..0000000 --- a/components/serialization/common/struct_ser/s120/ble_gap_struct_serialization.c +++ /dev/null @@ -1,1354 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_struct_serialization.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" -#include "string.h" - -uint32_t ble_gap_irk_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_irk_t * p_gap_irk = (ble_gap_irk_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN, buf_len - *p_index); - - memcpy(&p_buf[*p_index], p_gap_irk->irk, BLE_GAP_SEC_KEY_LEN); - - *p_index += BLE_GAP_SEC_KEY_LEN; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_irk_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - ble_gap_irk_t * p_gap_irk = (ble_gap_irk_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN, buf_len - *p_index); - - memcpy(p_gap_irk->irk, &p_buf[*p_index], BLE_GAP_SEC_KEY_LEN); - - *p_index += BLE_GAP_SEC_KEY_LEN; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_addr_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_addr_t * p_addr = (ble_gap_addr_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(1 + BLE_GAP_ADDR_LEN, buf_len - *p_index); - - p_buf[*p_index] = p_addr->addr_type; - (*p_index)++; - memcpy(&p_buf[*p_index], p_addr->addr, BLE_GAP_ADDR_LEN); - *p_index += BLE_GAP_ADDR_LEN; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_addr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_addr) -{ - ble_gap_addr_t * p_address = (ble_gap_addr_t *) p_addr; - - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_addr_t), buf_len - *p_index); - memcpy(p_address, &p_buf[*p_index], sizeof (ble_gap_addr_t)); - *p_index += sizeof (ble_gap_addr_t); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sec_levels_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_sec_levels_t * p_sec_levels = (ble_gap_sec_levels_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - - p_buf[*p_index] = (p_sec_levels->lv1 << 0) | (p_sec_levels->lv2 << 1) | (p_sec_levels->lv3 << 2); - (*p_index)++; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sec_levels_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - ble_gap_sec_levels_t * p_sec_levels = (ble_gap_sec_levels_t *)p_data; - uint32_t err_code; - uint32_t uint8_temp; - - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_sec_levels_t), buf_len - *p_index); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &(uint8_temp)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_sec_levels->lv1 = uint8_temp & 0x01; - p_sec_levels->lv2 = (uint8_temp >> 1) & 0x01; - p_sec_levels->lv3 = (uint8_temp >> 2) & 0x01; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_sec_keys_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_sec_keys_t * p_sec_keys = (ble_gap_sec_keys_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_enc(p_sec_keys->p_enc_key, p_buf, buf_len, p_index, ble_gap_enc_key_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_keys->p_id_key, p_buf, buf_len, p_index, ble_gap_id_key_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_keys->p_sign_key, p_buf, buf_len, p_index, ble_gap_sign_info_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_keys_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - ble_gap_sec_keys_t * p_sec_keys = (ble_gap_sec_keys_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void * *)&(p_sec_keys->p_enc_key), ble_gap_enc_key_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void * *)&(p_sec_keys->p_id_key), ble_gap_id_key_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void * *)&(p_sec_keys->p_sign_key), ble_gap_sign_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enc_info_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - ble_gap_enc_info_t * p_enc_info = (ble_gap_enc_info_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN + 1, buf_len - *p_index); - - memcpy(&p_buf[*p_index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); - *p_index += BLE_GAP_SEC_KEY_LEN; - - p_buf[*p_index] = p_enc_info->auth & 0x01; - p_buf[*p_index] |= (p_enc_info->ltk_len & 0x7F) << 1; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_enc_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_enc_infox) -{ - ble_gap_enc_info_t * p_enc_info = (ble_gap_enc_info_t *)p_enc_infox; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN, buf_len - *p_index); - memcpy(p_enc_info->ltk, &p_buf[*p_index], BLE_GAP_SEC_KEY_LEN); - *p_index += BLE_GAP_SEC_KEY_LEN; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_enc_info->auth = p_buf[*p_index] & 0x01; - p_enc_info->ltk_len = (p_buf[*p_index] >> 1) & 0x7F; - *p_index += 1; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sign_info_enc(void const * const p_sign_info, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_sign_info_t), buf_len - *p_index); - memcpy(&p_buf[*p_index], p_sign_info, sizeof (ble_gap_sign_info_t)); - *p_index += sizeof (ble_gap_sign_info_t); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sign_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_sign_info) -{ - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_sign_info_t), buf_len - *p_index); - memcpy(p_sign_info, &p_buf[*p_index], sizeof (ble_gap_sign_info_t)); - *p_index += sizeof (ble_gap_sign_info_t); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - ble_gap_evt_auth_status_t * p_auth_status = (ble_gap_evt_auth_status_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(6, buf_len - *p_index); - - err_code = uint8_t_enc(&(p_auth_status->auth_status), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - byte = (p_auth_status->error_src) | ((p_auth_status->bonded) << 2); - - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_levels_enc(&(p_auth_status->sm1_levels), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_levels_enc(&(p_auth_status->sm2_levels), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc(&(p_auth_status->kdist_periph), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc(&(p_auth_status->kdist_central), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - - ble_gap_evt_auth_status_t * p_auth_status = (ble_gap_evt_auth_status_t *)p_data; - uint32_t err_code; - uint8_t byte; - - SER_ASSERT_LENGTH_LEQ(6, buf_len - *p_index); - SER_ASSERT_NOT_NULL(p_auth_status); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_auth_status->auth_status)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_auth_status->error_src = byte & 0x03; - p_auth_status->bonded = (byte >> 2) & 0x01 ; - - err_code = ble_gap_sec_levels_dec(p_buf, buf_len, p_index, &(p_auth_status->sm1_levels)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_levels_dec(p_buf, buf_len, p_index, &(p_auth_status->sm2_levels)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, &(p_auth_status->kdist_periph)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, &(p_auth_status->kdist_central)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - - -uint32_t ble_gap_conn_sec_mode_enc(void const * const p_void_sec_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_conn_sec_mode_t * p_sec_mode = (ble_gap_conn_sec_mode_t *)p_void_sec_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8 = p_sec_mode->sm | (p_sec_mode->lv << 4); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_conn_sec_mode_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_mode) -{ - ble_gap_conn_sec_mode_t * p_sec_mode = (ble_gap_conn_sec_mode_t *)p_void_sec_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &temp8); - - p_sec_mode->sm = temp8; - p_sec_mode->lv = temp8 >> 4; - - return err_code; -} - -uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_conn_sec_update, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_conn_sec_t_enc(p_void_conn_sec_update, p_buf, buf_len, p_index); -} - -uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_conn_sec_update) -{ - return ble_gap_conn_sec_t_dec(p_buf, buf_len, p_index, p_void_conn_sec_update); -} - -uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_sec, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_conn_sec_t * p_conn_sec = (ble_gap_conn_sec_t *)p_void_sec; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_conn_sec_mode_enc(&p_conn_sec->sec_mode, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_conn_sec->encr_key_size, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec) -{ - ble_gap_conn_sec_t * p_conn_sec = (ble_gap_conn_sec_t *)p_void_sec; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_conn_sec->sec_mode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &p_conn_sec->encr_key_size); - - return err_code; -} - -uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_sec_info_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_evt_sec_info_request_t * p_conn_sec = - (ble_gap_evt_sec_info_request_t *)p_void_sec_info_request; - - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_addr_enc(&p_conn_sec->peer_addr, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_enc(&p_conn_sec->master_id, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint8_t temp8 = p_conn_sec->enc_info | - (p_conn_sec->id_info << 1) | - (p_conn_sec->sign_info << 2); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_info_request) -{ - ble_gap_evt_sec_info_request_t * p_conn_sec = (ble_gap_evt_sec_info_request_t *)p_void_sec_info_request; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_conn_sec->peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_dec(p_buf, buf_len, p_index, &(p_conn_sec->master_id)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &temp8); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_conn_sec->enc_info = temp8 & 0x01; - p_conn_sec->id_info = (temp8 >> 1) & 0x01; - p_conn_sec->sign_info = (temp8 >> 2) & 0x01; - - return err_code; -} - -uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_evt_connected_t * p_evt_conn = (ble_gap_evt_connected_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte = 0; - - err_code = ble_gap_addr_enc((void *)&p_evt_conn->peer_addr, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc((void *)&p_evt_conn->own_addr, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - byte = p_evt_conn->irk_match | (p_evt_conn->irk_match_idx << 1); - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_conn_params_t_enc((void *)&p_evt_conn->conn_params, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_connected) -{ - ble_gap_evt_connected_t * p_evt_conn = (ble_gap_evt_connected_t *)p_void_connected; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte = 0; - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_evt_conn->peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_evt_conn->own_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_evt_conn->irk_match = byte & 0x01; - p_evt_conn->irk_match_idx = (byte & 0xFE) >> 1; - - err_code = ble_gap_conn_params_t_dec(p_buf, buf_len, p_index, &(p_evt_conn->conn_params)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_sec_params_t * p_sec_params = (ble_gap_sec_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - temp8 = (p_sec_params->bond & 0x01) | - ((p_sec_params->mitm & 0x01) << 1) | - ((p_sec_params->io_caps & 0x07) << 2) | - ((p_sec_params->oob & 0x01) << 5); - - err_code = uint8_t_enc((void *) &temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *) &(p_sec_params->min_key_size), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *) &(p_sec_params->max_key_size), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc((void *) &(p_sec_params->kdist_periph), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc((void *) &(p_sec_params->kdist_central), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gap_sec_params_t * p_sec_params = (ble_gap_sec_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &temp8); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_sec_params->bond = temp8 & 0x01; - p_sec_params->mitm = (temp8 >> 1) & 0x01; - p_sec_params->io_caps = (temp8 >> 2) & 0x07; - p_sec_params->oob = (temp8 >> 5) & 0x01; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->min_key_size)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->max_key_size)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->kdist_periph)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->kdist_central)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_enable_params_t * p_enable_params = (ble_gap_enable_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - temp8 = (p_enable_params->role & 0x03); - - err_code = uint8_t_enc((void *) &temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gap_enable_params_t * p_enable_params = (ble_gap_enable_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &temp8); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_enable_params->role = temp8 & 0x03; - - return err_code; -} - -uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_sec_params_t_enc(p_void_struct, p_buf, buf_len, p_index); -} - - uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) - { - return ble_gap_sec_params_t_dec(p_buf, buf_len, p_index, p_void_struct); - } - -uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_evt_conn_param_update, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_conn_params_t_enc(p_void_evt_conn_param_update, p_buf, buf_len, p_index); -} - -uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_evt_conn_param_update) -{ - return ble_gap_conn_params_t_dec(p_buf, buf_len, p_index, p_void_evt_conn_param_update); -} - -uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_evt_conn_param_update_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_conn_params_t_enc(p_void_evt_conn_param_update_request, p_buf, buf_len, p_index); -} - -uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_evt_conn_param_update_request) -{ - return ble_gap_conn_params_t_dec(p_buf, buf_len, p_index, p_void_evt_conn_param_update_request); -} - -uint32_t ble_gap_conn_params_t_enc(void const * const p_void_conn_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_conn_params_t * p_conn_params = (ble_gap_conn_params_t *)p_void_conn_params; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_conn_params->min_conn_interval, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_conn_params->max_conn_interval, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_conn_params->slave_latency, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_conn_params->conn_sup_timeout, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_conn_params) -{ - ble_gap_conn_params_t * p_conn_params = (ble_gap_conn_params_t *)p_void_conn_params; - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->min_conn_interval); - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->max_conn_interval); - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->slave_latency); - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->conn_sup_timeout); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_disconnected, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_evt_disconnected_t * p_disconnected = (ble_gap_evt_disconnected_t *)p_void_disconnected; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&p_disconnected->reason, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_disconnected) -{ - ble_gap_evt_disconnected_t * p_disconnected = (ble_gap_evt_disconnected_t *)p_void_disconnected; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &p_disconnected->reason); - - return err_code; -} - -uint32_t ble_gap_master_id_t_enc(void const * const p_master_idx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_master_id_t * p_master_id = (ble_gap_master_id_t *) p_master_idx; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_master_id->ediv), p_buf, buf_len, p_index); - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_RAND_LEN, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_master_id->rand, BLE_GAP_SEC_RAND_LEN); - *p_index += BLE_GAP_SEC_RAND_LEN; - - return err_code; -} - -uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_master_idx) -{ - ble_gap_master_id_t *p_master_id = (ble_gap_master_id_t *)p_master_idx; - - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_master_id->ediv)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_RAND_LEN, buf_len - *p_index); - memcpy(p_master_id->rand, &p_buf[*p_index], BLE_GAP_SEC_RAND_LEN); - *p_index += BLE_GAP_SEC_RAND_LEN; - - return err_code; -} - -uint32_t ble_gap_whitelist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_whitelist_t *p_whitelist = (ble_gap_whitelist_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - uint32_t i = 0; - - SER_ERROR_CHECK(p_whitelist->addr_count <= BLE_GAP_WHITELIST_ADDR_MAX_COUNT, - NRF_ERROR_INVALID_PARAM); - SER_ERROR_CHECK(p_whitelist->irk_count <= BLE_GAP_WHITELIST_IRK_MAX_COUNT, - NRF_ERROR_INVALID_PARAM); - - err_code = uint8_t_enc(&(p_whitelist->addr_count), p_buf, buf_len, p_index); - - err_code = cond_field_enc(p_whitelist->pp_addrs, p_buf, buf_len, p_index, NULL); - - for (i = 0; i < p_whitelist->addr_count; i++) - { - err_code = cond_field_enc(p_whitelist->pp_addrs[i], p_buf, buf_len, p_index, ble_gap_addr_enc); - } - - err_code = uint8_t_enc(&(p_whitelist->irk_count), p_buf, buf_len, p_index); - - err_code = cond_field_enc(p_whitelist->pp_irks, p_buf, buf_len, p_index, NULL); - - for (i = 0; i < p_whitelist->irk_count; i++) - { - err_code = cond_field_enc(p_whitelist->pp_irks[i], p_buf, buf_len, p_index, ble_gap_irk_enc); - } - - return err_code; -} - -uint32_t ble_gap_whitelist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_whitelist_t * p_whitelist = (ble_gap_whitelist_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - uint32_t i = 0; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_whitelist->addr_count)); - SER_ERROR_CHECK(p_whitelist->addr_count <= BLE_GAP_WHITELIST_ADDR_MAX_COUNT, - NRF_ERROR_INVALID_LENGTH); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_addrs), NULL); - - for (i = 0; i < p_whitelist->addr_count; i++) - { - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_addrs[i]), ble_gap_addr_dec); - } - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_whitelist->irk_count)); - SER_ERROR_CHECK(p_whitelist->irk_count <= BLE_GAP_WHITELIST_IRK_MAX_COUNT, - NRF_ERROR_INVALID_LENGTH); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_irks), NULL); - - for (i = 0; i < p_whitelist->irk_count; i++) - { - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_irks[i]), ble_gap_irk_dec); - } - - return err_code; -} - -uint32_t ble_gap_scan_params_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_scan_params_t * p_scan_params = (ble_gap_scan_params_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[*p_index] = p_scan_params->active & 0x01; - p_buf[*p_index] |= (p_scan_params->selective & 0x7F) << 1; - (*p_index)++; - - err_code = cond_field_enc(p_scan_params->p_whitelist, p_buf, buf_len, p_index, ble_gap_whitelist_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_scan_params->interval), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_scan_params->window), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_scan_params->timeout), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_scan_params_t * p_scan_params = (ble_gap_scan_params_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_scan_params->active = p_buf[*p_index] & 0x01; - p_scan_params->selective = (p_buf[*p_index] >> 1) & 0x7F; - (*p_index)++; - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_scan_params->p_whitelist), ble_gap_whitelist_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_scan_params->interval)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_scan_params->window)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_scan_params->timeout)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enc_key_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_enc_key_t * p_enc_key = (ble_gap_enc_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_enc_info_enc(&(p_enc_key->enc_info), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_enc(&(p_enc_key->master_id), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_enc_key_t * p_enc_key = (ble_gap_enc_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_enc_info_dec(p_buf, buf_len, p_index, &(p_enc_key->enc_info)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_dec(p_buf, buf_len, p_index, &(p_enc_key->master_id)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} -uint32_t ble_gap_id_key_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_id_key_t * p_id_key = (ble_gap_id_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_irk_enc(&(p_id_key->id_info), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc(&(p_id_key->id_addr_info), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_id_key_t * p_id_key = (ble_gap_id_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_irk_dec(p_buf, buf_len, p_index, &(p_id_key->id_info)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_id_key->id_addr_info)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_keyset_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_keyset_t * p_sec_keyset = (ble_gap_sec_keyset_t *) p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_sec_keys_enc(&(p_sec_keyset->keys_periph), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keys_enc(&(p_sec_keyset->keys_central), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_keyset_t * p_sec_keyset = (ble_gap_sec_keyset_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_sec_keys_dec(p_buf, buf_len, p_index, &(p_sec_keyset->keys_periph)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keys_dec(p_buf, buf_len, p_index, &(p_sec_keyset->keys_central)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_evt_sec_request_t * p_evt_sec_request = (ble_gap_evt_sec_request_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - - p_buf[*p_index] = p_evt_sec_request->bond & 0x01; - p_buf[*p_index] |= (p_evt_sec_request->mitm & 0x01) << 1; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_evt_sec_request_t * p_sec_request = (ble_gap_evt_sec_request_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_sec_request->bond = p_buf[*p_index] & 0x01; - p_sec_request->mitm = (p_buf[*p_index] >> 1) & 0x01; - *p_index += 1; - - return err_code; -} - -uint32_t ble_gap_sec_kdist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_kdist_t * p_sec_kdist = (ble_gap_sec_kdist_t *) p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - - p_buf[*p_index] = p_sec_kdist->enc & 0x01; - p_buf[*p_index] |= (p_sec_kdist->id & 0x01) << 1; - p_buf[*p_index] |= (p_sec_kdist->sign & 0x01) << 2; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_kdist_t * p_sec_kdist = (ble_gap_sec_kdist_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_sec_kdist->enc = p_buf[*p_index] & 0x01; - p_sec_kdist->id = (p_buf[*p_index] >> 1) & 0x01; - p_sec_kdist->sign = (p_buf[*p_index] >> 2) & 0x01; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_ch_map_t * p_gap_opt_ch_map = (ble_gap_opt_ch_map_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_gap_opt_ch_map->conn_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(5, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_gap_opt_ch_map->ch_map, 5); - - *p_index += 5; - - return err_code; -} - -uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_ch_map_t * p_gap_opt_ch_map = (ble_gap_opt_ch_map_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &p_gap_opt_ch_map->conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(5, buf_len - *p_index); - memcpy(p_gap_opt_ch_map->ch_map, &p_buf[*p_index], 5); - - *p_index += 5; - - return err_code; -} - -uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_local_conn_latency, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_local_conn_latency_t * p_latency = - (ble_gap_opt_local_conn_latency_t *)p_void_local_conn_latency; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_latency->conn_handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_latency->requested_latency), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_latency->p_actual_latency, p_buf, buf_len, p_index, uint16_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_local_conn_latency) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_local_conn_latency_t * p_latency = - (ble_gap_opt_local_conn_latency_t *)p_void_local_conn_latency; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_latency->conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_latency->requested_latency)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_latency->p_actual_latency), - uint16_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_passkey, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_passkey_t * p_opt_passkey = (ble_gap_opt_passkey_t *)p_void_passkey; - uint32_t err_code = NRF_SUCCESS; - uint16_t passkey_len = BLE_GAP_PASSKEY_LEN; - - err_code = buf_enc(p_opt_passkey->p_passkey, passkey_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_passkey) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_passkey_t * p_opt_passkey = (ble_gap_opt_passkey_t *)p_void_passkey; - uint32_t err_code = NRF_SUCCESS; - uint16_t passkey_len = BLE_GAP_PASSKEY_LEN; - - err_code = buf_dec(p_buf, buf_len, p_index, &p_opt_passkey->p_passkey, passkey_len, - passkey_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_privacy_t_enc(void const * const p_void_privacy, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_privacy_t * p_privacy = (ble_gap_opt_privacy_t *)p_void_privacy; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_enc(p_privacy->p_irk, p_buf, buf_len, p_index, ble_gap_irk_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_privacy->interval_s), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_privacy_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_privacy) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_privacy_t * p_privacy = (ble_gap_opt_privacy_t *)p_void_privacy; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_privacy->p_irk), ble_gap_irk_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_privacy->interval_s)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_scan_req_report, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_scan_req_report_t * p_scan_req_report = (ble_gap_opt_scan_req_report_t *)p_void_scan_req_report; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_scan_req_report->enable; - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_scan_req_report) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_scan_req_report_t * p_scan_req_report = (ble_gap_opt_scan_req_report_t *)p_void_scan_req_report; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_scan_req_report->enable = byte & 0x01; - - return err_code; -} - -uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_compat_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_compat_mode_t * p_compat_mode = (ble_gap_opt_compat_mode_t *)p_void_compat_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_compat_mode->mode_1_enable; - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_compat_mode) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_compat_mode_t * p_compat_mode = (ble_gap_opt_compat_mode_t *)p_void_compat_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_compat_mode->mode_1_enable = byte & 0x01; - - return err_code; -} - -uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_ch_mask, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_adv_ch_mask_t * p_ch_mask = (ble_gap_adv_ch_mask_t *)p_void_ch_mask; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_ch_mask->ch_37_off | - (p_ch_mask->ch_38_off << 1) | - (p_ch_mask->ch_39_off << 2); - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_ch_mask) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_adv_ch_mask_t * p_ch_mask = (ble_gap_adv_ch_mask_t *)p_void_ch_mask; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_ch_mask->ch_37_off = byte & 0x01; - p_ch_mask->ch_38_off = (byte >> 1) & 0x01; - p_ch_mask->ch_39_off = (byte >> 2) & 0x01; - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s120/ble_gap_struct_serialization.h b/components/serialization/common/struct_ser/s120/ble_gap_struct_serialization.h deleted file mode 100644 index b5f06c2..0000000 --- a/components/serialization/common/struct_ser/s120/ble_gap_struct_serialization.h +++ /dev/null @@ -1,353 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap.h" - -uint32_t ble_gap_irk_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_irk_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_addr_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_addr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_addr); - -uint32_t ble_gap_sec_levels_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_levels_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_sec_keys_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_keys_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_enc_info_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_enc_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_enc_info); - -uint32_t ble_gap_sign_info_enc(void const * const p_sign_info, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sign_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_sign_info); - -uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_conn_sec_mode_enc(void const * const p_void_sec_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_conn_sec_mode_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_mode); - -uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_sec, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec); - -uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_conn_sec_update, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_conn_sec_update); - -uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_sec_info_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_info_request); - -uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_connected); - -uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gap_conn_params_t_enc(void const * const p_void_conn_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_conn_params); - -uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_evt_conn_param_update, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_evt_conn_param_update); - -uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_evt_conn_param_update_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_evt_conn_param_update_request); - -uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_disconnected, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_disconnected); - -uint32_t ble_gap_whitelist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_whitelist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * p_data); - -uint32_t ble_gap_scan_params_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_master_id_t_enc(void const * const p_master_idx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_master_idx); - -uint32_t ble_gap_enc_key_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_id_key_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_sec_keyset_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_sec_kdist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_local_conn_latency, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_local_conn_latency); - -uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_passkey, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_passkey); - -uint32_t ble_gap_opt_privacy_t_enc(void const * const p_void_privacy, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_privacy_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_privacy); - -uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_scan_req_report, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_scan_req_report); - -uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_compat_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_compat_mode); - -uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_ch_mask, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_ch_mask); diff --git a/components/serialization/common/struct_ser/s120/ble_gattc_struct_serialization.c b/components/serialization/common/struct_ser/s120/ble_gattc_struct_serialization.c deleted file mode 100644 index 9c36a55..0000000 --- a/components/serialization/common/struct_ser/s120/ble_gattc_struct_serialization.c +++ /dev/null @@ -1,363 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "ble_gattc_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gattc.h" -#include "cond_field_serialization.h" -#include - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gattc_evt_char_val_by_uuid_read_rsp_t * p_read = - (ble_gattc_evt_char_val_by_uuid_read_rsp_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_read->count), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_read->value_len), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t i; - ble_gattc_handle_value_t * p_handle_value = &p_read->handle_value[0]; - - for (i = 0; i < p_read->count; i++) - { - err_code = uint16_t_enc(&(p_handle_value->handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(p_read->value_len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_handle_value->p_value, p_read->value_len); - *p_index += p_read->value_len; - - p_handle_value++; - } - - return err_code; -} - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_size, - void * const p_void_struct) -{ - ble_gattc_evt_char_val_by_uuid_read_rsp_t * p_read = - (ble_gattc_evt_char_val_by_uuid_read_rsp_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint16_t value_len; - uint16_t count; - uint32_t i; - - SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &count); - uint16_dec(p_buf, buf_len, p_index, &value_len); - - uint32_t total_struct_size = *p_struct_size; - - //calculate the size of the struct - *p_struct_size = offsetof(ble_gattc_evt_char_val_by_uuid_read_rsp_t, handle_value[0]); - *p_struct_size += sizeof(((ble_gattc_evt_char_val_by_uuid_read_rsp_t *)0)->handle_value) * count; - *p_struct_size += value_len * count; - - if (p_read) - { - p_read->value_len = value_len; - p_read->count = count; - - ble_gattc_handle_value_t * p_handle_value; - uint8_t * p_value; - - SER_ASSERT_LENGTH_LEQ(*p_struct_size, total_struct_size); - - p_value = (uint8_t *)&p_read->handle_value[count]; - - for (i = 0; i < count; i++) - { - p_handle_value = (ble_gattc_handle_value_t *)&p_read->handle_value[i]; - p_handle_value->p_value = p_value; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_handle_value->handle)); - - SER_ASSERT_LENGTH_LEQ(p_read->value_len, buf_len - *p_index); - memcpy(p_handle_value->p_value, &p_buf[*p_index], p_read->value_len); - *p_index += p_read->value_len; - - p_value += value_len; - } - } - else - { - *p_index += count * (value_len + 2); - } - - return err_code; -} - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gattc_evt_char_vals_read_rsp_t * p_read = - (ble_gattc_evt_char_vals_read_rsp_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - //Encode len - error_code = uint16_t_enc(&(p_read->len), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - //Encode values - SER_ASSERT_LENGTH_LEQ(p_read->len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_read->values, p_read->len); - *p_index += p_read->len; - - return error_code; -} - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gattc_evt_char_vals_read_rsp_t * p_read = - (ble_gattc_evt_char_vals_read_rsp_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - //Decode len - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_read->len)); - - //Decode values - SER_ASSERT_LENGTH_LEQ(p_read->len, buf_len - *p_index); - memcpy(p_read->values, &p_buf[*p_index], p_read->len); - *p_index += p_read->len; - - return error_code; -} - -uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gattc_handle_range_t * p_range = (ble_gattc_handle_range_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_range->start_handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_range->end_handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gattc_handle_range_t * p_range = (ble_gattc_handle_range_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_range->start_handle)); - uint16_dec(p_buf, buf_len, p_index, &(p_range->end_handle)); - - return err_code; -} - - -uint32_t ble_gattc_service_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_service_t * p_service = (ble_gattc_service_t *) p_void_struct; - - error_code = ble_uuid_t_enc(&(p_service->uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_handle_range_t_enc(&(p_service->handle_range), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_service_t * p_service = (ble_gattc_service_t *) p_void_struct; - - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_service->uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_handle_range_t_dec(p_buf, buf_len, p_index, &(p_service->handle_range)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_include_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_void_struct; - - error_code = uint16_t_enc(&(p_include->handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_service_t_enc(&(p_include->included_srvc), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_void_struct; - - error_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_include->handle)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_service_t_dec(p_buf, buf_len, p_index, &(p_include->included_srvc)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - uint32_t i; - ble_gattc_evt_rel_disc_rsp_t * p_rsp = (ble_gattc_evt_rel_disc_rsp_t *) p_void_struct; - - error_code = uint16_t_enc(&(p_rsp->count), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_rsp->includes; - - for (i = 0; i < p_rsp->count; i++) - { - error_code = ble_gattc_include_t_enc(p_include, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - p_include++; - } - - return error_code; -} - -uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_evt_rel_disc_rsp_t * p_rsp = (ble_gattc_evt_rel_disc_rsp_t *) p_void_struct; - uint16_t include_count; - uint32_t i; - - error_code = uint16_t_dec(p_buf, buf_len, p_index, &include_count); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - p_rsp->count = include_count; - - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_rsp->includes; - - for (i = 0; i < include_count; i++) - { - error_code = ble_gattc_include_t_dec(p_buf, buf_len, p_index, p_include); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - p_include++; - } - - return error_code; -} - -uint32_t ble_gattc_write_params_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_void_write); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - uint32_t err_code = NRF_SUCCESS; - - ble_gattc_write_params_t * p_write = (ble_gattc_write_params_t *)p_void_write; - - err_code = uint8_t_enc(&(p_write->write_op), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&(p_write->flags), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_write->handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_write->offset), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len16data_enc(p_write->p_value, p_write->len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_write) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_write); - - uint32_t err_code = NRF_SUCCESS; - - ble_gattc_write_params_t * p_write = (ble_gattc_write_params_t *)p_void_write; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_write->write_op)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_write->flags)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_write->handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_write->offset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len16data_dec(p_buf, buf_len, p_index, &(p_write->p_value), &(p_write->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s120/ble_gattc_struct_serialization.h b/components/serialization/common/struct_ser/s120/ble_gattc_struct_serialization.h deleted file mode 100644 index cbfae81..0000000 --- a/components/serialization/common/struct_ser/s120/ble_gattc_struct_serialization.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_STRUCT_SERIALIZATION_H -#define BLE_GATTC_STRUCT_SERIALIZATION_H - -#include "ble_gattc.h" - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_size, - void * const p_void_struct); - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_service_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_include_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_write_params_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_write); - -#endif /*BLE_GATTC_STRUCT_SERIALIZATION_H*/ diff --git a/components/serialization/common/struct_ser/s120/ble_gatts_struct_serialization.c b/components/serialization/common/struct_ser/s120/ble_gatts_struct_serialization.c deleted file mode 100644 index c03e760..0000000 --- a/components/serialization/common/struct_ser/s120/ble_gatts_struct_serialization.c +++ /dev/null @@ -1,959 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gatts.h" -#include "cond_field_serialization.h" -#include - -uint32_t ser_ble_gatts_char_pf_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_pf) -{ - ble_gatts_char_pf_t * p_char_pf = (ble_gatts_char_pf_t *)p_void_char_pf; - - SER_ASSERT_LENGTH_LEQ(7, buf_len - *p_index); - - uint8_dec(p_buf, buf_len, p_index, &p_char_pf->format); - uint8_dec(p_buf, buf_len, p_index, (uint8_t *)&p_char_pf->exponent); - uint16_dec(p_buf, buf_len, p_index, &p_char_pf->unit); - uint8_dec(p_buf, buf_len, p_index, &p_char_pf->name_space); - uint16_dec(p_buf, buf_len, p_index, &p_char_pf->desc); - - return NRF_SUCCESS; -} - -uint32_t ser_ble_gatts_char_pf_enc(void const * const p_void_char_pf, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_char_pf_t * p_char_pf = (ble_gatts_char_pf_t *)p_void_char_pf; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&p_char_pf->format, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_char_pf->exponent, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_pf->unit, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_char_pf->name_space, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_pf->desc, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_attr_md_enc(void const * const p_void_attr_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_attr_md_t * p_attr_md = (ble_gatts_attr_md_t *)p_void_attr_md; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_conn_sec_mode_enc(&p_attr_md->read_perm, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_conn_sec_mode_enc(&p_attr_md->write_perm, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - /* serializer does not support attributes on stack */ - if (p_attr_md->vloc != BLE_GATTS_VLOC_STACK) - { - err_code = NRF_ERROR_INVALID_PARAM; - } - - uint8_t temp8; - temp8 = p_attr_md->vlen | - (p_attr_md->vloc << 1) | - (p_attr_md->rd_auth << 3) | - (p_attr_md->wr_auth << 4); - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[*p_index] = temp8; - *p_index += 1; - - return err_code; -} - -uint32_t ble_gatts_attr_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_md) -{ - ble_gatts_attr_md_t * p_attr_md = (ble_gatts_attr_md_t *)p_void_attr_md; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_attr_md->read_perm); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_attr_md->write_perm); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &temp8); - - p_attr_md->vlen = temp8; - p_attr_md->vloc = temp8 >> 1; - p_attr_md->rd_auth = temp8 >> 3; - p_attr_md->wr_auth = temp8 >> 4; - - return err_code; -} - -uint32_t ble_gatts_char_md_enc(void const * const p_void_char_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - - ble_gatts_char_md_t * p_char_md = (ble_gatts_char_md_t *)p_void_char_md; - uint8_t temp8; - - temp8 = p_char_md->char_props.broadcast | - (p_char_md->char_props.read << 1) | - (p_char_md->char_props.write_wo_resp << 2) | - (p_char_md->char_props.write << 3) | - (p_char_md->char_props.notify << 4) | - (p_char_md->char_props.indicate << 5) | - (p_char_md->char_props.auth_signed_wr << 6); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - temp8 = p_char_md->char_ext_props.reliable_wr | - (p_char_md->char_ext_props.wr_aux << 1); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_md->char_user_desc_max_size, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ERROR_CHECK(p_char_md->char_user_desc_size <= BLE_GATTS_VAR_ATTR_LEN_MAX, - NRF_ERROR_INVALID_PARAM); - err_code = len16data_enc(p_char_md->p_char_user_desc, p_char_md->char_user_desc_size, p_buf, - buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_char_pf, - p_buf, - buf_len, - p_index, - ser_ble_gatts_char_pf_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_user_desc_md, - p_buf, - buf_len, - p_index, - ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_cccd_md, p_buf, buf_len, p_index, ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_sccd_md, p_buf, buf_len, p_index, ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_char_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_md) -{ - uint32_t err_code = NRF_SUCCESS; - - ble_gatts_char_md_t * p_char_md = (ble_gatts_char_md_t *)p_void_char_md; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint8_t temp8 = p_buf[*p_index]; - - p_char_md->char_props.broadcast = temp8 >> 0; - p_char_md->char_props.read = temp8 >> 1; - p_char_md->char_props.write_wo_resp = temp8 >> 2; - p_char_md->char_props.write = temp8 >> 3; - p_char_md->char_props.notify = temp8 >> 4; - p_char_md->char_props.indicate = temp8 >> 5; - p_char_md->char_props.auth_signed_wr = temp8 >> 6; - - temp8 = p_buf[*p_index + 1]; - p_char_md->char_ext_props.reliable_wr = temp8 >> 0; - p_char_md->char_ext_props.wr_aux = temp8 >> 1; - - *p_index += 2; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_char_md->char_user_desc_max_size); - - err_code = len16data_dec(p_buf, - buf_len, - p_index, - &p_char_md->p_char_user_desc, - &p_char_md->char_user_desc_size); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_char_pf, - ser_ble_gatts_char_pf_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_user_desc_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_cccd_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_sccd_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; - -} - -uint32_t ble_gatts_attr_enc(void const * const p_void_gatts_attr, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - ble_gatts_attr_t * p_gatts_attr = (ble_gatts_attr_t *)p_void_gatts_attr; - - err_code = cond_field_enc((void *)p_gatts_attr->p_uuid, p_buf, buf_len, p_index, ble_uuid_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_gatts_attr->p_attr_md, - p_buf, - buf_len, - p_index, - ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_gatts_attr->init_offs, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_gatts_attr->max_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ERROR_CHECK(p_gatts_attr->init_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); - //init len move just before p_data to be able to use len16data decoder. - err_code = len16data_enc(p_gatts_attr->p_value, p_gatts_attr->init_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_attr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_gatts_attr) -{ - uint32_t err_code = NRF_SUCCESS; - ble_gatts_attr_t * p_gatts_attr = (ble_gatts_attr_t *)p_void_gatts_attr; - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_gatts_attr->p_uuid, - ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_gatts_attr->p_attr_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_gatts_attr->init_offs); - uint16_dec(p_buf, buf_len, p_index, &p_gatts_attr->max_len); - - //init len move just before p_data to be able to use len16data decoder. - err_code = len16data_dec(p_buf, - buf_len, - p_index, - &p_gatts_attr->p_value, - &p_gatts_attr->init_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_char_handles_enc(void const * const p_void_char_handles, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_char_handles_t * p_char_handles = (ble_gatts_char_handles_t *)p_void_char_handles; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_char_handles->value_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_handles->user_desc_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_handles->cccd_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_handles->sccd_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_char_handles_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_handles) -{ - ble_gatts_char_handles_t * p_char_handles = (ble_gatts_char_handles_t *)p_void_char_handles; - - SER_ASSERT_LENGTH_LEQ(8, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_char_handles->value_handle)); - uint16_dec(p_buf, buf_len, p_index, &p_char_handles->user_desc_handle); - uint16_dec(p_buf, buf_len, p_index, &p_char_handles->cccd_handle); - uint16_dec(p_buf, buf_len, p_index, &p_char_handles->sccd_handle); - - return NRF_SUCCESS; -} - -uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_hvx_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_hvx_params_t * p_hvx_params = (ble_gatts_hvx_params_t *)p_void_hvx_params; - - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2 + 1 + 2, buf_len - *p_index); - - err_code = uint16_t_enc(&p_hvx_params->handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_hvx_params->type, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_hvx_params->offset, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_hvx_params->p_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[(*p_index)++] = SER_FIELD_PRESENT; - - err_code = uint16_t_enc(p_hvx_params->p_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - if (p_hvx_params->p_data != NULL) - { - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[(*p_index)++] = SER_FIELD_PRESENT; - - SER_ASSERT_LENGTH_LEQ(*p_hvx_params->p_len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_hvx_params->p_data, *p_hvx_params->p_len); - *p_index += *p_hvx_params->p_len; - } - - return err_code; -} - -uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_hvx_params) -{ - ble_gatts_hvx_params_t * p_hvx_params = (ble_gatts_hvx_params_t *)p_void_hvx_params; - - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2 + 1 + 2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_hvx_params->handle); - uint8_dec(p_buf, buf_len, p_index, &p_hvx_params->type); - uint16_dec(p_buf, buf_len, p_index, &p_hvx_params->offset); - - SER_ASSERT_NOT_NULL(&p_hvx_params->p_len); - err_code = cond_len16_cond_data_dec(p_buf, - buf_len, - p_index, - &p_hvx_params->p_data, - &p_hvx_params->p_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_attr_context_t_enc(void const * const p_void_attr_context, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gatts_attr_context_t * p_context = (ble_gatts_attr_context_t *) p_void_attr_context; - - error_code = ble_uuid_t_enc(&(p_context->srvc_uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_enc(&(p_context->char_uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_enc(&(p_context->desc_uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&(p_context->srvc_handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&(p_context->value_handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint8_t_enc(&(p_context->type), p_buf, buf_len, p_index); - - return error_code; -} - -uint32_t ble_gatts_attr_context_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_context) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gatts_attr_context_t * p_context = (ble_gatts_attr_context_t *) p_void_attr_context; - - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->srvc_uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->char_uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->desc_uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - SER_ASSERT_LENGTH_LEQ(5, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_context->srvc_handle)); - uint16_dec(p_buf, buf_len, p_index, &(p_context->value_handle)); - uint8_dec(p_buf, buf_len, p_index, &(p_context->type)); - return error_code; -} - -uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_evt_write_t * p_write = (ble_gatts_evt_write_t *) p_void_write; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint16_t_enc(&(p_write->handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint8_t_enc(&(p_write->op), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gatts_attr_context_t_enc(&(p_write->context), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&(p_write->offset), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - uint16_t data_len = p_write->len; - error_code = uint16_t_enc(&data_len, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - SER_ASSERT_LENGTH_LEQ(data_len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_write->data, data_len); - *p_index += data_len; - - return error_code; -} - -uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_write) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_struct_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t in_struct_len = *p_struct_len; - - *p_struct_len = offsetof(ble_gatts_evt_write_t, data); - - uint16_t handle; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint8_t op; - err_code = uint8_t_dec(p_buf, buf_len, p_index, &op); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - ble_gatts_attr_context_t context; - err_code = ble_gatts_attr_context_t_dec(p_buf, buf_len, p_index, &context); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint16_t offset; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint16_t len; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_struct_len += len; - - if (p_void_write != NULL) - { - ble_gatts_evt_write_t * p_write = (ble_gatts_evt_write_t *)p_void_write; - - SER_ASSERT_LENGTH_LEQ(*p_struct_len, in_struct_len); - - p_write->handle = handle; - p_write->op = op; - - memcpy(&(p_write->context), &context, sizeof (ble_gatts_attr_context_t)); - - p_write->offset = offset; - p_write->len = len; - - SER_ASSERT_LENGTH_LEQ(p_write->len, buf_len - *p_index); - memcpy(p_write->data, &p_buf[*p_index], p_write->len); - } - - *p_index += len; - - return err_code; -} - -uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_read, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_read); - - ble_gatts_evt_read_t * p_read = (ble_gatts_evt_read_t *)p_void_read; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_read->handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_attr_context_t_enc(&(p_read->context), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_read->offset), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_read) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - uint32_t err_code = NRF_SUCCESS; - uint32_t in_struct_len = *p_struct_len; - - *p_struct_len = sizeof (ble_gatts_evt_read_t); - - uint16_t handle; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - ble_gatts_attr_context_t context; - err_code = ble_gatts_attr_context_t_dec(p_buf, buf_len, p_index, &context); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint16_t offset; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_void_read != NULL) - { - ble_gatts_evt_read_t * p_read = (ble_gatts_evt_read_t *)p_void_read; - - SER_ASSERT_LENGTH_LEQ(*p_struct_len, in_struct_len); - - p_read->handle = handle; - memcpy(&(p_read->context), &context, sizeof (context)); - p_read->offset = offset; - } - - return err_code; -} - -uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_authorize_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_authorize_request); - - ble_gatts_evt_rw_authorize_request_t * p_authorize_request = - (ble_gatts_evt_rw_authorize_request_t *)p_void_authorize_request; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&(p_authorize_request->type), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - switch (p_authorize_request->type) - { - case BLE_GATTS_AUTHORIZE_TYPE_READ: - err_code = ble_gatts_evt_read_t_enc(&(p_authorize_request->request.read), - p_buf, - buf_len, - p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - case BLE_GATTS_AUTHORIZE_TYPE_WRITE: - err_code = ble_gatts_evt_write_t_enc(&(p_authorize_request->request.write), - p_buf, - buf_len, - p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - default: - case BLE_GATTS_AUTHORIZE_TYPE_INVALID: - err_code = NRF_ERROR_INVALID_PARAM; - break; - } - - return err_code; -} - -uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_authorize_request) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_struct_len); - SER_ASSERT_NOT_NULL(p_index); - - uint32_t err_code = NRF_SUCCESS; - - uint8_t type; - err_code = uint8_t_dec(p_buf, buf_len, p_index, &type); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t in_struct_len = *p_struct_len; - - *p_struct_len = offsetof(ble_gatts_evt_rw_authorize_request_t, request); - - ble_gatts_evt_rw_authorize_request_t * p_authorize_request = - (ble_gatts_evt_rw_authorize_request_t *)p_void_authorize_request; - - void * p_void_request = NULL; - - if (p_void_authorize_request != NULL) - { - p_authorize_request->type = type; - - SER_ASSERT_LENGTH_LEQ(*p_struct_len, in_struct_len); - - switch (type) - { - case BLE_GATTS_AUTHORIZE_TYPE_READ: - p_void_request = &(p_authorize_request->request.read); - break; - - case BLE_GATTS_AUTHORIZE_TYPE_WRITE: - p_void_request = &(p_authorize_request->request.write); - break; - - default: - case BLE_GATTS_AUTHORIZE_TYPE_INVALID: - return NRF_ERROR_INVALID_DATA; - } - } - - switch (type) - { - case BLE_GATTS_AUTHORIZE_TYPE_READ: - err_code = ble_gatts_evt_read_t_dec(p_buf, - buf_len, - p_index, - &in_struct_len, - p_void_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - case BLE_GATTS_AUTHORIZE_TYPE_WRITE: - err_code = ble_gatts_evt_write_t_dec(p_buf, - buf_len, - p_index, - &in_struct_len, - p_void_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - default: - case BLE_GATTS_AUTHORIZE_TYPE_INVALID: - return NRF_ERROR_INVALID_DATA; - } - *p_struct_len += in_struct_len; - - return err_code; -} - -uint32_t ble_gatts_read_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_read_authorize_params_t * p_params = - (ble_gatts_read_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint16_t_enc(&(p_params->gatt_status), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - uint8_t temp_val = p_params->update; - error_code = uint8_t_enc(&temp_val, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - error_code = uint16_t_enc(&(p_params->offset), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - error_code = len16data_enc(p_params->p_data, p_params->len, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gatts_read_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_read_authorize_params_t * p_params = - (ble_gatts_read_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_params->gatt_status); - - uint8_t temp_val; - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &temp_val); - p_params->update = temp_val; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_params->offset); - - error_code = len16data_dec(p_buf, buf_len, p_index, &p_params->p_data, &p_params->len); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gatts_write_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_write_authorize_params_t * p_params = - (ble_gatts_write_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint16_t_enc(&(p_params->gatt_status), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gatts_write_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_write_authorize_params_t * p_params = - (ble_gatts_write_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_params->gatt_status); - - return error_code; -} - -uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_rw_authorize_reply_params_t const * const p_params = - (ble_gatts_rw_authorize_reply_params_t * ) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint8_t_enc(&(p_params->type), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_READ) - { - error_code = ble_gatts_read_authorize_params_t_enc(&p_params->params.read, - p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) - { - error_code = ble_gatts_write_authorize_params_t_enc(&p_params->params.write, - p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else - { - return NRF_ERROR_INVALID_PARAM; - } - - return error_code; -} - -uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_rw_authorize_reply_params_t * p_params = - (ble_gatts_rw_authorize_reply_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &(p_params->type)); - - if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_READ) - { - error_code = ble_gatts_read_authorize_params_t_dec(p_buf, buf_len, p_index, - &p_params->params.read); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) - { - error_code = ble_gatts_write_authorize_params_t_dec(p_buf, buf_len, p_index, - &p_params->params.write); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else - { - return NRF_ERROR_INVALID_PARAM; - } - - return error_code; -} - -uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_enable_params_t * p_enable_params = (ble_gatts_enable_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - temp8 = (p_enable_params->service_changed & 0x01); - - err_code = uint8_t_enc((void *) &temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_enable_params_t * p_enable_params = (ble_gatts_enable_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &temp8); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_enable_params->service_changed = temp8 & 0x01; - - return err_code; -} - -uint32_t ble_gatts_value_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_value_t * p_value = (ble_gatts_value_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc((void *) &(p_value->len), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *) &(p_value->offset), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = buf_enc(p_value->p_value, p_value->len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_value_t * p_value = (ble_gatts_value_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint16_t total_len = p_value->len; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, (void *) &(p_value->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, (void *) &(p_value->offset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = buf_dec(p_buf, buf_len, p_index, &(p_value->p_value), total_len, p_value->len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s120/ble_gatts_struct_serialization.h b/components/serialization/common/struct_ser/s120/ble_gatts_struct_serialization.h deleted file mode 100644 index 6139d9e..0000000 --- a/components/serialization/common/struct_ser/s120/ble_gatts_struct_serialization.h +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_STRUCT_SERIALIZATION_H -#define BLE_GATTS_STRUCT_SERIALIZATION_H - -#include "ble_gatts.h" - -uint32_t ser_ble_gatts_char_pf_enc(void const * const p_void_char_pf, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ser_ble_gatts_char_pf_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_pf); - -uint32_t ble_gatts_attr_md_enc(void const * const p_void_attr_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_attr_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_md); - -uint32_t ble_gatts_char_md_enc(void const * const p_void_char_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_char_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_md); - -uint32_t ble_gatts_attr_enc(void const * const p_void_gatts_attr, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_attr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_gatts_attr); - -uint32_t ble_gatts_char_handles_enc(void const * const p_void_char_handles, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_char_handles_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_handles); - -uint32_t ble_gatts_attr_context_t_enc(void const * const p_void_attr_context, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_attr_context_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_context); - -uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_write); - -uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_hvx_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_hvx_params); - -uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_read, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_read); - -uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_authorize_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_size, - void * const p_void_authorize_request); - -uint32_t ble_gatts_read_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_read_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_write_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_write_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_value_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -#endif /* BLE_GATTS_STRUCT_SERIALIZATION_H */ diff --git a/components/serialization/common/struct_ser/s120/ble_struct_serialization.c b/components/serialization/common/struct_ser/s120/ble_struct_serialization.c deleted file mode 100644 index 264571f..0000000 --- a/components/serialization/common/struct_ser/s120/ble_struct_serialization.c +++ /dev/null @@ -1,276 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_types.h" -#include "ble_l2cap.h" -#include "ble.h" -#include "cond_field_serialization.h" -#include - - -uint32_t ble_uuid_t_enc(void const * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_uuid_t * p_uuid = (ble_uuid_t *)p_void_uuid; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_uuid->uuid, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_uuid->type, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid) -{ - ble_uuid_t * p_uuid = (ble_uuid_t *)p_void_uuid; - - SER_ASSERT_LENGTH_LEQ(3, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_uuid->uuid); - uint8_dec(p_buf, buf_len, p_index, &p_uuid->type); - - return NRF_SUCCESS; -} - -uint32_t ble_uuid128_t_enc(void const * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_uuid128_t * p_uuid = (ble_uuid128_t *)p_void_uuid; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(16, buf_len - *p_index); - - memcpy(&p_buf[*p_index], p_uuid->uuid128, sizeof (p_uuid->uuid128)); - - *p_index += sizeof (p_uuid->uuid128); - - return err_code; -} - -uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid) -{ - ble_uuid128_t * p_uuid = (ble_uuid128_t *)p_void_uuid; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(16, buf_len - *p_index); - - memcpy(p_uuid->uuid128, &p_buf[*p_index], sizeof (p_uuid->uuid128)); - - *p_index += sizeof (p_uuid->uuid128); - - return err_code; -} - -uint32_t ble_l2cap_header_t_enc(void const * const p_void_header, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_header); - - ble_l2cap_header_t * p_header = (ble_l2cap_header_t *)p_void_header; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_header->len), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_header->cid), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_header) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_header); - - ble_l2cap_header_t * p_header = (ble_l2cap_header_t *)p_void_header; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_header->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_header->cid)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_evt_rx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_evt_rx); - - ble_l2cap_evt_rx_t * p_evt_rx = (ble_l2cap_evt_rx_t *)p_void_evt_rx; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_l2cap_header_t_enc(&(p_evt_rx->header), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(p_evt_rx->header.len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_evt_rx->data, p_evt_rx->header.len); - *p_index += p_evt_rx->header.len; - - return err_code; -} - -uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_evt_rx) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_struct_len); - - ble_l2cap_evt_rx_t * p_evt_rx = (ble_l2cap_evt_rx_t *)p_void_evt_rx; - uint32_t err_code = NRF_SUCCESS; - - uint32_t total_struct_len = *p_struct_len; - - /* Get data length */ - uint32_t tmp_index = *p_index; - uint16_t len = 0; - - err_code = uint16_t_dec(p_buf, buf_len, &tmp_index, &len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - /* Update struct length */ - *p_struct_len = offsetof(ble_l2cap_evt_rx_t, data[0]); - *p_struct_len += (uint8_t*)&p_evt_rx->data[len] - (uint8_t*)&p_evt_rx->data[0]; - - /* Decode header and copy data */ - if (p_void_evt_rx != NULL) - { - SER_ASSERT_LENGTH_LEQ(*p_struct_len, total_struct_len); - - err_code = ble_l2cap_header_t_dec(p_buf, buf_len, p_index, &(p_evt_rx->header)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(p_evt_rx->header.len, buf_len - *p_index); - memcpy(p_evt_rx->data, &p_buf[*p_index], p_evt_rx->header.len); - *p_index += p_evt_rx->header.len; - } - - return err_code; -} - -uint32_t ble_enable_params_t_enc(void const * const p_void_enable_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_enable_params); - - ble_enable_params_t * p_enable_params = (ble_enable_params_t *)p_void_enable_params; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_enable_params_t_enc(&p_enable_params->gap_enable_params, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_enable_params_t_enc(&p_enable_params->gatts_enable_params, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_enable_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_enable_params); - - ble_enable_params_t * p_enable_params = (ble_enable_params_t *)p_void_enable_params; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_enable_params_t_dec(p_buf, buf_len, p_index, &(p_enable_params->gap_enable_params)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_enable_params_t_dec(p_buf, buf_len, p_index, &(p_enable_params->gatts_enable_params)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_common_opt_radio_cpu_mutex_t_enc(void const * const p_void_opt_mutex, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_opt_mutex); - - ble_common_opt_radio_cpu_mutex_t * p_radio_cpu_mutex = (ble_common_opt_radio_cpu_mutex_t *)p_void_opt_mutex; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_radio_cpu_mutex->enable; - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_common_opt_radio_cpu_mutex_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_opt_mutex) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_opt_mutex); - - ble_common_opt_radio_cpu_mutex_t * p_radio_cpu_mutex = (ble_common_opt_radio_cpu_mutex_t *)p_void_opt_mutex; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_radio_cpu_mutex->enable = byte & 0x01; - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s120/ble_struct_serialization.h b/components/serialization/common/struct_ser/s120/ble_struct_serialization.h deleted file mode 100644 index 032bdd9..0000000 --- a/components/serialization/common/struct_ser/s120/ble_struct_serialization.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_types.h" - - -uint32_t ble_uuid_t_enc(void const * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid); - -uint32_t ble_uuid128_t_enc(const void * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid); - -uint32_t ble_l2cap_header_t_enc(void const * const p_void_header, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_header); - -uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_evt_rx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_event_len, - void * const p_void_evt_rx); - -uint32_t ble_enable_params_t_enc(void const * const p_void_enable_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_enable_params); - -uint32_t ble_common_opt_radio_cpu_mutex_t_enc(void const * const p_void_opt_mutex, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_common_opt_radio_cpu_mutex_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_opt_mutex); diff --git a/components/serialization/common/struct_ser/s130/ble_gap_struct_serialization.c b/components/serialization/common/struct_ser/s130/ble_gap_struct_serialization.c deleted file mode 100644 index 7f180c4..0000000 --- a/components/serialization/common/struct_ser/s130/ble_gap_struct_serialization.c +++ /dev/null @@ -1,1363 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_struct_serialization.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" -#include "string.h" - -uint32_t ble_gap_irk_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_irk_t * p_gap_irk = (ble_gap_irk_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN, buf_len - *p_index); - - memcpy(&p_buf[*p_index], p_gap_irk->irk, BLE_GAP_SEC_KEY_LEN); - - *p_index += BLE_GAP_SEC_KEY_LEN; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_irk_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - ble_gap_irk_t * p_gap_irk = (ble_gap_irk_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN, buf_len - *p_index); - - memcpy(p_gap_irk->irk, &p_buf[*p_index], BLE_GAP_SEC_KEY_LEN); - - *p_index += BLE_GAP_SEC_KEY_LEN; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_addr_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_addr_t * p_addr = (ble_gap_addr_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(1 + BLE_GAP_ADDR_LEN, buf_len - *p_index); - - p_buf[*p_index] = p_addr->addr_type; - (*p_index)++; - memcpy(&p_buf[*p_index], p_addr->addr, BLE_GAP_ADDR_LEN); - *p_index += BLE_GAP_ADDR_LEN; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_addr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_addr) -{ - ble_gap_addr_t * p_address = (ble_gap_addr_t *) p_addr; - - SER_ASSERT_LENGTH_LEQ(1 + BLE_GAP_ADDR_LEN, (int32_t)buf_len - *p_index); - - p_address->addr_type = p_buf[*p_index]; - (*p_index)++; - memcpy(p_address->addr, &p_buf[*p_index], BLE_GAP_ADDR_LEN); - *p_index += BLE_GAP_ADDR_LEN; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sec_levels_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_sec_levels_t * p_sec_levels = (ble_gap_sec_levels_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - - p_buf[*p_index] = (p_sec_levels->lv1 << 0) | (p_sec_levels->lv2 << 1) | (p_sec_levels->lv3 << 2); - (*p_index)++; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sec_levels_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - ble_gap_sec_levels_t * p_sec_levels = (ble_gap_sec_levels_t *)p_data; - uint32_t err_code; - uint32_t uint8_temp; - - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_sec_levels_t), buf_len - *p_index); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &(uint8_temp)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_sec_levels->lv1 = uint8_temp & 0x01; - p_sec_levels->lv2 = (uint8_temp >> 1) & 0x01; - p_sec_levels->lv3 = (uint8_temp >> 2) & 0x01; - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_sec_keys_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_sec_keys_t * p_sec_keys = (ble_gap_sec_keys_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_enc(p_sec_keys->p_enc_key, p_buf, buf_len, p_index, ble_gap_enc_key_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_keys->p_id_key, p_buf, buf_len, p_index, ble_gap_id_key_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_sec_keys->p_sign_key, p_buf, buf_len, p_index, ble_gap_sign_info_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_keys_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - ble_gap_sec_keys_t * p_sec_keys = (ble_gap_sec_keys_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void * *)&(p_sec_keys->p_enc_key), ble_gap_enc_key_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void * *)&(p_sec_keys->p_id_key), ble_gap_id_key_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void * *)&(p_sec_keys->p_sign_key), ble_gap_sign_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enc_info_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - ble_gap_enc_info_t * p_enc_info = (ble_gap_enc_info_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN + 1, buf_len - *p_index); - - memcpy(&p_buf[*p_index], p_enc_info->ltk, BLE_GAP_SEC_KEY_LEN); - *p_index += BLE_GAP_SEC_KEY_LEN; - - p_buf[*p_index] = p_enc_info->auth & 0x01; - p_buf[*p_index] |= (p_enc_info->ltk_len & 0x7F) << 1; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_enc_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_enc_infox) -{ - ble_gap_enc_info_t * p_enc_info = (ble_gap_enc_info_t *)p_enc_infox; - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_KEY_LEN, buf_len - *p_index); - memcpy(p_enc_info->ltk, &p_buf[*p_index], BLE_GAP_SEC_KEY_LEN); - *p_index += BLE_GAP_SEC_KEY_LEN; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_enc_info->auth = p_buf[*p_index] & 0x01; - p_enc_info->ltk_len = (p_buf[*p_index] >> 1) & 0x7F; - *p_index += 1; - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sign_info_enc(void const * const p_sign_info, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_sign_info_t), buf_len - *p_index); - memcpy(&p_buf[*p_index], p_sign_info, sizeof (ble_gap_sign_info_t)); - *p_index += sizeof (ble_gap_sign_info_t); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_sign_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_sign_info) -{ - SER_ASSERT_LENGTH_LEQ(sizeof (ble_gap_sign_info_t), buf_len - *p_index); - memcpy(p_sign_info, &p_buf[*p_index], sizeof (ble_gap_sign_info_t)); - *p_index += sizeof (ble_gap_sign_info_t); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - ble_gap_evt_auth_status_t * p_auth_status = (ble_gap_evt_auth_status_t *)p_data; - - SER_ASSERT_LENGTH_LEQ(6, buf_len - *p_index); - - err_code = uint8_t_enc(&(p_auth_status->auth_status), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - byte = (p_auth_status->error_src) | ((p_auth_status->bonded) << 2); - - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_levels_enc(&(p_auth_status->sm1_levels), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_levels_enc(&(p_auth_status->sm2_levels), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc(&(p_auth_status->kdist_periph), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc(&(p_auth_status->kdist_central), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - - ble_gap_evt_auth_status_t * p_auth_status = (ble_gap_evt_auth_status_t *)p_data; - uint32_t err_code; - uint8_t byte; - - SER_ASSERT_LENGTH_LEQ(6, buf_len - *p_index); - SER_ASSERT_NOT_NULL(p_auth_status); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_auth_status->auth_status)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_auth_status->error_src = byte & 0x03; - p_auth_status->bonded = (byte >> 2) & 0x01 ; - - err_code = ble_gap_sec_levels_dec(p_buf, buf_len, p_index, &(p_auth_status->sm1_levels)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_levels_dec(p_buf, buf_len, p_index, &(p_auth_status->sm2_levels)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, &(p_auth_status->kdist_periph)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, &(p_auth_status->kdist_central)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - - -uint32_t ble_gap_conn_sec_mode_enc(void const * const p_void_sec_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_conn_sec_mode_t * p_sec_mode = (ble_gap_conn_sec_mode_t *)p_void_sec_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8 = p_sec_mode->sm | (p_sec_mode->lv << 4); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_conn_sec_mode_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_mode) -{ - ble_gap_conn_sec_mode_t * p_sec_mode = (ble_gap_conn_sec_mode_t *)p_void_sec_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &temp8); - - p_sec_mode->sm = temp8; - p_sec_mode->lv = temp8 >> 4; - - return err_code; -} - -uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_conn_sec_update, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_conn_sec_t_enc(p_void_conn_sec_update, p_buf, buf_len, p_index); -} - -uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_conn_sec_update) -{ - return ble_gap_conn_sec_t_dec(p_buf, buf_len, p_index, p_void_conn_sec_update); -} - -uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_sec, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_conn_sec_t * p_conn_sec = (ble_gap_conn_sec_t *)p_void_sec; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_conn_sec_mode_enc(&p_conn_sec->sec_mode, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_conn_sec->encr_key_size, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec) -{ - ble_gap_conn_sec_t * p_conn_sec = (ble_gap_conn_sec_t *)p_void_sec; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_conn_sec->sec_mode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &p_conn_sec->encr_key_size); - - return err_code; -} - -uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_sec_info_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_evt_sec_info_request_t * p_conn_sec = - (ble_gap_evt_sec_info_request_t *)p_void_sec_info_request; - - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_addr_enc(&p_conn_sec->peer_addr, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_enc(&p_conn_sec->master_id, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint8_t temp8 = p_conn_sec->enc_info | - (p_conn_sec->id_info << 1) | - (p_conn_sec->sign_info << 2); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_info_request) -{ - ble_gap_evt_sec_info_request_t * p_conn_sec = (ble_gap_evt_sec_info_request_t *)p_void_sec_info_request; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_conn_sec->peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_dec(p_buf, buf_len, p_index, &(p_conn_sec->master_id)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &temp8); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_conn_sec->enc_info = temp8 & 0x01; - p_conn_sec->id_info = (temp8 >> 1) & 0x01; - p_conn_sec->sign_info = (temp8 >> 2) & 0x01; - - return err_code; -} - -uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_evt_connected_t * p_evt_conn = (ble_gap_evt_connected_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte = 0; - - err_code = ble_gap_addr_enc((void *)&p_evt_conn->peer_addr, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc((void *)&p_evt_conn->own_addr, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&(p_evt_conn->role), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - byte = p_evt_conn->irk_match | (p_evt_conn->irk_match_idx << 1); - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_conn_params_t_enc((void *)&p_evt_conn->conn_params, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_connected) -{ - ble_gap_evt_connected_t * p_evt_conn = (ble_gap_evt_connected_t *)p_void_connected; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte = 0; - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_evt_conn->peer_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_evt_conn->own_addr)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_evt_conn->role)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_evt_conn->irk_match = byte & 0x01; - p_evt_conn->irk_match_idx = (byte & 0xFE) >> 1; - - err_code = ble_gap_conn_params_t_dec(p_buf, buf_len, p_index, &(p_evt_conn->conn_params)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_sec_params_t * p_sec_params = (ble_gap_sec_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - temp8 = (p_sec_params->bond & 0x01) | - ((p_sec_params->mitm & 0x01) << 1) | - ((p_sec_params->io_caps & 0x07) << 2) | - ((p_sec_params->oob & 0x01) << 5); - - err_code = uint8_t_enc((void *) &temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *) &(p_sec_params->min_key_size), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *) &(p_sec_params->max_key_size), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc((void *) &(p_sec_params->kdist_periph), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_enc((void *) &(p_sec_params->kdist_central), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gap_sec_params_t * p_sec_params = (ble_gap_sec_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &temp8); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_sec_params->bond = temp8 & 0x01; - p_sec_params->mitm = (temp8 >> 1) & 0x01; - p_sec_params->io_caps = (temp8 >> 2) & 0x07; - p_sec_params->oob = (temp8 >> 5) & 0x01; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->min_key_size)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->max_key_size)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->kdist_periph)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_kdist_t_dec(p_buf, buf_len, p_index, (void *) &(p_sec_params->kdist_central)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ -// ble_gap_enable_params_t * p_enable_params = (ble_gap_enable_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8 = 0; - -// temp8 = (p_enable_params->role & 0x03); - - err_code = uint8_t_enc((void *) &temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ -// ble_gap_enable_params_t * p_enable_params = (ble_gap_enable_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8 = 0; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &temp8); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); -// p_enable_params->role = temp8 & 0x03; - - return err_code; -} - -uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_sec_params_t_enc(p_void_struct, p_buf, buf_len, p_index); -} - - uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) - { - return ble_gap_sec_params_t_dec(p_buf, buf_len, p_index, p_void_struct); - } - -uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_evt_conn_param_update, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_conn_params_t_enc(p_void_evt_conn_param_update, p_buf, buf_len, p_index); -} - -uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_evt_conn_param_update) -{ - return ble_gap_conn_params_t_dec(p_buf, buf_len, p_index, p_void_evt_conn_param_update); -} - -uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_evt_conn_param_update_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - return ble_gap_conn_params_t_enc(p_void_evt_conn_param_update_request, p_buf, buf_len, p_index); -} - -uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_evt_conn_param_update_request) -{ - return ble_gap_conn_params_t_dec(p_buf, buf_len, p_index, p_void_evt_conn_param_update_request); -} - -uint32_t ble_gap_conn_params_t_enc(void const * const p_void_conn_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_conn_params_t * p_conn_params = (ble_gap_conn_params_t *)p_void_conn_params; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_conn_params->min_conn_interval, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_conn_params->max_conn_interval, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_conn_params->slave_latency, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_conn_params->conn_sup_timeout, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_conn_params) -{ - ble_gap_conn_params_t * p_conn_params = (ble_gap_conn_params_t *)p_void_conn_params; - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->min_conn_interval); - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->max_conn_interval); - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->slave_latency); - - SER_ASSERT_LENGTH_LEQ(*p_index + 2, buf_len); - uint16_dec(p_buf, buf_len, p_index, &p_conn_params->conn_sup_timeout); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_disconnected, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_evt_disconnected_t * p_disconnected = (ble_gap_evt_disconnected_t *)p_void_disconnected; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&p_disconnected->reason, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_disconnected) -{ - ble_gap_evt_disconnected_t * p_disconnected = (ble_gap_evt_disconnected_t *)p_void_disconnected; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &p_disconnected->reason); - - return err_code; -} - -uint32_t ble_gap_master_id_t_enc(void const * const p_master_idx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gap_master_id_t * p_master_id = (ble_gap_master_id_t *) p_master_idx; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_master_id->ediv), p_buf, buf_len, p_index); - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_RAND_LEN, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_master_id->rand, BLE_GAP_SEC_RAND_LEN); - *p_index += BLE_GAP_SEC_RAND_LEN; - - return err_code; -} - -uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_master_idx) -{ - ble_gap_master_id_t *p_master_id = (ble_gap_master_id_t *)p_master_idx; - - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_master_id->ediv)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(BLE_GAP_SEC_RAND_LEN, buf_len - *p_index); - memcpy(p_master_id->rand, &p_buf[*p_index], BLE_GAP_SEC_RAND_LEN); - *p_index += BLE_GAP_SEC_RAND_LEN; - - return err_code; -} - -uint32_t ble_gap_whitelist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_whitelist_t *p_whitelist = (ble_gap_whitelist_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - uint32_t i = 0; - - SER_ERROR_CHECK(p_whitelist->addr_count <= BLE_GAP_WHITELIST_ADDR_MAX_COUNT, - NRF_ERROR_INVALID_PARAM); - SER_ERROR_CHECK(p_whitelist->irk_count <= BLE_GAP_WHITELIST_IRK_MAX_COUNT, - NRF_ERROR_INVALID_PARAM); - - err_code = uint8_t_enc(&(p_whitelist->addr_count), p_buf, buf_len, p_index); - - err_code = cond_field_enc(p_whitelist->pp_addrs, p_buf, buf_len, p_index, NULL); - - for (i = 0; i < p_whitelist->addr_count; i++) - { - err_code = cond_field_enc(p_whitelist->pp_addrs[i], p_buf, buf_len, p_index, ble_gap_addr_enc); - } - - err_code = uint8_t_enc(&(p_whitelist->irk_count), p_buf, buf_len, p_index); - - err_code = cond_field_enc(p_whitelist->pp_irks, p_buf, buf_len, p_index, NULL); - - for (i = 0; i < p_whitelist->irk_count; i++) - { - err_code = cond_field_enc(p_whitelist->pp_irks[i], p_buf, buf_len, p_index, ble_gap_irk_enc); - } - - return err_code; -} - -uint32_t ble_gap_whitelist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_whitelist_t * p_whitelist = (ble_gap_whitelist_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - uint32_t i = 0; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_whitelist->addr_count)); - SER_ERROR_CHECK(p_whitelist->addr_count <= BLE_GAP_WHITELIST_ADDR_MAX_COUNT, - NRF_ERROR_INVALID_LENGTH); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_addrs), NULL); - - for (i = 0; i < p_whitelist->addr_count; i++) - { - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_addrs[i]), ble_gap_addr_dec); - } - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_whitelist->irk_count)); - SER_ERROR_CHECK(p_whitelist->irk_count <= BLE_GAP_WHITELIST_IRK_MAX_COUNT, - NRF_ERROR_INVALID_LENGTH); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_irks), NULL); - - for (i = 0; i < p_whitelist->irk_count; i++) - { - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_whitelist->pp_irks[i]), ble_gap_irk_dec); - } - - return err_code; -} - -uint32_t ble_gap_scan_params_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_scan_params_t * p_scan_params = (ble_gap_scan_params_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[*p_index] = p_scan_params->active & 0x01; - p_buf[*p_index] |= (p_scan_params->selective & 0x7F) << 1; - (*p_index)++; - - err_code = cond_field_enc(p_scan_params->p_whitelist, p_buf, buf_len, p_index, ble_gap_whitelist_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_scan_params->interval), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_scan_params->window), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_scan_params->timeout), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_scan_params_t * p_scan_params = (ble_gap_scan_params_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_scan_params->active = p_buf[*p_index] & 0x01; - p_scan_params->selective = (p_buf[*p_index] >> 1) & 0x7F; - (*p_index)++; - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_scan_params->p_whitelist), ble_gap_whitelist_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_scan_params->interval)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_scan_params->window)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_scan_params->timeout)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enc_key_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_enc_key_t * p_enc_key = (ble_gap_enc_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_enc_info_enc(&(p_enc_key->enc_info), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_enc(&(p_enc_key->master_id), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_enc_key_t * p_enc_key = (ble_gap_enc_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_enc_info_dec(p_buf, buf_len, p_index, &(p_enc_key->enc_info)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_master_id_t_dec(p_buf, buf_len, p_index, &(p_enc_key->master_id)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} -uint32_t ble_gap_id_key_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_id_key_t * p_id_key = (ble_gap_id_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_irk_enc(&(p_id_key->id_info), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc(&(p_id_key->id_addr_info), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_id_key_t * p_id_key = (ble_gap_id_key_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_irk_dec(p_buf, buf_len, p_index, &(p_id_key->id_info)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_dec(p_buf, buf_len, p_index, &(p_id_key->id_addr_info)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_keyset_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_keyset_t * p_sec_keyset = (ble_gap_sec_keyset_t *) p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_sec_keys_enc(&(p_sec_keyset->keys_periph), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keys_enc(&(p_sec_keyset->keys_central), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_keyset_t * p_sec_keyset = (ble_gap_sec_keyset_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_sec_keys_dec(p_buf, buf_len, p_index, &(p_sec_keyset->keys_periph)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keys_dec(p_buf, buf_len, p_index, &(p_sec_keyset->keys_central)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_evt_sec_request_t * p_evt_sec_request = (ble_gap_evt_sec_request_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - - p_buf[*p_index] = p_evt_sec_request->bond & 0x01; - p_buf[*p_index] |= (p_evt_sec_request->mitm & 0x01) << 1; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_evt_sec_request_t * p_sec_request = (ble_gap_evt_sec_request_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_sec_request->bond = p_buf[*p_index] & 0x01; - p_sec_request->mitm = (p_buf[*p_index] >> 1) & 0x01; - *p_index += 1; - - return err_code; -} - -uint32_t ble_gap_sec_kdist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_kdist_t * p_sec_kdist = (ble_gap_sec_kdist_t *) p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - - p_buf[*p_index] = p_sec_kdist->enc & 0x01; - p_buf[*p_index] |= (p_sec_kdist->id & 0x01) << 1; - p_buf[*p_index] |= (p_sec_kdist->sign & 0x01) << 2; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_sec_kdist_t * p_sec_kdist = (ble_gap_sec_kdist_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_sec_kdist->enc = p_buf[*p_index] & 0x01; - p_sec_kdist->id = (p_buf[*p_index] >> 1) & 0x01; - p_sec_kdist->sign = (p_buf[*p_index] >> 2) & 0x01; - (*p_index)++; - - return err_code; -} - -uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_ch_map_t * p_gap_opt_ch_map = (ble_gap_opt_ch_map_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_gap_opt_ch_map->conn_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(5, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_gap_opt_ch_map->ch_map, 5); - - *p_index += 5; - - return err_code; -} - -uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_ch_map_t * p_gap_opt_ch_map = (ble_gap_opt_ch_map_t *)p_data; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &p_gap_opt_ch_map->conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(5, buf_len - *p_index); - memcpy(p_gap_opt_ch_map->ch_map, &p_buf[*p_index], 5); - - *p_index += 5; - - return err_code; -} - -uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_local_conn_latency, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_local_conn_latency_t * p_latency = - (ble_gap_opt_local_conn_latency_t *)p_void_local_conn_latency; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_latency->conn_handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_latency->requested_latency), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_latency->p_actual_latency, p_buf, buf_len, p_index, uint16_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_local_conn_latency) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_local_conn_latency_t * p_latency = - (ble_gap_opt_local_conn_latency_t *)p_void_local_conn_latency; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_latency->conn_handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_latency->requested_latency)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_latency->p_actual_latency), - uint16_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_passkey, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_passkey_t * p_opt_passkey = (ble_gap_opt_passkey_t *)p_void_passkey; - uint32_t err_code = NRF_SUCCESS; - uint16_t passkey_len = BLE_GAP_PASSKEY_LEN; - - err_code = buf_enc(p_opt_passkey->p_passkey, passkey_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_passkey) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_passkey_t * p_opt_passkey = (ble_gap_opt_passkey_t *)p_void_passkey; - uint32_t err_code = NRF_SUCCESS; - uint16_t passkey_len = BLE_GAP_PASSKEY_LEN; - - err_code = buf_dec(p_buf, buf_len, p_index, &p_opt_passkey->p_passkey, passkey_len, - passkey_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_privacy_t_enc(void const * const p_void_privacy, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_privacy_t * p_privacy = (ble_gap_opt_privacy_t *)p_void_privacy; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_enc(p_privacy->p_irk, p_buf, buf_len, p_index, ble_gap_irk_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_privacy->interval_s), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_privacy_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_privacy) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_privacy_t * p_privacy = (ble_gap_opt_privacy_t *)p_void_privacy; - uint32_t err_code = NRF_SUCCESS; - - err_code = cond_field_dec(p_buf, buf_len, p_index, (void **) &(p_privacy->p_irk), ble_gap_irk_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_privacy->interval_s)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_scan_req_report, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_scan_req_report_t * p_scan_req_report = (ble_gap_opt_scan_req_report_t *)p_void_scan_req_report; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_scan_req_report->enable; - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_scan_req_report) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_scan_req_report_t * p_scan_req_report = (ble_gap_opt_scan_req_report_t *)p_void_scan_req_report; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_scan_req_report->enable = byte & 0x01; - - return err_code; -} - -uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_compat_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_compat_mode_t * p_compat_mode = (ble_gap_opt_compat_mode_t *)p_void_compat_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte = 0; - - byte = p_compat_mode->mode_1_enable; - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_compat_mode) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_opt_compat_mode_t * p_compat_mode = (ble_gap_opt_compat_mode_t *)p_void_compat_mode; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte = 0; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_compat_mode->mode_1_enable = byte & 0x01; - - return err_code; -} - -uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_ch_mask, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_adv_ch_mask_t * p_ch_mask = (ble_gap_adv_ch_mask_t *)p_void_ch_mask; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_ch_mask->ch_37_off | - (p_ch_mask->ch_38_off << 1) | - (p_ch_mask->ch_39_off << 2); - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_ch_mask) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - ble_gap_adv_ch_mask_t * p_ch_mask = (ble_gap_adv_ch_mask_t *)p_void_ch_mask; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_ch_mask->ch_37_off = byte & 0x01; - p_ch_mask->ch_38_off = (byte >> 1) & 0x01; - p_ch_mask->ch_39_off = (byte >> 2) & 0x01; - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s130/ble_gattc_struct_serialization.c b/components/serialization/common/struct_ser/s130/ble_gattc_struct_serialization.c deleted file mode 100644 index 9c36a55..0000000 --- a/components/serialization/common/struct_ser/s130/ble_gattc_struct_serialization.c +++ /dev/null @@ -1,363 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "ble_gattc_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gattc.h" -#include "cond_field_serialization.h" -#include - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gattc_evt_char_val_by_uuid_read_rsp_t * p_read = - (ble_gattc_evt_char_val_by_uuid_read_rsp_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_read->count), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_read->value_len), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t i; - ble_gattc_handle_value_t * p_handle_value = &p_read->handle_value[0]; - - for (i = 0; i < p_read->count; i++) - { - err_code = uint16_t_enc(&(p_handle_value->handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(p_read->value_len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_handle_value->p_value, p_read->value_len); - *p_index += p_read->value_len; - - p_handle_value++; - } - - return err_code; -} - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_size, - void * const p_void_struct) -{ - ble_gattc_evt_char_val_by_uuid_read_rsp_t * p_read = - (ble_gattc_evt_char_val_by_uuid_read_rsp_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint16_t value_len; - uint16_t count; - uint32_t i; - - SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &count); - uint16_dec(p_buf, buf_len, p_index, &value_len); - - uint32_t total_struct_size = *p_struct_size; - - //calculate the size of the struct - *p_struct_size = offsetof(ble_gattc_evt_char_val_by_uuid_read_rsp_t, handle_value[0]); - *p_struct_size += sizeof(((ble_gattc_evt_char_val_by_uuid_read_rsp_t *)0)->handle_value) * count; - *p_struct_size += value_len * count; - - if (p_read) - { - p_read->value_len = value_len; - p_read->count = count; - - ble_gattc_handle_value_t * p_handle_value; - uint8_t * p_value; - - SER_ASSERT_LENGTH_LEQ(*p_struct_size, total_struct_size); - - p_value = (uint8_t *)&p_read->handle_value[count]; - - for (i = 0; i < count; i++) - { - p_handle_value = (ble_gattc_handle_value_t *)&p_read->handle_value[i]; - p_handle_value->p_value = p_value; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_handle_value->handle)); - - SER_ASSERT_LENGTH_LEQ(p_read->value_len, buf_len - *p_index); - memcpy(p_handle_value->p_value, &p_buf[*p_index], p_read->value_len); - *p_index += p_read->value_len; - - p_value += value_len; - } - } - else - { - *p_index += count * (value_len + 2); - } - - return err_code; -} - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gattc_evt_char_vals_read_rsp_t * p_read = - (ble_gattc_evt_char_vals_read_rsp_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - //Encode len - error_code = uint16_t_enc(&(p_read->len), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - //Encode values - SER_ASSERT_LENGTH_LEQ(p_read->len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_read->values, p_read->len); - *p_index += p_read->len; - - return error_code; -} - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gattc_evt_char_vals_read_rsp_t * p_read = - (ble_gattc_evt_char_vals_read_rsp_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - //Decode len - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_read->len)); - - //Decode values - SER_ASSERT_LENGTH_LEQ(p_read->len, buf_len - *p_index); - memcpy(p_read->values, &p_buf[*p_index], p_read->len); - *p_index += p_read->len; - - return error_code; -} - -uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gattc_handle_range_t * p_range = (ble_gattc_handle_range_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_range->start_handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_range->end_handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gattc_handle_range_t * p_range = (ble_gattc_handle_range_t *) p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_range->start_handle)); - uint16_dec(p_buf, buf_len, p_index, &(p_range->end_handle)); - - return err_code; -} - - -uint32_t ble_gattc_service_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_service_t * p_service = (ble_gattc_service_t *) p_void_struct; - - error_code = ble_uuid_t_enc(&(p_service->uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_handle_range_t_enc(&(p_service->handle_range), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_service_t * p_service = (ble_gattc_service_t *) p_void_struct; - - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_service->uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_handle_range_t_dec(p_buf, buf_len, p_index, &(p_service->handle_range)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_include_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_void_struct; - - error_code = uint16_t_enc(&(p_include->handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_service_t_enc(&(p_include->included_srvc), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_void_struct; - - error_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_include->handle)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_service_t_dec(p_buf, buf_len, p_index, &(p_include->included_srvc)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - uint32_t i; - ble_gattc_evt_rel_disc_rsp_t * p_rsp = (ble_gattc_evt_rel_disc_rsp_t *) p_void_struct; - - error_code = uint16_t_enc(&(p_rsp->count), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_rsp->includes; - - for (i = 0; i < p_rsp->count; i++) - { - error_code = ble_gattc_include_t_enc(p_include, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - p_include++; - } - - return error_code; -} - -uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gattc_evt_rel_disc_rsp_t * p_rsp = (ble_gattc_evt_rel_disc_rsp_t *) p_void_struct; - uint16_t include_count; - uint32_t i; - - error_code = uint16_t_dec(p_buf, buf_len, p_index, &include_count); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - p_rsp->count = include_count; - - ble_gattc_include_t * p_include = (ble_gattc_include_t *) p_rsp->includes; - - for (i = 0; i < include_count; i++) - { - error_code = ble_gattc_include_t_dec(p_buf, buf_len, p_index, p_include); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - p_include++; - } - - return error_code; -} - -uint32_t ble_gattc_write_params_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_void_write); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - uint32_t err_code = NRF_SUCCESS; - - ble_gattc_write_params_t * p_write = (ble_gattc_write_params_t *)p_void_write; - - err_code = uint8_t_enc(&(p_write->write_op), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&(p_write->flags), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_write->handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_write->offset), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len16data_enc(p_write->p_value, p_write->len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_write) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_write); - - uint32_t err_code = NRF_SUCCESS; - - ble_gattc_write_params_t * p_write = (ble_gattc_write_params_t *)p_void_write; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_write->write_op)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &(p_write->flags)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_write->handle)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_write->offset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = len16data_dec(p_buf, buf_len, p_index, &(p_write->p_value), &(p_write->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s130/ble_gattc_struct_serialization.h b/components/serialization/common/struct_ser/s130/ble_gattc_struct_serialization.h deleted file mode 100644 index cbfae81..0000000 --- a/components/serialization/common/struct_ser/s130/ble_gattc_struct_serialization.h +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_STRUCT_SERIALIZATION_H -#define BLE_GATTC_STRUCT_SERIALIZATION_H - -#include "ble_gattc.h" - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_size, - void * const p_void_struct); - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_service_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_include_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gattc_write_params_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_write); - -#endif /*BLE_GATTC_STRUCT_SERIALIZATION_H*/ diff --git a/components/serialization/common/struct_ser/s130/ble_gatts_struct_serialization.c b/components/serialization/common/struct_ser/s130/ble_gatts_struct_serialization.c deleted file mode 100644 index dbcf94b..0000000 --- a/components/serialization/common/struct_ser/s130/ble_gatts_struct_serialization.c +++ /dev/null @@ -1,965 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gatts.h" -#include "cond_field_serialization.h" -#include - -uint32_t ser_ble_gatts_char_pf_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_pf) -{ - ble_gatts_char_pf_t * p_char_pf = (ble_gatts_char_pf_t *)p_void_char_pf; - - SER_ASSERT_LENGTH_LEQ(7, buf_len - *p_index); - - uint8_dec(p_buf, buf_len, p_index, &p_char_pf->format); - uint8_dec(p_buf, buf_len, p_index, (uint8_t *)&p_char_pf->exponent); - uint16_dec(p_buf, buf_len, p_index, &p_char_pf->unit); - uint8_dec(p_buf, buf_len, p_index, &p_char_pf->name_space); - uint16_dec(p_buf, buf_len, p_index, &p_char_pf->desc); - - return NRF_SUCCESS; -} - -uint32_t ser_ble_gatts_char_pf_enc(void const * const p_void_char_pf, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_char_pf_t * p_char_pf = (ble_gatts_char_pf_t *)p_void_char_pf; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&p_char_pf->format, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_char_pf->exponent, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_pf->unit, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_char_pf->name_space, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_pf->desc, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_attr_md_enc(void const * const p_void_attr_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_attr_md_t * p_attr_md = (ble_gatts_attr_md_t *)p_void_attr_md; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gap_conn_sec_mode_enc(&p_attr_md->read_perm, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_conn_sec_mode_enc(&p_attr_md->write_perm, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - /* serializer does not support attributes on stack */ - if (p_attr_md->vloc != BLE_GATTS_VLOC_STACK) - { - err_code = NRF_ERROR_INVALID_PARAM; - } - - uint8_t temp8; - temp8 = p_attr_md->vlen | - (p_attr_md->vloc << 1) | - (p_attr_md->rd_auth << 3) | - (p_attr_md->wr_auth << 4); - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[*p_index] = temp8; - *p_index += 1; - - return err_code; -} - -uint32_t ble_gatts_attr_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_md) -{ - ble_gatts_attr_md_t * p_attr_md = (ble_gatts_attr_md_t *)p_void_attr_md; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8; - - err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_attr_md->read_perm); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_conn_sec_mode_dec(p_buf, buf_len, p_index, &p_attr_md->write_perm); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &temp8); - - p_attr_md->vlen = temp8; - p_attr_md->vloc = temp8 >> 1; - p_attr_md->rd_auth = temp8 >> 3; - p_attr_md->wr_auth = temp8 >> 4; - - return err_code; -} - -uint32_t ble_gatts_char_md_enc(void const * const p_void_char_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - - ble_gatts_char_md_t * p_char_md = (ble_gatts_char_md_t *)p_void_char_md; - uint8_t temp8; - - temp8 = p_char_md->char_props.broadcast | - (p_char_md->char_props.read << 1) | - (p_char_md->char_props.write_wo_resp << 2) | - (p_char_md->char_props.write << 3) | - (p_char_md->char_props.notify << 4) | - (p_char_md->char_props.indicate << 5) | - (p_char_md->char_props.auth_signed_wr << 6); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - temp8 = p_char_md->char_ext_props.reliable_wr | - (p_char_md->char_ext_props.wr_aux << 1); - - err_code = uint8_t_enc(&temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_md->char_user_desc_max_size, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ERROR_CHECK(p_char_md->char_user_desc_size <= BLE_GATTS_VAR_ATTR_LEN_MAX, - NRF_ERROR_INVALID_PARAM); - err_code = len16data_enc(p_char_md->p_char_user_desc, p_char_md->char_user_desc_size, p_buf, - buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_char_pf, - p_buf, - buf_len, - p_index, - ser_ble_gatts_char_pf_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_user_desc_md, - p_buf, - buf_len, - p_index, - ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_cccd_md, p_buf, buf_len, p_index, ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc(p_char_md->p_sccd_md, p_buf, buf_len, p_index, ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_char_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_md) -{ - uint32_t err_code = NRF_SUCCESS; - - ble_gatts_char_md_t * p_char_md = (ble_gatts_char_md_t *)p_void_char_md; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint8_t temp8 = p_buf[*p_index]; - - p_char_md->char_props.broadcast = temp8 >> 0; - p_char_md->char_props.read = temp8 >> 1; - p_char_md->char_props.write_wo_resp = temp8 >> 2; - p_char_md->char_props.write = temp8 >> 3; - p_char_md->char_props.notify = temp8 >> 4; - p_char_md->char_props.indicate = temp8 >> 5; - p_char_md->char_props.auth_signed_wr = temp8 >> 6; - - temp8 = p_buf[*p_index + 1]; - p_char_md->char_ext_props.reliable_wr = temp8 >> 0; - p_char_md->char_ext_props.wr_aux = temp8 >> 1; - - *p_index += 2; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_char_md->char_user_desc_max_size); - - err_code = len16data_dec(p_buf, - buf_len, - p_index, - &p_char_md->p_char_user_desc, - &p_char_md->char_user_desc_size); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_char_pf, - ser_ble_gatts_char_pf_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_user_desc_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_cccd_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_char_md->p_sccd_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; - -} - -uint32_t ble_gatts_attr_enc(void const * const p_void_gatts_attr, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t err_code = NRF_SUCCESS; - ble_gatts_attr_t * p_gatts_attr = (ble_gatts_attr_t *)p_void_gatts_attr; - - err_code = cond_field_enc((void *)p_gatts_attr->p_uuid, p_buf, buf_len, p_index, ble_uuid_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_enc((void *)p_gatts_attr->p_attr_md, - p_buf, - buf_len, - p_index, - ble_gatts_attr_md_enc); - SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_gatts_attr->init_offs, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_gatts_attr->max_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ERROR_CHECK(p_gatts_attr->init_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); - //init len move just before p_data to be able to use len16data decoder. - err_code = len16data_enc(p_gatts_attr->p_value, p_gatts_attr->init_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_attr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_gatts_attr) -{ - uint32_t err_code = NRF_SUCCESS; - ble_gatts_attr_t * p_gatts_attr = (ble_gatts_attr_t *)p_void_gatts_attr; - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_gatts_attr->p_uuid, - ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - p_index, - (void * *)&p_gatts_attr->p_attr_md, - ble_gatts_attr_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_gatts_attr->init_offs); - uint16_dec(p_buf, buf_len, p_index, &p_gatts_attr->max_len); - - //init len move just before p_data to be able to use len16data decoder. - err_code = len16data_dec(p_buf, - buf_len, - p_index, - &p_gatts_attr->p_value, - &p_gatts_attr->init_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_char_handles_enc(void const * const p_void_char_handles, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_char_handles_t * p_char_handles = (ble_gatts_char_handles_t *)p_void_char_handles; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_char_handles->value_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_handles->user_desc_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_handles->cccd_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_char_handles->sccd_handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_char_handles_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_handles) -{ - ble_gatts_char_handles_t * p_char_handles = (ble_gatts_char_handles_t *)p_void_char_handles; - - SER_ASSERT_LENGTH_LEQ(8, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_char_handles->value_handle)); - uint16_dec(p_buf, buf_len, p_index, &p_char_handles->user_desc_handle); - uint16_dec(p_buf, buf_len, p_index, &p_char_handles->cccd_handle); - uint16_dec(p_buf, buf_len, p_index, &p_char_handles->sccd_handle); - - return NRF_SUCCESS; -} - -uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_hvx_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_hvx_params_t * p_hvx_params = (ble_gatts_hvx_params_t *)p_void_hvx_params; - - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2 + 1 + 2, buf_len - *p_index); - - err_code = uint16_t_enc(&p_hvx_params->handle, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_hvx_params->type, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_hvx_params->offset, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_hvx_params->p_len != NULL) - { - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[(*p_index)++] = SER_FIELD_PRESENT; - - err_code = uint16_t_enc(p_hvx_params->p_len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - if (p_hvx_params->p_data != NULL) - { - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - p_buf[(*p_index)++] = SER_FIELD_PRESENT; - - SER_ASSERT_LENGTH_LEQ(*p_hvx_params->p_len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_hvx_params->p_data, *p_hvx_params->p_len); - *p_index += *p_hvx_params->p_len; - } - - return err_code; -} - -uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_hvx_params) -{ - ble_gatts_hvx_params_t * p_hvx_params = (ble_gatts_hvx_params_t *)p_void_hvx_params; - - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2 + 1 + 2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_hvx_params->handle); - uint8_dec(p_buf, buf_len, p_index, &p_hvx_params->type); - uint16_dec(p_buf, buf_len, p_index, &p_hvx_params->offset); - - SER_ASSERT_NOT_NULL(&p_hvx_params->p_len); - err_code = cond_len16_cond_data_dec(p_buf, - buf_len, - p_index, - &p_hvx_params->p_data, - &p_hvx_params->p_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_attr_context_t_enc(void const * const p_void_attr_context, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gatts_attr_context_t * p_context = (ble_gatts_attr_context_t *) p_void_attr_context; - - error_code = ble_uuid_t_enc(&(p_context->srvc_uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_enc(&(p_context->char_uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_enc(&(p_context->desc_uuid), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&(p_context->srvc_handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&(p_context->value_handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint8_t_enc(&(p_context->type), p_buf, buf_len, p_index); - - return error_code; -} - -uint32_t ble_gatts_attr_context_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_context) -{ - uint32_t error_code = NRF_SUCCESS; - ble_gatts_attr_context_t * p_context = (ble_gatts_attr_context_t *) p_void_attr_context; - - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->srvc_uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->char_uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_uuid_t_dec(p_buf, buf_len, p_index, &(p_context->desc_uuid)); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - SER_ASSERT_LENGTH_LEQ(5, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &(p_context->srvc_handle)); - uint16_dec(p_buf, buf_len, p_index, &(p_context->value_handle)); - uint8_dec(p_buf, buf_len, p_index, &(p_context->type)); - return error_code; -} - -uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_evt_write_t * p_write = (ble_gatts_evt_write_t *) p_void_write; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint16_t_enc(&(p_write->handle), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint8_t_enc(&(p_write->op), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gatts_attr_context_t_enc(&(p_write->context), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&(p_write->offset), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - uint16_t data_len = p_write->len; - error_code = uint16_t_enc(&data_len, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - SER_ASSERT_LENGTH_LEQ(data_len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_write->data, data_len); - *p_index += data_len; - - return error_code; -} - -uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_write) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_struct_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t in_struct_len = *p_struct_len; - - *p_struct_len = offsetof(ble_gatts_evt_write_t, data); - - uint16_t handle; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint8_t op; - err_code = uint8_t_dec(p_buf, buf_len, p_index, &op); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - ble_gatts_attr_context_t context; - err_code = ble_gatts_attr_context_t_dec(p_buf, buf_len, p_index, &context); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint16_t offset; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint16_t len; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_struct_len += len; - - if (p_void_write != NULL) - { - ble_gatts_evt_write_t * p_write = (ble_gatts_evt_write_t *)p_void_write; - - SER_ASSERT_LENGTH_LEQ(*p_struct_len, in_struct_len); - - p_write->handle = handle; - p_write->op = op; - - memcpy(&(p_write->context), &context, sizeof (ble_gatts_attr_context_t)); - - p_write->offset = offset; - p_write->len = len; - - SER_ASSERT_LENGTH_LEQ(p_write->len, buf_len - *p_index); - memcpy(p_write->data, &p_buf[*p_index], p_write->len); - } - - *p_index += len; - - return err_code; -} - -uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_read, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_read); - - ble_gatts_evt_read_t * p_read = (ble_gatts_evt_read_t *)p_void_read; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_read->handle), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_attr_context_t_enc(&(p_read->context), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_read->offset), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_read) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - - uint32_t err_code = NRF_SUCCESS; - uint32_t in_struct_len = *p_struct_len; - - *p_struct_len = sizeof (ble_gatts_evt_read_t); - - uint16_t handle; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - ble_gatts_attr_context_t context; - err_code = ble_gatts_attr_context_t_dec(p_buf, buf_len, p_index, &context); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint16_t offset; - err_code = uint16_t_dec(p_buf, buf_len, p_index, &offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_void_read != NULL) - { - ble_gatts_evt_read_t * p_read = (ble_gatts_evt_read_t *)p_void_read; - - SER_ASSERT_LENGTH_LEQ(*p_struct_len, in_struct_len); - - p_read->handle = handle; - memcpy(&(p_read->context), &context, sizeof (context)); - p_read->offset = offset; - } - - return err_code; -} - -uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_authorize_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_authorize_request); - - ble_gatts_evt_rw_authorize_request_t * p_authorize_request = - (ble_gatts_evt_rw_authorize_request_t *)p_void_authorize_request; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_enc(&(p_authorize_request->type), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - switch (p_authorize_request->type) - { - case BLE_GATTS_AUTHORIZE_TYPE_READ: - err_code = ble_gatts_evt_read_t_enc(&(p_authorize_request->request.read), - p_buf, - buf_len, - p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - case BLE_GATTS_AUTHORIZE_TYPE_WRITE: - err_code = ble_gatts_evt_write_t_enc(&(p_authorize_request->request.write), - p_buf, - buf_len, - p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - default: - case BLE_GATTS_AUTHORIZE_TYPE_INVALID: - err_code = NRF_ERROR_INVALID_PARAM; - break; - } - - return err_code; -} - -uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_authorize_request) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_struct_len); - SER_ASSERT_NOT_NULL(p_index); - - uint32_t err_code = NRF_SUCCESS; - - uint8_t type; - err_code = uint8_t_dec(p_buf, buf_len, p_index, &type); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t in_struct_len = *p_struct_len; - - *p_struct_len = offsetof(ble_gatts_evt_rw_authorize_request_t, request); - - ble_gatts_evt_rw_authorize_request_t * p_authorize_request = - (ble_gatts_evt_rw_authorize_request_t *)p_void_authorize_request; - - void * p_void_request = NULL; - - if (p_void_authorize_request != NULL) - { - p_authorize_request->type = type; - - SER_ASSERT_LENGTH_LEQ(*p_struct_len, in_struct_len); - - switch (type) - { - case BLE_GATTS_AUTHORIZE_TYPE_READ: - p_void_request = &(p_authorize_request->request.read); - break; - - case BLE_GATTS_AUTHORIZE_TYPE_WRITE: - p_void_request = &(p_authorize_request->request.write); - break; - - default: - case BLE_GATTS_AUTHORIZE_TYPE_INVALID: - return NRF_ERROR_INVALID_DATA; - } - } - - switch (type) - { - case BLE_GATTS_AUTHORIZE_TYPE_READ: - err_code = ble_gatts_evt_read_t_dec(p_buf, - buf_len, - p_index, - &in_struct_len, - p_void_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - case BLE_GATTS_AUTHORIZE_TYPE_WRITE: - err_code = ble_gatts_evt_write_t_dec(p_buf, - buf_len, - p_index, - &in_struct_len, - p_void_request); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - - default: - case BLE_GATTS_AUTHORIZE_TYPE_INVALID: - return NRF_ERROR_INVALID_DATA; - } - *p_struct_len += in_struct_len; - - return err_code; -} - -uint32_t ble_gatts_read_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_read_authorize_params_t * p_params = - (ble_gatts_read_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint16_t_enc(&(p_params->gatt_status), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - uint8_t temp_val = p_params->update; - error_code = uint8_t_enc(&temp_val, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - error_code = uint16_t_enc(&(p_params->offset), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - error_code = len16data_enc(p_params->p_data, p_params->len, p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gatts_read_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_read_authorize_params_t * p_params = - (ble_gatts_read_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_params->gatt_status); - - uint8_t temp_val; - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &temp_val); - p_params->update = temp_val; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_params->offset); - - error_code = len16data_dec(p_buf, buf_len, p_index, &p_params->p_data, &p_params->len); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gatts_write_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_write_authorize_params_t * p_params = - (ble_gatts_write_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint16_t_enc(&(p_params->gatt_status), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - return error_code; -} - -uint32_t ble_gatts_write_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_write_authorize_params_t * p_params = - (ble_gatts_write_authorize_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_params->gatt_status); - - return error_code; -} - -uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_rw_authorize_reply_params_t const * const p_params = - (ble_gatts_rw_authorize_reply_params_t * ) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - error_code = uint8_t_enc(&(p_params->type), p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_READ) - { - error_code = ble_gatts_read_authorize_params_t_enc(&p_params->params.read, - p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) - { - error_code = ble_gatts_write_authorize_params_t_enc(&p_params->params.write, - p_buf, buf_len, p_index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else - { - return NRF_ERROR_INVALID_PARAM; - } - - return error_code; -} - -uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_rw_authorize_reply_params_t * p_params = - (ble_gatts_rw_authorize_reply_params_t *) p_void_struct; - uint32_t error_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index); - uint8_dec(p_buf, buf_len, p_index, &(p_params->type)); - - if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_READ) - { - error_code = ble_gatts_read_authorize_params_t_dec(p_buf, buf_len, p_index, - &p_params->params.read); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else if (p_params->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) - { - error_code = ble_gatts_write_authorize_params_t_dec(p_buf, buf_len, p_index, - &p_params->params.write); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - } - else - { - return NRF_ERROR_INVALID_PARAM; - } - - return error_code; -} - -uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_enable_params_t * p_enable_params = (ble_gatts_enable_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8 = 0; - - temp8 = (p_enable_params->service_changed & 0x01); - - err_code = uint8_t_enc((void *) &temp8, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint32_t_enc(&(p_enable_params->attr_tab_size), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_enable_params_t * p_enable_params = (ble_gatts_enable_params_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint8_t temp8 = 0; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, (void *) &temp8); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_enable_params->service_changed = temp8 & 0x01; - - err_code = uint32_t_dec(p_buf, buf_len, p_index, (void *) &(p_enable_params->attr_tab_size)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_value_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_gatts_value_t * p_value = (ble_gatts_value_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc((void *) &(p_value->len), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *) &(p_value->offset), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = buf_enc(p_value->p_value, p_value->len, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct) -{ - ble_gatts_value_t * p_value = (ble_gatts_value_t *)p_void_struct; - uint32_t err_code = NRF_SUCCESS; - uint16_t total_len = p_value->len; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, (void *) &(p_value->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, (void *) &(p_value->offset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = buf_dec(p_buf, buf_len, p_index, &(p_value->p_value), total_len, p_value->len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s130/ble_gatts_struct_serialization.h b/components/serialization/common/struct_ser/s130/ble_gatts_struct_serialization.h deleted file mode 100644 index 6139d9e..0000000 --- a/components/serialization/common/struct_ser/s130/ble_gatts_struct_serialization.h +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_STRUCT_SERIALIZATION_H -#define BLE_GATTS_STRUCT_SERIALIZATION_H - -#include "ble_gatts.h" - -uint32_t ser_ble_gatts_char_pf_enc(void const * const p_void_char_pf, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ser_ble_gatts_char_pf_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_pf); - -uint32_t ble_gatts_attr_md_enc(void const * const p_void_attr_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_attr_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_md); - -uint32_t ble_gatts_char_md_enc(void const * const p_void_char_md, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_char_md_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_md); - -uint32_t ble_gatts_attr_enc(void const * const p_void_gatts_attr, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_attr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_gatts_attr); - -uint32_t ble_gatts_char_handles_enc(void const * const p_void_char_handles, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_char_handles_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_char_handles); - -uint32_t ble_gatts_attr_context_t_enc(void const * const p_void_attr_context, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_attr_context_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_attr_context); - -uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_write, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_write); - -uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_hvx_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_hvx_params); - -uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_read, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_read); - -uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_authorize_request, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_size, - void * const p_void_authorize_request); - -uint32_t ble_gatts_read_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_read_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_write_authorize_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_write_authorize_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -uint32_t ble_gatts_value_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); - -#endif /* BLE_GATTS_STRUCT_SERIALIZATION_H */ diff --git a/components/serialization/common/struct_ser/s130/ble_struct_serialization.c b/components/serialization/common/struct_ser/s130/ble_struct_serialization.c deleted file mode 100644 index 553bf73..0000000 --- a/components/serialization/common/struct_ser/s130/ble_struct_serialization.c +++ /dev/null @@ -1,270 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_types.h" -#include "ble_l2cap.h" -#include "ble.h" -#include "cond_field_serialization.h" -#include - - -uint32_t ble_uuid_t_enc(void const * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_uuid_t * p_uuid = (ble_uuid_t *)p_void_uuid; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_uuid->uuid, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_uuid->type, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid) -{ - ble_uuid_t * p_uuid = (ble_uuid_t *)p_void_uuid; - - SER_ASSERT_LENGTH_LEQ(3, buf_len - *p_index); - uint16_dec(p_buf, buf_len, p_index, &p_uuid->uuid); - uint8_dec(p_buf, buf_len, p_index, &p_uuid->type); - - return NRF_SUCCESS; -} - -uint32_t ble_uuid128_t_enc(void const * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - ble_uuid128_t * p_uuid = (ble_uuid128_t *)p_void_uuid; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(16, buf_len - *p_index); - - memcpy(&p_buf[*p_index], p_uuid->uuid128, sizeof (p_uuid->uuid128)); - - *p_index += sizeof (p_uuid->uuid128); - - return err_code; -} - -uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid) -{ - ble_uuid128_t * p_uuid = (ble_uuid128_t *)p_void_uuid; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(16, buf_len - *p_index); - - memcpy(p_uuid->uuid128, &p_buf[*p_index], sizeof (p_uuid->uuid128)); - - *p_index += sizeof (p_uuid->uuid128); - - return err_code; -} - -uint32_t ble_l2cap_header_t_enc(void const * const p_void_header, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_header); - - ble_l2cap_header_t * p_header = (ble_l2cap_header_t *)p_void_header; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&(p_header->len), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_header->cid), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_header) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_header); - - ble_l2cap_header_t * p_header = (ble_l2cap_header_t *)p_void_header; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_header->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, buf_len, p_index, &(p_header->cid)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_evt_rx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_evt_rx); - - ble_l2cap_evt_rx_t * p_evt_rx = (ble_l2cap_evt_rx_t *)p_void_evt_rx; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_l2cap_header_t_enc(&(p_evt_rx->header), p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(p_evt_rx->header.len, buf_len - *p_index); - memcpy(&p_buf[*p_index], p_evt_rx->data, p_evt_rx->header.len); - *p_index += p_evt_rx->header.len; - - return err_code; -} - -uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_struct_len, - void * const p_void_evt_rx) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_struct_len); - - ble_l2cap_evt_rx_t * p_evt_rx = (ble_l2cap_evt_rx_t *)p_void_evt_rx; - uint32_t err_code = NRF_SUCCESS; - - uint32_t total_struct_len = *p_struct_len; - - /* Get data length */ - uint32_t tmp_index = *p_index; - uint16_t len = 0; - - err_code = uint16_t_dec(p_buf, buf_len, &tmp_index, &len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - /* Update struct length */ - *p_struct_len = offsetof(ble_l2cap_evt_rx_t, data[0]); - *p_struct_len += (uint8_t*)&p_evt_rx->data[len] - (uint8_t*)&p_evt_rx->data[0]; - - /* Decode header and copy data */ - if (p_void_evt_rx != NULL) - { - SER_ASSERT_LENGTH_LEQ(*p_struct_len, total_struct_len); - - err_code = ble_l2cap_header_t_dec(p_buf, buf_len, p_index, &(p_evt_rx->header)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(p_evt_rx->header.len, buf_len - *p_index); - memcpy(p_evt_rx->data, &p_buf[*p_index], p_evt_rx->header.len); - *p_index += p_evt_rx->header.len; - } - - return err_code; -} - -uint32_t ble_enable_params_t_enc(void const * const p_void_enable_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_enable_params); - - ble_enable_params_t * p_enable_params = (ble_enable_params_t *)p_void_enable_params; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gatts_enable_params_t_enc(&p_enable_params->gatts_enable_params, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_enable_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_enable_params); - - ble_enable_params_t * p_enable_params = (ble_enable_params_t *)p_void_enable_params; - uint32_t err_code = NRF_SUCCESS; - - err_code = ble_gatts_enable_params_t_dec(p_buf, buf_len, p_index, &(p_enable_params->gatts_enable_params)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_common_opt_radio_cpu_mutex_t_enc(void const * const p_void_opt_mutex, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_opt_mutex); - - ble_common_opt_radio_cpu_mutex_t * p_radio_cpu_mutex = (ble_common_opt_radio_cpu_mutex_t *)p_void_opt_mutex; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - byte = p_radio_cpu_mutex->enable; - err_code = uint8_t_enc(&byte, p_buf, buf_len, p_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_common_opt_radio_cpu_mutex_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_opt_mutex) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_index); - SER_ASSERT_NOT_NULL(p_void_opt_mutex); - - ble_common_opt_radio_cpu_mutex_t * p_radio_cpu_mutex = (ble_common_opt_radio_cpu_mutex_t *)p_void_opt_mutex; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - - err_code = uint8_t_dec(p_buf, buf_len, p_index, &byte); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_radio_cpu_mutex->enable = byte & 0x01; - - return err_code; -} diff --git a/components/serialization/common/struct_ser/s130/ble_struct_serialization.h b/components/serialization/common/struct_ser/s130/ble_struct_serialization.h deleted file mode 100644 index 032bdd9..0000000 --- a/components/serialization/common/struct_ser/s130/ble_struct_serialization.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_types.h" - - -uint32_t ble_uuid_t_enc(void const * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid); - -uint32_t ble_uuid128_t_enc(const void * const p_void_uuid, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_uuid); - -uint32_t ble_l2cap_header_t_enc(void const * const p_void_header, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_header); - -uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_evt_rx, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - uint32_t * const p_event_len, - void * const p_void_evt_rx); - -uint32_t ble_enable_params_t_enc(void const * const p_void_enable_params, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_enable_params); - -uint32_t ble_common_opt_radio_cpu_mutex_t_enc(void const * const p_void_opt_mutex, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_common_opt_radio_cpu_mutex_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_opt_mutex); diff --git a/components/serialization/common/struct_ser/s132/ble_gap_struct_serialization.c b/components/serialization/common/struct_ser/s132/ble_gap_struct_serialization.c new file mode 100644 index 0000000..10e16cd --- /dev/null +++ b/components/serialization/common/struct_ser/s132/ble_gap_struct_serialization.c @@ -0,0 +1,1202 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gap_struct_serialization.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "string.h" +#include "ble_gatts.h" + +uint32_t ble_gap_evt_adv_report_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_adv_report_t); + + uint8_t ser_data = (p_struct->scan_rsp & 0x01) + | ((p_struct->type & 0x03) << 1); + uint8_t data_len = (p_struct->dlen & 0x1F); + SER_PUSH_FIELD(&p_struct->peer_addr, ble_gap_addr_t_enc); + SER_PUSH_FIELD(&p_struct->direct_addr, ble_gap_addr_t_enc); + SER_PUSH_int8(&p_struct->rssi); + SER_PUSH_uint8(&ser_data); + SER_PUSH_len8data(p_struct->data, data_len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_adv_report_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_adv_report_t); + + uint8_t ser_data; + uint8_t data_len = BLE_GAP_ADV_MAX_SIZE; + uint8_t * p_field_data = p_struct->data; + SER_PULL_FIELD(&p_struct->peer_addr, ble_gap_addr_t_dec); + SER_PULL_FIELD(&p_struct->direct_addr, ble_gap_addr_t_dec); + SER_PULL_int8(&p_struct->rssi); + SER_PULL_uint8(&ser_data); + SER_PULL_len8data(&p_field_data, &data_len); + + p_struct->scan_rsp = ser_data & 0x01; + p_struct->type = (ser_data >> 1) & 0x03; + p_struct->dlen = data_len; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_irk_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_irk_t); + SER_PUSH_uint8array(p_struct->irk, BLE_GAP_SEC_KEY_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_irk_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_irk_t); + SER_PULL_uint8array(p_struct->irk, BLE_GAP_SEC_KEY_LEN); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_addr_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_addr_t); + + uint8_t ser_data = (p_struct->addr_id_peer & 0x01) + | ((p_struct->addr_type & 0x7F) << 1); + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint8array(p_struct->addr, BLE_GAP_ADDR_LEN); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_addr_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_addr_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + SER_PULL_uint8array(p_struct->addr, BLE_GAP_ADDR_LEN); + + p_struct->addr_id_peer = ser_data & 0x01; + p_struct->addr_type = (ser_data >> 1) & 0x7F; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sec_levels_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sec_levels_t); + + uint8_t sec_levels_serialized = (p_struct->lv1 << 0) | (p_struct->lv2 << 1) + | (p_struct->lv3 << 2) | (p_struct->lv4 << 3); + SER_PUSH_uint8(&sec_levels_serialized); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sec_levels_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sec_levels_t); + + uint32_t sec_levels_serialized; + SER_PULL_uint8(&sec_levels_serialized); + + p_struct->lv1 = sec_levels_serialized & 0x01; + p_struct->lv2 = (sec_levels_serialized >> 1) & 0x01; + p_struct->lv3 = (sec_levels_serialized >> 2) & 0x01; + p_struct->lv4 = (sec_levels_serialized >> 3) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sec_keys_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sec_keys_t); + + SER_PUSH_COND(p_struct->p_enc_key, ble_gap_enc_key_t_enc); + SER_PUSH_COND(p_struct->p_id_key, ble_gap_id_key_t_enc); + SER_PUSH_COND(p_struct->p_sign_key, ble_gap_sign_info_t_enc); + SER_PUSH_COND(p_struct->p_pk, ble_gap_lesc_p256_pk_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sec_keys_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sec_keys_t); + + SER_PULL_COND(&(p_struct->p_enc_key), ble_gap_enc_key_t_dec); + SER_PULL_COND(&(p_struct->p_id_key), ble_gap_id_key_t_dec); + SER_PULL_COND(&(p_struct->p_sign_key), ble_gap_sign_info_t_dec); + SER_PULL_COND(&(p_struct->p_pk), ble_gap_lesc_p256_pk_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_enc_info_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_enc_info_t); + + SER_PUSH_uint8array(p_struct->ltk, BLE_GAP_SEC_KEY_LEN); + uint8_t ser_data = (p_struct->lesc & 0x01) + | ((p_struct->auth & 0x01) << 1) + | ((p_struct->ltk_len & 0x3F) << 2); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_enc_info_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_enc_info_t); + + uint8_t ser_data; + SER_PULL_uint8array(p_struct->ltk, BLE_GAP_SEC_KEY_LEN); + SER_PULL_uint8(&ser_data); + p_struct->lesc = ser_data & 0x01; + p_struct->auth = (ser_data >> 1) & 0x01; + p_struct->ltk_len = (ser_data >> 2) & 0x3F; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sign_info_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sign_info_t); + SER_PUSH_uint8array(p_struct->csrk, BLE_GAP_SEC_KEY_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sign_info_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sign_info_t); + SER_PULL_uint8array(p_struct->csrk, BLE_GAP_SEC_KEY_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_auth_status_t); + + uint8_t ser_data = (p_struct->error_src) | ((p_struct->bonded) << 2); + SER_PUSH_uint8(&(p_struct->auth_status)); + SER_PUSH_uint8(&ser_data); + + SER_PUSH_FIELD(&(p_struct->sm1_levels), ble_gap_sec_levels_t_enc); + SER_PUSH_FIELD(&(p_struct->sm2_levels), ble_gap_sec_levels_t_enc); + SER_PUSH_FIELD(&(p_struct->kdist_own), ble_gap_sec_kdist_t_enc); + SER_PUSH_FIELD(&(p_struct->kdist_peer), ble_gap_sec_kdist_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_auth_status_t); + + uint8_t ser_data; + SER_PULL_uint8(&(p_struct->auth_status)); + SER_PULL_uint8(&ser_data); + p_struct->error_src = ser_data & 0x03; + p_struct->bonded = (ser_data >> 2) & 0x01; + + SER_PULL_FIELD(&(p_struct->sm1_levels), ble_gap_sec_levels_t_dec); + SER_PULL_FIELD(&(p_struct->sm2_levels), ble_gap_sec_levels_t_dec); + SER_PULL_FIELD(&(p_struct->kdist_own), ble_gap_sec_kdist_t_dec); + SER_PULL_FIELD(&(p_struct->kdist_peer), ble_gap_sec_kdist_t_dec); + + SER_STRUCT_DEC_END; +} + + +uint32_t ble_gap_conn_sec_mode_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_conn_sec_mode_t); + + uint8_t ser_data = (p_struct->sm & 0x0F) + | ((p_struct->lv & 0x0F) << 4); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_conn_sec_mode_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_conn_sec_mode_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->sm = ser_data & 0x0F; + p_struct->lv = (ser_data >> 4) & 0x0F; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_conn_sec_update_t); + SER_PUSH_FIELD(&(p_struct->conn_sec), ble_gap_conn_sec_t_enc); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_conn_sec_update_t); + SER_PULL_FIELD(&(p_struct->conn_sec), ble_gap_conn_sec_t_dec); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_conn_sec_t); + + SER_PUSH_FIELD(&p_struct->sec_mode, ble_gap_conn_sec_mode_t_enc); + SER_PUSH_uint8(&p_struct->encr_key_size); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_conn_sec_t); + + SER_PULL_FIELD(&p_struct->sec_mode, ble_gap_conn_sec_mode_t_dec); + SER_PULL_uint8(&p_struct->encr_key_size); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_sec_info_request_t); + + uint8_t ser_data = (p_struct->enc_info & 0x01) + | ((p_struct->id_info & 0x01) << 1) + | ((p_struct->sign_info& 0x01) << 2); + SER_PUSH_FIELD(&p_struct->peer_addr, ble_gap_addr_t_enc); + SER_PUSH_FIELD(&p_struct->master_id, ble_gap_master_id_t_enc); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_sec_info_request_t); + + uint8_t ser_data; + SER_PULL_FIELD(&p_struct->peer_addr, ble_gap_addr_t_dec); + SER_PULL_FIELD(&p_struct->master_id, ble_gap_master_id_t_dec); + SER_PULL_uint8(&ser_data); + p_struct->enc_info = ser_data & 0x01; + p_struct->id_info = (ser_data >> 1) & 0x01; + p_struct->sign_info = (ser_data >> 2) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_connected_t); + + SER_PUSH_FIELD(&p_struct->peer_addr, ble_gap_addr_t_enc); + SER_PUSH_uint8(&p_struct->role); + SER_PUSH_FIELD(&p_struct->conn_params, ble_gap_conn_params_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_connected_t); + + SER_PULL_FIELD(&p_struct->peer_addr, ble_gap_addr_t_dec); + SER_PULL_uint8(&p_struct->role); + SER_PULL_FIELD(&p_struct->conn_params, ble_gap_conn_params_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sec_params_t); + + uint8_t ser_data = (p_struct->bond & 0x01) + | ((p_struct->mitm & 0x01) << 1) + | ((p_struct->lesc & 0x01) << 2) + | ((p_struct->keypress & 0x01) << 3) + | ((p_struct->io_caps & 0x07) << 4) + | ((p_struct->oob & 0x01) << 7); + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint8(&p_struct->min_key_size); + SER_PUSH_uint8(&p_struct->max_key_size); + SER_PUSH_FIELD(&p_struct->kdist_own, ble_gap_sec_kdist_t_enc); + SER_PUSH_FIELD(&p_struct->kdist_peer, ble_gap_sec_kdist_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sec_params_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + SER_PULL_uint8(&p_struct->min_key_size); + SER_PULL_uint8(&p_struct->max_key_size); + SER_PULL_FIELD(&p_struct->kdist_own, ble_gap_sec_kdist_t_dec); + SER_PULL_FIELD(&p_struct->kdist_peer, ble_gap_sec_kdist_t_dec); + p_struct->bond = ser_data & 0x01; + p_struct->mitm = (ser_data >> 1) & 0x01; + p_struct->lesc = (ser_data >> 2) & 0x01; + p_struct->keypress = (ser_data >> 3) & 0x01; + p_struct->io_caps = (ser_data >> 4) & 0x07; + p_struct->oob = (ser_data >> 7) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_sec_params_request_t); + SER_PUSH_FIELD(&(p_struct->peer_params), ble_gap_sec_params_t_enc); + SER_STRUCT_ENC_END; +} + + uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_sec_params_request_t); + SER_PULL_FIELD(&(p_struct->peer_params), ble_gap_sec_params_t_dec); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_conn_param_update_t); + SER_PUSH_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_enc); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_conn_param_update_t); + SER_PULL_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_dec); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_conn_param_update_request_t); + SER_PUSH_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_enc); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_conn_param_update_request_t); + SER_PULL_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_dec); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_conn_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_conn_params_t); + + SER_PUSH_uint16(&p_struct->min_conn_interval); + SER_PUSH_uint16(&p_struct->max_conn_interval); + SER_PUSH_uint16(&p_struct->slave_latency); + SER_PUSH_uint16(&p_struct->conn_sup_timeout); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_conn_params_t); + + SER_PULL_uint16(&p_struct->min_conn_interval); + SER_PULL_uint16(&p_struct->max_conn_interval); + SER_PULL_uint16(&p_struct->slave_latency); + SER_PULL_uint16(&p_struct->conn_sup_timeout); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_disconnected_t); + SER_PUSH_uint8(&p_struct->reason); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_disconnected_t); + SER_PULL_uint8(&p_struct->reason); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_master_id_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_master_id_t); + SER_PUSH_uint16(&p_struct->ediv); + SER_PUSH_uint8array(p_struct->rand, BLE_GAP_SEC_RAND_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_master_id_t); + SER_PULL_uint16(&p_struct->ediv); + SER_PULL_uint8array(p_struct->rand, BLE_GAP_SEC_RAND_LEN); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_scan_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_scan_params_t); + + uint8_t ser_data = (p_struct->active & 0x01) + | ((p_struct->use_whitelist & 0x01) << 1) + | ((p_struct->adv_dir_report & 0x01) << 2); + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint16(&p_struct->interval); + SER_PUSH_uint16(&p_struct->window); + SER_PUSH_uint16(&p_struct->timeout); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_scan_params_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + SER_PULL_uint16(&p_struct->interval); + SER_PULL_uint16(&p_struct->window); + SER_PULL_uint16(&p_struct->timeout); + + p_struct->active = ser_data & 0x01; + p_struct->use_whitelist = (ser_data >> 1) & 0x01; + p_struct->adv_dir_report = (ser_data >> 2) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_enc_key_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_enc_key_t); + + SER_PUSH_FIELD(&p_struct->enc_info, ble_gap_enc_info_t_enc); + SER_PUSH_FIELD(&p_struct->master_id, ble_gap_master_id_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_enc_key_t); + + SER_PULL_FIELD(&p_struct->enc_info, ble_gap_enc_info_t_dec); + SER_PULL_FIELD(&p_struct->master_id, ble_gap_master_id_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_id_key_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_id_key_t); + + SER_PUSH_FIELD(&p_struct->id_info, ble_gap_irk_t_enc); + SER_PUSH_FIELD(&p_struct->id_addr_info, ble_gap_addr_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_id_key_t); + + SER_PULL_FIELD(&p_struct->id_info, ble_gap_irk_t_dec); + SER_PULL_FIELD(&p_struct->id_addr_info, ble_gap_addr_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sec_keyset_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sec_keyset_t); + + SER_PUSH_FIELD(&p_struct->keys_own, ble_gap_sec_keys_t_enc); + SER_PUSH_FIELD(&p_struct->keys_peer, ble_gap_sec_keys_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sec_keyset_t); + + SER_PULL_FIELD(&p_struct->keys_own, ble_gap_sec_keys_t_dec); + SER_PULL_FIELD(&p_struct->keys_peer, ble_gap_sec_keys_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_evt_sec_request_t); + + uint8_t ser_data = (p_struct->bond & 0x01) + | ((p_struct->mitm & 0x01) << 1) + | ((p_struct->lesc & 0x01) << 2) + | ((p_struct->keypress & 0x01) << 3); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_evt_sec_request_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->bond = ser_data & 0x01; + p_struct->mitm = (ser_data >> 1) & 0x01; + p_struct->lesc = (ser_data >> 2) & 0x01; + p_struct->keypress = (ser_data >> 3) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_sec_kdist_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_sec_kdist_t); + + uint8_t ser_data = (p_struct->enc & 0x01) + | (p_struct->id & 0x01) << 1 + | (p_struct->sign & 0x01) << 2 + | (p_struct->link & 0x01) << 3; + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_sec_kdist_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->enc = ser_data & 0x01; + p_struct->id = (ser_data >> 1) & 0x01; + p_struct->sign = (ser_data >> 2) & 0x01; + p_struct->link = (ser_data >> 3) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_ch_map_t); + + SER_PUSH_uint16(&p_struct->conn_handle); + SER_PUSH_uint8array(p_struct->ch_map, 5); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_ch_map_t); + + SER_PULL_uint16(&p_struct->conn_handle); + SER_PULL_uint8array(p_struct->ch_map, 5); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_local_conn_latency_t); + + SER_PUSH_uint16(&p_struct->conn_handle); + SER_PUSH_uint16(&p_struct->requested_latency); + SER_PUSH_COND(p_struct->p_actual_latency, uint16_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_local_conn_latency_t); + + SER_PULL_uint16(&p_struct->conn_handle); + SER_PULL_uint16(&p_struct->requested_latency); + SER_PULL_COND(&p_struct->p_actual_latency, uint16_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_passkey_t); + SER_PUSH_buf(p_struct->p_passkey, BLE_GAP_PASSKEY_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_passkey_t); + SER_PULL_buf(&p_struct->p_passkey, BLE_GAP_PASSKEY_LEN, BLE_GAP_PASSKEY_LEN); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_scan_req_report_t); + + uint8_t ser_data = p_struct->enable & 0x01; + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_scan_req_report_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->enable = ser_data & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_compat_mode_t); + + uint8_t ser_data = p_struct->mode_1_enable & 0x01; + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_compat_mode_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->mode_1_enable = ser_data & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_adv_ch_mask_t); + + uint8_t ser_data = (p_struct->ch_37_off & 0x01) + | ((p_struct->ch_38_off & 0x01) << 1) + | ((p_struct->ch_39_off & 0x01) << 2); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_adv_ch_mask_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->ch_37_off = ser_data & 0x01; + p_struct->ch_38_off = (ser_data >> 1) & 0x01; + p_struct->ch_39_off = (ser_data >> 2) & 0x01; + + SER_STRUCT_DEC_END; +} +uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_enable_params_t); + + SER_PUSH_uint8(&p_struct->periph_conn_count); + SER_PUSH_uint8(&p_struct->central_conn_count); + SER_PUSH_uint8(&p_struct->central_sec_count); + SER_PUSH_COND(p_struct->p_device_name, ble_gap_device_name_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_enable_params_t); + + SER_PULL_uint8(&p_struct->periph_conn_count); + SER_PULL_uint8(&p_struct->central_conn_count); + SER_PULL_uint8(&p_struct->central_sec_count); + SER_PULL_COND(&p_struct->p_device_name, ble_gap_device_name_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_lesc_p256_pk_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_lesc_p256_pk_t); + SER_PUSH_uint8array(p_struct->pk, BLE_GAP_LESC_P256_PK_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_lesc_p256_pk_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_lesc_p256_pk_t); + SER_PULL_uint8array(p_struct->pk, BLE_GAP_LESC_P256_PK_LEN); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_lesc_dhkey_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_lesc_dhkey_t); + SER_PUSH_uint8array(p_struct->key, BLE_GAP_LESC_DHKEY_LEN); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_lesc_dhkey_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_lesc_dhkey_t); + SER_PULL_uint8array(p_struct->key, BLE_GAP_LESC_DHKEY_LEN); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_lesc_oob_data_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_lesc_oob_data_t); + + SER_PUSH_FIELD(&p_struct->addr, ble_gap_addr_t_enc); + SER_PUSH_uint8array(p_struct->r, BLE_GAP_SEC_KEY_LEN); + SER_PUSH_uint8array(p_struct->c, BLE_GAP_SEC_KEY_LEN); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_lesc_oob_data_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_lesc_oob_data_t); + + SER_PULL_FIELD(&p_struct->addr, ble_gap_addr_t_dec); + SER_PULL_uint8array(p_struct->r, BLE_GAP_SEC_KEY_LEN); + SER_PULL_uint8array(p_struct->c, BLE_GAP_SEC_KEY_LEN); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_adv_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_adv_params_t); + + SER_PUSH_uint8(&p_struct->type); + SER_PUSH_COND(p_struct->p_peer_addr, ble_gap_addr_t_enc); + SER_PUSH_uint8(&p_struct->fp); + SER_PUSH_uint16(&p_struct->interval); + SER_PUSH_uint16(&p_struct->timeout); + SER_PUSH_FIELD(&p_struct->channel_mask, ble_gap_adv_ch_mask_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_adv_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_adv_params_t); + + SER_PULL_uint8(&p_struct->type); + SER_PULL_COND(&p_struct->p_peer_addr, ble_gap_addr_t_dec); + SER_PULL_uint8(&p_struct->fp); + SER_PULL_uint16(&p_struct->interval); + SER_PULL_uint16(&p_struct->timeout); + SER_PULL_FIELD(&p_struct->channel_mask, ble_gap_adv_ch_mask_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_ext_len_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_ext_len_t); + SER_PUSH_uint8(&p_struct->rxtx_max_pdu_payload_size); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_ext_len_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_ext_len_t); + SER_PULL_uint8(&p_struct->rxtx_max_pdu_payload_size); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_opt_auth_payload_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_opt_auth_payload_timeout_t); + + SER_PUSH_uint16(&p_struct->conn_handle); + SER_PUSH_uint16(&p_struct->auth_payload_timeout); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_opt_auth_payload_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_opt_auth_payload_timeout_t); + + SER_PULL_uint16(&p_struct->conn_handle); + SER_PULL_uint16(&p_struct->auth_payload_timeout); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_device_name_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_device_name_t); + + /* serializer does not support attributes on stack */ + if (p_struct->vloc != BLE_GATTS_VLOC_STACK) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + + SER_PUSH_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_enc); + + uint8_t ser_data = p_struct->vloc & 0x03; + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint16(&p_struct->current_len); + SER_PUSH_uint16(&p_struct->max_len); + SER_PUSH_buf(p_struct->p_value, p_struct->current_len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_device_name_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_device_name_t); + + uint16_t value_max_len = p_struct->max_len; + uint8_t ser_data; + SER_PULL_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_dec); + SER_PULL_uint8(&ser_data); + p_struct->vloc = ser_data & 0x03; + SER_PULL_uint16(&p_struct->current_len); + SER_PULL_uint16(&p_struct->max_len); + SER_PULL_buf(&p_struct->p_value,value_max_len, p_struct->current_len); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gap_privacy_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gap_privacy_params_t); + + SER_PUSH_uint8(&p_struct->privacy_mode); + SER_PUSH_uint8(&p_struct->private_addr_type); + SER_PUSH_uint16(&p_struct->private_addr_cycle_s); + SER_PUSH_COND(p_struct->p_device_irk, ble_gap_irk_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gap_privacy_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gap_privacy_params_t); + + SER_PULL_uint8(&p_struct->privacy_mode); + SER_PULL_uint8(&p_struct->private_addr_type); + SER_PULL_uint16(&p_struct->private_addr_cycle_s); + SER_PULL_COND(&p_struct->p_device_irk, ble_gap_irk_t_dec); + + SER_STRUCT_DEC_END; +} diff --git a/components/serialization/common/struct_ser/s130/ble_gap_struct_serialization.h b/components/serialization/common/struct_ser/s132/ble_gap_struct_serialization.h similarity index 54% rename from components/serialization/common/struct_ser/s130/ble_gap_struct_serialization.h rename to components/serialization/common/struct_ser/s132/ble_gap_struct_serialization.h index b5f06c2..d23755a 100644 --- a/components/serialization/common/struct_ser/s130/ble_gap_struct_serialization.h +++ b/components/serialization/common/struct_ser/s132/ble_gap_struct_serialization.h @@ -1,78 +1,123 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -#include "ble_gap.h" - -uint32_t ble_gap_irk_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); +#ifndef BLE_GAP_STRUCT_SERIALIZATION_H__ +#define BLE_GAP_STRUCT_SERIALIZATION_H__ -uint32_t ble_gap_irk_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); +#include "ble_gap.h" -uint32_t ble_gap_addr_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t ble_gap_evt_adv_report_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_evt_adv_report_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_irk_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_irk_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_addr_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_addr_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_sec_levels_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); -uint32_t ble_gap_addr_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_addr); +uint32_t ble_gap_sec_levels_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); -uint32_t ble_gap_sec_levels_enc(void const * const p_data, +uint32_t ble_gap_sec_keys_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); -uint32_t ble_gap_sec_levels_dec(uint8_t const * const p_buf, +uint32_t ble_gap_sec_keys_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_data); + void * const p_void_struct); -uint32_t ble_gap_sec_keys_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_sec_keys_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_data); - -uint32_t ble_gap_enc_info_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); +uint32_t ble_gap_enc_info_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); -uint32_t ble_gap_enc_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_enc_info); +uint32_t ble_gap_enc_info_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); -uint32_t ble_gap_sign_info_enc(void const * const p_sign_info, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); +uint32_t ble_gap_sign_info_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); -uint32_t ble_gap_sign_info_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_sign_info); +uint32_t ble_gap_sign_info_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); -uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_data, +uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -80,19 +125,19 @@ uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_data, uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_data); + void * const p_void_struct); -uint32_t ble_gap_conn_sec_mode_enc(void const * const p_void_sec_mode, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); +uint32_t ble_gap_conn_sec_mode_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); -uint32_t ble_gap_conn_sec_mode_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_sec_mode); +uint32_t ble_gap_conn_sec_mode_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); -uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_sec, +uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -100,9 +145,9 @@ uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_sec, uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_sec); + void * const p_void_struct); -uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_conn_sec_update, +uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -110,9 +155,9 @@ uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_conn_sec_up uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_conn_sec_update); + void * const p_void_struct); -uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_sec_info_request, +uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -120,7 +165,7 @@ uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_sec_info_r uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_sec_info_request); + void * const p_void_struct); uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct, uint8_t * const p_buf, @@ -130,7 +175,7 @@ uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct, uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_connected); + void * const p_void_struct); uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct, uint8_t * const p_buf, @@ -141,16 +186,6 @@ uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, void * const p_void_struct); - -uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_struct); uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct, uint8_t * const p_buf, @@ -162,7 +197,7 @@ uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf, uint32_t * const p_index, void * const p_void_struct); -uint32_t ble_gap_conn_params_t_enc(void const * const p_void_conn_params, +uint32_t ble_gap_conn_params_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -170,9 +205,9 @@ uint32_t ble_gap_conn_params_t_enc(void const * const p_void_conn_params, uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_conn_params); + void * const p_void_struct); -uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_evt_conn_param_update, +uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -180,9 +215,9 @@ uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_evt_conn_ uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_evt_conn_param_update); + void * const p_void_struct); -uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_evt_conn_param_update_request, +uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -190,9 +225,9 @@ uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_e uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_evt_conn_param_update_request); + void * const p_void_struct); -uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_disconnected, +uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -200,19 +235,9 @@ uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_disconnected, uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_disconnected); - -uint32_t ble_gap_whitelist_t_enc(void const * const p_data, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); + void * const p_void_struct); -uint32_t ble_gap_whitelist_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * p_data); - -uint32_t ble_gap_scan_params_t_enc(void const * const p_data, +uint32_t ble_gap_scan_params_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -222,17 +247,17 @@ uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf, uint32_t * const p_index, void * const p_data); -uint32_t ble_gap_master_id_t_enc(void const * const p_master_idx, +uint32_t ble_gap_master_id_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf, uint32_t buf_len, - uint32_t * const p_index, - void * const p_master_idx); + uint32_t * const p_index, + void * const p_void_struct); -uint32_t ble_gap_enc_key_t_enc(void const * const p_data, +uint32_t ble_gap_enc_key_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -240,9 +265,9 @@ uint32_t ble_gap_enc_key_t_enc(void const * const p_data, uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_data); + void * const p_void_struct); -uint32_t ble_gap_id_key_t_enc(void const * const p_data, +uint32_t ble_gap_id_key_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -250,9 +275,9 @@ uint32_t ble_gap_id_key_t_enc(void const * const p_data, uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_data); + void * const p_void_struct); -uint32_t ble_gap_sec_keyset_t_enc(void const * const p_data, +uint32_t ble_gap_sec_keyset_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -260,7 +285,7 @@ uint32_t ble_gap_sec_keyset_t_enc(void const * const p_data, uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_data); + void * const p_void_struct); uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct, uint8_t * const p_buf, @@ -270,9 +295,9 @@ uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct, uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_data); + void * const p_void_struct); -uint32_t ble_gap_sec_kdist_t_enc(void const * const p_data, +uint32_t ble_gap_sec_kdist_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -280,9 +305,9 @@ uint32_t ble_gap_sec_kdist_t_enc(void const * const p_data, uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_data); + void * const p_void_struct); -uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_data, +uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -290,9 +315,9 @@ uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_data, uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_data); + void * const p_void_struct); -uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_local_conn_latency, +uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -300,9 +325,9 @@ uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_local_co uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_local_conn_latency); + void * const p_void_struct); -uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_passkey, +uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -310,29 +335,19 @@ uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_passkey, uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_passkey); + void * const p_void_struct); -uint32_t ble_gap_opt_privacy_t_enc(void const * const p_void_privacy, - uint8_t * const p_buf, - uint32_t buf_len, - uint32_t * const p_index); - -uint32_t ble_gap_opt_privacy_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_privacy); - -uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_scan_req_report, +uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint32_t * const p_index, - void * const p_void_scan_req_report); + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); -uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_compat_mode, +uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -340,9 +355,9 @@ uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_compat_mode, uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_compat_mode); + void * const p_void_struct); -uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_ch_mask, +uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_struct, uint8_t * const p_buf, uint32_t buf_len, uint32_t * const p_index); @@ -350,4 +365,100 @@ uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_ch_mask, uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf, uint32_t buf_len, uint32_t * const p_index, - void * const p_void_ch_mask); + void * const p_void_struct); + +uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_lesc_p256_pk_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_lesc_p256_pk_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_lesc_dhkey_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_lesc_dhkey_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_lesc_oob_data_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_lesc_oob_data_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_adv_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_adv_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_opt_ext_len_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_ext_len_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_opt_auth_payload_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_opt_auth_payload_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_device_name_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_device_name_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gap_privacy_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gap_privacy_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#ifdef __cplusplus +} +#endif + +#endif // BLE_GAP_STRUCT_SERIALIZATION_H__ diff --git a/components/serialization/common/struct_ser/s132/ble_gatt_struct_serialization.c b/components/serialization/common/struct_ser/s132/ble_gatt_struct_serialization.c new file mode 100644 index 0000000..217698d --- /dev/null +++ b/components/serialization/common/struct_ser/s132/ble_gatt_struct_serialization.c @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gatt_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "ble_gatt.h" +#include + +uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatt_char_props_t); + + uint8_t ser_data = (p_struct->broadcast & 0x01) + | ((p_struct->read & 0x01) << 1) + | ((p_struct->write_wo_resp & 0x01) << 2) + | ((p_struct->write & 0x01) << 3) + | ((p_struct->notify & 0x01) << 4) + | ((p_struct->indicate & 0x01) << 5) + | ((p_struct->auth_signed_wr & 0x01) << 6); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatt_char_props_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->broadcast = ser_data & 0x01; + p_struct->read = (ser_data >> 1) & 0x01; + p_struct->write_wo_resp = (ser_data >> 2) & 0x01; + p_struct->write = (ser_data >> 3) & 0x01; + p_struct->notify = (ser_data >> 4) & 0x01; + p_struct->indicate = (ser_data >> 5) & 0x01; + p_struct->auth_signed_wr = (ser_data >> 6) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatt_char_ext_props_t); + + uint8_t ser_data = (p_struct->reliable_wr & 0x01) + | ((p_struct->wr_aux & 0x01) << 1); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatt_char_ext_props_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->reliable_wr = ser_data & 0x01; + p_struct->wr_aux = (ser_data >> 1) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatt_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatt_enable_params_t); + SER_PUSH_uint16(&p_struct->att_mtu); + SER_STRUCT_ENC_END; +} + + +uint32_t ble_gatt_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatt_enable_params_t); + SER_PULL_uint16(&p_struct->att_mtu); + SER_STRUCT_DEC_END; +} diff --git a/components/serialization/common/struct_ser/s132/ble_gatt_struct_serialization.h b/components/serialization/common/struct_ser/s132/ble_gatt_struct_serialization.h new file mode 100644 index 0000000..37bc269 --- /dev/null +++ b/components/serialization/common/struct_ser/s132/ble_gatt_struct_serialization.h @@ -0,0 +1,84 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATT_STRUCT_SERIALIZATION_H +#define BLE_GATT_STRUCT_SERIALIZATION_H + +#include "ble_gatt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatt_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#ifdef __cplusplus +} +#endif + +#endif /*BLE_GATT_STRUCT_SERIALIZATION_H*/ diff --git a/components/serialization/common/struct_ser/s132/ble_gattc_struct_serialization.c b/components/serialization/common/struct_ser/s132/ble_gattc_struct_serialization.c new file mode 100644 index 0000000..31787a9 --- /dev/null +++ b/components/serialization/common/struct_ser/s132/ble_gattc_struct_serialization.c @@ -0,0 +1,694 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gatt_struct_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "ble_gattc.h" +#include "cond_field_serialization.h" +#include + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_val_by_uuid_read_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + SER_PUSH_uint16(&p_struct->value_len); + + // Copy the whole packed list. + uint16_t list_length = (p_struct->value_len + sizeof(uint16_t)) * p_struct->count; + SER_PUSH_uint8array(p_struct->handle_value, list_length); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_val_by_uuid_read_rsp_t); + + SER_PULL_uint16(&p_struct->count); + SER_PULL_uint16(&p_struct->value_len); + + uint16_t list_length = (p_struct->value_len + sizeof(uint16_t)) * p_struct->count; + SER_ASSERT_LENGTH_LEQ(list_length, *p_ext_len); + SER_PULL_uint8array(p_struct->handle_value, list_length); + *p_ext_len = list_length; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_vals_read_rsp_t); + + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint8array(p_struct->values, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_vals_read_rsp_t); + + SER_PULL_uint16(&p_struct->len); + + SER_ASSERT_LENGTH_LEQ(p_struct->len, *p_ext_len); + SER_PULL_uint8array(p_struct->values, p_struct->len); + *p_ext_len = p_struct->len; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_handle_range_t); + + SER_PUSH_uint16(&p_struct->start_handle); + SER_PUSH_uint16(&p_struct->end_handle); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_handle_range_t); + + SER_PULL_uint16(&p_struct->start_handle); + SER_PULL_uint16(&p_struct->end_handle); + + SER_STRUCT_DEC_END; +} + + +uint32_t ble_gattc_service_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_service_t); + + SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc); + SER_PUSH_FIELD(&p_struct->handle_range, ble_gattc_handle_range_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_service_t); + + SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec); + SER_PULL_FIELD(&p_struct->handle_range, ble_gattc_handle_range_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_include_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_include_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&p_struct->included_srvc, ble_gattc_service_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_include_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&p_struct->included_srvc, ble_gattc_service_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_rel_disc_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + + ble_gattc_include_t * p_include = &(p_struct->includes[0]); + uint32_t i; + + for (i = 0; i < p_struct->count; i++) + { + SER_PUSH_FIELD(p_include, ble_gattc_include_t_enc); + ++p_include; + } + + SER_STRUCT_ENC_END; +} + + + +uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_rel_disc_rsp_t); + + SER_PULL_uint16(&p_struct->count); + + uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_include_t)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + ble_gattc_include_t * p_include = &(p_struct->includes[0]); + uint32_t i; + + for (i = 0; i < p_struct->count; i++) + { + SER_PULL_FIELD(p_include, ble_gattc_include_t_dec); + ++p_include; + } + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_write_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_write_params_t); + + SER_PUSH_uint8(&p_struct->write_op); + SER_PUSH_uint8(&p_struct->flags); + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_len16data(p_struct->p_value, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_write_params_t); + + SER_PULL_uint8(&p_struct->write_op); + SER_PULL_uint8(&p_struct->flags); + SER_PULL_uint16(&p_struct->handle); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_len16data((uint8_t **) &p_struct->p_value, &p_struct->len); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_attr_info16_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_attr_info16_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&(p_struct->uuid), ble_uuid_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_attr_info16_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_attr_info16_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&(p_struct->uuid), ble_uuid_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_attr_info128_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_attr_info128_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&(p_struct->uuid), ble_uuid128_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_attr_info128_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_attr_info128_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&(p_struct->uuid), ble_uuid128_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_attr_info_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_attr_info_disc_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + SER_PUSH_uint8(&p_struct->format); + + field_encoder_handler_t fp_encoder = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ? + ble_gattc_attr_info16_t_enc : ble_gattc_attr_info128_t_enc; + + uint32_t i; + for (i = 0; i < p_struct->count; ++i) + { + void * uuid_struct; + uuid_struct = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ? + (void *)&(p_struct->info.attr_info16[i]) : (void *)&(p_struct->info.attr_info128[i]); + SER_PUSH_FIELD(uuid_struct, fp_encoder); + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_attr_info_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_attr_info_disc_rsp_t); + + SER_PULL_uint16(&p_struct->count); + SER_PULL_uint8(&p_struct->format); + + uint32_t i; + uint32_t data_len; + field_decoder_handler_t fp_decoder; + if (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) + { + fp_decoder = ble_gattc_attr_info16_t_dec; + data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_attr_info16_t)); + } + else + { + fp_decoder = ble_gattc_attr_info128_t_dec; + data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_attr_info128_t)); + } + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + for (i = 0; i < p_struct->count; i++) + { + void * uuid_struct; + uuid_struct = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ? + (void *)&(p_struct->info.attr_info16[i]) : (void *)&(p_struct->info.attr_info128[i]); + SER_PULL_FIELD(uuid_struct, fp_decoder); + } + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_char_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_char_t); + + uint8_t ser_data; + SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc); + SER_PUSH_FIELD(&p_struct->char_props, ble_gatt_char_props_t_enc); + ser_data = p_struct->char_ext_props & 0x01; + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint16(&p_struct->handle_decl); + SER_PUSH_uint16(&p_struct->handle_value); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_char_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_char_t); + + uint8_t ser_data; + SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec); + SER_PULL_FIELD(&p_struct->char_props, ble_gatt_char_props_t_dec); + SER_PULL_uint8(&ser_data); + p_struct->char_ext_props = ser_data & 0x01; + SER_PULL_uint16(&p_struct->handle_decl); + SER_PULL_uint16(&p_struct->handle_value); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_char_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_disc_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + SER_PUSH_FIELD_ARRAY(p_struct->chars, ble_gattc_char_t_enc, p_struct->count); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_char_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_disc_rsp_t); + + SER_PULL_uint16(&p_struct->count); + uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_char_t)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_FIELD_ARRAY(p_struct->chars, ble_gattc_char_t_dec, p_struct->count); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_desc_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_desc_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_desc_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_desc_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_desc_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_desc_disc_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + SER_PUSH_FIELD_ARRAY(p_struct->descs, ble_gattc_desc_t_enc, p_struct->count); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_desc_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_desc_disc_rsp_t); + + SER_PULL_uint16(&p_struct->count); + uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_desc_t)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_FIELD_ARRAY(p_struct->descs, ble_gattc_desc_t_dec, p_struct->count); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_hvx_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_hvx_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_uint8(&p_struct->type); + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint8array(p_struct->data, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_hvx_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_hvx_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_uint8(&p_struct->type); + SER_PULL_uint16(&p_struct->len); + + uint32_t data_len = (SUB1(p_struct->len)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_uint8array(p_struct->data, p_struct->len); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_prim_srvc_disc_rsp_t); + + SER_PUSH_uint16(&p_struct->count); + SER_PUSH_FIELD_ARRAY(p_struct->services, ble_gattc_service_t_enc, p_struct->count); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_prim_srvc_disc_rsp_t); + + SER_PULL_uint16(&p_struct->count); + uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_service_t)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_FIELD_ARRAY(p_struct->services, ble_gattc_service_t_dec, p_struct->count); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_read_rsp_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint8array(p_struct->data, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_read_rsp_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_uint16(&p_struct->len); + + uint32_t data_len = (SUB1(p_struct->len)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_uint8array(p_struct->data, p_struct->len); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_timeout_t); + SER_PUSH_uint8(&p_struct->src); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_timeout_t); + SER_PULL_uint8(&p_struct->src); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_write_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_write_rsp_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_uint8(&p_struct->write_op); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint8array(p_struct->data, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_write_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_write_rsp_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_uint8(&p_struct->write_op); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_uint16(&p_struct->len); + + uint32_t data_len = (SUB1(p_struct->len)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_uint8array(p_struct->data, p_struct->len); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_gattc_evt_exchange_mtu_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gattc_evt_exchange_mtu_rsp_t); + SER_PUSH_uint16(&p_struct->server_rx_mtu); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gattc_evt_exchange_mtu_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gattc_evt_exchange_mtu_rsp_t); + SER_PULL_uint16(&p_struct->server_rx_mtu); + SER_STRUCT_DEC_END; +} diff --git a/components/serialization/common/struct_ser/s132/ble_gattc_struct_serialization.h b/components/serialization/common/struct_ser/s132/ble_gattc_struct_serialization.h new file mode 100644 index 0000000..73bb4f6 --- /dev/null +++ b/components/serialization/common/struct_ser/s132/ble_gattc_struct_serialization.h @@ -0,0 +1,284 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATTC_STRUCT_SERIALIZATION_H +#define BLE_GATTC_STRUCT_SERIALIZATION_H + +#include "ble_gattc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_service_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_include_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_write_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_attr_info16_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_attr_info16_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_attr_info128_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_attr_info128_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_evt_attr_info_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_attr_info_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_char_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_char_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_evt_char_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_char_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_desc_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_desc_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_evt_desc_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_desc_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_hvx_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_hvx_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_read_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_read_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gattc_evt_write_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_write_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gattc_evt_exchange_mtu_rsp_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gattc_evt_exchange_mtu_rsp_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#ifdef __cplusplus +} +#endif + +#endif /*BLE_GATTC_STRUCT_SERIALIZATION_H*/ diff --git a/components/serialization/common/struct_ser/s132/ble_gatts_struct_serialization.c b/components/serialization/common/struct_ser/s132/ble_gatts_struct_serialization.c new file mode 100644 index 0000000..0c4c928 --- /dev/null +++ b/components/serialization/common/struct_ser/s132/ble_gatts_struct_serialization.c @@ -0,0 +1,615 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gatt_struct_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "ble_gatts.h" +#include "cond_field_serialization.h" +#include + +uint32_t ble_gatts_char_pf_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_char_pf_t); + + SER_PUSH_uint8(&p_struct->format); + SER_PUSH_int8(&p_struct->exponent); + SER_PUSH_uint16(&p_struct->unit); + SER_PUSH_uint8(&p_struct->name_space); + SER_PUSH_uint16(&p_struct->desc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_char_pf_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_char_pf_t); + + SER_PULL_uint8(&p_struct->format); + SER_PULL_int8(&p_struct->exponent); + SER_PULL_uint16(&p_struct->unit); + SER_PULL_uint8(&p_struct->name_space); + SER_PULL_uint16(&p_struct->desc); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_attr_md_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_attr_md_t); + + SER_PUSH_FIELD(&p_struct->read_perm, ble_gap_conn_sec_mode_t_enc); + SER_PUSH_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_enc); + uint8_t ser_data = (p_struct->vlen & 0x01) + | ((p_struct->vloc & 0x03) << 1) + | ((p_struct->rd_auth & 0x01) << 3) + | ((p_struct->wr_auth & 0x01) << 4); + SER_PUSH_uint8(&ser_data); + + // Serializer does not support attributes on stack. + if (p_struct->vloc != BLE_GATTS_VLOC_STACK) + { + err_code = NRF_ERROR_INVALID_PARAM; + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_attr_md_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_attr_md_t); + + uint8_t ser_data; + SER_PULL_FIELD(&p_struct->read_perm, ble_gap_conn_sec_mode_t_dec); + SER_PULL_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_dec); + SER_PULL_uint8(&ser_data); + + p_struct->vlen = ser_data & 0x01; + p_struct->vloc = (ser_data >> 1) & 0x03; + p_struct->rd_auth = (ser_data >> 3) & 0x01; + p_struct->wr_auth = (ser_data >> 4) & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_char_md_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_char_md_t); + + SER_PUSH_FIELD(&p_struct->char_props, ble_gatt_char_props_t_enc); + SER_PUSH_FIELD(&p_struct->char_ext_props, ble_gatt_char_ext_props_t_enc); + SER_PUSH_uint16(&p_struct->char_user_desc_max_size); + SER_ERROR_CHECK(p_struct->char_user_desc_size <= BLE_GATTS_VAR_ATTR_LEN_MAX, + NRF_ERROR_INVALID_PARAM); + SER_PUSH_len16data(p_struct->p_char_user_desc, p_struct->char_user_desc_size); + SER_PUSH_COND(p_struct->p_char_pf, ble_gatts_char_pf_t_enc); + SER_PUSH_COND(p_struct->p_user_desc_md, ble_gatts_attr_md_t_enc); + SER_PUSH_COND(p_struct->p_cccd_md, ble_gatts_attr_md_t_enc); + SER_PUSH_COND(p_struct->p_sccd_md, ble_gatts_attr_md_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_char_md_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_char_md_t); + + SER_PULL_FIELD(&p_struct->char_props, ble_gatt_char_props_t_dec); + SER_PULL_FIELD(&p_struct->char_ext_props, ble_gatt_char_ext_props_t_dec); + SER_PULL_uint16(&p_struct->char_user_desc_max_size); + SER_PULL_len16data(&p_struct->p_char_user_desc, &p_struct->char_user_desc_size); + SER_PULL_COND(&p_struct->p_char_pf, ble_gatts_char_pf_t_dec); + SER_PULL_COND(&p_struct->p_user_desc_md, ble_gatts_attr_md_t_dec); + SER_PULL_COND(&p_struct->p_cccd_md, ble_gatts_attr_md_t_dec); + SER_PULL_COND(&p_struct->p_sccd_md, ble_gatts_attr_md_t_dec); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_attr_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_attr_t); + + SER_PUSH_COND(p_struct->p_uuid, ble_uuid_t_enc); + SER_PUSH_COND(p_struct->p_attr_md, ble_gatts_attr_md_t_enc); + SER_PUSH_uint16(&p_struct->init_offs); + SER_PUSH_uint16(&p_struct->max_len); + SER_ERROR_CHECK(p_struct->init_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM); + SER_PUSH_len16data(p_struct->p_value, p_struct->init_len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_attr_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_attr_t); + + SER_PULL_COND(&p_struct->p_uuid, ble_uuid_t_dec); + SER_PULL_COND(&p_struct->p_attr_md, ble_gatts_attr_md_t_dec); + SER_PULL_uint16(&p_struct->init_offs); + SER_PULL_uint16(&p_struct->max_len); + SER_PULL_len16data(&p_struct->p_value, &p_struct->init_len); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_char_handles_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_char_handles_t); + + SER_PUSH_uint16(&p_struct->value_handle); + SER_PUSH_uint16(&p_struct->user_desc_handle); + SER_PUSH_uint16(&p_struct->cccd_handle); + SER_PUSH_uint16(&p_struct->sccd_handle); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_char_handles_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_char_handles_t); + + SER_PULL_uint16(&p_struct->value_handle); + SER_PULL_uint16(&p_struct->user_desc_handle); + SER_PULL_uint16(&p_struct->cccd_handle); + SER_PULL_uint16(&p_struct->sccd_handle); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_hvx_params_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_uint8(&p_struct->type); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_COND(p_struct->p_len, uint16_t_enc); + if (p_struct->p_len) + { + SER_PUSH_buf(p_struct->p_data, *p_struct->p_len); + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_hvx_params_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_uint8(&p_struct->type); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_COND(&p_struct->p_len, uint16_t_dec); + if (p_struct->p_len) + { + SER_PULL_buf(&p_struct->p_data, *p_struct->p_len, *p_struct->p_len); + } + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_write_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc); + SER_PUSH_uint8(&p_struct->op); + SER_PUSH_uint8(&p_struct->auth_required); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint8array(p_struct->data, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_write_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec); + SER_PULL_uint8(&p_struct->op); + SER_PULL_uint8(&p_struct->auth_required); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_uint16(&p_struct->len); + + // Data field is defined as 1-element array, so the first element + // is always allocated in the structure. + SER_ASSERT_LENGTH_LEQ(p_struct->len, *p_ext_len + 1); + SER_PULL_uint8array(p_struct->data, p_struct->len); + *p_ext_len = (p_struct->len > 1) ? p_struct->len - 1 : 0; + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_read_t); + + SER_PUSH_uint16(&p_struct->handle); + SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc); + SER_PUSH_uint16(&p_struct->offset); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_read_t); + + SER_PULL_uint16(&p_struct->handle); + SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec); + SER_PULL_uint16(&p_struct->offset); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_rw_authorize_request_t); + + SER_PUSH_uint8(&p_struct->type); + + switch (p_struct->type) + { + case BLE_GATTS_AUTHORIZE_TYPE_READ: + SER_PUSH_FIELD(&p_struct->request.read, ble_gatts_evt_read_t_enc); + break; + + case BLE_GATTS_AUTHORIZE_TYPE_WRITE: + SER_PUSH_FIELD(&p_struct->request.write, ble_gatts_evt_write_t_enc); + break; + + default: + case BLE_GATTS_AUTHORIZE_TYPE_INVALID: + err_code = NRF_ERROR_INVALID_PARAM; + break; + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_rw_authorize_request_t); + + SER_PULL_uint8(&p_struct->type); + + switch (p_struct->type) + { + case BLE_GATTS_AUTHORIZE_TYPE_READ: + SER_PULL_FIELD(&p_struct->request.read, ble_gatts_evt_read_t_dec); + break; + + case BLE_GATTS_AUTHORIZE_TYPE_WRITE: + err_code = ble_gatts_evt_write_t_dec(p_buf, + buf_len, + p_index, + p_ext_len, + &p_struct->request.write); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + break; + + default: + case BLE_GATTS_AUTHORIZE_TYPE_INVALID: + return NRF_ERROR_INVALID_DATA; + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_authorize_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_authorize_params_t); + + uint8_t ser_data = p_struct->update & 0x01; + SER_PUSH_uint16(&p_struct->gatt_status); + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_len16data(p_struct->p_data, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_authorize_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_authorize_params_t); + + uint8_t ser_data; + SER_PULL_uint16(&p_struct->gatt_status); + SER_PULL_uint8(&ser_data); + SER_PULL_uint16(&p_struct->offset); + SER_PULL_len16data((uint8_t **) &p_struct->p_data, &p_struct->len); + + p_struct->update = ser_data & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_rw_authorize_reply_params_t); + + SER_PUSH_uint8(&p_struct->type); + if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_READ) + { + SER_PUSH_FIELD(&p_struct->params.read, ble_gatts_authorize_params_t_enc); + } + else if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + SER_PUSH_FIELD(&p_struct->params.write, ble_gatts_authorize_params_t_enc); + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_rw_authorize_reply_params_t); + + SER_PULL_uint8(&p_struct->type); + if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_READ) + { + SER_PULL_FIELD(&p_struct->params.read, ble_gatts_authorize_params_t_dec); + } + else if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) + { + SER_PULL_FIELD(&p_struct->params.write, ble_gatts_authorize_params_t_dec); + } + else + { + return NRF_ERROR_INVALID_PARAM; + } + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_enable_params_t); + + uint8_t ser_data = p_struct->service_changed & 0x01; + SER_PUSH_uint8(&ser_data); + SER_PUSH_uint32(&p_struct->attr_tab_size); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_enable_params_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + SER_PULL_uint32(&p_struct->attr_tab_size); + + p_struct->service_changed = ser_data & 0x01; + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_value_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_value_t); + + SER_PUSH_uint16(&p_struct->offset); + SER_PUSH_len16data(p_struct->p_value, p_struct->len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_value_t); + + SER_PULL_uint16(&p_struct->offset); + SER_PULL_len16data(&p_struct->p_value, &p_struct->len); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_exchange_mtu_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_exchange_mtu_request_t); + SER_PUSH_uint16(&p_struct->client_rx_mtu); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_exchange_mtu_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_exchange_mtu_request_t); + SER_PULL_uint16(&p_struct->client_rx_mtu); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_hvc_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_hvc_t); + SER_PUSH_uint16(&p_struct->handle); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_hvc_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_hvc_t); + SER_PULL_uint16(&p_struct->handle); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_sys_attr_missing_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_sys_attr_missing_t); + SER_PUSH_uint8(&p_struct->hint); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_sys_attr_missing_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_sys_attr_missing_t); + SER_PULL_uint8(&p_struct->hint); + SER_STRUCT_DEC_END; +} + +uint32_t ble_gatts_evt_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_gatts_evt_timeout_t); + SER_PUSH_uint8(&p_struct->src); + SER_STRUCT_ENC_END; +} + +uint32_t ble_gatts_evt_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_gatts_evt_timeout_t); + SER_PULL_uint8(&p_struct->src); + SER_STRUCT_DEC_END; +} diff --git a/components/serialization/common/struct_ser/s132/ble_gatts_struct_serialization.h b/components/serialization/common/struct_ser/s132/ble_gatts_struct_serialization.h new file mode 100644 index 0000000..77223dd --- /dev/null +++ b/components/serialization/common/struct_ser/s132/ble_gatts_struct_serialization.h @@ -0,0 +1,226 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATTS_STRUCT_SERIALIZATION_H +#define BLE_GATTS_STRUCT_SERIALIZATION_H + +#include "ble_gatts.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t ble_gatts_char_pf_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_char_pf_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_attr_md_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_attr_md_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_char_md_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_char_md_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_attr_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_attr_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_char_handles_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_char_handles_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_gatts_authorize_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_authorize_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_value_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_exchange_mtu_request_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_exchange_mtu_request_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_hvc_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_hvc_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_sys_attr_missing_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_sys_attr_missing_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_gatts_evt_timeout_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_gatts_evt_timeout_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#ifdef __cplusplus +} +#endif + +#endif /* BLE_GATTS_STRUCT_SERIALIZATION_H */ diff --git a/components/serialization/common/struct_ser/s132/ble_struct_serialization.c b/components/serialization/common/struct_ser/s132/ble_struct_serialization.c new file mode 100644 index 0000000..1fa3453 --- /dev/null +++ b/components/serialization/common/struct_ser/s132/ble_struct_serialization.c @@ -0,0 +1,494 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_struct_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "ble_gatt_struct_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "ble_serialization.h" +#include "app_util.h" +#include "ble_types.h" +#include "ble_l2cap.h" +#include "ble.h" +#include "cond_field_serialization.h" +#include + + +uint32_t ble_uuid_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_uuid_t); + + SER_PUSH_uint16(&p_struct->uuid); + SER_PUSH_uint8(&p_struct->type); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_uuid_t); + + SER_PULL_uint16(&p_struct->uuid); + SER_PULL_uint8(&p_struct->type); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_uuid128_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_uuid128_t); + SER_PUSH_uint8array(p_struct->uuid128, sizeof (p_struct->uuid128)); + SER_STRUCT_ENC_END; +} + +uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_uuid128_t); + SER_PULL_uint8array(p_struct->uuid128, sizeof (p_struct->uuid128)); + SER_STRUCT_DEC_END; +} + +uint32_t ble_l2cap_header_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_l2cap_header_t); + + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_uint16(&p_struct->cid); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_l2cap_header_t); + + SER_PULL_uint16(&p_struct->len); + SER_PULL_uint16(&p_struct->cid); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_l2cap_evt_rx_t); + + SER_PUSH_FIELD(&p_struct->header, ble_l2cap_header_t_enc); + SER_PUSH_uint8array(p_struct->data, p_struct->header.len); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_l2cap_evt_rx_t); + + SER_PULL_FIELD(&p_struct->header, ble_l2cap_header_t_dec); + + uint32_t data_len = (SUB1(p_struct->header.len)); + SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len); + + SER_PULL_uint8array(p_struct->data, p_struct->header.len); + + *p_ext_len = data_len; + SER_STRUCT_DEC_END; +} + +uint32_t ble_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_enable_params_t); + + SER_PUSH_FIELD(&p_struct->common_enable_params, ble_common_enable_params_t_enc); + SER_PUSH_FIELD(&p_struct->gap_enable_params, ble_gap_enable_params_t_enc); + SER_PUSH_FIELD(&p_struct->gatt_enable_params, ble_gatt_enable_params_t_enc); + SER_PUSH_FIELD(&p_struct->gatts_enable_params, ble_gatts_enable_params_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_enable_params_t); + + SER_PULL_FIELD(&p_struct->common_enable_params, ble_common_enable_params_t_dec); + SER_PULL_FIELD(&p_struct->gap_enable_params, ble_gap_enable_params_t_dec); + SER_PULL_FIELD(&p_struct->gatt_enable_params, ble_gatt_enable_params_t_dec); + SER_PULL_FIELD(&p_struct->gatts_enable_params, ble_gatts_enable_params_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_conn_bw_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_conn_bw_t); + + SER_PUSH_uint8(&p_struct->conn_bw_rx); + SER_PUSH_uint8(&p_struct->conn_bw_tx); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_conn_bw_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_conn_bw_t); + + SER_PULL_uint8(&p_struct->conn_bw_rx); + SER_PULL_uint8(&p_struct->conn_bw_tx); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_common_opt_conn_bw_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_common_opt_conn_bw_t); + + SER_PUSH_uint8(&p_struct->role); + SER_PUSH_FIELD(&p_struct->conn_bw, ble_conn_bw_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_common_opt_conn_bw_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_common_opt_conn_bw_t); + + SER_PULL_uint8(&p_struct->role); + SER_PULL_FIELD(&p_struct->conn_bw, ble_conn_bw_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_conn_bw_count_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_conn_bw_count_t); + + SER_PUSH_uint8(&p_struct->high_count); + SER_PUSH_uint8(&p_struct->mid_count); + SER_PUSH_uint8(&p_struct->low_count); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_conn_bw_count_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_conn_bw_count_t); + + SER_PULL_uint8(&p_struct->high_count); + SER_PULL_uint8(&p_struct->mid_count); + SER_PULL_uint8(&p_struct->low_count); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_conn_bw_counts_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_conn_bw_counts_t); + + SER_PUSH_FIELD(&p_struct->tx_counts, ble_conn_bw_count_t_enc); + SER_PUSH_FIELD(&p_struct->rx_counts, ble_conn_bw_count_t_enc); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_conn_bw_counts_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_conn_bw_counts_t); + + SER_PULL_FIELD(&p_struct->tx_counts, ble_conn_bw_count_t_dec); + SER_PULL_FIELD(&p_struct->rx_counts, ble_conn_bw_count_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_common_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_common_enable_params_t); + + SER_PUSH_uint16(&p_struct->vs_uuid_count); + SER_PUSH_COND(p_struct->p_conn_bw_counts, ble_conn_bw_counts_t_enc); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_common_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_common_enable_params_t); + + SER_PULL_uint16(&p_struct->vs_uuid_count); + SER_PULL_COND(&p_struct->p_conn_bw_counts, ble_conn_bw_counts_t_dec); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_common_opt_pa_lna_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_common_opt_pa_lna_t); + + SER_PUSH_FIELD(&p_struct->pa_cfg, ble_pa_lna_cfg_t_enc); + SER_PUSH_FIELD(&p_struct->lna_cfg, ble_pa_lna_cfg_t_enc); + SER_PUSH_uint8(&p_struct->ppi_ch_id_set); + SER_PUSH_uint8(&p_struct->ppi_ch_id_clr); + SER_PUSH_uint8(&p_struct->gpiote_ch_id); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_common_opt_pa_lna_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_common_opt_pa_lna_t); + + SER_PULL_FIELD(&p_struct->pa_cfg, ble_pa_lna_cfg_t_dec); + SER_PULL_FIELD(&p_struct->lna_cfg, ble_pa_lna_cfg_t_dec); + SER_PULL_uint8(&p_struct->ppi_ch_id_set); + SER_PULL_uint8(&p_struct->ppi_ch_id_clr); + SER_PULL_uint8(&p_struct->gpiote_ch_id); + + SER_STRUCT_DEC_END; +} + + +uint32_t ble_pa_lna_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_pa_lna_cfg_t); + + uint8_t ser_data = (p_struct->enable & 0x01) + | ((p_struct->active_high & 0x01) << 1) + | ((p_struct->gpio_pin & 0x3F) << 2); + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_pa_lna_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_pa_lna_cfg_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->enable = ser_data & 0x01; + p_struct->active_high = (ser_data >> 1) & 0x01; + p_struct->gpio_pin = (ser_data >> 2) & 0x3F; + + SER_STRUCT_DEC_END; +} + + +uint32_t ble_user_mem_block_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_user_mem_block_t); + + SER_PUSH_uint16(&p_struct->len); + SER_PUSH_COND(p_struct->p_mem, NULL); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_user_mem_block_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_user_mem_block_t); + + SER_PULL_uint16(&p_struct->len); + SER_PULL_COND(&p_struct->p_mem, NULL); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_version_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_version_t); + + SER_PUSH_uint8(&p_struct->version_number); + SER_PUSH_uint16(&p_struct->company_id); + SER_PUSH_uint16(&p_struct->subversion_number); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_version_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_version_t); + + SER_PULL_uint8(&p_struct->version_number); + SER_PULL_uint16(&p_struct->company_id); + SER_PULL_uint16(&p_struct->subversion_number); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_evt_data_length_changed_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_evt_data_length_changed_t); + + SER_PUSH_uint16(&p_struct->max_tx_octets); + SER_PUSH_uint16(&p_struct->max_tx_time); + SER_PUSH_uint16(&p_struct->max_rx_octets); + SER_PUSH_uint16(&p_struct->max_rx_time); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_evt_data_length_changed_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_evt_data_length_changed_t); + + SER_PULL_uint16(&p_struct->max_tx_octets); + SER_PULL_uint16(&p_struct->max_tx_time); + SER_PULL_uint16(&p_struct->max_rx_octets); + SER_PULL_uint16(&p_struct->max_rx_time); + + SER_STRUCT_DEC_END; +} + +uint32_t ble_common_opt_conn_evt_ext_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(ble_common_opt_conn_evt_ext_t); + + uint8_t ser_data = p_struct->enable & 0x01; + SER_PUSH_uint8(&ser_data); + + SER_STRUCT_ENC_END; +} + +uint32_t ble_common_opt_conn_evt_ext_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(ble_common_opt_conn_evt_ext_t); + + uint8_t ser_data; + SER_PULL_uint8(&ser_data); + p_struct->enable = ser_data & 0x01; + + SER_STRUCT_DEC_END; +} diff --git a/components/serialization/common/struct_ser/s132/ble_struct_serialization.h b/components/serialization/common/struct_ser/s132/ble_struct_serialization.h new file mode 100644 index 0000000..00727dc --- /dev/null +++ b/components/serialization/common/struct_ser/s132/ble_struct_serialization.h @@ -0,0 +1,216 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_STRUCT_SERIALIZATION_H__ +#define BLE_STRUCT_SERIALIZATION_H__ + +#include "ble_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +uint32_t ble_uuid_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_uuid_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_uuid128_t_enc(const void * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_l2cap_header_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + uint32_t * const p_ext_len, + void * const p_void_struct); + +uint32_t ble_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_conn_bw_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_conn_bw_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_common_opt_conn_bw_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_common_opt_conn_bw_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_conn_bw_count_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_conn_bw_count_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_conn_bw_counts_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_conn_bw_counts_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_common_enable_params_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_common_enable_params_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_common_opt_pa_lna_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_common_opt_pa_lna_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_pa_lna_cfg_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_pa_lna_cfg_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_user_mem_block_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_user_mem_block_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_version_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_version_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_evt_data_length_changed_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_evt_data_length_changed_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t ble_common_opt_conn_evt_ext_t_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t ble_common_opt_conn_evt_ext_t_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#ifdef __cplusplus +} +#endif + +#endif // BLE_STRUCT_SERIALIZATION_H__ diff --git a/components/serialization/common/struct_ser/s132/nrf_soc_struct_serialization.c b/components/serialization/common/struct_ser/s132/nrf_soc_struct_serialization.c new file mode 100644 index 0000000..13acf3f --- /dev/null +++ b/components/serialization/common/struct_ser/s132/nrf_soc_struct_serialization.c @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_soc_struct_serialization.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include "string.h" + +uint32_t nrf_ecb_hal_data_t_in_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(nrf_ecb_hal_data_t); + + SER_PUSH_uint8array(p_struct->key, SOC_ECB_KEY_LENGTH); + SER_PUSH_uint8array(p_struct->cleartext, SOC_ECB_CLEARTEXT_LENGTH); + + SER_STRUCT_DEC_END; +} + +uint32_t nrf_ecb_hal_data_t_in_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(nrf_ecb_hal_data_t); + + SER_PULL_uint8array(p_struct->key, SOC_ECB_KEY_LENGTH); + SER_PULL_uint8array(p_struct->cleartext, SOC_ECB_CLEARTEXT_LENGTH); + + SER_STRUCT_DEC_END; +} + +uint32_t nrf_ecb_hal_data_t_out_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index) +{ + SER_STRUCT_ENC_BEGIN(nrf_ecb_hal_data_t); + SER_PUSH_uint8array(p_struct->ciphertext, SOC_ECB_CIPHERTEXT_LENGTH); + SER_STRUCT_DEC_END; +} + +uint32_t nrf_ecb_hal_data_t_out_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct) +{ + SER_STRUCT_DEC_BEGIN(nrf_ecb_hal_data_t); + SER_PULL_uint8array(p_struct->ciphertext, SOC_ECB_CIPHERTEXT_LENGTH); + SER_STRUCT_DEC_END; +} diff --git a/components/serialization/common/struct_ser/s132/nrf_soc_struct_serialization.h b/components/serialization/common/struct_ser/s132/nrf_soc_struct_serialization.h new file mode 100644 index 0000000..edda016 --- /dev/null +++ b/components/serialization/common/struct_ser/s132/nrf_soc_struct_serialization.h @@ -0,0 +1,74 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SOC_STRUCT_SERIALIZATION_H__ +#define NRF_SOC_STRUCT_SERIALIZATION_H__ + +#include "nrf_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t nrf_ecb_hal_data_t_in_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t nrf_ecb_hal_data_t_in_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +uint32_t nrf_ecb_hal_data_t_out_enc(void const * const p_void_struct, + uint8_t * const p_buf, + uint32_t buf_len, + uint32_t * const p_index); + +uint32_t nrf_ecb_hal_data_t_out_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint32_t * const p_index, + void * const p_void_struct); + +#ifdef __cplusplus +} +#endif + +#endif // NRF_SOC_STRUCT_SERIALIZATION_H__ diff --git a/components/serialization/common/transport/debug/debug_hci_config_nrf6310.h b/components/serialization/common/transport/debug/debug_hci_config_nrf6310.h deleted file mode 100644 index 624b769..0000000 --- a/components/serialization/common/transport/debug/debug_hci_config_nrf6310.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 DEBUG_HCI_CONFIG_NRF6310_H__ -#define DEBUG_HCI_CONFIG_NRF6310_H__ - -#include "boards.h" - -// define CONN_DGB to prevent CONN chip from being reseted while connected via DBG -#define nCONN_DGB - -#define PIN_EVT_DBG - -#define LED_MEM_CALLBACK LED_3 -#define LED_RX_CALLBACK LED_4 -#define LED_TX_CALLBACK LED_5 -#define LED_DP_CALLBACK LED_6 -#define LED_TX_ERR_CALLBACK LED_7 - -#define PIO_SLIP_EVT_PKT_TX 24 -#define PIO_SLIP_EVT_ACK_TX 25 -#define PIO_SLIP_EVT_PKT_TXED 28 -#define PIO_SLIP_EVT_ACK_TXED 29 -#define PIO_SLIP_EVT_PKT_RXED 0 -#define PIO_SLIP_EVT_ACK_RXED 1 -#define PIO_TIMER_EVT_TIMEOUT 2 -#define PIO_HCI_RETX 3 -#define PIO_MAIN_BUSY 4 -#define PIO_TX_REQ 5 - -#define PIO_SLIP_EVT_ERR_RXED LED_2 // only pulses not change of state - - -#endif //DEBUG_CONFIG_NRF6310_H__ - diff --git a/components/serialization/common/transport/debug/debug_hci_nrf6310.c b/components/serialization/common/transport/debug/debug_hci_nrf6310.c deleted file mode 100644 index 64425f6..0000000 --- a/components/serialization/common/transport/debug/debug_hci_nrf6310.c +++ /dev/null @@ -1,228 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include -#include "nrf_delay.h" -#include "nrf_gpio.h" - -#ifdef SER_PHY_HCI_DEBUG_ENABLE - -#include "ser_phy_debug_comm.h" -#include "debug_hci_config_nRF6310.h" -#include "app_error.h" - -#define LED_BLINK_us 1 /* 1 us */ - -static hci_dbg_event_handler_t m_hci_dbg_event_handler = NULL; - -static void pio_blink(uint8_t led) -{ - nrf_gpio_pin_set(led); - nrf_delay_us(LED_BLINK_us); - nrf_gpio_pin_clear(led); -} - - -static void Debug_PulseOnMemCallback() -{ - pio_blink(LED_MEM_CALLBACK); -} - - -static void Debug_PulseOnRxCallback() -{ - pio_blink(LED_RX_CALLBACK); -} - - -static void Debug_PulseOnTxCallback() -{ - pio_blink(LED_TX_CALLBACK); -} - - -static void Debug_PulseOnPacketDroppedCallback() -{ - pio_blink(LED_DP_CALLBACK); -} - -static void Debug_PulseOnTxError() -{ - pio_blink(LED_TX_ERR_CALLBACK); -} - -static void Debug_PulseOnPacketTX() -{ - pio_blink(PIO_SLIP_EVT_PKT_TX); -} - -static void Debug_PulseOnAckTX() -{ - pio_blink(PIO_SLIP_EVT_ACK_TX); -} - -static void Debug_PulseOnPacketTXED() -{ - pio_blink(PIO_SLIP_EVT_PKT_TXED); -} - -static void Debug_PulseOnAckTXED() -{ - pio_blink(PIO_SLIP_EVT_ACK_TXED); -} - -static void Debug_PulseOnPacketRXED() -{ - pio_blink(PIO_SLIP_EVT_PKT_RXED); -} - -static void Debug_PulseOnAckRXED() -{ - pio_blink(PIO_SLIP_EVT_ACK_RXED); -} - -static void Debug_PulseOnErrRXED() -{ - pio_blink(PIO_SLIP_EVT_ERR_RXED); - /* throw assert when in debug mode*/ - APP_ERROR_CHECK_BOOL(false); -} - -static void Debug_PulseOnTimer() -{ - pio_blink(PIO_TIMER_EVT_TIMEOUT); -} - -static void Debug_PulseOnRETX() -{ - pio_blink(PIO_HCI_RETX); -} - -static void Debug_LevelOnBusy(uint32_t data) -{ - if (data) - { - nrf_gpio_pin_set(PIO_MAIN_BUSY); - } - else - { - nrf_gpio_pin_clear(PIO_MAIN_BUSY); - } -} - -static void Debug_PulseOnTXReq() -{ - pio_blink(PIO_TX_REQ); -} - -static void default_hci_event_handler(hci_dbg_evt_t event) -{ - switch (event.evt) - { - case HCI_PHY_EVT_TX_PKT_SENT: - Debug_PulseOnTxCallback(); - break; - case HCI_PHY_EVT_BUF_REQUEST: - Debug_PulseOnMemCallback(); - break; - case HCI_PHY_EVT_RX_PKT_RECEIVED: - Debug_PulseOnRxCallback(); - break; - case HCI_PHY_EVT_RX_PKT_DROPPED: - Debug_PulseOnPacketDroppedCallback(); - break; - case HCI_PHY_EVT_TX_ERROR: - Debug_PulseOnTxError(); - break; - case HCI_SLIP_EVT_PACKET_TX: - Debug_PulseOnPacketTX(); - break; - case HCI_SLIP_EVT_ACK_TX: - Debug_PulseOnAckTX(); - break; - case HCI_SLIP_EVT_PACKET_TXED: - Debug_PulseOnPacketTXED(); - break; - case HCI_SLIP_EVT_ACK_TXED: - Debug_PulseOnAckTXED(); - break; - case HCI_SLIP_EVT_PACKET_RXED: - Debug_PulseOnPacketRXED(); - break; - case HCI_SLIP_EVT_ACK_RXED: - Debug_PulseOnAckRXED(); - break; - case HCI_SLIP_EVT_ERR_RXED: - Debug_PulseOnErrRXED(); - break; - case HCI_TIMER_EVT_TIMEOUT: - Debug_PulseOnTimer(); - break; - case HCI_RETX: - Debug_PulseOnRETX(); - break; - case HCI_MAIN_BUSY: - Debug_LevelOnBusy(event.data); - break; - case HCI_TX_REQ: - Debug_PulseOnTXReq(); - break; - - default: - break; - } - return; -} - - -void debug_init(hci_dbg_event_handler_t evt_callback) -{ - //Configure all LED as outputs. - nrf_gpio_range_cfg_output(LED_START, LED_STOP); - - nrf_gpio_cfg_output(PIO_SLIP_EVT_PKT_TX); - nrf_gpio_cfg_output(PIO_SLIP_EVT_ACK_TX); - nrf_gpio_cfg_output(PIO_SLIP_EVT_PKT_TXED); - nrf_gpio_cfg_output(PIO_SLIP_EVT_ACK_TXED); - nrf_gpio_cfg_output(PIO_SLIP_EVT_PKT_RXED); - nrf_gpio_cfg_output(PIO_SLIP_EVT_ACK_RXED); - nrf_gpio_cfg_output(PIO_TIMER_EVT_TIMEOUT); - nrf_gpio_cfg_output(PIO_HCI_RETX); - nrf_gpio_cfg_output(PIO_MAIN_BUSY); - nrf_gpio_cfg_output(PIO_TX_REQ); - m_hci_dbg_event_handler = evt_callback; - if (evt_callback) - { - m_hci_dbg_event_handler = evt_callback; - } - else - { - m_hci_dbg_event_handler = default_hci_event_handler; - } - -} - - -void debug_evt(hci_dbg_evt_type_t evt, uint32_t data) -{ - hci_dbg_evt_t event; - event.evt = evt; - event.data = data; - - if (m_hci_dbg_event_handler) - { - m_hci_dbg_event_handler(event); - } -} - -#endif diff --git a/components/serialization/common/transport/dtm_uart_params.h b/components/serialization/common/transport/dtm_uart_params.h index e4000c0..5d86dd5 100644 --- a/components/serialization/common/transport/dtm_uart_params.h +++ b/components/serialization/common/transport/dtm_uart_params.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 DTM_UART_PARAMS_H__ @@ -16,11 +44,15 @@ #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** @ingroup ble_dtm_app */ -/**@brief Enumeration of supported baud rates. */ +/**@brief Enumeration of supported baud rates. */ typedef enum { UART_BAUD_RATE_1200, /**< Baud rate 1200. */ @@ -54,4 +86,9 @@ typedef struct app_uart_stream_baud_rate_t baud_rate; /**< Baud rate configuration. */ } app_uart_stream_comm_params_t; + +#ifdef __cplusplus +} +#endif + #endif // DTM_UART_PARAMS_H__ diff --git a/components/serialization/common/transport/ser_hal_transport.c b/components/serialization/common/transport/ser_hal_transport.c index b2c32c3..c094350 100644 --- a/components/serialization/common/transport/ser_hal_transport.c +++ b/components/serialization/common/transport/ser_hal_transport.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include diff --git a/components/serialization/common/transport/ser_hal_transport.h b/components/serialization/common/transport/ser_hal_transport.h index 811dd4c..686a354 100644 --- a/components/serialization/common/transport/ser_hal_transport.h +++ b/components/serialization/common/transport/ser_hal_transport.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -16,18 +44,18 @@ * @{ * @ingroup ble_sdk_lib_serialization * - * @brief HAL Transport layer for serialization. + * @brief @tagAPI52832 HAL Transport layer for serialization. * - * @details This file contains declarations of functions and typedefs used as API of the HAL + * @details This section contains declarations of functions and typedefs used as API of the HAL * Transport layer for serialization. This layer is fully hardware independent. - * Currently the HAL Transport layer is responsible for controlling the PHY layer and - * memory management. In the future it is possible to add more feature to it as: crc, - * retransmission etc. + * Currently, the HAL Transport layer is responsible for controlling the PHY layer and + * memory management. In the future, it is possible to add more features to it, such as crc + * or retransmission. * * \n \n - * \image html ser_hal_transport_rx_state_machine.png "RX state machine" + * \image html ser_hal_transport_rx_state_machine.svg "RX state machine" * \n \n - * \image html ser_hal_transport_tx_state_machine.png "TX state machine" + * \image html ser_hal_transport_tx_state_machine.svg "TX state machine" * \n */ @@ -36,6 +64,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Serialization HAL Transport layer event types. */ typedef enum @@ -57,16 +89,16 @@ typedef enum typedef enum { SER_HAL_TRANSP_PHY_ERROR_RX_OVERFLOW = 0, /**< An error indicating that more information has - been transmitted than phy module could handle. */ - SER_HAL_TRANSP_PHY_ERROR_TX_OVERREAD, /**< An error indicating that phy module was forced to + been transmitted than the PHY module could handle. */ + SER_HAL_TRANSP_PHY_ERROR_TX_OVERREAD, /**< An error indicating that the PHY module was forced to transmit more information than possessed. */ - SER_HAL_TRANSP_PHY_ERROR_HW_ERROR, /**< An error indicating a hardware error in a phy + SER_HAL_TRANSP_PHY_ERROR_HW_ERROR, /**< An error indicating a hardware error in the PHY module. */ SER_HAL_TRANSP_PHY_ERROR_TYPE_MAX /**< Enumeration upper bound. */ } ser_hal_transport_phy_error_type_t; -/**@brief A struct containing parameters of the event of type +/**@brief Struct containing parameters of event of type * @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED. */ typedef struct @@ -76,42 +108,42 @@ typedef struct } ser_hal_transport_evt_rx_pkt_received_params_t; -/**@brief A struct containing parameters of the event of type @ref SER_HAL_TRANSP_EVT_PHY_ERROR. */ +/**@brief Struct containing parameters of event of type @ref SER_HAL_TRANSP_EVT_PHY_ERROR. */ typedef struct { - ser_hal_transport_phy_error_type_t error_type; /**< Type of PHY error. */ - uint32_t hw_error_code; /**< Hardware error code - specific for any microcontroller. Parameter - is valid only for the phy error of type + ser_hal_transport_phy_error_type_t error_type; /**< Type of the PHY error. */ + uint32_t hw_error_code; /**< Hardware error code - specific for a microcontroller. Parameter + is valid only for the PHY error of type @ref SER_HAL_TRANSP_PHY_ERROR_HW_ERROR. */ } ser_hal_transport_evt_phy_error_params_t; -/**@brief A struct containing events from the Serialization HAL Transport layer. +/**@brief Struct containing events from the Serialization HAL Transport layer. * - * @note Some events do not have parameters, then whole information is contained in the evt_type. + * @note Some events do not have parameters, then the whole information is contained in the evt_type. */ typedef struct { ser_hal_transport_evt_type_t evt_type; /**< Type of event. */ - union /**< Union alternative identified by evt_type in enclosing struct. */ + union /**< Union alternative identified by evt_type in the enclosing struct. */ { - ser_hal_transport_evt_rx_pkt_received_params_t rx_pkt_received; /**< Parameters of the event of type @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED. */ - ser_hal_transport_evt_phy_error_params_t phy_error; /**< Parameters of the event of type @ref SER_HAL_TRANSP_EVT_PHY_ERROR. */ + ser_hal_transport_evt_rx_pkt_received_params_t rx_pkt_received; /**< Parameters of event of type @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED. */ + ser_hal_transport_evt_phy_error_params_t phy_error; /**< Parameters of event of type @ref SER_HAL_TRANSP_EVT_PHY_ERROR. */ } evt_params; } ser_hal_transport_evt_t; -/**@brief A generic callback function type to be used by all Serialization HAL Transport layer +/**@brief Generic callback function type to be used by all Serialization HAL Transport layer * events. * * @param[in] event Serialization HAL Transport layer event. */ typedef void (*ser_hal_transport_events_handler_t)(ser_hal_transport_evt_t event); - -/**@brief A function for opening and initializing the Serialization HAL Transport layer. + +/**@brief Function for opening and initializing the Serialization HAL Transport layer. * - * @note The function opens the transport channel, initializes a PHY layer and registers callback + * @note The function opens the transport channel, initializes a PHY layer, and registers the callback * function to be used by all Serialization HAL Transport layer events. * * @warning If the function has been already called, the function @ref ser_hal_transport_close has @@ -119,36 +151,36 @@ typedef void (*ser_hal_transport_events_handler_t)(ser_hal_transport_evt_t event * * @param[in] events_handler Generic callback function to be used by all Serialization HAL * Transport layer events. - * + * * @retval NRF_SUCCESS Operation success. * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. * @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters taken from * the configuration file are wrong. * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. To call * it again the function @ref ser_hal_transport_close has to be - * called previously. - * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. + * called first. + * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. */ uint32_t ser_hal_transport_open(ser_hal_transport_events_handler_t events_handler); -/**@brief A function for closing a transport channel. +/**@brief Function for closing a transport channel. * - * @note The function disables hardware, resets internal module states and unregisters events - * callback function. Can be called multiple times, also for not opened channel. + * @note The function disables the hardware, resets internal module states, and unregisters the events + * callback function. Can be called multiple times, also for a channel that is not opened. */ void ser_hal_transport_close(void); -/**@brief A function for freeing a memory allocated for RX packet. +/**@brief Function for freeing memory allocated for an RX packet. * * @note The function should be called as a response to an event of type - * @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED when received data has beed processed. The function - * frees an RX memory pointed by p_buffer. The memory, immediately or at a later time, is + * @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED when the received data has beed processed. The function + * frees the RX memory pointed by p_buffer. The memory, immediately or at a later time, is * reused by the underlying transport layer. * - * @param[in] p_buffer A pointer to the beginning of a buffer that has been processed (has to be - * the same address as provided in an event of type + * @param[in] p_buffer A pointer to the beginning of the buffer that has been processed (has to be + * the same address as provided in the event of type * @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED). * * @retval NRF_SUCCESS Operation success. @@ -162,13 +194,13 @@ void ser_hal_transport_close(void); uint32_t ser_hal_transport_rx_pkt_free(uint8_t * p_buffer); -/**@brief A function for allocating a memory for TX packet. - * +/**@brief Function for allocating memory for a TX packet. + * * @param[out] pp_memory A pointer to pointer to which an address of the beginning of the * allocated buffer is written. * @param[out] p_num_of_bytes A pointer to a variable to which size in octets of the allocated * buffer is written. - * + * * @retval NRF_SUCCESS Operation success. Memory was allocated. * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. * @retval NRF_ERROR_NO_MEM Operation failure. No memory available. @@ -177,15 +209,14 @@ uint32_t ser_hal_transport_rx_pkt_free(uint8_t * p_buffer); */ uint32_t ser_hal_transport_tx_pkt_alloc(uint8_t ** pp_memory, uint16_t * p_num_of_bytes); -/**@brief A function for transmitting a packet. +/**@brief Function for transmitting a packet. * - * @note The function adds a packet pointed by p_buffer parameter to a transmission queue. A buffer - * provided to this function must be allocated by @ref ser_hal_transport_tx_pkt_alloc function. + * @note The function adds a packet pointed by the p_buffer parameter to a transmission queue. A buffer + * provided to this function must be allocated by the @ref ser_hal_transport_tx_pkt_alloc function. * - * @warning Completion of this method does not guarantee that actual peripheral transmission would - * have completed. + * @warning Completion of this method does not guarantee that actual peripheral transmission will be completed. * - * @param[in] p_buffer A pointer to a buffer to transmit. + * @param[in] p_buffer Pointer to the buffer to transmit. * @param[in] num_of_bytes Number of octets to transmit. Must be more than 0. * * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue. @@ -204,16 +235,16 @@ uint32_t ser_hal_transport_tx_pkt_alloc(uint8_t ** pp_memory, uint16_t * p_num_o uint32_t ser_hal_transport_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes); -/**@brief A function for freeing a memory allocated for TX packet. +/**@brief Function for freeing memory allocated for a TX packet. * - * @note The function frees a TX memory pointed by p_buffer. Freeing a TX buffer is possible only if + * @note The function frees the TX memory pointed by p_buffer. Freeing a TX buffer is possible only if * the buffer was allocated by @ref ser_hal_transport_tx_pkt_alloc function and transmittion - * is not in progress. When transmittion has finished this function is automatically called by + * is not in progress. When transmittion has finished, this function is automatically called by * the Serialization HAL Transport layer, so the only case when this function should be used * from outside is when a TX buffer was allocated but a transmittion has not been started * (@ref ser_hal_transport_tx_pkt_send function has not been called). * - * @param[in] p_buffer A pointer to the beginning of a buffer that has been allocated by + * @param[in] p_buffer Pointer to the beginning of a buffer that has been allocated by * @ref ser_hal_transport_tx_pkt_alloc function. * * @retval NRF_SUCCESS Operation success. Memory was freed. @@ -227,5 +258,10 @@ uint32_t ser_hal_transport_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of uint32_t ser_hal_transport_tx_pkt_free(uint8_t * p_buffer); + +#ifdef __cplusplus +} +#endif + #endif /* SER_HAL_TRANSPORT_H__ */ /** @} */ diff --git a/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h b/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h index 635502c..abeb323 100644 --- a/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h +++ b/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h @@ -1,16 +1,53 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SER_CONFIG_5W_APP_H__ #define SER_CONFIG_5W_APP_H__ +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + #endif /* SER_CONFIG_APP_H__ */ diff --git a/components/serialization/common/transport/ser_phy/config/ser_phy_config_app_nrf51.h b/components/serialization/common/transport/ser_phy/config/ser_phy_config_app.h similarity index 54% rename from components/serialization/common/transport/ser_phy/config/ser_phy_config_app_nrf51.h rename to components/serialization/common/transport/ser_phy/config/ser_phy_config_app.h index af0f70d..1b98035 100644 --- a/components/serialization/common/transport/ser_phy/config/ser_phy_config_app_nrf51.h +++ b/components/serialization/common/transport/ser_phy/config/ser_phy_config_app.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SER_CONFIG_APP_HAL_NRF51_H__ @@ -16,6 +44,10 @@ #include "boards.h" #include "ser_config.h" +#ifdef __cplusplus +extern "C" { +#endif + #if defined(SPI_MASTER_0_ENABLE) #define SER_PHY_SPI_MASTER SPI_MASTER_0 #endif @@ -58,7 +90,7 @@ #endif -#define CONN_CHIP_RESET_PIN_NO SER_CONN_CHIP_RESET_PIN /**< Pin used for reseting the nRF51822. */ +#define CONN_CHIP_RESET_PIN_NO SER_CONN_CHIP_RESET_PIN /**< Pin used for reseting the connectivity. */ /* UART configuration */ #define UART_IRQ_PRIORITY APP_IRQ_PRIORITY_MID @@ -67,4 +99,9 @@ #define SER_PHY_UART_CTS SER_APP_CTS_PIN #define SER_PHY_UART_RTS SER_APP_RTS_PIN + +#ifdef __cplusplus +} +#endif + #endif //SER_CONFIG_APP_HAL_NRF51_H__ diff --git a/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h b/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h new file mode 100644 index 0000000..902fbb2 --- /dev/null +++ b/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h @@ -0,0 +1,79 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SER_PHY_CONFIG_CONN_NRF51_H__ +#define SER_PHY_CONFIG_CONN_NRF51_H__ + +#include "boards.h" +#include "ser_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***********************************************************************************************//** + * SER_PHY layer configuration. + **************************************************************************************************/ +#define SER_PHY_SPI_PPI_RDY_CH 0 +#define SER_PHY_SPI_GPIOTE_RDY_CH 0 + +#define SER_PHY_SPI_SLAVE_INSTANCE 1 + +#define SER_PHY_SPI_SLAVE_REQ_PIN SER_CON_SPIS_REQ_PIN +#define SER_PHY_SPI_SLAVE_RDY_PIN SER_CON_SPIS_RDY_PIN +#define SER_PHY_SPI_SLAVE_SCK_PIN SER_CON_SPIS_SCK_PIN +#define SER_PHY_SPI_SLAVE_MISO_PIN SER_CON_SPIS_MISO_PIN +#define SER_PHY_SPI_SLAVE_MOSI_PIN SER_CON_SPIS_MOSI_PIN +#define SER_PHY_SPI_SLAVE_SS_PIN SER_CON_SPIS_CSN_PIN + +/* UART configuration */ +#define UART_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST + +#define SER_PHY_UART_RX SER_CON_RX_PIN +#define SER_PHY_UART_TX SER_CON_TX_PIN +#define SER_PHY_UART_CTS SER_CON_CTS_PIN +#define SER_PHY_UART_RTS SER_CON_RTS_PIN + + +#ifdef __cplusplus +} +#endif + +#endif //SER_PHY_CONFIG_CONN_NRF51_H__ diff --git a/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn_nrf51.h b/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn_nrf51.h deleted file mode 100644 index 233ab0c..0000000 --- a/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn_nrf51.h +++ /dev/null @@ -1,42 +0,0 @@ - /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 SER_PHY_CONFIG_CONN_NRF51_H__ -#define SER_PHY_CONFIG_CONN_NRF51_H__ - -#include "boards.h" -#include "ser_config.h" - -/***********************************************************************************************//** - * SER_PHY layer configuration. - **************************************************************************************************/ -#define SER_PHY_SPI_PPI_RDY_CH 0 -#define SER_PHY_SPI_GPIOTE_RDY_CH 0 - -#define SER_PHY_SPI_SLAVE_INSTANCE 1 - -#define SER_PHY_SPI_SLAVE_REQ_PIN SER_CON_SPIS_REQ_PIN -#define SER_PHY_SPI_SLAVE_RDY_PIN SER_CON_SPIS_RDY_PIN -#define SER_PHY_SPI_SLAVE_SCK_PIN SER_CON_SPIS_SCK_PIN -#define SER_PHY_SPI_SLAVE_MISO_PIN SER_CON_SPIS_MISO_PIN -#define SER_PHY_SPI_SLAVE_MOSI_PIN SER_CON_SPIS_MOSI_PIN -#define SER_PHY_SPI_SLAVE_SS_PIN SER_CON_SPIS_CSN_PIN - -/* UART configuration */ -#define UART_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SER_PHY_UART_RX SER_CON_RX_PIN -#define SER_PHY_UART_TX SER_CON_TX_PIN -#define SER_PHY_UART_CTS SER_CON_CTS_PIN -#define SER_PHY_UART_RTS SER_CON_RTS_PIN - -#endif //SER_PHY_CONFIG_CONN_NRF51_H__ diff --git a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h b/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h index 349af24..9ee56af 100644 --- a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h +++ b/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SER_PHY_DEBUG_APP_H__ @@ -32,7 +60,11 @@ #define DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(data) #else -#include "stdint.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif //Low level hardware events typedef enum @@ -73,7 +105,7 @@ void debug_evt(spi_master_raw_evt_type_t evt, uint32_t data); #define DEBUG_EVT(evt, data) \ do { \ debug_evt(evt, data); \ -} while(0); +} while (0); #define DEBUG_EVT_SPI_MASTER_RAW_REQUEST(data) \ @@ -157,6 +189,11 @@ do { \ +#endif + + +#ifdef __cplusplus +} #endif #endif //SER_PHY_DEBUG_APP_H__ diff --git a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h b/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h index 043d2b9..8bdafed 100644 --- a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h +++ b/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SER_PHY_DEBUG_CONN_H__ @@ -35,7 +63,11 @@ #else -#include "stdint.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif // low level hardware event types typedef enum @@ -127,4 +159,9 @@ do { \ #endif + +#ifdef __cplusplus +} +#endif + #endif //SER_PHY_DEBUG_CONN_H__ diff --git a/components/serialization/common/transport/ser_phy/ser_phy.c b/components/serialization/common/transport/ser_phy/ser_phy.c index e531487..532b89a 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy.c +++ b/components/serialization/common/transport/ser_phy/ser_phy.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ser_phy.h" diff --git a/components/serialization/common/transport/ser_phy/ser_phy.h b/components/serialization/common/transport/ser_phy/ser_phy.h index c797699..44cb9ff 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy.h +++ b/components/serialization/common/transport/ser_phy/ser_phy.h @@ -1,13 +1,41 @@ - /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -16,15 +44,15 @@ * @{ * @ingroup ble_sdk_lib_serialization * - * @brief PHY layer layer for serialization. + * @brief @tagAPI52832 PHY layer for serialization. * - * @details This file contains declarations of functions and definitions of data structures and + * @details Here you can find declarations of functions and definitions of data structures and * identifiers (typedef enum) used as API of the serialization PHY layer. * * \par Rationale * Each specific PHY layer (SPI, I2C, UART, low power UART etc.) should provide the same API. This - * allows the layer above (the HAL Transport layer) which is responsible for controlling the PHY - * layer, memory management, crc, retransmission etc. to be hardware independent. + * allows the layer above (the HAL Transport layer), which is responsible for controlling the PHY + * layer, memory management, crc, retransmission etc., to be hardware independent. * * * \par Interlayer communication and control @@ -32,51 +60,55 @@ * file. * The PHY layer communicates events to the HAL Transport layer by calling a callback function. * A handler to this function is passed in the @ref ser_phy_open function. This callback function - * should be called with parameter of type @ref ser_phy_evt_t filled accordingly to an event to be + * should be called with parameter of type @ref ser_phy_evt_t, filled accordingly to an event to be * passed. Types of supported events are defined in @ref ser_phy_evt_type_t. - * For example to pass an event indicating that RX packet has been successfully received first a + * For example, to pass an event indicating that RX packet has been successfully received, first a * struct of type @ref ser_phy_evt_t has to be filled: + * @code * ser_phy_evt_t phy_evt; * phy_evt.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; * phy_evt.evt_params.rx_pkt_received.p_buffer = (pointer to the RX buffer); * phy_evt.evt_params.rx_pkt_received.num_of_bytes = (number of received bytes); - * and then the callback function has to be called: + * @endcode + * , and then the callback function has to be called: + * @code * events_handler(phy_evt); - * All functions declared in this file are obligatory to implement. Some events specified in the + * @endcode + * All functions declared in this file are obligatory to implement. Some events specified in * @ref ser_phy_evt_type_t are optional to implement. * * \par Transmitting a packet * Each PHY layer is responsible for adding the PHY header to a packet to be sent. This header - * shall consists of 16-bit field carrying the packet length (the uint16_encode function defined in + * consists of a 16-bit field that carries the packet length (the uint16_encode function defined in * app_util.h should be used to ensure endianness independence). A pointer to a packet to be sent - * and a length of the packet are parameters of the @ref ser_phy_tx_pkt_send function. When a packet - * has been transmitted an event of type @ref SER_PHY_EVT_TX_PKT_SENT should be emitted. + * and length of the packet are parameters of the @ref ser_phy_tx_pkt_send function. When a packet + * has been transmitted, an event of type @ref SER_PHY_EVT_TX_PKT_SENT should be emitted. * - * \image html ser_phy_transport_tx.png "TX - interlayer communication" + * \image html ser_phy_transport_tx.svg "TX - interlayer communication" * * * \par Receiving a packet * The PHY layer should be able to store only the PHY header (16-bit field carrying the packet - * length). After the PHY header has been received the transmission shall be halted and the PHY - * layer has to sent a request to the HAL Transport layer for a memory to store a packet - an event + * length). After the PHY header has been received, the transmission is stopped and the PHY + * layer has to send a request to the HAL Transport layer for memory to store the packet - an event * of type @ref SER_PHY_EVT_RX_BUF_REQUEST with event parameters defined in * @ref ser_phy_evt_rx_buf_request_params_t (the uint16_decode function defined in app_util.h should * be used for header decoding to ensure endianness independence). The transmission should be - * resumed when @ref ser_phy_rx_buf_set function has been called. + * resumed when the @ref ser_phy_rx_buf_set function has been called. * - * When @ref ser_phy_rx_buf_set function parameter is equal to NULL it means that there is not - * enough memory to store the packet, however the packet shall be received to dummy location to - * ensure continuous communication. After receiving has finished an event of type - * @ref SER_PHY_EVT_RX_PKT_DROPPED shall be generated. + * When the @ref ser_phy_rx_buf_set function parameter equals NULL, it means that there is not + * enough memory to store the packet, however the packet will be received to dummy location to + * ensure continuous communication. After receiving has finished, an event of type + * @ref SER_PHY_EVT_RX_PKT_DROPPED is generated. * - * \image html ser_phy_transport_rx_dropped.png "RX dropping - interlayer communication" + * \image html ser_phy_transport_rx_dropped.svg "RX dropping - interlayer communication" * - * When @ref ser_phy_rx_buf_set function parameter is different from NULL the packet should be - * received to a buffer pointed by it. After receiving has finished an event of type - * @ref SER_PHY_EVT_RX_PKT_RECEIVED shall be generated with event parameters defined in + * When the @ref ser_phy_rx_buf_set function parameter is different than NULL, the packet is + * received to a buffer pointed by it. After receiving has finished, an event of type + * @ref SER_PHY_EVT_RX_PKT_RECEIVED is generated with event parameters defined in * @ref ser_phy_evt_rx_pkt_received_params_t. * - * \image html ser_phy_transport_rx_received.png "RX - interlayer communication" + * \image html ser_phy_transport_rx_received.svg "RX - interlayer communication" * * * \par PHY layer errors @@ -91,51 +123,55 @@ #include -/**@brief Serialization PHY module events types. */ +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Serialization PHY module event types. */ typedef enum { - SER_PHY_EVT_TX_PKT_SENT = 0, /**< Obligatory to implement. An event indicating that TX packet + SER_PHY_EVT_TX_PKT_SENT = 0, /**< Obligatory to implement. An event indicating that a TX packet * has been transmitted. */ - SER_PHY_EVT_RX_BUF_REQUEST, /**< Obligatory to implement. An event indicating that phy layer - * needs a buffer for RX packet. A PHY flow should be blocked - * until @ref ser_phy_rx_buf_set function is called. */ - SER_PHY_EVT_RX_PKT_RECEIVED, /**< Obligatory to implement. An event indicating that RX packet + SER_PHY_EVT_RX_BUF_REQUEST, /**< Obligatory to implement. An event indicating that the PHY layer + * needs a buffer for an RX packet. The PHY flow should be blocked + * until the @ref ser_phy_rx_buf_set function is called. */ + SER_PHY_EVT_RX_PKT_RECEIVED, /**< Obligatory to implement. An event indicating that an RX packet * has been successfully received. */ - SER_PHY_EVT_RX_PKT_DROPPED, /**< Obligatory to implement. An event indicating that RX packet - * receiving has been finished but packet was discarded because - * it was longer than available buffer. */ + SER_PHY_EVT_RX_PKT_DROPPED, /**< Obligatory to implement. An event indicating that the RX packet + * receiving has been finished but the packet was discarded because + * it was longer than available the buffer. */ SER_PHY_EVT_RX_OVERFLOW_ERROR, /**< Optional to implement. An event indicating that more - * information has been transmitted than phy module could + * information has been transmitted than the PHY module could * handle. */ - SER_PHY_EVT_TX_OVERREAD_ERROR, /**< Optional to implement. An event indicating that phy module + SER_PHY_EVT_TX_OVERREAD_ERROR, /**< Optional to implement. An event indicating that the PHY module * was forced to transmit more information than possessed. */ SER_PHY_EVT_HW_ERROR, /**< Optional to implement. An event indicating a hardware error - * in phy module. */ + * in the PHY module. */ SER_PHY_EVT_TYPE_MAX /**< Enumeration upper bound. */ } ser_phy_evt_type_t; -/**@brief A struct containing parameters of the event of type @ref SER_PHY_EVT_RX_BUF_REQUEST. */ +/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_RX_BUF_REQUEST. */ typedef struct { - uint16_t num_of_bytes; /**< Length of a buffer in octets that layer above PHY module should - * deliver to enable PHY module to receive packet. */ + uint16_t num_of_bytes; /**< Length of a buffer in octets that the layer above the PHY module should + * deliver, so that the PHY module can receive a packet. */ } ser_phy_evt_rx_buf_request_params_t; -/**@brief A struct containing parameters of the event of type @ref SER_PHY_EVT_RX_PKT_RECEIVED. */ +/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_RX_PKT_RECEIVED. */ typedef struct { - uint8_t * p_buffer; /**< Pointer to a buffer containing received packet. */ - uint16_t num_of_bytes; /**< Length of a received packet in octets. */ + uint8_t * p_buffer; /**< Pointer to a buffer containing the received packet. */ + uint16_t num_of_bytes; /**< Length of the received packet in octets. */ } ser_phy_evt_rx_pkt_received_params_t; -/**@brief A struct containing parameters of the event of type @ref SER_PHY_EVT_HW_ERROR. */ +/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_HW_ERROR. */ typedef struct { - uint32_t error_code; /**< Hardware error code - specific for any microcontroller. */ + uint32_t error_code; /**< Hardware error code - specific for a microcontroller. */ uint8_t * p_buffer; /**< Pointer to the buffer that was processed when error occured. */ } ser_phy_evt_hw_error_params_t; @@ -144,15 +180,15 @@ typedef struct * * @note Some events do not have parameters, then whole information is contained in the evt_type. */ -typedef struct +typedef struct { - ser_phy_evt_type_t evt_type; /**< Type of an event. */ + ser_phy_evt_type_t evt_type; /**< Type of event. */ union /**< Union alternative identified by evt_type in enclosing struct. */ { - /** Parameters of the event of type @ref SER_PHY_EVT_RX_BUF_REQUEST. */ + /** Parameters of event of type @ref SER_PHY_EVT_RX_BUF_REQUEST. */ ser_phy_evt_rx_buf_request_params_t rx_buf_request; - /** Parameters of the event of type @ref SER_PHY_EVT_RX_PKT_RECEIVED. */ + /** Parameters of event of type @ref SER_PHY_EVT_RX_PKT_RECEIVED. */ ser_phy_evt_rx_pkt_received_params_t rx_pkt_received; /** Parameters of the event of type @ref SER_PHY_EVT_HW_ERROR. */ ser_phy_evt_hw_error_params_t hw_error; @@ -167,7 +203,7 @@ typedef struct typedef void (*ser_phy_events_handler_t)(ser_phy_evt_t event); -/**@brief A function for opening and initializing a PHY module. +/**@brief Function for opening and initializing the PHY module. * * @note The function initializes hardware and internal module states, and registers callback * function to be used by all PHY module events. @@ -180,8 +216,8 @@ typedef void (*ser_phy_events_handler_t)(ser_phy_evt_t event); * * @retval NRF_SUCCESS Operation success. * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. - * To call it again the function @ref ser_phy_close has to be - * called previously. + * To call it again, the function @ref ser_phy_close has to be + * called first. * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. * @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters are not * supported. @@ -189,10 +225,10 @@ typedef void (*ser_phy_events_handler_t)(ser_phy_evt_t event); uint32_t ser_phy_open(ser_phy_events_handler_t events_handler); -/**@brief A function for transmitting a packet. +/**@brief Function for transmitting a packet. * * @note The function adds a packet pointed by p_buffer parameter to a transmission queue and - * schedules generating an event of type @ref SER_PHY_EVT_TX_PKT_SENT upon transmission + * schedules generation of an event of type @ref SER_PHY_EVT_TX_PKT_SENT upon transmission * completion. * * @param[in] p_buffer Pointer to a buffer to transmit. @@ -207,22 +243,22 @@ uint32_t ser_phy_open(ser_phy_events_handler_t events_handler); uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes); -/**@brief A function for setting an RX buffer and enabling reception of data (the PHY flow). +/**@brief Function for setting an RX buffer and enabling reception of data (the PHY flow). * * @note The function has to be called as a response to an event of type * @ref SER_PHY_EVT_RX_BUF_REQUEST. The function sets an RX buffer and enables reception of * data (enables the PHY flow). * Size of a buffer pointed by the p_buffer parameter should be at least equal to the - * num_of_bytes parameter passed within the event (@ref ser_phy_evt_rx_buf_request_params_t) + * num_of_bytes parameter passed within the event (@ref ser_phy_evt_rx_buf_request_params_t), * or p_buffer should be equal to NULL if there is not enough memory. - * When p_buffer is different from NULL and num_of_bytes octets has been received an event of + * When p_buffer is different from NULL and num_of_bytes octets have been received, an event of * type @ref SER_PHY_EVT_RX_PKT_RECEIVED is generated * (@ref ser_phy_evt_rx_pkt_received_params_t). - * When p_buffer is equal to NULL data are received to dummy location to ensure continuous - * communication. Then if num_of_bytes octets has been received an event of type + * When p_buffer is equal to NULL, data is received to dummy location to ensure continuous + * communication. Then, if num_of_bytes octets have been received, an event of type * @ref SER_PHY_EVT_RX_PKT_DROPPED is generated. * - * @param[in] p_buffer Pointer to an RX buffer where to receive. + * @param[in] p_buffer Pointer to an RX buffer in which to receive. * * @retval NRF_SUCCESS Operation success. * @retval NRF_ERROR_INVALID_STATE Operation failure. A buffer was set without request. @@ -230,27 +266,32 @@ uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes); uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer); -/**@brief A function for closing a PHY module. +/**@brief Function for closing the PHY module. * - * @note The function disables hardware, resets internal module states and unregisters events + * @note The function disables hardware, resets internal module states, and unregisters the events * callback function. */ void ser_phy_close(void); -/**@brief A function for enabling a PHY module interrupts. +/**@brief Function for enabling the PHY module interrupts. * - * @note The function enables all interrupts that are used by a PHY module (and only those). + * @note The function enables all interrupts that are used by the PHY module (and only those). */ void ser_phy_interrupts_enable(void); -/**@brief A function for disabling a PHY module interrupts. +/**@brief Function for disabling the PHY module interrupts. * - * @note The function disables all interrupts that are used by a PHY module (and only those). + * @note The function disables all interrupts that are used by the PHY module (and only those). */ void ser_phy_interrupts_disable(void); + +#ifdef __cplusplus +} +#endif + #endif /* SER_PHY_H__ */ /** @} */ diff --git a/components/serialization/common/transport/ser_phy/ser_phy_hci.c b/components/serialization/common/transport/ser_phy/ser_phy_hci.c index e675e16..d75aa30 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy_hci.c +++ b/components/serialization/common/transport/ser_phy/ser_phy_hci.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include @@ -17,13 +45,15 @@ #include "app_util.h" #include "app_util_platform.h" #include "app_timer.h" -#include "app_mailbox.h" +#include "nrf_queue.h" #include "ser_phy.h" #include "ser_phy_hci.h" #include "crc16.h" #include "nrf_soc.h" #include "ser_config.h" #include "ser_phy_debug_comm.h" +#define NRF_LOG_MODULE_NAME "SPHY_HCI" +#include "nrf_log.h" // hide globals for release version, expose for debug version #if defined(SER_PHY_HCI_DEBUG_ENABLE) #define _static @@ -59,6 +89,7 @@ #define HCI_PKT_SYNC_SIZE 6u /**< Size of SYNC and SYNC_RSP packet */ #define HCI_PKT_CONFIG_SIZE 7u /**< Size of CONFIG and CONFIG_RSP packet */ #define HCI_LINK_CONTROL_PKT_INVALID 0xFFFFu /**< Size of CONFIG and CONFIG_RSP packet */ +#define HCI_LINK_CONTROL_TIMEOUT 1u /**< Default link control timeout. */ #endif /* HCI_LINK_CONTROL */ #ifndef APP_TIMER_PRESCALER @@ -175,9 +206,15 @@ _static uint32_t m_tx_retry_count; // _static uint32_t m_tx_retx_counter = 0; // _static uint32_t m_rx_drop_counter = 0; +NRF_QUEUE_DEF(hci_evt_t, + m_tx_evt_queue, + TX_EVT_QUEUE_SIZE, + NRF_QUEUE_MODE_NO_OVERFLOW); -APP_MAILBOX_DEF(tx_evt_queue, TX_EVT_QUEUE_SIZE, sizeof(hci_evt_t)); -APP_MAILBOX_DEF(rx_evt_queue, RX_EVT_QUEUE_SIZE, sizeof(hci_evt_t)); +NRF_QUEUE_DEF(hci_evt_t, + m_rx_evt_queue, + RX_EVT_QUEUE_SIZE, + NRF_QUEUE_MODE_NO_OVERFLOW); _static hci_tx_fsm_state_t m_hci_tx_fsm_state = HCI_TX_STATE_DISABLE; _static hci_rx_fsm_state_t m_hci_rx_fsm_state = HCI_RX_STATE_DISABLE; @@ -229,7 +266,7 @@ static void hci_signal_timeout_event(void) hci_tx_event_handler(&event); #else hci_link_control_event_handler(&event); - if((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active) + if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active) { hci_tx_event_handler(&event); } @@ -714,6 +751,8 @@ static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event) if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT ) { + NRF_LOG_DEBUG("EVT_PKT_SENT\r\n"); + DEBUG_EVT_SLIP_PACKET_TXED(0); event.evt_source = HCI_SLIP_EVT; event.evt.ser_phy_slip_evt.evt_type = p_event->evt_type; @@ -728,6 +767,8 @@ static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event) } else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT ) { + NRF_LOG_DEBUG("EVT_ACK_SENT\r\n"); + DEBUG_EVT_SLIP_ACK_TXED(0); event.evt_source = HCI_SLIP_EVT; event.evt.ser_phy_slip_evt.evt_type = p_event->evt_type; @@ -755,6 +796,9 @@ static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event) event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer, event.evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes); + NRF_LOG_DEBUG("EVT_PKT_RECEIVED 0x%X/%u\r\n", packet_type, + p_event->evt_params.received_pkt.num_of_bytes); + if (packet_type == PKT_TYPE_ACK ) { DEBUG_EVT_SLIP_ACK_RXED(0); @@ -816,7 +860,10 @@ static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event) DEBUG_EVT_SLIP_ERR_RXED(0); } } - + else + { + NRF_LOG_DEBUG("EVT_HW_ERROR\r\n"); + } } @@ -1180,7 +1227,7 @@ static void hci_tx_fsm(void) { CRITICAL_REGION_ENTER(); - err_code = app_mailbox_get(&tx_evt_queue, &event); + err_code = nrf_queue_pop(&m_tx_evt_queue, &event); if (err_code != NRF_SUCCESS) { @@ -1206,7 +1253,7 @@ static void hci_rx_fsm(void) while (err_code == NRF_SUCCESS) { CRITICAL_REGION_ENTER(); - err_code = app_mailbox_get(&rx_evt_queue, &event); + err_code = nrf_queue_pop(&m_rx_evt_queue, &event); if (err_code != NRF_SUCCESS) { @@ -1230,7 +1277,7 @@ static void hci_tx_reschedule() uint32_t tx_queue_length; CRITICAL_REGION_ENTER(); - tx_queue_length = app_mailbox_length_get(&tx_evt_queue); + tx_queue_length = nrf_queue_utilization_get(&m_tx_evt_queue); #ifndef HCI_LINK_CONTROL if (m_tx_fsm_idle_flag && m_hci_global_enable_flag && tx_queue_length) @@ -1259,7 +1306,7 @@ static void hci_tx_event_handler(hci_evt_t * p_event) uint32_t err_code; CRITICAL_REGION_ENTER(); - err_code = app_mailbox_put(&tx_evt_queue, p_event); + err_code = nrf_queue_push(&m_tx_evt_queue, p_event); ser_phy_hci_assert(err_code == NRF_SUCCESS); // CRITICAL_REGION_ENTER(); @@ -1286,7 +1333,7 @@ static void hci_rx_reschedule() uint32_t rx_queue_length; CRITICAL_REGION_ENTER(); - rx_queue_length = app_mailbox_length_get(&rx_evt_queue); + rx_queue_length = nrf_queue_utilization_get(&m_rx_evt_queue); #ifndef HCI_LINK_CONTROL if (m_rx_fsm_idle_flag && m_hci_global_enable_flag && rx_queue_length) @@ -1315,7 +1362,7 @@ static void hci_rx_event_handler(hci_evt_t * p_event) uint32_t err_code; CRITICAL_REGION_ENTER(); - err_code = app_mailbox_put(&rx_evt_queue, p_event); + err_code = nrf_queue_push(&m_rx_evt_queue, p_event); ser_phy_hci_assert(err_code == NRF_SUCCESS); /* only one process can acquire rx_exec_flag */ @@ -1338,13 +1385,13 @@ static void hci_rx_event_handler(hci_evt_t * p_event) #ifdef HCI_LINK_CONTROL /* Link control event handler - used only for Link Control packets */ /* This handler will be called only in 2 cases: - - when SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED event is received + - when SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED event is received - when HCI_TIMER_EVT event is reveived */ static void hci_link_control_event_handler(hci_evt_t * p_event) { uint16_t pkt_type = HCI_LINK_CONTROL_PKT_INVALID; - switch(p_event->evt_source) + switch (p_event->evt_source) { case HCI_SLIP_EVT: pkt_type = link_control_packet_decode( @@ -1367,7 +1414,7 @@ static void hci_link_control_event_handler(hci_evt_t * p_event) m_hci_other_side_active = false; } hci_link_control_pkt_send(); - hci_timeout_setup(7u); // Need to trigger transmitting SYNC messages + hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT); // Need to trigger transmitting SYNC messages break; case HCI_PKT_SYNC_RSP: if (m_hci_mode == HCI_MODE_UNINITIALIZED) @@ -1389,7 +1436,7 @@ static void hci_link_control_event_handler(hci_evt_t * p_event) { m_hci_mode = HCI_MODE_ACTIVE; m_hci_tx_fsm_state = HCI_TX_STATE_SEND; - m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE; + m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE; } break; } @@ -1413,12 +1460,12 @@ static void hci_link_control_event_handler(hci_evt_t * p_event) //send packet m_hci_link_control_next_pkt = HCI_PKT_SYNC; hci_link_control_pkt_send(); - hci_timeout_setup(7u); + hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT); break; case HCI_MODE_INITIALIZED: m_hci_link_control_next_pkt = HCI_PKT_CONFIG; hci_link_control_pkt_send(); - hci_timeout_setup(7u); + hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT); break; case HCI_MODE_ACTIVE: case HCI_MODE_DISABLE: @@ -1551,7 +1598,7 @@ static uint32_t hci_timer_init(void) // Configure TIMER for compare[1] event HCI_TIMER->PRESCALER = 9; HCI_TIMER->MODE = TIMER_MODE_MODE_Timer; - HCI_TIMER->BITMODE = TIMER_BITMODE_BITMODE_32Bit; + HCI_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit; // Clear TIMER HCI_TIMER->TASKS_CLEAR = 1; @@ -1593,19 +1640,8 @@ uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) return NRF_ERROR_INTERNAL; } - err_code = app_mailbox_create(&tx_evt_queue); - - if (err_code != NRF_SUCCESS) - { - return NRF_ERROR_INTERNAL; - } - - err_code = app_mailbox_create(&rx_evt_queue); - - if (err_code != NRF_SUCCESS) - { - return NRF_ERROR_INTERNAL; - } + nrf_queue_reset(&m_tx_evt_queue); + nrf_queue_reset(&m_rx_evt_queue); err_code = ser_phy_hci_slip_open(hci_slip_event_handler); @@ -1624,7 +1660,7 @@ uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) m_hci_tx_fsm_state = HCI_TX_STATE_SEND; m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE; #else - hci_timeout_setup(7u);// Trigger sending SYNC messages + hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT);// Trigger sending SYNC messages m_hci_mode = HCI_MODE_UNINITIALIZED; m_hci_other_side_active = false; #endif /*HCI_LINK_CONTROL*/ diff --git a/components/serialization/common/transport/ser_phy/ser_phy_hci.h b/components/serialization/common/transport/ser_phy/ser_phy_hci.h index fda7d8a..58f3046 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy_hci.h +++ b/components/serialization/common/transport/ser_phy/ser_phy_hci.h @@ -1,13 +1,41 @@ - /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -16,7 +44,7 @@ * @{ * @ingroup ble_sdk_lib_serialization * - * @brief HCI PHY layer for serialization. + * @brief @tagAPI52832 HCI PHY layer for serialization. * * @details This file contains declarations of functions and definitions of data structures and * identifiers (typedef enum) used as API of the serialization HCI PHY layer. @@ -29,17 +57,21 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Serialization PHY HCI module events types. */ typedef enum { SER_PHY_HCI_SLIP_EVT_PKT_SENT = 0, /**< An event indicating that packet has been transmitted. */ - SER_PHY_HCI_SLIP_EVT_ACK_SENT, /**< An event indicating that ack packet has been transmitted. */ + SER_PHY_HCI_SLIP_EVT_ACK_SENT, /**< An event indicating that ack packet has been transmitted. */ SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED, /**< An event indicating that packet has been received. */ SER_PHY_HCI_SLIP_EVT_HW_ERROR, /**< An event indicating a hardware error in PHY HCI module. */ SER_PHY_HCI_SLIP_EVT_TYPE_MAX /**< Enumeration upper bound. */ } ser_phy_hci_slip_evt_type_t; -/**@brief A struct representing a PHY HCI packet. */ +/**@brief Struct representing a PHY HCI packet. */ typedef struct { uint8_t * p_buffer; /**< Pointer to a buffer containing a packet. */ @@ -47,39 +79,39 @@ typedef struct } ser_phy_hci_pkt_params_t; -/**@brief A struct containing parameters of the event of type @ref SER_PHY_HCI_SLIP_EVT_HW_ERROR. */ +/**@brief Struct containing parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_HW_ERROR. */ typedef struct { - uint32_t error_code; /**< Hardware error code - specific for any microcontroller. */ + uint32_t error_code; /**< Hardware error code - specific for a microcontroller. */ } ser_phy_hci_evt_hw_error_params_t; -/**@brief A struct containing events from a Serialization PHY module. +/**@brief Struct containing events from the Serialization PHY module. * - * @note Some events do not have parameters, then whole information is contained in the evt_type. + * @note Some events do not have parameters, then the whole information is contained in the evt_type. */ -typedef struct +typedef struct { ser_phy_hci_slip_evt_type_t evt_type; /**< Type of an event. */ - union /**< Union alternative identified by evt_type in enclosing struct. */ + union /**< Union alternative identified by evt_type in the enclosing struct. */ { - /** Parameters of the event of type @ref SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED. */ + /** Parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED. */ ser_phy_hci_pkt_params_t received_pkt; - /** Parameters of the event of type @ref SER_PHY_HCI_SLIP_EVT_HW_ERROR. */ + /** Parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_HW_ERROR. */ ser_phy_hci_evt_hw_error_params_t hw_error; } evt_params; } ser_phy_hci_slip_evt_t; -/**@brief A type of generic callback function handler to be used by all PHY HCI events. +/**@brief Type of generic callback function handler to be used by all PHY HCI events. * * @param[in] event Serialization PHY HCI module event. */ typedef void (*ser_phy_hci_slip_event_handler_t)(ser_phy_hci_slip_evt_t *p_event); -/**@brief A function for opening and initializing a HCI SLIP PHY module. +/**@brief Function for opening and initializing a HCI SLIP PHY module. * - * @note The function initializes hardware and internal module states, and registers callback + * @note The function initializes hardware and internal module states and registers callback * function to be used by all PHY HCI module events. * * @warning If the function has been already called, the function @ref ser_phy_hci_slip_close has to be @@ -90,8 +122,8 @@ typedef void (*ser_phy_hci_slip_event_handler_t)(ser_phy_hci_slip_evt_t *p_event * * @retval NRF_SUCCESS Operation success. * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. - * To call it again the function @ref ser_phy_hci_slip_close has to - * be called previously. + * To call it again, the function @ref ser_phy_hci_slip_close has to + * be called first. * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. * @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters are not * supported. @@ -102,7 +134,7 @@ uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler); /**@brief A function for transmitting a HCI SLIP packet. * * @note The function adds a packet pointed by p_buffer parameter to a transmission queue and - * schedules generating an event of type @ref SER_PHY_HCI_SLIP_EVT_PKT_SENT upon transmission + * schedules generation of an event of type @ref SER_PHY_HCI_SLIP_EVT_PKT_SENT upon transmission * completion. * * @param[in] p_header Pointer to ser_phy_hci_pkt_params_t structure representing packet header. @@ -110,10 +142,10 @@ uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler); * @param[in] p_crc Pointer to ser_phy_hci_pkt_params_t structure representing packet crc. * * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue - * and event will be send upon transmission completion. + * and event will be sent upon transmission completion. * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied in p_header parameter. * NULL pointer is allowed for p_payload and p_crc parameters. - * @retval NRF_ERROR_INVALID_PARAM Operation failure. Number of bytes to be send equal to 0. + * @retval NRF_ERROR_INVALID_PARAM Operation failure. Number of bytes to be sent equals 0. * @retval NRF_ERROR_BUSY Operation failure. Transmitting of a packet in progress. */ uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header, @@ -123,8 +155,8 @@ uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header, /**@brief A function for freeing an RX buffer. * - * @note The function has to be called as a response for event @ref SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED - * when RX packet has been processed. The function frees the RX buffer and therefore enables + * @note The function has to be called as a response to event @ref SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED + * when an RX packet has been processed. The function frees the RX buffer and therefore enables * reception of next incoming data. * @param[in] p_buffer Pointer to an RX buffer which must be freed. @@ -138,10 +170,15 @@ uint32_t ser_phy_hci_slip_rx_buf_free(uint8_t * p_buffer); /**@brief A function for closing a PHY HCI module. * - * @note The function disables hardware, resets internal module states and unregisters events + * @note The function disables hardware, resets internal module states, and unregisters the events * callback function. */ void ser_phy_hci_slip_close(void); + +#ifdef __cplusplus +} +#endif + #endif /* SER_PHY_HCI_H__ */ /** @} */ diff --git a/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c b/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c index 7e8431a..e8bcada 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c +++ b/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c @@ -1,36 +1,41 @@ - -/* Copyright (c) Nordic Semiconductor ASA +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include @@ -46,9 +51,9 @@ #include "nrf_soc.h" #ifdef SER_CONNECTIVITY -#include "ser_phy_config_conn_nrf51.h" +#include "ser_phy_config_conn.h" #else -#include "ser_phy_config_app_nrf51.h" +#include "ser_phy_config_app.h" #endif /* SER_CONNECTIVITY */ #include "ser_config.h" diff --git a/components/serialization/common/transport/ser_phy/ser_phy_nohci.c b/components/serialization/common/transport/ser_phy/ser_phy_nohci.c index 2aac44c..cc28253 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy_nohci.c +++ b/components/serialization/common/transport/ser_phy/ser_phy_nohci.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -26,7 +54,6 @@ #include "app_util.h" #include "app_util_platform.h" #include "app_timer.h" -#include "app_mailbox.h" #include "ser_phy.h" #include "ser_phy_hci.h" #include "crc16.h" diff --git a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_app.c b/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_app.c deleted file mode 100644 index 55cbbfe..0000000 --- a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_app.c +++ /dev/null @@ -1,754 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by STMicroelectronics that - * is used in combination with a processor manufactured by Nordic Semiconductor - * or in a processor manufactured by STMicroelectronics. - * - * - * 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 HOLDER 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. - */ - - -#include -#include - -#include "nordic_common.h" -#include "boards.h" -#include "nrf.h" -#include "nrf_error.h" -#include "nrf_gpio.h" -#include "nrf_delay.h" -#include "nrf_gpiote.h" -#include "app_gpiote.h" -#include "app_util.h" -#include "app_util_platform.h" - -#include "ser_phy.h" -#include "ser_phy_config_app_nrf51.h" - -#define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */ - -/** @brief States for the app_uart state machine. */ -typedef enum -{ - UART_IDLE, /**< Indicating that the current status for either RX or TX is idle. When both RX and TX is idle the UART will be disabled in order to save power. */ - UART_RX, /**< Used to indicate that a packet is currently being received on RX. */ - UART_RX_PENDING, /**< Used to indicate that byte is ready at RXD register but no buffer was available when the byte was received. The byte will be pulled when a buffer is set. */ - UART_TX_COMPLETE, /**< Used on TX to indicate that final byte has been put on TXD register. Next TXDRDY interrupt will indicate that last byte has been transmitted. */ - UART_TX_SEND, /**< Used to indicate that a packet is currently being transmitted on TX. */ - UART_TX_LAST_BYTE_WAIT, /**< Used to indicate that the last byte on a TX packet is currently waiting to be transmitted when CTS goes low. Note that flow control is off when tranmitting final byte. */ - UART_STALL, /**< Indicates that TX is stalled because final byte is being received on the UART. */ -} uart_states_t; - -static volatile uint32_t m_pin_cts_mask; /**< CTS pin mask for UART module. */ - -static volatile uint8_t * mp_tx_stream; /**< Pointer to array of data packet to be transmitted. */ -static volatile uint16_t m_tx_stream_length; /**< Total length of data packet to be transmitted. */ -static volatile uint16_t m_tx_stream_index; /**< Index in data packet for next byte to be transmitted. */ -static uint8_t m_tx_length_buf[SER_PHY_HEADER_SIZE]; /**< Buffer needed in transmission of packet length */ - -static uint8_t * mp_rx_stream; /**< Pointer to current receive buffer. */ -static volatile uint16_t m_rx_stream_length; /**< Length of receive buffer. */ -static volatile uint16_t m_rx_stream_index; /**< Index in receive buffer where the next byte will be placed. */ -static volatile bool m_rx_stream_header; /**< Indication of whether header data (true) or payload data (false) is currently being received. */ -static uint8_t m_rx_length_buf[SER_PHY_HEADER_SIZE]; /**< Buffer needed in reception of packet length */ -static uint8_t m_rx_drop_buf[1]; /**< Additional buffer, needed by packet dropping functionality. */ - -static volatile uart_states_t m_rx_state = UART_IDLE; /**< State of the RX state machine. */ -static volatile uart_states_t m_tx_state = UART_IDLE; /**< State of the TX state machine. */ -static volatile bool m_tx_pending = false; /**< If TX state is UART_STALL and a byte is ready for tranmission the pending flag is set to true. */ -static volatile bool m_cts_high_disconnect = false; /**< If CTS was sampled low when last byte was transmitted this flag is set to true to indicate that a switch from low->high on CTS should be interpreted as transmission has completed and UART is to be disabled to save power. */ - -static volatile ser_phy_events_handler_t m_ser_phy_event_handler; -static volatile ser_phy_evt_t m_ser_phy_event_rx; -static volatile ser_phy_evt_t m_ser_phy_event_tx; - - -static void uart_peripheral_disconnect_flow(void) -{ - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->CONFIG &= ~(UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); -} - - -static void uart_peripheral_connect_flow(void) -{ - NRF_UART0->PSELCTS = SER_PHY_UART_CTS; - NRF_UART0->PSELRTS = SER_PHY_UART_RTS; - NRF_UART0->CONFIG |= (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); -} - - -static void uart_peripheral_enable(void) -{ - if (!(NRF_UART0->ENABLE & (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos))) - { - NRF_UART0->PSELCTS = SER_PHY_UART_CTS; - NRF_UART0->PSELRTS = SER_PHY_UART_RTS; - NRF_UART0->CONFIG |= (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - NRF_UART0->TASKS_STARTRX = 1; - NRF_UART0->TASKS_STARTTX = 1; - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos); - } -} - - -static void uart_peripheral_disable(void) -{ - if ((m_tx_state == UART_IDLE || m_tx_state == UART_STALL) && - (m_rx_state == UART_IDLE)) - { - NRF_UART0->TASKS_STOPTX = 1; - NRF_UART0->TASKS_STOPRX = 1; - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos); - - nrf_gpio_cfg_input(SER_PHY_UART_RTS, NRF_GPIO_PIN_NOPULL); - - nrf_gpiote_event_configure(0, SER_PHY_UART_CTS, NRF_GPIOTE_POLARITY_TOGGLE); - - if (!nrf_gpio_pin_read(SER_PHY_UART_CTS)) - { - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - uart_peripheral_enable(); - } - } -} - - -static void uart_tx_start(void) -{ - if (mp_tx_stream != NULL) - { - //If RX is already ongoing then no wakeup signal is required. - if (m_rx_state == UART_IDLE) - { - nrf_gpiote_event_disable(0); - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - uart_peripheral_connect_flow(); - uart_peripheral_enable(); - } - } -} - - -static void uart_tx_send(void) -{ - //First send 2 bytes of header then payload - if (m_tx_stream_index < SER_PHY_HEADER_SIZE) - { - NRF_UART0->TXD = m_tx_length_buf[m_tx_stream_index++]; - } - else if (m_tx_stream_index < m_tx_stream_length) - { - NRF_UART0->TXD = mp_tx_stream[m_tx_stream_index++ - SER_PHY_HEADER_SIZE]; - } -} - - -static void uart_tx_last_byte(void) -{ - uart_peripheral_disconnect_flow(); - m_tx_state = UART_TX_LAST_BYTE_WAIT; - - //Configure event in case CTS is going low during this function execution - nrf_gpiote_event_configure(0, SER_PHY_UART_CTS, NRF_GPIOTE_POLARITY_TOGGLE); - - if (!nrf_gpio_pin_read(SER_PHY_UART_CTS)) //All pins are low --> last byte can be transmitted. - { - //Re-check state as it might have changed due to preemption of current interrupt. - nrf_gpiote_event_disable(0); - - if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - m_tx_state = UART_TX_COMPLETE; - uart_tx_send(); - } - } -} - - -static void tx_complete_event_send(void) -{ - mp_tx_stream = NULL; - m_tx_stream_length = 0; - m_tx_stream_index = 0; - - m_ser_phy_event_tx.evt_type = SER_PHY_EVT_TX_PKT_SENT; - m_ser_phy_event_handler(m_ser_phy_event_tx); -} - - -static void uart_txdrdy_handle(void) -{ - NRF_UART0->EVENTS_TXDRDY = 0; - - if (m_tx_state == UART_TX_SEND || m_tx_state == UART_IDLE) - { - if (m_tx_stream_index < (m_tx_stream_length - 1)) - { - m_tx_state = UART_TX_SEND; - uart_tx_send(); - //Keep same state. - } - else if (m_tx_stream_index == m_tx_stream_length) - { - m_tx_state = UART_IDLE; - tx_complete_event_send(); - } - else - { - uart_tx_last_byte(); - } - } - else if (m_tx_state == UART_TX_COMPLETE) - { - m_tx_state = UART_IDLE; - - if (m_rx_state == UART_IDLE) - { - nrf_delay_us(15); - nrf_gpiote_event_configure(0, SER_PHY_UART_CTS, NRF_GPIOTE_POLARITY_TOGGLE); - - if (nrf_gpio_pin_read(SER_PHY_UART_CTS)) - { - uart_peripheral_disable(); - } - else - { - uart_peripheral_connect_flow(); - m_cts_high_disconnect = true; - nrf_gpiote_event_configure(0, SER_PHY_UART_CTS, NRF_GPIOTE_POLARITY_TOGGLE); - - if (nrf_gpio_pin_read(SER_PHY_UART_CTS)) - { - //If second sample show CTS high it either - //1) happened BEFORE gpiote enable and uart should be disabled. - //(m_cts_high_disconnect == true). - //2) happened AFTER gpiote enable and an interrupt low->high has occured then - //uart should NOT be disabled as the ISR has disabled the UART. - //(m_cts_high_disconnect == false). - if (m_cts_high_disconnect == true) - { - m_cts_high_disconnect = false; - uart_peripheral_disable(); - } - } - } - } - else - { - uart_peripheral_connect_flow(); - } - - tx_complete_event_send(); - } - else if (m_tx_state == UART_STALL) - { - if (m_tx_stream_index == m_tx_stream_length) - { - tx_complete_event_send(); - } - else - { - m_tx_pending = true; - } - } - else - { - //Do nothing. - } -} - - -static __INLINE void on_cts_high(void) -{ - if (m_cts_high_disconnect == true) - { - m_cts_high_disconnect = false; - - if (m_rx_state == UART_IDLE && m_tx_state == UART_IDLE) - { - if (m_tx_stream_index == m_tx_stream_length) - { - uart_peripheral_disable(); - } - } - } -} - - -static __INLINE void on_cts_low(void) -{ - m_cts_high_disconnect = false; - nrf_gpiote_event_disable(0); - - if (m_tx_state == UART_STALL) - { - m_tx_pending = true; - } - else if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - m_tx_state = UART_TX_COMPLETE; - uart_tx_send(); - } - else if (m_rx_state == UART_IDLE && m_tx_state == UART_IDLE) - { - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - uart_peripheral_enable(); - } -} - - -static void uart_rxdrdy_handle(void) -{ - if (m_rx_state == UART_IDLE) - { - m_rx_state = UART_RX; - } - - //Set proper size and buff at the beginning of receiving header - if ((m_rx_stream_header == true) && !m_rx_stream_index) - { - m_rx_stream_length = SER_PHY_HEADER_SIZE; - mp_rx_stream = m_rx_length_buf; - } - - if (mp_rx_stream != NULL) - { - bool tx_dual_end = false; - - NRF_UART0->EVENTS_RXDRDY = 0; - - //Second last byte received. - //Disconnect CTS before pulling the byte and receiving the final byte. - if ((m_rx_stream_header == false) && ((m_rx_stream_index) == (m_rx_stream_length - 2))) - { - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - - //Last byte is waiting for tansmission. Thus dual end TX case. - // - if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - m_tx_state = UART_STALL; - nrf_gpiote_event_disable(0); - - //Checking pending state. - //- If pending is true then CTS have become low after we stalled the UART and final byte should be transmitted here. - //- If pending is false we should check if final byte was tranmitted and if not, the do the transmission her. - if ((m_tx_pending == true) || (m_tx_stream_index == (m_tx_stream_length - 1))) - { - //tx_dual_end = true; - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - uart_tx_send(); - } - } - - if (!tx_dual_end) - { - NRF_GPIO->OUTCLR = 1 << SER_PHY_UART_RTS; - } - m_tx_state = UART_STALL; - - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->CONFIG &= ~(UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - } - - if (m_rx_stream_index < (m_rx_stream_length - 1)) - { - if (mp_rx_stream != m_rx_drop_buf) - { - mp_rx_stream[m_rx_stream_index++] = NRF_UART0->RXD; - } - else - { - mp_rx_stream[0] = NRF_UART0->RXD; - m_rx_stream_index++; - } - - if (m_tx_stream_index == (m_tx_stream_length - 1)) - { - //Toggle CTS line to indicate ack. - //If CTS is connected to UART this code will have no effect. - //But on edge case on bi-directional last byte transfer this avoids lock-up. - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_delay_us(8); - NRF_GPIO->OUTCLR = 1 << SER_PHY_UART_RTS; - } - } - else - { - if (m_rx_stream_header == false) - { - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - - if (mp_rx_stream != m_rx_drop_buf) - { - mp_rx_stream[m_rx_stream_index++] = NRF_UART0->RXD; - } - else - { - mp_rx_stream[0] = NRF_UART0->RXD; - m_rx_stream_index++; - } - m_rx_state = UART_IDLE; - - //Last byte of payload received - notify that next transmission will be header - m_rx_stream_header = true; - - //Prepare event - if (mp_rx_stream != m_rx_drop_buf) - { - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; - m_ser_phy_event_rx.evt_params.rx_pkt_received.num_of_bytes = m_rx_stream_index; - m_ser_phy_event_rx.evt_params.rx_pkt_received.p_buffer = mp_rx_stream; - } - else - { - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; - } - - m_rx_stream_length = 0; - m_rx_stream_index = 0; - } - else - { - mp_rx_stream[m_rx_stream_index++] = NRF_UART0->RXD; - - //Last byte of header received - notify that next transmission will be payload - m_rx_stream_header = false; - - mp_rx_stream = NULL; - - //Clear index before receiving payload - m_rx_stream_index = 0; - - //Prepare event - m_rx_stream_length = uint16_decode(m_rx_length_buf); - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; - m_ser_phy_event_rx.evt_params.rx_buf_request.num_of_bytes = m_rx_stream_length; - } - - //Notify upwards - m_ser_phy_event_handler(m_ser_phy_event_rx); - - //UART TX was stalled while receiving final byte. Restart tx. - if (m_tx_state == UART_STALL) - { - if (m_tx_stream_length == m_tx_stream_index) - { - m_tx_state = UART_IDLE; - } - else if (m_tx_stream_index == (m_tx_stream_length - 1)) - { - m_tx_state = UART_TX_LAST_BYTE_WAIT; - } - else - { - m_tx_state = UART_TX_SEND; - } - - //Critical region for avoiding timing issues in 'simultaneous RX end and TX start' - CRITICAL_REGION_ENTER(); - if (m_tx_pending == true) - { - m_tx_pending = false; - uart_tx_start(); - - if (m_tx_state == UART_TX_SEND) - { - uart_tx_send(); - } - else if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - uart_tx_last_byte(); - } - } - CRITICAL_REGION_EXIT(); - - if (m_tx_state == UART_IDLE) - { - uart_peripheral_disable(); - } - } - } - } - else - { - m_rx_state = UART_RX_PENDING; - } -} - - -static __INLINE void uart_error_handle(void) -{ - uint32_t error_source; - - //Clear UART ERROR event flag. - NRF_UART0->EVENTS_ERROR = 0; - - //Clear error source. - error_source = NRF_UART0->ERRORSRC; - NRF_UART0->ERRORSRC = error_source; - - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_HW_ERROR; - m_ser_phy_event_rx.evt_params.hw_error.error_code = error_source; - - m_ser_phy_event_handler(m_ser_phy_event_rx); -} - - -/**@brief app_gpiote_fast_detect event handler. - * - */ -static void gpiote_evt_handler(void) -{ - if ( m_pin_cts_mask) - { - if ( nrf_gpio_pin_read(SER_PHY_UART_CTS) ) - { - on_cts_high(); - } - else - { - on_cts_low(); - } - } -} - -/**@brief Function for handling the UART Interrupt. - * - * @details UART interrupt handler to process TX Ready when TXD is available, RX Ready when a byte - * is received, or in case of error when receiving a byte. - */ -void UART0_IRQHandler(void) -{ - //Handle Reception. - if (NRF_UART0->EVENTS_RXDRDY != 0 && (NRF_UART0->INTENSET & UART_INTENSET_RXDRDY_Msk)) - { - uart_rxdrdy_handle(); - } - - //Handle transmission. - if (NRF_UART0->EVENTS_TXDRDY != 0 && (NRF_UART0->INTENSET & UART_INTENSET_TXDRDY_Msk)) - { - uart_txdrdy_handle(); - } - - //Handle errors. - if (NRF_UART0->EVENTS_ERROR != 0 && (NRF_UART0->INTENSET & UART_INTENSET_ERROR_Msk)) - { - uart_error_handle(); - } -} - - -uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) -{ - if (events_handler == NULL) - { - return NRF_ERROR_NULL; - } - - //Check if function was not called before - if (m_ser_phy_event_handler != NULL) - { - return NRF_ERROR_INVALID_STATE; - } - - //GPIO Setup - nrf_gpio_cfg_input(SER_PHY_UART_RTS, NRF_GPIO_PIN_NOPULL); - - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_TX; - nrf_gpio_cfg_output(SER_PHY_UART_TX); - - //Setup the gpiote to handle pin events on cts-pin. - //For the UART we want to detect both low->high and high->low transitions in order to - //know when to activate/de-activate the TX/RX in the UART. - //Configure pin. - m_pin_cts_mask = (1 << SER_PHY_UART_CTS); - nrf_gpio_cfg_sense_input(SER_PHY_UART_CTS, - NRF_GPIO_PIN_PULLUP, - NRF_GPIO_PIN_SENSE_LOW); - - nrf_gpio_cfg_sense_input(SER_PHY_UART_RX, - NRF_GPIO_PIN_PULLUP, - NRF_GPIO_PIN_NOSENSE); - - (void)app_gpiote_input_event_handler_register(0, - SER_PHY_UART_CTS, - GPIOTE_CONFIG_POLARITY_Toggle, - gpiote_evt_handler); - (void)app_gpiote_enable_interrupts(); - - NVIC_ClearPendingIRQ(PendSV_IRQn); - - m_rx_state = UART_IDLE; - m_tx_state = UART_IDLE; - - //Set header flag - m_rx_stream_header = true; - - //UART setup - NRF_UART0->PSELRXD = SER_PHY_UART_RX; - NRF_UART0->PSELTXD = SER_PHY_UART_TX; - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->BAUDRATE = SER_PHY_UART_BAUDRATE; - NRF_UART0->CONFIG = (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos); - - //Enable UART interrupt - NRF_UART0->INTENCLR = 0xFFFFFFFF; - NRF_UART0->INTENSET = (UART_INTENSET_TXDRDY_Set << UART_INTENSET_TXDRDY_Pos) | - (UART_INTENSET_RXDRDY_Set << UART_INTENSET_RXDRDY_Pos) | - (UART_INTENSET_ERROR_Set << UART_INTENSET_ERROR_Pos); - - NVIC_ClearPendingIRQ(UART0_IRQn); - NVIC_SetPriority(UART0_IRQn, APP_IRQ_PRIORITY_MID); - NVIC_EnableIRQ(UART0_IRQn); - - m_ser_phy_event_handler = events_handler; - - return NRF_SUCCESS; -} - - -void ser_phy_close(void) -{ - //Disable UART interrupt. - NRF_UART0->INTENCLR = 0xFFFFFFFF; - - //Unregister callback. - m_ser_phy_event_handler = NULL; - - //Will not check err_code here as we will still continue with closure of UART despite errors. - //Note that any error will still be reported back in the system. - nrf_gpiote_event_disable(0); - - uart_peripheral_disable(); - - //Clear internal UART states - m_rx_state = UART_IDLE; - m_tx_state = UART_IDLE; - - mp_tx_stream = NULL; - m_tx_stream_length = 0; - m_tx_stream_index = 0; - - mp_rx_stream = NULL; - m_rx_stream_length = 0; - m_rx_stream_index = 0; -} - - -uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) -{ - if (p_buffer == NULL) - { - return NRF_ERROR_NULL; - } - - if (num_of_bytes == 0) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (mp_tx_stream != NULL) - { - return NRF_ERROR_BUSY; - } - - m_tx_pending = true; - - (void) uint16_encode(num_of_bytes, m_tx_length_buf); - mp_tx_stream = (uint8_t *)p_buffer; - m_tx_stream_length = num_of_bytes + SER_PHY_HEADER_SIZE; - - //Critical region for avoiding timing issues in 'simultaneous RX end and TX start' - CRITICAL_REGION_ENTER(); - if ((!m_rx_stream_length) || (m_rx_stream_index < (m_rx_stream_length - 2))) - { - if (m_tx_state != UART_STALL) - { - if (m_tx_pending == true) - { - m_tx_pending = false; - uart_tx_start(); - //As no tx can be ongoing, then it is safe to call tx_send here. - uart_tx_send(); - } - } - } - CRITICAL_REGION_EXIT(); - - return NRF_SUCCESS; -} - - -uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) -{ - if (m_ser_phy_event_rx.evt_type != SER_PHY_EVT_RX_BUF_REQUEST) - { - return NRF_ERROR_INVALID_STATE; - } - - if (p_buffer != NULL) - { - mp_rx_stream = p_buffer; - } - else - { - mp_rx_stream = m_rx_drop_buf; - } - - return NRF_SUCCESS; -} - - -void ser_phy_interrupts_enable(void) -{ - NVIC_EnableIRQ(UART0_IRQn); - NVIC_EnableIRQ(GPIOTE_IRQn); -} - - -void ser_phy_interrupts_disable(void) -{ - NVIC_DisableIRQ(UART0_IRQn); - NVIC_DisableIRQ(GPIOTE_IRQn); -} diff --git a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_conn.c b/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_conn.c deleted file mode 100644 index e4782d2..0000000 --- a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart_stm_conn.c +++ /dev/null @@ -1,784 +0,0 @@ -/* Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by STMicroelectronics that - * is used in combination with a processor manufactured by Nordic Semiconductor - * or in a processor manufactured by STMicroelectronics. - * - * - * 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 HOLDER 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. - */ - - -#include -#include - -#include "nordic_common.h" -#include "boards.h" -#include "nrf.h" -#include "nrf_soc.h" -#include "nrf_error.h" -#include "nrf_gpio.h" -#include "nrf_delay.h" -#include "app_util_platform.h" -#include "app_gpiote.h" -#include "ser_phy.h" -#include "ser_phy_config_conn_nrf51.h" - -#define APP_GPIOTE_MAX_USERS 1 -#define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */ - -/** @brief States for the app_uart state machine. */ -typedef enum -{ - UART_IDLE, /**< Indicating that the current status for either RX or TX is idle. When both RX and TX is idle the UART will be disabled in order to save power. */ - UART_RX, /**< Used to indicate that a packet is currently being received on RX. */ - UART_RX_PENDING, /**< Used to indicate that byte is ready at RXD register but no buffer was available when the byte was received. The byte will be pulled when a buffer is set. */ - UART_TX_COMPLETE, /**< Used on TX to indicate that final byte has been put on TXD register. Next TXDRDY interrupt will indicate that last byte has been transmitted. */ - UART_TX_SEND, /**< Used to indicate that a packet is currently being transmitted on TX. */ - UART_TX_LAST_BYTE_WAIT, /**< Used to indicate that the last byte on a TX packet is currently waiting to be transmitted when CTS goes low. Note that flow control is off when tranmitting final byte. */ - UART_STALL, /**< Indicates that TX is stalled because final byte is being received on the UART. */ -} uart_states_t; - -static volatile uint32_t m_pin_cts_mask; /**< CTS pin mask for UART module. */ -static app_gpiote_user_id_t m_gpiote_uid; /**< GPIOTE module user id for the UART module. */ - -static volatile uint8_t * mp_tx_stream; /**< Pointer to array of data packet to be transmitted. */ -static volatile uint16_t m_tx_stream_length; /**< Total length of data packet to be transmitted. */ -static volatile uint16_t m_tx_stream_index; /**< Index in data packet for next byte to be transmitted. */ -static uint8_t m_tx_length_buf[SER_PHY_HEADER_SIZE]; /**< Buffer needed in transmission of packet length */ - -static uint8_t * mp_rx_stream; /**< Pointer to current receive buffer. */ -static volatile uint16_t m_rx_stream_length; /**< Length of receive buffer. */ -static volatile uint16_t m_rx_stream_index; /**< Index in receive buffer where the next byte will be placed. */ -static volatile bool m_rx_stream_header; /**< Indication of whether header data (true) or payload data (false) is currently being received. */ -static uint8_t m_rx_length_buf[SER_PHY_HEADER_SIZE]; /**< Buffer needed in reception of packet length */ -static uint8_t m_rx_drop_buf[1]; /**< Additional buffer, needed by packet dropping functionality. */ - -static volatile uart_states_t m_rx_state = UART_IDLE; /**< State of the RX state machine. */ -static volatile uart_states_t m_tx_state = UART_IDLE; /**< State of the TX state machine. */ -static volatile bool m_tx_pending = false; /**< If TX state is UART_STALL and a byte is ready for tranmission the pending flag is set to true. */ -static volatile bool m_cts_high_disconnect = false; /**< If CTS was sampled low when last byte was transmitted this flag is set to true to indicate that a switch from low->high on CTS should be interpreted as transmission has completed and UART is to be disabled to save power. */ - -static volatile ser_phy_events_handler_t m_ser_phy_event_handler; -static volatile ser_phy_evt_t m_ser_phy_event_rx; -static volatile ser_phy_evt_t m_ser_phy_event_tx; - - -static void uart_peripheral_disconnect_flow(void) -{ - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->CONFIG &= ~(UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); -} - - -static void uart_peripheral_connect_flow(void) -{ - NRF_UART0->PSELCTS = SER_PHY_UART_CTS; - NRF_UART0->PSELRTS = SER_PHY_UART_RTS; - NRF_UART0->CONFIG |= (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); -} - - -static void uart_peripheral_enable_wo_flow(void) -{ - if (!(NRF_UART0->ENABLE & (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos))) - { - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->CONFIG &= ~(UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - NRF_UART0->TASKS_STARTRX = 1; - NRF_UART0->TASKS_STARTTX = 1; - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos); - } -} - - -static void uart_peripheral_enable(void) -{ - if (!(NRF_UART0->ENABLE & (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos))) - { - NRF_UART0->PSELCTS = SER_PHY_UART_CTS; - NRF_UART0->PSELRTS = SER_PHY_UART_RTS; - NRF_UART0->CONFIG |= (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - NRF_UART0->TASKS_STARTRX = 1; - NRF_UART0->TASKS_STARTTX = 1; - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Enabled << UART_ENABLE_ENABLE_Pos); - } -} - - -static void uart_peripheral_disable(void) -{ - if ((m_tx_state == UART_IDLE || m_tx_state == UART_STALL) && - (m_rx_state == UART_IDLE)) - { - uint32_t pins; - NRF_UART0->TASKS_STOPTX = 1; - NRF_UART0->TASKS_STOPRX = 1; - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos); - - nrf_gpio_cfg_input(SER_PHY_UART_RTS, NRF_GPIO_PIN_NOPULL); - - (void) app_gpiote_user_enable(m_gpiote_uid); - (void) app_gpiote_pins_state_get(m_gpiote_uid, &pins); - - if (!pins) - { - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - uart_peripheral_enable(); - } - } -} - - -static void uart_tx_start(void) -{ - if (mp_tx_stream != NULL) - { - //If RX is already ongoing then no wakeup signal is required. - if (m_rx_state == UART_IDLE) - { - (void) app_gpiote_user_disable(m_gpiote_uid); - uart_peripheral_enable_wo_flow(); - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - NRF_GPIO->OUTCLR = 1 << SER_PHY_UART_RTS; - nrf_delay_us(4); - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - uart_peripheral_connect_flow(); - } - } -} - - -static void uart_tx_send(void) -{ - //First send 2 bytes of header then payload - if (m_tx_stream_index < SER_PHY_HEADER_SIZE) - { - NRF_UART0->TXD = m_tx_length_buf[m_tx_stream_index++]; - } - else if (m_tx_stream_index < m_tx_stream_length) - { - NRF_UART0->TXD = mp_tx_stream[m_tx_stream_index++ - SER_PHY_HEADER_SIZE]; - } -} - - -static void uart_tx_last_byte(void) -{ - uint32_t pins; - - uart_peripheral_disconnect_flow(); - m_tx_state = UART_TX_LAST_BYTE_WAIT; - - (void) app_gpiote_user_enable(m_gpiote_uid); - (void) app_gpiote_pins_state_get(m_gpiote_uid, &pins); - - if (!pins) //All pins are low --> last byte can be transmitted. - { - (void) app_gpiote_user_disable(m_gpiote_uid); - - //Re-check state as it might have changed due to preemption of current interrupt. - if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - m_tx_state = UART_TX_COMPLETE; - uart_tx_send(); - } - } -} - - -static void tx_complete_event_send(void) -{ - mp_tx_stream = NULL; - m_tx_stream_length = 0; - m_tx_stream_index = 0; - - m_ser_phy_event_tx.evt_type = SER_PHY_EVT_TX_PKT_SENT; - m_ser_phy_event_handler(m_ser_phy_event_tx); -} - - -static void uart_txdrdy_handle(void) -{ - NRF_UART0->EVENTS_TXDRDY = 0; - - if (m_tx_state == UART_TX_SEND || m_tx_state == UART_IDLE) - { - if (m_tx_stream_index < (m_tx_stream_length - 1)) - { - m_tx_state = UART_TX_SEND; - uart_tx_send(); - //Keep same state. - } - else if (m_tx_stream_index == m_tx_stream_length) - { - m_tx_state = UART_IDLE; - tx_complete_event_send(); - } - else - { - uart_tx_last_byte(); - } - } - else if (m_tx_state == UART_TX_COMPLETE) - { - m_tx_state = UART_IDLE; - - if (m_rx_state == UART_IDLE) - { - uint32_t pins; - (void) app_gpiote_pins_state_get(m_gpiote_uid, &pins); - - if (pins) - { - uart_peripheral_disable(); - } - else - { - uart_peripheral_connect_flow(); - m_cts_high_disconnect = true; - (void) app_gpiote_user_enable(m_gpiote_uid); - (void) app_gpiote_pins_state_get(m_gpiote_uid, &pins); - - if (pins) - { - //If second sample show CTS high it either - //1) happened BEFORE gpiote enable and uart should be disabled. - //(m_cts_high_disconnect == true). - //2) happened AFTER gpiote enable and an interrupt low->high has occured then - //uart should NOT be disabled as the ISR has disabled the UART. - //(m_cts_high_disconnect == false). - if (m_cts_high_disconnect == true) - { - m_cts_high_disconnect = false; - uart_peripheral_disable(); - } - } - } - } - else - { - uart_peripheral_connect_flow(); - } - - tx_complete_event_send(); - } - else if (m_tx_state == UART_STALL) - { - if (m_tx_stream_index == m_tx_stream_length) - { - tx_complete_event_send(); - } - else - { - m_tx_pending = true; - } - } - else - { - //Do nothing. - } -} - - -static __INLINE void on_cts_high(void) -{ - if (m_cts_high_disconnect == true) - { - m_cts_high_disconnect = false; - - if (m_rx_state == UART_IDLE && m_tx_state == UART_IDLE) - { - if (m_tx_stream_index == m_tx_stream_length) - { - uart_peripheral_disable(); - } - } - } -} - - -static __INLINE void on_cts_low(void) -{ - m_cts_high_disconnect = false; - (void) app_gpiote_user_disable(m_gpiote_uid); - - if (m_tx_state == UART_STALL) - { - m_tx_pending = true; - } - else if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - m_tx_state = UART_TX_COMPLETE; - uart_tx_send(); - } - else if (m_rx_state == UART_IDLE && m_tx_state == UART_IDLE) - { - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - uart_peripheral_enable(); - } -} - - -static void uart_rxdrdy_handle(void) -{ - if (m_rx_state == UART_IDLE) - { - m_rx_state = UART_RX; - } - - //Set proper size and buff at the beginning of receiving header - if ((m_rx_stream_header == true) && !m_rx_stream_index) - { - m_rx_stream_length = SER_PHY_HEADER_SIZE; - mp_rx_stream = m_rx_length_buf; - } - - if (mp_rx_stream != NULL) - { - bool tx_dual_end = false; - - NRF_UART0->EVENTS_RXDRDY = 0; - - //Second last byte received. - //Disconnect CTS before pulling the byte and receiving the final byte. - if ((m_rx_stream_header == false) && ((m_rx_stream_index) == (m_rx_stream_length - 2))) - { - nrf_gpio_cfg_output(SER_PHY_UART_RTS); - - //Last byte is waiting for tansmission. Thus dual end TX case. - // - if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - m_tx_state = UART_STALL; - (void) app_gpiote_user_disable(m_gpiote_uid); - - //Checking pending state. - //- If pending is true then CTS have become low after we stalled the UART and final byte should be transmitted here. - //- If pending is false we should check if final byte was tranmitted and if not, the do the transmission her. - if ((m_tx_pending == true) || (m_tx_stream_index == (m_tx_stream_length - 1))) - { - tx_dual_end = true; - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - uart_tx_send(); - } - } - - if (!tx_dual_end) - { - NRF_GPIO->OUTCLR = 1 << SER_PHY_UART_RTS; - } - m_tx_state = UART_STALL; - - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->CONFIG &= ~(UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - } - - if (m_rx_stream_index < (m_rx_stream_length - 1)) - { - if (mp_rx_stream != m_rx_drop_buf) - { - mp_rx_stream[m_rx_stream_index++] = NRF_UART0->RXD; - } - else - { - mp_rx_stream[0] = NRF_UART0->RXD; - m_rx_stream_index++; - } - - if (m_tx_stream_index == (m_tx_stream_length - 1)) - { - //Toggle CTS line to indicate ack. - //If CTS is connected to UART this code will have no effect. - //But on edge case on bi-directional last byte transfer this avoids lock-up. - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - nrf_delay_us(4); - NRF_GPIO->OUTCLR = 1 << SER_PHY_UART_RTS; - } - } - else - { - if (m_rx_stream_header == false) - { - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_RTS; - - if (mp_rx_stream != m_rx_drop_buf) - { - mp_rx_stream[m_rx_stream_index++] = NRF_UART0->RXD; - } - else - { - mp_rx_stream[0] = NRF_UART0->RXD; - m_rx_stream_index++; - } - m_rx_state = UART_IDLE; - - //Last byte of payload received - notify that next transmission will be header - m_rx_stream_header = true; - - //Prepare event - if (mp_rx_stream != m_rx_drop_buf) - { - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED; - m_ser_phy_event_rx.evt_params.rx_pkt_received.num_of_bytes = m_rx_stream_index; - m_ser_phy_event_rx.evt_params.rx_pkt_received.p_buffer = mp_rx_stream; - } - else - { - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_RX_PKT_DROPPED; - } - - m_rx_stream_length = 0; - m_rx_stream_index = 0; - } - else - { - mp_rx_stream[m_rx_stream_index++] = NRF_UART0->RXD; - - //Last byte of header received - notify that next transmission will be payload - m_rx_stream_header = false; - - mp_rx_stream = NULL; - - //Clear index before receiving payload - m_rx_stream_index = 0; - - //Prepare event - m_rx_stream_length = uint16_decode(m_rx_length_buf); - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_RX_BUF_REQUEST; - m_ser_phy_event_rx.evt_params.rx_buf_request.num_of_bytes = m_rx_stream_length; - } - - //Notify upwards - m_ser_phy_event_handler(m_ser_phy_event_rx); - - //UART TX was stalled while receiving final byte. Restart tx. - if (m_tx_state == UART_STALL) - { - if (m_tx_stream_length == m_tx_stream_index) - { - m_tx_state = UART_IDLE; - } - else if (m_tx_stream_index == (m_tx_stream_length - 1)) - { - m_tx_state = UART_TX_LAST_BYTE_WAIT; - } - else - { - m_tx_state = UART_TX_SEND; - } - - //Critical region for avoiding timing issues in 'simultaneous RX end and TX start' - CRITICAL_REGION_ENTER(); - if (m_tx_pending == true) - { - m_tx_pending = false; - uart_tx_start(); - - if (m_tx_state == UART_TX_SEND) - { - uart_tx_send(); - } - else if (m_tx_state == UART_TX_LAST_BYTE_WAIT) - { - uart_tx_last_byte(); - } - } - CRITICAL_REGION_EXIT(); - - if (m_tx_state == UART_IDLE) - { - uart_peripheral_disable(); - } - } - } - } - else - { - m_rx_state = UART_RX_PENDING; - } -} - - -static __INLINE void uart_error_handle(void) -{ - uint32_t error_source; - - //Clear UART ERROR event flag. - NRF_UART0->EVENTS_ERROR = 0; - - //Clear error source. - error_source = NRF_UART0->ERRORSRC; - NRF_UART0->ERRORSRC = error_source; - - m_ser_phy_event_rx.evt_type = SER_PHY_EVT_HW_ERROR; - m_ser_phy_event_rx.evt_params.hw_error.error_code = error_source; - - m_ser_phy_event_handler(m_ser_phy_event_rx); -} - - -/**@brief Function for handling the GPIOTE event. - * - * @param[in] event_pins_low_to_high Mask telling which pin(s) generated an event from low->high. - * @param[in] event_pins_high_to_low Mask telling which pin(s) generated an event from high->low. - */ -static void gpiote_uart_event_handler(uint32_t event_pins_low_to_high, - uint32_t event_pins_high_to_low) -{ - if ((event_pins_high_to_low & m_pin_cts_mask) != 0) - { - on_cts_low(); - } - - if ((event_pins_low_to_high & m_pin_cts_mask) != 0) - { - on_cts_high(); - } -} - - -/**@brief Function for handling the UART Interrupt. - * - * @details UART interrupt handler to process TX Ready when TXD is available, RX Ready when a byte - * is received, or in case of error when receiving a byte. - */ -void UART0_IRQHandler(void) -{ - //Handle Reception. - if (NRF_UART0->EVENTS_RXDRDY != 0 && (NRF_UART0->INTENSET & UART_INTENSET_RXDRDY_Msk)) - { - uart_rxdrdy_handle(); - } - - //Handle transmission. - if (NRF_UART0->EVENTS_TXDRDY != 0 && (NRF_UART0->INTENSET & UART_INTENSET_TXDRDY_Msk)) - { - uart_txdrdy_handle(); - } - - //Handle errors. - if (NRF_UART0->EVENTS_ERROR != 0 && (NRF_UART0->INTENSET & UART_INTENSET_ERROR_Msk)) - { - uart_error_handle(); - } -} - - -uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) -{ - uint32_t gpiote_pin_low_high_mask = 0; - uint32_t gpiote_pin_high_low_mask = 0; - - if (events_handler == NULL) - { - return NRF_ERROR_NULL; - } - - //Check if function was not called before - if (m_ser_phy_event_handler != NULL) - { - return NRF_ERROR_INVALID_STATE; - } - - //Configure GPIOTE with one user for the UART flow control feature. - APP_GPIOTE_INIT(APP_GPIOTE_MAX_USERS); - - //GPIO Setup - nrf_gpio_cfg_input(SER_PHY_UART_RTS, NRF_GPIO_PIN_NOPULL); - - NRF_GPIO->OUTSET = 1 << SER_PHY_UART_TX; - nrf_gpio_cfg_output(SER_PHY_UART_TX); - - //Setup the gpiote to handle pin events on cts-pin. - //For the UART we want to detect both low->high and high->low transitions in order to - //know when to activate/de-activate the TX/RX in the UART. - //Configure pin. - m_pin_cts_mask = (1 << SER_PHY_UART_CTS); - nrf_gpio_cfg_sense_input(SER_PHY_UART_CTS, - NRF_GPIO_PIN_PULLUP, - NRF_GPIO_PIN_SENSE_LOW); - - nrf_gpio_cfg_sense_input(SER_PHY_UART_RX, - NRF_GPIO_PIN_PULLUP, - NRF_GPIO_PIN_NOSENSE); - - gpiote_pin_low_high_mask = (1 << SER_PHY_UART_CTS); - gpiote_pin_high_low_mask = (1 << SER_PHY_UART_CTS); - - (void)app_gpiote_user_register(&m_gpiote_uid, - gpiote_pin_low_high_mask, - gpiote_pin_high_low_mask, - gpiote_uart_event_handler); - - (void)app_gpiote_user_enable(m_gpiote_uid); - - m_rx_state = UART_IDLE; - m_tx_state = UART_IDLE; - - //Set header flag - m_rx_stream_header = true; - - //UART setup - NRF_UART0->PSELRXD = SER_PHY_UART_RX; - NRF_UART0->PSELTXD = SER_PHY_UART_TX; - NRF_UART0->PSELCTS = UART_PIN_DISCONNECTED; - NRF_UART0->PSELRTS = UART_PIN_DISCONNECTED; - NRF_UART0->BAUDRATE = SER_PHY_UART_BAUDRATE; - NRF_UART0->CONFIG = (UART_CONFIG_HWFC_Enabled << UART_CONFIG_HWFC_Pos); - NRF_UART0->ENABLE = (UART_ENABLE_ENABLE_Disabled << UART_ENABLE_ENABLE_Pos); - - //Enable UART interrupt - NRF_UART0->INTENCLR = 0xFFFFFFFF; - NRF_UART0->INTENSET = (UART_INTENSET_TXDRDY_Set << UART_INTENSET_TXDRDY_Pos) | - (UART_INTENSET_RXDRDY_Set << UART_INTENSET_RXDRDY_Pos) | - (UART_INTENSET_ERROR_Set << UART_INTENSET_ERROR_Pos); - - NVIC_ClearPendingIRQ(UART0_IRQn); - NVIC_SetPriority(UART0_IRQn, APP_IRQ_PRIORITY_LOW); - NVIC_EnableIRQ(UART0_IRQn); - - m_ser_phy_event_handler = events_handler; - - return NRF_SUCCESS; -} - - -void ser_phy_close(void) -{ - //Disable UART interrupt. - NRF_UART0->INTENCLR = 0xFFFFFFFF; - - //Unregister callback. - m_ser_phy_event_handler = NULL; - - //Will not check err_code here as we will still continue with closure of UART despite errors. - //Note that any error will still be reported back in the system. - (void)app_gpiote_user_disable(m_gpiote_uid); - - uart_peripheral_disable(); - - //Clear internal UART states - m_rx_state = UART_IDLE; - m_tx_state = UART_IDLE; - - mp_tx_stream = NULL; - m_tx_stream_length = 0; - m_tx_stream_index = 0; - - mp_rx_stream = NULL; - m_rx_stream_length = 0; - m_rx_stream_index = 0; -} - - -uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) -{ - if (p_buffer == NULL) - { - return NRF_ERROR_NULL; - } - - if (num_of_bytes == 0) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (mp_tx_stream != NULL) - { - return NRF_ERROR_BUSY; - } - - m_tx_pending = true; - - (void) uint16_encode(num_of_bytes, m_tx_length_buf); - mp_tx_stream = (uint8_t *)p_buffer; - m_tx_stream_length = num_of_bytes + SER_PHY_HEADER_SIZE; - - //Critical region for avoiding timing issues in 'simultaneous RX end and TX start' - CRITICAL_REGION_ENTER(); - if ((!m_rx_stream_length) || (m_rx_stream_index < (m_rx_stream_length - 2))) - { - if (m_tx_state != UART_STALL) - { - if (m_tx_pending == true) - { - m_tx_pending = false; - uart_tx_start(); - //As no tx can be ongoing, then it is safe to call tx_send here. - uart_tx_send(); - } - } - } - CRITICAL_REGION_EXIT(); - - return NRF_SUCCESS; -} - - -uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) -{ - if (m_ser_phy_event_rx.evt_type != SER_PHY_EVT_RX_BUF_REQUEST) - { - return NRF_ERROR_INVALID_STATE; - } - - if (p_buffer != NULL) - { - mp_rx_stream = p_buffer; - } - else - { - mp_rx_stream = m_rx_drop_buf; - } - - return NRF_SUCCESS; -} - - -void ser_phy_interrupts_enable(void) -{ - NVIC_EnableIRQ(UART0_IRQn); -} - - -void ser_phy_interrupts_disable(void) -{ - NVIC_DisableIRQ(UART0_IRQn); -} diff --git a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_5W_master.c b/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_master.c similarity index 86% rename from components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_5W_master.c rename to components/serialization/common/transport/ser_phy/ser_phy_spi_5W_master.c index e1e931d..4c21e25 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_5W_master.c +++ b/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_master.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -29,7 +57,7 @@ #include "ser_config.h" #include "ser_config_5W_app.h" #include "ser_phy.h" -#include "ser_phy_config_app_nrf51.h" +#include "ser_phy_config_app.h" #include "spi_5W_master.h" #include "ser_phy_debug_app.h" #include "app_error.h" @@ -147,32 +175,29 @@ void SW_IRQ_Handler() } -void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) +#ifndef _SPI_5W_ +static void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin, + nrf_gpiote_polarity_t action) { + if (nrf_gpio_pin_read(pin) == 0) + { + m_slave_ready_flag = true; + m_pend_rdy_flag = true; + } + else + { + m_slave_ready_flag = false; + } -#ifdef _SPI_5W_ - //For 5W slave is considered to be always READY - m_slave_ready_flag = true; - m_pend_rdy_flag = false; - #else - if (nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY) == 0) - { - m_slave_ready_flag = true; - m_pend_rdy_flag = true; - } - else - { - m_slave_ready_flag = false; - } - - DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE((uint32_t) !m_slave_ready_flag); -#endif - + DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE((uint32_t) !m_slave_ready_flag); + SET_Pend_SW_IRQ(); } +#endif -void ser_phy_spi_master_request(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) +static void ser_phy_spi_master_request(nrf_drv_gpiote_pin_t pin, + nrf_gpiote_polarity_t action) { - if (nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST) == 0) + if (nrf_gpio_pin_read(pin) == 0) { m_slave_request_flag = true; m_pend_req_flag = true; @@ -606,56 +631,46 @@ static void ser_phy_spi_master_event_handler(spi_master_evt_t spi_master_evt) } } -/* Initialize GPIO */ -static __INLINE void ser_phy_init_gpio() -{ - nrf_gpio_cfg_input(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST, NRF_GPIO_PIN_PULLUP); - nrf_gpio_cfg_input(SER_PHY_SPI_MASTER_PIN_SLAVE_READY, NRF_GPIO_PIN_PULLUP); -} - -/* Initialize GPIO */ -static __INLINE void ser_phy_init_pendSV() +static void ser_phy_init_pendSV(void) { NVIC_SetPriority(SW_IRQn, APP_IRQ_PRIORITY_MID); NVIC_EnableIRQ(SW_IRQn); } -/* Initialize GPIOTE */ -static __INLINE void ser_phy_init_gpiote() +static void ser_phy_init_gpiote(void) { if (!nrf_drv_gpiote_is_init()) { (void)nrf_drv_gpiote_init(); } - m_slave_request_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST)); + NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH); nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true); - (void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST, &config, ser_phy_spi_master_request); + /* Enable pullup to ensure high state while connectivity device is reset */ + config.pull = NRF_GPIO_PIN_PULLUP; + (void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST, &config, + ser_phy_spi_master_request); nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST,true); m_slave_request_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST)); - #ifdef _SPI_5W_ - m_slave_ready_flag = true; - + m_slave_ready_flag = true; #else - m_slave_ready_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY)); - (void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_READY, &config, ser_phy_spi_master_ready); - + (void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_READY, &config, + ser_phy_spi_master_ready); nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_READY,true); + m_slave_ready_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY)); #endif NVIC_ClearPendingIRQ(SW_IRQn); } -static __INLINE void ser_phy_deinit_gpiote() +static void ser_phy_deinit_gpiote(void) { nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST); #ifndef _SPI_5W_ nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_READY); #endif - - } /* ser_phy API function */ @@ -676,12 +691,15 @@ uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes) return NRF_ERROR_BUSY; } - ser_phy_interrupts_disable(); + //ser_phy_interrupts_disable(); + CRITICAL_REGION_ENTER(); mp_tx_buffer = (uint8_t *)p_buffer; m_tx_buf_len = num_of_bytes; m_pend_tx_api_flag = true; SET_Pend_SW_IRQ(); - ser_phy_interrupts_enable(); + //ser_phy_interrupts_enable(); + CRITICAL_REGION_EXIT(); + return NRF_SUCCESS; } @@ -692,11 +710,15 @@ uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) { return NRF_ERROR_INVALID_STATE; } - ser_phy_interrupts_disable(); + + //ser_phy_interrupts_disable(); + CRITICAL_REGION_ENTER(); mp_rx_buffer = p_buffer; m_pend_rx_api_flag = true; SET_Pend_SW_IRQ(); - ser_phy_interrupts_enable(); + //ser_phy_interrupts_enable(); + CRITICAL_REGION_EXIT(); + return NRF_SUCCESS; } @@ -715,7 +737,6 @@ uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) } uint32_t err_code = NRF_SUCCESS; - ser_phy_init_gpio(); m_spi_master_state = SER_PHY_STATE_IDLE; m_callback_events_handler = events_handler; ser_phy_init_gpiote(); diff --git a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_5W_slave.c b/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_slave.c similarity index 87% rename from components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_5W_slave.c rename to components/serialization/common/transport/ser_phy/ser_phy_spi_5W_slave.c index 5bfdd33..618d1e1 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_5W_slave.c +++ b/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_slave.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -34,7 +62,7 @@ #include "nrf_soc.h" #include "app_error.h" #include "app_util.h" -#include "ser_phy_config_conn_nrf51.h" +#include "ser_phy_config_conn.h" #include "ser_phy_debug_conn.h" #include "app_error.h" @@ -80,8 +108,8 @@ _static uint16_t m_accumulated_tx_packet_length; _static uint16_t m_tx_packet_length; _static uint16_t m_current_tx_frame_length; -_static uint8_t m_header_rx_buffer[SER_PHY_HEADER_SIZE + 1]; //+1 for '0' guard in SPI_5W -_static uint8_t m_header_tx_buffer[SER_PHY_HEADER_SIZE + 1]; //+1 for '0' guard in SPI_5W +_static uint8_t m_header_rx_buffer[SER_PHY_HEADER_SIZE + 1]; // + 1 for '0' guard in SPI_5W +_static uint8_t m_header_tx_buffer[SER_PHY_HEADER_SIZE + 1]; // + 1 for '0' guard in SPI_5W _static uint8_t m_tx_frame_buffer[SER_PHY_SPI_5W_MTU_SIZE]; _static uint8_t m_rx_frame_buffer[SER_PHY_SPI_5W_MTU_SIZE]; @@ -465,11 +493,11 @@ static void spi_slave_ppi_init(void) static void spi_slave_gpio_init(void) { - nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req); nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req); + nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req); #ifndef _SPI_5W_ - nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy); nrf_gpio_pin_set(m_spi_slave_raw_config.pin_rdy); + nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy); #endif return; } @@ -577,16 +605,16 @@ uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) spi_slave_ppi_init(); #endif - spi_slave_config.miso_pin = SPIS_MISO_PIN; - spi_slave_config.mosi_pin = SPIS_MOSI_PIN; - spi_slave_config.sck_pin = SPIS_SCK_PIN; - spi_slave_config.csn_pin = SPIS_CSN_PIN; + spi_slave_config.miso_pin = SER_CON_SPIS_MISO_PIN; + spi_slave_config.mosi_pin = SER_CON_SPIS_MOSI_PIN; + spi_slave_config.sck_pin = SER_CON_SPIS_SCK_PIN; + spi_slave_config.csn_pin = SER_CON_SPIS_CSN_PIN; spi_slave_config.mode = NRF_DRV_SPIS_MODE_0; spi_slave_config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST; spi_slave_config.def = SER_PHY_SPI_DEF_CHARACTER; spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER; spi_slave_config.csn_pullup = NRF_GPIO_PIN_PULLUP; - spi_slave_config.irq_priority = NRF_APP_PRIORITY_LOW; + spi_slave_config.irq_priority = APP_IRQ_PRIORITY_LOWEST; //keep /CS high when init nrf_gpio_cfg_input(spi_slave_config.csn_pin, NRF_GPIO_PIN_PULLUP); @@ -605,7 +633,7 @@ uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) spi_slave_event_handle(event); } - + return err_code; } diff --git a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_nrf_drv_spi.c b/components/serialization/common/transport/ser_phy/ser_phy_spi_master.c similarity index 87% rename from components/serialization/common/transport/ser_phy/ser_phy_nrf51_nrf_drv_spi.c rename to components/serialization/common/transport/ser_phy/ser_phy_spi_master.c index 54900b6..ca04af3 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_nrf_drv_spi.c +++ b/components/serialization/common/transport/ser_phy/ser_phy_spi_master.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -32,7 +60,7 @@ #include "nrf_gpiote.h" #include "boards.h" #include "app_error.h" -#include "ser_phy_config_app_nrf51.h" +#include "ser_phy_config_app.h" #include "ser_phy_debug_app.h" #define notUSE_PendSV @@ -45,16 +73,9 @@ #else -#ifdef NRF51 #define SW_IRQn SWI3_IRQn #define SW_IRQ_Handler() SWI3_IRQHandler() #define SET_Pend_SW_IRQ() NVIC_SetPendingIRQ(SWI3_IRQn) -#elif defined NRF52 -#define SW_IRQn SWI3_EGU3_IRQn -#define SW_IRQ_Handler() SWI3_EGU3_IRQHandler() -#define SET_Pend_SW_IRQ() NVIC_SetPendingIRQ(SWI3_EGU3_IRQn) -#endif /* NRF51 */ - #endif /* USE_PendSV */ typedef enum @@ -157,7 +178,8 @@ void SW_IRQ_Handler() } } -void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) +static void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin, + nrf_gpiote_polarity_t action) { if (nrf_gpio_pin_read(pin) == 0) { @@ -173,7 +195,8 @@ void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t ac SET_Pend_SW_IRQ(); } -void ser_phy_spi_master_request(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action) +static void ser_phy_spi_master_request(nrf_drv_gpiote_pin_t pin, + nrf_gpiote_polarity_t action) { if (nrf_gpio_pin_read(pin) == 0) { @@ -589,9 +612,9 @@ static void ser_phy_switch_state(ser_phy_event_source_t evt_src) } } -static void ser_phy_spi_master_event_handler(nrf_drv_spi_event_t event) +static void ser_phy_spi_master_event_handler(nrf_drv_spi_evt_t const * p_event) { - switch (event) + switch (p_event->type) { case NRF_DRV_SPI_EVENT_DONE: @@ -606,45 +629,51 @@ static void ser_phy_spi_master_event_handler(nrf_drv_spi_event_t event) } } -static __INLINE void ser_phy_init_PendSV() +static void ser_phy_init_PendSV(void) { NVIC_SetPriority(SW_IRQn, APP_IRQ_PRIORITY_MID); NVIC_EnableIRQ(SW_IRQn); } -static __INLINE void ser_phy_init_gpio() -{ - nrf_gpio_cfg_input(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST, NRF_GPIO_PIN_PULLUP); - nrf_gpio_cfg_input(SER_PHY_SPI_MASTER_PIN_SLAVE_READY, NRF_GPIO_PIN_PULLUP); -} - -static __INLINE void ser_phy_init_gpiote() +static ret_code_t ser_phy_init_gpiote(void) { if (!nrf_drv_gpiote_is_init()) { (void)nrf_drv_gpiote_init(); } - m_slave_request_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST)); - m_slave_ready_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY)); + NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH); nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true); /* Enable pullup to ensure high state while connectivity device is reset */ config.pull = NRF_GPIO_PIN_PULLUP; - (void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST, &config, ser_phy_spi_master_request); + ret_code_t err_code = nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST, + &config, ser_phy_spi_master_request); + if (err_code != NRF_SUCCESS) + { + return err_code; + } nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST,true); - (void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_READY, &config, ser_phy_spi_master_ready); + err_code = nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_READY, + &config, ser_phy_spi_master_ready); + if (err_code != NRF_SUCCESS) + { + return err_code; + } nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_READY,true); + m_slave_request_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST)); + m_slave_ready_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY)); + NVIC_ClearPendingIRQ(SW_IRQn); + + return NRF_SUCCESS; } -static __INLINE void ser_phy_deinit_gpiote() +static void ser_phy_deinit_gpiote(void) { nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST); nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_READY); - -// (void)app_gpiote_end_irq_event_handler_unregister(); } /* ser_phy API function */ @@ -730,8 +759,7 @@ uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) return err_code; } - ser_phy_init_gpio(); - ser_phy_init_gpiote(); + err_code = ser_phy_init_gpiote(); ser_phy_init_PendSV(); return err_code; } diff --git a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_slave.c b/components/serialization/common/transport/ser_phy/ser_phy_spi_slave.c similarity index 89% rename from components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_slave.c rename to components/serialization/common/transport/ser_phy/ser_phy_spi_slave.c index e9fdfdd..4b20cbe 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_spi_slave.c +++ b/components/serialization/common/transport/ser_phy/ser_phy_spi_slave.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -31,7 +59,7 @@ #include "nrf_drv_spis.h" #include "ser_config.h" #include "ser_phy.h" -#include "ser_phy_config_conn_nrf51.h" +#include "ser_phy_config_conn.h" #include "ser_phy_debug_conn.h" #define SER_PHY_SPI_DEF_CHARACTER 0xFF //SPI default character. Character clocked out in case of an ignored transaction @@ -432,10 +460,10 @@ static void spi_slave_ppi_init(void) static void spi_slave_gpio_init(void) { - nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req); nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req); - nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy); + nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req); nrf_gpio_pin_set(m_spi_slave_raw_config.pin_rdy); + nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy); } /* ser_phy API function */ @@ -545,8 +573,8 @@ uint32_t ser_phy_open(ser_phy_events_handler_t events_handler) spi_slave_config.mode = NRF_DRV_SPIS_MODE_0; spi_slave_config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST; spi_slave_config.def = SER_PHY_SPI_DEF_CHARACTER; - spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER; - spi_slave_config.irq_priority = NRF_APP_PRIORITY_LOW; + spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER; + spi_slave_config.irq_priority = APP_IRQ_PRIORITY_LOWEST; spi_slave_config.miso_drive = NRF_DRV_SPIS_DEFAULT_MISO_DRIVE; //use /CS pullup because state of the line might be undefined when master redefines PIO lines spi_slave_config.csn_pullup = NRF_GPIO_PIN_PULLUP; diff --git a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart.c b/components/serialization/common/transport/ser_phy/ser_phy_uart.c similarity index 84% rename from components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart.c rename to components/serialization/common/transport/ser_phy/ser_phy_uart.c index d162921..e84a2fe 100644 --- a/components/serialization/common/transport/ser_phy/ser_phy_nrf51_uart.c +++ b/components/serialization/common/transport/ser_phy/ser_phy_uart.c @@ -1,43 +1,48 @@ - -/* Copyright (c) Nordic Semiconductor ASA +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + #include "ser_phy.h" #include #include #include - #include "nordic_common.h" #include "nrf.h" #include "nrf_error.h" @@ -45,20 +50,17 @@ #include "app_util.h" #include "app_uart.h" #include "app_error.h" +#include "nrf_drv_uart.h" #ifdef SER_CONNECTIVITY -#include "ser_phy_config_conn_nrf51.h" +#include "ser_phy_config_conn.h" #else -#include "ser_phy_config_app_nrf51.h" +#include "ser_phy_config_app.h" #endif /* SER_CONNECTIVITY */ #include "boards.h" -#ifdef NRF51 #define SER_UART_IRQ UART0_IRQn -#elif defined NRF52 -#define SER_UART_IRQ UARTE0_UART0_IRQn -#endif /* NRF51 */ static uint8_t * mp_tx_stream; /**< Pointer to Tx data */ static uint16_t m_tx_stream_length; /**< Length of Tx data including SER_PHY @@ -207,8 +209,11 @@ static void ser_phy_uart_tx(void) //Blocking TXRDY interrupt is done to avoid interrupting when this procedure is //triggered from main context +#ifdef UARTE_IN_USE + NRF_UARTE0->INTENCLR = (UARTE_INTENSET_ENDTX_Set << UARTE_INTENSET_ENDTX_Pos); +#else NRF_UART0->INTENCLR = (UART_INTENSET_TXDRDY_Set << UART_INTENSET_TXDRDY_Pos); - +#endif //Notify upper layer if whole packet has been transmitted if (m_tx_stream_index == m_tx_stream_length) { @@ -233,7 +238,11 @@ static void ser_phy_uart_tx(void) } //Unblock TXRDY interrupts +#ifdef UARTE_IN_USE + NRF_UARTE0->INTENSET = (UARTE_INTENSET_ENDTX_Set << UARTE_INTENSET_ENDTX_Pos); +#else NRF_UART0->INTENSET = (UART_INTENSET_TXDRDY_Set << UART_INTENSET_TXDRDY_Pos); +#endif } } @@ -255,8 +264,11 @@ static void ser_phy_uart_rx(uint8_t rx_byte) { //Block RXRDY interrupts at this point to not handle incoming bytes until upper //layer provides memory for payload +#ifdef UARTE_IN_USE + NRF_UARTE0->INTENCLR = (UARTE_INTENCLR_ENDRX_Clear << UARTE_INTENCLR_ENDRX_Pos); +#else NRF_UART0->INTENCLR = (UART_INTENCLR_RXDRDY_Clear << UART_INTENCLR_RXDRDY_Pos); - +#endif //Request rx buffer from upper layer callback_mem_request(); } @@ -417,8 +429,11 @@ uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer) } //Unblock RXRDY interrupts as higher layer has responded (with a valid or NULL pointer) +#ifdef UARTE_IN_USE + NRF_UARTE0->INTENSET = (UARTE_INTENSET_ENDRX_Set << UARTE_INTENSET_ENDRX_Pos); +#else NRF_UART0->INTENSET = (UART_INTENSET_RXDRDY_Set << UART_INTENSET_RXDRDY_Pos); - +#endif return NRF_SUCCESS; } diff --git a/components/serialization/common/transport/ser_phy/spi_5W_master.c b/components/serialization/common/transport/ser_phy/spi_5W_master.c deleted file mode 100644 index 5d48382..0000000 --- a/components/serialization/common/transport/ser_phy/spi_5W_master.c +++ /dev/null @@ -1,603 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -/**@file - * - * @defgroup ser_phy_spi_5W_hw_driver_master spi_5W_master.c - * @{ - * @ingroup ser_phy_spi_5W_hw_driver_master - * - * @brief SPI_5W_RAW hardware driver. - */ - -#include "app_error.h" -#include "app_util_platform.h" -#include "nrf_gpio.h" -#include "nrf.h" -#include "spi_5W_master.h" -#include "ser_config_5W_app.h" -#include "ser_phy_debug_app.h" - - -#define _static - -#define DOUBLE_BUFFERED /**< A flag for enabling double buffering. */ - -#define SPI_PIN_DISCONNECTED 0xFFFFFFFF /**< A value used to the PIN deinitialization. */ -#define SPI_DEFAULT_TX_BYTE 0x00 /**< Default byte (used to clock transmission - from slave to the master) */ - -typedef struct -{ - NRF_SPI_Type * p_nrf_spi; /**< A pointer to the NRF SPI master */ - IRQn_Type irq_type; /**< A type of NVIC IRQn */ - - uint8_t * p_tx_buffer; /**< A pointer to TX buffer. */ - uint16_t tx_length; /**< A length of TX buffer. */ - uint16_t tx_index; /**< A index of the current element in the TX buffer. */ - - uint8_t * p_rx_buffer; /**< A pointer to RX buffer. */ - uint16_t rx_length; /**< A length RX buffer. */ - uint16_t rx_index; /**< A index of the current element in the RX buffer. */ - - uint16_t max_length; /**< Max length (Max of the TX and RX length). */ - uint16_t bytes_count; - uint8_t pin_slave_select; /**< A pin for Slave Select. */ - - spi_master_event_handler_t callback_event_handler; /**< A handler for event callback function. */ - spi_master_state_t state; /**< A state of an instance of SPI master. */ - bool start_flag; - bool abort_flag; - -} spi_master_instance_t; - -#ifdef _SPI_5W_ -typedef enum -{ - HOOK_STATE_DISABLED, - HOOK_STATE_IDLE, - HOOK_STATE_GUARDED, - HOOK_STATE_ABORTED, - HOOK_STATE_RESTARTED, - HOOK_STATE_PASSING -} spi_hook_state_t; - - -_static spi_master_event_handler_t m_ser_phy_event_handler; -_static spi_master_hw_instance_t m_spi_master_hw_instance; -_static spi_hook_state_t m_hook_state = HOOK_STATE_DISABLED; -#endif - -#ifdef SER_PHY_DEBUG_APP_ENABLE -_static spi_master_raw_callback_t m_debug_callback; -#endif - -_static spi_master_instance_t m_spi_master_instances[SPI_MASTER_HW_ENABLED_COUNT]; - -static __INLINE spi_master_instance_t * spi_master_get_instance( - const spi_master_hw_instance_t spi_master_hw_instance); -static __INLINE void spi_master_send_recv_irq(spi_master_instance_t * const p_spi_instance); -static __INLINE void spi_master_signal_evt(spi_master_instance_t * const p_spi_instance, - spi_master_evt_type_t event_type, - const uint16_t data); - -#ifdef SPI_MASTER_0_ENABLE -/** - * @brief SPI0 interrupt handler. - */ -void SPI0_TWI0_IRQHandler(void) -{ - if (NRF_SPI0->EVENTS_READY != 0) - { - NRF_SPI0->EVENTS_READY = 0; - - spi_master_instance_t * p_spi_instance = spi_master_get_instance(SPI_MASTER_0); - - spi_master_send_recv_irq(p_spi_instance); - } -} -#endif //SPI_MASTER_0_ENABLE - -#ifdef SPI_MASTER_1_ENABLE -/** - * @brief SPI0 interrupt handler. - */ -void SPI1_TWI1_IRQHandler(void) -{ - if (NRF_SPI1->EVENTS_READY != 0) - { - NRF_SPI1->EVENTS_READY = 0; - - spi_master_instance_t * p_spi_instance = spi_master_get_instance(SPI_MASTER_1); - - spi_master_send_recv_irq(p_spi_instance); - } -} -#endif //SPI_MASTER_1_ENABLE - -#if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) - -/**@brief Function for getting an instance of SPI master. */ -static __INLINE spi_master_instance_t * spi_master_get_instance( - const spi_master_hw_instance_t spi_master_hw_instance) -{ - return &(m_spi_master_instances[(uint8_t)spi_master_hw_instance]); -} - -/** @brief Function for initializing instance of SPI master by default values. */ -static __INLINE void spi_master_init_hw_instance(NRF_SPI_Type * p_nrf_spi, - IRQn_Type irq_type, - spi_master_instance_t * p_spi_instance) -{ - APP_ERROR_CHECK_BOOL(p_spi_instance != NULL); - - p_spi_instance->p_nrf_spi = p_nrf_spi; - p_spi_instance->irq_type = irq_type; - - p_spi_instance->p_tx_buffer = NULL; - p_spi_instance->tx_length = 0; - p_spi_instance->tx_index = 0; - - p_spi_instance->p_rx_buffer = NULL; - p_spi_instance->rx_length = 0; - p_spi_instance->rx_index = 0; - - p_spi_instance->bytes_count = 0; - p_spi_instance->max_length = 0; - p_spi_instance->pin_slave_select = 0; - - p_spi_instance->callback_event_handler = NULL; - - p_spi_instance->state = SPI_MASTER_STATE_DISABLED; - p_spi_instance->abort_flag = false; - p_spi_instance->start_flag = false; -} - -/**@brief Function for initializing TX or RX buffer. */ -static __INLINE void spi_master_buffer_init(uint8_t * const p_buf, - const uint16_t buf_len, - uint8_t * * pp_buf, - uint16_t * const p_buf_len, - uint16_t * const p_index) -{ - APP_ERROR_CHECK_BOOL(pp_buf != NULL); - APP_ERROR_CHECK_BOOL(p_buf_len != NULL); - APP_ERROR_CHECK_BOOL(p_index != NULL); - - *pp_buf = p_buf; - *p_buf_len = (p_buf != NULL) ? buf_len : 0; - *p_index = 0; -} - -/**@brief Function for releasing TX or RX buffer. */ -static __INLINE void spi_master_buffer_release(uint8_t * * const pp_buf, uint16_t * const p_buf_len) -{ - APP_ERROR_CHECK_BOOL(pp_buf != NULL); - APP_ERROR_CHECK_BOOL(p_buf_len != NULL); - - *pp_buf = NULL; - *p_buf_len = 0; -} - -/**@brief Function for sending events by callback. */ -static __INLINE void spi_master_signal_evt(spi_master_instance_t * const p_spi_instance, - spi_master_evt_type_t event_type, - const uint16_t data) -{ - APP_ERROR_CHECK_BOOL(p_spi_instance != NULL); - - if (p_spi_instance->callback_event_handler != NULL) - { - spi_master_evt_t event = {SPI_MASTER_EVT_TYPE_MAX, 0}; - event.type = event_type; - event.data = data; - p_spi_instance->callback_event_handler(event); - } -} - -/**@brief Function insert to a TX buffer another byte or two bytes (depends on flag @ref DOUBLE_BUFFERED). */ -static __INLINE void spi_master_send_initial_bytes(spi_master_instance_t * const p_spi_instance) -{ - APP_ERROR_CHECK_BOOL(p_spi_instance != NULL); - - p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) && - (p_spi_instance->tx_index < p_spi_instance->tx_length)) ? - p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] : - SPI_DEFAULT_TX_BYTE; - (p_spi_instance->tx_index)++; - - #ifdef DOUBLE_BUFFERED - - if (p_spi_instance->tx_index < p_spi_instance->max_length) - { - p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) && - (p_spi_instance->tx_index < p_spi_instance->tx_length)) ? - p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] : - SPI_DEFAULT_TX_BYTE; - (p_spi_instance->tx_index)++; - } - #endif -} - -/**@brief Function for receiving and sending data from IRQ. (The same for both IRQs). */ -static __INLINE void spi_master_send_recv_irq(spi_master_instance_t * const p_spi_instance) -{ - - uint8_t rx_byte; - - APP_ERROR_CHECK_BOOL(p_spi_instance != NULL); - APP_ERROR_CHECK_BOOL(p_spi_instance->state == SPI_MASTER_STATE_BUSY); - - p_spi_instance->bytes_count++; - rx_byte = p_spi_instance->p_nrf_spi->RXD; - - if (p_spi_instance->start_flag) - { - p_spi_instance->start_flag = false; - spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_FIRST_BYTE_RECEIVED, (uint16_t)rx_byte); - } - else if (p_spi_instance->abort_flag ) //this is tricky, but callback for SPI_MASTER_EVT_FIRST_BYTE_RECEIVED will set this flag for a first byte, which is bad because there is still byte in a buffer - { //and for a single byte transaction you will get XFERDONE event to restart - p_spi_instance->abort_flag = false; - p_spi_instance->state = SPI_MASTER_STATE_ABORTED; - nrf_gpio_pin_set(p_spi_instance->pin_slave_select); - spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_ABORTED, 0); - return; - } - - if ((p_spi_instance->p_rx_buffer != NULL) && - (p_spi_instance->rx_index < p_spi_instance->rx_length)) - { - p_spi_instance->p_rx_buffer[p_spi_instance->rx_index++] = rx_byte; - } - - if ((p_spi_instance->tx_index < p_spi_instance->max_length) && (!(p_spi_instance->abort_flag))) //do not TX if you know that there is an abort to be done - this should work for a DOUBLE BUFFERING ??? - { - p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) && - (p_spi_instance->tx_index < p_spi_instance->tx_length)) ? - p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] : - SPI_DEFAULT_TX_BYTE; - (p_spi_instance->tx_index)++; - } - - if (p_spi_instance->bytes_count >= p_spi_instance->max_length) - { - APP_ERROR_CHECK_BOOL(p_spi_instance->bytes_count == p_spi_instance->max_length); - nrf_gpio_pin_set(p_spi_instance->pin_slave_select); - p_spi_instance->state = SPI_MASTER_STATE_IDLE; - spi_master_signal_evt(p_spi_instance, - SPI_MASTER_EVT_TRANSFER_COMPLETED, - p_spi_instance->tx_index); - } - return; -} -#endif //defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) - - -/** - * @brief Function for opening and initializing a SPI master driver. */ -uint32_t spi_master_open(const spi_master_hw_instance_t spi_master_hw_instance, - spi_master_config_t const * const p_spi_master_config) -{ - #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) - - - if (p_spi_master_config == NULL) - { - return NRF_ERROR_NULL; - } - - spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); - - switch (spi_master_hw_instance) - { - #ifdef SPI_MASTER_0_ENABLE - case SPI_MASTER_0: - spi_master_init_hw_instance(NRF_SPI0, SPI0_TWI0_IRQn, p_spi_instance); - break; - #endif //SPI_MASTER_0_ENABLE - - #ifdef SPI_MASTER_1_ENABLE - case SPI_MASTER_1: - spi_master_init_hw_instance(NRF_SPI1, SPI1_TWI1_IRQn, p_spi_instance); - break; - #endif //SPI_MASTER_1_ENABLE - - default: - break; - } - - //A Slave select must be set as high before setting it as output, - //because during connect it to the pin it causes glitches. - nrf_gpio_pin_set(p_spi_master_config->SPI_Pin_SS); - nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_SS); - nrf_gpio_pin_set(p_spi_master_config->SPI_Pin_SS); - - //Configure GPIO - nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_SCK); - nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_MOSI); - nrf_gpio_cfg_input(p_spi_master_config->SPI_Pin_MISO, NRF_GPIO_PIN_NOPULL); - p_spi_instance->pin_slave_select = p_spi_master_config->SPI_Pin_SS; - - /* Configure SPI hardware */ - p_spi_instance->p_nrf_spi->PSELSCK = p_spi_master_config->SPI_Pin_SCK; - p_spi_instance->p_nrf_spi->PSELMOSI = p_spi_master_config->SPI_Pin_MOSI; - p_spi_instance->p_nrf_spi->PSELMISO = p_spi_master_config->SPI_Pin_MISO; - - p_spi_instance->p_nrf_spi->FREQUENCY = p_spi_master_config->SPI_Freq; - - p_spi_instance->p_nrf_spi->CONFIG = - (uint32_t)(p_spi_master_config->SPI_CPHA << SPI_CONFIG_CPHA_Pos) | - (p_spi_master_config->SPI_CPOL << SPI_CONFIG_CPOL_Pos) | - (p_spi_master_config->SPI_ORDER << SPI_CONFIG_ORDER_Pos); - - - /* Clear waiting interrupts and events */ - p_spi_instance->p_nrf_spi->EVENTS_READY = 0; - - NVIC_ClearPendingIRQ(p_spi_instance->irq_type); - NVIC_SetPriority(p_spi_instance->irq_type, APP_IRQ_PRIORITY_MID); - - /* Clear event handler */ - p_spi_instance->callback_event_handler = NULL; - - /* Enable interrupt */ - p_spi_instance->p_nrf_spi->INTENSET = (SPI_INTENSET_READY_Set << SPI_INTENCLR_READY_Pos); - NVIC_EnableIRQ(p_spi_instance->irq_type); - - /* Enable SPI hardware */ - p_spi_instance->p_nrf_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); - - /* Change state to IDLE */ - p_spi_instance->state = SPI_MASTER_STATE_IDLE; - - return NRF_SUCCESS; - #else - return NRF_ERROR_NOT_SUPPORTED; - #endif -} - -/** - * @brief Function for closing a SPI master driver. - */ -void spi_master_close(const spi_master_hw_instance_t spi_master_hw_instance) -{ - #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) - spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); - - /* Disable interrupt */ - NVIC_ClearPendingIRQ(p_spi_instance->irq_type); - NVIC_DisableIRQ(p_spi_instance->irq_type); - - p_spi_instance->p_nrf_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos); - - /* Disconnect pin slave select */ - nrf_gpio_pin_clear(p_spi_instance->pin_slave_select); - p_spi_instance->pin_slave_select = (uint8_t)0xFF; - - /* Disconnect pins from SPI hardware */ - p_spi_instance->p_nrf_spi->PSELSCK = (uint32_t)SPI_PIN_DISCONNECTED; - p_spi_instance->p_nrf_spi->PSELMOSI = (uint32_t)SPI_PIN_DISCONNECTED; - p_spi_instance->p_nrf_spi->PSELMISO = (uint32_t)SPI_PIN_DISCONNECTED; - - /* Reset to default values */ - spi_master_init_hw_instance(NULL, (IRQn_Type)0, p_spi_instance); - #else - return; - #endif -} - -/** - * @brief Function for getting current state of the SPI master driver. - */ -__INLINE spi_master_state_t spi_master_get_state( - const spi_master_hw_instance_t spi_master_hw_instance) -{ - #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) - spi_master_instance_t * spi_instance = spi_master_get_instance(spi_master_hw_instance); - return spi_instance->state; - #else - return SPI_MASTER_STATE_DISABLED; - #endif -} - -/** - * @brief Function for event handler registration. - */ -__INLINE void spi_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance, - spi_master_event_handler_t event_handler) -{ - #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) - spi_master_instance_t * spi_instance = spi_master_get_instance(spi_master_hw_instance); - spi_instance->callback_event_handler = event_handler; - #else - return; - #endif -} - -/** - * @brief Function for transmitting data between SPI master and SPI slave. - */ -uint32_t spi_master_send_recv(const spi_master_hw_instance_t spi_master_hw_instance, - uint8_t * const p_tx_buf, const uint16_t tx_buf_len, - uint8_t * const p_rx_buf, const uint16_t rx_buf_len) -{ - #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE) - spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); - - uint32_t err_code = NRF_SUCCESS; - uint16_t max_length = 0; - - if (p_spi_instance->state == SPI_MASTER_STATE_IDLE) - { - NVIC_DisableIRQ(p_spi_instance->irq_type); - - max_length = (rx_buf_len > tx_buf_len) ? rx_buf_len : tx_buf_len; - - if (max_length > 0) - { - p_spi_instance->state = SPI_MASTER_STATE_BUSY; - p_spi_instance->start_flag = true; //abort_flag should set by abort and cleared only by restart - p_spi_instance->bytes_count = 0; - p_spi_instance->max_length = max_length; - spi_master_buffer_release(&(p_spi_instance->p_tx_buffer), &(p_spi_instance->tx_length)); - spi_master_buffer_release(&(p_spi_instance->p_rx_buffer), &(p_spi_instance->rx_length)); - /* Initialize buffers */ - spi_master_buffer_init(p_tx_buf, tx_buf_len, &(p_spi_instance->p_tx_buffer), - &(p_spi_instance->tx_length), &(p_spi_instance->tx_index)); - spi_master_buffer_init(p_rx_buf, rx_buf_len, &(p_spi_instance->p_rx_buffer), - &(p_spi_instance->rx_length), &(p_spi_instance->rx_index)); - nrf_gpio_pin_clear(p_spi_instance->pin_slave_select); - spi_master_send_initial_bytes(p_spi_instance); - spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_STARTED, max_length); - } - else - { - err_code = NRF_ERROR_INVALID_PARAM; - } - - NVIC_EnableIRQ(p_spi_instance->irq_type); - } - else - { - err_code = NRF_ERROR_BUSY; - } - - return err_code; - #else - return NRF_ERROR_NOT_SUPPORTED; - #endif -} - -#ifdef _SPI_5W_ - -/** - * @brief Function for aborting transfer - */ -uint32_t spi_master_abort(const spi_master_hw_instance_t spi_master_hw_instance) -{ - spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); - - NVIC_DisableIRQ(p_spi_instance->irq_type); - - if (p_spi_instance->state == SPI_MASTER_STATE_BUSY) - { - //set_flag - but only when there are events pending - //ignore when in IDLE - must be able to restart a completed transfer - p_spi_instance->abort_flag = true; - } - NVIC_EnableIRQ(p_spi_instance->irq_type); - return NRF_SUCCESS; -} - -/** - * @brief Function for restarting transfer - */ -uint32_t spi_master_restart(const spi_master_hw_instance_t spi_master_hw_instance) -{ - spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance); - - NVIC_DisableIRQ(p_spi_instance->irq_type); - spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_RESTARTED, 0); - p_spi_instance->state = SPI_MASTER_STATE_BUSY; - p_spi_instance->bytes_count = 0; - p_spi_instance->tx_index = 0; - p_spi_instance->rx_index = 0; - p_spi_instance->start_flag = true; - p_spi_instance->abort_flag = false; //you should force clearing abort flag - no other way for 1 byte transfer - nrf_gpio_pin_clear(p_spi_instance->pin_slave_select); - spi_master_send_initial_bytes(p_spi_instance); - NVIC_EnableIRQ(p_spi_instance->irq_type); - - return NRF_SUCCESS; -} - -static void spi_5W_master_event_handler(spi_master_evt_t evt) -{ - - switch (m_hook_state) - { - case HOOK_STATE_IDLE: - - if (evt.type == SPI_MASTER_EVT_TRANSFER_STARTED) - { - DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(0); - m_hook_state = HOOK_STATE_GUARDED; - m_ser_phy_event_handler(evt); - } - break; - - case HOOK_STATE_GUARDED: - - if (evt.type == SPI_MASTER_EVT_FIRST_BYTE_RECEIVED) - { - if (evt.data == 0) - { - DEBUG_EVT_SPI_MASTER_RAW_XFER_PASSED(0); - m_hook_state = HOOK_STATE_PASSING; - } - else - { - DEBUG_EVT_SPI_MASTER_RAW_XFER_ABORTED(0); - m_hook_state = HOOK_STATE_ABORTED; - (void)spi_master_abort(m_spi_master_hw_instance); - } - } - break; - - case HOOK_STATE_ABORTED: - - if ((evt.type == SPI_MASTER_EVT_TRANSFER_ABORTED) || - (evt.type == SPI_MASTER_EVT_TRANSFER_COMPLETED)) - { - DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(0); - m_hook_state = HOOK_STATE_RESTARTED; - (void)spi_master_restart(m_spi_master_hw_instance); - } - break; - - case HOOK_STATE_RESTARTED: - - if (evt.type == SPI_MASTER_EVT_TRANSFER_RESTARTED) - { - DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(0); - m_hook_state = HOOK_STATE_GUARDED; - } - break; - - case HOOK_STATE_PASSING: - - if (evt.type == SPI_MASTER_EVT_TRANSFER_COMPLETED) - { - m_hook_state = HOOK_STATE_IDLE; - m_ser_phy_event_handler(evt); //this is the only way to get a signal from complete transaction - } - break; - - default: - break; - } -} - -void spi_5W_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance, - spi_master_event_handler_t event_handler) -{ - m_ser_phy_event_handler = event_handler; - m_spi_master_hw_instance = spi_master_hw_instance; - m_hook_state = HOOK_STATE_IDLE; - spi_master_evt_handler_reg(spi_master_hw_instance, spi_5W_master_event_handler); - return; -} - -#endif - -/** @} */ diff --git a/components/serialization/common/transport/ser_phy/spi_5W_master.h b/components/serialization/common/transport/ser_phy/spi_5W_master.h deleted file mode 100644 index 940db8b..0000000 --- a/components/serialization/common/transport/ser_phy/spi_5W_master.h +++ /dev/null @@ -1,170 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 APP_SPI_MASTER_H -#define APP_SPI_MASTER_H - -#include -#include -#include "boards.h" - -#define _SPI_5W_ - -/**@brief Struct containing configuration parameters of the SPI master. */ -typedef struct -{ - uint32_t SPI_Freq; /**< SPI frequency. */ - uint32_t SPI_Pin_SCK; /**< SCK pin number. */ - uint32_t SPI_Pin_MISO; /**< MISO pin number. */ - uint32_t SPI_Pin_MOSI; /**< MOSI pin number .*/ - uint32_t SPI_Pin_SS; /**< Slave select pin number. */ - uint8_t SPI_ORDER; /**< Bytes order MSBFIRST or LSBFIRST. */ - uint8_t SPI_CPOL; /**< Serial clock polarity ACTIVEHIGH or ACTIVELOW. */ - uint8_t SPI_CPHA; /**< Serial clock phase LEADING or TRAILING. */ - } spi_master_config_t; - -/**@brief SPI master driver events types. */ -typedef enum -{ - SPI_MASTER_EVT_TRANSFER_STARTED = 0, /**< An event indicating that transfer has been started */ - SPI_MASTER_EVT_TRANSFER_COMPLETED, /**< An event indicating that transfer has been completed */ - SPI_MASTER_EVT_TRANSFER_ABORTED, /**< An event indicating that transfer has been aborted */ - SPI_MASTER_EVT_TRANSFER_RESTARTED, /**< An event indicating that transfer has been resumed */ - SPI_MASTER_EVT_FIRST_BYTE_RECEIVED, /**< An event indicating end of one byte transfer */ - SPI_MASTER_EVT_TYPE_MAX /**< Enumeration upper bound. */ -} spi_master_evt_type_t; - -/**@brief Struct containing parameters of the SPI MASTER event */ - typedef struct - { - spi_master_evt_type_t type; /**< Type of an event */ - uint16_t data; /**< event data - context dependent */ - } spi_master_evt_t; - - /**@brief SPI MASTER internal states types. */ - typedef enum - { - SPI_MASTER_STATE_DISABLED, /**< A state indicating that SPI master is disabled. */ - SPI_MASTER_STATE_BUSY, /**< A state indicating that SPI master is sending now. */ - SPI_MASTER_STATE_ABORTED, - SPI_MASTER_STATE_IDLE /**< A state indicating that SPI master is idle now. */ - } spi_master_state_t; - - /**@brief Instances of SPI master module. */ - typedef enum - { - #ifdef SPI_MASTER_0_ENABLE - SPI_MASTER_0, /**< A instance of SPI master 0. */ - #endif - - #ifdef SPI_MASTER_1_ENABLE - SPI_MASTER_1, /**< A instance of SPI master 1. */ - #endif - - SPI_MASTER_HW_ENABLED_COUNT /**< A number of enabled instances of SPI master. */ - } spi_master_hw_instance_t; - -/**@brief Type of generic callback function handler to be used by all SPI MASTER driver events. - * - * @param[in] spi_master_evt SPI MASTER driver event. - */ -typedef void (*spi_master_event_handler_t) (spi_master_evt_t spi_master_evt); - - -/**@brief Function for opening and initializing a SPI master driver. - * - * @note Function initializes SPI master hardware and internal module states, unregister events callback. - * - * @warning If the function has been already called, the function @ref spi_master_close has to be - * called before spi_master_open can be called again. - * - * @param[in] spi_master_hw_instance Instance of SPI master module. - * @param[in] p_spi_master_config Pointer to configuration structure which will be used - * to initialize SPI MASTER hardware. - * - * @retval NRF_SUCCESS Operation success. - * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. - * To call it again the function @ref spi_master_close - * has to be called previously. - * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied. - */ -uint32_t spi_master_open(const spi_master_hw_instance_t spi_master_hw_instance, - spi_master_config_t const * const p_spi_master_config); - - -/**@brief Function for closing a SPI MASTER driver. - * - * @note Function disable hardware, reset internal module states and unregister events callback - * function. - * - * @param[in] spi_master_hw_instance A instance of SPI master. - */ -void spi_master_close(const spi_master_hw_instance_t spi_master_hw_instance); - - -/**@brief Function for transferring data between SPI master and SPI slave - * - * @note Function registers buffers pointed by p_tx_buf and p_rx_buf parameters, after that starts transmission. - * Function generates an event of type @ref SPI_MASTER_EVT_TRANSFER_STARTED when transfer has been started - * and @ref SPI_MASTER_EVT_TRANSFER_COMPLETED when transfer has been completed. - * - * @param[in] spi_master_hw_instance Instance of SPI master module. - * @param[in] p_tx_buf Pointer to a transmit buffer. - * @param[in] tx_buf_len Number of octets to the transfer. - * @param[out] p_rx_buf Pointer to a receive buffer. - * @param[in] rx_buf_len Number of octets to be received. - * - * @retval NRF_SUCCESS Operation success. Packet was registered to the transmission - * and event will be send upon transmission completion. - * @retval NRF_ERROR_BUSY Operation failure. Transmitting of a data is in progress. - */ - uint32_t spi_master_send_recv(const spi_master_hw_instance_t spi_master_hw_instance, - uint8_t * const p_tx_buf, const uint16_t tx_buf_len, - uint8_t * const p_rx_buf, const uint16_t rx_buf_len); - - -/**@brief Function for registration event handler. -* -* @note Function registers a event handler to be used by SPI MASTER driver for sending events. -* @ref SPI_MASTER_EVT_TRANSFER_STARTED and @ref SPI_MASTER_EVT_TRANSFER_COMPLETED. -* -* @param[in] spi_master_hw_instance Instance of SPI master module. -* @param[in] event_handler Generic callback function handler to be used -* by all SPI master driver events. -*/ -void spi_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance, - spi_master_event_handler_t event_handler); - - -/**@brief Function for getting current state of the SPI master driver. - * - * @note Function gets current state of the SPI master driver. - * - * @param[in] spi_master_hw_instance Instance of SPI master module. - * - * @retval SPI_MASTER_STATE_DISABLED SPI MASTER is disabled. - * @retval SPI_MASTER_STATE_BUSY SPI_MASTER is sending now. - * @retval SPI_MASTER_STATE_IDLE SPI_MASTER is idle now. - */ -spi_master_state_t spi_master_get_state(const spi_master_hw_instance_t spi_master_hw_instance); - -#ifdef _SPI_5W_ - -uint32_t spi_master_abort(const spi_master_hw_instance_t spi_master_hw_instance); - -uint32_t spi_master_restart(const spi_master_hw_instance_t spi_master_hw_instance); - -void spi_5W_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance, - spi_master_event_handler_t event_handler); -#endif - -#endif diff --git a/components/serialization/common/transport/ser_phy_debug_comm.h b/components/serialization/common/transport/ser_phy_debug_comm.h index a694ec3..9eceeb2 100644 --- a/components/serialization/common/transport/ser_phy_debug_comm.h +++ b/components/serialization/common/transport/ser_phy_debug_comm.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SER_PHY_DEBUG_COMM_H__ @@ -34,7 +62,11 @@ #define DEBUG_EVT_TX_REQ(data) #else -#include "stdint.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif //Low level hardware events typedef enum @@ -76,7 +108,7 @@ void debug_evt(hci_dbg_evt_type_t evt, uint32_t data); #define DEBUG_EVT(event_type, data) \ do { \ debug_evt(event_type, data); \ -} while(0); +} while (0); #define DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(data) \ @@ -164,4 +196,9 @@ do { \ #endif // SER_PHY_HCI_DEBUG_ENABLE + +#ifdef __cplusplus +} +#endif + #endif // SER_PHY_DEBUG_COMM_H__ diff --git a/components/serialization/connectivity/codecs/common/ble_dtm_conn.h b/components/serialization/connectivity/codecs/common/ble_dtm_conn.h index a1b47b5..4b0d2fd 100644 --- a/components/serialization/connectivity/codecs/common/ble_dtm_conn.h +++ b/components/serialization/connectivity/codecs/common/ble_dtm_conn.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_DTM_CONN_H__ @@ -29,19 +57,23 @@ * @{ * @ingroup ser_conn_common_codecs * - * @brief DTM Connectivity command request decoder and command response encoder + * @brief DTM Connectivity command request decoder and command response encoder. */ #include "dtm_uart.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Decodes @ref ble_dtm_init command request. * - * @sa @ref nrf51_dtm_init_encoding_sec for packet format, + * @sa @ref encoding_data for packet format, * @ref ble_dtm_init_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[in] p_comm_params Pointer to the structure with DTM Uart configuration. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[in] p_comm_params Pointer to the structure with DTM UART configuration. * * @retval NRF_SUCCESS Decoding success. @@ -55,7 +87,7 @@ uint32_t ble_dtm_init_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref ble_dtm_init command response. * - * @sa @ref nrf51_dtm_init_encoding_sec for packet format. + * @sa @ref encoding_data for packet format. * @ref ble_dtm_init_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. @@ -73,5 +105,10 @@ uint32_t ble_dtm_init_rsp_enc(uint32_t return_code, uint32_t * const p_buf_len); /** @} */ + +#ifdef __cplusplus +} +#endif + #endif // BLE_DTM_CONN_H__ diff --git a/components/serialization/connectivity/codecs/common/ble_dtm_init.c b/components/serialization/connectivity/codecs/common/ble_dtm_init.c index 0af4f99..4476da5 100644 --- a/components/serialization/connectivity/codecs/common/ble_dtm_init.c +++ b/components/serialization/connectivity/codecs/common/ble_dtm_init.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_dtm_conn.h" diff --git a/components/serialization/connectivity/codecs/common/conn_mw.c b/components/serialization/connectivity/codecs/common/conn_mw.c index 9fcd291..f30204d 100644 --- a/components/serialization/connectivity/codecs/common/conn_mw.c +++ b/components/serialization/connectivity/codecs/common/conn_mw.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include diff --git a/components/serialization/connectivity/codecs/common/conn_mw.h b/components/serialization/connectivity/codecs/common/conn_mw.h index 378a96f..397a9a3 100644 --- a/components/serialization/connectivity/codecs/common/conn_mw.h +++ b/components/serialization/connectivity/codecs/common/conn_mw.h @@ -1,22 +1,54 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 _CONN_MW_H #define _CONN_MW_H #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Connectivity Middleware dispatcher function * - * @details It will handle decode the opcode from RX buffer and based on the opcode it will search + * @details It will handle decode the opcode from the RX buffer and based on the opcode it will search * for registered handler. Handler is called once it is found. * * @param[in] p_rx_buf Pointer to input buffer. @@ -35,4 +67,9 @@ uint32_t conn_mw_handler (uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len); + +#ifdef __cplusplus +} +#endif + #endif //_CONN_MW_H diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble.h b/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble.h deleted file mode 100644 index d4eba18..0000000 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble.h +++ /dev/null @@ -1,178 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_BLE_H -#define _CONN_MW_BLE_H - -#include - -/**@brief Handles @ref sd_ble_tx_buffer_count_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_tx_buffer_count_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_uuid_vs_add command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_uuid_vs_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_uuid_decode command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_uuid_decode(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_uuid_encode command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_uuid_encode(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_version_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_version_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_enable command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_enable(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_opt_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_opt_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_opt_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_user_mem_reply command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); -#endif //_CONN_MW_BLE_H diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gap.c b/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gap.c deleted file mode 100644 index 06ce2ad..0000000 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gap.c +++ /dev/null @@ -1,831 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "conn_mw_ble_gap.h" -#include "ble_serialization.h" -#include "ser_config.h" -#include "conn_ble_gap_sec_keys.h" - -extern ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS]; - -uint32_t conn_mw_ble_gap_address_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t addr_cycle_mode; - - ble_gap_addr_t addr; - ble_gap_addr_t * p_addr = &addr; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_address_set_req_dec(p_rx_buf, rx_buf_len, &addr_cycle_mode, &p_addr); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_address_set(addr_cycle_mode, p_addr); - - err_code = ble_gap_address_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_addr_t addr; - ble_gap_addr_t * p_addr = &addr; - - ble_gap_addr_t * pp_addr_tab[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t * pp_irk_tab[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - - ble_gap_whitelist_t whitelist; - whitelist.addr_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; - whitelist.pp_addrs = pp_addr_tab; - whitelist.irk_count = BLE_GAP_WHITELIST_IRK_MAX_COUNT; - whitelist.pp_irks = pp_irk_tab; - - ble_gap_scan_params_t scan_params; - scan_params.p_whitelist = &whitelist; - ble_gap_scan_params_t * p_scan_params = &scan_params; - - ble_gap_conn_params_t conn_params; - ble_gap_conn_params_t * p_conn_params = &conn_params; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_connect_req_dec(p_rx_buf, rx_buf_len, &p_addr, &p_scan_params, &p_conn_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_connect(p_addr, p_scan_params, p_conn_params); - - err_code = ble_gap_connect_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_connect_cancel(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - sd_err_code = sd_ble_gap_connect_cancel(); - - err_code = ble_gap_connect_cancel_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_address_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_addr_t addr; - ble_gap_addr_t * p_addr = &addr; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_address_get_req_dec(p_rx_buf, rx_buf_len, &p_addr); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_address_get(p_addr); - - err_code = ble_gap_address_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_addr); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_adv_data_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t data[BLE_GAP_ADV_MAX_SIZE]; - uint8_t * p_data = data; - uint8_t dlen = sizeof (data); - - uint8_t sr_data[BLE_GAP_ADV_MAX_SIZE]; - uint8_t * p_sr_data = sr_data; - uint8_t srdlen = sizeof (sr_data); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_adv_data_set_req_dec(p_rx_buf, - rx_buf_len, - &p_data, - &dlen, - &p_sr_data, - &srdlen); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_adv_data_set(p_data, dlen, p_sr_data, srdlen); - - err_code = ble_gap_adv_data_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - ble_gap_addr_t * p_addresses[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_addr_t addresses[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t * p_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - ble_gap_irk_t irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - ble_gap_addr_t peer_addr; - ble_gap_whitelist_t whitelist; - ble_gap_adv_params_t adv_params; - ble_gap_adv_params_t * p_adv_params; - - uint32_t i = 0; - - for (i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++) - { - p_addresses[i] = &(addresses[i]); - } - - for (i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++) - { - p_irks[i] = &(irks[i]); - } - - whitelist.pp_addrs = &p_addresses[0]; - whitelist.pp_irks = &p_irks[0]; - - adv_params.p_peer_addr = &peer_addr; - adv_params.p_whitelist = &whitelist; - - p_adv_params = &adv_params; - - err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_adv_start(p_adv_params); - - err_code = ble_gap_adv_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_adv_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - sd_err_code = sd_ble_gap_adv_stop(); - - err_code = ble_gap_adv_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_conn_param_update(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - ble_gap_conn_params_t conn_params; - ble_gap_conn_params_t * p_conn_params = &conn_params; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_conn_param_update_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_conn_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_conn_param_update(conn_handle, p_conn_params); - - err_code = ble_gap_conn_param_update_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_disconnect(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint8_t hci_status_code; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_disconnect_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &hci_status_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_disconnect(conn_handle, hci_status_code); - - err_code = ble_gap_disconnect_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_tx_power_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - int8_t tx_power; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_tx_power_set_req_dec(p_rx_buf, rx_buf_len, &tx_power); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_tx_power_set(tx_power); - - err_code = ble_gap_tx_power_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_appearance_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t appearance; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_appearance_set_req_dec(p_rx_buf, rx_buf_len, &appearance); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_appearance_set(appearance); - - err_code = ble_gap_appearance_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_appearance_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t appearance; - uint16_t * p_appearance = &appearance; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_appearance_get_req_dec(p_rx_buf, rx_buf_len, &p_appearance); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_appearance_get(p_appearance); - - err_code = ble_gap_appearance_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_appearance); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - - -uint32_t conn_mw_ble_gap_ppcp_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_conn_params_t conn_params; - ble_gap_conn_params_t * p_conn_params = &conn_params; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_ppcp_set_req_dec(p_rx_buf, rx_buf_len, &p_conn_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_ppcp_set(p_conn_params); - - err_code = ble_gap_ppcp_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_ppcp_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_conn_params_t conn_params; - ble_gap_conn_params_t * p_conn_params = &conn_params; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_ppcp_get_req_dec(p_rx_buf, rx_buf_len, &p_conn_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_ppcp_get(p_conn_params); - - err_code = ble_gap_ppcp_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_conn_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - - -uint32_t conn_mw_ble_gap_device_name_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint8_t dev_name[BLE_GAP_DEVNAME_MAX_LEN]; - uint8_t * p_dev_name = dev_name; - - uint16_t len; - uint16_t * p_len = &len; - - err_code = ble_gap_device_name_get_req_dec(p_rx_buf, rx_buf_len, &p_dev_name, &p_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_device_name_get(p_dev_name, p_len); - - err_code = ble_gap_device_name_get_rsp_enc(sd_err_code, p_dev_name, len, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_device_name_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - ble_gap_conn_sec_mode_t write_perm; - ble_gap_conn_sec_mode_t * p_write_perm = &write_perm; - - uint8_t dev_name[BLE_GAP_DEVNAME_MAX_LEN]; - uint8_t * p_dev_name = dev_name; - - uint16_t len = BLE_GAP_DEVNAME_MAX_LEN; - - err_code = ble_gap_device_name_set_req_dec(p_rx_buf, - rx_buf_len, - &p_write_perm, - &p_dev_name, - &len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_device_name_set(p_write_perm, p_dev_name, len); - - err_code = ble_gap_device_name_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_authenticate(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - - ble_gap_sec_params_t sec_params; - ble_gap_sec_params_t * p_sec_params = &sec_params; - - err_code = ble_gap_authenticate_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sec_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params); - - err_code = ble_gap_authenticate_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - uint32_t sec_tab_index = 0; - - uint16_t * p_conn_handle; - uint8_t sec_status; - - ble_gap_sec_params_t sec_params; - ble_gap_sec_params_t * p_sec_params = &sec_params; - - // Allocate global security context for soft device - err_code = conn_ble_gap_sec_context_create(&sec_tab_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_conn_handle = &(m_conn_keys_table[sec_tab_index].conn_handle); - - // Set up global structure for command decoder - ble_gap_sec_keyset_t * p_sec_keyset = &(m_conn_keys_table[sec_tab_index].keyset); - - p_sec_keyset->keys_periph.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_periph); - p_sec_keyset->keys_periph.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_periph); - p_sec_keyset->keys_periph.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_periph); - p_sec_keyset->keys_central.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_central); - p_sec_keyset->keys_central.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_central); - p_sec_keyset->keys_central.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_central); - - err_code = ble_gap_sec_params_reply_req_dec(p_rx_buf, - rx_buf_len, - p_conn_handle, - &sec_status, - &p_sec_params, - &p_sec_keyset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_sec_params_reply(*p_conn_handle, sec_status, p_sec_params, p_sec_keyset); - - err_code = ble_gap_sec_params_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sec_keyset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_auth_key_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - uint8_t key_type; - - uint8_t key[BLE_GAP_SEC_KEY_LEN]; - uint8_t * p_key = key; - - err_code = ble_gap_auth_key_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &key_type, &p_key); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_auth_key_reply(conn_handle, key_type, p_key); - - err_code = ble_gap_auth_key_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_sec_info_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - - ble_gap_enc_info_t enc_info; - ble_gap_enc_info_t * p_enc_info = &enc_info; - - ble_gap_irk_t id_info; - ble_gap_irk_t * p_id_info = &id_info; - - ble_gap_sign_info_t sign_info; - ble_gap_sign_info_t * p_sign_info = &sign_info; - - err_code = ble_gap_sec_info_reply_req_dec(p_rx_buf, - rx_buf_len, - &conn_handle, - &p_enc_info, - &p_id_info, - &p_sign_info); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_sec_info_reply(conn_handle, p_enc_info, p_id_info, p_sign_info); - - err_code = ble_gap_sec_info_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_conn_sec_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - - ble_gap_conn_sec_t conn_sec; - ble_gap_conn_sec_t * p_conn_sec = &conn_sec; - - err_code = ble_gap_conn_sec_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_conn_sec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_conn_sec_get(conn_handle, p_conn_sec); - - err_code = ble_gap_conn_sec_get_rsp_enc(sd_err_code, p_conn_sec, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_rssi_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - uint8_t threshold_dbm; - uint8_t skip_count; - - err_code = ble_gap_rssi_start_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &threshold_dbm, &skip_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_rssi_start(conn_handle, threshold_dbm, skip_count); - - err_code = ble_gap_rssi_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_rssi_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - - err_code = ble_gap_rssi_stop_req_dec(p_rx_buf, rx_buf_len, &conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_rssi_stop(conn_handle); - - err_code = ble_gap_rssi_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_encrypt(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - - ble_gap_master_id_t master_id; - ble_gap_master_id_t *p_master_id = &master_id; - - ble_gap_enc_info_t enc_info; - ble_gap_enc_info_t *p_enc_info = &enc_info; - - err_code = ble_gap_encrypt_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_master_id, &p_enc_info); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_encrypt(conn_handle, p_master_id, p_enc_info); - - err_code = ble_gap_encrypt_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_rssi_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - int8_t rssi; - int8_t * p_rssi = &rssi; - - err_code = ble_gap_rssi_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_rssi); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_rssi_get(conn_handle, p_rssi); - - err_code = ble_gap_rssi_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, rssi); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_addr_t * pp_addr_tab[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t * pp_irk_tab[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - - ble_gap_whitelist_t whitelist; - whitelist.addr_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; - whitelist.pp_addrs = pp_addr_tab; - whitelist.irk_count = BLE_GAP_WHITELIST_IRK_MAX_COUNT; - whitelist.pp_irks = pp_irk_tab; - - ble_gap_scan_params_t scan_params; - scan_params.p_whitelist = &whitelist; - ble_gap_scan_params_t * p_scan_params = &scan_params; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_scan_start_req_dec(p_rx_buf, rx_buf_len, &p_scan_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_scan_start(p_scan_params); - - err_code = ble_gap_scan_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_scan_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - sd_err_code = sd_ble_gap_scan_stop(); - - err_code = ble_gap_scan_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gap.h b/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gap.h deleted file mode 100644 index 2aad67a..0000000 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gap.h +++ /dev/null @@ -1,504 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_BLE_GAP_H -#define _CONN_MW_BLE_GAP_H - -#include - -/**@brief Handles @ref sd_ble_gap_address_set command request and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_address_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_address_get command request and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_address_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_adv_data_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_adv_data_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_adv_start command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_adv_stop command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_adv_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_conn_param_update command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_conn_param_update(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_disconnect command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_disconnect(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_tx_power_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_tx_power_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_appearance_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_appearance_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_appearance_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_appearance_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_ppcp_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_ppcp_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_ppcp_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_ppcp_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_device_name_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_device_name_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_device_name_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_device_name_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_authenticate command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_authenticate(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_sec_params_reply command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_auth_key_reply command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_auth_key_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_sec_info_reply command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_sec_info_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_conn_sec_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_conn_sec_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_rssi_start command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_rssi_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_rssi_stop command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_rssi_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_rssi_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_rssi_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_connect command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_connect_cancel command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_connect_cancel(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_encrypt command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ - -uint32_t conn_mw_ble_gap_encrypt(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_scan_start command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_scan_stop command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_scan_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -#endif //_CONN_MW_BLE_GAP_H diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gattc.c b/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gattc.c deleted file mode 100644 index d41ac4d..0000000 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gattc.c +++ /dev/null @@ -1,293 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "ble_gattc_conn.h" -#include "conn_mw_ble_gattc.h" -#include "ble_serialization.h" - -uint32_t conn_mw_ble_gattc_primary_services_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t start_handle; - ble_uuid_t srvc_uuid; - ble_uuid_t * p_srvc_uuid = &srvc_uuid; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_primary_services_discover_req_dec(p_rx_buf, - rx_buf_len, - &conn_handle, - &start_handle, - &p_srvc_uuid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_primary_services_discover(conn_handle, start_handle, p_srvc_uuid); - - err_code = ble_gattc_primary_services_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_relationships_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - ble_gattc_handle_range_t handle_range; - ble_gattc_handle_range_t * p_handle_range = &handle_range; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_relationships_discover_req_dec(p_rx_buf, rx_buf_len, - &conn_handle, &p_handle_range); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_relationships_discover(conn_handle, p_handle_range); - - err_code = ble_gattc_relationships_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_characteristics_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - ble_gattc_handle_range_t handle_range; - ble_gattc_handle_range_t * p_handle_range = &handle_range; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_characteristics_discover_req_dec(p_rx_buf, rx_buf_len, - &conn_handle, &p_handle_range); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_characteristics_discover(conn_handle, p_handle_range); - - err_code = ble_gattc_characteristics_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_descriptors_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - ble_gattc_handle_range_t handle_range; - ble_gattc_handle_range_t * p_handle_range = &handle_range; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_descriptors_discover_req_dec(p_rx_buf, rx_buf_len, - &conn_handle, &p_handle_range); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_descriptors_discover(conn_handle, p_handle_range); - - err_code = ble_gattc_descriptors_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_char_value_by_uuid_read(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - - ble_uuid_t uuid = {0}; - ble_uuid_t * p_uuid = &uuid; - - ble_gattc_handle_range_t handle_range; - ble_gattc_handle_range_t * p_handle_range = &handle_range; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_char_value_by_uuid_read_req_dec(p_rx_buf, rx_buf_len, - &conn_handle, &p_uuid, &p_handle_range); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_char_value_by_uuid_read(conn_handle, p_uuid, p_handle_range); - - err_code = ble_gattc_char_value_by_uuid_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_read(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t * p_conn_handle = &conn_handle; - - uint16_t handle; - uint16_t * p_handle = &handle; - - uint16_t offset; - uint16_t * p_offset = &offset; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_read_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_handle, p_offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_read(conn_handle, handle, offset); - - err_code = ble_gattc_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_char_values_read(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t * p_conn_handle = &conn_handle; - - uint16_t handles[BLE_GATTC_HANDLE_COUNT_LEN_MAX]; - uint16_t * p_handles = handles; - - uint16_t handle_count = BLE_GATTC_HANDLE_COUNT_LEN_MAX; - uint16_t * p_handle_count = &handle_count; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_char_values_read_req_dec(p_rx_buf, - rx_buf_len, - p_conn_handle, - &p_handles, - p_handle_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_char_values_read(conn_handle, p_handles, handle_count); - - err_code = ble_gattc_char_values_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_write(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t * p_conn_handle = &conn_handle; - - uint8_t value[BLE_GATTC_WRITE_P_VALUE_LEN_MAX]; - - ble_gattc_write_params_t write_params = {0}; - ble_gattc_write_params_t * p_write_params = &write_params; - - p_write_params->len = BLE_GATTC_WRITE_P_VALUE_LEN_MAX; - p_write_params->p_value = value; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_write_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &p_write_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_write(conn_handle, p_write_params); - - err_code = ble_gattc_write_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_hv_confirm(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - uint16_t * p_conn_handle = &conn_handle; - - uint16_t handle; - uint16_t * p_handle = &handle; - - err_code = ble_gattc_hv_confirm_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_hv_confirm(conn_handle, handle); - - err_code = ble_gattc_hv_confirm_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gattc.h b/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gattc.h deleted file mode 100644 index 403ae11..0000000 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gattc.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_BLE_GATTC_H - #define _CONN_MW_BLE_GATTC_H - -#include - -/**@brief Handles @ref sd_ble_gattc_primary_services_discover command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_primary_services_discover (uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_relationships_discover command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_relationships_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_characteristics_discover command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_characteristics_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_descriptors_discover command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_descriptors_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_char_value_by_uuid_read command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_char_value_by_uuid_read(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_read command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_read (uint8_t const *const rx_buf, - uint32_t rx_buf_len, - uint8_t *const tx_buf, - uint32_t *const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_char_values_read command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_char_values_read (uint8_t const *const rx_buf, - uint32_t rx_buf_len, - uint8_t *const tx_buf, - uint32_t *const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_write command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_write (uint8_t const *const rx_buf, - uint32_t rx_buf_len, - uint8_t *const tx_buf, - uint32_t *const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_hv_confirm command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_hv_confirm (uint8_t const *const rx_buf, - uint32_t rx_buf_len, - uint8_t *const tx_buf, - uint32_t *const p_tx_buf_len); - - -#endif //_CONN_MW_BLE_GATTC_H diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_l2cap.c b/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_l2cap.c deleted file mode 100644 index a3134b0..0000000 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_l2cap.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "ble_l2cap_conn.h" -#include "conn_mw_ble_l2cap.h" -#include "ble_serialization.h" - -uint32_t conn_mw_ble_l2cap_cid_register(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t cid; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_l2cap_cid_register_req_dec(p_rx_buf, rx_buf_len, &cid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_l2cap_cid_register(cid); - - err_code = ble_l2cap_cid_register_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_l2cap_cid_unregister(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t cid; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_l2cap_cid_unregister_req_dec(p_rx_buf, rx_buf_len, &cid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_l2cap_cid_unregister(cid); - - err_code = ble_l2cap_cid_unregister_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_l2cap_tx(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - ble_l2cap_header_t l2cap_header; - ble_l2cap_header_t * p_l2cap_header = &l2cap_header; - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - uint8_t const * p_data = NULL; - - err_code = ble_l2cap_tx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_l2cap_header, &p_data); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_l2cap_tx(conn_handle, p_l2cap_header, p_data); - - err_code = ble_l2cap_tx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_l2cap.h b/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_l2cap.h deleted file mode 100644 index dd6ac2e..0000000 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_l2cap.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_BLE_L2CAP_H_ -#define _CONN_MW_BLE_L2CAP_H_ - -#include - -/**@brief Handles @ref sd_ble_l2cap_cid_register command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_l2cap_cid_register(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_l2cap_cid_unregister command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_l2cap_cid_unregister(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_l2cap_tx command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_l2cap_tx(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -#endif diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_items.c b/components/serialization/connectivity/codecs/s110/middleware/conn_mw_items.c deleted file mode 100644 index 65fef73..0000000 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_items.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "conn_mw_nrf_soc.h" -#include "conn_mw_ble.h" -#include "conn_mw_ble_l2cap.h" -#include "conn_mw_ble_gap.h" -#include "conn_mw_ble_gatts.h" -#include "conn_mw_ble_gattc.h" - -/**@brief Connectivity middleware handlers table. */ -static const conn_mw_item_t conn_mw_item[] = { - //Functions from nrf_soc.h - {SD_POWER_SYSTEM_OFF, conn_mw_power_system_off}, - {SD_TEMP_GET, conn_mw_temp_get}, - //Functions from ble.h - {SD_BLE_TX_BUFFER_COUNT_GET, conn_mw_ble_tx_buffer_count_get}, - {SD_BLE_UUID_VS_ADD, conn_mw_ble_uuid_vs_add}, - {SD_BLE_UUID_DECODE, conn_mw_ble_uuid_decode}, - {SD_BLE_UUID_ENCODE, conn_mw_ble_uuid_encode}, - {SD_BLE_VERSION_GET, conn_mw_ble_version_get}, - {SD_BLE_ENABLE, conn_mw_ble_enable}, - {SD_BLE_OPT_GET, conn_mw_ble_opt_get}, - {SD_BLE_OPT_SET, conn_mw_ble_opt_set}, - {SD_BLE_USER_MEM_REPLY, conn_mw_ble_user_mem_reply}, - //Functions from ble_l2cap.h - {SD_BLE_L2CAP_CID_REGISTER, conn_mw_ble_l2cap_cid_register}, - {SD_BLE_L2CAP_CID_UNREGISTER, conn_mw_ble_l2cap_cid_unregister}, - {SD_BLE_L2CAP_TX, conn_mw_ble_l2cap_tx}, - //Functions from ble_gap.h - {SD_BLE_GAP_ADDRESS_SET, conn_mw_ble_gap_address_set}, - {SD_BLE_GAP_CONNECT, conn_mw_ble_gap_connect}, - {SD_BLE_GAP_CONNECT_CANCEL, conn_mw_ble_gap_connect_cancel}, - {SD_BLE_GAP_ADDRESS_GET, conn_mw_ble_gap_address_get}, - {SD_BLE_GAP_ADV_DATA_SET, conn_mw_ble_gap_adv_data_set}, - {SD_BLE_GAP_ADV_START, conn_mw_ble_gap_adv_start}, - {SD_BLE_GAP_ADV_STOP, conn_mw_ble_gap_adv_stop}, - {SD_BLE_GAP_CONN_PARAM_UPDATE, conn_mw_ble_gap_conn_param_update}, - {SD_BLE_GAP_DISCONNECT, conn_mw_ble_gap_disconnect}, - {SD_BLE_GAP_TX_POWER_SET, conn_mw_ble_gap_tx_power_set}, - {SD_BLE_GAP_APPEARANCE_SET, conn_mw_ble_gap_appearance_set}, - {SD_BLE_GAP_APPEARANCE_GET, conn_mw_ble_gap_appearance_get}, - {SD_BLE_GAP_PPCP_SET, conn_mw_ble_gap_ppcp_set}, - {SD_BLE_GAP_PPCP_GET, conn_mw_ble_gap_ppcp_get}, - {SD_BLE_GAP_DEVICE_NAME_SET, conn_mw_ble_gap_device_name_set}, - {SD_BLE_GAP_DEVICE_NAME_GET, conn_mw_ble_gap_device_name_get}, - {SD_BLE_GAP_AUTHENTICATE, conn_mw_ble_gap_authenticate}, - {SD_BLE_GAP_SEC_PARAMS_REPLY, conn_mw_ble_gap_sec_params_reply}, - {SD_BLE_GAP_AUTH_KEY_REPLY, conn_mw_ble_gap_auth_key_reply}, - {SD_BLE_GAP_SEC_INFO_REPLY, conn_mw_ble_gap_sec_info_reply}, - {SD_BLE_GAP_CONN_SEC_GET, conn_mw_ble_gap_conn_sec_get}, - {SD_BLE_GAP_RSSI_START, conn_mw_ble_gap_rssi_start}, - {SD_BLE_GAP_RSSI_STOP, conn_mw_ble_gap_rssi_stop}, - {SD_BLE_GAP_RSSI_GET, conn_mw_ble_gap_rssi_get}, - {SD_BLE_GAP_SCAN_START, conn_mw_ble_gap_scan_start}, - {SD_BLE_GAP_SCAN_START, conn_mw_ble_gap_scan_stop}, - //Functions from ble_gattc.h - {SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, conn_mw_ble_gattc_primary_services_discover}, - {SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, conn_mw_ble_gattc_relationships_discover}, - {SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, conn_mw_ble_gattc_characteristics_discover}, - {SD_BLE_GATTC_DESCRIPTORS_DISCOVER, conn_mw_ble_gattc_descriptors_discover}, - {SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, conn_mw_ble_gattc_char_value_by_uuid_read}, - {SD_BLE_GATTC_READ, conn_mw_ble_gattc_read}, - {SD_BLE_GATTC_CHAR_VALUES_READ, conn_mw_ble_gattc_char_values_read}, - {SD_BLE_GATTC_WRITE, conn_mw_ble_gattc_write}, - {SD_BLE_GATTC_HV_CONFIRM, conn_mw_ble_gattc_hv_confirm}, - //Functions from ble_gatts.h - {SD_BLE_GATTS_SERVICE_ADD, conn_mw_ble_gatts_service_add}, - {SD_BLE_GATTS_INCLUDE_ADD, conn_mw_ble_gatts_include_add}, - {SD_BLE_GATTS_CHARACTERISTIC_ADD, conn_mw_ble_gatts_characteristic_add}, - {SD_BLE_GATTS_DESCRIPTOR_ADD, conn_mw_ble_gatts_descriptor_add}, - {SD_BLE_GATTS_VALUE_SET, conn_mw_ble_gatts_value_set}, - {SD_BLE_GATTS_VALUE_GET, conn_mw_ble_gatts_value_get}, - {SD_BLE_GATTS_HVX, conn_mw_ble_gatts_hvx}, - {SD_BLE_GATTS_SERVICE_CHANGED, conn_mw_ble_gatts_service_changed}, - {SD_BLE_GATTS_RW_AUTHORIZE_REPLY, conn_mw_ble_gatts_rw_authorize_reply}, - {SD_BLE_GATTS_SYS_ATTR_SET, conn_mw_ble_gatts_sys_attr_set}, - {SD_BLE_GATTS_SYS_ATTR_GET, conn_mw_ble_gatts_sys_attr_get}, -}; diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_nrf_soc.c b/components/serialization/connectivity/codecs/s110/middleware/conn_mw_nrf_soc.c deleted file mode 100644 index c9a7509..0000000 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_nrf_soc.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "nrf_soc_conn.h" -#include "conn_mw_nrf_soc.h" -#include "ble_serialization.h" - -uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - - err_code = power_system_off_req_dec(p_rx_buf, rx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = sd_power_system_off(); - /* There should be no return from sd_power_system_off() */ - - return err_code; -} - -uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - int32_t temperature; - int32_t * p_temperature = &temperature; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = temp_get_req_dec(p_rx_buf, rx_buf_len, &p_temperature); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_temp_get(p_temperature); - - err_code = temp_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_temperature); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_nrf_soc.h b/components/serialization/connectivity/codecs/s110/middleware/conn_mw_nrf_soc.h deleted file mode 100644 index ba4a973..0000000 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_nrf_soc.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 CONN_MW_NRF_SOC_H__ -#define CONN_MW_NRF_SOC_H__ - -#include - -/**@brief Handles @ref sd_power_system_off command request. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. - */ -uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_temp_get command request and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. - */ -uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -#endif diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_conn.h b/components/serialization/connectivity/codecs/s110/serializers/ble_conn.h deleted file mode 100644 index aa20aa9..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_conn.h +++ /dev/null @@ -1,447 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_CONN_H__ -#define BLE_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_conn Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s110_codecs - * - * @brief Connectivity command request decoders and command response encoders. - */ -#include "ble.h" - -/**@brief Decodes @ref sd_ble_tx_buffer_count_get command request. - * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format, - * @ref ble_tx_buffer_count_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_count Pointer to pointer to location for count. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_tx_buffer_count_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint8_t * * const pp_count); - -/**@brief Encodes @ref sd_ble_tx_buffer_count_get command response. - * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format. - * @ref ble_tx_buffer_count_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_count Pointer to count value. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_tx_buffer_count_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_count); - -/**@brief Event encoding dispatcher. - * - * The event encoding dispatcher will route the event packet to the correct encoder which in turn - * encodes the contents of the event and updates the \p p_buf buffer. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_NOT_SUPPORTED Event encoder is not implemented. - */ -uint32_t ble_event_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_version_get command request. - * - * @sa @ref nrf51_version_get_encoding for packet format, - * @ref ble_version_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_version Pointer to pointer to @ref ble_version_t address. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_version_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_version_t * * const pp_version); - -/**@brief Encodes @ref sd_ble_version_get command response. - * - * @sa @ref nrf51_version_get_encoding for packet format. - * @ref ble_version_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_version Pointer to @ref ble_version_t address. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_version_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_version_t const * const p_version); - - -/**@brief Decodes @ref sd_ble_opt_get command request. - * - * @sa @ref nrf51_opt_get_encoding for packet format, - * @ref ble_opt_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_opt_id Pointer to pointer to @ref ble_version_t address. - * @param[out] pp_opt Pointer to pointer to @ref ble_opt_t address. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t **const pp_opt ); - - -/**@brief Encodes @ref sd_ble_opt_get command response. - * - * @sa @ref nrf51_opt_get_encoding for packet format. - * @ref ble_opt_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] opt_id identifies type of ble_opt_t union - * @param[in] p_opt Pointer to @ref ble_opt_t union. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_opt_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint32_t opt_id, - ble_opt_t const * const p_opt); - - -/**@brief Decodes @ref sd_ble_opt_set command request. - * - * @sa @ref nrf51_opt_set_encoding for packet format, - * @ref ble_opt_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_opt_id Pointer to @ref ble_opt_t union type identifier. - * @param[out] pp_opt Pointer to pointer to @ref ble_opt_t union. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t **const pp_opt ); - - -/**@brief Encodes @ref sd_ble_opt_set command response. - * - * @sa @ref nrf51_opt_set_encoding for packet format. - * @ref ble_opt_set_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_opt_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - - -/**@brief Decodes @ref sd_ble_uuid_encode command request. - * - * @sa @ref nrf51_uuid_encode_encoding for packet format, - * @ref ble_uuid_encode_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_uuid Pointer to pointer to @ref ble_uuid_t structure. - * @param[out] pp_uuid_le_len Pointer to pointer to the length of encoded UUID. - * @param[out] pp_uuid_le Pointer to pointer to buffer where encoded UUID will be stored. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_uuid_t * * const pp_uuid, - uint8_t * * const pp_uuid_le_len, - uint8_t * * const pp_uuid_le); - -/**@brief Encodes @ref sd_ble_uuid_encode command response. - * - * @sa @ref nrf51_uuid_encode_encoding for packet format. - * @ref ble_uuid_encode_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] uuid_le_len Length of the encoded UUID. - * @param[in] p_uuid_le Pointer to the buffer with encoded UUID. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t uuid_le_len, - uint8_t const * const p_uuid_le); - -/**@brief Decodes @ref sd_ble_uuid_decode command request. - * - * @sa @ref nrf51_uuid_decode_encoding for packet format, - * @ref ble_uuid_decode_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] p_uuid_le_len Pointer to the length of encoded UUID. - * @param[out] pp_uuid_le Pointer to pointer to buffer where encoded UUID will be stored. - * @param[out] pp_uuid Pointer to pointer to @ref ble_uuid_t structure. - * \c It will be set to NULL if p_uuid is not present in the packet. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, - uint8_t * p_uuid_le_len, - uint8_t * * const pp_uuid_le, - ble_uuid_t * * const pp_uuid); - -/**@brief Encodes @ref sd_ble_uuid_decode command response. - * - * @sa @ref nrf51_uuid_decode_encoding for packet format. - * @ref ble_uuid_decode_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_uuid Pointer to the buffer with encoded UUID. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_uuid_t const * const p_uuid); - -/**@brief Decodes @ref sd_ble_uuid_vs_add command request. - * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format, - * @ref ble_uuid_vs_add_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] pp_uuid Pointer to pointer to UUID. - * \c It will be set to NULL if p_uuid is not present in the packet. - * @param[out] pp_uuid_type Pointer to pointer to UUID type. - * \c It will be set to NULL if p_uuid_type is not present in the packet. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf, - uint16_t buf_len, - ble_uuid128_t * * const pp_uuid, - uint8_t * * const pp_uuid_type); - -/**@brief Encodes @ref sd_ble_uuid_vs_add command response. - * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format. - * @ref ble_uuid_vs_add_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_uuid_type Pointer to the UUID type. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_uuid_type); - -/**@brief Decodes @ref sd_ble_enable command request. - * - * @sa @ref nrf51_enable_encoding for packet format, - * @ref ble_enable_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_ble_enable_params Pointer to pointer to ble_enable_params_t. - * \c It will be set to NULL if p_ble_enable_params is not present in the packet. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_enable_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_enable_params_t * * const pp_ble_enable_params); - -/**@brief Encodes @ref sd_ble_enable command response. - * - * @sa @ref nrf51_enable_encoding for packet format. - * @ref ble_enable_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_enable_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_user_mem_reply command request. - * - * @sa @ref nrf51_user_mem_reply_encoding for packet format, - * @ref ble_user_mem_reply_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] p_conn_handle Pointer to Connection Handle. - * @param[in,out] pp_block Pointer to pointer to ble_user_mem_block_t. - * \c It will be set to NULL if p_block is not present in the packet. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_user_mem_block_t * * const pp_block); - -/**@brief Encodes @ref sd_ble_user_mem_reply command response. - * - * @sa @ref nrf51_user_mem_reply_encoding for packet format. - * @ref ble_user_mem_reply_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Pre-decodes opt_id of @ref ble_opt_t for middleware. - * - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] packet_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in,out] p_opt_id Pointer to opt_id which identifies type of @ref ble_opt_t union. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id); - -/** @} */ - -#endif diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_enable.c b/components/serialization/connectivity/codecs/s110/serializers/ble_enable.c deleted file mode 100644 index da81437..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_enable.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_enable_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_enable_params_t * * const pp_ble_enable_params) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_ble_enable_params); - SER_ASSERT_NOT_NULL(*pp_ble_enable_params); - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_ble_enable_params, ble_enable_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_enable_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - return op_status_enc(SD_BLE_ENABLE, return_code, p_buf, p_buf_len, &index); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_event.c b/components/serialization/connectivity/codecs/s110/serializers/ble_event.c deleted file mode 100644 index 4eedff6..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_event.c +++ /dev/null @@ -1,186 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include "ble_evt_conn.h" -#include "ble_gap_evt_conn.h" -#include "ble_gattc_evt_conn.h" -#include "ble_gatts_evt_conn.h" -#include "ble_l2cap_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_event_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t ret_val = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_NOT_NULL(p_event); - - switch (p_event->header.evt_id) - { - case BLE_EVT_TX_COMPLETE: - ret_val = ble_evt_tx_complete_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_EVT_USER_MEM_RELEASE: - ret_val = ble_evt_user_mem_release_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_EVT_USER_MEM_REQUEST: - ret_val = ble_evt_user_mem_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE: - ret_val = ble_gap_evt_conn_param_update_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: - ret_val = ble_gap_evt_conn_param_update_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - ret_val = ble_gap_evt_sec_params_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_SEC_INFO_REQUEST: - ret_val = ble_gap_evt_sec_info_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_AUTH_STATUS: - ret_val = ble_gap_evt_auth_status_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_PASSKEY_DISPLAY: - ret_val = ble_gap_evt_passkey_display_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_AUTH_KEY_REQUEST: - ret_val = ble_gap_evt_auth_key_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_CONN_SEC_UPDATE: - ret_val = ble_gap_evt_conn_sec_update_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_RSSI_CHANGED: - ret_val = ble_gap_evt_rssi_changed_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_TIMEOUT: - ret_val = ble_gap_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_DISCONNECTED: - ret_val = ble_gap_evt_disconnected_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_CONNECTED: - ret_val = ble_gap_evt_connected_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_SEC_REQUEST: - ret_val = ble_gap_evt_sec_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - ret_val = ble_gattc_evt_char_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_DESC_DISC_RSP: - ret_val = ble_gattc_evt_desc_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: - ret_val = ble_gattc_evt_char_val_by_uuid_read_rsp_enc(p_event, - event_len, - p_buf, - p_buf_len); - break; - - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - ret_val = ble_gattc_evt_prim_srvc_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_HVX: - ret_val = ble_gattc_evt_hvx_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_READ_RSP: - ret_val = ble_gattc_evt_read_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_TIMEOUT: - ret_val = ble_gattc_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_WRITE_RSP: - ret_val = ble_gattc_evt_write_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_REL_DISC_RSP: - ret_val = ble_gattc_evt_rel_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_CHAR_VALS_READ_RSP: - ret_val = ble_gattc_evt_char_vals_read_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_HVC: - ret_val = ble_gatts_evt_hvc_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_TIMEOUT: - ret_val = ble_gatts_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_SC_CONFIRM: - ret_val = ble_gatts_evt_sc_confirm_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_WRITE: - ret_val = ble_gatts_evt_write_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: - ret_val = ble_gatts_evt_rw_authorize_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - ret_val = ble_gatts_evt_sys_attr_missing_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_L2CAP_EVT_RX: - ret_val = ble_l2cap_evt_rx_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_ADV_REPORT: - ret_val = ble_gap_evt_adv_report_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_SCAN_REQ_REPORT: - ret_val = ble_gap_evt_scan_req_report_enc(p_event, event_len, p_buf, p_buf_len); - break; - - default: - ret_val = NRF_ERROR_NOT_SUPPORTED; - *p_buf_len = 0; - break; - } - - return ret_val; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_evt_conn.h b/components/serialization/connectivity/codecs/s110/serializers/ble_evt_conn.h deleted file mode 100644 index 3c341da..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_evt_conn.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_EVT_CONN_H__ -#define BLE_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_evt_conn Connectivity event encoders - * @{ - * @ingroup ser_conn_s110_codecs - * - * @brief Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes ble_evt_tx_complete event. - * - * @sa @ref nrf51_evt_tx_complete_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_evt_user_mem_release event. - * - * @sa @ref nrf51_evt_user_mem_release_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_evt_user_mem_request event. - * - * @sa @ref nrf51_evt_user_mem_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_evt_tx_complete.c b/components/serialization/connectivity/codecs/s110/serializers/ble_evt_tx_complete.c deleted file mode 100644 index f10dbf9..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_evt_tx_complete.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_EVT_TX_COMPLETE, &(p_buf[index])); - index += uint16_encode(p_event->evt.common_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.common_evt.params.tx_complete.count; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_evt_user_mem_release.c b/components/serialization/connectivity/codecs/s110/serializers/ble_evt_user_mem_release.c deleted file mode 100644 index fec44de..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_evt_user_mem_release.c +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "conn_ble_user_mem.h" - -uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - const uint16_t evt_header = BLE_EVT_USER_MEM_RELEASE; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.common_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.common_evt.params.user_mem_release.type), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&(p_event->evt.common_evt.params.user_mem_release.mem_block.len), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, *p_buf_len - index); - p_buf[index++] = p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - // Now user memory context can be released - err_code = conn_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_evt_user_mem_request.c b/components/serialization/connectivity/codecs/s110/serializers/ble_evt_user_mem_request.c deleted file mode 100644 index 8faa98b..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_evt_user_mem_request.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - const uint16_t evt_header = BLE_EVT_USER_MEM_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.common_evt.params.user_mem_request.type), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_address_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_address_get.c deleted file mode 100644 index f0dc9a5..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_address_get.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_address_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_addr_t * * const pp_address) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_address); - SER_ASSERT_LENGTH_LEQ(1 + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_ADDRESS_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_address = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_address_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_addr_t const * const p_address) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADDRESS_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - *p_buf_len = index; - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_address); - - SER_ASSERT_LENGTH_LEQ(index + sizeof (ble_gap_addr_t), total_len); - p_buf[index++] = p_address->addr_type; - memcpy(&p_buf[index], &p_address->addr[0], BLE_GAP_ADDR_LEN); - index += BLE_GAP_ADDR_LEN; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_address_set.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_address_set.c deleted file mode 100644 index f5ce35b..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_address_set.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_address_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_addr_cycle_mode, - ble_gap_addr_t * * const pp_addr) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_addr_cycle_mode); - SER_ASSERT_NOT_NULL(pp_addr); - SER_ASSERT_NOT_NULL(*pp_addr); - uint8_dec(p_buf, packet_len, &index, (void *)p_addr_cycle_mode); - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_addr, ble_gap_addr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gap_address_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - return op_status_enc(SD_BLE_GAP_ADDRESS_SET, return_code, p_buf, p_buf_len, &index); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_data_set.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_data_set.c deleted file mode 100644 index ab83ce0..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_data_set.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * const pp_data, - uint8_t * p_dlen, - uint8_t * * const pp_sr_data, - uint8_t * p_srdlen) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_dlen); - SER_ASSERT_NOT_NULL(p_srdlen); - - uint32_t index = SER_CMD_DATA_POS; - - uint32_t error_code = len8data_dec(p_buf, packet_len, &index, pp_data, p_dlen); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - error_code = len8data_dec(p_buf, packet_len, &index, pp_sr_data, p_srdlen); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADV_DATA_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_start.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_start.c deleted file mode 100644 index ad5b071..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_start.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_adv_params_t * * const pp_adv_params) -{ - uint32_t index = 0, i = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_adv_params); - SER_ASSERT_NOT_NULL(*pp_adv_params); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_peer_addr); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_addrs); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_irks); - - for (i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++) - { - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_addrs[i]); - } - - for (i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++) - { - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_irks[i]); - } - - /* Packet with variable length. */ - /* For now check: opcode + indicator showing if ble_gap_adv_params_t struct is present. */ - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GAP_ADV_START, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - err_code = uint8_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->type)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **) &((*pp_adv_params)->p_peer_addr), ble_gap_addr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->fp)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **) &((*pp_adv_params)->p_whitelist), ble_gap_whitelist_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->interval)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->timeout)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_adv_ch_mask_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->channel_mask)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - *pp_adv_params = NULL; - } - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADV_START, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_stop.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_stop.c deleted file mode 100644 index b3569a2..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_adv_stop.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADV_STOP, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_appearance_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_appearance_get.c deleted file mode 100644 index cc828b5..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_appearance_get.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * * const pp_appearance) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_appearance); - SER_ASSERT_NOT_NULL(*pp_appearance); - SER_ASSERT_LENGTH_EQ(2, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_APPEARANCE_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_appearance = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_appearance) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_APPEARANCE_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_appearance); - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + sizeof (uint16_t), total_len); - index += uint16_encode(*p_appearance, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_appearance_set.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_appearance_set.c deleted file mode 100644 index f393fdb..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_appearance_set.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * const p_appearance) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_appearance); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_LENGTH_EQ(3, buf_len); - SER_ASSERT(p_buf[index++] == SD_BLE_GAP_APPEARANCE_SET, NRF_ERROR_INVALID_PARAM); - - uint32_t err_code = uint16_t_dec(p_buf, buf_len, &index, p_appearance); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_APPEARANCE_SET, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_auth_key_reply.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_auth_key_reply.c deleted file mode 100644 index 988c711..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_auth_key_reply.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - uint8_t * p_key_type, - uint8_t * * const pp_key) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_key_type); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - uint8_t key_len; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - SER_ASSERT_LENGTH_LEQ(1, packet_len - index); - uint8_dec(p_buf, packet_len, &index, p_key_type); - - switch (*p_key_type) - { - case BLE_GAP_AUTH_KEY_TYPE_NONE: - key_len = 0; - break; - - case BLE_GAP_AUTH_KEY_TYPE_PASSKEY: - key_len = 6; - break; - - case BLE_GAP_AUTH_KEY_TYPE_OOB: - key_len = 16; - break; - - default: - return NRF_ERROR_INVALID_PARAM; - } - - err_code = buf_dec(p_buf, packet_len, &index, pp_key, key_len, key_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return err_code; -} - -uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_AUTH_KEY_REPLY, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_authenticate.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_authenticate.c deleted file mode 100644 index 4d7053e..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_authenticate.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "nordic_common.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - - -uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_gap_sec_params_t * * const pp_sec_params) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_sec_params); - SER_ASSERT_NOT_NULL(*pp_sec_params); - - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_sec_params, - ble_gap_sec_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_AUTHENTICATE, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn.h b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn.h deleted file mode 100644 index b07c114..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn.h +++ /dev/null @@ -1,1044 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GAP_CONN_H__ -#define BLE_GAP_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gap_conn GAP Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s110_codecs - * - * @brief GAP Connectivity command request decoders and command response encoders - */ -#include "ble_gap.h" - -/**@brief Decodes @ref sd_ble_gap_address_get command request. - * - * @sa @ref nrf51_address_get_encoding for packet format, - * @ref ble_gap_address_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_address Pointer to pointer to address. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_address_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_addr_t * * const pp_address); - -/**@brief Encodes @ref sd_ble_gap_address_get command response. - * - * @sa @ref nrf51_address_get_encoding for packet format. - * @ref ble_gap_address_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_address Pointer to @ref ble_gap_addr_t address - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_addr_t const * const p_address); - -/**@brief Decodes @ref sd_ble_gap_authenticate command request. - * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format, - * @ref ble_gap_authenticate_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle - * @param[out] pp_sec_params Pointer to pointer to security parameters. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_gap_sec_params_t * * const pp_sec_params); - -/**@brief Encodes @ref sd_ble_gap_authenticate command response. - * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format. - * @ref ble_gap_authenticate_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_address_set command request. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format, - * @ref ble_gap_address_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_addr_cycle_mode Pointer to address cycle mode - * @param[out] pp_addr Pointer to pointer to address structure. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_address_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * const p_addr_cycle_mode, - ble_gap_addr_t * * const pp_addr); - -/**@brief Encodes @ref sd_ble_gap_address_set command response. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format. - * @ref ble_gap_address_set_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_adv_data_set command request. - * - * @sa @ref nrf51_adv_set_encoding for packet format, - * @ref ble_gap_adv_data_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] pp_data Pointer to the buffer raw data to be placed in advertisement packet. - * @param[out] p_dlen Pointer to data length for p_data. - * @param[out] pp_sr_data Pointer to the buffer raw data to be placed in scan response packet. - * @param[out] p_srdlen Pointer to data length for p_sr_data. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * const pp_data, - uint8_t * p_dlen, - uint8_t * * const pp_sr_data, - uint8_t * p_srdlen); - -/**@brief Encodes @ref sd_ble_gap_adv_data_set command response. - * - * @sa @ref nrf51_adv_set_encoding for packet format. - * @ref ble_gap_adv_data_set_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_adv_start command request. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_gap_adv_start_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_adv_params Pointer to pointer to advertising parameters. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_adv_params_t * * const pp_adv_params); - -/**@brief Encodes @ref sd_ble_gap_adv_start command response. - * - * @sa @ref nrf51_adv_start_encoding for packet format. - * @ref ble_gap_adv_start_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_device_name_get command request. - * - * @sa @ref nrf51_device_name_get_encoding for packet format, - * @ref ble_gap_device_name_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_dev_name Pointer to pointer to device name buffer. - * @param[out] pp_dev_name_len Pointer to pointer to device name length location. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * pp_dev_name, - uint16_t * * pp_dev_name_len); - -/**@brief Encodes @ref sd_ble_gap_device_name_get command response. - * - * @sa @ref nrf51_device_name_get_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_dev_name Pointer to device name buffer. - * @param[in] dev_name_len Length of device name buffer. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buflen \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code, - uint8_t const * const p_dev_name, - uint16_t dev_name_len, - uint8_t * const p_buf, - uint32_t * const p_buflen); - -/**@brief Decodes @ref sd_ble_gap_conn_param_update command request. - * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format, - * @ref ble_gap_conn_param_update_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_conn_params Pointer to pointer to connection parameters. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection - * parameters field present. - */ -uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - ble_gap_conn_params_t * * const pp_conn_params); - -/**@brief Encodes @ref sd_ble_gap_conn_param_update command response. - * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - - -/**@brief Decodes @ref sd_ble_gap_disconnect command request. - * - * @sa @ref nrf51_disconnect_encoding for packet format, - * @ref ble_gap_disconnect_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] p_conn_handle Pointer to Connection Handle. - * @param[in] p_hci_status Pointer to HCI Status Code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * const p_hci_status); - -/**@brief Encodes @ref sd_ble_gap_disconnect command response. - * - * @sa @ref nrf51_disconnect_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_tx_power_set command request. - * - * @sa @ref nrf51_tx_power_set_encoding for packet format, - * @ref ble_gap_tx_power_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] tx_power Pointer to TX power value. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - int8_t * tx_power); - -/**@brief Encodes @ref sd_ble_gap_tx_power_set command response. - * - * @sa @ref nrf51_tx_power_set_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_ppcp_set command request. - * - * @sa @ref nrf51_ppcp_set_encoding for packet format, - * @ref ble_gap_ppcp_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_conn_params Pointer to pointer to connection parameters to be set. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection - * parameters field present. - */ -uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_params_t * * const pp_conn_params); - -/**@brief Encodes @ref sd_ble_gap_ppcp_set command response. - * - * @sa @ref nrf51_ppcp_set_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - - -/**@brief Decodes @ref sd_ble_gap_ppcp_get command request. - * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format, - * @ref ble_gap_ppcp_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_conn_params Pointer to pointer to ble_gap_conn_params_t. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_conn_params_t * * const pp_conn_params); - -/**@brief Encodes @ref sd_ble_gap_ppcp_get command response. - * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format. - * @ref ble_gap_ppcp_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_conn_params Pointer to ble_gap_conn_params_t. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_conn_params_t const * const p_conn_params); - - -/**@brief Encodes @ref sd_ble_gap_adv_stop command response. - * - * @sa @ref nrf51_sd_ble_gap_adv_stop for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_auth_key_reply command request. - * - * @sa @ref nrf51_auth_key_reply_encoding for packet format, - * @ref ble_gap_auth_key_reply_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_key_type Pointer to key type. - * @param[out] pp_key Pointer to pointer to buffer for incoming key. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - uint8_t * p_key_type, - uint8_t * * const pp_key); - -/**@brief Encodes @ref sd_ble_gap_auth_key_reply command response. - * - * @sa @ref nrf51_auth_key_reply_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_sec_params_reply command request. - * - * @sa @ref nrf51_sec_params_reply_encoding for packet format, - * @ref ble_gap_sec_params_reply_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_sec_status Pointer to security status. - * @param[out] pp_sec_params Pointer to pointer to security parameters structure. - * @param[out] pp_sec_keyset Pointer to pointer to security keyset structure. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection - * parameters field present. - */ -uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - uint8_t * p_sec_status, - ble_gap_sec_params_t * * const pp_sec_params, - ble_gap_sec_keyset_t * * const pp_sec_keyset); - -/**@brief Encodes @ref sd_ble_gap_sec_params_reply command response. - * - * @sa @ref nrf51_sec_params_reply_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in] p_sec_keyset Pointer to security keyset structure. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_sec_keyset_t * const p_sec_keyset); - -/**@brief Decodes @ref sd_ble_gap_rssi_start command request. - * - * @sa @ref nrf51_rssi_start_encoding for packet format, - * @ref ble_gap_rssi_start_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_threshold_dbm Pointer to threshold in dBm. - * @param[out] p_skip_count Pointer to sample skip count. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_conn_handle, - uint8_t * p_threshold_dbm, - uint8_t * p_skip_count); - -/**@brief Encodes @ref sd_ble_gap_rssi_start command response. - * - * @sa @ref nrf51_rssi_start_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_rssi_stop command request. - * - * @sa @ref nrf51_rssi_stop_encoding for packet format, - * @ref ble_gap_rssi_stop_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] conn_handle Pointer to connection handle. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ - -uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * conn_handle); - -/**@brief Encodes @ref sd_ble_gap_rssi_stop command response. - * - * @sa @ref nrf51_rssi_stop_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_appearance_get command request. - * - * @sa @ref nrf51_appearance_get_encoding for packet format, - * @ref ble_gap_appearance_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_appearance Pointer to pointer to uint16_t appearance. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * * const pp_appearance); - -/**@brief Encodes @ref sd_ble_gap_appearance_get command response. - * - * @sa @ref nrf51_appearance_get_encoding for packet format. - * @ref ble_gap_appearance_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_appearance Pointer to uint16_t appearance. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_appearance); - - -/**@brief Decodes @ref sd_ble_gap_appearance_set command request. - * - * @sa @ref nrf51_appearance_set_encoding for packet format, - * @ref ble_gap_tx_power_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of the packet. - * @param[out] p_appearance Pointer to the appearance. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * const p_appearance); - -/**@brief Encodes @ref sd_ble_gap_appearance_set command response. - * - * @sa @ref nrf51_appearance_set_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - - -/**@brief Decodes @ref sd_ble_gap_sec_info_reply command request. - * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format, - * @ref ble_gap_sec_info_reply_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of the packet. - * @param[out] p_conn_handle Pointer to the Connection Handle. - * @param[out] pp_enc_info Pointer to pointer to Encryption Information. - * @param[out] pp_id_info Pointer to pointer to Id Information. - * @param[out] pp_sign_info Pointer to pointer to Signing Information - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - ble_gap_enc_info_t * * const pp_enc_info, - ble_gap_irk_t * * const pp_id_info, - ble_gap_sign_info_t * * const pp_sign_info); - -/**@brief Encodes @ref sd_ble_gap_sec_info_reply command response. - * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_device_name_set command request. - * - * @sa @ref nrf51_device_name_set_encoding for packet format, - * @ref ble_gap_device_name_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of the packet. - * @param[out] pp_write_perm Pointer to pointer to write permissions filed. - * @param[out] pp_dev_name Pointer to pointer to device name string - * @param[out] p_dev_name_len Pointer to device name string length - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_sec_mode_t * * const pp_write_perm, - uint8_t * * const pp_dev_name, - uint16_t * const p_dev_name_len); - - -/**@brief Encodes @ref sd_ble_gap_device_name_set command response. - * - * @sa @ref nrf51_device_name_set_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_conn_sec_get command request. - * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format, - * @ref ble_gap_conn_sec_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to Connection Handle. - * @param[out] pp_conn_sec Pointer to pointer to @ref ble_gap_conn_sec_t to be filled by - * the softdevice. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - ble_gap_conn_sec_t * * const pp_conn_sec); - -/**@brief Encodes @ref sd_ble_gap_conn_sec_get command response. - * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format. - * @ref ble_gap_conn_sec_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_conn_sec Pointer to @ref ble_gap_conn_sec_t to be encoded. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code, - ble_gap_conn_sec_t * const p_conn_sec, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_encrypt command request. - * - * @sa @ref nrf51_gap_encrypt_encoding for packet format, - * @ref ble_gap_encrypt_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer connection_handle. - * @param[out] pp_master_id Pointer to pointer to @ref ble_gap_master_id_t. - * @param[out] pp_enc_info Pointer to pointer to @ref ble_gap_enc_info_t. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ - -uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gap_master_id_t ** const pp_master_id, - ble_gap_enc_info_t ** const pp_enc_info); - -/**@brief Encodes @ref sd_ble_gap_encrypt command response. - * - * @sa @ref nrf51_gap_encrypt_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_rssi_get command request. - * - * @sa @ref nrf51_rssi_get_encoding for packet format, - * @ref ble_gap_rssi_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] p_conn_handle Connection handle. - * @param[out] pp_rssi Pointer to pointer to rssi value. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - int8_t * * const pp_rssi); - -/**@brief Encodes @ref sd_ble_gap_rssi_get command response. - * - * @sa @ref nrf51_rssi_get_encoding for packet format. - * @ref ble_gap_rssi_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] rssi RSSI value. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int8_t rssi); - -/**@brief Decodes @ref sd_ble_gap_connect command request. - * - * @sa @ref nrf51_connect_encoding for packet format, - * @ref ble_gap_connect_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_addr Pointer to pointer to peer address @ref ble_gap_addr_t. - * @param[out] pp_scan_params Pointer to pointer to @ref ble_gap_scan_params_t. - * @param[out] pp_conn_params Pointer to pointer to @ref ble_gap_conn_params_t. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * * const pp_addr, - ble_gap_scan_params_t * * const pp_scan_params, - ble_gap_conn_params_t * * const pp_conn_params); - -/**@brief Encodes @ref sd_ble_gap_connect command response. - * - * @sa @ref nrf51_connect_encoding for packet format. - * @ref ble_gap_connect_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_connect_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Encodes @ref sd_ble_gap_connect_cancel command response. - * - * @sa @ref nrf51_connect_cancel_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_scan_start command request. - * - * @sa @ref nrf51_scan_start_encoding for packet format, - * @ref ble_gap_scan_start_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_scan_params Pointer to pointer to @ref ble_gap_scan_params_t. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_scan_params_t * * const pp_scan_params); - -/**@brief Encodes @ref sd_ble_gap_scan_start command response. - * - * @sa @ref nrf51_scan_start_encoding for packet format. - * @ref ble_gap_scan_start_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Encodes @ref sd_ble_gap_scan_stop command response. - * - * @sa @ref nrf51_scan_stop_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn_param_update.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn_param_update.c deleted file mode 100644 index 38ac3fd..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn_param_update.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_conn_params); - SER_ASSERT_NOT_NULL(*pp_conn_params); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 3, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_CONN_PARAM_UPDATE, NRF_ERROR_INVALID_PARAM); - - index++; - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - if (p_buf[index] == SER_FIELD_PRESENT) - { - index++; - SER_ASSERT_LENGTH_LEQ(index + 8, packet_len); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->min_conn_interval)); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->max_conn_interval)); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->slave_latency)); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->conn_sup_timeout)); - } - else if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - index++; - *pp_conn_params = NULL; - } - else - { - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONN_PARAM_UPDATE, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn_sec_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn_sec_get.c deleted file mode 100644 index d3631ee..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_conn_sec_get.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - - -uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - ble_gap_conn_sec_t * * const pp_conn_sec) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - - uint32_t index = 0; - uint8_t opcode; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, packet_len - index); - uint8_dec(p_buf, packet_len, &index, &opcode); - - SER_ASSERT(opcode == SD_BLE_GAP_CONN_SEC_GET, NRF_ERROR_INVALID_PARAM); - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_conn_sec, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code, - ble_gap_conn_sec_t * const p_conn_sec, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t buflen = *p_buf_len; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONN_SEC_GET, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = cond_field_enc(p_conn_sec, p_buf, buflen, &index, ble_gap_conn_sec_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_connect.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_connect.c deleted file mode 100644 index e7b6135..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_connect.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * * const pp_addr, - ble_gap_scan_params_t * * const pp_scan_params, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_addr); - SER_ASSERT_NOT_NULL(*pp_addr); - SER_ASSERT_NOT_NULL(pp_scan_params); - SER_ASSERT_NOT_NULL(*pp_scan_params); - SER_ASSERT_NOT_NULL(pp_conn_params); - SER_ASSERT_NOT_NULL(*pp_conn_params); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_addr, ble_gap_addr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_scan_params, ble_gap_scan_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_conn_params, ble_gap_conn_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_connect_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONNECT, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_connect_cancel.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_connect_cancel.c deleted file mode 100644 index 4551fcd..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_connect_cancel.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONNECT_CANCEL, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_device_name_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_device_name_get.c deleted file mode 100644 index e169d02..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_device_name_get.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - -uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * * pp_name, - uint16_t * * pp_name_len) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(pp_name_len); - SER_ASSERT_NOT_NULL(*pp_name_len); - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - - index++; - - if (p_buf[index] != SER_FIELD_PRESENT && p_buf[index] != SER_FIELD_NOT_PRESENT) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - err_code = uint16_t_dec(p_buf, buf_len, &index, *pp_name_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - *pp_name_len = NULL; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - - if (p_buf[index] != SER_FIELD_PRESENT && p_buf[index] != SER_FIELD_NOT_PRESENT) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - *pp_name = NULL; - } - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code, - uint8_t const * const p_dev_name, - uint16_t dev_name_len, - uint8_t * const p_buf, - uint32_t * const p_buflen) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buflen); - - uint32_t buflen = *p_buflen; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_DEVICE_NAME_GET, return_code, - p_buf, p_buflen); - uint32_t index = *p_buflen; - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = len16data_enc(p_dev_name, dev_name_len, p_buf, buflen, &index); - - *p_buflen = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_device_name_set.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_device_name_set.c deleted file mode 100644 index 84c49ff..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_device_name_set.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_sec_mode_t * * const pp_write_perm, - uint8_t * * const pp_dev_name, - uint16_t * const p_dev_name_len) -{ - SER_ASSERT_NOT_NULL(p_buf); //check if *p_buf is allocated - SER_ASSERT_NOT_NULL(pp_write_perm); //check if *pp_write_perm exist - SER_ASSERT_NOT_NULL(pp_dev_name); //check if *pp_dev_name exist - SER_ASSERT_NOT_NULL(p_dev_name_len); //check if *p_dev_name_len exist - - uint32_t index = SER_CMD_DATA_POS; - uint32_t status_code; - - SER_ASSERT_LENGTH_LEQ(4, packet_len - index); //make sure that payload is at least 4 bytes - - //decode optional write permissions field - status_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_write_perm, - ble_gap_conn_sec_mode_dec); - SER_ASSERT(status_code == NRF_SUCCESS, status_code); - - //decode optional device name field - status_code = len16data_dec(p_buf, packet_len, &index, pp_dev_name, p_dev_name_len); - SER_ASSERT(status_code == NRF_SUCCESS, status_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return status_code; -} - - -uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_DEVICE_NAME_SET, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_disconnect.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_disconnect.c deleted file mode 100644 index e69a0d0..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_disconnect.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * const p_hci_status) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_hci_status); - - uint8_t opcode; - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_dec(p_buf, packet_len, &index, &opcode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT(opcode == SD_BLE_GAP_DISCONNECT, NRF_ERROR_INVALID_PARAM); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_hci_status); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_DISCONNECT, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_encrypt.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_encrypt.c deleted file mode 100644 index 3cf0262..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_encrypt.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gap_master_id_t ** const pp_master_id, - ble_gap_enc_info_t ** const pp_enc_info) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_enc_info); - SER_ASSERT_NOT_NULL(pp_master_id); - SER_ASSERT_NOT_NULL(*pp_enc_info); - SER_ASSERT_NOT_NULL(*pp_master_id); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void **)pp_master_id, - ble_gap_master_id_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void **)pp_enc_info, - ble_gap_enc_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ENCRYPT, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_adv_report.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_adv_report.c deleted file mode 100644 index fa6cd3f..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_adv_report.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - const uint16_t evt_header = BLE_GAP_EVT_ADV_REPORT; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc((void *)&(p_event->evt.gap_evt.params.adv_report.peer_addr), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.gap_evt.params.adv_report.rssi), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - byte = (p_event->evt.gap_evt.params.adv_report.scan_rsp) | - ((p_event->evt.gap_evt.params.adv_report.type) << 0x01) | - ((p_event->evt.gap_evt.params.adv_report.dlen) << 0x03); - - err_code = uint8_t_enc((void *)&(byte), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_vector_enc(p_event->evt.gap_evt.params.adv_report.data, (uint16_t)p_event->evt.gap_evt.params.adv_report.dlen, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_auth_key_request.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_auth_key_request.c deleted file mode 100644 index 7805879..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_auth_key_request.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GAP_EVT_AUTH_KEY_REQUEST; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_event->evt.gap_evt.params.auth_key_request.key_type, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_auth_status.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_auth_status.c deleted file mode 100644 index 59a751a..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_auth_status.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gap_evt_conn.h" -#include "conn_ble_gap_sec_keys.h" - -extern ser_ble_gap_conn_keyset_t m_conn_keys_table[]; - -uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint16_t evt_header = BLE_GAP_EVT_AUTH_STATUS; - uint32_t total_len; - uint32_t err_code = NRF_SUCCESS; - uint32_t conn_index; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - total_len = *p_buf_len; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_auth_status_t_enc(&(p_event->evt.gap_evt.params.auth_status), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - // keyset is an extension of standard event data - used to synchronize keys at application - err_code = conn_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keyset_t_enc(&(m_conn_keys_table[conn_index].keyset), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = conn_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - return err_code; -} - diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn.h b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn.h deleted file mode 100644 index ce0851e..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn.h +++ /dev/null @@ -1,336 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GAP_EVT_CONN_H__ -#define BLE_GAP_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gap_evt_conn GAP Connectivity event encoders - * @{ - * @ingroup ser_conn_s110_codecs - * - * @brief GAP Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes ble_gap_evt_auth_key_request event. - * - * @sa @ref nrf51_evt_auth_key_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_auth_status event. - * - * @sa @ref nrf51_evt_auth_status_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_conn_param_update event. - * - * @sa @ref nrf51_evt_conn_param_update_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_adv_report event. - * - * @sa @ref nrf51_evt_adv_report_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_conn_sec_update event. - * - * @sa @ref nrf51_evt_conn_sec_update_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_connected event. - * - * @sa @ref nrf51_evt_connected_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_disconnected event. - * - * @sa @ref nrf51_evt_disconnected_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_passkey_display event. - * - * @sa @ref nrf51_evt_passkey_display for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_rssi_changed event. - * - * @sa @ref nrf51_evt_rssi_changed_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_sec_info_request event. - * - * @sa @ref nrf51_evt_sec_info_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_sec_params_request event. - * - * @sa @ref nrf51_evt_sec_param_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_timeout event. - * - * @sa @ref nrf51_evt_timeout_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_scan_req_report event. - * - * @sa @ref nrf51_evt_scan_req_report_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_conn_param_update_request event. - * - * @sa @ref nrf51_evt_conn_param_update_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_sec_request event. - * - * @sa @ref nrf51_evt_sec_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_param_update.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_param_update.c deleted file mode 100644 index a9565dc..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_param_update.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT(p_event->header.evt_id == BLE_GAP_EVT_CONN_PARAM_UPDATE, NRF_ERROR_INVALID_PARAM); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_conn_param_update_t_enc(&p_event->evt.gap_evt.params.conn_param_update, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_param_update_request.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_param_update_request.c deleted file mode 100644 index 5843ff3..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_param_update_request.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT(p_event->header.evt_id == BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, NRF_ERROR_INVALID_PARAM); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_conn_param_update_request_t_enc(&p_event->evt.gap_evt.params.conn_param_update_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_sec_update.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_sec_update.c deleted file mode 100644 index 8293866..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_conn_sec_update.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_CONN_SEC_UPDATE; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_conn_sec_update_t_enc( - (void *)&p_event->evt.gap_evt.params.conn_sec_update, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_connected.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_connected.c deleted file mode 100644 index 16cea4f..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_connected.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GAP_EVT_CONNECTED; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_connected_t_enc((void *)&p_event->evt.gap_evt.params.connected, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_disconnected.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_disconnected.c deleted file mode 100644 index a067462..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_disconnected.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gap_evt_conn.h" - -uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code; - uint16_t evt_header = BLE_GAP_EVT_DISCONNECTED; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&(p_event->evt.gap_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_disconnected_t_enc((void *)&(p_event->evt.gap_evt.params.disconnected), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_passkey_display.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_passkey_display.c deleted file mode 100644 index 1fcaab5..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_passkey_display.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble.h" -#include "ble_gap_evt_conn.h" - -#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey) - - -uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + PASSKEY_LEN, *p_buf_len); - index += uint16_encode(BLE_GAP_EVT_PASSKEY_DISPLAY, &(p_buf[index])); - index += uint16_encode(p_event->evt.gap_evt.conn_handle, &(p_buf[index])); - - memcpy(&p_buf[index], p_event->evt.gap_evt.params.passkey_display.passkey, PASSKEY_LEN); - index += PASSKEY_LEN; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_rssi_changed.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_rssi_changed.c deleted file mode 100644 index 6ee6a94..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_rssi_changed.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GAP_EVT_RSSI_CHANGED, &(p_buf[index])); - index += uint16_encode(p_event->evt.gap_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gap_evt.params.rssi_changed.rssi; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_scan_req_report.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_scan_req_report.c deleted file mode 100644 index 9707495..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_scan_req_report.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" - - -uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_SCAN_REQ_REPORT; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc((void *)&(p_event->evt.gap_evt.params.scan_req_report.peer_addr), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.gap_evt.params.scan_req_report.rssi), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_info_request.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_info_request.c deleted file mode 100644 index e3b7949..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_info_request.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_SEC_INFO_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_info_request_t_enc( - (void *)&p_event->evt.gap_evt.params.sec_info_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_params_request.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_params_request.c deleted file mode 100644 index f2fdf59..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_params_request.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_SEC_PARAMS_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_params_request_t_enc( - (void *)&p_event->evt.gap_evt.params.sec_params_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_request.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_request.c deleted file mode 100644 index 6a744b0..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_sec_request.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GAP_EVT_SEC_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_request_t_enc((void *)&p_event->evt.gap_evt.params.sec_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_timeout.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_timeout.c deleted file mode 100644 index 7894cdc..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_evt_timeout.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE + 3, *p_buf_len); - index += uint16_encode(BLE_GAP_EVT_TIMEOUT, &(p_buf[index])); - index += uint16_encode(p_event->evt.gap_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gap_evt.params.timeout.src; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_ppcp_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_ppcp_get.c deleted file mode 100644 index 38663fc..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_ppcp_get.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_conn_params); - SER_ASSERT_NOT_NULL(*pp_conn_params); - SER_ASSERT_LENGTH_LEQ(2, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_PPCP_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_conn_params = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_conn_params_t const * const p_conn_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_PPCP_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_conn_params); - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 8, total_len); - - index += uint16_encode(p_conn_params->min_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->max_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->slave_latency, &p_buf[index]); - index += uint16_encode(p_conn_params->conn_sup_timeout, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_ppcp_set.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_ppcp_set.c deleted file mode 100644 index e09aaf2..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_ppcp_set.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "nordic_common.h" -#include "app_util.h" - - -uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_conn_params); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GAP_PPCP_SET, NRF_ERROR_INVALID_PARAM); - - index++; - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_conn_params = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 8, packet_len); - SER_ASSERT_NOT_NULL(*pp_conn_params); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->min_conn_interval); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->max_conn_interval); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->slave_latency); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->conn_sup_timeout); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_PPCP_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_get.c deleted file mode 100644 index 306caa2..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_get.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - int8_t * * const pp_rssi) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_rssi); - SER_ASSERT_NOT_NULL(*pp_rssi); - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **) pp_rssi, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int8_t rssi) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_RSSI_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - uint32_t index = *p_buf_len; - - err_code = uint8_t_enc((uint8_t *) &rssi, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_start.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_start.c deleted file mode 100644 index cd6f516..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_start.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_conn_handle, - uint8_t * p_threshold_dbm, - uint8_t * p_skip_count) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_threshold_dbm); - SER_ASSERT_NOT_NULL(p_skip_count); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, &index, p_threshold_dbm); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, &index, p_skip_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_RSSI_START, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_stop.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_stop.c deleted file mode 100644 index d068f3d..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_rssi_stop.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_conn_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_RSSI_STOP, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_scan_start.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_scan_start.c deleted file mode 100644 index b561d3c..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_scan_start.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_scan_params_t * * const pp_scan_params) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_scan_params); - SER_ASSERT_NOT_NULL(*pp_scan_params); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_scan_params, ble_gap_scan_params_t_dec); - - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SCAN_START, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_scan_stop.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_scan_stop.c deleted file mode 100644 index a390f17..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_scan_stop.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SCAN_STOP, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_sec_info_reply.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_sec_info_reply.c deleted file mode 100644 index 3e85479..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_sec_info_reply.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - ble_gap_enc_info_t * * const pp_enc_info, - ble_gap_irk_t * * const pp_id_info, - ble_gap_sign_info_t * * const pp_sign_info) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_enc_info); - SER_ASSERT_NOT_NULL(pp_id_info); - SER_ASSERT_NOT_NULL(pp_sign_info); - SER_ASSERT_NOT_NULL(*pp_enc_info); - SER_ASSERT_NOT_NULL(*pp_id_info); - SER_ASSERT_NOT_NULL(*pp_sign_info); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_enc_info, - ble_gap_enc_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_id_info, - ble_gap_irk_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_sign_info, - ble_gap_sign_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return err_code; -} - -uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SEC_INFO_REPLY, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_sec_params_reply.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_sec_params_reply.c deleted file mode 100644 index 0c295be..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_sec_params_reply.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - uint8_t * p_sec_status, - ble_gap_sec_params_t * * const pp_sec_params, - ble_gap_sec_keyset_t * * const pp_sec_keyset) -{ - uint32_t index = SER_CMD_HEADER_SIZE; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_sec_status); - SER_ASSERT_NOT_NULL(pp_sec_params); - SER_ASSERT_NOT_NULL(*pp_sec_params); - SER_ASSERT_NOT_NULL(pp_sec_keyset); - SER_ASSERT_NOT_NULL(*pp_sec_keyset); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_sec_status); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *) pp_sec_params, ble_gap_sec_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *) pp_sec_keyset, ble_gap_sec_keyset_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -//opcode: 0x7F -uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_sec_keyset_t * const p_sec_keyset) -{ - uint32_t index = 0; - uint32_t buf_len = * p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SEC_PARAMS_REPLY, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_sec_keyset); - index = *p_buf_len; - - err_code = cond_field_enc(p_sec_keyset, p_buf, buf_len, &index, ble_gap_sec_keyset_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_tx_power_set.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gap_tx_power_set.c deleted file mode 100644 index 6af4f31..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gap_tx_power_set.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - int8_t * p_tx_power) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_tx_power); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_tx_power); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_TX_POWER_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_char_value_by_uuid_read.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_char_value_by_uuid_read.c deleted file mode 100644 index 6fbc19d..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_char_value_by_uuid_read.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "cond_field_serialization.h" -#include "ble_types.h" -#include - -uint32_t ble_gattc_char_value_by_uuid_read_req_dec( - uint8_t const * const p_buf, - uint16_t buf_len, - uint16_t * const p_conn_handle, - ble_uuid_t * * const pp_uuid, - ble_gattc_handle_range_t * * const - pp_handle_range) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2, buf_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, NRF_ERROR_INVALID_DATA); - index++; - - uint16_dec(p_buf, buf_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_handle_range, - ble_gattc_handle_range_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, return_code, - p_buf, p_buf_len); -} - diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_char_values_read.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_char_values_read.c deleted file mode 100644 index 39c6808..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_char_values_read.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * * const pp_handles, - uint16_t * const p_handle_count) -{ - SER_ASSERT_NOT_NULL(p_buf); //check if *p_buf is allocated - SER_ASSERT_NOT_NULL(p_conn_handle); //check if *p_conn_handle exist - SER_ASSERT_NOT_NULL(pp_handles); //check if *p_handles exist - SER_ASSERT_NOT_NULL(*pp_handles); //check if p_handles exist - SER_ASSERT_NOT_NULL(p_handle_count); //check if *p_handle_count exist - - uint32_t index = SER_CMD_DATA_POS; - uint32_t status_code; - - SER_ASSERT_LENGTH_LEQ(5, packet_len - index); //make sure that payload length is at least 5 bytes - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - //decode handle table count with optional handle table - status_code = count16_cond_data16_dec(p_buf, packet_len, &index, pp_handles, p_handle_count); - SER_ASSERT(status_code == NRF_SUCCESS, status_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return status_code; -} - - -uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - return op_status_enc(SD_BLE_GATTC_CHAR_VALUES_READ, return_code, p_buf, p_buf_len, &index); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_characteristics_discover.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_characteristics_discover.c deleted file mode 100644 index e17edb2..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_characteristics_discover.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_characteristics_discover_req_dec( - uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_handle_range = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->start_handle); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->end_handle); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_conn.h b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_conn.h deleted file mode 100644 index f803c91..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_conn.h +++ /dev/null @@ -1,398 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_CONN_H__ -#define BLE_GATTC_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gatc_conn GATTC Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s110_codecs - * - * @brief GATTC Connectivity command request decoders and command response encoders - */ -#include "ble_gattc.h" -#include "ble.h" - -/**@brief Decodes @ref sd_ble_gattc_characteristics_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format, - * @ref ble_gattc_characteristics_discover_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_handle_range Pointer to pointer to handle range. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present. - */ -uint32_t ble_gattc_characteristics_discover_req_dec - (uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range); - -/**@brief Encodes @ref sd_ble_gattc_characteristics_discover command response. - * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format. - * @ref ble_gattc_characteristics_discover_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_descriptors_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format, - * @ref ble_gattc_descriptors_discover_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_handle_range Pointer to pointer to handle range. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present. - */ -uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range); - -/**@brief Encodes @ref sd_ble_gattc_descriptors_discover command response. - * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format. - * @ref ble_gattc_descriptors_discover_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_relationships_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format, - * @ref ble_gattc_relationships_discover_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_handle_range Pointer to pointer to handle range. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present. - */ -uint32_t ble_gattc_relationships_discover_req_dec - (uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range); - -/**@brief Encodes @ref sd_ble_gattc_relationships_discover command response. - * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format. - * @ref ble_gattc_relationships_discover_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_primary_services_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_start_handle Pointer to start handle. - * @param[out] pp_srvc_uuid Pointer to pointer to service uuid. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for uuid field present. - */ -uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_start_handle, - ble_uuid_t * * const pp_srvc_uuid); - -/**@brief Encodes @ref sd_ble_gattc_primary_services_discover command response. - * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format. - * @ref ble_gattc_primary_services_discover_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format, - * @ref ble_gattc_read_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_handle Pointer to handle. - * @param[out] p_offset Pointer to offset. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle, - uint16_t * const p_offset); - -/**@brief Encodes @ref sd_ble_gattc_read command response. - * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format. - * @ref ble_gattc_read_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_char_values_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format, - * @ref ble_gattc_char_values_read_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_handles Pointer to pointer to handle table. - * @param[out] p_handle_count Pointer to handle handle table count. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ - -uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * * const pp_handles, - uint16_t * const p_handle_count); - -/**@brief Encodes @ref sd_ble_gattc_char_values_read command response. - * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format. - * @ref ble_gattc_char_values_read_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_write command request. - * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format, - * @ref ble_gattc_write_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_write_params Pointer to pointer to write parameters. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_write_params_t * * const pp_write_params); - -/**@brief Encodes @ref sd_ble_gattc_write command response. - * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format. - * @ref ble_gattc_write_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_write_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_hv_confirm command request. - * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format, - * @ref ble_gattc_hv_confirm_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_handle Pointer to handle of the attribute in the indication. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle); - -/**@brief Encodes @ref sd_ble_gattc_hv_confirm command response. - * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format. - * @ref ble_gattc_hv_confirm_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_char_value_by_uuid_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format, - * @ref ble_gattc_char_value_by_uuid_read_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of request packet. - * @param[out] p_conn_handle Pointer to connection handle of the connection. - * @param[out] pp_uuid Pointer to pointer to a characteristic value UUID to read. - * @param[out] pp_handle_range Pointer to pointer to the range of handles to perform this - * procedure on. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid operation type. - */ -uint32_t ble_gattc_char_value_by_uuid_read_req_dec - (uint8_t const * const p_buf, - uint16_t buf_len, - uint16_t * const p_conn_handle, - ble_uuid_t * * const pp_uuid, - ble_gattc_handle_range_t * * const pp_handle_range); - -/**@brief Encodes @ref sd_ble_gattc_char_value_by_uuid_read command response. - * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format. - * @ref ble_gattc_char_value_by_uuid_read_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif - diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_descriptors_discover.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_descriptors_discover.c deleted file mode 100644 index f78e675..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_descriptors_discover.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_handle_range = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->start_handle); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->end_handle); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_disc_rsp.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_disc_rsp.c deleted file mode 100644 index 5799434..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_disc_rsp.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 8, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_CHAR_DISC_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.count, &(p_buf[index])); - - uint16_t service_count = p_event->evt.gattc_evt.params.char_disc_rsp.count; - - SER_ASSERT_LENGTH_LEQ(index + (service_count * 9), *p_buf_len); - - for (uint16_t i = 0; i < service_count; i++) - { - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.uuid, - &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.type; - p_buf[index++] = (0x00 | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.broadcast << 0) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.read << 1) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.write_wo_resp << 2) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.write << 3) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.notify << 4) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.indicate << 5) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.auth_signed_wr << 6)); - p_buf[index++] = (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_ext_props & 0x01); - - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_decl, - &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_value, - &(p_buf[index])); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c deleted file mode 100644 index 4326380..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_util.h" -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_gattc_evt_conn.h" - - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gattc_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gattc_evt.gatt_status, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gattc_evt.error_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc( - &p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_vals_read_rsp.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_vals_read_rsp.c deleted file mode 100644 index fa7fc41..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_char_vals_read_rsp.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint16_t evt_header = BLE_GATTC_EVT_CHAR_VALS_READ_RSP; - - //Event Header - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - //GATTC Header - err_code = uint16_t_enc(&(p_event->evt.gattc_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gattc_evt.gatt_status), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gattc_evt.error_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - //Event structure for BLE_GATTC_EVT_CHAR_VALS_READ_RSP - err_code = - ble_gattc_evt_char_vals_read_rsp_t_enc(&(p_event->evt.gattc_evt.params.char_vals_read_rsp), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_conn.h b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_conn.h deleted file mode 100644 index 8e5d9f9..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_conn.h +++ /dev/null @@ -1,236 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_EVT_CONN_H__ -#define BLE_GATTC_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gattc_evt_conn GATTC Connectivity event encoders - * @{ - * @ingroup ser_conn_s110_codecs - * - * @brief GATTC Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes ble_gattc_evt_char_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_disc_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_char_val_by_uuid_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_val_by_uuid_read_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_char_vals_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_vals_read_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_desc_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_desc_disc_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_hvx event. - * - * @sa @ref nrf51_gattc_evt_hvx_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_prim_srvc_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_prim_srvc_disc_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_read_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_rel_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_rel_disc_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_timeout event. - * - * @sa @ref nrf51_gattc_evt_timeout_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_write_rsp event. - * - * @sa @ref nrf51_gattc_evt_write_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_desc_disc_rsp.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_desc_disc_rsp.c deleted file mode 100644 index 378e77b..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_desc_disc_rsp.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 8, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_DESC_DISC_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.count, &(p_buf[index])); - - uint16_t service_count = p_event->evt.gattc_evt.params.desc_disc_rsp.count; - - SER_ASSERT_LENGTH_LEQ(index + (service_count * 5), *p_buf_len); - - for (uint16_t i = 0; i < service_count; i++) - { - index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].handle, - &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.uuid, - &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.type; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_hvx.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_hvx.c deleted file mode 100644 index 8e3a49e..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_hvx.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 11, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_HVX, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.hvx.handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.hvx.type; - index += uint16_encode(p_event->evt.gattc_evt.params.hvx.len, &(p_buf[index])); - - SER_ASSERT_LENGTH_LEQ(index + p_event->evt.gattc_evt.params.hvx.len, *p_buf_len); - - if (p_event->evt.gattc_evt.params.hvx.len > 0) - { - memcpy(&(p_buf[index]), - &(p_event->evt.gattc_evt.params.hvx.data[0]), - p_event->evt.gattc_evt.params.hvx.len); - index += p_event->evt.gattc_evt.params.hvx.len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c deleted file mode 100644 index f70c538..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 8, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.count, &(p_buf[index])); - - uint16_t service_count = p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.count; - - SER_ASSERT_LENGTH_LEQ(index + (service_count * 7), *p_buf_len); - - for (uint16_t i = 0; i < service_count; i++) - { - index += uint16_encode( - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.uuid, - &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.type; - index += - uint16_encode( - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - start_handle, - &(p_buf[index])); - index += - uint16_encode( - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - end_handle, - &(p_buf[index])); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_read_rsp.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_read_rsp.c deleted file mode 100644 index 2d2b0f5..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_read_rsp.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 12, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_READ_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.read_rsp.handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.read_rsp.offset, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.read_rsp.len, &(p_buf[index])); - - SER_ASSERT_LENGTH_LEQ(index + p_event->evt.gattc_evt.params.read_rsp.len, *p_buf_len); - - if (p_event->evt.gattc_evt.params.read_rsp.len > 0) - { - memcpy(&(p_buf[index]), - &(p_event->evt.gattc_evt.params.read_rsp.data[0]), - p_event->evt.gattc_evt.params.read_rsp.len); - index += p_event->evt.gattc_evt.params.read_rsp.len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_rel_disc_rsp.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_rel_disc_rsp.c deleted file mode 100644 index fd83b62..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_rel_disc_rsp.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t error_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GATTC_EVT_REL_DISC_RSP; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - error_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&p_event->evt.gattc_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&p_event->evt.gattc_evt.gatt_status, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&p_event->evt.gattc_evt.error_handle, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_evt_rel_disc_rsp_t_enc(&p_event->evt.gattc_evt.params.rel_disc_rsp, - p_buf, - total_len, - &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - *p_buf_len = index; - - return error_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_timeout.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_timeout.c deleted file mode 100644 index ee1e08d..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_timeout.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_TIMEOUT, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.timeout.src; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_write_rsp.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_write_rsp.c deleted file mode 100644 index 7692b94..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_evt_write_rsp.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 13, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_WRITE_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.write_rsp.write_op; - index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.offset, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.len, &(p_buf[index])); - - SER_ASSERT_LENGTH_LEQ(index + p_event->evt.gattc_evt.params.write_rsp.len, *p_buf_len); - - if (p_event->evt.gattc_evt.params.write_rsp.len > 0) - { - memcpy(&(p_buf[index]), - &(p_event->evt.gattc_evt.params.write_rsp.data[0]), - p_event->evt.gattc_evt.params.write_rsp.len); - index += p_event->evt.gattc_evt.params.write_rsp.len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_hv_confirm.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_hv_confirm.c deleted file mode 100644 index 6a1be3f..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_hv_confirm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_HV_CONFIRM, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_primary_services_discover.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_primary_services_discover.c deleted file mode 100644 index 678e5e8..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_primary_services_discover.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_start_handle, - ble_uuid_t * * const pp_srvc_uuid) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_start_handle); - SER_ASSERT_NOT_NULL(pp_srvc_uuid); - SER_ASSERT_NOT_NULL(*pp_srvc_uuid); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - uint16_dec(p_buf, packet_len, &index, p_start_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_srvc_uuid = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 1, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_srvc_uuid)->uuid); - uint8_dec(p_buf, packet_len, &index, &(*pp_srvc_uuid)->type); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_read.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_read.c deleted file mode 100644 index ca0af98..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_read.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle, - uint16_t * const p_offset) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - SER_ASSERT_NOT_NULL(p_offset); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gattc_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_READ, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_relationships_discover.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_relationships_discover.c deleted file mode 100644 index 7a61a3a..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_relationships_discover.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_relationships_discover_req_dec( - uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const - pp_handle_range) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_handle_range = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->start_handle); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->end_handle); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_write.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_write.c deleted file mode 100644 index e889bce..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gattc_write.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" -#include - - -uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_write_params_t * * const pp_write_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_write_params); - SER_ASSERT_NOT_NULL(*pp_write_params); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - uint8_t op_code; - err_code = uint8_t_dec(p_buf, packet_len, &index, &op_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT(op_code == SD_BLE_GATTC_WRITE, NRF_ERROR_INVALID_PARAM); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_write_params, - ble_gattc_write_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gattc_write_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_WRITE, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_characteristic_add.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_characteristic_add.c deleted file mode 100644 index 1e1a9de..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_characteristic_add.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * service_handle, - ble_gatts_char_md_t * * const pp_char_md, - ble_gatts_attr_t * * const pp_attr_char_value, - ble_gatts_char_handles_t * * const pp_handles) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(service_handle); - SER_ASSERT_NOT_NULL(pp_char_md); - SER_ASSERT_NOT_NULL(pp_attr_char_value); - SER_ASSERT_NOT_NULL(pp_handles); - SER_ASSERT_NOT_NULL(*pp_char_md); - SER_ASSERT_NOT_NULL(*pp_attr_char_value); - SER_ASSERT_NOT_NULL(*pp_handles); - - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len); - uint32_t err_code; - SER_ASSERT_LENGTH_LEQ(2, buf_len - index); - uint16_dec(p_buf, buf_len, &index, service_handle); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_char_md, ble_gatts_char_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - &index, - (void * *)pp_attr_char_value, - ble_gatts_attr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_handles, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(index == buf_len, NRF_ERROR_INVALID_LENGTH); - - return err_code; -} - -uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gatts_char_handles_t const * const p_handles) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - SER_ASSERT_LENGTH_LEQ(1 + 4, total_len); - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_CHARACTERISTIC_ADD, - return_code, - p_buf, - p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code == NRF_SUCCESS) /* Add value and it's length. */ - { - err_code = cond_field_enc((void *)p_handles, - p_buf, - total_len, - p_buf_len, - ble_gatts_char_handles_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_descriptor_add.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_descriptor_add.c deleted file mode 100644 index 1929309..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_descriptor_add.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_char_handle, - ble_gatts_attr_t * * const pp_attr, - uint16_t * * const pp_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_char_handle); - SER_ASSERT_NOT_NULL(pp_attr); - SER_ASSERT_NOT_NULL(*pp_attr); - SER_ASSERT_NOT_NULL(pp_handle); - SER_ASSERT_NOT_NULL(*pp_handle); - - uint32_t index = 0; - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_DESCRIPTOR_ADD, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_char_handle); - - uint32_t err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_attr, - ble_gatts_attr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_handle, - NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4, total_len); - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_DESCRIPTOR_ADD, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 2, total_len); - - err_code = uint16_t_enc(&handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_conn.h b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_conn.h deleted file mode 100644 index c4ace61..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_conn.h +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_EVT_CONN_H__ -#define BLE_GATTS_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gatts_evt_conn GATTS Connectivity event encoders - * @{ - * @ingroup ser_conn_s110_codecs - * - * @brief GATTS Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes @ref BLE_GATTS_EVT_HVC event. - * - * @sa @ref nrf51_gatts_evt_hvc_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event. - * - * @sa @ref nrf51_evt_rw_authorize_request for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes @ref BLE_GATTS_EVT_SC_CONFIRM event. - * - * @sa @ref nrf51_gatts_evt_sc_confirm_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes @ref BLE_GATTS_EVT_SYS_ATTR_MISSING event. - * - * @sa @ref nrf51_evt_sys_attr_missing_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes @ref BLE_GATTS_EVT_TIMEOUT event. - * - * @sa @ref nrf51_gatts_evt_timeout_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes @ref BLE_GATTS_EVT_WRITE event. - * - * @sa @ref nrf51_evt_write_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_hvc.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_hvc.c deleted file mode 100644 index 872e9a5..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_hvc.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 2, *p_buf_len); - - index += uint16_encode(BLE_GATTS_EVT_HVC, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.params.hvc.handle, &(p_buf[index])); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_rw_authorize_request.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_rw_authorize_request.c deleted file mode 100644 index 770df04..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_rw_authorize_request.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "conn_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_conn_user_mem_table[]; - -uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_NOT_NULL(p_event); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gatts_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_evt_rw_authorize_request_t_enc( - &(p_event->evt.gatts_evt.params.authorize_request), - p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if((p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)) - { - uint32_t conn_index; - - if(conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_enc(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_sc_confirm.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_sc_confirm.c deleted file mode 100644 index 1bf1e0f..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_sc_confirm.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE + 2, *p_buf_len); - - uint32_t index = 0; - index += uint16_encode(BLE_GATTS_EVT_SC_CONFIRM, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_sys_attr_missing.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_sys_attr_missing.c deleted file mode 100644 index cb7c3e4..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_sys_attr_missing.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GATTS_EVT_SYS_ATTR_MISSING, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gatts_evt.params.sys_attr_missing.hint; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_timeout.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_timeout.c deleted file mode 100644 index 096ec5c..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_timeout.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GATTS_EVT_TIMEOUT, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gatts_evt.params.timeout.src; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_write.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_write.c deleted file mode 100644 index d37ce9f..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_evt_write.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "conn_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_conn_user_mem_table[]; - -uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint16_t evt_header = BLE_GATTS_EVT_WRITE; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gatts_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_evt_write_t_enc(&(p_event->evt.gatts_evt.params.write), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if(p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) - { - uint32_t conn_index; - - if(conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_enc(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_hvx.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_hvx.c deleted file mode 100644 index 67bd566..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_hvx.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_gatts_hvx_params_t * * const pp_hvx_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_hvx_params); - SER_ASSERT_NOT_NULL(*pp_hvx_params); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_HVX, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - uint32_t err_code = cond_field_dec(p_buf, packet_len, - &index, - (void * *)pp_hvx_params, - ble_gatts_hvx_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_bytes_written) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_HVX, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - uint32_t index = *p_buf_len; - - err_code = cond_field_enc(p_bytes_written, p_buf, total_len, &index, uint16_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_include_add.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_include_add.c deleted file mode 100644 index 766313f..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_include_add.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_service_handle, - uint16_t * const p_inc_srvc_handle, - uint16_t * * const pp_include_handle) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_service_handle); - SER_ASSERT_NOT_NULL(p_inc_srvc_handle); - SER_ASSERT_NOT_NULL(pp_include_handle); - SER_ASSERT_LENGTH_EQ(6, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_INCLUDE_ADD, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_service_handle); - uint16_dec(p_buf, packet_len, &index, p_inc_srvc_handle); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_include_handle = NULL; - } - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_include_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - uint32_t err_code; - - err_code = op_status_enc(SD_BLE_GATTS_INCLUDE_ADD, return_code, p_buf, p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - SER_ASSERT_NOT_NULL(p_include_handle); - err_code = uint16_t_enc(p_include_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; //update change made by op_status_enc - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_rw_authorize_reply.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_rw_authorize_reply.c deleted file mode 100644 index 94390bb..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_rw_authorize_reply.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gatts_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gatts_rw_authorize_reply_req_dec( - uint8_t const * const p_buf, - uint32_t - packet_len, - uint16_t * - p_conn_handle, - ble_gatts_rw_authorize_reply_params_t * * const - pp_reply_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - - uint32_t index = SER_CMD_HEADER_SIZE; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, packet_len, &index, - (void * *)pp_reply_params, ble_gatts_rw_authorize_reply_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_service_add.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_service_add.c deleted file mode 100644 index e1d7c68..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_service_add.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * const p_type, - ble_uuid_t * * const pp_uuid, - uint16_t * * const pp_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_type); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(pp_handle); - SER_ASSERT_NOT_NULL(*pp_handle); - - uint32_t index = SER_CMD_DATA_POS; - - uint32_t err_code; - SER_ASSERT_LENGTH_LEQ(3, buf_len - index); - err_code = uint8_t_dec(p_buf, buf_len, &index, p_type); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_handle, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(index == buf_len, NRF_ERROR_INVALID_LENGTH); - - return err_code; -} - -uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - uint32_t err_code; - - err_code = op_status_enc(SD_BLE_GATTS_SERVICE_ADD, return_code, p_buf, p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; //this seems silly but it is not - } - SER_ASSERT_NOT_NULL(p_handle); - err_code = uint16_t_enc(p_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; //update change made by op_status_enc - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_service_changed.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_service_changed.c deleted file mode 100644 index 37e9e34..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_service_changed.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - uint16_t * p_start_handle, - uint16_t * p_end_handle) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_start_handle); - SER_ASSERT_NOT_NULL(p_end_handle); - - SER_ASSERT_LENGTH_EQ(SER_CMD_HEADER_SIZE + 6, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_SERVICE_CHANGED, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - uint16_dec(p_buf, packet_len, &index, p_start_handle); - uint16_dec(p_buf, packet_len, &index, p_end_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_SERVICE_CHANGED, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_sys_attr_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_sys_attr_get.c deleted file mode 100644 index affbe8e..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_sys_attr_get.c +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * * const pp_sys_attr_data, - uint16_t * * const pp_sys_attr_data_len, - uint32_t * const p_flags) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_sys_attr_data); - SER_ASSERT_NOT_NULL(pp_sys_attr_data_len); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_SYS_ATTR_GET, NRF_ERROR_INVALID_PARAM); - index++; - - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_flags); - *p_conn_handle = uint16_decode(&p_buf[index]); - index += sizeof (uint16_t); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - - SER_ASSERT_NOT_NULL(*pp_sys_attr_data_len); - **pp_sys_attr_data_len = uint16_decode(&p_buf[index]); - index += sizeof (uint16_t); - } - else - { - *pp_sys_attr_data_len = NULL; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, packet_len); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_sys_attr_data = NULL; - } - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_flags); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_sys_attr_data, - uint16_t const * const p_sys_attr_data_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - SER_ASSERT_LENGTH_LEQ(1 + 4, total_len); - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_SYS_ATTR_GET, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_sys_attr_data); - SER_ASSERT_NOT_NULL(p_sys_attr_data_len); - uint32_t index = *p_buf_len; - uint16_t sys_attr_len = 0; - - SER_ASSERT_LENGTH_LEQ(index + 2, total_len); - - if (p_sys_attr_data_len != NULL) - { - index += uint16_encode(*p_sys_attr_data_len, &p_buf[index]); - sys_attr_len = *p_sys_attr_data_len; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, total_len); - p_buf[index++] = p_sys_attr_data ? SER_FIELD_PRESENT : - SER_FIELD_NOT_PRESENT; - - SER_ASSERT_LENGTH_LEQ(index + sys_attr_len, total_len); - - if (p_sys_attr_data != NULL) - { - memcpy(&p_buf[index], p_sys_attr_data, sys_attr_len); - index += sys_attr_len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_sys_attr_set.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_sys_attr_set.c deleted file mode 100644 index b25d9d9..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_sys_attr_set.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * * const pp_sys_attr_data, - uint16_t * const p_sys_attr_data_len, - uint32_t * const p_flags) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - uint16_t sys_attr_data_len_temp; - uint16_t * p_sys_attr_data_len_temp = &sys_attr_data_len_temp; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_sys_attr_data); - SER_ASSERT_NOT_NULL(*pp_sys_attr_data); - SER_ASSERT_NOT_NULL(p_sys_attr_data_len); - SER_ASSERT_NOT_NULL(p_flags); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 7, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_sys_attr_data = NULL; - SER_ASSERT_LENGTH_EQ(index + 4, packet_len); - *p_sys_attr_data_len = 0; - break; - - case SER_FIELD_PRESENT: - uint16_dec(p_buf, packet_len, &index, p_sys_attr_data_len_temp); - SER_ASSERT_LENGTH_LEQ(*p_sys_attr_data_len_temp, *p_sys_attr_data_len); - *p_sys_attr_data_len = *p_sys_attr_data_len_temp; - SER_ASSERT_LENGTH_EQ(index + *p_sys_attr_data_len + 4, packet_len); - memcpy(*pp_sys_attr_data, &p_buf[index], *p_sys_attr_data_len); - index += *p_sys_attr_data_len; - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_flags); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - - -uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_SYS_ATTR_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_value_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_value_get.c deleted file mode 100644 index eebd031..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_value_get.c +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle, - ble_gatts_value_t * * const pp_value) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - SER_ASSERT_NOT_NULL(pp_value); - SER_ASSERT_NOT_NULL(*pp_value); - SER_ASSERT_NOT_NULL((*pp_value)->p_value); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 5, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_VALUE_GET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_value)->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_value)->offset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, packet_len - index); - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - (*pp_value)->p_value = NULL; - } - } - else - { - *pp_value = NULL; - } - - return err_code; -} - - -uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gatts_value_t * const p_value) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_RSP_HEADER_SIZE, *p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_VALUE_GET, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - uint32_t index = *p_buf_len; - - if (return_code == NRF_SUCCESS) - { - SER_ASSERT_NOT_NULL(p_value); - - err_code = ble_gatts_value_t_enc(p_value, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_value_set.c b/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_value_set.c deleted file mode 100644 index 4a7eb2b..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_value_set.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "cond_field_serialization.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - uint16_t * p_handle, - ble_gatts_value_t * * const pp_value) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - SER_ASSERT_NOT_NULL(pp_value); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(4, packet_len - index); //make sure that payload length is at least 4 bytes - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - uint16_dec(p_buf, packet_len, &index, p_handle); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_value, ble_gatts_value_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buff, - uint32_t * const p_buff_len, - ble_gatts_value_t * p_value) -{ - SER_ASSERT_NOT_NULL(p_buff); - SER_ASSERT_NOT_NULL(p_buff_len); - - uint32_t buf_len = *p_buff_len; - uint32_t index = 0; - uint32_t err_code; - - err_code = op_status_enc(SD_BLE_GATTS_VALUE_SET, return_code, p_buff, p_buff_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - SER_ASSERT_NOT_NULL(p_value); - err_code = ble_gatts_value_t_enc(p_value, p_buff, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buff_len = index; //update change made by op_status_enc - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_cid_register.c b/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_cid_register.c deleted file mode 100644 index 9e2a775..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_cid_register.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_l2cap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_cid) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_cid); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_LENGTH_EQ(3, buf_len); - SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_REGISTER, NRF_ERROR_INVALID_PARAM); - - index++; - err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_REGISTER, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_cid_unregister.c b/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_cid_unregister.c deleted file mode 100644 index 74d4619..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_cid_unregister.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_l2cap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_cid) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_cid); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_LENGTH_EQ(3, buf_len); - SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_UNREGISTER, NRF_ERROR_INVALID_PARAM); - - index++; - err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_UNREGISTER, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_conn.h b/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_conn.h deleted file mode 100644 index 773bac4..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_conn.h +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (c) 2011 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * - */ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_l2cap_conn L2CAP Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s110_codecs - * - * @brief L2CAP Connectivity command request decoders and command response encoders. - */ - -#ifndef BLE_L2CAP_CONN_H__ -#define BLE_L2CAP_CONN_H__ - -#include "ble.h" -#include "ble_types.h" -#include "ble_ranges.h" -#include "ble_err.h" -#include "ble_l2cap.h" - -/**@brief Decodes @ref sd_ble_l2cap_cid_register command request. - * - * @sa @ref nrf51_ble_l2cap_cid_register for packet format, - * @ref ble_l2cap_cid_register_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[in] p_cid Pointer to L2CAP CID. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_cid); - -/**@brief Encodes @ref sd_ble_l2cap_cid_register command response. - * - * @sa @ref nrf51_ble_l2cap_cid_register for packet format. - * @ref ble_l2cap_cid_register_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_l2cap_cid_unregister command request. - * - * @sa @ref nrf51_ble_l2cap_cid_unregister for packet format, - * @ref ble_l2cap_cid_unregister_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[in] p_cid Pointer to L2CAP CID. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_cid); - -/**@brief Encodes @ref sd_ble_l2cap_cid_unregister command response. - * - * @sa @ref nrf51_ble_l2cap_cid_unregister for packet format. - * @ref ble_l2cap_cid_unregister_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_l2cap_tx command request. - * - * @sa @ref nrf51_ble_l2cap_tx for packet format, - * @ref ble_l2cap_tx_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[in] p_conn_handle Pointer to connection handle. - * @param[in] pp_l2cap_header Pointer to pointer to L2CAP header. - * @param[in] pp_data Pointer to pointer L2CAP data. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, - uint16_t * p_conn_handle, - ble_l2cap_header_t * * const pp_l2cap_header, - uint8_t const * * pp_data); - -/**@brief Encodes @ref sd_ble_l2cap_tx command response. - * - * @sa @ref nrf51_ble_l2cap_tx for packet format. - * @ref ble_l2cap_tx_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -#endif //BLE_L2CAP_CONN_H__ - -/** - @} - */ diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_evt_conn.h b/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_evt_conn.h deleted file mode 100644 index 805814e..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_evt_conn.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_L2CAP_EVT_CONN_H__ -#define BLE_L2CAP_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_l2cap_evt_conn L2CAP Connectivity event encoders - * @{ - * @ingroup ser_conn_s110_codecs - * - * @brief L2CAP Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes ble_l2cap_evt_rx event. - * - * @sa @ref nrf51_l2cap_evt_rx_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_evt_rx.c b/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_evt_rx.c deleted file mode 100644 index 15793ed..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_evt_rx.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_l2cap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code; - uint32_t total_len = *p_buf_len; - - uint16_t evt_id = BLE_L2CAP_EVT_RX; - - err_code = uint16_t_enc(&evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.l2cap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_l2cap_evt_rx_t_enc(&(p_event->evt.l2cap_evt.params.rx), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_tx.c b/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_tx.c deleted file mode 100644 index c574b40..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_l2cap_tx.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include -#include "ble_l2cap_conn.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, - uint16_t * p_conn_handle, - ble_l2cap_header_t * * const pp_l2cap_header, - uint8_t const * * pp_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_l2cap_header); - SER_ASSERT_NOT_NULL(*pp_l2cap_header); - SER_ASSERT_NOT_NULL(pp_data); - //SER_ASSERT_NOT_NULL(*pp_data); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_l2cap_header, - ble_l2cap_header_t_dec); - - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*pp_l2cap_header != NULL) - { - *pp_data = p_buf + index + 1; - index += 1 + (*pp_l2cap_header)->len; - } - else - { - *pp_data = NULL; - index++; - } - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_TX, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_opt_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_opt_get.c deleted file mode 100644 index 7f2da63..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_opt_get.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t **const pp_opt ) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_NOT_NULL(pp_opt); - SER_ASSERT_NOT_NULL(*pp_opt); - SER_ASSERT_LENGTH_EQ(SER_CMD_HEADER_SIZE + 4 + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_OPT_GET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (*p_opt_id == BLE_GAP_OPT_CH_MAP) || - (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (*p_opt_id == BLE_GAP_OPT_PASSKEY) || - (*p_opt_id == BLE_GAP_OPT_PRIVACY) || - (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_opt = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_opt_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint32_t opt_id, - ble_opt_t const * const p_opt) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_OPT_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_opt); - SER_ASSERT(((opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (opt_id == BLE_GAP_OPT_CH_MAP) || - (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (opt_id == BLE_GAP_OPT_PASSKEY) || - (opt_id == BLE_GAP_OPT_PRIVACY) || - (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - uint32_t index = *p_buf_len; - err_code = uint32_t_enc(&opt_id, p_buf, total_len, &index); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - switch (opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_enc((void *)&(p_opt->common_opt.radio_cpu_mutex), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_enc((void *)&(p_opt->gap_opt.ch_map), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_enc((void *)&(p_opt->gap_opt.local_conn_latency), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_enc((void *)&(p_opt->gap_opt.passkey), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_enc((void *)&(p_opt->gap_opt.privacy), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_enc((void *)&(p_opt->gap_opt.scan_req_report), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_enc((void *)&(p_opt->gap_opt.compat_mode), p_buf, total_len, &index); - break; - } - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_opt_id_pre_decoder.c b/components/serialization/connectivity/codecs/s110/serializers/ble_opt_id_pre_decoder.c deleted file mode 100644 index 7b0e749..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_opt_id_pre_decoder.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_OPT_SET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_opt_set.c b/components/serialization/connectivity/codecs/s110/serializers/ble_opt_set.c deleted file mode 100644 index 8a0b6e5..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_opt_set.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t **const pp_opt ) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_NOT_NULL(pp_opt); - SER_ASSERT_NOT_NULL(*pp_opt); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4 + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_OPT_SET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (*p_opt_id == BLE_GAP_OPT_CH_MAP) || - (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (*p_opt_id == BLE_GAP_OPT_PASSKEY) || - (*p_opt_id == BLE_GAP_OPT_PRIVACY) || - (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_opt = NULL; - } - else - { - switch(*p_opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_dec(p_buf, packet_len, &index, &((*pp_opt)->common_opt.radio_cpu_mutex)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.ch_map)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.local_conn_latency)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.passkey)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.privacy)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.scan_req_report)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.compat_mode)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_opt_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_OPT_SET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_tx_buffer_count_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_tx_buffer_count_get.c deleted file mode 100644 index eec8bb9..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_tx_buffer_count_get.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" - -uint32_t ble_tx_buffer_count_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint8_t * * const pp_count) -{ - SER_ASSERT_NOT_NULL(p_buf); - - uint32_t index = 0; - uint8_t opcode; - uint32_t err_code; - - err_code = uint8_t_dec(p_buf, packet_len, &index, &opcode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT(opcode == SD_BLE_TX_BUFFER_COUNT_GET, NRF_ERROR_INVALID_PARAM); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_count, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_tx_buffer_count_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_count) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_TX_BUFFER_COUNT_GET, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = cond_field_enc(p_count, p_buf, total_len, p_buf_len, uint8_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_user_mem_reply.c b/components/serialization/connectivity/codecs/s110/serializers/ble_user_mem_reply.c deleted file mode 100644 index d3f0108..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_user_mem_reply.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_user_mem_block_t * * const pp_mem_block) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_mem_block); - SER_ASSERT_NOT_NULL(*pp_mem_block); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_USER_MEM_REPLY, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - // Decoding order is different than structure elements order because - // mem block length is received first - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_mem_block)->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **)&((*pp_mem_block)->p_mem), NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - *pp_mem_block = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_USER_MEM_REPLY, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_uuid_decode.c b/components/serialization/connectivity/codecs/s110/serializers/ble_uuid_decode.c deleted file mode 100644 index 000e4d8..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_uuid_decode.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, - uint8_t * p_uuid_le_len, - uint8_t * * const pp_uuid_le, - ble_uuid_t * * const pp_uuid) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_uuid_le_len); - uint32_t err_code; - uint32_t index = 0; - uint8_t opcode = SD_BLE_UUID_DECODE; - - SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - index)); - uint8_dec(p_buf, buf_len, &index, &opcode); - SER_ASSERT(opcode == SD_BLE_UUID_DECODE, NRF_ERROR_INVALID_DATA); - - err_code = len8data_dec(p_buf, buf_len, &index, pp_uuid_le, p_uuid_le_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_uuid_t const * const p_uuid) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_UUID_DECODE, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - *p_buf_len = index; - return NRF_SUCCESS; - } - - err_code = cond_field_enc((void *)p_uuid, p_buf, total_len, &index, ble_uuid_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_uuid_encode.c b/components/serialization/connectivity/codecs/s110/serializers/ble_uuid_encode.c deleted file mode 100644 index 0843668..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_uuid_encode.c +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_uuid_t * * const pp_uuid, - uint8_t * * const pp_uuid_le_len, - uint8_t * * const pp_uuid_le) -{ - uint32_t index = SER_CMD_HEADER_SIZE; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(pp_uuid_le_len); - SER_ASSERT_NOT_NULL(pp_uuid_le); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid_le_len); - SER_ASSERT_NOT_NULL(*pp_uuid_le); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 3, packet_len); - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - index++; - *pp_uuid = NULL; - } - else if (p_buf[index] == SER_FIELD_PRESENT) - { - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 6, packet_len); - index++; - uint16_dec(p_buf, packet_len, &index, &((*pp_uuid)->uuid)); - (*pp_uuid)->type = p_buf[index++]; - } - else - { - return NRF_ERROR_INVALID_DATA; - } - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - *pp_uuid_le_len = NULL; - } - else if (p_buf[index] != SER_FIELD_PRESENT) - { - return NRF_ERROR_INVALID_DATA; - } - - index++; - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - *pp_uuid_le = NULL; - } - else if (p_buf[index] != SER_FIELD_PRESENT) - { - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index + 1, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t uuid_le_len, - uint8_t const * const p_uuid_le) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_UUID_ENCODE, return_code, - p_buf, p_buf_len); - uint32_t index = *p_buf_len; - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, total_len); - p_buf[index++] = uuid_le_len; - - if (p_uuid_le != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + uuid_le_len, total_len); - memcpy(p_buf + index, p_uuid_le, uuid_le_len); - index += uuid_le_len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_uuid_vs_add.c b/components/serialization/connectivity/codecs/s110/serializers/ble_uuid_vs_add.c deleted file mode 100644 index 5deeac7..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_uuid_vs_add.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf, - uint16_t buf_len, - ble_uuid128_t * * const pp_uuid, - uint8_t * * const pp_uuid_type) -{ - uint32_t index = SER_CMD_HEADER_SIZE; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(pp_uuid_type); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid_type); - - uint32_t err_code; - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid128_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid_type, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_uuid_type) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_UUID_VS_ADD, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = cond_field_enc((void *)p_uuid_type, p_buf, total_len, &index, uint8_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_version_get.c b/components/serialization/connectivity/codecs/s110/serializers/ble_version_get.c deleted file mode 100644 index 28dbe54..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_version_get.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_version_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_version_t * * const pp_version) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_version); - SER_ASSERT_NOT_NULL(*pp_version); - SER_ASSERT_LENGTH_EQ(SER_CMD_HEADER_SIZE + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_VERSION_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_version = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_version_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_version_t const * const p_version) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_VERSION_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_version); - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 5, total_len); - p_buf[index++] = p_version->version_number; - index += uint16_encode(p_version->company_id, &p_buf[index]); - index += uint16_encode(p_version->subversion_number, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/conn_ble_gap_sec_keys.c b/components/serialization/connectivity/codecs/s110/serializers/conn_ble_gap_sec_keys.c deleted file mode 100644 index f0bf74d..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/conn_ble_gap_sec_keys.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "conn_ble_gap_sec_keys.h" -#include "ser_config.h" -#include "nrf_error.h" -#include - -ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS]; - -uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -/**@brief GAP connection - keyset mapping structure. - * - * @note This structure is used to map keysets to connection instances, and will be stored in a static table. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that keys for this connection are used by soft device. 0: keys used; 1: keys not used*/ - ble_gap_sec_keyset_t keyset; /**< Keyset structure see @ref ble_gap_sec_keyset_t.*/ - ble_gap_enc_key_t enc_key_periph; /**< Peripheral Encryption Key, see @ref ble_gap_enc_key_t.*/ - ble_gap_id_key_t id_key_periph; /**< Peripheral Identity Key, see @ref ble_gap_id_key_t.*/ - ble_gap_sign_info_t sign_key_periph; /**< Peripheral Signing Information, see @ref ble_gap_sign_info_t.*/ - ble_gap_enc_key_t enc_key_central; /**< Central Encryption Key, see @ref ble_gap_enc_key_t.*/ - ble_gap_id_key_t id_key_central; /**< Central Identity Key, see @ref ble_gap_id_key_t.*/ - ble_gap_sign_info_t sign_key_central; /**< Central Signing Information, see @ref ble_gap_sign_info_t.*/ -} ser_ble_gap_conn_keyset_t; - -/**@brief allocates instance in m_conn_keys_table[] for storage of encryption keys. - * - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS great success. - * @retval NRF_ERROR_NO_MEM no free instance available. - */ -uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_gap_sec_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_conn_keys_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context table entry found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_CONN_BLE_GAP_SEC_KEYS_H diff --git a/components/serialization/connectivity/codecs/s110/serializers/conn_ble_user_mem.c b/components/serialization/connectivity/codecs/s110/serializers/conn_ble_user_mem.c deleted file mode 100644 index 7ee0563..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/conn_ble_user_mem.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "conn_ble_user_mem.h" -#include "ser_config.h" -#include "nrf_error.h" -#include - - - -ser_ble_user_mem_t m_conn_user_mem_table[SER_MAX_CONNECTIONS]; - -uint32_t conn_ble_user_mem_context_create(uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -/**@brief Connection - user memory mapping structure. - * - * @note This structure is used to map keysets to connection instances, and will be stored in a static table. - */ -//lint -esym(452,ser_ble_user_mem_t) -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that user memory for this connection is used by soft device. 0: memory used; 1: memory not used*/ - ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t.*/ - uint8_t mem_table[64]; /**< Memory table.*/ -} ser_ble_user_mem_t; - -/**@brief allocates instance in m_user_mem_table[] for storage. - * - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS great success. - * @retval NRF_ERROR_NO_MEM no free instance available. - */ -uint32_t conn_ble_user_mem_context_create(uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_user_mem_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_user_mem_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context table entry found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_CONN_BLE_USER_MEM_H diff --git a/components/serialization/connectivity/codecs/s110/serializers/nrf_soc_conn.h b/components/serialization/connectivity/codecs/s110/serializers/nrf_soc_conn.h deleted file mode 100644 index ea2b746..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/nrf_soc_conn.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_SOC_CONN_H__ -#define NRF_SOC_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup soc_conn SOC Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s110_codecs - * - * @brief SOC Connectivity command request decoders and command response encoderss. - */ -#include "nrf_soc.h" - -/**@brief Decodes @ref sd_power_system_off command request. - * - * @sa @ref nrf51_sd_power_off for packet format. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in] packet_len Length (in bytes) of request packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. - */ -uint32_t power_system_off_req_dec(uint8_t const * const p_buf, uint16_t packet_len); - - -/**@brief Decodes @ref sd_temp_get command request. - * - * @sa @ref nrf51_sd_temp_get for packet format. - * @ref temp_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in] buf_len Length (in bytes) of request packet. - * @param[out] pp_temp Pointer to pointer to result of temperature measurement. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. - */ -uint32_t temp_get_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - int32_t * * const pp_temp); - -/**@brief Encodes @ref sd_temp_get command response. - * - * @sa @ref nrf51_sd_temp_get for packet format. - * @ref temp_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_temp Pointer to result of temperature measurement. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t temp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int32_t * const p_temp); - -/** @} */ -#endif - diff --git a/components/serialization/connectivity/codecs/s110/serializers/power_system_off.c b/components/serialization/connectivity/codecs/s110/serializers/power_system_off.c deleted file mode 100644 index 00e66b2..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/power_system_off.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "nrf_soc_conn.h" -#include "ble_serialization.h" - -uint32_t power_system_off_req_dec(uint8_t const * const p_buf, - uint16_t packet_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - - uint32_t index = 0; - SER_ASSERT_LENGTH_LEQ(1, packet_len); - SER_ASSERT(p_buf[index] == SD_POWER_SYSTEM_OFF, NRF_ERROR_INVALID_PARAM); - index++; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s110/serializers/temp_get.c b/components/serialization/connectivity/codecs/s110/serializers/temp_get.c deleted file mode 100644 index 8cd2081..0000000 --- a/components/serialization/connectivity/codecs/s110/serializers/temp_get.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "nrf_soc.h" -#include "nrf_error.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" - -uint32_t temp_get_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - int32_t * * const pp_temp) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_temp); - SER_ASSERT_NOT_NULL(*pp_temp); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len); - SER_ASSERT(p_buf[index] == SD_TEMP_GET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_temp, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t temp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int32_t * const p_temp) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_temp); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t total_len = *p_buf_len; - - err_code = ser_ble_cmd_rsp_status_code_enc(SD_TEMP_GET, - return_code, - p_buf, - p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - index += *p_buf_len; - - if (return_code == NRF_SUCCESS) - { - err_code = uint32_t_enc(p_temp, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw.h b/components/serialization/connectivity/codecs/s120/middleware/conn_mw.h deleted file mode 100644 index 378a96f..0000000 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_H -#define _CONN_MW_H - -#include - -/**@brief Connectivity Middleware dispatcher function - * - * @details It will handle decode the opcode from RX buffer and based on the opcode it will search - * for registered handler. Handler is called once it is found. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. - */ -uint32_t conn_mw_handler (uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); -#endif //_CONN_MW_H diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble.c b/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble.c deleted file mode 100644 index 78a55ea..0000000 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble.c +++ /dev/null @@ -1,287 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "ble_conn.h" -#include "conn_mw_ble.h" -#include "ble_serialization.h" -#include "conn_ble_user_mem.h" - -extern ser_ble_user_mem_t m_conn_user_mem_table[]; - -uint32_t conn_mw_ble_tx_buffer_count_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t count; - uint8_t * p_count = &count; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_tx_buffer_count_get_req_dec(p_rx_buf, rx_buf_len, &p_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_tx_buffer_count_get(p_count); - - err_code = ble_tx_buffer_count_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_uuid_vs_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_uuid128_t uuid; - ble_uuid128_t * p_uuid = &uuid; - uint8_t uuid_type; - uint8_t * p_uuid_type = &uuid_type; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_uuid_vs_add_req_dec(p_rx_buf, rx_buf_len, &p_uuid, &p_uuid_type); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_uuid_vs_add(p_uuid, p_uuid_type); - - err_code = ble_uuid_vs_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid_type); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - return err_code; -} - -uint32_t conn_mw_ble_uuid_decode(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t raw_uuid[16]; - uint8_t uuid_len = sizeof (raw_uuid); - uint8_t * p_raw_uuid = raw_uuid; - ble_uuid_t uuid; - ble_uuid_t * p_uuid = &uuid; - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_uuid_decode_req_dec(p_rx_buf, rx_buf_len, &uuid_len, &p_raw_uuid, &p_uuid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_uuid_decode(uuid_len, p_raw_uuid, p_uuid); - - err_code = ble_uuid_decode_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_uuid_encode(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t raw_uuid[16]; - uint8_t uuid_len = sizeof (raw_uuid); - uint8_t * p_uuid_len = &uuid_len; - uint8_t * p_raw_uuid = raw_uuid; - ble_uuid_t uuid; - ble_uuid_t * p_uuid = &uuid; - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_uuid_encode_req_dec(p_rx_buf, rx_buf_len, &p_uuid, &p_uuid_len, &p_raw_uuid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_uuid_encode(p_uuid, p_uuid_len, p_raw_uuid); - - err_code = ble_uuid_encode_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, uuid_len, p_raw_uuid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_version_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_version_t version; - ble_version_t * p_version = &version; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_version_get_req_dec(p_rx_buf, rx_buf_len, &p_version); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_version_get(p_version); - - err_code = ble_version_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_version); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_opt_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t opt_id; - ble_opt_t opt; - ble_opt_t *p_opt = &opt; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_opt_get_req_dec(p_rx_buf, rx_buf_len, &opt_id, &p_opt); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_opt_get(opt_id, p_opt); - - err_code = ble_opt_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, opt_id, p_opt); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t opt_id = 0xFFFFFFFF; - uint16_t act_latency; - uint8_t passkey[BLE_GAP_PASSKEY_LEN]; - ble_gap_irk_t irk = {{0}}; - uint32_t err_code = NRF_SUCCESS; - - /* Pre-decode type of ble_opt_t union */ - err_code = ble_opt_id_pre_dec(p_rx_buf, rx_buf_len, &opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - ble_opt_t opt; - ble_opt_t *p_opt = &opt; - /* Initialaize appropriate pointers inside opt union based on opt_id */ - switch(opt_id) - { - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - opt.gap_opt.local_conn_latency.p_actual_latency = &act_latency; - break; - case BLE_GAP_OPT_PASSKEY: - opt.gap_opt.passkey.p_passkey = passkey; - break; - case BLE_GAP_OPT_PRIVACY: - opt.gap_opt.privacy.p_irk = &irk; - break; - } - - uint32_t sd_err_code; - - err_code = ble_opt_set_req_dec(p_rx_buf, rx_buf_len, &opt_id, &p_opt); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_opt_set(opt_id, p_opt); - - err_code = ble_opt_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_enable(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_enable_params_t params; - ble_enable_params_t * p_params = ¶ms; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_enable_req_dec(p_rx_buf, rx_buf_len, &p_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_enable(p_params); - - err_code = ble_enable_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t * p_conn_handle; - ble_user_mem_block_t * p_mem_block; - uint32_t err_code = NRF_SUCCESS; - uint32_t user_mem_tab_index; - - /* Allocate user memory context for SoftDevice */ - err_code = conn_ble_user_mem_context_create(&user_mem_tab_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_conn_handle = &(m_conn_user_mem_table[user_mem_tab_index].conn_handle); - p_mem_block = &(m_conn_user_mem_table[user_mem_tab_index].mem_block); - - uint32_t sd_err_code; - - err_code = ble_user_mem_reply_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &p_mem_block); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_user_mem_reply(*p_conn_handle, p_mem_block); - - err_code = ble_user_mem_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gap.c b/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gap.c deleted file mode 100644 index 4628349..0000000 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gap.c +++ /dev/null @@ -1,830 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "conn_mw_ble_gap.h" -#include "ble_serialization.h" -#include "conn_ble_gap_sec_keys.h" -#include - -extern ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS]; - -uint32_t conn_mw_ble_gap_address_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t addr_cycle_mode; - - ble_gap_addr_t addr; - ble_gap_addr_t * p_addr = &addr; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_address_set_req_dec(p_rx_buf, rx_buf_len, &addr_cycle_mode, &p_addr); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_address_set(addr_cycle_mode, p_addr); - - err_code = ble_gap_address_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_addr_t addr; - ble_gap_addr_t * p_addr = &addr; - - ble_gap_addr_t * pp_addr_tab[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t * pp_irk_tab[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - - ble_gap_whitelist_t whitelist; - whitelist.addr_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; - whitelist.pp_addrs = pp_addr_tab; - whitelist.irk_count = BLE_GAP_WHITELIST_IRK_MAX_COUNT; - whitelist.pp_irks = pp_irk_tab; - - ble_gap_scan_params_t scan_params; - scan_params.p_whitelist = &whitelist; - ble_gap_scan_params_t * p_scan_params = &scan_params; - - ble_gap_conn_params_t conn_params; - ble_gap_conn_params_t * p_conn_params = &conn_params; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_connect_req_dec(p_rx_buf, rx_buf_len, &p_addr, &p_scan_params, &p_conn_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_connect(p_addr, p_scan_params, p_conn_params); - - err_code = ble_gap_connect_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_connect_cancel(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - sd_err_code = sd_ble_gap_connect_cancel(); - - err_code = ble_gap_connect_cancel_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_addr_t * pp_addr_tab[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t * pp_irk_tab[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - - ble_gap_whitelist_t whitelist; - whitelist.addr_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; - whitelist.pp_addrs = pp_addr_tab; - whitelist.irk_count = BLE_GAP_WHITELIST_IRK_MAX_COUNT; - whitelist.pp_irks = pp_irk_tab; - - ble_gap_scan_params_t scan_params; - scan_params.p_whitelist = &whitelist; - ble_gap_scan_params_t * p_scan_params = &scan_params; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_scan_start_req_dec(p_rx_buf, rx_buf_len, &p_scan_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_scan_start(p_scan_params); - - err_code = ble_gap_scan_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_address_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_addr_t addr; - ble_gap_addr_t * p_addr = &addr; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_address_get_req_dec(p_rx_buf, rx_buf_len, &p_addr); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_address_get(p_addr); - - err_code = ble_gap_address_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_addr); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_adv_data_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t data[BLE_GAP_ADV_MAX_SIZE]; - uint8_t * p_data = data; - uint8_t dlen = sizeof (data); - - uint8_t sr_data[BLE_GAP_ADV_MAX_SIZE]; - uint8_t * p_sr_data = sr_data; - uint8_t srdlen = sizeof (sr_data); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_adv_data_set_req_dec(p_rx_buf, - rx_buf_len, - &p_data, - &dlen, - &p_sr_data, - &srdlen); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_adv_data_set(p_data, dlen, p_sr_data, srdlen); - - err_code = ble_gap_adv_data_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - ble_gap_addr_t * p_addresses[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_addr_t addresses[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t * p_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - ble_gap_irk_t irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - ble_gap_addr_t peer_addr; - ble_gap_whitelist_t whitelist; - ble_gap_adv_params_t adv_params; - ble_gap_adv_params_t * p_adv_params; - - uint32_t i = 0; - - for (i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++) - { - p_addresses[i] = &(addresses[i]); - } - - for (i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++) - { - p_irks[i] = &(irks[i]); - } - - whitelist.pp_addrs = &p_addresses[0]; - whitelist.pp_irks = &p_irks[0]; - - adv_params.p_peer_addr = &peer_addr; - adv_params.p_whitelist = &whitelist; - - p_adv_params = &adv_params; - - err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_adv_start(p_adv_params); - - err_code = ble_gap_adv_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_adv_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - sd_err_code = sd_ble_gap_adv_stop(); - - err_code = ble_gap_adv_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_conn_param_update(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - ble_gap_conn_params_t conn_params; - ble_gap_conn_params_t * p_conn_params = &conn_params; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_conn_param_update_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_conn_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_conn_param_update(conn_handle, p_conn_params); - - err_code = ble_gap_conn_param_update_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_disconnect(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint8_t hci_status_code; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_disconnect_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &hci_status_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_disconnect(conn_handle, hci_status_code); - - err_code = ble_gap_disconnect_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_tx_power_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - int8_t tx_power; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_tx_power_set_req_dec(p_rx_buf, rx_buf_len, &tx_power); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_tx_power_set(tx_power); - - err_code = ble_gap_tx_power_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_appearance_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t appearance; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_appearance_set_req_dec(p_rx_buf, rx_buf_len, &appearance); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_appearance_set(appearance); - - err_code = ble_gap_appearance_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_appearance_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t appearance; - uint16_t * p_appearance = &appearance; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_appearance_get_req_dec(p_rx_buf, rx_buf_len, &p_appearance); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_appearance_get(p_appearance); - - err_code = ble_gap_appearance_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_appearance); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - - -uint32_t conn_mw_ble_gap_ppcp_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_conn_params_t conn_params; - ble_gap_conn_params_t * p_conn_params = &conn_params; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_ppcp_set_req_dec(p_rx_buf, rx_buf_len, &p_conn_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_ppcp_set(p_conn_params); - - err_code = ble_gap_ppcp_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_ppcp_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_conn_params_t conn_params; - ble_gap_conn_params_t * p_conn_params = &conn_params; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_ppcp_get_req_dec(p_rx_buf, rx_buf_len, &p_conn_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_ppcp_get(p_conn_params); - - err_code = ble_gap_ppcp_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_conn_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - - -uint32_t conn_mw_ble_gap_device_name_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint8_t dev_name[BLE_GAP_DEVNAME_MAX_LEN]; - uint8_t * p_dev_name = dev_name; - - uint16_t len; - uint16_t * p_len = &len; - - err_code = ble_gap_device_name_get_req_dec(p_rx_buf, rx_buf_len, &p_dev_name, &p_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_device_name_get(p_dev_name, p_len); - - err_code = ble_gap_device_name_get_rsp_enc(sd_err_code, p_dev_name, len, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_device_name_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - ble_gap_conn_sec_mode_t write_perm; - ble_gap_conn_sec_mode_t * p_write_perm = &write_perm; - - uint8_t dev_name[BLE_GAP_DEVNAME_MAX_LEN]; - uint8_t * p_dev_name = dev_name; - - uint16_t len = BLE_GAP_DEVNAME_MAX_LEN; - - err_code = ble_gap_device_name_set_req_dec(p_rx_buf, - rx_buf_len, - &p_write_perm, - &p_dev_name, - &len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_device_name_set(p_write_perm, p_dev_name, len); - - err_code = ble_gap_device_name_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_authenticate(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - - ble_gap_sec_params_t sec_params; - ble_gap_sec_params_t * p_sec_params = &sec_params; - - err_code = ble_gap_authenticate_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sec_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params); - - err_code = ble_gap_authenticate_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - uint32_t sec_tab_index = 0; - - uint16_t * p_conn_handle; - uint8_t sec_status; - - ble_gap_sec_params_t sec_params; - ble_gap_sec_params_t * p_sec_params = &sec_params; - - // Allocate global security context for soft device - err_code = conn_ble_gap_sec_context_create(&sec_tab_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_conn_handle = &(m_conn_keys_table[sec_tab_index].conn_handle); - - // Set up global structure for command decoder - ble_gap_sec_keyset_t * p_sec_keyset = &(m_conn_keys_table[sec_tab_index].keyset); - - p_sec_keyset->keys_periph.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_periph); - p_sec_keyset->keys_periph.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_periph); - p_sec_keyset->keys_periph.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_periph); - p_sec_keyset->keys_central.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_central); - p_sec_keyset->keys_central.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_central); - p_sec_keyset->keys_central.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_central); - - err_code = ble_gap_sec_params_reply_req_dec(p_rx_buf, - rx_buf_len, - p_conn_handle, - &sec_status, - &p_sec_params, - &p_sec_keyset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_sec_params_reply(*p_conn_handle, sec_status, p_sec_params, p_sec_keyset); - - err_code = ble_gap_sec_params_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sec_keyset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_auth_key_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - uint8_t key_type; - - uint8_t key[BLE_GAP_SEC_KEY_LEN]; - uint8_t * p_key = key; - - err_code = ble_gap_auth_key_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &key_type, &p_key); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_auth_key_reply(conn_handle, key_type, p_key); - - err_code = ble_gap_auth_key_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_sec_info_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - - ble_gap_enc_info_t enc_info; - ble_gap_enc_info_t * p_enc_info = &enc_info; - - ble_gap_irk_t id_info; - ble_gap_irk_t * p_id_info = &id_info; - - ble_gap_sign_info_t sign_info; - ble_gap_sign_info_t * p_sign_info = &sign_info; - - err_code = ble_gap_sec_info_reply_req_dec(p_rx_buf, - rx_buf_len, - &conn_handle, - &p_enc_info, - &p_id_info, - &p_sign_info); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_sec_info_reply(conn_handle, p_enc_info, p_id_info, p_sign_info); - - err_code = ble_gap_sec_info_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_conn_sec_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - - ble_gap_conn_sec_t conn_sec; - ble_gap_conn_sec_t * p_conn_sec = &conn_sec; - - err_code = ble_gap_conn_sec_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_conn_sec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_conn_sec_get(conn_handle, p_conn_sec); - - err_code = ble_gap_conn_sec_get_rsp_enc(sd_err_code, p_conn_sec, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_rssi_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - uint8_t threshold_dbm; - uint8_t skip_count; - - err_code = ble_gap_rssi_start_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &threshold_dbm, &skip_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_rssi_start(conn_handle, threshold_dbm, skip_count); - - err_code = ble_gap_rssi_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_rssi_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - - err_code = ble_gap_rssi_stop_req_dec(p_rx_buf, rx_buf_len, &conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_rssi_stop(conn_handle); - - err_code = ble_gap_rssi_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_scan_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - sd_err_code = sd_ble_gap_scan_stop(); - - err_code = ble_gap_scan_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_encrypt(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - - ble_gap_master_id_t master_id; - ble_gap_master_id_t *p_master_id = &master_id; - - ble_gap_enc_info_t enc_info; - ble_gap_enc_info_t *p_enc_info = &enc_info; - - err_code = ble_gap_encrypt_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_master_id, &p_enc_info); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_encrypt(conn_handle, p_master_id, p_enc_info); - - err_code = ble_gap_encrypt_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gap_rssi_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - int8_t rssi; - int8_t * p_rssi = &rssi; - - err_code = ble_gap_rssi_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_rssi); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_rssi_get(conn_handle, p_rssi); - - err_code = ble_gap_rssi_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, rssi); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gatts.c b/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gatts.c deleted file mode 100644 index 018c5ce..0000000 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gatts.c +++ /dev/null @@ -1,407 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include "conn_mw_ble_gatts.h" -#include "ble_serialization.h" - -uint32_t conn_mw_ble_gatts_service_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t type; - ble_uuid_t uuid = {0}; - ble_uuid_t * p_uuid = &uuid; - uint16_t handle; - uint16_t * p_handle = &handle; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_service_add_req_dec(p_rx_buf, rx_buf_len, &type, &p_uuid, &p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_service_add(type, p_uuid, p_handle); - - err_code = ble_gatts_service_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_characteristic_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t service_handle; - - //Preparing char_md - ble_gatts_char_md_t char_md; - - uint8_t char_user_desc[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_gatts_char_pf_t char_pf; - ble_gatts_attr_md_t user_desc_md; - ble_gatts_attr_md_t cccd_md; - ble_gatts_attr_md_t sccd_md; - - char_md.char_user_desc_size = sizeof (char_user_desc); - char_md.p_char_user_desc = char_user_desc; - char_md.p_char_pf = &char_pf; - char_md.p_user_desc_md = &user_desc_md; - char_md.p_cccd_md = &cccd_md; - char_md.p_sccd_md = &sccd_md; - - ble_gatts_char_md_t * p_char_md = &char_md; - - //Preparing attr_char_value - ble_gatts_attr_t attr_char_value; - ble_uuid_t uuid; - ble_gatts_attr_md_t attr_md; - uint8_t value[BLE_GATTS_VAR_ATTR_LEN_MAX]; - - attr_char_value.p_uuid = &uuid; - attr_char_value.p_attr_md = &attr_md; - attr_char_value.init_len = sizeof (value); - attr_char_value.p_value = value; - - ble_gatts_attr_t * p_attr_char_value = &attr_char_value; - - //Preparing handles - ble_gatts_char_handles_t handles; - ble_gatts_char_handles_t * p_handles = &handles; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_characteristic_add_req_dec(p_rx_buf, rx_buf_len, &service_handle, - &p_char_md, &p_attr_char_value, &p_handles); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_characteristic_add(service_handle, p_char_md, - p_attr_char_value, p_handles); - - err_code = ble_gatts_characteristic_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, - p_handles); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; - -} - -uint32_t conn_mw_ble_gatts_include_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t service_handle; - uint16_t inc_srvc_handle; - uint16_t handle; - uint16_t * p_handle = &handle; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_include_add_req_dec(p_rx_buf, rx_buf_len, &service_handle, - &inc_srvc_handle, &p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_include_add(service_handle, inc_srvc_handle, p_handle); - - err_code = ble_gatts_include_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_descriptor_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t char_handle; - uint8_t attr_value[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_uuid_t char_uuid; - ble_gatts_attr_md_t metadata; - ble_gatts_attr_t attr; - ble_gatts_attr_t * p_attr = &attr; - - attr.p_uuid = &char_uuid; - attr.p_attr_md = &metadata; - attr.p_value = attr_value; - attr.init_len = sizeof (attr_value); - - uint16_t handle; - uint16_t * p_handle = &handle; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_descriptor_add_req_dec(p_rx_buf, rx_buf_len, &char_handle, &p_attr, - &p_handle); - - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_descriptor_add(char_handle, p_attr, p_handle); - - err_code = ble_gatts_descriptor_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_value_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t handle; - uint8_t attr_val_table[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_gatts_value_t attr_val = - { - .len = sizeof (attr_val_table), - .offset = 0, - .p_value = attr_val_table - }; - ble_gatts_value_t * p_attr_val = &attr_val; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_value_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_val); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_value_set(conn_handle, handle, p_attr_val); - - err_code = ble_gatts_value_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_val); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_value_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t handle; - uint8_t val[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_gatts_value_t attr_value; - ble_gatts_value_t * p_attr_value = &attr_value; - - attr_value.p_value = val; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_value_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_value); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_value_get(conn_handle, handle, p_attr_value); - - err_code = ble_gatts_value_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_value); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_hvx(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint8_t data[BLE_GATTS_VAR_ATTR_LEN_MAX]; - uint8_t * p_data = data; - uint16_t len = sizeof data; - uint16_t * p_len = &len; - - ble_gatts_hvx_params_t hvx_params; - ble_gatts_hvx_params_t * p_hvx_params = &hvx_params; - - hvx_params.p_len = p_len; - hvx_params.p_data = p_data; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_hvx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_hvx_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - sd_err_code = sd_ble_gatts_hvx(conn_handle, p_hvx_params); - - p_len = (p_hvx_params) ? p_hvx_params->p_len : NULL; - err_code = ble_gatts_hvx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_service_changed(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t start_handle; - uint16_t end_handle; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_service_changed_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &start_handle, - &end_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_service_changed(conn_handle, start_handle, end_handle); - - err_code = ble_gatts_service_changed_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_rw_authorize_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - - uint8_t data[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_gatts_rw_authorize_reply_params_t auth_params; - ble_gatts_rw_authorize_reply_params_t * p_auth_params = &auth_params; - - auth_params.params.read.p_data = data; - auth_params.params.read.len = sizeof (data); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_rw_authorize_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, - &p_auth_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_rw_authorize_reply(conn_handle, p_auth_params); - - err_code = ble_gatts_rw_authorize_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_sys_attr_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - - uint8_t sys_attr[BLE_GATTS_VAR_ATTR_LEN_MAX]; - - uint8_t * p_sys_attr = sys_attr; - uint16_t sys_attr_len = sizeof (sys_attr); - - uint32_t flags; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_sys_attr_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sys_attr, - &sys_attr_len, &flags); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_sys_attr_set(conn_handle, p_sys_attr, sys_attr_len, flags); - - err_code = ble_gatts_sys_attr_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - - uint8_t sys_attr[BLE_GATTS_VAR_ATTR_LEN_MAX]; - - uint8_t * p_sys_attr = sys_attr; - uint16_t sys_attr_len = sizeof (sys_attr); - uint16_t * p_sys_attr_len = &sys_attr_len; - - uint32_t flags; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_sys_attr_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sys_attr, - &p_sys_attr_len, &flags); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_sys_attr_get(conn_handle, p_sys_attr, p_sys_attr_len, flags); - - err_code = ble_gatts_sys_attr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sys_attr, - p_sys_attr_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gatts.h b/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gatts.h deleted file mode 100644 index d61865a..0000000 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gatts.h +++ /dev/null @@ -1,216 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_BLE_GATTS_H -#define _CONN_MW_BLE_GATTS_H - -#include - -/**@brief Handles @ref sd_ble_gatts_service_add command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_service_add (uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gatts_characteristic_add command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_characteristic_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_include_add command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_include_add (uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_descriptor_add command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_descriptor_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_value_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_value_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_value_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_value_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_hvx command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_hvx(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_service_changed command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_service_changed(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_rw_authorize_reply command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_rw_authorize_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_sys_attr_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_sys_attr_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_sys_attr_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); -#endif //_CONN_MW_BLE_GATTS_H - diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_nrf_soc.c b/components/serialization/connectivity/codecs/s120/middleware/conn_mw_nrf_soc.c deleted file mode 100644 index c9a7509..0000000 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_nrf_soc.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "nrf_soc_conn.h" -#include "conn_mw_nrf_soc.h" -#include "ble_serialization.h" - -uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - - err_code = power_system_off_req_dec(p_rx_buf, rx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = sd_power_system_off(); - /* There should be no return from sd_power_system_off() */ - - return err_code; -} - -uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - int32_t temperature; - int32_t * p_temperature = &temperature; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = temp_get_req_dec(p_rx_buf, rx_buf_len, &p_temperature); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_temp_get(p_temperature); - - err_code = temp_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_temperature); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_nrf_soc.h b/components/serialization/connectivity/codecs/s120/middleware/conn_mw_nrf_soc.h deleted file mode 100644 index ba4a973..0000000 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_nrf_soc.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 CONN_MW_NRF_SOC_H__ -#define CONN_MW_NRF_SOC_H__ - -#include - -/**@brief Handles @ref sd_power_system_off command request. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. - */ -uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_temp_get command request and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. - */ -uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -#endif diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_conn.h b/components/serialization/connectivity/codecs/s120/serializers/ble_conn.h deleted file mode 100644 index 9259445..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_conn.h +++ /dev/null @@ -1,447 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_CONN_H__ -#define BLE_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_conn Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief Connectivity command request decoders and command response encoders. - */ -#include "ble.h" - -/**@brief Decodes @ref sd_ble_tx_buffer_count_get command request. - * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format, - * @ref ble_tx_buffer_count_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_count Pointer to pointer to location for count. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_tx_buffer_count_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint8_t * * const pp_count); - -/**@brief Encodes @ref sd_ble_tx_buffer_count_get command response. - * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format. - * @ref ble_tx_buffer_count_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_count Pointer to count value. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_tx_buffer_count_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_count); - -/**@brief Event encoding dispatcher. - * - * The event encoding dispatcher will route the event packet to the correct encoder which in turn - * encodes the contents of the event and updates the \p p_buf buffer. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - * @retval NRF_ERROR_NOT_SUPPORTED Event encoder is not implemented. - */ -uint32_t ble_event_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_version_get command request. - * - * @sa @ref nrf51_version_get_encoding for packet format, - * @ref ble_version_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_version Pointer to pointer to @ref ble_version_t address. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_version_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_version_t * * const pp_version); - -/**@brief Encodes @ref sd_ble_version_get command response. - * - * @sa @ref nrf51_version_get_encoding for packet format. - * @ref ble_version_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_version Pointer to @ref ble_version_t address. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_version_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_version_t const * const p_version); - - -/**@brief Decodes @ref sd_ble_opt_get command request. - * - * @sa @ref nrf51_opt_get_encoding for packet format, - * @ref ble_opt_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_opt_id Pointer to pointer to @ref ble_version_t address. - * @param[out] pp_opt Pointer to pointer to @ref ble_opt_t address. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t **const pp_opt ); - - -/**@brief Encodes @ref sd_ble_opt_get command response. - * - * @sa @ref nrf51_opt_get_encoding for packet format. - * @ref ble_opt_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] opt_id identifies type of ble_opt_t union - * @param[in] p_opt Pointer to @ref ble_opt_t union. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_opt_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint32_t opt_id, - ble_opt_t const * const p_opt); - - -/**@brief Decodes @ref sd_ble_opt_set command request. - * - * @sa @ref nrf51_opt_set_encoding for packet format, - * @ref ble_opt_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_opt_id Pointer to @ref ble_opt_t union type identifier. - * @param[out] pp_opt Pointer to pointer to @ref ble_opt_t union. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t **const pp_opt ); - - -/**@brief Encodes @ref sd_ble_opt_set command response. - * - * @sa @ref nrf51_opt_set_encoding for packet format. - * @ref ble_opt_set_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_opt_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - - -/**@brief Decodes @ref sd_ble_uuid_encode command request. - * - * @sa @ref nrf51_uuid_encode_encoding for packet format, - * @ref ble_uuid_encode_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_uuid Pointer to pointer to @ref ble_uuid_t structure. - * @param[out] pp_uuid_le_len Pointer to pointer to the length of encoded UUID. - * @param[out] pp_uuid_le Pointer to pointer to buffer where encoded UUID will be stored. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_uuid_t * * const pp_uuid, - uint8_t * * const pp_uuid_le_len, - uint8_t * * const pp_uuid_le); - -/**@brief Encodes @ref sd_ble_uuid_encode command response. - * - * @sa @ref nrf51_uuid_encode_encoding for packet format. - * @ref ble_uuid_encode_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] uuid_le_len Length of the encoded UUID. - * @param[in] p_uuid_le Pointer to the buffer with encoded UUID. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t uuid_le_len, - uint8_t const * const p_uuid_le); - -/**@brief Decodes @ref sd_ble_uuid_decode command request. - * - * @sa @ref nrf51_uuid_decode_encoding for packet format, - * @ref ble_uuid_decode_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] p_uuid_le_len Pointer to the length of encoded UUID. - * @param[out] pp_uuid_le Pointer to pointer to buffer where encoded UUID will be stored. - * @param[out] pp_uuid Pointer to pointer to @ref ble_uuid_t structure. - * \c It will be set to NULL if p_uuid is not present in the packet. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, - uint8_t * p_uuid_le_len, - uint8_t * * const pp_uuid_le, - ble_uuid_t * * const pp_uuid); - -/**@brief Encodes @ref sd_ble_uuid_decode command response. - * - * @sa @ref nrf51_uuid_decode_encoding for packet format. - * @ref ble_uuid_decode_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_uuid Pointer to the buffer with encoded UUID. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_uuid_t const * const p_uuid); - -/**@brief Decodes @ref sd_ble_uuid_vs_add command request. - * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format, - * @ref ble_uuid_vs_add_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] pp_uuid Pointer to pointer to UUID. - * \c It will be set to NULL if p_uuid is not present in the packet. - * @param[out] pp_uuid_type Pointer to pointer to UUID type. - * \c It will be set to NULL if p_uuid_type is not present in the packet. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf, - uint16_t buf_len, - ble_uuid128_t * * const pp_uuid, - uint8_t * * const pp_uuid_type); - -/**@brief Encodes @ref sd_ble_uuid_vs_add command response. - * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format. - * @ref ble_uuid_vs_add_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_uuid_type Pointer to the UUID type. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_uuid_type); - -/**@brief Decodes @ref sd_ble_enable command request. - * - * @sa @ref nrf51_enable_encoding for packet format, - * @ref ble_enable_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_ble_enable_params Pointer to pointer to ble_enable_params_t. - * \c It will be set to NULL if p_ble_enable_params is not present in the packet. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_enable_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_enable_params_t * * const pp_ble_enable_params); - -/**@brief Encodes @ref sd_ble_enable command response. - * - * @sa @ref nrf51_enable_encoding for packet format. - * @ref ble_enable_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_enable_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Pre-decodes opt_id of @ref ble_opt_t for middleware. - * - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] packet_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in,out] p_opt_id Pointer to opt_id which identifies type of @ref ble_opt_t union. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id); - -/**@brief Decodes @ref sd_ble_user_mem_reply command request. - * - * @sa @ref nrf51_user_mem_reply_encoding for packet format, - * @ref ble_user_mem_reply_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] p_conn_handle Pointer to Connection Handle. - * @param[in,out] pp_block Pointer to pointer to ble_user_mem_block_t. - * \c It will be set to NULL if p_block is not present in the packet. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_user_mem_block_t * * const pp_block); - -/**@brief Encodes @ref sd_ble_user_mem_reply command response. - * - * @sa @ref nrf51_user_mem_reply_encoding for packet format. - * @ref ble_user_mem_reply_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ - -#endif diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_enable.c b/components/serialization/connectivity/codecs/s120/serializers/ble_enable.c deleted file mode 100644 index da81437..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_enable.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_enable_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_enable_params_t * * const pp_ble_enable_params) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_ble_enable_params); - SER_ASSERT_NOT_NULL(*pp_ble_enable_params); - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_ble_enable_params, ble_enable_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_enable_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - return op_status_enc(SD_BLE_ENABLE, return_code, p_buf, p_buf_len, &index); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_evt_conn.h b/components/serialization/connectivity/codecs/s120/serializers/ble_evt_conn.h deleted file mode 100644 index 2c8059a..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_evt_conn.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_EVT_CONN_H__ -#define BLE_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_evt_conn Connectivity event encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes ble_evt_tx_complete event. - * - * @sa @ref nrf51_evt_tx_complete_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_evt_user_mem_release event. - * - * @sa @ref nrf51_evt_user_mem_release_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_evt_user_mem_request event. - * - * @sa @ref nrf51_evt_user_mem_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_evt_tx_complete.c b/components/serialization/connectivity/codecs/s120/serializers/ble_evt_tx_complete.c deleted file mode 100644 index f10dbf9..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_evt_tx_complete.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_EVT_TX_COMPLETE, &(p_buf[index])); - index += uint16_encode(p_event->evt.common_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.common_evt.params.tx_complete.count; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_evt_user_mem_release.c b/components/serialization/connectivity/codecs/s120/serializers/ble_evt_user_mem_release.c deleted file mode 100644 index 5f4f3df..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_evt_user_mem_release.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "conn_ble_user_mem.h" - -uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - const uint16_t evt_header = BLE_EVT_USER_MEM_RELEASE; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.common_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.common_evt.params.user_mem_release.type), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&(p_event->evt.common_evt.params.user_mem_release.mem_block.len), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_buf[index++] = p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - // Now user memory context can be released - err_code = conn_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_evt_user_mem_request.c b/components/serialization/connectivity/codecs/s120/serializers/ble_evt_user_mem_request.c deleted file mode 100644 index 8faa98b..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_evt_user_mem_request.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - const uint16_t evt_header = BLE_EVT_USER_MEM_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.common_evt.params.user_mem_request.type), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_address_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_address_get.c deleted file mode 100644 index f0dc9a5..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_address_get.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_address_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_addr_t * * const pp_address) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_address); - SER_ASSERT_LENGTH_LEQ(1 + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_ADDRESS_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_address = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_address_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_addr_t const * const p_address) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADDRESS_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - *p_buf_len = index; - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_address); - - SER_ASSERT_LENGTH_LEQ(index + sizeof (ble_gap_addr_t), total_len); - p_buf[index++] = p_address->addr_type; - memcpy(&p_buf[index], &p_address->addr[0], BLE_GAP_ADDR_LEN); - index += BLE_GAP_ADDR_LEN; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_address_set.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_address_set.c deleted file mode 100644 index 8727a01..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_address_set.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_address_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * p_addr_cycle_mode, - ble_gap_addr_t * * const pp_addr) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_addr_cycle_mode); - SER_ASSERT_NOT_NULL(pp_addr); - SER_ASSERT_NOT_NULL(*pp_addr); - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_addr_cycle_mode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_addr, ble_gap_addr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gap_address_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - return op_status_enc(SD_BLE_GAP_ADDRESS_SET, return_code, p_buf, p_buf_len, &index); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_data_set.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_data_set.c deleted file mode 100644 index ab83ce0..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_data_set.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * const pp_data, - uint8_t * p_dlen, - uint8_t * * const pp_sr_data, - uint8_t * p_srdlen) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_dlen); - SER_ASSERT_NOT_NULL(p_srdlen); - - uint32_t index = SER_CMD_DATA_POS; - - uint32_t error_code = len8data_dec(p_buf, packet_len, &index, pp_data, p_dlen); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - error_code = len8data_dec(p_buf, packet_len, &index, pp_sr_data, p_srdlen); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADV_DATA_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_start.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_start.c deleted file mode 100644 index ad5b071..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_start.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_adv_params_t * * const pp_adv_params) -{ - uint32_t index = 0, i = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_adv_params); - SER_ASSERT_NOT_NULL(*pp_adv_params); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_peer_addr); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_addrs); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_irks); - - for (i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++) - { - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_addrs[i]); - } - - for (i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++) - { - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_irks[i]); - } - - /* Packet with variable length. */ - /* For now check: opcode + indicator showing if ble_gap_adv_params_t struct is present. */ - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GAP_ADV_START, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - err_code = uint8_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->type)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **) &((*pp_adv_params)->p_peer_addr), ble_gap_addr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->fp)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **) &((*pp_adv_params)->p_whitelist), ble_gap_whitelist_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->interval)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->timeout)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_adv_ch_mask_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->channel_mask)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - *pp_adv_params = NULL; - } - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADV_START, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_stop.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_stop.c deleted file mode 100644 index b3569a2..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_adv_stop.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADV_STOP, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_appearance_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_appearance_get.c deleted file mode 100644 index cc828b5..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_appearance_get.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * * const pp_appearance) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_appearance); - SER_ASSERT_NOT_NULL(*pp_appearance); - SER_ASSERT_LENGTH_EQ(2, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_APPEARANCE_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_appearance = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_appearance) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_APPEARANCE_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_appearance); - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + sizeof (uint16_t), total_len); - index += uint16_encode(*p_appearance, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_appearance_set.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_appearance_set.c deleted file mode 100644 index f393fdb..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_appearance_set.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * const p_appearance) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_appearance); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_LENGTH_EQ(3, buf_len); - SER_ASSERT(p_buf[index++] == SD_BLE_GAP_APPEARANCE_SET, NRF_ERROR_INVALID_PARAM); - - uint32_t err_code = uint16_t_dec(p_buf, buf_len, &index, p_appearance); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_APPEARANCE_SET, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_auth_key_reply.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_auth_key_reply.c deleted file mode 100644 index 988c711..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_auth_key_reply.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - uint8_t * p_key_type, - uint8_t * * const pp_key) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_key_type); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - uint8_t key_len; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - SER_ASSERT_LENGTH_LEQ(1, packet_len - index); - uint8_dec(p_buf, packet_len, &index, p_key_type); - - switch (*p_key_type) - { - case BLE_GAP_AUTH_KEY_TYPE_NONE: - key_len = 0; - break; - - case BLE_GAP_AUTH_KEY_TYPE_PASSKEY: - key_len = 6; - break; - - case BLE_GAP_AUTH_KEY_TYPE_OOB: - key_len = 16; - break; - - default: - return NRF_ERROR_INVALID_PARAM; - } - - err_code = buf_dec(p_buf, packet_len, &index, pp_key, key_len, key_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return err_code; -} - -uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_AUTH_KEY_REPLY, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_authenticate.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_authenticate.c deleted file mode 100644 index 4d7053e..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_authenticate.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "nordic_common.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - - -uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_gap_sec_params_t * * const pp_sec_params) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_sec_params); - SER_ASSERT_NOT_NULL(*pp_sec_params); - - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_sec_params, - ble_gap_sec_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_AUTHENTICATE, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn.h b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn.h deleted file mode 100644 index 9f6e520..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn.h +++ /dev/null @@ -1,1043 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GAP_CONN_H__ -#define BLE_GAP_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gap_conn GAP Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief GAP Connectivity command request decoders and command response encoders - */ -#include "ble_gap.h" - -/**@brief Decodes @ref sd_ble_gap_address_get command request. - * - * @sa @ref nrf51_address_get_encoding for packet format, - * @ref ble_gap_address_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_address Pointer to pointer to address. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_address_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_addr_t * * const pp_address); - -/**@brief Encodes @ref sd_ble_gap_address_get command response. - * - * @sa @ref nrf51_address_get_encoding for packet format. - * @ref ble_gap_address_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_address Pointer to @ref ble_gap_addr_t address - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_addr_t const * const p_address); - -/**@brief Decodes @ref sd_ble_gap_authenticate command request. - * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format, - * @ref ble_gap_authenticate_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle - * @param[out] pp_sec_params Pointer to pointer to security parameters. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_gap_sec_params_t * * const pp_sec_params); - -/**@brief Encodes @ref sd_ble_gap_authenticate command response. - * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format. - * @ref ble_gap_authenticate_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @brief Decodes @ref sd_ble_gap_address_set command request. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format, - * @ref ble_gap_address_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[in] p_addr_cycle_mode Pointer to address cycle mode. - * @param[out] pp_addr Pointer to pointer to the address structure. - - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * p_addr_cycle_mode, - ble_gap_addr_t * * const pp_addr); - -/**@brief Encodes @ref sd_ble_gap_address_set command response. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format. - * @ref ble_gap_address_set_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_adv_data_set command request. - * - * @sa @ref nrf51_adv_set_encoding for packet format, - * @ref ble_gap_adv_data_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] pp_data Pointer to the buffer raw data to be placed in advertisement packet. - * @param[out] p_dlen Pointer to data length for p_data. - * @param[out] pp_sr_data Pointer to the buffer raw data to be placed in scan response packet. - * @param[out] p_srdlen Pointer to data length for p_sr_data. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * const pp_data, - uint8_t * p_dlen, - uint8_t * * const pp_sr_data, - uint8_t * p_srdlen); - -/**@brief Encodes @ref sd_ble_gap_adv_data_set command response. - * - * @sa @ref nrf51_adv_set_encoding for packet format. - * @ref ble_gap_adv_data_set_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_adv_start command request. - * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_gap_adv_start_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_adv_params Pointer to pointer to advertising parameters. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_adv_params_t * * const pp_adv_params); - -/**@brief Encodes @ref sd_ble_gap_adv_start command response. - * - * @sa @ref nrf51_adv_start_encoding for packet format. - * @ref ble_gap_adv_start_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_device_name_get command request. - * - * @sa @ref nrf51_device_name_get_encoding for packet format, - * @ref ble_gap_device_name_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_dev_name Pointer to pointer to device name buffer. - * @param[out] pp_dev_name_len Pointer to pointer to device name length location. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * pp_dev_name, - uint16_t * * pp_dev_name_len); - -/**@brief Encodes @ref sd_ble_gap_device_name_get command response. - * - * @sa @ref nrf51_device_name_get_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_dev_name Pointer to device name buffer. - * @param[in] dev_name_len Length of device name buffer. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buflen \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code, - uint8_t const * const p_dev_name, - uint16_t dev_name_len, - uint8_t * const p_buf, - uint32_t * const p_buflen); - -/**@brief Decodes @ref sd_ble_gap_conn_param_update command request. - * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format, - * @ref ble_gap_conn_param_update_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_conn_params Pointer to pointer to connection parameters. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection - * parameters field present. - */ -uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - ble_gap_conn_params_t * * const pp_conn_params); - -/**@brief Encodes @ref sd_ble_gap_conn_param_update command response. - * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - - -/**@brief Decodes @ref sd_ble_gap_disconnect command request. - * - * @sa @ref nrf51_disconnect_encoding for packet format, - * @ref ble_gap_disconnect_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] p_conn_handle Pointer to Connection Handle. - * @param[in] p_hci_status Pointer to HCI Status Code. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * const p_hci_status); - -/**@brief Encodes @ref sd_ble_gap_disconnect command response. - * - * @sa @ref nrf51_disconnect_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_tx_power_set command request. - * - * @sa @ref nrf51_tx_power_set_encoding for packet format, - * @ref ble_gap_tx_power_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] tx_power Pointer to TX power value. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - int8_t * tx_power); - -/**@brief Encodes @ref sd_ble_gap_tx_power_set command response. - * - * @sa @ref nrf51_tx_power_set_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_ppcp_set command request. - * - * @sa @ref nrf51_ppcp_set_encoding for packet format, - * @ref ble_gap_ppcp_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_conn_params Pointer to pointer to connection parameters to be set. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection - * parameters field present. - */ -uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_params_t * * const pp_conn_params); - -/**@brief Encodes @ref sd_ble_gap_ppcp_set command response. - * - * @sa @ref nrf51_ppcp_set_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - - -/**@brief Decodes @ref sd_ble_gap_ppcp_get command request. - * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format, - * @ref ble_gap_ppcp_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_conn_params Pointer to pointer to ble_gap_conn_params_t. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_conn_params_t * * const pp_conn_params); - -/**@brief Encodes @ref sd_ble_gap_ppcp_get command response. - * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format. - * @ref ble_gap_ppcp_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_conn_params Pointer to ble_gap_conn_params_t. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_conn_params_t const * const p_conn_params); - -/**@brief Encodes @ref sd_ble_gap_adv_stop command response. - * - * @sa @ref nrf51_sd_ble_gap_adv_stop for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_auth_key_reply command request. - * - * @sa @ref nrf51_auth_key_reply_encoding for packet format, - * @ref ble_gap_auth_key_reply_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_key_type Pointer to key type. - * @param[out] pp_key Pointer to pointer to buffer for incoming key. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - uint8_t * p_key_type, - uint8_t * * const pp_key); - -/**@brief Encodes @ref sd_ble_gap_auth_key_reply command response. - * - * @sa @ref nrf51_auth_key_reply_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_sec_params_reply command request. - * - * @sa @ref nrf51_sec_params_reply_encoding for packet format, - * @ref ble_gap_sec_params_reply_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_sec_status Pointer to security status. - * @param[out] pp_sec_params Pointer to pointer to security parameters structure. - * @param[out] pp_sec_keyset Pointer to pointer to security keyset structure. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection - * parameters field present. - */ -uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - uint8_t * p_sec_status, - ble_gap_sec_params_t * * const pp_sec_params, - ble_gap_sec_keyset_t * * const pp_sec_keyset); - -/**@brief Encodes @ref sd_ble_gap_sec_params_reply command response. - * - * @sa @ref nrf51_sec_params_reply_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in] p_sec_keyset Pointer to security keyset structure. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_sec_keyset_t * const p_sec_keyset); - -/**@brief Decodes @ref sd_ble_gap_rssi_start command request. - * - * @sa @ref nrf51_rssi_start_encoding for packet format, - * @ref ble_gap_rssi_start_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_threshold_dbm Pointer to threshold in dBm. - * @param[out] p_skip_count Pointer to sample skip count. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_conn_handle, - uint8_t * p_threshold_dbm, - uint8_t * p_skip_count); - -/**@brief Encodes @ref sd_ble_gap_rssi_start command response. - * - * @sa @ref nrf51_rssi_start_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_rssi_stop command request. - * - * @sa @ref nrf51_rssi_stop_encoding for packet format, - * @ref ble_gap_rssi_stop_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] conn_handle Pointer to connection handle. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ - -uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * conn_handle); - -/**@brief Encodes @ref sd_ble_gap_rssi_stop command response. - * - * @sa @ref nrf51_rssi_stop_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_appearance_get command request. - * - * @sa @ref nrf51_appearance_get_encoding for packet format, - * @ref ble_gap_appearance_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_appearance Pointer to pointer to uint16_t appearance. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * * const pp_appearance); - -/**@brief Encodes @ref sd_ble_gap_appearance_get command response. - * - * @sa @ref nrf51_appearance_get_encoding for packet format. - * @ref ble_gap_appearance_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_appearance Pointer to uint16_t appearance. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_appearance); - - -/**@brief Decodes @ref sd_ble_gap_appearance_set command request. - * - * @sa @ref nrf51_appearance_set_encoding for packet format, - * @ref ble_gap_tx_power_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of the packet. - * @param[out] p_appearance Pointer to the appearance. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * const p_appearance); - -/**@brief Encodes @ref sd_ble_gap_appearance_set command response. - * - * @sa @ref nrf51_appearance_set_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - - -/**@brief Decodes @ref sd_ble_gap_sec_info_reply command request. - * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format, - * @ref ble_gap_sec_info_reply_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of the packet. - * @param[out] p_conn_handle Pointer to the Connection Handle. - * @param[out] pp_enc_info Pointer to pointer to Encryption Information. - * @param[out] pp_id_info Pointer to pointer to Id Information. - * @param[out] pp_sign_info Pointer to pointer to Signing Information - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - ble_gap_enc_info_t * * const pp_enc_info, - ble_gap_irk_t * * const pp_id_info, - ble_gap_sign_info_t * * const pp_sign_info); - -/**@brief Encodes @ref sd_ble_gap_sec_info_reply command response. - * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_device_name_set command request. - * - * @sa @ref nrf51_device_name_set_encoding for packet format, - * @ref ble_gap_device_name_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of the packet. - * @param[out] pp_write_perm Pointer to pointer to write permissions filed. - * @param[out] pp_dev_name Pointer to pointer to device name string - * @param[out] p_dev_name_len Pointer to device name string length - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_sec_mode_t * * const pp_write_perm, - uint8_t * * const pp_dev_name, - uint16_t * const p_dev_name_len); - - -/**@brief Encodes @ref sd_ble_gap_device_name_set command response. - * - * @sa @ref nrf51_device_name_set_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_conn_sec_get command request. - * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format, - * @ref ble_gap_conn_sec_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to Connection Handle. - * @param[out] pp_conn_sec Pointer to pointer to @ref ble_gap_conn_sec_t to be filled by - * the softdevice. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - ble_gap_conn_sec_t * * const pp_conn_sec); - -/**@brief Encodes @ref sd_ble_gap_conn_sec_get command response. - * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format. - * @ref ble_gap_conn_sec_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_conn_sec Pointer to @ref ble_gap_conn_sec_t to be encoded. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code, - ble_gap_conn_sec_t * const p_conn_sec, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Encodes @ref sd_ble_gap_scan_stop command response. - * - * @sa @ref nrf51_scan_stop_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_connect command request. - * - * @sa @ref nrf51_connect_encoding for packet format, - * @ref ble_gap_connect_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_addr Pointer to pointer to peer address @ref ble_gap_addr_t. - * @param[out] pp_scan_params Pointer to pointer to @ref ble_gap_scan_params_t. - * @param[out] pp_conn_params Pointer to pointer to @ref ble_gap_conn_params_t. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * * const pp_addr, - ble_gap_scan_params_t * * const pp_scan_params, - ble_gap_conn_params_t * * const pp_conn_params); - -/**@brief Encodes @ref sd_ble_gap_connect command response. - * - * @sa @ref nrf51_connect_encoding for packet format. - * @ref ble_gap_connect_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_connect_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_scan_start command request. - * - * @sa @ref nrf51_scan_start_encoding for packet format, - * @ref ble_gap_scan_start_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_scan_params Pointer to pointer to @ref ble_gap_scan_params_t. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_scan_params_t * * const pp_scan_params); - -/**@brief Encodes @ref sd_ble_gap_scan_start command response. - * - * @sa @ref nrf51_scan_start_encoding for packet format. - * @ref ble_gap_scan_start_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Encodes @ref sd_ble_gap_connect_cancel command response. - * - * @sa @ref nrf51_connect_cancel_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_encrypt command request. - * - * @sa @ref nrf51_gap_encrypt_encoding for packet format, - * @ref ble_gap_encrypt_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer connection_handle. - * @param[out] pp_master_id Pointer to pointer to @ref ble_gap_master_id_t. - * @param[out] pp_enc_info Pointer to pointer to @ref ble_gap_enc_info_t. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ - -uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gap_master_id_t ** const pp_master_id, - ble_gap_enc_info_t ** const pp_enc_info); - -/**@brief Encodes @ref sd_ble_gap_encrypt command response. - * - * @sa @ref nrf51_gap_encrypt_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gap_rssi_get command request. - * - * @sa @ref nrf51_rssi_get_encoding for packet format, - * @ref ble_gap_rssi_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[in] p_conn_handle Connection handle. - * @param[out] pp_rssi Pointer to pointer to rssi value. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - int8_t * * const pp_rssi); - -/**@brief Encodes @ref sd_ble_gap_rssi_get command response. - * - * @sa @ref nrf51_rssi_get_encoding for packet format. - * @ref ble_gap_rssi_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] rssi RSSI value. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int8_t rssi); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn_param_update.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn_param_update.c deleted file mode 100644 index 38ac3fd..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn_param_update.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_conn_params); - SER_ASSERT_NOT_NULL(*pp_conn_params); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 3, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_CONN_PARAM_UPDATE, NRF_ERROR_INVALID_PARAM); - - index++; - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - if (p_buf[index] == SER_FIELD_PRESENT) - { - index++; - SER_ASSERT_LENGTH_LEQ(index + 8, packet_len); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->min_conn_interval)); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->max_conn_interval)); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->slave_latency)); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->conn_sup_timeout)); - } - else if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - index++; - *pp_conn_params = NULL; - } - else - { - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONN_PARAM_UPDATE, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn_sec_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn_sec_get.c deleted file mode 100644 index d3631ee..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_conn_sec_get.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - - -uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - ble_gap_conn_sec_t * * const pp_conn_sec) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - - uint32_t index = 0; - uint8_t opcode; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, packet_len - index); - uint8_dec(p_buf, packet_len, &index, &opcode); - - SER_ASSERT(opcode == SD_BLE_GAP_CONN_SEC_GET, NRF_ERROR_INVALID_PARAM); - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_conn_sec, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code, - ble_gap_conn_sec_t * const p_conn_sec, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t buflen = *p_buf_len; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONN_SEC_GET, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = cond_field_enc(p_conn_sec, p_buf, buflen, &index, ble_gap_conn_sec_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_connect.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_connect.c deleted file mode 100644 index e7b6135..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_connect.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * * const pp_addr, - ble_gap_scan_params_t * * const pp_scan_params, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_addr); - SER_ASSERT_NOT_NULL(*pp_addr); - SER_ASSERT_NOT_NULL(pp_scan_params); - SER_ASSERT_NOT_NULL(*pp_scan_params); - SER_ASSERT_NOT_NULL(pp_conn_params); - SER_ASSERT_NOT_NULL(*pp_conn_params); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_addr, ble_gap_addr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_scan_params, ble_gap_scan_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_conn_params, ble_gap_conn_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_connect_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONNECT, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_connect_cancel.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_connect_cancel.c deleted file mode 100644 index 4551fcd..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_connect_cancel.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONNECT_CANCEL, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_device_name_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_device_name_get.c deleted file mode 100644 index e169d02..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_device_name_get.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - -uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * * pp_name, - uint16_t * * pp_name_len) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(pp_name_len); - SER_ASSERT_NOT_NULL(*pp_name_len); - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - - index++; - - if (p_buf[index] != SER_FIELD_PRESENT && p_buf[index] != SER_FIELD_NOT_PRESENT) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - err_code = uint16_t_dec(p_buf, buf_len, &index, *pp_name_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - *pp_name_len = NULL; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - - if (p_buf[index] != SER_FIELD_PRESENT && p_buf[index] != SER_FIELD_NOT_PRESENT) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - *pp_name = NULL; - } - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code, - uint8_t const * const p_dev_name, - uint16_t dev_name_len, - uint8_t * const p_buf, - uint32_t * const p_buflen) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buflen); - - uint32_t buflen = *p_buflen; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_DEVICE_NAME_GET, return_code, - p_buf, p_buflen); - uint32_t index = *p_buflen; - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = len16data_enc(p_dev_name, dev_name_len, p_buf, buflen, &index); - - *p_buflen = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_device_name_set.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_device_name_set.c deleted file mode 100644 index 84c49ff..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_device_name_set.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_sec_mode_t * * const pp_write_perm, - uint8_t * * const pp_dev_name, - uint16_t * const p_dev_name_len) -{ - SER_ASSERT_NOT_NULL(p_buf); //check if *p_buf is allocated - SER_ASSERT_NOT_NULL(pp_write_perm); //check if *pp_write_perm exist - SER_ASSERT_NOT_NULL(pp_dev_name); //check if *pp_dev_name exist - SER_ASSERT_NOT_NULL(p_dev_name_len); //check if *p_dev_name_len exist - - uint32_t index = SER_CMD_DATA_POS; - uint32_t status_code; - - SER_ASSERT_LENGTH_LEQ(4, packet_len - index); //make sure that payload is at least 4 bytes - - //decode optional write permissions field - status_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_write_perm, - ble_gap_conn_sec_mode_dec); - SER_ASSERT(status_code == NRF_SUCCESS, status_code); - - //decode optional device name field - status_code = len16data_dec(p_buf, packet_len, &index, pp_dev_name, p_dev_name_len); - SER_ASSERT(status_code == NRF_SUCCESS, status_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return status_code; -} - - -uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_DEVICE_NAME_SET, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_disconnect.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_disconnect.c deleted file mode 100644 index e69a0d0..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_disconnect.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * const p_hci_status) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_hci_status); - - uint8_t opcode; - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_dec(p_buf, packet_len, &index, &opcode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT(opcode == SD_BLE_GAP_DISCONNECT, NRF_ERROR_INVALID_PARAM); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_hci_status); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_DISCONNECT, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_encrypt.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_encrypt.c deleted file mode 100644 index 3cf0262..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_encrypt.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gap_master_id_t ** const pp_master_id, - ble_gap_enc_info_t ** const pp_enc_info) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_enc_info); - SER_ASSERT_NOT_NULL(pp_master_id); - SER_ASSERT_NOT_NULL(*pp_enc_info); - SER_ASSERT_NOT_NULL(*pp_master_id); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void **)pp_master_id, - ble_gap_master_id_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void **)pp_enc_info, - ble_gap_enc_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ENCRYPT, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_adv_report.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_adv_report.c deleted file mode 100644 index fa6cd3f..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_adv_report.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - const uint16_t evt_header = BLE_GAP_EVT_ADV_REPORT; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc((void *)&(p_event->evt.gap_evt.params.adv_report.peer_addr), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.gap_evt.params.adv_report.rssi), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - byte = (p_event->evt.gap_evt.params.adv_report.scan_rsp) | - ((p_event->evt.gap_evt.params.adv_report.type) << 0x01) | - ((p_event->evt.gap_evt.params.adv_report.dlen) << 0x03); - - err_code = uint8_t_enc((void *)&(byte), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_vector_enc(p_event->evt.gap_evt.params.adv_report.data, (uint16_t)p_event->evt.gap_evt.params.adv_report.dlen, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_auth_key_request.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_auth_key_request.c deleted file mode 100644 index 7805879..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_auth_key_request.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GAP_EVT_AUTH_KEY_REQUEST; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_event->evt.gap_evt.params.auth_key_request.key_type, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_auth_status.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_auth_status.c deleted file mode 100644 index 59a751a..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_auth_status.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gap_evt_conn.h" -#include "conn_ble_gap_sec_keys.h" - -extern ser_ble_gap_conn_keyset_t m_conn_keys_table[]; - -uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint16_t evt_header = BLE_GAP_EVT_AUTH_STATUS; - uint32_t total_len; - uint32_t err_code = NRF_SUCCESS; - uint32_t conn_index; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - total_len = *p_buf_len; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_auth_status_t_enc(&(p_event->evt.gap_evt.params.auth_status), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - // keyset is an extension of standard event data - used to synchronize keys at application - err_code = conn_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keyset_t_enc(&(m_conn_keys_table[conn_index].keyset), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = conn_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - return err_code; -} - diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn.h b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn.h deleted file mode 100644 index 8fbe6e0..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn.h +++ /dev/null @@ -1,336 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GAP_EVT_CONN_H__ -#define BLE_GAP_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gap_evt_conn GAP Connectivity event encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief GAP Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes ble_gap_evt_auth_key_request event. - * - * @sa @ref nrf51_evt_auth_key_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_auth_status event. - * - * @sa @ref nrf51_evt_auth_status_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_conn_param_update event. - * - * @sa @ref nrf51_evt_conn_param_update_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_conn_sec_update event. - * - * @sa @ref nrf51_evt_conn_sec_update_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_connected event. - * - * @sa @ref nrf51_evt_connected_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_disconnected event. - * - * @sa @ref nrf51_evt_disconnected_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_passkey_display event. - * - * @sa @ref nrf51_evt_passkey_display for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_rssi_changed event. - * - * @sa @ref nrf51_evt_rssi_changed_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_sec_info_request event. - * - * @sa @ref nrf51_evt_sec_info_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_sec_params_request event. - * - * @sa @ref nrf51_evt_sec_param_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_timeout event. - * - * @sa @ref nrf51_evt_timeout_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_sec_request event. - * - * @sa @ref nrf51_evt_sec_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_conn_param_update_request event. - * - * @sa @ref nrf51_evt_conn_param_update_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_adv_report event. - * - * @sa @ref nrf51_evt_adv_report_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gap_evt_scan_req_report event. - * - * @sa @ref nrf51_evt_scan_req_report_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_param_update.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_param_update.c deleted file mode 100644 index a9565dc..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_param_update.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT(p_event->header.evt_id == BLE_GAP_EVT_CONN_PARAM_UPDATE, NRF_ERROR_INVALID_PARAM); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_conn_param_update_t_enc(&p_event->evt.gap_evt.params.conn_param_update, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_param_update_request.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_param_update_request.c deleted file mode 100644 index 5843ff3..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_param_update_request.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT(p_event->header.evt_id == BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, NRF_ERROR_INVALID_PARAM); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_conn_param_update_request_t_enc(&p_event->evt.gap_evt.params.conn_param_update_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_sec_update.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_sec_update.c deleted file mode 100644 index 8293866..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_conn_sec_update.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_CONN_SEC_UPDATE; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_conn_sec_update_t_enc( - (void *)&p_event->evt.gap_evt.params.conn_sec_update, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_connected.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_connected.c deleted file mode 100644 index 16cea4f..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_connected.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GAP_EVT_CONNECTED; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_connected_t_enc((void *)&p_event->evt.gap_evt.params.connected, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_disconnected.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_disconnected.c deleted file mode 100644 index a067462..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_disconnected.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gap_evt_conn.h" - -uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code; - uint16_t evt_header = BLE_GAP_EVT_DISCONNECTED; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&(p_event->evt.gap_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_disconnected_t_enc((void *)&(p_event->evt.gap_evt.params.disconnected), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_passkey_display.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_passkey_display.c deleted file mode 100644 index 1fcaab5..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_passkey_display.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble.h" -#include "ble_gap_evt_conn.h" - -#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey) - - -uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + PASSKEY_LEN, *p_buf_len); - index += uint16_encode(BLE_GAP_EVT_PASSKEY_DISPLAY, &(p_buf[index])); - index += uint16_encode(p_event->evt.gap_evt.conn_handle, &(p_buf[index])); - - memcpy(&p_buf[index], p_event->evt.gap_evt.params.passkey_display.passkey, PASSKEY_LEN); - index += PASSKEY_LEN; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_rssi_changed.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_rssi_changed.c deleted file mode 100644 index 6ee6a94..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_rssi_changed.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GAP_EVT_RSSI_CHANGED, &(p_buf[index])); - index += uint16_encode(p_event->evt.gap_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gap_evt.params.rssi_changed.rssi; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_scan_req_report.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_scan_req_report.c deleted file mode 100644 index 9707495..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_scan_req_report.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" - - -uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_SCAN_REQ_REPORT; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc((void *)&(p_event->evt.gap_evt.params.scan_req_report.peer_addr), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.gap_evt.params.scan_req_report.rssi), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_info_request.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_info_request.c deleted file mode 100644 index e3b7949..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_info_request.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_SEC_INFO_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_info_request_t_enc( - (void *)&p_event->evt.gap_evt.params.sec_info_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_params_request.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_params_request.c deleted file mode 100644 index f2fdf59..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_params_request.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_SEC_PARAMS_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_params_request_t_enc( - (void *)&p_event->evt.gap_evt.params.sec_params_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_request.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_request.c deleted file mode 100644 index 6a744b0..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_sec_request.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GAP_EVT_SEC_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_request_t_enc((void *)&p_event->evt.gap_evt.params.sec_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_timeout.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_timeout.c deleted file mode 100644 index 7894cdc..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_evt_timeout.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE + 3, *p_buf_len); - index += uint16_encode(BLE_GAP_EVT_TIMEOUT, &(p_buf[index])); - index += uint16_encode(p_event->evt.gap_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gap_evt.params.timeout.src; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_ppcp_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_ppcp_get.c deleted file mode 100644 index 38663fc..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_ppcp_get.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_conn_params); - SER_ASSERT_NOT_NULL(*pp_conn_params); - SER_ASSERT_LENGTH_LEQ(2, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_PPCP_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_conn_params = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_conn_params_t const * const p_conn_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_PPCP_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_conn_params); - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 8, total_len); - - index += uint16_encode(p_conn_params->min_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->max_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->slave_latency, &p_buf[index]); - index += uint16_encode(p_conn_params->conn_sup_timeout, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_ppcp_set.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_ppcp_set.c deleted file mode 100644 index e09aaf2..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_ppcp_set.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "nordic_common.h" -#include "app_util.h" - - -uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_conn_params); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GAP_PPCP_SET, NRF_ERROR_INVALID_PARAM); - - index++; - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_conn_params = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 8, packet_len); - SER_ASSERT_NOT_NULL(*pp_conn_params); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->min_conn_interval); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->max_conn_interval); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->slave_latency); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->conn_sup_timeout); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_PPCP_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_get.c deleted file mode 100644 index 306caa2..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_get.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - int8_t * * const pp_rssi) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_rssi); - SER_ASSERT_NOT_NULL(*pp_rssi); - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **) pp_rssi, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int8_t rssi) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_RSSI_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - uint32_t index = *p_buf_len; - - err_code = uint8_t_enc((uint8_t *) &rssi, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_start.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_start.c deleted file mode 100644 index cd6f516..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_start.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_conn_handle, - uint8_t * p_threshold_dbm, - uint8_t * p_skip_count) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_threshold_dbm); - SER_ASSERT_NOT_NULL(p_skip_count); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, &index, p_threshold_dbm); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, &index, p_skip_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_RSSI_START, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_stop.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_stop.c deleted file mode 100644 index d068f3d..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_rssi_stop.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_conn_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_RSSI_STOP, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_scan_start.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_scan_start.c deleted file mode 100644 index b561d3c..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_scan_start.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_scan_params_t * * const pp_scan_params) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_scan_params); - SER_ASSERT_NOT_NULL(*pp_scan_params); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_scan_params, ble_gap_scan_params_t_dec); - - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SCAN_START, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_scan_stop.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_scan_stop.c deleted file mode 100644 index a390f17..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_scan_stop.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SCAN_STOP, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_sec_info_reply.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_sec_info_reply.c deleted file mode 100644 index 3e85479..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_sec_info_reply.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - ble_gap_enc_info_t * * const pp_enc_info, - ble_gap_irk_t * * const pp_id_info, - ble_gap_sign_info_t * * const pp_sign_info) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_enc_info); - SER_ASSERT_NOT_NULL(pp_id_info); - SER_ASSERT_NOT_NULL(pp_sign_info); - SER_ASSERT_NOT_NULL(*pp_enc_info); - SER_ASSERT_NOT_NULL(*pp_id_info); - SER_ASSERT_NOT_NULL(*pp_sign_info); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_enc_info, - ble_gap_enc_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_id_info, - ble_gap_irk_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_sign_info, - ble_gap_sign_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return err_code; -} - -uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SEC_INFO_REPLY, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_sec_params_reply.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_sec_params_reply.c deleted file mode 100644 index 0c295be..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_sec_params_reply.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - uint8_t * p_sec_status, - ble_gap_sec_params_t * * const pp_sec_params, - ble_gap_sec_keyset_t * * const pp_sec_keyset) -{ - uint32_t index = SER_CMD_HEADER_SIZE; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_sec_status); - SER_ASSERT_NOT_NULL(pp_sec_params); - SER_ASSERT_NOT_NULL(*pp_sec_params); - SER_ASSERT_NOT_NULL(pp_sec_keyset); - SER_ASSERT_NOT_NULL(*pp_sec_keyset); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_sec_status); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *) pp_sec_params, ble_gap_sec_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *) pp_sec_keyset, ble_gap_sec_keyset_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -//opcode: 0x7F -uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_sec_keyset_t * const p_sec_keyset) -{ - uint32_t index = 0; - uint32_t buf_len = * p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SEC_PARAMS_REPLY, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_sec_keyset); - index = *p_buf_len; - - err_code = cond_field_enc(p_sec_keyset, p_buf, buf_len, &index, ble_gap_sec_keyset_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_tx_power_set.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gap_tx_power_set.c deleted file mode 100644 index 6af4f31..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gap_tx_power_set.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - int8_t * p_tx_power) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_tx_power); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_tx_power); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_TX_POWER_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_char_value_by_uuid_read.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_char_value_by_uuid_read.c deleted file mode 100644 index 6fbc19d..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_char_value_by_uuid_read.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "cond_field_serialization.h" -#include "ble_types.h" -#include - -uint32_t ble_gattc_char_value_by_uuid_read_req_dec( - uint8_t const * const p_buf, - uint16_t buf_len, - uint16_t * const p_conn_handle, - ble_uuid_t * * const pp_uuid, - ble_gattc_handle_range_t * * const - pp_handle_range) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2, buf_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, NRF_ERROR_INVALID_DATA); - index++; - - uint16_dec(p_buf, buf_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_handle_range, - ble_gattc_handle_range_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, return_code, - p_buf, p_buf_len); -} - diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_char_values_read.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_char_values_read.c deleted file mode 100644 index 39c6808..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_char_values_read.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * * const pp_handles, - uint16_t * const p_handle_count) -{ - SER_ASSERT_NOT_NULL(p_buf); //check if *p_buf is allocated - SER_ASSERT_NOT_NULL(p_conn_handle); //check if *p_conn_handle exist - SER_ASSERT_NOT_NULL(pp_handles); //check if *p_handles exist - SER_ASSERT_NOT_NULL(*pp_handles); //check if p_handles exist - SER_ASSERT_NOT_NULL(p_handle_count); //check if *p_handle_count exist - - uint32_t index = SER_CMD_DATA_POS; - uint32_t status_code; - - SER_ASSERT_LENGTH_LEQ(5, packet_len - index); //make sure that payload length is at least 5 bytes - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - //decode handle table count with optional handle table - status_code = count16_cond_data16_dec(p_buf, packet_len, &index, pp_handles, p_handle_count); - SER_ASSERT(status_code == NRF_SUCCESS, status_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return status_code; -} - - -uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - return op_status_enc(SD_BLE_GATTC_CHAR_VALUES_READ, return_code, p_buf, p_buf_len, &index); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_characteristics_discover.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_characteristics_discover.c deleted file mode 100644 index e17edb2..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_characteristics_discover.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_characteristics_discover_req_dec( - uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_handle_range = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->start_handle); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->end_handle); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_conn.h b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_conn.h deleted file mode 100644 index 1a3794f..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_conn.h +++ /dev/null @@ -1,398 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_CONN_H__ -#define BLE_GATTC_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gatc_conn GATTC Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief GATTC Connectivity command request decoders and command response encoders - */ -#include "ble_gattc.h" -#include "ble.h" - -/**@brief Decodes @ref sd_ble_gattc_characteristics_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format, - * @ref ble_gattc_characteristics_discover_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_handle_range Pointer to pointer to handle range. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present. - */ -uint32_t ble_gattc_characteristics_discover_req_dec - (uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range); - -/**@brief Encodes @ref sd_ble_gattc_characteristics_discover command response. - * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format. - * @ref ble_gattc_characteristics_discover_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_descriptors_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format, - * @ref ble_gattc_descriptors_discover_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_handle_range Pointer to pointer to handle range. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present. - */ -uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range); - -/**@brief Encodes @ref sd_ble_gattc_descriptors_discover command response. - * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format. - * @ref ble_gattc_descriptors_discover_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_relationships_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format, - * @ref ble_gattc_relationships_discover_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_handle_range Pointer to pointer to handle range. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present. - */ -uint32_t ble_gattc_relationships_discover_req_dec - (uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range); - -/**@brief Encodes @ref sd_ble_gattc_relationships_discover command response. - * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format. - * @ref ble_gattc_relationships_discover_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_primary_services_discover command request. - * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_start_handle Pointer to start handle. - * @param[out] pp_srvc_uuid Pointer to pointer to service uuid. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for uuid field present. - */ -uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_start_handle, - ble_uuid_t * * const pp_srvc_uuid); - -/**@brief Encodes @ref sd_ble_gattc_primary_services_discover command response. - * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format. - * @ref ble_gattc_primary_services_discover_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format, - * @ref ble_gattc_read_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_handle Pointer to handle. - * @param[out] p_offset Pointer to offset. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle, - uint16_t * const p_offset); - -/**@brief Encodes @ref sd_ble_gattc_read command response. - * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format. - * @ref ble_gattc_read_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_char_values_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format, - * @ref ble_gattc_char_values_read_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_handles Pointer to pointer to handle table. - * @param[out] p_handle_count Pointer to handle handle table count. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ - -uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * * const pp_handles, - uint16_t * const p_handle_count); - -/**@brief Encodes @ref sd_ble_gattc_char_values_read command response. - * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format. - * @ref ble_gattc_char_values_read_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_write command request. - * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format, - * @ref ble_gattc_write_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_write_params Pointer to pointer to write parameters. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_write_params_t * * const pp_write_params); - -/**@brief Encodes @ref sd_ble_gattc_write command response. - * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format. - * @ref ble_gattc_write_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_write_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_hv_confirm command request. - * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format, - * @ref ble_gattc_hv_confirm_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command response packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_handle Pointer to handle of the attribute in the indication. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle); - -/**@brief Encodes @ref sd_ble_gattc_hv_confirm command response. - * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format. - * @ref ble_gattc_hv_confirm_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gattc_char_value_by_uuid_read command request. - * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format, - * @ref ble_gattc_char_value_by_uuid_read_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of request packet. - * @param[out] p_conn_handle Pointer to connection handle of the connection. - * @param[out] pp_uuid Pointer to pointer to a characteristic value UUID to read. - * @param[out] pp_handle_range Pointer to pointer to the range of handles to perform this - * procedure on. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid operation type. - */ -uint32_t ble_gattc_char_value_by_uuid_read_req_dec - (uint8_t const * const p_buf, - uint16_t buf_len, - uint16_t * const p_conn_handle, - ble_uuid_t * * const pp_uuid, - ble_gattc_handle_range_t * * const pp_handle_range); - -/**@brief Encodes @ref sd_ble_gattc_char_value_by_uuid_read command response. - * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format. - * @ref ble_gattc_char_value_by_uuid_read_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif - diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_descriptors_discover.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_descriptors_discover.c deleted file mode 100644 index f78e675..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_descriptors_discover.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_handle_range = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->start_handle); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->end_handle); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_disc_rsp.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_disc_rsp.c deleted file mode 100644 index 5799434..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_disc_rsp.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 8, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_CHAR_DISC_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.count, &(p_buf[index])); - - uint16_t service_count = p_event->evt.gattc_evt.params.char_disc_rsp.count; - - SER_ASSERT_LENGTH_LEQ(index + (service_count * 9), *p_buf_len); - - for (uint16_t i = 0; i < service_count; i++) - { - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.uuid, - &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.type; - p_buf[index++] = (0x00 | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.broadcast << 0) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.read << 1) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.write_wo_resp << 2) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.write << 3) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.notify << 4) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.indicate << 5) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.auth_signed_wr << 6)); - p_buf[index++] = (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_ext_props & 0x01); - - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_decl, - &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_value, - &(p_buf[index])); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c deleted file mode 100644 index 4326380..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_util.h" -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_gattc_evt_conn.h" - - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gattc_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gattc_evt.gatt_status, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gattc_evt.error_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc( - &p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_vals_read_rsp.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_vals_read_rsp.c deleted file mode 100644 index fa7fc41..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_char_vals_read_rsp.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint16_t evt_header = BLE_GATTC_EVT_CHAR_VALS_READ_RSP; - - //Event Header - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - //GATTC Header - err_code = uint16_t_enc(&(p_event->evt.gattc_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gattc_evt.gatt_status), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gattc_evt.error_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - //Event structure for BLE_GATTC_EVT_CHAR_VALS_READ_RSP - err_code = - ble_gattc_evt_char_vals_read_rsp_t_enc(&(p_event->evt.gattc_evt.params.char_vals_read_rsp), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_conn.h b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_conn.h deleted file mode 100644 index 12805cd..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_conn.h +++ /dev/null @@ -1,236 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTC_EVT_CONN_H__ -#define BLE_GATTC_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gattc_evt_conn GATTC Connectivity event encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief GATTC Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes ble_gattc_evt_char_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_disc_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_char_val_by_uuid_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_val_by_uuid_read_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_char_vals_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_char_vals_read_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_desc_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_desc_disc_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_hvx event. - * - * @sa @ref nrf51_gattc_evt_hvx_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_prim_srvc_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_prim_srvc_disc_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_read_rsp event. - * - * @sa @ref nrf51_gattc_evt_read_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_rel_disc_rsp event. - * - * @sa @ref nrf51_gattc_evt_rel_disc_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_timeout event. - * - * @sa @ref nrf51_gattc_evt_timeout_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes ble_gattc_evt_write_rsp event. - * - * @sa @ref nrf51_gattc_evt_write_rsp_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_desc_disc_rsp.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_desc_disc_rsp.c deleted file mode 100644 index 378e77b..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_desc_disc_rsp.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 8, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_DESC_DISC_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.count, &(p_buf[index])); - - uint16_t service_count = p_event->evt.gattc_evt.params.desc_disc_rsp.count; - - SER_ASSERT_LENGTH_LEQ(index + (service_count * 5), *p_buf_len); - - for (uint16_t i = 0; i < service_count; i++) - { - index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].handle, - &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.uuid, - &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.type; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_hvx.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_hvx.c deleted file mode 100644 index 8e3a49e..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_hvx.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 11, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_HVX, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.hvx.handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.hvx.type; - index += uint16_encode(p_event->evt.gattc_evt.params.hvx.len, &(p_buf[index])); - - SER_ASSERT_LENGTH_LEQ(index + p_event->evt.gattc_evt.params.hvx.len, *p_buf_len); - - if (p_event->evt.gattc_evt.params.hvx.len > 0) - { - memcpy(&(p_buf[index]), - &(p_event->evt.gattc_evt.params.hvx.data[0]), - p_event->evt.gattc_evt.params.hvx.len); - index += p_event->evt.gattc_evt.params.hvx.len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c deleted file mode 100644 index f70c538..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 8, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.count, &(p_buf[index])); - - uint16_t service_count = p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.count; - - SER_ASSERT_LENGTH_LEQ(index + (service_count * 7), *p_buf_len); - - for (uint16_t i = 0; i < service_count; i++) - { - index += uint16_encode( - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.uuid, - &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.type; - index += - uint16_encode( - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - start_handle, - &(p_buf[index])); - index += - uint16_encode( - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - end_handle, - &(p_buf[index])); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_read_rsp.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_read_rsp.c deleted file mode 100644 index 2d2b0f5..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_read_rsp.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 12, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_READ_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.read_rsp.handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.read_rsp.offset, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.read_rsp.len, &(p_buf[index])); - - SER_ASSERT_LENGTH_LEQ(index + p_event->evt.gattc_evt.params.read_rsp.len, *p_buf_len); - - if (p_event->evt.gattc_evt.params.read_rsp.len > 0) - { - memcpy(&(p_buf[index]), - &(p_event->evt.gattc_evt.params.read_rsp.data[0]), - p_event->evt.gattc_evt.params.read_rsp.len); - index += p_event->evt.gattc_evt.params.read_rsp.len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_rel_disc_rsp.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_rel_disc_rsp.c deleted file mode 100644 index fd83b62..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_rel_disc_rsp.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t error_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GATTC_EVT_REL_DISC_RSP; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - error_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&p_event->evt.gattc_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&p_event->evt.gattc_evt.gatt_status, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&p_event->evt.gattc_evt.error_handle, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_evt_rel_disc_rsp_t_enc(&p_event->evt.gattc_evt.params.rel_disc_rsp, - p_buf, - total_len, - &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - *p_buf_len = index; - - return error_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_timeout.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_timeout.c deleted file mode 100644 index ee1e08d..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_timeout.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_TIMEOUT, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.timeout.src; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_write_rsp.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_write_rsp.c deleted file mode 100644 index 7692b94..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_evt_write_rsp.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 13, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_WRITE_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.write_rsp.write_op; - index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.offset, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.len, &(p_buf[index])); - - SER_ASSERT_LENGTH_LEQ(index + p_event->evt.gattc_evt.params.write_rsp.len, *p_buf_len); - - if (p_event->evt.gattc_evt.params.write_rsp.len > 0) - { - memcpy(&(p_buf[index]), - &(p_event->evt.gattc_evt.params.write_rsp.data[0]), - p_event->evt.gattc_evt.params.write_rsp.len); - index += p_event->evt.gattc_evt.params.write_rsp.len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_hv_confirm.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_hv_confirm.c deleted file mode 100644 index 6a1be3f..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_hv_confirm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_HV_CONFIRM, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_primary_services_discover.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_primary_services_discover.c deleted file mode 100644 index 678e5e8..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_primary_services_discover.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_start_handle, - ble_uuid_t * * const pp_srvc_uuid) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_start_handle); - SER_ASSERT_NOT_NULL(pp_srvc_uuid); - SER_ASSERT_NOT_NULL(*pp_srvc_uuid); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - uint16_dec(p_buf, packet_len, &index, p_start_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_srvc_uuid = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 1, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_srvc_uuid)->uuid); - uint8_dec(p_buf, packet_len, &index, &(*pp_srvc_uuid)->type); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_read.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_read.c deleted file mode 100644 index ca0af98..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_read.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle, - uint16_t * const p_offset) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - SER_ASSERT_NOT_NULL(p_offset); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gattc_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_READ, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_relationships_discover.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_relationships_discover.c deleted file mode 100644 index 7a61a3a..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_relationships_discover.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_relationships_discover_req_dec( - uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const - pp_handle_range) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_handle_range = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->start_handle); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->end_handle); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_write.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_write.c deleted file mode 100644 index e889bce..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gattc_write.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" -#include - - -uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_write_params_t * * const pp_write_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_write_params); - SER_ASSERT_NOT_NULL(*pp_write_params); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - uint8_t op_code; - err_code = uint8_t_dec(p_buf, packet_len, &index, &op_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT(op_code == SD_BLE_GATTC_WRITE, NRF_ERROR_INVALID_PARAM); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_write_params, - ble_gattc_write_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gattc_write_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_WRITE, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_characteristic_add.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_characteristic_add.c deleted file mode 100644 index 1e1a9de..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_characteristic_add.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * service_handle, - ble_gatts_char_md_t * * const pp_char_md, - ble_gatts_attr_t * * const pp_attr_char_value, - ble_gatts_char_handles_t * * const pp_handles) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(service_handle); - SER_ASSERT_NOT_NULL(pp_char_md); - SER_ASSERT_NOT_NULL(pp_attr_char_value); - SER_ASSERT_NOT_NULL(pp_handles); - SER_ASSERT_NOT_NULL(*pp_char_md); - SER_ASSERT_NOT_NULL(*pp_attr_char_value); - SER_ASSERT_NOT_NULL(*pp_handles); - - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len); - uint32_t err_code; - SER_ASSERT_LENGTH_LEQ(2, buf_len - index); - uint16_dec(p_buf, buf_len, &index, service_handle); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_char_md, ble_gatts_char_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - &index, - (void * *)pp_attr_char_value, - ble_gatts_attr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_handles, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(index == buf_len, NRF_ERROR_INVALID_LENGTH); - - return err_code; -} - -uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gatts_char_handles_t const * const p_handles) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - SER_ASSERT_LENGTH_LEQ(1 + 4, total_len); - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_CHARACTERISTIC_ADD, - return_code, - p_buf, - p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code == NRF_SUCCESS) /* Add value and it's length. */ - { - err_code = cond_field_enc((void *)p_handles, - p_buf, - total_len, - p_buf_len, - ble_gatts_char_handles_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_conn.h b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_conn.h deleted file mode 100644 index d2144a1..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_conn.h +++ /dev/null @@ -1,514 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_CONN_H__ -#define BLE_GATTS_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gatts_conn GATTS Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief GATTS Connectivity command request decoders and command response encoders - */ - -#include "ble_gatts.h" -#include "ble.h" - -/**@brief Decodes @ref sd_ble_gatts_value_get command request. - * - * @sa @ref nrf51_gatts_value_get_encoding for packet format, - * @ref ble_gatts_value_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] p_conn_handle Pointer to the connection_handle. - * @param[out] p_handle Pointer to the attribute_handle. - * @param[out] pp_value Pointer to pointer to the Attribute Value structure. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle, - ble_gatts_value_t * * const pp_value); - -/**@brief Encodes @ref sd_ble_gatts_value_get command response. - * - * @sa @ref nrf51_gatts_value_get_sec_response for packet format. - * @ref ble_gatts_value_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_value Pointer to Attribute Value structure. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gatts_value_t * const p_value); - -/**@brief Decodes @ref sd_ble_gatts_characteristic_add command request. - * - * @sa @ref nrf51_characteristics_add_encoding for packet format, - * @ref ble_gatts_characteristic_add_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of request packet. - * @param[out] p_service_handle Pointer to the service_handle. - * @param[out] constpp_char_md Pointer to pointer to the location where Characteristic metadata - * will be decoded. - * @param[out] pp_attr_char_value Pointer to pointer to the location where GATT Attribute will be - * decoded. - * @param[out] pp_handles Pointer to pointer to the location where Characteristic definition - * handles will be decoded. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_service_handle, - ble_gatts_char_md_t * * constpp_char_md, - ble_gatts_attr_t * * const pp_attr_char_value, - ble_gatts_char_handles_t * * const pp_handles); - -/**@brief Encodes @ref ble_gatts_sys_attr_get_rsp_enc command response. - * - * @sa @ref sd_ble_gatts_sys_attr_get for packet format. - * @ref ble_gatts_sys_attr_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_handles Pointer to handle struct to be encoded. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gatts_char_handles_t const * const p_handles); - -/**@brief Decodes @ref sd_ble_gatts_include_add command request. - * - * @sa @ref nrf51_gatts_include_add_encoding for packet format, - * @ref ble_gatts_include_add_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] p_service_handle Pointer to the service_handle. - * @param[out] p_inc_srvc_handle Pointer to the handle of the included service. - * @param[out] pp_include_handle Pointer to Pointer to 16-bit word where the assigned handle will be stored. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ - -uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_service_handle, - uint16_t * const p_inc_srvc_handle, - uint16_t * * const pp_include_handle); - -/**@brief Encodes @ref ble_gatts_include_add_rsp_enc command response. - * - * @sa @ref nrf51_gatts_include_add_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_include_handle Pointer to a 16-bit word where the assigned handle was stored. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_include_handle); - -/**@brief Decodes @ref sd_ble_gatts_service_add command request. - * - * @sa @ref nrf51_gatts_service_add_encoding for packet format, - * @ref ble_gatts_service_add_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of request packet. - * @param[out] p_type Pointer to the service type. - * @param[out] pp_uuid Pointer to pointer to service UUID. - * @param[out] pp_handle Pointer to Pointer to a 16-bit word where the assigned handle will be stored. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ - -uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * const p_type, - ble_uuid_t * * const pp_uuid, - uint16_t * * const pp_handle); - -/**@brief Encodes @ref ble_gatts_service_add_rsp_enc command response. - * - * @sa @ref nrf51_gatts_service_add_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_handle Pointer to a 16-bit word where the assigned handle was stored. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_handle); - -/**@brief Decodes @ref ble_gatts_sys_attr_get_req_dec command request. - * - * @sa @ref sd_ble_gatts_sys_attr_get for packet format, - * @ref ble_gatts_sys_attr_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connectiton handle. - * @param[out] pp_sys_attr_data Pointer to pointer to buffer where system attributes data will be filled in. - * @param[out] pp_sys_attr_data_len Pointer to pointer to variable which contains size of buffer for system attributes. - * @param[out] p_flags Pointer to additional optional flags. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * * const pp_sys_attr_data, - uint16_t * * const pp_sys_attr_data_len, - uint32_t * const p_flags); - -/**@brief Encodes @ref ble_gatts_sys_attr_get_rsp_enc command response. - * - * @sa @ref sd_ble_gatts_sys_attr_get for packet format. - * @ref ble_gatts_sys_attr_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_sys_attr_data Pointer to buffer where system attributes data are storred. - * @param[in] p_sys_attr_data_len Pointer to variable which contains size of buffer for system attributes. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_sys_attr_data, - uint16_t const * const p_sys_attr_data_len); - -/**@brief Decodes @ref sd_ble_gatts_value_set command request. - * - * @sa @ref nrf51_gatts_value_set_encoding for packet format, - * @ref ble_gatts_value_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle - * @param[out] p_handle Pointer to attribute handle - * @param[out] pp_value Pointer to pointer to attribute value structure - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ - -uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - uint16_t * p_handle, - ble_gatts_value_t * * const pp_value); - -/**@brief Encodes @ref sd_ble_gatts_value_set command response. - * - * @sa @ref nrf51_gatts_value_set_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buff Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buff_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_value \c in: size of value returned when value was written with success - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buff, - uint32_t * const p_buff_len, - ble_gatts_value_t * p_value); - -/**@brief Decodes @ref sd_ble_gatts_sys_attr_set command request. - * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format, - * @ref ble_gatts_sys_attr_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] p_conn_handle Pointer to the buffer raw data to be placed in advertisement packet. - * @param[out] pp_sys_attr_data Pointer to pointer to system attribute data. - * @param[out] p_sys_attr_data_len Pointer to data length for system attribute data. - * @param[out] p_flags Pointer to additional optional flags. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * * const pp_sys_attr_data, - uint16_t * const p_sys_attr_data_len, - uint32_t * const p_flags); - -/**@brief Encodes @ref sd_ble_gatts_sys_attr_set command response. - * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format. - * @ref ble_gatts_sys_attr_set_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref ble_gatts_hvx_req_dec command request. - * - * @sa @ref sd_ble_gatts_hvx for packet format, - * @ref ble_gatts_hvx_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] p_conn_handle Pointer to the buffer raw data to be placed in advertisement packet. - * @param[out] pp_hvx_params Pointer to an HVx parameters structure. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_gatts_hvx_params_t * * const pp_hvx_params); - -/**@brief Encodes @ref ble_gatts_hvx_rsp_enc command response. - * - * @sa @ref sd_ble_gatts_sys_attr_set for packet format. - * @ref ble_gatts_hvx_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_bytes_written Pointer to number of bytes written. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_bytes_written); - -/**@brief Decodes @ref sd_ble_gatts_descriptor_add command request. - * - * @sa @ref sd_ble_gatts_descriptor_add for packet format, - * @ref ble_gatts_descriptor_add_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] p_char_handle Pointer to buffer where characteristic handle will be. - returned. - * @param[out] pp_attr Pointer to pointer to an attribute structure. - * @param[out] pp_handle Pointer to pointer to descriptor handle. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_char_handle, - ble_gatts_attr_t * * const pp_attr, - uint16_t * * const pp_handle); - -/**@brief Encodes @ref sd_ble_gatts_descriptor_add command response. - * - * @sa @ref sd_ble_gatts_sys_attr_set for packet format. - * @ref ble_gatts_descriptor_add_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] handle Descriptor handle value. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t handle); - -/**@brief Decodes @ref sd_ble_gatts_rw_authorize_reply command request. - * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format, - * @ref ble_gatts_rw_authorize_reply_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_reply_params Pointer to pointer to \ref ble_gatts_rw_authorize_reply_params_t - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ - -uint32_t ble_gatts_rw_authorize_reply_req_dec( - uint8_t const * const p_buf, - uint32_t - packet_len, - uint16_t * - p_conn_handle, - ble_gatts_rw_authorize_reply_params_t * * const - pp_reply_params); - -/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command response. - * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format. - * @ref ble_gatts_rw_authorize_reply_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gatts_service_changed command request. - * - * @sa @ref nrf51_service_changed_encoding for packet format, - * @ref ble_gatts_service_changed_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_start_handle Pointer to start handle. - * @param[out] p_end_handle Pointer to end handle. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - uint16_t * p_start_handle, - uint16_t * p_end_handle); - -/**@brief Encodes @ref sd_ble_gatts_service_changed command response. - * - * @sa @ref nrf51_service_changed_encoding for packet format. - * @ref ble_gatts_service_changed_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif //BLE_GATTS_CONN_H__ - diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_descriptor_add.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_descriptor_add.c deleted file mode 100644 index 1929309..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_descriptor_add.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_char_handle, - ble_gatts_attr_t * * const pp_attr, - uint16_t * * const pp_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_char_handle); - SER_ASSERT_NOT_NULL(pp_attr); - SER_ASSERT_NOT_NULL(*pp_attr); - SER_ASSERT_NOT_NULL(pp_handle); - SER_ASSERT_NOT_NULL(*pp_handle); - - uint32_t index = 0; - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_DESCRIPTOR_ADD, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_char_handle); - - uint32_t err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_attr, - ble_gatts_attr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_handle, - NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4, total_len); - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_DESCRIPTOR_ADD, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 2, total_len); - - err_code = uint16_t_enc(&handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_conn.h b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_conn.h deleted file mode 100644 index 42d0d3f..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_conn.h +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_EVT_CONN_H__ -#define BLE_GATTS_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gatts_evt_conn GATTS Connectivity event encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief GATTS Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes @ref BLE_GATTS_EVT_HVC event. - * - * @sa @ref nrf51_gatts_evt_hvc_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event. - * - * @sa @ref nrf51_evt_rw_authorize_request for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes @ref BLE_GATTS_EVT_SC_CONFIRM event. - * - * @sa @ref nrf51_gatts_evt_sc_confirm_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes @ref BLE_GATTS_EVT_SYS_ATTR_MISSING event. - * - * @sa @ref nrf51_evt_sys_attr_missing_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes @ref BLE_GATTS_EVT_TIMEOUT event. - * - * @sa @ref nrf51_gatts_evt_timeout_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** - * @brief Encodes @ref BLE_GATTS_EVT_WRITE event. - * - * @sa @ref nrf51_evt_write_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_hvc.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_hvc.c deleted file mode 100644 index 872e9a5..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_hvc.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 2, *p_buf_len); - - index += uint16_encode(BLE_GATTS_EVT_HVC, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.params.hvc.handle, &(p_buf[index])); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_rw_authorize_request.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_rw_authorize_request.c deleted file mode 100644 index 4674938..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_rw_authorize_request.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "conn_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_conn_user_mem_table[]; - -uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_NOT_NULL(p_event); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gatts_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_evt_rw_authorize_request_t_enc( - &(p_event->evt.gatts_evt.params.authorize_request), - p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if(p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) - { - uint32_t conn_index; - - if(conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_enc(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_sc_confirm.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_sc_confirm.c deleted file mode 100644 index 1bf1e0f..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_sc_confirm.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE + 2, *p_buf_len); - - uint32_t index = 0; - index += uint16_encode(BLE_GATTS_EVT_SC_CONFIRM, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_sys_attr_missing.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_sys_attr_missing.c deleted file mode 100644 index cb7c3e4..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_sys_attr_missing.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GATTS_EVT_SYS_ATTR_MISSING, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gatts_evt.params.sys_attr_missing.hint; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_timeout.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_timeout.c deleted file mode 100644 index 096ec5c..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_timeout.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GATTS_EVT_TIMEOUT, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gatts_evt.params.timeout.src; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_write.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_write.c deleted file mode 100644 index acc2a43..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_evt_write.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "conn_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_conn_user_mem_table[]; - -uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint16_t evt_header = BLE_GATTS_EVT_WRITE; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gatts_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_evt_write_t_enc(&(p_event->evt.gatts_evt.params.write), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if((p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_WRITE_REQ) || (p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)) - { - uint32_t conn_index; - - if(conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_enc(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_hvx.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_hvx.c deleted file mode 100644 index 67bd566..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_hvx.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_gatts_hvx_params_t * * const pp_hvx_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_hvx_params); - SER_ASSERT_NOT_NULL(*pp_hvx_params); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_HVX, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - uint32_t err_code = cond_field_dec(p_buf, packet_len, - &index, - (void * *)pp_hvx_params, - ble_gatts_hvx_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_bytes_written) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_HVX, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - uint32_t index = *p_buf_len; - - err_code = cond_field_enc(p_bytes_written, p_buf, total_len, &index, uint16_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_include_add.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_include_add.c deleted file mode 100644 index 766313f..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_include_add.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_service_handle, - uint16_t * const p_inc_srvc_handle, - uint16_t * * const pp_include_handle) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_service_handle); - SER_ASSERT_NOT_NULL(p_inc_srvc_handle); - SER_ASSERT_NOT_NULL(pp_include_handle); - SER_ASSERT_LENGTH_EQ(6, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_INCLUDE_ADD, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_service_handle); - uint16_dec(p_buf, packet_len, &index, p_inc_srvc_handle); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_include_handle = NULL; - } - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_include_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - uint32_t err_code; - - err_code = op_status_enc(SD_BLE_GATTS_INCLUDE_ADD, return_code, p_buf, p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - SER_ASSERT_NOT_NULL(p_include_handle); - err_code = uint16_t_enc(p_include_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; //update change made by op_status_enc - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_rw_authorize_reply.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_rw_authorize_reply.c deleted file mode 100644 index 94390bb..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_rw_authorize_reply.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gatts_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gatts_rw_authorize_reply_req_dec( - uint8_t const * const p_buf, - uint32_t - packet_len, - uint16_t * - p_conn_handle, - ble_gatts_rw_authorize_reply_params_t * * const - pp_reply_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - - uint32_t index = SER_CMD_HEADER_SIZE; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, packet_len, &index, - (void * *)pp_reply_params, ble_gatts_rw_authorize_reply_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_service_add.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_service_add.c deleted file mode 100644 index e1d7c68..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_service_add.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * const p_type, - ble_uuid_t * * const pp_uuid, - uint16_t * * const pp_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_type); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(pp_handle); - SER_ASSERT_NOT_NULL(*pp_handle); - - uint32_t index = SER_CMD_DATA_POS; - - uint32_t err_code; - SER_ASSERT_LENGTH_LEQ(3, buf_len - index); - err_code = uint8_t_dec(p_buf, buf_len, &index, p_type); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_handle, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(index == buf_len, NRF_ERROR_INVALID_LENGTH); - - return err_code; -} - -uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - uint32_t err_code; - - err_code = op_status_enc(SD_BLE_GATTS_SERVICE_ADD, return_code, p_buf, p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; //this seems silly but it is not - } - SER_ASSERT_NOT_NULL(p_handle); - err_code = uint16_t_enc(p_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; //update change made by op_status_enc - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_service_changed.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_service_changed.c deleted file mode 100644 index 37e9e34..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_service_changed.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - uint16_t * p_start_handle, - uint16_t * p_end_handle) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_start_handle); - SER_ASSERT_NOT_NULL(p_end_handle); - - SER_ASSERT_LENGTH_EQ(SER_CMD_HEADER_SIZE + 6, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_SERVICE_CHANGED, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - uint16_dec(p_buf, packet_len, &index, p_start_handle); - uint16_dec(p_buf, packet_len, &index, p_end_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_SERVICE_CHANGED, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_sys_attr_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_sys_attr_get.c deleted file mode 100644 index affbe8e..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_sys_attr_get.c +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * * const pp_sys_attr_data, - uint16_t * * const pp_sys_attr_data_len, - uint32_t * const p_flags) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_sys_attr_data); - SER_ASSERT_NOT_NULL(pp_sys_attr_data_len); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_SYS_ATTR_GET, NRF_ERROR_INVALID_PARAM); - index++; - - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_flags); - *p_conn_handle = uint16_decode(&p_buf[index]); - index += sizeof (uint16_t); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - - SER_ASSERT_NOT_NULL(*pp_sys_attr_data_len); - **pp_sys_attr_data_len = uint16_decode(&p_buf[index]); - index += sizeof (uint16_t); - } - else - { - *pp_sys_attr_data_len = NULL; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, packet_len); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_sys_attr_data = NULL; - } - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_flags); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_sys_attr_data, - uint16_t const * const p_sys_attr_data_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - SER_ASSERT_LENGTH_LEQ(1 + 4, total_len); - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_SYS_ATTR_GET, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_sys_attr_data); - SER_ASSERT_NOT_NULL(p_sys_attr_data_len); - uint32_t index = *p_buf_len; - uint16_t sys_attr_len = 0; - - SER_ASSERT_LENGTH_LEQ(index + 2, total_len); - - if (p_sys_attr_data_len != NULL) - { - index += uint16_encode(*p_sys_attr_data_len, &p_buf[index]); - sys_attr_len = *p_sys_attr_data_len; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, total_len); - p_buf[index++] = p_sys_attr_data ? SER_FIELD_PRESENT : - SER_FIELD_NOT_PRESENT; - - SER_ASSERT_LENGTH_LEQ(index + sys_attr_len, total_len); - - if (p_sys_attr_data != NULL) - { - memcpy(&p_buf[index], p_sys_attr_data, sys_attr_len); - index += sys_attr_len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_sys_attr_set.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_sys_attr_set.c deleted file mode 100644 index 1b26b77..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_sys_attr_set.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * * const pp_sys_attr_data, - uint16_t * const p_sys_attr_data_len, - uint32_t * const p_flags) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - uint16_t sys_attr_data_len_temp; - uint16_t * p_sys_attr_data_len_temp = &sys_attr_data_len_temp; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_sys_attr_data); - SER_ASSERT_NOT_NULL(*pp_sys_attr_data); - SER_ASSERT_NOT_NULL(p_sys_attr_data_len); - SER_ASSERT_NOT_NULL(p_flags); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 7, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_sys_attr_data = NULL; - SER_ASSERT_LENGTH_EQ(index + 4, packet_len); - *p_sys_attr_data_len = 0; - break; - - case SER_FIELD_PRESENT: - uint16_dec(p_buf, packet_len, &index, p_sys_attr_data_len_temp); - SER_ASSERT_LENGTH_LEQ(*p_sys_attr_data_len_temp, *p_sys_attr_data_len); - *p_sys_attr_data_len = *p_sys_attr_data_len_temp; - SER_ASSERT_LENGTH_EQ(index + *p_sys_attr_data_len + 4, packet_len); - memcpy(*pp_sys_attr_data, &p_buf[index], *p_sys_attr_data_len); - index += *p_sys_attr_data_len; - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_flags); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_SYS_ATTR_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_value_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_value_get.c deleted file mode 100644 index eebd031..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_value_get.c +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle, - ble_gatts_value_t * * const pp_value) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - SER_ASSERT_NOT_NULL(pp_value); - SER_ASSERT_NOT_NULL(*pp_value); - SER_ASSERT_NOT_NULL((*pp_value)->p_value); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 5, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_VALUE_GET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_value)->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_value)->offset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, packet_len - index); - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - (*pp_value)->p_value = NULL; - } - } - else - { - *pp_value = NULL; - } - - return err_code; -} - - -uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gatts_value_t * const p_value) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_RSP_HEADER_SIZE, *p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_VALUE_GET, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - uint32_t index = *p_buf_len; - - if (return_code == NRF_SUCCESS) - { - SER_ASSERT_NOT_NULL(p_value); - - err_code = ble_gatts_value_t_enc(p_value, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_value_set.c b/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_value_set.c deleted file mode 100644 index 4a7eb2b..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_gatts_value_set.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "cond_field_serialization.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - uint16_t * p_handle, - ble_gatts_value_t * * const pp_value) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - SER_ASSERT_NOT_NULL(pp_value); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(4, packet_len - index); //make sure that payload length is at least 4 bytes - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - uint16_dec(p_buf, packet_len, &index, p_handle); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_value, ble_gatts_value_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buff, - uint32_t * const p_buff_len, - ble_gatts_value_t * p_value) -{ - SER_ASSERT_NOT_NULL(p_buff); - SER_ASSERT_NOT_NULL(p_buff_len); - - uint32_t buf_len = *p_buff_len; - uint32_t index = 0; - uint32_t err_code; - - err_code = op_status_enc(SD_BLE_GATTS_VALUE_SET, return_code, p_buff, p_buff_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - SER_ASSERT_NOT_NULL(p_value); - err_code = ble_gatts_value_t_enc(p_value, p_buff, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buff_len = index; //update change made by op_status_enc - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_cid_register.c b/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_cid_register.c deleted file mode 100644 index 9e2a775..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_cid_register.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_l2cap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_cid) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_cid); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_LENGTH_EQ(3, buf_len); - SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_REGISTER, NRF_ERROR_INVALID_PARAM); - - index++; - err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_REGISTER, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_cid_unregister.c b/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_cid_unregister.c deleted file mode 100644 index 74d4619..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_cid_unregister.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_l2cap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_cid) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_cid); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_LENGTH_EQ(3, buf_len); - SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_UNREGISTER, NRF_ERROR_INVALID_PARAM); - - index++; - err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_UNREGISTER, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_conn.h b/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_conn.h deleted file mode 100644 index 9cbf645..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_conn.h +++ /dev/null @@ -1,156 +0,0 @@ -/* Copyright (c) 2011 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * - */ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_l2cap_conn L2CAP Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief L2CAP Connectivity command request decoders and command response encoders. - */ - -#ifndef BLE_L2CAP_CONN_H__ -#define BLE_L2CAP_CON__H__ - -#include "ble.h" -#include "ble_types.h" -#include "ble_ranges.h" -#include "ble_err.h" -#include "ble_l2cap.h" - -/**@brief Decodes @ref sd_ble_l2cap_cid_register command request. - * - * @sa @ref nrf51_ble_l2cap_cid_register for packet format, - * @ref ble_l2cap_cid_register_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[in] p_cid Pointer to L2CAP CID. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_cid); - -/**@brief Encodes @ref sd_ble_l2cap_cid_register command response. - * - * @sa @ref nrf51_ble_l2cap_cid_register for packet format. - * @ref ble_l2cap_cid_register_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_l2cap_cid_unregister command request. - * - * @sa @ref nrf51_ble_l2cap_cid_unregister for packet format, - * @ref ble_l2cap_cid_unregister_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[in] p_cid Pointer to L2CAP CID. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_cid); - -/**@brief Encodes @ref sd_ble_l2cap_cid_unregister command response. - * - * @sa @ref nrf51_ble_l2cap_cid_unregister for packet format. - * @ref ble_l2cap_cid_unregister_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_l2cap_tx command request. - * - * @sa @ref nrf51_ble_l2cap_tx for packet format, - * @ref ble_l2cap_tx_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[in] p_conn_handle Pointer to connection handle. - * @param[in] pp_l2cap_header Pointer to pointer to L2CAP header. - * @param[in] pp_data Pointer to pointer L2CAP data. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, - uint16_t * p_conn_handle, - ble_l2cap_header_t * * const pp_l2cap_header, - uint8_t const * * pp_data); - -/**@brief Encodes @ref sd_ble_l2cap_tx command response. - * - * @sa @ref nrf51_ble_l2cap_tx for packet format. - * @ref ble_l2cap_tx_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -#endif //BLE_L2CAP_CONN_H__ - -/** - @} - */ diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_evt_conn.h b/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_evt_conn.h deleted file mode 100644 index ee85aa1..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_evt_conn.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_L2CAP_EVT_CONN_H__ -#define BLE_L2CAP_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_l2cap_evt_conn L2CAP Connectivity event encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief L2CAP Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes ble_l2cap_evt_rx event. - * - * @sa @ref nrf51_l2cap_evt_rx_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_evt_rx.c b/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_evt_rx.c deleted file mode 100644 index 15793ed..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_evt_rx.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_l2cap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code; - uint32_t total_len = *p_buf_len; - - uint16_t evt_id = BLE_L2CAP_EVT_RX; - - err_code = uint16_t_enc(&evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.l2cap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_l2cap_evt_rx_t_enc(&(p_event->evt.l2cap_evt.params.rx), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_tx.c b/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_tx.c deleted file mode 100644 index c574b40..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_l2cap_tx.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include -#include "ble_l2cap_conn.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, - uint16_t * p_conn_handle, - ble_l2cap_header_t * * const pp_l2cap_header, - uint8_t const * * pp_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_l2cap_header); - SER_ASSERT_NOT_NULL(*pp_l2cap_header); - SER_ASSERT_NOT_NULL(pp_data); - //SER_ASSERT_NOT_NULL(*pp_data); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_l2cap_header, - ble_l2cap_header_t_dec); - - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*pp_l2cap_header != NULL) - { - *pp_data = p_buf + index + 1; - index += 1 + (*pp_l2cap_header)->len; - } - else - { - *pp_data = NULL; - index++; - } - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_TX, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_opt_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_opt_get.c deleted file mode 100644 index 7f2da63..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_opt_get.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t **const pp_opt ) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_NOT_NULL(pp_opt); - SER_ASSERT_NOT_NULL(*pp_opt); - SER_ASSERT_LENGTH_EQ(SER_CMD_HEADER_SIZE + 4 + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_OPT_GET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (*p_opt_id == BLE_GAP_OPT_CH_MAP) || - (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (*p_opt_id == BLE_GAP_OPT_PASSKEY) || - (*p_opt_id == BLE_GAP_OPT_PRIVACY) || - (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_opt = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_opt_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint32_t opt_id, - ble_opt_t const * const p_opt) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_OPT_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_opt); - SER_ASSERT(((opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (opt_id == BLE_GAP_OPT_CH_MAP) || - (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (opt_id == BLE_GAP_OPT_PASSKEY) || - (opt_id == BLE_GAP_OPT_PRIVACY) || - (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - uint32_t index = *p_buf_len; - err_code = uint32_t_enc(&opt_id, p_buf, total_len, &index); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - switch (opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_enc((void *)&(p_opt->common_opt.radio_cpu_mutex), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_enc((void *)&(p_opt->gap_opt.ch_map), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_enc((void *)&(p_opt->gap_opt.local_conn_latency), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_enc((void *)&(p_opt->gap_opt.passkey), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_enc((void *)&(p_opt->gap_opt.privacy), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_enc((void *)&(p_opt->gap_opt.scan_req_report), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_enc((void *)&(p_opt->gap_opt.compat_mode), p_buf, total_len, &index); - break; - } - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_opt_id_pre_decoder.c b/components/serialization/connectivity/codecs/s120/serializers/ble_opt_id_pre_decoder.c deleted file mode 100644 index 7b0e749..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_opt_id_pre_decoder.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_OPT_SET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_opt_set.c b/components/serialization/connectivity/codecs/s120/serializers/ble_opt_set.c deleted file mode 100644 index 8a0b6e5..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_opt_set.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t **const pp_opt ) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_NOT_NULL(pp_opt); - SER_ASSERT_NOT_NULL(*pp_opt); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4 + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_OPT_SET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (*p_opt_id == BLE_GAP_OPT_CH_MAP) || - (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (*p_opt_id == BLE_GAP_OPT_PASSKEY) || - (*p_opt_id == BLE_GAP_OPT_PRIVACY) || - (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_opt = NULL; - } - else - { - switch(*p_opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_dec(p_buf, packet_len, &index, &((*pp_opt)->common_opt.radio_cpu_mutex)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.ch_map)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.local_conn_latency)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.passkey)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.privacy)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.scan_req_report)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.compat_mode)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_opt_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_OPT_SET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_tx_buffer_count_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_tx_buffer_count_get.c deleted file mode 100644 index eec8bb9..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_tx_buffer_count_get.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" - -uint32_t ble_tx_buffer_count_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint8_t * * const pp_count) -{ - SER_ASSERT_NOT_NULL(p_buf); - - uint32_t index = 0; - uint8_t opcode; - uint32_t err_code; - - err_code = uint8_t_dec(p_buf, packet_len, &index, &opcode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT(opcode == SD_BLE_TX_BUFFER_COUNT_GET, NRF_ERROR_INVALID_PARAM); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_count, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_tx_buffer_count_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_count) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_TX_BUFFER_COUNT_GET, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = cond_field_enc(p_count, p_buf, total_len, p_buf_len, uint8_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_user_mem_reply.c b/components/serialization/connectivity/codecs/s120/serializers/ble_user_mem_reply.c deleted file mode 100644 index 61062b6..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_user_mem_reply.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_user_mem_block_t * * const pp_mem_block) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_mem_block); - SER_ASSERT_NOT_NULL(*pp_mem_block); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 4, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_USER_MEM_REPLY, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - // Decoding order is different than structure elements order because - // mem block length is received first - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_mem_block)->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **)&((*pp_mem_block)->p_mem), NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - *pp_mem_block = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_dec(p_buf, *p_buf_len, SD_BLE_USER_MEM_REPLY, &return_code); -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_uuid_decode.c b/components/serialization/connectivity/codecs/s120/serializers/ble_uuid_decode.c deleted file mode 100644 index 000e4d8..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_uuid_decode.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, - uint8_t * p_uuid_le_len, - uint8_t * * const pp_uuid_le, - ble_uuid_t * * const pp_uuid) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_uuid_le_len); - uint32_t err_code; - uint32_t index = 0; - uint8_t opcode = SD_BLE_UUID_DECODE; - - SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - index)); - uint8_dec(p_buf, buf_len, &index, &opcode); - SER_ASSERT(opcode == SD_BLE_UUID_DECODE, NRF_ERROR_INVALID_DATA); - - err_code = len8data_dec(p_buf, buf_len, &index, pp_uuid_le, p_uuid_le_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_uuid_t const * const p_uuid) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_UUID_DECODE, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - *p_buf_len = index; - return NRF_SUCCESS; - } - - err_code = cond_field_enc((void *)p_uuid, p_buf, total_len, &index, ble_uuid_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_uuid_encode.c b/components/serialization/connectivity/codecs/s120/serializers/ble_uuid_encode.c deleted file mode 100644 index 0843668..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_uuid_encode.c +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_uuid_t * * const pp_uuid, - uint8_t * * const pp_uuid_le_len, - uint8_t * * const pp_uuid_le) -{ - uint32_t index = SER_CMD_HEADER_SIZE; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(pp_uuid_le_len); - SER_ASSERT_NOT_NULL(pp_uuid_le); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid_le_len); - SER_ASSERT_NOT_NULL(*pp_uuid_le); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 3, packet_len); - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - index++; - *pp_uuid = NULL; - } - else if (p_buf[index] == SER_FIELD_PRESENT) - { - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 6, packet_len); - index++; - uint16_dec(p_buf, packet_len, &index, &((*pp_uuid)->uuid)); - (*pp_uuid)->type = p_buf[index++]; - } - else - { - return NRF_ERROR_INVALID_DATA; - } - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - *pp_uuid_le_len = NULL; - } - else if (p_buf[index] != SER_FIELD_PRESENT) - { - return NRF_ERROR_INVALID_DATA; - } - - index++; - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - *pp_uuid_le = NULL; - } - else if (p_buf[index] != SER_FIELD_PRESENT) - { - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index + 1, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t uuid_le_len, - uint8_t const * const p_uuid_le) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_UUID_ENCODE, return_code, - p_buf, p_buf_len); - uint32_t index = *p_buf_len; - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, total_len); - p_buf[index++] = uuid_le_len; - - if (p_uuid_le != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + uuid_le_len, total_len); - memcpy(p_buf + index, p_uuid_le, uuid_le_len); - index += uuid_le_len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_uuid_vs_add.c b/components/serialization/connectivity/codecs/s120/serializers/ble_uuid_vs_add.c deleted file mode 100644 index 5deeac7..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_uuid_vs_add.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf, - uint16_t buf_len, - ble_uuid128_t * * const pp_uuid, - uint8_t * * const pp_uuid_type) -{ - uint32_t index = SER_CMD_HEADER_SIZE; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(pp_uuid_type); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid_type); - - uint32_t err_code; - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid128_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid_type, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_uuid_type) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_UUID_VS_ADD, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = cond_field_enc((void *)p_uuid_type, p_buf, total_len, &index, uint8_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_version_get.c b/components/serialization/connectivity/codecs/s120/serializers/ble_version_get.c deleted file mode 100644 index 28dbe54..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_version_get.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_version_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_version_t * * const pp_version) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_version); - SER_ASSERT_NOT_NULL(*pp_version); - SER_ASSERT_LENGTH_EQ(SER_CMD_HEADER_SIZE + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_VERSION_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_version = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_version_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_version_t const * const p_version) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_VERSION_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_version); - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 5, total_len); - p_buf[index++] = p_version->version_number; - index += uint16_encode(p_version->company_id, &p_buf[index]); - index += uint16_encode(p_version->subversion_number, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/conn_ble_gap_sec_keys.c b/components/serialization/connectivity/codecs/s120/serializers/conn_ble_gap_sec_keys.c deleted file mode 100644 index a7db7e3..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/conn_ble_gap_sec_keys.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "conn_ble_gap_sec_keys.h" -#include "nrf_error.h" -#include - -ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS]; - -uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -#define SER_MAX_CONNECTIONS 2 - -/**@brief GAP connection - keyset mapping structure. - * - * @note This structure is used to map keysets to connection instances, and will be stored in a static table. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that keys for this connection are used by soft device. 0: keys used; 1: keys not used*/ - ble_gap_sec_keyset_t keyset; /**< Keyset structure see @ref ble_gap_sec_keyset_t.*/ - ble_gap_enc_key_t enc_key_periph; /**< Peripheral Encryption Key, see @ref ble_gap_enc_key_t.*/ - ble_gap_id_key_t id_key_periph; /**< Peripheral Identity Key, see @ref ble_gap_id_key_t.*/ - ble_gap_sign_info_t sign_key_periph; /**< Peripheral Signing Information, see @ref ble_gap_sign_info_t.*/ - ble_gap_enc_key_t enc_key_central; /**< Central Encryption Key, see @ref ble_gap_enc_key_t.*/ - ble_gap_id_key_t id_key_central; /**< Central Identity Key, see @ref ble_gap_id_key_t.*/ - ble_gap_sign_info_t sign_key_central; /**< Central Signing Information, see @ref ble_gap_sign_info_t.*/ -} ser_ble_gap_conn_keyset_t; - -/**@brief allocates instance in m_conn_keys_table[] for storage of encryption keys. - * - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS great success. - * @retval NRF_ERROR_NO_MEM no free instance available. - */ -uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_gap_sec_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_conn_keys_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context table entry found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_CONN_BLE_GAP_SEC_KEYS_H diff --git a/components/serialization/connectivity/codecs/s120/serializers/conn_ble_user_mem.c b/components/serialization/connectivity/codecs/s120/serializers/conn_ble_user_mem.c deleted file mode 100644 index 7ee0563..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/conn_ble_user_mem.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "conn_ble_user_mem.h" -#include "ser_config.h" -#include "nrf_error.h" -#include - - - -ser_ble_user_mem_t m_conn_user_mem_table[SER_MAX_CONNECTIONS]; - -uint32_t conn_ble_user_mem_context_create(uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -/**@brief Connection - user memory mapping structure. - * - * @note This structure is used to map keysets to connection instances, and will be stored in a static table. - */ -//lint -esym(452,ser_ble_user_mem_t) -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that user memory for this connection is used by soft device. 0: memory used; 1: memory not used*/ - ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t.*/ - uint8_t mem_table[64]; /**< Memory table.*/ -} ser_ble_user_mem_t; - -/**@brief allocates instance in m_user_mem_table[] for storage. - * - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS great success. - * @retval NRF_ERROR_NO_MEM no free instance available. - */ -uint32_t conn_ble_user_mem_context_create(uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_user_mem_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_user_mem_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context table entry found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_CONN_BLE_USER_MEM_H diff --git a/components/serialization/connectivity/codecs/s120/serializers/nrf_soc_conn.h b/components/serialization/connectivity/codecs/s120/serializers/nrf_soc_conn.h deleted file mode 100644 index 7448e81..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/nrf_soc_conn.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_SOC_CONN_H__ -#define NRF_SOC_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s120_codecs Connectivity s120 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup soc_conn SOC Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s120_codecs - * - * @brief SOC Connectivity command request decoders and command response encoderss. - */ -#include "nrf_soc.h" - -/**@brief Decodes @ref sd_power_system_off command request. - * - * @sa @ref nrf51_sd_power_off for packet format. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in] packet_len Length (in bytes) of request packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. - */ -uint32_t power_system_off_req_dec(uint8_t const * const p_buf, uint16_t packet_len); - - -/**@brief Decodes @ref sd_temp_get command request. - * - * @sa @ref nrf51_sd_temp_get for packet format. - * @ref temp_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in] buf_len Length (in bytes) of request packet. - * @param[out] pp_temp Pointer to pointer to result of temperature measurement. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. - */ -uint32_t temp_get_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - int32_t * * const pp_temp); - -/**@brief Encodes @ref sd_temp_get command response. - * - * @sa @ref nrf51_sd_temp_get for packet format. - * @ref temp_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_temp Pointer to result of temperature measurement. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t temp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int32_t * const p_temp); - -/** @} */ -#endif - diff --git a/components/serialization/connectivity/codecs/s120/serializers/power_system_off.c b/components/serialization/connectivity/codecs/s120/serializers/power_system_off.c deleted file mode 100644 index 00e66b2..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/power_system_off.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "nrf_soc_conn.h" -#include "ble_serialization.h" - -uint32_t power_system_off_req_dec(uint8_t const * const p_buf, - uint16_t packet_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - - uint32_t index = 0; - SER_ASSERT_LENGTH_LEQ(1, packet_len); - SER_ASSERT(p_buf[index] == SD_POWER_SYSTEM_OFF, NRF_ERROR_INVALID_PARAM); - index++; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s120/serializers/temp_get.c b/components/serialization/connectivity/codecs/s120/serializers/temp_get.c deleted file mode 100644 index 8cd2081..0000000 --- a/components/serialization/connectivity/codecs/s120/serializers/temp_get.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "nrf_soc.h" -#include "nrf_error.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" - -uint32_t temp_get_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - int32_t * * const pp_temp) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_temp); - SER_ASSERT_NOT_NULL(*pp_temp); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len); - SER_ASSERT(p_buf[index] == SD_TEMP_GET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_temp, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t temp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int32_t * const p_temp) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_temp); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t total_len = *p_buf_len; - - err_code = ser_ble_cmd_rsp_status_code_enc(SD_TEMP_GET, - return_code, - p_buf, - p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - index += *p_buf_len; - - if (return_code == NRF_SUCCESS) - { - err_code = uint32_t_enc(p_temp, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw.h b/components/serialization/connectivity/codecs/s130/middleware/conn_mw.h deleted file mode 100644 index 378a96f..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_H -#define _CONN_MW_H - -#include - -/**@brief Connectivity Middleware dispatcher function - * - * @details It will handle decode the opcode from RX buffer and based on the opcode it will search - * for registered handler. Handler is called once it is found. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. - */ -uint32_t conn_mw_handler (uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); -#endif //_CONN_MW_H diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble.c b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble.c deleted file mode 100644 index 78a55ea..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble.c +++ /dev/null @@ -1,287 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "ble_conn.h" -#include "conn_mw_ble.h" -#include "ble_serialization.h" -#include "conn_ble_user_mem.h" - -extern ser_ble_user_mem_t m_conn_user_mem_table[]; - -uint32_t conn_mw_ble_tx_buffer_count_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t count; - uint8_t * p_count = &count; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_tx_buffer_count_get_req_dec(p_rx_buf, rx_buf_len, &p_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_tx_buffer_count_get(p_count); - - err_code = ble_tx_buffer_count_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_uuid_vs_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_uuid128_t uuid; - ble_uuid128_t * p_uuid = &uuid; - uint8_t uuid_type; - uint8_t * p_uuid_type = &uuid_type; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_uuid_vs_add_req_dec(p_rx_buf, rx_buf_len, &p_uuid, &p_uuid_type); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_uuid_vs_add(p_uuid, p_uuid_type); - - err_code = ble_uuid_vs_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid_type); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - return err_code; -} - -uint32_t conn_mw_ble_uuid_decode(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t raw_uuid[16]; - uint8_t uuid_len = sizeof (raw_uuid); - uint8_t * p_raw_uuid = raw_uuid; - ble_uuid_t uuid; - ble_uuid_t * p_uuid = &uuid; - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_uuid_decode_req_dec(p_rx_buf, rx_buf_len, &uuid_len, &p_raw_uuid, &p_uuid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_uuid_decode(uuid_len, p_raw_uuid, p_uuid); - - err_code = ble_uuid_decode_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_uuid_encode(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t raw_uuid[16]; - uint8_t uuid_len = sizeof (raw_uuid); - uint8_t * p_uuid_len = &uuid_len; - uint8_t * p_raw_uuid = raw_uuid; - ble_uuid_t uuid; - ble_uuid_t * p_uuid = &uuid; - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_uuid_encode_req_dec(p_rx_buf, rx_buf_len, &p_uuid, &p_uuid_len, &p_raw_uuid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_uuid_encode(p_uuid, p_uuid_len, p_raw_uuid); - - err_code = ble_uuid_encode_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, uuid_len, p_raw_uuid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_version_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_version_t version; - ble_version_t * p_version = &version; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_version_get_req_dec(p_rx_buf, rx_buf_len, &p_version); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_version_get(p_version); - - err_code = ble_version_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_version); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_opt_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t opt_id; - ble_opt_t opt; - ble_opt_t *p_opt = &opt; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_opt_get_req_dec(p_rx_buf, rx_buf_len, &opt_id, &p_opt); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_opt_get(opt_id, p_opt); - - err_code = ble_opt_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, opt_id, p_opt); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t opt_id = 0xFFFFFFFF; - uint16_t act_latency; - uint8_t passkey[BLE_GAP_PASSKEY_LEN]; - ble_gap_irk_t irk = {{0}}; - uint32_t err_code = NRF_SUCCESS; - - /* Pre-decode type of ble_opt_t union */ - err_code = ble_opt_id_pre_dec(p_rx_buf, rx_buf_len, &opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - ble_opt_t opt; - ble_opt_t *p_opt = &opt; - /* Initialaize appropriate pointers inside opt union based on opt_id */ - switch(opt_id) - { - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - opt.gap_opt.local_conn_latency.p_actual_latency = &act_latency; - break; - case BLE_GAP_OPT_PASSKEY: - opt.gap_opt.passkey.p_passkey = passkey; - break; - case BLE_GAP_OPT_PRIVACY: - opt.gap_opt.privacy.p_irk = &irk; - break; - } - - uint32_t sd_err_code; - - err_code = ble_opt_set_req_dec(p_rx_buf, rx_buf_len, &opt_id, &p_opt); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_opt_set(opt_id, p_opt); - - err_code = ble_opt_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_enable(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_enable_params_t params; - ble_enable_params_t * p_params = ¶ms; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_enable_req_dec(p_rx_buf, rx_buf_len, &p_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_enable(p_params); - - err_code = ble_enable_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t * p_conn_handle; - ble_user_mem_block_t * p_mem_block; - uint32_t err_code = NRF_SUCCESS; - uint32_t user_mem_tab_index; - - /* Allocate user memory context for SoftDevice */ - err_code = conn_ble_user_mem_context_create(&user_mem_tab_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_conn_handle = &(m_conn_user_mem_table[user_mem_tab_index].conn_handle); - p_mem_block = &(m_conn_user_mem_table[user_mem_tab_index].mem_block); - - uint32_t sd_err_code; - - err_code = ble_user_mem_reply_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &p_mem_block); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_user_mem_reply(*p_conn_handle, p_mem_block); - - err_code = ble_user_mem_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble.h b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble.h deleted file mode 100644 index 8698fcc..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble.h +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_BLE_H -#define _CONN_MW_BLE_H - -#include - -/**@brief Handles @ref sd_ble_tx_buffer_count_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_tx_buffer_count_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_uuid_vs_add command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_uuid_vs_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_uuid_decode command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_uuid_decode(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_uuid_encode command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_uuid_encode(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_version_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_version_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_opt_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_opt_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_opt_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_enable command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_enable(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_user_mem_reply command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -#endif //_CONN_MW_BLE_H diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gap.h b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gap.h deleted file mode 100644 index aa43b0b..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gap.h +++ /dev/null @@ -1,532 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_BLE_GAP_H -#define _CONN_MW_BLE_GAP_H - -#include - -/**@brief Handles @ref sd_ble_gap_address_set command request and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_address_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_address_get command request and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_address_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_adv_data_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_adv_data_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_adv_start command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_adv_stop command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_adv_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_conn_param_update command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_conn_param_update(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_disconnect command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_disconnect(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_tx_power_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_tx_power_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_appearance_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_appearance_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_appearance_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_appearance_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_ppcp_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_ppcp_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_ppcp_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_ppcp_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_device_name_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_device_name_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_device_name_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_device_name_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_authenticate command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_authenticate(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_sec_params_reply command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_auth_key_reply command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_auth_key_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_sec_info_reply command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_sec_info_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_conn_sec_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_conn_sec_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_rssi_start command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_rssi_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_rssi_stop command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_rssi_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -///**@brief Handles @ref sd_ble_gap_rssi_get command and prepares response. -// * -// * @param[in] p_rx_buf Pointer to input buffer. -// * @param[in] rx_buf_len Size of p_rx_buf. -// * @param[out] p_tx_buf Pointer to output buffer. -// * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. -// * \c out: Length of valid data in \p p_tx_buf. -// * -// * @retval NRF_SUCCESS Handler success. -// * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. -// * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. -// * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. -// */ -//uint32_t conn_mw_ble_gap_rssi_get(uint8_t const * const p_rx_buf, -// uint32_t rx_buf_len, -// uint8_t * const p_tx_buf, -// uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_connect command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_connect_cancel command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_connect_cancel(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_scan_start command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_scan_stop command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_scan_stop(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_encrypt command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ - -uint32_t conn_mw_ble_gap_encrypt(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief allocates instance in m_conn_keys_table[] for storage of encryption keys. - * - * @param[in] conn_handle conn_handle - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS great success. - * @retval NRF_ERROR_NO_MEM no free instance available. - */ -uint32_t conn_mw_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS great success - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_mw_ble_gap_sec_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_conn_keys_table[]. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS great success - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_mw_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); - -#endif //_CONN_MW_BLE_GAP_H diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gattc.c b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gattc.c deleted file mode 100644 index d41ac4d..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gattc.c +++ /dev/null @@ -1,293 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "ble_gattc_conn.h" -#include "conn_mw_ble_gattc.h" -#include "ble_serialization.h" - -uint32_t conn_mw_ble_gattc_primary_services_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t start_handle; - ble_uuid_t srvc_uuid; - ble_uuid_t * p_srvc_uuid = &srvc_uuid; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_primary_services_discover_req_dec(p_rx_buf, - rx_buf_len, - &conn_handle, - &start_handle, - &p_srvc_uuid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_primary_services_discover(conn_handle, start_handle, p_srvc_uuid); - - err_code = ble_gattc_primary_services_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_relationships_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - ble_gattc_handle_range_t handle_range; - ble_gattc_handle_range_t * p_handle_range = &handle_range; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_relationships_discover_req_dec(p_rx_buf, rx_buf_len, - &conn_handle, &p_handle_range); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_relationships_discover(conn_handle, p_handle_range); - - err_code = ble_gattc_relationships_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_characteristics_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - ble_gattc_handle_range_t handle_range; - ble_gattc_handle_range_t * p_handle_range = &handle_range; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_characteristics_discover_req_dec(p_rx_buf, rx_buf_len, - &conn_handle, &p_handle_range); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_characteristics_discover(conn_handle, p_handle_range); - - err_code = ble_gattc_characteristics_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_descriptors_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - ble_gattc_handle_range_t handle_range; - ble_gattc_handle_range_t * p_handle_range = &handle_range; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_descriptors_discover_req_dec(p_rx_buf, rx_buf_len, - &conn_handle, &p_handle_range); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_descriptors_discover(conn_handle, p_handle_range); - - err_code = ble_gattc_descriptors_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_char_value_by_uuid_read(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - - ble_uuid_t uuid = {0}; - ble_uuid_t * p_uuid = &uuid; - - ble_gattc_handle_range_t handle_range; - ble_gattc_handle_range_t * p_handle_range = &handle_range; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_char_value_by_uuid_read_req_dec(p_rx_buf, rx_buf_len, - &conn_handle, &p_uuid, &p_handle_range); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_char_value_by_uuid_read(conn_handle, p_uuid, p_handle_range); - - err_code = ble_gattc_char_value_by_uuid_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_read(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t * p_conn_handle = &conn_handle; - - uint16_t handle; - uint16_t * p_handle = &handle; - - uint16_t offset; - uint16_t * p_offset = &offset; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_read_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_handle, p_offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_read(conn_handle, handle, offset); - - err_code = ble_gattc_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_char_values_read(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t * p_conn_handle = &conn_handle; - - uint16_t handles[BLE_GATTC_HANDLE_COUNT_LEN_MAX]; - uint16_t * p_handles = handles; - - uint16_t handle_count = BLE_GATTC_HANDLE_COUNT_LEN_MAX; - uint16_t * p_handle_count = &handle_count; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_char_values_read_req_dec(p_rx_buf, - rx_buf_len, - p_conn_handle, - &p_handles, - p_handle_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_char_values_read(conn_handle, p_handles, handle_count); - - err_code = ble_gattc_char_values_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_write(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t * p_conn_handle = &conn_handle; - - uint8_t value[BLE_GATTC_WRITE_P_VALUE_LEN_MAX]; - - ble_gattc_write_params_t write_params = {0}; - ble_gattc_write_params_t * p_write_params = &write_params; - - p_write_params->len = BLE_GATTC_WRITE_P_VALUE_LEN_MAX; - p_write_params->p_value = value; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gattc_write_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &p_write_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_write(conn_handle, p_write_params); - - err_code = ble_gattc_write_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gattc_hv_confirm(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - uint16_t conn_handle; - uint16_t * p_conn_handle = &conn_handle; - - uint16_t handle; - uint16_t * p_handle = &handle; - - err_code = ble_gattc_hv_confirm_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gattc_hv_confirm(conn_handle, handle); - - err_code = ble_gattc_hv_confirm_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gattc.h b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gattc.h deleted file mode 100644 index 403ae11..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gattc.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_BLE_GATTC_H - #define _CONN_MW_BLE_GATTC_H - -#include - -/**@brief Handles @ref sd_ble_gattc_primary_services_discover command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_primary_services_discover (uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_relationships_discover command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_relationships_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_characteristics_discover command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_characteristics_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_descriptors_discover command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_descriptors_discover(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_char_value_by_uuid_read command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_char_value_by_uuid_read(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_read command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_read (uint8_t const *const rx_buf, - uint32_t rx_buf_len, - uint8_t *const tx_buf, - uint32_t *const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_char_values_read command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_char_values_read (uint8_t const *const rx_buf, - uint32_t rx_buf_len, - uint8_t *const tx_buf, - uint32_t *const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_write command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_write (uint8_t const *const rx_buf, - uint32_t rx_buf_len, - uint8_t *const tx_buf, - uint32_t *const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gattc_hv_confirm command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gattc_hv_confirm (uint8_t const *const rx_buf, - uint32_t rx_buf_len, - uint8_t *const tx_buf, - uint32_t *const p_tx_buf_len); - - -#endif //_CONN_MW_BLE_GATTC_H diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gatts.c b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gatts.c deleted file mode 100644 index 018c5ce..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gatts.c +++ /dev/null @@ -1,407 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include "conn_mw_ble_gatts.h" -#include "ble_serialization.h" - -uint32_t conn_mw_ble_gatts_service_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t type; - ble_uuid_t uuid = {0}; - ble_uuid_t * p_uuid = &uuid; - uint16_t handle; - uint16_t * p_handle = &handle; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_service_add_req_dec(p_rx_buf, rx_buf_len, &type, &p_uuid, &p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_service_add(type, p_uuid, p_handle); - - err_code = ble_gatts_service_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_characteristic_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t service_handle; - - //Preparing char_md - ble_gatts_char_md_t char_md; - - uint8_t char_user_desc[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_gatts_char_pf_t char_pf; - ble_gatts_attr_md_t user_desc_md; - ble_gatts_attr_md_t cccd_md; - ble_gatts_attr_md_t sccd_md; - - char_md.char_user_desc_size = sizeof (char_user_desc); - char_md.p_char_user_desc = char_user_desc; - char_md.p_char_pf = &char_pf; - char_md.p_user_desc_md = &user_desc_md; - char_md.p_cccd_md = &cccd_md; - char_md.p_sccd_md = &sccd_md; - - ble_gatts_char_md_t * p_char_md = &char_md; - - //Preparing attr_char_value - ble_gatts_attr_t attr_char_value; - ble_uuid_t uuid; - ble_gatts_attr_md_t attr_md; - uint8_t value[BLE_GATTS_VAR_ATTR_LEN_MAX]; - - attr_char_value.p_uuid = &uuid; - attr_char_value.p_attr_md = &attr_md; - attr_char_value.init_len = sizeof (value); - attr_char_value.p_value = value; - - ble_gatts_attr_t * p_attr_char_value = &attr_char_value; - - //Preparing handles - ble_gatts_char_handles_t handles; - ble_gatts_char_handles_t * p_handles = &handles; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_characteristic_add_req_dec(p_rx_buf, rx_buf_len, &service_handle, - &p_char_md, &p_attr_char_value, &p_handles); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_characteristic_add(service_handle, p_char_md, - p_attr_char_value, p_handles); - - err_code = ble_gatts_characteristic_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, - p_handles); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; - -} - -uint32_t conn_mw_ble_gatts_include_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t service_handle; - uint16_t inc_srvc_handle; - uint16_t handle; - uint16_t * p_handle = &handle; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_include_add_req_dec(p_rx_buf, rx_buf_len, &service_handle, - &inc_srvc_handle, &p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_include_add(service_handle, inc_srvc_handle, p_handle); - - err_code = ble_gatts_include_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_descriptor_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t char_handle; - uint8_t attr_value[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_uuid_t char_uuid; - ble_gatts_attr_md_t metadata; - ble_gatts_attr_t attr; - ble_gatts_attr_t * p_attr = &attr; - - attr.p_uuid = &char_uuid; - attr.p_attr_md = &metadata; - attr.p_value = attr_value; - attr.init_len = sizeof (attr_value); - - uint16_t handle; - uint16_t * p_handle = &handle; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_descriptor_add_req_dec(p_rx_buf, rx_buf_len, &char_handle, &p_attr, - &p_handle); - - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_descriptor_add(char_handle, p_attr, p_handle); - - err_code = ble_gatts_descriptor_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_value_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t handle; - uint8_t attr_val_table[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_gatts_value_t attr_val = - { - .len = sizeof (attr_val_table), - .offset = 0, - .p_value = attr_val_table - }; - ble_gatts_value_t * p_attr_val = &attr_val; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_value_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_val); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_value_set(conn_handle, handle, p_attr_val); - - err_code = ble_gatts_value_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_val); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_value_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t handle; - uint8_t val[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_gatts_value_t attr_value; - ble_gatts_value_t * p_attr_value = &attr_value; - - attr_value.p_value = val; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_value_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_value); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_value_get(conn_handle, handle, p_attr_value); - - err_code = ble_gatts_value_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_value); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_hvx(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint8_t data[BLE_GATTS_VAR_ATTR_LEN_MAX]; - uint8_t * p_data = data; - uint16_t len = sizeof data; - uint16_t * p_len = &len; - - ble_gatts_hvx_params_t hvx_params; - ble_gatts_hvx_params_t * p_hvx_params = &hvx_params; - - hvx_params.p_len = p_len; - hvx_params.p_data = p_data; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_hvx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_hvx_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - sd_err_code = sd_ble_gatts_hvx(conn_handle, p_hvx_params); - - p_len = (p_hvx_params) ? p_hvx_params->p_len : NULL; - err_code = ble_gatts_hvx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_service_changed(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - uint16_t start_handle; - uint16_t end_handle; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_service_changed_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &start_handle, - &end_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_service_changed(conn_handle, start_handle, end_handle); - - err_code = ble_gatts_service_changed_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_rw_authorize_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - - uint8_t data[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_gatts_rw_authorize_reply_params_t auth_params; - ble_gatts_rw_authorize_reply_params_t * p_auth_params = &auth_params; - - auth_params.params.read.p_data = data; - auth_params.params.read.len = sizeof (data); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_rw_authorize_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, - &p_auth_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_rw_authorize_reply(conn_handle, p_auth_params); - - err_code = ble_gatts_rw_authorize_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_sys_attr_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - - uint8_t sys_attr[BLE_GATTS_VAR_ATTR_LEN_MAX]; - - uint8_t * p_sys_attr = sys_attr; - uint16_t sys_attr_len = sizeof (sys_attr); - - uint32_t flags; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_sys_attr_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sys_attr, - &sys_attr_len, &flags); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_sys_attr_set(conn_handle, p_sys_attr, sys_attr_len, flags); - - err_code = ble_gatts_sys_attr_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - - uint8_t sys_attr[BLE_GATTS_VAR_ATTR_LEN_MAX]; - - uint8_t * p_sys_attr = sys_attr; - uint16_t sys_attr_len = sizeof (sys_attr); - uint16_t * p_sys_attr_len = &sys_attr_len; - - uint32_t flags; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gatts_sys_attr_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sys_attr, - &p_sys_attr_len, &flags); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gatts_sys_attr_get(conn_handle, p_sys_attr, p_sys_attr_len, flags); - - err_code = ble_gatts_sys_attr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sys_attr, - p_sys_attr_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gatts.h b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gatts.h deleted file mode 100644 index d61865a..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gatts.h +++ /dev/null @@ -1,216 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_BLE_GATTS_H -#define _CONN_MW_BLE_GATTS_H - -#include - -/**@brief Handles @ref sd_ble_gatts_service_add command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_service_add (uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gatts_characteristic_add command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_characteristic_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_include_add command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_include_add (uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_descriptor_add command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_descriptor_add(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_value_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_value_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_value_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_value_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_hvx command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_hvx(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_service_changed command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_service_changed(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_rw_authorize_reply command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_rw_authorize_reply(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_sys_attr_set command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_sys_attr_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref conn_mw_ble_gatts_sys_attr_get command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); -#endif //_CONN_MW_BLE_GATTS_H - diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_l2cap.c b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_l2cap.c deleted file mode 100644 index a3134b0..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_l2cap.c +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "ble_l2cap_conn.h" -#include "conn_mw_ble_l2cap.h" -#include "ble_serialization.h" - -uint32_t conn_mw_ble_l2cap_cid_register(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t cid; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_l2cap_cid_register_req_dec(p_rx_buf, rx_buf_len, &cid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_l2cap_cid_register(cid); - - err_code = ble_l2cap_cid_register_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_l2cap_cid_unregister(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t cid; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_l2cap_cid_unregister_req_dec(p_rx_buf, rx_buf_len, &cid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_l2cap_cid_unregister(cid); - - err_code = ble_l2cap_cid_unregister_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t conn_mw_ble_l2cap_tx(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint16_t conn_handle; - ble_l2cap_header_t l2cap_header; - ble_l2cap_header_t * p_l2cap_header = &l2cap_header; - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - uint8_t const * p_data = NULL; - - err_code = ble_l2cap_tx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_l2cap_header, &p_data); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_l2cap_tx(conn_handle, p_l2cap_header, p_data); - - err_code = ble_l2cap_tx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_l2cap.h b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_l2cap.h deleted file mode 100644 index dd6ac2e..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_l2cap.h +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 _CONN_MW_BLE_L2CAP_H_ -#define _CONN_MW_BLE_L2CAP_H_ - -#include - -/**@brief Handles @ref sd_ble_l2cap_cid_register command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_l2cap_cid_register(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_l2cap_cid_unregister command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_l2cap_cid_unregister(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_l2cap_tx command and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_l2cap_tx(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -#endif diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_items.c b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_items.c deleted file mode 100644 index 989afba..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_items.c +++ /dev/null @@ -1,76 +0,0 @@ -#include "conn_mw_nrf_soc.h" -#include "conn_mw_ble.h" -#include "conn_mw_ble_l2cap.h" -#include "conn_mw_ble_gap.h" -#include "conn_mw_ble_gatts.h" -#include "conn_mw_ble_gattc.h" - -/**@brief Connectivity middleware handlers table. */ -static const conn_mw_item_t conn_mw_item[] = { - //Functions from nrf_soc.h - {SD_POWER_SYSTEM_OFF, conn_mw_power_system_off}, - {SD_TEMP_GET, conn_mw_temp_get}, - //Functions from ble.h - {SD_BLE_TX_BUFFER_COUNT_GET, conn_mw_ble_tx_buffer_count_get}, - {SD_BLE_UUID_VS_ADD, conn_mw_ble_uuid_vs_add}, - {SD_BLE_UUID_DECODE, conn_mw_ble_uuid_decode}, - {SD_BLE_UUID_ENCODE, conn_mw_ble_uuid_encode}, - {SD_BLE_VERSION_GET, conn_mw_ble_version_get}, - {SD_BLE_OPT_GET, conn_mw_ble_opt_get}, - {SD_BLE_OPT_SET, conn_mw_ble_opt_set}, - {SD_BLE_ENABLE, conn_mw_ble_enable}, - //Functions from ble_l2cap.h - {SD_BLE_L2CAP_CID_REGISTER, conn_mw_ble_l2cap_cid_register}, - {SD_BLE_L2CAP_CID_UNREGISTER, conn_mw_ble_l2cap_cid_unregister}, - {SD_BLE_L2CAP_TX, conn_mw_ble_l2cap_tx}, - //Functions from ble_gap.h - {SD_BLE_GAP_SCAN_STOP, conn_mw_ble_gap_scan_stop}, - {SD_BLE_GAP_ADDRESS_SET, conn_mw_ble_gap_address_set}, - {SD_BLE_GAP_CONNECT, conn_mw_ble_gap_connect}, - {SD_BLE_GAP_CONNECT_CANCEL, conn_mw_ble_gap_connect_cancel}, - {SD_BLE_GAP_SCAN_START, conn_mw_ble_gap_scan_start}, - {SD_BLE_GAP_SEC_INFO_REPLY, conn_mw_ble_gap_sec_info_reply}, - {SD_BLE_GAP_ENCRYPT, conn_mw_ble_gap_encrypt}, - {SD_BLE_GAP_ADDRESS_GET, conn_mw_ble_gap_address_get}, - {SD_BLE_GAP_ADV_DATA_SET, conn_mw_ble_gap_adv_data_set}, - {SD_BLE_GAP_ADV_START, conn_mw_ble_gap_adv_start}, - {SD_BLE_GAP_ADV_STOP, conn_mw_ble_gap_adv_stop}, - {SD_BLE_GAP_CONN_PARAM_UPDATE, conn_mw_ble_gap_conn_param_update}, - {SD_BLE_GAP_DISCONNECT, conn_mw_ble_gap_disconnect}, - {SD_BLE_GAP_TX_POWER_SET, conn_mw_ble_gap_tx_power_set}, - {SD_BLE_GAP_APPEARANCE_SET, conn_mw_ble_gap_appearance_set}, - {SD_BLE_GAP_APPEARANCE_GET, conn_mw_ble_gap_appearance_get}, - {SD_BLE_GAP_PPCP_SET, conn_mw_ble_gap_ppcp_set}, - {SD_BLE_GAP_PPCP_GET, conn_mw_ble_gap_ppcp_get}, - {SD_BLE_GAP_DEVICE_NAME_SET, conn_mw_ble_gap_device_name_set}, - {SD_BLE_GAP_DEVICE_NAME_GET, conn_mw_ble_gap_device_name_get}, - {SD_BLE_GAP_AUTHENTICATE, conn_mw_ble_gap_authenticate}, - {SD_BLE_GAP_SEC_PARAMS_REPLY, conn_mw_ble_gap_sec_params_reply}, - {SD_BLE_GAP_AUTH_KEY_REPLY, conn_mw_ble_gap_auth_key_reply}, - {SD_BLE_GAP_SEC_INFO_REPLY, conn_mw_ble_gap_sec_info_reply}, - {SD_BLE_GAP_CONN_SEC_GET, conn_mw_ble_gap_conn_sec_get}, - {SD_BLE_GAP_RSSI_START, conn_mw_ble_gap_rssi_start}, - {SD_BLE_GAP_RSSI_STOP, conn_mw_ble_gap_rssi_stop}, - //Functions from ble_gattc.h - {SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, conn_mw_ble_gattc_primary_services_discover}, - {SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, conn_mw_ble_gattc_relationships_discover}, - {SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, conn_mw_ble_gattc_characteristics_discover}, - {SD_BLE_GATTC_DESCRIPTORS_DISCOVER, conn_mw_ble_gattc_descriptors_discover}, - {SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, conn_mw_ble_gattc_char_value_by_uuid_read}, - {SD_BLE_GATTC_READ, conn_mw_ble_gattc_read}, - {SD_BLE_GATTC_CHAR_VALUES_READ, conn_mw_ble_gattc_char_values_read}, - {SD_BLE_GATTC_WRITE, conn_mw_ble_gattc_write}, - {SD_BLE_GATTC_HV_CONFIRM, conn_mw_ble_gattc_hv_confirm}, - //Functions from ble_gatts.h - {SD_BLE_GATTS_SERVICE_ADD, conn_mw_ble_gatts_service_add}, - {SD_BLE_GATTS_INCLUDE_ADD, conn_mw_ble_gatts_include_add}, - {SD_BLE_GATTS_CHARACTERISTIC_ADD, conn_mw_ble_gatts_characteristic_add}, - {SD_BLE_GATTS_DESCRIPTOR_ADD, conn_mw_ble_gatts_descriptor_add}, - {SD_BLE_GATTS_VALUE_SET, conn_mw_ble_gatts_value_set}, - {SD_BLE_GATTS_VALUE_GET, conn_mw_ble_gatts_value_get}, - {SD_BLE_GATTS_HVX, conn_mw_ble_gatts_hvx}, - {SD_BLE_GATTS_SERVICE_CHANGED, conn_mw_ble_gatts_service_changed}, - {SD_BLE_GATTS_RW_AUTHORIZE_REPLY, conn_mw_ble_gatts_rw_authorize_reply}, - {SD_BLE_GATTS_SYS_ATTR_SET, conn_mw_ble_gatts_sys_attr_set}, - {SD_BLE_GATTS_SYS_ATTR_GET, conn_mw_ble_gatts_sys_attr_get}, -}; diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_nrf_soc.c b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_nrf_soc.c deleted file mode 100644 index c9a7509..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_nrf_soc.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ -#include "nrf_soc_conn.h" -#include "conn_mw_nrf_soc.h" -#include "ble_serialization.h" - -uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - - err_code = power_system_off_req_dec(p_rx_buf, rx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = sd_power_system_off(); - /* There should be no return from sd_power_system_off() */ - - return err_code; -} - -uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - int32_t temperature; - int32_t * p_temperature = &temperature; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = temp_get_req_dec(p_rx_buf, rx_buf_len, &p_temperature); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_temp_get(p_temperature); - - err_code = temp_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_temperature); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_nrf_soc.h b/components/serialization/connectivity/codecs/s130/middleware/conn_mw_nrf_soc.h deleted file mode 100644 index ba4a973..0000000 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_nrf_soc.h +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 CONN_MW_NRF_SOC_H__ -#define CONN_MW_NRF_SOC_H__ - -#include - -/**@brief Handles @ref sd_power_system_off command request. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. - */ -uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_temp_get command request and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. - */ -uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -#endif diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_enable.c b/components/serialization/connectivity/codecs/s130/serializers/ble_enable.c deleted file mode 100644 index da81437..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_enable.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_enable_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_enable_params_t * * const pp_ble_enable_params) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_ble_enable_params); - SER_ASSERT_NOT_NULL(*pp_ble_enable_params); - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_ble_enable_params, ble_enable_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_enable_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - return op_status_enc(SD_BLE_ENABLE, return_code, p_buf, p_buf_len, &index); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_event.c b/components/serialization/connectivity/codecs/s130/serializers/ble_event.c deleted file mode 100644 index 058cfa4..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_event.c +++ /dev/null @@ -1,184 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include "ble_evt_conn.h" -#include "ble_gap_evt_conn.h" -#include "ble_gattc_evt_conn.h" -#include "ble_gatts_evt_conn.h" -#include "ble_l2cap_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_event_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t ret_val = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_NOT_NULL(p_event); - - switch (p_event->header.evt_id) - { - case BLE_EVT_TX_COMPLETE: - ret_val = ble_evt_tx_complete_enc(p_event, event_len, p_buf, p_buf_len); - break; - case BLE_EVT_USER_MEM_RELEASE: - ret_val = ble_evt_user_mem_release_enc(p_event, event_len, p_buf, p_buf_len); - break; - case BLE_EVT_USER_MEM_REQUEST: - ret_val = ble_evt_user_mem_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE: - ret_val = ble_gap_evt_conn_param_update_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: - ret_val = ble_gap_evt_conn_param_update_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_SEC_PARAMS_REQUEST: - ret_val = ble_gap_evt_sec_params_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_SEC_INFO_REQUEST: - ret_val = ble_gap_evt_sec_info_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_AUTH_STATUS: - ret_val = ble_gap_evt_auth_status_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_PASSKEY_DISPLAY: - ret_val = ble_gap_evt_passkey_display_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_AUTH_KEY_REQUEST: - ret_val = ble_gap_evt_auth_key_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_CONN_SEC_UPDATE: - ret_val = ble_gap_evt_conn_sec_update_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_RSSI_CHANGED: - ret_val = ble_gap_evt_rssi_changed_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_TIMEOUT: - ret_val = ble_gap_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_DISCONNECTED: - ret_val = ble_gap_evt_disconnected_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_CONNECTED: - ret_val = ble_gap_evt_connected_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_SEC_REQUEST: - ret_val = ble_gap_evt_sec_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_CHAR_DISC_RSP: - ret_val = ble_gattc_evt_char_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_DESC_DISC_RSP: - ret_val = ble_gattc_evt_desc_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP: - ret_val = ble_gattc_evt_char_val_by_uuid_read_rsp_enc(p_event, - event_len, - p_buf, - p_buf_len); - break; - - case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: - ret_val = ble_gattc_evt_prim_srvc_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_HVX: - ret_val = ble_gattc_evt_hvx_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_READ_RSP: - ret_val = ble_gattc_evt_read_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_TIMEOUT: - ret_val = ble_gattc_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_WRITE_RSP: - ret_val = ble_gattc_evt_write_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_REL_DISC_RSP: - ret_val = ble_gattc_evt_rel_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTC_EVT_CHAR_VALS_READ_RSP: - ret_val = ble_gattc_evt_char_vals_read_rsp_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_HVC: - ret_val = ble_gatts_evt_hvc_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_TIMEOUT: - ret_val = ble_gatts_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_SC_CONFIRM: - ret_val = ble_gatts_evt_sc_confirm_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_WRITE: - ret_val = ble_gatts_evt_write_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: - ret_val = ble_gatts_evt_rw_authorize_request_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GATTS_EVT_SYS_ATTR_MISSING: - ret_val = ble_gatts_evt_sys_attr_missing_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_L2CAP_EVT_RX: - ret_val = ble_l2cap_evt_rx_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_ADV_REPORT: - ret_val = ble_gap_evt_adv_report_enc(p_event, event_len, p_buf, p_buf_len); - break; - - case BLE_GAP_EVT_SCAN_REQ_REPORT: - ret_val = ble_gap_evt_scan_req_report_enc(p_event, event_len, p_buf, p_buf_len); - break; - - default: - ret_val = NRF_ERROR_NOT_SUPPORTED; - *p_buf_len = 0; - break; - } - - return ret_val; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_evt_tx_complete.c b/components/serialization/connectivity/codecs/s130/serializers/ble_evt_tx_complete.c deleted file mode 100644 index f10dbf9..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_evt_tx_complete.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_EVT_TX_COMPLETE, &(p_buf[index])); - index += uint16_encode(p_event->evt.common_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.common_evt.params.tx_complete.count; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_evt_user_mem_release.c b/components/serialization/connectivity/codecs/s130/serializers/ble_evt_user_mem_release.c deleted file mode 100644 index 5f4f3df..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_evt_user_mem_release.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "conn_ble_user_mem.h" - -uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - const uint16_t evt_header = BLE_EVT_USER_MEM_RELEASE; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.common_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.common_evt.params.user_mem_release.type), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&(p_event->evt.common_evt.params.user_mem_release.mem_block.len), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - p_buf[index++] = p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem ? SER_FIELD_PRESENT : SER_FIELD_NOT_PRESENT; - - // Now user memory context can be released - err_code = conn_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_evt_user_mem_request.c b/components/serialization/connectivity/codecs/s130/serializers/ble_evt_user_mem_request.c deleted file mode 100644 index 8faa98b..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_evt_user_mem_request.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - const uint16_t evt_header = BLE_EVT_USER_MEM_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.common_evt.params.user_mem_request.type), p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_address_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_address_get.c deleted file mode 100644 index f0dc9a5..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_address_get.c +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_address_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_addr_t * * const pp_address) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_address); - SER_ASSERT_LENGTH_LEQ(1 + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_ADDRESS_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_address = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_address_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_addr_t const * const p_address) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADDRESS_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - *p_buf_len = index; - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_address); - - SER_ASSERT_LENGTH_LEQ(index + sizeof (ble_gap_addr_t), total_len); - p_buf[index++] = p_address->addr_type; - memcpy(&p_buf[index], &p_address->addr[0], BLE_GAP_ADDR_LEN); - index += BLE_GAP_ADDR_LEN; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_address_set.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_address_set.c deleted file mode 100644 index 8727a01..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_address_set.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_address_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * p_addr_cycle_mode, - ble_gap_addr_t * * const pp_addr) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_addr_cycle_mode); - SER_ASSERT_NOT_NULL(pp_addr); - SER_ASSERT_NOT_NULL(*pp_addr); - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_addr_cycle_mode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_addr, ble_gap_addr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gap_address_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - return op_status_enc(SD_BLE_GAP_ADDRESS_SET, return_code, p_buf, p_buf_len, &index); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_data_set.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_data_set.c deleted file mode 100644 index ab83ce0..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_data_set.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * * const pp_data, - uint8_t * p_dlen, - uint8_t * * const pp_sr_data, - uint8_t * p_srdlen) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_dlen); - SER_ASSERT_NOT_NULL(p_srdlen); - - uint32_t index = SER_CMD_DATA_POS; - - uint32_t error_code = len8data_dec(p_buf, packet_len, &index, pp_data, p_dlen); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - error_code = len8data_dec(p_buf, packet_len, &index, pp_sr_data, p_srdlen); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADV_DATA_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_start.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_start.c deleted file mode 100644 index ad5b071..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_start.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_adv_params_t * * const pp_adv_params) -{ - uint32_t index = 0, i = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_adv_params); - SER_ASSERT_NOT_NULL(*pp_adv_params); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_peer_addr); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_addrs); - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_irks); - - for (i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++) - { - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_addrs[i]); - } - - for (i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++) - { - SER_ASSERT_NOT_NULL((*pp_adv_params)->p_whitelist->pp_irks[i]); - } - - /* Packet with variable length. */ - /* For now check: opcode + indicator showing if ble_gap_adv_params_t struct is present. */ - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GAP_ADV_START, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - err_code = uint8_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->type)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **) &((*pp_adv_params)->p_peer_addr), ble_gap_addr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->fp)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **) &((*pp_adv_params)->p_whitelist), ble_gap_whitelist_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->interval)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->timeout)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_adv_ch_mask_t_dec(p_buf, packet_len, &index, &((*pp_adv_params)->channel_mask)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - *pp_adv_params = NULL; - } - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADV_START, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_stop.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_stop.c deleted file mode 100644 index b3569a2..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_adv_stop.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ADV_STOP, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_appearance_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_appearance_get.c deleted file mode 100644 index cc828b5..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_appearance_get.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * * const pp_appearance) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_appearance); - SER_ASSERT_NOT_NULL(*pp_appearance); - SER_ASSERT_LENGTH_EQ(2, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_APPEARANCE_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_appearance = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_appearance) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_APPEARANCE_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_appearance); - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + sizeof (uint16_t), total_len); - index += uint16_encode(*p_appearance, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_appearance_set.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_appearance_set.c deleted file mode 100644 index f393fdb..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_appearance_set.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * const p_appearance) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_appearance); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_LENGTH_EQ(3, buf_len); - SER_ASSERT(p_buf[index++] == SD_BLE_GAP_APPEARANCE_SET, NRF_ERROR_INVALID_PARAM); - - uint32_t err_code = uint16_t_dec(p_buf, buf_len, &index, p_appearance); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_APPEARANCE_SET, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_auth_key_reply.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_auth_key_reply.c deleted file mode 100644 index 988c711..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_auth_key_reply.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - uint8_t * p_key_type, - uint8_t * * const pp_key) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_key_type); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - uint8_t key_len; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - SER_ASSERT_LENGTH_LEQ(1, packet_len - index); - uint8_dec(p_buf, packet_len, &index, p_key_type); - - switch (*p_key_type) - { - case BLE_GAP_AUTH_KEY_TYPE_NONE: - key_len = 0; - break; - - case BLE_GAP_AUTH_KEY_TYPE_PASSKEY: - key_len = 6; - break; - - case BLE_GAP_AUTH_KEY_TYPE_OOB: - key_len = 16; - break; - - default: - return NRF_ERROR_INVALID_PARAM; - } - - err_code = buf_dec(p_buf, packet_len, &index, pp_key, key_len, key_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return err_code; -} - -uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_AUTH_KEY_REPLY, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_authenticate.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_authenticate.c deleted file mode 100644 index 4d7053e..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_authenticate.c +++ /dev/null @@ -1,57 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "nordic_common.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - - -uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_gap_sec_params_t * * const pp_sec_params) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_sec_params); - SER_ASSERT_NOT_NULL(*pp_sec_params); - - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_sec_params, - ble_gap_sec_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_AUTHENTICATE, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn_param_update.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn_param_update.c deleted file mode 100644 index 38ac3fd..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn_param_update.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_conn_params); - SER_ASSERT_NOT_NULL(*pp_conn_params); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 3, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_CONN_PARAM_UPDATE, NRF_ERROR_INVALID_PARAM); - - index++; - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - if (p_buf[index] == SER_FIELD_PRESENT) - { - index++; - SER_ASSERT_LENGTH_LEQ(index + 8, packet_len); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->min_conn_interval)); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->max_conn_interval)); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->slave_latency)); - uint16_dec(p_buf, packet_len, &index, &((*pp_conn_params)->conn_sup_timeout)); - } - else if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - index++; - *pp_conn_params = NULL; - } - else - { - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONN_PARAM_UPDATE, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn_sec_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn_sec_get.c deleted file mode 100644 index d3631ee..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn_sec_get.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" - - -uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - ble_gap_conn_sec_t * * const pp_conn_sec) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - - uint32_t index = 0; - uint8_t opcode; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, packet_len - index); - uint8_dec(p_buf, packet_len, &index, &opcode); - - SER_ASSERT(opcode == SD_BLE_GAP_CONN_SEC_GET, NRF_ERROR_INVALID_PARAM); - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_conn_sec, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code, - ble_gap_conn_sec_t * const p_conn_sec, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t buflen = *p_buf_len; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONN_SEC_GET, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = cond_field_enc(p_conn_sec, p_buf, buflen, &index, ble_gap_conn_sec_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_connect.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_connect.c deleted file mode 100644 index e7b6135..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_connect.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_addr_t * * const pp_addr, - ble_gap_scan_params_t * * const pp_scan_params, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_addr); - SER_ASSERT_NOT_NULL(*pp_addr); - SER_ASSERT_NOT_NULL(pp_scan_params); - SER_ASSERT_NOT_NULL(*pp_scan_params); - SER_ASSERT_NOT_NULL(pp_conn_params); - SER_ASSERT_NOT_NULL(*pp_conn_params); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_addr, ble_gap_addr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_scan_params, ble_gap_scan_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_conn_params, ble_gap_conn_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_connect_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONNECT, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_connect_cancel.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_connect_cancel.c deleted file mode 100644 index 4551fcd..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_connect_cancel.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_CONNECT_CANCEL, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_device_name_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_device_name_get.c deleted file mode 100644 index e169d02..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_device_name_get.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - -uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * * pp_name, - uint16_t * * pp_name_len) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(pp_name_len); - SER_ASSERT_NOT_NULL(*pp_name_len); - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - - index++; - - if (p_buf[index] != SER_FIELD_PRESENT && p_buf[index] != SER_FIELD_NOT_PRESENT) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - err_code = uint16_t_dec(p_buf, buf_len, &index, *pp_name_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - *pp_name_len = NULL; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, buf_len); - - if (p_buf[index] != SER_FIELD_PRESENT && p_buf[index] != SER_FIELD_NOT_PRESENT) - { - return NRF_ERROR_INVALID_PARAM; - } - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - *pp_name = NULL; - } - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code, - uint8_t const * const p_dev_name, - uint16_t dev_name_len, - uint8_t * const p_buf, - uint32_t * const p_buflen) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buflen); - - uint32_t buflen = *p_buflen; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_DEVICE_NAME_GET, return_code, - p_buf, p_buflen); - uint32_t index = *p_buflen; - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = len16data_enc(p_dev_name, dev_name_len, p_buf, buflen, &index); - - *p_buflen = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_device_name_set.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_device_name_set.c deleted file mode 100644 index 84c49ff..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_device_name_set.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_sec_mode_t * * const pp_write_perm, - uint8_t * * const pp_dev_name, - uint16_t * const p_dev_name_len) -{ - SER_ASSERT_NOT_NULL(p_buf); //check if *p_buf is allocated - SER_ASSERT_NOT_NULL(pp_write_perm); //check if *pp_write_perm exist - SER_ASSERT_NOT_NULL(pp_dev_name); //check if *pp_dev_name exist - SER_ASSERT_NOT_NULL(p_dev_name_len); //check if *p_dev_name_len exist - - uint32_t index = SER_CMD_DATA_POS; - uint32_t status_code; - - SER_ASSERT_LENGTH_LEQ(4, packet_len - index); //make sure that payload is at least 4 bytes - - //decode optional write permissions field - status_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_write_perm, - ble_gap_conn_sec_mode_dec); - SER_ASSERT(status_code == NRF_SUCCESS, status_code); - - //decode optional device name field - status_code = len16data_dec(p_buf, packet_len, &index, pp_dev_name, p_dev_name_len); - SER_ASSERT(status_code == NRF_SUCCESS, status_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return status_code; -} - - -uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_DEVICE_NAME_SET, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_disconnect.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_disconnect.c deleted file mode 100644 index e69a0d0..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_disconnect.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * const p_hci_status) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_hci_status); - - uint8_t opcode; - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint8_t_dec(p_buf, packet_len, &index, &opcode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT(opcode == SD_BLE_GAP_DISCONNECT, NRF_ERROR_INVALID_PARAM); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_hci_status); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_DISCONNECT, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_encrypt.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_encrypt.c deleted file mode 100644 index 3cf0262..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_encrypt.c +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gap_master_id_t ** const pp_master_id, - ble_gap_enc_info_t ** const pp_enc_info) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_enc_info); - SER_ASSERT_NOT_NULL(pp_master_id); - SER_ASSERT_NOT_NULL(*pp_enc_info); - SER_ASSERT_NOT_NULL(*pp_master_id); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void **)pp_master_id, - ble_gap_master_id_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void **)pp_enc_info, - ble_gap_enc_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - -uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_ENCRYPT, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_adv_report.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_adv_report.c deleted file mode 100644 index fa6cd3f..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_adv_report.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint8_t byte; - const uint16_t evt_header = BLE_GAP_EVT_ADV_REPORT; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc((void *)&(p_event->evt.gap_evt.params.adv_report.peer_addr), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.gap_evt.params.adv_report.rssi), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - byte = (p_event->evt.gap_evt.params.adv_report.scan_rsp) | - ((p_event->evt.gap_evt.params.adv_report.type) << 0x01) | - ((p_event->evt.gap_evt.params.adv_report.dlen) << 0x03); - - err_code = uint8_t_enc((void *)&(byte), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_vector_enc(p_event->evt.gap_evt.params.adv_report.data, (uint16_t)p_event->evt.gap_evt.params.adv_report.dlen, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_auth_key_request.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_auth_key_request.c deleted file mode 100644 index 7805879..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_auth_key_request.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GAP_EVT_AUTH_KEY_REQUEST; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc(&p_event->evt.gap_evt.params.auth_key_request.key_type, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_auth_status.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_auth_status.c deleted file mode 100644 index 59a751a..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_auth_status.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gap_evt_conn.h" -#include "conn_ble_gap_sec_keys.h" - -extern ser_ble_gap_conn_keyset_t m_conn_keys_table[]; - -uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint16_t evt_header = BLE_GAP_EVT_AUTH_STATUS; - uint32_t total_len; - uint32_t err_code = NRF_SUCCESS; - uint32_t conn_index; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - total_len = *p_buf_len; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_auth_status_t_enc(&(p_event->evt.gap_evt.params.auth_status), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - // keyset is an extension of standard event data - used to synchronize keys at application - err_code = conn_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_sec_keyset_t_enc(&(m_conn_keys_table[conn_index].keyset), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = conn_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - return err_code; -} - diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_param_update.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_param_update.c deleted file mode 100644 index a9565dc..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_param_update.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT(p_event->header.evt_id == BLE_GAP_EVT_CONN_PARAM_UPDATE, NRF_ERROR_INVALID_PARAM); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_conn_param_update_t_enc(&p_event->evt.gap_evt.params.conn_param_update, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_param_update_request.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_param_update_request.c deleted file mode 100644 index 5843ff3..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_param_update_request.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT(p_event->header.evt_id == BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, NRF_ERROR_INVALID_PARAM); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_conn_param_update_request_t_enc(&p_event->evt.gap_evt.params.conn_param_update_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_sec_update.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_sec_update.c deleted file mode 100644 index 8293866..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn_sec_update.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_CONN_SEC_UPDATE; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_conn_sec_update_t_enc( - (void *)&p_event->evt.gap_evt.params.conn_sec_update, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_connected.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_connected.c deleted file mode 100644 index 16cea4f..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_connected.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GAP_EVT_CONNECTED; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_connected_t_enc((void *)&p_event->evt.gap_evt.params.connected, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_disconnected.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_disconnected.c deleted file mode 100644 index a067462..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_disconnected.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble.h" -#include "ble_gap_struct_serialization.h" -#include "ble_gap_evt_conn.h" - -uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code; - uint16_t evt_header = BLE_GAP_EVT_DISCONNECTED; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&(p_event->evt.gap_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_disconnected_t_enc((void *)&(p_event->evt.gap_evt.params.disconnected), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_passkey_display.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_passkey_display.c deleted file mode 100644 index 1fcaab5..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_passkey_display.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble.h" -#include "ble_gap_evt_conn.h" - -#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey) - - -uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + PASSKEY_LEN, *p_buf_len); - index += uint16_encode(BLE_GAP_EVT_PASSKEY_DISPLAY, &(p_buf[index])); - index += uint16_encode(p_event->evt.gap_evt.conn_handle, &(p_buf[index])); - - memcpy(&p_buf[index], p_event->evt.gap_evt.params.passkey_display.passkey, PASSKEY_LEN); - index += PASSKEY_LEN; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_rssi_changed.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_rssi_changed.c deleted file mode 100644 index 6ee6a94..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_rssi_changed.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GAP_EVT_RSSI_CHANGED, &(p_buf[index])); - index += uint16_encode(p_event->evt.gap_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gap_evt.params.rssi_changed.rssi; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_scan_req_report.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_scan_req_report.c deleted file mode 100644 index 9707495..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_scan_req_report.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" - - -uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_SCAN_REQ_REPORT; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_addr_enc((void *)&(p_event->evt.gap_evt.params.scan_req_report.peer_addr), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_enc((void *)&(p_event->evt.gap_evt.params.scan_req_report.rssi), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_info_request.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_info_request.c deleted file mode 100644 index e3b7949..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_info_request.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_SEC_INFO_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_info_request_t_enc( - (void *)&p_event->evt.gap_evt.params.sec_info_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_params_request.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_params_request.c deleted file mode 100644 index f2fdf59..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_params_request.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - const uint16_t evt_header = BLE_GAP_EVT_SEC_PARAMS_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_params_request_t_enc( - (void *)&p_event->evt.gap_evt.params.sec_params_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_request.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_request.c deleted file mode 100644 index 6a744b0..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_sec_request.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble.h" -#include "ble_gap_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GAP_EVT_SEC_REQUEST; - - err_code = uint16_t_enc((void *)&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc((void *)&p_event->evt.gap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gap_evt_sec_request_t_enc((void *)&p_event->evt.gap_evt.params.sec_request, - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_timeout.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_timeout.c deleted file mode 100644 index 7894cdc..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_timeout.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble.h" -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_evt_conn.h" - - -uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE + 3, *p_buf_len); - index += uint16_encode(BLE_GAP_EVT_TIMEOUT, &(p_buf[index])); - index += uint16_encode(p_event->evt.gap_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gap_evt.params.timeout.src; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_ppcp_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_ppcp_get.c deleted file mode 100644 index 38663fc..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_ppcp_get.c +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_conn_params); - SER_ASSERT_NOT_NULL(*pp_conn_params); - SER_ASSERT_LENGTH_LEQ(2, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GAP_PPCP_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_conn_params = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_conn_params_t const * const p_conn_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_PPCP_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_conn_params); - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 8, total_len); - - index += uint16_encode(p_conn_params->min_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->max_conn_interval, &p_buf[index]); - index += uint16_encode(p_conn_params->slave_latency, &p_buf[index]); - index += uint16_encode(p_conn_params->conn_sup_timeout, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_ppcp_set.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_ppcp_set.c deleted file mode 100644 index e09aaf2..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_ppcp_set.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "nordic_common.h" -#include "app_util.h" - - -uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_conn_params_t * * const pp_conn_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_conn_params); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GAP_PPCP_SET, NRF_ERROR_INVALID_PARAM); - - index++; - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_conn_params = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 8, packet_len); - SER_ASSERT_NOT_NULL(*pp_conn_params); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->min_conn_interval); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->max_conn_interval); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->slave_latency); - uint16_dec(p_buf, packet_len, &index, &(*pp_conn_params)->conn_sup_timeout); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_PPCP_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_get.c deleted file mode 100644 index 306caa2..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_get.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - int8_t * * const pp_rssi) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_rssi); - SER_ASSERT_NOT_NULL(*pp_rssi); - SER_ASSERT_LENGTH_LEQ(3, packet_len); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **) pp_rssi, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int8_t rssi) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_RSSI_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - uint32_t index = *p_buf_len; - - err_code = uint8_t_enc((uint8_t *) &rssi, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_start.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_start.c deleted file mode 100644 index cd6f516..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_start.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_conn_handle, - uint8_t * p_threshold_dbm, - uint8_t * p_skip_count) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_threshold_dbm); - SER_ASSERT_NOT_NULL(p_skip_count); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, &index, p_threshold_dbm); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, buf_len, &index, p_skip_count); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_RSSI_START, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_stop.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_stop.c deleted file mode 100644 index d068f3d..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_rssi_stop.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_conn_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_RSSI_STOP, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_scan_start.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_scan_start.c deleted file mode 100644 index b561d3c..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_scan_start.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - ble_gap_scan_params_t * * const pp_scan_params) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_scan_params); - SER_ASSERT_NOT_NULL(*pp_scan_params); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_scan_params, ble_gap_scan_params_t_dec); - - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SCAN_START, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_scan_stop.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_scan_stop.c deleted file mode 100644 index a390f17..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_scan_stop.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SCAN_STOP, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_sec_info_reply.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_sec_info_reply.c deleted file mode 100644 index 3e85479..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_sec_info_reply.c +++ /dev/null @@ -1,72 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - ble_gap_enc_info_t * * const pp_enc_info, - ble_gap_irk_t * * const pp_id_info, - ble_gap_sign_info_t * * const pp_sign_info) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_enc_info); - SER_ASSERT_NOT_NULL(pp_id_info); - SER_ASSERT_NOT_NULL(pp_sign_info); - SER_ASSERT_NOT_NULL(*pp_enc_info); - SER_ASSERT_NOT_NULL(*pp_id_info); - SER_ASSERT_NOT_NULL(*pp_sign_info); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_enc_info, - ble_gap_enc_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_id_info, - ble_gap_irk_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_sign_info, - ble_gap_sign_info_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return err_code; -} - -uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SEC_INFO_REPLY, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_sec_params_reply.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_sec_params_reply.c deleted file mode 100644 index 0c295be..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_sec_params_reply.c +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - uint8_t * p_sec_status, - ble_gap_sec_params_t * * const pp_sec_params, - ble_gap_sec_keyset_t * * const pp_sec_keyset) -{ - uint32_t index = SER_CMD_HEADER_SIZE; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_sec_status); - SER_ASSERT_NOT_NULL(pp_sec_params); - SER_ASSERT_NOT_NULL(*pp_sec_params); - SER_ASSERT_NOT_NULL(pp_sec_keyset); - SER_ASSERT_NOT_NULL(*pp_sec_keyset); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_sec_status); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *) pp_sec_params, ble_gap_sec_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *) pp_sec_keyset, ble_gap_sec_keyset_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -//opcode: 0x7F -uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_sec_keyset_t * const p_sec_keyset) -{ - uint32_t index = 0; - uint32_t buf_len = * p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_SEC_PARAMS_REPLY, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_sec_keyset); - index = *p_buf_len; - - err_code = cond_field_enc(p_sec_keyset, p_buf, buf_len, &index, ble_gap_sec_keyset_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_tx_power_set.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gap_tx_power_set.c deleted file mode 100644 index 6af4f31..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_tx_power_set.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gap_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - int8_t * p_tx_power) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_tx_power); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint8_t_dec(p_buf, packet_len, &index, p_tx_power); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GAP_TX_POWER_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_char_value_by_uuid_read.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_char_value_by_uuid_read.c deleted file mode 100644 index 6fbc19d..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_char_value_by_uuid_read.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "cond_field_serialization.h" -#include "ble_types.h" -#include - -uint32_t ble_gattc_char_value_by_uuid_read_req_dec( - uint8_t const * const p_buf, - uint16_t buf_len, - uint16_t * const p_conn_handle, - ble_uuid_t * * const pp_uuid, - ble_gattc_handle_range_t * * const - pp_handle_range) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2, buf_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, NRF_ERROR_INVALID_DATA); - index++; - - uint16_dec(p_buf, buf_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_handle_range, - ble_gattc_handle_range_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, return_code, - p_buf, p_buf_len); -} - diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_char_values_read.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_char_values_read.c deleted file mode 100644 index 39c6808..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_char_values_read.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * * const pp_handles, - uint16_t * const p_handle_count) -{ - SER_ASSERT_NOT_NULL(p_buf); //check if *p_buf is allocated - SER_ASSERT_NOT_NULL(p_conn_handle); //check if *p_conn_handle exist - SER_ASSERT_NOT_NULL(pp_handles); //check if *p_handles exist - SER_ASSERT_NOT_NULL(*pp_handles); //check if p_handles exist - SER_ASSERT_NOT_NULL(p_handle_count); //check if *p_handle_count exist - - uint32_t index = SER_CMD_DATA_POS; - uint32_t status_code; - - SER_ASSERT_LENGTH_LEQ(5, packet_len - index); //make sure that payload length is at least 5 bytes - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - //decode handle table count with optional handle table - status_code = count16_cond_data16_dec(p_buf, packet_len, &index, pp_handles, p_handle_count); - SER_ASSERT(status_code == NRF_SUCCESS, status_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return status_code; -} - - -uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - return op_status_enc(SD_BLE_GATTC_CHAR_VALUES_READ, return_code, p_buf, p_buf_len, &index); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_characteristics_discover.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_characteristics_discover.c deleted file mode 100644 index e17edb2..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_characteristics_discover.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_characteristics_discover_req_dec( - uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_handle_range = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->start_handle); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->end_handle); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_descriptors_discover.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_descriptors_discover.c deleted file mode 100644 index f78e675..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_descriptors_discover.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const pp_handle_range) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_handle_range = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->start_handle); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->end_handle); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_disc_rsp.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_disc_rsp.c deleted file mode 100644 index 5799434..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_disc_rsp.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 8, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_CHAR_DISC_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.count, &(p_buf[index])); - - uint16_t service_count = p_event->evt.gattc_evt.params.char_disc_rsp.count; - - SER_ASSERT_LENGTH_LEQ(index + (service_count * 9), *p_buf_len); - - for (uint16_t i = 0; i < service_count; i++) - { - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.uuid, - &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].uuid.type; - p_buf[index++] = (0x00 | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.broadcast << 0) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.read << 1) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.write_wo_resp << 2) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.write << 3) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.notify << 4) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.indicate << 5) | - (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_props.auth_signed_wr << 6)); - p_buf[index++] = (p_event->evt.gattc_evt.params.char_disc_rsp.chars[i]. - char_ext_props & 0x01); - - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_decl, - &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.char_disc_rsp.chars[i].handle_value, - &(p_buf[index])); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c deleted file mode 100644 index 4326380..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_val_by_uuid_read_rsp.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "app_util.h" -#include "ble.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_gattc_evt_conn.h" - - -uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gattc_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gattc_evt.gatt_status, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.gattc_evt.error_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc( - &p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_vals_read_rsp.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_vals_read_rsp.c deleted file mode 100644 index fa7fc41..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_char_vals_read_rsp.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_gattc_struct_serialization.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint16_t evt_header = BLE_GATTC_EVT_CHAR_VALS_READ_RSP; - - //Event Header - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - //GATTC Header - err_code = uint16_t_enc(&(p_event->evt.gattc_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gattc_evt.gatt_status), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gattc_evt.error_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - //Event structure for BLE_GATTC_EVT_CHAR_VALS_READ_RSP - err_code = - ble_gattc_evt_char_vals_read_rsp_t_enc(&(p_event->evt.gattc_evt.params.char_vals_read_rsp), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_desc_disc_rsp.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_desc_disc_rsp.c deleted file mode 100644 index 378e77b..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_desc_disc_rsp.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 8, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_DESC_DISC_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.count, &(p_buf[index])); - - uint16_t service_count = p_event->evt.gattc_evt.params.desc_disc_rsp.count; - - SER_ASSERT_LENGTH_LEQ(index + (service_count * 5), *p_buf_len); - - for (uint16_t i = 0; i < service_count; i++) - { - index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].handle, - &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.uuid, - &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.desc_disc_rsp.descs[i].uuid.type; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_hvx.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_hvx.c deleted file mode 100644 index 8e3a49e..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_hvx.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 11, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_HVX, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.hvx.handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.hvx.type; - index += uint16_encode(p_event->evt.gattc_evt.params.hvx.len, &(p_buf[index])); - - SER_ASSERT_LENGTH_LEQ(index + p_event->evt.gattc_evt.params.hvx.len, *p_buf_len); - - if (p_event->evt.gattc_evt.params.hvx.len > 0) - { - memcpy(&(p_buf[index]), - &(p_event->evt.gattc_evt.params.hvx.data[0]), - p_event->evt.gattc_evt.params.hvx.len); - index += p_event->evt.gattc_evt.params.hvx.len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c deleted file mode 100644 index f70c538..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_prim_srvc_disc_rsp.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 8, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.count, &(p_buf[index])); - - uint16_t service_count = p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.count; - - SER_ASSERT_LENGTH_LEQ(index + (service_count * 7), *p_buf_len); - - for (uint16_t i = 0; i < service_count; i++) - { - index += uint16_encode( - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.uuid, - &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].uuid.type; - index += - uint16_encode( - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - start_handle, - &(p_buf[index])); - index += - uint16_encode( - p_event->evt.gattc_evt.params.prim_srvc_disc_rsp.services[i].handle_range. - end_handle, - &(p_buf[index])); - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_read_rsp.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_read_rsp.c deleted file mode 100644 index 2d2b0f5..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_read_rsp.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 12, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_READ_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.read_rsp.handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.read_rsp.offset, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.read_rsp.len, &(p_buf[index])); - - SER_ASSERT_LENGTH_LEQ(index + p_event->evt.gattc_evt.params.read_rsp.len, *p_buf_len); - - if (p_event->evt.gattc_evt.params.read_rsp.len > 0) - { - memcpy(&(p_buf[index]), - &(p_event->evt.gattc_evt.params.read_rsp.data[0]), - p_event->evt.gattc_evt.params.read_rsp.len); - index += p_event->evt.gattc_evt.params.read_rsp.len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_rel_disc_rsp.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_rel_disc_rsp.c deleted file mode 100644 index fd83b62..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_rel_disc_rsp.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - uint32_t error_code = NRF_SUCCESS; - uint16_t evt_header = BLE_GATTC_EVT_REL_DISC_RSP; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - error_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&p_event->evt.gattc_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&p_event->evt.gattc_evt.gatt_status, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = uint16_t_enc(&p_event->evt.gattc_evt.error_handle, p_buf, total_len, &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - error_code = ble_gattc_evt_rel_disc_rsp_t_enc(&p_event->evt.gattc_evt.params.rel_disc_rsp, - p_buf, - total_len, - &index); - SER_ASSERT(error_code == NRF_SUCCESS, error_code); - - *p_buf_len = index; - - return error_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_timeout.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_timeout.c deleted file mode 100644 index ee1e08d..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_timeout.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_TIMEOUT, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.timeout.src; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_write_rsp.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_write_rsp.c deleted file mode 100644 index 7692b94..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_write_rsp.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_evt_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 13, *p_buf_len); - index += uint16_encode(BLE_GATTC_EVT_WRITE_RSP, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.gatt_status, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.error_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gattc_evt.params.write_rsp.write_op; - index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.offset, &(p_buf[index])); - index += uint16_encode(p_event->evt.gattc_evt.params.write_rsp.len, &(p_buf[index])); - - SER_ASSERT_LENGTH_LEQ(index + p_event->evt.gattc_evt.params.write_rsp.len, *p_buf_len); - - if (p_event->evt.gattc_evt.params.write_rsp.len > 0) - { - memcpy(&(p_buf[index]), - &(p_event->evt.gattc_evt.params.write_rsp.data[0]), - p_event->evt.gattc_evt.params.write_rsp.len); - index += p_event->evt.gattc_evt.params.write_rsp.len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_hv_confirm.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_hv_confirm.c deleted file mode 100644 index 6a1be3f..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_hv_confirm.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_HV_CONFIRM, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_primary_services_discover.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_primary_services_discover.c deleted file mode 100644 index 678e5e8..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_primary_services_discover.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_start_handle, - ble_uuid_t * * const pp_srvc_uuid) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_start_handle); - SER_ASSERT_NOT_NULL(pp_srvc_uuid); - SER_ASSERT_NOT_NULL(*pp_srvc_uuid); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - uint16_dec(p_buf, packet_len, &index, p_start_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_srvc_uuid = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 1, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_srvc_uuid)->uuid); - uint8_dec(p_buf, packet_len, &index, &(*pp_srvc_uuid)->type); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_read.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_read.c deleted file mode 100644 index ca0af98..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_read.c +++ /dev/null @@ -1,49 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" - -uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle, - uint16_t * const p_offset) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - SER_ASSERT_NOT_NULL(p_offset); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_offset); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gattc_read_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_READ, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_relationships_discover.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_relationships_discover.c deleted file mode 100644 index 7a61a3a..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_relationships_discover.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gattc_relationships_discover_req_dec( - uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_handle_range_t * * const - pp_handle_range) -{ - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_handle_range); - SER_ASSERT_NOT_NULL(*pp_handle_range); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_handle_range = NULL; - break; - - case SER_FIELD_PRESENT: - SER_ASSERT_LENGTH_LEQ(index + 2 + 2, packet_len); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->start_handle); - uint16_dec(p_buf, packet_len, &index, &(*pp_handle_range)->end_handle); - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, - return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_write.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_write.c deleted file mode 100644 index e889bce..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_write.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gattc_conn.h" -#include "ble_serialization.h" -#include "ble_gattc_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" -#include - - -uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - ble_gattc_write_params_t * * const pp_write_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_write_params); - SER_ASSERT_NOT_NULL(*pp_write_params); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = 0; - - uint8_t op_code; - err_code = uint8_t_dec(p_buf, packet_len, &index, &op_code); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT(op_code == SD_BLE_GATTC_WRITE, NRF_ERROR_INVALID_PARAM); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_write_params, - ble_gattc_write_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gattc_write_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTC_WRITE, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_characteristic_add.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_characteristic_add.c deleted file mode 100644 index 1e1a9de..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_characteristic_add.c +++ /dev/null @@ -1,88 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * service_handle, - ble_gatts_char_md_t * * const pp_char_md, - ble_gatts_attr_t * * const pp_attr_char_value, - ble_gatts_char_handles_t * * const pp_handles) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(service_handle); - SER_ASSERT_NOT_NULL(pp_char_md); - SER_ASSERT_NOT_NULL(pp_attr_char_value); - SER_ASSERT_NOT_NULL(pp_handles); - SER_ASSERT_NOT_NULL(*pp_char_md); - SER_ASSERT_NOT_NULL(*pp_attr_char_value); - SER_ASSERT_NOT_NULL(*pp_handles); - - uint32_t index = SER_CMD_DATA_POS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len); - uint32_t err_code; - SER_ASSERT_LENGTH_LEQ(2, buf_len - index); - uint16_dec(p_buf, buf_len, &index, service_handle); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_char_md, ble_gatts_char_md_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - buf_len, - &index, - (void * *)pp_attr_char_value, - ble_gatts_attr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_handles, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(index == buf_len, NRF_ERROR_INVALID_LENGTH); - - return err_code; -} - -uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gatts_char_handles_t const * const p_handles) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - SER_ASSERT_LENGTH_LEQ(1 + 4, total_len); - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_CHARACTERISTIC_ADD, - return_code, - p_buf, - p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code == NRF_SUCCESS) /* Add value and it's length. */ - { - err_code = cond_field_enc((void *)p_handles, - p_buf, - total_len, - p_buf_len, - ble_gatts_char_handles_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_conn.h b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_conn.h deleted file mode 100644 index 18cf3fb..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_conn.h +++ /dev/null @@ -1,514 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_GATTS_CONN_H__ -#define BLE_GATTS_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_gatts_conn GATTS Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s130_codecs - * - * @brief GATTS Connectivity command request decoders and command response encoders - */ - -#include "ble_gatts.h" -#include "ble.h" - -/**@brief Decodes @ref sd_ble_gatts_value_get command request. - * - * @sa @ref nrf51_gatts_value_get_encoding for packet format, - * @ref ble_gatts_value_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] p_conn_handle Pointer to the connection_handle. - * @param[out] p_handle Pointer to the attribute_handle. - * @param[out] pp_value Pointer to pointer to the Attribute Value structure. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle, - ble_gatts_value_t * * const pp_value); - -/**@brief Encodes @ref sd_ble_gatts_value_get command response. - * - * @sa @ref nrf51_gatts_value_get_sec_response for packet format. - * @ref ble_gatts_value_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_value Pointer to Attribute Value structure. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gatts_value_t * const p_value); - -/**@brief Decodes @ref sd_ble_gatts_characteristic_add command request. - * - * @sa @ref nrf51_characteristics_add_encoding for packet format, - * @ref ble_gatts_characteristic_add_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of request packet. - * @param[out] p_service_handle Pointer to the service_handle. - * @param[out] constpp_char_md Pointer to pointer to the location where Characteristic metadata - * will be decoded. - * @param[out] pp_attr_char_value Pointer to pointer to the location where GATT Attribute will be - * decoded. - * @param[out] pp_handles Pointer to pointer to the location where Characteristic definition - * handles will be decoded. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_service_handle, - ble_gatts_char_md_t * * constpp_char_md, - ble_gatts_attr_t * * const pp_attr_char_value, - ble_gatts_char_handles_t * * const pp_handles); - -/**@brief Encodes @ref ble_gatts_sys_attr_get_rsp_enc command response. - * - * @sa @ref sd_ble_gatts_sys_attr_get for packet format. - * @ref ble_gatts_sys_attr_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_handles Pointer to handle struct to be encoded. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gatts_char_handles_t const * const p_handles); - -/**@brief Decodes @ref sd_ble_gatts_include_add command request. - * - * @sa @ref nrf51_gatts_include_add_encoding for packet format, - * @ref ble_gatts_include_add_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] p_service_handle Pointer to the service_handle. - * @param[out] p_inc_srvc_handle Pointer to the handle of the included service. - * @param[out] pp_include_handle Pointer to Pointer to 16-bit word where the assigned handle will be stored. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ - -uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_service_handle, - uint16_t * const p_inc_srvc_handle, - uint16_t * * const pp_include_handle); - -/**@brief Encodes @ref ble_gatts_include_add_rsp_enc command response. - * - * @sa @ref nrf51_gatts_include_add_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_include_handle Pointer to a 16-bit word where the assigned handle was stored. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_include_handle); - -/**@brief Decodes @ref sd_ble_gatts_service_add command request. - * - * @sa @ref nrf51_gatts_service_add_encoding for packet format, - * @ref ble_gatts_service_add_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of request packet. - * @param[out] p_type Pointer to the service type. - * @param[out] pp_uuid Pointer to pointer to service UUID. - * @param[out] pp_handle Pointer to Pointer to a 16-bit word where the assigned handle will be stored. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ - -uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * const p_type, - ble_uuid_t * * const pp_uuid, - uint16_t * * const pp_handle); - -/**@brief Encodes @ref ble_gatts_service_add_rsp_enc command response. - * - * @sa @ref nrf51_gatts_service_add_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_handle Pointer to a 16-bit word where the assigned handle was stored. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ - -uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_handle); - -/**@brief Decodes @ref ble_gatts_sys_attr_get_req_dec command request. - * - * @sa @ref sd_ble_gatts_sys_attr_get for packet format, - * @ref ble_gatts_sys_attr_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connectiton handle. - * @param[out] pp_sys_attr_data Pointer to pointer to buffer where system attributes data will be filled in. - * @param[out] pp_sys_attr_data_len Pointer to pointer to variable which contains size of buffer for system attributes. - * @param[out] p_flags Pointer to additional optional flags. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * * const pp_sys_attr_data, - uint16_t * * const pp_sys_attr_data_len, - uint32_t * const p_flags); - -/**@brief Encodes @ref ble_gatts_sys_attr_get_rsp_enc command response. - * - * @sa @ref sd_ble_gatts_sys_attr_get for packet format. - * @ref ble_gatts_sys_attr_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_sys_attr_data Pointer to buffer where system attributes data are storred. - * @param[in] p_sys_attr_data_len Pointer to variable which contains size of buffer for system attributes. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_sys_attr_data, - uint16_t const * const p_sys_attr_data_len); - -/**@brief Decodes @ref sd_ble_gatts_value_set command request. - * - * @sa @ref nrf51_gatts_value_set_encoding for packet format, - * @ref ble_gatts_value_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle - * @param[out] p_handle Pointer to attribute handle - * @param[out] pp_value Pointer to pointer to attribute value structure - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ - -uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - uint16_t * p_handle, - ble_gatts_value_t * * const pp_value); - -/**@brief Encodes @ref sd_ble_gatts_value_set command response. - * - * @sa @ref nrf51_gatts_value_set_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buff Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buff_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_value \c in: size of value returned when value was written with success - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buff, - uint32_t * const p_buff_len, - ble_gatts_value_t * p_value); - -/**@brief Decodes @ref sd_ble_gatts_sys_attr_set command request. - * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format, - * @ref ble_gatts_sys_attr_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] p_conn_handle Pointer to the buffer raw data to be placed in advertisement packet. - * @param[out] pp_sys_attr_data Pointer to pointer to system attribute data. - * @param[out] p_sys_attr_data_len Pointer to data length for system attribute data. - * @param[out] p_flags Pointer to additional optional flags. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * * const pp_sys_attr_data, - uint16_t * const p_sys_attr_data_len, - uint32_t * const p_flags); - -/**@brief Encodes @ref sd_ble_gatts_sys_attr_set command response. - * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format. - * @ref ble_gatts_sys_attr_set_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref ble_gatts_hvx_req_dec command request. - * - * @sa @ref sd_ble_gatts_hvx for packet format, - * @ref ble_gatts_hvx_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] p_conn_handle Pointer to the buffer raw data to be placed in advertisement packet. - * @param[out] pp_hvx_params Pointer to an HVx parameters structure. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_gatts_hvx_params_t * * const pp_hvx_params); - -/**@brief Encodes @ref ble_gatts_hvx_rsp_enc command response. - * - * @sa @ref sd_ble_gatts_sys_attr_set for packet format. - * @ref ble_gatts_hvx_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_bytes_written Pointer to number of bytes written. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_bytes_written); - -/**@brief Decodes @ref sd_ble_gatts_descriptor_add command request. - * - * @sa @ref sd_ble_gatts_descriptor_add for packet format, - * @ref ble_gatts_descriptor_add_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[out] p_char_handle Pointer to buffer where characteristic handle will be. - returned. - * @param[out] pp_attr Pointer to pointer to an attribute structure. - * @param[out] pp_handle Pointer to pointer to descriptor handle. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_char_handle, - ble_gatts_attr_t * * const pp_attr, - uint16_t * * const pp_handle); - -/**@brief Encodes @ref sd_ble_gatts_descriptor_add command response. - * - * @sa @ref sd_ble_gatts_sys_attr_set for packet format. - * @ref ble_gatts_descriptor_add_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] handle Descriptor handle value. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t handle); - -/**@brief Decodes @ref sd_ble_gatts_rw_authorize_reply command request. - * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format, - * @ref ble_gatts_rw_authorize_reply_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_reply_params Pointer to pointer to \ref ble_gatts_rw_authorize_reply_params_t - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ - -uint32_t ble_gatts_rw_authorize_reply_req_dec( - uint8_t const * const p_buf, - uint32_t - packet_len, - uint16_t * - p_conn_handle, - ble_gatts_rw_authorize_reply_params_t * * const - pp_reply_params); - -/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command response. - * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format. - * @ref ble_gatts_rw_authorize_reply_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/**@brief Decodes @ref sd_ble_gatts_service_changed command request. - * - * @sa @ref nrf51_service_changed_encoding for packet format, - * @ref ble_gatts_service_changed_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] p_start_handle Pointer to start handle. - * @param[out] p_end_handle Pointer to end handle. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - uint16_t * p_start_handle, - uint16_t * p_end_handle); - -/**@brief Encodes @ref sd_ble_gatts_service_changed command response. - * - * @sa @ref nrf51_service_changed_encoding for packet format. - * @ref ble_gatts_service_changed_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif //BLE_GATTS_CONN_H__ - diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_descriptor_add.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_descriptor_add.c deleted file mode 100644 index 1929309..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_descriptor_add.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_char_handle, - ble_gatts_attr_t * * const pp_attr, - uint16_t * * const pp_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_char_handle); - SER_ASSERT_NOT_NULL(pp_attr); - SER_ASSERT_NOT_NULL(*pp_attr); - SER_ASSERT_NOT_NULL(pp_handle); - SER_ASSERT_NOT_NULL(*pp_handle); - - uint32_t index = 0; - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_DESCRIPTOR_ADD, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_char_handle); - - uint32_t err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_attr, - ble_gatts_attr_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, - packet_len, - &index, - (void * *)pp_handle, - NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4, total_len); - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_DESCRIPTOR_ADD, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 2, total_len); - - err_code = uint16_t_enc(&handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_hvc.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_hvc.c deleted file mode 100644 index 872e9a5..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_hvc.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 2, *p_buf_len); - - index += uint16_encode(BLE_GATTS_EVT_HVC, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.params.hvc.handle, &(p_buf[index])); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_rw_authorize_request.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_rw_authorize_request.c deleted file mode 100644 index 4674938..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_rw_authorize_request.c +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "conn_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_conn_user_mem_table[]; - -uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - SER_ASSERT_NOT_NULL(p_event); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint32_t err_code = NRF_SUCCESS; - - err_code = uint16_t_enc(&p_event->header.evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gatts_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_evt_rw_authorize_request_t_enc( - &(p_event->evt.gatts_evt.params.authorize_request), - p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if(p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) - { - uint32_t conn_index; - - if(conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_enc(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_sc_confirm.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_sc_confirm.c deleted file mode 100644 index 1bf1e0f..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_sc_confirm.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE + 2, *p_buf_len); - - uint32_t index = 0; - index += uint16_encode(BLE_GATTS_EVT_SC_CONFIRM, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_sys_attr_missing.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_sys_attr_missing.c deleted file mode 100644 index cb7c3e4..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_sys_attr_missing.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GATTS_EVT_SYS_ATTR_MISSING, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gatts_evt.params.sys_attr_missing.hint; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_timeout.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_timeout.c deleted file mode 100644 index 096ec5c..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_timeout.c +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len); - index += uint16_encode(BLE_GATTS_EVT_TIMEOUT, &(p_buf[index])); - index += uint16_encode(p_event->evt.gatts_evt.conn_handle, &(p_buf[index])); - p_buf[index++] = p_event->evt.gatts_evt.params.timeout.src; - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_write.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_write.c deleted file mode 100644 index acc2a43..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_write.c +++ /dev/null @@ -1,63 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_evt_conn.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "conn_ble_user_mem.h" -#include "app_util.h" - -extern ser_ble_user_mem_t m_conn_user_mem_table[]; - -uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t total_len = *p_buf_len; - uint16_t evt_header = BLE_GATTS_EVT_WRITE; - - err_code = uint16_t_enc(&evt_header, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&(p_event->evt.gatts_evt.conn_handle), p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_gatts_evt_write_t_enc(&(p_event->evt.gatts_evt.params.write), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if((p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_WRITE_REQ) || (p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)) - { - uint32_t conn_index; - - if(conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) - { - err_code = len16data_enc(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len, p_buf, *p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_hvx.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_hvx.c deleted file mode 100644 index 67bd566..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_hvx.c +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_gatts_hvx_params_t * * const pp_hvx_params) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_hvx_params); - SER_ASSERT_NOT_NULL(*pp_hvx_params); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_HVX, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - uint32_t err_code = cond_field_dec(p_buf, packet_len, - &index, - (void * *)pp_hvx_params, - ble_gatts_hvx_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - -uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_bytes_written) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_HVX, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - uint32_t index = *p_buf_len; - - err_code = cond_field_enc(p_bytes_written, p_buf, total_len, &index, uint16_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_include_add.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_include_add.c deleted file mode 100644 index 766313f..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_include_add.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_service_handle, - uint16_t * const p_inc_srvc_handle, - uint16_t * * const pp_include_handle) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_service_handle); - SER_ASSERT_NOT_NULL(p_inc_srvc_handle); - SER_ASSERT_NOT_NULL(pp_include_handle); - SER_ASSERT_LENGTH_EQ(6, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_INCLUDE_ADD, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_service_handle); - uint16_dec(p_buf, packet_len, &index, p_inc_srvc_handle); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_include_handle = NULL; - } - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_include_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - uint32_t err_code; - - err_code = op_status_enc(SD_BLE_GATTS_INCLUDE_ADD, return_code, p_buf, p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - SER_ASSERT_NOT_NULL(p_include_handle); - err_code = uint16_t_enc(p_include_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; //update change made by op_status_enc - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_rw_authorize_reply.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_rw_authorize_reply.c deleted file mode 100644 index 94390bb..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_rw_authorize_reply.c +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "ble_gatts_struct_serialization.h" -#include "cond_field_serialization.h" - -uint32_t ble_gatts_rw_authorize_reply_req_dec( - uint8_t const * const p_buf, - uint32_t - packet_len, - uint16_t * - p_conn_handle, - ble_gatts_rw_authorize_reply_params_t * * const - pp_reply_params) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - - uint32_t index = SER_CMD_HEADER_SIZE; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(2, packet_len - index); - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - err_code = cond_field_dec(p_buf, packet_len, &index, - (void * *)pp_reply_params, ble_gatts_rw_authorize_reply_params_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - -uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_service_add.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_service_add.c deleted file mode 100644 index e1d7c68..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_service_add.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include - -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint8_t * const p_type, - ble_uuid_t * * const pp_uuid, - uint16_t * * const pp_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_type); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(pp_handle); - SER_ASSERT_NOT_NULL(*pp_handle); - - uint32_t index = SER_CMD_DATA_POS; - - uint32_t err_code; - SER_ASSERT_LENGTH_LEQ(3, buf_len - index); - err_code = uint8_t_dec(p_buf, buf_len, &index, p_type); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_handle, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(index == buf_len, NRF_ERROR_INVALID_LENGTH); - - return err_code; -} - -uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint16_t const * const p_handle) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t buf_len = *p_buf_len; - uint32_t index = 0; - uint32_t err_code; - - err_code = op_status_enc(SD_BLE_GATTS_SERVICE_ADD, return_code, p_buf, p_buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; //this seems silly but it is not - } - SER_ASSERT_NOT_NULL(p_handle); - err_code = uint16_t_enc(p_handle, p_buf, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; //update change made by op_status_enc - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_service_changed.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_service_changed.c deleted file mode 100644 index 37e9e34..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_service_changed.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include "ble_gatts_conn.h" -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * p_conn_handle, - uint16_t * p_start_handle, - uint16_t * p_end_handle) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_start_handle); - SER_ASSERT_NOT_NULL(p_end_handle); - - SER_ASSERT_LENGTH_EQ(SER_CMD_HEADER_SIZE + 6, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_SERVICE_CHANGED, NRF_ERROR_INVALID_PARAM); - index++; - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - uint16_dec(p_buf, packet_len, &index, p_start_handle); - uint16_dec(p_buf, packet_len, &index, p_end_handle); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_SERVICE_CHANGED, - return_code, - p_buf, - p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_sys_attr_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_sys_attr_get.c deleted file mode 100644 index affbe8e..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_sys_attr_get.c +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * * const pp_sys_attr_data, - uint16_t * * const pp_sys_attr_data_len, - uint32_t * const p_flags) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_sys_attr_data); - SER_ASSERT_NOT_NULL(pp_sys_attr_data_len); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 1, packet_len); - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_SYS_ATTR_GET, NRF_ERROR_INVALID_PARAM); - index++; - - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_flags); - *p_conn_handle = uint16_decode(&p_buf[index]); - index += sizeof (uint16_t); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - SER_ASSERT_LENGTH_LEQ(index + 2, packet_len); - - SER_ASSERT_NOT_NULL(*pp_sys_attr_data_len); - **pp_sys_attr_data_len = uint16_decode(&p_buf[index]); - index += sizeof (uint16_t); - } - else - { - *pp_sys_attr_data_len = NULL; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, packet_len); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_sys_attr_data = NULL; - } - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_flags); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_sys_attr_data, - uint16_t const * const p_sys_attr_data_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - SER_ASSERT_LENGTH_LEQ(1 + 4, total_len); - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_SYS_ATTR_GET, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_sys_attr_data); - SER_ASSERT_NOT_NULL(p_sys_attr_data_len); - uint32_t index = *p_buf_len; - uint16_t sys_attr_len = 0; - - SER_ASSERT_LENGTH_LEQ(index + 2, total_len); - - if (p_sys_attr_data_len != NULL) - { - index += uint16_encode(*p_sys_attr_data_len, &p_buf[index]); - sys_attr_len = *p_sys_attr_data_len; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, total_len); - p_buf[index++] = p_sys_attr_data ? SER_FIELD_PRESENT : - SER_FIELD_NOT_PRESENT; - - SER_ASSERT_LENGTH_LEQ(index + sys_attr_len, total_len); - - if (p_sys_attr_data != NULL) - { - memcpy(&p_buf[index], p_sys_attr_data, sys_attr_len); - index += sys_attr_len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_sys_attr_set.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_sys_attr_set.c deleted file mode 100644 index b25d9d9..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_sys_attr_set.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - uint8_t * * const pp_sys_attr_data, - uint16_t * const p_sys_attr_data_len, - uint32_t * const p_flags) -{ - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - uint16_t sys_attr_data_len_temp; - uint16_t * p_sys_attr_data_len_temp = &sys_attr_data_len_temp; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_sys_attr_data); - SER_ASSERT_NOT_NULL(*pp_sys_attr_data); - SER_ASSERT_NOT_NULL(p_sys_attr_data_len); - SER_ASSERT_NOT_NULL(p_flags); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 7, packet_len); - - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - - switch (p_buf[index++]) - { - case SER_FIELD_NOT_PRESENT: - *pp_sys_attr_data = NULL; - SER_ASSERT_LENGTH_EQ(index + 4, packet_len); - *p_sys_attr_data_len = 0; - break; - - case SER_FIELD_PRESENT: - uint16_dec(p_buf, packet_len, &index, p_sys_attr_data_len_temp); - SER_ASSERT_LENGTH_LEQ(*p_sys_attr_data_len_temp, *p_sys_attr_data_len); - *p_sys_attr_data_len = *p_sys_attr_data_len_temp; - SER_ASSERT_LENGTH_EQ(index + *p_sys_attr_data_len + 4, packet_len); - memcpy(*pp_sys_attr_data, &p_buf[index], *p_sys_attr_data_len); - index += *p_sys_attr_data_len; - break; - - default: - return NRF_ERROR_INVALID_DATA; - } - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_flags); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - - -uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_SYS_ATTR_SET, return_code, p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_value_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_value_get.c deleted file mode 100644 index eebd031..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_value_get.c +++ /dev/null @@ -1,105 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * const p_conn_handle, - uint16_t * const p_handle, - ble_gatts_value_t * * const pp_value) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - SER_ASSERT_NOT_NULL(pp_value); - SER_ASSERT_NOT_NULL(*pp_value); - SER_ASSERT_NOT_NULL((*pp_value)->p_value); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 5, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_GATTS_VALUE_GET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_value)->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_value)->offset)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_LEQ(1, packet_len - index); - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - (*pp_value)->p_value = NULL; - } - } - else - { - *pp_value = NULL; - } - - return err_code; -} - - -uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gatts_value_t * const p_value) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_RSP_HEADER_SIZE, *p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_GATTS_VALUE_GET, - return_code, - p_buf, - p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - uint32_t index = *p_buf_len; - - if (return_code == NRF_SUCCESS) - { - SER_ASSERT_NOT_NULL(p_value); - - err_code = ble_gatts_value_t_enc(p_value, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_value_set.c b/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_value_set.c deleted file mode 100644 index 4a7eb2b..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_value_set.c +++ /dev/null @@ -1,74 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_gatts_conn.h" -#include -#include "cond_field_serialization.h" -#include "ble_serialization.h" -#include "ble_gatts_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint16_t * p_conn_handle, - uint16_t * p_handle, - ble_gatts_value_t * * const pp_value) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(p_handle); - SER_ASSERT_NOT_NULL(pp_value); - - uint32_t index = SER_CMD_DATA_POS; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(4, packet_len - index); //make sure that payload length is at least 4 bytes - uint16_dec(p_buf, packet_len, &index, p_conn_handle); - uint16_dec(p_buf, packet_len, &index, p_handle); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_value, ble_gatts_value_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buff, - uint32_t * const p_buff_len, - ble_gatts_value_t * p_value) -{ - SER_ASSERT_NOT_NULL(p_buff); - SER_ASSERT_NOT_NULL(p_buff_len); - - uint32_t buf_len = *p_buff_len; - uint32_t index = 0; - uint32_t err_code; - - err_code = op_status_enc(SD_BLE_GATTS_VALUE_SET, return_code, p_buff, p_buff_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - SER_ASSERT_NOT_NULL(p_value); - err_code = ble_gatts_value_t_enc(p_value, p_buff, buf_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buff_len = index; //update change made by op_status_enc - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_cid_register.c b/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_cid_register.c deleted file mode 100644 index 9e2a775..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_cid_register.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_l2cap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_cid) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_cid); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_LENGTH_EQ(3, buf_len); - SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_REGISTER, NRF_ERROR_INVALID_PARAM); - - index++; - err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_REGISTER, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_cid_unregister.c b/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_cid_unregister.c deleted file mode 100644 index 74d4619..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_cid_unregister.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_l2cap_conn.h" -#include "ble_serialization.h" -#include "nrf_error.h" - - -uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - uint16_t * p_cid) -{ - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_NOT_NULL(p_cid); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_LENGTH_EQ(3, buf_len); - SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_UNREGISTER, NRF_ERROR_INVALID_PARAM); - - index++; - err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_UNREGISTER, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_evt_conn.h b/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_evt_conn.h deleted file mode 100644 index 6026f57..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_evt_conn.h +++ /dev/null @@ -1,56 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 BLE_L2CAP_EVT_CONN_H__ -#define BLE_L2CAP_EVT_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup ble_l2cap_evt_conn L2CAP Connectivity event encoders - * @{ - * @ingroup ser_conn_s130_codecs - * - * @brief L2CAP Connectivity event encoders. - */ -#include "ble.h" - -/** - * @brief Encodes ble_l2cap_evt_rx event. - * - * @sa @ref nrf51_l2cap_evt_rx_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. - * @param[in] event_len Size (in bytes) of \p p_event buffer. - * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. - * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. - * \c out: Length of encoded contents in \p p_buf. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - -/** @} */ -#endif diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_evt_rx.c b/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_evt_rx.c deleted file mode 100644 index 15793ed..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_evt_rx.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_l2cap_evt_conn.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - - -uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event, - uint32_t event_len, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_event); - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code; - uint32_t total_len = *p_buf_len; - - uint16_t evt_id = BLE_L2CAP_EVT_RX; - - err_code = uint16_t_enc(&evt_id, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = uint16_t_enc(&p_event->evt.l2cap_evt.conn_handle, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = ble_l2cap_evt_rx_t_enc(&(p_event->evt.l2cap_evt.params.rx), - p_buf, - total_len, - &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_tx.c b/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_tx.c deleted file mode 100644 index c574b40..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_tx.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include -#include -#include "ble_l2cap_conn.h" -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "cond_field_serialization.h" -#include "app_util.h" - -uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, - uint16_t * p_conn_handle, - ble_l2cap_header_t * * const pp_l2cap_header, - uint8_t const * * pp_data) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_l2cap_header); - SER_ASSERT_NOT_NULL(*pp_l2cap_header); - SER_ASSERT_NOT_NULL(pp_data); - //SER_ASSERT_NOT_NULL(*pp_data); - - uint32_t err_code = NRF_SUCCESS; - uint32_t index = SER_CMD_DATA_POS; - - err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_l2cap_header, - ble_l2cap_header_t_dec); - - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (*pp_l2cap_header != NULL) - { - *pp_data = p_buf + index + 1; - index += 1 + (*pp_l2cap_header)->len; - } - else - { - *pp_data = NULL; - index++; - } - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_TX, return_code, - p_buf, p_buf_len); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_opt_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_opt_get.c deleted file mode 100644 index 7f2da63..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_opt_get.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "ble_struct_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t **const pp_opt ) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_NOT_NULL(pp_opt); - SER_ASSERT_NOT_NULL(*pp_opt); - SER_ASSERT_LENGTH_EQ(SER_CMD_HEADER_SIZE + 4 + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_OPT_GET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (*p_opt_id == BLE_GAP_OPT_CH_MAP) || - (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (*p_opt_id == BLE_GAP_OPT_PASSKEY) || - (*p_opt_id == BLE_GAP_OPT_PRIVACY) || - (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_opt = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_opt_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint32_t opt_id, - ble_opt_t const * const p_opt) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_OPT_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_opt); - SER_ASSERT(((opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (opt_id == BLE_GAP_OPT_CH_MAP) || - (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (opt_id == BLE_GAP_OPT_PASSKEY) || - (opt_id == BLE_GAP_OPT_PRIVACY) || - (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - uint32_t index = *p_buf_len; - err_code = uint32_t_enc(&opt_id, p_buf, total_len, &index); - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - switch (opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_enc((void *)&(p_opt->common_opt.radio_cpu_mutex), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_enc((void *)&(p_opt->gap_opt.ch_map), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_enc((void *)&(p_opt->gap_opt.local_conn_latency), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_enc((void *)&(p_opt->gap_opt.passkey), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_enc((void *)&(p_opt->gap_opt.privacy), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_enc((void *)&(p_opt->gap_opt.scan_req_report), p_buf, total_len, &index); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_enc((void *)&(p_opt->gap_opt.compat_mode), p_buf, total_len, &index); - break; - } - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_opt_id_pre_decoder.c b/components/serialization/connectivity/codecs/s130/serializers/ble_opt_id_pre_decoder.c deleted file mode 100644 index 7b0e749..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_opt_id_pre_decoder.c +++ /dev/null @@ -1,36 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_OPT_SET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_opt_set.c b/components/serialization/connectivity/codecs/s130/serializers/ble_opt_set.c deleted file mode 100644 index 8a0b6e5..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_opt_set.c +++ /dev/null @@ -1,114 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "ble_gap_struct_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint32_t * const p_opt_id, - ble_opt_t **const pp_opt ) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_opt_id); - SER_ASSERT_NOT_NULL(pp_opt); - SER_ASSERT_NOT_NULL(*pp_opt); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 4 + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_OPT_SET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint32_t_dec(p_buf, packet_len, &index, p_opt_id); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_RADIO_CPU_MUTEX) || - (*p_opt_id == BLE_GAP_OPT_CH_MAP) || - (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || - (*p_opt_id == BLE_GAP_OPT_PASSKEY) || - (*p_opt_id == BLE_GAP_OPT_PRIVACY) || - (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || - (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE)), NRF_ERROR_INVALID_PARAM); - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_opt = NULL; - } - else - { - switch(*p_opt_id) - { - case BLE_COMMON_OPT_RADIO_CPU_MUTEX: - err_code = ble_common_opt_radio_cpu_mutex_t_dec(p_buf, packet_len, &index, &((*pp_opt)->common_opt.radio_cpu_mutex)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_CH_MAP: - err_code = ble_gap_opt_ch_map_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.ch_map)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_LOCAL_CONN_LATENCY: - err_code = ble_gap_opt_local_conn_latency_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.local_conn_latency)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_PASSKEY: - err_code = ble_gap_opt_passkey_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.passkey)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_PRIVACY: - err_code = ble_gap_opt_privacy_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.privacy)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_SCAN_REQ_REPORT: - err_code = ble_gap_opt_scan_req_report_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.scan_req_report)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - case BLE_GAP_OPT_COMPAT_MODE: - err_code = ble_gap_opt_compat_mode_t_dec(p_buf, packet_len, &index, &((*pp_opt)->gap_opt.compat_mode)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - break; - } - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_opt_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_OPT_SET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_tx_buffer_count_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_tx_buffer_count_get.c deleted file mode 100644 index eec8bb9..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_tx_buffer_count_get.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" -#include "cond_field_serialization.h" - -uint32_t ble_tx_buffer_count_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - uint8_t * * const pp_count) -{ - SER_ASSERT_NOT_NULL(p_buf); - - uint32_t index = 0; - uint8_t opcode; - uint32_t err_code; - - err_code = uint8_t_dec(p_buf, packet_len, &index, &opcode); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - SER_ASSERT(opcode == SD_BLE_TX_BUFFER_COUNT_GET, NRF_ERROR_INVALID_PARAM); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_count, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_tx_buffer_count_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_count) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_TX_BUFFER_COUNT_GET, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = cond_field_enc(p_count, p_buf, total_len, p_buf_len, uint8_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_user_mem_reply.c b/components/serialization/connectivity/codecs/s130/serializers/ble_user_mem_reply.c deleted file mode 100644 index 61062b6..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_user_mem_reply.c +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint16_t * const p_conn_handle, - ble_user_mem_block_t * * const pp_mem_block) -{ - uint32_t index = 0; - uint32_t err_code; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_conn_handle); - SER_ASSERT_NOT_NULL(pp_mem_block); - SER_ASSERT_NOT_NULL(*pp_mem_block); - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 2 + 4, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_USER_MEM_REPLY, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = uint16_t_dec(p_buf, packet_len, &index, p_conn_handle); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - if (p_buf[index++] == SER_FIELD_PRESENT) - { - // Decoding order is different than structure elements order because - // mem block length is received first - err_code = uint16_t_dec(p_buf, packet_len, &index, &((*pp_mem_block)->len)); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, packet_len, &index, (void **)&((*pp_mem_block)->p_mem), NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - else - { - *pp_mem_block = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return err_code; -} - - -uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len) -{ - return ser_ble_cmd_rsp_dec(p_buf, *p_buf_len, SD_BLE_USER_MEM_REPLY, &return_code); -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_uuid_decode.c b/components/serialization/connectivity/codecs/s130/serializers/ble_uuid_decode.c deleted file mode 100644 index 000e4d8..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_uuid_decode.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, - uint8_t * p_uuid_le_len, - uint8_t * * const pp_uuid_le, - ble_uuid_t * * const pp_uuid) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_uuid_le_len); - uint32_t err_code; - uint32_t index = 0; - uint8_t opcode = SD_BLE_UUID_DECODE; - - SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - index)); - uint8_dec(p_buf, buf_len, &index, &opcode); - SER_ASSERT(opcode == SD_BLE_UUID_DECODE, NRF_ERROR_INVALID_DATA); - - err_code = len8data_dec(p_buf, buf_len, &index, pp_uuid_le, p_uuid_le_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_uuid_t const * const p_uuid) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_UUID_DECODE, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - *p_buf_len = index; - return NRF_SUCCESS; - } - - err_code = cond_field_enc((void *)p_uuid, p_buf, total_len, &index, ble_uuid_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_uuid_encode.c b/components/serialization/connectivity/codecs/s130/serializers/ble_uuid_encode.c deleted file mode 100644 index 0843668..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_uuid_encode.c +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_uuid_t * * const pp_uuid, - uint8_t * * const pp_uuid_le_len, - uint8_t * * const pp_uuid_le) -{ - uint32_t index = SER_CMD_HEADER_SIZE; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(pp_uuid_le_len); - SER_ASSERT_NOT_NULL(pp_uuid_le); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid_le_len); - SER_ASSERT_NOT_NULL(*pp_uuid_le); - - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 3, packet_len); - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - index++; - *pp_uuid = NULL; - } - else if (p_buf[index] == SER_FIELD_PRESENT) - { - SER_ASSERT_LENGTH_LEQ(SER_CMD_HEADER_SIZE + 6, packet_len); - index++; - uint16_dec(p_buf, packet_len, &index, &((*pp_uuid)->uuid)); - (*pp_uuid)->type = p_buf[index++]; - } - else - { - return NRF_ERROR_INVALID_DATA; - } - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - *pp_uuid_le_len = NULL; - } - else if (p_buf[index] != SER_FIELD_PRESENT) - { - return NRF_ERROR_INVALID_DATA; - } - - index++; - - if (p_buf[index] == SER_FIELD_NOT_PRESENT) - { - *pp_uuid_le = NULL; - } - else if (p_buf[index] != SER_FIELD_PRESENT) - { - return NRF_ERROR_INVALID_DATA; - } - - SER_ASSERT_LENGTH_EQ(index + 1, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t uuid_le_len, - uint8_t const * const p_uuid_le) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_UUID_ENCODE, return_code, - p_buf, p_buf_len); - uint32_t index = *p_buf_len; - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_LENGTH_LEQ(index + 1, total_len); - p_buf[index++] = uuid_le_len; - - if (p_uuid_le != NULL) - { - SER_ASSERT_LENGTH_LEQ(index + uuid_le_len, total_len); - memcpy(p_buf + index, p_uuid_le, uuid_le_len); - index += uuid_le_len; - } - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_uuid_vs_add.c b/components/serialization/connectivity/codecs/s130/serializers/ble_uuid_vs_add.c deleted file mode 100644 index 5deeac7..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_uuid_vs_add.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "cond_field_serialization.h" -#include "ble_struct_serialization.h" -#include "app_util.h" - -uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf, - uint16_t buf_len, - ble_uuid128_t * * const pp_uuid, - uint8_t * * const pp_uuid_type) -{ - uint32_t index = SER_CMD_HEADER_SIZE; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_uuid); - SER_ASSERT_NOT_NULL(pp_uuid_type); - SER_ASSERT_NOT_NULL(*pp_uuid); - SER_ASSERT_NOT_NULL(*pp_uuid_type); - - uint32_t err_code; - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid, ble_uuid128_t_dec); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_uuid_type, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - - -uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - uint8_t const * const p_uuid_type) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_UUID_VS_ADD, return_code, - p_buf, p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - uint32_t index = *p_buf_len; - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - err_code = cond_field_enc((void *)p_uuid_type, p_buf, total_len, &index, uint8_t_enc); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_version_get.c b/components/serialization/connectivity/codecs/s130/serializers/ble_version_get.c deleted file mode 100644 index 28dbe54..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_version_get.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "ble_conn.h" -#include -#include "ble_serialization.h" -#include "app_util.h" - -uint32_t ble_version_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_version_t * * const pp_version) -{ - uint32_t index = 0; - - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_version); - SER_ASSERT_NOT_NULL(*pp_version); - SER_ASSERT_LENGTH_EQ(SER_CMD_HEADER_SIZE + 1, packet_len); - - SER_ASSERT(p_buf[index] == SD_BLE_VERSION_GET, NRF_ERROR_INVALID_PARAM); - index++; - - if (p_buf[index++] == SER_FIELD_NOT_PRESENT) - { - *pp_version = NULL; - } - - SER_ASSERT_LENGTH_EQ(index, packet_len); - - return NRF_SUCCESS; -} - - -uint32_t ble_version_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_version_t const * const p_version) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t total_len = *p_buf_len; - - uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SD_BLE_VERSION_GET, return_code, - p_buf, p_buf_len); - - if (err_code != NRF_SUCCESS) - { - return err_code; - } - - if (return_code != NRF_SUCCESS) - { - return NRF_SUCCESS; - } - - SER_ASSERT_NOT_NULL(p_version); - uint32_t index = *p_buf_len; - - SER_ASSERT_LENGTH_LEQ(index + 5, total_len); - p_buf[index++] = p_version->version_number; - index += uint16_encode(p_version->company_id, &p_buf[index]); - index += uint16_encode(p_version->subversion_number, &p_buf[index]); - - *p_buf_len = index; - - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/conn_ble_gap_sec_keys.c b/components/serialization/connectivity/codecs/s130/serializers/conn_ble_gap_sec_keys.c deleted file mode 100644 index a7db7e3..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/conn_ble_gap_sec_keys.c +++ /dev/null @@ -1,73 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "conn_ble_gap_sec_keys.h" -#include "nrf_error.h" -#include - -ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS]; - -uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -#define SER_MAX_CONNECTIONS 2 - -/**@brief GAP connection - keyset mapping structure. - * - * @note This structure is used to map keysets to connection instances, and will be stored in a static table. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that keys for this connection are used by soft device. 0: keys used; 1: keys not used*/ - ble_gap_sec_keyset_t keyset; /**< Keyset structure see @ref ble_gap_sec_keyset_t.*/ - ble_gap_enc_key_t enc_key_periph; /**< Peripheral Encryption Key, see @ref ble_gap_enc_key_t.*/ - ble_gap_id_key_t id_key_periph; /**< Peripheral Identity Key, see @ref ble_gap_id_key_t.*/ - ble_gap_sign_info_t sign_key_periph; /**< Peripheral Signing Information, see @ref ble_gap_sign_info_t.*/ - ble_gap_enc_key_t enc_key_central; /**< Central Encryption Key, see @ref ble_gap_enc_key_t.*/ - ble_gap_id_key_t id_key_central; /**< Central Identity Key, see @ref ble_gap_id_key_t.*/ - ble_gap_sign_info_t sign_key_central; /**< Central Signing Information, see @ref ble_gap_sign_info_t.*/ -} ser_ble_gap_conn_keyset_t; - -/**@brief allocates instance in m_conn_keys_table[] for storage of encryption keys. - * - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS great success. - * @retval NRF_ERROR_NO_MEM no free instance available. - */ -uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_gap_sec_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_conn_keys_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context table entry found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_CONN_BLE_GAP_SEC_KEYS_H diff --git a/components/serialization/connectivity/codecs/s130/serializers/conn_ble_user_mem.c b/components/serialization/connectivity/codecs/s130/serializers/conn_ble_user_mem.c deleted file mode 100644 index 7ee0563..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/conn_ble_user_mem.c +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "conn_ble_user_mem.h" -#include "ser_config.h" -#include "nrf_error.h" -#include - - - -ser_ble_user_mem_t m_conn_user_mem_table[SER_MAX_CONNECTIONS]; - -uint32_t conn_ble_user_mem_context_create(uint32_t *p_index) -{ - uint32_t err_code = NRF_ERROR_NO_MEM; - uint32_t i; - - for (i=0; i - -/**@brief Connection - user memory mapping structure. - * - * @note This structure is used to map keysets to connection instances, and will be stored in a static table. - */ -//lint -esym(452,ser_ble_user_mem_t) -typedef struct -{ - uint16_t conn_handle; /**< Connection handle.*/ - uint8_t conn_active; /**< Indication that user memory for this connection is used by soft device. 0: memory used; 1: memory not used*/ - ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t.*/ - uint8_t mem_table[64]; /**< Memory table.*/ -} ser_ble_user_mem_t; - -/**@brief allocates instance in m_user_mem_table[] for storage. - * - * @param[out] p_index pointer to the index of allocated instance - * - * @retval NRF_SUCCESS great success. - * @retval NRF_ERROR_NO_MEM no free instance available. - */ -uint32_t conn_ble_user_mem_context_create(uint32_t *p_index); - -/**@brief release instance identified by a connection handle. - * - * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS Context released. - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_user_mem_context_destroy(uint16_t conn_handle); - -/**@brief finds index of instance identified by a connection handle in m_user_mem_table[]. - * - * @param[in] conn_handle conn_handle - * - * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle - * - * @retval NRF_SUCCESS Context table entry found - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found - */ -uint32_t conn_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index); -/** @} */ - -#endif //_CONN_BLE_USER_MEM_H diff --git a/components/serialization/connectivity/codecs/s130/serializers/nrf_soc_conn.h b/components/serialization/connectivity/codecs/s130/serializers/nrf_soc_conn.h deleted file mode 100644 index 8aae397..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/nrf_soc_conn.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_SOC_CONN_H__ -#define NRF_SOC_CONN_H__ - -/** - * @addtogroup ser_codecs Serialization codecs - * @ingroup ble_sdk_lib_serialization - */ - -/** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs - * @ingroup ser_codecs - */ - -/**@file - * - * @defgroup soc_conn SOC Connectivity command request decoders and command response encoders - * @{ - * @ingroup ser_conn_s130_codecs - * - * @brief SOC Connectivity command request decoders and command response encoderss. - */ -#include "nrf_soc.h" - -/**@brief Decodes @ref sd_power_system_off command request. - * - * @sa @ref nrf51_sd_power_off for packet format. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in] packet_len Length (in bytes) of request packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. - */ -uint32_t power_system_off_req_dec(uint8_t const * const p_buf, uint16_t packet_len); - - -/**@brief Decodes @ref sd_temp_get command request. - * - * @sa @ref nrf51_sd_temp_get for packet format. - * @ref temp_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to buffer where encoded data command will be returned. - * @param[in] buf_len Length (in bytes) of request packet. - * @param[out] pp_temp Pointer to pointer to result of temperature measurement. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. - */ -uint32_t temp_get_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - int32_t * * const pp_temp); - -/**@brief Encodes @ref sd_temp_get command response. - * - * @sa @ref nrf51_sd_temp_get for packet format. - * @ref temp_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_temp Pointer to result of temperature measurement. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t temp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int32_t * const p_temp); - -/** @} */ -#endif - diff --git a/components/serialization/connectivity/codecs/s130/serializers/power_system_off.c b/components/serialization/connectivity/codecs/s130/serializers/power_system_off.c deleted file mode 100644 index 00e66b2..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/power_system_off.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - */ - -#include "nrf_soc_conn.h" -#include "ble_serialization.h" - -uint32_t power_system_off_req_dec(uint8_t const * const p_buf, - uint16_t packet_len) -{ - SER_ASSERT_NOT_NULL(p_buf); - - uint32_t index = 0; - SER_ASSERT_LENGTH_LEQ(1, packet_len); - SER_ASSERT(p_buf[index] == SD_POWER_SYSTEM_OFF, NRF_ERROR_INVALID_PARAM); - index++; - - SER_ASSERT_LENGTH_EQ(index, packet_len); - return NRF_SUCCESS; -} diff --git a/components/serialization/connectivity/codecs/s130/serializers/temp_get.c b/components/serialization/connectivity/codecs/s130/serializers/temp_get.c deleted file mode 100644 index 8cd2081..0000000 --- a/components/serialization/connectivity/codecs/s130/serializers/temp_get.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - -#include "nrf_soc.h" -#include "nrf_error.h" -#include "ble_serialization.h" -#include "cond_field_serialization.h" - -uint32_t temp_get_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, - int32_t * * const pp_temp) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(pp_temp); - SER_ASSERT_NOT_NULL(*pp_temp); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - SER_ASSERT_LENGTH_LEQ(1, buf_len); - SER_ASSERT(p_buf[index] == SD_TEMP_GET, NRF_ERROR_INVALID_PARAM); - index++; - - err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_temp, NULL); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - SER_ASSERT_LENGTH_EQ(index, buf_len); - - return err_code; -} - -uint32_t temp_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - int32_t * const p_temp) -{ - SER_ASSERT_NOT_NULL(p_buf); - SER_ASSERT_NOT_NULL(p_temp); - SER_ASSERT_NOT_NULL(p_buf_len); - - uint32_t index = 0; - uint32_t err_code = NRF_SUCCESS; - - uint32_t total_len = *p_buf_len; - - err_code = ser_ble_cmd_rsp_status_code_enc(SD_TEMP_GET, - return_code, - p_buf, - p_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - index += *p_buf_len; - - if (return_code == NRF_SUCCESS) - { - err_code = uint32_t_enc(p_temp, p_buf, total_len, &index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - } - - *p_buf_len = index; - - return err_code; -} diff --git a/components/serialization/connectivity/codecs/s132/middleware/conn_mw.h b/components/serialization/connectivity/codecs/s132/middleware/conn_mw.h new file mode 100644 index 0000000..3bc3abc --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw.h @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 _CONN_MW_H +#define _CONN_MW_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Connectivity Middleware dispatcher function + * + * @details It handles decoding of the opcode from the RX buffer and based on the opcode, it searches + * for registered handler. Handler is called once it is found. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. + */ +uint32_t conn_mw_handler (uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +#ifdef __cplusplus +} +#endif + +#endif //_CONN_MW_H diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble.c b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble.c similarity index 64% rename from components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble.c rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble.c index 5a9de37..5eee498 100644 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble.c +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble.c @@ -1,22 +1,51 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + #include "ble_conn.h" #include "conn_mw_ble.h" #include "ble_serialization.h" #include "conn_ble_user_mem.h" +#include +extern sercon_ble_user_mem_t m_conn_user_mem_table[]; -extern ser_ble_user_mem_t m_conn_user_mem_table[]; - -uint32_t conn_mw_ble_tx_buffer_count_get(uint8_t const * const p_rx_buf, +uint32_t conn_mw_ble_tx_packet_count_get(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) @@ -26,17 +55,18 @@ uint32_t conn_mw_ble_tx_buffer_count_get(uint8_t const * const p_rx_buf, SER_ASSERT_NOT_NULL(p_tx_buf_len); uint8_t count; + uint16_t conn_handle; uint8_t * p_count = &count; uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; - err_code = ble_tx_buffer_count_get_req_dec(p_rx_buf, rx_buf_len, &p_count); + err_code = ble_tx_packet_count_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_count); SER_ASSERT(err_code == NRF_SUCCESS, err_code); - sd_err_code = sd_ble_tx_buffer_count_get(p_count); + sd_err_code = sd_ble_tx_packet_count_get(conn_handle, p_count); - err_code = ble_tx_buffer_count_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_count); + err_code = ble_tx_packet_count_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_count); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; @@ -115,6 +145,7 @@ uint32_t conn_mw_ble_uuid_encode(uint8_t const * const p_rx_buf, uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; + memset(&uuid, 0, sizeof(uuid)); err_code = ble_uuid_encode_req_dec(p_rx_buf, rx_buf_len, &p_uuid, &p_uuid_len, &p_raw_uuid); SER_ASSERT(err_code == NRF_SUCCESS, err_code); @@ -151,33 +182,6 @@ uint32_t conn_mw_ble_version_get(uint8_t const * const p_rx_buf, return err_code; } - -uint32_t conn_mw_ble_enable(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_enable_params_t params; - ble_enable_params_t * p_params = ¶ms; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_enable_req_dec(p_rx_buf, rx_buf_len, &p_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_enable(p_params); - - err_code = ble_enable_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - uint32_t conn_mw_ble_opt_get(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, @@ -197,6 +201,18 @@ uint32_t conn_mw_ble_opt_get(uint8_t const * const p_rx_buf, err_code = ble_opt_get_req_dec(p_rx_buf, rx_buf_len, &opt_id, &p_opt); SER_ASSERT(err_code == NRF_SUCCESS, err_code); + uint16_t act_latency; + uint8_t passkey[BLE_GAP_PASSKEY_LEN]; + /* Initialaize appropriate pointers inside opt union based on opt_id */ + switch (opt_id) + { + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + opt.gap_opt.local_conn_latency.p_actual_latency = &act_latency; + break; + case BLE_GAP_OPT_PASSKEY: + opt.gap_opt.passkey.p_passkey = passkey; + break; + } sd_err_code = sd_ble_opt_get(opt_id, p_opt); err_code = ble_opt_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, opt_id, p_opt); @@ -217,7 +233,6 @@ uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, uint32_t opt_id = 0xFFFFFFFF; uint16_t act_latency; uint8_t passkey[BLE_GAP_PASSKEY_LEN]; - ble_gap_irk_t irk = {{0}}; uint32_t err_code = NRF_SUCCESS; /* Pre-decode type of ble_opt_t union */ @@ -227,7 +242,7 @@ uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, ble_opt_t opt; ble_opt_t *p_opt = &opt; /* Initialaize appropriate pointers inside opt union based on opt_id */ - switch(opt_id) + switch (opt_id) { case BLE_GAP_OPT_LOCAL_CONN_LATENCY: opt.gap_opt.local_conn_latency.p_actual_latency = &act_latency; @@ -235,9 +250,6 @@ uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, case BLE_GAP_OPT_PASSKEY: opt.gap_opt.passkey.p_passkey = passkey; break; - case BLE_GAP_OPT_PRIVACY: - opt.gap_opt.privacy.p_irk = &irk; - break; } uint32_t sd_err_code; @@ -253,6 +265,58 @@ uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, return err_code; } +uint32_t conn_mw_ble_enable(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t app_ram_base; + +/*lint --e{10} --e{19} --e{27} --e{40} --e{529} -save suppress Error 27: Illegal character */ +#if defined(_WIN32) || defined(__unix) || defined(__APPLE__) + uint32_t ram_start = 0; +#elif defined ( __CC_ARM ) + extern uint32_t Image$$RW_IRAM1$$Base; + volatile uint32_t ram_start = (uint32_t) &Image$$RW_IRAM1$$Base; +#elif defined ( __ICCARM__ ) + extern uint32_t __ICFEDIT_region_RAM_start__; + volatile uint32_t ram_start = (uint32_t) &__ICFEDIT_region_RAM_start__; +#elif defined ( __GNUC__ ) + extern uint32_t __start_fs_data; + volatile uint32_t ram_start = (uint32_t) &__start_fs_data; +#endif + app_ram_base = ram_start; + + ble_enable_params_t params; + ble_enable_params_t * p_params = ¶ms; + ble_conn_bw_counts_t conn_bw_counts; + params.common_enable_params.p_conn_bw_counts = &conn_bw_counts; + + uint8_t gap_device_name_value[BLE_GAP_DEVNAME_MAX_LEN]; + ble_gap_device_name_t device_name; + device_name.max_len = BLE_GAP_DEVNAME_MAX_LEN; + device_name.p_value = gap_device_name_value; + params.gap_enable_params.p_device_name = &device_name; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_enable_req_dec(p_rx_buf, rx_buf_len, &p_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + //disabled till codec is adopted. + sd_err_code = sd_ble_enable(p_params, &app_ram_base); + + err_code = ble_enable_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, @@ -262,23 +326,29 @@ uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf, SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); - uint16_t * p_conn_handle; - ble_user_mem_block_t * p_mem_block; + ble_user_mem_block_t mem_block; + ble_user_mem_block_t * p_mem_block = &mem_block; uint32_t err_code = NRF_SUCCESS; uint32_t user_mem_tab_index; - + uint16_t conn_handle; /* Allocate user memory context for SoftDevice */ - err_code = conn_ble_user_mem_context_create(&user_mem_tab_index); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - p_conn_handle = &(m_conn_user_mem_table[user_mem_tab_index].conn_handle); - p_mem_block = &(m_conn_user_mem_table[user_mem_tab_index].mem_block); uint32_t sd_err_code; - err_code = ble_user_mem_reply_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &p_mem_block); + err_code = ble_user_mem_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_mem_block); SER_ASSERT(err_code == NRF_SUCCESS, err_code); - sd_err_code = sd_ble_user_mem_reply(*p_conn_handle, p_mem_block); + if (p_mem_block != NULL) + { + //Use the context if p_mem_block was not null + err_code = conn_ble_user_mem_context_create(&user_mem_tab_index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + m_conn_user_mem_table[user_mem_tab_index].conn_handle = conn_handle; + m_conn_user_mem_table[user_mem_tab_index].mem_block.len = p_mem_block->len; + p_mem_block = &(m_conn_user_mem_table[user_mem_tab_index].mem_block); + } + + sd_err_code = sd_ble_user_mem_reply(conn_handle, p_mem_block); err_code = ble_user_mem_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble.h b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble.h similarity index 79% rename from components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble.h rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble.h index 8698fcc..80c3cd3 100644 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble.h +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble.h @@ -1,20 +1,53 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 _CONN_MW_BLE_H #define _CONN_MW_BLE_H #include -/**@brief Handles @ref sd_ble_tx_buffer_count_get command and prepares response. +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Handles @ref sd_ble_tx_packet_count_get command and prepares response. * * @param[in] p_rx_buf Pointer to input buffer. * @param[in] rx_buf_len Size of p_rx_buf. @@ -27,7 +60,7 @@ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. */ -uint32_t conn_mw_ble_tx_buffer_count_get(uint8_t const * const p_rx_buf, +uint32_t conn_mw_ble_tx_packet_count_get(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len); @@ -139,7 +172,7 @@ uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len); - + /**@brief Handles @ref sd_ble_enable command and prepares response. * * @param[in] p_rx_buf Pointer to input buffer. @@ -176,4 +209,9 @@ uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len); + +#ifdef __cplusplus +} +#endif + #endif //_CONN_MW_BLE_H diff --git a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gap.c b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gap.c similarity index 65% rename from components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gap.c rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gap.c index 79e974b..8b9723c 100644 --- a/components/serialization/connectivity/codecs/s130/middleware/conn_mw_ble_gap.c +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gap.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_gap_conn.h" @@ -18,34 +46,6 @@ extern ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS]; -uint32_t conn_mw_ble_gap_address_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint8_t addr_cycle_mode; - - ble_gap_addr_t addr; - ble_gap_addr_t * p_addr = &addr; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_address_set_req_dec(p_rx_buf, rx_buf_len, &addr_cycle_mode, &p_addr); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_address_set(addr_cycle_mode, p_addr); - - err_code = ble_gap_address_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, @@ -54,33 +54,11 @@ uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf, SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); - + ble_gap_addr_t addr; ble_gap_addr_t * p_addr = &addr; - - ble_gap_addr_t * pp_addr_tab[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t * pp_irk_tab[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - - ble_gap_addr_t addr_tab[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t irk_tab[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - - for (uint8_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; ++i) - { - pp_addr_tab[i] = &addr_tab[i]; - } - for (uint8_t i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; ++i) - { - pp_irk_tab[i] = &irk_tab[i]; - } - - ble_gap_whitelist_t whitelist; - whitelist.addr_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; - whitelist.pp_addrs = pp_addr_tab; - whitelist.irk_count = BLE_GAP_WHITELIST_IRK_MAX_COUNT; - whitelist.pp_irks = pp_irk_tab; ble_gap_scan_params_t scan_params; - scan_params.p_whitelist = &whitelist; ble_gap_scan_params_t * p_scan_params = &scan_params; ble_gap_conn_params_t conn_params; @@ -108,7 +86,7 @@ uint32_t conn_mw_ble_gap_connect_cancel(uint8_t const * const p_rx_buf, SER_ASSERT_NOT_NULL(p_rx_buf); SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); - + uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; @@ -129,29 +107,7 @@ uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf, SER_ASSERT_NOT_NULL(p_tx_buf); SER_ASSERT_NOT_NULL(p_tx_buf_len); - ble_gap_addr_t * pp_addr_tab[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t * pp_irk_tab[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - - ble_gap_addr_t addr_tab[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t irk_tab[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - - for (uint8_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; ++i) - { - pp_addr_tab[i] = &addr_tab[i]; - } - for (uint8_t i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; ++i) - { - pp_irk_tab[i] = &irk_tab[i]; - } - - ble_gap_whitelist_t whitelist; - whitelist.addr_count = BLE_GAP_WHITELIST_ADDR_MAX_COUNT; - whitelist.pp_addrs = pp_addr_tab; - whitelist.irk_count = BLE_GAP_WHITELIST_IRK_MAX_COUNT; - whitelist.pp_irks = pp_irk_tab; - ble_gap_scan_params_t scan_params; - scan_params.p_whitelist = &whitelist; ble_gap_scan_params_t * p_scan_params = &scan_params; uint32_t err_code = NRF_SUCCESS; @@ -168,32 +124,6 @@ uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf, return err_code; } -uint32_t conn_mw_ble_gap_address_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len) -{ - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - ble_gap_addr_t addr; - ble_gap_addr_t * p_addr = &addr; - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - err_code = ble_gap_address_get_req_dec(p_rx_buf, rx_buf_len, &p_addr); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - sd_err_code = sd_ble_gap_address_get(p_addr); - - err_code = ble_gap_address_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_addr); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); - - return err_code; -} - uint32_t conn_mw_ble_gap_adv_data_set(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, @@ -235,51 +165,29 @@ uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len) { - SER_ASSERT_NOT_NULL(p_rx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf); - SER_ASSERT_NOT_NULL(p_tx_buf_len); - - uint32_t err_code = NRF_SUCCESS; - uint32_t sd_err_code; - - ble_gap_addr_t * p_addresses[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_addr_t addresses[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; - ble_gap_irk_t * p_irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - ble_gap_irk_t irks[BLE_GAP_WHITELIST_IRK_MAX_COUNT]; - ble_gap_addr_t peer_addr; - ble_gap_whitelist_t whitelist; - ble_gap_adv_params_t adv_params; - ble_gap_adv_params_t * p_adv_params; - - uint32_t i = 0; - - for (i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++) - { - p_addresses[i] = &(addresses[i]); - } - - for (i = 0; i < BLE_GAP_WHITELIST_IRK_MAX_COUNT; i++) - { - p_irks[i] = &(irks[i]); - } + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); - whitelist.pp_addrs = &p_addresses[0]; - whitelist.pp_irks = &p_irks[0]; + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; - adv_params.p_peer_addr = &peer_addr; - adv_params.p_whitelist = &whitelist; + ble_gap_addr_t peer_addr; + ble_gap_adv_params_t adv_params; + ble_gap_adv_params_t * p_adv_params; - p_adv_params = &adv_params; + adv_params.p_peer_addr = &peer_addr; + p_adv_params = &adv_params; - err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); + err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); - sd_err_code = sd_ble_gap_adv_start(p_adv_params); + sd_err_code = sd_ble_gap_adv_start(p_adv_params); - err_code = ble_gap_adv_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); - SER_ASSERT(err_code == NRF_SUCCESS, err_code); + err_code = ble_gap_adv_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); - return err_code; + return err_code; } uint32_t conn_mw_ble_gap_adv_stop(uint8_t const * const p_rx_buf, @@ -484,7 +392,6 @@ uint32_t conn_mw_ble_gap_ppcp_get(uint8_t const * const p_rx_buf, return err_code; } - uint32_t conn_mw_ble_gap_device_name_get(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, @@ -508,7 +415,7 @@ uint32_t conn_mw_ble_gap_device_name_get(uint8_t const * const p_rx_buf, sd_err_code = sd_ble_gap_device_name_get(p_dev_name, p_len); - err_code = ble_gap_device_name_get_rsp_enc(sd_err_code, p_dev_name, len, p_tx_buf, p_tx_buf_len); + err_code = ble_gap_device_name_get_rsp_enc(sd_err_code, p_dev_name, p_len, p_tx_buf, p_tx_buf_len); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; @@ -595,7 +502,7 @@ uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf, ble_gap_sec_params_t sec_params; ble_gap_sec_params_t * p_sec_params = &sec_params; - + // Allocate global security context for soft device err_code = conn_ble_gap_sec_context_create(&sec_tab_index); SER_ASSERT(err_code == NRF_SUCCESS, err_code); @@ -604,12 +511,14 @@ uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf, // Set up global structure for command decoder ble_gap_sec_keyset_t * p_sec_keyset = &(m_conn_keys_table[sec_tab_index].keyset); - p_sec_keyset->keys_periph.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_periph); - p_sec_keyset->keys_periph.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_periph); - p_sec_keyset->keys_periph.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_periph); - p_sec_keyset->keys_central.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_central); - p_sec_keyset->keys_central.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_central); - p_sec_keyset->keys_central.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_central); + p_sec_keyset->keys_own.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_own); + p_sec_keyset->keys_own.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_own); + p_sec_keyset->keys_own.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_own); + p_sec_keyset->keys_own.p_pk = &(m_conn_keys_table[sec_tab_index].pk_own); + p_sec_keyset->keys_peer.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_peer); + p_sec_keyset->keys_peer.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_peer); + p_sec_keyset->keys_peer.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_peer); + p_sec_keyset->keys_peer.p_pk = &(m_conn_keys_table[sec_tab_index].pk_peer); err_code = ble_gap_sec_params_reply_req_dec(p_rx_buf, rx_buf_len, @@ -619,6 +528,12 @@ uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf, &p_sec_keyset); SER_ASSERT(err_code == NRF_SUCCESS, err_code); + if (p_sec_keyset == NULL) + { + //If no keyset was sent destroy the context. + err_code = conn_ble_gap_sec_context_destroy(*p_conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } sd_err_code = sd_ble_gap_sec_params_reply(*p_conn_handle, sec_status, p_sec_params, p_sec_keyset); err_code = ble_gap_sec_params_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sec_keyset); @@ -672,7 +587,7 @@ uint32_t conn_mw_ble_gap_sec_info_reply(uint8_t const * const p_rx_buf, ble_gap_enc_info_t enc_info; ble_gap_enc_info_t * p_enc_info = &enc_info; - + ble_gap_irk_t id_info; ble_gap_irk_t * p_id_info = &id_info; @@ -852,3 +767,299 @@ uint32_t conn_mw_ble_gap_rssi_get(uint8_t const * const p_rx_buf, return err_code; } + +uint32_t conn_mw_ble_gap_keypress_notify(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + uint8_t kp_not; + + err_code = ble_gap_keypress_notify_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &kp_not); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_keypress_notify(conn_handle, kp_not); + + err_code = ble_gap_keypress_notify_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_lesc_dhkey_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + ble_gap_lesc_dhkey_t dhkey; + ble_gap_lesc_dhkey_t * p_dhkey = &dhkey; + + err_code = ble_gap_lesc_dhkey_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_dhkey); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_lesc_dhkey_reply(conn_handle, p_dhkey); + + err_code = ble_gap_lesc_dhkey_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_lesc_oob_data_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + ble_gap_lesc_oob_data_t own; + ble_gap_lesc_oob_data_t peer; + ble_gap_lesc_oob_data_t * p_own = &own; + ble_gap_lesc_oob_data_t * p_peer = &peer; + + err_code = ble_gap_lesc_oob_data_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_own, &p_peer); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_lesc_oob_data_set(conn_handle, p_own, p_peer); + + err_code = ble_gap_lesc_oob_data_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_lesc_oob_data_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint16_t conn_handle; + ble_gap_lesc_oob_data_t own; + ble_gap_lesc_oob_data_t * p_own = &own; + ble_gap_lesc_p256_pk_t pk; + ble_gap_lesc_p256_pk_t * p_pk = &pk; + + err_code = ble_gap_lesc_oob_data_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_pk, &p_own); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + sd_err_code = sd_ble_gap_lesc_oob_data_get(conn_handle, p_pk, p_own); + + err_code = ble_gap_lesc_oob_data_get_rsp_enc(sd_err_code, p_own, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_addr_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_gap_addr_t addr; + ble_gap_addr_t * p_addr = &addr; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_addr_set_req_dec(p_rx_buf, rx_buf_len, &p_addr); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_addr_set(p_addr); + + err_code = ble_gap_addr_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} +uint32_t conn_mw_ble_gap_addr_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + ble_gap_addr_t addr; + ble_gap_addr_t * p_addr = &addr; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gap_addr_get_req_dec(p_rx_buf, rx_buf_len, &p_addr); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_addr_get(p_addr); + + err_code = ble_gap_addr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_addr); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_privacy_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + ble_gap_privacy_params_t privacy_params; + ble_gap_privacy_params_t * p_privacy_params = &privacy_params; + + ble_gap_irk_t irk; + privacy_params.p_device_irk = &irk; + + err_code = ble_gap_privacy_set_req_dec(p_rx_buf, rx_buf_len, &p_privacy_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_privacy_set(p_privacy_params); + + err_code = ble_gap_privacy_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + + +uint32_t conn_mw_ble_gap_privacy_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + ble_gap_privacy_params_t privacy_params; + ble_gap_privacy_params_t * p_privacy_params = &privacy_params; + + ble_gap_irk_t irk; + privacy_params.p_device_irk = &irk; + + err_code = ble_gap_privacy_get_req_dec(p_rx_buf, rx_buf_len, &p_privacy_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_privacy_get(p_privacy_params); + + err_code = ble_gap_privacy_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_privacy_params); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_whitelist_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint8_t length; + ble_gap_addr_t wl_addr_array[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + ble_gap_addr_t * p_wl_addrs_array[BLE_GAP_WHITELIST_ADDR_MAX_COUNT]; + + for (uint8_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; ++i) + { + p_wl_addrs_array[i] = &wl_addr_array[i]; + } + + ble_gap_addr_t * * pp_wl_addrs = p_wl_addrs_array; + + err_code = ble_gap_whitelist_set_req_dec(p_rx_buf, rx_buf_len, &pp_wl_addrs, &length); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + sd_err_code = sd_ble_gap_whitelist_set((ble_gap_addr_t const * *)pp_wl_addrs, length); + + err_code = ble_gap_whitelist_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gap_device_identities_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + uint8_t length; + ble_gap_id_key_t id_key_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + ble_gap_id_key_t * p_id_key_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + ble_gap_irk_t irk_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + ble_gap_irk_t * p_irk_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT]; + + for (uint8_t i = 0; i < BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT; ++i) + { + p_id_key_array[i] = &id_key_array[i]; + p_irk_array[i] = &irk_array[i]; + } + + ble_gap_id_key_t * * pp_id_keys = p_id_key_array; + ble_gap_irk_t * * pp_local_irks = p_irk_array; + + err_code = ble_gap_device_identities_set_req_dec(p_rx_buf, rx_buf_len, + &pp_id_keys, + &pp_local_irks, + &length); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gap_device_identities_set((ble_gap_id_key_t const * *) pp_id_keys, + (ble_gap_irk_t const * *) pp_local_irks, + length); + + err_code = ble_gap_device_identities_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gap.h b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gap.h similarity index 70% rename from components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gap.h rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gap.h index c1fff5a..b428011 100644 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gap.h +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gap.h @@ -1,54 +1,51 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 _CONN_MW_BLE_GAP_H #define _CONN_MW_BLE_GAP_H #include -/**@brief Handles @ref sd_ble_gap_address_set command request and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_address_set(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); - -/**@brief Handles @ref sd_ble_gap_address_get command request and prepares response. - * - * @param[in] p_rx_buf Pointer to input buffer. - * @param[in] rx_buf_len Size of p_rx_buf. - * @param[out] p_tx_buf Pointer to output buffer. - * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. - * \c out: Length of valid data in \p p_tx_buf. - * - * @retval NRF_SUCCESS Handler success. - * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. - */ -uint32_t conn_mw_ble_gap_address_get(uint8_t const * const p_rx_buf, - uint32_t rx_buf_len, - uint8_t * const p_tx_buf, - uint32_t * const p_tx_buf_len); +#ifdef __cplusplus +extern "C" { +#endif /**@brief Handles @ref sd_ble_gap_adv_data_set command and prepares response. * @@ -501,32 +498,220 @@ uint32_t conn_mw_ble_gap_encrypt(uint8_t const * const p_rx_buf, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len); -/**@brief allocates instance in m_conn_keys_table[] for storage of encryption keys. +/**@brief Handles @ref sd_ble_gap_keypress_notify command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ + +uint32_t conn_mw_ble_gap_keypress_notify(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_lesc_dhkey_reply command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ + +uint32_t conn_mw_ble_gap_lesc_dhkey_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_lesc_oob_data_set command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ + +uint32_t conn_mw_ble_gap_lesc_oob_data_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_lesc_oob_data_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ + +uint32_t conn_mw_ble_gap_lesc_oob_data_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Allocates instance in m_conn_keys_table[] for storage of encryption keys. * * @param[in] conn_handle conn_handle - * @param[out] p_index pointer to the index of allocated instance + * @param[out] p_index Pointer to the index of allocated instance. * - * @retval NRF_SUCCESS great success. - * @retval NRF_ERROR_NO_MEM no free instance available. + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NO_MEM No free instance available. */ uint32_t conn_mw_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index); -/**@brief release instance identified by a connection handle. +/**@brief Releases the instance identified by a connection handle. * * @param[in] conn_handle conn_handle - * - * @retval NRF_SUCCESS great success - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found + + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found. */ uint32_t conn_mw_ble_gap_sec_context_destroy(uint16_t conn_handle); -/**@brief finds index of instance identified by a connection handle in m_conn_keys_table[]. +/**@brief Finds index of instance identified by a connection handle in m_conn_keys_table[]. * * @param[in] conn_handle conn_handle * - * @retval NRF_SUCCESS great success - * @retval NRF_ERROR_NOT_FOUND instance with conn_handle not found + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found. */ uint32_t conn_mw_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); +/**@brief Handles @ref sd_ble_gap_addr_set command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_addr_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_addr_get command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_addr_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_privacy_set command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_privacy_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_privacy_get command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_privacy_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_whitelist_get command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_whitelist_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gap_device_identities_set command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gap_device_identities_set(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +#ifdef __cplusplus +} +#endif + #endif //_CONN_MW_BLE_GAP_H diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gattc.c b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gattc.c similarity index 72% rename from components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gattc.c rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gattc.c index d41ac4d..2038cd2 100644 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gattc.c +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gattc.c @@ -1,14 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + #include "ble_gattc_conn.h" #include "conn_mw_ble_gattc.h" #include "ble_serialization.h" @@ -291,3 +320,58 @@ uint32_t conn_mw_ble_gattc_hv_confirm(uint8_t const * const p_rx_buf, return err_code; } + +uint32_t conn_mw_ble_gattc_attr_info_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t * p_conn_handle = &conn_handle; + + ble_gattc_handle_range_t range = {0}; + ble_gattc_handle_range_t * p_range = ⦥ + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_attr_info_discover_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &p_range); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_attr_info_discover(conn_handle, p_range); + + err_code = ble_gattc_attr_info_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gattc_exchange_mtu_request(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t client_rx_mtu; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gattc_exchange_mtu_request_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &client_rx_mtu); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gattc_exchange_mtu_request(conn_handle, client_rx_mtu); + + err_code = ble_gattc_exchange_mtu_request_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gattc.h b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gattc.h similarity index 69% rename from components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gattc.h rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gattc.h index 403ae11..4138a1b 100644 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_gattc.h +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gattc.h @@ -1,19 +1,52 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 _CONN_MW_BLE_GATTC_H #define _CONN_MW_BLE_GATTC_H #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Handles @ref sd_ble_gattc_primary_services_discover command and prepares response. * * @param[in] p_rx_buf Pointer to input buffer. @@ -176,5 +209,44 @@ uint32_t conn_mw_ble_gattc_hv_confirm (uint8_t const *const rx_buf, uint8_t *const tx_buf, uint32_t *const p_tx_buf_len); +/**@brief Handles @ref sd_ble_gattc_attr_info_discover command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_attr_info_discover(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ble_gattc_exchange_mtu_request command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gattc_exchange_mtu_request(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +#ifdef __cplusplus +} +#endif #endif //_CONN_MW_BLE_GATTC_H diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gatts.c b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gatts.c similarity index 72% rename from components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gatts.c rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gatts.c index 018c5ce..379d168 100644 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gatts.c +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gatts.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_gatts_conn.h" @@ -171,7 +199,7 @@ uint32_t conn_mw_ble_gatts_descriptor_add(uint8_t const * const p_rx_buf, sd_err_code = sd_ble_gatts_descriptor_add(char_handle, p_attr, p_handle); - err_code = ble_gatts_descriptor_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, handle); + err_code = ble_gatts_descriptor_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle); SER_ASSERT(err_code == NRF_SUCCESS, err_code); return err_code; @@ -189,20 +217,20 @@ uint32_t conn_mw_ble_gatts_value_set(uint8_t const * const p_rx_buf, uint16_t conn_handle; uint16_t handle; uint8_t attr_val_table[BLE_GATTS_VAR_ATTR_LEN_MAX]; - ble_gatts_value_t attr_val = + ble_gatts_value_t attr_val = { .len = sizeof (attr_val_table), .offset = 0, .p_value = attr_val_table }; - ble_gatts_value_t * p_attr_val = &attr_val; + ble_gatts_value_t * p_attr_val = &attr_val; uint32_t err_code = NRF_SUCCESS; uint32_t sd_err_code; err_code = ble_gatts_value_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_val); SER_ASSERT(err_code == NRF_SUCCESS, err_code); - + sd_err_code = sd_ble_gatts_value_set(conn_handle, handle, p_attr_val); err_code = ble_gatts_value_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_val); @@ -233,7 +261,6 @@ uint32_t conn_mw_ble_gatts_value_get(uint8_t const * const p_rx_buf, err_code = ble_gatts_value_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_value); SER_ASSERT(err_code == NRF_SUCCESS, err_code); - sd_err_code = sd_ble_gatts_value_get(conn_handle, handle, p_attr_value); err_code = ble_gatts_value_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_value); @@ -353,7 +380,7 @@ uint32_t conn_mw_ble_gatts_sys_attr_set(uint8_t const * const p_rx_buf, uint8_t * p_sys_attr = sys_attr; uint16_t sys_attr_len = sizeof (sys_attr); - + uint32_t flags; uint32_t err_code = NRF_SUCCESS; @@ -387,7 +414,7 @@ uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf, uint8_t * p_sys_attr = sys_attr; uint16_t sys_attr_len = sizeof (sys_attr); uint16_t * p_sys_attr_len = &sys_attr_len; - + uint32_t flags; uint32_t err_code = NRF_SUCCESS; @@ -405,3 +432,87 @@ uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf, return err_code; } + +uint32_t conn_mw_ble_gatts_attr_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t handle; + + ble_gatts_attr_md_t md; + ble_gatts_attr_md_t * p_md = &md; + ble_uuid_t uuid; + ble_uuid_t * p_uuid = &uuid; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_attr_get_req_dec(p_rx_buf, rx_buf_len, &handle, &p_uuid, &p_md); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_attr_get(handle, p_uuid, p_md); + + err_code = ble_gatts_attr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid, p_md); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_initial_user_handle_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t handle; + uint16_t * p_handle = &handle; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_initial_user_handle_get_req_dec(p_rx_buf, rx_buf_len, &p_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_initial_user_handle_get(p_handle); + + err_code = ble_gatts_initial_user_handle_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ble_gatts_exchange_mtu_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint16_t conn_handle; + uint16_t * p_conn_handle = &conn_handle; + uint16_t server_rx_mtu; + uint16_t * p_server_rx_mtu = &server_rx_mtu; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ble_gatts_exchange_mtu_reply_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_server_rx_mtu); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ble_gatts_exchange_mtu_reply(conn_handle, server_rx_mtu); + + err_code = ble_gatts_exchange_mtu_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} diff --git a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gatts.h b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gatts.h similarity index 68% rename from components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gatts.h rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gatts.h index d61865a..df94808 100644 --- a/components/serialization/connectivity/codecs/s110/middleware/conn_mw_ble_gatts.h +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_gatts.h @@ -1,20 +1,52 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 _CONN_MW_BLE_GATTS_H #define _CONN_MW_BLE_GATTS_H - + #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Handles @ref sd_ble_gatts_service_add command and prepares response. * * @param[in] p_rx_buf Pointer to input buffer. @@ -212,5 +244,64 @@ uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf, uint32_t rx_buf_len, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_attr_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_attr_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_ble_gatts_initial_user_handle_get command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_initial_user_handle_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref conn_mw_bble_gatts_exchange_mtu_reply command and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + */ +uint32_t conn_mw_ble_gatts_exchange_mtu_reply(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +#ifdef __cplusplus +} +#endif + #endif //_CONN_MW_BLE_GATTS_H diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_l2cap.c b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_l2cap.c similarity index 57% rename from components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_l2cap.c rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_l2cap.c index a3134b0..7d85a44 100644 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_l2cap.c +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_l2cap.c @@ -1,14 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + #include "ble_l2cap_conn.h" #include "conn_mw_ble_l2cap.h" #include "ble_serialization.h" diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_l2cap.h b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_l2cap.h similarity index 59% rename from components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_l2cap.h rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_l2cap.h index dd6ac2e..2189a5f 100644 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_ble_l2cap.h +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_ble_l2cap.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 _CONN_MW_BLE_L2CAP_H_ @@ -15,6 +43,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Handles @ref sd_ble_l2cap_cid_register command and prepares response. * * @param[in] p_rx_buf Pointer to input buffer. @@ -69,4 +101,9 @@ uint32_t conn_mw_ble_l2cap_tx(uint8_t const * const p_rx_buf, uint8_t * const p_tx_buf, uint32_t * const p_tx_buf_len); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_items.c b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_items.c similarity index 55% rename from components/serialization/connectivity/codecs/s120/middleware/conn_mw_items.c rename to components/serialization/connectivity/codecs/s132/middleware/conn_mw_items.c index 6db81a1..b7eff96 100644 --- a/components/serialization/connectivity/codecs/s120/middleware/conn_mw_items.c +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_items.c @@ -1,3 +1,43 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + #include "conn_mw_nrf_soc.h" #include "conn_mw_ble.h" #include "conn_mw_ble_l2cap.h" @@ -10,8 +50,9 @@ static const conn_mw_item_t conn_mw_item[] = { //Functions from nrf_soc.h {SD_POWER_SYSTEM_OFF, conn_mw_power_system_off}, {SD_TEMP_GET, conn_mw_temp_get}, + {SD_ECB_BLOCK_ENCRYPT, conn_mw_ecb_block_encrypt}, //Functions from ble.h - {SD_BLE_TX_BUFFER_COUNT_GET, conn_mw_ble_tx_buffer_count_get}, + {SD_BLE_TX_PACKET_COUNT_GET, conn_mw_ble_tx_packet_count_get}, {SD_BLE_UUID_VS_ADD, conn_mw_ble_uuid_vs_add}, {SD_BLE_UUID_DECODE, conn_mw_ble_uuid_decode}, {SD_BLE_UUID_ENCODE, conn_mw_ble_uuid_encode}, @@ -19,19 +60,24 @@ static const conn_mw_item_t conn_mw_item[] = { {SD_BLE_OPT_GET, conn_mw_ble_opt_get}, {SD_BLE_OPT_SET, conn_mw_ble_opt_set}, {SD_BLE_ENABLE, conn_mw_ble_enable}, + {SD_BLE_USER_MEM_REPLY, conn_mw_ble_user_mem_reply}, //Functions from ble_l2cap.h {SD_BLE_L2CAP_CID_REGISTER, conn_mw_ble_l2cap_cid_register}, {SD_BLE_L2CAP_CID_UNREGISTER, conn_mw_ble_l2cap_cid_unregister}, {SD_BLE_L2CAP_TX, conn_mw_ble_l2cap_tx}, //Functions from ble_gap.h {SD_BLE_GAP_SCAN_STOP, conn_mw_ble_gap_scan_stop}, - {SD_BLE_GAP_ADDRESS_SET, conn_mw_ble_gap_address_set}, + {SD_BLE_GAP_ADDR_SET, conn_mw_ble_gap_addr_set}, + {SD_BLE_GAP_ADDR_GET, conn_mw_ble_gap_addr_get}, + {SD_BLE_GAP_PRIVACY_SET, conn_mw_ble_gap_privacy_set}, + {SD_BLE_GAP_PRIVACY_GET, conn_mw_ble_gap_privacy_get}, + {SD_BLE_GAP_WHITELIST_SET, conn_mw_ble_gap_whitelist_set}, + {SD_BLE_GAP_DEVICE_IDENTITIES_SET, conn_mw_ble_gap_device_identities_set}, {SD_BLE_GAP_CONNECT, conn_mw_ble_gap_connect}, {SD_BLE_GAP_CONNECT_CANCEL, conn_mw_ble_gap_connect_cancel}, {SD_BLE_GAP_SCAN_START, conn_mw_ble_gap_scan_start}, {SD_BLE_GAP_SEC_INFO_REPLY, conn_mw_ble_gap_sec_info_reply}, {SD_BLE_GAP_ENCRYPT, conn_mw_ble_gap_encrypt}, - {SD_BLE_GAP_ADDRESS_GET, conn_mw_ble_gap_address_get}, {SD_BLE_GAP_ADV_DATA_SET, conn_mw_ble_gap_adv_data_set}, {SD_BLE_GAP_ADV_START, conn_mw_ble_gap_adv_start}, {SD_BLE_GAP_ADV_STOP, conn_mw_ble_gap_adv_stop}, @@ -51,6 +97,10 @@ static const conn_mw_item_t conn_mw_item[] = { {SD_BLE_GAP_CONN_SEC_GET, conn_mw_ble_gap_conn_sec_get}, {SD_BLE_GAP_RSSI_START, conn_mw_ble_gap_rssi_start}, {SD_BLE_GAP_RSSI_STOP, conn_mw_ble_gap_rssi_stop}, + {SD_BLE_GAP_KEYPRESS_NOTIFY, conn_mw_ble_gap_keypress_notify}, + {SD_BLE_GAP_LESC_DHKEY_REPLY, conn_mw_ble_gap_lesc_dhkey_reply}, + {SD_BLE_GAP_LESC_OOB_DATA_SET, conn_mw_ble_gap_lesc_oob_data_set}, + {SD_BLE_GAP_LESC_OOB_DATA_GET, conn_mw_ble_gap_lesc_oob_data_get}, {SD_BLE_GAP_RSSI_GET, conn_mw_ble_gap_rssi_get}, //Functions from ble_gattc.h {SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, conn_mw_ble_gattc_primary_services_discover}, @@ -62,6 +112,8 @@ static const conn_mw_item_t conn_mw_item[] = { {SD_BLE_GATTC_CHAR_VALUES_READ, conn_mw_ble_gattc_char_values_read}, {SD_BLE_GATTC_WRITE, conn_mw_ble_gattc_write}, {SD_BLE_GATTC_HV_CONFIRM, conn_mw_ble_gattc_hv_confirm}, + {SD_BLE_GATTC_ATTR_INFO_DISCOVER, conn_mw_ble_gattc_attr_info_discover}, + {SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, conn_mw_ble_gattc_exchange_mtu_request}, //Functions from ble_gatts.h {SD_BLE_GATTS_SERVICE_ADD, conn_mw_ble_gatts_service_add}, {SD_BLE_GATTS_INCLUDE_ADD, conn_mw_ble_gatts_include_add}, @@ -74,4 +126,7 @@ static const conn_mw_item_t conn_mw_item[] = { {SD_BLE_GATTS_RW_AUTHORIZE_REPLY, conn_mw_ble_gatts_rw_authorize_reply}, {SD_BLE_GATTS_SYS_ATTR_SET, conn_mw_ble_gatts_sys_attr_set}, {SD_BLE_GATTS_SYS_ATTR_GET, conn_mw_ble_gatts_sys_attr_get}, + {SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, conn_mw_ble_gatts_initial_user_handle_get}, + {SD_BLE_GATTS_ATTR_GET, conn_mw_ble_gatts_attr_get}, + {SD_BLE_GATTS_EXCHANGE_MTU_REPLY, conn_mw_ble_gatts_exchange_mtu_reply}, }; diff --git a/components/serialization/connectivity/codecs/s132/middleware/conn_mw_nrf_soc.c b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_nrf_soc.c new file mode 100644 index 0000000..a85eed2 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_nrf_soc.c @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_soc_conn.h" +#include "conn_mw_nrf_soc.h" +#include "ble_serialization.h" + +uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + uint32_t err_code = NRF_SUCCESS; + + err_code = power_system_off_req_dec(p_rx_buf, rx_buf_len); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = sd_power_system_off(); + /* There should be no return from sd_power_system_off() */ + + return err_code; +} + +uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + int32_t temperature; + int32_t * p_temperature = &temperature; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = temp_get_req_dec(p_rx_buf, rx_buf_len, &p_temperature); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_temp_get(p_temperature); + + err_code = temp_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_temperature); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} + +uint32_t conn_mw_ecb_block_encrypt(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len) +{ + SER_ASSERT_NOT_NULL(p_rx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf); + SER_ASSERT_NOT_NULL(p_tx_buf_len); + + nrf_ecb_hal_data_t ecb_data; + nrf_ecb_hal_data_t * p_ecb_data = &ecb_data; + + uint32_t err_code = NRF_SUCCESS; + uint32_t sd_err_code; + + err_code = ecb_block_encrypt_req_dec(p_rx_buf, rx_buf_len, &p_ecb_data); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + sd_err_code = sd_ecb_block_encrypt(p_ecb_data); + + err_code = ecb_block_encrypt_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_ecb_data); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + return err_code; +} diff --git a/components/serialization/connectivity/codecs/s132/middleware/conn_mw_nrf_soc.h b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_nrf_soc.h new file mode 100644 index 0000000..5312079 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/middleware/conn_mw_nrf_soc.h @@ -0,0 +1,112 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 CONN_MW_NRF_SOC_H__ +#define CONN_MW_NRF_SOC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Handles @ref sd_power_system_off command request. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. + */ +uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_temp_get command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. + */ +uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + +/**@brief Handles @ref sd_ecb_block_encrypt command request and prepares response. + * + * @param[in] p_rx_buf Pointer to input buffer. + * @param[in] rx_buf_len Size of p_rx_buf. + * @param[out] p_tx_buf Pointer to output buffer. + * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer. + * \c out: Length of valid data in \p p_tx_buf. + * + * @retval NRF_SUCCESS Handler success. + * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type. + * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported. + */ +uint32_t conn_mw_ecb_block_encrypt(uint8_t const * const p_rx_buf, + uint32_t rx_buf_len, + uint8_t * const p_tx_buf, + uint32_t * const p_tx_buf_len); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_conn.c b/components/serialization/connectivity/codecs/s132/serializers/ble_conn.c new file mode 100644 index 0000000..ff5d5b7 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_conn.c @@ -0,0 +1,445 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include "ble_conn.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "app_util.h" + + +uint32_t ble_enable_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_enable_params_t * * const pp_ble_enable_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_ENABLE); + SER_PULL_COND(pp_ble_enable_params, ble_enable_params_t_dec); + SER_REQ_DEC_END; +} + + +uint32_t ble_enable_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_ENABLE); +} + + +uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint32_t * const p_opt_id, + ble_opt_t **const pp_opt ) +{ + SER_REQ_DEC_BEGIN(SD_BLE_OPT_GET); + + SER_ASSERT_NOT_NULL(p_opt_id); + SER_ASSERT_NOT_NULL(pp_opt); + SER_ASSERT_NOT_NULL(*pp_opt); + + SER_PULL_uint32(p_opt_id); + SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_CONN_BW) || + (*p_opt_id == BLE_COMMON_OPT_PA_LNA) || + (*p_opt_id == BLE_COMMON_OPT_CONN_EVT_EXT) || + (*p_opt_id == BLE_GAP_OPT_CH_MAP) || + (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || + (*p_opt_id == BLE_GAP_OPT_PASSKEY) || + (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || + (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE) || + (*p_opt_id == BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT) || + (*p_opt_id == BLE_GAP_OPT_EXT_LEN)), NRF_ERROR_INVALID_PARAM); + + SER_PULL_COND(pp_opt, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_opt_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint32_t opt_id, + ble_opt_t const * const p_opt) +{ + SER_RSP_ENC_BEGIN(SD_BLE_OPT_GET); + + SER_ASSERT_NOT_NULL(p_opt); + SER_ASSERT(((opt_id == BLE_COMMON_OPT_CONN_BW) || + (opt_id == BLE_COMMON_OPT_PA_LNA) || + (opt_id == BLE_COMMON_OPT_CONN_EVT_EXT) || + (opt_id == BLE_GAP_OPT_CH_MAP) || + (opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || + (opt_id == BLE_GAP_OPT_PASSKEY) || + (opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || + (opt_id == BLE_GAP_OPT_COMPAT_MODE) || + (opt_id == BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT) || + (opt_id == BLE_GAP_OPT_EXT_LEN)), NRF_ERROR_INVALID_PARAM); + + SER_PUSH_uint32(&opt_id); + + field_encoder_handler_t fp_encoder = NULL; + void const * p_struct = NULL; + + switch (opt_id) + { + case BLE_COMMON_OPT_CONN_BW: + fp_encoder = ble_common_opt_conn_bw_t_enc; + p_struct = &p_opt->common_opt.conn_bw; + break; + case BLE_COMMON_OPT_PA_LNA: + fp_encoder = ble_common_opt_pa_lna_t_enc; + p_struct = &p_opt->common_opt.pa_lna; + break; + case BLE_COMMON_OPT_CONN_EVT_EXT: + fp_encoder = ble_common_opt_conn_evt_ext_t_enc; + p_struct = &p_opt->common_opt.conn_evt_ext; + break; + case BLE_GAP_OPT_CH_MAP: + fp_encoder = ble_gap_opt_ch_map_t_enc; + p_struct = &p_opt->gap_opt.ch_map; + break; + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + fp_encoder = ble_gap_opt_local_conn_latency_t_enc; + p_struct = &p_opt->gap_opt.local_conn_latency; + break; + case BLE_GAP_OPT_PASSKEY: + fp_encoder = ble_gap_opt_passkey_t_enc; + p_struct = &p_opt->gap_opt.passkey; + break; + case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT: + fp_encoder = ble_gap_opt_auth_payload_timeout_t_enc; + p_struct = &p_opt->gap_opt.auth_payload_timeout; + break; + case BLE_GAP_OPT_EXT_LEN: + fp_encoder = ble_gap_opt_ext_len_t_enc; + p_struct = &p_opt->gap_opt.ext_len; + break; + case BLE_GAP_OPT_SCAN_REQ_REPORT: + fp_encoder = ble_gap_opt_scan_req_report_t_enc; + p_struct = &p_opt->gap_opt.scan_req_report; + break; + case BLE_GAP_OPT_COMPAT_MODE: + fp_encoder = ble_gap_opt_compat_mode_t_enc; + p_struct = &p_opt->gap_opt.compat_mode; + break; + default: + SER_ASSERT(NRF_ERROR_INVALID_PARAM, NRF_ERROR_INVALID_PARAM); + break; + } + + SER_PUSH_FIELD(p_struct, fp_encoder); + + SER_RSP_ENC_END; +} + + +uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint32_t * const p_opt_id, + ble_opt_t **const pp_opt ) +{ + SER_REQ_DEC_BEGIN(SD_BLE_OPT_SET); + + SER_ASSERT_NOT_NULL(p_opt_id); + SER_ASSERT_NOT_NULL(pp_opt); + SER_ASSERT_NOT_NULL(*pp_opt); + + SER_PULL_uint32(p_opt_id); + SER_ASSERT(((*p_opt_id == BLE_COMMON_OPT_CONN_BW) || + (*p_opt_id == BLE_COMMON_OPT_PA_LNA) || + (*p_opt_id == BLE_COMMON_OPT_CONN_EVT_EXT) || + (*p_opt_id == BLE_GAP_OPT_CH_MAP) || + (*p_opt_id == BLE_GAP_OPT_LOCAL_CONN_LATENCY) || + (*p_opt_id == BLE_GAP_OPT_PASSKEY) || + (*p_opt_id == BLE_GAP_OPT_SCAN_REQ_REPORT) || + (*p_opt_id == BLE_GAP_OPT_COMPAT_MODE) || + (*p_opt_id == BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT) || + (*p_opt_id == BLE_GAP_OPT_EXT_LEN)), NRF_ERROR_INVALID_PARAM); + + SER_PULL_COND(pp_opt, NULL); + if (*pp_opt) + { + field_decoder_handler_t fp_decoder = NULL; + void * p_struct = NULL; + + switch(*p_opt_id) + { + case BLE_COMMON_OPT_CONN_BW: + fp_decoder = ble_common_opt_conn_bw_t_dec; + p_struct = &((*pp_opt)->common_opt.conn_bw); + break; + case BLE_COMMON_OPT_PA_LNA: + fp_decoder = ble_common_opt_pa_lna_t_dec; + p_struct = &((*pp_opt)->common_opt.pa_lna); + break; + case BLE_COMMON_OPT_CONN_EVT_EXT: + fp_decoder = ble_common_opt_conn_evt_ext_t_dec; + p_struct = &((*pp_opt)->common_opt.conn_evt_ext); + break; + case BLE_GAP_OPT_CH_MAP: + fp_decoder = ble_gap_opt_ch_map_t_dec; + p_struct = &((*pp_opt)->gap_opt.ch_map); + break; + case BLE_GAP_OPT_LOCAL_CONN_LATENCY: + fp_decoder = ble_gap_opt_local_conn_latency_t_dec; + p_struct = &((*pp_opt)->gap_opt.local_conn_latency); + break; + case BLE_GAP_OPT_PASSKEY: + fp_decoder = ble_gap_opt_passkey_t_dec; + p_struct = &((*pp_opt)->gap_opt.passkey); + break; + case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT: + fp_decoder = ble_gap_opt_auth_payload_timeout_t_dec; + p_struct = &((*pp_opt)->gap_opt.auth_payload_timeout); + break; + case BLE_GAP_OPT_EXT_LEN: + fp_decoder = ble_gap_opt_ext_len_t_dec; + p_struct = &((*pp_opt)->gap_opt.ext_len); + break; + case BLE_GAP_OPT_SCAN_REQ_REPORT: + fp_decoder = ble_gap_opt_scan_req_report_t_dec; + p_struct = &((*pp_opt)->gap_opt.scan_req_report); + break; + case BLE_GAP_OPT_COMPAT_MODE: + fp_decoder = ble_gap_opt_compat_mode_t_dec; + p_struct = &((*pp_opt)->gap_opt.compat_mode); + break; + default: + SER_ASSERT(NRF_ERROR_INVALID_PARAM,NRF_ERROR_INVALID_PARAM); + break; + } + + SER_PULL_FIELD(p_struct, fp_decoder); + } + + SER_REQ_DEC_END; +} + + +uint32_t ble_opt_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_OPT_SET); +} + +uint32_t ble_tx_packet_count_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * * const pp_count) +{ + SER_REQ_DEC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_count, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_tx_packet_count_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_count) +{ + SER_RSP_ENC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET); + SER_PUSH_COND(p_count, uint8_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_user_mem_block_t * * const pp_mem_block) +{ + SER_REQ_DEC_BEGIN(SD_BLE_USER_MEM_REPLY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_mem_block); + SER_ASSERT_NOT_NULL(*pp_mem_block); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_mem_block, ble_user_mem_block_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_USER_MEM_REPLY); +} + +uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf, + uint32_t const packet_len, + uint8_t * p_uuid_le_len, + uint8_t * * const pp_uuid_le, + ble_uuid_t * * const pp_uuid) +{ + SER_REQ_DEC_BEGIN(SD_BLE_UUID_DECODE); + + SER_PULL_len8data(pp_uuid_le, p_uuid_le_len); + SER_PULL_COND(pp_uuid, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_uuid_t const * const p_uuid) +{ + SER_RSP_ENC_BEGIN(SD_BLE_UUID_DECODE); + SER_PUSH_COND(p_uuid, ble_uuid_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_uuid_t * * const pp_uuid, + uint8_t * * const pp_uuid_le_len, + uint8_t * * const pp_uuid_le) +{ + SER_REQ_DEC_BEGIN(SD_BLE_UUID_ENCODE); + + SER_ASSERT_NOT_NULL(pp_uuid); + SER_ASSERT_NOT_NULL(pp_uuid_le_len); + SER_ASSERT_NOT_NULL(pp_uuid_le); + SER_ASSERT_NOT_NULL(*pp_uuid); + SER_ASSERT_NOT_NULL(*pp_uuid_le_len); + SER_ASSERT_NOT_NULL(*pp_uuid_le); + + SER_PULL_COND(pp_uuid, ble_uuid_t_dec); + SER_PULL_COND(pp_uuid_le_len, NULL); + SER_PULL_COND(pp_uuid_le, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t uuid_le_len, + uint8_t const * const p_uuid_le) +{ + SER_RSP_ENC_BEGIN(SD_BLE_UUID_ENCODE); + + SER_PUSH_uint8(&uuid_le_len); + if (p_uuid_le != NULL) + { + SER_PUSH_uint8array(p_uuid_le, uuid_le_len); + } + + SER_RSP_ENC_END; +} + +uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_uuid128_t * * const pp_uuid, + uint8_t * * const pp_uuid_type) +{ + SER_REQ_DEC_BEGIN(SD_BLE_UUID_VS_ADD); + + SER_ASSERT_NOT_NULL(pp_uuid); + SER_ASSERT_NOT_NULL(pp_uuid_type); + SER_ASSERT_NOT_NULL(*pp_uuid); + SER_ASSERT_NOT_NULL(*pp_uuid_type); + + SER_PULL_COND(pp_uuid, ble_uuid128_t_dec); + SER_PULL_COND(pp_uuid_type, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_uuid_type) +{ + SER_RSP_ENC_BEGIN(SD_BLE_UUID_VS_ADD); + SER_PUSH_COND(p_uuid_type, uint8_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_version_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_version_t * * const pp_version) +{ + SER_REQ_DEC_BEGIN(SD_BLE_VERSION_GET); + + SER_ASSERT_NOT_NULL(pp_version); + SER_ASSERT_NOT_NULL(*pp_version); + + SER_PULL_COND(pp_version, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_version_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_version_t const * const p_version) +{ + SER_RSP_ENC_BEGIN(SD_BLE_VERSION_GET); + SER_PUSH_FIELD(p_version, ble_version_t_enc); + SER_RSP_ENC_END; +} + + + +uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint32_t * const p_opt_id) +{ + SER_REQ_DEC_BEGIN(SD_BLE_OPT_SET); + + SER_ASSERT_NOT_NULL(p_opt_id); + SER_PULL_uint32(p_opt_id); + + // Pre-decoding; do not check if the whole packet was processed. + return NRF_SUCCESS; +} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_conn.h b/components/serialization/connectivity/codecs/s132/serializers/ble_conn.h similarity index 82% rename from components/serialization/connectivity/codecs/s130/serializers/ble_conn.h rename to components/serialization/connectivity/codecs/s132/serializers/ble_conn.h index 7a13b1d..4429c39 100644 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_conn.h +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_conn.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_CONN_H__ #define BLE_CONN_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs * @ingroup ser_codecs */ @@ -32,13 +61,17 @@ */ #include "ble.h" -/**@brief Decodes @ref sd_ble_tx_buffer_count_get command request. +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Decodes @ref sd_ble_tx_packet_count_get command request. * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format, - * @ref ble_tx_buffer_count_get_rsp_enc for response encoding. + * @sa @ref ble_tx_packet_count_get_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. * @param[out] pp_count Pointer to pointer to location for count. * * @retval NRF_SUCCESS Decoding success. @@ -46,14 +79,14 @@ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. */ -uint32_t ble_tx_buffer_count_get_req_dec(uint8_t const * const p_buf, +uint32_t ble_tx_packet_count_get_req_dec(uint8_t const * const p_buf, uint16_t packet_len, + uint16_t * const p_conn_handle, uint8_t * * const pp_count); -/**@brief Encodes @ref sd_ble_tx_buffer_count_get command response. +/**@brief Encodes @ref sd_ble_tx_packet_count_get command response. * - * @sa @ref nrf51_tx_buffer_count_get_encoding for packet format. - * @ref ble_tx_buffer_count_get_req_dec for request decoding. + * @sa @ref ble_tx_packet_count_get_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -66,7 +99,7 @@ uint32_t ble_tx_buffer_count_get_req_dec(uint8_t const * const p_buf, * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. */ -uint32_t ble_tx_buffer_count_get_rsp_enc(uint32_t return_code, +uint32_t ble_tx_packet_count_get_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len, uint8_t const * const p_count); @@ -94,8 +127,7 @@ uint32_t ble_event_enc(ble_evt_t const * const p_event, /**@brief Decodes @ref sd_ble_version_get command request. * - * @sa @ref nrf51_version_get_encoding for packet format, - * @ref ble_version_get_rsp_enc for response encoding. + * @sa @ref ble_version_get_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -112,8 +144,7 @@ uint32_t ble_version_get_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_version_get command response. * - * @sa @ref nrf51_version_get_encoding for packet format. - * @ref ble_version_get_req_dec for request decoding. + * @sa @ref ble_version_get_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -134,8 +165,7 @@ uint32_t ble_version_get_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_opt_get command request. * - * @sa @ref nrf51_opt_get_encoding for packet format, - * @ref ble_opt_get_rsp_enc for response encoding. + * @sa @ref ble_opt_get_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -155,8 +185,7 @@ uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_opt_get command response. * - * @sa @ref nrf51_opt_get_encoding for packet format. - * @ref ble_opt_get_req_dec for request decoding. + * @sa @ref ble_opt_get_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -177,11 +206,10 @@ uint32_t ble_opt_get_rsp_enc(uint32_t return_code, uint32_t opt_id, ble_opt_t const * const p_opt); - + /**@brief Decodes @ref sd_ble_opt_set command request. * - * @sa @ref nrf51_opt_set_encoding for packet format, - * @ref ble_opt_set_rsp_enc for response encoding. + * @sa @ref ble_opt_set_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -201,8 +229,7 @@ uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_opt_set command response. * - * @sa @ref nrf51_opt_set_encoding for packet format. - * @ref ble_opt_set_req_dec for request decoding. + * @sa @ref ble_opt_set_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -219,11 +246,10 @@ uint32_t ble_opt_set_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len); - + /**@brief Decodes @ref sd_ble_uuid_encode command request. * - * @sa @ref nrf51_uuid_encode_encoding for packet format, - * @ref ble_uuid_encode_rsp_enc for response encoding. + * @sa @ref ble_uuid_encode_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -244,8 +270,7 @@ uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_uuid_encode command response. * - * @sa @ref nrf51_uuid_encode_encoding for packet format. - * @ref ble_uuid_encode_req_dec for request decoding. + * @sa @ref ble_uuid_encode_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -253,7 +278,7 @@ uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf, * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. * \c out: Length of encoded command response packet. * @param[in] uuid_le_len Length of the encoded UUID. - * @param[in] p_uuid_le Pointer to the buffer with encoded UUID. + * @param[in] p_uuid_le Pointer to the buffer with encoded UUID. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -267,11 +292,10 @@ uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_uuid_decode command request. * - * @sa @ref nrf51_uuid_decode_encoding for packet format, - * @ref ble_uuid_decode_rsp_enc for response encoding. + * @sa @ref ble_uuid_decode_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_uuid_le_len Pointer to the length of encoded UUID. * @param[out] pp_uuid_le Pointer to pointer to buffer where encoded UUID will be stored. * @param[out] pp_uuid Pointer to pointer to @ref ble_uuid_t structure. @@ -282,15 +306,14 @@ uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code, * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. */ uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf, - uint32_t const buf_len, + uint32_t const packet_len, uint8_t * p_uuid_le_len, uint8_t * * const pp_uuid_le, ble_uuid_t * * const pp_uuid); /**@brief Encodes @ref sd_ble_uuid_decode command response. * - * @sa @ref nrf51_uuid_decode_encoding for packet format. - * @ref ble_uuid_decode_req_dec for request decoding. + * @sa @ref ble_uuid_decode_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -310,11 +333,10 @@ uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_uuid_vs_add command request. * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format, - * @ref ble_uuid_vs_add_rsp_enc for response encoding. + * @sa @ref ble_uuid_vs_add_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] pp_uuid Pointer to pointer to UUID. * \c It will be set to NULL if p_uuid is not present in the packet. * @param[out] pp_uuid_type Pointer to pointer to UUID type. @@ -325,21 +347,20 @@ uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code, * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. */ uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf, - uint16_t buf_len, + uint16_t packet_len, ble_uuid128_t * * const pp_uuid, uint8_t * * const pp_uuid_type); /**@brief Encodes @ref sd_ble_uuid_vs_add command response. * - * @sa @ref nrf51_uuid_vs_add_encoding for packet format. - * @ref ble_uuid_vs_add_req_dec for request decoding. + * @sa @ref ble_uuid_vs_add_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be * returned. * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. * \c out: Length of encoded command response packet. - * @param[in] p_uuid_type Pointer to the UUID type. + * @param[in] p_uuid_type Pointer to the UUID type. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -349,14 +370,13 @@ uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len, uint8_t const * const p_uuid_type); - + /**@brief Decodes @ref sd_ble_enable command request. * - * @sa @ref nrf51_enable_encoding for packet format, - * @ref ble_enable_rsp_enc for response encoding. + * @sa @ref ble_enable_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] pp_ble_enable_params Pointer to pointer to ble_enable_params_t. * \c It will be set to NULL if p_ble_enable_params is not present in the packet. * @@ -370,8 +390,7 @@ uint32_t ble_enable_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_enable command response. * - * @sa @ref nrf51_enable_encoding for packet format. - * @ref ble_enable_req_dec for request decoding. + * @sa @ref ble_enable_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -391,7 +410,7 @@ uint32_t ble_enable_rsp_enc(uint32_t return_code, * * @param[out] p_buf Pointer to buffer where encoded data command response will be * returned. - * @param[in,out] packet_len \c in: size of \p p_buf buffer. + * @param[in,out] packet_len \c in: size of \p p_buf buffer. * \c out: Length of encoded command response packet. * @param[in,out] p_opt_id Pointer to opt_id which identifies type of @ref ble_opt_t union. * @@ -405,8 +424,7 @@ uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf, /**@brief Decodes @ref sd_ble_user_mem_reply command request. * - * @sa @ref nrf51_user_mem_reply_encoding for packet format, - * @ref ble_user_mem_reply_rsp_enc for response encoding. + * @sa @ref ble_user_mem_reply_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -425,8 +443,7 @@ uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_user_mem_reply command response. * - * @sa @ref nrf51_user_mem_reply_encoding for packet format. - * @ref ble_user_mem_reply_req_dec for request decoding. + * @sa @ref ble_user_mem_reply_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -444,4 +461,9 @@ uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code, /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/connectivity/codecs/s120/serializers/ble_event.c b/components/serialization/connectivity/codecs/s132/serializers/ble_event_enc.c similarity index 67% rename from components/serialization/connectivity/codecs/s120/serializers/ble_event.c rename to components/serialization/connectivity/codecs/s132/serializers/ble_event_enc.c index 058cfa4..625bc4e 100644 --- a/components/serialization/connectivity/codecs/s120/serializers/ble_event.c +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_event_enc.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "ble_conn.h" @@ -18,7 +46,7 @@ #include "ble_l2cap_evt_conn.h" #include "ble_serialization.h" #include "app_util.h" - +#include "nrf_log.h" uint32_t ble_event_enc(ble_evt_t const * const p_event, uint32_t event_len, @@ -36,17 +64,23 @@ uint32_t ble_event_enc(ble_evt_t const * const p_event, case BLE_EVT_TX_COMPLETE: ret_val = ble_evt_tx_complete_enc(p_event, event_len, p_buf, p_buf_len); break; + case BLE_EVT_USER_MEM_RELEASE: ret_val = ble_evt_user_mem_release_enc(p_event, event_len, p_buf, p_buf_len); break; + case BLE_EVT_USER_MEM_REQUEST: ret_val = ble_evt_user_mem_request_enc(p_event, event_len, p_buf, p_buf_len); break; + case BLE_EVT_DATA_LENGTH_CHANGED: + ret_val = ble_evt_data_length_changed_enc(p_event, event_len, p_buf, p_buf_len); + break; + case BLE_GAP_EVT_CONN_PARAM_UPDATE: ret_val = ble_gap_evt_conn_param_update_enc(p_event, event_len, p_buf, p_buf_len); break; - + case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: ret_val = ble_gap_evt_conn_param_update_request_enc(p_event, event_len, p_buf, p_buf_len); break; @@ -94,7 +128,12 @@ uint32_t ble_event_enc(ble_evt_t const * const p_event, case BLE_GAP_EVT_SEC_REQUEST: ret_val = ble_gap_evt_sec_request_enc(p_event, event_len, p_buf, p_buf_len); break; - + case BLE_GAP_EVT_KEY_PRESSED: + ret_val = ble_gap_evt_key_pressed_enc(p_event, event_len, p_buf, p_buf_len); + break; + case BLE_GAP_EVT_LESC_DHKEY_REQUEST: + ret_val = ble_gap_evt_lesc_dhkey_request_enc(p_event, event_len, p_buf, p_buf_len); + break; case BLE_GATTC_EVT_CHAR_DISC_RSP: ret_val = ble_gattc_evt_char_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); break; @@ -138,6 +177,14 @@ uint32_t ble_event_enc(ble_evt_t const * const p_event, ret_val = ble_gattc_evt_char_vals_read_rsp_enc(p_event, event_len, p_buf, p_buf_len); break; + case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP: + ret_val = ble_gattc_evt_attr_info_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; + + case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: + ret_val = ble_gattc_evt_exchange_mtu_rsp_enc(p_event, event_len, p_buf, p_buf_len); + break; + case BLE_GATTS_EVT_HVC: ret_val = ble_gatts_evt_hvc_enc(p_event, event_len, p_buf, p_buf_len); break; @@ -162,6 +209,10 @@ uint32_t ble_event_enc(ble_evt_t const * const p_event, ret_val = ble_gatts_evt_sys_attr_missing_enc(p_event, event_len, p_buf, p_buf_len); break; + case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: + ret_val = ble_gatts_evt_exchange_mtu_request_enc(p_event, event_len, p_buf, p_buf_len); + break; + case BLE_L2CAP_EVT_RX: ret_val = ble_l2cap_evt_rx_enc(p_event, event_len, p_buf, p_buf_len); break; diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_evt_conn.c b/components/serialization/connectivity/codecs/s132/serializers/ble_evt_conn.c new file mode 100644 index 0000000..ed62e78 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_evt_conn.c @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_evt_conn.h" +#include +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "app_util.h" +#include "conn_ble_user_mem.h" + +uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_EVT_USER_MEM_RELEASE); + + SER_PUSH_uint16(&p_event->evt.common_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.common_evt.params.user_mem_release.type); + SER_PUSH_uint16(&p_event->evt.common_evt.params.user_mem_release.mem_block.len); + SER_PUSH_COND(p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem, NULL); + + // Now user memory context can be released + err_code = conn_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_EVT_ENC_END; +} + + + +uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_EVT_TX_COMPLETE); + + SER_PUSH_uint16(&p_event->evt.common_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.common_evt.params.tx_complete.count); + + SER_EVT_ENC_END; +} + +uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_EVT_USER_MEM_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.common_evt.params.user_mem_request.type); + + SER_EVT_ENC_END; +} + +uint32_t ble_evt_data_length_changed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_EVT_DATA_LENGTH_CHANGED); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.common_evt.params.data_length_changed, ble_evt_data_length_changed_t_enc); + + SER_EVT_ENC_END; +} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_evt_conn.h b/components/serialization/connectivity/codecs/s132/serializers/ble_evt_conn.h similarity index 50% rename from components/serialization/connectivity/codecs/s130/serializers/ble_evt_conn.h rename to components/serialization/connectivity/codecs/s132/serializers/ble_evt_conn.h index b187b94..3e6f104 100644 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_evt_conn.h +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_evt_conn.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_EVT_CONN_H__ #define BLE_EVT_CONN_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs * @ingroup ser_codecs */ @@ -32,12 +61,14 @@ */ #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Encodes ble_evt_tx_complete event. * - * @sa @ref nrf51_evt_tx_complete_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that will be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. @@ -55,8 +86,6 @@ uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_evt_user_mem_release event. * - * @sa @ref nrf51_evt_user_mem_release_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -75,9 +104,7 @@ uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_evt_user_mem_request event. * - * @sa @ref nrf51_evt_user_mem_request_encoding for packet format. - * - * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that will be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. @@ -91,5 +118,29 @@ uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event, uint32_t event_len, uint8_t * const p_buf, uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_evt_data_length_changed event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that will be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_evt_data_length_changed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_gap_conn.c b/components/serialization/connectivity/codecs/s132/serializers/ble_gap_conn.c new file mode 100644 index 0000000..5e9bf15 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gap_conn.c @@ -0,0 +1,918 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gap_conn.h" +#include +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "app_util.h" + +uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * const pp_data, + uint8_t * p_dlen, + uint8_t * * const pp_sr_data, + uint8_t * p_srdlen) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADV_DATA_SET); + + SER_ASSERT_NOT_NULL(p_dlen); + SER_ASSERT_NOT_NULL(p_srdlen); + SER_PULL_len8data(pp_data, p_dlen); + SER_PULL_len8data(pp_sr_data, p_srdlen); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADV_DATA_SET); +} + +uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_adv_params_t * * const pp_adv_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADV_START); + + SER_ASSERT_NOT_NULL(pp_adv_params); + SER_ASSERT_NOT_NULL(*pp_adv_params); + SER_ASSERT_NOT_NULL((*pp_adv_params)->p_peer_addr); + + SER_PULL_COND(pp_adv_params, ble_gap_adv_params_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADV_START); +} + + +uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADV_STOP); +} + + +uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * * const pp_appearance) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_APPEARANCE_GET); + + SER_ASSERT_NOT_NULL(pp_appearance); + SER_ASSERT_NOT_NULL(*pp_appearance); + SER_PULL_COND(pp_appearance, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_appearance) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_APPEARANCE_GET); + + SER_PUSH_COND(p_appearance, uint16_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_appearance) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_APPEARANCE_SET); + + SER_ASSERT_NOT_NULL(p_appearance); + SER_PULL_uint16(p_appearance); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_APPEARANCE_SET); +} + +uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_key_type, + uint8_t * * const pp_key) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_AUTH_KEY_REPLY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(p_key_type); + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint8(p_key_type); + + uint8_t key_len; + switch (*p_key_type) + { + case BLE_GAP_AUTH_KEY_TYPE_NONE: + key_len = 0; + break; + + case BLE_GAP_AUTH_KEY_TYPE_PASSKEY: + key_len = 6; + break; + + case BLE_GAP_AUTH_KEY_TYPE_OOB: + key_len = 16; + break; + + default: + return NRF_ERROR_INVALID_PARAM; + } + + SER_PULL_buf(pp_key, key_len, key_len); + SER_REQ_DEC_END; +} + +uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_AUTH_KEY_REPLY); +} + + +uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_gap_sec_params_t * * const pp_sec_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_AUTHENTICATE); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_sec_params); + SER_ASSERT_NOT_NULL(*pp_sec_params); + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_sec_params, ble_gap_sec_params_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_AUTHENTICATE); +} + +uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_conn_params_t * * const pp_conn_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_CONN_PARAM_UPDATE); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_conn_params); + SER_ASSERT_NOT_NULL(*pp_conn_params); + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_conn_params, ble_gap_conn_params_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_CONN_PARAM_UPDATE); +} + +uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_conn_sec_t * * const pp_conn_sec) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_CONN_SEC_GET); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_conn_sec, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code, + ble_gap_conn_sec_t * const p_conn_sec, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_CONN_SEC_GET); + + SER_PUSH_COND(p_conn_sec, ble_gap_conn_sec_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * const pp_addr, + ble_gap_scan_params_t * * const pp_scan_params, + ble_gap_conn_params_t * * const pp_conn_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_CONNECT); + + SER_ASSERT_NOT_NULL(pp_addr); + SER_ASSERT_NOT_NULL(*pp_addr); + SER_ASSERT_NOT_NULL(pp_scan_params); + SER_ASSERT_NOT_NULL(*pp_scan_params); + SER_ASSERT_NOT_NULL(pp_conn_params); + SER_ASSERT_NOT_NULL(*pp_conn_params); + + SER_PULL_COND(pp_addr, ble_gap_addr_t_dec); + SER_PULL_COND(pp_scan_params, ble_gap_scan_params_t_dec); + SER_PULL_COND(pp_conn_params, ble_gap_conn_params_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_connect_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_CONNECT); +} +uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_CONNECT_CANCEL); +} + +uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * * pp_name, + uint16_t * * pp_name_len) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET); + + SER_ASSERT_NOT_NULL(pp_name_len); + + SER_PULL_COND(pp_name_len, uint16_t_dec); + SER_PULL_COND(pp_name, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code, + uint8_t const * const p_dev_name, + uint16_t * p_dev_name_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET); + + SER_PUSH_COND(p_dev_name_len, uint16_t_enc); + + if (p_dev_name_len) + { + SER_PUSH_uint8array(p_dev_name, *p_dev_name_len); + } + + SER_RSP_ENC_END; +} + +uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_sec_mode_t * * const pp_write_perm, + uint8_t * * const pp_dev_name, + uint16_t * const p_dev_name_len) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_DEVICE_NAME_SET); + + SER_ASSERT_NOT_NULL(pp_write_perm); + SER_ASSERT_NOT_NULL(pp_dev_name); + SER_ASSERT_NOT_NULL(p_dev_name_len); + + SER_PULL_COND(pp_write_perm, ble_gap_conn_sec_mode_t_dec); + SER_PULL_len16data(pp_dev_name, p_dev_name_len); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_DEVICE_NAME_SET); +} + +uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * const p_hci_status) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_DISCONNECT); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(p_hci_status); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint8(p_hci_status); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_DISCONNECT); +} + +uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gap_master_id_t ** const pp_master_id, + ble_gap_enc_info_t ** const pp_enc_info) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_ENCRYPT); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_enc_info); + SER_ASSERT_NOT_NULL(pp_master_id); + SER_ASSERT_NOT_NULL(*pp_enc_info); + SER_ASSERT_NOT_NULL(*pp_master_id); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_master_id, ble_gap_master_id_t_dec); + SER_PULL_COND(pp_enc_info, ble_gap_enc_info_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ENCRYPT); +} + +uint32_t ble_gap_keypress_notify_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_kp_not) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_KEYPRESS_NOTIFY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(p_kp_not); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint8(p_kp_not); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_keypress_notify_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_KEYPRESS_NOTIFY); +} + +uint32_t ble_gap_lesc_dhkey_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_dhkey_t * * pp_dhkey) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_LESC_DHKEY_REPLY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_dhkey); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_dhkey, ble_gap_lesc_dhkey_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_lesc_dhkey_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_LESC_DHKEY_REPLY); +} + +uint32_t ble_gap_lesc_oob_data_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_p256_pk_t * * pp_pk_own, + ble_gap_lesc_oob_data_t * * pp_oobd_own) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_oobd_own); + SER_ASSERT_NOT_NULL(pp_pk_own); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_pk_own, ble_gap_lesc_p256_pk_t_dec); + SER_PULL_COND(pp_oobd_own, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_lesc_oob_data_get_rsp_enc(uint32_t return_code, + ble_gap_lesc_oob_data_t * p_oobd_own, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET); + + SER_PUSH_COND(p_oobd_own, ble_gap_lesc_oob_data_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gap_lesc_oob_data_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_oob_data_t * * pp_oobd_own, + ble_gap_lesc_oob_data_t * * pp_oobd_peer) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_SET); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_oobd_own); + SER_ASSERT_NOT_NULL(pp_oobd_peer); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_oobd_own, ble_gap_lesc_oob_data_t_dec); + SER_PULL_COND(pp_oobd_peer, ble_gap_lesc_oob_data_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_lesc_oob_data_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_LESC_OOB_DATA_SET); +} + +uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_conn_params_t * * const pp_conn_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_PPCP_GET); + + SER_ASSERT_NOT_NULL(pp_conn_params); + SER_ASSERT_NOT_NULL(*pp_conn_params); + SER_ASSERT_LENGTH_LEQ(2, packet_len); + + SER_PULL_COND(pp_conn_params, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_conn_params_t const * const p_conn_params) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_PPCP_GET); + + SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc); + + SER_RSP_ENC_END; +} + + +uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_conn_params_t * * const pp_conn_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_PPCP_SET); + + SER_ASSERT_NOT_NULL(pp_conn_params); + SER_PULL_COND(pp_conn_params, ble_gap_conn_params_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_PPCP_SET); +} + +uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + int8_t * * const pp_rssi) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_RSSI_GET); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_rssi); + SER_ASSERT_NOT_NULL(*pp_rssi); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_rssi, NULL); + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + int8_t rssi) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_RSSI_GET); + + SER_PUSH_int8(&rssi); + + SER_RSP_ENC_END; +} + +uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_threshold_dbm, + uint8_t * p_skip_count) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_RSSI_START); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(p_threshold_dbm); + SER_ASSERT_NOT_NULL(p_skip_count); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint8(p_threshold_dbm); + SER_PULL_uint8(p_skip_count); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_RSSI_START); +} + +uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_RSSI_STOP); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_PULL_uint16(p_conn_handle); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_RSSI_STOP); +} + +uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_scan_params_t * * const pp_scan_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_SCAN_START); + + SER_ASSERT_NOT_NULL(pp_scan_params); + SER_ASSERT_NOT_NULL(*pp_scan_params); + + SER_PULL_COND(pp_scan_params, ble_gap_scan_params_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_SCAN_START); +} + +uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_SCAN_STOP); +} + +uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + ble_gap_enc_info_t * * const pp_enc_info, + ble_gap_irk_t * * const pp_id_info, + ble_gap_sign_info_t * * const pp_sign_info) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_SEC_INFO_REPLY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_enc_info); + SER_ASSERT_NOT_NULL(pp_id_info); + SER_ASSERT_NOT_NULL(pp_sign_info); + SER_ASSERT_NOT_NULL(*pp_enc_info); + SER_ASSERT_NOT_NULL(*pp_id_info); + SER_ASSERT_NOT_NULL(*pp_sign_info); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_enc_info, ble_gap_enc_info_t_dec); + SER_PULL_COND(pp_id_info, ble_gap_irk_t_dec); + SER_PULL_COND(pp_sign_info, ble_gap_sign_info_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_SEC_INFO_REPLY); +} + +uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_sec_status, + ble_gap_sec_params_t * * const pp_sec_params, + ble_gap_sec_keyset_t * * const pp_sec_keyset) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(p_sec_status); + SER_ASSERT_NOT_NULL(pp_sec_params); + SER_ASSERT_NOT_NULL(*pp_sec_params); + SER_ASSERT_NOT_NULL(pp_sec_keyset); + SER_ASSERT_NOT_NULL(*pp_sec_keyset); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint8(p_sec_status); + SER_PULL_COND(pp_sec_params, ble_gap_sec_params_t_dec); + SER_PULL_COND(pp_sec_keyset, ble_gap_sec_keyset_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_sec_keyset_t * const p_sec_keyset) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY); + SER_PUSH_COND(p_sec_keyset, ble_gap_sec_keyset_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + int8_t * p_tx_power) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_TX_POWER_SET); + + SER_ASSERT_NOT_NULL(p_tx_power); + SER_PULL_int8(p_tx_power); + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_TX_POWER_SET); +} + + +uint32_t ble_gap_addr_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_addr_t * * const pp_address) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADDR_GET); + SER_PULL_COND(pp_address, NULL); + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_addr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_addr_t const * const p_address) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_ADDR_GET); + SER_PUSH_FIELD(p_address, ble_gap_addr_t_enc); + SER_RSP_ENC_END; +} + + +uint32_t ble_gap_addr_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * const pp_addr) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADDR_SET); + SER_PULL_COND(pp_addr, ble_gap_addr_t_dec); + SER_REQ_DEC_END; +} + + +uint32_t ble_gap_addr_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADDR_SET); +} + +uint32_t ble_gap_privacy_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_privacy_params_t * * const pp_privacy_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_PRIVACY_SET); + SER_PULL_COND(pp_privacy_params, ble_gap_privacy_params_t_dec); + SER_REQ_DEC_END; +} + +uint32_t ble_gap_privacy_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_PRIVACY_SET); +} + +uint32_t ble_gap_privacy_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_privacy_params_t * * const pp_privacy_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_PRIVACY_GET); + SER_PULL_COND(pp_privacy_params, ble_gap_privacy_params_t_dec); + SER_REQ_DEC_END; +} + +uint32_t ble_gap_privacy_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_privacy_params_t const * const p_privacy_params) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GAP_PRIVACY_GET); + SER_PUSH_COND(p_privacy_params, ble_gap_privacy_params_t_enc); + SER_RSP_ENC_END; +} + +uint32_t ble_gap_whitelist_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * * const ppp_wl_addrs, + uint8_t * const p_len) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_WHITELIST_SET); + + SER_ASSERT_NOT_NULL(ppp_wl_addrs); + SER_ASSERT_NOT_NULL(*ppp_wl_addrs); + SER_ASSERT_NOT_NULL(**ppp_wl_addrs); + + uint8_t presence; + SER_PULL_uint8(p_len); + + SER_PULL_uint8(&presence); + if (presence == SER_FIELD_PRESENT) + { + ble_gap_addr_t * * const pp_wl_addrs = *ppp_wl_addrs; + for (uint32_t i = 0; i < *p_len; ++i) + { + SER_PULL_COND(&(pp_wl_addrs[i]), ble_gap_addr_t_dec); + } + } + else + { + *ppp_wl_addrs = NULL; + } + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_whitelist_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_WHITELIST_SET); +} + +uint32_t ble_gap_device_identities_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_id_key_t * * * const ppp_id_keys, + ble_gap_irk_t * * * const ppp_local_irks, + uint8_t * const p_len) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GAP_DEVICE_IDENTITIES_SET); + + SER_ASSERT_NOT_NULL(ppp_id_keys); + SER_ASSERT_NOT_NULL(*ppp_id_keys); + SER_ASSERT_NOT_NULL(**ppp_id_keys); + SER_ASSERT_NOT_NULL(ppp_local_irks); + SER_ASSERT_NOT_NULL(*ppp_local_irks); + SER_ASSERT_NOT_NULL(**ppp_local_irks); + + uint8_t presence; + SER_PULL_uint8(p_len); + + SER_PULL_uint8(&presence); + if (presence == SER_FIELD_PRESENT) + { + ble_gap_id_key_t * * const pp_id_keys = *ppp_id_keys; + for (uint32_t i = 0; i < *p_len; ++i) + { + SER_PULL_COND(&(pp_id_keys[i]), ble_gap_id_key_t_dec); + } + } + else + { + *ppp_id_keys = NULL; + } + SER_PULL_uint8(&presence); + if (presence == SER_FIELD_PRESENT) + { + ble_gap_irk_t * * const pp_local_irks = *ppp_local_irks; + for (uint32_t i = 0; i < *p_len; ++i) + { + SER_PULL_COND(&(pp_local_irks[i]), ble_gap_irk_t_dec); + } + } + else + { + *ppp_local_irks = NULL; + } + + SER_REQ_DEC_END; +} + +uint32_t ble_gap_device_identities_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_DEVICE_IDENTITIES_SET); +} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn.h b/components/serialization/connectivity/codecs/s132/serializers/ble_gap_conn.h similarity index 67% rename from components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn.h rename to components/serialization/connectivity/codecs/s132/serializers/ble_gap_conn.h index 8c5ac79..689e723 100644 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_conn.h +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gap_conn.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GAP_CONN_H__ #define BLE_GAP_CONN_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs * @ingroup ser_codecs */ @@ -32,49 +61,13 @@ */ #include "ble_gap.h" -/**@brief Decodes @ref sd_ble_gap_address_get command request. - * - * @sa @ref nrf51_address_get_encoding for packet format, - * @ref ble_gap_address_get_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] pp_address Pointer to pointer to address. - * - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. - */ -uint32_t ble_gap_address_get_req_dec(uint8_t const * const p_buf, - uint16_t packet_len, - ble_gap_addr_t * * const pp_address); - -/**@brief Encodes @ref sd_ble_gap_address_get command response. - * - * @sa @ref nrf51_address_get_encoding for packet format. - * @ref ble_gap_address_get_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * @param[in] p_address Pointer to @ref ble_gap_addr_t address - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_get_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len, - ble_gap_addr_t const * const p_address); +#ifdef __cplusplus +extern "C" { +#endif /**@brief Decodes @ref sd_ble_gap_authenticate command request. * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format, - * @ref ble_gap_authenticate_rsp_enc for response encoding. + * @sa @ref ble_gap_authenticate_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -93,8 +86,7 @@ uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_authenticate command response. * - * @sa @ref nrf51_ble_gap_authenticate_encoding for packet format. - * @ref ble_gap_authenticate_req_dec for request decoding. + * @sa @ref ble_gap_authenticate_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -110,48 +102,9 @@ uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len); -/** @brief Decodes @ref sd_ble_gap_address_set command request. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format, - * @ref ble_gap_address_set_rsp_enc for response encoding. - * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. - * @param[in] p_addr_cycle_mode Pointer to address cycle mode. - * @param[out] pp_addr Pointer to pointer to the address structure. - - * @retval NRF_SUCCESS Decoding success. - * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_set_req_dec(uint8_t const * const p_buf, - uint32_t packet_len, - uint8_t * p_addr_cycle_mode, - ble_gap_addr_t * * const pp_addr); - -/**@brief Encodes @ref sd_ble_gap_address_set command response. - * - * @sa @ref nrf51_gap_address_set_encoding for packet format. - * @ref ble_gap_address_set_req_dec for request decoding. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[out] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. - * - * @retval NRF_SUCCESS Encoding success. - * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. - * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. - */ -uint32_t ble_gap_address_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buf, - uint32_t * const p_buf_len); - /**@brief Decodes @ref sd_ble_gap_adv_data_set command request. * - * @sa @ref nrf51_adv_set_encoding for packet format, - * @ref ble_gap_adv_data_set_rsp_enc for response encoding. + * @sa @ref ble_gap_adv_data_set_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of request packet. @@ -173,8 +126,7 @@ uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_adv_data_set command response. * - * @sa @ref nrf51_adv_set_encoding for packet format. - * @ref ble_gap_adv_data_set_req_dec for request decoding. + * @sa @ref ble_gap_adv_data_set_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -192,8 +144,7 @@ uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_adv_start command request. * - * @sa @ref nrf51_adv_start_encoding for packet format, - * @ref ble_gap_adv_start_rsp_enc for response encoding. + * @sa @ref ble_gap_adv_start_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -210,8 +161,7 @@ uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_adv_start command response. * - * @sa @ref nrf51_adv_start_encoding for packet format. - * @ref ble_gap_adv_start_req_dec for request decoding. + * @sa @ref ble_gap_adv_start_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -229,8 +179,7 @@ uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_device_name_get command request. * - * @sa @ref nrf51_device_name_get_encoding for packet format, - * @ref ble_gap_device_name_get_rsp_enc for response encoding. + * @sa @ref ble_gap_device_name_get_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -248,15 +197,13 @@ uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_device_name_get command response. * - * @sa @ref nrf51_device_name_get_encoding for packet format. - * - * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_dev_name Pointer to device name buffer. - * @param[in] dev_name_len Length of device name buffer. - * @param[in] p_buf Pointer to buffer where encoded data command response will be - * returned. - * @param[in, out] p_buflen \c in: size of \p p_buf buffer. - * \c out: Length of encoded command response packet. + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_dev_name Pointer to device name buffer. + * @param[in] p_dev_name_len Length of device name buffer. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -264,14 +211,13 @@ uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf, */ uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code, uint8_t const * const p_dev_name, - uint16_t dev_name_len, + uint16_t * p_dev_name_len, uint8_t * const p_buf, - uint32_t * const p_buflen); + uint32_t * const p_buf_len); /**@brief Decodes @ref sd_ble_gap_conn_param_update command request. * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format, - * @ref ble_gap_conn_param_update_rsp_enc for response encoding. + * @sa @ref ble_gap_conn_param_update_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -291,8 +237,6 @@ uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf ble_gap_conn_params_t * * const pp_conn_params); /**@brief Encodes @ref sd_ble_gap_conn_param_update command response. - * - * @sa @ref nrf51_gap_conn_param_update_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -311,8 +255,7 @@ uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_disconnect command request. * - * @sa @ref nrf51_disconnect_encoding for packet format, - * @ref ble_gap_disconnect_rsp_enc for response encoding. + * @sa @ref ble_gap_disconnect_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -330,8 +273,6 @@ uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf, uint8_t * const p_hci_status); /**@brief Encodes @ref sd_ble_gap_disconnect command response. - * - * @sa @ref nrf51_disconnect_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -349,8 +290,7 @@ uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_tx_power_set command request. * - * @sa @ref nrf51_tx_power_set_encoding for packet format, - * @ref ble_gap_tx_power_set_rsp_enc for response encoding. + * @sa @ref ble_gap_tx_power_set_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -366,8 +306,6 @@ uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf, int8_t * tx_power); /**@brief Encodes @ref sd_ble_gap_tx_power_set command response. - * - * @sa @ref nrf51_tx_power_set_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -385,8 +323,7 @@ uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_ppcp_set command request. * - * @sa @ref nrf51_ppcp_set_encoding for packet format, - * @ref ble_gap_ppcp_set_rsp_enc for response encoding. + * @sa @ref ble_gap_ppcp_set_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -404,8 +341,6 @@ uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf, ble_gap_conn_params_t * * const pp_conn_params); /**@brief Encodes @ref sd_ble_gap_ppcp_set command response. - * - * @sa @ref nrf51_ppcp_set_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -424,8 +359,7 @@ uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_ppcp_get command request. * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format, - * @ref ble_gap_ppcp_get_rsp_enc for response encoding. + * @sa @ref ble_gap_ppcp_get_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -442,8 +376,7 @@ uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_ppcp_get command response. * - * @sa @ref nrf51_gap_ppcp_get_encoding for packet format. - * @ref ble_gap_ppcp_get_req_dec for request decoding. + * @sa @ref ble_gap_ppcp_get_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -462,8 +395,6 @@ uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_cod ble_gap_conn_params_t const * const p_conn_params); /**@brief Encodes @ref sd_ble_gap_adv_stop command response. - * - * @sa @ref nrf51_sd_ble_gap_adv_stop for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -478,11 +409,10 @@ uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_cod uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len); - + /**@brief Decodes @ref sd_ble_gap_auth_key_reply command request. * - * @sa @ref nrf51_auth_key_reply_encoding for packet format, - * @ref ble_gap_auth_key_reply_rsp_enc for response encoding. + * @sa @ref ble_gap_auth_key_reply_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -502,8 +432,6 @@ uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf, uint8_t * * const pp_key); /**@brief Encodes @ref sd_ble_gap_auth_key_reply command response. - * - * @sa @ref nrf51_auth_key_reply_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -521,8 +449,7 @@ uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_sec_params_reply command request. * - * @sa @ref nrf51_sec_params_reply_encoding for packet format, - * @ref ble_gap_sec_params_reply_rsp_enc for response encoding. + * @sa @ref ble_gap_sec_params_reply_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -546,8 +473,6 @@ uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf, ble_gap_sec_keyset_t * * const pp_sec_keyset); /**@brief Encodes @ref sd_ble_gap_sec_params_reply command response. - * - * @sa @ref nrf51_sec_params_reply_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -567,11 +492,10 @@ uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_co /**@brief Decodes @ref sd_ble_gap_rssi_start command request. * - * @sa @ref nrf51_rssi_start_encoding for packet format, - * @ref ble_gap_rssi_start_rsp_enc for response encoding. + * @sa @ref ble_gap_rssi_start_rsp_enc for response encoding. * - * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_conn_handle Pointer to connection handle. * @param[out] p_threshold_dbm Pointer to threshold in dBm. * @param[out] p_skip_count Pointer to sample skip count. @@ -582,14 +506,12 @@ uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_co * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. */ uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, + uint32_t packet_len, uint16_t * p_conn_handle, uint8_t * p_threshold_dbm, uint8_t * p_skip_count); /**@brief Encodes @ref sd_ble_gap_rssi_start command response. - * - * @sa @ref nrf51_rssi_start_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -608,12 +530,11 @@ uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_rssi_stop command request. * - * @sa @ref nrf51_rssi_stop_encoding for packet format, - * @ref ble_gap_rssi_stop_rsp_enc for response encoding. + * @sa @ref ble_gap_rssi_stop_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. - * @param[out] conn_handle Pointer to connection handle. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] conn_handle Pointer to connection handle. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. @@ -622,12 +543,10 @@ uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code, */ uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, + uint32_t packet_len, uint16_t * conn_handle); /**@brief Encodes @ref sd_ble_gap_rssi_stop command response. - * - * @sa @ref nrf51_rssi_stop_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -646,8 +565,7 @@ uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_appearance_get command request. * - * @sa @ref nrf51_appearance_get_encoding for packet format, - * @ref ble_gap_appearance_get_rsp_enc for response encoding. + * @sa @ref ble_gap_appearance_get_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -664,15 +582,14 @@ uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_appearance_get command response. * - * @sa @ref nrf51_appearance_get_encoding for packet format. - * @ref ble_gap_appearance_get_req_dec for request decoding. + * @sa @ref ble_gap_appearance_get_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be * returned. * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. * \c out: Length of encoded command response packet. - * @param[in] p_appearance Pointer to uint16_t appearance. + * @param[in] p_appearance Pointer to uint16_t appearance. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -686,8 +603,7 @@ uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_appearance_set command request. * - * @sa @ref nrf51_appearance_set_encoding for packet format, - * @ref ble_gap_tx_power_set_rsp_enc for response encoding. + * @sa @ref ble_gap_tx_power_set_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] buf_len Length (in bytes) of the packet. @@ -702,8 +618,6 @@ uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf, uint16_t * const p_appearance); /**@brief Encodes @ref sd_ble_gap_appearance_set command response. - * - * @sa @ref nrf51_appearance_set_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -722,15 +636,14 @@ uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_sec_info_reply command request. * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format, - * @ref ble_gap_sec_info_reply_rsp_enc for response encoding. + * @sa @ref ble_gap_sec_info_reply_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of the packet. * @param[out] p_conn_handle Pointer to the Connection Handle. * @param[out] pp_enc_info Pointer to pointer to Encryption Information. - * @param[out] pp_id_info Pointer to pointer to Id Information. - * @param[out] pp_sign_info Pointer to pointer to Signing Information + * @param[out] pp_id_info Pointer to pointer to ID Information. + * @param[out] pp_sign_info Pointer to pointer to Signing Information. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. @@ -744,8 +657,6 @@ uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf, ble_gap_sign_info_t * * const pp_sign_info); /**@brief Encodes @ref sd_ble_gap_sec_info_reply command response. - * - * @sa @ref nrf51_gap_sec_info_reply_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -763,14 +674,13 @@ uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_device_name_set command request. * - * @sa @ref nrf51_device_name_set_encoding for packet format, - * @ref ble_gap_device_name_set_rsp_enc for response encoding. + * @sa @ref ble_gap_device_name_set_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of the packet. - * @param[out] pp_write_perm Pointer to pointer to write permissions filed. - * @param[out] pp_dev_name Pointer to pointer to device name string - * @param[out] p_dev_name_len Pointer to device name string length + * @param[out] pp_write_perm Pointer to pointer to write permissions filed. + * @param[out] pp_dev_name Pointer to pointer to device name string. + * @param[out] p_dev_name_len Pointer to device name string length. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. @@ -784,8 +694,6 @@ uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf /**@brief Encodes @ref sd_ble_gap_device_name_set command response. - * - * @sa @ref nrf51_device_name_set_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -803,14 +711,13 @@ uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_conn_sec_get command request. * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format, - * @ref ble_gap_conn_sec_get_rsp_enc for response encoding. + * @sa @ref ble_gap_conn_sec_get_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_conn_handle Pointer to Connection Handle. * @param[out] pp_conn_sec Pointer to pointer to @ref ble_gap_conn_sec_t to be filled by - * the softdevice. + * the SoftDevice. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. @@ -824,8 +731,7 @@ uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_conn_sec_get command response. * - * @sa @ref nrf51_gap_conn_sec_get_encoding for packet format. - * @ref ble_gap_conn_sec_get_req_dec for request decoding. + * @sa @ref ble_gap_conn_sec_get_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_conn_sec Pointer to @ref ble_gap_conn_sec_t to be encoded. @@ -844,8 +750,6 @@ uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code, uint32_t * const p_buf_len); /**@brief Encodes @ref sd_ble_gap_scan_stop command response. - * - * @sa @ref nrf51_scan_stop_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -863,8 +767,7 @@ uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_connect command request. * - * @sa @ref nrf51_connect_encoding for packet format, - * @ref ble_gap_connect_rsp_enc for response encoding. + * @sa @ref ble_gap_connect_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -885,8 +788,7 @@ uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_connect command response. * - * @sa @ref nrf51_connect_encoding for packet format. - * @ref ble_gap_connect_req_dec for request decoding. + * @sa @ref ble_gap_connect_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -904,8 +806,7 @@ uint32_t ble_gap_connect_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_scan_start command request. * - * @sa @ref nrf51_scan_start_encoding for packet format, - * @ref ble_gap_scan_start_rsp_enc for response encoding. + * @sa @ref ble_gap_scan_start_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -922,8 +823,7 @@ uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_scan_start command response. * - * @sa @ref nrf51_scan_start_encoding for packet format. - * @ref ble_gap_scan_start_req_dec for request decoding. + * @sa @ref ble_gap_scan_start_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -940,8 +840,6 @@ uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code, uint32_t * const p_buf_len); /**@brief Encodes @ref sd_ble_gap_connect_cancel command response. - * - * @sa @ref nrf51_connect_cancel_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -959,8 +857,7 @@ uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_encrypt command request. * - * @sa @ref nrf51_gap_encrypt_encoding for packet format, - * @ref ble_gap_encrypt_rsp_enc for response encoding. + * @sa @ref ble_gap_encrypt_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -981,8 +878,6 @@ uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf, ble_gap_enc_info_t ** const pp_enc_info); /**@brief Encodes @ref sd_ble_gap_encrypt command response. - * - * @sa @ref nrf51_gap_encrypt_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -1000,13 +895,12 @@ uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gap_rssi_get command request. * - * @sa @ref nrf51_rssi_get_encoding for packet format, - * @ref ble_gap_rssi_get_rsp_enc for response encoding. + * @sa @ref ble_gap_rssi_get_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. * @param[in] p_conn_handle Connection handle. - * @param[out] pp_rssi Pointer to pointer to rssi value. + * @param[out] pp_rssi Pointer to pointer to RSSI value. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. @@ -1020,8 +914,7 @@ uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gap_rssi_get command response. * - * @sa @ref nrf51_rssi_get_encoding for packet format. - * @ref ble_gap_rssi_get_req_dec for request decoding. + * @sa @ref ble_gap_rssi_get_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -1039,5 +932,379 @@ uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code, uint32_t * const p_buf_len, int8_t rssi); +/**@brief Decodes @ref sd_ble_gap_keypress_notify command request. + * + * @sa @ref ble_gap_keypress_notify_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Connection handle. + * @param[out] p_kp_not Pointer kp_not value. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_keypress_notify_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint8_t * p_kp_not); + +/**@brief Encodes @ref sd_ble_gap_keypress_notify command response. + * + * @sa @ref ble_gap_keypress_notify_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_keypress_notify_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_lesc_dhkey_reply command request. + * + * @sa @ref ble_gap_lesc_dhkey_reply_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Connection handle. + * @param[out] pp_dhkey Pointer to pointer to dhkey struct. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_lesc_dhkey_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_dhkey_t * * pp_dhkey); + +/**@brief Encodes @ref sd_ble_gap_lesc_dhkey_reply command response. + * + * @sa @ref ble_gap_lesc_dhkey_reply_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_dhkey_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_lesc_oob_data_set command request. + * + * @sa @ref ble_gap_lesc_oob_data_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Connection handle. + * @param[out] pp_oobd_own Pointer to pointer to own OOB data struct. + * @param[out] pp_oobd_peer Pointer to pointer to peer OOB data struct. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_lesc_oob_data_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_oob_data_t * * pp_oobd_own, + ble_gap_lesc_oob_data_t * * pp_oobd_peer); + +/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_set command response. + * + * @sa @ref ble_gap_lesc_oob_data_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_oob_data_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_lesc_oob_data_get command request. + * + * @sa @ref ble_gap_lesc_oob_data_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Connection handle. + * @param[out] pp_pk_own Pointer to pointer to PK. + * @param[out] pp_oobd_own Pointer to pointer to own OOB data struct. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_lesc_oob_data_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gap_lesc_p256_pk_t * * pp_pk_own, + ble_gap_lesc_oob_data_t * * pp_oobd_own); + +/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_get command response. + * + * @sa @ref ble_gap_lesc_oob_data_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_oobd_own Pointer to OOB data. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_lesc_oob_data_get_rsp_enc(uint32_t return_code, + ble_gap_lesc_oob_data_t * p_oobd_own, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gap_addr_get command request. + * + * @sa @ref ble_gap_addr_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_address Pointer to pointer to address. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gap_addr_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_addr_t * * const pp_address); + +/**@brief Encodes @ref sd_ble_gap_addr_get command response. + * + * @sa @ref ble_gap_addr_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_address Pointer to @ref ble_gap_addr_t address + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_addr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_addr_t const * const p_address); + +/** @brief Decodes @ref sd_ble_gap_addr_set command request. + * + * @sa @ref ble_gap_addr_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_addr Pointer to pointer to the address structure. + + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_addr_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * const pp_addr); + +/**@brief Encodes @ref sd_ble_gap_addr_set command response. + * + * @sa @ref ble_gap_addr_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_addr_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @brief Decodes @ref sd_ble_gap_privacy_set command request. + * + * @sa @ref ble_gap_privacy_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_privacy_params Pointer to pointer to the privacy settings structure. + + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_privacy_params_t * * const pp_privacy_params); + +/**@brief Encodes @ref sd_ble_gap_privacy_set command response. + * + * @sa @ref ble_gap_privacy_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @brief Decodes @ref sd_ble_gap_privacy_get command request. + * + * @sa @ref ble_gap_privacy_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_privacy_params Pointer to pointer to the privacy settings structure. + + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + ble_gap_privacy_params_t * * const pp_privacy_params); + +/**@brief Encodes @ref sd_ble_gap_privacy_set command response. + * + * @sa @ref ble_gap_privacy_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[out] p_privacy_params Pointer to privacy settings structure. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_privacy_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gap_privacy_params_t const * const p_privacy_params); + +/** @brief Decodes @ref sd_ble_gap_whitelist_set command request. + * + * @sa @ref ble_gap_whitelist_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] ppp_wl_addrs Pointer to a whitelist of peer addresses. + * @param[out] p_len Pointer to a length of the whitelist. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_whitelist_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_addr_t * * * const ppp_wl_addrs, + uint8_t * const p_len); + +/**@brief Encodes @ref sd_ble_gap_whitelist_set command response. + * + * @sa @ref ble_gap_whitelist_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_whitelist_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @brief Decodes @ref sd_ble_gap_device_identities_set command request. + * + * @sa @ref ble_gap_device_identities_set_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] ppp_id_keys Pointer to an array of peer identity addresses and peer IRKs. + * @param[out] ppp_local_irks Pointer to an array of local IRKs. + * @param[out] p_len Pointer to a length of the device identity list. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_identities_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + ble_gap_id_key_t * * * const ppp_id_keys, + ble_gap_irk_t * * * const ppp_local_irks, + uint8_t * const p_len); + +/**@brief Encodes @ref sd_ble_gap_device_identities_set command response. + * + * @sa @ref ble_gap_device_identities_set_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_device_identities_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_gap_evt_conn.c b/components/serialization/connectivity/codecs/s132/serializers/ble_gap_evt_conn.c new file mode 100644 index 0000000..32ddb3b --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gap_evt_conn.c @@ -0,0 +1,306 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble.h" +#include "ble_gap_evt_conn.h" +#include +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "ble_gap_struct_serialization.h" +#include "conn_ble_gap_sec_keys.h" +#include "app_util.h" + +extern ser_ble_gap_conn_keyset_t m_conn_keys_table[]; + +uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_ADV_REPORT); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.adv_report, ble_gap_evt_adv_report_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_AUTH_KEY_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.gap_evt.params.auth_key_request.key_type); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_AUTH_STATUS); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.auth_status, ble_gap_evt_auth_status_t_enc); + + // keyset is an extension of standard event data - used to synchronize keys at application + uint32_t conn_index; + err_code = conn_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); + if (err_code == NRF_SUCCESS) + { + SER_PUSH_FIELD(&(m_conn_keys_table[conn_index].keyset), ble_gap_sec_keyset_t_enc); + + err_code = conn_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + else + { + err_code = NRF_SUCCESS; + } + + SER_EVT_ENC_END; +} + + +uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.conn_param_update, ble_gap_evt_conn_param_update_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.conn_param_update_request, + ble_gap_evt_conn_param_update_request_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONN_SEC_UPDATE); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.conn_sec_update, ble_gap_evt_conn_sec_update_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONNECTED); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.connected, ble_gap_evt_connected_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_DISCONNECTED); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.disconnected, ble_gap_evt_disconnected_t_enc); + + // If disconnected and context is not yet destroyed, destroy it now + uint32_t conn_index; + err_code = conn_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index); + if (err_code == NRF_SUCCESS) + { + err_code = conn_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + err_code = NRF_SUCCESS; + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_key_pressed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_KEY_PRESSED); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.gap_evt.params.key_pressed.kp_not); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_lesc_dhkey_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_LESC_DHKEY_REQUEST); + + uint8_t ser_data = p_event->evt.gap_evt.params.lesc_dhkey_request.oobd_req & 0x01; + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_COND(p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer, ble_gap_lesc_p256_pk_t_enc); + SER_PUSH_uint8(&ser_data); + + SER_EVT_ENC_END; +} + +#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey) + + +uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_PASSKEY_DISPLAY); + + uint8_t ser_data = p_event->evt.gap_evt.params.passkey_display.match_request & 0x01; + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8array(p_event->evt.gap_evt.params.passkey_display.passkey, BLE_GAP_PASSKEY_LEN); + SER_PUSH_uint8(&ser_data); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_RSSI_CHANGED); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_int8(&p_event->evt.gap_evt.params.rssi_changed.rssi); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SCAN_REQ_REPORT); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.scan_req_report.peer_addr, ble_gap_addr_t_enc); + SER_PUSH_int8(&p_event->evt.gap_evt.params.scan_req_report.rssi); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SEC_INFO_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.sec_info_request, ble_gap_evt_sec_info_request_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SEC_PARAMS_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.sec_params_request, ble_gap_evt_sec_params_request_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SEC_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gap_evt.params.sec_request, ble_gap_evt_sec_request_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GAP_EVT_TIMEOUT); + + SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle); + SER_PUSH_uint8(&p_event->evt.gap_evt.params.timeout.src); + + SER_EVT_ENC_END; +} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn.h b/components/serialization/connectivity/codecs/s132/serializers/ble_gap_evt_conn.h similarity index 78% rename from components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn.h rename to components/serialization/connectivity/codecs/s132/serializers/ble_gap_evt_conn.h index b4233f6..0093734 100644 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gap_evt_conn.h +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gap_evt_conn.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GAP_EVT_CONN_H__ #define BLE_GAP_EVT_CONN_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs * @ingroup ser_codecs */ @@ -32,11 +61,13 @@ */ #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Encodes ble_gap_evt_auth_key_request event. * - * @sa @ref nrf51_evt_auth_key_request_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -55,8 +86,6 @@ uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_auth_status event. * - * @sa @ref nrf51_evt_auth_status_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -75,8 +104,6 @@ uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_conn_param_update event. * - * @sa @ref nrf51_evt_conn_param_update_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -95,8 +122,6 @@ uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_conn_sec_update event. * - * @sa @ref nrf51_evt_conn_sec_update_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -115,8 +140,6 @@ uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_connected event. * - * @sa @ref nrf51_evt_connected_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -135,8 +158,6 @@ uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_disconnected event. * - * @sa @ref nrf51_evt_disconnected_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -155,8 +176,6 @@ uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_passkey_display event. * - * @sa @ref nrf51_evt_passkey_display for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -175,8 +194,6 @@ uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_rssi_changed event. * - * @sa @ref nrf51_evt_rssi_changed_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -195,8 +212,6 @@ uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_sec_info_request event. * - * @sa @ref nrf51_evt_sec_info_request_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -215,8 +230,6 @@ uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_sec_params_request event. * - * @sa @ref nrf51_evt_sec_param_request_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -235,8 +248,6 @@ uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_timeout event. * - * @sa @ref nrf51_evt_timeout_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -255,8 +266,6 @@ uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_sec_request event. * - * @sa @ref nrf51_evt_sec_request_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -275,8 +284,6 @@ uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_conn_param_update_request event. * - * @sa @ref nrf51_evt_conn_param_update_request_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -295,8 +302,6 @@ uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_eve /** * @brief Encodes ble_gap_evt_adv_report event. * - * @sa @ref nrf51_evt_adv_report_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -315,8 +320,6 @@ uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gap_evt_scan_req_report event. * - * @sa @ref nrf51_evt_scan_req_report_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -330,7 +333,48 @@ uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event, uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event, uint32_t event_len, uint8_t * const p_buf, + uint32_t * const p_buf_len); +/** + * @brief Encodes ble_gap_evt_key_pressed event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_key_pressed_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gap_evt_lesc_dhkey_request event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gap_evt_lesc_dhkey_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_gattc_conn.c b/components/serialization/connectivity/codecs/s132/serializers/ble_gattc_conn.c new file mode 100644 index 0000000..94ababa --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gattc_conn.c @@ -0,0 +1,300 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gattc_conn.h" +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" +#include + + +uint32_t ble_gattc_attr_info_discover_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_ATTR_INFO_DISCOVER); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_handle_range); + SER_ASSERT_NOT_NULL(*pp_handle_range); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gattc_attr_info_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_ATTR_INFO_DISCOVER); +} + +uint32_t ble_gattc_char_value_by_uuid_read_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_uuid_t * * const pp_uuid, + ble_gattc_handle_range_t * * const + pp_handle_range) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_uuid); + SER_ASSERT_NOT_NULL(*pp_uuid); + SER_ASSERT_NOT_NULL(pp_handle_range); + SER_ASSERT_NOT_NULL(*pp_handle_range); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_uuid, ble_uuid_t_dec); + SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ); +} + + +uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * * const pp_handles, + uint16_t * const p_handle_count) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_CHAR_VALUES_READ); + + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_handles); + SER_ASSERT_NOT_NULL(*pp_handles); + SER_ASSERT_NOT_NULL(p_handle_count); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_len16data16(pp_handles, p_handle_count); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUES_READ); +} + +uint32_t ble_gattc_characteristics_discover_req_dec( + uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER); +} + + +uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_DESCRIPTORS_DISCOVER); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_DESCRIPTORS_DISCOVER); +} + +uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_HV_CONFIRM); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_handle); + + SER_REQ_DEC_END; +} + +uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_HV_CONFIRM); +} + +uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_start_handle, + ble_uuid_t * * const pp_srvc_uuid) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_start_handle); + SER_PULL_COND(pp_srvc_uuid, ble_uuid_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER); +} + +uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_handle, + uint16_t * const p_offset) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_READ); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_handle); + SER_PULL_uint16(p_offset); + + SER_REQ_DEC_END; +} + +uint32_t ble_gattc_read_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_READ); +} + +uint32_t ble_gattc_relationships_discover_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER); +} + +uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + ble_gattc_write_params_t * * const pp_write_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_WRITE); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_write_params, ble_gattc_write_params_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gattc_write_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_WRITE); +} + +uint32_t ble_gattc_exchange_mtu_request_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_client_rx_mtu) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_client_rx_mtu); + + SER_REQ_DEC_END; +} + +uint32_t ble_gattc_exchange_mtu_request_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST); +} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_conn.h b/components/serialization/connectivity/codecs/s132/serializers/ble_gattc_conn.h similarity index 69% rename from components/serialization/connectivity/codecs/s130/serializers/ble_gattc_conn.h rename to components/serialization/connectivity/codecs/s132/serializers/ble_gattc_conn.h index 3191729..3dd5c26 100644 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_conn.h +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gattc_conn.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATTC_CONN_H__ #define BLE_GATTC_CONN_H__ @@ -18,13 +47,13 @@ */ /** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs * @ingroup ser_codecs */ /**@file * - * @defgroup ble_gatc_conn GATTC Connectivity command request decoders and command response encoders + * @defgroup ble_gatc_conn GATTC connectivity command request decoders and command response encoders * @{ * @ingroup ser_conn_s130_codecs * @@ -33,10 +62,13 @@ #include "ble_gattc.h" #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Decodes @ref sd_ble_gattc_characteristics_discover command request. * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format, - * @ref ble_gattc_characteristics_discover_rsp_enc for response encoding. + * @sa @ref ble_gattc_characteristics_discover_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -56,8 +88,7 @@ uint32_t ble_gattc_characteristics_discover_req_dec /**@brief Encodes @ref sd_ble_gattc_characteristics_discover command response. * - * @sa @ref nrf51_sd_ble_gattc_characteristics_discover_encoding for packet format. - * @ref ble_gattc_characteristics_discover_req_dec for request decoding. + * @sa @ref ble_gattc_characteristics_discover_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -75,8 +106,7 @@ uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code /**@brief Decodes @ref sd_ble_gattc_descriptors_discover command request. * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format, - * @ref ble_gattc_descriptors_discover_rsp_enc for response encoding. + * @sa @ref ble_gattc_descriptors_discover_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -95,8 +125,7 @@ uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const /**@brief Encodes @ref sd_ble_gattc_descriptors_discover command response. * - * @sa @ref nrf51_sd_ble_gattc_descriptors_discover_encoding for packet format. - * @ref ble_gattc_descriptors_discover_req_dec for request decoding. + * @sa @ref ble_gattc_descriptors_discover_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -114,8 +143,7 @@ uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gattc_relationships_discover command request. * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format, - * @ref ble_gattc_relationships_discover_rsp_enc for response encoding. + * @sa @ref ble_gattc_relationships_discover_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -135,8 +163,7 @@ uint32_t ble_gattc_relationships_discover_req_dec /**@brief Encodes @ref sd_ble_gattc_relationships_discover command response. * - * @sa @ref nrf51_sd_ble_gattc_relationships_discover_encoding for packet format. - * @ref ble_gattc_relationships_discover_req_dec for request decoding. + * @sa @ref ble_gattc_relationships_discover_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -154,8 +181,7 @@ uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gattc_primary_services_discover command request. * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format, - * @ref ble_gattc_primary_services_discover_rsp_enc for response encoding. + * @sa @ref ble_gattc_primary_services_discover_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -176,8 +202,7 @@ uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf /**@brief Encodes @ref sd_ble_gattc_primary_services_discover command response. * - * @sa @ref nrf51_sd_ble_gattc_primary_services_discover_encoding for packet format. - * @ref ble_gattc_primary_services_discover_req_dec for request decoding. + * @sa @ref ble_gattc_primary_services_discover_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -195,8 +220,7 @@ uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_cod /**@brief Decodes @ref sd_ble_gattc_read command request. * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format, - * @ref ble_gattc_read_rsp_enc for response encoding. + * @sa @ref ble_gattc_read_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -216,8 +240,7 @@ uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_read command response. * - * @sa @ref nrf51_sd_ble_gattc_read_encoding for packet format. - * @ref ble_gattc_read_req_dec for request decoding. + * @sa @ref ble_gattc_read_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -235,13 +258,12 @@ uint32_t ble_gattc_read_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gattc_char_values_read command request. * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format, - * @ref ble_gattc_char_values_read_rsp_enc for response encoding. + * @sa @ref ble_gattc_char_values_read_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_handles Pointer to pointer to handle table. + * @param[out] pp_handles Pointer to pointer to handle table. * @param[out] p_handle_count Pointer to handle handle table count. * * @retval NRF_SUCCESS Decoding success. @@ -257,8 +279,7 @@ uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_char_values_read command response. * - * @sa @ref nrf51_sd_ble_gattc_char_values_read for packet format. - * @ref ble_gattc_char_values_read_req_dec for request decoding. + * @sa @ref ble_gattc_char_values_read_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -276,8 +297,7 @@ uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gattc_write command request. * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format, - * @ref ble_gattc_write_rsp_enc for response encoding. + * @sa @ref ble_gattc_write_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -295,8 +315,7 @@ uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_write command response. * - * @sa @ref nrf51_sd_ble_gattc_write_encoding for packet format. - * @ref ble_gattc_write_req_dec for request decoding. + * @sa @ref ble_gattc_write_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -314,8 +333,7 @@ uint32_t ble_gattc_write_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gattc_hv_confirm command request. * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format, - * @ref ble_gattc_hv_confirm_rsp_enc for response encoding. + * @sa @ref ble_gattc_hv_confirm_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command response packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -333,8 +351,7 @@ uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gattc_hv_confirm command response. * - * @sa @ref nrf51_sd_ble_gattc_hv_confirm for packet format. - * @ref ble_gattc_hv_confirm_req_dec for request decoding. + * @sa @ref ble_gattc_hv_confirm_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -352,11 +369,10 @@ uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gattc_char_value_by_uuid_read command request. * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format, - * @ref ble_gattc_char_value_by_uuid_read_rsp_enc for response encoding. + * @sa @ref ble_gattc_char_value_by_uuid_read_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of request packet. + * @param[in] packet_len Length (in bytes) of request packet. * @param[out] p_conn_handle Pointer to connection handle of the connection. * @param[out] pp_uuid Pointer to pointer to a characteristic value UUID to read. * @param[out] pp_handle_range Pointer to pointer to the range of handles to perform this @@ -369,15 +385,14 @@ uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code, */ uint32_t ble_gattc_char_value_by_uuid_read_req_dec (uint8_t const * const p_buf, - uint16_t buf_len, + uint16_t packet_len, uint16_t * const p_conn_handle, ble_uuid_t * * const pp_uuid, ble_gattc_handle_range_t * * const pp_handle_range); /**@brief Encodes @ref sd_ble_gattc_char_value_by_uuid_read command response. * - * @sa @ref nrf51_sd_ble_gattc_char_value_by_uuid_read_encoding for packet format. - * @ref ble_gattc_char_value_by_uuid_read_req_dec for request decoding. + * @sa @ref ble_gattc_char_value_by_uuid_read_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[in] p_buf Pointer to buffer where encoded data command response will be @@ -393,6 +408,85 @@ uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len); +/**@brief Decodes @ref sd_ble_gattc_attr_info_discover command request. + * + * @sa @ref ble_gattc_attr_info_discover_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] buf_len Length (in bytes) of request packet. + * @param[out] p_conn_handle Pointer to connection handle of the connection. + * @param[out] pp_handle_range Pointer to pointer to the range of handles. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid operation type. + */ +uint32_t ble_gattc_attr_info_discover_req_dec(uint8_t const * const p_buf, + uint16_t buf_len, + uint16_t * const p_conn_handle, + ble_gattc_handle_range_t * * const pp_handle_range); + +/**@brief Encodes @ref sd_ble_gattc_attr_info_discover command response. + * + * @sa @ref ble_gattc_attr_info_discover_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_attr_info_discover_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/**@brief Decodes @ref sd_ble_gattc_exchange_mtu_request command request. + * + * @sa @ref ble_gattc_exchange_mtu_request_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] p_conn_handle Pointer to connection handle of the connection. + * @param[out] p_client_rx_mtu Pointer to Client RX MTU size. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid operation type. + */ +uint32_t ble_gattc_exchange_mtu_request_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_client_rx_mtu); + +/**@brief Encodes @ref sd_ble_gattc_exchange_mtu_request command response. + * + * @sa @ref ble_gattc_exchange_mtu_request_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[in] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_exchange_mtu_request_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_gattc_evt_conn.c b/components/serialization/connectivity/codecs/s132/serializers/ble_gattc_evt_conn.c new file mode 100644 index 0000000..568ba9e --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gattc_evt_conn.c @@ -0,0 +1,236 @@ +/** + * Copyright (c) 2016 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gattc_evt_conn.h" +#include "ble_serialization.h" +#include "ble_gattc_struct_serialization.h" +#include "app_util.h" +#include + +uint32_t ble_gattc_evt_attr_info_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_ATTR_INFO_DISC_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.attr_info_disc_rsp, + ble_gattc_evt_attr_info_disc_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_CHAR_DISC_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.char_disc_rsp, + ble_gattc_evt_char_disc_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp, + ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_CHAR_VALS_READ_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.char_vals_read_rsp, + ble_gattc_evt_char_vals_read_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_DESC_DISC_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.desc_disc_rsp, + ble_gattc_evt_desc_disc_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_HVX); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.hvx, ble_gattc_evt_hvx_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.prim_srvc_disc_rsp, + ble_gattc_evt_prim_srvc_disc_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_READ_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.read_rsp, + ble_gattc_evt_read_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_REL_DISC_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.rel_disc_rsp, + ble_gattc_evt_rel_disc_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_TIMEOUT); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.timeout, + ble_gattc_evt_timeout_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_WRITE_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.write_rsp, + ble_gattc_evt_write_rsp_t_enc); + + SER_EVT_ENC_END; +} + +uint32_t ble_gattc_evt_exchange_mtu_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_EXCHANGE_MTU_RSP); + + SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle); + SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status); + SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle); + SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.exchange_mtu_rsp, + ble_gattc_evt_exchange_mtu_rsp_t_enc); + + SER_EVT_ENC_END; +} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_conn.h b/components/serialization/connectivity/codecs/s132/serializers/ble_gattc_evt_conn.h similarity index 71% rename from components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_conn.h rename to components/serialization/connectivity/codecs/s132/serializers/ble_gattc_evt_conn.h index 5791655..55dae74 100644 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gattc_evt_conn.h +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gattc_evt_conn.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATTC_EVT_CONN_H__ #define BLE_GATTC_EVT_CONN_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs * @ingroup ser_codecs */ @@ -32,11 +61,13 @@ */ #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Encodes ble_gattc_evt_char_disc_rsp event. * - * @sa @ref nrf51_gattc_evt_char_disc_rsp_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -55,8 +86,6 @@ uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gattc_evt_char_val_by_uuid_read_rsp event. * - * @sa @ref nrf51_gattc_evt_char_val_by_uuid_read_rsp_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -75,8 +104,6 @@ uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_e /** * @brief Encodes ble_gattc_evt_char_vals_read_rsp event. * - * @sa @ref nrf51_gattc_evt_char_vals_read_rsp_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -95,8 +122,6 @@ uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gattc_evt_desc_disc_rsp event. * - * @sa @ref nrf51_gattc_evt_desc_disc_rsp_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -115,8 +140,6 @@ uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gattc_evt_hvx event. * - * @sa @ref nrf51_gattc_evt_hvx_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -135,8 +158,6 @@ uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gattc_evt_prim_srvc_disc_rsp event. * - * @sa @ref nrf51_gattc_evt_prim_srvc_disc_rsp_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -155,8 +176,6 @@ uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gattc_evt_read_rsp event. * - * @sa @ref nrf51_gattc_evt_read_rsp_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -175,8 +194,6 @@ uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gattc_evt_rel_disc_rsp event. * - * @sa @ref nrf51_gattc_evt_rel_disc_rsp_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -195,8 +212,6 @@ uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gattc_evt_timeout event. * - * @sa @ref nrf51_gattc_evt_timeout_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -215,8 +230,6 @@ uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event, /** * @brief Encodes ble_gattc_evt_write_rsp event. * - * @sa @ref nrf51_gattc_evt_write_rsp_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -232,5 +245,48 @@ uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event, uint8_t * const p_buf, uint32_t * const p_buf_len); +/** + * @brief Encodes ble_gattc_evt_attr_info_disc_rsp event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gattc_evt_attr_info_disc_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** + * @brief Encodes ble_gattc_evt_exchange_mtu_rsp event. + * + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ + +uint32_t ble_gattc_evt_exchange_mtu_rsp_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_gatts_conn.c b/components/serialization/connectivity/codecs/s132/serializers/ble_gatts_conn.c new file mode 100644 index 0000000..72d5636 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gatts_conn.c @@ -0,0 +1,422 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gatts_conn.h" +#include +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "app_util.h" +#include "cond_field_serialization.h" + +uint32_t ble_gatts_attr_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_handle, + ble_uuid_t * * pp_uuid, + ble_gatts_attr_md_t * * pp_md) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_ATTR_GET); + + SER_PULL_uint16(p_handle); + SER_PULL_COND(pp_uuid, NULL); + SER_PULL_COND(pp_md, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_attr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_uuid_t * p_uuid, + ble_gatts_attr_md_t * p_md) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_ATTR_GET); + + SER_PUSH_COND(p_uuid, ble_uuid_t_enc); + SER_PUSH_COND(p_md, ble_gatts_attr_md_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_service_handle, + ble_gatts_char_md_t * * const pp_char_md, + ble_gatts_attr_t * * const pp_attr_char_value, + ble_gatts_char_handles_t * * const pp_handles) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD); + + SER_PULL_uint16(p_service_handle); + SER_PULL_COND(pp_char_md, ble_gatts_char_md_t_dec); + SER_PULL_COND(pp_attr_char_value, ble_gatts_attr_t_dec); + SER_PULL_COND(pp_handles, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gatts_char_handles_t const * const p_handles) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD); + + SER_PUSH_COND(p_handles, ble_gatts_char_handles_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_char_handle, + ble_gatts_attr_t * * const pp_attr, + uint16_t * * const pp_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD); + + SER_PULL_uint16(p_char_handle); + SER_PULL_COND(pp_attr, ble_gatts_attr_t_dec); + SER_PULL_COND(pp_handle, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t * p_handle) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD); + + SER_PUSH_COND(p_handle,uint16_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + ble_gatts_hvx_params_t * * const pp_hvx_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_HVX); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_hvx_params, ble_gatts_hvx_params_t_dec); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_bytes_written) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_HVX); + + SER_PUSH_COND(p_bytes_written, uint16_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_service_handle, + uint16_t * const p_inc_srvc_handle, + uint16_t * * const pp_include_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD); + + SER_PULL_uint16(p_service_handle); + SER_PULL_uint16(p_inc_srvc_handle); + SER_PULL_COND(pp_include_handle, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_include_handle) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD); + + SER_PUSH_COND(p_include_handle, uint16_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_initial_user_handle_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * * pp_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET); + + SER_PULL_COND(pp_handle, NULL); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_initial_user_handle_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t * p_handle) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET); + + SER_PUSH_COND(p_handle, uint16_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_rw_authorize_reply_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + ble_gatts_rw_authorize_reply_params_t * * const pp_reply_params) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_RW_AUTHORIZE_REPLY); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_reply_params, ble_gatts_rw_authorize_reply_params_t_dec); + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_RW_AUTHORIZE_REPLY); +} + +uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint8_t * const p_type, + ble_uuid_t * * const pp_uuid, + uint16_t * * const pp_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SERVICE_ADD); + + SER_PULL_uint8(p_type); + SER_PULL_COND(pp_uuid, ble_uuid_t_dec); + SER_PULL_COND(pp_handle, NULL); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t const * const p_handle) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_SERVICE_ADD); + + SER_PUSH_COND(p_handle, uint16_t_enc); + //SER_PUSH_uint16(p_handle); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_conn_handle, + uint16_t * p_start_handle, + uint16_t * p_end_handle) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SERVICE_CHANGED); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_start_handle); + SER_PULL_uint16(p_end_handle); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_SERVICE_CHANGED); +} + +uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * * const pp_sys_attr_data, + uint16_t * * const pp_sys_attr_data_len, + uint32_t * const p_flags) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_COND(pp_sys_attr_data_len, uint16_t_dec); + SER_PULL_COND(pp_sys_attr_data, NULL); + SER_PULL_uint32(p_flags); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint8_t const * const p_sys_attr_data, + uint16_t const * const p_sys_attr_data_len) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET); + + SER_PUSH_COND(p_sys_attr_data_len, uint16_t_enc); + if (p_sys_attr_data_len) + { + SER_PUSH_buf(p_sys_attr_data, *p_sys_attr_data_len); + } + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * const p_conn_handle, + uint8_t * * const pp_sys_attr_data, + uint16_t * const p_sys_attr_data_len, + uint32_t * const p_flags) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SYS_ATTR_SET); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_len16data(pp_sys_attr_data, p_sys_attr_data_len); + SER_PULL_uint32(p_flags); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_SYS_ATTR_SET); +} + +uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_handle, + ble_gatts_value_t * * const pp_value) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_VALUE_GET); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_handle); + + //Special case: skip the data. + SER_PULL_COND(pp_value, NULL); + if (*pp_value) + { + SER_PULL_uint16(&(*pp_value)->offset); + SER_PULL_uint16(&(*pp_value)->len); + SER_PULL_COND(&(*pp_value)->p_value, NULL); + } + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gatts_value_t * const p_value) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_VALUE_GET); + + SER_PUSH_COND(p_value, ble_gatts_value_t_enc); + + SER_RSP_ENC_END; +} + +uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * p_conn_handle, + uint16_t * p_handle, + ble_gatts_value_t * * const pp_value) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_VALUE_SET); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_handle); + SER_PULL_COND(pp_value, ble_gatts_value_t_dec); + + SER_REQ_DEC_END; +} + + +uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_gatts_value_t * p_value) +{ + SER_RSP_ENC_BEGIN(SD_BLE_GATTS_VALUE_SET); + + SER_PUSH_COND(p_value, ble_gatts_value_t_enc); + + SER_RSP_ENC_END; +} + + +uint32_t ble_gatts_exchange_mtu_reply_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_server_rx_mtu) +{ + SER_REQ_DEC_BEGIN(SD_BLE_GATTS_EXCHANGE_MTU_REPLY); + + SER_PULL_uint16(p_conn_handle); + SER_PULL_uint16(p_server_rx_mtu); + + SER_REQ_DEC_END; +} + +uint32_t ble_gatts_exchange_mtu_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_EXCHANGE_MTU_REPLY); +} diff --git a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_conn.h b/components/serialization/connectivity/codecs/s132/serializers/ble_gatts_conn.h similarity index 67% rename from components/serialization/connectivity/codecs/s110/serializers/ble_gatts_conn.h rename to components/serialization/connectivity/codecs/s132/serializers/ble_gatts_conn.h index 8f14c21..3a95649 100644 --- a/components/serialization/connectivity/codecs/s110/serializers/ble_gatts_conn.h +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gatts_conn.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATTS_CONN_H__ #define BLE_GATTS_CONN_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_conn_s110_codecs Connectivity s110 codecs + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs * @ingroup ser_codecs */ @@ -26,18 +55,21 @@ * * @defgroup ble_gatts_conn GATTS Connectivity command request decoders and command response encoders * @{ - * @ingroup ser_conn_s110_codecs + * @ingroup ser_conn_s130_codecs * - * @brief GATTS Connectivity command request decoders and command response encoders + * @brief GATTS Connectivity command request decoders and command response encoders. */ #include "ble_gatts.h" #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Decodes @ref sd_ble_gatts_value_get command request. * - * @sa @ref nrf51_gatts_value_get_encoding for packet format, - * @ref ble_gatts_value_get_rsp_enc for response encoding. + * @sa @ref ble_gatts_value_get_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of request packet. @@ -57,8 +89,7 @@ uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_value_get command response. * - * @sa @ref nrf51_gatts_value_get_sec_response for packet format. - * @ref ble_gatts_value_get_req_dec for request decoding. + * @sa @ref ble_gatts_value_get_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -78,13 +109,12 @@ uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gatts_characteristic_add command request. * - * @sa @ref nrf51_characteristics_add_encoding for packet format, - * @ref ble_gatts_characteristic_add_rsp_enc for response encoding. + * @sa @ref ble_gatts_characteristic_add_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of request packet. + * @param[in] packet_len Length (in bytes) of request packet. * @param[out] p_service_handle Pointer to the service_handle. - * @param[out] constpp_char_md Pointer to pointer to the location where Characteristic metadata + * @param[out] constpp_char_md Pointer to pointer to the location where Characteristic metadata * will be decoded. * @param[out] pp_attr_char_value Pointer to pointer to the location where GATT Attribute will be * decoded. @@ -96,7 +126,7 @@ uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code, * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. */ uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, + uint32_t packet_len, uint16_t * p_service_handle, ble_gatts_char_md_t * * constpp_char_md, ble_gatts_attr_t * * const pp_attr_char_value, @@ -104,8 +134,7 @@ uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const /**@brief Encodes @ref ble_gatts_sys_attr_get_rsp_enc command response. * - * @sa @ref sd_ble_gatts_sys_attr_get for packet format. - * @ref ble_gatts_sys_attr_get_req_dec for request decoding. + * @sa @ref ble_gatts_sys_attr_get_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -125,11 +154,10 @@ uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t /**@brief Decodes @ref sd_ble_gatts_include_add command request. * - * @sa @ref nrf51_gatts_include_add_encoding for packet format, - * @ref ble_gatts_include_add_rsp_enc for response encoding. + * @sa @ref ble_gatts_include_add_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] packet_len Length (in bytes) of request packet. + * @param[in] packet_len Length (in bytes) of request packet. * @param[out] p_service_handle Pointer to the service_handle. * @param[out] p_inc_srvc_handle Pointer to the handle of the included service. * @param[out] pp_include_handle Pointer to Pointer to 16-bit word where the assigned handle will be stored. @@ -146,8 +174,6 @@ uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf, uint16_t * * const pp_include_handle); /**@brief Encodes @ref ble_gatts_include_add_rsp_enc command response. - * - * @sa @ref nrf51_gatts_include_add_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -168,14 +194,13 @@ uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gatts_service_add command request. * - * @sa @ref nrf51_gatts_service_add_encoding for packet format, - * @ref ble_gatts_service_add_rsp_enc for response encoding. + * @sa @ref ble_gatts_service_add_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of request packet. + * @param[in] packet_len Length (in bytes) of request packet. * @param[out] p_type Pointer to the service type. * @param[out] pp_uuid Pointer to pointer to service UUID. - * @param[out] pp_handle Pointer to Pointer to a 16-bit word where the assigned handle will be stored. + * @param[out] pp_handle Pointer to pointer to a 16-bit word where the assigned handle will be stored. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. @@ -183,14 +208,12 @@ uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code, */ uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf, - uint32_t buf_len, + uint32_t packet_len, uint8_t * const p_type, ble_uuid_t * * const pp_uuid, uint16_t * * const pp_handle); /**@brief Encodes @ref ble_gatts_service_add_rsp_enc command response. - * - * @sa @ref nrf51_gatts_service_add_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -211,15 +234,14 @@ uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code, /**@brief Decodes @ref ble_gatts_sys_attr_get_req_dec command request. * - * @sa @ref sd_ble_gatts_sys_attr_get for packet format, - * @ref ble_gatts_sys_attr_get_rsp_enc for response encoding. + * @sa @ref ble_gatts_sys_attr_get_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_conn_handle Pointer to connectiton handle. * @param[out] pp_sys_attr_data Pointer to pointer to buffer where system attributes data will be filled in. * @param[out] pp_sys_attr_data_len Pointer to pointer to variable which contains size of buffer for system attributes. - * @param[out] p_flags Pointer to additional optional flags. + * @param[out] p_flags Pointer to additional optional flags. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. @@ -235,15 +257,14 @@ uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref ble_gatts_sys_attr_get_rsp_enc command response. * - * @sa @ref sd_ble_gatts_sys_attr_get for packet format. - * @ref ble_gatts_sys_attr_get_req_dec for request decoding. + * @sa @ref ble_gatts_sys_attr_get_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be * returned. * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. * \c out: Length of encoded command response packet. - * @param[in] p_sys_attr_data Pointer to buffer where system attributes data are storred. + * @param[in] p_sys_attr_data Pointer to buffer where system attributes data are stored. * @param[in] p_sys_attr_data_len Pointer to variable which contains size of buffer for system attributes. * * @retval NRF_SUCCESS Encoding success. @@ -258,14 +279,13 @@ uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gatts_value_set command request. * - * @sa @ref nrf51_gatts_value_set_encoding for packet format, - * @ref ble_gatts_value_set_rsp_enc for response encoding. + * @sa @ref ble_gatts_value_set_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. - * @param[out] p_conn_handle Pointer to connection handle - * @param[out] p_handle Pointer to attribute handle - * @param[out] pp_value Pointer to pointer to attribute value structure + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_handle Pointer to attribute handle. + * @param[out] pp_value Pointer to pointer to attribute value structure. * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. @@ -280,13 +300,11 @@ uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf, ble_gatts_value_t * * const pp_value); /**@brief Encodes @ref sd_ble_gatts_value_set command response. - * - * @sa @ref nrf51_gatts_value_set_encoding for packet format. * * @param[in] return_code Return code indicating if command was successful or not. - * @param[in] p_buff Pointer to buffer where encoded data command response will be + * @param[in] p_buf Pointer to buffer where encoded data command response will be * returned. - * @param[in, out] p_buff_len \c in: size of \p p_buf buffer. + * @param[in, out] p_buf_len \c in: size of \p p_buf buffer. * \c out: Length of encoded command response packet. * @param[in] p_value \c in: size of value returned when value was written with success * @@ -295,14 +313,13 @@ uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf, * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. */ uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code, - uint8_t * const p_buff, - uint32_t * const p_buff_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len, ble_gatts_value_t * p_value); /**@brief Decodes @ref sd_ble_gatts_sys_attr_set command request. * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format, - * @ref ble_gatts_sys_attr_set_rsp_enc for response encoding. + * @sa @ref ble_gatts_sys_attr_set_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of request packet. @@ -324,8 +341,7 @@ uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_sys_attr_set command response. * - * @sa @ref nrf51_gatts_sys_attr_set_encoding for packet format. - * @ref ble_gatts_sys_attr_set_req_dec for request decoding. + * @sa @ref ble_gatts_sys_attr_set_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -343,8 +359,7 @@ uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code, /**@brief Decodes @ref ble_gatts_hvx_req_dec command request. * - * @sa @ref sd_ble_gatts_hvx for packet format, - * @ref ble_gatts_hvx_rsp_enc for response encoding. + * @sa @ref ble_gatts_hvx_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of request packet. @@ -362,8 +377,7 @@ uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref ble_gatts_hvx_rsp_enc command response. * - * @sa @ref sd_ble_gatts_sys_attr_set for packet format. - * @ref ble_gatts_hvx_req_dec for request decoding. + * @sa @ref ble_gatts_hvx_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -383,14 +397,13 @@ uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gatts_descriptor_add command request. * - * @sa @ref sd_ble_gatts_descriptor_add for packet format, - * @ref ble_gatts_descriptor_add_rsp_enc for response encoding. + * @sa @ref ble_gatts_descriptor_add_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of request packet. * @param[out] p_char_handle Pointer to buffer where characteristic handle will be. returned. - * @param[out] pp_attr Pointer to pointer to an attribute structure. + * @param[out] pp_attr Pointer to pointer to an attribute structure. * @param[out] pp_handle Pointer to pointer to descriptor handle. * * @retval NRF_SUCCESS Decoding success. @@ -405,15 +418,14 @@ uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_descriptor_add command response. * - * @sa @ref sd_ble_gatts_sys_attr_set for packet format. - * @ref ble_gatts_descriptor_add_req_dec for request decoding. + * @sa @ref ble_gatts_descriptor_add_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be * returned. * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. * \c out: Length of encoded command response packet. - * @param[in] handle Descriptor handle value. + * @param[in] p_handle Pointer to descriptor handle value. * * @retval NRF_SUCCESS Encoding success. * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. @@ -422,17 +434,16 @@ uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf, uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len, - uint16_t handle); + uint16_t * p_handle); /**@brief Decodes @ref sd_ble_gatts_rw_authorize_reply command request. * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format, - * @ref ble_gatts_rw_authorize_reply_rsp_enc for response encoding. + * @sa @ref ble_gatts_rw_authorize_reply_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. * @param[out] p_conn_handle Pointer to connection handle. - * @param[out] pp_reply_params Pointer to pointer to \ref ble_gatts_rw_authorize_reply_params_t + * @param[out] pp_reply_params Pointer to pointer to \ref ble_gatts_rw_authorize_reply_params_t . * * @retval NRF_SUCCESS Decoding success. * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. @@ -451,8 +462,7 @@ uint32_t ble_gatts_rw_authorize_reply_req_dec( /**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command response. * - * @sa @ref nrf51_gatts_rw_authorize_reply_encoding for packet format. - * @ref ble_gatts_rw_authorize_reply_req_dec for request decoding. + * @sa @ref ble_gatts_rw_authorize_reply_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -470,8 +480,7 @@ uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_gatts_service_changed command request. * - * @sa @ref nrf51_service_changed_encoding for packet format, - * @ref ble_gatts_service_changed_rsp_enc for response encoding. + * @sa @ref ble_gatts_service_changed_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. * @param[in] packet_len Length (in bytes) of response packet. @@ -492,8 +501,7 @@ uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_gatts_service_changed command response. * - * @sa @ref nrf51_service_changed_encoding for packet format. - * @ref ble_gatts_service_changed_req_dec for request decoding. + * @sa @ref ble_gatts_service_changed_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -509,6 +517,129 @@ uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len); +/**@brief Decodes @ref ble_gatts_attr_get_req_dec command request. + * + * @sa @ref ble_gatts_attr_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_handle Pointer to handle. + * @param[out] pp_uuid Pointer to pointer to location for decoded uuid structure. + * @param[out] pp_md Pointer to pointer to location for md structure. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gatts_attr_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * p_handle, + ble_uuid_t * * pp_uuid, + ble_gatts_attr_md_t * * pp_md); + +/**@brief Encodes @ref ble_gatts_attr_get_rsp_enc command response. + * + * @sa @ref ble_gatts_attr_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_uuid Pointer to structure to be encoded. + * @param[in] p_md Pointer to structure to be encoded. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_attr_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + ble_uuid_t * p_uuid, + ble_gatts_attr_md_t * p_md); + +/**@brief Decodes @ref ble_gatts_initial_user_handle_get_req_dec command request. + * + * @sa @ref ble_gatts_initial_user_handle_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] pp_handle Pointer to pointer to handle. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ +uint32_t ble_gatts_initial_user_handle_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + uint16_t * * pp_handle); + +/**@brief Encodes @ref ble_gatts_initial_user_handle_get_rsp_enc command response. + * + * @sa @ref ble_gatts_initial_user_handle_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_handle Pointer to handle to be encoded. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_initial_user_handle_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + uint16_t * p_handle); + +/**@brief Decodes @ref sd_ble_gatts_rw_authorize_reply command request. + * + * @ref ble_gatts_exchange_mtu_reply_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to beginning of command request packet. + * @param[in] packet_len Length (in bytes) of response packet. + * @param[out] p_conn_handle Pointer to connection handle. + * @param[out] p_server_rx_mtu Pointer to Server RX MTU size. + * + * @retval NRF_SUCCESS Decoding success. + * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length. + * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type. + */ + +uint32_t ble_gatts_exchange_mtu_reply_req_dec(uint8_t const * const p_buf, + uint16_t packet_len, + uint16_t * const p_conn_handle, + uint16_t * const p_server_rx_mtu); + +/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command response. + * + * @ref ble_gatts_exchange_mtu_reply_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_exchange_mtu_reply_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif //BLE_GATTS_CONN_H__ diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_gatts_evt_conn.c b/components/serialization/connectivity/codecs/s132/serializers/ble_gatts_evt_conn.c new file mode 100644 index 0000000..b91ef7c --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gatts_evt_conn.c @@ -0,0 +1,164 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_gatts_evt_conn.h" +#include "ble_serialization.h" +#include "ble_gatts_struct_serialization.h" +#include "conn_ble_user_mem.h" +#include "app_util.h" + +extern sercon_ble_user_mem_t m_conn_user_mem_table[]; + + +uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.authorize_request, ble_gatts_evt_rw_authorize_request_t_enc); + + if((p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) && + ((p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || + (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ))) + { + uint32_t conn_index; + + if(conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) + { + err_code = len16data_enc(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len, p_buf, *p_buf_len, &index); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + } + } + + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_HVC); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.hvc, ble_gatts_evt_hvc_t_enc); + + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_HVC); + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_SYS_ATTR_MISSING); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.sys_attr_missing, ble_gatts_evt_sys_attr_missing_t_enc); + + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_TIMEOUT); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.timeout, ble_gatts_evt_timeout_t_enc); + + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_WRITE); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.write, ble_gatts_evt_write_t_enc); + + if((p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_WRITE_REQ) || (p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)) + { + uint32_t conn_index; + if(conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND) + { + SER_PUSH_len16data(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len); + } + } + + SER_EVT_ENC_END; +} + + +uint32_t ble_gatts_evt_exchange_mtu_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST); + + SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.exchange_mtu_request, ble_gatts_evt_exchange_mtu_request_t_enc); + + SER_EVT_ENC_END; +} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_conn.h b/components/serialization/connectivity/codecs/s132/serializers/ble_gatts_evt_conn.h similarity index 66% rename from components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_conn.h rename to components/serialization/connectivity/codecs/s132/serializers/ble_gatts_evt_conn.h index fdbf24e..7ac6268 100644 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_gatts_evt_conn.h +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_gatts_evt_conn.h @@ -1,14 +1,43 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_GATTS_EVT_CONN_H__ #define BLE_GATTS_EVT_CONN_H__ @@ -18,7 +47,7 @@ */ /** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs * @ingroup ser_codecs */ @@ -32,11 +61,13 @@ */ #include "ble.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Encodes @ref BLE_GATTS_EVT_HVC event. * - * @sa @ref nrf51_gatts_evt_hvc_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -55,8 +86,6 @@ uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event, /** * @brief Encodes @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event. * - * @sa @ref nrf51_evt_rw_authorize_request for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -75,8 +104,6 @@ uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event, /** * @brief Encodes @ref BLE_GATTS_EVT_SC_CONFIRM event. * - * @sa @ref nrf51_gatts_evt_sc_confirm_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -95,8 +122,6 @@ uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event, /** * @brief Encodes @ref BLE_GATTS_EVT_SYS_ATTR_MISSING event. * - * @sa @ref nrf51_evt_sys_attr_missing_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -115,8 +140,6 @@ uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event, /** * @brief Encodes @ref BLE_GATTS_EVT_TIMEOUT event. * - * @sa @ref nrf51_gatts_evt_timeout_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -135,8 +158,6 @@ uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event, /** * @brief Encodes @ref BLE_GATTS_EVT_WRITE event. * - * @sa @ref nrf51_evt_write_encoding for packet format. - * * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. * @param[in] event_len Size (in bytes) of \p p_event buffer. * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. @@ -152,5 +173,28 @@ uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event, uint8_t * const p_buf, uint32_t * const p_buf_len); +/** + * @brief Encodes @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_gatts_evt_exchange_mtu_request_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + /** @} */ + +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_conn.c b/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_conn.c new file mode 100644 index 0000000..3d14fc9 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_conn.c @@ -0,0 +1,157 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include +#include +#include "ble_l2cap_conn.h" +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "cond_field_serialization.h" +#include "app_util.h" + + +uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint16_t * p_cid) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_cid); + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_LENGTH_EQ(3, buf_len); + SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_REGISTER, NRF_ERROR_INVALID_PARAM); + + index++; + err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, buf_len); + + return err_code; +} + + +uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_REGISTER, return_code, + p_buf, p_buf_len); +} + +uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf, + uint32_t buf_len, + uint16_t * p_cid) +{ + uint32_t index = 0; + uint32_t err_code = NRF_SUCCESS; + + SER_ASSERT_NOT_NULL(p_cid); + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_LENGTH_EQ(3, buf_len); + SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_UNREGISTER, NRF_ERROR_INVALID_PARAM); + + index++; + err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + SER_ASSERT_LENGTH_EQ(index, buf_len); + + return err_code; +} + + +uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_UNREGISTER, return_code, + p_buf, p_buf_len); +} + + +uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf, + uint32_t const buf_len, + uint16_t * p_conn_handle, + ble_l2cap_header_t * * const pp_l2cap_header, + uint8_t const * * pp_data) +{ + SER_ASSERT_NOT_NULL(p_buf); + SER_ASSERT_NOT_NULL(p_conn_handle); + SER_ASSERT_NOT_NULL(pp_l2cap_header); + SER_ASSERT_NOT_NULL(*pp_l2cap_header); + SER_ASSERT_NOT_NULL(pp_data); + //SER_ASSERT_NOT_NULL(*pp_data); + + uint32_t err_code = NRF_SUCCESS; + uint32_t index = SER_CMD_DATA_POS; + + err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle); + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_l2cap_header, + ble_l2cap_header_t_dec); + + SER_ASSERT(err_code == NRF_SUCCESS, err_code); + + if (*pp_l2cap_header != NULL) + { + *pp_data = p_buf + index + 1; + index += 1 + (*pp_l2cap_header)->len; + } + else + { + *pp_data = NULL; + index++; + } + + SER_ASSERT_LENGTH_EQ(index, buf_len); + + return err_code; +} + +uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_TX, return_code, + p_buf, p_buf_len); +} diff --git a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_conn.h b/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_conn.h similarity index 67% rename from components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_conn.h rename to components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_conn.h index a4b0d4d..1d5d607 100644 --- a/components/serialization/connectivity/codecs/s130/serializers/ble_l2cap_conn.h +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_conn.h @@ -1,18 +1,51 @@ -/* Copyright (c) 2011 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is confidential property of Nordic Semiconductor. The use, - * copying, transfer or disclosure of such information is prohibited except by express written - * agreement with Nordic Semiconductor. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ + /** * @addtogroup ser_codecs Serialization codecs * @ingroup ble_sdk_lib_serialization */ /** - * @addtogroup ser_conn_s130_codecs Connectivity s130 codecs + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs * @ingroup ser_codecs */ @@ -34,13 +67,16 @@ #include "ble_err.h" #include "ble_l2cap.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@brief Decodes @ref sd_ble_l2cap_cid_register command request. * - * @sa @ref nrf51_ble_l2cap_cid_register for packet format, - * @ref ble_l2cap_cid_register_rsp_enc for response encoding. + * @sa @ref ble_l2cap_cid_register_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. + * @param[in] buf_len Length (in bytes) of response packet. * @param[in] p_cid Pointer to L2CAP CID. * * @retval NRF_SUCCESS Decoding success. @@ -54,8 +90,7 @@ uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_l2cap_cid_register command response. * - * @sa @ref nrf51_ble_l2cap_cid_register for packet format. - * @ref ble_l2cap_cid_register_req_dec for request decoding. + * @sa @ref ble_l2cap_cid_register_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -73,11 +108,10 @@ uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_l2cap_cid_unregister command request. * - * @sa @ref nrf51_ble_l2cap_cid_unregister for packet format, - * @ref ble_l2cap_cid_unregister_rsp_enc for response encoding. + * @sa @ref ble_l2cap_cid_unregister_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. + * @param[in] buf_len Length (in bytes) of response packet. * @param[in] p_cid Pointer to L2CAP CID. * * @retval NRF_SUCCESS Decoding success. @@ -91,8 +125,7 @@ uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_l2cap_cid_unregister command response. * - * @sa @ref nrf51_ble_l2cap_cid_unregister for packet format. - * @ref ble_l2cap_cid_unregister_req_dec for request decoding. + * @sa @ref ble_l2cap_cid_unregister_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -110,11 +143,10 @@ uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code, /**@brief Decodes @ref sd_ble_l2cap_tx command request. * - * @sa @ref nrf51_ble_l2cap_tx for packet format, - * @ref ble_l2cap_tx_rsp_enc for response encoding. + * @sa @ref ble_l2cap_tx_rsp_enc for response encoding. * * @param[in] p_buf Pointer to beginning of command request packet. - * @param[in] buf_len Length (in bytes) of response packet. + * @param[in] buf_len Length (in bytes) of response packet. * @param[in] p_conn_handle Pointer to connection handle. * @param[in] pp_l2cap_header Pointer to pointer to L2CAP header. * @param[in] pp_data Pointer to pointer L2CAP data. @@ -132,8 +164,7 @@ uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf, /**@brief Encodes @ref sd_ble_l2cap_tx command response. * - * @sa @ref nrf51_ble_l2cap_tx for packet format. - * @ref ble_l2cap_tx_req_dec for request decoding. + * @sa @ref ble_l2cap_tx_req_dec for request decoding. * * @param[in] return_code Return code indicating if command was successful or not. * @param[out] p_buf Pointer to buffer where encoded data command response will be @@ -149,6 +180,11 @@ uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code, uint8_t * const p_buf, uint32_t * const p_buf_len); + +#ifdef __cplusplus +} +#endif + #endif //BLE_L2CAP_CONN_H__ /** diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_evt_conn.c b/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_evt_conn.c new file mode 100644 index 0000000..0250dc9 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_evt_conn.c @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "ble_l2cap_evt_conn.h" +#include +#include "ble_serialization.h" +#include "ble_struct_serialization.h" +#include "app_util.h" + + +uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len) +{ + SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_RX); + + SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle); + SER_PUSH_FIELD(&p_event->evt.l2cap_evt.params.rx, ble_l2cap_evt_rx_t_enc); + + SER_EVT_ENC_END; +} diff --git a/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_evt_conn.h b/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_evt_conn.h new file mode 100644 index 0000000..da31f73 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/ble_l2cap_evt_conn.h @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 BLE_L2CAP_EVT_CONN_H__ +#define BLE_L2CAP_EVT_CONN_H__ + +/** + * @addtogroup ser_codecs Serialization codecs + * @ingroup ble_sdk_lib_serialization + */ + +/** + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs + * @ingroup ser_codecs + */ + +/**@file + * + * @defgroup ble_l2cap_evt_conn L2CAP Connectivity event encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief L2CAP Connectivity event encoders. + */ +#include "ble.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Encodes ble_l2cap_evt_rx event. + * + * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded. + * @param[in] event_len Size (in bytes) of \p p_event buffer. + * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet. + * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer. + * \c out: Length of encoded contents in \p p_buf. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event, + uint32_t event_len, + uint8_t * const p_buf, + uint32_t * const p_buf_len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/serialization/connectivity/codecs/s132/serializers/conn_ble_gap_sec_keys.c b/components/serialization/connectivity/codecs/s132/serializers/conn_ble_gap_sec_keys.c new file mode 100644 index 0000000..f6213dd --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/conn_ble_gap_sec_keys.c @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "conn_ble_gap_sec_keys.h" +#include "nrf_error.h" +#include + +ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS]; + +uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index) +{ + uint32_t err_code = NRF_ERROR_NO_MEM; + uint32_t i; + + for (i=0; i + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SER_MAX_CONNECTIONS +#define SER_MAX_CONNECTIONS 2 +#endif + +/**@brief GAP connection - keyset mapping structure. + * + * @note This structure is used to map keysets to connection instances, and will be stored in a static table. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection handle. */ + uint8_t conn_active; /**< Indication that keys for this connection are used by the SoftDevice. 0: keys used; 1: keys not used. */ + ble_gap_sec_keyset_t keyset; /**< Keyset structure, see @ref ble_gap_sec_keyset_t. */ + ble_gap_enc_key_t enc_key_own; /**< Own Encryption Key, see @ref ble_gap_enc_key_t. */ + ble_gap_id_key_t id_key_own; /**< Own Identity Key, see @ref ble_gap_id_key_t. */ + ble_gap_sign_info_t sign_key_own; /**< Own Signing Information, see @ref ble_gap_sign_info_t. */ + ble_gap_lesc_p256_pk_t pk_own; /**< Own Public key, see @ref ble_gap_lesc_p256_pk_t. */ + ble_gap_enc_key_t enc_key_peer; /**< Peer Encryption Key, see @ref ble_gap_enc_key_t. */ + ble_gap_id_key_t id_key_peer; /**< Peer Identity Key, see @ref ble_gap_id_key_t. */ + ble_gap_sign_info_t sign_key_peer; /**< Peer Signing Information, see @ref ble_gap_sign_info_t. */ + ble_gap_lesc_p256_pk_t pk_peer; /**< Peer Public key, see @ref ble_gap_lesc_p256_pk_t. */ +} ser_ble_gap_conn_keyset_t; + +/**@brief Allocates instance in m_conn_keys_table[] for storage of encryption keys. + * + * @param[out] p_index Pointer to the index of allocated instance. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NO_MEM No free instance available. + */ +uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index); + +/**@brief Releases the instance identified by a connection handle. + * + * @param[in] conn_handle conn_handle + * + * @retval NRF_SUCCESS Context released. + * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found. + */ +uint32_t conn_ble_gap_sec_context_destroy(uint16_t conn_handle); + +/**@brief Finds index of the instance identified by a connection handle in m_conn_keys_table[]. + * + * @param[in] conn_handle conn_handle + * + * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle. + * + * @retval NRF_SUCCESS Context table entry found. + * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found. + */ +uint32_t conn_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif //_CONN_BLE_GAP_SEC_KEYS_H diff --git a/components/serialization/connectivity/codecs/s132/serializers/conn_ble_user_mem.c b/components/serialization/connectivity/codecs/s132/serializers/conn_ble_user_mem.c new file mode 100644 index 0000000..83a12a6 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/conn_ble_user_mem.c @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "conn_ble_user_mem.h" +#include "ser_config.h" +#include "nrf_error.h" +#include + + + +sercon_ble_user_mem_t m_conn_user_mem_table[SER_MAX_CONNECTIONS]; + +uint32_t conn_ble_user_mem_context_create(uint32_t *p_index) +{ + uint32_t err_code = NRF_ERROR_NO_MEM; + uint32_t i; + + for (i=0; i + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Connection - user memory mapping structure. + * + * @note This structure is used to map keysets to connection instances, and will be stored in a static table. + */ +//lint -esym(452,ser_ble_user_mem_t) +typedef struct +{ + uint16_t conn_handle; /**< Connection handle.*/ + uint8_t conn_active; /**< Indication that user memory for this connection is used by the SoftDevice. 0: memory used; 1: memory not used. */ + ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t. */ + uint8_t mem_table[64]; /**< Memory table. */ +} sercon_ble_user_mem_t; + +/**@brief Allocates instance in m_user_mem_table[] for storage. + * + * @param[out] p_index Pointer to the index of allocated instance. + * + * @retval NRF_SUCCESS Success. + * @retval NRF_ERROR_NO_MEM No free instance available. + */ +uint32_t conn_ble_user_mem_context_create(uint32_t *p_index); + +/**@brief Releases the instance identified by a connection handle. + * + * @param[in] conn_handle conn_handle + * + * @retval NRF_SUCCESS Context released. + * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found. + */ +uint32_t conn_ble_user_mem_context_destroy(uint16_t conn_handle); + +/**@brief Finds index of the instance identified by a connection handle in m_user_mem_table[]. + * + * @param[in] conn_handle conn_handle + * + * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle. + * + * @retval NRF_SUCCESS Context table entry found. + * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found. + */ +uint32_t conn_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index); +/** @} */ + + +#ifdef __cplusplus +} +#endif + +#endif //_CONN_BLE_USER_MEM_H diff --git a/components/serialization/connectivity/codecs/s132/serializers/nrf_soc_conn.c b/components/serialization/connectivity/codecs/s132/serializers/nrf_soc_conn.c new file mode 100644 index 0000000..5696c82 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/nrf_soc_conn.c @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +#include "nrf_soc.h" +#include "nrf_soc_conn.h" +#include "nrf_error.h" +#include "ble_serialization.h" +#include "cond_field_serialization.h" +#include "nrf_soc_struct_serialization.h" + +uint32_t ecb_block_encrypt_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + nrf_ecb_hal_data_t * * const pp_ecb_data) +{ + SER_REQ_DEC_BEGIN(SD_ECB_BLOCK_ENCRYPT); + SER_PULL_COND(pp_ecb_data, nrf_ecb_hal_data_t_in_dec); + SER_REQ_DEC_END; +} + +uint32_t ecb_block_encrypt_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + nrf_ecb_hal_data_t * const p_ecb_data) +{ + SER_RSP_ENC_BEGIN(SD_ECB_BLOCK_ENCRYPT); + SER_PUSH_COND(p_ecb_data, nrf_ecb_hal_data_t_out_enc); + SER_RSP_ENC_END; +} +uint32_t power_system_off_req_dec(uint8_t const * const p_buf, + uint16_t packet_len) +{ + SER_REQ_DEC_BEGIN(SD_POWER_SYSTEM_OFF); + SER_REQ_DEC_END; +} + +uint32_t temp_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + int32_t * * const pp_temp) +{ + SER_REQ_DEC_BEGIN(SD_TEMP_GET); + SER_PULL_COND(pp_temp, NULL); + SER_REQ_DEC_END; +} + +uint32_t temp_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + int32_t * const p_temp) +{ + SER_RSP_ENC_BEGIN(SD_TEMP_GET); + SER_PUSH_COND(p_temp, uint32_t_enc); + SER_RSP_ENC_END; +} diff --git a/components/serialization/connectivity/codecs/s132/serializers/nrf_soc_conn.h b/components/serialization/connectivity/codecs/s132/serializers/nrf_soc_conn.h new file mode 100644 index 0000000..1cdeb75 --- /dev/null +++ b/components/serialization/connectivity/codecs/s132/serializers/nrf_soc_conn.h @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SOC_CONN_H__ +#define NRF_SOC_CONN_H__ + +/** + * @addtogroup ser_codecs Serialization codecs + * @ingroup ble_sdk_lib_serialization + */ + +/** + * @addtogroup ser_conn_s130_codecs Connectivity S132 codecs + * @ingroup ser_codecs + */ + +/**@file + * + * @defgroup soc_conn SOC Connectivity command request decoders and command response encoders + * @{ + * @ingroup ser_conn_s130_codecs + * + * @brief SOC Connectivity command request decoders and command response encoders. + */ +#include "nrf_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief Decodes @ref sd_power_system_off command request. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] packet_len Length (in bytes) of request packet. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. + */ +uint32_t power_system_off_req_dec(uint8_t const * const p_buf, uint16_t packet_len); + + +/**@brief Decodes @ref sd_temp_get command request. + * + * @sa @ref temp_get_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_temp Pointer to pointer to result of temperature measurement. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. + */ +uint32_t temp_get_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + int32_t * * const pp_temp); + +/**@brief Encodes @ref sd_temp_get command response. + * + * @sa @ref temp_get_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_temp Pointer to result of temperature measurement. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t temp_get_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + int32_t * const p_temp); + +/**@brief Decodes @ref sd_ecb_block_encrypt command request. + * + * @sa @ref ecb_block_encrypt_rsp_enc for response encoding. + * + * @param[in] p_buf Pointer to buffer where encoded data command will be returned. + * @param[in] packet_len Length (in bytes) of request packet. + * @param[out] pp_ecb_data Pointer to pointer to ECB data. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied + * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter. + */ +uint32_t ecb_block_encrypt_req_dec(uint8_t const * const p_buf, + uint32_t packet_len, + nrf_ecb_hal_data_t * * const pp_ecb_data); + +/**@brief Encodes @ref sd_ecb_block_encrypt command response. + * + * @sa @ref ecb_block_encrypt_req_dec for request decoding. + * + * @param[in] return_code Return code indicating if command was successful or not. + * @param[out] p_buf Pointer to buffer where encoded data command response will be + * returned. + * @param[in,out] p_buf_len \c in: size of \p p_buf buffer. + * \c out: Length of encoded command response packet. + * @param[in] p_ecb_data Pointer to ECB data. + * + * @retval NRF_SUCCESS Encoding success. + * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied. + * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length. + */ +uint32_t ecb_block_encrypt_rsp_enc(uint32_t return_code, + uint8_t * const p_buf, + uint32_t * const p_buf_len, + nrf_ecb_hal_data_t * const p_ecb_data); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/components/serialization/connectivity/hal/dtm_uart.c b/components/serialization/connectivity/hal/dtm_uart.c index c7e61b8..ce398f6 100644 --- a/components/serialization/connectivity/hal/dtm_uart.c +++ b/components/serialization/connectivity/hal/dtm_uart.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -55,31 +83,33 @@ * @note If UART bit rate is changed, this value should be recalculated as well. */ -static uint32_t m_baud_rates[] = {[UART_BAUD_RATE_1200] = UART_BAUDRATE_BAUDRATE_Baud1200, - [UART_BAUD_RATE_2400] = UART_BAUDRATE_BAUDRATE_Baud2400, - [UART_BAUD_RATE_4800] = UART_BAUDRATE_BAUDRATE_Baud4800, - [UART_BAUD_RATE_9600] = UART_BAUDRATE_BAUDRATE_Baud9600, - [UART_BAUD_RATE_14400] = UART_BAUDRATE_BAUDRATE_Baud14400, - [UART_BAUD_RATE_19200] = UART_BAUDRATE_BAUDRATE_Baud19200, - [UART_BAUD_RATE_28800] = UART_BAUDRATE_BAUDRATE_Baud28800, - [UART_BAUD_RATE_38400] = UART_BAUDRATE_BAUDRATE_Baud38400, - [UART_BAUD_RATE_57600] = UART_BAUDRATE_BAUDRATE_Baud57600, - [UART_BAUD_RATE_76800] = UART_BAUDRATE_BAUDRATE_Baud76800, - [UART_BAUD_RATE_115200] = UART_BAUDRATE_BAUDRATE_Baud115200, }; - -static uint32_t m_iteration[] = {[UART_BAUD_RATE_1200] = 51, - [UART_BAUD_RATE_2400] = 35, - [UART_BAUD_RATE_4800] = 27, - [UART_BAUD_RATE_9600] = 23, - [UART_BAUD_RATE_14400] = 21, - [UART_BAUD_RATE_19200] = 21, - [UART_BAUD_RATE_28800] = 20, - [UART_BAUD_RATE_38400] = 20, - [UART_BAUD_RATE_57600] = 19, - [UART_BAUD_RATE_76800] = 19, - [UART_BAUD_RATE_115200] = 19, }; - -static uint32_t m_iterations_next_byte_max = 51; +static uint32_t m_baud_rates[] = {[UART_BAUD_RATE_1200] = UART_BAUDRATE_BAUDRATE_Baud1200, + [UART_BAUD_RATE_2400] = UART_BAUDRATE_BAUDRATE_Baud2400, + [UART_BAUD_RATE_4800] = UART_BAUDRATE_BAUDRATE_Baud4800, + [UART_BAUD_RATE_9600] = UART_BAUDRATE_BAUDRATE_Baud9600, + [UART_BAUD_RATE_14400] = UART_BAUDRATE_BAUDRATE_Baud14400, + [UART_BAUD_RATE_19200] = UART_BAUDRATE_BAUDRATE_Baud19200, + [UART_BAUD_RATE_28800] = UART_BAUDRATE_BAUDRATE_Baud28800, + [UART_BAUD_RATE_38400] = UART_BAUDRATE_BAUDRATE_Baud38400, + [UART_BAUD_RATE_57600] = UART_BAUDRATE_BAUDRATE_Baud57600, + [UART_BAUD_RATE_76800] = UART_BAUDRATE_BAUDRATE_Baud76800, + [UART_BAUD_RATE_115200] = UART_BAUDRATE_BAUDRATE_Baud115200, }; + +static uint32_t m_iteration[] = {[UART_BAUD_RATE_1200] = 51, + [UART_BAUD_RATE_2400] = 35, + [UART_BAUD_RATE_4800] = 27, + [UART_BAUD_RATE_9600] = 23, + [UART_BAUD_RATE_14400] = 21, + [UART_BAUD_RATE_19200] = 21, + [UART_BAUD_RATE_28800] = 20, + [UART_BAUD_RATE_38400] = 20, + [UART_BAUD_RATE_57600] = 19, + [UART_BAUD_RATE_76800] = 19, + [UART_BAUD_RATE_115200] = 19, }; + +static uint32_t m_iterations_next_byte_max = 51; + +static nrf_drv_uart_t m_dtm_uart_driver = NRF_DRV_UART_INSTANCE(0); /**@brief Function for UART initialization. */ @@ -98,13 +128,13 @@ static uint32_t uart_init(app_uart_stream_comm_params_t * p_comm_params) config.hwfc = NRF_UART_HWFC_DISABLED; config.parity = NRF_UART_PARITY_EXCLUDED; - nrf_drv_uart_uninit(); - uint32_t err_code = nrf_drv_uart_init(&config, NULL); + nrf_drv_uart_uninit(&m_dtm_uart_driver); + uint32_t err_code = nrf_drv_uart_init(&m_dtm_uart_driver, &config, NULL); if (err_code != NRF_SUCCESS) { return err_code; } - nrf_drv_uart_rx_enable(); + nrf_drv_uart_rx_enable(&m_dtm_uart_driver); m_iterations_next_byte_max = m_iteration[p_comm_params->baud_rate]; @@ -175,7 +205,7 @@ uint32_t dtm_start(app_uart_stream_comm_params_t uart_comm_params) //Will return every timeout, 625 us. current_time = dtm_wait(); - if (NRF_SUCCESS != nrf_drv_uart_rx(&rx_byte,1)) + if (NRF_SUCCESS != nrf_drv_uart_rx(&m_dtm_uart_driver, &rx_byte,1)) { return NRF_ERROR_INTERNAL; } @@ -221,11 +251,11 @@ uint32_t dtm_start(app_uart_stream_comm_params_t uart_comm_params) uint8_t tx_byte = (result >> 8) & 0xFF; //Transmit MSB of the result. - (void)nrf_drv_uart_tx(&tx_byte, 1); + (void)nrf_drv_uart_tx(&m_dtm_uart_driver, &tx_byte, 1); //Transmit LSB of the result. tx_byte = result & 0xFF; - (void)nrf_drv_uart_tx(&tx_byte, 1); + (void)nrf_drv_uart_tx(&m_dtm_uart_driver, &tx_byte, 1); } } } diff --git a/components/serialization/connectivity/hal/dtm_uart.h b/components/serialization/connectivity/hal/dtm_uart.h index cdb5790..41091a7 100644 --- a/components/serialization/connectivity/hal/dtm_uart.h +++ b/components/serialization/connectivity/hal/dtm_uart.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 DTM_UART_H__ @@ -16,8 +44,17 @@ #include #include "dtm_uart_params.h" +#ifdef __cplusplus +extern "C" { +#endif + #define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */ uint32_t dtm_start(app_uart_stream_comm_params_t uart_comm_params); + +#ifdef __cplusplus +} +#endif + #endif // DTM_UART_H__ diff --git a/components/serialization/connectivity/pstorage_platform.h b/components/serialization/connectivity/pstorage_platform.h index 0dbda63..287c127 100644 --- a/components/serialization/connectivity/pstorage_platform.h +++ b/components/serialization/connectivity/pstorage_platform.h @@ -1,42 +1,84 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @cond To make doxygen skip this file */ /** @file - * This header contains defines with respect persistent storage that are specific to + * This header contains defines regarding persistent storage that are specific to * persistent storage implementation and application use case. */ #ifndef PSTORAGE_PL_H__ #define PSTORAGE_PL_H__ #include +#include "nrf.h" -#define PSTORAGE_FLASH_PAGE_SIZE ((uint16_t)NRF_FICR->CODEPAGESIZE) /**< Size of one flash page. */ +#ifdef __cplusplus +extern "C" { +#endif + +static __INLINE uint16_t pstorage_flash_page_size() +{ + return (uint16_t)NRF_FICR->CODEPAGESIZE; +} + +#define PSTORAGE_FLASH_PAGE_SIZE pstorage_flash_page_size() /**< Size of one flash page. */ #define PSTORAGE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */ -#define PSTORAGE_FLASH_PAGE_END \ - ((NRF_UICR->BOOTLOADERADDR != PSTORAGE_FLASH_EMPTY_MASK) \ - ? (NRF_UICR->BOOTLOADERADDR / PSTORAGE_FLASH_PAGE_SIZE) \ - : NRF_FICR->CODESIZE) - +static __INLINE uint32_t pstorage_flash_page_end() +{ + uint32_t bootloader_addr = NRF_UICR->NRFFW[0]; + + return ((bootloader_addr != PSTORAGE_FLASH_EMPTY_MASK) ? + (bootloader_addr/ PSTORAGE_FLASH_PAGE_SIZE) : NRF_FICR->CODESIZE); +} + +#define PSTORAGE_FLASH_PAGE_END pstorage_flash_page_end() #define PSTORAGE_NUM_OF_PAGES 2 /**< Number of flash pages allocated for the pstorage module excluding the swap page, configurable based on system requirements. */ -#define PSTORAGE_MIN_BLOCK_SIZE 0x0010 /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation is not have this value to be at least size of word. */ +#define PSTORAGE_MIN_BLOCK_SIZE 0x0010 /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation for this value is to have at least the size of a word. */ #define PSTORAGE_DATA_START_ADDR ((PSTORAGE_FLASH_PAGE_END - PSTORAGE_NUM_OF_PAGES) \ * PSTORAGE_FLASH_PAGE_SIZE) /**< Start address for persistent data, configurable according to system requirements. */ #define PSTORAGE_DATA_END_ADDR (PSTORAGE_FLASH_PAGE_END * PSTORAGE_FLASH_PAGE_SIZE) /**< End address for persistent data, configurable according to system requirements. */ -#define PSTORAGE_MAX_BLOCK_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. And should be greater than or equal to the minimum size. */ +#define PSTORAGE_MAX_BLOCK_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. Also, should be greater than or equal to the minimum size. */ #define PSTORAGE_CMD_QUEUE_SIZE 30 /**< Maximum number of flash access commands that can be maintained by the module for all applications. Configurable. */ @@ -54,6 +96,11 @@ typedef uint16_t pstorage_size_t; /** Size of length and offset fields. */ /**@brief Handles Flash Access Result Events. To be called in the system event dispatcher of the application. */ void pstorage_sys_event_handler (uint32_t sys_evt); + +#ifdef __cplusplus +} +#endif + #endif // PSTORAGE_PL_H__ /** @} */ diff --git a/components/serialization/connectivity/ser_conn_cmd_decoder.c b/components/serialization/connectivity/ser_conn_cmd_decoder.c index b54afa6..eeb6ea2 100644 --- a/components/serialization/connectivity/ser_conn_cmd_decoder.c +++ b/components/serialization/connectivity/ser_conn_cmd_decoder.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include diff --git a/components/serialization/connectivity/ser_conn_cmd_decoder.h b/components/serialization/connectivity/ser_conn_cmd_decoder.h index ad51944..611772c 100644 --- a/components/serialization/connectivity/ser_conn_cmd_decoder.h +++ b/components/serialization/connectivity/ser_conn_cmd_decoder.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -17,14 +45,14 @@ /** @file * - * @defgroup ser_cmd_decoder Command decoder in the connectivity chip + * @defgroup ser_cmd_decoder Command decoder in the Connectivity Chip * @{ * @ingroup ser_conn * - * @brief Decoder for serialized commands from an Application Chip. + * @brief Decoder for serialized commands from the Application Chip. * * @details This file contains declaration of common function used for commands decoding and sending - * responses back to an Application Chip after a command is processed. + * responses back to the Application Chip after a command is processed. */ #ifndef SER_CONN_CMD_DECODER_H__ @@ -32,12 +60,16 @@ #include -/**@brief A function decodes an encoded command and sends a response to an Application Chip. +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A function decodes an encoded command and sends a response to the Application Chip. * * @details The function decodes an encoded command and calls a SoftDevice API function when a - * command decoder was found or forms a common response with error code + * command decoder is found or forms a common response with error code * NRF_ERROR_NOT_SUPPORTED otherwise. Then the function sends a SoftDevice response or - * the response with NRF_ERROR_NOT_SUPPORTED error code to an Application Chip. + * the response with NRF_ERROR_NOT_SUPPORTED error code to the Application Chip. * * @param[in] p_command The encoded command. * @param[in] command_len Length of the encoded command including opcode. @@ -48,6 +80,11 @@ */ uint32_t ser_conn_command_process(uint8_t * p_command, uint16_t command_len); + +#ifdef __cplusplus +} +#endif + #endif /* SER_CONN_CMD_DECODER_H__ */ /** @} */ diff --git a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c b/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c index 075ae81..343ee7a 100644 --- a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c +++ b/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "app_util.h" diff --git a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h b/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h index 5866845..8d02b0e 100644 --- a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h +++ b/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -17,14 +45,14 @@ /** @file * - * @defgroup ser_dtm_decoder DTM Command Decoder in the connectivity chip + * @defgroup ser_dtm_decoder DTM Command Decoder in the Connectivity Chip * @{ * @ingroup ser_conn * - * @brief Decoder for serialized DTM commands from an Application Chip. + * @brief Decoder for serialized DTM commands from the Application Chip. * * @details This file contains declaration of common function used for DTM commands decoding and - * sending responses back to an Application Chip after a DTM command is processed. + * sending responses back to the Application Chip after a DTM command is processed. */ #ifndef SER_CONN_DTM_CMD_DECODER_H__ @@ -32,11 +60,15 @@ #include -/**@brief A function for processing the encoded DTM commands from an Application Chip. +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A function for processing the encoded DTM commands from the Application Chip. * * @details The function decodes encoded DTM commands and calls the appropriate DTM API. * Then creates a DTM Command Response packet with the return value from the - * DTM API encoded in it and sends it to an Application Chip. + * DTM API encoded in it and sends it to the Application Chip. * * @param[in] p_command The encoded command. * @param[in] command_len Length of the encoded command. @@ -48,14 +80,19 @@ uint32_t ser_conn_dtm_command_process(uint8_t * p_command, uint16_t command_len); -/**@brief A function for checking if Connectivity Chip is ready to enter the DTM mode. +/**@brief A function for checking if the Connectivity Chip is ready to enter the DTM mode. * - * @details The function checks if Connectivity Chip is ready to enter into DTM mode. - * If it is ready then it disables SoftDevice, closes HAL Transport Layer + * @details The function checks if the Connectivity Chip is ready to enter into DTM mode. + * If it is ready, then it disables the SoftDevice, closes HAL Transport Layer, * and starts DTM mode. */ void ser_conn_is_ready_to_enter_dtm(void); + +#ifdef __cplusplus +} +#endif + #endif /* SER_CONN_DTM_CMD_DECODER_H__ */ /** @} */ diff --git a/components/serialization/connectivity/ser_conn_error_handling.c b/components/serialization/connectivity/ser_conn_error_handling.c index ed57952..d7bf584 100644 --- a/components/serialization/connectivity/ser_conn_error_handling.c +++ b/components/serialization/connectivity/ser_conn_error_handling.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "nrf_assert.h" @@ -37,7 +65,7 @@ * @param[in] line_num Line number where the handler is called. * @param[in] p_file_name Pointer to the file name. */ - + #include "app_util_platform.h" #include "nrf_soc.h" @@ -45,25 +73,25 @@ // uint32_t m_error_line_num; // const uint8_t *m_p_error_file_name; -void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name) +void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) { - // disable INTs + // disable INTs CRITICAL_REGION_ENTER(); - #if LEDS_NUMBER > 0 - - /* Light a LED on error or warning. */ + #if LEDS_NUMBER > 0 + + /* Light a LED on error or warning. */ // nrf_gpio_cfg_output(SER_CONN_ASSERT_LED_PIN); // nrf_gpio_pin_set(SER_CONN_ASSERT_LED_PIN); - - #endif - // m_p_error_file_name = p_file_name; + #endif + + // m_p_error_file_name = p_file_name; // m_error_code = error_code; // m_error_line_num = line_num; /* Do not reset when warning. */ - if(SER_WARNING_CODE != error_code) + if (SER_WARNING_CODE != id) { /* This call can be used for debug purposes during application development. * @note CAUTION: Activating code below will write the stack to flash on an error. @@ -80,7 +108,7 @@ void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p #else /* Debug version. */ /* To be able to see function parameters in a debugger. */ uint32_t temp = 1; - while(temp); + while (temp); #endif } diff --git a/components/serialization/connectivity/ser_conn_event_encoder.c b/components/serialization/connectivity/ser_conn_event_encoder.c index 60f1ba1..9751890 100644 --- a/components/serialization/connectivity/ser_conn_event_encoder.c +++ b/components/serialization/connectivity/ser_conn_event_encoder.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include diff --git a/components/serialization/connectivity/ser_conn_event_encoder.h b/components/serialization/connectivity/ser_conn_event_encoder.h index 141ede0..ff580af 100644 --- a/components/serialization/connectivity/ser_conn_event_encoder.h +++ b/components/serialization/connectivity/ser_conn_event_encoder.h @@ -1,23 +1,52 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** * @addtogroup ser_conn Connectivity application code * @ingroup ble_sdk_lib_serialization + * @brief @tagAPI52832 Encoders, decoders, and event handlers related to the Connectivity Chip. */ /** @file * - * @defgroup ser_event_encoder Events encoder in the connectivity chip + * @defgroup ser_event_encoder Events encoder in the Connectivity Chip * @{ * @ingroup ser_conn * @@ -32,19 +61,28 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /**@brief A function for encoding a @ref ble_evt_t. The function passes the serialized byte stream * to the transport layer after encoding. * * @details The function is called by the application scheduler to process an event previously * pulled from BLE SoftDevice. * The function creates a new packet, calls an appropriate event encoder and sends the - * packet to an Application Chip. + * packet to the Application Chip. * * @param[in] p_event_data Pointer to event data of type @ref ble_evt_t. * @param[in] event_size Event data size. */ void ser_conn_ble_event_encoder(void * p_event_data, uint16_t event_size); + +#ifdef __cplusplus +} +#endif + #endif /* SER_CONN_EVENT_ENCODER_H__ */ /** @} */ diff --git a/components/serialization/connectivity/ser_conn_handlers.c b/components/serialization/connectivity/ser_conn_handlers.c index 854fe4f..fb1f5c1 100644 --- a/components/serialization/connectivity/ser_conn_handlers.c +++ b/components/serialization/connectivity/ser_conn_handlers.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include @@ -111,7 +139,6 @@ uint32_t ser_conn_rx_process(void) return err_code; } - void ser_conn_ble_event_handle(ble_evt_t * p_ble_evt) { uint32_t err_code = NRF_SUCCESS; @@ -124,6 +151,12 @@ void ser_conn_ble_event_handle(ble_evt_t * p_ble_evt) err_code = app_sched_event_put(p_ble_evt, sizeof (ble_evt_hdr_t) + p_ble_evt->header.evt_len, ser_conn_ble_event_encoder); APP_ERROR_CHECK(err_code); + uint16_t free_space = app_sched_queue_space_get(); + if (!free_space) + { + // Queue is full. Do not pull new events. + softdevice_handler_suspend(); + } } /** @} */ diff --git a/components/serialization/connectivity/ser_conn_handlers.h b/components/serialization/connectivity/ser_conn_handlers.h index acbd027..dd77ed9 100644 --- a/components/serialization/connectivity/ser_conn_handlers.h +++ b/components/serialization/connectivity/ser_conn_handlers.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ @@ -19,7 +47,7 @@ /** @file * - * @defgroup ser_conn_handlers Events handlers in the connectivity chip + * @defgroup ser_conn_handlers Events handlers in the Connectivity Chip * @{ * @ingroup ser_conn * @@ -41,6 +69,10 @@ #include "ble.h" #include "ser_hal_transport.h" +#ifdef __cplusplus +extern "C" { +#endif + /** Maximum number of events in the application scheduler queue. */ #define SER_CONN_SCHED_QUEUE_SIZE 16u @@ -80,5 +112,10 @@ uint32_t ser_conn_rx_process(void); */ void ser_conn_ble_event_handle(ble_evt_t * p_ble_evt); + +#ifdef __cplusplus +} +#endif + #endif /* SER_CONN_HANDLERS_H__ */ /** @} */ diff --git a/components/serialization/connectivity/ser_conn_pkt_decoder.c b/components/serialization/connectivity/ser_conn_pkt_decoder.c index f158799..498e152 100644 --- a/components/serialization/connectivity/ser_conn_pkt_decoder.c +++ b/components/serialization/connectivity/ser_conn_pkt_decoder.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include @@ -22,6 +50,10 @@ #include "ser_conn_cmd_decoder.h" #include "ser_conn_dtm_cmd_decoder.h" #include "ser_conn_reset_cmd_decoder.h" +#include "ser_dbg_sd_str.h" + +#define NRF_LOG_MODULE_NAME "SER_CONN" +#include "nrf_log.h" uint32_t ser_conn_received_pkt_process( @@ -35,6 +67,9 @@ uint32_t ser_conn_received_pkt_process( uint8_t * p_command = &p_rx_pkt_params->p_buffer[SER_PKT_OP_CODE_POS]; uint16_t command_len = p_rx_pkt_params->num_of_bytes - SER_PKT_TYPE_SIZE; + NRF_LOG_DEBUG("[SD_CALL]:%s\r\n", + (uint32_t)ser_dbg_sd_call_str_get(*p_command)); + switch (p_rx_pkt_params->p_buffer[SER_PKT_TYPE_POS]) { case SER_PKT_TYPE_CMD: @@ -48,7 +83,7 @@ uint32_t ser_conn_received_pkt_process( err_code = ser_conn_dtm_command_process(p_command, command_len); break; } - + case SER_PKT_TYPE_RESET_CMD: { ser_conn_reset_command_process(); diff --git a/components/serialization/connectivity/ser_conn_pkt_decoder.h b/components/serialization/connectivity/ser_conn_pkt_decoder.h index 1f39872..bd58ad9 100644 --- a/components/serialization/connectivity/ser_conn_pkt_decoder.h +++ b/components/serialization/connectivity/ser_conn_pkt_decoder.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -17,11 +45,11 @@ /** @file * - * @defgroup ser_pkt_decoder Packets decoder in the connectivity chip + * @defgroup ser_pkt_decoder Packets decoder in the Connectivity Chip * @{ * @ingroup ser_conn * - * @brief Decoder for serialized packets from an Application Chip. + * @brief Decoder for serialized packets from the Application Chip. * * @details This file contains declaration of common function used for processing packets (packets * dispatcher) received by the transport layer. @@ -33,7 +61,11 @@ #include #include "ser_hal_transport.h" -/**@brief A function for dispatching packets from an Application Chip to an appropriate decoder. +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A function for dispatching packets from the Application Chip to an appropriate decoder. * * @details The function is called to process received packets from a transport layer. * The function analyzes packet type and calls appropriate command decoder which among @@ -49,6 +81,11 @@ uint32_t ser_conn_received_pkt_process( ser_hal_transport_evt_rx_pkt_received_params_t * p_rx_pkt_params); + +#ifdef __cplusplus +} +#endif + #endif /* SER_CONN_PKT_DECODER_H__ */ /** @} */ diff --git a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c b/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c index 9b25fe8..3d96c4a 100644 --- a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c +++ b/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c @@ -1,20 +1,48 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -#include "nrf_soc.h" +#include "nrf_nvic.h" #include "ser_conn_reset_cmd_decoder.h" void ser_conn_reset_command_process() { (void)sd_nvic_SystemReset(); - while(1); + while (1); } diff --git a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h b/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h index 7492642..62ac403 100644 --- a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h +++ b/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ /** @@ -21,10 +49,10 @@ * @{ * @ingroup ser_conn * - * @brief Decoder for serialized reset command from an Application Chip. + * @brief Decoder for serialized reset command from the Application Chip. * * @details This file contains declaration of common function used for reset command decoding and - * sending responses back to an Application Chip after a command is processed. + * sending responses back to the Application Chip after a command is processed. */ #ifndef SER_CONN_RESET_CMD_DECODER_H__ @@ -32,13 +60,22 @@ #include -/**@brief A function for processing the encoded reset commands from an Application Chip. +#ifdef __cplusplus +extern "C" { +#endif + +/**@brief A function for processing the encoded reset commands from the Application Chip. * * @details The function decodes encoded system reset command and performs software reset. - * This command does not send back the Command Response packet to an Application Chip. + * This command does not send back the Command Response packet to the Application Chip. */ void ser_conn_reset_command_process(void); + +#ifdef __cplusplus +} +#endif + #endif /* SER_CONN_RESET_CMD_DECODER_H__ */ /** @} */ diff --git a/components/serialization/connectivity/startup/arm/arm_startup_nrf51.s b/components/serialization/connectivity/startup/arm/arm_startup_nrf51.s index 71f5109..431891c 100644 --- a/components/serialization/connectivity/startup/arm/arm_startup_nrf51.s +++ b/components/serialization/connectivity/startup/arm/arm_startup_nrf51.s @@ -1,20 +1,20 @@ ; Copyright (c) 2013, Nordic Semiconductor ASA ; 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 Nordic Semiconductor ASA 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 @@ -25,8 +25,8 @@ ; 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. - -; NOTE: Template files (including this one) are application specific and therefore + +; NOTE: Template files (including this one) are application specific and therefore ; expected to be copied into the application project folder prior to its use! ; Description message @@ -215,7 +215,7 @@ SWI5_IRQHandler ; User Initial Stack & Heap IF :DEF:__MICROLIB - + EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit diff --git a/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h b/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h index 23fa569..8b808ea 100644 --- a/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h +++ b/components/softdevice/common/softdevice_handler/ant_stack_handler_types.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -22,9 +50,14 @@ #ifndef ANT_STACK_HANDLER_TYPES_H__ #define ANT_STACK_HANDLER_TYPES_H__ +#ifdef __cplusplus +extern "C" { +#endif + #ifdef ANT_STACK_SUPPORT_REQD #include +#include #define ANT_STACK_EVT_MSG_BUF_SIZE 32 /**< Size of ANT event message buffer. This will be provided to the SoftDevice while fetching an event. */ #define ANT_STACK_EVT_STRUCT_SIZE (sizeof(ant_evt_t)) /**< Size of the @ref ant_evt_t structure. This will be used by the @ref softdevice_handler to internal event buffer size needed. */ @@ -32,9 +65,13 @@ /**@brief ANT stack event type. */ typedef struct { - uint8_t channel; /**< Channel number. */ - uint8_t event; /**< Event code. */ - uint8_t evt_buffer[ANT_STACK_EVT_MSG_BUF_SIZE]; /**< Event message buffer. */ + union + { + uint32_t ulForceAlign; ///< force the evt_buffer to be 4-byte aligned, required for some casting to ANT_MESSAGE. + uint8_t evt_buffer[ANT_STACK_EVT_MSG_BUF_SIZE]; ///< Event message buffer. + } msg; + uint8_t channel; ///< Channel number. + uint8_t event; ///< Event code. } ant_evt_t; /**@brief Application ANT stack event handler type. */ @@ -64,6 +101,11 @@ uint32_t softdevice_ant_evt_handler_set(ant_evt_handler_t ant_evt_handler); #endif // ANT_STACK_SUPPORT_REQD + +#ifdef __cplusplus +} +#endif + #endif // ANT_STACK_HANDLER_TYPES_H__ /** @} */ diff --git a/components/softdevice/common/softdevice_handler/app_ram_base.h b/components/softdevice/common/softdevice_handler/app_ram_base.h new file mode 100644 index 0000000..c50c1f7 --- /dev/null +++ b/components/softdevice/common/softdevice_handler/app_ram_base.h @@ -0,0 +1,188 @@ +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * + */ + +// ble_enable param app_ram_base + +#ifndef APP_RAM_BASE_H__ +#define APP_RAM_BASE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef S130 + #define APP_RAM_BASE_CENTRAL_LINKS_0_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20001870 + #define APP_RAM_BASE_CENTRAL_LINKS_0_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20001900 + #define APP_RAM_BASE_CENTRAL_LINKS_0_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20001fe8 + #define APP_RAM_BASE_CENTRAL_LINKS_0_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20002078 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20001ce0 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20001d70 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20001eb0 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20001f40 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002418 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x200024a8 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x200025e0 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002670 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002110 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x200021a0 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x200022d8 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002368 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002840 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x200028d0 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20002a10 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002aa0 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002538 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x200025c8 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20002708 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002798 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002c70 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20002d00 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20002e40 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002ed0 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002968 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x200029f8 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20002b30 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002bc0 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x200030a0 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003130 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003268 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x200032f8 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002d98 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20002e28 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20002f60 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002ff0 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x200034c8 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003558 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003698 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003728 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x200031c0 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003250 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003390 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003420 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x200038f8 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003988 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003ac0 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003b50 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x200035f0 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003680 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x200037b8 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003848 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20003d28 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003db8 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003ef0 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003f80 + #define APP_RAM_BASE_CENTRAL_LINKS_8_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20003a18 + #define APP_RAM_BASE_CENTRAL_LINKS_8_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003aa8 + #define APP_RAM_BASE_CENTRAL_LINKS_8_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003be8 + #define APP_RAM_BASE_CENTRAL_LINKS_8_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003c78 +#elif defined(S132) || defined(S332) + #define APP_RAM_BASE_CENTRAL_LINKS_0_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20001930 + #define APP_RAM_BASE_CENTRAL_LINKS_0_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x200019c0 + #define APP_RAM_BASE_CENTRAL_LINKS_0_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002128 + #define APP_RAM_BASE_CENTRAL_LINKS_0_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x200021b8 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20001e18 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20001ea8 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20001fe8 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002078 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x200025d0 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20002660 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20002798 + #define APP_RAM_BASE_CENTRAL_LINKS_1_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002828 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x200022c0 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20002350 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20002490 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002520 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002a78 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20002b08 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20002c40 + #define APP_RAM_BASE_CENTRAL_LINKS_2_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002cd0 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002768 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x200027f8 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20002938 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x200029c8 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002f20 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20002fb0 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x200030e8 + #define APP_RAM_BASE_CENTRAL_LINKS_3_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003178 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20002c10 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20002ca0 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20002de0 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20002e70 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x200033c8 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003458 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003590 + #define APP_RAM_BASE_CENTRAL_LINKS_4_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003620 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x200030b8 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003148 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003288 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003318 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20003870 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003900 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003a38 + #define APP_RAM_BASE_CENTRAL_LINKS_5_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003ac8 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20003560 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x200035f0 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003730 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x200037c0 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20003d18 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003da8 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003ee0 + #define APP_RAM_BASE_CENTRAL_LINKS_6_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003f70 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20003a08 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003a98 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20003bd8 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20003c68 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x200041c0 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_1_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20004250 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20004388 + #define APP_RAM_BASE_CENTRAL_LINKS_7_PERIPH_LINKS_1_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20004418 + #define APP_RAM_BASE_CENTRAL_LINKS_8_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_1_MID_BW 0x20003eb0 + #define APP_RAM_BASE_CENTRAL_LINKS_8_PERIPH_LINKS_0_SEC_COUNT_0_VS_UUID_COUNT_10_MID_BW 0x20003f40 + #define APP_RAM_BASE_CENTRAL_LINKS_8_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_1_MID_BW 0x20004080 + #define APP_RAM_BASE_CENTRAL_LINKS_8_PERIPH_LINKS_0_SEC_COUNT_1_VS_UUID_COUNT_10_MID_BW 0x20004110 +#endif + + +#ifdef __cplusplus +} +#endif + +#endif // APP_RAM_BASE_H__ diff --git a/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h b/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h index ff600f2..c43b702 100644 --- a/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h +++ b/components/softdevice/common/softdevice_handler/ble_stack_handler_types.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -29,9 +57,23 @@ #include "nrf_sdm.h" #include "app_error.h" #include "app_util.h" +#include "sdk_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + -#define BLE_STACK_EVT_MSG_BUF_SIZE (sizeof(ble_evt_t) + (GATT_MTU_SIZE_DEFAULT)) /**< Size of BLE event message buffer. This will be provided to the SoftDevice while fetching an event. */ -#define BLE_STACK_HANDLER_SCHED_EVT_SIZE 0 /**< The size of the scheduler event used by SoftDevice handler when passing BLE events using the @ref app_scheduler. */ +/** @brief Default Maximum ATT MTU size. + * + * This define should be defined in the sdk_config.h file to override the default. + */ +#ifndef NRF_BLE_GATT_MAX_MTU_SIZE + #define NRF_BLE_GATT_MAX_MTU_SIZE GATT_MTU_SIZE_DEFAULT +#endif + +#define BLE_STACK_EVT_MSG_BUF_SIZE (sizeof(ble_evt_t) + (NRF_BLE_GATT_MAX_MTU_SIZE)) /**< Size of BLE event message buffer. This will be provided to the SoftDevice while fetching an event. */ +#define BLE_STACK_HANDLER_SCHED_EVT_SIZE 0 /**< The size of the scheduler event used by SoftDevice handler when passing BLE events using the @ref app_scheduler. */ /**@brief Application stack event handler type. */ typedef void (*ble_evt_handler_t) (ble_evt_t * p_ble_evt); @@ -59,6 +101,11 @@ uint32_t softdevice_ble_evt_handler_set(ble_evt_handler_t ble_evt_handler); #endif // BLE_STACK_SUPPORT_REQD + +#ifdef __cplusplus +} +#endif + #endif // BLE_STACK_HANDLER_TYPES_H__ /** @} */ diff --git a/components/softdevice/common/softdevice_handler/softdevice_handler.c b/components/softdevice/common/softdevice_handler/softdevice_handler.c index 04187cd..c07d072 100644 --- a/components/softdevice/common/softdevice_handler/softdevice_handler.c +++ b/components/softdevice/common/softdevice_handler/softdevice_handler.c @@ -1,44 +1,90 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2012 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ - #include "softdevice_handler.h" #include -#include "nordic_common.h" -#include "app_error.h" -#include "app_util.h" +#include +#include +#include +#include "nrf.h" #include "nrf_assert.h" #include "nrf_soc.h" -#include "nrf.h" +#include "nrf_nvic.h" +#include "sdk_common.h" + +#if NRF_MODULE_ENABLED(CLOCK) +#include "nrf_drv_clock.h" +#endif // NRF_MODULE_ENABLED(CLOCK) +#include "app_error.h" + +#if NRF_MODULE_ENABLED(RNG) +#include "nrf_drv_rng.h" +#endif // NRF_MODULE_ENABLED(RNG) +#define NRF_LOG_MODULE_NAME "SDH" +#include "nrf_log.h" #if defined(ANT_STACK_SUPPORT_REQD) && defined(BLE_STACK_SUPPORT_REQD) #include "ant_interface.h" -#elif defined(ANT_STACK_SUPPORT_REQD) +#elif defined(ANT_STACK_SUPPORT_REQD) #include "ant_interface.h" #elif defined(BLE_STACK_SUPPORT_REQD) #include "ble.h" #endif -#ifdef NRF51 +#define RAM_START_ADDRESS 0x20000000 #define SOFTDEVICE_EVT_IRQ SD_EVT_IRQn /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ #define SOFTDEVICE_EVT_IRQHandler SD_EVT_IRQHandler -#elif defined (NRF52) -#define SOFTDEVICE_EVT_IRQ SWI2_EGU2_IRQn -#define SOFTDEVICE_EVT_IRQHandler SWI2_EGU2_IRQHandler -#endif /* NRF51 */ +#define RAM_TOTAL_SIZE ((NRF_FICR->INFO.RAM) * 1024) +#define RAM_END_ADDRESS (RAM_START_ADDRESS + RAM_TOTAL_SIZE) + + +#define SOFTDEVICE_VS_UUID_COUNT 0 +#define SOFTDEVICE_GATTS_ATTR_TAB_SIZE BLE_GATTS_ATTR_TAB_SIZE_DEFAULT +#define SOFTDEVICE_GATTS_SRV_CHANGED 0 +#define SOFTDEVICE_PERIPH_CONN_COUNT 1 +#define SOFTDEVICE_CENTRAL_CONN_COUNT 4 +#define SOFTDEVICE_CENTRAL_SEC_COUNT 1 static softdevice_evt_schedule_func_t m_evt_schedule_func; /**< Pointer to function for propagating SoftDevice events to the scheduler. */ static volatile bool m_softdevice_enabled = false; /**< Variable to indicate whether the SoftDevice is enabled. */ - +static volatile bool m_suspended; /**< Current state of the event handler. */ #ifdef BLE_STACK_SUPPORT_REQD // The following three definitions is needed only if BLE events are needed to be pulled from the stack. static uint8_t * mp_ble_evt_buffer; /**< Buffer for receiving BLE events from the SoftDevice. */ @@ -47,30 +93,31 @@ static ble_evt_handler_t m_ble_evt_handler; /**< App #endif #ifdef ANT_STACK_SUPPORT_REQD -// The following two definition is needed only if ANT events are needed to be pulled from the stack. +// The following two definitions are needed only if ANT events are needed to be pulled from the stack. static ant_evt_t m_ant_evt_buffer; /**< Buffer for receiving ANT events from the SoftDevice. */ static ant_evt_handler_t m_ant_evt_handler; /**< Application event handler for handling ANT events. */ #endif static sys_evt_handler_t m_sys_evt_handler; /**< Application event handler for handling System (SOC) events. */ - /**@brief Callback function for asserts in the SoftDevice. * * @details A pointer to this function will be passed to the SoftDevice. This function will be - * called if an ASSERT statement in the SoftDevice fails. + * called by the SoftDevice if certain unrecoverable errors occur within the + * application or SoftDevice. + * + * See @ref nrf_fault_handler_t for more details. * - * @param[in] pc The value of the program counter when the ASSERT call failed. - * @param[in] line_num Line number of the failing ASSERT call. - * @param[in] file_name File name of the failing ASSERT call. + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault. + * @param[in] info Optional additional information regarding the fault. Refer to each fault + * identifier for details. */ -void softdevice_assertion_handler(uint32_t pc, uint16_t line_num, const uint8_t * file_name) +void softdevice_fault_handler(uint32_t id, uint32_t pc, uint32_t info) { - UNUSED_PARAMETER(pc); - assert_nrf_callback(line_num, file_name); + app_error_fault_handler(id, pc, info); } - void intern_softdevice_events_execute(void) { if (!m_softdevice_enabled) @@ -80,8 +127,11 @@ void intern_softdevice_events_execute(void) return; } - +#if NRF_MODULE_ENABLED(CLOCK) + bool no_more_soc_evts = false; +#else bool no_more_soc_evts = (m_sys_evt_handler == NULL); +#endif #ifdef BLE_STACK_SUPPORT_REQD bool no_more_ble_evts = (m_ble_evt_handler == NULL); #endif @@ -95,11 +145,17 @@ void intern_softdevice_events_execute(void) if (!no_more_soc_evts) { + if (m_suspended) + { + // Cancel pulling next event if event handler was suspended by user. + return; + } + uint32_t evt_id; // Pull event from SOC. err_code = sd_evt_get(&evt_id); - + if (err_code == NRF_ERROR_NOT_FOUND) { no_more_soc_evts = true; @@ -111,7 +167,15 @@ void intern_softdevice_events_execute(void) else { // Call application's SOC event handler. +#if (NRF_MODULE_ENABLED(CLOCK) && defined(SOFTDEVICE_PRESENT)) + nrf_drv_clock_on_soc_event(evt_id); + if (m_sys_evt_handler) + { + m_sys_evt_handler(evt_id); + } +#else m_sys_evt_handler(evt_id); +#endif } } @@ -119,6 +183,12 @@ void intern_softdevice_events_execute(void) // Fetch BLE Events. if (!no_more_ble_evts) { + if (m_suspended) + { + // Cancel pulling next event if event handler was suspended by user. + return; + } + // Pull event from stack uint16_t evt_len = m_ble_evt_buffer_size; @@ -143,10 +213,16 @@ void intern_softdevice_events_execute(void) // Fetch ANT Events. if (!no_more_ant_evts) { + if (m_suspended) + { + // Cancel pulling next event if event handler was suspended by user. + return; + } + // Pull event from stack err_code = sd_ant_event_get(&m_ant_evt_buffer.channel, &m_ant_evt_buffer.event, - m_ant_evt_buffer.evt_buffer); + m_ant_evt_buffer.msg.evt_buffer); if (err_code == NRF_ERROR_NOT_FOUND) { no_more_ant_evts = true; @@ -193,12 +269,12 @@ void intern_softdevice_events_execute(void) } } -bool softdevice_handler_isEnabled(void) +bool softdevice_handler_is_enabled(void) { return m_softdevice_enabled; } -uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t clock_source, +uint32_t softdevice_handler_init(nrf_clock_lf_cfg_t * p_clock_lf_cfg, void * p_ble_evt_buffer, uint16_t ble_evt_buffer_size, softdevice_evt_schedule_func_t evt_schedule_func) @@ -212,7 +288,7 @@ uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t clock_source, { return NRF_ERROR_INVALID_PARAM; } - + // Check that buffer is correctly aligned. if (!is_word_aligned(p_ble_evt_buffer)) { @@ -230,48 +306,85 @@ uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t clock_source, m_evt_schedule_func = evt_schedule_func; -//Enabling FPU for SoftDevice -#ifdef S132 - SCB->CPACR |= (3UL << 20) | (3UL << 22); - __DSB(); - __ISB(); -#endif // Initialize SoftDevice. - err_code = sd_softdevice_enable(clock_source, softdevice_assertion_handler); +#if (NRF_MODULE_ENABLED(CLOCK) && defined(SOFTDEVICE_PRESENT)) + bool power_clock_isr_enabled = nrf_drv_common_irq_enable_check(POWER_CLOCK_IRQn); + if (power_clock_isr_enabled) + { + NVIC_DisableIRQ(POWER_CLOCK_IRQn); + } +#endif + +#if (NRF_MODULE_ENABLED(RNG) && defined(SOFTDEVICE_PRESENT)) + bool rng_isr_enabled = nrf_drv_common_irq_enable_check(RNG_IRQn); + if (rng_isr_enabled) + { + NVIC_DisableIRQ(RNG_IRQn); + } +#endif +#if defined(S212) || defined(S332) + err_code = sd_softdevice_enable(p_clock_lf_cfg, softdevice_fault_handler, ANT_LICENSE_KEY); +#else + err_code = sd_softdevice_enable(p_clock_lf_cfg, softdevice_fault_handler); +#endif + if (err_code != NRF_SUCCESS) { + +#if (NRF_MODULE_ENABLED(RNG) && defined(SOFTDEVICE_PRESENT)) + if (rng_isr_enabled) + { + NVIC_EnableIRQ(RNG_IRQn); + } +#endif +#if (NRF_MODULE_ENABLED(CLOCK) && defined(SOFTDEVICE_PRESENT)) + if (power_clock_isr_enabled) + { + NVIC_EnableIRQ(POWER_CLOCK_IRQn); + } +#endif return err_code; } -#ifdef S132 - SCB->CPACR = 0; - __DSB(); - __ISB(); -#endif m_softdevice_enabled = true; +#if (NRF_MODULE_ENABLED(CLOCK) && defined(SOFTDEVICE_PRESENT)) + nrf_drv_clock_on_sd_enable(); +#endif // Enable BLE event interrupt (interrupt priority has already been set by the stack). - return sd_nvic_EnableIRQ(SOFTDEVICE_EVT_IRQ); +#ifdef SOFTDEVICE_PRESENT + return sd_nvic_EnableIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ); +#else + //In case of Serialization NVIC must be accessed directly. + NVIC_EnableIRQ(SOFTDEVICE_EVT_IRQ); + return NRF_SUCCESS; +#endif } uint32_t softdevice_handler_sd_disable(void) { uint32_t err_code = sd_softdevice_disable(); - - m_softdevice_enabled = !(err_code == NRF_SUCCESS); + if (err_code == NRF_SUCCESS) + { + m_softdevice_enabled = false; + +#if (NRF_MODULE_ENABLED(CLOCK) && defined(SOFTDEVICE_PRESENT)) + nrf_drv_clock_on_sd_disable(); +#endif + +#if (NRF_MODULE_ENABLED(RNG) && defined(SOFTDEVICE_PRESENT)) + nrf_drv_rng_on_sd_disable(); +#endif + } return err_code; } - #ifdef BLE_STACK_SUPPORT_REQD uint32_t softdevice_ble_evt_handler_set(ble_evt_handler_t ble_evt_handler) { - if (ble_evt_handler == NULL) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(ble_evt_handler); m_ble_evt_handler = ble_evt_handler; @@ -283,10 +396,7 @@ uint32_t softdevice_ble_evt_handler_set(ble_evt_handler_t ble_evt_handler) #ifdef ANT_STACK_SUPPORT_REQD uint32_t softdevice_ant_evt_handler_set(ant_evt_handler_t ant_evt_handler) { - if (ant_evt_handler == NULL) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(ant_evt_handler); m_ant_evt_handler = ant_evt_handler; @@ -297,10 +407,7 @@ uint32_t softdevice_ant_evt_handler_set(ant_evt_handler_t ant_evt_handler) uint32_t softdevice_sys_evt_handler_set(sys_evt_handler_t sys_evt_handler) { - if (sys_evt_handler == NULL) - { - return NRF_ERROR_NULL; - } + VERIFY_PARAM_NOT_NULL(sys_evt_handler); m_sys_evt_handler = sys_evt_handler; @@ -324,3 +431,157 @@ void SOFTDEVICE_EVT_IRQHandler(void) intern_softdevice_events_execute(); } } + +void softdevice_handler_suspend() +{ +#ifdef SOFTDEVICE_PRESENT + ret_code_t err_code = sd_nvic_DisableIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ); + APP_ERROR_CHECK(err_code); +#else + NVIC_DisableIRQ(SOFTDEVICE_EVT_IRQ); +#endif + m_suspended = true; + return; +} + +void softdevice_handler_resume() +{ + if (!m_suspended) return; + m_suspended = false; + +#ifdef SOFTDEVICE_PRESENT + ret_code_t err_code; + + // Force calling ISR again to make sure that events not pulled previously + // has been processed. + err_code = sd_nvic_SetPendingIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ); + APP_ERROR_CHECK(err_code); + err_code = sd_nvic_EnableIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ); + APP_ERROR_CHECK(err_code); +#else + NVIC_SetPendingIRQ((IRQn_Type)SOFTDEVICE_EVT_IRQ); + NVIC_EnableIRQ(SOFTDEVICE_EVT_IRQ); +#endif + + return; +} + +bool softdevice_handler_is_suspended() +{ + return m_suspended; +} + +#if defined(BLE_STACK_SUPPORT_REQD) +uint32_t softdevice_enable_get_default_config(uint8_t central_links_count, + uint8_t periph_links_count, + ble_enable_params_t * p_ble_enable_params) +{ + memset(p_ble_enable_params, 0, sizeof(ble_enable_params_t)); + p_ble_enable_params->common_enable_params.vs_uuid_count = 1; + p_ble_enable_params->gatts_enable_params.attr_tab_size = SOFTDEVICE_GATTS_ATTR_TAB_SIZE; + p_ble_enable_params->gatts_enable_params.service_changed = SOFTDEVICE_GATTS_SRV_CHANGED; + p_ble_enable_params->gap_enable_params.periph_conn_count = periph_links_count; + p_ble_enable_params->gap_enable_params.central_conn_count = central_links_count; + if (p_ble_enable_params->gap_enable_params.central_conn_count != 0) + { + p_ble_enable_params->gap_enable_params.central_sec_count = SOFTDEVICE_CENTRAL_SEC_COUNT; + } + + return NRF_SUCCESS; +} + + +static inline uint32_t ram_total_size_get(void) +{ +#ifdef NRF51 + uint32_t size_ram_blocks = (uint32_t)NRF_FICR->SIZERAMBLOCKS; + uint32_t total_ram_size = size_ram_blocks; + total_ram_size = total_ram_size * (NRF_FICR->NUMRAMBLOCK); + return total_ram_size; +#elif (defined (NRF52) || defined(NRF52840_XXAA)) + return RAM_TOTAL_SIZE; +#endif /* NRF51 */ +} + +/*lint --e{528} -save suppress 528: symbol not referenced */ +/**@brief Function for finding the end address of the RAM. + * + * @retval ram_end_address Address of the end of the RAM. + */ +static inline uint32_t ram_end_address_get(void) +{ + uint32_t ram_end_address = (uint32_t)RAM_START_ADDRESS; + ram_end_address+= ram_total_size_get(); + return ram_end_address; +} +/*lint -restore*/ + +/*lint --e{10} --e{19} --e{27} --e{40} --e{529} -save suppress Error 27: Illegal character */ +uint32_t sd_check_ram_start(uint32_t sd_req_ram_start) +{ +#if (defined(S130) || defined(S132) || defined(S332)) +#if defined ( __CC_ARM ) + extern uint32_t Image$$RW_IRAM1$$Base; + const volatile uint32_t ram_start = (uint32_t) &Image$$RW_IRAM1$$Base; +#elif defined ( __ICCARM__ ) + extern uint32_t __ICFEDIT_region_RAM_start__; + volatile uint32_t ram_start = (uint32_t) &__ICFEDIT_region_RAM_start__; +#elif defined ( __GNUC__ ) + extern uint32_t __data_start__; + volatile uint32_t ram_start = (uint32_t) &__data_start__; +#endif//__CC_ARM + if (ram_start != sd_req_ram_start) + { + NRF_LOG_WARNING("RAM START ADDR 0x%x should be adjusted to 0x%x\r\n", + ram_start, + sd_req_ram_start); + NRF_LOG_WARNING("RAM SIZE should be adjusted to 0x%x \r\n", + ram_end_address_get() - sd_req_ram_start); + return NRF_SUCCESS; + } +#endif//defined(S130) || defined(S132) || defined(S332) + return NRF_SUCCESS; +} + +uint32_t softdevice_enable(ble_enable_params_t * p_ble_enable_params) +{ +#if (defined(S130) || defined(S132) || defined(S332)) + uint32_t err_code; + uint32_t app_ram_base; + +#if defined ( __CC_ARM ) + extern uint32_t Image$$RW_IRAM1$$Base; + const volatile uint32_t ram_start = (uint32_t) &Image$$RW_IRAM1$$Base; +#elif defined ( __ICCARM__ ) + extern uint32_t __ICFEDIT_region_RAM_start__; + volatile uint32_t ram_start = (uint32_t) &__ICFEDIT_region_RAM_start__; +#elif defined ( __GNUC__ ) + extern uint32_t __data_start__; + volatile uint32_t ram_start = (uint32_t) &__data_start__; +#endif + + app_ram_base = ram_start; + NRF_LOG_DEBUG("sd_ble_enable: RAM start at 0x%x\r\n", + app_ram_base); + err_code = sd_ble_enable(p_ble_enable_params, &app_ram_base); + + if (app_ram_base != ram_start) + { + NRF_LOG_WARNING("sd_ble_enable: RAM start should be adjusted to 0x%x\r\n", + app_ram_base); + NRF_LOG_WARNING("RAM size should be adjusted to 0x%x \r\n", + ram_end_address_get() - app_ram_base); + } + else if (err_code != NRF_SUCCESS) + { + NRF_LOG_ERROR("sd_ble_enable: error 0x%x\r\n", err_code); + } + return err_code; +#else + return NRF_SUCCESS; +#endif //defined(S130) || defined(S132) || defined(S332) + +} +/*lint -restore*/ + +#endif //BLE_STACK_SUPPORT_REQD diff --git a/components/softdevice/common/softdevice_handler/softdevice_handler.h b/components/softdevice/common/softdevice_handler/softdevice_handler.h index 14c44b5..cdd2115 100644 --- a/components/softdevice/common/softdevice_handler/softdevice_handler.h +++ b/components/softdevice/common/softdevice_handler/softdevice_handler.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 @@ -39,10 +67,31 @@ #include "app_util.h" #include "ble_stack_handler_types.h" #include "ant_stack_handler_types.h" +#if defined(BLE_STACK_SUPPORT_REQD) + #include "ble.h" +#endif +#include "app_ram_base.h" +#ifdef __cplusplus +extern "C" { +#endif #define SOFTDEVICE_SCHED_EVT_SIZE 0 /**< Size of button events being passed through the scheduler (is to be used for computing the maximum size of scheduler events). For SoftDevice events, this size is 0, since the events are being pulled in the event handler. */ #define SYS_EVT_MSG_BUF_SIZE sizeof(uint32_t) /**< Size of System (SOC) event message buffer. */ + + +/** @brief Macro for checking the RAM requirement of the SoftDevice. */ +#define CHECK_RAM_START_ADDR(C_LINK_CNT, P_LINK_CNT) + + +/**@brief Function for checking the RAM requirement of the SoftDevice. + * + * @details Call this function to check if the project settings have the correct RAM start address in respect to what the SoftDevice requires. + * + * @note This function is called using the CHECK_RAM_START_ADDR_INTERN macro and should not be called directly. + */ +uint32_t sd_check_ram_start(uint32_t sd_req_ram_start); + /**@brief Type of function for passing events from the stack handler module to the scheduler. */ typedef uint32_t (*softdevice_evt_schedule_func_t) (void); @@ -56,7 +105,7 @@ typedef void (*sys_evt_handler_t) (uint32_t evt_id); * events from the stack, making sure the buffer is correctly aligned. It will also * connect the stack event handler to the scheduler/RTOS (if specified). * - * @param[in] CLOCK_SOURCE Low frequency clock source and accuracy (type nrf_clock_lfclksrc_t, + * @param[in] CLOCK_SOURCE Low frequency clock source and accuracy (type nrf_clock_lf_cfg_t_t, * see sd_softdevice_enable() for details). * @param[in] EVT_HANDLER scheduler/RTOS event handler function. * @@ -66,7 +115,7 @@ typedef void (*sys_evt_handler_t) (uint32_t evt_id); */ /*lint -emacro(506, SOFTDEVICE_HANDLER_INIT) */ /* Suppress "Constant value Boolean */ #define SOFTDEVICE_HANDLER_INIT(CLOCK_SOURCE, \ - EVT_HANDLER) \ + EVT_HANDLER) \ do \ { \ static uint32_t BLE_EVT_BUFFER[CEIL_DIV(BLE_STACK_EVT_MSG_BUF_SIZE, sizeof(uint32_t))]; \ @@ -74,7 +123,7 @@ typedef void (*sys_evt_handler_t) (uint32_t evt_id); ERR_CODE = softdevice_handler_init((CLOCK_SOURCE), \ BLE_EVT_BUFFER, \ sizeof(BLE_EVT_BUFFER), \ - EVT_HANDLER); \ + EVT_HANDLER); \ APP_ERROR_CHECK(ERR_CODE); \ } while (0) @@ -85,7 +134,7 @@ typedef void (*sys_evt_handler_t) (uint32_t evt_id); * @retval false SD is not initialized and SD commands should not be called. * @retval true SD is already initialized */ -bool softdevice_handler_isEnabled(void); +bool softdevice_handler_is_enabled(void); /**@brief Function for initializing the stack handler module. * @@ -96,12 +145,12 @@ bool softdevice_handler_isEnabled(void); * @note Normally initialization should be done using the SOFTDEVICE_HANDLER_INIT() macro, * as that will both allocate the event buffer, and also align the buffer correctly. * - * @param[in] clock_source Low frequency clock source to be used by the SoftDevice. + * @param[in] p_clock_lf_cfg Low frequency clock source to be used by the SoftDevice. * @param[in] p_ble_evt_buffer Buffer for holding one BLE stack event. Since heap is not being * used, this buffer must be provided by the application. The * buffer must be large enough to hold the biggest stack event the * application is supposed to handle. The buffer must be aligned to - * a 4 byte boundary. This parameter is unused if BLE stack support + * a 4 byte boundary. This parameter is unused if BLE stack support * is not required. * @param[in] ble_evt_buffer_size Size of SoftDevice BLE event buffer. This parameter is unused if * BLE stack support is not required. @@ -114,7 +163,7 @@ bool softdevice_handler_isEnabled(void); * @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte * boundary) or NULL. */ -uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t clock_source, +uint32_t softdevice_handler_init(nrf_clock_lf_cfg_t * p_clock_lf_cfg, void * p_ble_evt_buffer, uint16_t ble_evt_buffer_size, softdevice_evt_schedule_func_t evt_schedule_func); @@ -127,6 +176,24 @@ uint32_t softdevice_handler_init(nrf_clock_lfclksrc_t clock_source, */ uint32_t softdevice_handler_sd_disable(void); +/**@brief Function for suspending the event handler. + * + * @details When event handler is disabled, no new events are pulled from SoftDevice. + * Application can suspend pulling incoming events when its event queue is full. + */ +void softdevice_handler_suspend(void); + +/**@brief Function for re-enabling the event handler after suspending. + */ +void softdevice_handler_resume(void); + +/**@brief Function for retrieving the information about the event handler state + * + * @retval false Event handler is active. + * @retval true Event handler is suspended and events from SD will not be pulled. + */ +bool softdevice_handler_is_suspended(void); + /**@brief Function for registering for System (SOC) events. * @@ -144,7 +211,40 @@ uint32_t softdevice_handler_sd_disable(void); */ uint32_t softdevice_sys_evt_handler_set(sys_evt_handler_t sys_evt_handler); +#if defined(BLE_STACK_SUPPORT_REQD) +/**@brief Function for fetching the default enable parameters for the SoftDevice. + * + * @details The default enable parameters will work for most projects in the SDK. + * They are not optimized with regards to RAM use. This function is meant as a way to abstract the + * details of p_ble_enable_params needed by @ref softdevice_enable. You might want to tweak + * the struct returned by this function or fill in the entire ble_enable_params_t + * instead of fetching it from this function. + * + * @param[in] central_links_count Number of central links used by the application. + * @param[in] periph_links_count Number of peripheral links used by the application. + * @param[out] p_ble_enable_params Default ble_enable_params_t to be used by @ref softdevice_enable. + * + * @retval NRF_SUCCESS If the operation was successful. + */ +uint32_t softdevice_enable_get_default_config(uint8_t central_links_count, + uint8_t periph_links_count, + ble_enable_params_t * p_ble_enable_params); +/**@brief Function for enabling the SoftDevice. + * + * @details This function calls the @ref sd_ble_enable SVC call. It has been abstracted to give + * feedback on the app_ram_base. If the app_ram_base is too low, this function will + * return an error. Using a app_ram_base that is too high will not fail, but will + * result in RAM that is never used. If the DEBUG macro is enabled, this + * function will provide the correct app_ram_base as mandated by the SoftDevice. + * This is useful to tweak the RAM use of your application. + * + * @param[in] p_ble_enable_params Parameters for configuring links and bandwidths. + * + * @retval NRF_SUCCESS If the operation was successful. + */ +uint32_t softdevice_enable(ble_enable_params_t * p_ble_enable_params); +#endif //BLE_STACK_SUPPORT_REQD // Functions for connecting the Stack Event Handler to the scheduler: /**@cond NO_DOXYGEN */ void intern_softdevice_events_execute(void); @@ -152,6 +252,11 @@ void intern_softdevice_events_execute(void); /**@endcond */ + +#ifdef __cplusplus +} +#endif + #endif // SOFTDEVICE_HANDLER_H__ /** @} */ diff --git a/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c b/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c index eacb33d..7883972 100644 --- a/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c +++ b/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.c @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ #include "softdevice_handler_appsh.h" diff --git a/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h b/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h index ec78973..1cf67a2 100644 --- a/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h +++ b/components/softdevice/common/softdevice_handler/softdevice_handler_appsh.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 SOFTDEVICE_HANDLER_APPSH_H @@ -16,9 +44,18 @@ #include "softdevice_handler.h" #include +#ifdef __cplusplus +extern "C" { +#endif + #define SOFTDEVICE_HANDLER_APPSH_INIT(CLOCK_SOURCE,USE_SCHEDULER) \ SOFTDEVICE_HANDLER_INIT(CLOCK_SOURCE,(USE_SCHEDULER) ? softdevice_evt_schedule : NULL) uint32_t softdevice_evt_schedule(void); + +#ifdef __cplusplus +} +#endif + #endif //SOFTDEVICE_HANDLER_APPSH_H diff --git a/components/softdevice/s110/doc/s110_nrf51822_8.0.0_migration_document.pdf b/components/softdevice/s110/doc/s110_nrf51822_8.0.0_migration_document.pdf deleted file mode 100644 index 40a448e637471a7d0a04d75003082fbc99d62ea0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 188439 zcmeFXcT`hbyFQu_2?(JGQUa)vCQ1(_bOH!UZ_;}Sy-4pE1W{3>BUM0((vd1X3P=@D zdIzOR7m!}=ihFvIUjrf6) zTD|GprwJ=tmMk0bdD1L-6lAi}9gg^=l z@E}DI!UFs}eEcR-QY07`Ydive!T$?TgpfSK{~H>90EYkofFH@jFNEM1Me>LW{st%b zH#kE7=WzIu0z9JsnQZuwJVF2%L17*dJT!hDk-vcv{yztU;^W~5miZqQ^`~fr@G=3= zhzRo_g%QF4Hss&Xp#B*eyn_El8vL91{x{kD3yz2Yj{qJHz#m}*9-Q#s;E4P)ICusB z3yz=w9}n_>5zZeh7D5T&S+MA{}PTco}K@h&k+UZ)6tui(gj3xY&ByA&^2yQC zC+0TB%GDYpCFSAijMeN-aUHf_a>0tZRz@iIe9;+N}1lfEJfCJ8e>}CI3En^ryCu>S~~AAHTRyq zTt{Y~^!X-?8P?Fy*(p^@P!n%U@-jlQN`S ze|nT~YISF1wVIiSoDq#yeTmf8(OjiketyeYCi6=k!K~-{n~_|LvfcvS2@zePI+vt2 z99`IVVxe&yWemgAs6HRo>r>nueJ63zy*V*@bN7?3!8+)dOS)%KcbcdW2UhNB&@W<+ zngkzd+pb52lwNGVv_ju^KW66I1o2^TQA-Mphzzl?gg zjFLst7{CHQETb}okJ4-EB7#|-1P|z69uiBqm3Fv}yL=4lkFzj-ML)F!Wz;+-5;@+ zHzeff<6KfqgCd9+|IT55u{F8BQqOpbeazE~1^DA0W5qSfQZhc&hmEtQmUObEUTt-v znl+u{k4;tm4DaTP{w2J&IENkj8>sY0Hit6oesHj-lIGebLym4jfk8q0(k55$*!*`-> zW&e}zB)~Fbhe(Lk|BW`yXP=xnflvYJ#(M_R#ULKWhvrGwFg zF$bTsH4S4`Z>1ch)7cBp@pZBfzI0-K63oJ?9n+S1w<7taqOeD*HMPuc>ZiL3$<}cs z?7!O|fDJvAQ0gn*E z7v9kWt2jHerB-{#suE0cN+=+Utm8=Yg7t(y=M{IcrdHpIb)o|32!L(Jv5)O?*bM0M z0IU8?y^}52$xf$w;w{{n=amb*u$apx4!z5GJvo94iod5;Zg0Xi#!7jb#~(Y#nrh7V zYhv6$7|cFaiTSsnE&%ER_*DGWiJ7X|FTV1sGY4L`Xp9u=E->oYq|g6U0jUX!ly25eCEgB6N|h`O&{%1enL6sgP_u_Zq- zO|22hs9H;?bcNy6y?2(NNp1-RF#^XtH+IJA>{r2mtxKYY*7;FD{^;tm`RLOG zXU(_m584YkZk{Kyj*94J_4A4gnd}F6)z_`OXK!}#Q&9B1qvbFXPOyj>I}5&-+s>IR zPt?fUa{={gJZC<`dqBjAe06q05WB0!{d0FTR%K%*BYw`PnLWr_2dY;2?&d-~27dmv zP<3omitO>tqQ%>DbEi*#4Fx7!eyNTA-X}sQOFJVi%<#%at!(_m^jr2$(qc6ZTmAI1 z^NAqQU8@?+)zzVmf{6^~dbjbiH5Stfr>ryy@8PhvTx>Qw-0Z= z6uj$x@`EfkI#(v;^?`oII7``$*Pijp0k=7plDOAKc8Q%LloA`u?u5C&aI%p85%ZWj zrByeLvi_~&{DDBq?T#Jxd^P9T@$3?)g3C2DKN`Q>$SoqmCZ2 zBh~hz*M?+Esk`8&H`eqneEqod#A>XYAX%d~1^@>1Auvpi=^(5730#$VzFpOQTxa5= z0L?J0!^%H)^(57*26EZ ztd~A+@y?d=+B$W}K1w&FsPFS+9t@H;d8|j%p4+lsBlDxk@ERLU@z2_woNJFYy$XK` z@h%kCZ4UlgDIs00WvZT-Ynn0152A}-KR9Lh`KHk0}D>ap#(@cvW5F)Sjcn z-2R6+zGDjtF5WrswT+{>GTRWRUytY9kLX~<^)(Jv6JgYY>MM(78Mto&Kr{_CE!|WZ z?AA7Zcr*A#;aSN<%pOZg_=wZlBWwNrxOHCFkU(^;j>E&Np5e{dJ$J8Z^{I8K+k{8U?@t&A2$fMH8;(9TWeOwBp&rZw6D58&<;8dKV1)X4lFrd zx_|7oR$6l7*Rjv)O!H&M_V+(VR^)sJFB4_7aDD~tzF;MH(&)b!K>&D43qt{mHV?*G~rbMmIUS~@FV_6c@>Zde9o*T1zfzU7;AeA zSy$iR)nuULia?1XO?YKoTwFapjDA<2wScN8emDXs#{O=8*PamkziU1~(eIC&zYp?= z-{mYV#P2c^(ENTM;&4$@KFtOe1L~H)n?F`T{;>*BcE;cQeEFIh2g!8@wT_Z+;O+?`*+p*x0HBg?L9p- zFz#}$&i7qi@ZuNY)w8z-a&=)5A>KdJb^&1|?_G?&t(_-Ah@by|PT_exvsew$BR^d~Y!;?75@j06{>Woxm7qo@ni#6lPDBd`}m!&1;xRQ}7O`lIMF zu=YbT0;h*DoID+kK1PYDtjgsW<#M*}a-B)*!nDmPVR56rjaQPkK7D5o`i}1gRQL3* z_4XWRl-GB%{(s3E%O+`92L_%-gFVSnu;7fgV&yDq{Af6~)==9b8UseygBFh{IGMye z-$L*Ynq)T;Y7N;hmJiFDFPyT05w&NbL=;yk$9T(KXPO%EL+(P{^J4W9B)IV74tO3u z--GE3o%?MztLK>H=wuP%$JpbH3+64@Tpb4?3jER6$#54yJ7+mMnvt%m+bQ6j)YJPPnvv!s4P$ z#8vsKtSpP;z4c$rRU{MD&V~3FVsEgPDsB9Adj11!TKS;BY$+Ar5U7Y6n?r0*6>(AC zzWv3O*qNC+uhm3uqXPL`G{Vl~_b%cwsNXeBnB){SP^5{TU|Uk=Nn+x!wQ4fL-C;8? z0Pk(iH2Z9tY9UlWgF{1_t-`L;Dw@S_-;Ta_`yNilI9zO0CBC_V%t|zOEl&dHFmF`4@{;;o&JI=kGCj=`NgyaJ9E-@$ z&(Gq}oaA^_s8?$G&ay3*O_`S4u=4)gM?zBCo($;+SMfk4WL)CYZu$-7D!=40Yih{J z32P|MAu1>=RD?ydu={XDUWyK7N2&IXi>Tu&V8HI{z1Nuu%bh2x3kq&U^c3h6((;;0 z09yF=?b}W5Je4#Nx08dP-#(opCqf;?f0d$wiGF z+)529Y+Ay}QUS3w_<1-xbBki!Kj$goQem_81gvEDXK^8bZjoeYlCWM=LqjDh%+cM-ECDeDteF!DmU!S<4O6p{1hZuTiKadw2OBK=iyV)SeyURuwp+eQmrs|5SV%72q5Cp*L5%-c>q_q9v95K70bOm$Lbd^244V!6P{>h) zrr^M>!LH$L8yx|oiB}Lwl!?2Aw*8M`^&7*guk@wm%dTj%3zG<2jKp93tj)fbjLgDx zh3S6yRHY8D@#%UWL|Z+wRS~rEUiSlgrAm64?Mm2UKDD=MdOyc#>lN)A!_Rb4m~X?K z)TzUXS}KO*B>(awu~Y|JEfmtHyV`jdgk2`}b#!!$j3!1$-v{iwG|8bEE^i?q2T#F8 zoaTTx0yu=hV7e2z0naCte;BPLB=+v z;d58V3zu@LUR_r`XBt}-)}m+?u7)B6ua)kbo4=G<3x`tg=`DMG6s~f))Pta*-C~x} zB$SoR8+5OTPtho#*A937v-SG+9I!w}BZ z^?2MZ0XFknP^WnGa4V=2%NXot@x5TksGTlm=ml>9quD)ai=G!3tr%`Rw@=}-8ENJJ zOx<3o!Zc8zU(ZNQp3JJ>ox}e*?$cU|V4nTAq)$(+yj7UArQKAf!d{PGlsA%hG;U0> zltrT5Ip!TY=ahm7TpNCd3ySdpBxO@hj0dilFDtUZCXYd)o)jiv&-izo*m&rV$STK? z-c*!pPZIzBbigKHP|sK+j5c}edlf?W_0oJr$9O*6Dz{fHNT}zpd1xK_q32jJDgP)d z)rs3Sm#m=JB9HoFtQ+%(N(z~g$g)We`jy>>GD9#g!~9Gk9qzjY=%UQGc`4bu6g|i% z;9U^zqy3k4co`i8@K(k2`uQ{v1-7!T1S;YZBdj&+t~I>)SZz)3IEmhY)9#< zCi|VsN9qcwKxExJyUSxGuQfl*XYXB(bbyN&=#)`Ra6cEWvVZXP%yaP7yX=(q7vnG zG>Pr)h3=7JBRvCyn_k4x-8NSUOuD#aT#;yhwX))3)fD($rO@3^T?w4eo;{lh+MlZE zlR5^RPl>xIZ6-B{VYAeCUe)@uWJ1K3n`uV5D91g!R25Z~hxwx%BL-cs$f`nLr#eAw zS80sejj|oe4ecm<-qI?0(>v9h=LL~+l2yx2becPK8@PrdLDzq=@=5ZQDqP`;E~tm6 za{EJy9A|MR5H4MtIGRuzh{t3E*mjCQIqk(I-%VQL2@tpw8%&pG)@w5;>hef z!q2Z7@EWc!#~9s-oJ2ZU|Kga-Nx1f+$gCmB@?$q>+il*v^HA#7pmu5V+0k3gY<9IY z5vxzn<)6_e0Q^cwct;L)pZppZI{k?-=PCGP9tR{BM@L61D=TD-!dwRB^MLyg+WCya zM}?dICE>HE`=pF80<7_ko#Ua`&g>H`qqIcTV-@R(#pBW*%$hxH7i{y6J}B0NPWG8g zUXzoSun@nR#Tm*LYjAm*Dy|czq$iiobun?U>lC5_<6}b%g~ZaMDL`C3i@GphdUn1c zNJW)DV(Jw*lwNMeEYKiZS>O|{7e(KM zY27Mj2_JbuZ^~=f@??bZPQ$d|w_i3NOyiyhO77%To~%HkR)(L{U%d0>-Q|argB^2K zERS8Uhz53d%nh+T){CS!y>58;WX@}6NmIoaj;<0rWnDT3oLKYjS7oioxWRnwrQY;< z%eIJLt0Qr#C5447FS#4_qBA&_RiSrFNk=Pe)vc_ooSmI9n1%5wM>;NjKJT?rAX;mx zkbAPLUQzw=qBnWf;mu2zIcI1MTG&=@D*Th0HW+sjtg75M>|_whIAMt)XNwRR%N(H~ zAAG3z7;=-Sv&cp@sn^49Fm>Q&On7a~*R?x}R7IBqC~`g!D#Gr@5xwn7(Pp_7!W}`C zxpGMoRCYi0@hfmf8}_j%Bz!ECwAO+kfUT@m>Ed9rC#gt^7=2eh0V||L>Ufu1AVT?E z)OVdTbfgjK`<*kiJG@DQfA>*W7U56}Ni~dfRIDgdw{pFO#2dzGN52=CZP#*k_Ni49Cetgk_P)ClGBT$Sq-LcVEODy2?bIXW}ypWEL_1K+8Ag3TAW7r)w zat#9V3hEnbK>EO5)vv6qjB*~Ybe<5lH%9x1ppTH5#l_D18&giVGl8V+UVHns2P$H% zO3-NN!Kna6+VNvj-s6d?m(rt~5s!a)ABK*Y_@4{CnF^fFF!e2H$ajpB0r71%7gxQ} zt*jFkFZ^XwT;QxcV`#mT$>S7uVaCj2X31O(m&N#o?}aYCP^eql$Ii7bGGn?hwR?9T z%6x^eMbKw5$mtMFw2Fo`P`wp?2@cUa=1a;yZ1wkYgA2npp z>Vn!;=8m&_;8?I;`eEFPy|!K>U*`NHa4s)QfBz%)m)xrwUUS2Tnp`%6%?0 z#T&V{tMU_Bqy5q|eE|>hz;>tPm?g1=`y`KLv-vnp1HD_G^_4vMIp!5g6iH5p5$w`%si3*tc z4rHtqdvxSa;)hR7^-9u!+`79yB*cIUk|znV@431wY=P^PyD)YS&r6Zh!LH7@L<(Q`1?&wyp!tlwp`7s`aB3&Y zHSp|bgiMrPER95ye5EsC)JTMG-x%lq*`t%-LIUmq2K%_m9pOKv+1j&4`-1|U z`a@ySi$qGil!>Nv=(z!dJoSvTxyRSY83a3&penpm+i^zz>0UE^w29p7D?ivd4G(`z zMzp0%PGu*)Fwts^9c~br8xlAlT-u#Uuc<889HA&v9RxW_)pJMv^grCIzM7p}@bIuD zs$*5Uc~DpMec1{jikP2XR660cxuyBWs-Kw4LD9Qv`E{N$q&$V^4!a@&qXoh)l!j&7 zj`dh3tDcsDy95V(CyCj{j zvM8vHeyLE>Bsf{d3R-CdM`*+V6yM}a;v`jq^=wPn;v(tq176nnqAxv5$2dMTNwo)h z9rnNcWOlZ5QST)1D~)tUU|ZiC6Soh~3we@)hWZvwhHO8S9&y#y^+gmO7uD6NcMb&& zn@-uL50f1IVi}ovi|(!rcQ)a?TBQUF`Iyzup+b`U@q8_Ul>M1)&d%2{Jy_6FOUql3 zjfS0Gz~WEv2b!gHAE~3|Y<1~VPashTl0u{A;2<5H1VKscBuZMD?+P59rI~bj8_3+3 zx!T&=t_5y=*y)pYWr3(2pVr!*{#ts#@UuUwM9uwZKlq@7Q($^yZA0n#!H)ROo%QJ% z_pzO3(bZDAw3y|_qH;|XEtPFl8gyO4yVW;FhTKUAq zLN7KmeB|7+7s!hrChs#6A6d*d+`B^j(7qMDuPab!!R~*eBW9r?dX6ehu&*O65+^C} z9CjKrL4VBDiUH@5$k^&KXBkI>F_7EvvXXZv$*HtGF41pDiZsM7&_0Wz=qZi4#$=8J zr30p6=q*MxDWw7AoQp;<>LhjgEe@!ET0{t?CuuZHC11W`Sp| z&-yalfBLmGOSmrb_NDK1o9^(eS1p&DcJr)OeJeLD1e(Qi)7&%~;{fi%Q!(y`RPXl; z?H>z$)8uTWJh-V^j-lL(VC1(=pSAeDk zPx#rMpMI25H?8(x70ZUvH@kQFMVYzp&G1OfXzK3;3-3T5Ff}N(_iURB zLz3d-m>mvCPu*pwVmI0IhL?J^%aR)P#H?_0`k=C5$dvU2YsDo9E99uptnFTi4AhDL zIi0@uCBbe6To)^UnWxgXCwkqx--*fZfd`a+XT?3?(d;)NW5|wULz6zmPbiC7eP!bJOg< z$zIkc`8WUHRP@&_Klhw|N4K9PqM@RK!L8TKoGoWZkzbWK_>7v#2|ol%3bs8-?|gq+ zPI1Y&f3xob?ImG%uYgG&bjGr2zflX?Y}|*!=%clu(WMW3dj#fB6`_-;l`r4OJc1?H zd|Z3E8`jPC;TWtSC)TjFiu2CZtlbsmjii&akEj*u6S@}}6<c~>^Mu__% z{iuSPnW&Yf&c5z1+v!;vn@~bavkyrl^FhG^RWe^eoO$e{UP;&Ou;Edzy#W?0C&AyO z1Wa?ABX#QQ-wb?=KP23KRdZS|O9|<|0Ovc;PHpwN^E`>CJG5Lz>B(uHAcw)@|C`9xXgpdtbNN3N(jaGxj69+)a6#MUF?kjd`079gleG@;1v? zk4oN`Y!(F5mHhCruy4*#R%mL{lG!>QF)KBaJMKU8ynIFZIv15(DrdL~5JQ%YsoU^w zujvfg1|&BU+Z`;t4O<@>fkPiqdx>I1xd0WPXF%Pm!bVkIp0IW;JRJJN0z88OJ&goH zRm1T{JrKgu5?~yr*{x5u)TZ>oNqp93&$VAiYd+_$vk8?y(unTCaqL80 z6$GZdrF!)Q7vN>4-W##DbdAlGTz-M?Q0D3HZ^VHk+%Y;X&S-d+2+?QWM=TDpIH~F0*-=VO^0UwZlv?0s8_A-VnKSCy?3MesHj*FE8 zwtAV3Cq&e=qc`mk4a}C1wdM=W2;N%)S65YKeW9 z23OnAT{YxlDcsQ^`2-&)u~yAZE5&ovt|vopP-hNZk3Dk5V9`xnDsyk*!S_0MkeT})FQvtQ z3sTZUl#lVw>~HnwMo0B103BB4t-v5A8s|;@1MAgUqJ68BmywUuZL>VS zz<)G&dPhLoT1}y_Yf@=1!C%`6b4tl<%%Ej8UCY)u-f&|*!RY0}b@%ZMo zE8??R>aTvBj^-|g5)6?Br@o{&`%FQ?x4EeWy+;ZGi-)0a!!@|cNILqiY;|wH$J%J1 z(;3Z^Sk13P4&b3FG9jPbP8Z%`4c$(S^NG;$V4%vb2`yrWZyAp1x-ekPW3y}g6E$`^ zuv`$EhLjOkhfwcC^Oj~dc>m<*fCtqGk)Qy0<_mHT52y&d%vwp-z=hsx;8Gv&+#*!4 zAe7+SB=!}C76}R^D4VSAd2#t*LSWYZIqu#?t_uGetXB>8=M=$WDbwyICX^Kt9Mtu+ z@Y9Rb<5szfs|PG&4MdyQjdo`xm9I7hv}OC0`tNSU-r3|iZBMsmyxQ#1LhX|%>1JE| zC;=V}lwaaKeV@`ZJW{;QOVuaKo*v(;=9ZaM$wVpL=Ex3#k}?WHILU^qyOP-w4#iukq zLVNFj-EH2c+o7^5e1vf$$MV6=CzNtC%(f5Q&mW9YzMGRyJ!#4$8WaVk>@^KZpe+#S z`=>+O+fU&0%a1mW!Ul&*lQQ$mA@Ykw8flS=8E!4B5=|-Gr3UDn-r%Dq%M`+ zdooJpc35HIH=^otSvRq-nMXYyEUp7D)Ah@rRoYMl|B!=h7ee^tDQOwI+4#-RnPdPr zl6MtxmkoNtfIz_cW)sgg$r;|C&15H%!^`Y&R?lAf*^LQM6bEi(=|HaDx^j1K_9%qH zg~PY3Xf`B*uH#I1{nM=r0oWJ0lpJYVAHx2~y`J^{%X!4Y%$3lw;F>9K#yBt#=1ny< zV|Jm}vtbCmSA_7)fOf7<(9e($q}$i(4^H0jva#Loj1KV;Pq(!vR zh!>RlZa@o(pq(a(w2m{3xc#pbdW#pxM~eEav@c+mN&tQMZB@0cv_deoCm2jb)?5|{ z;BdU;vBa-Opl_kDF2QE4fjb}(I6~s0e$}l1kN&f#s|Nc`%#gS5q>YkCP`(BIjC@9( zN1Q|XL4JOv2~Q~?N-akZOJ|${VH!zLzSpxhqOl*N8|Rm6-9m!n7;ni-OWEa1Bxgtj zH+M#Ee=NH+a?^@PSw5pFDZmw5XWSb}%EbRoz!XYcN^VEbrv6RE*ysBt$V*Sx%NX1- z<2;JEa|e>J59KNu>ZO=ujv~gp8cT0WT(do-qz$d=z;AvQ4o1yzRr@``J)_#nHo_Wz z&2v_57F)mLD)n=;;AUJ+Z%R{@FVeu|=e&P8JdV*u%^{6Vf1pUQ-bU5I+qJ&cDi_Tm zNK#=6GZVX%9@DFA`$pv6u(0!Vaoq@C7q&(5d*PxY^khEK)OLDeDUIkTmP%yvr*ens z>Ds!zqfPpLD{tu)|5X!~b5pH~rt@b$;|)?B-)J62es}E*==@9_X!`2ccQfs^+588` zdJt!!20D&5#*i@kU>2K=cR|DI$AisBPcpo*(+9EW)HlbEbWb$i(YX2&YKZApYX`?< zigBWY>_I5z%vBQe3|f-9;P4OSHpw)QR{>B5z}4PWhb1)|A)>(#w?D~M)$cX?8=Z^y zoqZ`)JG)k1s4hB}qTT#pJxZ-%;|B1>MyF!);SY*Z>GgR=HR**K+cfv@@HeqjTw}?v z)3Z(_zYnJN_MgOi=lz%D_3oQ&Aca{?+1FO_yqY-aa)810czH=Ty&F+?mEP}>{`LEG zby`E(8T_-gwDekR<|E~djeWJB#}tu)+m+(I;-`x{FI`=#{gcZO(B0r#w=@pONs#>g za8q*QxRnLmCln;^L52*sj|H-MdP>~?I-gLdYiz(G=VUXHZvh8{%Z${?N}OBu1W_(R zYu*pq79gnFegi%14B37HvIcP_(w@BnvqNd$r%5gw)u6llLhUIiqm{=!5GIa_eQ&*- zcFSU-!MWmMoABL1dsK$c_-3y-%a`Nl(z{=bUhn^CrWV9OSRr<^EFS7ivV=;j?nSI)_Wed48JXyVKXRyF@AtOM!6%rJyQu^%2%LWDE; zsvnf_rA-lxoiM~i!cDAGXfMJMgC}Grq_@03b34vEUp1&T-|1$gi%0R4IOGk#{wde; z@akxGprgK9xxuOF{VrZYqrlC+gE{GX^)n&yBf+xlD1sddCuGGrZJBUD>f!@VQSKm- z(X52G8T7Q*DB_!t#+-db(Vqwe8L+7|AUG)WP+Tk8rVraP7Fy>59*CmO^kczxLQY8e!yixACDfy;KYXQd*X3wL)Q~;mQ={D zohAkr=8*Ihk7bLxePdtu4CUml*j<}?*vay}yg05%)5@`vp-x%esKx2A16xF~u2X{b zM7>^0%A%x6d8h08TW#m$N8DBK40)?>AL<`6=ND=eUDKz)Ffmce2CD#Rtkm;uoNhL^p#CZjvv>~56w1FS~X@eybD`!|;W3Kt}{q;hz@eujox zQhaIB@7&bVb9Dk^#AeVq+s-y1?&hGOY_p#Il3vCA!?PNDr0kxnAz;~IF&>? zzpE78aIXHkm67}Fj1t6`WZOMh2}VgmgsGug4UQZ`Mno@HrIqK~K_SWXPZFs**x=^D z2Hq<=A)nVg``&!F?aEDKu$B5)a>csFwYRk2t8IiN&%QZTXviSnpiFgjELY8|v&Z<5 zsT0OCYFAOz^G$rQLby=q8@>U1dh2Eu;7dO7qta9mOcs@Mb*z&QOvB>xUKMcrV(C(Zu8XT=pV)^T6$0S|lfqS~n4~H0g^of+%2cy^hzpo5k z?F_5)DP<8TZP`ywGHQ>{6LmAad~VkXirA{ZrhYUPbdLRC4*VFNm=~iwbTcHn8x+fP zd0iL(OMebo?LGIRX#8g)Xjljgf6J288sAVFA@JXXU`Gky_--q02NpKB;$ZzSlNW!R z7zB^L$PwZtv(qkp#=qPR+(WF*=fLjM#HpZ7MZ|0R!ashL)gq8F0ZXxq1Qan-E>%3f zL9VzZTad z-1!!89H3(g7pc63M2uDtdENXLxQAo;W4&UT5fDQ5E--2t13I?W^2DGunbp-_b9j8g z!k#RRL88!UeOF(JR6V;gZU z7cPWJM1Kf~-Y8b*eLR{zr6@Uj=S+q3_)rgxfMDe;uR{hc*#-&K3Ux~tz9hhA?~qtu zi_W+^|E&2SLOJ4TU3f63G#9hI)gFnG8UuB;}3q9+e_pE}P&_9kRao6U>xAWqyFgY|sDf*b3X4wd4>w<+;HKCE2t33s|KSYi!o_VlEO)tn1@K z=li;zxh5(vR4);c1?u2>?Vr4?h4CG@=^@e062Ixohu3m_~2wlK*)jsMN?h(*5l!<+}_yuDUXP0Em0;+6PhjPfPkCgN9#|v?yZ2gOZm;{%t zu?ekwxyWyS?j5+qX}i1@OSBh>+F8S~m7sUB&2;t0q2FLUpG zk#kw<_yi1L0S{u2% zAI0X^tfhUBxQ4Rsnm#TDn|es*bsHp>hIL0t!M$NT@sin|{UV9c+mjGrT zF{OV{-Lx&dbU!1I4vEe7ieeHaQX(`9`rjvJJZ@G-6`uu zC-+DbEg~|1yc2fYBAD4+EoY{6JDUdmB3W2^rl>0h595q3O%1WGtr#2Ao+f9b^r|{| z7KN4n{*0nsRkBF*YcvPu(cak+E5!31EpPJEj{{Gb0~LYHT>fv4P=+UgiL-Vj`hkVU6AOqnmK5>d-QQbe zrVK5_A|6cU04s(P8mCJRgx!H&2x0?VeHfuOhJ%b`D_FP(X^-Cr)agz-DdtOml4ESRJghB572=T`}&OgGJ(|-wH z%-oP+)E-~x?^%^D0!aMW;(W&K|3-n&}z6zd<2&A~39H*inR zA>~{~F1$LhJ(lM=piSEr9>~{CGRnjVsvc#Apj`Wa#F_a97L#9d5@|a_>D{*iQ}6nl zW|NK$_39FBpH1!EvPa=*fVO$JNk&``vs<~;qYlsX^tCmF-X-r9(d_p$XQs0TEq%QX zRMJvf3Q#)yn0X)jKk@pAt`pkH=%B-cd__j? zWFbGh8kA6?1GIYcVYm!w%XPdQLaE_pnw6o~7Fh|k5aMr#3h zzRJQih6lCtZc_kv=UGpzs`70kL;?-lS2$@wtx2u z8HwGgxE>E)sQ0&)a|MB7a{FNxp|#z@4Sikng!k&`LQ{gi73l2Ok+fWA%gb2e+pv1_ z`cV1KXVVtU&nr9wqy$)_j#E)CtS}Ng$>~vbJprux&_V-*U1lEA6AL5DL*nMT-|hHT zx)KQl9VYyYW+wWuvNxx0cL?QM6;gU`Jd_Md`UaS&W9+Gu2nH>$t^SCrWeSk`ZR*vd zE)^n?1h8)7nhkG-uw<)ZS;|NNgBVFe7YOvVoeo|W(7XnGqRglOFH>GG0xS^mdUR0F zMxA7ojD+LZgM4DSUI+*vfpWLcL!xx!UIevBg>QO_z%K(s;Vme5rpQ>t{XOWDOL2Iy zKCv`2OKw1+_hU#uGkixOdrk_Era?_sGv6TBitBWn52aErK@K6NT~0DLW;g)LXaaE0 zo^k=1b_iw1{A(3+ottA$1R&oQzjwEum%~N}Cs_>SJ^D5v(O?8BhQxj_%M!2S;jKGR zCQ7`pEaJdd(mT5rUn#Nq2OuEm7tAzTdJ7z3Xh4sufid8DebggUXxZ}mhfGk1CO(yS z`FRJrrkBnoI{AXK3p*uQo`nL<^WZsJb1=k+*sbF%5e`FUI`~AHe+J(AlD`9M@3Sx^ z6nW0}p?JWV-=#|m7;H^_4FeK2=$r`Gh2E2eV$;Ioz&dgPt0#4{E4kMy2LtR93={3l z4r}Tz17#dwxO4zSmJ3qg)9uCrxZ>U~L59N{=^n+peV)%spT)eopch5+AT`)@m_7R5 zyQ)>P{^Q{8MuJTWyhc(F*dR%9#pH#sXh6vCZy&GdO>utr)NlBr8yu8=)WooG%Ex1k zWw~z70tuT2lM?m$fWxxHL4ZP>zGcJAOMvK<$pFlhKfRp3EoBH~25!^aHI@mVy)K6aKeBMQ0kq;f`=>;!6u!b1N;kU0LU&eW~7A;@vj;ebb`J( zy?P{TuIg*A9a97eJC`Q}EQr+jRIuc|^%!sTYZN*ilzE8&*mo;@#v1$Wk3fXbdX+4&~|OLX~*(t&X=$e7A>}yJKS(q@BYbZSDR`e7Q9k!kpg;k8HD(B zzycxP17dR+(p*`&FHy1_*qB~f)MtjKBZpI9GVoo<8xjWvN-hlctTt@d8vC;myrSEH z0uFlsEzQ*unOsJ#ao1zP0fY3_fFEA6YZBo-S|A|0_F{=*X$e~C-Xxg-oPWj*G`lp6G+)AZa#wbN1`g- z)k#D$nCTS(UUsktcY+qJJ7qZ_)wkRxNZ_Dy<(2jmrf&<4;Ft@)Rf#thCwdIpG0KTs z(iz}pp@=^?lQ#t5I%x9SGngGU1_Zc|c<_W_KvI<#8j76+CIYA)SflSyY}(3kKpZCg z9gHx5Hfu=$o5OMc@y@w$O=u-R;z^?4!_P5jkpPHcJ;w2ei})xR9OO=QE5}O|49qZS zc~c917=Zb0A|+Ku$Ouy-B5P2Gs&PVQv{eckNFM^*-vGZKHzM^Ih2i(#a~jMHo6Ovz zmoL2n?7Eo*B#0#MKg5TE6PkCsx6$Y;*VhlQzp1({Wn?}OYZ@nZPI3&$Og^=@@y(*x?0WuVp!9UxqEV4Yk} z8U(;B{8JBl7f-xQdozlP)5lw?Awa$Yq8FB$y0rvY^Vj4s5IS%Rzk!8QCk_l6RdL$1 z3%$&?ZM{vZly>zpHLw>JefX>&6#?kyha2$z&&Okcw=y~F0?9yFBXSmE9|oGmgC4OE zw$LJP=e3Mhv8AKE2~lfeowE0Orfj5{^VqAZI6FKd#45 z23Bn;6(F*aIE#RG3+hi6pW~{amo&CCp?uP*J4l3?UeP0hSPm+rGjmL-Gx%*W0l!?~ zF)Nh{W=WBVGe9xf?8GR#W8gx24SywJm~+-p;8-r^CLhKz#-F)xQ)J-gqb(~+2dS36=SAON!bWLa;QbBFsbe86 z_P`E!Xr2+hNn|t0?CkHUWuy^W+E*3~aGy3C%?TTK;JT@FX#Mc^w5Fl!Xo122v;WD% zV`lq!uujkM4rw{TCBlcVY2WLdNJW!t$}c(W^z<*J-R}aK+LIP~QKeWIT8o^TgLZLuXdv_T8@tnEjYkzpYD{|`{QdcBVmGs8?l>zqW29C0#*G$q>t*!{q*_lj~Im*^ywg=L;#yMj=1an^kwe zuD%qA0e8*|=F6eaZi@JJj&v)(ZXemBzkh{jS?&p!f}Ue8*ieoeQfWBOku|oVi^O_t zYb|%h@>ox)J0lz<5d~m5NQfhrgQ$XBX6L9?N0w_`oL!Z^VmM3~ZFSVcc>B{}vS19_ zu=O@{ZF=T2R}kEMTF=I?UxlUC7$P>Q&QP1IpTPlc-v3qX;^%tQ&NN6ah-*?2kIiA}wF z!|7|e@c+>E)^SlkU*qU53k%{BDu^H*(&2)Fm zjetl>H%K>k7X3WW=X>vcUccYHuY3Iic`@%fGjrzjnVFMP>1LVxli@j4O=ug$=68P8 zSR16m4RW81J<0MrO&t5_uL~*q!vOVm1DQOydXFO8dKuh&316X9b{safHj!^8d;iiQ!F)co z@yliyUf7OW85{HGpu~rt-VBk5r&EcoaaCwq-DOGkiboGXBd{Zxe3Y?EU3AtEy-w~c z_r)Z~)xo_|MZIb0qwidnpJaz0xpF<#5lc+*)-y-5eAO-$TD>}5QZu6j;waHM;s&nG zv@mz3Ysh4FccfmAH}y+gLZf+3pOMapY>&^}M7Ld=wBXiOSM)s2Dzkkbt_fgCW7Er# z7^0=EZ`xOVmS9ie3?G)ieixpm{XAyJG`Ui>1@6mq*1CP|l`Oo(iE+VvDUp+c^ZS=+$;NlU2jf{4 zTc6nr5xdX=+(Wm zTq+iCAYI>mK>PrD7sYp>ae(oteUF@nw*-j_{e=J@(qjU`wLt8|DSl$}E^J5N1tt;( z3U!&)mB*LvOHEDP#d&>>Os=fr%tPwI!Pkl{pAefTK3EZVtlwj`J|O2|82i(3rPUWv zm@Ub160%XNdu-kZ(R_y*r=&IV5=ugpr%?A$!f>KJ} zZ&#CXy1#|;HgLi+j+tNrREfWcjbzdYD2j|jmNYi1E z-@e4G0v!9u;QcS$EHyp;jX-5)9H%fVv6YSi;3wK9?nBv|MZLfTL+gGQ)zGtB$pm$N!wQZg>l|+pXq&j@%jQ5F-?w)w8MEoWU+vFY_t2z2J`Czf$#e>v-(FIM#f z%Q*v7|BGrAKR>Fh{}y&_qxkTnWTCrVm!mvR-arQ$*!+M<5H5#IY*TrPlM8D`okupj3&bh`IEuRon3&q>cxUo%UE25G!e1o8{ z;I_E|xlVwg$P=Nz2XZnI(~ZWz60JNhZT5EAuq_^_frp42=(X`D9kWmx5e zfRw_qJsnMsocH#%YbEdLwM2Pu101R{!$JpOc_jWt+mkOn*bPvO2B258k{Zb^ulUlzch_Zip)mfY-Y5ohh-E zjnFHPg8Dvfk)rW(7+ARbdAx1CGX%6TLG3v!Y8>YNV0-W1~qQCdT<+KD%lCNSJ zK=4E`q8O_U^6CK)DZ5O=9OYJhlG};#)m7CT=JS+w53SJU8%i$xqI{wt_D$@H@fNTn zpopFtXndmAd@`qSsblFLCXR`fP~z~{yRkm4kU^~oM-o}r5Hl2_P1YXXFJ4_ z5k*C<;2AG0j>?@q1U^Yn6TzH~PT`d+w01O>zKjL-?(uTxr zETI7ez(z-0P}845@$UWKHGs$=^FX4a8FY$_Md6}f<9kG5(k6!p?;P7>2%7Y7r^aGL zVNjYsf<<f+TI`u<9MlexY3^m_>0C(Q11)h*@19m;rKYgsp>yO3*x2rO^G|19|5WVoMb=oA9 zU5;?Z%@~|M@b;MnRwAl;{3vdd`A!)pGa_yYQY;SjK$FKnN1QdF5Da(Y0@O>9 zC$AAI2*I3bI`66bCf#vULSK%$J_jj>gqY*v0CoP!Q4y#90cMM-+91+*4bd3`NjKGp z^NB})Umss>*@s&X>}(MzV?T=N{b3GW3;kMRfC|pSnj-rL|L+l5k8n&mAtzXWk?0%& zCH%PjAA5w!5Ex+C5;G?Z+qV6KCjiBd@_%ahAOQi921EqL8k;T8p@%@aZImDv5#4_! z%`x#^+Ajcw;9t>2yd4tA3E+a@_WwCyK@0n!q!f{qNvAl=8gb%t^_1;)TB_gGLQkU6 z#xDBomd7U+UV-6w58HmWqlDY^Dj2@^Hf-vkkJUiu# z;Eei`Byd}Vab`}gDmM>)(2&Ybu^dGCfy$8B4{~hVN(MqbXQnqkrg3tt2J{OLe^<=Q zvSmMj9U2ZX7OfHVQfB2vKFTY)HDz{Zs6LXN(n9#~I)0s=N59(p?PV@(ubAjZX(vO2 z^7*!ec$}=cAN4vCKKrwq$UYL4&+T!*`MR^p;!A6Qf^Uxe_=Mn@%uw#jL$5qy7~U*o z`@R)b`!MyAB)=hwET-JIotSp`HQjeY3FY)(wfLWf3SOF)2FqfLKHm!V8F3K|#jpbPC zt)W41M?AME18L8@Tt%^S`R9*iW}f&YbteniwA&B$jRFRllnO$`uXr!cWFj`p#@gLh z5=my^i(NIvzgJ&gktWCX#scu;5PD1@U8TQ*Kjha%e2Pk9M7|F+ceg_2)QU%cHs$y# zI9Km-7zK-aIj-P+ zMEK}oRO&5QgMVgg2EF?;;^+NQP!v%Itu?S97;p{I&1h72BH4YwwUa1v?AJhS&L#r} zRRSCs;qga*V`Kc8k-xlN`2W7)45W|t&9G3Ky3)?`icNp>aoP26N>{&~JpR;#D-`DK52{Q_k zpKnW-MbnI>Hv1fXGSdv-=y7?zG(g3MJhT6%L-fkc6JtQqf}tztxB?zgGMp5V>TA@Kq%BN9+R)&H$l3PI zN_kJbx{+bQSt9hp?;53f8n`UumX2qQqzJ=G`0Q;@F%_BsA3x8qTen8mC3yEe)M*$y+SW4W}>;Qr+csflG=r{AmZ= zoosFtpChU;)0L5g$7Ja)sEFz0oF2tx-{rNO9xlI@Z%Qd^pG0}*Qb0%{$qYSRxXBLl z@i#AHj!}IRjuo@I;*3%MaHE64+EAVTm`4_EQYk?xl_5*b{9XNo$S5~*V&}eZMYeAn znOUme5hj*FNDKy0&Nab|FYo^I5tj1$3Q$7txEgz$>-@ebs5W3*5gOX z^WO`J5;Ch_MdrqIMrW9XWB;7qvi@yhtDmbQZOaM6;&!djTDL84y4|3;^ZkH?DQ^qr zHFs)F1MH_dL-d!~Eq?X=cUv4Ckm!UpBK|HHThD@5<^k6E)L>shHM-u*k5V{Z%tCAH)vr!|+3 zmVGsE?>cU2)2#JTk#&UeiCZMB>c~Xbz1V}2ktspk8y);?J*JA1%O-S_Ok{1>ASvXo zL9v>}t6$;%2t06#{pUt&#s`*np##p96So|~?8~c*Ls}C`Z3->pv*RACer|ho7_V0x z=-E%`B)&7OpsZU_VGMnaq&S+ihsRNZY{N z_ctzuB540me7 zL)+0=on%j<1xN-3()zZ?jnb|Kdhk)klEjqDz{vINs(5ezA_h{VGYt{gcaFF$*Yp)P^b%?g6wE^Wn)st?Y9#|4Nx` zZNK0LBM*Pj>5AOX`8b=D=O~$uO+Iy$;dYrP2U%az8-yn(5~-k`+;k7}XC`O_aqpmv z?Kg=!H4E!NZF~(*)tI(Sw#ydRfKfEDULL?>Ck{6bMp%5DOU2&USDaP?HpQBwBpe0D zi@W>SPx{rD7thVosA9Ba4|ENbGt;w@rxjFYBBU3<2S0Y;GHhsF|EmkY!u&f~l-T3; zL)R`(+1&^{*gNt{ZC%r_eN|ww(2v&I5OaEY-nyD7H~xa{Hcl#27)+zs=@v9 z@*_8CRn_NVcv&&DFyV>cH`*ckDax^`X&wsGl#u_L)nX1wh4jPQ{K@yW{W7;{#8CiM5z`sNL5mV01&Bi8 zNmG7^>{B*cSoOGN8(09;<4uEuqE-z*ir=C>U#Y<_T_dfJlLPxzNsFYyJvvyL!~=gR z?UJ;?i>Vh@jyq&qQ^#`|1mH@*ovSQAy{q;}p}!!n9XO4apk~{d^#T&Y#8ruc$4&D* zwjyu;=4V3@GFX9VtJFoV{z=220 za0!Tp&sZjmEeJnGe-zZGvAlK@;)TK*RApsRS0 z@XPz_7y}z`tm3-!e=h+APkZOx!NJPzB1o`wk$Vo zWmx6vH_qRq!^oS8f(uk1huUKmg}(y4*te7OgQQX|noIz!MKg~;chsf}Jo=dC3H69a0s6uqH75~kC#yKSE zPa;3_qjK^);lv+?W#lf_TRr|i@~hT$+mB++W9X}f(@{m|{Vrj%jPF2rqJESrJRQ+{ zo$E;}gx!S2hV{S2LEcOD5fRp8J|%kwyc0T6Cd}42SIvMYEv`>%ufb74k8ljoWuqWr z3>>Y3$Z{^(+7EK3*gVXMf#~Q&>6gu9lKG*$UO^i7ER17v5=Sk;z=76PEw* z-}r=mtoLCr*4uvz?_z{?9DP8Ff9xMk07SqWxcU-tCU6*d3H+nUOnn=9Y780wN{HWd|7Yd%59dDkOV|Iwv5|fVnedA#+y+OP zpI%8CyOHz{zeZ5Yy)3*R!^jNu=c5cfNzYdZYpMTGo;D80^bgztuK<{Mf^`P5&KZBz zCIo_o2@b8o$m=n#v5*~acM%E8Fgb*nawu>wyh!FGCitma-ZCkJX*GyqZ+9&w>o90#+rv2Ys+`D!n zf(I}BSe{(ynHI?JNATn(DGJQZNPz5@O7Q#tZdAlHg6vA}KfCc#1Ag#^d=+zya3F$3 z=`JZ#i~~4u{_}J&p=q+i(b2C`q{cv+qzw|_loTmP3y#<_!I1IKNZ(5gv%R5@5pY7m ze~hg^4!n>XK!>Q$Wr_J8No8yOTl4;)+j7;iRpD$-$!ehsvy6Nyrc32=9j5pOn&B^Z zpG7#xuM&%?8(bRyM-AmmN3C2t)hdm@Qbxk~eMm-BRr9Aun77s+JEhX+5=4~mON*rO z-UBHV-1vjQ|D=wu2Yj*lZ*EtBWd~#$r!`&7BEPVbb^@ythrIqgMg>xb{~zOf#zk%K z#-GM4`!8WX$1Sq#U(cgyf6V=t5BG^*ssK;!J46#_Q;PUMI%dc!QjoH`!P1sHUO>LC zI)}H1g2NLN>&~GD=%QZMZ*2Xd|Dnn4RfESC<^O8u%7WV}J^yq7hhM%}n+U=+9!ds1 zg8mo(>fO<92iGRkBU7owrzjYW-vd^!_@7z*sA;(d+OqWURc2fTsZCNLNdR9ZmNGUc ze!|f~(#t!tAAmW5(dX!hZ|F)D=c<2Hvc21YCVXD<^3%Wcg0WU;J3)>ynDW(itv@DB zSs}4A(F!MD9f(P*xCK7X`lCJ9tejpofm8DgLEMOpKb*QqAX;MoIpXvei<9t$;h9Z9 z*tioLNlA?d?3Bvpfd7$gFJ!wu8rbIaq7}DASqVVwSNbZFR^%_Wd;gn{LqYn%Rp8y% ztBO${5O{)I@8}VSF;e?R;KbMYifbNbys)-D7O&^hEY(Vr-*9wvf& z{5Q%9(x(5bhWaI=?ncz3M=SX{76b$q4h|M~?pVBevo<%kwlZAyHm0ONqsVEgzveR8 zI(V;gBb5AD^f)y1x?fU>?UK?@@gHH1T-=#3|3=n`S8#jovXpH)Kxs!n z_a>?K@b0a|$L~3;>~U#+E-QD|RqQ+4pAgzy&c($g5Ik7?NVPvPYP0ewAirj>x0#G) zef-$E;90==zL$`^Sk3kWvE`FrL{)OaMJrX4Yexm=%c6Tf)(gC9j)J+hB;b=SaKG5PwhmyWuf1jEH@x7{X%-1{E}$cY~IhI@_K94%29 zB{&qSb0f8qlS-oQ_7RrcTzeeQ>uoQ9BO$JcCgH%5%S^u3x8xU1?ZzR63Tz2tR*LZp zOz;$xQVKNPm>{tT7H0CkD$$;DU$LLXJLa+M>O^x0>#rDhaXknw3XZz*SMlJI5FIc{7avEn^PX$C(D_sT=5IpTM!$-N&DtJwL82N)$gDF?Gf2KE{7pYH)o9g!BC{_ zeYiq%6mukt>6?{zKG=1^nKC2vmRcfTFK6;(M#-$e6Y`EOu+*D$+#;*Qla0nhxByv@pJR-Hpv76IzOu&ZF?%q$Yr@YHTVrCU5TiwcXOZT?6anEKh}{k{ty23#60iRd26_K?;6aM@}P;Ht`-nQ$YjKG~|h zbnWMGetPH?d+JgKS0vhLrtVkXDwHKgPl!~ z$Jx3ytcHxrqvLC|-15Dxwr(q$nxn;QWx6iiqs*taI${4OYG9B5J40mpl5M-%(l;a&}wj=9T| z=VG-TMfY06<6ki-IWk7 zB2E74b6Bqf>gN5`uS;`7kdrJd?1R*E}1Txv;c+VrrLz?rm;e2=36Yi|kN6=C6Pq1`OANRi%>=rJ@U>Q85Gta7wJVsaB zft;%5$h^tG7b5EFg&}RCL zw71)t!{kK<9mgFSwBzN4ivY9{A&<&YCpwU5zkoy@34QY9xaIYl3}a>O>Duc7xlxDn zQ|(*wgq7XhBv$iWF}J6qTXwSF@uVEq9uuA(w2lMe*7~Vz{dhKdC_%`BRV@N4>|YVG z&V@^rfC=NR3RCz;KwlSVYwL`kMKTcSxLNEE*Lfz(C$%sq<;4pP7YN=hiD0kbC)2EP zz4K2vZ;@fJ*ogmZhNc10cz)6&S$DPzapiVwxyDJ5z7YZgD)AgiX))nt>3&t|5#c`0`fwuYTebT$hoV5ui;w{%)5?G92y_MRlJ<_P*Arh>xl z{zg(FcW7bYow@U`xCy{gIKUM%z9CTfV!V<=B`t-CkPAs@(n+YIk=3T~bxC-;^VHwJ z-#`KrZfv~=!i^UmAGkp`(}JOL+@5=x>tXy@ZbkBOQ#!M8ZZT!oCU{$Z9`-(4o@bKe zihNye&~`N!^&#&!6$nXeeQ%+nk8H_PQj=~Dz`sJur1Tv)RZ|HwB~_S?ce+X%_|}P6 zDQ+&C8={7k;&DP*OY6qTlwRq1zJiFkO;J!7a_z^4XUSsewefwy;r<_iI z!wKC6ZMvbY>oi>p7_PlA#6D5_j=1@4dXpXZeR68T%v5`@)U108AJW!%L4Zv-$1acJ zXVrc$+uBv4PpZ}LKN|}-eWj>tuvwujPU>IPdu-A%nh0c*#)~vFrNbI(F?$ zyMu$&rfnR;`J^N{A+uVC@$fooONNE%+0u)FA@d-*ojuni#TZ7tUbPOzw|bGBS`rhi z+EZ3rdOq$nkXMkpm8=$@)g2lC`DyM@?LGG6doy%$Lk6^z3=VgZw1F`%3H4>E#x2Dp z2K-kyLHh8;dEMFI;rNE->3*Hgz4aLRcQ`{#E9{+8Tc6Y_Mz~L}ds)8@buwF}bxG$U z)^hxOYk;fYgJPxp8QM6lukp!n*IPXhhWTPQ-PC=4wgGDl$W+!f%pWIVi_@LbE|j<# z7vUKqRwDPrl3|4~#gN$yN&K3@>AJBjZ(y!F9=RUlF;Z{xN0H9t+1~upK>AUK3+G$g zXPT8rbj@~>$FqoY%VfVJPVx0^$e)N**8*&jCv%eYi)~~HhoeupVpY3g$tUeFeuC@} z`y}bxn)AVQX(smmsuO$HlU4Gv0v)K_@;3YF3U*cJ*&dSujlAbCem3BZ_!Z(awg62_ z7!+xmjPJqih04{jo6k|2yo)cX36N73Y9qxS&RW6QpQSv-Z~ZlXi6@=BSyj{z!4qXj z-dpSGvCm(p$@>zatDCN=dUf_{f3}~YGkLv`&7N{EB$%J72KJ5L6XM@+>y@0PAJ0%MfTn^-@gnj|j86ZhXi|1IW0kR=!+F2ebVpR;X8i`T zc~k+!W1BVkui4C3m+_Y_H=MNk56WNS75Rm^G*M0dzO}=1N#H?ULs5gXlaH)PhRquy zI#{TICY+LzFKajBedz9+fS>&u7B6MtZ5A$#xLBIkbjOfWgob9nsK~}`0yOcsqD?5f zW3|4z(qya~O|MGavs`BjqaYwo;1dk!`Qc6zv%qusLaKRfs<_8Bw;+%0ar?In<>xsX z?T{ySiC_9`6@B)P4{>l-`7P)oBOI;J?Y&>V>vtdWPVmOlOq(~26Ee60|TeO$GIS}M6u7OGvKU?V-p)d((5Q-7?1)4k_|I*B79V9{5 zGZ*Wp?`V2@T?KZD$Ln1JU-nhWeC*}dy8#Q5ph$>TBu6!`Z5}STwi%naQec+MP6#@-Yeh?AB=j*l=oudW^&1)@*W)Te4T}l2DQlov%OR;)!X<) z-Y7V^=4bzz_t*LPMzUu=Qai6c26L8!r72(fmKH~E46bb6e8NK|jz*vnGSJK3bf10` zld!9)^b+b?iv#x?EKA2fdjPVe633REffp}N-iu%gT&G6XqkpeAUF5I~#U20TB3g9d zC11V_4m%}!9_81al?scHPgyZ>=&{1ee?u@~(hPzh?T}VwY`e?gOx0$J3*mh>HI*ho zudV32#SJ(5_uPmg8%)4otmjb*6%G(6eZlkg^sLIzX^J&fsYf|YGj@azhG8C>{;N&9d zu(UZKA>>3|eSYTgfM&c?M9et6F-IVJ*X(YfZ%C*lg>S0okHS;Xv_0kfDJ;xnNS$yc z;=8}d*uNF&VejT_X43lM@9=#c=U+o!=R!X^c!3_00%5rkjEYPLPRYBi@5+0Fik9wI z+qkD^DF4X@j<-R6RZ$15WbYhnaT9ZxX0q+?7i=6V27>ZJPY&`n*T)HS8QLJ!>ZC7c1C1_{ zHIX~FU?h7_;=kL>gpC73Wb=bvJhe-j)(J5k1Pu)FmTvGqCszMyn3esQbz|-CnQ^rT zAf<~rPsi|toVM6)zm`>5aJ?cE1V++Z=2v)whvtCWS) z-c(SVRMYrjyYeZam1_9#BMp`NBDfW_kg1#Z_w3lK4J5j+)^hx-k56Nbo0Hef&9%BS zhtu8^)d~Ussjji~*YD}$au1OFXr$w5ZowBFyC*>1xExe(6N;X@yP0G+zL-wa5QlGq zobtm)lCMvh{yTfjpZJASo3Q$KOUgIy4NNp==Jlx4QhL?d+5S(b$xly<=uasGtS3ll zGQNqZ-K4(JDIzS!iqd?G4z26O{nRteX$o{Rin$kE9s-cyg==6 z9TUcG`4eWpj6?@$Jv^RtE12o=5*^Ew?@@f zUD%$&d>V%=`J2z|hFTq!G2W~VF0kv~bKh#W7}gm+_^y0MzXe$Q@5L9^{urho2|GMvF0ryJy-G7@HRyg; z!}4+6>)4{BB*wvm9av*r|1wWI;}F&&65q$FoqkWl3TlRIMlC>OL7a3WCF!hWx8X_S2QrjEow)1#0J|^w*Q# zP*-cXWgzPkK~D?kLbmp6=&BA1xH)dOMShYO?mKxuNqIEV^N;hGH$&u=%u(jlP1)he zT3p5z;C3A*+JTk{ZO?e<{s9~jF!ie9WwgX(?GfJ~bx2>7ot@jm_F9`6!s>$;tr+q) z${cb({ISmMS+t_9tG!*(<8jc;O?a@Ze!f{+uzT9VzwTjHx|;S$lj*f{WZA|vy&qC}iodnZ= z{FB@sGC<{~NMB`7k8b4gh?AoZU zTJR_PN$srXMc-#L_a?w?cNy@%TkVNqiUSCwjL+^D)K)I6S4H;-N1sgj&PFk{CkQFW zW(XEM8@;9PhQ~{0fYw+H{+?i5!SeO^^u))<@8?+$b7b

On@C0+6+6sk-(r^^M#& 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

DILlO>&ZA( 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�`%N6(5BFWXJV7Q>Bc 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�^F&#}_y%>Du3e*c>K-r0gP= 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 C;ui=2 diff --git a/components/softdevice/s110/doc/s110_nrf51_8.0.0_licence-agreement.pdf b/components/softdevice/s110/doc/s110_nrf51_8.0.0_licence-agreement.pdf deleted file mode 100644 index 7aab95c8e7ae8c764467d3d81fa9069d2ff9c2ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5553 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 series. */ - uint16_t evt_len; /**< Length in octets excluding this header. */ -} ble_evt_hdr_t; - -/**@brief Common BLE Event type, wrapping the module specific event reports. */ -typedef struct -{ - ble_evt_hdr_t header; /**< Event header. */ - union - { - ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ - ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ - ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ - ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ - ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ - } evt; -} ble_evt_t; - - -/** - * @brief Version Information. - */ -typedef struct -{ - uint8_t version_number; /**< Link Layer Version number for BT 4.1 spec is 7 (https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer). */ - uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ - uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ -} ble_version_t; - -/**@brief Mutual exclusion of radio activity and CPU execution. - * - * This option configures the application's access to the CPU when the radio is active. The - * application can configure itself to be blocked from using the CPU while the radio is - * active. By default, the application will be able to share CPU time with the SoftDevice - * during radio activity. This parameter structure is used together with @ref sd_ble_opt_set - * to configure the @ref BLE_COMMON_OPT_RADIO_CPU_MUTEX option. - * - * @note Note that the application should use this option to configure the SoftDevice to block the - * CPU during radio activity (i.e enable mutual exclusion) when running the SoftDevice on - * hardware affected by PAN #44 "CCM may exceed real time requirements"and PAN #45 "AAR may - * exceed real time requirements". - * - * @note Note that when acting as a scanner, the mutex is only enabled for radio TX activity. - * - * @note @ref sd_ble_opt_get is not supported for this option. - * - */ -typedef struct -{ - uint8_t enable : 1; /**< Enable mutual exclusion of radio activity and the CPU execution. */ -} ble_common_opt_radio_cpu_mutex_t; - -/**@brief Option structure for common options. */ -typedef union -{ - ble_common_opt_radio_cpu_mutex_t radio_cpu_mutex; /**< Parameters for the option for the mutual exclusion of radio activity and CPU execution. */ -} ble_common_opt_t; - -/**@brief Common BLE Option type, wrapping the module specific options. */ -typedef union -{ - ble_common_opt_t common_opt; /**< Common option, opt_id in BLE_COMMON_OPT_* series. */ - ble_gap_opt_t gap_opt; /**< GAP option, opt_id in BLE_GAP_OPT_* series. */ -} ble_opt_t; - -/** - * @brief BLE GATTS init options - */ -typedef struct -{ - ble_gatts_enable_params_t gatts_enable_params; /**< GATTS init options @ref ble_gatts_enable_params_t. */ -} ble_enable_params_t; - -/** @} */ - -/** @addtogroup BLE_COMMON_FUNCTIONS Functions - * @{ */ - -/**@brief Enable the BLE stack - * - * @param[in] p_ble_enable_params Pointer to ble_enable_params_t - * - * @details This call initializes the BLE stack, no other BLE related function can be called before this one. - * - * @return @ref NRF_SUCCESS BLE the BLE stack has been initialized successfully - * @retval @ref NRF_ERROR_INVALID_STATE the BLE stack had already been initialized and cannot be reinitialized. - * @return @ref NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. - * @return @ref NRF_ERROR_INVALID_LENGTH The specified Attribute Table size is either too small or not a multiple of 4. - * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. - * @return @ref NRF_ERROR_NO_MEM The Attribute Table size is too large. Decrease size in @ref ble_gatts_enable_params_t. - */ -SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(ble_enable_params_t * p_ble_enable_params)); - -/**@brief Get an event from the pending events queue. - * - * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. This buffer must be 4-byte aligned in memory. - * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. - * - * @details This call allows the application to pull a BLE event from the BLE stack. The application is signalled that an event is - * available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. - * The application is free to choose whether to call this function from thread mode (main context) or directly from the Interrupt Service Routine - * that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher priority than the application, this function should be called - * in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. - * Failure to do so could potentially leave events in the internal queue without the application being aware of this fact. - * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to be copied into - * application memory. If the buffer provided is not large enough to fit the entire contents of the event, @ref NRF_ERROR_DATA_SIZE will be returned - * and the application can then call again with a larger buffer size. - * Please note that because of the variable length nature of some events, sizeof(ble_evt_t) will not always be large enough to fit certain events, - * and so it is the application's responsibility to provide an amount of memory large enough so that the relevant event is copied in full. - * The application may "peek" the event length by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return. - * - * @note The pointer supplied must be aligned to the extend defined by @ref BLE_EVTS_PTR_ALIGNMENT - * - * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. - * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. - * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. - */ -SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); - - -/**@brief Get the total number of available application transmission buffers per link in the BLE stack. - * - * @details This call allows the application to obtain the total number of - * transmission buffers available per link for application data. Please note that - * this does not give the number of free buffers, but rather the total amount of them. - * The application has two options to handle its own application transmission buffers: - * - Use a simple arithmetic calculation: at boot time the application should use this function - * to find out the total amount of buffers available to it and store it in a variable. - * Every time a packet that consumes an application buffer is sent using any of the - * exposed functions in this BLE API, the application should decrement that variable. - * Conversely, whenever a @ref BLE_EVT_TX_COMPLETE event is received by the application - * it should retrieve the count field in such event and add that number to the same - * variable storing the number of available packets. - * This mechanism allows the application to be aware at any time of the number of - * application packets available in the BLE stack's internal buffers, and therefore - * it can know with certainty whether it is possible to send more data or it has to - * wait for a @ref BLE_EVT_TX_COMPLETE event before it proceeds. - * - Choose to simply not keep track of available buffers at all, and instead handle the - * @ref BLE_ERROR_NO_TX_BUFFERS error by queueing the packet to be transmitted and - * try again as soon as a @ref BLE_EVT_TX_COMPLETE event arrives. - * - * The API functions that may consume an application buffer depending on - * the parameters supplied to them can be found below: - * - * - @ref sd_ble_gattc_write (write without response only) - * - @ref sd_ble_gatts_hvx (notifications only) - * - @ref sd_ble_l2cap_tx (all packets) - * - * @param[out] p_count Pointer to a uint8_t which will contain the number of application transmission buffers upon - * successful return. - * - * @retval ::NRF_SUCCESS Number of application transmission buffers retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_TX_BUFFER_COUNT_GET, uint32_t, sd_ble_tx_buffer_count_get(uint8_t *p_count)); - - -/**@brief Add a Vendor Specific UUID. - * - * @details This call enables the application to add a vendor specific UUID to the BLE stack's table, - * for later use all other modules and APIs. This then allows the application to use the shorter, - * 24-bit @ref ble_uuid_t format when dealing with both 16-bit and 128-bit UUIDs without having to - * check for lengths and having split code paths. The way that this is accomplished is by extending the - * grouping mechanism that the Bluetooth SIG standard base UUID uses for all other 128-bit UUIDs. The - * type field in the @ref ble_uuid_t structure is an index (relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN) - * to the table populated by multiple calls to this function, and the uuid field in the same structure - * contains the 2 bytes at indices 12 and 13. The number of possible 128-bit UUIDs available to the - * application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, - * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. - * - * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by - * the 16-bit uuid field in @ref ble_uuid_t. - * - * - * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding - * bytes 12 and 13. - * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored. - * - * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID. - * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. - * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. - * @retval ::NRF_ERROR_FORBIDDEN If p_vs_uuid has already been added to the VS UUID table. - */ -SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); - - -/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. - * - * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared - * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add - * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index - * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. - * - * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. - * - * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). - * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. - * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. - * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. - */ -SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); - - -/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). - * - * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. - * - * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. - * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). - * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. - * - * @retval ::NRF_SUCCESS Successfully encoded into the buffer. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. - */ -SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); - - -/**@brief Get Version Information. - * - * @details This call allows the application to get the BLE stack version information. - * - * @param[out] p_version Pointer to a ble_version_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Version information stored successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure). - */ -SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); - - -/**@brief Provide a user memory block. - * - * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. - * - * @param[in] conn_handle Connection handle. - * @param[in,out] p_block Pointer to a user memory block structure. - * - * @retval ::NRF_SUCCESS Successfully queued a response to the peer. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no execute write request pending. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. - */ -SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); - -/**@brief Set a BLE option. - * - * @details This call allows the application to set the value of an option. - * - * @param[in] opt_id Option ID. - * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. - * - * @retval ::NRF_SUCCESS Option set successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. - */ -SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); - - -/**@brief Get a BLE option. - * - * @details This call allows the application to retrieve the value of an option. - * - * @param[in] opt_id Option ID. - * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Option retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. - * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. - * - */ -SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); - -/** @} */ - -#endif /* BLE_H__ */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s110/headers/ble_err.h b/components/softdevice/s110/headers/ble_err.h deleted file mode 100644 index 1184f24..0000000 --- a/components/softdevice/s110/headers/ble_err.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_COMMON - @{ - @addtogroup nrf_error - @{ - @ingroup BLE_COMMON - @} - - @defgroup ble_err General error codes - @{ - - @brief General error code definitions for the BLE API. - - @ingroup BLE_COMMON -*/ -#ifndef NRF_BLE_ERR_H__ -#define NRF_BLE_ERR_H__ - -#include "nrf_error.h" - -/* @defgroup BLE_ERRORS Error Codes - * @{ */ -#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ -#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ -#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ -#define BLE_ERROR_NO_TX_BUFFERS (NRF_ERROR_STK_BASE_NUM+0x004) /**< Buffer capacity exceeded. */ -#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */ -/** @} */ - - -/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges - * @brief Assignment of subranges for module specific error codes. - * @note For specific error codes, see ble_.h or ble_error_.h. - * @{ */ -#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */ -#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */ -#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */ -#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ -/** @} */ - -#endif - - -/** - @} - @} -*/ diff --git a/components/softdevice/s110/headers/ble_gap.h b/components/softdevice/s110/headers/ble_gap.h deleted file mode 100644 index eebdf9e..0000000 --- a/components/softdevice/s110/headers/ble_gap.h +++ /dev/null @@ -1,1349 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_GAP Generic Access Profile (GAP) - @{ - @brief Definitions and prototypes for the GAP interface. - */ - -#ifndef BLE_GAP_H__ -#define BLE_GAP_H__ - -#include "ble_types.h" -#include "ble_ranges.h" -#include "nrf_svc.h" - -/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations - * @{ */ - -/**@brief GAP API SVC numbers. - */ -enum BLE_GAP_SVCS -{ - SD_BLE_GAP_ADDRESS_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ - SD_BLE_GAP_ADDRESS_GET, /**< Get own Bluetooth Address. */ - SD_BLE_GAP_ADV_DATA_SET, /**< Set Advertising Data. */ - SD_BLE_GAP_ADV_START, /**< Start Advertising. */ - SD_BLE_GAP_ADV_STOP, /**< Stop Advertising. */ - SD_BLE_GAP_CONN_PARAM_UPDATE, /**< Connection Parameter Update. */ - SD_BLE_GAP_DISCONNECT, /**< Disconnect. */ - SD_BLE_GAP_TX_POWER_SET, /**< Set TX Power. */ - SD_BLE_GAP_APPEARANCE_SET, /**< Set Appearance. */ - SD_BLE_GAP_APPEARANCE_GET, /**< Get Appearance. */ - SD_BLE_GAP_PPCP_SET, /**< Set PPCP. */ - SD_BLE_GAP_PPCP_GET, /**< Get PPCP. */ - SD_BLE_GAP_DEVICE_NAME_SET, /**< Set Device Name. */ - SD_BLE_GAP_DEVICE_NAME_GET, /**< Get Device Name. */ - SD_BLE_GAP_AUTHENTICATE, /**< Initiate Pairing/Bonding. */ - SD_BLE_GAP_SEC_PARAMS_REPLY, /**< Reply with Security Parameters. */ - SD_BLE_GAP_AUTH_KEY_REPLY, /**< Reply with an authentication key. */ - SD_BLE_GAP_ENCRYPT, /**< Initiate encryption procedure. */ - SD_BLE_GAP_SEC_INFO_REPLY, /**< Reply with Security Information. */ - SD_BLE_GAP_CONN_SEC_GET, /**< Obtain connection security level. */ - SD_BLE_GAP_RSSI_START, /**< Start reporting of changes in RSSI. */ - SD_BLE_GAP_RSSI_STOP, /**< Stop reporting of changes in RSSI. */ - SD_BLE_GAP_SCAN_START, /**< Start Scanning. */ - SD_BLE_GAP_SCAN_STOP, /**< Stop Scanning. */ - SD_BLE_GAP_CONNECT, /**< Connect. */ - SD_BLE_GAP_CONNECT_CANCEL, /**< Cancel ongoing connection procedure. */ - SD_BLE_GAP_RSSI_GET, /**< Get the last RSSI sample. */ -}; - -/**@brief GAP Event IDs. - * IDs that uniquely identify an event coming from the stack to the application. - */ -enum BLE_GAP_EVTS -{ - BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connection established. @ref ble_gap_evt_connected_t */ - BLE_GAP_EVT_DISCONNECTED, /**< Disconnected from peer. @ref ble_gap_evt_disconnected_t */ - BLE_GAP_EVT_CONN_PARAM_UPDATE, /**< Connection Parameters updated. ble_gap_evt_conn_param_update_t */ - BLE_GAP_EVT_SEC_PARAMS_REQUEST, /**< Request to provide security parameters. @ref ble_gap_evt_sec_params_request_t */ - BLE_GAP_EVT_SEC_INFO_REQUEST, /**< Request to provide security information. @ref ble_gap_evt_sec_info_request_t */ - BLE_GAP_EVT_PASSKEY_DISPLAY, /**< Request to display a passkey to the user. @ref ble_gap_evt_passkey_display_t */ - BLE_GAP_EVT_AUTH_KEY_REQUEST, /**< Request to provide an authentication key. @ref ble_gap_evt_auth_key_request_t */ - BLE_GAP_EVT_AUTH_STATUS, /**< Authentication procedure completed with status. @ref ble_gap_evt_auth_status_t */ - BLE_GAP_EVT_CONN_SEC_UPDATE, /**< Connection security updated. @ref ble_gap_evt_conn_sec_update_t */ - BLE_GAP_EVT_TIMEOUT, /**< Timeout expired. @ref ble_gap_evt_timeout_t */ - BLE_GAP_EVT_RSSI_CHANGED, /**< RSSI report. @ref ble_gap_evt_rssi_changed_t */ - BLE_GAP_EVT_ADV_REPORT, /**< Advertising report. @ref ble_gap_evt_adv_report_t */ - BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. @ref ble_gap_evt_sec_request_t */ - BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. @ref ble_gap_evt_conn_param_update_request_t */ - BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_evt_scan_req_report_t */ -}; - -/**@brief GAP Option IDs. - * IDs that uniquely identify a GAP option. - */ -enum BLE_GAP_OPTS -{ - BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ - BLE_GAP_OPT_LOCAL_CONN_LATENCY, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ - BLE_GAP_OPT_PASSKEY, /**< Set passkey. @ref ble_gap_opt_passkey_t */ - BLE_GAP_OPT_PRIVACY, /**< Custom privacy. @ref ble_gap_opt_privacy_t */ - BLE_GAP_OPT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_opt_scan_req_report_t */ - BLE_GAP_OPT_COMPAT_MODE /**< Compatibility mode. @ref ble_gap_opt_compat_mode_t */ -}; -/** @} */ - -/**@addtogroup BLE_GAP_DEFINES Defines - * @{ */ - -/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP - * @{ */ -#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ -#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ -#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ -/**@} */ - - -/**@defgroup BLE_GAP_ROLES GAP Roles - * @note Not explicitly used in peripheral API, but will be relevant for central API. - * @{ */ -#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */ -#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */ -#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */ -/**@} */ - - -/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources - * @{ */ -#define BLE_GAP_TIMEOUT_SRC_ADVERTISING 0x00 /**< Advertising timeout. */ -#define BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST 0x01 /**< Security request timeout. */ -#define BLE_GAP_TIMEOUT_SRC_SCAN 0x02 /**< Scanning timeout. */ -#define BLE_GAP_TIMEOUT_SRC_CONN 0x03 /**< Connection timeout. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types - * @{ */ -#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random Static address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Private Resolvable address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Private Non-Resolvable address. */ -/**@} */ - -/**@defgroup BLE_GAP_ADDR_CYCLE_MODES GAP Address cycle modes - * @{ */ -#define BLE_GAP_ADDR_CYCLE_MODE_NONE 0x00 /**< Set addresses directly, no automatic address cycling. */ -#define BLE_GAP_ADDR_CYCLE_MODE_AUTO 0x01 /**< Automatically generate and update private addresses. */ -/** @} */ - -/**@brief The default interval in seconds at which a private address is refreshed when address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO. */ -#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (60 * 15) - -/** @brief BLE address length. */ -#define BLE_GAP_ADDR_LEN 6 - - -/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format - * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm - * @{ */ -#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */ -#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */ -#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */ -#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */ -#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */ -#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */ -#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */ -#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */ -#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */ -#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */ -#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */ -#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */ -#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */ -#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */ -#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ -#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */ -#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ -#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ -#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ -#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ -#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags - * @{ */ -#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */ -#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */ -#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */ -#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */ -#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */ -#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */ -#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min - * @{ */ -#define BLE_GAP_ADV_INTERVAL_MIN 0x0020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */ -#define BLE_GAP_ADV_NONCON_INTERVAL_MIN 0x00A0 /**< Minimum Advertising interval in 625 us units for non connectable mode, i.e. 100 ms. */ -#define BLE_GAP_ADV_INTERVAL_MAX 0x4000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */ - /**@} */ - - -/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min - * @{ */ -#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ -#define BLE_GAP_SCAN_INTERVAL_MAX 0x4000 /**< Maximum Scan interval in 625 us units, i.e. 10.24 s. */ - /** @} */ - - -/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min - * @{ */ -#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ -#define BLE_GAP_SCAN_WINDOW_MAX 0x4000 /**< Maximum Scan window in 625 us units, i.e. 10.24 s. */ - /** @} */ - - -/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min - * @{ */ -#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in seconds. */ -#define BLE_GAP_SCAN_TIMEOUT_MAX 0xFFFF /**< Maximum Scan timeout in seconds. */ - /** @} */ - - -/**@brief Maximum size of advertising data in octets. */ -#define BLE_GAP_ADV_MAX_SIZE 31 - - -/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types - * @{ */ -#define BLE_GAP_ADV_TYPE_ADV_IND 0x00 /**< Connectable undirected. */ -#define BLE_GAP_ADV_TYPE_ADV_DIRECT_IND 0x01 /**< Connectable directed. */ -#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND 0x02 /**< Scannable undirected. */ -#define BLE_GAP_ADV_TYPE_ADV_NONCONN_IND 0x03 /**< Non connectable undirected. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies - * @{ */ -#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */ -#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */ -#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */ -#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values - * @{ */ -#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX 180 /**< Maximum advertising time in limited discoverable mode (TGAP(lim_adv_timeout) = 180s). */ -#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED 0 /**< Unlimited advertising in general discoverable mode. */ -/**@} */ - - -/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes - * @{ */ -#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */ -#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */ -#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */ -/**@} */ - -/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities - * @{ */ -#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */ -#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */ -#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */ -#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */ -#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */ -/**@} */ - - -/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types - * @{ */ -#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */ -#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */ -#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ -/**@} */ - -/**@defgroup BLE_GAP_SEC_STATUS GAP Security status - * @{ */ -#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ -#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */ -#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */ -#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user cancelled or other). */ -#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */ -#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */ -#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */ -#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */ -#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */ -#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */ -#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ -#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ -#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ -/**@} */ - -/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources - * @{ */ -#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */ -#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */ -/**@} */ - -/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits - * @{ */ -#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connction interval specified in connect parameters. */ -#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest mimimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ -#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connction interval specified in connect parameters. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ -#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ -#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */ -#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */ -#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */ -/**@} */ - - -/**@brief GAP device name maximum length. */ -#define BLE_GAP_DEVNAME_MAX_LEN 31 - -/**@brief Disable RSSI events for connections */ -#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF - -/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters - * - * See @ref ble_gap_conn_sec_mode_t. - * @{ */ -/**@brief Set sec_mode pointed to by ptr to have no access rights.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) -/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) -/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) -/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) -/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) -/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) -/**@} */ - - -/**@brief GAP Security Random Number Length. */ -#define BLE_GAP_SEC_RAND_LEN 8 - -/**@brief GAP Security Key Length. */ -#define BLE_GAP_SEC_KEY_LEN 16 - -/**@brief GAP Passkey Length. */ -#define BLE_GAP_PASSKEY_LEN 6 - -/**@brief Maximum amount of addresses in a whitelist. */ -#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8) - -/**@brief Maximum amount of IRKs in a whitelist. - * @note The number of IRKs is limited to 8, even if the hardware supports more. - */ -#define BLE_GAP_WHITELIST_IRK_MAX_COUNT (8) - -/**@defgroup GAP_SEC_MODES GAP Security Modes - * @{ */ -#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ -/**@} */ - -/**@} */ - -/**@addtogroup BLE_GAP_STRUCTURES Structures - * @{ */ - -/**@brief Bluetooth Low Energy address. */ -typedef struct -{ - uint8_t addr_type; /**< See @ref BLE_GAP_ADDR_TYPES. */ - uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */ -} ble_gap_addr_t; - - -/**@brief GAP connection parameters. - * - * @note When ble_conn_params_t is received in an event, both min_conn_interval and - * max_conn_interval will be equal to the connection interval set by the central. - * - * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies: - * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval - * that corresponds to the following Bluetooth Spec requirement: - * The Supervision_Timeout in milliseconds shall be larger than - * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. - */ -typedef struct -{ - uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ -} ble_gap_conn_params_t; - - -/**@brief GAP connection security modes. - * - * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n - * Security Mode 1 Level 1: No security is needed (aka open link).\n - * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n - * Security Mode 1 Level 3: MITM protected encrypted link required.\n - * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n - * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n - */ -typedef struct -{ - uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ - uint8_t lv : 4; /**< Level (1, 2 or 3), 0 for no permissions at all. */ - -} ble_gap_conn_sec_mode_t; - - -/**@brief GAP connection security status.*/ -typedef struct -{ - ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/ - uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */ -} ble_gap_conn_sec_t; - - -/**@brief Identity Resolving Key. */ -typedef struct -{ - uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ -} ble_gap_irk_t; - - -/**@brief Whitelist structure. */ -typedef struct -{ - ble_gap_addr_t **pp_addrs; /**< Pointer to an array of device address pointers, pointing to addresses to be used in whitelist. NULL if none are given. */ - uint8_t addr_count; /**< Count of device addresses in array, up to @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. */ - ble_gap_irk_t **pp_irks; /**< Pointer to an array of Identity Resolving Key (IRK) pointers, each pointing to an IRK in the whitelist. NULL if none are given. */ - uint8_t irk_count; /**< Count of IRKs in array, up to @ref BLE_GAP_WHITELIST_IRK_MAX_COUNT. */ -} ble_gap_whitelist_t; - -/**@brief Channel mask for RF channels used in advertising and scanning. */ -typedef struct -{ - uint8_t ch_37_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 37 */ - uint8_t ch_38_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 38 */ - uint8_t ch_39_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 39 */ -} ble_gap_adv_ch_mask_t; - -/**@brief GAP advertising parameters.*/ -typedef struct -{ - uint8_t type; /**< See @ref BLE_GAP_ADV_TYPES. */ - ble_gap_addr_t *p_peer_addr; /**< For @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND mode only, known peer address. */ - uint8_t fp; /**< Filter Policy, see @ref BLE_GAP_ADV_FILTER_POLICIES. */ - ble_gap_whitelist_t *p_whitelist; /**< Pointer to whitelist, NULL if none is given. */ - uint16_t interval; /**< Advertising interval between 0x0020 and 0x4000 in 0.625 ms units (20ms to 10.24s), see @ref BLE_GAP_ADV_INTERVALS. - - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for high duty cycle directed advertising. - - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, set @ref BLE_GAP_ADV_INTERVAL_MIN <= interval <= @ref BLE_GAP_ADV_INTERVAL_MAX for low duty cycle advertising.*/ - uint16_t timeout; /**< Advertising timeout between 0x0001 and 0x3FFF in seconds, 0x0000 disables timeout. See also @ref BLE_GAP_ADV_TIMEOUT_VALUES. If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for High duty cycle directed advertising. */ - ble_gap_adv_ch_mask_t channel_mask; /**< Advertising channel mask. @see ble_gap_channel_mask_t for documentation. */ -} ble_gap_adv_params_t; - - -/**@brief GAP scanning parameters. */ -typedef struct -{ - uint8_t active : 1; /**< If 1, perform active scanning (scan requests). */ - uint8_t selective : 1; /**< If 1, ignore unknown devices (non whitelisted). */ - ble_gap_whitelist_t * p_whitelist; /**< Pointer to whitelist, NULL if none is given. */ - uint16_t interval; /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ - uint16_t window; /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ - uint16_t timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ -} ble_gap_scan_params_t; - - -/** @brief Keys that can be exchanged during a bonding procedure. */ -typedef struct -{ - uint8_t enc : 1; /**< Long Term Key and Master Identification. */ - uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ - uint8_t sign : 1; /**< Connection Signature Resolving Key. */ -} ble_gap_sec_kdist_t; - - -/**@brief GAP security parameters. */ -typedef struct -{ - uint8_t bond : 1; /**< Perform bonding. */ - uint8_t mitm : 1; /**< Man In The Middle protection required. */ - uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ - uint8_t oob : 1; /**< Out Of Band data available. */ - uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ - uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ - ble_gap_sec_kdist_t kdist_periph; /**< Key distribution bitmap: keys that the peripheral device will distribute. */ - ble_gap_sec_kdist_t kdist_central; /**< Key distribution bitmap: keys that the central device will distribute. */ -} ble_gap_sec_params_t; - - -/**@brief GAP Encryption Information. */ -typedef struct -{ - uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ - uint8_t auth : 1; /**< Authenticated Key. */ - uint8_t ltk_len : 7; /**< LTK length in octets. */ -} ble_gap_enc_info_t; - - -/**@brief GAP Master Identification. */ -typedef struct -{ - uint16_t ediv; /**< Encrypted Diversifier. */ - uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */ -} ble_gap_master_id_t; - - -/**@brief GAP Signing Information. */ -typedef struct -{ - uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */ -} ble_gap_sign_info_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ - ble_gap_addr_t own_addr; /**< Bluetooth address of the local device used during connection setup. */ - uint8_t irk_match :1; /**< If 1, peer device's address resolved using an IRK. */ - uint8_t irk_match_idx :7; /**< Index in IRK list where the address was matched. */ - ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ -} ble_gap_evt_connected_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */ -typedef struct -{ - uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */ -} ble_gap_evt_disconnected_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */ -typedef struct -{ - ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ -} ble_gap_evt_conn_param_update_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */ -typedef struct -{ - ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */ -} ble_gap_evt_sec_params_request_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ - ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */ - uint8_t enc_info : 1; /**< If 1, Encryption Information required. */ - uint8_t id_info : 1; /**< If 1, Identity Information required. */ - uint8_t sign_info : 1; /**< If 1, Signing Information required. */ -} ble_gap_evt_sec_info_request_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */ -typedef struct -{ - uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ -} ble_gap_evt_passkey_display_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */ -typedef struct -{ - uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ -} ble_gap_evt_auth_key_request_t; - - -/**@brief Security levels supported. - * @note See Bluetooth Specification Version 4.1 Volume 3, Part C, Chapter 10. -*/ -typedef struct -{ - uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ - uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ - uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ -} ble_gap_sec_levels_t; - - -/**@brief Encryption Key. */ -typedef struct -{ - ble_gap_enc_info_t enc_info; /**< Encryption Information. */ - ble_gap_master_id_t master_id; /**< Master Identification. */ -} ble_gap_enc_key_t; - - -/**@brief Identity Key. */ -typedef struct -{ - ble_gap_irk_t id_info; /**< Identity Information. */ - ble_gap_addr_t id_addr_info; /**< Identity Address Information. */ -} ble_gap_id_key_t; - - -/**@brief Security Keys. */ -typedef struct -{ - ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ - ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ - ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ -} ble_gap_sec_keys_t; - - -/**@brief Security key set (both Peripheral and Central keys). - * Note that when distributing Bluetooth addresses pertaining to the local device those - * will have to be filled in by the user. */ -typedef struct -{ - ble_gap_sec_keys_t keys_periph; /**< Keys distributed by the device in the Peripheral role. */ - ble_gap_sec_keys_t keys_central; /**< Keys distributed by the device in the Central role. */ -} ble_gap_sec_keyset_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */ -typedef struct -{ - uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */ - uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ - uint8_t bonded : 1; /**< Procedure resulted in a bond. */ - ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ - ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ - ble_gap_sec_kdist_t kdist_periph; /**< Bitmap stating which keys were exchanged (distributed) by the peripheral. */ - ble_gap_sec_kdist_t kdist_central; /**< Bitmap stating which keys were exchanged (distributed) by the central. */ -} ble_gap_evt_auth_status_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */ -typedef struct -{ - ble_gap_conn_sec_t conn_sec; /**< Connection security level. */ -} ble_gap_evt_conn_sec_update_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */ -typedef struct -{ - uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */ -} ble_gap_evt_timeout_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */ -typedef struct -{ - int8_t rssi; /**< Received Signal Strength Indication in dBm. */ -} ble_gap_evt_rssi_changed_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ - int8_t rssi; /**< Received Signal Strength Indication in dBm. */ - uint8_t scan_rsp : 1; /**< If 1, the report corresponds to a scan response and the type field may be ignored. */ - uint8_t type : 2; /**< See @ref BLE_GAP_ADV_TYPES. Only valid if the scan_rsp field is 0. */ - uint8_t dlen : 5; /**< Advertising or scan response data length. */ - uint8_t data[BLE_GAP_ADV_MAX_SIZE]; /**< Advertising or scan response data. */ -} ble_gap_evt_adv_report_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */ -typedef struct -{ - uint8_t bond : 1; /**< Perform bonding. */ - uint8_t mitm : 1; /**< Man In The Middle protection required. */ -} ble_gap_evt_sec_request_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */ -typedef struct -{ - ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ -} ble_gap_evt_conn_param_update_request_t; - - -/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */ -typedef struct -{ - int8_t rssi; /**< Received Signal Strength Indication in dBm. */ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ -} ble_gap_evt_scan_req_report_t; - - - -/**@brief GAP event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which event occured. */ - union /**< union alternative identified by evt_id in enclosing struct. */ - { - ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ - ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */ - ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */ - ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ - ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ - ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ - ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ - ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ - ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ - ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ - ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event parameters. */ - ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */ - ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */ - ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ - ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report parameters. */ - } params; /**< Event Parameters. */ - -} ble_gap_evt_t; - - -/**@brief Channel Map option. - * Used with @ref sd_ble_opt_get to get the current channel map - * or @ref sd_ble_opt_set to set a new channel map. When setting the - * channel map, it applies to all current and future connections. When getting the - * current channel map, it applies to a single connection and the connection handle - * must be supplied. - * - * @note Setting the channel map may take some time, depending on connection parameters. - * The time taken may be different for each connection and the get operation will - * return the previous channel map until the new one has taken effect. - * - * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed. - * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46. - * - * @retval ::NRF_SUCCESS Get or set successful. - * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get. - * @retval ::NRF_ERROR_NOT_SUPPORTED Returned by sd_ble_opt_set in peripheral-only SoftDevices. - * - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle (only applicable for get) */ - uint8_t ch_map[5]; /**< Channel Map (37-bit). */ -} ble_gap_opt_ch_map_t; - - -/**@brief Local connection latency option. - * - * Local connection latency is a feature which enables the slave to improve - * current consumption by ignoring the slave latency set by the peer. The - * local connection latency can only be set to a multiple of the slave latency, - * and cannot be longer than half of the supervision timeout. - * - * Used with @ref sd_ble_opt_set to set the local connection latency. The - * @ref sd_ble_opt_get is not supported for this option, but the actual - * local connection latency (unless set to NULL) is set as a return parameter - * when setting the option. - * - * @note The latency set will be truncated down to the closest slave latency event - * multiple, or the nearest multiple before half of the supervision timeout. - * - * @note The local connection latency is disabled by default, and needs to be enabled for new - * connections and whenever the connection is updated. - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle */ - uint16_t requested_latency; /**< Requested local connection latency. */ - uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */ -} ble_gap_opt_local_conn_latency_t; - - -/**@brief Passkey Option. - * - * Structure containing the passkey to be used during pairing. This can be used with @ref - * sd_ble_opt_set to make the SoftDevice use a pre-programmed passkey for authentication - * instead of generating a random one. - * - * @note @ref sd_ble_opt_get is not supported for this option. - * - */ -typedef struct -{ - uint8_t * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/ -} ble_gap_opt_passkey_t; - - -/**@brief Custom Privacy Option. - * - * This structure is used with both @ref sd_ble_opt_set (as input) and with - * @ref sd_ble_opt_get (as output). - * - * Structure containing: - * - A pointer to an IRK to set (if input), or a place to store a read IRK (if output). - * - A private address refresh cycle. - * - * @note The specified address cycle interval is used when the address cycle mode is - * @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO. If 0 is given, the address will not be automatically - * refreshed at all. The default interval is @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. - * - * @note If the current address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO, the address will immediately be - * refreshed when a custom privacy option is set. A new address can be generated manually by calling - * @ref sd_ble_gap_address_set with the same type again. - * - * @note If the IRK is updated, the new IRK becomes the one to be distributed in all - * bonding procedures performed after @ref sd_ble_opt_set returns. - * - * @retval ::NRF_SUCCESS Set or read successfully. - * @retval ::NRF_ERROR_INVALID_ADDR The pointer to IRK storage is invalid. - */ -typedef struct -{ - ble_gap_irk_t * p_irk; /**< When input: Pointer to custom IRK, or NULL to use/reset to the device's default IRK. When output: Pointer to where the current IRK is to be stored, or NULL to not read out the IRK. */ - uint16_t interval_s; /**< When input: Custom private address cycle interval in seconds. When output: The current private address cycle interval. */ -} ble_gap_opt_privacy_t; - - -/**@brief Scan request report option. - * - * This can be used with @ref sd_ble_opt_set to make the SoftDevice send - * @ref BLE_GAP_EVT_SCAN_REQ_REPORT events. - * - * @note Due to the limited space reserved for scan request report events, - * not all received scan requests will be reported. - * - * @note If whitelisting is used, only whitelisted requests are reported. - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_INVALID_STATE When advertising is ongoing while the option is set. - */ -typedef struct -{ - uint8_t enable : 1; /**< Enable scan request reports. */ -} ble_gap_opt_scan_req_report_t; - -/**@brief Compatibility mode option. - * - * This can be used with @ref sd_ble_opt_set to enable and disable - * compatibility modes. Compatibility modes are disabled by default. - * - * @note Compatibility mode 1 enables interoperability with devices that do not support - * a value of 0 for the WinOffset parameter in the Link Layer CONNECT_REQ packet. - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set. - */ -typedef struct -{ - uint8_t mode_1_enable : 1; /**< Enable compatibility mode 1.*/ -} ble_gap_opt_compat_mode_t; - - -/**@brief Option structure for GAP options. */ -typedef union -{ - ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ - ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ - ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ - ble_gap_opt_privacy_t privacy; /**< Parameters for the Custom privacy option. */ - ble_gap_opt_scan_req_report_t scan_req_report; /**< Parameters for the scan request report option.*/ - ble_gap_opt_compat_mode_t compat_mode; /**< Parameters for the compatibility mode option.*/ -} ble_gap_opt_t; -/**@} */ - - -/**@addtogroup BLE_GAP_FUNCTIONS Functions - * @{ */ - -/**@brief Set local Bluetooth address. - * - * @note If the address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO, the address type is required to - * be @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or - * @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. The given address is ignored and the - * SoftDevice will generate a new private address automatically every - * @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S seconds. If this API - * call is used again with the same parameters, the SoftDevice will immediately - * generate a new private address to replace the current address. - * - * @note If the application wishes to use a @ref BLE_GAP_ADDR_TYPE_PUBLIC or - * @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC address, the cycle mode must be - * @ref BLE_GAP_ADDR_CYCLE_MODE_NONE. - * - * @note If this API function is called while advertising or scanning, the softdevice will immediately update the - * advertising or scanning address without the need to stop the procedure in the following cases: - * - If the previously set address is of type @ref BLE_GAP_ADDR_TYPE_PUBLIC and the new address - * is also of type @ref BLE_GAP_ADDR_TYPE_PUBLIC - * - If the previously set address is not @ref BLE_GAP_ADDR_TYPE_PUBLIC and the new address is - * also not @ref BLE_GAP_ADDR_TYPE_PUBLIC. - * If the address is changed from a @ref BLE_GAP_ADDR_TYPE_PUBLIC address to another type or from - * another type to a @ref BLE_GAP_ADDR_TYPE_PUBLIC address, the change will take effect the next - * time an advertising or scanning procedure is started. - * - * @note If the address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_NONE and the application is - * using privacy, the application must take care to generate and set new private addresses - * periodically to comply with the Privacy specification in Bluetooth Core Spec. - * - * @param[in] addr_cycle_mode Address cycle mode, see @ref BLE_GAP_ADDR_CYCLE_MODES. - * @param[in] p_addr Pointer to address structure. - * - * @retval ::NRF_SUCCESS Address successfully set. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - */ -SVCALL(SD_BLE_GAP_ADDRESS_SET, uint32_t, sd_ble_gap_address_set(uint8_t addr_cycle_mode, const ble_gap_addr_t *p_addr)); - - -/**@brief Get local Bluetooth address. - * - * @param[out] p_addr Pointer to address structure to be filled in. - * - * @retval ::NRF_SUCCESS Address successfully retrieved. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_GAP_ADDRESS_GET, uint32_t, sd_ble_gap_address_get(ble_gap_addr_t *p_addr)); - - -/**@brief Set, clear or update advertising and scan response data. - * - * @note The format of the advertising data will be checked by this call to ensure interoperability. - * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and - * duplicating the local name in the advertising data and scan response data. - * - * @note To clear the advertising data and set it to a 0-length packet, simply provide a valid pointer (p_data/p_sr_data) with its corresponding - * length (dlen/srdlen) set to 0. - * - * @note The call will fail if p_data and p_sr_data are both NULL since this would have no effect. - * - * @param[in] p_data Raw data to be placed in advertising packet. If NULL, no changes are made to the current advertising packet data. - * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_data is NULL, can be 0 if p_data is not NULL. - * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, no changes are made to the current scan response packet data. - * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL. - * - * @retval ::NRF_SUCCESS Advertising data successfully updated or cleared. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. - * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied, check the advertising data format specification. - * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied. - * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data type. - * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied. - */ -SVCALL(SD_BLE_GAP_ADV_DATA_SET, uint32_t, sd_ble_gap_adv_data_set(uint8_t const *p_data, uint8_t dlen, uint8_t const *p_sr_data, uint8_t srdlen)); - - -/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). - * - * @note An application can start an advertising procedure for broadcasting purposes while a connection - * is active. After a @ref BLE_GAP_EVT_CONNECTED event is received, this function may therefore - * be called to start a broadcast advertising procedure. The advertising procedure - * cannot however be connectable (it must be of type @ref BLE_GAP_ADV_TYPE_ADV_SCAN_IND or - * @ref BLE_GAP_ADV_TYPE_ADV_NONCONN_IND). @note Only one advertiser may be active at any time. - * - * @param[in] p_adv_params Pointer to advertising parameters structure. - * - * @retval ::NRF_SUCCESS The BLE stack has started advertising. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check the accepted ranges and limits. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Bluetooth address supplied. - * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - */ -SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params)); - - -/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). - * - * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in advertising state). - */ -SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(void)); - - -/**@brief Update connection parameters. - * - * @details In the central role this will initiate a Link Layer connection parameter update procedure, - * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for - * the central to perform the procedure. In both cases, and regardless of success or failure, the application - * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event. - * - * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, - * the parameters in the PPCP characteristic of the GAP service will be used instead. - * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected - * - * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, process pending events and wait for pending procedures to complete and retry. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - */ -SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params)); - - -/**@brief Disconnect (GAP Link Termination). - * - * @details This call initiates the disconnection procedure, and its completion will be communicated to the application - * with a @ref BLE_GAP_EVT_DISCONNECTED event. - * - * @param[in] conn_handle Connection handle. - * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE). - * - * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (disconnection is already in progress). - */ -SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code)); - - -/**@brief Set the radio's transmit power. - * - * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm). - * - * @note -40 dBm will not actually give -40 dBm, but will instead be remapped to -30 dBm. - * - * @retval ::NRF_SUCCESS Successfully changed the transmit power. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - */ -SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(int8_t tx_power)); - - -/**@brief Set GAP Appearance value. - * - * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. - * - * @retval ::NRF_SUCCESS Appearance value set successfully. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - */ -SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance)); - - -/**@brief Get GAP Appearance value. - * - * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES. - * - * @retval ::NRF_SUCCESS Appearance value retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance)); - - -/**@brief Set GAP Peripheral Preferred Connection Parameters. - * - * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters. - * - * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - */ -SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params)); - - -/**@brief Get GAP Peripheral Preferred Connection Parameters. - * - * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored. - * - * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params)); - - -/**@brief Set GAP device name. - * - * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t. - * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. - * @param[in] len Length of the UTF-8, non NULL-terminated string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN). - * - * @retval ::NRF_SUCCESS GAP device name and permissions set successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - */ -SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len)); - - -/**@brief Get GAP device name. - * - * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. - * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. - * - * @note If the device name is longer than the size of the supplied buffer, - * p_len will return the complete device name length, - * and not the number of bytes actually returned in p_dev_name. - * The application may use this information to allocate a suitable buffer size. - * - * @retval ::NRF_SUCCESS GAP device name retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - */ -SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len)); - - -/**@brief Initiate the GAP Authentication procedure. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. - * In the peripheral role, only the timeout, bond and mitm fields of this structure are used. - * In the central role, this pointer may be NULL to reject a Security Request. - * - * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), - * otherwise in the peripheral role, an SMP Security Request will be sent. - * - * @note Calling this function may result in the following events depending on the outcome and parameters: @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, - * @ref BLE_GAP_EVT_SEC_INFO_REQUEST, @ref BLE_GAP_EVT_AUTH_KEY_REQUEST, @ref BLE_GAP_EVT_CONN_SEC_UPDATE, @ref BLE_GAP_EVT_AUTH_STATUS. - * - * - * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_TIMEOUT A SMP timout has occured, and further SMP operations on this link is prohibited. - */ -SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); - - -/**@brief Reply with GAP security parameters. - * - * @param[in] conn_handle Connection handle. - * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. - * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have - * already been provided during a previous call to @ref sd_ble_gap_authenticate. - * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys distributed as a result of the ongoing security procedure - * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application - * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. - * The pointer to the ID key data distributed by the local device constitutes however an exception. It can either point to ID key data - * filled in by the user before calling this function, in which case a user-supplied Bluetooth address and IRK will be distributed, - * or the pointer to the ID key data structure can be NULL, in which case the device's configured (or default, if none is configured) - * Bluetooth address and IRK will be distributed. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * - * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); - - -/**@brief Reply with an authentication key. - * - * @param[in] conn_handle Connection handle. - * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. - * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. - * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination). - * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in Little Endian format. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * - * @retval ::NRF_SUCCESS Authentication key successfully set. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); - - -/**@brief Initiate GAP Encryption procedure. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. - * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. - * - * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. - * - * @note Calling this function may result in the following event depending on the outcome and parameters: @ref BLE_GAP_EVT_CONN_SEC_UPDATE. - * - * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. - * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry. - */ -SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info)); - - -/**@brief Reply with GAP security information. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available. - * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. - * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. - * - * @retval ::NRF_SUCCESS Successfully accepted security information. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info)); - - -/**@brief Get the current connection security. - * - * @param[in] conn_handle Connection handle. - * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Current connection security successfully retrieved. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec)); - - -/**@brief Start reporting the received signal strength to the application. - * - * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. - * - * @param[in] conn_handle Connection handle. - * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID. - * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event. - * - * @retval ::NRF_SUCCESS Successfully activated RSSI reporting. - * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress. Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count)); - - -/**@brief Stop reporting the received signal strength. - * - * @note An RSSI change detected before the call but not yet received by the application - * may be reported after @ref sd_ble_gap_rssi_stop has been called. - * - * @param[in] conn_handle Connection handle. - * - * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle)); - - -/**@brief Get the received signal strength for the last connection event. - * - * @param[in] conn_handle Connection handle. - * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. - * - * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND - * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start. - * - * @retval ::NRF_SUCCESS Successfully read the RSSI. - * @retval ::NRF_ERROR_NOT_FOUND No sample is available. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing, or disconnection in progress. - */ -SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi)); - - -/**@brief Start scanning (GAP Discovery procedure, Observer Procedure). - * - * @param[in] p_scan_params Pointer to scan parameters structure. - * - * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_NOT_SUPPORTED A selected feature is not supported (selective scanning). - */ -SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params)); - - -/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). - * - * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in scanning state). - */ -SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); - - -/**@brief Create a connection (GAP Link Establishment). - * - * @param[in] p_peer_addr Pointer to peer address. If the selective bit is set in @ref ble_gap_scan_params_t, then this must be NULL. - * @param[in] p_scan_params Pointer to scan parameters structure. - * @param[in] p_conn_params Pointer to desired connection parameters. - * - * @retval ::NRF_SUCCESS Successfully initiated connection procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. - * @retval ::NRF_ERROR_NO_MEM limit of available connections reached. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. -*/ -SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params)); - - -/**@brief Cancel a connection establishment. - * - * @retval ::NRF_SUCCESS Successfully cancelled an ongoing connection procedure. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - */ -SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); - -/** @} */ - -#endif // BLE_GAP_H__ - -/** - @} -*/ diff --git a/components/softdevice/s110/headers/ble_gattc.h b/components/softdevice/s110/headers/ble_gattc.h deleted file mode 100644 index 57ce312..0000000 --- a/components/softdevice/s110/headers/ble_gattc.h +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client - @{ - @brief Definitions and prototypes for the GATT Client interface. - */ - -#ifndef BLE_GATTC_H__ -#define BLE_GATTC_H__ - -#include "ble_gatt.h" -#include "ble_types.h" -#include "ble_ranges.h" -#include "nrf_svc.h" - -/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations - * @{ */ - -/**@brief GATTC API SVC numbers. */ -enum BLE_GATTC_SVCS -{ - SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */ - SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ - SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ - SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ - SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ - SD_BLE_GATTC_READ, /**< Generic read. */ - SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ - SD_BLE_GATTC_WRITE, /**< Generic write. */ - SD_BLE_GATTC_HV_CONFIRM /**< Handle Value Confirmation. */ -}; - -/** - * @brief GATT Client Event IDs. - */ -enum BLE_GATTC_EVTS -{ - BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. @ref ble_gattc_evt_prim_srvc_disc_rsp_t */ - BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. @ref ble_gattc_evt_rel_disc_rsp_t */ - BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. @ref ble_gattc_evt_char_disc_rsp_t */ - BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. @ref ble_gattc_evt_desc_disc_rsp_t */ - BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t */ - BLE_GATTC_EVT_READ_RSP, /**< Read Response event. @ref ble_gattc_evt_read_rsp_t */ - BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. @ref ble_gattc_evt_char_vals_read_rsp_t */ - BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. @ref ble_gattc_evt_write_rsp_t */ - BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. @ref ble_gattc_evt_hvx_t */ - BLE_GATTC_EVT_TIMEOUT /**< Timeout event. @ref ble_gattc_evt_timeout_t */ -}; - -/** @} */ - -/** @addtogroup BLE_GATTC_DEFINES Defines - * @{ */ - -/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC - * @{ */ -#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ -/** @} */ - -/**@brief Last Attribute Handle. */ -#define BLE_GATTC_HANDLE_END 0xFFFF - -/** @} */ - -/** @addtogroup BLE_GATTC_STRUCTURES Structures - * @{ */ - -/**@brief Operation Handle Range. */ -typedef struct -{ - uint16_t start_handle; /**< Start Handle. */ - uint16_t end_handle; /**< End Handle. */ -} ble_gattc_handle_range_t; - - -/**@brief GATT service. */ -typedef struct -{ - ble_uuid_t uuid; /**< Service UUID. */ - ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ -} ble_gattc_service_t; - - -/**@brief GATT include. */ -typedef struct -{ - uint16_t handle; /**< Include Handle. */ - ble_gattc_service_t included_srvc; /**< Handle of the included service. */ -} ble_gattc_include_t; - - -/**@brief GATT characteristic. */ -typedef struct -{ - ble_uuid_t uuid; /**< Characteristic UUID. */ - ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ - uint8_t char_ext_props : 1; /**< Extended properties present. */ - uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */ - uint16_t handle_value; /**< Handle of the Characteristic Value. */ -} ble_gattc_char_t; - - -/**@brief GATT descriptor. */ -typedef struct -{ - uint16_t handle; /**< Descriptor Handle. */ - ble_uuid_t uuid; /**< Descriptor UUID. */ -} ble_gattc_desc_t; - - -/**@brief Write Parameters. */ -typedef struct -{ - uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ - uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ - uint16_t handle; /**< Handle to the attribute to be written. */ - uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ - uint16_t len; /**< Length of data in bytes. */ - uint8_t *p_value; /**< Pointer to the value data. */ -} ble_gattc_write_params_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Service count. */ - ble_gattc_service_t services[1]; /**< Service data, variable length. */ -} ble_gattc_evt_prim_srvc_disc_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Include count. */ - ble_gattc_include_t includes[1]; /**< Include data, variable length. */ -} ble_gattc_evt_rel_disc_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Characteristic count. */ - ble_gattc_char_t chars[1]; /**< Characteristic data, variable length. */ -} ble_gattc_evt_char_disc_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Descriptor count. */ - ble_gattc_desc_t descs[1]; /**< Descriptor data, variable length. */ -} ble_gattc_evt_desc_disc_rsp_t; - -/**@brief GATT read by UUID handle value pair. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint8_t *p_value; /**< Pointer to value, variable length (length available as value_len in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t). - Please note that this pointer is absolute to the memory provided by the user when retrieving the event, - so it will effectively point to a location inside the handle_value array. */ -} ble_gattc_handle_value_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */ -typedef struct -{ - uint16_t count; /**< Handle-Value Pair Count. */ - uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ - ble_gattc_handle_value_t handle_value[1]; /**< Handle-Value(s) list, variable length. */ -} ble_gattc_evt_char_val_by_uuid_read_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint16_t offset; /**< Offset of the attribute data. */ - uint16_t len; /**< Attribute data length. */ - uint8_t data[1]; /**< Attribute data, variable length. */ -} ble_gattc_evt_read_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ -typedef struct -{ - uint16_t len; /**< Concatenated Attribute values length. */ - uint8_t values[1]; /**< Attribute values, variable length. */ -} ble_gattc_evt_char_vals_read_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ - uint16_t offset; /**< Data offset. */ - uint16_t len; /**< Data length. */ - uint8_t data[1]; /**< Data, variable length. */ -} ble_gattc_evt_write_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ -typedef struct -{ - uint16_t handle; /**< Handle to which the HVx operation applies. */ - uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ - uint16_t len; /**< Attribute data length. */ - uint8_t data[1]; /**< Attribute data, variable length. */ -} ble_gattc_evt_hvx_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ -typedef struct -{ - uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ -} ble_gattc_evt_timeout_t; - -/**@brief GATTC event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which event occured. */ - uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ - uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */ - union - { - ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */ - ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */ - ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */ - ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */ - ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */ - ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */ - ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */ - ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ - ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ - ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ - } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ -} ble_gattc_evt_t; -/** @} */ - -/** @addtogroup BLE_GATTC_FUNCTIONS Functions - * @{ */ - -/**@brief Initiate or continue a GATT Primary Service Discovery procedure. - * - * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle. - * If the last service has not been reached, this function must be called again with an updated start handle value to continue the search. - * - * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with - * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] start_handle Handle to start searching from. - * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid)); - - -/**@brief Initiate or continue a GATT Relationship Discovery procedure. - * - * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached, - * this must be called again with an updated handle range to continue the search. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Characteristic Discovery procedure. - * - * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached, - * this must be called again with an updated handle range to continue the discovery. - * - * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with - * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure. - * - * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached, - * this must be called again with an updated handle range to continue the discovery. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure. - * - * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached, - * this must be called again with an updated handle range to continue the discovery. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_uuid Pointer to a Characteristic value UUID to read. - * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure. - * - * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor - * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the - * complete value. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] handle The handle of the attribute to be read. - * @param[in] offset Offset into the attribute value to be read. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); - - -/**@brief Initiate a GATT Read Multiple Characteristic Values procedure. - * - * @details This function initiates a GATT Read Multiple Characteristic Values procedure. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. - * @param[in] handle_count The number of handles in p_handles. - * - * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count)); - - -/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure. - * - * @details This function can perform all write procedures described in GATT. - * - * @note It is important to note that a write without response will consume an application buffer, and will therefore - * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. A write (with response) on the other hand will use the - * standard client internal buffer and thus will only generate a @ref BLE_GATTC_EVT_WRITE_RSP event as soon as the write response - * has been received from the peer. Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_write_params A pointer to a write parameters structure. - * - * @retval ::NRF_SUCCESS Successfully started the Write procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - * @retval ::NRF_ERROR_BUSY Procedure already in progress. - * @retval ::BLE_ERROR_NO_TX_BUFFERS There are no available buffers left. - */ -SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); - - -/**@brief Send a Handle Value Confirmation to the GATT Server. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] handle The handle of the attribute in the indication. - * - * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed. - * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle. - */ -SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); - -/** @} */ - -#endif /* BLE_GATTC_H__ */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s110/headers/ble_gatts.h b/components/softdevice/s110/headers/ble_gatts.h deleted file mode 100644 index 97c5927..0000000 --- a/components/softdevice/s110/headers/ble_gatts.h +++ /dev/null @@ -1,639 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server - @{ - @brief Definitions and prototypes for the GATTS interface. - */ - -#ifndef BLE_GATTS_H__ -#define BLE_GATTS_H__ - -#include "ble_types.h" -#include "ble_ranges.h" -#include "ble_l2cap.h" -#include "ble_gap.h" -#include "ble_gatt.h" -#include "nrf_svc.h" - -/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations - * @{ */ - -/** - * @brief GATTS API SVC numbers. - */ -enum BLE_GATTS_SVCS -{ - SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */ - SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */ - SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */ - SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */ - SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */ - SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */ - SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */ - SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */ - SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ - SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ - SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */ -}; - -/** - * @brief GATT Server Event IDs. - */ -enum BLE_GATTS_EVTS -{ - BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. @ref ble_gatts_evt_write_t */ - BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request.@ref ble_gatts_evt_rw_authorize_request_t */ - BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending, awaiting a sd_ble_gatts_sys_attr_set(). @ref ble_gatts_evt_sys_attr_missing_t */ - BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. @ref ble_gatts_evt_hvc_t */ - BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. No additional event structure applies. */ - BLE_GATTS_EVT_TIMEOUT /**< Timeout. @ref ble_gatts_evt_timeout_t */ -}; -/** @} */ - -/** @addtogroup BLE_GATTS_DEFINES Defines - * @{ */ - -/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS - * @{ */ -#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */ -#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */ -/** @} */ - -/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths - * @{ */ -#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */ -#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */ -/** @} */ - -/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types - * @{ */ -#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */ -#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */ -#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */ -/** @} */ - - -/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types - * @{ */ -#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */ -#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */ -#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */ -#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */ -#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */ -#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */ -#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */ -#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */ -/** @} */ - - -/** @defgroup BLE_GATTS_OPS GATT Server Operations - * @{ */ -#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */ -#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */ -#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */ -#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ -#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ -#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */ -#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */ -/** @} */ - -/** @defgroup BLE_GATTS_VLOCS GATT Value Locations - * @{ */ -#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */ -#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */ -#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack - will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */ -/** @} */ - -/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types - * @{ */ -#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */ -#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */ -#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */ -/** @} */ - -/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags - * @{ */ -#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */ -#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */ -/** @} */ - -/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size - * @{ - */ -#define BLE_GATTS_ATTR_TAB_SIZE_MIN 216 /**< Minimum Attribute Table size */ -#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT 0x0000 /**< Default Attribute Table size (0x700 bytes for this version of the SoftDevice). */ -/** @} */ - -/** @} */ - -/** @addtogroup BLE_GATTS_STRUCTURES Structures - * @{ */ - -/** - * @brief BLE GATTS init options - */ -typedef struct -{ - uint8_t service_changed:1; /**< Include the Service Changed characteristic in the Attribute Table. */ - uint32_t attr_tab_size; /**< Attribute Table size in bytes. The size must be a multiple of 4. @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT is used to set the default size. */ -} ble_gatts_enable_params_t; - -/**@brief Attribute metadata. */ -typedef struct -{ - ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ - ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ - uint8_t vlen :1; /**< Variable length attribute. */ - uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ - uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */ - uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */ -} ble_gatts_attr_md_t; - - -/**@brief GATT Attribute. */ -typedef struct -{ - ble_uuid_t *p_uuid; /**< Pointer to the attribute UUID. */ - ble_gatts_attr_md_t *p_attr_md; /**< Pointer to the attribute metadata structure. */ - uint16_t init_len; /**< Initial attribute value length in bytes. */ - uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */ - uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ - uint8_t* p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer - that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. - The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/ -} ble_gatts_attr_t; - -/**@brief GATT Attribute Value. */ -typedef struct -{ - uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/ - uint16_t offset; /**< Attribute value offset. */ - uint8_t *p_value; /**< Pointer to where value is stored or will be stored. - If value is stored in user memory, only the attribute length is updated when p_value == NULL. - Set to NULL when reading to obtain the complete length of the attribute value */ -} ble_gatts_value_t; - - -/**@brief GATT Attribute Context. */ -typedef struct -{ - ble_uuid_t srvc_uuid; /**< Service UUID. */ - ble_uuid_t char_uuid; /**< Characteristic UUID if applicable (BLE_UUID_TYPE_UNKNOWN otherwise). */ - ble_uuid_t desc_uuid; /**< Descriptor UUID if applicable (BLE_UUID_TYPE_UNKNOWN otherwise). */ - uint16_t srvc_handle; /**< Service Handle. */ - uint16_t value_handle; /**< Characteristic Value Handle if applicable (BLE_GATT_HANDLE_INVALID otherwise). */ - uint8_t type; /**< Attribute Type, see @ref BLE_GATTS_ATTR_TYPES. */ -} ble_gatts_attr_context_t; - - -/**@brief GATT Characteristic Presentation Format. */ -typedef struct -{ - uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */ - int8_t exponent; /**< Exponent for integer data types. */ - uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */ - uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ - uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ -} ble_gatts_char_pf_t; - - -/**@brief GATT Characteristic metadata. */ -typedef struct -{ - ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ - ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */ - uint8_t *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */ - uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */ - uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ - ble_gatts_char_pf_t* p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */ - ble_gatts_attr_md_t* p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */ - ble_gatts_attr_md_t* p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */ - ble_gatts_attr_md_t* p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */ -} ble_gatts_char_md_t; - - -/**@brief GATT Characteristic Definition Handles. */ -typedef struct -{ - uint16_t value_handle; /**< Handle to the characteristic value. */ - uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ - uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ - uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ -} ble_gatts_char_handles_t; - - -/**@brief GATT HVx parameters. */ -typedef struct -{ - uint16_t handle; /**< Characteristic Value Handle. */ - uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ - uint16_t offset; /**< Offset within the attribute value. */ - uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after successful return. */ - uint8_t *p_data; /**< Actual data content, use NULL to use the current attribute value. */ -} ble_gatts_hvx_params_t; - -/**@brief GATT Read Authorization parameters. */ -typedef struct -{ - uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ - uint8_t update : 1; /**< If set, data supplied in p_data will be used in the ATT response. */ - uint16_t offset; /**< Offset of the attribute value being updated. */ - uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ - uint8_t *p_data; /**< Pointer to new value used to update the attribute value. */ -} ble_gatts_read_authorize_params_t; - -/**@brief GATT Write Authorization parameters. */ -typedef struct -{ - uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ -} ble_gatts_write_authorize_params_t; - -/**@brief GATT Read or Write Authorize Reply parameters. */ -typedef struct -{ - uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ - union { - ble_gatts_read_authorize_params_t read; /**< Read authorization parameters. */ - ble_gatts_write_authorize_params_t write; /**< Write authorization parameters. */ - } params; /**< Reply Parameters. */ -} ble_gatts_rw_authorize_reply_params_t; - - - -/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ - ble_gatts_attr_context_t context; /**< Attribute Context. */ - uint16_t offset; /**< Offset for the write operation. */ - uint16_t len; /**< Length of the received data. */ - uint8_t data[1]; /**< Received data, variable length. */ -} ble_gatts_evt_write_t; - -/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - ble_gatts_attr_context_t context; /**< Attribute Context. */ - uint16_t offset; /**< Offset for the read operation. */ -} ble_gatts_evt_read_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */ -typedef struct -{ - uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ - union { - ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */ - ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */ - } request; /**< Request Parameters. */ -} ble_gatts_evt_rw_authorize_request_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */ -typedef struct -{ - uint8_t hint; /**< Hint (currently unused). */ -} ble_gatts_evt_sys_attr_missing_t; - - -/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ -} ble_gatts_evt_hvc_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */ -typedef struct -{ - uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ -} ble_gatts_evt_timeout_t; - - -/**@brief GATT Server event callback event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ - union - { - ble_gatts_evt_write_t write; /**< Write Event Parameters. */ - ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ - ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ - ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ - ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ - } params; /**< Event Parameters. */ -} ble_gatts_evt_t; - -/** @} */ - -/** @addtogroup BLE_GATTS_FUNCTIONS Functions - * @{ */ - -/**@brief Add a service declaration to the Attribute Table. - * - * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. - * @param[in] p_uuid Pointer to service UUID. - * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. - * - * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to - * add a secondary service declaration that is not referenced by another service later in the Attribute Table. - * - * @retval ::NRF_SUCCESS Successfully added a service declaration. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - */ -SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle)); - - -/**@brief Add an include declaration to the Attribute Table. - * - * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time). - * - * @note The included service must already be present in the Attribute Table prior to this call. - * - * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. - * @param[in] inc_srvc_handle Handle of the included service. - * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. - * - * @retval ::NRF_SUCCESS Successfully added an include declaration. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - */ -SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle)); - - -/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table. - * - * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time). - * - * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writeable auxiliaries bits, - * readable (no security) and writeable (selectable) CCCDs and SCCDs and valid presentation format values. - * - * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions. - * - * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. - * @param[in] p_char_md Characteristic metadata. - * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. - * @param[out] p_handles Pointer to the structure where the assigned handles will be stored. - * - * @retval ::NRF_SUCCESS Successfully added a characteristic. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. - */ -SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles)); - - -/**@brief Add a descriptor to the Attribute Table. - * - * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). - * - * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. - * @param[in] p_attr Pointer to the attribute structure. - * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. - * - * @retval ::NRF_SUCCESS Successfully added a descriptor. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. - */ -SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); - -/**@brief Set the value of a given attribute. - * - * @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used. - * @param[in] handle Attribute handle. - * @param[in,out] p_value Attribute value information. - * - * @note Values other than system attributes can be set at any time, regardless of wheter any active connections exist. - * - * @retval ::NRF_SUCCESS Successfully set the value of the attribute. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE @ref BLE_CONN_HANDLE_INVALID supplied on a system attribute. - */ -SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); - -/**@brief Get the value of a given attribute. - * - * @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used. - * @param[in] handle Attribute handle. - * @param[in,out] p_value Attribute value information. - * - * @note If the attribute value is longer than the size of the supplied buffer, - * p_len will return the total attribute value length (excluding offset), - * and not the number of bytes actually returned in p_data. - * The application may use this information to allocate a suitable buffer size. - * - * @note When retrieving system attribute values with this function, the connection handle - * may refer to an already disconnected connection. Refer to the documentation of - * @ref sd_ble_gatts_sys_attr_get for further information. - * - * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE @ref BLE_CONN_HANDLE_INVALID supplied on a system attribute. - */ -SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); - -/**@brief Notify or Indicate an attribute value. - * - * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation - * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that - * the application can atomically perform a value update and a server initiated transaction with a single API call. - * If the application chooses to indicate an attribute value, a @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from - * the peer. - * - * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. - * When receiveing the error codes @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and - * @ref BLE_ERROR_NO_TX_BUFFERS the Attribute Table has been updated. - * The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len). - * - * @note It is important to note that a notification will consume an application buffer, and will therefore - * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. An indication on the other hand will use the - * standard server internal buffer and thus will only generate a @ref BLE_GATTS_EVT_HVC event as soon as the confirmation - * has been received from the peer. Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_hvx_params Pointer to an HVx parameters structure. If the p_data member contains a non-NULL pointer the attribute value will be updated with - * the contents pointed by it before sending the notification or indication. - * - * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate. - * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - * @retval ::NRF_ERROR_BUSY Procedure already in progress. - * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. - * @retval ::BLE_ERROR_NO_TX_BUFFERS There are no available buffers to send the data, applies only to notifications. - */ -SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); - -/**@brief Indicate the Service Changed attribute value. - * - * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute - * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will - * be issued. - * - * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. - * - * @param[in] conn_handle Connection handle. - * @param[in] start_handle Start of affected attribute handle range. - * @param[in] end_handle End of affected attribute handle range. - * - * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, notifications or indications must be enabled in the CCCD. - * @retval ::NRF_ERROR_BUSY Procedure already in progress. - * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. - */ -SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)); - -/**@brief Respond to a Read/Write authorization request. - * - * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. - * - * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. - * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, - * or for Read Authorization reply: requested handles not replied with, - * or for Write Authorization reply: handle supplied does not match requested handle. - * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time. - */ -SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); - - -/**@brief Update persistent system attribute information. - * - * @details Supply information about persistent system attributes to the stack, - * previously obtained using @ref sd_ble_gatts_sys_attr_get. - * This call is only allowed for active connections, and is usually - * made immediately after a connection is established with an known bonded device, - * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. - * - * p_sysattrs may point directly to the application's stored copy of the system attributes - * obtained using @ref sd_ble_gatts_sys_attr_get. - * If the pointer is NULL, the system attribute info is initialized, assuming that - * the application does not have any previously saved system attribute data for this device. - * - * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. - * - * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially. - * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or - * reset the SoftDevice to return to a known state. - * - * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified. - * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. - * @param[in] len Size of data pointed by p_sys_attr_data, in octets. - * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS - * - * @retval ::NRF_SUCCESS Successfully set the system attribute information. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time. - */ -SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); - - -/**@brief Retrieve persistent system attribute information from the stack. - * - * @details This call is used to retrieve information about values to be stored perisistently by the application - * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device, - * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set. - * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for - * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it. - * Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes - * may be written to at any time by the peer during a connection's lifetime. - * - * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned. - * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned. - * - * @param[in] conn_handle Connection handle of the recently terminated connection. - * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. NULL can be provided to - * obtain the length of the data - * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditially updated to actual length of system attribute data. - * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS - * - * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. - * @retval ::NRF_ERROR_NOT_FOUND No system attributes found. - */ -SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); - -/** @} */ - -#endif // BLE_GATTS_H__ - -/** - @} -*/ diff --git a/components/softdevice/s110/headers/ble_l2cap.h b/components/softdevice/s110/headers/ble_l2cap.h deleted file mode 100644 index 6eab9fb..0000000 --- a/components/softdevice/s110/headers/ble_l2cap.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) - @{ - @brief Definitions and prototypes for the L2CAP interface. - */ - -#ifndef BLE_L2CAP_H__ -#define BLE_L2CAP_H__ - -#include "ble_types.h" -#include "ble_ranges.h" -#include "ble_err.h" -#include "nrf_svc.h" - -/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations - * @{ */ - -/**@brief L2CAP API SVC numbers. */ -enum BLE_L2CAP_SVCS -{ - SD_BLE_L2CAP_CID_REGISTER = BLE_L2CAP_SVC_BASE, /**< Register a CID. */ - SD_BLE_L2CAP_CID_UNREGISTER, /**< Unregister a CID. */ - SD_BLE_L2CAP_TX /**< Transmit a packet. */ -}; - -/**@brief L2CAP Event IDs. */ -enum BLE_L2CAP_EVTS -{ - BLE_L2CAP_EVT_RX = BLE_L2CAP_EVT_BASE /**< L2CAP packet received. */ -}; - -/** @} */ - -/**@addtogroup BLE_L2CAP_DEFINES Defines - * @{ */ - -/**@defgroup BLE_ERRORS_L2CAP SVC return values specific to L2CAP - * @{ */ -#define BLE_ERROR_L2CAP_CID_IN_USE (NRF_L2CAP_ERR_BASE + 0x000) /**< CID already in use. */ -/** @} */ - -/**@brief Default L2CAP MTU. */ -#define BLE_L2CAP_MTU_DEF (23) - -/**@brief Invalid Channel Identifier. */ -#define BLE_L2CAP_CID_INVALID (0x0000) - -/**@brief Dynamic Channel Identifier base. */ -#define BLE_L2CAP_CID_DYN_BASE (0x0040) - -/**@brief Maximum amount of dynamic CIDs. */ -#define BLE_L2CAP_CID_DYN_MAX (8) - -/** @} */ - -/**@addtogroup BLE_L2CAP_STRUCTURES Structures - * @{ */ - -/**@brief Packet header format for L2CAP transmission. */ -typedef struct -{ - uint16_t len; /**< Length of valid info in data member. */ - uint16_t cid; /**< Channel ID on which packet is transmitted. */ -} ble_l2cap_header_t; - - -/**@brief L2CAP Received packet event report. */ -typedef struct -{ - ble_l2cap_header_t header; /**< L2CAP packet header. */ - uint8_t data[1]; /**< Packet data, variable length. */ -} ble_l2cap_evt_rx_t; - - -/**@brief L2CAP event callback event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which event occured. */ - union - { - ble_l2cap_evt_rx_t rx; /**< RX Event parameters. */ - } params; /**< Event Parameters. */ -} ble_l2cap_evt_t; - -/** @} */ - -/**@addtogroup BLE_L2CAP_FUNCTIONS Functions - * @{ */ - -/**@brief Register a CID with L2CAP. - * - * @details This registers a higher protocol layer with the L2CAP multiplexer, and is requried prior to all operations on the CID. - * - * @param[in] cid L2CAP CID. - * - * @retval ::NRF_SUCCESS Successfully registered a CID with the L2CAP layer. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CID must be above @ref BLE_L2CAP_CID_DYN_BASE. - * @retval ::BLE_ERROR_L2CAP_CID_IN_USE L2CAP CID already in use. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - */ -SVCALL(SD_BLE_L2CAP_CID_REGISTER, uint32_t, sd_ble_l2cap_cid_register(uint16_t cid)); - -/**@brief Unregister a CID with L2CAP. - * - * @details This unregisters a previously registerd higher protocol layer with the L2CAP multiplexer. - * - * @param[in] cid L2CAP CID. - * - * @retval ::NRF_SUCCESS Successfully unregistered the CID. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_NOT_FOUND CID not previously registered. - */ -SVCALL(SD_BLE_L2CAP_CID_UNREGISTER, uint32_t, sd_ble_l2cap_cid_unregister(uint16_t cid)); - -/**@brief Transmit an L2CAP packet. - * - * @note It is important to note that a call to this function will consume an application buffer, and will therefore - * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. - * Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. - * - * @param[in] conn_handle Connection Handle. - * @param[in] p_header Pointer to a packet header containing length and CID. - * @param[in] p_data Pointer to the data to be transmitted. - * - * @retval ::NRF_SUCCESS Successfully queued an L2CAP packet for transmission. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register. - * @retval ::NRF_ERROR_NOT_FOUND CID not found. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::BLE_ERROR_NO_TX_BUFFERS Not enough application buffers available. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF. - */ -SVCALL(SD_BLE_L2CAP_TX, uint32_t, sd_ble_l2cap_tx(uint16_t conn_handle, ble_l2cap_header_t const *p_header, uint8_t const *p_data)); - -/** @} */ - -#endif // BLE_L2CAP_H__ - -/** - @} -*/ diff --git a/components/softdevice/s110/headers/ble_ranges.h b/components/softdevice/s110/headers/ble_ranges.h deleted file mode 100644 index 69100b3..0000000 --- a/components/softdevice/s110/headers/ble_ranges.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_COMMON - @{ - @defgroup ble_ranges Module specific SVC, event and option number subranges - @{ - - @brief Definition of SVC, event and option number subranges for each API module. - - @note - SVCs, event and option numbers are split into subranges for each API module. - Each module receives its entire allocated range of SVC calls, whether implemented or not, - but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range. - - Note that the symbols BLE__SVC_LAST is the end of the allocated SVC range, - rather than the last SVC function call actually defined and implemented. - - Specific SVC, event and option values are defined in each module's ble_.h file, - which defines names of each individual SVC code based on the range start value. -*/ - -#ifndef BLE_RANGES_H__ -#define BLE_RANGES_H__ - -#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ -#define BLE_SVC_LAST 0x6B /**< Total: 12. */ - -#define BLE_RESERVED_SVC_BASE 0x6C /**< Reserved BLE SVC base. */ -#define BLE_RESERVED_SVC_LAST 0x6F /**< Total: 4. */ - -#define BLE_GAP_SVC_BASE 0x70 /**< GAP BLE SVC base. */ -#define BLE_GAP_SVC_LAST 0x8F /**< Total: 32. */ - -#define BLE_GATTC_SVC_BASE 0x90 /**< GATTC BLE SVC base. */ -#define BLE_GATTC_SVC_LAST 0x9F /**< Total: 32. */ - -#define BLE_GATTS_SVC_BASE 0xA0 /**< GATTS BLE SVC base. */ -#define BLE_GATTS_SVC_LAST 0xAF /**< Total: 16. */ - -#define BLE_L2CAP_SVC_BASE 0xB0 /**< L2CAP BLE SVC base. */ -#define BLE_L2CAP_SVC_LAST 0xBF /**< Total: 16. */ - - -#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */ - -#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */ -#define BLE_EVT_LAST 0x0F /**< Total: 15. */ - -#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */ -#define BLE_GAP_EVT_LAST 0x2F /**< Total: 32. */ - -#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */ -#define BLE_GATTC_EVT_LAST 0x4F /**< Total: 32. */ - -#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */ -#define BLE_GATTS_EVT_LAST 0x6F /**< Total: 32. */ - -#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */ -#define BLE_L2CAP_EVT_LAST 0x8F /**< Total: 32. */ - - -#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */ - -#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */ -#define BLE_OPT_LAST 0x1F /**< Total: 31. */ - -#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */ -#define BLE_GAP_OPT_LAST 0x3F /**< Total: 32. */ - -#define BLE_GATTC_OPT_BASE 0x40 /**< GATTC BLE Option base. */ -#define BLE_GATTC_OPT_LAST 0x5F /**< Total: 32. */ - -#define BLE_GATTS_OPT_BASE 0x60 /**< GATTS BLE Option base. */ -#define BLE_GATTS_OPT_LAST 0x7F /**< Total: 32. */ - -#define BLE_L2CAP_OPT_BASE 0x80 /**< L2CAP BLE Option base. */ -#define BLE_L2CAP_OPT_LAST 0x9F /**< Total: 32. */ - -#endif /* BLE_RANGES_H__ */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s110/headers/ble_types.h b/components/softdevice/s110/headers/ble_types.h deleted file mode 100644 index d99d774..0000000 --- a/components/softdevice/s110/headers/ble_types.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_COMMON - @{ - @defgroup ble_types Common types and macro definitions - @{ - - @brief Common types and macro definitions for the BLE SoftDevice. - */ - -#ifndef BLE_TYPES_H__ -#define BLE_TYPES_H__ - -#include - -/** @addtogroup BLE_TYPES_DEFINES Defines - * @{ */ - -/** @defgroup BLE_CONN_HANDLES BLE Connection Handles - * @{ */ -#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */ -#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */ -/** @} */ - - -/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs - * @{ */ -/* Generic UUIDs, applicable to all services */ -#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */ -#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */ -#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */ -#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */ -#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */ -#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */ -#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */ -/* GATT specific UUIDs */ -#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */ -#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */ -/* GAP specific UUIDs */ -#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */ -#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_PPF 0x2A02 /**< Peripheral Privacy Flag Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */ -/** @} */ - - -/** @defgroup BLE_UUID_TYPES Types of UUID - * @{ */ -#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */ -#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */ -#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */ -/** @} */ - - -/** @defgroup BLE_APPEARANCES Bluetooth Appearance values - * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml - * @{ */ -#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */ -#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */ -#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */ -#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */ -#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */ -#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */ -#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */ -#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */ -#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */ -#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */ -#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */ -#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */ -#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */ -#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */ -#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */ -#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */ -#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */ -#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */ -#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */ -#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */ -#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */ -#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */ -#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */ -#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystiq (HID Subtype). */ -#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */ -#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */ -#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */ -#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */ -#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */ -#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */ -#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */ -#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */ -#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */ -#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */ -#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */ -#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */ -#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */ -#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */ -#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */ -#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */ -#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */ -#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */ -#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */ -#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */ -#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ -/** @} */ - -/** @brief Set .type and .uuid fields of ble_uuid_struct to specified uuid value. */ -#define BLE_UUID_BLE_ASSIGN(instance, value) do {\ - instance.type = BLE_UUID_TYPE_BLE; \ - instance.uuid = value;} while(0) - -/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */ -#define BLE_UUID_COPY_PTR(dst, src) do {\ - (dst)->type = (src)->type; \ - (dst)->uuid = (src)->uuid;} while(0) - -/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */ -#define BLE_UUID_COPY_INST(dst, src) do {\ - (dst).type = (src).type; \ - (dst).uuid = (src).uuid;} while(0) - -/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ -#define BLE_UUID_EQ(p_uuid1, p_uuid2) \ - (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid)) - -/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ -#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \ - (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid)) - -/** @} */ - -/** @addtogroup BLE_TYPES_STRUCTURES Structures - * @{ */ - -/** @brief 128 bit UUID values. */ -typedef struct -{ - unsigned char uuid128[16]; /**< Little-Endian UUID bytes. */ -} ble_uuid128_t; - -/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ -typedef struct -{ - uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ - uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ -} ble_uuid_t; - -/** @} */ - -#endif /* BLE_TYPES_H__ */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s110/headers/nrf_error.h b/components/softdevice/s110/headers/nrf_error.h deleted file mode 100644 index efa1b65..0000000 --- a/components/softdevice/s110/headers/nrf_error.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - /** - @defgroup nrf_error SoftDevice Global Error Codes - @{ - - @brief Global Error definitions -*/ - -/* Header guard */ -#ifndef NRF_ERROR_H__ -#define NRF_ERROR_H__ - -/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions - * @{ */ -#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base -#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base -#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base -#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base -/** @} */ - -#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command -#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing -#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled -#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error -#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation -#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found -#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported -#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter -#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state -#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length -#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags -#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data -#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit -#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out -#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer -#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation -#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address -#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy - -#endif // NRF_ERROR_H__ - -/** - @} -*/ diff --git a/components/softdevice/s110/headers/nrf_error_sdm.h b/components/softdevice/s110/headers/nrf_error_sdm.h deleted file mode 100644 index 25a1437..0000000 --- a/components/softdevice/s110/headers/nrf_error_sdm.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - /** - @addtogroup nrf_sdm_api - @{ - @defgroup nrf_sdm_error SoftDevice Manager Error Codes - @{ - - @brief Error definitions for the SDM API -*/ - -/* Header guard */ -#ifndef NRF_ERROR_SDM_H__ -#define NRF_ERROR_SDM_H__ - -#include "nrf_error.h" - -#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown lfclk source. -#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). -#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erronous SoftDevice flashing). - -#endif // NRF_ERROR_SDM_H__ - -/** - @} - @} -*/ diff --git a/components/softdevice/s110/headers/nrf_sd_def.h b/components/softdevice/s110/headers/nrf_sd_def.h deleted file mode 100644 index 4740cd8..0000000 --- a/components/softdevice/s110/headers/nrf_sd_def.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_SD_DEF_H__ -#define NRF_SD_DEF_H__ - -#include - -#define SD_PPI_CHANNELS_USED 0xFFF0C000uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */ -#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ -#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ -#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ - -#endif /* NRF_SD_DEF_H__ */ diff --git a/components/softdevice/s110/headers/nrf_sdm.h b/components/softdevice/s110/headers/nrf_sdm.h deleted file mode 100644 index 4d407a9..0000000 --- a/components/softdevice/s110/headers/nrf_sdm.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - @defgroup nrf_sdm_api SoftDevice Manager API - @{ - - @brief APIs for SoftDevice management. - -*/ - -/* Header guard */ -#ifndef NRF_SDM_H__ -#define NRF_SDM_H__ - -#include "nrf_svc.h" -#include "nrf.h" -#include "nrf_soc.h" -#include "nrf_error_sdm.h" - -/** @addtogroup NRF_SDM_DEFINES Defines - * @{ */ - -/** @brief SoftDevice Manager SVC Base number. */ -#define SDM_SVC_BASE 0x10 - -/** @} */ - -/** @brief Defines the SoftDevice Information Structure location (address) as an offset from -the start of the softdevice (without MBR)*/ -#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) - -/** @brief Defines the usual size reserverd for the MBR when a softdevice is written to flash. -This is the offset where the first byte of the softdevice hex file is written.*/ -#define MBR_SIZE (0x1000) - -/** @brief Defines the absolute Softdevice information structure location (address)*/ -#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) - -/** @brief Defines the offset for Softdevice size value relative to Softdevice base address*/ -#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) - -/** @brief Defines the offset for FWID value relative to Softdevice base address*/ -#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) - -/** @brief Defines a macro for retreiving the actual Softdevice size value from a given base address - use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/ -#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) - -/** @brief Defines a macro for retreiving the actual FWID value from a given base address - use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/ -#define SD_FWID_GET(baseaddr) ((*((uint32_t *) ((baseaddr) + SD_FWID_OFFSET))) & 0xFFFF) - - -/** @addtogroup NRF_SDM_ENUMS Enumerations - * @{ */ - -/**@brief nRF SoftDevice Manager API SVC numbers. */ -enum NRF_SD_SVCS -{ - SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ - SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ - SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ - SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ - SVC_SDM_LAST /**< Placeholder for last SDM SVC */ -}; - -/**@brief Possible lfclk oscillator sources. */ -enum NRF_CLOCK_LFCLKSRCS -{ - NRF_CLOCK_LFCLKSRC_SYNTH_250_PPM, /**< LFCLK Synthesized from HFCLK. */ - NRF_CLOCK_LFCLKSRC_XTAL_500_PPM, /**< LFCLK crystal oscillator 500 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_250_PPM, /**< LFCLK crystal oscillator 250 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_150_PPM, /**< LFCLK crystal oscillator 150 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_100_PPM, /**< LFCLK crystal oscillator 100 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_75_PPM, /**< LFCLK crystal oscillator 75 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, /**< LFCLK crystal oscillator 50 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_30_PPM, /**< LFCLK crystal oscillator 30 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, /**< LFCLK crystal oscillator 20 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION, /**< LFCLK RC oscillator, 250ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_500MS_CALIBRATION, /**< LFCLK RC oscillator, 500ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_1000MS_CALIBRATION, /**< LFCLK RC oscillator, 1000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_2000MS_CALIBRATION, /**< LFCLK RC oscillator, 2000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, /**< LFCLK RC oscillator, 4000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_8000MS_CALIBRATION, /**< LFCLK RC oscillator, 8000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_1000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 1000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_2000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 2000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_4000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 4000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_8000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 8000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_16000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 16000ms, if changed above a threshold, a calibration is done.*/ -}; - -/** @} */ - -/** @addtogroup NRF_SDM_TYPES Types - * @{ */ - -/**@brief Type representing lfclk oscillator source. */ -typedef uint32_t nrf_clock_lfclksrc_t; - - -/**@brief SoftDevice Assertion Handler type. - * - * When an unexpected error occurs within the SoftDevice it will call the SoftDevice assertion handler callback. - * The protocol stack will be in an undefined state when this happens and the only way to recover will be to - * perform a reset, using e.g. CMSIS NVIC_SystemReset(). - * - * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the SoftDevice assert callback. - * - * @param[in] pc The program counter of the failed assert. - * @param[in] line_number Line number where the assert failed. - * @param[in] file_name File name where the assert failed. - */ -typedef void (*softdevice_assertion_handler_t)(uint32_t pc, uint16_t line_number, const uint8_t * p_file_name); - -/** @} */ - -/** @addtogroup NRF_SDM_FUNCTIONS Functions - * @{ */ - -/**@brief Enables the SoftDevice and by extension the protocol stack. - * - * Idempotent function to enable the SoftDevice. - * - * @note Some care must be taken if a low frequency clock source is already running when calling this function: - * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new - * clock source will be started. - * - * @note This function has no effect when returning with an error. - * - * @post If return code is ::NRF_SUCCESS - * - SoC library and protocol stack APIs are made available. - * - A portion of RAM will be unavailable (see relevant SDS documentation). - * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). - * - Interrupts will not arrive from protected peripherals or interrupts. - * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the softdevice. - * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). - * - Chosen low frequency clock source will be running. - * - * @param clock_source Low frequency clock source and accuracy. (Note: In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock). - * @param assertion_handler Callback for SoftDevice assertions. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and assertion handler cannot be updated. - * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDeviceinterrupt is already enabled, or an enabled interrupt has an illegal priority level. - * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. - */ -SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lfclksrc_t clock_source, softdevice_assertion_handler_t assertion_handler)); - -/**@brief Disables the SoftDevice and by extension the protocol stack. - * - * Idempotent function to disable the SoftDevice. - * - * @post SoC library and protocol stack APIs are made unavailable. - * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). - * @post All peripherals used by the SoftDevice will be reset to default values. - * @post All of RAM become available. - * @post All interrupts are forwarded to the application. - * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); - -/**@brief Check if the SoftDevice is enabled. - * - * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); - -/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice - * - * This function is only intended to be called when a bootloader is enabled. - * - * @param[in] address The base address of the interrupt vector table for forwarded interrupts. - - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); - -/** @} */ - -#endif // NRF_SDM_H__ - -/** - @} -*/ diff --git a/components/softdevice/s110/headers/softdevice_assert.h b/components/softdevice/s110/headers/softdevice_assert.h deleted file mode 100644 index a2a8af8..0000000 --- a/components/softdevice/s110/headers/softdevice_assert.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** @brief Utilities for verifying program logic - */ - -#ifndef SOFTDEVICE_ASSERT_H_ -#define SOFTDEVICE_ASSERT_H_ - -#include - -/** @brief This function handles assertions. - * - * - * @note - * This function is called when an assertion has triggered. - * - * - * @param line_num The line number where the assertion is called - * @param file_name Pointer to the file name - */ -void assert_softdevice_callback(uint16_t line_num, const uint8_t *file_name); - - -/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ -/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \ -/** @brief Check intended for production code - * - * Check passes if "expr" evaluates to true. */ -#define ASSERT(expr) \ -if (expr) \ -{ \ -} \ -else \ -{ \ - assert_softdevice_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \ - /*lint -unreachable */ \ -} - -#endif /* SOFTDEVICE_ASSERT_H_ */ diff --git a/components/softdevice/s110/hex/s110_nrf51_8.0.0_softdevice.hex b/components/softdevice/s110/hex/s110_nrf51_8.0.0_softdevice.hex deleted file mode 100644 index 7551e41..0000000 --- a/components/softdevice/s110/hex/s110_nrf51_8.0.0_softdevice.hex +++ /dev/null @@ -1,5649 +0,0 @@ -:020000040000FA -:10000000C0070000D1060000D1000000B1060000CA -:1000100000000000000000000000000000000000E0 -:100020000000000000000000000000005107000078 -:100030000000000000000000DB000000E500000000 -:10004000EF000000F9000000030100000D010000B6 -:1000500017010000210100002B0100003501000004 -:100060003F01000049010000530100005D01000054 -:1000700067010000710100007B01000085010000A4 -:100080008F01000099010000A3010000AD010000F4 -:10009000B7010000C1010000CB010000D501000044 -:1000A000DF010000E9010000F3010000FD01000094 -:1000B00007020000110200001B02000025020000E0 -:1000C0001FB5C046C04600F0EFFA04B00FB41FBD24 -:1000D00008205A49096809580847382057490968CB -:1000E000095808473C2055490968095808474020E5 -:1000F0005249096809580847442050490968095875 -:10010000084748204D490968095808474C204B4981 -:10011000096809580847502048490968095808479C -:100120005420464909680958084758204349096836 -:10013000095808475C204149096809580847602068 -:100140003E4909680958084764203C49096809582C -:100150000847682039490968095808476C20374919 -:100160000968095808477020344909680958084740 -:100170007420324909680958084778202F490968CE -:10018000095808477C202D490968095808478020EC -:100190002A490968095808478420284909680958E4 -:1001A0000847882025490968095808478C202349B1 -:1001B00009680958084790202049096809580847E4 -:1001C00094201E4909680958084798201B49096866 -:1001D000095808479C201949096809580847A02070 -:1001E0001649096809580847A4201449096809589C -:1001F0000847A8201149096809580847AC200F4949 -:10020000096809580847B0200C4909680958084787 -:10021000B4200A49096809580847B82007490968FD -:1002200009580847BC2005490968095808470000D3 -:1002300003480449024A034B7047000000000020B5 -:10024000C0070000C00700000122D84B5A6000BF61 -:10025000D74A1268002AFBD0016000BFD44A126856 -:10026000002AFBD00022D14B5A6000BFD04A12684E -:10027000002AFBD07047F0B505460E46174600240D -:1002800006E0A200B158A2005019FFF7DDFF641C80 -:10029000BC42F6D30020F0BD0120C043C549086030 -:1002A000401048607047014601229204086890425D -:1002B00001D9102070470020FCE7F0B505460C4638 -:1002C0001646002706E028462168FFF7BDFF2D1DD2 -:1002D000241D7F1CB742F6D3F0BD70B505460C4611 -:1002E0002E460BE0304600F075F9FF2C01D80024B3 -:1002F00001E0FF3C013C012080023618002CF1D1C6 -:1003000070BD0146012292044868904201D909203B -:100310007047A9484069401C01D10F20F8E7002030 -:10032000F6E7FEB504462068030000F037FA05043E -:100330002B4249598B00201DFFF7E3FF0546002D96 -:1003400001D02846FEBDFFF7A7FF0120C00200F044 -:1003500041F9042221469948FFF78DFF002801D07A -:100360000320EFE708222146944800F06DF90028A9 -:1003700006D1002192480068FFF766FF00F00CF9F3 -:100380000320DFE7A768E6686068019031463846D9 -:10039000FFF7A3FF324638460199FFF78EFFB20000 -:1003A0003846019900F050F9002800D1CAE703202F -:1003B000C8E700F0E3F9834800688349086041E03A -:1003C00060680190E668A0680090B200009901980A -:1003D00000F03AF90746002F00D1B3E70E20B1E74D -:1003E000201DFFF760FF0546002D01D02846A9E734 -:1003F0006068002807D1FFF74FFF0320800200F05C -:10040000E9F800F0C9F8FFF747FF0120C00200F04B -:10041000E1F8042221466948FFF72DFF002801D0AA -:1004200003208FE708222146644800F00DF90028D8 -:1004300006D1002162480068FFF706FF00F0ACF823 -:1004400003207FE700BF00207CE770B505460C461F -:10045000182D04D12068FFF764FF206002E001201E -:10046000206000BF00BF70BDF0B589B05248406940 -:1004700003905248806881000398081802900398FE -:10048000000B01900121090302984018401E000B47 -:1004900000900124002520462946019A00F0C4F866 -:1004A0000022401E91410791069001260027304608 -:1004B0003946009A00F0B8F80022401E914105919B -:1004C0000490049BDB43059AD2430698184307998E -:1004D00011430791069037490698086007984860CD -:1004E00009B0F0BD70B53448446934488568466841 -:1004F000AA003146204600F0A7F8002801D00020CD -:1005000070BD0120FCE72D484068002801D0012083 -:1005100000E000200546FFF7E5FF002807D0FFF7C1 -:10052000BBFE0320800200F055F800F035F8FFF71D -:100530009BFF002D0ED020484669204884684768FC -:1005400021463046FFF7C9FE224639463046FFF7BE -:10055000B4FE00BF00F020F810B5184844681A48EF -:100560000460204600F0DCF810BD15480068006803 -:10057000401C01D100BFFEE710480068002802D0EF -:10058000042806D101E0FFF7BEFFFFF7E5FF00BF3B -:10059000FEE700BF00BFFEE7BFF34F8F0B480C49DB -:1005A000C860BFF34F8F00BFFEE7000000E50140C9 -:1005B00000E40140000600400010001000080000A8 -:1005C000B8070000BC070000000000200400FA0586 -:1005D00000ED00E010B50146104B1A6808460223F2 -:1005E0000F4C636000BF0F4B1B68002BFBD0531CEC -:1005F00004D0904202D20A4B186101E0084B986087 -:1006000000BF084B1B68002BFBD00023044C636029 -:1006100000BF044B1B68002BFBD010BD0010001066 -:1006200000E5014000E4014010B5202A04DB01464A -:10063000203A9140002010BD914020239C1A03468F -:10064000E3401943904010BD034610B50B439B0790 -:100650000FD1042A0DD308C810C9121FA342F8D025 -:1006600018BA21BA884201D9012010BD0020C04328 -:1006700010BD002A03D0D30703D0521C07E000208E -:1006800010BD03780C78401C491C1B1B07D1037854 -:100690000C78401C491C1B1B01D1921EF1D118463D -:1006A00010BD70477047704710B500F007F810BDD7 -:1006B000014B1B68DB6818470000002019481A49E5 -:1006C0007047FFF7FBFFFFF7FBFC00BD20BFFDE716 -:1006D0001649174C24688C420BD1164B1B68994263 -:1006E0000CD1154B154A1360186810498842EDD09B -:1006F0000AE0134880F30888124B18470F4A13602A -:1007000018680A498842E1D080F308880E49884277 -:1007100004DD0E48026802210A4302605B68184744 -:100720000346DFE7C0070000C0070000FFFFFFFF30 -:10073000000C000014100010001000000000002049 -:10074000000400206B05000000200020240500406C -:100750000D48704502D1EFF3098101E0EFF3088104 -:10076000886902380078182802D1C046074A104725 -:10077000074A12682C3212681047000000B5054B7A -:10078000054A9B58984700BDFDFFFFFF4B04000042 -:1007900000000020001000000400000030B4744687 -:1007A000641E2578641CAB4204D3635D5B00E318D0 -:1007B00030BC18471D46F8E7000C00000010000090 -:1010000000150020CD64010025220000336401009A -:1010100000000000000000000000000000000000D0 -:101020000000000000000000000000003D6501001D -:101030000000000000000000252200002522000022 -:10104000A9650100AF6501002522000025220000EE -:101050002522000025220000252200002522000074 -:10106000B56501002522000025220000BB650100B6 -:1010700025220000C1650100C7650100CD650100A2 -:101080002522000025220000252200002522000044 -:101090002522000025220000252200002522000034 -:1010A000D3650100D965010025220000252200003A -:1010B0002522000025220000252200002522000014 -:1010C00000F002F815F0E3F90CA030C80838241835 -:1010D0002D18A246671EAB4654465D46AC4201D170 -:1010E00015F0D5F97E460F3E0FCCB64601263342A9 -:1010F00000D0FB1AA246AB4633431847B456010052 -:10110000E4560100103A02D378C878C1FAD85207E1 -:1011100001D330C830C101D504680C6070470000AD -:101120000023002400250026103A01D378C1FBD803 -:10113000520700D330C100D50B6070471FB5C046C1 -:10114000C04615F063F904B00FB41FBDF0B44046BB -:10115000494652465B460FB402A0013001B506482D -:10116000004700BF01BC86460FBC804689469246B8 -:101170009B46F0BC70470000C11000008269024924 -:101180008161024810447047911100000100000085 -:1011900001B41EB400B50BF0E6FF01B40198864619 -:1011A00001BC01B01EBD0000401E00BF00BF00BF5B -:1011B00000BF00BF00BF00BF00BF00BF00BF00BF37 -:1011C00000BFF1D17047000070B505460C461646C9 -:1011D00002E00FCC0FC5103E102EFAD2082E02D31B -:1011E00003CC03C5083E042E07D301CC01C5361F2E -:1011F00003E021782970641C6D1C761EF9D270BD45 -:101200008307FF22DB0E9A408907090E99400028C8 -:101210000BDA0007000F0838830828489B001818CD -:10122000C36993430B43C3617047830824489B0001 -:101230001B181868904308431860704710B504469F -:1012400000210120FFF7DCFF00211820FFF7D8FF65 -:1012500000210B20FFF7D4FF02211920FFF7D0FF58 -:1012600002210D20FFF7CCFF02210E20FFF7C8FF5F -:1012700002210F20FFF7C4FF0221C81FFFF7C0FFA4 -:1012800003211620FFF7BCFF03211520FFF7B8FF4D -:10129000204600F019F8002010BD6421018070473D -:1012A00010B500F020F810BD0648704710B500F0EA -:1012B00022F810BD704770477047000000ED00E055 -:1012C00000E400E003F9004370B505462D4C07200B -:1012D0002070A01CFFF7E1FF5920A080294620467E -:1012E00000F099FB70BD10B500F09EFB2549002071 -:1012F000891E087010BDF8B5224E0446B61E30781F -:1013000001270D46002807D0204660380B2808D852 -:10131000204600F03DFF2BE0602CF9D01A48086011 -:10132000F8BD20466C38032803D8204600F071FF32 -:101330001EE0204670381F2803D8204600F045F9EB -:1013400016E0204690380F2803D8204600F0E8F831 -:101350000EE02046A0380F2803D8204600F074F88D -:1013600006E02046B0380F2804D8204600F0CAF91D -:10137000286000E02F60602CD2D128680028CFD1EF -:101380003770F8BD1A000020013000000120244908 -:10139000C003086023490020087007202249C005C7 -:1013A0008860704770B51F4D04462878A04207D06A -:1013B000002C05D0002803D01CA14D2015F033F8D7 -:1013C0002878A0420ED000211D4A17482C70002C0E -:1013D00019D01C4B012C06D0022C0BD013A1682075 -:1013E00015F021F870BD11600221116053610321D5 -:1013F000090605E011600321116053610121C9054F -:101400008160416070BD116011600721C905816074 -:1014100070BD10B505A1712015F005F810BD0000D4 -:1014200080E100E02000002000F501407372635C61 -:1014300068616C5F63636D5F6161722E63000000C1 -:1014400000F500404001002010B5A038030015F061 -:10145000DBF80B070E172028313A414B525C650030 -:101460004B6808788A68194603F0E6F910BD888849 -:101470008A6883B20888194680B203F0ECF910BD7F -:1014800008884C68CB688A6880B2214603F0E7F987 -:1014900010BD08884B688A6880B2194603F0FBF9D2 -:1014A00010BD88888A6883B20888194680B203F024 -:1014B00007FA10BD88888A6883B20888194680B206 -:1014C00003F041FA10BD08884A6880B2114603F063 -:1014D00080FA10BD088982B2888883B208881946CC -:1014E00080B203F081FA10BD08884A6880B21146C4 -:1014F00003F09EFA10BD08894C6882B20888CB6858 -:1015000080B2214603F018FB10BD08884C68CB68F8 -:101510008A6880B2214603F02AFC10BD012010BD6C -:1015200010B59038030015F06FF809060F161D244A -:101530002C363F464E0088888A6883B20888194650 -:1015400080B204F031F910BD08884A6880B21146B3 -:1015500004F065F910BD08884A6880B2114604F0AD -:101560006AF910BD08884A6880B2114604F070F923 -:1015700010BD08884B688A6880B2194604F07BF970 -:1015800010BD088982B2888883B20888194680B263 -:1015900004F07AF910BD08894B6882B208881946B0 -:1015A00080B204F090F910BD08884A6880B21146F4 -:1015B00004F09BF910BD888882B20888114680B279 -:1015C00004F0EFF910BD012010BD10B57038030014 -:1015D00015F01AF81B0F15192125282F363B40440A -:1015E000484C53585F688D707980888D8D8D8D8FB4 -:1015F00096004A680878114608F0FDFD10BD08689D -:1016000008F04AFE10BD0C790B7B8A6808682146F9 -:1016100008F053FE10BD086808F011FF10BD08F077 -:1016200065FB10BD08884A6880B2114609F043F88E -:1016300010BD0A790888114680B209F0D3F810BDB0 -:10164000087840B209F0DCF810BD088880B209F0D3 -:10165000F0F810BD086809F0FEF810BD086801F048 -:10166000D2FB10BD086801F0FCFB10BD088982B2F6 -:1016700009C9194609F007F910BD05C9114609F055 -:1016800051F910BD08884A6880B211460AF0A6F9DF -:1016900010BD0C790888CB688A6880B221460AF0B0 -:1016A000C5FA10BD0B7908888A6880B219460AF01D -:1016B0006DFC10BD08884C68CB688A6880B22146F2 -:1016C0000AF0D5FC10BD08884A6880B211460AF0BD -:1016D00018FD10BD0B7908880A7A80B2194609F006 -:1016E00044F910BD088880B209F044F910BD062005 -:1016F00010BD08884A6880B2114609F042F910BD51 -:10170000012010BD10B5B02805D0B12808D0B228EE -:101710000BD0012010BD088880B20BF0FBF810BD83 -:10172000088880B20BF015F910BD08884B688A68EC -:1017300080B219460BF01EF910BD000010B5030071 -:1017400014F062FF0A0609060C0C0F0F06060612BB -:1017500008F0F4FA10BD0AF0C5FE10BD01F03EFA23 -:1017600010BD06F09FFA10BDFAA1FE4814F05BFE12 -:1017700010BD3EB5FC49054603C900900191FF200C -:10178000C33069460881F94A092310460A212838DE -:101790000BF0BFFD0024F6480BF0D9FD641CE4B249 -:1017A0000A2CF8D3F14801231A4602A990300BF015 -:1017B000A0F9002804D0FF20E6A13D3014F033FE4C -:1017C000686800F024FC00211E22084604F06CF931 -:1017D00008F0C3FC02222421E64801F07DFBE54825 -:1017E00001222C214C3001F077FBE2490B20B0396B -:1017F00001F0FEF9002804D0FF20D6A1513014F0EA -:1018000012FE0AF03EFE02F097F96B460022082114 -:10181000D9A008F07DFB002804D0FF20CDA15730CF -:1018200014F001FE284602F0E7FC002804D0FF2057 -:10183000C8A1593014F0F7FDF3218900D14814F004 -:10184000D3FCD04801214171022181710721C1716E -:101850003EBD10B5CB4CA0780A2804D3FF20BDA113 -:10186000903014F0E0FD20786021484300190021F9 -:101870000173417BF722C908C900C91C1140EF223E -:10188000114041730121E1700C3010BD70B50E465E -:1018900000211C4619801546030014F0B5FE0723ED -:1018A000050B1711231D23002246294630460AF056 -:1018B00037FE70BD22462946304608F095F870BDC7 -:1018C00022462946304601F0E2FF70BD22462946F5 -:1018D000304603F0EAFD70BD22462946304600F04E -:1018E00010FC70BDFF209BA1EF3014F09CFD032085 -:1018F00070BD70B5A34CE078002818D02078602126 -:1019000048430019407B00254007400F0119087922 -:10191000401E08712078401CC0B220700A2800D1F7 -:101920002570A078401CA0700BF097FEE57070BD8C -:101930009448C079002800D08BE7704770B5914D6E -:10194000A86800280CD0FFF7F3FF002862D06022BF -:10195000A968FFF739FCFFF7CCFF0020A860EFE78C -:101960006879002856D0FFF774FF044681484C3050 -:1019700001F0C2FA6060002804D17A4875A14A30AB -:1019800014F051FD606801F01AFB00280DD02046CC -:1019900007F00BFF6078010703D5C008C000401CAA -:1019A0002BE0744861684C302DE0724861684C301F -:1019B00001F0ABFA00F05AFB00282BD1FFF749FFEA -:1019C00004466C4801F098FA6060002804D1332086 -:1019D00060A1000114F027FD606801F0F4FA00280E -:1019E00014D060680088608020460AF0CCFD6078E2 -:1019F000010706D5C008C000801C6070FFF779FFA2 -:101A00009EE75C48616801F080FA99E7594861688F -:101A100001F07BFA70BD10B55B4CE160A0605B48E3 -:101A200000F032FC607010BD57490020087070470C -:101A300070B5574E0546706A94B00C46401C04D1F0 -:101A4000B06AC0430004000C0BD0306AC007C00F5E -:101A50002870706A14F0DBFBB06A2071000A6071B4 -:101A600014E02B206946087009A9684601F07BFA4A -:101A7000002804D03B4837A17E3814F0D4FC012064 -:101A8000287006220AA9204614F04FFB2878002867 -:101A900003D06079C0210843607114B070BDF0B507 -:101AA0003B4C0646206895B00D4637460837401C2B -:101AB00008D16068401C05D1A068401C02D1E068D4 -:101AC000401C11D02068314614F0A1FB6068311D24 -:101AD00014F09DFBA068394614F099FBE06831468C -:101AE0000C3114F094FB25E02B206946087009A9FD -:101AF000684601F038FA002804D01A4815A1553874 -:101B000014F091FC08220AA9304614F00EFB2B2099 -:101B10006946087009A9684601F025FA002804D032 -:101B200010480CA14E3814F07EFC08220AA9384651 -:101B300014F0FBFA20692E460836401C08D1606973 -:101B4000401C05D1A069401C02D1E069401C33D083 -:101B500020691FE07372635C686F73745F636F72F8 -:101B6000652E6300C3020000F866010094010020A6 -:101B70003D170000640800206E524635313832327D -:101B800000000000E8030020240000203D190000B0 -:101B900080000010294614F03AFB6069291D14F0FA -:101BA00036FBA069314614F032FBE06929460C315E -:101BB00014F02DFB15B0F0BD2B246846047009A964 -:101BC00001F0D1F9002803D0F649F74814F02BFCB6 -:101BD000082209AF28460AA914F0A7FA684604703B -:101BE00009A901F0C0F9002804D0EF48ED49C01D53 -:101BF00014F019FC0822391D304614F096FAD9E782 -:101C000070B5EA4C0546A068002804D0E648E549CE -:101C1000563014F008FCA56070BD10B50146E448CC -:101C200001F073F9E1498879401CC0B2887101283C -:101C300003D1E048407800F04BFB10BD70B504467E -:101C4000DD4816460D46814204D1D748D549CB30F0 -:101C500014F0E9FB012E05D0D348D249DA3014F054 -:101C6000E2FB70BD6620207000202072A58101205B -:101C7000A07370BD70B515460C460646FFF758FEBA -:101C800000280CD066210170468001210172216874 -:101C90000161A18881820573FFF72BFE70BD1321BE -:101CA000304608F09FFD70BDC2494968884201D2A4 -:101CB00010207047072101700020704770B5BD4C9F -:101CC00005462078002694B0002801D00820E4E6DC -:101CD000BA4A6260954201D21020DEE668680028A8 -:101CE00009D00921D82804D3C31C9B089B00834238 -:101CF00005D00846D1E60720000268600EE0012109 -:101D000009074B6B896B4B43AD49511A0122591A94 -:101D1000D202891A814201D20421EAE700F050FF81 -:101D20006178A06806F052F8E068401E07280BD8DA -:101D3000302269460A708870684607F007F9002863 -:101D400002D009A806F07CFA2846FFF712FD012010 -:101D500020703046A1E6F8B5044696480F46406824 -:101D6000814208D3002C01D0844204D3E01C8008B7 -:101D70008000A04201D01020F8BD8C488178002955 -:101D800011D0398800914178602251430D18287B89 -:101D90000C350007000F3B4600222946FFF776FD71 -:101DA000060004D015E0002038800520F8BD002C86 -:101DB00013D039880098814201D90C260DE028788B -:101DC0003B460007000F22462946FFF75FFD06004D -:101DD00005D00C2E01D0002038803046F8BD734C61 -:101DE0006078401CC0B260700A2801D10020607089 -:101DF000A078401EA07068784107490F01290ED0D5 -:101E0000022906D003291AD066496E4814F00BFB4C -:101E1000E3E7C006E1D46868FFF7FFFEDDE764484A -:101E200069684C3001F071F86079401CC0B2607193 -:101E30000128D2D15F48407800F04AFACDE7E07936 -:101E4000401CE071C9E7604A10B5904209D3594A75 -:101E50000124A4045268A04201D3904201D39142CC -:101E600001D2102010BD00F0FCFE10BD564B10B585 -:101E7000994209D34F4B0124A4045B68A14201D3CA -:101E8000994201D39A4201D2102010BD022803D0FA -:101E9000102801D0092010BD00F009FF0028FAD059 -:101EA000052010BD484B10B598420DD3414B01247D -:101EB000A4045B68A04201D3984205D3994203D39E -:101EC000002A03D09A4201D2102010BD00F015FF65 -:101ED0000028FAD0072010BD10B50446354894B04C -:101EE0004068844202D2102014B010BD0F2008A90F -:101EF000087369460BA801F036F80028F4D168464B -:101F0000007A207068464089608068468089A08099 -:101F10000020E9E710B500290BD0264A526891420B -:101F200002D30B68934201D2102010BD8A88002A88 -:101F300002D001F05AFE10BD092010BD10B5224A92 -:101F400094B091420ED31B4A01239B0452689942DC -:101F500001D3914206D3441E1E2C41D8994203D38B -:101F6000914201D21020BFE7012837D10878002420 -:101F7000C007C00F002803D003206946887001E025 -:101F80006846847038206946087009A9684600F0E0 -:101F9000EAFF002804D041200CA1C00014F043FA4D -:101FA0002046A1E7541B000093020000E803002034 -:101FB0006408002024000020FFFF0000001900201A -:101FC000000000200A040000008001007372635CBE -:101FD000686F73745F636F72652E6300072083E719 -:101FE0000246203A1F2AF9D807F0F9FF7CE710B51E -:101FF0005F4A5268914201D2102010BD0246203A39 -:102000001F2A02D808F065F810BD072010BD70B572 -:102010000546584C0020207020464619544846601A -:10202000E01C80088000A04204D0FF2052491330F9 -:1020300014F0F9F901200007C06AC0430006000E41 -:1020400003D14E480068401C03D04D484D49301A1A -:10205000C862A8B20122214604F039F9002804D050 -:10206000FF204549233014F0DEF970BDF0B595B07E -:102070003B2008A9087369460BA800F074FF0028EC -:1020800004D0FF203C496B3014F0CDF93E4E0024C3 -:102090006D4630E02F19B87DC10706D0400704D443 -:1020A00060004019C0880AF08DFB3848807900280C -:1020B0001FD0B87D80071CD560004019C088002261 -:1020C00006210AF09CFB002813D03C2108A80173CC -:1020D00060004019C1886846C18569460BA800F0B8 -:1020E00042FF06000BD0FF2023497F3014F09BF9FC -:1020F00005E0641CE4B268460079A042CAD83046C4 -:1021000058E5F7B505460078002700090C463E461D -:10211000062804D0FF201849A83014F084F9287A42 -:1021200000280ED0012814D0FF201349C93014F024 -:102130007AF90298002C068001D027806680002062 -:10214000FEBD02270926002C0ED0A889A080A87BFE -:1021500008E003271426002C06D02869E060A88A2E -:102160002082287B2072E4E702980680E7E70000DF -:102170002400002000190020CC1F000000100010D7 -:10218000000000200005004004300000E8030020AB -:1021900010B56038030014F037FA0A060A0F131856 -:1021A0001F252930353A0868FFF788FD10BD05C99D -:1021B0001146FFF7D0FD10BD0868FFF775FD10BD93 -:1021C00005C91146FFF73FFE10BD4B6808788A68C5 -:1021D0001946FFF74BFE10BD8A6809C91946FFF77B -:1021E00061FE10BD0868FFF777FE10BD08884A68D9 -:1021F00080B21146FFF78EFE10BD05C91146FFF7EC -:102200009DFE10BD05C91146FFF7F1FE10BD01206E -:1022100010BD0120704700000E4A12680C498A4226 -:102220000AD118470B4A1268094B9A4204D101B5EA -:102230000AF090FF03BC8E46074909680958084711 -:1022400006480749054A064B704700000000000099 -:10225000BEBAFECA7800002004000020001500204D -:102260000015002001203F49400608603E490860F3 -:102270003E490A68FF231B029A4383121A430A60ED -:10228000384980390860704710B502460420384943 -:1022900004E0C3005B181B79002B0AD00346401EE4 -:1022A000C0B2002BF5D133A1432014F0BCF8FF20BD -:1022B00010BDC300CA50002259184A718A71012208 -:1022C0000A7110BD2A4A0021C000801801717047B0 -:1022D00010B50446042803D326A1522014F0A3F815 -:1022E0002348E1000C182079012803D021A15320B4 -:1022F00014F099F86079A179401CC0B2814200D0F5 -:1023000060710120174940068031086010BD70B52A -:10231000164804250068164E0004800F1B4C022846 -:102320001AD014A1692014F07EF815E02078C100BD -:1023300088190279012A07D1427983799A4203D018 -:1023400042798271705880472078401CC0B220705A -:10235000042801D30020207028466D1EEDB200280D -:10236000E4D170BD80E100E080E200E018E400E02C -:10237000E00800207372635C736F635F7369676E5C -:10238000616C6C696E672E630000000034000020F1 -:1023900010B5EFF31080C407E40F72B6D24841784D -:1023A000491C41704078012801D10BF07BF9002CC9 -:1023B00000D162B610BD70B5CB4CE07800280AD1D0 -:1023C0000125E570FFF7E4FF0BF074F9002804D055 -:1023D00000200BF047F9002070BDC44865714560CE -:1023E000F9E770B5EFF31080C507ED0F72B6BE4C7C -:1023F0006078002803D1BEA18F2014F014F8607813 -:10240000401E60706078002801D10BF04FF9002D5C -:1024100000D162B670BD10B5B348C178002904D0B0 -:1024200000214171C170FFF7DCFF002010BD10B525 -:1024300004460BF03FF9AC49C978084000D00120B0 -:102440002060002010BDF8B50246A74C0026A671FA -:102450000820042101251027130014F0D5F80D08D9 -:102460000A0C0E101214161E262123252800257191 -:1024700022E0022001E021711EE020711CE02771A2 -:102480001AE02020F9E7012616E0FFF781FF0BF0A4 -:1024900011F90028FBD002260EE02171A5710BE096 -:1024A0002771FBE7202000E040202071F6E7FF20A5 -:1024B0008FA1763013F0B7FF0BF008F9002809D090 -:1024C0000BF00AF9B04205D130460BF008F90028AC -:1024D000FAD02CE001208007C560894900224A60BB -:1024E000884A9661814B02225A608560864802695B -:1024F000D243D206D517026910231A4302610F4650 -:102500006D1C00E020BF78680028FBD030460BF03F -:10251000E6F80028FAD0002D04D17B48026910218A -:102520008A43026171490220886000207860A079A6 -:1025300000280CD00BF0BEF805460BF01BF8734AD0 -:10254000002D02D0A260E06001E0E260A060002EF9 -:1025500001D100F0A5F8F8BD10B504460BF0B0F8B5 -:10256000002805D060490120C8704A78521C4A7082 -:102570002046FFF768FF10BDF8B5614DA86800263A -:10258000012802D1AE600BF06DF86868012800D117 -:102590006E6028680127544C012812D12E606079A2 -:1025A000002803D000200BF05DF866712078002829 -:1025B00007D00BF07FF8002803D0012080070761C7 -:1025C000A770286901282AD12E6100F05FF8012048 -:1025D00080074761A079002815D00BF06BF80090B8 -:1025E0000AF0C8FF0099002901D0E16800E0A16865 -:1025F000411A022901DA8A1C11DC0099002901D054 -:10260000E06000E0A060FFF7C3FE0BF053F8002885 -:1026100004D0012080070761A77000E02770E868F8 -:10262000012812D100F032F800F030F800F02EF856 -:10263000A078002804D1FF202DA1033013F0F3FE71 -:10264000EE60A6702670FFF7CCFEF8BD10B5264CE4 -:10265000E078002801D10BF029F80120810788617A -:1026600000F014F8A07800280BD0254CE068002872 -:1026700003D10BF034F80028F8D10020E06000F01E -:1026800005F800201949C043886010BD08B55020E6 -:10269000694608806A461088411E1180FAD208BD3A -:1026A000F8B5124819278760154900200860C860EE -:1026B0000BF000F8BE0701240B4D002802D0346156 -:1026C000AC7000E02C70FFF763FE084847600D49CE -:1026D00028798863FFF7DAFFB461FFF7D7FF08496D -:1026E000002008617461F8BD38000020000300403C -:1026F0007372635C736F635F636C6F636B2E6300F5 -:10270000000100400005004000ED00E0FFFFFF7FFA -:102710008107C90E002808DA0007000F0838800872 -:102720002E4A80008018C06904E080082C4A80008E -:1027300080180068C8400006800F704710B50D2053 -:10274000FFF7E6FFC4B20420C043FFF7E1FFC0B2C9 -:10275000844203D023A11A2013F065FE26490120EC -:10276000486010BD0121254A48031060244B002217 -:102770001A60244A5160244A1060244A11601F499B -:1027800080390860704701211C4A480310601F4AC5 -:1027900051601B4A002111601B490860704710B549 -:1027A00017490868012804D00EA1572013F03BFEFA -:1027B00010BD114880680022C0B20A600AF020FCF7 -:1027C00010BD10B50E4801680029FCD0FFF7E7FFE7 -:1027D00001200D494003086010BD000000ED00E03D -:1027E00000E400E07372635C736F635F68616C5F49 -:1027F000726E672E6300000000D5004080E100E0AB -:1028000000D1004000D3004080E200E000D0004052 -:1028100030B40121BC48C9020160CD1005604A03F3 -:102820000260BA4803681B021B0A036004680023A5 -:10283000240A24020460B6480468240A24020460BE -:10284000B448012444608460B34C23606360A36097 -:10285000B24B19601D601A60B14B19601A600121FA -:10286000016030BC704710B40121A748CA02026061 -:102870000B0203600C060460A64841608160A94811 -:1028800041680029FCD1A4490020086048608860A4 -:10289000A24802600360046010BC704701219F4899 -:1028A000C9020160C91001607047002805D00128E5 -:1028B00005D0022805D19C4870479C4870479C4829 -:1028C000704710B59BA18B2013F0ADFD002010BD0B -:1028D00070B500219E4C9F4D9F4A8F4B002808D019 -:1028E00001281DD0022822D092A1B32013F09BFD15 -:1028F00070BD01200004A060A86011601960974BB2 -:10290000C2039A60964A90607F4A00121060954810 -:10291000016086480160944801609448017070BD70 -:1029200001204004A060A8605160596070BD012082 -:102930008004A060A8609160996070BDF8B594466D -:10294000834A8B4F834D00240126002808D001289C -:1029500032D0022840D077A1E82013F064FDF8BD02 -:10296000891E0902090A0120000490603C64686025 -:102970006C4A1164012B1DD000217C4A7D4B5170A3 -:102980006146DC63DE637C4B5C6002249C60042453 -:102990001C61744B3D31196073490E605F4B8915A2 -:1029A00019606F4B58605E4801606C49C005486013 -:1029B0001670F8BD0121E0E70120704E4004704F11 -:1029C000012B04D13464506068603964F8BD9060B4 -:1029D000346468603964F8BD01206A4E80046A4F2F -:1029E000012BF4D1EEE74F484068704770B54A4D6F -:1029F00028680026564C012806D1A068C00303D5DC -:102A000001200004A0602E606868012809D1A06838 -:102A1000800306D501204004A0606E6001200BF009 -:102A200041FEA868012809D1A068400306D501200D -:102A30008004A060AE6002200BF034FE70BD10B5C3 -:102A40004A490878002818D00120444AC0079060FD -:102A5000434AC00B90602C4A00121060414A00208B -:102A60001060324A1060404A106008704A78002AAC -:102A700002D048700BF016FE10BD0320FAE70120CB -:102A8000424900060860704701202449000608609A -:102A9000704701203D4940050860704701201F49EB -:102AA00040050860704733490020C86388151B49FA -:102AB00008607047410A364AC005C00D5043801C6B -:102AC0005143400A0818704710B4324C430B63431B -:102AD0001B0C5C020C602E4C6343C31A2E485C0234 -:102AE00058432B4B400D4343E31A0124DB032404DA -:102AF0001B191B1613700A681018086010BC704769 -:102B000010B50BF0A2FE10BD80E100E008E400E08B -:102B100018E400E000B0004040B1004080E200E076 -:102B200000E100E000B5004048B1004040810040B5 -:102B300044B100407372635C72656D5F68616C5F85 -:102B40006576656E745F74696D65722E6300000052 -:102B500000B3004040B3004040B5004000F50140E4 -:102B60000083004040850040008200404800002073 -:102B700000B10040C08F00400085004004B100401B -:102B800004B5004008B1004008B5004000E200E094 -:102B9000093D0000378600006F0C010010B50BF0F6 -:102BA00040FE10BD00200449C8630120012181407E -:102BB000024A116000BF7047C01F004080E200E081 -:102BC00010B50CF097FA0AF059F9FEF7DFFB12F096 -:102BD00063FA0CF0F5FF0CF081FF10BD70B50C46E8 -:102BE000054603F0D5FA214628460EF026F870BDBA -:102BF00070B50D46040012D0002D10D021012846DA -:102C000013F0F0FA10225449284613F08EFA524875 -:102C100001210838018044804560002070BD0120FA -:102C200070BD70B54C4E00240546083E11E0716839 -:102C300020014018817BAA7B914209D1C17BEA7BAC -:102C4000914205D10C22294613F042FA002806D001 -:102C5000641C30888442EADB0020C04370BD2046FB -:102C600070BD70B50D4606000AD0002D08D03A4C54 -:102C7000083C20886188401C884203D9042070BD2C -:102C8000102070BD3046FFF7CCFF002801DB401C50 -:102C90000AE020886168000140181022314613F0D4 -:102CA00044FA2088401C20802870002070BD70B538 -:102CB00014460D001FD0002C1DD00021A170022849 -:102CC00002D0102817D108E068782978000208435C -:102CD00011D00121A17010800BE02846FFF7A1FF61 -:102CE000002808DB401CA070687B297B0002084399 -:102CF0002080002070BD012070BD70B505461446CF -:102D00000E000AD000203070A878012807D004D91E -:102D1000114908390A8890420BD9012070BD002C56 -:102D200004D0287820702888000A5070022008708B -:102D300010E0002C0CD049680001411810222046F8 -:102D4000103913F0F2F9287820732888000A60738C -:102D500010203070002070BD540000205A4910B57A -:102D6000884207D301218904884205D3574909685D -:102D7000884201D2102010BD0146012006F0E4FA7D -:102D800010BD30B5044693B000200D4607901421C5 -:102D90000BA813F029FA1C21684613F025FA6A469D -:102DA000112010770020507710780221084310700E -:102DB00007A80C90012008AA907245486A46108521 -:102DC0000AA80B902088108460885084A088908482 -:102DD000E088D084907FF9210840801C40084000A2 -:102DE000907708209086108708A80F9010AA0BA94A -:102DF000684600F083FF002803D110A800882880CF -:102E0000002013B030BD3EB5044608206946088056 -:102E10002D48844207D301208004844205D32B48E7 -:102E20000068844201D210203EBD2146012006F0F8 -:102E30008BFA0028F8D12088694688806088C8808D -:102E4000A0880881E088488107F05FF801AB6A46F6 -:102E5000002101F0E1FB694609880829E4D003203C -:102E60003EBD1FB504460020029008206946088137 -:102E700015480391844207D301208004844206D37D -:102E800012480068844202D2102004B010BD07F03E -:102E90003CF8014602AA0F4801F055FD0028F4D184 -:102EA00069460989082901D00320EEE769460988A7 -:102EB000218069464988618069468988A180694680 -:102EC000C988E180E1E700000080010028000020BF -:102ED000042A0000FFFF000010B5031D036000205E -:102EE000521E04E05C181C60401C2346C0B2904295 -:102EF000F8DB0020186010BD01460A680020002A97 -:102F000002D0104612680A60704702680A600160C9 -:102F10007047000000B51E2823D00BDC0C281CD005 -:102F20001FDC030013F070FB090F1D111D1D171787 -:102F300013151D00302814DD3A38030013F064FB2C -:102F4000030F11091100002000BD214800BD04201D -:102F500000BD0D2000BD0F2000BD082000BD1120C8 -:102F600000BD032000BD10B50C4605F0EFFF0028A2 -:102F70001ED0204605F064F9002816D022780E2ACB -:102F80000DD00F2A0BD0022A09D0032A07D0102A0D -:102F900009D010A17C2013F046FA002010BDA078C3 -:102FA000FFF7B8FF10BD112010BD0AA18220F2E783 -:102FB00008A18820EFE710B504F083FF10BD10B51D -:102FC00005F03EF910BD10B504F0D9FF10BD0000AA -:102FD000023000007372635C686F73745F686369CA -:102FE0002E63000070477047704770477047704706 -:102FF00070477047704770477047704770470000D0 -:1030000010FFFFFFDBE5B151008001006400FFFF0E -:1030100003B40148019001BD09000020002803D03D -:103020008178012939D101E0102070470188FE4ADA -:10303000881A914233D01BDCFC4A881A91422ED068 -:103040000BDC00292BD00320C002081A27D001284E -:1030500025D001210903401A07E001281FD00228CA -:103060001DD0FF281BD0FF380138002815D116E0ED -:10307000FF220132811A904211D008DC01280ED0C3 -:1030800002280CD0FE280AD0FF2806D107E001292B -:1030900005D0022903D0032901D0002070470F205A -:1030A000704700B50B2826D009DC030013F0ACFAFA -:1030B0000B1D2125251B25292325271F1B00112832 -:1030C0001BD008DC0C2816D00D281CD00F2814D0DB -:1030D000102808D10FE0822809D084280FD0852835 -:1030E0000FD0872811D0032000BD002000BD05208F -:1030F00000BDCF4800BD072000BD0F2000BD04204B -:1031000000BD062000BD0C2000BD0D20800200BDCA -:1031100070B500290BD0CB1FFA3B81241E46CDB2DF -:10312000112B1BD2012805D0022806D009E000206F -:1031300010701DE0FF20043001E0FF2003308142C9 -:1031400018D0330013F060FA111613131613161665 -:103150001316161613131313161316000846FF380A -:1031600081381F2803D9FF39FE39022902D815708A -:10317000002070BD1470072070BD00B5030013F06F -:1031800043FA060406040C080A0C002000BD1120B6 -:1031900000BD072000BD082000BD032000BD007851 -:1031A0000207120F04D0012A05D0022A0AD10EE02C -:1031B000000907D108E00009012805D0022803D042 -:1031C000032801D0072070470870002070470620B0 -:1031D0007047002807D0012807D0022807D003280D -:1031E00007D007207047002004E0112002E02120D2 -:1031F00000E0312008700020704738B50C4605000B -:103200004FD06946FFF7CBFF002822D12088032149 -:1032100089028843694609788907090D0843208097 -:103220006946681CFFF7BBFF002812D121880320E4 -:1032300000038143684600788007800C01432180A9 -:10324000A8784007820F2020012A03D0022A03D049 -:10325000072038BD814300E00143218088B2010589 -:10326000890F08D0012189038843A9780907C90F6C -:1032700089030843208080B28104890F0AD0A9788D -:103280004004C906C90F400CC903084320808004CC -:10329000800F02D12088400403D5208840210843B4 -:1032A0002080002038BD70B50446002008801546F7 -:1032B0006068FFF7A2FF002815D12189A08981420B -:1032C00010D861688978C90708D00121490288426D -:1032D00008D8491C12F0A3FF298009E0FF21FF3123 -:1032E000884201D90C2070BDFF30FF3003302880A8 -:1032F000002070BD10B5137804785B08E4075B000C -:10330000E40F23431370FD2423400478A407E40F43 -:10331000640023431370FB24234004786407E40F04 -:10332000A40023431370F724234004782407E40FF8 -:10333000E40023431370EF2423400478E406E40FF1 -:10334000240123431370DF2423400478A406E40FF0 -:103350006401234313700078BF244006C00F23404C -:10336000800103431370002906D00878C10701D1FA -:10337000800701D5012000E00020C0015906490E58 -:103380000843107010BD30B50A8803239B020488DF -:103390009A4323059D0F02D1A3049C0F01D09B0FDC -:1033A00000E001239B021A4303230A801B039A4374 -:1033B00003889804840F02D11805830F01D0800F71 -:1033C00000E00120000302430A8030BDF3B593B052 -:1033D0000D000FD0139800280FD01221284612F0AC -:1033E00001FF03AAFF21012003F0E7F8002426468D -:1033F00037467AE0102015B0F0BD0720FBE768469D -:10340000807D01280BD16846818A0520C002081AF8 -:1034100010D0012810D0022812D0032812D0042C7A -:1034200014D0052C15D113E002290000012800005A -:1034300003300000012400E002246846468A08E0C8 -:10344000032406E068460424478A02E0052400E0DD -:1034500006246846418A1398814246D12C74002E76 -:1034600041D00DAA0EA905200292019100901023CF -:103470000022FF21304603F041F9002823D168469D -:10348000808E2A46C0B20EA9FFF711FC00281AD17F -:10349000AE81002F27D00DA9052008AE0291009023 -:1034A000132300220196FF21384603F027F9002854 -:1034B00009D16846808EF11CC01EC0B22A1DFFF7DC -:1034C000F6FB002801D0032095E708A88178427810 -:1034D00008021043E881062C05D16846807DA87259 -:1034E0006846808A2881002085E703A803F06EF8EB -:1034F000002884D0FFF7D5FD7DE7002805D0F94AE4 -:10350000012903D0022903D003207047518800E02D -:103510009188814201D1002070470720704770B523 -:103520000C4605461C21204612F05CFE002020803F -:10353000002D08D0012D04D0EBA1F04812F073FF4C -:1035400070BD062000E00520A07070BD70B592B07F -:103550001546064601206A461071107453740846D9 -:1035600008300395029048889082FEF7E1F9040044 -:1035700019D06580172069468883203600940AABED -:103580007178023307AA01A80DF05FF9064660784A -:10359000000701D5FEF7ADF9002E0AD03046FFF73F -:1035A000ECFD12B070BD1321284607F01BF9032073 -:1035B000F7E708A800906846838B0422012128467B -:1035C00008F035FEEDE770B506468AB000200D46DE -:1035D00007900590069003A90490052402460291E5 -:1035E0000190102300942946304603F087F8002804 -:1035F0000DD108A804A9009102900194684683891E -:1036000000222946304602F095FE002801D0FFF73F -:1036100048FD0AB070BD10B50DF01DFB10BDF0B532 -:1036200089B000260546059600780C460827030059 -:1036300012F0EAFF0CFD070C3A0B77779EC2FCD81C -:10364000E8FD68680A38FEF7E8FA0DE1A88800236B -:1036500080B201220321009009F08CFA0290002C24 -:1036600004D0A648A0A16E3012F0DDFE029800281A -:1036700004D1A2489CA16F3012F0D5FE02980099A7 -:1036800008300CF017FDFEF753F9040007D06078FE -:103690003843607000986080FEF72BF9E6E0132154 -:1036A000009807F09FF8EFE0002C04D1BD208EA118 -:1036B000800012F0B8FE608800230122032109F087 -:1036C00059FA0090002804D18C4887A1883012F064 -:1036D000AAFE0099002008802A7994461EE0C300C3 -:1036E0005B199B6807936B469B8B1A0708D5DA0614 -:1036F00006D56046C20050194038C08F088006E0E9 -:103700005B0409D50871C2005019C08848806078F0 -:10371000384360700226A7E0401CC0B28445DED862 -:10372000A2E0E888694608800090002C04D1734824 -:103730006DA1983012F077FE2878062814D10098F1 -:10374000C00B11D0608800230122032109F012FA76 -:10375000060004D1694864A1A23012F064FE002082 -:103760003071A88870803BE06078384360707BE0FF -:10377000002C04D161485CA1B43012F054FE608882 -:1037800000230122032109F0F5F90090002804D15B -:103790005A4855A1B73012F046FE009808300DF097 -:1037A000ACFA0121484002D1E888C00B5CD00098F7 -:1037B00061880226C180D7E7002C04D14F484AA176 -:1037C000D03012F030FE608800230122032109F07E -:1037D000D1F9002804D1494843A1D33012F023FE87 -:1037E0000226C1E7002C04D144483FA1DC3012F08E -:1037F0001AFE0226618801222046FEF71FFA0120E8 -:103800000590B1E7A889002380B20122032100902E -:1038100009F0B0F90746002C04D0384832A1EE3048 -:1038200012F001FE002F07D12FA101E00FE016E0FA -:103830003248EF3012F0F7FD686802902889694637 -:103840008881012202A90098FEF714FA0CE0002CEE -:103850008AD16D2024A1C00012F0E5FD84E727483D -:1038600021A1FE3012F0DFFD002C0DD060780007A2 -:103870000AD50598002807D18420207020465822B8 -:1038800029460830FDF7A0FC304609B0F0BDF7B579 -:103890000C460546007A224688B00A320292921CF3 -:1038A00004920027811E16323E4601920B0012F050 -:1038B000ABFE08F605F548488DD1F4F5688800237D -:1038C0000122032109F056F90190002803D106A135 -:1038D0000B4812F0A8FD01980088002812D052274A -:1038E000072601E1000900207372635C676174744C -:1038F000735F636F72652E63000000006F0200004B -:103900008603000051271E26002C7DD06888A080E9 -:103910000120A071019802990079C0004019C08966 -:10392000FFF754FD002870D101980079C0004019BC -:10393000C089208101980079C0004019408AA08385 -:10394000F2E0698A0091062820D1E889C00B1DD0D9 -:1039500008462230512786B2002CD6D0A889049977 -:10396000FFF734FD002873D16888A0800220A07181 -:10397000A88920810120A072288AE08300982084F1 -:103980006969009A019812F0D0FBCDE0084620301A -:10399000502786B2002CB8D0A8890299FFF716FDEF -:1039A000002855D16888A080A889E080287A062858 -:1039B0000AD002202072288AA0830098E083204643 -:1039C00069692030009ADEE70120F3E76888002368 -:1039D0000122032109F0CEF80690688A009006982B -:1039E000002803D1FD49FE4812F01DFD069808305D -:1039F0000DF083F90121484002D1E889C00B26D09F -:103A00000098223086B201E073E021E05127002CBB -:103A100079D06888A080A8890499FFF7D7FC00288E -:103A200016D10220A071A88920810420A072288AC2 -:103A3000E083009820846969009A019812F075FB70 -:103A40000699002008710698A98941806CE003203E -:103A50000BB0F0BD688805F0D2FB019068880023A8 -:103A60000122032109F086F800900198002804D172 -:103A7000DB48DA492C3012F0D6FC0098002804D13B -:103A8000D748D6492D3012F0CEFC0098D549C088D1 -:103A9000884205D05127222604E01EE03FE035E0B1 -:103AA00050272026002C2ED06888A080502F07D0C9 -:103AB0000220A0712146287B0831FFF730FD33E05A -:103AC000287BA11DFFF72BFD6A8800230099019830 -:103AD000FFF73CFD0028BBD126E0C349A889C9886F -:103AE000814207D154270626002C0CD06888A0807C -:103AF0001AE008E053270826002C04D06888A0802C -:103B0000A889E08010E00A98068013E05527072670 -:103B1000002CF8D0A889A0800020A07104E08D209E -:103B2000AE49C00012F07FFC0A98002C068001D03C -:103B30002780668000208BE7AB4900200870704723 -:103B400030B585B00C4601F0E0F90546FF2804D1F8 -:103B5000A348A249953012F066FC00202080207115 -:103B60006080401EE0802046294608300CF096FA1E -:103B70006A462946012002F020FD102412E0684622 -:103B8000808800070ED56846C0882946FFF71BFDD0 -:103B900068468188FF2321438180C0882946019A95 -:103BA00002F036FE684602F011FD0028E7D005B0AD -:103BB00030BD0A46014610B5104608300CF082FAB6 -:103BC00010BD70B5002305461A46032108F0D2FF48 -:103BD000040004D182488149B73012F024FC204609 -:103BE000294608300CF066FA70BDF0B591B00C466D -:103BF000074605F004FB050005D02878222804D2EA -:103C0000082011B0F0BD7948FBE700231A460321D4 -:103C1000384608F0AFFF0646002C02D0A0880028E6 -:103C20000CD00120694608710220087400204874F5 -:103C3000002C05D0A0880883206802E00920E0E776 -:103C4000088305903046083003970290FDF770FE18 -:103C5000040018D0678017206946888320350094B7 -:103C60000AAB6978023307AA01A80CF0EEFD0546FD -:103C70006078000701D5FDF73CFE002D09D02846ED -:103C8000FFF77BFABDE71321384606F0ABFD0320B2 -:103C9000B7E708A800906846838B042201213846C4 -:103CA00008F0C5FA0021C943F180AAE7FFB585B045 -:103CB0000E9E7788384605F0A2FA054600231A467C -:103CC0000321384608F056FF0446002D03D143492E -:103CD000474812F0A8FB002C04D145483F49401C3E -:103CE00012F0A1FB0834089869460394C1C105A8E5 -:103CF0000DC8203569780CF017FAC6E5F0B5044612 -:103D0000002099B00D4601460D9010A881811646FD -:103D100001818180344A68469180018510A8018024 -:103D200068460187818581841078012808D002289F -:103D300006D0032804D0042802D0082019B0F0BD12 -:103D40002C4A944273D32C4F0121890438688C4249 -:103D500001D3844278D3274A954275D3012189043F -:103D60008D4201D385426FD36168002913D0214A67 -:103D7000914269D301229204914201D3814263D3DB -:103D800060892189884203D801225202914201D9D7 -:103D90000C20D3E70D9016AA0EA92846FFF783FA48 -:103DA0000028CBD1686880784007800F02280AD1AC -:103DB0006846008F8004800F05D02869002802D053 -:103DC0003968884240D30AA92069FFF716FA00280B -:103DD000B4D1206900281CD060780FE0E8380000DA -:103DE000EE030000FFFF0000000900200230000089 -:103DF0000C050000008001002800002080076846B4 -:103E0000008D03D58004800F68D002E08004800F0D -:103E100064D16846008D810618D58004800F6068E3 -:103E200006D0002812D0396888420DD302E00BE09A -:103E300000280BD0FE49884206D30121890488421C -:103E400004D33968884201D2102077E709A9606954 -:103E5000FFF7D3F900289CD16069002808D0684694 -:103E6000808C0105890F012938D18004800F35D05D -:103E70000BA9A069FFF7C1F900288AD16846808C98 -:103E800080062BD46846808D810627D4A16900293D -:103E900006D00105890F012920D18004800F1DD093 -:103EA000E068002804D00078002817D01C2815D21C -:103EB00004AA611C2046FFF71DFA0121890210A8FF -:103EC0000180012768468773DA49818104AA033299 -:103ED00017A92868FEF711FF002801D007202DE759 -:103EE00010A8007F15A9C01CC2B200200C9201903E -:103EF000FF32009003460291FF3203A8033210996B -:103F000002F0B3FA002826D110A9888A0F902A89D6 -:103F10002969C94801910092029010A90A8B6B8906 -:103F200028680E9902F0A1FA01007DD1C24800254F -:103F3000001F818868464174090A8174052104A81C -:103F40006A4623C210A82A46FF21808A0C9B02F0F1 -:103F5000F1F9002802D0FFF7A4F8EFE66846007CEC -:103F60000322C1090020920290430122920280188C -:103F70001490002928D0014610A801806846292104 -:103F8000877309028181058608A8007C0023410807 -:103F900060784900C007C00F014308A80174FD20E4 -:103FA00001406078A54A8007C00F4000014308A87F -:103FB00001740CA9022001910090029503A81099A8 -:103FC00002F053FA01002FD16068002828D0206940 -:103FD00000280DD10AA90EA8FFF7D5F9607880074F -:103FE00006D46946088D032109038843694608857C -:103FF000904968468773FE31818190492089891EE6 -:1040000012F00DF962680D9811AB019200900293C5 -:104010000A46002303A80A9902F027FA010003D1F7 -:104020002078C10603D400E086E080062AD56846E1 -:104030000586606900280DD109A90EA8FFF7A3F92C -:104040006846818C03208002814301208002091888 -:10405000684681846946888CC821084369468884FB -:1040600074488F73FF30888112AA0CA90220029233 -:10407000019100900023714A03A8099902F0F5F913 -:10408000010059D12078C00729D068460586A0696B -:1040900000280DD10BA90EA8FFF775F96846818D90 -:1040A000032080028143012080020918684681852F -:1040B0006846818D40200143684681858773604949 -:1040C000818113AA0CA90220029201910090002381 -:1040D0005A4A03A80B9902F0C8F901002CD1E068F4 -:1040E00000282DD010A8149901805549684687737F -:1040F000491C8181E16808A80A78027449784174F2 -:10410000E0684122418868464186E06800230179E1 -:1041100008A80175E068D200C18808A84175090A9D -:1041200081750CA8072101900091029503A81099B0 -:1041300002F09BF9010003D00F9800F0EAFEFDE5C4 -:104140003D480321001F0170002E0AD08088308076 -:1041500010A88088708010A80089B08010A880897D -:10416000F0800020EAE530B501248BB015460B46FF -:10417000012802D002281CD104E06846052184737E -:10418000C90203E02B4968468473891E8181002B94 -:1041900012D003210020890288430121890240189E -:1041A0006946888405AA04A91846FEF7A6FD0028DA -:1041B00004D007200BB030BD1020FBE76A46127C0C -:1041C0001D480092801E05A9FF3201910290FF3226 -:1041D000002303A80332099902F047F9002802D00E -:1041E000FEF75FFFE6E71448001F002D01D041886D -:1041F000298004700020DDE770B592B004460126E6 -:1042000008A886700F496846018410AA08A930469C -:10421000FFF7A9FF00284DD12078074DC0070024E3 -:104220002D1F002848D01C21684611F0DDFF0BE04F -:1042300000800100032800000409002003020000A0 -:10424000032900000118000068460178202001437E -:104250006846017008A88670F9496846018411947F -:104260000794817FF92001406846891C81770020EE -:1042700001466846017700200146684641770421DF -:104280008185C485018607A80A9011A80D9008A809 -:1042900009900EAA09A96846FFF730FD002809D148 -:1042A0006846008FE8806846808F2881401C6881BE -:1042B0002C70002012B070BDEC802C8110A80088FA -:1042C000F4E7F7B5DF4900260A789EB0012A04D04A -:1042D000022A02D0082021B0F0BD4A88824201D0D3 -:1042E0000620F8E71F98824201D10720F3E7012258 -:1042F00010A98A75D4488882002003239B020146B6 -:1043000099439302CB1810A90B8669468A81CF4A3C -:10431000CA8118A9887110A9888419A904916946CD -:10432000CA820690FF20087503A802F072F90024E3 -:104330002546274608AA052103A802F06DF90028A2 -:1043400010D082286FD1002C6FD0002D6DD010A816 -:104350008480C5800021017418A8807B11AC0128DD -:1043600065D06DE008A88079002F21D0012857D1B1 -:104370006846818CB44881421CD113AA0DA905203E -:104380006B4607C36846408C10230022FF2102F0D1 -:10439000B5F9002868D110A88089042801D0062822 -:1043A0004CD16846818E1F98814239D10F2092E707 -:1043B000012835D16846808C0521C902884202D087 -:1043C000491C88422CD19F4841886846408C8142D4 -:1043D00001D1012700E00027002C01D0002D10D0D2 -:1043E0001F9988421CD113AB0DAA05216E460EC63B -:1043F000044610230022FF2102F080F9002833D167 -:1044000001E035460CE010A88089022801D0102870 -:1044100014D1C0B21BAA0DA9FEF749FC00280DD18A -:104420006846468C86E71FE0FFE7052053E714A99E -:104430001BA8221DFEF761FC002801D003204AE7DB -:1044400010A8007C0023001DC2B210A8027420989E -:1044500002900194009215A81C9902F006F8002819 -:1044600002D1784902220A70FEF71BFE33E710B52D -:104470000B46401E86B084B203AA00211846FEF700 -:1044800039FF04AA052103A802920191009001239B -:104490000022FF21204601F04DFF04466846008AB5 -:1044A000012804D06D206A49000111F0BCFF2046AC -:1044B000FEF7F7FD06B010BDF0B5624F0446387840 -:1044C00087B00E46032804D0042802D0082007B085 -:1044D000F0BD04AA03A92046FEF7E5FE0500F6D1CB -:1044E000606880784007800F02280DD16846808977 -:1044F0008004800F08D02069002805D0554909683C -:10450000884201D21020E2E7208905AA6B46216982 -:1045100007C369460A8A63892068039901F0A5FFE9 -:10452000002802D0FEF7BDFDD1E7002E02D068467C -:10453000808A3080042038702846C8E738B50C00DF -:10454000054609D000236A46FF2102F039F9002808 -:1045500004D0FEF7A6FD38BD102038BD69462046C0 -:10456000FEF74BFE0028F8D1A078FF21C307DB0F30 -:104570002846009A02F04CF9EBE73EB50C0009D052 -:1045800002AB6A46FF2102F01BF9002804D0FEF7B7 -:1045900088FD3EBD10203EBD0321204611F022FEC5 -:1045A0006846008801A90005800FFEF712FE00286A -:1045B0000BD16846007920706846008801A9800404 -:1045C000800FFEF706FE002801D003203EBD68469E -:1045D00000796070A278EF20024068460088C10B25 -:1045E00009010A43F7210A404104C90FC9000A43DF -:1045F000A270F9210A40800601D5022000E00120C6 -:10460000400069460243097A50084000C907C90FB3 -:104610000843A07000203EBD7FB5144605220192DC -:1046200003AD029500930A462388FF2101F082FE24 -:10463000694689892180FEF734FD04B070BD000011 -:10464000052A00000009002002280000FFFF0000EA -:10465000E838000028000020F3B5002799B068462C -:104660000C4607873D4600291ED0E068002806D08A -:10467000A068002818D001886A4611870780199819 -:1046800004F0BDFD002812D0007822287ED31998AE -:1046900000F03BFC002300901A460321199808F013 -:1046A00069FA060009D104E010201BB0F0BDFD48F6 -:1046B000FBE7FD49FD4811F0B6FEA078012803D0C4 -:1046C000022801D00720F0E72088002808D0401EEB -:1046D00080B203AA009901F070FF002859D11DE0B3 -:1046E000F048401CE1E76946498A228891420BD292 -:1046F0006846807D0025012810D16846808AEC49F3 -:1047000088420BD1012509E0914203D1002D2AD026 -:104710006D1C01E0022D0BD0032D04D203A801F083 -:1047200055FF0028DFD082281BD0002831D11DE0A2 -:104730006946897D0129F1D16946DD4B8A8A5B1E74 -:10474000D11A9A420FD005DCDA48101A0BD0012892 -:10475000E4D108E0012906D0FF390129DED1032583 -:10476000E1E7022D15D10D2080029EE7E0680028C8 -:1047700016D00EA9052202910192009069460B8F76 -:10478000A2882088FF2101F0D5FD00E01EE000286E -:1047900002D0FEF786FC88E76846A168008F088093 -:1047A0006846008AC00601D5C3487EE707980028FE -:1047B00003D06846008B022801D0032075E70798D4 -:1047C000A1780078012903D0800710D408206CE775 -:1047D000C007FBD000220721199808F010F8002824 -:1047E00002D00725022004E0AE48801C5DE70225C8 -:1047F000032008A908702188684681851998083621 -:104800000A90099617216846818712AB02330FAAD6 -:10481000052108A800970CF018F8002802D0FEF730 -:10482000ACFC42E710A800906846838F042229461A -:10483000199807F0FCFC38E770B5064615460C469B -:104840000846FEF7EBFB002804D12A4621463046F5 -:10485000FFF789FCF2E610B5FFF733FD10BD70B528 -:104860001E4614460D0014D0002C12D06168002999 -:104870000FD00121FEF741FE002809D12068FEF784 -:10488000CDFB002804D1324621462846FFF736FAF0 -:10489000D4E61020D2E670B515460C000ED00221E9 -:1048A000FEF72BFE002808D12068FEF7B7FB002892 -:1048B00003D129462046FFF7FFFDBFE61020BDE6E5 -:1048C000F8B506467D480D46016814468A4231D344 -:1048D0006068002808D07A4A90422BD301229204C3 -:1048E000904201D3884225D37648864204D0304690 -:1048F00004F085FC00280CD0304600F006FB06468C -:10490000284600F0BFFA002804D16068002802D0D1 -:1049100012E06448F8BD00236A463146284601F09B -:104920004FFF002802D0FEF7BCFBF8BD68460088A8 -:10493000800601D41020F8BD6188224628466368AD -:10494000FFF76AFEF8BDF7B55C4E0746306886B0E3 -:104950001446824202D2102009B0F0BD384600F061 -:10496000D4FA05465748874201D0FF2D08D00023CE -:1049700004AA2946079801F023FF002826D101E068 -:104980004848E9E76846008AC00601D54A48E3E797 -:1049900003A9002002910527019000976288494BE6 -:1049A0002946079801F0AAFE00280FD161683268F5 -:1049B000914208D30191029000972388628829468A -:1049C000079801F09BFE694689892180FEF769FB03 -:1049D000C2E7002907D03C4B0A881B899A4202D8BB -:1049E0003048401C704737E610B586B004236C464B -:1049F000A382354BDC88002C07D01B898B4201D267 -:104A0000914204D92748401C54E5062052E56B46E4 -:104A100019825A820021009101911C800221997013 -:104A200005A9029104A903916946FFF715FE41E526 -:104A3000F3B50C4685B0812069460873002C1BD065 -:104A4000059804F0DCFB070018D03878222869D3D9 -:104A5000059800F05AFA049000220121059807F009 -:104A6000CEFE00280CD000231A460321059808F03A -:104A700081F805000AD105E0102028E5094826E55F -:104A8000112024E50849114811F0CDFC28460830D2 -:104A90000BF032FB06462078012819D0022838D0C6 -:104AA000072014E502300000E8380000E1080000AB -:104AB0000328000000280000013400002800002026 -:104AC00000800100FFFF000000090020840A0000B0 -:104AD000A18803AAFEF71CFB0028CED1B00721D580 -:104AE0006846007B00281FD1A079C0071CD0E06871 -:104AF000002205216B4607C36389228968880499CF -:104B000001F018FC6946087300280DD0FEF7C9FAB9 -:104B1000DDE4A18803AAFEF7FBFA0028ADD134201A -:104B2000064201D10820D2E46846037B2946384674 -:104B3000059AFEF70BFDCAE4FFB597B0002001907F -:104B40001F4615460C460E46179804F058FB0028E1 -:104B500004D00078222803D20820A6E5F448A4E572 -:104B6000B80801D00720A0E5032F00D1002717982F -:104B700000F0CBF90890002C1BD0022D77D3ED4824 -:104B8000006884427CD361190091012902D0491E3A -:104B9000814275D3AD1EAAB22146E74810F036F81F -:104BA00000991E394A7F0B7F11021943884267D151 -:104BB000ADB2E248B90702D50189491C00E00121E4 -:104BC00089B20091F90701D0078900E0DA4F03AA02 -:104BD0000899009801F0F1FC0DE0F078B17800023E -:104BE000084310284CD80199091D401880B2019043 -:104BF000A84245D82618002E60D07078317800027F -:104C0000084300998842E8D358E06946098A0A07B0 -:104C100054D5002C3FD0019AA618121D92B20992C9 -:104C2000F278B37812021A439446102A28D8099AC7 -:104C30006244AA4224D87278337812021A4390420E -:104C40001ED1C8061ED509980AAA052120186B4650 -:104C500007C3707831780002084363460022089940 -:104C600001F068FB002803D0FEF71BFA1DE507E002 -:104C7000F078B178000208436946098D884201D076 -:104C80000B2012E5F078B17800020843099940182A -:104C900080B2019006E0C90604D50899FEF793FC9E -:104CA0000028E3D16946088A1021884369460882B2 -:104CB000488AFF23049A089901F0AAFD03A801F08D -:104CC00085FC002803D16846408AB8429DD900235C -:104CD0001A460321179807F04DFF040003D19849A5 -:104CE000984811F0A0FB20880028BFD0012108A817 -:104CF00001700173002646732188684601862046AC -:104D00000830099017980A90FCF712FE05001BD096 -:104D10001798688017206946888010AB023301AA73 -:104D2000052108A800950BF090FD0746687800075C -:104D300004D584488249223011F075FB002F09D038 -:104D40003846FEF71AFAB0E41321179805F04AFD29 -:104D50000320AAE40EA8009068468388042201215B -:104D6000179807F064FA00288BD126809DE4F0B5EF -:104D700000248DB01F4615460E46002A04D0B908FF -:104D800004D007200DB0F0BD1020FBE7032F00D1A9 -:104D9000002700F0BAF80390FF2804D06749B8074D -:104DA00003D5488902E06248ECE70120FA0702D007 -:104DB0004989491E00E0604906AA8FB2039901F0B3 -:104DC000FCFB38E06946898B090734D504AB052123 -:104DD0000022029300910192574B039901F08EFC3F -:104DE000002821D1002E21D06A46128A2988A218D3 -:104DF0003019121D914234D36946CA8B0270120ACF -:104E000042700A8A8270120AC27004A90522001D2B -:104E10000092029101906946C88B0B8A0022039987 -:104E200001F06CFC002801D00320ABE76846008A43 -:104E30002018001D84B206A801F0C8FB002804D089 -:104E4000822806D0FEF72DF99CE76846C08BB84251 -:104E5000B8D9002C07D0002E10D02988A01C814280 -:104E600003D20C208EE705208CE7224631463248DB -:104E70000FF0CCFE31190870000A4870A41C2C8079 -:104E800000207FE700B585B06946FEF79FFA00284D -:104E90000AD16846007C030011F0B6FB08052F2FED -:104EA0002F2F08080531032005B000BD6846807823 -:104EB000012807D1684600880321C902401A1CD086 -:104EC00001281AD068468079012806D16846808872 -:104ED00015214902401A05280FD96846807A012811 -:104EE00011D16846018929200002081A05D002283C -:104EF00003D0032801D0042805D10F20D4E712A144 -:104F0000164811F090FA0020CEE710B507F028FE01 -:104F100010BD10B50C4601F023FB002803D00AA1F8 -:104F20000F4811F080FA2046FEF7BBF810BD0000D4 -:104F30000230000028000020FFFF000000090020D0 -:104F4000E83800003F0B00007372635C67617474A3 -:104F5000735F636F72652E63000000002202000021 -:104F6000BB060000F8B500780C46164610340E3625 -:104F7000069F022809D0032836D005287ED0FF20BE -:104F8000F6A1E53011F04FFAF8BDCD890A2068434B -:104F90000E30188031203880002AF5D0087B9581AA -:104FA000801FC7B21AE020886168308048780A788C -:104FB00000021043F080C8788A78000210433081E4 -:104FC000B21C3846091DFDF772FE002F01D00028E3 -:104FD00002D000203071708008340A3628466D1ED9 -:104FE000ADB20028DFD1F8BDCD890A2068430E306C -:104FF000188032203880002AF5D0087B9581401F28 -:10500000C7B243E0616822880878F2803279C3072A -:1050100052085200DB0F1A43FD231A408307DB0FAF -:105020005B001A43FB231A404307DB0F9B001A4324 -:10503000F7231A400307DB0FDB001A43EF231A4064 -:10504000C306DB0F1B011A43DF231A408306DB0F65 -:105050005B011A43BF231A404306DB0F9B011A432F -:105060003271C00970718A784B7810021843308110 -:1050700032463846C91CFDF71AFE00E00CE0002855 -:1050800002D00020B070308008340A3628466D1EE9 -:10509000ADB20028B6D1F8BD087BCD89801E86B29E -:1050A0003046083068431030188034203880002A99 -:1050B000F1D0174695811037E800D681C0190090CD -:1050C0000DE020883880009878603246616800984A -:1050D00011F02BF800980834801908370090284602 -:1050E0006D1EADB20028ECD1F8BDFFB581B00A9DB0 -:1050F0001E460C46002A05D0607AFF300130D08071 -:10510000E089108101980E270078030011F07CFAE5 -:105110000B7E0719293541536C7878787E00009210 -:10512000087B082805D0032803D091A1954811F0E9 -:105130007AF9378030200FE000990020888105B08F -:10514000F0BD0092087B042804D08E4888A114305A -:1051500011F069F937803120288000980028EBD1C0 -:10516000EDE70092087B042804D0932080A1800002 -:1051700011F059F937803220EEE70092087B0228BF -:1051800004D080487AA13A3011F04DF937803320AD -:10519000E2E7087B1746042804D07A4874A14C3013 -:1051A00011F041F91020308034202880002FC6D023 -:1051B0000020B88116E0207B1746052806D0062877 -:1051C00004D070486AA1603011F02DF912203080AF -:1051D00035202880002FB2D0E089B88100203882A5 -:1051E00001984088F881AAE70092087B072804D03C -:1051F00064485FA1713011F016F937803620ABE7B3 -:1052000033460095019800F00EFC98E72F2053A13B -:10521000000111F008F992E770B50C46054603F05D -:10522000EEFF002804D00078222803D2082070BDA9 -:10523000554870BD00231A460421284607F09AFC01 -:105240002060002801D0002070BD032070BDFFB594 -:105250008BB00D4607461720694608850E98032631 -:105260001446002805D10EA93846FFF7D5FF0028BF -:1052700034D1002D0BD000220321384607F0BFFAAD -:10528000002834D00E980078002830D108E020782B -:10529000092819D00F2823D030A13C4811F0C3F8B9 -:1052A0000E98A760801D03AA606002320AA92046FA -:1052B00000F00FFC002827D0030011F0A5F9071A11 -:1052C000182323211C1E23000726002231463846BE -:1052D00007F095FA0028E3D12B48801C0FB0F0BDF1 -:1052E00000220321384607F08AFA0028D8D111207D -:1052F000F4E70020F2E70820F0E72348401CEDE740 -:105300000720EBE70320E9E701A800906846038D3A -:1053100004223146384606F08AFF0028DED1002DEF -:10532000DCD00E990D70D9E730B587B01D460C461C -:10533000002A11D0042369460B7013888B81528890 -:10534000CA81A2788A7422880A8200236A46294682 -:10535000FFF77DFF07B030BD1020FBE77372635C81 -:1053600067617474635F636F72652E630000000091 -:105370007372635C67617474635F636F72652E63DD -:105380000000000025020000023000004F03000072 -:10539000F3B581B001980C4600780826030011F09F -:1053A00033F9125F47471B134B0A0A0A0A0A0A0A13 -:1053B0000A0A0A0A0A5F002C02D1F849F84808E0F4 -:1053C0006078304360703CE0002CF9D1F448F34938 -:1053D000083011F028F8F3E70198002380880122B3 -:1053E00087B20421384607F0C5FB0546002C04D0DF -:1053F0007520EA49C00011F016F8002D04D1E848E4 -:10540000E649143011F00FF83946A81D00F058FB9A -:10541000FCF78EFA040006D0607830436070678035 -:10542000FCF767FA0FE01321384605F0DBF915E0C9 -:10543000DB48DA49283002E0D948D8492D3010F04D -:10544000F2FF002C0AD06078000707D59320207067 -:105450002046582208300199FBF7B6FE0020FEBD19 -:10546000CF48CE493130EAE710B500210170801DE8 -:1054700000F023FB10BD0A4610B50146901D00F058 -:1054800027FB10BD70B5002305461A46042107F01E -:1054900071FB040004D1F920C049800010F0C3FF63 -:1054A0002946A01D00F00CFB70BDF7B5054684B081 -:1054B0000C4600206946088188806F8803460122D7 -:1054C0000421384607F056FB060004D1FD20B349FD -:1054D000800010F0A8FF002C03D0A7800020E080FF -:1054E0002081297A20461230C91E142700900B0013 -:1054F00011F08AF80FFEFDFC3809A95E657A2FB21B -:10550000C9E99191FC003078012804D0A3497020AA -:10551000143110F088FFA9896A46C8000E309080C7 -:1055200030201081002C13D0A18100200DE0C1009B -:10553000327909190A747288CA8182005319DA898A -:105540004A821A8A401C8A8280B2A1898142EED89E -:10555000F1E002A8009001AB22462946304600F057 -:105560002BFAE8E03078042804D08C49BD201431AF -:1055700010F059FFA8890622014650436A460E30B2 -:10558000908033201081002CE2D0A18100200BE01C -:10559000062141434F190919FA89CA81BA7C8A74D4 -:1055A0003A8A401C0A8280B2A1898142F0D8C2E0C6 -:1055B000307806280BD079491431D72005E03078AF -:1055C000062804D07549EB20143110F02CFFE8892F -:1055D00069461230888035200881002CB8D0A9890E -:1055E000A1817188E18126E03078072804D06B49D9 -:1055F000FF20143110F017FFA8896A4601460E30CB -:10560000908036201081002CA2D0A1812046AA894A -:105610000E30296954E0E8896946123080B2382298 -:1056200088800A81002C7ED0A989A181287A10283F -:1056300007D00221A173E9892182EA8929690098AA -:105640003EE00121F6E702A8009001AB2246294680 -:105650003046FFF787FC6EE03078082805D04F49C8 -:10566000FF201431EE3010F0DEFE684637218780CF -:105670000181002C5FD0A989A18100206082208255 -:105680000120A07357E03078092805D04349FF2056 -:105690001431FF3010F0C7FE288A69461430888024 -:1056A00037200881002C46D00421A173A989A1814B -:1056B000E9892182298A618220462A8A143069690F -:1056C00010F033FD37E030780A2804D033493548EC -:1056D000143110F0A8FE6846372187800181002C24 -:1056E00029D00521A1730020A08102E01EE003E083 -:1056F0000CE0208260821EE002A8009001AB2246EE -:1057000029463046FFF7F1FC15E00CE00D20694614 -:10571000392288800A81002C05D00120E0800020F9 -:105720002081207307E00699088019E01C481B4976 -:10573000A43010F078FE6846069980880880002C16 -:105740000ED0684600892080684680886080287A6C -:10575000032805D0102803D0112801D00020307074 -:10576000002007B0F0BDF7B5568815460F46002358 -:1057700082B01A460421304607F0FCF9040004D137 -:1057800007480649C43010F04EFEA41D33462A4691 -:1057900039460094029800F022FBD0E45C530000EC -:1057A0009503000013020000F7B58CB00D461446B7 -:1057B00007A90C98FFF730FD002812D1B64E01273B -:1057C000002C0FD00321684601701021818208A8A7 -:1057D00002460690204605A9FDF78FFA00280BD057 -:1057E00007207BE50821684601708581C681052177 -:1057F0008774C90201820BE00798A17801712188A2 -:105800004180684605218774C90201828581C6816D -:1058100002460121079B0C98FFF719FD5EE508B5CC -:1058200001236A4693709D4B13800A460223694602 -:10583000FFF77AFD08BD08B501236A469370974BC0 -:105840005B1C13800A4603236946FFF76DFD08BD04 -:1058500000B587B000290CD002236A4613700B886C -:1058600093814988D18100230421FFF7F0FC07B020 -:1058700000BD1020FBE710B5002903D00523FFF77A -:1058800053FD10BD072010BD70B588B00D461446FD -:10589000064607A9FFF7C0FC00280DD1002C0DD04B -:1058A0000621684601708581C481079B02465C80A1 -:1058B00006213046FFF7CBFC08B070BD05216846D5 -:1058C00001708581F1E710B588B000290BD007245D -:1058D0006B461C709A81049100236A462146FFF7AB -:1058E000B6FC08B010BD1020FBE770B500241722ED -:1058F00088B0002914D00D782B0010F085FE062307 -:10590000050519041B231522D21E93B2CA88002A4A -:1059100002D08E68002E03D09A4203D90C20CBE728 -:105920001020C9E7042D05D08A88002A0AD101E099 -:105930000620C1E7012D11D0022D05D0042D18D06D -:10594000052D23D00720B7E709236A4613704B883B -:105950009381CB88D381896804911DE00C236A462A -:1059600013704B889381CB88D38189680824049174 -:1059700012E00D236A4613704B8893818B88D38184 -:10598000CB88138289680924059105E00E236A46B5 -:105990001370497811730A2400232146FFF757FC3E -:1059A0008AE700B587B00F236A4613709181002300 -:1059B0001946FFF74CFC5AE7FEB50078089D1C46D7 -:1059C00016460F46012803D03549912010F02BFDD3 -:1059D000F889C0000E30208030202880387B001FDE -:1059E000C0B20190002E1DD0F889B081002516E0CC -:1059F000E8008419C0190090224641690E320198CE -:105A0000FDF755F9002802D000202074E0810098AD -:105A10006D1C008A60820098ADB2408AA082B08975 -:105A2000A842E5D8FEBD70B514461425049A1D8021 -:105A300037231380002C0ED0CA89A28100226282F3 -:105A40000078082808D0092810D00A2819D014494D -:105A5000144810F0E8FC70BD087B0C2804D01148F5 -:105A60000F490C3810F0DFFC012008E0087B0D28FE -:105A700004D00C480A49083810F0D5FC0420A07363 -:105A800070BD087B0E2804D006480549001F10F0A1 -:105A9000CAFC0520F3E70000FFFF00000228000019 -:105AA00070530000BB02000010B5FE4B5860197225 -:105AB0001A80C90010F098FB10BD002101807047CA -:105AC00010B50022D2430280032007F0F8FC10BD7D -:105AD0007047F0B50E460446017801208840F2492F -:105AE00099B008400090616815460888EF4A9042D6 -:105AF00006D0009A002A06D0EB4A521E104202D06D -:105B0000012019B0F0BD009A10430880002D12D07A -:105B1000002028702178EA1C0027681C01920B00E5 -:105B200010F072FD10F30E16233A59616F3CB4B0B9 -:105B30008AB8F2F1F0F320780B28EBD00420E0E7EC -:105B400002212970A1890170090A4170032097E0A0 -:105B500004212970A1890170090A41700198E18925 -:105B60000170090A417005208AE006212970A18987 -:105B70000170090A41700199E2890A70120A4A709B -:105B8000218A0171090A4171A28AE81DA16910F0F8 -:105B9000CCFAA08AC01D73E0082129702178082959 -:105BA00001D110212970A1890170090A4170019861 -:105BB000E1890170090A41700520308020466A1D84 -:105BC00002A91030FDF799F800287DD16946308888 -:105BD000097A401854E00A212970A1890170090A44 -:105BE000417003200BE00C212970A1890170090A82 -:105BF00041700198E1890170090A417005203080E7 -:105C00009CE0A08984464000401C81B230888842D4 -:105C10005AD3052958D30E202870002008E02369A4 -:105C200042009B5A521953701B0A401C937080B259 -:105C30006045F4D33180B9E09A48417A002973D0A5 -:105C4000491E4172217B4068C9004518A98828680F -:105C5000082240180838216910F067FA02216846C6 -:105C600001710021417128680390A988684601816B -:105C7000002101A8FFF78CFB0020A880002E00D097 -:105C8000308093E0297880221143297029784022BE -:105C90001143297029788909890112312970A18954 -:105CA0000170090A4170E289E81C216910F03DFA8F -:105CB000E089C01C3080287841063FD5C00975D0E6 -:105CC00001216846017200E02CE000214172318818 -:105CD000091D81810495E189019808180590001D2E -:105CE00006907048017A68460177002102A8FFF704 -:105CF0004FFB074630880C303080022F06D0002F33 -:105D000054D065E03DE033E01CE05EE06548694664 -:105D1000097F4268CB00D218037A994202D2918857 -:105D2000002902D0042753E02FE0417A491C417238 -:105D30001560308890800020308049E06168A0893B -:105D4000888033E029788909890116312970A18971 -:105D50000170090A41700198E1890170090A4170D6 -:105D6000228A681D616910F0E0F9208A401D46E72B -:105D700028788009800118302870207B6870022004 -:105D80007EE760680188090401D4052720E0C08807 -:105D9000A189884201D006271AE01E202870012020 -:105DA0003080606801884904490C0180009800280F -:105DB0000ED03C4800220088A1688300032007F031 -:105DC000D9FA61682078887007E0002030800327C6 -:105DD0006068009902888A430280384691E6FFB5E0 -:105DE0009FB0289D0E46002805D0172803D82A8882 -:105DF0002E4B9A4202D1072023B0F0BD32785306D1 -:105E000001D4D20901D00820F6E700226B461A71AE -:105E10005A7114463278431E1D939BB2189303ABFC -:105E20001A939706CB1CBF0E1B93821E711C3B005E -:105E300010F0EAFB209011EE66EE74EEB0EED4EEB8 -:105E4000EDEEECEEEBEEEAEEE9EEEEEEE8EEE7EE8E -:105E5000E6EEE5EE90EE05287CD10421684601715E -:105E6000A9780172F078B278010211436846418145 -:105E70003179417170788006800E0C282ED009DCB3 -:105E8000801E030010F0C0FB0919661C6621662401 -:105E90006627660012282AD00ADC0E2821D0102896 -:105EA000DAD121E00C090020FF710000FFFF0000A3 -:105EB00016281FD01828CFD11FE02878800701E0CE -:105EC00028784007002845DA45E128780007F9E7F7 -:105ED0002878C006F6E728788006F3E72878400699 -:105EE000F0E728780006EDE72888C005EAE728886B -:105EF000C004E7E728888004E4E728884004E1E755 -:105F00002A78920726D50328A6D105206A46107163 -:105F1000487809780002084310811CE12978490774 -:105F2000F0D5062816D3717890B2012902D0022943 -:105F300092D101E0022100E01021189106216A4669 -:105F400011710021118102AF189AB11C0237921C05 -:105F50001B921AE0B3E04A780B7812021A433A8097 -:105F6000801E891C1790BA1C1A911898FCF79FFE86 -:105F70001A991898189A091817986B46801A1A894E -:105F800080B2521C1A811B9ABF1D8242E3D900289D -:105F900086D1E0E028780007B4D51D98694682B222 -:105FA0000720087100200881701C0A3111E0437835 -:105FB00007781B023B430B80C37887781B023B4367 -:105FC0004B806F463B89121F5B1C001D92B23B81C8 -:105FD000091D042AEBD2002A71D1BCE02978C90638 -:105FE0006DD502286BD308206946087100204881CE -:105FF00070780872844692B2B01C1A9919E089E050 -:1060000090E07EE067E05BE030E025E019E013E03F -:10601000BCE0437807781B023B430B80831C4B603A -:106020006346D21A6F467B8960445B1C92B27B81C7 -:1060300008319445EDD9CEE7287880063FD509226E -:1060400003E0287840063AD50A2268460271AA88F9 -:106050000281189A428107E0287800062FD50B208C -:106060006A46107118981081039174E02988C90557 -:1060700025D5022823D30C206946087100204881C9 -:1060800070780872844692B2B01C1A9914E0437872 -:1060900007781B023B430B80C37887781B023B4386 -:1060A0004B80031D4B606346D21A6F467B89604468 -:1060B0005B1C92B27B8108319445E8D98BE763E0A1 -:1060C0002988C90460D501285ED10D216846017177 -:1060D000A98801813FE02988890455D5052853D333 -:1060E0000E2269460A71AA880A811B99401F4A78C4 -:1060F000097812020A4369464A818881701D04901A -:1061000029E0298849043FD501283DD10F2069465F -:10611000087120E02A88120436D44A780B781202DB -:106120001A43EA8003282FD332789206920E1B2A54 -:1061300026D011226B461A712A880123DB031A43E9 -:106140002A804A78097812020A4369460A81C01EE9 -:1061500048811B98039030788006800E1B2809D058 -:106160001D2807D00320229907F0A9F92888C00B21 -:10617000C003288001A82199FFF70AF920463BE6D1 -:1061800010226B461A71DCE70724F7E70824F5E7CD -:1061900000B597B0032806D16A461070019100211E -:1061A0006846FFF7F5F817B000BD000010B58B7812 -:1061B000002B11D082789A4207D10B88002B0BD08C -:1061C00003E08B79091D002B08D08B789A42F8D117 -:1061D00003880C88A342F4D1002010BD812010BD9B -:1061E000052826D0002A02D0012A0DD102E0098814 -:1061F000090501E009888904890F07D0012918D011 -:10620000022909D003290ED081207047002A01D02D -:10621000032070470220704703280AD0042808D0C2 -:10622000002804D007E0042803D0022803D005206A -:106230007047002070470F20704770B513880546DF -:1062400014460B8018061DD5FE481022807AA842FD -:1062500003D813430B80002070BDA06893430078DF -:10626000E840C007C00E03430B802078A178800768 -:10627000800D0843F4490FF0D2FFA0686943081865 -:10628000401C70BD906870BD37B569468B8813801F -:1062900019061BD5EB4C0125A47A9168844209D8D4 -:1062A000FE280FD1D80602D5A5406D1E00E00025BE -:1062B0000D7007E085400C78DB06DB0FAC438340B4 -:1062C0001C430C7010881021884310803EBDF8B527 -:1062D0000746C81C80080E468000B04201D08620C8 -:1062E000F8BD082A01D90E20F8BDD64D00202E6039 -:1062F000AF802881AA723446E88016E0E988491CFC -:10630000E980810610D48007A178800D0843CE492A -:106310000FF085FF206800F0BAFA2989401880B292 -:106320002881381A8019A0600C3420884107E5D4F0 -:106330000020F8BDFFB589B09F041646139DBF0C21 -:106340000193099800F095FA04000AD0207800061D -:1063500009D5BC48817A0A98814204D887200DB0BB -:10636000F0BD0120FBE7224669460A98FFF765FF6A -:106370000690002069460872052D14D0012221469E -:106380002846FFF72DFF0028E9D1207840060AD5DE -:10639000022168460172099981810188C1810682C2 -:1063A0004782129805900198000404D500273E46C4 -:1063B0000125079709E02078A1788007800D084320 -:1063C000A14907900FF02BFF0D46019840040AD514 -:1063D0000798A84207D12088E1788005800F000245 -:1063E0000843B04201D3AE4201D90720B7E7B8193C -:1063F00080B20190A84201D90D20B0E76846007A2A -:10640000002804D002A8FDF706F90028A7D10798B4 -:10641000A8420BD1208803210902884301998905EC -:10642000890F0902084320800198E0701498002821 -:1064300000D007801298002815D006983A46801997 -:1064400012990FF072FE224669460A98FFF7F5FE90 -:1064500069460888102188436946088022460099C9 -:106460000A98FFF711FF002079E7FFB5754D0C2260 -:10647000E8882968504383B00C180D9F724905982D -:106480000FF0CDFE0091049800F001FA29682A89E6 -:106490008E46611A0C310918944651188AB2A9889F -:1064A000914202D8842007B0F0BD6A46168A3206AF -:1064B00003D5B20601D58520F5E7EA88521C92B2D1 -:1064C000EA800E9B002B00D01A80B20601D5A7608F -:1064D00006E0604480B22881091A70460818A0605E -:1064E0002246FE200499FFF7CFFE0598A070009881 -:1064F000E07020880599800889058000890F08438D -:1065000003210902884300998905890F090208437C -:1065100004210843208003988078A07103980088A4 -:10652000A08000202073310601D5AC7A00E0012460 -:10653000B10600D5002700260EE0052100200191BC -:1065400002900097E88831460C9B069AFFF7F2FE0E -:106550000028A8D1761CF6B2A642EED30020A2E70E -:10656000F1B5009800F085F9060002D00025009CE6 -:1065700014E00120F8BD204600F07BF907460078C2 -:1065800031498007820DB87810430FF048FE386813 -:1065900000F07DF94019641C85B2A4B22948C18875 -:1065A000601E8142E7DC00992648491EC1800189AE -:1065B000491B018100203070F8BD002804D0401E26 -:1065C00010809170002070470120704710B504467C -:1065D00001881C48C288914201D3822010BD006806 -:1065E0000C22514342189079A07290882081108823 -:1065F000D1788005800F00020843A081A078211D7A -:10660000FFF71BFE20612088401C2080E0800020D6 -:1066100010BD012101827047F7B50546002084B006 -:10662000C043108068681746817868468170686842 -:1066300001886846018000218171288A2C88A04247 -:1066400005D303E0180900200102000004462C8253 -:1066500035E0288A401C2882301D6968FFF7A6FDB6 -:1066600000282AD139889248814201D1601E3880A1 -:106670006888A04228D33088F1788005800F000216 -:10668000084302906946301DFFF790FD002814D1A1 -:106690006989874881421BD0002231460598FFF75F -:1066A0009FFD002809D16A890298824205D1E968D4 -:1066B000B0680FF00DFD00280AD0641CA4B220467B -:1066C00000F0D7F80600C4D1641E2C828220EAE6CE -:1066D0007C80B079B871B088B8803078B1788007A4 -:1066E000800D084378810298B8813946287A32466D -:1066F0000831FFF7A2FD38610020D4E6FFB585B070 -:106700001C460F46059800F0B4F8050009D028781B -:10671000000608D56748807AB84204D8872009B0B7 -:10672000F0BD0120FBE707982A468605B60D6946AD -:106730003846FFF782FD07460E98052816D000223E -:106740002946FFF74DFD0028E9D1287840060DD5F0 -:106750000121684601710599018101884181868185 -:10676000C48101A8FCF757FF0028D8D12888AA784F -:106770008107890D11438005800FEA7800021043DC -:10678000079A964207D04C4A914204D3611E814237 -:1067900001DD0B20C3E7864201D90720BFE7801B3C -:1067A00082B2A24200D922461098002800D002806E -:1067B0000F98002802D0B9190FF0B7FC0020AEE7FF -:1067C000F8B51D4617460E4600F053F8040008D0F1 -:1067D0002078000607D53748807AB04203D8872052 -:1067E000F8BD0120F8BD224639463046FFF725FDA9 -:1067F000002D0BD02078A1788007800D08432E490A -:10680000884201D2012000E0002028700020F8BD5D -:10681000F8B51E4617460D4600F02BF8040008D0C8 -:106820002078000607D52348807AA84203D887201D -:10683000F8BD0120F8BD224639462846FFF724FD61 -:10684000FF2E14D02588A178A807800D08431A4987 -:106850000FF0E5FC002E03D1FF31FF31033189B287 -:10686000A170A80880008905890F084320800020B6 -:10687000F8BD1049CA88824207D3002805D00C22EF -:10688000096850430C38081870470020704703B55A -:106890000846694609888A0607D4090604D50549C9 -:1068A000897A4143491C88B20CBD00200CBD000010 -:1068B000FFFF00001809002001020000F8B507786A -:1068C0000D460446012F19D0072F02D00C2F19D1E5 -:1068D00014E0A068216906780B2E0BD0052006F085 -:1068E000EEFD052E0ED0782300220520216906F04A -:1068F00041FD07E0782300220620F8E70520216902 -:1069000006F0DDFD002D0ED000202870294620461F -:1069100004F0AEF9FE482978C05D884201D1032019 -:10692000F8BD0220F8BD0021204604F0A1F90020A6 -:10693000F8BD70B50E460C462036317901208AB07C -:106940001546002909D0012905D12978042902D149 -:106950000520107000200AB070BD6068019005A885 -:1069600002900D21C01C0FF03DFC032205A8A16878 -:106970000FF0DBFB01203071062069460870206AA9 -:10698000049029466846FFF799FFE4E770B50C4686 -:10699000154620310A790120062686B0002A2CD01F -:1069A000012A28D12978042925D169681022A068F4 -:1069B00001F0B4F96868C07B000606D5D44AA06827 -:1069C0001023103A014601F09EF91022A168E068F8 -:1069D00001F0A4F9A068C07B000606D5CC4AE068A7 -:1069E0001023103A014601F08EF92E70A0686860FD -:1069F000E068A860002006B070BD60680190C448DF -:106A0000203802900120087168460670206A0490C0 -:106A100029466846FFF752FFEDE7027B032A06D0BE -:106A2000002224235A540B78092B02D003E00420BF -:106A300070470A76CA61027B9300521C0273C150F0 -:106A400003207047F0B50E4615460C462036024628 -:106A500031790120072393B000290CD0012924D0DB -:106A600002292ED0032904D12978042901D12B70C1 -:106A7000002013B0F0BD01203071606800280DD0F7 -:106A8000A1690B7060684860206988606069C860AF -:106A9000206A08621046FFF7C0FFEAE70620287068 -:106AA000206968606069A86009E029780629E0D15A -:106AB0000220307104202870954820386860032037 -:106AC000D7E729780429D4D1A08910280AD9103809 -:106AD00080B2A081A1681023091805A86A6801F096 -:106AE00012F923E010282FD0C2B21020801AA1681A -:106AF0000DAF1190C0190FF018FB11980006000E91 -:106B000006D0401EC1B28020785438460FF06AFB90 -:106B1000626910230DA909A801F0F5F8102309A94D -:106B200005A86A6801F0EFF80320307160680190F1 -:106B300005A80290062069460870206A049029463C -:106B40006846FFF7BBFE94E710232269A168E2E7DD -:106B5000F0B50E460C4620363179012006278FB05D -:106B6000154600290BD0012932D0022905D12978F8 -:106B7000042902D10820107000200FB0F0BD217D43 -:106B800008A8CA07D20F02718807C10F08A80171AF -:106B90006846027041700722801CE1680FF0C5FA58 -:106BA00002A80722013021690FF0BFFA6068059042 -:106BB0000AA8069010236A46A16801F0A4F80120F3 -:106BC000307168460774206A0890294604A820E0BE -:106BD00029780429D1D1062205A8E1690FF0A5FA88 -:106BE00006A806220230A1690FF09FFA0020089043 -:106BF0006068019009A80290102305AA696801F055 -:106C000082F80220307168460770206A0490294695 -:106C10006846FFF753FEB0E770B50D460C462035C9 -:106C2000297901208CB01646002909D0012905D107 -:106C30003178042902D10920107000200CB070BDF9 -:106C40006068019006A802900822E1680FF06DFAD2 -:106C5000082208A8A1680FF068FA01202871062010 -:106C600069460870206A049031466846FFF726FEA0 -:106C7000E4E770B50D460C462035297901208CB02B -:106C80001646002908D00129D8D131780429D5D158 -:106C90000A2010700020D1E76068019006A80290D9 -:106CA0000822A1680FF041FA002008900990012005 -:106CB0002871062069460870206A049031466846AB -:106CC000FFF7FCFDBAE730B50B4620331C790120F5 -:106CD0008BB0002C09D0012C05D11178042902D1E8 -:106CE0000B20107000200BB030BD4868019005A843 -:106CF00002908C6868462578057564784475CC6880 -:106D0000257885756478C47500200690079001E0A9 -:106D10002867010008900120187106236846037057 -:106D2000086A049011466846FFF7C8FDDBE770B5B6 -:106D30000C462034034625790120002D0AD0012D70 -:106D400014D0022D05D111780A2902D10C2010701F -:106D5000002070BD01202071C868052202704A68B9 -:106D60004260F84A8260921CC2600BE015780B2DDD -:106D7000EFD102202071C868042404705268426078 -:106D80008A688260096A016201461846FFF745FE7B -:106D900070BD30B5011D02463132947803258379E8 -:106DA000ED432C4323408371DB070DD04B7954799D -:106DB00023404B710B79127913400B718278C9789B -:106DC0008A4200D9817030BD00224A710A71F5E70C -:106DD000F7B50C4686B00020694626460870203676 -:106DE000317901271E2015461F2977D24B007B449D -:106DF0009B885B009F441E0017023E0256026902F8 -:106E000088029A02D102F5022E03590371037F030F -:106E1000AE03C303CC03F7031A0464049A04AB045F -:106E2000DF04FE0410052A0565059B05C6058305DC -:106E300087058B056069002802D0007813287DD073 -:106E4000A0680590002849D0012168460170206A99 -:106E500004900321684601710A214171E0690290A2 -:106E600020790028EFD0059909780029E7D00C296E -:106E700064D20B000FF0C8FB0CFD1A4B90B5E8FC78 -:106E8000FBFAF9F807FD022828D16069002802D032 -:106E90000078082852D1022168460170206A0490C7 -:106EA00005984178684601710021B9E20620216AFF -:106EB00006F005FB20790728E6D1606900F050FF55 -:106EC00002280CD0606900F04BFF042807D06069ED -:106ED0000028B8D000780128D6D103E01BE2616910 -:106EE0000120087005980079C11F0A2901D30A20E2 -:106EF00050E06169072288706069059930300FF0B1 -:106F000014F90120307161690320087034E007280A -:106F1000BAD16069002896D001780929B4D10599C1 -:106F2000C978890707D1059949790029DFD10599E1 -:106F300089790029DBD105994A7900E04EE20146C2 -:106F400020314B7D9A43D2D1059A8B7D92799A4319 -:106F5000CDD1059A1279D31F0A2BC8D20979914253 -:106F600036D80722C01C05990FF0DFF801203071D8 -:106F700061690A200870032069460870206A04903D -:106F80006069313001906069001D029060691C30B9 -:106F90000390A1E22076F2E311288DD1606900F020 -:106FA000DFFE042804D0606900F0DAFE0B2893D1DC -:106FB0006069059910223730491C0FF0B6F86069F6 -:106FC000017804297CD12421095C8278914201D97D -:106FD0000620DFE70521017003203071684601704B -:106FE000E2E3112894D1606900F0BAFE062804D0CB -:106FF000606900F0B5FE0C288AD1E068002813D043 -:107000002069002810D060690178062910D00D2170 -:1070100001706069059910225730491C0FF085F8FE -:107020006069573009218CE100206946087072E1DF -:10703000072101706069059910224730491C0FF043 -:1070400074F860694730EDE70228F0D1606900F01C -:1070500087FE0028EBD0606900F082FE0128E6D0B0 -:10706000606900F07DFE05E0B1E08DE06CE02AE0B3 -:107070000AE0D6E00828DAD00521684601710598B3 -:1070800041786846417146E11128D0D160690028F5 -:10709000CDD001780E29CAD1C16A4078022810D01B -:1070A0000020142250431430085805991022491C1E -:1070B0000FF03BF80520216A00F040FE0F205EE053 -:1070C000F1E10120EDE70B28B1D160690028AED0D5 -:1070D00001780F29ABD1C16A4078022826D0002060 -:1070E000142250430C300958059842780A70807871 -:1070F00048706069C16A4078022819D000201422C3 -:1071000050431030085805990822C91C0FF00DF89B -:107110000520216A00F012FE60694178022909D039 -:1071200000220832825C5208520073E00120D7E747 -:107130000120E4E70122F4E7012100E00021083109 -:107140004254BCE30267010011289CD16069002809 -:1071500099D00178102996D1C16A4078022811D0BF -:107160000020142250431830085805991022491C59 -:107170000EF0DBFF0520216A00F0E0FD11206169BF -:107180000870B4E30120ECE7082884D16069002886 -:107190009DD00178112997D10599C06A497801706D -:1071A00060690599C06A0622401C891C0EF0BDFF6B -:1071B0000520216A00F0C2FD60694178022904D0EF -:1071C00000220832825CFD2323E00122F9E7112826 -:1071D000BBD160690028BBD001781229B5D1C16A42 -:1071E0004078022819D00020142250431C3008583F -:1071F00005991022491C0EF098FF0520216A00F025 -:107200009DFD60694178022909D000220832825C24 -:10721000FB231A40022991D18EE70120E4E70122E5 -:10722000F4E70720B6E6287801288ED160696968FE -:1072300014221C30F9F7C8FF6069017F002901D0D2 -:107240002176ACE30178032901D0032037E002273F -:10725000C77081794907490F8171017A4907490F40 -:107260000172417A4907490F41726069FFF791FD48 -:10727000377196E228780F28E3D107206946087015 -:10728000216A049191680291694608716169072237 -:10729000C91C02980EF049FF6169042008700020A3 -:1072A0003071BBE028780328CBD1606901780529CB -:1072B000696807D0082247300EF037FF042030718C -:1072C00005206FE208225730F6E728780328B8D166 -:1072D000606901780529696811D008224F300EF0E5 -:1072E00024FF052030716069006A00280AD002205E -:1072F0002870002028716069006AA860F9E00822FF -:107300005F30ECE704204DE22878022899D12879F3 -:10731000002801D0207642E36069A96801626069B3 -:10732000002901D1F949016206200BE228780F28D3 -:1073300087D1A868E0616069017805292BD04730C2 -:1073400007213171E16802220A706269126A4A609B -:10735000886060693030C8606069C01C086162691B -:10736000087D926A400812784000D207D20F10437D -:1073700008756269926A521C8A61FD221040626936 -:10738000D26A1278D207920F104308756069C06AFA -:10739000401CC86153E25730D2E728780828BAD198 -:1073A0006069017805291AD00B2101700720694610 -:1073B0000870206A0490E069029011200871029818 -:1073C0000321017051681022401C0EF0AEFE002116 -:1073D0006846FFF773FA00203071E06187E206210A -:1073E000E3E728780F2896D1072069460870206ABD -:1073F0000490A8680290112008710298042101707D -:1074000061690A78072A0ED0002232710C220A70B4 -:1074100061691022401C47310EF087FE002168464A -:10742000FFF74CFA63E21022401C57310EF07DFE4C -:1074300000216846FFF742FA0A203071E168032014 -:1074400008706069006A48606069573088606069E8 -:107450004730F3E128780828A1D1606969681022D3 -:1074600037300EF035FE002801D0042092E5606927 -:107470000078072817D00A203071E16803200870CF -:107480006069006A486060695730886060694730A9 -:10749000C860206A08620698FFF7BFFA074660696D -:1074A000FFF777FC6BE208207AE1287809289AD167 -:1074B0000B20307161696868897810224018511A70 -:1074C0000EF090FE082069460870206A04906868F3 -:1074D000019060698078087268E129780D29BBD134 -:1074E00061698979C90703D00C20307109203EE019 -:1074F0003071032770E228780E28ADD1606914221C -:10750000291D1C30F9F760FE6069018DC06A417267 -:10751000090A817260698178C06AC1716169CA6A49 -:10752000081D117AC909C9011172437962691943A9 -:107530008378D26A9B079B0F012B00D00023007930 -:107540009B01C00003431943117260694078012810 -:1075500076D0B4E160694178022901D0012100E0D0 -:1075600000210831405CC00707D00E20EAE06946E0 -:107570000870206A1146049019E11320B8E72878B2 -:107580000F2894D1A868E0610F2030710520EEE744 -:10759000287803288BD16069C16A4078022801D01D -:1075A000012000E000201422504310300858082227 -:1075B00069680EF0BAFD10203071E168062022697A -:1075C00008706069406A48606069C36A4078022850 -:1075D00001D0012000E00020142778431030185813 -:1075E000CA6088602BE128780C2886D16069C26A5D -:1075F0004078022801D0012000E0002014214843F7 -:107600000C30105802230932696800F07CFB11200D -:107610003071E168052008706069006A486060693F -:10762000C06A093088603948001F07E128780B28B4 -:10763000A7D161694878CA6A022802D0012001E016 -:1076400059E1002014235843143010588A7869688F -:107650000EF06BFD60694178C26A022901D00121F8 -:1076600000E00021142359431431525881785018F6 -:107670001022511A0EF0B6FD072069460870206AE4 -:107680000490E069029011200871029806210170AF -:107690006169CA6A4978022901D0012100E000210C -:1076A00014235943143151581022401C0EF03DFD53 -:1076B00000216846FFF702F90020E06112206FE028 -:1076C00028780F2891D1072168460170206A04901C -:1076D000906802900B2268460271029801706169FD -:1076E000CA6A4978022901D0012100E0002114234F -:1076F00059430C3151580A78427049788170616958 -:10770000CA6A4978022903D0012102E00867010012 -:10771000002114235943103151580822C01C0EF087 -:1077200004FD00216846FFF7C9F826E76069417843 -:10773000022901D0012100E000210831405C8007CE -:1077400003D5142030710A2011E71620D0E62878DE -:107750000F287AD1A868E061072069460870206A7E -:107760000490E069029011200871029808210170CC -:107770006169CA6A4978022902D0012101E011E158 -:10778000002114235943183151581022401C0EF087 -:10779000CCFC00216846FFF791F80020E06115203D -:1077A00030710A2069460870206A049029466846AC -:1077B000FFF784F82BE028780F2846D10720694688 -:1077C0000870206A0490906802900820087102985E -:1077D0000921017061690622C969097841706169EE -:1077E000801CC969491C0EF0A0FC00216846FFF707 -:1077F00065F8AAE760694178022901D0012200E01A -:1078000000220832805C400703D51720C8E70746EE -:10781000B5E0012953D070E028780F2815D1A86869 -:10782000E06118203071E168052008706069006A25 -:1078300048606069C06A09308860F848C860206A9A -:1078400008620698FFF7E9F8E1E76FE028780B286F -:107850006CD16069C16A4078022801D0012000E043 -:107860000020142250431C300858102269680EF082 -:107870005CFC072069460870206A0490E069029069 -:107880001120087102980A2101706169CA6A497859 -:10789000022901D0012100E00021142359431C31A9 -:1078A00051581022401C0EF040FC00216846FFF7A2 -:1078B00005F80020E0616069407801281DD1192099 -:1078C00016E660694278022A09D000210831411881 -:1078D000097800290DD0CA0703D00E2106E0012146 -:1078E000F4E7890701D5102100E01221017000277B -:1078F00072E0012A01D00D20FAE51C20F8E51D20D8 -:1079000030710B2033E62978102948D1F0E5606901 -:107910000178012943D0082941D00021317100F0BC -:1079200019FA0C2069460870206A049037E028781C -:107930000F2805D01020107003271B2030714BE05A -:10794000072168460170206A0490A868029002210D -:1079500068460171029805210170217E4170002165 -:107960006846FEF7ABFF0B2168460170206A049061 -:1079700029466846FEF7A2FF07461B203071012FFB -:107980000DD029E0012168460170206A049004218D -:1079900068460171217E41710020207612E0207E30 -:1079A00000280FD06169132008701A2030710A2056 -:1079B00069460870206A049029466846FEF77EFFF3 -:1079C000074609E06069002801D01421017068466B -:1079D0000078002800D021E5384609B0F0BDF7B5A1 -:1079E0000F4620373879012686B00C46002804D08F -:1079F000012828D002281CD197E02079012804D042 -:107A0000022811D0032814D10AE0A0684078012888 -:107A10000ED10620216A05F02CFD00287FD10CE054 -:107A2000A1681320087008E0A0684178022901D0FD -:107A3000052674E00078082871D1012038710A20E9 -:107A40006946087033E0089800780F2867D107214D -:107A500068460170206A049008988568029522792A -:107A60000220012A04D0022A29D0032A57D10FE08C -:107A70000646684606710B202870207B00214007CF -:107A8000400F68706846FEF719FFA068067045E071 -:107A900006466846067105202870207B6870002124 -:107AA0006846FEF70BFF3E710B2168460170206AA5 -:107AB000049068460899FEF701FF06462FE06846E5 -:107AC000017101202870207C6870607CC007C00FA5 -:107AD000A870A07C4007400FE870E17C2971C007C6 -:107AE0001FD0207D4007400F6871607D4007400F28 -:107AF000A87100216846FEF7E1FEA068072229462A -:107B000030300EF012FBE068017AA068203001717D -:107B1000A16828798870A16809200870002630467D -:107B20005BE70020A8716871E3E7A1681420087082 -:107B3000012168460170206A0490042168460171A1 -:107B4000217B41710021FEF7B9FEE7E7F0B585B072 -:107B50000F4605460124287B800040198038C66FF7 -:107B60003078411E0A290AD22C498000323140184F -:107B70008038C36F3A463146284698470446002C61 -:107B800001D0012C11D1287B401E0006000E287365 -:107B900001D00324DFE70D2069460870306A0490A5 -:107BA000002101966846FEF789FE032CD3D02046BB -:107BB00005B0F0BD70B515460A4604462946104684 -:107BC000FFF7C4FF0646002C0FD0207814280CD1F4 -:107BD000207E002806D000202870204629460C3040 -:107BE000FFF7B4FF204600F0B5F8304670BD70478F -:107BF00010B5012903D0022901D0052010BD417024 -:107C000000F0A8F8002010BD002809D0027E002A4C -:107C100006D00A4601460C31CCE700000667010099 -:107C20000120704730B5044687B00D46062005F0A8 -:107C300046FC2946052005F042FC2078142805D092 -:107C40000020694608702046FFF7DEFF07B030BD10 -:107C50007FB50E4600216A4611730178092903D0C9 -:107C60000A2903D0002407E0446900E08468002C5E -:107C700002D0217E002912D0154601462846FEF783 -:107C8000CCFE032809D1324629462046FFF792FF51 -:107C90006946097B002900D0042004B070BD254648 -:107CA0000C35EAE700B50023012285B005280CD089 -:107CB000062808D1684602700491022101714371BF -:107CC0000021FEF7FBFD05B000BD6846027004917F -:107CD0000271F4E710B590B00C4605216A461170A8 -:107CE000019022480290001D03900AA96846FFF700 -:107CF000AFFF002805D1102220460B990EF015FA8F -:107D0000002010B010BD30B505E05B1EDBB2CC5CCE -:107D1000D55C6C40C454002BF7D130BD10B50024A5 -:107D200009E00B78521E5B00234303700B78401C64 -:107D3000DC09D2B2491C002AF3D110BD70B50C4643 -:107D4000054605F0BCFB782300222146284605F0B5 -:107D500011FB70BD4178012900D0082101707047E6 -:107D6000002801D0007870470820704700670100A4 -:107D700038B50446002069460870204609F053FDD6 -:107D8000002803D1FBA1A3200EF04DFB204609F0F3 -:107D900099FC002803D1F7A1A8200EF044FB684607 -:107DA000007838BD70B5F84D002428462C77203077 -:107DB0008471C47101F09AF928464038047020306B -:107DC0008473847484772C75AC7170BD10B50C46C7 -:107DD000EE4982888A8042884A8000780870084686 -:107DE0000E38847009F050FC08F0FDFFFFF7DAFF51 -:107DF00020460BF013F8E449A8310846813809F011 -:107E0000ADFEE2480CF021FBE0480A3808F0FEFF26 -:107E1000002803D0D7A1C5200EF005FB01F066F9BC -:107E200010BD7CB50E461D46144601A909F008F8A0 -:107E3000002807D10AF091FB022803D1D248007D27 -:107E4000002801D001207CBD01988030807C09F0A1 -:107E50004DFC00280CD0684609F052FC0028F2D0F6 -:107E6000002C03D009F011FCA04206D200207CBDFA -:107E7000C0A1C7480EF0D7FAF8E7009809F0D8F883 -:107E80003146009809F0DBF8E2B22946009809F083 -:107E9000F0F909F045FC002804D1BD48B5A11E3019 -:107EA0000EF0C1FAB94C00250E3C6068A030417953 -:107EB000002902D045710BF0D8F860688030458306 -:107EC000C0E730B40179002904D0012907D030BCC3 -:107ED00000207047831D42880488022103E0428805 -:107EE0000488831D0121204630BC9AE7F8B51D4661 -:107EF00014460E4607460AF030FB022803D0A2487B -:107F0000007D002823D0A1480E3841684988398077 -:107F100040688030807C09F069FD002804D153203E -:107F200094A1C0000EF07FFA684609F069FD0028B0 -:107F30000DD0009809F0BAF83070022808D0012856 -:107F400006D093488BA167300EF06DFA0020F8BD83 -:107F50002946009809F0A4F92080002804D1552072 -:107F600084A1C0000EF05FFA09F05DFD002804D185 -:107F7000874880A160300EF056FA0120F8BD38B570 -:107F80000446831D821C6946FFF7B0FF00280DD010 -:107F90000020607168460078012808D0022806D0C9 -:107FA000FF2074A101300EF03EFA012038BD20718F -:107FB000FBE7F8B50AF0D1FA744D734C0E3D022878 -:107FC00002D0207D00287DD0207F0026102818D1E7 -:107FD000A079002803D067A16E480EF024FA6868E3 -:107FE00001464030827F92070BD526724988618115 -:107FF000C17F2173018CE181408C20820120A0711E -:108000002677614F203FB87C00285ED168686946BA -:108010008030807C09F007FC002805D0694668782C -:1080200009784018687004E05A4852A119300EF0DF -:10803000FAF9207D00283AD06868418852484038D3 -:10804000806D4088814204D00F204AA1C0010EF00B -:10805000EAF968688030807C09F0C8FC002804D107 -:108060004C4844A124300EF0DEF909F0EEFC002863 -:108070001DD068688030807CFFF77AFE69784018F0 -:10808000687041484038806D4030417A01290DD1F7 -:108090002670696849886180807A20710120B877EC -:1080A000207F102801D0282800D1267726756978EE -:1080B00000290AD06868428833484038C286018760 -:1080C000012000E001E0B8746E700AF029FA00287F -:1080D00005D1207D002802D0A878FAF7F9F8F8BD7C -:1080E000F8B50446FFF765FF274D0026203DA87E22 -:1080F000002808D0667010202070E87EA070287FCD -:10810000E070AE769AE0204F403F3878002808D0E3 -:108110002C22B91C20460EF008F80E2020703E706C -:108120008CE0A87B184F002815D0387F102808D085 -:10813000282806D0002804D0FF200EA1C2300EF05F -:1081400072F90120E070E87BA070287C60700F203D -:108150002070AE7372E00121204609F099FC0028DE -:108160001AD0387D002857D10021204609F090FC14 -:10817000F8BD00007372635C6C6C5F6374726C2E8C -:1081800073302E630000000094090020720000206C -:108190004F02000062070000A97CF8480090F848F0 -:1081A000002910D0017805290DD2491C0170667094 -:1081B0000D202070012028750622A01C00990DF0CA -:1081C000B4FFAE743AE0EE480670B879002812D0D9 -:1081D000387F002804D00120EA4940020EF023F93C -:1081E00066700120E54920700A221431A01C0DF0B0 -:1081F0009CFFBE7122E020460CF083F800281DD1C0 -:10820000A87C002802D0DE480178CEE7A87F0028AD -:1082100002D0387D002801D00020A9E7387F00284F -:1082200003D0D849D8480EF0FEF866700A202070B6 -:1082300006223946A01C0DF078FFAE77012097E7A3 -:108240004EE710B5CD4C343C2178002904D01321E1 -:108250000E2000F052FF10BDC9490088091D08F02A -:10826000EFFD002801D0022007E0C5484068014624 -:1082700020318A79012A02D00C20207105E00022E9 -:108280002271097E21724088E080012060711321F3 -:10829000E1700E21A170207010BDB84810B53438BF -:1082A0000178002904D024210E2000F026FF10BD03 -:1082B000012101702422C2700C220271417110BD93 -:1082C00070B5AE4C0546343C2078002804D03E21E1 -:1082D0000E2000F012FF70BD0AF03FF9002808D10F -:1082E0000AF03EF9002804D1A4480C30007F002891 -:1082F00001D00C2003E0287809F033FD0020207124 -:10830000012060713E21E170207070BD9B4810B566 -:1083100034380178002904D03C210E2000F0EDFE15 -:1083200010BD00210171012141713C22C270017018 -:1083300010BDF8B5914C343C2078002804D03B2186 -:108340000E2000F0DAFE13E70020A0710AF005F914 -:108350008A4E01250C36022802D0307D002840D0FC -:10836000874F694678688030807C09F073FA00286E -:1083700003D1844985480EF056F8307D002806D098 -:10838000A06D4030407A002801D0012600E0002690 -:1083900078688030807C09F029FB002804D17B4874 -:1083A000784908300EF03FF809F04FFB684031463D -:1083B000014316D07968FD2249882181217E400041 -:1083C000490849003143114001432176684600784D -:1083D000002802D00420014301E0FB200140217667 -:1083E000A5710020207165713B20E0702570BFE60B -:1083F00010B5624C343C2078002804D00E21084689 -:1084000000F07BFE10BD5E4906220831A01D0DF074 -:108410008CFE00202071012060710E21E17020701F -:1084200010BD70B5554C0546343C2078002804D06A -:1084300038210E2000F061FE70BD50480C30007FE6 -:10844000002807D00C202071012060713821E170D4 -:10845000207070BD287809F072FC28780CF05BF968 -:108460000020F0E770B5454D0446343D28780028DB -:1084700004D037210E2000F040FE70BD3F480C3084 -:10848000007F002801D00C200AE03D4E2188706852 -:108490004088884203D10AF060F8022807D0022001 -:1084A0002871012068713721E970287070BD7168EA -:1084B0007F2020310876487600208876A2788A715D -:1084C000E278CA7122790A72EAE710B52B4C343C83 -:1084D0002078002804D039210E2000F00EFE10BDB7 -:1084E0000AF03BF8032808D00AF03AF8032804D031 -:1084F00022480C30007F002801D00C2003E01F49E7 -:1085000000202C31C8712071012060713921E17087 -:10851000207010BD70B5194C0646343C20780028F8 -:1085200004D03A210E2000F0E8FD70BD0AF015F8E5 -:10853000032808D00AF014F8032804D00F480C30A0 -:10854000007F002801D00C2011E00C4D2C35E8797B -:1085500008280BD20001001910223146683000F0C3 -:10856000D6FDE879401CE871002000E0072020716A -:10857000012060713A21E170207070BD88090020EF -:108580006400002074810000210200001708000030 -:10859000F8B5FA4E04463078002804D03D210E206C -:1085A00000F0ABFDE4E5F5484030007F002801D045 -:1085B0000C2034E0F24D218868684088884203D15D -:1085C00009F0CBFF022801D0022028E06F68648800 -:1085D000FD883A896800B988401C844218D3E9486C -:1085E00041431046E84A50430DF019FE401EFF215A -:1085F00080B2F531884200D90846844200D2204634 -:10860000691C401C0DF00BFE6D1C6843401E85B2BA -:10861000E620C05D002800D1BD84F58000203071C7 -:10862000012070713D21F1703070A1E5F8B5D34C97 -:1086300005462078002804D035210E2000F05DFD8D -:1086400096E5CE484030007F002801D00C2016E08F -:10865000A878002801D0012804D1A888FF21F5318D -:10866000884201D912200AE0C54F298878684088DD -:10867000884203D109F071FF022807D0022020713F -:10868000012060713521E170207071E57968002664 -:108690000846C0310E70AA884A800122A0300271BB -:1086A000AA78012A00D000220A704079002801D05F -:1086B0000AF0DBFC2671E3E770B5B04C0546207884 -:1086C000002804D030210E2000F017FD55E709F0F6 -:1086D00044FF002804D1A9484030007F002801D081 -:1086E0000C2003E028780AF0E0FB00202071012034 -:1086F00060713021E17020703FE770B59F4C0546F6 -:108700002078002804D033210E2000F0F6FC34E756 -:1087100009F023FF002804D198484030007F00284A -:1087200001D00C2018E02978002911D00A290FD097 -:1087300014290DD01E290BD0282909D0322907D0A1 -:108740004B2905D0642903D0FF2901D0122003E072 -:1087500028460AF023FC002020710120607133219B -:10876000E170207009E770B5844C06462078251D1D -:10877000002804D032210E2000F0BFFCFDE6314677 -:10878000002009F0AEFA2870002805D17C480622A6 -:10879000314608300DF0C9FC012060713221E170D2 -:1087A0002070EAE670B5754C2178002904D031219B -:1087B0000E2000F0A2FCE0E600214156012504292C -:1087C00012D0002910D0081D0ED0001D0CD0001DA5 -:1087D0000AD0001D08D0001D06D00A3004D00A308F -:1087E00002D01220207103E0084606F079FD657181 -:1087F0003120E0702570C0E6FEB5604C0746207859 -:10880000002804D025210E2000F077FCFEBD38881A -:10881000694608F015FB594D01460020083500292E -:1088200004D002212171286028710FE00098009E79 -:108830000A30019060360020B07105222846019967 -:108840000DF073FCB0790028F5D13888E0800E2057 -:10885000A0702520E070012060712070FEBD10B571 -:10886000464C2078002804D005210E2000F045FC5D -:1088700010BD0020207108F008FFE08008F0D1FF53 -:108880002072012060710521E170207010BDF1B5EA -:108890003A4C2034A07B002804D010210F2000F097 -:1088A0002CFC65E4354D4035A8790C2610270028AE -:1088B00016D1287F002813D109F04FFE022824D1B9 -:1088C0002F4800994068098842888A421DD1014694 -:1088D000C0310A7A002A05D04030807F80070DD44D -:1088E000E6730EE05E22125C920707D406220A723B -:1088F000A0304079002801D00AF0B7FB2F77002084 -:10890000E07327740120A07332E40220F8E710B569 -:108910001A480178002904D00F210E2000F0EDFB49 -:1089200010BD00210171FF2181710021C943018126 -:1089300013490E310A7882728A8882814988C181FE -:10894000012141710E2282700F22C270017010BD90 -:1089500010B50A4C2078002804D02B210E2000F0FE -:10896000CCFB10BD0821A01D04F024FB00202071C9 -:10897000012060712B21E170207010BD540900208E -:1089800064000020C40900001027000070B5FA4DF3 -:1089900004462878002804D02A210E2000F0ADFBE0 -:1089A000EBE5F54810222146303800F0B0FBF248E4 -:1089B0001022A118203800F0AAFBEF4830380CF044 -:1089C000BCFBED49102210392C46A81D00F09FFB7E -:1089D000002020710E20A0702A20E070012060711C -:1089E0002070CAE5F8B50546E348E34C40300090F6 -:1089F000007F0C2628272034002801D0E6733EE0B3 -:108A0000A07B002804D028210F2000F076FB04E48E -:108A1000A87805280DD013280BD0142809D01528C4 -:108A200007D01A2805D0292803D03D2801D03B289B -:108A300003D12888D149884201D912201EE009F0CB -:108A40008CFD0228DAD1CE482A88406841889142BC -:108A500013D10146C0310A79002ACFD1AA784A71D0 -:108A600001220A710099A0300F770021E17340794B -:108A7000002804D00AF0F9FA01E00220E07327741C -:108A80000120A0735FE4F8B5BB4F064638783D1D62 -:108A9000002804D017210E2000F02FFB53E43146AC -:108AA000012009F01EF901242870002807D1B248DE -:108AB00006226030314605460DF037FBAC717C7103 -:108AC0001720F8703C703EE470B5AB4C0646207839 -:108AD000002804D00B210E2000F00FFB4DE509F01B -:108AE0003CFD032808D009F03BFD032804D0A24830 -:108AF0004030007F002801D00C2016E03378002B96 -:108B000003D0012B01D012200FE09B4DE035297AD4 -:108B1000082909D22846721C0C3006F097FB287AE7 -:108B2000401C2872002000E00720207101206071A5 -:108B30000B21E170207020E510B58F4C20780028C3 -:108B400004D00A210E2000F0D8FA16E709F005FD3E -:108B5000032808D009F004FD032804D086484030DB -:108B6000007F002801D00C2002E000F0BFFA0020B6 -:108B70002071012060710A21E1702070FDE610B5BE -:108B80000AF032F9002803D07E497F480DF04BFCF3 -:108B900008F04BFD0BF051FC002804D01720794958 -:108BA00040010DF040FC08F0ACFF002804D0B920D3 -:108BB000744980000DF037FC00F098FAFFF7F2F8E6 -:108BC0006D4800210171012141710222C2700170C2 -:108BD000D3E610B5684C2178002904D020210E205E -:108BE00000F08BFAC9E601781F290ED8411C0CD081 -:108BF000002121710278411C104609F08FF80120F4 -:108C000060712021E1702070B7E612202071F6E734 -:108C1000F8B5594C2178002904D01B210E2000F012 -:108C20006CFABFE401216171534E0C212171403671 -:108C3000317F00296FD10078514F0025012804D0E1 -:108C400000284AD01220207165E009F086FC002837 -:108C500003D109F085FC002804D009F07EFC02282D -:108C600022D058E008F08FFF002854D0307D002833 -:108C700051D1786801224580032108F0B4FB78685F -:108C800009F05AF97868923008F001FD002803D104 -:108C90003C493E480DF0C7FB0AF00BF9002839D0DB -:108CA00085203849C00015E009F05AFC002832D16F -:108CB000707F00282FD001282DD004282BD008F059 -:108CC00062FF002827D00AF0F4F8002822D02F48AD -:108CD0002C4918300DF0A7FB1CE009F03EFC0328DE -:108CE00004D009F03DFC03280FD014E000200AF066 -:108CF00005F800280FD12571307D00280BD1786848 -:108D00008030807CFFF734F805E0002009F0F6FFA2 -:108D1000002800D125711B20E0700120207041E463 -:108D200010B5154C2178002904D01A210E2000F02E -:108D3000E4F922E601781F290ED8411C0CD000214D -:108D400021710278411C104608F0FDFF012060717E -:108D50001A21E170207010E612202071F6E770B53C -:108D6000054E044630780C25002811D018210E201D -:108D700000F0C3F9AAE4000054090020FF0E00002F -:108D80006400002074810000D3020000240400006D -:108D900009F0E3FB03285AD009F0E2FB032856D080 -:108DA000E14A107F002852D16079002801D00128C3 -:108DB0002DD1A079002801D0012828D1A07B00283E -:108DC00005D0012803D0022801D003281FD1607BE1 -:108DD00000281CD0C0081AD161880120800381427C -:108DE00002D82388834203D9207901280FD119E0C2 -:108DF0002079002806D0012814D0022805D00328A5 -:108E000005D102E020290BD30CE0A02B0AD2207957 -:108E1000042805D12088202802D36188884201D9FE -:108E2000122514E0207950776079002802D00128BB -:108E300003D00CE0BD4A002105E0BB4A2032907906 -:108E4000002804D00121204608F0CEFE054601206E -:108E5000357170711821F170307037E470B5B24C13 -:108E60000546403C2078002804D02E210E2000F03A -:108E700044F92BE409F071FB0C22022815D1AA4811 -:108E8000007F002811D1A9482B88083841684888FC -:108E900083421AD10846C030037A002B05D1203115 -:108EA000C97E0F2903D0102901D0227103E00521CA -:108EB0000172002020710E20A0702E20E070288802 -:108EC000E08001206071207016E40220F2E770B5A6 -:108ED000954C0546403C2078002804D02D210E20DA -:108EE00000F00BF908E409F038FB0C21022814D13A -:108EF0008D48007F002810D18C4E2A88083E70686B -:108F000043889A4220D1C822125C002A05D13B2214 -:108F1000125C0F2A03D0102A01D021710AE010221E -:108F2000A91CD6300DF001F970680421C03001721F -:108F3000002020710E20A0702D20E0702888E08095 -:108F40000120607120700DE40220F2E710B5017875 -:108F50000B000DF059FB3F9E9E399E9E599E9E9E92 -:108F60009E3C3F9E9E8752559E9E999E9E9E432963 -:108F70009E2D319E9E9E9E359E9E9E955C9E9E47FA -:108F80009E4B4F9E21259E6C6064689E709E7F83E1 -:108F90007C788A8D74919E00801CFFF798FF76E0A4 -:108FA000801CFFF75BFF72E0801CFFF7D8FE6EE0CD -:108FB000801CFFF7B5FE6AE0801CFFF729FE66E023 -:108FC000801CFFF706FE62E0FFF7D9FD5FE0FFF7C8 -:108FD000B3FD5CE0801CFFF777FD58E0801CFFF7D5 -:108FE00052FD54E0801CFFF7FDFC50E0801CFFF7B1 -:108FF000CDFC4CE0FFF7ACFC49E0FFF788FC46E015 -:10900000801CFFF744FC42E0FFF729FC3FE0801C96 -:10901000FFF7F2FB3BE0801CFFF7C4FB37E0801C4E -:10902000FFF7A1FB33E0801CFFF767FB2FE0801CFC -:10903000FFF742FB2BE0801CFFF7F8FA27E0801CCB -:10904000FFF7A6FA23E0801CFFF764FA1FE0FFF7A2 -:109050003CFA1CE0801CFFF705FA18E0801CFFF7C3 -:10906000E0F914E0FFF7C4F911E0FFF762F90EE050 -:10907000801CFFF74BF90AE0801CFFF721F906E09E -:10908000801CFFF70AF902E0801CFFF7DAF80120E4 -:1090900073E4002071E470B52349244C054640393F -:1090A000083C0A460126403260682B000DF0ACFAFD -:1090B00005171A1A04171A000122002108F093F963 -:1090C000616800220846C0310A724A7209F067FFDF -:1090D000002803D016A11B480DF0A5F960E4167511 -:1090E00088655DE4174812A13330F5E70E4900208A -:1090F000C031C8612039087270470B4A203A937E0C -:10910000002B03D1D076117701209076704730B5CF -:10911000134606E0CC18203CE47FD51A44555B1E6C -:10912000DBB2002BF6D130BD940900206C0000208A -:109130007372635C6C6C5F6374726C2E73302E633D -:10914000000000005108000070B5FD4D040008D07B -:10915000012C10D0022C07D0032C05D0F9A17020CF -:1091600007E0F8A1672004E02878012803D0F5A1E2 -:109170006D200DF058F92C7070BD70B5F04D04469F -:1091800010280AD0112C16D028468178122C07D02E -:10919000132C0AD0EBA19F200BE0EAA1942008E059 -:1091A000112908D0E7A1992003E0112903D0E5A1F6 -:1091B0009C200DF038F9AC7070BD10B5E04894B04B -:1091C000007B002819D0172069460870DC4900A8E8 -:1091D00006220D3102300CF0A8FF09A96846F9F704 -:1091E000C2FE0446112805D0002C03D0D5A1BB2017 -:1091F0000DF019F9204614B010BD3220E4E710B587 -:1092000001220023114603F0B5FC10BDFFB595B057 -:109210001D460E460746FFF7F2FF04000AD02078ED -:10922000222804D3A07F8006C00FA84204D10820C2 -:1092300019B0F0BDC748FBE7372168460170478089 -:10924000002D05D00121017146711799817102E04D -:1092500000206946087109A96846F9F784FEA07FD5 -:10926000DF21084069010843A0770020E0E770B5DE -:109270000446084620380D4603000DF0C5F90A06DD -:109280000A11232C334249505761FF20ADA1083009 -:1092900052E02078202851D1FF20AAA10B304BE0CA -:1092A000A7480178032949D08078132846D0207830 -:1092B000242843D0252841D023283FD0FF20A1A136 -:1092C0000E3039E02078222838D0232836D8FF20E5 -:1092D0009CA1153030E0207822282FD0FF2099A1C2 -:1092E000193029E02078222828D0242826D02628C2 -:1092F00024D0272822D0292820D0FF2091A11C305B -:109300001AE02078252819D0FF208EA1233013E001 -:109310002078252812D0FF208AA126300CE0207862 -:1093200025280BD0FF2087A1293005E020782828A8 -:1093300004D0FF2083A12C300DF075F8257070BD8E -:10934000FF2080A12F30F7E730B5834C0B88834A8C -:10935000022801D0934204D09D1FA54225D20228A5 -:1093600002D04D88954203D04D88AD1FA5421CD236 -:109370004C88A34219D88B88FF25F435AB4214D80A -:10938000022802D0C888904205D0C888724D0A3899 -:109390002D1FA84209D2C888904208D0944206D016 -:1093A0005B1C63438000834201DB072030BD00204B -:1093B00030BDF0B56A49884245D36A4A0125AD04FB -:1093C0001368A84201D398423DD30279002A06D0FF -:1093D000082A02D8067B082E05D90720F0BD047B99 -:1093E000002CFAD0F6E7002A06D004688C422AD373 -:1093F000AC4201D39C4226D3002E06D084688C4216 -:1094000021D3AC4201D39C421DD300240CE005685B -:10941000A700ED598D4216D30127BF04BD4201D3E9 -:109420009D4210D3641CE4B2A242F0D80022012570 -:10943000AD040CE084689700E4598C4203D3AC423D -:1094400003D39C4201D21020F0BD521CD2B29642EE -:10945000F0D80020F0BDFFB50022099B002802D003 -:10946000994205DC58E0002902D1002004B0F0BD8B -:109470000920FBE7845C002C12D087187D78112D21 -:1094800043D010DC2B000DF0BFF80A401726262C25 -:109490002C2E2E363640835C002B30D1521CD2B29B -:1094A0008A42F8DBE1E71C2D2FDA123D2B000DF08C -:1094B000ABF8042C2C121A2C022CD9D1BB78039CAB -:1094C000072B237001D25B0701D40A20CEE7029B51 -:1094D00001241B7816E0E343DB0708E0012C08D0E9 -:1094E00013E00620C2E70F2523072D075B19002B89 -:1094F000F4D03046BAE7029B1B789C0701D50B20BD -:10950000B4E702242343029C2370835C521C9A1804 -:10951000D2B28A4202DDABE7192676028A42A9DB83 -:10952000A3E710B504780B46002C1FD001210E4A8A -:10953000012C1ED0022C22D0032C2AD125E00000C1 -:10954000740A00207372635C6761705F636F726599 -:109550002E630000023000007B0C0000FFFF0000C3 -:109560000080010028000020023200000021197054 -:1095700011E019708179890903290AD10BE019706A -:1095800081798909012904D105E019708179890956 -:1095900001D0104610BD411C0622581C0CF0C5FD20 -:1095A000002010BD08B51346002806D0FEA00068B4 -:1095B000009048796A468009105C18700622581C91 -:1095C0000CF0B3FD08BD30B50C46097895B02229E2 -:1095D00002D2082015B030BD282369460B704880A0 -:1095E000132A03D03B2A01D00720F3E708460A716B -:1095F00009A9F9F7B8FC050003D121212046FFF79E -:1096000036FE2846E6E700B595B0232369460B7081 -:109610004880108888805088C880D0884881908889 -:10962000088100208881C88109A96846F9F79BFC58 -:1096300015B000BD70B50C00064610D0FFF7DFFD79 -:10964000050003D1D949DA480CF0EDFEA68028893F -:10965000E0802889208168896081A889A08170BD07 -:1096600070B50E46050003D00021092003F027FF46 -:109670000120D04C022E207324D0032E04D0CC48DD -:10968000CA491E300CF0CFFECA4806210D3003F047 -:1096900091FCA07C8006800EA074FFF78EFDA08B4D -:1096A00000280ED0002D0CD08300012200210920BB -:1096B00003F060FE092804D0BD48BC4928300CF0F6 -:1096C000B2FE70BDBB480321103003F073FCA07CD8 -:1096D00040218006800E0843A074B6480C3002F08A -:1096E00015F9DAE77FB501A9012003F0C3FA0028D4 -:1096F00004D0AF48AD4967300CF095FEAE4E01A8DE -:1097000003F0C6FA050002D0052D4CD048E0029CBB -:10971000A07F01072CD520462230009068462346C2 -:10972000628E80882146343301F07BFA0546A07FA3 -:10973000F7210840A077002D05D0B5422FD09C48D6 -:109740009A49783029E0E17F480889074000C90F2D -:1097500008432021095D4007400FC9000843E07716 -:10976000207828281CD129212046FFF780FD17E00A -:109770004007C4D568462246808821460E32FFF74E -:1097800042FF0546A07FFB210840A077002D07D0AF -:10979000B54204D08648854992300CF044FE00253D -:1097A000284604B070BD0020FBE7F8B5040004D1E2 -:1097B000ED207E4980000CF036FE7220207060683B -:1097C00008250178091F0B000CF01EFF11F90A3D56 -:1097D0005FF83D0EF8F83E3D3D3D3DF986F93D0010 -:1097E00073487249AA3074E087883846FFF707FD4E -:1097F000060004D16E486D49B2300CF014FE60785A -:109800000421284360706B4CA07F0843A07721217E -:109810003046FFF72CFDB07F8007800F012801D173 -:10982000801EA080384602F057FE3846FBF72AFE1D -:109830003846FAF7C6F93946022003F040FEB07FF9 -:10984000EF210840B077F8BD86883046FFF7D7FC97 -:10985000002804D156485549D0300CF0E4FD60682A -:109860008078012804D052485049D2300CF0DBFDFA -:1098700060688179304602F04EFF0028E3D06178BD -:10988000294361706168C880F8BD87883846FFF752 -:10989000B6FC060004D146484449E3300CF0C3FD51 -:1098A00060783946284360706068C088308160689D -:1098B0000089708160684089B081022003F0FFFD5B -:1098C0000020B075FFF70EFF0028DDD001203749DA -:1098D00080020CF0A8FDF8BD80783C2815D0002748 -:1098E000022815D00026002804D031482F49F8302E -:1098F0000CF099FD0021084603F0E1FD002107204E -:1099000003F0DDFD002E05D046E001270026F1E73B -:109910000126EAE76078284360702648817F294362 -:109920008177002F38D160688688304601F055F87D -:109930000546807F6168800889798000012900D010 -:1099400002210843A87760680622C08A28816068DF -:10995000008B68816068408BA8816068C079E87579 -:1099600061682846183008310CF0DFFB6068062279 -:10997000807B68706168A81C0F310CF0D6FBA87F53 -:109980008107890F304602F090FDA87F8007800F85 -:10999000012801D10748868006480178032913D0A1 -:1099A0008078132814D00BE00302FF0144950000D7 -:1099B00013030000740A0020023000000CE00FE0E6 -:1099C000FF20FCA1453084E70120FFF7BDFBF8BD77 -:1099D0001120FFF7D2FBF8BD204601F02AFCF8BDAC -:1099E000607828436070F8BDF7B505460078002719 -:1099F00000090C463E4601287ED00022F14902288B -:109A00007BD0072804D00A2878D0EAA1EE482DE1BF -:109A1000686803780D2B31D006DC042B6FD0072B40 -:109A200036D00A2B6AD106E0122B38D0132B40D047 -:109A3000142BF7D1B2E011270726002C72D08088B2 -:109A4000A0806968FB238979A171E04905468A7F76 -:109A50001A408A77032103F0C5F80421284603F051 -:109A6000C1F80021284603F0BDF80221284603F082 -:109A7000B9F80121284603F0B5F8F9E001270926D5 -:109A8000002CDBD08088A080686880792072EFE0AD -:109A900012270E2680882146FFF7CCFDE8E01A2722 -:109AA0000726002CCAD04088A08068680079A07181 -:109AB000DEE081783C2936D010271E26002CBDD050 -:109AC0008088A0806868C08A20836868C08AE08235 -:109AD0006868008B60836868408BA0836968207D1C -:109AE000497F4008C9074000C90F084320756968CD -:109AF000C007C00F497F03E05FE08AE0ADE01CE0F3 -:109B000049084900084320756968A21DC8790831D1 -:109B1000FFF748FD69682246887B0D320F31FFF759 -:109B200041FD05E074E019270726002C70D0A271D2 -:109B3000A648F722817F11407DE01B272E26002CAE -:109B400066D0A1806968A21D0879491DFFF72AFD2A -:109B500068682030C07A60736868C0780428A07B89 -:109B600019D040084000A073F921084069681F22FD -:109B7000C9788907490F0843A07369684007C97A03 -:109B8000400FC9000843A073696820460F300C31AC -:109B90000CF0CBFA6CE001210843E4E71E270E2607 -:109BA000002C6DD0A1806868E21D407AA0716968C0 -:109BB0008878C91CFFF7F6FC5AE0287A012805D0FE -:109BC000022815D080487BA132384FE01D270E2691 -:109BD000002C55D06888A080A889E080E889208181 -:109BE000288A6081688AA0817848DF22817FA2E785 -:109BF00012270E266888FFF71DFD002C40D06878DC -:109C00004007400F032833D17048FD22817F92E73F -:109C100036E0287A03000CF0F7FC06041010202030 -:109C2000202619270726002C2AD0A1806748A27178 -:109C3000817F4908490081771AE019270726002CFF -:109C40001ED0A180287A012805D00320A0715F488A -:109C5000EF22817F6FE70220F8E721462846029A2B -:109C600001F04BFCFEBD532052A100010CF0DBFBC8 -:109C70000298002C068001D0278066800020FEBD5F -:109C800002980680FAE710B5504894B080781328FF -:109C900002D0082014B010BD22206946087009A91E -:109CA0006846F9F760F904460021072003F007FC35 -:109CB0002046EFE700B5454895B08078122801D0DE -:109CC0000820B5E41E216846017000218170C17032 -:109CD00009A9F9F748F90028F3D10021072003F07A -:109CE000EEFB1120FFF749FA0020A1E400B5374848 -:109CF00095B00078022801D0032818D11B2108A8AC -:109D000001730021817369460BA8F9F72CF900282B -:109D100004D1684640781B2801D0032088E4002144 -:109D2000084603F0CCFB68468078002801D0082064 -:109D30007EE40120FFF708FA002079E4F8B5234C0F -:109D400003000CF061FC0A068017808080804B3590 -:109D50006E80FFF7CBFF00282AD1F7F7E9FD002836 -:109D600026D02221017000210172F7F7C2FDA07FE9 -:109D7000012152E08EB23046FFF741FA050004D1CE -:109D800011480CA12E300CF04EFB287821280FD062 -:109D9000F7F7CEFD00281BD01221017002270772B1 -:109DA00046800020A875F7F7A4FDA07F3843A07770 -:109DB000F8BD00007372635C6761705F636F72650A -:109DC0002E630000FFFF000036050000740A00202B -:109DD000132229463046FFF7F6FBE9E7A578122D56 -:109DE00006D0132D07D0FA49FA480CF01CFBDFE728 -:109DF000FFF760FF01E0FFF746FF0028D8D1F7F733 -:109E000097FD0028D4D022210170122D07D0022105 -:109E10000172F7F76EFDA07F10210843C7E701210B -:109E2000F6E7A07C810901290BD0800904D0E9481C -:109E3000E74922300CF0F7FA03210020FFF710FC6D -:109E4000B6E70221F9E7E348E1492930CDE7F7B564 -:109E500014460D0004D1DF48DD4931300CF0E3FA3F -:109E600028780827012807D002281FD0D948D849C8 -:109E700062300CF0D8FAFEBD0098FFF7C0F906007A -:109E800004D1D448D24938300CF0CDFA0220B07554 -:109E90001030207060783843607007CD083407C4F4 -:109EA000CD482022817F11438177FEBD0098FFF7C6 -:109EB000A6F9060004D1C748C54946300CF0B3FAEC -:109EC000A988C648814208D1EA88824205D1132276 -:109ED00031460098FFF777FBFEBD814202D1E8884A -:109EE000002809D01220207060783843607007CDB8 -:109EF000083407C4002006E07823002202200099DD -:109F000003F038FA0120B075FEBDB34840897047B0 -:109F1000FFB591B01498F8F721FF00285DD1012416 -:109F2000684603218471C9028180002201A920466C -:109F3000FAF719F9002850D16846152184714902B1 -:109F4000818000261C2102A800960CF04DF901200A -:109F50000146684610310170002001466846417094 -:109F60008178F9273940891C21438170017A0225C3 -:109F70002943017212998186C6861F2101870C90A0 -:109F800011980F9001A80B9009AA0BA902A8F9F744 -:109F9000B5FE002821D168468F4E808CF08068463F -:109FA00084718F498180807809AA3840801C4108DB -:109FB0004900684681708586058713A80F900BA914 -:109FC00002A8F9F79BFE002807D16846808C3081F3 -:109FD00031460A311498F8F7D4FE15B0F0BD30B50B -:109FE0000C46804995B08C4241D37F4901229204AE -:109FF0000968944201D38C4239D3203800220125CC -:10A0000003000CF001FB06042F494D535C64002152 -:10A01000082003F02EFA002802D0112015B030BD20 -:10A0200024206946087000A80522A11C02300CF00B -:10A030007CF809A96846F8F796FF050002D0082DBC -:10A040000ED031E0082300221146184603F092F9A1 -:10A05000082829D05F485E49D6300CF0E4F923E0A7 -:10A060000620DBE76068002803D0884201D2102078 -:10A07000D4E73D2168460170218841806188818054 -:10A0800009A9F8F770FF05000ED1606800280BD011 -:10A090006946098D018007E0206801F079FC02E043 -:10A0A000204600F0D8FC05462846B7E73E2007E0EA -:10A0B000857000E0827009A9F8F755FFF3E73420B6 -:10A0C000694608702078C0076846F3D0F0E707209B -:10A0D000A4E730B50C46444995B009688C4201D2DA -:10A0E00010209BE7203803000CF08EFA0504212194 -:10A0F000232132002088FFF782F8002804D000785E -:10A10000222803D2082089E7384887E725216846B6 -:10A1100001702188418009A9F8F725FF050015D1B4 -:10A120000AA905220231A01C0BF0FFFF0EE0062554 -:10A130000CE02068002805D0884201D2102505E0F7 -:10A1400001F01BFC24480025808BA080284665E791 -:10A15000072063E720481330704710B520211E48C0 -:10A160000CF040F80120FEF7EFFF1120FFF705F893 -:10A1700000211948C943818000218176E1218900AD -:10A18000818301460C300D310446F7F751FC12482B -:10A190000722214613300BF0C8FFFFF70EF8002806 -:10A1A00003D00B4912480CF03EF900F0D5FF10BD6A -:10A1B00010B504463C210CF015F8A07F8008800003 -:10A1C000A077202020700020A0752034607010BD82 -:10A1D000B49D00008C050000740A0020FFFF000001 -:10A1E000012A000000800100280000200230000049 -:10A1F000FB0600007047FEB50546FF480C4681424D -:10A2000007D301208004844205D3FC4800688442BF -:10A2100001D21020FEBD002D02D0012D32D126E04A -:10A22000F74908220F4668460BF07FFF3946204663 -:10A23000FFF777F90028EDD1FEF7BFFF060006D043 -:10A240000722694638460BF070FF3046FEBD207885 -:10A25000002801D0012805D1E94807223946C01D50 -:10A260000BF063FF0021092003F029F90FE00978C2 -:10A27000002907D0012905D0022905D0032903D0E0 -:10A28000E048FEBD0720FEBD0120FFF7E9F9DC48EC -:10A290000C3885760020FEBD10B5D8490968884283 -:10A2A00001D2102093E7D64902460C390B7B0D31C1 -:10A2B0001846FFF777F9002089E7FFB599B0054602 -:10A2C000002069460871087208A9087408751446C8 -:10A2D000CA480122C849920400681E46002D05D0D4 -:10A2E0008D420BD3954201D3854207D3002C08D071 -:10A2F0008C4203D3944204D3844202D210201DB076 -:10A30000F0BD2846204318D01F270CAB01AA0097A8 -:10A3100028461A99FFF79FF80028F0D10DAB02AA42 -:10A32000314620460097FFF796F80028E7D16846A7 -:10A33000007AC10703D00A20E1E70720DFE78007A2 -:10A3400005D568460079800701D50B20D7E703AF14 -:10A35000002D0FD01A20694608731A988873294671 -:10A36000F81C1A9A0BF0E1FE0EA903A8F8F7FBFD02 -:10A370000028C4D1002C0ED02021684601738673BA -:10A3800032462146F81C0BF0D0FE0EA903A8F8F7C0 -:10A39000EAFD0028B3D19A4908A8007C0C3948701E -:10A3A0000020ACE770B504460A2020700D46204618 -:10A3B000F8F7D9FD002805D139202070294620461C -:10A3C000F8F7D1FD70BDF7B500260C4605460B2702 -:10A3D0001AE02968B00009580978002903D001293A -:10A3E00001D00720FEBDA170296806220958E01C93 -:10A3F000491C0BF09AFE277020460299F8F7B3FD2E -:10A400000028EFD1761CF6B22879B042E1D80026B8 -:10A410003A270FE0A868B10041581022A01C0BF0A9 -:10A4200084FE277020460299F8F79DFD0028D9D1B7 -:10A43000761CF6B2287BB042ECD80020FEBDF0B509 -:10A44000044671A003C897B06B4B00271591149078 -:10A450009C4211D369480125AD040268AC4201D386 -:10A46000944209D32078012809D16168994203D325 -:10A47000A94204D3914202D2102017B0F0BD604926 -:10A480000C390A78012A0CD18A88614B9A4203D090 -:10A49000002806D0012804D08A7F13079B0F06D11D -:10A4A00001E00820E9E7D30701D1910701D5112088 -:10A4B000E3E7218A574B0A46203A9A4207D30128FC -:10A4C00075D1002973D1628A002A70D111E0022867 -:10A4D00001D0032801D1A02969D3012809D0484A15 -:10A4E0000C3A5278D20704D0628A002A5FD0B42A8C -:10A4F0005DD8002806D0012808D0022804D00328FF -:10A5000055D117E0002518E0022516E0002902D1F8 -:10A51000608A00280CD004256068007800280CD0E0 -:10A52000012809D0022807D0032805D03548A4E720 -:10A530000125F1E7032500E00127207A002806D055 -:10A54000012806D0022806D003287CD105E0002689 -:10A5500004E0012602E0022600E00326002D01D0DF -:10A56000022D14D1002E12D0E068FEF722FF002841 -:10A5700083D123480C384078800702D02148401E00 -:10A580007BE7022D03D1022E5DD0032E5BD0182174 -:10A5900068460170218A4180218A8180857118482E -:10A5A0000C38007B002803D001286FD104E04AE07A -:10A5B00000216846C17102E001206946C871684601 -:10A5C000077221780930012937D006210BF00AFEE5 -:10A5D00069460E74207D8207C107D20F4007C90F5C -:10A5E0005200C00F11438000014314A8405C69462B -:10A5F000C873002827D00FE0008001002800002049 -:10A60000800A002002320000070605040302010050 -:10A61000FFFF0000E13F000009A96846F8F7A3FC2E -:10A62000002884D109A96846FFF7BCFE0028A7D1FD -:10A63000002D0AD0022D08D010E061680622491CC6 -:10A640000BF073FDC4E7072017E7002E06D009AA18 -:10A650006946E068FFF7B7FE002891D11B206946E4 -:10A6600008700120887009A96846F8F77CFC00286A -:10A6700086D108A840791B2819D12B000BF0C4FF04 -:10A680000504040707040A00032001E00FE002208C -:10A69000FEF75AFD012D0CD0608A002809D0002257 -:10A6A00083001146104602F065FE002801D0032009 -:10A6B000E3E60020E1E6F3B5032687B00D46002966 -:10A6C0000AD0FA4885426FD301208004854203D323 -:10A6D000F7480068854267D30798FEF790FD0400AD -:10A6E00005D02078222804D2082009B0F0BDF14816 -:10A6F000FBE7A07F8707BF0F002D05D0294638460E -:10A70000FEF722FE0600F0D139460027EA4801296B -:10A7100007D0022931D0E949E9480BF084FE3046E0 -:10A72000E3E7A27D2946012A02D0827F920701D564 -:10A730001120DAE700291BD108216A46049711820B -:10A740000592418904AADF48FAF7FDF80028CCD128 -:10A750006846008A082801D00320C6E768460188B9 -:10A7600001814188418181888181C188C18102A99B -:10A77000079801F061FF0646D1E7A17D022916D1B5 -:10A78000807F800613D4002D04D0A07F40070CD416 -:10A79000002100E00121079801F08FFF0600BED1E3 -:10A7A000A775002DBBD004E01AE01126B7E7002DF5 -:10A7B00016D02A4621460798FEF725FF064611289F -:10A7C000ADD1A07F4007AAD42046082229460E30EA -:10A7D0000BF0ABFCA07F04210843A07700269EE786 -:10A7E000102082E770B50C460546FEF708FD010013 -:10A7F00004D022462846FEF7E6FE70BDAD4870BD87 -:10A8000000B50146143195B0192901D2810707D04E -:10A8100001461E3104D00A3102D0072015B000BD18 -:10A82000312269460A70887009A96846F8F79BFBCF -:10A83000F4E701B582B00220694608809E4802AB69 -:10A8400000896A460021F9F7E7FE6946098802296E -:10A8500000D003200EBD1CB50021009102216A46E4 -:10A860001180934901900968884201D210201CBDD3 -:10A87000914801899348FAF766F8694609880229E0 -:10A88000F5D003201CBDF0B50E46884985B01746AB -:10A8900005468E4207D386480122920400689642FC -:10A8A00004D3864202D2102005B0F0BD1F2F01D97B -:10A8B0000C20F9E7804C8D4226D3954201D3854286 -:10A8C00022D3E08803A9F9F758FE0028ECD12878B4 -:10A8D00069464873E08803A9F9F730FE0028E3D100 -:10A8E0006946009008780221084369460870497B50 -:10A8F000090703D00821084369460870E0886946C3 -:10A90000F9F7B5FD0028CFD169468F80E08833463E -:10A9100001AA0021F9F780FE69468988B942C3D0AF -:10A920000320C1E71CB50C4600210091019122884B -:10A9300069460A805E4901900968002801D0884272 -:10A9400001D38C4201D210201CBD002801D0002A66 -:10A9500009D059486A46C1885A48F9F7F4FF694650 -:10A96000098821801CBD0C201CBD10B50123FEF7F9 -:10A970004DFC2CE4002310B51A461946FEF746FCA0 -:10A9800025E430B505464A4895B000680C4681423A -:10A9900002D2102015B030BD2846FEF730FC00284A -:10A9A00007D00178222902D3807F800603D40820B3 -:10A9B000F0E74048EEE7132168460170458009A999 -:10A9C000F8F7D1FA0028E5D108AA0A2151567F29C3 -:10A9D00001D02170DEE70520DCE7F8B5012304464D -:10A9E0001A46194602F0C6F8074601231A46022104 -:10A9F000204602F0BFF8064601231A4604212046ED -:10AA000002F0B8F8054601231A460321204602F059 -:10AA1000B1F80446002F03D128492B480BF003FD61 -:10AA2000002E04D1AD20254980000BF0FCFC002D48 -:10AA300004D125482149801C0BF0F5FC002C04D1E1 -:10AA400021481E49C01C0BF0EEFC22213846FEF7BF -:10AA50000EFC3846F8BD10B50446006800280CD03E -:10AA60001249884207D301218904884205D310493D -:10AA70000968884201D2102014E400F071FFA08818 -:10AA80000D4CA083A07E01280DD10021092002F0E9 -:10AA9000F0FC002800D00120A17C8909012915D0F3 -:10AAA0000321FEF7DDFD002006E400000080010028 -:10AAB0002800002002300000740A0020B49D00002D -:10AAC000C6090000FFFF0000B30200000221E8E712 -:10AAD00030B5F74B9A4207D301239B049A4205D322 -:10AAE000F44B1B689A4201D2102030BD1578EB065A -:10AAF0005B0F042B07D85478072C04D39378102BC2 -:10AB000001D8A34201D2072030BDD3785B0702D41D -:10AB100013795B0701D5062030BDC37FAC075B0806 -:10AB20005B00E40F2343C3770878EF2318401378C2 -:10AB30009B06DB0F1B0118430870F12318401378A4 -:10AB4000DB065B0F5B001843087050780873002029 -:10AB500030BD30B500240C70C378DB07DB0F0B7001 -:10AB6000C578AD07ED0F6D002B430B70C5786D07F1 -:10AB7000ED0FAD002B430B7014700179C907C90F9D -:10AB8000117003799B07DB0F5B001943117000798B -:10AB90004007C00F80000143117030BD70B51446EE -:10ABA0000D460646F6F7C4FE002809D0A221017022 -:10ABB000142221460830F6F707FBF6F79AFE70BD1F -:10ABC000132229463046FEF7FEFC70BD70B51446D0 -:10ABD0000E460546F6F7ACFE002809D0222101708A -:10ABE00045802178017261784172F6F782FE70BD6E -:10ABF000132231462846FEF7E6FC70BD10B5AE4C78 -:10AC0000207C00280CD1204621461038FDF762F840 -:10AC1000002803D0A9A1F2200BF005FC012020742C -:10AC200010BD70B594B015460C462C226946189E8E -:10AC30000A704880002B17D00822194601A80BF093 -:10AC400074FA68468581102231460E300BF06DFA99 -:10AC500009A96846F8F787F9002803D1A17F1022D7 -:10AC60001143A17714B070BD002001900290E8E775 -:10AC7000F0B50646008A97B080B20D460190FEF707 -:10AC8000BEFA04468C48317848380746E8370990C0 -:10AC90000B000BF0B9FC0EFCFB48085F8798B8D995 -:10ACA000FAF9F8F7F6FC002301221946019801F0A1 -:10ACB00061FF050004D1FF2080A130300BF0B3FB11 -:10ACC000002C04D1FF207DA131300BF0ACFB387E8D -:10ACD000C00904D078486030C06DA86112E02B2014 -:10ACE000694608720BA902A8F8F73DF9002804D0BC -:10ACF000FF2072A13C300BF096FB74490C980BF0CE -:10AD00008EFAA9617068A862B068E862A07F8007C7 -:10AD1000800F012820780DD0252804D0FF2067A1BE -:10AD20004D300BF080FB324621460198FFF736FF8D -:10AD300017B0F0BD2528F6D0222806D0242804D04C -:10AD4000FF205EA146300BF06EFB25212046FEF76A -:10AD50008EFAE8E7002301221946019801F00AFF64 -:10AD6000060004D1FF2055A158300BF05CFB002CED -:10AD700004D1FF2051A159300BF055FB2078252834 -:10AD800004D03078012108433070D1E702202870C8 -:10AD9000B068A860B068002802D000202871C7E71A -:10ADA0000120FBE72B2069460870434968464C396F -:10ADB000F8F7D9F8002804D0FF2040A178300BF034 -:10ADC00032FB03201BE02A206946087000A81022ED -:10ADD000023071680BF0A9F904A810220230B168A2 -:10ADE0000BF0A3F9344968464C39F8F7BCF8002851 -:10ADF00004D0FF2031A189300BF015FB042028700E -:10AE00000998686094E7B068002804D1FF202BA15E -:10AE100095300BF008FBE07F400704D5FF2027A109 -:10AE200096300BF000FBB06806220A3800903379A8 -:10AE30000421019801F0FBF90028A6D0FF201FA1F2 -:10AE40009B300BF0F0FA73E7002C04D1FF201BA11C -:10AE5000A3300BF0E8FA2046223010220546716834 -:10AE60000BF063F928212046FEF701FAA07F800746 -:10AE7000800F022814D100231A462146009501981C -:10AE800006E04BE1BAE0B0E095E03FE071E05FE161 -:10AE9000FFF7C7FE11281BD029212046FEF7E7F94E -:10AEA000E07F317A4007400FC9000843E0773FE771 -:10AEB0000080010028000020400B00207372635CBA -:10AEC0006761705F7365632E6300000040420F008E -:10AED000A07F000704D5FF20FD49B0300BF0A3FA96 -:10AEE000A07F08210843A0770020608620463430E8 -:10AEF0000BF078F9E07FFD220146C9071040890F69 -:10AF00000843E077307A2034207011E700230122D3 -:10AF10001946019801F02EFE040004D1FF20EC49EF -:10AF2000CD300BF080FA2B2069460872E94902A85F -:10AF3000F8F719F8002804D0FF20E549D2300BF0CB -:10AF400072FAE4488188204621300176090A417668 -:10AF50000E2129702146FC316960017E2974407EF2 -:10AF60006874DC482C30A860103030346C61E860C4 -:10AF7000DEE6002C04D1FF20D549E6300BF053FA71 -:10AF80002078212893D93079012802D0022808D1CD -:10AF900003E0E07F04210843E077387E0121084385 -:10AFA0003876324621460198FFF7F8FD23212046E6 -:10AFB000FEF75DF9BCE601220421019801F01FFCB7 -:10AFC0000028A2D0002301221946019801F0D2FDE9 -:10AFD000040003D1BE49C0480BF025FA0F202870A9 -:10AFE000172028716E34AC60A2E60421019801F0AC -:10AFF00056FC002889D11020287099E600230122F0 -:10B000001946019801F0B6FD050004D18720B0492A -:10B0100080000BF008FA2E462036307E41064DD5D2 -:10B02000A17F8F07BF0FC00713D029468031486F1B -:10B0300000280ED0027CF37DD207D20F5B001A43AA -:10B040000274486F5108E27F4900D207D20F1143C2 -:10B050000174307E000713D52A468032116F002913 -:10B060000ED0087CF37DC007C00F5B001843087446 -:10B07000116FE27F40084000D207D20F10430874DE -:10B08000307E80070BD5F8204259002A07D0012FC7 -:10B0900005D02946307C31311032FEF783FA307EFC -:10B0A000C0060BD5F8204259002A07D0012F05D140 -:10B0B0002946307C31311032FEF774FA0523684698 -:10B0C0000370357E4570834822216038019A0170F3 -:10B0D0004178C908C900C91C417042800372457299 -:10B0E000F6F78EFD2078252809D021280BD07A4844 -:10B0F00077495B300BF097F92078222803D9222179 -:10B100002046FEF7B4F80021019801F06BFD0028FD -:10B1100000D10DE670486E49633092E674686D4D5B -:10B1200020786035092802D00A28F2D10BE0E168C6 -:10B13000002902D02846F7F7E8FE2169002902D04D -:10B140002846F7F7E2FE21462846F7F7DEFEEFE550 -:10B1500061485F49883074E65E4810B504222821B2 -:10B160006030F7F7B9FE5B480024EC30017E4906F9 -:10B17000490E01764038C465FCF739FD55493C312C -:10B1800008461038F6F78BFC52484C30047410BD5A -:10B1900070B50D46FEF733F8040004D14E484C4913 -:10B1A000A7300BF040F9FF21053128460BF01CF8C1 -:10B1B000A07F8007800F01280CD00221284688300C -:10B1C000FCF716FD002804D043484149AC300BF091 -:10B1D0002AF970BD0121F1E70A46014610B5104673 -:10B1E0008830FCF71FFD10BD70B5054611200C46D8 -:10B1F0000870002161702121495D002908D00329D0 -:10B200000ED0042910D034483149C6300BF00BF968 -:10B2100020780009012802D9E87FC008607070BD5D -:10B220000007000F203002E00007000F30302070D0 -:10B23000EEE7F0B504464068082601789BB008297F -:10B240000DD00B2903D00C294BD1012181716068ED -:10B2500087883846FDF7D3FF05004CD147E0478883 -:10B260003846FDF7CCFF050004D1172018494001EE -:10B270000BF0D9F82878212833D0282833D16068FA -:10B2800002210C3000F050FF00282CD0606808210B -:10B29000001D00F049FF002825D02D2168460170CF -:10B2A000478029461022223101A80AF03EFF0FA94B -:10B2B0006846F7F758FE002804D007480449EF30E5 -:10B2C0000BF0B1F8A87F10210843A877292105E0E9 -:10B2D000BCAE0000F40A0020030200002846FDF77F -:10B2E000C6FF1BB0F0BD607830436070F9E7FE49DF -:10B2F000FE480BF098F8A87FEF210840A87729783E -:10B3000021290FD061688A79002A02D08978002922 -:10B3100012D08007800F022849D0F448F249343017 -:10B320000BF081F8FEF7DEF90028DAD0EF48EE499D -:10B330003F300BF078F8D4E7607830436070E87FF6 -:10B34000C00701D0042100E00321212041552878C5 -:10B3500029280BD03946062002F0B1F82878242895 -:10B36000E0D122212846FDF782FFDBE700230122FE -:10B370001946384601F0FEFB040004D1C920DA4921 -:10B3800080000BF050F825212846FDF770FF0D20B6 -:10B3900008A90871204609A98830FCF735FC022865 -:10B3A000C0D00028BED0D148CF491D30B8E7607862 -:10B3B00030436070B6E7F7B58AB015460646FDF72C -:10B3C0001EFF002841D0017822293ED323293CD0FA -:10B3D000C17F490739D4807F8007800F01280DD0B5 -:10B3E000002301220021304601F0C4FB0746C0487B -:10B3F0000290F7F781FD040007D101E00123F0E797 -:10B40000BA48B94959300BF00EF8002F1FD08837D1 -:10B4100067610298F7F770FD07460298F7F76CFD31 -:10B4200009212170266225710B99E760A1602061D6 -:10B4300003A92046FCF70CFC022806D0002804D003 -:10B44000AA48A94975300AF0EEFF0DB0F0BD002002 -:10B4500007466061E4E730B5002387B00546012266 -:10B46000194601F087FB04462846FDF7C8FE007820 -:10B4700022281BD9002C04D19C489B4981300AF01A -:10B48000D2FF0F21684601701721017120466E30EE -:10B49000029069461A30FCF7B7FB022806D0002854 -:10B4A00004D0E520904980000AF0BDFF07B030BD10 -:10B4B00030B5002387B005460122194601F05AFB3A -:10B4C00004462846FDF79BFE00782228EED9002C82 -:10B4D00004D18648844993300AF0A5FF10206946BC -:10B4E000087020468830FCF78FFB0028DED0E9206A -:10B4F0007D4980000AF097FFD8E7F7B50546007848 -:10B500000027000982B00C463E4602287ED007285C -:10B5100002D00A284AD14AE068680178082907D091 -:10B520000B2930D00C292ED070486F49D33060E100 -:10B5300014271A26002C6AD04088A080FDF75FFEF1 -:10B540000090002804D169486749AF300AF06BFFCA -:10B5500000980099C07DA21D1831FEF723F8686895 -:10B5600008228089E081696820461030091D0AF0B0 -:10B57000DCFD207E01210843F92108402076009857 -:10B580004021807F47E018270826002CD3D08088F0 -:10B59000A080FDF734FE050004D1F7205249800059 -:10B5A0000AF041FFA11D2846FFF71EFE23E1002CF3 -:10B5B00001D0288BA080287A01287DD0022804D0D1 -:10B5C00003282FD048494B4813E11C270726002C9D -:10B5D000B1D0A088FDF713FE0090002804D1FD2013 -:10B5E000414980000AF01FFF287B8007800F012857 -:10B5F000A07914D040084000A071FD210840297BAB -:10B600004907C90F49000843A07101E0E3E0DFE00A -:10B6100000988021807F084300998877EBE0012122 -:10B620000843E9E713270B26002C84D0A088FDF7F8 -:10B63000E6FD00900023A0880122194601F09AFA45 -:10B6400005460098002804D12A48274960380AF0A6 -:10B65000EAFE002D04D181202349C0000AF0E3FE58 -:10B660000098807F8007800F012859D0E86A817890 -:10B670008907890F0129A17954D049084900A1718E -:10B680008278FD255207D20F294052001143A17143 -:10B69000E322114002785207D20E1143A171DF223A -:10B6A00011404278D207920E1143A1710021E1713D -:10B6B000C1782172427900E037E00179607AD307DE -:10B6C00040084000DB0F18439307DB0F28405B0066 -:10B6D00018435207FB23D20F1840920010436072A8 -:10B6E000A07A4008400007E0BCAE00000E03000056 -:10B6F000540B002067040000CA07D20F10438A07CA -:10B70000D20F2840520049071043C90F1840890042 -:10B710000843A0720098007823286CD92621AFE056 -:10B72000A86AA4E701221143A9E7297BFE48022960 -:10B7300010D017270C26002C4AD0012911D003293C -:10B740001ED004291FD005291DD0F849F8480AF059 -:10B750006AFE23E019270726002C4CD00121A17195 -:10B7600005E00121A171E17989088900E171017E7B -:10B77000CA094906D201890E49000A4302760DE042 -:10B780000220A07106E0687B0007000F8030A071E6 -:10B79000052918D0E07980088000E071A088FDF7C5 -:10B7A0002EFD05460078212825D0232804D0E04826 -:10B7B000DE490C300AF037FEA088002101F012FAB1 -:10B7C000222128465DE0E07980088000401CE4E703 -:10B7D0000498068015E0002C01D06888A080287AA3 -:10B7E000032828D004280FD005284DD0D048CF49B1 -:10B7F00064300AF018FE0498002C068001D02780DF -:10B800006680002005B0F0BD15270C26002CDFD087 -:10B810000023A0880122194601F0ACF9050004D1EB -:10B82000C348C2492A300AF0FEFD0622A11DA869BC -:10B8300009F0DCF9DFE716270726002CC8D0A0881E -:10B84000FDF7DDFC00900023A0880122194601F0DD -:10B8500091F905460098002801D0002D04D1B44884 -:10B86000B24938300AF0DFFD2878C00601D5022041 -:10B8700000E00120A071009800782328BBD927217F -:10B880000098FDF7F4FCB6E717270C26002C9FD094 -:10B89000A088FDF7B4FC00906D7A002804D1A4487C -:10B8A000A2494B300AF0BFFD0621A01D0AF09AFC08 -:10B8B0000020A071207A032108432072FB21084058 -:10B8C0000099C97FC907490F08432072680692D5BD -:10B8D000E07904210843E071A07AE90740084000BC -:10B8E000C90F0843E17A2A0749084900D20F1143DA -:10B8F000FD22AB07DB0F10405B001843A072E80687 -:10B90000C00F114040000143E17274E710B50446D6 -:10B91000807990B08009012804D04D20834900012E -:10B920000AF081FDFFF76AF90120694608707E4838 -:10B930000AA9A0380190201D0290601C0B90684657 -:10B94000FCF786F9002804D07948784987300AF056 -:10B950006AFD0322601C0B990AF0E7FB10B010BDD2 -:10B9600010B5714CA03C002805D00146102220469D -:10B970000AF0DBFB0120207410BD10B50446FFF770 -:10B980003DF969491022A03920460AF0CEFB10BDCE -:10B9900070B50025644C00281CD06649884207D346 -:10B9A00001218904884205D363490968884201D28C -:10B9B00010250DE0062109F003F9411C07D05A4972 -:10B9C0004039C865207E80210843207600E00725A5 -:10B9D000284670BD207E4006400EF6E7F3B50020F5 -:10B9E00089B00D46029000290AD0524885421CD3E6 -:10B9F00001208004854203D34F480068854214D358 -:10BA00000998FDF7FCFB060003D03078222815D1F9 -:10BA100002E04A480BB0F0BD002D08D1B07FC1094B -:10BA200003D08007800F022801D01020F2E7B07FFA -:10BA3000C10601D4000703D5002D01D00820E9E795 -:10BA40003948007EC00712D1F07F400701D50D2094 -:10BA5000E0E7002201231146099801F08BF8070066 -:10BA600005D0B07F8007800F022802D00BE01120A4 -:10BA7000D0E7002D07D02A4639463046FFF728F890 -:10BA800002900028C6D128488C38F7F735FA040010 -:10BA900003D126492A480AF0C6FC0A2020700998DA -:10BAA000206238468830A060B07FFB218007800F7D -:10BAB000012829D0002D4CD002202071381DE060D3 -:10BAC00038780007400F20743878C006C00F6074C3 -:10BAD000A07C2A788008D2078000D20F1043A0747F -:10BAE0000840F17F01AAC907490F0843A074A8784C -:10BAF000E07469462846FFF72CF8684600792075FF -:10BB000068460078607528E001202071207B2A7843 -:10BB10008008D2078000D20F104320730840297894 -:10BB20008907C90F89000DE0E00B0020BCAE0000C2 -:10BB300053040000008001002800002002300000B3 -:10BB4000630500000843207324213046FDF78FFB76 -:10BB50000BE0032020710520207325213046FDF7DE -:10BB600086FBB07F4006400EB07703A92046FCF765 -:10BB70006FF8022805D0002803D0FD49FD480AF0DF -:10BB800052FC029846E7FFB581B00A9D06461C4666 -:10BB90001746142128460AF027FB0B980021016064 -:10BBA000F8070ED0F44920680968884239D312306A -:10BBB00028602068143068602068A8600B982168AD -:10BBC0000160B80726D56068002803D0EA490968F3 -:10BBD000884226D3029900290AD0FC3600280ED0CC -:10BBE00031461030FDF79DFC00281BD1606810E045 -:10BBF000002816D0E86080366068B0670AE0FEF77B -:10BC0000A9FA0146072230460AF08FFAFEF7F6FF3E -:10BC1000DA48E860780707D5D749A06809688842FC -:10BC200001D21020EEE528610020EBE5FFB5D44AF3 -:10BC30000E4607CA97B002AB07C3002700970197CB -:10BC40001798FDF7DCFA050005D02878262804D0DF -:10BC500008201BB0F0BDCB48FBE700231A4619466D -:10BC6000179800F087FF040004D1C248C049803013 -:10BC70000AF0D9FBA87F8007800F1690012814D006 -:10BC8000022824D0BB48BA4999300AF0CCFB0121E4 -:10BC90000022852E31D01EDC002E26D0812E26D00B -:10BCA000822E26D0832E1ED125E0002EEFD12146F4 -:10BCB0002846199AFEF70CFF0028CAD119988078F7 -:10BCC000009019980078C007C00F0190DFE719981D -:10BCD000002808D1DBE7862E11D0882E11D0892EBE -:10BCE00011D08A2E11D00720B3E710460EE0084687 -:10BCF0000CE002200AE0032008E0052006E0062010 -:10BD000004E0082002E0092000E00A20002222715D -:10BD100001216A461176211D0791002801D020716A -:10BD2000FAE0169801280CD0A66AE06A02220121E6 -:10BD300010900020A0602846173002291AD0012157 -:10BD400019E0E66AA06A1090032030702078FB2387 -:10BD5000C006C00F7070B07801221840009BF370CD -:10BD60008008019B800018430221B0700020707190 -:10BD70003071DEE70021890009190861681C022A78 -:10BD800001D0012100E00021890009190861B07883 -:10BD90008007800F01285ED1109880788007800F7F -:10BDA000012858D110980079844610984079009065 -:10BDB000169801281DD0317908A801747179017590 -:10BDC00008A8027C6046024008A8007D009908404F -:10BDD000139010433FD06C491A98884207D3012131 -:10BDE0008904884215D364490968884211D2102019 -:10BDF0002FE70CAA0DA91998FEF7ABFE08A8007C46 -:10BE000061460840307108A8007D009908407071B3 -:10BE1000D6E720463C3021460090F031169801913B -:10BE2000022834D000211A9B20460C33FFF7ABFECA -:10BE30000028DDD12046503021460090F43116987C -:10BE40000191012825D0002120461A9B139AFFF763 -:10BE50009AFE0028CCD110988078400702D4E87F61 -:10BE6000C0072BD0169902A8012914D0109909787F -:10BE70004900405A21780907490F4900C8408707FF -:10BE8000BF0F2AD0012F14D0022F0FD113E00121B0 -:10BE9000C9E70121D8E721780907490F4900405A2D -:10BEA000109909784900C8408707BF0F032F04D0B5 -:10BEB00004E0022711E001270FE00227169801286D -:10BEC0000BD1B078FB210840E97FC907490F08432F -:10BED000B07020780007400F3070207810224008A2 -:10BEE000400020701099D2434978C907C90E114308 -:10BEF00008402070C00623D4022F21D0012F21D06A -:10BF00000020A061E0612062606220461830A060DD -:10BF1000E87F40084000E877204606A98830FBF714 -:10BF200073FE002806D0022804D06F2010490001BB -:10BF30000AF079FA25212846FDF799F9002088E6CC -:10BF4000032008E020460D211B300AF04BF9204663 -:10BF50001830A060042069460875E87F0121084375 -:10BF6000E87705AA29461798FEF730FED4E70000C7 -:10BF7000BCAE00008E05000028000020400B002011 -:10BF8000606701000230000000800100F0B587B05A -:10BF900015460E0004460DD06A48854207D301209D -:10BFA0008004854206D368480068854202D210208A -:10BFB00007B0F0BD2046FDF722F9070004D038781D -:10BFC000272803D00820F3E76048F1E700231A464A -:10BFD0001946204600F0CEFD040003D15C495D48BF -:10BFE0000AF021FA0020002E05D0022E08D0012EE2 -:10BFF00011D00720DCE701216A461171A06018E02A -:10C00000234618336946A360087110222946184652 -:10C010000AF08BF80DE021461831A16069460871DD -:10C02000A061E061206260620621284608F0C8FD38 -:10C03000A0612078C10714D0400840002070022081 -:10C04000694608702046183002907030FBF7DCFD1E -:10C05000022806D0002804D03E483D4923300AF08B -:10C06000E2F925213846FDF702F90020A0E770B576 -:10C0700094B00D460646002B02D0072014B070BDC8 -:10C08000FDF7BDF8040007D02078222802D3A07F56 -:10C09000400603D40820F1E72C48EFE7002D19D023 -:10C0A0002D216846017046801022294601A80AF019 -:10C0B0003CF8E07F297C4008C9074000C90F0843CD -:10C0C000E077297C40078906400FC90EC900084364 -:10C0D000E07703E02E2168460170468009A9684692 -:10C0E000F6F741FF694609782D2905D1002803D1CB -:10C0F000A17F10221143A177A17FBF221140A17718 -:10C10000BCE710B50C46FDF77AF8002805D00E49BB -:10C1100009688C4203D2102010BD0C4810BD214686 -:10C12000FFF762F8002010BD05E00278401C002AED -:10C1300001D0002070470A46491E89B2002AF4D176 -:10C14000012070470080010028000020023000001C -:10C15000BCAE00000F07000030B50346072903D02E -:10C160000820DA781C7916E00720FAE707290BD0B7 -:10C170005500ED186D79072D01D0401EC0B2521C3C -:10C18000D2B20F2A07D105E05500ED186D79072DC1 -:10C19000F3D0F4E700222546641EE4B2002DE5D179 -:10C1A00030BDFFB581B00C461646114620460A9FA9 -:10C1B0000B9DFFF7D1FF00280AD020790F2803D369 -:10C1C000FEA1A0200AF02FF9A078C00907D019E03D -:10C1D000072E02D0112005B0F0BDFD48FBE7019805 -:10C1E0002880381D6880002068712871EF800498CD -:10C1F00028812846F6F7DFFE002803D1EFA1AD2005 -:10C200000AF011F9E07821794018491CC0B2217177 -:10C210000F2801D30F38C0B2400000194671817950 -:10C22000F12249084900114081710020D3E7FFB590 -:10C2300083B01C4616460F4600231A4602210C9D69 -:10C24000039800F097FC010008D033463A46019568 -:10C2500000940398FFF7A5FF07B0F0BDDC48801EEF -:10C26000FAE7F0B5054616460F4650888DB0002314 -:10C270000122022100F07EFC040003D1CFA1DF20C7 -:10C280000AF0D1F8002069460871A078400603D171 -:10C29000CAA1E3200AF0C7F8042F5ED32A78D0079A -:10C2A000C017401C06D161786B78994255D121782E -:10C2B000090752D00121142A46DA012A42D0122A53 -:10C2C00002D0132A40D128E00C2F3DD1A27852068B -:10C2D000520E012A38D0207800090001401C20703D -:10C2E000687860706846017168792A7901021143A3 -:10C2F00068460181E879AA790102114368464181C3 -:10C30000687A2A7A0102114368468181E87AAA7A1A -:10C31000010211436846C1811AE0062F14D120782A -:10C320000009000120707188012001F0C8F8022185 -:10C3300068460171C91E018168792A790102114399 -:10C3400068461FE0062F0AD06A461279002A1BD0E1 -:10C350007088324601A9FDF77AFD0DB0F0BD207856 -:10C360000009000120707188012001F0A8F8022165 -:10C370006846017168792A79010211436846018192 -:10C380000021C9434181E3E70028E6D0748868466C -:10C3900081766978C176022181830021C18304A856 -:10C3A00005220090062311462046FFF740FF002893 -:10C3B000D3D088A1D6200AF036F8CEE7F7B58CB0F6 -:10C3C00015460C990D98F9F7CEF9C0B2082851D14D -:10C3D000002069468885688800230122022100F038 -:10C3E000C9FB040004D1FF2074A163300AF01BF8DC -:10C3F00001230021E07822790BE046003619767996 -:10C400009E4201D1491CC9B2401CC0B20F2800D1C4 -:10C4100000201646521ED2B2002EEED1002902D1C3 -:10C4200017206946888504AB02330BAA00950C9946 -:10C430000D98F7F73BFC0006000E07D002281BD032 -:10C44000032817D0FF205DA1893011E06846808D58 -:10C4500000280FD002A901910090688804230122CE -:10C460002146FFF79EFE002804D0FF2053A176301E -:10C4700009F0D9FF0FB0F0BD68781021084368704B -:10C48000F8E70020584902464300401CCA520828D9 -:10C49000FAD3704700218170017809090901017000 -:10C4A00000214170C1700171704770B50D460023C5 -:10C4B0000122022100F05EFB040004D1FF203FA115 -:10C4C000CF3009F0B0FFA0786906C009C001490E5D -:10C4D0000843A07070BD704710B50146012000F000 -:10C4E000EEFF10BD3EB58DB2002301220221284689 -:10C4F00000F040FB040004D1FF2030A1E43009F03B -:10C5000092FF20786946000900012070022008701F -:10C5100036488880C88000222846FDF798FC3EBD3A -:10C52000F7B505460078002700090C463E4601286D -:10C5300004D0FF2021A1F33009F075FF287A0328E9 -:10C540000CD041201DA1C00009F06DFF0298002C05 -:10C55000068001D0278066800020FEBDEA89702712 -:10C5600010460A3086B2002C0AD06888A080A889BC -:10C570002081E28020460A30296909F0D6FDE5E7EE -:10C5800002980680E8E7F8B543680246D9799C79B5 -:10C59000090221435C7A1E7A25025C88981D354386 -:10C5A000241FA14238D11B79022B35D1042D34D060 -:10C5B000052D3DD0062D34D0402D19E07372635CFB -:10C5C0006C326361705F636F72652E630000000000 -:10C5D000043000007372635C6C326361705F636F80 -:10C5E00072652E6300000000000C0020FFFF0000B9 -:10C5F00012D3061D0F461446284600F0E9F9082814 -:10C600000AD01120207003202072A581E7812661C5 -:10C610006078082108436070F8BD001DFFF7CEFE6A -:10C62000F8BD031D50880A461946FEF7C4FEF8BD42 -:10C63000001DFFF716FEF8BD70B50D4600238CB047 -:10C6400006461A46022100F095FA040031D02078FF -:10C650000007000F01282ED01220694688746078E8 -:10C660000523801CC874082088822888C8826888AE -:10C670000883A8884883E888888302A90C20019150 -:10C6800000901A4621463046FFF78BFD00280ED158 -:10C69000F02300223146012000F06CFE20780009D2 -:10C6A0000001401C20706078801C607000200CB07D -:10C6B00070BDCD48FBE71120F9E770B50D460023AA -:10C6C0008CB006461A46022100F054FA040006D047 -:10C6D00020780007000F012803D00820E7E7C248B0 -:10C6E000E5E71321684681746178C1740221818273 -:10C6F000C58202A906200523019100901A46214611 -:10C700003046FFF74EFD0028D1D120780009000106 -:10C7100020700020CBE7F3B581B00D460023012245 -:10C720000221019800F026FA00260446002803D1D1 -:10C73000AE49AF4809F077FE2079A8423BD2AC4819 -:10C74000AA49401C09F06FFE35E0E07841000F195E -:10C75000401C7979C0B20091E0700F2801D100200F -:10C76000E0702079401E2071B879C00708D0009889 -:10C770000199042815D09D498220183109F053FEF3 -:10C78000B8790007410F08D0400F019904280CD058 -:10C7900096498F20183109F046FE009807280AD1E3 -:10C7A00007E00846FEF784FEEAE70846FEF753FE78 -:10C7B000F3E7761CF6B228466D1EEDB20028C4D110 -:10C7C0003046FEBD10B500230122022100F0D2F94F -:10C7D000040004D1B5208549800009F024FEE078EA -:10C7E00021794018C0B2E0700F2801D30F38E070F3 -:10C7F00000202071A07880210843A07010BDF8B5FA -:10C8000017460D4600231A46022100F0B3F9040032 -:10C8100005D0002D0CD0002F07D0062006E0072DF4 -:10C8200001D00820F8BD0720F8BD0820A84204D890 -:10C830006F486E49423009F0F6FD29462046FFF761 -:10C840008BFC0646002F28D0002E26D1E0782179D7 -:10C850001CE0420012195379072B03D093791B0770 -:10C860005B0F04D0401CC0B20F280CD00CE040007D -:10C8700000198079F12318406B071B0F1843907142 -:10C8800000290AD104E00020491EC9B20029E0D1E4 -:10C89000574856495A3009F0C6FD3046F8BDF8B53C -:10C8A0000D4600231A46022100F064F9040004D169 -:10C8B0004F484E49683009F0B6FD681E052804D37C -:10C8C0004B484A49693009F0AEFD0F21E2782079E2 -:10C8D000002310E0560036197779AF4206D1B179BE -:10C8E00049084900B1715B1CDBB21146521CD2B23F -:10C8F0000F2A00D100220646401EC0B2002EE9D108 -:10C900000F2905D248000019817901221143817154 -:10C910001846F8BD10B50446402801D2072010BDC6 -:10C9200000F056F8082802D03120000210BD002186 -:10C93000304802E0491C082903D24A00825A002AE2 -:10C94000F8D1082903D049004452002010BD04202A -:10C9500010BD10B5402801D2072010BD00F038F8F6 -:10C96000082805D00021234A40001152084610BD76 -:10C97000052010BDF0B58BB016460C00074607D059 -:10C98000002E05D06188402904D207200BB0F0BDED -:10C990001020FBE72088002801D0172801D90C209F -:10C9A000F4E7084600F014F808280FD0258803A8FB -:10C9B0002A463146023009F0B8FB01A8009062888F -:10C9C0002B4607213846FFF732FCDFE70520DDE77D -:10C9D00001460020074A02E0401C082803D2430019 -:10C9E000D35A8B42F8D1704702300000BCC500001A -:10C9F000AD020000000C0020F8B50546E54C079E8E -:10CA0000069821706270A370E6702071681C42085D -:10CA10005200E14B0021880000198446C261605C2D -:10CA200040008218002D0AD0002005E0664647002D -:10CA3000F669401CF353C0B2665C8642F6D8491CC6 -:10CA4000C9B20529E7D30026D21C9708B000BF0061 -:10CA500000198760304600F042F9A15D761C48431A -:10CA6000C219F6B2052EEFD3501B80B2F8BDF0B557 -:10CA70000546C84F8C460020FF247E5DA9009646DF -:10CA80000346CF190CE0F9695A008A5AC2498A4212 -:10CA900004D1401CC0B2FF2C00D11C465B1CDBB291 -:10CAA0009E42F0D86146002909D100280BD0002D04 -:10CAB00007D0B84949788E4203D2401EC0B2002840 -:10CAC00001D071460C70F0BD70B5B24C8D000023E2 -:10CAD0002D19615C09E0EC695E00A45B844202D11F -:10CAE0001370012070BD5B1CDBB29942F3D80020AB -:10CAF00070BDFEB51C4617460D46060008D0002D39 -:10CB000006D0F01C80088000B04203D01020FEBD8B -:10CB10000E20FEBD002F03D0002C01D0A74201D96A -:10CB20000720FEBD0094234622463946002001948A -:10CB3000FFF762FF2988814207D0814201D2042198 -:10CB400000E0092128800846FEBD009423462246C5 -:10CB5000394630460194FFF74FFF28800020FEBD84 -:10CB600010B5044600F0C5F8002801D0E0B210BDB1 -:10CB7000FF2010BDFFB50546874881B01E460C4614 -:10CB8000854204D0052C02D20398022802D300204B -:10CB900005B0F0BD002769460F7028466A46214659 -:10CBA000FFF792FF00280ED068460178204600F07B -:10CBB000A8F8002EECD00028EAD1284600F099F819 -:10CBC000002809D103E03846002EF6D1E0E7FF2027 -:10CBD00072A15C3009F027FC21462846039A00F038 -:10CBE0009CF8D5E7F8B505460C4600206A4E694624 -:10CBF0006E4F0870B5423BD0052C01D30720F8BD1D -:10CC00000A4621462846FFF75FFF002830D06846D5 -:10CC10000178204600F075F8230009F0F5FC0504C2 -:10CC2000090C11161B0001462846FEF7D5FA15E03F -:10CC3000FDF7E0FA12E001462846FFF74CFC0DE054 -:10CC400001462846F6F7B5FF08E001462846F8F702 -:10CC500012FC03E056A17B2009F0E5FB4D4A684633 -:10CC6000A10000788918C96940000E520020F8BD63 -:10CC70003846F8BD524A1268914201D210207047DE -:10CC8000052801D3072070470872002048727047BA -:10CC9000F8B504464A480068844201D21020F8BD25 -:10CCA000207A3C4A83009B18617A3B4D125C11E06C -:10CCB000DE694F00F65BAE420AD04A1C6272DA6946 -:10CCC0004B00D25A228000F01CF860600020F8BDB2 -:10CCD000491CC9B28A42EBD861720520F8BD0EB575 -:10CCE000384B40000ECB0091029301926946085ADE -:10CCF0000EBD28494978814201D9012070470020A2 -:10CD0000704770B50C460546FFF7E9FF214AA900B8 -:10CD1000891889686043401870BDF8B50C4606460E -:10CD200000206946134608706A4619462046FFF7F8 -:10CD30009EFE002500282BD0164A6846A1000078E8 -:10CD40008918C96940000E52684601782046FFF7ED -:10CD5000D8FF0546230009F057FC0504090C0F1401 -:10CD6000170029463046FEF713FA11E0FDF720FAC6 -:10CD70000EE0FFF78FFB0BE029463046F6F7E0FEAA -:10CD800006E0F8F771FB03E009A1622009F04BFB14 -:10CD90002846F8BD100C0020FFFF00007372635C92 -:10CDA000686F73745F636D2E6300000002300000D3 -:10CDB0007372635C686F73745F636D2E6300000051 -:10CDC000280000206C67010010B5014620220948A8 -:10CDD00009F0ABF907490020C877084610BD06499D -:10CDE000012048610548064A0168914201D10021AD -:10CDF00001607047400C00200005004078000020D2 -:10CE0000BEBAFECA8107C90E002808DA0007000F63 -:10CE100008388008C24A80008018C06904E0800891 -:10CE2000C04A800080180068C8400006800F704724 -:10CE3000BD4948788978884201D3401A02E021220E -:10CE4000511A0818C0B27047B74923314878897819 -:10CE5000884201D3401A02E02122511A0818C0B2B8 -:10CE60007047B149463148788978884201D3401AE1 -:10CE700002E02122511A0818C0B27047A94910B522 -:10CE80000C310868FF22120290430122D2031043A2 -:10CE90000860A54900202331487088702339487004 -:10CEA0008870463148708870A04808F0C8F89F48DC -:10CEB000401C08F0C4F8F5F741FC00F028F910BD5B -:10CEC00020207047B4E770B50C4605460026FFF7F2 -:10CED000AFFF9549A04214D30A46203A00232046CA -:10CEE000641EE4B200280BD08878105C2870887823 -:10CEF0006D1C401CC0B288702128F0D18B70EEE709 -:10CF0000012600F004F9304670BD202070479BE7F1 -:10CF100070B50C4605460026FFF796FF824923317F -:10CF2000A04214D30A46203A00232046641EE4B2ED -:10CF300000280BD08878105C287088786D1C401C05 -:10CF4000C0B288702128F0D18B70EEE7012600F086 -:10CF5000DEF8304670BD202101700020704710B50A -:10CF60000446FFF77EFF2070002010BD70B50C4610 -:10CF70000546FFF776FF6C494631A04215D30A46B5 -:10CF8000203A00232046641EE4B200280BD08878A3 -:10CF9000105C287088786D1C401CC0B288702128F5 -:10CFA000F0D18B70EEE7002400E0614C00F0AFF8A8 -:10CFB000204670BD70B50C460546212904D9FF20D6 -:10CFC0005CA1473009F02FFA55484068103840B24C -:10CFD000FFF718FFC6B20D20FFF714FFC0B286425C -:10CFE00007D2FF2053A14D3009F01DFA01E0F5F7FB -:10CFF000E8FB21462846FFF766FF0028F7D070BD02 -:10D00000F8B507464948484C401E474E007825462B -:10D0100046362335002806D1A9786878212200F009 -:10D020006BF800280ED0A1786078212200F064F817 -:10D03000002814D0B1787078212200F05DF8002823 -:10D0400028D033E038496878C91C0F546878401CF0 -:10D05000C0B26870212829D10020687026E03249CA -:10D06000607820390F546078401CC0B2607021286D -:10D0700001D1002060702D4F7F1E3878002815D018 -:10D08000A1786078212200F037F800280ED0002027 -:10D0900038700BE02449707826310F547078401CAA -:10D0A000C0B27070212801D100207070A978687812 -:10D0B000212200F021F800281DD0A17860782122DB -:10D0C00000F01AF8002816D0B1787078212200F00C -:10D0D00013F800280FD0F5F756FB144807F0B7FFF8 -:10D0E00001214903884203D016A1C12009F09BF910 -:10D0F0000E4807F0C4FFF8BD401C884205D090429E -:10D1000001D1002901D0002070470120704710B5DF -:10D11000064807F09CFF002801D1F5F723FB10BD5E -:10D1200000ED00E000E400E0800C00207D00002025 -:10D13000072000007372635C736F635F72616E64DB -:10D140002E6300007372635C736F635F72616E6461 -:10D150002E6300000C4908784A78401CC0B2904207 -:10D1600000D008707047094A074820BF40BF20BF61 -:10D170004178037843701368002B02D103788B4207 -:10D18000F3D00020704700007F00002000E200E0A4 -:10D19000FEB5F34C07466068FF213E0181552178BA -:10D1A000FF2913D00901083141583246491E08327F -:10D1B00009020192090A805800F0C8F9002802D03B -:10D1C0002478254615E06168207888552770FEBDD3 -:10D1D000E34842680198115828010090083010581F -:10D1E00000F0B4F9002806D1DD482C4641680098CB -:10D1F0000D5CFF2DECD1DA4821014068855547547C -:10D20000FEBD70B5D64A04460020157A53680AE080 -:10D210000201561C9E5DA64203D10C329A588A42E6 -:10D2200004D0401CC0B28542F2D8FF2070BDF8B5D2 -:10D23000CB4F3E7801F013FE0146FF2E68D034013B -:10D24000254678680835405900F080F9022802D94F -:10D25000786840595AE0C2494868025D0A70A11CCA -:10D26000425C002A0CD0521E425441590122D20580 -:10D2700089180902090A41513046FFF789FF30E059 -:10D28000631CC25C0092221D94468258002A10D072 -:10D2900001239B029A420FD99205920D43595703DD -:10D2A000DB191B021B0A43516346C3589A1A920AA0 -:10D2B00009E0FF21C1540AE0435952039A181202AF -:10D2C000120A4251002242543046FFF761FFA4483F -:10D2D0000C344168C26800980959800012580098BF -:10D2E00090479F4C2078FF2812D001F0B8FD0146EE -:10D2F0002078626800010830105800F027F90128F2 -:10D3000096D92078616800010830085801F09AFD2C -:10D31000F8BDF8B51C4615460E460746FF2B03D34D -:10D3200090A1D32009F07FF88D48FF21C7604560A8 -:10D3300004720674017000224270104604E002017B -:10D34000521C401CA954C0B2A042F8D3F8BD70B51D -:10D35000834C06466578207C854203D381A1E62074 -:10D3600009F061F8E068A90046506078401C6070E0 -:10D37000284670BDFFB581B01D46FF2401F06FFD4A -:10D38000774F064679780198814203D875A1F42039 -:10D3900009F049F872480021037A406810E00A0158 -:10D3A0009446521C825CFF2A24D0019FBA4205D1C8 -:10D3B00062460C328758029A97421DD0491CC9B266 -:10D3C0008B42ECD8FF2C17D021014B1C019AC25480 -:10D3D0000B33029AC250039B614F0022012B0ED0E7 -:10D3E0000B1DC25001239B029D4216D9AA05920D26 -:10D3F00008D008E00C46E1E7FF2005B0F0BD0B1DAA -:10D40000C550EFE71A4653039B190E461B02083618 -:10D410001B0AAA1A8351920A09E0002D00D10125A6 -:10D420006B039B191D022D0A0B460833C550891C3E -:10D4300042543D463E782046FFF7AAFE2878B04287 -:10D4400015D001F00CFD014628786A68000108300B -:10D45000105800F07BF8012807D928786968000186 -:10D460000830085801F0EEFC01E0FFF7E0FE0198FB -:10D47000C3E770B50C46054601F0F1FC06462146AF -:10D480002846FFF7BEFEFF2817D0354D0401204681 -:10D49000696808300858314600F058F8012109033E -:10D4A00040186968A41C095D400B002901D089025D -:10D4B0000818002800D1012070BD002070BDF3B510 -:10D4C00081B00F460198FFF79CFEFF282AD0244D1B -:10D4D0002E7869683246344604E0844205D02646F8 -:10D4E0002301CC5CFF2CF8D11CE0FF2C1AD0A64203 -:10D4F0001FD11001085C2870FF2818D001F0AFFC84 -:10D500002A780146120168680832805800F01EF837 -:10D51000012809D92878696800010830085801F005 -:10D5200091FC06E00020FEBDFFF781FE01E001F066 -:10D5300091FC39460198FFF79CFF22016968FF239F -:10D54000541C0B558A5C3301CA54FEBD401A0002BC -:10D550000121000AC905884200D900207047000057 -:10D56000CC0C00207372635C736F635F74696D65CC -:10D57000722E6300F0B500241C4A01211C4B0803E5 -:10D58000546018601B4B1C601B4C20601B480469D6 -:10D59000E443E406E617046910252C430461184CA3 -:10D5A0006160184D2960761C00E020BF1F68002FC5 -:10D5B000FBD0002E03D107691026B743076190689E -:10D5C0008005906801D5104A10436960A160002170 -:10D5D00019600121084A09031160F0BD10B5044625 -:10D5E000FFF7C8FF2060002010BD000000C500400C -:10D5F00080E100E000C1004080E200E000ED00E0DA -:10D6000000C3004000C0004000FCFFFF70B51F4990 -:10D610000A68002A17D000231D4601244A68521CBC -:10D620004A60092A00D34D600E792246B2400E6846 -:10D6300016420AD072B60B6893430B6062B6496813 -:10D640000160002070BD052070BD5B1C092BE5D377 -:10D650000FA1362008F0E7FEF5E70120104980050C -:10D6600008607047EFF31081CA07D20F72B601212C -:10D6700081400648036819430160002A00D162B660 -:10D68000EBE7024800210160416070478400002000 -:10D690007372635C736F635F6576742E6300000062 -:10D6A00000E200E001208107086070470120810747 -:10D6B000486070471048C068C00700D0012070471C -:10D6C0000D488068C00700D0012070470A484069B3 -:10D6D000C00700D0012070470748C069704706495D -:10D6E0008A69D20306D589698907890F814201D1E8 -:10D6F000012070470020704700040040F8B5F84C46 -:10D70000207BE17A88421CD00126F64D0027E07A82 -:10D71000215C14200A4642435019037C052B11D08A -:10D72000037C062B1CD0037C072B28D0437C012BC9 -:10D7300033D0EDA1EF4808F076FE207BE17A8842F5 -:10D74000E5D1F8BD0674E07A0A2807D0E07A401CDB -:10D75000E072491CC8B2AA5802210CE00020F7E789 -:10D760000674E07A0A2808D0E07A401CE072491C6E -:10D77000C8B2AA5803219047DFE70020F6E70674F5 -:10D78000E07A0A2807D0E07A401CE072491CC8B24F -:10D79000AA580821EFE70020F7E74774E07A0A2843 -:10D7A00007D0E07A401CE072491CC8B2AA58072191 -:10D7B000E1E70020F7E770B50024CF4E0620707235 -:10D7C000CE4825464477047738300473C472CC4879 -:10D7D00007F035FCCB480575F572CB49601E8860B3 -:10D7E0007571B570F57035717570C848643905701C -:10D7F00045701420604340180574641CE4B2052C85 -:10D80000F7D30120F5F764F80020F5F761F801205F -:10D81000B071F4F727FDBE48F4F736FDBD4C20701B -:10D82000BD48F4F731FD6070F4F7F2FF70BD10B53C -:10D83000F5F719F8B74C2078F4F744FD6078F4F761 -:10D8400041FDAD4C207A002803D0F4F7CAFD00203A -:10D85000207210BD70B5A84CA079002804D0A2A1F8 -:10D86000AE4808F0E0FD70BDE07A002803D19EA12B -:10D87000AB4808F0D8FD0126A6710025E572607A54 -:10D88000042114225043974A801801749E488168ED -:10D89000491C04D0691E81600120F5F719F80020A9 -:10D8A000F5F716F8F4F7FAFF07F00AFDF5F7FBF8BD -:10D8B0009C480560056001209B49C0030860F5F79E -:10D8C00071F992480078022804D0032804D1E07846 -:10D8D000002801D0A67000E0A570F5F7D0F870BD63 -:10D8E000034680490520142242435218203A127FF1 -:10D8F000002A04D0401E0006000EF4D17047142206 -:10D90000424351180A46803AD366012220390A77E9 -:10D910007047012805D0032805D1002903D1002034 -:10D9200070470029FBD010B4734C00236370774A12 -:10D93000002890700CD002280AD007291AD20800BB -:10D9400078440079001887441505070D0F1113005E -:10D95000D37003E01B2000E03A20D07001206070FB -:10D9600010BC70475820F8E77720F6E79620F4E7D8 -:10D97000B520F2E710BC0020704710B5634840782E -:10D98000F5F798F880B210BD411E1422504310B52F -:10D99000544A8418203C042902D8207F002803D14F -:10D9A00051A1624808F03FFD207F012804D0B32038 -:10D9B0004DA1800008F037FD0020207710BD70B524 -:10D9C0004E4C607F217F884201D1012500E0002577 -:10D9D000F5F709F8F5F76EF8617F227F914201D1E2 -:10D9E000012100E00021A942EBD170BDF7B5074647 -:10D9F000481E84468EB0C0B2142205905043394A66 -:10DA000085180495287C2D1D07282AD1344C002622 -:10DA1000E07A227B824221D0235C059A934201D195 -:10DA2000012601E0002E04D00A2811D0421CA25C7D -:10DA300022540A280ED0401C227BC0B28242EBD175 -:10DA4000002E0BD0207B002806D0207B401E04E057 -:10DA50000022ECE70020EFE70A202073049A01205F -:10DA600010746046244C042813D8142041431D48E8 -:10DA700008182038007F00280BD00498007C01286B -:10DA80000BD00498007C012803D01098807A0128DC -:10DA900007D015A1264808F0C6FC1098807A012806 -:10DAA0006FD104980F4B007C022845D00C4C207B92 -:10DAB0000A2872D0207BE17A401C884203D10AA157 -:10DAC0001C4808F0B0FC049901204874217B05989B -:10DAD0006054207B0A2864D0207B401C20731CE10A -:10DAE000D80D0020E80D00207372635C72656D2E06 -:10DAF00063000000CF0500006C0E0020A00D002088 -:10DB0000780E0020C00D00204C0E00208E0000205A -:10DB10002FD200008C000020FDD600007D02000006 -:10DB20005E02000000F5004080E200E0CB02000051 -:10DB30001503000022030000607A059A0146904216 -:10DB400006D0014614267043C018807C9042F8D15C -:10DB5000627A824208D1617A14225143C918897CC1 -:10DB600061720121A17207E014224243D2181426E7 -:10DB70007143927CC9188A74142206215043C0183C -:10DB800081741098007A062819D201007944097925 -:10DB900049188F440812100E0C0AE07A00288ED023 -:10DBA00091E700209AE700200FE0B4200DE07320F9 -:10DBB0000BE0322009E00A2007E0062005E0FF2004 -:10DBC000FDA1E03008F02FFC0020029010980168C1 -:10DBD0000298081A28601099097A002912D00221A7 -:10DBE000401A0102090A296010980268406810185A -:10DBF0000002000A68601098807A0228109803D00A -:10DC0000007B74E00421EBE7007A002813D00222A5 -:10DC1000029810188446109842686046083016181A -:10DC2000E848029A4078904202D9E278002A04D06B -:10DC30003046083005E00422EAE7029A801A80198B -:10DC40000830627A062A1CD0627A14235A43DE4BCB -:10DC5000D2185268914214D0DC4B0793617A142297 -:10DC60005143D94A89184A688968D21BC91B1202D4 -:10DC70000902120A090A90423AD89A4238D89942BF -:10DC800036D83818801B0002000A286010996044BA -:10DC9000CF4AC9680002000A9446421A01239B0534 -:10DCA00007929A4201D2104614E00A1A09929A4247 -:10DCB00001D207980EE0079A6346624503D9591AC4 -:10DCC0000818401C06E0099A624506D9181A40183F -:10DCD000401C4042002860DC03E0B7A1BD4808F0CA -:10DCE000A2FB286880190002000A686000202872E0 -:10DCF0006868082608300002000A68601098407AB8 -:10DD0000A8721098007A687203280ED200280CD0EE -:10DD1000FFF7D0FC002803D007E0002011B0F0BDD1 -:10DD200002983A210E1A32200290A6480178012961 -:10DD300001D0032909D141780298814205D9E078C0 -:10DD4000002802D10298081A861928689F4AC01B29 -:10DD5000844601026868090AC01B03021B0A029379 -:10DD60008E421AD81346914217D80299994214D874 -:10DD7000617A062915D0667A6146062203920092DE -:10DD80001422914B7243D2189368DB1B8B4216D836 -:10DD90000396967C062EF3D177E0059801F055F9AD -:10DDA000BBE70499022205980A74627A062A00D019 -:10DDB000627A8A7460720120A07211B0F0BD062EE2 -:10DDC00063D000223146944614227F4B4A43D21836 -:10DDD0005368DB1B834229D2917BAB7A99421FD8CF -:10DDE00004980521059C01747B4D287B0A2811D0DD -:10DDF000287BE97A401C884203D16FA1774808F05C -:10DE000012FB287B2C54287B0A2807D0287B401C37 -:10DE1000287382E7E87A0028EFD0F2E70020F7E7DE -:10DE200001218C46917C0629CED102E06046002873 -:10DE30002AD03546009114202A46424362480621E2 -:10DE4000171839741038007B0A28634816D0017BF4 -:10DE5000C07A491C814203D157A1614808F0E3FA16 -:10DE60005D48017B4554017B0A290BD0017B491C8D -:10DE70000173BD7C0098A842DDD106E0C07A00287D -:10DE8000EAD0EDE70021F3E70096049902204E4D19 -:10DE90000874607AB04207D1049900988874059894 -:10DEA00060720120A07221E00398062E0FD0062890 -:10DEB00003D141A14B4808F0B6FA0398142250430D -:10DEC0004019059981740499009888740EE0062819 -:10DED00003D139A1444808F0A6FA0398142250430C -:10DEE000401905998174049906208874012011B0A5 -:10DEF000F0BD70B50D463D4A441900210B46101A7D -:10DF00008B4103D22CA13A4808F08DFA394885425A -:10DF100003DD29A1384808F086FA3848854203DA3B -:10DF200025A1374808F07FFA3648844205DA002CEC -:10DF300001DB204670BD334800E03348201870BD37 -:10DF4000401E70B5C0B2142148431F494418607B7D -:10DF5000062813D201007944097949188F44020C2C -:10DF60000A080604002068E0B42010E073200EE0E8 -:10DF700032200CE00A200AE0062008E0FF200EA173 -:10DF8000E03008F050FA617B0020002955D00221D2 -:10DF90004018616840180002000AF4F78BFD0C2558 -:10DFA0006557124A441900210B46101A8B412FD293 -:10DFB00001A10F482AE000007372635C72656D2E48 -:10DFC000630000008E000020E80D0020FFFF3F00EE -:10DFD000FFFFFF000E070000D80D00200702000021 -:10DFE000C5030000DD030000E3030000FF7F841E83 -:10DFF000F50300000020A107F603000000E05EF832 -:10E00000F70300000080841E00807BE108F00BFA1B -:10E01000FB48854203DDFB49FB4808F004FAFB4856 -:10E02000854203DAF749FA4808F0FDF9F9488442D5 -:10E0300007DA002C03DB204670BD0421A8E7F54871 -:10E0400000E0F548201870BDF0B5064683B0F348EF -:10E050000190457A029534687068001B0702F04809 -:10E060003F0A001B0090062D2DD014202946414365 -:10E07000EC480122081884464168E9489205864622 -:10E08000081B904210D3631A93420DD30246704688 -:10E09000724503D900984018401C05E073450ED91D -:10E0A000411A0819401C404200280CDA60460295CB -:10E0B000857C0198C0790028D5D003B0F0BDD14946 -:10E0C000D94808F0B0F90298854226D01421484377 -:10E0D000D4490123401802908068D1499B058C46A1 -:10E0E000011B8646994210D3221A9A420DD36346E9 -:10E0F000614503D900997144491C06E019466245FF -:10E100002DD9091A0819401C4142002905DD029841 -:10E11000B17A807B814200D37446062D15D0C14967 -:10E120001420454368184268121B1202120ABA42B0 -:10E130000BD2B37A827B934200D38468857C0198AA -:10E14000C0790028B9D1062DEAD13068A042B4D0F8 -:10E15000E0190002000A3460706003B0F0BDA94904 -:10E16000B14808F060F9D8E7F0B5B049044648680E -:10E1700085B0C005C00D1CD0103840B200280CDAA4 -:10E180000207120F083A920892005118C9698007D5 -:10E19000C00EC1400806800F09E08108A44A89002A -:10E1A000891809688007C00EC1400806800F002842 -:10E1B00008D000272078002806D0012804D00020AD -:10E1C00005B0F0BD0127F5E72079062813D201003C -:10E1D0007944097949188F44020C0A080604002082 -:10E1E00018E0B42010E073200EE032200CE00A208A -:10E1F0000AE0062008E0FF208249E03008F013F929 -:10E2000021790020002905D002214618834D002FD6 -:10E2100002D003E00421F8E70020E871694602AA71 -:10E22000A068F4F751FC694608228A56E06801A903 -:10E2300080180122C01C1F2801DA019209E003AAFC -:10E24000F4F742FC6846007B002802D00198401C8D -:10E25000019000990198401808300002000A0190CE -:10E26000881B0002000A0090607969468872009855 -:10E270000390F4F7B8FB009A019B121A181A6D4923 -:10E2800012020002120A000A8A4216D8884214D8E2 -:10E290006846FFF7D9FE00990398814205D0881996 -:10E2A0000002000AF4F706FCA0600120E9790029C9 -:10E2B00086D0002FB0D005B0F0BD0020F6E7F3B552 -:10E2C0008FB05D480C460B9006F0C1FE5B4A0F997B -:10E2D000524F56185A4D203E00280BD05948007D09 -:10E2E000002803D058A15B4808F09DF82078012849 -:10E2F0007ED060E1687F0A280CD0687F297F401CAF -:10E30000884203D150A1544808F08DF820780128A4 -:10E3100004D00CE0287F0028F4D0F7E7F07F002835 -:10E3200003D049A14D4808F07EF80120F077697FBD -:10E330000F9814224A4E51438919087420780228F4 -:10E3400022D0687F14214843861920793072607981 -:10E35000707232460C323146A068F4F7B5FB0C20DF -:10E3600030560F2804DD1F3830733068401C306091 -:10E370000C217156301DE26801905018C01C1F28F6 -:10E3800070DA01200199FDE028494868C005C00DF8 -:10E3900021D0103840B200280CDA0207120F083AD8 -:10E3A000920892005118C9698007C00EC140080642 -:10E3B000800F09E081081E4A8900891809688007D2 -:10E3C000C00EC1400806800F002804D105201EA100 -:10E3D000000208F028F8687F1421484386190021BC -:10E3E000E0686A460691117006A9F4F76DFB00E03B -:10E3F000D7E06A46002010560F2834DD012033E0B4 -:10E400000020A107B8DF0000F603000000E05EF87E -:10E41000F70300000080841E00807BE16C0E00206A -:10E42000FFFFFF00E80D00200E07000000ED00E0F8 -:10E4300000E400E0FFFF3F00780E00209200002083 -:10E44000A00D0020C00D00207372635C72656D2EFC -:10E450006300000011050000EF040000F404000058 -:10E46000E00C002082E0002006994018079002206E -:10E47000B0722079307260797072A068311DC01C52 -:10E4800006911F2801DA012009E0F4F71DFB684618 -:10E490000078002804D0069806990068401C08609F -:10E4A000307A062813D201007944097949188F443B -:10E4B000020C0A08060400200FE0B4200DE07320CF -:10E4C0000BE0322009E00A2007E0062005E0FF20EB -:10E4D000FD49E03007F0A7FF00202179002943D053 -:10E4E00002214018069071680830081807990890B2 -:10E4F00009180698081A0C900020F871F4F773FABE -:10E5000004463060079820180002000AF060787A0C -:10E51000062825D0797A14204143EC480818406831 -:10E520000899029040180002000A0390707A694628 -:10E53000887402A8FFF788FD0299039A091B121B31 -:10E5400009021202E24B090A120A0C98994207D8F2 -:10E55000824205D80299069808180002000A306025 -:10E56000F8790028C8D110E00421BAE704AA01997B -:10E57000F4F7AAFA6846007C002804D001980199B3 -:10E580000068401C08602078B072687F0A2806D0B6 -:10E59000687F401C68770B9806F071FD47E000200B -:10E5A000F8E7F07F002804D0A320CAA1C00007F03C -:10E5B0003AFF0120F077CA490F98087420780228A2 -:10E5C00003D1C4A1C74807F02EFFC54E2079307291 -:10E5D0006079707232460C323146A068F4F774FAF2 -:10E5E0000C2030560F2804DD1F3830733068401C73 -:10E5F00030600C22B256301DE16801908818C01CB2 -:10E600001F2802DA012001990BE003AA0199F4F70F -:10E610005BFA6846007B002804D0019801990068E5 -:10E62000401C08602078B072AD4901200875687FF1 -:10E63000297F884224D07C7A062C23D0F4F7D3F9A2 -:10E6400014214C43A14961180A7C042A18D00A7C81 -:10E65000032A15D04B6889681B1A081A1B0200028E -:10E660009B4A1B0A000A082B0AD31146934207D87B -:10E67000884205D8687F297F884201D0F4F7FFF9E6 -:10E6800011B0F0BD687F297F8842F7D111B0F0BD8D -:10E6900010B50020F4F709F910BD10B50120F4F70A -:10E6A00004F910BDF1B5009802281ED08E4C607A96 -:10E6B000062803D187A18D4807F0B5FE0026A67174 -:10E6C0000125E572607A03211422804F5043C0195E -:10E6D0000174F4F7D9F9009800280BD0012829D04B -:10E6E000032879D07BA1824844E082480078F3F780 -:10E6F000EFFDF8BD8048007F002803D075A17F485A -:10E7000007F091FE65717C4D00202E60F4F7E0F873 -:10E71000A968481C04D0012300221846F4F70EF91A -:10E72000607A617A401CC0B2142251437A580121A8 -:10E730009047F8BD0120F4F7CBF8607900280DD0A0 -:10E740006D488068401C09D0607A617A401CC0B274 -:10E75000142251437A5806219047F8BD6648007F3D -:10E7600001280AD0022812D0032822D0042834D04D -:10E7700058A1634807F057FEF8BD2079002803D060 -:10E780002671F4F786F9E5705B480677F8BD207AC4 -:10E79000002802D1F3F7FCFD2572607A617A401CF3 -:10E7A000C0B2142251437A5800219047524806774C -:10E7B000F8BD514F0123397B78680022411A184671 -:10E7C000F4F7BCF82079002803D02671F4F761F93A -:10E7D000E57002203877F8BD19E0474E217870685F -:10E7E0000123411A00221846F4F7A8F8207A0028DD -:10E7F00002D1F3F7CDFD2572607A617A401CC0B278 -:10E80000142251437A58002190473577F8BD607A39 -:10E81000617A401CC0B2142251437A5805219047B6 -:10E82000F8BD10B5304C607A062803D129A13548CF -:10E8300007F0F9FD607A617A401CC0B2142251439E -:10E84000224A52580421904710BDF0B583B00620EB -:10E850000290F4F7C8F8244C0090617A2A4801909D -:10E86000062920D0617A1420414318480918097CF0 -:10E87000042918D0617A142251430818007C032817 -:10E880007BD0019900980B6849681B1A081A1B0273 -:10E8900000020F4A1B0A000A082B6ED3114693424E -:10E8A0006BD8884269D814488068401C03D009A1FD -:10E8B000164807F0B8FD00206071607A06282CD158 -:10E8C0006078002829D023E0B8DF0000E80D0020A0 -:10E8D000FFFF3F007372635C72656D2E6300000082 -:10E8E000C00D00201E0500006C0E00204F0500002A -:10E8F000A20500008C0000204C0E00205B050000EB -:10E9000096050000A90500005C0E0020E50500004A -:10E91000FE48C178417081780170607A062815D070 -:10E92000607A1421FA4A48438018007C04280DD1EB -:10E93000607A0290607A0121142358438018017490 -:10E94000607A58438018807C6072A172F14D687FB4 -:10E95000297FF14F884233D0F04E287F142148435D -:10E960008019007CC05D0128287F07D048438019AA -:10E97000007CC05D02282FD044E0FDE11421484313 -:10E980008019807A01280AD0287F0221142250435E -:10E990008019007CC155287F0A2808D009E0287F0B -:10E9A0000021142250438019007CC1552AE0002028 -:10E9B00001E0287F401C2877687F297F8842CCD1DE -:10E9C000D74D287D00284CD0287CC15D012928D056 -:10E9D000C05D022830D03AE0287F142148438019D6 -:10E9E000807A012803D0CFA1D14807F01CFD297FF0 -:10E9F00000201422514389198872297F51438919B3 -:10EA0000097CC855287F142148438219287F484330 -:10EA10008019017C0098FEF7E9FF287F0A28C8D1F9 -:10EA2000C5E7A97A012904D00221C1550020287523 -:10EA30000DE00021C1550AE0A87A012803D0B9A150 -:10EA4000BC4807F0F0FC0020A872297CC855287D3E -:10EA5000002806D0297CB24A0098FEF7C7FF0020A4 -:10EA60002875029806281ED014214843A84940184A -:10EA7000017C012917D107210174AF4D287B0A2899 -:10EA80003CD0287BE97A401C884203D1A5A1AB4841 -:10EA900007F0C9FC297B02986854287B0A2831D0EA -:10EAA000287B401C2873607A06287DD0A07A002835 -:10EAB0007BD00020A072617A1420414394480E1844 -:10EAC0009F49B56873680A46F6687C32CB679660E2 -:10EAD00055609C4D697E002916D00226617A142269 -:10EAE0008B4851430818407B06281BD2010079440B -:10EAF000097949188F440A1412100E0CE87A00287C -:10EB0000C4D0C7E70020CDE70426E7E700210FE0E7 -:10EB1000B4210DE073210BE0322109E00A2107E066 -:10EB2000062105E0FF208849E03007F07CFC002149 -:10EB30002973687E022801D0012810D12869009A23 -:10EB40004018821A1202120A3A2A08D932380321CE -:10EB500000026976000A28613220287308E0322911 -:10EB600006D2207A00280AD1F3F712FC012005E032 -:10EB7000207A002803D0F3F734FC00202072634988 -:10EB80000822487820700978012901D0032906D18C -:10EB900001212171297B884201D9421A0832A378C8 -:10EBA000002B00D0921C01E08DE09BE02179002930 -:10EBB00001D1002B5DD09446644A00990092019ADD -:10EBC000176852687F1A511A3F0209023F0A090A60 -:10EBD000BC451BD85D4A974218D8009A914215D877 -:10EBE000297B884223D92B69421A9A1A1202120AE7 -:10EBF000101880190002000A2A616860002914D0E8 -:10EC0000032028770006000E3ED14CE00020207142 -:10EC1000A070297B002925D028694018801900029E -:10EC2000000A6860022028772EE00120E9E781428F -:10EC30000BD92A69511889190902090A6960002843 -:10EC400001D00420DDE70220DBE7002B03D135A152 -:10EC50003F4807F0E8FB286980190002000A686055 -:10EC6000002004E0296989190902090A69602877E6 -:10EC700019E0287B00280FD02969081880190002A4 -:10EC8000000A686002202877286901238119002280 -:10EC90001846F3F753FE09E0286980190002000ABC -:10ECA0006860002028770120F3F712FE607A1421B3 -:10ECB000484317490C2240188256012300206968F6 -:10ECC000F3F73CFE0EE00120F3F702FE0020F3F71D -:10ECD000FFFDF3F7E3FD207A002803D0F3F781FB73 -:10ECE00000202072A078002804D0F3F7D2FE002084 -:10ECF000E070A0706078002804D00448C1784170AA -:10ED000081780170207900282BD023E08E0000202C -:10ED1000E80D0020A00D002091000020E00C002054 -:10ED2000C00D00207372635C72656D2E630000007D -:10ED30000706000023060000D80D0020350600005D -:10ED4000E00D00204C0E0020B8DF0000FFFF3F0068 -:10ED5000870600000020CF49E0700978002900D123 -:10ED60002071CD48017BC07A814203D0CB484078E6 -:10ED7000F3F7AEFA0120E07103B0F0BDF0B5C84C76 -:10ED80000746607A83B0062803D1C6A1C84807F0B9 -:10ED90004AFB607A1421C74E48438019007C03283F -:10EDA00003D0C0A1C44807F03EFBC44DA868401C76 -:10EDB00003D0BCA1C24807F036FB607A1421484357 -:10EDC00081190C20085600216A4600911171C01962 -:10EDD00001AA6946F3F778FE6A46042010560F2808 -:10EDE00001DD012000E0002000994018696840180A -:10EDF0000102090AA9606079002804D001230022D9 -:10EE00001846F3F79BFD03B0F0BD70B5AE4CAD4AAC -:10EE10000B1AA34214D3451AA54211D3934203D926 -:10EE2000101A43185B1C0BE0954204D9511A0818BC -:10EE3000401C434204E0A549A54807F0F4FA00232A -:10EE4000184670BD10B50146012300220220F3F7D9 -:10EE500075FD10BD10B50220F3F73AFD10BD10B5D9 -:10EE6000F3F7C1FD10BDF0B58D4D0446E87A83B0CF -:10EE7000002803D18BA1974807F0D5FA642C4DD315 -:10EE8000954900200246091B824147D39348417FA0 -:10EE9000007F814242D19248007D00283ED1687AAD -:10EEA0001421844F4843854EC519306801AA0019C2 -:10EEB0006946F3F709FE694604200856002802DD7A -:10EEC0000098401C0090A96800986B680A18D21A34 -:10EED0001202844B120A9A4220D8AA7C062A08D031 -:10EEE00014235A43D2195268511A0902090A81425D -:10EEF00014D3B068401C05D00120F3F7E9FC0020D2 -:10EF0000C043B060306800193060A86800994018AC -:10EF10000002000A7061012003B0F0BD002003B0C0 -:10EF2000F0BDF8B50646401EC5B2142061496843DD -:10EF30004418207C002803D15AA16B4807F073FACB -:10EF40006648017F407F81420CD0684A14234B43BE -:10EF50009B181B7CB3420CD00A290CD0491CC9B2A7 -:10EF60008142F3D15E48017D002964D0007CB0422B -:10EF700061D10020F8BD0021F1E7217C052905D0F1 -:10EF8000217C062902D0217C072928D10121217466 -:10EF9000C17A0023027B8A4221D00246565CAE42EF -:10EFA00001D1012301E0002B04D00A2911D04E1C0D -:10EFB000965D56540A290ED0491C167BC9B28E4262 -:10EFC000ECD1002B0BD0117B002906D0117B491E00 -:10EFD00004E00026ECE70021EFE70A211173617CD1 -:10EFE00000292AD06774C17A0023027B8A4224D088 -:10EFF000425CAA4201D1012301E0002B04D00A297E -:10F0000012D04A1C825C42540A290FD0491C027B50 -:10F01000C9B28A42ECD1002B0FD0027B0146002AF4 -:10F0200006D00A7B521E04E00022EBE70021EEE747 -:10F030000A220A7301E018480027217C01299CD18B -:10F04000617C002999D10120F8BD70B505461420D6 -:10F05000184A05216843801801740F4C207B0A2848 -:10F0600011D0207BE17A401C884203D11749204807 -:10F0700007F0D9F9207B2554207B0A2807D0207B74 -:10F08000401C207370BDE07A0028EFD0F2E700202A -:10F09000F7E700008E000020D80D00208C00002033 -:10F0A0006C0E00207372635C72656D2E630000004D -:10F0B000EA060000E80D0020EB0600004C0E0020E0 -:10F0C000EC060000FF7F841E0020A107B8DF0000CF -:10F0D0000E0700002D070000FF1FA107A00D002054 -:10F0E000C00D0020FFFF3F006A070000E00C002079 -:10F0F0000702000070B5FF4D00246C702C70AC61ED -:10F1000000F0CEFC284620304470C473AC6214304A -:10F110002C6305F094FF002804D0FF20F6A14E30A8 -:10F1200007F081F92C7770BD0B23DB4310B5C21AB1 -:10F13000F54998421FD008DC1C3222D00A2A20D080 -:10F14000142A1CD0182A08D117E0083011D004283E -:10F150000DD0082809D00C2805D0FF20E6A1753075 -:10F1600007F061F910BD04200CE000200AE0FC204B -:10F1700008E0F82006E0F42004E0F02002E0EC20B3 -:10F1800000E0D820C86010BD70B50125DF49022617 -:10F190000E60DF490022CA63CD63DE49C96A0907F0 -:10F1A0000ED4DC494031CB6ADB4A53620B6B93626D -:10F1B0004B6BD3628B6B1363C96BD30519435163DC -:10F1C000D14C002826D0012828D0FF20CAA1A13088 -:10F1D00007F029F9D148A063FF200430606325635C -:10F1E00003202061C849962040314860C1491C2055 -:10F1F0000856FFF799FFCB49C9488860C948CA49F2 -:10F2000080304160C9490160C9480660C949102081 -:10F21000486070BDC8486061C84803E0C848606184 -:10F22000C648801FA061D5E770B50C46B14D0146B8 -:10F230000622A81C06F079FF2C7270BDAD48203064 -:10F2400040787047AB4A517010707047F8B504466B -:10F250000D465079117900020843690009190884A4 -:10F260001F461646501C06F0C1FF317800020843C5 -:10F27000A90060502846083001268640002F0ED095 -:10F28000012F04D0FF209CA1E83007F0CCF8206BC0 -:10F29000304301460120A84001432163F8BD206BA3 -:10F2A000B043F6E770B50D460446082904D9FF209F -:10F2B00091A1F93007F0B7F80022A24809E09100C7 -:10F2C000635809180B6053001B191B8C0B62521CEE -:10F2D000D2B2AA42F3D3206B9A494031086070BD84 -:10F2E00010B50446FFF720FF8248047710BD81481F -:10F2F0002030007B704710B5834CC178616206F006 -:10F3000075FF0002E06110BD252808D0262808D02E -:10F31000272808D041000A2807D8091D06E0022145 -:10F3200005E01A2103E0502101E0891DC9B2764AA7 -:10F33000916075494031486170476E4988617047F6 -:10F3400070B5002818D002226A4C784B0320A272B4 -:10F35000F0331860734D72486860002001262075F4 -:10F3600000290BD0012910D002291BD0952062A1C1 -:10F37000800007F058F870BD0122E5E77248012AC5 -:10F3800001D0466070BD066070BD5A48012A006B0E -:10F3900005D00121490508432063696070BD012142 -:10F3A0000905F8E7A069002803D153A1674807F0D1 -:10F3B0003AF8A169A06A40186549886059486549CA -:10F3C0008030816060491031C1600120216BC00331 -:10F3D00001432163686047482030C67370BD08B59B -:10F3E0000C20694608705148002110380161564AC6 -:10F3F000012111610BE000BF00BF00BF00BF00BFD3 -:10F4000000BF00BF00BF6A461178491E11706946EF -:10F410000978002902D001690029ECD068460078FB -:10F42000002804D1494834A1203006F0FCFF08BD73 -:10F43000F8B53E4CF034206886083E48B600416876 -:10F44000C906CD0F10218160002727603549344857 -:10F450008860FFF7C4FF35481038076100F020FBD3 -:10F460002660002D02D0334910204860F8BD10B549 -:10F4700006F0BCFE00022449000AC86310BD2349FF -:10F48000022008602A49086070472049022080391C -:10F4900008607047304908707047164810B534301E -:10F4A00005F0D5FD002804D0284813A15A3006F0F5 -:10F4B000BAFF10BD0F4810B5343005F0E0FD10BDA7 -:10F4C00011494860704770B50A4D0446A86AA042C9 -:10F4D00004D31E4808A16B3006F0A5FF0120287355 -:10F4E0001C49002008392C6148601948446000F02C -:10F4F000DEFA70BD7C0E00207372635C68616C5F25 -:10F500007263732E630000000015004080E100E08C -:10F51000C01F004080000010001700405B06000084 -:10F520000040000400F50140408000401011004000 -:10F5300080E200E000130040060102002500030203 -:10F5400005010300001600400010004047020000C3 -:10F5500040850040488100409700002010B5FF48DA -:10F5600002210173C6210161FD4A00215160806AB8 -:10F57000FC49C630486000F09AFA10BD0121FA48F3 -:10F5800089058160F548026B8A430021026301739B -:10F590007047F64801214160C160F1490020486090 -:10F5A000F0494860ED4988627047F149402008629F -:10F5B000F0490A6802430A607047EE480168402239 -:10F5C00091430160EA49002008627047E9480168F8 -:10F5D000102291430160E849012088617047E749A2 -:10F5E0000020C861E34801681022114301607047A0 -:10F5F000E249CA69012A01D000207047DC4A9268BA -:10F600005206520E524202700020C861012070471B -:10F6100070B5D248D24D017B002902D0696801291A -:10F6200009D00024D5490A69012A06D00023807A2E -:10F63000012804D006E00124F4E74023F7E7CA6874 -:10F64000012A04D000221A43012802D004E020221B -:10F65000F9E74B68012B05D000231343C84A022861 -:10F6600002D007E01023F8E71668012E02D1CE6819 -:10F67000012E04D000261E43022802D007E00826EF -:10F68000F9E71268002A02D1CA68012A04D00022D0 -:10F690003243022802D005E00422F9E7002C01D011 -:10F6A000022300E000231343022807D14868012801 -:10F6B00004D16868012801D0012600E00026B14885 -:10F6C0001E4302681206120E02D04A69012A00D0B7 -:10F6D0000022A24C2034227300680006000E02D0E3 -:10F6E0008869012800D000206073A148006A0028C2 -:10F6F00003D000F0A8FA012800D00020A07300F089 -:10F70000C7F9002068603046F3E670B50C00054686 -:10F7100003D19D499D4806F086FEE00706D0012CE6 -:10F7200004D06D209849C00006F07DFE002D0ED05B -:10F7300002218A4801294172C4728E4809D00229E7 -:10F740000AD0924890491A3006F06DFED1E60121A8 -:10F75000EFE70168042201E001680822114301601B -:10F76000C7E670B57D4C0022E37A990701D54107C1 -:10F7700014D47A49DD062031002D05DA4D7B002DA9 -:10F7800002D08D7B002D09D01D0702D50D78002DEC -:10F7900004D15B0703D54978002900D10122637A9F -:10F7A0007449002B06D00225284010430CD0FFF7E7 -:10F7B0003FFE9EE66C4A76489060086880088000AC -:10F7C000086000F06DF994E6012B07D0022B0ED0F3 -:10F7D0006E486D496B3006F026FE8AE60868042202 -:10F7E0009043086000F05CF90120A07281E608688F -:10F7F00008229043086000F053F9A57279E6574952 -:10F8000008757047F8B5554F544D2037FA7B564C64 -:10F810000021286B002A31D00122D203A26090433C -:10F820002A46544D10632E685A4A102090600020DA -:10F8300028601014A060FFF7D2FD00F029F92E60B7 -:10F84000281460605349102048604448817A4A482F -:10F8500001290DD002290ED04C484FA1801F06F07F -:10F86000E2FD0020F8733D48007D022874D0F8BD09 -:10F8700001210160F5E701214160F2E73A4A906019 -:10F880000E462963FFF7C4FE044636482E754168CC -:10F8900069620068A862AA7A022A0AD16A78002AF4 -:10F8A00007D0334B403B5B681B7813402A789A4360 -:10F8B00008D03E70E20708D0084603F04AFD012157 -:10F8C000A86A09E001223A70F4E7A10601D50221F5 -:10F8D00002E0A10702D5002103F04BFD2448403887 -:10F8E00041680622A81C093106F0F2FB002809D164 -:10F8F0001F48297A403840680078C009814201D108 -:10F90000012000E0002078702046FFF72AFF2648FB -:10F91000007800280DD001284AD002285BD00328A7 -:10F9200078D01DA1214806F07EFDA87A022870D06B -:10F93000A3E0A00701D502F0EDFB200702D50120CE -:10F9400002F020FC600702D5002002F01BFCA0069C -:10F95000EBD502F07CFBE8E793E000007C0E002092 -:10F96000408100404085004000F50140008000409B -:10F9700040150040001200400010004000110040FF -:10F980000014004040160040F8F40000630300003B -:10F9900000400004001300407372635C68616C5F98 -:10F9A0007263732E6300000097000020E6040000DD -:10F9B000A00701D504F0BBFF200702D5012004F009 -:10F9C00021FF600702D5002004F01CFFA006ACD583 -:10F9D00004F0A4FEA9E7A007BF27002802DA3C40F4 -:10F9E000F3F702FB200703D53C400120F3F7FBFAB5 -:10F9F000600703D53C400020F3F7F5FAA00602D5D6 -:10FA00003C40F3F7EFFA60068FD5F3F7EEFA8CE798 -:10FA100000E012E0A00701D5F3F7EAFA200702D5CB -:10FA20000120F3F7E4FA600702D50020F3F7DFFACC -:10FA3000A00690D5F3F7DAFA77E7287B00281CD0E8 -:10FA40001F494E6002281FD0012803D01D491E48BF -:10FA500006F0E9FCA96A2869884204D81A481949BD -:10FA6000401C06F0E0FC2969184841600120296B20 -:10FA700080050143296316494860287D012800D08C -:10FA8000F5E6F3F7C5FAF8BD2969A86A4118EBE76E -:10FA900010480021C160016141604161816170478E -:10FAA0000D480021417281720121C17270470A48DC -:10FAB0000121026B89050A430263054841607047D2 -:10FAC0004081004098F90000FB04000040850040A0 -:10FAD00000F50140001100407C0E00202E4800215E -:10FAE00001704170704770B5064614460D460120FE -:10FAF000F1F758FC28490120284B08709E60DC6013 -:10FB00001D6170BDF8B504460120F1F74BFC224998 -:10FB10000120087021494C60214900264E600321D4 -:10FB2000204D0906A960204F002C0AD0012C03D0DB -:10FB30001EA1412006F077FC3E60032000066860AD -:10FB4000F8BD386001200006F9E710B512480178C9 -:10FB500000290ED00321134A0906916010494A6812 -:10FB60000021002A03D0154A1268427000E041705B -:10FB700001700020F1F716FC10BD0748017800293C -:10FB800007D007484068002802D00C480068C0B27F -:10FB900070474078704700009800002000F5004052 -:10FBA00000F1004000F5014000F200407372635C18 -:10FBB00068616C5F63636D2E6300000000F40040B9 -:10FBC0003A4800210170417010218170704770B572 -:10FBD000064614460D460220F1F7E4FB01203349A6 -:10FBE000334A0870E41E14619660556070BD10B50C -:10FBF0000220F1F7D7FB2D49012008702D48002184 -:10FC000001604160816001202B49C005486010BD42 -:10FC100010B5264C2078002811D001202649C005B7 -:10FC2000886000F034F80021002804D001206070C2 -:10FC30002248006801E061701020A070217000204F -:10FC4000F1F7B0FB10BD10B51848017800290BD0B2 -:10FC500018480068002805D000F019F8002800D0E6 -:10FC6000012010BD022010BD407810BD10B50F4816 -:10FC70000178002909D000F00AF8002803D00F48C5 -:10FC80000068C0B210BD102010BD807810BD0948BA -:10FC90000168002905D04168002902D08068002849 -:10FCA00001D0002070470120704700009A0000201A -:10FCB00000F5004000F1004000F5014000F4004074 -:10FCC000FFB593B0044600201D9E049015981C9D1E -:10FCD0001027082806D0E06901F014F8002809D0A0 -:10FCE0003770CCE028880921384328801F980227E4 -:10FCF000017016E0E169012088710521E269C902FD -:10FD00009180E1698872E169F9480881E169002020 -:10FD10008873288820210843288011211F980427F0 -:10FD200001701F980225801C0390307810900A20E3 -:10FD30003070204618301190F6F76BFC00206FE011 -:10FD40001598102809D1022D07D06846828A049997 -:10FD50000398401A8270110AC1706846C08A1699C9 -:10FD6000884203D9E349097A149106E0884204D114 -:10FD70001099002901D0317021E003990870000A20 -:10FD800048701E980088401BC01B83B2FF20C01B18 -:10FD9000984200D203460398149AC0190CA9009205 -:10FDA000019002912020015D6846C08A0022F6F78A -:10FDB000A5FC3070002806D0C0B2832862D0684607 -:10FDC000C08A208345E00F98002805D0C948006804 -:10FDD00000790A2830D33CE06846008EC119C9B2C8 -:10FDE0000491022D0FD01F99049A4978914203D1B2 -:10FDF0006A46128C824209D0BE480491006801789C -:10FE0000032909D027E008461F994870B9480068BF -:10FE10000178042906D008E000790A281BD20120C5 -:10FE20000F9009E06946C98A8180039904980818EF -:10FE300003900498281885B205AA14991198F6F72A -:10FE4000EBFB002805D11E980088401BB84200DB60 -:10FE500076E7022D0ED01598102807D1049A039941 -:10FE60006846808A891A8870000AC8701E980580C2 -:10FE7000002030709F4800680078032802D00020DE -:10FE800017B0F0BD0220FBE7F8B50446406B002632 -:10FE9000134600282BD0491F8DB2618F2A460832A5 -:10FEA000278F8A18BA4221D89A7840185F781102B1 -:10FEB00039430170090A41701A79DF781102394318 -:10FEC0008170090AC1700571290A41712A46591DBC -:10FED000801D06F02AF9608FAD1D401980B2608741 -:10FEE000626B002110180170417000E00926304655 -:10FEF000F8BD30B50B88048F9C4212D9446BE018D2 -:10FF00004478057824022C430BD0447905792402E7 -:10FF10002C436404640CA41D1B190B80106000208A -:10FF200030BD822030BDF7B588B000256846058217 -:10FF300005275DE00398417802780E021643417967 -:10FF4000027908021043000452D40A980123068063 -:10FF500005A802905B02002200970195304609999E -:10FF6000F6F7CCFB04004AD16846018A0183039866 -:10FF70004179027909021143437802781C02144343 -:10FF8000B4421ED10A041CD44B0401215B0C89032A -:10FF900000950B4301970295C17880780A020243CD -:10FFA00020460999F6F7C6F9040011D1039948795A -:10FFB0000A79000210430122D20310430871000A9B -:10FFC000487103AA06A90898FFF793FF0400CED052 -:10FFD0000399009501970295487809780002084333 -:10FFE00069468B8A00220999F6F7A4F9822C06D17A -:10FFF00003AA04A90898FFF77CFF04009AD068467A -:020000040001F9 -:10000000058209E003984179027909021143490404 -:10001000490C0171090A417103AA04A90898FFF764 -:1000200068FF0028EED0822C02D020460BB0F0BD35 -:100030000020FBE730B50446406B002597B0002850 -:100040000DD00B2268460270228F0281606B0391F3 -:10005000019000216846F3F7E2FA6846057065638F -:100060006587258717B030BDF8B50F460546696B23 -:100070000020069E144600290FD0012B0DD13246D8 -:1000800039462846FFF74FFF002806D1002C04D040 -:1000900032463946284600F044FEF8BD0022028070 -:1000A000C262831D0263C3614263428702872030BC -:1000B0000170704710B50022D24302800420FDF782 -:1000C000FEF910BD10B596B00446FFF7B3FF208EC1 -:1000D000002808D0012069460870E06A01900021DC -:1000E0006846F3F79CFA0020E062206316B010BD6A -:1000F00001280000B40E00200146098800200A07EC -:1001000000D501200A06120F01D002221043CA05B1 -:1001100001D5042210438A0501D510221043490558 -:1001200001D5202108437047FFB5A9B00600329DD4 -:10013000359C2B981F46229016D0007841060FD48C -:100140008106890E1E2909D021884A05520E0BD13D -:100150003A88172A08D3FE4A914205D0C10906D031 -:100160008006800E122802D003202DB0F0BD20465C -:100170002C302690F7492A980872002018AA03907C -:1001800010726A46107404AA0A60339A4A6020AA60 -:10019000908090812298007801908106681C1C90C4 -:1001A000701F1D902B98890EC21C2492224620326B -:1001B0001B92083A401C02920B0006F025FA1FFD24 -:1001C000FD11FD1FFD8EFDFCFDFBFDFAFDF9FDFCA3 -:1001D000FDF8FDFDFDF7FDF6FDFDFDFDFDF5FD0066 -:1001E000032E76D102E018A9087219E303202870C3 -:1001F0001C9917220A7000224A70CFE2052EF0D116 -:100200004178027808021043208320A98880249A2C -:100210005178127809021143618300287ED0884208 -:100220007CD800202072E080401E60840298F6F79F -:10023000F0F905202870A81C0190022000901BAA4C -:100240002A990298F6F7E8F9002868D118A8807C66 -:10025000012803D002206870102002E0012068709D -:1002600002202490002225A91CA8F2F746FD0028B0 -:100270002BD120A8007D2499814226D13A8800996B -:10028000801C511A814220DB10A8C18D0198017099 -:10029000090A417001991CA8891C01910099019AD1 -:1002A000891C009125A9F2F728FD20A8007D01995D -:1002B0001BAA091801910099081880B200902A9988 -:1002C0000298F6F7A9F90028CCD00098022826D089 -:1002D00064E272E018A9087261E2072E6DD34178DA -:1002E0000346027808021043208320A98880249ABC -:1002F0005178127809021143618300280ED0884298 -:100300000CD8012020725879197900020843E08046 -:1003100000202073E06900F0F5FC01E098E0A9E01E -:1003200000280ED1E169012088710521E269C90226 -:100330009180E1698872E16987480881E16900205C -:100340008873F01F60842298C01D60620298F6F7DF -:1003500060F907202870681C00900120019000209F -:1003600010A9C8852FE00198012814D0E069807990 -:10037000012830D000981E38417F007F09020143D8 -:1003800000980170090A41700098801C0090019843 -:10039000801C80B2019010A8C18D00980170090ADC -:1003A00041700098801C09E00AE296E13BE1DFE041 -:1003B00004E29BE077E036E016E2AFE000900198BF -:1003C000801C80B201901BAA2A990298F6F724F9A2 -:1003D000002803D007E010A8818DD1E73988019863 -:1003E000081A0428BFDA0198012843D0E06980790F -:1003F000012804D010A8818D5548814206D110A84B -:10040000818D00980170090A417009E000981E383A -:10041000417F027F0802009910430870000A48706B -:100420000198801CBAE1072E01D0152E76D14178B3 -:10043000027808021043208320A98880249A5178EA -:100440001278090211436183002801D0884201D942 -:1004500001203FE7012020720020E0802073052E5C -:100460000AD01D982299E269C0B2491DF2F71FFC1B -:10047000002801D00A202DE70020C04360841AA87C -:10048000019023A9229802970395009100780023F8 -:100490008206920E20462A99FFF712FC0390208BC9 -:1004A00020A988807BE1032EC0D1402220A98A8127 -:1004B0004178027808021043208320A988802A9975 -:1004C0001EAB1C9A02930192009139880022491EAA -:1004D0008BB21B990978F6F711F918A90872002850 -:1004E00033D10B20287010A8008F3FE0052E9DD13E -:1004F000802220A98A814178027808021043208353 -:10050000249984464A78097812020A43628420A911 -:1005100088801248824202D30720DBE6AFE03F200A -:100520008002024362842A981FAB1C9902930191B6 -:1005300000903888401E83B21B9801786046F6F719 -:10054000DDF818A9087200280CD08328AAD107E08A -:10055000FFFF0000B40E002001280000010200008F -:100560000220B8E00D20287010A8808F401C15E1F3 -:1005700001990C22C9095143C91CB14204D90198FF -:1005800040067CD5002009E1427803781002184328 -:1005900020AA9080844622980078400609D505203C -:1005A0006A46107422980078C00905D000201074A3 -:1005B0001DE106206A46107424981F902A9A009024 -:1005C0000023701A029383B21E9001921B9800229E -:1005D00001786046F5F7AEFE18A908720022694658 -:1005E0000A74832801D102200390229800784006E3 -:1005F0000DD52088C00506D520A9208B8988884282 -:1006000001D100206062002018A90872C6E0FF2115 -:10061000013120A88181808820831E9860841F98E2 -:1006200060621320B8E0052E29D3417802780802D1 -:10063000104320A98880218F002902D0FE4A9142D0 -:1006400006D10A216A4611740121C943218702E0BB -:1006500007216A46117422992A9A491D0192009134 -:1006600001221D990023D203029311438BB22499D6 -:100670004A78097812020A431B99097800E0C9E018 -:10068000F5F758FE18A90872002269460A7401227B -:10069000520220A98A81832808D0002809D0218FFE -:1006A000E54881427ED10020208778E08888208339 -:1006B0004DE7606B002808D031462046229AFFF7AC -:1006C000E3FB18A90872002869D12B463A46304648 -:1006D000229900F056FB039061E02298022E4078A8 -:1006E00001907DD1002801D0012879D108206946E8 -:1006F00008740198087521A800901B9800220178C1 -:100700002046019BFFF7B0FC6946002248758A75B8 -:10071000002802D10198012809D0208F002806D096 -:10072000002008740120800220A988810EE004A81E -:100730003399F2F774FF0390002069460874012092 -:10074000800220A988810398022807D0BB4800684E -:100750008079002805D018A908722BE00198208321 -:100760001DE00398002803D0812018A9087240E0FA -:1007700021A800901B98012201782046019BFFF7D9 -:1007800073FC18A9087220463499FFF753FC18A986 -:10079000087A002803D11920287001203880684683 -:1007A000007C00E03CE0002804D004A83399F2F774 -:1007B00036FF0390039800282ED01AE0062012E599 -:1007C0002078000713D5012E11D109216846017444 -:1007D000A188818204203499FCF771FE082100E091 -:1007E00005E020A88181CDE60198400612D50320BE -:1007F000039020A9208889890843208020A988891E -:100800004005400E04D026992B98086026988680D3 -:100810000398AAE40420E6E418A8007A00280ED081 -:100820000120287022980078687020A88088A8701D -:10083000000AE87018A8007A28710520388020A9DD -:100840002088898988432080E2E7FFB50746A1B068 -:1008500000201C903A7801209040794A7C68104032 -:1008600010AA1087744B22885B1C9A4203D0002880 -:1008700004D0100702D5012025B0F0BD249E002031 -:10088000307023980025028810A8028518A80575E5 -:100890006A4B68461972057404A8186020462C300B -:1008A0001B902A985860249E94463878721C052123 -:1008B000039201282DD0022808D003287DD130785A -:1008C000800980011D303070B889A08038780228F6 -:1008D00004D13078800980011B303070F01C1FAAD1 -:1008E00001900292009110A8008D0022C01E83B2D8 -:1008F0002020015DB889F5F701FF0028DED10398BB -:10090000B9890170090A417010A9888FC01C088537 -:1009100028E1787B18AA10753A7B012A02D0022AB6 -:10092000CCD1FCE022887F231B011A4010AB1A8730 -:10093000802A4AD006DC102A10D0202A0ED0402A65 -:100940000AD124E0FF3A013A65D0FF3A013A79D062 -:10095000FF3AFF3A022A76D00525A2E02078C006A9 -:1009600001D5082000E010201C9004206A46107475 -:10097000002090821AA81DAA1EAB03960192029035 -:1009800000933B8A20461C9AFFF79AF984E0228B59 -:100990003B8A9646934268D10A221C92002839D19C -:1009A000039801906046401E1FAA83B20292202045 -:1009B0000091015D0022704600E0BAE0F5F79EFE6E -:1009C000014618A801750B201AE0228B3B8A964637 -:1009D00093424AD10C221C92002862D103980190C4 -:1009E00060461FAA401E0292009183B22020015D42 -:1009F000628C7046F5F782FE014618A801750D203D -:100A0000307010A8818F491C01850421684601744B -:100A1000218B818245E0238B3A8A9C469A4224D1DD -:100A200012221C9200283CD1606A002813D00022B8 -:100A30006B4607C3638C07E0FEFF0000B40E002086 -:100A400009F800000DE04BE02020015D6046F5F75D -:100A500071FC18A9087513203070012010A90885B1 -:100A60001FE0398A228B914201D00425B6E016217D -:100A70001C91002815D11B98818802682046FFF739 -:100A800003FA18A9087500280BD11B983346016892 -:100A900080881AAA00F075F9054602281BD0042D9B -:100AA00019D01B988088002811D06846007C002847 -:100AB00004D004A82A99F2F7B2FD05460120694640 -:100AC00008741B981B990068059000208880002DF1 -:100AD00048D0052D2ED06846007C032878D07DE0D4 -:100AE00018211C91002806D0388A20832046B96836 -:100AF000FFF7A0FAD5E72046183000902020015DCE -:100B0000237E01222046FFF7AFFA18A908750028B6 -:100B1000ECD119203070012010A90885E6E7208863 -:100B200001214902084010A90887FF38FF38022830 -:100B300006D0052510A92088098F884320804DE024 -:100B4000208F9849884290D116201C90386900283F -:100B500005D06063B88A20870020608702E000200B -:100B6000C043208710A8008F7F21090102468A43D5 -:100B70000DD0782300220420B968FCF7FBFB3878FD -:100B8000A07010A92088098F0843208002E02188E6 -:100B9000814321806846007C002805D08248416856 -:100BA00004A8F2F73CFD054618A8007D002815D0E2 -:100BB0001C98707001203070208BB070000AF070AB -:100BC00018A8007D3071052110A8018506E0FFE717 -:100BD0007548416804A8F2F722FD05467248017A7B -:100BE00020884005400E22D11B98808800281ED006 -:100BF000239A0026138810AA1385249A2A9B6F46ED -:100C00004CC71B9A039412681AABFFF78DFA05467E -:100C100002280CD00120694608741B982A990068A4 -:100C2000059004A8F2F7FBFC05461B98868010A8E7 -:100C3000018D2398018028461EE600B597B0042850 -:100C400007D102206A461070019100216846F2F730 -:100C5000E6FC17B000BD10B5534C037800222168A4 -:100C6000012B02D0022B42D126E00B78002B01D0C1 -:100C7000042B03D10A712268032111702168838833 -:100C80000A79D200921D8B5221680A79D20008326B -:100C90008918C2880A80216803890A79D2000A3239 -:100CA0008B52428920680179C9000C314252216877 -:100CB0000879401C08711EE00A7482888A802168C5 -:100CC000C288CA80226801891181226841895181C4 -:100CD000C1682068C1606168F2F7A1FC0146022882 -:100CE00007D02068007C002802D1002903D0812091 -:100CF00010BD832010BD002010BD406B002800D027 -:100D0000012070478178012909D100880521C90295 -:100D1000884202D0491C884201D10020704705203A -:100D20007047F7B586B00024684615460F468481A3 -:100D300005261AE0049841780278090211432980B7 -:100D4000811D019602940091417902790B021343AF -:100D5000C178827809020A43417800780902084381 -:100D60003946F5F7E7FA002806D104AA03A9069840 -:100D7000FFF7BFF80028DDD0822800D1002009B09D -:100D8000F0BD10B51488844201D2052010BD17248F -:100D90001C701080421E581C491C05F0C6F900202A -:100DA00010BD0000FEFF0000B40E002010B540484A -:100DB00004F04DF9002801D00C2010BDFF211131A5 -:100DC0003C4805F011FA3B4901200870002048809A -:100DD000E03188718874887520310871344804F0D6 -:100DE0004EF9002010BD10B5314804F028F9002854 -:100DF00003D031A1312005F016FBFFF7D7FF002803 -:100E000003D02DA1382005F00EFB10BD10B504460F -:100E1000274804F01CF9002801D00C2010BD2549FA -:100E20000878002807D0002008702148216004F0CD -:100E300026F9002010BD1E4804F021F91F2010BD26 -:100E400070B505460C461A4804F001F9002801D097 -:100E50000C2070BD174A5088A84202D11078002893 -:100E600004D0134804F00BF9122070BD1048226022 -:100E700004F005F9002070BD10B504460C4804F0DC -:100E8000E6F8002801D00C2010BD0A48017800299E -:100E900007D00020C0432080054804F0F0F812205D -:100EA00010BD40882080024804F0E9F8002010BD01 -:100EB0009D000020C00E00207372635C6C6C5F6448 -:100EC000622E630010B5282105F08CF910BD70B5B5 -:100ED000054600780A0700090001120F1043287028 -:100EE0000B0005F091FB07050705070509050B0039 -:100EF000062408E00C2406E0222404E00024F2A1E9 -:100F0000572005F090FA68788009800120436870C6 -:100F100070BD00780007000F704710B50622C01C96 -:100F200005F003F910BD10B50622093005F0FDF8F3 -:100F300010BD0278BF23C9071A40490E0A43027048 -:100F4000704702785206520EC9010A430270704778 -:100F500070B515460E4604461F2A03D9DAA1A8200B -:100F600005F061FA20462A463146093005F0DDF8E1 -:100F70006078AD1D80098001A906890E0843607064 -:100F800070BD70B515460E4604461F2A03D9CEA182 -:100F9000CC2005F048FA20462A463146093005F0B3 -:100FA000C4F86078AD1D80098001A906890E084348 -:100FB000607070BD70B501780907090F03292ED044 -:100FC000052931D1411C827E0C46437E1102194312 -:100FD000037FC27D1D02037EC67E1B021343827DFA -:100FE000407835438006800E22281DD106291BD368 -:100FF0001920C001814217D8FF26F436B54213D814 -:10100000002A11D0082A0FD88A420DD28B420BD861 -:10101000617F227F09021143814207D904E04078B1 -:101020008006800E0C2801D0002070BD012070BD0C -:1010300000210A464254491C2229FBDB704710B5A7 -:1010400002788B07920892009B0F1A430270427835 -:10105000520952014270012908D0022906D0032901 -:1010600005D0FF2098A1EE3005F0DDF910BD01217B -:101070000A43427010BD10B502788B0792089200A7 -:101080009B0F1A43027042785209520142700129A3 -:1010900007D0022905D0032904D08BA18E4805F082 -:1010A000C2F910BD01210A43427010BD00788007CB -:1010B000800F70470278EF23C9071A40C90E0A4310 -:1010C0000270704770B50546C1700B0005F09CFAC0 -:1010D0000E080A0C0E1012120C14141212160C1810 -:1010E0000C2413E0082411E002240FE017240DE083 -:1010F0000D240BE0012409E0092407E0062405E0A3 -:101100007548002470A1A03005F08DF96878400979 -:1011100040012043687070BDC0787047017AC27981 -:10112000080210437047817A427A080210437047E0 -:10113000017BC27A08021043704781794279080224 -:101140001043704700797047817B427B080210434F -:10115000704770B5017AC37909021943431C857A37 -:101160001C46467A2B023343657926792C02344398 -:10117000C21C5A4E00798D1FB54214D8FF25F43594 -:10118000AB4210D800280ED008280CD888420AD2CA -:101190008C4208D8507A117A00020843B11D884267 -:1011A00001D8012070BD002070BD0B4610B5011D97 -:1011B0000522184604F0B9FF10BD817A427A080270 -:1011C0001043704701717047007970470B4610B5A6 -:1011D000011D0822184604F0A8FF10BD027B0A700A -:1011E000407B487070470B46014610B508220E310F -:1011F000184604F09AFF10BD0B46014610B50422B4 -:101200001631184604F091FF10BD10B50822001DDC -:1012100004F08BFF10BD10B504220C3004F085FFE4 -:1012200010BD017170474171090A81717047C17128 -:10123000090A017270470079704781794279080282 -:1012400010437047017AC279080210437047017158 -:101250007047017170470B4610B5011D08221846F2 -:1012600004F063FF10BD10B50822001D04F05DFFFF -:1012700010BD70B515460E4604461B2A03D912A1AF -:10128000174805F0D0F82A463146E01C04F04DFF1F -:101290006078E90640094001C90E0843607070BDDE -:1012A00070B5054640780E46C406E40E1B2C04D9E2 -:1012B0000B4805A10C3005F0B6F82246E91C304673 -:1012C00004F033FF204670BD7372635C756C5F7011 -:1012D00064752E6300000000070200007A0C000015 -:1012E000F7030000C1074008C207C90FD20F511809 -:1012F0004008C207D20F51184008C207D20F511838 -:101300004008C207D20F51184208D007C00F40183A -:101310005208D107C90F0918500840187047002219 -:1013200002808271C271C2720273427382738270D0 -:10133000C270027142714276828303464284203336 -:101340009A7102859A72C2750276C2730274DA7259 -:101350001A739A7319750284FF21603081709A752F -:10136000704770B504460020A083208C1E46484379 -:101370001546114604F061FF2084F000294604F070 -:101380004EFF401C80B20146192269439202E0835D -:10139000914201DD401EE0837D202946000204F0D9 -:1013A0003EFF401CA08470BD70B50546087B0E460C -:1013B000C006C00E08730020A87504463019007AD4 -:1013C000FFF790FF29194874A97D641C0818E4B23E -:1013D000A875052CF2D3C0B2252803D979A18A209B -:1013E00005F021F870BDF8B5044630302646274692 -:1013F0002546C036A03780350090032909D0002942 -:101400001AD0012924D0022902D1A11CFFF7CCFF58 -:10141000F8BD1146FFF783FF002028836883A88367 -:10142000E883288468847871E88538732621085514 -:10143000A08430703071F8BD0020E885B871A188B3 -:1014400023890A460098FFF78CFFA11C0098DDE76E -:101450000020E885B38A328AA1880098FFF781FFCF -:10146000F8BD70B5867D0D460446002E01D0252EB0 -:1014700001D9122070BD002A18D0287EE17D50438A -:101480000818252104F0CBFE0846E1754207520FEB -:10149000C908504B69189A5C097A8A4368D031466A -:1014A00004F0BDFE491CCAB2002007E0002070BD58 -:1014B000002803D02118097C511ACAB22118497C8E -:1014C00091423AD32918097AC943CB07DB17D21ABC -:1014D000521E1206120E35D08B07DB17D21A521E7F -:1014E0001206120E30D04B07DB17D21A521E12060C -:1014F000120E2CD00B07DB17D21A521E1206120E38 -:1015000028D0CB06DB17D21A521E1206120E24D098 -:101510008B06DB17D21A521E1206120E20D04B0673 -:10152000DB17D21A521E1206120E1CD00906C9175A -:10153000511A491E0A06120E18D0401C0528B7DBA6 -:101540001F2070BDC00013E0C000401C10E0C000B0 -:10155000801C0DE0C000C01C0AE0C000001D07E0B8 -:10156000C000401D04E0C000801D01E0C000C01D9F -:1015700020769BE738B505460C466846FEF738F8F6 -:1015800000281ED0694600200856207209216156A5 -:101590000022411A00D5494220356B798B420FDC7D -:1015A000FF2B0DD0A17A491CC9B2A172AB79994227 -:1015B00002D8617A7F2903D160720020A0720122D3 -:1015C000104638BD7372635C6C6C5F7574696C2E09 -:1015D000630000007667010010B5040004D0FF200E -:1015E000FAA1AB3004F01FFFFB4821464143FB4802 -:1015F000FF230918FF330022581C5A544254C81DB7 -:10160000FF30FA3002704270F448001FC378A342E2 -:1016100002D18270FF23C370EF48EF4BC01E081841 -:101620009B1EC91802700A7010BD70B5EB480026E9 -:10163000001F8670FF24C47035462846FFF7CCFF94 -:101640006D1C2D062D0EF8D00020E4490B229201CE -:10165000E14B43435B189B181E74401C0006000EB0 -:10166000F6D0DF48FFF7E4FC0021DD48FFF722FD5C -:101670000121DB48FFF7E3FCDA4804704470847012 -:10168000C4700471447170BDCFE71B20704730B542 -:101690000021D24A0B239B01CF4C4C43A418E418E1 -:1016A000247C002C05D0491C0906090EF4D000202A -:1016B00030BDC94C01254C43A218D21815740170D5 -:1016C000284630BD10B5044600F0D0F900280CD0F3 -:1016D0002046FFF781FFC0490B224C43BF49002041 -:1016E0006118920189180874012010BD10B50446D4 -:1016F00000F0BCF9002802D0BA484471012010BDA6 -:10170000034610B5B748B44940794843B349421835 -:101710001046FF30E130C17F807F04F0D5FF10BD5F -:1017200010B5B048AC4940790F224843AB49401846 -:10173000A949D239095CFF30FF3004F09FFF10BD8A -:1017400010B5044600F092F9002802D0A5480471B3 -:10175000012010BD034610B5A2489F4900794843B7 -:101760009E4942181046FF30E130C17F807F04F06F -:1017700098FF10BD70B59B4C97492079974D484311 -:101780004019C11DFF31F931FF30E130807F0F2258 -:1017900004F064FF002813D020798F494843401992 -:1017A000FF30FF3002300178491C01700178407829 -:1017B000814204D1884885A1773804F034FE0120A5 -:1017C00070BD884884490079484384494018FF30F7 -:1017D000E130C17F807F814201D10120704700202C -:1017E000704770B57F487C49007948437B49401871 -:1017F000FF30E130867FC57F0F242946304604F054 -:1018000026FF002801D0204670BD70066906400EF4 -:10181000490E884201D3401A01E0081A201AC0B2CA -:1018200070BD0F20704770B50C46054600F01EF9DC -:1018300000280ED0002020706748454367482818CC -:10184000FF30FF300230017842788A1A22704170EE -:10185000012070BD70B50C46054600F007F9002860 -:101860000BD05D4845435D482818FF30FF300230FB -:1018700001784078081A2070012070BD5849016035 -:10188000704710B5044600F0F1F8002802D0554822 -:101890000470012010BD5149091FCA78FF2A02D0E7 -:1018A0000021016007E08A784C492439012A02D0DE -:1018B000016001207047002070474848801E017871 -:1018C000012908D001210170464801784348001FD2 -:1018D000C170012070470020704710B5044600F029 -:1018E000C5F8002802D03F484470012010BD3B4994 -:1018F0003C4B091FCA785B789A4206D18A78203916 -:10190000002A02D001600120704700207047334850 -:10191000344A001FC1785278914209D1FF21C17029 -:10192000801C0178002903D000210170012070473C -:101930000020704729482B4A001FC17852789142F5 -:1019400004D18078002801D0002070470120704722 -:1019500010B5044600F08AF8002802D02148C4706F -:10196000012010BD034610B51E481B49C0784843EE -:101970001A494018C21DFF320B21FC328901401860 -:10198000C17B807B04F0A0FE10BD10B51548124944 -:10199000C0784843114940180B2189014118C97B7F -:1019A0000D4AD21E8018062204F068FE10BD0D48B4 -:1019B0000949C0784843094941180B20800108189B -:1019C000C17B807B81420FD1012070477372635CC1 -:1019D000646D5F712E630000D1020000F40F0020DF -:1019E000C51200209E0000200020EEE710B504463E -:1019F00000F03CF8002802D021488470012010BD7E -:101A0000034610B51E481F49807848431E494018B8 -:101A1000C21DFF320B21FC3289014018C17B807B43 -:101A200004F03FFE10BD10B51548164980780B2212 -:101A300048431549920140181249891E41188018DF -:101A4000807B062204F00AFE10BD0D480D49807807 -:101A500048430D4941180B2080010818C17B807B49 -:101A6000814201D10120B0E70020AEE7002805D176 -:101A70000648007C002801D00120A6E70020A4E74A -:101A80009E000020D1020000F40F0020B4120020BC -:101A9000F8B5FF4E0446B079002500280AD0002989 -:101AA0002DD1657010202070F079A070307AE07030 -:101AB000B57124E0F64F203F387A012804D0707ABF -:101AC000012810D00020F8BD002918D1657013201E -:101AD000EF4920701C221639A01C04F026FB0120BF -:101AE000A0713D720BE0002909D165701420E8490E -:101AF000207008220A31A01C04F017FB7572012027 -:101B0000F8BDF8B5E3480178002902D00C2630462C -:101B1000F8BD0026DE4D3446403D2E756E75EE75DF -:101B20002E76AE75294620396E730F464E734037B8 -:101B30007E717F218170687E002804D0FDF73DFD15 -:101B4000FEF766F86C763C72D14884711430FFF76A -:101B5000B9F9CF483C30FFF7B5F9D8E710B5CD4B10 -:101B600000221A70CA4B203B1A711A46603A11665D -:101B7000D065FFF7C6FF002804D0FF20C6A187303C -:101B800004F051FC10BDC2484038007D7047C04988 -:101B900010B54039C87B897B42078307D20FDB0F22 -:101BA000D218C007C00F101840000B0004F02CFD25 -:101BB000050B060B04080F00BB4906E0BB4810BD2F -:101BC000B949083101E0B8490839085A10BDFF2069 -:101BD000B1A1A73004F027FC002010BDAC48B449E7 -:101BE0004038008A48437047F8B5A94C0646407B08 -:101BF000403CE07337791346A773012F26D0308815 -:101C00002082A348B27B203882710546603D29704E -:101C100006221946681C04F088FAB0796873062217 -:101C2000F11DE81D04F081FA607B0126002800D038 -:101C3000667597486038407B002800D0A6753B0049 -:101C400004F0E2FC0506082549084B000020D7E710 -:101C500000211DE08E4801211430FFF738F98C482F -:101C6000E91D1430FFF75FF9687B002807D00128D1 -:101C700007D0FF2088A1EE3004F0D5FB0CE0002156 -:101C800000E0012182481430FFF75BF904E00621EF -:101C90007F481430FFF71BF90020E07520767C4860 -:101CA000691C1430FFF739F9794829781430FFF7A7 -:101CB00040F9774804213C30FFF709F97448691C62 -:101CC0003C30FFF72AF9724829783C30FFF731F9A8 -:101CD00026750020F8BD0221DAE7FF206EA1F8305A -:101CE000CAE770B56A4C0125403C0346257620467C -:101CF0002030007A002801D03A2070BD64480022CC -:101D0000803806789E4206D1E2750622401C04F017 -:101D10000CFAE57500E02276002070BD70B504462F -:101D20005B4D0020403DA87528462246323804F01D -:101D3000FCF92846203844730120A87570BD544929 -:101D400020390871704710B5514C0022403C627533 -:101D5000607302462046123804F0E7F901206075EE -:101D600010BD4B49203948717047F8B500F0A4FB0D -:101D7000474C0025403C607E002804D0FDF71DFC48 -:101D8000FDF746FF6576434F3D70FDF793FBA07B63 -:101D9000012804D00021084601F0A6FAF8BD002170 -:101DA000022001F0A1FA3A4C203C207A002809D008 -:101DB000374881790029F1D11321C17105720121C0 -:101DC0008171F8BD78780028FBD0314E0622803E24 -:101DD000707BE0733078A0753046F11D703004F0F0 -:101DE000A4F930460622711C773004F09EF93C209D -:101DF000A072012020727D70F8BD10B5244C403CCB -:101E0000E17BA07CCA0701D0C2070BD08A070FD59F -:101E100082070DD42620FDF777FAA07C0221084323 -:101E2000A07410BD2520FDF76FFAA07C0121F6E714 -:101E30004907F6D54007F4D42720FDF765FAA07CC2 -:101E40000421ECE770B5134E3078002872D1104CA5 -:101E5000403C207D00286DD0FDF71FFB0025A574B8 -:101E6000E57475702846FDF715FB0020FDF78CF929 -:101E70000D480D38FDF73FFA0B481038FDF7F7FA1B -:101E8000FDF76CFBFFF7B9FFFDF7FFFA012111E049 -:101E900068130020A40000207372635C6C6C5F61A7 -:101EA00064762E63000000008E6701009A8913009B -:101EB000710200000020FDF743FA0F210520FDF715 -:101EC000C1F92646403E3178701CFDF7ADF9A07B84 -:101ED00001280CD004280AD0607D002807D02146B4 -:101EE00012390846627B6630FFF732F86575A07DCF -:101EF000002807D0FE480146427B12399C30FFF78C -:101F000040F8A575306E0178002903D00178001DD6 -:101F1000FDF7C8F9F06D0178002906D0F44A401C9D -:101F2000C732FDF754FE01206076FDF7C3FA0020AA -:101F300070BDFFE70C20FBE7EE494860704770B5C5 -:101F4000050001D0FFF759FFE94C2034E07C002860 -:101F50000AD0A07B012804D19920E749C00004F0F1 -:101F600062FAFFF702FFE3E7002D0DD00221002007 -:101F7000FDF7E6F9DE4840300079032801D001285A -:101F800002D10220FDF73BFCE07D002600280DD0A9 -:101F9000D74D203D2846691C9430FEF7BEFF2846E9 -:101FA000691CBC30FEF7B9FFE6752676D048743060 -:101FB000FDF786FAA07B030004F026FB0504040469 -:101FC0000D04090001210846FDF79FFB03E0CA4903 -:101FD000CA4804F028FAE17BA07C81430120002953 -:101FE00003D1A17B012903D0E074C24908709FE7A7 -:101FF000A674FAE710B5FDF750FABE48007800283D -:1020000018D1BB482030007D002813D00020FFF7F6 -:1020100096FFB74840300079002809D001280FD03A -:10202000022805D003280BD0B349B54804F0FBF9CA -:10203000002010BD00F040FAFDF73CFA0C2010BD66 -:10204000F0F7E6FFF4E7AB49012048707047F8B5B8 -:10205000002400F0E0FF002824D0FF202D30FDF701 -:102060006CF9A44D2878A24F403701281DD00228D2 -:1020700001D0032834D0A2489F496B3004F0D3F933 -:10208000287800280DD0387900280AD0012808D0F7 -:10209000022838D0032836D099489749803004F078 -:1020A000C2F9F8BDFFF761FEF8BD914E2036B07B56 -:1020B000032815D0707E002803D0FDF798FDFDF7AA -:1020C00074FA8B48C430FDF7FBF9B07B012812D0BD -:1020D000042810D0B879012806D0032804D004E0E1 -:1020E0000120FFF72CFFCBE7102421460E200143EF -:1020F0000020FDF70AFB7879012801D1FDF76FFA7E -:1021000002202870BCE728780228CDD10120FDF7F5 -:1021100076FBF8BD70B5764840304079012801D192 -:1021200000F0D4F9724C2034607E002803D0FDF713 -:1021300044FAFDF76DFD00F06EFF00280CD06D4DE8 -:102140002878022804D06E486B49A33004F06BF95C -:10215000A07B012803D006E0FFF707FEE8E6992000 -:102160008000FDF7EAF80120FFF7E9FE2878002853 -:10217000F4D028780128F1D039205F49000104F01B -:1021800052F9D5E6F0B5074689B000200690FDF774 -:10219000AEF800900020019056480078022804D044 -:1021A00057485549F03004F03EF9514D40356879B3 -:1021B000012801D100F08AF94D48C430FEF7A9FE8C -:1021C0004B4E04462036002F70D03046A430FEF728 -:1021D000F1FE0028F8D0FDF731F80028F4D0707E29 -:1021E00000280AD005277F1EFFB2FDF72CFD02282C -:1021F0000FD0012800D0002001903D492046C43175 -:102200000C46643C030004F0FFF906A4A4A40CA44B -:1022100056A4002FE7D177203AA1C00004F003F9BB -:10222000E9E7B07B012841D004283FD0019A00980B -:10223000104304D1A879002801D0022836D168794A -:1022400001281DD1607A00281AD101206072087817 -:1022500006224006C00FA0722548C91C6B3003F04F -:1022600064FF244C224FA07871377F2804D1A92025 -:1022700024A1C00004F0D7F8A07838707F20A070A7 -:102280001B489C30FDF71CF91A480321017028797E -:10229000002860D001280AD002285CD0032806D08C -:1022A000164818A1E03804F0BEF854E051E00120CF -:1022B000FDF7A5FA4FE00E480F462038C978C079DF -:1022C000814230D10A4839792038027A91422AD1A4 -:1022D0007979427A914226D1B979827A914222D192 -:1022E000F979C27A91421ED1397A027B914211E08A -:1022F00008130020A4000020981E0100F60400002E -:10230000DE0200007372635C6C6C5F6164762E6346 -:102310000000000007D13978407B4906C90F81428F -:1023200001D1012100E00021B07B012801D0042867 -:1023300001D100290AD100280BD101990098084346 -:1023400004D1A879002801D0012802D1307E0028CC -:102350001FD001200690707E002803D0FDF72DF9D4 -:10236000FDF756FC0698002802D00120FFF7E7FD94 -:102370005D48017800290AD00178012907D000784A -:10238000032804D095205949C00004F04CF809B046 -:10239000F0BD55480422406855490F3003F0C5FE92 -:1023A000387806224006C10F4F4840680177F91C73 -:1023B0001D3003F0BAFE4C484D4940680322091D08 -:1023C000133003F0B2FE4848494A4068B97D817530 -:1023D0000F3A117ED37D09021943018311468B7E8A -:1023E0004F7E1B023B438380137FD77E1A023A4302 -:1023F000C2808A7F4B7F1102194301813C4905222B -:1024000010310A3003F091FE3948374A1130017912 -:102410005768C906C90EB97600794009F876287A56 -:10242000002809D0A07900283AD11320E0710020BB -:1024300020720120A07133E00020A8727888B08556 -:10244000387FE8732A48394606221D31833803F065 -:102450006CFE27490622F3390878A87508467730BC -:10246000491C03F062FEB888F087F888208038891C -:102470006080F87E20710198002860790BD00121DE -:1024800008436071FDF7F2FB61794000C907C90F8D -:102490000143617102E04008400060710120287230 -:1024A000114C0020207000F007F8FDF703F8012020 -:1024B000616800F019FF4EE710B5FDF76AF8FDF707 -:1024C0005DF8FCF7B5FFFCF7DAFF10BD064810B564 -:1024D000801CFDF78DF8002802D103497F20887009 -:1024E000FDF774F810BD0000A400002004230100D3 -:1024F000DB1300208107C90E002808DA0007000F4F -:1025000008388008F74A80008018C06904E0800815 -:10251000F54A800080180068C8400006800F7047A8 -:1025200010B500F03BFF10BD70B5F04C0546626879 -:10253000002908D0002A04D0FF20EDA10C3003F0C0 -:1025400072FF656070BD002A04D1FF20E8A112303F -:1025500003F069FF0020606070BDE948C07E7047ED -:10256000E7482830C07E704738B5E04C20680168E5 -:102570004978012925D001216846FAF7C9FC684647 -:102580000078E049000203F04AFE2068426AC06811 -:1025900012685118FBF7ADFC2168C860D84A206862 -:1025A00028320321904218D0028B002A15D0012234 -:1025B0004272017200210171021D017F00F0FBFED9 -:1025C00038BD7D21C068C900FBF793FC2168C86055 -:1025D000FFF7DDFA21680861E0E7028B521C0283F5 -:1025E0004172E6E7FFB5C64E85B0706A346805688B -:1025F00060680190306A0390298E0798401A80B273 -:1026000002900898002804D02746383720464830E2 -:1026100002E0371D2846A830009003203871059845 -:10262000002820D001287DD002285ED003287AD04F -:10263000AFA1B54803F0F7FE0898002807D0387915 -:10264000032804D0B048AAA1093003F0ECFEA16A27 -:102650007069FBF74EFCB860616A206A88427DD9D8 -:10266000009801601FE1306A002804D1A648A0A1AB -:102670007A3803F0D8FEA449288B373948434018EC -:10268000069900F0A6FEA0619F49A8883739484303 -:10269000069900F09EFEE061316A9B48891CA162A8 -:1026A0002A8B37384243A069974B121AE63BD2185F -:1026B0005118A162944BAA7D373B5A4340008018C1 -:1026C000FF30193020626062306A081AED21FF384D -:1026D000C90015388842AFD28C49884204D28A4852 -:1026E00083A15D3803F09FFEB6E0874A288B373A16 -:1026F000E16850430818069900F06BFEA06182491A -:10270000A88837394843069900F063FEE061306AD3 -:10271000002804D17C4876A1553803F084FEAE2011 -:10272000405B01E02CE05AE00028288B784AE16801 -:102730001DD050430818A169401AA0622169A06801 -:10274000734A4843A1694018A97D4000514340188D -:10275000FF3017302062A888504300E0A1E0E16913 -:10276000411A6F20C000081A6062A06A34E050432A -:102770000818A169401A3168D63849684018DCE762 -:10278000284680300190C08D002802D0306A002891 -:1027900004D15F4856A1401F03F045FEA8885C495C -:1027A000E3694843C01AA06201999C46CA8D216919 -:1027B000A368521A4B43A169591863465343C91879 -:1027C000AA7D534B49005A438918FF3117312162C2 -:1027D0006F21C900411A6162316A401A35E00898D8 -:1027E000002803D03420005D002878D1A88848490B -:1027F0004843E169401A02994843A0622846803064 -:102800000490C08D0028019829D0002804D03E48AB -:1028100037A1163803F007FE04983D4AC18D02988F -:102820000818E16948434000FF3017302062A8884B -:102830005043411A6F20C000081A606200F0AEFDDC -:1028400000281CD0A16A0398081AED21FF38C9009E -:102850005538884200D3EFE601203871ECE60028B5 -:1028600002D00398002804D1294821A11A3003F08E -:10287000DAFD0198A16AD6380818A062CCE7FBF708 -:102880009EF8726901461046FCF7BFFAA16A081A61 -:10289000ED21FF38C90050388842DCD2012009B050 -:1028A000F0BD0099086000981A4900688035081842 -:1028B000F860298B0798081A00B2002804DD0598F3 -:1028C000022801D0032000E00120787108983870B8 -:1028D0000898002820D03420005D00281CD0022059 -:1028E000DDE7000000ED00E000E400E0B4000020BF -:1028F0007372635C6C6C5F6C6D2E73302E630000C2 -:10290000F413002010270000190500002902000020 -:10291000E20400004B1700000898012148402034D1 -:102920006075317F3A46304600F045FD0020B6E73D -:1029300010B5FE4900280A68516A096807D0126874 -:102940008988FB4BD2695943891A03F068FC10BD92 -:10295000F8B5F64F38680468416A26460D68203697 -:10296000717D00290AD0618E2A8E914206D1407A6B -:10297000012803D1EF49F04803F055FDFBF71FF89C -:10298000014638684069FCF740FAFFF7D1FF2A8E0C -:10299000618E1318994202DB491C618602E0401CDB -:1029A00010186086B07D002806D19C21608E495B9E -:1029B000884201D1401C6086DC480168088B0328EE -:1029C00002D2401C088302E0618E982041532846C1 -:1029D00040300646C1898089081A298E401E401859 -:1029E00087B218E0D148EB7E00685B00406A00794E -:1029F0004100D248415AC05A401881B2207D00237C -:102A0000FFF7F0FD00280FD001280ED0CA48C949B1 -:102A10003A3003F008FD628EB81A00B20028E1DAFD -:102A20000820B07200F010FEF8BD608E401C608679 -:102A3000F1E770B5BD4D002168680162C27E1300E8 -:102A400003F0E2FD045656034A56426A14680268CF -:102A500011700268516000682030407D002808D164 -:102A6000FAF7ADFF69680968096CFCF7CEF9002830 -:102A700018DC6868228E0168498E914206D1214691 -:102A800080318B8B9A1ACA83238605E0891A9E228D -:102A900011530168498E21860268C1681164C168BA -:102AA000416111E068680168098E228E8B1A224606 -:102AB0008032D3830168098E218601680B6CC36064 -:102AC0000B6C4361886C9062204601F0D8FC0028B2 -:102AD0000DD098499A4808E0C1684161FFF7B2F902 -:102AE000002804D096489349801D03F09CFC70BDDB -:102AF000934890490D30F8E710B58C4A0B001268E6 -:102B000003F082FD0906090F1F0C2E2E082B2E0044 -:102B1000FFF78FFF10BD00F068FC10BDFCF772FEE0 -:102B200010BDD07E022806D0D07E032806D0FF201C -:102B30008049A3300EE0FFF70BFF10BDFFF714FD37 -:102B400010BDD07E0228F6D0D07E0328F6D0FF201C -:102B50007849AE3003F067FCF0E7FAF715FF10BDD7 -:102B6000FF207449BC3003F05EFC10BDF3B581B0AA -:102B70000E4601276D4D734C0B0003F045FD090611 -:102B80002F39392F40403939400001216D48FFF776 -:102B9000CBFC31460198FFF7AFFFE07E022826D13B -:102BA00068680568406A0668FAF7E7FEB188604A17 -:102BB0005143EA69891AD639E962B72802D26248D4 -:102BC000081803E0081A6049B7314018E8625F4806 -:102BD000E96A814200D80846E86205E00198FFF7FB -:102BE0008BFFE07E022802D1206820300775FEBDF1 -:102BF0002C600198FFF780FF00202860FEBDFF20B9 -:102C00004C495C3003F00FFCFEBD70B50C46064627 -:102C10000B0003F0F9FC09060D10100D1A1A101024 -:102C20001A00484801212830FFF77EFC2146304633 -:102C3000FFF762FF70BD43483C4D283028603046A6 -:102C4000FFF75AFF0020286070BDFF20394982300D -:102C500003F0E9FB70BDF0B5344C0020216885B06D -:102C600003258D76CA7E0746032A03D0C97E002934 -:102C700029D029E0087F002803D12E49344803F0E9 -:102C8000D2FB2068067F684605714571FAF797FE0A -:102C90000290FF20F53003900121684601706946DB -:102CA0003046FBF70CFB00E020BF2068007FFCF7FC -:102CB00038F90028F8D02068007FFAF765FE206810 -:102CC000077700F072FB012021688F7605B0F0BD18 -:102CD00016490A68907600E020BF0A68D07E002876 -:102CE00003D0D07E937E9842F6D0D07E002803D0C9 -:102CF00000200021917670470120FAE770B5114954 -:102D00000024CA7E094D032A03D02831CA7E032A33 -:102D10002ED12960002827D0012821D00C48054950 -:102D2000973003F080FB0020296813E0B4000020F6 -:102D3000E2040000F0280100F70500009E67010092 -:102D4000A1030000F4130020C4F8FFFF38120000B4 -:102D500072020000086048622860002C08D070BD34 -:102D60000320FFF7B5FF01E0FFF775FF0446DAE740 -:102D70000C2070BDF8B5F94F04461F25E67E3300E0 -:102D800003F042FC042920031B20F548844204D0B0 -:102D9000FF20F449FC3003F046FB02203C60FFF7C3 -:102DA00097FF002805D03968002008604862386025 -:102DB00011E00C25002038600AE00120FFF79EFF9B -:102DC000054603E0E749E84803F02DFB002D02D05B -:102DD000E07EB042D2D1E07E002804D0E248E14952 -:102DE000801D03F020FBF8BD10B5DD48FFF7C2FFE2 -:102DF000DB482830FFF7BEFFD94900205031087565 -:102E0000D649C91F4870D64948610A4628325061E0 -:102E100088769076D1494860086010BD70B5044648 -:102E20000120FFF767FBC5B20B20FFF763FBC0B2C1 -:102E3000854204D0FF20CB49C63003F0F4FA0120CC -:102E4000FFF758FBC5B21820FFF754FBC0B285420C -:102E500004D0FF20C349C73003F0E5FA0420C04383 -:102E6000FFF748FBC5B21920FFF744FBC0B285420B -:102E700004D0FF20BB49C83003F0D5FAB748B849A1 -:102E8000083804700020C87688760A462832D07642 -:102E90009076B24B012408331C711860486250626E -:102EA00008601060FFF7A0FF70BDAC4908310871E1 -:102EB0007047FEB5AA49CA7E08462830A74C002AAA -:102EC00002D1C27E002A03D0C97E022903D005E0C8 -:102ED000A648216006E0C17E002901D00C20FEBD7D -:102EE0002060A348FAF7FCFC216808779B4920681A -:102EF000C91F0160C91C4162007F002804D1AD20B8 -:102F00009849800003F08FFAFAF737FD9949884213 -:102F100000D20846FF30C83086B220680325C57647 -:102F2000FEF735FE21680861FEF758FE00270028ED -:102F300027D0FEF753FE21684A6A10600968012015 -:102F4000087001466846F9F7E3FF684600788A4949 -:102F5000000203F064F90191FAF731FD019971184B -:102F6000FAF7C7FF2168C8602068057245720771CB -:102F7000021D017F00F01FFA2068078300202760F0 -:102F8000FEBDFAF71CFD3146FAF7B3FF2168C860B1 -:102F900008680770096801204870E5E77047F8B5D0 -:102FA0006F4EF17E002904D131462831C97E0029B7 -:102FB00001D00C20F8BD0221F176694C674F5034E6 -:102FC0000837776234600025386025753979C07E0E -:102FD0004A006A4940008A5A085A2B46101881B2A2 -:102FE0002A462846FFF7FEFA002804D0CF205D4984 -:102FF000800003F018FA25610120A5602075658620 -:1030000025865748703085753968088E401E0886B9 -:1030100035830020F8BD10B5504801244068817EFA -:1030200003290CD001684978002906D0006A544968 -:10303000884202D90024FFF706F8204610BD00247C -:10304000FBE74648406802681178491C1170016A24 -:103050000068C26A914204D8007D012801D0012095 -:1030600070470020704700207047F8B53B4C3C4843 -:103070002060416A00680D68002634210E54A621A4 -:10308000495D00294BD1007D032848D1FAF797FC10 -:10309000014620684069FBF7B8FE00283FDDFFF7D6 -:1030A00047FC298E401C4118206802681186006880 -:1030B000018E9C22525B511A09B200292FDD012199 -:1030C0002030817528464030C1898089081A298EB0 -:1030D000401E401887B21BE0496A09794A00274917 -:1030E0008B5A028E007D9446EA7E5200895AC91896 -:1030F00089B201236246FFF775FA00280FD0012834 -:103100000FD002280BD01B481649193803F08BF951 -:1031100021680868028EBA1A12B2002ADCDA266028 -:10312000F8BD20680068018E491C0186F0E7F8B5FB -:103130000A4D00266A680128516A0C6853D1087943 -:103140000E4940000B5A1068077D032F1AD0027DEC -:10315000022A24D0007D012834D044E0B4000020AD -:10316000F4130020F0280100070200006D2B01007D -:103170000B2C0100F6050000102700009E670100DF -:10318000D98213000661106886609C20025BE07E95 -:103190004000085AC01881B2002303201BE02246D9 -:1031A0008032D78D0761E07E928B4000085AC018AC -:1031B00081B200230220FFF715FA6A680121126824 -:1031C00011750AE09C20025BE07E4000085AC0189E -:1031D00081B200230120FFF705FA002803D09C49A3 -:1031E0009C4803F020F9FAF735FB9B480078EFF78D -:1031F0006FF8686806830268218E51860068203067 -:103200008675F8BD38B5944C0021083460680D46C9 -:1032100000684278002A01D045701FE0007800283D -:1032200009D001216846F9F773FE684600788B499A -:10323000000202F0F4FF6068426AC0681268511828 -:10324000FAF757FE01466068C160057103214172BB -:10325000021D017F00F0AFF860680583FAF7FAFA03 -:103260007D480078EFF734F838BD7B4A10B5014649 -:10327000083250680B0003F0C7F9060D1504081753 -:103280000C31012100F0D1F807E00021106800F0B6 -:10329000CCF810BD0120FFF74AFF00210846FFF7D8 -:1032A00043F910BD032116E0416A02680968D36939 -:1032B00093608A886A4B5A430368DA600A46C032D0 -:1032C000D3890B83137B8B75138A8B80538ACB80B6 -:1032D000928A0A8102210068017510BD5D485C492F -:1032E000913003F0A0F810BD70B500280BD05A4CF7 -:1032F000083401280ED002281ED056485449B43054 -:1033000003F091F870BDFFF77DFF00210846FFF73D -:103310000BF970BD6068002501684D7000F045F83C -:103320000320F5F7B8FEFAF795FA4B486560007888 -:10333000EEF7CEFF656070BDFFF764FF606800F0D8 -:1033400034F800210846FFF7EFF80420F5F7A3FE54 -:1033500070BD414908314968CA7E022A08D10A680D -:103360001378002B04D150600968CA6A1018C8622B -:103370007047394A10B50832526800290CD001292B -:1033800007D0022907D033483149D93003F04BF830 -:1033900010BD801E00E0401F106210BD2E48083096 -:1033A0004068002800D0012070470021C176817656 -:1033B00001604162704710B50B46C17E847EA14218 -:1033C00004D011461846FAF77AFF10BDFFF7EDFF5B -:1033D00010BD024610B50020002905D00846504314 -:1033E000204902F01CFF401C10BD1B4810B50830DE -:1033F0004068C07E030003F007F9041515030B15A0 -:1034000001F05EF900280CD00F2017A1800106E022 -:10341000FEF7F0FD002804D0F12013A1800003F096 -:1034200002F810BD10A11448F9E710B504460029B0 -:1034300003D00020FFF77BFE03E007480078EEF79B -:1034400047FF2046FFF7B1FF0020F5F724FE10BD2F -:10345000F028010092060000AC00002010270000B8 -:10346000E204000040420F007372635C6C6C5F6C9E -:103470006D2E73302E630000CB030000F8B5FEF70D -:10348000B0F90446FEF756FAF84E0546706920304A -:10349000407D002809D0012827D002282AD00328FF -:1034A00032D0FF20F2A19A3037E0F0481830FEF712 -:1034B0001EFA002801D003200FE0EC481830FEF778 -:1034C00049F9002804D070695B21095C002908D003 -:1034D000E6481830FEF7D2F90120716920314875AD -:1034E0001DE002212030417519E0E0481830FEF758 -:1034F000C5F914E0DD481830FEF72CF900280ED18C -:10350000FF20DBA18C3008E0D8481830FEF7EFF937 -:10351000002804D1FF20D6A1943002F084FFB069C6 -:10352000F72201781140017072692032937DDB0728 -:103530001B0F1943FB2319400170D37DDB075B0F81 -:1035400019430170577DEF23022F04D0012F07D0BC -:10355000032F07D00CE0012C06D8002D04D007E083 -:103560006D1E2C43002C03D019401023194300E09A -:1035700019400170D17F002916D0517D012913D047 -:10358000BF48FBF79DFFBE480021283001767269D5 -:10359000916ED26E42610161B949B269FCF7A3FA3A -:1035A0000020FCF7AFFA03E0FBF78AFFFCF7CDFA47 -:1035B000B0690078C00606D4F0690078C00602D46D -:1035C000F079002806D0B079002803D101210846FF -:1035D000FCF79BF8032030703079002803D1FBF70B -:1035E000BDFF01203071F8BD70B5A0481C30FEF75A -:1035F000B9F901259D4C002802D00020607002E03E -:1036000065709F48E061606940300078002802D012 -:103610006078002805D0E069FBF752FFFCF795FAC7 -:1036200070BD9748FBF74CFF9548283005766269D6 -:10363000116F526F42610161914AE169FCF753FADF -:103640000120FCF75FFA70BD10B588490023486976 -:1036500002462030C3768377012049239854A03254 -:103660009279002A03D008700021022001E0002195 -:103670000320FFF7FAFD10BD70B57C4C6079C206DF -:103680002046406901468031002A01DA002202E02A -:10369000CA8DCB8BD218CA850246C0321379002B53 -:1036A00005D0034640331D8AC98B69181982617A97 -:1036B000002903D03D2001F051F94AE003462033B0 -:1036C000D97E042945D0217A002913D0480701D496 -:1036D000C80601D51E2030E0080701D53D202CE0AA -:1036E000C80705D1880703D461A1664802F09BFE94 -:1036F0002A2022E04030817D002905D0418A4D1CDE -:103700004582858AA9420FD2517A062902D0117AC0 -:10371000062905D1018B4A1C0283828A914203D279 -:10372000028AC1898A4201D3222006E09A7F8089D9 -:10373000002A0AD088420FD3082001F00FF96069EF -:103740002030C07E042804D006E0062804D33E20A2 -:10375000F3E7FFF779FF70BD0120207000210846D4 -:10376000FFF783FD70BD10B5404840690146203128 -:103770008A7F002A29D0012A27D0022A06D0032ACC -:1037800004D03BA1404802F04EFE10BDC97E032983 -:103790000FD0082919D001464031CA898989511AA8 -:1037A000891E89B2032900D303218030828B5118EE -:1037B00009E0014640318A89032A06D3028EC9896D -:1037C00080305118491C018310BD8030818BFAE78D -:1037D00000B5030002F018FF0604070B0F121217C2 -:1037E00000290ED00FE0891E02290AD90BE0891F9B -:1037F000012906D907E0082903D004E00B390C2978 -:1038000001D8012000BD002000BDFEB505461748C7 -:103810001830FEF740F8002804D11B4814A1D13815 -:1038200002F001FE114CA069FDF702FC0321A06922 -:10383000FDF721FCA069EF220178114001702946B3 -:10384000FDF740FC002601272B0002F0DDFE0E5C98 -:103850005C085C2C6060255C4C5C603C375C60699B -:103860006521095C002911D0062111E0C400002067 -:103870007372635C6C6C5F736C6176652E630000C1 -:1038800090140020430200005C080000C030417921 -:10389000A069FDF797FC3AE060698030417CA0693F -:1038A000FDF7D7FC33E06169A069B831FDF7ADFCE5 -:1038B0006169A0698C31FDF7AEFC28E00621A069A2 -:1038C000FDF7C5FC23E020690178A069FDF7A9FC9C -:1038D00020698188A069FDF7A6FC20694188A0695C -:1038E000FDF7A5FC13E00096019660696030007951 -:1038F000002803D069460878384308706946A069F3 -:10390000FDF7B1FC03E0F949F94802F08CFDFDF741 -:10391000D4FF002804D1F648F449801D02F083FD4D -:103920000C2D06D0072D03D0606940304682877584 -:10393000FEBD606940300683FEBDF0B5ED4CC82089 -:1039400061698DB0405C04280AD0052835D15C201F -:10395000405C00282AD0012060314871022026E016 -:1039600010226846D63101F030F86169102204A8AF -:10397000B03101F02AF8684601F0DFFB08AE8DCEC9 -:10398000616984250E4678360DC66F5000250D6797 -:103990004D67012540267554D74D88318DC5284681 -:1039A0000822093002F0C1FB052000E00D20FFF7DE -:1039B0002CFF61690020C03108720DB0F0BDF8B570 -:1039C000CC481830FDF767FF002848D0C94C207A52 -:1039D000002844D16069C421095C002500290ED06B -:1039E0002030C17E0120FFF7F3FE002807D1606977 -:1039F0002030C17E0420FFF7EBFE002806D060696E -:103A0000C921095C0126062907D00DE06069502113 -:103A10000D526030457102204EE02030C17E0420FE -:103A2000FFF7D6FE002813D0616908462030C27E19 -:103A3000921E130002F0E8FD166262621D6262626D -:103A400060621F6262622843626262626262466210 -:103A500060695E21095CC90702D0C0304572F8BDBB -:103A60000C20FFF7D2FE60694030817F31438177BF -:103A7000F8BD072020E0FDF79AFF0028F8D0606924 -:103A8000403005700B2017E0F9F741FA0C28EFD30E -:103A900060690821B830F9F73BFA002806D0606960 -:103AA00004218C30F9F734FA002804D1C72093A1FF -:103AB000C00002F0B8FC0420FFF7A7FEF8BDFFF736 -:103AC0003CFFF8BD00228A66CA66C6770A4678318E -:103AD000C8C9894878322838D26842632830C8C0BB -:103AE00008220D30091D02F020FB0620FFF78DFE95 -:103AF000606940308575F8BD0920DDE700F036FFCC -:103B0000F8BD70B57B4C3B216069095C08292FD159 -:103B10000146028EC0314B89521C9A4228D1227A2A -:103B2000002A25D10A8A83889A4207D14B8AC58800 -:103B3000AB4203D18B8A0589AB4209D043884B85C0 -:103B40008A854A8ACA858A8A0A860122E6210A5417 -:103B500001221146FDF747FC00210420FFF785FBF9 -:103B600060690021C92211542030C1760321817778 -:103B700070BD70B55F4C60692030C07E172803D0DF -:103B80005EA1624802F04FFC616900220B4640339F -:103B9000DA7608469A75E030867D0B240125002EE2 -:103BA00006D0837C002B14D1C4740275857410E098 -:103BB0001E7F002E07D01A774C88FA235C520276BB -:103BC0000C23837505E04E88FA235E520276057752 -:103BD00084752031CA7670BD70B5464CA0798007D7 -:103BE00036D5207A002833D160692030C17E01208B -:103BF000FFF7EEFD00282BD1A0690126C078002533 -:103C0000030002F001FD0E8585088537465F0A85B1 -:103C1000168526625285032152E060692030C07EFD -:103C2000052804D0394835A1333802F0FCFB60691F -:103C30000CE060692030C07E092804D033482FA1F1 -:103C40002D3802F0F0FB606956210D542030C57606 -:103C500070BD60692030C07E0B2804D02B4827A19E -:103C6000263802F0E0FB60695B210E540C21203005 -:103C7000C17670BD60692030C07E0F2804D0234813 -:103C80001EA11F3802F0CFFB60695B210E5410218A -:103C9000EDE760692030C07E102804D01B4817A1D2 -:103CA000183802F0C0FB12210AE060692030C07EA3 -:103CB000102804D0154811A1123802F0B4FB1421C9 -:103CC0006069D4E7FFF755FF70BD60690146C030F9 -:103CD000027A062A04D14031897F890700D505720E -:103CE000417A0629F0D1457270BD0000703801009C -:103CF000CD070000C4000020B81400207372635C7C -:103D00006C6C5F736C6176652E6300004C0500007F -:103D1000FD49FE4802F087FBE6E710B5FC4C606900 -:103D20002030C17E0020FFF753FD002803D1207A08 -:103D3000012108432072207A002808D1E069FDF7AC -:103D4000EBF961699122505405202031C87610BDED -:103D500010B5EF4C60690146C0314A7A002A06D09E -:103D6000097A062903D0217A012211432172217A8E -:103D7000002928D14030807F800715D4E069FDF705 -:103D80005AFA61694031C877E069FDF756FA61690E -:103D900040310884E069FDF755FA6169022240313B -:103DA0004884887F10438877606900220146C031CB -:103DB0000B7A062B00D10A724030837FDB0702D1D9 -:103DC00006234B72028310BDF8B5D14C60692030D8 -:103DD000C17E0020FFF7FCFC0125002807D16069A7 -:103DE0004030007F002802D1207A28432072207AB8 -:103DF000002830D160690026014640304682857532 -:103E0000B031E069FDF7EFF96169E0698831FDF7EC -:103E1000F3F960690146E030827D0827002A06D068 -:103E2000817C002913D1C774067585740FE04A8818 -:103E3000F8204252FA31E069FDF7C8F96169E0699A -:103E4000FF310331FDF7CAF96069E03087756069B9 -:103E50000F212030C176F8BD10B5AD4C606920301F -:103E6000C17E0020FFF7B4FC002803D1207A012195 -:103E700008432072207A002812D1E069FDF769F921 -:103E800000280ED0E069FDF75FF96169CA2250523F -:103E9000098E00F0D6FD002806D0282000F05EFD37 -:103EA00010BDFFF73AFF10BDE069FDF74BF96169FE -:103EB000C0310873E069FDF740F96169C031C8811C -:103EC000E069FDF72BF96169C0310882E069FDF70F -:103ED0002AF96169C0314882E069FDF729F9616911 -:103EE000D422505208202031C87610BDF8B5884C35 -:103EF000A079C00776D0207A002873D1606920307D -:103F0000C17E0120FFF764FC002863D1E069002531 -:103F1000C178022701260B0002F076FB0D1613086C -:103F2000415A5A445C575A192F545A00FDF74CF91C -:103F30006169C62250543B20475440314D828E75F2 -:103F400048E000F093FD45E0FFF786FF42E060693E -:103F50002030C17E0020FFF73BFC002802D1207AF0 -:103F600030432072207A002834D160690146403104 -:103F70004D828E750B2120300FE0606901462030A4 -:103F8000C27E0C2A02D0227A3A432272227A002A76 -:103F900020D1C57740310E770D21C1761AE0FFF7A9 -:103FA00013FF17E0606901462030C27E122A02D05A -:103FB000227A3A432272227A002A0BD140318D753F -:103FC0001721EAE7FFF7C4FE04E000F00DFD01E071 -:103FD000FFF7A3FE62690023106F516F401C594127 -:103FE00051671067F8BDF8B5494C05466069203047 -:103FF0008079012801D1FBF7E9FA012D14D160691C -:104000004021095C002903D12030C07F002801D065 -:10401000FBF79BFDFBF7BDFAFBF7B0FAFBF708FADD -:10402000FBF72DFAFBF746FA60790225C107012656 -:10403000002901D180070ED560692030817F0029D9 -:1040400002D0032902D006E0867700E085770021C0 -:104050000120FFF70AF960692030817F012903D12F -:104060006179090700D58577607A002803D100F0CF -:1040700027FDFFF7A4FC207900250028606902D005 -:104080008030058403E08030018C491C0184607914 -:10409000C00705D06069AC210D544030858104E033 -:1040A000616940318889401C8881E079002806D008 -:1040B0006169A031087B022806D8401C087360693A -:1040C000A030007B022806D9606901468030058453 -:1040D0004584A0310D7360692030C17E0020FFF758 -:1040E00077FB002804D160692030C07E072855D1B5 -:1040F00060690146C0310A7A062A4FD0497A0629FA -:104100004CD03E21095C05E0FC3C0100BA050000F2 -:10411000C4000020022941D1A030007B00283DD1FD -:10412000FDF74FFB002839D0FDF704FC002835D0FF -:1041300061690A468032508B01282FD90846A03089 -:10414000844646716038C7898389B81E834201DB83 -:10415000012002E0F81A401E80B2138CA789BB42EE -:1041600001D3012302E0FB1A5B1C9BB2984200D9E9 -:104170001846012801D163465D71C0310B78002BD0 -:1041800010D0528C49888A4201D3012102E0891A59 -:10419000491C89B2884205D9084603E061690120BB -:1041A000A0314D7161690A8E803110188883FFF744 -:1041B000DAFAFFF761FAFEF756FF002809D06069C6 -:1041C0000146FF3001300279002A02D14988C180BE -:1041D00006716069A0308571F8BD70B5F84C6069F2 -:1041E0002030407D00283ED0022810D1FDF7C2FAD1 -:1041F000002804D17120F349000102F014F962692A -:104200000023916ED06E491C58419166D06660695A -:10421000002520304575017D012904D10575A1795E -:1042200010221143A171C17C012915D1C574A07957 -:1042300008210843A071FDF76AFB002804D1E5209E -:10424000E049C00002F0EFF860690023816EC26EA1 -:10425000491C5A41C266816660692030817D01290E -:1042600002D0012181753FE585753DE570B5D44CDF -:104270000026E169012508788207920F0420012AAF -:1042800015D0022A13D0032A03D0217A01432172C8 -:104290002AE560780028FBD1606920308574A17917 -:1042A0002943A17122E0C6751EE5C5751CE5497854 -:1042B000CA0624D06278002AEAD1C906C90E1B2991 -:1042C00018D8617901436171FDF75FFB002804D1C3 -:1042D0003B20BC49400102F0A6F860690023016F51 -:1042E000426F491C5A41426701672030C17D012954 -:1042F000DBD1D8E7207A102108432072F4E460690A -:10430000F3E77CB504460020C0436946888001A8D5 -:10431000FCF7B2FD00287AD169468888FCF790FD49 -:10432000002803D0A749A84802F07DF8009801466C -:10433000E030827C0025002A08D0657010212170B1 -:10434000C17CA170017DE170857472E082799C4E20 -:10435000002A13D065700720207008E07169E620FC -:104360008D8445540A22A01CE83101F0DEFE00983D -:10437000E03080790028F1D1A5705AE0827D002AD2 -:1043800038D0827D130002F03FF90D2F2F2F2F2FF1 -:104390002F2F2F112F2F24082F0065700C21217033 -:1043A000017EA17071694988A18010E065700820C4 -:1043B00020707069082240886080201DFA3101F069 -:1043C000B4FEFF2100980331095AA181E0308575C0 -:1043D0002FE065700B212170017EA1707169498801 -:1043E000A180017FA171F2E7774876495D3002F044 -:1043F0001AF81EE0C81DF9300279002A08D01122EF -:1044000065702270811C89886180057111E012E05D -:10441000027A002A0FD012226570FF312270033118 -:1044200004E005720A8962804A89A280027A002A21 -:10443000F7D101207CBD00207CBD614800780128B7 -:1044400001D00C2070470020704770B55C4C0546C9 -:104450002078002804D05C485A49933001F0E3FFEB -:1044600000202561A07201202070FFF7E6FF0028E0 -:1044700004D0554853499E3001F0D5FF34E4F8B5D7 -:104480004F4F3978012901D00C20F8BD0126A62113 -:1044900078610E548030807CFDF752F900282FD0CF -:1044A00078698030807CFDF753FA002828D078693D -:1044B0008030807CFDF7E5F9002821D078698030D4 -:1044C000807CFDF70AFA00281AD0FAF7E6FF78692F -:1044D00000258030408B002827D039481830FDF760 -:1044E000DAF9002821D07869C421095C00291CD0A0 -:1044F0002030C17E0120FFF76BF9002802D014E0C4 -:104500001220F8BD78692030C17E0420FFF760F9E1 -:1045100000280AD1786950210D526030457102207F -:10452000FFF773F97869A03045717869E621095C75 -:10453000002903D1818CC288914200D8C188B981F9 -:1045400001468031CA8B521E93B20A8CD21892B2A5 -:104550000A8494460246A0321479002C02D04D847D -:10456000157102E04C8CE4184C8404464034A78951 -:10457000FF18A7814C8B012C01D8641C4C83002BA5 -:1045800000D015732030C07E0D4C04281ED0507909 -:1045900000281DD0A1898C451AD2FDF712F90028F8 -:1045A00016D060690146C0310A78002A10D08030E8 -:1045B000408C498888420BD3A570E6700AE0000061 -:1045C000C4000020FC3C010081080000A67001E04E -:1045D000A570E5706069A5210D543B21095C062991 -:1045E00001D0072918D1CA21028E095A511A09B2DD -:1045F000002911DB01460522CC310A3001F095FD7E -:10460000012202216069FCF7EEFE6069C9210D54A8 -:104610003B210D546030867160699E210A5A811CCD -:104620003030FCF71EFFA07800283DD16069C02122 -:10463000095C002901D0803045840120FAF7A4FDEF -:1046400060691330FAF713FF60690F30FAF753FE11 -:104650000120FAF71FFF61694020405C002803D168 -:104660003F20405C00280DD00A467831C8C9F9487F -:104670007832D26842632830C8C008220D30091D44 -:1046800001F053FDFAF701FF01210846FAF758FE41 -:1046900060698030806AFAF716FFFEF7A5FF60694F -:1046A0004030007AFAF730FE6571E571A571257228 -:1046B0006572257102202070FAF7FCFE0020F8BD1B -:1046C00010B5E54C2078022801D00C2010BDA07850 -:1046D000002803D00020FFF786FC17E0FAF7DDFE84 -:1046E00000F033F9606920308079012801D1FAF7B0 -:1046F00076FFA07A002809D0012807D0022807D029 -:10470000032805D0D549D64801F08DFE002010BD04 -:10471000EEF77EFCFAE7D0498872704710B5CE4CB0 -:104720002078032804D0CE48CC49293001F07BFE04 -:10473000606901212030827C002A06D00022827428 -:104740000175A27904231A43A271A2691378DB438D -:104750009B0707D1C37C002B04D1C174A07902212F -:104760000843A0711078C00606D4E0690078C0063E -:1047700002D4E07900280CD06078002809D1A07913 -:10478000002806D1FEF75DFC002802D0207A002820 -:1047900003D00120FFF727FC03E0FEF725FF00F020 -:1047A000D4F8207801280DD0A07A00280AD001285A -:1047B00008D0022807D0032805D0A948A7496830A7 -:1047C00001F031FE10BD0120FBF719F810BD10B546 -:1047D000A14C606920308079012812D1FAF7F6FEE9 -:1047E0006169881C3031FCF7C5FE002809D060697A -:1047F000C21D4388F93253812030007E107301209E -:10480000107210BD70B5944C05462078042804D071 -:1048100093489249803001F006FE617910200143EF -:104820006171002D50D0FBF7A8F96178012508438C -:10483000002811D160694021095C00290CD0E16990 -:104840004A78D20608D0097820300907C07DC90F00 -:10485000814201D165724EE0E078002809D0E0691C -:104860004178C90605D10078C00602D4FFF7AFFF32 -:1048700041E0FFF7ACFFE06900784007C10F6069D5 -:104880002030807D814205D0FFF7A7FC60790821A8 -:1048900008436071E06900780007C10F606920304B -:1048A000C07D814201D1FFF7E1FC6079284360714E -:1048B0000020E071A079000704D560692030C07E37 -:1048C000032818D0207A14E0022001436171E079B6 -:1048D000401CC0B2E07101280DD8606940300078FA -:1048E00000280CD05B484078C106C90E052906D2C5 -:1048F000C006002803D00120FFF775FB01E0FEF79A -:10490000BDFD207801280DD0A07A00280AD001280A -:1049100009D0022806D0032805D051484F49E2307B -:1049200001F081FD9FE40120FAF769FF9BE410B5D7 -:1049300049480078042804D049484849EA3001F041 -:1049400072FD0120FFF74FFB10BD10B501210020C3 -:10495000FAF7DBFE40490420087010BD3E494A22A8 -:104960004969505404202031C876704710B53A4C3C -:10497000C8206169405C00281CD0062806D0203180 -:10498000C97E0020FEF724FF002813D0606901468D -:10499000C0310A7A130001F037FE070D0D0D0D0D21 -:1049A0000D050D004030807FC20704D0C043800752 -:1049B00000D1087210BD0C20FEF727FF60690122AC -:1049C0004030817F1143817710BD10B5002A0AD095 -:1049D000002306E0D41A6418203CE47FC4545B1C16 -:1049E000DBB29342F6D310BD7CB51B4C606920301E -:1049F000C17E0020FEF7ECFE0125002802D1207ABE -:104A000028432072207A00281AD16946E069FCF711 -:104A100022FC684600780022C107C90F6846017071 -:104A20006069002902D06030057101E060300271D8 -:104A30006069014640304282857509202031C87680 -:104A40007CBD401A074900B2884201DC00280BDC1B -:104A50000120704790140020C4000020FC3C01009D -:104A6000F4090000FE7F00000020F2E710B5534C6F -:104A700060692030C17E0020FEF7AAFE0028207A5F -:104A800010D000280DD1E069FCF797FB6169CA22BC -:104A90005052098EFFF7D5FF002807D02820FFF7D6 -:104AA0005DFF10BD01210843207210BD6169E069FE -:104AB000CC31FCF77AFB606906212030C17610BD4D -:104AC00010B500F04EF83D4C607940070BD5606999 -:104AD0002030C17E0520FEF77BFE002803D0207A1F -:104AE000082108432072FFF701FA00F018F8FFF7D9 -:104AF00073F8A079C0060FD5207A00280CD1606920 -:104B00002030C17E0B0001F07FFD07070707070774 -:104B1000070507000721C176FEF7F3FF10BD10B5AA -:104B200026488179490715D5017A002912D14069B3 -:104B30003B21095C891E0B0001F066FD07050C0C8A -:104B40000C0D0C0F0C00002256210A54C030807945 -:104B5000FFF704FF10BD012100E00221C0304172C7 -:104B600010BD10B515488179090720D5017A0029B3 -:104B70001DD1406902462032D47EA41E230001F0DC -:104B800043FD13160B1616161616161616161616BF -:104B90001616161616171600562211546030407954 -:104BA000002801D0062000E01620FFF7D7FE10BD38 -:104BB0004030C1768175D17610BD0000C400002060 -:104BC00030B50346002002460DE09C5C2546303D92 -:104BD0000A2D02D30020C04330BD0A256843303877 -:104BE0002018521CD2B28A42EFD330BD70B50D46A8 -:104BF000144608E00A2101F012FB2A193031203A4C -:104C0000641ED177E4B2002CF4D170BD10B500233E -:104C100010E0040A00020443A0B2CC5C4440200629 -:104C2000000F60400407240C44402006C00C604084 -:104C30005B1C9BB29342ECD310BD000010B572B662 -:104C400000F0DCF800280BD0ECF72AFBF8F7EFFDBA -:104C500000F0A5FD6E490020C86288626D490860B9 -:104C600062B6002010BDF3B5002501200007C06A20 -:104C700081B0C0430006000E04D167480068401CA4 -:104C800000D1012572B600F0B9F8002802D062B652 -:104C90000820FEBDECF75AFAECF706FB5F4B604EBE -:104CA00000211A68CA40D2071FD00246CA40D20764 -:104CB00018D14AB2002A07DA1407240F083CA408C6 -:104CC000A400A419E46904E09408564FA400E41970 -:104CD00024689207D20ED4402206920F012A04D0F3 -:104CE000032A02D062B65048FEBD491C2029D8D301 -:104CF0000198030001F088FC14212323232323239C -:104D000023230B0D0F11131F1517191B1D2E002424 -:104D100016E0012414E0022412E0032410E004242D -:104D20000EE008240CE009240AE00A2408E00B2421 -:104D300006E00C2404E0052402E0072400E0062439 -:104D4000F06901210002000AC9070843F061002D43 -:104D500004D009E062B601200003FEBD2C4D3348AB -:104D6000E862ECF7A1FAA8622A49314808603149A3 -:104D700002980860ECF798FA214600F0F7FCF8F783 -:104D80001AFD00F0FDFE00F073FD0198ECF756FAF5 -:104D9000040062B603D0FFF751FF2046FEBD00209D -:104DA000FEBD10B5044600F029F8002800D001200F -:104DB0002070002010BD204908600020704710B509 -:104DC0000C46102808D011280BD012280CD013281C -:104DD0000ED00120086010BD03CC083CFFF743FF54 -:104DE0000AE0FFF72BFF07E02068FFF7DAFF03E098 -:104DF0001149206808600020206010BD05480C495A -:104E00000068884201D101207047002070470000EF -:104E100000050040780000200010001000E100E0D4 -:104E200000ED00E000E400E00110000000190000C7 -:104E3000BEBAFECAE40000200400002010B52038ED -:104E40000C46030001F0E0FB33A6AAAEB2B8BCC02A -:104E5000C5E0DBE41B1F23272C31373C41474D5075 -:104E600054585C606D71656974787C8084888C901E -:104E700094989C9FA2CACFE9F0F3D3D7F80020689A -:104E800000F0DDF8D6E0206800F0E1F8D2E020681C -:104E900000F0F5F8CEE0207840B200F0D7FAC9E093 -:104EA000207840B200F0F5FAC4E02078616840B2A2 -:104EB00000F008FBBEE0207840B200F018FBB9E03B -:104EC000207840B200F023FBB4E02078217940B292 -:104ED00000F02EFBAEE02078616840B200F058FB95 -:104EE000A8E000F064FBA5E0206800F068FBA1E00A -:104EF000207800F07DFB9DE02068F8F72CF899E021 -:104F00002068F8F72CF895E021792068F8F72EF85A -:104F100090E0206800F0E6F98CE0206800F0E7F906 -:104F200088E0207800F0E7F984E000F0F1F981E012 -:104F3000207800F0F3F97DE0207800F005FA79E0C0 -:104F4000206800F01EFA75E0206800F020FA71E099 -:104F5000206800F022FA6DE0206800F023FA69E092 -:104F6000206800F025FA65E0206800F027FA61E08B -:104F7000206800F028FA5DE00846ECF7FFF859E0F9 -:104F8000EDF719FA56E0EDF746FA53E02068EDF731 -:104F90004EFA4FE0206800F0E1F84BE0206800F0A6 -:104FA000E9F847E0206800F0F0F843E02078A268D4 -:104FB000616800F0F5F83DE0207800F006F939E08E -:104FC000207800F017F935E02078616800F027F9C3 -:104FD00030E02078616800F03AF92BE02179207800 -:104FE00000F016FC26E0206800F06BF822E0206854 -:104FF000F8F70CFB1EE02068F8F7F0FA1AE007CC8F -:105000000C3C00F0FFFC15E0206800F052FD11E0C0 -:1050100003CC083C00F07DFD0CE0206800F06EFF42 -:1050200008E009E003E0FFE700F080FF02E020680D -:1050300000F0B8FF206010BD0120086010BD002105 -:105040000170084670470146002008707047EFF372 -:105050001081C907C90F72B60278012A01D0012256 -:1050600000E0002201230370002900D162B6002A6B -:1050700001D000207047012040037047E7E7EFF3BD -:105080001081C907C90F72B600220270002900D131 -:1050900062B600207047F2E710B52848FFF7CFFF4F -:1050A000002803D026A11D2001F0BDF92348401C93 -:1050B000FFF7C5FF002803D021A1212001F0B3F99B -:1050C00010BDF1B5224D6F6801261C48FFF7BFFFE8 -:1050D0001A4C002803D10026601CFFF7D0FF1D4AA0 -:1050E0001D490120506000BF00BF00BF00BF00BFCE -:1050F00000230B604B60009B6B60106000BF00BF23 -:1051000000BF00BF00BF0868002802D1486800281F -:10511000F9D048680028E4D1002E04D06F60601CEC -:10512000FFF795FF07E0601CFFF791FF0028D3D140 -:105130000248FFF7A4FF0020F8BDC2E7E800002006 -:105140007372635C736F635F6563622E630000005C -:1051500000E5004000E0004000E100405A495B4BA0 -:105160000A685B499A42096801D18904890C016087 -:10517000002070475449554B0A6855499A4201D15D -:105180008004800C4860002070474F494F4B0A68EC -:105190004F499A4201D18004800C886000207047FA -:1051A00030B5494B494D1C684A4BAC4202D01028DF -:1051B00002D203E00E2801D3184630BDC300444894 -:1051C000181801614261002030BD3F493F4B0A6819 -:1051D0004049491C9A4202D0042802D203E0022826 -:1051E00001D3084670473C4A0121C0008018016085 -:1051F000002070473449354B0A683649491C9A42A9 -:1052000002D0042802D203E0022801D308467047E6 -:10521000314A0121C000801841600020704770B5FC -:10522000294A2C4B14682D4E284D82005B1C921984 -:10523000AC4203D0042803D2116006E0022801D357 -:10524000184670BD8804800C1060002070BD70B5D9 -:105250001D4A204B1468214E1C4D82005B1C921984 -:10526000AC4203D0042803D2106806E0022801D320 -:10527000184670BD10688004800C0860002070BD66 -:1052800010B5134A164890600E200021C3009B18E9 -:1052900019615961401C1028F8D300200F4A05E01D -:1052A000022803D383009B18196005E083009B1834 -:1052B0001C68A404A40C1C60401C0428F0D310BD7E -:1052C000034907488860704778000020BEBAFECACC -:1052D00000F501400820000000F0014000F8014006 -:1052E00000C0FFFF47490968016000207047454939 -:1052F0000860002070470121434A002803D001289C -:1053000003D042487047916300E0D16300207047AA -:105310003F49012008603D48801C704704223D4BF6 -:105320003B49002805D05A600869012210430861F2 -:1053300008E008694008400008619A60324900208E -:10534000C03188600020704731490622002808D00B -:10535000012809D002280DD003280FD02B48401C6B -:1053600070470869904302E008699043801C086117 -:105370000020704708699043001DF8E70869104352 -:10538000F5E723494A6A02434A62002070472049F0 -:105390004A6A82434A62002070471D49496A016097 -:1053A000002070471A49CA690243CA610020704749 -:1053B0001749CA698243CA61002070471449C96904 -:1053C0000160002070471249024600204031002A47 -:1053D00003D0012A01D0072070478A6370470D4926 -:1053E0000420886008490020C03188600A480168AC -:1053F0008022090A0902114301600849012008605E -:1054000070470000000400404000004004200000FD -:10541000000500400003004000E400E000E100E07F -:105420008107C90E002808DA0007000F0838800835 -:10543000814A80008018C06904E080087F4A8000AB -:1054400080180068C8400006800F704710B50446F9 -:1054500000F0DBF8002813D02046FFF7E1FFC0B2D0 -:1054600000F0E1F800280DD07549E2060B78D20E65 -:1054700001209040002B08D04A681043486006E0A5 -:10548000704810BD6F48401C10BD6F490860002077 -:1054900010BD10B5044600F0B8F800280BD06849DC -:1054A000E2060B78D20E01209040002B05D04A680E -:1054B00082434A6004E0634810BD6349803108605C -:1054C000002010BD70B50D46044600F09EF800287F -:1054D0000BD05E480068E206D20E012191400840E0 -:1054E00000D001202860002070BD564870BD10B566 -:1054F000044600F08AF8002807D0E106C90E012012 -:10550000884052490860002010BD4E4810BD10B5BB -:10551000044600F07AF8002808D0E106C90E012000 -:1055200088404A4980310860002010BD454810BDC0 -:1055300070B50D46044600F068F8002819D02846DA -:1055400000F071F8002816D0A007C10EFF228A4093 -:10555000A807000E8840002C10DA2107090F08392F -:105560008B0835499B005B18D96991430143D96188 -:105570000CE0344870BD3348401C70BDA3082F496F -:105580009B005B181968914301431960002070BDAE -:1055900070B50C46054600F038F8002805D02846BE -:1055A000FFF73EFF2070002070BD264870BDBFF39E -:1055B0004F8F21492648C860BFF34F8FFEE770B573 -:1055C0001F4C05462178012000290ED1207072B6AB -:1055D00000F0F4F81C4E803631688143616000F0C1 -:1055E000EDF8C043306062B600202870002070BD26 -:1055F00013490A78002A06D0002804D1124A4868C4 -:105600001060002008700020704710B50446202864 -:1056100007DA00F0D3F80121A140084201D10120AE -:1056200010BD002010BD012803D0032801D00020A8 -:10563000704701207047000000ED00E000E400E04A -:10564000EC0000200120000000E100E000E200E0AA -:105650000400FA05F8B50446800700250126002855 -:1056600004DA5848C563C66302208443E00404D5C5 -:105670005548C563C66380148443600003D553480E -:10568000456080058443E00504D55148C563C66381 -:1056900080158443A00404D54E48C563C6634014F6 -:1056A000844360042704C00FF90F884203D04AA145 -:1056B000612000F0B8FEB80F0AD04C49CD634C48C9 -:1056C000C563C563CE63C663C6630320800384439A -:1056D00020050AD5474FFD632F20EBF765FDFE63DC -:1056E0002F20EBF761FDF8148443FFF7C9FD424812 -:1056F000044203D038A18D2000F095FEF8BDF0B52E -:1057000000210A46FF230446CC40E4072AD04CB2CD -:10571000E606F60E0125B540384E3560384E356048 -:10572000002C11DA25072D0F083DAE08354DB600C7 -:105730007719FD69A407E60E1C46B440A54314463C -:10574000B4402543FD610DE0A6082F4DB600761943 -:105750003568A407E70E1C46BC40A5431446BC4070 -:1057600025433560491C2029CDD3F0BD70B5274CA9 -:105770000D462060FFF76EFF2068FFF7C0FF284648 -:10578000ECF7EAFEFFF788FCF7F778FBFFF778FD08 -:10579000FFF725FEECF766FD00F06AF870BD10B566 -:1057A0001A4C2068FFF756FF2068FFF7A8FFFFF7A5 -:1057B00067FDECF74BFF0020206010BD1348006828 -:1057C00070470000C01F0040C0CF004000E501400E -:1057D000C08F0040C0DF00407372635C736F635F13 -:1057E000636F6E6669672E6300000000C0EF0040C3 -:1057F000C0FF0040C0BF0040FEFF0FFC80E100E0A2 -:1058000080E200E000ED00E000E400E0F4000020B1 -:1058100070B5002402460D4620462146002A1ED0BF -:10582000012A04D0022A04D0032A1ED103E0012059 -:1058300002E0022013E003202B0000F0E5FE071633 -:105840000507090B0D0F1600012108E0022106E0F3 -:10585000032104E0042102E0052100E00621F8F71D -:1058600058F8002801D0204670BD0724FBE700004F -:10587000B348002101708170704770B5B14D0123AC -:105880006B60B14B1C68002CFCD0002407E00E6854 -:1058900006601E68002EFCD0001D091D641C944289 -:1058A000F5D30020686018680028FCD070BD70B582 -:1058B000A34C0E466178884203D0A4A16F2000F06B -:1058C000B2FD0325330000F09FFE09520624245246 -:1058D0005252524952002078022803D09BA17320D3 -:1058E00000F0A1FD2570A078022802D0012804D084 -:1058F00008E0A06800F0D2FB04E02046083007C8AA -:10590000FFF7BBFF0020A070F7F7A4FF0420207072 -:1059100070BDF8F754F801466068F9F776FA064664 -:105920002078022803D089A1872000F07CFD8B4AD3 -:105930008B498C48964205D86269032A02D2521CD0 -:10594000626102E0864207D84D71801BC8608449BD -:105950006078F8F7B4FC70BD032003E0A07800285D -:10596000FAD10220F7F77EFE00F0E1F870BD77A1D2 -:10597000B12000F058FD70BD70B50546F8F71FF86E -:105980006F4C60602078012803D070A1B82000F02F -:105990004AFD73490220087000220A718D600422BA -:1059A0004A71704ACA6020706078F8F788FC70BD50 -:1059B00010B5634CA078002802D12078002801D0CF -:1059C000112010BD6848F7F78BFF607060780028E1 -:1059D00004D0012020700020606110BD032010BDA4 -:1059E00010B50124020B64040121604BA04202D2D5 -:1059F0009140186802E0203A58689140084000D071 -:105A0000012010BDF8B50E46910005464F19144609 -:105A10003F1F009100F053FB009980028919091F74 -:105A2000B14201D2012200E00022002C03D0FF216C -:105A300001318C4201D90920F8BD4D498D4219D35D -:105A4000AF4217D3854205D2874203D2284630435E -:105A5000800701D01020F8BD8E420BD3002A09D157 -:105A60002846FFF7BDFF002804D13846FFF7B8FFEE -:105A7000002801D00F20F8BD3E483F490068884209 -:105A800005D0224631462846FFF7F7FE0FE0FFF724 -:105A90008FFF0028EFD12A480121C660856004618C -:105AA00081702046302148431830FFF765FF002001 -:105AB000F8BD10B504462E48800A84420BD300F08E -:105AC000FEFAA04201D8102010BDA0020446FFF744 -:105AD00087FF002801D00F2010BD26482649006806 -:105AE000884203D0204600F0D9FA0AE0FFF760FFB1 -:105AF0000028F1D112480221846081701F48FFF70D -:105B00003BFF002010BD1A48010B01208840401EB9 -:105B1000704700B50B460246FFF7F5FF104201D073 -:105B20000F2000BD114802604360002000BD10B589 -:105B3000034C6078F7F728FF00202070A07010BD9C -:105B4000F800002000E5014000E401407372635C4E -:105B5000736F635F666C6173682E6300307500005D -:105B6000E0140020D0FB0100AF5801000006004007 -:105B70000080010078000020BEBAFECA3A5600003C -:105B8000F74805218170002101704170C17081606A -:105B9000704710B5F3490A78022A07D0CA6810186E -:105BA000C860C8689638F9F7E9F810BD8A68101817 -:105BB00088608868F6E70378EB49EC4A002B02D04E -:105BC000012B10D014E00379002B01D0012B0FD151 -:105BD0004379002B01D0012B0AD18368643B8B42AF -:105BE00006D2C06810E00379002B03D0012B01D04E -:105BF000002070474379002B01D0012BF8D1C368F6 -:105C0000643B8B42F4D280689042F1D80120704707 -:105C1000F8B504460226F8F740FD0068002803D0D6 -:105C2000D3A1BD2000F0FFFB0127CD4D002C08D0F3 -:105C30002078002817D0012805D0022811D0032889 -:105C400013D02F710DE06068C82808D3F9F70BF95D -:105C5000002804D06068FFF79CFF012603E00026BF -:105C600001E000F0F9F93046F8BD28780028F8D1B5 -:105C70006068FFF7A0FF0028E3D060680078002884 -:105C800026D0A878042803D0B9A1F72000F0CBFBD8 -:105C9000B44F0020387060680079012800D00020DF -:105CA000387160684079002837D0042078716068C6 -:105CB0008168E868F8F71DF9B8606068C0689630D8 -:105CC000F8600320A870A749E878F8F7F8FAC8E761 -:105CD000A4480221017061680979012919D00021C5 -:105CE000017161684979002915D004214171616809 -:105CF0008968963181606168C968C160C068984CE4 -:105D000014346060F7F75BFE20606F700220A870AB -:105D1000A7E70321E4E70321E8E70320C6E7F8B596 -:105D20008F4C0D46E178884204D0FF2090A11930B5 -:105D300000F079FB28468A4F00250126143703001E -:105D400000F062FC090612375A7C8D97C4A0C4008B -:105D5000A078032807D0A078022804D0FF2084A1CF -:105D60001D3000F060FBF8BDA078032807D0A078B4 -:105D7000022804D0FF207EA1213000F054FB042033 -:105D8000A07025712078002810D1FFF702FFE0787D -:105D9000F8F7D6F8E0607D49886A7D4A02402261C2 -:105DA0007B4AD24310408862002050E000F054F952 -:105DB000F8BDA078032807D0A078022804D0FF20DF -:105DC0006BA1423000F02FFB2078002802D000F0B9 -:105DD0004FF9F8BDA07803281FD104202AE0091A42 -:105DE0006048C1600146E078F8F769FAF8BD042020 -:105DF000F7F738FCA570F8BDA078032807D0A07885 -:105E0000022804D0FF205AA1633000F00CFB207858 -:105E10000028DCD1A07803280BD0F7F7D0FD01468D -:105E20003868F8F7F2FF0028E1DB79688142DEDBB1 -:105E3000D5E70520F7F716FCA670F8BDA078042872 -:105E400004D0FF204AA1843000F0EDFA0220A168BE -:105E50008847FFF7DDFEFF260546BD3642E0A07805 -:105E6000042804D0FF2042A1893000F0DCFA012090 -:105E7000EDE7A078042899D0FF203DA18E3000F0F6 -:105E8000D2FA93E7A07804280AD06078002802D0DC -:105E9000A078022804D0FF2035A1933000F0C3FA87 -:105EA0002078002893D12079002804D00620F7F725 -:105EB000D9FB2571C0E76078002805D02949E07832 -:105EC000F8F7FDF96570F8BD0720B3E7FF2028A1BA -:105ED000AE3046E7002D0AD0012D06D024A1304671 -:105EE00000F0A1FA022DF5D1F8BD042000E0032056 -:105EF000A1688847FFF78CFE0546F3E770B50500FB -:105F000005D0174CA078052803D0112070BD1020B3 -:105F100070BD2048F7F7E4FCE070E078002803D07B -:105F2000A5600020A07070BD032070BD10B50C48A6 -:105F30000178002901D0112010BD817805292BD0CE -:105F4000817801292AD08178002927D00121017088 -:105F50008178012922D0807800281FD020E000001D -:105F600010010020F01400203D860100FF1FA10752 -:105F70007372635C736F635F726164696F5F74698E -:105F80006D65736C6F742E630000000000050040A7 -:105F9000028100001F5D01000F2010BD00F068F8B5 -:105FA000002010BDF8B5394E0446B078002801D065 -:105FB00001280DD1002C0DD02046FFF7FCFD002854 -:105FC0000AD02078324D002808D0B078012823D09C -:105FD0000F20F8BD1020F8BD0720F8BD02272F7054 -:105FE0002079012814D0002028716079002811D070 -:105FF00004206871A0689630A860E068E860E868EE -:10600000224C14346060F7F7DAFC2060B77019E0B6 -:106010000320E9E70320ECE700202870207901281D -:1060200016D0002028716079002813D004206871F0 -:10603000A168F068F7F75DFFA860E0689630E86057 -:106040000320B0701249F078F8F739F90020F8BD54 -:106050000320E7E70320EAE710B50E48816A0E4AFD -:1060600011400A4A126911438162F7F7F3FB10BD30 -:1060700010B5064CE078F7F787FC0820F7F7F2FA3E -:106080000520A07000202070607010BD100100205D -:10609000F014002000050040FD7EFFFF0A4A0221A7 -:1060A00051600A490B68002BFCD0906008680028FA -:1060B000FCD00020506008680028FCD07047012008 -:1060C000000740697047000000E5014000E401401E -:1060D000034610B50B439B070FD1042A0DD308C804 -:1060E00010C9121FA342F8D018BA21BA884201D9A8 -:1060F000012010BD0020C04310BD002A03D0D307EB -:1061000003D0521C07E0002010BD03780C78401C1F -:10611000491C1B1B07D103780C78401C491C1B1B16 -:1061200001D1921EF1D1184610BDF8B5042A2CD326 -:10613000830712D00B78491C0370401C521E830742 -:106140000BD00B78491C0370401C521E830704D0EF -:106150000B78491C0370401C521E8B079B0F05D007 -:10616000C91ADF002023DE1B08C90AE0EBF72CF870 -:10617000F8BD1D4608C9FD401C46B4402C4310C064 -:10618000121F042AF5D2F308C91A521EF0D40B7854 -:10619000491C0370401C521EEAD40B78491C037042 -:1061A000401C012AE4D409780170F8BD01E004C064 -:1061B000091F0429FBD28B0701D50280801CC90767 -:1061C00000D00270704700290BD0C30702D00270C4 -:1061D000401C491E022904D3830702D50280801C7B -:1061E000891EE3E70022EEE70022DFE70378C278AA -:1061F0001946437812061B0219438378C0781B04A2 -:10620000194311430902090A000608437047020AAC -:1062100008704A70020C8A70020ECA707047002221 -:1062200003098B4273D3030A8B4258D3030B8B426F -:106230003CD3030C8B4221D312E003460B437FD4A3 -:10624000002243088B4274D303098B425FD3030AB5 -:106250008B4244D3030B8B4228D3030C8B420DD3C8 -:10626000FF22090212BA030C8B4202D31212090256 -:1062700065D0030B8B4219D300E0090AC30B8B4294 -:1062800001D3CB03C01A5241830B8B4201D38B0342 -:10629000C01A5241430B8B4201D34B03C01A5241E7 -:1062A000030B8B4201D30B03C01A5241C30A8B422A -:1062B00001D3CB02C01A5241830A8B4201D38B0215 -:1062C000C01A5241430A8B4201D34B02C01A5241B9 -:1062D000030A8B4201D30B02C01A5241CDD2C3092B -:1062E0008B4201D3CB01C01A524183098B4201D3A7 -:1062F0008B01C01A524143098B4201D34B01C01A92 -:10630000524103098B4201D30B01C01A5241C30809 -:106310008B4201D3CB00C01A524183088B4201D378 -:106320008B00C01A524143088B4201D34B00C01A64 -:106330005241411A00D201465241104670475DE079 -:10634000CA0F00D04942031000D3404253400022FC -:106350009C4603098B422DD3030A8B4212D3FC22A5 -:10636000890112BA030A8B420CD3890192118B4224 -:1063700008D3890192118B4204D389013AD092113A -:1063800000E08909C3098B4201D3CB01C01A5241F5 -:1063900083098B4201D38B01C01A524143098B42BE -:1063A00001D34B01C01A524103098B4201D30B01A7 -:1063B000C01A5241C3088B4201D3CB00C01A5241CC -:1063C00083088B4201D38B00C01A5241D9D24308B3 -:1063D0008B4201D34B00C01A5241411A00D20146F0 -:1063E000634652415B10104601D34042002B00D55A -:1063F0004942704763465B1000D3404201B500201C -:10640000C046C04602BD70477047704710B500F0E7 -:106410003BF810BD012308CB134B1860134B1960D8 -:10642000134B1A607047134A134B13607246053AB8 -:10643000F0E7114A0F4B1B689A420ED10D4B00201A -:10644000186001980D4B04B598470CBC9E46024657 -:10645000029800990A4B1B68184706980599094B42 -:106460001B68DB6818470000340100203801002059 -:106470003C0100202C010020EFBEADDEC9CD0000A4 -:10648000E4000020040000201D481E497047FFF76B -:10649000FBFFEAF753FE00BD01200007C06AC0B24F -:1064A000FF2804D1184819490968884202D01848C1 -:1064B00018490160184819490968884203D1184AE7 -:1064C00013605B68184700BD20BFFDE71248134901 -:1064D000096888420ED1134B18680B498842F3D0E3 -:1064E00080F308881049884204DD104802680221C0 -:1064F0000A4302600E4880470E4880470E48004716 -:106500000015002000150020FFFFFFFF0010001005 -:106510002C050040080000000010000000000020D2 -:10652000040000200080010000200020240500401D -:10653000DFCD000099640100156401001348704527 -:1065400002D1EFF3098101E0EFF308818869023895 -:106550000078102814DB202810DB2B280BDB0C4ADA -:1065600012680C4B9A4203D1602804DB0A4A104798 -:10657000022008607047094A10470000084A104787 -:10658000084A12682C32126810470000FDFFFFFF16 -:1065900078000020BEBAFECAAD1200003D4E0100D8 -:1065A000BF4D0100040000200D4B0E4908470E4B63 -:1065B0000C4908470D4B0B4908470D4B0949084743 -:1065C0000C4B084908470C4B064908470B4B05493B -:1065D00008470B4B034908470A4B0249084700008C -:1065E00079250000192200009D2B00003F2A0000A1 -:1065F000ED2900009F270000B912000013140000CD -:10660000012B00000F23000030B47446641E25786F -:10661000641CAB4200D21D46635D5B00E31830BCD6 -:10662000184703B5684600784006400E401C884273 -:1066300005D269460878401CC0B208700CBD684697 -:106640000078000601D500200CBD80200CBD414023 -:10665000802901D0002070470120704737B50878A5 -:106660000C4669460978884206D020781146FFF723 -:10667000D8FF207001203EBD00203EBD37B5044646 -:106680000078154669460979FFF7E1FF002801D037 -:1066900000203EBD20782946FFF7C3FF207001206F -:1066A0003EBD0FB568460179007881420AD0684640 -:1066B000007922214006400E4843801818600120CE -:1066C00004B000BD0020FBE77FB5684601791C4699 -:1066D00015460078FFF7BBFF002802D0002004B069 -:1066E00070BD6846007822214006400E484340199C -:1066F00020600120F3E70000FFFFFFFF0000FFFF25 -:106700000100030000000100000000000000000084 -:1067100000000000000000008700000000000000F2 -:10672000000000000000000000000001020304005F -:106730000D0E0F100000000033690000516B0000C7 -:10674000196C0000736C0000C76C00002F6D000016 -:106750008D690000456A0000D16D0000DF790000FE -:10676000100110013A0200001A02000004013C006E -:10677000230044000E0001020408102040805555FB -:1067800055D6BE898E0000007006120DB4130000AD -:1067900014035A06A00900006004F208840DF401F5 -:1067A000FA00960064004B0032001E001400000046 -:1067B000E067010008000020100000000411000044 -:1067C000F0670100180000202801000004110000FB -:1067D0001869010040010020C013000020110000D2 -:1067E0000249022208681042FCD0704700E200E033 -:1067F0000000000000000000000000000000000099 -:106800000000000000000000000000000000000088 -:106810000000000000000000000000000000000078 -:10682000000000000100010054000020FB349B5FC9 -:106830008000008000100000000000000000000048 -:106840000000000000000000000000000000000048 -:106850000000000001000000000000000000000037 -:106860000000000000000000000000000000000028 -:106870000000000000000000000000000000000018 -:106880000000000000000000000000000000000008 -:1068900000000000000000000000000000000000F8 -:1068A00000000000000000000000000000000000E8 -:1068B00000000000000000000000000000000000D8 -:1068C00000000000000000000000000000000000C8 -:1068D00000000000000000000000000000000000B8 -:1068E00000000000000000000000000000000000A8 -:1068F0000000000000000000000000000000000098 -:106900000000000000000000196401000000000009 -:0869100000000000000000007F -:00000001FF diff --git a/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51422_xxaa.ld b/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51422_xxaa.ld deleted file mode 100644 index 64e8506..0000000 --- a/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51422_xxaa.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x18000, LENGTH = 0x28000 - RAM (rwx) : ORIGIN = 0x20002000, LENGTH = 0x2000 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51422_xxac.ld b/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51422_xxac.ld deleted file mode 100644 index 1fcc989..0000000 --- a/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51422_xxac.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x18000, LENGTH = 0x28000 - RAM (rwx) : ORIGIN = 0x20002000, LENGTH = 0x6000 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51822_xxaa.ld b/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51822_xxaa.ld deleted file mode 100644 index 64e8506..0000000 --- a/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51822_xxaa.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x18000, LENGTH = 0x28000 - RAM (rwx) : ORIGIN = 0x20002000, LENGTH = 0x2000 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51822_xxab.ld b/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51822_xxab.ld deleted file mode 100644 index 1bad769..0000000 --- a/components/softdevice/s110/toolchain/armgcc/armgcc_s110_nrf51822_xxab.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x18000, LENGTH = 0x8000 - RAM (rwx) : ORIGIN = 0x20002000, LENGTH = 0x2000 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s110/toolchain/iar/iar_s110_nrf51822_xxab.icf b/components/softdevice/s110/toolchain/iar/iar_s110_nrf51822_xxab.icf deleted file mode 100644 index 1781997..0000000 --- a/components/softdevice/s110/toolchain/iar/iar_s110_nrf51822_xxab.icf +++ /dev/null @@ -1,31 +0,0 @@ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ -/*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x18000; -/*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x18000; -define symbol __ICFEDIT_region_ROM_end__ = 0x1ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002000; -define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; -/*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 0x800; -define symbol __ICFEDIT_size_heap__ = 0x200; -/**** End of ICF editor section. ###ICF###*/ - -define memory mem with size = 4G; -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; - -define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; -define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; - -initialize by copy { readwrite }; -do not initialize { section .noinit }; - -keep { section .intvec }; -place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; -place in ROM_region { readonly }; -place in RAM_region { readwrite, - block CSTACK, - block HEAP }; diff --git a/components/softdevice/s120/doc/s120_nrf51_2.1.0_licence_agreement.pdf b/components/softdevice/s120/doc/s120_nrf51_2.1.0_licence_agreement.pdf deleted file mode 100644 index 7aab95c8e7ae8c764467d3d81fa9069d2ff9c2ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5553 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%0DgVcy181#tXs%uHq2+y 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

Q)lJ&Lx>M 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 series. */ - uint16_t evt_len; /**< Length in octets excluding this header. */ -} ble_evt_hdr_t; - -/**@brief Common BLE Event type, wrapping the module specific event reports. */ -typedef struct -{ - ble_evt_hdr_t header; /**< Event header. */ - union - { - ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ - ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ - ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ - ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ - ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ - } evt; -} ble_evt_t; - - -/** - * @brief Version Information. - */ -typedef struct -{ - uint8_t version_number; /**< Link Layer Version number for BT 4.1 spec is 7 (https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer). */ - uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ - uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ -} ble_version_t; - -/**@brief Mutual exclusion of radio activity and CPU execution. - * - * This option configures the application's access to the CPU when the radio is active. The - * application can configure itself to be blocked from using the CPU while the radio is - * active. By default, the application will be able to share CPU time with the SoftDevice - * during radio activity. This parameter structure is used together with @ref sd_ble_opt_set - * to configure the @ref BLE_COMMON_OPT_RADIO_CPU_MUTEX option. - * - * @note Note that the application should use this option to configure the SoftDevice to block the - * CPU during radio activity (i.e enable mutual exclusion) when running the SoftDevice on - * hardware affected by PAN #44 "CCM may exceed real time requirements"and PAN #45 "AAR may - * exceed real time requirements". - * - * @note Note that when acting as a scanner, the mutex is only enabled for radio TX activity. - * - * @note @ref sd_ble_opt_get is not supported for this option. - * - */ -typedef struct -{ - uint8_t enable : 1; /**< Enable mutual exclusion of radio activity and the CPU execution. */ -} ble_common_opt_radio_cpu_mutex_t; - -/**@brief Option structure for common options. */ -typedef union -{ - ble_common_opt_radio_cpu_mutex_t radio_cpu_mutex; /**< Parameters for the option for the mutual exclusion of radio activity and CPU execution. */ -} ble_common_opt_t; - -/**@brief Common BLE Option type, wrapping the module specific options. */ -typedef union -{ - ble_common_opt_t common_opt; /**< Common option, opt_id in BLE_COMMON_OPT_* series. */ - ble_gap_opt_t gap_opt; /**< GAP option, opt_id in BLE_GAP_OPT_* series. */ -} ble_opt_t; - -/** - * @brief BLE GATTS init options - */ -typedef struct -{ - ble_gap_enable_params_t gap_enable_params; /**< GAP init options @ref ble_gap_enable_params_t */ - ble_gatts_enable_params_t gatts_enable_params; /**< GATTS init options @ref ble_gatts_enable_params_t. */ -} ble_enable_params_t; - -/** @} */ - -/** @addtogroup BLE_COMMON_FUNCTIONS Functions - * @{ */ - -/**@brief Enable the bluetooth stack - * - * @param[in] p_ble_enable_params Pointer to ble_enable_params_t - * - * @details This call initializes the bluetooth stack, no other BLE related call can be called before this one has been executed. - * - * @return @ref NRF_SUCCESS BLE stack has been initialized successfully - * @retval @ref NRF_ERROR_INVALID_STATE stack had already been initialized and cannot be reinitialized. - * @return @ref NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. - * @retval @ref NRF_ERROR_INVALID_PARAM Invalid parameter supplied. - */ -SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(ble_enable_params_t * p_ble_enable_params)); - -/**@brief Get an event from the pending events queue. - * - * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. This buffer must be 4-byte aligned in memory. - * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. - * - * @details This call allows the application to pull a BLE event from the BLE stack. The application is signalled that an event is - * available from the BLE Stack by the triggering of the SD_EVT_IRQn interrupt (mapped to IRQ 22). - * The application is free to choose whether to call this function from thread mode (main context) or directly from the Interrupt Service Routine - * that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher priority than the application, this function should be called - * in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the stack. - * Failure to do so could potentially leave events in the internal queue without the application being aware of this fact. - * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to be copied into - * application memory. If the buffer provided is not large enough to fit the entire contents of the event, @ref NRF_ERROR_DATA_SIZE will be returned - * and the application can then call again with a larger buffer size. - * Please note that because of the variable length nature of some events, sizeof(ble_evt_t) will not always be large enough to fit certain events, - * and so it is the application's responsibility to provide an amount of memory large enough so that the relevant event is copied in full. - * The application may "peek" the event length by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return. - * - * @note The pointer supplied must be aligned to the extend defined by @ref BLE_EVTS_PTR_ALIGNMENT - * - * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. - * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. - * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. - */ -SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); - - -/**@brief Get the total number of available application transmission buffers per link in the BLE stack. - * - * @details This call allows the application to obtain the total number of - * transmission buffers available per link for application data. Please note that - * this does not give the number of free buffers, but rather the total amount of them. - * The application has two options to handle its own application transmission buffers: - * - Use a simple arithmetic calculation: at boot time the application should use this function - * to find out the total amount of buffers available to it and store it in a variable. - * Every time a packet that consumes an application buffer is sent using any of the - * exposed functions in this BLE API, the application should decrement that variable. - * Conversely, whenever a @ref BLE_EVT_TX_COMPLETE event is received by the application - * it should retrieve the count field in such event and add that number to the same - * variable storing the number of available packets. - * This mechanism allows the application to be aware at any time of the number of - * application packets available in the BLE stack's internal buffers, and therefore - * it can know with certainty whether it is possible to send more data or it has to - * wait for a @ref BLE_EVT_TX_COMPLETE event before it proceeds. - * - Choose to simply not keep track of available buffers at all, and instead handle the - * @ref BLE_ERROR_NO_TX_BUFFERS error by queueing the packet to be transmitted and - * try again as soon as a @ref BLE_EVT_TX_COMPLETE event arrives. - * - * The API functions that may consume an application buffer depending on - * the parameters supplied to them can be found below: - * - * - @ref sd_ble_gattc_write (write without response only) - * - @ref sd_ble_gatts_hvx (notifications only) - * - @ref sd_ble_l2cap_tx (all packets) - * - * @param[out] p_count Pointer to a uint8_t which will contain the number of application transmission buffers upon - * successful return. - * - * @retval ::NRF_SUCCESS Number of application transmission buffers retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_TX_BUFFER_COUNT_GET, uint32_t, sd_ble_tx_buffer_count_get(uint8_t *p_count)); - - -/**@brief Add a Vendor Specific UUID. - * - * @details This call enables the application to add a vendor specific UUID to the BLE stack's table, - * for later use all other modules and APIs. This then allows the application to use the shorter, - * 24-bit @ref ble_uuid_t format when dealing with both 16-bit and 128-bit UUIDs without having to - * check for lengths and having split code paths. The way that this is accomplished is by extending the - * grouping mechanism that the Bluetooth SIG standard base UUID uses for all other 128-bit UUIDs. The - * type field in the @ref ble_uuid_t structure is an index (relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN) - * to the table populated by multiple calls to this function, and the uuid field in the same structure - * contains the 2 bytes at indices 12 and 13. The number of possible 128-bit UUIDs available to the - * application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, - * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. - * - * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by - * the 16-bit uuid field in @ref ble_uuid_t. - * - * - * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding - * bytes 12 and 13. - * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored. - * - * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID. - * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. - * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. - * @retval ::NRF_ERROR_FORBIDDEN If p_vs_uuid has already been added to the VS UUID table. - */ -SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); - - -/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. - * - * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared - * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add - * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index - * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. - * - * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. - * - * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). - * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. - * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. - * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. - */ -SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); - - -/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). - * - * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. - * - * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. - * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). - * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. - * - * @retval ::NRF_SUCCESS Successfully encoded into the buffer. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. - */ -SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); - - -/**@brief Get Version Information. - * - * @details This call allows the application to get the BLE stack version information. - * - * @param[out] p_version Pointer to a ble_version_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Version information stored successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY The stack is busy (typically doing a locally-initiated disconnection procedure). - */ -SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); - - -/**@brief Provide a user memory block. - * - * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. - * - * @param[in] conn_handle Connection handle. - * @param[in,out] p_block Pointer to a user memory block structure. - * - * @retval ::NRF_SUCCESS Successfully queued a response to the peer. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no execute write request pending. - * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time. - */ -SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); - -/**@brief Set a BLE option. - * - * @details This call allows the application to set the value of an option. - * - * @param[in] opt_id Option ID. - * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. - * - * @retval ::NRF_SUCCESS Option set successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. - * @retval ::NRF_ERROR_BUSY The stack is busy or the previous procedure has not completed. - */ -SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); - - -/**@brief Get a BLE option. - * - * @details This call allows the application to retrieve the value of an option. - * - * @param[in] opt_id Option ID. - * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Option retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. - * @retval ::NRF_ERROR_BUSY The stack is busy or the previous procedure has not completed. - * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. - * - */ -SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); - -/** @} */ - -#endif /* BLE_H__ */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s120/headers/ble_gap.h b/components/softdevice/s120/headers/ble_gap.h deleted file mode 100644 index de25d37..0000000 --- a/components/softdevice/s120/headers/ble_gap.h +++ /dev/null @@ -1,1365 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_GAP Generic Access Profile (GAP) - @{ - @brief Definitions and prototypes for the GAP interface. - */ - -#ifndef BLE_GAP_H__ -#define BLE_GAP_H__ - -#include "ble_types.h" -#include "ble_ranges.h" -#include "nrf_svc.h" - -/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations - * @{ */ - -/**@brief GAP API SVC numbers. - */ -enum BLE_GAP_SVCS -{ - SD_BLE_GAP_ADDRESS_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ - SD_BLE_GAP_ADDRESS_GET, /**< Get own Bluetooth Address. */ - SD_BLE_GAP_ADV_DATA_SET, /**< Set Advertising Data. */ - SD_BLE_GAP_ADV_START, /**< Start Advertising. */ - SD_BLE_GAP_ADV_STOP, /**< Stop Advertising. */ - SD_BLE_GAP_CONN_PARAM_UPDATE, /**< Connection Parameter Update. */ - SD_BLE_GAP_DISCONNECT, /**< Disconnect. */ - SD_BLE_GAP_TX_POWER_SET, /**< Set TX Power. */ - SD_BLE_GAP_APPEARANCE_SET, /**< Set Appearance. */ - SD_BLE_GAP_APPEARANCE_GET, /**< Get Appearance. */ - SD_BLE_GAP_PPCP_SET, /**< Set PPCP. */ - SD_BLE_GAP_PPCP_GET, /**< Get PPCP. */ - SD_BLE_GAP_DEVICE_NAME_SET, /**< Set Device Name. */ - SD_BLE_GAP_DEVICE_NAME_GET, /**< Get Device Name. */ - SD_BLE_GAP_AUTHENTICATE, /**< Initiate Pairing/Bonding. */ - SD_BLE_GAP_SEC_PARAMS_REPLY, /**< Reply with Security Parameters. */ - SD_BLE_GAP_AUTH_KEY_REPLY, /**< Reply with an authentication key. */ - SD_BLE_GAP_ENCRYPT, /**< Initiate encryption procedure. */ - SD_BLE_GAP_SEC_INFO_REPLY, /**< Reply with Security Information. */ - SD_BLE_GAP_CONN_SEC_GET, /**< Obtain connection security level. */ - SD_BLE_GAP_RSSI_START, /**< Start reporting of changes in RSSI. */ - SD_BLE_GAP_RSSI_STOP, /**< Stop reporting of changes in RSSI. */ - SD_BLE_GAP_SCAN_START, /**< Start Scanning. */ - SD_BLE_GAP_SCAN_STOP, /**< Stop Scanning. */ - SD_BLE_GAP_CONNECT, /**< Connect. */ - SD_BLE_GAP_CONNECT_CANCEL, /**< Cancel ongoing connection procedure. */ - SD_BLE_GAP_RSSI_GET, /**< Get the last RSSI sample. */ -}; - -/**@brief GAP Event IDs. - * IDs that uniquely identify an event coming from the stack to the application. - */ -enum BLE_GAP_EVTS -{ - BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connection established. */ - BLE_GAP_EVT_DISCONNECTED, /**< Disconnected from peer. */ - BLE_GAP_EVT_CONN_PARAM_UPDATE, /**< Connection Parameters updated. */ - BLE_GAP_EVT_SEC_PARAMS_REQUEST, /**< Request to provide security parameters. */ - BLE_GAP_EVT_SEC_INFO_REQUEST, /**< Request to provide security information. */ - BLE_GAP_EVT_PASSKEY_DISPLAY, /**< Request to display a passkey to the user. */ - BLE_GAP_EVT_AUTH_KEY_REQUEST, /**< Request to provide an authentication key. */ - BLE_GAP_EVT_AUTH_STATUS, /**< Authentication procedure completed with status. */ - BLE_GAP_EVT_CONN_SEC_UPDATE, /**< Connection security updated. */ - BLE_GAP_EVT_TIMEOUT, /**< Timeout expired. */ - BLE_GAP_EVT_RSSI_CHANGED, /**< Signal strength measurement report. */ - BLE_GAP_EVT_ADV_REPORT, /**< Advertising report. */ - BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. */ - BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. */ - BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. */ -}; - -/**@brief GAP Option IDs. - * IDs that uniquely identify a GAP option. - */ -enum BLE_GAP_OPTS -{ - BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ - BLE_GAP_OPT_LOCAL_CONN_LATENCY, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ - BLE_GAP_OPT_PASSKEY, /**< Set passkey. @ref ble_gap_opt_passkey_t */ - BLE_GAP_OPT_PRIVACY, /**< Custom privacy. @ref ble_gap_opt_privacy_t */ - BLE_GAP_OPT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_opt_scan_req_report_t */ - BLE_GAP_OPT_COMPAT_MODE /**< Compatibility mode. @ref ble_gap_opt_compat_mode_t */ -}; -/** @} */ - -/**@addtogroup BLE_GAP_DEFINES Defines - * @{ */ - -/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP - * @{ */ -#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ -#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ -#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ -/**@} */ - - -/**@defgroup BLE_GAP_ROLES GAP Roles - * @{ */ -#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */ -#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */ -#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */ -/**@} */ - - -/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources - * @{ */ -#define BLE_GAP_TIMEOUT_SRC_ADVERTISING 0x00 /**< Advertising timeout. */ -#define BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST 0x01 /**< Security request timeout. */ -#define BLE_GAP_TIMEOUT_SRC_SCAN 0x02 /**< Scanning timeout. */ -#define BLE_GAP_TIMEOUT_SRC_CONN 0x03 /**< Connection timeout. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types - * @{ */ -#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random Static address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Private Resolvable address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Private Non-Resolvable address. */ -/**@} */ - -/**@defgroup BLE_GAP_ADDR_CYCLE_MODES GAP Address cycle modes - * @{ */ -#define BLE_GAP_ADDR_CYCLE_MODE_NONE 0x00 /**< Set addresses directly, no automatic address cycling. */ -#define BLE_GAP_ADDR_CYCLE_MODE_AUTO 0x01 /**< Automatically generate and update private addresses. */ -/** @} */ - -/**@brief The default interval in seconds at which a private address is refreshed when address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO. */ -#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (60 * 15) - -/** @brief BLE address length. */ -#define BLE_GAP_ADDR_LEN 6 - - -/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format - * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm - * @{ */ -#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */ -#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */ -#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */ -#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */ -#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */ -#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */ -#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */ -#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */ -#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */ -#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */ -#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */ -#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */ -#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */ -#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */ -#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */ -#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ -#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */ -#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */ -#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ -#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ -#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ -#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ -#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags - * @{ */ -#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */ -#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */ -#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */ -#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */ -#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */ -#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */ -#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min - * @{ */ -#define BLE_GAP_ADV_INTERVAL_MIN 0x0020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */ -#define BLE_GAP_ADV_NONCON_INTERVAL_MIN 0x00A0 /**< Minimum Advertising interval in 625 us units for non connectable mode, i.e. 100 ms. */ -#define BLE_GAP_ADV_INTERVAL_MAX 0x4000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s. */ - /**@} */ - - -/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min - * @{ */ -#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */ -#define BLE_GAP_SCAN_INTERVAL_MAX 0x4000 /**< Maximum Scan interval in 625 us units, i.e. 10.24 s. */ - /** @} */ - - -/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min - * @{ */ -#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */ -#define BLE_GAP_SCAN_WINDOW_MAX 0x4000 /**< Maximum Scan window in 625 us units, i.e. 10.24 s. */ - /** @} */ - - -/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min - * @{ */ -#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in seconds. */ -#define BLE_GAP_SCAN_TIMEOUT_MAX 0xFFFF /**< Maximum Scan timeout in seconds. */ - /** @} */ - - -/**@brief Maximum size of advertising data in octets. */ -#define BLE_GAP_ADV_MAX_SIZE 31 - - -/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types - * @{ */ -#define BLE_GAP_ADV_TYPE_ADV_IND 0x00 /**< Connectable undirected. */ -#define BLE_GAP_ADV_TYPE_ADV_DIRECT_IND 0x01 /**< Connectable directed. */ -#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND 0x02 /**< Scannable undirected. */ -#define BLE_GAP_ADV_TYPE_ADV_NONCONN_IND 0x03 /**< Non connectable undirected. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies - * @{ */ -#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */ -#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */ -#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */ -#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */ -/**@} */ - - -/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values - * @{ */ -#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX 180 /**< Maximum advertising time in limited discoverable mode (TGAP(lim_adv_timeout) = 180s in spec (Addendum 2)). */ -#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED 0 /**< Unlimited advertising in general discoverable mode. */ -/**@} */ - - -/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes - * @{ */ -#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */ -#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */ -#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */ -/**@} */ - -/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities - * @{ */ -#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */ -#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */ -#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */ -#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */ -#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */ -/**@} */ - - -/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types - * @{ */ -#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */ -#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */ -#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ -/**@} */ - -/**@defgroup BLE_GAP_SEC_STATUS GAP Security status - * @{ */ -#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ -#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */ -#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */ -#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user cancelled or other). */ -#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */ -#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */ -#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */ -#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */ -#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */ -#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */ -#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ -#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ -#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ -/**@} */ - -/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources - * @{ */ -#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */ -#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */ -/**@} */ - -/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits - * @{ */ -#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connction interval specified in connect parameters. */ -#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest mimimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ -#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connction interval specified in connect parameters. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ -#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ -#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */ -#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */ -#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */ -/**@} */ - - -/**@brief GAP device name maximum length. */ -#define BLE_GAP_DEVNAME_MAX_LEN 31 - -/**@brief Disable RSSI events for connections */ -#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF - -/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters - * - * See @ref ble_gap_conn_sec_mode_t. - * @{ */ -/**@brief Set sec_mode pointed to by ptr to have no access rights.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) -/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) -/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) -/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) -/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) -/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) -/**@} */ - - -/**@brief GAP Security Random Number Length. */ -#define BLE_GAP_SEC_RAND_LEN 8 - -/**@brief GAP Security Key Length. */ -#define BLE_GAP_SEC_KEY_LEN 16 - -/**@brief GAP Passkey Length. */ -#define BLE_GAP_PASSKEY_LEN 6 - -/**@brief Maximum amount of addresses in a whitelist. */ -#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8) - -/**@brief Maximum amount of IRKs in a whitelist. - * @note The number of IRKs is limited to 8, even if the hardware supports more. - */ -#define BLE_GAP_WHITELIST_IRK_MAX_COUNT (8) - -/**@defgroup GAP_SEC_MODES GAP Security Modes - * @{ */ -#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ -/**@} */ - -/**@} */ - -/**@addtogroup BLE_GAP_STRUCTURES Structures - * @{ */ - -/** - * @brief BLE GAP init options - */ -typedef struct -{ - uint8_t role:2; /**< BLE role to use, see @ref BLE_GAP_ROLES */ -} ble_gap_enable_params_t; - - -/**@brief Bluetooth Low Energy address. */ -typedef struct -{ - uint8_t addr_type; /**< See @ref BLE_GAP_ADDR_TYPES. */ - uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */ -} ble_gap_addr_t; - - -/**@brief GAP connection parameters. - * - * @note When ble_conn_params_t is received in an event, both min_conn_interval and - * max_conn_interval will be equal to the connection interval set by the central. - * - * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies: - * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval - * that corresponds to the following BT Spec 4.1 Vol 2 Part E, Section 7.8.12 requirement: - * The Supervision_Timeout in milliseconds shall be larger than - * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds. - */ -typedef struct -{ - uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/ - uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ -} ble_gap_conn_params_t; - - -/**@brief GAP link requirements. - * - * See Bluetooth Core specification, Volume 3 Part C 10.2 for details. - * - * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n - * Security Mode 1 Level 1: No security is needed (aka open link).\n - * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n - * Security Mode 1 Level 3: MITM protected encrypted link required.\n - * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n - * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n - */ -typedef struct -{ - uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ - uint8_t lv : 4; /**< Level (1, 2 or 3), 0 for no permissions at all. */ - -} ble_gap_conn_sec_mode_t; - - -/**@brief GAP connection security status.*/ -typedef struct -{ - ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/ - uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */ -} ble_gap_conn_sec_t; - - -/**@brief Identity Resolving Key. */ -typedef struct -{ - uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ -} ble_gap_irk_t; - - -/**@brief Whitelist structure. */ -typedef struct -{ - ble_gap_addr_t **pp_addrs; /**< Pointer to array of device address pointers, pointing to addresses to be used in whitelist. NULL if none are given. */ - uint8_t addr_count; /**< Count of device addresses in array, up to @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. */ - ble_gap_irk_t **pp_irks; /**< Pointer to array of Identity Resolving Key (IRK) pointers, each pointing to an IRK in the whitelist. NULL if none are given. */ - uint8_t irk_count; /**< Count of IRKs in array, up to @ref BLE_GAP_WHITELIST_IRK_MAX_COUNT. */ -} ble_gap_whitelist_t; - -/**@brief Channel mask for RF channels used in advertising and scanning. */ -typedef struct -{ - uint8_t ch_37_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 37 */ - uint8_t ch_38_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 38 */ - uint8_t ch_39_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 39 */ -} ble_gap_adv_ch_mask_t; - -/**@brief GAP advertising parameters.*/ -typedef struct -{ - uint8_t type; /**< See @ref BLE_GAP_ADV_TYPES. */ - ble_gap_addr_t *p_peer_addr; /**< For @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND mode only, known peer address. */ - uint8_t fp; /**< Filter Policy, see @ref BLE_GAP_ADV_FILTER_POLICIES. */ - ble_gap_whitelist_t *p_whitelist; /**< Pointer to whitelist, NULL if none is given. */ - uint16_t interval; /**< Advertising interval between 0x0020 and 0x4000 in 0.625 ms units (20ms to 10.24s), see @ref BLE_GAP_ADV_INTERVALS. - - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for high duty cycle directed advertising. - - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, set @ref BLE_GAP_ADV_INTERVAL_MIN <= interval <= @ref BLE_GAP_ADV_INTERVAL_MAX for low duty cycle advertising.*/ - uint16_t timeout; /**< Advertising timeout between 0x0001 and 0x3FFF in seconds, 0x0000 disables timeout. See also @ref BLE_GAP_ADV_TIMEOUT_VALUES. If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for High duty cycle directed advertising. */ - ble_gap_adv_ch_mask_t channel_mask; /**< Advertising channel mask. @see ble_gap_channel_mask_t for documentation. */ -} ble_gap_adv_params_t; - - -/**@brief GAP scanning parameters. */ -typedef struct -{ - uint8_t active : 1; /**< If 1, perform active scanning (scan requests). */ - uint8_t selective : 1; /**< If 1, ignore unknown devices (non whitelisted). */ - ble_gap_whitelist_t * p_whitelist; /**< Pointer to whitelist, NULL if none is given. */ - uint16_t interval; /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ - uint16_t window; /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ - uint16_t timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ -} ble_gap_scan_params_t; - - -/** @brief Keys that can be exchanged. */ -typedef struct -{ - uint8_t enc : 1; /**< Long Term Key and Master Identification. */ - uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ - uint8_t sign : 1; /**< Connection Signature Resolving Key. */ -} ble_gap_sec_kdist_t; - - -/**@brief GAP security parameters. */ -typedef struct -{ - uint8_t bond : 1; /**< Perform bonding. */ - uint8_t mitm : 1; /**< Man In The Middle protection required. */ - uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ - uint8_t oob : 1; /**< Out Of Band data available. */ - uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ - uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ - ble_gap_sec_kdist_t kdist_periph; /**< Key distribution bitmap: keys that the peripheral device will distribute. */ - ble_gap_sec_kdist_t kdist_central; /**< Key distribution bitmap: keys that the central device will distribute. */ -} ble_gap_sec_params_t; - - -/**@brief GAP Encryption Information. */ -typedef struct -{ - uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ - uint8_t auth : 1; /**< Authenticated Key. */ - uint8_t ltk_len : 7; /**< LTK length in octets. */ -} ble_gap_enc_info_t; - - -/**@brief GAP Master Identification. */ -typedef struct -{ - uint16_t ediv; /**< Encrypted Diversifier. */ - uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */ -} ble_gap_master_id_t; - - -/**@brief GAP Signing Information. */ -typedef struct -{ - uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */ -} ble_gap_sign_info_t; - - -/**@brief Event data for connected event. */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ - ble_gap_addr_t own_addr; /**< Bluetooth address of the local device used during connection setup. */ - uint8_t irk_match :1; /**< If 1, peer device's address resolved using an IRK. */ - uint8_t irk_match_idx :7; /**< Index in IRK list where the address was matched. */ - ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ -} ble_gap_evt_connected_t; - - -/**@brief Event data for disconnected event. */ -typedef struct -{ - uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */ -} ble_gap_evt_disconnected_t; - - -/**@brief Event data for connection parameter update event. */ -typedef struct -{ - ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ -} ble_gap_evt_conn_param_update_t; - - -/**@brief Event data for security parameters request event. */ -typedef struct -{ - ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */ -} ble_gap_evt_sec_params_request_t; - - -/**@brief Event data for security info request event. */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ - ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */ - uint8_t enc_info : 1; /**< If 1, Encryption Information required. */ - uint8_t id_info : 1; /**< If 1, Identity Information required. */ - uint8_t sign_info : 1; /**< If 1, Signing Information required. */ -} ble_gap_evt_sec_info_request_t; - - -/**@brief Event data for passkey display event. */ -typedef struct -{ - uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ -} ble_gap_evt_passkey_display_t; - - -/**@brief Event data for authentication key request event. */ -typedef struct -{ - uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ -} ble_gap_evt_auth_key_request_t; - - -/**@brief Security levels supported. - * @note See Bluetooth Specification Version 4.1 Volume 3, Part C, Chapter 10. -*/ -typedef struct -{ - uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ - uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ - uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ -} ble_gap_sec_levels_t; - - -/**@brief Encryption Key. */ -typedef struct -{ - ble_gap_enc_info_t enc_info; /**< Encryption Information. */ - ble_gap_master_id_t master_id; /**< Master Identification. */ -} ble_gap_enc_key_t; - - -/**@brief Identity Key. */ -typedef struct -{ - ble_gap_irk_t id_info; /**< Identity Information. */ - ble_gap_addr_t id_addr_info; /**< Identity Address Information. */ -} ble_gap_id_key_t; - - -/**@brief Security Keys. */ -typedef struct -{ - ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ - ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ - ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ -} ble_gap_sec_keys_t; - - -/**@brief Security key set (both Peripheral and Central keys). - * Note that when distributing Bluetooth addresses pertaining to the local device those - * will have to be filled in by the user. */ -typedef struct -{ - ble_gap_sec_keys_t keys_periph; /**< Keys distributed by the device in the Peripheral role. */ - ble_gap_sec_keys_t keys_central; /**< Keys distributed by the device in the Central role. */ -} ble_gap_sec_keyset_t; - - -/**@brief Event data for authentication status event. */ -typedef struct -{ - uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */ - uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */ - uint8_t bonded : 1; /**< Procedure resulted in a bond. */ - ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ - ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ - ble_gap_sec_kdist_t kdist_periph; /**< Bitmap stating which keys were exchanged (distributed) by the peripheral. */ - ble_gap_sec_kdist_t kdist_central; /**< Bitmap stating which keys were exchanged (distributed) by the central. */ -} ble_gap_evt_auth_status_t; - - -/**@brief Event data for connection security update event. */ -typedef struct -{ - ble_gap_conn_sec_t conn_sec; /**< Connection security level. */ -} ble_gap_evt_conn_sec_update_t; - - -/**@brief Event data for timeout event. */ -typedef struct -{ - uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */ -} ble_gap_evt_timeout_t; - - -/**@brief Event data for advertisement report event. */ -typedef struct -{ - int8_t rssi; /**< Received Signal Strength Indication in dBm. */ -} ble_gap_evt_rssi_changed_t; - - -/**@brief Event data for advertising report event. */ -typedef struct -{ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ - int8_t rssi; /**< Received Signal Strength Indication in dBm. */ - uint8_t scan_rsp : 1; /**< If 1, the report corresponds to a scan response and the type field may be ignored. */ - uint8_t type : 2; /**< See @ref BLE_GAP_ADV_TYPES. Only valid if the scan_rsp field is 0. */ - uint8_t dlen : 5; /**< Advertising or scan response data length. */ - uint8_t data[BLE_GAP_ADV_MAX_SIZE]; /**< Advertising or scan response data. */ -} ble_gap_evt_adv_report_t; - - -/**@brief Event data for scan request report events. */ -typedef struct -{ - int8_t rssi; /**< Received Signal Strength Indication in dBm. */ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ -} ble_gap_evt_scan_req_report_t; - - -/**@brief Event data for security request event. */ -typedef struct -{ - uint8_t bond : 1; /**< Perform bonding. */ - uint8_t mitm : 1; /**< Man In The Middle protection required. */ -} ble_gap_evt_sec_request_t; - - -/**@brief Event data for connection parameter update request event. */ -typedef struct -{ - ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ -} ble_gap_evt_conn_param_update_request_t; - - -/**@brief GAP event callback event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which event occured. */ - union /**< union alternative identified by evt_id in enclosing struct. */ - { - ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ - ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */ - ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */ - ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ - ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ - ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ - ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ - ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ - ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ - ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ - ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event parameters. */ - ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */ - ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */ - ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ - ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report parameters. */ - } params; /**< Event Parameters. */ - -} ble_gap_evt_t; - - -/**@brief Channel Map option. - * Used with @ref sd_ble_opt_get to get the current channel map - * or @ref sd_ble_opt_set to set a new channel map. When setting the - * channel map, it applies to all current and future connections. When getting the - * current channel map, it applies to a single connection and the connection handle - * must be supplied. - * - * @note Setting the channel map may take some time, depending on connection parameters. - * The time taken may be different for each connection and the get operation will - * return the previous channel map until the new one has taken effect. - * - * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed. - * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46. - * - * @retval ::NRF_SUCCESS Get or set successful. - * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get. - * @retval ::NRF_ERROR_NOT_SUPPORTED Returned by sd_ble_opt_set in peripheral-only SoftDevices. - * - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle (only applicable for get) */ - uint8_t ch_map[5]; /**< Channel Map (37-bit). */ -} ble_gap_opt_ch_map_t; - - -/**@brief Local connection latency option. - * - * Local connection latency is a feature which enables the slave to improve - * current consumption by ignoring the slave latency set by the peer. The - * local connection latency can only be set to a multiple of the slave latency, - * and cannot be longer than half of the supervision timeout. - * - * Used with @ref sd_ble_opt_set to set the local connection latency. The - * @ref sd_ble_opt_get is not supported for this option, but the actual - * local connection latency (unless set to NULL) is set as a return parameter - * when setting the option. - * - * @note The latency set will be truncated down to the closest slave latency event - * multiple, or the nearest multiple before half of the supervision timeout. - * - * @note The local connection latency is default off, and needs to be set for new - * connections and whenever the connection is updated. - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. - */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle */ - uint16_t requested_latency; /**< Requested local connection latency. */ - uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */ -} ble_gap_opt_local_conn_latency_t; - - -/**@brief Passkey Option. - * - * Structure containing the passkey to be used during pairing. This can be used with @ref - * sd_ble_opt_set to make the SoftDevice use a pre-programmed passkey for authentication - * instead of generating a random one. - * - * @note @ref sd_ble_opt_get is not supported for this option. - * - */ -typedef struct -{ - uint8_t * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/ -} ble_gap_opt_passkey_t; - - -/**@brief Custom Privacy Option. - * - * This structure is used with both @ref sd_ble_opt_set (as input) and with - * @ref sd_ble_opt_get (as output). - * - * Structure containing: - * - A pointer to an IRK to set (if input), or a place to store a read IRK (if output). - * - A private address refresh cycle. - * - * @note The specified address cycle interval is used when the address cycle mode is - * @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO. If 0 is given, the address will not be automatically - * refreshed at all. The default interval is @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. - * - * @note If the current address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO, the address will immediately be - * refreshed when a custom privacy option is set. A new address can be generated manually by calling - * @ref sd_ble_gap_address_set with the same type again. - * - * @note If the IRK is updated, the new IRK becomes the one to be distributed in all - * bonding procedures performed after @ref sd_ble_opt_set returns. - * - * @retval ::NRF_SUCCESS Set or read successfully. - * @retval ::NRF_ERROR_INVALID_ADDR The pointer to IRK storage is invalid. - */ -typedef struct -{ - ble_gap_irk_t * p_irk; /**< When input: Pointer to custom IRK, or NULL to use/reset to the device's default IRK. When output: Pointer to where the current IRK is to be stored, or NULL to not read out the IRK. */ - uint16_t interval_s; /**< When input: Custom private address cycle interval in seconds. When output: The current private address cycle interval. */ -} ble_gap_opt_privacy_t; - - -/**@brief Scan request report option. - * - * This can be used with @ref sd_ble_opt_set to make the SoftDevice send - * @ref BLE_GAP_EVT_SCAN_REQ_REPORT events. - * - * @note Due to the limited space reserved for scan request report events, - * not all received scan requests will be reported. - * - * @note If whitelisting is used, only whitelisted requests are reported. - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_INVALID_STATE When advertising is ongoing while the option is set. - */ -typedef struct -{ - uint8_t enable : 1; /**< Enable scan request reports. */ -} ble_gap_opt_scan_req_report_t; - -/**@brief Compatibility mode option. - * - * This can be used with @ref sd_ble_opt_set to enable and disable - * compatibility modes. Compatibility modes are disabled by default. - * - * @note Compatibility mode 1 enables interoperability with devices that do not support - * a value of 0 for the WinOffset parameter in the Link Layer CONNECT_REQ packet. - * - * @retval ::NRF_SUCCESS Set successfully. - * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set. - */ -typedef struct -{ - uint8_t mode_1_enable : 1; /**< Enable compatibility mode 1.*/ -} ble_gap_opt_compat_mode_t; - - -/**@brief Option structure for GAP options. */ -typedef union -{ - ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ - ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ - ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ - ble_gap_opt_privacy_t privacy; /**< Parameters for the Custom privacy option. */ - ble_gap_opt_scan_req_report_t scan_req_report; /**< Parameters for the scan request report option.*/ - ble_gap_opt_compat_mode_t compat_mode; /**< Parameters for the compatibility mode option.*/ -} ble_gap_opt_t; -/**@} */ - - -/**@addtogroup BLE_GAP_FUNCTIONS Functions - * @{ */ - -/**@brief Set local Bluetooth address. - * - * @note If the address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO, the address type is required to - * be @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or - * @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. The given address is ignored and the - * SoftDevice will generate a new private address automatically every - * @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S seconds. If this API - * call is used again with the same parameters, the SoftDevice will immediately - * generate a new private address to replace the current address. - * - * @note If the application wishes to use a @ref BLE_GAP_ADDR_TYPE_PUBLIC or - * @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC address, the cycle mode must be - * @ref BLE_GAP_ADDR_CYCLE_MODE_NONE. - * - * @note If this API function is called while advertising or scanning, the softdevice will immediately update the - * advertising or scanning address without the need to stop the procedure in the following cases: - * - If the previously set address is of type @ref BLE_GAP_ADDR_TYPE_PUBLIC and the new address - * is also of type @ref BLE_GAP_ADDR_TYPE_PUBLIC - * - If the previously set address is not @ref BLE_GAP_ADDR_TYPE_PUBLIC and the new address is - * also not @ref BLE_GAP_ADDR_TYPE_PUBLIC. - * If the address is changed from a @ref BLE_GAP_ADDR_TYPE_PUBLIC address to another type or from - * another type to a @ref BLE_GAP_ADDR_TYPE_PUBLIC address, the change will take effect the next - * time an advertising or scanning procedure is started. - * - * @note If the address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_NONE and the application is - * using privacy, the application must take care to generate and set new private addresses - * periodically to comply with the Privacy specification in Bluetooth Core Spec. - * - * @param[in] addr_cycle_mode Address cycle mode, see @ref BLE_GAP_ADDR_CYCLE_MODES. - * @param[in] p_addr Pointer to address structure. - * - * @retval ::NRF_SUCCESS Address successfully set. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - */ -SVCALL(SD_BLE_GAP_ADDRESS_SET, uint32_t, sd_ble_gap_address_set(uint8_t addr_cycle_mode, const ble_gap_addr_t *p_addr)); - - -/**@brief Get local Bluetooth address. - * - * @param[out] p_addr Pointer to address structure to be filled in. - * - * @retval ::NRF_SUCCESS Address successfully retrieved. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_GAP_ADDRESS_GET, uint32_t, sd_ble_gap_address_get(ble_gap_addr_t *p_addr)); - - -/**@brief Set, clear or update advertising and scan response data. - * - * @note The format of the advertising data will be checked by this call to ensure interoperability. - * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and - * duplicating the local name in the advertising data and scan response data. - * - * @note To clear the advertising data and set it to a 0-length packet, simply provide a valid pointer (p_data/p_sr_data) with its corresponding - * length (dlen/srdlen) set to 0. - * - * @note The call will fail if p_data and p_sr_data are both NULL since this would have no effect. - * - * @param[in] p_data Raw data to be placed in advertising packet. If NULL, no changes are made to the current advertising packet data. - * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_data is NULL, can be 0 if p_data is not NULL. - * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, no changes are made to the current scan response packet data. - * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL. - * - * @retval ::NRF_SUCCESS Advertising data successfully updated or cleared. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. - * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied, check the advertising data format specification. - * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied. - * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied. - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Central role. - */ -SVCALL(SD_BLE_GAP_ADV_DATA_SET, uint32_t, sd_ble_gap_adv_data_set(uint8_t const *p_data, uint8_t dlen, uint8_t const *p_sr_data, uint8_t srdlen)); - - -/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). - * - * @note An application can start an advertising procedure for broadcasting purposes while a connection - * is active. After a @ref BLE_GAP_EVT_CONNECTED event is received, this function may therefore - * be called to start a broadcast advertising procedure. The advertising procedure - * cannot however be connectable (it must be of type @ref BLE_GAP_ADV_TYPE_ADV_SCAN_IND or - * @ref BLE_GAP_ADV_TYPE_ADV_NONCONN_IND). @note Only one advertiser may be active at any time. - * - * @param[in] p_adv_params Pointer to advertising parameters structure. - * - * @retval ::NRF_SUCCESS The BLE stack has started advertising. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check the accepted ranges and limits. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Bluetooth address supplied. - * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Central role. - */ -SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params)); - - -/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). - * - * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in advertising state). - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Central role. - */ -SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(void)); - - -/**@brief Update connection parameters. - * - * @details In the central role this will initiate a Link Layer connection parameter update procedure, - * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for - * the central to perform the procedure. In both cases, and regardless of success or failure, the application - * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event. - * - * @details This function can be used both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, - * the parameters in the PPCP characteristic of the GAP service will be used instead. - * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected - * - * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, process pending events and wait for pending procedures to complete and retry. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - */ -SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params)); - - -/**@brief Disconnect (GAP Link Termination). - * - * @details This call initiates the disconnection procedure, and its completion will be communicated to the application - * with a @ref BLE_GAP_EVT_DISCONNECTED event. - * - * @param[in] conn_handle Connection handle. - * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are BTLE_REMOTE_USER_TERMINATED_CONNECTION and BTLE_CONN_INTERVAL_UNACCEPTABLE). - * - * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (disconnection is already in progress). - */ -SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code)); - - -/**@brief Set the radio's transmit power. - * - * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm). - * - * @note -40 dBm will not actually give -40 dBm, but will instead be remapped to -30 dBm. - * - * @retval ::NRF_SUCCESS Successfully changed the transmit power. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - */ -SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(int8_t tx_power)); - - -/**@brief Set GAP Appearance value. - * - * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES. - * - * @retval ::NRF_SUCCESS Appearance value set successfully. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - */ -SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance)); - - -/**@brief Get GAP Appearance value. - * - * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES. - * - * @retval ::NRF_SUCCESS Appearance value retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance)); - - -/**@brief Set GAP Peripheral Preferred Connection Parameters. - * - * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters. - * - * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Central role. - */ -SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params)); - - -/**@brief Get GAP Peripheral Preferred Connection Parameters. - * - * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored. - * - * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Central role. - */ -SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params)); - - -/**@brief Set GAP device name. - * - * @param[in] p_write_perm Write permissions for the Device Name characteristic see @ref ble_gap_conn_sec_mode_t. - * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. - * @param[in] len Length of the UTF-8, non NULL-terminated string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN). - * - * @retval ::NRF_SUCCESS GAP device name and permissions set successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - */ -SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len)); - - -/**@brief Get GAP device name. - * - * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. - * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. - * - * @note If the device name is longer than the size of the supplied buffer, - * p_len will return the complete device name length, - * and not the number of bytes actually returned in p_dev_name. - * The application may use this information to allocate a suitable buffer size. - * - * @retval ::NRF_SUCCESS GAP device name retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - */ -SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len)); - - -/**@brief Initiate GAP Authentication procedure. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing procedure. - * In the peripheral role, only the timeout, bond and mitm fields of this structure are used. - * In the central role, this pointer may be NULL to reject a Security Request. - * - * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), - * otherwise in the peripheral role, an SMP Security Request will be sent. - * - * @note Calling this function may result in the following events depending on the outcome and parameters: @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, - * @ref BLE_GAP_EVT_SEC_INFO_REQUEST, @ref BLE_GAP_EVT_AUTH_KEY_REQUEST, @ref BLE_GAP_EVT_AUTH_STATUS. - * - * - * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_TIMEOUT A SMP timout has occured, and further SMP operations on this link is prohibited. - */ -SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); - - -/**@brief Reply with GAP security parameters. - * - * @param[in] conn_handle Connection handle. - * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. - * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. As a central this must be set to NULL, as the parameters have - * already been provided during a previous call to @ref sd_ble_gap_authenticate. - * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys distributed as a result of the ongoing security procedure - * will be stored into the memory referenced inside this structure. The keys will be stored and availabel to the applicaiton upon reception - * of a @ref BLE_GAP_EVT_AUTH_STATUS event. A NULL pointer will result in the keys not being stored at all. - * The ID key data distributed by the local device constitute an exception. It will either have to be filled in by the user - * before calling this function, in which case the filled in address and IRK is distributed, or the pointer to the ID key data structure - * can be NULL, in which case the device's configured (or default, if none is configured) Bluetooth address and IRK is distributed. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * - * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); - - -/**@brief Reply with an authentication key. - * - * @param[in] conn_handle Connection handle. - * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. - * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. - * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination). - * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in Little Endian format. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * - * @retval ::NRF_SUCCESS Authentication key successfully set. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); - - -/**@brief Initiate GAP Encryption procedure. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. - * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. - * - * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. - * - * @note Calling this function may result in the following event depending on the outcome and parameters: @ref BLE_GAP_EVT_CONN_SEC_UPDATE. - * - * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. - * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry. - */ -SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info)); - - -/**@brief Reply with GAP security information. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available. - * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. - * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * @note Data signing is not implemented yet. p_sign_info must therefore be NULL. - * - * @retval ::NRF_SUCCESS Successfully accepted security information. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info)); - - -/**@brief Get the current connection security. - * - * @param[in] conn_handle Connection handle. - * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Current connection security successfully retrieved. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec)); - - -/**@brief Start reporting the received signal strength to the application. - * - * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. - * - * @param[in] conn_handle Connection handle. - * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID - * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event. - * - * @retval ::NRF_SUCCESS Successfully activated RSSI reporting. - * @retval ::NRF_ERROR_INVALID_STATE Disconnection in progress. Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count)); - - -/**@brief Stop reporting the received signal strength. - * - * An RSSI change detected before the call but not yet received by the application - * may be reported after @ref sd_ble_gap_rssi_stop has been called. - * - * @param[in] conn_handle Connection handle. - * - * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - */ -SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle)); - - -/**@brief Get RSSI for the last connection event. - * - * @param[in] conn_handle Connection handle. - * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. - * - * @ref sd_ble_gap_rssi_start should be called to start sampling RSSI. @ref NRF_ERROR_NOT_FOUND - * will be returned until RSSI was sampled for the first time after calling sd_ble_gap_rssi_start. - * - * @retval ::NRF_SUCCESS Successfully read the RSSI. - * @retval ::NRF_ERROR_NOT_FOUND No sample is available. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_INVALID_STATE RSSI is not started, or disconnection in progress. - */ -SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi)); - - -/**@brief Start scanning (GAP Discovery procedure, Observer Procedure). - * - * @param[in] p_scan_params Pointer to scan parameters structure. - * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_NOT_SUPPORTED A selected feature is not supported (selective scanning). - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. - */ -SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params)); - - -/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). - * - * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in scanning state). - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. - */ -SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); - - -/**@brief Create a connection (GAP Link Establishment). - * - * @param[in] p_peer_addr Pointer to peer address. If the selective bit is set in @ref ble_gap_scan_params_t, then this must be NULL. - * @param[in] p_scan_params Pointer to scan parameters structure. - * @param[in] p_conn_params Pointer to desired connection parameters. - * - * @retval ::NRF_SUCCESS Successfully initiated connection procedure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. - * @retval ::NRF_ERROR_NO_MEM limit of available connections reached. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. -*/ -SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params)); - - -/**@brief Cancel a connection establishment. - * - * @retval ::NRF_SUCCESS Successfully cancelled an inprogress connection procedure. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role. - */ -SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); -/**@} */ - -/** @} */ - -#endif // BLE_GAP_H__ - -/** - @} -*/ diff --git a/components/softdevice/s120/headers/ble_gatt.h b/components/softdevice/s120/headers/ble_gatt.h deleted file mode 100644 index 7887b9b..0000000 --- a/components/softdevice/s120/headers/ble_gatt.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common - @{ - @brief Common definitions and prototypes for the GATT interfaces. - */ - -#ifndef BLE_GATT_H__ -#define BLE_GATT_H__ - -#include "ble_types.h" -#include "ble_ranges.h" - - -/** @addtogroup BLE_GATT_DEFINES Defines - * @{ */ - -/** @brief Default MTU size. */ -#define GATT_MTU_SIZE_DEFAULT 23 - -/** @brief Only the default MTU size of 23 is currently supported. */ -#define GATT_RX_MTU 23 - - -/**@brief Invalid Attribute Handle. */ -#define BLE_GATT_HANDLE_INVALID 0x0000 - -/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources - * @{ */ -#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ -/** @} */ - -/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations - * @{ */ -#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */ -#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */ -#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */ -#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ -#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ -#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */ -/** @} */ - -/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags - * @{ */ -#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 -#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 -/** @} */ - -/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations - * @{ */ -#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */ -#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */ -#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */ -/** @} */ - -/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes - * @{ */ -#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */ -#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */ -#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */ -#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */ -#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */ -#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorisation. */ -#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */ -#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */ -#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */ -#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */ -#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */ -#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */ -#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */ -#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */ -#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */ -#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */ -/** @} */ - - -/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats - * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml - * @{ */ -#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */ -#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */ -#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */ -#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */ -#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */ -#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */ -#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */ -#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */ -#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */ -#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */ -#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */ -#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */ -/** @} */ - -/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces - * @{ - */ -#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */ -#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */ -/** @} */ - -/** @} */ - -/** @addtogroup BLE_GATT_STRUCTURES Structures - * @{ */ - -/**@brief GATT Characteristic Properties. */ -typedef struct -{ - /* Standard properties */ - uint8_t broadcast :1; /**< Broadcasting of value permitted. */ - uint8_t read :1; /**< Reading value permitted. */ - uint8_t write_wo_resp :1; /**< Writing value with Write Command permitted. */ - uint8_t write :1; /**< Writing value with Write Request permitted. */ - uint8_t notify :1; /**< Notications of value permitted. */ - uint8_t indicate :1; /**< Indications of value permitted. */ - uint8_t auth_signed_wr :1; /**< Writing value with Signed Write Command permitted. */ -} ble_gatt_char_props_t; - -/**@brief GATT Characteristic Extended Properties. */ -typedef struct -{ - /* Extended properties */ - uint8_t reliable_wr :1; /**< Writing value with Queued Write Request permitted. */ - uint8_t wr_aux :1; /**< Writing the Characteristic User Description permitted. */ -} ble_gatt_char_ext_props_t; - -#endif // BLE_GATT_H__ - -/** @} */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s120/headers/ble_gattc.h b/components/softdevice/s120/headers/ble_gattc.h deleted file mode 100644 index 347025f..0000000 --- a/components/softdevice/s120/headers/ble_gattc.h +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client - @{ - @brief Definitions and prototypes for the GATT Client interface. - */ - -#ifndef BLE_GATTC_H__ -#define BLE_GATTC_H__ - -#include "ble_gatt.h" -#include "ble_types.h" -#include "ble_ranges.h" -#include "nrf_svc.h" - -/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations - * @{ */ - -/**@brief GATTC API SVC numbers. */ -enum BLE_GATTC_SVCS -{ - SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */ - SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ - SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ - SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ - SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ - SD_BLE_GATTC_READ, /**< Generic read. */ - SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ - SD_BLE_GATTC_WRITE, /**< Generic write. */ - SD_BLE_GATTC_HV_CONFIRM /**< Handle Value Confirmation. */ -}; - -/** - * @brief GATT Client Event IDs. - */ -enum BLE_GATTC_EVTS -{ - BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. */ - BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. */ - BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. */ - BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. */ - BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. */ - BLE_GATTC_EVT_READ_RSP, /**< Read Response event. */ - BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. */ - BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. */ - BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. */ - BLE_GATTC_EVT_TIMEOUT /**< Timeout event. */ -}; - -/** @} */ - -/** @addtogroup BLE_GATTC_DEFINES Defines - * @{ */ - -/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC - * @{ */ -#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ -/** @} */ - -/**@brief Last Attribute Handle. */ -#define BLE_GATTC_HANDLE_END 0xFFFF - -/** @} */ - -/** @addtogroup BLE_GATTC_STRUCTURES Structures - * @{ */ - -/**@brief Operation Handle Range. */ -typedef struct -{ - uint16_t start_handle; /**< Start Handle. */ - uint16_t end_handle; /**< End Handle. */ -} ble_gattc_handle_range_t; - - -/**@brief GATT service. */ -typedef struct -{ - ble_uuid_t uuid; /**< Service UUID. */ - ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */ -} ble_gattc_service_t; - - -/**@brief GATT include. */ -typedef struct -{ - uint16_t handle; /**< Include Handle. */ - ble_gattc_service_t included_srvc; /**< Handle of the included service. */ -} ble_gattc_include_t; - - -/**@brief GATT characteristic. */ -typedef struct -{ - ble_uuid_t uuid; /**< Characteristic UUID. */ - ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ - uint8_t char_ext_props : 1; /**< Extended properties present. */ - uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */ - uint16_t handle_value; /**< Handle of the Characteristic Value. */ -} ble_gattc_char_t; - - -/**@brief GATT descriptor. */ -typedef struct -{ - uint16_t handle; /**< Descriptor Handle. */ - ble_uuid_t uuid; /**< Descriptor UUID. */ -} ble_gattc_desc_t; - - -/**@brief Write Parameters. */ -typedef struct -{ - uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ - uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ - uint16_t handle; /**< Handle to the attribute to be written. */ - uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ - uint16_t len; /**< Length of data in bytes. */ - uint8_t *p_value; /**< Pointer to the value data. */ -} ble_gattc_write_params_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Service count. */ - ble_gattc_service_t services[1]; /**< Service data, variable length. */ -} ble_gattc_evt_prim_srvc_disc_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Include count. */ - ble_gattc_include_t includes[1]; /**< Include data, variable length. */ -} ble_gattc_evt_rel_disc_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Characteristic count. */ - ble_gattc_char_t chars[1]; /**< Characteristic data, variable length. */ -} ble_gattc_evt_char_disc_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ -typedef struct -{ - uint16_t count; /**< Descriptor count. */ - ble_gattc_desc_t descs[1]; /**< Descriptor data, variable length. */ -} ble_gattc_evt_desc_disc_rsp_t; - -/**@brief GATT read by UUID handle value pair. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint8_t *p_value; /**< Pointer to value, variable length (length available as value_len in ble_gattc_evt_read_by_uuid_rsp_t). - Please note that this pointer is absolute to the memory provided by the user when retrieving the event, - so it will effectively point to a location inside the handle_value array. */ -} ble_gattc_handle_value_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */ -typedef struct -{ - uint16_t count; /**< Handle-Value Pair Count. */ - uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ - ble_gattc_handle_value_t handle_value[1]; /**< Handle-Value(s) list, variable length. */ -} ble_gattc_evt_char_val_by_uuid_read_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint16_t offset; /**< Offset of the attribute data. */ - uint16_t len; /**< Attribute data length. */ - uint8_t data[1]; /**< Attribute data, variable length. */ -} ble_gattc_evt_read_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ -typedef struct -{ - uint16_t len; /**< Concatenated Attribute values length. */ - uint8_t values[1]; /**< Attribute values, variable length. */ -} ble_gattc_evt_char_vals_read_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ - uint16_t offset; /**< Data Offset. */ - uint16_t len; /**< Data length. */ - uint8_t data[1]; /**< Data, variable length. */ -} ble_gattc_evt_write_rsp_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ -typedef struct -{ - uint16_t handle; /**< Handle to which the HVx operation applies. */ - uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ - uint16_t len; /**< Attribute data length. */ - uint8_t data[1]; /**< Attribute data, variable length. */ -} ble_gattc_evt_hvx_t; - -/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ -typedef struct -{ - uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ -} ble_gattc_evt_timeout_t; - -/**@brief GATTC event type. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which event occured. */ - uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ - uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */ - union - { - ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */ - ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */ - ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */ - ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */ - ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */ - ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */ - ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */ - ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ - ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ - ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ - } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ -} ble_gattc_evt_t; -/** @} */ - -/** @addtogroup BLE_GATTC_FUNCTIONS Functions - * @{ */ - -/**@brief Initiate or continue a GATT Primary Service Discovery procedure. - * - * @details This function initiates a Primary Service discovery, starting from the supplied handle. - * If the last service has not been reached, this must be called again with an updated start handle value to continue the search. - * - * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with - * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] start_handle Handle to start searching from. - * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid)); - - -/**@brief Initiate or continue a GATT Relationship Discovery procedure. - * - * @details This function initiates the Find Included Services sub-procedure. If the last included service has not been reached, - * this must be called again with an updated handle range to continue the search. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Characteristic Discovery procedure. - * - * @details This function initiates a Characteristic discovery procedure. If the last Characteristic has not been reached, - * this must be called again with an updated handle range to continue the discovery. - * - * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with - * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure. - * - * @details This function initiates the Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached, - * this must be called again with an updated handle range to continue the discovery. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure. - * - * @details This function initiates the Read using Characteristic UUID procedure. If the last Characteristic has not been reached, - * this must be called again with an updated handle range to continue the discovery. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_uuid Pointer to a Characteristic value UUID to read. - * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range)); - - -/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure. - * - * @details This function initiates a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor - * to be read is longer than GATT_MTU - 1, this function must be called multiple times with appropriate offset to read the - * complete value. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] handle The handle of the attribute to be read. - * @param[in] offset Offset into the attribute value to be read. - * - * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); - - -/**@brief Initiate a GATT Read Multiple Characteristic Values procedure. - * - * @details This function initiates a GATT Read Multiple Characteristic Values procedure. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. - * @param[in] handle_count The number of handles in p_handles. - * - * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY Client procedure already in progress. - */ -SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count)); - - -/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure. - * - * @details This function can perform all write procedures described in GATT. - * - * @note It is important to note that a write without response will consume an application buffer, and will therefore - * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. A write on the other hand will use the - * standard client internal buffer and thus will only generate a @ref BLE_GATTC_EVT_WRITE_RSP event as soon as the write response - * has been received from the peer. Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] p_write_params A pointer to a write parameters structure. - * - * @retval ::NRF_SUCCESS Successfully started the Write procedure. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - * @retval ::NRF_ERROR_BUSY Procedure already in progress. - * @retval ::BLE_ERROR_NO_TX_BUFFERS There are no available buffers left. - */ -SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); - - -/**@brief Send a Handle Value Confirmation to the GATT Server. - * - * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. - * @param[in] handle The handle of the attribute in the indication. - * - * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed. - * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle. - */ -SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); - -/** @} */ - -#endif /* BLE_GATTC_H__ */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s120/headers/ble_gatts.h b/components/softdevice/s120/headers/ble_gatts.h deleted file mode 100644 index 648ec7f..0000000 --- a/components/softdevice/s120/headers/ble_gatts.h +++ /dev/null @@ -1,615 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server - @{ - @brief Definitions and prototypes for the GATTS interface. - */ - -#ifndef BLE_GATTS_H__ -#define BLE_GATTS_H__ - -#include "ble_types.h" -#include "ble_ranges.h" -#include "ble_l2cap.h" -#include "ble_gap.h" -#include "ble_gatt.h" -#include "nrf_svc.h" - -/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations - * @{ */ - -/** - * @brief GATTS API SVC numbers. - */ -enum BLE_GATTS_SVCS -{ - SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */ - SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */ - SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */ - SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */ - SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */ - SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */ - SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */ - SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */ - SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ - SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ - SD_BLE_GATTS_SYS_ATTR_GET, /**< Get updated persistent system attributes after terminating a connection. */ -}; - -/** - * @brief GATT Server Event IDs. - */ -enum BLE_GATTS_EVTS -{ - BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. */ - BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. */ - BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending, awaiting a sd_ble_gatts_sys_attr_set(). */ - BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. */ - BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. */ - BLE_GATTS_EVT_TIMEOUT /**< Timeout. */ -}; -/** @} */ - -/** @addtogroup BLE_GATTS_DEFINES Defines - * @{ */ - -/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS - * @{ */ -#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */ -#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */ -/** @} */ - -/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths - * @{ */ -#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */ -#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */ -/** @} */ - -/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types - * @{ */ -#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */ -#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */ -#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */ -/** @} */ - - -/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types - * @{ */ -#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */ -#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */ -#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */ -#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */ -#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */ -#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */ -#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */ -#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */ -/** @} */ - - -/** @defgroup BLE_GATTS_OPS GATT Server Operations - * @{ */ -#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */ -#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */ -#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */ -#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ -#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ -#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */ -#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */ -/** @} */ - -/** @defgroup BLE_GATTS_VLOCS GATT Value Locations - * @{ */ -#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */ -#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */ -#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack - will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */ -/** @} */ - -/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types - * @{ */ -#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */ -#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */ -#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */ -/** @} */ - -/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags - * @{ */ -#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */ -#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */ -/** @} */ - - -/** @} */ - -/** @addtogroup BLE_GATTS_STRUCTURES Structures - * @{ */ - -/** - * @brief BLE GATTS init options - */ -typedef struct -{ - uint8_t service_changed:1; /**< Include the Service Changed characteristic in the local attributes. */ -} ble_gatts_enable_params_t; - -/**@brief Attribute metadata. */ -typedef struct -{ - ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */ - ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ - uint8_t vlen :1; /**< Variable length attribute. */ - uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ - uint8_t rd_auth :1; /**< Read Authorization and value will be requested from the application on every read operation. */ - uint8_t wr_auth :1; /**< Write Authorization will be requested from the application on every Write Request operation (but not Write Command). */ -} ble_gatts_attr_md_t; - - -/**@brief GATT Attribute. */ -typedef struct -{ - ble_uuid_t *p_uuid; /**< Pointer to the attribute UUID. */ - ble_gatts_attr_md_t *p_attr_md; /**< Pointer to the attribute metadata structure. */ - uint16_t init_len; /**< Initial attribute value length in bytes. */ - uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */ - uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ - uint8_t* p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer - that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. - The stack may access that memory directly without the application's knowledge. For writable characteristics, this value should not be a location in flash memory.*/ -} ble_gatts_attr_t; - -/**@brief GATT Attribute Value. */ -typedef struct -{ - uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/ - uint16_t offset; /**< Attribute value offset. */ - uint8_t* p_value; /**< Pointer to where value is stored or will be stored. - If value is stored in user memory, only the attribute length is updated when p_value == NULL. - Set to NULL when reading to obtain the complete length of the attribute value*/ -} ble_gatts_value_t; - - -/**@brief GATT Attribute Context. */ -typedef struct -{ - ble_uuid_t srvc_uuid; /**< Service UUID. */ - ble_uuid_t char_uuid; /**< Characteristic UUID if applicable (BLE_UUID_TYPE_UNKNOWN if N/A). */ - ble_uuid_t desc_uuid; /**< Descriptor UUID if applicable (BLE_UUID_TYPE_UNKNOWN if N/A). */ - uint16_t srvc_handle; /**< Service Handle. */ - uint16_t value_handle; /**< Characteristic Handle if applicable (BLE_GATT_HANDLE_INVALID if N/A). */ - uint8_t type; /**< Attribute Type, see @ref BLE_GATTS_ATTR_TYPES. */ -} ble_gatts_attr_context_t; - - -/**@brief GATT Characteristic Presentation Format. */ -typedef struct -{ - uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */ - int8_t exponent; /**< Exponent for integer data types. */ - uint16_t unit; /**< UUID from Bluetooth Assigned Numbers. */ - uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ - uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */ -} ble_gatts_char_pf_t; - - -/**@brief GATT Characteristic metadata. */ -typedef struct -{ - ble_gatt_char_props_t char_props; /**< Characteristic Properties. */ - ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */ - uint8_t *p_char_user_desc; /**< Pointer to a UTF-8, NULL if the descriptor is not required. */ - uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */ - uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ - ble_gatts_char_pf_t* p_char_pf; /**< Pointer to a presentation format structure or NULL if the descriptor is not required. */ - ble_gatts_attr_md_t* p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */ - ble_gatts_attr_md_t* p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */ - ble_gatts_attr_md_t* p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */ -} ble_gatts_char_md_t; - - -/**@brief GATT Characteristic Definition Handles. */ -typedef struct -{ - uint16_t value_handle; /**< Handle to the characteristic value. */ - uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ - uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ - uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */ -} ble_gatts_char_handles_t; - - -/**@brief GATT HVx parameters. */ -typedef struct -{ - uint16_t handle; /**< Characteristic Value Handle. */ - uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ - uint16_t offset; /**< Offset within the attribute value. */ - uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after successful return. */ - uint8_t *p_data; /**< Actual data content, use NULL to use the current attribute value. */ -} ble_gatts_hvx_params_t; - -/**@brief GATT Read Authorization parameters. */ -typedef struct -{ - uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ - uint8_t update : 1; /**< If set, data supplied in p_data will be used in the ATT response. */ - uint16_t offset; /**< Offset of the attribute value being updated. */ - uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ - uint8_t *p_data; /**< Pointer to new value used to update the attribute value. */ -} ble_gatts_read_authorize_params_t; - -/**@brief GATT Write Authorisation parameters. */ -typedef struct -{ - uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ -} ble_gatts_write_authorize_params_t; - -/**@brief GATT Read or Write Authorize Reply parameters. */ -typedef struct -{ - uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ - union { - ble_gatts_read_authorize_params_t read; /**< Read authorization parameters. */ - ble_gatts_write_authorize_params_t write; /**< Write authorization parameters. */ - } params; /**< Reply Parameters. */ -} ble_gatts_rw_authorize_reply_params_t; - - - -/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ - ble_gatts_attr_context_t context; /**< Attribute Context. */ - uint16_t offset; /**< Offset for the write operation. */ - uint16_t len; /**< Length of the incoming data. */ - uint8_t data[1]; /**< Incoming data, variable length. */ -} ble_gatts_evt_write_t; - -/**@brief Event structure for authorize read request. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ - ble_gatts_attr_context_t context; /**< Attribute Context. */ - uint16_t offset; /**< Offset for the read operation. */ -} ble_gatts_evt_read_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */ -typedef struct -{ - uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ - union { - ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */ - ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */ - } request; /**< Request Parameters. */ -} ble_gatts_evt_rw_authorize_request_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */ -typedef struct -{ - uint8_t hint; /**< Hint (TBD). */ -} ble_gatts_evt_sys_attr_missing_t; - - -/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */ -typedef struct -{ - uint16_t handle; /**< Attribute Handle. */ -} ble_gatts_evt_hvc_t; - -/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */ -typedef struct -{ - uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */ -} ble_gatts_evt_timeout_t; - - -/**@brief GATT Server event callback event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which event occurred. */ - union - { - ble_gatts_evt_write_t write; /**< Write Event Parameters. */ - ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ - ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ - ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ - ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ - } params; /**< Event Parameters. */ -} ble_gatts_evt_t; - -/** @} */ - -/** @addtogroup BLE_GATTS_FUNCTIONS Functions - * @{ */ - -/**@brief Add a service declaration to the local server ATT table. - * - * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. - * @param[in] p_uuid Pointer to service UUID. - * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. - * - * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to - * add a secondary service declaration that is not referenced by another service later in the ATT table. - * - * @retval ::NRF_SUCCESS Successfully added a service declaration. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - */ -SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle)); - - -/**@brief Add an include declaration to the local server ATT table. - * - * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential addition is supported at this time). - * - * @note The included service must already be present in the ATT table prior to this call. - * - * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. - * @param[in] inc_srvc_handle Handle of the included service. - * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. - * - * @retval ::NRF_SUCCESS Successfully added an include declaration. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - */ -SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle)); - - -/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the local server ATT table. - * - * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential addition is supported at this time). - * - * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writeable auxiliaries bits, - * readable (no security) and writeable (selectable) CCCDs and SCCDs and valid presentation format values. - * - * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions. - * - * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. - * @param[in] p_char_md Characteristic metadata. - * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. - * @param[out] p_handles Pointer to the structure where the assigned handles will be stored. - * - * @retval ::NRF_SUCCESS Successfully added a characteristic. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. - */ -SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles)); - - -/**@brief Add a descriptor to the local server ATT table. - * - * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential addition is supported at this time). - * - * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. - * @param[in] p_attr Pointer to the attribute structure. - * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. - * - * @retval ::NRF_SUCCESS Successfully added a descriptor. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. - */ -SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); - -/**@brief Set the value of a given attribute. - * - * @param[in] conn_handle Connection handle. If there is no connection (and value is not a CCCD), then @ref BLE_CONN_HANDLE_INVALID can be used. - * @param[in] handle Attribute handle. - * @param[in,out] p_value Attribute value information. - * - * @retval ::NRF_SUCCESS Successfully set the value of the attribute. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX. - */ -SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); - -/**@brief Get the value of a given attribute. - * - * @param[in] conn_handle Connection handle. If there is no connection (and value is not a CCCD), then @ref BLE_CONN_HANDLE_INVALID can be used. - * @param[in] handle Attribute handle. - * @param[in,out] p_value Attribute value information. - * - * @note If the attribute value is longer than the size of the supplied buffer, - * p_len will return the total attribute value length (excluding offset), - * and not the number of bytes actually returned in p_data. - * The application may use this information to allocate a suitable buffer size. - * - * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - */ -SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); - -/**@brief Notify or Indicate an attribute value. - * - * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation - * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that - * the application can atomically perform a value update and a server initiated transaction with a single API call. - * If the application chooses to indicate an attribute value, a @ref BLE_GATTS_EVT_HVC will be sent up as soon as the confirmation arrives from - * the peer. - * - * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. - * When receiveing the error codes @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and - * @ref BLE_ERROR_NO_TX_BUFFERS the ATT table has been updated. - * The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len). - * - * @note It is important to note that a notification will consume an application buffer, and will therefore - * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. An indication on the other hand will use the - * standard server internal buffer and thus will only generate a @ref BLE_GATTS_EVT_HVC event as soon as the confirmation - * has been received from the peer. Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_hvx_params Pointer to an HVx parameters structure. If the p_data member contains a non-NULL pointer the attribute value will be updated with - * the contents pointed by it before sending the notification or indication. - * - * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate. - * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated. - * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. - * @retval ::NRF_ERROR_BUSY Procedure already in progress. - * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. - * @retval ::BLE_ERROR_NO_TX_BUFFERS There are no available buffers to send the data, applies only to notifications. - */ -SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); - -/**@brief Indicate the Service Changed attribute value. - * - * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the attribute - * table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will - * be issued. - * - * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. - * - * @param[in] conn_handle Connection handle. - * @param[in] start_handle Start of affected attribute handle range. - * @param[in] end_handle End of affected attribute handle range. - * - * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, notifications or indications must be enabled in the CCCD. - * @retval ::NRF_ERROR_BUSY Procedure already in progress. - * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. - */ -SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle)); - -/**@brief Respond to a Read/Write authorization request. - * - * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. - * - * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, ATT table updated. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. - * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, - * or for Read Authorization reply: requested handles not replied with, - * or for Write Authorization reply: handle supplied does not match requested handle. - * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time. - */ -SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); - - -/**@brief Update persistent system attribute information. - * - * @details Supply to the stack information about persistent system attributes. - * This call is legal in the connected state only, and is usually - * made immediately after a connection is established and the bond identified. - * usually as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. - * - * p_sysattrs may point directly to the application's stored copy of the struct. - * If the pointer is NULL, the system attribute info is initialized, assuming that - * the application does not have any previously saved data for this bond. - * - * @note The state of persistent system attributes is reset upon connection and then remembered for its duration. - * - * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially. - * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or - * reset the SoftDevice to return to a known state. - * - * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. - * @param[in] len Size of data pointed by p_sys_attr_data, in octets. - * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS - * - * @retval ::NRF_SUCCESS Successfully set the system attribute information. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time. - */ -SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); - - -/**@brief Retrieve persistent system attribute information from the stack. - * - * @details This call is used to retrieve information about values to be stored perisistently by the application - * after a connection has been terminated. When a new connection is made to the same bond, the values - * should be restored using @ref sd_ble_gatts_sys_attr_set. - * The data should be read before any new advertising is started, or any new connection established. The connection handle for - * the previous now defunct connection will remain valid until a new one is created to allow this API call to refer to it. - * - * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned. - * - * @param[in] conn_handle Connection handle of the recently terminated connection. - * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. NULL can be provided to - * obtain the length of the data - * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditially updated to actual length of system attribute data. - * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS - * - * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. - */ -SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); - -/** @} */ - -#endif // BLE_GATTS_H__ - -/** - @} -*/ diff --git a/components/softdevice/s120/headers/ble_hci.h b/components/softdevice/s120/headers/ble_hci.h deleted file mode 100644 index 2488985..0000000 --- a/components/softdevice/s120/headers/ble_hci.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_COMMON - @{ -*/ - - -#ifndef BLE_HCI_H__ -#define BLE_HCI_H__ - -/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes - * @{ */ - -#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */ -#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */ -#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */ -/*0x03 Hardware Failure -0x04 Page Timeout -*/ -#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */ -#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */ -#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */ -#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */ -/*0x09 Connection Limit Exceeded -0x0A Synchronous Connection Limit To A Device Exceeded -0x0B ACL Connection Already Exists*/ -#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */ -/*0x0D Connection Rejected due to Limited Resources -0x0E Connection Rejected Due To Security Reasons -0x0F Connection Rejected due to Unacceptable BD_ADDR -0x10 Connection Accept Timeout Exceeded -0x11 Unsupported Feature or Parameter Value*/ -#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */ -#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */ -#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/ -#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */ -#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */ -/* -0x17 Repeated Attempts -0x18 Pairing Not Allowed -0x19 Unknown LMP PDU -*/ -#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */ -/* -0x1B SCO Offset Rejected -0x1C SCO Interval Rejected -0x1D SCO Air Mode Rejected*/ -#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */ -#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */ -/*0x20 Unsupported LMP Parameter Value -0x21 Role Change Not Allowed -*/ -#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */ -/*0x23 LMP Error Transaction Collision*/ -#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */ -/*0x25 Encryption Mode Not Acceptable -0x26 Link Key Can Not be Changed -0x27 Requested QoS Not Supported -*/ -#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */ -#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */ -#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */ -/* -0x2B Reserved -0x2C QoS Unacceptable Parameter -0x2D QoS Rejected -0x2E Channel Classification Not Supported -0x2F Insufficient Security -0x30 Parameter Out Of Mandatory Range -0x31 Reserved -0x32 Role Switch Pending -0x33 Reserved -0x34 Reserved Slot Violation -0x35 Role Switch Failed -0x36 Extended Inquiry Response Too Large -0x37 Secure Simple Pairing Not Supported By Host. -0x38 Host Busy - Pairing -0x39 Connection Rejected due to No Suitable Channel Found*/ -#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */ -#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */ -#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Adverisement Timeout. */ -#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */ -#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */ - -/** @} */ - - -#endif // BLE_HCI_H__ - -/** @} */ diff --git a/components/softdevice/s120/headers/ble_l2cap.h b/components/softdevice/s120/headers/ble_l2cap.h deleted file mode 100644 index 6eab9fb..0000000 --- a/components/softdevice/s120/headers/ble_l2cap.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP) - @{ - @brief Definitions and prototypes for the L2CAP interface. - */ - -#ifndef BLE_L2CAP_H__ -#define BLE_L2CAP_H__ - -#include "ble_types.h" -#include "ble_ranges.h" -#include "ble_err.h" -#include "nrf_svc.h" - -/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations - * @{ */ - -/**@brief L2CAP API SVC numbers. */ -enum BLE_L2CAP_SVCS -{ - SD_BLE_L2CAP_CID_REGISTER = BLE_L2CAP_SVC_BASE, /**< Register a CID. */ - SD_BLE_L2CAP_CID_UNREGISTER, /**< Unregister a CID. */ - SD_BLE_L2CAP_TX /**< Transmit a packet. */ -}; - -/**@brief L2CAP Event IDs. */ -enum BLE_L2CAP_EVTS -{ - BLE_L2CAP_EVT_RX = BLE_L2CAP_EVT_BASE /**< L2CAP packet received. */ -}; - -/** @} */ - -/**@addtogroup BLE_L2CAP_DEFINES Defines - * @{ */ - -/**@defgroup BLE_ERRORS_L2CAP SVC return values specific to L2CAP - * @{ */ -#define BLE_ERROR_L2CAP_CID_IN_USE (NRF_L2CAP_ERR_BASE + 0x000) /**< CID already in use. */ -/** @} */ - -/**@brief Default L2CAP MTU. */ -#define BLE_L2CAP_MTU_DEF (23) - -/**@brief Invalid Channel Identifier. */ -#define BLE_L2CAP_CID_INVALID (0x0000) - -/**@brief Dynamic Channel Identifier base. */ -#define BLE_L2CAP_CID_DYN_BASE (0x0040) - -/**@brief Maximum amount of dynamic CIDs. */ -#define BLE_L2CAP_CID_DYN_MAX (8) - -/** @} */ - -/**@addtogroup BLE_L2CAP_STRUCTURES Structures - * @{ */ - -/**@brief Packet header format for L2CAP transmission. */ -typedef struct -{ - uint16_t len; /**< Length of valid info in data member. */ - uint16_t cid; /**< Channel ID on which packet is transmitted. */ -} ble_l2cap_header_t; - - -/**@brief L2CAP Received packet event report. */ -typedef struct -{ - ble_l2cap_header_t header; /**< L2CAP packet header. */ - uint8_t data[1]; /**< Packet data, variable length. */ -} ble_l2cap_evt_rx_t; - - -/**@brief L2CAP event callback event structure. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which event occured. */ - union - { - ble_l2cap_evt_rx_t rx; /**< RX Event parameters. */ - } params; /**< Event Parameters. */ -} ble_l2cap_evt_t; - -/** @} */ - -/**@addtogroup BLE_L2CAP_FUNCTIONS Functions - * @{ */ - -/**@brief Register a CID with L2CAP. - * - * @details This registers a higher protocol layer with the L2CAP multiplexer, and is requried prior to all operations on the CID. - * - * @param[in] cid L2CAP CID. - * - * @retval ::NRF_SUCCESS Successfully registered a CID with the L2CAP layer. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CID must be above @ref BLE_L2CAP_CID_DYN_BASE. - * @retval ::BLE_ERROR_L2CAP_CID_IN_USE L2CAP CID already in use. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - */ -SVCALL(SD_BLE_L2CAP_CID_REGISTER, uint32_t, sd_ble_l2cap_cid_register(uint16_t cid)); - -/**@brief Unregister a CID with L2CAP. - * - * @details This unregisters a previously registerd higher protocol layer with the L2CAP multiplexer. - * - * @param[in] cid L2CAP CID. - * - * @retval ::NRF_SUCCESS Successfully unregistered the CID. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_NOT_FOUND CID not previously registered. - */ -SVCALL(SD_BLE_L2CAP_CID_UNREGISTER, uint32_t, sd_ble_l2cap_cid_unregister(uint16_t cid)); - -/**@brief Transmit an L2CAP packet. - * - * @note It is important to note that a call to this function will consume an application buffer, and will therefore - * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. - * Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. - * - * @param[in] conn_handle Connection Handle. - * @param[in] p_header Pointer to a packet header containing length and CID. - * @param[in] p_data Pointer to the data to be transmitted. - * - * @retval ::NRF_SUCCESS Successfully queued an L2CAP packet for transmission. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register. - * @retval ::NRF_ERROR_NOT_FOUND CID not found. - * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::BLE_ERROR_NO_TX_BUFFERS Not enough application buffers available. - * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF. - */ -SVCALL(SD_BLE_L2CAP_TX, uint32_t, sd_ble_l2cap_tx(uint16_t conn_handle, ble_l2cap_header_t const *p_header, uint8_t const *p_data)); - -/** @} */ - -#endif // BLE_L2CAP_H__ - -/** - @} -*/ diff --git a/components/softdevice/s120/headers/nrf_error_sdm.h b/components/softdevice/s120/headers/nrf_error_sdm.h deleted file mode 100644 index 25a1437..0000000 --- a/components/softdevice/s120/headers/nrf_error_sdm.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - /** - @addtogroup nrf_sdm_api - @{ - @defgroup nrf_sdm_error SoftDevice Manager Error Codes - @{ - - @brief Error definitions for the SDM API -*/ - -/* Header guard */ -#ifndef NRF_ERROR_SDM_H__ -#define NRF_ERROR_SDM_H__ - -#include "nrf_error.h" - -#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown lfclk source. -#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). -#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erronous SoftDevice flashing). - -#endif // NRF_ERROR_SDM_H__ - -/** - @} - @} -*/ diff --git a/components/softdevice/s120/headers/nrf_error_soc.h b/components/softdevice/s120/headers/nrf_error_soc.h deleted file mode 100644 index cfddf7e..0000000 --- a/components/softdevice/s120/headers/nrf_error_soc.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - @addtogroup nrf_soc_api - @{ - @defgroup nrf_soc_error SoC Library Error Codes - @{ - - @brief Error definitions for the SoC library - -*/ - -/* Header guard */ -#ifndef NRF_ERROR_SOC_H__ -#define NRF_ERROR_SOC_H__ - -#include "nrf_error.h" - -/* Mutex Errors */ -#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken - -/* NVIC errors */ -#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available -#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed -#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return - -/* Power errors */ -#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown -#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown -#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return - -/* Rand errors */ -#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values - -/* PPI errors */ -#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel -#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group - -#endif // NRF_ERROR_SOC_H__ -/** - @} - @} -*/ diff --git a/components/softdevice/s120/headers/nrf_mbr.h b/components/softdevice/s120/headers/nrf_mbr.h deleted file mode 100644 index 6ffde6a..0000000 --- a/components/softdevice/s120/headers/nrf_mbr.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - @defgroup nrf_mbr_api Master Boot Record API - @{ - - @brief APIs for updating SoftDevice and BootLoader - -*/ - -/* Header guard */ -#ifndef NRF_MBR_H__ -#define NRF_MBR_H__ - -#include "nrf_svc.h" -#include - - -/** @addtogroup NRF_MBR_DEFINES Defines - * @{ */ - -/**@brief MBR SVC Base number. */ -#define MBR_SVC_BASE 0x18 - -/**@brief Page size in words. */ -#define PAGE_SIZE_IN_WORDS 256 -/** @} */ - -/** @addtogroup NRF_MBR_ENUMS Enumerations - * @{ */ - -/**@brief nRF Master Boot Record API SVC numbers. */ -enum NRF_MBR_SVCS -{ - SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */ -}; - -/**@brief Possible values for ::sd_mbr_command_t.command */ -enum NRF_MBR_COMMANDS -{ - SD_MBR_COMMAND_COPY_BL, /**< Copy a new a new BootLoader. @see sd_mbr_command_copy_bl_t */ - SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ - SD_MBR_COMMAND_INIT_SD, /**< Init forwarding interrupts to SD, and run reset function in SD*/ - SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ - SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Start forwarding all exception to this address @see ::sd_mbr_command_vector_table_base_set_t*/ -}; - -/** @} */ - -/** @addtogroup NRF_MBR_TYPES Types - * @{ */ - -/**@brief This command copies part of a new SoftDevice - * The destination area is erased before copying. - * If dst is in the middle of a flash page, that whole flash page will be erased. - * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. - * - * The user of this function is responsible for setting the PROTENSET registers. - * - * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. - * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. - */ -typedef struct -{ - uint32_t *src; /**< Pointer to the source of data to be copied.*/ - uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ - uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of 256 words.*/ -}sd_mbr_command_copy_sd_t; - - -/**@brief This command works like memcmp, but takes the length in words. - * - * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal. - * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal. - */ -typedef struct -{ - uint32_t *ptr1; /**< Pointer to block of memory. */ - uint32_t *ptr2; /**< Pointer to block of memory. */ - uint32_t len; /**< Number of 32 bit words to compare.*/ -}sd_mbr_command_compare_t; - - -/**@brief This command copies a new BootLoader. - * With this command, destination of BootLoader is always the address written in NRF_UICR->BOOTADDR. - * - * Destination is erased by this function. - * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased. - * - * This function will use PROTENSET to protect the flash that is not intended to be written. - * - * On Success, this function will not return. It will start the new BootLoader from reset-vector as normal. - * - * @retval ::NRF_ERROR_INVALID_STATE indicates that something was wrong. - * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. - * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. - * @retval ::NRF_ERROR_INVALID_LENGTH is invalid. - */ -typedef struct -{ - uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/ - uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */ -}sd_mbr_command_copy_bl_t; - -/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR - * - * Once this function has been called, this address is where the MBR will start to forward interrupts to after a reset. - * - * To restore default forwarding thiss function should be called with @param address set to 0. - * The MBR will then start forwarding to interrupts to the adress in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set. - * - * @retval ::NRF_SUCCESS - */ -typedef struct -{ - uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ -}sd_mbr_command_vector_table_base_set_t; - -typedef struct -{ - uint32_t command; /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */ - union - { - sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy.*/ - sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy SoftDevice and BootLoader.*/ - sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ - sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set.*/ - } params; -}sd_mbr_command_t; - -/** @} */ - -/** @addtogroup NRF_MBR_FUNCTIONS Functions - * @{ */ - -/**@brief Issue Master Boot Record commands - * - * Commands used when updating a SoftDevice and bootloader. - * - * @param[in] param Pointer to a struct describing the command. - * - *@note for retvals see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t - -*/ -SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); - -/** @} */ -#endif // NRF_MBR_H__ - -/** - @} -*/ diff --git a/components/softdevice/s120/headers/nrf_sd_def.h b/components/softdevice/s120/headers/nrf_sd_def.h deleted file mode 100644 index 4740cd8..0000000 --- a/components/softdevice/s120/headers/nrf_sd_def.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_SD_DEF_H__ -#define NRF_SD_DEF_H__ - -#include - -#define SD_PPI_CHANNELS_USED 0xFFF0C000uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */ -#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ -#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ -#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ - -#endif /* NRF_SD_DEF_H__ */ diff --git a/components/softdevice/s120/headers/nrf_sdm.h b/components/softdevice/s120/headers/nrf_sdm.h deleted file mode 100644 index 703eddf..0000000 --- a/components/softdevice/s120/headers/nrf_sdm.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - @defgroup nrf_sdm_api SoftDevice Manager API - @{ - - @brief APIs for SoftDevice management. - -*/ - -/* Header guard */ -#ifndef NRF_SDM_H__ -#define NRF_SDM_H__ - -#include "nrf_svc.h" -#include "nrf51.h" -#include "nrf_soc.h" -#include "nrf_error_sdm.h" - -/** @addtogroup NRF_SDM_DEFINES Defines - * @{ */ - -/** @brief SoftDevice Manager SVC Base number. */ -#define SDM_SVC_BASE 0x10 - -/** @} */ - -/** @brief Defines the SoftDevice Information Structure location (address) as an offset from -the start of the softdevice (without MBR)*/ -#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) - -/** @brief Defines the usual size reserverd for the MBR when a softdevice is written to flash. -This is the offset where the first byte of the softdevice hex file is written.*/ -#define MBR_SIZE (0x1000) - -/** @brief Defines the absolute Softdevice information structure location (address)*/ -#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) - -/** @brief Defines the offset for Softdevice size value relative to Softdevice base address*/ -#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) - -/** @brief Defines the offset for FWID value relative to Softdevice base address*/ -#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) - -/** @brief Defines a macro for retreiving the actual Softdevice size value from a given base address - use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/ -#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) - -/** @brief Defines a macro for retreiving the actual FWID value from a given base address - use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/ -#define SD_FWID_GET(baseaddr) ((*((uint32_t *) ((baseaddr) + SD_FWID_OFFSET))) & 0xFFFF) - - -/** @addtogroup NRF_SDM_ENUMS Enumerations - * @{ */ - -/**@brief nRF SoftDevice Manager API SVC numbers. */ -enum NRF_SD_SVCS -{ - SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ - SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ - SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ - SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ - SVC_SDM_LAST /**< Placeholder for last SDM SVC */ -}; - -/**@brief Possible lfclk oscillator sources. */ -enum NRF_CLOCK_LFCLKSRCS -{ - NRF_CLOCK_LFCLKSRC_SYNTH_250_PPM, /**< LFCLK Synthesized from HFCLK. */ - NRF_CLOCK_LFCLKSRC_XTAL_500_PPM, /**< LFCLK crystal oscillator 500 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_250_PPM, /**< LFCLK crystal oscillator 250 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_150_PPM, /**< LFCLK crystal oscillator 150 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_100_PPM, /**< LFCLK crystal oscillator 100 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_75_PPM, /**< LFCLK crystal oscillator 75 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, /**< LFCLK crystal oscillator 50 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_30_PPM, /**< LFCLK crystal oscillator 30 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, /**< LFCLK crystal oscillator 20 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION, /**< LFCLK RC oscillator, 250ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_500MS_CALIBRATION, /**< LFCLK RC oscillator, 500ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_1000MS_CALIBRATION, /**< LFCLK RC oscillator, 1000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_2000MS_CALIBRATION, /**< LFCLK RC oscillator, 2000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, /**< LFCLK RC oscillator, 4000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_8000MS_CALIBRATION, /**< LFCLK RC oscillator, 8000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_1000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 1000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_2000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 2000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_4000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 4000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_8000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 8000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_16000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 16000ms, if changed above a threshold, a calibration is done.*/ -}; - -/** @} */ - -/** @addtogroup NRF_SDM_TYPES Types - * @{ */ - -/**@brief Type representing lfclk oscillator source. */ -typedef uint32_t nrf_clock_lfclksrc_t; - - -/**@brief SoftDevice Assertion Handler type. - * - * When an unexpected error occurs within the SoftDevice it will call the SoftDevice assertion handler callback. - * The protocol stack will be in an undefined state when this happens and the only way to recover will be to - * perform a reset, using e.g. CMSIS NVIC_SystemReset(). - * - * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the SoftDevice assert callback. - * - * @param[in] pc The program counter of the failed assert. - * @param[in] line_number Line number where the assert failed. - * @param[in] file_name File name where the assert failed. - */ -typedef void (*softdevice_assertion_handler_t)(uint32_t pc, uint16_t line_number, const uint8_t * p_file_name); - -/** @} */ - -/** @addtogroup NRF_SDM_FUNCTIONS Functions - * @{ */ - -/**@brief Enables the SoftDevice and by extension the protocol stack. - * - * Idempotent function to enable the SoftDevice. - * - * @note Some care must be taken if a low frequency clock source is already running when calling this function: - * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new - * clock source will be started. - * - * @note This function has no effect when returning with an error. - * - * @post If return code is ::NRF_SUCCESS - * - SoC library and protocol stack APIs are made available. - * - A portion of RAM will be unavailable (see relevant SDS documentation). - * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). - * - Interrupts will not arrive from protected peripherals or interrupts. - * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the softdevice. - * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). - * - Chosen low frequency clock source will be running. - * - * @param clock_source Low frequency clock source and accuracy. (Note: In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock). - * @param assertion_handler Callback for SoftDevice assertions. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and assertion handler cannot be updated. - * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDeviceinterrupt is already enabled, or an enabled interrupt has an illegal priority level. - * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. - */ -SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lfclksrc_t clock_source, softdevice_assertion_handler_t assertion_handler)); - -/**@brief Disables the SoftDevice and by extension the protocol stack. - * - * Idempotent function to disable the SoftDevice. - * - * @post SoC library and protocol stack APIs are made unavailable. - * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). - * @post All peripherals used by the SoftDevice will be reset to default values. - * @post All of RAM become available. - * @post All interrupts are forwarded to the application. - * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); - -/**@brief Check if the SoftDevice is enabled. - * - * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); - -/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice - * - * This function is only intended to be called when a bootloader is enabled. - * - * @param[in] address The base address of the interrupt vector table for forwarded interrupts. - - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); - -/** @} */ - -#endif // NRF_SDM_H__ - -/** - @} -*/ diff --git a/components/softdevice/s120/headers/nrf_soc.h b/components/softdevice/s120/headers/nrf_soc.h deleted file mode 100644 index 1d2defe..0000000 --- a/components/softdevice/s120/headers/nrf_soc.h +++ /dev/null @@ -1,993 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - * @defgroup nrf_soc_api SoC Library API - * @{ - * - * @brief APIs for the SoC library. - * - */ - -#ifndef NRF_SOC_H__ -#define NRF_SOC_H__ - -#include -#include -#include "nrf_svc.h" -#include "nrf51.h" -#include "nrf51_bitfields.h" -#include "nrf_error_soc.h" - -/**@addtogroup NRF_SOC_DEFINES Defines - * @{ */ - -/**@brief The number of the lowest SVC number reserved for the SoC library. */ -#define SOC_SVC_BASE (0x20) -#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) - -/**@brief Guranteed time for application to process radio inactive notification. */ -#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) - -/**@brief The minimum allowed timeslot extension time. */ -#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200) - -#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */ -#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ -#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ - -#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ -#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */ -#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ -#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. */ - -#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ -#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ - -#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */ - -#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */ - -#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */ - -/**@} */ - -/**@addtogroup NRF_SOC_TYPES Types - * @{ */ - -/**@brief The SVC numbers used by the SVC functions in the SoC library. */ -enum NRF_SOC_SVCS -{ - SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE, - SD_PPI_CHANNEL_ENABLE_SET, - SD_PPI_CHANNEL_ENABLE_CLR, - SD_PPI_CHANNEL_ASSIGN, - SD_PPI_GROUP_TASK_ENABLE, - SD_PPI_GROUP_TASK_DISABLE, - SD_PPI_GROUP_ASSIGN, - SD_PPI_GROUP_GET, - SD_FLASH_PAGE_ERASE, - SD_FLASH_WRITE, - SD_FLASH_PROTECT, - SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, - SD_MUTEX_ACQUIRE, - SD_MUTEX_RELEASE, - SD_NVIC_ENABLEIRQ, - SD_NVIC_DISABLEIRQ, - SD_NVIC_GETPENDINGIRQ, - SD_NVIC_SETPENDINGIRQ, - SD_NVIC_CLEARPENDINGIRQ, - SD_NVIC_SETPRIORITY, - SD_NVIC_GETPRIORITY, - SD_NVIC_SYSTEMRESET, - SD_NVIC_CRITICAL_REGION_ENTER, - SD_NVIC_CRITICAL_REGION_EXIT, - SD_RAND_APPLICATION_POOL_CAPACITY, - SD_RAND_APPLICATION_BYTES_AVAILABLE, - SD_RAND_APPLICATION_GET_VECTOR, - SD_POWER_MODE_SET, - SD_POWER_SYSTEM_OFF, - SD_POWER_RESET_REASON_GET, - SD_POWER_RESET_REASON_CLR, - SD_POWER_POF_ENABLE, - SD_POWER_POF_THRESHOLD_SET, - SD_POWER_RAMON_SET, - SD_POWER_RAMON_CLR, - SD_POWER_RAMON_GET, - SD_POWER_GPREGRET_SET, - SD_POWER_GPREGRET_CLR, - SD_POWER_GPREGRET_GET, - SD_POWER_DCDC_MODE_SET, - SD_APP_EVT_WAIT, - SD_CLOCK_HFCLK_REQUEST, - SD_CLOCK_HFCLK_RELEASE, - SD_CLOCK_HFCLK_IS_RUNNING, - SD_RADIO_NOTIFICATION_CFG_SET, - SD_ECB_BLOCK_ENCRYPT, - SD_RADIO_SESSION_OPEN, - SD_RADIO_SESSION_CLOSE, - SD_RADIO_REQUEST, - SD_EVT_GET, - SD_TEMP_GET, - SVC_SOC_LAST -}; - -/**@brief Possible values of a ::nrf_mutex_t. */ -enum NRF_MUTEX_VALUES -{ - NRF_MUTEX_FREE, - NRF_MUTEX_TAKEN -}; - -/**@brief Possible values of ::nrf_app_irq_priority_t. */ -enum NRF_APP_PRIORITIES -{ - NRF_APP_PRIORITY_HIGH = 1, - NRF_APP_PRIORITY_LOW = 3 -}; - -/**@brief Possible values of ::nrf_power_mode_t. */ -enum NRF_POWER_MODES -{ - NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ - NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ -}; - - -/**@brief Possible values of ::nrf_power_failure_threshold_t */ -enum NRF_POWER_THRESHOLDS -{ - NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V27 /**< 2.7 Volts power failure threshold. */ -}; - - -/**@brief Possible values of ::nrf_power_dcdc_mode_t. */ -enum NRF_POWER_DCDC_MODES -{ - NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ - NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ -}; - -/**@brief Possible values of ::nrf_radio_notification_distance_t. */ -enum NRF_RADIO_NOTIFICATION_DISTANCES -{ - NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ - NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */ -}; - - -/**@brief Possible values of ::nrf_radio_notification_type_t. */ -enum NRF_RADIO_NOTIFICATION_TYPES -{ - NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ -}; - -/**@brief SoC Events. */ -enum NRF_SOC_EVTS -{ - NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ - NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ - NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ - NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ - NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ - NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ - NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio signal callback handler return was invalid. */ - NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio session is idle. */ - NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio session is closed. */ - NRF_EVT_NUMBER_OF_EVTS -}; - -/**@} */ - -/**@addtogroup NRF_SOC_TYPES Types - * @{ */ - -/**@brief Represents a mutex for use with the nrf_mutex functions. - * @note Accessing the value directly is not safe, use the mutex functions! - */ -typedef volatile uint8_t nrf_mutex_t; - -/**@brief The interrupt priorities available to the application while the softdevice is active. */ -typedef uint8_t nrf_app_irq_priority_t; - -/**@brief Represents a power mode, used in power mode functions */ -typedef uint8_t nrf_power_mode_t; - -/**@brief Represents a power failure threshold value. */ -typedef uint8_t nrf_power_failure_threshold_t; - -/**@brief Represents a DCDC mode value. */ -typedef uint32_t nrf_power_dcdc_mode_t; - -/**@brief Radio notification distances. */ -typedef uint8_t nrf_radio_notification_distance_t; - -/**@brief Radio notification types. */ -typedef uint8_t nrf_radio_notification_type_t; - -/**@brief The Radio signal callback types. */ -enum NRF_RADIO_CALLBACK_SIGNAL_TYPE -{ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */ -}; - -/**@brief The actions requested by the signal callback. - * - * This code gives the SOC instructions about what action to take when the signal callback has - * returned. - */ -enum NRF_RADIO_SIGNAL_CALLBACK_ACTION -{ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current timeslot (maximum execution time for this action is when the extension succeeded). */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ -}; - -/**@brief Radio timeslot high frequency clock source configuration. */ -enum NRF_RADIO_HFCLK_CFG -{ - NRF_RADIO_HFCLK_CFG_DEFAULT, /**< Use the currently selected oscillator as HF clock source during the timeslot (i.e. the source is not specified). */ - NRF_RADIO_HFCLK_CFG_FORCE_XTAL, /**< Force external crystal to be used as HF clock source during whole the timeslot. */ -}; - -/**@brief Radio timeslot priorities. */ -enum NRF_RADIO_PRIORITY -{ - NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */ - NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activites of the SoftDevice stack(s)). */ -}; - -/**@brief Radio timeslot request type. */ -enum NRF_RADIO_REQUEST_TYPE -{ - NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request timeslot as early as possible. This should always be used for the first request in a session. */ - NRF_RADIO_REQ_TYPE_NORMAL /**< Normal timeslot request. */ -}; - -/**@brief Parameters for a request for a timeslot as early as possible. */ -typedef struct -{ - uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ - uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ - uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */ - uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ -} nrf_radio_request_earliest_t; - -/**@brief Parameters for a normal radio request. */ -typedef struct -{ - uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ - uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ - uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */ - uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ -} nrf_radio_request_normal_t; - -/**@brief Radio request parameters. */ -typedef struct -{ - uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ - union - { - nrf_radio_request_earliest_t earliest; /**< Parameters for a request for a timeslot as early as possible. */ - nrf_radio_request_normal_t normal; /**< Parameters for a normal radio request. */ - } params; -} nrf_radio_request_t; - -/**@brief Return parameters of the radio timeslot signal callback. */ -typedef struct -{ - uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */ - union - { - struct - { - nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */ - } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ - struct - { - uint32_t length_us; /**< Requested extension of the timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ - } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ - } params; -} nrf_radio_signal_callback_return_param_t; - -/**@brief The radio signal callback type. - * - * @note In case of invalid return parameters, the radio timeslot will automatically end - * immediately after returning from the signal callback and the - * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent. - * @note The returned struct pointer must remain valid after the signal callback - * function returns. For instance, this means that it must not point to a stack variable. - * - * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE. - * - * @return Pointer to structure containing action requested by the application. - */ -typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); - -/**@brief AES ECB data structure */ -typedef struct -{ - uint8_t key[SOC_ECB_KEY_LENGTH]; /**< Encryption key. */ - uint8_t cleartext[SOC_ECB_CLEARTEXT_LENGTH]; /**< Clear Text data. */ - uint8_t ciphertext[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Cipher Text data. */ -} nrf_ecb_hal_data_t; - -/**@} */ - -/**@addtogroup NRF_SOC_FUNCTIONS Functions - * @{ */ - -/**@brief Initialize a mutex. - * - * @param[in] p_mutex Pointer to the mutex to initialize. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex)); - -/**@brief Attempt to acquire a mutex. - * - * @param[in] p_mutex Pointer to the mutex to acquire. - * - * @retval ::NRF_SUCCESS The mutex was successfully acquired. - * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired. - */ -SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); - -/**@brief Release a mutex. - * - * @param[in] p_mutex Pointer to the mutex to release. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); - -/**@brief Enable External Interrupt. - * @note Corresponds to NVIC_EnableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was enabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. - */ -SVCALL(SD_NVIC_ENABLEIRQ, uint32_t, sd_nvic_EnableIRQ(IRQn_Type IRQn)); - -/**@brief Disable External Interrupt. - * @note Corresponds to NVIC_DisableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was disabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - */ -SVCALL(SD_NVIC_DISABLEIRQ, uint32_t, sd_nvic_DisableIRQ(IRQn_Type IRQn)); - -/**@brief Get Pending Interrupt. - * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. - * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. - * - * @retval ::NRF_SUCCESS The interrupt is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_GETPENDINGIRQ, uint32_t, sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)); - -/**@brief Set Pending Interrupt. - * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt is set pending. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_SETPENDINGIRQ, uint32_t, sd_nvic_SetPendingIRQ(IRQn_Type IRQn)); - -/**@brief Clear Pending Interrupt. - * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_CLEARPENDINGIRQ, uint32_t, sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)); - -/**@brief Set Interrupt Priority. - * @note Corresponds to NVIC_SetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * @pre Priority is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. - * @param[in] priority A valid IRQ priority for use by the application. - * - * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. - */ -SVCALL(SD_NVIC_SETPRIORITY, uint32_t, sd_nvic_SetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t priority)); - -/**@brief Get Interrupt Priority. - * @note Corresponds to NVIC_GetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. - * @param[out] p_priority Return value from NVIC_GetPriority. - * - * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. - */ -SVCALL(SD_NVIC_GETPRIORITY, uint32_t, sd_nvic_GetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t * p_priority)); - -/**@brief System Reset. - * @note Corresponds to NVIC_SystemReset in CMSIS. - * - * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN - */ -SVCALL(SD_NVIC_SYSTEMRESET, uint32_t, sd_nvic_SystemReset(void)); - -/**@brief Enters critical region. - * - * @post Application interrupts will be disabled. - * @sa sd_nvic_critical_region_exit - * - * @param[out] p_is_nested_critical_region 1: If in a nested critical region. - * 0: Otherwise. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_NVIC_CRITICAL_REGION_ENTER, uint32_t, sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)); - -/**@brief Exit critical region. - * - * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. - * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. - * - * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_NVIC_CRITICAL_REGION_EXIT, uint32_t, sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)); - -/**@brief Query the capacity of the application random pool. - * - * @param[out] p_pool_capacity The capacity of the pool. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); - -/**@brief Get number of random bytes available to the application. - * - * @param[out] p_bytes_available The number of bytes currently available in the pool. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); - -/**@brief Get random bytes from the application pool. - * - * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. - * @param[in] length Number of bytes to take from pool and place in p_buff. - * - * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. - * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. -*/ -SVCALL(SD_RAND_APPLICATION_GET_VECTOR, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); - -/**@brief Gets the reset reason register. - * - * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason)); - -/**@brief Clears the bits of the reset reason register. - * - * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk)); - -/**@brief Sets the power mode when in CPU sleep. - * - * @param[in] power_mode The power mode to use when in CPU sleep. @sa sd_app_evt_wait - * - * @retval ::NRF_SUCCESS The power mode was set. - * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. - */ -SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(nrf_power_mode_t power_mode)); - -/**@brief Puts the chip in System OFF mode. - * - * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN - */ -SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void)); - -/**@brief Enables or disables the power-fail comparator. - * - * Enabling this will give a softdevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs. - * The event can be retrieved with sd_evt_get(); - * - * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); - -/**@brief Sets the power-fail threshold value. - * - * @param[in] threshold The power-fail threshold value to use. - * - * @retval ::NRF_SUCCESS The power failure threshold was set. - * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. - */ -SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(nrf_power_failure_threshold_t threshold)); - -/**@brief Sets bits in the NRF_POWER->RAMON register. - * - * @param[in] ramon Contains the bits needed to be set in the NRF_POWER->RAMON register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAMON_SET, uint32_t, sd_power_ramon_set(uint32_t ramon)); - -/**@brief Clears bits in the NRF_POWER->RAMON register. - * - * @param ramon Contains the bits needed to be cleared in the NRF_POWER->RAMON register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAMON_CLR, uint32_t, sd_power_ramon_clr(uint32_t ramon)); - -/**@brief Get contents of NRF_POWER->RAMON register, indicates power status of ram blocks. - * - * @param[out] p_ramon Content of NRF_POWER->RAMON register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAMON_GET, uint32_t, sd_power_ramon_get(uint32_t * p_ramon)); - -/**@brief Set bits in the NRF_POWER->GPREGRET register. - * - * @param[in] gpregret_msk Bits to be set in the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_msk)); - -/**@brief Clear bits in the NRF_POWER->GPREGRET register. - * - * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_msk)); - -/**@brief Get contents of the NRF_POWER->GPREGRET register. - * - * @param[out] p_gpregret Contents of the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t *p_gpregret)); - -/**@brief Sets the DCDC mode. - * - * This function is to enable or disable the DCDC periperhal. - * - * @param[in] dcdc_mode The mode of the DCDC. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. - */ -SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(nrf_power_dcdc_mode_t dcdc_mode)); - -/**@brief Request the high frequency crystal oscillator. - * - * Will start the high frequency crystal oscillator, the startup time of the crystal varies - * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started. - * - * @see sd_clock_hfclk_is_running - * @see sd_clock_hfclk_release - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void)); - -/**@brief Releases the high frequency crystal oscillator. - * - * Will stop the high frequency crystal oscillator, this happens immediately. - * - * @see sd_clock_hfclk_is_running - * @see sd_clock_hfclk_request - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void)); - -/**@brief Checks if the high frequency crystal oscillator is running. - * - * @see sd_clock_hfclk_request - * @see sd_clock_hfclk_release - * - * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running)); - -/**@brief Waits for an application event. - * - * An application event is either an application interrupt or a pended interrupt when the - * interrupt is disabled. When the interrupt is enabled it will be taken immediately since - * this function will wait in thread mode, then the execution will return in the application's - * main thread. When an interrupt is disabled and gets pended it will return to the application's - * thread main. The application must ensure that the pended flag is cleared using - * ::sd_nvic_ClearPendingIRQ in order to sleep using this function. This is only necessary for - * disabled interrupts, as the interrupt handler will clear the pending flag automatically for - * enabled interrupts. - * - * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M0 - * System Control Register (SCR). @sa CMSIS_SCB - * - * @note If an application interrupt has happened since the last time sd_app_evt_wait was - * called this function will return immediately and not go to sleep. This is to avoid race - * conditions that can occur when a flag is updated in the interrupt handler and processed - * in the main loop. - * - * @post An application interrupt has happened or a interrupt pending flag is set. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void)); - -/**@brief Get PPI channel enable register contents. - * - * @param[out] p_channel_enable The contents of the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable)); - -/**@brief Set PPI channel enable register. - * - * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)); - -/**@brief Clear PPI channel enable register. - * - * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk)); - -/**@brief Assign endpoints to a PPI channel. - * - * @param[in] channel_num Number of the PPI channel to assign. - * @param[in] evt_endpoint Event endpoint of the PPI channel. - * @param[in] task_endpoint Task endpoint of the PPI channel. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint)); - -/**@brief Task to enable a channel group. - * - * @param[in] group_num Number of the channel group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num)); - -/**@brief Task to disable a channel group. - * - * @param[in] group_num Number of the PPI group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num)); - -/**@brief Assign PPI channels to a channel group. - * - * @param[in] group_num Number of the channel group. - * @param[in] channel_msk Mask of the channels to assign to the group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk)); - -/**@brief Gets the PPI channels of a channel group. - * - * @param[in] group_num Number of the channel group. - * @param[out] p_channel_msk Mask of the channels assigned to the group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk)); - -/**@brief Configures the Radio Notification signal. - * - * @note - * - The notification signal latency depends on the interrupt priority settings of SWI used - * for notification signal. - * - To ensure that the radio notification signal behaves in a consistent way, always - * configure radio notifications when there is no protocol stack or other SoftDevice - * activity in progress. It is recommended that the radio notification signal is - * configured directly after the SoftDevice has been enabled. - * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice - * will interrupt the application to do Radio Event preparation. - * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have - * to shorten the connection events to have time for the Radio Notification signals. - * - * @param[in] type Type of notification signal. - * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio - * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is - * recommended (but not required) to be used with - * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. - * - * @param[in] distance Distance between the notification signal and start of radio activity. - * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or - * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. - * - * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(nrf_radio_notification_type_t type, nrf_radio_notification_distance_t distance)); - -/**@brief Encrypts a block according to the specified parameters. - * - * 128-bit AES encryption. - * - * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input - * parameters and one output parameter). - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); - -/**@brief Gets any pending events generated by the SoC API. - * - * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. - * - * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending. - * - * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter. - * @retval ::NRF_ERROR_NOT_FOUND No pending events. - */ -SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); - -/**@brief Get the temperature measured on the chip - * - * This function will block until the temperature measurement is done. - * It takes around 50us from call to return. - * - * @note Pan #28 in PAN-028 v 1.6 "Negative measured values are not represented correctly" is corrected by this function. - * - * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees celsius. - * - * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp - */ -SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); - -/**@brief Flash Write -* -* Commands to write a buffer to flash -* -* If the SoftDevice is enabled: -* This call initiates the flash access command, and its completion will be communicated to the -* application with exactly one of the following events: -* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. -* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. -* -* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the - * write has been completed -* -* @note -* - This call takes control over the radio and the CPU during flash erase and write to make sure that -* they will not interfere with the flash access. This means that all interrupts will be blocked -* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual -* and the command parameters). -* -* -* @param[in] p_dst Pointer to start of flash location to be written. -* @param[in] p_src Pointer to buffer with data to be written. -* @param[in] size Number of 32-bit words to write. Maximum size is 256 32bit words. -* -* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. -* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. -* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or more than 256 words. -* @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location. -* @retval ::NRF_SUCCESS The command was accepted. -*/ -SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * const p_dst, uint32_t const * const p_src, uint32_t size)); - - -/**@brief Flash Erase page -* -* Commands to erase a flash page -* If the SoftDevice is enabled: -* This call initiates the flash access command, and its completion will be communicated to the -* application with exactly one of the following events: -* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. -* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. -* -* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the -* erase has been completed -* -* @note -* - This call takes control over the radio and the CPU during flash erase and write to make sure that -* they will not interfere with the flash access. This means that all interrupts will be blocked -* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual -* and the command parameters). -* -* -* @param[in] page_number Pagenumber of the page to erase -* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. -* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. -* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. -* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a protected page. -* @retval ::NRF_SUCCESS The command was accepted. -*/ -SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); - - -/**@brief Flash Protection set - * - * Commands to set the flash protection registers PROTENSETx - * - * @note To read the values in PROTENSETx you can read them directly. They are only write-protected. - * - * @param[in] protenset0 Value to be written to PROTENSET0. - * @param[in] protenset1 Value to be written to PROTENSET1. - * - * @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice. - * @retval ::NRF_SUCCESS Values successfully written to PROTENSETx. - */ -SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_t protenset1)); - -/**@brief Opens a session for radio requests. - * - * @note Only one session can be open at a time. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot - * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed - * by the application. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0 - * interrupt occurs. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO - * interrupt occurs. - * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This - * implies that none of the sd_* API calls can be used from p_radio_signal_callback(). - * - * @param[in] p_radio_signal_callback The signal callback. - * - * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer. - * @retval ::NRF_ERROR_BUSY If session cannot be opened. - * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); - -/**@brief Closes a session for radio requests. - * - * @note Any current radio timeslot will be finished before the session is closed. - * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. - * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED - * event is received. - * - * @retval ::NRF_ERROR_FORBIDDEN If session not opened. - * @retval ::NRF_ERROR_BUSY If session is currently being closed. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void)); - -/**@brief Requests a radio timeslot. - * - * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST - * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref - * NRF_RADIO_REQ_TYPE_EARLIEST. - * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by - * p_request->distance_us and is given relative to the start of the previous timeslot. - * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. - * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event. - * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths. - * @note If an opportunity for the first radio timeslot is not found before 100ms after the call to this - * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent. - * The application may then try to schedule the first radio timeslot again. - * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START). - * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS. - * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us. - * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the - * specified radio timeslot start, but this does not affect the actual start time of the timeslot. - * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency - * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is - * guaranteed to be clocked from the external crystal. - * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral - * during the radio timeslot. - * - * @param[in] p_request Pointer to the request parameters. - * - * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE. - * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid. - * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t * p_request )); - -/**@} */ - -#endif // NRF_SOC_H__ - -/**@} */ diff --git a/components/softdevice/s120/headers/nrf_svc.h b/components/softdevice/s120/headers/nrf_svc.h deleted file mode 100644 index 895f7f2..0000000 --- a/components/softdevice/s120/headers/nrf_svc.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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 NRF_SVC__ -#define NRF_SVC__ - -#ifdef SVCALL_AS_NORMAL_FUNCTION -#define SVCALL(number, return_type, signature) return_type signature -#else - -#ifndef SVCALL -#if defined (__CC_ARM) -#define SVCALL(number, return_type, signature) return_type __svc(number) signature -#elif defined (__GNUC__) -#define SVCALL(number, return_type, signature) \ - _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ - _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \ - __attribute__((naked)) static return_type signature \ - { \ - __asm( \ - "svc %0\n" \ - "bx r14" : : "I" (number) : "r0" \ - ); \ - } -#elif defined (__ICCARM__) -#define PRAGMA(x) _Pragma(#x) -#define SVCALL(number, return_type, signature) \ -PRAGMA(swi_number = number) \ - __swi return_type signature; -#else -#define SVCALL(number, return_type, signature) return_type signature -#endif -#endif // SVCALL - -#endif // SVCALL_AS_NORMAL_FUNCTION -#endif // NRF_SVC__ diff --git a/components/softdevice/s120/headers/softdevice_assert.h b/components/softdevice/s120/headers/softdevice_assert.h deleted file mode 100644 index a2a8af8..0000000 --- a/components/softdevice/s120/headers/softdevice_assert.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** @brief Utilities for verifying program logic - */ - -#ifndef SOFTDEVICE_ASSERT_H_ -#define SOFTDEVICE_ASSERT_H_ - -#include - -/** @brief This function handles assertions. - * - * - * @note - * This function is called when an assertion has triggered. - * - * - * @param line_num The line number where the assertion is called - * @param file_name Pointer to the file name - */ -void assert_softdevice_callback(uint16_t line_num, const uint8_t *file_name); - - -/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ -/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \ -/** @brief Check intended for production code - * - * Check passes if "expr" evaluates to true. */ -#define ASSERT(expr) \ -if (expr) \ -{ \ -} \ -else \ -{ \ - assert_softdevice_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \ - /*lint -unreachable */ \ -} - -#endif /* SOFTDEVICE_ASSERT_H_ */ diff --git a/components/softdevice/s120/hex/s120_nrf51_2.1.0_softdevice.hex b/components/softdevice/s120/hex/s120_nrf51_2.1.0_softdevice.hex deleted file mode 100644 index 7cdfb1c..0000000 --- a/components/softdevice/s120/hex/s120_nrf51_2.1.0_softdevice.hex +++ /dev/null @@ -1,7080 +0,0 @@ -:020000040000FA -:10000000C0070000D1060000D1000000B1060000CA -:1000100000000000000000000000000000000000E0 -:100020000000000000000000000000005107000078 -:100030000000000000000000DB000000E500000000 -:10004000EF000000F9000000030100000D010000B6 -:1000500017010000210100002B0100003501000004 -:100060003F01000049010000530100005D01000054 -:1000700067010000710100007B01000085010000A4 -:100080008F01000099010000A3010000AD010000F4 -:10009000B7010000C1010000CB010000D501000044 -:1000A000DF010000E9010000F3010000FD01000094 -:1000B00007020000110200001B02000025020000E0 -:1000C0001FB5C046C04600F0EFFA04B00FB41FBD24 -:1000D00008205A49096809580847382057490968CB -:1000E000095808473C2055490968095808474020E5 -:1000F0005249096809580847442050490968095875 -:10010000084748204D490968095808474C204B4981 -:10011000096809580847502048490968095808479C -:100120005420464909680958084758204349096836 -:10013000095808475C204149096809580847602068 -:100140003E4909680958084764203C49096809582C -:100150000847682039490968095808476C20374919 -:100160000968095808477020344909680958084740 -:100170007420324909680958084778202F490968CE -:10018000095808477C202D490968095808478020EC -:100190002A490968095808478420284909680958E4 -:1001A0000847882025490968095808478C202349B1 -:1001B00009680958084790202049096809580847E4 -:1001C00094201E4909680958084798201B49096866 -:1001D000095808479C201949096809580847A02070 -:1001E0001649096809580847A4201449096809589C -:1001F0000847A8201149096809580847AC200F4949 -:10020000096809580847B0200C4909680958084787 -:10021000B4200A49096809580847B82007490968FD -:1002200009580847BC2005490968095808470000D3 -:1002300003480449024A034B7047000000000020B5 -:10024000C0070000C00700000122D84B5A6000BF61 -:10025000D74A1268002AFBD0016000BFD44A126856 -:10026000002AFBD00022D14B5A6000BFD04A12684E -:10027000002AFBD07047F0B505460E46174600240D -:1002800006E0A200B158A2005019FFF7DDFF641C80 -:10029000BC42F6D30020F0BD0120C043C549086030 -:1002A000401048607047014601229204086890425D -:1002B00001D9102070470020FCE7F0B505460C4638 -:1002C0001646002706E028462168FFF7BDFF2D1DD2 -:1002D000241D7F1CB742F6D3F0BD70B505460C4611 -:1002E0002E460BE0304600F075F9FF2C01D80024B3 -:1002F00001E0FF3C013C012080023618002CF1D1C6 -:1003000070BD0146012212044868904201D90920BB -:100310007047A9484069401C01D10F20F8E7002030 -:10032000F6E7FEB504462068030000F037FA05043E -:100330002B4249598B00201DFFF7E3FF0546002D96 -:1003400001D02846FEBDFFF7A7FF0120C00200F044 -:1003500041F9042221469948FFF78DFF002801D07A -:100360000320EFE708222146944800F06DF90028A9 -:1003700006D1002192480068FFF766FF00F00CF9F3 -:100380000320DFE7A768E6686068019031463846D9 -:10039000FFF7A3FF324638460199FFF78EFFB20000 -:1003A0003846019900F050F9002800D1CAE703202F -:1003B000C8E700F0E3F9834800688349086041E03A -:1003C00060680190E668A0680090B200009901980A -:1003D00000F03AF90746002F00D1B3E70E20B1E74D -:1003E000201DFFF760FF0546002D01D02846A9E734 -:1003F0006068002807D1FFF74FFF0320800200F05C -:10040000E9F800F0C9F8FFF747FF0120C00200F04B -:10041000E1F8042221466948FFF72DFF002801D0AA -:1004200003208FE708222146644800F00DF90028D8 -:1004300006D1002162480068FFF706FF00F0ACF823 -:1004400003207FE700BF00207CE770B505460C461F -:10045000182D04D12068FFF764FF206002E001201E -:10046000206000BF00BF70BDF0B589B05248406940 -:1004700003905248806881000398081802900398FE -:10048000000B01900121090302984018401E000B47 -:1004900000900124002520462946019A00F0C4F866 -:1004A0000022401E91410791069001260027304608 -:1004B0003946009A00F0B8F80022401E914105919B -:1004C0000490049BDB43059AD2430698184307998E -:1004D00011430791069037490698086007984860CD -:1004E00009B0F0BD70B53448446934488568466841 -:1004F000AA003146204600F0A7F8002801D00020CD -:1005000070BD0120FCE72D484068002801D0012083 -:1005100000E000200546FFF7E5FF002807D0FFF7C1 -:10052000BBFE0320800200F055F800F035F8FFF71D -:100530009BFF002D0ED020484669204884684768FC -:1005400021463046FFF7C9FE224639463046FFF7BE -:10055000B4FE00BF00F020F810B5184844681A48EF -:100560000460204600F0DCF810BD15480068006803 -:10057000401C01D100BFFEE710480068002802D0EF -:10058000042806D101E0FFF7BEFFFFF7E5FF00BF3B -:10059000FEE700BF00BFFEE7BFF34F8F0B480C49DB -:1005A000C860BFF34F8F00BFFEE7000000E50140C9 -:1005B00000E40140000600400010001000080000A8 -:1005C000B8070000BC070000000000200400FA0586 -:1005D00000ED00E010B50146104B1A6808460223F2 -:1005E0000F4C636000BF0F4B1B68002BFBD0531CEC -:1005F00004D0904202D20A4B186101E0084B986087 -:1006000000BF084B1B68002BFBD00023044C636029 -:1006100000BF044B1B68002BFBD010BD0010001066 -:1006200000E5014000E4014010B5202A04DB01464A -:10063000203A9140002010BD914020239C1A03468F -:10064000E3401943904010BD034610B50B439B0790 -:100650000FD1042A0DD308C810C9121FA342F8D025 -:1006600018BA21BA884201D9012010BD0020C04328 -:1006700010BD002A03D0D30703D0521C07E000208E -:1006800010BD03780C78401C491C1B1B07D1037854 -:100690000C78401C491C1B1B01D1921EF1D118463D -:1006A00010BD70477047704710B500F007F810BDD7 -:1006B000014B1B68DB6818470000002019481A49E5 -:1006C0007047FFF7FBFFFFF7FBFC00BD20BFFDE716 -:1006D0001649174C24688C420BD1164B1B68994263 -:1006E0000CD1154B154A1360186810498842EDD09B -:1006F0000AE0134880F30888124B18470F4A13602A -:1007000018680A498842E1D080F308880E49884277 -:1007100004DD0E48026802210A4302605B68184744 -:100720000346DFE7C0070000C0070000FFFFFFFF30 -:10073000000C000014100010001000000000002049 -:10074000000400206B05000000200020240500406C -:100750000D48704502D1EFF3098101E0EFF3088104 -:10076000886902380078182802D1C046074A104725 -:10077000074A12682C3212681047000000B5054B7A -:10078000054A9B58984700BDFDFFFFFF4B04000042 -:1007900000000020001000000400000030B4744687 -:1007A000641E2578641CAB4204D3635D5B00E318D0 -:1007B00030BC18471D46F8E7000C00000010000090 -:10100000801E002095BF0100E5210000FBBE01000D -:1010100000000000000000000000000000000000D0 -:1010200000000000000000000000000005C00100FA -:101030000000000000000000E5210000E5210000A4 -:1010400071C0010077C00100E5210000E52100002A -:10105000E5210000E5210000E5210000E521000078 -:101060007DC00100E5210000E521000083C00100F2 -:10107000E521000089C001008FC0010095C001007A -:10108000E5210000E5210000E5210000E521000048 -:10109000E5210000E5210000E5210000E521000038 -:1010A0009BC00100A1C00100E5210000E521000076 -:1010B000E5210000E5210000E5210000E521000018 -:1010C00000F002F81AF047FF0CA030C808382418C6 -:1010D0002D18A246671EAB4654465D46AC4201D170 -:1010E0001AF039FF7E460F3E0FCCB646012633423A -:1010F00000D0FB1AA246AB463343184728B1010083 -:1011000058B10100103A02D378C878C1FAD8520712 -:1011100001D330C830C101D504680C6070470000AD -:101120000023002400250026103A01D378C1FBD803 -:10113000520700D330C100D50B6070471FB5C046C1 -:10114000C0461AF0AAFE04B00FB41FBDF0B440466A -:10115000494652465B460FB402A0013001B506482D -:10116000004700BF01BC86460FBC804689469246B8 -:101170009B46F0BC70470000C11000008269024924 -:101180008161024810447047911100000100000085 -:1011900001B41EB400B50BF0A4F801B40198864662 -:1011A00001BC01B01EBD0000401E00BF00BF00BF5B -:1011B00000BF00BF00BF00BF00BF00BF00BF00BF37 -:1011C00000BFF1D17047000070B505460C461646C9 -:1011D00002E00FCC0FC5103E102EFAD2082E02D31B -:1011E00003CC03C5083E042E07D301CC01C5361F2E -:1011F00003E021782970641C6D1C761EF9D270BD45 -:101200008307FF22DB0E9A408907090E99400028C8 -:101210000BDA0007000F0838830828489B001818CD -:10122000C36993430B43C3617047830824489B0001 -:101230001B181868904308431860704710B504469F -:1012400000210120FFF7DCFF00211820FFF7D8FF65 -:1012500000210B20FFF7D4FF02211920FFF7D0FF58 -:1012600002210D20FFF7CCFF02210E20FFF7C8FF5F -:1012700002210F20FFF7C4FF0221C81FFFF7C0FFA4 -:1012800003211620FFF7BCFF03211520FFF7B8FF4D -:10129000204600F019F8002010BD6B210180704736 -:1012A00010B500F028F810BD0648704710B500F0E2 -:1012B0002AF810BD704770477047000000ED00E04D -:1012C00000E400E003F9004370B50546314C072007 -:1012D0006070A01CFFF7E1FF5920A0802E492F4825 -:1012E0001AF0D8FC2E492F481AF0D4FC2946204683 -:1012F00000F0C6FB70BD10B500F0CBFB2549002007 -:10130000891E087010BDF8B5224E0446B61E30780E -:1013100001270D46002807D0204660380B2808D842 -:10132000204600F015FF2BE0602CF9D01E48086025 -:10133000F8BD20466C38032803D8204600F049FF4A -:101340001EE0204670381F2803D8204600F04FF9D1 -:1013500016E0204690380F2803D8204600F0F2F817 -:101360000EE02046A0380F2803D8204600F07EF873 -:1013700006E02046B0380F2804D8204600F0EAF9ED -:10138000286000E02F60602CD2D128680028CFD1DF -:101390003770F8BD1A00002060040000801E002095 -:1013A00080090000801E0020013000000120254936 -:1013B000C003086024490020087007202349C005A5 -:1013C0008860704770B5204D04462878A04207D049 -:1013D000002C05D0002803D01DA14D201AF087FD58 -:1013E0002878A0420ED000211E4A18482C70002CEC -:1013F0001BD01D4B012C06D0022C0DD014A168204F -:101400001AF075FD70BD1160022111605361032156 -:1014100009068160416070BD116003211160536154 -:101420000121C9058160416070BD11601160072113 -:10143000C905816070BD10B505A171201AF057FD76 -:1014400010BD000080E100E02000002000F5014018 -:101450007372635C68616C5F63636D5F6161722E60 -:101460006300000000F500409001002010B5A03896 -:1014700003001AF06AFE0B070E172028313A414B81 -:10148000525C65004B6808788A68194603F0BDF91C -:1014900010BD88888A6883B20888194680B203F034 -:1014A000C3F910BD08884C68CB688A6880B22146B1 -:1014B00003F0BEF910BD08884B688A6880B21946EF -:1014C00003F0D2F910BD88888A6883B2088819466B -:1014D00080B203F0DEF910BD88888A6883B208887C -:1014E000194680B203F00CFA10BD08884A6880B231 -:1014F000114603F03FFA10BD088982B2888883B292 -:101500000888194680B203F040FA10BD08884A687E -:1015100080B2114603F05DFA10BD08894C6882B2B2 -:101520000888CB6880B2214603F0D6FA10BD08883F -:101530004C68CB688A6880B2214603F0E7FB10BD97 -:10154000012010BD10B5903803001AF0FEFD090609 -:101550000F161D242C363F464E0088888A6883B2B9 -:101560000888194680B204F0E5F810BD08884A687A -:1015700080B2114604F019F910BD08884A6880B29B -:10158000114604F01EF910BD08884A6880B2114661 -:1015900004F024F910BD08884B688A6880B21946A7 -:1015A00004F02FF910BD088982B2888883B20888B8 -:1015B000194680B204F02EF910BD08894B6882B23A -:1015C0000888194680B204F044F910BD08884A68BA -:1015D00080B2114604F04FF910BD888882B20888A5 -:1015E000114680B204F0A3F910BD012010BD10B562 -:1015F000703803001AF0A9FD1B0F15192125282F9B -:10160000363B4044484C53585F68707881889095C9 -:10161000999CA2A5AC004A680878114607F005FC21 -:1016200010BD086807F051FC10BD0C790B7B8A686F -:101630000868214607F058FC10BD086807F01BFD3C -:1016400010BD07F052F910BD08884A6880B21146F3 -:1016500007F053FE10BD0A790888114680B207F0E2 -:10166000E3FE10BD087840B207F0ECFE10BD08881C -:1016700080B207F000FF10BD086807F00EFF10BD34 -:10168000086801F0A5FB10BD086801F0D5FB10BD8E -:10169000088982B209C9194607F016FF10BD05C9AD -:1016A000114607F05DFF10BD08884A6880B21146F8 -:1016B00009F0FEF810BD0C790888CB688A6880B202 -:1016C000214609F019FA10BD0B7908888A6880B2A2 -:1016D000194609F0C3FB10BD08884B688A6880B2C0 -:1016E000194609F02BFC10BD08884C68CB688A6845 -:1016F00080B2214609F08EFC10BD08884A6880B28D -:10170000114609F0D1FC10BD0B7908880A7A80B225 -:10171000194607F047FF10BD088880B207F047FF61 -:1017200010BD086807F058FF10BD07F0BAF810BDEB -:101730008A6809C9194607F0BEFF10BD07F093F883 -:1017400010BD08884A6880B2114608F071F810BDD3 -:10175000012010BD10B5B02805D0B12808D0B2289E -:101760000BD0012010BD088880B20AF02AF910BD04 -:10177000088880B20AF044F910BD08884B688A686E -:1017800080B219460AF04DF910BD000010B50300F3 -:101790001AF0DBFC0A0609060C0C0F0F06060612EF -:1017A00007F0D2F810BD09F0D6FE10BD01F0FCF92B -:1017B00010BD06F03DFA10BDFAA1FE481AF097FBE5 -:1017C00010BD3EB5FC49054603C9009001912F208C -:1017D000400169460881F94A142310460A21283835 -:1017E0000AF055FE0024F6480AF06FFE641CE4B2CD -:1017F0000A2CF8D30823012202A9F2480AF0CDF9F5 -:10180000002804D0FF20E7A101301AF070FB372038 -:101810000822ED49400104F020FD002804D0FF20FB -:10182000E0A104301AF063FB00211E22084604F0F8 -:1018300001F9284607F0B8FA02222421E34801F012 -:1018400039FBE24801222C214C3001F033FBDF4907 -:101850000B20B03901F0B2F9002804D0FF20D1A14B -:1018600015301AF044FB28788007800F09F007FE36 -:1018700002F05EF96B4600220821D5A007F04FF96F -:10188000002804D0FF20C7A11B301AF030FB681CD1 -:1018900002F0A2FC002804D0FF20C2A11D301AF0E3 -:1018A00026FBDB218900CD481AF0F6F9CB4801214F -:1018B0004171022181710621C1713EBD10B5C74C35 -:1018C000A078092804D3FF20B6A154301AF00FFBEA -:1018D000207860214843001900210173417BF722E1 -:1018E000C908C900C91C1140EF22114041730121F0 -:1018F000E1700C3010BD70B50E4600211C461980F9 -:10190000154603001AF021FC0723050B1711231DB0 -:10191000230022462946304609F03AFE70BD224691 -:101920002946304606F050FE70BD22462946304614 -:1019300001F0A9FF70BD22462946304603F07BFD29 -:1019400070BD22462946304600F0C7FB70BDFF201F -:1019500094A1B3301AF0CBFA032070BD70B59F4C40 -:10196000E078002818D02078602148430019407B97 -:1019700000254007400F01190879401E08712078A2 -:10198000401CC0B22070092800D12570A078401CEE -:10199000A0700AF020FFE57070BD9048C079002863 -:1019A00000D08BE7704770B58C4DA86800280CD02C -:1019B000FFF7F3FF002862D06022A968FFF704FC5C -:1019C000FFF7CCFF0020A860EFE76879002856D029 -:1019D000FFF774FF04467D484C3001F07BFA6060ED -:1019E000002804D173486FA14A301AF080FA606869 -:1019F00001F0D3FA00280DD0204606F0C3FC607831 -:101A0000010703D5C008C000401C2BE06F48616887 -:101A10004C302DE06D4861684C3001F064FA00F004 -:101A2000F5FA00282BD1FFF749FF0446674801F07B -:101A300051FA6060002804D1BD205AA180001AF03C -:101A400056FA606801F0ADFA002814D0606800888A -:101A50006080204609F0CFFD6078010706D5C008F8 -:101A6000C000801C6070FFF779FF9EE757486168EF -:101A700001F039FA99E75548616801F034FA70BD10 -:101A800010B5574CA1606060564800F0DDFB207037 -:101A900010BD534900204870704770B5524E05463E -:101AA000706A94B00C46401C04D1B06AC043000474 -:101AB000000C0BD0306AC007C00F2870706A1AF093 -:101AC000EDF8B06A2071000A607114E02B206946BD -:101AD000087009A9684601F034FA002804D0354896 -:101AE00030A17E381AF003FA0120287006220AA9D4 -:101AF00020461AF072F82878002803D06079C021B7 -:101B00000843607114B070BDF0B5374C06462068CC -:101B100095B00D4637460837401C08D16068401C18 -:101B200005D1A068401C02D1E068401C11D020689B -:101B300031461AF0B3F86068311D1AF0AFF8A068AA -:101B400039461AF0ABF8E06831460C311AF0A6F8C5 -:101B500025E02B206946087009A9684601F0F1F9D3 -:101B6000002804D013480FA155381AF0C0F90822F4 -:101B70000AA930461AF031F82B206946087009A9E5 -:101B8000684601F0DEF9002804D00A4805A14E3865 -:101B90001AF0ADF908220AA938461AF01EF8206991 -:101BA0002E4623E07372635C686F73745F636F72B9 -:101BB000652E63008702000064C10100E40100207B -:101BC0008D170000040A00202403002000140020C8 -:101BD0006E5246353138323200000000E40F0020EA -:101BE00024000020A7190000800000100836401CC7 -:101BF00008D16069401C05D1A069401C02D1E06990 -:101C0000401C12D0206929461AF048F86069291D45 -:101C10001AF044F8A06931461AF040F8E069294604 -:101C20000C311AF03BF815B0F0BD2B246846047057 -:101C300009A901F086F9002803D0FE49FE481AF0F0 -:101C400056F9082209AF28460AA919F0C6FF6846C6 -:101C5000047009A901F075F9002804D0F648F54987 -:101C6000C01D1AF044F90822391D304619F0B5FF9D -:101C7000D9E770B5F14C0546A068002804D0EE48BD -:101C8000EC4956301AF033F9A56070BD10B5014625 -:101C9000EB4801F028F9E9498879401CC0B2887105 -:101CA000012803D1E748007800F0F2FA10BD70B5C2 -:101CB0000446E54816460D46814204D1DE48DD491A -:101CC000CB301AF014F9012E05D0DB48D949DA30AF -:101CD0001AF00DF970BD6620207000202072A581D9 -:101CE0000120A07370BD70B515460C460646FFF77F -:101CF00054FE00280CD0662101704680012101723B -:101D000021680161A18881820573FFF727FE70BDFC -:101D10001321304607F088FB70BD70B5C94C0546ED -:101D2000607894B0002801D00820EBE6C7488542CF -:101D300006D301208004854204D3C548854201D2E0 -:101D40001020DFE6287801268007800F012803D0C5 -:101D5000022805D00720D5E661680020087001E060 -:101D60006068067000F012FF217860680CF066FA77 -:101D7000A068401E07280BD8302269460A70887078 -:101D800068460CF07DFA002802D009A80CF083FA0E -:101D90002846FFF716FD66700020B3E6F8B5044646 -:101DA000AB480F46814208D3002C01D0844204D3B3 -:101DB000E01C80088000A04201D01020F8BD9F48A0 -:101DC0008178002911D039880091417860225143EF -:101DD0000D18287B0C350007000F3B4600222946D2 -:101DE000FFF789FD060004D015E0002038800520AB -:101DF000F8BD002C13D039880098814201D90C26F7 -:101E00000DE028783B460007000F22462946FFF7E1 -:101E100072FD060005D00C2E01D00020388030461F -:101E2000F8BD864C6078401CC0B26070092801D1B2 -:101E300000206070A078401EA07068784107490FAC -:101E400001290ED0022906D003291AD079498148E8 -:101E50001AF04DF8E3E7C006E1D46868FFF716FF13 -:101E6000DDE7774869684C3001F03DF86079401C47 -:101E7000C0B260710128D2D17248007800F008FA2F -:101E8000CDE7E079401CE071C9E7704A10B5904297 -:101E900008D30124A4046E4AA04201D3904201D386 -:101EA000914201D2102010BD00F0C1FE10BD674B61 -:101EB00010B5994208D30124A404654BA14201D373 -:101EC000994201D39A4201D2102010BD022803D0BA -:101ED000102801D0092010BD00F0CFFE0028FAD054 -:101EE000052010BD594B10B598420CD30124A40411 -:101EF000574BA04201D3984205D3994203D3002AFD -:101F000003D09A4201D2102010BD00F0DCFE002860 -:101F1000FAD0072010BD10B504464D4894B0844255 -:101F200002D2102014B010BD0F2008A90873694612 -:101F30000BA801F006F80028F4D16846007A20705A -:101F400068464089608068468089A0800020E9E773 -:101F500010B500290AD03E4A914202D30B68934241 -:101F600001D2102010BD8A88002A02D001F032FE72 -:101F700010BD092010BD10B5344A94B091420DD364 -:101F800001229204324B914201D3994206D3441E5E -:101F90001E2C25D8914203D3994201D21020C1E7CB -:101FA00001281BD108780024C007C00F002803D0E7 -:101FB00003206946887001E06846847038206946CD -:101FC000087009A9684600F0BCFF002804D0FF2073 -:101FD00021A1CD3019F08BFF2046A3E70720A1E710 -:101FE0000246203A1F2AF9D806F011FE9AE7184A4D -:101FF00010B5914201D2102010BD0246203A1F2A8E -:1020000002D806F07CFE10BD072010BDF0B595B0DB -:102010003B2008A9087369460BA800F092FF00282E -:1020200004D0FF200CA12F3019F061FF0E4E0024C8 -:102030006D464CE0A41B000057020000E40F002096 -:102040000014002024000020FFFF000000D0010049 -:1020500000280020C20300007372635C686F737411 -:102060005F636F72652E6300043000002F19B87D26 -:10207000C10706D0400704D460004019C08809F0A9 -:10208000C7FB3148807900281FD0B87D80071CD558 -:1020900060004019C0880022062109F0CDFB00280D -:1020A00013D03C2108A8017360004019C18868461C -:1020B000C18569460BA800F044FF06000BD0FF2045 -:1020C0002249433019F013FF05E0641CE4B268466E -:1020D0000079A042CAD83046A5E5F7B50546007894 -:1020E000002700090C463E46062804D0FF20174969 -:1020F0006C3019F0FCFE287A00280ED0012814D08C -:10210000FF2012498D3019F0F2FE0298002C068053 -:1021100001D0278066800020FEBD02270926002C02 -:102120000ED0A889A080A87B08E003271426002CE5 -:1021300006D02869E060A88A2082287B2072E4E724 -:1021400002980680E7E70000E40F00205820000016 -:1021500010B56038030019F0F8FF0A060A0F1318CB -:102160001F252930353A0868FFF7D7FD10BD05C98E -:102170001146FFF713FE10BD086809F018FC10BDEA -:1021800005C91146FFF781FE10BD4B6808788A68C3 -:102190001946FFF78CFE10BD8A6809C91946FFF77A -:1021A000A1FE10BD0868FFF7B6FE10BD08884A689A -:1021B00080B21146FFF7CCFE10BD05C91146FFF7EE -:1021C000DAFE10BD05C91146FFF711FF10BD012051 -:1021D00010BD0120704700000E4A12680C498A4267 -:1021E0000AD118470B4A1268094B9A4204D101B52B -:1021F0000AF06EF803BC8E4607490968095808477B -:1022000006480749054A064B7047000000000000D9 -:10221000BEBAFECA6000002004000020801E00201C -:10222000801E002001203F49400608603E490860AA -:102230003E490A68FF231B029A4383121A430A602D -:10224000384980390860704710B502460420384983 -:1022500004E0C3005B181B79002B0AD00346401E24 -:10226000C0B2002BF5D133A1432019F040FEFF206E -:1022700010BDC300CA50002259184A718A71012248 -:102280000A7110BD2A4A0021C000801801717047F0 -:1022900010B50446042803D326A1522019F027FEC6 -:1022A0002348E1000C182079012803D021A15320F4 -:1022B00019F01DFE6079A179401CC0B2814200D0A6 -:1022C00060710120174940068031086010BD70B56B -:1022D000164800680004800F022803D015A1692069 -:1022E00019F005FE124E194C03252078C1008819FB -:1022F0000279012A07D1427983799A4203D042793F -:102300008271705880472078401CC0B22070042829 -:1023100001D30020207028466D1EEDB20028E4D1C4 -:1023200070BD000080E100E080E200E018E400E021 -:102330007C1400207372635C736F635F7369676EF4 -:10234000616C6C696E672E63000000003000002035 -:1023500010B5EFF31080C407E40F72B6DA48417885 -:10236000491C41704078012801D10AF059FA002C2B -:1023700000D162B610BD70B5D34CE07800280AD108 -:102380000125E570FFF7E4FF0AF052FA002804D0B7 -:1023900000200AF025FA002070BDCC486571456028 -:1023A000F9E770B5EFF31080C507ED0F72B6C64CB4 -:1023B0006078002803D1C6A18F2019F098FD6078BD -:1023C000401E60706078002801D10AF02DFA002DBF -:1023D00000D162B670BD10B5BB48C178002904D0E9 -:1023E00000214171C170FFF7DCFF002010BD10B566 -:1023F00004460AF01DFAB449C978084000D001200B -:102400002060002010BDF8B50246AF4C0026A67132 -:102410000820042101251027130019F096FE0D084D -:102420000A0C0E101214161E2621232528002571D1 -:1024300022E0022001E021711EE020711CE02771E2 -:102440001AE02020F9E7012616E0FFF781FF0AF0E5 -:10245000EFF90028FBD002260EE02171A5710BE0F8 -:102460002771FBE7202000E040202071F6E7FF20E5 -:1024700097A17E3019F03BFD0AF0E6F9002809D05B -:102480000AF0E8F9B04205D130460AF0E6F9002832 -:10249000FAD02CE001208007C560914900224A60F3 -:1024A000904A9661894B02225A6085608E48026983 -:1024B000D243D206D51702696D1C10231A4302615C -:1024C0000F4600E020BF78680028FBD030460AF0B5 -:1024D000C4F90028FAD0002D04D1834802691021E4 -:1024E0008A43026179490220886000207860A079DF -:1024F00000280CD00AF09CF905460AF0F9F87B4A4E -:10250000002D02D0A260E06001E0E260A060002E39 -:1025100001D100F0B1F8F8BD10B504460AF08EF90B -:10252000002805D068490120C8704A78521C4A70BA -:102530002046FFF768FF10BDF8B5694FB868002561 -:10254000012802D1BD600AF04BF97868012800D15A -:102550007D60386801265C4C012814D13D606079AB -:10256000002803D000200AF03BF96571207800288C -:1025700009D00AF05DF9002805D05948C0388663B3 -:1025800000060661A670386901282CD13D6100F073 -:1025900068F8012080074661A079002815D00AF06C -:1025A00047F900900AF0A4F80099002901D0E168E9 -:1025B00000E0A168411A022901DA8A1C13DC0099A3 -:1025C000002901D0E06000E0A060FFF7C1FE0AF042 -:1025D0002FF9002806D04248C038866300060661FD -:1025E000A67000E02670F868012819D100F039F8CB -:1025F00000F037F800F035F8A078002804D1FF206B -:1026000033A1053019F073FCFD60A5702570FFF74C -:10261000C8FE09F0BCFC002802D03148C038C663AF -:10262000F8BD10B5284CE078002801D10AF0FCF87C -:1026300001208107886100F014F8A07800280BD0F1 -:10264000274CE068002803D10AF007F90028F8D1E8 -:102650000020E06000F005F800201C49C0438860BD -:1026600010BD08B55020694608806A461088411E92 -:1026700011800028F9D108BDF8B5144819278760E2 -:10268000174900200860C8600AF0D2F8BD0701248D -:102690000D4E002805D01248C03884632C61B470F8 -:1026A00000E03470FFF754FE084847600D49307968 -:1026B0008863FFF7D6FFAC61FFF7D3FF084900201E -:1026C00008616C61F8BD0000340000200003004088 -:1026D0007372635C736F635F636C6F636B2E630015 -:1026E000000100400005004000ED00E0FFFFFF7F1B -:1026F0008107C90E002808DA0007000F0838800893 -:102700002C4A80008018C06904E080082A4A8000B2 -:1027100080180068C8400006800F704710B50D2073 -:10272000FFF7E6FFC4B20420C043FFF7E1FFC0B2E9 -:10273000844203D021A11A2019F0D9FB10BD012138 -:10274000234A48031060234B00221A60224A51603A -:10275000224A1060224A11601D4980390860704782 -:1027600001211B4A480310601D4A5160194A00218B -:1027700011601A490860704710B5164908680128A9 -:1027800004D00EA1562019F0B2FB10BD1548806888 -:102790000022C0B20A6009F00BFD10BD10B50D4853 -:1027A00001680029FCD0FFF7E7FF01200B49400337 -:1027B000086010BD00ED00E000E400E07372635CAF -:1027C000736F635F68616C5F726E672E63000000F9 -:1027D00080E100E000D1004000D3004080E200E052 -:1027E00000D0004000D5004030B40121BC48C902EF -:1027F0000160CD1005604A030260BA4803681B02FD -:102800001B0A036004680023240A24020460B648FB -:102810000468240A24020460B448012444608460EB -:10282000B34C23606360A360B24B19601D601A60F3 -:10283000B14B19601A600121016030BC704710B4BF -:102840000121A748CA0202600B0203600C06046063 -:10285000A64841608160A94841680029FCD1A4498B -:102860000020086048608860A2480260036004603D -:1028700010BC704701219F48C9020160C910016066 -:102880007047002805D0012805D0022805D19C48B2 -:1028900070479C4870479C48704710B59BA18B209F -:1028A00019F025FB002010BD70B500219E4C9F4DF6 -:1028B0009F4A8F4B002808D001281DD0022822D023 -:1028C00092A1B32019F013FB70BD01200004A06099 -:1028D000A86011601960974BC2039A60964A906095 -:1028E0007F4A001210609548016086480160944854 -:1028F00001609448017070BD01204004A060A86090 -:102900005160596070BD01208004A060A860916092 -:10291000996070BDF8B59446834A754F834D002485 -:102920000126002808D0012832D0022840D077A103 -:10293000E82019F0DCFAF8BD891E0902090A012015 -:10294000000490603C606860794A1160012B1DD0E2 -:1029500000217C4A7C4B517061463D31DC63DE6373 -:102960007A4B5C6002249C6004241C61734B1960E8 -:1029700073490E605F4B891519606F4B58605E4854 -:1029800001606C49C00548601670F8BD0121E0E7A0 -:1029900001205D4E40046E4F012B04D13460506025 -:1029A00068603960F8BD9060346068603960F8BD77 -:1029B0000120534E8004674F012BF4D1EEE74F48BE -:1029C0004068704770B54A4D28680026564C01286B -:1029D00006D1A068C00303D501200004A0602E60CA -:1029E0006868012809D1A068800306D50120400449 -:1029F000A0606E6001200AF0FEFEA868012809D1DF -:102A0000A068400306D501208004A060AE600220CB -:102A10000AF0F1FE70BD10B54A490878002818D0B8 -:102A20000120444AC0079060434AC00B90602C4A82 -:102A300000121060414A00201060324A1060404A83 -:102A4000106008704A78002A02D048700AF0D3FE5D -:102A500010BD0320FAE701203F49000608607047D7 -:102A60000120244900060860704701203A494005CA -:102A70000860704701201F494005086070473249CF -:102A80000020C86388151B4908607047410A334A13 -:102A9000C005C00D5043801C5143400A08187047C0 -:102AA00010B42F4C430B63431B0C5C020C602B4C8B -:102AB0006343C31A2B485C025843284B400D4343E1 -:102AC000E31A0124DB0324041B191B1613700A6884 -:102AD0001018086010BC704710B50AF05FFF10BDF9 -:102AE00080E100E008E400E018E400E000B000400D -:102AF00040B1004080E200E000E100E000B50040AD -:102B000048B100404081004044B100407372635CB2 -:102B100072656D5F68616C5F6576656E745F746920 -:102B20006D65722E6300000000B3004040B30040AA -:102B300040B5004000F50140008300404085004062 -:102B40000082004044000020C08F0040008500400B -:102B500044B5004048B5004000E200E0093D0000F7 -:102B6000378600006F0C010010B50AF003FF10BD9E -:102B700000200449C863012001218140024A1160FC -:102B800000BF7047C01F004080E200E010B50BF0AE -:102B9000A5FB09F04BFAFEF709FC0DF01FFD0CF048 -:102BA000B5F90CF041F910BD70B50C46054603F0BF -:102BB000B5FA214628460DF0E8F970BD70B50D460E -:102BC000040012D0002D10D02101284619F062F81F -:102BD00010225449284619F000F8524801210838BB -:102BE000018044804560002070BD012070BD70B53B -:102BF0004C4E00240546083E11E071682001401843 -:102C0000817BAA7B914209D1C17BEA7B914205D1AC -:102C10000C22294618F0B4FF002806D0641C308826 -:102C20008442EADB0020C04370BD204670BD70B511 -:102C30000D4606000AD0002D08D03A4C083C2088EA -:102C40006188401C884203D9042070BD102070BDEB -:102C50003046FFF7CCFF002801DB401C0AE020884B -:102C60006168000140181022314618F0B6FF208834 -:102C7000401C20802870002070BD70B514460D00E7 -:102C80001FD0002C1DD00021A170022802D01028D6 -:102C900017D108E0687829780002084311D0012193 -:102CA000A17010800BE02846FFF7A1FF002808DB89 -:102CB000401CA070687B297B000208432080002014 -:102CC00070BD012070BD70B5054614460E000AD0D7 -:102CD00000203070A878012807D004D9114908399C -:102CE0000A8890420BD9012070BD002C04D02878AE -:102CF00020702888000A50700220087010E0002C14 -:102D00000CD049680001411810222046103918F0F3 -:102D100064FF287820732888000A607310203070C0 -:102D2000002070BD500000205D4910B5884206D3D8 -:102D300001218904884204D35A49884201D21020D3 -:102D400010BD0146012005F0D5F810BD30B5044690 -:102D500093B000200D46079014210BA818F09CFF9B -:102D60001C21684618F098FF6A4611201077002051 -:102D70005077107802210843107007A80C900120AA -:102D800008AA907248486A4610850AA80B902088C5 -:102D9000108460885084A0889084E088D084907FDC -:102DA000F9210840801C4008400090770820908658 -:102DB000108708A80F9010AA0BA9684600F094FF8E -:102DC000002803D110A800882880002013B030BD4F -:102DD00030B585B0044608206946088105F09CFEA0 -:102DE00005000CD02E48844206D301208004844282 -:102DF00007D32C48844204D2102005B030BD2B48A4 -:102E0000FBE72146012005F075F80028F5D1208860 -:102E10006946088060884880A0888880E088C880EB -:102E20006B4602AA0021284601F0DDFB69460989AC -:102E30000829E2D00320E0E71FB5044605F06CFE48 -:102E4000010012D00020029008206A461081144828 -:102E50000392844206D301208004844207D31148A0 -:102E6000844204D2102004B010BD1048FBE702AA2F -:102E70000F4801F045FD0028F5D169460989082968 -:102E800001D00320EFE76946098821806946498817 -:102E9000618069468988A1806946C988E180E2E746 -:102EA00000D0010000280020042A000005300000A6 -:102EB000FFFF000010B5031D03600020521E04E058 -:102EC0005C181C60401C2346C0B29042F8DB002016 -:102ED000186010BD01460A680020002A02D0104682 -:102EE00012680A60704702680A600160704700005B -:102EF00000B51E2823D00BDC0C281CD01FDC0300DF -:102F000019F023F9090F1D111D1D171713151D00A9 -:102F1000302814DD3A38030019F017F9030F1109AE -:102F20001100002000BD214800BD042000BD0D207F -:102F300000BD0F2000BD082000BD112000BD0320F2 -:102F400000BD10B50C460BF09BF900281ED02046A2 -:102F50000BF0A1F9002816D022780E2A0DD00F2AE6 -:102F60000BD0022A09D0032A07D0102A09D010A1B9 -:102F70007C2018F0BCFF002010BDA078FFF7B8FF40 -:102F800010BD112010BD0AA18220F2E708A18820FF -:102F9000EFE710B50BF05EF910BD10B50BF07BF943 -:102FA00010BD10B50BF061F910BD0000023000003B -:102FB0007372635C686F73745F6863692E6300008B -:102FC00010B501462022094818F007FE07490020E5 -:102FD000C877084610BD0649012048610548064AE1 -:102FE0000168914201D1002101607047B0160020B4 -:102FF0000005004060000020BEBAFECA704770475E -:1030000010FFFFFFDBE5B15100D001006B00FFFFB7 -:1030100003B40148019001BD09000020002803D03D -:103020008178012939D101E0102070470188FC4ADC -:10303000881A914233D01BDCFA4A881A91422ED06A -:103040000BDC00292BD00320C002081A27D001284E -:1030500025D001210903401A07E001281FD00228CA -:103060001DD0FF281BD0FF380138002815D116E0ED -:10307000FF220132811A904211D008DC01280ED0C3 -:1030800002280CD0FE280AD0FF2806D107E001292B -:1030900005D0022903D0032901D0002070470F205A -:1030A000704700B50A2821D008DC030019F04DF85C -:1030B0000A1C2024241A24282224261A102819D075 -:1030C00008DC0B2816D00C2814D00D281AD00F2895 -:1030D00008D111E011280FD0822807D084280DD004 -:1030E00085280DD0032000BD002000BD052000BDB7 -:1030F000CD4800BD072000BD0F2000BD042000BD4D -:10310000062000BD0C2000BD70B500290BD0CB1FE0 -:10311000FA3B81241E46CDB2112B1BD2012805D0CB -:10312000022806D009E0002010701DE0FF200430C6 -:1031300001E0FF200330814218D0330019F005F878 -:10314000111613131613161613161616131313133C -:10315000161316000846FF3881381F2803D9FF3997 -:10316000FE39022902D81570002070BD14700720A6 -:1031700070BD00B5030018F0E8FF060406040C0853 -:103180000A0C002000BD112000BD072000BD082052 -:1031900000BD032000BD00780207120F04D0012AF1 -:1031A00005D0022A0AD10EE0000907D108E0000983 -:1031B000012805D0022803D0032801D0072070473A -:1031C00008700020704706207047002807D00128AB -:1031D00007D0022807D0032807D007207047002017 -:1031E00004E0112002E0212000E0312008700020DE -:1031F000704738B50C4605004FD06946FFF7CBFF46 -:10320000002822D120880321890288436946097851 -:103210008907090D084320806946681CFFF7BBFF3A -:10322000002812D1218803200003814368460078DA -:103230008007800C01432180A8784007820F20205E -:10324000012A03D0022A03D0072038BD814300E0C1 -:103250000143218088B20105890F08D0012189032B -:103260008843A9780907C90F89030843208080B2E1 -:103270008104890F0AD0A9784004C906C90F400CFF -:10328000C903084320808004800F02D120884004B5 -:1032900003D52088402108432080002038BD70B528 -:1032A00004460020088015466068FFF7A2FF00284A -:1032B00015D12189A089814210D861688978C90710 -:1032C00008D001214902884208D8491C18F0EEFCB8 -:1032D000298009E0FF21FF31884201D90C2070BD0F -:1032E000FF30FF3003302880002070BD10B5137808 -:1032F00004785B08E4075B00E40F23431370FD24AC -:1033000023400478A407E40F640023431370FB24D4 -:10331000234004786407E40FA40023431370F724C8 -:10332000234004782407E40FE40023431370EF24C0 -:1033300023400478E406E40F240123431370DF24C0 -:1033400023400478A406E40F64012343137000783B -:10335000BF244006C00F234080010343137000299F -:1033600006D00878C10701D1800701D5012000E00F -:103370000020C0015906490E0843107010BD30B539 -:103380000A8803239B0204889A4323059D0F02D1D8 -:10339000A3049C0F01D09B0F00E001239B021A4362 -:1033A00003230A801B039A4303889804840F02D1E5 -:1033B0001805830F01D0800F00E0012000030243B5 -:1033C0000A8030BDF3B593B00D000FD013980028DC -:1033D0000FD01221284618F05DFC03AAFF2101201E -:1033E00003F0B1F80024264637467AE0102015B0E5 -:1033F000F0BD0720FBE76846807D01280BD16846B9 -:10340000818A0520C002081A10D0012810D0022895 -:1034100012D0032812D0042C14D0052C15D113E09F -:10342000022900000128000003300000012400E010 -:1034300002246846468A08E0032406E0684604241D -:10344000478A02E0052400E006246846418A139872 -:10345000814246D12C74002E41D00DAA0EA9052020 -:1034600002920191009010230022FF21304603F0C8 -:103470000BF9002823D16846808E2A46C0B20EA9D7 -:10348000FFF7FBFB00281AD1AE81002F27D00DA932 -:10349000052008AE02910090132300220196FF211F -:1034A000384603F0F1F8002809D16846808EF11CF7 -:1034B000C01EC0B22A1DFFF7E0FB002801D0032088 -:1034C00095E708A88178427808021043E881062C25 -:1034D00005D16846807DA8726846808A28810020D0 -:1034E00085E703A803F038F8002884D0FFF7D9FD5A -:1034F0007DE7002805D0FA4A012903D0022903D02C -:1035000003207047518800E09188814201D100205A -:1035100070470720704770B50C4605461C212046B1 -:1035200018F0B8FB00202080002D08D0012D04D019 -:10353000ECA1F14818F0DBFC70BD062000E005208E -:10354000A07070BD70B592B01546064601206A465F -:10355000107110745374084608300395029048881F -:103560009082FEF71AFA040019D065801720694688 -:103570008883203600940AAB7178023307AA01A829 -:103580000CF00BFB06466078000701D5FEF7E6F964 -:10359000002E0AD03046FFF7ECFD12B070BD1321AB -:1035A000284605F041FF0320F7E708A80090684689 -:1035B000838B04220121284607F028FEEDE770B531 -:1035C00006468AB000200D4607900590069003A994 -:1035D000049005240246029101901023009429468C -:1035E000304603F051F800280DD108A804A9009135 -:1035F000029001946846838900222946304602F0F1 -:103600005FFE002801D0FFF74CFD0AB070BD10B579 -:103610000CF0C9FC10BDF0B589B000260546059632 -:1036200000780C460827030018F08FFD0CFD070CEE -:103630003A0B77779EC2FCD8E8FD68680A38FEF737 -:1036400025FB0DE1A888002380B201220321009010 -:1036500008F0E7FA0290002C04D0A748A1A16E3030 -:1036600018F045FC0298002804D15B209DA1C00001 -:1036700018F03DFC0298009908300BF0C3FEFEF7ED -:103680008CF9040007D0607838436070009860803F -:10369000FEF764F9E6E01321009805F0C5FEEFE0BF -:1036A000002C04D194488FA1853018F020FC60884C -:1036B00000230122032108F0B4FA0090002804D16D -:1036C0008D4888A1883018F012FC009900200880ED -:1036D0002A7994461EE0C3005B199B6807936B46EA -:1036E0009B8B1A0708D5DA0606D56046C20050192A -:1036F0004038C08F088006E05B0409D50871C2001D -:103700005019C08848806078384360700226A7E06E -:10371000401CC0B28445DED8A2E0E8886946088033 -:103720000090002C04D174486EA1983018F0DFFB93 -:103730002878062814D10098C00B11D06088002387 -:103740000122032108F06DFA060004D16A4865A140 -:10375000A23018F0CCFB00203071A88870803BE0CC -:103760006078384360707BE0002C04D162485DA132 -:10377000B43018F0BCFB608800230122032108F05C -:1037800050FA0090002804D1192056A1400118F0E9 -:10379000AEFB009808300CF058FC0121484002D1E3 -:1037A000E888C00B5CD0009861880226C180D7E70A -:1037B000002C04D150484BA1D03018F098FB608801 -:1037C00000230122032108F02CFA002804D1CF2085 -:1037D00044A1800018F08BFB0226C1E7002C04D125 -:1037E000454840A1DC3018F082FB022661880122A6 -:1037F0002046FEF75CFA01200590B1E7A889002376 -:1038000080B201220321009008F00BFA0746002C39 -:1038100004D0394833A1EE3018F069FB002F07D1EE -:1038200030A101E00FE016E06B20C00018F05FFB54 -:1038300068680290288969468881012202A9009857 -:10384000FEF751FA0CE0002C8AD12B4825A1F93063 -:1038500018F04DFB84E7284822A1FE3018F047FB02 -:10386000002C0DD0607800070AD50598002807D1F4 -:10387000842020702046582229460830FDF7A4FCF9 -:10388000304609B0F0BDF7B50C460546007A224631 -:1038900088B00A320292921C04920027811E1632CE -:1038A0003E4601920B0018F050FC08F605F548481A -:1038B0008DD2F4F5688800230122032108F0B1F9C4 -:1038C0000190002804D1072006A1C00118F00FFBC9 -:1038D00001980088002811D05227072600E1000037 -:1038E0009C1400207372635C67617474735F636F10 -:1038F00072652E63000000006902000051271E2639 -:10390000002C7DD06888A0800120A07101980299C8 -:103910000079C0004019C089FFF754FD002870D11C -:1039200001980079C0004019C08920810198007970 -:10393000C0004019408AA083F2E0698A00910628FD -:1039400020D1E889C00B1DD008462230512786B20D -:10395000002CD6D0A8890499FFF734FD002874D133 -:103960006888A0800220A071A88920810120A0720F -:10397000288AE083009820846969009A019818F0E9 -:103980002CF9CDE008462030502786B2002CB8D064 -:10399000A8890299FFF716FD002856D16888A080F3 -:1039A000A889E080287A06280AD002202072288A76 -:1039B000A0830098E083204669692030009ADEE702 -:1039C0000120F3E7688800230122032108F029F988 -:1039D0000690688A00900698002804D17D20FD4951 -:1039E000C00018F084FA069808300CF02EFB012174 -:1039F000484002D1E889C00B26D00098223001E06F -:103A000073E022E0512786B2002C78D06888A0802D -:103A1000A8890499FFF7D6FC002816D10220A071CE -:103A2000A88920810420A072288AE083009820843D -:103A30006969009A019818F0D0F806990020087179 -:103A40000698A98941806BE003200BB0F0BD68881F -:103A500004F0AFF90190688800230122032108F0E7 -:103A6000E0F800900198002803D1DA49DA4818F00C -:103A70003EFA0098002804D1D748D649401C18F0D7 -:103A800036FA0098D549C088884205D051272226A9 -:103A900004E01EE03FE035E050272026002C2ED029 -:103AA0006888A080502F07D00220A0712146287B73 -:103AB0000831FFF730FD33E0287BA11DFFF72BFD18 -:103AC0006A88002300990198FFF73CFD0028BCD1CB -:103AD00026E0C349A889C988814207D15427062610 -:103AE000002C0CD06888A0801AE008E05327082634 -:103AF000002C04D06888A080A889E08010E00A9893 -:103B0000068013E055270726002CF8D0A889A0804E -:103B10000020A07104E0B048AE494E3018F0E7F93B -:103B20000A98002C068001D02780668000208CE750 -:103B3000AB4900200870704730B585B00C4601F0E5 -:103B4000ACF905460020208020716080401EE08096 -:103B50002046294608300BF049FC6A4629460120D8 -:103B600002F0F1FC102412E06846808800070ED5B0 -:103B70006846C0882946FFF722FD68468188FF23F2 -:103B800021438180C0882946019A02F007FE6846D9 -:103B900002F0E2FC0028E7D005B030BD0A4601463D -:103BA00010B5104608300BF035FC10BD70B5002381 -:103BB00005461A46032108F034F8040004D186486B -:103BC00084498A3018F093F92046294608300BF0D2 -:103BD00019FC70BDF0B591B00C46074604F0E9F849 -:103BE000050005D02878222804D2082011B0F0BDA5 -:103BF0007C48FBE700231A460321384608F011F8F9 -:103C00000646002C02D0A08800280CD0012069466E -:103C100008710220087400204874002C05D0A08888 -:103C20000883206802E00920E0E708830590304619 -:103C3000083003970290FDF7B0FE040018D06780AB -:103C4000172069468883203500940AAB69780233CF -:103C500007AA01A80BF0A1FF05466078000701D56F -:103C6000FDF77CFE002D09D02846FFF782FABDE75C -:103C70001321384605F0D8FB0320B7E708A80090C9 -:103C80006846838B04220121384607F0BFFA0021E1 -:103C9000C943F180AAE7FFB585B00E9E7788384604 -:103CA00004F087F8054600231A460321384607F03A -:103CB000B8FF0446002D04D147484649F13018F0BA -:103CC00016F9002C04D144484249F23018F00FF99B -:103CD0000834089869460394C1C105A80DC8203569 -:103CE00069780BF0C9FBCCE5F0B50446002099B02B -:103CF0000D4601460D9010A88181164601818180F4 -:103D0000374A68469180018510A80180684601877E -:103D1000818581841078012808D0022806D00328E4 -:103D200004D0042802D0082019B0F0BD2E488442E7 -:103D300079D3012189042D4F8C4201D3BC4272D327 -:103D4000294885426FD301208004854201D3BD42BA -:103D500069D36068002813D02349884263D30121C6 -:103D60008904884201D3B8425DD3608921898842A1 -:103D700003D801225202914201D90C20D4E70D90C0 -:103D800016AA0EA92846FFF78AFA0028CCD168683F -:103D900080784007800F022809D16846008F800490 -:103DA000800F04D02869002801D0B8423BD30AA96B -:103DB0002069FFF71EFA0028B6D1206900281AD022 -:103DC000607880076846008D12D58004800F74D01B -:103DD00011E00000E438000014040000FFFF0000C0 -:103DE0009C1400200230000000D0010000280020B8 -:103DF0008004800F61D16846008D810615D580044E -:103E0000800F606804D000280FD0B8420BD301E0C7 -:103E100000280AD0FE49884205D30121890488423E -:103E200003D3B84201D210207EE709A96069FFF7E9 -:103E3000E0F90028A2D16069002808D06846808C8B -:103E40000105890F012938D18004800F35D00BA9D5 -:103E5000A069FFF7CEF9002890D16846808C8006D3 -:103E60002BD46846808D810627D4A169002906D00D -:103E70000105890F012920D18004800F1DD0E06841 -:103E8000002804D00078002817D01C2815D204AAD6 -:103E9000611C2046FFF72AFA0120800210A9088041 -:103EA000012769468F73DB48888104AA033217A96A -:103EB0002868FEF708FF002801D0072034E710A883 -:103EC000007F15A9C01CC2B200200C920190FF32E5 -:103ED000009003460291FF3203A80332109902F0CA -:103EE0008AFA002828D110A9888A0F902A8929697E -:103EF000C94801910092029010A90A8B6B89286829 -:103F00000E9902F078FA002801D001464DE0C2482F -:103F10000025001F818868464174090A81740521C3 -:103F200004A86A4623C210A82A46FF21808A0C9B57 -:103F300002F0C6F9002802D0FFF7B3F8F4E66846AD -:103F4000007C0322C10900209202904301229202C8 -:103F50008018149000292CD0014610A801806846D2 -:103F60002921877309028181058608A8007C002326 -:103F7000410860784900C007C00F014308A80174D8 -:103F8000FD2001406078A54A8007C00F4000014332 -:103F900008A801740CA9022001910090029503A8C1 -:103FA000109902F028FA010003D00F9800F079FF71 -:103FB000BAE66068002829D0206900280DD10AA936 -:103FC0000EA8FFF7DCF96078800706D46946088DF3 -:103FD000032109038843694608858E49684687732B -:103FE000FE3181818D492089891E17F05FFE62684C -:103FF0000D9811AB0192009002930A46002303A88A -:104000000A9902F0F8F9002800D07EE72078C1066E -:1040100001D480062AD568460586606900280DD13E -:1040200009A90EA8FFF7ABF96846818C032080022E -:104030008143012080020918684681846946888C82 -:10404000C82108436946888472488F73FF3088818D -:1040500012AA0CA9022002920191009000236F4A3B -:1040600003A8099902F0C7F90028CED12078C0072B -:1040700029D068460586A06900280DD10BA90EA895 -:10408000FFF77DF96846808D03218902884301216D -:1040900089024118684681856846818D4020014328 -:1040A0006846818587735E49818113AA0CA9022025 -:1040B0000292019100900023584A03A80B9902F044 -:1040C0009AF90028A1D1E068002829D010A81499F5 -:1040D0000180534968468773491C8181E16808A8BB -:1040E0000A78027449784174E06841224188684640 -:1040F0004186E0680023017908A80175E068D200D4 -:10410000C18808A84175090A81750CA8072101908A -:104110000091029503A8109902F06DF90028A4D12E -:104120003D480321001F0170002E0AD08088308096 -:1041300010A88088708010A80089B08010A880899D -:10414000F0800020F0E530B501248BB015460B4619 -:10415000012802D002281CD104E06846052184739E -:10416000C90203E02B4968468473891E8181002BB4 -:1041700012D00321002089028843012189024018BE -:104180006946888405AA04A91846FEF79CFD002804 -:1041900004D007200BB030BD1020FBE76A46127C2C -:1041A0001D480092801E05A9FF3201910290FF3246 -:1041B000002303A80332099902F01DF9002802D058 -:1041C000FEF76FFFE6E71448001F002D01D041887D -:1041D000298004700020DDE770B592B00446012606 -:1041E00008A886700F4968460184002208A9304655 -:1041F000FFF7A9FF00284BD12078074DC007002406 -:104200002D1F002842D01C21684617F045FD0BE009 -:1042100000D0010003280000A014002003020000C9 -:10422000032900000118000068460178202001439E -:104230006846017008A88670FE496846018411949A -:104240000794817FF92001406846891C817700200E -:1042500001466846017700200146684641770421FF -:104260008185C485018607A80A9011A80D9008A829 -:1042700009900EAA09A96846FFF736FD002807D164 -:104280006846008FE8806846808F28812C70002067 -:1042900012B070BDF7B5E84900260A789EB0012A31 -:1042A00004D0022A02D0082021B0F0BD4A88824200 -:1042B00001D00620F8E71F98824201D10720F3E7DA -:1042C000012210A98A75DD488882002003239B0201 -:1042D000014699439302CB1810A90B8669468A813F -:1042E000D74ACA8118A9887110A9888419A904918C -:1042F0006946CA820690FF20087503A802F04FF9AC -:1043000000242546274608AA052103A802F04AF9F9 -:10431000002810D082286FD1002C6FD0002D6DD0D6 -:1043200010A88480C5800021017418A8807B11AC7E -:10433000012865D06DE008A88079002F21D00128E0 -:1043400057D16846818CBD4881421CD113AA0DA962 -:1043500005206B4607C36846408C10230022FF21CE -:1043600002F092F9002868D110A88089042801D0B1 -:1043700006284CD16846818E1F98814239D10F2082 -:1043800092E7012835D16846808C0521C902884210 -:1043900002D0491C88422CD1A74841886846408CED -:1043A000814201D1012700E00027002C01D0002D1F -:1043B00010D01F9988421CD113AB0DAA05216E465F -:1043C0000EC6044610230022FF2102F05DF90028EA -:1043D00033D101E035460CE010A88089022801D0D5 -:1043E000102814D1C0B21BAA0DA9FEF746FC002864 -:1043F0000DD16846468C86E71FE0FFE7052053E7AE -:1044000014A91BA8221DFEF75EFC002801D0032082 -:104410004AE710A8007C0023001DC2B210A8027455 -:10442000209802900194009215A81C9901F0E3FFD6 -:10443000002802D1804902220A70FEF732FE33E7DB -:1044400010B50B46401E86B084B203AA0021184660 -:10445000FEF74CFF04AA052103A8029201910090E7 -:1044600001230022FF21204601F02AFF044668466E -:10447000008A012803D07349734817F038FD20469D -:10448000FEF70FFE06B010BDF0B56B4F044638784E -:1044900087B00E46032804D0042802D0082007B0B5 -:1044A000F0BD04AA03A92046FEF7F9FE0500F6D1E7 -:1044B000606880784007800F02280CD168468089A8 -:1044C0008004800F07D02069002804D05F4988420B -:1044D00001D21020E3E7208905AA6B46216907C3B2 -:1044E00069460A8A63892068039901F084FF0028DD -:1044F00002D0FEF7D6FDD2E7002E02D06846808AB1 -:104500003080042038702846C9E738B50C000546CD -:1045100009D000236A46FF2102F018F9002804D0D0 -:10452000FEF7BFFD38BD102038BD69462046FEF7B6 -:1045300060FE0028F8D1A078FF21C307DB0F2846D2 -:10454000009A02F02BF9EBE73EB50C0009D002AB64 -:104550006A46FF2102F0FAF8002804D0FEF7A1FD18 -:104560003EBD10203EBD0321204617F093FB684658 -:10457000008801A90005800FFEF727FE00280BD157 -:104580006846007920706846008801A98004800F81 -:10459000FEF71BFE002801D003203EBD68460079CF -:1045A0006070A278EF20024068460088C10B0901C4 -:1045B0000A43F7210A404104C90FC9000A43A27007 -:1045C000F9210A40800601D5022000E001204000C8 -:1045D00069460243097A50084000C907C90F0843D9 -:1045E000A07000203EBD7FB514460522019203ADA8 -:1045F000029500930A462388FF2101F061FE694677 -:1046000089892180FEF74DFD04B070BDF3B5002708 -:1046100099B068460C4607873D4600292DD0E068D2 -:10462000002806D0A068002827D001886A46118794 -:1046300007800DE0052A00009C14002002280000DD -:10464000FFFF0000E4380000BF0600000028002043 -:10465000199803F0AEFB002812D0007822286FD3FF -:10466000199800F01AFC002300901A4603211998AB -:1046700007F0D7FA06000AD104E010201BB0F0BD05 -:10468000FE48FBE78D20FE49000117F030FCA078C2 -:10469000012803D0022801D00720EFE72088002856 -:1046A00008D0401E80B203AA009901F04CFF0028F8 -:1046B00058D11DE0F148401CE0E76946498A22884C -:1046C00091420BD26846807D0025012810D16846B2 -:1046D000808AEC4988420BD1012509E0914203D13F -:1046E000002D2AD06D1C01E0022D0BD0032D04D229 -:1046F00003A801F031FF0028DFD082281BD000285A -:1047000030D11EE06946897D0129F1D16946DD4B32 -:104710008A8A5B1ED11A9A420FD005DCDA48101A39 -:104720000BD00128E4D108E0012906D0FF39012986 -:10473000DED10325E1E7022D14D10D2080029DE793 -:104740002DE0E068002814D00EA905220291019204 -:10475000009069460B8FA2882088FF2101F0B0FDF0 -:10476000002802D0FEF79DFC88E76846A168008F0C -:1047700008806846008AC00601D5C4487EE70798CD -:10478000002803D06846008B022801D0032075E77B -:104790000798A1780078012903D0800710D4082059 -:1047A0006CE7C007FBD000220721199807F044F8F6 -:1047B000002802D00725022004E0B048801C5DE7F5 -:1047C0000225032008A90870218868468185199868 -:1047D00008360A90099617216846818712AB023382 -:1047E0000FAA052108A800970BF0D7F9002802D0DE -:1047F000FEF7BFFC42E710A800906846838F0422B2 -:104800002946199806F002FD38E770B506461546A8 -:104810000C460846FEF702FC002804D12A46214631 -:104820003046FFF790FC70BD10B5FFF733FD10BDAB -:1048300070B51E4614460D0014D0002C12D06168CD -:1048400000290FD00121FEF754FE002809D120686D -:10485000FEF7E4FB002804D1324621462846FFF744 -:1048600043FA70BD102070BD70B515460C000ED017 -:104870000221FEF73EFE002808D12068FEF7CEFB9D -:10488000002803D129462046FFF7FEFD70BD102009 -:1048900070BDF8B50D4614467D4902468C4226D3BC -:1048A0006068002808D07B4B984220D301239B04EA -:1048B000984201D388421AD3104600F0EEFA064619 -:1048C000284600F0A6FA00280CD16068002810D114 -:1048D00000236A463146284601F038FF002802D0FE -:1048E000FEF7DFFBF8BD68460088800601D4102083 -:1048F000F8BD6188224628466368FFF774FEF8BD5C -:10490000F7B5634D86B01446AA4202D2102009B012 -:10491000F0BD00F0C2FA01460390002305AA0798F3 -:1049200001F014FF002822D16846808AC00601D514 -:104930005648ECE704A80026052702900097019648 -:104940006288554B0399079801F09EFE00280ED10E -:104950006168A94208D30296019100972388628872 -:104960000399079801F090FE6946098A2180FEF7B5 -:1049700098FBCCE7002907D0484B0A881B899A424C -:1049800002D83E48401C704740E610B586B004236C -:104990006C46A382414BDC88002C07D01B898B42DC -:1049A00001D2914204D93548401C6BE5062069E5E7 -:1049B0006B4619825A820021009101911C800221CC -:1049C000997005A9029104A903916946FFF71EFE9B -:1049D00058E5F3B50C4685B0812069460873002C74 -:1049E0001BD0059803F0E5F9070018D03878222885 -:1049F00068D3059800F051FA04900022012105982F -:104A000006F01AFF00280CD000231A46032105984F -:104A100007F007F905000AD105E010203FE5174827 -:104A20003DE511203BE516491D4817F060FA284680 -:104A300008300AF009FD06462078012803D0022834 -:104A400037D007202BE5A18803AAFEF75DFB0028DD -:104A5000E4D1B00736D56846007B002834D1A07970 -:104A6000C00731D0E068002205216B4607C3638987 -:104A700022896888049901F023FC13E002300000C9 -:104A8000E438000003280000002800000134000082 -:104A90000028002000D00100FFFF00009C1400202F -:104AA000670A00006946087300280DD0FEF7F9FA7E -:104AB000F5E4A18803AAFEF727FB0028AED1342035 -:104AC000064201D10820EAE46846037B29463846BD -:104AD000059AFEF737FDE2E4FFB597B0002001909C -:104AE0001F4615460C460E46179803F062F900283B -:104AF00004D00078222803D20820BFE5F048BDE5A5 -:104B0000B80801D00720B9E5032F00D10027179876 -:104B100000F0C3F90890002C1AD0022D7FD3E94889 -:104B200084427CD361190091012902D0491E81423F -:104B300075D3AD1EAAB22146E3480BF005FB0099E0 -:104B40001E394B7F0A7F19021143884267D1ADB2EB -:104B5000DE48B90702D50189491C00E0012189B26C -:104B60000091F90701D0078900E0D74F03AA0899FF -:104B7000009801F0E8FC0DE0F078B17800020843FD -:104B800010284CD80199091D401880B20190A84204 -:104B900045D82618002E60D070783178000208437E -:104BA00000998842E8D358E06946098A0A0754D533 -:104BB000002C3FD0019AA618121D92B20992F378E8 -:104BC000B2781B0213439C46102B28D8099A6244E2 -:104BD000AA4224D87278337812021A4390421ED126 -:104BE000C8061ED509980AAA052120186B4607C3D6 -:104BF000707831780002084363460022089901F07A -:104C00005FFB002803D0FEF74CFA37E507E0F078A9 -:104C1000B178000208436946098D884201D00B2013 -:104C20002CE5F078B178000208430999401880B269 -:104C3000019006E0C90604D50899FEF7C0FC0028DB -:104C4000E3D16946088A1021884369460882488A68 -:104C5000FF23049A089901F0A1FD03A801F07CFC50 -:104C6000002803D16846408AB8429DD900231A46DD -:104C70000321179806F0D5FF040003D19449954805 -:104C800017F035F920880028BFD0012108A801704D -:104C90000173002646732188684601862046083045 -:104CA000099017980A90FCF778FE05001BD017981A -:104CB000688017206946888010AB023301AA05215D -:104CC00008A800950AF069FF07466878000704D530 -:104CD00080487F49223017F00AF9002F09D0384662 -:104CE000FEF747FACAE41321179804F09DFB03204E -:104CF000C4E40EA800906846838804220121179816 -:104D000006F084FA00288BD12680B7E4F0B50024A1 -:104D10008DB01F4615460E46002A04D0B90804D0AF -:104D200007200DB0F0BD1020FBE7032F00D10027B6 -:104D300000F0B3F803906549B80702D50889401C14 -:104D400000E0012080B2FA0701D00F8900E05E4F39 -:104D500006AA039901F0F7FB38E06946898B090739 -:104D600034D504AB05210022029300910192564BE9 -:104D7000039901F089FC002821D1002E21D06A4638 -:104D8000128A2988A2183019121D914232D369461D -:104D9000CA8B0270120A42700A8A8270120AC270AA -:104DA00004A90522001D0092029101906946C88B5A -:104DB0000B8A0022039901F067FC002801D0032030 -:104DC000AFE76846008A2018001D84B206A801F0EB -:104DD000C3FB002804D0822806D0FEF762F9A0E7C2 -:104DE0006846C08BB842B8D9002E0ED02988A01CC6 -:104DF000814201D20C2094E72246314632480BF022 -:104E0000A3F931190870000A4870A41C2C800020F6 -:104E100087E700B585B06946FEF7D4FA00280AD1C5 -:104E20006846007C030017F090F908052F2F2F2FFC -:104E300008080531032005B000BD684680780128C8 -:104E400007D1684600880321C902401A1CD00128F6 -:104E50001AD068468079012806D1684680881521D5 -:104E60004902401A05280FD96846807A012812D1D4 -:104E70006846018929200002081A05D0022803D0BB -:104E8000032801D0042806D10F20D4E7872012A1DF -:104E9000800017F02CF80020CDE710B506F0B4FE26 -:104EA00010BD10B50C4601F021FB002803D00AA16B -:104EB0000E4817F01CF82046FEF7F3F810BD00006E -:104EC0000230000000280020FFFF00009C1400209A -:104ED000E4380000220B00007372635C6761747435 -:104EE000735F636F72652E6300000000AA06000006 -:104EF000F8B500780C46164610340E36069F022888 -:104F000009D0032836D005287ED0FF20F6A1E53051 -:104F100016F0EDFFF8BDCD890A2068430E301880E9 -:104F200031203880002AF5D0087B9581801FC7B2D8 -:104F30001AE020886168308048780A7800021043BF -:104F4000F080C8788A78000210433081B21C38465D -:104F5000091DFDF792FE002F01D0002802D000208D -:104F60003071708008340A3628466D1EADB20028B4 -:104F7000DFD1F8BDCD890A2068430E301880322079 -:104F80003880002AF5D0087B9581401FC7B243E0E6 -:104F9000616822880878F2803279C307520852008B -:104FA000DB0F1A43FD231A408307DB0F5B001A4314 -:104FB000FB231A404307DB0F9B001A43F7231A40D9 -:104FC0000307DB0FDB001A43EF231A40C306DB0F96 -:104FD0001B011A43DF231A408306DB0F5B011A43D0 -:104FE000BF231A404306DB0F9B011A433271C009ED -:104FF00070718A784B7810021843308132463846F7 -:10500000C91CFDF73AFE00E00CE0002802D00020A9 -:10501000B070308008340A3628466D1EADB20028C4 -:10502000B6D1F8BD087BCD89801E86B230460830E7 -:1050300068431030188034203880002AF1D0174699 -:1050400095811037E800D681C01900900DE02088C6 -:1050500038800098786032466168009816F0BDFD8F -:105060000098083480190837009028466D1EADB2AC -:105070000028ECD1F8BDFFB581B00A9D1E460C4654 -:10508000002A05D0607AFF300130D080E08910819D -:1050900001980E270078030017F057F80B7E0719C8 -:1050A000293541536C7878787E000092087B082877 -:1050B00005D0032803D091A1954816F018FF37803A -:1050C00030200FE000990020888105B0F0BD0092EB -:1050D000087B042804D08E4888A1143016F007FFFE -:1050E00037803120288000980028EBD1EDE700922E -:1050F000087B042804D0932080A1800016F0F7FEDE -:1051000037803220EEE70092087B022804D08048E6 -:105110007AA13A3016F0EBFE37803320E2E7087BC5 -:105120001746042804D07A4874A14C3016F0DFFEEC -:105130001020308034202880002FC6D00020B88175 -:1051400016E0207B1746052806D0062804D07048B4 -:105150006AA1603016F0CBFE122030803520288006 -:10516000002FB2D0E089B8810020388201984088B1 -:10517000F881AAE70092087B072804D064485FA161 -:10518000713016F0B4FE37803620ABE73346009519 -:10519000019800F00EFC98E72F2053A1000116F0B3 -:1051A000A6FE92E770B50C46054602F002FE002806 -:1051B00004D00078222803D2082070BD554870BD65 -:1051C00000231A460421284606F02BFD2060002803 -:1051D00001D0002070BD032070BDFFB58BB00D461F -:1051E00007461720694608850E98032614460028AE -:1051F00005D10EA93846FFF7D5FF002834D1002D80 -:105200000BD000220321384606F016FB002834D0CC -:105210000E980078002830D108E02078092819D0AD -:105220000F2823D030A13C4816F061FE0E98A760ED -:10523000801D03AA606002320AA9204600F00FFC1C -:10524000002827D0030016F080FF071A1823232117 -:105250001C1E2300072600223146384606F0ECFAD1 -:105260000028E3D12B48801C0FB0F0BD00220321A1 -:10527000384606F0E1FA0028D8D11120F4E70020E2 -:10528000F2E70820F0E72348401CEDE70720EBE7B2 -:105290000320E9E701A800906846038D0422314607 -:1052A000384605F0B3FF0028DED1002DDCD00E9982 -:1052B0000D70D9E730B587B01D460C46002A11D0D5 -:1052C000042369460B7013888B815288CA81A278A7 -:1052D0008A7422880A8200236A462946FFF77DFFE6 -:1052E00007B030BD1020FBE77372635C67617474B4 -:1052F000635F636F72652E63000000007372635C0E -:1053000067617474635F636F72652E6300000000F1 -:1053100025020000023000004F030000F3B581B009 -:1053200001980C4600780826030016F00EFF125F65 -:1053300047471B134B0A0A0A0A0A0A0A0A0A0A0AF8 -:105340000A5F002C02D1F849F84808E06078304341 -:1053500060703CE0002CF9D1F448F349083016F0B5 -:10536000C6FDF3E7019800238088012287B204215B -:10537000384606F056FC0546002C04D07520EA4954 -:10538000C00016F0B4FD002D04D1E848E649143001 -:1053900016F0ADFD3946A81D00F058FBFCF7FDFAEC -:1053A000040006D06078304360706780FCF7D6FA5E -:1053B0000FE01321384604F037F815E0DB48DA49EE -:1053C000283002E0D948D8492D3016F090FD002C45 -:1053D0000AD06078000707D5932020702046582215 -:1053E00008300199FBF7F0FE0020FEBDCF48CE4902 -:1053F0003130EAE710B500210170801D00F023FB79 -:1054000010BD0A4610B50146901D00F027FB10BDE7 -:1054100070B5002305461A46042106F002FC04007C -:1054200004D1F920C049800016F061FD2946A01D75 -:1054300000F00CFB70BDF7B5054684B00C460020AB -:105440006946088188806F88034601220421384616 -:1054500006F0E7FB060004D1FD20B349800016F0FA -:1054600046FD002C03D0A7800020E0802081297A0F -:1054700020461230C91E142700900B0016F065FE5E -:105480000FFEFDFC3809A95E657A2FB2C9E991913A -:10549000FC003078012804D0A3497020143116F0A4 -:1054A00026FDA9896A46C8000E3090803020108100 -:1054B000002C13D0A18100200DE0C1003279091920 -:1054C0000A747288CA8182005319DA894A821A8A58 -:1054D000401C8A8280B2A1898142EED8F1E002A804 -:1054E000009001AB22462946304600F02BFAE8E056 -:1054F0003078042804D08C49BD20143116F0F7FC14 -:10550000A8890622014650436A460E309080332017 -:105510001081002CE2D0A18100200BE00621414344 -:105520004F190919FA89CA81BA7C8A743A8A401CCF -:105530000A8280B2A1898142F0D8C2E03078062880 -:105540000BD079491431D72005E03078062804D0F3 -:105550007549EB20143116F0CAFCE889694612300F -:10556000888035200881002CB8D0A989A181718854 -:10557000E18126E03078072804D06B49FF20143100 -:1055800016F0B5FCA8896A4601460E309080362098 -:105590001081002CA2D0A1812046AA890E30296951 -:1055A00054E0E8896946123080B2382288800A8146 -:1055B000002C7ED0A989A181287A102807D0022149 -:1055C000A173E9892182EA89296900983EE00121D5 -:1055D000F6E702A8009001AB224629463046FFF7C5 -:1055E00087FC6EE03078082805D04F49FF20143141 -:1055F000EE3016F07CFC6846372187800181002C54 -:105600005FD0A989A1810020608220820120A0733F -:1056100057E03078092805D04349FF201431FF3086 -:1056200016F065FC288A6946143088803720088186 -:10563000002C46D00421A173A989A181E989218286 -:10564000298A618220462A8A1430696916F0C5FACF -:1056500037E030780A2804D033493548143116F041 -:1056600046FC6846372187800181002C29D005211E -:10567000A1730020A08102E01EE003E00CE0208284 -:1056800060821EE002A8009001AB22462946304607 -:10569000FFF7F1FC15E00CE00D2069463922888007 -:1056A0000A81002C05D00120E08000202081207399 -:1056B00007E00699088019E01C481B49A43016F041 -:1056C00016FC6846069980880880002C0ED0684633 -:1056D00000892080684680886080287A032805D069 -:1056E000102803D0112801D000203070002007B00E -:1056F000F0BDF7B5568815460F46002382B01A460E -:105700000421304606F08DFA040004D1074806490A -:10571000C43016F0ECFBA41D33462A4639460094EB -:10572000029800F022FBD0E4E8520000950300004C -:1057300013020000F7B58CB00D46144607A90C986B -:10574000FFF730FD002812D1B64E0127002C0FD0F4 -:105750000321684601701021818208A80246069044 -:10576000204605A9FDF7AFFA00280BD007207BE5FE -:105770000821684601708581C68105218774C902A8 -:1057800001820BE00798A178017121884180684669 -:1057900005218774C90201828581C68102460121E3 -:1057A000079B0C98FFF719FD5EE508B501236A46D3 -:1057B00093709D4B13800A4602236946FFF77AFDDA -:1057C00008BD08B501236A469370974B5B1C138094 -:1057D0000A4603236946FFF76DFD08BD00B587B093 -:1057E00000290CD002236A4613700B8893814988E4 -:1057F000D18100230421FFF7F0FC07B000BD102089 -:10580000FBE710B5002903D00523FFF753FD10BDBA -:10581000072010BD70B588B00D461446064607A98E -:10582000FFF7C0FC00280DD1002C0DD006216846E2 -:1058300001708581C481079B02465C800621304649 -:10584000FFF7CBFC08B070BD05216846017085816B -:10585000F1E710B588B000290BD007246B461C7007 -:105860009A81049100236A462146FFF7B6FC08B0EE -:1058700010BD1020FBE770B50024172288B0002966 -:1058800014D00D782B0016F060FC062305051904D2 -:105890001B231522D21E93B2CA88002A02D08E681A -:1058A000002E03D09A4203D90C20CBE71020C9E781 -:1058B000042D05D08A88002A0AD101E00620C1E71C -:1058C000012D11D0022D05D0042D18D0052D23D087 -:1058D0000720B7E709236A4613704B889381CB886A -:1058E000D381896804911DE00C236A4613704B88AC -:1058F0009381CB88D38189680824049112E00D2319 -:105900006A4613704B8893818B88D381CB8813822E -:1059100089680924059105E00E236A4613704978C9 -:1059200011730A2400232146FFF757FC8AE700B5CC -:1059300087B00F236A461370918100231946FFF741 -:105940004CFC5AE7FEB50078089D1C4616460F46EB -:10595000012803D03549912016F0C9FAF889C00012 -:105960000E30208030202880387B001FC0B201908C -:10597000002E1DD0F889B081002516E0E8008419BA -:10598000C0190090224641690E320198FDF775F961 -:10599000002802D000202074E08100986D1C008A4D -:1059A00060820098ADB2408AA082B089A842E5D852 -:1059B000FEBD70B514461425049A1D80372313804C -:1059C000002C0ED0CA89A2810022628200780828A9 -:1059D00008D0092810D00A2819D01449144816F004 -:1059E00086FA70BD087B0C2804D011480F490C388A -:1059F00016F07DFA012008E0087B0D2804D00C4841 -:105A00000A49083816F073FA0420A07370BD087BA9 -:105A10000E2804D006480549001F16F068FA052034 -:105A2000F3E70000FFFF000002280000FC52000026 -:105A3000BB02000010B5FE4B586019721A80C900F5 -:105A400016F02AF910BD00210180704710B5002220 -:105A5000D2430280032006F0F0FD10BD7047F0B580 -:105A60000E460446017801208840F24999B008406A -:105A70000090616815460888EF4A904206D0009A67 -:105A8000002A06D0EB4A521E104202D0012019B063 -:105A9000F0BD009A10430880002D12D0002028701D -:105AA0002178EA1C0027681C01920B0016F04DFBC0 -:105AB00010F30E16233A59616F3CB4B08AB8F2F174 -:105AC000F0F320780B28EBD00420E0E702212970C6 -:105AD000A1890170090A4170032097E0042129700F -:105AE000A1890170090A41700198E1890170090AD0 -:105AF000417005208AE006212970A1890170090AF8 -:105B000041700199E2890A70120A4A70218A017172 -:105B1000090A4171A28AE81DA16916F05EF8A08AFF -:105B2000C01D73E0082129702178082901D11021B6 -:105B30002970A1890170090A41700198E1890170F9 -:105B4000090A41700520308020466A1D02A91030E4 -:105B5000FDF7B9F800287DD169463088097A4018E8 -:105B600054E00A212970A1890170090A41700320BB -:105B70000BE00C212970A1890170090A417001987C -:105B8000E1890170090A4170052030809CE0A089FC -:105B900084464000401C81B2308888425AD305298F -:105BA00058D30E202870002008E0236942009B5A39 -:105BB000521953701B0A401C937080B26045F4D395 -:105BC0003180B9E09A48417A002973D0491E417268 -:105BD000217B4068C9004518A98828680822401818 -:105BE0000838216915F0F9FF02216846017100218A -:105BF000417128680390A98868460181002101A8A5 -:105C0000FFF78CFB0020A880002E00D0308093E0AE -:105C10002978802211432970297840221143297064 -:105C200029788909890112312970A1890170090A2D -:105C30004170E289E81C216915F0CFFFE089C01CA2 -:105C40003080287841063FD5C00975D001216846CB -:105C5000017200E02CE0002141723188091D818130 -:105C60000495E189019808180590001D0690704878 -:105C7000017A68460177002102A8FFF74FFB07462B -:105C800030880C303080022F06D0002F54D065E0D1 -:105C90003DE033E01CE05EE065486946097F42680C -:105CA000CB00D218037A994202D29188002902D0FF -:105CB000042753E02FE0417A491C41721560308877 -:105CC00090800020308049E06168A089888033E0BE -:105CD00029788909890116312970A1890170090A79 -:105CE00041700198E1890170090A4170228A681D9A -:105CF000616915F072FF208A401D46E72878800907 -:105D0000800118302870207B687002207EE7606870 -:105D10000188090401D4052720E0C088A1898842B0 -:105D200001D006271AE01E2028700120308060680C -:105D300001884904490C0180009800280ED03C4895 -:105D400000220088A1688300032006F0D1FB61686F -:105D50002078887007E00020308003276068009971 -:105D600002888A430280384691E6FFB59FB0289D9D -:105D70000E46002805D0172803D82A882E4B9A42B1 -:105D800002D1072023B0F0BD3278530601D4D209E6 -:105D900001D00820F6E700226B461A715A711446AA -:105DA0003278431E1D939BB2189303AB1A93970648 -:105DB000CB1CBF0E1B93821E711C3B0016F0C5F955 -:105DC000209011EE66EE74EEB0EED4EEEDEEECEE59 -:105DD000EBEEEAEEE9EEEEEEE8EEE7EEE6EEE5EE0D -:105DE00090EE05287CD1042168460171A9780172E2 -:105DF000F078B278010211436846418131794171EE -:105E000070788006800E0C282ED009DC801E0300DE -:105E100016F09BF90919661C662166246627660040 -:105E200012282AD00ADC0E2821D01028DAD121E04D -:105E3000A8140020FF710000FFFF000016281FD0EB -:105E40001828CFD11FE02878800701E02878400784 -:105E5000002845DA45E128780007F9E72878C006E8 -:105E6000F6E728788006F3E728784006F0E72878F8 -:105E70000006EDE72888C005EAE72888C004E7E7C0 -:105E800028888004E4E728884004E1E72A7892071C -:105E900026D50328A6D105206A46107148780978CE -:105EA0000002084310811CE129784907F0D5062833 -:105EB00016D3717890B2012902D0022992D101E063 -:105EC000022100E01021189106216A46117100217B -:105ED000118102AF189AB11C0237921C1B921AE072 -:105EE000B3E04A780B7812021A433A80801E891C6C -:105EF0001790BA1C1A911898FCF7BFFE1A991898B7 -:105F0000189A091817986B46801A1A8980B2521C81 -:105F10001A811B9ABF1D8242E3D9002886D1E0E096 -:105F200028780007B4D51D98694682B20720087109 -:105F300000200881701C0A3111E0437807781B02A9 -:105F40003B430B80C37887781B023B434B806F46F3 -:105F50003B89121F5B1C001D92B23B81091D042A64 -:105F6000EBD2002A71D1BCE02978C9066DD5022890 -:105F70006BD3082069460871002048817078087248 -:105F8000844692B2B01C1A9919E089E090E07EE054 -:105F900067E05BE030E025E019E013E0BCE0437827 -:105FA00007781B023B430B80831C4B606346D21A6D -:105FB0006F467B8960445B1C92B27B8108319445BB -:105FC000EDD9CEE7287880063FD5092203E028786E -:105FD00040063AD50A2268460271AA880281189AB8 -:105FE000428107E0287800062FD50B206A46107101 -:105FF00018981081039174E02988C90525D50228D5 -:1060000023D30C20694608710020488170780872FB -:10601000844692B2B01C1A9914E0437807781B02A8 -:106020003B430B80C37887781B023B434B80031DA7 -:106030004B606346D21A6F467B8960445B1C92B208 -:106040007B8108319445E8D98BE763E02988C9044E -:1060500060D501285ED10D2168460171A9880181B2 -:106060003FE02988890455D5052853D30E22694677 -:106070000A71AA880A811B99401F4A78097812027E -:106080000A4369464A818881701D049029E0298865 -:1060900049043FD501283DD10F206946087120E011 -:1060A0002A88120436D44A780B7812021A43EA80FE -:1060B00003282FD332789206920E1B2A26D0112263 -:1060C0006B461A712A880123DB031A432A804A7817 -:1060D000097812020A4369460A81C01E48811B984A -:1060E000039030788006800E1B2809D01D2807D029 -:1060F0000320229906F0A1FA2888C00BC00328804B -:1061000001A82199FFF70AF920463BE610226B46C9 -:106110001A71DCE70724F7E70824F5E700B597B024 -:10612000032806D16A461070019100216846FFF7E6 -:10613000F5F817B000BD000010B58B78002B11D01A -:1061400082789A4207D10B88002B0BD003E08B7921 -:10615000091D002B08D08B789A42F8D103880C884F -:10616000A342F4D1002010BD812010BD052826D007 -:10617000002A02D0012A0DD102E00988090501E0B8 -:1061800009888904890F07D0012918D0022909D06C -:1061900003290ED081207047002A01D003207047C8 -:1061A0000220704703280AD0042808D0002804D011 -:1061B00007E0042803D0022803D005207047002000 -:1061C00070470F20704770B51388054614460B8042 -:1061D00018061DD5FE481022807AA84203D8134322 -:1061E0000B80002070BDA06893430078E840C00792 -:1061F000C00E03430B802078A1788007800D0843F0 -:10620000F44915F053FDA06869430818401C70BD9F -:10621000906870BD37B569468B88138019061BD509 -:10622000EB4C0125A47A9168844209D8FE280FD14D -:10623000D80602D5A5406D1E00E000250D7007E0D0 -:1062400085400C78DB06DB0FAC4383401C430C70AD -:1062500010881021884310803EBDF8B50746C81C41 -:1062600080080E468000B04201D08620F8BD082A82 -:1062700001D90E20F8BDD64D00202E60AF802881B8 -:10628000AA723446E88016E0E988491CE980810654 -:1062900010D48007A178800D0843CE4915F006FD83 -:1062A000206800F0BAFA2989401880B22881381A8B -:1062B0008019A0600C3420884107E5D40020F8BD87 -:1062C000FFB589B09F041646139DBF0C0193099832 -:1062D00000F095FA04000AD02078000609D5BC48E1 -:1062E000817A0A98814204D80E200DB0F0BD0120B9 -:1062F000FBE7224669460A98FFF765FF06900020F3 -:1063000069460872052D14D0012221462846FFF760 -:106310002DFF0028E9D1207840060AD502216846E1 -:106320000172099981810188C18106824782129890 -:1063300005900198000404D500273E4601250797E3 -:1063400009E02078A1788007800D0843A1490790D3 -:1063500015F0ACFC0D46019840040AD50798A842F8 -:1063600007D12088E1788005800F00020843B04201 -:1063700001D3AE4201D90720B7E7B81980B2019026 -:10638000A84201D90D20B0E76846007A002804D061 -:1063900002A8FDF73CF90028A7D10798A8420BD125 -:1063A000208803210902884301998905890F090280 -:1063B000084320800198E0701498002800D00780DE -:1063C0001298002815D006983A468019129915F0AF -:1063D00004FC224669460A98FFF7F5FE69460888DC -:1063E0001021884369460880224600990A98FFF7E1 -:1063F00011FF002079E7FFB5754D0C22E888296868 -:10640000504383B00C180D9F7249059815F04EFC4F -:106410000091049800F001FA29682A898E46611AD1 -:106420000C310918944651188AB2A988914202D8B1 -:10643000842007B0F0BD6A46168A320603D5B2063C -:1064400001D50E20F5E7EA88521C92B2EA800E9B35 -:10645000002B00D01A80B20601D5A76006E0604488 -:1064600080B22881091A70460818A0602246FE20D2 -:106470000499FFF7CFFE0598A0700098E07020887F -:106480000599800889058000890F084303210902C6 -:10649000884300998905890F0902084304210843AC -:1064A000208003988078A07103980088A080002045 -:1064B0002073310601D5AC7A00E00124B10600D585 -:1064C000002700260EE00521002001910290009790 -:1064D000E88831460C9B069AFFF7F2FE0028A8D107 -:1064E000761CF6B2A642EED30020A2E7F1B50098E2 -:1064F00000F085F9060002D00025009C14E0012080 -:10650000F8BD204600F07BF9074600783149800746 -:10651000820DB878104315F0C9FB386800F07DF99A -:106520004019641C85B2A4B22948C188601E81420A -:10653000E7DC00992648491EC1800189491B018179 -:1065400000203070F8BD002804D0401E10809170EB -:10655000002070470120704710B5044601881C4890 -:10656000C288914201D3822010BD00680C225143A1 -:1065700042189079A072908820811088D178800587 -:10658000800F00020843A081A078211DFFF71BFEA9 -:1065900020612088401C2080E080002010BD012167 -:1065A00001827047F7B50546002084B0C0431080D3 -:1065B000686817468178684681706868018868460F -:1065C000018000218171288A2C88A04205D303E034 -:1065D000B41400200102000004462C8235E0288A11 -:1065E000401C2882301D6968FFF7A6FD00282AD1CB -:1065F00039889248814201D1601E38806888A04263 -:1066000028D33088F1788005800F0002084302907B -:106610006946301DFFF790FD002814D1698987482D -:1066200081421BD0002231460598FFF79FFD0028CC -:1066300009D16A890298824205D1E968B06815F0EB -:106640009FFA00280AD0641CA4B2204600F0D7F8B4 -:106650000600C4D1641E2C828220EAE67C80B079D8 -:10666000B871B088B8803078B1788007800D084361 -:1066700078810298B8813946287A32460831FFF786 -:10668000A2FD38610020D4E6FFB585B01C460F4658 -:10669000059800F0B4F8050009D02878000608D560 -:1066A0006748807AB84204D80E2009B0F0BD0120B6 -:1066B000FBE707982A468605B60D69463846FFF778 -:1066C00082FD07460E98052816D000222946FFF7BE -:1066D0004DFD0028E9D1287840060DD501216846F6 -:1066E000017105990181018841818681C48101A8D8 -:1066F000FCF78DFF0028D8D12888AA788107890D5A -:1067000011438005800FEA7800021043079A9642F1 -:1067100007D04C4A914204D3611E814201DD0B2017 -:10672000C3E7864201D90720BFE7801B82B2A2429D -:1067300000D922461098002800D002800F98002827 -:1067400002D0B91915F049FA0020AEE7F8B51D4698 -:1067500017460E4600F053F8040008D020780006D3 -:1067600007D53748807AB04203D80E20F8BD012003 -:10677000F8BD224639463046FFF725FD002D0BD0E7 -:106780002078A1788007800D08432E49884201D2E5 -:10679000012000E0002028700020F8BDF8B51E465A -:1067A00017460D4600F02BF8040008D020780006AC -:1067B00007D52348807AA84203D80E20F8BD0120CF -:1067C000F8BD224639462846FFF724FDFF2E14D097 -:1067D0002588A178A807800D08431A4915F066FAA4 -:1067E000002E03D1FF31FF31033189B2A170A80817 -:1067F00080008905890F084320800020F8BD1049DA -:10680000CA88824207D3002805D00C220968504369 -:106810000C38081870470020704703B508466946D1 -:1068200009888A0607D4090604D50549897A4143AF -:10683000491C88B20CBD00200CBD0000FFFF000009 -:10684000B414002001020000F8B507780D46044694 -:10685000012F19D0072F02D00C2F19D114E0A068F6 -:10686000216906780B2E0BD0052005F0E6FE052EDB -:106870000ED0782300220520216905F039FE07E0BB -:10688000782300220620F8E70520216905F0D5FECF -:10689000002D0ED0002028702946204603F049F92B -:1068A000FE482978C05D884201D10320F8BD02204E -:1068B000F8BD0021204603F03CF90020F8BD70B57A -:1068C0000E460C462036317901208AB01546002943 -:1068D00009D0012905D12978042902D10520107099 -:1068E00000200AB070BD6068019005A802900D21DB -:1068F000C01C15F0CFF9032205A8A16815F06DF9A9 -:1069000001203071062069460870206A04902946EB -:106910006846FFF799FFE4E770B50C46154620314D -:106920000A790120062686B0002A2CD0012A28D117 -:106930002978042925D169681022A06801F0B4F9EA -:106940006868C07B000606D5D44AA0681023103AB8 -:10695000014601F09EF91022A168E06801F0A4F957 -:10696000A068C07B000606D5CC4AE0681023103A28 -:10697000014601F08EF92E70A0686860E068A8609A -:10698000002006B070BD60680190C44820380290B5 -:106990000120087168460670206A049029466846FE -:1069A000FFF752FFEDE7027B032A06D000222423E3 -:1069B0005A540B78092B02D003E0042070470A7662 -:1069C000CA61027B9300521C0273C15003207047BE -:1069D000F0B50E4615460C462036024631790120A8 -:1069E000072393B000290CD0012924D002292ED0EE -:1069F000032904D12978042901D12B70002013B078 -:106A0000F0BD01203071606800280DD0A1690B70C5 -:106A100060684860206988606069C860206A0862B0 -:106A20001046FFF7C0FFEAE706202870206968607B -:106A30006069A86009E029780629E0D10220307158 -:106A4000042028709548203868600320D7E729780B -:106A50000429D4D1A08910280AD9103880B2A08185 -:106A6000A1681023091805A86A6801F012F923E04B -:106A700010282FD0C2B21020801AA1680DAF11903B -:106A8000C01915F0AAF811980006000E06D0401E95 -:106A9000C1B280207854384615F0FCF862691023A2 -:106AA0000DA909A801F0F5F8102309A905A86A683D -:106AB00001F0EFF8032030716068019005A80290A2 -:106AC000062069460870206A049029466846FFF748 -:106AD000BBFE94E710232269A168E2E7F0B50E46F9 -:106AE0000C4620363179012006278FB01546002943 -:106AF0000BD0012932D0022905D12978042902D1ED -:106B00000820107000200FB0F0BD217D08A8CA0732 -:106B1000D20F02718807C10F08A801716846027080 -:106B200041700722801CE16815F057F802A807227F -:106B30000130216915F051F8606805900AA80690A7 -:106B400010236A46A16801F0A4F80120307168465C -:106B50000774206A0890294604A820E029780429AF -:106B6000D1D1062205A8E16915F037F806A806225A -:106B70000230A16915F031F800200890606801909A -:106B800009A80290102305AA696801F082F8022082 -:106B9000307168460770206A049029466846FFF7FE -:106BA00053FEB0E770B50D460C462035297901201B -:106BB0008CB01646002909D0012905D13178042965 -:106BC00002D10920107000200CB070BD60680190E7 -:106BD00006A802900822E16814F0FFFF082208A826 -:106BE000A16814F0FAFF0120287106206946087098 -:106BF000206A049031466846FFF726FEE4E770B548 -:106C00000D460C462035297901208CB01646002906 -:106C100008D00129D8D131780429D5D10A201070A3 -:106C20000020D1E76068019006A802900822A168C0 -:106C300014F0D3FF0020089009900120287106204D -:106C400069460870206A049031466846FFF7FCFDEB -:106C5000BAE730B50B4620331C7901208BB0002CED -:106C600009D0012C05D11178042902D10B20107014 -:106C700000200BB030BD4868019005A802908C68D8 -:106C800068462578057564784475CC6825788575DF -:106C90006478C47500200690079001E094C101005B -:106CA000089001201871062368460370086A049052 -:106CB00011466846FFF7C8FDDBE770B50C46203487 -:106CC000034625790120002D0AD0012D14D0022D74 -:106CD00005D111780A2902D10C201070002070BD56 -:106CE00001202071C868052202704A684260F84A93 -:106CF0008260921CC2600BE015780B2DEFD1022050 -:106D00002071C86804240470526842608A688260F6 -:106D1000096A016201461846FFF745FE70BD30B5AD -:106D2000011D02463132947803258379ED432C43CB -:106D300023408371DB070DD04B79547923404B718D -:106D40000B79127913400B718278C9788A4200D985 -:106D5000817030BD00224A710A71F5E7F7B50C4623 -:106D600086B0002069462646087020363179012712 -:106D70001E2015461F2977D24B007B449B885B0061 -:106D80009F441E0017023E025602690288029A02C0 -:106D9000D102F5022E03590371037F03AE03C3032F -:106DA000CC03F7031A0464049A04AB04DF04FE0462 -:106DB00010052A0565059B05C605830587058B0516 -:106DC0006069002802D0007813287DD0A068059063 -:106DD000002849D0012168460170206A04900321EF -:106DE000684601710A214171E0690290207900280A -:106DF000EFD0059909780029E7D00C2964D20B005F -:106E000015F0A3F90CFD1A4B90B5E8FCFBFAF9F864 -:106E100007FD022828D16069002802D000780828E0 -:106E200052D1022168460170206A04900598417889 -:106E3000684601710021B9E20620216A05F0FDFBD8 -:106E400020790728E6D1606900F050FF02280CD0B5 -:106E5000606900F04BFF042807D060690028B8D0B3 -:106E600000780128D6D103E01BE261690120087097 -:106E700005980079C11F0A2901D30A2050E06169F1 -:106E80000722887060690599303014F0A6FE012051 -:106E9000307161690320087034E00728BAD1606955 -:106EA000002896D001780929B4D10599C9788907B5 -:106EB00007D1059949790029DFD1059989790029F8 -:106EC000DBD105994A7900E04EE2014620314B7D45 -:106ED0009A43D2D1059A8B7D92799A43CDD1059A66 -:106EE0001279D31F0A2BC8D20979914236D80722CA -:106EF000C01C059914F071FE0120307161690A20EF -:106F00000870032069460870206A04906069313077 -:106F100001906069001D029060691C300390A1E23D -:106F20002076F2E311288DD1606900F0DFFE04289D -:106F300004D0606900F0DAFE0B2893D160690599EE -:106F400010223730491C14F048FE6069017804298A -:106F50007CD12421095C8278914201D90620DFE7A7 -:106F6000052101700320307168460170E2E31128A9 -:106F700094D1606900F0BAFE062804D0606900F080 -:106F8000B5FE0C288AD1E068002813D020690028BB -:106F900010D060690178062910D00D210170606958 -:106FA000059910225730491C14F017FE60695730BC -:106FB00009218CE100206946087072E10721017007 -:106FC0006069059910224730491C14F006FE60697B -:106FD0004730EDE70228F0D1606900F087FE002815 -:106FE000EBD0606900F082FE0128E6D0606900F015 -:106FF0007DFE05E0B1E08DE06CE02AE00AE0D6E03D -:107000000828DAD00521684601710598417868465C -:10701000417146E11128D0D160690028CDD00178B6 -:107020000E29CAD1C16A4078022810D0002014224B -:1070300050431430085805991022491C14F0CDFD16 -:107040000520216A00F040FE0F205EE0F1E1012002 -:10705000EDE70B28B1D160690028AED001780F2987 -:10706000ABD1C16A4078022826D0002014225043B8 -:107070000C300958059842780A7080784870606929 -:10708000C16A4078022819D00020142250431030E1 -:10709000085805990822C91C14F09FFD0520216A93 -:1070A00000F012FE60694178022909D000220832FE -:1070B000825C5208520073E00120D7E70120E4E728 -:1070C0000122F4E7012100E0002108314254BCE331 -:1070D0006EC1010011289CD16069002899D0017807 -:1070E000102996D1C16A4078022811D000201422BC -:1070F00050431830085805991022491C14F06DFDB2 -:107100000520216A00F0E0FD112061690870B4E3F8 -:107110000120ECE7082884D1606900289DD001781F -:10712000112997D10599C06A49780170606905995C -:10713000C06A0622401C891C14F04FFD0520216AFC -:1071400000F0C2FD60694178022904D000220832B3 -:10715000825CFD2323E00122F9E71128BBD160699D -:107160000028BBD001781229B5D1C16A4078022825 -:1071700019D00020142250431C30085805991022C1 -:10718000491C14F02AFD0520216A00F09DFD60696C -:107190004178022909D000220832825CFB231A4080 -:1071A000022991D18EE70120E4E70122F4E70720CC -:1071B000B6E6287801288ED16069696814221C30EF -:1071C000FAF702F86069017F002901D02176ACE36B -:1071D0000178032901D0032037E00227C7708179A5 -:1071E0004907490F8171017A4907490F0172417AB4 -:1071F0004907490F41726069FFF791FD377196E2C7 -:1072000028780F28E3D1072069460870216A049185 -:10721000916802916946087161690722C91C029848 -:1072200014F0DBFC61690420087000203071BBE0C1 -:1072300028780328CBD1606901780529696807D0CF -:107240000822473014F0C9FC0420307105206FE299 -:1072500008225730F6E728780328B8D1606901780A -:107260000529696811D008224F3014F0B6FC0520BA -:1072700030716069006A00280AD00220287000205E -:1072800028716069006AA860F9E008225F30ECE7C5 -:1072900004204DE22878022899D12879002801D0CD -:1072A000207642E36069A96801626069002901D122 -:1072B000F949016206200BE228780F2887D1A868D7 -:1072C000E0616069017805292BD0473007213171D1 -:1072D000E16802220A706269126A4A608860606925 -:1072E0003030C8606069C01C08616269087D926ABC -:1072F000400812784000D207D20F10430875626927 -:10730000926A521C8A61FD2210406269D26A127828 -:10731000D207920F104308756069C06A401CC861AB -:1073200053E25730D2E728780828BAD1606901784B -:1073300005291AD00B210170072069460870206AC0 -:107340000490E069029011200871029803210170F5 -:1073500051681022401C14F040FC00216846FFF7E1 -:1073600073FA00203071E06187E20621E3E72878B4 -:107370000F2896D1072069460870206A0490A868F3 -:1073800002901120087102980421017061690A7845 -:10739000072A0ED0002232710C220A706169102275 -:1073A000401C473114F019FC00216846FFF74CFAE5 -:1073B00063E21022401C573114F00FFC0021684694 -:1073C000FFF742FA0A203071E16803200870606913 -:1073D000006A486060695730886060694730F3E14F -:1073E00028780828A1D1606969681022373014F024 -:1073F000C7FB002801D0042092E5606900780728C7 -:1074000017D00A203071E168032008706069006AB3 -:10741000486060695730886060694730C860206A9A -:1074200008620698FFF7BFFA07466069FFF777FC26 -:107430006BE208207AE1287809289AD10B20307174 -:1074400061696868897810224018511A14F022FC8A -:10745000082069460870206A049068680190606995 -:107460008078087268E129780D29BBD16169897932 -:10747000C90703D00C20307109203EE0307103278A -:1074800070E228780E28ADD160691422291D1C30C5 -:10749000F9F79AFE6069018DC06A4172090A81722A -:1074A00060698178C06AC1716169CA6A081D117A10 -:1074B000C909C90111724379626919438378D26A93 -:1074C0009B079B0F012B00D0002300799B01C0007C -:1074D00003431943117260694078012876D0B4E102 -:1074E00060694178022901D0012100E000210831C2 -:1074F000405CC00707D00E20EAE069460870206AA9 -:107500001146049019E11320B8E728780F2894D188 -:10751000A868E0610F2030710520EEE72878032885 -:107520008BD16069C16A4078022801D0012000E057 -:10753000002014225043103008580822696814F0C3 -:107540004CFB10203071E1680620226908706069E8 -:10755000406A48606069C36A4078022801D001200F -:1075600000E000201427784310301858CA60886063 -:107570002BE128780C2886D16069C26A40780228FD -:1075800001D0012000E00020142148430C301058A5 -:1075900002230932696800F07CFB11203071E16838 -:1075A000052008706069006A48606069C06A093037 -:1075B00088603948001F07E128780B28A7D1616946 -:1075C0004878CA6A022802D0012001E059E100206F -:1075D00014235843143010588A78696814F0FDFA5F -:1075E00060694178C26A022901D0012100E00021CE -:1075F0001423594314315258817850181022511ACB -:1076000014F048FB072069460870206A0490E0697E -:107610000290112008710298062101706169CA6AFE -:107620004978022901D0012100E0002114235943A7 -:10763000143151581022401C14F0CFFA0021684632 -:10764000FFF702F90020E06112206FE028780F2890 -:1076500091D1072168460170206A049090680290D9 -:107660000B2268460271029801706169CA6A497802 -:10767000022901D0012100E00021142359430C31DB -:1076800051580A784270497881706169CA6A4978AC -:10769000022903D0012102E074C10100002114235A -:1076A0005943103151580822C01C14F096FA002199 -:1076B0006846FFF7C9F826E760694178022901D0DA -:1076C000012100E000210831405C800703D514202F -:1076D00030710A2011E71620D0E628780F287AD1D9 -:1076E000A868E061072069460870206A0490E06994 -:1076F0000290112008710298082101706169CA6A1C -:107700004978022902D0012101E011E1002114236E -:107710005943183151581022401C14F05EFA0021D0 -:107720006846FFF791F80020E061152030710A20CB -:1077300069460870206A049029466846FFF784F875 -:107740002BE028780F2846D1072069460870206A68 -:107750000490906802900820087102980921017035 -:1077600061690622C969097841706169801CC9692B -:10777000491C14F032FA00216846FFF765F8AAE7C1 -:1077800060694178022901D0012200E0002208321C -:10779000805C400703D51720C8E70746B5E00129FC -:1077A00053D070E028780F2815D1A868E061182020 -:1077B0003071E168052008706069006A486060699E -:1077C000C06A09308860F848C860206A0862069874 -:1077D000FFF7E9F8E1E76FE028780B286CD16069E2 -:1077E000C16A4078022801D0012000E00020142264 -:1077F00050431C3008581022696814F0EEF9072035 -:1078000069460870206A0490E069029011200871AE -:1078100002980A2101706169CA6A4978022901D077 -:10782000012100E00021142359431C31515810223A -:10783000401C14F0D2F900216846FFF705F800203B -:10784000E0616069407801281DD1192016E6606961 -:107850004278022A09D0002108314118097800290C -:107860000DD0CA0703D00E2106E00121F4E78907F5 -:1078700001D5102100E012210170002772E0012AD9 -:1078800001D00D20FAE51C20F8E51D2030710B20F9 -:1078900033E62978102948D1F0E56069017801299B -:1078A00043D0082941D00021317100F019FA0C2091 -:1078B00069460870206A049037E028780F2805D0C0 -:1078C0001020107003271B2030714BE00721684601 -:1078D0000170206A0490A868029002216846017134 -:1078E000029805210170217E417000216846FEF753 -:1078F000ABFF0B2168460170206A04902946684658 -:10790000FEF7A2FF07461B203071012F0DD029E0A2 -:10791000012168460170206A0490042168460171C3 -:10792000217E41710020207612E0207E00280FD0B9 -:107930006169132008701A2030710A2069460870A6 -:10794000206A049029466846FEF77EFF074609E054 -:107950006069002801D01421017068460078002871 -:1079600000D021E5384609B0F0BDF7B50F46203705 -:107970003879012686B00C46002804D0012828D08A -:1079800002281CD197E02079012804D0022811D0C8 -:10799000032814D10AE0A068407801280ED10620FF -:1079A000216A04F024FE00287FD10CE0A168132096 -:1079B000087008E0A0684178022901D0052674E02B -:1079C0000078082871D1012038710A2069460870B2 -:1079D00033E0089800780F2867D1072168460170C6 -:1079E000206A049008988568029522790220012A6D -:1079F00004D0022A29D0032A57D10FE00646684650 -:107A000006710B202870207B00214007400F687012 -:107A10006846FEF719FFA068067045E0064668460E -:107A2000067105202870207B687000216846FEF7EB -:107A30000BFF3E710B2168460170206A0490684676 -:107A40000899FEF701FF06462FE068460171012004 -:107A50002870207C6870607CC007C00FA870A07C74 -:107A60004007400FE870E17C2971C0071FD0207DDE -:107A70004007400F6871607D4007400FA8710021EA -:107A80006846FEF7E1FEA06807222946303014F070 -:107A9000A4F8E068017AA06820300171A168287913 -:107AA0008870A16809200870002630465BE7002036 -:107AB000A8716871E3E7A168142008700121684685 -:107AC0000170206A0490042168460171217B417194 -:107AD0000021FEF7B9FEE7E7F0B585B00F46054691 -:107AE0000124287B800040198038C66F3078411E01 -:107AF0000A290AD22C498000323140188038C36FDD -:107B00003A463146284698470446002C01D0012CBD -:107B100011D1287B401E0006000E287301D00324DB -:107B2000DFE70D2069460870306A04900021019655 -:107B30006846FEF789FE032CD3D0204605B0F0BD81 -:107B400070B515460A46044629461046FFF7C4FF9D -:107B50000646002C0FD0207814280CD1207E002857 -:107B600006D000202870204629460C30FFF7B4FFCD -:107B7000204600F0B5F8304670BD704710B50129B9 -:107B800003D0022901D0052010BD417000F0A8F8F3 -:107B9000002010BD002809D0027E002A06D00A4627 -:107BA00001460C31CCE7000072C101000120704792 -:107BB00030B5044687B00D46062004F03EFD294648 -:107BC000052004F03AFD2078142805D000206946ED -:107BD00008702046FFF7DEFF07B030BD7FB50E46C8 -:107BE00000216A4611730178092903D00A2903D0BC -:107BF000002407E0446900E08468002C02D0217E64 -:107C0000002912D0154601462846FEF7CCFE03286F -:107C100009D1324629462046FFF792FF6946097B83 -:107C2000002900D0042004B070BD25460C35EAE7D9 -:107C300000B50023012285B005280CD0062808D104 -:107C40006846027004910221017143710021FEF720 -:107C5000FBFD05B000BD6846027004910271F4E7B7 -:107C600010B590B00C4605216A461170019022486B -:107C70000290001D03900AA96846FFF7AFFF002895 -:107C800005D1102220460B9913F0A7FF002010B059 -:107C900010BD30B505E05B1EDBB2CC5CD55C6C4042 -:107CA000C454002BF7D130BD10B5002409E00B7887 -:107CB000521E5B00234303700B78401CDC09D2B2D8 -:107CC000491C002AF3D110BD70B50C46054604F0DE -:107CD000B4FC782300222146284604F009FC70BD3C -:107CE0004178012900D0082101707047002801D097 -:107CF00000787047082070476CC1010070B5FD4DD9 -:107D0000040008D0012C10D0022C07D0032C05D081 -:107D1000F9A1702007E0F8A1672004E02878012885 -:107D200003D0F5A16D2014F0E2F82C7070BD70B591 -:107D3000F04D044610280AD0112C16D02846817820 -:107D4000122C07D0132C0AD0EBA19F200BE0EAA144 -:107D5000942008E0112908D0E7A1992003E0112917 -:107D600003D0E5A19C2014F0C2F8AC7070BD10B532 -:107D7000E04894B0007B002819D0172069460870AD -:107D8000DC4900A806220D31023013F026FF09A9B4 -:107D90006846FBF7D6F80446112805D0002C03D01E -:107DA000D5A1BB2014F0A3F8204614B010BD32209A -:107DB000E4E710B501220023114603F032FF10BDA5 -:107DC000FFB595B01D460E460746FFF7F2FF0400CB -:107DD0000AD02078222804D3A07F8006C00FA842B2 -:107DE00004D1082019B0F0BDC748FBE73721684629 -:107DF00001704780002D05D001210171467117994E -:107E0000817102E000206946087109A96846FBF704 -:107E100098F8A07FDF21084069010843A07700207F -:107E2000E0E770B50446084620380D46030014F01C -:107E30008CF90A060A1121282F3E454C535DFF207C -:107E4000ADA108304EE0207820284DD1FF20AAA116 -:107E50000B3047E0A7480178032945D080781328E4 -:107E600042D0207825283FD023283DD0FF20A2A152 -:107E70000E3037E02078232836D8FF209EA114301A -:107E800030E0207822282FD0FF209BA1173029E056 -:107E90002078222828D0242826D0262824D0272835 -:107EA00022D0292820D0FF2093A11A301AE0207870 -:107EB000252819D0FF2090A1213013E02078252813 -:107EC00012D0FF208CA124300CE0207825280BD084 -:107ED000FF2089A1273005E02078282804D0FF2042 -:107EE00085A12A3014F003F8257070BDFF2082A10F -:107EF0002D30F7E730B5854C0B88854A022801D034 -:107F0000934204D09D1FA54225D2022802D04D885D -:107F1000954203D04D88AD1FA5421CD24C88A34288 -:107F200019D88B88FF25F435AB4214D8022802D02B -:107F3000C888904205D0C888744D0A382D1FA842C1 -:107F400009D2C888904208D0944206D05B1C634393 -:107F50008000834201DB072030BD002030BDF0B53A -:107F60006C4A904242D3012189046B4C884201D370 -:107F7000A0423BD30579002D06D0082D02D8067B00 -:107F8000082E05D90720F0BD037B002BFAD0F6E7B9 -:107F9000002D06D00368934228D38B4201D3A3421D -:107FA00024D3002E06D0836893421FD38B4201D383 -:107FB000A3421BD300230BE004689F00E4599442C2 -:107FC00014D38C4202D3544FBC420FD35B1CDBB2A0 -:107FD0009D42F1D80023504D0CE084689F00E45985 -:107FE000944203D38C4203D3AC4201D21020F0BDA3 -:107FF0005B1CDBB29E42F0D80020F0BD10B50289B8 -:10800000464B111F994211D2418904290ED3DB1C22 -:1080100099420BD8914209D80178890704D5406864 -:10802000FFF79DFF002800D1002010BD072010BDE4 -:10803000FFB50022099B002802D0994205DC6FE0C1 -:10804000002902D1002004B0F0BD0920FBE7845CC8 -:10805000002C12D087187D78112D43D010DC2B0016 -:1080600014F073F80A401726262C2C2E2E36364094 -:10807000835C002B30D1521CD2B28A42F8DBE1E79C -:108080001C2D2FDA123D2B0014F05FF8042C2C125B -:108090001A2C022CD9D1BB78039C072B237001D258 -:1080A0005B0701D40A20CEE7029B01241B7816E06F -:1080B000E343DB0708E0012C08D013E00620C2E709 -:1080C0000F2523072D075B19002BF4D03046BAE7A4 -:1080D000029B1B789C0701D50B20B4E702242343A5 -:1080E000029C2370835C521C9A18D2B28A4219DD1A -:1080F000ABE70000C01400207372635C6761705FBF -:10810000636F72652E630000023000007B0C00007C -:10811000FFFF000000D0010000280020FD3F00000C -:10812000192676028A4292DB8CE710B504780B465A -:10813000002C08D00121FE4A012C07D0022C0BD0C4 -:10814000032C13D10EE00021197011E01970817910 -:10815000890903290AD10BE019708179890901295C -:1081600004D105E019708179890901D0104610BD4C -:10817000411C0622581C13F030FD002010BD08B52C -:108180001346002806D0EBA00068009048796A46A4 -:108190008009105C18700622581C13F01EFD08BDE3 -:1081A00030B50C46097895B0222902D2082015B0C6 -:1081B00030BD282369460B704880132A03D03B2A20 -:1081C00001D00720F3E708460A7109A9FAF7B9FEBA -:1081D000050003D121212046FFF723FE2846E6E7CC -:1081E00000B595B0232369460B70488010888880BD -:1081F0005088C880D0884881908808810020888174 -:10820000C88109A96846FAF79CFE15B000BD70B593 -:108210000C00064610D0FFF7CCFD050003D1C6497F -:10822000C64813F064FEA6802889E0802889208152 -:1082300068896081A889A08170BD70B50E4605006F -:1082400003D00021092004F0F8F90120BC4C022ED3 -:10825000207324D0032E04D0B848B7491E3013F041 -:1082600046FEB74806210D3003F07CFFA07C800657 -:10827000800EA074FFF77BFDA08B00280ED0002D90 -:108280000CD0830001220021092004F031F90928D3 -:1082900004D0AA48A849283013F029FE70BDA84888 -:1082A0000321103003F05EFFA07C40218006800E89 -:1082B0000843A074A2480C3002F093FADAE77FB5C5 -:1082C00001A9012003F02BFD002804D06F209A495A -:1082D000C00013F00CFE9B4E01A803F02DFD05001D -:1082E00002D0052D4CD048E0029CA07F01072CD580 -:1082F00020462230009068462346628E80882146C0 -:10830000343301F0EFFB0546A07FF7210840A0774A -:10831000002D05D0B5422FD088488749783029E014 -:10832000E17F480889074000C90F08432021095D03 -:108330004007400FC9000843E077207828281CD167 -:1083400029212046FFF76DFD17E04007C4D5684698 -:108350002246808821460E32FFF742FF0546A07F65 -:10836000FB210840A077002D07D0B54204D0734808 -:108370007149923013F0BBFD0025284604B070BD52 -:108380000020FBE7F8B5040004D16C486A49A1302D -:1083900013F0ADFD72202070606808250178091F78 -:1083A0000B0013F0D2FE11FC0A3D5FFB3D0EFBFB00 -:1083B0003E3D3D3D3DFC86FC3D0060485E49AA30A7 -:1083C00074E087883846FFF7F4FC060004D15B4868 -:1083D0005949B23013F08BFD607804212843607056 -:1083E000574CA07F0843A07721213046FFF719FDA5 -:1083F000B07F8007800F012801D1801EA080384601 -:1084000003F0A3F83846FDF703F83846FBF7CEFB38 -:108410003946022004F011F9B07FEF210840B0770F -:10842000F8BD86883046FFF7C4FC002804D14348D5 -:108430004149D03013F05BFD60688078012804D09A -:108440003E483D49D23013F052FD60688179304694 -:1084500003F07EF90028E3D06178294361706168F8 -:10846000C880F8BD87883846FFF7A3FC060004D112 -:10847000FD203149800013F03AFD607839462843E9 -:1084800060706068C0883081606800897081606851 -:108490004089B081022004F0D0F80020B075FFF7C9 -:1084A0000EFF0028DDD025482349ED3013F01FFDD5 -:1084B000F8BD80783C2815D00027022815D000266A -:1084C000002804D01D481C49F83013F010FD00218D -:1084D000084604F0B2F80021072004F0AEF8002EA0 -:1084E00005D053E001270026F1E70126EFE7607889 -:1084F000284360701248817F29438177002F45D13E -:1085000060688688304601F0BFF90546807F616863 -:10851000800889798000012900D002210843A877CA -:108520006068C08A28816068008B688160680BE0A1 -:10853000023200000302FF01F88000001103000076 -:10854000C014002002300000408BA8816068062221 -:10855000C079E875616828461830083113F03DFB92 -:1085600060680622807B68706168A81C0F3113F078 -:1085700034FBA87F8107890F304602F0CFFFA87F28 -:108580008007800F012801D1FD488680FC480178D2 -:10859000032909D0807813280AD001E00CE00FE00D -:1085A000FF20F8A1433081E70120FFF7A7FBF8BDCA -:1085B0001120FFF7BCFBF8BD204601F09FFDF8BD80 -:1085C000607828436070F8BDF7B50546007800274D -:1085D00000090C463E4601287ED00022ED490228C3 -:1085E0007BD0072804D00A2878D0E6A1EA482DE1FC -:1085F000686803780D2B31D006DC042B6FD0072B75 -:1086000036D00A2B6AD106E0122B38D0132B40D07B -:10861000142BF7D1B2E011270726002C72D08088E6 -:10862000A0806968FB238979A171D54905468A7FB5 -:108630001A408A77032103F02AFB0421284603F01D -:1086400026FB0021284603F022FB0221284603F0E6 -:108650001EFB0121284603F01AFBF9E00127092639 -:10866000002CDBD08088A080686880792072EFE0E1 -:1086700012270E2680882146FFF7C9FDE8E01A2759 -:108680000726002CCAD04088A08068680079A071B5 -:10869000DEE081783C2936D010271E26002CBDD084 -:1086A0008088A0806868C08A20836868C08AE08269 -:1086B0006868008B60836868408BA0836968207D50 -:1086C000497F4008C9074000C90F08432075696801 -:1086D000C007C00F497F03E05FE08AE0ADE01CE027 -:1086E00049084900084320756968A21DC879083106 -:1086F000FFF745FD69682246887B0D320F31FFF791 -:108700003EFD05E074E019270726002C70D0A27109 -:108710009B48F722817F11407DE01B272E26002CED -:1087200066D0A1806968A21D0879491DFFF727FD61 -:1087300068682030C07A60736868C0780428A07BBD -:1087400019D040084000A073F921084069681F2231 -:10875000C9788907490F0843A07369684007C97A37 -:10876000400FC9000843A073696820460F300C31E0 -:1087700013F033FA6CE001210843E4E71E270E26CC -:10878000002C6DD0A1806868E21D407AA0716968F4 -:108790008878C91CFFF7F3FC5AE0287A012805D035 -:1087A000022815D07C4877A132384FE01D270E26CD -:1087B000002C55D06888A080A889E080E8892081B5 -:1087C000288A6081688AA0816D48DF22817FA2E7C4 -:1087D00012270E266888FFF71AFD002C40D0687813 -:1087E0004007400F032833D16548FD22817F92E77F -:1087F00036E0287A030013F0A8FC060410102020AD -:10880000202619270726002C2AD0A1805C48A271B7 -:10881000817F4908490081771AE019270726002C33 -:108820001ED0A180287A012805D00320A0715448C9 -:10883000EF22817F6FE70220F8E721462846029A5F -:1088400001F0B9FDFEBD54484EA1801F13F04FFB4F -:108850000298002C068001D0278066800020FEBD93 -:1088600002980680FAE710B5454894B0817E8907E2 -:10887000890F022902D0494814B010BD807813280E -:1088800001D00820F8E722206946087009A9684647 -:10889000FAF757FB04460021072003F0CEFE2046DE -:1088A000EAE700B5364895B0817E8907890F02292D -:1088B00001D03A48A9E48078122801D00820A4E425 -:1088C0001E206946087000208870C87009A9684693 -:1088D000FAF737FB0028EDD10021072003F0ADFEA9 -:1088E0001120FFF724FA00208FE400B5244895B04A -:1088F000817E8907890F012901D0284885E4007805 -:10890000022801D0032818D11B2108A801730021D7 -:10891000817369460BA8FAF714FB0028EED168466C -:1089200040781B2801D003206FE40021084603F0A3 -:1089300084FE68468078002801D0082065E4012084 -:10894000FFF7DCF9002060E4F8B50D4C030013F0EC -:10895000FCFB0A068127818181814B446F81FFF7EF -:10896000C4FF002839D1F9F718F8002835D02221A2 -:10897000017000210172F8F7F1FFA07F012153E09F -:10898000C01400207372635C6761705F636F72650F -:108990002E630000FFFF00003405000005300000DA -:1089A0008EB23046FFF705FA050003D1F549F648C7 -:1089B00013F09DFA287821280FD0F8F7EEFF002851 -:1089C0000CD0122101700227077246800020A87582 -:1089D000F8F7C4FFA07F3843A077F8BD13222946DB -:1089E0003046FFF7DDFBF8BDA578122D07D0132D1B -:1089F00008D0E548E349283013F079FAF8BDFFF7CD -:108A000050FF01E0FFF72FFF0028F7D1F8F7C5FF6F -:108A10000028F3D022210170122D07D0022101720B -:108A2000F8F79CFFA07F10210843D5E70121F6E766 -:108A3000A07C810901290BD0800904D0D248D149FA -:108A40004A3013F054FA03210020FFF7F6FBF8BD7B -:108A50000221F9E7CC48CB495130CDE7F7B51446B0 -:108A60000D0004D1C848C749593013F040FA28789E -:108A70000827012807D002281FD0C348C1498A30DF -:108A800013F035FAFEBD0098FFF793F9060004D104 -:108A9000BD48BC49603013F02AFA0220B07510308E -:108AA000207060783843607007CD083407C4B74839 -:108AB0002022817F11438177FEBD0098FFF779F96D -:108AC000060004D15D20AF49000113F010FAA98817 -:108AD000AF48814208D1EA88824205D1132231464B -:108AE0000098FFF75DFBFEBD814202D1E8880028B7 -:108AF00009D01220207060783843607007CD0834A8 -:108B000007C4002006E0782300220220009903F029 -:108B1000EFFC0120B075FEBD9C4840897047FFB551 -:108B20009A4C91B0A07E8007800F012804D1149840 -:108B3000FAF7FAF8002860D101256846032185710B -:108B4000C9028180002201A92846FBF7FCFA00280F -:108B500053D16846152185714902818000261C2168 -:108B600002A8009613F098F80120014668461031DB -:108B7000017000200146684641708178F92001406B -:108B8000891C294368468170017A022739430172A2 -:108B900012998186C6861F2101870C9011980F902B -:108BA00001A80B9009AA0BA902A8FBF79DF80028C1 -:108BB00023D16846808CE080684685717549818044 -:108BC0008078F9210840801C41084900684681707E -:108BD0008786078713A80F9009AA0BA902A8FBF79D -:108BE00083F8002809D16846808C2081A07E800708 -:108BF000800F012803D06681002015B0F0BD6349C5 -:108C000014980A31FAF7A2F80028F5D0F5E730B544 -:108C10000C46614995B08C423FD3012189045F4ADB -:108C20008C4201D3944238D320380021012503001F -:108C300013F08BFA06042E484C525B630021082087 -:108C400003F0D5FC002802D0112015B030BD24203F -:108C50006946087000A80522A11C023012F0BDFF71 -:108C600009A96846FAF76DF9050002D0082D0DD064 -:108C700030E0082300221146184603F039FC08288A -:108C800028D04049464813F032F923E00620DCE7BB -:108C90006068002803D0904201D21020D5E73D2122 -:108CA00068460170218841806188818009A9FAF7AE -:108CB00048F905000ED1606800280BD06946098D7F -:108CC000018007E0206801F0CEFD02E0204600F0C0 -:108CD00028FE05462846B8E73E2007E0857000E0FC -:108CE000817009A9FAF72DF9F3E734206A4610706C -:108CF0002078C0076846F3D0F0E70720A5E730B535 -:108D00000C46264995B08C4201D210209DE72038B0 -:108D1000030013F01AFA05042121232132002088D0 -:108D2000FFF747F8002804D00078222803D2082053 -:108D30008BE71C4889E7252168460170218841801E -:108D400009A9FAF7FEF8050015D10AA90522023192 -:108D5000A01C12F042FF0EE006250CE0206800285F -:108D600005D0884201D2102505E001F071FD0748C9 -:108D70000025808BA080284667E7072065E7034829 -:108D8000133070478489000062050000C014002081 -:108D9000FFFF0000012A000000D001000028002091 -:108DA0006B0600000230000010B504462021F84890 -:108DB00012F070FF0120FEF7A1FF1120FEF7B7FFB0 -:108DC0000021F348C943818021788907890F817682 -:108DD0000021C176E1218900818301460C300D31EB -:108DE0000446F8F75AFEEA4807222146133012F0EB -:108DF000F4FEFEF7BCFF002803D0E649E64813F076 -:108E000076F801F00EF910BD10B504463C2112F0C1 -:108E100041FFA07F80088000A077202020700020E4 -:108E2000A0752034607010BD7047FEB50546DB4864 -:108E30000C46814206D301208004844204D3D848E2 -:108E4000844201D21020FEBD002D02D0012D33D16D -:108E500027E0CF4908220C310F46684612F0BDFECC -:108E600039462046FFF761F90028ECD1FEF77FFF75 -:108E7000060006D007226946384612F0AEFE30469C -:108E8000FEBD2078002801D0012805D1C048072266 -:108E90003946133012F0A1FE0021092003F0CDFB6A -:108EA0000FE00978002907D0012905D0022905D053 -:108EB000032903D0BB48FEBD0720FEBD0120FFF7FC -:108EC000BCF9B348C5760020FEBDB54910B588424F -:108ED00001D2102010BDAE4902460B7B0D31184661 -:108EE000FFF74DF9002010BDFFB599B005460020F1 -:108EF00069460871087208A90874A54F0875B87EFC -:108F000014468007800F012802D0A7481DB0F0BD8D -:108F10000120A2498004A24A002D05D08D420BD326 -:108F2000854201D3954207D3002C07D08C4203D34E -:108F3000844203D3944201D21020E7E7284620431D -:108F400018D01F260CAB01AA009628461A99FFF7E5 -:108F50006FF80028DAD10DAB02AA009620461C99C2 -:108F6000FFF766F80028D1D16846007AC10703D020 -:108F70000A20CBE70720C9E7800705D568460079B6 -:108F8000800701D50B20C1E703AE002D0FD01A20BA -:108F9000694608731A9888732946F01C1A9A12F0C9 -:108FA0001CFE0EA903A8F9F7CCFF0028AED1002CB7 -:108FB0000FD02020694608731C9888732146F01C46 -:108FC0001C9A12F00AFE0EA903A8F9F7BAFF0028AE -:108FD0009CD108A8007C7870002097E770B5044603 -:108FE0000A2020700D462046F9F7ABFF002805D176 -:108FF0003920207029462046F9F7A3FF70BDF7B548 -:1090000000260C4605460B271AE02968B0000958CF -:109010000978002903D0012901D00720FEBDA170E5 -:10902000296806220958E01C491C12F0D6FD277059 -:1090300020460299F9F785FF0028EFD1761CF6B299 -:109040002879B042E1D800263A270FE0A868B1009D -:1090500041581022A01C12F0C0FD27702046029932 -:10906000F9F76FFF0028D9D1761CF6B2287BB04201 -:10907000ECD80020FEBDF0B504464CA103C997B062 -:10908000434F15911490B87E00258007800F01286A -:1090900002D0454817B0F0BD404A944210D3012396 -:1090A0009B043F4E9C4201D3B44209D3207801284F -:1090B00008D16168914203D3994203D3B14201D2EE -:1090C0001020E7E7397801290CD1B988394A914253 -:1090D00003D0002806D0012804D0B97F0A07920FD8 -:1090E00006D101E00820D5E7CA0701D1890701D5DB -:1090F0001120CFE7218A304B0A46203A9A4207D303 -:10910000012873D1002971D1628A002A6ED110E042 -:10911000022801D0032801D1A02967D3012808D053 -:109120001B4A5278D20704D0628A002A5ED0B42A41 -:109130005CD8002806D0012808D0022804D00328D3 -:1091400054D117E0002618E0022616E0002902D1CB -:10915000608A00280CD004266068007800280CD0B3 -:10916000012809D0022807D0032805D00D4891E72F -:109170000126F1E7032600E00125207A00281DD012 -:1091800001281DD002281DD003287FD11CE000003B -:10919000C0140020848900000507000000D00100F1 -:1091A00000280020023200000530000007060504F8 -:1091B00003020100FFFF0000E13F0000002704E080 -:1091C000012702E0022700E00327002E01D0022E33 -:1091D00013D1002F11D0E068FEF7C1FE002888D11E -:1091E000F6484078800702D0F54853E74EE0022E5B -:1091F00003D1022F4AD0032F48D0182168460170AE -:10920000218A4180218A81808671EC48007B002878 -:1092100002D001286DD103E000206946C87102E048 -:1092200001216846C171684605722178093001291B -:1092300026D0062112F02EFD69460F74207D82078C -:10924000C107D20F4007C90F5200C00F1143800061 -:10925000014314A8405C6946C873002816D009A9C8 -:109260006846F9F76EFE0028BFD109A96846FFF7E6 -:10927000B5FE0028B9D1002E0AD0022E08D010E089 -:1092800061680622491C12F0A8FCD5E7072001E717 -:10929000002F06D009AA6946E068FFF7B0FE002853 -:1092A000A3D11B20694608700120887009A968466F -:1092B000F9F747FE002898D108A840791B2818D153 -:1092C000330012F042FF05040406060409000320DF -:1092D00000E00220FEF712FD012E0CD0608A00286B -:1092E00009D0002283001146104603F001F900283E -:1092F00001D00320CEE60020CCE6F3B5032687B0EC -:109300000D46002909D0AF4885426FD30120800463 -:10931000854202D3AC48854268D30798FEF749FDE1 -:10932000040005D02078222804D2082009B0F0BD1E -:10933000A648FBE7A07F8707BF0F002D05D0294671 -:109340003846FEF7D7FD0600F0D1394600279B4886 -:10935000012908D0022932D04F209D49400112F046 -:10936000C6FD3046E2E7A27D2946012A02D0827F6F -:10937000920701D51120D9E700291BD108216A469F -:10938000049711820592418904AA9248FBF7B8FA22 -:109390000028CBD16846008A082801D00320C5E701 -:1093A0006846018801814188418181888181C18825 -:1093B000C18102A9079802F05CF90646D1E7A17DB8 -:1093C000022916D1807F800613D4002D04D0A07FFF -:1093D00040070CD4002100E00121079802F08AF92F -:1093E0000600BED1A775002DBBD004E01AE01126FF -:1093F000B7E7002D16D02A4621460798FEF7F0FE63 -:1094000006461128ADD1A07F4007AAD420460822E5 -:1094100029460E3012F0E1FBA07F04210843A0771B -:1094200000269EE7102081E770B50C460546FEF742 -:10943000C0FC010004D022462846FEF7B1FE70BDF4 -:10944000624870BD00B50146143195B0192901D2AA -:10945000810707D001461E3104D00A3102D007200F -:1094600015B000BD312269460A70887009A96846A6 -:10947000F9F767FDF4E701B582B00220694608807C -:109480004E4802AB00896A460021FBF7ACF86946FA -:109490000988022900D003200EBD1CB500210091CF -:1094A00002216A46118048490190884201D2102069 -:1094B0001CBD424801894748FBF722FA69460988E2 -:1094C0000229F5D003201CBDFEB517463D4A0E46C5 -:1094D0000546914206D3012080043B49864203D3CE -:1094E0008E4201D21020FEBD1F2F01D90C20FEBDDF -:1094F000324C954226D3854201D38D4222D3E08857 -:1095000001A9FBF721F80028F1D1287869464871B4 -:10951000E08801A9FAF7F9FF0028E8D16946009030 -:10952000087802210843694608704979090703D081 -:109530000821084369460870E0886946FAF780FF09 -:109540000028D4D169460F81E088334602AA002161 -:10955000FBF749F869460989B942C8D00320FEBD26 -:109560001CB50C46002100910191228869460A80B1 -:1095700015490190002801D0884201D38C4201D2C4 -:1095800010201CBD002801D0002A09D00B486A46D3 -:10959000C1881048FBF7B4F96946098821801CBDD1 -:1095A0000C201CBD10B50123FEF70AFC10BD0023E2 -:1095B00010B51A461946FEF703FC10BDC014002072 -:1095C0000132000000D0010000280020023000001D -:1095D00084890000FFFF000070B5E74D0446A87EB7 -:1095E00094B08007800F022802D0E44814B070BD08 -:1095F000E348844206D301208004844204D3E14836 -:10960000844201D21020F1E72046FEF7F7FC002843 -:10961000ECD1A878112801D00820E7E7A87FC00680 -:1096200001D51120E2E71D2168460170207801264E -:10963000C107C90F68468170218981806189C18015 -:1096400020788007C10F68464172287B00250028DA -:1096500003D0012804D00320C8E76846057201E062 -:109660006846067209A9F9F76CFC0028BED109A961 -:109670006846FFF7B3FC0028B8D12078800706D5EC -:1096800009AA69466068FFF7BAFC0028AED11E211E -:10969000684601708670C57009A9F9F752FC002868 -:1096A000A4D1A08900F02EF904009FD11220FEF76A -:1096B0003EFB20469AE7F0B5AF4F0546B87E95B021 -:1096C0008007800F16460C46022802D0AB4815B022 -:1096D000F0BD0121AA488904AA4A002D05D085427F -:1096E0000FD38D4201D395420BD3844209D38C42D0 -:1096F00001D3944205D3864203D38E4203D39642CC -:1097000001D21020E3E7B87FC106890F01D14007DD -:1097100001D51120DBE72046FEF770FC0028D6D1EA -:1097200020788107C90F294303D0800703D5002D76 -:1097300001D00720CBE731460220FEF7DBFB0028F3 -:10974000C5D18D488078112803D0122801D0082077 -:10975000BDE70121084602F059FA0027002804D08D -:1097600085488078122802D005E00420AFE7FFF793 -:1097700098F80028ABD109A96846FFF72FFC00280C -:10978000A5D12078800706D509AA69466068FFF749 -:1097900036FC00289BD12121684601702189418037 -:1097A0006189818020788007C10F684681712078A7 -:1097B000800715D42878002807D0012808D002286F -:1097C00006D0032804D0704881E76846C77102E0DC -:1097D00001206946C8710622691C02A812F0FDF931 -:1097E0006548007B002803D0012804D003206EE7E1 -:1097F0006846877302E001206946887331886846AD -:10980000018271884182B1888182F188C182078397 -:10981000478309A9F9F795FB00288BD1A08900F0AF -:1098200071F8040086D11320FEF781FA20464EE736 -:1098300030B50546534895B00C46814202D21020FF -:1098400015B030BD2846FEF7B4FA002807D00178DD -:10985000222902D3807F800604D40820F0E74748FD -:10986000C01EEDE7132168460170458009A9F9F78C -:1098700068FB0028E4D108AA0A2151567F2901D0AB -:109880002170DDE70520DBE7F8B5012304461A4621 -:10989000194602F0C6F9074601231A46022120465E -:1098A00002F0BFF9064601231A460421204602F0C1 -:1098B000B8F9054601231A460321204602F0B1F902 -:1098C0000446002F03D13149314812F010FB002E1D -:1098D00004D12F482D49401C12F009FB002D04D162 -:1098E0002B482A49801C12F002FB002C04D1AD2029 -:1098F0002649800012F0FBFA22213846FEF791FA41 -:109900003846F8BD10B5002809D083000022114662 -:10991000072002F0EDFD072801D0032010BD002034 -:1099200010BD10B50446006800280BD014498842C9 -:1099300006D301218904884204D31249884201D206 -:10994000102010BD00F077FFA0880B4CA083E07EB4 -:1099500001280DD10021092002F049FE002800D085 -:109960000120A17C8909012904D00321FEF765FCAF -:10997000002010BD0221F9E7C014002005300000CE -:1099800000D001000028002002320000848900007D -:10999000B102000030B5F74B9A4206D301239B0475 -:1099A0009A4204D3F44B9A4201D2102030BD14786D -:1099B000E3065B0F042B07D85378072B04D3957865 -:1099C000102D01D89D4201D2072030BDD3785B070E -:1099D00002D413795B0701D5062030BDC37FA407ED -:1099E0005B085B00E40F2343C3770878EF2318403C -:1099F00013789B06DB0F1B0118430870F1231840F6 -:109A00001378DB065B0F5B0018430870507808730F -:109A1000002030BD30B500240C70C378DB07DB0FAD -:109A20000B70C578AD07ED0F6D002B430B70C5783B -:109A30006D07ED0FAD002B430B7014700179C90752 -:109A4000C90F117003799B07DB0F5B00194311707D -:109A500000794007C00F80000143117030BD70B520 -:109A600014460D460646F7F798FF002809D0A221B4 -:109A70000170142221460830F7F7A6FBF7F76EFFB6 -:109A800070BD132229463046FEF78AFB70BD70B5C3 -:109A900014460E460546F7F780FF002809D022211C -:109AA000017045802178017261784172F7F756FFA5 -:109AB00070BD132231462846FEF772FB70BD10B50B -:109AC000AE4C207C00280CD1204621461038FEF7F1 -:109AD000C7F8002803D0AAA1F22012F008FA01204A -:109AE000207410BD70B594B015460C462C22694602 -:109AF000189E0A704880002B17D00822194601A82A -:109B000012F06BF868468581102231460E3012F053 -:109B100064F809A96846F9F714FA002803D1A17F6F -:109B200010221143A17714B070BD00200190029063 -:109B3000E8E7F0B50646008A97B080B20D4601907E -:109B4000FEF737F904468D48317848380746E8373C -:109B500009900B0012F0F9FA0EFEFD48085F879895 -:109B6000B8D9FCFBFAF9F8FE002301221946019846 -:109B700002F057F8050004D1FF2081A1303012F027 -:109B8000B6F9002C04D1FF207DA1313012F0AFF9DD -:109B9000387EC00904D079486030C06DA86112E0F9 -:109BA0002B20694608720BA902A8F9F7CAF9002808 -:109BB00004D0FF2072A13C3012F099F974490C983E -:109BC00012F074F8A9617068A862B068E862A07FBA -:109BD0008007800F012820780DD0252804D0FF2091 -:109BE00067A14D3012F083F9324621460198FFF704 -:109BF00036FF17B0F0BD2528F6D0222806D024283D -:109C000004D0FF205EA1463012F071F925212046D4 -:109C1000FEF707F9E8E7002301221946019802F050 -:109C200000F8060004D1FF2055A1583012F05FF96A -:109C3000002C04D1FF2052A1593012F058F920789D -:109C4000252804D03078012108433070D1E7022064 -:109C50002870B068A860B068002802D00020287181 -:109C6000C7E70120FBE72B20694608704349684697 -:109C70004C39F9F766F9002804D0FF2040A178306C -:109C800012F035F903201BE02A206946087000A86D -:109C900010220230716811F0A0FF04A810220230D7 -:109CA000B16811F09AFF354968464C39F9F749F91E -:109CB000002804D0FF2032A1893012F018F90420C6 -:109CC00028700998686094E7B068002804D1FF20E4 -:109CD0002BA1953012F00BF9E07F400704D5FF204F -:109CE00027A1963012F003F9B06806220A380090D6 -:109CF00033790421019801F089FA0028A6D0FF20C9 -:109D00001FA19B3012F0F3F873E7002C04D1FF2061 -:109D10001BA1A33012F0EBF820462230102205469A -:109D2000716811F05AFF28212046FEF77AF8A07FCB -:109D30008007800F022814D100231A46214600957F -:109D40000198FFF7CFFE06E04DE1BCE0B2E097E0FE -:109D50003EE070E061E111281CD029212046FEF789 -:109D600060F8E07F317A4007400FC9000843E07790 -:109D70003FE7000000D00100002800208C150020E3 -:109D80007372635C6761705F7365632E63000000CC -:109D900040420F00A07F000704D5FF20FD49B030EE -:109DA00012F0A5F8A07F08210843A0770020608664 -:109DB0002046343011F06EFFE07FFD220146C907D6 -:109DC0001040890F0843E077307A2034207010E784 -:109DD000002301221946019801F023FF040004D159 -:109DE000FF20EC49CD3012F082F82B206946087232 -:109DF000E94902A8F9F7A5F8002804D0FF20E549B1 -:109E0000D23012F074F8E44881882046213001767F -:109E1000090A41760E2129702146FC316960017ED4 -:109E20002974407E6874DC482C30A86010303034CF -:109E30006C61E860DDE6002C04D1FF20D549E630F6 -:109E400012F055F82078212892D93079012802D0D3 -:109E5000022808D103E0E07F04210843E077387E40 -:109E6000012108433876324621460198FFF7F7FD75 -:109E700020782328ABD923212046FDF7D2FFB8E66E -:109E800001220421019801F0D7FC00289FD0002373 -:109E900001221946019801F0C4FE040003D1BD4916 -:109EA000BE4812F024F80F202870172028716E3455 -:109EB000AC609EE60421019801F01CFD002886D1CB -:109EC0001020287095E6002301221946019801F020 -:109ED000A8FE050004D11120AE49400112F007F898 -:109EE0002E462036307E41064DD5A17F8F07BF0F0D -:109EF000C00713D02A468032516F00290ED0087C4B -:109F0000F37DC007C00F5B0018430874516FE27FF8 -:109F100040084000D207D20F10430874307E00077B -:109F200013D52A468032116F00290ED0087CF37DAC -:109F3000C007C00F5B0018430874116FE27F400830 -:109F40004000D207D20F10430874307E80070BD533 -:109F5000F8204259002A07D0012F05D02946307C2D -:109F600031311032FEF70BF9307EC0060BD5F820E8 -:109F70004259002A07D0012F05D12946307C3131C2 -:109F80001032FEF7FCF8052368460370357E4570F5 -:109F9000814822216038019A01704178C908C900BE -:109FA000C91C4170428003724572F7F762FE207847 -:109FB000252809D021280BD0784876495B3011F04C -:109FC00096FF2078222803D922212046FDF729FF79 -:109FD0000021019801F05BFE002800D109E66F48DE -:109FE0006C4963308EE674686B4D207860350928C3 -:109FF00002D00A28F2D10BE0E168002902D02846FD -:10A00000F8F771FF2169002902D02846F8F76BFFA5 -:10A0100021462846F8F767FFEBE560485D49883040 -:10A0200070E65D4810B5042228216030F8F742FF41 -:10A0300059480024EC30017E4906490E017640382B -:10A04000C465FDF79AFD54493C3108461038F7F7CE -:10A050005BFD51484C30047410BD70B50D46FDF7E2 -:10A06000A8FE040004D14D484A49A73011F03FFF33 -:10A07000FF210531284611F00FFEA07F8007800FD9 -:10A0800001280CD0022128468830FDF777FD0028F2 -:10A0900004D042483F49AC3011F029FF70BD012186 -:10A0A000F1E70A46014610B510468830FDF780FDFD -:10A0B00010BD70B5054611200C4608700021617076 -:10A0C0002121495D002908D003290ED0042910D090 -:10A0D00032483049C63011F00AFF207800090128C3 -:10A0E00002D9E87FC008607070BD0007000F203003 -:10A0F00002E00007000F30302070EEE7F0B50446B4 -:10A100004068082601789BB008290DD00B2903D0A0 -:10A110000C294BD101218171606887883846FDF791 -:10A1200048FE05004CD147E047883846FDF741FE20 -:10A13000050004D1B9201749800011F0D8FE287815 -:10A14000212833D0282833D1606802210C3000F058 -:10A15000BDFF00282CD060680821001D00F0B6FF6C -:10A16000002825D02D2168460170478029461022FD -:10A17000223101A811F031FD0FA96846F8F7E1FE80 -:10A18000002804D005480349EF3011F0B0FEA87F45 -:10A19000102105E0809D000040150020070200000E -:10A1A0000843A87729212846FDF73BFE1BB0F0BDE8 -:10A1B000607830436070F9E7FD49FE4811F097FE82 -:10A1C000A87FEF210840A877297821290FD061685E -:10A1D0008A79002A02D08978002912D08007800F5E -:10A1E000022842D0F348F249303011F080FEFEF7E9 -:10A1F00066F80028DAD0EF48ED493B3011F077FEE1 -:10A20000D4E7607830436070E87FC00701D0042154 -:10A2100000E00321212041552878292804D039461F -:10A22000062002F00AFAE2E7002301221946384626 -:10A2300001F0F7FC040004D16520DD49C00011F0F5 -:10A2400056FE25212846FDF7ECFD0D2008A90871D2 -:10A25000204609A98830FDF79DFC0228C7D00028B8 -:10A26000C5D0D448D2491D30BFE760783043607014 -:10A27000BDE7F7B58AB015460646FDF79AFD0028FA -:10A2800041D0017822293ED323293CD0C17F490700 -:10A2900039D4807F8007800F01280DD00023012250 -:10A2A0000021304601F0BDFC0746C3480290F8F794 -:10A2B00011FE040007D101E00123F0E7BD48BC49CD -:10A2C000553011F014FE002F1FD0883767610298B7 -:10A2D000F8F700FE07460298F8F7FCFD0921217007 -:10A2E000266225710B99E760A160206103A92046D1 -:10A2F000FDF774FC022806D0002804D0AD48AC4914 -:10A30000713011F0F4FD0DB0F0BD00200746606122 -:10A31000E4E730B5002387B005460122194601F075 -:10A3200080FC04462846FDF744FD007822281BD90E -:10A33000002C04D19F489E497D3011F0D8FD0F219B -:10A34000684601701721017120466E3002906946FF -:10A350001A30FDF71FFC022806D0002804D0E520A3 -:10A360009349800011F0C3FD07B030BD30B5002324 -:10A3700087B005460122194601F053FC04462846E1 -:10A38000FDF717FD00782228EED9002C04D189486A -:10A3900087498F3011F0ABFD1020694608702046C8 -:10A3A0008830FDF7F7FB0028DED0E92080498000E7 -:10A3B00011F09DFDD8E7F7B50546007800270009A4 -:10A3C00082B00C463E4602287ED0072802D00A28DA -:10A3D0004AD14AE068680178082907D00B2930D0B3 -:10A3E0000C292ED073487249CF306DE114271A26FC -:10A3F000002C6AD04088A080FDF7DBFC009000288C -:10A4000004D16C486A49AB3011F071FD0098009995 -:10A41000C07DA21D1831FDF7B2FE68680822808950 -:10A42000E081696820461030091D11F0D6FB207EBE -:10A4300001210843F9210840207600984021807FBF -:10A4400048E018270826002CD3D08088A080FDF78C -:10A45000B0FC050004D1F7205549800011F047FDFC -:10A46000A11D2846FFF725FE30E1002C01D0288BE6 -:10A47000A080287A01287DD0022805D0032830D07A -:10A480008D204B49C0001FE11C270726002CB0D0AF -:10A49000A088FDF78EFC0090002804D1FD204449DF -:10A4A000800011F024FD287B8007800F0128A0790F -:10A4B00014D040084000A071FD210840297B4907C5 -:10A4C000C90F4900084301E0F0E0ECE0A0710098FA -:10A4D0008021807F084300998877F7E001210843B5 -:10A4E000E9E713270B26002CAED0A088FDF761FC0E -:10A4F00000900023A0880122194601F092FB054636 -:10A500000098002801D0002D04D12A482849F530B0 -:10A5100011F0EDFC0098807F8007800F012857D054 -:10A52000E86A81788907890F0129A17952D0490801 -:10A530004900A1718278FD255207D20F29405200AF -:10A540001143A171E322114002785207D20E114348 -:10A55000A171DF2211404278D207920E1143A171FE -:10A560000021E171C178217242790179607A400855 -:10A57000400000E031E0D307DB0F18439307DB0F07 -:10A5800028405B0018435207FB23D20F184092006B -:10A5900010436072A07ACA0740084000D20F1043EF -:10A5A0008A07D20F2840520010431840490705E09F -:10A5B000809D000012030000A0150020C90F890033 -:10A5C0000843A0720098007823287FD92621C2E092 -:10A5D000A86AA6E701221143ABE7297BFE480229BE -:10A5E00018D017270C26002C5DD001292AD003296A -:10A5F00037D0042938D0052936D08B20F749C00040 -:10A6000011F075FCA088FDF7D4FB054600782328DF -:10A610003BD05BE019270726002C44D00121A17113 -:10A62000017ECA094906890ED20149000A43027611 -:10A63000A088FDF7BEFB05460078232830D0E74907 -:10A64000E7482BE00121A171E17989088900E171D6 -:10A65000017ECA094906D201890E49000A430276E1 -:10A66000D0E70220A07106E0687B0007000F803071 -:10A67000A071052904D0E07980088000E071C1E76D -:10A68000E07980088000401CF8E7A088002101F0F4 -:10A69000FEFA002804D02320D049400111F027FC05 -:10A6A0002221284658E00498068015E0002C01D0AD -:10A6B0006888A080287A032828D004280FD005288D -:10A6C0004DD09720C549C00011F011FC0498002C12 -:10A6D000068001D027806680002005B0F0BD1527D8 -:10A6E0000C26002CDFD00023A0880122194601F09F -:10A6F00098FA050004D1BA48B849483011F0F7FB80 -:10A700000622A11DA86905F00FFDDFE71627072621 -:10A71000002CC8D0A088FDF74CFB00900023A08837 -:10A720000122194601F07DFA05460098002801D063 -:10A73000002D04D1AA48A949563011F0D8FB287839 -:10A74000C00601D5022000E00120A0710098007829 -:10A750002328BBD927210098FDF763FBB6E717270D -:10A760000C26002C9FD0A088FDF723FB00906D7A6B -:10A77000002804D19A489949693011F0B8FB0621A4 -:10A78000A01D11F087FA0020A071207A0321084350 -:10A790002072FB2108400099C97FC907490F08436F -:10A7A0002072680692D5E07904210843E071A07A0E -:10A7B000E90740084000C90F0843E17A2A07490821 -:10A7C0004900D20F1143FD22AB07DB0F10405B00A5 -:10A7D0001843A072E806C00F114040000143E17227 -:10A7E00074E710B50446807990B08009012804D040 -:10A7F0007B487A499B3011F07AFBFFF760F9012022 -:10A800006946087074480AA9A0380190201D02907A -:10A81000601C0B906846FDF7E1F9002804D07048F1 -:10A820006E49A53011F063FB0322601C0B9911F0F7 -:10A83000D4F910B010BD10B5674CA03C002805D06D -:10A8400001461022204611F0C8F90120207410BDE5 -:10A8500010B50446FFF733F95F491022A0392046AE -:10A8600011F0BBF910BD70B500255B4C00281BD062 -:10A870005C49884206D301218904884204D35A499D -:10A88000884201D210250DE0062105F037FC411C5D -:10A8900007D051494039C865207E80210843207681 -:10A8A00000E00725284670BD207E4006400EF6E7F2 -:10A8B000F3B5002089B00D460290002909D049481F -:10A8C00085421BD301208004854202D3464885423D -:10A8D00014D30998FDF76DFA060003D030782228CA -:10A8E00015D102E041480BB0F0BD002D08D1B07F7A -:10A8F000C10903D08007800F022801D01020F2E7A1 -:10A90000B07FC10601D4000703D5002D01D0082077 -:10A91000E9E73148007EC00712D1F07F400701D53A -:10A920000D20E0E7002201231146099801F079F992 -:10A93000070005D0B07F8007800F022802D00BE00F -:10A940001120D0E7002D07D02A4639463046FFF7C0 -:10A9500021F802900028C6D11F488C38F8F7BAFABF -:10A96000040003D11D49224811F0C1FA0A202070C9 -:10A970000998206238468830A060B07FFB218007AC -:10A98000800F012838D0002D4CD002202071381DB6 -:10A99000E06038780007400F20743878C006C00F98 -:10A9A0006074A07C2A788008D2078000D20F104300 -:10A9B000A0740840F17F01AAC907490F0843A07499 -:10A9C000A878E07469462846FFF724F868460079BD -:10A9D0002075684600780DE02C160020809D000050 -:10A9E0003604000000D001000028002002300000E2 -:10A9F00064050000607519E001202071207B2A7831 -:10AA00008008D2078000D20F1043207308402978B5 -:10AA10008907C90F89000843207324213046FDF7B8 -:10AA200000FA0BE003202071052020732521304619 -:10AA3000FDF7F7F9B07F4006400EB07703A9204636 -:10AA4000FDF7CCF8022805D0002803D0FB49FC48CC -:10AA500011F04DFA029846E7FFB581B00A9D06460F -:10AA60001C4617461421284611F016F90B980021B0 -:10AA70000160F8070DD0F3492068884237D31230BF -:10AA800028602068143068602068A8600B982168EE -:10AA90000160B80725D56068002802D0E9498842DE -:10AAA00025D3029900290AD0FC3600280ED0314661 -:10AAB0001030FDF73AFB00281AD1606810E000283A -:10AAC00015D0E86080366068B0670AE0FEF757F995 -:10AAD00001460722304611F080F8FEF7F0FFDA4811 -:10AAE000E860780706D5D749A068884201D21020CF -:10AAF000F3E528610020F0E5FFB5D44A0E4607CA09 -:10AB000097B002AB07C30027009701971798FDF78E -:10AB100050F9050005D02878262804D008201BB05D -:10AB2000F0BDCB48FBE700231A461946179801F001 -:10AB300078F8040004D1C248C049803011F0D7F938 -:10AB4000A87F8007800F1690012814D0022824D0F7 -:10AB5000C520BA49C00011F0CAF901210022852E92 -:10AB600031D01EDC002E26D0812E26D0822E26D07B -:10AB7000832E1ED125E0002EEFD121462846199ABA -:10AB8000FEF708FF0028CAD119988078009019981C -:10AB90000078C007C00F0190DFE71998002808D19E -:10ABA000DBE7862E11D0882E11D0892E11D08A2E67 -:10ABB00011D00720B3E710460EE008460CE0022053 -:10ABC0000AE0032008E0052006E0062004E0082053 -:10ABD00002E0092000E00A200022227101216A46D9 -:10ABE0001176211D0791002801D02071F9E01698F7 -:10ABF00001280CD0A66AE06A0222012110900020F0 -:10AC0000A0602846173002291AD0012119E0E66A0F -:10AC1000A06A1090032030702078FB23C006C00F7C -:10AC20007070B07801221840009BF3708008019B7F -:10AC3000800018430221B070002070713071DEE78F -:10AC40000021890009190861681C022A01D001212C -:10AC500000E00021890009190861B0788007800FA1 -:10AC600001285DD1109880788007800F012857D186 -:10AC70001098007984461098407900901698012821 -:10AC80001CD0317908A801747179017508A8027C7B -:10AC90006046024008A8007D0099084013901043C8 -:10ACA0003ED06C491A98884206D301218904884213 -:10ACB00014D36449884211D2102030E70CAA0DA9A0 -:10ACC0001998FEF7A7FE08A8007C6146084030717D -:10ACD00008A8007D009908407071D7E720463C30F5 -:10ACE00021460090F03116980191022834D00021BD -:10ACF0001A9B20460C33FFF7AFFE0028DDD120461B -:10AD0000503021460090F43116980191012825D049 -:10AD1000002120461A9B139AFFF79EFE0028CCD1F3 -:10AD200010988078400702D4E87FC0072BD016998E -:10AD300002A8012914D0109909784900405A2178B5 -:10AD40000907490F4900C8408707BF0F2AD0012FC4 -:10AD500014D0022F0FD113E00121C9E70121D8E758 -:10AD600021780907490F4900405A1099097849008C -:10AD7000C8408707BF0F032F04D004E0022711E06B -:10AD800001270FE00227169801280BD1B078FB218C -:10AD90000840E97FC907490F0843B07020780007D1 -:10ADA000400F307020781022400840002070109929 -:10ADB000D2434978C907C90E114308402070C00624 -:10ADC00025D4022F23D0012F23D00020A061E061E1 -:10ADD0002062606220461830A060E87F4008400092 -:10ADE000E877204606A98830FCF7D4FE002805D075 -:10ADF000022803D01149184811F079F82878212841 -:10AE000003D025212846FDF70CF8002087E6032013 -:10AE100008E020460D211B3010F03CFF2046183082 -:10AE2000A060042069460875E87F01210843E8779F -:10AE300005AA29461798FEF72AFED2E7809D000052 -:10AE40008F050000002800208C150020CCC10100D7 -:10AE50000230000000D00100F1060000F0B587B01C -:10AE600015460E0004460CD09F48854206D30120AB -:10AE70008004854205D39D48854202D2102007B048 -:10AE8000F0BD2046FCF795FF070004D0387827284E -:10AE900003D00820F3E79648F1E700231A46194645 -:10AEA000204600F0BEFE040003D19249924811F002 -:10AEB0001EF80020002E05D0022E08D0012E11D041 -:10AEC0000720DCE701216A461171A06018E02346E3 -:10AED00018336946A360087110222946184610F0FD -:10AEE0007CFE0DE021461831A16069460871A06121 -:10AEF000E061206260620621284605F0FFF8A0614B -:10AF00002078C10714D04008400020700220694614 -:10AF100008702046183002907030FCF73BFE022883 -:10AF200006D0002804D074487249233010F0DFFFA7 -:10AF300025213846FCF775FF0020A0E7F8B5154637 -:10AF40000E460746FCF735FF040004D0207822287F -:10AF500003D00820F8BD6648F8BDA07F8007800FA9 -:10AF6000022802D06248C01CF8BD5F4886420CD35C -:10AF7000012189045D4A8E4201D3964205D3854260 -:10AF800003D38D4203D3954201D21020F8BD009522 -:10AF90003288B31C21463846FEF7A4FD112816D08E -:10AFA0000028F3D1E17F2A7C4908D2074900D20F5B -:10AFB0001143E1772A7C49079206490FD20ED2004D -:10AFC0001143E177A17F4906490EA177F8BDA17F22 -:10AFD0000907FBD420460822B11C343010F0FDFDD7 -:10AFE00030886086204610222946223010F0F5FD78 -:10AFF000E07FFD210840297CC907890F0843E077DD -:10B00000287C410820200155A07F08210843A07713 -:10B010000020D7E770B594B00D460646002B02D04D -:10B02000072014B070BDFCF7C4FE040007D02078E0 -:10B03000222802D3A07F400603D40820F1E72C4841 -:10B04000EFE7002D19D02D216846017046801022AF -:10B05000294601A810F0C1FDE07F297C4008C907FE -:10B060004000C90F0843E077297C40078906400F5C -:10B07000C90EC9000843E07703E02E21684601703D -:10B08000468009A96846F7F75CFF694609782D29CB -:10B0900005D1002803D1A17F10221143A177A17F00 -:10B0A000BF221140A177BCE710B50C46FCF781FE2A -:10B0B000002804D00D498C4203D2102010BD0C484A -:10B0C00010BD2146FEF7F5FF002010BD05E0027817 -:10B0D000401C002A01D0002070470A46491E89B250 -:10B0E000002AF4D10120704700D001000028002080 -:10B0F00002300000809D000013070000F7B50F46E6 -:10B10000FA4D0146029A687C072A01D02A7C101A5F -:10B11000C6B2FC78084600F077FD297C401C484305 -:10B12000401EC2B238790FE0029B072B13D0630098 -:10B130005B199B7C072B01D0761EF6B2641CE4B22F -:10B14000944201D9631ADCB20346401EC0B2002B00 -:10B15000EAD13046FEBD63005B199B7C072BEBD028 -:10B16000ECE7FFB581B00D460A9F0B9C019800F0FB -:10B170004BFDDE4E401C317C039A4843401EC0B25A -:10B18000009029460198FFF7B9FF00280BD02879D5 -:10B19000317C884203D3D6A1BB2010F0A8FEA8784A -:10B1A000C00908D01AE00398072802D0112005B082 -:10B1B000F0BDD448FBE701982080381D6080002056 -:10B1C00060712071E780049820812046F7F7E1FE46 -:10B1D000002803D1C6A1C82010F089FEE87829799B -:10B1E0004018491C29710099C0B2884202D9317CAB -:10B1F000401AC0B24000801903998174C17CF122C9 -:10B20000490849001140C1740020D0E7FFB583B060 -:10B210001C4616460F4600231A4602210C9D039831 -:10B2200000F0FFFC010008D033463A460195009437 -:10B230000398FFF796FF07B0F0BDB248801EFAE70B -:10B24000F0B5054616460F4650888DB00023012202 -:10B25000022100F0E6FC040003D1A5A1FA2010F0C1 -:10B2600046FE002069460871A078400603D1A0A1DF -:10B27000FE2010F03CFE042F5ED32A78D007C017C2 -:10B28000401C06D161786B78994255D12178090725 -:10B2900052D00121142A46DA012A42D0122A02D0C1 -:10B2A000132A40D128E00C2F3DD1A2785206520E2D -:10B2B000012A38D0207800090001401C20706878ED -:10B2C00060706846017168792A7901021143684605 -:10B2D0000181E879AA790102114368464181687ABF -:10B2E0002A7A0102114368468181E87AAA7A01022A -:10B2F00011436846C1811AE0062F14D12078000955 -:10B30000000120707188012001F097F90221684640 -:10B310000171C91E018168792A79010211436846C9 -:10B320001FE0062F0AD06A461279002A1BD07088C7 -:10B33000324601A9FDF792FB0DB0F0BD207800095F -:10B34000000120707188012001F077F90221684620 -:10B35000017168792A79010211436846018100214F -:10B36000C9434181E3E70028E6D0748868468176C6 -:10B370006978C176022181830021C18304A8052256 -:10B3800000900C2311462046FFF740FF0028D3D041 -:10B390005DA1F12010F0ABFDCEE7F7B592B01546F8 -:10B3A00012991398FAF7A5F9C0B2082860D10020C5 -:10B3B00069468881688800230122022100F031FC5F -:10B3C000060004D1FF204AA17E3010F090FD68886D -:10B3D00001210E910027F47800F016FC434A401C2E -:10B3E000117C48438C46401EC1B230790FE03F4A81 -:10B3F00063009A18937C0E9A934201D17F1CFFB28E -:10B40000641CE4B28C4202D96246A21AD4B202464B -:10B41000401EC0B2002AEAD1002F02D1172168468F -:10B42000818106AB023303AA009512991398F8F7AD -:10B4300032FC0006000E07D002281BD0032817D0CC -:10B44000FF202BA1A43011E06846808900280FD08E -:10B4500004A9019100906888042301223146FFF776 -:10B4600080FE002804D0FF2021A1913010F03FFD84 -:10B4700015B0F0BD6878102108436870F8E710B582 -:10B4800000221A4913465400521C0B53082AFAD3BF -:10B49000012807D0022809D0FF2015A1E53010F0BF -:10B4A00026FD10BD0F200874072002E0022008745A -:10B4B0000120487410BD70B50C460021A1702178A0 -:10B4C0000025090909012170657000F09DFB0749FD -:10B4D000097C4843C0B2E0704018102804D9FF200E -:10B4E00003A1F13010F003FD257170BD4C16002052 -:10B4F0007372635C6C326361705F636F72652E633D -:10B5000000000000043000007372635C6C32636101 -:10B51000705F636F72652E630000000070B50D46AA -:10B5200000230122022100F07CFB040004D1FF2053 -:10B53000FD49F93010F0DBFCA0786906C009C001B4 -:10B54000490E0843A070D0E7704710B501460120AE -:10B5500001F073F810BD3EB58DB200230122022127 -:10B56000284600F05EFB040003D1EF49EF4810F0DD -:10B57000BEFC207869460009000120700220087096 -:10B58000EB488880C88000222846FDF767FA3EBD58 -:10B59000F7B505460078002700090C463E4601280D -:10B5A00004D08720E049800010F0A1FC287A03280D -:10B5B0000CD0DE48DC49253010F099FC0298002CB4 -:10B5C000068001D0278066800020FEBDEA897027B2 -:10B5D00010460A3086B2002C0AD06888A080A8895C -:10B5E0002081E28020460A30296910F0F6FAE5E76A -:10B5F00002980680E8E7F8B543680246D9799C7955 -:10B60000090221435C7A1E7A25025C88981D354325 -:10B61000241FA1421DD11B79022B1AD1042D19D050 -:10B62000052D22D0062D19D0402D12D3061D0F4610 -:10B630001446284600F023FA08280AD0112020706A -:10B6400003202072A581E7812661607808210843E4 -:10B650006070F8BD001DFFF7A0FEF8BD031D508807 -:10B660000A461946FEF705FEF8BD001DFFF7E8FD86 -:10B67000F8BD70B50D4600238CB006461A4602216F -:10B6800000F0CFFA040031D020780007000F012825 -:10B690002ED012206946887460780523801CC874F7 -:10B6A000082088822888C88268880883A8884883F8 -:10B6B000E888888302A90C20019100901A4621464F -:10B6C0003046FFF74EFD00280ED1F0230022314610 -:10B6D000012000F00DFF207800090001401C2070BF -:10B6E0006078801C607000200CB0FEE69148FBE79B -:10B6F0001120F9E770B50D4600238CB006461A46B6 -:10B70000022100F08EFA040006D020780007000F16 -:10B71000012803D00820E7E78648E5E713216846BB -:10B7200081746178C17402218182C58202A90620D8 -:10B730000523019100901A4621463046FFF711FD7E -:10B740000028D1D120780009000120700020CBE72B -:10B75000F3B581B00D46002301220221019800F0CB -:10B7600060FA00260446002804D170486E49CA30A9 -:10B7700010F0BDFB2079A84243D25B206A49C0008B -:10B7800010F0B5FB3DE0E778019800F03DFA6A491A -:10B790007B000A7C5F18B97C0091E178401C504323 -:10B7A000491C401EC9B2C0B2E170814201D9881A59 -:10B7B000E0702079401E2071F87CC00708D0009905 -:10B7C0000198042915D058499C20183110F08FFB9E -:10B7D000F87C0107480F08D0490F019804290BD0C5 -:10B7E0005149A920183110F082FB0098072808D190 -:10B7F00005E0FEF7BBFDEBE7FEF78BFDF5E7761CFA -:10B80000F6B228466D1EEDB20028BCD13046FEBD12 -:10B8100010B500230122022100F003FA040004D134 -:10B8200042484149F23010F062FB00202071A078BC -:10B8300080210843A07010BDF7B582B015460F46B1 -:10B8400000231A460221029800F0EBF93A4C060058 -:10B8500005D0002F0FD0002D0AD0062009E0072FB9 -:10B8600004D0207C617C401AC0B2A0E4607CFBE77D -:10B870000820B84203D82C49304810F038FB3A462B -:10B8800031460298FFF73AFC0090002D24D00028A2 -:10B8900022D1F578029800F0B7F9217C401C48438A -:10B8A000401EC2B2307910E06B001B199E7C072E3F -:10B8B00003D0DE7C3607760F10D06D1CEDB29542BA -:10B8C00001D96B1ADDB2401EC0B20028ECD1CB20EA -:10B8D0001549800010F00BFB009868E46900091915 -:10B8E000C97CF12211407A07120F1143D974002844 -:10B8F000F2D1ECE7F3B5002381B007461A460221E6 -:10B9000000F08FF9060004D10C480749283010F0E8 -:10B91000EEFA0298401E052804D3CF200249800089 -:10B9200010F0E5FA00250BE0F0B400000D02000075 -:10B93000FFFF0000023000004C160020130300003F -:10B94000F478384600F060F9534F401C397C484386 -:10B95000401EC2B2531C3079D9B218E04E4E670077 -:10B96000BE19B446B77C029EB74208D16146C97C75 -:10B970004E0876006146CE746D1CEDB22146641C03 -:10B98000E4B2944203D9444E367CA41BE4B206468A -:10B99000401EC0B2002EE1D1994206D23E48490075 -:10B9A0000818C17C01221143C1742846FEBD3B49E1 -:10B9B000884201D2102070473749497C017000202D -:10B9C000704710B50446402801D2072010BD00F092 -:10B9D00056F8082802D03120000210BD00212E4860 -:10B9E00002E0491C082903D24A00825A002AF8D1F1 -:10B9F000082903D049004452002010BD042010BD86 -:10BA000010B5402801D2072010BD00F038F80828F2 -:10BA100005D00021204A40001152084610BD0520E3 -:10BA200010BDF0B58BB016460C00074607D0002EAF -:10BA300005D06188402904D207200BB0F0BD10204A -:10BA4000FBE72088002801D0172801D90C20F4E753 -:10BA5000084600F014F808280FD0258803A82A46C5 -:10BA60003146023010F0B9F801A8009062882B46E8 -:10BA700007213846FFF7CAFBDFE70520DDE701466F -:10BA80000020054A02E0401C082803D24300D35A94 -:10BA90008B42F8D1704700004C160020002800208F -:10BAA000F8B50546E24C079E069821706270A370B7 -:10BAB000E6702071681C42085200DE4B00218800AD -:10BAC00000198446C261605C40008218002D0AD0D3 -:10BAD000002005E066464700F669401CF353C0B2FB -:10BAE000665C8642F6D8491CC9B20529E7D3002610 -:10BAF000D21C9708B000BF0000198760304600F0E4 -:10BB000041F9A15D761C4843C219F6B2052EEFD368 -:10BB1000501B80B2F8BDF0B50546C54F8C460020DD -:10BB2000FF247E5DA90096460346CF190CE0F96913 -:10BB30005A008A5ABF498A4204D1401CC0B2FF2C25 -:10BB400000D11C465B1CDBB29E42F0D86146002946 -:10BB500009D100280BD0002D07D0B54949788E4275 -:10BB600003D2401EC0B2002801D071460C70F0BD57 -:10BB700070B5AF4C8D0000232D19615C09E0EC69B4 -:10BB80005E00A45B844202D11370012070BD5B1C77 -:10BB9000DBB29942F3D8002070BDFEB51C461746B3 -:10BBA0000D46060008D0002D06D0F01C800880004D -:10BBB000B04203D01020FEBD0E20FEBD002F03D0EA -:10BBC000002C01D0A74201D90720FEBD00942346D6 -:10BBD0002246394600200194FFF762FF29888142FE -:10BBE00007D0814201D2042100E0092128800846C3 -:10BBF000FEBD009423462246394630460194FFF7A5 -:10BC00004FFF28800020FEBDC0B2704708B5052850 -:10BC100001D2022901D3002008BD6A46FFF77BFF4D -:10BC200008BDFFB50446834881B01E460D468442D8 -:10BC300004D0052D02D20398022802D3002005B0BB -:10BC4000F0BD002769460F7020466A462946FFF777 -:10BC50008FFF002817D068460178284600F09CF82E -:10BC6000002EECD00028EAD171484078A04204D8D8 -:10BC7000FF2071A1553010F03AF929462046039A69 -:10BC800000F096F8DBE73846002EEDD1D7E7F8B59F -:10BC900005460C460020674E69466B4F0870B5425A -:10BCA0003BD0052C01D30720F8BD0A462146284683 -:10BCB000FFF75EFF002830D068460178204600F08C -:10BCC0006BF8230010F041FA0504090C11161B0053 -:10BCD00001462846FEF7E5F915E0FDF7A5F812E064 -:10BCE00001462846FFF730FC0DE001462846F7F7ED -:10BCF00055FF08E001462846F9F783FB03E053A10E -:10BD00007B2010F0F4F84A4A6846A10000788918B0 -:10BD1000C96940000E520020F8BD3846F8BD4F4AB0 -:10BD2000914201D210207047052801D307207047A7 -:10BD30000872002048727047F8B5044647488442AC -:10BD400001D21020F8BD207A394A83009B18617A0D -:10BD5000384D125C11E0DE694F00F65BAE420AD04E -:10BD60004A1C6272DA694B00D25A228000F014F841 -:10BD700060600020F8BD491CC9B28A42EBD86172EC -:10BD80000520F8BD0EB5364B40000ECB0091029356 -:10BD900001926946085A0EBD70B50C460546FFF77C -:10BDA000F1FF234AA900891889686043401870BDD3 -:10BDB000F8B50C46064600206946134608706A46E8 -:10BDC00019462046FFF7A7FE002500282DD0184A67 -:10BDD0006846A10000788918C96940000E5268467B -:10BDE00001782046FFF7D8FF0546230010F0ADF993 -:10BDF0000504090C1116190029463046FEF72DF9E5 -:10BE000013E0FDF701F810E029463046FFF753FB39 -:10BE10000BE029463046F7F78FFE06E0F9F7EAFA1D -:10BE200003E00AA1622010F062F82846F8BD000085 -:10BE300080160020FFFF00007372635C686F7374EC -:10BE40005F636D2E63000000023000007372635C5C -:10BE5000686F73745F636D2E63000000002800201C -:10BE6000D8C101004B490968016000207047494969 -:10BE70000860002070470121474A484B002803D042 -:10BE8000012805D04648704791630020187001E0F2 -:10BE9000D163197000207047424901200860404872 -:10BEA000801C70470422404B3E49002805D05A6050 -:10BEB000086901221043086108E008694008400051 -:10BEC00008619A6034490020C031886000207047C2 -:10BED00034490622002808D0012809D002280DD0B4 -:10BEE00003280FD02E48401C70470869904302E099 -:10BEF00008699043801C08610020704708699043DE -:10BF0000001DF8E708691043F5E726494A6A02432D -:10BF10004A620020704723494A6A82434A620020ED -:10BF200070472049496A0160002070471D49CA696D -:10BF30000243CA61002070471A49CA698243CA6134 -:10BF4000002070471749C9690160002070471549F2 -:10BF5000024600204031002A03D0012A01D00720E8 -:10BF600070478A6370471049042088600A4900209E -:10BF7000C03188600949012008700C490A68802393 -:10BF8000120A12021A430A600949086070470348FE -:10BF9000007870470004004040000040640000202A -:10BFA00004200000000500400003004000E400E021 -:10BFB00000E100E08107C90E002808DA0007000F41 -:10BFC00008388008B94A80008018C06904E08008F9 -:10BFD000B74A800080180068C8400006800F70478C -:10BFE000B44948788978884201D3401A02E0212276 -:10BFF000511A0818C0B27047AE4923314878897881 -:10C00000884201D3401A02E02122511A0818C0B216 -:10C010007047A849463148788978884201D3401A48 -:10C0200002E02122511A0818C0B27047A04810B58A -:10C030000C300168FF22120291430122D203114306 -:10C0400001609C4900202331487088702339487072 -:10C050008870463148708870974804F092FA964884 -:10C06000401C04F08EFAF6F759FB00F015F910BDEC -:10C0700020207047B4E770B50C4605460026FFF750 -:10C08000AFFF8C49A04214D30A46203A0023204631 -:10C09000641EE4B200280BD08878105C2870887881 -:10C0A0006D1C401CC0B288702128F0D18B70EEE767 -:10C0B000012600F0F1F8304670BD202070479BE764 -:10C0C00070B50C4605460026FFF796FF79492331E7 -:10C0D000A04214D30A46203A00232046641EE4B24C -:10C0E00000280BD08878105C287088786D1C401C64 -:10C0F000C0B288702128F0D18B70EEE7012600F0E5 -:10C10000CBF8304670BD202101700020704710B57B -:10C110000446FFF77EFF2070002010BD70B50C466E -:10C120000546FFF776FF63494631A04215D30A461C -:10C13000203A00232046641EE4B200280BD0887801 -:10C14000105C287088786D1C401CC0B28870212853 -:10C15000F0D18B70EEE7002400E0584C00F09CF822 -:10C16000204670BD70B50C460546212904D9FF2034 -:10C1700053A147300FF0BBFE4C484068103840B226 -:10C18000FFF718FFC6B20D20FFF714FFC0B28642BA -:10C1900007D2FF204AA14D300FF0A9FE01E0F6F7CB -:10C1A000FDFA21462846FFF766FF0028F7D070BD4C -:10C1B000F8B5404E07462336B1787078212200F05A -:10C1C00060F8354623353B4C00280ED0A1786078C6 -:10C1D000212200F056F8002814D0A978687821228E -:10C1E00000F04FF800281AD025E032497078C91CB9 -:10C1F0000F547078401CC0B2707021281BD10020F1 -:10C20000707018E02B49607820390F546078401C1A -:10C21000C0B2607021280ED1002060700BE025496B -:10C22000687826310F546878401CC0B268702128A5 -:10C2300001D100206870B1787078212200F021F8D7 -:10C2400000281DD0A1786078212200F01AF800287B -:10C2500016D0A9786878212200F013F800280FD0B2 -:10C26000F6F77EFA144804F094F901214903884254 -:10C2700003D013A1C1200FF03AFE0F4804F0A1F93A -:10C28000F8BD401C884205D0904201D1002901D060 -:10C29000002070470120704710B5074804F079F975 -:10C2A000002801D1F6F74BFA10BD000000ED00E0C8 -:10C2B00000E400E0F01600206500002007200000E8 -:10C2C0007372635C736F635F72616E642E630000F0 -:10C2D0000C4908784A78401CC0B2904200D00870DF -:10C2E0007047094A074820BF40BF20BF4178037804 -:10C2F00043701368002B02D103788B42F3D00020E7 -:10C30000704700006700002000E200E0FEB5F34C3B -:10C3100007466068FF213E0181552178FF2913D02F -:10C320000901083141583246491E0832090201927A -:10C33000090A805800F0C8F9002802D02478254660 -:10C3400015E06168207888552770FEBDE348426893 -:10C3500001981158280100900830105800F0B4F9E5 -:10C36000002806D1DD482C46416800980D5CFF2D61 -:10C37000ECD1DA482101406885554754FEBD70B5BF -:10C38000D64A04460020157A53680AE00201561C7A -:10C390009E5DA64203D10C329A588A4204D0401CBA -:10C3A000C0B28542F2D8FF2070BDF8B5CB4F3E78C1 -:10C3B00001F002FE0146FF2E68D034012546786860 -:10C3C0000835405900F080F9022802D978684059B0 -:10C3D0005AE0C2494868025D0A70A11C425C002A0A -:10C3E0000CD0521E425441590122D205891809022B -:10C3F000090A41513046FFF789FF30E0631CC25CF7 -:10C400000092221D94468258002A10D001239B02DC -:10C410009A420FD99205920D43595703DB191B021B -:10C420001B0A43516346C3589A1A920A09E0FF2136 -:10C43000C1540AE0435952039A181202120A425197 -:10C44000002242543046FFF761FFA4480C34416893 -:10C45000C2680098095980001258009890479F4C74 -:10C460002078FF2812D001F0A7FD014620786268ED -:10C4700000010830105800F027F9012896D92078DB -:10C48000616800010830085801F089FDF8BDF8B571 -:10C490001C4615460E460746FF2B03D390A1D3201A -:10C4A0000FF025FD8D48FF21C760456004720674BA -:10C4B000017000224270104604E00201521C401C30 -:10C4C000A954C0B2A042F8D3F8BD70B5834C06465B -:10C4D0006578207C854203D381A1E6200FF007FD1B -:10C4E000E068A90046506078401C6070284670BD26 -:10C4F000FFB581B01D46FF2401F05EFD774F064673 -:10C5000079780198814203D875A1F4200FF0EFFCEF -:10C5100072480021037A406810E00A019446521CD8 -:10C52000825CFF2A24D0019FBA4205D162460C32B8 -:10C530008758029A97421DD0491CC9B28B42ECD849 -:10C54000FF2C17D021014B1C019AC2540B33029AC5 -:10C55000C250039B614F0022012B0ED00B1DC25015 -:10C5600001239B029D4216D9AA05920D08D008E02E -:10C570000C46E1E7FF2005B0F0BD0B1DC550EFE70D -:10C580001A4653039B190E461B0208361B0AAA1AA9 -:10C590008351920A09E0002D00D101256B039B19FC -:10C5A0001D022D0A0B460833C550891C42543D46D6 -:10C5B0003E782046FFF7AAFE2878B04215D001F059 -:10C5C000FBFC014628786A6800010830105800F02A -:10C5D0007BF8012807D928786968000108300858D5 -:10C5E00001F0DDFC01E0FFF7E0FE0198C3E770B564 -:10C5F0000C46054601F0E0FC064621462846FFF7BA -:10C60000BEFEFF2817D0354D04012046696808306A -:10C610000858314600F058F80121090340186968AC -:10C62000A41C095D400B002901D0890208180028CC -:10C6300000D1012070BD002070BDF3B581B00F4660 -:10C640000198FFF79CFEFF282AD0244D2E786968B8 -:10C650003246344604E0844205D026462301CC5CB1 -:10C66000FF2CF8D11CE0FF2C1AD0A6421FD11001DC -:10C67000085C2870FF2818D001F09EFC2A7801463B -:10C68000120168680832805800F01EF8012809D9A4 -:10C690002878696800010830085801F080FC06E03D -:10C6A0000020FEBDFFF781FE01E001F080FC39466D -:10C6B0000198FFF79CFF22016968FF23541C0B556A -:10C6C0008A5C3301CA54FEBD401A00020121000AEF -:10C6D000C905884200D90020704700003C1700209F -:10C6E0007372635C736F635F74696D65722E630050 -:10C6F000F0B500241C4A01211C4B0803546018604B -:10C700001B4B1C601B4C20601B480469E443E4067F -:10C71000E6170469761C10252C430461174C6160F0 -:10C72000174D296000E020BF1F68002FFBD0002EAE -:10C7300003D107691026B7430761906880059068A8 -:10C7400001D5104A10436960A160002119600121E0 -:10C75000084A09031160F0BD10B50446FFF7C8FF91 -:10C760002060002010BD000000C5004080E100E016 -:10C7700000C1004080E200E000ED00E000C30040A6 -:10C7800000C0004000FCFFFF70B51F490A68002A86 -:10C7900017D000231D4601244A68521C4A60092A0A -:10C7A00000D34D600E792246B2400E6816420AD080 -:10C7B00072B60B6893430B6062B649680160002053 -:10C7C00070BD052070BD5B1C092BE5D30FA1362081 -:10C7D0000FF08DFBF5E701201049800508607047D8 -:10C7E000EFF31081CA07D20F72B6012181400648CB -:10C7F000036819430160002A00D162B6EBE70248E2 -:10C8000000210160416070476C0000207372635C1E -:10C81000736F635F6576742E6300000000E200E0D2 -:10C820000120810708607047012081074860704738 -:10C830001048C068C00700D0012070470D488068CC -:10C84000C00700D0012070470A484069C00700D0E7 -:10C85000012070470748C069704706498A69D203BA -:10C8600006D589698907890F814201D10120704766 -:10C870000020704700040040F8B5FE4C207EE17DAA -:10C8800088421AD00126FC4D0027E07D215C14204F -:10C890000A4642435019037C052B0FD0062B1BD0B0 -:10C8A000072B28D0437C012B33D0F4A1F6480FF09E -:10C8B0001EFB207EE17D8842E7D1F8BD0674E07D55 -:10C8C000162807D0E07D401CE075491CC8B2AA5864 -:10C8D00002210CE00020F7E70674E07D162808D05E -:10C8E000E07D401CE075491CC8B2AA58032190475E -:10C8F000DFE70020F6E70674E07D162807D0E07D2C -:10C90000401CE075491CC8B2AA580821EFE7002076 -:10C91000F7E74774E07D162807D0E07D401CE075FE -:10C92000491CC8B2AA580721E1E70020F7E770B513 -:10C93000D64D0C206872D648002444730473283006 -:10C940000476C475D34803F01CFED3480475EC721A -:10C95000D249601E88606C71AC70EC702C716C7088 -:10C96000CF48052104704470CE4804700475283007 -:10C970000470491EFAD10120F5F796FF0020F5F763 -:10C9800093FF0120A871F5F74DFCC748F5F75CFC53 -:10C99000C64C2070C648F5F757FC6070F5F724FFC9 -:10C9A00070BD10B5F5F74BFFC04C2078F5F76AFC69 -:10C9B0006078F5F767FCB54C207A002803D0F5F7CE -:10C9C000F0FC0020207210BD70B5B04CA07900289A -:10C9D00004D0AAA1B7480FF08AFA70BDE07A002807 -:10C9E00003D1A6A1B4480FF082FA0126A671002552 -:10C9F000E572607A0421142250439F4A8018017422 -:10CA0000A6488168491C04D0691E81600120F5F7A1 -:10CA10004BFF0020F5F748FFF5F72CFF03F0F2FE7F -:10CA2000F6F72DF8A548056005600120A449C0036C -:10CA30000860F6F79DF89A480078022804D0032889 -:10CA400004D1E078002801D0A67000E0A570F6F7C8 -:10CA500002F870BD034688490B2014224243521845 -:10CA6000203A127F002A04D0401E0006000EF4D1A6 -:10CA700070471422424351180A46403AD3620122B9 -:10CA800020390A777047012805D0032805D10029ED -:10CA900003D1002070470029FBD010B47B4C002349 -:10CAA00063707F4A002890700CD002280AD00729B2 -:10CAB0001AD20B007B441B79DB189F441505070D28 -:10CAC0000F111300D37003E01B2000E03A20D07058 -:10CAD0000120607010BC70475820F8E77720F6E717 -:10CAE0009620F4E7B520F2E710BC0020704710B59F -:10CAF0006B484078F5F7CAFF80B210BD411E142282 -:10CB0000504310B55C4A8418203C0A2902D8207F83 -:10CB1000002803D159A16B480FF0E9F9207F0128C3 -:10CB200004D0B32055A180000FF0E1F90020207758 -:10CB300010BD70B5564C607B217B884201D1012528 -:10CB400000E00025F5F73BFFF5F7A0FF617B227BB6 -:10CB5000914201D1012100E00021A942EBD170BD39 -:10CB6000F7B50646481E84468EB0C0B21422049023 -:10CB70005043414A851828460595007C2D1D0728FD -:10CB80002AD13C4C0027E07D227E824221D0235CCA -:10CB9000049A934201D1012701E0002F04D0162806 -:10CBA00011D0421CA25C225416280ED0401C227EBA -:10CBB000C0B28242EBD1002F0BD0207E002806D0DD -:10CBC000207E401E04E00022ECE70020EFE7162064 -:10CBD0002076059A0120107460462C4C0A280FD844 -:10CBE00014204143244808182038007F002807D02B -:10CBF0000598007C012807D01098807A012807D07A -:10CC00001EA131480FF073F91098807A01286FD176 -:10CC10000598194B007C022816D0164C207E162849 -:10CC200072D0207EE17D401C884203D113A12748A9 -:10CC30000FF05DF9059901204874217E0498605435 -:10CC4000207E162864D065E0607A049A01469042FE -:10CC500006D0014614277843C018807C9042F8D152 -:10CC6000627A824237D1617A14225143C918897C91 -:10CC700061722DE038190020541900207372635C32 -:10CC800072656D2E63000000D30500005C1A002061 -:10CC900010190020681A0020201900203C1A0020DA -:10CCA0007600002064190020ABC30000740000204F -:10CCB00079C800007D0200005E02000000F500401F -:10CCC00080E200E0CB020000150300002203000018 -:10CCD0000121A17207E014224243D218142779439C -:10CCE000927CC9188A7414220C215043C018817494 -:10CCF0001098007A06281DD203007B441B79DB18AC -:10CD00009F440C161412100EE07D00288ED091E77F -:10CD1000002001E0207E401C2076B5E000210FE0DD -:10CD2000B4210DE073210BE0322109E00A2107E074 -:10CD3000062105E0FF20FE49E0300FF0D8F8002181 -:10CD4000109802910068401A28601099097A002909 -:10CD500012D00221401A0102090A296010980268C3 -:10CD6000406810180002000A68601098807A022853 -:10CD7000109803D0007B71E00421EBE7007A0028D3 -:10CD800012D00222029812181098436810461030F0 -:10CD900018180A90E748029B4078984202D9E37835 -:10CDA000002B03D00A9805E00422EBE7029BC31A8C -:10CDB0000A981818637A10300C2B1CD0637A142749 -:10CDC0007B43DD4FDB195B68994214D0DB4F617AFE -:10CDD000BC4614235943D84BC9184B6889689B1B20 -:10CDE000891B1B0209021B0A090A984237D86345AE -:10CDF00035D8614533D831180A980123081A000242 -:10CE0000000A286010998018C9680002000A471AB1 -:10CE1000CB4A9B05BC469F4201D2384610E00F1A10 -:10CE20009F4201D260460BE0944503D9511A08187D -:10CE3000401C05E0974206D9101A4018401C404299 -:10CE4000002860DC03E0BA49BE480FF050F82968BA -:10CE50000A9808180002000A6860002028726868B2 -:10CE6000102710300002000A68601098407AA872FB -:10CE70001098007A687203280ED200280CD0FFF7B1 -:10CE8000D7FC002803D007E0002011B0F0BD0298C5 -:10CE900042210F1A32200290A6490878012801D0B9 -:10CEA000032809D148780299884205D9E1780029F8 -:10CEB00002D10299401AC7192868A04A801B8446EB -:10CEC00001026868090A801B03021B0A8F421AD8F4 -:10CED0001746914217D8BB4215D8617A0C2916D053 -:10CEE000677A62460C210391009139461423594315 -:10CEF000914BC9188B689B1B934216D803978F7C64 -:10CF00000C2FF2D173E0049801F049F9BCE70599C0 -:10CF1000022204980A74627A0C2A00D0627A8A7417 -:10CF200060720120A07211B0F0BD0C2F5FD0002202 -:10CF3000394694461422804B4A43D21853689B1BAF -:10CF4000834225D2917BAB7A99421BD80598052163 -:10CF5000049D7D4C0174207E16280FD0207EE17D3B -:10CF6000401C884203D1724978480EF0C0FF207EF1 -:10CF70002554207E162800D0CCE6C9E6E07D0028A6 -:10CF8000F1D0F4E701218C46917C0C29D2D102E04A -:10CF9000604600282AD03D46009114202A4642438C -:10CFA00065480621161831741C38007E162866481C -:10CFB00016D0017EC07D491C814203D164A167481F -:10CFC0000EF095FF6048017E4554017E16290BD076 -:10CFD000017E491C0176B57C0098A842DDD106E0AF -:10CFE000C07D0028EAD0EDE70021F3E7009705991E -:10CFF00002200874504D607AB84207D10599009814 -:10D000008874049860720120A07221E003980C2FAC -:10D010000FD00C2803D14EA151480EF068FF0398A1 -:10D02000142250434019049981740599009888741A -:10D030000EE00C2803D146A14A480EF058FF039891 -:10D040001422504340190499817405990C20887466 -:10D05000012011B0F0BD70B50D46064642490024CE -:10D060002046891BA04103D239A140480EF03FFF62 -:10D070003F490020491BA04104D2FD2034A180007B -:10D080000EF035FF3B4A70190021821A8C4101D302 -:10D090003949401870BDF8B5401EC0B2142148434C -:10D0A00025494518687B062813D203007B441B7969 -:10D0B000DB189F44020C0A080604002065E0B42037 -:10D0C00010E073200EE032200CE00A200AE0062077 -:10D0D00008E0FF201EA1E0300EF009FF697B002070 -:10D0E000002952D0022140186968002440180C2100 -:10D0F00000026956000A002949DBF5F7C7FC1A4A05 -:10D1000006460C27EF570021101AA14103D210A1A7 -:10D1100016480EF0ECFE16490020C91BA04104D2AF -:10D12000FD200BA180000EF0E2FEF019114A25E06F -:10D130007CCC00007600002054190020FFFF3F0047 -:10D14000FFFFFF001207000038190020070200004F -:10D150007372635C72656D2E63000000C50300008E -:10D16000DD030000E3030000FF7F841EF3030000E3 -:10D170000020A1070080841E00807BE10021821A2C -:10D180008C4101D3F7494018F8BD0421ABE7F5F70E -:10D190007DFC0C21695600224018F349091AA2416E -:10D1A000F2D24042F8BDF0B5064683B0EF48019098 -:10D1B000457A029534687068001B0702EC483F0A04 -:10D1C000001B00900C2D2DD0142029464143E94826 -:10D1D0000122081884464168E54892058646081BE6 -:10D1E000904210D3631A93420DD3024670467245A3 -:10D1F00003D900984018401C05E073450ED9411A28 -:10D200000819401C404200280CDA60460295857CD3 -:10D210000198C0790028D5D003B0F0BDD649D748D1 -:10D220000EF065FE0298854226D014214843D1496C -:10D230000123401802908068CD499B058C46011B54 -:10D240008646994210D3221A9A420DD3634661450D -:10D2500003D900997144491C06E0194662452DD94D -:10D26000091A0819401C4142002905DD0298B17ACB -:10D27000807B814200D374460C2D15D0BD4914200B -:10D28000454368184268121B1202120ABA420BD2B6 -:10D29000B27A837B9A4200D38468857C0198C079F6 -:10D2A0000028B9D10C2DEAD13068A042B4D0E019E1 -:10D2B0000002000A3460706003B0F0BDAE49AF48B0 -:10D2C0000EF015FED8E7F0B5AD490446486885B0C4 -:10D2D000C005C00D1CD0103840B200280CDA02077F -:10D2E000120F083A920892005118C9698007C00EBF -:10D2F000C1400806800F09E08108A24A8900891808 -:10D3000009688007C00EC1400806800F002808D0B9 -:10D3100000262078002806D0012804D0002005B07F -:10D32000F0BD0126F5E72079062813D203007B44DF -:10D330001B79DB189F44020C0A080604002018E041 -:10D34000B42010E073200EE032200CE00A200AE046 -:10D35000062008E0FF208849E0300EF0C8FD217962 -:10D360000020002905D002214718804D002E02D050 -:10D3700003E00421F8E70020E87102AA6946A068EA -:10D38000F5F78EFB694608228A56E06801A98018E5 -:10D39000C01C01221F2801DA019209E003AAF5F757 -:10D3A0007FFB6846007B002802D00198401C01905A -:10D3B00000990198401810300002000A0190C81B23 -:10D3C0000002000A00906079694688720098039014 -:10D3D000F5F7F5FA009A019B121A181A6A49120217 -:10D3E0000002120A000A8A4216D8884214D86846F7 -:10D3F000FFF7D9FE00990398814205D0C8190002B1 -:10D40000000AF5F743FBA0600120E979002986D0E6 -:10D41000002EB0D005B0F0BD0020F6E7F3B58FB018 -:10D420005A480C460B9003F0B4F8594A0F994F4EE6 -:10D430005518203D574F00280BD05748007D002835 -:10D4400003D056A158480EF052FD207801287DD017 -:10D450005AE1787B16280CD0787B397B401C8842B7 -:10D4600003D14EA151480EF042FD2078012804D08E -:10D470000DE0387B0028F4D0F7E7E87F002804D0DF -:10D480009F2046A1C0000EF032FD0120E877787B96 -:10D490000F991422464D50434019017420780228F8 -:10D4A00023D0787B1421484345192079287260796C -:10D4B00068722A460C322946A068F5F7F1FA0C206A -:10D4C00028560F2804DD1F3828732868401C286060 -:10D4D0000C22AA56281DE16802908818C01C1F283B -:10D4E0003FDA029901200860F7E025494868C00545 -:10D4F000C00D20D0103840B200280CDA0207120FFD -:10D50000083A920892005118C9698007C00EC140BC -:10D510000806800F09E081081A4A890089180968FD -:10D520008007C00EC1400806800F002803D11BA150 -:10D5300020480EF0DCFC787B14214843451900217B -:10D54000E0686A460591117303AA00E0D3E005A9DB -:10D55000F5F7A6FA6A460C2010560F282CDD01209C -:10D560002BE0ADE000807BE1FF7F841E5C1A002091 -:10D57000FFFFFF005419002050D1000012070000E7 -:10D5800000ED00E000E400E0FFFF3F00681A00202B -:10D59000301A002010190020201900207372635CDB -:10D5A00072656D2E6300000015050000F304000095 -:10D5B000501700200405000000200599401808902D -:10D5C0000220A8722079287260796872A068291DEB -:10D5D000C01C03911F2801DA01200AE006AAF5F712 -:10D5E0005FFA6846007E002804D00398039900681B -:10D5F000401C0860287A062813D203007B441B795C -:10D60000DB189F44020C0A08060400200FE0B42037 -:10D610000DE073200BE0322009E00A2007E006202D -:10D6200005E0FF20FD49E0300EF061FC002021798B -:10D63000002943D002214118069168681031401832 -:10D640000899059008180699401A0C900020F0716E -:10D65000F5F7B5F904462860089820180002000A7A -:10D66000E860707A0C2825D0707A14214843EC4980 -:10D67000401840680090059940180002000A019087 -:10D68000687A694688726846FFF78DFD0098019AAE -:10D69000001B121B00021202E24B000A120A0C9934 -:10D6A000984207D88A4205D80099069808180002BF -:10D6B000000A2860F0790028C8D110E00421BAE7F8 -:10D6C00004AA0299F5F7ECF96846007C002804D01A -:10D6D000029802990068401C08602078A872787B44 -:10D6E000162806D0787B401C78730B9802F069FFEF -:10D6F00047E00020F8E7E87F002803D0CAA1CD4822 -:10D700000EF0F5FB0120E877CB490F9808742078DC -:10D71000022803D1C4A1C9480EF0E9FBC64D207907 -:10D720002872607968722A460C322946A068F5F79B -:10D73000B7F90C2028560F2804DD1F3828732868F5 -:10D74000401C28600C22AA56281DE1680290881807 -:10D75000C01C1F2803DA0299012008600CE003AA0C -:10D760000299F5F79DF96846007B002804D00298DD -:10D7700002990068401C08602078A872AE49012018 -:10D780000875797B387B814223D0747A0C2C22D0A7 -:10D79000F5F715F914214C43A1496218117C0429AD -:10D7A00017D0032915D0536892681B1A101A1B0250 -:10D7B00000029C491B0A000A102B0AD30A468B421E -:10D7C00007D8904205D8787B397B884201D0F5F79D -:10D7D00042F911B0F0BD787B397B8842F7D111B0A6 -:10D7E000F0BD10B50020F5F74CF810BD10B50120C4 -:10D7F000F5F747F810BDF1B5009802281ED0904CFF -:10D80000607A0C2803D188A18E480EF070FB0026A8 -:10D81000A6710125E572607A03211422804F5043DE -:10D82000C0190174F5F71CF9009800280BD00128E5 -:10D8300029D0032879D07CA1834844E0834800782C -:10D84000F4F726FDF8BD8248007F002803D076A1BA -:10D8500080480EF04CFB65717D4D00202E60F5F781 -:10D8600023F8A968481C04D0012300221846F5F7C4 -:10D8700051F8607A617A401CC0B2142251437A5840 -:10D8800001219047F8BD0120F5F70EF860790028D6 -:10D890000DD06F488068401C09D0607A617A401CC6 -:10D8A000C0B2142251437A5806219047F8BD684807 -:10D8B000007F01280AD0022812D0032822D0042891 -:10D8C00034D059A164480EF012FBF8BD207900282D -:10D8D00003D02671F5F7C9F8E5705D480677F8BD05 -:10D8E000207A002802D1F4F733FD2572607A617A3C -:10D8F000401CC0B2142251437A580021904754482A -:10D900000677F8BD524F0123397B78680022411A0F -:10D910001846F4F7FFFF2079002803D02671F5F7A9 -:10D92000A4F8E57002203877F8BD19E0484E217858 -:10D9300070680123411A00221846F4F7EBFF207AA1 -:10D94000002802D1F4F704FD2572607A617A401C48 -:10D95000C0B2142251437A58002190473577F8BD60 -:10D96000607A617A401CC0B2142251437A58052172 -:10D970009047F8BD10B5324C607A0C2803D12AA12B -:10D9800036480EF0B4FA607A617A401CC0B21422B4 -:10D990005143234A52580421904710BDF0B583B03B -:10D9A0000C200290F5F70BF8254C0090617A2C487A -:10D9B00001900C2920D0617A14204143184809189D -:10D9C000097C042918D0617A142251430818007C7C -:10D9D00003287DD00198009A036840689B1A801A3A -:10D9E0001B0200020F491B0A000A102B70D30A46C3 -:10D9F0008B426DD890426BD815488068401C03D08C -:10DA000009A118480EF073FA00206071607A0C28A2 -:10DA100030D1607800282DD0134827E09CD5000035 -:10DA200054190020FFFF3F007372635C72656D2E16 -:10DA3000630000001C0500002019002022050000E2 -:10DA40005C1A002053050000A605000074000020A9 -:10DA50003C1A00205F0500009A050000AD0500009B -:10DA60004C1A0020E905000076000020C1784170C2 -:10DA700081780170607A0C2815D0607A1421FF4AF1 -:10DA800048438018007C04280DD1607A0290617AA6 -:10DA900001201423594389180874617A594389185D -:10DAA000897C6172A072F64D687B297BF54F8842B4 -:10DAB00034D0F54E287B142148438019007CC05D8A -:10DAC0000128287B08D048438019007CC05D00E015 -:10DAD000FEE102282ED043E0142148438019807AC9 -:10DAE00001280AD0287B0221142250438019007C8F -:10DAF000C155287B162808D009E0297B0020142274 -:10DB000051438919097CC8552AE0002001E0287B8F -:10DB1000401C2873687B297B8842CBD1DB4D287D54 -:10DB200000284CD0287CC15D012928D0C05D022886 -:10DB300030D03AE0287B142148438019807A0128AC -:10DB400003D0D3A1D5480EF0D2F9297B00201422AE -:10DB5000514389198872297B51438919097CC85519 -:10DB6000287B142148438219287B48438019017C73 -:10DB70000098FEF7F5FF287B1628C8D1C5E7A97ADB -:10DB8000012904D00221C155002028750DE0002193 -:10DB9000C1550AE0A87A012803D0BDA1C0480EF003 -:10DBA000A6F90020A872297CC855287D002806D037 -:10DBB000297CB64A0098FEF7D3FF0020287502980A -:10DBC0000C281ED014214843AC494018017C01297F -:10DBD00017D10721B34D0174287E16283CD0287E2A -:10DBE000E97D401C884203D1A9A1AF480EF07FF91E -:10DBF000297E02986854287E162831D0287E401C41 -:10DC00002876607A0C287DD0A07A00287BD000206E -:10DC1000A072617A142041439848A44B0A185668B0 -:10DC200091681D46D2687C35DE67AA606960A04DA8 -:10DC3000697E002916D00226617A14228F4851434A -:10DC40000818407B06281BD203007B441B79DB1895 -:10DC50009F440A1412100E0CE87D0028C4D0C7E7B8 -:10DC60000020CDE70426E7E700200FE0B4200DE018 -:10DC700073200BE0322009E00A2007E0062005E0CF -:10DC8000FF2083A1E0300EF032F900202873697E76 -:10DC9000022901D0012910D12969009A09188A1A8C -:10DCA0001202120A422A08D9032068763239080281 -:10DCB000000A28613220287308E0322806D2207A30 -:10DCC00000280AD1F4F744FB012005E0207A00285F -:10DCD00003D0F4F766FB00202072764910224878C2 -:10DCE00020700978012901D0032906D10121217171 -:10DCF000297B884201D9421A1032A378002B00D028 -:10DD0000921C01E08DE09BE02179002901D1002BDC -:10DD10005DD09446684A00990092019A176852684B -:10DD20007F1A511A3F0209023F0A090ABC451BD853 -:10DD3000614A974218D8009A914215D8297B8842A7 -:10DD400023D92B69421A9A1A1202120A1018801942 -:10DD50000002000A2A616860002914D00320287795 -:10DD60000006000E3ED14CE000202071A070297BFF -:10DD7000002925D02869401880190002000A68602F -:10DD8000022028772EE00120E9E781420BD92A6999 -:10DD9000511889190902090A6960002801D0042074 -:10DDA000DDE70220DBE7002B03D139A143480EF069 -:10DDB0009EF8286980190002000A6860002004E0CB -:10DDC000296989190902090A6960287719E0287BFD -:10DDD00000280FD02969081880190002000A68601D -:10DDE0000220287728690123811900221846F4F7B8 -:10DDF00091FD09E0286980190002000A686000208E -:10DE000028770120F4F750FD607A142148431B491C -:10DE10000C2240188256012300206968F4F77AFD2D -:10DE20000EE00120F4F740FD0020F4F73DFDF4F78B -:10DE300021FD207A002803D0F4F7B3FA00202072E5 -:10DE4000A078002804D0F4F710FE0020E070A07045 -:10DE50006078002804D01748C1784170817801703B -:10DE60002079002806D000201249E07009780029A6 -:10DE700000D120710B48017EC07D21E054190020A3 -:10DE8000101900202F1A0020501700202019002000 -:10DE90007372635C72656D2E630000000B060000F8 -:10DEA000270600003819002039060000D01900208C -:10DEB0003C1A002076000020FFFF3F008B06000088 -:10DEC000814203D0C8484078F4F7E2F90120E071BC -:10DED00003B0F0BDF0B5C54C0746607A83B00C289E -:10DEE00003D1C3A1C5480EF002F8607A1421C44ED4 -:10DEF00048438019007C032803D0BDA1C1480DF020 -:10DF0000F6FFC14DA868401C04D06F20B8A10001E5 -:10DF10000DF0EDFF607A1421484381190C2008565A -:10DF200000216A4600911171C01901AA6946F4F7EF -:10DF3000B7FD6A46042010560F2801DD012000E0DD -:10DF4000002000994018696840180102090AA96078 -:10DF50006079002804D0012300221846F4F7DAFC87 -:10DF600003B0F0BD70B5AA4CA84A0B1AA34214D353 -:10DF7000451AA54211D3934203D9101A43185B1CCA -:10DF80000BE0954204D9511A0818401C434204E0A2 -:10DF900097A1A0480DF0ABFF0023184670BD10B547 -:10DFA0000146012300220220F4F7B4FC10BD10B595 -:10DFB0000220F4F779FC10BD10B5F4F700FD10BD98 -:10DFC000F0B58A4D0446E87A83B0002803D188A1D1 -:10DFD00091480DF08CFF642C4DD3904A00210846E7 -:10DFE000121B884147D38E48417B007B814242D13E -:10DFF0008C48007D00283ED1687A1421804F484328 -:10E00000814EC519306801AA00196946F4F748FD28 -:10E01000694604200856002802DD0098401C009044 -:10E02000A96800986B680A18D21A12027E4B120A6D -:10E030009A4220D8AA7C0C2A08D014235A43D21919 -:10E040005268511A0902090A814214D3B068401C6F -:10E0500005D00120F4F728FC0020C043B0603068F0 -:10E0600000193060A868009940180002000A706129 -:10E07000012003B0F0BD002003B0F0BDF8B50646A6 -:10E08000401EC4B214205E4960434518287C002815 -:10E0900003D157A165480DF02AFF6148017B407B01 -:10E0A00081420CD0624A14234B439B181B7CB34221 -:10E0B0000CD016290CD0491CC9B28142F3D1594861 -:10E0C000017D002961D0007CB0425ED10020F8BD06 -:10E0D0000021F1E7052903D0062901D0072928D11D -:10E0E00001212974C17D0023027E8A4221D002468B -:10E0F000565CA64201D1012301E0002B04D0162971 -:10E1000011D04E1C965D565416290ED0491C167E11 -:10E11000C9B28E42ECD1002B0BD0117E002906D063 -:10E12000117E491E04E00026ECE70021EFE71621EE -:10E130001176697C00292AD06F74C17D0023027E8C -:10E140008A4224D0425CA24201D1012301E0002B8B -:10E1500004D0162912D04A1C825C425416290FD0D2 -:10E16000491C027EC9B28A42ECD1002B0FD0027E3C -:10E170000146002A06D00A7E521E04E00022EBE788 -:10E180000021EEE716220A7601E02A480027297CC2 -:10E1900001299FD16A7C002A9CD10120F8BD70B56D -:10E1A00005461420164A052168438018214C017445 -:10E1B000207E162811D0207EE17D401C884203D1AC -:10E1C0000BA11D480DF093FE207E2554207E1628BD -:10E1D00007D0207E401C207670BDE07D0028EFD067 -:10E1E000F2E70020F7E70000740000205C1A00202E -:10E1F0007372635C72656D2E63000000EE060000B2 -:10E2000054190020EF0600003C1A0020FF7F841EF6 -:10E210000020A1071207000031070000FF1FA1071F -:10E220001019002020190020FFFF3F006E0700009A -:10E2300050170020381900200702000010B502789E -:10E24000254B002A1A7002D002F015FB10BD05F014 -:10E250005FFD10BD10B520490978002902D002F0F9 -:10E2600067FB10BD05F0DEFD10BD10B51A49097839 -:10E27000002902D002F0D6FB10BD05F02FFE10BD24 -:10E2800010B515490978002902D003F0C2FB10BD72 -:10E2900006F098FC10BD10B50F490978002902D08E -:10E2A00002F092FD10BD05F0BEFF10BD10B50A4989 -:10E2B0000978002902D004F058FC10BD05F0BBFB22 -:10E2C00010BD10B5044A1278002A02D004F04EFCAA -:10E2D00010BD05F0BFFB10BD7A00002070B5FC4DED -:10E2E00000246C702C70AC616C72AC720120E8720E -:10E2F000F8484470C473AC62F7482C6302F041F9EB -:10E30000002804D0FF20F5A14E300DF0F0FD2C7751 -:10E3100070BDF8B5F54902250D60F5490026CE63BC -:10E320000127CF63F349C96A09070DD4F24AD36ABA -:10E33000F2494B62136B8B62536BCB62936B0B6333 -:10E34000D26BCB051A434A63ED4C002823D0012839 -:10E3500025D0FF20E1A1A1300DF0C9FDE948A0635F -:10E36000FF2004306063276303202061E649962084 -:10E370004860D7491C2008560B22D243811A90428C -:10E3800037D011DC1C313AD00A2938D0142934D0C6 -:10E39000182911D12FE0DD486061DD4802E0DD4839 -:10E3A0006061DD48A061D9E708301FD004281BD088 -:10E3B000082817D00C2812D0FF20D8A175300DF0F6 -:10E3C00096FDDB49D9488860DB48DA494160DB4982 -:10E3D0000160DB480560DB4910204860F8BD04207F -:10E3E000E060EEE7E660ECE7FC2000E0F820E060AB -:10E3F000E7E7F420FBE7F020F9E7EC20F7E7D82087 -:10E40000F5E710B50C460146CF480DF072FEB04856 -:10E41000047210BDAF4840787047AD4A517010701B -:10E420007047F8B504460D4650791179000208434B -:10E43000690009190884501C01460E7801273046EE -:10E440004E78360230438E78C97836043043090658 -:10E450000843117800020843A9006050284608309C -:10E460003E468640002B0CD0012B04D0FF209BA100 -:10E47000E8300DF03CFD206B3043AF403843206363 -:10E48000F8BD206BB043F8E770B50D460446082987 -:10E4900004D9FF2091A1F9300DF029FD0022002DB3 -:10E4A0000CD9AA489100635809180B6053001B1936 -:10E4B0001B8C0B62521CD2B2AA42F3D3206BA4492C -:10E4C000086070BD10B504460B22D2430C308C4955 -:10E4D000944223D008DC1C3026D00A2824D01428EB -:10E4E00020D0182809D11BE02046083014D0042879 -:10E4F00010D008280BD00C2807D0FF2087A175303A -:10E500000DF0F5FC7248047710BD042000E00020F7 -:10E51000C860F7E7FC20FBE7F820F9E7F420F7E70D -:10E52000F020F5E7EC20F3E7D820F1E76948007B1D -:10E5300070477349C2784A62024613781846537886 -:10E540001B0218439378D2781B0418431206104319 -:10E550000002C8617047252808D0262808D027283F -:10E5600008D041000A2807D8091D06E0022105E06D -:10E570001A2103E0502101E0891DC9B2604A91606F -:10E5800061494861704752498861704770B50028F9 -:10E5900017D002224E4C6F4BA27203201860644DBC -:10E5A0006248686000200126207500290BD00129EF -:10E5B00010D002291ED0952048A180000DF097FCB4 -:10E5C00070BD0122E6E76448012A01D0466070BDB3 -:10E5D000066070BD3E48012A006B05D00121490547 -:10E5E00008432063696070BD012109050843206369 -:10E5F000696070BDA069002803D138A157480DF0AB -:10E6000076FCA169A06A4018554988604A48554976 -:10E6100081605549C1600120216BC0030143216322 -:10E6200068602C48C67370BDF8B54A4801688F0809 -:10E630004449BF004A68D206D60F10228A600024DF -:10E6400004603B48394981600C2069460870474D99 -:10E650002C614149012008610BE000BF00BF00BFF1 -:10E6600000BF00BF00BF00BF00BF69460878401E62 -:10E67000087068460078002802D028690028ECD08D -:10E6800068460078002803D124A139480DF02FFCFA -:10E690002C610F48012144728472C1722D480760B9 -:10E6A000002E02D0274910204860F8BD01460A78A4 -:10E6B00010464A78120210438A78C978120410432F -:10E6C0000906084300020E49000AC86370470000AB -:10E6D0006C1A00208C1A0020A01A00207372635C50 -:10E6E00068616C5F7263732E6300000080E100E07C -:10E6F000C01F004080000010C00000100017004044 -:10E70000001500405B0600004015004006010200B5 -:10E7100025000302050103001F0003027372635CFE -:10E7200068616C5F7263732E630000000040000438 -:10E7300000F501404080004080F50140101100408C -:10E7400080E200E0001300406E1A00200016004036 -:10E750004016004000120040001000404702000038 -:10E7600040850040488100401010004000110040EA -:10E7700067020000F94902200860F9490860704703 -:10E78000F849022008607047F7490870704710B5D3 -:10E79000F64801F0FEFE002803D0F549F5480DF0DB -:10E7A000A6FB10BD10B5F14801F00BFF10BDF249FA -:10E7B0004860704770B5F14C0546A06AA84203D383 -:10E7C000EB49EF480DF093FB01202073ED49002049 -:10E7D00025614860EC4845600120216B80050143BC -:10E7E0002163EA49486070BDE44802210173C621F3 -:10E7F0000161E44A00215160816AE34AC6315160F7 -:10E800000121026B89050A430263E04841607047B9 -:10E810000121DE4889058160D848026B8A430021C6 -:10E82000026301737047DA4801214160C160D54934 -:10E8300000204860D4494860D04988627047D54973 -:10E8400040200862D4490A6802430A607047D248EF -:10E850000168402291430160CE4900200862704760 -:10E86000CD480168102291430160CC4901208861A4 -:10E870007047CB490020C861C74801681022114386 -:10E8800001607047C649CA69012A01D0002070475B -:10E89000C04A92685206520E524202700020C8616D -:10E8A0000120704770B50C00054603D1B049BD4842 -:10E8B0000DF01DFBE00706D0012C04D06D20AC4903 -:10E8C000C0000DF014FB002D0DD00221AB48012932 -:10E8D0004172C472B04808D002290BD0A449B24892 -:10E8E0000DF005FB70BD0121F0E701680422114322 -:10E8F000016070BD016808221143016070BDF8B568 -:10E900009E4C0025E27A910701D5410713D4D30626 -:10E91000A649002B05DA4B7B002B02D08B7B002B0A -:10E9200009D0130702D50B78002B04D1520703D569 -:10E930004978002900D10125677A002201239649F0 -:10E94000002F1BD002263040284347D008460168DC -:10E950008E089749B6004D68ED06ED0F10278F60C1 -:10E9600000210160894A934890600C206A4610702B -:10E970008B4F396189490120086114E0834D8D482E -:10E98000A8600868800880000860A272E372F8BD81 -:10E9900000BF00BF00BF00BF00BF00BF00BF00BF7F -:10E9A0001078401E10701078002802D038690028B6 -:10E9B000EED01078002803D17F4980480DF097FAF7 -:10E9C000002038616072A0720120E0727248066017 -:10E9D000002DDCD0764810214160F8BD012F06D013 -:10E9E000022F0CD0624976480DF081FAF8BD086814 -:10E9F0000425A84308606272E372A372F8BD086838 -:10EA00000825A84308606272E372A672F8BD5B49EC -:10EA100008757047F8B5654E5848F37B604C002583 -:10EA2000016B002B55D0594AE3139360994301635E -:10EA3000594807685E4B102199600021016000145D -:10EA400090600C206A4610702161544801250561D0 -:10EA50000AE000BF00BF00BF00BF00BF00BF00BF93 -:10EA600000BF1078401E10701078002802D0206976 -:10EA70000028EED01078002803D14F494F480DF000 -:10EA800036FA0020E060206160606061A061424869 -:10EA900007603E4900144860454910204860374CE3 -:10EAA000A07A01280FD0022810D0434945480DF024 -:10EAB0001EFA0020F073207D022803D1424801682D -:10EAC0008907FCD5F8BD35480560F2E73348456055 -:10EAD000EFE72E4A91600563017B002903D02949A5 -:10EAE0004968012908D000222169012906D00023A4 -:10EAF000817A012904D006E00122F5E74023F7E7F7 -:10EB0000E768012F04D000271F43012902D004E049 -:10EB10002027F9E76368012B05D000233B432B4FE7 -:10EB2000022902D007E01023F8E73868012802D153 -:10EB3000E068012804D000201843022902D007E031 -:10EB40000820F9E73B68002B02D1E368012B3FD096 -:10EB50000023034302293DD040E0000080E100E0B3 -:10EB600080E200E000E100E07B000020A01A00202D -:10EB7000DCE60000A1020000001500406C1A002035 -:10EB8000B2020000408100404085004000F5014095 -:10EB9000008000404015004000120040001000407E -:10EBA00000110040630300007D0300008C1A002068 -:10EBB00000130040004000041CE700006702000052 -:10EBC000CE0300005D03000000E200E000140040FE -:10EBD0000423BEE7002A01D0022200E000221A43EB -:10EBE000022908D16068012805D1824840680128BF -:10EBF00001D0012700E000277F481743016809067C -:10EC0000090E02D06169012900D00021317300682A -:10EC10000006000E02D0A069012800D00020707309 -:10EC20007648006A002803D000F0B9F9012800D026 -:10EC30000020B073E560256165606561A5616D4880 -:10EC400045606F4C6F4825754168616200680B46EE -:10EC5000A062A17A022909D16178002906D06A4A06 -:10EC6000526812780A40217891430AD03570F9072A -:10EC70000AD01846FFF71AFB0121A06AFFF721FB13 -:10EC80000BE001213170F2E7B90601D5022102E063 -:10EC9000B90702D50021FFF714FB5B484168062243 -:10ECA000A01C09310CF06CFF002808D15648217ACD -:10ECB00040680078C009814201D1012000E00020B5 -:10ECC00070703846FFF71BFE5048007800280DD0C2 -:10ECD00001281ED002282FD003284AD04C494D4885 -:10ECE0000DF005F9A07A022856D074E0B80701D5D6 -:10ECF0000BF0D9F8380702D501200BF010F978078E -:10ED000002D500200BF00BF9B806EBD50BF06DF82F -:10ED1000E8E7B80701D50CF09DFB380702D50120C4 -:10ED20000CF03FFA780702D500200CF03AFAB8064A -:10ED3000D8D50CF0B5F9D5E7B807BF26002802DA18 -:10ED4000374009F03BF9380703D53740012008F078 -:10ED50006EFD780703D53740002008F068FDB8063F -:10ED600002D5374009F06EF87806BBD508F05BFD98 -:10ED7000B8E7B80701D509F0D7FF380702D5012059 -:10ED800009F0B6FE780702D5002009F0B1FEB806FA -:10ED9000A8D509F03EFEA5E7217B00291BD0154828 -:10EDA0004560022920D0012903D019491A480DF0E5 -:10EDB0009EF8A16A2069884203D8154917480DF0CA -:10EDC00096F81048216941600120216B80050143BC -:10EDD000216313494860207D012800D072E6114864 -:10EDE00001688907FCD5F8BD2169A06A411805486A -:10EDF0004160E9E740810040401600404015004076 -:10EE00006C1A002040850040001500407B00002067 -:10EE1000DCE60000E6040000FB040000FC04000047 -:10EE200000F5014000E200E02E4800210170417031 -:10EE3000704770B5064614460D460120F2F7C2FA37 -:10EE400028490120284B08709E60DC601D6170BD60 -:10EE5000F8B504460120F2F7B5FA224901200870FE -:10EE600021494C60214900264E600321204D0906AE -:10EE7000A960204F002C0AD0012C03D01EA14120F4 -:10EE80000DF035F83E60032000066860F8BD38607C -:10EE900001200006F9E710B51248017800290ED0CC -:10EEA0000321134A0906916010494A680021002A8B -:10EEB00003D0154A1268427000E0417001700020D2 -:10EEC000F2F780FA10BD07480178002907D00748FB -:10EED0004068002802D00C480068C0B270474078F3 -:10EEE000704700007C00002000F5004000F1004069 -:10EEF00000F5014000F200407372635C68616C5F72 -:10EF000063636D2E6300000000F400403B48002165 -:10EF10000170417010218170704770B5064614462B -:10EF20000D460220F2F74EFA01203449344A0870A7 -:10EF3000E41E14619660556070BD10B50220F2F7B2 -:10EF400041FA2E49012008702E48002101604160DD -:10EF5000816001202C49C005486010BD10B52748CC -:10EF60000178002917D00121274AC9059160254958 -:10EF70000B680022002B05D04B68002B02D089685B -:10EF8000002902D04270102103E0012141701F4985 -:10EF90000968817002700020F2F714FA10BD17485A -:10EFA0000178002912D01748016800290AD00168A9 -:10EFB000002905D04168002902D08068002803D0CC -:10EFC000002070470220704701207047407870474A -:10EFD0000A48017800290FD00A480168002905D0A5 -:10EFE0004168002902D08068002801D010207047B5 -:10EFF00006480068C0B27047807870477E000020E5 -:10F0000000F5004000F1004000F5014000F4004030 -:10F01000FFB593B0044600201D9E049015981C9DDA -:10F020001027082806D0E06901F014F8002809D05C -:10F030003770CCE028880921384328801F980227A0 -:10F04000017016E0E169012088710521E269C902B9 -:10F050009180E1698872E169F9480881E1690020DD -:10F060008873288820210843288011211F980427AD -:10F0700001701F980225801C0390307810900A20A0 -:10F080003070204618301190F7F789FA00206FE0B1 -:10F090001598102809D1022D07D06846828A049954 -:10F0A0000398401A8270110AC1706846C08A169986 -:10F0B000884203D9E349097A149106E0884204D1D1 -:10F0C0001099002901D0317021E003990870000ADD -:10F0D00048701E980088401BC01B83B2FF20C01BD5 -:10F0E000984200D203460398149AC0190CA90092C2 -:10F0F000019002912020015D6846C08A0022F7F746 -:10F10000C3FA3070002806D0C0B2832862D06846A7 -:10F11000C08A208345E00F98002805D0C9480068C0 -:10F1200000790A2830D33CE06846008EC119C9B284 -:10F130000491022D0FD01F99049A4978914203D16E -:10F140006A46128C824209D0BE4804910068017858 -:10F15000032909D027E008461F994870B94800687C -:10F160000178042906D008E000790A281BD2012082 -:10F170000F9009E06946C98A8180039904980818AC -:10F1800003900498281885B205AA14991198F7F7E6 -:10F1900009FA002805D11E980088401BB84200DB00 -:10F1A00076E7022D0ED01598102807D1049A0399FE -:10F1B0006846808A891A8870000AC8701E9805807F -:10F1C000002030709F4800680078032802D000209B -:10F1D00017B0F0BD0220FBE7F8B50446406B0026EF -:10F1E000134600282BD0491F8DB2618F2A46083262 -:10F1F000278F8A18BA4221D89A7840185F7811026E -:10F2000039430170090A41701A79DF7811023943D4 -:10F210008170090AC1700571290A41712A46591D78 -:10F22000801D0CF0DAFC608FAD1D401980B2608744 -:10F23000626B002110180170417000E00926304611 -:10F24000F8BD30B50B88048F9C4212D9446BE0188E -:10F250004478057824022C430BD0447905792402A4 -:10F260002C436404640CA41D1B190B801060002047 -:10F2700030BD822030BDF7B588B0002568460582D4 -:10F2800005275DE00398417802780E021643417924 -:10F29000027908021043000452D40A980123068020 -:10F2A00005A802905B02002200970195304609995B -:10F2B000F7F7EAF904004AD16846018A0183039806 -:10F2C0004179027909021143437802781C02144300 -:10F2D000B4421ED10A041CD44B0401215B0C8903E7 -:10F2E00000950B4301970295C17880780A0202438A -:10F2F00020460999F6F7E4FF040011D103994879F3 -:10F300000A79000210430122D20310430871000A57 -:10F31000487103AA06A90898FFF793FF0400CED00E -:10F3200003990095019702954878097800020843EF -:10F3300069468B8A00220999F6F7C2FF822C06D112 -:10F3400003AA04A90898FFF77CFF04009AD0684636 -:10F35000058209E0039841790279090211434904C1 -:10F36000490C0171090A417103AA04A90898FFF721 -:10F3700068FF0028EED0822C02D020460BB0F0BDF2 -:10F380000020FBE730B50446406B002597B000280D -:10F390000DD00B2268460270228F0281606B0391B0 -:10F3A000019000216846F4F736F9684605706563F8 -:10F3B0006587258717B030BDF8B50F460546696BE0 -:10F3C0000020069E144600290FD0012B0DD1324695 -:10F3D00039462846FFF74FFF002806D1002C04D0FD -:10F3E00032463946284600F044FEF8BD002202802D -:10F3F000C262831D0263C361426342870287203079 -:10F400000170704710B50022D24302800420FDF73E -:10F4100014F910BD10B596B00446FFF7B3FF208E67 -:10F42000002808D0012069460870E06A0190002198 -:10F430006846F4F7F0F80020E062206316B010BDD3 -:10F4400001280000A41A00200146098800200A07AC -:10F4500000D501200A06120F01D002221043CA056E -:10F4600001D5042210438A0501D510221043490515 -:10F4700001D5202108437047FFB5A9B00600329D91 -:10F48000359C2B981F46229016D0007841060FD449 -:10F490008106890E1E2909D021884A05520E0BD1FA -:10F4A0003A88172A08D3FE4A914205D0C10906D0EE -:10F4B0008006800E122802D003202DB0F0BD204619 -:10F4C0002C302690F7492A980872002018AA039039 -:10F4D00010726A46107404AA0A60339A4A6020AA1D -:10F4E000908090812298007801908106681C1C9081 -:10F4F000701F1D902B98890EC21C24922246203228 -:10F500001B92083A401C02920B000CF01EFE1FFDDD -:10F51000FD11FD1FFD8EFDFCFDFBFDFAFDF9FDFC5F -:10F52000FDF8FDFDFDF7FDF6FDFDFDFDFDF5FD0022 -:10F53000032E76D102E018A9087219E3032028707F -:10F540001C9917220A7000224A70CFE2052EF0D1D2 -:10F550004178027808021043208320A98880249AE9 -:10F560005178127809021143618300287ED08842C5 -:10F570007CD800202072E080401E60840298F7F75B -:10F580000EF805202870A81C0190022000901BAAEC -:10F590002A990298F7F706F8002868D118A8807C05 -:10F5A000012803D002206870102002E0012068705A -:10F5B00002202490002225A91CA8F3F784FB002830 -:10F5C0002BD120A8007D2499814226D13A88009928 -:10F5D000801C511A814220DB10A8C18D0198017056 -:10F5E000090A417001991CA8891C01910099019A8E -:10F5F000891C009125A9F3F766FB20A8007D0199DD -:10F600001BAA091801910099081880B200902A9944 -:10F610000298F6F7C7FF0028CCD00098022826D021 -:10F6200064E272E018A9087261E2072E6DD3417896 -:10F630000346027808021043208320A98880249A78 -:10F640005178127809021143618300280ED0884254 -:10F650000CD8012020725879197900020843E08003 -:10F6600000202073E06900F0F5FC01E098E0A9E0DB -:10F6700000280ED1E169012088710521E269C902E3 -:10F680009180E1698872E16987480881E169002019 -:10F690008873F01F60842298C01D60620298F6F79C -:10F6A0007EFF07202870681C009001200190002038 -:10F6B00010A9C8852FE00198012814D0E06980794D -:10F6C000012830D000981E38417F007F0902014395 -:10F6D00000980170090A41700098801C0090019800 -:10F6E000801C80B2019010A8C18D00980170090A99 -:10F6F00041700098801C09E00AE296E13BE1DFE0FE -:10F7000004E29BE077E036E016E2AFE0009001987B -:10F71000801C80B201901BAA2A990298F6F742FF3A -:10F72000002803D007E010A8818DD1E7398801981F -:10F73000081A0428BFDA0198012843D0E0698079CB -:10F74000012804D010A8818D5548814206D110A807 -:10F75000818D00980170090A417009E000981E38F7 -:10F76000417F027F0802009910430870000A487028 -:10F770000198801CBAE1072E01D0152E76D1417870 -:10F78000027808021043208320A98880249A5178A7 -:10F790001278090211436183002801D0884201D9FF -:10F7A00001203FE7012020720020E0802073052E19 -:10F7B0000AD01D982299E269C0B2491DF3F75DFA9B -:10F7C000002801D00A202DE70020C04360841AA839 -:10F7D000019023A9229802970395009100780023B5 -:10F7E0008206920E20462A99FFF712FC0390208B86 -:10F7F00020A988807BE1032EC0D1402220A98A81E4 -:10F800004178027808021043208320A988802A9931 -:10F810001EAB1C9A02930192009139880022491E66 -:10F820008BB21B990978F6F72FFF18A908720028E8 -:10F8300033D10B20287010A8008F3FE0052E9DD1FA -:10F84000802220A98A81417802780802104320830F -:10F85000249984464A78097812020A43628420A9CE -:10F8600088801248824202D30720DBE6AFE03F20C7 -:10F870008002024362842A981FAB1C990293019173 -:10F8800000903888401E83B21B9801786046F6F7D6 -:10F89000FBFE18A9087200280CD08328AAD107E023 -:10F8A000FFFF0000A41A0020012800000102000050 -:10F8B0000220B8E00D20287010A8808F401C15E1B0 -:10F8C00001990C22C9095143C91CB14204D90198BC -:10F8D00040067CD5002009E14278037810021843E5 -:10F8E00020AA9080844622980078400609D50520F9 -:10F8F0006A46107422980078C00905D00020107460 -:10F900001DE106206A46107424981F902A9A0090E0 -:10F910000023701A029383B21E9001921B9800225A -:10F9200001786046F6F7CCFC18A9087200226946F7 -:10F930000A74832801D1022003902298007840069F -:10F940000DD52088C00506D520A9208B898888423E -:10F9500001D100206062002018A90872C6E0FF21D2 -:10F96000013120A88181808820831E9860841F989F -:10F9700060621320B8E0052E29D34178027808028E -:10F98000104320A98880218F002902D0FE4A91428D -:10F9900006D10A216A4611740121C943218702E078 -:10F9A00007216A46117422992A9A491D01920091F1 -:10F9B00001221D990023D203029311438BB2249993 -:10F9C0004A78097812020A431B99097800E0C9E0D5 -:10F9D000F6F776FC18A90872002269460A7401221B -:10F9E000520220A98A81832808D0002809D0218FBB -:10F9F000E54881427ED10020208778E088882083F6 -:10FA00004DE7606B002808D031462046229AFFF768 -:10FA1000E3FB18A90872002869D12B463A46304604 -:10FA2000229900F056FB039061E02298022E407864 -:10FA300001907DD1002801D0012879D108206946A4 -:10FA400008740198087521A800901B98002201787D -:10FA50002046019BFFF7B0FC6946002248758A7575 -:10FA6000002802D10198012809D0208F002806D053 -:10FA7000002008740120800220A988810EE004A8DB -:10FA80003399F3F7C8FD03900020694608740120FC -:10FA9000800220A988810398022807D0BB4800680B -:10FAA0008079002805D018A908722BE001982083DE -:10FAB0001DE00398002803D0812018A9087240E0B7 -:10FAC00021A800901B98012201782046019BFFF796 -:10FAD00073FC18A9087220463499FFF753FC18A943 -:10FAE000087A002803D11920287001203880684640 -:10FAF000007C00E03CE0002804D004A83399F3F730 -:10FB00008AFD0390039800282ED01AE0062012E503 -:10FB10002078000713D5012E11D109216846017400 -:10FB2000A188818204203499FCF787FD082100E038 -:10FB300005E020A88181CDE60198400612D503207A -:10FB4000039020A9208889890843208020A98889DA -:10FB50004005400E04D026992B9808602698868090 -:10FB60000398AAE40420E6E418A8007A00280ED03E -:10FB70000120287022980078687020A88088A870DA -:10FB8000000AE87018A8007A28710520388020A99A -:10FB90002088898988432080E2E7FFB50746A1B025 -:10FBA00000201C903A7801209040794A7C681040EF -:10FBB00010AA1087744B22885B1C9A4203D000283D -:10FBC00004D0100702D5012025B0F0BD249E0020EE -:10FBD000307023980025028810A8028518A80575A2 -:10FBE0006A4B68461972057404A8186020462C30C8 -:10FBF0001B902A985860249E94463878721C0521E0 -:10FC0000039201282DD0022808D003287DD1307816 -:10FC1000800980011D303070B889A08038780228B2 -:10FC200004D13078800980011B303070F01C1FAA8D -:10FC300001900292009110A8008D0022C01E83B294 -:10FC40002020015DB889F6F71FFD0028DED103985A -:10FC5000B9890170090A417010A9888FC01C0885F4 -:10FC600028E1787B18AA10753A7B012A02D0022A73 -:10FC7000CCD1FCE022887F231B011A4010AB1A87ED -:10FC8000802A4AD006DC102A10D0202A0ED0402A22 -:10FC90000AD124E0FF3A013A65D0FF3A013A79D01F -:10FCA000FF3AFF3A022A76D00525A2E02078C00666 -:10FCB00001D5082000E010201C9004206A46107432 -:10FCC000002090821AA81DAA1EAB039601920290F2 -:10FCD00000933B8A20461C9AFFF79AF984E0228B16 -:10FCE0003B8A9646934268D10A221C92002839D159 -:10FCF000039801906046401E1FAA83B20292202002 -:10FD00000091015D0022704600E0BAE0F6F7BCFC0D -:10FD1000014618A801750B201AE0228B3B8A9646F3 -:10FD200093424AD10C221C92002862D10398019080 -:10FD300060461FAA401E0292009183B22020015DFE -:10FD4000628C7046F6F7A0FC014618A801750D20DC -:10FD5000307010A8818F491C018504216846017408 -:10FD6000218B818245E0238B3A8A9C469A4224D19A -:10FD700012221C9200283CD1606A002813D0002275 -:10FD80006B4607C3638C07E0FEFF0000A41A002047 -:10FD900009F800000DE04BE02020015D6046F6F719 -:10FDA0008FFA18A9087513203070012010A9088552 -:10FDB0001FE0398A228B914201D00425B6E016213A -:10FDC0001C91002815D11B98818802682046FFF7F6 -:10FDD00003FA18A9087500280BD11B98334601684F -:10FDE00080881AAA00F075F9054602281BD0042D58 -:10FDF00019D01B988088002811D06846007C002804 -:10FE000004D004A82A99F3F706FC054601206946A8 -:10FE100008741B981B990068059000208880002DAD -:10FE200048D0052D2ED06846007C032878D07DE090 -:10FE300018211C91002806D0388A20832046B968F2 -:10FE4000FFF7A0FAD5E72046183000902020015D8A -:10FE5000237E01222046FFF7AFFA18A90875002873 -:10FE6000ECD119203070012010A90885E6E7208820 -:10FE700001214902084010A90887FF38FF380228ED -:10FE800006D0052510A92088098F884320804DE0E1 -:10FE9000208F9849884290D116201C9038690028FC -:10FEA00005D06063B88A20870020608702E00020C8 -:10FEB000C043208710A8008F7F21090102468A4392 -:10FEC0000DD0782300220420B968FCF711FB3878A4 -:10FED000A07010A92088098F0843208002E02188A3 -:10FEE000814321806846007C002805D08248416813 -:10FEF00004A8F3F790FB054618A8007D002815D04C -:10FF00001C98707001203070208BB070000AF07067 -:10FF100018A8007D3071052110A8018506E0FFE7D3 -:10FF20007548416804A8F3F776FB05467248017AE4 -:10FF300020884005400E22D11B98808800281ED0C2 -:10FF4000239A0026138810AA1385249A2A9B6F46A9 -:10FF50004CC71B9A039412681AABFFF78DFA05463B -:10FF600002280CD00120694608741B982A99006861 -:10FF7000059004A8F3F74FFB05461B98868010A850 -:10FF8000018D2398018028461EE600B597B004280D -:10FF900007D102206A461070019100216846F3F7EC -:10FFA0003AFB17B000BD10B5534C0378002221680E -:10FFB000012B02D0022B42D126E00B78002B01D07E -:10FFC000042B03D10A7122680321117021688388F0 -:10FFD0000A79D200921D8B5221680A79D200083228 -:10FFE0008918C2880A80216803890A79D2000A32F6 -:10FFF0008B52428920680179C9000C314252216834 -:020000040001F9 -:100000000879401C08711EE00A7482888A80216881 -:10001000C288CA8022680189118122684189518180 -:10002000C1682068C1606168F3F7F5FA01460228EB -:1000300007D02068007C002802D1002903D081204D -:1000400010BD832010BD002010BD406B002800D0E3 -:10005000012070478178012909D100880521C90252 -:10006000884202D0491C884201D1002070470520F7 -:100070007047F7B586B00024684615460F46848160 -:1000800005261AE004984178027809021143298074 -:10009000811D019602940091417902790B0213436C -:1000A000C178827809020A4341780078090208433E -:1000B0003946F6F705F9002806D104AA03A90698DF -:1000C000FFF7BFF80028DDD0822800D1002009B05A -:1000D000F0BD10B51488844201D2052010BD17244C -:1000E0001C701080421E581C491C0BF076FD00202D -:1000F00010BD0000FEFF0000A41A002030B503462A -:10010000002002460DE09C5C2546303D0A2D02D3BE -:100110000020C04330BD0A25684330382018521CE7 -:10012000D2B28A42EFD330BD70B50D46144608E016 -:100130000A210BF0BBFD2A193031203A641ED17719 -:10014000E4B2002CF4D170BD10B5002310E0040A15 -:1001500000020443A0B2CC5C44402006000F604083 -:100160000407240C44402006C00C60405B1C9BB27A -:100170009342ECD310BD000010B572B600F0DFF86A -:1001800000280BD0F1F78CF8FCF70BFC05F0FFF919 -:100190006F490020C86288626E49086062B600201C -:1001A00010BDF3B5002501200007C06A81B0C0432F -:1001B0000006000E04D168480068401C00D10125EB -:1001C00072B600F0BCF8002802D062B60820FEBD6E -:1001D000F0F7BCFFF1F768F8604C614A0021236832 -:1001E000CB40DB071FD00346CB40DB0718D14BB217 -:1001F000002B07DA1E07360F083EB608B600B61801 -:10020000F66904E09E08574FB600F61936689B075A -:10021000DB0EDE4033069B0F012B04D0032B02D0F4 -:1002200062B65148FEBD491C2029D8D3019C01204B -:100230004E4923000BF089FF142224242424242473 -:1002400024240B0D1012142016181A1C1E2F002423 -:1002500000E00124C86314E00224FBE70324F9E76B -:100260000424F7E70824F5E70924F3E70A24F1E773 -:100270000B24EFE70C24EDE70524EBE7072400E06F -:100280000624D06901210002000AC9070843D06191 -:10029000002D04D009E062B601200003FEBD2C4D04 -:1002A0003348E862F1F700F8A8622A49314808604B -:1002B000314902980860F0F7F7FF214605F04EF942 -:1002C000FCF735FB05F056FB05F0CAF90198F0F78D -:1002D000B5FF040062B603D0FFF74EFF2046FEBD17 -:1002E0000020FEBD10B5044600F029F8002800D01B -:1002F00001202070002010BD2049086000207047B8 -:1003000010B50C46102808D011280BD012280CD09C -:1003100013280ED00120086010BD61682068FFF727 -:1003200040FF0AE0FFF728FF07E02068FFF7DAFF49 -:1003300003E01249206808600020206010BD0548D5 -:100340000C490068884201D10120704700207047A5 -:1003500000050040600000200010001000E100E0F7 -:1003600000ED00E000E400E001100000400000406B -:1003700000280000BEBAFECA84000020040000204D -:1003800010B520380C4603000BF0DFFE33A6AAAEF2 -:10039000B2B8BCC0C5E0DBE41B1F23272C31373CBF -:1003A00041474D5054585C606D71656974787C802C -:1003B00084888C9094989C9FA2CACFE9F0F3D3D7FD -:1003C000F800206800F0DDF8D6E0206800F0E1F8E1 -:1003D000D2E0206800F0F5F8CEE0207840B204F0DA -:1003E0002DFFC9E0207840B204F04BFFC4E0207834 -:1003F000616840B204F05EFFBEE0207840B204F0D5 -:100400006EFFB9E0207840B204F079FFB4E02078C4 -:10041000217940B204F084FFAEE02078616840B2F8 -:1004200004F0AEFFA8E004F0BAFFA5E0206804F0F5 -:10043000BEFFA1E0207804F0D3FF9DE02068FBF729 -:1004400062FE99E02068FBF762FE95E02179206862 -:10045000FBF764FE90E02068FBF704FD8CE0206869 -:10046000FBF705FD88E02078FBF705FD84E0FBF74E -:1004700013FD81E02078FBF715FD7DE02078FBF788 -:1004800027FD79E02068FBF740FD75E02068FBF769 -:1004900042FD71E02068FBF744FD6DE02068FBF74A -:1004A00045FD69E02068FBF747FD65E02068FBF744 -:1004B00049FD61E02068FBF74AFD5DE00846F0F782 -:1004C0005DFE59E0F1F757FF56E0F1F784FF53E086 -:1004D0002068F1F78CFF4FE0206800F0E1F84BE076 -:1004E000206800F0E9F847E0206800F0F0F843E009 -:1004F0002078A268616800F0F5F83DE0207800F00F -:1005000006F939E0207800F017F935E020786168C5 -:1005100000F027F930E02078616800F03AF92BE02C -:100520002179207805F06CF826E0206800F06BF85F -:1005300022E02068FCF728F91EE02068FCF70CF99F -:100540001AE0204607C805F056F915E0206805F0C6 -:10055000A9F911E06168206805F0D4F90CE0206881 -:1005600005F0C6FB08E009E003E0FFE705F0D8FB73 -:1005700002E0206805F010FC206010BD012008603A -:1005800010BD002101700846704701460020087028 -:100590007047EFF31081C907C90F72B60278012ABC -:1005A00001D0012200E0002201230370002900D1C4 -:1005B00062B6002A01D00020704701204003704736 -:1005C000E7E7EFF31081C907C90F72B60022027086 -:1005D000002900D162B600207047F2E710B5284824 -:1005E000FFF7CFFF002803D026A11D200BF07FFCD2 -:1005F0002348401CFFF7C5FF002803D021A121207C -:100600000BF075FC10BDF1B5224D6F6801261C483A -:10061000FFF7BFFF1A4C002803D10026601CFFF72C -:10062000D0FF1D4A1D490120506000BF00BF00BF20 -:1006300000BF00BF00230B604B60009B6B6010602D -:1006400000BF00BF00BF00BF00BF0868002802D184 -:1006500048680028F9D048680028E4D1002E04D06A -:100660006F60601CFFF795FF07E0601CFFF791FFCC -:100670000028D3D10248FFF7A4FF0020F8BDC2E74D -:10068000880000207372635C736F635F6563622E22 -:100690006300000000E5004000E0004000E1004091 -:1006A0005A495B4B0A685B499A42096801D189043F -:1006B000890C0160002070475449554B0A68554920 -:1006C0009A4201D18004800C4860002070474F4955 -:1006D0004F4B0A684F499A4201D18004800C8860D0 -:1006E0000020704730B5494B494D1C684A4BAC421D -:1006F00002D0102802D203E00E2801D3184630BDE4 -:10070000C3004448181801614261002030BD3F49D0 -:100710003F4B0A684049491C9A4202D0042802D241 -:1007200003E0022801D3084670473C4A0121C0007B -:1007300080180160002070473449354B0A683649FB -:10074000491C9A4202D0042802D203E0022801D3B5 -:1007500008467047314A0121C000801841600020DE -:10076000704770B5294A2C4B14682D4E284D8200D5 -:100770005B1C9219AC4203D0042803D2116006E03E -:10078000022801D3184670BD8804800C1060002038 -:1007900070BD70B51D4A204B1468214E1C4D82005F -:1007A0005B1C9219AC4203D0042803D2106806E007 -:1007B000022801D3184670BD10688004800C0860C0 -:1007C000002070BD10B5134A164890600E2000211D -:1007D000C3009B1819615961401C1028F8D30020F0 -:1007E0000F4A05E0022803D383009B18196005E037 -:1007F00083009B181C68A404A40C1C60401C0428E3 -:10080000F0D310BD0349074888607047600000209E -:10081000BEBAFECA00F501400820000000F0014009 -:1008200000F8014000C0FFFF10B5FFA1086882B0CA -:10083000496801910090FE490020887604228A834D -:100840001022CA83FB4AFC4B0A849A84FB4AFC4C64 -:1008500090762070907390748871907708725877B2 -:10086000F848694604460BF062FC2146F64808F059 -:10087000CCF802B010BD10B5F44C6060A17001203E -:1008800006F036FA05F030FBFFF7CEFFA07801F056 -:100890006CFF06F066FE606807F090FF0024EC48ED -:1008A00021460471EB4806F00BFEEB482146047725 -:1008B000EA4806F00EFE10BD70B582B00E461D4629 -:1008C000144601A905F047FB00282ED1019880307D -:1008D000807C06F05FFA002807D0684606F06AFAC6 -:1008E000002808D0002C0CD107E05120DCA1C0006A -:1008F0000BF0FDFA002002B070BDD9A1DD480BF06D -:10090000F6FA009805F092FD3146009805F093FD47 -:10091000E2B22946009805F04BFF06F074FA002871 -:1009200003D1CFA1D4480BF0E2FA012002B070BD90 -:1009300030B40179002904D0012909D030BC00204D -:1009400070470488831D4288204630BC0221B3E7EB -:100950000488831D4288204630BC0121ACE7FFB5E6 -:10096000B34C83B00E460746208C69460880154676 -:1009700002A905F0F0FA002807D0684605F0F9FA58 -:10098000002802D0002007B0F0BD6846008820840F -:10099000AF4805F0EEFA002802D00020C0432084C2 -:1009A00068460088388002A905F0D5FA002803D0EF -:1009B000ABA1B2480BF09BFA02988030807C06F025 -:1009C0000FFC002803D1A6A1AD480BF090FA01A8B6 -:1009D00006F016FC0028D6D0019805F063FD3070B3 -:1009E000022808D0012806D09DA1A6480BF07FFA66 -:1009F000002007B0F0BD0699019805F0F0FE2880B0 -:100A0000002804D1172096A140010BF070FA06F0DF -:100A100023FC002803D192A19B480BF068FA012027 -:100A200007B0F0BD10B584B00446831D02AA694624 -:100A300001A8FFF794FF002813D068468088208023 -:100A4000684600896080002060716846007801284F -:100A500009D0022807D0FF2081A131300BF047FADE -:100A6000012004B010BD2071FAE7F0B58BB005008D -:100A700004D1FF207AA1D4300BF039FA6F4C002753 -:100A8000A07E00280AD06F7010202870E07EA87029 -:100A9000207FE870A77601200BB0F0BD6848007891 -:100AA000002809D0664C2C22A11C28460BF095F892 -:100AB0000E20287027700BE0A07B00280BD00120AF -:100AC000E870E07BA870207C68700F202870A77306 -:100AD00001200BB0F0BD6D48099005F04AFA0146BF -:100AE000A81C534E019000297ED153480790808C5A -:100AF0000890079804A9808C0390684607750398AE -:100B000005F029FA002803D055A161480BF0EFF950 -:100B100004984921095C002942D08030017E0029D7 -:100B200070D1A17C00297DD1A17F00296DD1807C6D -:100B300006F056FB002803D149A156480BF0D7F91F -:100B400006F0B7FB002826D0049805A98030807CE9 -:100B500006F020FA002803D141A14F480BF0C7F955 -:100B60006846027D002A05D035480399C186028770 -:100B70000120A074377003987080049801464030BB -:100B8000807A30710120A0778031CA6A0398518839 -:100B9000814200D1177004984030407A002831D14A -:100BA000A07C002815D1049805A98030807C06F02F -:100BB000F1F9002803D12AA138480BF098F96846CA -:100BC000017D002905D01E48039AC28601870120B5 -:100BD000A07404984030417F002913D0817F890799 -:100BE00010D5317A002900E05FE00BD1B77203998C -:100BF000B181C17FB173018C3182418C718201213D -:100C000031724777A07C002852D1307A002863D116 -:100C1000A07F002860D1099805F0ABF9002844D1E5 -:100C200007983DE044E00000FFFFFFFF1F000000C9 -:100C3000C01E0020FFFF0000801F0020A01E00201B -:100C4000801E00209E1F00209D1F00208C00002081 -:100C5000E01E0020E81E0020001F00201D1F0020B5 -:100C60007372635C6C6C5F6374726C2E6D302E6398 -:100C70000000000093020000A2020000CA0200006F -:100C8000D1020000ED020000E6020000A41F0020D7 -:100C9000180900002A090000310900005609000067 -:100CA000818C0898814200D023E7A07C002813D0D3 -:100CB000F749487805280FD2401C48706F700D2006 -:100CC0002870012020750198A18A0180E18A418065 -:100CD000218B8180A774FBE6ED484770307A0028AD -:100CE00009D06F70012028700A22EA49A81C0AF076 -:100CF00074FF3772ECE6B07900280AD06F701320C9 -:100D000028701C21A81C0AF0C5FF0220A870B7712A -:100D1000DEE6284606F0E8FA0028DCD1284607F08F -:100D2000B5FC0028D7D1A07C002811D0D848417844 -:100D3000491C41706F700D202870012020750198AA -:100D4000A18A0180E18A4180218B8180A774BFE65E -:100D5000A07F002800D1BCE66F700A20287001989F -:100D60003188018071884180B1888180A77770883F -:100D700006A905F0F0F8002803D0C749C7480BF0D2 -:100D8000B6F8B07805F0E5FF002803D1C249C448A1 -:100D90000BF0ADF8069849210F548030006C0178B3 -:100DA000002907D040887188884203D1BA49BD48DC -:100DB0000BF09DF8069805F00FF900288BD0B64986 -:100DC000B9480BF094F883E64FE6F0B5B74C01272D -:100DD000207885B000280AD0B5480E21837E3B22BA -:100DE000002B02D1C1760277877605B0F0BD0020D6 -:100DF000A071B0486946008C888002A905F0ABF864 -:100E0000002804D001A805F0B4F8002858D168469D -:100E10008188254601801835684602A9008805F0BA -:100E20009AF8002803D09C49A3480BF060F8684664 -:100E3000008803A9C0B206F0C3F8002803D1964980 -:100E40009E480BF054F8029849210E5C8030807C5B -:100E500006F0C6F9002803D18F4999480BF047F8EE -:100E600006F027FA7840314601431FD06A461188C0 -:100E7000A279FD23520012191181A2794000515D1F -:100E80004908490031435155A27919400143515550 -:100E90006A46107B002802D00420014301E0FB20B9 -:100EA0000140A0794155A079401CA071684605F029 -:100EB00060F8002804D16846018880888142ABD15F -:100EC0000020207167713B20E070277005B0F0BDF5 -:100ED00038B5774C0546A17B0120002908D0A37EB8 -:100EE0000F222621002B02D1E2762177A07638BD91 -:100EF0001F21E17326212174A0732888694605F01B -:100F00002AF8002814D100990022087800280FD16F -:100F10004920405C00280BD18031087E002807D092 -:100F2000087E042804D0C86A0378002B06D101E0AB -:100F3000022004E0096C0978002902D03A20E0730D -:100F400038BD07210170009829888030C06A41802F -:100F5000E27338BDF0B5554C07462078012583B0C3 -:100F600000280AD052480E22837E2421002B02D171 -:100F7000C2760177857603B0F0BD65712420E070FC -:100F80002570384605F006FE002801D0002000E05C -:100F9000122020710028EED14A4E394675774A4812 -:100FA0000BF09CF800277777781E69460880684622 -:100FB00004F0DFFF002818D168460688684601A9BA -:100FC000008804F0C8FF002803D033493F480AF0E6 -:100FD0008EFF0198A0300575684604F0CAFF00280E -:100FE00003D1684600888642E8D1277103B0F0BD7E -:100FF000F8B52F4C0546A17B0120002908D0A37E1F -:101000000F212322002B02D1E1762277A076F8BDB2 -:101010001F21E17323212174A0736B882C4A991F2F -:101020003020914278D2A9888E1F964274D28B428A -:1010300072D8EA88FF23F4339A426DD82A89254E64 -:1010400013460A3BB34267D2C9088A4264D9698908 -:10105000AA89914260D800262888694604F07BFF5F -:101060000222002838D100990878002834D149207C -:10107000405C002830D18031087E00282CD0087ECA -:10108000042829D0C86A0378002B2BD126E0000061 -:101090008C000020CA1E0020600C01004F020000DE -:1010A000550200005F02000065020000801E002063 -:1010B000A01E0020C01E0020C1040000C6040000C5 -:1010C000CC040000801F00209E1F0020CD080000DF -:1010D0007B0C0000770C0000E273F8BD0B6C1B78F2 -:1010E000002B01D03A2017E005238371C86A0681DE -:1010F000CB6AA8885881CB6AE8889881CB6A28890E -:10110000D881C86A01894389994204D8817908291C -:1011100001D8994202D31220E073F8BD298841809A -:1011200000988030C06A0270E673F8BD38B5FE4C96 -:1011300001252078002809D0FC480E22837E222138 -:10114000002B02D1C2760177857638BD1F20207131 -:1011500065712220E070257001F01DFD052802D088 -:101160000C20207138BD00202071684601F0A1FBE1 -:101170000028F7D100988030807C05F0EAFD002837 -:1011800003D1EB49EB480AF0B2FE009804F024FFCB -:10119000002803D0E649E8480AF0A9FEE74885712F -:1011A000E7488078F1F774F838BDF0B50446E5A15A -:1011B000086887B04968DD4D06910590A87B012736 -:1011C000002809D0AA7E0F212120002A02D1E97629 -:1011D0002877AF7607B0F0BD1F20E8732120287470 -:1011E000AF732188D94E081F3022B0423AD26088AE -:1011F000031FB34236D2884234D8E189D44E881FC7 -:10120000B0422FD2208A831FB3422BD2814229D8E9 -:10121000618AFF23F433994224D8A18A361F0B46F2 -:101220000A3BB3421ED2C00881421BD9E18A208BFF -:10123000814217D8A01D12220028207905D000284D -:1012400006D0207901280DD107E000280AD0F8E760 -:101250006079002801D0012804D1207B002804D027 -:10126000012802D0EA7307B0F0BD01F094FC052814 -:101270000AD001F090FC042806D002A804F047FE32 -:10128000002805D00920A5E00C20E87307B0F0BDC8 -:1012900001220321029805F072FB029801460F30EB -:1012A00001904E880421FAF75DFF3146019805F060 -:1012B0004FFCA8A0029E00680490032104A81336E6 -:1012C000FAF7D9FE002004A90A5C3254401CC0B2CF -:1012D0000328F9D39A48002601780298C176218A1A -:1012E0008180618AC180A18A0181014620318E7589 -:1012F000CE756179002902D0012903D101E006777A -:1013000000E00777A11D1D300AF0F3FE029805A941 -:101310000A300AF00CFF0298A030077569460E717A -:10132000012101A8FAF7A7FE694608794107C2061C -:10133000490F920F80068918C00F08186946087176 -:10134000401D029B0928987601D208309876012228 -:101350000021184605F013FB0298923005F0DAFCE4 -:10136000002803D172497C480AF0C1FD207B002887 -:1013700006D0012808D06E4978480AF0B8FD3BE055 -:101380000021774A012006E06C48807E00280ED0BC -:101390000121744A084606F0EAF900282CD0029888 -:1013A0008030807C05F0D5FC002816D019E002982A -:1013B0008030807C05F0CDFC002803D15C496A4870 -:1013C0000AF095FD029804F007FE002846D058491F -:1013D000664841E0E87307B0F0BD554964480AF03B -:1013E00086FD029804F0F8FD002803D050496148BA -:1013F0000AF07DFD1F20EDE72079012801D00028AB -:1014000003D106F0D0F900280CD10320029906F090 -:10141000DAF9002806D162882188029801F0D5F90E -:10142000002807D002988030807C05F092FC0028CC -:1014300006D009E00298A0300672EE7307B0F0BD46 -:101440003B494D480AF053FD029804F0C5FD0028C1 -:1014500004D0C3203649C0000AF049FD0C20B9E78A -:1014600070B5314C01212278002A09D02F480E2274 -:10147000847E1E23002C02D1C2760377817670BD54 -:101480001F22227161711E22E270217002781221E6 -:10149000012A01D0002A04D14078002803D0012875 -:1014A00001D0217170BD00260C25012A08D001F061 -:1014B00072FB05280BD001F08FF8002809D006E058 -:1014C0001E48C18B808B01F0C0F9002801D0257126 -:1014D00070BD267170BDF8B5134D06462878012100 -:1014E000002809D011480E23847E1D22002C02D131 -:1014F000C37602778176F8BD1F20287169711D209F -:10150000E870297001F047FB0C2704286FD00528EC -:101510006DD0B0791224012801D0002849D130784B -:1015200000282CD0012829E0801E0020A01E0020C9 -:10153000600C0100460600004A060000C01E0020A4 -:101540008C000020FFFFFFFF1F000000FD3F000098 -:101550007B0C000011223300C9050000E3050000E8 -:1015600094000020D41E0020D6050000DA050000FB -:10157000EA050000EE0500001406000019D1F0791C -:10158000002801D0012814D17188F9480A1F30249D -:1015900082420ED2B288121F82420AD2F54800243B -:1015A0008183B188C183B179012904D000290CD08D -:1015B00017E02C71F8BD807E002835D00121EE4A5D -:1015C000084606F0D4F8044605E0EC4A0021012064 -:1015D00006F0CDF80446002C03D0E949E9480AF0AA -:1015E00086FCF079012803D0002806D009E01BE032 -:1015F000012006F0D8F8044603E0002006F0D3F8F6 -:101600000446002C01D01F2011E03078012802D0C0 -:10161000002803D00AE00021022001E0002101207F -:1016200006F0D1F8002801D02F71F8BD00202871F4 -:10163000F8BDF8B5D44C0546A17B0120002908D09F -:10164000A37E0F222C21002B02D1E2762177A076F7 -:10165000F8BD1F21E1732C212174A07328886946ED -:1016600004F079FC002815D1009A00261178104664 -:1016700000290FD14921895C00290BD18032117ECC -:10168000002907D0117E042904D0D16A0B78002BE1 -:1016900007D102E00220E073F8BD136C1B78002B29 -:1016A00001D03A2022E06030007900281DD06B88FC -:1016B0008B80AB88CB80EB880B812B894B81D16AE7 -:1016C00068898881D06A294610220C310E300AF0D0 -:1016D00084FA009803218030C06A0170009829883C -:1016E0008030C06A4180E673F8BD0C20E073F8BD1D -:1016F000F8B5A64C0546207800280AD0A2480E224C -:10170000837E3A21002B03D1C276017701218176B5 -:10171000F8BD01F040FA04281CD005281AD09C4AD4 -:10172000107F082819D200010319102001469D33AB -:101730006E18203E471A491EF67F0906DE55090E2F -:10174000F6D1107F401CC1B21177924805F0C1FE5E -:10175000002003E00C20207101E00720207101200F -:1017600060713A21E1702070F8BDF8B5864C0646EC -:10177000A07B0125002808D0A27E0F201021002A7E -:1017800002D1E0762177A576F8BD1F20E073102006 -:101790002074A5733088694604F0DDFB002815D15C -:1017A000009900220878002810D108464030437A7A -:1017B000002B0BD180310B7E002B07D00B7E042B2E -:1017C00004D0C96A0B78002B09D101E0022007E0A0 -:1017D000684B1B7A002B02D1437F002B02D03A20AA -:1017E000E073F8BD807F800706D10620087000985E -:1017F00031888030C06A4180E2730098403045777C -:10180000F8BDF0B5614C012721788DB000290AD0D0 -:101810005D480E22837E2A21002B02D1C2760177F9 -:1018200087760DB0F0BD10216B460A464518203D65 -:10183000561A491EED7F09069D55090EF6D1102155 -:1018400010300A4610334518203D561A491EED7FC8 -:1018500009069D55090EF6D16846FEF710FFA11D39 -:101860001020024608AB1D18203D161A401EED7FC1 -:1018700000068D55000EF6D120710E20A0702A2092 -:10188000E070677127700DB0F0BDF8B53E4C0646AC -:10189000A07B0125002808D0A27E0F212820002A45 -:1018A00002D1E1762077A576F8BDB07800271A2816 -:1018B0002DD011DC16283CD2010079440979491851 -:1018C0008F44373737373725373737373737373755 -:1018D00037373737372525252A282AD00DDC1E38FB -:1018E0000C2826D201007944097949188F44212116 -:1018F0002121212121212121210F3A38042818D228 -:1019000001007944097949188F4413011301308883 -:10191000214988420DD81F20E07328202074A57328 -:101920003088694604F017FB002804D00220E073D9 -:10193000F8BD122014E00098017800290FD1492148 -:10194000095C00290BD1014680310A7E002A06D0AD -:10195000097E042903D0A0300179002902D00C208F -:10196000E073F8BDE773B17841710571F8BD00000F -:10197000FD3F0000C01E0020D41E00209400002067 -:10198000600C01000D040000A01E0020801E00203D -:10199000001F00201D1F0020FF0E0000F8B5FB4CAB -:1019A000F94D0646217828790127002909D0F84801 -:1019B0000E22837E0B21002B02D1C276017787761F -:1019C000F8BD3178002903D0012901D0122016E09A -:1019D00008281CD201F0DFF8042816D0052814D0FE -:1019E000EC483378721C29790646FCF71AFD2879F1 -:1019F000401CC1B22971304605F062FD0020207103 -:101A000067710B20E0702770F8BD0C20F7E7072006 -:101A1000F5E7F0B5044683B00120009020783D281A -:101A200050D201007944097949188F44F0F01EF032 -:101A3000F0EFEEF0F0F04C72F0F0EDB7F2F0F0EB0A -:101A4000F0F0F076F0F0F0F0F0EAE9F0F0E8E7E638 -:101A5000E5E4E3F098F09CA0E2F0F0F0E1F6DFF0CE -:101A6000DEF0F0DDDCDBDAD9D80000F006FE00287D -:101A700004D0C320C84980000AF039FA05F0F0F814 -:101A800004F006FA002803D0C349C4480AF02FFA2C -:101A900006F08CFE05F026FD0024BB4821460471AB -:101AA000083005F00DFDBE4821460477BD4805F01D -:101AB00010FDFEF7B9FEB548012104714171022203 -:101AC000C2700170AAE2B14C207800280AD0B04957 -:101AD0000E208B7E0A22002B40D1C8760A77012087 -:101AE00088769BE201F057F804280FD005280DD026 -:101AF0000025A54829460571083005F0E1FC25714F -:101B0000012060710A21E170207087E20C202071B1 -:101B1000F6E7A01CFFF742FF80E2A51C9B4C207853 -:101B2000261D002806D09A480E22837E1721002BFE -:101B30006ED073E22A460121002005F018FE3070B5 -:101B4000002806D1294698480AF0D3FA974801217F -:101B50008176012060711721E17020705EE2A01C87 -:101B6000FFF793FE5AE2A01CFFF74BFE56E2874CAC -:101B70002078002806D086480E21837E2B22002B59 -:101B800078D04BE20821A01DFAF7ECFA0020207172 -:101B9000012060712B21E17020703FE27B480178C9 -:101BA000002906D02030837E0E220F21002B2FD05B -:101BB00034E2002101710E2181700F21C170FF21DB -:101BC00081710021C9430181794949684A7882724B -:101BD0008A8882814988C1810121417182E0B6E110 -:101BE000B2E181E084E01BE1A6E0F4E147E014E02B -:101BF00064E0E1E08AE155E1F5E0F0E0ECE0E7E007 -:101C0000E2E0DDE0B9E104E031E183E1EFE003E2AD -:101C10008CE0A01CFFF7A9FD00E25C4D28780028AD -:101C200006D05B480E22837E3121002B7ED0F5E169 -:101C3000022020560B22D243811A90421BD008DC8E -:101C40001C3118D00A2916D0142914D0182909D10A -:101C500011E0014608310ED004290CD008290AD021 -:101C60000C2908D012202871012068713121E970F7 -:101C70002870D3E137E1FCF725FC0020F3E7A51C31 -:101C8000424C2078261D002806D041480E22837E33 -:101C90003221002B4AD0C1E100212A46084605F036 -:101CA00066FD3070002803D1294642480AF021FA27 -:101CB000012060713221E1702070AFE1334801787A -:101CC000002906D02030837E0E223021002B2DD01B -:101CD000A4E1374AA17811700021017101214171FD -:101CE000302248E1017099E1A01CFFF701FD95E168 -:101CF000264C2078002806D025480E22837E3921E4 -:101D0000002B13D08AE100F046FF042811D00528EB -:101D10000FD000252248294605771D3005F0D9FB54 -:101D20002571012060713921E17000E083E02070AD -:101D300074E10C202071F4E7144D2878002806D0B7 -:101D400013480E22837E3721002B74D066E1608811 -:101D500001A904F000F9002806D002202871012012 -:101D600068713721E97034E101987F2120300176D4 -:101D7000417600218176227982716279C271A279DD -:101D800002722971EBE70000E01E0020801E002097 -:101D9000A01E0020E81E0020600C010016030000B9 -:101DA000001F00201D1F0020D41E0020C01E002088 -:101DB0008C00002094000020A01CFFF73AFC2DE1CD -:101DC000A01CFFF788FB29E1A01CFFF749FB25E1D8 -:101DD000A01CFFF7EAF921E1FFF7A8F91EE1A01C1A -:101DE000FFF706F91AE1A01CFFF7B4F816E1994CC9 -:101DF0002078002806D098480E21837E0522002BEB -:101E000071D00BE104F084FFE08005F0C0F820728F -:101E100000202071012060710521E1702070FDE03B -:101E20008C4D2878002807D08B480E21837E3822DD -:101E3000002B58D0F2E095E01F2028710120687136 -:101E40003821E9702870A078002808D0012806D031 -:101E5000022804D0032802D012202871DEE00026D8 -:101E600005F0BBFCA07806F0CDFD2E71D6E07948D8 -:101E70000178002906D020300E22837E1146002BE7 -:101E800070D0CBE0754A73491389CB8053890B819D -:101E900092894A8100210171012141710E22C27093 -:101EA0000170BBE06B480078002806D06A480E221B -:101EB000837E2521002B55D0B0E0608801A904F075 -:101EC0004AF8002810D00220624900220871084612 -:101ED00082600273CA805F480E2181702521C17023 -:101EE00001214171FEE652E0019E5D4F35466035AD -:101EF0000A360020A871314638460AF018F9A87948 -:101F00000028F6D153486188C180E4E7A01CFEF7A1 -:101F1000DFFF83E04F4C2078002806D04E480E218A -:101F2000837E0622002B32D078E0002020710E2024 -:101F3000A0700620E0704B480AF0CAF8A179012091 -:101F40000143A171607163E0FEF73FFF66E0414825 -:101F50000178002907D02030837E0E213C22002BFF -:101F600015D05BE042E0404962880A84002101719B -:101F7000012141713C22C270B4E6364D2878002818 -:101F80000AD035480E21837E1322002B46D1C1761C -:101F900002770121817641E0608801A903F0DBFF2F -:101FA000002801D0022006E0019801462030827905 -:101FB000012A02D00C20287105E000222A71007E3F -:101FC00028724888E880012068711321E9700E2189 -:101FD000A970287022E0A51C1E4C207800280AD089 -:101FE0001D480E22837E3421002B17D1C276017743 -:101FF0000121817612E000F0CEFD05280AD02846A6 -:1020000000F09CFB00202071012060713421E17000 -:10201000207003E00C20F6E700200090009803B049 -:10202000F0BD10B5062811D201007944097949188C -:102030008F440C0B0B0C0C0200F044FC002804D065 -:102040009B200A49000109F052FF10BD07490848CA -:10205000F9E70000801E0020A01E00208C00002058 -:10206000881E0020861E0020C01E0020600C01007B -:10207000CA090000F7B582B0064603981746818862 -:10208000FE48FE4A41430398039D008B00245043C1 -:10209000009080352A7E002A0CD0F948012A406839 -:1020A0003AD0022A1ED0032A36D0F6A1F94809F008 -:1020B0001EFF4AE0002F03D1F2A1F74809F017FFF5 -:1020C000EF4C6068002803D1EEA1F44809F00FFF3F -:1020D0006068A168001D0A18F1490098401814189A -:1020E000012017E0791E084303D1E6A1ED4809F06D -:1020F000FEFEED48016800980C18002F09D0E0485A -:102100004168EA480818A04203D9DEA1E84809F06E -:10211000EEFE0320287616E00C46002F13D0D84F91 -:10212000002807D17878002804D0FF20D5A18000AE -:1021300009F0DDFEDD4879680818A04203D9D1A175 -:10214000DC4809F0D4FE002C03D1CEA1DA4809F016 -:10215000CEFE2146E869FAF77EFF0027E861377076 -:1021600001243471E869B060039806F0E9FD0028A5 -:1021700001D0777104E0287E012805D0022070711B -:10218000CE48F06005B0F0BD7471F9E7F0B50546D2 -:1021900087B00F46012000F001FDC4B20B2000F013 -:1021A000FDFCC0B2844204D0FF20B6A14A3009F041 -:1021B0009EFE012000F0F2FCC4B2182000F0EEFCFC -:1021C000C0B2844204D0FF20AEA14B3009F08FFE94 -:1021D0003846BB4F6C1E6900CD190026403D0928CA -:1021E0007DD201007944097949188F440441505047 -:1021F0004CEAEAEAA0000B2C04DBFF20B1A11E3060 -:1022000009F075FEE88F694603F0A5FE002804D0AA -:10221000FF209CA1533009F06AFE0B2C04DBFF2049 -:10222000A8A11E3009F063FE0099E88F4988884212 -:1022300004D0FF2093A1553009F059FE009880305A -:10224000007E002804D1FF208EA1563009F04FFEF9 -:102250008B48466046708660009806F0C6FA0028F3 -:1022600004D0FF2087A15D3009F041FE07B0F0BD2A -:1022700006F050FB0028F9D0FF2082A1633009F05E -:1022800036FE07B0F0BDFCF7C5FB07B0F0BD04207B -:10229000C04300F083FCC6B2192000F07FFCC0B23E -:1022A000864204D0FF2077A16F3009F020FE0B2C6E -:1022B00004DBFF2083A11E3009F019FEE88F694678 -:1022C00003F049FE002804D0FF206EA1733009F00E -:1022D0000EFE0B2C06DBFF207AA11E3000E070E022 -:1022E00009F005FE0099E88F4988884204D0FF2054 -:1022F00064A1753009F0FBFD009806F039FB002859 -:1023000004D0FF205FA1783009F0F1FD009C00228D -:10231000214602A8FFF7AEFEA034A07802A9FBF781 -:102320007DF80099088E401C088607B0F0BD0B2C84 -:1023300004DBFF2063A11E3009F0D9FDE88F694658 -:1023400003F009FE002804D0FF204EA1833009F0DD -:10235000CEFD0B2C04DBFF205AA11E3009F0C7FD77 -:102360000099E88F4988884204D0FF2045A1853034 -:1023700009F0BDFD00988030007E042804D0FF20C5 -:1023800040A1863009F0B3FD009C98200655A0348A -:10239000A578504F681E0B2804DBFF2049A124308C -:1023A00009F0A5FD4648690008184038C787A0789D -:1023B000FAF7A4FB4848A6700078EFF769FF07B06A -:1023C000F0BDFF202FA190304EE7F8B5434E0546F3 -:1023D00030780A4600240127002809D03146496890 -:1023E00004280BD0052813D0772026A1C00002E0D6 -:1023F000E72024A1800009F07AFD0FE00220687137 -:10240000002A0AD00820326900F0E1FB044605E00A -:102410006F71002A01D0324C00E00C462146306931 -:10242000FAF719FE0021306129702F71A860B06899 -:10243000FF303130E860F8BDF0B5074685B00E4694 -:10244000012000F0ABFBC4B20B2000F0A7FBC0B230 -:10245000844204D0FF200BA19B3009F048FD0120ED -:1024600000F09CFBC4B2182000F098FBC0B284427C -:102470003AD0FF2003A19C3034E00000E2040000C9 -:10248000A81F00207372635C6C6C5F6C6D2E6D30E6 -:102490002E63000002040000CE030000CF03000002 -:1024A00055040000E9030000A00000205F040000C4 -:1024B000EE030000FD03000005040000F604000028 -:1024C000D41F00207372635C6C6C5F6C6D2E6D307A -:1024D0002E630000FFFF00009C000020B41F0020BE -:1024E000B80B000009F003FD00250120FA4C092E6D -:1024F0006ED231007944097949188F44041A37376C -:1025000033696918510060732073607800280ED118 -:10251000F248456085602573A068C33805F032F83D -:10252000002804D0FF20EE49B03009F0E0FC05B0EF -:10253000F0BD6178002909D0207B002801D105F089 -:1025400056F96573FAF740FA05B0F0BDA07305F0CF -:102550009CF80028F8D0FF20E149C43009F0C7FCFE -:1025600005B0F0BDFCF756FA05B0F0BD0420C0433D -:1025700000F014FBC4B2192000F010FBC0B284427A -:1025800004D0FF20D649D23009F0B1FC00216846C2 -:10259000FFF71BFF69463846FAF740FF05B0F0BD6C -:1025A0002078052804D0FF20CD49DE3009F09FFCBB -:1025B000207F002804D1FF20C949DF3009F097FCB3 -:1025C00025772570207DFAF799FA257505B0F0BDBD -:1025D000FF20C349EA30A8E7F0B5BF4C87B02078A8 -:1025E0000026042805D02078052802D00C2007B04A -:1025F000F0BD01276770607B0025002827D072B6E8 -:10260000607B002808D0A07B002805D005F0EFF8FB -:102610006573A573FAF7D8F962B6207DFBF72EFD36 -:10262000002828D0207F002808D02577207805288A -:1026300003D0AB49AB4809F05AFC0C2665702570F5 -:10264000207DFAF75BFA2575304607B0F0BD207D96 -:10265000009003216846017302214173FAF769FA79 -:1026600004900020C04305906846077202A90098B4 -:10267000FAF7D4FED1E720BFCFE7F0B5964883B094 -:102680000078002801D0FFF7A7FF944F0120387091 -:10269000FF26954D2A36002405E00B2C03D39349E1 -:1026A000304609F024FC204601A903F054FC002820 -:1026B0003AD101988030007E002835D00B2C03D30E -:1026C0008A49304609F013FC2046AC4230D06946B6 -:1026D00003F041FC002804D0C1208449800009F0A7 -:1026E00006FC0098A0308078FBF7C8FC002823D0B7 -:1026F0000098002198221154A03084780C2C04D327 -:10270000FF207A49243009F0F2FB7948610008186B -:102710004038C5870098A0308078FAF7EFF9009923 -:102720000020A0318870B6E7641CE4B2082CB4D352 -:102730000020387003B0F0BD20BFD2E710B500789C -:102740006C4C00280FD001280CD068496A4809F069 -:10275000CEFBA0686949884203D36449684809F000 -:10276000C6FB10BD6748A060F3E710B55B490022C7 -:102770000A70604C207058480270427002770273F1 -:1027800042738273826102752030574B03800521AA -:1027900043808380001D491EFAD1100004D0002A16 -:1027A00004D05848A06005E0A26003E04F495248B9 -:1027B00009F09DFBA0685149884203D34B4950481A -:1027C00009F095FBFFF759FF10BD70B5424D0E465D -:1027D000297884B01446002902D00C2004B070BDC2 -:1027E000A8618030007E002804D051203C49C00000 -:1027F00009F07DFB4448464344434448E41C3018F8 -:102800006E60AC60844200D82046A8603349002046 -:10281000886005212970687028773D48FAF71AF911 -:102820002875002803D12E493A4809F060FBFAF7D1 -:1028300080F9286101216846FFF7C7FD287D6946B8 -:10284000FAF7ECFD002004B070BD10B5224C84B046 -:102850002278002A02D00C2004B010BD2A4A51432D -:102860005043C91C294AA16060608018814200D889 -:102870000846A06000206070042020702448FAF709 -:10288000E9F82075002803D11549234809F02FFBEA -:10289000FAF74FF92149FAF7DEFB2061012168467A -:1028A000FFF793FD207D6946FAF7B8FD002004B0DC -:1028B00010BD10B5084CA1690160FFF78DFE002125 -:1028C000A16110BD70B5044C84B02078052827D0D4 -:1028D0000C2004B070BD0000B41F0020A81F002011 -:1028E0008424010073020000FFFF0000C4240100E3 -:1028F000D41F00209C000020310500006A18000051 -:102900003A050000C409000071020000B3FBFFFF9C -:102910003924010093020000B1020000B80B00004E -:10292000A069002803D1D949D94809F0E0FAA06983 -:102930008030007E002804D0B520D449800009F002 -:10294000D6FAA069A0308078002803D0CF49D148BA -:1029500009F0CDFAD048FAF77DF8A169A2225054C7 -:1029600005464E88401E0B2804DBFF20CB4924304F -:1029700009F0BDFACA49680040184038C687A06906 -:10298000A0308078002803D1C049C64809F0AFFACA -:1029900001226846A169FFF76DFBA0696946A03076 -:1029A0008078FAF73BFD0020A06104B070BD10B53F -:1029B000BD494C68983400280DD001280ED002285B -:1029C00010D0B249B94809F092FAB9488068A042DB -:1029D0000BD9012010BDFF347934F6E7B120800017 -:1029E0002418F2E7FF346134EFE7002010BDAE4851 -:1029F0004178002902D10078002801D000207047DA -:102A00000120704730B502460423AA4D803285B0BC -:102A1000002916D001292FD0022907D003292DD053 -:102A20009A49A54809F063FA05B030BD1376F9F765 -:102A3000CBFF2878EFF72CFC0220FFF7F2FA05B065 -:102A400030BD044698480078002807D01376F9F77F -:102A5000BBFF2878EFF71CFC05B030BD01222146F2 -:102A60006846FFF707FBA220005D6946FAF7D6FC2F -:102A7000208E401C2086EAE7032010E081888F4BDF -:102A800059438F4B1960D16A0B8903838B79837506 -:102A90004B8983808B89C380C9890181022010768C -:102AA00005B030BDF0B5834E014600253078804C2E -:102AB00085B0002908D0012919D0022944D0032962 -:102AC0004FD072497F483BE0EFF7E2FB6078002887 -:102AD00007D100216846FFF778FC207D6946FAF7A8 -:102AE0009DFCF9F771FF6573A57305B0F0BD6E4FDE -:102AF00020697968714B401873494218A069818830 -:102B00004088594300F063F8B1680546884205D211 -:102B1000A1696A4A88884243551903E0674909F068 -:102B2000C5F8A1690883A06905218175008B6349F7 -:102B30004843281A6549B8608842D6D35749644843 -:102B400009F0D5F905B0F0BDEFF7A2FB0120207721 -:102B5000A06921698030C16105760520FFF761FA1F -:102B6000BFE7EFF795FB05B0F0BD704710B54E4AD3 -:102B700000290ED0012906D0022906D04349554824 -:102B800009F0B5F910BD401E03E05178491C5170A1 -:102B9000001F506010BD4648007870478107C90E7D -:102BA00000280BDA0007000F083880084A4A800026 -:102BB0008018C069C8400006800F70478008474AE7 -:102BC000800080180068C8400006800F7047F7B585 -:102BD00082B00D460646424F002406E00B2C04D37B -:102BE000FF202E492A3009F082F9204601A903F07E -:102BF000B2F900280ED101988030007E002809D05B -:102C00000B2C04D3FF2025492A3009F070F9BC426F -:102C100004D006E0641CE4B2082CDFD3002005B029 -:102C2000F0BD6946204603F096F9002804D0D7206D -:102C30001A49800009F05BF9A64203D117492948D7 -:102C400009F055F92848341B444300988030C16985 -:102C50000498FBF787F9041908D5281B6642294612 -:102C6000401E09F031F86843841B05E029462046E0 -:102C700009F02AF86843241AAC4204D9DD20074938 -:102C8000800009F034F9204605B0F0BD842401002D -:102C9000D2020000D60200008D210100C4240100F0 -:102CA000D41F0020D9020000A81F00203B03000011 -:102CB000B41F00209C000020CD040000E2040000AE -:102CC000A0000020F90400004E0600006A18000071 -:102CD000840400001605000000ED00E000E400E0C0 -:102CE000FFFF00005F03000077080000FE48406817 -:102CF000002800D001207047FC48C07E7047FC4887 -:102D0000C07E7047FFB5F94E85B0706A34680568BB -:102D100060680190306A0390298E0798401A80B24B -:102D200002900898002804D02746383720464830BB -:102D300002E0371D2846A83000900320387105981E -:102D400000281FD001287DD0022864D003287AD023 -:102D5000E8A1EC4809F0CBF80898002806D03879AB -:102D6000032803D0E3A1E84809F0C1F8A16A70691B -:102D7000FAF771F9B860216A606A81427ED90099D8 -:102D8000086036E1306A002804D12520D9A140012D -:102D900009F0ADF8288BDD49484342180698002118 -:102DA000002804D05043DA4908F080FF411CA1619B -:102DB0000191AA88D548002142430698002804D0F2 -:102DC0005043D34908F072FF411CE161306ACF4A99 -:102DD000801CA062298BCD4B5143019A891ACD4AA0 -:102DE00089180A18A262A87D019958434900081859 -:102DF000FF30193020626062306AC749101AFF380C -:102E000015388842A8D2C54988427DD2B9A1C448A4 -:102E100009F06DF88CE0288BBC4AE16850430A1831 -:102E200006980021002804D05043B94908F03EFF1D -:102E3000411CA161AA88B548002142430698002898 -:102E400007D001E041E076E05043B14908F02EFFA1 -:102E5000411CE161306A002803D1A6A1B14809F004 -:102E600046F8AE20405BA94A0028288BE16823D0B1 -:102E700050430818A169401AA06200E0B7E0216938 -:102E8000A068A24A4843A1694018A97D4000514367 -:102E90004018FF3017302062A888E1695043411A7A -:102EA000A14808186062A06A316A401A9A49FF383E -:102EB000553888423CD34FE750430818A169401A5F -:102EC0003168D63849684018D6E7284680300190E6 -:102ED000C08D002802D0306A002803D185A1934814 -:102EE00009F005F8A8888949E3694843C01AA06237 -:102EF00001999C46CA8D2169A368521A4B43A16966 -:102F000059186346534300E012E0C918AA7D7F4B6D -:102F100049005A438918FF3117312162824941180B -:102F20006162316A401A7C49FF3855388842C2D202 -:102F30000120387110E70898002803D03420005D84 -:102F4000002872D1A88871494843E169401A029962 -:102F50004843A062284680300490C08D0028019824 -:102F600025D0002803D063A1714808F0C0FF049861 -:102F7000664AC18D02980818E16948434000FF3055 -:102F800017302062A8885043411A674808186062C9 -:102F900055484068002819D0A26A03990120511AA7 -:102FA0005D4AFF395539914285D23871D4E60028FF -:102FB00002D00398002803D14EA15E4808F097FF85 -:102FC0000198A16AD6380818A062D0E7F9F7B1FDD8 -:102FD000726901461046FAF7C5FFA16A081A4E4900 -:102FE000FF3850388842A5D2012009B0F0BD0098C2 -:102FF000016000985049006880354018F860298BBE -:103000000798081A00B2002804DD0598022801D0AC -:10301000022000E000207871089838700898002895 -:1030200006D03420005D002802D0022009B0F0BD97 -:1030300008980121484020346075307FF27E39467F -:10304000B37E9A4202D0FAF7E9F904E00020F07664 -:10305000B07630607062002009B0F0BDF8B5224F44 -:1030600038680468416A26460D682036717D00295B -:103070000AD0618E2A8E914206D1407A002803D16F -:103080001CA12E4808F033FFF9F753FD164F39689D -:103090004A6901461046FAF765FF3F680028796AD9 -:1030A000096807D08988194A51433A68D269891A50 -:1030B00008F0FCFD2A8E618E1318994202DB491C30 -:1030C000618602E0401C10186086B07D002806D1A1 -:1030D0009C21608E495B884201D1401C6086388B00 -:1030E000014E03282FD22BE0B0000020801E0020CC -:1030F000A81E00207372635C6C6C5F6C6D2E733065 -:103100002E6300001A05000023050000E204000001 -:1031100040420F00330400005C0800001D03000063 -:10312000BD040000C504000094FBFFFFDE040000A6 -:1031300004050000FD0400004B1700000406000019 -:10314000401C388302E0618E98204153284640306D -:103150000090C1898089081A298E401E401887B2C4 -:1031600016E03068FF49406AEB7E00795B00400062 -:10317000085AC95A081881B2207D0023FFF7C2FD02 -:1031800000280FD001280ED0F749F84808F0AFFE0C -:10319000628EB81A00B20028E3DA00980821817222 -:1031A00007F042F9F8BD608E401C6086F0E770B50C -:1031B000EF4D09292B686A687BD20C007C44247986 -:1031C0002419A7440463879784A6A675A30000204A -:1031D0001062D17E042956D20B007B441B79DB1888 -:1031E0009F4451510147516A0C6811680870116879 -:1031F000486010682030407D002808D1F9F799FC1C -:1032000069680968096CFAF7ADFE002817DC686880 -:10321000228E0168498E914205D123468033998BD5 -:103220008A1ADA8304E0891A9E2211530168498EB2 -:1032300021860268C1681164C168416111E0686853 -:103240000168098E228E8B1A22468032D383016850 -:10325000098E218601680B6CC3600B6C4361886C1E -:103260009062204607F090FD002821D0C1A1C548FA -:103270002AE0D068506106F052FC002818D0752072 -:10328000BCA1C00020E0BBA1BF481DE0D07E042847 -:1032900017D201007944097949188F441212010BA1 -:1032A00007F0CCFE002803D0B2A1B84808F01FFEFA -:1032B00070BD2EE006F068FD0028F9D0ADA1B4483D -:1032C00002E0F320ABA1800008F011FE70BDFBF717 -:1032D000A1FB70BDD87E022806D0D87E032806D078 -:1032E000FF20A4A1A4300EE0FFF7B8FE70BD00F0EF -:1032F000DEFB70BDD87E0228F6D0D87E0328F6D03B -:10330000FF209CA1AF3008F0F2FDF0E7F9F7F6FBE3 -:1033100070BDFF2097A1BE30D6E7F3B50126944CCF -:103320009C4D81B00F46092945D2080078440079A8 -:1033300000188744042D38382D40403838000121CA -:10334000944800F09BFB39460198FFF730FFE87E78 -:10335000022826D160680468406A0768F9F7C7FB4D -:10336000B9888D4A5143E269891AD639E162B72892 -:1033700003D283200001081A02E0081A8749401886 -:10338000E0628748E16A814200D80846E06205E0D1 -:103390000198FFF70CFFE87E022802D12868203050 -:1033A000067503B0F0BD25600198FFF700FF00200F -:1033B000206003B0F0BDFF206EA15C3008F097FDE7 -:1033C00003B0F0BD70B506460C4609291FD20800AF -:1033D0007844007900188744040D11110D1A1A1150 -:1033E000110001216F4800F049FB21463046FFF7EC -:1033F000DEFE70BD3046FFF7DAFE70BD5C4D6948F9 -:1034000028603046FFF7D3FE0020286070BDFF2003 -:1034100058A1823008F06BFD70BDF0B55D4985B0F4 -:10342000CA7E0026524C032A03D02831CA7E032AC2 -:1034300063D100252160002822D001280CD04DA1A5 -:10344000594808F054FD2068002E0560456225604B -:1034500053D0002005B0F0BD0320887600E020BFE7 -:103460002068C17E002903D0C17E827E9142F6D0C1 -:10347000C17E002902D000268576E4E70126FBE71D -:103480000026032708468F76C97E032903D0C07E15 -:1034900000282ED02EE0007F002803D135A143481C -:1034A00008F025FD2068067F6846077102214171FA -:1034B000F9F73FFB0290FF20F530039001216846A9 -:1034C000017069463046F9F7A9FF2068007FFAF7D6 -:1034D000D5FD00280BD02068007FF9F70FFB20688E -:1034E0000577C576857605600126456202E020BF36 -:1034F000EBE7012620688576A5E70C2005B0F0BD36 -:1035000010B5244800F019FB264800F016FB2849A6 -:1035100000200875274948701E494861214A5061BA -:103520008876907612494860086010BDF8B5224E42 -:1035300005463068002401270004810F1F480068F9 -:10354000800F814204D0FF200AA1C83008F0CFFCD0 -:1035500030681B4E0004810F30680006800F8142E6 -:1035600035D02FE0E2C10100F43001003E0600003A -:10357000B00000207372635C6C6C5F6C6D2E7330F6 -:103580002E630000A2030000AF030000C10300008F -:10359000C5030000801E0020E204000087F8FFFF42 -:1035A00038120000A81E00200A0300007302000069 -:1035B000D01E0020A900002000E400E008E400E0A4 -:1035C00018E400E0FF20FE49C93008F090FCFD48F7 -:1035D000C0693168800F0904890F884204D0FF2038 -:1035E000F749CA3008F083FCF7480570F74DEC76D0 -:1035F000AC76F74EF476B476F648077104606C62E8 -:1036000074622C602846346000F097FA304600F06F -:1036100094FAF1480475F14844706C617461AC76B9 -:10362000B476EF4844600460F8BDEA490871704719 -:10363000F8B5E649CA7EE648E94C002A02D1C27EC6 -:10364000002A03D0C97E022907D009E0E54821609D -:10365000F9F700FA216808770AE0C17E002901D055 -:103660000C20F8BD2060E048F9F7F4F921680877EC -:103670002068DA490160DD494162007F002803D1FA -:10368000CF49DB4808F033FCF9F731FAD9498842D1 -:1036900000D20846D849401886B221680320C8766F -:1036A00006F018F92168086106F03CF901270025A9 -:1036B000002827D006F036F921684A6A10600868A9 -:1036C000012107706846F8F7FBFC68460078CB4993 -:1036D000000208F0EBFA0F46F9F72BFAF119F9F7A7 -:1036E000BAFC2168C8602268032010720220507260 -:1036F0001571107FD37E111D967EB3420ED0F9F75F -:103700008DFE0FE0F9F715FA3146F9F7A4FC2168B0 -:10371000C8600868057008684770E4E7D576957654 -:10372000156055622068058300202560F8BD70474C -:10373000F8B5A64EF17E002903D1A549C97E00291E -:1037400001D00C20F8BD0221F176A24FA24C776285 -:1037500034600025386025753979C07E4A00A84953 -:1037600040008A5A085A2B46101881B22A46284629 -:10377000FFF7C8FA002803D09149A24808F0B7FB28 -:1037800025610120A5602075658625869E48857582 -:103790003968088E401E088635830020F8BD10B5B4 -:1037A0008F4801244068817E03290CD00168497844 -:1037B000002906D0006A9549884202D9002406F003 -:1037C00010FB204610BD0024FBE7854840680268D6 -:1037D0001178491C1170016A0068C26A914204D8CC -:1037E000007D012801D00120704700207047002093 -:1037F0007047F8B57A4C75482060416A00680D68DA -:10380000002134221154A621495D002951D1007DA7 -:1038100003284ED1F9F78DF9226852690146104606 -:10382000FAF7A0FB002844DD2768794A796A3E68E8 -:10383000096889885143F269891A08F037FA298E94 -:10384000401C401830869C20415B3868028E891AE3 -:1038500009B200292DDD0121203081752846403034 -:10386000C1898089664F081A298E401E401886B289 -:1038700018E0496A028E09794900795AEB7E007D89 -:103880005B00FB5A591889B20123FFF73BFA002865 -:103890000FD0012810D002280BD0BD204849C0000D -:1038A00008F025FB21680868028EB21A12B2002ABD -:1038B000DFDA00202060F8BD20680068018E491C16 -:1038C0000186EFE770B5464900244D68062849D2C5 -:1038D00002007A441279921897441E2602112A1087 -:1038E000002000F072F9EC76AC762C6000206C625F -:1038F00001F049FC0021084600F0C0F870BD3248D4 -:103900000D680078EEF7C4FCEC76AC762C600020F5 -:103910006C6201F038FC70BD012000F056F9002106 -:10392000084600F0ABF870BD29680320087570BD2B -:10393000686A29680068CA698A608188344A514384 -:103940002A68D1600146C031CA8902830A7B827528 -:103950000A8A82804A8AC280898A01812968022073 -:10396000087570BD73201649000108F0C0FA70BDDB -:1039700070B500280AD00024194D01280DD0022866 -:103980004AD00F49234808F0B2FA70BD00F074F92C -:103990000021084600F072F870BD686801684C703C -:1039A000C476847604604462032001F0ECFBF9F7EE -:1039B0000BF805486C600078EEF76AFC6C6070BD2F -:1039C0007435010000ED00E0A8000020801E0020FA -:1039D000A81E0020B8000020D01E0020A900002052 -:1039E000B00000201B330100C5330100AC000020F3 -:1039F000B5020000F6050000BB0200001027000021 -:103A0000E2C101003D030000F01E0020D982130036 -:103A1000E20400005307000000F02EF96868C47645 -:103A20008476046000214462084600F027F80420F0 -:103A300001F0A9FB70BDAD494968CA7E022A08D1D0 -:103A40000A681378002B04D150600968CA6A1018FC -:103A5000C862704710B5A54A002952680CD00129E8 -:103A600007D0022907D0EF20A149C00008F03FFA93 -:103A700010BD801E00E0401F106210BD70B59B4C51 -:103A800005466268002908D0002A04D0FF20984922 -:103A90000C3008F02CFA656070BD002A04D1FF20BC -:103AA0009349123008F023FA0020606070BD38B5E9 -:103AB0008E4C206801684978012927D00121684689 -:103AC000F8F7FEFA684600788A49000208F0EEF836 -:103AD0002068426AC06812685118F9F7BCFA216878 -:103AE000C86085482268002382421BD0108B0028C2 -:103AF00018D05372032010721371107FD47E111DE1 -:103B0000957EAC4214D0F9F789FC38BD7D21C068A0 -:103B1000C900F9F7A0FA2168C86005F0DBFE21684A -:103B20000861DEE7108B401C108302205072E1E731 -:103B3000D37693761360536238BDF8B56B4C054667 -:103B40001F27EE7E042E2ED2300078440079001814 -:103B50008744332901246948854204D0FF20644901 -:103B6000FD3008F0C4F902202560A87600E020BFEF -:103B70002168C87E002803D0CA7E887E8242F6D0A3 -:103B8000CA7E002A04D000228A760C27226011E027 -:103B900000228A760A604A6222600EE00120FFF766 -:103BA0003CFC074604E041205149C00008F09FF961 -:103BB000002F02D0E87EB042C3D1E87E002803D0B7 -:103BC0004B494F4808F093F9F8BDF8B5474D00262A -:103BD0006A680128516A0C683FD108794949400058 -:103BE0000B5A1068077D032F06D0027D022A10D0E1 -:103BF000007D012820D030E00661106886609C209E -:103C0000025BE07E4000085AC01881B20023032006 -:103C10001BE022468032D78D0761E07E928B400008 -:103C2000085AC01881B200230220FFF76BF86A68B7 -:103C30000121126811750AE09C20025BE07E4000C1 -:103C4000085AC01881B200230120FFF75BF8002852 -:103C500003D027492C4808F04AF9F8F7B5FE2B485D -:103C60000078EEF715FB686806830268218E51869E -:103C7000006820308675F8BDF8B51C4D00216868D5 -:103C80000C4600684278002A01D0447027E0007892 -:103C9000002809D001216846F8F712FA6846007832 -:103CA0001449000208F002F86868426AC0681268A5 -:103CB0005118F9F7D0F96A68D06014710220507277 -:103CC000107FD37E111D967EB34202D0F9F7A6FB7A -:103CD00003E0D47694761460546268680483F8F73D -:103CE00073FE0A480078EEF7D3FAF8BDB000002062 -:103CF0007435010010270000A81E0020801E00203F -:103D00000E020000E2C101009F060000A800002092 -:103D1000F3B5FB4F81B078600298B870002002F0D4 -:103D2000E7FF02F085F9F7490024F7480C77847122 -:103D3000C471F64EF64DF461F6482C720470F648E4 -:103D40008473847484770C758C710298FFF7EEFB92 -:103D5000F249F34805F08BFD786806F0FEFFF14864 -:103D600002F08EF9002803D0EFA1C32008F0BFF8BD -:103D7000F4612C7203B0F0BD70B582B00E461D46E2 -:103D8000144601A902F096F9002807D1FEF7B4FF06 -:103D9000022803D1DB48007D002802D0012002B0B8 -:103DA00070BD01988030807C02F0F4FF00280DD0B7 -:103DB000684602F0FFFF0028F1D0002C03D002F08B -:103DC000A7FFA0420AD2002002B070BD9320DBA161 -:103DD000800008F08CF8002002B070BD009802F05E -:103DE00025FB3146009802F026FBE2B229460098F6 -:103DF00002F0DEFC03F007F8002803D1CFA1D4487D -:103E000008F075F8BE4C0025A068A0304179002963 -:103E100002D04571FFF7EDFCA0688030458301209A -:103E200002B070BD30B40179002904D0012909D055 -:103E300030BC002070470488831D4288204630BC77 -:103E4000022199E70488831D4288204630BC012165 -:103E500092E7F8B51D4614460E460746FEF74CFF9E -:103E6000022803D0A748007D002820D0A4488168FC -:103E70004988398080688030807C03F0B1F900285F -:103E800003D1AEA1B34808F032F8684603F0B8F9A0 -:103E900000280CD0009802F005FB3070022807D0F3 -:103EA000012805D0A5A1AC4808F021F80020F8BDF4 -:103EB0002946009802F093FC2080002803D19FA19E -:103EC000A64808F014F803F0C7F9002804D1AB2085 -:103ED0009AA1800008F00BF80120F8BD38B504461F -:103EE000831D821C6946FFF7B4FF00280CD0002018 -:103EF000607168460078012807D0022805D08AA1A1 -:103F0000FD2007F0F4FF012038BD2071FBE7F0B57C -:103F100083B00546FEF7F0FE7E4F3E463C46203617 -:103F20004034022802D0207D00287DD0207F102838 -:103F30001AD1A079002803D080A1894807F0D7FFC3 -:103F40006F48816808464030827F92070CD5002276 -:103F5000227249886181C17F2173018CE181408C8B -:103F600020820120A0712277B07C002876D164489D -:103F700002A980688030807C03F00CF8002806D00D -:103F80005F486A464178127A8918417004E0EF2050 -:103F90006AA1C00007F0ABFF207D002852D058482E -:103FA000B96D806849884088884203D063A16D4814 -:103FB00007F09DFF524880688030807C03F010F944 -:103FC000002803D15DA1684807F091FF03F071F963 -:103FD000002837D04A48694680688030807C01904C -:103FE00000200870019802F0D5FF002803D153A1EA -:103FF000A32007F07CFF019802F0ABFE002803D15C -:104000004EA1A82007F073FF684601783C4842782B -:1040100089184170B96D40314A7A012A10D10022C5 -:1040200022708068408800E018E06080887A207103 -:104030000120B077207F102801D0282800D12277D6 -:10404000002020752E484178002907D082685288C8 -:10405000FA8639870121B17400214170FEF746FECE -:10406000002806D1207D002803D025488078EEF76F -:104070000FF9B07E00280BD0002068701021297045 -:10408000F17EA970317FE970B076012003B0F0BDF8 -:104090003878002809D02C22B91C284607F09DFD4D -:1040A0000E2028700020387018E0B07B002818D04F -:1040B000207F102808D0282806D0002804D0FF2010 -:1040C00019A1BF3007F013FF0120E870F07BA87042 -:1040D000307C68700F2028700020B073012003B07E -:1040E000F0BD0121284605F05FFB00283ED0207D71 -:1040F00000286FD10021284605F056FB03B0F0BD23 -:10410000C00000208C1F0020AC1F00204C2000208D -:104110002C2000204C1F00206C1F00203420002089 -:10412000B31F0020C80000207372635C6C6C5F6377 -:1041300074726C2E73302E63000000007372635C27 -:104140006C6C5F6374726C2E73302E630000000021 -:104150006A02000095020000B3020000A502000000 -:104160005F0700007D07000083070000B17CAF1CE3 -:10417000FE480090002914D0FD480178052910D28E -:10418000491C0170002068700D21297001213175D2 -:1041900000998A883A80CA887A800989B980B0747F -:1041A0009CE7F34900200870A079002813D0207FF5 -:1041B000002804D0FF20EF49FE3007F098FE0026CB -:1041C0006E70012028700A22EB49A81C07F005FD3B -:1041D000A67183E710E0284606F00BFD0028DFD12A -:1041E000B07C002802D0E2480178C9E7B07F0028FF -:1041F00002D0207D002802D0002003B0F0BD207F37 -:10420000002803D0DB49DD4807F071FE002068700C -:104210000A21297000990A8A3A804A8A7A80898A12 -:10422000B980B0775AE772E6F8B5D54C2078012509 -:10423000002809D0D3480E21837E3B22002B02D1D7 -:10424000C17602778576F8BD0020A071FEF754FD97 -:10425000CD4E022802D0307D00283FD0C44F6946A1 -:10426000B8688030807C02F0ABFE002803D1C749DB -:10427000C74807F03CFE307D002806D0A06D4030D6 -:10428000407A002801D0012600E00026B86880307E -:10429000807C02F0A5FF002803D1BC49BD4807F08F -:1042A00026FE03F006F868403146014316D0B9688F -:1042B000FD2249882181217E40004908490031437F -:1042C00011400143217668460078002802D004207E -:1042D000014301E0FB2001402176A57100202071FF -:1042E00065713B20E0702570F8BDF8B5A44C05461B -:1042F00020780126002809D0A2480E22837E37218B -:10430000002B02D1C27601778676F8BD9E48007FE9 -:10431000002802D00C2020710BE0954F2988B86846 -:104320004088884203D1FEF7E7FC022806D002202D -:10433000207166713720E0702670F8BDB9687F2063 -:1043400020310876487600208876AA788A71EA7843 -:10435000CA712A790A72EBE7F8B5894C05462078CC -:1043600000280AD087480E21837E3A22002B03D1F1 -:10437000C176027701218176F8BDFEF7BDFC0328E6 -:1043800007D0FEF7BCFC032803D07F48007F00283D -:1043900002D00C20207118E07F4BD879082812D267 -:1043A000000102191020014668326E18203EF67F87 -:1043B000471AD655491E0906090EF6D1D879401C70 -:1043C000D871002000E007202071012060713A219F -:1043D000E1702070F8BDF8B5694E044630780028C9 -:1043E0000AD068480E22837E3D21002B03D1C2767D -:1043F000017701218176F8BD6348007F002802D053 -:104400000C2030710BE05A4D2188A8684088884202 -:1044100003D1FEF771FC022807D002203071012081 -:1044200070713D21F1703070F8BDAF686488FD880F -:104430003A896800B988401C844218D357484143E0 -:104440001046574A504307F031FC401EFF2180B20E -:10445000F531884200D90846844200D22046691CC2 -:10446000401C07F023FC6D1C6843401E85B2E6200B -:10447000C05D002800D1BD84F5800020CEE7F8B5EE -:104480003F4C054620780126002809D03D480E22E1 -:10449000837E3521002B02D1C27601778676F8BD66 -:1044A0003948007F002801D00C200AE0A8780028B5 -:1044B00001D0012804D1A888FF21F531884206D90E -:1044C0001220207166713520E0702670F8BD284FEB -:1044D0002988B8684088884203D1FEF70DFC02287D -:1044E00001D00220EDE7B96800220846C0310A7009 -:1044F000AA884A80A0300671AA78012A00D000223A -:104500000A704079002801D0FFF773F90020D8E73E -:1045100070B51B4C064620780125002809D01948A3 -:104520000E22837E3321002B02D1C276017785765D -:1045300070BDFEF7E1FB002803D11348007F00287F -:1045400002D00C20207136E0317800292ED00A29C3 -:104550002CD014292AD01E2928D0282926D0322947 -:1045600024D04B2922D0642920D01BE07C1F0020BE -:10457000C000002028410100941F00201E020000FE -:104580004C1F00206C1F00208C1F00203C410100AC -:10459000140800001C080000AC1F0020C409000023 -:1045A00010270000FF2901D0122003E03046FFF75A -:1045B000BEF80020207165713320E070257070BD59 -:1045C000F1B5FA4CA07B0126002808D0A27E0F216D -:1045D0001020002A02D1E1762077A676F8BDF44DAE -:1045E000A8790C27002816D1287F002813D1FEF7C0 -:1045F00083FB022821D1EF4800998068098842880E -:104600008A421AD10146C0310A7A002A05D04030C8 -:10461000807F80070DD4E77311E05E22125C920761 -:1046200007D406220A72A0304079002801D0FFF793 -:10463000E0F810202877002000E00220E07310202E -:104640002074A673F8BDF8B5DB4C2178012700294A -:1046500009D0D6480E22837E2A21002B02D1C276B1 -:1046600001778776F8BDD54B10210A464518203DC5 -:10467000ED7F561A9D55491E0906090EF6D11021E7 -:10468000CF4B0A4610304518203DED7F561A9D55F8 -:10469000491E0906090EF6D1C848FBF7F0FFA11D17 -:1046A000C84B102002461D18203DED7F161A8D556F -:1046B000401E0006000EF6D120710E20A0702A20A8 -:1046C000E07067712770F8BDF8B5B94F0546387FBF -:1046D0000126B64C002802D00C20E07342E0A07BFB -:1046E000002808D0A27E0F212820002A02D1E176DE -:1046F0002077A676F8BDA87805280DD013280BD012 -:10470000142809D0152807D01A2805D0292803D045 -:104710003D2801D03B2803D12888AB49884201D9E4 -:1047200012201EE0FEF7E8FA02280AD1A1482A88E2 -:1047300080684188914219D10146C0310A79002A26 -:1047400001D00C200DE0AA784A710E71282139772A -:104750000021E173A0304079002803D0FFF749F829 -:1047600000E0E07328202074A673F8BD0220F8E76B -:10477000F8B5914C074620780125002809D08B48D0 -:104780000E22837E0B21002B02D1C2760177857623 -:10479000F8BDFEF7B1FA032807D0FEF7B0FA0328F8 -:1047A00003D08348007F002801D00C2005E03B782F -:1047B000002B08D0012B06D01220207165710B2030 -:1047C000E0702570F8BD814E317A082908D27A1C34 -:1047D0007F48F9F726FE307A401C30720020ECE763 -:1047E0000720EAE710B5FEF78BFE002804D02D2045 -:1047F0007849000107F07BFB02F032FA06F0A5FAD7 -:10480000002803D07349744807F071FB05F006F8DF -:10481000002803D06F49714807F069FB70490020F8 -:10482000C86120390872624B6E4918778871C87167 -:10483000603908705D4A907390749077187598711C -:104840000871012048710222CA70087010BDF8B5C5 -:10485000594C21780127002909D054480E22837E23 -:104860001B21002B02D1C27601778776F8BD6771D4 -:104870000C214F4E2171317F002957D1007800253E -:10488000012804D0002849D01220207178E0FEF7DA -:1048900033FA002803D1FEF732FA002804D0FEF7DD -:1048A0002BFA022822D06BE005F011F8002867D01F -:1048B000307D002864D13F4E0122B068032145803D -:1048C00002F003F8B06805F0E1F9B068923002F048 -:1048D00021FA002803D14449444807F008FBFEF7B9 -:1048E000A7FE00284BD04049414814E0FEF707FAE4 -:1048F000002845D1707F002842D0012840D00428EC -:104900003ED004F0E4FF00283AD0FEF791FE0028E4 -:1049100035D03549374807F0EAFA30E0FEF7ECF9D0 -:10492000032804D0FEF7EBF9032823D028E0002069 -:10493000FEF773FD002823D12571307D00281FD19B -:104940001C48694680688030867C68460570304621 -:1049500002F020FB002803D11E49A32007F0C7FA6C -:10496000304602F0F6F900280AD11A49A82007F0CB -:10497000BEFA05E00020FEF750FD002800D12571A9 -:104980001B20E0702770F8BDF8B50B4E0446307858 -:104990000C25012700282FD004480E22837E1821E1 -:1049A000002B02D1C27601778776F8BD6C1F0020FC -:1049B0008C1F0020C00000204C1F00201C1F002066 -:1049C0002C1F00203C1F0020FF0E00002C20002088 -:1049D000382000203C410100DD020000E10200001F -:1049E0004C200020AC1F00202841010021040000C1 -:1049F0002504000039040000FEF77EF903285DD08D -:104A0000FEF77DF9032859D0FE48017F002955D1D2 -:104A10006179002901D001292DD1A179002901D086 -:104A2000012928D1A17B002905D0012903D0022921 -:104A300001D003291FD1617B00291CD0C9081AD1DC -:104A40006288012189038A4202D823888B4203D9D4 -:104A5000217901290FD119E02179002906D00129F6 -:104A600014D0022905D0032905D102E0202A0BD356 -:104A70000CE0A02B0AD22179042905D12188202914 -:104A800002D36288914201D9122517E0217941773A -:104A90006079002802D0012807D00FE0DA4A00210F -:104AA000204604F044FF054608E0D84A90790028E3 -:104AB00004D00121204604F03AFF05463571777194 -:104AC0001820F0703770F8BD70B5D14C06462078CC -:104AD0000125002809D0CF480E22837E2E21002BED -:104AE00002D1C2760177857670BDFEF705F90C22FA -:104AF000022814D1C348007F002810D1C64833884B -:104B000081684888834218D10846C030037A002B58 -:104B100005D12031C97E0F290BD0102909D022716F -:104B20000E20A0702E20E0703088E0806571257026 -:104B300070BD05210172002000E002202071EFE726 -:104B4000F8B5B34C054620780127002809D0B148B4 -:104B50000E22837E2D21002B02D1C276017787762B -:104B6000F8BDFEF7C9F80C21022813D1A548007F33 -:104B700000280FD1A84E2A88B06843889A421ED1D7 -:104B8000C822125C002A05D13B22125C0F2A0BD0EE -:104B9000102A09D021710E20A0702D20E0702888E5 -:104BA000E08067712770F8BD1022A91CD63007F08D -:104BB00014F8B0680421C0300172002000E0022027 -:104BC0002071E8E7F8B5044600783F2875D2010067 -:104BD0007944097949188F447070747070E8707066 -:104BE0007070779C7070E7F6E57070E4707070A07C -:104BF00027702B4F7070707053707070E3E270709C -:104C0000C170C5C9701F2370E1E0DFDE70DD70DCAC -:104C1000DBDAD9D8D7D6D500A01CFFF791FF8FE2F9 -:104C2000A01CFFF751FF8BE2A01CFFF7ADFE87E24F -:104C3000A11C774C207800280AD076490E208B7E64 -:104C40001A22002B3FD1C8760A770120887677E2B6 -:104C500008781F280DD8481C0BD000202071087838 -:104C6000491C04F007FF012060711A21E1702070D7 -:104C700066E212202071F6E7A01CFFF7E8FD5FE274 -:104C8000A11C634C2078002806D02022A018837E27 -:104C90000E21002B75D053E208781F280ED8481C2F -:104CA0000CD0002020710878491C04F0D2FE0120AD -:104CB00060712021E170207042E262E212202071D6 -:104CC000F5E7FFF78FFD3BE2514C2078002806D036 -:104CD00050480E22837E0A21002B67D030E2FEF777 -:104CE0000BF8032807D0FEF70AF8032803D045483D -:104CF000007F002801D00C2004E048490020C86152 -:104D0000474908722071012060710A21E17020700A -:104D100016E2A01CFFF72CFD12E2A51C3C4C2078EB -:104D2000261D002806D03B480E22837E1721002B2B -:104D30003CD005E22946012004F073FE30700028C3 -:104D400006D132482946064607F0D3F90120B07152 -:104D5000012060711721E1702070F1E1A01CFFF7C4 -:104D6000B3FCEDE1A01CFFF76EFCE9E1284C2078D4 -:104D700000281CD027480E21837E2B22002B00D038 -:104D8000DEE16EE194E112E17FE17BE113E116E106 -:104D90003DE138E107E1E2E0C3E098E0E3E062E012 -:104DA000A9E1BFE142E00EE050E143E08EE00821DE -:104DB000A01DF7F7D7F900202071012060712B2189 -:104DC000E1702070BCE112480178002906D0203043 -:104DD000837E0E220F21002B78D0B1E100210171DA -:104DE000FF2181710021C94301810B4949684A783B -:104DF00082728A8882814988C181012141710E2293 -:104E000082700FE08C1F0020CC000020AC1F00201F -:104E10004C1F00206C1F0020C00000204C200020F0 -:104E20002C2000200F22C270017089E1A01CFFF726 -:104E3000C7FB85E1E94C2078002806D0E8480E221F -:104E4000837E0521002B41D07AE10020207101F002 -:104E50005FFFE08002F09BF8207201206071052165 -:104E6000E17020706CE1DD480078002806D0DC4855 -:104E70000E22837E2521002B28D061E160886946BF -:104E800001F018F900280FD00220D449002208713F -:104E9000084682600273CA80D0480E2181702521A5 -:104EA000C1700121417101E1009FCE4E3D46603548 -:104EB0000A370020A8713946304607F038F9A8793A -:104EC0000028F6D1C5486188C180E5E782E0C34D7E -:104ED0002878002806D0C2480E22837E3121002B7C -:104EE00078D02DE102202056042812D0002810D0BE -:104EF000011D0ED0091D0CD0091D0AD0091D08D0B6 -:104F0000091D06D00A3104D00A3102D012202871BE -:104F100003E0F9F7D7FA012068713120E870012029 -:104F200092E0A51CAD4C2078261D002806D0AC4888 -:104F30000E22837E3221002B4CD001E12946002035 -:104F400004F06FFD3070002803D12946A64807F011 -:104F5000D0F8012060713221E1702070F0E0A01CD7 -:104F6000FFF7D6FAECE09D4D2878002806D09C4843 -:104F70000E21837E3022002B73D0E1E0FDF7BCFED2 -:104F8000002803D19948007F002801D00C2003E0BD -:104F9000A078FEF74AFB00202871012068713021BB -:104FA000E9702870CCE0A01CFFF769FAC8E0A01CEB -:104FB000FFF711FAC4E0A01CFFF7CEF9C0E0874C60 -:104FC0002078002807D086480E21837E3922002BC6 -:104FD00047D0B5E099E0FDF78FFE032807D0FDF735 -:104FE0008EFE032803D08148007F002801D00C20CA -:104FF00002E07F490020C8712071012060713921D1 -:10500000E17020709CE0A01CFFF76FF998E0734DF1 -:105010002878002806D072480E22837E3821002B83 -:1050200073D08DE07148007F002805D00C202871D6 -:105030000120687138215CE0A07804F018FDA078A8 -:1050400006F02BF80020F2E7287079E06348017839 -:10505000002907D020300E22837E1146002B54D029 -:105060006EE069E0644A63499389CB86D3890B87F4 -:10507000128A4A8700210171012141710E22C270FA -:1050800001705DE0FFF7D0F85AE05448017800293C -:1050900006D02030837E0E223C21002B35D04FE0FD -:1050A00000210171012141713C22C270017047E071 -:1050B0004A4D2878002806D049480E21837E3E229A -:1050C000002B39D03CE0FDF717FE002807D1FDF793 -:1050D00016FE002803D14548007F002801D00C208F -:1050E00003E0A07804F0D2FC002028710120687150 -:1050F0003E21E970A8E73948017800290AD020301C -:10510000837E0E222421002B1AD1C2760177012141 -:10511000817615E0012101702422C2700C220271F7 -:1051200041710DE02D4D287800280BD02C480E2120 -:10513000837E3722002B03D1C1760277012181764D -:105140000120F8BD60882D4900F0B4FF002801D08F -:10515000022007E028488168084620308279012A29 -:1051600002D00C20287105E000222A71007E2872EE -:105170004888E880012068711321E9700E21A97028 -:1051800062E70020F8BD70B514491B4C03460A467F -:1051900001254032A068052B1DD21E007E443679C1 -:1051A000B619B7441518180215000122002101F0A4 -:1051B0008CFBA06800220146C0310A724A72FEF7D9 -:1051C000B7FA002803D00E490E4806F090FE70BDD5 -:1051D0001575886570BD0C490C48F6E74C1F00201A -:1051E0006C1F0020541F0020CC0000208C1F0020CA -:1051F000AC1F00201C1F0020C0000020C8000020A1 -:105200003C4101004E0800002841010081080000D7 -:105210008107C90E002808DA0007000F0838800847 -:10522000814A80008018C06904E080087F4A8000BD -:1052300080180068C8400006800F704710B504460B -:1052400000F0DBF8002813D02046FFF7E1FFC0B2E2 -:1052500000F0E1F800280DD07549E2060B78D20E77 -:1052600001209040002B08D04A681043486006E0B7 -:10527000704810BD6F48401C10BD6F490860002089 -:1052800010BD10B5044600F0B8F800280BD06849EE -:10529000E2060B78D20E01209040002B05D04A6820 -:1052A00082434A6004E0634810BD6349803108606E -:1052B000002010BD70B50D46044600F09EF8002891 -:1052C0000BD05E480068E206D20E012191400840F2 -:1052D00000D001202860002070BD564870BD10B578 -:1052E000044600F08AF8002807D0E106C90E012024 -:1052F000884052490860002010BD4E4810BD10B5CE -:10530000044600F07AF8002808D0E106C90E012012 -:1053100088404A4980310860002010BD454810BDD2 -:1053200070B50D46044600F068F8002819D02846EC -:1053300000F071F8002816D0A007C20EFF209040A0 -:10534000A907090E9140002C10DA2207120F083A23 -:105350009308354A9B009B18DA6982430A43DA6155 -:105360000CE0344870BD3348401C70BDA3082F4A80 -:105370009B009B181A6882430A431A60002070BD84 -:1053800070B50C46054600F038F8002805D02846D0 -:10539000FFF73EFF2070002070BD264870BDBFF3B0 -:1053A0004F8F21492648C860BFF34F8FFEE770B585 -:1053B0001F4C05462178012000290ED1207072B6BD -:1053C00000F0F4F81C4E803631688143616000F0D3 -:1053D000EDF8C043306062B600202870002070BD38 -:1053E00013490A78002A06D0002804D1124A4868D6 -:1053F0001060002008700020704710B50446202877 -:1054000005DA00F0D3F80121A140084201D00020C4 -:1054100010BD012010BD012803D0032801D00020B9 -:10542000704701207047000000ED00E000E400E05C -:10543000D40000200120000000E100E000E200E0D4 -:105440000400FA05F8B50446800700250126002867 -:1054500004DA5848C563C66302208443E00404D5D7 -:105460005548C563C66380148443600003D5534820 -:10547000456080058443E00504D55148C563C66393 -:1054800080158443A00404D54E48C563C663401408 -:10549000844360042704C00FF90F884203D04AA157 -:1054A000612006F024FDB80F0AD04C49CD634C486A -:1054B000C563C563CE63C663C663032080038443AC -:1054C00020050AD5474FFD632F20EBF76DFEFE63E5 -:1054D0002F20EBF769FEF8148443FBF773F9424879 -:1054E000044203D038A18D2006F001FDF8BDF0B5CF -:1054F00000210A46FF230446CC40E4072AD04CB2E0 -:10550000E606F60E0125B540384E3560384E35605A -:10551000002C11DA25072D0F083DAE08354DB600D9 -:105520007619F569A407E70E1C46BC40A54314464E -:10553000BC402543F5610DE0A6082F4DB600761955 -:105540003568A407E70E1C46BC40A5431446BC4082 -:1055500025433560491C2029CDD3F0BD70B5274CBB -:105560000D462060FFF76EFF2068FFF7C0FF28465A -:10557000ECF7D2FFFBF732F8F6F758FDFBF722F90C -:10558000F6F7F1FCECF74EFE00F06AF870BD10B5CE -:105590001A4C2068FFF756FF2068FFF7A8FFFBF7BB -:1055A00011F9EDF73EF80020206010BD13480068A7 -:1055B00070470000C01F0040C0CF004000E5014020 -:1055C000C08F0040C0DF00407372635C736F635F25 -:1055D000636F6E6669672E6300000000C0EF0040D5 -:1055E000C0FF0040C0BF0040FEFF0FFC80E100E0B4 -:1055F00080E200E000ED00E000E400E0DC000020DC -:1056000070B5002402460D4620462146002A1ED0D1 -:10561000012A04D0022A04D0032A1ED103E001206B -:1056200002E0022013E003202B0006F08EFD071697 -:105630000507090B0D0F1600012108E0022106E005 -:10564000032104E0042102E0052100E00621F7F730 -:105650001AFA002801D0204670BD0724FBE700009D -:10566000B448002101708170704770B5B24D0123BC -:105670006B60B24B1C68002CFCD0002407E00E6865 -:1056800006601E68002EFCD0001D091D641C94429B -:10569000F5D30020686018680028FCD070BD70B594 -:1056A000A44C0D466178884203D0A5A16F2006F076 -:1056B0001EFC2B0006F049FD0954062525545454C0 -:1056C000544B54002078022803D09DA1732006F08B -:1056D0000EFC03202070A078022802D0012804D0FC -:1056E00008E0A06806F02EFA04E02269E168A068EC -:1056F000FFF7BBFF0020A070F7F766F904202070C9 -:1057000070BDF7F716FA01466068F8F72BFC0546FE -:105710002078022803D08AA1872006F0E8FB8C4A73 -:105720008C498D48954205D86269032A02D2521CE1 -:10573000626103E0854208D802224A71401BC860BA -:1057400084496078F7F76AFE70BD032003E0A07813 -:105750000028FAD10220F7F743F800F0E1F870BD15 -:1057600077A1B12006F0C3FB70BD70B50546F7F711 -:10577000E0F9704C60602078012803D070A1B82057 -:1057800006F0B5FB73490220087000220A718D6093 -:1057900003224A71704ACA6020706078F7F73EFEB3 -:1057A00070BD10B5634CA078002802D12078002885 -:1057B00001D0112010BD6948F7F74CF9607060788E -:1057C000002804D0012020700020606110BD03205B -:1057D00010BD10B50124020B64040121604BA042EE -:1057E00002D29140186802E0203A5868914008407F -:1057F00000D0012010BDF8B50E46910005464F19A6 -:1058000014463F1F009106F0AEF9009980028919F5 -:10581000091FB14201D2012200E00022002C03D076 -:10582000FF2101318C4201D90920F8BD4D498D423B -:1058300019D3AF4217D3854205D2874203D22846F7 -:105840003043800701D01020F8BD8E420BD3002AD0 -:1058500009D12846FFF7BDFF002804D13846FFF7DD -:10586000B8FF002801D00F20F8BD3F483F4900682D -:10587000884205D0224631462846FFF7F6FE0FE063 -:10588000FFF78FFF0028EFD12A480121C66085600D -:10589000046181702046302148431830FFF765FFCE -:1058A0000020F8BD10B504462E48800A84420BD370 -:1058B00006F059F9A04201D8102010BDA0020446FC -:1058C000FFF787FF002801D00F2010BD2648274989 -:1058D0000068884203D0204606F034F90AE0FFF75A -:1058E00060FF0028F1D113480221846081702048B4 -:1058F000FFF73BFF002010BD1A48010B0120884034 -:10590000401E704700B50B460246FFF7F5FF1042F8 -:1059100001D00F2000BD124802604360002000BD8E -:1059200010B5044C6078F7F7E9F800202070A070FB -:1059300010BD0000E000002000E5014000E401404F -:105940007372635C736F635F666C6173682E630070 -:1059500030750000B01A0020D0FB01009F560100F6 -:105960000006004000D0010060000020BEBAFECA60 -:105970003A560000F74805218170002101704170FE -:10598000C1708160704710B5F3490A78022A07D0C8 -:10599000CA681018C860C8689638F8F79BFA10BD36 -:1059A0008A68101888608868F6E70378EB49EC4A43 -:1059B000002B02D0012B10D014E00379002B01D072 -:1059C000012B0FD14379002B01D0012B0AD1836821 -:1059D000643B8B4206D2C06810E00379002B03D0F1 -:1059E000012B01D0002070474379002B01D0012BFF -:1059F000F8D1C368643B8B42F4D280689042F1D8FE -:105A000001207047F8B504460226F7F7EFFE00685C -:105A1000002803D0D3A1BD2006F069FA0127CD4D9F -:105A2000002C08D02078002817D0012805D00228A3 -:105A300011D0032813D02F710DE06068C82808D357 -:105A4000F8F7BEFA002804D06068FFF79CFF012633 -:105A500003E0002601E000F0F9F93046F8BD2878AF -:105A60000028F8D16068FFF7A0FF0028E3D0606845 -:105A70000078002826D0A878042803D0B9A1F72000 -:105A800006F035FAB44F00203870606800790128BC -:105A900000D00020387160684079002837D003209A -:105AA000787160688168E868F7F7D5FAB86060686F -:105AB000C0689630F8600320A870A749E878F7F727 -:105AC000ADFCC8E7A4480221017061680979012989 -:105AD00019D00021017161684979002915D003218D -:105AE000417161688968963181606168C968C16087 -:105AF000C068984C14346060F7F71BF820606F7032 -:105B00000220A870A7E70321E4E70221E8E70220CA -:105B1000C6E7F8B58F4C0D46E178884204D0FF20E7 -:105B200090A1193006F0E3F928468A4F0025012696 -:105B30001437030006F009FB090612375A7C8D97CB -:105B4000C4A0C400A078032807D0A078022804D0FD -:105B5000FF2084A11D3006F0CAF9F8BDA078032803 -:105B600007D0A078022804D0FF207EA1213006F0C3 -:105B7000BEF90420A07025712078002810D1FFF70D -:105B800002FFE078F7F787FAE0607D49886A7D4A8E -:105B9000024022617B4AD24310408862002050E0DC -:105BA00000F054F9F8BDA078032807D0A0780228A7 -:105BB00004D0FF206BA1423006F099F9207800282C -:105BC00002D000F04FF9F8BDA07803281FD10420BF -:105BD0002AE0091A6048C1600146E078F7F71EFC28 -:105BE000F8BD0420F6F7FCFDA570F8BDA0780328E9 -:105BF00007D0A078022804D0FF205AA1633006F015 -:105C000076F920780028DCD1A07803280BD0F6F7AD -:105C100090FF01463868F8F7A5F90028E1DB7968BC -:105C20008142DEDBD5E70520F6F7DAFDA670F8BD88 -:105C3000A078042804D0FF204AA1843006F057F948 -:105C40000220A1688847FFF7DDFEFF260546BD3626 -:105C500042E0A078042804D0FF2042A1893006F059 -:105C600046F90120EDE7A078042899D0FF203DA156 -:105C70008E3006F03CF993E7A07804280AD06078CB -:105C8000002802D0A078022804D0FF2035A193304C -:105C900006F02DF92078002893D12079002804D02F -:105CA0000620F6F79DFD2571C0E76078002805D035 -:105CB0002949E078F7F7B2FB6570F8BD0720B3E734 -:105CC000FF2028A1AE3046E7002D0AD0012D06D0D6 -:105CD00024A1304606F00BF9022DF5D1F8BD0420C1 -:105CE00000E00320A1688847FFF78CFE0546F3E734 -:105CF00070B5050005D0174CA078052803D01120F9 -:105D000070BD102070BD2048F6F7A4FEE070E0786A -:105D1000002803D0A5600020A07070BD032070BDD6 -:105D200010B50C480178002901D0112010BD8178F0 -:105D300005292BD0817801292AD08178002927D004 -:105D4000012101708178012922D0807800281FD09C -:105D500020E00000F8000020C01A00203D8601006D -:105D6000FF1FA1077372635C736F635F7261646985 -:105D70006F5F74696D65736C6F742E630000000053 -:105D80000005004002810000135B01000F2010BDE0 -:105D900000F068F8002010BDF8B5394E0446B07820 -:105DA000002801D001280DD1002C0DD02046FFF78E -:105DB000FCFD00280AD02078324D002808D0B078A9 -:105DC000012823D00F20F8BD1020F8BD0720F8BD12 -:105DD00002272F702079012814D0002028716079C3 -:105DE000002811D003206871A0689630A860E06890 -:105DF000E860E868224C14346060F6F79AFE206090 -:105E0000B77019E00320E9E70220ECE700202870D2 -:105E10002079012816D0002028716079002813D03D -:105E200003206871A168F068F7F715F9A860E068C9 -:105E30009630E8600320B0701249F078F7F7EEFA78 -:105E40000020F8BD0320E7E70220EAE710B50E487E -:105E5000816A0E4A11400A4A126911438162F6F7BB -:105E6000B3FD10BD10B5064CE078F6F747FE0820EC -:105E7000F6F7B6FC0520A07000202070607010BD01 -:105E8000F8000020C01A002000050040FD7EFFFF42 -:105E9000F8B500245C48FAF77CFB002801D00C2000 -:105EA000F8BD5A4FC82026464643F51901462846F4 -:105EB00005F0F2FE0120B8556C80554900200870AD -:105EC000544A4A808035E9625349641C087029634A -:105ED0005249E4B208704A802964082CE2D34A4847 -:105EE000FAF76FFB0020F8BD10B54748FAF749FBF9 -:105EF000002803D04AA1212005F0F9FFFFF7C8FFD1 -:105F0000002803D046A1272005F0F1FF10BD10B5F1 -:105F100004463D48FAF73DFB002801D00C2010BD97 -:105F20003A4A0021C8204843105C00280AD0C82300 -:105F3000002059435054881820603348FAF741FB39 -:105F4000002010BD491CC9B20829EBD32E48FAF72E -:105F500038FB1F2010BD082805D2C82250432B4A09 -:105F6000135C002B01D012207047801808600020BD -:105F7000704710B504462448FAF70BFB002801D0FF -:105F80000C2010BD2088214A082804D2C82148438B -:105F9000105C002801D00020208000202188491CAE -:105FA00089B22180082900D300212180C8235943C8 -:105FB000515C00290BD0401CC0B20828EED3002051 -:105FC000C04320801048FAF7FCFA122010BD0E489A -:105FD000FAF7F7FA002010BD10B504460A48FAF7A0 -:105FE000D8FA002801D00C2010BD2078002804D059 -:105FF0000548FAF7E6FA0C2010BD0120207002488F -:10600000FAF7DFFA002010BD14010020F01F002075 -:1060100030260020FFFF0000150100205E26002032 -:106020007372635C6C6C5F64622E6D302E63000073 -:1060300010B53C48FAF7A5FA002803D03AA11E2073 -:1060400005F055FF3748FAF7A4FA002804D036A126 -:10605000242005F04CFF10BDFF211131364805F01A -:106060001BFE3549012008700020488033498871A3 -:1060700088748875324908712A48FAF7A2FA10BD67 -:1060800010B504462748FAF784FA002801D00C20FE -:1060900010BD29490878002807D000200870214841 -:1060A0002160FAF78EFA002010BD1E48FAF789FA2F -:1060B0001F2010BD70B505460C461A48FAF769FA5C -:1060C000002801D00C2070BD1B4A5088A84202D184 -:1060D0001078002804D01348FAF773FA122070BD24 -:1060E00010482260FAF76DFA002070BD10B5044622 -:1060F0000C48FAF74EFA002801D00C2010BD0E48CB -:106100000178002907D00020C04320800548FAF715 -:1061100058FA122010BD408820800248FAF751FA40 -:10612000002010BD1B0100207372635C6C6C5F6407 -:10613000622E73302E63000070200020502100205A -:106140007021002010B5282105F0A4FD10BD70B508 -:10615000054600780A0700090001120F1043287055 -:1061600007290ED2080078440079001887440305F7 -:10617000030503070300062408E00C2406E022249C -:1061800004E00024F8A1572005F0B1FE68788009EA -:1061900080012043687070BD00780007000F7047D1 -:1061A00010B5C01C05F0A5FF10BD0A4610B5C11CF6 -:1061B000104605F09EFF10BD10B5093005F099FF9F -:1061C00010BD0278BF23C9071A40490E0A43027066 -:1061D000704700784006C00F704702785206520E92 -:1061E000C9010A430270704770B50C460546C11CD0 -:1061F0002046093005F07DFF20784006400E2070D3 -:1062000029784906C90FC9010843207070BD70B5CF -:1062100015460E4604461F2A03D9D3A1A82005F02F -:1062200066FE20462A463146093005F0D6FC6078E5 -:10623000AD1D80098001A906890E0843607070BDFC -:1062400070B5054640780E468406A40E062C03D28F -:10625000C5A1B82005F04BFEA41FE4B21F2C00D945 -:106260001F24294622460931304605F0B6FC204657 -:1062700070BD70B515460E4604461F2A03D9BAA153 -:10628000CC2005F034FE20462A463146093005F080 -:10629000A4FC6078AD1D80098001A906890E084321 -:1062A000607070BD70B5044640780E468506AD0E30 -:1062B000062D03D2ACA1DD2005F019FEAD1FEDB215 -:1062C0001F2D03D9A8A1E12005F011FE21462A4681 -:1062D0000931304605F081FC284670BD0A78C2734A -:1062E0004A7802748A784274C978817470470A784F -:1062F000C2744A7802758978417570474176090AF7 -:1063000081767047C176090A017770474177090A9B -:1063100081777047C175090A0176704781757047AA -:1063200020300279C90652095201C90E0A4302718E -:10633000704720300279D206D20E49010A43027119 -:10634000704710B51F3005F0C9FE10BD41780078C8 -:106350008906890E0007000F06D0012808D0022800 -:1063600009D0062810D10AE0891F1F290AD90BE09D -:106370000C2907D008E0891F1F2903D904E0891FD1 -:106380001F2901D80120704700207047417800780C -:1063900089060007890E000F042805D1062903D3BA -:1063A000252901D8012070470020704770B401787A -:1063B0000907090F03292ED0052931D1411C827EFE -:1063C0000C46437E11021943037FC27D1D02037EEA -:1063D000C67E1B021343827D407835438006800EC3 -:1063E00022281DD106291BD31920C001814217D8AC -:1063F000FF26F436B54213D8002A11D0082A0FD848 -:106400008A420DD28B420BD8617F227F0902114351 -:10641000814208D904E040788006800E0C2802D022 -:1064200070BC0020704770BC0120704710B522215D -:1064300005F030FC10BD10B502788B079208920071 -:106440009B0F1A430270427852095201427001298F -:1064500008D0022906D0032905D0FF2042A1EE3042 -:1064600005F045FD10BD01210A43427010BD10B575 -:1064700002788B07920892009B0F1A4302704278B1 -:10648000520952014270012907D0022905D003297F -:1064900004D035A1384805F02AFD10BD01210A437A -:1064A000427010BD00788007800F70470278EF239C -:1064B000C9071A40C90E0A43027070474178C07874 -:1064C000C906C90E0E2835D202007A4412799218F4 -:1064D000974406090C0F1215181B1E2124272A2D7C -:1064E0000C2929D02AE0082926D027E0022923D028 -:1064F00024E0172920D021E00D291DD01EE001291C -:106500001AD01BE0012917D018E0022914D015E099 -:10651000092911D012E009290ED00FE001290BD072 -:106520000CE0012908D009E0062905D006E002297F -:1065300002D003E01B2901D80120704700207047DA -:1065400070B50546C1700E2926D20800784400793E -:106550000018874406131517191B1B151D1D1B1B3F -:106560001F150C241DE000007372635C756C5F7076 -:1065700064752E630000000007020000082410E08C -:1065800002240EE017240CE00D240AE0012408E0A8 -:10659000092406E0062404E000249A499A4805F0FC -:1065A000A6FC6878400940012043687070BDC0783F -:1065B0007047C171090A01727047017AC2790802F5 -:1065C000104370474172090A81727047817A427A9A -:1065D000080210437047C172090A01737047017BBA -:1065E000C27A0802104370474171090A81717047ED -:1065F0008179427908021043704701717047007930 -:1066000070474173090A81737047817B427B08029E -:106610001043704770B4017AC37909021943431CCF -:10662000857A1C46467A2B023343657926792C02FB -:106630003443C21C754E00798D1FB54215D8FF2515 -:10664000F435AB4211D800280FD008280DD8884265 -:106650000BD28C4209D8507A117A00020843B11D3E -:10666000884202D870BC0120704770BC002070477F -:1066700010B5001D05F032FD10BD0A4610B5011D14 -:10668000104605F02BFD10BD4172090A817270475A -:10669000817A427A0802104370470171704700798D -:1066A000704710B5001D05F031FD10BD0A4610B54C -:1066B000011D104605F02AFD10BD0A7802734978C5 -:1066C00041737047027B0A70407B4870704710B579 -:1066D0000E3005F01BFD10BD0A46014610B50E3107 -:1066E000104605F013FD10BD0A7882754A78C27510 -:1066F0008A780276C97841767047827D0A70C27DB9 -:106700004A70027E8A70407EC870704710B5001DC6 -:1067100005F0FCFC10BD0A4610B5011D104605F041 -:10672000F5FC10BD0A7802734A7842738A78827346 -:10673000C978C1737047027B0A70427B4A70827BC2 -:106740008A70C07BC8707047017170474171090A37 -:1067500081717047C171090A0172704700797047F1 -:1067600081794279080210437047017AC2790802A0 -:10677000104370470171704700797047017170478D -:1067800010B5001D05F0C2FC10BD0A4610B5011D74 -:10679000104605F0BBFC10BD10B5001D05F0B6FCA1 -:1067A00010BD0A4610B5011D104605F0AFFC10BD26 -:1067B00070B515460E4604461B2A03D911491448E4 -:1067C00005F095FB2A463146E01C05F006FA607894 -:1067D000E90640094001C90E0843607070BD70B5FC -:1067E000054640780E46C406E40E1B2C03D9054925 -:1067F000084805F07CFB2246E91C304605F0EDF91F -:10680000204670BD68650100A70200007A0C0000F8 -:10681000F70300000304000070B504460020A083C5 -:10682000208C1E4648431546114605F04DFA20843B -:10683000F000294605F03AFA401C80B201461922C0 -:1068400069439202E083914201DD401EE0837D2096 -:106850002946000205F02AFA401CA08470BD70B5DC -:106860000A7BD206D20E0A73002282758B181B7A1D -:10687000DC075B08DD07E40FED0F2C195B08DD0773 -:10688000ED0F2C195B08DD07ED0F2C195B08DD07F8 -:10689000ED0F2D195C08E307DB0F5B196508EC07AA -:1068A000E40FE4186B081B1984186374847D521C70 -:1068B000E318D2B28375052AD8D3D8B2252803D9D4 -:1068C000E2A18A2005F013FB70BDF8B50446174617 -:1068D0000E46254622462346214600203035C0324A -:1068E000A0338031032E0AD0002E37D0012E3ED0A7 -:1068F000022E03D1A11C2846FFF7B1FFF8BD288066 -:10690000A871E871E87228736873A873A870E870BA -:10691000287168716876A8832E4668842036B07125 -:106920002885B072E8752876E8732874F0723073A1 -:10693000B07337752884FF276035AF70B075088352 -:1069400048838883C883088448845871C88518732D -:1069500026210855A08410701071F8BDC885987163 -:10696000A18823890A462846FFF756FFC2E7C88553 -:10697000938A128AA1882846FFF74EFFF8BD70B5AA -:106980000446034630348033054603290AD00029E3 -:1069900034D0012939D0022903D1A91C2046FFF7A0 -:1069A0005EFF70BD00202080A071E071E072207356 -:1069B0006073A073A070E070207160716076A08336 -:1069C000214660842031887120858872E0752076A8 -:1069D000E0732074C872087388730A752084FF22DC -:1069E0006034A270887529461884A03188701876A2 -:1069F0002035D861A8710871087570BDA9882B89E8 -:106A00000A462046FFF708FFC7E7D86AA988C38966 -:106A100042892046FFF700FF70BD70B5867D0D46A8 -:106A20000446002E01D0252E01D9122070BD002A67 -:106A300018D0287EE17D50430818252105F036F94D -:106A4000E1750846CA084907490F844BAA18595CE2 -:106A5000127A914308D0314605F028F9491CCAB290 -:106A600000200AE0002070BD2076002070BD0028C4 -:106A700003D02118097C511ACAB22118497C9142CD -:106A80003AD32918097AC943CB07DB17D21A521E09 -:106A90001206120E35D08B07DB17D21A521E1206C1 -:106AA000120E32D04B07DB17D21A521E1206120EEC -:106AB00030D00B07DB17D21A521E1206120E2ED040 -:106AC000CB06DB17D21A521E1206120E2CD08B06E2 -:106AD000DB17D21A521E1206120E2AD04B06DB17F3 -:106AE000D21A521E1206120E28D00906C917511AC0 -:106AF000491E0A06120E26D0401C0528B7DB1F20AF -:106B000070BDC0002076002070BDC000401C207603 -:106B1000002070BDC000801C2076002070BDC00029 -:106B2000C01C2076002070BDC000001D2076002013 -:106B300070BDC000401D2076002070BDC000801DCB -:106B40002076002070BDC000C01D2076002070BDE2 -:106B500070B50D460446072904D9FF203BA15B30E0 -:106B600005F0C5F9E078502108406907490F8830E1 -:106B70000843E070A078A72108401830A070607822 -:106B80005E210840203060702078BC2108404030F1 -:106B9000207070BD0179490901D0002070470022A2 -:106BA00030B41146445C491CE3076408E507DB0F79 -:106BB000ED0FEB186408E507ED0FEB186408E50727 -:106BC000ED0FEB186408E507ED0FEB186408E50717 -:106BD000ED0FEB186408E507ED0FA407EB18E40FC1 -:106BE000E318D218D2B20529DCDB002A02D030BC6F -:106BF0000120704730BC0020704738B505460C4670 -:106C00006846F7F73FFE00281ED069460020085668 -:106C10002072092161560022411A00D549422035CF -:106C20006B798B420FDCFF2B0DD0A17A491CC9B2C6 -:106C3000A172AB79994202D8617A7F2903D160723F -:106C40000020A0720122104638BD00007372635C00 -:106C50006C6C5F7574696C2E63000000F2C10100FA -:106C6000F8B5F94F0024BC70FF20F84DF870287873 -:106C7000264600281CD9C0B2864204D3FF20F4A1C6 -:106C8000C03005F034F9F000811BF4480818047096 -:106C900044708470C470F978B14202D1BC70FF2195 -:106CA000F97004714471761C2878F6B28642E2D3FA -:106CB00029780020002908D9E84AC3001B1A9B182C -:106CC0009C71401CC0B28842F7D3E548FFF7AEFB89 -:106CD0000021E348FFF7EAFB0121E148FFF7ABFBA6 -:106CE000FF20E87028716871A871E8712872F8BDFA -:106CF000D6490122002805D00820087002204870DB -:106D00008A7004E00A700F20487006208870A7E798 -:106D10001B20704710B4CD4A00211378CF4A002BB6 -:106D200009D9CC00641AA418A479002C03D0491CFA -:106D3000C9B29942F5D3994208D2CC000123641A12 -:106D4000A2189371017010BC1846704710BC002047 -:106D5000704710B4BD4900230978884217D2C20099 -:106D6000BE49121A51188A79002A10D00B704B7044 -:106D70008B70CB70B44AD478844202D19370FF20D8 -:106D8000D0700B714B718B7110BC0120704710BC1F -:106D900000207047AD490A78904209D2C3001A1A00 -:106DA000AE4BD2189279002A02D0087201207047A7 -:106DB0000020704770B4A54BA84D197A82B0CA0064 -:106DC000541A2E5D6A461670621954786A46147118 -:106DD0005A78514322225143A24A8B186A461478AA -:106DE0001179614080290AD0117822224906490E82 -:106DF0005143C918016002B070BC0120704702B055 -:106E000070BC00207047914981B0087AC200121A04 -:106E10009248101843786A461370497803781278BC -:106E20005A40802A0ED003786A46137012785206B0 -:106E3000520E521C8A4208D26A461178491CC9B2C5 -:106E4000117009E0002001B0704769460978090611 -:106E500001D5002100E080210170012001B07047C0 -:106E60007A490A78904209D2C3001A1A7B4BD21889 -:106E70009279002A02D0C871012070470020704723 -:106E800070B4724B754CD97982B0CA00551A665DE0 -:106E90006A4616712A1954786A4614705A78514312 -:106EA000222251436F4A8B186A4611781279914217 -:106EB0000BD06946097822224906490E5143C91868 -:106EC000016002B070BC0120704702B070BC0020AD -:106ED000704738B55D4AD079C100091A5F48445CF3 -:106EE0006B461C70081852784478411C1B789C42F1 -:106EF00024D00C786B461C701B785B065B0E5B1C09 -:106F0000934205D26B461A78521CD2B21A7006E030 -:106F10006A461278120601D5002200E080220A702B -:106F20008178491C81708178C078814204D19F208A -:106F300047A1800004F0DBFF012038BD002038BDF0 -:106F40004248C079C100091A44480A185278405C86 -:106F5000824201D101207047002070473B48C1792F -:106F6000CA00531A3D4AD15C9A18527840781346A9 -:106F70004B40802B0AD049065206490E520E9142D0 -:106F800001D3881A01E0511A401AC0B270472F4845 -:106F9000407870472D4A1378002298420ED2C300E1 -:106FA0001B1A2E4818188379002B07D00A70827894 -:106FB000C378D31A0B70C27001207047002070474D -:106FC000224A127890420CD2C200121A234810189A -:106FD0008279002A05D08278C078101A08700120C2 -:106FE0007047002070471E490160704717490A78B2 -:106FF000904209D2C3001A1A184BD2189279002A6B -:1070000002D0C87001207047002070470E49CA782E -:10701000FF2A03D000210160084670478A78124990 -:10702000012A02D0016001207047002070470F48FC -:10703000017801291CD0012101700448C17802485F -:10704000C170012070470000F01A00201C010020D0 -:107050007372635C646D5F712E630000F41A00202C -:107060005C1E00202C1B0020D01A0020F21A0020E9 -:107070000020E7E796490A78904209D2C3001A1A1D -:10708000944BD2189279002A02D0087101207047DF -:107090000020704790498E4BCA781B799A4206D1DE -:1070A0008A788E49002A02D00160012070470020B2 -:1070B00070478948864AC1781279914209D1FF21E7 -:1070C000C17087480178002903D000210170012098 -:1070D00070470020704780487D4AC17812799142FC -:1070E00004D18078002801D000207047012070472B -:1070F00077490A78904209D2C3001A1A754BD21800 -:107100009279002A02D088710120704700207047D0 -:1071100030B46F4982B08A79D3009C1A6D4BE41861 -:1071200025796B461D7064791C710B784C788978D1 -:1071300063434A439918222251436A4A6B461C789A -:107140008A181979614080290AD0197822234906C2 -:10715000490E59438918016002B030BC01207047C4 -:1071600002B030BC00207047594981B08879C20014 -:10717000121A584812185379101D6A4613708978EC -:10718000037812785A40802A0ED003786A4613702A -:1071900012785206520E521C8A4208D26A46117860 -:1071A000491CC9B2117009E0002001B0704769465E -:1071B0000978090601D5002100E080210170012035 -:1071C00001B0704742488079C100091A4148091846 -:1071D00048790979884201D1012070470020704721 -:1071E0003B490A78904209D2C3001A1A394BD21887 -:1071F0009279002A02D04871012070470020704720 -:1072000030B4334982B04A79D3009C1A314BE41828 -:1072100025796B461D7164791C700B784C788978E0 -:1072200063434A439918222251432E4A6B468918D8 -:107230001A781B799A420BD06A461278222352069A -:10724000520E5A435118016002B030BC0120704701 -:1072500002B030BC002070471D4981B04879C2009F -:10726000121A1C48101803796A46137089784379FA -:107270001278401D934219D003786A461370127831 -:107280005206520E521C8A4205D26A461178491C97 -:10729000C9B2117006E069460978090601D50021D6 -:1072A00000E080210170012001B07047002001B092 -:1072B000704707484079C100091A064809184879FB -:1072C0000979884201D101207047002070470000F1 -:1072D0001C010020F41A0020F01A0020D01A00200F -:1072E000F21A00202C1B0020F8B5FF4E04467078DF -:1072F00001270025FD49002802D0012806D009E019 -:10730000FB48407A002805D0777003E0887F00288A -:1073100000D07570F748027D002A09D065701021F1 -:107320002170417DA170817DE17005750120F8BD5E -:1073300070782B2250434018827F002A10D00146DB -:107340002A221F31A01C04F048FC65700420207024 -:10735000A77070782B214843E4494018857711E0E5 -:107360000878012801D00020F8BD65701320207036 -:107370000E461C22891CA01C04F02FFCA571357040 -:10738000DD48C5760120F8BDF8B5D84E0746B07F78 -:1073900000282DD13846FEF7FFFE00210125D74CED -:1073A000072824D202007A441279921897440305E0 -:1073B000081F1F1F0A00217006E02570217208E0D7 -:1073C000032000E002202070CD493846FEF738FF48 -:1073D00020723846FEF7FDFE6070CA493846FEF757 -:1073E000E4FEC14CC84F20787F2807D101E021720C -:1073F000F8BDFF20C5A14F3004F079FD207838702A -:107400007F202070B5770320FBF74CFBF8BD10B54B -:107410000020FBF7CCFA002812D0F7F7B1F90021D1 -:107420000120F7F7B3F8BE48F7F7C1F9BD4C606C1F -:10743000F7F7C0F9207D032805D0022803D006E025 -:1074400000F0FFFD10BD01210020F7F72BFAF7F740 -:1074500010FAA94C607F002803D0F7F76EFDF7F70C -:10746000EEF90320E07710BD10B5AF4C002861891C -:1074700008D0FF290DD24804000C6081FF2808D9EC -:10748000FF2005E0012904D94808608101D10120CD -:10749000608195484168012901D0002901D10D2161 -:1074A0004160C94317225143627A3B23D2435A4376 -:1074B0008A1842606189900C04F0F8FB617210BD7B -:1074C000984A0023D3775062D1778B480121017607 -:1074D0007047894A00231370924B98621170012003 -:1074E00010767047F8B5844CE07F022804D0E07F26 -:1074F000012801D00C20F8BD00207C4A05462B2134 -:10750000414389188D77401CC0B20228F7D315700B -:10751000784E3575607F002804D0F7F798F9F7F7B3 -:107520001DFD65776576A576E5767E4F257701208A -:10753000F8733D75A57738737873B8737B497C48C9 -:1075400004F0FCFDF07FF877387820703846011D94 -:107550004EC9074624374EC741694163257600204E -:10756000F8BD10B564480021C1776F4A1170012140 -:10757000C177FFF7B7FF002803D064A16D4804F07E -:10758000B6FC10BDF1B586B00C205B4C0490E07FDA -:10759000012805D0E07F022802D00C2007B0F0BD02 -:1075A000F7F7F5F80020F6F7B4FE504D207E2E4692 -:1075B00060368035002838D05C485D49009004F082 -:1075C000BDFDE87FF07720782870284601462431F9 -:1075D0008EC9001D8EC0016A002701606776A776FC -:1075E000287B002805D1687B002802D1A87B0028D1 -:1075F00019D0207F002816D0287D032802D0022829 -:1076000005D008E005214C4800F039FD03E00321D6 -:10761000494800F034FDB17F0098F6F7F2FE0020F3 -:10762000049027760AE0277602E0E07F022803D064 -:10763000E07F022824D008E000200490E07F0128A9 -:1076400003D1394908720220E077F07F002803D087 -:10765000F17F6868F6F718FF2878002806D02978A7 -:10766000364AA868F7F759FC0120607706986864E5 -:107670003348F7F71BF8F7F795F8049807B0F0BD13 -:107680000120E0770C2007B0F0BDF8B5F7F77FF8E0 -:10769000194CE07F022803D0F7F784F80C20F8BDDE -:1076A000214E0120707270810220F7F76DF8254895 -:1076B000F6F73FFF244F0025A07F0321401C04F074 -:1076C000F5FAA177C85D012848D06D1CEDB2032DF5 -:1076D000F2D3FFF79CFE307800283DD001283BD044 -:1076E000022841D0032831E0280100207026002024 -:1076F000B0260020D0260020102700209026002051 -:107700009926002092260020B82600207372635C20 -:107710006C6C5F64645F7363616E2E6300000000D5 -:107720003C270020F026002030270020E8260020FB -:10773000082700205B030000642700203F2700206B -:10774000FAC1010000C20100FC2600200CD0FD207F -:10775000F849800004F0CBFB0020F8BDC8B2F64920 -:10776000085CF6F7F8FEB4E7EBF752FCF4E770B507 -:10777000F24C0125A576E37E002B01D03A2070BDA6 -:10778000EF4B0026002802D1987F884208D19977D4 -:1077900066761146EB4804F0ACFC657625772576D5 -:1077A000A676002070BD024600200123E349002A8E -:1077B00003D0012A03D012207047CB7300E0C873B6 -:1077C0000B764A757047032801D1DD4A1163DB4906 -:1077D00008750120087600207047DB49012803D096 -:1077E000032801D0002000E001200870704710B588 -:1077F000F7F719F8F7F70CF8F6F716FFF6F7BAFFF0 -:10780000CE4C607F002805D0F7F721F8F7F7A6FBEC -:1078100000206077CC48012101720220E077F6F762 -:10782000C1FF002010BD10B500F00BFC10BDF0B57D -:10783000C74C83B02146C031C44EA034009100280B -:1078400010D0C448FEF782FD002804D1C148FEF7DD -:107850009DFD002806D0BA4D287D03280DD1A07EBD -:1078600000280AD0E07F052869D20100794409790F -:1078700049188F44646464F3F200E07F052878D2ED -:1078800001007944097949188F4473737302EA003F -:10789000B048FEF781FCAD498870E87B002803D131 -:1078A000F6F744FE002800D001200190607F0028F8 -:1078B00013D00526761EF6B2F7F771FB07460228AD -:1078C00005D1002EF6D19B49A34804F010FB019886 -:1078D000002810D1012F0ED001909C4F9F4EB878F8 -:1078E000072870D201007944097949188F446CFD4A -:1078F000056B6B6B28000120EEE7607F002803D04A -:10790000F6F7A5FFF7F72AFB9048F6F7BBFF00282C -:1079100001D17F203870F6F7A3FF019800280AD024 -:10792000287D012801D0022805D1F6F77DFE89487F -:10793000FFF72AFD2EE2F6F777FEFFF768FD2BE250 -:10794000607F002803D0F6F782FFF7F707FB7F4838 -:10795000F6F798FF002801D17F203870F6F780FFF6 -:107960000198002877D0287D022803D0012878D0FC -:1079700041E218E27748FFF707FD0120FBF717F80F -:1079800000286CD076497348FEF72EFC7448F6F751 -:107990000EFF607E00280DD06948018B3180418B3D -:1079A0007180808BB08031466D48FEF7F9FB002076 -:1079B0006076A07601210846F6F774FFF6F714FF0B -:1079C0000520E077E8E14DE1607F002803D0F6F77D -:1079D0003EFFF7F7C3FA5D48F6F754FF002801D1E0 -:1079E0007F203870F6F73CFF0198002833D0287DBF -:1079F000022808D0012834D0032836D04D495948F0 -:107A000004F075FAC8E15348FFF7BEFC0120FAF70D -:107A1000CEFF002823D052494E48FEF7E5FB5048E0 -:107A2000F6F7C5FE607E00280DD04548018B3180F9 -:107A3000418B7180808BB08031464948FEF7B0FBA6 -:107A400000206076A07601210846F6F72BFFF6F7B6 -:107A5000CBFE0520F5E018E103E0B9E1A7E1B3E0D2 -:107A600017E13C48FFF790FC94E13A482969C27855 -:107A70004B7F9A421DD102798B7F9A4219D142796C -:107A8000CB7F9A4215D10A46203283791778BB42C0 -:107A90000FD1C3795778BB420BD1037A92789342C6 -:107AA00007D100780A7F4006C00F904201D1012023 -:107AB00000E000206A7D012A2FD0002800D13AE79B -:107AC0000220FAF774FF00287ED00120FAF7EAFFBF -:107AD00023492048FEF788FB2869018B2048FEF7E0 -:107AE00019FC2869817D1E4800E03DE0FEF716FC88 -:107AF0001B48F6F75CFE607E002866D01048018BBC -:107B00003180418B7180808BB08031461448FEF704 -:107B100047FB00206076A07690E00028D0D10D4889 -:107B20001D31FEF742FB0B48FEF753FB296908772E -:107B3000C6E700000C770100FDC1010010270020FE -:107B4000F0260020082700203027002028010020F0 -:107B5000702600203C270020CE040000E8260020EC -:107B600064270020C6050000607F002803D0F6F7D8 -:107B70006EFEF7F7F3F9FA48F6F784FE002801D114 -:107B80007F203870F6F76CFE019800287DD0F6F75C -:107B900041FC002879D0287D0328F24804D0FFF763 -:107BA000F3FBF6F741FDF5E02969C2784B7F9A4275 -:107BB00020D102798B7F9A421CD14279CB7F9A42A5 -:107BC00018D183790A4601E049E037E0203217787E -:107BD000BB420FD1C3795778BB420BD1037A92785D -:107BE000934207D100780A7F4006C00F904201D12E -:107BF000012000E000206A7D012A24D0002800D165 -:107C000099E60220FAF7D3FE002828D00120FAF7DF -:107C100049FFD549D348FEF7E7FA2869018BD248D6 -:107C2000FEF778FB2869817DCF48FEF777FBCE48C9 -:107C3000F6F7BDFD607E002800D05FE70120E0760A -:107C40000620E077A8E00028DBD1C6481D31FEF70A -:107C5000ACFAC448FEF7BDFA29690877D1E700F00D -:107C6000F0F999E0607F002803D0F6F7F0FDF7F710 -:107C700075F9BB48F6F706FE002801D17F20387061 -:107C8000F6F7EEFDF6F7D0FC00E0B4E0FFF7BFFB3F -:107C900082E0B448FEF780FAB070B248B249C278C8 -:107CA0004B7A9A421CD102798B7A9A4218D1427946 -:107CB000CB7A9A4214D182790B7B9A4210D1C27945 -:107CC0004B7B9A420CD1027A8B7B9A4208D1007886 -:107CD00009784006C00FC909884201D1012500E09A -:107CE0000025F6F7A1FCB078042840D1002D3ED045 -:107CF0009B48F6F7C7FD002801D17F203070F6F7CA -:107D0000AFFD0098007A002802D00020FFF7ACFBFE -:107D100000990120954D0872924F687A002839D158 -:107D20000420E8723846FEF754FA002801D00128F2 -:107D300000D128738E493846FEF737FA8D49384608 -:107D4000FEF7B0FAE8741F2801D91F20E8743078D4 -:107D5000894F7F2804D1FF2088494F3004F0C7F8AD -:107D6000307838707F2030700120687212E07C48D3 -:107D7000F6F788FD002801D17F203070F6F770FDFE -:107D80000098007A002802D10120FFF76DFB0099CE -:107D900000200872FFF73BFBE07F022840D0E07F25 -:107DA00004282FD12AE0D3207449C00028E6607F40 -:107DB000002803D0F6F74BFDF7F7D0F86848F6F740 -:107DC00061FD002801D17F203070F6F749FD12E0F7 -:107DD0006348F6F757FD002801D17F203070F6F791 -:107DE0003FFD0098007A002802D10120FFF73CFBFC -:107DF000009900200872F6F717FCCBE75F4960484E -:107E000004F075F800980078002809D001280ED0F9 -:107E1000022807D0032810D058495A4804F067F8C0 -:107E200003B0F0BDE07F032807D003B0F0BDE07FD2 -:107E3000062802D0E07F0528F7D10120F6F7E7FDFC -:107E400003B0F0BDF8B5504DE87F504F072867D21A -:107E500001007944097949188F44626262626203C1 -:107E60000B004048F6F7A3FCF6F703FD0420E87783 -:107E70005AE0F6F7D8FCF6F7CBFCF6F7D5FBF6F7A9 -:107E800079FC012038720220E877F6F78BFC404C31 -:107E9000217800203F4E01292CD0A0703E48009050 -:107EA00001694888A080087FE0713C481D3104F0DA -:107EB00020F9009800698188E182C18821830189C5 -:107EC0006183C07E2077B07FA0733549354804F0C8 -:107ED00010F9687F002803D0F7F761F8012812D065 -:107EE000607F400840006077012020700220FAF790 -:107EF000D9FD19E0317D0029F8D113217175B075D4 -:107F000001203075F2E7607F012108436077F7F7C1 -:107F10005FF8617F4000C907C90F01436177E3E75C -:107F20001649214803F0E3FFE87F022816D0E87FD6 -:107F3000032806D0E87F042803D010491B4803F02B -:107F4000D6FF3878002809D0012807D0022831D080 -:107F500003282FD00949164803F0C9FFF8BD0000D7 -:107F6000280100203C27002064270020B0260020A4 -:107F7000BD260020C4260020E32600200C77010047 -:107F8000DA060000EF06000010270020302700204E -:107F900070260020D0260020F02600207826002021 -:107FA000E82600207F260020540700005A07000022 -:107FB000660700000120F6F72AFDF8BD70B55D4C9C -:107FC000E07F5D4D052820D20100794409794918E8 -:107FD0008F441B1B1B1902005848F6F753FC00285E -:107FE00002D156497F200870F6F73AFC287A00281B -:107FF00002D10120FFF738FA00202872F6F714FBAF -:10800000FFF705FA01E000F01CF8E07F022813D02A -:10801000E07F032803D04A494A4803F068FF2878E4 -:10802000002809D0012807D0022806D0032804D050 -:108030004349454803F05BFF70BD0120F6F7E7FCBC -:1080400070BD10B5F6F7EFFBF6F7E2FBF6F7ECFACA -:10805000F6F790FB374C607F002805D0F6F7F7FB6A -:10806000F6F77CFF0020607733480121017202207F -:10807000E077F6F797FB0020FAF714FD10BD70B516 -:10808000324C0546264660367834032943D005290C -:1080900040D1FEF757F805212846FEF758F8B17F82 -:1080A0002846FEF78EF821462846FEF779F8284C38 -:1080B000284621690F31FEF711F92169284613314D -:1080C000FEF715F92069817D2846FEF727F920691A -:1080D000018B2846FEF71EF9206981882846FEF7A5 -:1080E0000DF92069C1882846FEF70CF9206901893D -:1080F0002846FEF70BF9216928460A31FEF721F9D7 -:108100002069817E2846FEF70BF92069C17E28464A -:10811000FEF70FF970BDFEF715F803212846FEF7AC -:1081200016F8B17F2846FEF74CF821462846FEF7A0 -:1081300037F870BD102700203027002028010020CC -:108140000C7701009D070000A907000070260020A1 -:10815000F0260020F8B5FEF701FF0446FEF7BBFF4E -:10816000F94E0546F0682030407D002826D00128D1 -:1081700067D0022869D0032871D0FF20F3A177309F -:1081800003F0B5FE3069F722017811400170F26802 -:108190002032937DDB071B0F1943FB23194001702D -:1081A000D37DDB075B0F19430170577DEF23022F4F -:1081B00060D0012F63D0032F65D06AE0E748FEF757 -:1081C00069FF002827D030690090F168088EC988BF -:1081D0004018801D87B20098FEF7E9F9012805D004 -:1081E0000098FEF7E4F9002808D00FE0F06839465F -:1081F0008030C7860098FEF747FA07E0F0683946F6 -:108200008030C06A87800098FEF7FBF9F168032090 -:1082100020314875B6E7D148FEF732FE002804D079 -:10822000F0685B21095C002907D0CC48FEF7DBFE33 -:10823000F168012020314875A4E702212030417502 -:10824000A0E7C648FEF7CFFE9CE7C448FEF718FE3D -:10825000002897D1FF20BDA1693008E0FFE7BF48A3 -:10826000FEF718FF00288DD1FF20B8A1713003F070 -:108270003EFE87E7012C08D8002D06D009E06D1ED0 -:108280002C4302D105E0002C03D0194010231943E0 -:1082900000E019400170D17F002915D0517D0129DE -:1082A00012D0AF48F6F783FAAE4801210176F268A2 -:1082B000916ED26E42610161A9493269F6F7B9FD4A -:1082C0000020F6F7C5FD03E0F6F771FAF6F7E3FDD7 -:1082D00001210846F6F7E6FA03203070F8BD0828B9 -:1082E0002FD203007B441B79DB189F4403060B0E3F -:1082F00011152528002926D023E0022923D003299F -:1083000021D01EE007291ED01BE008291BD018E051 -:108310000A390C2917D914E00D2914D00C2912D0D0 -:10832000002A04D00D290CD316290CD909E01129F3 -:1083300007D3162907D904E0092904D001E001294F -:1083400001D0002070470120704730B5054683B04A -:108350008248FEF75BFE002803D17CA1824803F02F -:10836000C6FD794C2069FEF761F803212069FEF70C -:108370007EF82069EF220178114001702946FEF74E -:10838000DFF80D2D76D22800784400790018874454 -:108390001F1606448080840E7280848460006A48C0 -:1083A000C1680069A0314979FEF777F975E0664840 -:1083B000C16800698031497CFEF7E0F96DE06248F0 -:1083C000C16800698031096B491CFEF751F964E00E -:1083D0005D4CE0688030C06A81792069FEF70DF954 -:1083E000E0688030C06A01892069FEF7FDF8E06826 -:1083F0008030C06A41892069FEF7DBF8E068803090 -:10840000C06A81892069FEF7DDF8E0688030C06AC3 -:10841000C1892069FEF7DFF83FE04B4CE06880300F -:10842000C16A2069091DFEF73CF9E0688030C16A25 -:1084300020690C31FEF741F9E0688030C16A20699B -:108440001E31FEF744F9E16820698831FEF74CF9E6 -:1084500023E03D4CA06941782069FEF775F9A069D9 -:1084600081882069FEF772F9A06941882069FEF7CA -:1084700071F912E00DE00020009069460190087843 -:1084800001210843694608702F480069FEF778F912 -:1084900003E02EA1354803F02AFDFEF7C8FD0028B1 -:1084A00003D12AA1324803F022FD0C2D0ED0072D56 -:1084B0000ED0012D0AD0002D08D0022D06D0224862 -:1084C0000021C068403041820121817503B030BD78 -:1084D0001D480021C0684030018303B030BDF8B5AD -:1084E000F6F7A1F9F6F794F9F6F79EF8F6F742F9E0 -:1084F000F6F7D1FCF6F756F9134CE0682030807996 -:10850000012801D1F6F7ACF9E068012502462032D6 -:10851000917F002908D1E178CB0701D1890703D5E4 -:1085200095770121FAF76EFAA079002803D100F0BF -:10853000F7FD00F015FCE0780026C0070028E06891 -:1085400018D04030868119E0300100207372635CDE -:108550006C6C5F6D61737465722E63004001002066 -:10856000B2270020D827002065060000A9060000D9 -:10857000AF06000040308189491C8181E068A42158 -:10858000095C002908D15C210A5C2030417F012070 -:10859000FFF7A5FE002804D0E0684030018A491C9E -:1085A0000182A0793D21002804D0E068403081722A -:1085B00045725BE0E07902280AD001280AD0607990 -:1085C00000281BD0420701D4C2060AD51E21ECE7C1 -:1085D0001621EAE7E068A621095C40308172457205 -:1085E00044E00207E1D4C10706D1800704D4232068 -:1085F000F5A1000103F07BFC2A21D6E7E0680246E2 -:108600004032917D002905D0518A4B1C5382938AB8 -:10861000994213D2917E002905D0138B591C1183E6 -:10862000918A8B420AD2118AD389994203D3A42713 -:108630003F5C002F02D1978AB94203D32220907267 -:10864000557213E03E21095C0029918905D09942B9 -:1086500009D308209072557208E0062903D33E2002 -:108660009072557202E0517A00290AD0E068014602 -:108670002031CE760E778E7749210D542570022158 -:1086800001E025700021FAF7BDF9F8BDF8B5044600 -:10869000D148FDF76EFC00286FD1D04E6946708935 -:1086A000FDF759FC002803D0C7A1CD4803F01FFCFB -:1086B000009800258030016C0978072920D0A21C81 -:1086C0000C292CD00B2936D0062942D07789009866 -:1086D0000146A0310A7E002A50D065701222227015 -:1086E000009AA032127E002A08D0A2300D76028BAA -:1086F0006280428BA2800A7E002AF7D10120F8BD59 -:10870000657007212170016C0A22A01C091D03F06D -:1087100064FA00988030006C05700120F8BD657027 -:108720000C212170016C8A886280C988A180006C4C -:1087300005700120F8BD65700B212170016C8B88DC -:108740001380CB88538009899180006C05700120CB -:10875000F8BD657006212170016C8B881380CB8871 -:1087600053800B8993804B89D3808B891381CB896C -:108770005381006C05700120F8BD15E09648FDF7A7 -:10878000F8FB002803D090A1964803F0B0FB69469F -:108790007089FDF7E0FB002803D08BA1924803F01D -:1087A000A6FB7089B84292D10020F8BD8B480078B2 -:1087B000012801D00C2070470020704770B5874C0D -:1087C00005462078002803D07FA1884803F08FFB5E -:1087D0000020A5612072012020702078012803D09C -:1087E00079A1834803F083FB70BDF8B57B4C2178F9 -:1087F000012901D00C20F8BDE0608030807CFEF7BC -:108800002FFB00283AD0E0688030807CFEF770FCB7 -:10881000002833D0E0688030807CFEF7E7FB00283A -:108820002CD0E0688030807CFEF724FC002825D026 -:10883000F5F7ADFF0026A6710120F5F76AFDE068A7 -:10884000014640318A7D002A03D04A8A8B8A9A42A7 -:1088500011D28A7E002A03D00A8B8B8A9A420AD2CE -:108860000B8ACA89934206D23E231B5C8989002B5E -:1088700006D0914206D30120A0703EE01220F8BD40 -:108880000629F8D2A6701330F5F710FFE0680F3014 -:10889000F5F74FFE0320F5F777FFE5684020405DD0 -:1088A000002803D13F20405D00280CD02F467837A8 -:1088B0005048A96FBB68EA6FFF688EC029464E48D2 -:1088C000883103F023FCA020405BA91C401C82B22D -:1088D00028463030FEF7A1F8002803D03AA14748D7 -:1088E00003F005FBE0684030007AF5F734FEF5F759 -:1088F00047FF01210020F5F749FEE67026716671F9 -:10890000E67102202070E06880300684F5F74AFFA7 -:108910000020F8BD10B5F5F73AFF304C207802285A -:1089200003D0F5F73FFF0C2010BDA078002802D03F -:10893000FFF7D5FD17E0F5F757FFFFF70BFCE068F1 -:1089400020308079012801D1F5F793FF207A0028A3 -:1089500009D0012809D0022805D0032805D01AA182 -:10896000274803F0C4FA002010BDEAF751FBFAE7EC -:1089700070B5044601468031088C2546401C0884A9 -:108980004035A889401CA881A87D002802D0688AAB -:10899000401C6882A87E002802D0288B401C2883B7 -:1089A000A420005D002807D13D20015D2A7F012021 -:1089B000FFF795FC002802D0288A401C2882204618 -:1089C00000F046FB002070BD7372635C6C6C5F6DE1 -:1089D00061737465722E63003A010020300100203B -:1089E00084070000CD070000D1070000EB0700005E -:1089F000F7070000D8270020F127002036080000E4 -:108A000076080000F94908727047F84A1162D0618F -:108A10007047F8B5F54C2078032803D0F449F548A1 -:108A200003F065FAE06804262030817C00250029E7 -:108A300003D0857421793143217121690127097897 -:108A4000C9438907002907D1C17C002904D1C77413 -:108A500021790222114321712179490702D5407FF2 -:108A6000022802D06079002802D0FFF738FD2AE002 -:108A7000E148FEF74DFB002801D0657002E0677009 -:108A8000DE486061E06840300078002811D0DC48A2 -:108A9000F5F78DFEDB480576E268116F526F426193 -:108AA0000161D74A6169F6F7C4F90120F6F7D0F9F8 -:108AB00004E06069F5F77BFEF6F7EDF9022100208E -:108AC000F5F7F0FE2670207801280CD0207A0028D7 -:108AD00009D0012807D0022806D0032804D0C449B1 -:108AE000C94803F004FAF8BD0120F5F790FFF8BD7E -:108AF000F8B5BE4C05462078042803D0BC49C348CD -:108B000003F0F5F9002D7DD0F6F7DDF96178012548 -:108B10000843002813D1E0684021095C00290ED0E9 -:108B200061694A78D2060AD0097820300907C07DE9 -:108B3000C90F814203D1A571FFF7D1FC8CE0E06839 -:108B400020308079012811D1F5F78AFEE168881C70 -:108B50003031FEF752F8002808D0E068BA21428888 -:108B60000A523921095CA030017705766069002638 -:108B700000784007C10FE0682030827D914236D0F6 -:108B8000407D002833D0022810D1FEF7A2F900283A -:108B900004D12F209649400103F0A9F9E26800238F -:108BA000906ED16E401C5941D1669066E0682030CD -:108BB0004675C17C012914D1C67420790821084367 -:108BC0002071FEF776FA002803D18949904803F016 -:108BD0008EF9E2680023906ED16E401C5941D16637 -:108BE0009066E0682030817D012946D085756069F6 -:108BF00001788C460907CF0FE1680A462031CB7D0A -:108C00009F4200E087E00CD16746BF07BF0F012FEE -:108C10004BD0022F49D0032F31D060790421084373 -:108C20006071E0782843E07020690078C00604D4C1 -:108C300060690078C00600D47EE720790028FBD167 -:108C400060780028F8D1F9F7D2FE0028F4D06079D6 -:108C50000028F1D1FFF77EFA207801280CD0207A85 -:108C6000002809D001285BD0022805D0032857D05E -:108C70005F49684803F03BF9F8BD8675B7E7FDF733 -:108C80001DFC00280CD0E068203085742179294330 -:108C90002171C17D012901D1C675C2E7C575C0E743 -:108CA0006079102108436071BBE74078C7062CD07B -:108CB0006378002BB5D1C006C00E1B28F0D8403217 -:108CC000127FC97E0520FFF70AFB002804D06079D7 -:108CD000082108436071A4E7E07804210843E070AC -:108CE000FEF742FA002803D141494B4803F0FFF850 -:108CF000E0680023016F426F491C5A4142670167D7 -:108D00002030C17D0129C9D1C6E7012B01D0CD7525 -:108D100087E7CE7585E7E07802210843E0700BE72E -:108D20000120F5F774FEF8BD10B53048007804282E -:108D300003D02F49394803F0DAF8FFF7D0FB10BD14 -:108D40003E210A5C40308189891C002A04D0C089F8 -:108D5000814203D3012070470629FBD200207047CF -:108D6000F0B58DB02E48FEF751F9002869D01F4CA0 -:108D70006079002865D1E0685C210A5C2030417F81 -:108D80000120FFF7ACFA00285BD1E068A421095C60 -:108D9000002901D00220BDE002462032D17E052903 -:108DA0004BD0204E0C2953D000250D294BD0132930 -:108DB00068D0127F012A7DD0052A7CD0AC221258BF -:108DC0001378002B78D0528843889A4274D140306F -:108DD000027F0020FFF783FA00286DD0E068AC2105 -:108DE00009580978891E062966D21EE03001002044 -:108DF000C8890100AB080000440100209027002032 -:108E0000B2270020D8270020D6080000DF08000085 -:108E1000F105000032090000390600003A0900009F -:108E2000400100202A0700000BE00A007A44127972 -:108E300092189744898BC4C4B5F6F849F84803F0F2 -:108E400056F80DB0F0BDD577403005700B2061E0CD -:108E5000F3F735F90C28F4D3E06808218030C06AB4 -:108E60001E30F3F72DF9002806D0E0680421883081 -:108E7000F3F726F9002803D1E849304603F037F824 -:108E8000032047E08030E749C56A10260023082206 -:108E900069440E35F41A6419203CE77F4F70A47FB3 -:108EA0008C70891C521E9B1C002AF3D1DE4C1026AC -:108EB000C56A02E03AE031E081E003A9082003310D -:108EC0001E35B31A5B19203BDF7F4F709B7F8B7081 -:108ED000401E891C921C0028F3D16846F7F7CFFB8F -:108EE000E16808AE1DCE0D46CA6778358867EC602C -:108EF000AB6000250D674D678D66CD6601253F2669 -:108F0000755440267554C94D88311DC5C84803F0B5 -:108F1000FDF80620FFF719FA0DB0F0BD0720FFF7A6 -:108F200014FAE068203005770DB0F0BD0C20FFF793 -:108F30000CFAE1680123084640318A7F1A438A7798 -:108F4000203005770DB0F0BD00200CE03F21095C1A -:108F500000290BD040300078002803D1AF49B54834 -:108F600002F0C5FF0A20FFF7F0F928E0F3F7A7F8B1 -:108F70000C2824D3E06808218030C06A1E30F3F743 -:108F80009FF8002806D0E06804218830F3F798F8AD -:108F9000002803D1A149304602F0A9FF0320E2E7EF -:108FA0004030807F80070AD10C20FFF7CEF9E168BE -:108FB000012040314D8288758A7F02438A77E068BC -:108FC0005C210A5C2030C17E0020FFF788F9002870 -:108FD000B8D0E168B420405C0028B3D0E0690078E4 -:108FE0000028AFD1088E0A28ACD905220A31206AA0 -:108FF00002F0C6FD002826D0E0688030016B0878BA -:10900000002810D00522491C206A02F0B9FD002872 -:1090100098D1E0688030006B0078002803D009E028 -:10902000FFE708209FE7E068216A8030006B401C62 -:1090300003F054F8E0688030016B0878401C087039 -:109040000120FFF782F9E068A03005750DB0F0BD92 -:10905000F8B5054606462036F07E2C4600278034BB -:1090600007281FD1288EE18E401C884257D1216BE2 -:1090700028460A30491C03F031F801220221284613 -:10908000FDF77DFCF776012166204155206B0078C5 -:10909000002803D16149684802F029FF216B087854 -:1090A000401E0870F07E082839D1E16A288E898830 -:1090B000401C884233D1206C0178002904D05749E4 -:1090C0005E4802F014FF15E06988C180E06A216CF7 -:1090D00040890881E06A216C80894881E06A216CBE -:1090E000C0898881206C0771216C07200870216C71 -:1090F00068884880012211462846FDF740FC03217C -:109100002846F9F77FFCE06A69884088884203D0E6 -:1091100042494B4802F0EBFEE06A0770F776F8BD73 -:1091200070B5414C6079002877D12079012640073D -:10913000002500284ADAE0683B21095C11293ED06D -:1091400004DC022907D0052939D107E0132936D0DC -:10915000152934D107E031493A4801E02F493A480E -:1091600002F0C5FE2BE001464031CD768D75AC2175 -:10917000095840884988814203D02849334802F081 -:10918000B6FEE06801468030C26A1570026C137842 -:10919000002B04D021492E4802F0A9FE0CE04B8898 -:1091A000D380036C027C1A71026C1572036C0B2263 -:1091B0001A70006C49884180E0682030C576E0680C -:1091C0002030417F022901D1E6714577207980075F -:1091D0004AD56079002847D12069C0780D287DD212 -:1091E00001007944097949188F446552069EFAFABC -:1091F000B9343FFA798EC700E0685C210A5C203000 -:10920000417F0120FFF76BF800282DD1E068032291 -:109210003D210A5440308575E0E0F8E0C88901003E -:1092200092050000FFFFFFFF30010020D82700203B -:10923000F12700204D050000820200008F0200008F -:10924000A3020000210400002504000034040000F3 -:1092500039040000E0685C210A5C2030017F0020B6 -:10926000FFF73DF8002879D1BEE0E0685C210A5C98 -:109270002030C17E0020FFF732F8002803D1FE49DC -:10928000FE4802F034FEE06809212030C176ABE0F0 -:10929000E0685C210A5C2030C17E0020FFF71FF8E7 -:1092A000002803D1F449F64802F021FEE0680721C6 -:1092B0002030C17698E0E0685C210A5C2030C17EF5 -:1092C0000020FFF70CF8002803D1EB49ED4802F02D -:1092D0000EFEE06808212030C17685E080E0E0687D -:1092E0005C210A5C2030C17E0020FEF7F8FF0028D8 -:1092F00003D1E149E44802F0FAFDE0685B210E5435 -:109300000A212030C1766FE0E0682030C07E0D2851 -:1093100003D0D949DD4802F0EAFDE0685C210E5433 -:109320000C212030C1765FE0E0685C210A5C2030CF -:10933000C17E0020FEF7D3FF002808D1E06840304E -:10934000007F002803D1CC49D14802F0D0FDE0686D -:109350005B210E540E212030C17645E03CE0E068F0 -:109360002030C07E132803D0C349CA4802F0BFFD95 -:10937000E06816212030C17636E0E068AC2109585B -:1093800043884A889A421DD1097806291AD15C215E -:109390000A5C2030C17E0020FEF7A1FF002804D126 -:1093A0004B20B549000102F0A2FDE06801464031C2 -:1093B0008A7F920702D42030C67603E08D75803014 -:1093C000C06A0570E0685C210A5C2030017F0020E3 -:1093D000FEF785FF002807D0E0684030857603E07F -:1093E000A549AD4802F083FD207900070AD56079D0 -:1093F000002807D1E0682030417F032902D10221F3 -:10940000E171457700F004F8E068FFF721FE70BDD8 -:1094100070B5A24C82B02079C0076ED06079002868 -:109420006BD16069C0780E2868D20100794409794F -:1094300049188F44636306632645646163FD631EB8 -:10944000A64DE0685C210A5C2030417F0120FEF7D8 -:1094500046FF002850D16069FDF721F9E168A62296 -:10946000505402223D2042540020403188768875B5 -:109470008BE1E0682030C17E0A2945D10D21C176FB -:1094800083E1E0683B21095C0E293DD1AC210958FC -:1094900040884988814203D07749814802F027FDFE -:1094A000E0688030C16A60692631FDF734F9E1680F -:1094B00060698C31FDF73FF9E0681121203005E04B -:1094C000E0682030C17E11291ED11321C1765CE1F4 -:1094D000E0683B21095C112901D00E2914D14030EC -:1094E000007F002810D16069FDF746F9E1689022FD -:1094F000505415202031C87647E14EE126E1E0685E -:109500003B21095C162902D0022060713DE1014631 -:1095100000254031CD768D75AC21095840884988A9 -:10952000814203D054495F4802F0E1FCE068014603 -:109530008031CA6A15700A6C1378002B02D04E492C -:109540005948E5E0034640331E7F002E0BD01D77BF -:109550004388D3800A6C15710B6C0C221A70096C4D -:1095600040884880EEE04388D3800A6C15710B6C0C -:1095700001221A720B6C0B221A70096C4088488009 -:10958000E0E0E0685C210A5C2030017F0020FEF70B -:10959000A6FE00280DD1E0685C210A5C2030C17E67 -:1095A0000720FEF79CFE002803D1607901210843C3 -:1095B0006071607900284ED1E0684030807F80077C -:1095C00015D46069FDF7CAF8E1684031C877606971 -:1095D000FDF7C6F8E168403108846069FDF7C5F819 -:1095E000E168022240314884887F10438877E06830 -:1095F000014640318A7FD20716D10A7F2030017F91 -:109600000020FEF76CFE002803D11B49274802F01A -:109610006EFCE06801213C2211540623A822135459 -:109620004030817600210183E0680146203100E06E -:1096300012E0CA7E012A03D10022CA7656210A54BA -:10964000AC21095840884A88824204D1087806280B -:1096500001D10020087098E0E0685C210A5C2030AD -:10966000C17E0620FEF73BFE002803D16079012170 -:109670000843607160791BE0C88901008204000022 -:10968000870400008C04000091040000970400008F -:109690009D040000A4040000CA0400003001002062 -:1096A000FE0200003A0300003F0300007A030000BE -:1096B00000286AD169466069FDF773F8684600784A -:1096C000C107C90F6846017004D0E068012160300D -:1096D000017103E0E068002160300171E06800255D -:1096E00056210D54AC21095840884988814204D044 -:1096F00075202B49C00002F0FAFBE068014680307B -:10970000C26A1570026C1378002B04D024492548D6 -:1097100002F0EDFB16E04B88D380026C6B461571AE -:10972000026C1B8813816B465B8853816B469B8858 -:1097300093816B46DB88D381036C06221A70006C20 -:1097400049884180E0682030C5761EE0E0685C21F1 -:109750000A5C2030017F0020FEF7C1FD002803D104 -:109760006079012108436071607900280DD160693A -:10977000FCF71DFFE1689122505405223C20425421 -:1097800000204031088301208876E2680023116FB1 -:10979000506F491C58411167506702B070BD0000FE -:1097A000C8890100AD03000070B50446F94882790C -:1097B0000025002A0AD000292ED1657010212170C1 -:1097C000C179A170017AE170857125E0F24E327A9B -:1097D000012A04D0427A012A0FD0002070BD00294E -:1097E0001AD16570132020701C22EC49A01C02F0D5 -:1097F000F4F90120A07135720EE000290CD16570DA -:1098000014212170E3494A8962808A89A280CA8929 -:10981000E2800A8A22814572012070BDF8B5E048D5 -:109820000178002902D00C263046F8BD0026DD4D17 -:1098300034462E756E75EE752E76AE75DA496E73FA -:109840004E73D54F7F217E718170687E002804D0D1 -:10985000F4F7FDFFF5F782FB6C763C72CD4884711E -:10986000D248FCF76FFCD248FCF76CFCDCE770B523 -:10987000CB4A00251570C84ECE4B35711966D86598 -:109880001078002805D0FF20CBA1873002F02FFBF5 -:1098900070BDC44C25756575E5752576A575C248FE -:1098A0006573457375717F209070607E002804D0C9 -:1098B000F4F7CDFFF5F752FB65763572B548857143 -:1098C0001430FCF73FFCBA48FCF73CFC70BDB548CF -:1098D000007D704710B5B349C87B897B4207830779 -:1098E000D20FDB0FC007D218C00F10184000052997 -:1098F00011D20A007A441279921897440905090294 -:109900000700B149085A10BDB04810BDB04900E089 -:10991000B049085A10BDFF20A7A1A73002F0E7FA0E -:10992000002010BD9F48AC49008A48437047F8B5F5 -:1099300006469C4C407BE07330790027A0730128D9 -:1099400025D0308820829448B37B8371994DA348F9 -:109950002970114602F0CDFBB0796873F11DA04863 -:1099600002F0C7FB607B0126002800D066758E4898 -:10997000407B002800D0A675A07B05284DD20100B1 -:109980007944097949188F440409262B0900278254 -:10999000D9E700218548FCF7DAFB25E0012183485F -:1099A000FCF7D5FBE91D8148FCF706FC687B002825 -:1099B00007D001280AD0FF207FA1EE3002F097FAED -:1099C00012E000217948FCF708FC0DE001217748FE -:1099D000FCF703FC08E006217448FCF7B8FB03E041 -:1099E00002217248FCF7B3FBE7752776691C6F48C4 -:1099F000FCF7D6FB29786D48FCF7E3FB04216C48A3 -:109A0000FCF7A5FB691C6A48FCF7CAFB2978684883 -:109A1000FCF7D7FB26750020F8BDFF2066A1F830C3 -:109A2000CCE770B55F4C012525765B4A127A002A97 -:109A300001D03A2070BD5F4A13780022834205D1DD -:109A4000E275664802F055FBE57500E022760020DD -:109A500070BD70B50446534D0020A875224661487C -:109A600002F0BBF8504844730120A87570BD4A4904 -:109A70000871704710B54B4C002262756073024646 -:109A8000594802F0AAF80120607510BD424948719A -:109A90007047F8B5F4F7C7FEF4F7BAFEF4F7C4FD63 -:109AA000F4F768FE3F4C0025607E002804D0F4F7F0 -:109AB000CEFEF5F753FA6576394F3D70F4F772FE36 -:109AC000A07B012804D000210846F9F751FFF8BD1A -:109AD00000210220F9F74CFF2F4C207A01260028A4 -:109AE00008D02C4881790029F1D11321C171057268 -:109AF0008671F8BD78780028FBD02E48417BE17351 -:109B00000078A0753649394802F0F3FA33493848ED -:109B100002F0EFFA3C20A07226727D70F8BDF8B515 -:109B20001F4D287800282CD11E4C207D002828D0DD -:109B3000F4F72DFE0026A674E6746E703046F4F736 -:109B400023FE0020F4F7E5FB2A48F4F7F2FC2A484C -:109B5000F4F7ACFDF4F748FEE07B0127C1070029CC -:109B600002D0A17CC9070ED0810747D5A17C890707 -:109B700044D42620F4F7EFFCA07C02210843A07413 -:109B800048E00C20F8BD2520F4F7E5FCA07C384324 -:109B90003FE0000000220020E0210020EA21002018 -:109BA00054010020C0210020A02100201422002008 -:109BB0003C220020802100207372635C6C6C5F612A -:109BC00064762E630000000014C201009A8913001D -:109BD0001CC201000CC201007102000081210020A2 -:109BE000872100208E210020AE210020F0210020BE -:109BF000F721002007C2010004C20100400709D577 -:109C0000A07C400706D42720F4F7A5FCA07C042103 -:109C10000843A074F4F7B4FD01210020F4F7B6FC6A -:109C20000F210520F4F7F9FBFE4D2978681CF4F7A5 -:109C3000E8FBA07B01280AD0042808D0607D00281A -:109C400005D0627BF849F948FCF7E1FA6675A07D1A -:109C5000002806D0F648F749427BF748FCF709FB95 -:109C6000A675286E0178002903D00178001DF4F74D -:109C70000BFCE86D0178002904D0F04A401CF5F790 -:109C80004CF96776F4F78EFD0020F8BDEC4948608A -:109C90007047F8B50126EB4C0546002824D0E07B40 -:109CA0002146C207897C002A01D0CA070BD082074F -:109CB0000FD58A070DD42620F4F74DFCA07C022195 -:109CC0000843A07410E02520F4F745FCA07C304345 -:109CD000F7E7400708D5480706D42720F4F73BFCF0 -:109CE000A07C04210843A074E07C00280AD0A07B5B -:109CF000012804D19920D449C00002F0F8F8FFF7F8 -:109D0000C8FEF8BD002D0CD002210020F4F73EFC67 -:109D1000CE480079032801D0012802D10220F4F7AF -:109D200076FEE07D002700280AD0BE4DBF48691CA2 -:109D3000FCF736FA691CC048FCF732FAE77527765B -:109D4000BA48F4F734FDA07B05280CD20100794411 -:109D5000097949188F440202020B020001210846CA -:109D6000F4F7A0FD03E0B849B94802F0C0F8E07B81 -:109D7000A17C884303D1A07B012803D0E674B048BE -:109D80000670F8BDA774FAE710B5F4F700FDAC480B -:109D90000078002816D1AB48007D002812D00020A2 -:109DA000FFF777FFA9480079002809D0012815D0CE -:109DB000022805D0032811D0A349A64802F097F83D -:109DC000002010BDF4F72FFDF4F722FDF4F72CFC72 -:109DD000F4F7D0FCF4F7E6FC0C2010BDE9F718F915 -:109DE000EEE79749012048707047F8B50024F9F76D -:109DF000D6FC002821D0FF202D30F4F7C4FB904D75 -:109E00002878924F01281BD0022801D0032830D097 -:109E10008D49914802F06BF8287800280CD03879E9 -:109E2000002809D0012807D0022835D0032833D0D4 -:109E300085498A4802F05BF8F8BDFFF72AFEF8BDB5 -:109E4000804EB07B032814D0707E002803D0F5F735 -:109E500074F8F4F7F4FC8248F4F7A9FCB07B01280D -:109E600012D0042810D0B879012806D0032804D0D5 -:109E700004E00120FFF70DFFCEE7102421460E205D -:109E800001430020F4F70EFD7879012801D1F4F7A1 -:109E9000F0FC02202870BFE728780228CFD10120EB -:109EA000F4F7B5FDF8BD70B56848654C40790128F8 -:109EB00008D16C48F4F7E6FC002801D17F20A0709F -:109EC000F4F7CEFC5F4D687E002803D0F4F7BFFCAA -:109ED000F5F744F8F9F763FC00280AD02078022847 -:109EE00003D05949604802F002F8A87B012803D04A -:109EF00006E0FFF7CEFD70BD99208000F4F743FB2C -:109F00000120FFF7C6FE20780028F4D02078012831 -:109F1000F1D039204C49000101F0E9FF70BDF0B5E6 -:109F2000044689B0002006900090F4F7FFFA0290F2 -:109F300043480078022803D043494C4801F0D7FF3A -:109F4000424D6879012809D14648F4F79BFC002866 -:109F500002D13B497F208870F4F782FC4048FCF72F -:109F60001BF9384E0746002C5AD03D48FCF71EFA24 -:109F7000002855D0F4F74EFA002851D0707E002802 -:109F80000AD00524641EE4B2F5F709F8022811D0BE -:109F9000012800D000200090314A354CD01C01909F -:109FA000062F3DD238007844007900188744BDBDA3 -:109FB000BD0ABD85002CE5D177202EA1C00001F09F -:109FC00096FFE7E7B07B01282AD0042828D0009923 -:109FD0000298084304D1A879002801D002281FD193 -:109FE000687901281AD1607A002817D1012060729F -:109FF00010784006C00FA0722248019902F079F84B -:10A000000F4F214CB8787F2804D1A92019A1C00096 -:10A0100001F06DFFB87820707F20B870064835E0F9 -:10A0200083E0000080210020AE21002014220020C7 -:10A03000A02100208E2100203C2200206722002049 -:10A0400054010020C0210020B89B0100E021002025 -:10A05000F6040000DE020000490300005E03000079 -:10A06000642200205601002081030000CE0300007E -:10A07000002200207372635C6C6C5F6164762E63F7 -:10A08000000000000B22002011220020F4F78FFBBB -:10A090007F48032101702879002848D0012808D082 -:10A0A000022844D0032804D07A497B4801F01FFFDE -:10A0B0003DE00120F4F7ABFC39E07848D178C07975 -:10A0C00081421CD175481179037A994217D151798F -:10A0D000437A994213D19179837A99420FD1D179F8 -:10A0E000C37A99420BD1117A037B994207D1117837 -:10A0F000407B4906C90F814201D1012100E00021C6 -:10A10000B07B012801D0042801D100290AD1002800 -:10A110000BD100990298084304D1A879002801D0F6 -:10A12000012802D1307E00281FD001200690707EC9 -:10A13000002803D0F4F78BFBF4F710FF06980028F3 -:10A1400002D00120FFF7A5FD5148017800290AD06F -:10A150000178012907D00078032804D095204D49C3 -:10A16000C00001F0C4FE09B0F0BD49484C4F406842 -:10A17000397CC173797C0174B97C4174F97C817438 -:10A18000484909784906C90F01771D30019901F046 -:10A19000B0FF3F48397D4068C174797D0175B97D54 -:10A1A0004175791C897D817501994A7D0B7D11026C -:10A1B00019430183791C8A7E4B7E12021A438280E6 -:10A1C000019A537E177E1A023A43C2808A7F4B7FE0 -:10A1D00011021943018134490A3001F07FFF3348ED -:10A1E0002B4A01795768C906C90EB976007940092A -:10A1F000F876287A002809D0A079002835D11320D4 -:10A20000E071002020720120A0712EE00020A872D1 -:10A210007888B085387FE87339461D31244801F0CD -:10A2200068FF1E4823490078A875234801F061FFA4 -:10A23000B888F087F888208038896080F87E20719F -:10A240000098002860790BD0012108436071F4F771 -:10A25000BFFE61794000C907C90F0143617102E087 -:10A2600040084000607101202872094C00202070D5 -:10A27000F4F7D9FAF4F7CCFAF4F7D6F9F4F77AFA56 -:10A28000F4F790FA01206168F9F772FB4FE70000DC -:10A290005401002074A00100160400008021002059 -:10A2A00063220020642200208322002084220020D8 -:10A2B000F021002081210020F7210020F8B5FCF7D3 -:10A2C0004DFE0446FCF707FFF84E05467069203046 -:10A2D000407D002826D0012844D0022846D00328FB -:10A2E0004DD0FF20F2A19A3001F001FEB069F722B3 -:10A2F00001781140017072692032937DDB071B0FDA -:10A300001943FB2319400170D37DDB075B0F194311 -:10A310000170577DEF23022F3CD0012F3FD0032F38 -:10A3200041D046E0E648FCF7B5FE002804D071694C -:10A33000032020314875D9E7E148FCF7A1FD00284A -:10A3400004D070695B21095C002907D0DC48FCF768 -:10A350004AFE7169012020314875C7E7022120308B -:10A360004175C3E7D648FCF73EFEBFE7D448FCF78B -:10A3700087FD0028BAD1FF20CDA18C3007E0D0485E -:10A38000FCF788FE0028B1D1FF20C9A1943001F06C -:10A39000AEFDABE7012C08D8002D06D009E06D1EFC -:10A3A0002C4302D105E0002C03D01940102319439F -:10A3B00000E019400170D17F002915D0517D01299D -:10A3C00012D0C048F4F7F3F9BF4800210176726952 -:10A3D000916ED26E42610161BA49B269F4F729FD0A -:10A3E0000020F4F735FD03E0F4F7E1F9F4F753FD4D -:10A3F000B0690078C00606D4F0690078C00602D4BF -:10A40000F079002806D0B079002803D10121084650 -:10A41000F4F748FA032030703079002803D1F4F7BC -:10A42000E3F901203071F8BD10B5A0490023486957 -:10A4300002462030C3768377012049239854A03206 -:10A440009279002A03D008700021022001E0002147 -:10A450000320F9F737FA10BD06281AD202007A4411 -:10A460001279921897440205090D101000290ED098 -:10A470000FE0891E02290AD90BE0891F012906D99C -:10A4800007E0082903D004E00B390C2901D801208A -:10A4900070470020704730B5044683B08848FCF709 -:10A4A000B5FD002803D182A1884801F020FD7F4D31 -:10A4B000A869FBF7BBFF0321A869FBF7D8FFA869D0 -:10A4C000EF220178114001702146FCF739F80E2C7B -:10A4D0005BD220007844007900188744565606560F -:10A4E0001F5A5A175642565A312B704865224169F5 -:10A4F000525C002A04D006218069FCF7CEF848E0BF -:10A50000C03149798069FCF7C8F842E06748416981 -:10A5100080698031497CFCF731F93AE0634D696923 -:10A52000A869B831FCF7F2F86969A8698C31FCF7C1 -:10A53000F9F82EE05D4806218069FCF71BF928E058 -:10A540005A4D28694178A869FCF7FEF82869818886 -:10A55000A869FCF7FBF828694188A869FCF7FAF8B4 -:10A5600017E000200090019050484169603109795E -:10A57000002905D06A461178012211436A461170FC -:10A5800069468069FCF708F903E049A1504801F0E9 -:10A59000AEFCFCF74CFD002803D145A14D4801F06D -:10A5A000A6FC0C2C0AD0072C06D04048002140699C -:10A5B000403041820121817503B030BD3B4800210C -:10A5C00040694030018303B030BDF0B5374C0546DB -:10A5D00060698DB020308079012801D1F4F740F90D -:10A5E000012D14D160694021095C002903D120307C -:10A5F000C07F002801D0F4F74EFCF4F714F9F4F70B -:10A6000007F9F4F711F8F4F7B5F8F4F7CBF8607937 -:10A610000225C107002901D1800713D560692030C8 -:10A62000817F002902D0032907D00BE00121817727 -:10A6300000210120F9F746F904E085770021012087 -:10A64000F9F740F960692030817F012903D16179F0 -:10A65000090700D5857715480024407A002866D17F -:10A6600000F005FF1648FCF7D1FC00285FD00F4D25 -:10A67000287A00285BD16869C421095C00290ED0C2 -:10A680002030C17E0120FFF7E7FE002807D168696E -:10A690002030C17E0420FFF7DFFE00281CD068694F -:10A6A000C921095C06291ED024E000005C010020BD -:10A6B0007372635C6C6C5F736C6176652E63000013 -:10A6C0007401002090220020B82200208B07000097 -:10A6D000CD070000D3070000686950210C5260309C -:10A6E0004471022051E02030C17E0420FFF7B4FE07 -:10A6F000002815D068692030C07E801E16287DD2C3 -:10A7000001007944097949188F44C3C3C31CC3C3EA -:10A71000C3BFC31EC3C3C32742C3C3C3C3C3C3A5ED -:10A7200068695E21095CC90702D0C0304472D6E076 -:10A730000C20FFF7B0FE686901224030817F114391 -:10A740008177CCE0072020E0FCF73CFD00286FD0AB -:10A750006869403004700B2017E0F1F7B0FC0C285A -:10A7600066D368690821B830F1F7AAFC002806D042 -:10A77000686904218C30F1F7A3FC002804D1C720BC -:10A78000FDA1C00001F0B3FB0420FFF784FEA6E0AA -:10A7900068698446C030007A042802D0052848D071 -:10A7A0009DE0F9496046102600230822D63069440E -:10A7B000F51A2D18203DEF7F4F70AD7F8D70891CED -:10A7C000521E9B1C002AF3D103A8624610260021CA -:10A7D00008230330B032751AAD18203DEF7F477063 -:10A7E000AD7F8570801C891C5B1EF4D16846F5F72F -:10A7F00046FFE64841690D46783500E049E008AE7D -:10A800008DCECA678867EF60AB6000250D674D6726 -:10A81000012640256E54DE4D88318DC5DD4801F09E -:10A8200075FC0520FFF737FED8484069C030047238 -:10A8300055E060464030007F002805D06046012189 -:10A8400060304171022000E00D20FFF724FE6869AE -:10A85000C030047243E0696900208866C866012040 -:10A860003F2250540F4678378A6FC948CB6FBE6875 -:10A87000FF68CCC00930883101F048FC0620FFF7A2 -:10A880000AFE68694030847529E00920FFF703FE5D -:10A8900025E06869C821095C002920D0062906D076 -:10A8A0002030C17E0020FFF7D7FD002817D068694F -:10A8B0000146C0310A7A072A11D213007B441B7962 -:10A8C000DB189F440C0C0C0C0C0C03004030807FF8 -:10A8D000C20700D12CE7C043800700D10C72AB4DFA -:10A8E00028790028686902D08030048403E0803031 -:10A8F000018C491C01846879C007686904D0AC21C7 -:10A900000C544030848103E040308189491C8181AE -:10A91000E879002806D06969A031087B022806D8AA -:10A92000401C08736869A030007B022806D968695A -:10A930000146803004844484A0310C73686920305F -:10A94000C17E0020FFF788FD002804D1686920300F -:10A95000C07E07284ED168690146C0310A7A062AAE -:10A9600048D0497A062945D03E21095C022941D1C7 -:10A97000A030007B00283DD1FCF7E2FA002839D056 -:10A98000FCF7A9FB002835D069690A468032508B54 -:10A9900001282FD90B460120A033587108464030BA -:10A9A0008789C089861EB74201DB012002E0C01BF7 -:10A9B000401E80B2168CAF89BE4201D3012602E050 -:10A9C000BE1B761CB6B2B04200D93046012800D179 -:10A9D0005C71C0310B78002B10D0528C49888A42B0 -:10A9E00001D3012102E0891A491C89B2884205D9A4 -:10A9F000084603E069690120A0314C7169690E8E37 -:10AA00000A46301883B28032084693832030877F0D -:10AA1000002F29D0012F27D0022F0CD0032F0AD0CE -:10AA200055A15D4801F063FA6879C00668691DD5D3 -:10AA30008030C4851FE0C07E03280DD0082813D0C5 -:10AA40004031C8898989401A801E80B2032800D30A -:10AA5000032018181083E7E740318889032803D3BF -:10AA6000C8893018401CF5E71383DDE78030C18DBD -:10AA7000C28B8918C18568690246C03211790029E4 -:10AA800006D0014640319E230E8A1B5AF3180B82D2 -:10AA9000697A0426002913D0014640313D230A4635 -:10AAA0008B722039CC768C7701215172A03080795D -:10AAB000002875D0297000210220F8F703FF74E008 -:10AAC00001462031CB7E042B48D02B7A002B1ED0A0 -:10AAD0005A0701D4DA0604D51E2240308272CE769F -:10AAE0003CE01A0704D53D2240308272CE7635E034 -:10AAF000D80705D1980703D41FA1284801F0F7F91A -:10AB000068692A214A2211542030C67626E0403056 -:10AB1000837D002B05D0478A7B1C4382838A9F421A -:10AB20000FD2537A062B02D0127A062A05D1038B54 -:10AB30005A1C0283828A934203D2038AC2899342B7 -:10AB400003D322228272CE7608E08B7F002B38D08E -:10AB5000838993423FD308228272CE766869492264 -:10AB600001462031CC768C7701211154A0308079B8 -:10AB700000282DD0297014E07372635C6C6C5F73D5 -:10AB80006C6176652E630000FFFFFFFF5C01002013 -:10AB9000B8220020D12200205C08000043020000FF -:10ABA00016E000210220F8F78DFEF8F720FE0028BD -:10ABB0001AD068690146FF3001300279002A0FD0AF -:10ABC00012E08289062A06D33E228272CE76C5E73B -:10ABD00000210320E7E70120287000210846E2E772 -:10ABE0004988C180012101716869A03084710DB06C -:10ABF000F0BD70B5044682B00020C04369460880AD -:10AC00006846FBF773FA002873D1684601A90088EB -:10AC1000FBF750FA002803D0FD49FE4801F067F920 -:10AC200001990A46E031887C002500280AD0657029 -:10AC300010202070C87CA070087DE0708D74012009 -:10AC400002B070BD8879F44E002815D065700720D9 -:10AC50002070887900280DD07169E6208D844554D4 -:10AC60000A22A01CE83100F0B8FF0198E03080799A -:10AC70000028F1D1A5704EE0887D00283FD0887D66 -:10AC80000D2837D203007B441B79DB189F443232F6 -:10AC90003232323232320F323225060065700C20E9 -:10ACA0002070087EA07070694088A08013E06570F5 -:10ACB00008202070706913464088FA336080188835 -:10ACC000A0805888E08098882081D888FF326081F1 -:10ACD00003321088A0818D751DE065700B202070F7 -:10ACE000087EA07070694088A080087FA0718D7573 -:10ACF00011E027E0C649C94801F0F9F80BE0D01D82 -:10AD0000F9300179002909D0112165702170821C68 -:10AD1000918861800571012002B070BD017A00291F -:10AD200010D0657012212170017A0029F3D0FF3212 -:10AD300003320572118961805189A180017A00294D -:10AD4000F7D1E8E7002002B070BDB34800780128D1 -:10AD500001D00C2070470020704770B5AE4C0546FE -:10AD60002078002803D0AA49AD4801F0C0F800209F -:10AD70002561A072012020702078012803D0A44909 -:10AD8000A84801F0B4F870BDF8B5A34F397801298F -:10AD900001D00C20F8BD0125A62178610D5480302A -:10ADA000807CFCF75DF800282ED078698030807CAC -:10ADB000FCF79EF9002827D078698030807CFCF76A -:10ADC00015F9002820D078698030807CFCF752F992 -:10ADD000002819D0F3F7DBFC786900248030408B21 -:10ADE000002826D09048FCF711F9002821D0786976 -:10ADF000C421095C00291CD02030C17E0120FFF74E -:10AE00002BFB002802D014E01220F8BD7869203016 -:10AE1000C17E0420FFF720FB00280AD17869502169 -:10AE20000C52603044710220FFF735FB7869A03086 -:10AE300044717869E621095C002905D1818CC288BA -:10AE4000914201D9B98101E0C188B98101468031BF -:10AE5000CA8B521E93B20A8CD21892B20A849446BC -:10AE60000246A0321679002E02D04C84147102E002 -:10AE70004E8CF6184E8406464036B789FF18B781C7 -:10AE80004E8B012E01D8761C4E83002B00D01473FC -:10AE90002030C07E604E042817D05079002816D08C -:10AEA000B1898C4513D2FCF74BF800280FD070699C -:10AEB0000146C0310A78002A09D08030408C498888 -:10AEC000884204D3B470F57003E0B57001E0B4704B -:10AED000F4707069A5210C543B21095C062901D04E -:10AEE000072917D1CA21028E095A511A09B200291D -:10AEF00010DB0146CC310A3001F019F901220221A0 -:10AF00007069FBF7E2FC7069C9210C543B210C54B9 -:10AF100060308571404E9E2170690A5A014630307A -:10AF2000891CFBF77AFDB078002852D17069C021E6 -:10AF3000095C002901D0803044840120F3F7E9F94D -:10AF4000354E70691330F3F7B1FB70690F30F3F7CA -:10AF5000F0FA0120F3F718FC71694020405C0028EA -:10AF600003D13F20405C00280BD00F4678378A6F12 -:10AF70002E48CB6FBE68FF68CCC02D48883101F0E9 -:10AF8000C5F8F3F7FDFB01210846F3F7FFFA224E5F -:10AF900070698030806AF3F70DFC2648FCF7B8F83A -:10AFA000002801D0747002E075702348F061706968 -:10AFB00040300078002802D07078002816D0F06960 -:10AFC000F3F7F5FBF3F767FF70694030007AF3F7AA -:10AFD000C2FA114802214471C4718471047244722E -:10AFE00004710170F3F7DEFB0020F8BD1248F3F79F -:10AFF000DEFB0E4805767269116F526F4261016186 -:10B000000D4AF169F3F715FF0120F3F721FFDBE7A4 -:10B0100078AB0100810800005C010020DE08000020 -:10B02000140900001F09000074010020B82200204C -:10B03000D1220020780100209022002010B5F94C88 -:10B040002078022801D00C2010BDA078002803D061 -:10B050000020FFF7BAFA1BE0F3F799FB012100206B -:10B06000F3F720FC042020706069203080790128EB -:10B0700001D1F3F7FEFBA07A002809D0012807D000 -:10B08000022807D0032805D0E749E84800F02FFF41 -:10B09000002010BDE7F7BCFFFAE7E249887270476D -:10B0A000F8B5E04C2078032803D0DF49E04800F0F1 -:10B0B0001EFF606900262030817C042701250029BD -:10B0C00004D086740575A1793943A171A1690A7804 -:10B0D000D243920707D1C27C002A04D1C574A0795B -:10B0E00002221043A0710878C00606D4E0690078F7 -:10B0F000C00602D4E07900280CD06078002809D17D -:10B10000A079002806D1F8F760FB002802D0207A49 -:10B11000002803D00120FFF758FA1BE0C548FBF7D1 -:10B12000F7FF002801D0667002E06570C248E06158 -:10B13000606940300078002802D0607800281AD07A -:10B14000E069F3F734FBF3F7A6FE01210020F3F7E3 -:10B15000A9FB2770207801280CD0A07A002809D0FC -:10B16000012807D0022818D0032816D0AE49B348CA -:10B1700000F0BDFEF8BDB048F3F719FBB048057606 -:10B180006269116F526F42610161AB4AE169F3F785 -:10B1900050FE0120F3F75CFED7E70120F3F737FC00 -:10B1A000F8BDF8B59F4C05462078042803D09E4989 -:10B1B000A44800F09CFE6179102001436171002DCC -:10B1C0007ED0F3F780FE617801250843002814D172 -:10B1D00060694021095C00290FD0E1694A78D206F4 -:10B1E0000BD0097820300907C07DC90F814204D1F6 -:10B1F00065720120FFF7E9F903E1E07800281ED02D -:10B20000E0694178C9061AD10078C00617D4606990 -:10B210002030807901287DD1F3F722FB6169881CF9 -:10B220003031FBF7EAFC002874D06069C11D428808 -:10B23000F9314A812030007E08730D72DBE06069CD -:10B2400020308079012811D1F3F70AFB6169881C4D -:10B250003031FBF7D2FC002808D06169C81D4A884C -:10B26000F93042812031097E01730572E0690026C0 -:10B2700000784007C10F60692030827D914244D040 -:10B28000407D082700283DD0022810D1FBF721FE81 -:10B29000002804D171206449000100F028FE626991 -:10B2A0000023906ED16E401C5941D1669066606952 -:10B2B00020304675017D012906D10675A17900E08F -:10B2C00083E010221143A171C17C012914D1C674FD -:10B2D000A0793843A071FBF7ECFE002804D1E520EB -:10B2E0005149C00000F003FE62690023906ED16EE8 -:10B2F000401C5941D166906660692030817D0129EA -:10B300002AD08575607938436071E3691A7810072F -:10B31000C70F00E06FE060692030C17D8F420BD124 -:10B320009207920F0427012A25D0022A23D0032A4C -:10B3300014D0207A38432072607928436071E67116 -:10B34000A079000704D560692030C07E032852D060 -:10B35000207A00284FD152E08675D3E76278002A20 -:10B36000EAD18574A2792A43A271012901D1C67557 -:10B37000E2E7C575E0E75A78D30623D06078002865 -:10B38000DAD1D006C00E1B2818D860793843607116 -:10B39000FBF7EAFE002804D13B202349400100F0DE -:10B3A000A6FD60690023016F426F491C5A41426744 -:10B3B00001672030C17D0129DBD1D8E7207A102137 -:10B3C0000843B8E70129D4D1D1E7022001436171D4 -:10B3D000E079401CC0B2E07101280CD860694030AF -:10B3E000007800280BD014484078C106C90E052902 -:10B3F00005D2C00603D00120FFF7E7F801E0FEF711 -:10B400005DFF207801280CD0A07A002809D00128FF -:10B410001CD0022805D0032818D003490A4800F0A0 -:10B4200066FDF8BD5C01002078AB0100F409000066 -:10B430001D0A000078010020902200205C0A000014 -:10B44000B8220020740A0000D60A00000120F3F799 -:10B45000DEFAE6E710B5FE480078042803D0FD497F -:10B46000FD4800F044FD0120FFF7AFF810BDF8B52E -:10B47000F74C0025A0790007002832DA207A00284E -:10B480002FD160692030C07E801E132829D2010090 -:10B490007944097949188F44240924242424242434 -:10B4A000242424242424242424241D0060696522C7 -:10B4B000014640318D75125C002A05D006228A7241 -:10B4C00004212030C1760CE016228A72042120303B -:10B4D000C17606E0606901464030C5768575203149 -:10B4E000CD76607940070BD560692030C17E05209C -:10B4F000FEF7B2FF002803D0207A0821084320720B -:10B5000000F032F9A37901265807002821DA207AC1 -:10B5100000281ED1606902462032D17E891E07298B -:10B5200017D20F007F443F79FF19BF440312121254 -:10B530000C120F00014640318D75C0308079887241 -:10B540000420D07605E0C030467202E00221C0300F -:10B55000417298070327002849DA207A002846D14B -:10B5600060692030C17E0120FEF776FF00283ED1C1 -:10B57000A069C0780E287DD2010079440979491864 -:10B580008F44A3A306A33646620AA317A3269354A7 -:10B5900060692030C7769CE060692030C07E052855 -:10B5A00003D0AC49AD4800F0A2FC60692030C576FC -:10B5B0008FE060692030C07E092803D0A549A848E3 -:10B5C00000F095FC606956210D542030C57680E06E -:10B5D00060692030C07E0B2803D09E49A14800F04E -:10B5E00086FC60695B210E540C212030C17670E02E -:10B5F00060692030C07E0F2803D096499A4800F039 -:10B6000076FC60695B210E5410212030C17660E029 -:10B6100060692030C07E102803D08E49934800F026 -:10B6200066FC606912212030C17652E060692030EA -:10B63000C07E102803D087498D4800F058FC60690F -:10B6400014212030C17644E060692030C07E172884 -:10B6500003D08049874800F04AFC606901464031C8 -:10B66000CD7602468D75E032937D002B09D0917C1A -:10B67000002900E029E015D10B21D17415759674CD -:10B6800010E00B7F002B06D00D774388FA210B5278 -:10B6900015760C2105E04388FA210B5215761677B2 -:10B6A0000B2191752030C57613E060690146C030EA -:10B6B000027A062A04D14031897F890700D50572B4 -:10B6C000417A062905D1457203E062496A4800F0D3 -:10B6D0000EFCA079C00613D5207A002810D160692D -:10B6E0002030C17E07290BD20A007A4412799218C1 -:10B6F000974406060606060603000721C176F8BD34 -:10B7000060693B21095C0829F9D10146028EC031EC -:10B710004B89521C9A42F2D1227A002AEFD10A8A2E -:10B7200083889A4207D14B8AC488A34203D18B8A6B -:10B730000489A34208D043884B858A854A8ACA85F2 -:10B740008A8A0A86E6210E5401221146404CFBF7F4 -:10B75000BCF800210420F8F7B5F86069C9210D5440 -:10B760002030C5768777F8BD70B5394C82B0A079A6 -:10B77000C0076BD0207A002868D160692030C17E74 -:10B780000120FEF769FE002844D1E069C0780D2849 -:10B790005DD201007944097949188F443C1506E8C7 -:10B7A0005858FD3BFC58BBD5FB00E069FAF777FF22 -:10B7B0006169C622505402223B204254002040318D -:10B7C000488201208875B0E160692030C17E002088 -:10B7D000FEF742FE0028207A02D000281AD103E0AA -:10B7E000012108432072A0E1E069FAF751FF616985 -:10B7F000CA2250520A8E801A204A00B290427DDC42 -:10B8000000287BDDCC31E069FAF737FF606906215B -:10B810002030C17689E160692030C17E0020FEF7CA -:10B820001BFE002803D1207A012108432072207AD0 -:10B83000002867D1E069FAF7EDFE002848D0E069FA -:10B84000FAF7E3FE6169CA22505219E075E154E14A -:10B850005C01002078AB0100DE0A00001905000041 -:10B860001F050000260500002D050000340500001E -:10B870003A0500004C050000BA050000FE7F0000FC -:10B880000A8E801AAE4A00B290423CDC00283ADDB3 -:10B89000E069FAF7B4FE6169C0310873E069FAF74C -:10B8A000A7FE6169C031C881E069FAF786FE616967 -:10B8B000C0310882E069FAF789FE6169C0314882C7 -:10B8C000E069FAF78CFE6169D422505208202AE11F -:10B8D00060692030C17E0020FEF7BEFD002803D144 -:10B8E000207A012108432072207A00280AD1E069D9 -:10B8F000FAF75DFE61699122505400E003E00520F3 -:10B900002031C87611E128204A22505404202031E9 -:10B91000C8760AE160692030C17E0020FEF79CFDF8 -:10B92000002803D1207A012108432072207A0028C0 -:10B9300068D160690022014640304282012282754E -:10B940000B202031C876F0E0606901462031CA7EC4 -:10B950000C2A03D0227A02231A432272227A002A66 -:10B9600050D1CA770122403002770D20DCE06069B7 -:10B970002030C17E0020FEF76FFD002808D16069ED -:10B980004030007F002803D1207A01210843207233 -:10B99000207A02E048E082E035E0002832D1606998 -:10B9A000002501464030458201268675B031E069A8 -:10B9B000FAF792FE6169E0698831FAF79EFE6069E4 -:10B9C0000146E030827D002A07D0817C002915D114 -:10B9D0000821C1740575867410E04A88F820425227 -:10B9E000FA31E069FAF762FE6169E069FF3103311B -:10B9F000FAF768FE60690821E030817560690F21FF -:10BA00002030C17691E0606901462031CA7E122A59 -:10BA100003D0227A02231A432272227A002A6BD19F -:10BA20004030827517207FE060690146C0314A7A54 -:10BA3000002A06D0097A062903D0217A012211436F -:10BA40002172217A002970D14030807F800715D47F -:10BA5000E069FAF783FE61694031C877E069FAF777 -:10BA60007FFE616940310884E069FAF77EFE616912 -:10BA7000022240314884887F1043887760690146FC -:10BA8000C030027A062A01D10022027240318A7F38 -:10BA9000D2074AD1062242720020088345E060693D -:10BAA0002030C17E0020FEF7D7FC002803D1207A89 -:10BAB000012108432072207A002836D16946E069C6 -:10BAC000FAF763FE68460078C107C90F684601703F -:10BAD00004D0606901216030017103E060690021D8 -:10BAE00060300171606900220146403042820122CB -:10BAF000827509202031C87617E060692030C17E48 -:10BB00000020FEF7A9FC002803D1207A0121084378 -:10BB10002072207A002808D1E069FAF748FD6169AF -:10BB20009122505405202031C87662690023116F9C -:10BB3000506F491C58411167506702B070BD00003A -:10BB4000FE7F00000A4A022151600A490B68002B5F -:10BB5000FCD0906008680028FCD000205060086885 -:10BB60000028FCD0704701200007406970470000A2 -:10BB700000E5014000E4014070477047704770479E -:10BB8000034610B50B439B070FD1042A0DD308C8F9 -:10BB900010C9121FA342F8D018BA21BA884201D99D -:10BBA000012010BD0020C04310BD002A03D0D307E0 -:10BBB00003D0521C07E0002010BD03780C78401C15 -:10BBC000491C1B1B07D103780C78401C491C1B1B0C -:10BBD00001D1921EF1D1184610BDF8B5042A2CD31C -:10BBE000830712D00B78491C0370401C521E830738 -:10BBF0000BD00B78491C0370401C521E830704D0E5 -:10BC00000B78491C0370401C521E8B079B0F05D0FC -:10BC1000C91ADF002023DE1B08C90AE0E5F7D4FAC1 -:10BC2000F8BD1D4608C9FD401C46B4402C4310C059 -:10BC3000121F042AF5D2F308C91A521EF0D40B7849 -:10BC4000491C0370401C521EEAD40B78491C037037 -:10BC5000401C012AE4D409780170F8BD01E004C059 -:10BC6000091F0429FBD28B0701D50280801CC9075C -:10BC700000D00270704700290BD0C30702D00270B9 -:10BC8000401C491E022904D3830702D50280801C70 -:10BC9000891EE3E70022EEE70022DFE7020A0870D0 -:10BCA0004A70020C8A70020ECA70704700220309A3 -:10BCB0008B4273D3030A8B4258D3030B8B423CD382 -:10BCC000030C8B4221D312E003460B437FD40022A6 -:10BCD00043088B4274D303098B425FD3030A8B4220 -:10BCE00044D3030B8B4228D3030C8B420DD3FF228A -:10BCF000090212BA030C8B4202D31212090265D058 -:10BD0000030B8B4219D300E0090AC30B8B4201D30A -:10BD1000CB03C01A5241830B8B4201D38B03C01A51 -:10BD20005241430B8B4201D34B03C01A5241030BC8 -:10BD30008B4201D30B03C01A5241C30A8B4201D379 -:10BD4000CB02C01A5241830A8B4201D38B02C01A24 -:10BD50005241430A8B4201D34B02C01A5241030A9B -:10BD60008B4201D30B02C01A5241CDD2C3098B4280 -:10BD700001D3CB01C01A524183098B4201D38B01FD -:10BD8000C01A524143098B4201D34B01C01A5241A0 -:10BD900003098B4201D30B01C01A5241C3088B42E5 -:10BDA00001D3CB00C01A524183088B4201D38B00D0 -:10BDB000C01A524143088B4201D34B00C01A524172 -:10BDC000411A00D201465241104670475DE0CA0F49 -:10BDD00000D04942031000D34042534000229C4609 -:10BDE00003098B422DD3030A8B4212D3FC22890113 -:10BDF00012BA030A8B420CD3890192118B4208D3E9 -:10BE0000890192118B4204D389013AD0921100E04A -:10BE10008909C3098B4201D3CB01C01A524183095E -:10BE20008B4201D38B01C01A524143098B4201D38B -:10BE30004B01C01A524103098B4201D30B01C01AB6 -:10BE40005241C3088B4201D3CB00C01A5241830830 -:10BE50008B4201D38B00C01A5241D9D243088B4286 -:10BE600001D34B00C01A5241411A00D20146634629 -:10BE700052415B10104601D34042002B00D549428D -:10BE8000704763465B1000D3404201B50020C046B6 -:10BE9000C04602BD70477047704710B500F058F8B3 -:10BEA00010BD30B58C180278401C13071B0F01D150 -:10BEB0000378401C120906D10278401C03E0057883 -:10BEC000401C0D70491C5B1EF9D101E00B70491C30 -:10BED000521EFBD1A142E6D3002030BD012308CB86 -:10BEE000134B1860134B1960134B1A607047134AB9 -:10BEF000134B13607246053AF0E7114A0F4B1B686B -:10BF00009A420ED10D4B0020186001980D4B04B5DC -:10BF100098470CBC9E460246029800990A4B1B6843 -:10BF2000184706980599094B1B68DB6818470000FD -:10BF300084010020880100208C0100207C01002069 -:10BF4000EFBEADDEC12F0000840000200400002001 -:10BF50001D481E497047FFF7FBFFE5F7EFF800BDEE -:10BF600001200007C06AC0B2FF2804D1184819494F -:10BF70000968884202D018481849016018481949D0 -:10BF80000968884203D1184A13605B68184700BDEE -:10BF900020BFFDE712481349096888420ED1134BB0 -:10BFA00018680B498842F3D080F30888104988420A -:10BFB00004DD1048026802210A4302600E488047EF -:10BFC0000E4880470E480047801E0020801E00203B -:10BFD000FFFFFFFF001000102C05004008000000CC -:10BFE00000100000000000200400002000D001002C -:10BFF0000020002024050040D72F000061BF010071 -:10C00000DDBE01001348704502D1EFF3098101E064 -:10C01000EFF30881886902380078102814DB2028A3 -:10C0200010DB2B280BDB0C4A12680C4B9A4203D115 -:10C03000602804DB0A4A1047022008607047094A5A -:10C0400010470000084A1047084A12682C3212684C -:10C0500010470000FDFFFFFF60000020BEBAFECACF -:10C06000AD12000081030100010301000400002063 -:10C070000D4B0E4908470E4B0C4908470D4B0B4919 -:10C0800008470D4B094908470C4B084908470C4B1A -:10C09000064908470B4B054908470B4B034908471E -:10C0A0000A4B02490847000039250000D921000049 -:10C0B000692B0000172A0000C5290000792700001D -:10C0C000B912000037140000D92A0000CF22000066 -:10C0D0000021018041808180C18070470A78027010 -:10C0E0004B7843708A788270CA78C2700B7903717A -:10C0F00070470A7802704B7843708A788270CA78E9 -:10C10000C2700B7903714A79427170470A780270E4 -:10C110004B7843708A788270CA78C2700B79037149 -:10C120004A7942718A798271CB79C37170470A88E2 -:10C1300002804A8842800A79027170470A68026068 -:10C140008B8883808A798271704730B47446641E0C -:10C150002578641CAB4200D21D46635D5B00E3188A -:10C1600030BC1847FFFFFFFF0000FFFF0100030086 -:10C1700000000100000000000000000000000000BE -:10C180000000000087000000000000000000000028 -:10C190000000000000000001020304000D0E0F105B -:10C1A00000000000BF680000DD6A0000A56B000011 -:10C1B000FF6B0000536C0000BB6C000019690000AD -:10C1C000D16900005D6D00006B7900001001100165 -:10C1D0003A0200001A02000004013C00050044007D -:10C1E0000E00F401FA00960064004B0032001E00BD -:10C1F00014000102040810204080555555252627BB -:10C20000D6BE898E555555D6BE898E000000700663 -:10C21000120DB413000014035A06A00900006004B4 -:10C22000F208840D54C20100080000201000000034 -:10C230000411000064C20100180000207801000011 -:10C24000A2BE01008CC2010090010020F01C000081 -:10C2500020110000024801688907FCD570470000E2 -:10C2600000E200E0D10224FF360100010050372037 -:10C27000FB349B5F80B4800010022801029C0133D4 -:0CC280007F01E2290345FFFFE4E1BE015D -:00000001FF diff --git a/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51422_xxaa.ld b/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51422_xxaa.ld deleted file mode 100644 index 1ce9c2f..0000000 --- a/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51422_xxaa.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x1d000, LENGTH = 0x23000 - RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x1800 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51422_xxac.ld b/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51422_xxac.ld deleted file mode 100644 index 411672d..0000000 --- a/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51422_xxac.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x1d000, LENGTH = 0x23000 - RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x5800 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51822_xxaa.ld b/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51822_xxaa.ld deleted file mode 100644 index 1ce9c2f..0000000 --- a/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51822_xxaa.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x1d000, LENGTH = 0x23000 - RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x1800 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51822_xxab.ld b/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51822_xxab.ld deleted file mode 100644 index 4095abb..0000000 --- a/components/softdevice/s120/toolchain/armgcc/armgcc_s120_nrf51822_xxab.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x1d000, LENGTH = 0x3000 - RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x1800 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s120/toolchain/iar/iar_s120_nrf51422_xxaa.icf b/components/softdevice/s120/toolchain/iar/iar_s120_nrf51422_xxaa.icf deleted file mode 100644 index 48568ea..0000000 --- a/components/softdevice/s120/toolchain/iar/iar_s120_nrf51422_xxaa.icf +++ /dev/null @@ -1,31 +0,0 @@ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ -/*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x1d000; -/*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x1d000; -define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002800; -define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; -/*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 0x800; -define symbol __ICFEDIT_size_heap__ = 0x200; -/**** End of ICF editor section. ###ICF###*/ - -define memory mem with size = 4G; -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; - -define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; -define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; - -initialize by copy { readwrite }; -do not initialize { section .noinit }; - -keep { section .intvec }; -place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; -place in ROM_region { readonly }; -place in RAM_region { readwrite, - block CSTACK, - block HEAP }; diff --git a/components/softdevice/s120/toolchain/iar/iar_s120_nrf51422_xxac.icf b/components/softdevice/s120/toolchain/iar/iar_s120_nrf51422_xxac.icf deleted file mode 100644 index b8b7f08..0000000 --- a/components/softdevice/s120/toolchain/iar/iar_s120_nrf51422_xxac.icf +++ /dev/null @@ -1,31 +0,0 @@ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ -/*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x1d000; -/*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x1d000; -define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002800; -define symbol __ICFEDIT_region_RAM_end__ = 0x20007fff; -/*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 0x800; -define symbol __ICFEDIT_size_heap__ = 0x200; -/**** End of ICF editor section. ###ICF###*/ - -define memory mem with size = 4G; -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; - -define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; -define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; - -initialize by copy { readwrite }; -do not initialize { section .noinit }; - -keep { section .intvec }; -place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; -place in ROM_region { readonly }; -place in RAM_region { readwrite, - block CSTACK, - block HEAP }; diff --git a/components/softdevice/s120/toolchain/iar/iar_s120_nrf51822_xxaa.icf b/components/softdevice/s120/toolchain/iar/iar_s120_nrf51822_xxaa.icf deleted file mode 100644 index 48568ea..0000000 --- a/components/softdevice/s120/toolchain/iar/iar_s120_nrf51822_xxaa.icf +++ /dev/null @@ -1,31 +0,0 @@ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ -/*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x1d000; -/*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x1d000; -define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002800; -define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; -/*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 0x800; -define symbol __ICFEDIT_size_heap__ = 0x200; -/**** End of ICF editor section. ###ICF###*/ - -define memory mem with size = 4G; -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; - -define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; -define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; - -initialize by copy { readwrite }; -do not initialize { section .noinit }; - -keep { section .intvec }; -place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; -place in ROM_region { readonly }; -place in RAM_region { readwrite, - block CSTACK, - block HEAP }; diff --git a/components/softdevice/s120/toolchain/iar/iar_s120_nrf51822_xxab.icf b/components/softdevice/s120/toolchain/iar/iar_s120_nrf51822_xxab.icf deleted file mode 100644 index 1f632ab..0000000 --- a/components/softdevice/s120/toolchain/iar/iar_s120_nrf51822_xxab.icf +++ /dev/null @@ -1,31 +0,0 @@ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ -/*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x1d000; -/*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x1d000; -define symbol __ICFEDIT_region_ROM_end__ = 0x1ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002800; -define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; -/*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 0x800; -define symbol __ICFEDIT_size_heap__ = 0x200; -/**** End of ICF editor section. ###ICF###*/ - -define memory mem with size = 4G; -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; - -define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; -define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; - -initialize by copy { readwrite }; -do not initialize { section .noinit }; - -keep { section .intvec }; -place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; -place in ROM_region { readonly }; -place in RAM_region { readwrite, - block CSTACK, - block HEAP }; diff --git a/components/softdevice/s130/doc/s130_nrf51822_1.0.0_licence_agreement.pdf b/components/softdevice/s130/doc/s130_nrf51822_1.0.0_licence_agreement.pdf deleted file mode 100644 index 8f804c0dcfb894350c209001673383302ad0811e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5564 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 S{26r^2nwbZ7S=RE(*74LM~6oM literal 0 HcmV?d00001 diff --git a/components/softdevice/s130/doc/s130_nrf51822_2.0.1_readme.txt b/components/softdevice/s130/doc/s130_nrf51822_2.0.1_readme.txt new file mode 100644 index 0000000..e3a25d5 --- /dev/null +++ b/components/softdevice/s130/doc/s130_nrf51822_2.0.1_readme.txt @@ -0,0 +1,10 @@ +s130_nrf51_2.0.1 + +This release consists of the following: +- This readme file +- The s130_nrf51_2.0.1 API (SoftDevice header files) +- The s130_nrf51_2.0.1 license agreement +- The s130_nrf51_2.0.1 release notes +- The s130_nrf51_2.0.1 SoftDevice (binary hex file) +- The s13x_nrf5x_2.0.1 migration document + diff --git a/components/softdevice/s130/doc/s130_nrf51822_2.0.1_releasenotes.pdf b/components/softdevice/s130/doc/s130_nrf51822_2.0.1_releasenotes.pdf new file mode 100644 index 0000000000000000000000000000000000000000..872446c127907eb173a9b7391b35d4999347c951 GIT binary patch literal 51579 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 R4_yu*E;Je%F?n&c{|6UqUDp5r literal 0 HcmV?d00001 diff --git a/components/softdevice/s130/doc/s130_nrf51822_1.0.0_licence_agreement.txt b/components/softdevice/s130/doc/s130_nrf51_2.0.1_licence_agreement.txt similarity index 71% rename from components/softdevice/s130/doc/s130_nrf51822_1.0.0_licence_agreement.txt rename to components/softdevice/s130/doc/s130_nrf51_2.0.1_licence_agreement.txt index ae8bcfe..09a78bb 100644 --- a/components/softdevice/s130/doc/s130_nrf51822_1.0.0_licence_agreement.txt +++ b/components/softdevice/s130/doc/s130_nrf51_2.0.1_licence_agreement.txt @@ -1,91 +1,96 @@ -S110/S120/S130 license agreement - -NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT - -License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120 and S130 Bluetooth SoftDevice software packages ("SoftDevice"). - -You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before -downloading, installing and/or using any software or content in the SoftDevice provided herewith. - -YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS -OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF -THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. - -IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE -INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. - -1. Grant of License -Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license -("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated -in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this -agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. - -2. Title -Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and -other intellectual property rights in and to the SoftDevice. - -3.No Modifications or Reverse Engineering -Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code -parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. - -4. Distribution Restrictions -Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. -Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. -Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee -necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making -such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. - -5. No Other Rights -Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be -contrary to this Agreement. - -6. Fees -Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to -comply with the Agreement. - -7. DISCLAIMER OF WARRANTY -THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS -LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR -THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE -IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE -REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. -LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S -INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. - -8. No Support -Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, -bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. - -9. Limitation of Liability -In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of -procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any -special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, -tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, -licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or -limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to -USD 50. - -10. Breach of Contract -Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably -attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both -direct and indirect costs for Nordic and its licensors. - -11. Indemnity -Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and -agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which -is not due to causes for which Nordic is responsible. - -12. Governing Law -This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. - -13. Assignment -Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. - -14. Termination -Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this -Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any -other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. - -15. Third party beneficiaries -Nordic’s licensors are intended third party beneficiaries under this Agreement. \ No newline at end of file +S110/S120/S130/S132 license agreement + + +NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT + +License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120, S130 and S132 Bluetooth SoftDevice software packages +("SoftDevice"). + +You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before +downloading, installing and/or using any software or content in the SoftDevice provided herewith. + +YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS +OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF +THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. + +IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE +INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. + +1. Grant of License +Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license +("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated +in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this +agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. + +2. Title +Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and +other intellectual property rights in and to the SoftDevice. + +3. No Modifications or Reverse Engineering +Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code +parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. + +4. Distribution Restrictions +Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. +Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. +Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee +necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making +such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. + +5. No Other Rights +Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be +contrary to this Agreement. + +6. Fees +Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to +comply with the Agreement. + +7. DISCLAIMER OF WARRANTY +THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS +LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR +THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE +IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE +REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. +LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S +INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. + + +8. No Support +Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, +bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. + +9. Limitation of Liability +In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of +procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any +special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, +tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, +licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or +limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to +USD 50. + +10. Breach of Contract +Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably +attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both +direct and indirect costs for Nordic and its licensors. + +11. Indemnity +Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and +agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which +is not due to causes for which Nordic is responsible. + +12. Governing Law +This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. + +13. Assignment +Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. + +14. Termination +Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this +Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any +other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. + +15. Third party beneficiaries +Nordic’s licensors are intended third party beneficiaries under this Agreement. + + diff --git a/components/softdevice/s130/doc/s13x_nrf5x_2.0.1_migration_document.pdf b/components/softdevice/s130/doc/s13x_nrf5x_2.0.1_migration_document.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e8b21fd779093fa5dccab906c3fa3b867a99da8c GIT binary patch literal 45493 zcmd42b#NWslO-tTCuWu`w3sD}nVFfHnVFfHnHeo+W_%)xEoMfqzwX|cnCV}1$85xG z%=@QqWxboXDC(TdJV~w~B1XqV&k9Gre=xTM$4<;hY;R-*$HT)QV`^vaVnNKr$;QSY zW@+PM>ck*sW9VWkVrpz}V#>$o?BZlwA)bRdH4yQVI4WGNgf_zeHvLQC7K zATZFm8>mp%$lBIAj(Z)0ZvT?y^L^WSVPsZJvqFX3PI}w)1rq zbEmdjzXvH#{*y|2d;)#~>E@#c>*bL0daln$$f@=profVYaMmeH9MR3php{1+v46HqA~p@JWdzg>(LxBGdjcF6YPJXk-{yIGmr;u) zMj43mf=vc~f!ys(rN|* zFslI8{}MRuk2GlwWgZkkl8AA_G-Zt)Kiln55PWdlp0vG7#6Qb5(WTQ;ifrP)Y3tJK z8B=mEqX(3F1|1d_w%byQuB2}WP)f8PA3Dc~$M4FZNl4m$u82M4w!LQjIK)mHR^g?z zR8iQmsDEn3MVA~=r9KC!n=r`1tQZ`;G#*hpjg^8GL`Brz53cD!gtTHr6=DkC$=P(- zzv}8biB6nVs;4i6A-~8Jr*`kjI4(vZGFJ7RWJlR>Cg!M?*hx}vJo{Ql@U3hU3dn60 zPl-d4#3C@+hmhr@dLQ2dxE!0z-F3KoF=W5VxpsYvIzL!mlgC>F&=0W3jMn=d5WQ*L zMWuMJUUhV4DgWu$8jKq&qn94E zWNkpeNM2K@!*LO}2}I{HR^Pc@HPSawb)SYPk9PYoA1|r}pje+>eVs9%dc`pIj%lt* zzYuO`PzTm)$356yO(5(-LZ{F|5R58g%9AAJi;8P35r=q^=$#DS#FSMPOynm*TS|Q^ zW^_O6zhcUib`0R6HR`^viCd=L9x+i;ahha1&ulPs)b>*es1n_?tA~_dS}uP3#%?nVRb& zt3jx5(Pr~37tE#QgXK^c8WDlgZ&`qr1g$TX%)%WgH8=CRY`hngi3R|0*mzqVN0eGe zFVo$5*}-#DB_;xn8bD_ermMHHeeZ7P{2)4>l7=Tbs-1jpy0FLb8; zj1uZLliT=hKt?oY_=dKT+lm_7#FV`f_QJ~5+bv5oKi!7H zXHe~6(??dE^iBhd*1nYR4CU*6b?5RoXq^{^9rt`V>yArVCP1cd<&N z4jqYaeukJLV{}DFMH_JmA1OmO8Is9O(r-U7Gv`o-4M=kj;YnfM=!R$@@` zbTDO5Ff=!1P%?G4cXcv0b^Z(53QqRM%BC*F+6;ejotQzz)We0CLDKf`--P~SEBqf@ zNnHl9zaIb25o01|{x_Fm%)~7JK42kc{r3SYG21@_zP~>PSyK~BLm_()ZN|SQHZC@L zW=>*GRwjB*PF+5}f3D-7v*-MK?0+Q?9PIx!ftbu zM$Oo<-xeXM8qTAdI;*3$c5+JgQRHusP){Ts0GS#fqxvJnm+|vRkj%rr%0Af_Tn;y( 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�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 literal 0 HcmV?d00001 diff --git a/components/softdevice/s130/headers/ble.h b/components/softdevice/s130/headers/ble.h index 9edd67c..e90aa13 100644 --- a/components/softdevice/s130/headers/ble.h +++ b/components/softdevice/s130/headers/ble.h @@ -1,26 +1,26 @@ -/* +/* * Copyright (c) Nordic Semiconductor ASA * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. - * + * * 2. 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. - * + * * 3. Neither the name of Nordic Semiconductor ASA nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * 4. This software must only be used in a processor manufactured by Nordic * Semiconductor ASA, or in a processor manufactured by a third party that * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * + * + * * 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 @@ -31,7 +31,7 @@ * 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. - * + * */ /** @@ -55,6 +55,10 @@ #include "ble_gattc.h" #include "ble_gatts.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations * @{ */ @@ -65,7 +69,7 @@ enum BLE_COMMON_SVCS { SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */ SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */ - SD_BLE_TX_BUFFER_COUNT_GET, /**< Get the total number of available application transmission buffers from the BLE stack. */ + SD_BLE_TX_PACKET_COUNT_GET, /**< Get the total number of available application transmission packets for a particular connection. */ SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific UUID. */ SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */ SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */ @@ -75,9 +79,9 @@ enum BLE_COMMON_SVCS SD_BLE_OPT_GET, /**< Get a BLE option. */ }; -/** - * @brief BLE Module Independent Event IDs. - */ + /** + * @brief BLE Module Independent Event IDs. + */ enum BLE_COMMON_EVTS { BLE_EVT_TX_COMPLETE = BLE_EVT_BASE, /**< Transmission Complete. @ref ble_evt_tx_complete_t */ @@ -85,13 +89,26 @@ enum BLE_COMMON_EVTS BLE_EVT_USER_MEM_RELEASE /**< User Memory release. @ref ble_evt_user_mem_release_t */ }; +/**@brief BLE connection bandwidth types. + * Bandwidth types supported by the SoftDevice. The bandwidth type dictates the maximum number of full length packets per connection interval. + */ +enum BLE_CONN_BWS +{ + BLE_CONN_BW_NONE = 0, /**< Invalid connection bandwidth. */ + BLE_CONN_BW_LOW, /**< Low connection bandwidth. */ + BLE_CONN_BW_MID, /**< Medium connection bandwidth. */ + BLE_CONN_BW_HIGH /**< High connection bandwidth. */ +}; + /**@brief Common Option IDs. * IDs that uniquely identify a common option. */ enum BLE_COMMON_OPTS { - BLE_COMMON_OPT_RADIO_CPU_MUTEX = BLE_OPT_BASE /**< Radio CPU mutex option. @ref ble_common_opt_radio_cpu_mutex_t */ + BLE_COMMON_OPT_CONN_BW = BLE_OPT_BASE, /**< Bandwidth configuration @ref ble_common_opt_conn_bw_t */ + BLE_COMMON_OPT_PA_LNA /**< PA and LNA options */ }; + /** @} */ /** @addtogroup BLE_COMMON_DEFINES Defines @@ -107,9 +124,12 @@ enum BLE_COMMON_OPTS #define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */ /** @} */ -/** @brief Maximum number of Vendor Specific UUIDs. -*/ -#define BLE_UUID_VS_MAX_COUNT 10 +/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific UUID counts + * @{ + */ +#define BLE_UUID_VS_COUNT_MIN 1 /**< Minimum VS UUID count. */ +#define BLE_UUID_VS_COUNT_DEFAULT 0 /**< Use the default VS UUID count (10 for this version of the SoftDevice). */ +/** @} */ /** @} */ @@ -148,34 +168,34 @@ typedef struct /**@brief Event structure for events not associated with a specific function module. */ typedef struct { - uint16_t conn_handle; /**< Connection Handle on which this event occurred. */ + uint16_t conn_handle; /**< Connection Handle on which this event occurred. */ union { ble_evt_tx_complete_t tx_complete; /**< Transmission Complete. */ ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */ ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */ - } params; + } params; /**< Event parameter union. */ } ble_common_evt_t; /**@brief BLE Event header. */ typedef struct { - uint16_t evt_id; /**< Value from a BLE__EVT series. */ - uint16_t evt_len; /**< Length in octets excluding this header. */ + uint16_t evt_id; /**< Value from a BLE__EVT series. */ + uint16_t evt_len; /**< Length in octets including this header. */ } ble_evt_hdr_t; /**@brief Common BLE Event type, wrapping the module specific event reports. */ typedef struct { - ble_evt_hdr_t header; /**< Event header. */ + ble_evt_hdr_t header; /**< Event header. */ union { - ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ - ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ - ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ - ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ - ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ - } evt; + ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ + ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ + ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ + ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ + ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ + } evt; /**< Event union. */ } ble_evt_t; @@ -184,53 +204,162 @@ typedef struct */ typedef struct { - uint8_t version_number; /**< Link Layer Version number for BT 4.1 spec is 7 (https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer). */ - uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ - uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ + uint8_t version_number; /**< Link Layer Version number for BT 4.1 spec is 7 (https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer). */ + uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ + uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ } ble_version_t; -/**@brief Mutual exclusion of radio activity and CPU execution. - * - * This option configures the application's access to the CPU when the radio is active. The - * application can configure itself to be blocked from using the CPU while the radio is - * active. By default, the application will be able to share CPU time with the SoftDevice - * during radio activity. This parameter structure is used together with @ref sd_ble_opt_set - * to configure the @ref BLE_COMMON_OPT_RADIO_CPU_MUTEX option. +/** + * @brief Configuration parameters for the PA and LNA. + */ +typedef struct +{ + uint8_t enable :1; /**< Enable toggling for this amplifier */ + uint8_t active_high :1; /**< Set the pin to be active high */ + uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */ +} ble_pa_lna_cfg_t; + +/** + * @brief PA & LNA GPIO toggle configuration * - * @note Note that the application should use this option to configure the SoftDevice to block the - * CPU during radio activity (i.e enable mutual exclusion) when running the SoftDevice on - * hardware affected by PAN #44 "CCM may exceed real time requirements"and PAN #45 "AAR may - * exceed real time requirements". + * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or + * a low noise amplifier. * - * @note Note that when acting as a scanner, the mutex is only enabled for radio TX activity. + * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided + * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. * * @note @ref sd_ble_opt_get is not supported for this option. + * @note This feature is only supported for nRF52, on nRF51 @ref NRF_ERROR_NOT_SUPPORTED will always be returned. + * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences + * and must be avoided by the application. + */ +typedef struct +{ + ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ + ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ + + uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */ + uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ + uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */ +} ble_common_opt_pa_lna_t; + +/** + * @brief BLE connection bandwidth configuration parameters + */ +typedef struct +{ + uint8_t conn_bw_tx; /**< Connection bandwidth configuration for transmission, see @ref BLE_CONN_BWS.*/ + uint8_t conn_bw_rx; /**< Connection bandwidth configuration for reception, see @ref BLE_CONN_BWS.*/ +} ble_conn_bw_t; + +/**@brief BLE connection specific bandwidth configuration parameters. * + * This can be used with @ref sd_ble_opt_set to set the bandwidth configuration to be used when creating connections. + * + * Call @ref sd_ble_opt_set with this option prior to calling @ref sd_ble_gap_adv_start or @ref sd_ble_gap_connect. + * + * The bandwidth configurations set via @ref sd_ble_opt_set are maintained separately for central and peripheral + * connections. The given configurations are used for all future connections of the role indicated in this structure + * unless they are changed by subsequent @ref sd_ble_opt_set calls. + * + * @note When this option is not used, the SoftDevice will use the default options: + * - @ref BLE_CONN_BW_HIGH for @ref BLE_GAP_ROLE_PERIPH connections (both transmission and reception). + * - @ref BLE_CONN_BW_MID for @ref BLE_GAP_ROLE_CENTRAL connections (both transmisison and reception). + * This option allows the application to selectively override these defaults for each role. + * + * @note The global memory pool configuration can be set with the @ref ble_conn_bw_counts_t configuration parameter, which + * is provided to @ref sd_ble_enable. + * + * @note Please refer to SoftDevice Specification for more information on bandwidth configuration. + * + * @mscs + * @mmsc{@ref BLE_COMMON_CONF_BW} + * @endmscs + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::BLE_ERROR_INVALID_ROLE The role is invalid. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid bandwidth configuration parameters. + * @retval ::NRF_ERROR_NOT_SUPPORTED If the combination of role and bandwidth configuration is not supported. */ typedef struct { - uint8_t enable : 1; /**< Enable mutual exclusion of radio activity and the CPU execution. */ -} ble_common_opt_radio_cpu_mutex_t; + uint8_t role; /**< BLE role of the connection, see @ref BLE_GAP_ROLES. */ + ble_conn_bw_t conn_bw; /**< Bandwidth configuration parameters. */ +} ble_common_opt_conn_bw_t; /**@brief Option structure for common options. */ typedef union { - ble_common_opt_radio_cpu_mutex_t radio_cpu_mutex; /**< Parameters for the option for the mutual exclusion of radio activity and CPU execution. */ + ble_common_opt_conn_bw_t conn_bw; /**< Parameters for the connection bandwidth option. */ + ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */ } ble_common_opt_t; /**@brief Common BLE Option type, wrapping the module specific options. */ typedef union { - ble_common_opt_t common_opt; /**< Common option, opt_id in BLE_COMMON_OPT_* series. */ - ble_gap_opt_t gap_opt; /**< GAP option, opt_id in BLE_GAP_OPT_* series. */ + ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */ + ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */ } ble_opt_t; /** - * @brief BLE GATTS init options + * @brief BLE bandwidth count parameters + * + * These parameters are used to configure the memory pools allocated within the SoftDevice for application packets + * (both transmission and reception) for all connections. + * + * @note The sum of all three counts must add up to the sum of @ref ble_gap_enable_params_t::central_conn_count and + * @ref ble_gap_enable_params_t::periph_conn_count in @ref ble_gap_enable_params_t. + */ +typedef struct { + uint8_t high_count; /**< Total number of high bandwidth TX or RX memory pools available to the application at runtime for all active connections. */ + uint8_t mid_count; /**< Total number of medium bandwidth TX or RX memory pools available to the application at runtime for all active connections. */ + uint8_t low_count; /**< Total number of low bandwidth TX or RX memory pools available to the application at runtime for all active connections. */ +} ble_conn_bw_count_t; + +/** + * @brief BLE bandwidth global memory pool configuration parameters + * + * These configuration parameters are used to set the amount of memory dedicated to application packets for + * all connections. The application should specify the most demanding configuration for the intended use. + * + * Please refer to the SoftDevice Specification for more information on bandwidth configuration. + * + * @note Each connection created at runtime requires both a TX and an RX memory pool. By the use of these configuration + * parameters, the application can decide the size and total number of the global memory pools that will be later + * available for connection creation. + * + * @mscs + * @mmsc{@ref BLE_COMMON_CONF_BW} + * @endmscs + * + */ +typedef struct { + ble_conn_bw_count_t tx_counts; /**< Global memory pool configuration for transmission.*/ + ble_conn_bw_count_t rx_counts; /**< Global memory pool configuration for reception.*/ +} ble_conn_bw_counts_t; + +/** + * @brief BLE Common Initialization parameters. + * + * @note If @ref p_conn_bw_counts is NULL the SoftDevice will assume default bandwidth configuration for all connections. + * To fit a custom bandwidth configuration requirement, the application developer may have to specify a custom memory + * pool configuration here. See @ref ble_common_opt_conn_bw_t for bandwidth configuration of individual connections. + * Please refer to the SoftDevice Specification for more information on bandwidth configuration. */ typedef struct { - ble_gatts_enable_params_t gatts_enable_params; /**< GATTS init options @ref ble_gatts_enable_params_t. */ + uint16_t vs_uuid_count; /**< Maximum number of 128-bit, Vendor Specific UUID bases to allocate. */ + ble_conn_bw_counts_t *p_conn_bw_counts; /**< Bandwidth configuration parameters or NULL for defaults. */ +} ble_common_enable_params_t; + +/** + * @brief BLE Initialization parameters. + */ +typedef struct +{ + ble_common_enable_params_t common_enable_params; /**< Common init parameters @ref ble_common_enable_params_t. */ + ble_gap_enable_params_t gap_enable_params; /**< GAP init parameters @ref ble_gap_enable_params_t. */ + ble_gatts_enable_params_t gatts_enable_params; /**< GATTS init parameters @ref ble_gatts_enable_params_t. */ } ble_enable_params_t; /** @} */ @@ -240,39 +369,71 @@ typedef struct /**@brief Enable the BLE stack * - * @param[in] p_ble_enable_params Pointer to ble_enable_params_t + * @param[in, out] p_ble_enable_params Pointer to ble_enable_params_t + * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the application RAM region + * (APP_RAM_BASE). On return, this will contain the minimum start address of the application RAM region required by the + * SoftDevice for this configuration. Calling @ref sd_ble_enable() with *p_app_ram_base set to 0 can be used during + * development to find out how much memory a specific configuration will need. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices with the same major + * version number. + * + * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located between 0x20000000 and + * APP_RAM_BASE-1 and the application's RAM region is located between APP_RAM_BASE and the start of the call stack. * * @details This call initializes the BLE stack, no other BLE related function can be called before this one. * - * @return @ref NRF_SUCCESS BLE the BLE stack has been initialized successfully - * @retval @ref NRF_ERROR_INVALID_STATE the BLE stack had already been initialized and cannot be reinitialized. - * @return @ref NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. - * @return @ref NRF_ERROR_INVALID_LENGTH The specified Attribute Table size is either too small or not a multiple of 4. - * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. - * @return @ref NRF_ERROR_NO_MEM The Attribute Table size is too large. Decrease size in @ref ble_gatts_enable_params_t. + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH The specified Attribute Table size is either too small or not a multiple of 4. + * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. + * @retval ::NRF_ERROR_INVALID_PARAM Incorrectly configured VS UUID count or connection count parameters. + * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by *p_app_ram_base is not + * large enough to fit this configuration's memory requirement. Check *p_app_ram_base + * and set the start address of the application RAM region accordingly. + * @retval ::NRF_ERROR_CONN_COUNT The requested number of connections exceeds the maximum supported by the SoftDevice. + * Please refer to the SoftDevice Specification for more information on role configuration. */ -SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(ble_enable_params_t * p_ble_enable_params)); +SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(ble_enable_params_t * p_ble_enable_params, uint32_t * p_app_ram_base)); /**@brief Get an event from the pending events queue. * - * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. This buffer must be 4-byte aligned in memory. + * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. + * This buffer must be 4-byte aligned in memory. * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. * - * @details This call allows the application to pull a BLE event from the BLE stack. The application is signalled that an event is - * available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. - * The application is free to choose whether to call this function from thread mode (main context) or directly from the Interrupt Service Routine - * that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher priority than the application, this function should be called - * in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. - * Failure to do so could potentially leave events in the internal queue without the application being aware of this fact. - * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to be copied into - * application memory. If the buffer provided is not large enough to fit the entire contents of the event, @ref NRF_ERROR_DATA_SIZE will be returned - * and the application can then call again with a larger buffer size. - * Please note that because of the variable length nature of some events, sizeof(ble_evt_t) will not always be large enough to fit certain events, - * and so it is the application's responsibility to provide an amount of memory large enough so that the relevant event is copied in full. - * The application may "peek" the event length by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return. + * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that + * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. + * The application is free to choose whether to call this function from thread mode (main context) or directly from the + * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher + * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) + * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so + * could potentially leave events in the internal queue without the application being aware of this fact. Sizing the + * p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to + * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event, + * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size. + * Please note that because of the variable length nature of some events, sizeof(ble_evt_t) will not always be large + * enough to fit certain events, and so it is the application's responsibility to provide an amount of memory large + * enough so that the relevant event is copied in full. The application may "peek" the event length by providing p_dest + * as a NULL pointer and inspecting the value of *p_len upon return: + * + * \code + * uint16_t len; + * errcode = sd_ble_evt_get(NULL, &len); + * \endcode * * @note The pointer supplied must be aligned to the extend defined by @ref BLE_EVTS_PTR_ALIGNMENT * + * @mscs + * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC} + * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC} + * @endmscs + * * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. @@ -281,59 +442,61 @@ SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(ble_enable_params_t * p_ble_enable SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); -/**@brief Get the total number of available application transmission buffers per link in the BLE stack. - * - * @details This call allows the application to obtain the total number of - * transmission buffers available per link for application data. Please note that - * this does not give the number of free buffers, but rather the total amount of them. - * The application has two options to handle its own application transmission buffers: - * - Use a simple arithmetic calculation: at boot time the application should use this function - * to find out the total amount of buffers available to it and store it in a variable. - * Every time a packet that consumes an application buffer is sent using any of the - * exposed functions in this BLE API, the application should decrement that variable. - * Conversely, whenever a @ref BLE_EVT_TX_COMPLETE event is received by the application - * it should retrieve the count field in such event and add that number to the same - * variable storing the number of available packets. - * This mechanism allows the application to be aware at any time of the number of - * application packets available in the BLE stack's internal buffers, and therefore - * it can know with certainty whether it is possible to send more data or it has to - * wait for a @ref BLE_EVT_TX_COMPLETE event before it proceeds. - * - Choose to simply not keep track of available buffers at all, and instead handle the - * @ref BLE_ERROR_NO_TX_BUFFERS error by queueing the packet to be transmitted and - * try again as soon as a @ref BLE_EVT_TX_COMPLETE event arrives. - * - * The API functions that may consume an application buffer depending on - * the parameters supplied to them can be found below: - * - * - @ref sd_ble_gattc_write (write without response only) - * - @ref sd_ble_gatts_hvx (notifications only) - * - @ref sd_ble_l2cap_tx (all packets) - * - * @param[out] p_count Pointer to a uint8_t which will contain the number of application transmission buffers upon +/**@brief Get the total number of available guaranteed application transmission packets for a particular connection. + * + * @details This call allows the application to obtain the total number of guaranteed application transmission packets + * available for a connection. Please note that this does not return the number of free packets, but rather the total + * amount of them for that particular connection. The application has two options to handle transmitting application packets: + * - Use a simple arithmetic calculation: after connection creation time the application should use this function to + * find out the total amount of guaranteed packets available to it and store it in a variable. + * Every time a packet is successfully queued for a transmission on this connection using any of the exposed functions in + * this BLE API, the application should decrement that variable. Conversely, whenever a @ref BLE_EVT_TX_COMPLETE event + * with the conn_handle matching the particular connection is received by the application, it should retrieve the count + * field in such event and add that number to the same variable storing the number of available guaranteed packets. This + * mechanism allows the application to be aware at any time of the number of guaranteed application packets available for + * each of the active connections, and therefore it can know with certainty whether it is possible to send more data or + * it has to wait for a @ref BLE_EVT_TX_COMPLETE event before it proceeds. + * The application can still pursue transmissions when the number of guaranteed application packets available is smaller + * than or equal to zero, but successful queuing of the tranmsission is not guaranteed. + * - Choose to simply not keep track of available packets at all, and instead handle the @ref BLE_ERROR_NO_TX_PACKETS error + * by queueing the packet to be transmitted and try again as soon as a @ref BLE_EVT_TX_COMPLETE event arrives. + * + * The API functions that may consume an application packet depending on the parameters supplied to them can be found below: + * - @ref sd_ble_gattc_write (write without response only) + * - @ref sd_ble_gatts_hvx (notifications only) + * - @ref sd_ble_l2cap_tx (all packets) + * + * @param[in] conn_handle Connection handle. + * @param[out] p_count Pointer to a uint8_t which will contain the number of application transmission packets upon * successful return. + * @mscs + * @mmsc{@ref BLE_COMMON_APP_BUFF_MSC} + * @endmscs * - * @retval ::NRF_SUCCESS Number of application transmission buffers retrieved successfully. + * @retval ::NRF_SUCCESS Number of application transmission packets retrieved successfully. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. */ -SVCALL(SD_BLE_TX_BUFFER_COUNT_GET, uint32_t, sd_ble_tx_buffer_count_get(uint8_t *p_count)); +SVCALL(SD_BLE_TX_PACKET_COUNT_GET, uint32_t, sd_ble_tx_packet_count_get(uint16_t conn_handle, uint8_t *p_count)); /**@brief Add a Vendor Specific UUID. * - * @details This call enables the application to add a vendor specific UUID to the BLE stack's table, - * for later use all other modules and APIs. This then allows the application to use the shorter, - * 24-bit @ref ble_uuid_t format when dealing with both 16-bit and 128-bit UUIDs without having to - * check for lengths and having split code paths. The way that this is accomplished is by extending the - * grouping mechanism that the Bluetooth SIG standard base UUID uses for all other 128-bit UUIDs. The - * type field in the @ref ble_uuid_t structure is an index (relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN) - * to the table populated by multiple calls to this function, and the uuid field in the same structure - * contains the 2 bytes at indices 12 and 13. The number of possible 128-bit UUIDs available to the - * application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, - * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. - * - * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by + * @details This call enables the application to add a vendor specific UUID to the BLE stack's table, for later use + * all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t format + * when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code paths. + * The way that this is accomplished is by extending the grouping mechanism that the Bluetooth SIG standard base + * UUID uses for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to + * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the uuid field + * in the same structure contains the 2 bytes at indices 12 and 13. The number of possible 128-bit UUIDs available to + * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, + * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. + * + * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by * the 16-bit uuid field in @ref ble_uuid_t. * + * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in + * p_uuid_type along with an NRF_SUCCESS error code. * * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding * bytes 12 and 13. @@ -342,29 +505,28 @@ SVCALL(SD_BLE_TX_BUFFER_COUNT_GET, uint32_t, sd_ble_tx_buffer_count_get(uint8_t * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID. * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. - * @retval ::NRF_ERROR_FORBIDDEN If p_vs_uuid has already been added to the VS UUID table. */ SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); /** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. - * - * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared - * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add - * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index - * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. + * + * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared + * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add + * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index + * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. * * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. * - * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). - * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. + * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). + * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. * * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. - */ + */ SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); @@ -372,9 +534,9 @@ SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uin * * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. * - * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. - * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). - * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. + * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. + * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). + * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. * * @retval ::NRF_SUCCESS Successfully encoded into the buffer. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. @@ -403,6 +565,15 @@ SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version * @param[in] conn_handle Connection handle. * @param[in,out] p_block Pointer to a user memory block structure. * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @endmscs + * * @retval ::NRF_SUCCESS Successfully queued a response to the peer. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no execute write request pending. @@ -414,7 +585,12 @@ SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_hand * * @details This call allows the application to set the value of an option. * - * @param[in] opt_id Option ID. + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @mmsc{@ref BLE_COMMON_CONF_BW} + * @endmscs + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. * * @retval ::NRF_SUCCESS Option set successfully. @@ -431,7 +607,7 @@ SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const * * @details This call allows the application to retrieve the value of an option. * - * @param[in] opt_id Option ID. + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. * * @retval ::NRF_SUCCESS Option retrieved successfully. @@ -446,7 +622,9 @@ SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); /** @} */ - +#ifdef __cplusplus +} +#endif #endif /* BLE_H__ */ /** diff --git a/components/softdevice/s130/headers/ble_err.h b/components/softdevice/s130/headers/ble_err.h index 1184f24..2332267 100644 --- a/components/softdevice/s130/headers/ble_err.h +++ b/components/softdevice/s130/headers/ble_err.h @@ -54,12 +54,16 @@ #include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + /* @defgroup BLE_ERRORS Error Codes * @{ */ #define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ #define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ #define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ -#define BLE_ERROR_NO_TX_BUFFERS (NRF_ERROR_STK_BASE_NUM+0x004) /**< Buffer capacity exceeded. */ +#define BLE_ERROR_NO_TX_PACKETS (NRF_ERROR_STK_BASE_NUM+0x004) /**< Not enough application packets available on this connection. */ #define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */ /** @} */ @@ -74,6 +78,9 @@ #define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ /** @} */ +#ifdef __cplusplus +} +#endif #endif diff --git a/components/softdevice/s130/headers/ble_gap.h b/components/softdevice/s130/headers/ble_gap.h index 5cc4df1..ad0fd30 100644 --- a/components/softdevice/s130/headers/ble_gap.h +++ b/components/softdevice/s130/headers/ble_gap.h @@ -1,26 +1,26 @@ -/* +/* * Copyright (c) Nordic Semiconductor ASA * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. - * + * * 2. 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. - * + * * 3. Neither the name of Nordic Semiconductor ASA nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * 4. This software must only be used in a processor manufactured by Nordic * Semiconductor ASA, or in a processor manufactured by a third party that * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * + * + * * 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 @@ -31,7 +31,7 @@ * 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. - * + * */ /** @@ -47,6 +47,10 @@ #include "ble_ranges.h" #include "nrf_svc.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@addtogroup BLE_GAP_ENUMERATIONS Enumerations * @{ */ @@ -71,11 +75,15 @@ enum BLE_GAP_SVCS SD_BLE_GAP_AUTHENTICATE, /**< Initiate Pairing/Bonding. */ SD_BLE_GAP_SEC_PARAMS_REPLY, /**< Reply with Security Parameters. */ SD_BLE_GAP_AUTH_KEY_REPLY, /**< Reply with an authentication key. */ + SD_BLE_GAP_LESC_DHKEY_REPLY, /**< Reply with an LE Secure Connections DHKey. */ + SD_BLE_GAP_KEYPRESS_NOTIFY, /**< Notify of a keypress during an authentication procedure. */ + SD_BLE_GAP_LESC_OOB_DATA_GET, /**< Get the local LE Secure Connections OOB data. */ + SD_BLE_GAP_LESC_OOB_DATA_SET, /**< Set the remote LE Secure Connections OOB data. */ SD_BLE_GAP_ENCRYPT, /**< Initiate encryption procedure. */ SD_BLE_GAP_SEC_INFO_REPLY, /**< Reply with Security Information. */ SD_BLE_GAP_CONN_SEC_GET, /**< Obtain connection security level. */ - SD_BLE_GAP_RSSI_START, /**< Start reporting of changes in RSSI. */ - SD_BLE_GAP_RSSI_STOP, /**< Stop reporting of changes in RSSI. */ + SD_BLE_GAP_RSSI_START, /**< Start reporting of changes in RSSI. */ + SD_BLE_GAP_RSSI_STOP, /**< Stop reporting of changes in RSSI. */ SD_BLE_GAP_SCAN_START, /**< Start Scanning. */ SD_BLE_GAP_SCAN_STOP, /**< Stop Scanning. */ SD_BLE_GAP_CONNECT, /**< Connect. */ @@ -88,21 +96,23 @@ enum BLE_GAP_SVCS */ enum BLE_GAP_EVTS { - BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connection established. @ref ble_gap_evt_connected_t */ - BLE_GAP_EVT_DISCONNECTED, /**< Disconnected from peer. @ref ble_gap_evt_disconnected_t */ - BLE_GAP_EVT_CONN_PARAM_UPDATE, /**< Connection Parameters updated. ble_gap_evt_conn_param_update_t */ - BLE_GAP_EVT_SEC_PARAMS_REQUEST, /**< Request to provide security parameters. @ref ble_gap_evt_sec_params_request_t */ - BLE_GAP_EVT_SEC_INFO_REQUEST, /**< Request to provide security information. @ref ble_gap_evt_sec_info_request_t */ - BLE_GAP_EVT_PASSKEY_DISPLAY, /**< Request to display a passkey to the user. @ref ble_gap_evt_passkey_display_t */ - BLE_GAP_EVT_AUTH_KEY_REQUEST, /**< Request to provide an authentication key. @ref ble_gap_evt_auth_key_request_t */ - BLE_GAP_EVT_AUTH_STATUS, /**< Authentication procedure completed with status. @ref ble_gap_evt_auth_status_t */ - BLE_GAP_EVT_CONN_SEC_UPDATE, /**< Connection security updated. @ref ble_gap_evt_conn_sec_update_t */ - BLE_GAP_EVT_TIMEOUT, /**< Timeout expired. @ref ble_gap_evt_timeout_t */ - BLE_GAP_EVT_RSSI_CHANGED, /**< RSSI report. @ref ble_gap_evt_rssi_changed_t */ - BLE_GAP_EVT_ADV_REPORT, /**< Advertising report. @ref ble_gap_evt_adv_report_t */ - BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. @ref ble_gap_evt_sec_request_t */ - BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. @ref ble_gap_evt_conn_param_update_request_t */ - BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_evt_scan_req_report_t */ + BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connection established. \n See @ref ble_gap_evt_connected_t. */ + BLE_GAP_EVT_DISCONNECTED, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */ + BLE_GAP_EVT_SEC_PARAMS_REQUEST, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */ + BLE_GAP_EVT_SEC_INFO_REQUEST, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */ + BLE_GAP_EVT_PASSKEY_DISPLAY, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */ + BLE_GAP_EVT_KEY_PRESSED, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */ + BLE_GAP_EVT_AUTH_KEY_REQUEST, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */ + BLE_GAP_EVT_LESC_DHKEY_REQUEST, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */ + BLE_GAP_EVT_AUTH_STATUS, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */ + BLE_GAP_EVT_CONN_SEC_UPDATE, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */ + BLE_GAP_EVT_TIMEOUT, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */ + BLE_GAP_EVT_RSSI_CHANGED, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */ + BLE_GAP_EVT_ADV_REPORT, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */ + BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */ + BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */ }; /**@brief GAP Option IDs. @@ -117,6 +127,7 @@ enum BLE_GAP_OPTS BLE_GAP_OPT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_opt_scan_req_report_t */ BLE_GAP_OPT_COMPAT_MODE /**< Compatibility mode. @ref ble_gap_opt_compat_mode_t */ }; + /** @} */ /**@addtogroup BLE_GAP_DEFINES Defines @@ -127,7 +138,7 @@ enum BLE_GAP_OPTS #define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ #define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ #define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ -#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to overwrite the whitelist while already in use by another operation. */ +#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to overwrite the whitelist while already in use by another operation. */ /**@} */ @@ -195,13 +206,14 @@ enum BLE_GAP_OPTS #define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */ #define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */ #define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */ -#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ +#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */ #define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */ #define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */ #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */ #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ #define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ #define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ +#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */ #define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ #define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ /**@} */ @@ -293,7 +305,6 @@ enum BLE_GAP_OPTS #define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */ /**@} */ - /**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types * @{ */ #define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */ @@ -301,6 +312,15 @@ enum BLE_GAP_OPTS #define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ /**@} */ +/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types + * @{ */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */ +/**@} */ + /**@defgroup BLE_GAP_SEC_STATUS GAP Security status * @{ */ #define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ @@ -318,7 +338,11 @@ enum BLE_GAP_OPTS #define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ #define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ #define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ -#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8B /**< Reserved for Future Use range #2 begin. */ +#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */ +#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */ +#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */ +#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */ #define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */ /**@} */ @@ -330,10 +354,10 @@ enum BLE_GAP_OPTS /**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits * @{ */ -#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connction interval specified in connect parameters. */ -#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest mimimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ #define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connction interval specified in connect parameters. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */ #define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ #define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ #define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ @@ -354,17 +378,19 @@ enum BLE_GAP_OPTS * See @ref ble_gap_conn_sec_mode_t. * @{ */ /**@brief Set sec_mode pointed to by ptr to have no access rights.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) /**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) /**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) /**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) +/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0) /**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) /**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) /**@} */ @@ -374,6 +400,12 @@ enum BLE_GAP_OPTS /**@brief GAP Security Key Length. */ #define BLE_GAP_SEC_KEY_LEN 16 +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */ +#define BLE_GAP_LESC_P256_PK_LEN 64 + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */ +#define BLE_GAP_LESC_DHKEY_LEN 32 + /**@brief GAP Passkey Length. */ #define BLE_GAP_PASSKEY_LEN 6 @@ -389,12 +421,21 @@ enum BLE_GAP_OPTS * @{ */ #define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ /**@} */ - -/**@} */ +/** @} */ /**@addtogroup BLE_GAP_STRUCTURES Structures * @{ */ +/** + * @brief BLE GAP initialization parameters. + */ +typedef struct +{ + uint8_t periph_conn_count; /**< Number of connections acting as a peripheral */ + uint8_t central_conn_count; /**< Number of connections acting as a central */ + uint8_t central_sec_count; /**< Number of SMP instances for all connections acting as a central. */ +} ble_gap_enable_params_t; + /**@brief Bluetooth Low Energy address. */ typedef struct { @@ -429,13 +470,14 @@ typedef struct * Security Mode 1 Level 1: No security is needed (aka open link).\n * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n * Security Mode 1 Level 3: MITM protected encrypted link required.\n + * Security Mode 1 Level 4: LESC MITM protected encrypted link required.\n * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n */ typedef struct { uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ - uint8_t lv : 4; /**< Level (1, 2 or 3), 0 for no permissions at all. */ + uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */ } ble_gap_conn_sec_mode_t; @@ -464,7 +506,7 @@ typedef struct uint8_t irk_count; /**< Count of IRKs in array, up to @ref BLE_GAP_WHITELIST_IRK_MAX_COUNT. */ } ble_gap_whitelist_t; -/**@brief Channel mask for RF channels used in advertising and scanning. */ +/**@brief Channel mask for RF channels used in advertising. */ typedef struct { uint8_t ch_37_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 37 */ @@ -483,7 +525,7 @@ typedef struct - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for high duty cycle directed advertising. - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, set @ref BLE_GAP_ADV_INTERVAL_MIN <= interval <= @ref BLE_GAP_ADV_INTERVAL_MAX for low duty cycle advertising.*/ uint16_t timeout; /**< Advertising timeout between 0x0001 and 0x3FFF in seconds, 0x0000 disables timeout. See also @ref BLE_GAP_ADV_TIMEOUT_VALUES. If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for High duty cycle directed advertising. */ - ble_gap_adv_ch_mask_t channel_mask; /**< Advertising channel mask. @see ble_gap_channel_mask_t for documentation. */ + ble_gap_adv_ch_mask_t channel_mask; /**< Advertising channel mask. See @ref ble_gap_adv_ch_mask_t. */ } ble_gap_adv_params_t; @@ -505,20 +547,23 @@ typedef struct uint8_t enc : 1; /**< Long Term Key and Master Identification. */ uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ uint8_t sign : 1; /**< Connection Signature Resolving Key. */ + uint8_t link : 1; /**< Derive the Link Key from the LTK. */ } ble_gap_sec_kdist_t; /**@brief GAP security parameters. */ typedef struct { - uint8_t bond : 1; /**< Perform bonding. */ - uint8_t mitm : 1; /**< Man In The Middle protection required. */ - uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ - uint8_t oob : 1; /**< Out Of Band data available. */ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Enable Man In The Middle protection. */ + uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */ + uint8_t keypress : 1; /**< Enable generation of keypress notifications. */ + uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ + uint8_t oob : 1; /**< Out Of Band data available. */ uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ - ble_gap_sec_kdist_t kdist_periph; /**< Key distribution bitmap: keys that the peripheral device will distribute. */ - ble_gap_sec_kdist_t kdist_central; /**< Key distribution bitmap: keys that the central device will distribute. */ + ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */ + ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */ } ble_gap_sec_params_t; @@ -526,8 +571,9 @@ typedef struct typedef struct { uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ + uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */ uint8_t auth : 1; /**< Authenticated Key. */ - uint8_t ltk_len : 7; /**< LTK length in octets. */ + uint8_t ltk_len : 6; /**< LTK length in octets. */ } ble_gap_enc_info_t; @@ -545,6 +591,25 @@ typedef struct uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */ } ble_gap_sign_info_t; +/**@brief GAP LE Secure Connections P-256 Public Key. */ +typedef struct +{ + uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */ +} ble_gap_lesc_p256_pk_t; + +/**@brief GAP LE Secure Connections DHKey. */ +typedef struct +{ + uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */ +} ble_gap_lesc_dhkey_t; + +/**@brief GAP LE Secure Connections OOB data. */ +typedef struct +{ + ble_gap_addr_t addr; /**< Bluetooth address of the device. */ + uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */ + uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */ +} ble_gap_lesc_oob_data_t; /**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */ typedef struct @@ -594,8 +659,17 @@ typedef struct typedef struct { uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ + uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply + with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or + @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */ } ble_gap_evt_passkey_display_t; +/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */ +typedef struct +{ + uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */ +} ble_gap_evt_key_pressed_t; + /**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */ typedef struct @@ -603,15 +677,24 @@ typedef struct uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ } ble_gap_evt_auth_key_request_t; +/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */ +typedef struct +{ + ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory + inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */ + uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */ +} ble_gap_evt_lesc_dhkey_request_t; + /**@brief Security levels supported. - * @note See Bluetooth Specification Version 4.1 Volume 3, Part C, Chapter 10. + * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1. */ typedef struct { uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ + uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */ } ble_gap_sec_levels_t; @@ -634,19 +717,19 @@ typedef struct /**@brief Security Keys. */ typedef struct { - ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ - ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ - ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ + ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ + ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ + ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ + ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined + in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */ } ble_gap_sec_keys_t; -/**@brief Security key set (both Peripheral and Central keys). - * Note that when distributing Bluetooth addresses pertaining to the local device those - * will have to be filled in by the user. */ +/**@brief Security key set for both local and peer keys. */ typedef struct { - ble_gap_sec_keys_t keys_periph; /**< Keys distributed by the device in the Peripheral role. */ - ble_gap_sec_keys_t keys_central; /**< Keys distributed by the device in the Central role. */ + ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */ + ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */ } ble_gap_sec_keyset_t; @@ -658,8 +741,8 @@ typedef struct uint8_t bonded : 1; /**< Procedure resulted in a bond. */ ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ - ble_gap_sec_kdist_t kdist_periph; /**< Bitmap stating which keys were exchanged (distributed) by the peripheral. */ - ble_gap_sec_kdist_t kdist_central; /**< Bitmap stating which keys were exchanged (distributed) by the central. */ + ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */ + ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */ } ble_gap_evt_auth_status_t; @@ -699,8 +782,10 @@ typedef struct /**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */ typedef struct { - uint8_t bond : 1; /**< Perform bonding. */ - uint8_t mitm : 1; /**< Man In The Middle protection required. */ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Man In The Middle protection requested. */ + uint8_t lesc : 1; /**< LE Secure Connections requested. */ + uint8_t keypress : 1; /**< Generation of keypress notifications requested. */ } ble_gap_evt_sec_request_t; @@ -723,7 +808,7 @@ typedef struct /**@brief GAP event structure. */ typedef struct { - uint16_t conn_handle; /**< Connection Handle on which event occured. */ + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ union /**< union alternative identified by evt_id in enclosing struct. */ { ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ @@ -732,7 +817,9 @@ typedef struct ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ + ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */ ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ + ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */ ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ @@ -829,12 +916,12 @@ typedef struct * - A private address refresh cycle. * * @note The specified address cycle interval is used when the address cycle mode is - * @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO. If 0 is given, the address will not be automatically + * @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO. If 0 is given, the address will not be automatically * refreshed at all. The default interval is @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. * * @note If the current address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO, the address will immediately be * refreshed when a custom privacy option is set. A new address can be generated manually by calling - * @ref sd_ble_gap_address_set with the same type again. + * @ref sd_ble_gap_address_set with the same type again. * * @note If the IRK is updated, the new IRK becomes the one to be distributed in all * bonding procedures performed after @ref sd_ble_opt_set returns. @@ -872,7 +959,7 @@ typedef struct * This can be used with @ref sd_ble_opt_set to enable and disable * compatibility modes. Compatibility modes are disabled by default. * - * @note Compatibility mode 1 enables interoperability with devices that do not support + * @note Compatibility mode 1 enables interoperability with devices that do not support * a value of 0 for the WinOffset parameter in the Link Layer CONNECT_REQ packet. * * @retval ::NRF_SUCCESS Set successfully. @@ -883,7 +970,6 @@ typedef struct uint8_t mode_1_enable : 1; /**< Enable compatibility mode 1.*/ } ble_gap_opt_compat_mode_t; - /**@brief Option structure for GAP options. */ typedef union { @@ -905,7 +991,7 @@ typedef union * @note If the address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO, the address type is required to * be @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or * @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. The given address is ignored and the - * SoftDevice will generate a new private address automatically every + * SoftDevice will generate a new private address automatically every * @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S seconds. If this API * call is used again with the same parameters, the SoftDevice will immediately * generate a new private address to replace the current address. @@ -914,6 +1000,10 @@ typedef union * @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC address, the cycle mode must be * @ref BLE_GAP_ADDR_CYCLE_MODE_NONE. * + * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being + * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged + * for the lifetime of each IC. + * * @note If this API function is called while advertising or scanning, the softdevice will immediately update the * advertising or scanning address without the need to stop the procedure in the following cases: * - If the previously set address is of type @ref BLE_GAP_ADDR_TYPE_PUBLIC and the new address @@ -928,6 +1018,10 @@ typedef union * using privacy, the application must take care to generate and set new private addresses * periodically to comply with the Privacy specification in Bluetooth Core Spec. * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @endmscs + * * @param[in] addr_cycle_mode Address cycle mode, see @ref BLE_GAP_ADDR_CYCLE_MODES. * @param[in] p_addr Pointer to address structure. * @@ -938,7 +1032,7 @@ typedef union * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. */ -SVCALL(SD_BLE_GAP_ADDRESS_SET, uint32_t, sd_ble_gap_address_set(uint8_t addr_cycle_mode, const ble_gap_addr_t *p_addr)); +SVCALL(SD_BLE_GAP_ADDRESS_SET, uint32_t, sd_ble_gap_address_set(uint8_t addr_cycle_mode, ble_gap_addr_t const *p_addr)); /**@brief Get local Bluetooth address. @@ -955,19 +1049,25 @@ SVCALL(SD_BLE_GAP_ADDRESS_GET, uint32_t, sd_ble_gap_address_get(ble_gap_addr_t * * * @note The format of the advertising data will be checked by this call to ensure interoperability. * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and - * duplicating the local name in the advertising data and scan response data. + * duplicating the local name in the advertising data and scan response data. * - * @note To clear the advertising data and set it to a 0-length packet, simply provide a valid pointer (p_data/p_sr_data) with its corresponding + * @note To clear the advertising data and set it to a 0-length packet, simply provide a valid pointer (p_data/p_sr_data) with its corresponding * length (dlen/srdlen) set to 0. * * @note The call will fail if p_data and p_sr_data are both NULL since this would have no effect. * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * * @param[in] p_data Raw data to be placed in advertising packet. If NULL, no changes are made to the current advertising packet data. * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_data is NULL, can be 0 if p_data is not NULL. * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, no changes are made to the current scan response packet data. * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL. * * @retval ::NRF_SUCCESS Advertising data successfully updated or cleared. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, both p_data and p_sr_data cannot be NULL. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied, check the advertising data format specification. @@ -988,21 +1088,41 @@ SVCALL(SD_BLE_GAP_ADV_DATA_SET, uint32_t, sd_ble_gap_adv_data_set(uint8_t const * * @note To use the currently active whitelist set p_adv_params->p_whitelist to NULL. * + * @events + * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Advertisement has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * * @param[in] p_adv_params Pointer to advertising parameters structure. * * @retval ::NRF_SUCCESS The BLE stack has started advertising. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started. + * @retval ::NRF_ERROR_NO_MEM The configured memory pools (see @ref ble_conn_bw_counts_t) are not large enough for the + * bandwidth selected for this connection. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check the accepted ranges and limits. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Bluetooth address supplied. * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE Unable to replace the whitelist while another operation is using it. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Observer) and try again */ SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params)); /**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs * * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in advertising state). @@ -1019,6 +1139,18 @@ SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(void)); * * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. * + * @events + * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CPU_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, * the parameters in the PPCP characteristic of the GAP service will be used instead. @@ -1040,6 +1172,14 @@ SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint * @details This call initiates the disconnection procedure, and its completion will be communicated to the application * with a @ref BLE_GAP_EVT_DISCONNECTED event. * + * @events + * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CONN_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE). * @@ -1055,7 +1195,8 @@ SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_hand * * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm). * - * @note -40 dBm will not actually give -40 dBm, but will instead be remapped to -30 dBm. + * @note The -30dBm setting is only available on nRF51 series ICs. + * @note The -40dBm setting is only available on nRF52 series ICs. * * @retval ::NRF_SUCCESS Successfully changed the transmit power. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. @@ -1119,15 +1260,15 @@ SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_ /**@brief Get GAP device name. - * - * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. - * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. * * @note If the device name is longer than the size of the supplied buffer, * p_len will return the complete device name length, * and not the number of bytes actually returned in p_dev_name. * The application may use this information to allocate a suitable buffer size. * + * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. + * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. + * * @retval ::NRF_SUCCESS GAP device name retrieved successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. @@ -1137,65 +1278,137 @@ SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t /**@brief Initiate the GAP Authentication procedure. * - * @param[in] conn_handle Connection handle. - * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. - * In the peripheral role, only the timeout, bond and mitm fields of this structure are used. - * In the central role, this pointer may be NULL to reject a Security Request. - * - * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), + * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), * otherwise in the peripheral role, an SMP Security Request will be sent. * - * @note Calling this function may result in the following events depending on the outcome and parameters: @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, - * @ref BLE_GAP_EVT_SEC_INFO_REQUEST, @ref BLE_GAP_EVT_AUTH_KEY_REQUEST, @ref BLE_GAP_EVT_CONN_SEC_UPDATE, @ref BLE_GAP_EVT_AUTH_STATUS. + * @events + * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:} + * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST} + * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST} + * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY} + * @event{@ref BLE_GAP_EVT_KEY_PRESSED} + * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST} + * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST} + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE} + * @event{@ref BLE_GAP_EVT_AUTH_STATUS} + * @event{@ref BLE_GAP_EVT_TIMEOUT} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs * + * @param[in] conn_handle Connection handle. + * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. + * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used. + * In the central role, this pointer may be NULL to reject a Security Request. * * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_TIMEOUT A SMP timout has occured, and further SMP operations on this link is prohibited. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited. */ SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); /**@brief Reply with GAP security parameters. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have * already been provided during a previous call to @ref sd_ble_gap_authenticate. - * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys distributed as a result of the ongoing security procedure + * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. - * The pointer to the ID key data distributed by the local device constitutes however an exception. It can either point to ID key data - * filled in by the user before calling this function, in which case a user-supplied Bluetooth address and IRK will be distributed, - * or the pointer to the ID key data structure can be NULL, in which case the device's configured (or default, if none is configured) - * Bluetooth address and IRK will be distributed. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * Note that the SoftDevice expects the application to provide memory for storing the + * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key + * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the + * @ref BLE_GAP_EVT_AUTH_STATUS event. * * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. */ SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); /**@brief Reply with an authentication key. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. - * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination). - * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in Little Endian format. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination) + * or NULL when confirming LE Secure Connections Numeric Comparison. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in Little Endian format. * * @retval ::NRF_SUCCESS Authentication key successfully set. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. @@ -1205,16 +1418,123 @@ SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16 */ SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); +/**@brief Reply with an LE Secure connections DHKey. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dhkey LE Secure Connections DHKey. + * + * @retval ::NRF_SUCCESS DHKey successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)); -/**@brief Initiate GAP Encryption procedure. +/**@brief Notify the peer of a local keypress. + * + * @details This function can only be used when an authentication procedure using LE Secure Connection is in progress. Calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. - * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. - * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. + * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES. + * + * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either not entering a passkey or keypresses have not been enabled by both peers. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. + */ +SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not)); + +/**@brief Generate a set of OOB data to send to a peer out of band. + * + * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established, + * the one used during connection setup). The application may manually overwrite it with an updated value. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Can be BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet. + * @param[in] p_pk_own LE Secure Connections local P-256 Public Key. + * @param[out] p_oobd_own The OOB data to be sent out of band to a peer. + * + * @retval ::NRF_SUCCESS OOB data successfully generated. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own)); + +/**@brief Provide the OOB data sent/received out of band. + * + * @note At least one of the 2 pointers provided must be different from NULL. + * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function. + * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if none sent. + * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received. + * + * @retval ::NRF_SUCCESS OOB data accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer)); + +/**@brief Initiate GAP Encryption procedure. * * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. * - * @note Calling this function may result in the following event depending on the outcome and parameters: @ref BLE_GAP_EVT_CONN_SEC_UPDATE. + * @events + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. * * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. @@ -1227,16 +1547,20 @@ SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, bl /**@brief Reply with GAP security information. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available. * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available. * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. - * * @retval ::NRF_SUCCESS Successfully accepted security information. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. @@ -1257,10 +1581,21 @@ SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t c SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec)); -/**@brief Start reporting the received signal strength to the application. +/**@brief Start reporting the received signal strength to the application. * * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. * + * @events + * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is + dependent on the settings of the threshold_dbm + and skip_count input parameters.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID. * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event. @@ -1274,9 +1609,14 @@ SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_hand /**@brief Stop reporting the received signal strength. * - * @note An RSSI change detected before the call but not yet received by the application + * @note An RSSI change detected before the call but not yet received by the application * may be reported after @ref sd_ble_gap_rssi_stop has been called. * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. @@ -1287,13 +1627,17 @@ SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle /**@brief Get the received signal strength for the last connection event. - * - * @param[in] conn_handle Connection handle. - * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. * * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start. * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. + * * @retval ::NRF_SUCCESS Successfully read the RSSI. * @retval ::NRF_ERROR_NOT_FOUND No sample is available. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. @@ -1307,6 +1651,16 @@ SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, * * @note To use the currently active whitelist set p_scan_params->p_whitelist to NULL. * + * @events + * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * * @param[in] p_scan_params Pointer to scan parameters structure. * * @retval ::NRF_SUCCESS Successfully initiated scanning procedure. @@ -1315,11 +1669,18 @@ SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE Unable to replace the whitelist while another operation is using it. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again */ SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params)); /**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs * * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in scanning state). @@ -1329,7 +1690,13 @@ SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); /**@brief Create a connection (GAP Link Establishment). * - * @note To use the currently active whitelist set p_scan_params->p_whitelist to NULL. + * @note To use the currently active whitelist set p_scan_params->p_whitelist to NULL. + * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function. + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs * * @param[in] p_peer_addr Pointer to peer address. If the selective bit is set in @ref ble_gap_scan_params_t, then this must be NULL. * @param[in] p_scan_params Pointer to scan parameters structure. @@ -1340,15 +1707,23 @@ SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. - * @retval ::NRF_ERROR_NO_MEM limit of available connections reached. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. If another connection is being established wait for the corresponding - * @ref BLE_GAP_EVT_CONNECTED event before calling again. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached. + * @retval ::NRF_ERROR_NO_MEM The configured memory pool (see @ref ble_conn_bw_counts_t) is not large enough for the + * bandwidth selected for this connection. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. If another connection is being established + * wait for the corresponding @ref BLE_GAP_EVT_CONNECTED event before calling again. * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE Unable to replace the whitelist while another operation is using it. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again */ SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params)); /**@brief Cancel a connection establishment. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs * * @retval ::NRF_SUCCESS Successfully cancelled an ongoing connection procedure. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. @@ -1357,6 +1732,9 @@ SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); /** @} */ +#ifdef __cplusplus +} +#endif #endif // BLE_GAP_H__ /** diff --git a/components/softdevice/s130/headers/ble_gatt.h b/components/softdevice/s130/headers/ble_gatt.h index cb8a67b..4813ba0 100644 --- a/components/softdevice/s130/headers/ble_gatt.h +++ b/components/softdevice/s130/headers/ble_gatt.h @@ -46,6 +46,9 @@ #include "ble_types.h" #include "ble_ranges.h" +#ifdef __cplusplus +extern "C" { +#endif /** @addtogroup BLE_GATT_DEFINES Defines * @{ */ @@ -60,6 +63,12 @@ /**@brief Invalid Attribute Handle. */ #define BLE_GATT_HANDLE_INVALID 0x0000 +/**@brief First Attribute Handle. */ +#define BLE_GATT_HANDLE_START 0x0001 + +/**@brief Last Attribute Handle. */ +#define BLE_GATT_HANDLE_END 0xFFFF + /** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources * @{ */ #define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ @@ -77,8 +86,8 @@ /** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags * @{ */ -#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 -#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */ /** @} */ /** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations @@ -190,6 +199,9 @@ typedef struct uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */ } ble_gatt_char_ext_props_t; +#ifdef __cplusplus +} +#endif #endif // BLE_GATT_H__ /** @} */ diff --git a/components/softdevice/s130/headers/ble_gattc.h b/components/softdevice/s130/headers/ble_gattc.h index 57ce312..902460c 100644 --- a/components/softdevice/s130/headers/ble_gattc.h +++ b/components/softdevice/s130/headers/ble_gattc.h @@ -48,6 +48,10 @@ #include "ble_ranges.h" #include "nrf_svc.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations * @{ */ @@ -58,11 +62,12 @@ enum BLE_GATTC_SVCS SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ + SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */ SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ SD_BLE_GATTC_READ, /**< Generic read. */ SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ SD_BLE_GATTC_WRITE, /**< Generic write. */ - SD_BLE_GATTC_HV_CONFIRM /**< Handle Value Confirmation. */ + SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */ }; /** @@ -70,16 +75,17 @@ enum BLE_GATTC_SVCS */ enum BLE_GATTC_EVTS { - BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. @ref ble_gattc_evt_prim_srvc_disc_rsp_t */ - BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. @ref ble_gattc_evt_rel_disc_rsp_t */ - BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. @ref ble_gattc_evt_char_disc_rsp_t */ - BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. @ref ble_gattc_evt_desc_disc_rsp_t */ - BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t */ - BLE_GATTC_EVT_READ_RSP, /**< Read Response event. @ref ble_gattc_evt_read_rsp_t */ - BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. @ref ble_gattc_evt_char_vals_read_rsp_t */ - BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. @ref ble_gattc_evt_write_rsp_t */ - BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. @ref ble_gattc_evt_hvx_t */ - BLE_GATTC_EVT_TIMEOUT /**< Timeout event. @ref ble_gattc_evt_timeout_t */ + BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */ + BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */ + BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */ + BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */ + BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */ + BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */ + BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */ + BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */ + BLE_GATTC_EVT_TIMEOUT /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */ }; /** @} */ @@ -92,8 +98,11 @@ enum BLE_GATTC_EVTS #define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ /** @} */ -/**@brief Last Attribute Handle. */ -#define BLE_GATTC_HANDLE_END 0xFFFF +/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats + * @{ */ +#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */ +#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */ +/** @} */ /** @} */ @@ -154,34 +163,57 @@ typedef struct uint8_t *p_value; /**< Pointer to the value data. */ } ble_gattc_write_params_t; +/**@brief Attribute Information. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + union { + ble_uuid_t uuid16; /**< 16-bit Attribute UUID. */ + ble_uuid128_t uuid128; /**< 128-bit Attribute UUID. */ + } info; /**< Attribute information union. */ +} ble_gattc_attr_info_t; + /**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ typedef struct { uint16_t count; /**< Service count. */ - ble_gattc_service_t services[1]; /**< Service data, variable length. */ + ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_prim_srvc_disc_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ typedef struct { uint16_t count; /**< Include count. */ - ble_gattc_include_t includes[1]; /**< Include data, variable length. */ + ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_rel_disc_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ typedef struct { uint16_t count; /**< Characteristic count. */ - ble_gattc_char_t chars[1]; /**< Characteristic data, variable length. */ + ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_char_disc_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ typedef struct { uint16_t count; /**< Descriptor count. */ - ble_gattc_desc_t descs[1]; /**< Descriptor data, variable length. */ + ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_desc_disc_rsp_t; +/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Attribute count. */ + uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */ + ble_gattc_attr_info_t attr_info[1]; /**< Attribute information. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ +} ble_gattc_evt_attr_info_disc_rsp_t; + /**@brief GATT read by UUID handle value pair. */ typedef struct { @@ -196,7 +228,8 @@ typedef struct { uint16_t count; /**< Handle-Value Pair Count. */ uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ - ble_gattc_handle_value_t handle_value[1]; /**< Handle-Value(s) list, variable length. */ + ble_gattc_handle_value_t handle_value[1]; /**< Handle-Value(s) list. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_char_val_by_uuid_read_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ @@ -205,14 +238,16 @@ typedef struct uint16_t handle; /**< Attribute Handle. */ uint16_t offset; /**< Offset of the attribute data. */ uint16_t len; /**< Attribute data length. */ - uint8_t data[1]; /**< Attribute data, variable length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_read_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ typedef struct { uint16_t len; /**< Concatenated Attribute values length. */ - uint8_t values[1]; /**< Attribute values, variable length. */ + uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_char_vals_read_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ @@ -222,7 +257,8 @@ typedef struct uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ uint16_t offset; /**< Data offset. */ uint16_t len; /**< Data length. */ - uint8_t data[1]; /**< Data, variable length. */ + uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_write_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ @@ -231,7 +267,8 @@ typedef struct uint16_t handle; /**< Handle to which the HVx operation applies. */ uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ uint16_t len; /**< Attribute data length. */ - uint8_t data[1]; /**< Attribute data, variable length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_hvx_t; /**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ @@ -258,6 +295,7 @@ typedef struct ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */ } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ } ble_gattc_evt_t; /** @} */ @@ -273,6 +311,14 @@ typedef struct * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. * + * @events + * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] start_handle Handle to start searching from. * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. @@ -291,6 +337,14 @@ SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_se * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached, * this must be called again with an updated handle range to continue the search. * + * @events + * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_REL_DISC_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. * @@ -312,6 +366,14 @@ SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. * @@ -329,6 +391,14 @@ SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteris * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached, * this must be called again with an updated handle range to continue the discovery. * + * @events + * @event{BLE_GATTC_EVT_DESC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. * @@ -346,6 +416,14 @@ SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_dis * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached, * this must be called again with an updated handle range to continue the discovery. * + * @events + * @event{BLE_GATTC_EVT_DESC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_UUID_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_uuid Pointer to a Characteristic value UUID to read. * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. @@ -365,6 +443,14 @@ SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_b * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the * complete value. * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] handle The handle of the attribute to be read. * @param[in] offset Offset into the attribute value to be read. @@ -372,7 +458,6 @@ SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_b * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. */ SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); @@ -382,6 +467,14 @@ SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint * * @details This function initiates a GATT Read Multiple Characteristic Values procedure. * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_MULT_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. * @param[in] handle_count The number of handles in p_handles. @@ -402,8 +495,19 @@ SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(ui * @note It is important to note that a write without response will consume an application buffer, and will therefore * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. A write (with response) on the other hand will use the * standard client internal buffer and thus will only generate a @ref BLE_GATTC_EVT_WRITE_RSP event as soon as the write response - * has been received from the peer. Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. + * has been received from the peer. Please see the documentation of @ref sd_ble_tx_packet_count_get for more details. * + * @events + * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Generated when using write request or queued writes.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC} + * @mmsc{@ref BLE_COMMON_APP_BUFF_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_write_params A pointer to a write parameters structure. * @@ -414,13 +518,17 @@ SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(ui * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. * @retval ::NRF_ERROR_BUSY Procedure already in progress. - * @retval ::BLE_ERROR_NO_TX_BUFFERS There are no available buffers left. + * @retval ::BLE_ERROR_NO_TX_PACKETS No available application packets for this connection. */ SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); /**@brief Send a Handle Value Confirmation to the GATT Server. - * + * + * @mscs + * @mmsc{@ref BLE_GATTC_HVI_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] handle The handle of the attribute in the indication. * @@ -431,8 +539,28 @@ SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, bl */ SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); +/**@brief Discovers information about a range of attributes on a GATT server. + * + * @events + * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.} + * @endevents + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range The range of handles to request information about. + * + * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range)); + /** @} */ +#ifdef __cplusplus +} +#endif #endif /* BLE_GATTC_H__ */ /** diff --git a/components/softdevice/s130/headers/ble_gatts.h b/components/softdevice/s130/headers/ble_gatts.h index 756571e..d240100 100644 --- a/components/softdevice/s130/headers/ble_gatts.h +++ b/components/softdevice/s130/headers/ble_gatts.h @@ -1,26 +1,26 @@ -/* +/* * Copyright (c) Nordic Semiconductor ASA * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. - * + * * 2. 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. - * + * * 3. Neither the name of Nordic Semiconductor ASA nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * 4. This software must only be used in a processor manufactured by Nordic * Semiconductor ASA, or in a processor manufactured by a third party that * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * + * + * * 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 @@ -31,7 +31,7 @@ * 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. - * + * */ /** @@ -50,6 +50,10 @@ #include "ble_gatt.h" #include "nrf_svc.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations * @{ */ @@ -66,9 +70,11 @@ enum BLE_GATTS_SVCS SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */ SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */ SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */ - SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ - SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ + SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ + SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */ + SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */ + SD_BLE_GATTS_ATTR_GET /**< Retrieve the UUID and/or metadata of an attribute. */ }; /** @@ -76,12 +82,12 @@ enum BLE_GATTS_SVCS */ enum BLE_GATTS_EVTS { - BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. @ref ble_gatts_evt_write_t */ - BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request.@ref ble_gatts_evt_rw_authorize_request_t */ - BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending, awaiting a sd_ble_gatts_sys_attr_set(). @ref ble_gatts_evt_sys_attr_missing_t */ - BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. @ref ble_gatts_evt_hvc_t */ - BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. No additional event structure applies. */ - BLE_GATTS_EVT_TIMEOUT /**< Timeout. @ref ble_gatts_evt_timeout_t */ + BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */ + BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */ + BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */ + BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */ + BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. No additional event structure applies. */ + BLE_GATTS_EVT_TIMEOUT /**< Peer failed to resonpond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */ }; /** @} */ @@ -97,7 +103,7 @@ enum BLE_GATTS_EVTS /** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths * @{ */ #define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */ -#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */ +#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */ /** @} */ /** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types @@ -157,7 +163,7 @@ enum BLE_GATTS_EVTS * @{ */ #define BLE_GATTS_ATTR_TAB_SIZE_MIN 216 /**< Minimum Attribute Table size */ -#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT 0x0000 /**< Default Attribute Table size (0x600 bytes for this version of the SoftDevice). */ +#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT 0x0000 /**< Default Attribute Table size (0x580 bytes for this version of the SoftDevice). */ /** @} */ /** @} */ @@ -166,7 +172,7 @@ enum BLE_GATTS_EVTS * @{ */ /** - * @brief BLE GATTS init options + * @brief BLE GATTS initialization parameters. */ typedef struct { @@ -181,7 +187,7 @@ typedef struct ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ uint8_t vlen :1; /**< Variable length attribute. */ uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ - uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */ + uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */ uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */ } ble_gatts_attr_md_t; @@ -195,7 +201,7 @@ typedef struct uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */ uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */ uint8_t* p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer - that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. + that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location. The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/ } ble_gatts_attr_t; @@ -204,24 +210,12 @@ typedef struct { uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/ uint16_t offset; /**< Attribute value offset. */ - uint8_t *p_value; /**< Pointer to where value is stored or will be stored. + uint8_t *p_value; /**< Pointer to where value is stored or will be stored. If value is stored in user memory, only the attribute length is updated when p_value == NULL. Set to NULL when reading to obtain the complete length of the attribute value */ } ble_gatts_value_t; -/**@brief GATT Attribute Context. */ -typedef struct -{ - ble_uuid_t srvc_uuid; /**< Service UUID. */ - ble_uuid_t char_uuid; /**< Characteristic UUID if applicable (BLE_UUID_TYPE_UNKNOWN otherwise). */ - ble_uuid_t desc_uuid; /**< Descriptor UUID if applicable (BLE_UUID_TYPE_UNKNOWN otherwise). */ - uint16_t srvc_handle; /**< Service Handle. */ - uint16_t value_handle; /**< Characteristic Value Handle if applicable (BLE_GATT_HANDLE_INVALID otherwise). */ - uint8_t type; /**< Attribute Type, see @ref BLE_GATTS_ATTR_TYPES. */ -} ble_gatts_attr_context_t; - - /**@brief GATT Characteristic Presentation Format. */ typedef struct { @@ -240,7 +234,7 @@ typedef struct ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */ uint8_t *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */ uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */ - uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ + uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */ ble_gatts_char_pf_t* p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */ ble_gatts_attr_md_t* p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */ ble_gatts_attr_md_t* p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */ @@ -268,29 +262,25 @@ typedef struct uint8_t *p_data; /**< Actual data content, use NULL to use the current attribute value. */ } ble_gatts_hvx_params_t; -/**@brief GATT Read Authorization parameters. */ +/**@brief GATT Authorization parameters. */ typedef struct { uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ - uint8_t update : 1; /**< If set, data supplied in p_data will be used in the ATT response. */ + uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value. + Please note that for @ref BLE_GATTS_OP_WRITE_REQ operations this bit must always be set, + as the data to be written needs to be stored and later provided by the application. */ uint16_t offset; /**< Offset of the attribute value being updated. */ uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ - uint8_t *p_data; /**< Pointer to new value used to update the attribute value. */ -} ble_gatts_read_authorize_params_t; - -/**@brief GATT Write Authorization parameters. */ -typedef struct -{ - uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ -} ble_gatts_write_authorize_params_t; + const uint8_t *p_data; /**< Pointer to new value used to update the attribute value. */ +} ble_gatts_authorize_params_t; /**@brief GATT Read or Write Authorize Reply parameters. */ typedef struct { uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ union { - ble_gatts_read_authorize_params_t read; /**< Read authorization parameters. */ - ble_gatts_write_authorize_params_t write; /**< Write authorization parameters. */ + ble_gatts_authorize_params_t read; /**< Read authorization parameters. */ + ble_gatts_authorize_params_t write; /**< Write authorization parameters. */ } params; /**< Reply Parameters. */ } ble_gatts_rw_authorize_reply_params_t; @@ -300,18 +290,20 @@ typedef struct typedef struct { uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ - ble_gatts_attr_context_t context; /**< Attribute Context. */ + uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalise the writing operation. */ uint16_t offset; /**< Offset for the write operation. */ uint16_t len; /**< Length of the received data. */ - uint8_t data[1]; /**< Received data, variable length. */ + uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gatts_evt_write_t; /**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */ typedef struct { uint16_t handle; /**< Attribute Handle. */ - ble_gatts_attr_context_t context; /**< Attribute Context. */ + ble_uuid_t uuid; /**< Attribute UUID. */ uint16_t offset; /**< Offset for the read operation. */ } ble_gatts_evt_read_t; @@ -365,14 +357,18 @@ typedef struct * @{ */ /**@brief Add a service declaration to the Attribute Table. + * + * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to + * add a secondary service declaration that is not referenced by another service later in the Attribute Table. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs * * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. * @param[in] p_uuid Pointer to service UUID. * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. * - * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to - * add a secondary service declaration that is not referenced by another service later in the Attribute Table. - * * @retval ::NRF_SUCCESS Successfully added a service declaration. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. @@ -384,10 +380,14 @@ SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type /**@brief Add an include declaration to the Attribute Table. * - * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time). + * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time). * * @note The included service must already be present in the Attribute Table prior to this call. * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. * @param[in] inc_srvc_handle Handle of the included service. * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. @@ -396,6 +396,7 @@ SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service. * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. @@ -405,13 +406,17 @@ SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t ser /**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table. * - * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time). + * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time). * * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writeable auxiliaries bits, * readable (no security) and writeable (selectable) CCCDs and SCCDs and valid presentation format values. * * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions. * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. * @param[in] p_char_md Characteristic metadata. * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. @@ -430,7 +435,11 @@ SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_ad /**@brief Add a descriptor to the Attribute Table. * - * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). + * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs * * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. * @param[in] p_attr Pointer to the attribute structure. @@ -447,13 +456,18 @@ SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_ad SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); /**@brief Set the value of a given attribute. + * + * @note Values other than system attributes can be set at any time, regardless of wheter any active connections exist. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used. * @param[in] handle Attribute handle. * @param[in,out] p_value Attribute value information. * - * @note Values other than system attributes can be set at any time, regardless of wheter any active connections exist. - * * @retval ::NRF_SUCCESS Successfully set the value of the attribute. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. @@ -466,25 +480,27 @@ SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16 SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); /**@brief Get the value of a given attribute. - * - * @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used. - * @param[in] handle Attribute handle. - * @param[in,out] p_value Attribute value information. * * @note If the attribute value is longer than the size of the supplied buffer, * p_len will return the total attribute value length (excluding offset), * and not the number of bytes actually returned in p_data. * The application may use this information to allocate a suitable buffer size. - * + * * @note When retrieving system attribute values with this function, the connection handle * may refer to an already disconnected connection. Refer to the documentation of * @ref sd_ble_gatts_sys_attr_get for further information. * + * @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE @ref BLE_CONN_HANDLE_INVALID supplied on a system attribute. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. */ SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); @@ -496,15 +512,28 @@ SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_ha * If the application chooses to indicate an attribute value, a @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from * the peer. * - * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. - * When receiveing the error codes @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and - * @ref BLE_ERROR_NO_TX_BUFFERS the Attribute Table has been updated. + * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. + * When receiveing the error codes @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and + * @ref BLE_ERROR_NO_TX_PACKETS the Attribute Table has been updated. * The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len). * - * @note It is important to note that a notification will consume an application buffer, and will therefore - * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. An indication on the other hand will use the - * standard server internal buffer and thus will only generate a @ref BLE_GATTS_EVT_HVC event as soon as the confirmation - * has been received from the peer. Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. + * @note It is important to note that a notification will consume an application buffer, and will therefore + * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. An indication on the other hand will use the + * standard server internal buffer and thus will only generate a @ref BLE_GATTS_EVT_HVC event as soon as the confirmation + * has been received from the peer. Please see the documentation of @ref sd_ble_tx_packet_count_get for more details. + * + * @events + * @event{@ref BLE_EVT_TX_COMPLETE, Transmission complete.} + * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_HVN_MSC} + * @mmsc{@ref BLE_GATTS_HVI_MSC} + * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC} + * @mmsc{@ref BLE_COMMON_APP_BUFF_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_hvx_params Pointer to an HVx parameters structure. If the p_data member contains a non-NULL pointer the attribute value will be updated with @@ -521,7 +550,7 @@ SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_ha * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. * @retval ::NRF_ERROR_BUSY Procedure already in progress. * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. - * @retval ::BLE_ERROR_NO_TX_BUFFERS There are no available buffers to send the data, applies only to notifications. + * @retval ::BLE_ERROR_NO_TX_PACKETS No available application packets for this connection, applies only to notifications. */ SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); @@ -533,16 +562,24 @@ SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_ga * * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. * + * @events + * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_SC_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] start_handle Start of affected attribute handle range. * @param[in] end_handle End of affected attribute handle range. * * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref sd_ble_enable and @ref ble_gatts_enable_params_t. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, notifications or indications must be enabled in the CCCD. * @retval ::NRF_ERROR_BUSY Procedure already in progress. * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. */ @@ -552,15 +589,26 @@ SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint * * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. * * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, - * or for Read Authorization reply: requested handles not replied with, - * or for Write Authorization reply: handle supplied does not match requested handle. + * handle supplied does not match requested handle, + * or invalid data to be written provided by the application. * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time. */ SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); @@ -568,18 +616,18 @@ SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_repl /**@brief Update persistent system attribute information. * - * @details Supply information about persistent system attributes to the stack, + * @details Supply information about persistent system attributes to the stack, * previously obtained using @ref sd_ble_gatts_sys_attr_get. - * This call is only allowed for active connections, and is usually + * This call is only allowed for active connections, and is usually * made immediately after a connection is established with an known bonded device, * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. * - * p_sysattrs may point directly to the application's stored copy of the system attributes + * p_sysattrs may point directly to the application's stored copy of the system attributes * obtained using @ref sd_ble_gatts_sys_attr_get. * If the pointer is NULL, the system attribute info is initialized, assuming that * the application does not have any previously saved system attribute data for this device. * - * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. + * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration. * * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially. * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or @@ -588,25 +636,33 @@ SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_repl * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified. * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified. * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. - * @param[in] len Size of data pointed by p_sys_attr_data, in octets. + * @param[in] len Size of data pointed by p_sys_attr_data, in octets. * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS * * @retval ::NRF_SUCCESS Successfully set the system attribute information. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time. - */ -SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags)); + - /**@brief Retrieve persistent system attribute information from the stack. * * @details This call is used to retrieve information about values to be stored perisistently by the application - * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device, + * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device, * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set. * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it. @@ -616,22 +672,53 @@ SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t c * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned. * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned. * + * @mscs + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle of the recently terminated connection. - * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. NULL can be provided to - * obtain the length of the data + * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described + * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data. * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditially updated to actual length of system attribute data. * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS * * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. * @retval ::NRF_ERROR_NOT_FOUND No system attributes found. - */ -SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); + */ +SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); + + +/**@brief Retrieve the first valid user attribute handle. + * + * @param[out] p_handle Pointer to an integer where the handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully retrieved the handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle)); + +/**@brief Retrieve the attribute UUID and/or metadata. + * + * @param[in] handle Attribute handle + * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field. + * @param[out] p_md Metadata of the attribute. Use NULL to omit this field. + * + * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata, + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL. + * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found. + */ +SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md)); /** @} */ +#ifdef __cplusplus +} +#endif #endif // BLE_GATTS_H__ /** diff --git a/components/softdevice/s130/headers/ble_hci.h b/components/softdevice/s130/headers/ble_hci.h index 2488985..4a9620c 100644 --- a/components/softdevice/s130/headers/ble_hci.h +++ b/components/softdevice/s130/headers/ble_hci.h @@ -42,6 +42,9 @@ #ifndef BLE_HCI_H__ #define BLE_HCI_H__ +#ifdef __cplusplus +extern "C" { +#endif /** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes * @{ */ @@ -120,6 +123,9 @@ /** @} */ +#ifdef __cplusplus +} +#endif #endif // BLE_HCI_H__ /** @} */ diff --git a/components/softdevice/s130/headers/ble_l2cap.h b/components/softdevice/s130/headers/ble_l2cap.h index 6eab9fb..8a68ed9 100644 --- a/components/softdevice/s130/headers/ble_l2cap.h +++ b/components/softdevice/s130/headers/ble_l2cap.h @@ -1,26 +1,26 @@ -/* +/* * Copyright (c) Nordic Semiconductor ASA * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. - * + * * 2. 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. - * + * * 3. Neither the name of Nordic Semiconductor ASA nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * 4. This software must only be used in a processor manufactured by Nordic * Semiconductor ASA, or in a processor manufactured by a third party that * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * + * + * * 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 @@ -31,7 +31,7 @@ * 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. - * + * */ /** @@ -41,18 +41,22 @@ */ #ifndef BLE_L2CAP_H__ -#define BLE_L2CAP_H__ +#define BLE_L2CAP_H__ #include "ble_types.h" #include "ble_ranges.h" #include "ble_err.h" #include "nrf_svc.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations * @{ */ /**@brief L2CAP API SVC numbers. */ -enum BLE_L2CAP_SVCS +enum BLE_L2CAP_SVCS { SD_BLE_L2CAP_CID_REGISTER = BLE_L2CAP_SVC_BASE, /**< Register a CID. */ SD_BLE_L2CAP_CID_UNREGISTER, /**< Unregister a CID. */ @@ -60,7 +64,7 @@ enum BLE_L2CAP_SVCS }; /**@brief L2CAP Event IDs. */ -enum BLE_L2CAP_EVTS +enum BLE_L2CAP_EVTS { BLE_L2CAP_EVT_RX = BLE_L2CAP_EVT_BASE /**< L2CAP packet received. */ }; @@ -76,16 +80,16 @@ enum BLE_L2CAP_EVTS /** @} */ /**@brief Default L2CAP MTU. */ -#define BLE_L2CAP_MTU_DEF (23) +#define BLE_L2CAP_MTU_DEF (23) /**@brief Invalid Channel Identifier. */ -#define BLE_L2CAP_CID_INVALID (0x0000) +#define BLE_L2CAP_CID_INVALID (0x0000) /**@brief Dynamic Channel Identifier base. */ -#define BLE_L2CAP_CID_DYN_BASE (0x0040) +#define BLE_L2CAP_CID_DYN_BASE (0x0040) /**@brief Maximum amount of dynamic CIDs. */ -#define BLE_L2CAP_CID_DYN_MAX (8) +#define BLE_L2CAP_CID_DYN_MAX (8) /** @} */ @@ -104,7 +108,8 @@ typedef struct typedef struct { ble_l2cap_header_t header; /**< L2CAP packet header. */ - uint8_t data[1]; /**< Packet data, variable length. */ + uint8_t data[1]; /**< Packet data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_l2cap_evt_rx_t; @@ -126,7 +131,11 @@ typedef struct /**@brief Register a CID with L2CAP. * * @details This registers a higher protocol layer with the L2CAP multiplexer, and is requried prior to all operations on the CID. - * + * + * @mscs + * @mmsc{@ref BLE_L2CAP_API_MSC} + * @endmscs + * * @param[in] cid L2CAP CID. * * @retval ::NRF_SUCCESS Successfully registered a CID with the L2CAP layer. @@ -139,7 +148,11 @@ SVCALL(SD_BLE_L2CAP_CID_REGISTER, uint32_t, sd_ble_l2cap_cid_register(uint16_t c /**@brief Unregister a CID with L2CAP. * * @details This unregisters a previously registerd higher protocol layer with the L2CAP multiplexer. - * + * + * @mscs + * @mmsc{@ref BLE_L2CAP_API_MSC} + * @endmscs + * * @param[in] cid L2CAP CID. * * @retval ::NRF_SUCCESS Successfully unregistered the CID. @@ -150,9 +163,18 @@ SVCALL(SD_BLE_L2CAP_CID_UNREGISTER, uint32_t, sd_ble_l2cap_cid_unregister(uint16 /**@brief Transmit an L2CAP packet. * - * @note It is important to note that a call to this function will consume an application buffer, and will therefore - * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. - * Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. + * @note It is important to note that a call to this function will consume an application packet, and will therefore + * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. + * Please see the documentation of @ref sd_ble_tx_packet_count_get for more details. + * + * @events + * @event{@ref BLE_EVT_TX_COMPLETE} + * @event{@ref BLE_L2CAP_EVT_RX} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_API_MSC} + * @endmscs * * @param[in] conn_handle Connection Handle. * @param[in] p_header Pointer to a packet header containing length and CID. @@ -163,13 +185,16 @@ SVCALL(SD_BLE_L2CAP_CID_UNREGISTER, uint32_t, sd_ble_l2cap_cid_unregister(uint16 * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register. * @retval ::NRF_ERROR_NOT_FOUND CID not found. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::BLE_ERROR_NO_TX_BUFFERS Not enough application buffers available. + * @retval ::BLE_ERROR_NO_TX_PACKETS Not enough application packets available. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF. */ SVCALL(SD_BLE_L2CAP_TX, uint32_t, sd_ble_l2cap_tx(uint16_t conn_handle, ble_l2cap_header_t const *p_header, uint8_t const *p_data)); /** @} */ +#ifdef __cplusplus +} +#endif #endif // BLE_L2CAP_H__ /** diff --git a/components/softdevice/s130/headers/ble_ranges.h b/components/softdevice/s130/headers/ble_ranges.h index 69100b3..2e5ff7b 100644 --- a/components/softdevice/s130/headers/ble_ranges.h +++ b/components/softdevice/s130/headers/ble_ranges.h @@ -57,6 +57,10 @@ #ifndef BLE_RANGES_H__ #define BLE_RANGES_H__ +#ifdef __cplusplus +extern "C" { +#endif + #define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ #define BLE_SVC_LAST 0x6B /**< Total: 12. */ @@ -111,6 +115,9 @@ #define BLE_L2CAP_OPT_BASE 0x80 /**< L2CAP BLE Option base. */ #define BLE_L2CAP_OPT_LAST 0x9F /**< Total: 32. */ +#ifdef __cplusplus +} +#endif #endif /* BLE_RANGES_H__ */ /** diff --git a/components/softdevice/s130/headers/ble_types.h b/components/softdevice/s130/headers/ble_types.h index d99d774..23e23a1 100644 --- a/components/softdevice/s130/headers/ble_types.h +++ b/components/softdevice/s130/headers/ble_types.h @@ -48,6 +48,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** @addtogroup BLE_TYPES_DEFINES Defines * @{ */ @@ -178,17 +182,20 @@ /** @brief 128 bit UUID values. */ typedef struct { - unsigned char uuid128[16]; /**< Little-Endian UUID bytes. */ + uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */ } ble_uuid128_t; /** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ typedef struct { - uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ - uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ + uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ + uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ } ble_uuid_t; /** @} */ +#ifdef __cplusplus +} +#endif #endif /* BLE_TYPES_H__ */ diff --git a/components/softdevice/s130/headers/nrf_mbr.h b/components/softdevice/s130/headers/nrf51/nrf_mbr.h similarity index 95% rename from components/softdevice/s130/headers/nrf_mbr.h rename to components/softdevice/s130/headers/nrf51/nrf_mbr.h index 111c642..8d4486b 100644 --- a/components/softdevice/s130/headers/nrf_mbr.h +++ b/components/softdevice/s130/headers/nrf51/nrf_mbr.h @@ -48,6 +48,13 @@ #include "nrf_svc.h" #include +#ifndef NRF51 +#error "This header file shall only be included for nRF51 projects" +#endif + +#ifdef __cplusplus +extern "C" { +#endif /** @addtogroup NRF_MBR_DEFINES Defines * @{ */ @@ -59,6 +66,10 @@ #define PAGE_SIZE_IN_WORDS 256 /** @} */ +/** @brief The size that must be reserved for the MBR when a softdevice is written to flash. +This is the offset where the first byte of the softdevice hex file is written.*/ +#define MBR_SIZE (0x1000) + /** @addtogroup NRF_MBR_ENUMS Enumerations * @{ */ @@ -178,6 +189,9 @@ typedef struct SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); /** @} */ +#ifdef __cplusplus +} +#endif #endif // NRF_MBR_H__ /** diff --git a/components/softdevice/s130/headers/nrf_error.h b/components/softdevice/s130/headers/nrf_error.h index efa1b65..1035b76 100644 --- a/components/softdevice/s130/headers/nrf_error.h +++ b/components/softdevice/s130/headers/nrf_error.h @@ -44,6 +44,10 @@ #ifndef NRF_ERROR_H__ #define NRF_ERROR_H__ +#ifdef __cplusplus +extern "C" { +#endif + /** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions * @{ */ #define NRF_ERROR_BASE_NUM (0x0) ///< Global error base @@ -64,13 +68,18 @@ #define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length #define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags #define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data -#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit +#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size #define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out #define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer #define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation #define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address #define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy +#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded. +#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation +#ifdef __cplusplus +} +#endif #endif // NRF_ERROR_H__ /** diff --git a/components/softdevice/s130/headers/nrf_error_sdm.h b/components/softdevice/s130/headers/nrf_error_sdm.h index 25a1437..412b9b5 100644 --- a/components/softdevice/s130/headers/nrf_error_sdm.h +++ b/components/softdevice/s130/headers/nrf_error_sdm.h @@ -1,26 +1,26 @@ -/* +/* * Copyright (c) Nordic Semiconductor ASA * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. - * + * * 2. 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. - * + * * 3. Neither the name of Nordic Semiconductor ASA nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * 4. This software must only be used in a processor manufactured by Nordic * Semiconductor ASA, or in a processor manufactured by a third party that * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * + * + * * 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 @@ -31,14 +31,14 @@ * 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. - * + * */ /** @addtogroup nrf_sdm_api @{ @defgroup nrf_sdm_error SoftDevice Manager Error Codes @{ - + @brief Error definitions for the SDM API */ @@ -48,10 +48,17 @@ #include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + #define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown lfclk source. #define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). #define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erronous SoftDevice flashing). +#ifdef __cplusplus +} +#endif #endif // NRF_ERROR_SDM_H__ /** diff --git a/components/softdevice/s130/headers/nrf_error_soc.h b/components/softdevice/s130/headers/nrf_error_soc.h index cfddf7e..93958a4 100644 --- a/components/softdevice/s130/headers/nrf_error_soc.h +++ b/components/softdevice/s130/headers/nrf_error_soc.h @@ -48,6 +48,9 @@ #define NRF_ERROR_SOC_H__ #include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif /* Mutex Errors */ #define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken @@ -69,6 +72,9 @@ #define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel #define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group +#ifdef __cplusplus +} +#endif #endif // NRF_ERROR_SOC_H__ /** @} diff --git a/components/softdevice/s130/headers/nrf_nvic.h b/components/softdevice/s130/headers/nrf_nvic.h new file mode 100644 index 0000000..b308bf0 --- /dev/null +++ b/components/softdevice/s130/headers/nrf_nvic.h @@ -0,0 +1,485 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 HOLDER 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. + * + */ +/** + * @defgroup nrf_nvic_api SoftDevice NVIC API + * @{ + * + * @note In order to use this module, the following code has to be added to a .c file: + * \code + * nrf_nvic_state_t nrf_nvic_state = {0}; + * \endcode + * + * @note Definitions and declarations starting with __ (double underscore) in this header file are + * not intended for direct use by the application. + * + * @brief APIs for the accessing NVIC when using a SoftDevice. + * + */ + +#ifndef NRF_NVIC_H__ +#define NRF_NVIC_H__ + +#include +#include "nrf.h" + +#include "nrf_error_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_NVIC_DEFINES Defines + * @{ */ + +/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions + * @{ */ + +#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */ + +#ifdef NRF51 + #define __NRF_NVIC_ISER_COUNT (1) /**< The number of ISER/ICER registers in the NVIC that are used. */ + + /**@brief Interrupts used by the SoftDevice. */ + #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ + (1U << POWER_CLOCK_IRQn) \ + | (1U << RADIO_IRQn) \ + | (1U << RTC0_IRQn) \ + | (1U << TIMER0_IRQn) \ + | (1U << RNG_IRQn) \ + | (1U << ECB_IRQn) \ + | (1U << CCM_AAR_IRQn) \ + | (1U << TEMP_IRQn) \ + | (1U << __NRF_NVIC_NVMC_IRQn) \ + | (1U << (uint32_t)SWI4_IRQn) \ + | (1U << (uint32_t)SWI5_IRQn) \ + )) + + /**@brief Interrupts available for to application. */ + #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) +#endif + +#ifdef NRF52 + #define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */ + + /**@brief Interrupts used by the SoftDevice. */ + #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ + (1U << POWER_CLOCK_IRQn) \ + | (1U << RADIO_IRQn) \ + | (1U << RTC0_IRQn) \ + | (1U << TIMER0_IRQn) \ + | (1U << RNG_IRQn) \ + | (1U << ECB_IRQn) \ + | (1U << CCM_AAR_IRQn) \ + | (1U << TEMP_IRQn) \ + | (1U << __NRF_NVIC_NVMC_IRQn) \ + | (1U << (uint32_t)SWI4_EGU4_IRQn) \ + | (1U << (uint32_t)SWI5_EGU5_IRQn) \ + )) + #define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0) + + /**@brief Interrupts available for to application. */ + #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) + #define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1) +#endif +/**@} */ + +/**@} */ + +/**@addtogroup NRF_NVIC_VARIABLES Variables + * @{ */ + +/**@brief Type representing the state struct for the SoftDevice NVIC module. */ +typedef struct +{ + uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */ + uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */ +} nrf_nvic_state_t; + +/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an + * application source file. */ +extern nrf_nvic_state_t nrf_nvic_state; + +/**@} */ + +/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions + * @{ */ + +/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts. + * + * @retval The value of PRIMASK prior to disabling the interrupts. + */ +static inline int __sd_nvic_irq_disable(void) +{ + int pm = __get_PRIMASK(); + __disable_irq(); + return pm; +} + +/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts. + */ +static inline void __sd_nvic_irq_enable(void) +{ + __enable_irq(); +} + +/**@brief Checks if IRQn is available to application + * @param[in] IRQn irq to check + * + * @retval 1 (true) if the irq to check is available to the application + */ +static inline uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn) +{ + if (IRQn < 32) + { + return ((1UL<= (1 << __NVIC_PRIO_BITS)) + { + return 0; + } +#ifdef NRF51 + if( priority == 0 + || priority == 2 + ) + { + return 0; + } +#endif +#ifdef NRF52 + if( priority == 0 + || priority == 1 + || priority == 4 + || priority == 5 + ) + { + return 0; + } +#endif + return 1; +} + +/**@} */ + +/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions + * @{ */ + +/**@brief Enable External Interrupt. + * @note Corresponds to NVIC_EnableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was enabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. + */ +static inline uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn))) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); + } + else + { + NVIC_EnableIRQ(IRQn); + } + return NRF_SUCCESS; +} + +/**@brief Disable External Interrupt. + * @note Corresponds to NVIC_DisableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was disabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + */ +static inline uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F)); + } + else + { + NVIC_DisableIRQ(IRQn); + } + + return NRF_SUCCESS; +} + +/**@brief Get Pending Interrupt. + * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. + * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. + * + * @retval ::NRF_SUCCESS The interrupt is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +static inline uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_pending_irq = NVIC_GetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +/**@brief Set Pending Interrupt. + * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt is set pending. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +static inline uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_SetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +/**@brief Clear Pending Interrupt. + * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +static inline uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_ClearPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +/**@brief Set Interrupt Priority. + * @note Corresponds to NVIC_SetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * @pre Priority is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. + * @param[in] priority A valid IRQ priority for use by the application. + * + * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. + */ +static inline uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (!__sd_nvic_is_app_accessible_priority(priority)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + NVIC_SetPriority(IRQn, (uint32_t)priority); + return NRF_SUCCESS; +} + +/**@brief Get Interrupt Priority. + * @note Corresponds to NVIC_GetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. + * @param[out] p_priority Return value from NVIC_GetPriority. + * + * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. + */ +static inline uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_priority = (NVIC_GetPriority(IRQn) & 0xFF); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +/**@brief System Reset. + * @note Corresponds to NVIC_SystemReset in CMSIS. + * + * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN + */ +static inline uint32_t sd_nvic_SystemReset(void) +{ + NVIC_SystemReset(); + return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN; +} + +/**@brief Enters critical region. + * + * @post Application interrupts will be disabled. + * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each + * execution context + * @sa sd_nvic_critical_region_exit + * + * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region. + * + * @retval ::NRF_SUCCESS + */ +static inline uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) +{ + int was_masked = __sd_nvic_irq_disable(); + if (!nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__cr_flag = 1; + nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 ); + NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0; + #ifdef NRF52 + nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 ); + NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1; + #endif + *p_is_nested_critical_region = 0; + } + else + { + *p_is_nested_critical_region = 1; + } + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + return NRF_SUCCESS; +} + +/**@brief Exit critical region. + * + * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. + * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. + * + * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. + * + * @retval ::NRF_SUCCESS + */ +static inline uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) +{ + if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0)) + { + int was_masked = __sd_nvic_irq_disable(); + NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0]; + #ifdef NRF52 + NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1]; + #endif + nrf_nvic_state.__cr_flag = 0; + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + } + + return NRF_SUCCESS; +} +/**@} */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_NVIC_H__ + +/**@} */ diff --git a/components/softdevice/s130/headers/nrf_sd_def.h b/components/softdevice/s130/headers/nrf_sd_def.h index 5b58c4f..4f753ac 100644 --- a/components/softdevice/s130/headers/nrf_sd_def.h +++ b/components/softdevice/s130/headers/nrf_sd_def.h @@ -1,13 +1,41 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SD_DEF_H__ @@ -15,9 +43,18 @@ #include -#define SD_PPI_CHANNELS_USED 0xFFF0C000uL /**< PPI channels utilized by SotfDevice (not available to the application). */ +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_PPI_CHANNELS_USED 0xFFF0C000uL /**< PPI channels utilized by SotfDevice (not available to the application). */ #define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ #define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ #define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ + +#ifdef __cplusplus +} +#endif + #endif /* NRF_SD_DEF_H__ */ diff --git a/components/softdevice/s130/headers/nrf_sdm.h b/components/softdevice/s130/headers/nrf_sdm.h index 4d407a9..27a7987 100644 --- a/components/softdevice/s130/headers/nrf_sdm.h +++ b/components/softdevice/s130/headers/nrf_sdm.h @@ -1,26 +1,26 @@ -/* +/* * Copyright (c) Nordic Semiconductor ASA * All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: - * + * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. - * + * * 2. 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. - * + * * 3. Neither the name of Nordic Semiconductor ASA nor the names of other * contributors to this software may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * 4. This software must only be used in a processor manufactured by Nordic * Semiconductor ASA, or in a processor manufactured by a third party that * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * + * + * * 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 @@ -31,14 +31,14 @@ * 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. - * + * */ /** @defgroup nrf_sdm_api SoftDevice Manager API @{ - + @brief APIs for SoftDevice management. - + */ /* Header guard */ @@ -50,22 +50,25 @@ #include "nrf_soc.h" #include "nrf_error_sdm.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @addtogroup NRF_SDM_DEFINES Defines * @{ */ +#ifdef NRFSOC_DOXYGEN +//Stuff defined elsewere, to satisfy doxygen +#define MBR_SIZE 0 +#warning test +#endif /** @brief SoftDevice Manager SVC Base number. */ -#define SDM_SVC_BASE 0x10 +#define SDM_SVC_BASE 0x10 -/** @} */ - -/** @brief Defines the SoftDevice Information Structure location (address) as an offset from +/** @brief Defines the SoftDevice Information Structure location (address) as an offset from the start of the softdevice (without MBR)*/ #define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) -/** @brief Defines the usual size reserverd for the MBR when a softdevice is written to flash. -This is the offset where the first byte of the softdevice hex file is written.*/ -#define MBR_SIZE (0x1000) - /** @brief Defines the absolute Softdevice information structure location (address)*/ #define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) @@ -83,6 +86,19 @@ This is the offset where the first byte of the softdevice hex file is written.*/ use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/ #define SD_FWID_GET(baseaddr) ((*((uint32_t *) ((baseaddr) + SD_FWID_OFFSET))) & 0xFFFF) +/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges + * @{ */ +#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */ +#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */ +/**@} */ + +/**@defgroup NRF_FAULT_IDS Fault ID types + * @{ */ +#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter will be set to 0x00000000. */ +#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain the address in memory that was accessed. */ +/** @} */ + +/** @} */ /** @addtogroup NRF_SDM_ENUMS Enumerations * @{ */ @@ -97,30 +113,33 @@ enum NRF_SD_SVCS SVC_SDM_LAST /**< Placeholder for last SDM SVC */ }; -/**@brief Possible lfclk oscillator sources. */ -enum NRF_CLOCK_LFCLKSRCS -{ - NRF_CLOCK_LFCLKSRC_SYNTH_250_PPM, /**< LFCLK Synthesized from HFCLK. */ - NRF_CLOCK_LFCLKSRC_XTAL_500_PPM, /**< LFCLK crystal oscillator 500 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_250_PPM, /**< LFCLK crystal oscillator 250 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_150_PPM, /**< LFCLK crystal oscillator 150 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_100_PPM, /**< LFCLK crystal oscillator 100 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_75_PPM, /**< LFCLK crystal oscillator 75 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, /**< LFCLK crystal oscillator 50 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_30_PPM, /**< LFCLK crystal oscillator 30 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, /**< LFCLK crystal oscillator 20 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION, /**< LFCLK RC oscillator, 250ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_500MS_CALIBRATION, /**< LFCLK RC oscillator, 500ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_1000MS_CALIBRATION, /**< LFCLK RC oscillator, 1000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_2000MS_CALIBRATION, /**< LFCLK RC oscillator, 2000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, /**< LFCLK RC oscillator, 4000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_8000MS_CALIBRATION, /**< LFCLK RC oscillator, 8000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_1000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 1000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_2000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 2000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_4000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 4000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_8000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 8000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_16000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 16000ms, if changed above a threshold, a calibration is done.*/ -}; +/** @} */ + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ + +/**@defgroup NRF_CLOCK_LF_XTAL_ACCURACY Clock accuracy + * @{ */ + +#define NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_500_PPM (1) /**< 500 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_150_PPM (2) /**< 150 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_100_PPM (3) /**< 100 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_75_PPM (4) /**< 75 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_50_PPM (5) /**< 50 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_30_PPM (6) /**< 30 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM (7) /**< 20 ppm */ + +/** @} */ + +/**@defgroup NRF_CLOCK_LF_SRC Possible lfclk oscillator sources + * @{ */ + +#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */ +#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */ +#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */ + +/** @} */ /** @} */ @@ -128,22 +147,52 @@ enum NRF_CLOCK_LFCLKSRCS * @{ */ /**@brief Type representing lfclk oscillator source. */ -typedef uint32_t nrf_clock_lfclksrc_t; +typedef struct +{ + uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */ + uint8_t rc_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second + units (nRF51: 1-64, nRF52: 1-32). + @note To avoid excessive clock drift, 0.5 degrees Celsius is the + maximum temperature change allowed in one calibration timer + interval. The interval should be selected to ensure this. + + @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. */ + uint8_t rc_temp_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: How often (in number of calibration + intervals) the RC oscillator shall be calibrated if the temperature + hasn't changed. + 0: Always calibrate even if the temperature hasn't changed. + 1: Only calibrate if the temperature has changed (nRF51 only). + 2-33: Check the temperature and only calibrate if it has changed, + however calibration will take place every rc_temp_ctiv + intervals in any case. + @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. -/**@brief SoftDevice Assertion Handler type. + @note For nRF52, the application must ensure calibration at least once + every 8 seconds to ensure +/-250ppm clock stability. The + recommended configuration for NRF_CLOCK_LF_SRC_RC on nRF52 is + rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at + least once every 8 seconds and for temperature changes of 0.5 + degrees Celsius every 4 seconds. See the Product Specification + for the nRF52 device being used for more information.*/ + uint8_t xtal_accuracy; /**< External crystal clock accuracy used in the LL to compute timing windows. + + @note For the NRF_CLOCK_LF_SRC_RC clock source this parameter is ignored. */ +} nrf_clock_lf_cfg_t; + +/**@brief Fault Handler type. * - * When an unexpected error occurs within the SoftDevice it will call the SoftDevice assertion handler callback. + * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back. * The protocol stack will be in an undefined state when this happens and the only way to recover will be to * perform a reset, using e.g. CMSIS NVIC_SystemReset(). * - * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the SoftDevice assert callback. - * - * @param[in] pc The program counter of the failed assert. - * @param[in] line_number Line number where the assert failed. - * @param[in] file_name File name where the assert failed. + * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault. + * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details. */ -typedef void (*softdevice_assertion_handler_t)(uint32_t pc, uint16_t line_number, const uint8_t * p_file_name); +typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info); /** @} */ @@ -151,8 +200,6 @@ typedef void (*softdevice_assertion_handler_t)(uint32_t pc, uint16_t line_number * @{ */ /**@brief Enables the SoftDevice and by extension the protocol stack. - * - * Idempotent function to enable the SoftDevice. * * @note Some care must be taken if a low frequency clock source is already running when calling this function: * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new @@ -160,27 +207,30 @@ typedef void (*softdevice_assertion_handler_t)(uint32_t pc, uint16_t line_number * * @note This function has no effect when returning with an error. * - * @post If return code is ::NRF_SUCCESS + * @post If return code is ::NRF_SUCCESS * - SoC library and protocol stack APIs are made available. * - A portion of RAM will be unavailable (see relevant SDS documentation). * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). * - Interrupts will not arrive from protected peripherals or interrupts. - * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the softdevice. + * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice. * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). * - Chosen low frequency clock source will be running. * - * @param clock_source Low frequency clock source and accuracy. (Note: In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock). - * @param assertion_handler Callback for SoftDevice assertions. + * @param p_clock_lf_cfg Low frequency clock source and accuracy. + If NULL the clock will be configured as an rc source with rc_ctiv = 16 and .rc_temp_ctiv = 2 + In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock. + * @param fault_handler Callback to be invoked in case of fault. * * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and assertion handler cannot be updated. - * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDeviceinterrupt is already enabled, or an enabled interrupt has an illegal priority level. + * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated. + * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level. * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. */ -SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lfclksrc_t clock_source, softdevice_assertion_handler_t assertion_handler)); +SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler)); + /**@brief Disables the SoftDevice and by extension the protocol stack. - * + * * Idempotent function to disable the SoftDevice. * * @post SoC library and protocol stack APIs are made unavailable. @@ -203,17 +253,20 @@ SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); /**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice - * + * * This function is only intended to be called when a bootloader is enabled. * * @param[in] address The base address of the interrupt vector table for forwarded interrupts. - + * @retval ::NRF_SUCCESS */ -SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); +SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); /** @} */ +#ifdef __cplusplus +} +#endif #endif // NRF_SDM_H__ /** diff --git a/components/softdevice/s130/headers/nrf_soc.h b/components/softdevice/s130/headers/nrf_soc.h index 07088fc..f083011 100644 --- a/components/softdevice/s130/headers/nrf_soc.h +++ b/components/softdevice/s130/headers/nrf_soc.h @@ -48,14 +48,19 @@ #include #include "nrf_svc.h" #include "nrf.h" + #include "nrf_error_soc.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@addtogroup NRF_SOC_DEFINES Defines * @{ */ /**@brief The number of the lowest SVC number reserved for the SoC library. */ -#define SOC_SVC_BASE (0x20) -#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) +#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */ +#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */ /**@brief Guranteed time for application to process radio inactive notification. */ #define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) @@ -67,10 +72,18 @@ #define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ #define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ +#ifdef NRF51 #define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ #define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */ #define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ #define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. */ +#endif +#ifdef NRF52 +#define SD_EVT_IRQn (SWI2_EGU2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define SD_EVT_IRQHandler (SWI2_EGU2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */ +#define RADIO_NOTIFICATION_IRQn (SWI1_EGU1_IRQn) /**< The radio notification IRQ number. */ +#define RADIO_NOTIFICATION_IRQHandler (SWI1_EGU1_IRQHandler) /**< The radio notification IRQ handler. */ +#endif #define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ #define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ @@ -83,7 +96,7 @@ /**@} */ -/**@addtogroup NRF_SOC_TYPES Types +/**@addtogroup NRF_SOC_ENUMS Enumerations * @{ */ /**@brief The SVC numbers used by the SVC functions in the SoC library. */ @@ -103,19 +116,19 @@ enum NRF_SOC_SVCS SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, SD_MUTEX_ACQUIRE, SD_MUTEX_RELEASE, - SD_NVIC_ENABLEIRQ, - SD_NVIC_DISABLEIRQ, - SD_NVIC_GETPENDINGIRQ, - SD_NVIC_SETPENDINGIRQ, - SD_NVIC_CLEARPENDINGIRQ, - SD_NVIC_SETPRIORITY, - SD_NVIC_GETPRIORITY, - SD_NVIC_SYSTEMRESET, - SD_NVIC_CRITICAL_REGION_ENTER, - SD_NVIC_CRITICAL_REGION_EXIT, - SD_RAND_APPLICATION_POOL_CAPACITY, - SD_RAND_APPLICATION_BYTES_AVAILABLE, - SD_RAND_APPLICATION_GET_VECTOR, + SD_RFU_1, + SD_RFU_2, + SD_RFU_3, + SD_RFU_4, + SD_RFU_5, + SD_RFU_6, + SD_RFU_7, + SD_RFU_8, + SD_RFU_9, + SD_RFU_10, + SD_RAND_APPLICATION_POOL_CAPACITY_GET, + SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, + SD_RAND_APPLICATION_VECTOR_GET, SD_POWER_MODE_SET, SD_POWER_SYSTEM_OFF, SD_POWER_RESET_REASON_GET, @@ -135,6 +148,7 @@ enum NRF_SOC_SVCS SD_CLOCK_HFCLK_IS_RUNNING, SD_RADIO_NOTIFICATION_CFG_SET, SD_ECB_BLOCK_ENCRYPT, + SD_ECB_BLOCKS_ENCRYPT, SD_RADIO_SESSION_OPEN, SD_RADIO_SESSION_CLOSE, SD_RADIO_REQUEST, @@ -150,14 +164,7 @@ enum NRF_MUTEX_VALUES NRF_MUTEX_TAKEN }; -/**@brief Possible values of ::nrf_app_irq_priority_t. */ -enum NRF_APP_PRIORITIES -{ - NRF_APP_PRIORITY_HIGH = 1, - NRF_APP_PRIORITY_LOW = 3 -}; - -/**@brief Possible values of ::nrf_power_mode_t. */ +/**@brief Power modes. */ enum NRF_POWER_MODES { NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ @@ -165,7 +172,7 @@ enum NRF_POWER_MODES }; -/**@brief Possible values of ::nrf_power_failure_threshold_t */ +/**@brief Power failure thresholds */ enum NRF_POWER_THRESHOLDS { NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ @@ -175,14 +182,14 @@ enum NRF_POWER_THRESHOLDS }; -/**@brief Possible values of ::nrf_power_dcdc_mode_t. */ +/**@brief DC/DC converter modes. */ enum NRF_POWER_DCDC_MODES { NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ }; -/**@brief Possible values of ::nrf_radio_notification_distance_t. */ +/**@brief Radio notification distances. */ enum NRF_RADIO_NOTIFICATION_DISTANCES { NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ @@ -195,7 +202,7 @@ enum NRF_RADIO_NOTIFICATION_DISTANCES }; -/**@brief Possible values of ::nrf_radio_notification_type_t. */ +/**@brief Radio notification types. */ enum NRF_RADIO_NOTIFICATION_TYPES { NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ @@ -204,49 +211,6 @@ enum NRF_RADIO_NOTIFICATION_TYPES NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ }; -/**@brief SoC Events. */ -enum NRF_SOC_EVTS -{ - NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ - NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ - NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ - NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ - NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ - NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ - NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio signal callback handler return was invalid. */ - NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio session is idle. */ - NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio session is closed. */ - NRF_EVT_NUMBER_OF_EVTS -}; - -/**@} */ - -/**@addtogroup NRF_SOC_TYPES Types - * @{ */ - -/**@brief Represents a mutex for use with the nrf_mutex functions. - * @note Accessing the value directly is not safe, use the mutex functions! - */ -typedef volatile uint8_t nrf_mutex_t; - -/**@brief The interrupt priorities available to the application while the softdevice is active. */ -typedef uint8_t nrf_app_irq_priority_t; - -/**@brief Represents a power mode, used in power mode functions */ -typedef uint8_t nrf_power_mode_t; - -/**@brief Represents a power failure threshold value. */ -typedef uint8_t nrf_power_failure_threshold_t; - -/**@brief Represents a DCDC mode value. */ -typedef uint32_t nrf_power_dcdc_mode_t; - -/**@brief Radio notification distances. */ -typedef uint8_t nrf_radio_notification_distance_t; - -/**@brief Radio notification types. */ -typedef uint8_t nrf_radio_notification_type_t; - /**@brief The Radio signal callback types. */ enum NRF_RADIO_CALLBACK_SIGNAL_TYPE { @@ -273,8 +237,14 @@ enum NRF_RADIO_SIGNAL_CALLBACK_ACTION /**@brief Radio timeslot high frequency clock source configuration. */ enum NRF_RADIO_HFCLK_CFG { - NRF_RADIO_HFCLK_CFG_DEFAULT, /**< Use the currently selected oscillator as HF clock source during the timeslot (i.e. the source is not specified). */ - NRF_RADIO_HFCLK_CFG_FORCE_XTAL, /**< Force external crystal to be used as HF clock source during whole the timeslot. */ + NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the + external crystal for the whole duration of the timeslot. This should be the + preferred option for events that use the radio or require high timing accuracy. */ + NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots. + The RC oscillator may be the clock source in part or for the whole duration of the timeslot. + The RC oscillator's accuracy must therefore be taken into consideration. + @note If the application will use the radio peripheral in timeslots with this configuration, + it must make sure that the crystal is running and stable before starting the radio. */ }; /**@brief Radio timeslot priorities. */ @@ -287,10 +257,36 @@ enum NRF_RADIO_PRIORITY /**@brief Radio timeslot request type. */ enum NRF_RADIO_REQUEST_TYPE { - NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request timeslot as early as possible. This should always be used for the first request in a session. */ - NRF_RADIO_REQ_TYPE_NORMAL /**< Normal timeslot request. */ + NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */ + NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */ +}; + +/**@brief SoC Events. */ +enum NRF_SOC_EVTS +{ + NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ + NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ + NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ + NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ + NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ + NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ + NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */ + NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */ + NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */ + NRF_EVT_NUMBER_OF_EVTS }; +/**@} */ + + +/**@addtogroup NRF_SOC_STRUCTURES Structures + * @{ */ + +/**@brief Represents a mutex for use with the nrf_mutex functions. + * @note Accessing the value directly is not safe, use the mutex functions! + */ +typedef volatile uint8_t nrf_mutex_t; + /**@brief Parameters for a request for a timeslot as early as possible. */ typedef struct { @@ -300,7 +296,7 @@ typedef struct uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ } nrf_radio_request_earliest_t; -/**@brief Parameters for a normal radio request. */ +/**@brief Parameters for a normal radio timeslot request. */ typedef struct { uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ @@ -309,15 +305,15 @@ typedef struct uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ } nrf_radio_request_normal_t; -/**@brief Radio request parameters. */ +/**@brief Radio timeslot request parameters. */ typedef struct { uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ union { - nrf_radio_request_earliest_t earliest; /**< Parameters for a request for a timeslot as early as possible. */ - nrf_radio_request_normal_t normal; /**< Parameters for a normal radio request. */ - } params; + nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */ + nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */ + } params; /**< Parameter union. */ } nrf_radio_request_t; /**@brief Return parameters of the radio timeslot signal callback. */ @@ -332,12 +328,12 @@ typedef struct } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ struct { - uint32_t length_us; /**< Requested extension of the timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ + uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ - } params; + } params; /**< Parameter union. */ } nrf_radio_signal_callback_return_param_t; -/**@brief The radio signal callback type. +/**@brief The radio timeslot signal callback type. * * @note In case of invalid return parameters, the radio timeslot will automatically end * immediately after returning from the signal callback and the @@ -351,14 +347,28 @@ typedef struct */ typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); +/**@brief AES ECB parameter typedefs */ +typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */ +typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */ +typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */ + /**@brief AES ECB data structure */ typedef struct { - uint8_t key[SOC_ECB_KEY_LENGTH]; /**< Encryption key. */ - uint8_t cleartext[SOC_ECB_CLEARTEXT_LENGTH]; /**< Clear Text data. */ - uint8_t ciphertext[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Cipher Text data. */ + soc_ecb_key_t key; /**< Encryption key. */ + soc_ecb_cleartext_t cleartext; /**< Cleartext data. */ + soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */ } nrf_ecb_hal_data_t; +/**@brief AES ECB block. Used to provide multiple blocks in a single call + to @ref sd_ecb_blocks_encrypt.*/ +typedef struct +{ + soc_ecb_key_t* p_key; /**< Pointer to the Encryption key. */ + soc_ecb_cleartext_t* p_cleartext; /**< Pointer to the Cleartext data. */ + soc_ecb_ciphertext_t* p_ciphertext; /**< Pointer to the Ciphertext data. */ +} nrf_ecb_hal_data_block_t; + /**@} */ /**@addtogroup NRF_SOC_FUNCTIONS Functions @@ -389,133 +399,13 @@ SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); */ SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); -/**@brief Enable External Interrupt. - * @note Corresponds to NVIC_EnableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was enabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. - */ -SVCALL(SD_NVIC_ENABLEIRQ, uint32_t, sd_nvic_EnableIRQ(IRQn_Type IRQn)); - -/**@brief Disable External Interrupt. - * @note Corresponds to NVIC_DisableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was disabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - */ -SVCALL(SD_NVIC_DISABLEIRQ, uint32_t, sd_nvic_DisableIRQ(IRQn_Type IRQn)); - -/**@brief Get Pending Interrupt. - * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. - * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. - * - * @retval ::NRF_SUCCESS The interrupt is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_GETPENDINGIRQ, uint32_t, sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)); - -/**@brief Set Pending Interrupt. - * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt is set pending. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_SETPENDINGIRQ, uint32_t, sd_nvic_SetPendingIRQ(IRQn_Type IRQn)); - -/**@brief Clear Pending Interrupt. - * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_CLEARPENDINGIRQ, uint32_t, sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)); - -/**@brief Set Interrupt Priority. - * @note Corresponds to NVIC_SetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * @pre Priority is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. - * @param[in] priority A valid IRQ priority for use by the application. - * - * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. - */ -SVCALL(SD_NVIC_SETPRIORITY, uint32_t, sd_nvic_SetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t priority)); - -/**@brief Get Interrupt Priority. - * @note Corresponds to NVIC_GetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. - * @param[out] p_priority Return value from NVIC_GetPriority. - * - * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. - */ -SVCALL(SD_NVIC_GETPRIORITY, uint32_t, sd_nvic_GetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t * p_priority)); - -/**@brief System Reset. - * @note Corresponds to NVIC_SystemReset in CMSIS. - * - * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN - */ -SVCALL(SD_NVIC_SYSTEMRESET, uint32_t, sd_nvic_SystemReset(void)); - -/**@brief Enters critical region. - * - * @post Application interrupts will be disabled. - * @sa sd_nvic_critical_region_exit - * - * @param[out] p_is_nested_critical_region 1: If in a nested critical region. - * 0: Otherwise. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_NVIC_CRITICAL_REGION_ENTER, uint32_t, sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)); - -/**@brief Exit critical region. - * - * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. - * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. - * - * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_NVIC_CRITICAL_REGION_EXIT, uint32_t, sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)); - /**@brief Query the capacity of the application random pool. * * @param[out] p_pool_capacity The capacity of the pool. * * @retval ::NRF_SUCCESS */ -SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); +SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); /**@brief Get number of random bytes available to the application. * @@ -523,7 +413,7 @@ SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY, uint32_t, sd_rand_application_pool_cap * * @retval ::NRF_SUCCESS */ -SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); +SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); /**@brief Get random bytes from the application pool. * @@ -533,7 +423,7 @@ SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE, uint32_t, sd_rand_application_bytes_ * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. */ -SVCALL(SD_RAND_APPLICATION_GET_VECTOR, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); +SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); /**@brief Gets the reset reason register. * @@ -553,12 +443,12 @@ SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t r /**@brief Sets the power mode when in CPU sleep. * - * @param[in] power_mode The power mode to use when in CPU sleep. @sa sd_app_evt_wait + * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait * * @retval ::NRF_SUCCESS The power mode was set. * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. */ -SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(nrf_power_mode_t power_mode)); +SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode)); /**@brief Puts the chip in System OFF mode. * @@ -579,12 +469,12 @@ SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); /**@brief Sets the power-fail threshold value. * - * @param[in] threshold The power-fail threshold value to use. + * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS. * * @retval ::NRF_SUCCESS The power failure threshold was set. * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. */ -SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(nrf_power_failure_threshold_t threshold)); +SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold)); /**@brief Sets bits in the NRF_POWER->RAMON register. * @@ -636,14 +526,14 @@ SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t *p_gpregr /**@brief Sets the DCDC mode. * - * This function is to enable or disable the DCDC periperhal. + * Enable or disable the DCDC peripheral. * - * @param[in] dcdc_mode The mode of the DCDC. + * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES. * * @retval ::NRF_SUCCESS * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. */ -SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(nrf_power_dcdc_mode_t dcdc_mode)); +SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode)); /**@brief Request the high frequency crystal oscillator. * @@ -791,25 +681,30 @@ SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have * to shorten the connection events to have time for the Radio Notification signals. * - * @param[in] type Type of notification signal. + * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES. * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is * recommended (but not required) to be used with * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. * - * @param[in] distance Distance between the notification signal and start of radio activity. + * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES. * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or - * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. + * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. * * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. * @retval ::NRF_SUCCESS */ -SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(nrf_radio_notification_type_t type, nrf_radio_notification_distance_t distance)); +SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance)); /**@brief Encrypts a block according to the specified parameters. * * 128-bit AES encryption. * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input * parameters and one output parameter). * @@ -817,6 +712,23 @@ SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(nr */ SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); +/**@brief Encrypts multiple data blocks provided as an array of data block structures. + * + * @details: Performs 128-bit AES encryption on multiple data blocks + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in] block_count Count of blocks in the p_data_blocks array. + * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of + * @ref nrf_ecb_hal_data_block_t structures. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks)); + /**@brief Gets any pending events generated by the SoC API. * * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. @@ -833,8 +745,6 @@ SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); * This function will block until the temperature measurement is done. * It takes around 50us from call to return. * - * @note Pan #28 in PAN-028 v 1.6 "Negative measured values are not represented correctly" is corrected by this function. - * * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees celsius. * * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp @@ -863,11 +773,11 @@ SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); * * @param[in] p_dst Pointer to start of flash location to be written. * @param[in] p_src Pointer to buffer with data to be written. -* @param[in] size Number of 32-bit words to write. Maximum size is 256 32bit words. +* @param[in] size Number of 32-bit words to write. Maximum size is 256 32-bit words for nRF51 and 1024 for nRF52. * * @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. * @retval ::NRF_ERROR_BUSY The previous command has not yet completed. -* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or more than 256 words. +* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size. * @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location. * @retval ::NRF_SUCCESS The command was accepted. */ @@ -905,19 +815,23 @@ SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)) /**@brief Flash Protection set * - * Commands to set the flash protection registers PROTENSETx + * Commands to set the flash protection configuration registers. + On nRF51 this sets the PROTENSETx registers of the MPU peripheral. + On nRF52 this sets the CONFIGx registers of the BPROT peripheral. * - * @note To read the values in PROTENSETx you can read them directly. They are only write-protected. + * @note To read the values read them directly. They are only write-protected. * - * @param[in] protenset0 Value to be written to PROTENSET0. - * @param[in] protenset1 Value to be written to PROTENSET1. + * @param[in] block_cfg0 Value to be written to the configuration register. + * @param[in] block_cfg1 Value to be written to the configuration register. + * @param[in] block_cfg2 Value to be written to the configuration register (ignored on nRF51). + * @param[in] block_cfg3 Value to be written to the configuration register (ignored on nRF51). * * @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice. - * @retval ::NRF_SUCCESS Values successfully written to PROTENSETx. + * @retval ::NRF_SUCCESS Values successfully written to configuration registers. */ -SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_t protenset1)); +SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t block_cfg0, uint32_t block_cfg1, uint32_t block_cfg2, uint32_t block_cfg3)); -/**@brief Opens a session for radio requests. +/**@brief Opens a session for radio timeslot requests. * * @note Only one session can be open at a time. * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot @@ -939,7 +853,7 @@ SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_ */ SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); -/**@brief Closes a session for radio requests. +/**@brief Closes a session for radio timeslot requests. * * @note Any current radio timeslot will be finished before the session is closed. * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. @@ -955,8 +869,7 @@ SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_ /**@brief Requests a radio timeslot. * * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST - * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type - * @ref NRF_RADIO_REQ_TYPE_EARLIEST. + * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST. * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by * p_request->distance_us and is given relative to the start of the previous timeslot. * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. @@ -987,6 +900,9 @@ SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_ /**@} */ +#ifdef __cplusplus +} +#endif #endif // NRF_SOC_H__ /**@} */ diff --git a/components/softdevice/s130/headers/nrf_svc.h b/components/softdevice/s130/headers/nrf_svc.h index 8c84a9c..20f7c8d 100644 --- a/components/softdevice/s130/headers/nrf_svc.h +++ b/components/softdevice/s130/headers/nrf_svc.h @@ -37,6 +37,12 @@ #ifndef NRF_SVC__ #define NRF_SVC__ +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + #ifdef SVCALL_AS_NORMAL_FUNCTION #define SVCALL(number, return_type, signature) return_type signature #else @@ -45,22 +51,29 @@ #if defined (__CC_ARM) #define SVCALL(number, return_type, signature) return_type __svc(number) signature #elif defined (__GNUC__) -#define SVCALL(number, return_type, signature) \ - _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ - __attribute__((naked)) static return_type signature \ - { \ - __asm( \ - "svc %0\n" \ - "bx r14" : : "I" (number) : "r0" \ - ); \ - } \ +#ifdef __cplusplus +#define GCC_CAST_CPP (uint8_t) +#else +#define GCC_CAST_CPP +#endif +#define SVCALL(number, return_type, signature) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ + __attribute__((naked)) \ + __attribute__((unused)) \ + static return_type signature \ + { \ + __asm( \ + "svc %0\n" \ + "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ + ); \ + } \ _Pragma("GCC diagnostic pop") + #elif defined (__ICCARM__) #define PRAGMA(x) _Pragma(#x) -#define SVCALL(number, return_type, signature) \ -PRAGMA(swi_number = number) \ +#define SVCALL(number, return_type, signature) \ +PRAGMA(swi_number = (number)) \ __swi return_type signature; #else #define SVCALL(number, return_type, signature) return_type signature @@ -68,4 +81,8 @@ PRAGMA(swi_number = number) \ #endif // SVCALL #endif // SVCALL_AS_NORMAL_FUNCTION + +#ifdef __cplusplus +} +#endif #endif // NRF_SVC__ diff --git a/components/softdevice/s130/headers/softdevice_assert.h b/components/softdevice/s130/headers/softdevice_assert.h deleted file mode 100644 index a2a8af8..0000000 --- a/components/softdevice/s130/headers/softdevice_assert.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** @brief Utilities for verifying program logic - */ - -#ifndef SOFTDEVICE_ASSERT_H_ -#define SOFTDEVICE_ASSERT_H_ - -#include - -/** @brief This function handles assertions. - * - * - * @note - * This function is called when an assertion has triggered. - * - * - * @param line_num The line number where the assertion is called - * @param file_name Pointer to the file name - */ -void assert_softdevice_callback(uint16_t line_num, const uint8_t *file_name); - - -/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ -/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \ -/** @brief Check intended for production code - * - * Check passes if "expr" evaluates to true. */ -#define ASSERT(expr) \ -if (expr) \ -{ \ -} \ -else \ -{ \ - assert_softdevice_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \ - /*lint -unreachable */ \ -} - -#endif /* SOFTDEVICE_ASSERT_H_ */ diff --git a/components/softdevice/s130/hex/s130_nrf51_1.0.0_softdevice.hex b/components/softdevice/s130/hex/s130_nrf51_1.0.0_softdevice.hex deleted file mode 100644 index d6fe985..0000000 --- a/components/softdevice/s130/hex/s130_nrf51_1.0.0_softdevice.hex +++ /dev/null @@ -1,6861 +0,0 @@ -:020000040000FA -:10000000C0070000D1060000D1000000B1060000CA -:1000100000000000000000000000000000000000E0 -:100020000000000000000000000000005107000078 -:100030000000000000000000DB000000E500000000 -:10004000EF000000F9000000030100000D010000B6 -:1000500017010000210100002B0100003501000004 -:100060003F01000049010000530100005D01000054 -:1000700067010000710100007B01000085010000A4 -:100080008F01000099010000A3010000AD010000F4 -:10009000B7010000C1010000CB010000D501000044 -:1000A000DF010000E9010000F3010000FD01000094 -:1000B00007020000110200001B02000025020000E0 -:1000C0001FB5C046C04600F0EFFA04B00FB41FBD24 -:1000D00008205A49096809580847382057490968CB -:1000E000095808473C2055490968095808474020E5 -:1000F0005249096809580847442050490968095875 -:10010000084748204D490968095808474C204B4981 -:10011000096809580847502048490968095808479C -:100120005420464909680958084758204349096836 -:10013000095808475C204149096809580847602068 -:100140003E4909680958084764203C49096809582C -:100150000847682039490968095808476C20374919 -:100160000968095808477020344909680958084740 -:100170007420324909680958084778202F490968CE -:10018000095808477C202D490968095808478020EC -:100190002A490968095808478420284909680958E4 -:1001A0000847882025490968095808478C202349B1 -:1001B00009680958084790202049096809580847E4 -:1001C00094201E4909680958084798201B49096866 -:1001D000095808479C201949096809580847A02070 -:1001E0001649096809580847A4201449096809589C -:1001F0000847A8201149096809580847AC200F4949 -:10020000096809580847B0200C4909680958084787 -:10021000B4200A49096809580847B82007490968FD -:1002200009580847BC2005490968095808470000D3 -:1002300003480449024A034B7047000000000020B5 -:10024000C0070000C00700000122D84B5A6000BF61 -:10025000D74A1268002AFBD0016000BFD44A126856 -:10026000002AFBD00022D14B5A6000BFD04A12684E -:10027000002AFBD07047F0B505460E46174600240D -:1002800006E0A200B158A2005019FFF7DDFF641C80 -:10029000BC42F6D30020F0BD0120C043C549086030 -:1002A000401048607047014601229204086890425D -:1002B00001D9102070470020FCE7F0B505460C4638 -:1002C0001646002706E028462168FFF7BDFF2D1DD2 -:1002D000241D7F1CB742F6D3F0BD70B505460C4611 -:1002E0002E460BE0304600F075F9FF2C01D80024B3 -:1002F00001E0FF3C013C012080023618002CF1D1C6 -:1003000070BD0146012212044868904201D90920BB -:100310007047A9484069401C01D10F20F8E7002030 -:10032000F6E7FEB504462068030000F037FA05043E -:100330002B4249598B00201DFFF7E3FF0546002D96 -:1003400001D02846FEBDFFF7A7FF0120C00200F044 -:1003500041F9042221469948FFF78DFF002801D07A -:100360000320EFE708222146944800F06DF90028A9 -:1003700006D1002192480068FFF766FF00F00CF9F3 -:100380000320DFE7A768E6686068019031463846D9 -:10039000FFF7A3FF324638460199FFF78EFFB20000 -:1003A0003846019900F050F9002800D1CAE703202F -:1003B000C8E700F0E3F9834800688349086041E03A -:1003C00060680190E668A0680090B200009901980A -:1003D00000F03AF90746002F00D1B3E70E20B1E74D -:1003E000201DFFF760FF0546002D01D02846A9E734 -:1003F0006068002807D1FFF74FFF0320800200F05C -:10040000E9F800F0C9F8FFF747FF0120C00200F04B -:10041000E1F8042221466948FFF72DFF002801D0AA -:1004200003208FE708222146644800F00DF90028D8 -:1004300006D1002162480068FFF706FF00F0ACF823 -:1004400003207FE700BF00207CE770B505460C461F -:10045000182D04D12068FFF764FF206002E001201E -:10046000206000BF00BF70BDF0B589B05248406940 -:1004700003905248806881000398081802900398FE -:10048000000B01900121090302984018401E000B47 -:1004900000900124002520462946019A00F0C4F866 -:1004A0000022401E91410791069001260027304608 -:1004B0003946009A00F0B8F80022401E914105919B -:1004C0000490049BDB43059AD2430698184307998E -:1004D00011430791069037490698086007984860CD -:1004E00009B0F0BD70B53448446934488568466841 -:1004F000AA003146204600F0A7F8002801D00020CD -:1005000070BD0120FCE72D484068002801D0012083 -:1005100000E000200546FFF7E5FF002807D0FFF7C1 -:10052000BBFE0320800200F055F800F035F8FFF71D -:100530009BFF002D0ED020484669204884684768FC -:1005400021463046FFF7C9FE224639463046FFF7BE -:10055000B4FE00BF00F020F810B5184844681A48EF -:100560000460204600F0DCF810BD15480068006803 -:10057000401C01D100BFFEE710480068002802D0EF -:10058000042806D101E0FFF7BEFFFFF7E5FF00BF3B -:10059000FEE700BF00BFFEE7BFF34F8F0B480C49DB -:1005A000C860BFF34F8F00BFFEE7000000E50140C9 -:1005B00000E40140000600400010001000080000A8 -:1005C000B8070000BC070000000000200400FA0586 -:1005D00000ED00E010B50146104B1A6808460223F2 -:1005E0000F4C636000BF0F4B1B68002BFBD0531CEC -:1005F00004D0904202D20A4B186101E0084B986087 -:1006000000BF084B1B68002BFBD00023044C636029 -:1006100000BF044B1B68002BFBD010BD0010001066 -:1006200000E5014000E4014010B5202A04DB01464A -:10063000203A9140002010BD914020239C1A03468F -:10064000E3401943904010BD034610B50B439B0790 -:100650000FD1042A0DD308C810C9121FA342F8D025 -:1006600018BA21BA884201D9012010BD0020C04328 -:1006700010BD002A03D0D30703D0521C07E000208E -:1006800010BD03780C78401C491C1B1B07D1037854 -:100690000C78401C491C1B1B01D1921EF1D118463D -:1006A00010BD70477047704710B500F007F810BDD7 -:1006B000014B1B68DB6818470000002019481A49E5 -:1006C0007047FFF7FBFFFFF7FBFC00BD20BFFDE716 -:1006D0001649174C24688C420BD1164B1B68994263 -:1006E0000CD1154B154A1360186810498842EDD09B -:1006F0000AE0134880F30888124B18470F4A13602A -:1007000018680A498842E1D080F308880E49884277 -:1007100004DD0E48026802210A4302605B68184744 -:100720000346DFE7C0070000C0070000FFFFFFFF30 -:10073000000C000014100010001000000000002049 -:10074000000400206B05000000200020240500406C -:100750000D48704502D1EFF3098101E0EFF3088104 -:10076000886902380078182802D1C046074A104725 -:10077000074A12682C3212681047000000B5054B7A -:10078000054A9B58984700BDFDFFFFFF4B04000042 -:1007900000000020001000000400000030B4744687 -:1007A000641E2578641CAB4204D3635D5B00E318D0 -:1007B00030BC18471D46F8E7000C00000010000090 -:10100000F0210020FDB101005D22000063B101006C -:1010100000000000000000000000000000000000D0 -:101020000000000000000000000000006DB20100A0 -:1010300000000000000000005D2200005D220000B2 -:10104000D9B20100DFB201005D2200005D22000084 -:101050005D2200005D2200005D2200005D22000094 -:10106000E5B201005D2200005D220000EBB201004C -:101070005D220000F1B20100F7B20100FDB20100F3 -:101080005D2200005D2200005D2200005D22000064 -:101090005D2200005D2200005D2200005D22000054 -:1010A00003B3010009B301005D2200005D220000CE -:1010B0005D2200005D2200005D2200005D22000034 -:1010C00000F002F81AF07BF80CA030C80838241899 -:1010D0002D18A246671EAB4654465D46AC4201D170 -:1010E0001AF06DF87E460F3E0FCCB646012633420D -:1010F00000D0FB1AA246AB46334318477CA301003D -:10110000ACA30100103A02D378C878C1FAD85207CC -:1011100001D330C830C101D504680C6070470000AD -:101120000023002400250026103A01D378C1FBD803 -:10113000520700D330C100D50B6070471FB5C046C1 -:10114000C04619F0DEFF04B00FB41FBDF0B4404636 -:10115000494652465B460FB402A0013001B506482D -:10116000004700BF01BC86460FBC804689469246B8 -:101170009B46F0BC70470000C11000008269024924 -:101180008161024810447047911100000100000085 -:1011900001B41EB400B501F000FF01B40198864609 -:1011A00001BC01B01EBD0000401E00BF00BF00BF5B -:1011B00000BF00BF00BF00BF00BF00BF00BF00BF37 -:1011C00000BFF1D17047000070B505460C461646C9 -:1011D00002E00FCC0FC5103E102EFAD2082E02D31B -:1011E00003CC03C5083E042E07D301CC01C5361F2E -:1011F00003E021782970641C6D1C761EF9D270BD45 -:101200008307FF22DB0E9A408907090E99400028C8 -:101210000BDA0007000F0838830828489B001818CD -:10122000C36993430B43C3617047830824489B0001 -:101230001B181868904308431860704710B504469F -:1012400000210120FFF7DCFF00211820FFF7D8FF65 -:1012500000210B20FFF7D4FF02211920FFF7D0FF58 -:1012600002210D20FFF7CCFF02210E20FFF7C8FF5F -:1012700002210F20FFF7C4FF0221C81FFFF7C0FFA4 -:1012800003211620FFF7BCFF03211520FFF7B8FF4D -:10129000204600F019F8002010BD6721018070473A -:1012A00010B500F020F810BD0648704710B500F0EA -:1012B00022F810BD704770477047000000ED00E055 -:1012C00000E400E003F9004370B505462D4C08200A -:1012D0002070A01CFFF7E1FF5920A080294620467E -:1012E00000F0B3FB70BD10B500F0B8FB254900203D -:1012F000891E087010BDF8B5224E0446B61E30781F -:1013000001270D46002807D0204660380B2808D852 -:10131000204600F059FF2BE0602CF9D01A480860F5 -:10132000F8BD20466C38032803D8204600F08DFF16 -:101330001EE0204670381F2803D8204600F047F9E9 -:1013400016E0204690380F2803D8204600F0EAF82F -:101350000EE02046A0380F2803D8204600F076F88B -:1013600006E02046B0380F2804D8204600F0E2F905 -:10137000286000E02F60602CD2D128680028CFD1EF -:101380003770F8BD1A000020013000000120254907 -:10139000C003086024490020087007202349C005C5 -:1013A0008860704770B5204D04462878A04207D069 -:1013B000002C05D0002803D01DA14D2019F0CBFE34 -:1013C0002878A0420ED000211E4A18482C70002C0C -:1013D0001BD01D4B012C06D0022C0DD014A168206F -:1013E00019F0B9FE70BD1160022111605361032133 -:1013F00009068160416070BD116003211160536175 -:101400000121C9058160416070BD11601160072133 -:10141000C905816070BD10B505A1712019F09BFE52 -:1014200010BD000080E100E02000002000F5014038 -:101430007372635C68616C5F63636D5F6161722E80 -:101440006300000000F500408401002010B5A038C2 -:10145000030019F0A1FF0B070E172028313A414B6A -:10146000525C65004B6808788A68194603F0D9F920 -:1014700010BD88888A6883B20888194680B203F054 -:10148000DFF910BD08884C68CB688A6880B22146B5 -:1014900003F0DAF910BD08884B688A6880B21946F3 -:1014A00003F0EEF910BD88888A6883B2088819466F -:1014B00080B203F0FAF910BD88888A6883B2088880 -:1014C000194680B203F034FA10BD08884A6880B229 -:1014D000114603F073FA10BD088982B2888883B27E -:1014E0000888194680B203F074FA10BD08884A686B -:1014F00080B2114603F091FA10BD08894C6882B29F -:101500000888CB6880B2214603F00AFB10BD08882A -:101510004C68CB688A6880B2214603F01BFC10BD82 -:10152000012010BD10B59038030019F035FF0906F1 -:101530000F161D242C363F464E0088888A6883B2D9 -:101540000888194680B204F01DF910BD08884A6861 -:1015500080B2114604F051F910BD08884A6880B283 -:10156000114604F056F910BD08884A6880B2114649 -:1015700004F05CF910BD08884B688A6880B219468F -:1015800004F067F910BD088982B2888883B20888A0 -:10159000194680B204F066F910BD08894B6882B222 -:1015A0000888194680B204F07CF910BD08884A68A2 -:1015B00080B2114604F087F910BD888882B208888D -:1015C000114680B204F0DBF910BD012010BD10B54A -:1015D0007038030019F0E0FE1B0F15192125282F84 -:1015E000363B4044484C53585F68707881889095EA -:1015F000999CA2A5AC004A680878114607F019FC2E -:1016000010BD086807F066FC10BD0C790B7B8A687A -:101610000868214607F06FFC10BD086807F000FD60 -:1016200010BD07F08CF910BD08884A6880B21146D9 -:1016300007F034FE10BD0A790888114680B207F021 -:10164000C4FE10BD087840B207F0CDFE10BD08887A -:1016500080B207F0E1FE10BD086807F0EFFE10BD94 -:10166000086801F0ECFB10BD086801F016FC10BD25 -:10167000088982B209C9194607F0F8FE10BD05C9EC -:10168000114607F042FF10BD08884A6880B2114633 -:1016900009F0FAF910BD0C790888CB688A6880B225 -:1016A000214609F0CDFA10BD0B7908888A6880B20E -:1016B000194609F07DFC10BD08884B688A6880B225 -:1016C000194609F0EEFC10BD08884C68CB688A68A2 -:1016D00080B2214609F053FD10BD08884A6880B2E7 -:1016E000114609F08CFD10BD0B7908880A7A80B28A -:1016F000194607F02DFF10BD088880B207F02DFFB6 -:1017000010BD086807F030FF10BD07F0FCF810BDF1 -:101710008A6809C9194607F08CFF10BD07F0DCF88C -:1017200010BD08884A6880B2114608F05BF810BD09 -:10173000012010BD10B5B02805D0B12808D0B228BE -:101740000BD0012010BD088880B20AF056F910BDF8 -:10175000088880B20AF070F910BD08884B688A6862 -:1017600080B219460AF079F910BD000010B50300E7 -:1017700019F012FE0A0609060C0C0F0F06060612D7 -:1017800007F005F910BD09F027FF10BD01F042FA7E -:1017900010BD06F075FA10BDFAA1FE4819F0DBFC89 -:1017A00010BD7FB5FC49054603C901900291132085 -:1017B000800169468881F94A0F2310460A2128389A -:1017C0000AF043FE0024F6480AF05DFE641CE4B211 -:1017D0000A2CF8D304200090F04801231A4603A9EC -:1017E000F0300AF05DFA002804D0FF20E5A1533064 -:1017F00019F0B1FC686800F024FC00211E220846A4 -:1018000004F040F907F0C6FA02222421E54801F06D -:101810007FFBE44801222C214C3001F079FBE149A7 -:101820000B20B03901F000FA002804D0FF20D5A128 -:10183000673019F090FC09F09FFE02F075F901ABDA -:1018400000220821D8A007F085F9002804D0FF2045 -:10185000CCA16D3019F07FFC284602F0C2FC0028B4 -:1018600004D0FF20C7A16F3019F075FCDB2189007F -:10187000D04819F045FBCF48012141710221817107 -:101880000621C1717FBD10B5CA4CA078092804D3C8 -:10189000FF20BCA1A73019F05EFC207860214843EE -:1018A000001900210173417BF722C908C900C91C36 -:1018B0001140EF22114041730121E1700C3010BD45 -:1018C00070B50E4600211C4619801546030019F01C -:1018D00063FD0723050B1711231D2300224629460C -:1018E000304609F096FE70BD22462946304606F085 -:1018F00098FE70BD22462946304601F0C2FF70BDF9 -:1019000022462946304603F0C0FD70BD22462946D6 -:10191000304600F010FC70BD9E489AA1D53819F0F1 -:101920001AFC032070BD70B5A24CE078002818D0D6 -:101930002078602148430019407B00254007400F74 -:1019400001190879401E08712078401CC0B220702F -:10195000092800D12570A078401CA0700AF01DFF56 -:10196000E57070BD9348C079002800D08BE77047C0 -:1019700070B5904DA86800280CD0FFF7F3FF002841 -:1019800062D06022A968FFF71FFCFFF7CCFF0020A0 -:10199000A860EFE76879002856D0FFF774FF044687 -:1019A00080484C3001F0C4FA6060002804D1C9209E -:1019B00074A1800019F0CFFB60680AF0EAF80028F3 -:1019C0000DD0204606F011FD6078010703D5C00850 -:1019D000C000401C2BE0734861684C302DE071481A -:1019E00061684C3001F0ADFA00F05AFB00282BD1B1 -:1019F000FFF749FF04466B4801F09AFA606000283F -:101A000004D164485FA16D3019F0A5FB60680AF04D -:101A1000C4F8002814D0606800886080204609F06F -:101A20002BFE6078010706D5C008C000801C6070DE -:101A3000FFF779FF9EE75B48616801F082FA99E75A -:101A40005848616801F07DFA70BD10B55A4CE160EC -:101A5000A0605A4800F034FC607010BD5649002068 -:101A60000870704770B5564E0546706A94B00C46C3 -:101A7000401C04D1B06AC0430004000C0BD0306A93 -:101A8000C007C00F2870706A19F03CFAB06A207164 -:101A9000000A607114E02B206946087009A96846A5 -:101AA0000AF04BF8002804D0972036A1800019F0E6 -:101AB00052FB0120287006220AA9204619F0C1F91C -:101AC0002878002803D06079C0210843607114B0E1 -:101AD00070BDF0B53A4C0646206895B00D463746C5 -:101AE0000837401C08D16068401C05D1A068401C24 -:101AF00002D1E068401C11D02068314619F002FA8A -:101B00006068311D19F0FEF9A068394619F0FAF93C -:101B1000E06831460C3119F0F5F925E02B206946D3 -:101B2000087009A968460AF008F8002804D0194886 -:101B300014A1553819F00FFB08220AA9304619F0F4 -:101B400080F92B206946087009A9684609F0F5FF5D -:101B5000002804D0A3200BA1800019F0FCFA082271 -:101B60000AA9384619F06DF920692E460836401C3E -:101B700029D16069401C26D1A069401C23D1E069AD -:101B8000401C1FE07372635C686F73745F636F72F5 -:101B9000652E6300DA020000B4B30100D801002012 -:101BA0006D170000A40B00206E52463531383232DA -:101BB00000000000880700202400002071190000A8 -:101BC0008000001012D02069294619F09BF9606945 -:101BD000291D19F097F9A069314619F093F9E069C8 -:101BE00029460C3119F08EF915B0F0BD2B2468464A -:101BF000047009A909F0A1FF002803D0F649F748AD -:101C000019F0A9FA082209AF28460AA919F019F90A -:101C10006846047009A909F090FF002804D0EF4835 -:101C2000ED49C01D19F097FA0822391D304619F008 -:101C300008F9D9E770B5EA4C0546A068002804D039 -:101C40000320E549000219F086FAA56070BD10B5C1 -:101C50000146E44801F075F9E1498879401CC0B2B9 -:101C60008871012803D1E048407800F04DFB10BD99 -:101C700070B50446DD4816460D46814204D1D7486A -:101C8000D549CB3019F067FA012E05D0E120D249B1 -:101C9000800019F060FA70BD66202070002020726C -:101CA000A5810120A07370BD70B515460C4606468F -:101CB000FFF758FE00280CD06621017046800121F4 -:101CC000017221680161A18881820573FFF72BFEF3 -:101CD00070BD1321304607F078FB70BDC2494968DA -:101CE000884201D210207047032101700020704704 -:101CF00070B5BD4C05462078002694B0002801D070 -:101D00000820E4E6BA4A6260954201D21020DEE67D -:101D10006868002809D00921D82804D3C31C9B086F -:101D20009B00834205D00846D1E60320400268604C -:101D30000EE0012109074B6B896B4B43AD49511AEA -:101D40000122591AD202891A814201D20421EAE7FA -:101D500000F052FF6178A0680CF04EFBE068401E76 -:101D600007280BD8302269460A70887068460DF043 -:101D700088FF002802D009A80CF0FBFC2846FFF7DA -:101D800010FD012020703046A1E6F8B504469648C3 -:101D90000F464068814208D3002C01D0844204D30E -:101DA000E01C80088000A04201D01020F8BD8C48C3 -:101DB0008178002911D039880091417860225143FF -:101DC0000D18287B0C350007000F3B4600222946E2 -:101DD000FFF776FD060004D015E0002038800520CE -:101DE000F8BD002C13D039880098814201D90C2607 -:101DF0000DE028783B460007000F22462946FFF7F2 -:101E00005FFD060005D00C2E01D000203880304642 -:101E1000F8BD734C6078401CC0B26070092801D1D5 -:101E200000206070A078401EA07068784107490FBC -:101E300001290ED0022906D003291AD066496E481E -:101E400019F089F9E3E7C006E1D46868FFF7FFFEFF -:101E5000DDE7644869684C3001F073F86079401C34 -:101E6000C0B260710128D2D15F48407800F04CFACE -:101E7000CDE7E079401CE071C9E7604A10B59042B7 -:101E800009D3594A0124A4045268A04201D39042C4 -:101E900001D3914201D2102010BD00F0FEFE10BD12 -:101EA000564B10B5994209D34F4B0124A4045B68EB -:101EB000A14201D3994201D39A4201D2102010BD10 -:101EC000022803D0102801D0092010BD00F00BFF1C -:101ED0000028FAD0052010BD484B10B598420DD30C -:101EE000414B0124A4045B68A04201D3984205D36E -:101EF000994203D3002A03D09A4201D2102010BD88 -:101F000000F017FF0028FAD0072010BD10B50446D6 -:101F1000354894B04068844202D2102014B010BDFD -:101F20000F2008A9087369460BA809F006FE0028CF -:101F3000F4D16846007A207068464089608068461F -:101F40008089A0800020E9E710B500290BD0264A3F -:101F50005268914202D30B68934201D2102010BD07 -:101F60008A88002A02D001F037FE10BD092010BD7A -:101F700010B5224A94B091420ED31B4A01239B0410 -:101F80005268994201D3914206D3441E1E2C41D877 -:101F9000994203D3914201D21020BFE7012837D1E3 -:101FA00008780024C007C00F002803D0032069462A -:101FB000887001E06846847038206946087009A975 -:101FC000684609F0BAFD002804D004480CA18B38FB -:101FD00019F0C1F82046A1E7841B0000AA02000006 -:101FE00088070020A40B002024000020FFFF000031 -:101FF00000220020000000202104000000C0010099 -:102000007372635C686F73745F636F72652E6300D5 -:10201000072083E70246203A1F2AF9D806F001FE7E -:102020007CE710B5604A5268914201D2102010BD81 -:102030000246203A1F2A02D806F068FE10BD07208B -:1020400010BD70B50546594C002020702046461939 -:1020500055484660E01C80088000A04204D0FF2064 -:102060005349293019F077F801200007C06AC043AE -:102070000006000E03D14F480068401C03D04E48B4 -:102080004E49301AC862A8B20422214604F00DF964 -:10209000002804D0FF204649393019F05CF870BDA3 -:1020A000F0B595B03B2008A9087369460BA809F064 -:1020B00044FD002804D0FF203D49813019F04BF841 -:1020C0003F4E00246D4630E02F19B87DC10706D081 -:1020D000400704D460004019C08809F0E9FB394882 -:1020E000807900281FD0B87D80071CD5600040197A -:1020F000C0880022062109F0F7FB002813D03C21FC -:1021000008A8017360004019C1886846C185694606 -:102110000BA809F012FD06000BD0FF2024499630D1 -:1021200019F019F805E0641CE4B268460079A04291 -:10213000CAD8304658E5F7B50546007800270009AB -:102140000C463E46062804D0FF201949BF3019F03E -:1021500002F8287A00280ED0012814D0FF20144954 -:10216000E03018F0F8FF0298002C068001D027809C -:1021700066800020FEBD02270926002C10D0A88909 -:10218000A080A87B0AE003271426002C08D06888CA -:10219000A0802869E060A88A2082287B2072E2E77C -:1021A00002980680E5E700002400002000220020BD -:1021B000002000000010001000000020000500407A -:1021C000043000008807002010B56038030019F0C3 -:1021D000E3F80A060A0F13181F252930353A086854 -:1021E000FFF786FD10BD05C91146FFF7CEFD10BDF6 -:1021F0000868FFF773FD10BD05C91146FFF73DFEE6 -:1022000010BD4B6808788A681946FFF749FE10BD73 -:102210008A6809C91946FFF75FFE10BD0868FFF715 -:1022200075FE10BD08884A6880B21146FFF78CFE23 -:1022300010BD05C91146FFF79BFE10BD05C911462B -:10224000FFF7EFFE10BD012010BD01207047000018 -:102250000E4A12680C498A420AD118470B4A126882 -:10226000094B9A4204D101B500F08EFE03BC8E46A4 -:10227000074909680958084706480749054A064BAF -:102280007047000000000000BEBAFECA64000020D3 -:1022900004000020F0210020F021002001203F490F -:1022A000400608603E4908603E490A68FF231B0259 -:1022B0009A4383121A430A6038498039086070478C -:1022C00010B502460420384904E0C3005B181B79AE -:1022D000002B0AD00346401EC0B2002BF5D133A11B -:1022E000432018F038FFFF2010BDC300CA50002261 -:1022F00059184A718A7101220A7110BD2A4A0021B7 -:10230000C00080180171704710B50446042803D33B -:1023100026A1522018F01FFF2348E1000C18207955 -:10232000012803D021A1532018F015FF6079A1796D -:10233000401CC0B2814200D06071012017494006A4 -:102340008031086010BD70B5164804250068164E2F -:102350000004800F1B4C02281AD014A1692018F029 -:10236000FAFE15E02078C10088190279012A07D108 -:10237000427983799A4203D04279827170588047BA -:102380002078401CC0B22070042801D300202070A7 -:1023900028466D1EEDB20028E4D170BD80E100E05A -:1023A00080E200E018E400E0200C00207372635C1F -:1023B000736F635F7369676E616C6C696E672E63C0 -:1023C000000000003400002010B5EFF31080C407B7 -:1023D000E40F72B6D2484178491C41704078012818 -:1023E00001D10AF0FFF9002C00D162B610BD70B522 -:1023F000CB4CE07800280AD10125E570FFF7E4FF17 -:102400000AF0F8F9002804D000200AF0CBF90020E7 -:1024100070BDC44865714560F9E770B5EFF3108091 -:10242000C507ED0F72B6BE4C6078002803D1BEA17F -:102430008F2018F090FE6078401E60706078002851 -:1024400001D10AF0D3F9002D00D162B670BD10B5EC -:10245000B348C178002904D000214171C170FFF751 -:10246000DCFF002010BD10B504460AF0C3F9AC49EA -:10247000C978084000D001202060002010BDF8B5C8 -:102480000246A74C0026A67108200421012510272A -:10249000130018F081FF0D080A0C0E101214161EFE -:1024A000262123252800257122E0022001E0217148 -:1024B0001EE020711CE027711AE02020F9E70126B8 -:1024C00016E0FFF781FF0AF095F90028FBD00226FD -:1024D0000EE02171A5710BE02771FBE7202000E0E1 -:1024E00040202071F6E7FF208FA1763018F033FEF0 -:1024F0000AF08CF9002809D00AF08EF9B04205D113 -:1025000030460AF08CF90028FAD02CE00120800730 -:10251000C560894900224A60884A9661814B02223F -:102520005A60856086480269D243D206D51702698F -:1025300010231A4302610F466D1C00E020BF78682B -:102540000028FBD030460AF06AF90028FAD0002DA6 -:1025500004D17B48026910218A430261714902203B -:10256000886000207860A07900280CD00AF042F939 -:1025700005460AF09FF8734A002D02D0A260E06081 -:1025800001E0E260A060002E01D100F0A5F8F8BDE6 -:1025900010B504460AF034F9002805D0604901203E -:1025A000C8704A78521C4A702046FFF768FF10BD79 -:1025B000F8B5614DA8680026012802D1AE600AF086 -:1025C000F1F86868012800D16E6028680127544C32 -:1025D000012812D12E606079002803D000200AF073 -:1025E000E1F866712078002807D00AF003F9002886 -:1025F00003D0012080070761A770286901282AD12C -:102600002E6100F05FF8012080074761A079002863 -:1026100015D00AF0EFF800900AF04CF80099002964 -:1026200001D0E16800E0A168411A022901DA8A1CA0 -:1026300011DC0099002901D0E06000E0A060FFF704 -:10264000C3FE0AF0D7F8002804D0012080070761F4 -:10265000A77000E02770E868012812D100F032F876 -:1026600000F030F800F02EF8A078002804D1FF2008 -:102670002DA1033018F06FFDEE60A6702670FFF7F5 -:10268000CCFEF8BD10B5264CE078002801D10AF048 -:10269000ADF801208107886100F014F8A0780028C7 -:1026A0000BD0254CE068002803D10AF0B8F80028C8 -:1026B000F8D10020E06000F005F800201949C0437F -:1026C000886010BD08B55020694608806A461088A9 -:1026D000411E1180FAD208BDF8B51248192787604B -:1026E000154900200860C8600AF084F8BE0701247C -:1026F0000B4D002802D03461AC7000E02C70FFF765 -:1027000063FE084847600D4928798863FFF7DAFFC0 -:10271000B461FFF7D7FF0849002008617461F8BD74 -:1027200038000020000300407372635C736F635FC6 -:10273000636C6F636B2E6300000100400005004076 -:1027400000ED00E0FFFFFF7F8107C90E002808DAD7 -:102750000007000F083880082E4A80008018C069E2 -:1027600004E080082C4A800080180068C8400006F9 -:10277000800F704710B50D20FFF7E6FFC4B20420AC -:10278000C043FFF7E1FFC0B2844203D023A11A2067 -:1027900018F0E1FC26490120486010BD0121254ABE -:1027A00048031060244B00221A60244A5160244AD6 -:1027B0001060244A11601F49803908607047012168 -:1027C0001C4A480310601F4A51601B4A00211160D7 -:1027D0001B490860704710B517490868012804D0E4 -:1027E0000EA1572018F0B7FC10BD114880680022D8 -:1027F000C0B20A6009F0BEFC10BD10B50E480168F9 -:102800000029FCD0FFF7E7FF01200D4940030860D5 -:1028100010BD000000ED00E000E400E07372635CB6 -:10282000736F635F68616C5F726E672E6300000098 -:1028300000D5004080E100E000D1004000D300401E -:1028400080E200E000D0004030B40121BC48C90261 -:102850000160CD1005604A030260BA4803681B029C -:102860001B0A036004680023240A24020460B6489B -:102870000468240A24020460B4480124446084608B -:10288000B34C23606360A360B24B19601D601A6093 -:10289000B14B19601A600121016030BC704710B45F -:1028A0000121A748CA0202600B0203600C06046003 -:1028B000A64841608160A94841680029FCD1A4492B -:1028C0000020086048608860A248026003600460DD -:1028D00010BC704701219F48C9020160C910016006 -:1028E0007047002805D0012805D0022805D19C4852 -:1028F00070479C4870479C48704710B59BA18B203F -:1029000018F029FC002010BD70B500219E4C9F4D91 -:102910009F4A8F4B002808D001281DD0022822D0C2 -:1029200092A1B32018F017FC70BD01200004A06034 -:10293000A86011601960974BC2039A60964A906034 -:102940007F4A0012106095480160864801609448F3 -:1029500001609448017070BD01204004A060A8602F -:102960005160596070BD01208004A060A860916032 -:10297000996070BDF8B59446834A8B4F834D00240F -:102980000126002808D0012832D0022840D077A1A3 -:10299000E82018F0E0FBF8BD891E0902090A0120B1 -:1029A000000490603C6468606C4A1164012B1DD087 -:1029B00000217C4A7D4B51706146DC63DE637C4BB9 -:1029C0005C6002249C6004241C61744B3D311960DE -:1029D00073490E605F4B891519606F4B58605E48F4 -:1029E00001606C49C00548601670F8BD0121E0E740 -:1029F0000120704E4004704F012B04D134645060AC -:102A000068603964F8BD9060346468603964F8BD0A -:102A100001206A4E80046A4F012BF4D1EEE74F4843 -:102A20004068704770B54A4D28680026564C01280A -:102A300006D1A068C00303D501200004A0602E6069 -:102A40006868012809D1A068800306D501204004E8 -:102A5000A0606E6001200AF0B9FEA868012809D1C3 -:102A6000A068400306D501208004A060AE6002206B -:102A70000AF0ACFE70BD10B54A490878002818D09D -:102A80000120444AC0079060434AC00B90602C4A22 -:102A900000121060414A00201060324A1060404A23 -:102AA000106008704A78002A02D048700AF08EFE42 -:102AB00010BD0320FAE70120424900060860704774 -:102AC0000120244900060860704701203D49400567 -:102AD0000860704701201F4940050860704733496E -:102AE0000020C86388151B4908607047410A364AB0 -:102AF000C005C00D5043801C5143400A0818704760 -:102B000010B4324C430B63431B0C5C020C602E4C24 -:102B10006343C31A2E485C0258432B4B400D43437A -:102B2000E31A0124DB0324041B191B1613700A6823 -:102B30001018086010BC704710B50AF01BFF10BDDC -:102B400080E100E008E400E018E400E000B00040AC -:102B500040B1004080E200E000E100E000B500404C -:102B600048B100404081004044B100407372635C52 -:102B700072656D5F68616C5F6576656E745F7469C0 -:102B80006D65722E6300000000B3004040B300404A -:102B900040B5004000F50140008300404085004002 -:102BA000008200404800002000B10040C08F00407B -:102BB0000085004004B1004004B5004008B1004069 -:102BC00008B5004000E200E0093D00003786000043 -:102BD0006F0C010010B50AF0B9FE10BD00200449C9 -:102BE000C863012001218140024A116000BF704783 -:102BF000C01F004080E200E010B50DF05DF909F063 -:102C0000F7F9FEF7C3FB0FF0F5FA0DF08FFF0DF0AB -:102C10001BFF10BD70B50C46054603F0A7FA214610 -:102C200028460EF0C2FF70BD70B50D46040012D0EC -:102C3000002D10D02101284618F060F910225449C7 -:102C4000284618F0FEF852480121083801804480D7 -:102C50004560002070BD012070BD70B54C4E002451 -:102C60000546083E11E0716820014018817BAA7B6F -:102C7000914209D1C17BEA7B914205D10C222946C0 -:102C800018F0B2F8002806D0641C30888442EADBD1 -:102C90000020C04370BD204670BD70B50D460600D3 -:102CA0000AD0002D08D03A4C083C20886188401C8E -:102CB000884203D9042070BD102070BD3046FFF754 -:102CC000CCFF002801DB401C0AE02088616800017D -:102CD00040181022314618F0B4F82088401C20809B -:102CE0002870002070BD70B514460D001FD0002C58 -:102CF0001DD00021A170022802D0102817D108E0B1 -:102D0000687829780002084311D00121A170108051 -:102D10000BE02846FFF7A1FF002808DB401CA0704D -:102D2000687B297B000208432080002070BD0120C1 -:102D300070BD70B5054614460E000AD000203070F4 -:102D4000A878012807D004D9114908390A88904287 -:102D50000BD9012070BD002C04D028782070288861 -:102D6000000A50700220087010E0002C0CD0496856 -:102D70000001411810222046103918F062F8287816 -:102D800020732888000A607310203070002070BD06 -:102D9000540000205A4910B5884207D30121890404 -:102DA000884205D357490968884201D2102010BDD6 -:102DB0000146012005F0CBF810BD30B5044693B0B4 -:102DC00000200D46079014210BA818F099F81C213B -:102DD000684618F095F86A46112010770020507761 -:102DE000107802210843107007A80C90012008AA4F -:102DF000907245486A4610850AA80B902088108476 -:102E000060885084A0889084E088D084907FF921E5 -:102E10000840801C4008400090770820908610876A -:102E200008A80F9010AA0BA9684600F05CFF0028C4 -:102E300003D110A800882880002013B030BD3EB513 -:102E400004460820694608802D48844207D30120A3 -:102E50008004844205D32B480068844201D21020AC -:102E60003EBD2146012005F072F80028F8D12088E7 -:102E7000694688806088C880A0880881E088488189 -:102E800005F065FE01AB6A46002101F0BBFB694617 -:102E900009880829E4D003203EBD1FB50446002060 -:102EA000029008206946088115480391844207D39F -:102EB00001208004844206D312480068844202D272 -:102EC000102004B010BD05F042FE014602AA0F48D2 -:102ED00001F02EFD0028F4D169460989082901D0A6 -:102EE0000320EEE7694609882180694649886180A8 -:102EF00069468988A1806946C988E180E1E70000C8 -:102F000000C0010028000020042A0000FFFF00008C -:102F100010B5031D03600020521E04E05C181C6005 -:102F2000401C2346C0B29042F8DB0020186010BD60 -:102F300001460A680020002A02D0104612680A6082 -:102F4000704702680A6001607047000010B50146D2 -:102F50002022094817F075FF07490020C877084666 -:102F600010BD0649012048610548064A01689142A2 -:102F700001D1002101607047B00E00200005004023 -:102F800064000020BEBAFECA0C4908784A78401C8A -:102F9000C0B2904200D008707047094A074820BF6D -:102FA00040BF20BF4178037843701368002B02D1E3 -:102FB00003788B42F3D00020704700006B000020A4 -:102FC00000E200E00A4A022151600A490B68002B26 -:102FD000FCD0906008680028FCD000205060086891 -:102FE0000028FCD0704701200007406970470000AE -:102FF00000E5014000E401407047704770477047AA -:1030000010FFFFFFDBE5B15100C001006700FFFFCB -:1030100003B40148019001BD09000020002803D03D -:103020008178012939D101E0102070470188FE4ADA -:10303000881A914233D01BDCFC4A881A91422ED068 -:103040000BDC00292BD00320C002081A27D001284E -:1030500025D001210903401A07E001281FD00228CA -:103060001DD0FF281BD0FF380138002815D116E0ED -:10307000FF220132811A904211D008DC01280ED0C3 -:1030800002280CD0FE280AD0FF2806D107E001292B -:1030900005D0022903D0032901D0002070470F205A -:1030A000704700B50B2826D009DC030018F074F92E -:1030B0000B1D2125251B25292325271F1B00112832 -:1030C0001BD008DC0C2816D00D281CD00F2814D0DB -:1030D000102808D10FE0822809D084280FD0852835 -:1030E0000FD0872811D0032000BD002000BD05208F -:1030F00000BDCF4800BD072000BD0F2000BD04204B -:1031000000BD062000BD0C2000BD0D20800200BDCA -:1031100070B500290BD0CB1FFA3B81241E46CDB2DF -:10312000112B1BD2012805D0022806D009E000206F -:1031300010701DE0FF20043001E0FF2003308142C9 -:1031400018D0330018F028F9111613131613161699 -:103150001316161613131313161316000846FF380A -:1031600081381F2803D9FF39FE39022902D815708A -:10317000002070BD1470072070BD00B5030018F06A -:103180000BF9060406040C080A0C002000BD1120EF -:1031900000BD072000BD082000BD032000BD007851 -:1031A0000207120F04D0012A05D0022A0AD10EE02C -:1031B000000907D108E00009012805D0022803D042 -:1031C000032801D0072070470870002070470620B0 -:1031D0007047002807D0012807D0022807D003280D -:1031E00007D007207047002004E0112002E02120D2 -:1031F00000E0312008700020704738B50C4605000B -:103200004FD06946FFF7CBFF002822D12088032149 -:1032100089028843694609788907090D0843208097 -:103220006946681CFFF7BBFF002812D121880320E4 -:1032300000038143684600788007800C01432180A9 -:10324000A8784007820F2020012A03D0022A03D049 -:10325000072038BD814300E00143218088B2010589 -:10326000890F08D0012189038843A9780907C90F6C -:1032700089030843208080B28104890F0AD0A9788D -:103280004004C906C90F400CC903084320808004CC -:10329000800F02D12088400403D5208840210843B4 -:1032A0002080002038BD70B50446002008801546F7 -:1032B0006068FFF7A2FF002815D12189A08981420B -:1032C00010D861688978C90708D00121490288426D -:1032D00008D8491C17F01EFE298009E0FF21FF31A4 -:1032E000884201D90C2070BDFF30FF3003302880A8 -:1032F000002070BD10B5137804785B08E4075B000C -:10330000E40F23431370FD2423400478A407E40F43 -:10331000640023431370FB24234004786407E40F04 -:10332000A40023431370F724234004782407E40FF8 -:10333000E40023431370EF2423400478E406E40FF1 -:10334000240123431370DF2423400478A406E40FF0 -:103350006401234313700078BF244006C00F23404C -:10336000800103431370002906D00878C10701D1FA -:10337000800701D5012000E00020C0015906490E58 -:103380000843107010BD30B50A8803239B020488DF -:103390009A4323059D0F02D1A3049C0F01D09B0FDC -:1033A00000E001239B021A4303230A801B039A4374 -:1033B00003889804840F02D11805830F01D0800F71 -:1033C00000E00120000302430A8030BDF3B593B052 -:1033D0000D000FD0139800280FD01221284617F0A7 -:1033E0008DFD03AAFF21012003F0D5F80024264615 -:1033F00037467AE0102015B0F0BD0720FBE768469D -:10340000807D01280BD16846818A0520C002081AF8 -:1034100010D0012810D0022812D0032812D0042C7A -:1034200014D0052C15D113E002290000012800005A -:1034300003300000012400E002246846468A08E0C8 -:10344000032406E068460424478A02E0052400E0DD -:1034500006246846418A1398814246D12C74002E76 -:1034600041D00DAA0EA905200292019100901023CF -:103470000022FF21304603F02FF9002823D16846AF -:10348000808E2A46C0B20EA9FFF72DFC00281AD163 -:10349000AE81002F27D00DA9052008AE0291009023 -:1034A000132300220196FF21384603F015F9002866 -:1034B00009D16846808EF11CC01EC0B22A1DFFF7DC -:1034C00012FC002801D0032095E708A881784278F3 -:1034D00008021043E881062C05D16846807DA87259 -:1034E0006846808A2881002085E703A803F05CF8FD -:1034F000002884D0FFF7D5FD7DE7002805D0FE4ADF -:10350000012903D0022903D003207047518800E02D -:103510009188814201D1002070470720704770B523 -:103520000C4605461C21204617F0E8FC00202080B0 -:10353000002D08D0012D04D0F0A1F54817F00BFEA6 -:1035400070BD062000E00520A07070BD70B592B07F -:103550001546064601206A461071107453740846D9 -:1035600008300395029048889082FEF7FBF904002A -:1035700019D06580172069468883203600940AABED -:103580007178023307AA01A80EF017F90646607891 -:10359000000701D5FEF7C7F9002E0AD03046FFF725 -:1035A000ECFD12B070BD1321284605F00EFF03207C -:1035B000F7E708A800906846838B0422012128467B -:1035C00007F0B3FEEDE770B506468AB000200D4661 -:1035D00007900590069003A90490052402460291E5 -:1035E0000190102300942946304603F075F8002816 -:1035F0000DD108A804A9009102900194684683891E -:1036000000222946304602F083FE002801D0FFF751 -:1036100048FD0AB070BD10B50EF0D5FA10BDF0B57A -:1036200089B000260546059600780C460827030059 -:1036300017F0B2FE0CFD070C390B75759BBEFCD361 -:10364000E3FD68680A38FEF702FB07E1A88800225C -:1036500080B20421009008F067FB0290002C04D097 -:10366000AB48A6A16E3017F076FD0298002804D171 -:10367000A748A2A16F3017F06EFD0298009908309C -:103680000DF0D0FCFEF76EF9040007D060783843E7 -:10369000607000986080FEF746F9E1E01321009821 -:1036A00005F093FEEAE0002C04D1BD2093A1800038 -:1036B00017F051FD60880022042108F035FB0090CE -:1036C000002804D192488DA1883017F044FD00995C -:1036D000002008802A7994461EE0C3005B199B688D -:1036E00007936B469B8B1A0708D5DA0606D560460A -:1036F000C20050194038C08F088006E05B0409D52D -:103700000871C2005019C0884880607838436070E2 -:103710000226A3E0401CC0B28445DED89EE0E888C3 -:10372000694608800090002C04D1794873A1983034 -:1037300017F011FD2878062813D10098C00B10D07F -:1037400060880022042108F0EFFA060004D17048D6 -:103750006AA1A23017F0FFFC00203071A8887080A9 -:1037600039E060783843607078E0002C04D1684814 -:1037700062A1B43017F0EFFC60880022042108F049 -:10378000D3FA0090002804D161485CA1B73017F04B -:10379000E2FC009808300EF068FA0121484002D19E -:1037A000E888C00B5AD0009861880226C180D8E70B -:1037B000002C04D1564851A1D03017F0CCFC6088C1 -:1037C0000022042108F0B0FA002804D150484BA18F -:1037D000D33017F0C0FC0226C3E7002C04D14C48BC -:1037E00046A1DC3017F0B7FC022661880122204692 -:1037F000FEF73EFA01200590B3E7A889002280B2C7 -:103800000421009008F090FA0746002C04D04048AC -:103810003AA1EE3017F09FFC002F04D13C4837A1AD -:10382000EF3017F098FC6868029001E009E010E0C2 -:10383000288969468881012202A90098FEF734FA96 -:103840000CE0002C8DD16D202CA1C00017F083FC62 -:1038500087E72F4829A1FE3017F07DFC002C0DD002 -:10386000607800070AD50598002807D184202070C9 -:103870002046582229460830FDF7A6FC304609B0FC -:10388000F0BDF7B50C460546007A224688B00A32EC -:103890000492921C01920027811E16323E4602922B -:1038A0000B0017F079FD08F405F348488ED0F2F3C9 -:1038B00068880022042108F037FA0190002803D11B -:1038C0000EA1144817F047FC01980088002802D088 -:1038D0005227072600E151271E26002C70D0688849 -:1038E000A0800120A071019804990079C0004019BE -:1038F000C089FFF76BFD0FE0400C00207372635C22 -:1039000067617474735F636F72652E6300000000FB -:103910006F0200008603000000287DD10198007925 -:10392000C0004019C089208101980079C000401969 -:10393000408AA083F0E0698A0091062820D1E889B6 -:10394000C00B1DD008462230512786B2002CC5D0AE -:10395000A8890199FFF73AFD002872D16888A080F4 -:103960000220A071A88920810120A072288AE0830A -:10397000009820846969009A029817F062FACBE0F7 -:1039800008462030502786B2002CA7D0A889049979 -:10399000FFF71CFD002854D16888A080A889E0802A -:1039A000287A06280AD002202072288AA08300984C -:1039B000E083204669692030009ADEE70120F3E7C2 -:1039C0008FE068880022042108F0AEF90690688A2A -:1039D00000900698002803D1FD49FE4817F0BBFB74 -:1039E000069808300EF041F90121484002D1E889DB -:1039F000C00B25D000985127223086B2002C7AD0F7 -:103A00006888A080A8890199FFF7E0FC002818D1F8 -:103A10000220A071A88900E013E020810420A07298 -:103A2000288AE083009820846969009A029817F038 -:103A300008FA0699002008710698A98941806BE070 -:103A400003200BB0F0BD688804F0DDF900906888B1 -:103A50000022042108F068F901900098002804D1A0 -:103A6000DC48DB492C3017F076FB0198002804D1A4 -:103A7000D848D7492D3017F06EFB0198D649C08839 -:103A8000884205D05127222604E01EE03FE035E0C1 -:103A900050272026002C2ED06888A080502F07D0D9 -:103AA0000220A0712146287B0831FFF738FD33E062 -:103AB000287BA11DFFF733FD6A8800230199009838 -:103AC000FFF744FD0028BCD126E0C449A889C98875 -:103AD000814207D154270626002C0CD06888A0808C -:103AE0001AE008E053270826002C04D06888A0803C -:103AF000A889E08010E00A98068013E05527072681 -:103B0000002CF8D0A889A0800020A07104E08D20AE -:103B1000AF49C00017F01FFB0A98002C068001D0A7 -:103B20002780668000208CE7AC4900200870704731 -:103B300030B585B00C4601F0DBF90546FF2804D10D -:103B4000A448A349953017F006FB0020208020717F -:103B50006080401EE0802046294608300DF056FA6D -:103B60006A462946012002F016FD102412E068463C -:103B7000808800070ED56846C0882946FFF723FDD8 -:103B800068468188FF2321438180C0882946019AA5 -:103B900002F02CFE684602F007FD0028E7D005B0D1 -:103BA00030BD0A46014610B5104608300DF042FA05 -:103BB00010BD70B505460022042108F0B5F80400D8 -:103BC00004D184488249B73017F0C5FA2046294607 -:103BD00008300DF027FA70BDF0B591B00C460746DD -:103BE00004F011F9050005D02878222804D2082015 -:103BF00011B0F0BD7A48FBE700220421384608F0F6 -:103C000093F80646002C02D0A08800280CD0012092 -:103C1000694608710220087400204874002C05D001 -:103C2000A0880883206802E00920E1E70883059066 -:103C30003046083003970290FDF794FE040018D038 -:103C40006780172069468883203500940AAB69781D -:103C5000023307AA01A80DF0B0FD05466078000701 -:103C600001D5FDF760FE002D09D02846FFF785FA43 -:103C7000BEE71321384605F0A8FB0320B8E708A8E3 -:103C800000906846838B04220121384607F04DFBE3 -:103C90000021C943F180ABE7FFB585B00E9E778860 -:103CA000384604F0B0F8054600220421384608F0F2 -:103CB0003BF80446002D03D145494A4817F04BFA1A -:103CC000002C04D147484249401C17F044FA0834FC -:103CD000089869460394C1C105A80DC820356978C4 -:103CE0000DF0DAF9CBE5F0B50446002099B00D46A9 -:103CF00001460D9010A88181164601818180374AC6 -:103D000068469180018510A80180684601878185F9 -:103D100081841078012808D0022806D0032804D016 -:103D2000042802D0082019B0F0BD2F4A944273D362 -:103D30002E4F0121890438688C4201D3844278D304 -:103D4000294A954275D3012189048D4201D38542C8 -:103D50006FD36168002913D0234A914269D30122AD -:103D60009204914201D3814263D3608921898842C0 -:103D700003D801225202914201D90C20D3E70D90C1 -:103D800016AA0EA92846FFF78EFA0028CBD168683C -:103D900080784007800F02280AD16846008F80048F -:103DA000800F05D02869002802D03968884240D3A6 -:103DB0000AA92069FFF721FA0028B4D12069002858 -:103DC0001CD0607880076846008D14D580040FE011 -:103DD000FC380000EE030000FFFF0000400C002054 -:103DE000023000000C05000000C001002800002087 -:103DF000800F68D002E08004800F64D16846008D97 -:103E0000810618D58004800F606806D0002812D083 -:103E1000396888420DD302E00BE000280BD0FE4940 -:103E2000884206D301218904884204D33968884234 -:103E300001D2102077E709A96069FFF7DEF90028B1 -:103E40009CD16069002808D06846808C0105890FE4 -:103E5000012938D18004800F35D00BA9A069FFF764 -:103E6000CCF900288AD16846808C80062BD468461D -:103E7000808D810627D4A169002906D00105890F0C -:103E8000012920D18004800F1DD0E068002804D0D3 -:103E90000078002817D01C2815D204AA611C2046DF -:103EA000FFF728FA0121890210A80180012768463E -:103EB0008773DA49818104AA033217A92868FEF7BB -:103EC00038FF002801D007202DE710A8007F15A992 -:103ED000C01CC2B200200C920190FF320090034639 -:103EE0000291FF3203A80332109902F0ACFA0028C5 -:103EF00026D110A9888A0F902A892969C84801917A -:103F00000092029010A90A8B6B8928680E9902F022 -:103F10009AFA01007ED1C2480025001F81886846B8 -:103F20004174090A8174052104A86A4623C210A8B5 -:103F30002A46FF21808A0C9B02F0EAF9002802D071 -:103F4000FFF7AFF8EFE66846007C0322C1090020C6 -:103F5000920290430122920280181490002928D0E6 -:103F6000014610A8018068462921877309028181D2 -:103F7000058608A8007C0023410860784900C00736 -:103F8000C00F014308A80174FD2001406078A54AD4 -:103F90008007C00F4000014308A801740CA902204B -:103FA00001910090029503A8109902F04CFA0100CB -:103FB00030D16068002828D0206900280DD10AA9D6 -:103FC0000EA8FFF7E0F96078800706D46946088DEF -:103FD0000321090388436946088590496846877329 -:103FE000FE3181818F492089891E16F093FF626816 -:103FF0000D9811AB0192009002930A46002303A88A -:104000000A9902F020FA010004D12078C10603D4F5 -:10401000800600E085E02AD56846058660690028AC -:104020000DD109A90EA8FFF7AEF96846818C0320CF -:104030008002814301208002091868468184694614 -:10404000888CC82108436946888474488F73FF3080 -:10405000888112AA0CA902200292019100900023EB -:10406000704A03A8099902F0EEF9010059D12078AD -:10407000C00729D068460586A06900280DD10BA984 -:104080000EA8FFF780F96846818D032080028143E6 -:10409000012080020918684681856846818D40208C -:1040A00001436846818587735F49818113AA0CA902 -:1040B000022002920191009000235A4A03A80B9912 -:1040C00002F0C1F901002CD1E06800282DD010A821 -:1040D00014990180544968468773491C8181E168BD -:1040E00008A80A78027449784174E068412241883E -:1040F00068464186E0680023017908A80175E068F8 -:10410000D200C18808A84175090A81750CA8072149 -:1041100001900091029503A8109902F094F9010012 -:1041200003D00F9800F0E8FEFDE53D480321001F95 -:104130000170002E0AD08088308010A8808870809E -:1041400010A80089B08010A88089F0800020EAE5DE -:1041500030B501248BB015460B46012802D0022849 -:104160001CD104E0684605218473C90203E02B4991 -:1041700068468473891E8181002B12D003210020A0 -:10418000890288430121890240186946888405AA6A -:1041900004A91846FEF7CDFD002804D007200BB077 -:1041A00030BD1020FBE76A46127C1D480092801E3D -:1041B00005A9FF3201910290FF32002303A80332C8 -:1041C000099902F040F9002802D0FEF76AFFE6E7FD -:1041D0001348001F002D01D0418829800470002061 -:1041E000DDE770B592B00446012608A886700F4935 -:1041F0006846018410AA08A93046FFF7A9FF0028E5 -:104200004ED12078064DC00700242D1F002849D02C -:104210001C2168460CE0000000C0010003280000DB -:10422000440C0020030200000329000001180000D4 -:1042300016F066FE6846017820200143684601704A -:1042400008A88670F9496846018411940794817F13 -:10425000F92001406846891C8177002001466846A4 -:104260000177002001466846417704218185C48595 -:10427000018607A80A9011A80D9008A809900EAA17 -:1042800009A96846FFF72FFD002809D16846008F6D -:10429000E8806846808F2881401C68812C7000204F -:1042A00012B070BDEC802C8110A80088F4E7F7B53F -:1042B000DF4900260A789EB0012A04D0022A02D0E3 -:1042C000082021B0F0BD4A88824201D00620F8E7DC -:1042D0001F98824201D10720F3E7012210A98A75B5 -:1042E000D4488882002003239B020146994393020D -:1042F000CB1810A90B8669468A81CF4ACA8118A9B2 -:10430000887110A9888419A904916946CA82069007 -:10431000FF20087503A802F06AF900242546274605 -:1043200008AA052103A802F065F9002810D0822808 -:104330006FD1002C6FD0002D6DD010A88480C58067 -:104340000021017418A8807B11AC012865D06DE0B4 -:1043500008A88079002F21D0012857D16846818C88 -:10436000B44881421CD113AA0DA905206B4607C38E -:104370006846408C10230022FF2102F0ADF900288E -:1043800068D110A88089042801D006284CD168463D -:10439000818E1F98814239D10F2092E7012835D1B3 -:1043A0006846808C0521C902884202D0491C884297 -:1043B0002CD19F4841886846408C814201D1012719 -:1043C00000E00027002C01D0002D10D01F9988425A -:1043D0001CD113AB0DAA05216E460EC60446102350 -:1043E0000022FF2102F078F9002833D101E03546A0 -:1043F0000CE010A88089022801D0102814D1C0B286 -:104400001BAA0DA9FEF76FFC00280DD16846468C4B -:1044100086E71FE0FFE7052053E714A91BA8221D2C -:10442000FEF787FC002801D003204AE710A8007C93 -:104430000023001DC2B210A80274209802900194BB -:10444000009215A81C9901F0FEFF002802D17849BE -:1044500002220A70FEF725FE33E710B50B46401E18 -:1044600086B084B203AA00211846FEF743FF04AACF -:10447000052103A802920191009001230022FF214F -:10448000204601F045FF04466846008A012804D012 -:104490006D206A49000116F05EFE2046FEF701FE1F -:1044A00006B010BDF0B5624F0446387887B00E46AE -:1044B000032804D0042802D0082007B0F0BD04AAC5 -:1044C00003A92046FEF7EFFE0500F6D1606880786C -:1044D0004007800F02280DD1684680898004800F34 -:1044E00008D02069002805D055490968884201D2C2 -:1044F0001020E2E7208905AA6B46216907C36946B7 -:104500000A8A63892068039901F09DFF002802D080 -:10451000FEF7C7FDD1E7002E02D06846808A3080C2 -:10452000042038702846C8E738B50C00054609D085 -:1045300000236A46FF2102F031F9002804D0FEF77B -:10454000B0FD38BD102038BD69462046FEF755FE47 -:104550000028F8D1A078FF21C307DB0F2846009A76 -:1045600002F044F9EBE73EB50C0009D002AB6A4615 -:10457000FF2102F013F9002804D0FEF792FD3EBDA2 -:1045800010203EBD0321204616F0B8FC6846008886 -:1045900001A90005800FFEF71CFE00280BD168461C -:1045A000007920706846008801A98004800FFEF71A -:1045B00010FE002801D003203EBD684600796070DF -:1045C000A278EF20024068460088C10B09010A4327 -:1045D000F7210A404104C90FC9000A43A270F9211A -:1045E0000A40800601D5022000E001204000694613 -:1045F0000243097A50084000C907C90F0843A07058 -:1046000000203EBD7FB514460522019203AD029500 -:1046100000930A462388FF2101F07AFE69468989C2 -:104620002180FEF73EFD04B070BD0000052A0000A9 -:10463000400C002002280000FFFF0000FC380000B2 -:1046400028000020F3B5002799B068460C4607877C -:104650003D4600291DD0E068002806D0A06800284B -:1046600017D001886A4611870780199803F0CBFBA1 -:10467000002811D0007822287ED3199800F038FC49 -:10468000009000220421199807F04EFB060009D182 -:1046900004E010201BB0F0BDFC48FBE7FC49FD48DE -:1046A00016F059FDA078012803D0022801D0072078 -:1046B000F0E72088002808D0401E80B203AA0099A5 -:1046C00001F069FF002859D11DE0F048401CE1E7E6 -:1046D0006946498A228891420BD26846807D00252E -:1046E000012810D16846808AEB4988420BD1012508 -:1046F00009E0914203D1002D2AD06D1C01E0022D6A -:104700000BD0032D04D203A801F04EFF0028DFD008 -:1047100082281BD0002831D11DE06946897D0129FE -:10472000F1D16946DC4B8A8A5B1ED11A9A420FD0BE -:1047300005DCDA48101A0BD00128E4D108E0012981 -:1047400006D0FF390129DED10325E1E7022D15D17D -:104750000D2080029EE7E068002816D00EA90522F1 -:1047600002910192009069460B8FA2882088FF2158 -:1047700001F0CEFD002800E01DE002D0FEF791FC24 -:1047800088E76846A168008F08806846008AC006EE -:1047900001D5C3487EE70798002803D06846008B00 -:1047A000022801D0032075E70798A1780078012935 -:1047B00003D0800710D408206CE7C007FBD000228C -:1047C0000721199807F090F8002802D00725022049 -:1047D00004E0AE48801C5DE70225032008A90870AC -:1047E000218868468185199808360A90099617210C -:1047F0006846818712AB02330FAA052108A80097EB -:104800000CF0DBFF002802D0FEF7B7FC42E710A84F -:1048100000906846838F04222946199806F085FD8A -:1048200038E770B5064615460C460846FEF7F6FB17 -:10483000002804D12A4621463046FFF789FCF3E6DA -:1048400010B5FFF734FD10BD70B51E4614460D00BF -:1048500014D0002C12D0616800290FD00121FEF77E -:104860004CFE002809D12068FEF7D8FB002804D1AF -:10487000324621462846FFF736FAD5E61020D3E621 -:1048800070B515460C000ED00221FEF736FE00284A -:1048900008D12068FEF7C2FB002803D12946204634 -:1048A000FFF700FEC0E61020BEE6F8B506467D48DC -:1048B0000D46016814468A4231D36068002808D04A -:1048C000794A90422BD301229204904201D388422C -:1048D00025D37648864204D0304603F094FA002867 -:1048E0000CD0304600F004FB0646284600F0BDFA26 -:1048F000002804D16068002802D012E06348F8BDA7 -:1049000000236A463146284601F048FF002802D0BD -:10491000FEF7C7FBF8BD68460088800601D410206A -:10492000F8BD6188224628466368FFF76BFEF8BD34 -:10493000F7B55C4E0746306886B01446824202D214 -:10494000102009B0F0BD384600F0D2FA05465748AD -:10495000874201D0FF2D08D0002304AA29460798DA -:1049600001F01CFF002826D101E04848E9E768462D -:10497000008AC00601D54A48E3E703A90020029156 -:104980000527019000976288484B2946079801F057 -:10499000A3FE00280FD161683268914208D30191CB -:1049A00002900097238862882946079801F094FEB8 -:1049B000694689892180FEF774FBC2E7002907D088 -:1049C0003B4B0A881B899A4202D83048401C7047EA -:1049D00038E610B586B004236C46A382344BDC88DD -:1049E000002C07D01B898B4201D2914204D9274861 -:1049F000401C55E5062053E56B4619825A8200217A -:104A0000009101911C800221997005A9029104A9CD -:104A100003916946FFF716FE42E5F3B50C4685B0F3 -:104A2000812069460873002C1AD0059803F0EBF931 -:104A3000070017D03878222868D3059800F058FA74 -:104A4000049000220121059806F04EFF00280BD0AB -:104A500000220421059807F067F905000AD105E056 -:104A600010202AE5094828E5112026E508491148C3 -:104A700016F071FB284608300CF0F6FA064620784E -:104A8000012819D0022838D0072016E5023000008E -:104A9000FC380000E10800000328000000280000A6 -:104AA000013400002800002000C00100FFFF0000CA -:104AB000400C0020840A0000A18803AAFEF728FB0E -:104AC0000028CED1B00721D56846007B00281FD131 -:104AD000A079C0071CD0E068002205216B4607C3FF -:104AE000638922896888049901F012FC6946087379 -:104AF00000280DD0FEF7D5FADFE4A18803AAFEF75F -:104B000007FB0028ADD13420064201D10820D4E4AF -:104B10006846037B29463846059AFEF717FDCCE424 -:104B2000FFB597B0002001901F4615460C460E4673 -:104B3000179803F068F9002804D00078222803D2DF -:104B40000820A7E5F348A5E5B80801D00720A1E5AE -:104B5000032F00D10027179800F0CAF90890002C05 -:104B60001BD0022D77D3EC48006884427CD36119B6 -:104B70000091012902D0491E814275D3AD1EAAB20F -:104B80002146E6480DF0F0F800991E394A7F0B7F68 -:104B900011021943884267D1ADB2E148B90702D585 -:104BA0000189491C00E0012189B20091F90701D077 -:104BB000078900E0D94F03AA0899009801F0EBFC9F -:104BC0000DE0F078B1780002084310284CD8019924 -:104BD000091D401880B20190A84245D82618002E21 -:104BE00060D0707831780002084300998842E8D399 -:104BF00058E06946098A0A0754D5002C3FD0019A2B -:104C0000A618121D92B20992F278B37812021A43D2 -:104C10009446102A28D8099A6244AA4224D8727865 -:104C2000337812021A4390421ED1C8061ED5099845 -:104C30000AAA052120186B4607C370783178000254 -:104C4000084363460022089901F062FB002803D064 -:104C5000FEF727FA1EE507E0F078B1780002084376 -:104C60006946098D884201D00B2013E5F078B178B0 -:104C7000000208430999401880B2019006E0C90675 -:104C800004D50899FEF79FFC0028E3D16946088AFD -:104C90001021884369460882488AFF23049A0899AC -:104CA00001F0A4FD03A801F07FFC002803D16846B1 -:104CB000408AB8429DD900220421179807F034F8A1 -:104CC000040003D19749984816F045FA2088002837 -:104CD000C0D0012108A80170017300264673218805 -:104CE0006846018620460830099017980A90FCF71C -:104CF00039FE05001BD01798688017206946888008 -:104D000010AB023301AA052108A800950CF055FD4F -:104D100007466878000704D583488249223016F098 -:104D20001AFA002F09D03846FEF727FAB2E4132109 -:104D3000179804F04AFB0320ACE40EA800906846E4 -:104D4000838804220121179806F0EFFA00288CD1FD -:104D500026809FE4F0B500248DB01F4615460E4610 -:104D6000002A04D0B90804D007200DB0F0BD1020EF -:104D7000FBE7032F00D1002700F0BAF80390FF28CB -:104D800004D06749B80703D5488902E06148ECE7D9 -:104D90000120FA0702D04989491E00E05F4906AAAE -:104DA0008FB2039901F0F7FB38E06946898B090758 -:104DB00034D504AB05210022029300910192574B98 -:104DC000039901F089FC002821D1002E21D06A46E8 -:104DD000128A2988A2183019121D914234D36946CB -:104DE000CA8B0270120A42700A8A8270120AC2705A -:104DF00004A90522001D0092029101906946C88B0A -:104E00000B8A0022039901F067FC002801D00320DF -:104E1000ABE76846008A2018001D84B206A801F09E -:104E2000C3FB002804D0822806D0FEF73AF99CE79D -:104E30006846C08BB842B8D9002C07D0002E10D0DD -:104E40002988A01C814203D20C208EE705208CE724 -:104E50002246314631480CF087FF31190870000AAC -:104E60004870A41C2C8000207FE700B585B06946FF -:104E7000FEF7ACFA00280AD16846007C030016F061 -:104E80008BFA08052F2F2F2F08080531032005B0B6 -:104E900000BD68468078012807D168460088032154 -:104EA000C902401A1CD001281AD06846807901280E -:104EB00006D16846808815214902401A05280FD975 -:104EC0006846807A012811D16846018929200002AC -:104ED000081A05D0022803D0032801D0042805D1E0 -:104EE0000F20D4E711A1164816F035F90020CEE7BF -:104EF00010B506F00FFF10BD10B50C4601F01EFBFB -:104F0000002803D009A10F4816F025F92046FEF726 -:104F1000C8F810BD0230000028000020FFFF00008C -:104F2000400C0020FC3800003F0B00007372635CF3 -:104F300067617474735F636F72652E6300000000B5 -:104F400022020000BB060000F8B500780C461646A9 -:104F500010340E36069F022809D0032836D00528C3 -:104F60007ED0FF20F6A1E53016F0F5F8F8BDCD892A -:104F70000A2068430E30188031203880002AF5D08E -:104F8000087B9581801FC7B21AE020886168308055 -:104F900048780A7800021043F080C8788A780002C6 -:104FA00010433081B21C3846091DFDF79CFE002FCE -:104FB00001D0002802D000203071708008340A36F9 -:104FC00028466D1EADB20028DFD1F8BDCD890A207C -:104FD00068430E30188032203880002AF5D0087BD4 -:104FE0009581401FC7B243E0616822880878F2804B -:104FF0003279C30752085200DB0F1A43FD231A40CF -:105000008307DB0F5B001A43FB231A404307DB0FC8 -:105010009B001A43F7231A400307DB0FDB001A43F8 -:10502000EF231A40C306DB0F1B011A43DF231A408C -:105030008306DB0F5B011A43BF231A404306DB0FD5 -:105040009B011A433271C00970718A784B78100243 -:105050001843308132463846C91CFDF744FE00E053 -:105060000CE0002802D00020B070308008340A36EE -:1050700028466D1EADB20028B6D1F8BD087BCD899B -:10508000801E86B2304608306843103018803420C5 -:105090003880002AF1D0174695811037E800D68174 -:1050A000C01900900DE02088388000987860324662 -:1050B0006168009815F0C5FE00980834801908371B -:1050C000009028466D1EADB20028ECD1F8BDFFB5AA -:1050D00081B00A9D1E460C46002A05D0607AFF303A -:1050E0000130D080E089108101980E2700780300FC -:1050F00016F052F90B7E0719293541536C787878F0 -:105100007E000092087B082805D0032803D091A1D7 -:10511000954816F020F8378030200FE000990020E5 -:10512000888105B0F0BD0092087B042804D08E4829 -:1051300088A1143016F00FF83780312028800098AD -:105140000028EBD1EDE70092087B042804D09320DF -:1051500080A1800015F0FFFF37803220EEE700923B -:10516000087B022804D080487AA13A3015F0F3FF7A -:1051700037803320E2E7087B1746042804D07A48BA -:1051800074A14C3015F0E7FF1020308034202880C7 -:10519000002FC6D00020B88116E0207B17460528D6 -:1051A00006D0062804D070486AA1603015F0D3FFFD -:1051B0001220308035202880002FB2D0E089B881BD -:1051C0000020388201984088F881AAE70092087B85 -:1051D000072804D064485FA1713015F0BCFF378008 -:1051E0003620ABE733460095019800F00AFC98E7BB -:1051F0002F2053A1000115F0AEFF92E770B50C46C9 -:10520000054602F000FE002804D00078222803D2D0 -:10521000082070BD554870BD00220521284606F0C3 -:1052200083FD2060002801D0002070BD032070BDE8 -:10523000FFB58BB00D4607461720694608850E98C6 -:1052400003261446002805D10EA93846FFF7D6FFDD -:10525000002834D1002D0BD000220321384606F05F -:1052600043FB002834D00E980078002830D108E0A5 -:105270002078092819D00F2823D031A13C4815F0F7 -:105280006AFF0E98A760801D03AA606002320AA917 -:10529000204600F00CFC002827D0030016F07CF814 -:1052A000071A182323211C1E23000726002231463B -:1052B000384606F019FB0028E3D12C48801C0FB0BB -:1052C000F0BD00220321384606F00EFB0028D8D19D -:1052D0001120F4E70020F2E70820F0E72348401C03 -:1052E000EDE70720EBE70320E9E701A80090684617 -:1052F000038D04223146384606F017F80028DED127 -:10530000002DDCD00E990D70D9E730B587B01D4661 -:105310000C46002A11D0042369460B7013888B8138 -:105320005288CA81A2788A7422880A8200236A4637 -:105330002946FFF77DFF07B030BD1020FBE70000D6 -:105340007372635C67617474635F636F72652E630D -:10535000000000007372635C67617474635F636F65 -:1053600072652E630000000025020000023000007C -:105370004F030000F3B581B001980C460078082671 -:10538000030016F009F8125E46461B134A0A0A0A81 -:105390000A0A0A0A0A0A0A0A0A5E002C02D1F64917 -:1053A000F64808E06078304360703BE0002CF9D1AB -:1053B000F248F149083015F0CEFEF3E701980022DB -:1053C0008088052187B2384606F0AEFC0546002CE1 -:1053D00004D07520E849C00015F0BDFE002D04D1B1 -:1053E000E648E549143015F0B6FE3946A81D00F030 -:1053F00055FBFCF7B7FA040006D0607830436070C4 -:105400006780FCF790FA0FE01321384603F0DDFFC8 -:1054100015E0DA48D849283002E0D848D6492D307E -:1054200015F099FE002C0AD06078000707D593206C -:1054300020702046582208300199FBF7C5FE002055 -:10544000FEBDCE48CC493130EAE710B500210170ED -:10545000801D00F020FB10BD0A4610B50146901DCE -:1054600000F024FB10BD70B505460022052106F0B2 -:105470005BFC040004D1F920BF49800015F06BFEED -:105480002946A01D00F00AFB70BDF7B5054684B0A3 -:105490000C4600206946088188806F8802460521F5 -:1054A000384606F041FC060004D1FD20B2498000D8 -:1054B00015F051FE002C03D0A7800020E080208151 -:1054C000297A20461230C91E142700900B0015F0CF -:1054D00063FF0FFDFCFB3809A95E657A2FB2C9E9AD -:1054E0009191FB003078012804D0A3497020143139 -:1054F00015F031FEA9896A46C8000E309080302030 -:105500001081002C13D0A18100200DE0C100327960 -:1055100009190A747288CA8182005319DA894A8289 -:105520001A8A401C8A8280B2A1898142EED8F1E0B9 -:1055300002A8009001AB22462946304600F02AFA24 -:10554000E8E03078042804D08B49BD20143115F0F0 -:1055500002FEA8890622014650436A460E3090801A -:1055600033201081002CE2D0A18100200BE0062125 -:1055700041434F190919FA89CA81BA7C8A743A8A57 -:10558000401C0A8280B2A1898142F0D8C2E0307802 -:1055900006280BD078491431D72005E0307806284A -:1055A00004D07549EB20143115F0D5FDE889694622 -:1055B0001230888035200881002CB8D0A989A181BB -:1055C0007188E18126E03078072804D06A49FF20FD -:1055D000143115F0C0FDA8896A4601460E3090804E -:1055E00036201081002CA2D0A1812046AA890E303D -:1055F000296954E0E8896946123080B238228880EF -:105600000A81002C7ED0A989A181287A102807D090 -:105610000221A173E9892182EA89296900983EE083 -:105620000121F6E702A8009001AB22462946304648 -:10563000FFF78AFC6EE03078082805D04E49FF203D -:105640001431EE3015F087FD6846372187800181DF -:10565000002C5FD0A989A1810020608220820120D6 -:10566000A07357E03078092805D04349FF20143152 -:10567000FF3015F070FD288A694614308880372085 -:105680000881002C46D00421A173A989A181E98950 -:105690002182298A618220462A8A1430696915F09C -:1056A000D0FB37E030780A2804D03349344814312D -:1056B00015F051FD6846372187800181002C29D0E3 -:1056C0000521A173002002E01FE004E00DE0A081AD -:1056D000208260821EE002A8009001AB224629468B -:1056E0003046FFF7F4FC15E00CE00D206946392246 -:1056F00088800A81002C05D00120E08000202081D4 -:10570000207307E00699088019E01C481A49A43064 -:1057100015F021FD6846069980880880002C0ED07F -:10572000684600892080684680886080287A03283F -:1057300005D0102803D0112801D00020307000209F -:1057400007B0F0BDF7B5568815460F4682B0002267 -:105750000521304606F0E8FA040004D1074806495E -:10576000C43015F0F8FCA41D33462A46394600948F -:10577000029800F022FBD4E440530000950300009F -:1057800013020000F7B58CB00D46144607A90C981B -:10579000FFF734FD002812D1B64E0127002C0FD0A0 -:1057A0000321684601701021818208A802460690F4 -:1057B000204605A9FDF7BDFA00280BD007207EE59D -:1057C0000821684601708581C68105218774C90258 -:1057D00001820BE00798A178017121884180684619 -:1057E00005218774C90201828581C6810246012193 -:1057F000079B0C98FFF71CFD61E508B501236A467D -:1058000093709D4B13800A4602236946FFF77DFD86 -:1058100008BD08B501236A469370974B5B1C138043 -:105820000A4603236946FFF770FD08BD00B587B03F -:1058300000290CD002236A4613700B889381498893 -:10584000D18100230421FFF7F3FC07B000BD102035 -:10585000FBE710B5002903D00523FFF756FD10BD67 -:10586000072010BD70B588B00D461446064607A93E -:10587000FFF7C4FC00280DD1002C0DD0062168468E -:1058800001708581C481079B02465C8006213046F9 -:10589000FFF7CEFC08B070BD052168460170858118 -:1058A000F1E710B588B000290BD007246B461C70B7 -:1058B0009A81049100236A462146FFF7B9FC08B09B -:1058C00010BD1020FBE770B50024172288B0002916 -:1058D00014D00D782B0015F05FFD06230505190483 -:1058E0001B231522D21E93B2CA88002A02D08E68CA -:1058F000002E03D09A4203D90C20CBE71020C9E731 -:10590000042D05D08A88002A0AD101E00620C1E7CB -:10591000012D11D0022D05D0042D18D0052D23D036 -:105920000720B7E709236A4613704B889381CB8819 -:10593000D381896804911DE00C236A4613704B885B -:105940009381CB88D38189680824049112E00D23C8 -:105950006A4613704B8893818B88D381CB881382DE -:1059600089680924059105E00E236A461370497879 -:1059700011730A2400232146FFF75AFC8AE700B579 -:1059800087B00F236A461370918100231946FFF7F1 -:105990004FFC5AE7FEB50078089D1C4616460F4698 -:1059A000012803D03549912015F0D5FBF889C000B6 -:1059B0000E30208030202880387B001FC0B201903C -:1059C000002E1DD0F889B081002516E0E80084196A -:1059D000C0190090224641690E320198FDF783F903 -:1059E000002802D000202074E08100986D1C008AFD -:1059F00060820098ADB2408AA082B089A842E5D802 -:105A0000FEBD70B514461425049A1D8037231380FB -:105A1000002C0ED0CA89A281002262820078082858 -:105A200008D0092810D00A2819D01449144815F0B4 -:105A300092FB70BD087B0C2804D011480F490C382C -:105A400015F089FB012008E0087B0D2804D00C48E4 -:105A50000A49083815F07FFB0420A07370BD087B4D -:105A60000E2804D006480549001F15F074FB0520D8 -:105A7000F3E70000FFFF000002280000545300007D -:105A8000BB02000010B5FE4B586019721A80C900A5 -:105A900015F036FA10BD00210180704710B50022C4 -:105AA000D2430280032006F0A8FD10BD7047F0B578 -:105AB0000E460446017801208840F24999B008401A -:105AC0000090616815460888EF4A904206D0009A17 -:105AD000002A06D0EB4A521E104202D0012019B013 -:105AE000F0BD009A10430880002D12D000202870CD -:105AF0002178EA1C0027681C01920B0015F04CFC71 -:105B000010F30E16233A59616F3CB4B08AB8F2F123 -:105B1000F0F320780B28EBD00420E0E70221297075 -:105B2000A1890170090A4170032097E004212970BE -:105B3000A1890170090A41700198E1890170090A7F -:105B4000417005208AE006212970A1890170090AA7 -:105B500041700199E2890A70120A4A70218A017122 -:105B6000090A4171A28AE81DA16915F06AF9A08AA3 -:105B7000C01D73E0082129702178082901D1102166 -:105B80002970A1890170090A41700198E1890170A9 -:105B9000090A41700520308020466A1D02A9103094 -:105BA000FDF7C7F800287DD169463088097A40188A -:105BB00054E00A212970A1890170090A417003206B -:105BC0000BE00C212970A1890170090A417001982C -:105BD000E1890170090A4170052030809CE0A089AC -:105BE00084464000401C81B2308888425AD305293F -:105BF00058D30E202870002008E0236942009B5AE9 -:105C0000521953701B0A401C937080B26045F4D344 -:105C10003180B9E09A48417A002973D0491E417217 -:105C2000217B4068C9004518A988286808224018C7 -:105C30000838216915F005F9022168460171002133 -:105C4000417128680390A98868460181002101A854 -:105C5000FFF790FB0020A880002E00D0308093E05A -:105C60002978802211432970297840221143297014 -:105C700029788909890112312970A1890170090ADD -:105C80004170E289E81C216915F0DBF8E089C01C4D -:105C90003080287841063FD5C00975D0012168467B -:105CA000017200E02CE0002141723188091D8181E0 -:105CB0000495E189019808180590001D0690704828 -:105CC000017A68460177002102A8FFF753FB0746D7 -:105CD00030880C303080022F06D0002F54D065E081 -:105CE0003DE033E01CE05EE065486946097F4268BC -:105CF000CB00D218037A994202D29188002902D0AF -:105D0000042753E02FE0417A491C41721560308826 -:105D100090800020308049E06168A089888033E06D -:105D200029788909890116312970A1890170090A28 -:105D300041700198E1890170090A4170228A681D49 -:105D4000616915F07EF8208A401D46E728788009B1 -:105D5000800118302870207B687002207EE7606820 -:105D60000188090401D4052720E0C088A189884260 -:105D700001D006271AE01E202870012030806068BC -:105D800001884904490C0180009800280ED03C4845 -:105D900000220088A1688300032006F087FB616869 -:105DA0002078887007E00020308003276068009921 -:105DB00002888A430280384691E6FFB59FB0289D4D -:105DC0000E46002805D0172803D82A882E4B9A4261 -:105DD00002D1072023B0F0BD3278530601D4D20996 -:105DE00001D00820F6E700226B461A715A7114465A -:105DF0003278431E1D939BB2189303AB1A939706F8 -:105E0000CB1CBF0E1B93821E711C3B0015F0C4FA05 -:105E1000209011EE66EE74EEB0EED4EEEDEEECEE08 -:105E2000EBEEEAEEE9EEEEEEE8EEE7EEE6EEE5EEBC -:105E300090EE05287CD1042168460171A978017291 -:105E4000F078B2780102114368464181317941719D -:105E500070788006800E0C282ED009DC801E03008E -:105E600015F09AFA0919661C6621662466276600F1 -:105E700012282AD00ADC0E2821D01028DAD121E0FD -:105E80004C0C0020FF710000FFFF000016281FD0FF -:105E90001828CFD11FE02878800701E02878400734 -:105EA000002845DA45E128780007F9E72878C00698 -:105EB000F6E728788006F3E728784006F0E72878A8 -:105EC0000006EDE72888C005EAE72888C004E7E770 -:105ED00028888004E4E728884004E1E72A789207CC -:105EE00026D50328A6D105206A461071487809787E -:105EF0000002084310811CE129784907F0D50628E3 -:105F000016D3717890B2012902D0022992D101E012 -:105F1000022100E01021189106216A46117100212A -:105F2000118102AF189AB11C0237921C1B921AE021 -:105F3000B3E04A780B7812021A433A80801E891C1B -:105F40001790BA1C1A911898FCF7CDFE1A99189858 -:105F5000189A091817986B46801A1A8980B2521C31 -:105F60001A811B9ABF1D8242E3D9002886D1E0E046 -:105F700028780007B4D51D98694682B207200871B9 -:105F800000200881701C0A3111E0437807781B0259 -:105F90003B430B80C37887781B023B434B806F46A3 -:105FA0003B89121F5B1C001D92B23B81091D042A14 -:105FB000EBD2002A71D1BCE02978C9066DD5022840 -:105FC0006BD30820694608710020488170780872F8 -:105FD000844692B2B01C1A9919E089E090E07EE004 -:105FE00067E05BE030E025E019E013E0BCE04378D7 -:105FF00007781B023B430B80831C4B606346D21A1D -:106000006F467B8960445B1C92B27B81083194456A -:10601000EDD9CEE7287880063FD5092203E028781D -:1060200040063AD50A2268460271AA880281189A67 -:10603000428107E0287800062FD50B206A461071B0 -:1060400018981081039174E02988C90525D5022884 -:1060500023D30C20694608710020488170780872AB -:10606000844692B2B01C1A9914E0437807781B0258 -:106070003B430B80C37887781B023B434B80031D57 -:106080004B606346D21A6F467B8960445B1C92B2B8 -:106090007B8108319445E8D98BE763E02988C904FE -:1060A00060D501285ED10D2168460171A988018162 -:1060B0003FE02988890455D5052853D30E22694627 -:1060C0000A71AA880A811B99401F4A78097812022E -:1060D0000A4369464A818881701D049029E0298815 -:1060E00049043FD501283DD10F206946087120E0C1 -:1060F0002A88120436D44A780B7812021A43EA80AE -:1061000003282FD332789206920E1B2A26D0112212 -:106110006B461A712A880123DB031A432A804A78C6 -:10612000097812020A4369460A81C01E48811B98F9 -:10613000039030788006800E1B2809D01D2807D0D8 -:106140000320229906F059FA2888C00BC003288042 -:1061500001A82199FFF70EF920463BE610226B4675 -:106160001A71DCE70724F7E70824F5E700B597B0D4 -:10617000032806D16A461070019100216846FFF796 -:10618000F9F817B000BD000010B58B78002B11D0C6 -:1061900082789A4207D10B88002B0BD003E08B79D1 -:1061A000091D002B08D08B789A42F8D103880C88FF -:1061B000A342F4D1002010BD812010BD052826D0B7 -:1061C000002A02D0012A0DD102E00988090501E068 -:1061D00009888904890F07D0012918D0022909D01C -:1061E00003290ED081207047002A01D00320704778 -:1061F0000220704703280AD0042808D0002804D0C1 -:1062000007E0042803D0022803D0052070470020AF -:1062100070470F20704770B51388054614460B80F1 -:1062200018061DD5FE481022807AA84203D81343D1 -:106230000B80002070BDA06893430078E840C00741 -:10624000C00E03430B802078A1788007800D08439F -:10625000F44914F05FFEA06869430818401C70BD43 -:10626000906870BD37B569468B88138019061BD5B9 -:10627000EB4C0125A47A9168844209D8FE280FD1FD -:10628000D80602D5A5406D1E00E000250D7007E080 -:1062900085400C78DB06DB0FAC4383401C430C705D -:1062A00010881021884310803EBDF8B50746C81CF1 -:1062B00080080E468000B04201D08620F8BD082A32 -:1062C00001D90E20F8BDD64D00202E60AF80288168 -:1062D000AA723446E88016E0E988491CE980810604 -:1062E00010D48007A178800D0843CE4914F012FE27 -:1062F000206800F0BAFA2989401880B22881381A3B -:106300008019A0600C3420884107E5D40020F8BD36 -:10631000FFB589B09F041646139DBF0C01930998E1 -:1063200000F095FA04000AD02078000609D5BC4890 -:10633000817A0A98814204D887200DB0F0BD0120EF -:10634000FBE7224669460A98FFF765FF06900020A2 -:1063500069460872052D14D0012221462846FFF710 -:106360002DFF0028E9D1207840060AD50221684691 -:106370000172099981810188C18106824782129840 -:1063800005900198000404D500273E460125079793 -:1063900009E02078A1788007800D0843A149079083 -:1063A00014F0B8FD0D46019840040AD50798A8429C -:1063B00007D12088E1788005800F00020843B042B1 -:1063C00001D3AE4201D90720B7E7B81980B20190D6 -:1063D000A84201D90D20B0E76846007A002804D011 -:1063E00002A8FDF718F90028A7D10798A8420BD1F9 -:1063F000208803210902884301998905890F090230 -:10640000084320800198E0701498002800D007808D -:106410001298002815D006983A468019129914F05F -:1064200010FD224669460A98FFF7F5FE694608887E -:106430001021884369460880224600990A98FFF790 -:1064400011FF002079E7FFB5754D0C22E888296817 -:10645000504383B00C180D9F7249059814F05AFDF3 -:106460000091049800F001FA29682A898E46611A81 -:106470000C310918944651188AB2A988914202D861 -:10648000842007B0F0BD6A46168A320603D5B206EC -:1064900001D58520F5E7EA88521C92B2EA800E9B6E -:1064A000002B00D01A80B20601D5A76006E0604438 -:1064B00080B22881091A70460818A0602246FE2082 -:1064C0000499FFF7CFFE0598A0700098E07020882F -:1064D0000599800889058000890F08430321090276 -:1064E000884300998905890F09020843042108435C -:1064F000208003988078A07103980088A0800020F5 -:106500002073310601D5AC7A00E00124B10600D534 -:10651000002700260EE0052100200191029000973F -:10652000E88831460C9B069AFFF7F2FE0028A8D1B6 -:10653000761CF6B2A642EED30020A2E7F1B5009891 -:1065400000F085F9060002D00025009C14E001202F -:10655000F8BD204600F07BF90746007831498007F6 -:10656000820DB878104314F0D5FC386800F07DF93E -:106570004019641C85B2A4B22948C188601E8142BA -:10658000E7DC00992648491EC1800189491B018129 -:1065900000203070F8BD002804D0401E108091709B -:1065A000002070470120704710B5044601881C4840 -:1065B000C288914201D3822010BD00680C22514351 -:1065C00042189079A072908820811088D178800537 -:1065D000800F00020843A081A078211DFFF71BFE59 -:1065E00020612088401C2080E080002010BD012117 -:1065F00001827047F7B50546002084B0C043108083 -:1066000068681746817868468170686801886846BE -:10661000018000218171288A2C88A04205D303E0E3 -:10662000580C00200102000004462C8235E0288A24 -:10663000401C2882301D6968FFF7A6FD00282AD17A -:1066400039889248814201D1601E38806888A04212 -:1066500028D33088F1788005800F0002084302902B -:106660006946301DFFF790FD002814D169898748DD -:1066700081421BD0002231460598FFF79FFD00287C -:1066800009D16A890298824205D1E968B06814F09C -:10669000ABFB00280AD0641CA4B2204600F0D7F857 -:1066A0000600C4D1641E2C828220EAE67C80B07988 -:1066B000B871B088B8803078B1788007800D084311 -:1066C00078810298B8813946287A32460831FFF736 -:1066D000A2FD38610020D4E6FFB585B01C460F4608 -:1066E000059800F0B4F8050009D02878000608D510 -:1066F0006748807AB84204D8872009B0F0BD0120ED -:10670000FBE707982A468605B60D69463846FFF727 -:1067100082FD07460E98052816D000222946FFF76D -:106720004DFD0028E9D1287840060DD501216846A5 -:10673000017105990181018841818681C48101A887 -:10674000FCF769FF0028D8D12888AA788107890D2D -:1067500011438005800FEA7800021043079A9642A1 -:1067600007D04C4A914204D3611E814201DD0B20C7 -:10677000C3E7864201D90720BFE7801B82B2A2424D -:1067800000D922461098002800D002800F980028D7 -:1067900002D0B91914F055FB0020AEE7F8B51D463C -:1067A00017460E4600F053F8040008D02078000683 -:1067B00007D53748807AB04203D88720F8BD01203A -:1067C000F8BD224639463046FFF725FD002D0BD097 -:1067D0002078A1788007800D08432E49884201D295 -:1067E000012000E0002028700020F8BDF8B51E460A -:1067F00017460D4600F02BF8040008D0207800065C -:1068000007D52348807AA84203D88720F8BD012005 -:10681000F8BD224639462846FFF724FDFF2E14D046 -:106820002588A178A807800D08431A4914F072FB47 -:10683000002E03D1FF31FF31033189B2A170A808C6 -:1068400080008905890F084320800020F8BD104989 -:10685000CA88824207D3002805D00C220968504319 -:106860000C38081870470020704703B50846694681 -:1068700009888A0607D4090604D50549897A41435F -:10688000491C88B20CBD00200CBD0000FFFF0000B9 -:10689000580C002001020000F8B507780D460446A8 -:1068A000012F19D0072F02D00C2F19D114E0A068A6 -:1068B000216906780B2E0BD0052005F09EFE052ED3 -:1068C0000ED0782300220520216905F0EFFD07E0B6 -:1068D000782300220620F8E70520216905F08DFEC7 -:1068E000002D0ED0002028702946204603F0E2F942 -:1068F000FE482978C05D884201D10320F8BD0220FE -:10690000F8BD0021204603F0D5F90020F8BD70B590 -:106910000E460C462036317901208AB015460029F2 -:1069200009D0012905D12978042902D10520107048 -:1069300000200AB070BD6068019005A802900D218A -:10694000C01C14F0DBFA032205A8A16814F079FA40 -:1069500001203071062069460870206A049029469B -:106960006846FFF799FFE4E770B50C4615462031FD -:106970000A790120062686B0002A2CD0012A28D1C7 -:106980002978042925D169681022A06801F0B5F999 -:106990006868C07B000606D5D44AA0681023103A68 -:1069A000014601F09FF91022A168E06801F0A5F905 -:1069B000A068C07B000606D5CC4AE0681023103AD8 -:1069C000014601F08FF92E70A0686860E068A86049 -:1069D000002006B070BD60680190C4482038029065 -:1069E0000120087168460670206A049029466846AE -:1069F000FFF752FFEDE7027B032A06D00022242393 -:106A00005A540B78092B02D003E0042070470A7611 -:106A1000CA61027B9300521C0273C150032070476D -:106A2000F0B50E4615460C46203602463179012057 -:106A3000072393B000290CD0012924D002292ED09D -:106A4000032904D12978042901D12B70002013B027 -:106A5000F0BD01203071606800280DD0A1690B7075 -:106A600060684860206988606069C860206A086260 -:106A70001046FFF7C0FFEAE706202870206968602B -:106A80006069A86009E029780629E0D10220307108 -:106A9000042028709548203868600320D7E72978BB -:106AA0000429D4D1A08910280AD9103880B2A08135 -:106AB000A1681023091805A86A6801F013F923E0FA -:106AC00010282FD0C2B21020801AA1680DAF1190EB -:106AD000C01914F0B6F911980006000E06D0401E39 -:106AE000C1B280207854384614F008FA6269102345 -:106AF0000DA909A801F0F6F8102309A905A86A68EC -:106B000001F0F0F8032030716068019005A8029050 -:106B1000062069460870206A049029466846FFF7F7 -:106B2000BBFE94E710232269A168E2E7F0B50E46A8 -:106B30000C4620363179012006278FB015460029F2 -:106B40000BD0012932D0022905D12978042902D19C -:106B50000820107000200FB0F0BD217D08A8CA07E2 -:106B6000D20F02718807C10F08A801716846027030 -:106B700041700722801CE16814F063F902A8072223 -:106B80000130216914F05DF9606805900AA806904B -:106B900010236A46A16801F0A5F80120307168460B -:106BA0000774206A0890294604A820E0297804295F -:106BB000D1D1062205A8E16914F043F906A80622FE -:106BC0000230A16914F03DF900200890606801903E -:106BD00009A80290102305AA696801F083F8022031 -:106BE000307168460770206A049029466846FFF7AE -:106BF00053FEB0E770B50D460C46203529790120CB -:106C00008CB01646002909D0012905D13178042914 -:106C100002D10920107000200CB070BD6068019096 -:106C200006A802900822E16814F00BF9082208A8CF -:106C3000A16814F006F90120287106206946087041 -:106C4000206A049031466846FFF726FEE4E770B5F7 -:106C50000D460C462035297901208CB016460029B6 -:106C600008D00129D8D131780429D5D10A20107053 -:106C70000020D1E76068019006A802900822A16870 -:106C800014F0DFF8002008900990012028710620F8 -:106C900069460870206A049031466846FFF7FCFD9B -:106CA000BAE730B50B4620331C7901208BB0002C9D -:106CB00009D0012C05D11178042902D10B201070C4 -:106CC00000200BB030BD4868019005A802908C6888 -:106CD00068462578057564784475CC68257885758F -:106CE0006478C47500200690079001E0E4B30100C9 -:106CF000089001201871062368460370086A049002 -:106D000011466846FFF7C8FDDBE770B50C46203436 -:106D1000034625790120002D0AD0012D14D0022D23 -:106D200005D111780A2902D10C201070002070BD05 -:106D300001202071C868052202704A684260F84A42 -:106D40008260921CC2600BE015780B2DEFD10220FF -:106D50002071C86804240470526842608A688260A6 -:106D6000096A016201461846FFF745FE70BD30B55D -:106D7000011D02463132947803258379ED432C437B -:106D800023408371DB070DD04B79547923404B713D -:106D90000B79127913400B718278C9788A4200D935 -:106DA000817030BD00224A710A71F5E7F7B50C46D3 -:106DB00086B00020694626460870203631790127C2 -:106DC0001E2015461F2977D24B007B449B885B0011 -:106DD0009F441E0017023E025602690288029A0270 -:106DE000D102F5022E03590371037F03AE03C303DF -:106DF000CC03F7031A0464049A04AB04DF04FE0412 -:106E000010052A0565059B05C605830587058B05C5 -:106E10006069002802D0007813287DD0A068059012 -:106E2000002849D0012168460170206A049003219E -:106E3000684601710A214171E069029020790028B9 -:106E4000EFD0059909780029E7D00C2964D20B000E -:106E500014F0A2FA0CFD1A4B90B5E8FCFBFAF9F815 -:106E600007FD022828D16069002802D00078082890 -:106E700052D1022168460170206A04900598417839 -:106E8000684601710021B9E20620216A05F0B5FBD0 -:106E900020790728E6D1606900F051FF02280CD064 -:106EA000606900F04CFF042807D060690028B8D062 -:106EB00000780128D6D103E01BE261690120087047 -:106EC00005980079C11F0A2901D30A2050E06169A1 -:106ED0000722887060690599303013F0B2FF0120F5 -:106EE000307161690320087034E00728BAD1606905 -:106EF000002896D001780929B4D10599C978890765 -:106F000007D1059949790029DFD1059989790029A7 -:106F1000DBD105994A7900E04EE2014620314B7DF4 -:106F20009A43D2D1059A8B7D92799A43CDD1059A15 -:106F30001279D31F0A2BC8D20979914236D8072279 -:106F4000C01C059913F07DFF0120307161690A2092 -:106F50000870032069460870206A04906069313027 -:106F600001906069001D029060691C300390A1E2ED -:106F70002076F2E311288DD1606900F0E0FE04284C -:106F800004D0606900F0DBFE0B2893D1606905999D -:106F900010223730491C13F054FF6069017804292E -:106FA0007CD12421095C8278914201D90620DFE757 -:106FB000052101700320307168460170E2E3112859 -:106FC00094D1606900F0BBFE062804D0606900F02F -:106FD000B6FE0C288AD1E068002813D0206900286A -:106FE00010D060690178062910D00D210170606908 -:106FF000059910225730491C13F023FF6069573060 -:1070000009218CE100206946087072E107210170B6 -:107010006069059910224730491C13F012FF60691E -:107020004730EDE70228F0D1606900F088FE0028C3 -:10703000EBD0606900F083FE0128E6D0606900F0C3 -:107040007EFE05E0B1E08DE06CE02AE00AE0D6E0EB -:107050000828DAD00521684601710598417868460C -:10706000417146E11128D0D160690028CDD0017866 -:107070000E29CAD1C16A4078022810D000201422FB -:1070800050431430085805991022491C13F0D9FEBA -:107090000520216A00F041FE0F205EE0F1E10120B1 -:1070A000EDE70B28B1D160690028AED001780F2937 -:1070B000ABD1C16A4078022826D000201422504368 -:1070C0000C300958059842780A70807848706069D9 -:1070D000C16A4078022819D0002014225043103091 -:1070E000085805990822C91C13F0ABFE0520216A37 -:1070F00000F013FE60694178022909D000220832AD -:10710000825C5208520073E00120D7E70120E4E7D7 -:107110000122F4E7012100E0002108314254BCE3E0 -:10712000BEB3010011289CD16069002899D0017874 -:10713000102996D1C16A4078022811D0002014226B -:1071400050431830085805991022491C13F079FE55 -:107150000520216A00F0E1FD112061690870B4E3A7 -:107160000120ECE7082884D1606900289DD00178CF -:10717000112997D10599C06A49780170606905990C -:10718000C06A0622401C891C13F05BFE0520216AA0 -:1071900000F0C3FD60694178022904D00022083262 -:1071A000825CFD2323E00122F9E71128BBD160694D -:1071B0000028BBD001781229B5D1C16A40780228D5 -:1071C00019D00020142250431C3008580599102271 -:1071D000491C13F036FE0520216A00F09EFD60690F -:1071E0004178022909D000220832825CFB231A4030 -:1071F000022991D18EE70120E4E70122F4E707207C -:10720000B6E6287801288ED16069696814221C309E -:10721000F9F7DAFF6069017F002901D02176ACE33C -:107220000178032901D0032037E00227C770817954 -:107230004907490F8171017A4907490F0172417A63 -:107240004907490F41726069FFF791FD377196E276 -:1072500028780F28E3D1072069460870216A049135 -:10726000916802916946087161690722C91C0298F8 -:1072700013F0E7FD61690420087000203071BBE065 -:1072800028780328CBD1606901780529696807D07F -:107290000822473013F0D5FD0420307105206FE23D -:1072A00008225730F6E728780328B8D160690178BA -:1072B0000529696811D008224F3013F0C2FD05205E -:1072C00030716069006A00280AD00220287000200E -:1072D00028716069006AA860F9E008225F30ECE775 -:1072E00004204DE22878022899D12879002801D07D -:1072F000207642E36069A96801626069002901D1D2 -:10730000F949016206200BE228780F2887D1A86886 -:10731000E0616069017805292BD047300721317180 -:10732000E16802220A706269126A4A6088606069D4 -:107330003030C8606069C01C08616269087D926A6B -:10734000400812784000D207D20F104308756269D6 -:10735000926A521C8A61FD2210406269D26A1278D8 -:10736000D207920F104308756069C06A401CC8615B -:1073700053E25730D2E728780828BAD160690178FB -:1073800005291AD00B210170072069460870206A70 -:107390000490E069029011200871029803210170A5 -:1073A00051681022401C13F04CFD00216846FFF785 -:1073B00073FA00203071E06187E20621E3E7287864 -:1073C0000F2896D1072069460870206A0490A868A3 -:1073D00002901120087102980421017061690A78F5 -:1073E000072A0ED0002232710C220A706169102225 -:1073F000401C473113F025FD00216846FFF74CFA89 -:1074000063E21022401C573113F01BFD0021684637 -:10741000FFF742FA0A203071E168032008706069C2 -:10742000006A486060695730886060694730F3E1FE -:1074300028780828A1D1606969681022373013F0D4 -:10744000D3FC002801D0042092E560690078072869 -:1074500017D00A203071E168032008706069006A63 -:10746000486060695730886060694730C860206A4A -:1074700008620698FFF7BFFA07466069FFF777FCD6 -:107480006BE208207AE1287809289AD10B20307124 -:1074900061696868897810224018511A13F02EFD2E -:1074A000082069460870206A049068680190606945 -:1074B0008078087268E129780D29BBD161698979E2 -:1074C000C90703D00C20307109203EE0307103273A -:1074D00070E228780E28ADD160691422291D1C3075 -:1074E000F9F772FE6069018DC06A4172090A817202 -:1074F00060698178C06AC1716169CA6A081D117AC0 -:10750000C909C90111724379626919438378D26A42 -:107510009B079B0F012B00D0002300799B01C0002B -:1075200003431943117260694078012876D0B4E1B1 -:1075300060694178022901D0012100E00021083171 -:10754000405CC00707D00E20EAE069460870206A58 -:107550001146049019E11320B8E728780F2894D138 -:10756000A868E0610F2030710520EEE72878032835 -:107570008BD16069C16A4078022801D0012000E007 -:10758000002014225043103008580822696813F074 -:1075900058FC10203071E16806202269087060698B -:1075A000406A48606069C36A4078022801D00120BF -:1075B00000E000201427784310301858CA60886013 -:1075C0002BE128780C2886D16069C26A40780228AD -:1075D00001D0012000E00020142148430C30105855 -:1075E00002230932696800F07DFB11203071E168E7 -:1075F000052008706069006A48606069C06A0930E7 -:1076000088603948001F07E128780B28A7D16169F5 -:107610004878CA6A022802D0012001E059E100201E -:1076200014235843143010588A78696813F009FC01 -:1076300060694178C26A022901D0012100E000217D -:107640001423594314315258817850181022511A7A -:1076500013F054FC072069460870206A0490E06922 -:107660000290112008710298062101706169CA6AAE -:107670004978022901D0012100E000211423594357 -:10768000143151581022401C13F0DBFB00216846D6 -:10769000FFF702F90020E06112206FE028780F2840 -:1076A00091D1072168460170206A04909068029089 -:1076B0000B2268460271029801706169CA6A4978B2 -:1076C000022901D0012100E00021142359430C318B -:1076D00051580A784270497881706169CA6A49785C -:1076E000022903D0012102E0C4B3010000211423C8 -:1076F0005943103151580822C01C13F0A2FB00213D -:107700006846FFF7C9F826E760694178022901D089 -:10771000012100E000210831405C800703D51420DE -:1077200030710A2011E71620D0E628780F287AD188 -:10773000A868E061072069460870206A0490E06943 -:107740000290112008710298082101706169CA6ACB -:107750004978022902D0012101E011E1002114231E -:107760005943183151581022401C13F06AFB002174 -:107770006846FFF791F80020E061152030710A207B -:1077800069460870206A049029466846FFF784F825 -:107790002BE028780F2846D1072069460870206A18 -:1077A00004909068029008200871029809210170E5 -:1077B00061690622C969097841706169801CC969DB -:1077C000491C13F03EFB00216846FFF765F8AAE765 -:1077D00060694178022901D0012200E000220832CC -:1077E000805C400703D51720C8E70746B5E00129AC -:1077F00053D070E028780F2815D1A868E0611820D0 -:107800003071E168052008706069006A486060694D -:10781000C06A09308860F848C860206A0862069823 -:10782000FFF7E9F8E1E76FE028780B286CD1606991 -:10783000C16A4078022801D0012000E00020142213 -:1078400050431C3008581022696813F0FAFA0720D8 -:1078500069460870206A0490E0690290112008715E -:1078600002980A2101706169CA6A4978022901D027 -:10787000012100E00021142359431C3151581022EA -:10788000401C13F0DEFA00216846FFF705F80020DF -:10789000E0616069407801281DD1192016E6606911 -:1078A0004278022A09D000210831411809780029BC -:1078B0000DD0CA0703D00E2106E00121F4E78907A5 -:1078C00001D5102100E012210170002772E0012A89 -:1078D00001D00D20FAE51C20F8E51D2030710B20A9 -:1078E00033E62978102948D1F0E56069017801294B -:1078F00043D0082941D00021317100F01AFA0C2040 -:1079000069460870206A049037E028780F2805D06F -:107910001020107003271B2030714BE007216846B0 -:107920000170206A0490A8680290022168460171E3 -:10793000029805210170217E417000216846FEF702 -:10794000ABFF0B2168460170206A04902946684607 -:10795000FEF7A2FF07461B203071012F0DD029E052 -:10796000012168460170206A049004216846017173 -:10797000217E41710020207612E0207E00280FD069 -:107980006169132008701A2030710A206946087056 -:10799000206A049029466846FEF77EFF074609E004 -:1079A0006069002801D01421017068460078002821 -:1079B00000D021E5384609B0F0BDF7B50F462037B5 -:1079C0003879012686B00C46002804D0012828D03A -:1079D00002281CD197E02079012804D0022811D078 -:1079E000032814D10AE0A068407801280ED10620AF -:1079F000216A04F0DCFD00287FD10CE0A16813208F -:107A0000087008E0A0684178022901D0052674E0DA -:107A10000078082871D1012038710A206946087061 -:107A200033E0089800780F2867D107216846017075 -:107A3000206A049008988568029522790220012A1C -:107A400004D0022A29D0032A57D10FE006466846FF -:107A500006710B202870207B00214007400F6870C2 -:107A60006846FEF719FFA068067045E006466846BE -:107A7000067105202870207B687000216846FEF79B -:107A80000BFF3E710B2168460170206A0490684626 -:107A90000899FEF701FF06462FE0684601710120B4 -:107AA0002870207C6870607CC007C00FA870A07C24 -:107AB0004007400FE870E17C2971C0071FD0207D8E -:107AC0004007400F6871607D4007400FA87100219A -:107AD0006846FEF7E1FEA06807222946303013F021 -:107AE000B0F9E068017AA06820300171A1682879B6 -:107AF0008870A16809200870002630465BE70020E6 -:107B0000A8716871E3E7A168142008700121684634 -:107B10000170206A0490042168460171217B417143 -:107B20000021FEF7B9FEE7E7F0B585B00F46054640 -:107B30000124287B800040198038C66F3078411EB0 -:107B40000A290AD22C498000323140188038C36F8C -:107B50003A463146284698470446002C01D0012C6D -:107B600011D1287B401E0006000E287301D003248B -:107B7000DFE70D2069460870306A04900021019605 -:107B80006846FEF789FE032CD3D0204605B0F0BD31 -:107B900070B515460A46044629461046FFF7C4FF4D -:107BA0000646002C0FD0207814280CD1207E002807 -:107BB00006D000202870204629460C30FFF7B4FF7D -:107BC000204600F0B6F8304670BD704710B5012968 -:107BD00003D0022901D0052010BD417000F0A9F8A2 -:107BE000002010BD002809D0027E002A06D00A46D7 -:107BF00001460C31CCE70000C2B301000120704700 -:107C000030B5044687B00D46062004F0F6FC294640 -:107C1000052004F0F2FC2078142805D000206946E5 -:107C200008702046FFF7DEFF07B030BD7FB50E4677 -:107C300000216A4611730178092903D00A2903D06B -:107C4000002407E0446900E08468002C02D0217E13 -:107C5000002912D0154601462846FEF7CCFE03281F -:107C600009D1324629462046FFF792FF6946097B33 -:107C7000002900D0042004B070BD25460C35EAE789 -:107C800000B50023012285B005280CD0062808D1B4 -:107C90006846027004910221017143710021FEF7D0 -:107CA000FBFD05B000BD6846027004910271F4E767 -:107CB00010B590B00C4605216B4619700190234811 -:107CC00002900892001D03900AA96846FFF7AEFFD4 -:107CD000002805D1102220460B9913F0B2F800209D -:107CE00010B010BD30B505E05B1EDBB2CC5CD55CDE -:107CF0006C40C454002BF7D130BD10B5002409E00E -:107D00000B78521E5B00234303700B78401CDC0988 -:107D1000D2B2491C002AF3D110BD70B50C460546FD -:107D200004F06BFC782300222146284604F0BEFBB9 -:107D300070BD4178012900D00821017070470028EA -:107D400001D000787047082070470000BCB30100E4 -:107D500070B5F84D040008D0012C10D0022C07D0CB -:107D6000032C05D0F4A1752007E0F3A16C2004E0FA -:107D70002878012803D0F0A1722013F0ECF92C70C0 -:107D800070BD70B5EB4D044610280AD0112C16D0EA -:107D900028468178122C07D0132C0AD0E6A1A42003 -:107DA0000BE0E5A1992008E0112908D0E2A19E206E -:107DB00003E0112903D0E0A1A12013F0CCF9AC70AD -:107DC00070BD10B5DB4894B0007B002819D0172097 -:107DD00069460870D74900A806220D31023013F019 -:107DE00030F809A9684603F0A8FE0446112805D01A -:107DF000002C03D0D0A1C02013F0ADF9204614B060 -:107E000010BD3220E4E710B50022022103F08CFF00 -:107E100010BDFFB595B01D460E460746FFF7F3FFB0 -:107E200004000AD02078222804D3A07F8006C00F47 -:107E3000A84204D1082019B0F0BDC348FBE73721A0 -:107E4000684601704780002D05D0012101714671FF -:107E50001799817102E000206946087109A96846F6 -:107E600003F06BFEA07FDF21084069010843A07783 -:107E70000020E0E770B50446084620380D460300B0 -:107E800013F08AFA0A060A11232C3342495057612B -:107E9000FF20A9A10D3052E02078202851D1FF20E9 -:107EA000A5A110304BE0A3480178032949D0807880 -:107EB000132846D02078242843D0252841D02328D1 -:107EC0003FD0FF209CA1133039E02078222838D001 -:107ED000232836D8FF2098A11A3030E020782228B5 -:107EE0002FD0FF2094A11E3029E02078222828D00E -:107EF000242826D0262824D0272822D0292820D07C -:107F0000FF208DA121301AE02078252819D0FF20EC -:107F100089A1283013E02078252812D0FF2086A1DF -:107F20002B300CE0207825280BD0FF2082A12E30AA -:107F300005E02078282804D0FF207FA1313013F0FD -:107F40000AF9257070BDFF207BA13430F7E730B50A -:107F50007E4C0B887E4A022801D0934204D09D1F9C -:107F6000A54225D2022802D04D88954203D04D88E3 -:107F7000AD1FA5421CD24C88A34219D88B88FF257F -:107F8000F435AB4214D8022802D0C888904205D0FC -:107F9000C8886E4D0A382D1FA84209D2C888904261 -:107FA00008D0944206D05B1C63438000834201DB0F -:107FB000072030BD002030BDF0B56649884245D36A -:107FC000654A0125AD041368A84201D398423DD308 -:107FD0000279002A06D0082A02D8067B082E05D985 -:107FE0000720F0BD047B002CFAD0F6E7002A06D06B -:107FF00004688C422AD3AC4201D39C4226D3002E83 -:1080000006D084688C4221D3AC4201D39C421DD35C -:1080100000240CE00568A700ED598D4216D3012716 -:10802000BF04BD4201D39D4210D3641CE4B2A242FE -:10803000F0D800220125AD040CE084689700E459D3 -:108040008C4203D3AC4203D39C4201D21020F0BD3A -:10805000521CD2B29642F0D80020F0BD10B5028971 -:108060003E4B111F994213D24189042910D3DB1CC6 -:1080700099420DD891420BD80178890706D54068FE -:10808000002803D0FFF798FF002800D1002010BD82 -:10809000072010BDFFB50022099B002802D099429D -:1080A00005DC6EE0002902D1002004B0F0BD0920FB -:1080B000FBE7845C002C12D087187D78112D59D0F5 -:1080C00010DC2B0013F068F90A561726262C2C2EEC -:1080D0002E4C4C56835C002B46D1521CD2B28A42A5 -:1080E000F8DBE1E71C2D45DA123D2B0013F054F9C3 -:1080F000044242121A42022CD9D1BB78039C072BAE -:10810000237001D25B0701D40A20CEE7029B012431 -:108110001B782CE0E343DB0708E0012C08D029E0C2 -:108120000620C2E70F2523072D075B19002BF4D08B -:108130003046BAE7640C00207372635C6761705F5D -:10814000636F72652E630000023000007B0C00003C -:10815000FFFF000000C0010028000020FD3F0000DC -:10816000029B1B789C0701D50B209EE7022423432A -:10817000029C2370835C521C9A18D2B28A4202DDA0 -:1081800095E7192676028A4293DB8DE710B50478CD -:108190000B46002C08D00121F94A012C07D0022CF3 -:1081A0000BD0032C13D10EE00021197011E01970CF -:1081B0008179890903290AD10BE01970817989092C -:1081C000012904D105E019708179890901D010468F -:1081D00010BD411C0622581C12F033FE002010BDB9 -:1081E00008B51346002806D0E6A00068009048793C -:1081F0006A468009105C18700622581C12F021FE95 -:1082000008BD30B50C46097895B0222902D2082065 -:1082100015B030BD282369460B704880132A03D05F -:108220003B2A01D00720F3E708460A7109A903F0A9 -:1082300084FC050003D121212046FFF71BFE2846C0 -:10824000E6E700B595B0232369460B704880108897 -:1082500088805088C880D088488190880881002014 -:108260008881C88109A9684603F067FC15B000BD84 -:1082700070B50C00064610D0FFF7C5FD050003D110 -:10828000C149C24812F067FFA6802889E08028898A -:10829000208168896081A889A08170BD70B50E4673 -:1082A000050003D00021092004F0A7F90120B84CF3 -:1082B000022E207324D0032E04D0D320B249800094 -:1082C00012F049FFB24806210D3003F02DFFA07CCB -:1082D0008006800EA074FFF774FDA08B00280ED0DE -:1082E000002D0CD0830001220021092004F0DEF8CB -:1082F000092804D0A548A449283012F02CFF70BDED -:10830000A3480321103003F00FFFA07C402180061A -:10831000800E0843A0749E480C3002F04EFBDAE752 -:108320007FB501A9022003F06EFD002851D09748C7 -:108330009549673012F00FFF4BE0029C207821280E -:1083400047D0A07F01072BD52046223000906846F9 -:108350002346628E80882146343301F084FC050078 -:1083600005D011282ED089488749843028E0A07F85 -:10837000F7210840A077E17F480889074000C90F2E -:1083800008432021095D4007400FC9000843E077FA -:108390002078282824D129212046FFF76BFD1FE0F3 -:1083A000400716D568462246808821460E32FFF7E0 -:1083B00048FF050008D0112804D074487249933052 -:1083C00012F0C9FE00250BE0A07FFB210840A0773A -:1083D00006E001A803F025FD0500AED0052D02D072 -:1083E000284604B070BD0020FBE7F8B5040004D1B6 -:1083F00066486549A13012F0AEFE722020706068B8 -:1084000008260178091F0B0012F0C6FF11FD0A466D -:1084100068FC460EFCFC4746464646FD92FD46007B -:108420007B205949C00035E087883846FFF7EBFCD0 -:10843000050004D11F205449400112F08CFE6078E1 -:10844000042130436070524CA07F0843A077212163 -:108450002846FFF70FFDA87F8007800F012801D174 -:10846000801EA080384603F0B1F83846FCF7FBFFC9 -:108470003846FBF79EFB3946022004F0BEF8A87F81 -:10848000EF210840A877FFF74BFF002804D03F48B2 -:108490003D49C93012F05FFEF8BD85882846FFF7D8 -:1084A000B2FC002804D139483749D33012F053FECA -:1084B00060688078012804D034483349D53012F000 -:1084C0004AFE60688179284603F09CF90028E3D0D1 -:1084D0006178314361706168C880F8BD878838462B -:1084E000FFF791FC050004D128482749E63012F037 -:1084F00032FE60783946304360706068C0882881F9 -:1085000060680089688160684089A881022004F061 -:1085100074F80020A875A87F8007800F0228DCD19E -:10852000FFF7FEFE0028D8D0212017494001B1E70F -:1085300080783C2803D00025022814D000E00125D3 -:108540000027002808D03C2806D0022804D00F4875 -:108550000D49FF3012F0FFFD002F06D002263046F5 -:1085600001F06CF9F8BD0127EBE7607830436070EB -:108570000748817F31438177002D0BD00126EEE73C -:10858000023200000302FF01388100002E030000C8 -:10859000640C002060688788384601F07BF9054646 -:1085A00060688079012832D00226A87F06228008E0 -:1085B00080003043A8776068C08A28816068008B9B -:1085C00068816068408BA8816068C079E8756168DF -:1085D00028461830083112F034FC60680622807B8F -:1085E00068706168A81C0F3112F02BFCA87F81070E -:1085F000890F384602F0D4FFA87F8007800F01283A -:10860000ADD101E005E008E0FE488780A7E701263C -:10861000CBE7204601F01EFEF8BD60783043607065 -:10862000F8BDF7B505460078002700090C463E4620 -:1086300001287DD00022F44902287AD0072804D0EE -:108640000A2877D0F149F24839E1686803780D2BA0 -:1086500035D006DC042B6ED0072B3AD00A2B69D11B -:1086600006E0122B3CD0132B44D0142BF7D1BEE0E4 -:1086700011270726002C7CD08088A0806968FB2306 -:108680008979A171DF4905468A7F1A408A770421DA -:1086900003F071FB0521284603F06DFB00212846FD -:1086A00003F069FB0121284603F065FB03212846FE -:1086B00003F061FB0221284603F05DFB01E1012785 -:1086C0000926002CD7D08088A08068688079207225 -:1086D000F7E012270E2680882146FFF7C9FDF0E05B -:1086E0001A270726002CC6D04088A0806868007929 -:1086F000A071E6E081783C293ED010271E26002C90 -:10870000B9D08088A0806868C08A20836868C08AE1 -:10871000E0826868008B60836868408BA08369682A -:10872000607D497F40084000C907C90F084303E046 -:108730006CE097E0BAE029E060756968C007497F9E -:10874000C00F49084900084360756968A21DC879CF -:108750000831FFF745FD69682246887B0D320F31ED -:10876000FFF73EFD68688079002803D0012020755E -:1087700007E076E00220FAE719270726002C70D0E0 -:10878000A271A048F722817F11407DE01B272E2691 -:10879000002C66D0A1806968A21D0879491DFFF7E9 -:1087A0001FFD68682030C07A60736868C07804284C -:1087B000A07B19D040084000A073F92108406968E7 -:1087C0001F22C9788907490F0843A07369684007C9 -:1087D000C97A400FC9000843A073696820460F306A -:1087E0000C3112F02EFB6CE001210843E4E71E2758 -:1087F0000E26002C6DD0A1806868E21D407AA07121 -:1088000069688878C91CFFF7EBFC5AE0287A0128D0 -:1088100005D0022815D07E487C4932384FE01D270C -:108820000E26002C55D06888A080A889E080E889B1 -:108830002081288A6081688AA0817248DF22817F36 -:10884000A2E712270E266888FFF712FD002C40D001 -:1088500068784007400F032833D16A48FD22817FA2 -:1088600092E736E0287A030012F096FD0604101015 -:108870002020202619270726002C2AD0A180614815 -:10888000A271817F4908490081771AE019270726DC -:10889000002C1ED0A180287A012805D00320A071C9 -:1088A0005848EF22817F6FE70220F8E721462846EB -:1088B000029A01F068FEFEBD55485449801F12F02F -:1088C0004AFC0298002C068001D027806680002098 -:1088D000FEBD02980680FAE710B54A4894B0807849 -:1088E000132802D0082014B010BD22206946087059 -:1088F00009A9684603F021F904460021072003F086 -:108900007CFE2046EFE700B53E4895B080781228FF -:1089100001D00820AAE41E21684601700021817060 -:10892000C17009A903F009F90028F3D1002107203B -:1089300003F063FE1120FFF724FA002096E400B54F -:10894000304895B00078022801D0032818D11B21A7 -:1089500008A801730021817369460BA803F0EDF8A4 -:10896000002804D1684640781B2801D003207DE40C -:108970000021084603F041FE68468078002801D0B7 -:10898000082073E40120FFF7E3F900206EE4F8B556 -:108990001C4C030012F000FD0A06791779797979E9 -:1089A00044356779FFF7CBFF00282AD1F8F7DAFFC3 -:1089B000002826D02221017000210172F8F7B3FFB0 -:1089C000A07F01214BE08EB23046FFF71CFA050074 -:1089D00004D10F480D492E3012F0BDFB2878212814 -:1089E0000FD0F8F7BFFF002814D012210170022722 -:1089F000077246800020A875F8F795FFA07F3843DE -:108A0000A077F8BD640C0020FFFF00003881000053 -:108A10005F050000132229463046FFF7F2FBF0E71E -:108A2000A578122D06D0132D07D0F849F84812F07A -:108A300092FBE6E7FFF767FF01E0FFF74DFF002835 -:108A4000DFD1F8F78FFF0028DBD022210170122D33 -:108A500007D002210172F8F766FFA07F10210843BA -:108A6000CEE70121F6E7A07C810901290BD080091E -:108A700004D0E748E549223012F06DFB03210020C5 -:108A8000FFF70CFCBDE70221F9E7E148DF49293097 -:108A9000CDE7F7B514460D0004D1DD48DB49313090 -:108AA00012F059FB28780827012807D002281FD088 -:108AB000D748D649623012F04EFBFEBD0098FFF752 -:108AC000A2F9060004D1D248D049383012F043FB55 -:108AD0000220B0751030207060783843607007CD88 -:108AE000083407C4CB482022817F11438177FEBD23 -:108AF0000098FFF788F9060004D1C548C3494630FD -:108B000012F029FBA988C448814208D1EA88824230 -:108B100005D1132231460098FFF773FBFEBD814259 -:108B200002D1E888002809D01220207060783843EC -:108B3000607007CD083407C4002006E078230022C7 -:108B40000220009903F0B2FC0120B075FEBDB148CF -:108B500040897047FFB591B01498FAF71BF90028C7 -:108B60005DD10124684603218471C90281800022FD -:108B700001A92046FBF7ECFA002850D168461521E0 -:108B800084714902818000261C2102A8009612F0FF -:108B9000B7F90120014668461031017000200146F6 -:108BA000684641708178F9273940891C21438170DA -:108BB000017A02252943017212998186C6861F21F6 -:108BC00001870C9011980F9001A80B9009AA0BA98E -:108BD00002A8FBF788F8002821D168468D4E808CCA -:108BE000F080684684718D498180807809AA384078 -:108BF000801C41084900684681708586058713A856 -:108C00000F900BA902A8FBF76EF8002807D1684661 -:108C1000808C308131460A311498FAF7CEF815B0BD -:108C2000F0BD30B50C467E4995B08C423CD37D49B1 -:108C3000012292040968944201D38C4234D3203833 -:108C400000220125030012F0A7FB06042A44484E27 -:108C5000575F0021082003F0AAFC002802D0112051 -:108C600015B030BD24206946087000A80522A11C5B -:108C7000023012F0E6F809A9684602F05EFF05002E -:108C80002FD1082300221146184603F00FFC0828B4 -:108C900027D05F485D49D63012F05DFA21E0606868 -:108CA000002803D0884201D21020D9E73D21684630 -:108CB0000170218841806188818009A902F03DFF0F -:108CC00005000ED1606800280BD06946098D01802F -:108CD00007E0206801F0B2FE02E0204600F024FE2A -:108CE00005462846BCE73E2007E0857000E082701C -:108CF00009A902F022FFF3E73420694608702078C2 -:108D0000C0076846F3D0F0E70720A9E730B50C4666 -:108D1000444995B009688C4201D21020A0E7203860 -:108D2000030012F039FB05042121232132002088A1 -:108D3000FFF769F8002804D00078222803D2082021 -:108D40008EE739488CE725216846017021884180EB -:108D500009A902F0F2FE050015D10AA90522023187 -:108D6000A01C12F06EF80EE006250CE0206800282A -:108D700005D0884201D2102505E001F055FE2548B6 -:108D80000025808BA08028466AE7072068E72148F5 -:108D90001330704710B520211E4812F0AFF80120A3 -:108DA000FEF7D6FF1120FEF7ECFF00211948C9435A -:108DB000818000218176E1218900818301460C3088 -:108DC0000D310446F8F74EFE1248072221461330B3 -:108DD00012F037F8FEF7F5FF002803D00B491348CF -:108DE00012F0B9F901F0E5F910BD10B504463C21C7 -:108DF00012F084F8A07F80088000A07720202070E7 -:108E00000020A0752034607010BD00003881000083 -:108E1000B5050000640C0020FFFF0000012A0000DF -:108E200000C0010028000020023000001C070000E4 -:108E30007047FEB50546FF480C46814207D3012026 -:108E40008004844205D3FC480068844201D210208B -:108E5000FEBD002D02D0012D32D126E0F7490822B7 -:108E60000F46684611F0EDFF39462046FFF78EF9B0 -:108E70000028EDD1FEF7A5FF060006D007226946BF -:108E8000384611F0DEFF3046FEBD2078002801D0C4 -:108E9000012805D1E94807223946C01D11F0D1FF4C -:108EA0000021092003F0A9FB0FE00978002907D071 -:108EB000012905D0022905D0032903D0E048FEBDD1 -:108EC0000720FEBD0120FFF7E9F9DC480C38857664 -:108ED0000020FEBD10B5D8490968884201D2102093 -:108EE00092E7D64902460C390B7B0D311846FFF745 -:108EF00077F9002088E7FFB599B00546002008A95A -:108F000008746946087108A908730875CA481446A8 -:108F10000121C84A890400681E46002D05D09542EB -:108F20000BD38D4201D3854207D3002C08D0944245 -:108F300003D38C4204D3844202D210201DB0F0BD72 -:108F40002846204318D01F270BAB0CAA00972846B1 -:108F50001A99FFF79FF80028F0D10DAB01AA31460E -:108F600020460097FFF796F80028E7D16846007979 -:108F7000C00703D00A20E1E70720DFE702AF002D9A -:108F80000FD01A20694608721A9888722946F81C70 -:108F90001A9A11F056FF0EA902A802F0CEFD002881 -:108FA000CCD1002C0ED02021684601728672324648 -:108FB0002146F81C11F045FF0EA902A802F0BDFDE4 -:108FC0000028BBD19D4908A8007B0C3948700020BF -:108FD000B4E770B506460A200C46087015461146DF -:108FE000204602F0AAFD002807D139212170204631 -:108FF000294602F0A2FD002804D0082801D190489B -:10900000401C70BD2A462146304600F0B9FC04469B -:10901000082803D18B498C4812F09DF8204670BD7A -:10902000F0B5044689A003C897B0824D002715917A -:109030001490AC4211D380480121890403688C420A -:1090400001D39C4209D32078012809D16268AA4241 -:1090500003D38A4204D39A4202D2102017B0F0BD43 -:1090600076490C390A78012A0CD18A88794B9A42C0 -:1090700003D0002806D0012804D08A7F13079B0F55 -:1090800006D101E00820E9E7D30701D1910701D516 -:109090001120E3E7218A704B0A46203A9A4207D30F -:1090A000012877D1002975D1628A002A72D111E096 -:1090B000022801D0032801D1A0296BD3012809D0AF -:1090C0005E4A0C3A5278D20704D0628A002A61D0F4 -:1090D000B42A5FD8002806D0012808D0022804D07E -:1090E000032857D117E0002518E0022516E00029D3 -:1090F00002D1608A00280CD004256068007800281E -:109100000CD0012809D0022807D0032805D04C48EC -:10911000A4E70125F1E7032500E00127207A0028D4 -:1091200006D0012806D0022806D0032867D105E022 -:10913000002604E0012602E0022600E00326002DBE -:1091400001D0022D16D1002E14D0E068002803D0E3 -:10915000FEF732FF002881D138480C38407880076C -:1091600002D03748401E79E7022D03D1022E46D0A7 -:10917000032E44D0182168460170218A4180218A3B -:10918000818085712D480C38007B002803D0012890 -:109190006FD104E033E000216846C17102E0012094 -:1091A0006946C8716846077221780930012920D0C4 -:1091B000062111F0A3FE69460E74207D8207C107C7 -:1091C000D20F4007C90F5200C00F11438000014366 -:1091D00014A8405C6946C873002810D009A96846E5 -:1091E00002F0ABFC002893D1002D0AD0022D08D04C -:1091F00012E061680622491C11F023FEDBE707201C -:109200002CE7002E08D0E068002805D009AA69469E -:10921000FFF7DFFE0028A6D11B2069460870012059 -:10922000887009A9684602F088FC00289BD108A82C -:10923000407913E000C0010028000020700C0020DD -:1092400002320000388100002708000007060504EC -:1092500003020100FFFF0000E13F00001B2819D1BD -:109260002B0012F099F80504040707040A000320F4 -:1092700001E00FE00220FEF76BFD012D0CD0608AAB -:10928000002809D0002283001146104603F00EF991 -:10929000002801D00320E1E60020DFE6F3B5032635 -:1092A00087B00D4600290AD0FE4885426FD30120C1 -:1092B0008004854203D3FC480068854267D3079841 -:1092C000FEF7A1FD040005D02078222804D2082052 -:1092D00009B0F0BDF548FBE7A07F8707BF0F002D61 -:1092E00005D029463846FEF732FE0600F0D1394651 -:1092F0000027EF48012907D0022931D0ED49EE4877 -:1093000011F029FF3046E3E7A27D2946012A02D069 -:10931000827F920701D51120DAE700291BD10821AD -:109320006A46049711820592418904AAE348FBF733 -:10933000FFFA0028CCD16846008A082801D0032013 -:10934000C6E7684601880181418841818188818121 -:10935000C188C18102A9079802F0E7F90646D1E762 -:10936000A17D022916D1807F800613D4002D04D060 -:10937000A07F40070CD4002100E00121079802F0F3 -:1093800014FA0600BED1A775002DBBD004E01AE088 -:109390001126B7E7002D16D02A4621460798FEF77A -:1093A00050FF06461128ADD1A07F4007AAD4204621 -:1093B000082229460E3011F044FDA07F0421084305 -:1093C000A07700269EE7102082E770B50C46054680 -:1093D000FEF719FD010004D022462846FEF711FFD2 -:1093E00070BDB24870BD00B50146143195B0192961 -:1093F00001D2810707D001461E3104D00A3102D0C4 -:10940000072015B000BD312269460A70887009A98D -:10941000684602F092FBF4E701B582B0022069468B -:109420000880A34802AB00896A460021FBF7EAF8EE -:1094300069460988022900D003200EBD1CB5002111 -:10944000009102216A46118097490190096888427B -:1094500001D210201CBD964801899848FBF768FA94 -:10946000694609880229F5D003201CBDF0B50E46D7 -:109470008C4985B0174605468E4207D38A4801229B -:1094800092040068964204D3864202D2102005B0AE -:10949000F0BD1F2F01D90C20F9E7854C8D4226D352 -:1094A000954201D3854222D3E08803A9FBF75BF8FC -:1094B0000028ECD1287869464873E08803A9FBF7B7 -:1094C00033F80028E3D16946009008780221084368 -:1094D00069460870497B090703D00821084369469B -:1094E0000870E0886946FAF7B8FF0028CFD16946CE -:1094F0008F80E088334601AA0021FBF783F8694694 -:109500008988B942C3D00320C1E71CB50C460021AD -:1095100000910191228869460A8063490190096897 -:10952000002801D0884201D38C4201D210201CBDFA -:10953000002801D0002A09D05D486A46C1885F48EA -:10954000FBF7F6F96946098821801CBD0C201CBD7B -:1095500010B50123FEF75DFC56E4002310B51A4652 -:109560001946FEF756FC4FE470B504464D4894B0DA -:10957000844207D301208004844206D34A4800680D -:10958000844202D2102014B070BD2046FEF766FD62 -:109590000028F8D146488178112901D00820F2E747 -:1095A000817FC90601D51120EDE71D2269460A70A9 -:1095B00021780025CA07D20F69468A7022898A80DD -:1095C0006289CA80217801268907CA0F69464A72D2 -:1095D000007B002803D0012804D00320D3E70846ED -:1095E0000D7201E008460E7209A902F0A6FA0028E1 -:1095F000C9D12078800708D56068002805D009AA5D -:109600006946FFF7E6FC0028BDD11E2168460170BF -:109610008670C57009A902F090FA0028B3D1A0891C -:1096200000F073F90400AED11220FEF7AAFB204629 -:10963000A9E7F0B516461C4A0C4605001948204912 -:10964000126899B005D085420FD38D4201D395425F -:109650000BD3844209D38C4201D3944205D3864272 -:1096600003D38E4204D3964202D2102019B0F0BD2B -:109670000F4FB87FC106890F01D1400701D51120D6 -:10968000F4E72046FEF7EAFC0028EFD120788107B6 -:10969000C90F294303D0800714D5002D12D007200D -:1096A000E4E7000000C001002800002002300000B4 -:1096B000640C002038810000F3090000FFFF000067 -:1096C0000000040031460220FEF741FC0028CDD105 -:1096D000C9488078112803D0122801D00820C5E796 -:1096E0000220002714A9189002F08DFB00280DD04D -:1096F000C2A1C64811F02FFD08E01598807F8107B0 -:109700001898890F814201D17F1CFFB214A802F082 -:1097100088FB0028F1D0032F01D30420A6E7B64828 -:109720008078122803D1FFF7EEF800289ED1207828 -:10973000800708D56068002805D009AA6946FFF7A8 -:1097400048FC002892D1212168460170218941807E -:1097500061898180207800278007C10F6846817168 -:1097600020788007002815DB2878002807D00128FA -:1097700008D0022806D0032804D0A54876E768461A -:10978000C77102E001206946C8710622691C02A85F -:1097900011F057FB9848007B002803D0012804D023 -:1097A000032063E76846877302E0012069468873F7 -:1097B00031886846018271884182B1888182F1884E -:1097C000C1820783478309A902F0B7F9002886D12F -:1097D000A08900F09AF80400A0D11320FEF7D1FA76 -:1097E000204643E730B505468A4895B000680C46E8 -:1097F000814202D2102015B030BD2846FEF703FB8F -:10980000002807D00178222902D3807F800603D464 -:109810000820F0E78048EEE7132168460170458094 -:1098200009A902F08AF90028E5D108AA0A215156AF -:109830007F2901D02170DEE70520DCE710B56E49F5 -:10984000012807D0022815D0FF206CA14D3011F05F -:1098500082FC81E60878032804D0FF2067A143300A -:1098600011F079FC0021084602F0C7FE0120FEF746 -:109870006FFA71E68878132804D0FF205FA1483082 -:1098800011F069FC0021072002F0B7FE1120FEF75D -:1098900078FA61E6F8B504460122022102F044FAA2 -:1098A000074601220321204602F03EFA0646012225 -:1098B0000521204602F038FA0546012204212046FF -:1098C00002F032FA0446002F04D1AF204BA18000F1 -:1098D00011F041FC002E04D14C4848A11A3811F077 -:1098E0003AFC002D04D1494844A1193811F033FC49 -:1098F000002C04D1454841A1183811F02CFC22213C -:109900003846FEF7B7FA3846F8BD10B5002809D03A -:10991000830000221146072002F0C8FD072801D06D -:10992000032019E6002017E610B504460068002859 -:109930000CD03A49884207D301218904884205D3D3 -:1099400034490968884201D2102005E601F060F828 -:10995000A088294CA083A07E01280DD100210920D8 -:1099600002F025FE002800D00120A17C89090129F0 -:1099700004D00321FEF792FC0020EDE50221F9E777 -:10998000F7B500260C4605460B271AE02968B000FB -:1099900009580978002903D0012901D00720FEBD0C -:1099A000A170296806220958E01C491C11F049FAE7 -:1099B00027702046029902F0C0F80028EFD1761CEB -:1099C000F6B22879B042E1D800263A270FE0A8681D -:1099D000B10041581022A01C11F033FA2770204624 -:1099E000029902F0AAF80028D9D1761CF6B2287B99 -:1099F000B042ECD80020FEBD640C00207372635CA2 -:109A00006761705F636F72652E630000D7020000AC -:109A100002320000280000200230000000C00100D7 -:109A200030B5FE4B9A4207D301239B049A4205D3DB -:109A3000FB4B1B689A4201D2102030BD1578EB0613 -:109A40005B0F042B07D85478072C04D39378102B82 -:109A500001D8A34201D2072030BDD3785B0702D4DE -:109A600013795B0701D5062030BDC37FAC075B08C7 -:109A70005B00E40F2343C3770878EF231840137883 -:109A80009B06DB0F1B0118430870F1231840137865 -:109A9000DB065B0F5B0018430870507808730020EA -:109AA00030BD30B500240C70C378DB07DB0F0B70C2 -:109AB000C578AD07ED0F6D002B430B70C5786D07B2 -:109AC000ED0FAD002B430B7014700179C907C90F5E -:109AD000117003799B07DB0F5B001943117000794C -:109AE0004007C00F80000143117030BD70B51446AF -:109AF0000D460646F7F736FF002809D0A22101706F -:109B0000142221460830F7F75FFBF7F70CFF70BD12 -:109B1000132229463046FEF774FB70BD70B514461B -:109B20000E460546F7F71EFF002809D022210170D6 -:109B300045802178017261784172F7F7F4FE70BDBB -:109B4000132231462846FEF75CFB70BD10B5B54CBC -:109B5000207C00280DD12046B34A21461038FEF75C -:109B6000A7F8002803D0B1A1F12011F0F4FA0120E8 -:109B7000207410BDFFB581B00A9D06461C461746ED -:109B80001421284611F0BCF90B9800210160F80758 -:109B90000ED0A34920680968884239D31230286062 -:109BA0002068143068602068A8600B982168016004 -:109BB000B80726D56068002803D09949096888420B -:109BC00026D3029900290AD0FC3600280ED031464F -:109BD0001030FEF7DBFA00281BD1606810E0002887 -:109BE00016D0E86080366068B0670AE0FFF7CFF80B -:109BF00001460722304611F024F9FFF7A7FF8948F4 -:109C0000E860780708D58649A0680968884202D2CA -:109C1000102005B0F0BD28610020FAE770B50546B8 -:109C200011200C460870002161702121495D002936 -:109C300008D003290ED0042910D0FF207BA1523078 -:109C400011F089FA20780009012802D9E87FC008BC -:109C5000607070BD0007000F203002E00007000FA9 -:109C600030302070EEE770B594B015460C462C22CB -:109C70006946189E0A704880002B17D008221946A2 -:109C800001A811F0DEF868468581102231460E30B9 -:109C900011F0D7F809A9684601F04FFF002803D159 -:109CA000A17F10221143A17714B070BD0020019054 -:109CB0000290E8E7F0B50646008A97B080B20D46FC -:109CC0000190FEF7A0F804465648317848385B4FBB -:109CD00009900B0011F060FB0EFEFD43084A7283F1 -:109CE000B8D9FCFBFAF9F8FEA07F8007800F0128A5 -:109CF00007D000210022019802F016F8050007D1D4 -:109D000001E00121F6E7FF2048A1943011F023FA89 -:109D1000387CC00904D049484038406DA86112E041 -:109D20002B20694608720BA902A801F006FF002843 -:109D300004D0FF203DA19F3011F00DFA40490C984E -:109D400011F0E8F8A9617068A862B068E86220784C -:109D5000252804D0FF2035A1A53011F0FCF93246AA -:109D600021460198FFF7C2FE17B0F0BDA07F800723 -:109D7000800F012807D000210022019801F0D4FFB4 -:109D8000060007D101E00121F6E7FF2027A1AF304F -:109D900011F0E1F92078252804D03078012108431A -:109DA0003070E1E702202870B068A860B068002831 -:109DB00002D000202871D7E70120FBE72B2069465D -:109DC0000870184968464C3901F0B7FE002804D0E5 -:109DD000FF2016A1CE3011F0BEF903201BE02A208F -:109DE0006946087000A810220230716811F029F845 -:109DF00004A810220230B16811F023F8094968461E -:109E00004C3901F09AFE002804D0FF2007A1DF3072 -:109E100011F0A1F904202870099813E000C0010096 -:109E200028000020300D0020FFFF00007372635CEB -:109E30006761705F7365632E63000000500E002041 -:109E400040420F0068608FE7B068002804D1FF200F -:109E5000F649EB3011F07FF9E07F400704D5FF2091 -:109E6000F249EC3011F077F9B06806220A38009018 -:109E700033790421019801F058FA002891D0FF208D -:109E8000EA49F13011F067F96EE7002C04D1FF20A8 -:109E9000E649F93011F05FF92046223010220546DC -:109EA000716810F0CEFF28212046FDF7E3FFA07F68 -:109EB0008007800F022814D100231A4621460095FE -:109EC0000198FFF7D0FE06E055E1B6E0ACE089E08E -:109ED0002CE065E069E111280BD029212046FDF72F -:109EE000C9FFE07F317A4007400FC9000843E0779F -:109EF0003AE7A07F000703D5CC49CD4811F02BF9F4 -:109F0000A07F08210843A0770020608620463430D7 -:109F100010F0F4FFE07FFD220146C9071040890FD1 -:109F20000843E077307A203420701DE7A07F800757 -:109F3000800F012807D000210022019801F0F4FED3 -:109F4000040007D101E00121F6E7B948B7491D3007 -:109F500011F001F92B2069460872B64902A801F0F8 -:109F6000ECFD002804D0B248B049223011F0F3F8DB -:109F7000B0488188204621300176090A41760E21B9 -:109F800029702146FC316960017E2974407E687425 -:109F9000A8482C30A860103030346C61E860E3E6EB -:109FA000002C04D1A248A149363011F0D4F8207811 -:109FB00021289DD93079012802D0022808D103E058 -:109FC000E07F04210843E077387C0121084338749E -:109FD000324621460198FFF789FD23212046FDF7EF -:109FE00049FFC1E601220421019801F07DFC00280F -:109FF0009BD0A07F8007800F012807D0002100227E -:10A00000019801F091FE040007D101E00121F6E77B -:10A0100087488649543011F09EF80F202870172089 -:10A0200028716E34AC609FE60421019801F0ABFC0E -:10A030000028B4D11020287096E6A07F8007800FFA -:10A04000012807D000210022019801F06DFE0500D3 -:10A0500007D101E00121F6E7754874496D3011F030 -:10A060007AF82E462036307E41064DD5A17F8F07E7 -:10A07000BF0FC00713D02A468032516F00290ED07F -:10A08000087CF37DC007C00F5B0018430874516F54 -:10A09000E27F40084000D207D20F10430874307EA0 -:10A0A000000713D528468030026F002A0ED0117C9D -:10A0B000F37DC907C90F5B0019431174E27F49089A -:10A0C0004900D207006FD20F11430174307E800720 -:10A0D0000BD5F8204259002A07D0012F05D0294678 -:10A0E000307C31311032FEF77BF8307EC0060BD564 -:10A0F000F8204259002A07D0012F05D12946307C8B -:10A1000031311032FEF76CF8052368460370357E56 -:10A110004570484822226038019902704278D2087E -:10A12000D200D21C4270418003724572F7F782FD63 -:10A130002078252809D021280BD0AD203B4980006C -:10A1400011F009F82078222803D922212046FDF7B2 -:10A1500091FEA07F8007800F01280AD0002101987E -:10A1600001F009FE002800D1FEE5AF202F49800054 -:10A1700088E60121F3E774682E4D207860350928C0 -:10A1800002D00A28F0D10BE0E168002902D028466D -:10A19000F8F7D7FE2169002902D02846F8F7D1FE4A -:10A1A00021462846F8F7CDFEDEE521481F49DC3080 -:10A1B00068E6204810B5072228216030F8F7A8FE8D -:10A1C0001D480024017C4906490E0174403844654D -:10A1D000FDF7FBFC17493C3108461038F7F779FCCE -:10A1E00014484C30047410BD70B50D46FDF70BFEDD -:10A1F000040004D103200D49000210F0ACFFFF2140 -:10A200000531284610F07CFEA07F8007800F0128D2 -:10A2100016D0022128468830FDF7D8FC002803D04C -:10A220000249064810F097FF70BD00002C9E000008 -:10A2300005020000E40C0020500E00200503000081 -:10A240000121E7E70A46014610B510468830FDF7C0 -:10A25000D7FC10BDF0B505464068082601789BB0D4 -:10A2600008290DD00B2903D00C293FD10121817180 -:10A27000686887883846FDF7C6FD040041D13BE099 -:10A2800047883846FDF7BFFD040003D1FD49FE486D -:10A2900010F061FF2078212828D0282828D168686C -:10A2A00002210C3000F0BEFF002821D06868082190 -:10A2B000001D00F0B7FF00281AD02D21684601705C -:10A2C000478021461022223101A810F0BAFD0FA9C3 -:10A2D000684601F032FC002804D0CB20E949800018 -:10A2E00010F039FF29212046FDF7C4FD1BB0F0BD59 -:10A2F000687830436870F9E7E348E2492D3010F0A0 -:10A300002AFFA07F8107890F022902D1EF2108408F -:10A31000A0772078212810D068688179002902D0A0 -:10A320008078002818D0A07F8007800F022864D092 -:10A330000720D449C00110F00EFFA07F8007800FD6 -:10A340000228D3D1FDF7ECFF0028CFD0CE48CD496D -:10A35000733010F000FFC9E7687830436870E07F21 -:10A36000C00701D0042100E00321212001552078FD -:10A37000292818D02428E0D13946062002F03DF9DA -:10A3800022212046FDF776FDA07F8007800F01285F -:10A3900031D00021384601F0EEFC0028CDD0BA487B -:10A3A000B8495830C7E7A07F8007800F012807D041 -:10A3B00000210022384601F0B7FC050007D101E07A -:10A3C0000121F6E71B20AF49400110F0C4FE252112 -:10A3D0002046FDF74FFD0D2008A90871284609A960 -:10A3E0008830FDF7FFFB0228A7D00028A5D0A6489B -:10A3F000A4494D309FE70121CCE76878304368706D -:10A400009BE7F7B58AB00A98FDF7FDFC050056D02A -:10A410002878222853D3232851D0E87F40074ED4F0 -:10A42000A87F8007800F01280ED0002201280DD0C0 -:10A4300000210A9801F078FC064694480290F8F74B -:10A4400077FD040009D103E00122EFE70121F0E7E5 -:10A4500075208C49C00010F07EFE002E0FD088368B -:10A4600066610298F8F764FD07460298F8F760FD08 -:10A4700006462878222807D0242805D008E00020A6 -:10A4800007460646606103E025212846FDF7F2FCF9 -:10A49000092020700A9820620C9820710B98E760C0 -:10A4A0002661A06004A92046FDF7C0FB022806D063 -:10A4B000002804D074487349AF3010F04CFE0DB042 -:10A4C000F0BD30B587B00446FDF79DFC0546807FA2 -:10A4D0008007800F01280BD000210022204601F0C8 -:10A4E00023FC0446287822281ED9002C07D101E03D -:10A4F0000121F2E764486349BB3010F02CFE0F21C4 -:10A50000684601701721017120466E30029069463D -:10A510001A30FDF767FB022806D0002804D05A48FD -:10A520005849C03010F017FE07B030BD30B587B0C5 -:10A530000446FDF768FC0546807F8007800F0128F0 -:10A540000BD000210022204601F0EEFB04462878C3 -:10A550002228E9D9002C07D101E00121F2E74A487D -:10A560004849CD3010F0F7FD1020694608702046AC -:10A570008830FDF737FB0028D6D043484149D0301A -:10A5800010F0E9FDD0E7F7B505460078002700098F -:10A5900082B00C463E4602287CD0072802D00A280A -:10A5A00049D149E068680178082906D00B292FD0E5 -:10A5B0000C292DD03349364865E114271A26002C82 -:10A5C00069D04088A080FDF71EFC0090002804D1CF -:10A5D0002F482C49243810F0BEFD00980099C07D0A -:10A5E000A21D1831FDF7FCFD686808228089E08112 -:10A5F000696820461030091D10F023FC207E0121DF -:10A600000843F9210840207600984021807F50E0DF -:10A6100018270826002CD3D08088A080FDF7F3FBF4 -:10A62000050004D11A481749401F10F094FDA11DE0 -:10A630002846FFF7F3FA28E1002C01D0288BA080F0 -:10A64000287A01287ED0022805D0032838D0104867 -:10A650000C49853017E11C270726002CB0D0A088B4 -:10A66000FDF7D1FB0090002804D1094805491330BB -:10A6700010F071FD287B8007800F0128A0791CD085 -:10A68000400809E02C9E00001A030000440D002041 -:10A6900027040000E9E0E3E04000A071FD2108404C -:10A6A000297B4907C90F49000843A0710098802100 -:10A6B000807F084300998877E7E001210843ECE7B1 -:10A6C00013270B26002CA6D0A088FDF79CFB00903A -:10A6D000807F8007800F012807D00021A0880022FA -:10A6E00001F022FB050006D101E00121F6E7FB495C -:10A6F000FB4810F030FD0098807F8007800F012814 -:10A7000050D0E86A81788907890F0129A1794BD057 -:10A7100049084900A1718278FD255207D20F2940CE -:10A7200052001143A171E322114002785207D20E68 -:10A730001143A171DF2211404278D207920E1143DA -:10A74000A17100E033E00021E171C178217242790A -:10A750000179607AD30740084000DB0F1843930764 -:10A76000DB0F28405B0018435207FB23D20F184031 -:10A77000920010436072A07ACA0740084000D20FCE -:10A7800010438A07D20F2840520049071043C90FCF -:10A79000184089000843A07200980078232874D9D3 -:10A7A0002621C4E0A86AADE701221143B2E7297B64 -:10A7B000CC48022911D017270C26002C50D0012993 -:10A7C00012D003291FD0042920D005291ED09320A0 -:10A7D000C249C00010F0BFFC23E019270726002C57 -:10A7E00053D00121A17105E00121A171E17989080E -:10A7F0008900E171017CCA094906D201890E49002C -:10A800000A4302740DE00220A07106E0687B000795 -:10A81000000F8030A07105291DD0E07980088000EC -:10A82000E071A088FDF7EFFA0546007821282CD0CA -:10A83000232804D0AA48A949573010F08CFCA87FDF -:10A840008007800F01280ED00021A08801F093FA24 -:10A85000222128466CE0E07980088000401CDFE778 -:10A860000498068017E00121EFE7002C01D06888EA -:10A87000A080287A032832D004280FD005285AD087 -:10A8800097489649B03010F066FC0498002C06807A -:10A8900001D027806680002005B0F0BD15270C266A -:10A8A000002CDDD0A088FDF7AEFA807F8007800FF6 -:10A8B000012807D00021A088002201F035FA050008 -:10A8C00007D101E00121F6E785488449763010F090 -:10A8D00042FC0622A11DA86907F036FAD5E7162723 -:10A8E0000726002CBCD0A088FDF78DFA0090807F51 -:10A8F0008007800F012807D00021A088002201F0E6 -:10A9000013FA050007D101E00121F6E77448734905 -:10A91000843010F020FC2878C00601D5022000E029 -:10A920000120A071009800782328AED92721009833 -:10A93000FDF7A0FAA9E717270C26002C90D0A088D5 -:10A94000FDF761FA00906D7A002804D164486349EC -:10A95000973010F000FC0621A01D10F0CFFA002067 -:10A96000A071207A032108432072FB21084000993E -:10A97000C97FC907490F08432072680685D5E07969 -:10A9800004210843E071A07AE90740084000C90F9C -:10A990000843E17A2A0749084900D20F1143FD22F2 -:10A9A000AB07DB0F10405B001843A072E806C00F36 -:10A9B000114040000143E17267E710B50446807919 -:10A9C00090B08009012804D045484449C93010F0AE -:10A9D000C2FBFFF7BBF801206946087042480890A7 -:10A9E00042480190201D0290601C0B900AA9684605 -:10A9F000FDF71CF9002804D039483849D43010F04C -:10AA0000AAFB0322601C0B9910F01BFA10B010BDBA -:10AA100010B5364C002805D001461022204610F013 -:10AA200010FA0120207410BD10B50446FFF78EF80F -:10AA300010222E49204610F004FA10BD70B50025F2 -:10AA4000284C00281CD02A49884207D301218904B8 -:10AA5000884205D327490968884201D210250DE0B4 -:10AA6000062107F05BF9411C07D01E4940394865B3 -:10AA7000207C80210843207400E00725284670BD13 -:10AA8000207C4006400EF6E7F3B5002089B00D4665 -:10AA9000029000290AD0164885421CD30120800468 -:10AAA000854203D313480068854214D30998FDF703 -:10AAB000AAF9060003D03078222826D102E00E48F9 -:10AAC0000BB0F0BD002D19D1B07FC10903D08007B4 -:10AAD000800F022812D01020F2E700002C9E000008 -:10AAE0004D040000500E0020FFFF0000300D00203C -:10AAF00000C001002800002002300000B07FC10625 -:10AB000001D4010703D5002D01D00820D8E7FE4964 -:10AB1000097CC90717D1F17F490701D50D20CFE77F -:10AB20008007800F01280CD000210122099801F034 -:10AB3000FBF8070007D0B07F8007800F022804D001 -:10AB40000DE00121F1E71120BAE7002D07D02A46D8 -:10AB500039463046FEF764FF02900028B0D1EB483A -:10AB6000F8F7E6F9040003D1E949EA4810F0F3FAEE -:10AB70000A2020700998206238468830A060B07F93 -:10AB8000FB218007800F012829D0002D3DD0022015 -:10AB90002071381DE06038780007400F2074387845 -:10ABA000C006C00F6074A07C2A788008D20780009D -:10ABB000D20F1043A0740840F17F01AAC907490FC2 -:10ABC0000843A074A878E07469462846FEF769FF38 -:10ABD00068460079207568460078607519E00120A4 -:10ABE0002071207B2A788008D2078000D20F104382 -:10ABF0002073084029788907C90F8900084320730A -:10AC000024213046FDF736F90BE0032020710520A2 -:10AC1000207325213046FDF72DF9B07F4006400E08 -:10AC2000B07703A92046FDF701F8022806D00028D6 -:10AC300004D0B848B6492B3010F08DFA02983FE79F -:10AC4000FFB5B54A0E4607CA97B002AB07C3002747 -:10AC500001970C971798FDF7D6F8050005D02878CE -:10AC6000262804D008201BB0F0BDAC48FBE7A87F25 -:10AC70008007800F012807D000210022179801F0DB -:10AC800053F8040007D101E00121F6E7A148A049EB -:10AC9000623010F060FAA87F8007800F16900128BC -:10ACA00014D0022824D09B4899497B3010F053FAE5 -:10ACB00001210022852E31D01EDC002E26D0812ECF -:10ACC00026D0822E26D0832E1ED125E0002EEFD155 -:10ACD00021462846199AFEF7A3FE0028C3D11998E9 -:10ACE0008078019019980078C007C00F0C90DFE7BA -:10ACF0001998002808D1DBE7862E11D0882E11D0B4 -:10AD0000892E11D08A2E11D00720ACE710460EE014 -:10AD100008460CE002200AE0032008E0052006E0D7 -:10AD2000062004E0082002E0092000E00A200022BA -:10AD3000227101216A461176211D0791002801D058 -:10AD400020710BE1169801280CD0A66AE06A022255 -:10AD5000012111900020A0602846173002291AD046 -:10AD6000012119E0E66AA06A119003203070207872 -:10AD7000FB23C006C00F7070B07801221840019B01 -:10AD8000F37080080C9B800018430221B0700020F3 -:10AD900070713071DEE70021890009190861681CB3 -:10ADA000022A01D0012100E000218900091908616F -:10ADB000B0788007800F01285ED1119880788007D5 -:10ADC000800F012858D1119800790190119840798D -:10ADD0000090169801281DD0317908A80174717966 -:10ADE000017508A8027C01980099024008A8007D1E -:10ADF0000840149010433FD049491A98884207D31D -:10AE000001218904884215D346490968884211D234 -:10AE1000102028E70CAA0DA91998FEF742FE08A8F1 -:10AE2000007C01990840307108A8007D0099084015 -:10AE30007071D6E720463C3021460090F0311698DC -:10AE40000191022834D000211A9B20460C33FEF7D2 -:10AE500091FE0028DDD12046503021460090F4318B -:10AE600016980191012825D0002120461A9B149A9A -:10AE7000FEF780FE0028CCD111988078400702D4DC -:10AE8000E87FC0072BD0169902A8012914D0119988 -:10AE900009784900405A21780907490F4900C840FC -:10AEA0008707BF0F2AD0012F14D0022F0FD113E034 -:10AEB0000121C9E70121D8E721780907490F490095 -:10AEC000405A119909784900C8408707BF0F032FDE -:10AED00004D004E0022711E001270FE002271698B2 -:10AEE00001280BD1B078FB210840E97FC907490F41 -:10AEF0000843B07020780007400F30702078400879 -:10AF00004000207011990FE0500E0020440D0020E9 -:10AF10002C9E0000A90500001CB4010002300000B6 -:10AF200000C001002800002049781022C907C90E7E -:10AF3000D243114308402070C00622D4022F20D0F3 -:10AF4000012F20D00020A061E061206260622046D5 -:10AF50001830A060E87F40084000E877204606A946 -:10AF60008830FCF73FFE002805D0022803D0B44902 -:10AF7000B44810F0F0F825212846FCF77BFF0020AC -:10AF800071E6032008E020460D211B300FF0B6FFCC -:10AF900020461830A060042069460875E87F01212A -:10AFA0000843E87705AA29461798FEF7B7FDD5E7C5 -:10AFB000F0B587B015460F0004460DD0A248854273 -:10AFC00007D301208004854206D3A048006885424B -:10AFD00002D2102007B0F0BD2046FCF714FF060097 -:10AFE00004D03078272803D00820F3E79848F1E709 -:10AFF000B07F8007800F012807D000210022204663 -:10B0000000F092FE040007D101E00121F6E78D482F -:10B010008B491F3010F09FF80020002F05D0022F21 -:10B0200008D0012F11D00720D4E701216A46117101 -:10B03000A06018E0234618336946A3600871102207 -:10B04000294618460FF0FDFE0DE021461831A1609B -:10B0500069460871A061E0612062606206212846AD -:10B0600006F05CFEA0612078C10714D040084000C3 -:10B070002070022069460870204618300290703017 -:10B08000FCF7B0FD022806D0002804D06D486C49BA -:10B09000423010F060F825213046FCF7EBFE00202E -:10B0A00098E7F8B515460E460746FCF7ACFE0400D7 -:10B0B00004D02078222803D00820F8BD6448F8BDC9 -:10B0C000A07F8007800F022802D06148C01CF8BD15 -:10B0D0005D4886420ED3012189045C4A8E4202D328 -:10B0E00013689E4206D3854204D38D4204D3106870 -:10B0F000854201D21020F8BD00953288B31C21464C -:10B100003846FEF7B0FD112816D00028F3D1E17FB4 -:10B110002A7C4908D2074900D20F1143E1772A7CE3 -:10B1200049079206490FD20ED2001143E177A17F61 -:10B130004906490EA177F8BDA17F0907FBD4204637 -:10B140000822B11C34300FF07CFE30886086204627 -:10B150001022294622300FF074FEE07FFD210840C6 -:10B16000297CC907890F0843E077287C4108202003 -:10B170000155A07F08210843A0770020D7E770B5CC -:10B1800094B00D460646002B02D0072014B070BDC7 -:10B19000FCF739FE040007D02078222802D3A07FD4 -:10B1A000400603D40820F1E72948EFE7002D19D025 -:10B1B0002D216846017046801022294601A80FF013 -:10B1C00040FEE07F297C4008C9074000C90F0843C2 -:10B1D000E077297C40078906400FC90EC900084363 -:10B1E000E07703E02E2168460170468009A9684691 -:10B1F00000F0A3FCA17FBF221140A177C6E710B5E4 -:10B200000C46FCF700FE002805D0104909688C4266 -:10B2100003D2102010BD0E4810BD2146FEF7FEFCE3 -:10B22000002010BD05E00278401C002A01D000205B -:10B2300070470A46491E89B2002AF4D1012070479E -:10B240002C9E0000ED06000000C001002800002038 -:10B250000230000030B50346072903D00620DA7813 -:10B260001C7916E00320FAE707290BD05500ED18EA -:10B270006D79072D01D0401EC0B2521CD2B2092AEE -:10B2800007D105E05500ED186D79072DF3D0F4E7EF -:10B2900000222546641EE4B2002DE5D130BDFFB585 -:10B2A00081B00C461646114620460A9F0B9DFFF7BB -:10B2B000D1FF00280AD02079092803D3FEA1A020BD -:10B2C0000FF049FFA078C00907D019E0072E02D07F -:10B2D000112005B0F0BDFD48FBE701982880381D1E -:10B2E0006880002068712871EF80049828812846C2 -:10B2F00000F04BFC002803D1EFA1AD200FF02BFF95 -:10B30000E07821794018491CC0B22171092801D385 -:10B310000938C0B24000001946718179F12249080C -:10B320004900114081710020D3E7FFB583B0164674 -:10B330000F461C46002203210C9D039800F0F4FCEC -:10B34000010008D033463A46019500940398FFF770 -:10B35000A6FF07B0F0BDDD48801EFAE7F0B5054650 -:10B3600016460F4650888DB00022032100F0DCFC09 -:10B37000040003D1D0A1DF200FF0EDFE00206946CC -:10B380000871A078400603D1CBA1E3200FF0E3FEC3 -:10B39000042F5ED32A78D007C017401C06D16178ED -:10B3A0006B78994255D12178090752D00121142A8E -:10B3B00046DA012A42D0122A02D0132A40D128E0CC -:10B3C0000C2F3DD1A2785206520E012A38D0207897 -:10B3D00000090001401C20706878607068460171A7 -:10B3E00068792A790102114368460181E879AA79CE -:10B3F0000102114368464181687A2A7A01021143A9 -:10B4000068468181E87AAA7A010211436846C181BF -:10B410001AE0062F14D120780009000120707188ED -:10B42000012001F0EAF8022168460171C91E01817C -:10B4300068792A790102114368461FE0062F0AD075 -:10B440006A461279002A1BD07088324601A9FDF79E -:10B4500020FB0DB0F0BD207800090001207071883C -:10B46000012001F0CAF802216846017168792A7941 -:10B4700001021143684601810021C9434181E3E78C -:10B480000028E6D07488684681766978C176022102 -:10B4900081830021C18304A8052200900623114660 -:10B4A0002046FFF742FF0028D3D089A1D6200FF015 -:10B4B00052FECEE7F7B58CB015460C990D98FAF709 -:10B4C00041F9C0B2082850D10020694688856888B3 -:10B4D0000022032100F028FC040004D1FF2076A103 -:10B4E00063300FF038FE01230021E07822790BE071 -:10B4F0004600361976799E4201D1491CC9B2401CDA -:10B50000C0B2092800D100201646521ED2B2002E29 -:10B51000EED1002902D117206946888504AB023399 -:10B520000BAA00950C990D98F8F7B6FB0006000ED3 -:10B5300007D002281BD0032817D0FF205EA1893036 -:10B5400011E06846808D00280FD002A9019100907B -:10B550006888042301222146FFF7A1FE002804D0B9 -:10B56000FF2055A176300FF0F6FD0FB0F0BD6878E2 -:10B57000102108436870F8E700205A49024643004A -:10B58000401CCA520828FAD3704700218170017804 -:10B5900009090901017000214170C17001717047F2 -:10B5A00070B50D460022032100F0BEFB040004D15B -:10B5B000FF2041A1CF300FF0CEFDA0786906C00971 -:10B5C000C001490E0843A07070BD704710B5014618 -:10B5D000012001F012F810BD3EB58DB2002203210A -:10B5E000284600F0A1FB040004D1FF2032A1E43082 -:10B5F0000FF0B1FD2078694600090001207002209B -:10B60000087039488880C88000222846FDF741FA32 -:10B610003EBDF7B505460078002700090C463E46BA -:10B62000012804D0FF2024A1F3300FF094FD287AE4 -:10B6300003280CD0412020A1C0000FF08CFD0298FF -:10B64000002C068001D0278066800020FEBDEA899C -:10B65000702710460A3086B2002C0AD06888A08075 -:10B66000A8892081E28020460A3029690FF0E9FB91 -:10B67000E5E702980680E8E7F8B543680246D9791D -:10B680009C79090221435C7A1E7A25025C88981D08 -:10B690003543241FA14238D11B79022B35D1042D0B -:10B6A00034D0052D3DD0062D34D0402D2DD3061D90 -:10B6B0000F461446284619E07372635C6C3263616E -:10B6C000705F636F72652E6300000000043000003D -:10B6D0007372635C6C326361705F636F72652E635B -:10B6E00000000000680E0020FFFF000000F0E3F9FA -:10B6F00008280AD01120207003202072A581E7813C -:10B7000026616078082108436070F8BD001DFFF7CE -:10B71000D1FEF8BD031D50880A461946FEF771FE9A -:10B72000F8BD001DFFF71AFEF8BD70B50D468CB0D0 -:10B7300006460022032100F0F7FA040031D02078F9 -:10B740000007000F01282ED0122069468874607807 -:10B750000523801CC874082088822888C8826888CD -:10B760000883A8884883E888888302A90C2001916F -:10B7700000901A4621463046FFF791FD00280ED171 -:10B78000F02300223146012000F090FE20780009CD -:10B790000001401C20706078801C607000200CB09C -:10B7A00070BDCB48FBE71120F9E770B50D468CB0B2 -:10B7B00006460022032100F0B7FA040006D02078E4 -:10B7C0000007000F012803D00820E8E7C048E6E79B -:10B7D0001321684681746178C17402218182C58217 -:10B7E00002A906200523019100901A462146304601 -:10B7F000FFF755FD0028D2D1207800090001207004 -:10B800000020CCE7F3B581B00D460022032101985A -:10B8100000F08AFA00260446002803D1AD49AE485C -:10B820000FF099FC2079A8423BD2AB48A949401CB3 -:10B830000FF091FC35E0E07841000F19401C797958 -:10B84000C0B20091E070092801D10020E070207999 -:10B85000401E2071B879C00708D0009801990428CB -:10B8600015D09C49822018310FF075FCB87900077B -:10B87000410F08D0400F019904280CD095498F2022 -:10B8800018310FF068FC009807280AD107E0084635 -:10B89000FEF74CFEEAE70846FEF713FEF3E7761CD8 -:10B8A000F6B228466D1EEDB20028C4D13046FEBD6A -:10B8B00010B50022032100F037FA040004D1B520AE -:10B8C000844980000FF047FCE07821794018C0B22D -:10B8D000E070092801D30938E07000202071A078B9 -:10B8E00080210843A07010BDF8B517460D46002210 -:10B8F000032100F019FA040005D0002D0CD0002F10 -:10B9000007D0062006E0072D01D00620F8BD032051 -:10B91000F8BD0820A84204D86F486E4942300FF0A5 -:10B920001AFC29462046FFF795FC0646002F28D032 -:10B93000002E26D1E07821791CE0420012195379BB -:10B94000072B03D093791B075B0F04D0401CC0B2B8 -:10B9500009280CD00CE0400000198079F123184030 -:10B960006B071B0F1843907100290AD104E00020D7 -:10B97000491EC9B20029E0D1574856495A300FF044 -:10B98000EAFB3046F8BDF8B50D460022032100F071 -:10B99000CBF9040004D150484E4968300FF0DBFB6E -:10B9A000681E052804D34C484A4969300FF0D3FB80 -:10B9B0000921E2782079002310E0560036197779C2 -:10B9C000AF4206D1B17949084900B1715B1CDBB2C5 -:10B9D0001146521CD2B2092A00D100220646401E4E -:10B9E000C0B2002EE9D1092905D248000019817999 -:10B9F0000122114381711846F8BD10B50446402854 -:10BA000001D2072010BD00F056F8082802D03120DE -:10BA1000000210BD0021314802E0491C082903D270 -:10BA20004A00825A002AF8D1082903D0490044521A -:10BA3000002010BD042010BD10B5402801D2072001 -:10BA400010BD00F038F8082805D00021234A400036 -:10BA50001152084610BD052010BDF0B58BB016463A -:10BA60000C00074607D0002E05D06188402904D27B -:10BA700007200BB0F0BD1020FBE72088002801D084 -:10BA8000172801D90C20F4E7084600F014F808281C -:10BA90000FD0258803A82A46314602300FF0D1F98D -:10BAA00001A8009062882B4607213846FFF73DFC2D -:10BAB000DFE70520DDE701460020084A02E0401CE0 -:10BAC000082803D24300D35A8B42F8D170470000B4 -:10BAD00002300000B8B60000AD020000680E002081 -:10BAE00000B51E2827D00FDC0C2820D008DC03006E -:10BAF0000FF052FC0913211521211B1B17192100DE -:10BB0000122818D1072000BD302814DD3A38030070 -:10BB10000FF042FC030F11091100002000BD214865 -:10BB200000BD042000BD0D2000BD0F2000BD082079 -:10BB300000BD112000BD032000BD10B50C4604F06F -:10BB4000A0F800281ED0204602F013FE002816D0D0 -:10BB500022780E2A0DD00F2A0BD0022A09D0032AF0 -:10BB600007D0102A09D010A17E200FF0F4FA00208F -:10BB700010BDA078FFF7B4FF10BD112010BD0AA1C1 -:10BB80008420F2E708A18A20EFE710B502F0A2FCBA -:10BB900010BD10B502F0EDFD10BD10B502F01AFD9C -:10BBA00010BD0000023000007372635C686F737434 -:10BBB0005F6863692E630000F8B5054606ACC1CC2A -:10BBC000E44C21706270A370E070681C4208277119 -:10BBD0005200E14B66710021880000198446026220 -:10BBE000605C40008218002D0AD0002005E0664607 -:10BBF0004700366A401CF353C0B2665C8642F6D8F2 -:10BC0000491CC9B20629E7D30026D21C9708B00008 -:10BC1000BF0000198760304600F02AF9A15D761C4C -:10BC20004843C219F6B2062EEFD3501B80B2F8BDBE -:10BC3000F0B504468C46C7490020A500FF23024604 -:10BC40006D18C54E0C5D0BE02F6A5100795AB14258 -:10BC500004D1401CC0B2FF2B00D11346521CD2B2FB -:10BC60009442F1D8002801D061460B70F0BD70B548 -:10BC7000B84C0023655CA678B54200D10346890024 -:10BC800009199D420AD90C6A5E00A45B844202D164 -:10BC90001370012070BD5B1C9BB2F2E7002070BDE9 -:10BCA000FFB583B00C9C1F460D46060009D0002D41 -:10BCB00007D0F01C80088000B04204D0102007B0EC -:10BCC000F0BD0E20FBE70598A04201D8A74201D99C -:10BCD0000720F4E701460094019423463A460020E9 -:10BCE0000294FFF769FF2988814207D0814201D27F -:10BCF000042100E0092128800846E0E7009401942F -:10BD000023463A46029430460599FFF755FF2880AE -:10BD10000020D4E710B5044600F0B4F8002801D0A4 -:10BD2000E0B210BDFF2010BDF8B505468A481646A2 -:10BD30000C46854201D0062C01D30020F8BD002717 -:10BD400069460F7028466A462146FFF790FF002893 -:10BD50000DD068460178204600F09CF8002EEDD00A -:10BD60000028EBD12146284600F0A0F8F8BD38465F -:10BD7000002EF7D1F8BDF8B505460C460020764EEA -:10BD80006946764F0870B5423BD0062C01D3072098 -:10BD9000F8BD0A4621462846FFF769FF002830D043 -:10BDA00068460178204600F075F823000FF0F4FA99 -:10BDB000060404090C11161B01462846FEF742FA38 -:10BDC00015E0FDF735F812E001462846FFF7FDFBC8 -:10BDD0000DE001462846F7F7E4FE08E00146284654 -:10BDE000F9F73AFB03E05EA17C200FF0B4F9594A61 -:10BDF0006846A10000788918096A40000E520020A8 -:10BE0000F8BD3846F8BD5A4A1268914201D2102056 -:10BE10007047062801D30720704708720020487237 -:10BE20007047F8B5044652480068844201D2102099 -:10BE3000F8BD207A474A83009B18617A464D125C10 -:10BE400011E01E6A4F00F65BAE420AD04A1C6272D5 -:10BE50001A6A4B00D25A228000F01CF86060002061 -:10BE6000F8BD491CC9B28A42EBD861720520F8BD01 -:10BE70000EB5404B40000ECB0091029301926946F3 -:10BE8000085A0EBD33498978814201D90120704793 -:10BE90000020704770B50C460546FFF7E9FF2D4AB4 -:10BEA000A900891889686043401870BDF8B5044638 -:10BEB0000E4600206946087005462046FFF7E2FF5F -:10BEC000002803D126A1F3200FF045F92148214B8A -:10BED000815D8278B000C718914209D1E0B269460D -:10BEE0000870396A4000085A1B49884206D02EE083 -:10BEF00069463046FFF79CFE002828D06846007847 -:10BF0000396A40000C52684601783046FFF7C2FF9C -:10BF1000054633000FF040FA060404090C0F14170D -:10BF200029462046FEF760F911E0FCF75EFF0EE0BF -:10BF3000FFF72BFB0BE029462046F7F7F9FD06E05B -:10BF4000F9F783FA03E006A162200FF004F928460E -:10BF5000F8BD0000780E0020FFFF00000230000056 -:10BF60007372635C686F73745F636D2E63000000AF -:10BF70002800002028B401008107C90E002808DA33 -:10BF80000007000F08388008C24A80008018C06986 -:10BF900004E08008C04A800080180068C84000069D -:10BFA000800F7047BD4948788978884201D3401A8C -:10BFB00002E02122511A0818C0B27047B749233154 -:10BFC00048788978884201D3401A02E02122511A28 -:10BFD0000818C0B27047B14946314878897888421C -:10BFE00001D3401A02E02122511A0818C0B270474A -:10BFF000A94910B50C310868FF22120290430122B2 -:10C00000D20310430860A54900202331487088708E -:10C01000233948708870463148708870A04806F00F -:10C02000BCF89F48401C06F0B8F8F6F7A3FB00F0F8 -:10C0300028F910BD20207047B4E770B50C460546BE -:10C040000026FFF7AFFF9549A04214D30A46203AD5 -:10C0500000232046641EE4B200280BD08878105CD0 -:10C06000287088786D1C401CC0B288702128F0D1DF -:10C070008B70EEE7012600F004F9304670BD2020F9 -:10C0800070479BE770B50C4605460026FFF796FF04 -:10C0900082492331A04214D30A46203A0023204685 -:10C0A000641EE4B200280BD08878105C2870887871 -:10C0B0006D1C401CC0B288702128F0D18B70EEE757 -:10C0C000012600F0DEF8304670BD2021017000200E -:10C0D000704710B50446FFF77EFF2070002010BDAA -:10C0E00070B50C460546FFF776FF6C494631A04215 -:10C0F00015D30A46203A00232046641EE4B20028E5 -:10C100000BD08878105C287088786D1C401CC0B2F9 -:10C1100088702128F0D18B70EEE7002400E0614C9C -:10C1200000F0AFF8204670BD70B50C4605462129D9 -:10C1300004D9FF205CA147300FF00DF85548406846 -:10C14000103840B2FFF718FFC6B20D20FFF714FFFA -:10C15000C0B2864207D2FF2053A14D300EF0FBFF44 -:10C1600001E0F6F74AFB21462846FFF766FF002864 -:10C17000F7D070BDF8B507464948484C401E474EB9 -:10C180000078254646362335002806D1A9786878F8 -:10C19000212200F06BF800280ED0A17860782122CF -:10C1A00000F064F8002814D0B1787078212200F0F3 -:10C1B0005DF8002828D033E038496878C91C0F544E -:10C1C0006878401CC0B26870212829D100206870AE -:10C1D00026E03249607820390F546078401CC0B2A4 -:10C1E0006070212801D1002060702D4F7F1E3878AB -:10C1F000002815D0A1786078212200F037F80028B7 -:10C200000ED0002038700BE02449707826310F548E -:10C210007078401CC0B27070212801D1002070706D -:10C22000A9786878212200F021F800281DD0A17893 -:10C230006078212200F01AF8002816D0B1787078C2 -:10C24000212200F013F800280FD0F6F7B8FA1448AE -:10C2500005F0ABFF01214903884203D016A1C1209C -:10C260000EF079FF0E4805F0B8FFF8BD401C88427B -:10C2700005D0904201D1002901D000207047012053 -:10C28000704710B5064805F090FF002801D1F6F779 -:10C2900085FA10BD00ED00E000E400E0F00E0020A3 -:10C2A00069000020072000007372635C736F635F96 -:10C2B00072616E642E6300007372635C736F635F00 -:10C2C00072616E642E630000FEB5F54C074660682F -:10C2D000FF213E0181552178FF2913D00901083142 -:10C2E00041583246491E083209020192090A805813 -:10C2F00000F0CCF9002802D02478254615E06168CA -:10C30000207888552770FEBDE5484268019811588D -:10C31000280100900830105800F0B8F9002806D124 -:10C32000DF482C46416800980D5CFF2DECD1DC48BD -:10C330002101406885554754FEBD70B5D84A044672 -:10C340000020157A53680AE00201561C9E5DA64241 -:10C3500003D10C329A588A4204D0401CC0B28542A4 -:10C36000F2D8FF2070BDF8B5CD4F3E7801F00AFE3F -:10C370000146FF2E68D034012546786808354059BB -:10C3800000F084F9022802D9786840595AE0C4497B -:10C390004868025D0A70A11C425C002A0CD0521E43 -:10C3A000425441590122D20589180902090A415112 -:10C3B0003046FFF789FF30E0631CC25C0092221D0B -:10C3C00094468258002A10D001239B029A420FD92A -:10C3D0009205920D43595703DB191B021B0A435167 -:10C3E0006346C3589A1A920A09E0FF21C1540AE031 -:10C3F000435952039A181202120A4251002242541F -:10C400003046FFF761FFA6480C344168C2680098C7 -:10C4100009598000125800989047A14C2078FF28B5 -:10C4200012D001F0AFFD01462078626800010830AB -:10C43000105800F02BF9012896D920786168000186 -:10C440000830085801F091FDF8BDF8B51C461546B6 -:10C450000E460746FF2B03D392A1D3200EF07BFE9E -:10C460008F48FF21C7604560047206740170002286 -:10C470004270104604E00201521C401CA954C0B294 -:10C48000A042F8D3F8BD70B5854C06466578207C8F -:10C49000854203D383A1E6200EF05DFEE068A9008B -:10C4A00046506078401C6070284670BDFFB581B072 -:10C4B0001D46FF2401F066FD794F06467978019804 -:10C4C000814203D877A1F4200EF045FE7448002184 -:10C4D000037A406810E00A019446521C825CFF2AED -:10C4E00024D0019FBA4205D162460C328758029A85 -:10C4F00097421DD0491CC9B28B42ECD8FF2C17D0F3 -:10C5000021014B1C019AC2540B33029AC250039B67 -:10C51000634F0022012B0ED00B1DC25001239B0242 -:10C520009D4216D9AA05920D08D008E00C46E1E715 -:10C53000FF2005B0F0BD0B1DC550EFE71A465303B1 -:10C540009B190E461B0208361B0AAA1A8351920A2F -:10C5500009E0002D00D101256B039B191D022D0A56 -:10C560000B460833C550891C42543D463E78204650 -:10C57000FFF7AAFE2878B04217D001F003FD01466C -:10C5800028786A6800010830105800F07FF8012808 -:10C5900007D92878696800010830085801F0E5FCDF -:10C5A00003E001F010F9F5F7AFFE0198C1E770B5AF -:10C5B0000C46054601F0E6FC064621462846FFF7F4 -:10C5C000BCFEFF2817D0364D0401204669680830AC -:10C5D0000858314600F05AF80121090340186968EB -:10C5E000A41C095D400B002901D08902081800280D -:10C5F00000D1012070BD002070BDF3B581B00F46A1 -:10C600000198FFF79AFEFF282AD0254D2E786968F9 -:10C610003246344604E0844205D026462301CC5CF1 -:10C62000FF2CF8D11CE0FF2C1AD0A64221D110011A -:10C63000085C2870FF281AD001F0A4FC2A78014673 -:10C64000120168680832805800F020F8012809D9E2 -:10C650002878696800010830085801F086FC08E075 -:10C660000020FEBD01F0AFF8F5F74EFE01E001F04D -:10C6700084FC39460198FFF79AFF22016968FF237D -:10C68000541C0B558A5C3301CA54FEBD401A00028B -:10C690000121000AC905884200D900207047000026 -:10C6A0003C0F00207372635C736F635F74696D6528 -:10C6B000722E6300F0B500241C4A01211C4B0803B4 -:10C6C000546018601B4B1C601B4C20601B480469A5 -:10C6D000E443E406E617046910252C430461184C72 -:10C6E0006160184D2960761C00E020BF1F68002F94 -:10C6F000FBD0002E03D107691026B743076190686D -:10C700008005906801D5104A10436960A16000213E -:10C7100019600121084A09031160F0BD10B50446F3 -:10C72000FFF7C8FF2060002010BD000000C50040DA -:10C7300080E100E000C1004080E200E000ED00E0A8 -:10C7400000C3004000C0004000FCFFFF70B51F495F -:10C750000A68002A17D000231D4601244A68521C8B -:10C760004A60092A00D34D600E792246B2400E6815 -:10C7700016420AD072B60B6893430B6062B64968E2 -:10C780000160002070BD052070BD5B1C092BE5D346 -:10C790000FA136200EF0DFFCF5E7012010498005DF -:10C7A00008607047EFF31081CA07D20F72B60121FB -:10C7B00081400648036819430160002A00D162B62F -:10C7C000EBE70248002101604160704770000020E3 -:10C7D0007372635C736F635F6576742E6300000031 -:10C7E00000E200E001208107086070470120810716 -:10C7F000486070471048C068C00700D001207047EB -:10C800000D488068C00700D0012070470A48406981 -:10C81000C00700D0012070470748C069704706492B -:10C820008A69D20306D589698907890F814201D1B6 -:10C83000012070470020704700040040F8B5F74C15 -:10C84000207EE17D88421CD00126F54D0027E07D49 -:10C85000215C14200A4642435019037C052B11D059 -:10C86000037C062B1CD0037C072B28D0437C012B98 -:10C8700033D0ECA1EE480EF06EFC207EE17D8842C4 -:10C88000E5D1F8BD0674E07D162807D0E07D401C98 -:10C89000E075491CC8B2AA5802210CE00020F7E755 -:10C8A0000674E07D162808D0E07D401CE075491C28 -:10C8B000C8B2AA5803219047DFE70020F6E70674C4 -:10C8C000E07D162807D0E07D401CE075491CC8B209 -:10C8D000AA580821EFE70020F7E74774E07D162803 -:10C8E00007D0E07D401CE075491CC8B2AA5807215A -:10C8F000E1E70020F7E770B50024CE4E0C207072FF -:10C90000CD4825464473047328300476C475CB485B -:10C9100005F043FCCA480575F572CA49601E886077 -:10C920007571B570F57035717570C748E839057067 -:10C9300045701420604340180574641CE4B20B2C4D -:10C94000F7D30120F5F7E0FF0020F5F7DDFF012028 -:10C95000B071F5F7A3FCBD48F5F7B2FCBC4C2070F4 -:10C96000BC48F5F7ADFC6070F5F76EFF70BD10B513 -:10C97000F5F795FFB64C2078F5F7C0FC6078F5F731 -:10C98000BDFCAC4C207A002803D0F5F746FD002012 -:10C99000207210BD70B5A74CA079002804D0A1A1C9 -:10C9A000AD480EF0D8FB70BDE07A002803D19DA100 -:10C9B000AA480EF0D0FB0126A6710025E572607A28 -:10C9C000042114225043964A801801749D488168BE -:10C9D000491C04D0691E81600120F5F795FF0020F5 -:10C9E000F5F792FFF5F776FF05F018FDF6F777F803 -:10C9F0009B480560056001209A49C0030860F6F76E -:10CA0000EDF891480078022804D0032804D1E0789A -:10CA1000002801D0A67000E0A570F6F74CF870BDB4 -:10CA200003467F490B20142242435218203A127FBA -:10CA3000002A04D0401E0006000EF4D170471422D4 -:10CA4000424351180A46803AD366012220390A77B8 -:10CA50007047012805D0032805D1002903D1002003 -:10CA600070470029FBD010B4724C00236370764AE3 -:10CA7000002890700CD002280AD007291AD208008A -:10CA800078440079001887441505070D0F1113002D -:10CA9000D37003E01B2000E03A20D07001206070CA -:10CAA00010BC70475820F8E77720F6E79620F4E7A7 -:10CAB000B520F2E710BC0020704710B562484078FE -:10CAC000F6F714F880B210BD411E1422504310B581 -:10CAD000534A8418203C0A2902D8207F002803D119 -:10CAE00050A161480EF037FB207F012804D0B3200D -:10CAF0004CA180000EF02FFB0020207710BD70B5F8 -:10CB00004D4C607B217B884201D1012500E000254E -:10CB1000F5F785FFF5F7EAFF617B227B914201D1B2 -:10CB2000012100E00021A942EBD170BDF7B5064616 -:10CB3000481E84468EB0C0B2142205905043384A35 -:10CB400085180495287C2D1D07282AD1334C0027F1 -:10CB5000E07D227E824221D0235C059A934201D15E -:10CB6000012701E0002F04D0162811D0421CA25C3E -:10CB7000225416280ED0401C227EC0B28242EBD135 -:10CB8000002F0BD0207E002806D0207E401E04E01F -:10CB90000022ECE70020EFE716202076049801221F -:10CBA00002746046234C0A2813D8142041431C48C1 -:10CBB00008182038007F00280BD00498007C01283A -:10CBC0000BD00498007C012803D01098807A0128AB -:10CBD00007D014A125480EF0BEFA1098807A0128DB -:10CBE0006DD104980E4B007C022843D00B4C207E64 -:10CBF000162870D0207EE17D401C884203D109A117 -:10CC00001B480EF0A8FA049901204874217E05986B -:10CC10006054207E162862D063E0000038110020A6 -:10CC2000541100207372635C72656D2E6300000006 -:10CC3000D40500005C1200201011002068120020B2 -:10CC4000201100203C1200207A00002067C3000061 -:10CC5000780000203DC800007D0200005E02000058 -:10CC600000F5004080E200E0CB0200001503000068 -:10CC700022030000607A059A0146904206D00146E0 -:10CC800014277843C018807C9042F8D1627A82429F -:10CC900008D1617A14225143C918897C617201213B -:10CCA000A17207E014224243D21814277943927CE0 -:10CCB000C9188A7414220C215043C018817410982A -:10CCC000007A06281DD201007944097949188F4459 -:10CCD0000C161412100EE07D002890D093E700206F -:10CCE00001E0207E401C2076B5E000210FE0B42159 -:10CCF0000DE073210BE0322109E00A2107E0062153 -:10CD000005E0FF20FDA1E0300EF025FA002110988B -:10CD100002910068401A28601099097A002912D0FF -:10CD20000221401A0102090A29601098026840682D -:10CD300010180002000A68601098807A0228109883 -:10CD400003D0007B71E00421EBE7007A002812D0C9 -:10CD500002220298121810984368104610301818D2 -:10CD60000A90E948029B4078984202D9E378002B68 -:10CD700003D00A9805E00422EBE7029BC31A0A9845 -:10CD80001818637A10300C2B1CD0637A14277B435D -:10CD9000DE4FDB195B68994214D0DD4F617ABC46E7 -:10CDA00014235943D94BC9184B6889689B1B891BAD -:10CDB0001B0209021B0A090A984237D8634535D875 -:10CDC000614533D831180A980123081A0002000A75 -:10CDD000286010998018C9680002000A471ACD4AD5 -:10CDE0009B05BC469F4201D2384610E00F1A9F4275 -:10CDF00001D260460BE0944503D9511A0818401C33 -:10CE000005E0974206D9101A4018401C40420028FD -:10CE10005FDC03E0B9A1C0480EF09DF929680A98CB -:10CE200008180002000A686000202872686810274D -:10CE300010300002000A68601098407AA8721098BA -:10CE4000007A687203280ED200280CD0FFF7D2FCBB -:10CE5000002803D007E0002011B0F0BD0298422165 -:10CE60000F1A32200290A8490878012801D003281F -:10CE700009D148780299884205D9E178002902D180 -:10CE80000299401AC7196B6828689B1B801B9C4637 -:10CE900001021B029E4A090A1B0A8F4219D8174633 -:10CEA000914216D8BB4214D8617A0C2915D0677A02 -:10CEB00061460C22039200921422944B7A43D218BA -:10CEC00093689B1B834216D80397977C0C2FF3D152 -:10CED00073E0059801F04CF9BDE70498022205992A -:10CEE0000274627A0C2A00D0627A82746172012024 -:10CEF000A07211B0F0BD0C2F5FD0002238469446CE -:10CF00001422824B4243D21853689B1B8B4225D27A -:10CF1000907BAB7A98421BD804980521059D01743B -:10CF20007E4C207E16280FD0207EE17D401C88425A -:10CF300003D172A17A480EF00EF9207E2554207E8E -:10CF4000162800D0CDE6CAE6E07D0028F1D0F4E74F -:10CF500001208446907C0C28D2D102E06146002951 -:10CF60002AD03D46009014202A46424367480621B5 -:10CF7000161831741C38007E1628684816D0017EB9 -:10CF8000C07D491C814203D15CA166480EF0E3F8E4 -:10CF90006248017E4554017E16290BD0017E491C52 -:10CFA0000176B57C0098A842DDD106E0C07D00285E -:10CFB000EAD0EDE70021F3E7009704990220534DF2 -:10CFC0000874607AB84207D104990098887405986B -:10CFD00060720120A07221E003980C2F0FD00C2862 -:10CFE00003D146A150480EF0B6F8039814225043DE -:10CFF0004019059981740499009888740EE00C28F2 -:10D0000003D13EA149480EF0A6F8039814225043DC -:10D0100040190599817404990C208874012011B07D -:10D02000F0BD70B50D46424A441900210B46101A56 -:10D030008B4103D231A13F480EF08DF83E48854226 -:10D0400003DD2EA13D480EF086F83D48854203DA07 -:10D050002AA13C480EF07FF83B48844205DA002CB8 -:10D0600001DB204670BD384800E03848201870BD0C -:10D07000401E70B5C0B21421484324494418607B57 -:10D08000062813D201007944097949188F44020C0B -:10D090000A080604002067E0B42010E073200EE0C8 -:10D0A00032200CE00A200AE0062008E0FF2013A14D -:10D0B000E0300EF050F8617B0020002954D00221AE -:10D0C0004018616840180002000AF5F70FFD0C25B2 -:10D0D0006557174A441900210B46101A8B4103D299 -:10D0E00006A114480EF037F81348854203DD03A16A -:10D0F00012480EF030F81248854229E07372635CE2 -:10D1000072656D2E630000007A000020541100202B -:10D11000FFFF3F00FFFFFF00130700003811002052 -:10D1200007020000C5030000DD030000E303000068 -:10D13000FF7F841EF50300000020A107F603000016 -:10D1400000E05EF8F70300000080841E00807BE1B1 -:10D1500003DAF749F7480DF0FEFFF748844207DA93 -:10D16000002C03DB204670BD0421A9E7F24800E053 -:10D17000F248201870BDF0B5064683B0F048019023 -:10D18000457A029534687068001B0702ED483F0A33 -:10D19000001B00900C2D2DD0142029464143EA4855 -:10D1A0000122081884464168E64892058646081B15 -:10D1B000904210D3631A93420DD3024670467245D3 -:10D1C00003D900984018401C05E073450ED9411A58 -:10D1D0000819401C404200280CDA60460295857C04 -:10D1E0000198C0790028D5D003B0F0BDD049D74808 -:10D1F0000DF0B1FF0298854226D014214843D24950 -:10D200000123401802908068CE499B058C46011B83 -:10D210008646994210D3221A9A420DD3634661453D -:10D2200003D900997144491C06E0194662452DD97D -:10D23000091A0819401C4142002905DD0298B17AFB -:10D24000807B814200D374460C2D15D0BE4914203A -:10D25000454368184268121B1202120ABA420BD2E6 -:10D26000B37A827B934200D38468857C0198C0792D -:10D270000028B9D10C2DEAD13068A042B4D0E01911 -:10D280000002000A3460706003B0F0BDA849AF48E6 -:10D290000DF061FFD8E7F0B5AD490446486885B0A8 -:10D2A000C005C00D1CD0103840B200280CDA0207AF -:10D2B000120F083A920892005118C9698007C00EEF -:10D2C000C1400806800F09E08108A24A8900891838 -:10D2D00009688007C00EC1400806800F002808D0EA -:10D2E00000272078002806D0012804D0002005B0AF -:10D2F000F0BD0127F5E72079062813D20100794413 -:10D30000097949188F44020C0A080604002018E025 -:10D31000B42010E073200EE032200CE00A200AE076 -:10D32000062008E0FF208249E0300DF014FF21794B -:10D330000020002905D002214618814D002F02D07F -:10D3400003E00421F8E70020E871694602AAA0681A -:10D35000F5F7D6FB694608228A56E06801A98018CD -:10D360000122C01C1F2801DA019209E003AAF5F787 -:10D37000C7FB6846007B002802D00198401C019042 -:10D3800000990198401810300002000A0190881B93 -:10D390000002000A00906079694688720098039044 -:10D3A000F5F73DFB009A019B121A181A6A491202FE -:10D3B0000002120A000A8A4216D8884214D8684627 -:10D3C000FFF7D9FE00990398814205D08819000221 -:10D3D000000AF5F78BFBA0600120E979002986D0CF -:10D3E000002FB0D005B0F0BD0020F6E7F3B58FB048 -:10D3F0005A480C460B9004F0D8FE594A0F99504FEA -:10D400005618584D203E00280BD05748007D002864 -:10D4100003D056A158480DF09EFE207801287CD0FC -:10D420005AE1687B16280CD0687B297B401C884217 -:10D4300003D14EA151480DF08EFE2078012804D072 -:10D440000CE0287B0028F4D0F7E7F07F002803D019 -:10D4500046A14B480DF07FFE0120F077697B0F98C5 -:10D460001422484E5143891908742078022822D08A -:10D47000687B142148438619207930726079707274 -:10D4800032460C323146A068F5F73AFB0C20305694 -:10D490000F2804DD1F3830733068401C30600C21C9 -:10D4A0007156301DE26801905018C01C1F283EDAEA -:10D4B00001200199F7E026494868C005C00D21D038 -:10D4C000103840B200280CDA0207120F083A92080E -:10D4D00092005118C9698007C00EC1400806800F2C -:10D4E00009E081081B4A8900891809688007C00E75 -:10D4F000C1400806800F002804D105201BA10002AE -:10D500000DF029FE687B1421484386190021E0684C -:10D510006A460691117006A900E0D3E0F5F7F0FA2B -:10D520006A46002010560F282EDD01202DE0AEE0C7 -:10D53000FCD00000F70300000080841E00807BE127 -:10D540005C120020FFFFFF005411002013070000B1 -:10D5500000ED00E000E400E0FFFF3F006812002063 -:10D560003012002010110020201100207372635C23 -:10D5700072656D2E6300000011050000EF040000CD -:10D58000F4040000500F0020002006994018079076 -:10D590000220B0722079307260797072A068311DFB -:10D5A000C01C06911F2801DA012009E0F5F7A8FA4E -:10D5B00068460078002804D0069806990068401C48 -:10D5C0000860307A062813D2010079440979491895 -:10D5D0008F44020C0A08060400200FE0B4200DE07E -:10D5E00073200BE0322009E00A2007E0062005E066 -:10D5F000FF20FE49E0300DF0AEFD0020217900292A -:10D6000043D002214018069071681030081807991D -:10D61000089009180698081A0C900020F871F5F780 -:10D62000FEF904463060079820180002000AF060F6 -:10D63000787A0C2825D0797A14204143EC480818D0 -:10D6400040680899029040180002000A0390707A1E -:10D650006946887402A8FFF78EFD0299039A091B98 -:10D66000121B09021202E34B090A120A0C98994292 -:10D6700007D8824205D80299069808180002000AC5 -:10D680003060F8790028C8D110E00421BAE704AA74 -:10D690000199F5F735FA6846007C002804D0019816 -:10D6A00001990068401C08602078B072687B1628D9 -:10D6B00006D0687B401C68730B9804F08EFD47E031 -:10D6C0000020F8E7F07F002804D0A320CAA1C00002 -:10D6D0000DF041FD0120F077CA490F9808742078B9 -:10D6E000022803D1C4A1C8480DF035FDC54E2079EC -:10D6F00030726079707232460C323146A068F5F7AC -:10D70000FFF90C2030560F2804DD1F3830733068C5 -:10D71000401C30600C22B256301DE1680190881820 -:10D72000C01C1F2802DA012001990BE003AA01990D -:10D73000F5F7E6F96846007B002804D001980199C6 -:10D740000068401C08602078B072AE49012008755E -:10D75000687B297B884224D07C7A0C2C23D0F5F777 -:10D760005EF914214C43A24961180A7C042A18D09E -:10D770000A7C032A15D04B6889681B1A081A1B02F9 -:10D7800000029C4A1B0A000A102B0AD3114693423E -:10D7900007D8884205D8687B297B884201D0F5F7F5 -:10D7A0008AF911B0F0BD687B297B8842F7D111B0AE -:10D7B000F0BD10B50020F5F794F810BD10B50120AC -:10D7C000F5F78FF810BD914800787047F1B50098D3 -:10D7D00002281ED08E4C607A0C2803D186A18D4879 -:10D7E0000DF0B9FC0026A6710125E572607A0321CF -:10D7F00014227F4F5043C0190174F5F761F9009866 -:10D8000000280BD001282AD003287AD07AA1824898 -:10D8100045E07E480078F4F777FDF8BD7F48007F4B -:10D82000002804D02B2074A140010DF094FC6571F8 -:10D830007A4D00202E60F5F767F8A968481C04D0DF -:10D84000012300221846F5F795F8607A617A401CAA -:10D85000C0B2142251437A5801219047F8BD0120EB -:10D86000F5F752F8607900280DD06C488068401CAC -:10D8700009D0607A617A401CC0B2142251437A58B0 -:10D8800006219047F8BD6548007F01280AD002288C -:10D8900012D0032822D0042834D057A160480DF0BC -:10D8A0005AFCF8BD2079002803D02671F5F70DF950 -:10D8B000E5705A480677F8BD207A002802D1F4F7BF -:10D8C00083FD2572607A617A401CC0B214225143F4 -:10D8D0007A580021904751480677F8BD4F4F0123F1 -:10D8E000397B78680022411A1846F5F743F8207909 -:10D8F000002803D02671F5F7E8F8E57002203877A4 -:10D90000F8BD19E0454E217870680123411A0022C4 -:10D910001846F5F72FF8207A002802D1F4F754FDC5 -:10D920002572607A617A401CC0B2142251437A5841 -:10D93000002190473577F8BD607A617A401CC0B20B -:10D94000142251437A5805219047F8BD10B5304C48 -:10D95000607A0C2803D128A132480DF0FCFB607AD4 -:10D96000617A401CC0B214225143214A525804210A -:10D97000904710BDF0B583B00C200290F5F74FF83A -:10D98000234C0090617A284801900C2920D0617ABC -:10D990001420414316480918097C042918D0617ADB -:10D9A000142251430818007C032879D0019900986B -:10D9B0000B6849681B1A081A1B0200020D4A1B0A51 -:10D9C000000A102B6CD31146934269D8884267D85D -:10D9D00012488068401C03D007A114480DF0BBFB1F -:10D9E00000206071607A0C282AD121E0FCD0000070 -:10D9F00054110020FFFF3F007372635C72656D2E4F -:10DA000063000000201100201E05000078000020A7 -:10DA10005C12002054050000A70500003C12002005 -:10DA20009B050000AE0500004C120020EA05000036 -:10DA30006078002804D0FE48C17841708178017078 -:10DA4000607A0C2815D0607A1421FA4A484380186D -:10DA5000007C04280DD1607A0290607A01211423A1 -:10DA6000584380180174607A58438018807C607233 -:10DA7000A172F14D687B297BF04F884233D0F04E84 -:10DA8000287B142148438019007CC05D0128287B35 -:10DA900007D048438019007CC05D02282FD044E0A5 -:10DAA000FCE1142148438019807A01280AD0287BA0 -:10DAB0000221142250438019007CC155287B16286E -:10DAC00008D009E0287B0021142250438019007CF3 -:10DAD000C1552AE0002001E0287B401C2873687BA8 -:10DAE000297B8842CCD1D74D287D00284DD0287C79 -:10DAF000C15D012928D0C05D022830D03BE0287BE1 -:10DB0000142148438019807A012803D0CEA1D1483E -:10DB10000DF021FB297B00201422514389198872C2 -:10DB2000297B51438919097CC855287B1421484316 -:10DB30008219287B48438019017C0098FEF7F6FF84 -:10DB4000287B1628C8D1C5E7A97A012904D002216B -:10DB5000C155002028750EE00021C1550BE0A87AC0 -:10DB6000012804D0C520B8A1C0000DF0F4FA0020AF -:10DB7000A872297CC855287D002806D0297CB14A86 -:10DB80000098FEF7D3FF0020287502980C281ED0BD -:10DB900014214843A7494018017C012917D10721C6 -:10DBA0000174AD4D287E16283CD0287EE97D401CAE -:10DBB000884203D1A4A1A9480DF0CDFA297E02988C -:10DBC0006854287E162831D0287E401C2876607A3A -:10DBD0000C287DD0A07A00287BD00020A072617A2A -:10DBE0001420414393480E189D49B56873680A464E -:10DBF000F6687C32CB67966055609A4D697E002945 -:10DC000016D00226617A14228A4851430818407BB4 -:10DC100006281BD201007944097949188F440A1457 -:10DC200012100E0CE87D0028C4D0C7E70020CDE715 -:10DC30000426E7E700210FE0B4210DE073210BE09B -:10DC4000322109E00A2107E0062105E0FF2086498C -:10DC5000E0300DF080FA00212973687E022801D09F -:10DC6000012810D12869009A4018821A1202120A5B -:10DC7000422A08D93238032100026976000A286155 -:10DC80003220287308E0322906D2207A00280AD1EF -:10DC9000F4F79AFB012005E0207A002803D0F4F77E -:10DCA000BCFB00202072624910224878207009785D -:10DCB000012901D0032906D101212171297B884244 -:10DCC00001D9421A1032A378002B00D0921C01E037 -:10DCD0008DE09BE02179002901D1002B5DD0944695 -:10DCE000624A00990092019A176852687F1A511A85 -:10DCF0003F0209023F0A090ABC451BD85B4A97420A -:10DD000018D8009A914215D8297B884223D92B69CB -:10DD1000421A9A1A1202120A101880190002000AF6 -:10DD20002A616860002914D0032028770006000EBD -:10DD30003ED14CE000202071A070297B002925D025 -:10DD40002869401880190002000A686002202877BC -:10DD50002EE00120E9E781420BD92A69511889197F -:10DD60000902090A6960002801D00420DDE70220C9 -:10DD7000DBE7002B03D134A13D480DF0ECF9286915 -:10DD800080190002000A6860002004E029698919EE -:10DD90000902090A6960287719E0287B00280FD05A -:10DDA0002969081880190002000A68600220287793 -:10DDB00028690123811900221846F4F7DBFD09E0E8 -:10DDC000286980190002000A686000202877012075 -:10DDD000F4F79AFD607A1421484316490C22401842 -:10DDE0008256012300206968F4F7C4FD0EE001208B -:10DDF000F4F78AFD0020F4F787FDF4F76BFD207A35 -:10DE0000002803D0F4F709FB00202072A078002836 -:10DE100004D0F4F75AFE0020E070A070607800286B -:10DE200004D00348C178417081780170207921E0E5 -:10DE30007A00002054110020101100202F12002021 -:10DE4000500F0020201100207372635C72656D2EEC -:10DE5000630000000C060000381100203A060000A4 -:10DE6000D01100203C120020FCD00000FFFF3F003A -:10DE70008C060000002806D00020CF49E070097809 -:10DE8000002900D12071CD48017EC07D814203D0A0 -:10DE9000CB484078F4F738FA0120E07103B0F0BDC8 -:10DEA000F0B5C84C0746607A83B00C2803D1C6A1F0 -:10DEB000C8480DF050F9607A1421C74E48438019C4 -:10DEC000007C032804D06F20BFA100010DF043F9AE -:10DED000C24DA868401C03D0BBA1C1480DF03BF95E -:10DEE000607A1421484381190C20085600216A46A3 -:10DEF00000911171C01901AA6946F4F701FE6A4642 -:10DF0000042010560F2801DD012000E000200099B8 -:10DF10004018696840180102090AA9606079002860 -:10DF200004D0012300221846F4F724FD03B0F0BD0D -:10DF300070B5AD4CAB4A0B1AA34214D3451AA54297 -:10DF400011D3934203D9101A43185B1C0BE095427E -:10DF500004D9511A0818401C434204E0A349A448BC -:10DF60000DF0F9F80023184670BD10B501460123E5 -:10DF700000220220F4F7FEFC10BD10B50220F4F7D9 -:10DF8000C3FC10BD10B5F4F74AFD10BDF0B58D4DC2 -:10DF90000446E87A83B0002803D18BA195480DF0A0 -:10DFA000DAF8642C4DD3944900200246091B8241C3 -:10DFB00047D39248417B007B814242D19048007D0B -:10DFC00000283ED1687A1421834F4843834EC519F7 -:10DFD000306801AA00196946F4F792FD69460420E9 -:10DFE0000856002802DD0098401C0090A96800989F -:10DFF0006B680A18D21A1202824B120A9A4220D86F -:10E00000AA7C0C2A08D014235A43D2195268511AF8 -:10E010000902090A814214D3B068401C05D00120CE -:10E02000F4F772FC0020C043B06030680019306023 -:10E03000A868009940180002000A7061012003B02E -:10E04000F0BD002003B0F0BDF8B50646401EC5B2D5 -:10E050001420614968434418207C002803D15AA148 -:10E0600069480DF078F86548017B407B81420CD00F -:10E07000664A14234B439B181B7CB3420CD01629D1 -:10E080000CD0491CC9B28142F3D15D48017D002901 -:10E0900064D0007CB04261D10020F8BD0021F1E7DE -:10E0A000217C052905D0217C062902D0217C072965 -:10E0B00028D101212174C17D0023027E8A4221D012 -:10E0C0000246565CAE4201D1012301E0002B04D090 -:10E0D000162911D04E1C965D565416290ED0491C97 -:10E0E000167EC9B28E42ECD1002B0BD0117E0029D6 -:10E0F00006D0117E491E04E00026ECE70021EFE780 -:10E1000016211176617C00292AD06774C17D002315 -:10E11000027E8A4224D0425CAA4201D1012301E05E -:10E12000002B04D0162912D04A1C825C42541629B6 -:10E130000FD0491C027EC9B28A42ECD1002B0FD00D -:10E14000027E0146002A06D00A7E521E04E000220A -:10E15000EBE70021EEE716220A7601E017480027D8 -:10E16000217C01299CD1617C002999D10120F8BD35 -:10E1700070B505461420184A0521684380180174BB -:10E180000E4C207E162811D0207EE17D401C884256 -:10E1900003D116491E480CF0DEFF207E2554207E58 -:10E1A000162807D0207E401C207670BDE07D002818 -:10E1B000EFD0F2E70020F7E77A00002038110020C6 -:10E1C000780000205C1200207372635C72656D2E13 -:10E1D00063000000EF060000541100203C120020F4 -:10E1E000F1060000FF7F841E0020A107FCD0000084 -:10E1F0001307000032070000FF1FA10710110020C5 -:10E2000020110020FFFF3F006F070000500F00208B -:10E210000702000010B509F063FC042803D009F0E0 -:10E220005FFC052803D106F0D1FE00280BD104F0D5 -:10E2300007F9032803D004F009F9032805D109F0F0 -:10E24000B0FD002801D0012010BD002010BDF0B5A8 -:10E2500085B00746002668460D4606726946384670 -:10E2600005F05CFA00287DD16846007800280BD0C4 -:10E2700009F009FDB84275D00022294638460AF057 -:10E28000CCFE00283ED120E006F077FCB842F2D068 -:10E2900000222946384608F01DF900287DD1019C4E -:10E2A0009020005D2834002804D1607E002801D031 -:10E2B000012000E000200490204660300390807828 -:10E2C00006F08AFB002804D008E0019C2834607E18 -:10E2D000F1E7FF20FDA1DA300CF03DFF20462030B1 -:10E2E000417B00290FD0817B89070CD56E700121FD -:10E2F0002970AE70AF80C17BA971218E2981618E9A -:10E300006981467349E0039802A9807806F030FAE3 -:10E31000002804D1FF20EDA1EE300CF01CFF684670 -:10E32000007A002809D06E700D202870AF806846F2 -:10E33000007AE8800120A8702FE0049800282FD0F0 -:10E3400006F0B5FB00282BD068460078002806D1DF -:10E3500001988030406A4188B94200D10670039824 -:10E36000807800E01CE006F0CAF8002803D1D7A1AD -:10E37000DA480CF0F0FE6E700A202870AE70AF80A4 -:10E38000A07EA8716676684605F07EFA002804D063 -:10E39000D248CEA10E300CF0DEFE012005B0F0BD5B -:10E3A0000020FBE77CB5CEA103C9CF4D002401912D -:10E3B0000090AC7001F067FD2946EC7004204039F4 -:10E3C000088710204887C81DC84AF9304280047168 -:10E3D000C280E03844740C7084730475C0300477D4 -:10E3E0001D300522694604460CF02BFD28462146C7 -:10E3F000BC3008F0F7F97CBDF8B5BD4C0D46606047 -:10E40000217006F057F805F0D1F8FFF7CBFF207820 -:10E4100009F03AF9B4498431084681380F46064676 -:10E4200006F08CFC606808F0D8F8284604F06EFC12 -:10E430003946304609F057FC60680AF08AFE01F060 -:10E4400022FDA9480021C170F8BDFEB50E461D464B -:10E45000144601A905F062F9002839D102988030EC -:10E46000807A06F079F800280CD0684606F087F824 -:10E47000002806D0002C03D006F01DF8A04206D2DA -:10E480000020FEBD91A19B480CF065FEF8E70098C6 -:10E4900005F0AAFB3146009805F0ABFBE2B2294635 -:10E4A000009805F063FD06F08FF8002804D191482C -:10E4B00086A11E300CF04FFE68460079012807D176 -:10E4C00001A801F0E7FC8A48002180688030418281 -:10E4D0000120FEBD30B40179002904D0012907D004 -:10E4E00030BC00207047831D42880488022103E06D -:10E4F00042880488831D0121204630BCA5E7FFB572 -:10E50000794C85B00E460746C0346088694608805D -:10E51000154602A905F002F9002811D0002168462D -:10E5200005F059F9002823D1684602A9008805F0B2 -:10E53000F5F8002804D06F4864A13C300CF00BFEC5 -:10E5400068460088388068460088608066480021F8 -:10E55000C23005F040F9002802D00020C04360809E -:10E5600003988030807A06F037FA002803D007E05D -:10E57000002009B0F0BD5F4854A156300CF0EBFD0F -:10E5800004A806F03CFA0028F3D0049805F068FBD4 -:10E590003070022807D0012805D056484BA17230B0 -:10E5A0000CF0D9FDE4E70899049805F0F6FC288002 -:10E5B000002804D14F4845A165300CF0CCFD06F091 -:10E5C00045FA002804D1E92040A180000CF0C3FDE9 -:10E5D0000120CEE73EB50446831D02AA694601A884 -:10E5E000FFF78DFF002813D068468088208068469A -:10E5F000008960800020607168460078012808D09A -:10E60000022806D03B4831A192380CF0A4FD01202D -:10E610003EBD2071FBE7FEB5040004D135482BA1B7 -:10E620007E380CF098FD304D0026203D687C002897 -:10E6300008D0667010202070A87CA070E87CE07084 -:10E640006E7430E0284F403F3878002808D02C22E4 -:10E65000B91C20460CF0F5FB0E2020703E7022E025 -:10E66000A87B002809D00120E070E87BA070287CFE -:10E6700060700F202070AE7315E01B480221C63079 -:10E68000029005F0A8F8002871D1174FC037F8881C -:10E690000190F888042808D0052831D02146FFF7DA -:10E6A000D6FD002859D00120FEBD0021204606F0ED -:10E6B00019FA0028F7D1287D00284ED06670132063 -:10E6C00020701C21A01C0CF019FC15E07372635C17 -:10E6D0006C6C5F6374726C2E630000000D020000AE -:10E6E000FFFFFFFF1F000000AC120020FFFF000033 -:10E6F00080000020390300000220A0702E75D2E7B0 -:10E700000021204609F098FA002826D02078132806 -:10E71000C9D1A0783C28C6D1A088694604F07CFF06 -:10E72000002803D0FD49FE480CF015FD009880300C -:10E73000807A05F0E4FE002804D1F948F749001D6D -:10E740000CF009FD009804F09FFF0028ABD0F448BE -:10E75000F24908300CF0FFFCA5E70221029805F011 -:10E760003AF8002803D1F9880198814291D100201C -:10E77000FEBD50E710B508F011FF002804D0E848AE -:10E78000E649BE300CF0E7FC07F01FFF06F09AFAEE -:10E7900004F07AFA002804D07920E049C0000CF097 -:10E7A000DAFC0AF0CEFC002804D03D20DB49000151 -:10E7B0000CF0D1FC09F070FA002804D0F520D749FC -:10E7C00080000CF0C8FCFFF7EDFD04F0ABFE002864 -:10E7D00004D0F720D14980000CF0BDFC05F01CFEF0 -:10E7E00001F051FBCF480021C17040380171012177 -:10E7F00041710222C270017010BD10B5C94C403C7D -:10E800002078002804D00A210E2001F002FB10BD60 -:10E81000FFF700FD002801D00C2002E001F033FBDF -:10E8200000202071012060710A21E170207010BD6C -:10E8300070B5BC4C0646403C2078002804D03A21F4 -:10E840000E2001F0E6FA70BDFFF7E4FC002801D0CD -:10E850000C2010E0B34DE87808280BD20001001915 -:10E8600010223146443001F0DEFAE878401CE870AE -:10E87000002000E007202071012060713A21E17042 -:10E88000207070BD70B5A74C0646403C207800282B -:10E8900004D00B210E2001F0BCFA70BD30780028A6 -:10E8A00003D0012801D0122015E09E4D8035287933 -:10E8B000082817D2FFF7AEFC002801D00C200AE090 -:10E8C000984833782979721C883001F098FB2879B0 -:10E8D000401C287100202071012060710B21E17023 -:10E8E000207070BD0720F6E710B58E4C403C2078B4 -:10E8F000002804D039210E2001F08BFA10BDFFF75B -:10E9000089FC002801D00C2002E086490020C87054 -:10E910002071012060713921E170207010BD8148A3 -:10E9200010B540380178002904D00F210E2001F0E5 -:10E9300070FA10BD002101710E2181700F21C1708C -:10E94000FF2181710021C9430181774949680A7813 -:10E9500082728A8882814988C18101214171017056 -:10E9600010BD704910B540390A78002A04D03C2106 -:10E970000E2001F04EFA10BD6A4A0088C032508065 -:10E980000120107100220A7148713C22CA7008707F -:10E9900010BD10B5634C403C2078002804D02B21DA -:10E9A0000E2001F036FA10BD0821A01DFDF7BCFBBA -:10E9B00000202071012060712B21E170207010BDBA -:10E9C00010B5584C403C2078002804D005210E207A -:10E9D00001F01FFA10BD05F06EFDE08005F0C6FEE7 -:10E9E000207200202071012060710521E1702070EB -:10E9F00010BD10B54B4C403C2178002904D031218A -:10EA00000E2001F006FA10BD00214156042911D054 -:10EA100000290FD0081D0DD0001D0BD0001D09D0FE -:10EA2000001D07D0001D05D00A3003D00A3001D0E8 -:10EA3000122003E0084601F033FB00202071312052 -:10EA4000E07001206071207010BD30B5354D044676 -:10EA5000403D28788DB0002805D02A210E2001F0F5 -:10EA6000D8F90DB030BD10222146684601F0DBF91F -:10EA70001022A11804A801F0D6F9684603F00BFC97 -:10EA800010222C46A81D08A901F0CDF90020207104 -:10EA90000E20A0702A20E070012060712070E0E755 -:10EAA000F0B5204C85B0403C2078002804D03B21B4 -:10EAB0000E2001F0AEF971E40020A07119486946FA -:10EAC000C0304088888002A904F028FE002805D0C4 -:10EAD000002101A804F07FFE002865D16846114D91 -:10EAE00081880180283D684602A9008804F016FE4E -:10EAF000002803D009490D480CF02DFB039E04A902 -:10EB000037468837B878283605F04BFE002804D100 -:10EB100006480249401D0CF01EFB09E0CCE600004F -:10EB2000FF020000AC12002080000020140500004D -:10EB3000767EB87805F050FF002803D1FB49FC48E9 -:10EB40000CF009FB05F0B3FF0121484031460143B9 -:10EB50001FD06A461188A279FD2352001219118133 -:10EB6000A2794000515D4908490031435155A279CD -:10EB70001940014351556A46107C002802D00420F8 -:10EB8000014301E0FB200140A0794155A079401CE0 -:10EB9000A0710021684604F01EFE002804D16846DA -:10EBA0000188808881429ED10020207101206071FF -:10EBB0003B21E17020707EE770B5DE4C0546207881 -:10EBC000002804D034210E2001F023F970BD08F094 -:10EBD00087FF052804D0284608F03FFD002000E00C -:10EBE0000C202071012060713421E170207070BD13 -:10EBF00010B5D04C2078002804D00E21084601F032 -:10EC000008F910BD0622CC49A01D0CF01AF900200D -:10EC10002071012060710E21E170207010BD70B56F -:10EC2000C44C06462078251D002804D032210E2031 -:10EC300001F0EFF870BD3146002009F032F928707C -:10EC400000280CD100213246084606F080F92870D1 -:10EC5000002804D106223146B7480CF0F2F8012012 -:10EC600060713221E170207070BD70B5B14C054605 -:10EC70002078002804D030210E2001F0CAF870BDA1 -:10EC800008F073FD002803D104F0DEFA00280DD04F -:10EC9000287804F08AF8287806F0C0F9002020715E -:10ECA000012060713021E170207070BD0C20F6E70A -:10ECB000F8B5A04C06462078251D002804D0172161 -:10ECC0000E2001F0A6F8F8BD3146012009F0E9F860 -:10ECD0000127287000280FD13246012106F037F9AC -:10ECE0002870002808D19348062231463C300CF0A9 -:10ECF000A8F890484030877067711720E07027703F -:10ED0000F8BDFEB58B4C05462034A07B002804D00E -:10ED100028210F2001F07DF8FEBDA8781A2824D004 -:10ED20000EDC03000CF038FB16333333333321335E -:10ED300033333333333333333333333321212133D9 -:10ED40002A2824D00ADC1E3803000CF025FB0C20F6 -:10ED5000202020202020202020200E203A380300D0 -:10ED60000CF01AFB04150315031528887349884213 -:10ED70000DD81F21E173282121740120A073288858 -:10ED8000694604F0CBFC002803D0022014E01220D6 -:10ED900012E068460078019F00280FD0C637019E18 -:10EDA00000280DD0C736684601F05CF8002802D074 -:10EDB0003878002806D00C20E073FEBD9C37EEE7C3 -:10EDC0009D36F0E701203870A87830700020E0739D -:10EDD000684601F05FF8FEBDF0B5564C0746207856 -:10EDE00085B0002804D025210E2001F012F862E63B -:10EDF000388802A904F092FC4E4E00210836002803 -:10EE00000CD00220207131603171E1800E20A070A1 -:10EE10002520E0700120607120704CE6039D28469B -:10EE20000A30483501900020A87505223046019926 -:10EE30000CF007F8A87D0028F5D13888E080E5E7D8 -:10EE4000FEB53C4C06462034A07B002804D010219F -:10EE50000F2000F0DEFFFEBD1F20E07310202074A5 -:10EE60000127A7733088694604F058FC002810D1A8 -:10EE7000684600F0F7FF00280BD06846019D007837 -:10EE800028350028019806D0CA300178002909D118 -:10EE900004E0022007E08030406AF6E72035697B15 -:10EEA000002902D03A20E073FEBDA97B89070DD16D -:10EEB0000621017068460078002804D10198318845 -:10EEC0008030406A4180684600F0E4FF0020E07333 -:10EED0006F73FEBD70B5174D04462878002804D026 -:10EEE00038210E2000F095FF70BD1F2028710120F1 -:10EEF00068713821E97028702078002808D001282E -:10EF000006D0022804D0032802D01220287170BD38 -:10EF1000002606F051F8207807F061FC207808F010 -:10EF2000E6FF20780AF0ABFA2E7170BDCCE6000047 -:10EF30001F0500006C1200208C000020FF0E000056 -:10EF4000F8B5FE4D06462878002804D01D210E2075 -:10EF500000F05FFFF8BD1F202871012068711D219E -:10EF6000E970287008F0BCFD0C27042857D005284C -:10EF700055D0B0791224012801D000281DD1307855 -:10EF8000002801D0012818D1F079002801D00128EB -:10EF900013D17088EA49021F30248A420DD2B28808 -:10EFA000121F8A4209D22887B0886887B079002466 -:10EFB000012804D000280CD016E02C71F8BDDF48E1 -:10EFC0004030807800282AD0DC4A3C3201210846B3 -:10EFD00002E0DC4A0021012005F0B9FF040003D063 -:10EFE000D949DA480CF0B7F8F079012801D00028A7 -:10EFF00002D105F0C8FF0446002C01D01F2011E00B -:10F000003078012802D0002803D00AE00021022035 -:10F0100001E00021012005F0C6FF002801D02F717A -:10F02000F8BD00202871F8BD70B5C44C21780029C6 -:10F0300004D01E210E2000F0ECFE76E71F21217186 -:10F04000012161711E22E270217002781221012AD1 -:10F0500001D0002A04D14078002803D0012801D033 -:10F06000217162E700260C25012A09D008F038FD3D -:10F07000052803D008F042FA002806D0257154E78D -:10F08000618F208F08F083FBF6E726714DE7F0B51E -:10F09000AD490446143103C987B0A84D0591203508 -:10F0A0000490A87B002805D021210F2000F0B1FE9C -:10F0B00007B0F0BD1F20E873212028740126AE732D -:10F0C00022889F4B111F3020994243D261880F1F25 -:10F0D0009F42FAD291423DD8E2899D4B911F9942BD -:10F0E000F3D2218A8F1F9F42EFD28A42F3D8628ADD -:10F0F000FF23F4339A42EED8A28A954F13460A3B77 -:10F100003F1FBB42E1D2C9088A4223D9E18A228B40 -:10F110009142E0D821791220002902D0012919D189 -:10F1200002E061790029F9D1217B002901D0012970 -:10F13000F5D108F0D5FC05280BD008F0D1FC042847 -:10F1400007D0287D002804D105F017FD81498842A9 -:10F1500001D00C20BDE0684604F0AEFA002801D0D2 -:10F160000920B6E001220321009804F0E6FF009F89 -:10F17000042178880F3703903846FCF7D5FF3846CE -:10F18000039905F0C2F874A0009F0068069003215F -:10F1900006A81337FCF751FF002006A90A5C3A5471 -:10F1A000401CC0B20328F9D30098218A8180618A6B -:10F1B000C180A18A01810146002720318F73CF735E -:10F1C0006179002902D0012903D101E0C77600E06E -:10F1D000C6760622A11D1C300BF033FE00980522D6 -:10F1E00004A90A300BF02DFE0098A0300673694682 -:10F1F0000F71012101A8FCF720FF6946087941073A -:10F20000C206490F920F80068918C00F0818694678 -:10F210000871401D009B0928987601D20830987625 -:10F2200001220021184604F088FF00988A3005F07A -:10F2300044F9002804D145484349FC300BF08BFFCA -:10F24000207B002806D0012808D03F4943480BF016 -:10F2500082FF40E000213B4A012008E0374840306F -:10F26000807800280FD0354A01213C32084605F04D -:10F270006EFE00282FD000988030807A05F03FF98C -:10F28000002816D01AE000988030807A05F037F90F -:10F29000002804D131482C490D380BF05CFF009850 -:10F2A00004F0DAFA002800D153E72C48264909383F -:10F2B00041E02A482449C01D0BF04DFF009804F09E -:10F2C000CBFA002804D025481F490B300BF043FF30 -:10F2D0001F20E873ECE62079012801D0002803D133 -:10F2E00005F051FE00280CD10320009905F05BFECB -:10F2F000002806D162882188009808F0F5F90028D6 -:10F3000007D000988030807A05F0F9F8002805D001 -:10F3100009E00098A0300770EF73C9E60F480A496A -:10F3200031300BF018FF009804F096FA0028BBD09B -:10F330000A48054935300BF00EFF0AE76C12002031 -:10F34000FD3F00008C000020CCE600000607000016 -:10F350007B0C0000FFFF0000112233001C0800009E -:10F3600038B5F94C2078002804D022210E2000F076 -:10F3700050FD38BD1F202071012565712220E070ED -:10F38000257008F0ADFB052802D00C20207138BD97 -:10F3900000202071684608F059FA0028F7D100983B -:10F3A0008030807A05F0ABF8002803D1E749E848BF -:10F3B0000BF0D1FE009804F04FFA002804D0E44886 -:10F3C000E249001D0BF0C7FEDF4820300575E1481B -:10F3D0000078F2F799FF38BDF8B5DB4D04462035CB -:10F3E000A87B002804D023210F2000F012FDF8BDD7 -:10F3F0001F20E873232028740120A8736288D64B4D -:10F40000911F302099424CD2A1888E1F9E4248D233 -:10F410008A4246D8E288FF23F4339A4241D82289AF -:10F42000CD4E13460A3B361FB3423AD2C9088A4230 -:10F4300037D96189A289914233D80026208869464C -:10F4400004F05EF9022700280BD1009800F0F8FCC8 -:10F45000002806D000988030416A0A78002A06D138 -:10F4600001E0EF73F8BD826B1278002A01D03A20D8 -:10F4700017E005228A71416A0E81426AA188518192 -:10F48000426AE1889181426A2189D181406A018979 -:10F490004289914204D88179082901D8914202D346 -:10F4A0001220E873F8BD2188418000988030406ABE -:10F4B0000770EE73F8BDFEB5A34C06462078002811 -:10F4C00004D024210E2000F0A4FCFEBD01256571AE -:10F4D0002420E0702570304604F039FF002801D068 -:10F4E000002000E0122020710028EED1964F052266 -:10F4F000E03738463D7731461D300BF0A2FC002640 -:10F500003E77701E69460880684604F031F900288D -:10F5100019D168460788684601A9008804F0F0F808 -:10F52000002804D08A4889498F300BF014FE0198D6 -:10F53000A0300573684604F01BF9002803D1684623 -:10F5400000888742E7D12671FEBD38B57E4C05465E -:10F550002034A07B002804D026210F2000F059FC85 -:10F5600038BD1F20E073262020740120A073288856 -:10F57000694604F0C5F800280BD1009800F060FC43 -:10F58000002806D000988030416A0A78002A06D107 -:10F5900001E002200DE0806B0078002801D03A20C5 -:10F5A00007E007200870009829888030406A418071 -:10F5B0000020E07338BD10B5634C2078002804D0DB -:10F5C00006210E2000F025FC10BD002020710E2029 -:10F5D000A0700620E0700821A01D0BF08FFCA1791F -:10F5E00001200143A1716071207010BD38B5564CE7 -:10F5F00005462034A07B002804D02C210F2000F0E9 -:10F6000008FC38BD1F20E0732C2020740120A0735B -:10F610002888694604F074F800280CD1009800F09E -:10F620000FFC002807D00098014680314B6A1A78F9 -:10F63000002A06D101E0022025E0896B0978002923 -:10F6400001D03A201FE04030007F00281DD0082262 -:10F65000A91C181D0BF0F5FB00986A898030416ADF -:10F660008A81406A294610220C310E300BF0E9FBEA -:10F67000009803218030406A01700098298880300A -:10F68000406A41800020E07338BD0C20FBE770B574 -:10F690002D4E044630780C25002804D018210E2069 -:10F6A00000F0B7FB41E402F0CBFE032865D002F086 -:10F6B000CDFE032861D06079002801D001282DD12A -:10F6C000A079002801D0012828D1A07B002805D0EE -:10F6D000012803D0022801D003281FD1607B002815 -:10F6E0001CD0C0081AD1628801208003824202D84F -:10F6F0002188814203D9207901280FD119E020798E -:10F70000002806D0012814D0022805D0032805D1EE -:10F7100002E0202A0BD30CE0A0290AD22079042889 -:10F7200005D12088202802D36188884201D912257A -:10F7300023E00548217920308175607900280DD0BB -:10F7400001280FD019E000006C120020CCE6000068 -:10F750007F080000800000207B0C0000FA4A002196 -:10F76000204607E0F9488078002806D0F74A0121B2 -:10F77000121F204608F01BFB0546012035717071F1 -:10F780001821F170307058E410B5F04C403C2178ED -:10F79000002904D01A210E2000F03BFB10BD017897 -:10F7A0001F2902D91220207106E000212171027860 -:10F7B000411C104608F09EFB012060711A21E17087 -:10F7C000207010BD10B5E14C403C2178002904D0D8 -:10F7D00020210E2000F01DFB10BD01781F2902D949 -:10F7E0001220207106E0002121710278411C104690 -:10F7F00008F06FFB012060712021E170207010BDC6 -:10F80000F8B5D24C403C2178002904D01B210E20B1 -:10F8100000F0FFFAF8BD012666710C212171007815 -:10F820000025012804D000285CD01220207188E037 -:10F8300002F006FE002835D102F008FE002831D182 -:10F8400008F021FAC24988422CD108F07AFA00283F -:10F8500077D0684603F0C6FEBB4A00990C3A916027 -:10F86000002803D0BB49BC480BF075FC01220321E2 -:10F87000009804F008FC009808F0CDFB00988A304E -:10F8800004F01BFE002804D1B348B24908300BF045 -:10F8900062FC009803F08CFA002851D0AE48AD49C4 -:10F8A0000C301CE002F0CCFD02284AD102F0CEFD63 -:10F8B000002846D1A5482038807D002841D0012865 -:10F8C0003FD004283DD008F03CFA002839D0002071 -:10F8D00003F06EFA002833D09F489E4924300BF085 -:10F8E0003AFC2DE002F0ACFD032804D002F0AEFD9E -:10F8F000032820D025E002F0A6FD0090002003F0B0 -:10F900004FF900281DD1257100988030807A04F0CD -:10F91000F6FD002804D190488E493E300BF01BFCC8 -:10F92000009803F0B1FE00280BD08B488949423083 -:10F930000BF011FC05E0002003F032F9002800D1A3 -:10F9400025711B20E0702670F8BD38B57F4C054648 -:10F95000403C2078002804D02D210E2000F059FAD8 -:10F9600038BD2888694603F057FE002801D00220E0 -:10F970000FE00098CA21095C002909D13321095CF4 -:10F980000F2901D0102903D1FC21095C00290BD0DB -:10F990000C2020710E20A0702D20E0702888E080BF -:10F9A00001206071207038BD1022A91CD8300BF0E6 -:10F9B00048FA00980421C03081720020E9E738B588 -:10F9C000624C0546403C2078002804D02E210E20B1 -:10F9D00000F01FFA38BD2888694603F01DFE002894 -:10F9E00001D002200CE000980146C030827A002A43 -:10F9F00005D12031C97C0F290DD010290BD00C2046 -:10FA000020710E20A0702E20E0702888E080012058 -:10FA10006071207038BD052181720020F0E77CB54F -:10FA20004A4C0546403C2078002804D037210E205F -:10FA300000F0EFF97CBD2888694603F06FFE0028CE -:10FA400007D002202071012060713721E170207001 -:10FA50007CBD01987F22014628300272427200224A -:10FA60008272A87822318870E878C8702879087185 -:10FA70002271E8E71CB5354C403C2178002904D0C0 -:10FA800013210E2000F0C5F91CBD0088694603F063 -:10FA900045FE002801D0022006E001982421095CDF -:10FAA000801C012902D00C20207107E0002201995E -:10FAB00022712831097A21720088E080012060716A -:10FAC0001321E1700E21A17020701CBDF8B51F4CF0 -:10FAD0000546403C2078002804D035210E2000F057 -:10FAE00098F9F8BDA878002801D0012804D1A88889 -:10FAF000FF21F531884201D91220207128886946FA -:10FB000003F08AFD0126002806D0022020716671CC -:10FB10003520E0702670F8BD009800270246C030FE -:10FB20000770AB8801464380104680300677AA787C -:10FB3000012A00D000220A70407F002801D003F083 -:10FB400027FA2771E3E700008C000020AC120020A8 -:10FB5000FFFF0000CCE600002D0A0000F8B5D44EEF -:10FB600004463078002804D03D210E2000F051F9E1 -:10FB7000F8BD2088694603F04FFD002801D002201F -:10FB800027E0009F6488FD883A896800B988401C96 -:10FB9000844217D3C7484143800050430BF0BAF961 -:10FBA000401EFF2180B2F531884200D908468442C8 -:10FBB00000D22046691C401C0BF0ACF96D1C684358 -:10FBC000401E85B2E820C05D002800D17D84F5800C -:10FBD00000203071012070713D21F1703070F8BD4E -:10FBE00070B5B34C05462078002804D033210E2090 -:10FBF00000F00FF956E502F023FC002801D00C209C -:10FC000018E02978002911D00A290FD014290DD025 -:10FC10001E290BD0282909D0322907D04B2905D01D -:10FC2000642903D0FF2901D0122003E0284603F005 -:10FC30004BF900202071012060713321E1702070A8 -:10FC400030E570B59A4C05462078002804D03E2156 -:10FC50000E2000F0DEF825E502F0F2FB002803D1CB -:10FC600002F0F4FB002801D00C2003E0287808F013 -:10FC70004DF900202071012060713E21E17020705B -:10FC800010E510B5017801240B000BF085FB3FBF98 -:10FC9000BF21BFBF4C94BFBFBF2427BFBF464F612A -:10FCA000BFBF59BFBFBF2B97BF9B9FBF797DBFA36E -:10FCB0008185888C6590BF5DBF555275A7ABBF37F6 -:10FCC0002F33BB6DAFBF71423F3B4969B3B7C00033 -:10FCD000FEF750FD9BE0FEF790FD98E0801CFEF7DC -:10FCE000D1FD94E0801CFEF7E3FF90E0801CFEF75E -:10FCF00080FE8CE0801CFEF792FF88E0801CFEF7FF -:10FD0000B4FF84E0801CFEF793FD80E0FEF7ECFD7D -:10FD10007DE0801CFFF7DEF879E0FEF769FF76E012 -:10FD2000FEF7BEFE73E0FEF74BFE70E0FEF7F7FD58 -:10FD30006DE0FEF72EFE6AE0801CFEF786FE66E0B0 -:10FD4000801CFFF797FE62E0801CFEF7DAFF5EE0A2 -:10FD5000801CFFF775F85AE0801CFFF73DF856E06D -:10FD6000801CFEF7FEFD52E0801CFEF725FF4EE0F2 -:10FD7000801CFFF754FE4AE0801CFFF737FC46E08A -:10FD8000801CFFF7DDF842E0801CFFF74DF93EE0F4 -:10FD9000801CFFF77CF93AE0FFF7E2FA37E0801CBD -:10FDA000FFF71AFB33E0801CFFF785FB2FE0801C78 -:10FDB000FFF7CBFB2BE0FFF7FEFB28E0801CFFF7F3 -:10FDC00066FC24E0801CFFF7DFFC20E0801CFFF7CE -:10FDD00017FD1CE0801CFFF7F5FC18E0801CFFF706 -:10FDE000B4FD14E0801CFFF7EAFD10E0801CFFF773 -:10FDF0006DFE0CE0801CFFF7B1FE08E0801CFFF7F1 -:10FE000020FF04E0801CFFF7EBFE00E0002420460A -:10FE100010BD274A2032537C002B03D19074D1743B -:10FE200001205074704730B5134606E0CC18203CD2 -:10FE3000D51AE47F5B1E4455DBB2002BF6D130BDF2 -:10FE4000017800290CD14121095C002908D18030BA -:10FE5000017C002904D0007C042801D001207047D7 -:10FE60000020704701784068002903D001780029FC -:10FE700005D100E0E4E740304078002801D00020C0 -:10FE80007047012070470A4900208031886740315F -:10FE90000871704710B50178012908D14068803099 -:10FEA000417F002903D00021417703F071F810BD94 -:10FEB0006C120020C409000070B5FC4D00246C7069 -:10FEC0002C70AC616C72AC720120E872F84844701E -:10FED000C473AC62F7482C6302F05FF9002804D0C9 -:10FEE000FF20F5A14F300BF036F92C7770BDF8B537 -:10FEF000F54902250D60F5490026CE630127CF6341 -:10FF0000F349C96A09070DD4F24AD36AF2494B6230 -:10FF1000136B8B62536BCB62936B0B63D26BCB0512 -:10FF20001A434A63ED4C002823D0012825D0FF2036 -:10FF3000E1A1A2300BF00FF9E948A063FF200430E3 -:10FF40006063276303202061E64996204860D74913 -:10FF50001C2008560B22D243811A904237D011DC64 -:10FF60001C313AD00A2938D0142934D0182911D19B -:10FF70002FE0DD486061DD4802E0DD486061DD487A -:10FF8000A061D9E708301FD004281BD0082817D05B -:10FF90000C2812D0FF20D8A176300BF0DCF8DB491A -:10FFA000D9488860DB48DA494160DB490160DB48B9 -:10FFB0000560DB4910204860F8BD0420E060EEE7F2 -:10FFC000E660ECE7FC2000E0F820E060E7E7F420E2 -:10FFD000FBE7F020F9E7EC20F7E7D820F5E710B5CC -:10FFE0000C460146CF480BF0B2F9B048047210BD80 -:10FFF000AF4840787047AD4A517010707047F8B5FF -:020000040001F9 -:1000000004460D4650791179000208436900091928 -:100010000884501C01460E78012730464E7836027F -:1000200030438E78C9783604304309060843117886 -:1000300000020843A9006050284608303E4686402A -:10004000002B0CD0012B04D0FF209BA1E9300BF03A -:1000500082F8206B3043AF4038432063F8BD206BFB -:10006000B043F8E770B50D460446082904D9FF20CF -:1000700091A1FA300BF06FF80022002D0CD9AA489C -:100080009100635809180B6053001B191B8C0B62FD -:10009000521CD2B2AA42F3D3206BA449086070BDAF -:1000A00010B504460B22D2430C308C49944223D025 -:1000B00008DC1C3026D00A2824D0142820D0182888 -:1000C00009D11BE02046083014D0042810D008289D -:1000D0000BD00C2807D0FF2087A176300BF03BF81F -:1000E0007248047710BD042000E00020C860F7E7E4 -:1000F000FC20FBE7F820F9E7F420F7E7F020F5E72C -:10010000EC20F3E7D820F1E76948007B704773499A -:10011000C2784A6202461378184653781B02184385 -:100120009378D2781B041843120610430002C8616A -:100130007047252808D0262808D0272808D0410055 -:100140000A2807D8091D06E0022105E01A2103E06C -:10015000502101E0891DC9B2604A9160614948613E -:10016000704752498861704770B5002816D0022246 -:100170004E4C6F4BA27203201860644D6248686059 -:1001800000200126207500290AD001290FD002295C -:100190001DD049A167480AF0DEFF70BD0122E7E7E4 -:1001A0006548012A01D0466070BD066070BD3F48B9 -:1001B000012A006B05D001214905084320636960CD -:1001C00070BD0121090508432063696070BDA06905 -:1001D000002804D1492038A1C0000AF0BCFFA16961 -:1001E000A06A4018554988604A4855498160554978 -:1001F000C1600120216BC0030143216368602C486A -:10020000C67370BDF8B54A4801688F084449BF00FD -:100210004A68D206D60F10228A60002404603B4848 -:10022000394981600C2069460870474D2C6142496C -:10023000012008610BE000BF00BF00BF00BF00BF8E -:1002400000BF00BF00BF69460878401E08706846BE -:100250000078002802D028690028ECD06846007891 -:10026000002804D14D2024A1C0000AF074FF2C61A5 -:100270000E48012144728472C1722D480760002E1D -:1002800002D0274910204860F8BD01460A78104680 -:100290004A78120210438A78C9781204104309067A -:1002A000084300020D49000AC86370477413002018 -:1002B00094130020A81300207372635C68616C5F64 -:1002C0007263732E6300000080E100E0C01F0040F5 -:1002D00080000010C0000010001700400015004012 -:1002E0005B060000401500400601020025000302E5 -:1002F000050103001F0003027372635C68616C5F99 -:100300007263732E630000000040000400F501409A -:100310004080004080F501401011004080E200E084 -:1003200000130040761300200016004040160040E5 -:1003300000120040550200000010004040850040BF -:10034000488100401010004000110040FB4902208D -:100350000860FB4908607047FA490220086070474E -:10036000F9490870704710B5F84801F01EFF0028E1 -:1003700003D0F749F7480AF0EEFE10BD10B5F34878 -:1003800001F02BFF10BDF4494860704770B5F34C85 -:100390000546A06AA84203D3ED49F1480AF0DBFE06 -:1003A00001202073EF49002025614860EE48456038 -:1003B0000120216B800501432163EC49486070BD39 -:1003C000E64802210173C6210161E64A002151601D -:1003D000816AE54AC63151600121026B89050A43F1 -:1003E0000263E248416070470121E048890581606D -:1003F000DA48026B8A430021026301737047DC48CC -:1004000001214160C160D74900204860D649486059 -:10041000D24988627047D74940200862D6490A68A5 -:1004200002430A607047D44801684022914301604A -:10043000D049002008627047CF48016810229143DC -:100440000160CE49012088617047CD490020C86114 -:10045000C94801681022114301607047C849CA6940 -:10046000012A01D000207047C24A92685206520EFB -:10047000524202700020C8610120704770B50C0024 -:10048000054604D1D920B24980000AF064FEE00795 -:1004900005D0012C03D0AE49BA480AF05CFE002D0D -:1004A0000DD00221AD4801294172C472B24808D072 -:1004B00002290BD0A649B4480AF04DFE70BD0121B7 -:1004C000F0E7016804221143016070BD0168082251 -:1004D0001143016070BDF8B5A04C0025E27A910788 -:1004E00001D5410713D4D306A849002B05DA4B7B6D -:1004F000002B02D08B7B002B09D0130702D50B7881 -:10050000002B04D1520703D54978002900D10125D9 -:10051000677A002201239849002F1BD00226304021 -:10052000284348D0084601688E089949B6004D68AE -:10053000ED06ED0F10278F60002101608B4A954872 -:1005400090600C206A4610708D4F39618B490120F4 -:10055000086114E0854D8F48A86008688008800015 -:100560000860A272E372F8BD00BF00BF00BF00BF09 -:1005700000BF00BF00BF00BF1078401E1070107891 -:10058000002802D038690028EED01078002804D165 -:100590004D208149C0000AF0DEFD00203861607204 -:1005A000A0720120E07274480660002DDBD078480C -:1005B00010214160F8BD012F06D0022F0CD06449F4 -:1005C00076480AF0C8FDF8BD08680425A84308600D -:1005D0006272E372A372F8BD08680825A843086038 -:1005E0006272E372A672F8BD5C4908757047F8B58F -:1005F000664D5A49EC7B086B002C58D001245B4AAD -:10060000E4039460A04308635B480768604C1021D2 -:10061000A16000210160001490600C206A461070F7 -:10062000574C21615548012606610AE000BF00BF12 -:1006300000BF00BF00BF00BF00BF00BF1078401E5A -:1006400010701078002802D020690028EED01078B1 -:10065000002804D14D205049C0000AF07CFD002044 -:10066000E060206160606061A061434807603F49CD -:1006700000144860464910204860384CA07A012890 -:100680000FD0022810D0444945480AF064FD0020EC -:10069000E873207D022803D1424801688907FCD510 -:1006A000F8BD36480660F2E734484660EFE72F4A67 -:1006B000906000200863087B2A4E002802D07068F2 -:1006C000012809D000222E4C2069012806D00023E1 -:1006D000887A012804D006E00122F4E74023F7E7F6 -:1006E000E768012F04D000271F43012802D004E04F -:1006F0002027F9E76368012B05D000233B432A4FED -:10070000022802D007E01023F8E73968012902D156 -:10071000E168012904D000211943022802D007E032 -:100720000821F9E73B68002B02D1E368012B3DD09B -:1007300000230B4302283BD03EE0000080E100E0B4 -:1007400080E200E000E100E092000020A813002019 -:10075000B8020100A202000000150040741300203E -:10076000B3020000408100404085004000F5014098 -:100770000080004040150040001200400010004082 -:1007800000110040690300007E0300009413002064 -:100790000013004000400004F8020100CF030000F5 -:1007A0005E03000000E200E0001400400423C0E704 -:1007B000002A01D0022100E000211943022807D1BC -:1007C0006068012804D17068012801D0012700E089 -:1007D000002790480F4301680906090E02D061699D -:1007E000012900D00021297300680006000E02D004 -:1007F000A069012800D0002068738748006A00289B -:1008000003D000F0DCF9012800D00020A8730020FC -:10081000E060206160606061A06180494860804E56 -:100820008049307548683C4670620968B1620B4681 -:10083000B17A022909D17178002906D07A4A526822 -:1008400012780A40317891430ED000212970774FF9 -:10085000E10710D03978032908D0022906D002F028 -:10086000D1FC0121B06A20E00121EFE707F022F975 -:100870000121B06A27E0A0060ED53878032806D0FB -:10088000022804D00221184602F0CBFC0FE002211E -:10089000184607F010F90AE0A00708D538780328B1 -:1008A0000FD002280DD00021184602F0BAFC5E4895 -:1008B00041680622B01C09310AF096FA002805D0DA -:1008C0000DE00021184607F0F6F8F0E75648317AB7 -:1008D00040680078C009814201D1012000E0002079 -:1008E00068702046FFF7F7FD387800280DD0012802 -:1008F0001ED002282FD003284AD04D494D480AF077 -:100900002AFCB07A022856D075E0A00701D507F07E -:10091000C6FC200702D5012007F0FDFC600702D5C8 -:10092000002007F0F8FCA006EBD507F059FCE8E73B -:10093000A00701D508F0E8FF200702D5012008F044 -:100940004DFE600702D5002008F048FEA006D8D56D -:1009500008F098FDD5E7A007BF25002802DA2C4053 -:1009600004F022FF200703D52C40012004F05DFB9A -:10097000600703D52C40002004F057FBA00602D5E9 -:100980002C4004F061FE6006BBD504F04AFBB8E7DA -:10099000A00701D506F0F0F8200702D5012005F0E8 -:1009A000B1FF600702D5002005F0ACFFA006A8D576 -:1009B00005F01CFFA5E7307B00281CD0174900225A -:1009C0004A60022820D0012803D019491A480AF0A9 -:1009D000C2FBB16A3069884203D8154917480AF04A -:1009E000BAFB1048316941600120316B8005014339 -:1009F000316313494860307D012800D050E611482A -:100A000001688907FCD5F8BD3169B06A411805480D -:100A10004160E9E740160040401500404081004039 -:100A20007413002040850040001500409200002013 -:100A3000B8020100FD0400001205000013050000CB -:100A400000F5014000E200E02E48002101704170F5 -:100A5000704770B5064614460D460120F0F7A2FC1B -:100A600028490120284B08709E60DC601D6170BD24 -:100A7000F8B504460120F0F795FC224901200870E2 -:100A800021494C60214900264E600321204D090672 -:100A9000A960204F002C0AD0012C03D01EA14120B8 -:100AA0000AF059FB3E60032000066860F8BD38601C -:100AB00001200006F9E710B51248017800290ED090 -:100AC0000321134A0906916010494A680021002A4F -:100AD00003D0154A1268427000E041700170002096 -:100AE000F0F760FC10BD07480178002907D00748DF -:100AF0004068002802D00C480068C0B270474078B7 -:100B0000704700009300002000F5004000F1004015 -:100B100000F5014000F200407372635C68616C5F35 -:100B200063636D2E6300000000F400403B48002129 -:100B30000170417010218170704770B506461446EF -:100B40000D460220F0F72EFC01203449344A08708B -:100B5000E41E14619660556070BD10B50220F0F778 -:100B600021FC2E49012008702E48002101604160BF -:100B7000816001202C49C005486010BD10B5274890 -:100B80000178002917D00121274AC905916025491C -:100B90000B680022002B05D04B68002B02D089681F -:100BA000002902D04270102103E0012141701F4949 -:100BB0000968817002700020F0F7F4FB10BD17483F -:100BC0000178002912D01748016800290AD001686D -:100BD000002905D04168002902D08068002803D090 -:100BE000002070470220704701207047407870470E -:100BF0000A48017800290FD00A480168002905D069 -:100C00004168002902D08068002801D01020704778 -:100C100006480068C0B27047807870479500002091 -:100C200000F5004000F1004000F5014000F40040F4 -:100C3000FFB593B0044600201D9E049015981C9D9E -:100C40001027082806D0E06901F014F8002809D020 -:100C50003770CCE028880921384328801F98022764 -:100C6000017016E0E169012088710521E269C9027D -:100C70009180E1698872E169F9480881E1690020A1 -:100C80008873288820210843288011211F98042771 -:100C900001701F980225801C0390307810900A2064 -:100CA0003070204618301190F5F7A1FC00206FE05D -:100CB0001598102809D1022D07D06846828A049918 -:100CC0000398401A8270110AC1706846C08A16994A -:100CD000884203D9E349097A149106E0884204D195 -:100CE0001099002901D0317021E003990870000AA1 -:100CF00048701E980088401BC01B83B2FF20C01B99 -:100D0000984200D203460398149AC0190CA9009285 -:100D1000019002912020015D6846C08A0022F5F70B -:100D2000DBFC3070002806D0C0B2832862D0684651 -:100D3000C08A208345E00F98002805D0C948006884 -:100D400000790A2830D33CE06846008EC119C9B248 -:100D50000491022D0FD01F99049A4978914203D132 -:100D60006A46128C824209D0BE480491006801781C -:100D7000032909D027E008461F994870B948006840 -:100D80000178042906D008E000790A281BD2012046 -:100D90000F9009E06946C98A818003990498081870 -:100DA00003900498281885B205AA14991198F5F7AC -:100DB00021FC002805D11E980088401BB84200DBAA -:100DC00076E7022D0ED01598102807D1049A0399C2 -:100DD0006846808A891A8870000AC8701E98058043 -:100DE000002030709F4800680078032802D000205F -:100DF00017B0F0BD0220FBE7F8B50446406B0026B3 -:100E0000134600282BD0491F8DB2618F2A46083225 -:100E1000278F8A18BA4221D89A7840185F78110231 -:100E200039430170090A41701A79DF781102394398 -:100E30008170090AC1700571290A41712A46591D3C -:100E4000801D09F0FEFF608FAD1D401980B26087E4 -:100E5000626B002110180170417000E009263046D5 -:100E6000F8BD30B50B88048F9C4212D9446BE01852 -:100E70004478057824022C430BD044790579240268 -:100E80002C436404640CA41D1B190B80106000200B -:100E900030BD822030BDF7B588B000256846058298 -:100EA00005275DE00398417802780E0216434179E8 -:100EB000027908021043000452D40A9801230680E4 -:100EC00005A802905B02002200970195304609991F -:100ED000F5F702FC04004AD16846018A01830398B1 -:100EE0004179027909021143437802781C021443C4 -:100EF000B4421ED10A041CD44B0401215B0C8903AB -:100F000000950B4301970295C17880780A0202434D -:100F100020460999F5F7FCF9040011D103994879A5 -:100F20000A79000210430122D20310430871000A1B -:100F3000487103AA06A90898FFF793FF0400CED0D2 -:100F400003990095019702954878097800020843B3 -:100F500069468B8A00220999F5F7DAF9822C06D1C5 -:100F600003AA04A90898FFF77CFF04009AD06846FA -:100F7000058209E003984179027909021143490485 -:100F8000490C0171090A417103AA04A90898FFF7E5 -:100F900068FF0028EED0822C02D020460BB0F0BDB6 -:100FA0000020FBE730B50446406B002597B00028D1 -:100FB0000DD00B2268460270228F0281606B039174 -:100FC000019000216846F2F72AFB684605706563C8 -:100FD0006587258717B030BDF8B50F460546696BA4 -:100FE0000020069E144600290FD0012B0DD1324659 -:100FF00039462846FFF74FFF002806D1002C04D0C1 -:1010000032463946284600F044FEF8BD00220280F0 -:10101000C262831D0263C36142634287028720303C -:101020000170704710B50022D24302800420FBF704 -:10103000E4FA10BD10B596B00446FFF7B3FF208E5A -:10104000002808D0012069460870E06A019000215C -:101050006846F2F7E4FA0020E062206316B010BDA3 -:1010600001280000AC1300200146098800200A076F -:1010700000D501200A06120F01D002221043CA0532 -:1010800001D5042210438A0501D5102210434905D9 -:1010900001D5202108437047FFB5A9B00600329D55 -:1010A000359C2B981F46229016D0007841060FD40D -:1010B0008106890E1E2909D021884A05520E0BD1BE -:1010C0003A88172A08D3FE4A914205D0C10906D0B2 -:1010D0008006800E122802D003202DB0F0BD2046DD -:1010E0002C302690F7492A980872002018AA0390FD -:1010F00010726A46107404AA0A60339A4A6020AAE1 -:10110000908090812298007801908106681C1C9044 -:10111000701F1D902B98890EC21C249222462032EB -:101120001B92083A401C02920B000AF035F91FFD91 -:10113000FD11FD1FFD8EFDFCFDFBFDFAFDF9FDFC23 -:10114000FDF8FDFDFDF7FDF6FDFDFDFDFDF5FD00E6 -:10115000032E76D102E018A9087219E30320287043 -:101160001C9917220A7000224A70CFE2052EF0D196 -:101170004178027808021043208320A98880249AAD -:101180005178127809021143618300287ED0884289 -:101190007CD800202072E080401E60840298F5F721 -:1011A00026FA05202870A81C0190022000901BAA96 -:1011B0002A990298F5F71EFA002868D118A8807CB1 -:1011C000012803D002206870102002E0012068701E -:1011D00002202490002225A91CA8F1F7AAFD0028CE -:1011E0002BD120A8007D2499814226D13A880099EC -:1011F000801C511A814220DB10A8C18D019801701A -:10120000090A417001991CA8891C01910099019A51 -:10121000891C009125A9F1F78CFD20A8007D01997A -:101220001BAA091801910099081880B200902A9908 -:101230000298F5F7DFF90028CCD00098022826D0D4 -:1012400064E272E018A9087261E2072E6DD341785A -:101250000346027808021043208320A98880249A3C -:101260005178127809021143618300280ED0884218 -:101270000CD8012020725879197900020843E080C7 -:1012800000202073E06900F0F5FC01E098E0A9E09F -:1012900000280ED1E169012088710521E269C902A7 -:1012A0009180E1698872E16987480881E1690020DD -:1012B0008873F01F60842298C01D60620298F5F761 -:1012C00096F907202870681C0090012001900020EA -:1012D00010A9C8852FE00198012814D0E069807911 -:1012E000012830D000981E38417F007F0902014359 -:1012F00000980170090A41700098801C00900198C4 -:10130000801C80B2019010A8C18D00980170090A5C -:1013100041700098801C09E00AE296E13BE1DFE0C1 -:1013200004E29BE077E036E016E2AFE0009001983F -:10133000801C80B201901BAA2A990298F5F75AF9ED -:10134000002803D007E010A8818DD1E739880198E3 -:10135000081A0428BFDA0198012843D0E06980798F -:10136000012804D010A8818D5548814206D110A8CB -:10137000818D00980170090A417009E000981E38BB -:10138000417F027F0802009910430870000A4870EC -:101390000198801CBAE1072E01D0152E76D1417834 -:1013A000027808021043208320A98880249A51786B -:1013B0001278090211436183002801D0884201D9C3 -:1013C00001203FE7012020720020E0802073052EDD -:1013D0000AD01D982299E269C0B2491DF1F783FC39 -:1013E000002801D00A202DE70020C04360841AA8FD -:1013F000019023A922980297039500910078002379 -:101400008206920E20462A99FFF712FC0390208B49 -:1014100020A988807BE1032EC0D1402220A98A81A7 -:101420004178027808021043208320A988802A99F5 -:101430001EAB1C9A02930192009139880022491E2A -:101440008BB21B990978F5F747F918A9087200289B -:1014500033D10B20287010A8008F3FE0052E9DD1BE -:10146000802220A98A8141780278080210432083D3 -:10147000249984464A78097812020A43628420A992 -:1014800088801248824202D30720DBE6AFE03F208B -:101490008002024362842A981FAB1C990293019137 -:1014A00000903888401E83B21B9801786046F5F79B -:1014B00013F918A9087200280CD08328AAD107E0D4 -:1014C000FFFF0000AC130020012800000102000013 -:1014D0000220B8E00D20287010A8808F401C15E174 -:1014E00001990C22C9095143C91CB14204D9019880 -:1014F00040067CD5002009E14278037810021843A9 -:1015000020AA9080844622980078400609D50520BC -:101510006A46107422980078C00905D00020107423 -:101520001DE106206A46107424981F902A9A0090A4 -:101530000023701A029383B21E9001921B9800221E -:1015400001786046F4F7E4FE18A9087200226946A3 -:101550000A74832801D10220039022980078400663 -:101560000DD52088C00506D520A9208B8988884202 -:1015700001D100206062002018A90872C6E0FF2196 -:10158000013120A88181808820831E9860841F9863 -:1015900060621320B8E0052E29D341780278080252 -:1015A000104320A98880218F002902D0FE4A914251 -:1015B00006D10A216A4611740121C943218702E03C -:1015C00007216A46117422992A9A491D01920091B5 -:1015D00001221D990023D203029311438BB2249957 -:1015E0004A78097812020A431B99097800E0C9E099 -:1015F000F4F78EFE18A90872002269460A740122C7 -:10160000520220A98A81832808D0002809D0218F7E -:10161000E54881427ED10020208778E088882083B9 -:101620004DE7606B002808D031462046229AFFF72C -:10163000E3FB18A90872002869D12B463A463046C8 -:10164000229900F056FB039061E02298022E407828 -:1016500001907DD1002801D0012879D10820694668 -:1016600008740198087521A800901B980022017841 -:101670002046019BFFF7B0FC6946002248758A7539 -:10168000002802D10198012809D0208F002806D017 -:10169000002008740120800220A988810EE004A89F -:1016A0003399F1F7BCFF03900020694608740120CC -:1016B000800220A988810398022807D0BB480068CF -:1016C0008079002805D018A908722BE001982083A2 -:1016D0001DE00398002803D0812018A9087240E07B -:1016E00021A800901B98012201782046019BFFF75A -:1016F00073FC18A9087220463499FFF753FC18A907 -:10170000087A002803D11920287001203880684603 -:10171000007C00E03CE0002804D004A83399F1F7F5 -:101720007EFF0390039800282ED01AE0062012E5D1 -:101730002078000713D5012E11D1092168460174C4 -:10174000A188818204203499FAF757FF082100E02C -:1017500005E020A88181CDE60198400612D503203E -:10176000039020A9208889890843208020A988899E -:101770004005400E04D026992B9808602698868054 -:101780000398AAE40420E6E418A8007A00280ED002 -:101790000120287022980078687020A88088A8709E -:1017A000000AE87018A8007A28710520388020A95E -:1017B0002088898988432080E2E7FFB50746A1B0E9 -:1017C00000201C903A7801209040794A7C681040B3 -:1017D00010AA1087744B22885B1C9A4203D0002801 -:1017E00004D0100702D5012025B0F0BD249E0020B2 -:1017F000307023980025028810A8028518A8057566 -:101800006A4B68461972057404A8186020462C308B -:101810001B902A985860249E94463878721C0521A3 -:10182000039201282DD0022808D003287DD13078DA -:10183000800980011D303070B889A0803878022876 -:1018400004D13078800980011B303070F01C1FAA51 -:1018500001900292009110A8008D0022C01E83B258 -:101860002020015DB889F4F737FF0028DED1039806 -:10187000B9890170090A417010A9888FC01C0885B8 -:1018800028E1787B18AA10753A7B012A02D0022A37 -:10189000CCD1FCE022887F231B011A4010AB1A87B1 -:1018A000802A4AD006DC102A10D0202A0ED0402AE6 -:1018B0000AD124E0FF3A013A65D0FF3A013A79D0E3 -:1018C000FF3AFF3A022A76D00525A2E02078C0062A -:1018D00001D5082000E010201C9004206A461074F6 -:1018E000002090821AA81DAA1EAB039601920290B6 -:1018F00000933B8A20461C9AFFF79AF984E0228BDA -:101900003B8A9646934268D10A221C92002839D11C -:10191000039801906046401E1FAA83B202922020C5 -:101920000091015D0022704600E0BAE0F4F7D4FEB9 -:10193000014618A801750B201AE0228B3B8A9646B7 -:1019400093424AD10C221C92002862D10398019044 -:1019500060461FAA401E0292009183B22020015DC2 -:10196000628C7046F4F7B8FE014618A801750D2088 -:10197000307010A8818F491C0185042168460174CC -:10198000218B818245E0238B3A8A9C469A4224D15E -:1019900012221C9200283CD1606A002813D0002239 -:1019A0006B4607C3638C07E0FEFF0000AC1300200A -:1019B00009F800000DE04BE02020015D6046F4F7DF -:1019C000A7FC18A9087513203070012010A90885FC -:1019D0001FE0398A228B914201D00425B6E01621FE -:1019E0001C91002815D11B98818802682046FFF7BA -:1019F00003FA18A9087500280BD11B983346016813 -:101A000080881AAA00F075F9054602281BD0042D1B -:101A100019D01B988088002811D06846007C0028C7 -:101A200004D004A82A99F1F7FAFD05460120694679 -:101A300008741B981B990068059000208880002D71 -:101A400048D0052D2ED06846007C032878D07DE054 -:101A500018211C91002806D0388A20832046B968B6 -:101A6000FFF7A0FAD5E72046183000902020015D4E -:101A7000237E01222046FFF7AFFA18A90875002837 -:101A8000ECD119203070012010A90885E6E72088E4 -:101A900001214902084010A90887FF38FF380228B1 -:101AA00006D0052510A92088098F884320804DE0A5 -:101AB000208F9849884290D116201C9038690028C0 -:101AC00005D06063B88A20870020608702E000208C -:101AD000C043208710A8008F7F21090102468A4356 -:101AE0000DD0782300220420B968FAF7DFFC38789B -:101AF000A07010A92088098F0843208002E0218867 -:101B0000814321806846007C002805D082484168D6 -:101B100004A8F1F784FD054618A8007D002815D01B -:101B20001C98707001203070208BB070000AF0702B -:101B300018A8007D3071052110A8018506E0FFE797 -:101B40007548416804A8F1F76AFD05467248017AB4 -:101B500020884005400E22D11B98808800281ED086 -:101B6000239A0026138810AA1385249A2A9B6F466D -:101B70004CC71B9A039412681AABFFF78DFA0546FF -:101B800002280CD00120694608741B982A99006825 -:101B9000059004A8F1F743FD05461B98868010A820 -:101BA000018D2398018028461EE600B597B00428D1 -:101BB00007D102206A461070019100216846F1F7B2 -:101BC0002EFD17B000BD10B5534C037800222168DC -:101BD000012B02D0022B42D126E00B78002B01D042 -:101BE000042B03D10A7122680321117021688388B4 -:101BF0000A79D200921D8B5221680A79D2000832EC -:101C00008918C2880A80216803890A79D2000A32B9 -:101C10008B52428920680179C9000C3142522168F7 -:101C20000879401C08711EE00A7482888A80216845 -:101C3000C288CA8022680189118122684189518144 -:101C4000C1682068C1606168F1F7E9FC01460228BB -:101C500007D02068007C002802D1002903D0812011 -:101C600010BD832010BD002010BD406B002800D0A7 -:101C7000012070478178012909D100880521C90216 -:101C8000884202D0491C884201D1002070470520BB -:101C90007047F7B586B00024684615460F46848124 -:101CA00005261AE004984178027809021143298038 -:101CB000811D019602940091417902790B02134330 -:101CC000C178827809020A43417800780902084302 -:101CD0003946F4F71DFB002806D104AA03A906988B -:101CE000FFF7BFF80028DDD0822800D1002009B01E -:101CF000F0BD10B51488844201D2052010BD172410 -:101D00001C701080421E581C491C09F09AF80020D3 -:101D100010BD0000FEFF0000AC13002030B50346EC -:101D2000002002460DE09C5C2546303D0A2D02D382 -:101D30000020C04330BD0A25684330382018521CAB -:101D4000D2B28A42EFD330BD70B50D46144608E0DA -:101D50000A2109F0DFF82A193031203A641ED177C0 -:101D6000E4B2002CF4D170BD10B5002310E0040AD9 -:101D700000020443A0B2CC5C44402006000F604047 -:101D80000407240C44402006C00C60405B1C9BB23E -:101D90009342ECD310BD000010B572B600F0DCF831 -:101DA00000280BD0EFF77CFAFAF7E1FD08F097FB7B -:101DB0006E490020C86288626D49086062B60020E2 -:101DC00010BDF3B5002501200007C06A81B0C043F3 -:101DD0000006000E04D167480068401C00D10125B0 -:101DE00072B600F0B9F8002802D062B60820FEBD35 -:101DF000EFF7ACF9EFF758FA5F4B604E00211A6825 -:101E0000CA40D2071FD00246CA40D20718D14AB2F0 -:101E1000002A07DA1407240F083CA408A400A41918 -:101E2000E46904E09408564FA400E419246892077A -:101E3000D20ED4402206920F012A04D0032A02D0E7 -:101E400062B65048FEBD491C2029D8D30198030032 -:101E500009F0A2FA142123232323232323230B0D88 -:101E60000F11131F1517191B1D2E002416E0012436 -:101E700014E0022412E0032410E004240EE00824FD -:101E80000CE009240AE00A2408E00B2406E00C24F4 -:101E900004E0052402E0072400E00624F0690121A3 -:101EA0000002000AC9070843F061002D04D009E0D0 -:101EB00062B601200003FEBD2C4D3348E862EFF707 -:101EC000F3F9A8622A49314808603149029808604C -:101ED000EFF7EAF9214608F0E9FAFAF70CFD08F005 -:101EE000EFFC08F065FB0198EFF7A8F9040062B673 -:101EF00003D0FFF751FF2046FEBD0020FEBD10B508 -:101F0000044600F029F8002800D0012020700020AD -:101F100010BD204908600020704710B50C461028FD -:101F200008D011280BD012280CD013280ED0012075 -:101F3000086010BD03CC083CFFF743FF0AE0FFF741 -:101F40002BFF07E02068FFF7DAFF03E01149206864 -:101F500008600020206010BD05480C4900688842D8 -:101F600001D10120704700207047000000050040AB -:101F7000640000200010001000E100E000ED00E02F -:101F800000E400E00110000000220000BEBAFECA1A -:101F9000980000200400002010B520380C460300F3 -:101FA00009F0FAF933A6AAAEB2B8BCC0C5E0DBE4CA -:101FB0001B1F23272C31373C41474D5054585C6040 -:101FC0006D71656974787C8084888C9094989C9FEE -:101FD000A2CACFE9F0F3D3D7F800206800F0DDF80B -:101FE000D6E0206800F0E1F8D2E0206800F0F5F8D3 -:101FF000CEE0207840B208F0C9F8C9E0207840B2BD -:1020000008F0E7F8C4E02078616840B208F0FAF818 -:10201000BEE0207840B208F00AF9B9E0207840B27A -:1020200008F015F9B4E02078217940B208F020F9E1 -:10203000AEE02078616840B208F04AF9A8E008F004 -:1020400056F9A5E0206808F05AF9A1E0207808F0D8 -:102050006FF99DE02068FAF738F899E02068FAF700 -:1020600038F895E021792068FAF73AF890E020688E -:1020700007F0D8FF8CE0206807F0D9FF88E02078CF -:1020800007F0D9FF84E007F0E3FF81E0207807F054 -:10209000E5FF7DE0207807F0F7FF79E0206808F0A1 -:1020A00010F875E0206808F012F871E0206808F078 -:1020B00014F86DE0206808F015F869E0206808F071 -:1020C00017F865E0206808F019F861E0206808F06A -:1020D0001AF85DE00846EFF751F859E0F0F787F994 -:1020E00056E0F0F7B4F953E02068F0F7BCF94FE0A0 -:1020F000206800F0E1F84BE0206800F0E9F847E0E4 -:10210000206800F0F0F843E02078A268616800F0F1 -:10211000F5F83DE0207800F006F939E0207800F08D -:1021200017F935E02078616800F027F930E0207871 -:10213000616800F03AF92BE02179207808F008FA7C -:1021400026E0206800F06BF822E02068FAF7FEFA3B -:102150001EE02068FAF7E2FA1AE007CC0C3C08F01F -:10216000F1FA15E0206808F044FB11E003CC083CCC -:1021700008F06FFB0CE0206808F065FD08E009E05E -:1021800003E0FFE708F077FD02E0206808F0AEFD0D -:10219000206010BD0120086010BD002101700846BC -:1021A00070470146002008707047EFF31081C9079F -:1021B000C90F72B60278012A01D0012200E0002284 -:1021C00001230370002900D162B6002A01D000204B -:1021D0007047012040037047E7E7EFF31081C9071C -:1021E000C90F72B600220270002900D162B6002029 -:1021F0007047F2E710B52848FFF7CFFF002803D05B -:1022000026A11D2008F0A7FF2348401CFFF7C5FFAB -:10221000002803D021A1212008F09DFF10BDF1B5B9 -:10222000224D6F6801261C48FFF7BFFF1A4C00289B -:1022300003D10026601CFFF7D0FF1D4A1D49012075 -:10224000506000BF00BF00BF00BF00BF00230B6095 -:102250004B60009B6B60106000BF00BF00BF00BF01 -:1022600000BF0868002802D148680028F9D04868F3 -:102270000028E4D1002E04D06F60601CFFF795FFAA -:1022800007E0601CFFF791FF0028D3D10248FFF759 -:10229000A4FF0020F8BDC2E79C0000207372635CBD -:1022A000736F635F6563622E6300000000E50040AA -:1022B00000E0004000E100405A495B4B0A685B497E -:1022C0009A42096801D18904890C01600020704795 -:1022D0005449554B0A6855499A4201D18004800CF3 -:1022E0004860002070474F494F4B0A684F499A4257 -:1022F00001D18004800C88600020704730B5494BC4 -:10230000494D1C684A4BAC4202D0102802D203E06F -:102310000E2801D3184630BDC30044481818016187 -:102320004261002030BD3F493F4B0A684049491C8B -:102330009A4202D0042802D203E0022801D30846C0 -:1023400070473C4A0121C00080180160002070479E -:102350003449354B0A683649491C9A4202D0042850 -:1023600002D203E0022801D308467047314A012116 -:10237000C000801841600020704770B5294A2C4B7E -:1023800014682D4E284D82005B1C9219AC4203D07C -:10239000042803D2116006E0022801D3184670BD5C -:1023A0008804800C1060002070BD70B51D4A204B61 -:1023B0001468214E1C4D82005B1C9219AC4203D064 -:1023C000042803D2106806E0022801D3184670BD25 -:1023D00010688004800C0860002070BD10B5134A9E -:1023E000164890600E200021C3009B1819615961A6 -:1023F000401C1028F8D300200F4A05E0022803D320 -:1024000083009B18196005E083009B181C68A404D6 -:10241000A40C1C60401C0428F0D310BD03490748DD -:102420008860704764000020BEBAFECA00F5014013 -:102430000820000000F0014000F8014000C0FFFF4C -:10244000FE48C07E7047FE4840687047FD48C07E29 -:102450007047FFB5F94E85B0706A346805686068EA -:102460000190306A0390298D0798401A80B202903B -:102470000898002804D0274638372046483002E024 -:10248000371D2846A0300090032038710598002899 -:102490001FD001287ED0022863D003287BD0EAA178 -:1024A000ED4808F058FE0898002806D0387903282F -:1024B00003D0E5A1E94808F04EFEA16A7069FAF779 -:1024C000B0FDB860216A606A814265D900990860F0 -:1024D00034E1306A002803D1DBA1E14808F03BFE7B -:1024E000288BE0494843421806980021002804D070 -:1024F0005043DD4908F00EFD411CA1610191AA88FD -:10250000D848002142430698002804D05043D649B9 -:1025100008F000FD411CE161306AD24A801CA062D3 -:10252000298BD04B5143019A891AD04A891809182E -:10253000A162AA7D01985A4340008018FF301930EB -:1025400020626062306A081AC949FF38153888422B -:10255000A9D2C84988427DD2BBA1C74808F0FBFD7B -:102560008BE0288BBF4AE16850430A180698002187 -:10257000002804D05043BC4908F0CCFC411CA161A8 -:10258000AA88B848002142430698002808D0504342 -:10259000B54902E03EE073E0CEE008F0BBFC411C30 -:1025A000E161306A002803D1A7A1B44808F0D3FD47 -:1025B000A620405BAB4A0028288BE16821D050431D -:1025C0000818A169401AA0622169A068A54A484379 -:1025D000A1694018A97D400051434018FF301730D1 -:1025E0002062A888E1695043411AA5480818606232 -:1025F000A06A316A401A9E49FF38553888423CD358 -:1026000051E750430818A169401A3168D638496823 -:102610004018D8E7284680300190C08C002802D0AE -:10262000306A002803D188A1964808F094FDA88854 -:102630008C49E3694843C01AA06201999C46CA8C40 -:102640002169A368521A4B43A16959186346534341 -:10265000C91800E011E0AA7D824B49005A4389184D -:10266000FF3117312162864941186162316A401A8F -:102670007F49FF3855388842C2D20120387112E7AD -:102680000898002803D03420005D00287ED1A88857 -:1026900074494843E169401A02994843A0622846B8 -:1026A00080300490C08C0028019825D0002803D0E9 -:1026B00065A1754808F04FFD04986A4AC18C0298DC -:1026C0000818E16948434000FF3017302062A888AD -:1026D0005043411A6A48081860626C4840680028F4 -:1026E00019D0A26A03990120511A614AFF3955395C -:1026F000914285D23871D6E6002802D0039800288E -:1027000003D151A1624808F026FD0198A16AD6388C -:102710000818A062D0E7FAF7F2F97269014610468C -:10272000FBF706FCA16A081A5149FF385038884265 -:10273000A5D2012009B0F0BD00980160009855496C -:1027400000684018F86028468030028A0799511ABC -:1027500009B2002904DD0599022901D0032100E016 -:10276000002179710E99002915D0028F002A1ED000 -:10277000418F4187A0352B7F491C4B4393420AD29E -:102780007979491E002906DD012100E00CE079710C -:10279000418F491C4187089838700898002808D054 -:1027A0003420005D002804D0022009B0F0BD0021D3 -:1027B000DFE708980121484020346075307FF27EC1 -:1027C0003946B37E9A4202D0FAF710FE04E00020A8 -:1027D000F076B07630607062002009B0F0BDF0B5E0 -:1027E0002A4F83B038680568416A2E460C68203647 -:1027F000717D00290AD0698E228D914206D1407ADE -:10280000002803D110A1244808F0A5FCFAF777F9B5 -:102810001E4F39684A6901461046FBF789FB3F683D -:102820000028796A096807D089880E4A51433A68B6 -:10283000D269891A08F06EFB698E2FE0B813002068 -:10284000B8000020E01300207372635C6C6C5F6C56 -:102850006D2E73302E630000310500003A05000034 -:10286000B7040000E204000040420F0033040000FF -:102870005C0800001D030000D4040000DC0400001C -:1028800094FBFFFFF50400001B050000A8000020DA -:1028900014050000FF0B000021060000228D131814 -:1028A000994202DB491C698602E0401C10186886C8 -:1028B000B07D002806D19421688E095B884201D141 -:1028C000401C6886388BFB4E401C388320464030C5 -:1028D0000190C1888088081A218D401E401887B257 -:1028E000C03418E03068F449406A002300794000A1 -:1028F000085A009323795B00C95A081881B2287DD1 -:102900000023FFF7A6FD00280FD001280FD0EB49C8 -:10291000EB4808F020FC6A8EB81A00B20028E1DA11 -:1029200001980821817005F0BDFF03B0F0BD688EED -:10293000401C6886EFE770B5DE4D09292B686A6890 -:102940007BD20C007C4424792419A7440463869626 -:1029500083A5A575A20000201062D17E042956D25D -:102960000B007B441B79DB189F4451510147516A8E -:102970000C68116808701168486010682030407D4C -:10298000002808D1FAF7BBF869680968096CFBF7F9 -:10299000CFFA002817DC6868228D0168498E9142C1 -:1029A00005D123468033998A8A1ADA8204E0891A8B -:1029B000962211530168498E21850268C16811640D -:1029C000C168416111E068680168098E228D8B1A27 -:1029D00022468032D3820168098E218501680B6C02 -:1029E000C3600B6C4361886C1062204606F0C8FB24 -:1029F000002821D0B3A1B74829E0D068506105F084 -:102A000088FA002818D0EF20AEA180001FE0ADA109 -:102A1000B1481CE0D07E042817D20100794409791E -:102A200049188F441212010B06F0E6FC002803D06F -:102A3000A4A1AA4808F08FFB70BD2DE005F09FFB14 -:102A40000028F9D09FA1A64801E09EA1A54808F062 -:102A500082FB70BDFDF7CBFD70BDD87E022806D08D -:102A6000D87E032806D0FF2096A1AB300EE0FFF7FA -:102A7000B6FE70BD00F013FC70BDD87E0228F6D003 -:102A8000D87E0328F6D0FF208EA1B83008F063FB73 -:102A9000F0E7FAF719F870BDFF208AA1C630D6E733 -:102AA000F3B50126834C904D81B00F46092945D2DC -:102AB00008007844007900188744042D38382D40E8 -:102AC000403838000121884800F0D0FB3946019891 -:102AD000FFF731FFE87E022826D160680468406A6B -:102AE0000768F9F7EAFFB988804A5143E269891A11 -:102AF000D639E162B72803D283200001081A02E028 -:102B0000081A7B494018E0627A48E16A814200D89D -:102B10000846E06205E00198FFF70DFFE87E022815 -:102B200002D128682030067503B0F0BD25600198F9 -:102B3000FFF701FF0020206003B0F0BDFF2061A17E -:102B4000623008F008FB03B0F0BD70B506460C46D5 -:102B500009291FD208007844007900188744040D21 -:102B600011110D1A1A1111000121634800F07EFBAA -:102B700021463046FFF7DFFE70BD3046FFF7DBFE33 -:102B800070BD4C4D5C4828603046FFF7D4FE0020F5 -:102B9000286070BDFF204BA1883008F0DCFA70BDC2 -:102BA000F0B5514985B0CA7E0026424C032A03D0B5 -:102BB0002831CA7E032A64D100252160002824D050 -:102BC00001280ED03FA14D4808F0C5FA2068002E1C -:102BD00005604562256054D049484560002005B035 -:102BE000F0BD0320887600E020BF2068C17E002968 -:102BF00003D0C17E827E9142F6D0C17E002902D0F0 -:102C000000268576E2E70126FBE700260327084633 -:102C10008F76C97E032903D0C07E00282DD02DE0F9 -:102C2000007F002803D127A1364808F094FA2068D5 -:102C3000067F684607714771F9F761FF0290FF2030 -:102C4000F530039001216846017069463046FAF775 -:102C5000CDFB2068007FFBF7F7F900280BD0206838 -:102C6000007FF9F731FF20680577C5768576056026 -:102C70000126456202E020BFEBE701262068857649 -:102C8000A4E70C2005B0F0BD10B5174800F04DFBCF -:102C9000194800F04AFB1C49002008751849487083 -:102CA00011494861144A506188769076014948601C -:102CB000086010BDA800002034B4010048280100BD -:102CC0005B0600007372635C6C6C5F6C6D2E73301E -:102CD0002E630000B6030000C3030000D60300000B -:102CE000DB030000E2030000B8130020E204000050 -:102CF00087F8FFFFEC060000E01300201E03000031 -:102D0000B80000207E02000008140020F8B5FF4E35 -:102D100005463068002401270004810FFC48006844 -:102D2000800F814204D0FF20FA49D03008F013FA16 -:102D30003068F94E0004810F30680006800F814230 -:102D400004D0FF20F349D13008F005FAF348C069F8 -:102D50003168800F0904890F884204D0FF20ED49B3 -:102D6000D23008F0F8F9EE480570EE4DEC76AC760E -:102D7000ED4EF476B476ED48077104606C627462CF -:102D80002C60EB4F346028467C6000F0CEFA304671 -:102D900000F0CBFAE74804757C706C617461AC7626 -:102DA000B476E54844600460F8BDE04908717047B6 -:102DB000F8B5DC490546CA7EDB48DF4C002A02D163 -:102DC000C27E002A03D0C97E022907D009E0DB4871 -:102DD0002160F9F725FE216808770AE0C17E002905 -:102DE00001D00C20F8BD2060D548F9F719FE216804 -:102DF0000877CF48456021680860D2484862284675 -:102E00000121BC30F9F790F9A035287F8007800FA9 -:102E1000401C28772068007F002803D1BD49CA489C -:102E200008F099F9F9F749FEC849884200D20846E6 -:102E3000C749401886B221680320C87604F084FF91 -:102E40002168086104F0A8FF01270025002826D08A -:102E500004F0A2FF21684A6A106008680121077027 -:102E60006846F9F7EAF868460078BA49000208F0BF -:102E700051F80F46F9F743FEF119FAF7D2F8216835 -:102E8000C86022680320107250721571107FD37EC3 -:102E9000111D967EB3420ED0FAF7A8FA0FE0F9F7AB -:102EA0002EFE3146FAF7BDF82168C8600868057043 -:102EB00008684770E5E7D576957615605562206815 -:102EC000058300202560F8BD7047F8B5954EF17E6A -:102ED000002903D19449C97E002901D00C20F8BDF6 -:102EE0000221F176914F934D77623560002438606E -:102EF0002C7500943979C0304A00974900798A5A74 -:102F00004000085A2346101881B222462046FFF797 -:102F1000A0FA002803D07F49904808F01CF92C61E2 -:102F20000120AC6028756C862C868D4884753968C4 -:102F3000088D401E088534830020F8BD10B57E48FA -:102F400001244068817E03290CD00168497800295A -:102F500006D0006A8349884202D9002405F03CF972 -:102F6000204610BD0024FBE77348406802681178D2 -:102F7000491C1170016A0068C26A914204D8007D40 -:102F8000012801D0012070470020704700207047C1 -:102F9000F8B5694D63482860416A00270C680068ED -:102FA000342126460F548036B17F002927D1007D79 -:102FB000032824D1F9F7A3FD29684A690146104680 -:102FC000FAF7B6FF00281ADD2D68674B6A6A296890 -:102FD000126892880091C9695A43511A07F09AFF02 -:102FE000218D401C4218009953480A862968B28AEC -:102FF0000B8ED21A12B2002A03DC0760F8BD2F60D4 -:10300000F8BD012220318A7521464031CA8889885D -:10301000514F511A228D491E89188EB20546C0346F -:1030200019E0496A09794900795A00220092028E12 -:103030002379007D5B00FB5A591889B20123FFF701 -:1030400008FA00280ED001280FD002280AD03149F2 -:10305000464808F080F829680868028EB21A12B251 -:10306000002ADEDA00202860F8BD28680068018E9A -:10307000491C0186EFE770B52F4900244D680628EA -:1030800076D202007A441279921897441820020EE0 -:10309000240D002000F08FF9EC76AC762C60002136 -:1030A00008466C6200F0E2F870BD1D480D680078BB -:1030B000EFF72AF9EC76AC762C606C6270BD0120DB -:1030C00000F079F90021084600F0D0F870BD2968B9 -:1030D0000320087570BD686A29680068CA698A603B -:1030E0008188214A51432A68D1600146C0310A8A49 -:1030F00002838A7B82754A8A82808A8AC280C98AD0 -:10310000018129680220087570BD31E000E400E00B -:1031100008E400E0C42C010018E400E000ED00E049 -:10312000A0000020B8130020E0130020B000002011 -:10313000B800002008140020A8000020A12A0100E7 -:103140004B2B0100A4000020C9020000F60500007E -:10315000BB0200001027000034B40100520300003D -:1031600028140020D9821300E204000007060000A2 -:10317000DD49DE4807F0EFFF70BD70B500280BD0C9 -:103180000024DB4D01280ED002282FD0EF20D64995 -:10319000C00007F0E0FF70BD00F06BF900210846A9 -:1031A00000F064F870BD686801684C70C47684767D -:1031B0000460D04E446201220021706800F063FF79 -:1031C00071680846C0318C72CC72FFF77EFE002811 -:1031D00003D0C549C84807F0BEFFF9F7DBFBC74875 -:1031E0006C600078EFF790F86C6070BD00F041F90A -:1031F0006868C4768476046000214462084600F062 -:1032000035F870BDBA494968CA7E022A08D10A68F1 -:103210001378002B04D150600968CA6A1018C8627C -:10322000704710B5B24A002952680BD0012906D068 -:10323000022906D0AC49B24807F08DFF10BD801EB0 -:1032400000E0401F106210BD08B50020C043694671 -:103250000880AC48C07E002801D0002008BD084688 -:1032600000F0F6F90028F9D0012008BD70B5A04C97 -:1032700005466268002908D0002A04D0FF209A4938 -:103280000D3007F068FF656070BD002A04D1FF2093 -:103290009549133007F05FFF0020606070BD38B5BE -:1032A000934C20680168497801291FD001216846A4 -:1032B000F8F7C3FE684600789349000207F02AFE3B -:1032C0002068426AC06812685118F9F7AAFE21689E -:1032D000C8608C4822680321824202D0108B0A28E1 -:1032E00010D2108B401C108351720DE07D21C068FC -:1032F000C900F9F796FE2168C86004F025FD216831 -:103300000861E6E702205072117200231371107FEA -:10331000D47E111D957EAC4202D0FAF767F838BD15 -:10332000D37693761360536238BDF8B5704C05467A -:103330001F27EE7E042E2DD230007844007900182D -:103340008744312801237148854203D0664970487B -:1033500007F001FF02202560A87600E020BF216869 -:10336000C87E002803D0CA7E887E8242F6D0CA7EFC -:10337000002A04D000228A760C27226010E0002266 -:103380008A760A604A6222600DE00120FFF708FC9D -:10339000074603E054495F4807F0DDFE002F02D0E6 -:1033A000E87EB042C5D1E87E002803D04E495A4895 -:1033B00007F0D1FEF8BDF8B54D4D01286A68516A95 -:1033C0000C6846D10879554940000B5A1068077DB2 -:1033D0000126032F06D0027D022A13D0007D01288A -:1033E00024D036E00027076110688760942000969B -:1033F000025BC420005D4000085AC01881B23B4601 -:1034000003201EE022468032D78C07610096C4203C -:10341000005D928A4000085AC01881B20023022041 -:10342000FFF717F8696809680E750CE0942000969C -:10343000025BC420005D4000085AC01881B200231E -:103440000120FFF706F8002803D02749344807F089 -:1034500082FEF9F79FFA29480078EEF755FF696870 -:10346000002008830B68228D5A86096820318875F0 -:10347000F8BDF8B51E4D002168680C46006842781A -:10348000002A01D0447027E00078002809D00121EB -:103490006846F8F7F7FD684600781B49000207F018 -:1034A00039FD6868426AC06812685118F9F7B9FDB9 -:1034B0006A68D060147103205072107FD37E111D92 -:1034C000967EB34202D0F9F791FF03E0D47694766A -:1034D0001460546268680483F9F75CFA074800785E -:1034E000EEF712FFF8BD0000C42C010056070000E3 -:1034F000A8000020B800002003070000A000002062 -:103500009D070000E013002010270000B8130020E2 -:1035100007020000130200001902000034B4010089 -:10352000BC060000F8B50024E948FEF73EFE00287E -:1035300025D1E84FC02026464643F51901462846C6 -:1035400007F0DEFC0120B8556C80E34900200870CC -:10355000E24A4A8080356962E149641C0870A962C8 -:10356000E049E4B208704A80A963032CE2D3D8484A -:10357000FEF733FED648FEF718FE002801D00C20D7 -:10358000F8BDFF211931D84807F0BAFCD64801210F -:1035900001704480D5490020087208750877D44925 -:1035A0008872CB48FEF719FE0020F8BD10B5C84858 -:1035B000FEF7F3FD002803D0CEA1282007F0CBFDB5 -:1035C000C348FEF7EAFD002803D0CAA12D2007F06A -:1035D000C2FDFFF7A7FF002803D0C6A1332007F0E4 -:1035E000BAFD10BD10B50446B948FEF7DEFD00284F -:1035F00001D00C2010BDBC490878002807D000205D -:103600000870B3482160FEF7E8FD002010BDB04807 -:10361000FEF7E3FD1F2010BD70B505460C46AC4813 -:10362000FEF7C3FD002801D00C2070BDAE4A5088C3 -:10363000A84202D11078002804D0A548FEF7CDFD9D -:10364000122070BDA2482260FEF7C7FD002070BDA9 -:1036500010B504469E48FEF7A8FD002801D00C20B6 -:1036600010BDA1480178002907D00020C043208068 -:103670009748FEF7B2FD122010BD40882080944884 -:10368000FEF7ABFD002010BD10B504469048FEF7D4 -:103690008CFD002801D00C2010BD2078002804D01B -:1036A0008B48FEF79AFD0C2010BD01202070884841 -:1036B000FEF793FD002010BD10B504468448FEF7C8 -:1036C00074FD002801D00C2010BD824A0021C020CA -:1036D0004843105C00280AD0C023002059435054AE -:1036E000881820607A48FEF778FD002010BD491C3C -:1036F000C9B20329EBD37648FEF76FFD1F2010BD3A -:10370000032805D2C0225043724A135C002B01D01B -:1037100012207047801808600020704710B5002202 -:103720000C46032809D2C02148436A490B5C002B90 -:1037300014D122704018606018E003280ED164484C -:10374000FEF733FD002809D167484188032902D1DB -:103750000178002904D05E48FEF73FFD122010BD1D -:1037600060605B48FEF739FD01202070002010BD2D -:1037700010B504465648FEF718FD002801D00C206D -:1037800010BD2088534A032804D2C0214843105C4E -:10379000002801D00020208000202188491C89B207 -:1037A0002180032900D300212180C0235943515C8B -:1037B00000290BD0401CC0B20328EED30020C04328 -:1037C00020804348FEF709FD122010BD4048FEF757 -:1037D00004FD002010BD70B505460E463C48FEF7BE -:1037E000E4FC002801D00C2070BD2888341D03287B -:1037F00004D303D0A04201D3002028800020361D2E -:103800001DD0394B33492A88521C92B22A80A242D9 -:1038100000D300222A80042A02D3A24217D301E057 -:10382000032A05D0C02672438A5C002A0FD002E02A -:103830001A78002A0BD0401CC0B2A042E3D300206B -:10384000C04328802248FEF7C8FC122070BD2048E3 -:10385000FEF7C3FC002070BD10B504461C48FEF7FF -:10386000A4FC002801D00C2010BD2078002804D032 -:103870001748FEF7B2FC0C2010BD01202070144840 -:10388000FEF7ABFC002010BD10B504461048FEF753 -:103890008CFC002801D00C2010BD217801200029CB -:1038A00002D0012905D008E061680A78002A09D011 -:1038B00003E061680A78002A04D00548FEF78DFC11 -:1038C0000C2010BD08700248FEF787FC002010BDD8 -:1038D000C00000205814002098160020FFFF0000B0 -:1038E000C1000020C6160020D8160020B8170020FE -:1038F000D81700207372635C6C6C5F64622E630087 -:1039000010B5282107F0FAFA10BD70B50546007809 -:103910000A0700090001120F1043287007290ED270 -:10392000080078440079001887440305030503075D -:103930000300062408E00C2406E0222404E000240E -:10394000F8A1572007F007FC687880098001204320 -:10395000687070BD00780007000F704710B5C01C7C -:1039600007F0F5FC10BD0A4610B5C11C104607F063 -:10397000EEFC10BD10B5093007F0E9FC10BD02786F -:10398000BF23C9071A40490E0A43027070470078E6 -:103990004006C00F704702785206520EC9010A4312 -:1039A0000270704770B50C460546C11C20460930B0 -:1039B00007F0CDFC20784006400E2070297849069B -:1039C000C90FC9010843207070BD70B515460E4679 -:1039D00004461F2A03D9D3A1A82007F0BCFB204628 -:1039E0002A463146093007F02CFA6078AD1D80096F -:1039F0008001A906890E0843607070BD70B5054648 -:103A000040780E468406A40E062C03D2C5A1B82029 -:103A100007F0A1FBA41FE4B21F2C00D91F242946E4 -:103A200022460931304607F00CFA204670BD70B5C9 -:103A300015460E4604461F2A03D9BAA1CC2007F02A -:103A40008AFB20462A463146093007F0FAF96078A9 -:103A5000AD1D80098001A906890E0843607070BD04 -:103A600070B5044640780E468506AD0E062D03D28D -:103A7000ACA1DD2007F06FFBAD1FEDB21F2D03D908 -:103A8000A8A1E12007F067FB21462A46093130460C -:103A900007F0D7F9284670BD0A78C2734A780274D5 -:103AA0008A784274C978817470470A78C2744A78F7 -:103AB00002758978417570474176090A81767047A9 -:103AC000C176090A017770474177090A8177704703 -:103AD000C175090A017670478175704720300279F7 -:103AE000C90652095201C90E0A43027170472030BB -:103AF0000279D206D20E49010A430271704710B50D -:103B00001F3007F019FC10BD417800788906890E36 -:103B10000007000F06D0012808D0022809D0062887 -:103B200010D10AE0891F1F290AD90BE00C2907D000 -:103B300008E0891F1F2903D904E0891F1F2901D824 -:103B400001207047002070474178007889060007FF -:103B5000890E000F042805D1062903D3252901D891 -:103B6000012070470020704770B401780907090FE1 -:103B700003292ED0052931D1411C827E0C46437E7B -:103B800011021943037FC27D1D02037EC67E1B0204 -:103B90001343827D407835438006800E22281DD154 -:103BA00006291BD31920C001814217D8FF26F436FD -:103BB000B54213D8002A11D0082A0FD88A420DD254 -:103BC0008B420BD8617F227F09021143814208D9C1 -:103BD00004E040788006800E0C2802D070BC0020E3 -:103BE000704770BC0120704710B5222107F086F99C -:103BF00010BD10B502788B07920892009B0F1A43F4 -:103C000002704278520952014270012908D00229FB -:103C100006D0032905D0FF2042A1E83007F09BFA27 -:103C200010BD01210A43427010BD10B502788B0708 -:103C3000920892009B0F1A43027042785209520177 -:103C40004270012907D0022905D0032904D035A1EB -:103C5000384807F080FA10BD01210A43427010BDB8 -:103C600000788007800F70470278EF23C9071A4059 -:103C7000C90E0A43027070474178C078C906C90E60 -:103C80000E2835D202007A44127992189744060918 -:103C90000C0F1215181B1E2124272A2D0C2929D0A0 -:103CA0002AE0082926D027E0022923D024E017297A -:103CB00020D021E00D291DD01EE001291AD01BE0E3 -:103CC000012917D018E0022914D015E0092911D0D4 -:103CD00012E009290ED00FE001290BD00CE00129D8 -:103CE00008D009E0062905D006E0022902D003E049 -:103CF0001B2901D8012070470020704770B5054688 -:103D0000C1700E2926D20800784400790018874433 -:103D100006131517191B1B151D1D1B1B1F150C2426 -:103D20001DE000007372635C756C5F7064752E63D8 -:103D30000000000001020000082410E002240EE050 -:103D400017240CE00D240AE0012408E0092406E011 -:103D5000062404E000249A499A4807F0FCF96878A0 -:103D6000400940012043687070BDC0787047C17140 -:103D7000090A01727047017AC2790802104370473C -:103D80004172090A81727047817A427A08021043AF -:103D90007047C172090A01737047017BC27A080239 -:103DA000104370474171090A8171704781794279E6 -:103DB00008021043704701717047007970474173E2 -:103DC000090A81737047817B427B08021043704768 -:103DD00070B4017AC37909021943431C857A1C46E1 -:103DE000467A2B023343657926792C023443C21C70 -:103DF000754E00798D1FB54215D8FF25F435AB42BD -:103E000011D800280FD008280DD888420BD28C4238 -:103E100009D8507A117A00020843B11D884202D8AD -:103E200070BC0120704770BC0020704710B5001DA9 -:103E300007F082FA10BD0A4610B5011D104607F0C2 -:103E40007BFA10BD4172090A81727047817A427A09 -:103E5000080210437047017170470079704710B530 -:103E6000001D07F081FA10BD0A4610B5011D10466D -:103E700007F07AFA10BD0A780273497841737047E7 -:103E8000027B0A70407B4870704710B50E3007F017 -:103E90006BFA10BD0A46014610B50E31104607F008 -:103EA00063FA10BD0A7882754A78C2758A780276FC -:103EB000C97841767047827D0A70C27D4A70027E61 -:103EC0008A70407EC870704710B5001D07F04CFA2C -:103ED00010BD0A4610B5011D104607F045FA10BD89 -:103EE0000A7802734A7842738A788273C978C173F8 -:103EF0007047027B0A70427B4A70827B8A70C07B6B -:103F0000C8707047017170474171090A817170472B -:103F1000C171090A0172704700797047817942794D -:103F2000080210437047017AC279080210437047B3 -:103F300001717047007970470171704710B5001D1D -:103F400007F012FA10BD0A4610B5011D104607F021 -:103F50000BFA10BD10B5001D07F006FA10BD0A4699 -:103F600010B5011D104607F0FFF910BD70B51546DC -:103F70000E4604461B2A03D91149144807F0EBF8F2 -:103F80002A463146E01C06F05CFF6078E9064009ED -:103F90004001C90E0843607070BD70B50546407899 -:103FA0000E46C406E40E1B2C03D90549084807F049 -:103FB000D2F82246E91C304606F043FF204670BD89 -:103FC000243D0100A10200007A0C0000F103000072 -:103FD000FD03000070B504460020A083208C1E461F -:103FE00048431546114606F0A3FF2084F0002946F9 -:103FF00006F090FF401C80B20146192269439202EC -:10400000E083914201DD401EE0837D2029460002CD -:1040100006F080FF401CA08470BD70B50A7BD206FC -:10402000D20E0A73002282758B181B7ADC075B089C -:10403000DD07E40FED0F2C195B08DD07ED0F2C19E0 -:104040005B08DD07ED0F2C195B08DD07ED0F2D195F -:104050005C08E307DB0F5B196508EC07E40FE41865 -:104060006B081B1984186374847D521CE318D2B248 -:104070008375052AD8D3D8B2252803D9E1A18A208F -:1040800007F069F870BD70B504460B462546264614 -:10409000214600202835C0368031032B0AD0002B62 -:1040A0003AD0012B41D0022B03D1A11C2846FFF7A7 -:1040B000B4FF70BD2880A871E871E8722873687336 -:1040C000A873A870E870287168716876A8832B4679 -:1040D00068842033987128859872E8752876E8738B -:1040E0002874D872187398731A752884FF22603563 -:1040F000AA709875088248828882C882088348839B -:104100004877C884A4221055088748872421085579 -:1041100060843070B07170BDC8848877A1882389AD -:104120000A462846FFF756FFBFE7C884F38A728A1B -:10413000A1882846FFF74EFF70BD70B504460346C0 -:1041400028348033054603290AD0002933D00129B9 -:1041500038D0022903D1A91C2046FFF75EFF70BDAD -:1041600000202080A071E071E07220736073A07362 -:10417000A070E070207160716076A0832146608439 -:104180002031887120858872E0752076E073207474 -:10419000C872087388730A752084FF226034A27085 -:1041A00088751883987618742421586148551877B3 -:1041B000A035287370BDA9882B890A462046FFF7D1 -:1041C00009FFC8E7586AA988C38942892046FFF7D2 -:1041D00001FF70BD70B5867D0D460446002E01D0EE -:1041E000252E01D9122070BD002A18D0287EE17D2D -:1041F00050430818252106F08DFEE1750846CA08CF -:104200004907490F834BAA18595C127A914308D089 -:10421000314606F07FFE491CCAB200200AE00020A9 -:1042200070BD2076002070BD002803D02118097CC5 -:10423000511ACAB22118497C91423AD32918097AF5 -:10424000C943CB07DB17D21A521E1206120E35D005 -:104250008B07DB17D21A521E1206120E32D04B07F2 -:10426000DB17D21A521E1206120E30D00B07DB17C4 -:10427000D21A521E1206120E2ED0CB06DB17D21AFD -:10428000521E1206120E2CD08B06DB17D21A521EAB -:104290001206120E2AD04B06DB17D21A521E120635 -:1042A000120E28D00906C917511A491E0A06120E05 -:1042B00026D0401C0528B7DB1F2070BDC00020762B -:1042C000002070BDC000401C2076002070BDC000E2 -:1042D000801C2076002070BDC000C01C207600200D -:1042E00070BDC000001D2076002070BDC000401DC4 -:1042F0002076002070BDC000801D2076002070BD9B -:10430000C000C01D2076002070BD70B50D4604466B -:10431000072904D9FF203BA15D3006F01CFFE0789F -:10432000502108406907490F88300843E070A078A1 -:10433000A72108401830A07060785E210840203026 -:1043400060702078BC2108404030207070BD017939 -:10435000490901D000207047002230B41146445C66 -:10436000491CE3076408E507DB0FED0FEB18640851 -:10437000E507ED0FEB186408E507ED0FEB1864088F -:10438000E507ED0FEB186408E507ED0FEB1864087F -:10439000E507ED0FA407EB18E40FE318D218D2B22B -:1043A0000529DCDB002A02D030BC0120704730BC7C -:1043B0000020704738B505460C466846FCF74EF8B5 -:1043C00000281ED069460020085620720921615637 -:1043D0000022411A00D549422035EB788B420FDC90 -:1043E000FF2B0DD0A17A491CC9B2A1722B79994239 -:1043F00002D8617A7F2903D160720020A072012265 -:10440000104638BD7372635C6C6C5F7574696C2E9A -:104410006300000044B40100F8B50024F74EFF200B -:10442000B470F0702546F64F06E0042D04D3FF204B -:10443000F4A1AB3006F08FFEFF212846A03148439F -:10444000FF213331C0194A1C0C540146FF3114546A -:1044500021310C754C75F178A94202D1B470FF215D -:10446000F170FF219D314A1C6D1C0C54EDB21454A7 -:10447000042DDAD30020FF21A0314143C919FF31B7 -:1044800081318C77401CC0B20428F4D3E048FFF798 -:10449000ABFB0021DE48FFF7E7FB0121DC48FFF71B -:1044A000A8FBDC49FF20087048708870C87008714C -:1044B0004871F8BDB0E71B20704710B4D04A002106 -:1044C000FF23A0334B439B18FF3381339B7F002B8B -:1044D00004D0491CC9B20429F2D30DE004290BD23F -:1044E000FF23A0334B439A180124FF328132947783 -:1044F0000170204610BC704710BC0020704730B4DB -:104500000025042825D2FF220146A0325143BC4A8F -:1045100089180B46FF3381339A7F002A19D0FF2474 -:104520003334621C655455541A46603A15755575F6 -:10453000B24AD478844202D19570FF20D070FF2017 -:104540009D304554FF319E310D709D7730BC012068 -:10455000704730BC0020704704280ED2FF2201466D -:10456000A0325143A64A8918FF318131897F002941 -:1045700003D0A8494871012070470020704710B44B -:10458000A449FF224979A03251439D4A82B089183B -:104590000A46FF322132937C6C462370D27C227112 -:1045A000237822795A40802A0AD022782223520680 -:1045B000520E5A435118016002B010BC01207047DE -:1045C00002B010BC002070479248FF214079A03112 -:1045D00048438B4981B041180846FF303330FF31E2 -:1045E0002131CA7C69460A7003780922097859404A -:1045F00080290ED0037869460B7009784906490E68 -:10460000491C914208D26A461178491CC9B21170FE -:1046100009E0002001B0704769460978090601D514 -:10462000002100E080210170012001B070470428C2 -:104630000ED2FF220146A0325143714A8918FF3140 -:104640008131897F002903D07249087101207047A8 -:104650000020704710B46F49FF220979A0325143FE -:10466000674A82B089180A46FF322132947C6B4631 -:104670001C71D27C1A701C781A7994420AD01A786C -:1046800022235206520E5A435118016002B010BC48 -:104690000120704702B010BC0020704738B55D485B -:1046A0000179FF20A0304143554808180146FF31E9 -:1046B00021318A7C6C4622700922FF303430037825 -:1046C0002478A34223D004786B461C701B785B06C9 -:1046D0005B0E5B1C934205D26B461A78521CD2B219 -:1046E0001A7006E06A461278120601D5002200E030 -:1046F00080220270087D401C0875087D497D884233 -:1047000003D140A1444806F026FD012038BD002019 -:1047100038BD4048FF210079A0314843384940184E -:10472000FF302130C17C807C814201D10120704763 -:10473000002070473748FF210079A03148433049B5 -:104740004018FF302130817CC27C092013464B4049 -:10475000802B0AD049065206490E520E914201D3CF -:10476000881A01E0511A401AC0B2704709207047F8 -:104770000022042813D2FF23A0335843204BC01833 -:10478000FF239F331B5C002B09D0FF300A702130C0 -:10479000027D437DD31A0B704275012070470020C3 -:1047A0007047042811D2FF22A0325043144A8018C7 -:1047B000FF229F32125C002A07D0FF302130027D99 -:1047C000407D101A08700120704700207047104982 -:1047D0000160704704280ED2FF220146A0325143E7 -:1047E000074A8918FF318131897F002903D009499F -:1047F000087001207047002070470000101800204A -:10480000141800207372635C646D5F712E63000086 -:10481000901E0020C70000205A020000AC49CA7850 -:10482000FF2A03D000210160084670478A78A94911 -:10483000012A02D001600120704700207047A6487D -:104840000178012907D001210170A4480178A0480E -:10485000C170012070470020704704280ED2FF224B -:104860000146A03251439E4A8918FF318131897F28 -:10487000002903D0994948700120704700207047F3 -:104880009349964BCA785B789A4206D18A78203948 -:10489000002A02D0016001207047002070478C4838 -:1048A0008E4AC1785278914209D1FF21C170801C93 -:1048B0000178002903D000210170012070470020F9 -:1048C00070478348854AC1785278914204D18078F4 -:1048D000002801D0002070470120704704280ED224 -:1048E000FF220146A03251437D4A8918FF318131B0 -:1048F000897F002903D07949C870012070470020C2 -:10490000704710B47549FF22C978A0325143744AE8 -:1049100082B089180A46FF328132147F6B461C70C0 -:10492000527F1A711C781A79FF3162403731802A20 -:104930000AD01A7822235206520E5A4351180160A7 -:1049400002B010BC0120704702B010BC00207047BC -:104950006248FF21C078A0314843614981B04118C5 -:104960000846FF309D30FF3181314A7F69460A7029 -:10497000037803220978594080290ED003786946CC -:104980000B7009784906490E491C914208D26A46C3 -:104990001178491CC9B2117009E0002001B07047BC -:1049A00069460978090601D5002100E080210170DF -:1049B000012001B070474948FF21C078A031484329 -:1049C00047494018FF308130417F007F814201D14B -:1049D000012070470020704704280ED2FF220146B4 -:1049E000A03251433E4A8918FF318131897F002925 -:1049F00003D03A498870012070470020704710B4F6 -:104A00003649FF228978A0325143354A82B089184D -:104A10000A46FF328132147F6B461C71527F1A7036 -:104A20001A781B79FF3137319A420BD06A461278D7 -:104A300022235206520E5A435118016002B010BC94 -:104A40000120704702B010BC002070472348FF21AE -:104A50008078A0314843224981B04018FF219D3120 -:104A6000095C6B4619700321FF309E3002781B7879 -:104A70009A4219D003786A46137012785206520E81 -:104A8000521C8A4205D26A461178491CC9B211707B -:104A900006E069460978090601D5002100E0802179 -:104AA0000170012001B07047002001B070470B4831 -:104AB000FF218078A031484309494018FF308130F8 -:104AC000417F007F814201D1012070470020704763 -:104AD00010180020F017002012180020C700002036 -:104AE00014180020F8B5FD4F0A46044600207978D6 -:104AF000FB4D0646002902D0012909D00FE0F949F3 -:104B0000497A00290BD0002A08D10120787005E0ED -:104B1000A97F002903D0002A00D17E700120797876 -:104B20002B23594349198B7F034311D0002A22D1EB -:104B30002A22A01C1F3106F084F966700420207020 -:104B40000120A07078782B2148434019867712E025 -:104B50002878012801D00020F8BD002A0BD166700A -:104B6000132020701C22A91CA01C06F06AF9A67153 -:104B70002E70DD48C6770120F8BDD948017800299C -:104B800001D080887047D9487047F8B5D44E0746A1 -:104B9000B07F00282DD13846FEF7DCFE002101252C -:104BA000D34C072824D202007A44127992189744F1 -:104BB0000305081F1F1F0A00217006E025702172DF -:104BC00008E0032000E002202070CA493846FEF7C2 -:104BD00015FF20723846FEF7DAFE6070C649384687 -:104BE000FEF7C1FEBD4CC54F20787F2807D101E0FC -:104BF0002172F8BDFF20C2A1543006F0ACFA207833 -:104C000038707F202070B577032002F0E7FEF8BDF2 -:104C100010B5002002F072FE002812D0FBF79CFBBA -:104C200000210120FBF7A0FABA48FBF7ACFBAE4C21 -:104C3000A06AFBF7ABFB2079032805D0022803D03C -:104C400006E000F0F3FD10BD01210020FBF716FC8B -:104C5000FBF7FBFBB04C6078002803D0FBF77DFF2F -:104C6000FBF7D9FB0320E07010BD70B59E4900280A -:104C7000CA8D08D0FF2A0DD25004000CC885FF2829 -:104C800008D9FF2005E0012A04D95008C88501D1C0 -:104C90000120C88591484268012A01D0002A01D12B -:104CA0000D224260D24317239B4C5A43637B3B2522 -:104CB000DB436B43D2184260C98D900C06F02AF991 -:104CC000617370BDF8B5944CE078022804D0E078A8 -:104CD000012801D00C20F8BD0020814A05462B2177 -:104CE000414389188D77401CC0B20228F7D3157054 -:104CF0006078002804D0FBF796FBFBF73FFF657058 -:104D0000794845778577C5778449257001228A7768 -:104D10000571A570CA760A774A77714E0146324608 -:104D2000736F7432B46FF66FD7688B60CC600E61AE -:104D30004F6112698A6105770020F8BD10B5764A87 -:104D40000023D3701371684B596318630120D0702E -:104D5000FFF7B8FF002803D069A1714806F0FBF9FE -:104D600010BDF1B582B00C2001906B480090C07866 -:104D7000012806D00098C078022802D00C2003B089 -:104D8000F0BDFBF7F0FA0020FBF7B1F8564C207F9E -:104D9000002837D0524920460F4682687437C368CE -:104DA000056946694A678B67CD67FE60806938612F -:104DB00000266677A677594DE87E002805D1287F22 -:104DC000002802D1687F00281AD0009800780028B7 -:104DD00016D02079032802D0022805D008E005214A -:104DE000504800F040FD03E003214E4800F03BFD39 -:104DF000A97E3846FBF7F3F80020019026770CE0F7 -:104E0000267703E00098C078022804D00098C07884 -:104E1000022828D00AE0002001900098C0780128DC -:104E200004D10099087300980221C170606B017869 -:104E3000002903D00178001DFBF714F9206B0178DD -:104E4000002906D0384A401CFBF777FE0099012064 -:104E500048700298A0623548FBF717FAFBF78EFA04 -:104E6000019803B0F0BD00990120C8700C2003B078 -:104E7000F0BD70B5FBF777FA274CE078022803D035 -:104E8000FBF77CFA0C2070BD012017496073C885C0 -:104E90000220FBF765FA2648FBF739F9254E002575 -:104EA000A0780321401C06F035F8A170885D012828 -:104EB00044D06D1CEDB2032DF2D3FFF7A9FE20798B -:104EC000002809D0012807D002283DD003283BD074 -:104ED0000BA1194806F03FF9002070BDD00000205A -:104EE000B41E0020F41E0020341F0020FFFF00002D -:104EF000D41E0020DD1E0020D61E0020FC1E002037 -:104F00007372635C6C6C5F64645F7363616E2E6369 -:104F1000000000006C1F0020541F0020141F002000 -:104F200051030000941F00206F1F00204CB40100AB -:104F300052B401002F1F0020EA030000C8B2FC4950 -:104F4000085CFBF7F6F8B8E7EEF762F8C4E770B56F -:104F5000F84C0125A577E37F002B01D03A2070BDE6 -:104F60000026002802D1A07B884209D1A173667770 -:104F70001146F14806F0EBF96577F04805702577A2 -:104F8000A677002070BD024600200123E949002ACF -:104F900003D0012A03D0122070478B7400E088747C -:104FA0000B774A767047E34A032800D151611076A7 -:104FB0000120107700207047E049012803D0032822 -:104FC00001D0002000E0012008717047D948017F1E -:104FD000002903D0407E002803D170474079002883 -:104FE000FBD00120704710B5FBF709FAFBF7FCF97D -:104FF000FBF708F9FBF7AAF9D04C6078002805D038 -:10500000FBF711FAFBF7BAFD002060700120207356 -:105010000220E070FBF7B2F9002010BDC7494871CB -:10502000704710B500F002FC10BDF0B5C44EC34D82 -:1050300083B0002810D0C348FEF766FD002804D1D5 -:10504000C048FEF781FD002806D0BA4C207903281D -:105050000DD1A07F00280AD0E87805286BD2010086 -:105060007944097949188F44666666F7F600E8784E -:1050700005287AD201007944097949188F44757559 -:105080007502EE00AF48FEF765FCAD498870AE488A -:105090000190807F002803D1FBF736F8002800D06C -:1050A000012000906878002813D00526761EF6B2FD -:1050B000FBF785FD0746022805D1002EF6D1A3494E -:1050C000A34806F048F80098002810D1012F0ED010 -:1050D00000909B4F9F4EB878072871D20100794409 -:1050E000097949188F446DFE056C6C6C280001200D -:1050F000EEE76878002803D0FBF795F9FBF73EFD53 -:105100008F48FBF7ABF9002801D17F203870FBF7FF -:1051100093F9009800280AD02079012801D00228AC -:1051200005D1FBF76FF88748FFF72FFD37E2FBF754 -:1051300069F8FFF76DFD34E26878002803D0FBF7CB -:1051400072F9FBF71BFD7E48FBF788F9002801D1B7 -:105150007F203870FBF770F90098002879D020790B -:10516000022803D001287AD047E221E27548FFF7F0 -:105170000CFD012002F0C2FB00286ED07649714878 -:10518000FEF710FC7448FBF7FEF8607F00280ED095 -:105190006848019902898A824289CA828089088383 -:1051A00031466D48FEF7DAFB00206077A0770121D9 -:1051B0000846FBF763F9FBF703F90520E870F0E117 -:1051C0005BE16878002803D0FBF72DF9FBF7D6FCEC -:1051D0005B48FBF743F9002801D17F203870FBF7CB -:1051E0002BF90098002834D02079022808D0012813 -:1051F00035D0032837D05549584805F0ACFFD0E1E9 -:105200005048FFF7C2FC012002F078FB002824D0B0 -:1052100051494C48FEF7C6FB4F48FBF7B4F8607F96 -:1052200000280ED04348019902898A824289CA82A5 -:105230008089088331464848FEF790FB002060775C -:10524000A07701210846FBF719F9FBF7B9F805200B -:1052500001E10EE103E0BFE1ADE1B3E022E1394855 -:10526000FFF793FC9BE137482168C2780B7F9A4295 -:105270001DD102794B7F9A4219D142798B7F9A4294 -:1052800015D18279CB7F9A4211D10A462032C37957 -:105290001778BB420BD1037A5278934207D100783A -:1052A000CA7E4006C00F904201D1012000E00020DC -:1052B0006279012A30D0002800D138E7022002F0BC -:1052C0001DFB00287ED0012002F088FB22491D48EA -:1052D000FEF768FB2068018B1F48FEF7F9FB20688A -:1052E000817D00E03CE01C48FEF7F6FB1A48FBF726 -:1052F0004AF8607F002866D00E48019902898A82A8 -:105300004289CA828089088331461348FEF726FB0A -:1053100000206077A0779BE00028CFD109481C319E -:10532000FEF721FB0748FEF732FB2168C876C5E788 -:105330004FB40100341F00203C1F0020541F0020E8 -:10534000D00000206C1F0020141F0020004F01001F -:10535000D4040000281F0020941F0020CC0500006A -:105360006878002803D0FBF75EF8FBF707FCF948E4 -:10537000FBF774F8002801D17F203870FBF75CF848 -:105380000098002875D0FAF733FE002871D02079F4 -:105390000328F14804D0FFF7F8FBFAF733FFFEE0EB -:1053A0002168C2780B7F9A4220D102794B7F9A42C2 -:1053B0001CD142798B7F9A4218D18279CB7F9A4255 -:1053C00014D101E056E043E00A462032C379177851 -:1053D000BB420BD1037A5278934207D10078CA7E40 -:1053E0004006C00F904201D1012000E00020627908 -:1053F000012A32D0002800D199E6022002F07EFA7C -:10540000002837D0012002F0E9FAD449D248FEF74B -:10541000C9FA2068018BD148FEF75AFB2068817DCC -:10542000CE48FEF759FBCD48FAF7ADFF607F002864 -:105430000ED0CB4901980A8982824A89C282898921 -:1054400001833146C548FEF789FA00206077A077CE -:105450000120E0770620E870A3E00028CDD1BE4807 -:105460001C31FEF780FABC48FEF791FA2168C87635 -:10547000C3E7C2E000F0DAF993E06878002803D0CF -:10548000FAF7D1FFFBF77AFBB248FAF7E7FF0028FB -:1054900001D17F203870FAF7CFFFFAF7B3FEFFF79C -:1054A000B7FB7EE0AC48FEF755FAB070AA48AB49AE -:1054B000C3784A7A93421CD103798A7A934218D1ED -:1054C0004379CA7A934214D183790A7B934210D1EB -:1054D000C3794A7B93420CD1037A8A7B934208D1E9 -:1054E000007809784006C00FC909884201D101241B -:1054F00000E00024FAF786FEB07804283ED1002CA4 -:105500003CD09448FAF7AAFF002801D17F203070E0 -:10551000FAF792FF287B002802D00020FFF7A5FBB6 -:105520000120904C28738C4F607A002837D10420DA -:10553000E0723846FEF72BFA002801D0012800D18E -:10554000207389493846FEF70EFA88493846FEF737 -:1055500087FAE0741F2801D91F20E0743078844F47 -:105560007F2804D1FF208349543005F0F4FD3078C2 -:1055700038707F2030700120607210E07548FAF7B3 -:105580006DFF002801D17F203070FAF755FF287B8E -:10559000002802D10120FFF768FB00202873FFF7E5 -:1055A00037FBE87802283DD0E87804282DD127E0A1 -:1055B0007049714821E66878002803D0FAF733FF74 -:1055C000FBF7DCFA6348FAF749FF002801D17F2096 -:1055D0003070FAF731FF10E05E48FAF73FFF00281D -:1055E00001D17F203070FAF727FF287B002802D1F5 -:1055F0000120FFF73AFB00202873FAF703FECEE7FD -:1056000037205C49400105F0A6FD2879002809D023 -:1056100001280ED0022807D0032810D0554957483A -:1056200005F099FD03B0F0BDE878032807D003B07A -:10563000F0BDE878062802D0E8780528F7D10120E7 -:10564000FAF7D2FF03B0F0BD70B54D4CE0780728F3 -:105650005FD201007944097949188F445A5A5A5A3D -:105660005A030B003C48FAF78EFEFAF7EEFE0420D0 -:10567000E07053E0FAF7C3FEFAF7B6FEFAF7C2FDA0 -:10568000FAF764FE012626730220E070FAF776FE30 -:105690003C4D2878002803D036493B4805F05BFD97 -:1056A0000020A8702E4800684188A980C17EE97159 -:1056B000818B2981C18B6981018CA9818188E982D3 -:1056C000C188298300896883607928772F48304909 -:1056D000807EA8732F4805F03AFE6078002803D03A -:1056E000FBF76DFA012808D0687F40084000687712 -:1056F0002E70022002F072F910E0687F3043687764 -:10570000FBF776FA697F4000C907C90F0143697743 -:10571000EEE775201749000105F01DFDE07802282D -:1057200016D0E078032806D0E078042803D0114989 -:10573000194805F010FD2079002809D0012807D06C -:1057400002282DD003282BD00A49144805F003FD68 -:1057500070BD0000D00000206C1F0020941F0020AE -:10576000341F0020F41E0020011F0020081F00200D -:10577000271F0020004F01009E060000F5060000D4 -:10578000541F0020B41E002029070000141F002011 -:10579000281F0020C31E00205607000062070000DB -:1057A0000120FAF721FF70BD10B55C4CE0780528A8 -:1057B00020D201007944097949188F441B1B1B1919 -:1057C00002005748FAF74AFE002802D154497F20C8 -:1057D0000870FAF731FE207B002802D10120FFF784 -:1057E00044FA00202073FAF70DFDFFF711FA01E0EB -:1057F00000F01CF8E078022813D0E078032803D0EA -:105800004849494805F0A7FC2079002809D001281B -:1058100007D0022806D0032804D04249434805F0A7 -:105820009AFC10BD0120FAF7DFFE10BD10B5FAF7A3 -:10583000E6FDFAF7D9FDFAF7E5FCFAF787FD374CF4 -:105840006078002805D0FAF7EEFDFBF797F9002005 -:105850006070012020730220E070FAF78FFD0020B5 -:1058600002F0BCF810BD70B5314C054626466036D6 -:105870007434032943D0052940D1FEF741F80521AE -:105880002846FEF742F8B17E2846FEF778F8214612 -:105890002846FEF763F8274C284621680F31FEF7AB -:1058A000FBF8216828461331FEF7FFF82068817D58 -:1058B0002846FEF711F92068018B2846FEF708F903 -:1058C000206881882846FEF7F7F82068C1882846B6 -:1058D000FEF7F6F8206801892846FEF7F5F82168FA -:1058E00028460A31FEF70BF92068817E2846FEF72C -:1058F000F5F80A4841792846FEF7F9F870BDFDF73A -:10590000FFFF03212846FEF700F8B17E2846FEF788 -:1059100036F821462846FEF721F870BD541F0020B6 -:10592000D0000020004F010099070000A5070000EB -:10593000B41E0020341F0020F8B5FEF7FBFE04461D -:10594000FEF7BFFFF74E0546F0682030407B002889 -:1059500026D0012867D0022869D0032871D0FF2003 -:10596000F1A1793005F0F7FB3069F7220178114099 -:105970000170F2682032937BDB071B0F1943FB2376 -:1059800019400170D37BDB075B0F19430170577B14 -:10599000EF23022F60D0012F63D0032F65D06AE080 -:1059A000E548FEF76DFF002827D030690090F168C8 -:1059B000088DC9884018801D87B20098FEF7D5F978 -:1059C000012805D00098FEF7D0F9002808D00FE094 -:1059D000F06839468030C7850098FEF733FA07E053 -:1059E000F06839468030406A87800098FEF7E7F912 -:1059F000F168032020314873B6E7CF48FEF72AFE4E -:105A0000002804D0F0685321095C002907D0CA4857 -:105A1000FEF7DDFEF168012020314873A4E7022182 -:105A200020304173A0E7C448FEF7D1FE9CE7C2488E -:105A3000FEF710FE002897D1FF20BBA16B3008E0D5 -:105A4000FFE7BD48FEF71CFF00288DD1FF20B6A15F -:105A5000733005F080FB87E7012C08D8002D06D0B5 -:105A600009E06D1E2C4302D105E0002C03D0194043 -:105A70001023194300E019400170D17D002915D091 -:105A8000517B012912D0AD48FAF77DFCAC480121C9 -:105A90000176F268116E526E42610161A749326966 -:105AA000FAF7D7FF0020FAF7E3FF03E0FAF76BFC01 -:105AB000FBF701F801210846FAF7E0FC03203070FB -:105AC000F8BD08282FD203007B441B79DB189F44C4 -:105AD00003060B0E11152528002926D023E00229E4 -:105AE00023D0032921D01EE007291ED01BE008295E -:105AF0001BD018E00A390B2917D914E00D2914D04E -:105B00000C2912D0002A04D00D290CD315290CD948 -:105B100009E0112907D3152907D904E0092904D080 -:105B200001E0012901D0002070470120704730B505 -:105B3000054683B08048FEF771FE002803D17AA1A4 -:105B4000804805F008FB774C2069FEF74DF80321EB -:105B50002069FEF76AF82069EF2201781140017090 -:105B60002946FEF7CBF80D2D76D22800784400792F -:105B7000001887441F1606448080840E7280848437 -:105B800060006848C16800698031497FFEF763F9A9 -:105B900075E06448C16800698031497AFEF7CCF944 -:105BA0006DE06048C16800698031896A491CFEF770 -:105BB0003DF964E05B4CE0688030406A817920699F -:105BC000FEF7F9F8E0688030406A01892069FEF745 -:105BD000E9F8E0688030406A41892069FEF7C7F83B -:105BE000E0688030406A81892069FEF7C9F8E06882 -:105BF0008030406AC1892069FEF7CBF83FE0494C0C -:105C0000E0688030416A2069091DFEF728F9E068E4 -:105C10008030416A20690C31FEF72DF9E068803050 -:105C2000416A20691E31FEF730F9E1682069803150 -:105C3000FEF738F923E03B4CA06901782069FEF7B4 -:105C400061F9A06981882069FEF75EF9A069418841 -:105C50002069FEF75DF912E00DE000200090694632 -:105C60000190087801210843694608702D480069B1 -:105C7000FEF764F903E02CA1334805F06CFAFEF757 -:105C8000DEFD002803D128A1304805F064FA0C2D70 -:105C90000ED0072D0ED0012D0AD0002D08D0022DD8 -:105CA00006D020480021C068403041810121817325 -:105CB00003B030BD1B480021C0684030018203B0F2 -:105CC00030BDF0B5174C8DB02079C0077ED060791B -:105CD00000287BD16069C0780E2878D20100794411 -:105CE000097949188F44737306733D5DE25C73FD57 -:105CF0007334FCA5E06854210A5C2030417D01200A -:105D0000FFF7DFFE00284BD16069FEF7A6F8E168D7 -:105D10009E22505402223520425400204031887483 -:105D20008873EFE1D80000207372635C6C6C5F6D68 -:105D300061737465722E6300E8000020E21F00208A -:105D40000820002083060000C7060000CD060000E2 -:105D5000E0682030C17C0A297ED10021C1750D2167 -:105D60001DE0E0683321095C0E2975D1A421095892 -:105D700040884988814203D0FAA1FE4805F0EBF93A -:105D8000E0688030416A60692631FEF7A2F8E16878 -:105D900060698431FEF7ADF8E06811212030C174EC -:105DA000B0E1E1683320405C112855D180318C4648 -:105DB0004B6AF14810260022082168440E33B51AB8 -:105DC000ED18203DEF7F4770AD7F01E0A2E17AE161 -:105DD0008570801C491E921C0029F0D161464B6AD7 -:105DE00003A810260022082103301E33B51AED182F -:105DF000203DEF7F4770AD7F8570801C491E921C4F -:105E00000029F3D16846FCF746FA08AD8DCDE1686C -:105E100000260E664E660D4670318DC10126203576 -:105E2000EE75D64E8DC6D64805F09EFA1320E8745E -:105E300068E1E0683321095C112901D00E293AD1CB -:105E40004030007D002836D16069FEF773F8E168C4 -:105E50000B460A46803300E02DE0187200254031E1 -:105E6000CD748D73586A51884088884203D0BDA193 -:105E7000C44805F070F9E06801468030426A157048 -:105E8000826B1378002B03D0D920B6A1800033E0B9 -:105E90004B88D380836B027A1A71826B1572836B85 -:105EA0000B221A70806B4988418008E1E068332139 -:105EB000095C152902D00220607123E1014600250A -:105EC0004031CD748D73A42109584088498881429E -:105ED00003D0A4A1AC4805F03EF9E068014601E01A -:105EE0002CE094E080314A6A15708A6B1378002B9D -:105EF00005D071209BA1C00005F02DF9DFE003461D -:105F000040331E7D002E0BD01D754388D3808A6BD5 -:105F100015718B6B0C221A70896B40884880CEE01B -:105F20004388D3808A6B15718B6B01221A728B6B3D -:105F30000B221A70896B40884880C0E0E0685421C9 -:105F40000A5C2030017D0020FFF7BBFD00280DD149 -:105F5000E06854210A5C2030C17C0720FFF7B1FDC6 -:105F6000002803D16079012108436071607900281D -:105F70004CD1E0684030807D800715D46069FDF722 -:105F8000CBFFE1684031C8756069FDF7C7FFE16884 -:105F9000403108836069FDF7C6FFE16802224031A5 -:105FA0004883887D10438875E068014640318A7DCA -:105FB000D20716D10A7D2030017D0020FFF781FD38 -:105FC000002803D167A1714805F0C5F8E0680121F8 -:105FD000342211540623A02213544030817400212E -:105FE0000182E06801462031CA7C012A03D10022E7 -:105FF000CA744E210A54A421095840884A88824212 -:1060000004D1087806287DD1002008707AE0E06885 -:1060100054210A5C2030C17C0620FFF752FD002885 -:1060200003D160790121084360716079002869D14A -:1060300069466069FDF793FF68460078C107C90F9C -:106040006846017004D0E06801214030017703E028 -:10605000E068002140300177E06800254E210D54B2 -:10606000A421095840884988814203D03DA148486D -:1060700005F071F8E06802468030416A0D70816B6E -:106080000B78002B04D037A1424805F064F816E0E5 -:106090005388CB80816B6B460D71816B1B880B81A4 -:1060A0006B465B884B816B469B888B816B46DB889C -:1060B000CB81836B06211970806B51884180E06829 -:1060C0002030C5741EE0E06854210A5C2030017D58 -:1060D0000020FFF7F6FC002803D160790121084376 -:1060E0006071607900280DD16069FDF73EFEE168BE -:1060F0008922505405223420425400204031088225 -:1061000001208874E2680023916ED06E491C5841CA -:106110009166D0660DB0F0BDF8B5FAF770F9FAF7F0 -:1061200063F9FAF76FF8FAF711F9FAF7C4FCFAF71E -:1061300025F9194CE06820300079012801D1FAF7DF -:106140007BF9E068012502462032917D002908D1C3 -:10615000E178CB0701D1890703D59575012101F0BD -:10616000F9FB1BE07372635C6C6C5F6D617374654B -:10617000722E630021030000FFFFFFFF08200020B4 -:10618000212000205F03000083030000C303000000 -:10619000F1030000F6030000D8000020E07900269B -:1061A00000284FD100F06DFDF848FEF737FB0028BE -:1061B00048D06079002845D1E06854210A5C20303D -:1061C000417D0120FFF77DFC00283BD1E0680246BD -:1061D0008032117F002901D0022051E00346203394 -:1061E000D97C05292AD0E927FF000C292DD00D29BB -:1061F00029D0132943D01B7D012B4BD0052B42D036 -:10620000526A1378002B61D0528843889A425DD13C -:106210004030027D0020FFF754FC00287FD0E0686A -:10622000A42109580978891E062978D20A007A44DF -:106230001279921897443A3C7373658CD449D548C7 -:1062400004F089FFB6E00B201AE0F5F71AFF0C28DE -:106250007DD3E06808218030406A1E30F5F712FFD8 -:10626000002806D0E06804218030F5F70BFF0028F5 -:1062700003D1C749384604F06EFF032000E0062032 -:10628000FFF755FC96E00720FFF751FCE06820304F -:1062900006758FE00C20FFF74AFCE06801464030AD -:1062A000827D2A43827520310E7583E000200BE049 -:1062B0002030C17D00290AD0007E002803D1B449D6 -:1062C000B54804F048FF0A20FFF731FC27E0F5F756 -:1062D000D8FE0C2823D3E06808218030406A1E30A5 -:1062E000F5F7D0FE002806D0E06804218030F5F7ED -:1062F000C9FE002803D1A649384604F02CFF03202C -:10630000E2E74030807D800709D10C20FFF70FFCC9 -:10631000E068403046818573817D294381759B48C3 -:10632000FEF77CFA002845D0E06854210A5C203052 -:10633000C17C0020FFF7C5FB00283BD0E168AC2002 -:10634000405C002836D0E0690078002802D031E0B7 -:106350000820B9E7088D0A282CD905220A31206ABD -:1063600004F042FD002822D0E0688030816A08787D -:1063700000280CD00522491C206A04F035FD0028B5 -:1063800018D1E0688030806A0078002806D1E06883 -:10639000216A8030806A401C04F0CEFFE0688030C3 -:1063A000806A0178491C01700120FFF7C0FBE0689A -:1063B000A0300673E078C007E06802D040308680E5 -:1063C00003E040308188491C8180E0689C21095CA1 -:1063D000002908D154210A5C2030417D0120FFF7BB -:1063E00070FB002804D0E06840300189491C01811D -:1063F000E0793D21002804D0E0684030817045708C -:106400005AE0207A02280AD001280AD060790028B0 -:106410001AD0420701D4C2060AD51E21ECE7162184 -:10642000EAE7E0689E21095C40308170457043E0F6 -:106430000207E1D4C10705D1800703D45449574866 -:1064400004F089FE2A21D7E7E06802464032917BBA -:10645000002905D05389591C518191898B4213D24F -:10646000917C002905D0118A4B1C13829389994293 -:106470000AD21789D3889F4203D39C21095C002943 -:1064800002D191898F4203D322209070557013E07E -:106490003621095C0029918805D0994209D308204A -:1064A0009070557008E0062903D33E209070557017 -:1064B00002E05178002908D0E06801462031CE740E -:1064C0000E758E752570022101E02570002101F006 -:1064D00041FAF8BDF8B50C4616466946FDF710F9C5 -:1064E000002801D00020F8BD009800250246803029 -:1064F000816B0B78072B1CD0A71C0C2B29D00B2BE6 -:1065000034D0062B4CD01146A031087C0028EAD0AC -:10651000657012202070087C002808D0A2320D740B -:10652000108A6080508AA080087C0028F7D1012062 -:10653000F8BD002EFBD1657007212170816B0A2206 -:10654000A01C091D04F07DFC00988030806B057054 -:10655000EDE7002EEBD165700C212170816B8A88EC -:106560006280C988A180806B0570E0E7002EDED1D3 -:1065700065700B212170816B8A883A80CA887A8085 -:106580000989B980806B0570D1E70000E800002020 -:1065900064610100BE0500007905000032020000C0 -:1065A000002EC4D1657006212170816B8A883A80E3 -:1065B000CA887A800A89BA804A89FA808A893A81A7 -:1065C000CA897A81806B0570B1E7FE48007801289E -:1065D00001D00C2070470020704770B5F94C05467B -:1065E0002078002803D0F849F84804F0B4FD0020D2 -:1065F000A5616072012020702078012803D0F24943 -:10660000F34804F0A8FD70BDF8B5EE4C21780129DF -:1066100001D00C20F8BDE0608030807AFEF707F8EA -:1066200000283AD0E0688030807AFEF757F90028D9 -:1066300033D0E0688030807AFEF7CCF800282CD088 -:10664000E0688030807AFEF708F9002825D0F9F755 -:106650008AFE0026E6710120F9F749FCE068014650 -:1066600040318A7B002A03D04A898B899A4211D211 -:106670008A7C002A03D00A8A8B899A420AD20B8923 -:10668000CA88934206D236231B5C8988002B06D029 -:10669000914206D30120A0703BE01220F8BD0629EC -:1066A000F8D2A6701330F9F7F0FDE0680F30F9F773 -:1066B0002EFD0320F9F754FEE06805462030017EE8 -:1066C000002902D1C07D002809D0294670318EC929 -:1066D000C0488EC02946C048803104F045FE98204D -:1066E000405BA91C401C82B228462830FDF772FD91 -:1066F000002803D0B449B94804F02DFDE0684030CB -:106700000078F9F716FDF9F727FE01210020F9F7C7 -:106710002BFDE67026716671A6712672022020702C -:10672000E06880300683F9F729FE0020F8BD10B537 -:10673000F9F719FEA34C2078022803D0F9F71EFEC2 -:106740000C2010BDA078002802D0FFF7E5FC17E070 -:10675000F9F736FEFFF7F0F8E068203000790128FD -:1067600001D1F9F772FE607A002809D0012809D01A -:10677000022805D0032805D09349994804F0EBFC82 -:10678000002010BDECF744FCFAE770B505468030F8 -:10679000018B2C46491C01834034A188491CA180EF -:1067A000A17B002902D06189491C6181A17C00295B -:1067B00002D0218A491C2182007F002807D1352080 -:1067C000415D227D0120FFF77CF9002802D020895D -:1067D000401C2081284600F0EBF9002070BD79496B -:1067E00048727047774A1162D0617047F8B5754CAE -:1067F0002078032803D074497A4804F0ACFCE1689F -:1068000004272031887A0025002803D08D72207952 -:1068100038432071206901260278D2439207002A6A -:106820001FD1CA7A002A1CD1CE72217902221143CB -:106830002171FDF79AFA062802D00B2811D10AE03F -:10684000E06801462030C27C132A0AD100228A6601 -:10685000CA66067605E0E0682030C17C0D2900D1CB -:1068600005762079400704D5E0682030407D022875 -:1068700005D06079002802D1A079002802D0FFF766 -:106880004BFC2AE05848FEF73CF8002801D0657020 -:1068900002E0667055486061E0682030007E0028A4 -:1068A00011D05348F9F76FFD4A480576E268916EBA -:1068B000D26E426101614E4A6169FAF7CAF801205D -:1068C000FAF7D6F804E06069F9F75DFDFAF7F3F836 -:1068D00002210020F9F7D2FD2770207801280CD082 -:1068E000607A002809D0012807D0022806D00328A2 -:1068F00004D035493F4804F02EFCF8BD0120F9F7DB -:1069000073FEF8BDF8B52F4C05462078042803D057 -:106910002D49394804F01FFC002D71D0FAF7E3F837 -:106920000125002812D1E0682030017E00290DD019 -:1069300061694A78D20609D00978C07B0907C90F76 -:10694000814203D1E571FFF7E7FBACE0E06820305E -:106950000079012811D1F9F76FFDE168881C283111 -:10696000FDF728FD002808D0E068B22142880A52CD -:106970003121095CA030017505746069002600783A -:106980004007C10FE0682030827B914255D0407BA8 -:10699000002852D002280FD1FDF780FE002803D135 -:1069A0000949164804F0D7FBE2680023106E516EC7 -:1069B000401C594151661066E06820304673C17A28 -:1069C00001291EE0D800002064610100EF070000EB -:1069D000FB07000008200020212000203A080000CA -:1069E0007A080000AF080000EC000020C01F002063 -:1069F000E21F0020F3080000FB080000FD05000076 -:106A0000B1E014D1C6722079082108432071FDF746 -:106A100046FF002803D1FE49FE4804F09CFBE268D3 -:106A20000023106E516E401C594151661066E0689B -:106A30002030817B012948D08573606901788C46BC -:106A40000907CF0FE1680A462031CB7B9F420CD16A -:106A50006746BF07BF0F012F4FD0022F4DD0032F26 -:106A600035D06079042108436071E0782843E070F4 -:106A700020690078C00604D460690078C00600D49C -:106A800061E720790028FBD160780028F8D100F078 -:106A900056FF0028F4D060790028F1D1A0790028B1 -:106AA000EED1FEF749FF207801280DD0607A00284A -:106AB0000AD001285CD0022806D0032858D095209F -:106AC000D349000104F047FBF8BD8673B5E7FDF735 -:106AD000D3F800280CD0E068203085722179294352 -:106AE0002171C17B012901D1C673BEE7C573BCE723 -:106AF0006079102108436071B7E74078C7062CD051 -:106B00006378002BB1D1C006C00E1B28F0D84032EC -:106B1000127DC97C0520FEF7D4FF002804D0A0799F -:106B200008210843A071A0E7E07804210843E07041 -:106B3000FDF70EFF002803D1B549B74804F00BFB61 -:106B4000E0680023816EC26E491C5A41C2668166AC -:106B50002030C17B0129C9D1C6E7012B01D0CD73FB -:106B600083E7CE7381E7E07802210843E070EAE62C -:106B70000120F9F739FDF8BD10B5A84800780428C0 -:106B800003D0A349A64804F0E6FAFFF7C5FA10BD02 -:106B900036210A5C40308188091D002A04D0C08853 -:106BA000814203D3012070470629FBD200207047A1 -:106BB000F8B5054606462036F07C2C460027803482 -:106BC000072820D1288DE18D401C884258D1A16A28 -:106BD00028460A30491C04F0AFFB01220221284656 -:106BE000FDF7ABFAF77401215E204155A06A0078E9 -:106BF000002804D1A1208649800004F0ACFAA16AE3 -:106C00000878401E0870F07C082839D1616A288D08 -:106C10008988401C884233D1A06B0178002904D0B8 -:106C20007B49804804F097FA15E06988C180606A62 -:106C3000A16B40890881606AA16B80894881606A84 -:106C4000A16BC0898881A06B0771A16B07200870B8 -:106C5000A16B68884880012211462846FDF76DFA2D -:106C60000321284600F076FE606A698840888842E1 -:106C700003D067496C4804F06EFA606A0770F774D5 -:106C8000F8BDF8B5654C6079002875D120790126EA -:106C900040070025002815DAE0682030C07C022873 -:106CA00002D0052807D102E05949604801E058495F -:106CB0005F4804F050FAE0682030417D022901D19C -:106CC00026724575207908278007002840DA607908 -:106CD00000283DD12069C0780D2875D20100794483 -:106CE000097949188F4449350681FCFCBB1722FC01 -:106CF0005B71CA00E06854210A5C2030417D0120AC -:106D0000FEF7DFFE002823D1E0680321352211546D -:106D100040308573E2E0E06854210A5C2030017D58 -:106D20000020FEF7CEFE002870D1DDE0E06854219F -:106D30000A5C2030C17C0020FEF7C3FE002803D18E -:106D400033493C4804F007FAE06809212030C17457 -:106D5000CAE0E06854210A5C2030C17C0020FEF7C4 -:106D6000B0FE002803D12A49334804F0F4F9E06862 -:106D700007212030C174B7E0FBE0E06854210A5CD1 -:106D80002030C17C0020FEF79CFE002803D1204962 -:106D90002A4804F0E0F9E0682030C774A4E0E06815 -:106DA00054210A5C2030C17C0020FEF78AFE0028B6 -:106DB00003D11749224804F0CEF9E06853210E545C -:106DC0000A212030C1748FE08AE0E0682030C07C66 -:106DD0000D2803D00E491B4804F0BDF9E06854218A -:106DE0000E540C212030C1747EE0E06854210A5C0E -:106DF0002030C17C0020FEF764FE002828D1E06826 -:106E00004030007D002823D101491DE064E00000EE -:106E1000646101000E06000057060000D800002043 -:106E20005809000091020000A50200006A04000059 -:106E30006E040000AC040000B1040000B6040000C1 -:106E4000BB040000C20400009920C00004F083F9D4 -:106E5000E06853210E540E212030C17444E0E068F4 -:106E60002030C07C132804D04D204349000104F099 -:106E700072F9E06815212030C17435E0E068A42182 -:106E8000095843884A889A421CD10978062919D1A1 -:106E900054210A5C2030C17C0020FEF712FE00283D -:106EA00003D13549354804F056F9E06801464031D0 -:106EB0008A7D920702D42030C67403E08D7380303F -:106EC000406A0570E06854210A5C2030017D002092 -:106ED000FEF7F7FD002807D0E0684030857403E036 -:106EE0002549274804F037F9207900070AD5607949 -:106EF000002807D1E0682030417D032902D102211A -:106F000021724575FEF7DDFEA07900072ED5E068F9 -:106F100054210A5C2030C17C0520FEF7D2FD0028F8 -:106F20000BD0607938436071E0688030816B0878FD -:106F30000B2800D10020087018E0E07804210843F5 -:106F4000E070FDF705FD002803D10B490D4804F062 -:106F500002F9E0680023816EC26E491C5A41C26684 -:106F600081662030C17B012904D0C673E068FFF739 -:106F70001FFEF8BDC573F9E764610100DC04000081 -:106F8000F6040000EA020000F7B582B00646039856 -:106F900017468188FE48FE4A41430398039D008BB3 -:106FA00000245043009080352A7C002A0CD0F948F8 -:106FB000012A40683CD0022A1FD0032A38D0F6A10B -:106FC000F94804F0C8F84BE0002F04D17D20F2A16D -:106FD000C00004F0C0F8EF4C6068002803D1EEA1B7 -:106FE000F24804F0B8F86068A168001D0918F04A7A -:106FF000009880180C18012018E0791E084303D16E -:10700000E5A1EC4804F0A7F8EB48016800980C18DB -:10701000002F0AD0DF484168E8480818A04204D988 -:107020008120DDA1C00004F096F80320287415E04B -:107030000C46002F12D0D74F002806D178780028B0 -:1070400003D0D5A1DE4804F086F8DC48796808183A -:10705000A04203D9D0A1DB4804F07DF8002C03D175 -:10706000CDA1D94804F077F821466869F5F7D9FF32 -:10707000686100203070012434716869B060039841 -:10708000FFF786FD002801D0747104E0287C0128F8 -:1070900005D003207071CD48F06005B0F0BD02202E -:1070A000F8E7F0B5054687B00F46012000F01BFD5C -:1070B000C4B20B2000F017FDC0B2844204D0FF2000 -:1070C000B5A14D3004F047F8012000F00CFDC4B22A -:1070D000182000F008FDC0B2844204D0FF20AEA109 -:1070E0004E3004F038F83846B94F6C1E6900CD199F -:1070F0000026403D09287DD20100794409794918CC -:107100008F44044150504CE9E9E9A0000B2C04DB0A -:10711000FF20B0A1213004F01EF8E88F6946FCF78B -:10712000EFFA002804D0FF209BA1563004F013F89A -:107130000B2C04DBFF20A7A1213004F00CF80099F0 -:10714000E88F4988884204D0FF2093A1583004F08A -:1071500002F800988030007C002804D1FF208EA126 -:10716000593003F0F8FF8B484660467086600098FF -:10717000FFF74AFA002804D0FF2087A1603003F00F -:10718000EAFF07B0F0BDFFF7D2FA0028F9D0FF20E0 -:1071900081A1663003F0DFFF07B0F0BDF9F727FAF1 -:1071A00007B0F0BD0420C04300F09DFCC6B219201A -:1071B00000F099FCC0B2864204D0FF2076A1723064 -:1071C00003F0C9FF0B2C04DBFF2082A1213003F068 -:1071D000C2FFE88F6946FCF793FA002804D0FF202D -:1071E0006DA1763003F0B7FF0B2C06DBFF2079A1F1 -:1071F000213000E06FE003F0AEFF0099E88F49888E -:10720000884204D0FF2064A1783003F0A4FF0098E6 -:10721000FFF7BBFA002804D0FF205FA17B3003F00A -:107220009AFF009C0022214602A8FFF7ADFE8034A1 -:10723000A07E02A9F6F7DAF80099088D401C0885AF -:1072400007B0F0BD0B2C04DBFF2062A1213003F05E -:1072500082FFE88F6946FCF753FA002804D0FF202C -:107260004DA1863003F077FF0B2C04DBFF2059A1E2 -:10727000213003F070FF0099E88F4988884204D0DC -:10728000FF2045A1883003F066FF00988030007C25 -:10729000042804D0FF2040A1893003F05CFF009C4B -:1072A00080342674A57E4F4F681E0B2804DBFF2018 -:1072B00048A1273003F04FFF4548690008184038BF -:1072C000C787A07EF5F700FC4748A6760078EBF765 -:1072D0001BF807B0F0BDFF202FA193304FE770B52A -:1072E000424C0646E08B0025401C80B2E0832378A8 -:1072F0000A46002B09D021464968042B0BD0052BE8 -:1073000017D03D2024A1000102E0ED2022A1800041 -:1073100003F021FF14E00A2801D3022000E003203B -:107320007071002A0BD00320226900F0F5FB05469E -:1073300006E002207071002A01D02D4D00E00D46BC -:1073400029462069F5F76DFE002120613170012189 -:107350003171B060A068FF303130F06070BDF0B5C1 -:10736000074685B00E46012000F0BDFBC4B20B20DD -:1073700000F0B9FBC0B2844204D0FF2006A19E30C9 -:1073800003F0E9FE012000F0AEFBC4B2182031E0AA -:10739000E2040000302000207372635C6C6C5F6C50 -:1073A0006D2E6D302E6300001C040000E903000008 -:1073B0005504000003040000000100205F040000E9 -:1073C00016040000170400001F040000F60400006B -:1073D0005C2000207372635C6C6C5F6C6D2E6D3092 -:1073E0002E630000FFFF0000FC0000203C20002076 -:1073F000B80B000000F077FBC0B2844204D0FF203D -:10740000FD499F3003F0A7FE00250120FB4C092E0B -:1074100070D231007944097949188F44041A3737FA -:10742000336B6B18520060732073607800280ED1A4 -:10743000F348456085602573A068C338FDF791FC6B -:10744000002804D0FF20EC49B33003F084FE05B0DF -:10745000F0BD6178002909D0207B002801D1FDF71B -:10746000C2FD6573F5F796FA05B0F0BDA073FDF7A0 -:1074700000FD0028F8D0FF20DF49C73003F06BFE85 -:1074800005B0F0BDF9F7B3F805B0F0BD0420C04376 -:1074900000F029FBC4B2192000F025FBC0B28442E1 -:1074A00004D0FF20D449D53003F055FE012200213D -:1074B0006846FFF714FF69463846F5F797FF05B0B1 -:1074C000F0BD2078052804D0FF20CB49E13003F03F -:1074D00042FE207F002804D1FF20C749E23003F09C -:1074E0003AFE25772570207DF5F7EEFA257505B073 -:1074F000F0BDFFE7FF20C049ED30A6E7F0B5BF4C77 -:1075000087B020780026042805D02078052802D0EE -:107510000C2007B0F0BD01276770607B00250028B4 -:1075200027D072B6607B002808D0A07B002805D049 -:10753000FDF759FD6573A573F5F72CFA62B6207D4A -:10754000F6F782FD002827D0207F002808D0257775 -:107550002078052803D0A849AA4803F0FCFD0C2692 -:1075600065702570207DF5F7AFFA2575304607B0B8 -:10757000F0BD207D00900320694608734873F5F73D -:10758000BEFA04900020C043694605900F7202A91C -:107590000098F5F72BFFD2E720BFD0E7F0B597486A -:1075A00083B00078002801D0FFF7A8FF944F012096 -:1075B0003870FF26944D2D36002405E00B2C03D3A4 -:1075C0009249304603F0C7FD204601A9FCF798F820 -:1075D000002838D101988030007C002833D00B2C53 -:1075E00003D38A49304603F0B6FD2046AC422ED084 -:1075F0006946FCF785F8002803D08449844803F0E5 -:10760000AAFD00988030807EF6F71EFD002822D06B -:107610000098002180300174847E0C2C04D3FF205C -:107620007A49273003F097FD7A48610008184038FE -:10763000C58700988030807EF5F746FA00990020D3 -:1076400080318876B8E7641CE4B2032CB6D30020FE -:10765000387003B0F0BD20BFD3E710B500786E4C92 -:1076600000280FD001280CD068496C4803F073FD46 -:10767000A0686B49884203D364496A4803F06BFDF4 -:1076800010BD6948A060F3E710B55D4900220A709B -:10769000614C207059480270427002770273427345 -:1076A0008273826102752030574B0380052143802D -:1076B0008380001D491EFAD1100004D0002A04D096 -:1076C0005948A06005E0A26003E05049534803F028 -:1076D00042FDA0685249884203D34C49514803F007 -:1076E0003AFDFFF75BFF10BD70B5444C0E462178A4 -:1076F00084B01546002902D00C2004B070BDA061F2 -:107700008030007C002803D03B49484803F023FD2B -:107710004748464345434748ED1C30186660A5601E -:10772000854200D82846A0603549002088600521A0 -:10773000217060702077E0833F48F5F771F920757C -:10774000002803D12C493D4803F005FDF5F7D7F992 -:107750002061002201216846FFF7C1FD207D6946B6 -:10776000F5F744FE002004B070BD08B50020C0430A -:107770006946088021480078002801D0002008BD13 -:107780000846FBF7F5FF0028F9D0012008BD10B529 -:107790001A4C84B02278002A02D00C2004B010BD0C -:1077A000234A51435043C91C224AA160606080189B -:1077B000814200D80846A06000206070042121703A -:1077C000E0831D48F5F72CF92075002803D10A49FC -:1077D0001B4803F0C0FCF5F792F91A49F5F721FCB4 -:1077E0002061002201216846FFF779FD207D69466E -:1077F000F5F7FCFD002027E0987301003C200020F5 -:107800003020002076020000FFFF0000D47301004A -:10781000190300005C200020FC000020510500003E -:107820006A1800005A050000C40900008B0200001D -:1078300071020000B3FBFFFF5F73010097020000BD -:10784000C6020000B80B000004B010BD10B5E14C3A -:10785000A1690160FFF752FE0021A16110BD70B562 -:10786000DC4C84B02078052802D00C2004B070BD18 -:10787000A069002803D1D849D84803F06CFCA0695E -:107880008030007C002803D0D349D54803F063FC46 -:10789000A0698030807E002803D0CF49D14803F012 -:1078A0005AFCD148F5F7BCF8A1699A225054054614 -:1078B0004E88401E0B2804DBFF20C749273003F009 -:1078C0004AFCCA49680040184038C687A069803021 -:1078D000807E002803D1C049C54803F03CFC01224A -:1078E0006846A169FFF750FBA06969468030807E39 -:1078F000F5F77CFD0020A06104B070BD10B5BD4956 -:107900004C68983400280ED001280FD0022811D0DE -:107910003520B949000103F01EFCAE488068A04242 -:107920000BD9012010BDFF347934F6E7B120800077 -:107930002418F2E7FF346134EFE7002010BDAD48B2 -:107940004178002902D10078002801D0002070473A -:107950000120704770B504460422A84E803484B0DC -:1079600000290DD0012923D0022907D0032921D0D5 -:10797000A149A34803F0EFFB04B070BD227410E0EE -:1079800005469C4800780028F8D12946012268461F -:10799000FFF7FAFAA07E6946F5F728FD288D401C0E -:1079A0002885F4F7F7FF3078EAF7AEFC04B070BD35 -:1079B000032010E08188934A5143934A1160616A21 -:1079C0000A8902838A7982754A8982808A89C2807B -:1079D000C98901810220207404B070BDF0B5874EC2 -:1079E0000146307800257B4C85B0002908D001295C -:1079F00016D0022942D0032958D07F49834839E064 -:107A0000E583EAF781FC6078002849D1002211461D -:107A10006846FFF764FC207D6946F5F7E7FC3FE028 -:107A2000744F20697968774B401879494218A069EA -:107A300081884088594300F06FF8B1680546884254 -:107A400005D2A1696F4A88884243551903E06D4900 -:107A500003F060FAA1690883A06905218175008B94 -:107A600068494843281A6B49B860884204D32520E6 -:107A70005949400103F06FFB05B0F0BDE583EAF71B -:107A800043FC01202077A0692169803041610574A1 -:107A9000FFF7E5FE002803D04F495F4803F05BFB8A -:107AA000F4F778FF6573A57305B0F0BDEAF72CFC19 -:107AB00005B0F0BD704710B54E4A00290ED001291F -:107AC00006D0022906D04C49544803F044FB10BDAF -:107AD000401E03E05178491C5170001F506010BDDA -:107AE0003C48007870478107C90E00280BDA000770 -:107AF000000F083880084A4A80008018C069C840D2 -:107B00000006800F70478008464A80008018006891 -:107B1000C8400006800F7047F7B582B00D46064694 -:107B2000414F002406E00B2C04D3FF202A492D30BE -:107B300003F011FB204601A9FBF7E2FD00280ED15E -:107B400001988030007C002809D00B2C04D3FF2042 -:107B500021492D3003F0FFFABC4204D006E0641C3A -:107B6000E4B2032CDFD3002005B0F0BD6946204607 -:107B7000FBF7C6FD002803D017492C4803F0EBFAA9 -:107B8000A64204D1DD201449800003F0E4FA28481D -:107B9000341B44430098803041690498F6F7C8F9D3 -:107BA000041908D5281B66422946401E03F0C0F977 -:107BB0006843841B05E02946204603F0B9F9684371 -:107BC000241AAC4203D904491A4803F0C4FA2046E7 -:107BD00005B0F0BD3C200020D4730100E702000096 -:107BE000E9020000EB020000A37001005C2000200D -:107BF000EE0200003020002098730100FC000020FD -:107C0000ED040000E204000000010020190500005E -:107C10004E0600006A180000B3040000360500009C -:107C200000ED00E000E400E0FFFF00007103000051 -:107C3000770800008903000070B5F84E0446B0795B -:107C40000025012805D0F64E307A01280CD00020FE -:107C500070BD002915D1657014202070F149A01C59 -:107C600003F082FBB5710CE000290AD16570132086 -:107C700020701C22EC49A01C03F0E3F80120A07145 -:107C80003572012070BDE648007A002802D0E7482E -:107C9000808D7047E6487047F8B5E64801780029BE -:107CA00002D00C263046F8BD0026E04D34462E7535 -:107CB0006E75EE752E76AE75DF496E734E73D84FC6 -:107CC0007F217E718170687E002804D0F8F7ABFBBD -:107CD000F8F754FF6C763C72D848FBF711FED84891 -:107CE000FBF70EFEDEE770B5D24A00251570CC4ECC -:107CF000D44B35711966D8651078002805D0FF205F -:107D0000D1A17A3003F027FA70BDC84C257565758E -:107D1000E5752576A575C8486573457375717F202F -:107D20009070607E002804D0F8F77DFBF8F726FFFE -:107D300065763572C148FBF7E3FDC148FBF7E0FD0E -:107D400070BDBA48007D704710B5B849C87B897BC3 -:107D500042078307D20FDB0FC007D218C00F1018DD -:107D60004000052911D20A007A44127992189744EA -:107D7000090509020700B849085A10BDB74810BDE7 -:107D8000B74900E0B749085A10BDFF20AEA19A30AC -:107D900003F0E1F9002010BDA448B349008A48432C -:107DA00070479F488079002800D001207047F8B5BF -:107DB00006469E4C407BE07330790027A073012873 -:107DC00025D0308820829648B37B83719D4DA7488B -:107DD0002970114603F0BBFAB0796873F11DA4480D -:107DE00003F0B5FA607B0126002800D06675924842 -:107DF000407B002800D0A675A07B05284DD201004D -:107E00007944097949188F440409262B09002782EF -:107E1000D9E700218948FBF778FD25E00121874853 -:107E2000FBF773FDE91D8548FBF7A4FD687B00287F -:107E300007D001280AD0FF2083A1E83003F08BF996 -:107E400012E000217D48FBF7A6FD0DE001217B48F3 -:107E5000FBF7A1FD08E006217848FBF756FD03E09B -:107E600002217648FBF751FDE7752776691C7348B8 -:107E7000FBF774FD29787148FBF781FD04217048F8 -:107E8000FBF743FD691C6E48FBF768FD29786C48D9 -:107E9000FBF775FD26750020F8BDFF206AA1F230C2 -:107EA000CCE770B5614C012525765D4A127A002A2F -:107EB00001D03A2070BD634A13780022834205D175 -:107EC000E2756A4803F043FAE57500E02276002087 -:107ED00070BD70B50446554D0020A8752246654812 -:107EE00002F0AFFF544844730120A87570BD4C499F -:107EF0000871704710B54D4C0022627560730246E0 -:107F00005D4802F09EFF0120607510BD4449487134 -:107F10007047F8B5474D287800282CD1434C207D78 -:107F2000002828D0F8F71FFA0026A674E6746E70B1 -:107F30003046F8F715FA0020F7F7D9FF4F48F8F761 -:107F4000E6F84F48F8F7A1F9F8F73AFAE07B01278D -:107F5000C107002902D0A17CC9070ED0810712D524 -:107F6000A17C89070FD42620F8F7E3F8A07C022132 -:107F70000843A07413E00C20F8BD2520F8F7D9F8C9 -:107F8000A07C38430AE0400709D5A07C400706D40E -:107F90002720F8F7CEF8A07C04210843A074F8F756 -:107FA000DBF901210020F8F7DFF80F210520F8F7B1 -:107FB00022F8244D2978681CF8F711F8A07B0128D5 -:107FC0000AD0042808D0607D002805D0627B2A49A9 -:107FD0001A48FBF7FAFC6675A07D002806D0164803 -:107FE0002449427B9830FBF722FDA675286E017864 -:107FF000002903D00178001DF8F734F8E86D017806 -:10800000002904D01F4A401CF8F797FD6776F8F75F -:10801000B5F90020F8BD074948607047F4200020FA -:10802000D4200020FB200020DE200020B4200020EF -:10803000FFFF000008010020942000200421002000 -:108040002C210020742000207372635C6C6C5F61D3 -:1080500064762E630000000066B401009A89130064 -:108060006EB401005EB401007102000075200020B2 -:108070007B20002082200020A220002059B4010093 -:1080800056B4010057210020F8B50126FE4C0546E4 -:10809000002824D0E07B2146C207897C002A01D039 -:1080A000CA070BD082070FD58A070DD42620F8F710 -:1080B00040F8A07C02210843A07410E02520F8F7C6 -:1080C00038F8A07C3043F7E7400708D5480706D4C6 -:1080D0002720F8F72EF8A07C04210843A074E07C48 -:1080E00000280AD0A07B012804D14B20E7490001D9 -:1080F00003F031F800F0BDFAF8BD002D0CD00221DC -:108100000020F8F731F8E2480079032801D001286F -:1081100002D10220F8F768FAE07D002700280AD093 -:10812000DC4DDD48691CFBF719FC691CDB48FBF7DB -:1081300015FCE7752776D848F8F725F9A07B0528C0 -:108140000CD201007944097949188F440202020BCC -:10815000020001210846F8F791F903E0CB49D04825 -:1081600002F0F9FFE07BA17C884303D1A07B0128CA -:1081700003D0E674CB480670F8BDA774FAE710B5D3 -:10818000F8F7F1F8C7480078002816D1BE48007DFE -:10819000002812D00020FFF777FFBD4800790028A3 -:1081A00009D0012815D0022805D0032811D0B749DD -:1081B000BD4802F0D0FF002010BDF8F720F9F8F715 -:1081C00013F9F8F71FF8F8F7C1F8F8F7D7F80C200B -:1081D00010BDEAF71DFFEEE7B24901204870704775 -:1081E000F8B50024FAF7AAFE002822D0FF202D308F -:1081F000F7F7B7FFAB4D2878A54F01281CD0022810 -:1082000001D0032831D0CF20A049800002F0A3FF85 -:10821000287800280CD03879002809D0012807D008 -:10822000022835D0032833D09849A04802F093FFA4 -:10823000F8BD00F01EFAF8BD934EB07B032814D0B1 -:10824000707E002803D0F8F788FCF8F7E4F8984827 -:10825000F8F799F8B07B012812D0042810D0B8792B -:10826000012806D0032804D004E00120FFF70CFF0A -:10827000CEE7102421460E2001430020F8F7FEF837 -:108280007879012801D1F8F7E0F802202870BFE7DB -:1082900028780228CFD10120F8F7A6F9F8BD70B5EB -:1082A0007B48804C4079012808D18248F8F7D6F8FD -:1082B000002801D17F20A070F8F7BEF8724D687ECB -:1082C000002803D0F8F7AFF8F8F758FCFAF736FEB5 -:1082D00000280BD02078022804D0DD206B498000D4 -:1082E00002F039FFA87B012803D006E000F0C1F9B5 -:1082F00070BD99208000F7F734FF0120FFF7C4FE1E -:1083000020780028F4D020780128F1D05F496A480D -:1083100002F021FF70BDF0B5044689B00020069040 -:108320000190F7F7F1FE03905E480078022803D031 -:108330005649624802F00FFF554D6879012809D16E -:108340005C48F8F78BF8002802D156497F208870E6 -:10835000F8F772F85648FBF7FDFA4B4E0746002C2B -:108360006FD05348FBF700FC00286AD0F7F740FEB7 -:10837000002866D0707E00280AD00524641EE4B26E -:10838000F8F71DFC022811D0012800D00020019030 -:10839000474A4B4CD01C0290062F52D238007844EA -:1083A000007900188744B4B4B409B44E002CE5D168 -:1083B00044A1484802F0CFFEE8E7B07B012840D056 -:1083C00004283ED001990398084304D1A8790028D5 -:1083D00001D0022835D1687901281AD1A079002866 -:1083E00017D10120A07110784006C00FE0713A4803 -:1083F000029902F0ACFF2B4C384FA0787F2804D1B3 -:10840000532030A1000102F0A6FEA07838707F2032 -:10841000A0702248F7F7B7FF22480321017028799E -:10842000002877D0012808D0022873D0032804D070 -:1084300024A12B4802F08FFE6CE00120F8F7D4F85D -:1084400068E065E01348D178C07981424AD111488B -:108450001179037A994245D15179437A994241D1B0 -:108460009179837A99423DD1D179C37A994239D1B0 -:10847000117A037B994235D11178407B4906C90FA7 -:1084800081422FD101212EE0B4200020488001003C -:10849000D420002074200020042100202C21002062 -:1084A000DE04000008010020D1020000510300009A -:1084B000542100200A01002083030000C1030000B2 -:1084C000F42000207372635C6C6C5F6164762E63D1 -:1084D00000000000AB030000FC200020022100206F -:1084E000090400000021B07B012801D0042801D13B -:1084F00000290AD100280BD101990398084304D11F -:10850000A879002801D0012802D1307E00281FD090 -:1085100001200690707E002803D0F7F784FFF8F75B -:108520002DFB0698002802D00120FFF7ADFD73480F -:10853000017800290AD00178012907D000780328A2 -:1085400004D049206E49000102F005FE09B0F0BDDB -:108550006A486C4F4068397BC173797B0174B97B81 -:108560004174F97B8174684909784906C90FC1765D -:108570001C30029902F0EBFE6048397C4068C174FF -:10858000797C0175B97C4175F91E897D81750299E7 -:108590004A7D0B7D110219430183F91E8A7E4B7EB1 -:1085A00012021A438280029A537E177E1A023A43BD -:1085B000C2808A7F4B7F11021943018153490A30DF -:1085C00002F0BAFE52480179CA064C49D20E4968F7 -:1085D0008A7600794009C0310871287A002803D0D2 -:1085E00047494C4802F0B7FD0020A87243484B4968 -:1085F00047687888B085F87EE873B88B2882F88B56 -:108600006882388CA88244480078A875444802F0F3 -:108610009EFEB888F087F888208038896080C0374F -:10862000387920710198002860790BD00121084326 -:108630006071F8F7DDFA61794000C907C90F01439D -:10864000617102E0400840006071012028722B4CEB -:1086500000202070F7F7D3FEF7F7C6FEF7F7D2FD3C -:10866000F7F774FEF7F78AFE01206168FAF785FDD7 -:1086700050E7F8B5F7F7C3FEF7F7B6FEF7F7C2FD18 -:10868000F7F764FE274E0027707E002804D0F7F726 -:10869000CAFEF8F773FA7776184D2F70F7F76EFE6B -:1086A000B07B012804D000210846FAF766FDF8BD2A -:1086B00000210220FAF761FD1B4C207A002803D02C -:1086C0000F491A4802F047FD68780028EFD0124899 -:1086D000417BE1730078A0751549164802F037FE1A -:1086E0000E490F4802F033FE3C20A07268684088B3 -:1086F000B085012020726F70F8BD000008010020D5 -:10870000C48401005721002054210020732100203F -:10871000742100203D0400007420002075200020FA -:10872000EB200020B4200020D42000204F020000C5 -:108730007B200020E4200020F8B5FBF7FBFF044677 -:10874000FCF7BFF8FE4E054670692030407B0028DC -:1087500026D0012844D0022846D003284DD0FF203F -:10876000F8A19C3002F0F7FCB069F72201781140C3 -:10877000017072692032937BDB071B0F1943FB23C7 -:1087800019400170D37BDB075B0F19430170577BE6 -:10879000EF23022F3CD0012F3FD0032F41D046E0E2 -:1087A000EC48FCF76DF8002804D0716903202031F3 -:1087B0004873D9E7E748FBF74DFF002804D07069FC -:1087C0005321095C002907D0E248FCF700F87169E1 -:1087D000012020314873C7E7022120304173C3E7ED -:1087E000DC48FBF7F4FFBFE7DA48FBF733FF00286C -:1087F000BAD1FF20D3A18E3007E0D648FCF740F86D -:108800000028B1D1FF20CFA1963002F0A4FCABE745 -:10881000012C08D8002D06D009E06D1E2C4302D192 -:1088200005E0002C03D019401023194300E0194043 -:108830000170D17D002915D0517B012912D0C64885 -:10884000F7F7A1FDC548002101767269116E526EDD -:1088500042610161C049B269F8F7FBF80020F8F7FE -:1088600007F903E0F7F78FFDF8F725F9B06900780D -:10887000C00606D4F0690078C00602D4F07900285A -:1088800006D0B079002803D101210846F7F7F6FD9C -:10889000032030703079002803D1F7F791FD0120D3 -:1088A0003071F8BD10B5A649002348690246203052 -:1088B000C37483750120412398548032927F002A2B -:1088C00003D008700021022001E000210320FAF704 -:1088D000D2FB10BD06281AD202007A4412799218EF -:1088E00097440205090D101000290ED00FE0891ED3 -:1088F00002290AD90BE0891F012906D907E00829B6 -:1089000003D004E00B390B2901D801207047002067 -:10891000704730B5044683B08E48FBF77FFF0028D0 -:1089200004D1F52087A1C00002F015FC844DA86990 -:10893000FBF75AF90321A869FBF777F9A869EF2239 -:108940000178114001702146FBF7D8F90E2C5BD25B -:1089500020007844007900188744565606561F5A5E -:108960005A175642565A312B75485D224169525C5E -:10897000002A04D006218069FBF76DFA48E0C03177 -:10898000C9798069FBF767FA42E06D4841698069FF -:108990008031497AFBF7D0FA3AE0694D6969A869F4 -:1089A000B031FBF791FA6969A8698431FBF798FA4D -:1089B0002EE0634806218069FBF7BAFA28E0604D93 -:1089C00028690178A869FBF79DFA28698188A86958 -:1089D000FBF79AFA28694188A869FBF799FA17E02A -:1089E000002000900190564841694031097F0029DC -:1089F00005D06A461178012211436A461170694612 -:108A00008069FBF7A7FA03E04EA1554802F0A3FBEB -:108A1000FBF715FF002804D17F204AA1000102F0D6 -:108A20009AFB0C2C0AD0072C06D04548002140693F -:108A3000403041810121817303B030BD40480021A5 -:108A400040694030018203B030BDF0B53C4D064670 -:108A500068698DB020300079012801D1F7F7ECFC6E -:108A60000024012E1ED168692030017E002902D128 -:108A7000C07D002801D0F8F71EF8F7F7C0FCF7F723 -:108A8000B3FCF7F7BFFBF7F761FCF7F777FC687902 -:108A9000C006686902D58030048703E08030018F0A -:108AA000491C018768790226C107002901D1800786 -:108AB00013D568692030817D002902D0032907D0B1 -:108AC0000BE00121817500210120FAF7D4FA04E0BE -:108AD000867500210120FAF7CEFA68692030817D81 -:108AE000012903D16979090700D586751448807A70 -:108AF000002861D100F015FF1648FBF78FFE002813 -:108B00005AD00F4D287A002856D16869C621095CD1 -:108B100000290ED02030C17C0120FFF7DBFE0028A9 -:108B200007D168692030C17C0420FFF7D3FE0028FC -:108B300018D06869CB21095C062919D01FE0000014 -:108B4000100100207372635C6C6C5F736C617665FE -:108B50002E6300002801002080210020A821002091 -:108B6000EA070000686940300481447702204DE044 -:108B70002030C17C0420FFF7ADFE002815D06869C5 -:108B80002030C07C801E15287ED2010079440979EE -:108B900049188F449B9B9B1C9B9B9B979B1E9B9B5D -:108BA0009B243E9B9B9B9B9B900068695621095C84 -:108BB000C90702D0C030C472AEE00C20FFF7A9FE96 -:108BC000686901224030817D11438175A4E007204E -:108BD0001CE0FBF7F0FE00286CD00B2016E0F3F74A -:108BE00050FA0C2866D368690821B030F3F74AFAC6 -:108BF000002806D0686904218430F3F743FA00287E -:108C000003D1F4A1F74802F0A6FA0420FFF781FE91 -:108C100082E068698446C030807A042802D0052842 -:108C200039D079E06046E030007D002874D1EE490B -:108C30006046102600230822D8306944F51A2D1802 -:108C4000203DEF7F4F70AD7F8D70891C521E9B1CA5 -:108C5000002AF3D103A86346102608210330A83365 -:108C6000B51AED18203DEF7F4770AD7F8570801CF1 -:108C7000491E921C0029F3D16846F9F70CFB08AF96 -:108C80004ECFDA4D686900E020E070304EC005201C -:108C9000FFF73FFE0BE060464030017D002903D026 -:108CA00001214177022000E00D20FFF732FE6869C4 -:108CB000C030847230E00620FFF72BFE6869403038 -:108CC000847329E00920FFF724FE25E06869CA21A2 -:108CD000095C002920D0062906D02030C17C002064 -:108CE000FFF7F8FD002817D068690146C0318A7A7D -:108CF000072A11D213007B441B79DB189F440C0C0C -:108D00000C0C0C0C03004030807DC20700D154E7EE -:108D1000C043800700D18C72B44D2879002868695F -:108D200002D08030048303E08030018B491C018332 -:108D30006879C007686904D0A4210C54403084804D -:108D400003E040308188491C8180E879002806D002 -:108D50006969A0310879022806D8401C0871686941 -:108D6000A0300079022806D9686901468030048362 -:108D70004483A0310C7168692030C17C0020FFF76A -:108D8000A9FD002804D168692030C07C07284CD197 -:108D900068690146C0318A7A062A46D0C97A06290E -:108DA00043D03621095C02293FD1A0300079002848 -:108DB0003BD1FBF7AEFC002837D0FBF782FD002843 -:108DC00033D06869014680314A8A012A2DD90122AF -:108DD0004A77024640329688D288931E9E4201DB33 -:108DE000012302E0921B521E93B20A8BAE89B2425B -:108DF00001D3012202E0B21A521C92B2934200D96E -:108E00001346012B00D14C77C0300278002A10D0D5 -:108E1000498B4088814201D3012102E0401A401C65 -:108E200081B28B4205D90B4603E06869012380308B -:108E300044776A69118D1646C81883B2104680308F -:108E400083822036B77D002F25D0012F23D0022F1B -:108E50000CD0032F0AD05FA1654802F07CF9687935 -:108E6000C006686919D58030C4841BE0F67C032EE7 -:108E700009D0082E0FD04032D1889288891A891ED5 -:108E800059180182EBE740329688032E03D3D2882B -:108E90008918491CF5E70382E1E78030C18CC28A5A -:108EA0008918C18468690246C0329179002906D0C8 -:108EB0000146403196230E891B5AF3180B81A97A7B -:108EC0000426002913D002463D214032917001460C -:108ED0002031CC748C75012151708030807F002846 -:108EE00070D0297000210220FAF7C5F85EE0014633 -:108EF0002031CB7C042B48D02B7A002B1ED05A0774 -:108F000001D4DA0604D51E2240308270CE743CE0D3 -:108F10001A0704D53D2240308270CE7435E0D80760 -:108F200005D1980703D42BA1324802F014F96869DF -:108F30002A21422211542030C67426E04030837B1F -:108F4000002B05D047897B1C438183899F420FD228 -:108F5000D37A062B02D0927A062A05D1038A5A1CAC -:108F600002828289934203D20389C288934203D347 -:108F700022228270CE7408E08B7D002B23D0838860 -:108F800093423CD308228270CE7468694122014624 -:108F90002031CC748C75012111548030807F0028E1 -:108FA0002AD0297000210220FAF765F8F9F7EEFFC0 -:108FB00000282DD068690146FF300130827A002AEE -:108FC00022D025E018E08288062A18D33E2282703B -:108FD000CE74DAE77372635C6C6C5F736C61766598 -:108FE0002E63000039060000FFFFFFFF1001002084 -:108FF000790800004502000000210320D4E7012089 -:10900000287000210846CFE74988818101218172BB -:109010006869803084770DB0F0BDF8B50C4617460E -:109020006946FAF7F9FA002801D00020F8BD009847 -:109030000146E030027AF74E0025002A17D0002FB3 -:109040007DD1657007212170007A00280DD07169EB -:10905000E8204D8445540A22A01CEA3101F0F1FEBB -:109060000098E030007A0028F1D1A57067E0027D19 -:10907000002A2AD0002F62D1017D0D2920D20A00BA -:109080007A441279921897441B1B1B1B1B1B1B1B3A -:109090001B1B1B0F060065700C212170817DA170C8 -:1090A00071694988A18009E065700B212170817D7B -:1090B000A17071694988A180817EA17105753EE02A -:1090C000D549D64802F047F839E0027F002A15D08A -:1090D000002F34D16570082222707269FF315288E6 -:1090E000628001310A88A2804A88E2808A882281CF -:1090F000CA8862810989A181057720E0FF310131A9 -:10910000887A002808D0002F19D1657011202070AE -:10911000888960808D7212E0887B002886D0002FBD -:109120000DD1657012202070887B002807D08D73C8 -:10913000088A6080488AA080887B0028F7D10120B7 -:10914000F8BDB4480078012801D00C2070470020F9 -:10915000704770B5AF4C05462078002803D0AE4963 -:10916000AF4801F0F8FF00202561E0720120207077 -:109170002078012803D0A849AA4801F0ECFF70BD6F -:10918000F8B5A44D2978012901D00C20F8BD01269D -:10919000686180308677807AFBF749FA00282ED004 -:1091A00068698030807AFBF799FB002827D06869CE -:1091B0008030807AFBF70EFB002820D06869803071 -:1091C000807AFBF74AFB002819D0F7F7CCF86869DA -:1091D00000248030408A002825D09348FBF71EFBEE -:1091E000002820D06869C621095C00291BD02030E6 -:1091F000C17C0120FFF76EFB002802D013E0122093 -:10920000F8BD68692030C17C0420FFF763FB0028AB -:1092100009D168694030048144770220FFF779FB67 -:109220006869803044776869E821095C002905D1C4 -:10923000418CC288914201D9A98101E0C188A981EC -:1092400001468031CA8A521E93B20A8BD21892B25A -:109250000A830F7F002F02D04C830C7702E04F8BE4 -:10926000FF184F8305464035AF88FF18AF804D8A01 -:10927000012D01D86D1C4D82002B01D0A4231C545C -:109280002030C07C634D042817D0487F002816D0BA -:10929000A889824213D2FBF73CFA00280FD06869F4 -:1092A0000146C0310A78002A09D08030408B4988B5 -:1092B000884204D3AC70EE7003E0AE7001E0AC7095 -:1092C000EC7068699D210C543321095C062901D09A -:1092D000072917D1CC21028D095A511A09B2002948 -:1092E00010DB0146CE310A3002F04FF80122022194 -:1092F0006869FAF7C8FE6869CB210C5433210C5415 -:1093000040308677434D962168690A5A01462830D5 -:10931000891CFAF75FFFA87800284DD16869C02141 -:10932000095C002901D0803044830120F6F7DFFD7D -:10933000384D68691330F6F7A8FF68690F30F6F703 -:10934000E6FE0120F7F70CF8686901462030027E3E -:10935000002A02D1C07D002806D07031ACC9334844 -:10936000ACC0334802F000F8F6F7F6FF01210846DA -:10937000F6F7FAFE274D68698030006AF7F706F8BD -:109380002C48FBF7BEFA002801D06C7002E06E702A -:109390002948E86168692030007E002802D068789A -:1093A000002817D0E869F6F7EEFFF7F784FB686945 -:1093B00040300078F6F7BDFE164802214471C471B2 -:1093C000847104724472847204710170F6F7D6FFDE -:1093D0000020F8BD1848F6F7D6FF144806766A69EB -:1093E000916ED26E42610161134AE969F7F731FB70 -:1093F0000120F7F73DFBDAE710B5064C207802288C -:1094000001D00C2010BDA078002817D00020FFF755 -:109410001CFB2FE010010020D48F0100DD080000AC -:109420002D0900003809000028010020A821002093 -:10943000C12100202C01002080210020F6F793FF9D -:1094400001210020F7F71AF804202070606920300D -:109450000079012801D1F6F7F8FFE07A002809D059 -:10946000012807D0022807D0032805D0F949FA4877 -:1094700001F071FE002010BDE9F7CAFDFAE7F749D7 -:10948000C8727047F8B5F54C2078032803D0F1492D -:10949000F34801F060FE616901252031887A0028D7 -:1094A00006D0002088720D73A07904221043A071A9 -:1094B000A0690278D24392072BD1C97A002928D11A -:1094C000FAF753FC04281DD0052802D00B2819D127 -:1094D00011E0606901462030C27C102A12D10022BE -:1094E0008A66CA6605767031CCC9DE48CCC0DE48D3 -:1094F00001F03AFF06E060692030C17C0B2901D100 -:1095000000210176606902212030C572A0790843EC -:10951000A071A0690078C00606D4E0690078C00692 -:1095200002D4E07900280FD0607800280CD1A0790F -:10953000002809D1F9F718FD002805D0207A002865 -:1095400002D1607A002803D00120FFF77EFA1DE0E7 -:10955000C648FBF7D6F9002802D00020607002E070 -:109560006570C348E06160692030007E002802D049 -:10957000607800281CD0E069F6F705FFF7F79BFA42 -:1095800001210020F6F77AFF0420207020780128BE -:109590000DD0E07A00280AD0012808D0022819D07E -:1095A000032817D0A920AB49000101F0D4FDF8BD74 -:1095B000AF48F6F7E8FEAB4805766269916ED26E69 -:1095C00042610161AA4AE169F7F743FA0120F7F71E -:1095D0004FFAD5E70120F7F707F8F8BDF8B59F4C2B -:1095E00005462078042803D09A49A24801F0B3FD2B -:1095F0009A481027417939434171002D7ED0F7F701 -:1096000072FA0125002814D1944842692032117E53 -:1096100000290ED0C1694B78DB060AD00978D27BCD -:109620000907C90F914204D185720120FFF70DFA95 -:1096300054E18A4CE07800281ED0E0694178C906E0 -:109640001AD10078C00617D460692030007901284B -:109650007ED1F6F7F1FE6169881C2831FAF7AAFE7F -:10966000002875D06069C21D4388F932138220300A -:10967000007C907495732BE160692030007901289B -:1096800011D1F6F7D9FE6169881C2831FAF792FEEC -:10969000002808D06069C21D4388F9321382203047 -:1096A000007C90749573E069002600784007C10F34 -:1096B00060692030827B914242D0407B00283BD0C1 -:1096C00002280FD1FAF7EAFF002803D161496A485E -:1096D00001F041FD62690023106E516E401C59413A -:1096E00051661066606920304673017B012903D101 -:1096F0000673A1793943A171C17A00E0D1E0012953 -:1097000014D1C672A07908210843A071FBF7C7F8ED -:10971000002803D14F49594801F01DFD626900231B -:10972000106E516E401C59415166106660692030C0 -:10973000817B01292ED085736079082108436071EF -:109740004649C869496903781A07D40F203100E0F7 -:109750007FE0CA7B94420CD19B07404C9B0F012BAE -:1097600048D0022B46D0032B16D0207A0421084380 -:1097700020723A48417929434171C67181790907BC -:1097800004D541692031C97C032962D0017A0029BE -:109790005FD182E08673CFE76378002BE9D18D72C9 -:1097A000A3792B43A371012A10D0CD73FAF7DDFA08 -:1097B00006280DD00B28DCD1606901462030C27C20 -:1097C0000C2AD6D1C67540310D75D2E7CE73EDE7C0 -:1097D000606901462030C27C122ACAD100220A6682 -:1097E0004A66C57570319CC91E489CC0093001F09D -:1097F000BBFDBEE74078C30649D06278002AB8D1E5 -:10980000C006C00E1B283FD8C97C0520FFF762F8B0 -:10981000002804D0607A082108436072A9E76079C3 -:10982000042108436071FBF793F8002803D109492C -:10983000134801F090FC60690023816EC26E491CE0 -:109840005A41C26681662030C17B01291AD0C57396 -:109850008FE73DE0D48F01000D0A000010010020C9 -:10986000360A0000A8210020C12100202C01002080 -:1098700080210020A80A00000A070000220700003B -:109880007C070000C67374E7207A384370E7012A2A -:1098900001D0CD736DE7CE736BE7407A002817D106 -:1098A0001AE0F948022211434171C179491CC9B239 -:1098B000C17101290CD840692030007E00280BD0EE -:1098C000F2484078C106C90E052905D2C00603D06A -:1098D0000120FFF7BAF801E0FEF72EFFEA48017811 -:1098E00001290CD0C07A002809D0012808D002280C -:1098F00005D0032804D0E649E64801F02CFCF8BD69 -:109900000120F6F771FEF8BD10B5DF480078042895 -:1099100003D0DF49E04801F01EFC0120FFF795F875 -:1099200010BDF8B5D84C0427A07900250007002801 -:109930002FDA207A00282CD160692030C07C801E6C -:10994000132826D201007944097949188F44210946 -:1099500021212121212121212121212121212121F7 -:109960001A006069014640318D734A7F002A04D095 -:1099700006228A702030C7740BE016228A702030CD -:10998000C77406E0606901464031CD748D732030A4 -:10999000C57400F063F9BC4801268279500700289D -:1099A00022DAB948017A00291ED1406901462031E6 -:1099B0000B46C97C891E072916D20C007C442479E9 -:1099C0002419A744031111110B110E000146403157 -:1099D0008D73C030007A8870DF7405E0C030C672C5 -:1099E00002E00221C030C172A74C90074AD5207A0C -:1099F000002847D160692030C17C0120FEF76AFF52 -:109A000000283FD1A069C0780E287DD2010079449A -:109A1000097949188F44A7A706A73747630BA718EA -:109A2000A7279755616903202031C8749FE06069BA -:109A30002030C07C052803D09549984801F08BFB65 -:109A400060692030C57492E060692030C07C0928CC -:109A500003D08F49924801F07EFB60694E210D547E -:109A60002030C57483E060692030C07C0B2803D0AF -:109A700087498C4801F06FFB606953210E540C211B -:109A80002030C17473E060692030C07C0F2803D09F -:109A90007F49854801F05FFB606953210E54102116 -:109AA0002030C17463E060692030C07C102803D08E -:109AB00077497E4801F04FFB606912212030C17464 -:109AC00055E060692030C07C102803D07049784888 -:109AD00001F041FB606914212030C17447E06069E6 -:109AE0002030C07C162803D06949724801F033FB4E -:109AF000606901464030C5748573E031087D0028F7 -:109B000006D063492B2000E02DE0400101F023FB4B -:109B10006069014640310A7D002A08D00D754288EF -:109B2000F8210A520146E0318D750C2207E0418888 -:109B3000F82211520146E0318D758E760B220A759E -:109B40002030C57413E060690146C030827A062A6D -:109B500004D14031897D890700D58572C17A0629F3 -:109B600005D1C57203E04A49534801F0F4FAA079DF -:109B7000C00612D5207A00280FD160692030C17C40 -:109B800007290AD20A007A441279921897440505E7 -:109B90000505050503000721C174607A000727D574 -:109BA00060692030C17C0520FEF794FE002807D0B4 -:109BB000207A0821084320726069E030057517E0BB -:109BC000607938436071FAF7C3FE002803D1304949 -:109BD0003A4801F0C0FA60690023816EC26E491CE8 -:109BE0005A41C26681662030C17B012934D0C673D8 -:109BF00060693321095C08292DD10146028DC031ED -:109C00008B89521C9A4226D1227A002A23D14A8A71 -:109C100083889A4207D18B8AC788BB4203D1CB8AFB -:109C20000789BB4208D043888B85CA858A8A0A8601 -:109C3000CA8A4A86E8210E5401221146FAF723FA0D -:109C400000210420F9F717FA6069CB210D54203068 -:109C5000C57403218175F8BDC573C9E730B50A4CD9 -:109C600083B0A079C0077DD0207A00287AD16069BE -:109C70002030C17C0120FEF72DFE00284AD1E0698A -:109C8000C0780D286FD21BE0100100208021002039 -:109C9000D48F01000E0B0000160B000027050000FA -:109CA0002D050000340500003C05000043050000C0 -:109CB000490500005B050000BD0500009E03000093 -:109CC00001007944097949188F443B1506C14D4D6F -:109CD000FE24FD4D98B2FC00E069FAF7BEF8616918 -:109CE000C82250540222332042540020403148817F -:109CF0000120887385E160692030C17C0020FEF777 -:109D0000E9FD0028207A02D0002803D103E00121D8 -:109D10000843207275E1E069FAF798F86169CC228E -:109D200050520A8D801ABC4A00B290425FDC002873 -:109D30005DDDCE31E069FAF77EF8606906212030FA -:109D400083E060692030C17C0020FEF7C3FD00285D -:109D500003D1207A012108432072207A00284CD1B7 -:109D6000E06901E055E134E1FAF732F800282ED03D -:109D7000E069FAF728F86169CC2250520A8D801AFE -:109D8000A54A00B2904232DC002830DDE069FAF7E3 -:109D900014F86169C0318873E069FAF707F86169FE -:109DA000C0310882E069F9F7E6FF6169C031488295 -:109DB000E069F9F7E9FF6169C0318882E069F9F784 -:109DC000ECFF6169D62250520820203196E060698C -:109DD0002030C17C0020FEF77DFD002803D1207AD1 -:109DE000012108432072207A002806D100E12820B2 -:109DF0004222505404202031C87402E160692030AE -:109E0000C17C0020FEF766FD002803D1207A0121E5 -:109E100008432072207A00285FD160690022014641 -:109E200040304281012282730B202031C874E8E067 -:109E300060692030C17C0C2903D0217A02221143B1 -:109E40002172217A002948D10D21C174D9E06069BD -:109E50002030C17C0020FEF73DFD002808D160695C -:109E60004030007D002803D1207A01210843207270 -:109E7000207A002831D160690022014640304281B9 -:109E800001258573A831E069FAF704F86169E06992 -:109E90008031FAF710F86069E030007F002803D0C5 -:109EA0005E495F4801F057F96169FE204A884252D5 -:109EB000FF310131E069F9F7D7FF6169E069FF31EE -:109EC000093102E01CE056E008E0F9F7D9FF6069CB -:109ED000FC210D540F212030C17492E060690146CD -:109EE0002031CA7C122A03D0227A02231A4322721A -:109EF000227A002A6CD1403082731620C87480E028 -:109F000060690146C031CA7A002A06D0897A0629DA -:109F100003D0217A012211432172217A002970D1C4 -:109F20004030807D800715D4E069F9F7F5FF61695D -:109F30004031C875E069F9F7F1FF61694031088384 -:109F4000E069F9F7F0FF6169022240314883887DBA -:109F50001043887560690146C0318A7A062A01D1AA -:109F600000228A724030827DD2074AD10622CA720C -:109F70000021018245E060692030C17C0020FEF7AD -:109F8000A9FC002803D1207A012108432072207AFD -:109F9000002836D16946E069F9F7D5FF68460078B0 -:109FA000C107C90F6846017004D0606901214030C3 -:109FB000017703E060690021403001776069002289 -:109FC0000146403042810122827309202031C87449 -:109FD00017E060692030C17C0020FEF77BFC002880 -:109FE00003D1207A012108432072207A002808D169 -:109FF000E069F9F7BAFE61698922505405202031E1 -:10A00000C87461690023886ECA6E401C5A41CA66D2 -:10A01000886603B030BD0000FE7F0000D48F0100D1 -:10A020002104000047490968016000207047454944 -:10A030000860002070470121434A002803D001280E -:10A0400003D042487047916300E0D163002070471D -:10A050003F49012008603D48801C704704223D4B69 -:10A060003B49002805D05A60086901221043086165 -:10A0700008E008694008400008619A603249002001 -:10A08000C03188600020704731490622002808D07E -:10A09000012809D002280DD003280FD02B48401CDE -:10A0A00070470869904302E008699043801C08618A -:10A0B0000020704708699043001DF8E708691043C5 -:10A0C000F5E723494A6A02434A6200207047204963 -:10A0D0004A6A82434A62002070471D49496A01600A -:10A0E000002070471A49CA690243CA6100207047BC -:10A0F0001749CA698243CA61002070471449C96977 -:10A100000160002070471249024600204031002AB9 -:10A1100003D0012A01D0072070478A6370470D4998 -:10A120000420886008490020C03188600A4801681E -:10A130008022090A090211430160084901200860D0 -:10A140007047000000040040400000400420000070 -:10A15000000500400003004000E400E000E100E0F2 -:10A160008107C90E002808DA0007000F08388008A8 -:10A17000814A80008018C06904E080087F4A80001E -:10A1800080180068C8400006800F704710B504466C -:10A1900000F0DBF8002813D02046FFF7E1FFC0B243 -:10A1A00000F0E1F800280DD07549E2060B78D20ED8 -:10A1B00001209040002B08D04A681043486006E018 -:10A1C000704810BD6F48401C10BD6F4908600020EA -:10A1D00010BD10B5044600F0B8F800280BD068494F -:10A1E000E2060B78D20E01209040002B05D04A6881 -:10A1F00082434A6004E0634810BD634980310860CF -:10A20000002010BD70B50D46044600F09EF80028F1 -:10A210000BD05E480068E206D20E01219140084052 -:10A2200000D001202860002070BD564870BD10B5D8 -:10A23000044600F08AF8002807D0E106C90E012084 -:10A24000884052490860002010BD4E4810BD10B52E -:10A25000044600F07AF8002808D0E106C90E012073 -:10A2600088404A4980310860002010BD454810BD33 -:10A2700070B50D46044600F068F8002819D028464D -:10A2800000F071F8002816D0A007C10EFF228A4006 -:10A29000A807000E8840002C10DA2107090F0839A2 -:10A2A0008B0835499B005B18D96991430143D961FB -:10A2B0000CE0344870BD3348401C70BDA3082F49E2 -:10A2C0009B005B181968914301431960002070BD21 -:10A2D00070B50C46054600F038F8002805D0284631 -:10A2E000FFF73EFF2070002070BD264870BDBFF311 -:10A2F0004F8F21492648C860BFF34F8FFEE770B5E6 -:10A300001F4C05462178012000290ED1207072B61D -:10A3100000F0F4F81C4E803631688143616000F033 -:10A32000EDF8C043306062B600202870002070BD98 -:10A3300013490A78002A06D0002804D1124A486836 -:10A340001060002008700020704710B504462028D7 -:10A3500007DA00F0D3F80121A140084201D1012021 -:10A3600010BD002010BD012803D0032801D000201B -:10A37000704701207047000000ED00E000E400E0BD -:10A38000300100200120000000E100E000E200E0D8 -:10A390000400FA05F8B504468007002501260028C8 -:10A3A00004DA5848C563C66302208443E00404D538 -:10A3B0005548C563C66380148443600003D5534881 -:10A3C000456080058443E00504D55148C563C663F4 -:10A3D00080158443A00404D54E48C563C663401469 -:10A3E000844360042704C00FF90F884203D04AA1B8 -:10A3F000612000F0B0FEB80F0AD04C49CD634C4844 -:10A40000C563C563CE63C663C6630320800384430C -:10A4100020050AD5474FFD632F20E6F7C5FEFE63F2 -:10A420002F20E6F7C1FEF8148443F7F7D7FF424820 -:10A43000044203D038A18D2000F08DFEF8BDF0B5A8 -:10A4400000210A46FF230446CC40E4072AD04CB240 -:10A45000E606F60E0125B540384E3560384E3560BB -:10A46000002C11DA25072D0F083DAE08354DB6003A -:10A470007719FD69A407E60E1C46B440A5431446AF -:10A48000B4402543FD610DE0A6082F4DB6007619B6 -:10A490003568A407E70E1C46BC40A5431446BC40E3 -:10A4A00025433560491C2029CDD3F0BD70B5274C1C -:10A4B0000D462060FFF76EFF2068FFF7C0FF2846BB -:10A4C000E8F766F8F7F796FEF1F792FDF7F786FFE3 -:10A4D000FFF725FEE7F7E2FE00F06AF870BD10B561 -:10A4E0001A4C2068FFF756FF2068FFF7A8FFF7F720 -:10A4F00075FFE8F7C7F80020206010BD134800681A -:10A5000070470000C01F0040C0CF004000E5014080 -:10A51000C08F0040C0DF00407372635C736F635F85 -:10A52000636F6E6669672E6300000000C0EF004035 -:10A53000C0FF0040C0BF0040FEFF0FFC80E100E014 -:10A5400080E200E000ED00E000E400E038010020DF -:10A5500070B5002402460D4620462146002A1ED032 -:10A56000012A04D0022A04D0032A1ED103E00120CC -:10A5700002E0022013E003202B0000F00DFF07167D -:10A580000507090B0D0F1600012108E0022106E066 -:10A59000032104E0042102E0052100E00621F2F796 -:10A5A00058FA002801D0204670BD0724FBE70000C0 -:10A5B000B348002101708170704770B5B14D01231F -:10A5C0006B60B14B1C68002CFCD0002407E00E68C7 -:10A5D00006601E68002EFCD0001D091D641C9442FC -:10A5E000F5D30020686018680028FCD070BD70B5F5 -:10A5F000A34C0E466178884203D0A4A16F2000F0DE -:10A60000AAFD0325330000F0C7FE09520624245298 -:10A610005252524952002078022803D09BA1732045 -:10A6200000F099FD2570A078022802D0012804D0FE -:10A6300008E0A068E8F7C6FC04E02046083007C838 -:10A64000FFF7BBFF0020A070F2F7A4F904202070F0 -:10A6500070BDF2F754FA01466068F3F769FC0646EC -:10A660002078022803D089A1872000F074FD8B4A4E -:10A670008B498C48964205D86269032A02D2521C43 -:10A68000626102E0864207D84D71801BC860844930 -:10A690006078F2F7ABFE70BD032003E0A0780028DD -:10A6A000FAD10220F2F77EF800F0E1F870BD77A150 -:10A6B000B12000F050FD70BD70B50546F2F71FFAED -:10A6C0006F4C60602078012803D070A1B82000F0A2 -:10A6D00042FD73490220087000220A718D60042235 -:10A6E0004A71704ACA6020706078F2F77FFE70BDD0 -:10A6F00010B5634CA078002802D12078002801D042 -:10A70000112010BD6848F2F78BF96070607800285E -:10A7100004D0012020700020606110BD032010BD16 -:10A7200010B50124020B64040121604BA04202D247 -:10A730009140186802E0203A58689140084000D0E3 -:10A74000012010BDF8B50E46910005464F1914467C -:10A750003F1F0091E8F747FC009980028919091F03 -:10A76000B14201D2012200E00022002C03D0FF21DF -:10A7700001318C4201D90920F8BD4D498D4219D3D0 -:10A78000AF4217D3854205D2874203D228463043D1 -:10A79000800701D01020F8BD8E420BD3002A09D1CA -:10A7A0002846FFF7BDFF002804D13846FFF7B8FF61 -:10A7B000002801D00F20F8BD3E483F49006888427C -:10A7C00005D0224631462846FFF7F7FE0FE0FFF797 -:10A7D0008FFF0028EFD12A480121C66085600461FF -:10A7E00081702046302148431830FFF765FF002074 -:10A7F000F8BD10B504462E48800A84420BD3E8F712 -:10A80000F2FBA04201D8102010BDA0020446FFF7C1 -:10A8100087FF002801D00F2010BD26482649006878 -:10A82000884203D02046E8F7CDFB0AE0FFF760FF3F -:10A830000028F1D112480221846081701F48FFF77F -:10A840003BFF002010BD1A48010B01208840401E2C -:10A85000704700B50B460246FFF7F5FF104201D0E6 -:10A860000F2000BD114802604360002000BD10B5FC -:10A87000034C6078F2F728F900202070A07010BD1A -:10A880003C01002000E5014000E401407372635C7C -:10A89000736F635F666C6173682E630030750000D0 -:10A8A000D0210020D0FB0100EFA5010000060040F0 -:10A8B00000C0010064000020BEBAFECA3A56000083 -:10A8C000F94805218170002101704170C1708160DB -:10A8D000704710B5F5490A78022A07D0CA681018DF -:10A8E000C860C8689638F3F7DBFA10BD8A6810189C -:10A8F00088608868F6E70378ED49EE4A002B02D0BD -:10A90000012B10D014E00379002B01D0012B0FD1C3 -:10A910004379002B01D0012B0AD18368643B8B4221 -:10A9200006D2C06810E00379002B03D0012B01D0C0 -:10A93000002070474379002B01D0012BF8D1C36868 -:10A94000643B8B42F4D280689042F1D8012070477A -:10A95000F8B504460226F2F731FF0068002803D05C -:10A96000D5A1BD2000F0F7FB0127CF4D002C08D06A -:10A970002078002817D0012805D0022811D00328FC -:10A9800013D02F710DE06068C82808D3F3F7FEFAE2 -:10A99000002804D06068FFF79CFF012603E0002632 -:10A9A00001E000F0FDF93046F8BD28780028F8D124 -:10A9B0006068FFF7A0FF0028E3D0606800780028F7 -:10A9C00026D0A878042803D0BBA1F72000F0C3FB51 -:10A9D000B64F0020387060680079012800D0002050 -:10A9E000387160684079002837D004207871606839 -:10A9F0008168E868F2F715FBB8606068C068963057 -:10AA0000F8600320A870A949E878F2F7EFFCC8E7DE -:10AA1000A6480221017061680979012919D0002135 -:10AA2000017161684979002915D00421417161687B -:10AA30008968963181606168C968C160C0689A4C54 -:10AA400014346060F2F75BF820606F700220A87029 -:10AA5000A7E70321E4E70321E8E70320C6E7F8B509 -:10AA6000914C0D46E178884204D0FF2092A11A3023 -:10AA700000F071FB2846002501268C4F030000F0F2 -:10AA80008BFC0906123C5E82939DCAA6CA00A07880 -:10AA9000032807D0A078022804D0FF2086A11E300A -:10AAA00000F059FBF8BDA078032807D0A078022851 -:10AAB00004D0FF2080A1223000F04DFB0420A070C4 -:10AAC00025712078002815D1FFF703FF3878022878 -:10AAD0000CD0B868E0607F49886A7F4A02402261F2 -:10AAE0007D4AD24310408862002055E0E078F2F7BA -:10AAF000BFFAEFE700F054F9F8BDA078032807D0BB -:10AB0000A078022804D0FF206BA14B3000F023FB7B -:10AB10002078002802D000F04FF9F8BDA078032873 -:10AB20001ED104202BE0081AF8606049E078F2F7A3 -:10AB30005DFCF8BD0420F1F735FEA570F8BDA078E6 -:10AB4000032807D0A078022804D0FF205AA16C3037 -:10AB500000F001FB20780028DDD1A07803280DD07B -:10AB6000F1F7CDFF504E014614363068F3F7E0F9A7 -:10AB70000028DFDB71688142DCDBD4E70520F1F7D8 -:10AB800011FEA670F8BDA078042804D0FF204AA1C9 -:10AB90008D3000F0E0FA0220A1688847FFF7D8FE68 -:10ABA000FF260546C63642E0A078042804D0FF20E0 -:10ABB00041A1923000F0CFFA0120EDE7A0780428FF -:10ABC00098D0FF203CA1973000F0C5FA92E7A0781A -:10ABD00004280AD06078002802D0A078022804D087 -:10ABE000FF2035A19C3000F0B6FA2078002892D1E1 -:10ABF0002079002804D00620F1F7D4FD2571C0E7A4 -:10AC00006078002805D02949E078F2F7EFFB6570FD -:10AC1000F8BD0720B3E7FF2027A1B73040E7002D9C -:10AC20000AD0012D06D024A1304600F094FA022D5E -:10AC3000F5D1F8BD042000E00320A1688847FFF7A4 -:10AC400087FE0546F3E770B5050005D0164CA078E1 -:10AC5000052803D0112070BD102070BD1F48F1F7EA -:10AC6000DFFEE070E078002803D0A5600020A0702F -:10AC700070BD032070BD10B50B480178002901D0CC -:10AC8000112010BD817805292AD08178012929D089 -:10AC90008178002926D0012101708178012921D0F5 -:10ACA000807800281ED01FE054010020E021002001 -:10ACB0003D860100FF1FA1077372635C736F635FC2 -:10ACC000726164696F5F74696D65736C6F742E6314 -:10ACD0000000000000050040028100005FAA0100A2 -:10ACE0000F2010BD00F068F8002010BDF8B5394EF7 -:10ACF0000446B078002801D001280DD1002C0DD0D9 -:10AD00002046FFF7F8FD00280AD02078324D0028B1 -:10AD100008D0B078012823D00F20F8BD1020F8BD4E -:10AD20000720F8BD02272F702079012814D00020B9 -:10AD300028716079002811D004206871A0689630CD -:10AD4000A860E068E860E868224C14346060F1F7BD -:10AD5000D6FE2060B77019E00320E9E70320ECE796 -:10AD6000002028702079012816D0002028716079F1 -:10AD7000002813D004206871A168F068F2F751F937 -:10AD8000A860E0689630E8600320B0701249F0785F -:10AD9000F2F72CFB0020F8BD0320E7E70320EAE7E9 -:10ADA00010B50E48816A0E4A11400A4A12691143D1 -:10ADB0008162F1F7EFFD10BD10B5064CE078F1F7B8 -:10ADC00083FE0820F1F7EEFC0520A0700020207023 -:10ADD000607010BD54010020E021002000050040FB -:10ADE000FD7EFFFF70477047034610B50B439B077E -:10ADF0000FD1042A0DD308C810C9121FA342F8D0DE -:10AE000018BA21BA884201D9012010BD0020C043E0 -:10AE100010BD002A03D0D30703D0521C07E0002046 -:10AE200010BD03780C78401C491C1B1B07D103780C -:10AE30000C78401C491C1B1B01D1921EF1D11846F5 -:10AE400010BDF8B5042A2CD3830712D00B78491C07 -:10AE50000370401C521E83070BD00B78491C0370F3 -:10AE6000401C521E830704D00B78491C0370401C01 -:10AE7000521E8B079B0F05D0C91ADF002023DE1B53 -:10AE800008C90AE0E6F7A0F9F8BD1D4608C9FD406B -:10AE90001C46B4402C4310C0121F042AF5D2F308FC -:10AEA000C91A521EF0D40B78491C0370401C521E64 -:10AEB000EAD40B78491C0370401C012AE4D40978B9 -:10AEC0000170F8BD01E004C0091F0429FBD28B0703 -:10AED00001D50280801CC90700D00270704700298C -:10AEE0000BD0C30702D00270401C491E022904D3B4 -:10AEF000830702D50280801C891EE3E70022EEE76B -:10AF00000022DFE7020A08704A70020C8A70020E03 -:10AF1000CA707047002203098B4273D3030A8B4225 -:10AF200058D3030B8B423CD3030C8B4221D312E04A -:10AF300003460B437FD4002243088B4274D303099A -:10AF40008B425FD3030A8B4244D3030B8B4228D33B -:10AF5000030C8B420DD3FF22090212BA030C8B4261 -:10AF600002D31212090265D0030B8B4219D300E001 -:10AF7000090AC30B8B4201D3CB03C01A5241830B86 -:10AF80008B4201D38B03C01A5241430B8B4201D336 -:10AF90004B03C01A5241030B8B4201D30B03C01A5F -:10AFA0005241C30A8B4201D3CB02C01A5241830AD9 -:10AFB0008B4201D38B02C01A5241430A8B4201D308 -:10AFC0004B02C01A5241030A8B4201D30B02C01A32 -:10AFD0005241CDD2C3098B4201D3CB01C01A524199 -:10AFE00083098B4201D38B01C01A524143098B4222 -:10AFF00001D34B01C01A524103098B4201D30B010B -:10B00000C01A5241C3088B4201D3CB00C01A52412F -:10B0100083088B4201D38B00C01A524143088B42F4 -:10B0200001D34B00C01A5241411A00D2014652418D -:10B03000104670475DE0CA0F00D04942031000D3AC -:10B040004042534000229C4603098B422DD3030A01 -:10B050008B4212D3FC22890112BA030A8B420CD311 -:10B06000890192118B4208D3890192118B4204D33A -:10B0700089013AD0921100E08909C3098B4201D3BA -:10B08000CB01C01A524183098B4201D38B01C01AF4 -:10B09000524143098B4201D34B01C01A524103096B -:10B0A0008B4201D30B01C01A5241C3088B4201D31A -:10B0B000CB00C01A524183088B4201D38B00C01AC7 -:10B0C0005241D9D243088B4201D34B00C01A52419E -:10B0D000411A00D20146634652415B10104601D32B -:10B0E0004042002B00D54942704763465B1000D3B5 -:10B0F000404201B50020C046C04602BD70477047BF -:10B10000704710B500F058F810BD30B58C180278B3 -:10B11000401C13071B0F01D10378401C120906D1F4 -:10B120000278401C03E00578401C0D70491C5B1E32 -:10B13000F9D101E00B70491C521EFBD1A142E6D3AC -:10B14000002030BD012308CB134B1860134B19604E -:10B15000134B1A607047134A134B13607246053A3B -:10B16000F0E7114A0F4B1B689A420ED10D4B00209D -:10B17000186001980D4B04B598470CBC9E460246DA -:10B18000029800990A4B1B68184706980599094BC5 -:10B190001B68DB6818470000780100207C01002054 -:10B1A0008001002070010020EFBEADDE4D2F0000B9 -:10B1B00098000020040000201D481E497047FFF73A -:10B1C000FBFFE5F7BBFF00BD01200007C06AC0B26E -:10B1D000FF2804D1184819490968884202D0184844 -:10B1E00018490160184819490968884203D1184A6A -:10B1F00013605B68184700BD20BFFDE71248134984 -:10B20000096888420ED1134B18680B498842F3D065 -:10B2100080F308881049884204DD10480268022142 -:10B220000A4302600E4880470E4880470E48004798 -:10B23000F0210020F0210020FFFFFFFF0010001090 -:10B240002C05004008000000001000000000002055 -:10B250000400002000C00100002000202405004060 -:10B26000632F0000C9B1010045B1010013487045CA -:10B2700002D1EFF3098101E0EFF308818869023818 -:10B280000078102814DB202810DB2B280BDB0C4A5D -:10B2900012680C4B9A4203D1602804DB0A4A10471B -:10B2A000022008607047094A10470000084A10470A -:10B2B000084A12682C32126810470000FDFFFFFF99 -:10B2C00064000020BEBAFECAAD120000991F010042 -:10B2D0001B1F0100040000200D4B0E4908470E4BB8 -:10B2E0000C4908470D4B0B4908470D4B09490847C6 -:10B2F0000C4B084908470C4B064908470B4B0549BE -:10B3000008470B4B034908470A4B0249084700000E -:10B31000B125000051220000D52B0000772A000043 -:10B32000252A0000D7270000B912000017140000DA -:10B33000392B0000472300000A7802704B784370D5 -:10B340008A788270CA78C2700B79037170470A7864 -:10B3500002704B7843708A788270CA78C2700B7919 -:10B3600003714A79427170470A7802704B784370D2 -:10B370008A788270CA78C2700B7903714A794271F7 -:10B380008A798271CB79C37170470A8802804A88B2 -:10B3900042800A790271704730B47446641E257881 -:10B3A000641CAB4200D21D46635D5B00E31830BCF9 -:10B3B00018470000FFFFFFFF0000FFFF0100030030 -:10B3C000000001000000000000000000000000007C -:10B3D00000000000870000000000000000000000E6 -:10B3E0000000000000000001020304000D0E0F1019 -:10B3F000000000000F6900002D6B0000F56B0000DD -:10B400004F6C0000A36C00000B6D00006969000028 -:10B41000216A0000AD6D0000BB7900001001100131 -:10B420003A0200001A020000040104013C00170067 -:10B4300044000E00F401FA00960064004B00320054 -:10B440001E001400010204081020408055555525A7 -:10B450002627D6BE898E555555D6BE898E0000004A -:10B460007006120DB413000014035A06A009000060 -:10B470006004F208840D0000A8B401000800002058 -:10B480001000000004110000B8B4010018000020F2 -:10B490006C0100000AB10100D8B401008401002051 -:10B4A0006C20000020110000024801688907FCD5CB -:10B4B0007047000000E200E0013536010001005451 -:10B4C0003720FB349B5F80B4800010026801337F1B -:08B4D0000102A029E449B101C9 -:00000001FF diff --git a/components/softdevice/s120/doc/s120_nrf51822_2.0.0_licence_agreement.txt b/components/softdevice/s130/hex/s130_nrf51_2.0.1_licence-agreement.txt similarity index 71% rename from components/softdevice/s120/doc/s120_nrf51822_2.0.0_licence_agreement.txt rename to components/softdevice/s130/hex/s130_nrf51_2.0.1_licence-agreement.txt index ef3a1dc..09a78bb 100644 --- a/components/softdevice/s120/doc/s120_nrf51822_2.0.0_licence_agreement.txt +++ b/components/softdevice/s130/hex/s130_nrf51_2.0.1_licence-agreement.txt @@ -1,91 +1,96 @@ -S110/S120 license agreement - -NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT - -License Agreement for the Nordic Semiconductor ASA ("Nordic") S110 and S120 Bluetooth SoftDevice software packages ("SoftDevice"). - -You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before -downloading, installing and/or using any software or content in the SoftDevice provided herewith. - -YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS -OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF -THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. - -IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE -INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. - -1. Grant of License -Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license -("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated -in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this -agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. - -2. Title -Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and -other intellectual property rights in and to the SoftDevice. - -3. No Modifications or Reverse Engineering -Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code -parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. - -4. Distribution Restrictions -Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. -Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. -Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee -necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making -such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. - -5. No Other Rights -Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be -contrary to this Agreement. - -6. Fees -Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to -comply with the Agreement. - -7. DISCLAIMER OF WARRANTY -THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS -LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR -THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE -IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE -REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. -LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S -INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. - -8. No Support -Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, -bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. - -9. Limitation of Liability -In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of -procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any -special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, -tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, -licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or -limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to -USD 50. - -10. Breach of Contract -Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably -attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both -direct and indirect costs for Nordic and its licensors. - -11. Indemnity -Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and -agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which -is not due to causes for which Nordic is responsible. - -12. Governing Law -This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. - -13. Assignment -Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. - -14. Termination -Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this -Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any -other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. - -15. Third party beneficiaries -Nordic’s licensors are intended third party beneficiaries under this Agreement. \ No newline at end of file +S110/S120/S130/S132 license agreement + + +NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT + +License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120, S130 and S132 Bluetooth SoftDevice software packages +("SoftDevice"). + +You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before +downloading, installing and/or using any software or content in the SoftDevice provided herewith. + +YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS +OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF +THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. + +IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE +INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. + +1. Grant of License +Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license +("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated +in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this +agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. + +2. Title +Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and +other intellectual property rights in and to the SoftDevice. + +3. No Modifications or Reverse Engineering +Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code +parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. + +4. Distribution Restrictions +Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. +Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. +Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee +necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making +such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. + +5. No Other Rights +Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be +contrary to this Agreement. + +6. Fees +Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to +comply with the Agreement. + +7. DISCLAIMER OF WARRANTY +THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS +LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR +THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE +IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE +REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. +LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S +INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. + + +8. No Support +Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, +bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. + +9. Limitation of Liability +In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of +procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any +special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, +tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, +licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or +limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to +USD 50. + +10. Breach of Contract +Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably +attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both +direct and indirect costs for Nordic and its licensors. + +11. Indemnity +Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and +agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which +is not due to causes for which Nordic is responsible. + +12. Governing Law +This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. + +13. Assignment +Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. + +14. Termination +Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this +Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any +other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. + +15. Third party beneficiaries +Nordic’s licensors are intended third party beneficiaries under this Agreement. + + diff --git a/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51422_xxaa.ld b/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51422_xxaa.ld index c925a32..ea5aee6 100644 --- a/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51422_xxaa.ld +++ b/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51422_xxaa.ld @@ -5,18 +5,24 @@ GROUP(-lgcc -lc -lnosys) MEMORY { - FLASH (rx) : ORIGIN = 0x1c000, LENGTH = 0x24000 - RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x1800 + FLASH (rx) : ORIGIN = 0x1b000, LENGTH = 0x25000 + RAM (rwx) : ORIGIN = 0x200013c8, LENGTH = 0x2c38 } SECTIONS { - .fs_data_out ALIGN(4): + .fs_data : { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM + .pwr_mgmt_data : + { + PROVIDE(__start_pwr_mgmt_data = .); + KEEP(*(.pwr_mgmt_data)) + PROVIDE(__stop_pwr_mgmt_data = .); + } > RAM +} INSERT AFTER .data; -INCLUDE "nrf5x_common.ld" \ No newline at end of file +INCLUDE "nrf5x_common.ld" diff --git a/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51422_xxac.ld b/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51422_xxac.ld index 987b1d2..c969e93 100644 --- a/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51422_xxac.ld +++ b/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51422_xxac.ld @@ -5,18 +5,24 @@ GROUP(-lgcc -lc -lnosys) MEMORY { - FLASH (rx) : ORIGIN = 0x1c000, LENGTH = 0x24000 - RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x5800 + FLASH (rx) : ORIGIN = 0x1b000, LENGTH = 0x25000 + RAM (rwx) : ORIGIN = 0x200013c8, LENGTH = 0x6c38 } SECTIONS { - .fs_data_out ALIGN(4): + .fs_data : { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM + .pwr_mgmt_data : + { + PROVIDE(__start_pwr_mgmt_data = .); + KEEP(*(.pwr_mgmt_data)) + PROVIDE(__stop_pwr_mgmt_data = .); + } > RAM +} INSERT AFTER .data; -INCLUDE "nrf5x_common.ld" \ No newline at end of file +INCLUDE "nrf5x_common.ld" diff --git a/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51822_xxaa.ld b/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51822_xxaa.ld index c925a32..ea5aee6 100644 --- a/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51822_xxaa.ld +++ b/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51822_xxaa.ld @@ -5,18 +5,24 @@ GROUP(-lgcc -lc -lnosys) MEMORY { - FLASH (rx) : ORIGIN = 0x1c000, LENGTH = 0x24000 - RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x1800 + FLASH (rx) : ORIGIN = 0x1b000, LENGTH = 0x25000 + RAM (rwx) : ORIGIN = 0x200013c8, LENGTH = 0x2c38 } SECTIONS { - .fs_data_out ALIGN(4): + .fs_data : { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM + .pwr_mgmt_data : + { + PROVIDE(__start_pwr_mgmt_data = .); + KEEP(*(.pwr_mgmt_data)) + PROVIDE(__stop_pwr_mgmt_data = .); + } > RAM +} INSERT AFTER .data; -INCLUDE "nrf5x_common.ld" \ No newline at end of file +INCLUDE "nrf5x_common.ld" diff --git a/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51822_xxab.ld b/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51822_xxab.ld index 9f02c11..cfaad22 100644 --- a/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51822_xxab.ld +++ b/components/softdevice/s130/toolchain/armgcc/armgcc_s130_nrf51822_xxab.ld @@ -5,18 +5,24 @@ GROUP(-lgcc -lc -lnosys) MEMORY { - FLASH (rx) : ORIGIN = 0x1c000, LENGTH = 0x4000 - RAM (rwx) : ORIGIN = 0x20002800, LENGTH = 0x1800 + FLASH (rx) : ORIGIN = 0x1b000, LENGTH = 0x5000 + RAM (rwx) : ORIGIN = 0x200013c8, LENGTH = 0x2c38 } SECTIONS { - .fs_data_out ALIGN(4): + .fs_data : { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM + .pwr_mgmt_data : + { + PROVIDE(__start_pwr_mgmt_data = .); + KEEP(*(.pwr_mgmt_data)) + PROVIDE(__stop_pwr_mgmt_data = .); + } > RAM +} INSERT AFTER .data; -INCLUDE "nrf5x_common.ld" \ No newline at end of file +INCLUDE "nrf5x_common.ld" diff --git a/components/softdevice/s130/toolchain/iar/iar_s130_nrf51422_xxaa.icf b/components/softdevice/s130/toolchain/iar/iar_s130_nrf51422_xxaa.icf index 5d78384..830cb6f 100644 --- a/components/softdevice/s130/toolchain/iar/iar_s130_nrf51422_xxaa.icf +++ b/components/softdevice/s130/toolchain/iar/iar_s130_nrf51422_xxaa.icf @@ -2,12 +2,14 @@ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x1c000; +define symbol __ICFEDIT_intvec_start__ = 0x1b000; /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x1c000; +define symbol __ICFEDIT_region_ROM_start__ = 0x1b000; define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002800; +define symbol __ICFEDIT_region_RAM_start__ = 0x200013c8; define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; +export symbol __ICFEDIT_region_RAM_start__; +export symbol __ICFEDIT_region_RAM_end__; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x200; @@ -29,3 +31,4 @@ place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; + diff --git a/components/softdevice/s130/toolchain/iar/iar_s130_nrf51422_xxac.icf b/components/softdevice/s130/toolchain/iar/iar_s130_nrf51422_xxac.icf index 97e1f9e..84e7d71 100644 --- a/components/softdevice/s130/toolchain/iar/iar_s130_nrf51422_xxac.icf +++ b/components/softdevice/s130/toolchain/iar/iar_s130_nrf51422_xxac.icf @@ -2,12 +2,14 @@ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x1c000; +define symbol __ICFEDIT_intvec_start__ = 0x1b000; /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x1c000; +define symbol __ICFEDIT_region_ROM_start__ = 0x1b000; define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002800; +define symbol __ICFEDIT_region_RAM_start__ = 0x200013c8; define symbol __ICFEDIT_region_RAM_end__ = 0x20007fff; +export symbol __ICFEDIT_region_RAM_start__; +export symbol __ICFEDIT_region_RAM_end__; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x200; @@ -29,3 +31,4 @@ place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; + diff --git a/components/softdevice/s130/toolchain/iar/iar_s130_nrf51822_xxaa.icf b/components/softdevice/s130/toolchain/iar/iar_s130_nrf51822_xxaa.icf index 5d78384..830cb6f 100644 --- a/components/softdevice/s130/toolchain/iar/iar_s130_nrf51822_xxaa.icf +++ b/components/softdevice/s130/toolchain/iar/iar_s130_nrf51822_xxaa.icf @@ -2,12 +2,14 @@ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x1c000; +define symbol __ICFEDIT_intvec_start__ = 0x1b000; /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x1c000; +define symbol __ICFEDIT_region_ROM_start__ = 0x1b000; define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002800; +define symbol __ICFEDIT_region_RAM_start__ = 0x200013c8; define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; +export symbol __ICFEDIT_region_RAM_start__; +export symbol __ICFEDIT_region_RAM_end__; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x200; @@ -29,3 +31,4 @@ place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; + diff --git a/components/softdevice/s130/toolchain/iar/iar_s130_nrf51822_xxab.icf b/components/softdevice/s130/toolchain/iar/iar_s130_nrf51822_xxab.icf index 511e44d..f0e510d 100644 --- a/components/softdevice/s130/toolchain/iar/iar_s130_nrf51822_xxab.icf +++ b/components/softdevice/s130/toolchain/iar/iar_s130_nrf51822_xxab.icf @@ -2,12 +2,14 @@ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x1c000; +define symbol __ICFEDIT_intvec_start__ = 0x1b000; /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x1c000; +define symbol __ICFEDIT_region_ROM_start__ = 0x1b000; define symbol __ICFEDIT_region_ROM_end__ = 0x1ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002800; +define symbol __ICFEDIT_region_RAM_start__ = 0x200013c8; define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; +export symbol __ICFEDIT_region_RAM_start__; +export symbol __ICFEDIT_region_RAM_end__; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x200; @@ -29,3 +31,4 @@ place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; + diff --git a/components/softdevice/s132/doc/s132_nrf52_3.0.0_licence_agreement.pdf b/components/softdevice/s132/doc/s132_nrf52_3.0.0_licence_agreement.pdf new file mode 100644 index 0000000000000000000000000000000000000000..68424a831e694bab02025a4332a1f0873094fc29 GIT binary patch literal 5532 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 S{26r^2nwbZ7S=RE(*74LM~6oM literal 0 HcmV?d00001 diff --git a/components/softdevice/s110/doc/s110_nrf51_8.0.0_licence-agreement.txt b/components/softdevice/s132/doc/s132_nrf52_3.0.0_licence_agreement.txt similarity index 71% rename from components/softdevice/s110/doc/s110_nrf51_8.0.0_licence-agreement.txt rename to components/softdevice/s132/doc/s132_nrf52_3.0.0_licence_agreement.txt index e1db300..09a78bb 100644 --- a/components/softdevice/s110/doc/s110_nrf51_8.0.0_licence-agreement.txt +++ b/components/softdevice/s132/doc/s132_nrf52_3.0.0_licence_agreement.txt @@ -1,88 +1,96 @@ -S110/S120 license agreement - -NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT -License Agreement for the Nordic Semiconductor ASA ("Nordic") S110 and S120 Bluetooth SoftDevice software packages ("SoftDevice"). -You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before -downloading, installing and/or using any software or content in the SoftDevice provided herewith. - -YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS -OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF -THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. -IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE -INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. - -1. Grant of License -Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license -("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated -in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this -agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. - -2. Title -Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and -other intellectual property rights in and to the SoftDevice. - -3. No Modifications or Reverse Engineering -Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code -parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. - -4. Distribution Restrictions -Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. -Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. -Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee -necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making -such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. - -5. No Other Rights -Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be -contrary to this Agreement. - -6. Fees -Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to -comply with the Agreement. - -7. DISCLAIMER OF WARRANTY -THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS -LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR -THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE -IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE -REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. -LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S -INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. - -8. No Support -Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, -bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. - -9. Limitation of Liability -In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of -procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any -special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, -tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, -licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or -limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to -USD 50. - -10. Breach of Contract -Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably -attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both -direct and indirect costs for Nordic and its licensors. - -11. Indemnity -Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and -agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which -is not due to causes for which Nordic is responsible. - -12. Governing Law -This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. - -13. Assignment -Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. - -14. Termination -Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this -Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any -other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. - -15. Third party beneficiaries -Nordic’s licensors are intended third party beneficiaries under this Agreement. +S110/S120/S130/S132 license agreement + + +NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT + +License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120, S130 and S132 Bluetooth SoftDevice software packages +("SoftDevice"). + +You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before +downloading, installing and/or using any software or content in the SoftDevice provided herewith. + +YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS +OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF +THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. + +IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE +INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. + +1. Grant of License +Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license +("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated +in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this +agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. + +2. Title +Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and +other intellectual property rights in and to the SoftDevice. + +3. No Modifications or Reverse Engineering +Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code +parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. + +4. Distribution Restrictions +Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. +Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. +Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee +necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making +such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. + +5. No Other Rights +Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be +contrary to this Agreement. + +6. Fees +Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to +comply with the Agreement. + +7. DISCLAIMER OF WARRANTY +THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS +LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR +THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE +IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE +REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. +LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S +INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. + + +8. No Support +Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, +bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. + +9. Limitation of Liability +In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of +procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any +special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, +tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, +licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or +limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to +USD 50. + +10. Breach of Contract +Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably +attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both +direct and indirect costs for Nordic and its licensors. + +11. Indemnity +Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and +agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which +is not due to causes for which Nordic is responsible. + +12. Governing Law +This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. + +13. Assignment +Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. + +14. Termination +Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this +Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any +other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. + +15. Third party beneficiaries +Nordic’s licensors are intended third party beneficiaries under this Agreement. + + diff --git a/components/softdevice/s132/doc/s132_nrf52_3.0.0_migration_document.pdf b/components/softdevice/s132/doc/s132_nrf52_3.0.0_migration_document.pdf new file mode 100644 index 0000000000000000000000000000000000000000..71b8df45903fff1be07292e2be6bb3c36796accc GIT binary patch literal 71996 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 Lv$M;p%HjVnTlxp| literal 0 HcmV?d00001 diff --git a/components/softdevice/s132/doc/s132_nrf52_3.0.0_readme.txt b/components/softdevice/s132/doc/s132_nrf52_3.0.0_readme.txt new file mode 100644 index 0000000..f4d870d --- /dev/null +++ b/components/softdevice/s132/doc/s132_nrf52_3.0.0_readme.txt @@ -0,0 +1,12 @@ +s132_nrf52_3.0.0 + +This release consists of the following: +- This readme file +- The s132_nrf52_3.0.0 API (SoftDevice header files) +- The s132_nrf52_3.0.0 license agreement +- The s132_nrf52_3.0.0 release notes +- The s132_nrf52_3.0.0 SoftDevice (binary hex file) +- The s13x_nrf5x_3.0.0 migration document +- The s13x_nrf5x_3.0.0 API diff + + diff --git a/components/softdevice/s132/doc/s132_nrf52_3.0.0_releasenotes.pdf b/components/softdevice/s132/doc/s132_nrf52_3.0.0_releasenotes.pdf new file mode 100644 index 0000000000000000000000000000000000000000..33ab892d582292e733a35f596769ccca8c2a9268 GIT binary patch literal 55456 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

&*4X+C8foJO}n$v@i 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 Ue_0V0W+rA97*bLpX_EVT series. */ + uint16_t evt_len; /**< Length in octets including this header. */ +} ble_evt_hdr_t; + +/**@brief Common BLE Event type, wrapping the module specific event reports. */ +typedef struct +{ + ble_evt_hdr_t header; /**< Event header. */ + union + { + ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ + ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ + ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ + ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ + ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ + } evt; /**< Event union. */ +} ble_evt_t; + + +/** + * @brief Version Information. + */ +typedef struct +{ + uint8_t version_number; /**< Link Layer Version number for BT 4.1 spec is 7 (https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer). */ + uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ + uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ +} ble_version_t; + +/** + * @brief Configuration parameters for the PA and LNA. + */ +typedef struct +{ + uint8_t enable :1; /**< Enable toggling for this amplifier */ + uint8_t active_high :1; /**< Set the pin to be active high */ + uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */ +} ble_pa_lna_cfg_t; + +/** + * @brief PA & LNA GPIO toggle configuration + * + * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or + * a low noise amplifier. + * + * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided + * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * @note This feature is only supported for nRF52, on nRF51 @ref NRF_ERROR_NOT_SUPPORTED will always be returned. + * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences + * and must be avoided by the application. + */ +typedef struct +{ + ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */ + ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */ + + uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */ + uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */ + uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */ +} ble_common_opt_pa_lna_t; + +/** + * @brief BLE connection bandwidth configuration parameters + */ +typedef struct +{ + uint8_t conn_bw_tx; /**< Connection bandwidth configuration for transmission, see @ref BLE_CONN_BWS.*/ + uint8_t conn_bw_rx; /**< Connection bandwidth configuration for reception, see @ref BLE_CONN_BWS.*/ +} ble_conn_bw_t; + +/**@brief BLE connection specific bandwidth configuration parameters. + * + * This can be used with @ref sd_ble_opt_set to set the bandwidth configuration to be used when creating connections. + * + * Call @ref sd_ble_opt_set with this option prior to calling @ref sd_ble_gap_adv_start or @ref sd_ble_gap_connect. + * + * The bandwidth configurations set via @ref sd_ble_opt_set are maintained separately for central and peripheral + * connections. The given configurations are used for all future connections of the role indicated in this structure + * unless they are changed by subsequent @ref sd_ble_opt_set calls. + * + * @note When this option is not used, the SoftDevice will use the default options: + * - @ref BLE_CONN_BW_HIGH for @ref BLE_GAP_ROLE_PERIPH connections (both transmission and reception). + * - @ref BLE_CONN_BW_MID for @ref BLE_GAP_ROLE_CENTRAL connections (both transmisison and reception). + * This option allows the application to selectively override these defaults for each role. + * + * @note The global memory pool configuration can be set with the @ref ble_conn_bw_counts_t configuration parameter, which + * is provided to @ref sd_ble_enable. + * + * @note @ref sd_ble_opt_get is not supported for this option. + * @note Please refer to SoftDevice Specification for more information on bandwidth configuration. + * + * @mscs + * @mmsc{@ref BLE_COMMON_CONF_BW} + * @endmscs + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::BLE_ERROR_INVALID_ROLE The role is invalid. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid bandwidth configuration parameters. + * @retval ::NRF_ERROR_NOT_SUPPORTED If the combination of role and bandwidth configuration is not supported. + */ +typedef struct +{ + uint8_t role; /**< BLE role of the connection, see @ref BLE_GAP_ROLES. */ + ble_conn_bw_t conn_bw; /**< Bandwidth configuration parameters. */ +} ble_common_opt_conn_bw_t; + +/** + * @brief Configuration of extended BLE connection events. + * + * When enabled the SoftDevice will dynamically extend the connection event when possible. + * + * The connection event length is controlled by the bandwidth configuration as set by @ref ble_common_opt_conn_bw_t. + * The connection event can be extended if there is time to send another packet pair before the start of the next connection interval, + * and if there are no conflicts with other BLE roles requesting radio time. + * + * @note @ref sd_ble_opt_get is not supported for this option. + */ +typedef struct +{ + uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */ +} ble_common_opt_conn_evt_ext_t; + +/**@brief Option structure for common options. */ +typedef union +{ + ble_common_opt_conn_bw_t conn_bw; /**< Parameters for the connection bandwidth option. */ + ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */ + ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */ +} ble_common_opt_t; + +/**@brief Common BLE Option type, wrapping the module specific options. */ +typedef union +{ + ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */ + ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */ +} ble_opt_t; + +/** + * @brief BLE bandwidth count parameters + * + * These parameters are used to configure the memory pools allocated within the SoftDevice for application packets + * (both transmission and reception) for all connections. + * + * @note The sum of all three counts must add up to the sum of @ref ble_gap_enable_params_t::central_conn_count and + * @ref ble_gap_enable_params_t::periph_conn_count in @ref ble_gap_enable_params_t. + */ +typedef struct { + uint8_t high_count; /**< Total number of high bandwidth TX or RX memory pools available to the application at runtime for all active connections. */ + uint8_t mid_count; /**< Total number of medium bandwidth TX or RX memory pools available to the application at runtime for all active connections. */ + uint8_t low_count; /**< Total number of low bandwidth TX or RX memory pools available to the application at runtime for all active connections. */ +} ble_conn_bw_count_t; + +/** + * @brief BLE bandwidth global memory pool configuration parameters + * + * These configuration parameters are used to set the amount of memory dedicated to application packets for + * all connections. The application should specify the most demanding configuration for the intended use. + * + * Please refer to the SoftDevice Specification for more information on bandwidth configuration. + * + * @note Each connection created at runtime requires both a TX and an RX memory pool. By the use of these configuration + * parameters, the application can decide the size and total number of the global memory pools that will be later + * available for connection creation. + * + * @mscs + * @mmsc{@ref BLE_COMMON_CONF_BW} + * @endmscs + * + */ +typedef struct { + ble_conn_bw_count_t tx_counts; /**< Global memory pool configuration for transmission.*/ + ble_conn_bw_count_t rx_counts; /**< Global memory pool configuration for reception.*/ +} ble_conn_bw_counts_t; + +/** + * @brief BLE Common Initialization parameters. + * + * @note If @ref p_conn_bw_counts is NULL the SoftDevice will assume default bandwidth configuration for all connections. + * To fit a custom bandwidth configuration requirement, the application developer may have to specify a custom memory + * pool configuration here. See @ref ble_common_opt_conn_bw_t for bandwidth configuration of individual connections. + * Please refer to the SoftDevice Specification for more information on bandwidth configuration. + */ +typedef struct +{ + uint16_t vs_uuid_count; /**< Maximum number of 128-bit, Vendor Specific UUID bases to allocate. */ + ble_conn_bw_counts_t *p_conn_bw_counts; /**< Bandwidth configuration parameters or NULL for defaults. */ +} ble_common_enable_params_t; + +/** + * @brief BLE Initialization parameters. + */ +typedef struct +{ + ble_common_enable_params_t common_enable_params; /**< Common init parameters @ref ble_common_enable_params_t. */ + ble_gap_enable_params_t gap_enable_params; /**< GAP init parameters @ref ble_gap_enable_params_t. */ + ble_gatt_enable_params_t gatt_enable_params; /**< GATT init parameters @ref ble_gatt_enable_params_t. */ + ble_gatts_enable_params_t gatts_enable_params; /**< GATTS init parameters @ref ble_gatts_enable_params_t. */ +} ble_enable_params_t; + +/** @} */ + +/** @addtogroup BLE_COMMON_FUNCTIONS Functions + * @{ */ + +/**@brief Enable the BLE stack + * + * @param[in, out] p_ble_enable_params Pointer to ble_enable_params_t + * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the application RAM region + * (APP_RAM_BASE). On return, this will contain the minimum start address of the application RAM region required by the + * SoftDevice for this configuration. Calling @ref sd_ble_enable() with *p_app_ram_base set to 0 can be used during + * development to find out how much memory a specific configuration will need. + * + * @note The memory requirement for a specific configuration will not increase between SoftDevices with the same major + * version number. + * + * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located between 0x20000000 and + * APP_RAM_BASE-1 and the application's RAM region is located between APP_RAM_BASE and the start of the call stack. + * + * @details This call initializes the BLE stack, no other BLE related function can be called before this one. + * + * @mscs + * @mmsc{@ref BLE_COMMON_ENABLE} + * @endmscs + * + * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully. + * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true: + * - The specified Attribute Table size is too small. + * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. + * - The specified Attribute Table size is not a multiple of 4. + * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN). + * - The device name length is too long for the given Attribute Table. + * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true: + * - Incorrectly configured VS UUID count. + * - Invalid connection count parameters. + * - Invalid device name location (vloc). + * - Invalid device name security mode. + * - Invalid maximum ATT_MTU size, see @ref ble_gatt_enable_params_t::att_mtu. + * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported. + * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by *p_app_ram_base is not + * large enough to fit this configuration's memory requirement. Check *p_app_ram_base + * and set the start address of the application RAM region accordingly. + * @retval ::NRF_ERROR_CONN_COUNT The requested number of connections exceeds the maximum supported by the SoftDevice. + * Please refer to the SoftDevice Specification for more information on role configuration. + */ +SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(ble_enable_params_t * p_ble_enable_params, uint32_t * p_app_ram_base)); + +/**@brief Get an event from the pending events queue. + * + * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. + * This buffer must be aligned to the extend defined by @ref BLE_EVTS_PTR_ALIGNMENT. + * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. + * + * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that + * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. + * The application is free to choose whether to call this function from thread mode (main context) or directly from the + * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher + * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) + * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so + * could potentially leave events in the internal queue without the application being aware of this fact. Sizing the + * p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to + * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event, + * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size. + * The maximum possible event length is defined by @ref BLE_EVTS_LEN_MAX. The application may also "peek" the event length + * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return: + * + * \code + * uint16_t len; + * errcode = sd_ble_evt_get(NULL, &len); + * \endcode + * + * @mscs + * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC} + * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. + * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. + * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. + */ +SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); + + +/**@brief Get the total number of available guaranteed application transmission packets for a particular connection. + * + * @details This call allows the application to obtain the total number of guaranteed application transmission packets + * available for a connection. Please note that this does not return the number of free packets, but rather the total + * amount of them for that particular connection. The application has two options to handle transmitting application packets: + * - Use a simple arithmetic calculation: after connection creation time the application should use this function to + * find out the total amount of guaranteed packets available to it and store it in a variable. + * Every time a packet is successfully queued for a transmission on this connection using any of the exposed functions in + * this BLE API, the application should decrement that variable. Conversely, whenever a @ref BLE_EVT_TX_COMPLETE event + * with the conn_handle matching the particular connection is received by the application, it should retrieve the count + * field in such event and add that number to the same variable storing the number of available guaranteed packets. This + * mechanism allows the application to be aware at any time of the number of guaranteed application packets available for + * each of the active connections, and therefore it can know with certainty whether it is possible to send more data or + * it has to wait for a @ref BLE_EVT_TX_COMPLETE event before it proceeds. + * The application can still pursue transmissions when the number of guaranteed application packets available is smaller + * than or equal to zero, but successful queuing of the tranmsission is not guaranteed. + * - Choose to simply not keep track of available packets at all, and instead handle the @ref BLE_ERROR_NO_TX_PACKETS error + * by queueing the packet to be transmitted and try again as soon as a @ref BLE_EVT_TX_COMPLETE event arrives. + * + * The API functions that may consume an application packet depending on the parameters supplied to them can be found below: + * - @ref sd_ble_gattc_write (write without response only) + * - @ref sd_ble_gatts_hvx (notifications only) + * - @ref sd_ble_l2cap_tx (all packets) + * + * @param[in] conn_handle Connection handle. + * @param[out] p_count Pointer to a uint8_t which will contain the number of application transmission packets upon + * successful return. + * @mscs + * @mmsc{@ref BLE_COMMON_APP_BUFF_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Number of application transmission packets retrieved successfully. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_TX_PACKET_COUNT_GET, uint32_t, sd_ble_tx_packet_count_get(uint16_t conn_handle, uint8_t *p_count)); + + +/**@brief Add a Vendor Specific base UUID. + * + * @details This call enables the application to add a vendor specific base UUID to the BLE stack's table, for later + * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t + * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code + * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses + * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to + * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the uuid field + * in the same structure contains the 2 bytes at indices 12 and 13. The number of possible 128-bit UUIDs available to + * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, + * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. + * + * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by + * the 16-bit uuid field in @ref ble_uuid_t. + * + * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in + * p_uuid_type along with an NRF_SUCCESS error code. + * + * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding + * bytes 12 and 13. + * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored. + * + * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID. + * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. + * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. + */ +SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); + + +/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. + * + * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared + * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add + * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index + * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. + * + * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. + * + * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). + * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. + * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. + * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. + */ +SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); + + +/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). + * + * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. + * + * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. + * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). + * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. + * + * @retval ::NRF_SUCCESS Successfully encoded into the buffer. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. + */ +SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); + + +/**@brief Get Version Information. + * + * @details This call allows the application to get the BLE stack version information. + * + * @param[out] p_version Pointer to a ble_version_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Version information stored successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure). + */ +SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); + + +/**@brief Provide a user memory block. + * + * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. + * + * @param[in] conn_handle Connection handle. + * @param[in,out] p_block Pointer to a user memory block structure. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Successfully queued a response to the peer. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no execute write request pending. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. + */ +SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); + +/**@brief Set a BLE option. + * + * @details This call allows the application to set the value of an option. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @mmsc{@ref BLE_COMMON_CONF_BW} + * @endmscs + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. + * + * @retval ::NRF_SUCCESS Option set successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + */ +SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); + + +/**@brief Get a BLE option. + * + * @details This call allows the application to retrieve the value of an option. + * + * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS. + * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. + * + * @retval ::NRF_SUCCESS Option retrieved successfully. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. + * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. + * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. + * + */ +SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); + +/** @} */ +#ifdef __cplusplus +} +#endif +#endif /* BLE_H__ */ + +/** + @} + @} +*/ diff --git a/components/softdevice/s120/headers/ble_err.h b/components/softdevice/s132/headers/ble_err.h similarity index 94% rename from components/softdevice/s120/headers/ble_err.h rename to components/softdevice/s132/headers/ble_err.h index 1184f24..2332267 100644 --- a/components/softdevice/s120/headers/ble_err.h +++ b/components/softdevice/s132/headers/ble_err.h @@ -54,12 +54,16 @@ #include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + /* @defgroup BLE_ERRORS Error Codes * @{ */ #define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ #define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ #define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ -#define BLE_ERROR_NO_TX_BUFFERS (NRF_ERROR_STK_BASE_NUM+0x004) /**< Buffer capacity exceeded. */ +#define BLE_ERROR_NO_TX_PACKETS (NRF_ERROR_STK_BASE_NUM+0x004) /**< Not enough application packets available on this connection. */ #define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */ /** @} */ @@ -74,6 +78,9 @@ #define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ /** @} */ +#ifdef __cplusplus +} +#endif #endif diff --git a/components/softdevice/s310/headers/ble_gap.h b/components/softdevice/s132/headers/ble_gap.h similarity index 55% rename from components/softdevice/s310/headers/ble_gap.h rename to components/softdevice/s132/headers/ble_gap.h index 63d9274..9c8ab2d 100644 --- a/components/softdevice/s310/headers/ble_gap.h +++ b/components/softdevice/s132/headers/ble_gap.h @@ -47,6 +47,10 @@ #include "ble_ranges.h" #include "nrf_svc.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@addtogroup BLE_GAP_ENUMERATIONS Enumerations * @{ */ @@ -54,33 +58,41 @@ */ enum BLE_GAP_SVCS { - SD_BLE_GAP_ADDRESS_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ - SD_BLE_GAP_ADDRESS_GET, /**< Get own Bluetooth Address. */ - SD_BLE_GAP_ADV_DATA_SET, /**< Set Advertising Data. */ - SD_BLE_GAP_ADV_START, /**< Start Advertising. */ - SD_BLE_GAP_ADV_STOP, /**< Stop Advertising. */ - SD_BLE_GAP_CONN_PARAM_UPDATE, /**< Connection Parameter Update. */ - SD_BLE_GAP_DISCONNECT, /**< Disconnect. */ - SD_BLE_GAP_TX_POWER_SET, /**< Set TX Power. */ - SD_BLE_GAP_APPEARANCE_SET, /**< Set Appearance. */ - SD_BLE_GAP_APPEARANCE_GET, /**< Get Appearance. */ - SD_BLE_GAP_PPCP_SET, /**< Set PPCP. */ - SD_BLE_GAP_PPCP_GET, /**< Get PPCP. */ - SD_BLE_GAP_DEVICE_NAME_SET, /**< Set Device Name. */ - SD_BLE_GAP_DEVICE_NAME_GET, /**< Get Device Name. */ - SD_BLE_GAP_AUTHENTICATE, /**< Initiate Pairing/Bonding. */ - SD_BLE_GAP_SEC_PARAMS_REPLY, /**< Reply with Security Parameters. */ - SD_BLE_GAP_AUTH_KEY_REPLY, /**< Reply with an authentication key. */ - SD_BLE_GAP_ENCRYPT, /**< Initiate encryption procedure. */ - SD_BLE_GAP_SEC_INFO_REPLY, /**< Reply with Security Information. */ - SD_BLE_GAP_CONN_SEC_GET, /**< Obtain connection security level. */ - SD_BLE_GAP_RSSI_START, /**< Start reporting of changes in RSSI. */ - SD_BLE_GAP_RSSI_STOP, /**< Stop reporting of changes in RSSI. */ - SD_BLE_GAP_SCAN_START, /**< Start Scanning. */ - SD_BLE_GAP_SCAN_STOP, /**< Stop Scanning. */ - SD_BLE_GAP_CONNECT, /**< Connect. */ - SD_BLE_GAP_CONNECT_CANCEL, /**< Cancel ongoing connection procedure. */ - SD_BLE_GAP_RSSI_GET, /**< Get the last RSSI sample. */ + SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */ + SD_BLE_GAP_ADDR_GET, /**< Get own Bluetooth Address. */ + SD_BLE_GAP_WHITELIST_SET, /**< Set active whitelist. */ + SD_BLE_GAP_DEVICE_IDENTITIES_SET, /**< Set device identity list. */ + SD_BLE_GAP_PRIVACY_SET, /**< Set Privacy settings*/ + SD_BLE_GAP_PRIVACY_GET, /**< Get Privacy settings*/ + SD_BLE_GAP_ADV_DATA_SET, /**< Set Advertising Data. */ + SD_BLE_GAP_ADV_START, /**< Start Advertising. */ + SD_BLE_GAP_ADV_STOP, /**< Stop Advertising. */ + SD_BLE_GAP_CONN_PARAM_UPDATE, /**< Connection Parameter Update. */ + SD_BLE_GAP_DISCONNECT, /**< Disconnect. */ + SD_BLE_GAP_TX_POWER_SET, /**< Set TX Power. */ + SD_BLE_GAP_APPEARANCE_SET, /**< Set Appearance. */ + SD_BLE_GAP_APPEARANCE_GET, /**< Get Appearance. */ + SD_BLE_GAP_PPCP_SET, /**< Set PPCP. */ + SD_BLE_GAP_PPCP_GET, /**< Get PPCP. */ + SD_BLE_GAP_DEVICE_NAME_SET, /**< Set Device Name. */ + SD_BLE_GAP_DEVICE_NAME_GET, /**< Get Device Name. */ + SD_BLE_GAP_AUTHENTICATE, /**< Initiate Pairing/Bonding. */ + SD_BLE_GAP_SEC_PARAMS_REPLY, /**< Reply with Security Parameters. */ + SD_BLE_GAP_AUTH_KEY_REPLY, /**< Reply with an authentication key. */ + SD_BLE_GAP_LESC_DHKEY_REPLY, /**< Reply with an LE Secure Connections DHKey. */ + SD_BLE_GAP_KEYPRESS_NOTIFY, /**< Notify of a keypress during an authentication procedure. */ + SD_BLE_GAP_LESC_OOB_DATA_GET, /**< Get the local LE Secure Connections OOB data. */ + SD_BLE_GAP_LESC_OOB_DATA_SET, /**< Set the remote LE Secure Connections OOB data. */ + SD_BLE_GAP_ENCRYPT, /**< Initiate encryption procedure. */ + SD_BLE_GAP_SEC_INFO_REPLY, /**< Reply with Security Information. */ + SD_BLE_GAP_CONN_SEC_GET, /**< Obtain connection security level. */ + SD_BLE_GAP_RSSI_START, /**< Start reporting of changes in RSSI. */ + SD_BLE_GAP_RSSI_STOP, /**< Stop reporting of changes in RSSI. */ + SD_BLE_GAP_SCAN_START, /**< Start Scanning. */ + SD_BLE_GAP_SCAN_STOP, /**< Stop Scanning. */ + SD_BLE_GAP_CONNECT, /**< Connect. */ + SD_BLE_GAP_CONNECT_CANCEL, /**< Cancel ongoing connection procedure. */ + SD_BLE_GAP_RSSI_GET, /**< Get the last RSSI sample. */ }; /**@brief GAP Event IDs. @@ -88,21 +100,23 @@ enum BLE_GAP_SVCS */ enum BLE_GAP_EVTS { - BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connection established. @ref ble_gap_evt_connected_t */ - BLE_GAP_EVT_DISCONNECTED, /**< Disconnected from peer. @ref ble_gap_evt_disconnected_t */ - BLE_GAP_EVT_CONN_PARAM_UPDATE, /**< Connection Parameters updated. ble_gap_evt_conn_param_update_t */ - BLE_GAP_EVT_SEC_PARAMS_REQUEST, /**< Request to provide security parameters. @ref ble_gap_evt_sec_params_request_t */ - BLE_GAP_EVT_SEC_INFO_REQUEST, /**< Request to provide security information. @ref ble_gap_evt_sec_info_request_t */ - BLE_GAP_EVT_PASSKEY_DISPLAY, /**< Request to display a passkey to the user. @ref ble_gap_evt_passkey_display_t */ - BLE_GAP_EVT_AUTH_KEY_REQUEST, /**< Request to provide an authentication key. @ref ble_gap_evt_auth_key_request_t */ - BLE_GAP_EVT_AUTH_STATUS, /**< Authentication procedure completed with status. @ref ble_gap_evt_auth_status_t */ - BLE_GAP_EVT_CONN_SEC_UPDATE, /**< Connection security updated. @ref ble_gap_evt_conn_sec_update_t */ - BLE_GAP_EVT_TIMEOUT, /**< Timeout expired. @ref ble_gap_evt_timeout_t */ - BLE_GAP_EVT_RSSI_CHANGED, /**< RSSI report. @ref ble_gap_evt_rssi_changed_t */ - BLE_GAP_EVT_ADV_REPORT, /**< Advertising report. @ref ble_gap_evt_adv_report_t */ - BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. @ref ble_gap_evt_sec_request_t */ - BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. @ref ble_gap_evt_conn_param_update_request_t */ - BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_evt_scan_req_report_t */ + BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE, /**< Connection established. \n See @ref ble_gap_evt_connected_t. */ + BLE_GAP_EVT_DISCONNECTED, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */ + BLE_GAP_EVT_SEC_PARAMS_REQUEST, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */ + BLE_GAP_EVT_SEC_INFO_REQUEST, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */ + BLE_GAP_EVT_PASSKEY_DISPLAY, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */ + BLE_GAP_EVT_KEY_PRESSED, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */ + BLE_GAP_EVT_AUTH_KEY_REQUEST, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */ + BLE_GAP_EVT_LESC_DHKEY_REQUEST, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */ + BLE_GAP_EVT_AUTH_STATUS, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */ + BLE_GAP_EVT_CONN_SEC_UPDATE, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */ + BLE_GAP_EVT_TIMEOUT, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */ + BLE_GAP_EVT_RSSI_CHANGED, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */ + BLE_GAP_EVT_ADV_REPORT, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */ + BLE_GAP_EVT_SEC_REQUEST, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */ + BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */ + BLE_GAP_EVT_SCAN_REQ_REPORT, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */ }; /**@brief GAP Option IDs. @@ -113,10 +127,12 @@ enum BLE_GAP_OPTS BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */ BLE_GAP_OPT_LOCAL_CONN_LATENCY, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */ BLE_GAP_OPT_PASSKEY, /**< Set passkey. @ref ble_gap_opt_passkey_t */ - BLE_GAP_OPT_PRIVACY, /**< Custom privacy. @ref ble_gap_opt_privacy_t */ BLE_GAP_OPT_SCAN_REQ_REPORT, /**< Scan request report. @ref ble_gap_opt_scan_req_report_t */ - BLE_GAP_OPT_COMPAT_MODE /**< Compatibility mode. @ref ble_gap_opt_compat_mode_t */ + BLE_GAP_OPT_COMPAT_MODE, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_t */ + BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */ + BLE_GAP_OPT_EXT_LEN, /**< Extended length packets. @ref ble_gap_opt_ext_len_t */ }; + /** @} */ /**@addtogroup BLE_GAP_DEFINES Defines @@ -127,6 +143,9 @@ enum BLE_GAP_OPTS #define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */ #define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */ #define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */ +#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */ +#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */ /**@} */ @@ -145,28 +164,34 @@ enum BLE_GAP_OPTS #define BLE_GAP_TIMEOUT_SRC_SECURITY_REQUEST 0x01 /**< Security request timeout. */ #define BLE_GAP_TIMEOUT_SRC_SCAN 0x02 /**< Scanning timeout. */ #define BLE_GAP_TIMEOUT_SRC_CONN 0x03 /**< Connection timeout. */ +#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x04 /**< Authenticated payload timeout. */ /**@} */ /**@defgroup BLE_GAP_ADDR_TYPES GAP Address types * @{ */ #define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random Static address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Private Resolvable address. */ -#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Private Non-Resolvable address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */ +#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */ /**@} */ -/**@defgroup BLE_GAP_ADDR_CYCLE_MODES GAP Address cycle modes - * @{ */ -#define BLE_GAP_ADDR_CYCLE_MODE_NONE 0x00 /**< Set addresses directly, no automatic address cycling. */ -#define BLE_GAP_ADDR_CYCLE_MODE_AUTO 0x01 /**< Automatically generate and update private addresses. */ -/** @} */ -/**@brief The default interval in seconds at which a private address is refreshed when address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO. */ -#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (60 * 15) +/**@brief The default interval in seconds at which a private address is refreshed. */ +#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */ +/**@brief The maximum interval in seconds at which a private address can be refreshed. */ +#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */ + /** @brief BLE address length. */ -#define BLE_GAP_ADDR_LEN 6 +#define BLE_GAP_ADDR_LEN (6) + + +/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes + * @{ */ +#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */ +#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */ +/**@} */ /**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format @@ -201,6 +226,7 @@ enum BLE_GAP_OPTS #define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */ #define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */ #define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */ +#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */ #define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */ #define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */ /**@} */ @@ -248,7 +274,7 @@ enum BLE_GAP_OPTS /**@brief Maximum size of advertising data in octets. */ -#define BLE_GAP_ADV_MAX_SIZE 31 +#define BLE_GAP_ADV_MAX_SIZE (31) /**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types @@ -271,8 +297,8 @@ enum BLE_GAP_OPTS /**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values * @{ */ -#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX 180 /**< Maximum advertising time in limited discoverable mode (TGAP(lim_adv_timeout) = 180s). */ -#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED 0 /**< Unlimited advertising in general discoverable mode. */ +#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (180) /**< Maximum advertising time in limited discoverable mode (TGAP(lim_adv_timeout) = 180s). */ +#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode. */ /**@} */ @@ -283,6 +309,7 @@ enum BLE_GAP_OPTS #define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */ /**@} */ + /**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities * @{ */ #define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */ @@ -300,11 +327,24 @@ enum BLE_GAP_OPTS #define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */ /**@} */ + +/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types + * @{ */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */ +#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */ +/**@} */ + + /**@defgroup BLE_GAP_SEC_STATUS GAP Security status * @{ */ #define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */ #define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */ #define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */ #define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user cancelled or other). */ #define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */ #define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */ @@ -315,20 +355,28 @@ enum BLE_GAP_OPTS #define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */ #define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */ #define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */ +#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */ +#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */ +#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */ +#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */ +#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */ /**@} */ + /**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources * @{ */ #define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */ #define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */ /**@} */ + /**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits * @{ */ -#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connction interval specified in connect parameters. */ -#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest mimimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */ +#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ #define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ -#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connction interval specified in connect parameters. */ +#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */ #define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */ #define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */ #define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */ @@ -338,54 +386,71 @@ enum BLE_GAP_OPTS /**@} */ -/**@brief GAP device name maximum length. */ -#define BLE_GAP_DEVNAME_MAX_LEN 31 +/**@brief GAP device name defines. */ +#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */ +#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */ +#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */ + /**@brief Disable RSSI events for connections */ -#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF +#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF + /**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters * * See @ref ble_gap_conn_sec_mode_t. * @{ */ /**@brief Set sec_mode pointed to by ptr to have no access rights.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0) /**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0) /**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0) /**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0) +/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/ +#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0) /**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0) /**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/ -#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) +#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0) /**@} */ /**@brief GAP Security Random Number Length. */ #define BLE_GAP_SEC_RAND_LEN 8 + /**@brief GAP Security Key Length. */ #define BLE_GAP_SEC_KEY_LEN 16 + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */ +#define BLE_GAP_LESC_P256_PK_LEN 64 + + +/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */ +#define BLE_GAP_LESC_DHKEY_LEN 32 + + /**@brief GAP Passkey Length. */ #define BLE_GAP_PASSKEY_LEN 6 -/**@brief Maximum amount of addresses in a whitelist. */ + +/**@brief Maximum amount of addresses in the whitelist. */ #define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8) -/**@brief Maximum amount of IRKs in a whitelist. - * @note The number of IRKs is limited to 8, even if the hardware supports more. - */ -#define BLE_GAP_WHITELIST_IRK_MAX_COUNT (8) + +/**@brief Maximum amount of identities in the device identities list. */ +#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8) + /**@defgroup GAP_SEC_MODES GAP Security Modes * @{ */ #define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */ /**@} */ +/** @} */ -/**@} */ /**@addtogroup BLE_GAP_STRUCTURES Structures * @{ */ @@ -393,8 +458,10 @@ enum BLE_GAP_OPTS /**@brief Bluetooth Low Energy address. */ typedef struct { - uint8_t addr_type; /**< See @ref BLE_GAP_ADDR_TYPES. */ - uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */ + uint8_t addr_id_peer : 1; /**< Only valid for peer addresses. + Reference to peer in device identities list (as set with @ref sd_ble_gap_device_identities_set) when peer is using privacy. */ + uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */ + uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */ } ble_gap_addr_t; @@ -424,13 +491,14 @@ typedef struct * Security Mode 1 Level 1: No security is needed (aka open link).\n * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n * Security Mode 1 Level 3: MITM protected encrypted link required.\n + * Security Mode 1 Level 4: LESC MITM protected encrypted link required.\n * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n */ typedef struct { uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */ - uint8_t lv : 4; /**< Level (1, 2 or 3), 0 for no permissions at all. */ + uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */ } ble_gap_conn_sec_mode_t; @@ -443,23 +511,40 @@ typedef struct } ble_gap_conn_sec_t; -/**@brief Identity Resolving Key. */ +/** + * @brief Device name and its properties + * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK, the attribute table size must be increased to have room for the longer device name (see @ref ble_gatts_enable_params_t). + */ typedef struct { - uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ -} ble_gap_irk_t; + ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */ + uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/ + uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored.*/ + uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/ + uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/ +} ble_gap_device_name_t; + + +/** + * @brief BLE GAP initialization parameters. + */ +typedef struct +{ + uint8_t periph_conn_count; /**< Number of connections acting as a peripheral */ + uint8_t central_conn_count; /**< Number of connections acting as a central */ + uint8_t central_sec_count; /**< Number of SMP instances for all connections acting as a central. */ + ble_gap_device_name_t const *p_device_name; /**< Pointer to device name instance. If NULL, @ref sd_ble_enable() will set the device name to @ref BLE_GAP_DEVNAME_DEFAULT. */ +} ble_gap_enable_params_t; -/**@brief Whitelist structure. */ +/**@brief Identity Resolving Key. */ typedef struct { - ble_gap_addr_t **pp_addrs; /**< Pointer to an array of device address pointers, pointing to addresses to be used in whitelist. NULL if none are given. */ - uint8_t addr_count; /**< Count of device addresses in array, up to @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. */ - ble_gap_irk_t **pp_irks; /**< Pointer to an array of Identity Resolving Key (IRK) pointers, each pointing to an IRK in the whitelist. NULL if none are given. */ - uint8_t irk_count; /**< Count of IRKs in array, up to @ref BLE_GAP_WHITELIST_IRK_MAX_COUNT. */ -} ble_gap_whitelist_t; + uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */ +} ble_gap_irk_t; + -/**@brief Channel mask for RF channels used in advertising and scanning. */ +/**@brief Channel mask for RF channels used in advertising. */ typedef struct { uint8_t ch_37_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 37 */ @@ -467,53 +552,87 @@ typedef struct uint8_t ch_39_off : 1; /**< Setting this bit to 1 will turn off advertising on channel 39 */ } ble_gap_adv_ch_mask_t; -/**@brief GAP advertising parameters.*/ + +/**@brief GAP advertising parameters. */ typedef struct { uint8_t type; /**< See @ref BLE_GAP_ADV_TYPES. */ - ble_gap_addr_t *p_peer_addr; /**< For @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND mode only, known peer address. */ + ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer. + - When privacy is enabled and the local device use @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses, the device identity list is searched for a matching + entry. If the local IRK for that device identity is set, the local IRK for that device will be used to generate the advertiser address field in the advertise packet. + - If type is @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this must be set to the targeted initiator. If the initiator is in the device identity list, + the peer IRK for that device will be used to generate the initiator address field in the ADV_DIRECT_IND packet. */ uint8_t fp; /**< Filter Policy, see @ref BLE_GAP_ADV_FILTER_POLICIES. */ - ble_gap_whitelist_t *p_whitelist; /**< Pointer to whitelist, NULL if none is given. */ uint16_t interval; /**< Advertising interval between 0x0020 and 0x4000 in 0.625 ms units (20ms to 10.24s), see @ref BLE_GAP_ADV_INTERVALS. - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for high duty cycle directed advertising. - If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, set @ref BLE_GAP_ADV_INTERVAL_MIN <= interval <= @ref BLE_GAP_ADV_INTERVAL_MAX for low duty cycle advertising.*/ uint16_t timeout; /**< Advertising timeout between 0x0001 and 0x3FFF in seconds, 0x0000 disables timeout. See also @ref BLE_GAP_ADV_TIMEOUT_VALUES. If type equals @ref BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, this parameter must be set to 0 for High duty cycle directed advertising. */ - ble_gap_adv_ch_mask_t channel_mask; /**< Advertising channel mask. @see ble_gap_channel_mask_t for documentation. */ + ble_gap_adv_ch_mask_t channel_mask; /**< Advertising channel mask. See @ref ble_gap_adv_ch_mask_t. */ } ble_gap_adv_params_t; /**@brief GAP scanning parameters. */ typedef struct { - uint8_t active : 1; /**< If 1, perform active scanning (scan requests). */ - uint8_t selective : 1; /**< If 1, ignore unknown devices (non whitelisted). */ - ble_gap_whitelist_t * p_whitelist; /**< Pointer to whitelist, NULL if none is given. */ - uint16_t interval; /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ - uint16_t window; /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ - uint16_t timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ + uint8_t active : 1; /**< If 1, perform active scanning (scan requests). */ + uint8_t use_whitelist : 1; /**< If 1, filter advertisers using current active whitelist. */ + uint8_t adv_dir_report : 1; /**< If 1, also report directed advertisements where the initiator field is set to a private resolvable address, + even if the address did not resolve to an entry in the device identity list. A report will be generated + even if the peer is not in the whitelist. */ + uint16_t interval; /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ + uint16_t window; /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */ + uint16_t timeout; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */ } ble_gap_scan_params_t; +/**@brief Device Privacy. + * + * The privacy feature provides a way for the device to avoid being tracked over a period of time. + * The privacy feature, when enabled, hides the local device identity and replaces it with a private address + * that is automatically refreshed at a specified interval. + * + * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK). + * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key, + * and devices can establish connections without revealing their real identities. + * + * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all + * bonding procedures performed after @ref sd_ble_gap_privacy_set returns. + * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called. + */ +typedef struct +{ + uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */ + uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */ + uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */ + ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used. + When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored. + By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */ +} ble_gap_privacy_params_t; + + /** @brief Keys that can be exchanged during a bonding procedure. */ typedef struct { uint8_t enc : 1; /**< Long Term Key and Master Identification. */ uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */ uint8_t sign : 1; /**< Connection Signature Resolving Key. */ + uint8_t link : 1; /**< Derive the Link Key from the LTK. */ } ble_gap_sec_kdist_t; /**@brief GAP security parameters. */ typedef struct { - uint8_t bond : 1; /**< Perform bonding. */ - uint8_t mitm : 1; /**< Man In The Middle protection required. */ - uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ - uint8_t oob : 1; /**< Out Of Band data available. */ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Enable Man In The Middle protection. */ + uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */ + uint8_t keypress : 1; /**< Enable generation of keypress notifications. */ + uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */ + uint8_t oob : 1; /**< Out Of Band data available. */ uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */ uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */ - ble_gap_sec_kdist_t kdist_periph; /**< Key distribution bitmap: keys that the peripheral device will distribute. */ - ble_gap_sec_kdist_t kdist_central; /**< Key distribution bitmap: keys that the central device will distribute. */ + ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */ + ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */ } ble_gap_sec_params_t; @@ -521,8 +640,9 @@ typedef struct typedef struct { uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */ + uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */ uint8_t auth : 1; /**< Authenticated Key. */ - uint8_t ltk_len : 7; /**< LTK length in octets. */ + uint8_t ltk_len : 6; /**< LTK length in octets. */ } ble_gap_enc_info_t; @@ -541,13 +661,35 @@ typedef struct } ble_gap_sign_info_t; +/**@brief GAP LE Secure Connections P-256 Public Key. */ +typedef struct +{ + uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */ +} ble_gap_lesc_p256_pk_t; + + +/**@brief GAP LE Secure Connections DHKey. */ +typedef struct +{ + uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */ +} ble_gap_lesc_dhkey_t; + + +/**@brief GAP LE Secure Connections OOB data. */ +typedef struct +{ + ble_gap_addr_t addr; /**< Bluetooth address of the device. */ + uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */ + uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */ +} ble_gap_lesc_oob_data_t; + + /**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */ typedef struct { - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ - ble_gap_addr_t own_addr; /**< Bluetooth address of the local device used during connection setup. */ - uint8_t irk_match :1; /**< If 1, peer device's address resolved using an IRK. */ - uint8_t irk_match_idx :7; /**< Index in IRK list where the address was matched. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ + uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */ } ble_gap_evt_connected_t; @@ -588,8 +730,17 @@ typedef struct typedef struct { uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */ + uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply + with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or + @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */ } ble_gap_evt_passkey_display_t; +/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */ +typedef struct +{ + uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */ +} ble_gap_evt_key_pressed_t; + /**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */ typedef struct @@ -597,15 +748,24 @@ typedef struct uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */ } ble_gap_evt_auth_key_request_t; +/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */ +typedef struct +{ + ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory + inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */ + uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */ +} ble_gap_evt_lesc_dhkey_request_t; + /**@brief Security levels supported. - * @note See Bluetooth Specification Version 4.1 Volume 3, Part C, Chapter 10. + * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1. */ typedef struct { uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */ uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */ uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */ + uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */ } ble_gap_sec_levels_t; @@ -620,27 +780,27 @@ typedef struct /**@brief Identity Key. */ typedef struct { - ble_gap_irk_t id_info; /**< Identity Information. */ - ble_gap_addr_t id_addr_info; /**< Identity Address Information. */ + ble_gap_irk_t id_info; /**< Identity Resolving Key. */ + ble_gap_addr_t id_addr_info; /**< Identity Address. */ } ble_gap_id_key_t; /**@brief Security Keys. */ typedef struct { - ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ - ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ - ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ + ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */ + ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */ + ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */ + ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined + in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */ } ble_gap_sec_keys_t; -/**@brief Security key set (both Peripheral and Central keys). - * Note that when distributing Bluetooth addresses pertaining to the local device those - * will have to be filled in by the user. */ +/**@brief Security key set for both local and peer keys. */ typedef struct { - ble_gap_sec_keys_t keys_periph; /**< Keys distributed by the device in the Peripheral role. */ - ble_gap_sec_keys_t keys_central; /**< Keys distributed by the device in the Central role. */ + ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */ + ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */ } ble_gap_sec_keyset_t; @@ -652,8 +812,8 @@ typedef struct uint8_t bonded : 1; /**< Procedure resulted in a bond. */ ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */ ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */ - ble_gap_sec_kdist_t kdist_periph; /**< Bitmap stating which keys were exchanged (distributed) by the peripheral. */ - ble_gap_sec_kdist_t kdist_central; /**< Bitmap stating which keys were exchanged (distributed) by the central. */ + ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */ + ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */ } ble_gap_evt_auth_status_t; @@ -681,7 +841,10 @@ typedef struct /**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT. */ typedef struct { - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ + ble_gap_addr_t direct_addr; /**< Set when the scanner is unable to resolve the private resolvable address of the initiator + field of a directed advertisement packet and the scanner has been enabled to report this in @ref ble_gap_scan_params_t::adv_dir_report. */ int8_t rssi; /**< Received Signal Strength Indication in dBm. */ uint8_t scan_rsp : 1; /**< If 1, the report corresponds to a scan response and the type field may be ignored. */ uint8_t type : 2; /**< See @ref BLE_GAP_ADV_TYPES. Only valid if the scan_rsp field is 0. */ @@ -693,8 +856,10 @@ typedef struct /**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */ typedef struct { - uint8_t bond : 1; /**< Perform bonding. */ - uint8_t mitm : 1; /**< Man In The Middle protection required. */ + uint8_t bond : 1; /**< Perform bonding. */ + uint8_t mitm : 1; /**< Man In The Middle protection requested. */ + uint8_t lesc : 1; /**< LE Secure Connections requested. */ + uint8_t keypress : 1; /**< Generation of keypress notifications requested. */ } ble_gap_evt_sec_request_t; @@ -709,15 +874,15 @@ typedef struct typedef struct { int8_t rssi; /**< Received Signal Strength Indication in dBm. */ - ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */ + ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1 + and the address is the device's identity address. */ } ble_gap_evt_scan_req_report_t; - /**@brief GAP event structure. */ typedef struct { - uint16_t conn_handle; /**< Connection Handle on which event occured. */ + uint16_t conn_handle; /**< Connection Handle on which event occurred. */ union /**< union alternative identified by evt_id in enclosing struct. */ { ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */ @@ -726,7 +891,9 @@ typedef struct ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */ ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */ ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */ + ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */ ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */ + ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */ ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */ ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */ ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */ @@ -736,7 +903,6 @@ typedef struct ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */ ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report parameters. */ } params; /**< Event Parameters. */ - } ble_gap_evt_t; @@ -804,6 +970,8 @@ typedef struct * sd_ble_opt_set to make the SoftDevice use a pre-programmed passkey for authentication * instead of generating a random one. * + * @note Repeated pairing attempts using the same pre-programmed passkey makes pairing vulnerable to MITM attacks. + * * @note @ref sd_ble_opt_get is not supported for this option. * */ @@ -813,36 +981,6 @@ typedef struct } ble_gap_opt_passkey_t; -/**@brief Custom Privacy Option. - * - * This structure is used with both @ref sd_ble_opt_set (as input) and with - * @ref sd_ble_opt_get (as output). - * - * Structure containing: - * - A pointer to an IRK to set (if input), or a place to store a read IRK (if output). - * - A private address refresh cycle. - * - * @note The specified address cycle interval is used when the address cycle mode is - * @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO. If 0 is given, the address will not be automatically - * refreshed at all. The default interval is @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. - * - * @note If the current address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO, the address will immediately be - * refreshed when a custom privacy option is set. A new address can be generated manually by calling - * @ref sd_ble_gap_address_set with the same type again. - * - * @note If the IRK is updated, the new IRK becomes the one to be distributed in all - * bonding procedures performed after @ref sd_ble_opt_set returns. - * - * @retval ::NRF_SUCCESS Set or read successfully. - * @retval ::NRF_ERROR_INVALID_ADDR The pointer to IRK storage is invalid. - */ -typedef struct -{ - ble_gap_irk_t * p_irk; /**< When input: Pointer to custom IRK, or NULL to use/reset to the device's default IRK. When output: Pointer to where the current IRK is to be stored, or NULL to not read out the IRK. */ - uint16_t interval_s; /**< When input: Custom private address cycle interval in seconds. When output: The current private address cycle interval. */ -} ble_gap_opt_privacy_t; - - /**@brief Scan request report option. * * This can be used with @ref sd_ble_opt_set to make the SoftDevice send @@ -861,6 +999,7 @@ typedef struct uint8_t enable : 1; /**< Enable scan request reports. */ } ble_gap_opt_scan_req_report_t; + /**@brief Compatibility mode option. * * This can be used with @ref sd_ble_opt_set to enable and disable @@ -877,6 +1016,51 @@ typedef struct uint8_t mode_1_enable : 1; /**< Enable compatibility mode 1.*/ } ble_gap_opt_compat_mode_t; +/**@brief Data length extension option. + * + * This can be used with @ref sd_ble_opt_set to enable longer data packets. + * + * @note An rxtx_max_pdu_payload_size of 0 will result in the default minimum payload size of 27. + * @note Not supported by SoftDevices for nRF51 Series devices. + * @note The parameters for a connection are applied when a connection complete + * event is generated for the host. + * + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM If the payload size is not 0 or a valid link layer PDU payload size. + * @retval ::NRF_ERROR_NOT_SUPPORTED If called on a SoftDevice designed for nRF51 (e.g. s130). + */ +typedef struct +{ + uint8_t rxtx_max_pdu_payload_size; /**< Max PDU payload size (in octets). */ +} ble_gap_opt_ext_len_t; + + + +/**@brief Authenticated payload timeout option. + * + * This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other than the default of 8 minutes. + * + * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated + * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted + * link. + * + * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance + * to reset the timer. In addition the stack will try to prioritize running of LE ping over other + * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects + * on other activities, it is recommended to use high timeout values. + * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)). + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter. + */ +typedef struct +{ + uint16_t conn_handle; /**< Connection Handle */ + uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit. Maximum is 48 000 (=480 000 ms =8 min). Minimum is 1 (=10ms). */ +} ble_gap_opt_auth_payload_timeout_t; + /**@brief Option structure for GAP options. */ typedef union @@ -884,9 +1068,10 @@ typedef union ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */ ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */ ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/ - ble_gap_opt_privacy_t privacy; /**< Parameters for the Custom privacy option. */ ble_gap_opt_scan_req_report_t scan_req_report; /**< Parameters for the scan request report option.*/ ble_gap_opt_compat_mode_t compat_mode; /**< Parameters for the compatibility mode option.*/ + ble_gap_opt_ext_len_t ext_len; /**< Parameters for the extended length option. */ + ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/ } ble_gap_opt_t; /**@} */ @@ -894,55 +1079,139 @@ typedef union /**@addtogroup BLE_GAP_FUNCTIONS Functions * @{ */ -/**@brief Set local Bluetooth address. - * - * @note If the address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_AUTO, the address type is required to - * be @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or - * @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. The given address is ignored and the - * SoftDevice will generate a new private address automatically every - * @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S seconds. If this API - * call is used again with the same parameters, the SoftDevice will immediately - * generate a new private address to replace the current address. - * - * @note If the application wishes to use a @ref BLE_GAP_ADDR_TYPE_PUBLIC or - * @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC address, the cycle mode must be - * @ref BLE_GAP_ADDR_CYCLE_MODE_NONE. - * - * @note If this API function is called while advertising or scanning, the softdevice will immediately update the - * advertising or scanning address without the need to stop the procedure in the following cases: - * - If the previously set address is of type @ref BLE_GAP_ADDR_TYPE_PUBLIC and the new address - * is also of type @ref BLE_GAP_ADDR_TYPE_PUBLIC - * - If the previously set address is not @ref BLE_GAP_ADDR_TYPE_PUBLIC and the new address is - * also not @ref BLE_GAP_ADDR_TYPE_PUBLIC. - * If the address is changed from a @ref BLE_GAP_ADDR_TYPE_PUBLIC address to another type or from - * another type to a @ref BLE_GAP_ADDR_TYPE_PUBLIC address, the change will take effect the next - * time an advertising or scanning procedure is started. - * - * @note If the address cycle mode is @ref BLE_GAP_ADDR_CYCLE_MODE_NONE and the application is - * using privacy, the application must take care to generate and set new private addresses - * periodically to comply with the Privacy specification in Bluetooth Core Spec. - * - * @param[in] addr_cycle_mode Address cycle mode, see @ref BLE_GAP_ADDR_CYCLE_MODES. - * @param[in] p_addr Pointer to address structure. +/**@brief Set the local Bluetooth identity address. + * + * The local Bluetooth identity address is the address that identifies this device to other peers. + * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. + * The identity address cannot be changed while roles are running. + * + * @note This address will be distributed to the peer during bonding. + * If the address changes, the address stored in the peer device will not be valid and the ability to + * reconnect using the old address will be lost. + * + * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being + * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged + * for the lifetime of each IC. + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @endmscs + * + * @param[in] p_addr Pointer to address structure. * * @retval ::NRF_SUCCESS Address successfully set. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while the roles are running. */ -SVCALL(SD_BLE_GAP_ADDRESS_SET, uint32_t, sd_ble_gap_address_set(uint8_t addr_cycle_mode, const ble_gap_addr_t *p_addr)); +SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr)); -/**@brief Get local Bluetooth address. +/**@brief Get local Bluetooth identity address. + * + * @note This will always return the identity address irrespective of the privacy settings, + * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC. * * @param[out] p_addr Pointer to address structure to be filled in. * * @retval ::NRF_SUCCESS Address successfully retrieved. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied. + */ +SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr)); + + +/**@brief Set the active whitelist in the SoftDevice. + * + * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles. + * The whitelist cannot be set if a BLE role is using the whitelist. + * + * @note If an address is resolved using the information in the device identity list, then the whitelist + * filter policy applies to the peer identity address and not the resolvable address sent on air. + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @endmscs + * + * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared. + * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. + * + * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid. + * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when + * pp_wl_addrs is not NULL. */ -SVCALL(SD_BLE_GAP_ADDRESS_GET, uint32_t, sd_ble_gap_address_get(ble_gap_addr_t *p_addr)); +SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len)); + + +/**@brief Set device identity list. + * + * @note Only one device identity list can be used at a time and the list is shared between the BLE roles. + * The device identity list cannot be set if a BLE role is using the list. + * + * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared. + * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index. + * To fill in the list with the currently set device IRK for all peers, set to NULL. + * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS The device identity list successfully set/cleared. + * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid. + This code may be returned if the local IRK list also has an invalid entry. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared. + * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can + * only return when pp_id_keys is not NULL. + */ +SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len)); + + +/**@brief Set privacy settings. + * + * @note Privacy settings cannot be set while BLE roles are running. + * + * @param[in] p_privacy_params Privacy settings. + * + * @mscs + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @endmscs + * + * @retval ::NRF_SUCCESS Set successfully. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid. + Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided. + * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while BLE roles using privacy are enabled. + */ +SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params)); + + +/**@brief Get privacy settings. + * + * @note The privacy settings returned include the current device irk as well. + * + * @param[in] p_privacy_params Privacy settings. + * + * @retval ::NRF_SUCCESS Privacy settings read. + * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid. + Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer. + */ +SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params)); /**@brief Set, clear or update advertising and scan response data. @@ -956,12 +1225,18 @@ SVCALL(SD_BLE_GAP_ADDRESS_GET, uint32_t, sd_ble_gap_address_get(ble_gap_addr_t * * * @note The call will fail if p_data and p_sr_data are both NULL since this would have no effect. * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * * @param[in] p_data Raw data to be placed in advertising packet. If NULL, no changes are made to the current advertising packet data. * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_data is NULL, can be 0 if p_data is not NULL. * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL, no changes are made to the current scan response packet data. * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_MAX_SIZE octets. Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL. * * @retval ::NRF_SUCCESS Advertising data successfully updated or cleared. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, both p_data and p_sr_data cannot be NULL. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied. * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied, check the advertising data format specification. @@ -980,20 +1255,42 @@ SVCALL(SD_BLE_GAP_ADV_DATA_SET, uint32_t, sd_ble_gap_adv_data_set(uint8_t const * cannot however be connectable (it must be of type @ref BLE_GAP_ADV_TYPE_ADV_SCAN_IND or * @ref BLE_GAP_ADV_TYPE_ADV_NONCONN_IND). @note Only one advertiser may be active at any time. * + * @events + * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Advertisement has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs + * * @param[in] p_adv_params Pointer to advertising parameters structure. * * @retval ::NRF_SUCCESS The BLE stack has started advertising. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started. + * @retval ::NRF_ERROR_NO_MEM The configured memory pools (see @ref ble_conn_bw_counts_t) are not large enough for the + * bandwidth selected for this connection. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check the accepted ranges and limits. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Bluetooth address supplied. * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Observer) and try again */ SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(ble_gap_adv_params_t const *p_adv_params)); /**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_ADV_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs * * @retval ::NRF_SUCCESS The BLE stack has stopped advertising. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in advertising state). @@ -1010,6 +1307,18 @@ SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(void)); * * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested. * + * @events + * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CPU_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role, * the parameters in the PPCP characteristic of the GAP service will be used instead. @@ -1031,6 +1340,14 @@ SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint * @details This call initiates the disconnection procedure, and its completion will be communicated to the application * with a @ref BLE_GAP_EVT_DISCONNECTED event. * + * @events + * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CONN_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE). * @@ -1044,9 +1361,11 @@ SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_hand /**@brief Set the radio's transmit power. * - * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm). + * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, 3, and 4 dBm). * - * @note -40 dBm will not actually give -40 dBm, but will instead be remapped to -30 dBm. + * @note The +3dBm setting is only available on nRF52 series ICs. + * @note The -30dBm setting is only available on nRF51 series ICs. + * @note The -40dBm setting is only available on nRF52 series ICs. * * @retval ::NRF_SUCCESS Successfully changed the transmit power. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. @@ -1101,24 +1420,27 @@ SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t * @param[in] p_dev_name Pointer to a UTF-8 encoded, non NULL-terminated string. * @param[in] len Length of the UTF-8, non NULL-terminated string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN). * + * @note If the device name is located in application flash memory (see @ref ble_gap_device_name_t), it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned. + * * @retval ::NRF_SUCCESS GAP device name and permissions set successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. + * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable. */ SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len)); /**@brief Get GAP device name. - * - * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. - * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. * * @note If the device name is longer than the size of the supplied buffer, * p_len will return the complete device name length, * and not the number of bytes actually returned in p_dev_name. * The application may use this information to allocate a suitable buffer size. * + * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 non NULL-terminated string will be placed. Set to NULL to obtain the complete device name length. + * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output. + * * @retval ::NRF_SUCCESS GAP device name retrieved successfully. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. @@ -1127,66 +1449,138 @@ SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t /**@brief Initiate the GAP Authentication procedure. - * - * @param[in] conn_handle Connection handle. - * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. - * In the peripheral role, only the timeout, bond and mitm fields of this structure are used. - * In the central role, this pointer may be NULL to reject a Security Request. * * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected), * otherwise in the peripheral role, an SMP Security Request will be sent. * - * @note Calling this function may result in the following events depending on the outcome and parameters: @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, - * @ref BLE_GAP_EVT_SEC_INFO_REQUEST, @ref BLE_GAP_EVT_AUTH_KEY_REQUEST, @ref BLE_GAP_EVT_CONN_SEC_UPDATE, @ref BLE_GAP_EVT_AUTH_STATUS. + * @events + * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:} + * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST} + * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST} + * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY} + * @event{@ref BLE_GAP_EVT_KEY_PRESSED} + * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST} + * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST} + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE} + * @event{@ref BLE_GAP_EVT_AUTH_STATUS} + * @event{@ref BLE_GAP_EVT_TIMEOUT} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs * + * @param[in] conn_handle Connection handle. + * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure. + * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used. + * In the central role, this pointer may be NULL to reject a Security Request. * * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. + * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. - * @retval ::NRF_ERROR_TIMEOUT A SMP timout has occured, and further SMP operations on this link is prohibited. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. + * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited. */ SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params)); /**@brief Reply with GAP security parameters. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS. * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have * already been provided during a previous call to @ref sd_ble_gap_authenticate. - * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys distributed as a result of the ongoing security procedure + * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event. - * The pointer to the ID key data distributed by the local device constitutes however an exception. It can either point to ID key data - * filled in by the user before calling this function, in which case a user-supplied Bluetooth address and IRK will be distributed, - * or the pointer to the ID key data structure can be NULL, in which case the device's configured (or default, if none is configured) - * Bluetooth address and IRK will be distributed. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * Note that the SoftDevice expects the application to provide memory for storing the + * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key + * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the + * @ref BLE_GAP_EVT_AUTH_STATUS event. * * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported. */ SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset)); /**@brief Reply with an authentication key. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES. * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL. - * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination). - * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in Little Endian format. - * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination) + * or NULL when confirming LE Secure Connections Numeric Comparison. + * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in Little Endian format. * * @retval ::NRF_SUCCESS Authentication key successfully set. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. @@ -1196,16 +1590,123 @@ SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16 */ SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key)); +/**@brief Reply with an LE Secure connections DHKey. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_dhkey LE Secure Connections DHKey. + * + * @retval ::NRF_SUCCESS DHKey successfully set. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)); -/**@brief Initiate GAP Encryption procedure. +/**@brief Notify the peer of a local keypress. + * + * @details This function can only be used when an authentication procedure using LE Secure Connection is in progress. Calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. - * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. - * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. + * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES. + * + * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either not entering a passkey or keypresses have not been enabled by both peers. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. + */ +SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not)); + +/**@brief Generate a set of OOB data to send to a peer out of band. + * + * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established, + * the one used during connection setup). The application may manually overwrite it with an updated value. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. Can be BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet. + * @param[in] p_pk_own LE Secure Connections local P-256 Public Key. + * @param[out] p_oobd_own The OOB data to be sent out of band to a peer. + * + * @retval ::NRF_SUCCESS OOB data successfully generated. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own)); + +/**@brief Provide the OOB data sent/received out of band. + * + * @note At least one of the 2 pointers provided must be different from NULL. + * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function. + * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function. + * + * @events + * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if none sent. + * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received. + * + * @retval ::NRF_SUCCESS OOB data accepted. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. + */ +SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer)); + +/**@brief Initiate GAP Encryption procedure. * * @details In the central role, this function will initiate the encryption procedure using the encryption information provided. * - * @note Calling this function may result in the following event depending on the outcome and parameters: @ref BLE_GAP_EVT_CONN_SEC_UPDATE. + * @events + * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC} + * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure. + * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. * * @retval ::NRF_SUCCESS Successfully initiated authentication procedure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. @@ -1218,16 +1719,20 @@ SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, bl /**@brief Reply with GAP security information. + * + * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. + * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. + * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. + * + * @mscs + * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available. * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available. * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available. * - * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE. - * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters. - * @note Data signing is not yet supported, and p_sign_info must therefore be NULL. - * * @retval ::NRF_SUCCESS Successfully accepted security information. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. @@ -1252,6 +1757,17 @@ SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_ * * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called. * + * @events + * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is + dependent on the settings of the threshold_dbm + and skip_count input parameters.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID. * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event. @@ -1268,6 +1784,11 @@ SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_hand * @note An RSSI change detected before the call but not yet received by the application * may be reported after @ref sd_ble_gap_rssi_stop has been called. * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting. @@ -1278,13 +1799,17 @@ SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle /**@brief Get the received signal strength for the last connection event. - * - * @param[in] conn_handle Connection handle. - * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. * * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start. * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC} + * @endmscs + * + * @param[in] conn_handle Connection handle. + * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored. + * * @retval ::NRF_SUCCESS Successfully read the RSSI. * @retval ::NRF_ERROR_NOT_FOUND No sample is available. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. @@ -1295,6 +1820,17 @@ SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, /**@brief Start scanning (GAP Discovery procedure, Observer Procedure). + * + * + * @events + * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.} + * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs * * @param[in] p_scan_params Pointer to scan parameters structure. * @@ -1303,12 +1839,18 @@ SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. - * @retval ::NRF_ERROR_NOT_SUPPORTED A selected feature is not supported (selective scanning). + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again */ SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params)); /**@brief Stop scanning (GAP Discovery procedure, Observer Procedure). + * + * @mscs + * @mmsc{@ref BLE_GAP_SCAN_MSC} + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @endmscs * * @retval ::NRF_SUCCESS Successfully stopped scanning procedure. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (most probably not in scanning state). @@ -1318,22 +1860,45 @@ SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void)); /**@brief Create a connection (GAP Link Establishment). * - * @param[in] p_peer_addr Pointer to peer address. If the selective bit is set in @ref ble_gap_scan_params_t, then this must be NULL. + * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function. + * + * @mscs + * @mmsc{@ref BLE_GAP_WL_SHARE_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC} + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs + * + * @param[in] p_peer_addr Pointer to peer address. If the use_whitelist bit is set in @ref ble_gap_scan_params_t, then this is ignored. + * If @ref ble_gap_addr_t::addr_id_peer is set then p_peer_addr must be present in the device identity list + * see @ref sd_ble_gap_device_identities_set. * @param[in] p_scan_params Pointer to scan parameters structure. * @param[in] p_conn_params Pointer to desired connection parameters. * * @retval ::NRF_SUCCESS Successfully initiated connection procedure. * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + - Invalid parameter(s) in p_scan_params or p_conn_params. + - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set. + - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set. + * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an + * existing locally initiated connect procedure, which must complete before initiating again. * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address. - * @retval ::NRF_ERROR_NO_MEM limit of available connections reached. - * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. -*/ + * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached. + * @retval ::NRF_ERROR_NO_MEM The configured memory pool (see @ref ble_conn_bw_counts_t) is not large enough for the + * bandwidth selected for this connection. + * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry. If another connection is being established + * wait for the corresponding @ref BLE_GAP_EVT_CONNECTED event before calling again. + * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available. + * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again + */ SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params)); /**@brief Cancel a connection establishment. + * + * @mscs + * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC} + * @endmscs * * @retval ::NRF_SUCCESS Successfully cancelled an ongoing connection procedure. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. @@ -1342,6 +1907,9 @@ SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void)); /** @} */ +#ifdef __cplusplus +} +#endif #endif // BLE_GAP_H__ /** diff --git a/components/softdevice/s110/headers/ble_gatt.h b/components/softdevice/s132/headers/ble_gatt.h similarity index 90% rename from components/softdevice/s110/headers/ble_gatt.h rename to components/softdevice/s132/headers/ble_gatt.h index cb8a67b..53eea73 100644 --- a/components/softdevice/s110/headers/ble_gatt.h +++ b/components/softdevice/s132/headers/ble_gatt.h @@ -46,23 +46,28 @@ #include "ble_types.h" #include "ble_ranges.h" +#ifdef __cplusplus +extern "C" { +#endif /** @addtogroup BLE_GATT_DEFINES Defines * @{ */ -/** @brief Default MTU size. */ +/** @brief Default MTU size, in bytes. */ #define GATT_MTU_SIZE_DEFAULT 23 -/** @brief Only the default MTU size of 23 is currently supported. */ -#define GATT_RX_MTU 23 - - /**@brief Invalid Attribute Handle. */ #define BLE_GATT_HANDLE_INVALID 0x0000 +/**@brief First Attribute Handle. */ +#define BLE_GATT_HANDLE_START 0x0001 + +/**@brief Last Attribute Handle. */ +#define BLE_GATT_HANDLE_END 0xFFFF + /** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources * @{ */ -#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ +#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ /** @} */ /** @defgroup BLE_GATT_WRITE_OPS GATT Write operations @@ -77,8 +82,8 @@ /** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags * @{ */ -#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 -#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */ +#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */ /** @} */ /** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations @@ -169,6 +174,21 @@ /** @addtogroup BLE_GATT_STRUCTURES Structures * @{ */ +/** + * @brief BLE GATT initialization parameters. + */ +typedef struct +{ + uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive. + If it is 0 then @ref GATT_MTU_SIZE_DEFAULT will be used. + Otherwise @ref GATT_MTU_SIZE_DEFAULT is the minimum value. + @mscs + @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + @endmscs + */ +} ble_gatt_enable_params_t; + /**@brief GATT Characteristic Properties. */ typedef struct { @@ -190,11 +210,11 @@ typedef struct uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */ } ble_gatt_char_ext_props_t; +/** @} */ + +#ifdef __cplusplus +} +#endif #endif // BLE_GATT_H__ /** @} */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s310/headers/ble_gattc.h b/components/softdevice/s132/headers/ble_gattc.h similarity index 59% rename from components/softdevice/s310/headers/ble_gattc.h rename to components/softdevice/s132/headers/ble_gattc.h index dc476aa..534c69d 100644 --- a/components/softdevice/s310/headers/ble_gattc.h +++ b/components/softdevice/s132/headers/ble_gattc.h @@ -47,6 +47,11 @@ #include "ble_types.h" #include "ble_ranges.h" #include "nrf_svc.h" +#include "nrf_error.h" + +#ifdef __cplusplus +extern "C" { +#endif /** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations * @{ */ @@ -58,11 +63,13 @@ enum BLE_GATTC_SVCS SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */ SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */ SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */ + SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */ SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */ SD_BLE_GATTC_READ, /**< Generic read. */ SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */ SD_BLE_GATTC_WRITE, /**< Generic write. */ - SD_BLE_GATTC_HV_CONFIRM /**< Handle Value Confirmation. */ + SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */ + SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */ }; /** @@ -70,16 +77,18 @@ enum BLE_GATTC_SVCS */ enum BLE_GATTC_EVTS { - BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. @ref ble_gattc_evt_prim_srvc_disc_rsp_t */ - BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. @ref ble_gattc_evt_rel_disc_rsp_t */ - BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. @ref ble_gattc_evt_char_disc_rsp_t */ - BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. @ref ble_gattc_evt_desc_disc_rsp_t */ - BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t */ - BLE_GATTC_EVT_READ_RSP, /**< Read Response event. @ref ble_gattc_evt_read_rsp_t */ - BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. @ref ble_gattc_evt_char_vals_read_rsp_t */ - BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. @ref ble_gattc_evt_write_rsp_t */ - BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. @ref ble_gattc_evt_hvx_t */ - BLE_GATTC_EVT_TIMEOUT /**< Timeout event. @ref ble_gattc_evt_timeout_t */ + BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */ + BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */ + BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */ + BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */ + BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */ + BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */ + BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */ + BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */ + BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */ + BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */ + BLE_GATTC_EVT_TIMEOUT /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */ }; /** @} */ @@ -92,8 +101,11 @@ enum BLE_GATTC_EVTS #define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */ /** @} */ -/**@brief Last Attribute Handle. */ -#define BLE_GATTC_HANDLE_END 0xFFFF +/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats + * @{ */ +#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */ +#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */ +/** @} */ /** @} */ @@ -146,49 +158,80 @@ typedef struct /**@brief Write Parameters. */ typedef struct { - uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ - uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ - uint16_t handle; /**< Handle to the attribute to be written. */ - uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ - uint16_t len; /**< Length of data in bytes. */ - uint8_t *p_value; /**< Pointer to the value data. */ + uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */ + uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */ + uint16_t handle; /**< Handle to the attribute to be written. */ + uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */ + uint16_t len; /**< Length of data in bytes. */ + uint8_t const *p_value; /**< Pointer to the value data. */ } ble_gattc_write_params_t; +/**@brief Attribute Information for 16-bit Attribute UUID. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + ble_uuid_t uuid; /**< 16-bit Attribute UUID. */ +} ble_gattc_attr_info16_t; + +/**@brief Attribute Information for 128-bit Attribute UUID. */ +typedef struct +{ + uint16_t handle; /**< Attribute handle. */ + ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */ +} ble_gattc_attr_info128_t; + /**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */ typedef struct { uint16_t count; /**< Service count. */ - ble_gattc_service_t services[1]; /**< Service data, variable length. */ + ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_prim_srvc_disc_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */ typedef struct { uint16_t count; /**< Include count. */ - ble_gattc_include_t includes[1]; /**< Include data, variable length. */ + ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_rel_disc_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */ typedef struct { uint16_t count; /**< Characteristic count. */ - ble_gattc_char_t chars[1]; /**< Characteristic data, variable length. */ + ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_char_disc_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */ typedef struct { uint16_t count; /**< Descriptor count. */ - ble_gattc_desc_t descs[1]; /**< Descriptor data, variable length. */ + ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_desc_disc_rsp_t; +/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */ +typedef struct +{ + uint16_t count; /**< Attribute count. */ + uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */ + union { + ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ + ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ + } info; /**< Attribute information union. */ +} ble_gattc_evt_attr_info_disc_rsp_t; + /**@brief GATT read by UUID handle value pair. */ typedef struct { uint16_t handle; /**< Attribute Handle. */ - uint8_t *p_value; /**< Pointer to value, variable length (length available as value_len in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t). - Please note that this pointer is absolute to the memory provided by the user when retrieving the event, - so it will effectively point to a location inside the handle_value array. */ + uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */ } ble_gattc_handle_value_t; /**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */ @@ -196,7 +239,9 @@ typedef struct { uint16_t count; /**< Handle-Value Pair Count. */ uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */ - ble_gattc_handle_value_t handle_value[1]; /**< Handle-Value(s) list, variable length. */ + uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter. + @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_char_val_by_uuid_read_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */ @@ -205,14 +250,16 @@ typedef struct uint16_t handle; /**< Attribute Handle. */ uint16_t offset; /**< Offset of the attribute data. */ uint16_t len; /**< Attribute data length. */ - uint8_t data[1]; /**< Attribute data, variable length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_read_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */ typedef struct { uint16_t len; /**< Concatenated Attribute values length. */ - uint8_t values[1]; /**< Attribute values, variable length. */ + uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_char_vals_read_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */ @@ -222,7 +269,8 @@ typedef struct uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */ uint16_t offset; /**< Data offset. */ uint16_t len; /**< Data length. */ - uint8_t data[1]; /**< Data, variable length. */ + uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_write_rsp_t; /**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */ @@ -231,9 +279,16 @@ typedef struct uint16_t handle; /**< Handle to which the HVx operation applies. */ uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */ uint16_t len; /**< Attribute data length. */ - uint8_t data[1]; /**< Attribute data, variable length. */ + uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gattc_evt_hvx_t; +/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */ +typedef struct +{ + uint16_t server_rx_mtu; /**< Server RX MTU size. */ +} ble_gattc_evt_exchange_mtu_rsp_t; + /**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */ typedef struct { @@ -257,7 +312,9 @@ typedef struct ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */ ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */ ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */ + ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */ ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */ + ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */ } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */ } ble_gattc_evt_t; /** @} */ @@ -273,6 +330,14 @@ typedef struct * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. * + * @events + * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] start_handle Handle to start searching from. * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned. @@ -291,6 +356,14 @@ SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_se * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached, * this must be called again with an updated handle range to continue the search. * + * @events + * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_REL_DISC_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. * @@ -312,6 +385,14 @@ SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event. * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on. * @@ -329,6 +410,14 @@ SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteris * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached, * this must be called again with an updated handle range to continue the discovery. * + * @events + * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on. * @@ -346,6 +435,14 @@ SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_dis * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached, * this must be called again with an updated handle range to continue the discovery. * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_UUID_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_uuid Pointer to a Characteristic value UUID to read. * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on. @@ -365,6 +462,14 @@ SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_b * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the * complete value. * + * @events + * @event{@ref BLE_GATTC_EVT_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] handle The handle of the attribute to be read. * @param[in] offset Offset into the attribute value to be read. @@ -372,7 +477,6 @@ SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_b * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_BUSY Client procedure already in progress. */ SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset)); @@ -382,6 +486,14 @@ SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint * * @details This function initiates a GATT Read Multiple Characteristic Values procedure. * + * @events + * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_READ_MULT_MSC} + * @endmscs + * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read. * @param[in] handle_count The number of handles in p_handles. @@ -402,7 +514,18 @@ SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(ui * @note It is important to note that a write without response will consume an application buffer, and will therefore * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. A write (with response) on the other hand will use the * standard client internal buffer and thus will only generate a @ref BLE_GATTC_EVT_WRITE_RSP event as soon as the write response - * has been received from the peer. Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. + * has been received from the peer. Please see the documentation of @ref sd_ble_tx_packet_count_get for more details. + * + * @events + * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Generated when using write request or queued writes.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC} + * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC} + * @mmsc{@ref BLE_COMMON_APP_BUFF_MSC} + * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] p_write_params A pointer to a write parameters structure. @@ -414,12 +537,16 @@ SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(ui * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. * @retval ::NRF_ERROR_BUSY Procedure already in progress. - * @retval ::BLE_ERROR_NO_TX_BUFFERS There are no available buffers left. + * @retval ::BLE_ERROR_NO_TX_PACKETS No available application packets for this connection. */ SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params)); /**@brief Send a Handle Value Confirmation to the GATT Server. + * + * @mscs + * @mmsc{@ref BLE_GATTC_HVI_MSC} + * @endmscs * * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. * @param[in] handle The handle of the attribute in the indication. @@ -431,11 +558,103 @@ SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, bl */ SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle)); +/**@brief Discovers information about a range of attributes on a GATT server. + * + * @events + * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.} + * @endevents + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] p_handle_range The range of handles to request information about. + * + * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range)); + +/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value, and + * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref GATT_MTU_SIZE_DEFAULT. + * + * @events + * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP} + * @event{@ref BLE_EVT_DATA_LENGTH_CHANGED, Generated if a data length update procedure is performed after the ATT_MTU exchange.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] client_rx_mtu Client RX MTU size. + * - The minimum value is @ref GATT_MTU_SIZE_DEFAULT. + * - The maximum value is @ref ble_gatt_enable_params_t::att_mtu. + * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent request to the server. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied. + * @retval ::NRF_ERROR_BUSY Client procedure already in progress. + */ +SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu)); + +/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * + * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event. + * @note If the buffer contains different event, behavior is undefined. + * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with + * the next Handle-Value pair in each iteration. If the function returns other than + * @ref NRF_SUCCESS, it will not be changed. + * - To start iteration, initialize the structure to zero. + * - To continue, pass the value from previous iteration. + * + * \code + * ble_gattc_handle_value_t iter; + * memset(&iter, 0, sizeof(ble_gattc_handle_value_t)); + * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS) + * { + * app_handle = iter.handle; + * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len); + * } + * \endcode + * + * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair. + * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list. + */ +static inline uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter) +{ + uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len; + uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value; + uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first; + + if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count) + { + p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0]; + p_iter->p_value = p_next + sizeof(uint16_t); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_NOT_FOUND; + } +} + /** @} */ +#ifdef __cplusplus +} +#endif #endif /* BLE_GATTC_H__ */ /** @} - @} */ diff --git a/components/softdevice/s310/headers/ble_gatts.h b/components/softdevice/s132/headers/ble_gatts.h similarity index 76% rename from components/softdevice/s310/headers/ble_gatts.h rename to components/softdevice/s132/headers/ble_gatts.h index faec547..4fc4532 100644 --- a/components/softdevice/s310/headers/ble_gatts.h +++ b/components/softdevice/s132/headers/ble_gatts.h @@ -50,6 +50,10 @@ #include "ble_gatt.h" #include "nrf_svc.h" +#ifdef __cplusplus +extern "C" { +#endif + /** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations * @{ */ @@ -69,6 +73,9 @@ enum BLE_GATTS_SVCS SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */ SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */ SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */ + SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */ + SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */ + SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */ }; /** @@ -76,12 +83,13 @@ enum BLE_GATTS_SVCS */ enum BLE_GATTS_EVTS { - BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. @ref ble_gatts_evt_write_t */ - BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request.@ref ble_gatts_evt_rw_authorize_request_t */ - BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending, awaiting a sd_ble_gatts_sys_attr_set(). @ref ble_gatts_evt_sys_attr_missing_t */ - BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. @ref ble_gatts_evt_hvc_t */ - BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. No additional event structure applies. */ - BLE_GATTS_EVT_TIMEOUT /**< Timeout. @ref ble_gatts_evt_timeout_t */ + BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */ + BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */ + BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */ + BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */ + BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. No additional event structure applies. */ + BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */ + BLE_GATTS_EVT_TIMEOUT /**< Peer failed to resonpond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */ }; /** @} */ @@ -156,8 +164,8 @@ enum BLE_GATTS_EVTS /** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size * @{ */ -#define BLE_GATTS_ATTR_TAB_SIZE_MIN 216 /**< Minimum Attribute Table size */ -#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT 0x0000 /**< Default Attribute Table size (0x700 bytes for this version of the SoftDevice). */ +#define BLE_GATTS_ATTR_TAB_SIZE_MIN 248 /**< Minimum Attribute Table size */ +#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT 0x0000 /**< Default Attribute Table size (0x580 bytes for this version of the SoftDevice). */ /** @} */ /** @} */ @@ -166,12 +174,12 @@ enum BLE_GATTS_EVTS * @{ */ /** - * @brief BLE GATTS init options + * @brief BLE GATTS initialization parameters. */ typedef struct { - uint8_t service_changed:1; /**< Include the Service Changed characteristic in the Attribute Table. */ - uint32_t attr_tab_size; /**< Attribute Table size in bytes. The size must be a multiple of 4. @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT is used to set the default size. */ + uint8_t service_changed:1; /**< Include the Service Changed characteristic in the Attribute Table. */ + uint32_t attr_tab_size; /**< Attribute Table size in bytes. The size must be a multiple of 4. @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT is used to set the default size. */ } ble_gatts_enable_params_t; /**@brief Attribute metadata. */ @@ -210,18 +218,6 @@ typedef struct } ble_gatts_value_t; -/**@brief GATT Attribute Context. */ -typedef struct -{ - ble_uuid_t srvc_uuid; /**< Service UUID. */ - ble_uuid_t char_uuid; /**< Characteristic UUID if applicable (BLE_UUID_TYPE_UNKNOWN otherwise). */ - ble_uuid_t desc_uuid; /**< Descriptor UUID if applicable (BLE_UUID_TYPE_UNKNOWN otherwise). */ - uint16_t srvc_handle; /**< Service Handle. */ - uint16_t value_handle; /**< Characteristic Value Handle if applicable (BLE_GATT_HANDLE_INVALID otherwise). */ - uint8_t type; /**< Attribute Type, see @ref BLE_GATTS_ATTR_TYPES. */ -} ble_gatts_attr_context_t; - - /**@brief GATT Characteristic Presentation Format. */ typedef struct { @@ -268,29 +264,25 @@ typedef struct uint8_t *p_data; /**< Actual data content, use NULL to use the current attribute value. */ } ble_gatts_hvx_params_t; -/**@brief GATT Read Authorization parameters. */ +/**@brief GATT Authorization parameters. */ typedef struct { uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ - uint8_t update : 1; /**< If set, data supplied in p_data will be used in the ATT response. */ + uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value. + Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set, + as the data to be written needs to be stored and later provided by the application. */ uint16_t offset; /**< Offset of the attribute value being updated. */ uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */ - uint8_t *p_data; /**< Pointer to new value used to update the attribute value. */ -} ble_gatts_read_authorize_params_t; - -/**@brief GATT Write Authorization parameters. */ -typedef struct -{ - uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */ -} ble_gatts_write_authorize_params_t; + const uint8_t *p_data; /**< Pointer to new value used to update the attribute value. */ +} ble_gatts_authorize_params_t; /**@brief GATT Read or Write Authorize Reply parameters. */ typedef struct { uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */ union { - ble_gatts_read_authorize_params_t read; /**< Read authorization parameters. */ - ble_gatts_write_authorize_params_t write; /**< Write authorization parameters. */ + ble_gatts_authorize_params_t read; /**< Read authorization parameters. */ + ble_gatts_authorize_params_t write; /**< Write authorization parameters. */ } params; /**< Reply Parameters. */ } ble_gatts_rw_authorize_reply_params_t; @@ -300,18 +292,20 @@ typedef struct typedef struct { uint16_t handle; /**< Attribute Handle. */ + ble_uuid_t uuid; /**< Attribute UUID. */ uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */ - ble_gatts_attr_context_t context; /**< Attribute Context. */ + uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalise the writing operation. */ uint16_t offset; /**< Offset for the write operation. */ uint16_t len; /**< Length of the received data. */ - uint8_t data[1]; /**< Received data, variable length. */ + uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_gatts_evt_write_t; /**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */ typedef struct { uint16_t handle; /**< Attribute Handle. */ - ble_gatts_attr_context_t context; /**< Attribute Context. */ + ble_uuid_t uuid; /**< Attribute UUID. */ uint16_t offset; /**< Offset for the read operation. */ } ble_gatts_evt_read_t; @@ -338,6 +332,12 @@ typedef struct uint16_t handle; /**< Attribute Handle. */ } ble_gatts_evt_hvc_t; +/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */ +typedef struct +{ + uint16_t client_rx_mtu; /**< Client RX MTU size. */ +} ble_gatts_evt_exchange_mtu_request_t; + /**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */ typedef struct { @@ -345,18 +345,19 @@ typedef struct } ble_gatts_evt_timeout_t; -/**@brief GATT Server event callback event structure. */ +/**@brief GATTS event structure. */ typedef struct { uint16_t conn_handle; /**< Connection Handle on which the event occurred. */ union { - ble_gatts_evt_write_t write; /**< Write Event Parameters. */ - ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ - ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ - ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ - ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ - } params; /**< Event Parameters. */ + ble_gatts_evt_write_t write; /**< Write Event Parameters. */ + ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */ + ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */ + ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */ + ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */ + ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */ + } params; /**< Event Parameters. */ } ble_gatts_evt_t; /** @} */ @@ -365,14 +366,18 @@ typedef struct * @{ */ /**@brief Add a service declaration to the Attribute Table. + * + * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to + * add a secondary service declaration that is not referenced by another service later in the Attribute Table. + * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs * * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES. * @param[in] p_uuid Pointer to service UUID. * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. * - * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to - * add a secondary service declaration that is not referenced by another service later in the Attribute Table. - * * @retval ::NRF_SUCCESS Successfully added a service declaration. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table. @@ -388,6 +393,10 @@ SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type * * @note The included service must already be present in the Attribute Table prior to this call. * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. * @param[in] inc_srvc_handle Handle of the included service. * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored. @@ -396,6 +405,7 @@ SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services. * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. + * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service. * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. @@ -412,6 +422,10 @@ SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t ser * * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions. * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. * @param[in] p_char_md Characteristic metadata. * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value. @@ -432,6 +446,10 @@ SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_ad * * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time). * + * @mscs + * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC} + * @endmscs + * * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially. * @param[in] p_attr Pointer to the attribute structure. * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored. @@ -447,13 +465,18 @@ SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_ad SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle)); /**@brief Set the value of a given attribute. + * + * @note Values other than system attributes can be set at any time, regardless of wheter any active connections exist. + * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used. * @param[in] handle Attribute handle. * @param[in,out] p_value Attribute value information. * - * @note Values other than system attributes can be set at any time, regardless of wheter any active connections exist. - * * @retval ::NRF_SUCCESS Successfully set the value of the attribute. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. @@ -466,10 +489,6 @@ SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16 SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); /**@brief Get the value of a given attribute. - * - * @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used. - * @param[in] handle Attribute handle. - * @param[in,out] p_value Attribute value information. * * @note If the attribute value is longer than the size of the supplied buffer, * p_len will return the total attribute value length (excluding offset), @@ -480,11 +499,17 @@ SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_ha * may refer to an already disconnected connection. Refer to the documentation of * @ref sd_ble_gatts_sys_attr_get for further information. * + * @param[in] conn_handle Connection handle. If the value does not belong to a system attribute then @ref BLE_CONN_HANDLE_INVALID can be used. + * @param[in] handle Attribute handle. + * @param[in,out] p_value Attribute value information. + * * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied. * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE @ref BLE_CONN_HANDLE_INVALID supplied on a system attribute. + * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. */ SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value)); @@ -497,14 +522,27 @@ SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_ha * the peer. * * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution. - * When receiveing the error codes @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and - * @ref BLE_ERROR_NO_TX_BUFFERS the Attribute Table has been updated. + * The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY, + * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref BLE_ERROR_NO_TX_PACKETS. * The caller can check whether the value has been updated by looking at the contents of *(p_hvx_params->p_len). * * @note It is important to note that a notification will consume an application buffer, and will therefore * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. An indication on the other hand will use the * standard server internal buffer and thus will only generate a @ref BLE_GATTS_EVT_HVC event as soon as the confirmation - * has been received from the peer. Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. + * has been received from the peer. Please see the documentation of @ref sd_ble_tx_packet_count_get for more details. + * + * @events + * @event{@ref BLE_EVT_TX_COMPLETE, Transmission complete.} + * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_HVN_MSC} + * @mmsc{@ref BLE_GATTS_HVI_MSC} + * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC} + * @mmsc{@ref BLE_COMMON_APP_BUFF_MSC} + * @endmscs * * @param[in] conn_handle Connection handle. * @param[in] p_hvx_params Pointer to an HVx parameters structure. If the p_data member contains a non-NULL pointer the attribute value will be updated with @@ -512,16 +550,20 @@ SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_ha * * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate. * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated. * @retval ::NRF_ERROR_NOT_FOUND Attribute not found. + * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied. * @retval ::NRF_ERROR_BUSY Procedure already in progress. * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. - * @retval ::BLE_ERROR_NO_TX_BUFFERS There are no available buffers to send the data, applies only to notifications. + * @retval ::BLE_ERROR_NO_TX_PACKETS No available application packets for this connection, applies only to notifications. */ SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params)); @@ -533,16 +575,27 @@ SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_ga * * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here. * + * @events + * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_SC_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] start_handle Start of affected attribute handle range. * @param[in] end_handle End of affected attribute handle range. * * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or notifications and/or indications not enabled in the CCCD. + * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref sd_ble_enable and @ref ble_gatts_enable_params_t. + * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true: + * - Invalid Connection State + * - Notifications and/or indications not enabled in the CCCD + * - An ATT_MTU exchange is ongoing * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application. - * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, notifications or indications must be enabled in the CCCD. * @retval ::NRF_ERROR_BUSY Procedure already in progress. * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value. */ @@ -552,15 +605,30 @@ SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint * * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application. * + * @mscs + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC} + * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC} + * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_PEER_CANCEL_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application. * + * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond + * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update + * is set to 0. + * * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending. * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid, - * or for Read Authorization reply: requested handles not replied with, - * or for Write Authorization reply: handle supplied does not match requested handle. + * handle supplied does not match requested handle, + * or invalid data to be written provided by the application. * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time. */ SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params)); @@ -588,6 +656,12 @@ SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_repl * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified. * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified. * + * @mscs + * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC} + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle. * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL. * @param[in] len Size of data pointed by p_sys_attr_data, in octets. @@ -595,7 +669,9 @@ SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_repl * * @retval ::NRF_SUCCESS Successfully set the system attribute information. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time. @@ -616,22 +692,85 @@ SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t c * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned. * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned. * + * @mscs + * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC} + * @endmscs + * * @param[in] conn_handle Connection handle of the recently terminated connection. - * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. NULL can be provided to - * obtain the length of the data + * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described + * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data. * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditially updated to actual length of system attribute data. * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS * * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information. * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied. * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer. * @retval ::NRF_ERROR_NOT_FOUND No system attributes found. */ SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags)); + +/**@brief Retrieve the first valid user attribute handle. + * + * @param[out] p_handle Pointer to an integer where the handle will be stored. + * + * @retval ::NRF_SUCCESS Successfully retrieved the handle. + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + */ +SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle)); + +/**@brief Retrieve the attribute UUID and/or metadata. + * + * @param[in] handle Attribute handle + * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field. + * @param[out] p_md Metadata of the attribute. Use NULL to omit this field. + * + * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata, + * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL. + * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found. + */ +SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md)); + +/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client. + * + * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. + * + * @details The SoftDevice sets ATT_MTU to the minimum of: + * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and + * - The Server RX MTU value. + * + * However, the SoftDevice never sets ATT_MTU lower than @ref GATT_MTU_SIZE_DEFAULT. + * + * @events + * @event{@ref BLE_EVT_DATA_LENGTH_CHANGED, Generated if a data length update procedure is performed after the ATT_MTU exchange.} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE} + * @endmscs + * + * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on. + * @param[in] server_rx_mtu Server RX MTU size. + * - The minimum value is @ref GATT_MTU_SIZE_DEFAULT. + * - The maximum value is @ref ble_gatt_enable_params_t::att_mtu. + * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request + * if an ATT_MTU exchange has already been performed in the other direction. + * + * @retval ::NRF_SUCCESS Successfully sent response to the client. + * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. + * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending. + * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied. + * @retval ::NRF_ERROR_BUSY The stack is busy. Retry at later time. + */ +SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu)); /** @} */ +#ifdef __cplusplus +} +#endif #endif // BLE_GATTS_H__ /** diff --git a/components/softdevice/s110/headers/ble_hci.h b/components/softdevice/s132/headers/ble_hci.h similarity index 98% rename from components/softdevice/s110/headers/ble_hci.h rename to components/softdevice/s132/headers/ble_hci.h index 2488985..4a9620c 100644 --- a/components/softdevice/s110/headers/ble_hci.h +++ b/components/softdevice/s132/headers/ble_hci.h @@ -42,6 +42,9 @@ #ifndef BLE_HCI_H__ #define BLE_HCI_H__ +#ifdef __cplusplus +extern "C" { +#endif /** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes * @{ */ @@ -120,6 +123,9 @@ /** @} */ +#ifdef __cplusplus +} +#endif #endif // BLE_HCI_H__ /** @} */ diff --git a/components/softdevice/s310/headers/ble_l2cap.h b/components/softdevice/s132/headers/ble_l2cap.h similarity index 88% rename from components/softdevice/s310/headers/ble_l2cap.h rename to components/softdevice/s132/headers/ble_l2cap.h index bd4099e..8a68ed9 100644 --- a/components/softdevice/s310/headers/ble_l2cap.h +++ b/components/softdevice/s132/headers/ble_l2cap.h @@ -48,6 +48,10 @@ #include "ble_err.h" #include "nrf_svc.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations * @{ */ @@ -104,7 +108,8 @@ typedef struct typedef struct { ble_l2cap_header_t header; /**< L2CAP packet header. */ - uint8_t data[1]; /**< Packet data, variable length. */ + uint8_t data[1]; /**< Packet data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation. + See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */ } ble_l2cap_evt_rx_t; @@ -127,6 +132,10 @@ typedef struct * * @details This registers a higher protocol layer with the L2CAP multiplexer, and is requried prior to all operations on the CID. * + * @mscs + * @mmsc{@ref BLE_L2CAP_API_MSC} + * @endmscs + * * @param[in] cid L2CAP CID. * * @retval ::NRF_SUCCESS Successfully registered a CID with the L2CAP layer. @@ -140,6 +149,10 @@ SVCALL(SD_BLE_L2CAP_CID_REGISTER, uint32_t, sd_ble_l2cap_cid_register(uint16_t c * * @details This unregisters a previously registerd higher protocol layer with the L2CAP multiplexer. * + * @mscs + * @mmsc{@ref BLE_L2CAP_API_MSC} + * @endmscs + * * @param[in] cid L2CAP CID. * * @retval ::NRF_SUCCESS Successfully unregistered the CID. @@ -150,9 +163,18 @@ SVCALL(SD_BLE_L2CAP_CID_UNREGISTER, uint32_t, sd_ble_l2cap_cid_unregister(uint16 /**@brief Transmit an L2CAP packet. * - * @note It is important to note that a call to this function will consume an application buffer, and will therefore + * @note It is important to note that a call to this function will consume an application packet, and will therefore * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted. - * Please see the documentation of @ref sd_ble_tx_buffer_count_get for more details. + * Please see the documentation of @ref sd_ble_tx_packet_count_get for more details. + * + * @events + * @event{@ref BLE_EVT_TX_COMPLETE} + * @event{@ref BLE_L2CAP_EVT_RX} + * @endevents + * + * @mscs + * @mmsc{@ref BLE_L2CAP_API_MSC} + * @endmscs * * @param[in] conn_handle Connection Handle. * @param[in] p_header Pointer to a packet header containing length and CID. @@ -163,13 +185,16 @@ SVCALL(SD_BLE_L2CAP_CID_UNREGISTER, uint32_t, sd_ble_l2cap_cid_unregister(uint16 * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register. * @retval ::NRF_ERROR_NOT_FOUND CID not found. * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation. - * @retval ::BLE_ERROR_NO_TX_BUFFERS Not enough application buffers available. + * @retval ::BLE_ERROR_NO_TX_PACKETS Not enough application packets available. * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF. */ SVCALL(SD_BLE_L2CAP_TX, uint32_t, sd_ble_l2cap_tx(uint16_t conn_handle, ble_l2cap_header_t const *p_header, uint8_t const *p_data)); /** @} */ +#ifdef __cplusplus +} +#endif #endif // BLE_L2CAP_H__ /** diff --git a/components/softdevice/s120/headers/ble_ranges.h b/components/softdevice/s132/headers/ble_ranges.h similarity index 75% rename from components/softdevice/s120/headers/ble_ranges.h rename to components/softdevice/s132/headers/ble_ranges.h index 69100b3..24cbb56 100644 --- a/components/softdevice/s120/headers/ble_ranges.h +++ b/components/softdevice/s132/headers/ble_ranges.h @@ -57,60 +57,79 @@ #ifndef BLE_RANGES_H__ #define BLE_RANGES_H__ +#ifdef __cplusplus +extern "C" { +#endif + #define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ -#define BLE_SVC_LAST 0x6B /**< Total: 12. */ +#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */ + -#define BLE_RESERVED_SVC_BASE 0x6C /**< Reserved BLE SVC base. */ -#define BLE_RESERVED_SVC_LAST 0x6F /**< Total: 4. */ +#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */ +#define BLE_GAP_SVC_LAST 0x93 /**< GAP BLE SVC last. */ -#define BLE_GAP_SVC_BASE 0x70 /**< GAP BLE SVC base. */ -#define BLE_GAP_SVC_LAST 0x8F /**< Total: 32. */ -#define BLE_GATTC_SVC_BASE 0x90 /**< GATTC BLE SVC base. */ -#define BLE_GATTC_SVC_LAST 0x9F /**< Total: 32. */ +#define BLE_GATTC_SVC_BASE 0x94 /**< GATTC BLE SVC base. */ +#define BLE_GATTC_SVC_LAST 0x9F /**< GATTC BLE SVC last. */ + #define BLE_GATTS_SVC_BASE 0xA0 /**< GATTS BLE SVC base. */ -#define BLE_GATTS_SVC_LAST 0xAF /**< Total: 16. */ +#define BLE_GATTS_SVC_LAST 0xAF /**< GATTS BLE SVC last. */ + #define BLE_L2CAP_SVC_BASE 0xB0 /**< L2CAP BLE SVC base. */ -#define BLE_L2CAP_SVC_LAST 0xBF /**< Total: 16. */ +#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */ #define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */ + #define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */ -#define BLE_EVT_LAST 0x0F /**< Total: 15. */ +#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */ + #define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */ -#define BLE_GAP_EVT_LAST 0x2F /**< Total: 32. */ +#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */ + #define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */ -#define BLE_GATTC_EVT_LAST 0x4F /**< Total: 32. */ +#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */ + #define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */ -#define BLE_GATTS_EVT_LAST 0x6F /**< Total: 32. */ +#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */ + #define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */ -#define BLE_L2CAP_EVT_LAST 0x8F /**< Total: 32. */ +#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */ #define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */ + #define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */ -#define BLE_OPT_LAST 0x1F /**< Total: 31. */ +#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */ + #define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */ -#define BLE_GAP_OPT_LAST 0x3F /**< Total: 32. */ +#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */ + #define BLE_GATTC_OPT_BASE 0x40 /**< GATTC BLE Option base. */ -#define BLE_GATTC_OPT_LAST 0x5F /**< Total: 32. */ +#define BLE_GATTC_OPT_LAST 0x5F /**< GATTC BLE Option last. */ + #define BLE_GATTS_OPT_BASE 0x60 /**< GATTS BLE Option base. */ -#define BLE_GATTS_OPT_LAST 0x7F /**< Total: 32. */ +#define BLE_GATTS_OPT_LAST 0x7F /**< GATTS BLE Option last. */ + #define BLE_L2CAP_OPT_BASE 0x80 /**< L2CAP BLE Option base. */ -#define BLE_L2CAP_OPT_LAST 0x9F /**< Total: 32. */ +#define BLE_L2CAP_OPT_LAST 0x9F /**< L2CAP BLE Option last. */ + +#ifdef __cplusplus +} +#endif #endif /* BLE_RANGES_H__ */ /** diff --git a/components/softdevice/s120/headers/ble_types.h b/components/softdevice/s132/headers/ble_types.h similarity index 96% rename from components/softdevice/s120/headers/ble_types.h rename to components/softdevice/s132/headers/ble_types.h index d99d774..79c7fef 100644 --- a/components/softdevice/s120/headers/ble_types.h +++ b/components/softdevice/s132/headers/ble_types.h @@ -48,6 +48,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + /** @addtogroup BLE_TYPES_DEFINES Defines * @{ */ @@ -79,9 +83,9 @@ #define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */ #define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */ #define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_PPF 0x2A02 /**< Peripheral Privacy Flag Characteristic. */ #define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */ #define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */ +#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */ /** @} */ @@ -178,17 +182,20 @@ /** @brief 128 bit UUID values. */ typedef struct { - unsigned char uuid128[16]; /**< Little-Endian UUID bytes. */ + uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */ } ble_uuid128_t; /** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ typedef struct { - uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ - uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ + uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ + uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ } ble_uuid_t; /** @} */ +#ifdef __cplusplus +} +#endif #endif /* BLE_TYPES_H__ */ diff --git a/components/softdevice/s110/headers/nrf_mbr.h b/components/softdevice/s132/headers/nrf52/nrf_mbr.h similarity index 76% rename from components/softdevice/s110/headers/nrf_mbr.h rename to components/softdevice/s132/headers/nrf52/nrf_mbr.h index 3ac6dbf..8d52d51 100644 --- a/components/softdevice/s110/headers/nrf_mbr.h +++ b/components/softdevice/s132/headers/nrf52/nrf_mbr.h @@ -48,12 +48,26 @@ #include "nrf_svc.h" #include +#if !(defined(NRF52) || defined(NRF52840_XXAA)) +#error "This header file shall only be included for nRF52 projects" +#endif + +#ifdef __cplusplus +extern "C" { +#endif /** @addtogroup NRF_MBR_DEFINES Defines * @{ */ /**@brief MBR SVC Base number. */ -#define MBR_SVC_BASE (0x18) +#define MBR_SVC_BASE (0x18) + +/**@brief Page size in words. */ +#define MBR_PAGE_SIZE_IN_WORDS (1024) + +/** @brief The size that must be reserved for the MBR when a softdevice is written to flash. +This is the offset where the first byte of the softdevice hex file is written.*/ +#define MBR_SIZE (0x1000) /** @} */ @@ -86,7 +100,7 @@ enum NRF_MBR_COMMANDS * If dst is in the middle of a flash page, that whole flash page will be erased. * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. * - * The user of this function is responsible for setting the PROTENSET registers. + * The user of this function is responsible for setting the BPROT registers. * * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. @@ -95,7 +109,7 @@ typedef struct { uint32_t *src; /**< Pointer to the source of data to be copied.*/ uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ - uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of PAGE_SIZE_IN_WORDS words.*/ + uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/ } sd_mbr_command_copy_sd_t; @@ -125,6 +139,7 @@ typedef struct * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area. + * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see sds for more info) */ typedef struct { @@ -137,26 +152,29 @@ typedef struct * Once this function has been called, this address is where the MBR will start to forward interrupts to after a reset. * * To restore default forwarding this function should be called with @param address set to 0. - * The MBR will then start forwarding to interrupts to the adress in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set. + * The MBR will then start forwarding to interrupts to the address in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set. + * + * On Success, this function will not return. It will reset the device. * - * @retval ::NRF_SUCCESS * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size. + * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see sds for more info) */ typedef struct { uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ } sd_mbr_command_vector_table_base_set_t; + typedef struct { uint32_t command; /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */ union { sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ - sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader.*/ sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ - sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set.*/ + sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */ + sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/ } params; } sd_mbr_command_t; @@ -169,14 +187,29 @@ typedef struct * * Commands used when updating a SoftDevice and bootloader. * + * The SD_MBR_COMMAND_COPY_BL and SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires parameters to be + * retained by the MBR when resetting the IC. This is done in a separate flash page + * provided by the application. The uicr register UICR.NRFFW[1] must be set + * to an address corresponding to a page in the application flash space. This page will be cleared + * by the MBR and used to store the command before reset. When the UICR.NRFFW[1] field is set + * the page it refers to must not be used by the application. If the UICR.NRFFW[1] is set to + * 0xFFFFFFFF (the default) MBR commands which use flash will be unavailable and return + * NRF_ERROR_NO_MEM. + * * @param[in] param Pointer to a struct describing the command. * - *@note for retvals see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t - + * @note for retvals see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t ::sd_mbr_command_vector_table_base_set_t + * + * @retval NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF). + * @retval NRF_ERROR_INVALID_PARAM if an invalid command is given. */ SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); /** @} */ + +#ifdef __cplusplus +} +#endif #endif // NRF_MBR_H__ /** diff --git a/components/softdevice/s120/headers/nrf_error.h b/components/softdevice/s132/headers/nrf_error.h similarity index 92% rename from components/softdevice/s120/headers/nrf_error.h rename to components/softdevice/s132/headers/nrf_error.h index efa1b65..1035b76 100644 --- a/components/softdevice/s120/headers/nrf_error.h +++ b/components/softdevice/s132/headers/nrf_error.h @@ -44,6 +44,10 @@ #ifndef NRF_ERROR_H__ #define NRF_ERROR_H__ +#ifdef __cplusplus +extern "C" { +#endif + /** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions * @{ */ #define NRF_ERROR_BASE_NUM (0x0) ///< Global error base @@ -64,13 +68,18 @@ #define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length #define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags #define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data -#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit +#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size #define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out #define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer #define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation #define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address #define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy +#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded. +#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation +#ifdef __cplusplus +} +#endif #endif // NRF_ERROR_H__ /** diff --git a/components/softdevice/s210/headers/nrf_error_sdm.h b/components/softdevice/s132/headers/nrf_error_sdm.h similarity index 97% rename from components/softdevice/s210/headers/nrf_error_sdm.h rename to components/softdevice/s132/headers/nrf_error_sdm.h index b3b9b76..412b9b5 100644 --- a/components/softdevice/s210/headers/nrf_error_sdm.h +++ b/components/softdevice/s132/headers/nrf_error_sdm.h @@ -48,10 +48,17 @@ #include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif + #define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown lfclk source. #define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). #define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erronous SoftDevice flashing). +#ifdef __cplusplus +} +#endif #endif // NRF_ERROR_SDM_H__ /** diff --git a/components/softdevice/s110/headers/nrf_error_soc.h b/components/softdevice/s132/headers/nrf_error_soc.h similarity index 98% rename from components/softdevice/s110/headers/nrf_error_soc.h rename to components/softdevice/s132/headers/nrf_error_soc.h index cfddf7e..93958a4 100644 --- a/components/softdevice/s110/headers/nrf_error_soc.h +++ b/components/softdevice/s132/headers/nrf_error_soc.h @@ -48,6 +48,9 @@ #define NRF_ERROR_SOC_H__ #include "nrf_error.h" +#ifdef __cplusplus +extern "C" { +#endif /* Mutex Errors */ #define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken @@ -69,6 +72,9 @@ #define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel #define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group +#ifdef __cplusplus +} +#endif #endif // NRF_ERROR_SOC_H__ /** @} diff --git a/components/softdevice/s132/headers/nrf_nvic.h b/components/softdevice/s132/headers/nrf_nvic.h new file mode 100644 index 0000000..ce49a41 --- /dev/null +++ b/components/softdevice/s132/headers/nrf_nvic.h @@ -0,0 +1,485 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 HOLDER 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. + * + */ +/** + * @defgroup nrf_nvic_api SoftDevice NVIC API + * @{ + * + * @note In order to use this module, the following code has to be added to a .c file: + * \code + * nrf_nvic_state_t nrf_nvic_state = {0}; + * \endcode + * + * @note Definitions and declarations starting with __ (double underscore) in this header file are + * not intended for direct use by the application. + * + * @brief APIs for the accessing NVIC when using a SoftDevice. + * + */ + +#ifndef NRF_NVIC_H__ +#define NRF_NVIC_H__ + +#include +#include "nrf.h" + +#include "nrf_error_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/**@addtogroup NRF_NVIC_DEFINES Defines + * @{ */ + +/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions + * @{ */ + +#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */ + +#ifdef NRF51 + #define __NRF_NVIC_ISER_COUNT (1) /**< The number of ISER/ICER registers in the NVIC that are used. */ + + /**@brief Interrupts used by the SoftDevice. */ + #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ + (1U << POWER_CLOCK_IRQn) \ + | (1U << RADIO_IRQn) \ + | (1U << RTC0_IRQn) \ + | (1U << TIMER0_IRQn) \ + | (1U << RNG_IRQn) \ + | (1U << ECB_IRQn) \ + | (1U << CCM_AAR_IRQn) \ + | (1U << TEMP_IRQn) \ + | (1U << __NRF_NVIC_NVMC_IRQn) \ + | (1U << (uint32_t)SWI4_IRQn) \ + | (1U << (uint32_t)SWI5_IRQn) \ + )) + + /**@brief Interrupts available for to application. */ + #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) +#endif + +#if (defined(NRF52) || defined(NRF52840_XXAA)) + #define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */ + + /**@brief Interrupts used by the SoftDevice. */ + #define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \ + (1U << POWER_CLOCK_IRQn) \ + | (1U << RADIO_IRQn) \ + | (1U << RTC0_IRQn) \ + | (1U << TIMER0_IRQn) \ + | (1U << RNG_IRQn) \ + | (1U << ECB_IRQn) \ + | (1U << CCM_AAR_IRQn) \ + | (1U << TEMP_IRQn) \ + | (1U << __NRF_NVIC_NVMC_IRQn) \ + | (1U << (uint32_t)SWI4_EGU4_IRQn) \ + | (1U << (uint32_t)SWI5_EGU5_IRQn) \ + )) + #define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0) + + /**@brief Interrupts available for to application. */ + #define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0) + #define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1) +#endif +/**@} */ + +/**@} */ + +/**@addtogroup NRF_NVIC_VARIABLES Variables + * @{ */ + +/**@brief Type representing the state struct for the SoftDevice NVIC module. */ +typedef struct +{ + uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */ + uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */ +} nrf_nvic_state_t; + +/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an + * application source file. */ +extern nrf_nvic_state_t nrf_nvic_state; + +/**@} */ + +/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions + * @{ */ + +/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts. + * + * @retval The value of PRIMASK prior to disabling the interrupts. + */ +static inline int __sd_nvic_irq_disable(void) +{ + int pm = __get_PRIMASK(); + __disable_irq(); + return pm; +} + +/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts. + */ +static inline void __sd_nvic_irq_enable(void) +{ + __enable_irq(); +} + +/**@brief Checks if IRQn is available to application + * @param[in] IRQn irq to check + * + * @retval 1 (true) if the irq to check is available to the application + */ +static inline uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn) +{ + if (IRQn < 32) + { + return ((1UL<= (1 << __NVIC_PRIO_BITS)) + { + return 0; + } +#ifdef NRF51 + if( priority == 0 + || priority == 2 + ) + { + return 0; + } +#endif +#if (defined(NRF52) || defined(NRF52840_XXAA)) + if( priority == 0 + || priority == 1 + || priority == 4 + || priority == 5 + ) + { + return 0; + } +#endif + return 1; +} + +/**@} */ + +/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions + * @{ */ + +/**@brief Enable External Interrupt. + * @note Corresponds to NVIC_EnableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was enabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. + */ +static inline uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn))) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); + } + else + { + NVIC_EnableIRQ(IRQn); + } + return NRF_SUCCESS; +} + +/**@brief Disable External Interrupt. + * @note Corresponds to NVIC_DisableIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt was disabled. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. + */ +static inline uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F)); + } + else + { + NVIC_DisableIRQ(IRQn); + } + + return NRF_SUCCESS; +} + +/**@brief Get Pending Interrupt. + * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. + * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. + * + * @retval ::NRF_SUCCESS The interrupt is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +static inline uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_pending_irq = NVIC_GetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +/**@brief Set Pending Interrupt. + * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt is set pending. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +static inline uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_SetPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +/**@brief Clear Pending Interrupt. + * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. + * + * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + */ +static inline uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + NVIC_ClearPendingIRQ(IRQn); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +/**@brief Set Interrupt Priority. + * @note Corresponds to NVIC_SetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * @pre Priority is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. + * @param[in] priority A valid IRQ priority for use by the application. + * + * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. + */ +static inline uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if (!__sd_nvic_app_accessible_irq(IRQn)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } + + if (!__sd_nvic_is_app_accessible_priority(priority)) + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED; + } + + NVIC_SetPriority(IRQn, (uint32_t)priority); + return NRF_SUCCESS; +} + +/**@brief Get Interrupt Priority. + * @note Corresponds to NVIC_GetPriority in CMSIS. + * + * @pre IRQn is valid and not reserved by the stack. + * + * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. + * @param[out] p_priority Return value from NVIC_GetPriority. + * + * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. + * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. + */ +static inline uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority) +{ + if (__sd_nvic_app_accessible_irq(IRQn)) + { + *p_priority = (NVIC_GetPriority(IRQn) & 0xFF); + return NRF_SUCCESS; + } + else + { + return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE; + } +} + +/**@brief System Reset. + * @note Corresponds to NVIC_SystemReset in CMSIS. + * + * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN + */ +static inline uint32_t sd_nvic_SystemReset(void) +{ + NVIC_SystemReset(); + return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN; +} + +/**@brief Enters critical region. + * + * @post Application interrupts will be disabled. + * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each + * execution context + * @sa sd_nvic_critical_region_exit + * + * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region. + * + * @retval ::NRF_SUCCESS + */ +static inline uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region) +{ + int was_masked = __sd_nvic_irq_disable(); + if (!nrf_nvic_state.__cr_flag) + { + nrf_nvic_state.__cr_flag = 1; + nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 ); + NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0; + #if (defined(NRF52) || defined(NRF52840_XXAA)) + nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 ); + NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1; + #endif + *p_is_nested_critical_region = 0; + } + else + { + *p_is_nested_critical_region = 1; + } + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + return NRF_SUCCESS; +} + +/**@brief Exit critical region. + * + * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. + * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. + * + * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. + * + * @retval ::NRF_SUCCESS + */ +static inline uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region) +{ + if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0)) + { + int was_masked = __sd_nvic_irq_disable(); + NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0]; + #if (defined(NRF52) || defined(NRF52840_XXAA)) + NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1]; + #endif + nrf_nvic_state.__cr_flag = 0; + if (!was_masked) + { + __sd_nvic_irq_enable(); + } + } + + return NRF_SUCCESS; +} +/**@} */ + +#ifdef __cplusplus +} +#endif + +#endif // NRF_NVIC_H__ + +/**@} */ diff --git a/components/softdevice/s132/headers/nrf_sd_def.h b/components/softdevice/s132/headers/nrf_sd_def.h new file mode 100644 index 0000000..4f753ac --- /dev/null +++ b/components/softdevice/s132/headers/nrf_sd_def.h @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SD_DEF_H__ +#define NRF_SD_DEF_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_PPI_CHANNELS_USED 0xFFF0C000uL /**< PPI channels utilized by SotfDevice (not available to the application). */ +#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ +#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ +#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SD_DEF_H__ */ diff --git a/components/softdevice/s132/headers/nrf_sdm.h b/components/softdevice/s132/headers/nrf_sdm.h new file mode 100644 index 0000000..10d9323 --- /dev/null +++ b/components/softdevice/s132/headers/nrf_sdm.h @@ -0,0 +1,331 @@ +/* + * Copyright (c) Nordic Semiconductor ASA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 4. This software must only be used in a processor manufactured by Nordic + * Semiconductor ASA, or in a processor manufactured by a third party that + * is used in combination with a processor manufactured by Nordic Semiconductor. + * + * + * 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 HOLDER 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. + * + */ +/** + @defgroup nrf_sdm_api SoftDevice Manager API + @{ + + @brief APIs for SoftDevice management. + +*/ + +#ifndef NRF_SDM_H__ +#define NRF_SDM_H__ + +#include "nrf_svc.h" +#include "nrf.h" +#include "nrf_soc.h" +#include "nrf_error_sdm.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ +#ifdef NRFSOC_DOXYGEN +/// Declared in nrf_mbr.h +#define MBR_SIZE 0 +#warning test +#endif + +/** @brief The major version for the SoftDevice binary distributed with this header file. */ +#define SD_MAJOR_VERSION (3) + +/** @brief The minor version for the SoftDevice binary distributed with this header file. */ +#define SD_MINOR_VERSION (0) + +/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */ +#define SD_BUGFIX_VERSION (0) + +/** @brief The full version number for the SoftDevice binary this header file was distributed + * with, as a decimal number in the form Mmmmbbb, where: + * - M is major version (one or more digits) + * - mmm is minor version (three digits) + * - bbb is bugfix version (three digits). */ +#define SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION) + +/** @brief SoftDevice Manager SVC Base number. */ +#define SDM_SVC_BASE 0x10 + +/** @brief Invalid info field. Returned when an info field does not exist. */ +#define SDM_INFO_FIELD_INVALID (0) + +/** @brief Defines the SoftDevice Information Structure location (address) as an offset from +the start of the softdevice (without MBR)*/ +#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) + +/** @brief Defines the absolute SoftDevice Information Structure location (address) when the + * SoftDevice is installed just above the MBR (the usual case). */ +#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) + +/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the + * SoftDevice base address. The size value is of type uint8_t. */ +#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET) + +/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address. + * The size value is of type uint32_t. */ +#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) + +/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value + * is of type uint16_t. */ +#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) + +/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID + * is of type uint32_t. */ +#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10) + +/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in + * the same format as @ref SD_VERSION, stored as an uint32_t. */ +#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14) + +/** @brief Defines a macro for retreiving the actual SoftDevice Information Structure size value + * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is + * installed just above the MBR (the usual case). */ +#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET))) + +/** @brief Defines a macro for retreiving the actual SoftDevice size value from a given base + * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above + * the MBR (the usual case). */ +#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) + +/** @brief Defines a macro for retreiving the actual FWID value from a given base address. Use @ref + * MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual + * case). */ +#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET))) + +/** @brief Defines a macro for retreiving the actual SoftDevice ID from a given base address. Use + * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the + * usual case). */ +#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/** @brief Defines a macro for retreiving the actual FWID value from a given base address. Use @ref + * MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual + * case). */ +#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \ + ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID) + +/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges + * @{ */ +#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */ +#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */ +/**@} */ + +/**@defgroup NRF_FAULT_IDS Fault ID types + * @{ */ +#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter will be set to 0x00000000. */ +#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access (nRF52 only). The info parameter will contain 0x00000000, in case of SoftDevice RAM + access violation. In case of SoftDevice peripheral register violation the info parameter will contain the sub-region number of PREGION[0], on whose address range the unallowed + write access caused the memory access fault. */ +/**@} */ + +/** @} */ + +/** @addtogroup NRF_SDM_ENUMS Enumerations + * @{ */ + +/**@brief nRF SoftDevice Manager API SVC numbers. */ +enum NRF_SD_SVCS +{ + SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ + SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ + SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ + SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ + SVC_SDM_LAST /**< Placeholder for last SDM SVC */ +}; + +/** @} */ + +/** @addtogroup NRF_SDM_DEFINES Defines + * @{ */ + +/**@defgroup NRF_CLOCK_LF_XTAL_ACCURACY Clock accuracy + * @{ */ + +#define NRF_CLOCK_LF_XTAL_ACCURACY_250_PPM (0) /**< Default: 250 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_500_PPM (1) /**< 500 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_150_PPM (2) /**< 150 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_100_PPM (3) /**< 100 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_75_PPM (4) /**< 75 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_50_PPM (5) /**< 50 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_30_PPM (6) /**< 30 ppm */ +#define NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM (7) /**< 20 ppm */ + +/** @} */ + +/**@defgroup NRF_CLOCK_LF_SRC Possible lfclk oscillator sources + * @{ */ + +#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */ +#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */ +#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */ + +/** @} */ + +/** @} */ + +/** @addtogroup NRF_SDM_TYPES Types + * @{ */ + +/**@brief Type representing lfclk oscillator source. */ +typedef struct +{ + uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */ + uint8_t rc_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second + units (nRF51: 1-64, nRF52: 1-32). + @note To avoid excessive clock drift, 0.5 degrees Celsius is the + maximum temperature change allowed in one calibration timer + interval. The interval should be selected to ensure this. + + @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. */ + uint8_t rc_temp_ctiv; /**< Only for NRF_CLOCK_LF_SRC_RC: How often (in number of calibration + intervals) the RC oscillator shall be calibrated if the temperature + hasn't changed. + 0: Always calibrate even if the temperature hasn't changed. + 1: Only calibrate if the temperature has changed (nRF51 only). + 2-33: Check the temperature and only calibrate if it has changed, + however calibration will take place every rc_temp_ctiv + intervals in any case. + + @note Must be 0 if source is not NRF_CLOCK_LF_SRC_RC. + + @note For nRF52, the application must ensure calibration at least once + every 8 seconds to ensure +/-250ppm clock stability. The + recommended configuration for NRF_CLOCK_LF_SRC_RC on nRF52 is + rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at + least once every 8 seconds and for temperature changes of 0.5 + degrees Celsius every 4 seconds. See the Product Specification + for the nRF52 device being used for more information.*/ + uint8_t xtal_accuracy; /**< External crystal clock accuracy used in the LL to compute timing windows. + + @note For the NRF_CLOCK_LF_SRC_RC clock source this parameter is ignored. */ +} nrf_clock_lf_cfg_t; + +/**@brief Fault Handler type. + * + * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back. + * The protocol stack will be in an undefined state when this happens and the only way to recover will be to + * perform a reset, using e.g. CMSIS NVIC_SystemReset(). + * + * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback. + * + * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS. + * @param[in] pc The program counter of the instruction that triggered the fault. + * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details. + * + * @note When id is set to NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when + * the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault. + */ +typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info); + +/** @} */ + +/** @addtogroup NRF_SDM_FUNCTIONS Functions + * @{ */ + +/**@brief Enables the SoftDevice and by extension the protocol stack. + * + * @note Some care must be taken if a low frequency clock source is already running when calling this function: + * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new + * clock source will be started. + * + * @note This function has no effect when returning with an error. + * + * @post If return code is ::NRF_SUCCESS + * - SoC library and protocol stack APIs are made available. + * - A portion of RAM will be unavailable (see relevant SDS documentation). + * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). + * - Interrupts will not arrive from protected peripherals or interrupts. + * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice. + * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). + * - Chosen low frequency clock source will be running. + * + * @param p_clock_lf_cfg Low frequency clock source and accuracy. + If NULL the clock will be configured as an rc source with rc_ctiv = 16 and .rc_temp_ctiv = 2 + In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock. + * @param fault_handler Callback to be invoked in case of fault. + * + * @retval ::NRF_SUCCESS + * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated. + * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level. + * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. + */ +SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler)); + + +/**@brief Disables the SoftDevice and by extension the protocol stack. + * + * Idempotent function to disable the SoftDevice. + * + * @post SoC library and protocol stack APIs are made unavailable. + * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). + * @post All peripherals used by the SoftDevice will be reset to default values. + * @post All of RAM become available. + * @post All interrupts are forwarded to the application. + * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); + +/**@brief Check if the SoftDevice is enabled. + * + * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); + +/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice + * + * This function is only intended to be called when a bootloader is enabled. + * + * @param[in] address The base address of the interrupt vector table for forwarded interrupts. + + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); + +/** @} */ + +#ifdef __cplusplus +} +#endif +#endif // NRF_SDM_H__ + +/** + @} +*/ diff --git a/components/softdevice/s110/headers/nrf_soc.h b/components/softdevice/s132/headers/nrf_soc.h similarity index 77% rename from components/softdevice/s110/headers/nrf_soc.h rename to components/softdevice/s132/headers/nrf_soc.h index 053c6c5..c9dc40c 100644 --- a/components/softdevice/s110/headers/nrf_soc.h +++ b/components/softdevice/s132/headers/nrf_soc.h @@ -48,14 +48,19 @@ #include #include "nrf_svc.h" #include "nrf.h" + #include "nrf_error_soc.h" +#ifdef __cplusplus +extern "C" { +#endif + /**@addtogroup NRF_SOC_DEFINES Defines * @{ */ /**@brief The number of the lowest SVC number reserved for the SoC library. */ -#define SOC_SVC_BASE (0x20) -#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) +#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */ +#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */ /**@brief Guranteed time for application to process radio inactive notification. */ #define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) @@ -67,11 +72,18 @@ #define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ #define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ +#ifdef NRF51 #define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ #define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */ - #define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ #define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. */ +#endif +#if (defined(NRF52) || defined(NRF52840_XXAA)) +#define SD_EVT_IRQn (SWI2_EGU2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ +#define SD_EVT_IRQHandler (SWI2_EGU2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */ +#define RADIO_NOTIFICATION_IRQn (SWI1_EGU1_IRQn) /**< The radio notification IRQ number. */ +#define RADIO_NOTIFICATION_IRQHandler (SWI1_EGU1_IRQHandler) /**< The radio notification IRQ handler. */ +#endif #define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ #define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ @@ -84,7 +96,7 @@ /**@} */ -/**@addtogroup NRF_SOC_TYPES Types +/**@addtogroup NRF_SOC_ENUMS Enumerations * @{ */ /**@brief The SVC numbers used by the SVC functions in the SoC library. */ @@ -104,19 +116,9 @@ enum NRF_SOC_SVCS SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, SD_MUTEX_ACQUIRE, SD_MUTEX_RELEASE, - SD_NVIC_ENABLEIRQ, - SD_NVIC_DISABLEIRQ, - SD_NVIC_GETPENDINGIRQ, - SD_NVIC_SETPENDINGIRQ, - SD_NVIC_CLEARPENDINGIRQ, - SD_NVIC_SETPRIORITY, - SD_NVIC_GETPRIORITY, - SD_NVIC_SYSTEMRESET, - SD_NVIC_CRITICAL_REGION_ENTER, - SD_NVIC_CRITICAL_REGION_EXIT, - SD_RAND_APPLICATION_POOL_CAPACITY, - SD_RAND_APPLICATION_BYTES_AVAILABLE, - SD_RAND_APPLICATION_GET_VECTOR, + SD_RAND_APPLICATION_POOL_CAPACITY_GET, + SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, + SD_RAND_APPLICATION_VECTOR_GET, SD_POWER_MODE_SET, SD_POWER_SYSTEM_OFF, SD_POWER_RESET_REASON_GET, @@ -136,6 +138,7 @@ enum NRF_SOC_SVCS SD_CLOCK_HFCLK_IS_RUNNING, SD_RADIO_NOTIFICATION_CFG_SET, SD_ECB_BLOCK_ENCRYPT, + SD_ECB_BLOCKS_ENCRYPT, SD_RADIO_SESSION_OPEN, SD_RADIO_SESSION_CLOSE, SD_RADIO_REQUEST, @@ -151,14 +154,7 @@ enum NRF_MUTEX_VALUES NRF_MUTEX_TAKEN }; -/**@brief Possible values of ::nrf_app_irq_priority_t. */ -enum NRF_APP_PRIORITIES -{ - NRF_APP_PRIORITY_HIGH = 1, - NRF_APP_PRIORITY_LOW = 3 -}; - -/**@brief Possible values of ::nrf_power_mode_t. */ +/**@brief Power modes. */ enum NRF_POWER_MODES { NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ @@ -166,7 +162,7 @@ enum NRF_POWER_MODES }; -/**@brief Possible values of ::nrf_power_failure_threshold_t */ +/**@brief Power failure thresholds */ enum NRF_POWER_THRESHOLDS { NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ @@ -176,14 +172,14 @@ enum NRF_POWER_THRESHOLDS }; -/**@brief Possible values of ::nrf_power_dcdc_mode_t. */ +/**@brief DC/DC converter modes. */ enum NRF_POWER_DCDC_MODES { NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ }; -/**@brief Possible values of ::nrf_radio_notification_distance_t. */ +/**@brief Radio notification distances. */ enum NRF_RADIO_NOTIFICATION_DISTANCES { NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ @@ -196,7 +192,7 @@ enum NRF_RADIO_NOTIFICATION_DISTANCES }; -/**@brief Possible values of ::nrf_radio_notification_type_t. */ +/**@brief Radio notification types. */ enum NRF_RADIO_NOTIFICATION_TYPES { NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ @@ -205,49 +201,6 @@ enum NRF_RADIO_NOTIFICATION_TYPES NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ }; -/**@brief SoC Events. */ -enum NRF_SOC_EVTS -{ - NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ - NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ - NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ - NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ - NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ - NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ - NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio signal callback handler return was invalid. */ - NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio session is idle. */ - NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio session is closed. */ - NRF_EVT_NUMBER_OF_EVTS -}; - -/**@} */ - -/**@addtogroup NRF_SOC_TYPES Types - * @{ */ - -/**@brief Represents a mutex for use with the nrf_mutex functions. - * @note Accessing the value directly is not safe, use the mutex functions! - */ -typedef volatile uint8_t nrf_mutex_t; - -/**@brief The interrupt priorities available to the application while the softdevice is active. */ -typedef uint8_t nrf_app_irq_priority_t; - -/**@brief Represents a power mode, used in power mode functions */ -typedef uint8_t nrf_power_mode_t; - -/**@brief Represents a power failure threshold value. */ -typedef uint8_t nrf_power_failure_threshold_t; - -/**@brief Represents a DCDC mode value. */ -typedef uint32_t nrf_power_dcdc_mode_t; - -/**@brief Radio notification distances. */ -typedef uint8_t nrf_radio_notification_distance_t; - -/**@brief Radio notification types. */ -typedef uint8_t nrf_radio_notification_type_t; - /**@brief The Radio signal callback types. */ enum NRF_RADIO_CALLBACK_SIGNAL_TYPE { @@ -274,8 +227,14 @@ enum NRF_RADIO_SIGNAL_CALLBACK_ACTION /**@brief Radio timeslot high frequency clock source configuration. */ enum NRF_RADIO_HFCLK_CFG { - NRF_RADIO_HFCLK_CFG_DEFAULT, /**< Use the currently selected oscillator as HF clock source during the timeslot (i.e. the source is not specified). */ - NRF_RADIO_HFCLK_CFG_FORCE_XTAL, /**< Force external crystal to be used as HF clock source during whole the timeslot. */ + NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the + external crystal for the whole duration of the timeslot. This should be the + preferred option for events that use the radio or require high timing accuracy. */ + NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots. + The RC oscillator may be the clock source in part or for the whole duration of the timeslot. + The RC oscillator's accuracy must therefore be taken into consideration. + @note If the application will use the radio peripheral in timeslots with this configuration, + it must make sure that the crystal is running and stable before starting the radio. */ }; /**@brief Radio timeslot priorities. */ @@ -288,10 +247,36 @@ enum NRF_RADIO_PRIORITY /**@brief Radio timeslot request type. */ enum NRF_RADIO_REQUEST_TYPE { - NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request timeslot as early as possible. This should always be used for the first request in a session. */ - NRF_RADIO_REQ_TYPE_NORMAL /**< Normal timeslot request. */ + NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */ + NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */ +}; + +/**@brief SoC Events. */ +enum NRF_SOC_EVTS +{ + NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ + NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ + NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ + NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ + NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ + NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ + NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */ + NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */ + NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */ + NRF_EVT_NUMBER_OF_EVTS }; +/**@} */ + + +/**@addtogroup NRF_SOC_STRUCTURES Structures + * @{ */ + +/**@brief Represents a mutex for use with the nrf_mutex functions. + * @note Accessing the value directly is not safe, use the mutex functions! + */ +typedef volatile uint8_t nrf_mutex_t; + /**@brief Parameters for a request for a timeslot as early as possible. */ typedef struct { @@ -301,7 +286,7 @@ typedef struct uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ } nrf_radio_request_earliest_t; -/**@brief Parameters for a normal radio request. */ +/**@brief Parameters for a normal radio timeslot request. */ typedef struct { uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ @@ -310,15 +295,15 @@ typedef struct uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ } nrf_radio_request_normal_t; -/**@brief Radio request parameters. */ +/**@brief Radio timeslot request parameters. */ typedef struct { uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ union { - nrf_radio_request_earliest_t earliest; /**< Parameters for a request for a timeslot as early as possible. */ - nrf_radio_request_normal_t normal; /**< Parameters for a normal radio request. */ - } params; + nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */ + nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */ + } params; /**< Parameter union. */ } nrf_radio_request_t; /**@brief Return parameters of the radio timeslot signal callback. */ @@ -333,12 +318,12 @@ typedef struct } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ struct { - uint32_t length_us; /**< Requested extension of the timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ + uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ - } params; + } params; /**< Parameter union. */ } nrf_radio_signal_callback_return_param_t; -/**@brief The radio signal callback type. +/**@brief The radio timeslot signal callback type. * * @note In case of invalid return parameters, the radio timeslot will automatically end * immediately after returning from the signal callback and the @@ -352,14 +337,28 @@ typedef struct */ typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); +/**@brief AES ECB parameter typedefs */ +typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */ +typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */ +typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */ + /**@brief AES ECB data structure */ typedef struct { - uint8_t key[SOC_ECB_KEY_LENGTH]; /**< Encryption key. */ - uint8_t cleartext[SOC_ECB_CLEARTEXT_LENGTH]; /**< Clear Text data. */ - uint8_t ciphertext[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Cipher Text data. */ + soc_ecb_key_t key; /**< Encryption key. */ + soc_ecb_cleartext_t cleartext; /**< Cleartext data. */ + soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */ } nrf_ecb_hal_data_t; +/**@brief AES ECB block. Used to provide multiple blocks in a single call + to @ref sd_ecb_blocks_encrypt.*/ +typedef struct +{ + soc_ecb_key_t* p_key; /**< Pointer to the Encryption key. */ + soc_ecb_cleartext_t* p_cleartext; /**< Pointer to the Cleartext data. */ + soc_ecb_ciphertext_t* p_ciphertext; /**< Pointer to the Ciphertext data. */ +} nrf_ecb_hal_data_block_t; + /**@} */ /**@addtogroup NRF_SOC_FUNCTIONS Functions @@ -390,133 +389,13 @@ SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); */ SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); -/**@brief Enable External Interrupt. - * @note Corresponds to NVIC_EnableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was enabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. - */ -SVCALL(SD_NVIC_ENABLEIRQ, uint32_t, sd_nvic_EnableIRQ(IRQn_Type IRQn)); - -/**@brief Disable External Interrupt. - * @note Corresponds to NVIC_DisableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was disabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - */ -SVCALL(SD_NVIC_DISABLEIRQ, uint32_t, sd_nvic_DisableIRQ(IRQn_Type IRQn)); - -/**@brief Get Pending Interrupt. - * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. - * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. - * - * @retval ::NRF_SUCCESS The interrupt is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_GETPENDINGIRQ, uint32_t, sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)); - -/**@brief Set Pending Interrupt. - * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt is set pending. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_SETPENDINGIRQ, uint32_t, sd_nvic_SetPendingIRQ(IRQn_Type IRQn)); - -/**@brief Clear Pending Interrupt. - * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_CLEARPENDINGIRQ, uint32_t, sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)); - -/**@brief Set Interrupt Priority. - * @note Corresponds to NVIC_SetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * @pre Priority is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. - * @param[in] priority A valid IRQ priority for use by the application. - * - * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. - */ -SVCALL(SD_NVIC_SETPRIORITY, uint32_t, sd_nvic_SetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t priority)); - -/**@brief Get Interrupt Priority. - * @note Corresponds to NVIC_GetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. - * @param[out] p_priority Return value from NVIC_GetPriority. - * - * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. - */ -SVCALL(SD_NVIC_GETPRIORITY, uint32_t, sd_nvic_GetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t * p_priority)); - -/**@brief System Reset. - * @note Corresponds to NVIC_SystemReset in CMSIS. - * - * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN - */ -SVCALL(SD_NVIC_SYSTEMRESET, uint32_t, sd_nvic_SystemReset(void)); - -/**@brief Enters critical region. - * - * @post Application interrupts will be disabled. - * @sa sd_nvic_critical_region_exit - * - * @param[out] p_is_nested_critical_region 1: If in a nested critical region. - * 0: Otherwise. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_NVIC_CRITICAL_REGION_ENTER, uint32_t, sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)); - -/**@brief Exit critical region. - * - * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. - * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. - * - * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_NVIC_CRITICAL_REGION_EXIT, uint32_t, sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)); - /**@brief Query the capacity of the application random pool. * * @param[out] p_pool_capacity The capacity of the pool. * * @retval ::NRF_SUCCESS */ -SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); +SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); /**@brief Get number of random bytes available to the application. * @@ -524,7 +403,7 @@ SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY, uint32_t, sd_rand_application_pool_cap * * @retval ::NRF_SUCCESS */ -SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); +SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); /**@brief Get random bytes from the application pool. * @@ -534,7 +413,7 @@ SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE, uint32_t, sd_rand_application_bytes_ * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. */ -SVCALL(SD_RAND_APPLICATION_GET_VECTOR, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); +SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); /**@brief Gets the reset reason register. * @@ -554,12 +433,12 @@ SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t r /**@brief Sets the power mode when in CPU sleep. * - * @param[in] power_mode The power mode to use when in CPU sleep. @sa sd_app_evt_wait + * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait * * @retval ::NRF_SUCCESS The power mode was set. * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. */ -SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(nrf_power_mode_t power_mode)); +SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode)); /**@brief Puts the chip in System OFF mode. * @@ -580,12 +459,12 @@ SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); /**@brief Sets the power-fail threshold value. * - * @param[in] threshold The power-fail threshold value to use. + * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS. * * @retval ::NRF_SUCCESS The power failure threshold was set. * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. */ -SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(nrf_power_failure_threshold_t threshold)); +SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold)); /**@brief Sets bits in the NRF_POWER->RAMON register. * @@ -611,40 +490,46 @@ SVCALL(SD_POWER_RAMON_CLR, uint32_t, sd_power_ramon_clr(uint32_t ramon)); */ SVCALL(SD_POWER_RAMON_GET, uint32_t, sd_power_ramon_get(uint32_t * p_ramon)); -/**@brief Set bits in the NRF_POWER->GPREGRET register. +/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*). * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. * @param[in] gpregret_msk Bits to be set in the GPREGRET register. * + * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. * @retval ::NRF_SUCCESS */ -SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_msk)); +SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk)); -/**@brief Clear bits in the NRF_POWER->GPREGRET register. +/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*). * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. * + * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. * @retval ::NRF_SUCCESS */ -SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_msk)); +SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk)); -/**@brief Get contents of the NRF_POWER->GPREGRET register. +/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*). * + * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2. * @param[out] p_gpregret Contents of the GPREGRET register. * + * @note nRF51 does only have one general purpose retained register, so gpregret_id must be 0 on nRF51. * @retval ::NRF_SUCCESS */ -SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t *p_gpregret)); +SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret)); /**@brief Sets the DCDC mode. * - * This function is to enable or disable the DCDC periperhal. + * Enable or disable the DCDC peripheral. * - * @param[in] dcdc_mode The mode of the DCDC. + * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES. * * @retval ::NRF_SUCCESS * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. */ -SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(nrf_power_dcdc_mode_t dcdc_mode)); +SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode)); /**@brief Request the high frequency crystal oscillator. * @@ -792,25 +677,30 @@ SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have * to shorten the connection events to have time for the Radio Notification signals. * - * @param[in] type Type of notification signal. + * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES. * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is * recommended (but not required) to be used with * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. * - * @param[in] distance Distance between the notification signal and start of radio activity. + * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES. * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or - * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. + * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. * * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. * @retval ::NRF_SUCCESS */ -SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(nrf_radio_notification_type_t type, nrf_radio_notification_distance_t distance)); +SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance)); /**@brief Encrypts a block according to the specified parameters. * * 128-bit AES encryption. * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input * parameters and one output parameter). * @@ -818,6 +708,23 @@ SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(nr */ SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); +/**@brief Encrypts multiple data blocks provided as an array of data block structures. + * + * @details: Performs 128-bit AES encryption on multiple data blocks + * + * @note: + * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while + * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application + * main or low interrupt level. + * + * @param[in] block_count Count of blocks in the p_data_blocks array. + * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of + * @ref nrf_ecb_hal_data_block_t structures. + * + * @retval ::NRF_SUCCESS + */ +SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks)); + /**@brief Gets any pending events generated by the SoC API. * * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. @@ -834,8 +741,6 @@ SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); * This function will block until the temperature measurement is done. * It takes around 50us from call to return. * - * @note Pan #28 in PAN-028 v 1.6 "Negative measured values are not represented correctly" is corrected by this function. - * * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees celsius. * * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp @@ -860,15 +765,17 @@ SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); * they will not interfere with the flash access. This means that all interrupts will be blocked * for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual * and the command parameters). +* - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS +* or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled. * * * @param[in] p_dst Pointer to start of flash location to be written. * @param[in] p_src Pointer to buffer with data to be written. -* @param[in] size Number of 32-bit words to write. Maximum size is 256 32bit words. +* @param[in] size Number of 32-bit words to write. Maximum size is 256 32-bit words for nRF51 and 1024 for nRF52. * * @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. * @retval ::NRF_ERROR_BUSY The previous command has not yet completed. -* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or more than 256 words. +* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size. * @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location. * @retval ::NRF_SUCCESS The command was accepted. */ @@ -906,19 +813,23 @@ SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)) /**@brief Flash Protection set * - * Commands to set the flash protection registers PROTENSETx + * Commands to set the flash protection configuration registers. + On nRF51 this sets the PROTENSETx registers of the MPU peripheral. + On nRF52 this sets the CONFIGx registers of the BPROT peripheral. * - * @note To read the values in PROTENSETx you can read them directly. They are only write-protected. + * @note To read the values read them directly. They are only write-protected. * - * @param[in] protenset0 Value to be written to PROTENSET0. - * @param[in] protenset1 Value to be written to PROTENSET1. + * @param[in] block_cfg0 Value to be written to the configuration register. + * @param[in] block_cfg1 Value to be written to the configuration register. + * @param[in] block_cfg2 Value to be written to the configuration register (ignored on nRF51). + * @param[in] block_cfg3 Value to be written to the configuration register (ignored on nRF51). * * @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice. - * @retval ::NRF_SUCCESS Values successfully written to PROTENSETx. + * @retval ::NRF_SUCCESS Values successfully written to configuration registers. */ -SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_t protenset1)); +SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t block_cfg0, uint32_t block_cfg1, uint32_t block_cfg2, uint32_t block_cfg3)); -/**@brief Opens a session for radio requests. +/**@brief Opens a session for radio timeslot requests. * * @note Only one session can be open at a time. * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot @@ -940,7 +851,7 @@ SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_ */ SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); -/**@brief Closes a session for radio requests. +/**@brief Closes a session for radio timeslot requests. * * @note Any current radio timeslot will be finished before the session is closed. * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. @@ -956,8 +867,7 @@ SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_ /**@brief Requests a radio timeslot. * * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST - * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type - * @ref NRF_RADIO_REQ_TYPE_EARLIEST. + * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST. * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by * p_request->distance_us and is given relative to the start of the previous timeslot. * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. @@ -988,6 +898,9 @@ SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_ /**@} */ +#ifdef __cplusplus +} +#endif #endif // NRF_SOC_H__ /**@} */ diff --git a/components/softdevice/s110/headers/nrf_svc.h b/components/softdevice/s132/headers/nrf_svc.h similarity index 71% rename from components/softdevice/s110/headers/nrf_svc.h rename to components/softdevice/s132/headers/nrf_svc.h index 8c84a9c..20f7c8d 100644 --- a/components/softdevice/s110/headers/nrf_svc.h +++ b/components/softdevice/s132/headers/nrf_svc.h @@ -37,6 +37,12 @@ #ifndef NRF_SVC__ #define NRF_SVC__ +#include "stdint.h" + +#ifdef __cplusplus +extern "C" { +#endif + #ifdef SVCALL_AS_NORMAL_FUNCTION #define SVCALL(number, return_type, signature) return_type signature #else @@ -45,22 +51,29 @@ #if defined (__CC_ARM) #define SVCALL(number, return_type, signature) return_type __svc(number) signature #elif defined (__GNUC__) -#define SVCALL(number, return_type, signature) \ - _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ - __attribute__((naked)) static return_type signature \ - { \ - __asm( \ - "svc %0\n" \ - "bx r14" : : "I" (number) : "r0" \ - ); \ - } \ +#ifdef __cplusplus +#define GCC_CAST_CPP (uint8_t) +#else +#define GCC_CAST_CPP +#endif +#define SVCALL(number, return_type, signature) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ + __attribute__((naked)) \ + __attribute__((unused)) \ + static return_type signature \ + { \ + __asm( \ + "svc %0\n" \ + "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \ + ); \ + } \ _Pragma("GCC diagnostic pop") + #elif defined (__ICCARM__) #define PRAGMA(x) _Pragma(#x) -#define SVCALL(number, return_type, signature) \ -PRAGMA(swi_number = number) \ +#define SVCALL(number, return_type, signature) \ +PRAGMA(swi_number = (number)) \ __swi return_type signature; #else #define SVCALL(number, return_type, signature) return_type signature @@ -68,4 +81,8 @@ PRAGMA(swi_number = number) \ #endif // SVCALL #endif // SVCALL_AS_NORMAL_FUNCTION + +#ifdef __cplusplus +} +#endif #endif // NRF_SVC__ diff --git a/components/softdevice/s132/hex/s132_nrf52_3.0.0_licence-agreement.txt b/components/softdevice/s132/hex/s132_nrf52_3.0.0_licence-agreement.txt new file mode 100644 index 0000000..09a78bb --- /dev/null +++ b/components/softdevice/s132/hex/s132_nrf52_3.0.0_licence-agreement.txt @@ -0,0 +1,96 @@ +S110/S120/S130/S132 license agreement + + +NORDIC SEMICONDUCTOR ASA SOFTDEVICE LICENSE AGREEMENT + +License Agreement for the Nordic Semiconductor ASA ("Nordic") S110, S120, S130 and S132 Bluetooth SoftDevice software packages +("SoftDevice"). + +You ("You" "Licensee") must carefully and thoroughly read this License Agreement ("Agreement"), and accept to adhere to this Agreement before +downloading, installing and/or using any software or content in the SoftDevice provided herewith. + +YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS +OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE SOFTDEVICE, IN THIS CASE YOU AGREE THAT THE USE OF +THE SOFTDEVICE CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. + +IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE +INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE SOFTDEVICE. + +1. Grant of License +Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license +("License"): (a) to use the SoftDevice solely in connection with a Nordic integrated circuit, and (b) to distribute the SoftDevice solely as integrated +in Licensee Product. Licensee shall not use the SoftDevice for any purpose other than specifically authorized herein. It is a material breach of this +agreement to use or modify the SoftDevice for use on any wireless connectivity integrated circuit other than a Nordic integrated circuit. + +2. Title +Nordic retains full rights, title, and ownership to the SoftDevice and any and all patents, copyrights, trade secrets, trade names, trademarks, and +other intellectual property rights in and to the SoftDevice. + +3. No Modifications or Reverse Engineering +Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code +parts of the SoftDevice including, but not limited to pre-compiled hex files, binaries and object code. + +4. Distribution Restrictions +Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the SoftDevice to any third party. +Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the SoftDevice as proscribed herein. +Licensee also agrees that use of and access to the SoftDevice will be strictly limited to the employees and subcontractors of the Licensee +necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making +such employees and subcontractors comply with the obligations concerning use and non-disclosure of the SoftDevice. + +5. No Other Rights +Licensee shall use the SoftDevice only in compliance with this Agreement and shall refrain from using the SoftDevice in any way that may be +contrary to this Agreement. + +6. Fees +Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to +comply with the Agreement. + +7. DISCLAIMER OF WARRANTY +THE SOFTDEVICE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS +LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR +THAT THE SOFTDEVICE WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. THERE +IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE SOFTDEVICE WILL MEET THE +REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE SOFTDEVICE WILL BE UNINTERRUPTED OR ERROR-FREE. +LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE SOFTDEVICE TO ACHIEVE LICENSEE’S +INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. + + +8. No Support +Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, +bug-fixes or support. Nordic reserves the right to make changes to the SoftDevice without further notice. + +9. Limitation of Liability +In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of +procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any +special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, +tort, negligence, or other theory of liability arising out of the use of or inability to use the SoftDevice, even if Nordic or its employees or suppliers, +licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the exclusion or +limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be limited to +USD 50. + +10. Breach of Contract +Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably +attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both +direct and indirect costs for Nordic and its licensors. + +11. Indemnity +Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and +agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which +is not due to causes for which Nordic is responsible. + +12. Governing Law +This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. + +13. Assignment +Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. + +14. Termination +Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this +Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any +other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. + +15. Third party beneficiaries +Nordic’s licensors are intended third party beneficiaries under this Agreement. + + diff --git a/components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld b/components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld new file mode 100644 index 0000000..37ea952 --- /dev/null +++ b/components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld @@ -0,0 +1,28 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000 + RAM (rwx) : ORIGIN = 0x200019c0, LENGTH = 0xe640 +} + +SECTIONS +{ + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM + .pwr_mgmt_data : + { + PROVIDE(__start_pwr_mgmt_data = .); + KEEP(*(.pwr_mgmt_data)) + PROVIDE(__stop_pwr_mgmt_data = .); + } > RAM +} INSERT AFTER .data; + +INCLUDE "nrf5x_common.ld" diff --git a/components/softdevice/s110/toolchain/iar/iar_s110_nrf51422_xxac.icf b/components/softdevice/s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf similarity index 74% rename from components/softdevice/s110/toolchain/iar/iar_s110_nrf51422_xxac.icf rename to components/softdevice/s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf index 028107f..8d6c9e8 100644 --- a/components/softdevice/s110/toolchain/iar/iar_s110_nrf51422_xxac.icf +++ b/components/softdevice/s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf @@ -2,12 +2,14 @@ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x18000; +define symbol __ICFEDIT_intvec_start__ = 0x1f000; /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x18000; -define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002000; -define symbol __ICFEDIT_region_RAM_end__ = 0x20007fff; +define symbol __ICFEDIT_region_ROM_start__ = 0x1f000; +define symbol __ICFEDIT_region_ROM_end__ = 0x7ffff; +define symbol __ICFEDIT_region_RAM_start__ = 0x200019c0; +define symbol __ICFEDIT_region_RAM_end__ = 0x2000ffff; +export symbol __ICFEDIT_region_RAM_start__; +export symbol __ICFEDIT_region_RAM_end__; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x200; @@ -29,3 +31,4 @@ place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; + diff --git a/components/softdevice/s210/doc/s210_nrf51422_5.0.0_licence_agreement.pdf b/components/softdevice/s210/doc/s210_nrf51422_5.0.0_licence_agreement.pdf deleted file mode 100644 index 61f64d3824ed1122550d40e296fc139bda42b74c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7025 zcmc&(XF!un)>aV^klw42UQHn+fQZt2@4bXj1HmLf00C*zk&aa9f^?|@f&wB6Qbh!$ z2uSZ$6y*!|-rc*qcXz)Z-;Zzp%sb~j^UTbdGjE6mLEC#*-CFh%87#t;s0zd$? zy(>UQ2B?YjaKbqQATXE|P}v2ALt=o+C_5Zd5s5%MAZ2B-I1JLxogAP2!t5<(N|o-# zzKHPmqWC;19&f(B2g>;Z6MC>T9E)yZXU^`(j(*3qOC(G&2* z{fh$}Whu(pdgwjTGaP(mm?C@~9;Kfj{mf>%`f@59qd3b(^%xa~wP+kG^QJAFNS({6 zdb02qB}H3E9rJe45rTE|S)-gxL+l%m6UXY2DO4;dI#}>I-ko>T5j84(A-RVIc0~+h zc(;JRAhW;P&x{y!KdaQnj%QSJ)jU?+ZBCD(ySW;W%&w&2%q^CXc-FPK9(+7?O81hC zEaqXC?`Yq;n%DyvqGoMy)w}ZIH7xUTJzdZ*ri8O=bdbF;E&~ML((2-@m+>V;v+}tz5}{psHh79qhsy>kDB(u1bzO^(+G$?ESBjA4@rk3W?$Si% z?iJqf4#vV={N4oP)|=J6;_c|Zo6b&`H{*9VM{!5_*|%*TnRVuz*}5CtJCQWg{N{E` zFzo3xLU(^~3nxqeY0nWC{_~eqruD<#98bCn9fgJ4z#GA2bIOQgZ(KltfJge}fuEA# z@2@yUbPP0|NM`VtQKHpyKkqK?ZCJGBc2vI^XERrz-x?gGSvWzhYEN7EJQJ-K&x~_1 zk$t%mE@9$w_|rZR0l1f|1I`_6k7Y9H^PBRD@P2DGdMr9HX4${AHO!Pwe^;u5m{m>+ z*LKtFvnVB#^OtVPZ;~P=Ht#$7tCkBz^v6fSWoP4;;g72Ywu-ohU)Hv`hxS%*)}AbF zXB7cTgP^VS*z86c8)cuG)hGI^z>3$};S(nNyJEr6n_~Q*Fc>69rMWKk)kO!-;g3$G zOuPtora+k-REPBQ={mn2EBEzXJ()mNUT&y$`i6c`_N^LerC+@!HmT{XAr}Wrc{R0a z9zWAk8)la-vj;nfE>`I}y+cO}#?O>)TVG)F)pdMi=iOo)Wl8)x3u?nSG0>**L1AMU zkwLVc&%+dbk9bM+{(X3mf~k5K-(v5pYDN>mYQ#NWI(z=D+|4Se_sC$p2V$`C*zY{-@90w zEsSUJx&1;NtG6kR#uNEUdg+8Lxx*&u#E5F;XZ9NxA8lwE`5Lg1m3Dp_U+-Fv^i}VE zc`U6LtUmhAn_8O3B2D?Jifm0~)h@oeW;u#37ylAxd96B!YrfUrvCUhWvyWx!i>H?t zQ}!1gs)Dw`KJv$5>d=ruMfL2W#oeJbj|ez}f@hZ^lCDZ#DN^;oF{@ZBarkbJiQa`$ z-sv?f)-4@{Fp-D7hQLLgn`&j(EbzNqy6)+!XIBrrXV+MWi{BAdV2UFhO5e!|CZk<0 z##PEOQC?z^jQH_#&__5p=lw7Pk)_FtOVh#&jd_WN8}nh@G7>XB+13x+Bx{7`r&Y%*t*en64bEN1sgZ`fFKPrIiga>_6IiP5lmPk z88Q5}Et~sc_4?hWSE9=Pi&?!8a3VJ8QT+&P7#2y8E+xBq+ra{F# z8P1Ayt-(TcS3a=98vKoCrAA8zXudc)S9QT&2#*SWT@Ej}xV%<>WJ%io0g^3#GVqgr z1#I-Wry%DGZ;L2hhuETUiFEh}qY0T5Qe)}~p-8O<(j{InTBJTz#kHqdnT;!+>a2&t z*zZ?}mdl7REt+vr&4UFnNF2|Nbeb2w@=`QQ`wkv$v!?sO5ENGquk#we!7oe4F%v2N z;!u6+POfCXTYI_ghq)K2N1Ek3Qq6oFCO)wV0xxbzFtmoCP_WF&Qi zY>e7=g@>|2V6{C4YKpUOjqB<4^k_+Z_gda$f8n6|R_1eqzTVGxJi&}vbLR@l@oTZU zQxjfW>X!mt<2+IKc8jM{<#ckHNo9xIPAnRMWDRiHBz$LF{CDk!@cAh8JGoa3hE`be zj*cP0H}8avRSuhfD3lwed@O0_+Zr2I;E+kMx^hf^Tc*XzAn(B;5kEfrBSXsL;uAXc zchj`K82VsF0Zdnhu)%Bn9rYAW&dJE&Sdt?+@Z;f-zk-|XGp7{);3U=9nY0`G4nswp zCel>%l$5Wn)%N^GbTU#EBZ-8TYt-J64cSG0ATI^ACnif*U76x+c&FH!mP-}elJMyI zHTs`=QBHGcvs(-J6^O$tNe(OG%q4I{^o!>Y7tU7WH^NfjYO$Ym-n&+v_It5yUVgc) zx;7#<#82yL&&ha#Cim^JSjnLXNUP-X8^2LKs#&~rQ7&yL!^mRL3o*ufL7eTLp(td+ zQx^2%x-{p%2bz)dmya^^6a2n$K54^?NPl>& zdY8L~#iX0Wr~^w4wO3Lc6Ni}k zoV^e#yXRvf+7`&x1jp5z(u{)FuBys6#fJiBl2uq;E-p8zfCo&T36P@mce|t7T2Tt5IO4yUSsLgHm4A9YkZ7VoaR^>h50_kfnoqER==66b-GrX z|B7Z^i2~M6JBV+$y+8yXy>Sit5LX9$f!1qNp>5OSH{j5XeC(iR?mANXHebNiPbtrD zsIuxS%Xkp~O-9lklLjK7Ahw#c*TomEQo3qF7f}B)crLx?NwJ+`y6}NZjHdBX4>Zs( zxJHR(w}E_pljBnt*UzKZ9?udF*gI=K1|UwSDT=6c$gpwNWbOCmxxaR>ZJF&zgmCM! z7lnJJJ|4yvp(ND6k4TG8zar_{GP?uHQp{IEttVV^ORMv8&dLTK@0RzzT+5jPd0C{n zuYI(hAR3f9W&Rw`yuNBOFw1^+(Y>Zgf*k4L@CWZCJQ0X0Irw+NO5m%yb{M1w4j@4= z=mQnd9yme^3pgjV`anZpPb9&?2?^9kV$oh01QL7R1A|5wAaMW-Ab|t}fQCps4ggeh zC%DP~Q7imWt62e+35bL~%3uKGH%Mg&K>YkcmQa9NNCy`?c{JVvL@>d?5CB{XVkIkk zKHc+4!U)!XVbx%9$bV4Rm`?*_{bsm+JD>PMc67OKS+$pSjohO=(eft9aX0+LV4GdIWEKeUgtwGD4H zPUJg2JDdN~lsRmhJb4y~t}&_{LrfdTY`Si0Ygj3*Jsn%1Z0T7j*Z6tQ;)i*RUBs_q z_Q{=vUI(k0ZSf#0@ecu^!x(z_RR8SQuUl#Pk>b})8z~DS88d88jBB2g3CgwE@AKbC zl9Yz9)`2EAd04yiZAmlGwfc_zlST3yirM9dlbXUGUG6h~ba@u4#fqM(iC&hw=MXU$ z86o%U+8O)qUXU*Ptr-c%HO?6`^0}yesOoOu9yvvI<45NmZw)j5=hmpUhUQUm-@=Jr_iVtDmlo&%(u(-{p867{Wprc|T3xO9-Fx^=9mZ#U z){68Y;`nZz^^06IST1&{c8v?li>z5@x!YHn5PgWcaCp|hW^00%mPg9<`g=#ml7U`5 zi12~CDqKUZuBR$**q@3$-WexV0W50rRRs*PP15)MsBq4DdS%UNOx?prbLQqcxim)5 zl6hE0CeIj>R^ij39#8bztER!;)soROCJN?D# z7dT?T&D?!YUU2$s5fv7c4lrRYxiNZ9i zh~9w#F2yTp%h129PSk99g}-0`L+gQHB^llfxjnzQW0%EIgR`(U;@M{VJj5Ut^FE^C zG`NT4e#TLD-N<7@2kw9yS=Pevsq8x<@FDR9%3EqPEb!7`KBd5;D@8Ad*M=G<`M0x< zA5@Y3T$i?k8gBGp1h7gJUWc_;(;!JFwSE?bU0OMl+E;5dWej-6_fty>26$VZ-|^Ru zpO-i0RmvPQE9!hyv=&%njj#y2UHF{LgkfFc)}7cw-aeNh(=JQSQ~Sb8weLez=Z=MY zi6FH0jHt@;M0lQ;7E9~{rKc)1_{WTWqUpYg6pd<0smigomxN%Q^S4McdAvUpvtM{w zEgF^D*v`00yVdhtb<{q{9;;SZ+}k_B+gG)1*_Y@oWL4Qcv*Gic%BGPy|0?%4paJbt z{mED1ZdIn`14CO9E$_(J6jRK#{a?kwPiDs|uBWy$n`*)9onFSoUU-k^u${MF-9?F{ z+z2&%8f+Hl^EEQYsyzQ#SE7a7KmJ}>ohd3|@6xDWP6F>c>0i7okK~MSN%Ouc@2F(* zKICs-u;fqq_5|7c6n>j}O+8byN{3Y){esR>;=9LVc*E!IA&@IIh4Elgvk2{W{sl8` zBYlb{ffgx$nrLT+D$W22hB?FN4MbXU!$X?%{tK3a1LcZi8bxLpK%dVYw5NiO{=5o{ zT(CKISZnF=YL!BfR3VV%#cMt)fGMAVHN8ku#u4{bNK${R)ESl9?P}5Wr?qWe>Dr;| z+u3v^!RGxD71O0vDeu$XwjRTtmrTr;cwipn3x8D*zSK-nMN+&{?t{Xuus@0wJ(`oU z?W;>PSgQHDyVSbcT{Hqr^qto!i>8x!SU+2QPmso0y4NL@%Mk3vH)OP2lPatVCZ=vR zcx$daR@}4UgV(8JTpZ#t%x~hWDQ2(E!!A{zJ1#a|OuAmgJa#<6&!?E)Euh5Vz)%?z zx#>WnZcJ=c!_IEbVJCm+93`w5*Easuy)r53iW1W7TA#8U<1uGJovTnrj%>&A!sjqp z-{{pYLv@UtB>VSOPZi;fSi7t5Y2-^WX5FZK-f6Lc?X zB*fh9z+ec0|wuq;4;bG8}S?CEm3E~&Vi60?Iv!|z5M?>ME58_dokGlqJ~?^priA(O!o#V~ z!pus@!FQQj4xO>s>dW^6x|KFoXjh@1%7p-_MVW?6&m#|aidA&P@?DkvIA=CK``d^6 zOV2A??0$*CMfgTtNCS=vZKqG#AV~}||4N?Vzw?s+NS@Al%l|uhlKcyKg2G_`ojb)P z4|;q6(e!KwMoWblW}MD0n(|5l?mT7qKr}xWC%|4!ce8=>X&Z@7f(mkjxFsd664Tqe z|GpnBE8w%?-beRIg0(*Bh1&#WD}qdC&x-6=G?Y3;<{30tXJftTGOvj1Cq`n;ii&8K zIIys5ZrGy{r!PXcYb;92bnqM3uio324dq0$Is2#e>@$SORO8JQZq}MKy`y&A1zE`4 z(D%ABbAL#L<#rx%IaR2S$nj7 zv~!}g_0$D#pt!YZnJp_+Wnc}}%Qn6@W$Q+YPJ&UjQ>Ym!3;!?##*S$&l$w{J=Y z-sXtCONw~Q!45kv4fXmp0jBu6Sx9|AY{AT@vli48Xr67<=JAUz;@bBIKQDWH=QjOo z=1To9nR}iz|L>U#{);#PpX&pCpdu2Bvp9dL4>UD1C)98#L8n*&4P9_3q@V!=3<4U6 z6MRuF2&4xV39xg*Ad&6_JtOp|ruYqtASwul_cwK;ElI^L13V!9hOl2 zK8msn=I@O^AyKQ zME@Uj7(tl*Q+EYBoE-}71pHg<0DtVyIjk1pk^^XjMgHyGZ}JiQyS)5!nczRyNl=px zUI-*c(B(HF3Aq8fAqlV)wD$#|&^~rfF31}Qw7aE{5RibZNVrE4RFsB*z)+AlNE{4- zNP@*hKwtq7NI(dvK)6`Jxu8A%tJj}%z+;e(!5)J}M!o($!4p2uZMBH8+ v1c6D)S^?EO9MOQ^azP(x;NpiQYzAR}usAym?zi26Nk~bM^YJO^D3kvW&G;@` diff --git a/components/softdevice/s210/doc/s210_nrf51422_5.0.0_licence_agreement.txt b/components/softdevice/s210/doc/s210_nrf51422_5.0.0_licence_agreement.txt deleted file mode 100644 index e88fb31..0000000 --- a/components/softdevice/s210/doc/s210_nrf51422_5.0.0_licence_agreement.txt +++ /dev/null @@ -1,110 +0,0 @@ -S210/S310 license agreement - -S210 AND S310 LICENSE AGREEMENT - -License Agreement for the Nordic Semiconductor ASA (“Nordic”) S210 ANT Softdevice software package (“S210”) and the Nordic Semiconductor -ASA S310 ANT and BLE Softdevice software package (“S310”). - -You (“You” or “Licensee”) must carefully and thoroughly read this License Agreement (“Agreement”), and accept to adhere to this Agreement -before downloading, installing and/or using any software or content in the S210 or S310 provided herewith. - -YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS -OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE S210 OR S310, IN THIS CASE YOU AGREE THAT THE USE OF -THE S210 OR S310 CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. - -IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE -INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE S210 OR S310 OR ANY DOCUMENTATION RELATED TO THE S210 OR -S310. - -1. Grant of License -Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license -(“License”): (a) to use the S210 and S310 solely in connection with the nRF51422 Nordic Integrated Circuit (“nRF51422 IC”), and (b) to distribute -the S210 or S310 solely as implemented in Licensee products. Licensee shall not use the S210 or S310 for any purpose other than specifically -authorized herein. It is a material breach of this agreement to use or modify the S210 or S310 for use on any wireless connectivity integrated -circuit other than the nRF51422 IC. - -2. Title -Nordic or its licensors (as applicable) retain full rights, title, and ownership to the S210 and S310 and any and all patents, copyrights, trade -secrets, trade names, trademarks, and other intellectual property rights in and to the S210 and S310. Nordic licenses portions of the S210 and -S310 from third party licensors, and such licensors retain their respective full rights, title, and ownership in and of the S210 and S310 and any and -all patents, copyrights, trade secrets, trade names, trademarks, and other intellectual property rights in and to the S210 and S310. - -3. No Modifications or Reverse Engineering -Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code -parts of the S210 and S310 including, but not limited to pre-compiled hex files, binaries and object code. - -4. Distribution Restrictions -Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the S210 and S310 to any third party. -Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the S210 and S310 as proscribed herein. -Licensee also agrees that use of and access to the S210 and S310 will be strictly limited to the employees and subcontractors of the Licensee -necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making -such employees and subcontractors agree on complying with the obligations concerning use and non-disclosure of the S210 and S310. - -5. End Use Restrictions -Licensee agrees that the S210 and S310 may not be sold, resold, transferred, diverted, exported, re-exported or disposed of (i) for use in -activities involving the development, production, handling, use, operation, maintenance, storage, detection, identification or dissemination of -nuclear, chemical, or biological weapons (including missiles and weapons of mass destruction), nor for use in any facilities engaged in activities -related to such weapons, including where there are reasonable grounds to suspect any such use; (ii) for a military end-use in China or in any -other country subject to any applicable arms embargo or for an item designed, modified, configured, or adapted for a military application in China -or any other country subject to an applicable arms embargo; (iii) to or for the benefit of individuals or entities listed on any applicable restricted or -prohibited party lists; or (iv) to the following countries: Cuba, Iran, North Korea, Sudan, and Syria. Licensee further agree to abide by all other -applicable export controls, trade sanctions and embargo laws, regulations, rules and licenses ("Export Controls and Sanctions Rules") in force -from time to time as they relate to the S210 and S310. You acknowledge that your obligation to comply with applicable Export Controls and -Sanctions Rules is independent of these terms and conditions and you agree to indemnify and hold Nordic and its licensors harmless from and -against any third-party claim, including fines, losses, liabilities or legal fees that arise as a result of the breach by you of these terms and -conditions or any applicable export controls, trade sanctions and embargo laws, regulations, rules and licenses. - -6. No Other Rights -Licensee shall use the S210 and S310 only in compliance with this Agreement and shall refrain from using the S210 and S310 in any way that -may be contrary to this Agreement. - -7. Fees -Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to -comply with the Agreement. - -8. DISCLAIMER OF WARRANTY -THE S210 AND S310 ARE PROVIDED “AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS -LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR -THAT THE S210 AND S310 WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. -THERE IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE S210 AND S310 WILL -MEET THE REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE S210 AND S310 WILL BE UNINTERRUPTED OR -ERROR-FREE. LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE S210 AND S310 TO ACHIEVE -LICENSEE’S INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. - -9. No Support -Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, -bug-fixes or support. Nordic reserves the right to make changes to the S210 and S310 without further notice. - -10. Limitation of Liability -In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of -procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any -special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, -tort, negligence, or other theory of liability arising out of the use of or inability to use the S210 and S310, even if Nordic or its employees or -suppliers, licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the -exclusion or limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be -limited to USD 50. - -11. Breach of Contract -Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably -attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both -direct and indirect costs for Nordic and its licensors. - -12. Indemnity -Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and -agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which -is not due to causes for which Nordic is responsible. - -13. Governing Law -This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. - -14. Assignment -Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. - -15. Termination -Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this -Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any -other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. - -16. Third party beneficiaries -Nordic’s licensors are intended third party beneficiaries under this Agreement. \ No newline at end of file diff --git a/components/softdevice/s210/doc/s210_nrf51422_5.0.0_migration_document.pdf b/components/softdevice/s210/doc/s210_nrf51422_5.0.0_migration_document.pdf deleted file mode 100644 index e752835069a30dd6ff8dbe6ebcdcd40b11bac070..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 637984 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�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 z zS0ZtAsVOw_cO^^9La$OgMv0P9Xykbu=O>nP971o5Jj%r%GP#6bl)1GSc@&#J7;mp{ z3cqH$0z*M`3d8c~gN=IKDd<--w_+Qhb|6Kvui%QDFMJfse1^Tv9tR2foYZ156=sO2`@Z*8;hTpwOyGPR5F2ahbg_g z))i(OT+(wGq@$4w-UguCjKf6vD$_B&m`;D7j%3zyRxn^JLzrwolRR{ArmtZYgrG>e zyD?$4`ug}Njhq15^QrGvN)J4onG-GKiiyK+=WQ}_E2me}NyZf)%C$zm6*&>oD{s&T z9cy7@dm+UZHS=Y^&Pq?IwW`6hS%_fQ=K)uSFrxQ6g+y9(gS;n>RLF z)zh6EJgL{^qAIz%v(T0ERvYV#JX)9*Rg+Va@y|SAH;!a*8>V@`ZdZ@n3ip|;t?Sm) z%h9LK)b=sSV1x&8#?ssiDVR^65YH#26D1BGQh3}w!|nVMR-QXfjSG#LkAagftFzw( z1NvJ8Q9ZB+6k2*}QVMP}_6v)c4=*nF?94qVlblZLf{N|K*9xkN z)t8r6JYU^se|dTE@h+`;RkzAkAr$fqMQT%`GKa2QD%NPGX{fKe)O$a`%#wI(c5!&L z*0nTp^J(FYH%B_E5%J0O+qGMmTDUn~o(<+vz+`njjNYsfjH%FdvM+7AUZ}ZS4R)2H zFmSoqPH5|heEPg+2vf#(R3~wdf5PqR<#IC+cK-St^~Ul7`6lw_a$AS7$-xQwqH$ea zBh!4YGQn=-A&r0+z#}R*B!v-Fx@c@gyXjutQP=c#@)N|DIJnk!+*x#O>}t9`*jmW| z4(==s^AFksT1wh*fNhB*h!NUVo0{q^T{R6I*AFAFv-pi~2G-8*=JqdjcNHliS2hf3 z?>7w3#Zj5<;tn-SJUm-jyxkAaj$UpjV0bL-f4z1j+->(-c;+(3%M`UYZ3wQn8FAUt zWzZ#5ttXq+?>$SOI=Q#7HLOa6!P{31I#{-IgKW&26z^}&1TusZQLg2ew`E&6dF9I3 zQY#iLs?1n$Zc9dv=SMI20jC4cNgaSWSD*+j7k;@$Cp$g2e5InhY5_MRx9a%*j2NBO zlTW2QWpngn)FN$+q+u=4BS)6@g*FL~-hh z0I=0^nf%RJ`DD~b`m7-if*EY5F(gXoQY@X?=CkEQ8Ek!G z$YRQ*obKlnR;?CdlbcNv1&kdxq0gTerQrbp`ug`Xx?KnZ+ciHb#&Y}mzShMH2c7e# zOpxaCCZQo>=!zwftNbKVq2w+)^R(jDWR@_r+vM3RYY^wfyZ*JMuWIB>sZ`E}-JlPR zf-%A=I~2 zs`5KYzI+7}m*?fan=`itAn93Cl8Tx{={J%hhzQzmpL+*(U`qG#*`1tR=m-rUCn&N<=XD$#-oQ9Ci45hGnC~S4U7*J_xFgrfJgli zMd-94jK~23Wcr;;hLp+9_~TP>Ped<|3tJyJ4dO-hH6K;R`&c^E9MKZZ3N}u^ON*Xr zm*xZa=($zv+(VBBX}OP>GZu|2>#sJo@|QL>ENM&^7gsAMH;?bw8F3>hW;tYS%j2{( z(QJ}vC{k&gHLlbK?#zP?e7!;3C~w7YIiN7=5)ay}H^QsSJEb%)q4y zF+e2LUP8vD2kA+6jCer3Ewp==b4MWTHqCtV9<^Up zqtbn);hgJ}S-DJW^fyb*!*_ri)z2z;%~l!in(u2d7k8@Rzb;T{iqgNM;Vijdn~fwX}Z_4%UaO+)3`BzSmq8(O10fRbbYk8*`(Z7aN-vFDGZvQ0{3 z;>CSVC{`L9jLAWs(s($X408tk=?0ayyV&=w4A>gyV*?ICDx;sO*0baFuSg9PwL-nD z517l?WIoiZeO9_F+O*U&mcblnWLHX2ez~du*INKb>n)FhslQqPX zBO2u_6o_+F3?PLsHcCIbnxaNk%aSD;)>rHh=5Xc@z&Ec5g#k=Cj`Ed7e>*L{c~UH{ zVOJuR8a4@~91zν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 Ii5 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%0DFjO!0>(C)=OpdgLnZ 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%0D9E#k~FY45n8YF4}^V-%{Qxdq1rBMNc70A|O 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�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�wXm+v)Pr>F95x|wS?3U~8f-d;X<@O3<1s{?5G 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଄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 XUl{u3%kT5w-ET+3XZOTa-x~fW=}6gT diff --git a/components/softdevice/s210/headers/ant_error.h b/components/softdevice/s210/headers/ant_error.h deleted file mode 100644 index 0b326b9..0000000 --- a/components/softdevice/s210/headers/ant_error.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Dynastream Innovations Inc. - * Cochrane, AB, CANADA - * - * Copyright (c) 2012 Dynastream Innovations Inc. - * THIS SOFTWARE IS AN EXAMPLE USAGE OF THE ANT PROTOCOL MODULE. - * IT MAY BE USED, MODIFIED and DISTRIBUTED ONLY WITH THE - * APPROPRIATE LICENSE AGREEMENT. - */ - -/* Header guard */ -#ifndef ANT_ERROR_H__ -#define ANT_ERROR_H__ - -#include "ant_parameters.h" - -/** - @defgroup ant_error ANT Error Return - @{ - @ingroup ant_interface -*/ - -/** @brief ANT Error Return parameter definitions */ -#define NRF_ANT_ERROR_OFFSET 0x4000 //ANT's Exception offset - -#define NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE NRF_ANT_ERROR_OFFSET + CHANNEL_IN_WRONG_STATE ///< Response on attempt to perform an action from the wrong channel state. -#define NRF_ANT_ERROR_CHANNEL_NOT_OPENED NRF_ANT_ERROR_OFFSET + CHANNEL_NOT_OPENED ///< Response on attempt to communicate on a channel that is not open. -#define NRF_ANT_ERROR_CHANNEL_ID_NOT_SET NRF_ANT_ERROR_OFFSET + CHANNEL_ID_NOT_SET ///< Response on attempt to open a channel without setting the channel ID. -#define NRF_ANT_ERROR_CLOSE_ALL_CHANNELS NRF_ANT_ERROR_OFFSET + CLOSE_ALL_CHANNELS ///< Response when attempting to start scanning mode, when channels are still open. -#define NRF_ANT_ERROR_TRANSFER_IN_PROGRESS NRF_ANT_ERROR_OFFSET + TRANSFER_IN_PROGRESS ///< Response on attempt to communicate on a channel with a TX transfer in progress. -#define NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR NRF_ANT_ERROR_OFFSET + TRANSFER_SEQUENCE_NUMBER_ERROR ///< Response when sequence number of burst message or burst data segment is out of order. -#define NRF_ANT_ERROR_TRANSFER_IN_ERROR NRF_ANT_ERROR_OFFSET + TRANSFER_IN_ERROR ///< Response when transfer error has occured on supplied burst message or burst data segment. -#define NRF_ANT_ERROR_TRANSFER_BUSY NRF_ANT_ERROR_OFFSET + TRANSFER_BUSY ///< Response when transfer is busy and cannot process supplied burst message or burst data segment. -#define NRF_ANT_ERROR_MESSAGE_SIZE_EXCEEDS_LIMIT NRF_ANT_ERROR_OFFSET + MESSAGE_SIZE_EXCEEDS_LIMIT ///< Response if a data message is provided that is too large. -#define NRF_ANT_ERROR_INVALID_MESSAGE NRF_ANT_ERROR_OFFSET + INVALID_MESSAGE ///< Response when the message has an invalid parameter. -#define NRF_ANT_ERROR_INVALID_NETWORK_NUMBER NRF_ANT_ERROR_OFFSET + INVALID_NETWORK_NUMBER ///< Response when an invalid network number is provided -#define NRF_ANT_ERROR_INVALID_LIST_ID NRF_ANT_ERROR_OFFSET + INVALID_LIST_ID ///< Response when the provided list ID or size exceeds the limit -#define NRF_ANT_ERROR_INVALID_SCAN_TX_CHANNEL NRF_ANT_ERROR_OFFSET + INVALID_SCAN_TX_CHANNEL ///< Response when attempting to transmit on channel 0 when in scan mode. -#define NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED NRF_ANT_ERROR_OFFSET + INVALID_PARAMETER_PROVIDED ///< Response when an invalid parameter is specified in a configuration message -#endif // ANT_ERROR_H__ -/** - @} - */ diff --git a/components/softdevice/s210/headers/ant_interface.h b/components/softdevice/s210/headers/ant_interface.h deleted file mode 100644 index b60f60b..0000000 --- a/components/softdevice/s210/headers/ant_interface.h +++ /dev/null @@ -1,939 +0,0 @@ -/* - * Dynastream Innovations Inc. - * Cochrane, AB, CANADA - * - * Copyright (c) 2014 Dynastream Innovations Inc. - * THIS SOFTWARE IS AN EXAMPLE USAGE OF THE ANT PROTOCOL MODULE. - * IT MAY BE USED, MODIFIED and DISTRIBUTED ONLY WITH THE - * APPROPRIATE LICENSE AGREEMENT. - */ -/* Header guard */ -#ifndef ANT_INTERFACE_H__ -#define ANT_INTERFACE_H__ - -#include -#include -#include "nrf_svc.h" - -/** - @addtogroup stack_ant_module ANT STACK - @{ - @defgroup ant_interface ANT Application Interface - @{ -* @brief ANT Stack Application Programming Interface (API). -*/ - -#define STK_SVC_BASE_2 0xC0 // ANT stack protocol SVC base - -/** @brief ANT Stack API SVC numbers */ -enum { - /*ant re/initialization API*/ - SVC_ANT_STACK_INIT = STK_SVC_BASE_2, - /*event API*/ - SVC_ANT_EVENT_GET, - /*channel control API*/ - SVC_ANT_CHANNEL_ASSIGN, - SVC_ANT_CHANNEL_UNASSIGN, - SVC_ANT_CHANNEL_OPEN, - SVC_ANT_CHANNEL_CLOSE, - SVC_ANT_RX_SCAN_MODE_START, - /*data APIs*/ - SVC_ANT_TX_BROADCAST_MESSAGE, - SVC_ANT_TX_ACKNOWLEDGED_MESSAGE, - SVC_ANT_BURST_HANDLER_REQUEST, - SVC_ANT_PENDING_TRANSMIT_CLEAR, - SVC_ANT_TRANSFER_STOP, - /*radio configuration APIs*/ - SVC_ANT_NETWORK_KEY_SET, - SVC_ANT_CHANNEL_RADIO_FREQ_SET, - SVC_ANT_CHANNEL_RADIO_FREQ_GET, - SVC_ANT_CHANNEL_RADIO_TX_POWER_SET, - SVC_ANT_PROX_SEARCH_SET, - /*configuration APIs*/ - SVC_ANT_CHANNEL_PERIOD_SET, - SVC_ANT_CHANNEL_PERIOD_GET, - SVC_ANT_CHANNEL_ID_SET, - SVC_ANT_CHANNEL_ID_GET, - SVC_ANT_SEARCH_WAVEFORM_SET, - SVC_ANT_CHANNEL_RX_SEARCH_TIMEOUT_SET, - SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET, - SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET, - SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET, - SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET, - SVC_ANT_ADV_BURST_CONFIG_SET, - SVC_ANT_ADV_BURST_CONFIG_GET, - SVC_ANT_LIB_CONFIG_SET, - SVC_ANT_LIB_CONFIG_CLEAR, - SVC_ANT_LIB_CONFIG_GET, - SVC_ANT_ID_LIST_ADD, - SVC_ANT_ID_LIST_CONFIG, - SVC_ANT_AUTO_FREQ_HOP_TABLE_SET, - SVC_ANT_EVENT_FILTERING_SET, - SVC_ANT_EVENT_FILTERING_GET, - /*status APIs*/ - SVC_ANT_ACTIVE, - SVC_ANT_CHANNEL_IN_PROGRESS, - SVC_ANT_CHANNEL_STATUS_GET, - SVC_ANT_PENDING_TRANSMIT, - /*radio test APIs*/ - SVC_ANT_INIT_CW_TEST_MODE, - SVC_ANT_CW_TEST_MODE, - /*antstack version API*/ - SVC_ANT_VERSION, - /*antstack capabilities API*/ - SVC_ANT_CAPABILITIES, - /*more data APIs*/ - SVC_ANT_BURST_HANDLER_WAIT_FLAG_ENABLE, - SVC_ANT_BURST_HANDLER_WAIT_FLAG_DISABLE, - /*more configuration APIs*/ - SVC_ANT_SDU_MASK_SET, - SVC_ANT_SDU_MASK_GET, - SVC_ANT_SDU_MASK_CONFIG, - SVC_ANT_CRYPTO_CHANNEL_ENABLE, - SVC_ANT_CRYPTO_KEY_SET, - SVC_ANT_CRYPTO_INFO_SET, - SVC_ANT_CRYPTO_INFO_GET, - SVC_ANT_RFACTIVE_NOTIFICATION_CONFIG_SET, - SVC_ANT_RFACTIVE_NOTIFICATION_CONFIG_GET, - SVC_ANT_COEX_CONFIG_SET, - SVC_ANT_COEX_CONFIG_GET, - SVC_ANT_ENABLE, - /*reserved APIs*/ - SVC_ANT_RESERVED1, - SVC_ANT_RESERVED2, - /*extended APIs*/ - SVC_ANT_EXTENDED0, - SVC_ANT_EXTENDED1, - SVC_ANT_EXTENDED2, // LAST (64 SVCs) -}; - -////////////////////////////////////////////// -/** @name ANT enable channel structure - * - * @brief Structure for setting up ANT stack channels -@{ */ -////////////////////////////////////////////// -typedef struct -{ - /*Total number of channels wanted in ANT stack*/ - uint8_t ucTotalNumberOfChannels; - /*Number of encrypted channels wanted (subset of total channels)*/ - uint8_t ucNumberOfEncryptedChannels; - /*Memory location pointer to start allocating ANT channels*/ - uint8_t* pucMemoryBlockStartLocation; - /*Block byte size available for ANT channels starting at memory location pointer*/ - uint16_t usMemoryBlockByteSize; -} ANT_ENABLE; -/** @} */ - -/******************************************************************************/ -/** @name ANT API functions - * @{ */ -/******************************************************************************/ - -/******************************* RE/INITIALIZATION API *******************************/ - -/** @brief Function for initializing or re-initializing ANT Stack. - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_STACK_INIT, uint32_t, sd_ant_stack_reset (void)); - -/******************************* EVENT API *******************************/ - -/** @brief This function returns ANT channel events and data messages. - * - * @param[out] pucChannel is the pointer to an unsigned char (1 octet) where the channel number will be copied. - * @param[out] pucEvent is the pointer to an unsigned char (1 octet) where the event code will be copied. See Channel Events and Command Response Codes in ant_parameters.h. - * @param[out] aucANTMesg is the buffer where event's message will be copied. The array size must be at least MESG_BUFFER_SIZE to accommadate the entire ANT_MESSAGE structure size. See ANT Message Structure in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * @return ::NRF_ERROR_INVALID_PARAM - * @return ::NRF_ERROR_NOT_FOUND - */ -SVCALL(SVC_ANT_EVENT_GET, uint32_t, sd_ant_event_get (uint8_t *pucChannel, uint8_t *pucEvent, uint8_t *aucANTMesg)); - -/********************** CHANNEL CONTROL APIS ******************************/ - -/** @brief This function assigns and initializes a new channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to assign. - * @param[in] ucChannelType is an unsigned char (1 octet) denoting the channel type. See Assign Channel Parameters/Assign Channel Types in ant_parameters.h. - * @param[in] ucNetwork is an unsigned char (1 octet) denoting the network key to associate with the channel. - * @param[in] ucExtAssign is a bit field (1 octet) for an extended assign. See Ext. Assign Channel Parameters in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_INVALID_NETWORK_NUMBER - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - */ -SVCALL(SVC_ANT_CHANNEL_ASSIGN, uint32_t, sd_ant_channel_assign (uint8_t ucChannel, uint8_t ucChannelType, uint8_t ucNetwork, uint8_t ucExtAssign)); - -/** @brief This function unassigns a channel. The channel to unassign must be in an assigned state. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to unassign. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - */ -SVCALL(SVC_ANT_CHANNEL_UNASSIGN, uint32_t, sd_ant_channel_unassign (uint8_t ucChannel)); - -/** @brief This function opens and activates a channel. The channel to open must be in an assigned state. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to open. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - */ -SVCALL(SVC_ANT_CHANNEL_OPEN, uint32_t, sd_ant_channel_open(uint8_t ucChannel)); - -/** @brief This function closes a channel. The channel must be in an open state (SEARCHING or TRACKING). - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to close. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - * - */ -SVCALL(SVC_ANT_CHANNEL_CLOSE, uint32_t, sd_ant_channel_close (uint8_t ucChannel)); - -/** @brief This function starts receive scanning mode feature. Channel 0 must be assigned. All other channels must be closed. - * - * @param[in] ucSyncChannelPacketsOnly is an unsigned char (1 octet) denoting synchronous channel only scanning mode. 0 = disable, 1 = enable. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_CLOSE_ALL_CHANNELS - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - */ -SVCALL(SVC_ANT_RX_SCAN_MODE_START, uint32_t, sd_ant_rx_scan_mode_start (uint8_t ucSyncChannelPacketsOnly)); - -/*********************** DATA APIS ****************************************/ - -/** @brief This function is used to set broadcast data for transmission. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to send the data on. - * @param[in] ucSize is an unsigned char (1 octet) denoting the size of the message, ucSize must be 8. - * @param[in] aucMesg is the buffer where the message is located (array must be 8 octets). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_MESSAGE_SIZE_EXCEEDS_LIMIT - * ::NRF_ANT_ERROR_INVALID_SCAN_TX_CHANNEL - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - * ::NRF_ANT_ERROR_TRANSFER_IN_ERROR - */ -SVCALL(SVC_ANT_TX_BROADCAST_MESSAGE, uint32_t, sd_ant_broadcast_message_tx (uint8_t ucChannel, uint8_t ucSize, uint8_t *aucMesg)); - -/** @brief This function is used to send an acknowledge message. This message requests an acknowledgement from the slave to validate reception. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to send the data on. - * @param[in] ucSize is an unsigned char (1 octet) denoting the size of the message, ucSize must be 8. - * @param[in] aucMesg is the buffer where the message is located (array must be 8 octets). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_MESSAGE_SIZE_EXCEEDS_LIMIT - * ::NRF_ANT_ERROR_INVALID_SCAN_TX_CHANNEL - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - * ::NRF_ANT_ERROR_TRANSFER_IN_ERROR - */ -SVCALL(SVC_ANT_TX_ACKNOWLEDGED_MESSAGE, uint32_t, sd_ant_acknowledge_message_tx (uint8_t ucChannel, uint8_t ucSize, uint8_t *aucMesg)); - -/** @brief This function is used to queue data for burst transmission. After every successful call, the input buffer is held in use by the burst handler and must not be changed. - * When the burst handler releases the input buffer, it will either generate a EVENT_TRANSFER_NEXT_DATA_BLOCK event or clear a specified wait flag assigned to the - * burst handler. Transfer end events: EVENT_TRANSFER_TX_COMPLETED and EVENT_TRANSFER_TX_FAILED also releases the input buffer. Special care must be made to ensure that - * the input buffer does not change until it is released by the burst handler to avoid data corruption. Use of burst segment identifiers (BURST_SEGMENT_START, BURST_SEGMENT_CONTINUE, - * and BURST_SEGMENT_END) is required to indicate the sequence of the data block being sent as a burst transfer. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to do a burst transmission. - * @param[in] usSize is an unsigned short (2 octets) denoting the size of the message block. Size must be divisible by 8. - * @param[in] aucData is the buffer where the message block is located. - * @param[in] ucBurstSegment is an unsigned char (1 octet) containing a bitfield representing the message block type. See Tx Burst Handler Request Segment Defines in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_INVALID_SCAN_TX_CHANNEL - * ::NRF_ANT_ERROR_CHANNEL_NOT_OPENED - * ::NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - * ::NRF_ANT_ERROR_TRANSFER_IN_ERROR - * ::NRF_ANT_ERROR_MESSAGE_SIZE_EXCEEDS_LIMIT - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - * ::NRF_ANT_ERROR_TRANSFER_BUSY - */ -SVCALL(SVC_ANT_BURST_HANDLER_REQUEST, uint32_t, sd_ant_burst_handler_request(uint8_t ucChannel, uint16_t usSize, uint8_t *aucData, uint8_t ucBurstSegment)); - -/** @brief This function clears a pending transmit. Primarily intended for shared slave channels (receive channel). - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to clear pending transmit. - * @param[out] pucSuccess is the pointer to an unsigned char (1 octet) where the result will be stored. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_PENDING_TRANSMIT_CLEAR, uint32_t, sd_ant_pending_transmit_clear (uint8_t ucChannel, uint8_t *pucSuccess)); - -/** @brief This function kills a receive transfer that is in progress. - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_TRANSFER_STOP, uint32_t, sd_ant_transfer_stop (void)); - -/********************** RADIO CONFIGURATION APIS **************************/ - -/** @brief This function sets the 64bit network address. - * - * @param[in] ucNetwork is an unsigned char (1 octet) denoting the network number to assign the network address to. - * @param[in] aucNetworkKey is the pointer to location of the Network Key (8 octets in length) - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_NETWORK_NUMBER - */ -SVCALL(SVC_ANT_NETWORK_KEY_SET, uint32_t, sd_ant_network_address_set (uint8_t ucNetwork, uint8_t *aucNetworkKey)); - -/** @brief This function sets the radio frequency of an ANT channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set to. - * @param[in] ucFreq is an unsigned char (1 octet) denoting the radio frequency offset from 2400MHz (eg. 2466MHz, ucFreq = 66). - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_NETWORK_NUMBER - */ -SVCALL(SVC_ANT_CHANNEL_RADIO_FREQ_SET, uint32_t, sd_ant_channel_radio_freq_set (uint8_t ucChannel, uint8_t ucFreq)); - -/** @brief This function returns the radio frequency of an ANT channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pucRfreq is the pointer to an unsigned char (1 octet) where the frequency will be stored. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_RADIO_FREQ_GET, uint32_t, sd_ant_channel_radio_freq_get (uint8_t ucChannel, uint8_t *pucRfreq)); - -/** @brief This function sets the radio tx power. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to assign the radio tx power. - * @param[in] ucTxPower is an unsigned char (1 octet) denoting the ANT transmit power index. See Radio TX Power Definitions in ant_parameters.h. - * @param[in] ucCustomTxPower is an unsigned char (1 octet) denoting the custom nRF transmit power as defined in nrf51_bitfields.h. Only applicable if ucTxPower is set to custom tx power selection. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_RADIO_TX_POWER_SET, uint32_t, sd_ant_channel_radio_tx_power_set (uint8_t ucChannel, uint8_t ucTxPower, uint8_t ucCustomTxPower)); - -/** @brief This function sets the sensitivity threshold for acquisition on a searching channel. One time set. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number. - * @param[in] ucProxThreshold is an unsigned char (1 octet) denoting the minimum RSSI threshold required for acquisition during a search. See Radio Proximity Search Threshold in ant_parameters.h - * @param[in] ucCustomProxThreshold is an unsigned char (1 octet) denoting the custom minimum RSSI threshold for acquisition during a search. Only applicable if ucProxThreshold is set to custom proximity selection. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_PROX_SEARCH_SET, uint32_t, sd_ant_prox_search_set (uint8_t ucChannel, uint8_t ucProxThreshold, uint8_t ucCustomProxThreshold)); - -/********************** CONFIGURATION APIS ********************************/ - -/** @brief This function sets the channel period. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set the period to. - * @param[in] usPeriod is an unsigned short (2 octets) denoting the period in 32 kHz counts (usPeriod/32768 s). - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_PERIOD_SET, uint32_t, sd_ant_channel_period_set (uint8_t ucChannel, uint16_t usPeriod)); - -/** @brief This function returns the current channel period. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pusPeriod is the pointer to an unsigned short (2 octets) where the channel period will be stored. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_PERIOD_GET, uint32_t, sd_ant_channel_period_get (uint8_t ucChannel, uint16_t *pusPeriod)); - -/** @brief This function sets the channel ID. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set. - * @param[in] usDeviceNumber is an unsigned short (2 octets) denoting the device number. - * @param[in] ucDeviceType is an unsigned char (1 octet) denoting the device type. - * @param[in] ucTransmitType is an unsigned char (1 octet) denoting the transmission type. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_ID_SET, uint32_t, sd_ant_channel_id_set (uint8_t ucChannel, uint16_t usDeviceNumber, uint8_t ucDeviceType, uint8_t ucTransmitType)); - -/** @brief This function returns the current Channel ID of a channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pusDeviceNumber is the pointer to an unsigned short (2 octets) where the device number will be stored. - * @param[out] pucDeviceType is the pointer to an unsigned char (1 octet) where the device type will be stored. - * @param[out] pucTransmitType is the pointer to an unsigned char (1 octet) where the transmit type will be stored. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_ID_GET, uint32_t, sd_ant_channel_id_get (uint8_t ucChannel, uint16_t *pusDeviceNumber, uint8_t *pucDeviceType, uint8_t *pucTransmitType)); - -/** @brief This function sets the searching waveform value of an ANT Channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set. - * @param[in] usWaveform is an unsigned short (2 octets) denoting the channel waveform period (usWaveform/32768 s). Default = 316. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_SEARCH_WAVEFORM_SET, uint32_t, sd_ant_search_waveform_set (uint8_t ucChannel, uint16_t usWaveform)); - -/** @brief This function sets the receive channel search timeout. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set. - * @param[in] ucTimeout is an unsigned char (1 octet) denoting the timeout value in 2.5 second increments. Default = 10 (25s). - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_RX_SEARCH_TIMEOUT_SET, uint32_t, sd_ant_channel_rx_search_timeout_set (uint8_t ucChannel, uint8_t ucTimeout)); - -/** @brief This function sets the channel's search priority. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set. - * @param[in] ucSearchPriority is an unsigned char (1 octet) denoting the search priority value. 0 to 7 (Default = 0). - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET, uint32_t, sd_ant_search_channel_priority_set (uint8_t ucChannel, uint8_t ucSearchPriority)); - -/** @brief This function sets the search cycle number of separate searching channels for active search time sharing. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to configure. - * @param[in] ucCycles is an unsigned char (1 octet) denoting the number of cycles to set. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET, uint32_t, sd_ant_active_search_sharing_cycles_set (uint8_t ucChannel, uint8_t ucCycles)); - -/** @brief This function returns the search sharing cycles number of the specified searching channel for active search time sharing. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pucCycles is the pointer to an unsigned char (1 octet) where the cycle value will be stored. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET, uint32_t, sd_ant_active_search_sharing_cycles_get (uint8_t ucChannel, uint8_t *pucCycles)); - -/** @brief This function sets the low priority search timeout value of a channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set. - * @param[in] ucTimeout is an unsigned char (1 octet) denoting the timeout value in 2.5 seconds increments. Default = 2 (5s). - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET, uint32_t, sd_ant_channel_low_priority_rx_search_timeout_set (uint8_t ucChannel, uint8_t ucTimeout)); - -/** @brief This function sets the advanced burst configuration. Configuration structure is as follows: - * Required Byte0 = 0-Disable, 1-Enable. See Advanced Burst Configuration Defines in ant_parameters.h. - * Required Byte1 = RF payload size. See Advanced Burst Configuration Defines in ant_parameters.h. - * Required Byte2 = Required advanced burst modes. See Advanced Burst Configuration Defines in ant_parameters.h. - * Required Byte3 = 0, Reserved - * Required Byte4 = 0, Reserved - * Required Byte5 = Optional advanced burst modes. See Advanced Burst Configuration Defines in ant_parameters.h. - * Required Byte6 = 0, Reserved - * Required Byte7 = 0, Reserved - * Optional Byte8 = Advanced burst stalling count config LSB. Typical is 3210 (~10s of stalling) where each count represents ~3ms of stalling. - * Optional Byte9 = Advanced burst stalling count config MSB. - * Optional Byte10 = Advanced burst retry count cycle extension. Typical is 3 (15 retries) where each count cycles represents 5 retries. - * - * @param[in] aucConfig is a buffer containing the advanced burst configuration to be set (as stated above). - * @param[in] ucSize is an unsigned char (1 octet) denoting the size of the configuration parameter buffer. Minimum config set is 8 octets, maximum is 11 octets. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_ADV_BURST_CONFIG_SET, uint32_t, sd_ant_adv_burst_config_set (uint8_t *aucConfig, uint8_t ucSize)); - -/** @brief This function gets the advance burst configuration and supported capabilities. - * Returned structure is as follows for configuration: - * Byte0 = RF payload size. See Advanced Burst Configuration Defines in ant_parameters.h. - * Byte1 = Required advanced burst modes. See Advanced Burst Configuration Defines in ant_parameters.h. - * Byte2 = 0, Reserved - * Byte3 = 0, Reserved - * Byte4 = Optional advanced burst modes. See Advanced Burst Configuration Defines in ant_parameters.h. - * Byte5 = 0, Reserved - * Byte6 = 0, Reserved - * Byte7 = Advanced burst stalling count config LSB. Each count represents ~3ms of stalling. - * Byte8 = Advanced burst stalling count config MSB - * Byte9 = Advanced burst retry count cycle extension. Each count cycle represents 5 retries. - * - * Returned structure is as follows for capabilities: - * Byte0 = Supported RF payload size. See Advanced Burst Configuration Defines in ant_parameters.h. - * Byte1 = Supported burst configurations. See Advanced Burst Configuration Defines in ant_parameters.h. - * Byte2 = 0, Reserved - * Byte3 = 0, Reserved - * - * @param[in] ucRequestType is an unsigned char (1 octet) denoting the type of request. 1 = configuration, 0 = capability. - * @param[out] aucConfig is the pointer to the buffer where the configuration/capabilities will be read to. The array should be at least 10 octets - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_ADV_BURST_CONFIG_GET, uint32_t, sd_ant_adv_burst_config_get (uint8_t ucRequestType, uint8_t *aucConfig)); - -/** @brief This function sets the ANT Messaging Library Configuration used by Extended messaging. - * - * @param[in] ucANTLibConfig is an unsigned char (1 octet) denoting the ANT lib config bit flags. See ANT Library Config in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_LIB_CONFIG_SET, uint32_t, sd_ant_lib_config_set (uint8_t ucANTLibConfig)); - -/** @brief This function clears the ANT Messaging Library Configuration. - * - * @param[in] ucANTLibConfig is an unsigned char (1 octet) denoting the ANT lib Config bit(s) to clear. See ANT Library Config in ant_parameters.h. - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_LIB_CONFIG_CLEAR, uint32_t, sd_ant_lib_config_clear (uint8_t ucANTLibConfig)); - -/** @brief This function returns current ANT Messaging Library Configuration. - * - * @param[out] pucANTLibConfig is the pointer to an unsigned char (1 octet) where the bit flags will be stored. See ANT Library Config in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_LIB_CONFIG_GET, uint32_t, sd_ant_lib_config_get (uint8_t *pucANTLibConfig)); - -/** @brief This function is used to add a Device ID to an include or exclude list. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to add the list entry to. - * @param[in] aucDevId is the pointer to the buffer (4 octets) containing device ID information with the following format: - * Byte0 = DeviceNumber_LSB - * Byte1 = DeviceNumber_MSB - * Byte2 = DeviceType - * Byte3 = TransType - * @param[in] ucListIndex is an unsigned char (1 octet) denoting the index where the specified Channel ID is to be placed in the list (0-3). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_INVALID_LIST_ID - */ -SVCALL(SVC_ANT_ID_LIST_ADD, uint32_t, sd_ant_id_list_add (uint8_t ucChannel, uint8_t *aucDevId, uint8_t ucListIndex)); - -/** @brief This function is used to configure the device ID list as include or exclude as well as the number of IDs to compare against. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number of the device ID list. - * @param[in] ucIDListSize is an unsigned char (1 octet) denoting the size of the inclusion or exclusion list (0-4). - * @param[in] ucIncExcFlag is an unsigned char (1 octet) denoting the type of list as Include(0) or Exclude(1) - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_INVALID_LIST_ID - */ -SVCALL(SVC_ANT_ID_LIST_CONFIG, uint32_t, sd_ant_id_list_config (uint8_t ucChannel, uint8_t ucIDListSize, uint8_t ucIncExcFlag)); - -/** @brief This function populates the frequency hop table list. This table is used when frequency hopping is enabled on a channel via extended assignment bit. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set the frequency hop table list. - * @param[in] ucFreq0 is an unsigned char (1 octet) denoting the offset from 2400MHz of the 1st frequency hop value. - * @param[in] ucFreq1 is an unsigned char (1 octet) denoting the offset from 2400MHz of the 2nd frequency hop value. - * @param[in] ucFreq2 is an unsigned char (1 octet) denoting the offset from 2400MHz of the 3rd frequency hop value. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_AUTO_FREQ_HOP_TABLE_SET, uint32_t, sd_ant_auto_freq_hop_table_set (uint8_t ucChannel, uint8_t ucFreq0, uint8_t ucFreq1, uint8_t ucFreq2)); - -/** @brief This function is used to specify filter configuration for channel event message generation. - * - * @param[in] usFilter is an unsigned short (2 octets) denoting the filter configuration bitfield. See Event Filtering in ant_parameters.h. - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_EVENT_FILTERING_SET, uint32_t, sd_ant_event_filtering_set (uint16_t usFilter)); - -/** @brief This function is used to retrieve the filter configuration for channel event message generation. - * - * @param[out] pusFilter is the pointer to an unsigned short (2 octets) where the filter configuration will be stored. See Event Filtering in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_EVENT_FILTERING_GET, uint32_t, sd_ant_event_filtering_get (uint16_t *pusFilter)); - -/*************************** STATUS APIS **********************************/ - -/** @brief This function gets the ANT activity status. - * - * @param[out] pbAntActive is the pointer to an unsigned char (1 octet) where the ANT activity value will be stored. 1 = active, 0 = otherwise. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_ACTIVE, uint32_t, sd_ant_active (uint8_t *pbAntActive)); - -/** @brief This function gets the status if the channel is in progress. - * - * @param[out] pbChannelInProgress is the pointer to an unsigned char (1 octet) where the result will be stored. 1 = in progress, 0 = otherwise. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_CHANNEL_IN_PROGRESS, uint32_t, sd_ant_channel_in_progress (uint8_t *pbChannelInProgress)); - -/** @brief This function gets a specific channel's status. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pucStatus is the pointer to an unsigned char (1 octet) where the channel status will be stored. See Channel Status in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_STATUS_GET, uint32_t, sd_ant_channel_status_get (uint8_t ucChannel, uint8_t *pucStatus)); - -/** @brief This function determines if there is a pending transmission on a specific channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pucPending is the pointer to an unsigned char (1 octet) where the pending result will be stored. 1 = pending, 0 = otherwise. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_PENDING_TRANSMIT, uint32_t, sd_ant_pending_transmit (uint8_t ucChannel, uint8_t *pucPending)); - -/*************************** TEST APIS **********************************/ - -/** @brief This function initialize the stack to get ready for a continuous wave transmission test. - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_INIT_CW_TEST_MODE, uint32_t, sd_ant_cw_test_mode_init (void)); - -/** @brief This function starts a continuous wave test mode transmission. - * - * @param[in] ucRadioFreq is an unsigned char (1 octet) denoting the radio frequency offset from 2400MHz for continuous wave mode. (eg. 2466MHz, ucRadioFreq = 66). - * @param[in] ucTxPower is an unsigned char (1 octet) denoting the ANT transmit power index for continuous wave mode. See Radio TX Power Definitions in ant_parameters.h - * @param[in] ucCustomTxPower is an unsigned char (1 octet) denoting the custom nRF transmit power as defined in nrf51_bitfields.h. Only applicable if ucTxPower is set to custom tx power selection. - * @param[in] ucMode is an unsigned char (1 octet) denoting test mode type where 0 = cw tx carrier transmission, 1 = cw tx modulated transmission - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_CW_TEST_MODE, uint32_t, sd_ant_cw_test_mode (uint8_t ucRadioFreq, uint8_t ucTxPower, uint8_t ucCustomTxPower, uint8_t ucMode)); - -/** @brief This function gets the version string of the ANT stack. - * - * @param[out] aucVersion is the pointer to the buffer where the version string will be copied, the array should be at least 11 octets. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_VERSION, uint32_t, sd_ant_version_get (uint8_t* aucVersion)); - -/** @brief This function gets the capabilities of the stack. - * - * @param[out] aucCapabilities is the pointer to the buffer where the capabilities message will be copied, the array should be at least 8 octets. - * Byte0 = Maximum supported ANT channels - * Byte1 = Maximum supported ANT networks - * Byte2 = CAPABILITIES_STANDARD. See Standard capabilities defines in ant_parameters.h - * Byte3 = CAPABILITIES_ADVANCED. See Advanced capabilities defines in ant_parameters.h - * Byte4 = CAPABILITIES_ADVANCED_2. See Advanced capabilities 2 defines in ant_parameters.h - * Byte5 = Maximum support ANT data channels (only applicable for SensRcore support) - * Byte6 = CAPABILITIES_ADVANCED_3. See Advanced capabilities 3 defines in ant_parameters.h - * Byte7 = CAPABILITIES_ADVANCED_4. Advanced capabilities 4 defines in ant_parameters.h - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_CAPABILITIES, uint32_t, sd_ant_capabilities_get (uint8_t* aucCapabilities)); - -/*********************** MORE DATA APIS ****************************************/ - -/** @brief This function assigns a wait variable to the the burst handler. When the input buffer is locked by the handler the wait flag is set to 1. When the - * input buffer is unlocked, the wait flag is set to 0. When a wait flag is assigned, EVENT_TRANSFER_NEXT_DATA_BLOCK events will not - * be generated until the wait flag unassigned. The wait flag should be declared as a static variable. - * - * @param[in] pucWaitFlag is the pointer to a static unsigned char (1 octet) where the status of the burst handler will be updated. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - */ -SVCALL(SVC_ANT_BURST_HANDLER_WAIT_FLAG_ENABLE, uint32_t, sd_ant_burst_handler_wait_flag_enable (uint8_t* pucWaitFlag)); - -/** @brief This function unassigns any previously assigned wait variable from the burst handler. The burst handler returns to the default method in generating - * EVENT_TRANSFER_NEXT_DATA_BLOCK to indicate input buffer unlock. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - */ -SVCALL(SVC_ANT_BURST_HANDLER_WAIT_FLAG_DISABLE, uint32_t, sd_ant_burst_handler_wait_flag_disable (void)); - -/********************** MORE CONFIGURATION API ********************************/ - -/** @brief This function is used to assign a selective data update (SDU) mask (8 octets) to an identifier, ucMask. - * - * @param[in] ucMask is an unsigned char (1 octet) denoting the index representing the SDU data mask. - * @param[in] aucMask is a buffer (8 octets) containing the SDU mask to be assigned to ucMask. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_SDU_MASK_SET, uint32_t, sd_ant_sdu_mask_set (uint8_t ucMask, uint8_t *aucMask)); - -/** @brief This function returns the selective data update (SDU) mask (8 octets) from the specified identifier, ucMask. - * - * @param[in] ucMask is an unsigned char (1 octet) denoting the index representing the SDU data mask. - * @param[out] aucMask is a pointer to the buffer where the SDU data mask will be copied, the array should be at least 8 octects. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_SDU_MASK_GET, uint32_t, sd_ant_sdu_mask_get (uint8_t ucMask, uint8_t *aucMask)); - -/** @brief This function assigns a SDU mask configuration to a particular channel. The configuration specifies the mask identifier and the type of rx data in which the mask should be applied to. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel in which the SDU mask configuration is to be applied to. - * @param[in] ucMaskConfig is an unsigned char (1 octet) denoting SDU mask configuration. See Selective Data Update Mask Configuration Defines in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_SDU_MASK_CONFIG, uint32_t, sd_ant_sdu_mask_config (uint8_t ucChannel, uint8_t ucMaskConfig)); - -/** @brief This function enables/disables 128-bit AES encryption mode to the specified channel. Advanced burst must be enabled beforehand to enable encrypted channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel in which encryption mode is set. - * @param[in] ucEnable is an unsigned char (1 octet) denoting the encryption mode. See Encrypted Channel Defines in ant_parameters.h. - * @param[in] ucKeyNum is an unsigned char (1 octet) denoting the key index of the 128-bit key to be used for encryption. The key index range is bound by the number of - encrypted channels configured by sd_ant_enable(). If sd_ant_enable() is not used then by default ucKeyNum is 0. Range is [0 to (num encrypted channels - 1)], - if 1 or more encrypted channels are configured. - * @param[in] ucDecimationRate is an unsigned char (1 octet) denoting the decimate rate to apply for encrypted slave channel. Must be > 0. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_INVALID_SCAN_TX_CHANNEL - * ::NRF_ANT_ERROR_CHANNEL_NOT_OPENED - * ::NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - * ::NRF_ANT_ERROR_TRANSFER_IN_ERROR - * ::NRF_ANT_ERROR_MESSAGE_SIZE_EXCEEDS_LIMIT - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - * ::NRF_ANT_ERROR_TRANSFER_BUSY - */ -SVCALL(SVC_ANT_CRYPTO_CHANNEL_ENABLE, uint32_t, sd_ant_crypto_channel_enable (uint8_t ucChannel, uint8_t ucEnable, uint8_t ucKeyNum, uint8_t ucDecimationRate)); - -/** @brief This function assigns a 128-bit AES encryption key to a key index. - * - * @param[in] ucKeyNum is an unsigned char (1 octet) denoting the key index for assignment. The key index range is bound by the number of encrypted channels configured - by sd_ant_enable(). If sd_ant_enable() is not used then by default ucKeyNum is 0. Range is [0 to (num encrypted channels - 1)], if 1 or more - encrypted channels are configured. - * @param[in] aucKey is a buffer (16 octets) containing the 128-bit AES key to be assigned to the key index. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CRYPTO_KEY_SET, uint32_t, sd_ant_crypto_key_set (uint8_t ucKeyNum, uint8_t *aucKey)); - - /** @brief This function sets specific information to be exchanged between the channel master and slave during encryption channel set-up/negotiation. - * - * @param[in] ucType is an unsigned char (1 octet) denoting the type of information being set. See Encrypted Channel Defines in ant_parameters.h. - * @param[in] aucInfo is a buffer containing the information being set (4 octets for ID, 19 octets for custom user data). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CRYPTO_INFO_SET, uint32_t, sd_ant_crypto_info_set (uint8_t ucType, uint8_t *aucInfo)); - - /** @brief This function retrieves specific information to be exchanged between the channel master and slave during encryption channel set-up/negotiation. - * - * @param[in] ucType is an unsigned char (1 octet) denoting the type of information being requested. See Encrypted Channel Defines in ant_parameters.h. - * @param[out] aucInfo is a pointer to a buffer in which the information retrieved will be copied to (1 octet for supported mode, 4 octets for ID, 19 octets for custom user data). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_CRYPTO_INFO_GET, uint32_t, sd_ant_crypto_info_get (uint8_t ucType, uint8_t *aucInfo)); - - /** @brief This function enables/disables event notifications to be generated to the application indicating the time to the next ANT radio activity exceeds the configured time threshold. - * Latency (delay in event notification being received and processed by application) must be taken into account if attempting to use this generated event to perform - * operations prior to the radio activity. Cannot be used if asynchronous tx channel is assigned or used. Please note that this only generates events for ANT radio activity. - * - * @param[in] ucMode is an unsigned char (1 octet) denoting the mode of event notification. See RFActive Notification Defines in ant_parameters.h. - * @param[in] usTimeThreshold is an unsigned short (2 octets) denoting the minimum time threshold (32 kHz counts (usTimeThreshold/32768 s)) before the next radio activity that will trigger generation of the event notification. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - */ -SVCALL(SVC_ANT_RFACTIVE_NOTIFICATION_CONFIG_SET, uint32_t, sd_ant_rfactive_notification_config_set (uint8_t ucMode, uint16_t usTimeThreshold)); - - /** @brief This function retrieves the ANT rf active notification configuration - * - * @param[in] pucMode is a pointer to an unsigned char (1 octet) where the configured mode of event notification will be stored. - * @param[out] pusTimeThreshold is a pointer to an unsigned short (2 octets) where the configured time threhold value will be stored. Time threshold is in 32 kHz counts (usTimeThreshold/32768 s). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_RFACTIVE_NOTIFICATION_CONFIG_GET, uint32_t, sd_ant_rfactive_notification_config_get (uint8_t *pucMode, uint16_t *pusTimeThreshold)); - - /** @brief This function sets ANT radio coexistence behaviour. Supported only if ANT is sharing radio HW concurrently with another wireless protocol. - * Configuration structure is as follows: - * Byte0 = Configuration enable bitfield - * bit0 - enable/disable tx/rx channel keep alive config (Byte4/5 & Byte6/7) - * bit1 - enable/disable tx/rx channel fixed interval priority config (Byte1) - * bit2 - enable/disable transfer keep alive config (Byte2) - * bit3 - enable/disable search channel fixed interval priority config (Byte3) - * else - reserved - * Byte1 = tx/rx channel fixed interval priority configuration - * Byte2 = transfer keep alive configuration - * Byte3 = search channel fixed interval priority configuration - * Byte4(LSB)/Byte5(MSB) = tx channel keep alive configuration - * Byte6(LSB)/Byte7(MSB) = rx channel keep alive configuration - * - * Advanced configuration structure is as follows: - * Byte0 = Configuration enable bitfield - * bit0 - enable/disable priority override config (Byte1) - * bit1-7 - reserved - * Byte1 = ANT priority override. 0 = low, 1 = normal(default), 2 = high, 3 = critical - * Byte2 = Reserved - * Byte3 = Reserved - * Byte4 = Reserved - * Byte5 = Reserved - * Byte6 = Reserved - * Byte7 = Reserved - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel for which the coexistence configuration is to be set. - * @param[in] aucCoexConfig is a buffer containing the coex configuration to be set. Must be 8 octet in size. Set as null for no change. - * @param[in] aucAdvCoexConfig is a buffer containing the advanced coex configuration to be set. Must be 8 octet in size. Set as null for no change. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_COEX_CONFIG_SET, uint32_t, sd_ant_coex_config_set (uint8_t ucChannel, uint8_t *aucCoexConfig, uint8_t *aucAdvCoexConfig)); - - /** @brief This function retrieves the configured ANT radio coexistence behaviour as described in ant_coex_config_set. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to query. - * @param[out] aucCoexConfig is the pointer to a buffer where the coexistence configuration will be stored. Must be at least 8 octet in size. Set as null to ignore. - * @param[out] aucAdvCoexConfig is the pointer to a buffer where the advanced coexistence configuration will be stored. Must be at least 8 octet in size. Set as null to ignore. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_COEX_CONFIG_GET, uint32_t, sd_ant_coex_config_get (uint8_t ucChannel, uint8_t *aucCoexConfig, uint8_t *aucAdvCoexConfig)); - - /** @brief This function is used to specify the total number of ANT channels, number of encrypted channels (subset of total ANT channels) and transmit burst queue size to be supported - * by the ANT stack. Upon enabling the SoftDevice successfully, the ANT stack defaults to supporting 1 ANT channel (encryption capable) and a 64 byte transmit burst buffer. If additional - * channels are needed and/or more encrypted channels are needed and/or larger tx burst buffer size is needed, then the desired configuration can be specified to the SoftDevice - * using this function. In this case, a static RAM buffer (of minimum size defined by ANT_ENABLE_GET_REQUIRED_SPACE) must be supplied by the application to be used by the ANT SoftDevice stack. - * - * Notes: - If used, function should be called immediately after sd_softdevice_enable() and before any ANT related SVC calls. - * - Using sd_ant_stack_reset() will not reset ANT stack channel allocation configuration. It will be maintained. - * - Disabling the SoftDevice and then re-enabling the SoFtDevice will reset channel allocation to default. Any previously supplied memory buffer by the application will not be used. - * - * - * @param[in] pstChannelEnable is a pointer to ANT_ENABLE structure. - * where ucTotalNumberOfChannels is an unsigned char (1 octet) denoting the total number of ANT channels desired (1 to MAX_ANT_CHANNELS, defined in ant_parameters.h) - * where ucTotalNumberOfEncryptedChannels is an unsigned char (1 octet) denoting the total number of ANT channels (0 to ucTotalNumberOfChannels) that support encryption - * where pucMemoryBlockStartLocation is the pointer to an application supplied buffer to be used by the ANT SoftDevice stack. - * where usMemoryBlockByteSize is an unsigned short (2 octet) denoting the size of the given memory block (pucMemoryBlockStartLocation). The defined ANT_ENABLE_GET_REQUIRED_SPACE - * macro (see ant_parameters.h) should be used to determine the minimum buffer size requirement - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_ENABLE, uint32_t, sd_ant_enable(ANT_ENABLE * const pstChannelEnable)); - -/** @brief Extended0 ANT SVCs. Access extended SVC functions via ucExtID -* -* @param[in] ucExtID is the extended ID defined by SD_ANT_EXT0_ID_ -* @param[in,out] pvArg0 is first argument to extended ANT SVC function specified by ucExtID -* @param[in,out] pvArg1 is second argument to extended ANT SVC function specified by ucExtID -* @param[in,out] pvArg2 is third argument to extended ANT SVC function specified by ucExtID -* -* @return Return value(s) of extended ANT SVC function specified by ucExtID -*/ -SVCALL(SVC_ANT_EXTENDED0, uint32_t, sd_ant_extended0 (uint8_t ucExtID, void *pvArg0, void *pvArg1, void *pvArg2)); - -/** @brief This function configures CPU wake on ANT RF activity behaviour. CPU is woken up via generation of SD_EVENT_IRQn interrupt upon the start of specified RF activity. In -* order to wakeup in the event that SD_EVENT_IRQn is disabled, the SEVONPEND flag has to be set in the Cortex-M0 System Control Register (SCR). CPU is dissallowed from -* entering low power state when calling sd_app_event_wait() for the duration of the RF activity. The intention of this function is to allow/disallow sudden shifts in -* current consumption during RF transmission/ RF reception window which may impact RF performance. When enabled there is a slight increase in average current consumption for -* ANT activities. -* -* @param[in] ucExtID = SD_ANT_EXT0_ID_WAKEON_RF_ACTIVITY_CONFIG_SET -* @param[in] pvArg0 is a pointer to unsigned char (1 octet) denoting the CPU wakeup configuration. See Wake On RF Activity Defines in ant_parameters.h. -* @param[in,out] pvArg1 is unused. Set to NULL. -* @param[in,out] pvArg2 is unused. Set to NULL. -* -* @return ::NRF_SUCCESS -* ::NRF_ERROR_INVALID_PARAM -*/ -#define SD_ANT_EXT0_ID_WAKEON_RF_ACTIVITY_CONFIG_SET 0x00 - -/** @brief This function retrieves the configured CPU wake on ANT RF activity behaviour. -* -* @param[in] ucExtID = SD_ANT_EXT0_ID_WAKEON_RF_ACTIVITY_CONFIG_GET -* @param[out] pvArg0 is a pointer to unsigned char (1 octet) denoting where the CPU wakeup configuration will be stored. -* @param[in,out] pvArg1 is unused. Set to NULL. -* @param[in,out] pvArg2 is unused. Set to NULL. -* -* @return ::NRF_SUCCESS -* ::NRF_ERROR_INVALID_PARAM -*/ -#define SD_ANT_EXT0_ID_WAKEON_RF_ACTIVITY_CONFIG_GET 0x01 - -/** @brief This function enables or disables a feature for preventing long periods of consecutive multi-tracking channel collisions. This feature is -* enabled by default/upon stack reset. -* -* @param[in] ucExtID = SD_ANT_EXT0_ID_ENHANCED_CHANNEL_SPACING_SET -* @param[out] pvArg0 is a pointer to unsigned char (1 octet) denoting enable/disable control. See Enhanced Channel Spacing Defines in ant_parameters.h -* @param[in,out] pvArg1 is unused. Set to NULL. -* @param[in,out] pvArg2 is unused. Set to NULL. -* -* @return ::NRF_SUCCESS -* ::NRF_ERROR_INVALID_PARAM -*/ -#define SD_ANT_EXT0_ID_ENHANCED_CHANNEL_SPACING_SET 0x02 - - -#endif // ANT_INTERFACE_H__ - -/** - @} - @} - @} - */ diff --git a/components/softdevice/s210/headers/ant_parameters.h b/components/softdevice/s210/headers/ant_parameters.h deleted file mode 100644 index d7f38e2..0000000 --- a/components/softdevice/s210/headers/ant_parameters.h +++ /dev/null @@ -1,725 +0,0 @@ -/* - * Dynastream Innovations Inc. - * Cochrane, AB, CANADA - * - * Copyright (c) 2012 Dynastream Innovations Inc. - * THIS SOFTWARE IS AN EXAMPLE USAGE OF THE ANT PROTOCOL MODULE. - * IT MAY BE USED, MODIFIED and DISTRIBUTED ONLY WITH THE - * APPROPRIATE LICENSE AGREEMENT. - */ - -#ifndef ANTDEFINES_H -#define ANTDEFINES_H - -#include - -/** - @defgroup ant_parameters ANT Stack Parameters - @{ - @ingroup ant_interface -*/ - -////////////////////////////////////////////// -/** @name ANT Channel Init Definitions -@{ */ -////////////////////////////////////////////// -#define MAX_ANT_CHANNELS ((uint8_t)15) -#define SIZE_OF_NONENCRYPTED_ANT_CHANNEL ((uint8_t)88) -#define SIZE_OF_ENCRYPTED_ANT_CHANNEL ((uint8_t)21) -#define MIN_ANT_TX_BURST_QUEUE_SIZE ((uint8_t)64) - -#define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) ) - -#define GET_TX_BURST_QUEUE_SIZE(requestedSize) \ - (requestedSize < MIN_ANT_TX_BURST_QUEUE_SIZE ? MIN_ANT_TX_BURST_QUEUE_SIZE : (IS_POWER_OF_TWO(requestedSize) ? requestedSize : MIN_ANT_TX_BURST_QUEUE_SIZE)) - -#define ANT_ENABLE_GET_REQUIRED_SPACE_MORE_THAN_TWO_CH(ucTotalNumberOfChannels, ucNumberOfEncryptedChannels, usTxQueueByteSize) \ - ((ucTotalNumberOfChannels - 2) * SIZE_OF_NONENCRYPTED_ANT_CHANNEL) + (ucNumberOfEncryptedChannels * SIZE_OF_ENCRYPTED_ANT_CHANNEL) + GET_TX_BURST_QUEUE_SIZE(usTxQueueByteSize) - -#define ANT_ENABLE_GET_REQUIRED_SPACE_LESS_THAN_OR_EQ_TWO_CH(ucNumberOfEncryptedChannels, usTxQueueByteSize) \ - (ucNumberOfEncryptedChannels * SIZE_OF_ENCRYPTED_ANT_CHANNEL) + GET_TX_BURST_QUEUE_SIZE(usTxQueueByteSize) - -#define ANT_ENABLE_GET_REQUIRED_SPACE(ucTotalNumberOfChannels, ucNumberOfEncryptedChannels, usTxQueueByteSize) \ - ucTotalNumberOfChannels > 2 ? \ - ANT_ENABLE_GET_REQUIRED_SPACE_MORE_THAN_TWO_CH(ucTotalNumberOfChannels, ucNumberOfEncryptedChannels, usTxQueueByteSize) : \ - ANT_ENABLE_GET_REQUIRED_SPACE_LESS_THAN_OR_EQ_TWO_CH(ucNumberOfEncryptedChannels, usTxQueueByteSize) -/** @} */ - -////////////////////////////////////////////// -/** @brief ANT Clock Definition */ -////////////////////////////////////////////// -#define ANT_CLOCK_FREQUENCY ((uint32_t)32768) ///< ANT system clock frequency. - -////////////////////////////////////////////// -/** @brief ANT Message Payload Size */ -////////////////////////////////////////////// -#define ANT_STANDARD_DATA_PAYLOAD_SIZE ((uint8_t)8) ///< Standard data payload size - -////////////////////////////////////////////// -/** @name Radio TX Power Definitions -@{ */ -////////////////////////////////////////////// -#define RADIO_TX_POWER_LVL_CUSTOM ((uint8_t)0x80) ///< Custom tx power selection -#define RADIO_TX_POWER_LVL_0 ((uint8_t)0x00) ///< Lowest ANT Tx power level setting. (-20dBm). -#define RADIO_TX_POWER_LVL_1 ((uint8_t)0x01) ///< ANT Tx power > Lvl 0. (-12dBm) -#define RADIO_TX_POWER_LVL_2 ((uint8_t)0x02) ///< ANT Tx power > Lvl 1. (-4dBm) -#define RADIO_TX_POWER_LVL_3 ((uint8_t)0x03) ///< ANT Tx power > Lvl 2. Default tx power level. (0dBm) -#define RADIO_TX_POWER_LVL_4 ((uint8_t)0x04) ///< ANT Tx power > Lvl 3. (+4dBm) -/** @} */ - -////////////////////////////////////////////// -/** @name Radio Proximity Search Threshold -@{ */ -////////////////////////////////////////////// -#define PROXIMITY_THRESHOLD_CUSTOM ((uint8_t)0x80) ///< Custom proximity search selection. -#define PROXIMITY_THRESHOLD_OFF ((uint8_t)0x00) ///< Disable proximity search detection. -#define PROXIMITY_THRESHOLD_1 ((uint8_t)0x01) ///< Proximity search detection radius > preset threshold (~ -44dBm on nRF51) -#define PROXIMITY_THRESHOLD_2 ((uint8_t)0x02) ///< Proximity search detection radius > preset threshold (~ -48dBm on nRF51). -#define PROXIMITY_THRESHOLD_3 ((uint8_t)0x03) ///< Proximity search detection radius > preset threshold (~ -52dBm on nRF51). -#define PROXIMITY_THRESHOLD_4 ((uint8_t)0x04) ///< Proximity search detection radius > preset threshold (~ -56dBm on nRF51). -#define PROXIMITY_THRESHOLD_5 ((uint8_t)0x05) ///< Proximity search detection radius > preset threshold (~ -60dBm on nRF51). -#define PROXIMITY_THRESHOLD_6 ((uint8_t)0x06) ///< Proximity search detection radius > preset threshold (~ -64dBm on nRF51). -#define PROXIMITY_THRESHOLD_7 ((uint8_t)0x07) ///< Proximity search detection radius > preset threshold (~ -68dBm on nRF51). -#define PROXIMITY_THRESHOLD_8 ((uint8_t)0x08) ///< Proximity search detection radius > preset threshold (~ -72dBm on nRF51). -#define PROXIMITY_THRESHOLD_9 ((uint8_t)0x09) ///< Proximity search detection radius > preset threshold (~ -76dBm on nRF51). -#define PROXIMITY_THRESHOLD_10 ((uint8_t)0x0A) ///< Proximity search detection radius > preset threshold (~ -80dBm on nRF51). -/** @} */ - -////////////////////////////////////////////// -/** @name Assign Channel Parameters -@{ */ -////////////////////////////////////////////// -#define PARAMETER_RX_NOT_TX ((uint8_t)0x00) ///< Bitfield for slave channel. -#define PARAMETER_TX_NOT_RX ((uint8_t)0x10) ///< Bitfield for master channel. -#define PARAMETER_SHARED_CHANNEL ((uint8_t)0x20) ///< Bitfield for enabling shared channel mode for master or slave channel. -#define PARAMETER_NO_TX_GUARD_BAND ((uint8_t)0x40) ///< Bitfield for enabling tx only mode for master channel. -#define PARAMETER_RX_ONLY ((uint8_t)0x40) ///< Bitfield for enabling rx only mode for slave channel. -/** @} */ - -////////////////////////////////////////////// -/** @name Extended Assign Channel Parameters -@{ */ -////////////////////////////////////////////// -#define EXT_PARAM_ALWAYS_SEARCH ((uint8_t)0x01) ///< Bitfield for enabling background searching behaviour. -#define EXT_PARAM_IGNORE_TRANSMISSION_TYPE ((uint8_t)0x02) ///< Bitfield for enabling ignore transmission type behaviour. -#define EXT_PARAM_FREQUENCY_AGILITY ((uint8_t)0x04) ///< Bitfield for enabling frequency agility behaviour. -#define EXT_PARAM_AUTO_SHARED_SLAVE ((uint8_t)0x08) ///< Auto shared channel. -#define EXT_PARAM_FAST_INITIATION_MODE ((uint8_t)0x10) ///< Channel fast initiation mode. -#define EXT_PARAM_ASYNC_TX_MODE ((uint8_t)0x20) ///< Async transmit channel. -/** @} */ - -////////////////////////////////////////////// -/** @name Assign Channel Types -@{ */ -////////////////////////////////////////////// -#define CHANNEL_TYPE_SLAVE ((uint8_t) 0x00) ///< Slave channel (PARAMETER_RX_NOT_TX). -#define CHANNEL_TYPE_MASTER ((uint8_t) 0x10) ///< Master channel (PARAMETER_TX_NOT_RX). -#define CHANNEL_TYPE_SLAVE_RX_ONLY ((uint8_t) 0x40) ///< Slave rx only channel (PARAMETER_RX_NOT_TX | PARAMETER_RX_ONLY). -#define CHANNEL_TYPE_MASTER_TX_ONLY ((uint8_t) 0x50) ///< Master tx only channel (PARAMETER_TX_NOT_RX | PARAMETER_NO_TX_GUARD_BAND). -#define CHANNEL_TYPE_SHARED_SLAVE ((uint8_t) 0x20) ///< Shared slave channel (PARAMETER_RX_NOT_TX | PARAMETER_SHARED_CHANNEL). -#define CHANNEL_TYPE_SHARED_MASTER ((uint8_t) 0x30) ///< Shared master channel (PARAMETER_TX_NOT_RX | PARAMETER_SHARED_CHANNEL). -/** @} */ - -////////////////////////////////////////////// -/** @name Channel ID Definitions -@{ */ -////////////////////////////////////////////// -#define ANT_ID_SIZE ((uint8_t)4) ///< 4 octet channel ID -#define ANT_ID_TRANS_TYPE_OFFSET ((uint8_t)3) ///< Transmission type offset in channel ID -#define ANT_ID_DEVICE_TYPE_OFFSET ((uint8_t)2) ///< Device type offset in channel ID -#define ANT_ID_DEVICE_NUMBER_HIGH_OFFSET ((uint8_t)1) ///< MSB Device number in channel ID -#define ANT_ID_DEVICE_NUMBER_LOW_OFFSET ((uint8_t)0) ///< LSB Device number in channel ID -#define ANT_ID_DEVICE_TYPE_PAIRING_FLAG ((uint8_t)0x80) ///< Pairing bit in device type field - -#define ANT_TRANS_TYPE_SHARED_ADDR_MASK ((uint8_t)0x03) ///< shared address mask in transmission type field -#define ANT_TRANS_TYPE_1_BYTE_SHARED_ADDRESS ((uint8_t)0x02) ///< 1 byte shared address field -#define ANT_TRANS_TYPE_2_BYTE_SHARED_ADDRESS ((uint8_t)0x03) ///< 2 byte shared address field -/** @} */ - -////////////////////////////////////////////// -/** @name Channel Status -@{ */ -////////////////////////////////////////////// -#define STATUS_CHANNEL_STATE_MASK ((uint8_t)0x03) ///< Channel state mask -#define STATUS_UNASSIGNED_CHANNEL ((uint8_t)0x00) ///< Indicates channel has not been assigned. -#define STATUS_ASSIGNED_CHANNEL ((uint8_t)0x01) ///< Indicates channel has been assigned. -#define STATUS_SEARCHING_CHANNEL ((uint8_t)0x02) ///< Indicates channel is active and in searching state. -#define STATUS_TRACKING_CHANNEL ((uint8_t)0x03) ///< Indicates channel is active and in tracking state. -/** @} */ - -////////////////////////////////////////////// -/** @name Standard capabilities defines -@{ */ -////////////////////////////////////////////// -#define CAPABILITIES_NO_RX_CHANNELS ((uint8_t)0x01) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no rx channel support. -#define CAPABILITIES_NO_TX_CHANNELS ((uint8_t)0x02) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no tx channel support. -#define CAPABILITIES_NO_RX_MESSAGES ((uint8_t)0x04) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no rx message support. -#define CAPABILITIES_NO_TX_MESSAGES ((uint8_t)0x08) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no tx message support. -#define CAPABILITIES_NO_ACKD_MESSAGES ((uint8_t)0x10) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no acknolwedged message support. -#define CAPABILITIES_NO_BURST_TRANSFER ((uint8_t)0x20) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no burst transfer support. -/** @} */ - -////////////////////////////////////////////// -/** @name Advanced capabilities defines -@{ */ -////////////////////////////////////////////// -#define CAPABILITIES_NETWORK_ENABLED ((uint8_t)0x02) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating network support. -#define CAPABILITIES_SERIAL_NUMBER_ENABLED ((uint8_t)0x08) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating serial number support. -#define CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED ((uint8_t)0x10) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating per channel transmit power support. -#define CAPABILITIES_LOW_PRIORITY_SEARCH_ENABLED ((uint8_t)0x20) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating lower priority search support. -#define CAPABILITIES_SCRIPT_ENABLED ((uint8_t)0x40) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating scripting support. -#define CAPABILITIES_SEARCH_LIST_ENABLED ((uint8_t)0x80) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating include/exclude list support. -/** @} */ - -////////////////////////////////////////////// -/** @name Advanced capabilities 2 defines -@{ */ -////////////////////////////////////////////// -#define CAPABILITIES_LED_ENABLED ((uint8_t)0x01) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating built-in LED support. -#define CAPABILITIES_EXT_MESSAGE_ENABLED ((uint8_t)0x02) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating extended messaging support. -#define CAPABILITIES_SCAN_MODE_ENABLED ((uint8_t)0x04) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating scanning mode support. -#define CAPABILITIES_RESERVED ((uint8_t)0x08) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte currently reserved for future use. -#define CAPABILITIES_PROX_SEARCH_ENABLED ((uint8_t)0x10) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating proximity search support. -#define CAPABILITIES_EXT_ASSIGN_ENABLED ((uint8_t)0x20) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating extended assign support. -#define CAPABILITIES_FS_ANTFS_ENABLED ((uint8_t)0x40) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating built-in FS/ANT-FS support -#define CAPABILITIES_FIT1_ENABLED ((uint8_t)0x80) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating FIT1 module support -/** @} */ - -////////////////////////////////////////////// -/** @name Advanced capabilities 3 defines -@{ */ -////////////////////////////////////////////// -#define CAPABILITIES_ADVANCED_BURST_ENABLED ((uint8_t)0x01) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating advanced burst support. -#define CAPABILITIES_EVENT_BUFFERING_ENABLED ((uint8_t)0x02) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating extended messaging support. -#define CAPABILITIES_EVENT_FILTERING_ENABLED ((uint8_t)0x04) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating event filtering support. -#define CAPABILITIES_HIGH_DUTY_SEARCH_MODE_ENABLED ((uint8_t)0x08) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating high duty search mode support. -#define CAPABILITIES_ACTIVE_SEARCH_SHARING_MODE_ENABLED ((uint8_t)0x10) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating active search sharing mode support. -#define CAPABILITIES_RADIO_COEX_CONFIG_ENABLED ((uint8_t)0x20) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating radio coexistence configuration support. -#define CAPABILITIES_SELECTIVE_DATA_UPDATE_ENABLED ((uint8_t)0x40) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating selective rx data update support. -#define CAPABILITIES_ENCRYPTED_CHANNEL_ENABLED ((uint8_t)0x80) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating encrypted channel support. -/** @} */ - -////////////////////////////////////////////// -/** @name Advanced capabilities 4 defines -@{ */ -////////////////////////////////////////////// -#define CAPABILITIES_RFACTIVE_NOTIFICATION_ENABLED ((uint8_t)0x01) ///< Bitfield in CAPABILITIES_ADVANCED_4 byte indicating rfactive notification support. -/** @} */ - - - -////////////////////////////////////////////// -/** @name Rx Burst Message Sequencing Defines -@{ */ -////////////////////////////////////////////// -#define CHANNEL_NUMBER_MASK ((uint8_t)0x1F) ///< Valid bitfields for channel number -#define SEQUENCE_NUMBER_MASK ((uint8_t)0xE0) ///< Valid bitfields for burst sequence -#define SEQUENCE_NUMBER_ROLLOVER ((uint8_t)0x60) ///< Sequence rollover -#define SEQUENCE_FIRST_MESSAGE ((uint8_t)0x00) ///< Sequence indicating first burst message -#define SEQUENCE_LAST_MESSAGE ((uint8_t)0x80) ///< Sequence indicating last burst message -#define SEQUENCE_NUMBER_INC ((uint8_t)0x20) ///< Incremental sequence value -/** @} */ - -////////////////////////////////////////////// -/** @name Tx Burst Handler Request Segment Defines -@{ */ -////////////////////////////////////////////// -#define BURST_SEGMENT_CONTINUE ((uint8_t)0x00) ///< Bitfield for indicating continuation of burst data segment (no starting or ending burst packet). -#define BURST_SEGMENT_START ((uint8_t)0x01) ///< Bitfield for indicating burst data segment containing starting burst packet. -#define BURST_SEGMENT_END ((uint8_t)0x02) ///< Bitfield for indicating burst data segment containing ending burst packet. -/** @} */ - -////////////////////////////////////////////// -/** @name ANT Library Config -@{ */ -////////////////////////////////////////////// -#define ANT_LIB_CONFIG_MASK_ALL ((uint8_t)0xFF) ///< libary configuration mask -#define ANT_LIB_CONFIG_RADIO_CONFIG_ALWAYS ((uint8_t)0x01) ///< Bitfield intended for platform specific configuration (unused) -#define ANT_LIB_CONFIG_MESG_OUT_INC_TIME_STAMP ((uint8_t)0x20) ///< Bitfield for enabling extended rx messages including ant time stamp field -#define ANT_LIB_CONFIG_MESG_OUT_INC_RSSI ((uint8_t)0x40) ///< Bitfield for enabling extended rx messages including RSSI measurement field -#define ANT_LIB_CONFIG_MESG_OUT_INC_DEVICE_ID ((uint8_t)0x80) ///< Bitfield for enabling extended rx messages including device ID field -/** @} */ - -////////////////////////////////////////////// -/** @name Extended Data Message Bitfield Definitions -@{ */ -////////////////////////////////////////////// -#define ANT_EXT_MESG_BITFIELD_DEVICE_ID ((uint8_t)0x80) ///< Bitfield for indicating device ID field present in extended data message after the extended message bitfield byte -#define ANT_EXT_MESG_BITFIELD_RSSI ((uint8_t)0x40) ///< Bitfield for indicating RSSI field present in extended data message after device id field (if present) -#define ANT_EXT_MESG_BITFIELD_TIME_STAMP ((uint8_t)0x20) ///< Bitfield for indicating timestamp field present in extended data message after rssi/agc field (if present) -#define ANT_EXT_MESG_BIFIELD_EXTENSION ((uint8_t)0x01) ///< Bitfield reserved -/** @} */ - -////////////////////////////////////////////// -/** @name RSSI Definitions in Extended Data Message -@{ */ -////////////////////////////////////////////// -#define RSSI_TYPE_AGC_EXT_MESG_FIELD_SIZE ((uint8_t)4) ///< Extended bitfield message size for AGC type RSSI measurement -#define RSSI_TYPE_DBM_EXT_MESG_FIELD_SIZE ((uint8_t)3) ///< Extended bitfield message size for DBM type RSSI measurement - -#define RSSI_TYPE_OFFSET ((uint8_t)0) ///< RSSI type offset in RSSI field in extended data message -#define RSSI_AGC_TYPE ((uint8_t)0x10) ///< RSSI type indicating support for AGC measurement -#define RSSI_DBM_TYPE ((uint8_t)0x20) ///< RSSI type indicating support for DBM measurement - -#define RSSI_TYPE_AGC_THRESHOLD_OFFSET ((uint8_t)1) ///< Offset of AGC value indicating above or below configured AGC threshold -#define RSSI_TYPE_AGC_REGISTER_LOW ((uint8_t)2) ///< Offset of LSB AGC threshold configuration in RSSI field -#define RSSI_TYPE_AGC_REGISTER_HIGH ((uint8_t)3) ///< Offset of MSB AGC threshold configuration in RSSI field - -#define RSSI_TYPE_DBM_VALUE ((uint8_t)1) ///< Offset of DBM value in RSSI field -#define RSSI_TYPE_DBM_SETTING ((uint8_t)2) ///< Offset of DBM threshold configuration in RSSI field -/** @} */ - -////////////////////////////////////////////// -/** @name Reset/Startup Mesg Codes -@{ */ -////////////////////////////////////////////// -#define RESET_FLAGS_MASK ((uint8_t)0xE0) ///< Message code mask -#define RESET_SUSPEND ((uint8_t)0x80) ///< Startup/Reset from suspend mode -#define RESET_SYNC ((uint8_t)0x40) ///< Startup/Reset from synchronous reset -#define RESET_CMD ((uint8_t)0x20) ///< Startup/Reset from ant message reset command -#define RESET_WDT ((uint8_t)0x02) ///< Startup/Reset from watchdog timeout -#define RESET_RST ((uint8_t)0x01) ///< Startup/Reset from HW reset pin -#define RESET_POR ((uint8_t)0x00) ///< Startup/Reset from HW power on reset -/** @} */ - -////////////////////////////////////////////// -/** @name Event Filtering -@{ */ -////////////////////////////////////////////// -#define FILTER_EVENT_RX_SEARCH_TIMEOUT ((uint16_t)0x0001) ///< Bitfield for filtering EVENT_RX_SEARCH_TIMEOUT -#define FILTER_EVENT_RX_FAIL ((uint16_t)0x0002) ///< Bitfield for filtering EVENT_RX_FAIL -#define FILTER_EVENT_TX ((uint16_t)0x0004) ///< Bitfield for filtering EVENT_TX -#define FILTER_EVENT_TRANSFER_RX_FAILED ((uint16_t)0x0008) ///< Bitfield for filtering EVENT_TRANSFER_RX_FAILED -#define FILTER_EVENT_TRANSFER_TX_COMPLETED ((uint16_t)0x0010) ///< Bitfield for filtering EVENT_TRANSFER_TX_COMPLETED -#define FILTER_EVENT_TRANSFER_TX_FAILED ((uint16_t)0x0020) ///< Bitfield for filtering EVENT_TRANSFER_TX_FAILED -#define FILTER_EVENT_CHANNEL_CLOSED ((uint16_t)0x0040) ///< Bitfield for filtering EVENT_CHANNEL_CLOSED -#define FILTER_EVENT_RX_FAIL_GO_TO_SEARCH ((uint16_t)0x0080) ///< Bitfield for filtering EVENT_RX_FAIL_GO_TO_SEARCH -#define FILTER_EVENT_CHANNEL_COLLISION ((uint16_t)0x0100) ///< Bitfield for filtering EVENT_CHANNEL_COLLISION -#define FILTER_EVENT_TRANSFER_TX_START ((uint16_t)0x0200) ///< Bitfield for filtering EVENT_TRANSFER_TX_START -/** @} */ - - -////////////////////////////////////////////// -/** @name Selective Data Update Mask Configuration Defines -@{ */ -////////////////////////////////////////////// -#define INVALID_SDU_MASK ((uint8_t)0xFF) ///< Selective data update configuration invalid mask. Used to disable SDU for a particular channel -#define SDU_MASK_ACK_CONFIG_BIT ((uint8_t)0x80) ///< Selective data acknowledge config bit. Use to enable SDU for acknowledged data in addition to broadcast data -/** @} */ - -////////////////////////////////////////////// -/** @name Advanced Burst Configuration Defines -@{ */ -////////////////////////////////////////////// -#define ADV_BURST_MODE_DISABLE ((uint8_t)0x00) ///< Set to disable advanced burst transfers -#define ADV_BURST_MODE_ENABLE ((uint8_t)0x01) ///< Set to enable advanced burst transfers - -#define ADV_BURST_MODES_MAX_SIZE ((uint8_t)0x03) ///< Maximum allowable value for advanced burst packets size configuration -#define ADV_BURST_MODES_SIZE_8_BYTES ((uint8_t)0x01) ///< 8-bytes packet size for maximum 20kbps advanced burst transfer rate -#define ADV_BURST_MODES_SIZE_16_BYTES ((uint8_t)0x02) ///< 16-bytes packet size for maximum 40kbps advanced burst transfer rate -#define ADV_BURST_MODES_SIZE_24_BYTES ((uint8_t)0x03) ///< 24-bytes packet size for maximum 60kbps advanced burst transfer rate - -#define ADV_BURST_MODES_MASK ((uint8_t)0x03) ///< Bitfield mask for advanced burst modes -#define ADV_BURST_MODES_FREQ_HOP ((uint8_t)0x01) ///< Bitfield for required/optional frequency hopping mode during advanced burst -#define ADV_BURST_MODES_RESERVED0 ((uint8_t)0x02) ///< Bitfield reserved -/** @} */ - -////////////////////////////////////////////// -/** @name Encrypted Channel Defines -@{ */ -////////////////////////////////////////////// -#define ENCRYPTION_DISABLED_MODE ((uint8_t) 0x00) ///< Set encryption mode to disabled -#define ENCRYPTION_BASIC_REQUEST_MODE ((uint8_t) 0x01) ///< Enable encryption mode with basic request (crypto ID exchange) -#define ENCRYPTION_USER_DATA_REQUEST_MODE ((uint8_t) 0x02) ///< Enable encryption mode with user data request (crypto ID + custom user data exchange) - -#define MAX_SUPPORTED_ENCRYPTION_MODE ENCRYPTION_USER_DATA_REQUEST_MODE ///< Maximum supported encryption mode -#define ENCRYPTION_USER_DATA_SIZE ((uint8_t)19) ///< Maximum size of custom user data - -#define ENCRYPTION_INFO_SET_CRYPTO_ID ((uint8_t)0x00) ///< Set configured crypto ID to be exchanged during encryption negotiation -#define ENCRYPTION_INFO_SET_CUSTOM_USER_DATA ((uint8_t)0x01) ///< Set configured custom user data to be exchanged during encryption negotation -#define ENCRYPTION_INFO_SET_RNG_SEED ((uint8_t)0x02) ///< Set RNG seed - -#define ENCRYPTION_INFO_GET_SUPPORTED_MODE ((uint8_t)0x00) ///< Get supported encrytped mode -#define ENCRYPTION_INFO_GET_CRYPTO_ID ((uint8_t)0x01) ///< Get configured crypto ID to be exchanged during encryption negotiation -#define ENCRYPTION_INFO_GET_CUSTOM_USER_DATA ((uint8_t)0x02) ///< Get configured custom user data to be exchanged during encryption negotiation -/** @} */ - -////////////////////////////////////////////// -/** @name RFActive Notification Defines -@{ */ -////////////////////////////////////////////// -#define RFACTIVE_NOTIFICATION_DISABLED_MODE ((uint8_t)0x00) ///< Set RF Active notification mode to disabled -#define RFACTIVE_NOTIFICATION_ONE_TIME_MODE ((uint8_t)0x01) ///< Set to generate RF Active notification event for only 1 time -#define RFACTIVE_NOTIFICATION_CONTINUOUS_MODE ((uint8_t)0x02) ///< Set to generate RF Active notification event continuously - -#define RFACTIVE_NOTIFICATION_MIN_TIME_THRESHOLD ((uint16_t)0x00A4) ///< Minimum time threshold of 5ms in 32768 time base -/** @} */ - -////////////////////////////////////////////// -/** @name WakeOn RF Activity Defines -@{ */ -////////////////////////////////////////////// -#define WAKEON_RF_ACTIVITY_NONE ((uint8_t)0x00) ///< Disable wakeon -#define WAKEON_RF_ACTIVITY_TX ((uint8_t)0x01) ///< Enable wakeon for ANT RF transmission windows -#define WAKEON_RF_ACTIVITY_RX ((uint8_t)0x02) ///< Enable wakeon for ANT RF reception windows -#define WAKEON_RF_ACTIVITY_ALL ((uint8_t)0x03) ///< (WAKE_ON_RF_ACTIVITY_TX | WAKE_ON_RF_ACTIVITY_RX)) -/** @} */ - -////////////////////////////////////////////// -/** @name Enhanced Channel Spacing Defines -@{ */ -////////////////////////////////////////////// -#define ENHANCED_CHANNEL_SPACING_DISABLE ((uint8_t)0x00) ///< Disable enhanced channel spacing -#define ENHANCED_CHANNEL_SPACING_ENABLE ((uint8_t)0x01) ///< Enable enhanced channel spacing -/** @} */ - - - - -////////////////////////////////////////////// -/** @name Channel Events and Command Response Codes -@{ */ -////////////////////////////////////////////// -#define RESPONSE_NO_ERROR ((uint8_t)0x00) ///< Command response with no error -#define NO_EVENT ((uint8_t)0x00) ///< No Event -#define EVENT_RX_SEARCH_TIMEOUT ((uint8_t)0x01) ///< ANT stack generated event when rx searching state for the channel has timed out -#define EVENT_RX_FAIL ((uint8_t)0x02) ///< ANT stack generated event when synchronous rx channel has missed receiving an ANT packet -#define EVENT_TX ((uint8_t)0x03) ///< ANT stack generated event when synchronous tx channel has occurred -#define EVENT_TRANSFER_RX_FAILED ((uint8_t)0x04) ///< ANT stack generated event when the completion of rx transfer has failed -#define EVENT_TRANSFER_TX_COMPLETED ((uint8_t)0x05) ///< ANT stack generated event when the completion of tx transfer has succeeded -#define EVENT_TRANSFER_TX_FAILED ((uint8_t)0x06) ///< ANT stack generated event when the completion of tx transfer has failed -#define EVENT_CHANNEL_CLOSED ((uint8_t)0x07) ///< ANT stack generated event when channel has closed -#define EVENT_RX_FAIL_GO_TO_SEARCH ((uint8_t)0x08) ///< ANT stack generated event when synchronous rx channel has lost tracking and is entering rx searching state -#define EVENT_CHANNEL_COLLISION ((uint8_t)0x09) ///< ANT stack generated event during a multi-channel setup where an instance of the current synchronous channel is blocked by another synchronous channel -#define EVENT_TRANSFER_TX_START ((uint8_t)0x0A) ///< ANT stack generated event when the start of tx transfer is occuring -//... -#define EVENT_TRANSFER_NEXT_DATA_BLOCK ((uint8_t)0x11) ///< ANT stack generated event when the stack requires the next transfer data block for tx transfer continuation or completion -//... -#define CHANNEL_IN_WRONG_STATE ((uint8_t)0x15) ///< Command response on attempt to perform an action from the wrong channel state -#define CHANNEL_NOT_OPENED ((uint8_t)0x16) ///< Command response on attempt to communicate on a channel that is not open -//... -#define CHANNEL_ID_NOT_SET ((uint8_t)0x18) ///< Command response on attempt to open a channel without setting the channel ID -#define CLOSE_ALL_CHANNELS ((uint8_t)0x19) ///< Command response when attempting to start scanning mode, when channels are still open -//... -#define TRANSFER_IN_PROGRESS ((uint8_t)0x1F) ///< Command response on attempt to communicate on a channel with a TX transfer in progress -#define TRANSFER_SEQUENCE_NUMBER_ERROR ((uint8_t)0x20) ///< Command response when sequence number of burst message or burst data segment is out of order -#define TRANSFER_IN_ERROR ((uint8_t)0x21) ///< Command response when transfer error has occured on supplied burst message or burst data segment -#define TRANSFER_BUSY ((uint8_t)0x22) ///< Command response when transfer is busy and cannot process supplied burst message or burst data segment -//... -#define MESSAGE_SIZE_EXCEEDS_LIMIT ((uint8_t)0x27) ///< Command response if a data message is provided that is too large -#define INVALID_MESSAGE ((uint8_t)0x28) ///< Command response when the message has an invalid parameter -#define INVALID_NETWORK_NUMBER ((uint8_t)0x29) ///< Command response when an invalid network number is provided -#define INVALID_LIST_ID ((uint8_t)0x30) ///< Command response when the provided list ID or size exceeds the limit -#define INVALID_SCAN_TX_CHANNEL ((uint8_t)0x31) ///< Command response when attempting to transmit on channel 0 when in scan mode -#define INVALID_PARAMETER_PROVIDED ((uint8_t)0x33) ///< Command response when an invalid parameter is specified in a configuration message -#define EVENT_QUE_OVERFLOW ((uint8_t)0x35) ///< ANT stack generated event when the event queue in the stack has overflowed and drop 1 or 2 events -#define EVENT_ENCRYPT_NEGOTIATION_SUCCESS ((uint8_t)0x38) ///< ANT stack generated event when connecting to an encrypted channel has succeeded -#define EVENT_ENCRYPT_NEGOTIATION_FAIL ((uint8_t)0x39) ///< ANT stack generated event when connecting to an encrypted channel has failed -#define EVENT_RFACTIVE_NOTIFICATION ((uint8_t)0x3A) ///< ANT stack generated event when the time to next synchronous channel RF activity exceeds configured time threshold -#define EVENT_CONNECTION_START ((uint8_t)0x3B) ///< Application generated event used to indicate when starting a connection to a channel -#define EVENT_CONNECTION_SUCCESS ((uint8_t)0x3C) ///< Application generated event used to indicate when successfuly connected to a channel -#define EVENT_CONNECTION_FAIL ((uint8_t)0x3D) ///< Application generated event used to indicate when failed to connect to a channel -#define EVENT_CONNECTION_TIMEOUT ((uint8_t)0x3E) ///< Application generated event used to indicate when connecting to a channel has timed out -#define EVENT_CONNECTION_UPDATE ((uint8_t)0x3F) ///< Application generated event used to indicate when connection parameters have been updated -//... -#define NO_RESPONSE_MESSAGE ((uint8_t)0x50) ///< Command response type intended to indicate that no serial reply message should be generated -#define EVENT_RX ((uint8_t)0x80) ///< ANT stack generated event indicating received data (eg. broadcast, acknowledge, burst) from the channel -#define EVENT_BLOCKED ((uint8_t)0xFF) ///< ANT stack generated event that should be ignored (eg. filtered events will generate this) -/** @} */ - - -#endif // !ANTDEFINES_H -/* - * Dynastream Innovations Inc. - * Cochrane, AB, CANADA - * - * Copyright (c) 2012 Dynastream Innovations Inc. - * THIS SOFTWARE IS AN EXAMPLE USAGE OF THE ANT PROTOCOL MODULE. - * IT MAY BE USED, MODIFIED and DISTRIBUTED ONLY WITH THE - * APPROPRIATE LICENSE AGREEMENT. - */ - -#ifndef ANTMESSAGE_H -#define ANTMESSAGE_H - -#include - -///////////////////////////////////////////////////////////////////////////// -// Message Format -// Messages are in the format: -// -// AX XX YY -------- CK -// -// where: AX is the 1 byte sync byte either transmit or recieve -// XX is the 1 byte size of the message (0-249) NOTE: THIS WILL BE LIMITED BY THE EMBEDDED RECEIVE BUFFER SIZE -// YY is the 1 byte ID of the message (1-255, 0 is invalid) -// ----- is the data of the message (0-249 bytes of data) -// CK is the 1 byte Checksum of the message -///////////////////////////////////////////////////////////////////////////// -#define MESG_TX_SYNC ((uint8_t)0xA4) -#define MESG_RX_SYNC ((uint8_t)0xA5) -#define MESG_SYNC_SIZE ((uint8_t)1) -#define MESG_SIZE_SIZE ((uint8_t)1) -#define MESG_ID_SIZE ((uint8_t)1) -#define MESG_CHANNEL_NUM_SIZE ((uint8_t)1) -#define MESG_EXT_MESG_BF_SIZE ((uint8_t)1) // NOTE: this could increase in the future -#define MESG_CHECKSUM_SIZE ((uint8_t)1) -#define MESG_DATA_SIZE ((uint8_t)9) - -////////////////////////////////////////////// -// ANT LIBRARY Extended Data Message Fields -// NOTE: You must check the extended message -// bitfield first to find out which fields -// are present before accessing them! -////////////////////////////////////////////// -#define ANT_EXT_MESG_DEVICE_ID_FIELD_SIZE ((uint8_t)4) -#define ANT_EXT_MESG_RSSI_FIELD_SIZE ((uint8_t)4) // maximum RSSI field size regardless of RSSI type -#define ANT_EXT_MESG_TIME_STAMP_FIELD_SIZE ((uint8_t)2) -#define ANT_EXT_STRING_SIZE ((uint8_t)16) // additional buffer to accommdate for 24 byte advance burst mode & encrypted usr data - -// The largest serial message is an ANT data message with all of the extended fields -#define MESG_ANT_MAX_PAYLOAD_SIZE ANT_STANDARD_DATA_PAYLOAD_SIZE - -#define MESG_MAX_EXT_DATA_SIZE (ANT_EXT_MESG_DEVICE_ID_FIELD_SIZE + ANT_EXT_MESG_RSSI_FIELD_SIZE + ANT_EXT_MESG_TIME_STAMP_FIELD_SIZE + ANT_EXT_STRING_SIZE) // ANT device ID (4 bytes) + ANT RSSI (4 bytes) + ANT timestamp (2 bytes) + ANT Ext String Size - -#define MESG_MAX_DATA_SIZE (MESG_ANT_MAX_PAYLOAD_SIZE + MESG_EXT_MESG_BF_SIZE + MESG_MAX_EXT_DATA_SIZE) // ANT data payload (8 bytes) + extended bitfield (1 byte) + extended data (10 bytes) -#define MESG_MAX_SIZE_VALUE (MESG_MAX_DATA_SIZE + MESG_CHANNEL_NUM_SIZE) // this is the maximum value that the serial message size value is allowed to be -#define MESG_BUFFER_SIZE (MESG_SIZE_SIZE + MESG_ID_SIZE + MESG_CHANNEL_NUM_SIZE + MESG_MAX_DATA_SIZE + MESG_CHECKSUM_SIZE) -#define MESG_FRAMED_SIZE (MESG_ID_SIZE + MESG_CHANNEL_NUM_SIZE + MESG_MAX_DATA_SIZE) -#define MESG_HEADER_SIZE (MESG_SYNC_SIZE + MESG_SIZE_SIZE + MESG_ID_SIZE) -#define MESG_FRAME_SIZE (MESG_HEADER_SIZE + MESG_CHECKSUM_SIZE) -#define MESG_MAX_SIZE (MESG_MAX_DATA_SIZE + MESG_FRAME_SIZE) - -#define MESG_SIZE_OFFSET (MESG_SYNC_SIZE) -#define MESG_ID_OFFSET (MESG_SYNC_SIZE + MESG_SIZE_SIZE) -#define MESG_DATA_OFFSET (MESG_HEADER_SIZE) - -////////////////////////////////////////////// -/** @name Message ID's -@{ */ -////////////////////////////////////////////// -#define MESG_INVALID_ID ((uint8_t)0x00) ///< invalid ANT message ID -#define MESG_EVENT_ID ((uint8_t)0x01) ///< ANT stack - channel event ID -//... -#define MESG_VERSION_ID ((uint8_t)0x3E) ///< ANT stack - version message ID -#define MESG_RESPONSE_EVENT_ID ((uint8_t)0x40) ///< ANT stack - channel/response event ANT message ID -#define MESG_UNASSIGN_CHANNEL_ID ((uint8_t)0x41) ///< ANT stack - channel unassign message ID -#define MESG_ASSIGN_CHANNEL_ID ((uint8_t)0x42) ///< ANT stack - channel assign message ID -#define MESG_CHANNEL_MESG_PERIOD_ID ((uint8_t)0x43) ///< ANT stack - channel period message ID -#define MESG_CHANNEL_SEARCH_TIMEOUT_ID ((uint8_t)0x44) ///< ANT stack - channel (high priority) search timeout message ID -#define MESG_CHANNEL_RADIO_FREQ_ID ((uint8_t)0x45) ///< ANT stack - channel radio frequency message ID -#define MESG_NETWORK_KEY_ID ((uint8_t)0x46) ///< ANT stack - network key message ID -#define MESG_RADIO_TX_POWER_ID ((uint8_t)0x47) ///< ANT stack - transmit power message ID -#define MESG_RADIO_CW_MODE_ID ((uint8_t)0x48) ///< ANT stack - CW test mode message ID -#define MESG_SEARCH_WAVEFORM_ID ((uint8_t)0x49) ///< ANT stack - search waveform message ID -#define MESG_SYSTEM_RESET_ID ((uint8_t)0x4A) ///< ANT application - system reset message ID -#define MESG_OPEN_CHANNEL_ID ((uint8_t)0x4B) ///< ANT stack - channel open message ID -#define MESG_CLOSE_CHANNEL_ID ((uint8_t)0x4C) ///< ANT stack - channel close message ID -#define MESG_REQUEST_ID ((uint8_t)0x4D) ///< ANT stack - request message ID -#define MESG_BROADCAST_DATA_ID ((uint8_t)0x4E) ///< ANT stack - broadcast message ID -#define MESG_ACKNOWLEDGED_DATA_ID ((uint8_t)0x4F) ///< ANT stack - acknowledged message ID -#define MESG_BURST_DATA_ID ((uint8_t)0x50) ///< ANT stack - burst message ID -#define MESG_CHANNEL_ID_ID ((uint8_t)0x51) ///< ANT stack - channel ID message ID -#define MESG_CHANNEL_STATUS_ID ((uint8_t)0x52) ///< ANT stack - channel status message ID -#define MESG_RADIO_CW_INIT_ID ((uint8_t)0x53) ///< ANT stack - CW test mode init message ID -#define MESG_CAPABILITIES_ID ((uint8_t)0x54) ///< ANT stack - capabilities message ID -//... -#define MESG_ID_LIST_ADD_ID ((uint8_t)0x59) ///< ANT stack - inc/exc list add message ID -#define MESG_ID_LIST_CONFIG_ID ((uint8_t)0x5A) ///< ANT stack - inc/exc list config message ID -#define MESG_OPEN_RX_SCAN_ID ((uint8_t)0x5B) ///< ANT stack - rx scanning channel open message ID -#define MESG_EXT_BROADCAST_DATA_ID ((uint8_t)0x5D) ///< ANT application - extended broadcast message ID -#define MESG_EXT_ACKNOWLEDGED_DATA_ID ((uint8_t)0x5E) ///< ANT application - extended acknowledged message ID -#define MESG_EXT_BURST_DATA_ID ((uint8_t)0x5F) ///< ANT application - extended burst message ID -#define MESG_CHANNEL_RADIO_TX_POWER_ID ((uint8_t)0x60) ///< ANT stack - channel transmit power message ID -#define MESG_GET_SERIAL_NUM_ID ((uint8_t)0x61) ///< ANT application - device serial number request message ID -#define MESG_SET_LP_SEARCH_TIMEOUT_ID ((uint8_t)0x63) ///< ANT stack - channel (low priority) search timeout message ID -#define MESG_SERIAL_NUM_SET_CHANNEL_ID_ID ((uint8_t)0x65) ///< ANT application - use serial number to set channel message ID -#define MESG_RX_EXT_MESGS_ENABLE_ID ((uint8_t)0x66) ///< ANT stack - extended rx message enable message ID -#define MESG_ANTLIB_CONFIG_ID ((uint8_t)0x6E) ///< ANT stack - lib config message ID -#define MESG_STARTUP_MESG_ID ((uint8_t)0x6F) ///< ANT application - startup message ID -#define MESG_AUTO_FREQ_CONFIG_ID ((uint8_t)0x70) ///< ANT stack - frequency agility config message ID -#define MESG_PROX_SEARCH_CONFIG_ID ((uint8_t)0x71) ///< ANT stack - proximity search config message ID -#define MESG_ADV_BURST_DATA_ID ((uint8_t)0x72) ///< ANT stack - advanced burst data message ID -#define MESG_COEX_PRIORITY_CONFIG_ID ((uint8_t)0x73) ///< ANT stack - coexistence priority config message ID -#define MESG_EVENT_BUFFERING_CONFIG_ID ((uint8_t)0x74) ///< ANT application - event buffering config message ID -#define MESG_SET_SEARCH_CH_PRIORITY_ID ((uint8_t)0x75) ///< ANT stack - search channel priority config message ID -#define MESG_CONFIG_ADV_BURST_ID ((uint8_t)0x78) ///< ANT stack - advanced burst config message ID -#define MESG_EVENT_FILTER_CONFIG_ID ((uint8_t)0x79) ///< ANT stack - event filtering config message ID -#define MESG_SDU_CONFIG_ID ((uint8_t)0x7A) ///< ANT stack - selective data update config message ID -#define MESG_SDU_SET_MASK_ID ((uint8_t)0x7B) ///< ANT stack - selective data update mask message ID -#define MESG_ENCRYPT_ENABLE_ID ((uint8_t)0x7D) ///< ANT stack - channel encryption mode enable message ID -#define MESG_SET_ENCRYPT_KEY_ID ((uint8_t)0x7E) ///< ANT stack - channel encryption key config message ID -#define MESG_SET_ENCRYPT_INFO_ID ((uint8_t)0x7F) ///< ANT stack - channel encryption info config message ID -#define MESG_ACTIVE_SEARCH_SHARING_ID ((uint8_t)0x81) ///< ANT stack - active seach sharing config message ID -#define MESG_COEX_ADV_PRIORITY_CONFIG_ID ((uint8_t)0x82) ///< ANT stack - advanced/platform specific coexistence priority config message ID -#define MESG_RFACTIVE_NOTIFICATION_ID ((uint8_t)0x84) ///< ANT stack - RF active notification config message ID -/** @} */ - -////////////////////////////////////////////// -/** @name Extended Message ID's -@{ */ -////////////////////////////////////////////// -#define MSG_EXT_ID_MASK ((uint8_t)0xE0) ///< ANT message ID extension mask -#define MESG_EXT_ID_0 ((uint8_t)0xE0) ///< ANT message ID extension 0xE1 -#define MESG_EXT_ID_1 ((uint8_t)0xE1) ///< ANT message ID 0xE1 extension -#define MESG_EXT_ID_2 ((uint8_t)0xE2) ///< ANT message ID 0xE2 extension -#define MESG_EXT_ID_3 ((uint8_t)0xE3) ///< ANT message ID 0xE3 extension -#define MESG_EXT_ID_4 ((uint8_t)0xE4) ///< ANT message ID 0xE4 extension - -// 0xE0 extended IDs -#define MESG_EXT_RESPONSE_ID ((uint16_t)0xE000) ///< Reserved for future use. ANT response messages using extended message IDs - -// 0xE1 extended IDs -#define MESG_EXT_REQUEST_ID ((uint16_t)0xE100) ///< Reserved for future use. ANT request messages using extended message IDs - - -// 0xE3 extended IDs -#define MESG_SET_SYNC_SERIAL_BIT_RATE ((uint16_t)0xE300) ///< ANT application - configure byte synchronous serial interface bit rate -#define MESG_SET_SYNC_SERIAL_SRDY_SLEEP ((uint16_t)0xE301) ///< ANT application - configure byte synchronous serial interface SRDY sleep delay - -// 0xE4 extended IDs -#define MESG_ANTFS_OTA_FW_UPDATE ((uint16_t)0xE400) ///< ANT application - run ANTFS over-the-air (OTA) device firmware update -/** @} */ - -////////////////////////////////////////////// -/** @name Debug Message ID's -@{ */ -////////////////////////////////////////////// -#define MESG_DEBUG_ID ((uint8_t)0xF0) // ANT application - debug message ID. Uses sub-index identifiers to differentiate message types -/** @} */ - -////////////////////////////////////////////// -/** @name Message Sizes -@{ */ -////////////////////////////////////////////// -#define MESG_INVALID_SIZE ((uint8_t)0) -#define MESG_VERSION_SIZE ((uint8_t)13) -#define MESG_RESPONSE_EVENT_SIZE ((uint8_t)3) -#define MESG_CHANNEL_STATUS_SIZE ((uint8_t)2) -#define MESG_UNASSIGN_CHANNEL_SIZE ((uint8_t)1) -#define MESG_ASSIGN_CHANNEL_SIZE ((uint8_t)3) -#define MESG_CHANNEL_ID_SIZE ((uint8_t)5) -#define MESG_CHANNEL_MESG_PERIOD_SIZE ((uint8_t)3) -#define MESG_CHANNEL_SEARCH_TIMEOUT_SIZE ((uint8_t)2) -#define MESG_CHANNEL_RADIO_FREQ_SIZE ((uint8_t)2) -#define MESG_CHANNEL_RADIO_TX_POWER_SIZE ((uint8_t)2) -#define MESG_NETWORK_KEY_SIZE ((uint8_t)9) -#define MESG_RADIO_TX_POWER_SIZE ((uint8_t)2) -#define MESG_RADIO_CW_MODE_SIZE ((uint8_t)3) -#define MESG_RADIO_CW_INIT_SIZE ((uint8_t)1) -#define MESG_SEARCH_WAVEFORM_SIZE ((uint8_t)3) -#define MESG_SYSTEM_RESET_SIZE ((uint8_t)1) -#define MESG_OPEN_CHANNEL_SIZE ((uint8_t)1) -#define MESG_CLOSE_CHANNEL_SIZE ((uint8_t)1) -#define MESG_REQUEST_SIZE ((uint8_t)2) -#define MESG_CAPABILITIES_SIZE ((uint8_t)8) -#define MESG_ID_LIST_ADD_SIZE ((uint8_t)6) -#define MESG_ID_LIST_CONFIG_SIZE ((uint8_t)3) -#define MESG_OPEN_RX_SCAN_SIZE ((uint8_t)2) -#define MESG_EXT_CHANNEL_RADIO_FREQ_SIZE ((uint8_t)3) -#define MESG_RADIO_CONFIG_ALWAYS_SIZE ((uint8_t)2) -#define MESG_RX_EXT_MESGS_ENABLE_SIZE ((uint8_t)2) -#define MESG_SET_TX_SEARCH_ON_NEXT_SIZE ((uint8_t)2) -#define MESG_SET_LP_SEARCH_TIMEOUT_SIZE ((uint8_t)2) -#define MESG_GET_SERIAL_NUM_SIZE ((uint8_t)4) -#define MESG_ANTLIB_CONFIG_SIZE ((uint8_t)2) -#define MESG_STARTUP_MESG_SIZE ((uint8_t)1) -#define MESG_AUTO_FREQ_CONFIG_SIZE ((uint8_t)4) -#define MESG_PROX_SEARCH_CONFIG_SIZE ((uint8_t)2) -#define MESG_COEX_PRIORITY_CONFIG_REQ_SIZE ((uint8_t)9) -#define MESG_EVENT_BUFFERING_CONFIG_REQ_SIZE ((uint8_t)6) -#define MESG_CONFIG_ADV_BURST_REQ_CAPABILITIES_SIZE ((uint8_t)4) -#define MESG_CONFIG_ADV_BURST_REQ_CONFIG_SIZE ((uint8_t)10) -#define MESG_CONFIG_ENCRYPT_REQ_CAPABILITIES_SIZE ((uint8_t)2) -#define MESG_CONFIG_ENCRYPT_REQ_CONFIG_ID_SIZE ((uint8_t)5) -#define MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE ((uint8_t)20) -#define MESG_CONFIG_ENCRYPT_REQ_CURRENT_CTR ((uint8_t)17) -#define MESG_EVENT_FILTER_CONFIG_REQ_SIZE ((uint8_t)3) -#define MESG_ACTIVE_SEARCH_SHARING_REQ_SIZE ((uint8_t)2) -#define MESG_COEX_ADV_PRIORITY_CONFIG_REQ_SIZE ((uint8_t)9) -#define MESG_RFACTIVE_NOTIFICATION_SIZE ((uint8_t)4) -#define MESG_FLASH_PROTECTION_CHECK_SIZE ((uint8_t)1) -#define MESG_BIST_SIZE ((uint8_t)6) -/** @} */ - -////////////////////////////////////////////// -/* ANT Message Structure */ -////////////////////////////////////////////// -/** @cond */ -typedef union -{ - uint8_t ucExtMesgBF; - struct - { - uint8_t bExtFieldCont : 1; - uint8_t : 1; - uint8_t : 1; - uint8_t : 1; - uint8_t : 1; - uint8_t bANTTimeStamp : 1; - uint8_t bANTRssi : 1; - uint8_t bANTDeviceID : 1; - }stExtMesgBF; - -} EXT_MESG_BF; // extended message bitfield - -typedef union -{ - uint32_t ulForceAlign; // force the struct to be 4-byte aligned, required for some casting in command.c - uint8_t aucMessage[MESG_BUFFER_SIZE]; // the complete message buffer pointer - struct - { - uint8_t ucSize; // the message size - union - { - uint8_t aucFramedData[MESG_FRAMED_SIZE]; // pointer for serial framer - struct - { - uint8_t ucMesgID; // the message ID - union - { - uint8_t aucMesgData[MESG_MAX_SIZE_VALUE]; // the message data - struct - { - union - { - uint8_t ucChannel; // ANT channel number - uint8_t ucSubID; // subID portion of ext ID message - }uData0; - uint8_t aucPayload[ANT_STANDARD_DATA_PAYLOAD_SIZE]; // ANT message payload - EXT_MESG_BF sExtMesgBF; // extended message bitfield (NOTE: this will not be here for longer data messages) - uint8_t aucExtData[MESG_MAX_EXT_DATA_SIZE]; // extended message data - }stMesgData; - }uMesgData; - }stFramedData; - }uFramedData; - uint8_t ucCheckSum; // the message checksum - }stMessage; - -} ANT_MESSAGE; -/* @endcond */ - -/** @brief Defines for accesssing ANT_MESSAGE members variables */ -/** @name ANT serial message structure -@{ */ -#define ANT_MESSAGE_ulForceAlign ulForceAlign -#define ANT_MESSAGE_aucMessage aucMessage -#define ANT_MESSAGE_ucSize stMessage.ucSize -#define ANT_MESSAGE_aucFramedData stMessage.uFramedData.aucFramedData -#define ANT_MESSAGE_ucMesgID stMessage.uFramedData.stFramedData.ucMesgID -#define ANT_MESSAGE_aucMesgData stMessage.uFramedData.stFramedData.uMesgData.aucMesgData -#define ANT_MESSAGE_ucChannel stMessage.uFramedData.stFramedData.uMesgData.stMesgData.uData0.ucChannel -#define ANT_MESSAGE_ucSubID stMessage.uFramedData.stFramedData.uMesgData.stMesgData.uData0.ucSubID -#define ANT_MESSAGE_aucPayload stMessage.uFramedData.stFramedData.uMesgData.stMesgData.aucPayload -#define ANT_MESSAGE_sExtMesgBF stMessage.uFramedData.stFramedData.uMesgData.stMesgData.sExtMesgBF -#define ANT_MESSAGE_ucExtMesgBF stMessage.uFramedData.stFramedData.uMesgData.stMesgData.sExtMesgBF.ucExtMesgBF -#define ANT_MESSAGE_stExtMesgBF stMessage.uFramedData.stFramedData.uMesgData.stMesgData.sExtMesgBF.stExtMesgBF -#define ANT_MESSAGE_aucExtData stMessage.uFramedData.stFramedData.uMesgData.stMesgData.aucExtData -#define ANT_MESSAGE_ucCheckSum stMessage.ucCheckSum -/** @} */ - -#endif // !ANTMESSAGE_H - -/** - @} - */ diff --git a/components/softdevice/s210/headers/nrf_error.h b/components/softdevice/s210/headers/nrf_error.h deleted file mode 100644 index d580aa3..0000000 --- a/components/softdevice/s210/headers/nrf_error.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - /** - @defgroup nrf_error SoftDevice Global Error Codes - @{ - - @brief Global Error definitions -*/ - -/* Header guard */ -#ifndef NRF_ERROR_H__ -#define NRF_ERROR_H__ - -/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions - * @{ */ -#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base -#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base -#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base -#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base -/** @} */ - -#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command -#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing -#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled -#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error -#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation -#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found -#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported -#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter -#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state -#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length -#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags -#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data -#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit -#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out -#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer -#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation -#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address -#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy - -#endif // NRF_ERROR_H__ - -/** - @} -*/ diff --git a/components/softdevice/s210/headers/nrf_error_soc.h b/components/softdevice/s210/headers/nrf_error_soc.h deleted file mode 100644 index d80d626..0000000 --- a/components/softdevice/s210/headers/nrf_error_soc.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - @addtogroup nrf_soc_api - @{ - @defgroup nrf_soc_error SoC Library Error Codes - @{ - - @brief Error definitions for the SoC library - -*/ - -/* Header guard */ -#ifndef NRF_ERROR_SOC_H__ -#define NRF_ERROR_SOC_H__ - -#include "nrf_error.h" - -/* Mutex Errors */ -#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken - -/* NVIC errors */ -#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available -#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed -#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return - -/* Power errors */ -#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown -#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown -#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return - -/* Rand errors */ -#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values - -/* PPI errors */ -#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel -#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group - -#endif // NRF_ERROR_SOC_H__ -/** - @} - @} -*/ diff --git a/components/softdevice/s210/headers/nrf_mbr.h b/components/softdevice/s210/headers/nrf_mbr.h deleted file mode 100644 index 3ac6dbf..0000000 --- a/components/softdevice/s210/headers/nrf_mbr.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - @defgroup nrf_mbr_api Master Boot Record API - @{ - - @brief APIs for updating SoftDevice and BootLoader - -*/ - -/* Header guard */ -#ifndef NRF_MBR_H__ -#define NRF_MBR_H__ - -#include "nrf_svc.h" -#include - - -/** @addtogroup NRF_MBR_DEFINES Defines - * @{ */ - -/**@brief MBR SVC Base number. */ -#define MBR_SVC_BASE (0x18) - -/** @} */ - -/** @addtogroup NRF_MBR_ENUMS Enumerations - * @{ */ - -/**@brief nRF Master Boot Record API SVC numbers. */ -enum NRF_MBR_SVCS -{ - SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */ -}; - -/**@brief Possible values for ::sd_mbr_command_t.command */ -enum NRF_MBR_COMMANDS -{ - SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see sd_mbr_command_copy_bl_t */ - SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ - SD_MBR_COMMAND_INIT_SD, /**< Init forwarding interrupts to SD, and run reset function in SD*/ - SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ - SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Start forwarding all exception to this address @see ::sd_mbr_command_vector_table_base_set_t*/ -}; - -/** @} */ - -/** @addtogroup NRF_MBR_TYPES Types - * @{ */ - -/**@brief This command copies part of a new SoftDevice - * The destination area is erased before copying. - * If dst is in the middle of a flash page, that whole flash page will be erased. - * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. - * - * The user of this function is responsible for setting the PROTENSET registers. - * - * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. - * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. - */ -typedef struct -{ - uint32_t *src; /**< Pointer to the source of data to be copied.*/ - uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ - uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of PAGE_SIZE_IN_WORDS words.*/ -} sd_mbr_command_copy_sd_t; - - -/**@brief This command works like memcmp, but takes the length in words. - * - * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal. - * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal. - */ -typedef struct -{ - uint32_t *ptr1; /**< Pointer to block of memory. */ - uint32_t *ptr2; /**< Pointer to block of memory. */ - uint32_t len; /**< Number of 32 bit words to compare.*/ -} sd_mbr_command_compare_t; - - -/**@brief This command copies a new BootLoader. - * With this command, destination of BootLoader is always the address written in NRF_UICR->BOOTADDR. - * - * Destination is erased by this function. - * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased. - * - * This function will use PROTENSET to protect the flash that is not intended to be written. - * - * On Success, this function will not return. It will start the new BootLoader from reset-vector as normal. - * - * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. - * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. - * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area. - */ -typedef struct -{ - uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/ - uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */ -} sd_mbr_command_copy_bl_t; - -/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR - * - * Once this function has been called, this address is where the MBR will start to forward interrupts to after a reset. - * - * To restore default forwarding this function should be called with @param address set to 0. - * The MBR will then start forwarding to interrupts to the adress in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. - * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size. - */ -typedef struct -{ - uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ -} sd_mbr_command_vector_table_base_set_t; - -typedef struct -{ - uint32_t command; /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */ - union - { - sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ - sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader.*/ - sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ - sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set.*/ - } params; -} sd_mbr_command_t; - -/** @} */ - -/** @addtogroup NRF_MBR_FUNCTIONS Functions - * @{ */ - -/**@brief Issue Master Boot Record commands - * - * Commands used when updating a SoftDevice and bootloader. - * - * @param[in] param Pointer to a struct describing the command. - * - *@note for retvals see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t - -*/ -SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); - -/** @} */ -#endif // NRF_MBR_H__ - -/** - @} -*/ diff --git a/components/softdevice/s210/headers/nrf_sd_def.h b/components/softdevice/s210/headers/nrf_sd_def.h deleted file mode 100644 index 4740cd8..0000000 --- a/components/softdevice/s210/headers/nrf_sd_def.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_SD_DEF_H__ -#define NRF_SD_DEF_H__ - -#include - -#define SD_PPI_CHANNELS_USED 0xFFF0C000uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */ -#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ -#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ -#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ - -#endif /* NRF_SD_DEF_H__ */ diff --git a/components/softdevice/s210/headers/nrf_sdm.h b/components/softdevice/s210/headers/nrf_sdm.h deleted file mode 100644 index 63a89ab..0000000 --- a/components/softdevice/s210/headers/nrf_sdm.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - @defgroup nrf_sdm_api SoftDevice Manager API - @{ - - @brief APIs for SoftDevice management. - -*/ - -/* Header guard */ -#ifndef NRF_SDM_H__ -#define NRF_SDM_H__ - -#include "nrf_svc.h" -#include "nrf51.h" -#include "nrf_soc.h" -#include "nrf_error_sdm.h" - -/** @addtogroup NRF_SDM_DEFINES Defines - * @{ */ - -/** @brief SoftDevice Manager SVC Base number. */ -#define SDM_SVC_BASE 0x10 - -/** @} */ - -/** @brief Defines the SoftDevice Information Structure location (address) as an offset from -the start of the softdevice (without MBR)*/ -#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) - -/** @brief Defines the usual size reserverd for the MBR when a softdevice is written to flash. -This is the offset where the first byte of the softdevice hex file is written.*/ -#define MBR_SIZE (0x1000) - -/** @brief Defines the absolute Softdevice information structure location (address)*/ -#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) - -/** @brief Defines the offset for Softdevice size value relative to Softdevice base address*/ -#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) - -/** @brief Defines the offset for FWID value relative to Softdevice base address*/ -#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) - -/** @brief Defines a macro for retreiving the actual Softdevice size value from a given base address - use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/ -#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) - -/** @brief Defines a macro for retreiving the actual FWID value from a given base address - use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/ -#define SD_FWID_GET(baseaddr) ((*((uint32_t *) ((baseaddr) + SD_FWID_OFFSET))) & 0xFFFF) - - -/** @addtogroup NRF_SDM_ENUMS Enumerations - * @{ */ - -/**@brief nRF SoftDevice Manager API SVC numbers. */ -enum NRF_SD_SVCS -{ - SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ - SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ - SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ - SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ - SVC_SDM_LAST /**< Placeholder for last SDM SVC */ -}; - -/**@brief Possible lfclk oscillator sources. */ -enum NRF_CLOCK_LFCLKSRCS -{ - NRF_CLOCK_LFCLKSRC_SYNTH_250_PPM, /**< LFCLK Synthesized from HFCLK. */ - NRF_CLOCK_LFCLKSRC_XTAL_500_PPM, /**< LFCLK crystal oscillator 500 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_250_PPM, /**< LFCLK crystal oscillator 250 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_150_PPM, /**< LFCLK crystal oscillator 150 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_100_PPM, /**< LFCLK crystal oscillator 100 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_75_PPM, /**< LFCLK crystal oscillator 75 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, /**< LFCLK crystal oscillator 50 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_30_PPM, /**< LFCLK crystal oscillator 30 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, /**< LFCLK crystal oscillator 20 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION, /**< LFCLK RC oscillator, 250ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_500MS_CALIBRATION, /**< LFCLK RC oscillator, 500ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_1000MS_CALIBRATION, /**< LFCLK RC oscillator, 1000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_2000MS_CALIBRATION, /**< LFCLK RC oscillator, 2000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, /**< LFCLK RC oscillator, 4000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_8000MS_CALIBRATION, /**< LFCLK RC oscillator, 8000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_1000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 1000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_2000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 2000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_4000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 4000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_8000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 8000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_16000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 16000ms, if changed above a threshold, a calibration is done.*/ -}; - -/** @} */ - -/** @addtogroup NRF_SDM_TYPES Types - * @{ */ - -/**@brief Type representing lfclk oscillator source. */ -typedef uint32_t nrf_clock_lfclksrc_t; - - -/**@brief SoftDevice Assertion Handler type. - * - * When an unexpected error occurs within the SoftDevice it will call the SoftDevice assertion handler callback. - * The protocol stack will be in an undefined state when this happens and the only way to recover will be to - * perform a reset, using e.g. CMSIS NVIC_SystemReset(). - * - * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the SoftDevice assert callback. - * - * @param[in] pc The program counter of the failed assert. - * @param[in] line_number Line number where the assert failed. - * @param[in] file_name File name where the assert failed. - */ -typedef void (*softdevice_assertion_handler_t)(uint32_t pc, uint16_t line_number, const uint8_t * p_file_name); - -/** @} */ - -/** @addtogroup NRF_SDM_FUNCTIONS Functions - * @{ */ - -/**@brief Enables the SoftDevice and by extension the protocol stack. - * - * Idempotent function to enable the SoftDevice. - * - * @note Some care must be taken if a low frequency clock source is already running when calling this function: - * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new - * clock source will be started. - * - * @note This function has no effect when returning with an error. - * - * @post If return code is ::NRF_SUCCESS - * - SoC library and protocol stack APIs are made available. - * - A portion of RAM will be unavailable (see relevant SDS documentation). - * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). - * - Interrupts will not arrive from protected peripherals or interrupts. - * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the softdevice. - * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). - * - Chosen low frequency clock source will be running. - * - * @param clock_source Low frequency clock source and accuracy. (Note: In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock). - * @param assertion_handler Callback for SoftDevice assertions. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and assertion handler cannot be updated. - * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDeviceinterrupt is already enabled, or an enabled interrupt has an illegal priority level. - * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. - */ -SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lfclksrc_t clock_source, softdevice_assertion_handler_t assertion_handler)); - -/**@brief Disables the SoftDevice and by extension the protocol stack. - * - * Idempotent function to disable the SoftDevice. - * - * @post SoC library and protocol stack APIs are made unavailable. - * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). - * @post All peripherals used by the SoftDevice will be reset to default values. - * @post All of RAM become available. - * @post All interrupts are forwarded to the application. - * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); - -/**@brief Check if the SoftDevice is enabled. - * - * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); - -/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice - * - * This function is only intended to be called when a bootloader is enabled. - * - * @param[in] address The base address of the interrupt vector table for forwarded interrupts. - - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); - -/** @} */ - -#endif // NRF_SDM_H__ - -/** - @} -*/ diff --git a/components/softdevice/s210/headers/nrf_soc.h b/components/softdevice/s210/headers/nrf_soc.h deleted file mode 100644 index c1f9428..0000000 --- a/components/softdevice/s210/headers/nrf_soc.h +++ /dev/null @@ -1,993 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - * @defgroup nrf_soc_api SoC Library API - * @{ - * - * @brief APIs for the SoC library. - * - */ - -#ifndef NRF_SOC_H__ -#define NRF_SOC_H__ - -#include -#include -#include "nrf_svc.h" -#include "nrf51.h" -#include "nrf51_bitfields.h" -#include "nrf_error_soc.h" - -/**@addtogroup NRF_SOC_DEFINES Defines - * @{ */ - -/**@brief The number of the lowest SVC number reserved for the SoC library. */ -#define SOC_SVC_BASE (0x20) -#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) - -/**@brief Guranteed time for application to process radio inactive notification. */ -#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) - -/**@brief The minimum allowed timeslot extension time. */ -#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200) - -#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */ -#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ -#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ - -#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ -#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */ -#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ -#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. */ - -#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ -#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ - -#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */ - -#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */ - -#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */ - -/**@} */ - -/**@addtogroup NRF_SOC_TYPES Types - * @{ */ - -/**@brief The SVC numbers used by the SVC functions in the SoC library. */ -enum NRF_SOC_SVCS -{ - SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE, - SD_PPI_CHANNEL_ENABLE_SET, - SD_PPI_CHANNEL_ENABLE_CLR, - SD_PPI_CHANNEL_ASSIGN, - SD_PPI_GROUP_TASK_ENABLE, - SD_PPI_GROUP_TASK_DISABLE, - SD_PPI_GROUP_ASSIGN, - SD_PPI_GROUP_GET, - SD_FLASH_PAGE_ERASE, - SD_FLASH_WRITE, - SD_FLASH_PROTECT, - SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, - SD_MUTEX_ACQUIRE, - SD_MUTEX_RELEASE, - SD_NVIC_ENABLEIRQ, - SD_NVIC_DISABLEIRQ, - SD_NVIC_GETPENDINGIRQ, - SD_NVIC_SETPENDINGIRQ, - SD_NVIC_CLEARPENDINGIRQ, - SD_NVIC_SETPRIORITY, - SD_NVIC_GETPRIORITY, - SD_NVIC_SYSTEMRESET, - SD_NVIC_CRITICAL_REGION_ENTER, - SD_NVIC_CRITICAL_REGION_EXIT, - SD_RAND_APPLICATION_POOL_CAPACITY, - SD_RAND_APPLICATION_BYTES_AVAILABLE, - SD_RAND_APPLICATION_GET_VECTOR, - SD_POWER_MODE_SET, - SD_POWER_SYSTEM_OFF, - SD_POWER_RESET_REASON_GET, - SD_POWER_RESET_REASON_CLR, - SD_POWER_POF_ENABLE, - SD_POWER_POF_THRESHOLD_SET, - SD_POWER_RAMON_SET, - SD_POWER_RAMON_CLR, - SD_POWER_RAMON_GET, - SD_POWER_GPREGRET_SET, - SD_POWER_GPREGRET_CLR, - SD_POWER_GPREGRET_GET, - SD_POWER_DCDC_MODE_SET, - SD_APP_EVT_WAIT, - SD_CLOCK_HFCLK_REQUEST, - SD_CLOCK_HFCLK_RELEASE, - SD_CLOCK_HFCLK_IS_RUNNING, - SD_RADIO_NOTIFICATION_CFG_SET, - SD_ECB_BLOCK_ENCRYPT, - SD_RADIO_SESSION_OPEN, - SD_RADIO_SESSION_CLOSE, - SD_RADIO_REQUEST, - SD_EVT_GET, - SD_TEMP_GET, - SVC_SOC_LAST -}; - -/**@brief Possible values of a ::nrf_mutex_t. */ -enum NRF_MUTEX_VALUES -{ - NRF_MUTEX_FREE, - NRF_MUTEX_TAKEN -}; - -/**@brief Possible values of ::nrf_app_irq_priority_t. */ -enum NRF_APP_PRIORITIES -{ - NRF_APP_PRIORITY_HIGH = 1, - NRF_APP_PRIORITY_LOW = 3 -}; - -/**@brief Possible values of ::nrf_power_mode_t. */ -enum NRF_POWER_MODES -{ - NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ - NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ -}; - - -/**@brief Possible values of ::nrf_power_failure_threshold_t */ -enum NRF_POWER_THRESHOLDS -{ - NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V27 /**< 2.7 Volts power failure threshold. */ -}; - - -/**@brief Possible values of ::nrf_power_dcdc_mode_t. */ -enum NRF_POWER_DCDC_MODES -{ - NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ - NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ -}; - -/**@brief Possible values of ::nrf_radio_notification_distance_t. */ -enum NRF_RADIO_NOTIFICATION_DISTANCES -{ - NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ - NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */ -}; - - -/**@brief Possible values of ::nrf_radio_notification_type_t. */ -enum NRF_RADIO_NOTIFICATION_TYPES -{ - NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ -}; - -/**@brief SoC Events. */ -enum NRF_SOC_EVTS -{ - NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ - NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ - NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ - NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ - NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ - NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ - NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio signal callback handler return was invalid. */ - NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio session is idle. */ - NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio session is closed. */ - NRF_EVT_NUMBER_OF_EVTS -}; - -/**@} */ - -/**@addtogroup NRF_SOC_TYPES Types - * @{ */ - -/**@brief Represents a mutex for use with the nrf_mutex functions. - * @note Accessing the value directly is not safe, use the mutex functions! - */ -typedef volatile uint8_t nrf_mutex_t; - -/**@brief The interrupt priorities available to the application while the softdevice is active. */ -typedef uint8_t nrf_app_irq_priority_t; - -/**@brief Represents a power mode, used in power mode functions */ -typedef uint8_t nrf_power_mode_t; - -/**@brief Represents a power failure threshold value. */ -typedef uint8_t nrf_power_failure_threshold_t; - -/**@brief Represents a DCDC mode value. */ -typedef uint32_t nrf_power_dcdc_mode_t; - -/**@brief Radio notification distances. */ -typedef uint8_t nrf_radio_notification_distance_t; - -/**@brief Radio notification types. */ -typedef uint8_t nrf_radio_notification_type_t; - -/**@brief The Radio signal callback types. */ -enum NRF_RADIO_CALLBACK_SIGNAL_TYPE -{ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */ -}; - -/**@brief The actions requested by the signal callback. - * - * This code gives the SOC instructions about what action to take when the signal callback has - * returned. - */ -enum NRF_RADIO_SIGNAL_CALLBACK_ACTION -{ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current timeslot (maximum execution time for this action is when the extension succeeded). */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ -}; - -/**@brief Radio timeslot high frequency clock source configuration. */ -enum NRF_RADIO_HFCLK_CFG -{ - NRF_RADIO_HFCLK_CFG_DEFAULT, /**< Use the currently selected oscillator as HF clock source during the timeslot (i.e. the source is not specified). */ - NRF_RADIO_HFCLK_CFG_FORCE_XTAL, /**< Force external crystal to be used as HF clock source during whole the timeslot. */ -}; - -/**@brief Radio timeslot priorities. */ -enum NRF_RADIO_PRIORITY -{ - NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */ - NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activites of the SoftDevice stack(s)). */ -}; - -/**@brief Radio timeslot request type. */ -enum NRF_RADIO_REQUEST_TYPE -{ - NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request timeslot as early as possible. This should always be used for the first request in a session. */ - NRF_RADIO_REQ_TYPE_NORMAL /**< Normal timeslot request. */ -}; - -/**@brief Parameters for a request for a timeslot as early as possible. */ -typedef struct -{ - uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ - uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ - uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */ - uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ -} nrf_radio_request_earliest_t; - -/**@brief Parameters for a normal radio request. */ -typedef struct -{ - uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ - uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ - uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */ - uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ -} nrf_radio_request_normal_t; - -/**@brief Radio request parameters. */ -typedef struct -{ - uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ - union - { - nrf_radio_request_earliest_t earliest; /**< Parameters for a request for a timeslot as early as possible. */ - nrf_radio_request_normal_t normal; /**< Parameters for a normal radio request. */ - } params; -} nrf_radio_request_t; - -/**@brief Return parameters of the radio timeslot signal callback. */ -typedef struct -{ - uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */ - union - { - struct - { - nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */ - } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ - struct - { - uint32_t length_us; /**< Requested extension of the timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ - } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ - } params; -} nrf_radio_signal_callback_return_param_t; - -/**@brief The radio signal callback type. - * - * @note In case of invalid return parameters, the radio timeslot will automatically end - * immediately after returning from the signal callback and the - * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent. - * @note The returned struct pointer must remain valid after the signal callback - * function returns. For instance, this means that it must not point to a stack variable. - * - * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE. - * - * @return Pointer to structure containing action requested by the application. - */ -typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); - -/**@brief AES ECB data structure */ -typedef struct -{ - uint8_t key[SOC_ECB_KEY_LENGTH]; /**< Encryption key. */ - uint8_t cleartext[SOC_ECB_CLEARTEXT_LENGTH]; /**< Clear Text data. */ - uint8_t ciphertext[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Cipher Text data. */ -} nrf_ecb_hal_data_t; - -/**@} */ - -/**@addtogroup NRF_SOC_FUNCTIONS Functions - * @{ */ - -/**@brief Initialize a mutex. - * - * @param[in] p_mutex Pointer to the mutex to initialize. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex)); - -/**@brief Attempt to acquire a mutex. - * - * @param[in] p_mutex Pointer to the mutex to acquire. - * - * @retval ::NRF_SUCCESS The mutex was successfully acquired. - * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired. - */ -SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); - -/**@brief Release a mutex. - * - * @param[in] p_mutex Pointer to the mutex to release. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); - -/**@brief Enable External Interrupt. - * @note Corresponds to NVIC_EnableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was enabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. - */ -SVCALL(SD_NVIC_ENABLEIRQ, uint32_t, sd_nvic_EnableIRQ(IRQn_Type IRQn)); - -/**@brief Disable External Interrupt. - * @note Corresponds to NVIC_DisableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was disabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - */ -SVCALL(SD_NVIC_DISABLEIRQ, uint32_t, sd_nvic_DisableIRQ(IRQn_Type IRQn)); - -/**@brief Get Pending Interrupt. - * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. - * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. - * - * @retval ::NRF_SUCCESS The interrupt is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_GETPENDINGIRQ, uint32_t, sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)); - -/**@brief Set Pending Interrupt. - * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt is set pending. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_SETPENDINGIRQ, uint32_t, sd_nvic_SetPendingIRQ(IRQn_Type IRQn)); - -/**@brief Clear Pending Interrupt. - * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_CLEARPENDINGIRQ, uint32_t, sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)); - -/**@brief Set Interrupt Priority. - * @note Corresponds to NVIC_SetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * @pre Priority is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. - * @param[in] priority A valid IRQ priority for use by the application. - * - * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. - */ -SVCALL(SD_NVIC_SETPRIORITY, uint32_t, sd_nvic_SetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t priority)); - -/**@brief Get Interrupt Priority. - * @note Corresponds to NVIC_GetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. - * @param[out] p_priority Return value from NVIC_GetPriority. - * - * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. - */ -SVCALL(SD_NVIC_GETPRIORITY, uint32_t, sd_nvic_GetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t * p_priority)); - -/**@brief System Reset. - * @note Corresponds to NVIC_SystemReset in CMSIS. - * - * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN - */ -SVCALL(SD_NVIC_SYSTEMRESET, uint32_t, sd_nvic_SystemReset(void)); - -/**@brief Enters critical region. - * - * @post Application interrupts will be disabled. - * @sa sd_nvic_critical_region_exit - * - * @param[out] p_is_nested_critical_region 1: If in a nested critical region. - * 0: Otherwise. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_NVIC_CRITICAL_REGION_ENTER, uint32_t, sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)); - -/**@brief Exit critical region. - * - * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. - * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. - * - * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_NVIC_CRITICAL_REGION_EXIT, uint32_t, sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)); - -/**@brief Query the capacity of the application random pool. - * - * @param[out] p_pool_capacity The capacity of the pool. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); - -/**@brief Get number of random bytes available to the application. - * - * @param[out] p_bytes_available The number of bytes currently available in the pool. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); - -/**@brief Get random bytes from the application pool. - * - * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. - * @param[in] length Number of bytes to take from pool and place in p_buff. - * - * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. - * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. -*/ -SVCALL(SD_RAND_APPLICATION_GET_VECTOR, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); - -/**@brief Gets the reset reason register. - * - * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason)); - -/**@brief Clears the bits of the reset reason register. - * - * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk)); - -/**@brief Sets the power mode when in CPU sleep. - * - * @param[in] power_mode The power mode to use when in CPU sleep. @sa sd_app_evt_wait - * - * @retval ::NRF_SUCCESS The power mode was set. - * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. - */ -SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(nrf_power_mode_t power_mode)); - -/**@brief Puts the chip in System OFF mode. - * - * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN - */ -SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void)); - -/**@brief Enables or disables the power-fail comparator. - * - * Enabling this will give a softdevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs. - * The event can be retrieved with sd_evt_get(); - * - * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); - -/**@brief Sets the power-fail threshold value. - * - * @param[in] threshold The power-fail threshold value to use. - * - * @retval ::NRF_SUCCESS The power failure threshold was set. - * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. - */ -SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(nrf_power_failure_threshold_t threshold)); - -/**@brief Sets bits in the NRF_POWER->RAMON register. - * - * @param[in] ramon Contains the bits needed to be set in the NRF_POWER->RAMON register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAMON_SET, uint32_t, sd_power_ramon_set(uint32_t ramon)); - -/**@brief Clears bits in the NRF_POWER->RAMON register. - * - * @param ramon Contains the bits needed to be cleared in the NRF_POWER->RAMON register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAMON_CLR, uint32_t, sd_power_ramon_clr(uint32_t ramon)); - -/**@brief Get contents of NRF_POWER->RAMON register, indicates power status of ram blocks. - * - * @param[out] p_ramon Content of NRF_POWER->RAMON register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAMON_GET, uint32_t, sd_power_ramon_get(uint32_t * p_ramon)); - -/**@brief Set bits in the NRF_POWER->GPREGRET register. - * - * @param[in] gpregret_msk Bits to be set in the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_msk)); - -/**@brief Clear bits in the NRF_POWER->GPREGRET register. - * - * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_msk)); - -/**@brief Get contents of the NRF_POWER->GPREGRET register. - * - * @param[out] p_gpregret Contents of the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t *p_gpregret)); - -/**@brief Sets the DCDC mode. - * - * This function is to enable or disable the DCDC periperhal. - * - * @param[in] dcdc_mode The mode of the DCDC. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. - */ -SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(nrf_power_dcdc_mode_t dcdc_mode)); - -/**@brief Request the high frequency crystal oscillator. - * - * Will start the high frequency crystal oscillator, the startup time of the crystal varies - * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started. - * - * @see sd_clock_hfclk_is_running - * @see sd_clock_hfclk_release - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void)); - -/**@brief Releases the high frequency crystal oscillator. - * - * Will stop the high frequency crystal oscillator, this happens immediately. - * - * @see sd_clock_hfclk_is_running - * @see sd_clock_hfclk_request - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void)); - -/**@brief Checks if the high frequency crystal oscillator is running. - * - * @see sd_clock_hfclk_request - * @see sd_clock_hfclk_release - * - * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running)); - -/**@brief Waits for an application event. - * - * An application event is either an application interrupt or a pended interrupt when the - * interrupt is disabled. When the interrupt is enabled it will be taken immediately since - * this function will wait in thread mode, then the execution will return in the application's - * main thread. When an interrupt is disabled and gets pended it will return to the application's - * thread main. The application must ensure that the pended flag is cleared using - * ::sd_nvic_ClearPendingIRQ in order to sleep using this function. This is only necessary for - * disabled interrupts, as the interrupt handler will clear the pending flag automatically for - * enabled interrupts. - * - * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M0 - * System Control Register (SCR). @sa CMSIS_SCB - * - * @note If an application interrupt has happened since the last time sd_app_evt_wait was - * called this function will return immediately and not go to sleep. This is to avoid race - * conditions that can occur when a flag is updated in the interrupt handler and processed - * in the main loop. - * - * @post An application interrupt has happened or a interrupt pending flag is set. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void)); - -/**@brief Get PPI channel enable register contents. - * - * @param[out] p_channel_enable The contents of the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable)); - -/**@brief Set PPI channel enable register. - * - * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)); - -/**@brief Clear PPI channel enable register. - * - * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk)); - -/**@brief Assign endpoints to a PPI channel. - * - * @param[in] channel_num Number of the PPI channel to assign. - * @param[in] evt_endpoint Event endpoint of the PPI channel. - * @param[in] task_endpoint Task endpoint of the PPI channel. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint)); - -/**@brief Task to enable a channel group. - * - * @param[in] group_num Number of the channel group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num)); - -/**@brief Task to disable a channel group. - * - * @param[in] group_num Number of the PPI group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num)); - -/**@brief Assign PPI channels to a channel group. - * - * @param[in] group_num Number of the channel group. - * @param[in] channel_msk Mask of the channels to assign to the group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk)); - -/**@brief Gets the PPI channels of a channel group. - * - * @param[in] group_num Number of the channel group. - * @param[out] p_channel_msk Mask of the channels assigned to the group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk)); - -/**@brief Configures the Radio Notification signal. - * - * @note - * - The notification signal latency depends on the interrupt priority settings of SWI used - * for notification signal. - * - To ensure that the radio notification signal behaves in a consistent way, always - * configure radio notifications when there is no protocol stack or other SoftDevice - * activity in progress. It is recommended that the radio notification signal is - * configured directly after the SoftDevice has been enabled. - * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice - * will interrupt the application to do Radio Event preparation. - * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have - * to shorten the connection events to have time for the Radio Notification signals. - * - * @param[in] type Type of notification signal. - * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio - * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is - * recommended (but not required) to be used with - * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. - * - * @param[in] distance Distance between the notification signal and start of radio activity. - * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or - * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. - * - * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(nrf_radio_notification_type_t type, nrf_radio_notification_distance_t distance)); - -/**@brief Encrypts a block according to the specified parameters. - * - * 128-bit AES encryption. - * - * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input - * parameters and one output parameter). - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); - -/**@brief Gets any pending events generated by the SoC API. - * - * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. - * - * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending. - * - * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter. - * @retval ::NRF_ERROR_NOT_FOUND No pending events. - */ -SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); - -/**@brief Get the temperature measured on the chip - * - * This function will block until the temperature measurement is done. - * It takes around 50us from call to return. - * - * @note Pan #28 in PAN-028 v 1.6 "Negative measured values are not represented correctly" is corrected by this function. - * - * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees celsius. - * - * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp - */ -SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); - -/**@brief Flash Write -* -* Commands to write a buffer to flash -* -* If the SoftDevice is enabled: -* This call initiates the flash access command, and its completion will be communicated to the -* application with exactly one of the following events: -* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. -* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. -* -* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the - * write has been completed -* -* @note -* - This call takes control over the radio and the CPU during flash erase and write to make sure that -* they will not interfere with the flash access. This means that all interrupts will be blocked -* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual -* and the command parameters). -* -* -* @param[in] p_dst Pointer to start of flash location to be written. -* @param[in] p_src Pointer to buffer with data to be written. -* @param[in] size Number of 32-bit words to write. Maximum size is 256 32bit words. -* -* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. -* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. -* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or more than 256 words. -* @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location. -* @retval ::NRF_SUCCESS The command was accepted. -*/ -SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * const p_dst, uint32_t const * const p_src, uint32_t size)); - - -/**@brief Flash Erase page -* -* Commands to erase a flash page -* If the SoftDevice is enabled: -* This call initiates the flash access command, and its completion will be communicated to the -* application with exactly one of the following events: -* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. -* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. -* -* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the -* erase has been completed -* -* @note -* - This call takes control over the radio and the CPU during flash erase and write to make sure that -* they will not interfere with the flash access. This means that all interrupts will be blocked -* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual -* and the command parameters). -* -* -* @param[in] page_number Pagenumber of the page to erase -* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. -* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. -* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. -* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a protected page. -* @retval ::NRF_SUCCESS The command was accepted. -*/ -SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); - - -/**@brief Flash Protection set - * - * Commands to set the flash protection registers PROTENSETx - * - * @note To read the values in PROTENSETx you can read them directly. They are only write-protected. - * - * @param[in] protenset0 Value to be written to PROTENSET0. - * @param[in] protenset1 Value to be written to PROTENSET1. - * - * @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice. - * @retval ::NRF_SUCCESS Values successfully written to PROTENSETx. - */ -SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_t protenset1)); - -/**@brief Opens a session for radio requests. - * - * @note Only one session can be open at a time. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot - * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed - * by the application. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0 - * interrupt occurs. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO - * interrupt occurs. - * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This - * implies that none of the sd_* API calls can be used from p_radio_signal_callback(). - * - * @param[in] p_radio_signal_callback The signal callback. - * - * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer. - * @retval ::NRF_ERROR_BUSY If session cannot be opened. - * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); - -/**@brief Closes a session for radio requests. - * - * @note Any current radio timeslot will be finished before the session is closed. - * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. - * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED - * event is received. - * - * @retval ::NRF_ERROR_FORBIDDEN If session not opened. - * @retval ::NRF_ERROR_BUSY If session is currently being closed. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void)); - -/**@brief Requests a radio timeslot. - * - * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST - * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref - * NRF_RADIO_REQ_TYPE_EARLIEST. - * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by - * p_request->distance_us and is given relative to the start of the previous timeslot. - * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. - * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event. - * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths. - * @note If an opportunity for the first radio timeslot is not found before 100ms after the call to this - * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent. - * The application may then try to schedule the first radio timeslot again. - * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START). - * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS. - * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us. - * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the - * specified radio timeslot start, but this does not affect the actual start time of the timeslot. - * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency - * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is - * guaranteed to be clocked from the external crystal. - * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral - * during the radio timeslot. - * - * @param[in] p_request Pointer to the request parameters. - * - * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE. - * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid. - * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t * p_request )); - -/**@} */ - -#endif // NRF_SOC_H__ - -/**@} */ diff --git a/components/softdevice/s210/headers/nrf_svc.h b/components/softdevice/s210/headers/nrf_svc.h deleted file mode 100644 index 49f1425..0000000 --- a/components/softdevice/s210/headers/nrf_svc.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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 NRF_SVC__ -#define NRF_SVC__ - -#ifdef SVCALL_AS_NORMAL_FUNCTION -#define SVCALL(number, return_type, signature) return_type signature -#else - -#ifndef SVCALL -#if defined (__CC_ARM) -#define SVCALL(number, return_type, signature) return_type __svc(number) signature -#elif defined (__GNUC__) -#define SVCALL(number, return_type, signature) \ - _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ - __attribute__((naked)) static return_type signature \ - { \ - __asm( \ - "svc %0\n" \ - "bx r14" : : "I" (number) : "r0" \ - ); \ - } \ - _Pragma("GCC diagnostic pop") -#elif defined (__ICCARM__) -#define PRAGMA(x) _Pragma(#x) -#define SVCALL(number, return_type, signature) \ -PRAGMA(swi_number = number) \ - __swi return_type signature; -#else -#define SVCALL(number, return_type, signature) return_type signature -#endif -#endif // SVCALL - -#endif // SVCALL_AS_NORMAL_FUNCTION -#endif // NRF_SVC__ diff --git a/components/softdevice/s210/headers/softdevice_assert.h b/components/softdevice/s210/headers/softdevice_assert.h deleted file mode 100644 index 89e1d11..0000000 --- a/components/softdevice/s210/headers/softdevice_assert.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** @brief Utilities for verifying program logic - */ - -#ifndef SOFTDEVICE_ASSERT_H_ -#define SOFTDEVICE_ASSERT_H_ - -#include - -/** @brief This function handles assertions. - * - * - * @note - * This function is called when an assertion has triggered. - * - * - * @param line_num The line number where the assertion is called - * @param file_name Pointer to the file name - */ -void assert_softdevice_callback(uint16_t line_num, const uint8_t *file_name); - - -/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ -/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \ -/** @brief Check intended for production code - * - * Check passes if "expr" evaluates to true. */ -#define ASSERT(expr) \ -if (expr) \ -{ \ -} \ -else \ -{ \ - assert_softdevice_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \ - /*lint -unreachable */ \ -} - -#endif /* SOFTDEVICE_ASSERT_H_ */ diff --git a/components/softdevice/s210/hex/s210_nrf51422_5.0.0_softdevice.hex b/components/softdevice/s210/hex/s210_nrf51422_5.0.0_softdevice.hex deleted file mode 100644 index 88c2a46..0000000 --- a/components/softdevice/s210/hex/s210_nrf51422_5.0.0_softdevice.hex +++ /dev/null @@ -1,2952 +0,0 @@ -:020000040000FA -:10000000C0070000D1060000D1000000B1060000CA -:1000100000000000000000000000000000000000E0 -:100020000000000000000000000000005107000078 -:100030000000000000000000DB000000E500000000 -:10004000EF000000F9000000030100000D010000B6 -:1000500017010000210100002B0100003501000004 -:100060003F01000049010000530100005D01000054 -:1000700067010000710100007B01000085010000A4 -:100080008F01000099010000A3010000AD010000F4 -:10009000B7010000C1010000CB010000D501000044 -:1000A000DF010000E9010000F3010000FD01000094 -:1000B00007020000110200001B02000025020000E0 -:1000C0001FB5C046C04600F0EFFA04B00FB41FBD24 -:1000D00008205A49096809580847382057490968CB -:1000E000095808473C2055490968095808474020E5 -:1000F0005249096809580847442050490968095875 -:10010000084748204D490968095808474C204B4981 -:10011000096809580847502048490968095808479C -:100120005420464909680958084758204349096836 -:10013000095808475C204149096809580847602068 -:100140003E4909680958084764203C49096809582C -:100150000847682039490968095808476C20374919 -:100160000968095808477020344909680958084740 -:100170007420324909680958084778202F490968CE -:10018000095808477C202D490968095808478020EC -:100190002A490968095808478420284909680958E4 -:1001A0000847882025490968095808478C202349B1 -:1001B00009680958084790202049096809580847E4 -:1001C00094201E4909680958084798201B49096866 -:1001D000095808479C201949096809580847A02070 -:1001E0001649096809580847A4201449096809589C -:1001F0000847A8201149096809580847AC200F4949 -:10020000096809580847B0200C4909680958084787 -:10021000B4200A49096809580847B82007490968FD -:1002200009580847BC2005490968095808470000D3 -:1002300003480449024A034B7047000000000020B5 -:10024000C0070000C00700000122D84B5A6000BF61 -:10025000D74A1268002AFBD0016000BFD44A126856 -:10026000002AFBD00022D14B5A6000BFD04A12684E -:10027000002AFBD07047F0B505460E46174600240D -:1002800006E0A200B158A2005019FFF7DDFF641C80 -:10029000BC42F6D30020F0BD0120C043C549086030 -:1002A000401048607047014601229204086890425D -:1002B00001D9102070470020FCE7F0B505460C4638 -:1002C0001646002706E028462168FFF7BDFF2D1DD2 -:1002D000241D7F1CB742F6D3F0BD70B505460C4611 -:1002E0002E460BE0304600F075F9FF2C01D80024B3 -:1002F00001E0FF3C013C012080023618002CF1D1C6 -:1003000070BD0146012292044868904201D909203B -:100310007047A9484069401C01D10F20F8E7002030 -:10032000F6E7FEB504462068030000F037FA05043E -:100330002B4249598B00201DFFF7E3FF0546002D96 -:1003400001D02846FEBDFFF7A7FF0120C00200F044 -:1003500041F9042221469948FFF78DFF002801D07A -:100360000320EFE708222146944800F06DF90028A9 -:1003700006D1002192480068FFF766FF00F00CF9F3 -:100380000320DFE7A768E6686068019031463846D9 -:10039000FFF7A3FF324638460199FFF78EFFB20000 -:1003A0003846019900F050F9002800D1CAE703202F -:1003B000C8E700F0E3F9834800688349086041E03A -:1003C00060680190E668A0680090B200009901980A -:1003D00000F03AF90746002F00D1B3E70E20B1E74D -:1003E000201DFFF760FF0546002D01D02846A9E734 -:1003F0006068002807D1FFF74FFF0320800200F05C -:10040000E9F800F0C9F8FFF747FF0120C00200F04B -:10041000E1F8042221466948FFF72DFF002801D0AA -:1004200003208FE708222146644800F00DF90028D8 -:1004300006D1002162480068FFF706FF00F0ACF823 -:1004400003207FE700BF00207CE770B505460C461F -:10045000182D04D12068FFF764FF206002E001201E -:10046000206000BF00BF70BDF0B589B05248406940 -:1004700003905248806881000398081802900398FE -:10048000000B01900121090302984018401E000B47 -:1004900000900124002520462946019A00F0C4F866 -:1004A0000022401E91410791069001260027304608 -:1004B0003946009A00F0B8F80022401E914105919B -:1004C0000490049BDB43059AD2430698184307998E -:1004D00011430791069037490698086007984860CD -:1004E00009B0F0BD70B53448446934488568466841 -:1004F000AA003146204600F0A7F8002801D00020CD -:1005000070BD0120FCE72D484068002801D0012083 -:1005100000E000200546FFF7E5FF002807D0FFF7C1 -:10052000BBFE0320800200F055F800F035F8FFF71D -:100530009BFF002D0ED020484669204884684768FC -:1005400021463046FFF7C9FE224639463046FFF7BE -:10055000B4FE00BF00F020F810B5184844681A48EF -:100560000460204600F0DCF810BD15480068006803 -:10057000401C01D100BFFEE710480068002802D0EF -:10058000042806D101E0FFF7BEFFFFF7E5FF00BF3B -:10059000FEE700BF00BFFEE7BFF34F8F0B480C49DB -:1005A000C860BFF34F8F00BFFEE7000000E50140C9 -:1005B00000E40140000600400010001000080000A8 -:1005C000B8070000BC070000000000200400FA0586 -:1005D00000ED00E010B50146104B1A6808460223F2 -:1005E0000F4C636000BF0F4B1B68002BFBD0531CEC -:1005F00004D0904202D20A4B186101E0084B986087 -:1006000000BF084B1B68002BFBD00023044C636029 -:1006100000BF044B1B68002BFBD010BD0010001066 -:1006200000E5014000E4014010B5202A04DB01464A -:10063000203A9140002010BD914020239C1A03468F -:10064000E3401943904010BD034610B50B439B0790 -:100650000FD1042A0DD308C810C9121FA342F8D025 -:1006600018BA21BA884201D9012010BD0020C04328 -:1006700010BD002A03D0D30703D0521C07E000208E -:1006800010BD03780C78401C491C1B1B07D1037854 -:100690000C78401C491C1B1B01D1921EF1D118463D -:1006A00010BD70477047704710B500F007F810BDD7 -:1006B000014B1B68DB6818470000002019481A49E5 -:1006C0007047FFF7FBFFFFF7FBFC00BD20BFFDE716 -:1006D0001649174C24688C420BD1164B1B68994263 -:1006E0000CD1154B154A1360186810498842EDD09B -:1006F0000AE0134880F30888124B18470F4A13602A -:1007000018680A498842E1D080F308880E49884277 -:1007100004DD0E48026802210A4302605B68184744 -:100720000346DFE7C0070000C0070000FFFFFFFF30 -:10073000000C000014100010001000000000002049 -:10074000000400206B05000000200020240500406C -:100750000D48704502D1EFF3098101E0EFF3088104 -:10076000886902380078182802D1C046074A104725 -:10077000074A12682C3212681047000000B5054B7A -:10078000054A9B58984700BDFDFFFFFF4B04000042 -:1007900000000020001000000400000030B4744687 -:1007A000641E2578641CAB4204D3635D5B00E318D0 -:1007B00030BC18471D46F8E7000C00000010000090 -:101000001808002079BD000025140000DFBC000096 -:1010100000000000000000000000000000000000D0 -:10102000000000000000000000000000E9BD00001A -:10103000000000000000000025140000251400003E -:1010400055BE00005BBE0000251400002514000002 -:1010500025140000251400002514000025140000AC -:1010600061BE0000251400002514000067BE0000CA -:10107000251400006DBE000073BE000079BE0000A4 -:10108000251400002514000025140000251400007C -:10109000251400002514000025140000251400006C -:1010A0007FBE000085BE000025140000251400004E -:1010B000251400002514000025140000251400004C -:1010C00000F002F80AF039FE0CA030C808382418E5 -:1010D0002D18A246671EAB4654465D46AC4201D170 -:1010E0000AF02BFE7E460F3E0FCCB6460126334259 -:1010F00000D0FB1AA246AB463343184758AE000057 -:1011000078AE0000103A02D378C878C1FAD85207F6 -:1011100001D330C830C101D504680C6070470000AD -:101120000023002400250026103A01D378C1FBD803 -:10113000520700D330C100D50B6070471FB5C046C1 -:10114000C04601F056FF04B00FB41FBD40BA70474F -:10115000C0BA7047F0B44046494652465B460FB4A9 -:1011600002A0013001B50648004700BF01BC864619 -:101170000FBC8046894692469B46F0BC70470000F3 -:10118000C110000040BA7047C0BA70478269024976 -:101190008161024810447047A11100000100000065 -:1011A00001B41EB400B501F0CAFB01B40198864633 -:1011B00001BC01B01EBD000040BA7047C0BA704704 -:1011C000401E00BF00BF00BF00BF00BF00BF00BF88 -:1011D00000BF00BF00BF00BF00BFF1D170470000DB -:1011E00070B505460C46164602E00FCC0FC5103E02 -:1011F000102EFAD2082E02D303CC03C5083E042ECB -:1012000007D301CC01C5361F03E021782970641C87 -:101210006D1C761EF9D270BD10B572B600F0DCF808 -:1012200000280BD000F0B0F901F08BFF01F034FE84 -:101230006E490020C86288626D49086062B600206D -:1012400010BDF3B5002501200007C06A81B0C0437E -:101250000006000E04D167480068401C00D101253B -:1012600072B600F0B9F8002802D062B60820FEBDC0 -:10127000FFF770FF00F08CF95F4B604E00211A6899 -:10128000CA40D2071FD00246CA40D20718D14AB27C -:10129000002A07DA1407240F083CA408A400A419A4 -:1012A000E46904E09408564FA400E4192468920706 -:1012B000D20ED440A204120E012A04D0032A02D076 -:1012C00062B65048FEBD491C2029D8D301980300BE -:1012D0000AF00BFE142123232323232323230B0DA6 -:1012E0000F11131F1517191B1D2E002416E00124C2 -:1012F00014E0022412E0032410E004240EE0082489 -:101300000CE009240AE00A2408E00B2406E00C247F -:1013100004E0052402E0072400E00624F06901212E -:101320000002000AC9070843F061002D04D009E05B -:1013300062B601200003FEBD2C4D3348E86200F088 -:1013400027F9A8622A4931480860314902980860A3 -:1013500000F01EF9214601F086FD01F0B6FE03F013 -:1013600079FD03F0E9FB019800F0B8F8040062B6DB -:1013700003D0FFF751FF2046FEBD0020FEBD10B593 -:10138000044600F029F8002800D001202070002039 -:1013900010BD204908600020704710B50C46102889 -:1013A00008D011280BD012280CD013280ED0012001 -:1013B000086010BD61682068FFF743FF0AE0FFF78F -:1013C0002BFF07E02068FFF7DAFF03E011492068F0 -:1013D00008600020206010BD05480C490068884264 -:1013E00001D1012070470020704700000005004037 -:1013F0000C0000200010001000E100E000ED00E013 -:1014000000E400E00110000000090000BEBAFECABE -:1014100008000020040000200E4A12680C498A428D -:101420000AD118470B4A1268094B9A4204D101B5F8 -:1014300001F07CFA03BC8E46074909680958084741 -:1014400006480749054A064B7047000000000000A7 -:10145000BEBAFECA0C0000200400002018080020BC -:101460001808002010B50146202209480AF0F2FAB7 -:1014700007490020C877084610BD06490120486189 -:101480000548064A0168914201D100210160704778 -:101490002C010020000500400C000020BEBAFECA4E -:1014A0008307FF22DB0E9A408907090E9940002826 -:1014B0000BDA0007000F083883083A489B001B1816 -:1014C000D86990430843D8617047830836489B0029 -:1014D0001B181868904308431860704710B5334ACA -:1014E0000446D06980B23C2815D03149088CC0B27E -:1014F000012812D1888C00070FD1088D0006000F3B -:1015000001280AD1888D0006000F06D1D06929492B -:10151000000C884201D1022010BD00210120FFF7FC -:10152000BFFF00211820FFF7BBFF00210B20FFF7B2 -:10153000B7FF02211920FFF7B3FF02210D20FFF7AB -:10154000AFFF02210E20FFF7ABFF02210F20FFF7B4 -:10155000A7FF0221C81FFFF7A3FF03211620FFF7F3 -:101560009FFF03211520FFF79BFF134A042310461A -:101570001946103801F0B9FA204600F025F800208D -:1015800010BD69210180704710B500F030F810BD22 -:101590000A48704710B500F037FD10BD704770471E -:1015A0007047704700ED00E000E400E040000010EC -:1015B000C00F00F0FFFF00005C01002003F90043B2 -:1015C00010B508F0F2FF10BD10B5FD4801780029F4 -:1015D0000CD101210170FB484173203804F0A6FBB7 -:1015E000F94804F0F3FB012006F07CF810BD10B5BB -:1015F000F3480178002907D000210170F1484173B8 -:1016000004F0C6FB04F0A8FC10BD10B5EC4800784F -:10161000002808D004F0BCFB04F09EFC002006F07B -:1016200061F8002010BD022010BDF8B516460C462A -:10163000054600F0CCFC002809D1204600F0C7FC8C -:10164000002804D1304600F0C2FC002801D0072059 -:10165000F8BD304606F0EBFD6946009048782070F2 -:1016600009782970002801D00020F8BD0520F8BDB8 -:1016700070B50446D5481D460078401E844201DD01 -:10168000D34870BD072A02D9D1480A3870BD204618 -:1016900006F0E4F9002805D12946204606F056FA5E -:1016A0000028F3D001218903084370BD10B5C74954 -:1016B0000978491E884201DDC54810BD06F070FA60 -:1016C0000028FAD001218903084310BD10B5BF4995 -:1016D0000978491E884201DDBD4810BD05F0D2FCE5 -:1016E0000028FAD001218903084310BD10B5B7497D -:1016F0000978491E884201DDB54810BD06F062FA3E -:101700000028FAD001218903084310BD10B506F066 -:1017100098FA002802D001218903084310BD70B552 -:101720000446AA480E4600781546401E844201DD54 -:10173000A74870BD104600F04AFC002801D00720E1 -:1017400070BD2B4632460021204604F07EFF502813 -:1017500003D001218903084370BD002070BD70B51E -:1017600004469A480E4600781546401E844201DD24 -:10177000974870BD104600F02AFC002801D00720D1 -:1017800070BD2B463246A021204604F05EFF502853 -:1017900003D001218903084370BD002070BDF8B556 -:1017A00004468A481E4600780F46401E154684426D -:1017B00001DD8748F8BD104600F009FC002801D083 -:1017C0000720F8BD33462A463946204605F04DFD30 -:1017D000502803D0012189030843F8BD0020F8BD3B -:1017E00010B5044600F0F3FB002801D0072010BD1F -:1017F000204605F0A3FD0028F9D001218903084304 -:1018000010BD10B505F0A6FD002802D00121890306 -:10181000084310BD70B505466C480C460078401E64 -:10182000854201DD6A4870BD084600F0D0FB002803 -:1018300001D0072070BD284606F035FA2070002040 -:1018400070BD10B506F00DFB002010BD70B504464C -:101850000D46072802D95E480A3870BD084600F0D8 -:10186000B6FB002801D0072070BD2946204605F0B0 -:1018700038FB002070BD10B5544A1278521E9042B9 -:1018800001DD534810BD05F022F9002010BD70B5F0 -:1018900005464E480C460078401E854201DD4C4806 -:1018A00070BD084600F093FB002801D0072070BDF2 -:1018B000284605F01BF92070002070BD10B5434B81 -:1018C0001B785B1E984201DD414810BD05F0E5F82C -:1018D000002010BD10B53D4B1B785B1E984201DD0A -:1018E0003B4810BD05F01BF9002010BD10B5374A6C -:1018F0001278521E904201DD354810BD06F04AF8BC -:10190000002010BD70B5054630480C460078401EDA -:10191000854201DD2E4870BD084600F058FB0028C6 -:1019200001D0072070BD284606F04FF82080002027 -:1019300070BD38B5254C2478641EA04201DD2448D2 -:1019400038BD6C462170090A6170A270E370694667 -:1019500006F014F80028F3D001218903084338BDAC -:10196000F8B5074619481C4600781546401E0E4635 -:10197000874201DD1648F8BD084600F028FB002824 -:1019800009D1284600F023FB002804D1204600F0AE -:101990001EFB002801D00720F8BD6946384605F037 -:1019A000CBFF6846017840780002084330806846E3 -:1019B000807828706846C07820700020F8BD00004C -:1019C00010000020BC010020C1150000780000209C -:1019D0003340000010B5FC4A1278521E904201DDDF -:1019E000FA4810BD06F001F8002010BD10B5F64A07 -:1019F0001278521E904201DDF44810BD05F0F0FF50 -:101A0000002010BD10B5F04A1278521E904201DD40 -:101A1000EE4810BD05F0EEFF002010BD10B5EA4AFB -:101A20001278521E904201DDE84810BD05F0E9FF32 -:101A3000002010BD70B50546E3480C460078401EF6 -:101A4000854201DDE14870BD084600F0C0FA00287B -:101A500001D0072070BD284605F0D9FF2070002076 -:101A600070BD10B5D84A1278521E904201DDD74899 -:101A700010BD05F0AFFF002010BD70B50C46054647 -:101A800000F0A5FA002801D0072070BD21462846A5 -:101A900006F0EEF90028F8D001218903084370BD53 -:101AA00070B505460C46084600F091FA002801D0B2 -:101AB000072070BD2146284606F011FA0028F8D00C -:101AC00001218903084370BD10B505F00AFF002805 -:101AD00002D001218903084310BD10B505F00AFFAB -:101AE000002010BD10B5044600F071FA002801D0A6 -:101AF000072010BD05F003FF2070002010BD7CB54D -:101B00000546B148164600780C46401E854201DD68 -:101B1000AE487CBD084600F05AFA002801D00720E4 -:101B20007CBD21786846017061784170A178817030 -:101B3000E178C17006716946284605F031FC00283D -:101B4000EED00121890308437CBD08B59E4B1B786C -:101B50005B1E984201DD9D4808BD6B4619705A70A6 -:101B6000694605F001FC0028F6D0012189030843ED -:101B700008BD10B5944C2478641EA04201DD934842 -:101B800010BD05F035FC002010BD10B505F026FC99 -:101B9000002010BD38B5044600F019FA002801D025 -:101BA000072038BD684605F01CFC6946087849786E -:101BB000090201432180002038BD70B505460C465E -:101BC000084600F004FA002801D0072070BD214625 -:101BD000284606F084FC0028F8D001218903084338 -:101BE00070BD70B505460C46084600F0F0F90028B7 -:101BF00001D0072070BD2146284606F07CFC002855 -:101C0000F8D001218903084370BD10B56E4A1278DF -:101C1000521E904201DD6D4810BD06F07AFC00288E -:101C2000FAD001218903084310BD10B5664C247811 -:101C3000641EA04201DD654810BD06F079FC002855 -:101C4000FAD001218903084310BD70B505460C4642 -:101C5000084600F0BCF9002801D0072070BD2146DD -:101C6000284606F04DFD0028F8D0012189030843DD -:101C700070BD70B505460C46084600F0A8F900286E -:101C800001D0072070BD2146284606F057FD0028E8 -:101C9000F8D001218903084370BD70B505460C4694 -:101CA000084600F094F9002801D0072070BD2146B5 -:101CB000284606F056FD002070BD10B506F067FD01 -:101CC000002802D001218903084310BD70B50C46DD -:101CD000054600F07CF9002804D1204600F077F991 -:101CE000002801D0072070BD2146284606F096FD49 -:101CF000002070BD70B506463348144600780D4686 -:101D0000401E864201DD314870BD002D04D00846DA -:101D100000F05DF9002806D1002C06D0204600F026 -:101D200056F9002801D0072070BD002D03D02946A8 -:101D3000304605F0A5FB002C03D02146304605F0C7 -:101D4000E3FB002070BD70B506461F4814460078BE -:101D50000D46401E864201DD1C4870BD002D04D09A -:101D6000084600F034F9002806D1002C06D02046A1 -:101D700000F02DF9002801D0072070BD002D03D000 -:101D80002946304605F0A1FB002C03D02146304601 -:101D900005F0CFFB002070BD10B504460C4800785C -:101DA000002817D003F0F4FF04F0D6F8204605F021 -:101DB00029FD002810D0044920780870002005F083 -:101DC00091FC002010BD000078000020334000008E -:101DD000100000200220F5E70720F3E710B50446C5 -:101DE00000F0F5F8002801D00720EBE705F08AFDA8 -:101DF00020700020E6E710B5044600F0E8F800285F -:101E000001D00720DEE705F082FD20700020D9E731 -:101E100070B5054676480C460078401E854201DDC7 -:101E2000744870BD084600F0D2F8002801D00720A1 -:101E300070BD284605F071FD2070002070BD70B5A2 -:101E400005466B480C460078401E854201DD694816 -:101E500070BD084600F0BBF8002801D0072070BD17 -:101E6000284605F060FD2070002070BD10B504F01C -:101E7000F9FD0020A6E710B504F0FAFD0020A1E767 -:101E800010B5044600F0A3F8002801D0072099E718 -:101E900059480021425C6254491CC9B20B29F9D34C -:101EA00000208FE710B5044600F091F8002801D01B -:101EB000072087E74E48B221007820700820607024 -:101EC0000020A070E170362121716071F520A071B1 -:101ED0000120E071002075E7FFB5062581B01E46A0 -:101EE00017460C46002904D0084600F070F8002878 -:101EF0000DD1002F04D0384600F069F8002806D133 -:101F0000002E07D0304600F062F8002802D00720EB -:101F100005B0F0BD0198002804D0012806D00228A1 -:101F200008D109E0207804F04BF802E004F04CF806 -:101F3000207000252846EBE7207806F076FCF8E7CD -:101F4000FFB5062581B01E4617460C46002904D071 -:101F5000084600F03CF800280DD1002F04D0384688 -:101F600000F035F8002806D1002E06D0304600F0EB -:101F70002EF8002801D00720CAE70198002804D0D5 -:101F8000012811D002280DD119E0002528461B4E4A -:101F9000256004E0297801F011F86D1C2060B5423D -:101FA000F8D300252846B3E7154822788105002A92 -:101FB000826A02D00A438262F3E78A43FBE7207811 -:101FC00006F03EFCEDE710B509F0D9FCFAE6002872 -:101FD00009D00A49884206D301214907884204D31F -:101FE0000849884201D20120704700207047000054 -:101FF000780000203340000004BF000000D0000043 -:10200000000500400009002010B5C0380C46030050 -:1020100009F06BFF4021242933373B3F434A515A93 -:102020005F62676D727A82888D979DA3A9AFB5BAFA -:10203000C0C6CBEFF3F7FEEAE9E8E7E6E5E4E3E262 -:10204000E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2F8 -:10205000D1D1D0D1CFD1FFF7D8FA71E1204607C84E -:10206000FFF7E3FA6CE1207BC3B2207AC2B2207999 -:10207000C1B22078FFF7FCFA62E12078FFF716FB87 -:102080005EE12078FFF722FB5AE12078FFF72EFB74 -:1020900056E12078FFF73AFB52E12079A268C1B2FD -:1020A0002078FFF73CFB4BE12079A268C1B2207891 -:1020B000FFF755FB44E1207BA268C3B2A08881B240 -:1020C0002078FFF76CFB3BE120786168FFF7A2FB0B -:1020D00036E1FFF7B6FB33E120786168FFF7B6FB26 -:1020E0002EE12079C1B22078FFF7C5FB28E12078E6 -:1020F0006168FFF7CCFB23E1207AC2B22079C1B23C -:102100002078FFF7DBFB1BE1207AC2B22079C1B255 -:102110002078FFF7DFFB13E1A08881B22078FFF77A -:10212000E5FB0DE120786168FFF7ECFB08E1207B1F -:10213000C3B2207AC2B2A08881B22078FFF7F9FB3F -:10214000FEE0211D0EC92078FFF70AFCF8E0A08808 -:1021500081B22078FFF73EFCF2E02079C1B220780E -:10216000FFF744FCECE02079C1B22078FFF74AFC8D -:10217000E6E02079C1B22078FFF750FCE0E020785B -:102180006168FFF757FCDBE02079C1B22078FFF7E8 -:1021900068FCD5E02079C1B22068FFF76EFCCFE083 -:1021A00020786168FFF77CFCCAE02078FFF78CFCA0 -:1021B000C6E0C0E0B9E0C4E0B3E0ACE0A5E09FE079 -:1021C00098E092E08CE086E07BE074E06EE068E00E -:1021D00064E05FE05AE055E04AE046E040E03AE083 -:1021E00035E030E02BE025E01AE011E009E004E002 -:1021F000FFE72078FFF771FCA2E02068FFF772FC90 -:102200009EE0207A6168C2B22078FFF778FC97E000 -:10221000207AC2B22079C1B22078FFF796FC8FE015 -:10222000207BC3B2207AC2B22079C1B22078FFF7F6 -:10223000A0FC85E0208880B2FFF7A7FC80E0206842 -:10224000FFF7A8FC7CE02068FFF7C8FD78E0206875 -:10225000FFF7D1FD74E020786168FFF7D9FD6FE0EA -:1022600020786168FFF7EBFD6AE0FFF7FFFD67E0AC -:10227000207BC3B2207AC2B22079C1B22078FFF7A6 -:10228000FAFD5DE02068FFF7FBFD59E02068FFF7ED -:1022900009FE55E02068FFF7A3FA51E0FFF7B1FA15 -:1022A0004EE020786168FFF788FC49E0207861689B -:1022B000FFF797FC44E02079C1B22078FFF7A5FC36 -:1022C0003EE0207BC3B2207AC2B22079C1B220782E -:1022D000FFF7ABFC34E020786168FFF7B6FC2FE035 -:1022E00020786168FFF7C5FC2AE020786168FFF775 -:1022F000D4FC25E0A08881B22078FFF7DEFC1FE047 -:1023000061682068FFF7E2FC1AE02078A268616843 -:10231000FFF7F0FC14E02078A2686168FFF713FD76 -:102320000EE02068FFF738FD0AE0211D0EC9207875 -:10233000FFF7D2FD04E0211D0EC92078FFF700FE53 -:10234000206010BD30B40121BD48C9020160CD102C -:1023500005604A030260BB4803681B021B0A036056 -:1023600004680023240A24020460B7480468240A8D -:1023700024020460B548012444608460B44C2360A6 -:102380006360A360B34B19601D601A60B24B1960A3 -:102390001A600121016030BC704710B40121A848C7 -:1023A000CA0202600B0203600C060460A748416089 -:1023B0008160AA4841680029FCD1A5490020086035 -:1023C00048608860A34802600360046010BC7047E6 -:1023D0000121A048C9020160C910016070470028AE -:1023E00005D0012805D0022805D19D4870479D4899 -:1023F00070479D48704710B59CA18C2009F069FC7E -:10240000002010BD70B500219F4CA04DA04A904BFC -:10241000002808D001281DD0022822D093A1B42082 -:1024200009F057FC70BD01200004A060A860116095 -:102430001960984BC2039A60974A9060804A0012D4 -:102440001060964801608748016095480160954892 -:10245000017070BD01204004A060A8605160596007 -:1024600070BD01208004A060A8609160996070BD7B -:10247000F8B59446844A764F844D002401260028FE -:1024800008D0012832D0022840D078A1E92009F0F4 -:1024900020FCF8BD891E0902090A01200004906091 -:1024A0003C6068607A4A1160012B1DD000217D4A92 -:1024B0007D4B517061463D31DC63DE637B4B5C607C -:1024C00002249C6004241C61744B196074490E60E2 -:1024D000604B89151960704B58605F4801606D4909 -:1024E000C00548601670F8BD0121E0E701205E4E8E -:1024F00040046F4F012B04D1346050606860396034 -:10250000F8BD9060346068603960F8BD0120544EB9 -:102510008004684F012BF4D1EEE7504840687047C3 -:1025200070B54B4D28680026574C012806D1A0688D -:10253000C00303D501200004A0602E606868012854 -:1025400009D1A068800306D501204004A0606E6018 -:10255000012001F033FDA868012809D1A0684003DB -:1025600006D501208004A060AE60022001F026FDA7 -:1025700070BD10B54B490878002818D00120454A95 -:10258000C0079060444AC00B90602D4A0012106052 -:10259000424A00201060334A1060414A10600870BF -:1025A0004A78002A02D0487001F008FD10BD0320CF -:1025B000FAE70120404900060860704701202549DC -:1025C00000060860704701203B49400508607047DD -:1025D0000120204940050860704733490020C86346 -:1025E00088151C4908607047410A344AC005C00D6F -:1025F00050435143801C08225040400A081870473D -:1026000010B42F4C430B63431B0C5C020C602B4C2F -:102610006343C31A2B485C025843284B400D434385 -:10262000E31A9B1C082463405B1213700A6810189D -:10263000086010BC704710B501F097FD10BD000098 -:1026400080E100E008E400E018E400E000B00040B1 -:1026500040B1004080E200E000E100E000B5004051 -:1026600048B100404081004044B100407372635C57 -:1026700072656D5F68616C5F6576656E745F7469C5 -:102680006D65722E6300000000B3004040B300404F -:1026900040B5004000F50140008300404085004007 -:1026A000008200401C000020C08F004000850040D8 -:1026B00044B5004048B5004000E200E0093D00009C -:1026C000378600006F0C010010B501F03AFD10BD17 -:1026D00000200449C863012001218140024A1160A1 -:1026E00000BF7047C01F004080E200E070B5203896 -:1026F0000C46030009F0F9FB33BCC0C4C8CED2D6E7 -:10270000DBEFFCED1B1F23272C31373C41484E519A -:1027100055595D616F73676B767A7E82868A8E9279 -:10272000969AB2B5B8E0F0EBEAE9F4F8E600206872 -:1027300008F008FEF4E0206808F00CFEF0E02068E5 -:1027400008F020FEECE0207840B208F03EFEE7E022 -:10275000207840B208F05FFEE2E02078616840B285 -:1027600008F075FEDCE0207840B208F085FED7E086 -:10277000207840B208F090FED2E02079C1B22078F3 -:1027800040B208F09AFECBE02078616840B208F0D1 -:10279000CAFEC5E008F0D6FEC2E0206808F0DAFE06 -:1027A000BEE0207808F0EFFEBAE0206808F0D2FC26 -:1027B000B6E0206808F0D2FCB2E02079C1B220680F -:1027C00008F0D3FCACE0206808F07EFBA8E02068AD -:1027D00008F07FFBA4E0207808F07FFBA0E008F081 -:1027E00089FB9DE0207808F08BFB99E0207808F0C9 -:1027F0009DFB95E0206808F0B6FB91E0206808F0AA -:10280000B8FB8DE0206808F0BAFB89E0206808F08A -:10281000BBFB85E0206808F0BDFB81E0206808F084 -:10282000BFFB7DE0206808F0C0FB79E003F0CCFB43 -:10283000C0070025002805D003F0CAFB002801D0FE -:10284000256070BD03F0C0FB800703D503F0C7FB14 -:102850000028F5D12046FEF799FC61E002F099FDD1 -:102860005EE002F0C6FD5BE0206802F0CEFD57E0BE -:10287000206808F01DFF53E0206808F025FF4FE0B6 -:10288000206808F02CFF4BE02078A268616808F00F -:1028900031FF45E0207808F042FF41E0207808F061 -:1028A00053FF3DE02078616808F063FF38E020784E -:1028B000616808F075FF33E02079C1B2207808F034 -:1028C000BDFF2DE02EE00FE00AE026E022E01DE053 -:1028D00002E016E00CE010E0206808F09AFE1FE02D -:1028E000206809F025F81BE0206809F00AF817E0D5 -:1028F000204607C802F0EAF912E0206802F041FA27 -:102900000EE06168206802F06CFA09E0206802F0CD -:102910005EFC05E002F073FC02E0206802F0AAFC15 -:10292000206070BD0120086070BD00000C4908786F -:102930004A78401CC0B2904200D008707047094AE3 -:10294000074820BF40BF20BF417803784370136819 -:10295000002B02D103788B42F3D000207047000097 -:102960001E00002000E200E0FEB5F34C0746606860 -:10297000FF213E0181552178FF2913D0090108313B -:1029800041583246491E083209020192090A80580C -:1029900000F0C8F9002802D02478254615E06168C7 -:1029A000207888552770FEBDE34842680198115889 -:1029B000280100900830105800F0B4F9002806D122 -:1029C000DD482C46416800980D5CFF2DECD1DA48BB -:1029D0002101406885554754FEBD70B5D64A04466E -:1029E0000020157A53680AE00201561C9E5DA6423B -:1029F00003D10C329A588A4204D0401CC0B285429E -:102A0000F2D8FF2070BDF8B5CB4F3E7801F0B8FE8C -:102A10000146FF2E68D034012546786808354059B4 -:102A200000F080F9022802D9786840595AE0C2497A -:102A30004868025D0A70A11C425C002A0CD0521E3C -:102A4000425441590122D20589180902090A41510B -:102A50003046FFF789FF30E0631CC25C0092221D04 -:102A600094468258002A10D001239B029A420FD923 -:102A70009205920D43595703DB191B021B0A435160 -:102A80006346C3589A1A920A09E0FF21C1540AE02A -:102A9000435952039A181202120A42510022425418 -:102AA0003046FFF761FFA4480C344168C2680098C3 -:102AB000095980001258009890479F4C2078FF28B1 -:102AC00012D001F05DFE01462078626800010830F6 -:102AD000105800F027F9012896D920786168000184 -:102AE0000830085801F03FFEF8BDF8B51C46154601 -:102AF0000E460746FF2B03D390A1D32009F0E9F837 -:102B00008D48FF21C7604560047206740170002281 -:102B10004270104604E00201521C401CA954C0B28D -:102B2000A042F8D3F8BD70B5834C06466578207C8A -:102B3000854203D381A1E62009F0CBF8E068A90023 -:102B400046506078401C6070284670BDFFB581B06B -:102B50001D46FF2401F014FE774F06467978019850 -:102B6000814203D875A1F42009F0B3F8724800211E -:102B7000037A406810E00A019446521C825CFF2AE6 -:102B800024D0019FBA4205D162460C328758029A7E -:102B900097421DD0491CC9B28B42ECD8FF2C17D0EC -:102BA00021014B1C019AC2540B33029AC250039B61 -:102BB000614F0022012B0ED00B1DC25001239B023E -:102BC0009D4216D9AA05920D08D008E00C46E1E70F -:102BD000FF2005B0F0BD0B1DC550EFE71A465303AB -:102BE0009B190E461B0208361B0AAA1A8351920A29 -:102BF00009E0002D00D101256B039B191D022D0A50 -:102C00000B460833C550891C42543D463E78204649 -:102C1000FFF7AAFE2878B04215D001F0B1FD0146B9 -:102C200028786A6800010830105800F07BF8012805 -:102C300007D92878696800010830085801F093FD29 -:102C400001E0FFF7E0FE0198C3E770B50C460546CA -:102C500001F096FD064621462846FFF7BEFEFF28F6 -:102C600017D0354D040120466968083008583146B0 -:102C700000F058F80121090340186968A41C095D97 -:102C8000400B002901D089020818002800D101203A -:102C900070BD002070BDF3B581B007460299FFF703 -:102CA0009CFEFF282AD0244D2E786968324634468F -:102CB00004E0844205D026462301CC5CFF2CF8D1E9 -:102CC0001CE0FF2C1AD0A6421FD11001085C28700E -:102CD000FF2818D001F054FD2A78014612016868D7 -:102CE0000832805800F01EF8012809D92878696850 -:102CF00000010830085801F036FD06E00020FEBD56 -:102D0000FFF781FE01E001F036FD38460299FFF73A -:102D10009CFF22016968FF23541C0B558A5C330118 -:102D2000CA54FEBD401A00020121000AC9058842AA -:102D300000D9002070470000680300207372635CB4 -:102D4000736F635F74696D65722E6300F8B5044636 -:102D5000800700250126002804DA5848C563C663A9 -:102D600002208443E00404D55548C563C66380143B -:102D70008443600003D55348456080058443E005E3 -:102D800004D55148C563C66380158443A00404D5A7 -:102D90004E48C563C6634014844360042104C00FD9 -:102DA000C90F884203D04AA1612008F092FF200495 -:102DB000800F0AD04B49CD634B48C563C563CE63D2 -:102DC000C663C66303208003844320050AD5474FAA -:102DD000FD632F20FEF7F4F9FE632F20FEF7F0F9D4 -:102DE000F814844308F0F7FC4148044203D038A1AA -:102DF0008D2008F06EFFF8BDF0B500210A46FF23D4 -:102E00000446CC40E4072AD04CB2E606F60E012573 -:102E1000B540384E3560384E3560002C11DA250744 -:102E20002D0F083DAE08354DB6007719FD69A40792 -:102E3000E60E1C46B440A5431446B4402543FD614C -:102E40000DE0A6082E4DB60076193568A407E70EEA -:102E50001C46BC40A5431446BC4025433560491C74 -:102E60002029CDD3F0BD70B5264C0D462060FFF76C -:102E70006DFF2068FFF7C0FF284602F05BFB08F0FB -:102E8000B3FB08F0FAF808F0A6FC08F09AF801F095 -:102E9000BFFD01F051FE70BD10B51A4C2068FFF760 -:102EA00055FF2068FFF7A8FF08F095FC02F0BCFB77 -:102EB0000020206010BD134800687047C01F00400C -:102EC000C0CF004000E50140C08F0040C0DF00409F -:102ED0007372635C736F635F636F6E6669672E63A3 -:102EE00000000000C0EF0040C0FF0040C0BF004035 -:102EF000FEFF0FFC80E100E080E200E000ED00E07A -:102F000000E400E02000002008B5027869460A705D -:102F100040784870088808BD08B5027869460A708C -:102F200042784A7082788A70C078C870009808BD6C -:102F300003E00B78491C0370401C1346521ED2B2AA -:102F4000002BF6D1704701E00170401C1346521E61 -:102F5000D2B2002BF8D1704710B507E003780C7897 -:102F6000401C491CA34201D0012010BD1346521E33 -:102F7000D2B2002BF2D1002010BD02090007000ED2 -:102F80000243CC20104081083320024090000143CE -:102F9000AA200840552240081140490008437047C4 -:102FA0000204120E000202434A401006000F504075 -:102FB000010341400806C00C48407047C0434840E8 -:102FC000064A0021C30702D04008504000E04008F4 -:102FD000491CC9B20829F5D3C04370472083B8ED16 -:102FE0007047704770477047704770477047704729 -:102FF000704710B508F09EFE10BD000000000000F4 -:1030000010FFFFFFDBE5B15100D000006900FFFFBA -:10301000F8B5F74C207BE17A88421CD00126F54DAB -:103020000027E07A215C14200A4642435019037CB1 -:10303000052B11D0037C062B1CD0037C072B28D03A -:10304000437C012B33D0ECA1EE4808F042FE207BFC -:10305000E17A8842E5D1F8BD0674E07A0A2807D003 -:10306000E07A401CE072491CC8B2AA5802210CE068 -:103070000020F7E70674E07A0A2808D0E07A401CBE -:10308000E072491CC8B2AA5803219047DFE700202C -:10309000F6E70674E07A0A2807D0E07A401CE0726E -:1030A000491CC8B2AA580821EFE70020F7E7477487 -:1030B000E07A0A2807D0E07A401CE072491CC8B2C6 -:1030C000AA580721E1E70020F7E770B50024CE4EAB -:1030D00006207072CD482546447704773830047353 -:1030E000C472CB4808F02EF9CA480575F572CA4972 -:1030F000601E88607571B570F57035717570C74860 -:103100006439057045701420604340180574641CD0 -:10311000E4B2052CF7D30120FFF774F90020FFF784 -:1031200071F90120B07101F073FCBD4801F082FC1F -:10313000BC4C2070BC4801F07DFC6070FFF702F9C8 -:1031400070BD10B5FFF729F9B64C207801F090FC5E -:10315000607801F08DFCAC4C207A002803D002F09E -:103160002EF90020207210BD70B5A74CA079002860 -:1031700004D0A1A1AD4808F0ACFD70BDE07A0028F4 -:1031800003D19DA1AA4808F0A4FD0126A67100253F -:10319000E572607A042114225043964A8018017423 -:1031A0009D488168491C04D0691E81600120FFF799 -:1031B00029F90020FFF726F9FFF70AF908F02BFBA1 -:1031C000FFF70BFA9B480560056001209A49C00390 -:1031D0000860FFF77DFA91480078022804D00328A0 -:1031E00004D1E078002801D0A67000E0A570FFF7B8 -:1031F000E0F970BD03467F4905201422424352186E -:10320000203A127F002A04D0401E0006000EF4D19E -:1032100070471422424351180A46403AD3620122B1 -:1032200020390A777047012805D0032805D10029E5 -:1032300003D1002070470029FBD010B4724C00234A -:103240006370764A002890700CD002280AD00729B3 -:103250001AD20B007B441B79DB189F441505070D20 -:103260000F111300D37003E01B2000E03A20D07050 -:103270000120607010BC70475820F8E77720F6E70F -:103280009620F4E7B520F2E710BC0020704710B597 -:1032900062484078FFF7A8F980B210BD411E1422A1 -:1032A000504310B5534A8418203C042902D8207F8B -:1032B000002803D150A1614808F00BFD207F0128B0 -:1032C00004D0B3204CA1800008F003FD002020773B -:1032D00010BD70B54D4C607F217F884201D1012522 -:1032E00000E00025FFF719F9FFF77EF9617F227FE3 -:1032F000914201D1012100E00021A942EBD170BD32 -:10330000F7B50646481E84468EB0C0B2142202901D -:103310005043384A851828460695007C2D1D0728FD -:103320002AD1334F0022F87A3B7B834221D03C5C88 -:10333000029B9C4201D1012201E0002A04D00A280C -:1033400011D0431CFB5C3B540A280ED0401C3B7B35 -:10335000C0B28342EBD1002A0BD0387B002806D0C4 -:10336000387B401E04E00023ECE70020EFE70A2052 -:103370003873069A012010746046234C042813D831 -:10338000142041431B4808182038007F00280BD028 -:103390000698007C01280BD00698007C012803D0F9 -:1033A0001098807A012807D013A1254808F091FCD5 -:1033B0001098807A01286CD106980E4A007C022869 -:1033C00042D00B4C207B0A286FD0207BE17A401C36 -:1033D000884203D108A11B4808F07BFC0699012014 -:1033E0004874217B02986054207B0A2861D062E0F7 -:1033F000C4020020D40200207372635C72656D2EDB -:1034000063000000CF050000580300208C0200205C -:1034100064030020AC0200203803002013000020C9 -:10342000072A000011000020113000007D0200007A -:103430005E02000000F5004080E200E0CB020000E8 -:103440001503000022030000607A029B01469842A7 -:1034500006D00146142778438018807C9842F8D122 -:10346000637A834208D1617A142359438918897C8D -:1034700061720121A17207E0142343439B181427B2 -:1034800079439B7C89188B74142306215843801838 -:1034900081741098007A06281DD203007B441B79A2 -:1034A000DB189F440C161412100EE07A002891D0FD -:1034B00094E7002001E0207B401C2073B9E000204D -:1034C0000FE0B4200DE073200BE0322009E00A2069 -:1034D00007E0072005E0FF20FD49E03008F0F9FB98 -:1034E00000200190109801680198081A286010992E -:1034F000097A002912D00221401A0102090A296022 -:1035000010980268406810180002000A686010985D -:10351000807A0228109803D0007B74E00421EBE746 -:10352000007A002813D002220198101884461098BF -:103530004268604608301718E648019A4078904281 -:1035400002D9E278002A04D03846083005E0042287 -:10355000EAE7019A801AC0190830627A062A1CD05C -:10356000627A14235A43DC4BD2185268914214D029 -:10357000DA4B0793617A14225143D74A89184A6873 -:103580008968921B891B12020902120A090A9042D9 -:103590003AD89A4238D8994236D83018C01B00021F -:1035A000000A286010996044CD4AC9680002000AE8 -:1035B0009446421A01239B0507929A4201D2104673 -:1035C00014E00A1A08929A4201D207980EE0079A6C -:1035D0006346624503D9591A0818401C06E0089A48 -:1035E000624506D9181A4018401C4042002860DC89 -:1035F00003E0B749BB4808F06CFB2868C01900021B -:10360000000A6860002028726868082708300002F5 -:10361000000A68601098407AA8721098007A687260 -:1036200003280ED200280CD008F0F0F9002803D0AF -:1036300007E0002011B0F0BD01983A210F1A3220A6 -:103640000190A4480178012901D0032909D14078CB -:103650000199884205D9E178002902D10199401ADF -:10366000C71928689D4A801B844601026868090AB8 -:10367000801B03021B0A03938F421AD81346914200 -:1036800017D80399994214D8617A062915D0677A18 -:10369000614606220392019214228F4B7A43D2187C -:1036A00093689B1B8B4216D80397977C062FF3D108 -:1036B00073E0029801F05AF9BBE7069902220298DA -:1036C0000A74627A062A00D0627A8A7460720120D3 -:1036D000A07211B0F0BD062F5FD00022394694468B -:1036E00014227D4B4A43D21853689B1B834225D238 -:1036F000917BAB7A99421BD806980521029D0174F3 -:10370000794C207B0A280FD0207BE17A401C88422C -:1037100003D16F49754808F0DCFA207B2554207BE3 -:103720000A2800D0C7E6C4E6E07A0028F1D0F4E722 -:1037300001218C46917C0629D2D102E06046002806 -:103740002AD03D46019114202A4642436248062170 -:10375000161831741038007B0A28634816D0017B94 -:10376000C07A491C814203D161A1644808F0B1FAD2 -:103770005D48017B4554017B0A290BD0017B491C24 -:103780000173B57C0198A842DDD106E0C07A00281B -:10379000EAD0EDE70021F3E70197069902204E4DAC -:1037A0000874607AB84207D1069901988874029823 -:1037B00060720120A07221E00398062F0FD0062826 -:1037C00003D14BA14E4808F084FA039814225043C9 -:1037D0004019029981740699019888740EE00628B0 -:1037E00003D143A1474808F074FA039814225043C8 -:1037F000401902998174069906208874012011B03D -:10380000F0BD70B50D46404A441900210B46101A10 -:103810008B4103D236A13D4808F05BFA3C48854213 -:1038200003DD33A13B4808F054FA3B48854203DAF4 -:103830002FA13A4808F04DFA3948844205DA002CA5 -:1038400001DB204670BD364800E03648201870BDC8 -:10385000401E70B5C0B2142148431F494418607B14 -:10386000062813D203007B441B79DB189F44020C0B -:103870000A080604002069E0B42010E073200EE07E -:1038800032200CE00A200AE0072008E0FF2018A1FF -:10389000E03008F01EFA617B0020002956D002219A -:1038A0004018616840180002000AFEF79DFE0C25D2 -:1038B0006557154A441900210B46101A8B4103D253 -:1038C0000BA1124808F005FA1148854230DD2BE0C3 -:1038D000F833000013000020D4020020FFFF3F0057 -:1038E000FFFFFF000E070000C402002007020000D7 -:1038F0007372635C72656D2E63000000C503000087 -:10390000DD030000E3030000FF7F841EF5030000D9 -:103910000020A107F603000000E05EF8F7030000B6 -:103920000080841E00807BE1FA49FB4808F0D1F951 -:10393000FA48854203DAF749F94808F0CAF9F94824 -:10394000844207DA002C03DB204670BD0421A7E780 -:10395000F44800E0F448201870BDF0B5064683B086 -:10396000F2480190457A029534687068001B07029E -:10397000EF483F0A001B0090062D2DD01420294649 -:103980004143EC480122081884464168E848920502 -:103990008646081B904210D3631A93420DD3024609 -:1039A0007046724503D900984018401C05E07345E5 -:1039B0000ED9411A0819401C404200280CDA604612 -:1039C0000295857C0198C0790028D5D003B0F0BD60 -:1039D000D049D94808F07DF90298854226D01421B3 -:1039E0004843D4490123401802908068D0499B0580 -:1039F0008C46011B8646994210D3221A9A420DD357 -:103A00006346614503D900997144491C06E0194693 -:103A100062452DD9091A0819401C4142002905DDCB -:103A20000298B17A807B814200D37446062D15D06E -:103A3000C0491420454368184268121B1202120A3A -:103A4000BA420BD2B27A837B9A4200D38468857CD7 -:103A50000198C0790028B9D1062DEAD13068A0427A -:103A6000B4D0E0190002000A3460706003B0F0BD09 -:103A7000A849B14808F02DF9D8E7F0B5AF49044698 -:103A8000486885B0C005C00D1BD0103840B2002872 -:103A90000BDA0207120F083A920892005118C9690E -:103AA0008007C00EC140880908E08108A44A890047 -:103AB000891809688007C00EC14088090006000EF9 -:103AC00008D000262078002806D0012804D0002045 -:103AD00005B0F0BD0126F5E72079062813D20300D2 -:103AE0007B441B79DB189F44020C0A080604002063 -:103AF00018E0B42010E073200EE032200CE00A2021 -:103B00000AE0072008E0FF208249E03008F0E1F8F1 -:103B100021790020002905D002214718834D002E6D -:103B200002D003E00421F8E70020E87102AA694608 -:103B3000A068FEF765FD694608228A56E06801A97B -:103B40008018C01C01221F2801DA019209E003AA93 -:103B5000FEF756FD6846007B002802D00198401C05 -:103B6000019000990198401808300002000A019065 -:103B7000C81B0002000A00906079694688720098AC -:103B80000390FEF7CAFC009A019B121A181A6D499D -:103B900012020002120A000A8A4210D888420ED885 -:103BA0006846FFF7DAFE00990398814205D0C819EC -:103BB0000002000AFEF718FDA060012000E00020CE -:103BC000E979002984D0002EAED005B0F0BDF0B563 -:103BD00005468FB05C480C460B9007F0BBFB534E7C -:103BE0005A4F00280BD05A48007D002803D059A115 -:103BF0005B4808F06EF8207801287DD068E1787F76 -:103C00000A280CD0787F397F401C884203D151A10B -:103C1000544808F05EF82078012804D011E0387F7D -:103C20000028F4D0F7E75048401920380090C07FB2 -:103C3000002803D047A14D4808F04BF80099012017 -:103C4000C877797F28461422494D51434919087491 -:103C50002078022823D0787F142148434519207901 -:103C60002872607968722A460C322946A068FEF7ED -:103C7000C7FC0C2028560F2804DD1F38287328683D -:103C8000401C28600C216956281DE26801905018DC -:103C9000C01C1F286EDA019901200860FBE027494B -:103CA0004868C005C00D20D0103840B200280BDA9B -:103CB0000207120F083A920892005118C96980074A -:103CC000C00EC140880908E081081D4A8900891892 -:103CD00009688007C00EC14088090006000E04D1A3 -:103CE00005201CA1000207F0F4FF787F142148434F -:103CF00045190021E06800E0DBE06A46049111709C -:103D000004A9FEF77DFC6A46002010560F2832DD1C -:103D1000012031E0F0380000F603000000E05EF81A -:103D2000F70300000080841E00807BE15803002020 -:103D3000FFFFFF00D40200200E07000000ED00E0AE -:103D400000E400E0FFFF3F00640300208C0200203D -:103D5000AC0200207372635C72656D2E630000001C -:103D600011050000EF04000017000020F40400001B -:103D7000CC01002082E00020049940180790022026 -:103D8000A8722079287260796872A068291DC01C09 -:103D900004911F2801DA012009E0FEF731FC684692 -:103DA0000078002804D0049804990068401C08603A -:103DB000287A062813D203007B441B79DB189F4422 -:103DC000020C0A08060400200FE0B4200DE0732066 -:103DD0000BE0322009E00A2007E0072005E0FF2081 -:103DE000FD49E03007F075FF00202179002943D01C -:103DF0000221401804906968083008180799089053 -:103E000009180498081A0C900020F071FEF785FB41 -:103E100004462860079820180002000AE860707ABB -:103E2000062825D0707A14214843EC494018406890 -:103E30000899019040180002000A0290687A6946C9 -:103E4000887301A8FFF789FD0199029A091B121BCB -:103E500009021202E24B090A120A0C98994207D889 -:103E6000824205D80199049808180002000A2860C7 -:103E7000F0790028C8D110E00421BAE704AA01991A -:103E8000FEF7BEFB6846007C002804D0019801992B -:103E90000068401C08602078A872787F0A2806D045 -:103EA000787F401C78770B9807F06CFA4BE0002085 -:103EB000F8E7CC48401920380090C07F002804D093 -:103EC000A320C9A1C00007F004FF00990120C87712 -:103ED000C84805742078022803D1C3A1C64807F05A -:103EE000F8FEC44D20792872607968722A460C3237 -:103EF0002946A068FEF784FB0C2028560F2804DD15 -:103F00001F3828732868401C28600C216956E06817 -:103F10002A1D4018C01C01921F2802DA01201060DF -:103F20000CE004AA0199FEF76BFB6846007C0028B0 -:103F300004D0019801990068401C08602078A8729C -:103F4000AC4901200875787F397F884224D0747A83 -:103F5000062C23D0FEF7E1FA14214C439F49611847 -:103F60000A7C042A18D00A7C032A15D04B68896879 -:103F70001B1A081A1B020002994A1B0A000A082B86 -:103F80000AD31146934207D8884205D8787F397FF3 -:103F9000884201D0FEF70DFB0FB0F0BD787F397F6E -:103FA0008842F7D10FB0F0BD10B50020FEF717FA28 -:103FB00010BD10B50120FEF712FA10BDF1B5009842 -:103FC00002287DD08D4C607A062803D186A18C48CA -:103FD00007F07FFE0026A6710125E572607A0321B5 -:103FE00014227E4F5043C0190174FEF7E7FA00987F -:103FF000002808D0012826D0022861D0032876D0D6 -:1040000079A180483FE08048007F002803D076A156 -:104010007E4807F05EFE65717B4D00202E60FEF746 -:10402000F1F9A968481C04D0012300221846FEF7C4 -:104030001FFA607A617A401CC0B2142251437A5848 -:1040400001219047F8BD0120FEF7DCF960790028D6 -:104050000DD06D488068401C09D0607A617A401CA0 -:10406000C0B2142251437A5806219047F8BD6648E1 -:10407000007F01280AD0022812D0032824D0042867 -:1040800036D059A1624807F024FEF8BD20790028F7 -:1040900003D02671FEF797FAE5705B480677F8BD06 -:1040A000207A002802D101F061F92572607A617AE4 -:1040B000401CC0B2142251437A580021904700E0BE -:1040C00030E051480677F8BD4F4F0123397B7868BF -:1040D0000022411A1846FEF7CBF92079002803D0B8 -:1040E0002671FEF770FAE57002203877F8BD1EE001 -:1040F000454E217870680123411A00221846FEF7C8 -:10410000B7F9207A002802D101F030F92572607ADF -:10411000617A401CC0B2142251437A580021904762 -:104120003577F8BD3B48007800F0A8FCF8BD607A10 -:10413000617A401CC0B2142251437A58052190473D -:10414000F8BD10B52D4C607A062803D126A132485F -:1041500007F0BFFD607A617A401CC0B2142251435F -:104160001E4A52580421904710BDF0B583B0062076 -:104170000290FEF7D2F9214C0090617A2748019015 -:10418000062920D0617A1420414314480918097C7B -:10419000042918D0617A142251430818007C03289E -:1041A0007DD00198009E02684068921B801B0C49DC -:1041B00012020002120A000A0B46082A6FD39A4222 -:1041C0006DD888426BD810488068401C03D006A187 -:1041D000134807F07EFD25E0543D0000D402002086 -:1041E000FFFF3F00170000207372635C72656D2E45 -:1041F00063000000AC0200201E05000058030020F0 -:104200004F050000A2050000380300205B050000F8 -:104210009605000011000020A905000048030020B9 -:10422000E505000000206071607A062807D16078FB -:10423000002804D0FE48C178417081780170607A0E -:10424000062815D0617A14204143FA480918097CE0 -:1042500004290DD1617A0291627A012114235A4313 -:1042600012181174627A5A431018807C6072A1721D -:10427000F14D687F297FF14F884233D0F04E287F7F -:10428000142148438019007CC05D0128287F07D095 -:1042900048438019007CC05D02282FD044E0FCE137 -:1042A000142148438019807A01280AD0297F0220EE -:1042B000142251438919097CC855287F0A2808D03F -:1042C00009E0297F0020142251438919097CC8552F -:1042D0002AE0002001E0287F401C2877687F297FA2 -:1042E0008842CCD1D74D287D00284CD0287CC15D98 -:1042F000012928D0C05D022830D03AE0287F14215F -:1043000048438019807A012803D0CFA1D14807F013 -:10431000E0FC297F00201422514389198872297FEB -:1043200051438919097CC855287F142148438219B3 -:10433000287F48438019017C0098FEF7E1FF287F21 -:104340000A28C8D1C5E7A97A012904D00221C1559C -:10435000002028750DE00021C1550AE0A87A012847 -:1043600003D0B9A1BC4807F0B4FC0020A872297C96 -:10437000C855287D002806D0297CB24A0098FEF74F -:10438000BFFF00202875029806281ED0142148433C -:10439000A8494018017C012917D107210174AF4DAC -:1043A000287B0A283CD0287BE97A401C884203D12C -:1043B000A5A1AB4807F08DFC297B02986854287BA7 -:1043C0000A2831D0287B401C2873607A06287DD0CB -:1043D000A07A00287BD00020A072617A142041438B -:1043E0009448A04B0A18566891681D46D2687C35DF -:1043F000DE67AA6069609C4D697E002916D002269E -:10440000617A14228B4851430818407B06281BD23E -:1044100003007B441B79DB189F440A1412100E0C16 -:10442000E87A0028C4D0C7E70020CDE70426E7E7F4 -:1044300000200FE0B4200DE073200BE0322009E0F3 -:104440000A2007E0072005E0FF207FA1E03007F009 -:1044500040FC0020C1B22973687E022801D00128E7 -:1044600010D1286942180098101A0002000A3A2850 -:1044700008D903206876323A1002000A28613220F7 -:10448000287308E0322906D2207A00280AD100F0E9 -:104490006DFF012005E0207A002803D000F08FFF97 -:1044A000002020726249082248782070097801298A -:1044B00001D0032906D101212171297B884201D92C -:1044C000421A0832A378002B03D001E08EE09CE072 -:1044D000921C2179002901D1002B5DD09446634ABA -:1044E00000990092019A176852687F1A511A3F0288 -:1044F00009023F0A090ABC4538D85C4A974235D8B8 -:10450000009A914232D8297B884214D92B69421AE9 -:104510009A1A1202120A101880190002000A2A615F -:104520006860002905D0032028770006000E3ED1E0 -:104530004CE00120F8E781420BD92A69511889190A -:104540000902090A6960002801D00420ECE7022072 -:10455000EAE7002B03D13CA1454807F0BAFB2869E4 -:1045600080190002000A6860002013E0002020711A -:10457000A070297B002908D0286940188019000202 -:10458000000A68600220287711E029698919090268 -:10459000090A6960287719E0287B00280FD029696B -:1045A000081880190002000A68600220287728692C -:1045B0000123811900221846FDF75AFF09E02869F6 -:1045C00080190002000A6860002028770120FDF7AA -:1045D00019FF617A1420414316480C2208188256AC -:1045E000012300206968FDF743FF0EE00120FDF77D -:1045F00009FF0020FDF706FFFDF7EAFE207A0028FC -:1046000003D000F0DCFE00202072A078002804D047 -:10461000FDF7D9FF0020E070A0706078002804D07A -:104620000348C1784170817801702079002821E029 -:1046300013000020D40200208C020020160000206D -:10464000CC010020AC0200207372635C72656D2E99 -:10465000630000000706000023060000C4020020DB -:1046600035060000CC02002038030020FFFF3F0089 -:104670008706000006D00020CE49E07009780029A6 -:1046800000D12071CC48017BC07A814203D0CB4855 -:10469000407800F0F3F90120E07103B0F0BDF0B50F -:1046A000C74C0746607A83B0062803D1C5A1C84825 -:1046B00007F00FFB607A1421C64E48438019007C36 -:1046C000032803D0BFA1C44807F003FBC34DA8686B -:1046D000401C03D0BBA1C24807F0FBFA607A14214A -:1046E000484381190C20085600216A460091117137 -:1046F000C01901AA6946FDF783FF6A4604201056D7 -:104700000F2801DD012000E00020009940186968B1 -:1047100040180102090AA9606079002804D0012329 -:1047200000221846FDF7A4FE03B0F0BD70B5AE4CF4 -:10473000AC4A0B1AA34214D3451AA54211D3934293 -:1047400003D9101A43185B1C0BE0954204D9511A87 -:104750000818401C434204E09AA1A44807F0B9FAA3 -:104760000023184670BD10B5014601230022022027 -:10477000FDF77EFE10BD10B50220FDF743FE10BD13 -:1047800010B5FDF7CAFE10BDF0B58D4D0446E87AB0 -:1047900083B0002803D18BA1954807F09AFA642CC6 -:1047A0004DD3944A00210846121B884147D39248B2 -:1047B000417F007F814242D19048007D00283ED158 -:1047C000687A1421834F4843844EC519306801AA82 -:1047D00000196946FDF714FF6946042008560028B1 -:1047E00002DD0098401C0090A96800986B680A18C8 -:1047F000D21A1202824B120A9A4220D8AA7C062AA6 -:1048000008D014235A43D2195268511A0902090ACE -:10481000814214D3B068401C05D00120FDF7F2FDA1 -:104820000020C043B060306800193060A86800996B -:1048300040180002000A7061012003B0F0BD0020A2 -:1048400003B0F0BDF8B50646401EC5B2142061495C -:1048500068434418207C002803D15AA1694807F016 -:1048600038FA6548017F407F81420CD0664A1423A4 -:104870004B439B181B7CB3420CD00A290CD0491C1B -:10488000C9B28142F3D15D48017D002964D0007C2A -:10489000B04261D10020F8BD0021F1E7217C05295B -:1048A00005D0217C062902D0217C072928D10121AD -:1048B0002174C17A0023027B8A4221D00246565CD1 -:1048C000AE4201D1012301E0002B04D00A2911D00E -:1048D0004E1C965D56540A290ED0491C167BC9B24F -:1048E0008E42ECD1002B0BD0117B002906D0117B1E -:1048F000491E04E00026ECE70021EFE70A211173CE -:10490000617C00292AD06774C17A0023027B8A4225 -:1049100024D0425CAA4201D1012301E0002B04D043 -:104920000A2912D04A1C825C42540A290FD0491C21 -:10493000027BC9B28A42ECD1002B0FD0027B014628 -:10494000002A06D00A7B521E04E00022EBE7002179 -:10495000EEE70A220A7301E017480027217C0129AB -:104960009CD1617C002999D10120F8BD70B5054624 -:104970001420184A05216843801801740E4C207BCE -:104980000A2811D0207BE17A401C884203D10DA176 -:104990001E4807F09EF9207B2554207B0A2807D06B -:1049A000207B401C207370BDE07A0028EFD0F2E736 -:1049B0000020F7E713000020C402002011000020AF -:1049C000580300207372635C72656D2E63000000F3 -:1049D000EA060000D4020020EB06000038030020A5 -:1049E000EC060000FF7F841E0020A1070E070000D8 -:1049F0002D070000FF1FA1078C020020AC02002041 -:104A0000FFFF3F006A070000CC0100200702000002 -:104A100001203E49400608603D4908603D490A685A -:104A2000FF231B029A4383121A430A6037498039D5 -:104A30000860704710B502460420374904E0C300FF -:104A40005B181B79002B0AD00346401EC0B2002B16 -:104A5000F5D132A1482007F03CF9FF2010BDC3007A -:104A6000CA50002259184A718A7101220A7110BD78 -:104A7000294A0021C00080180171704710B5044612 -:104A8000042803D325A1572007F023F92248E10089 -:104A90000C182079012803D020A1582007F019F91B -:104AA0006079A179401CC0B2814200D060710120C0 -:104AB000164940068031086010BD70B51548006881 -:104AC000800B022803D015A1722007F002F9124DC5 -:104AD000184C03262078C10048190279012A07D111 -:104AE000427983799A4203D042798271685880472B -:104AF0002078401CC0B22070042801D30020207010 -:104B00003046761EF6B20028E4D170BD80E100E0A8 -:104B100080E200E018E400E07C0300207372635C34 -:104B2000736F635F7369676E616C6C696E672E6328 -:104B30000000000024000020B548002101708170B1 -:104B4000704770B5B34D01236B60B34B1C68002CEC -:104B5000FCD0002407E00E6806601E68002EFCD022 -:104B6000001D091D641C9442F5D30020686018687C -:104B70000028FCD070BD70B5A54C0E466178884207 -:104B800003D0A6A16F2007F0A4F80325330007F097 -:104B9000ACF909520624245252525249520020784C -:104BA000022803D09DA1732007F093F82570A07808 -:104BB000022802D0012804D008E0A06806F004FF13 -:104BC00004E02269E168A068FFF7BBFF0020A07045 -:104BD000FEF7CAFA0420207070BDFEF77AFB01468A -:104BE0006068FFF7A3FD06462078022803D08BA15A -:104BF000872007F06EF88D4A8D498E48964205D879 -:104C00006269032A02D2521C626102E0864207D81E -:104C10004D71801BC86086496078FEF7D8FF70BD73 -:104C2000032003E0A0780028FAD1022006F0ACFEB1 -:104C300000F0E5F870BD79A1B12007F04AF870BD29 -:104C400070B50546FEF745FB714C60602078012881 -:104C500003D072A1B82007F03CF875490220087013 -:104C600000220A718D6004224A71724ACA60207063 -:104C70006078FEF7ACFF70BD10B5654CA0780028D9 -:104C800002D12078002801D0112010BD6A48FEF71B -:104C9000B1FA60706078002804D0012020700020F4 -:104CA000606110BD032010BD10B50124020B640427 -:104CB0000121624BA04202D29140186802E0203AE2 -:104CC00058689140084000D0012010BDF8B50E464C -:104CD000910004460F1915463F1F009106F085FE0E -:104CE000009980028919091FB14201D2012200E016 -:104CF0000022002D03D0FF2101318D4201D909206E -:104D0000F8BD4F498C421DD3A7421BD3844201D228 -:104D1000874203D34B4820187C2803D820463043D1 -:104D2000800701D01020F8BD8E420BD3002A09D194 -:104D30002046FFF7B9FF002804D13846FFF7B4FF3B -:104D4000002801D00F20F8BD3F4840490068884244 -:104D500005D02A4631462046FFF7F3FE0FE0FFF765 -:104D60008BFF0028EFD12A480121C66005618460CD -:104D700081702846302148431830FFF761FF00203A -:104D8000F8BD10B504462E48800A84420BD306F0C5 -:104D90002CFEA04201D8102010BDA4022046FFF72F -:104DA00083FF002801D00F2010BD27482749006845 -:104DB000884203D0204606F007FE0AE0FFF75CFFBA -:104DC0000028F1D112480221846081702048FFF749 -:104DD00037FF002010BD1A48010B01208840401EFB -:104DE000704700B50B460246FFF7F5FF104201D0B1 -:104DF0000F2000BD114802604360002000BD10B5C7 -:104E0000034C6078FEF74AFA00202070A07010BDB5 -:104E10002800002000E5014000E401407372635C5B -:104E2000736F635F666C6173682E6300307500009A -:104E30009C030020D0FB0100774B000000060040DF -:104E400000D0000080EFFFEF0C000020BEBAFECAC9 -:104E50003A560000F7480521817000210170417029 -:104E6000C1708160704710B5F3490A78022A07D0F3 -:104E7000CA681018C860C8689638FFF710FC10BDE3 -:104E80008A68101888608868F6E70378EB49EC4A6E -:104E9000002B02D0012B10D014E00379002B01D09D -:104EA000012B0FD14379002B01D0012B0AD183684C -:104EB000643B8B4206D2C06810E00379002B03D01C -:104EC000012B01D0002070474379002B01D0012B2A -:104ED000F8D1C368643B8B42F4D280689042F1D829 -:104EE00001207047F8B504460226FFF762F8006813 -:104EF000002803D0D3A1BD2006F0EBFE0127CD4D45 -:104F0000002C08D02078002817D0012805D00228CE -:104F100011D0032813D02F710DE06068C82808D382 -:104F2000FFF732FC002804D06068FFF79CFF0126E1 -:104F300003E0002601E000F0F7F93046F8BD2878DC -:104F40000028F8D16068FFF7A0FF0028E3D0606870 -:104F50000078002826D0A878042803D0B9A1F7202B -:104F600006F0B7FEB44F0020387060680079012861 -:104F700000D00020387160684079002837D00420C4 -:104F8000787160688168E868FEF73BFCB86060682B -:104F9000C0689630F8600320A870A749E878FEF74B -:104FA00016FEC8E7A4480221017061680979012949 -:104FB00019D00021017161684979002915D00421B7 -:104FC000417161688968963181606168C968C160B2 -:104FD000C068984C14346060FEF77BF920606F70F5 -:104FE0000220A870A7E70321E4E70321E8E70320F4 -:104FF000C6E7F8B58F4C0D46E178884204D0FF2013 -:1050000090A1193006F065FE28468A4F002501263A -:105010001437030006F069FF09061237607B8C968F -:10502000C39FC300A078032807D0A078022804D02B -:10503000FF2084A11D3006F04CFEF8BDA0780328A7 -:1050400007D0A078022804D0FF207EA1213006F0EE -:1050500040FE0420A07025712078002810D1FFF7B1 -:1050600002FFE078FEF7F4FBE0607D49886A7D4A44 -:10507000024022617B4AD2431040886200204FE008 -:1050800000F052F9F8BDA078032807D0A0780228D4 -:1050900004D0FF206BA1423006F01BFE20780028D0 -:1050A00002D000F04DF9F8BDA078032801D104200A -:1050B00024E0FEF70EF901463868FFF737FB0028B9 -:1050C00020DB796881421DDB091A5B48C16001461B -:1050D000E078FEF77CFDF8BDA078032807D0A07823 -:1050E000022804D0FF2057A1633006F0F2FD20789B -:1050F0000028D6D1A0780328DBD1052006F044FC97 -:10510000A670F8BD042006F03FFCA570F8BDA0789D -:10511000042804D0FF204BA1843006F0DAFD0220E1 -:10512000A1688847FFF7DEFEFF260546BD3642E050 -:10513000A078042804D0FF2042A1893006F0C9FDE0 -:105140000120EDE7A07804289AD0FF203DA18E3001 -:1051500006F0BFFD94E7A07804280AD06078002804 -:1051600002D0A078022804D0FF2036A1933006F0A8 -:10517000B0FD2078002894D12079002804D00620A2 -:1051800006F002FC2571BBE76078002805D02A49AB -:10519000E078FEF71CFD6570F8BD0720AEE7FF2044 -:1051A00028A1AE3047E7002D0AD0012D06D025A159 -:1051B000304606F08EFD022DF5D1F8BD042000E04A -:1051C0000320A1688847FFF78DFE0546F3E770B519 -:1051D000050005D0174CA078052803D0112070BD1C -:1051E000102070BD2048FEF705F8E070E078002838 -:1051F00003D0A5600020A07070BD032070BD10B565 -:105200000C480178002901D0112010BD81780529B2 -:105210000ED08178012929D08178002926D001215A -:1052200001708178012921D0807800281ED01FE0EC -:105230000F2010BD40000020AC0300203D8601007F -:10524000FF1FA1077372635C736F635F72616469B0 -:105250006F5F74696D65736C6F742E63000000007E -:105260000005004002810000F34F000000F068F8E4 -:10527000002010BDF8B5394E0446B078002801D0A2 -:1052800001280DD1002C0DD02046FFF7FEFD00288F -:105290000AD02078324D002808D0B078012823D0D9 -:1052A0000F20F8BD1020F8BD0720F8BD02272F7091 -:1052B0002079012814D0002028716079002811D0AD -:1052C00004206871A0689630A860E068E860E8682B -:1052D000224C14346060FDF7FCFF2060B77019E0C9 -:1052E0000320E9E70320ECE700202870207901285B -:1052F00016D0002028716079002813D0042068712E -:10530000A168F068FEF77DFAA860E0689630E86072 -:105310000320B0701249F078FEF759FC0020F8BD68 -:105320000320E7E70320EAE710B50E48816A0E4A3A -:1053300011400A4A126911438162FDF715FF10BD41 -:1053400010B5064CE078FDF7A9FF082006F01CFB1D -:105350000520A07000202070607010BD400000206B -:10536000AC03002000050040FD7EFFFF10B5EFF309 -:105370001080C407E40F72B6D1484178491C4170CF -:105380004078012801D106F039FB002C00D162B62B -:1053900010BD70B5CA4CE07800280AD10125E5702F -:1053A000FFF7E4FF06F032FB002804D0002006F0EF -:1053B000EBFA002070BDC34865714560F9E770B530 -:1053C000EFF31080C507ED0F72B6BD4C6078002872 -:1053D00003D1BDA18F2006F07CFC6078401E607078 -:1053E0006078002801D106F00DFB002D00D162B6D7 -:1053F00070BD10B5B248C178002904D000214171B8 -:10540000C170FFF7DCFF002010BD10B5044606F0A8 -:10541000FDFAAB49C978084000D001202060002087 -:1054200010BDF8B50246A64C0026A6710420202126 -:1054300001251027130006F058FD0D080A0B0D0F6B -:105440001113151D1F2124262800257122E002209A -:1054500020711FE00820FBE727711BE0217119E094 -:10546000012617E0FFF782FF06F0D0FA0028FBD0F4 -:1054700002260FE0207102E00820FBE72771A571EA -:1054800008E02171FBE74020F4E7FF208EA1763091 -:1054900006F01FFC06F0C6FA002809D006F0C8FA8C -:1054A000B04205D1304606F0C6FA0028FAD02CE00A -:1054B00001208007C5608C4900224A608B4A9661B2 -:1054C000804B02225A60856089480269D243D20625 -:1054D000D51702696D1C10231A4302610F4600E0C4 -:1054E00020BF78680028FBD0304606F0A4FA0028D8 -:1054F000FAD0002D04D17E48026910218A4302614E -:1055000070490220886000207860A07900280CD0C3 -:1055100006F07CFA054606F0C1F9764A002D02D065 -:10552000A260E06001E0E260A060002E01D100F026 -:10553000A2F8F8BD10B5044606F06EFA002805D0B2 -:105540005F490120C8704A78521C4A702046FFF714 -:1055500068FF10BDF8B5644DA8680026012802D187 -:10556000AE6006F011FA6868012800D16E60286804 -:105570000127534C012812D12E606079002803D0F6 -:10558000002006F001FA66712078002807D006F0A6 -:105590003DFA002803D0012080070761A770286921 -:1055A00001282AD12E6100F05FF8012080074761B1 -:1055B000A079002815D006F029FA009006F06EF9BF -:1055C0000099002901D0E16800E0A168411A022990 -:1055D00001DA8A1C11DC0099002901D0E06000E0AA -:1055E000A060FFF7C3FE06F011FA002804D00120E6 -:1055F00080070761A77000E02770E868012812D1D2 -:1056000000F032F800F030F800F02EF8A078002812 -:1056100004D1FF202CA1033006F05BFBEE60A670E6 -:105620002670FFF7CCFEF8BD10B5254CE0780028B9 -:1056300001D106F0E7F901208107886100F014F834 -:10564000A07800280BD0284CE068002803D106F091 -:10565000F2F90028F8D10020E06000F005F8002001 -:105660001849C043886010BD50210846491E89B2C0 -:105670000028FAD17047F8B51248192787601A49EF -:1056800000200860C86006F0C1F9BE0701240C4D77 -:10569000002802D03461AC7000E02C70FFF766FE89 -:1056A00008484760114928798863FFF7DDFFB46136 -:1056B000FFF7DAFF0C49002008617461F8BD0000B3 -:1056C0005C000020000300402E2E5C2E2E5C6C69D6 -:1056D00062735C736F635C7372635C736F635F634D -:1056E0006C6F636B2E6300000001004000050040FA -:1056F00000ED00E0FFFFFF7F8107C90E002808DAF8 -:105700000007000F083880082D4A80008018C06903 -:1057100004E080082B4A800080180068C840800997 -:10572000704710B50D20FFF7E7FFC4B20420C04357 -:10573000FFF7E2FFC0B2844203D023A11B2006F092 -:10574000C8FA26490120486010BD0121244A4803B7 -:105750001060244B00221A60234A5160234A1060D3 -:10576000234A11601E4980390860704701211C4A94 -:10577000480310601E4A51601A4A002111601B49FB -:105780000860704710B517490868012804D00EA1B9 -:105790005C2006F09EFA10BD104880680022C0B25E -:1057A0000A6005F02CFD10BD10B50E4801680029F7 -:1057B000FCD0FFF7E7FF01200C494003086010BD53 -:1057C00000ED00E000E400E07372635C736F635F00 -:1057D00068616C5F726E672E6300000000D5004048 -:1057E00080E100E000D1004000D3004080E200E012 -:1057F00000D000408307FF22DB0E9A408907090E84 -:10580000994000280BDA0007000F08388308FF488A -:105810009B001B18D86990430843D86170478308E0 -:10582000FB489B001B18186890430843186070479A -:10583000F849C86AC0070ED1F7480A6B42624A6B42 -:1058400082628A6BC262C96B0163F24940310968A6 -:10585000C20511434163704710B5F0494968487269 -:10586000097ACA0701D0012803D0890703D5022885 -:1058700001D1FCF7A8FB10BD70B5E9480024C46352 -:105880000125C563E7480460284600F0B8FBE649F7 -:10589000601E8860E5480461E5490D6101690029E1 -:1058A000FCD00461C460446084600460012000F0A6 -:1058B000AEFB70BDF8B5DF480125C560D8480026AD -:1058C000C663C563FFF7B4FFDB4C6661D34FDB4AA9 -:1058D0007868C17809028918A161A1696A069143B3 -:1058E000A161D04A03211160D0490E61CE604E60A3 -:1058F0000E60D349A16309078A692B4693431A02B4 -:10590000921C6263CF4AE2638279E2602563E662B9 -:105910008B692A4689699A438D43AA409107890F6A -:105920002161001D00F0D7FB78688078A060BE4937 -:105930001020486000210120FFF75CFF012000F0EB -:1059400057FBBC48C660F8BDF1B5BB4EB068B34C60 -:105950006568A97888420ED12D1D6878FDF70DFB8A -:10596000716AC9B2884206D12878FDF706FBF16951 -:105970000006884201D00020F8BDFDF7AAFC0746CA -:1059800060683946C069FEF7D1FE0546642800D23A -:1059900064256068816A02694919914203D97D21B1 -:1059A00049020161E7E72846FEF7EEFE0028E3D052 -:1059B0006168CF61886A40198862FEF770FE0098BE -:1059C000012500280DD0FFF775FF01F047F8706042 -:1059D00097484560964A95491432091D0E2000F0FB -:1059E0001DFB082000F00BFB0120974900044860D4 -:1059F0009648C56060689649406A086095490020ED -:105A0000086001460820FFF7F5FE082000F0FFFAC5 -:105A1000082000F0EDFA01F054FA0120F8BDF8B5C5 -:105A20000A467E4901268A4D00244868130006F084 -:105A30005CFA090631ECEC7BEBEA1EE91E000F462E -:105A40000978022912D040787B4C834D01280FD071 -:105A500001F0EDF8FFF72EFF01F002F86060012081 -:105A6000000568607868806AFEF719FE7E70F8BDF0 -:105A700001F057F9FFF71EFF00F0F0FF6060012012 -:105A8000400568606A4A69491432091D0E2000F019 -:105A9000C5FAE7E70F46497800291ED03978022970 -:105AA00022D0082000F0ABFA6A490C607868426A9C -:105AB0002A60027B002A25D020300673012062492B -:105AC0000004486000210820FFF794FE082000F041 -:105AD0009EFA082000F08CFA1BE0407801F0E9F90A -:105AE000F878FEF7CBFF06E04078012807D000F0F9 -:105AF00017FB00F09FFA3C70FDF736FB10E000F05A -:105B0000ABFAF6E720304A4A047310320F2000F057 -:105B100085FA78684078012804D00120FFF79CFEC0 -:105B20007C70F8BD0220F9E74C4A002753683B49D6 -:105B3000DB07DB0F8B70407801281ED001F03DF9A8 -:105B400000F0EEFA3548007802282BD033482C219B -:105B50004068095C002941D0007B00283ED001F05C -:105B600008FF384323D0002F38D02C4847683969C4 -:105B7000B86A884221D93C6121E02C48416801295A -:105B800005D1C068012802D11068012802D000F0B8 -:105B90009CFAD7E7012701F049F801F00EF900F06F -:105BA0005BFACFE700F046FA1C48047083E001205E -:105BB000FFF7CAFE002811D0F8BD081A386139690C -:105BC00000917D214902009805F085FF7D22C0B239 -:105BD000520200995043081A801838610F4F7868B4 -:105BE00020300473F878FEF749FF0020FFF734FEF9 -:105BF0003C70082000F003FA0120134900044860BB -:105C000012482DE03DE08EE03DE02FE000ED00E0A9 -:105C100000E400E080000010001700406C0000204D -:105C2000C01F00400012004000130040001100405F -:105C300000100040000A0040001500401E00010155 -:105C400021100000FFFF00000083004000800040A2 -:105C5000408500404081004000F5014000140040B4 -:105C6000C660FF20913049E02C70F8BD0D460978E0 -:105C70000229F9D0407801F01CF9E878FEF7FEFE21 -:105C8000F2E70C70F8BDFE4A1368002BFAD01460DE -:105C90002C22125C002A3FD00F460978022907D037 -:105CA000007B00280FD001F064FE002806D00AE037 -:105CB00000F0C0F93C70FDF757FAF8BD0020FFF77F -:105CC00043FE0028F9D1012000F099F9ED48006960 -:105CD00000F0FBF9786820300473F878FEF7CEFE08 -:105CE0000020FFF7B9FD3C70082000F088F9012082 -:105CF000E54900044860E548C66096202860E04811 -:105D0000046000210820FFF775FD082000F07FF9EE -:105D1000082000F06DF9F8BD0878012803D0286844 -:105D200096302860F8BD00F085F9C4E770B5D84D0D -:105D30006860012000F063F9012000F068F900219B -:105D40000120FFF757FD012000F052F90024D1484F -:105D5000AC60FDF74FFA69680870CC7101200872D9 -:105D60004C728C72CC727D200C7340020861203121 -:105D70000C732C706C70AC7070BD10B5C44840686A -:105D8000C179002903D00021C171FFF718FB10BDB4 -:105D900010B5BF482D224168525C002A0AD009780C -:105DA000002907D00178002904D002210170017870 -:105DB0000029FCD172B6FFF7E0FF62B610BDB4480F -:105DC0008168002901D000200847704710B50028DD -:105DD00005D0AF4CA060B048FEF72CFEE07010BDBF -:105DE00070B50C46054600F03BFE2246294605F0FC -:105DF00031FE70BDF8B5A64C154600266268012735 -:105E00005670D0615176002B01D0177500E01675E1 -:105E100001F07DFD002804D060687D210776C9006F -:105E200003E06068032101769C496918016261689A -:105E30004D62086A643888620E7308781431FDF781 -:105E4000C6FE2770F8BDF8B5914C1646012562686C -:105E5000069F5570D0615176002B01D0157501E079 -:105E60000020107501F053FD002804D060687D21EA -:105E70000576C90003E0606803210176874971183F -:105E8000016261684E62086A643888620F7308783C -:105E90001431FDF79CFE2570F8BD10B57C48C07824 -:105EA000FEF7ECFD10BD10B5FDF7ABFC10BD10B555 -:105EB000FDF70FFA10BD764949688871704774493B -:105EC000496888707047724949688880704770498E -:105ED0004968C87070476E4901204968C8727047A8 -:105EE000F0B56B4D07466868C1B0807A002831D1A3 -:105EF0006B480026C6630124C463FFF799FCFFF7D3 -:105F000035FA6A6867489179C16006619178816065 -:105F1000654BF90716D0AA2141626449C161082185 -:105F20004161634981614663FE216D46297000210C -:105F30006E187170491CC9B2FE29F9D3456007205B -:105F4000186004E01C6057490320403108604D4848 -:105F50000460947241B0F0BD70B54D4D6868807AB0 -:105F6000002814D0FFF788FC4F48002404605148F3 -:105F700004614C4940310C60424A012111610169C0 -:105F80000029FCD00461FFF71AFA6868847270BDBA -:105F90004848C069002804D04248403080684042E8 -:105FA00040B270473A488078704710B5384840682A -:105FB000C179002903D10121C171FFF7D7F910BDC3 -:105FC000334949680872704731484068007A704721 -:105FD0002F484068407A012800D0002070472C48A4 -:105FE0004068407A022801D00020704701207047A5 -:105FF000C106C90E012088402F4908607047C106BC -:10600000C90E012088402C49803108607047C106C4 -:10601000C90E0120884029490860704710B5284CF6 -:10602000C3001B1919605A600121814024481038AF -:10603000416010BD10B50120134900048860134968 -:10604000012048600E49002008600820FFF7D7FFB4 -:106050000820FFF7DCFF10BD10B50A490120886158 -:1060600014490020C8610E2000F065F80120144991 -:106070004005103988600F2000F05DF822E0000034 -:10608000408100400010004000830040008000403C -:106090006C0000201F5A0000BF5D0000B80B00001C -:1060A000C01F00400015004000120040BEBAFECAEA -:1060B000FF0004030011004000E100E080E200E086 -:1060C00010F50140FFF7D8FB10BD10B500F075FECC -:1060D000FFF7C2FF10BD70B505461C48002640689A -:1060E0001B4CC17A002907D0C672606A000A000200 -:1060F0006062E069E66170BD606A000A0002606289 -:106100006878FCF73AFF616A08436062E069E6611B -:106110002878FCF732FFE16900060843E06170BDB2 -:1061200010B501200B49000588600F2000F003F82E -:10613000FFF7A2FB10BD0121064A814091600021BA -:10614000C000801801614161704700006C000020B0 -:106150000015004000F5014070B50C460546FFF7FC -:10616000A6FE01462846FEF7E1FAFE49002805DAB8 -:106170004042400205F0AFFC201A03E0400205F067 -:10618000AAFC001980B270BD10B5F74C208F618F4A -:10619000626E401AF34980B24843410AC005C00DFF -:1061A00080186066820500D5491CC005C00D606678 -:1061B000E06DFFF778FEA06510BD8100EB48415807 -:1061C000084640308278D20701D0C078704720312D -:1061D000C8797047E64A04211078030741D5F8B51D -:1061E000F72318401070E04A507A8300DF48C35804 -:1061F000184640308478E40701D0C07801E02033AD -:10620000D879002804D0012804D0022803D101E065 -:10621000032100E00221D748D74C85792078C307B5 -:10622000D148DB0F006E002D05D0D27ED200E132C6 -:10623000FFF7E0FD0BE0157ACB4ACA4ED28D7243D0 -:10624000520A122D08D000250095FFF7FCFD20789A -:10625000400840002070F8BD01250095FFF7F3FDD0 -:10626000F5E77047C048407A8100C0484058017F38 -:10627000490702D501212030C1717047012A00DC95 -:106280000122491E401ED30703D0491C0B78401C35 -:106290000370521007D04B784370891C801C0B7818 -:1062A0000370521EF7D17047C27B0F21521CC2737C -:1062B00004E0491EC9B2425C521C4254425C002AAE -:1062C00001D10029F5D17047002A4ED0FFB5AB4867 -:1062D00083B001461F311030154601910090102DFA -:1062E00004D91024A54805F0D2F905E02C46A348AE -:1062F00005F0CDF9002C22D003990498491E401EC8 -:10630000019AE30706D0491C521C0B78167873409B -:10631000401C037063080CD04E785778891C7E406F -:106320004670921C0E781778801C7E4006705B1EAB -:10633000F2D1039800190390049800190490009971 -:106340000F20CA7B521CCA7304E0401EC0B20A5C14 -:10635000521C0A540A5C002A01D10028F5D1281BDE -:1063600005062D0EBBD107B0F0BD7047F8B58048CB -:106370007D4C00787D4E8107607A8300002967DBC1 -:106380007F48814D007882077E4801780DD17F4893 -:106390000078400709D5C80607D52878C20904D176 -:1063A000A22210432870F25810712878C7076E484F -:1063B000C27E501F002F30D0754F09072BD575496D -:1063C000921FA164082A09DDD2B20023891DB81DDD -:1063D000FFF77AFFA16C7879487105E0C2B200231B -:1063E000491D781DFFF770FF607A800031586948B9 -:1063F00004F0FCFBA16C387908712878000704D5FB -:10640000082265496548FFF739FF65488022017811 -:1064100011430170F8BDA764F8BD090718D55D4F99 -:10642000C2B2A764F0580023401D791DFFF74CFF4E -:10643000607A052280003158A06CFFF71FFF287892 -:106440000007E9D50822791D5448FFF717FFF8BD6A -:10645000F058A064F8BDF8B5474C434D207880064D -:1064600005D400266E87FFF722FD6E66E865698F0A -:10647000E86DFFF771FE2887FFF719FDA865298FE2 -:106480006987E865FFF768FE07462078F72108402E -:10649000207072B6FFF789FD62B641373448012695 -:1064A0000178314301702F8704F06DFBFFF7F5FC95 -:1064B0002078810601D53043207010202872207882 -:1064C000202108432070F8BDF8B527482D4D017AEA -:1064D000467A264F102941D1E91C0978490604D58E -:1064E000002141721121017238E02E4C2178CA0638 -:1064F00034D5FF22427203799E4200D10271B0006E -:1065000038584030007A800611D5EF2001401D48F0 -:10651000217000780A0780088000002A01DA801CB8 -:1065200000E0401C2870F7200140217016E0072190 -:10653000304600F06AFA2078EF2108402070287871 -:10654000114C80088000401C28702078C00903D0BE -:106550000621304600F059FA022020700A480178DE -:10656000B00021E0093D0000780000205804002020 -:10657000A000002098000020870000206C07002069 -:106580008E000020840000208C0000208500002068 -:10659000FA030020BC030020C1030020F600002005 -:1065A00088000020890000203A581171FE490978BE -:1065B000490603D4385829784030C171F8BDF8B580 -:1065C000FA4D07468600A8594030017A89060DD554 -:1065D000C1798907890F012908D100218171A85942 -:1065E0004030C17989088900891CC171EE48007862 -:1065F000800627D5EE4C618FE06DFFF7ADFDEA49CF -:1066000009780A07EB4909D5627AFF2A13D092006C -:10661000AA58128A101A80B258280CD8A8594030AB -:10662000007A800606D5607A874203D1087808226E -:1066300010430870F8BD0878C00603D510202072FA -:10664000FFF742FFFFF707FFF8BD082A01D927200F -:106650007047FFB50546D44881B00278D348530649 -:1066600004D5002D08D1312005B0F0BDAB00C358D2 -:106670004033DB799B0716D0CC48AF00C3599C460A -:106680004033D879C40611D41B7A9C060BD4440637 -:1066900009D4DB0707D1520608D40A0606D58007BD -:1066A000800F022802D2152005B0F0BDA0200140C5 -:1066B00002200143C04EBE48F571427ABF480C46E5 -:1066C000002100789646954208D1002806D043075D -:1066D00004D4BB490978C9092AD10121B54B1B78DB -:1066E0009A0613D5DF221340B24A7545137003D1C1 -:1066F000002901D100280FD1B24801788906890EFE -:106700000170FF20F071212005B0F0BD62461379C1 -:106710001B0601D500290BD0754512D1AA4A0029C4 -:106720000BD0D11C0C70491EF7231840087007E0ED -:10673000FF20F0711F2005B0F0BD107820431070CD -:1067400014789A4861460C71C0590822401D04997A -:10675000FFF794FD9648407A854207D19748007824 -:10676000002803D1200601D5FFF77CFD8F49DF23E8 -:10677000C859403082791A408271FF20F071C8599F -:106780004030007A800605D52846FFF718FF5020D4 -:1067900005B0F0BD502005B0F0BD01898388C288E6 -:1067A000481E934201D180B270479A1A891A01405B -:1067B000491E88B27047F0B5844B0F461C4606460A -:1067C00025899888D9886C1E884201D1A1B204E03D -:1067D000411A691A2140491E89B2914227D31446B1 -:1067E000281A734A794985B28988D06E0818AC4254 -:1067F00002D82246394608E0EAB23946FFF73EFDA4 -:10680000601BC2B26A487919C06EFFF737FDB00647 -:1068100004D5684880220178114301706B48818853 -:1068200002890919521E114081805020F0BD22209A -:10683000F0BDF8B5604C8227A07A012813D1644DD1 -:10684000A88800280FD05A4E706F002804D001216C -:106850000170A88800285BD0207B810706D5A98815 -:10686000082902D002E02120F8BDA027C00720D1CE -:10687000E07A81004D4840580079000614D508227E -:106880003846316FFFF797FF502859D1306F0830E5 -:106890003067A8880838A880B80636D545488022D1 -:1068A00001781143017030E0424820220178114301 -:1068B000017008223946E07A336FFFF7C6FE502890 -:1068C000D2D1306F08303067A8880838A880227B82 -:1068D000D0071AD03F480378590608D5811D09789A -:1068E00000291DD0490702D420210B430370E07A10 -:1068F0006072364900208880C8802E480178490699 -:10690000490E0170500840002073A8880028A3D1C8 -:106910000220A072706F00280ED0002101700FE0DD -:1069200010210B4303702C49002008702070B08E9A -:106930007086A0786070DAE71121607A00F065F85F -:106940005020F8BD10B51C4AD37A984215D10529BC -:1069500007D0062905D085290FD1FFF76AFF00214E -:106960000BE0FF231A4CD3720020A0809072403CB1 -:10697000646F002C00D020705372084610BD10B414 -:10698000164B0A4A09292BD002290AD18000105837 -:106990004721095CC90604D42721095C00292ED0AF -:1069A000438410BC7047000087000020580400207A -:1069B0007800002089000020980000208E00002030 -:1069C0008F0000208B0000208C0000209C070020FE -:1069D000B80000208800002097000020FFFF000082 -:1069E000810050584724245CE40601D5038400E06C -:1069F00043845058FE232030437110BC7047418CB3 -:106A0000428A8918418410BC704770B504460D460F -:106A1000FFF7B5FF29462046FFF794FFFC4B1D7892 -:106A20006907C90F491E014217D0FA49CA78561C96 -:106A3000F6B2CE70202E01D30026CE708978F6B241 -:106A40008E4203D1042005431D7035205100F24AC7 -:106A5000545489184870FBF7B6FA70BDEF48704778 -:106A6000EF48704710B5FFF793F9FFF775FA10BDBF -:106A700070B505461C46080601D5104604E00529F8 -:106A800000D30421E748405CFFF715FA2846FFF7DA -:106A900016FA2046FFF724FA70BD70B5E24C850067 -:106AA00063590E062033002E01DADA7705E0052956 -:106AB00000D30421DB4A515CD977D649497A884210 -:106AC00004D160592030C07FFFF7F5F970BDD64A78 -:106AD0008300D25820329177CE4A527A904204D124 -:106AE00010B50846FFF7EBF910BD7047CE4980009E -:106AF00008582030807F7047CC4B42009952C54ADD -:106B0000527AFF2A0AD0C84B92009A58527B82428E -:106B100004D110B50846FFF7D6F910BD70478300C1 -:106B200030B4C148B024C55840356C70C4584034A6 -:106B3000A5796D066D0EA5710D068024002D09DA6C -:106B4000C15840314A70C058403081792143817129 -:106B500030BC70470029FBD027228900D243511A4C -:106B6000C25840325170C058403081792143817100 -:106B700030BC7047704770B5A64CE18FA06EFFF730 -:106B8000EBFAAB49A0870978A74D890706D0617A4F -:106B90008900695840318979C90646D4A54910232E -:106BA0000A781A430A70218FE27E081A411E1346A2 -:106BB0000D3BDB105B1C0904490CDBB20004A37124 -:106BC000000C05D00126F603B04201D85818A07178 -:106BD0000D2A1CD991489849012A00DC0122401E47 -:106BE000491ED30705D0491C43780E787340437083 -:106BF000401C52100BD046784B78891C5E40467082 -:106C000083780E7873408370801C521EF3D1FFF797 -:106C1000BFF9617A8900695840310870207A1228DA -:106C200003D1A08F20870520A07170BDA3E7F8B520 -:106C3000FFF79CFB7F4EF72130780840307072B62A -:106C4000FFF7B3F962B67D48724C00782546C0075D -:106C50002035002805D0E878062802D27849085C5B -:106C60000EE030784106704805D500682030807FFE -:106C7000FFF725F906E0617A890040582030807FCF -:106C8000FFF71DF9E07EFFF722F96E486E490078A4 -:106C900008716E490978890701D4A16C0871C00791 -:106CA00034D0E07E84460D2826D969480078C00992 -:106CB000A06C1DD06646604A012E00DC0126401EF5 -:106CC000521EF10705D0521C437817787B40437061 -:106CD000401C731010D047785178921C4F40477079 -:106CE000877811784F408770801C5B1EF3D103E0DA -:106CF0000179ED2251400171554801784906490E4C -:106D000001706146A06CFFF76BF803E00D21A06CE9 -:106D1000FFF766F8E879617A884201D1FFF7DBF87E -:106D2000F8BD70B5434CF72120780840207072B64A -:106D3000FFF73BF962B64148364D0078C00706D0F0 -:106D40004448C078062802D23D49085C0EE020780D -:106D50004106354805D500682030807FFFF7AFF841 -:106D600006E0697A890040582030807FFFF7A7F855 -:106D7000E87EFFF7ACF870BD26492648497AC3790A -:106D8000002229488900092B09D0032B0ED0042B9F -:106D900004D140582421095CC90705D070474058E8 -:106DA0004721095C4906F9D502847047214B1B78BD -:106DB000DB06FAD5405842847047DDE770B41549C8 -:106DC0001448497AC279244C012317488900092ABA -:106DD00044D0032A4DD0042A52D00C2A01D0052ACF -:106DE0004CD1134A1278920748D04258107F40077E -:106DF00044D518491446487B2034401CC5B24D7315 -:106E0000E6790020002E4DD00222E2714EE0000013 -:106E100089000020780000200806002036040020A9 -:106E2000DA03002010BF0000580400205C07002097 -:106E30008E0000208700002015BF00009700002072 -:106E4000F00000208C000020FA030020A0000020A9 -:106E50008800002098000020FFFF000042582725EE -:106E6000AD5C002D01D0148403E0148C558A6419A4 -:106E700014844058203001791943017170BC704767 -:106E80004058014620310A79D207F7D1C979002943 -:106E900002D0048470BC7047018C428A8918018436 -:106EA00070BC7047D27FAA42FAD8E371487370BCB5 -:106EB000704710B5002801D1FFF758FAFFF77EFFA1 -:106EC00010BD10B5F74CE18F6187A06EE065FFF74C -:106ED00043F92087FFF758F9208FE087A06DA0665F -:106EE00010BDF3B5CF788B788FB05F40CF700E793F -:106EF0007E400E714D79B44675404D710B95887981 -:106F000068408871CA794240CA714C7854404C70CC -:106F100008940E78A64666400E70EF240796264029 -:106F20008F24664000967446BE2634403626744050 -:106F3000009E3443A646EC241E462640202466408C -:106F400074462643B646BC06A40E1A2674407646FE -:106F50003443A6466646D7242640472466407446F6 -:106F60002643DB2425401124654035437926044619 -:106F70003440502674402C43F72515409326754025 -:106F8000254305D0C8490F98FFF7B6FD11B0F0BDF5 -:106F9000079C10252C40089D41263540254364461A -:106FA000282634402C4386252840204313242340A0 -:106FB000BC09A40108701C430B9B24252B402343D0 -:106FC000082422401A434A70110201430F98FFF728 -:106FD00093FD11B0F0BD7047704710B504F0E9F8AB -:106FE00010BD10B5102104F0E4F810BD00B5014645 -:106FF0001022AE48FFF742F900BD00B5014610224D -:10700000AB48FFF73BF900BD30B50D460446002AFA -:1070100013D0012A10D1214603220D312846FFF753 -:107020002DF90A22E11CE81CFFF728F92846032263 -:1070300021460D30FFF722F930BD214604220C31E4 -:107040002846FFF71BF90822211D281DFFF716F916 -:107050000422284621460C30ECE710B4914B954AA7 -:10706000D86E1060002090809349D0804C881481A5 -:10707000924AFF2454720880D472888090725867B4 -:1070800010BC704770B58E4982008B5840331C7A13 -:10709000A40608D4DC79A407A40F012C03D1894CE1 -:1070A0002478650601D5152070BD9D79ED0901D0C4 -:1070B000A02500E020259D718B584033DD79AD0877 -:1070C000AD00AD1CDD718B58DD7D6D086D00DD758B -:1070D0008D580023EB81A30602D4FFF7BCF906E02C -:1070E00089584031097AC90601D5FFF768FA0020AE -:1070F00070BD13B582B0714A0C466846017A537A66 -:10710000407A994205D1382801D0392801D1FF2091 -:10711000507288006A4908584030007A400703D509 -:107120002146029803F06BFD029800906846407873 -:10713000421E092A06D8012191405F4A1288114255 -:1071400000D0FF20694648720021FF2800D121703D -:107150006846008904B010BD402801D20020704765 -:107160000120704710B4544AFF28508002D9FF20F4 -:107170000130508053884020402B09D05488430070 -:10718000A34201D898B200E0508053888342F5D1E1 -:107190004448C16610BC70478188C2880089891A3A -:1071A000401E014088B27047F8B504464148464E3B -:1071B0008288C3880089D21A401E0240C806002176 -:1071C0006170050E832192B2A01C217095420ED9E8 -:1071D0003178C9091CD001216170D1080170471CA8 -:1071E000D5B2072200213846FBF7ADFEF81D29462F -:1071F00003F05FFD3078C00910D02E488188C28826 -:107200000089891A401E01400804000C02D005E0E4 -:107210000020F8BD20782021084320700120F8BD0F -:1072200070B5244D0446A888E988401A2989491E6A -:1072300008400004000C17D0822020700821601C38 -:1072400003F037FD20480078C0090CD0A888E988F1 -:10725000401A2989491E08400004000C03D12078F7 -:10726000202108432070012070BDF8B59446154ACE -:1072700006461D461278CB082120520603D5002E63 -:1072800024D13120F8BD0E4AB40012594032147A8C -:10729000A4061BD4D2799207920F022A16D8162080 -:1072A000F8BD0000780000205B2500006C0700207E -:1072B0007C0700209C070020B800002098000020D8 -:1072C000580400208700002089000020FB4CA27A8F -:1072D000E77A002A09D0012A2ED0022AE0D1F84804 -:1072E0000078C0090AD01F20DAE7E80708D0FF2F8E -:1072F000F9D1D80088420AD1E6720AE0E80701D045 -:107300002020CDE7B74202D1D800884201D03320F7 -:10731000C6E7EC4A60461067EB4881802573012080 -:10732000A072FFF786FAE907BAD05028B8D0FF213B -:10733000E1720021A172B3E72220B1E7DF49897A27 -:10734000002901D01F2103E0DE4A002150670170AF -:1073500008467047D948807A002801D01F2070471E -:10736000D84A0020506770470B78042B01D9302091 -:10737000704730B4D54C850062595B064032507A74 -:107380005B0EC009C001184350726259400649782B -:107390004032400EC9010843507230BC0020704793 -:1073A0000A79042A01D33020704700B5C74B80000A -:1073B0001B5890002E3018180422FEF75FFF0020A3 -:1073C00000BD8200C148835859718058C278920725 -:1073D000920F022A01D0090A81717047BA490880C8 -:1073E0007047B9490A7802700988090A41707047E4 -:1073F00070B5B64C850066592036F1726659203654 -:107400003273625920325373FFF761FB70BDF0B4E1 -:10741000AC48002305781A46002D2DD9AB48042727 -:10742000990046580D24347744585B1C62774458C1 -:10743000DBB2A7771D244658640234834658748310 -:1074400046580324F47744584034A2704658022426 -:107450004036F4704458203422714458203462710C -:1074600044582034A27144582284445862844158BC -:107470002031CA71AB42D3D390484273F0BC7047FD -:1074800010B40A781307820090481B0F84582377A2 -:107490004B7884581B071B0F63778B7884581B0726 -:1074A0001B0FE377CB7884581B071B0FA3774B790F -:1074B0000C791B02234384582383CB798C791902DE -:1074C00080582143418310BC704782007F48835815 -:1074D0001B7F1B071B0F0B7083585B7F4B70835800 -:1074E000DB7F8B7083589B7FCB7083581B7E0B7127 -:1074F00083581B8B1B0A4B7183589B7E8B71805862 -:10750000408B000AC871704710B40A78D407820013 -:107510006E48E40F835840339C7083584978403359 -:10752000D97080584030022901D90221C17010BCA5 -:10753000704782006548835840339B780B708058B1 -:107540004030C078487000208870C8700871487159 -:107550008871C8717047F0B45A4900234A7A5B4970 -:10756000840094461D4690420CD10A59FB272032D4 -:1075700016797608760016710A5920323E40167147 -:107580004E4A55730A594726B65CB707BF0F022FFC -:1075900010D0F043800756D1107FC00733D04C483D -:1075A000F60626D5168C178BBE422CD386421DD1EB -:1075B00002231CE0434E604502D1F079082810D028 -:1075C00020329079401CC6B296710A59107F00078C -:1075D0002CD51046927F2030964227D30123857107 -:1075E00024E0107F00072BD5012329E00123158417 -:1075F00009E0568C578BBE4205D3864201D1022347 -:1076000000E001235584085920304279521CD6B23B -:1076100046710A59107F800708D51046527F2030E6 -:10762000964203D3FF2E10D00123457108594030F4 -:10763000C0798207920F022A02D0C043800702D18C -:1076400008592030C371F0BC70470223EDE7214890 -:107650001E4A007881061B48407A80001058002995 -:1076600003DB1D490978890606D5017F490702D544 -:1076700002212030C1717047014620310A7952073A -:1076800005D5007F4007F6D50120C871704700205E -:10769000C8710A494873704700B50C490F48086023 -:1076A00008490120087048700C490D4A08465830B6 -:1076B00010606D314320FFF755FD00BD980000209C -:1076C0008900002078000020B80000205804002025 -:1076D000FFFF00008C0000208D000020D00400205F -:1076E00080050020F8B58446FE4800250570FE4858 -:1076F000FF260090C671FD48FD4C021D29460F2350 -:107700008F00E55116700832491C5B1EF8D16146A6 -:107710000127F84C00290CD0F849F74A0A60783163 -:107720000A4627706770583202606D314320FFF7B8 -:1077300019FDFFF792FCFFF76AFEF149002008707F -:10774000F04A02211170FF212171EF4A6071F04B64 -:1077500017701870EF4BED4A1870EF4B1870EF4B25 -:107760001870A070E07020726172ED4908700D21F0 -:10777000E1760321A1762077EA48A08600988170FF -:107780000A20107072B6FEF7F8FA62B6E64E0020D4 -:107790003146FFF7B1F9E54F012569007E52617A64 -:1077A0003046FF2907D0D54A890051584A7BAA4262 -:1077B00001D1FEF788FB6D1CEDB2082DEDD30099C9 -:1077C00000200871411EE186D949DA4A0870217803 -:1077D000491E1170C949FF2613789C000D59403588 -:1077E000A8710D594035E8710D59403528720D5971 -:1077F000403568720C594034A6725C1E1470002B20 -:10780000EAD1F8BDF0B502784378048941680F2ABF -:1078100021D893421FD8002A1DD000291BD0002C4C -:1078200019D018461525684384460846022A06D909 -:10783000951E002D03DD582555436818B038002BE0 -:1078400000D06044401A80B2A04204D8201A864674 -:1078500080B2402801D20020F0BDA648A74C02709B -:1078600043700020A44F08E0582545438600ED19D9 -:10787000401CC0B2A551022801D29042F4D3951EFB -:10788000002D10DD0020EDB2582646438700761803 -:107890003F19401C6D1E2D06BE602D0EF4D15820E0 -:1078A00042435118B039002B15D0A3480022DC0701 -:1078B00002D00830012201605B080BD0152454432C -:1078C0006418846015341030921C5B1E1B06046023 -:1078D0001B0EF3D16144704680B2FFF743FC0120D8 -:1078E000F0BD89490A780243C0060A70000F00D033 -:1078F0003320704784490A7882430A70704782486F -:1079000000787047814800788006C00F70477F4834 -:1079100000780007C017401C70477849800008585D -:107920004030C079704775498000085840308079F0 -:107930008006C017401C704710B50C466F49800088 -:107940000958204603F052F9A0784006400EA07076 -:1079500010BD6A4980000858C078704781006748A8 -:107960004158088A4031C979C90601D55B3080B2D7 -:10797000704768480078C006C00F704710B55A4C71 -:107980005E4AE0718000105803F030F9FF20E0718A -:10799000002010BD70B5594D0C468600A9594A8A81 -:1079A000A2420FD20B8A9A1A0A82A95912190A8284 -:1079B0005049497A884205D154480078000701D5DA -:1079C000FEF749FDA859448270BD4C498000085813 -:1079D000408A7047494A80001058403041717047D2 -:1079E000464A8000105881757047444A80001058FC -:1079F000818270470907C90E404A80001058C1753E -:107A000070473E4A800010584030017170473B4932 -:107A100080000858403000797047384A8300D258B7 -:107A2000C9074032D379090E5B065B0E0B43D37155 -:107A3000304A527A904205D1404802785206520E9E -:107A40000A43027070470B4600B52C498000095864 -:107A50000822491D1846FEF711FC00BDF0B4274B63 -:107A600080001D584724645DA40702D0F0BC152097 -:107A70007047082A02D3F0BC292070470024203523 -:107A8000EC771D5842262035AE771E58B02540367B -:107A900075701E58022540367571FF261F583D36F9 -:107AA000BE821F580A26BE751E580909F4751E5855 -:107AB0000901403634711E58491C35711D58403536 -:107AC000E97101211D584903698219584A731958EF -:107AD0004C711858C1788907890F022900D0847128 -:107AE00017482FE0A000002098000020800500200B -:107AF0009404002078000020D004002058040020C6 -:107B00008E0000208F0000208600002087000020CB -:107B100088000020890000208A0000208C000020BE -:107B2000850000208A0C00005B2500005C07002017 -:107B30009D0000208B00002078050020840000209C -:107B4000970000200470F0BC00207047F8B50C4688 -:107B5000FA4A8100535840331C725558630713D5B5 -:107B600000232035AB7255584B262B8557580323DD -:107B70002037FB725758272520373D735158203145 -:107B80004E731946FEF7A3FFC820044201D03320EC -:107B9000F8BDA00602D5EA49002008710020F8BD12 -:107BA0008300E648C1584031CA799207920F012AF2 -:107BB00001D0152070470022CA71C05840300272AF -:107BC00010467047F8B5DD4C05468600A0590146C1 -:107BD00040310A7A920604D4C9798907890F0129AC -:107BE00001D81520F8BDD64F0621FD7120308172D5 -:107BF000D448417A8D4205D1D348102201781143EF -:107C000001701AE001798D4201D1FF210171A05963 -:107C10004030C17989088900491CC1710721284673 -:107C2000FEF7F3FEA0590079000603D50621284689 -:107C3000FEF7EBFEA15902200871FF20F871002029 -:107C4000F8BDF8B50446C1480078800601D5192072 -:107C5000F8BD0020FFF716FA0028F9D1BA49FD2235 -:107C600008781040E207920F10430870B34CB848F0 -:107C7000216802F0BBFFB34901200B78012B0DD91D -:107C8000202602278200A158401C40318D79C0B2C5 -:107C900035438D71A15898420F71F3D3A948112132 -:107CA00001720020F8BD70B5A54CA649E0714A7A72 -:107CB000FF25022190420AD1A64A1278002A02D05A -:107CC000E571002070BDA44A1170A44A11709B4A4E -:107CD0008300D6583171D158202340318A791A4314 -:107CE0008A710621FEF791FEE571012070BDF8B59D -:107CF000994900240B789A495D06097820D4002818 -:107D000007D0480703D5C80601D4382413E005245A -:107D100011E093484A0706D5CA0604D43924F7224D -:107D20001140017000E00624980604D48D480178C3 -:107D30008906890E017002208749012208704AE0F5 -:107D4000844B1B78002B46D0002805D048072BD544 -:107D5000C80629D538242AE0480703D5C80601D526 -:107D6000392400E0042477498878CB78497A98420E -:107D700011D07D4A4500AE187778802F04D1555D2B -:107D80008D4201D1FF257570401CC0B2202800D360 -:107D900000209842EED1694889004058EF224030D7 -:107DA00081791140817102E0002002F0B8FF6F4933 -:107DB000EF250878684B02469206D20F2840120140 -:107DC0001043DF2210400870C81D00781870881D0D -:107DD00000780007C20F5B480D21C1760027634B76 -:107DE00007761D78F7263540614E06213770761CE0 -:107DF0003770F1706906490E1970591C0B78BF2550 -:107E00002B400B70C91C0B785A49067FDD0705D043 -:107E100002252E4306770E782E4304E0FD252E40E2 -:107E200006770E782E400E70382C01D0392C04D1F4 -:107E30004B49FB260D7835400D70464D3F492F705C -:107E4000407AD20785004E59920E33714959DF2589 -:107E500040318B792B4013438B712146FEF7D5FDC2 -:107E6000F8BD3C480078002801D000203FE770476B -:107E70004378032B01D93320704710B4314A9376ED -:107E800083789C080FD1C478002C0CD10479002C85 -:107E900009D1137743799C0805D18479002C02D14C -:107EA000C479002C02D010BC3320704753770A29C4 -:107EB00004D3437A047A1B02234393860B2902D30B -:107EC0001F49827A8A70294900780A78BF23C0073F -:107ED0001A40400E02430A7010BC00207047002276 -:107EE000002812D01748837E0B70037F4B708A7076 -:107EF000CA70437F0B714A718A71808EC871000A03 -:107F000008720F488078487204E0032008704870B7 -:107F10008A70CA7000207047F7B50C4A0C464109B8 -:107F2000C606127800274901F60E82B0520623D504 -:107F3000002E30D1312005B0F0BD000058040020E3 -:107F40009800002078000020890000208700002091 -:107F5000C40000208E0000208C0000208F00002034 -:107F6000840000208B0000200806002088000020EC -:107F70009700002096000020FE4AB300D2584032FD -:107F8000137A9B0607D4D2799207920F022A02D85D -:107F9000162005B0F0BD620702D0272005B0F0BD65 -:107FA0000A0600D5012749060A0EF34D0092697AA8 -:107FB0000DD0F24A009B12789509AD019D4242D046 -:107FC000EE489106890E0170202005B0F0BDFF2912 -:107FD00002D01F2005B0F0BD082282213046049B4C -:107FE000FEF733FB5028F5D1E5490A78530608D54A -:107FF000E44B1B78002B19D05B0702D420231A43D3 -:108000000A70E1496E7200228A80CA80DF490A78CC -:108010005206520E0A70891C0A789206920E0A7055 -:1080200004990831083CE4B2049116E010231A4385 -:108030000A70D74A002111702970D6498A8E4A8663 -:10804000A9786970DDE7B14202D0212005B0F0BD0A -:10805000CD498A88CB889A4204D1CB490989491EE7 -:1080600089B206E00989D21A8A1A491E0A40521EAC -:1080700091B2C900A14202D2222005B0F0BD002F6A -:1080800005D0BE490A789206920E0A7006E0009961 -:10809000C029BA490A7814D040320A70002C04D0A2 -:1080A000224600200499FEF786FB5028E5D1002FD8 -:1080B00004D0B6488022017811430170502005B0E9 -:1080C000F0BD5206520EE8E7F7B58E46AB49097887 -:1080D0008A0994467246082A02D9272003B0F0BDC7 -:1080E0004209C406AC4852010078E40E400604D5AB -:1080F000002C11D1312003B0F0BD9E48A300C05820 -:108100004030037A9B0607D4C0798007800F02288D -:1081100002D8162003B0F0BD8226100600D5A02696 -:108120005006954D070E687A024643D093488B0956 -:1081300000789B018006800EBB4204D08F490870F6 -:10814000202003B0F0BDB30602D58C49087004E0CE -:108150008A48C02F11D0403101708648A100405894 -:108160000079000620D5A2420AD172463046029913 -:10817000FEF721FB502804D10DE04906490EEBE73C -:1081800021207E490A7893069B0E62469201134392 -:108190000B7003B0F0BDB106FBD57C4980230A7893 -:1081A0001A430A7003B0F0BD7848202201781143C9 -:1081B000017004E0FF2802D01F2003B0F0BD72461A -:1081C00031462046029BFEF740FA0346002F1FD19E -:1081D000502B1DD16A48002201784E06002E08DA85 -:1081E000861D3678002E16D0760702D4202631431D -:1081F000017065486C728280C280644801784906CB -:10820000490E0170801C01788906890E4031017089 -:10821000184603B0F0BD1026314301705C4802706F -:108220002A701F38818E4186A8786870E1E7F8B51A -:1082300004460020207069464870544B5548197810 -:1082400082784D0705D4C578AA4202D168460088D5 -:10825000F8BD5500514E521CAD192D886E46D2B254 -:1082600035808270202A01D300228270FB200140D9 -:1082700019703778A7707678404D802E11D0832EF4 -:1082800076D0842E74D0802E06D203202070402019 -:1082900060700120E0702671382E6AD0392E68D0C7 -:1082A0000EE1092020703348BE0081594F20475C01 -:1082B00050310822E01CFDF7E1FF2E48815920468D -:1082C0004B310C3002F092FC2A48EF2281594031A8 -:1082D000887910408871274989594031C979490600 -:1082E00028D4390626D5800708D52878CF2108401C -:1082F0002870B80602D54F20607012E050206070E0 -:108300002020074028783022790002400A4351009B -:10831000A2780A438106890FA270032907D0103082 -:1083200028700020E072A078400905D0C8E0DF2165 -:108330000840F5E74E20DFE7194900200A78D10907 -:1083400002D08020E0720420510632D5E17A402329 -:108350001943E1722318202119730649401C8B59D7 -:10836000C0B2403325181B78401C2B73C0B219E0F3 -:1083700042E086E058040020980000208B00002096 -:10838000880000208E0000209C070020890000202B -:1083900097000020780000208700002008060020B9 -:1083A000860000208959231840314978401C1973F0 -:1083B000C0B2910618D5F84920258A59138AE27A65 -:1083C0002A43E2728A59518A591A4032D27989B2C3 -:1083D000D20601D55B3100E0153189B22218117344 -:1083E000090A801C5173C0B2E17A002901D0401CF7 -:1083F000C0B22178081862E0E849842E08798446E2 -:1084000033D04879891DC006020E2270E01CFDF7AA -:1084100035FFE149BA008858EF2640308379334070 -:1084200083712078401C2070885840308079800704 -:1084300003D52878CF2108402870722060706046EC -:108440002021084041002878302202400A43510090 -:10845000A2780A438106890FA27003290ED010303A -:1084600028708020694648702AE08879CC49C00687 -:10847000020E2270E01CFDF701FFCAE7DF21084071 -:10848000EEE70422C749601DFDF7F8FE2078001DC5 -:108490002070382E14D1C049B80009584031C9792C -:1084A000C9060DD5C0490858407C022808D120468D -:1084B0001322BE490930FDF7E1FE20781330207009 -:1084C00021460098FEF715FE009068460088F8BD2A -:1084D00010B5FEF79AFA10BDB548407A70470228E9 -:1084E00001D333207047B34A10B5C000801803F0A1 -:1084F000EBFC002010BD022801D333207047AD4AA9 -:10850000C000821810B50846114603F0DDFC0020BB -:1085100010BDFF2903D0CA06D20E022A06D29E4AF7 -:10852000800010584030817200207047332070471F -:10853000FFB5054681B09E4802999F4A40789A4B04 -:10854000002954D09D490978490614D50499002979 -:1085500011D0AC001946095900291AD1002818D9A0 -:10856000471E1646CA0093191B79AB4211D0FF2B48 -:1085700004D0B94209D1332005B0F0BDC80031584C -:10858000894801519019057103E0491CC9B2814223 -:10859000E8D3814808230159834E4031CA79012725 -:1085A0001A43CA7132590399117400594030C07985 -:1085B000C006002878DB304602592846802108434F -:1085C0001021FFF7A9FC5028D6D1794902200A7F53 -:1085D00002430A777A490A7802436F480A700359BE -:1085E000784A197910780E46864328D029E0002170 -:1085F0006F4C002810D9CE00B6183679AE4207D19C -:108600000020AE009851FF20C9008918087103E0CE -:10861000491CC9B28142EED3607A854204D16A48CE -:10862000F7220178114001705B48A9004058F722F9 -:108630004030C1791140C171002005B0F0BD384310 -:108640001070554839431971005904224030C179DE -:108650001143C171544802990359597403590021B7 -:1086600099740659049BF374005901755048407A77 -:10867000854242D1544D2878104328700398102227 -:108680000101524809185248FDF7F8FD2878F721F2 -:108690000840414909594031C9790907C90FC90042 -:1086A0000843287029E0FFE73059102102F081FDCE -:1086B000315910224748FDF7E1FD315900208874F7 -:1086C0003159CF74315908753948407A854214D1EF -:1086D0000398102201013D4809183D48FDF7CEFDE1 -:1086E0003948F722017811402B4A12594032D27989 -:1086F0001207D20FD20011430170002005B0F0BD67 -:108700000F2801D33320704730B5054602012F48AA -:10871000101804461022FDF7B1FD2548407AFF28C5 -:108720000AD0214980000858007CA84204D1214683 -:1087300010222748FDF7A2FD002030BD10B500280B -:1087400005D0012807D0022809D0332010BD2248C7 -:1087500002F04CFA03E013221448FDF78FFD0020CD -:1087600010BD10B50B46002809D001280AD00228F8 -:1087700004D113220D491846FDF780FD10BD0220DB -:10878000087010BD1449184602F030FA10BDA42933 -:1087900024D2332070470000580400201804002021 -:1087A00026040020CC00002094040020480600206D -:1087B00078000020F80500208005002088000020B7 -:1087C000960000208C000020840000206B06002012 -:1087D0006C0700207C070020C800002070B4FE4D0C -:1087E00000222B78002B0DD9FC4E940034594034D4 -:1087F000247AA40602D570BC15207047521CD2B250 -:108800009A42F2D3002803D0F54A1071E98602E0BB -:108810000020C043E88670BC00207047F04A1279FF -:108820000270ED48C08E08807047EE4A002811782B -:1088300002D00220014301E0FD2001401170704789 -:10884000E9490870704770B48200E44882581046C5 -:108850002E304032557A6A06520E29D00478012310 -:10886000002C02D14678002E07D00E78A64203D104 -:108870004C784678B44200D000238478002C03D092 -:108880008E78A64200D00023C478002C04D0CE7885 -:10889000A64201D0001D05E0001D002B02D0E80912 -:1088A00006D008E0521E1206120ED7D1E80902D0F7 -:1088B00070BC0120704770BC00207047F8B5CB48F1 -:1088C000CB4A00781378C407CA48C34D017802D058 -:1088D000D8070FD10CE0C748CC067DD5EF24214046 -:1088E0000170580840001070287F800775D4D0E2CE -:1088F000C80671D5687AB94E80003158BE4CBF4F5A -:10890000BF4802F073F9BF4800784107B44873D5F7 -:10891000B84909788C46C9066FD502780223032A24 -:108920006FD006DC002A09D0012A30D0022A7DD17E -:1089300039E0042A7BD0FF2A78D116E02178641C24 -:1089400022295CD12278AB7E61789A4201D22A76C4 -:1089500000E02B762A7F13468B4350D16B7FAA4CC5 -:1089600019400A432270FF2144E02178222946D190 -:10897000297EA54CC900891D69762178A34A8B08F8 -:108980009B0089071370890F2170FE2109E021786F -:10899000242966D19D4901230A781A430A70FE21D1 -:1089A000C170017084E02178641C292959D1974A4B -:1089B0001178194311702378641C22789449641C3F -:1089C0000A7022784A70641C22788A70641C2278AB -:1089D000641CCA70012B01E05BE210E00FD0697AE1 -:1089E00023788A008B4989580B708A4B61789A5892 -:1089F0005170032101706BE07CE110E201E0052081 -:108A0000F8BD2178641C2A292BD1804A117819439A -:108A10001170697A7F4A89005258237893707D4A91 -:108A200063785258D370A3787A4A01E019E014E0D1 -:108A300052581371774AE37852585371754A237923 -:108A400052589371734A63795258D371714BA2791A -:108A500059580A72042101703AE02178641C2B29CC -:108A600002D0FE2A24D033E0684A117819431170ED -:108A7000697A684A8900525823785372654A637844 -:108A800052589372634AA3785258D372614AE3787A -:108A9000525813735F4A2379525853735D4A63796E -:108AA000525893735B4BA2795958CA73FE210170D7 -:108AB000554C2278002A0BD00121D307DB0F04D1BB -:108AC0004906090E13460B42FAD001708A43227000 -:108AD000007803287ED004DC01282AD0022804D1A3 -:108AE0009FE0042877D0FF2805D042486146EF2256 -:108AF0001140017001E23E490122087810430870DC -:108B0000387020207870287EB8703F4804220078A2 -:108B1000F870002038717871B871F87138720D20D2 -:108B20006876687A800030582030017911430171ED -:108B3000AAE1288F0007000F0C2800D90C20C11CC7 -:108B4000CAB235490A70009202462A32D2B2CA70BD -:108B5000322A01D13022CA706A7A92009446B25801 -:108B60002032947F23071B0F43400C2B00D90C238A -:108B700018461030C2B22730C0B24A700871392886 -:108B800002D04D79422D01D1801E08712009584034 -:108B90000C2800D90C2003461D338B704430144D33 -:108BA00048712C78012634432C703C7023247C704F -:108BB000FE24BC70009CFC703A717B71CA78BA715B -:108BC0000979F971387205486146405820300179B9 -:108BD000042223E04AE06BE07800002058040020E3 -:108BE00098000020870000209D0000208D000020BC -:108BF0008C000020880000203B040020FE030020A1 -:108C0000FA0300208E00002096000020970000202C -:108C1000CC00002094040020F000002011430171DA -:108C200032E1FE490122087810430870387026208E -:108C30007870687AFA4980000958497CB970F94916 -:108C40000A78FA704A783A718A787A71C978B97173 -:108C5000F5490A78FA714A783A7289787972305807 -:108C6000042220300179114301710DE1EB49012209 -:108C7000087810430870387027207870EA4804227A -:108C8000C178B9700179F970417939718179797157 -:108C9000C179B971017AF971417A3972807A787241 -:108CA000687A800030582030017911430171EBE07F -:108CB000DA4901220878104308703870282078704B -:108CC000D9480422C17AB970017BF970417B3971AE -:108CD000817B7971C17BB971017CF971417C3972F9 -:108CE000807C7872687A8000305820300179114396 -:108CF0000171C9E022217970A97EB9700321F97050 -:108D0000002139717971B971F9712178641C2039A8 -:108D100009297DD20B007B441B79DB189F4404EDAD -:108D2000ED17EDED4082BB0021782976BF4A6378CC -:108D300013700622C270C800801D6876687A04220B -:108D40008000305820300179114301719CE0217876 -:108D5000C170B74967780F700097A7784F70BE460B -:108D6000E7788F702379CB7062790A71A4794C719E -:108D7000BC46B04924274F71C0788871009FCF71DD -:108D800077460F7267464F728B72CA720C73687A9D -:108D9000042280003058203001791143017173E0C2 -:108DA000687A9F4F8200BB5821785974A249637832 -:108DB0000B70A3784B70E3788B702379CB709A4952 -:108DC00063790B70A3794B70E3798B70B9589B4C26 -:108DD000497C012901D0022922D19749FFF733FDAF -:108DE00000281DD000202921217060708D48017855 -:108DF000A1704178E17081782171C0786071687AE2 -:108E0000800039580978A17139584978E17100E03A -:108E100073E030580422203001791143017133E0AE -:108E20000120E0E780482178C17061780171A17864 -:108E30004171E17881712179C17161790172A17902 -:108E40004172E17981727B482A214171697A744AC1 -:108E5000890053589B7883715358DB78C3715358FA -:108E60001B79037253585B79437253589B79837211 -:108E70005358DB79C3725258127A02737058042225 -:108E800020300179114301716D48082201781143A6 -:108E900001700220F8BD64482178C17261780173C5 -:108EA000A1784173E17881732179C173617901748B -:108EB000A1794174E17981745E482B214171697A0D -:108EC000574A890053585B7A837153589B7AC37110 -:108ED0005358DB7A037253581B7B437253585B7BA6 -:108EE000837253589B7BC3725258D27B0273705863 -:108EF0000422203001791143C5E7687AFB22800003 -:108F00003058203001791140BDE7F8B54D4801785F -:108F10004A064D49520E0D78AB07DB0FDB011A43B1 -:108F20000270E8090AD049483C4C0278207893073F -:108F300019D0014669404B0601D40520F8BDC90689 -:108F400002D4410602D503E0410601D50320F8BD55 -:108F5000A90606D5510701D50420F8BD20210843F4 -:108F600020700220F8BD50210D4201D00720F8BD2D -:108F70003749384B08700D21D976002230491A76CE -:108F80000978F7263140294E3270334E3270B77867 -:108F900077709E8E5E86DF260E40C906C90F490196 -:108FA0000E43EF210E4026490E7071061AD52B4E46 -:108FB000012720491F7637780F7077784F70B77880 -:108FC0008F70F678CE7003260E7122274F719B7E2C -:108FD0008B71CE710A724A728A72CA720A73012147 -:108FE000084320701E4E3078010714D5E90712D0CF -:108FF000C00610D51B4802F05DFF08221A491B4825 -:10900000FDF73CF9194910221948FDF737F9307876 -:10901000042108433070207800072BE08C000020EA -:1090200094040020C800002048060020970000207B -:10903000F0000020FA030020CC000020FF030020F5 -:1090400088000020870000208D0000208E00002076 -:109050008F000020780000209800002036040020B7 -:109060008400002063060020F60000205B0600203C -:109070007C070020FE49000F09780909090108430F -:1090800020700120F8BDF8B50546FA48FA4C007882 -:1090900001071DD5400708D5F5480078000704D51D -:1090A0000822F649F648FDF7E9F8E07E0146801F00 -:1090B000082805DDC2B2F3480123811D801D05E0AB -:1090C000491FF048CAB2411D0123401DFDF7FCF8BD -:1090D000012D01D0002D36D1EB48FB220178114043 -:1090E0000170607A8C468100E84841584A20405C13 -:1090F000FF2828D0C206E34FC0093B79D20EC00139 -:109100001E0608D500281ED0A02098431BD1E04899 -:109110000078800717D1DF4B0020D200D318024619 -:109120005032D84F8E5C1A5C3F187F79164017403A -:10913000BE4208D1401CC0B20828F0D3D2486146D4 -:10914000042211430170022D01D0042D04D1FFF738 -:10915000B5FB022800D00546002001220227CE4E92 -:10916000CE49082D77D22B007B441B79DB189F4416 -:1091700003072DAFECF19E0501F0BDFD0020F8BD09 -:109180003078502148403070607AC04985004C5991 -:10919000BF4B4034A0793843A0718406E40F49598D -:1091A000E40022431A70DF22403110408871B14838 -:1091B0000078410701D5C00605D4AD480078800687 -:1091C00001D401F098FDFDF74DF8B9E0B04B0C2546 -:1091D0001A782A403A431A70327810235A40B04D18 -:1091E00032702B781F0702D58878487000E04870ED -:1091F000AC48BF27017839400170500607D59C481C -:109200000078800650D4012001F089FD4CE0D8069A -:1092100003D5802003432B7042E0D00726D0A24F15 -:10922000217E381DFDF7C0FF002815D03078397930 -:10923000DF22084330703871A08E6086607A81002A -:1092400092484058403081791140817128788021BE -:109250000843287024E07DE0607A202281008B485A -:109260004058403081791143817119E0607A874D0F -:1092700080002858001DFDF7D3FF002808D0617A30 -:109280003078890069580A7910433070087107E016 -:10929000607A202280002858403081791143817102 -:1092A0008521607AFDF7B1FBFEF7D1F948E0784AF5 -:1092B0001278520702D43278920646D4627A93002A -:1092C000724AD25840329279D20601D46D4A507116 -:1092D0006F4A107803091B01502B3BD2931F1B7858 -:1092E0001B0718D5638E002B15D045070FD48507B3 -:1092F00011D0657AAE00654DAD594035AD79ED06BA -:1093000009D5252168485B1E4171638612E05D4DD9 -:109310006D79252D16D01030C3B2180900011370D5 -:10932000502807D34878002804D01B071B0F137060 -:10933000401E487010780321800880000843107098 -:109340000120F8BD5B1E6386F4E70120FEF7CFFC29 -:109350000020F8BD0020FEF7CAFC0FE7534909784A -:109360008A07484907D4C278002A04D0CB789A42A9 -:1093700001D00020704730B48478424B62069B785D -:10938000520E03D05D066D0E954212D10278002A6E -:1093900005D14578002D02D15C40230606D50B7817 -:1093A0009A4206D140784978884202D130BC0120E7 -:1093B000704730BC0020704770B52F4D298F401882 -:1093C00084B2698FE86DFCF7C7FE401C83B2384851 -:1093D000F7220178CE07002E02D02C8711400DE035 -:1093E000294E367836070BD4E31A01269BB2F603D2 -:1093F000B34205D9114001222C871143017070BD81 -:109400002C8701F0C0FB70BDF8B519481F4D0778D7 -:109410001538437A1B49980028580C791449064698 -:109420000C701539CA790F310E360978052A7DD0AE -:1094300006DC022A5AD0032A3FD0042A55D15CE226 -:10944000082A43D0122A50D10E490B4C1846FFF778 -:10945000FAF9002849D0607A800028584030817994 -:10946000CA0642D4C90928D000214156012221E070 -:109470008D00002084000020780000203B040020A4 -:10948000F600002036040020870000205804002049 -:109490008E000020F80500208C000020980000209D -:1094A0008800002089000020FA03002085000020A9 -:1094B000A00000208256914217DBFE4F3878C0068C -:1094C0007ED5FD4CE07903287BD118E1C9060CD488 -:1094D000018A428A8918F94A89180182002030805D -:1094E000F7480322017811430170F8BDC90669D518 -:1094F000210767D540308279FD231A408271F148F7 -:10950000ED49027813090A781B011407240F23433D -:10951000521E0370D4B2A700E859FFF71FFF0028BE -:109520005AD0E85901464031CA7900E078E1132366 -:109530001A40032A02D0022A0BD04DE0E148DE4A4D -:1095400001781278090909011207120F11430170FD -:1095500047E0D94A1279A2420FD084462030837F57 -:109560009000285800902030827F934234D1009898 -:109570006246527B407B82422ED1D248007802075D -:10958000CD48120F0078824202D0087AC00723D15A -:10959000CD492046FFF757F900281DD0E859403043 -:1095A0008179C90910D0C4490022497A0123890070 -:1095B0006958C35640318A569A420DDB097802E059 -:1095C000E3E0A0E061E00170BE49220708780009ED -:1095D0000001120F104308702046641EE4B20028F8 -:1095E00099D1B848B44A017812780907090F914215 -:1095F0004BD0880028584821095C2C46C90726D141 -:10960000B04FB14901F0F2FA38780107090F8B0029 -:10961000E25803204032D7790743D771E2584032ED -:109620009379DF0902D05B065B0E9371A24A537AED -:10963000994205D1FF2313710C3213780343137041 -:10964000084601F0F1FBA1480078C0091DD19D4FEB -:10965000472138780007800E2058095C890614D409 -:10966000994A002111714B300D229749FCF706FEF3 -:10967000387810230007000F8100615840318A7943 -:109680001A438A718021FDF7C0F98B48407A810026 -:109690006A5840325279FF2A00D126E732780A2AE6 -:1096A000FBD30A3A32708A4A1378DC0712D07478F6 -:1096B000641CE4B274706F5840377F79BC42ECD3BD -:1096C0005B085B001370002272706958897D002965 -:1096D0000CD0F8BD6A58927DFF2AFAD07278521CDD -:1096E000D2B272706958897D8A42F2D379491023C7 -:1096F0000A781A430A700121FDF787F9F8BD73480B -:109700000078000741D5607A80002858FFF726FED0 -:1097100000283AD0607AFD238100695840318A7967 -:109720001A408A7101F080FB012001F057FB0028EC -:1097300019D0E079122807D166480078800703D550 -:109740006248007800070ED50620E0715C4800787A -:10975000C10901D1400602D501F0CDFA03E0FFF7BF -:10976000D4FBFFF790FC3878400707D556480179BD -:10977000607A800028584030C173F8BD607A524941 -:10978000800028584B300D220CE138784006F4D484 -:109790004948514B407A02218200AC58678A9F4267 -:1097A000737814D95B1CDBB27370042B28D3444943 -:1097B0000B789B089B009B1C0B70AB580821DC7D31 -:1097C00064086400DC75AA580023D38118E03F0ABE -:1097D000FF18FFB2BB4201D17F1CFFB2BB4201D2D6 -:1097E00077700DE036490B789B089B009B1C0B7033 -:1097F000E37D08215B085B00E375AA580023D38151 -:10980000FDF703F935480078C009B6D02C48007838 -:109810008007800F0228B0D10020FEF768FAF8BD5B -:109820000624C90610D5FFF799FD00280CD0224860 -:10983000FD22407A800028584030817911408171A2 -:10984000FFF763FB044601E02048077024480078D6 -:109850004007C70F2046FFF716FC8446062C14D09D -:109860001A480078C00707D01348017E002903D0AA -:10987000C27E15491B4806E00F480D22407A124966 -:10988000800028584B30FCF7F9FC60460028C6D110 -:1098900009480021C1710A49002F097824D0C9065E -:1098A000BDD5062C04D1034980230A781A430A70D7 -:1098B0000B211CE087000020780000200300FFFF40 -:1098C000840000208B000020360400208D00002042 -:1098D00088000020890000205D7400008C000020BA -:1098E0008E00002018040020C90602D40521C17191 -:1098F000F8BD062CFCD10421C1717278002A1DD05C -:10990000FE49FF4B887A497A890069584C8A9C4203 -:1099100000D94008D20902D10A8A121A0A82717843 -:109920004A06520E824202D80020707006E0CA0930 -:10993000081AD2014006400E02437270F1480078C6 -:10994000C006D5D5ED4C607A80002858FFF706FD9B -:1099500000286DD0EC4F3878400769D4607AFD223A -:109960008000285840308179114081710A20E071CF -:10997000E6480078C10901D1400602D501F0BBF9E3 -:1099800007E0FFF7C2FAFFF77EFB002801D00520B1 -:10999000E0713878C00708D0207E002805D0E27E2C -:1099A000DB49DC48FCF76AFCF8BDD6480078400784 -:1099B00007D5D7480179607A800028584030C173B4 -:1099C00007E0607A0D2280002858D1494B30FCF71F -:1099D00055FCD14A1378D807E6D0607AA0278400D6 -:1099E000285901464030C67B3E42DDD0067C442EDD -:1099F000DAD1467C022ED7D1C07C5E0703D5400762 -:109A0000000FC64E02E04007C54E000F305A002836 -:109A100008D00E8A4F8AF61B0E82295936180E82FC -:109A2000295948829807BFD4580840001070F8BDE3 -:109A3000B5480078010701D44007F8D570780028B0 -:109A40001FD1FCF734FAC0B21A2102F044F80746DD -:109A5000FCF72DFA1A214F43C01BC0B24106490E34 -:109A600070700D2905D280210843C009C0017E30E5 -:109A700006E00721C8411921C90640181921C8412B -:109A80007070A1480078400703D570784006400EFA -:109A90007070A449A08F0A785307C8D4238FC01AC6 -:109AA0001330012380B2DB03984201D9032006E082 -:109AB000022801D2022002E00428B8D201200423A7 -:109AC0001A430A70617A890069580A8A101A088252 -:109AD000F8BDF0B48B488D4C0178954F4906490E7E -:109AE00001700F38417A8A008F498A588F49138A4A -:109AF000038615790D7011464031CE792670B40772 -:109B0000A40FC471097A3970F10608D5A41DC47177 -:109B10000824F91D25430D701571DB1E03860021F5 -:109B200001768049FB230A781A400A702021C185FA -:109B3000C1790172F0BC70477248007840067DD44C -:109B4000F0B56E488BB0018F09318FB2017A1029C0 -:109B500001D10C37BFB2417A734A89005158403164 -:109B60008979490703D5018EFF392D390186018E88 -:109B7000791A018600246C49A50048594722125CD5 -:109B80009207920F012A74D9664B1B780593DB0765 -:109B900006D05A4E33799C4202D1338E5A333386E3 -:109BA000038AF91A8EB25549098E8E427ED8032A4D -:109BB00010D05248007907915B49019048590346FB -:109BC00040339C46DB7902469E070E32B60F022ECA -:109BD0006DD0FBE0428A54499A1802824748407A85 -:109BE000844211D14A590020907348594030C079BD -:109BF00000075BD54F484059017D002956D1817C33 -:109C0000C27C89188174ECE08000474907900858AD -:109C10004721095C8907890F02295AD04249468A9F -:109C200048590890408A0090864214D9014630462F -:109C300001F051FF00994143701A00E0F6E00099ED -:109C400080B24908814204D20099081A80B20021EA -:109C500011E001210FE0314601F03DFF0099704312 -:109C6000081A80B27108814204D2301A80B20121F0 -:109C700001E0C1E00021002800D10121089A927B77 -:109C8000521CD3B2089A022B937306D3264A042699 -:109C900052594032937933439371052819D2224E99 -:109CA000079846223058125C520701E06BE06BE0E7 -:109CB00001D500290DD115490A78132191433FD0D0 -:109CC0001A4904200A7802430A701B490A780243A1 -:109CD0000A7009212046FCF798FE1348405940308D -:109CE000C07900077DD5134A00235059C07C002855 -:109CF00077D951590F20CE7B761C1FE078000020C9 -:109D00005D740000870000208D000020840000208A -:109D100036040020180400209D00002044BF0000ED -:109D200034BF000088000020580400208C00002070 -:109D300085000020940400208F000020CE7317E0DF -:109D40000599FA4A4907C4D40599042319431170A7 -:109D5000028AD21E028207983058C17B0029B8D1EE -:109D60007E21C173B5E7401EC0B20E5C761C0E5456 -:109D70000E5C002E01D10028F5D150595B1CC07C2F -:109D8000DBB29842B5D82CE0DB061FD4038A868A62 -:109D9000DB04DB0CF618B6B29E4201D2082300E0C9 -:109DA000730B0093019BA3420CD0FF2B0ED0634694 -:109DB0001B79002B0AD0C37D019880000858C07D14 -:109DC000834203D113780098181810704A59138AE7 -:109DD000908A18181082381A82B20798824200D8E6 -:109DE000ECE6D2480078C00706D0D14801798C4211 -:109DF00002D1018E5A390186CD48641C0078E4B244 -:109E0000844200D2B7E6CA480786407A8300C94830 -:109E1000C058403081794A0702D5FB221140817138 -:109E2000C5490020C95808750BB0F0BD7047F0B5A2 -:109E3000BF4885B0102101720D21C1720179103027 -:109E40000078FF29844603D0C00701D1B849C87102 -:109E5000BA480678BA480090BA480490B448B107A6 -:109E6000447AB948A200007800297AD0B049B84BAA -:109E7000CF79B6491D7809780391B649CB785B1C38 -:109E8000DBB20293AA4B052F5B7E019322D0A84B35 -:109E9000062F9B7907D0092F7AD00C2F33D00020C2 -:109EA000FDF725FF60E1A2490C230B720B469B795D -:109EB000ED095B00002D03D02525EB1ACB7202E0E3 -:109EC0001625EB1ACB7205238B7100075FD5FF2C8B -:109ED00079D149E196480C220272EA0901D00722A1 -:109EE000C2726246120752D5720701D40D2168E092 -:109EF000039AD20705D0029ACA70062A01D100221D -:109F0000CA70C37630E1904CC00607D492480078FE -:109F1000800603D5B007800F012808D084480522A9 -:109F20000272EA0938D02322D21AC27237E0012025 -:109F3000FDF7DDFE00F095FF002828D07C4D0C20B9 -:109F40002872217808071AD5687AFF2817D04907A0 -:109F500008D481007848012240588049FDF754F820 -:109F600008E041E0049801F0A5FF08227C497B4805 -:109F7000FCF784F9794910220098FCF77FF97448BE -:109F80000078C009A87904D07621081AE872EBE0BD -:109F90001AE07821081AE6E03822D21AC272624624 -:109FA00012077AD5720702D50D21C176DCE0039A3B -:109FB000D20705D0029ACA70062A01D10022CA70BF -:109FC0000199C176D0E008E0594905230B72352389 -:109FD000CB72000761D5FF2C5FD057485F4980588E -:109FE0000022FDF711F878E0514D0421EE79761F3B -:109FF000072E52D233007B441B79DB189F44733DFC -:10A00000B4B4030D2500430647D429723521E97203 -:10A01000000742D5FF2CE0D1A6E0297200070CD53D -:10A02000FF2C0AD044484D4980580122FCF7ECFF30 -:10A030004A4910220098FCF721F945480078C009E8 -:10A0400001D03A208FE060208DE0297200070CD506 -:10A05000FF2C0AD03848414980580122FCF7D4FF30 -:10A060003E4910220098FCF709F939480078C009E8 -:10A0700001D04A2077E05F2075E000F0F2FE002872 -:10A0800072D00C20287232480078C009A87905D017 -:10A0900041002520401AE87204E065E041001620E6 -:10A0A000401AE8720520A8712748007801075BD59F -:10A0B000697AFF2958D0400707D41F4889004058C3 -:10A0C00000222649FCF7A0FF07E0049801F0F2FE09 -:10A0D000082223492148FCF7D1F820491022009892 -:10A0E000FCF7CCF840E000F0BCFE00283CD00C208F -:10A0F00028721548007800070ED5687AFF280BD023 -:10A1000081000D48012240581449FCF77DFF134996 -:10A1100010220098FCF7B2F80D480078C00921D051 -:10A120002020E8720620A8711EE0000088000020B0 -:10A130007800002058040020940400208E000020A5 -:10A140007C07002063060020840000209700002088 -:10A1500087000020980000208C0000205B06002073 -:10A16000F60000200D20E872FC4CE07AFFF724F99D -:10A170001020E0721520E085207AE07105B0F0BD76 -:10A18000F0B58FB0F648F54B0690597A0091002152 -:10A1900019721A8F1886093294B2FF20F14A587248 -:10A1A0001070187905901B780A46EF4D9600AE594D -:10A1B0004725AD5DAC46AD07AD0F022D0CD1FF2894 -:10A1C00006D0E94D8700ED59F67DED7DAE4203D90D -:10A1D0006546ED0600D41046521CD2B29A42E4D332 -:10A1E000059A904202D0DD4D00226A71FF283AD0D4 -:10A1F000DD4F85007A590D9240321579D74A56794C -:10A20000B5422CD8002509965E1E02460E96521CB9 -:10A21000D2B29A4200D30022D34E9700F6590C9640 -:10A220004036B446F679B707BF0F022F0FD1F606B6 -:10A230000DD466463679002E09D00C9EF77D0D9E12 -:10A24000F67DB74203D300200990104604E06D1C50 -:10A250000E9EEDB2B542DADBC04A099D5571BF4A88 -:10A2600055796D1C5571059A904214D0FF2A0ED075 -:10A27000BD4F9600BA59D57D6D086D00D575BB4AA6 -:10A280001278D20703D1BA5901263543D5758022F9 -:10A290001043B24A1071B4488A0085584726765D4B -:10A2A000B707BF0F022F02D0032F53D125E0F606C8 -:10A2B00002D5AC4801704DE0A84E37797E06760E87 -:10A2C0008E4247D13E0618D52C82A44DA74E297147 -:10A2D000357845276D086D0035708658BF5D002FB5 -:10A2E00003D001273D43A14F3D70F57DED0704D01C -:10A2F0009E4D2E78760876002E708558974A288ACB -:10A300001679001B80B2B1420BD1984E3678F60711 -:10A3100001D05A3004E01E2801D2002001E01E388E -:10A3200080B24035EE79F643B7070BD1AD796D07B2 -:10A3300008D5FF252D35A84201D2002002E0FF38C4 -:10A340002D3880B2158EA84204D810865172B207FB -:10A3500000D10690491CC9B299429CD37F48457AE6 -:10A36000FF2D09D001798D4206D180490978C907AE -:10A3700002D0018E5A3901867D4800780590800709 -:10A3800056D57648008E0790CB2851D2FF2D4FD05E -:10A390000098FF284CD085424AD0800072490A902C -:10A3A0000F584720C05D0990C043800740D1A800E6 -:10A3B00008584722125CD243920739D1408A019053 -:10A3C0007E8AB04211D9314601F085FB0199704374 -:10A3D000081A80B27108814204D2301A80B205286E -:10A3E00019D316E0032816D313E00146304601F0D6 -:10A3F00072FB01994143701A019980B24908814268 -:10A4000005D20199081A80B2032804D301E0052877 -:10A4100001D300280CD109981321534E8143042203 -:10A4200000294CD00798C12802D9387910433871D7 -:10A430004C480278FF2A58D00698CB2855D9FF2DD2 -:10A4400018D046480079854214D14749AB00CB5813 -:10A450001B8A1B1B9BB2B42B0CD8AD008300C858C1 -:10A46000068A878AF61906824859008A001B80B23C -:10A47000B428F4D93C48960081590B4640331D7AE4 -:10A48000EF0601D4AD062BD50979090604D5FF25C1 -:10A4900006994935A94246D3D97903252943D9716B -:10A4A00081590C822D494A7280594030007A8006C9 -:10A4B00039D53048102201781143017033E02B491F -:10A4C00008784307B4D4FB7B002BB1D10323FB7383 -:10A4D000104308700A983058018AC91E0182A7E704 -:10A4E000B4341E480C8242721DE01C4D288E522846 -:10A4F00019D905981E4908221043087072B6FBF757 -:10A500003CFC62B61C4C207900280CD0288EE98EC9 -:10A51000884208D33A21687AFCF777FA2079012833 -:10A5200001D1002020710D4C607AFF282ED0FFF75A -:10A53000D0FA607A472281000B484058018A125CA9 -:10A54000C904C90C491CD243920717D0828A5018FB -:10A5500080B2884216D2082015E000007800002062 -:10A56000FFFF00008C00002058040020880000201D -:10A57000870000208900002098000020428A50189F -:10A5800080B2E6E7400BA0720FB0F0BDF74C082197 -:10A5900020780843207072B6FBF7EFFB62B6207894 -:10A5A000DF21084020700FB0F0BDF0B5F04EF14C47 -:10A5B00083B0F7272078C10706D1317A122919D044 -:10A5C000318F7187B16DF1654008400038402070CF -:10A5D000307A801E11287CD203007B441B79DB1863 -:10A5E0009F440C113434777711607777853D54FEA2 -:10A5F00077FDFC00F18F7187B16EE4E7308E1E3875 -:10A6000030862920F0852078400840002070707A3C -:10A61000FCF7A1FF707AD84D80002858018A318755 -:10A620002030C07FFBF747FC707A8000285820302C -:10A63000807FFBF744FC707AD04980002858407B2B -:10A640004000085AFBF73FFC0020F07220784008D9 -:10A6500040002070F07AFEF7AFFE0D2030722078B7 -:10A66000C00703D1308F7087B06DF065308FF087F1 -:10A67000B06DB066F08DFEF79FFE0320B071BB4851 -:10A68000EF220178114001700E2001E120780121B4 -:10A69000084320700E20FEF78FFEFEF7B5FE0F2058 -:10A6A00030726AE22078400840002070707AFCF72F -:10A6B00052FF707AB04D80002858018A31872030CF -:10A6C000C07FFBF7F8FB707A800028582030807F2D -:10A6D00000E000E2FBF7F3FB707AA84980002858FD -:10A6E000407B4000085AFBF7EEFB0C2030722078CC -:10A6F000400840002070A2480078800772D0717A2C -:10A700009D4D88002B584620C25C92066AD59D4A12 -:10A710001278D20747D09C48407A884226D19B487D -:10A720000078400622D4317E9948FCF73DFD002890 -:10A730001CD0707A80002958964800F057FA914B47 -:10A74000944918780A79104318700871707ADF21DB -:10A7500080002A584032907908409071B08E7086FF -:10A760008D4880220178114301703BE0708E0028F3 -:10A770004ED0707A80002958864800F037FA814818 -:10A78000802201788348017125214171708E401E1D -:10A7900070868148017811430170401C0178402285 -:10A7A000114301701EE0784A527A8A4230D1181D56 -:10A7B000FCF736FD00282BD0717A72488D006E4967 -:10A7C00000784A596F4913791843087010716A4824 -:10A7D000DF22405940308179114002E09AE060E088 -:10A7E00019E18171707A644980000858FB22001DCC -:10A7F00001781140017063490D78690703D56049FC -:10A800000978002909D05E480078800725D028E023 -:10A81000207805210843207023E0604AFB2113784B -:10A820000D400B401370D21E15700C210170431E99 -:10A830001A7855214A401A70801E02784A400270E8 -:10A84000401E02784A400270401E02784A40027060 -:10A85000207802210843207003E0E80901D0FBF7CB -:10A8600001FD48480078000703D50720FEF7A4FD46 -:10A8700008E03E480078C00901D00D2000E01E200D -:10A88000FEF79AFD2078C00706D0FBF76FFD0F207A -:10A890003072FBF79FFC70E1308F7087B06DF06510 -:10A8A000F5E720784008400020702920FEF784FD5D -:10A8B000308FF087B06DB06600207072FFF709F935 -:10A8C000707A2D4D80002858354900F08FF9707A44 -:10A8D000800028582030C07FFBF7EDFA707A8000A6 -:10A8E00028582030807FFBF7EAFA707A23498000ED -:10A8F0002858407B4000085AFBF7E5FA1B49EF2235 -:10A900000878104040221043087012203072212035 -:10A91000F085BEE7154D2878C0060DD4F18FB06ED6 -:10A92000FBF71AFCF18F0123421A92B2DB039A4221 -:10A9300001D9318700E03087207814494008400071 -:10A9400020701220F07128784006400E2870097897 -:10A95000C90627D510213172BF21084028700A4846 -:10A96000FF214172FBF7B0FD3FE0000087000020AF -:10A9700078000020A0000020580400205C07002080 -:10A980008E0000208C00002098000020890000200C -:10A99000FE030020FA030020880000208F00002022 -:10A9A000C4000020C00620D5FEF72EFDF079062851 -:10A9B0001BD1F9480078002803D100F0D5F9002810 -:10A9C00013D000F0D1F9F54D80002858F44900F07B -:10A9D0000DF9707AF2498000285800F007F9182024 -:10A9E000FEF7EAFC0F20307206E02878EF210840DD -:10A9F0002870307A122804D0207801210843207072 -:10AA0000BBE02120F0852920FEF7D6FC308FF087AF -:10AA1000B06DB0663DE7F079092801D00C284FD120 -:10AA2000E0480178394001708C462178480703D509 -:10AA3000FB200140217043E0707A00908000D74DE8 -:10AA400001902858FB23001D02781A4002708A07E3 -:10AA500014D5FD2211402170421E137855214B4020 -:10AA60001370801E02784A400270401E02784A40ED -:10AA70000270401E02784A40027021E0C648017808 -:10AA800089071DD16146C9090FD05E21017060465A -:10AA9000800615D4C4480078410701D5C0060FD5FB -:10AAA0000A210098FBF7B1FF0AE0019820222858FC -:10AAB000403081791143817103210098FBF7A5FF94 -:10AAC0002078012108432070FFF7B1F9FFF734F82F -:10AAD000FBF7FAFC51E0207841084900B3482170A7 -:10AAE0000278930646D50120014321700C20FEF721 -:10AAF00063FCAD480078000720D5707AFF281DD090 -:10AB0000AB4A81005158897C002917D08300D15865 -:10AB10000F20CD7B6D1CCD7304E0401EC0B20D5CD8 -:10AB20006D1C0D540D5C002D01D10028F5D1D158BC -:10AB3000887C401E0006000E8874E8D1FFF720FBD9 -:10AB400099480078000718D5707AFF2815D0984DDD -:10AB5000800028589749007C10220001411896482F -:10AB6000FBF78CFB707A1022800029589348FBF782 -:10AB700085FB02E05108490001702078C00700D031 -:10AB800018E503B0F0BD10B58D48007A801E11287D -:10AB90001AD203007B441B79DB189F44080808087D -:10ABA0001515081615151624151515080800FBF7B8 -:10ABB000EBFA83480822816D016682480021817189 -:10ABC000814801781143017010BDFBF7DDFA7C4824 -:10ABD0000822816D016601212030817108300178E1 -:10ABE0001143017010BDFBF7CFFA10BD0A78027057 -:10ABF0004A7842708A788270C978C170704773B59C -:10AC00006A461078654B840019594722525CD60673 -:10AC10006A4655780022002E20DA052D05D0062D33 -:10AC200007D0072D03D120318A721859028502B04E -:10AC300070BD0D8D4E8AAE19B6B20E851959AE4251 -:10AC4000F5D820318D7AED1CEDB28D7219590E4672 -:10AC5000B67D2031B542EAD98A7212E0012D0CD0BE -:10AC6000072D16D0082D0CD0802DE0D12031887A08 -:10AC70000628DCD28A7202B070BD20318A7A521C5A -:10AC80008A721A592032937FD17A8B4209D1117B73 -:10AC90000BE020318B7A062BECD2FCF7F3F902B0F3 -:10ACA00070BD147BA34200D1517BFBF710FF02B0B3 -:10ACB00070BDF0B5454C8446E288414F0E46208970 -:10ACC000F96E801A85B25118AE4202D832466046FB -:10ACD00008E0EAB26046FBF7D1FA701BC2B26046E8 -:10ACE0004019F96EFBF7CAFAE08821898019491EDC -:10ACF0000840E080F0BD2D48007840070ED410B524 -:10AD00002F482649407A10238200895840318A7999 -:10AD10001A438A718021FBF778FE10BD704770B529 -:10AD20002B490978C9071CD02A4C002800D02A4C8E -:10AD30002078002801D0012812D1214D1749687AC6 -:10AD400010238200895840318A791A438A71217808 -:10AD50008331C9B2FBF759FE287E2070A88E688621 -:10AD600070BDFFF7C8FF70BD70B515480078401E74 -:10AD70000406240E0ED0094DA00028584621095C77 -:10AD8000890603D4FEF7EAFA002803D1641E2406DC -:10AD9000240EF1D1204670BD8E0000205804002002 -:10ADA000360400208C000020840000208700002052 -:10ADB000940400206B0600206C0700207C07002014 -:10ADC0007800002098000020A00000209C070020B0 -:10ADD0008D0000201D0400203B0400203349497AE7 -:10ADE0008A0033498B58334AD97812788907890FFA -:10ADF000920601D40120704730B42F4A5D7954790E -:10AE00009279AC4207D1022902D09B799A4202D1B1 -:10AE1000012030BC7047002C03D10229F9D0002A50 -:10AE2000F7D030BC0020704710B4214980001F4B80 -:10AE30000A589B8F548A153BE31813820B58002243 -:10AE4000DA8109584031C979090708D51B4A1158D8 -:10AE50008B7CCC7C1B198B7410580121017510BCA4 -:10AE6000704770B51648114C0078114D154E4006CC -:10AE700008D5FBF729FBFFF777FF607280002858A1 -:10AE800000793070307840070BD4607A8000285801 -:10AE900040308079800606D40020FFF79FFF00280D -:10AEA00001D0012070BD002070BD0000780000209E -:10AEB0005804002084000020360400209404002060 -:10AEC000870000208C0000204749096801600020AD -:10AED000704745490860002070470121434A002817 -:10AEE00003D0012803D042487047916300E0D1634A -:10AEF000002070473F49012008603D48801C704792 -:10AF000004223D4B3B49002805D05A6008690122C4 -:10AF10001043086108E008694008400008619A6031 -:10AF200032490020C0318860002070473149062234 -:10AF3000002808D0012809D002280DD003280FD0FE -:10AF40002B48401C70470869904302E00869904311 -:10AF5000801C08610020704708699043001DF8E7D5 -:10AF600008691043F5E723494A6A02434A62002010 -:10AF7000704720494A6A82434A62002070471D494F -:10AF8000496A0160002070471A49CA690243CA61D0 -:10AF9000002070471749CA698243CA610020704780 -:10AFA0001449C96901600020704712490246002017 -:10AFB0004031002A03D0012A01D0072070478A635C -:10AFC00070470D490420886008490020C03188601E -:10AFD0000A4801688022090A0902114301600849F0 -:10AFE000012008607047000000040040400000405D -:10AFF00004200000000500400003004000E400E0E1 -:10B0000000E100E08107C90E002808DA0007000F00 -:10B0100008388008C24A80008018C06904E08008AF -:10B02000C04A800080180068C84080097047BE4947 -:10B0300048788978884201D3401A02E02122511AC7 -:10B040000818C0B27047B8492331487889788842D7 -:10B0500001D3401A02E02122511A0818C0B27047E9 -:10B06000B149463148788978884201D3401A02E0D4 -:10B070002122511A0818C0B27047AA4910B50C31E4 -:10B080000868FF22120290430122D2031043086095 -:10B09000A549002023314870887023394870887092 -:10B0A000463148708870A14800F04CF99F48401C18 -:10B0B00000F048F9FAF735FB00F028F910BD202020 -:10B0C0007047B4E770B50C4605460026FFF7AFFFA2 -:10B0D0009549A04214D30A46203A00232046641E14 -:10B0E000E4B200280BD08878105C287088786D1C3A -:10B0F000401CC0B288702128F0D18B70EEE7012689 -:10B1000000F004F9304670BD202070479BE770B511 -:10B110000C4605460026FFF796FF83492331A042DF -:10B1200014D30A46203A00232046641EE4B20028C5 -:10B130000BD08878105C287088786D1C401CC0B2D9 -:10B1400088702128F0D18B70EEE7012600F0DEF840 -:10B15000304670BD202101700020704710B50446B4 -:10B16000FFF77EFF2070002010BD70B50C4605462D -:10B17000FFF776FF6C494631A04215D30A46203AC4 -:10B1800000232046641EE4B200280BD08878105CAF -:10B19000287088786D1C401CC0B288702128F0D1BE -:10B1A0008B70EEE7002400E0614C00F0AFF8204621 -:10B1B00070BD70B50C460546212904D9FF205DA15C -:10B1C000473000F086FD56484068103840B2FFF71F -:10B1D00019FFC6B20D20FFF715FFC0B2864207D295 -:10B1E000FF2054A14D3000F074FD01E0FAF7DCFAC5 -:10B1F00021462846FFF766FF0028F7D070BDF8B556 -:10B2000007464A48484C401E474E00782546463679 -:10B210002335002806D1A9786878212200F06BF840 -:10B2200000280ED0A1786078212200F064F8002870 -:10B2300014D0B1787078212200F05DF8002828D071 -:10B2400033E039496878C91C0F546878401CC0B293 -:10B250006870212829D10020687026E03249607882 -:10B2600020390F546078401CC0B26070212801D191 -:10B27000002060702D4F7F1E3878002815D0A178EF -:10B280006078212200F037F800280ED000203870B6 -:10B290000BE02549707826310F547078401CC0B2FD -:10B2A0007070212801D100207070A978687821225F -:10B2B00000F021F800281DD0A1786078212200F04C -:10B2C0001AF8002816D0B1787078212200F013F80F -:10B2D00000280FD0FAF74AFA144800F03BF8012191 -:10B2E0004903884203D013A1C12000F0F2FC0F48AB -:10B2F00000F048F8F8BD401C884205D0904201D1CA -:10B30000002901D0002070470120704710B5074880 -:10B3100000F020F8002801D1FAF717FA10BD00005C -:10B3200000ED00E000E400E0C8070020FF0000207E -:10B33000072000007372635C736F635F72616E64F9 -:10B340002E6300000021017008467047014600206E -:10B3500008707047EFF31081C907C90F72B6027801 -:10B36000012A01D0012200E00022012303700029FC -:10B3700000D162B6002A01D00020704701204003AE -:10B380007047E7E7EFF31081C907C90F72B60022D3 -:10B390000270002900D162B600207047F2E7000079 -:10B3A0008107C90E002808DA0007000F0838800856 -:10B3B000864A80008018C06904E08008844A8000C2 -:10B3C00080180068C8408009704710B5044600F036 -:10B3D000E7F8002813D02046FFF7E2FFC0B200F0E4 -:10B3E000EDF800280DD07B4801210278002A0BD00F -:10B3F000E206D20E914042681143416009E076486E -:10B4000010BD7548401C10BDE006C00E8140734859 -:10B410000160002010BD10B5044600F0C1F80028FE -:10B420000BD06C4901200A78002A08D0E206D20E1F -:10B4300090404A6882434A6007E0674810BDE106D1 -:10B44000C90E8840654980310860002010BD70B584 -:10B450000D46044600F0A4F800280BD060480068B0 -:10B46000E206D20E01219140084000D00120286060 -:10B47000002070BD584870BD10B5044600F090F82B -:10B48000002807D0E106C90E012088405449086011 -:10B49000002010BD504810BD10B5044600F080F8E3 -:10B4A000002808D0E106C90E012088404C498031AF -:10B4B0000860002010BD484810BD70B50D46044618 -:10B4C00000F06EF8002819D0284600F077F8002820 -:10B4D00016D0FF20002C16DA2107090F08398A0838 -:10B4E0003A4992005118CB69A207D20E904083438B -:10B4F000A807000E90400343CB6112E0364870BDB0 -:10B500003548401C70BDA2083149920051180A68A4 -:10B51000A307DB0E98408243A807000E9840024321 -:10B520000A60002070BD70B50C46054600F038F882 -:10B53000002805D02846FFF733FF2070002070BD9B -:10B54000254870BDBFF34F8F20492648C860BFF320 -:10B550004F8FFEE770B51F4C05462178012000296A -:10B560000ED1207072B6F7F7A6FC1C4E80363168FB -:10B5700081436160F7F79FFCC043306062B60020F2 -:10B580002870002070BD13490A78002A06D00028D0 -:10B5900004D1124A486810600020087000207047EB -:10B5A00010B50446202805DAF7F785FC0121A140F3 -:10B5B000084201D0002010BD012010BD012803D099 -:10B5C000032801D0002070470120704700ED00E003 -:10B5D00000E400E0040100200120000000E100E0A0 -:10B5E00000E200E00400FA0510B52948FFF7AAFEC2 -:10B5F000002803D027A11D2000F06BFB2448401C2D -:10B60000FFF7A0FE002803D022A1212000F061FB5B -:10B6100010BDF8B5234D07466868009001261C4808 -:10B62000FFF798FE1A4C002803D10026601CFFF794 -:10B63000A9FE1D4A1D4900230120506000BF00BF24 -:10B6400000BF00BF00BF0B604B606F60106000BFA9 -:10B6500000BF00BF00BF00BF0868002802D14868D3 -:10B660000028F9D048680028E6D1002E05D00098BF -:10B670006860601CFFF76EFE07E0601CFFF76AFE63 -:10B680000028D3D10248FFF77DFE0020F8BDC0E7B7 -:10B690000C0100207372635C736F635F6563622EDD -:10B6A0006300000000E5004000E0004000E10040D1 -:10B6B0005B495C4B0A685C499A42096801D189047C -:10B6C000890C0160002070475549564B0A6856495D -:10B6D0009A4201D18004800C486000207047504994 -:10B6E000504B0A6850499A4201D18004800C88600E -:10B6F0000020704730B54A4B4A4D1C684B4BAC425A -:10B7000002D0102802D203E00E2801D3184630BD23 -:10B71000C3004548181801614261002030BD40490E -:10B72000404B0A684149491C9A4202D0042802D27F -:10B7300003E0022801D3084670473D4A0121C000BA -:10B7400080180160002070473549364B0A68374938 -:10B75000491C9A4202D0042802D203E0022801D3F5 -:10B7600008467047324A0121C0008018416000201D -:10B77000704730B52A4A2D4B2A4D14685B1C2D4A60 -:10B78000AC4206D0042806D2800080180160002058 -:10B7900030BD022801D3184630BD8904890CF3E777 -:10B7A00030B51F4A214B1F4D14685B1C214AAC4227 -:10B7B00005D0042805D280008018006808E002281F -:10B7C00001D3184630BD8000801800688004800CCA -:10B7D0000860002030BD10B5134A174890600E2055 -:10B7E0000021C3009B1819615961401C1028F8D32F -:10B7F0000020104A05E0022803D383009B1819603B -:10B8000005E083009B181C68A404A40C1C60401C69 -:10B810000428F0D310BD0449074888607047000031 -:10B820000C000020BEBAFECA00F50140082000004E -:10B8300000F0014000F8014000C0FFFF70B5002497 -:10B8400002460D4620462146002A20D0012A04D077 -:10B85000022A04D0032A0DD103E0012002E00220D5 -:10B8600015E003202B0000F040FB070507090B0D36 -:10B870000F11050007240EE0012108E0022106E077 -:10B88000032104E0042102E0052100E00621F7F78E -:10B89000CAFC0028EED0204670BD0000F0B51C4860 -:10B8A000002701211B4A8314476013601A4A17605E -:10B8B0001A4C23601A4B1C691E69E443E406E41722 -:10B8C000641C10252E431E61164B5960164E3160C4 -:10B8D00000E020BF1668002EFBD0002C03D1104CD6 -:10B8E0002669AE43266184688068A40501D50F4CA3 -:10B8F00020430D4C616099601760084AA1141160E3 -:10B90000F0BD10B50446FFF7C9FF2060002010BD50 -:10B9100000C5004080E100E000C1004080E200E09E -:10B9200000ED00E000C3004000C0004000FCFFFF4D -:10B9300070B51F490A68002A17D000231D4601244C -:10B940004A68521C4A60092A00D34D600E7922468B -:10B95000B2400E6816420AD072B60B6893430B6071 -:10B9600062B649680160002070BD052070BD5B1C97 -:10B97000092BE5D30FA1362000F0ABF9F5E7012044 -:10B980001049800508607047EFF31081CA07D20F95 -:10B9900072B6012181400648036819430160002AFC -:10B9A00000D162B6EBE702480021016041607047B8 -:10B9B000100100207372635C736F635F6576742E91 -:10B9C0006300000000E200E00A4A022151600A49D7 -:10B9D0000B68002BFCD0906008680028FCD0002089 -:10B9E000506008680028FCD07047012000074069BB -:10B9F0007047000000E5014000E40140012081079C -:10BA00000860704701208107486070471048C0688F -:10BA1000C00700D0012070470D488068C00700D0E3 -:10BA2000012070470A484069C00700D001207047D4 -:10BA30000748C069704706498A69D20306D58969F3 -:10BA40008907890F814201D101207047002070478A -:10BA500000040040F8B5042A2CD3830712D00B78D9 -:10BA6000491C0370401C521E83070BD00B78491CE5 -:10BA70000370401C521E830704D00B78491C0370CE -:10BA8000401C521E8B079B0F05D0C91ADF002023D4 -:10BA9000DE1B08C90AE0F5F7A3FBF8BD1D4608C97F -:10BAA000FD401C46B4402C4310C0121F042AF5D29E -:10BAB000F308C91A521EF0D40B78491C0370401CBD -:10BAC000521EEAD40B78491C0370401C521EE4D469 -:10BAD00009780170F8BD002203098B4273D3030A71 -:10BAE0008B4258D3030B8B423CD3030C8B4221D3A4 -:10BAF00012E003460B437FD4002243088B4274D3E9 -:10BB000003098B425FD3030A8B4244D3030B8B425E -:10BB100028D3030C8B420DD3FF22090212BA030C67 -:10BB20008B4202D31212090265D0030B8B4219D348 -:10BB300000E0090AC30B8B4201D3CB03C01A524168 -:10BB4000830B8B4201D38B03C01A5241430B8B42B0 -:10BB500001D34B03C01A5241030B8B4201D30B0399 -:10BB6000C01A5241C30A8B4201D3CB02C01A5241C0 -:10BB7000830A8B4201D38B02C01A5241430A8B4283 -:10BB800001D34B02C01A5241030A8B4201D30B026C -:10BB9000C01A5241CDD2C3098B4201D3CB01C01A86 -:10BBA000524183098B4201D38B01C01A5241430990 -:10BBB0008B4201D34B01C01A524103098B4201D37E -:10BBC0000B01C01A5241C3088B4201D3CB00C01AEB -:10BBD000524183088B4201D38B00C01A5241430863 -:10BBE0008B4201D34B00C01A5241411A00D2014688 -:10BBF0005241104670475DE0CA0F00D04942031021 -:10BC000000D34042534000229C4603098B422DD36F -:10BC1000030A8B4212D3FC22890112BA030A8B4217 -:10BC20000CD3890192118B4208D3890192118B4266 -:10BC300004D389013AD0921100E08909C3098B42EB -:10BC400001D3CB01C01A524183098B4201D38B012E -:10BC5000C01A524143098B4201D34B01C01A5241D1 -:10BC600003098B4201D30B01C01A5241C3088B4216 -:10BC700001D3CB00C01A524183088B4201D38B0001 -:10BC8000C01A5241D9D243088B4201D34B00C01A8B -:10BC90005241411A00D20146634652415B101046A0 -:10BCA00001D34042002B00D54942704763465B10E8 -:10BCB00000D3404201B50020C046C04602BD00008E -:10BCC000012308CB134B1860134B1960134B1A60F8 -:10BCD0007047134A134B13607246053AF0E7114A56 -:10BCE0000F4B1B689A420ED10D4B00201860019833 -:10BCF0000D4B04B598470CBC9E460246029800992D -:10BD00000A4B1B68184706980599094B1B68DB68A6 -:10BD100018470000200100202401002028010020F5 -:10BD200018010020EFBEADDE651400000800002001 -:10BD3000040000201D481E497047FFF7FBFFF5F780 -:10BD4000FDF900BD01200007C06AC0B2FF2804D180 -:10BD5000184819490968884202D0184818490160F2 -:10BD6000184819490968884203D1184A13605B686A -:10BD7000184700BD20BFFDE71248134909688842F3 -:10BD80000ED1134B18680B498842F3D080F3088812 -:10BD90001049884204DD1048026802210A4302600B -:10BDA0000E4880470E4880470E480047180800207C -:10BDB00018080020FFFFFFFF001000102C050040B6 -:10BDC0000800000000100000000000200400002017 -:10BDD00000D0000000200020240500407B1400005B -:10BDE00045BD0000C1BC00001348704502D1EFF30F -:10BDF000098101E0EFF30881886902380078102892 -:10BE000014DB202810DB2B280BDB0C4A12680C4BB0 -:10BE10009A4203D1602804DB0A4A104702200860D6 -:10BE20007047094A10470000084A1047084A12683C -:10BE30002C32126810470000FDFFFFFF0C000020AD -:10BE4000BEBAFECA95150000ED2600009B13000047 -:10BE5000040000200D4B0E4908470E4B0C490847C3 -:10BE60000D4B0B4908470D4B094908470C4B084936 -:10BE700008470C4B064908470B4B054908470B4B35 -:10BE8000034908470A4B024908470000555500007E -:10BE900019140000C92600007325000021250000A8 -:10BEA00085570000A1150000A315000037260000EB -:10BEB000BB4A00000021017041708170C1700171A6 -:10BEC00041718171C17170470A7802704B7843707B -:10BED0008A788270CA78C2700B7903714A7942718C -:10BEE0008A798271CB79C371704730B47446641E0D -:10BEF0002578641CAB4200D21D46635D5B00E318ED -:10BF000030BC1847415858352E3030423030000090 -:10BF1000ECF4FC0004FFE11D9AED853324EA7AD2AB -:10BF2000397097570A547D2DD86D0DBA8F6759C750 -:10BF3000A2BF3400FFFF008000400020001000007E -:10BF400000000000F8FC7C7E3E3F9F1FCF0FE707FC -:10BF50000000000074BF0000080000202401000061 -:10BF60000411000098C000002C010020EC06000025 -:10BF70002011000000000000000000000000000090 -:10BF800000000000000000000000000000000000B1 -:10BF900000000000000000000000000000000000A1 -:10BFA0000000000000000000000000000000000091 -:10BFB0000000000000000000000000000000000081 -:10BFC0000000000000000000000000000000000071 -:10BFD0000000000000000000000000000000000061 -:10BFE0000000000000000000000000000000000051 -:10BFF0000000000000000000000000000000000041 -:10C000000000000000000000000000000000000030 -:10C010000000000000000000000000000000000020 -:10C020000000000000000000000000000000000010 -:10C030000000000000000000000000000000000000 -:10C0400000000000000000000000000000000000F0 -:10C0500000000000000000000000000000000000E0 -:10C0600000000000000000000000010000000000CF -:10C0700000000000000000000000000000000000C0 -:10C080000000000000000000C5BC0000000000002F -:08C090000000000000000000A8 -:00000001FF diff --git a/components/softdevice/s210/toolchain/armgcc/armgcc_s210_nrf51422_xxaa.ld b/components/softdevice/s210/toolchain/armgcc/armgcc_s210_nrf51422_xxaa.ld deleted file mode 100644 index ba46908..0000000 --- a/components/softdevice/s210/toolchain/armgcc/armgcc_s210_nrf51422_xxaa.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0xd000, LENGTH = 0x33000 - RAM (rwx) : ORIGIN = 0x20000900, LENGTH = 0x3700 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s210/toolchain/armgcc/armgcc_s210_nrf51422_xxac.ld b/components/softdevice/s210/toolchain/armgcc/armgcc_s210_nrf51422_xxac.ld deleted file mode 100644 index 11eb042..0000000 --- a/components/softdevice/s210/toolchain/armgcc/armgcc_s210_nrf51422_xxac.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0xd000, LENGTH = 0x33000 - RAM (rwx) : ORIGIN = 0x20000900, LENGTH = 0x7700 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s210/toolchain/iar/iar_s210_nrf51422_xxaa.icf b/components/softdevice/s210/toolchain/iar/iar_s210_nrf51422_xxaa.icf deleted file mode 100644 index 8369cf3..0000000 --- a/components/softdevice/s210/toolchain/iar/iar_s210_nrf51422_xxaa.icf +++ /dev/null @@ -1,31 +0,0 @@ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ -/*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0xd000; -/*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0xd000; -define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20000900; -define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; -/*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 0x800; -define symbol __ICFEDIT_size_heap__ = 0x200; -/**** End of ICF editor section. ###ICF###*/ - -define memory mem with size = 4G; -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; - -define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; -define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; - -initialize by copy { readwrite }; -do not initialize { section .noinit }; - -keep { section .intvec }; -place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; -place in ROM_region { readonly }; -place in RAM_region { readwrite, - block CSTACK, - block HEAP }; diff --git a/components/softdevice/s210/toolchain/iar/iar_s210_nrf51422_xxac.icf b/components/softdevice/s210/toolchain/iar/iar_s210_nrf51422_xxac.icf deleted file mode 100644 index 9ae7e3d..0000000 --- a/components/softdevice/s210/toolchain/iar/iar_s210_nrf51422_xxac.icf +++ /dev/null @@ -1,31 +0,0 @@ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ -/*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0xd000; -/*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0xd000; -define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20000900; -define symbol __ICFEDIT_region_RAM_end__ = 0x20007fff; -/*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 0x800; -define symbol __ICFEDIT_size_heap__ = 0x200; -/**** End of ICF editor section. ###ICF###*/ - -define memory mem with size = 4G; -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; - -define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; -define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; - -initialize by copy { readwrite }; -do not initialize { section .noinit }; - -keep { section .intvec }; -place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; -place in ROM_region { readonly }; -place in RAM_region { readwrite, - block CSTACK, - block HEAP }; diff --git a/components/softdevice/s212/headers/nrf_sd_def.h b/components/softdevice/s212/headers/nrf_sd_def.h new file mode 100644 index 0000000..d66ceff --- /dev/null +++ b/components/softdevice/s212/headers/nrf_sd_def.h @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SD_DEF_H__ +#define NRF_SD_DEF_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_PPI_CHANNELS_USED 0xFFF0FF00uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */ +#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ +#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ +#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SD_DEF_H__ */ diff --git a/components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld b/components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld new file mode 100644 index 0000000..ad335fa --- /dev/null +++ b/components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld @@ -0,0 +1,28 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x12000, LENGTH = 0x6e000 + RAM (rwx) : ORIGIN = 0x20000a80, LENGTH = 0xf580 +} + +SECTIONS +{ + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM + .pwr_mgmt_data : + { + PROVIDE(__start_pwr_mgmt_data = .); + KEEP(*(.pwr_mgmt_data)) + PROVIDE(__stop_pwr_mgmt_data = .); + } > RAM +} INSERT AFTER .data; + +INCLUDE "nrf5x_common.ld" diff --git a/components/softdevice/s110/toolchain/iar/iar_s110_nrf51822_xxaa.icf b/components/softdevice/s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf similarity index 74% rename from components/softdevice/s110/toolchain/iar/iar_s110_nrf51822_xxaa.icf rename to components/softdevice/s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf index 7b19877..d4e407d 100644 --- a/components/softdevice/s110/toolchain/iar/iar_s110_nrf51822_xxaa.icf +++ b/components/softdevice/s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf @@ -2,12 +2,14 @@ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x18000; +define symbol __ICFEDIT_intvec_start__ = 0x12000; /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x18000; -define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002000; -define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; +define symbol __ICFEDIT_region_ROM_start__ = 0x12000; +define symbol __ICFEDIT_region_ROM_end__ = 0x7ffff; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000a80; +define symbol __ICFEDIT_region_RAM_end__ = 0x2000ffff; +export symbol __ICFEDIT_region_RAM_start__; +export symbol __ICFEDIT_region_RAM_end__; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x200; @@ -29,3 +31,4 @@ place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; + diff --git a/components/softdevice/s310/doc/s310_nrf51822_3.0.0_licence_agreement.pdf b/components/softdevice/s310/doc/s310_nrf51822_3.0.0_licence_agreement.pdf deleted file mode 100644 index 61f64d3824ed1122550d40e296fc139bda42b74c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7025 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 diff --git a/components/softdevice/s310/doc/s310_nrf51822_3.0.0_licence_agreement.txt b/components/softdevice/s310/doc/s310_nrf51822_3.0.0_licence_agreement.txt deleted file mode 100644 index e88fb31..0000000 --- a/components/softdevice/s310/doc/s310_nrf51822_3.0.0_licence_agreement.txt +++ /dev/null @@ -1,110 +0,0 @@ -S210/S310 license agreement - -S210 AND S310 LICENSE AGREEMENT - -License Agreement for the Nordic Semiconductor ASA (“Nordic”) S210 ANT Softdevice software package (“S210”) and the Nordic Semiconductor -ASA S310 ANT and BLE Softdevice software package (“S310”). - -You (“You” or “Licensee”) must carefully and thoroughly read this License Agreement (“Agreement”), and accept to adhere to this Agreement -before downloading, installing and/or using any software or content in the S210 or S310 provided herewith. - -YOU ACCEPT THIS LICENSE AGREEMENT BY (A) CLICKING ACCEPT OR AGREE TO THIS LICENSE AGREEMENT, WHERE THIS -OPTION IS MADE AVAILABLE TO YOU; OR (B) BY ACTUALLY USING THE S210 OR S310, IN THIS CASE YOU AGREE THAT THE USE OF -THE S210 OR S310 CONSTITUTES ACCEPTANCE OF THE LICENSING AGREEMENT FROM THAT POINT ONWARDS. - -IF YOU DO NOT AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT, THEN DO NOT DOWNLOAD, INSTALL/COMPLETE -INSTALLATION OF, OR IN ANY OTHER WAY MAKE USE OF THE S210 OR S310 OR ANY DOCUMENTATION RELATED TO THE S210 OR -S310. - -1. Grant of License -Subject to the terms in this Agreement Nordic grants Licensee a limited, non-exclusive, non-transferable, non-sub licensable, revocable license -(“License”): (a) to use the S210 and S310 solely in connection with the nRF51422 Nordic Integrated Circuit (“nRF51422 IC”), and (b) to distribute -the S210 or S310 solely as implemented in Licensee products. Licensee shall not use the S210 or S310 for any purpose other than specifically -authorized herein. It is a material breach of this agreement to use or modify the S210 or S310 for use on any wireless connectivity integrated -circuit other than the nRF51422 IC. - -2. Title -Nordic or its licensors (as applicable) retain full rights, title, and ownership to the S210 and S310 and any and all patents, copyrights, trade -secrets, trade names, trademarks, and other intellectual property rights in and to the S210 and S310. Nordic licenses portions of the S210 and -S310 from third party licensors, and such licensors retain their respective full rights, title, and ownership in and of the S210 and S310 and any and -all patents, copyrights, trade secrets, trade names, trademarks, and other intellectual property rights in and to the S210 and S310. - -3. No Modifications or Reverse Engineering -Licensee shall not, modify, reverse engineer, disassemble, decompile or otherwise attempt to discover the source code of any non-source code -parts of the S210 and S310 including, but not limited to pre-compiled hex files, binaries and object code. - -4. Distribution Restrictions -Except as set forward in Section 1 above, the Licensee may not disclose or distribute any or all parts of the S210 and S310 to any third party. -Licensee agrees to provide reasonable security precautions to prevent unauthorized access to or use of the S210 and S310 as proscribed herein. -Licensee also agrees that use of and access to the S210 and S310 will be strictly limited to the employees and subcontractors of the Licensee -necessary for the performance of development, verification and production tasks under this Agreement. The Licensee is responsible for making -such employees and subcontractors agree on complying with the obligations concerning use and non-disclosure of the S210 and S310. - -5. End Use Restrictions -Licensee agrees that the S210 and S310 may not be sold, resold, transferred, diverted, exported, re-exported or disposed of (i) for use in -activities involving the development, production, handling, use, operation, maintenance, storage, detection, identification or dissemination of -nuclear, chemical, or biological weapons (including missiles and weapons of mass destruction), nor for use in any facilities engaged in activities -related to such weapons, including where there are reasonable grounds to suspect any such use; (ii) for a military end-use in China or in any -other country subject to any applicable arms embargo or for an item designed, modified, configured, or adapted for a military application in China -or any other country subject to an applicable arms embargo; (iii) to or for the benefit of individuals or entities listed on any applicable restricted or -prohibited party lists; or (iv) to the following countries: Cuba, Iran, North Korea, Sudan, and Syria. Licensee further agree to abide by all other -applicable export controls, trade sanctions and embargo laws, regulations, rules and licenses ("Export Controls and Sanctions Rules") in force -from time to time as they relate to the S210 and S310. You acknowledge that your obligation to comply with applicable Export Controls and -Sanctions Rules is independent of these terms and conditions and you agree to indemnify and hold Nordic and its licensors harmless from and -against any third-party claim, including fines, losses, liabilities or legal fees that arise as a result of the breach by you of these terms and -conditions or any applicable export controls, trade sanctions and embargo laws, regulations, rules and licenses. - -6. No Other Rights -Licensee shall use the S210 and S310 only in compliance with this Agreement and shall refrain from using the S210 and S310 in any way that -may be contrary to this Agreement. - -7. Fees -Nordic grants the License to the Licensee free of charge provided that the Licensee undertakes the obligations in the Agreement and warrants to -comply with the Agreement. - -8. DISCLAIMER OF WARRANTY -THE S210 AND S310 ARE PROVIDED “AS IS" WITHOUT WARRANTY OF ANY KIND EXPRESS OR IMPLIED AND NEITHER NORDIC, ITS -LICENSORS OR AFFILIATES NOR THE COPYRIGHT HOLDERS MAKE ANY REPRESENTATIONS OR WARRANTIES, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR -THAT THE S210 AND S310 WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. -THERE IS NO WARRANTY BY NORDIC OR BY ANY OTHER PARTY THAT THE FUNCTIONS CONTAINED IN THE S210 AND S310 WILL -MEET THE REQUIREMENTS OF LICENSEE OR THAT THE OPERATION OF THE S210 AND S310 WILL BE UNINTERRUPTED OR -ERROR-FREE. LICENSEE ASSUMES ALL RESPONSIBILITY AND RISK FOR THE SELECTION OF THE S210 AND S310 TO ACHIEVE -LICENSEE’S INTENDED RESULTS AND FOR THE INSTALLATION, USE AND RESULTS OBTAINED FROM IT. - -9. No Support -Nordic is not obligated to furnish or make available to Licensee any further information, software, technical information, know-how, show-how, -bug-fixes or support. Nordic reserves the right to make changes to the S210 and S310 without further notice. - -10. Limitation of Liability -In no event shall Nordic, its employees or suppliers, licensors or affiliates be liable for any lost profits, revenue, sales, data or costs of -procurement of substitute goods or services, property damage, personal injury, interruption of business, loss of business information or for any -special, direct, indirect, incidental, economic, punitive, special or consequential damages, however caused and whether arising under contract, -tort, negligence, or other theory of liability arising out of the use of or inability to use the S210 and S310, even if Nordic or its employees or -suppliers, licensors or affiliates are advised of the possibility of such damages. Because some countries/states/jurisdictions do not allow the -exclusion or limitation of liability, but may allow liability to be limited, in such cases, Nordic, its employees or licensors or affiliates’ liability shall be -limited to USD 50. - -11. Breach of Contract -Upon a breach of contract by the Licensee, Nordic and its licensor are entitled to damages in respect of any direct loss which can be reasonably -attributed to the breach by the Licensee. If the Licensee has acted with gross negligence or willful misconduct, the Licensee shall cover both -direct and indirect costs for Nordic and its licensors. - -12. Indemnity -Licensee undertakes to indemnify, hold harmless and defend Nordic and its directors, officers, affiliates, shareholders, licensors, employees and -agents from and against any claims or lawsuits, including attorney's fees, that arise or result of the Licensee’s execution of the License and which -is not due to causes for which Nordic is responsible. - -13. Governing Law -This Agreement shall be construed according to the laws of Norway, and hereby submits to the exclusive jurisdiction of the Oslo tingrett. - -14. Assignment -Licensee shall not assign this Agreement or any rights or obligations hereunder without the prior written consent of Nordic. - -15. Termination -Without prejudice to any other rights, Nordic may cancel this Agreement if Licensee does not abide by the terms and conditions of this -Agreement. Upon termination Licensee must promptly cease the use of the License and destroy all copies of the Licensed Technology and any -other material provided by Nordic or its affiliate, or produced by the Licensee in connection with the Agreement or the Licensed Technology. - -16. Third party beneficiaries -Nordic’s licensors are intended third party beneficiaries under this Agreement. \ No newline at end of file diff --git a/components/softdevice/s310/doc/s310_nrf51822_3.0.0_migration_document.pdf b/components/softdevice/s310/doc/s310_nrf51822_3.0.0_migration_document.pdf deleted file mode 100644 index d8a089f314ee9b02413449acf38f94c249f2e7fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 432939 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

?}-=#|J+i8laI1D#_TcGAf3vc9y^$!$f%1WS5) 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 z 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 z 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 diff --git a/components/softdevice/s310/doc/s310_nrf51822_3.0.0_readme.txt b/components/softdevice/s310/doc/s310_nrf51822_3.0.0_readme.txt deleted file mode 100644 index c617a24..0000000 --- a/components/softdevice/s310/doc/s310_nrf51822_3.0.0_readme.txt +++ /dev/null @@ -1,14 +0,0 @@ -s310_nrf51422_3.0.0 - -This release consists of the following: -- This readme file -- The s310_nrf51422_3.0.0 softdevice (binary hex file) -- The s310_nrf51422_3.0.0 API (softdevice header files) -- The s210 and s310 licence agreement -- The s310_nrf51422_3.0.0 release notes -- The s310_nrf51422_3.0.0 migration-document.pdf - - -IMPORTANT NOTE: If you intend to use the softdevice with the nRF51 -SDK only, you do _not_ need the API files. The API header files are -already installed as part of the nRF51 SDK version 7.1.0 or newer. diff --git a/components/softdevice/s310/doc/s310_nrf51822_3.0.0_releasenotes.pdf b/components/softdevice/s310/doc/s310_nrf51822_3.0.0_releasenotes.pdf deleted file mode 100644 index 3c7d5b04242f921e753cbaf3e6bbab1b00f1d484..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140119 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 Fe*nT1-H!kO diff --git a/components/softdevice/s310/headers/ant_error.h b/components/softdevice/s310/headers/ant_error.h deleted file mode 100644 index 0b326b9..0000000 --- a/components/softdevice/s310/headers/ant_error.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Dynastream Innovations Inc. - * Cochrane, AB, CANADA - * - * Copyright (c) 2012 Dynastream Innovations Inc. - * THIS SOFTWARE IS AN EXAMPLE USAGE OF THE ANT PROTOCOL MODULE. - * IT MAY BE USED, MODIFIED and DISTRIBUTED ONLY WITH THE - * APPROPRIATE LICENSE AGREEMENT. - */ - -/* Header guard */ -#ifndef ANT_ERROR_H__ -#define ANT_ERROR_H__ - -#include "ant_parameters.h" - -/** - @defgroup ant_error ANT Error Return - @{ - @ingroup ant_interface -*/ - -/** @brief ANT Error Return parameter definitions */ -#define NRF_ANT_ERROR_OFFSET 0x4000 //ANT's Exception offset - -#define NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE NRF_ANT_ERROR_OFFSET + CHANNEL_IN_WRONG_STATE ///< Response on attempt to perform an action from the wrong channel state. -#define NRF_ANT_ERROR_CHANNEL_NOT_OPENED NRF_ANT_ERROR_OFFSET + CHANNEL_NOT_OPENED ///< Response on attempt to communicate on a channel that is not open. -#define NRF_ANT_ERROR_CHANNEL_ID_NOT_SET NRF_ANT_ERROR_OFFSET + CHANNEL_ID_NOT_SET ///< Response on attempt to open a channel without setting the channel ID. -#define NRF_ANT_ERROR_CLOSE_ALL_CHANNELS NRF_ANT_ERROR_OFFSET + CLOSE_ALL_CHANNELS ///< Response when attempting to start scanning mode, when channels are still open. -#define NRF_ANT_ERROR_TRANSFER_IN_PROGRESS NRF_ANT_ERROR_OFFSET + TRANSFER_IN_PROGRESS ///< Response on attempt to communicate on a channel with a TX transfer in progress. -#define NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR NRF_ANT_ERROR_OFFSET + TRANSFER_SEQUENCE_NUMBER_ERROR ///< Response when sequence number of burst message or burst data segment is out of order. -#define NRF_ANT_ERROR_TRANSFER_IN_ERROR NRF_ANT_ERROR_OFFSET + TRANSFER_IN_ERROR ///< Response when transfer error has occured on supplied burst message or burst data segment. -#define NRF_ANT_ERROR_TRANSFER_BUSY NRF_ANT_ERROR_OFFSET + TRANSFER_BUSY ///< Response when transfer is busy and cannot process supplied burst message or burst data segment. -#define NRF_ANT_ERROR_MESSAGE_SIZE_EXCEEDS_LIMIT NRF_ANT_ERROR_OFFSET + MESSAGE_SIZE_EXCEEDS_LIMIT ///< Response if a data message is provided that is too large. -#define NRF_ANT_ERROR_INVALID_MESSAGE NRF_ANT_ERROR_OFFSET + INVALID_MESSAGE ///< Response when the message has an invalid parameter. -#define NRF_ANT_ERROR_INVALID_NETWORK_NUMBER NRF_ANT_ERROR_OFFSET + INVALID_NETWORK_NUMBER ///< Response when an invalid network number is provided -#define NRF_ANT_ERROR_INVALID_LIST_ID NRF_ANT_ERROR_OFFSET + INVALID_LIST_ID ///< Response when the provided list ID or size exceeds the limit -#define NRF_ANT_ERROR_INVALID_SCAN_TX_CHANNEL NRF_ANT_ERROR_OFFSET + INVALID_SCAN_TX_CHANNEL ///< Response when attempting to transmit on channel 0 when in scan mode. -#define NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED NRF_ANT_ERROR_OFFSET + INVALID_PARAMETER_PROVIDED ///< Response when an invalid parameter is specified in a configuration message -#endif // ANT_ERROR_H__ -/** - @} - */ diff --git a/components/softdevice/s310/headers/ant_interface.h b/components/softdevice/s310/headers/ant_interface.h deleted file mode 100644 index b60f60b..0000000 --- a/components/softdevice/s310/headers/ant_interface.h +++ /dev/null @@ -1,939 +0,0 @@ -/* - * Dynastream Innovations Inc. - * Cochrane, AB, CANADA - * - * Copyright (c) 2014 Dynastream Innovations Inc. - * THIS SOFTWARE IS AN EXAMPLE USAGE OF THE ANT PROTOCOL MODULE. - * IT MAY BE USED, MODIFIED and DISTRIBUTED ONLY WITH THE - * APPROPRIATE LICENSE AGREEMENT. - */ -/* Header guard */ -#ifndef ANT_INTERFACE_H__ -#define ANT_INTERFACE_H__ - -#include -#include -#include "nrf_svc.h" - -/** - @addtogroup stack_ant_module ANT STACK - @{ - @defgroup ant_interface ANT Application Interface - @{ -* @brief ANT Stack Application Programming Interface (API). -*/ - -#define STK_SVC_BASE_2 0xC0 // ANT stack protocol SVC base - -/** @brief ANT Stack API SVC numbers */ -enum { - /*ant re/initialization API*/ - SVC_ANT_STACK_INIT = STK_SVC_BASE_2, - /*event API*/ - SVC_ANT_EVENT_GET, - /*channel control API*/ - SVC_ANT_CHANNEL_ASSIGN, - SVC_ANT_CHANNEL_UNASSIGN, - SVC_ANT_CHANNEL_OPEN, - SVC_ANT_CHANNEL_CLOSE, - SVC_ANT_RX_SCAN_MODE_START, - /*data APIs*/ - SVC_ANT_TX_BROADCAST_MESSAGE, - SVC_ANT_TX_ACKNOWLEDGED_MESSAGE, - SVC_ANT_BURST_HANDLER_REQUEST, - SVC_ANT_PENDING_TRANSMIT_CLEAR, - SVC_ANT_TRANSFER_STOP, - /*radio configuration APIs*/ - SVC_ANT_NETWORK_KEY_SET, - SVC_ANT_CHANNEL_RADIO_FREQ_SET, - SVC_ANT_CHANNEL_RADIO_FREQ_GET, - SVC_ANT_CHANNEL_RADIO_TX_POWER_SET, - SVC_ANT_PROX_SEARCH_SET, - /*configuration APIs*/ - SVC_ANT_CHANNEL_PERIOD_SET, - SVC_ANT_CHANNEL_PERIOD_GET, - SVC_ANT_CHANNEL_ID_SET, - SVC_ANT_CHANNEL_ID_GET, - SVC_ANT_SEARCH_WAVEFORM_SET, - SVC_ANT_CHANNEL_RX_SEARCH_TIMEOUT_SET, - SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET, - SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET, - SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET, - SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET, - SVC_ANT_ADV_BURST_CONFIG_SET, - SVC_ANT_ADV_BURST_CONFIG_GET, - SVC_ANT_LIB_CONFIG_SET, - SVC_ANT_LIB_CONFIG_CLEAR, - SVC_ANT_LIB_CONFIG_GET, - SVC_ANT_ID_LIST_ADD, - SVC_ANT_ID_LIST_CONFIG, - SVC_ANT_AUTO_FREQ_HOP_TABLE_SET, - SVC_ANT_EVENT_FILTERING_SET, - SVC_ANT_EVENT_FILTERING_GET, - /*status APIs*/ - SVC_ANT_ACTIVE, - SVC_ANT_CHANNEL_IN_PROGRESS, - SVC_ANT_CHANNEL_STATUS_GET, - SVC_ANT_PENDING_TRANSMIT, - /*radio test APIs*/ - SVC_ANT_INIT_CW_TEST_MODE, - SVC_ANT_CW_TEST_MODE, - /*antstack version API*/ - SVC_ANT_VERSION, - /*antstack capabilities API*/ - SVC_ANT_CAPABILITIES, - /*more data APIs*/ - SVC_ANT_BURST_HANDLER_WAIT_FLAG_ENABLE, - SVC_ANT_BURST_HANDLER_WAIT_FLAG_DISABLE, - /*more configuration APIs*/ - SVC_ANT_SDU_MASK_SET, - SVC_ANT_SDU_MASK_GET, - SVC_ANT_SDU_MASK_CONFIG, - SVC_ANT_CRYPTO_CHANNEL_ENABLE, - SVC_ANT_CRYPTO_KEY_SET, - SVC_ANT_CRYPTO_INFO_SET, - SVC_ANT_CRYPTO_INFO_GET, - SVC_ANT_RFACTIVE_NOTIFICATION_CONFIG_SET, - SVC_ANT_RFACTIVE_NOTIFICATION_CONFIG_GET, - SVC_ANT_COEX_CONFIG_SET, - SVC_ANT_COEX_CONFIG_GET, - SVC_ANT_ENABLE, - /*reserved APIs*/ - SVC_ANT_RESERVED1, - SVC_ANT_RESERVED2, - /*extended APIs*/ - SVC_ANT_EXTENDED0, - SVC_ANT_EXTENDED1, - SVC_ANT_EXTENDED2, // LAST (64 SVCs) -}; - -////////////////////////////////////////////// -/** @name ANT enable channel structure - * - * @brief Structure for setting up ANT stack channels -@{ */ -////////////////////////////////////////////// -typedef struct -{ - /*Total number of channels wanted in ANT stack*/ - uint8_t ucTotalNumberOfChannels; - /*Number of encrypted channels wanted (subset of total channels)*/ - uint8_t ucNumberOfEncryptedChannels; - /*Memory location pointer to start allocating ANT channels*/ - uint8_t* pucMemoryBlockStartLocation; - /*Block byte size available for ANT channels starting at memory location pointer*/ - uint16_t usMemoryBlockByteSize; -} ANT_ENABLE; -/** @} */ - -/******************************************************************************/ -/** @name ANT API functions - * @{ */ -/******************************************************************************/ - -/******************************* RE/INITIALIZATION API *******************************/ - -/** @brief Function for initializing or re-initializing ANT Stack. - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_STACK_INIT, uint32_t, sd_ant_stack_reset (void)); - -/******************************* EVENT API *******************************/ - -/** @brief This function returns ANT channel events and data messages. - * - * @param[out] pucChannel is the pointer to an unsigned char (1 octet) where the channel number will be copied. - * @param[out] pucEvent is the pointer to an unsigned char (1 octet) where the event code will be copied. See Channel Events and Command Response Codes in ant_parameters.h. - * @param[out] aucANTMesg is the buffer where event's message will be copied. The array size must be at least MESG_BUFFER_SIZE to accommadate the entire ANT_MESSAGE structure size. See ANT Message Structure in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * @return ::NRF_ERROR_INVALID_PARAM - * @return ::NRF_ERROR_NOT_FOUND - */ -SVCALL(SVC_ANT_EVENT_GET, uint32_t, sd_ant_event_get (uint8_t *pucChannel, uint8_t *pucEvent, uint8_t *aucANTMesg)); - -/********************** CHANNEL CONTROL APIS ******************************/ - -/** @brief This function assigns and initializes a new channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to assign. - * @param[in] ucChannelType is an unsigned char (1 octet) denoting the channel type. See Assign Channel Parameters/Assign Channel Types in ant_parameters.h. - * @param[in] ucNetwork is an unsigned char (1 octet) denoting the network key to associate with the channel. - * @param[in] ucExtAssign is a bit field (1 octet) for an extended assign. See Ext. Assign Channel Parameters in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_INVALID_NETWORK_NUMBER - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - */ -SVCALL(SVC_ANT_CHANNEL_ASSIGN, uint32_t, sd_ant_channel_assign (uint8_t ucChannel, uint8_t ucChannelType, uint8_t ucNetwork, uint8_t ucExtAssign)); - -/** @brief This function unassigns a channel. The channel to unassign must be in an assigned state. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to unassign. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - */ -SVCALL(SVC_ANT_CHANNEL_UNASSIGN, uint32_t, sd_ant_channel_unassign (uint8_t ucChannel)); - -/** @brief This function opens and activates a channel. The channel to open must be in an assigned state. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to open. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - */ -SVCALL(SVC_ANT_CHANNEL_OPEN, uint32_t, sd_ant_channel_open(uint8_t ucChannel)); - -/** @brief This function closes a channel. The channel must be in an open state (SEARCHING or TRACKING). - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to close. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - * - */ -SVCALL(SVC_ANT_CHANNEL_CLOSE, uint32_t, sd_ant_channel_close (uint8_t ucChannel)); - -/** @brief This function starts receive scanning mode feature. Channel 0 must be assigned. All other channels must be closed. - * - * @param[in] ucSyncChannelPacketsOnly is an unsigned char (1 octet) denoting synchronous channel only scanning mode. 0 = disable, 1 = enable. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_CLOSE_ALL_CHANNELS - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - */ -SVCALL(SVC_ANT_RX_SCAN_MODE_START, uint32_t, sd_ant_rx_scan_mode_start (uint8_t ucSyncChannelPacketsOnly)); - -/*********************** DATA APIS ****************************************/ - -/** @brief This function is used to set broadcast data for transmission. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to send the data on. - * @param[in] ucSize is an unsigned char (1 octet) denoting the size of the message, ucSize must be 8. - * @param[in] aucMesg is the buffer where the message is located (array must be 8 octets). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_MESSAGE_SIZE_EXCEEDS_LIMIT - * ::NRF_ANT_ERROR_INVALID_SCAN_TX_CHANNEL - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - * ::NRF_ANT_ERROR_TRANSFER_IN_ERROR - */ -SVCALL(SVC_ANT_TX_BROADCAST_MESSAGE, uint32_t, sd_ant_broadcast_message_tx (uint8_t ucChannel, uint8_t ucSize, uint8_t *aucMesg)); - -/** @brief This function is used to send an acknowledge message. This message requests an acknowledgement from the slave to validate reception. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to send the data on. - * @param[in] ucSize is an unsigned char (1 octet) denoting the size of the message, ucSize must be 8. - * @param[in] aucMesg is the buffer where the message is located (array must be 8 octets). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_MESSAGE_SIZE_EXCEEDS_LIMIT - * ::NRF_ANT_ERROR_INVALID_SCAN_TX_CHANNEL - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - * ::NRF_ANT_ERROR_TRANSFER_IN_ERROR - */ -SVCALL(SVC_ANT_TX_ACKNOWLEDGED_MESSAGE, uint32_t, sd_ant_acknowledge_message_tx (uint8_t ucChannel, uint8_t ucSize, uint8_t *aucMesg)); - -/** @brief This function is used to queue data for burst transmission. After every successful call, the input buffer is held in use by the burst handler and must not be changed. - * When the burst handler releases the input buffer, it will either generate a EVENT_TRANSFER_NEXT_DATA_BLOCK event or clear a specified wait flag assigned to the - * burst handler. Transfer end events: EVENT_TRANSFER_TX_COMPLETED and EVENT_TRANSFER_TX_FAILED also releases the input buffer. Special care must be made to ensure that - * the input buffer does not change until it is released by the burst handler to avoid data corruption. Use of burst segment identifiers (BURST_SEGMENT_START, BURST_SEGMENT_CONTINUE, - * and BURST_SEGMENT_END) is required to indicate the sequence of the data block being sent as a burst transfer. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to do a burst transmission. - * @param[in] usSize is an unsigned short (2 octets) denoting the size of the message block. Size must be divisible by 8. - * @param[in] aucData is the buffer where the message block is located. - * @param[in] ucBurstSegment is an unsigned char (1 octet) containing a bitfield representing the message block type. See Tx Burst Handler Request Segment Defines in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_INVALID_SCAN_TX_CHANNEL - * ::NRF_ANT_ERROR_CHANNEL_NOT_OPENED - * ::NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - * ::NRF_ANT_ERROR_TRANSFER_IN_ERROR - * ::NRF_ANT_ERROR_MESSAGE_SIZE_EXCEEDS_LIMIT - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - * ::NRF_ANT_ERROR_TRANSFER_BUSY - */ -SVCALL(SVC_ANT_BURST_HANDLER_REQUEST, uint32_t, sd_ant_burst_handler_request(uint8_t ucChannel, uint16_t usSize, uint8_t *aucData, uint8_t ucBurstSegment)); - -/** @brief This function clears a pending transmit. Primarily intended for shared slave channels (receive channel). - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to clear pending transmit. - * @param[out] pucSuccess is the pointer to an unsigned char (1 octet) where the result will be stored. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_PENDING_TRANSMIT_CLEAR, uint32_t, sd_ant_pending_transmit_clear (uint8_t ucChannel, uint8_t *pucSuccess)); - -/** @brief This function kills a receive transfer that is in progress. - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_TRANSFER_STOP, uint32_t, sd_ant_transfer_stop (void)); - -/********************** RADIO CONFIGURATION APIS **************************/ - -/** @brief This function sets the 64bit network address. - * - * @param[in] ucNetwork is an unsigned char (1 octet) denoting the network number to assign the network address to. - * @param[in] aucNetworkKey is the pointer to location of the Network Key (8 octets in length) - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_NETWORK_NUMBER - */ -SVCALL(SVC_ANT_NETWORK_KEY_SET, uint32_t, sd_ant_network_address_set (uint8_t ucNetwork, uint8_t *aucNetworkKey)); - -/** @brief This function sets the radio frequency of an ANT channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set to. - * @param[in] ucFreq is an unsigned char (1 octet) denoting the radio frequency offset from 2400MHz (eg. 2466MHz, ucFreq = 66). - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_NETWORK_NUMBER - */ -SVCALL(SVC_ANT_CHANNEL_RADIO_FREQ_SET, uint32_t, sd_ant_channel_radio_freq_set (uint8_t ucChannel, uint8_t ucFreq)); - -/** @brief This function returns the radio frequency of an ANT channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pucRfreq is the pointer to an unsigned char (1 octet) where the frequency will be stored. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_RADIO_FREQ_GET, uint32_t, sd_ant_channel_radio_freq_get (uint8_t ucChannel, uint8_t *pucRfreq)); - -/** @brief This function sets the radio tx power. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to assign the radio tx power. - * @param[in] ucTxPower is an unsigned char (1 octet) denoting the ANT transmit power index. See Radio TX Power Definitions in ant_parameters.h. - * @param[in] ucCustomTxPower is an unsigned char (1 octet) denoting the custom nRF transmit power as defined in nrf51_bitfields.h. Only applicable if ucTxPower is set to custom tx power selection. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_RADIO_TX_POWER_SET, uint32_t, sd_ant_channel_radio_tx_power_set (uint8_t ucChannel, uint8_t ucTxPower, uint8_t ucCustomTxPower)); - -/** @brief This function sets the sensitivity threshold for acquisition on a searching channel. One time set. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number. - * @param[in] ucProxThreshold is an unsigned char (1 octet) denoting the minimum RSSI threshold required for acquisition during a search. See Radio Proximity Search Threshold in ant_parameters.h - * @param[in] ucCustomProxThreshold is an unsigned char (1 octet) denoting the custom minimum RSSI threshold for acquisition during a search. Only applicable if ucProxThreshold is set to custom proximity selection. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_PROX_SEARCH_SET, uint32_t, sd_ant_prox_search_set (uint8_t ucChannel, uint8_t ucProxThreshold, uint8_t ucCustomProxThreshold)); - -/********************** CONFIGURATION APIS ********************************/ - -/** @brief This function sets the channel period. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set the period to. - * @param[in] usPeriod is an unsigned short (2 octets) denoting the period in 32 kHz counts (usPeriod/32768 s). - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_PERIOD_SET, uint32_t, sd_ant_channel_period_set (uint8_t ucChannel, uint16_t usPeriod)); - -/** @brief This function returns the current channel period. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pusPeriod is the pointer to an unsigned short (2 octets) where the channel period will be stored. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_PERIOD_GET, uint32_t, sd_ant_channel_period_get (uint8_t ucChannel, uint16_t *pusPeriod)); - -/** @brief This function sets the channel ID. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set. - * @param[in] usDeviceNumber is an unsigned short (2 octets) denoting the device number. - * @param[in] ucDeviceType is an unsigned char (1 octet) denoting the device type. - * @param[in] ucTransmitType is an unsigned char (1 octet) denoting the transmission type. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_ID_SET, uint32_t, sd_ant_channel_id_set (uint8_t ucChannel, uint16_t usDeviceNumber, uint8_t ucDeviceType, uint8_t ucTransmitType)); - -/** @brief This function returns the current Channel ID of a channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pusDeviceNumber is the pointer to an unsigned short (2 octets) where the device number will be stored. - * @param[out] pucDeviceType is the pointer to an unsigned char (1 octet) where the device type will be stored. - * @param[out] pucTransmitType is the pointer to an unsigned char (1 octet) where the transmit type will be stored. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_ID_GET, uint32_t, sd_ant_channel_id_get (uint8_t ucChannel, uint16_t *pusDeviceNumber, uint8_t *pucDeviceType, uint8_t *pucTransmitType)); - -/** @brief This function sets the searching waveform value of an ANT Channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set. - * @param[in] usWaveform is an unsigned short (2 octets) denoting the channel waveform period (usWaveform/32768 s). Default = 316. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_SEARCH_WAVEFORM_SET, uint32_t, sd_ant_search_waveform_set (uint8_t ucChannel, uint16_t usWaveform)); - -/** @brief This function sets the receive channel search timeout. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set. - * @param[in] ucTimeout is an unsigned char (1 octet) denoting the timeout value in 2.5 second increments. Default = 10 (25s). - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_RX_SEARCH_TIMEOUT_SET, uint32_t, sd_ant_channel_rx_search_timeout_set (uint8_t ucChannel, uint8_t ucTimeout)); - -/** @brief This function sets the channel's search priority. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set. - * @param[in] ucSearchPriority is an unsigned char (1 octet) denoting the search priority value. 0 to 7 (Default = 0). - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET, uint32_t, sd_ant_search_channel_priority_set (uint8_t ucChannel, uint8_t ucSearchPriority)); - -/** @brief This function sets the search cycle number of separate searching channels for active search time sharing. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to configure. - * @param[in] ucCycles is an unsigned char (1 octet) denoting the number of cycles to set. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET, uint32_t, sd_ant_active_search_sharing_cycles_set (uint8_t ucChannel, uint8_t ucCycles)); - -/** @brief This function returns the search sharing cycles number of the specified searching channel for active search time sharing. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pucCycles is the pointer to an unsigned char (1 octet) where the cycle value will be stored. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET, uint32_t, sd_ant_active_search_sharing_cycles_get (uint8_t ucChannel, uint8_t *pucCycles)); - -/** @brief This function sets the low priority search timeout value of a channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set. - * @param[in] ucTimeout is an unsigned char (1 octet) denoting the timeout value in 2.5 seconds increments. Default = 2 (5s). - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET, uint32_t, sd_ant_channel_low_priority_rx_search_timeout_set (uint8_t ucChannel, uint8_t ucTimeout)); - -/** @brief This function sets the advanced burst configuration. Configuration structure is as follows: - * Required Byte0 = 0-Disable, 1-Enable. See Advanced Burst Configuration Defines in ant_parameters.h. - * Required Byte1 = RF payload size. See Advanced Burst Configuration Defines in ant_parameters.h. - * Required Byte2 = Required advanced burst modes. See Advanced Burst Configuration Defines in ant_parameters.h. - * Required Byte3 = 0, Reserved - * Required Byte4 = 0, Reserved - * Required Byte5 = Optional advanced burst modes. See Advanced Burst Configuration Defines in ant_parameters.h. - * Required Byte6 = 0, Reserved - * Required Byte7 = 0, Reserved - * Optional Byte8 = Advanced burst stalling count config LSB. Typical is 3210 (~10s of stalling) where each count represents ~3ms of stalling. - * Optional Byte9 = Advanced burst stalling count config MSB. - * Optional Byte10 = Advanced burst retry count cycle extension. Typical is 3 (15 retries) where each count cycles represents 5 retries. - * - * @param[in] aucConfig is a buffer containing the advanced burst configuration to be set (as stated above). - * @param[in] ucSize is an unsigned char (1 octet) denoting the size of the configuration parameter buffer. Minimum config set is 8 octets, maximum is 11 octets. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_ADV_BURST_CONFIG_SET, uint32_t, sd_ant_adv_burst_config_set (uint8_t *aucConfig, uint8_t ucSize)); - -/** @brief This function gets the advance burst configuration and supported capabilities. - * Returned structure is as follows for configuration: - * Byte0 = RF payload size. See Advanced Burst Configuration Defines in ant_parameters.h. - * Byte1 = Required advanced burst modes. See Advanced Burst Configuration Defines in ant_parameters.h. - * Byte2 = 0, Reserved - * Byte3 = 0, Reserved - * Byte4 = Optional advanced burst modes. See Advanced Burst Configuration Defines in ant_parameters.h. - * Byte5 = 0, Reserved - * Byte6 = 0, Reserved - * Byte7 = Advanced burst stalling count config LSB. Each count represents ~3ms of stalling. - * Byte8 = Advanced burst stalling count config MSB - * Byte9 = Advanced burst retry count cycle extension. Each count cycle represents 5 retries. - * - * Returned structure is as follows for capabilities: - * Byte0 = Supported RF payload size. See Advanced Burst Configuration Defines in ant_parameters.h. - * Byte1 = Supported burst configurations. See Advanced Burst Configuration Defines in ant_parameters.h. - * Byte2 = 0, Reserved - * Byte3 = 0, Reserved - * - * @param[in] ucRequestType is an unsigned char (1 octet) denoting the type of request. 1 = configuration, 0 = capability. - * @param[out] aucConfig is the pointer to the buffer where the configuration/capabilities will be read to. The array should be at least 10 octets - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_ADV_BURST_CONFIG_GET, uint32_t, sd_ant_adv_burst_config_get (uint8_t ucRequestType, uint8_t *aucConfig)); - -/** @brief This function sets the ANT Messaging Library Configuration used by Extended messaging. - * - * @param[in] ucANTLibConfig is an unsigned char (1 octet) denoting the ANT lib config bit flags. See ANT Library Config in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_LIB_CONFIG_SET, uint32_t, sd_ant_lib_config_set (uint8_t ucANTLibConfig)); - -/** @brief This function clears the ANT Messaging Library Configuration. - * - * @param[in] ucANTLibConfig is an unsigned char (1 octet) denoting the ANT lib Config bit(s) to clear. See ANT Library Config in ant_parameters.h. - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_LIB_CONFIG_CLEAR, uint32_t, sd_ant_lib_config_clear (uint8_t ucANTLibConfig)); - -/** @brief This function returns current ANT Messaging Library Configuration. - * - * @param[out] pucANTLibConfig is the pointer to an unsigned char (1 octet) where the bit flags will be stored. See ANT Library Config in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_LIB_CONFIG_GET, uint32_t, sd_ant_lib_config_get (uint8_t *pucANTLibConfig)); - -/** @brief This function is used to add a Device ID to an include or exclude list. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to add the list entry to. - * @param[in] aucDevId is the pointer to the buffer (4 octets) containing device ID information with the following format: - * Byte0 = DeviceNumber_LSB - * Byte1 = DeviceNumber_MSB - * Byte2 = DeviceType - * Byte3 = TransType - * @param[in] ucListIndex is an unsigned char (1 octet) denoting the index where the specified Channel ID is to be placed in the list (0-3). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_INVALID_LIST_ID - */ -SVCALL(SVC_ANT_ID_LIST_ADD, uint32_t, sd_ant_id_list_add (uint8_t ucChannel, uint8_t *aucDevId, uint8_t ucListIndex)); - -/** @brief This function is used to configure the device ID list as include or exclude as well as the number of IDs to compare against. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number of the device ID list. - * @param[in] ucIDListSize is an unsigned char (1 octet) denoting the size of the inclusion or exclusion list (0-4). - * @param[in] ucIncExcFlag is an unsigned char (1 octet) denoting the type of list as Include(0) or Exclude(1) - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_INVALID_LIST_ID - */ -SVCALL(SVC_ANT_ID_LIST_CONFIG, uint32_t, sd_ant_id_list_config (uint8_t ucChannel, uint8_t ucIDListSize, uint8_t ucIncExcFlag)); - -/** @brief This function populates the frequency hop table list. This table is used when frequency hopping is enabled on a channel via extended assignment bit. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to set the frequency hop table list. - * @param[in] ucFreq0 is an unsigned char (1 octet) denoting the offset from 2400MHz of the 1st frequency hop value. - * @param[in] ucFreq1 is an unsigned char (1 octet) denoting the offset from 2400MHz of the 2nd frequency hop value. - * @param[in] ucFreq2 is an unsigned char (1 octet) denoting the offset from 2400MHz of the 3rd frequency hop value. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_AUTO_FREQ_HOP_TABLE_SET, uint32_t, sd_ant_auto_freq_hop_table_set (uint8_t ucChannel, uint8_t ucFreq0, uint8_t ucFreq1, uint8_t ucFreq2)); - -/** @brief This function is used to specify filter configuration for channel event message generation. - * - * @param[in] usFilter is an unsigned short (2 octets) denoting the filter configuration bitfield. See Event Filtering in ant_parameters.h. - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_EVENT_FILTERING_SET, uint32_t, sd_ant_event_filtering_set (uint16_t usFilter)); - -/** @brief This function is used to retrieve the filter configuration for channel event message generation. - * - * @param[out] pusFilter is the pointer to an unsigned short (2 octets) where the filter configuration will be stored. See Event Filtering in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_EVENT_FILTERING_GET, uint32_t, sd_ant_event_filtering_get (uint16_t *pusFilter)); - -/*************************** STATUS APIS **********************************/ - -/** @brief This function gets the ANT activity status. - * - * @param[out] pbAntActive is the pointer to an unsigned char (1 octet) where the ANT activity value will be stored. 1 = active, 0 = otherwise. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_ACTIVE, uint32_t, sd_ant_active (uint8_t *pbAntActive)); - -/** @brief This function gets the status if the channel is in progress. - * - * @param[out] pbChannelInProgress is the pointer to an unsigned char (1 octet) where the result will be stored. 1 = in progress, 0 = otherwise. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_CHANNEL_IN_PROGRESS, uint32_t, sd_ant_channel_in_progress (uint8_t *pbChannelInProgress)); - -/** @brief This function gets a specific channel's status. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pucStatus is the pointer to an unsigned char (1 octet) where the channel status will be stored. See Channel Status in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CHANNEL_STATUS_GET, uint32_t, sd_ant_channel_status_get (uint8_t ucChannel, uint8_t *pucStatus)); - -/** @brief This function determines if there is a pending transmission on a specific channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel number to query. - * @param[out] pucPending is the pointer to an unsigned char (1 octet) where the pending result will be stored. 1 = pending, 0 = otherwise. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_PENDING_TRANSMIT, uint32_t, sd_ant_pending_transmit (uint8_t ucChannel, uint8_t *pucPending)); - -/*************************** TEST APIS **********************************/ - -/** @brief This function initialize the stack to get ready for a continuous wave transmission test. - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_INIT_CW_TEST_MODE, uint32_t, sd_ant_cw_test_mode_init (void)); - -/** @brief This function starts a continuous wave test mode transmission. - * - * @param[in] ucRadioFreq is an unsigned char (1 octet) denoting the radio frequency offset from 2400MHz for continuous wave mode. (eg. 2466MHz, ucRadioFreq = 66). - * @param[in] ucTxPower is an unsigned char (1 octet) denoting the ANT transmit power index for continuous wave mode. See Radio TX Power Definitions in ant_parameters.h - * @param[in] ucCustomTxPower is an unsigned char (1 octet) denoting the custom nRF transmit power as defined in nrf51_bitfields.h. Only applicable if ucTxPower is set to custom tx power selection. - * @param[in] ucMode is an unsigned char (1 octet) denoting test mode type where 0 = cw tx carrier transmission, 1 = cw tx modulated transmission - * - * @return ::NRF_SUCCESS - */ -SVCALL(SVC_ANT_CW_TEST_MODE, uint32_t, sd_ant_cw_test_mode (uint8_t ucRadioFreq, uint8_t ucTxPower, uint8_t ucCustomTxPower, uint8_t ucMode)); - -/** @brief This function gets the version string of the ANT stack. - * - * @param[out] aucVersion is the pointer to the buffer where the version string will be copied, the array should be at least 11 octets. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_VERSION, uint32_t, sd_ant_version_get (uint8_t* aucVersion)); - -/** @brief This function gets the capabilities of the stack. - * - * @param[out] aucCapabilities is the pointer to the buffer where the capabilities message will be copied, the array should be at least 8 octets. - * Byte0 = Maximum supported ANT channels - * Byte1 = Maximum supported ANT networks - * Byte2 = CAPABILITIES_STANDARD. See Standard capabilities defines in ant_parameters.h - * Byte3 = CAPABILITIES_ADVANCED. See Advanced capabilities defines in ant_parameters.h - * Byte4 = CAPABILITIES_ADVANCED_2. See Advanced capabilities 2 defines in ant_parameters.h - * Byte5 = Maximum support ANT data channels (only applicable for SensRcore support) - * Byte6 = CAPABILITIES_ADVANCED_3. See Advanced capabilities 3 defines in ant_parameters.h - * Byte7 = CAPABILITIES_ADVANCED_4. Advanced capabilities 4 defines in ant_parameters.h - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_CAPABILITIES, uint32_t, sd_ant_capabilities_get (uint8_t* aucCapabilities)); - -/*********************** MORE DATA APIS ****************************************/ - -/** @brief This function assigns a wait variable to the the burst handler. When the input buffer is locked by the handler the wait flag is set to 1. When the - * input buffer is unlocked, the wait flag is set to 0. When a wait flag is assigned, EVENT_TRANSFER_NEXT_DATA_BLOCK events will not - * be generated until the wait flag unassigned. The wait flag should be declared as a static variable. - * - * @param[in] pucWaitFlag is the pointer to a static unsigned char (1 octet) where the status of the burst handler will be updated. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - */ -SVCALL(SVC_ANT_BURST_HANDLER_WAIT_FLAG_ENABLE, uint32_t, sd_ant_burst_handler_wait_flag_enable (uint8_t* pucWaitFlag)); - -/** @brief This function unassigns any previously assigned wait variable from the burst handler. The burst handler returns to the default method in generating - * EVENT_TRANSFER_NEXT_DATA_BLOCK to indicate input buffer unlock. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - */ -SVCALL(SVC_ANT_BURST_HANDLER_WAIT_FLAG_DISABLE, uint32_t, sd_ant_burst_handler_wait_flag_disable (void)); - -/********************** MORE CONFIGURATION API ********************************/ - -/** @brief This function is used to assign a selective data update (SDU) mask (8 octets) to an identifier, ucMask. - * - * @param[in] ucMask is an unsigned char (1 octet) denoting the index representing the SDU data mask. - * @param[in] aucMask is a buffer (8 octets) containing the SDU mask to be assigned to ucMask. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_SDU_MASK_SET, uint32_t, sd_ant_sdu_mask_set (uint8_t ucMask, uint8_t *aucMask)); - -/** @brief This function returns the selective data update (SDU) mask (8 octets) from the specified identifier, ucMask. - * - * @param[in] ucMask is an unsigned char (1 octet) denoting the index representing the SDU data mask. - * @param[out] aucMask is a pointer to the buffer where the SDU data mask will be copied, the array should be at least 8 octects. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_SDU_MASK_GET, uint32_t, sd_ant_sdu_mask_get (uint8_t ucMask, uint8_t *aucMask)); - -/** @brief This function assigns a SDU mask configuration to a particular channel. The configuration specifies the mask identifier and the type of rx data in which the mask should be applied to. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel in which the SDU mask configuration is to be applied to. - * @param[in] ucMaskConfig is an unsigned char (1 octet) denoting SDU mask configuration. See Selective Data Update Mask Configuration Defines in ant_parameters.h. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_SDU_MASK_CONFIG, uint32_t, sd_ant_sdu_mask_config (uint8_t ucChannel, uint8_t ucMaskConfig)); - -/** @brief This function enables/disables 128-bit AES encryption mode to the specified channel. Advanced burst must be enabled beforehand to enable encrypted channel. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel in which encryption mode is set. - * @param[in] ucEnable is an unsigned char (1 octet) denoting the encryption mode. See Encrypted Channel Defines in ant_parameters.h. - * @param[in] ucKeyNum is an unsigned char (1 octet) denoting the key index of the 128-bit key to be used for encryption. The key index range is bound by the number of - encrypted channels configured by sd_ant_enable(). If sd_ant_enable() is not used then by default ucKeyNum is 0. Range is [0 to (num encrypted channels - 1)], - if 1 or more encrypted channels are configured. - * @param[in] ucDecimationRate is an unsigned char (1 octet) denoting the decimate rate to apply for encrypted slave channel. Must be > 0. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_INVALID_SCAN_TX_CHANNEL - * ::NRF_ANT_ERROR_CHANNEL_NOT_OPENED - * ::NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR - * ::NRF_ANT_ERROR_TRANSFER_IN_PROGRESS - * ::NRF_ANT_ERROR_TRANSFER_IN_ERROR - * ::NRF_ANT_ERROR_MESSAGE_SIZE_EXCEEDS_LIMIT - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - * ::NRF_ANT_ERROR_TRANSFER_BUSY - */ -SVCALL(SVC_ANT_CRYPTO_CHANNEL_ENABLE, uint32_t, sd_ant_crypto_channel_enable (uint8_t ucChannel, uint8_t ucEnable, uint8_t ucKeyNum, uint8_t ucDecimationRate)); - -/** @brief This function assigns a 128-bit AES encryption key to a key index. - * - * @param[in] ucKeyNum is an unsigned char (1 octet) denoting the key index for assignment. The key index range is bound by the number of encrypted channels configured - by sd_ant_enable(). If sd_ant_enable() is not used then by default ucKeyNum is 0. Range is [0 to (num encrypted channels - 1)], if 1 or more - encrypted channels are configured. - * @param[in] aucKey is a buffer (16 octets) containing the 128-bit AES key to be assigned to the key index. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CRYPTO_KEY_SET, uint32_t, sd_ant_crypto_key_set (uint8_t ucKeyNum, uint8_t *aucKey)); - - /** @brief This function sets specific information to be exchanged between the channel master and slave during encryption channel set-up/negotiation. - * - * @param[in] ucType is an unsigned char (1 octet) denoting the type of information being set. See Encrypted Channel Defines in ant_parameters.h. - * @param[in] aucInfo is a buffer containing the information being set (4 octets for ID, 19 octets for custom user data). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - */ -SVCALL(SVC_ANT_CRYPTO_INFO_SET, uint32_t, sd_ant_crypto_info_set (uint8_t ucType, uint8_t *aucInfo)); - - /** @brief This function retrieves specific information to be exchanged between the channel master and slave during encryption channel set-up/negotiation. - * - * @param[in] ucType is an unsigned char (1 octet) denoting the type of information being requested. See Encrypted Channel Defines in ant_parameters.h. - * @param[out] aucInfo is a pointer to a buffer in which the information retrieved will be copied to (1 octet for supported mode, 4 octets for ID, 19 octets for custom user data). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_CRYPTO_INFO_GET, uint32_t, sd_ant_crypto_info_get (uint8_t ucType, uint8_t *aucInfo)); - - /** @brief This function enables/disables event notifications to be generated to the application indicating the time to the next ANT radio activity exceeds the configured time threshold. - * Latency (delay in event notification being received and processed by application) must be taken into account if attempting to use this generated event to perform - * operations prior to the radio activity. Cannot be used if asynchronous tx channel is assigned or used. Please note that this only generates events for ANT radio activity. - * - * @param[in] ucMode is an unsigned char (1 octet) denoting the mode of event notification. See RFActive Notification Defines in ant_parameters.h. - * @param[in] usTimeThreshold is an unsigned short (2 octets) denoting the minimum time threshold (32 kHz counts (usTimeThreshold/32768 s)) before the next radio activity that will trigger generation of the event notification. - * - * @return ::NRF_SUCCESS - * ::NRF_ANT_ERROR_INVALID_PARAMETER_PROVIDED - * ::NRF_ANT_ERROR_CHANNEL_IN_WRONG_STATE - */ -SVCALL(SVC_ANT_RFACTIVE_NOTIFICATION_CONFIG_SET, uint32_t, sd_ant_rfactive_notification_config_set (uint8_t ucMode, uint16_t usTimeThreshold)); - - /** @brief This function retrieves the ANT rf active notification configuration - * - * @param[in] pucMode is a pointer to an unsigned char (1 octet) where the configured mode of event notification will be stored. - * @param[out] pusTimeThreshold is a pointer to an unsigned short (2 octets) where the configured time threhold value will be stored. Time threshold is in 32 kHz counts (usTimeThreshold/32768 s). - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_RFACTIVE_NOTIFICATION_CONFIG_GET, uint32_t, sd_ant_rfactive_notification_config_get (uint8_t *pucMode, uint16_t *pusTimeThreshold)); - - /** @brief This function sets ANT radio coexistence behaviour. Supported only if ANT is sharing radio HW concurrently with another wireless protocol. - * Configuration structure is as follows: - * Byte0 = Configuration enable bitfield - * bit0 - enable/disable tx/rx channel keep alive config (Byte4/5 & Byte6/7) - * bit1 - enable/disable tx/rx channel fixed interval priority config (Byte1) - * bit2 - enable/disable transfer keep alive config (Byte2) - * bit3 - enable/disable search channel fixed interval priority config (Byte3) - * else - reserved - * Byte1 = tx/rx channel fixed interval priority configuration - * Byte2 = transfer keep alive configuration - * Byte3 = search channel fixed interval priority configuration - * Byte4(LSB)/Byte5(MSB) = tx channel keep alive configuration - * Byte6(LSB)/Byte7(MSB) = rx channel keep alive configuration - * - * Advanced configuration structure is as follows: - * Byte0 = Configuration enable bitfield - * bit0 - enable/disable priority override config (Byte1) - * bit1-7 - reserved - * Byte1 = ANT priority override. 0 = low, 1 = normal(default), 2 = high, 3 = critical - * Byte2 = Reserved - * Byte3 = Reserved - * Byte4 = Reserved - * Byte5 = Reserved - * Byte6 = Reserved - * Byte7 = Reserved - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel for which the coexistence configuration is to be set. - * @param[in] aucCoexConfig is a buffer containing the coex configuration to be set. Must be 8 octet in size. Set as null for no change. - * @param[in] aucAdvCoexConfig is a buffer containing the advanced coex configuration to be set. Must be 8 octet in size. Set as null for no change. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_COEX_CONFIG_SET, uint32_t, sd_ant_coex_config_set (uint8_t ucChannel, uint8_t *aucCoexConfig, uint8_t *aucAdvCoexConfig)); - - /** @brief This function retrieves the configured ANT radio coexistence behaviour as described in ant_coex_config_set. - * - * @param[in] ucChannel is an unsigned char (1 octet) denoting the channel to query. - * @param[out] aucCoexConfig is the pointer to a buffer where the coexistence configuration will be stored. Must be at least 8 octet in size. Set as null to ignore. - * @param[out] aucAdvCoexConfig is the pointer to a buffer where the advanced coexistence configuration will be stored. Must be at least 8 octet in size. Set as null to ignore. - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_COEX_CONFIG_GET, uint32_t, sd_ant_coex_config_get (uint8_t ucChannel, uint8_t *aucCoexConfig, uint8_t *aucAdvCoexConfig)); - - /** @brief This function is used to specify the total number of ANT channels, number of encrypted channels (subset of total ANT channels) and transmit burst queue size to be supported - * by the ANT stack. Upon enabling the SoftDevice successfully, the ANT stack defaults to supporting 1 ANT channel (encryption capable) and a 64 byte transmit burst buffer. If additional - * channels are needed and/or more encrypted channels are needed and/or larger tx burst buffer size is needed, then the desired configuration can be specified to the SoftDevice - * using this function. In this case, a static RAM buffer (of minimum size defined by ANT_ENABLE_GET_REQUIRED_SPACE) must be supplied by the application to be used by the ANT SoftDevice stack. - * - * Notes: - If used, function should be called immediately after sd_softdevice_enable() and before any ANT related SVC calls. - * - Using sd_ant_stack_reset() will not reset ANT stack channel allocation configuration. It will be maintained. - * - Disabling the SoftDevice and then re-enabling the SoFtDevice will reset channel allocation to default. Any previously supplied memory buffer by the application will not be used. - * - * - * @param[in] pstChannelEnable is a pointer to ANT_ENABLE structure. - * where ucTotalNumberOfChannels is an unsigned char (1 octet) denoting the total number of ANT channels desired (1 to MAX_ANT_CHANNELS, defined in ant_parameters.h) - * where ucTotalNumberOfEncryptedChannels is an unsigned char (1 octet) denoting the total number of ANT channels (0 to ucTotalNumberOfChannels) that support encryption - * where pucMemoryBlockStartLocation is the pointer to an application supplied buffer to be used by the ANT SoftDevice stack. - * where usMemoryBlockByteSize is an unsigned short (2 octet) denoting the size of the given memory block (pucMemoryBlockStartLocation). The defined ANT_ENABLE_GET_REQUIRED_SPACE - * macro (see ant_parameters.h) should be used to determine the minimum buffer size requirement - * - * @return ::NRF_SUCCESS - * ::NRF_ERROR_INVALID_PARAM - */ -SVCALL(SVC_ANT_ENABLE, uint32_t, sd_ant_enable(ANT_ENABLE * const pstChannelEnable)); - -/** @brief Extended0 ANT SVCs. Access extended SVC functions via ucExtID -* -* @param[in] ucExtID is the extended ID defined by SD_ANT_EXT0_ID_ -* @param[in,out] pvArg0 is first argument to extended ANT SVC function specified by ucExtID -* @param[in,out] pvArg1 is second argument to extended ANT SVC function specified by ucExtID -* @param[in,out] pvArg2 is third argument to extended ANT SVC function specified by ucExtID -* -* @return Return value(s) of extended ANT SVC function specified by ucExtID -*/ -SVCALL(SVC_ANT_EXTENDED0, uint32_t, sd_ant_extended0 (uint8_t ucExtID, void *pvArg0, void *pvArg1, void *pvArg2)); - -/** @brief This function configures CPU wake on ANT RF activity behaviour. CPU is woken up via generation of SD_EVENT_IRQn interrupt upon the start of specified RF activity. In -* order to wakeup in the event that SD_EVENT_IRQn is disabled, the SEVONPEND flag has to be set in the Cortex-M0 System Control Register (SCR). CPU is dissallowed from -* entering low power state when calling sd_app_event_wait() for the duration of the RF activity. The intention of this function is to allow/disallow sudden shifts in -* current consumption during RF transmission/ RF reception window which may impact RF performance. When enabled there is a slight increase in average current consumption for -* ANT activities. -* -* @param[in] ucExtID = SD_ANT_EXT0_ID_WAKEON_RF_ACTIVITY_CONFIG_SET -* @param[in] pvArg0 is a pointer to unsigned char (1 octet) denoting the CPU wakeup configuration. See Wake On RF Activity Defines in ant_parameters.h. -* @param[in,out] pvArg1 is unused. Set to NULL. -* @param[in,out] pvArg2 is unused. Set to NULL. -* -* @return ::NRF_SUCCESS -* ::NRF_ERROR_INVALID_PARAM -*/ -#define SD_ANT_EXT0_ID_WAKEON_RF_ACTIVITY_CONFIG_SET 0x00 - -/** @brief This function retrieves the configured CPU wake on ANT RF activity behaviour. -* -* @param[in] ucExtID = SD_ANT_EXT0_ID_WAKEON_RF_ACTIVITY_CONFIG_GET -* @param[out] pvArg0 is a pointer to unsigned char (1 octet) denoting where the CPU wakeup configuration will be stored. -* @param[in,out] pvArg1 is unused. Set to NULL. -* @param[in,out] pvArg2 is unused. Set to NULL. -* -* @return ::NRF_SUCCESS -* ::NRF_ERROR_INVALID_PARAM -*/ -#define SD_ANT_EXT0_ID_WAKEON_RF_ACTIVITY_CONFIG_GET 0x01 - -/** @brief This function enables or disables a feature for preventing long periods of consecutive multi-tracking channel collisions. This feature is -* enabled by default/upon stack reset. -* -* @param[in] ucExtID = SD_ANT_EXT0_ID_ENHANCED_CHANNEL_SPACING_SET -* @param[out] pvArg0 is a pointer to unsigned char (1 octet) denoting enable/disable control. See Enhanced Channel Spacing Defines in ant_parameters.h -* @param[in,out] pvArg1 is unused. Set to NULL. -* @param[in,out] pvArg2 is unused. Set to NULL. -* -* @return ::NRF_SUCCESS -* ::NRF_ERROR_INVALID_PARAM -*/ -#define SD_ANT_EXT0_ID_ENHANCED_CHANNEL_SPACING_SET 0x02 - - -#endif // ANT_INTERFACE_H__ - -/** - @} - @} - @} - */ diff --git a/components/softdevice/s310/headers/ant_parameters.h b/components/softdevice/s310/headers/ant_parameters.h deleted file mode 100644 index d7f38e2..0000000 --- a/components/softdevice/s310/headers/ant_parameters.h +++ /dev/null @@ -1,725 +0,0 @@ -/* - * Dynastream Innovations Inc. - * Cochrane, AB, CANADA - * - * Copyright (c) 2012 Dynastream Innovations Inc. - * THIS SOFTWARE IS AN EXAMPLE USAGE OF THE ANT PROTOCOL MODULE. - * IT MAY BE USED, MODIFIED and DISTRIBUTED ONLY WITH THE - * APPROPRIATE LICENSE AGREEMENT. - */ - -#ifndef ANTDEFINES_H -#define ANTDEFINES_H - -#include - -/** - @defgroup ant_parameters ANT Stack Parameters - @{ - @ingroup ant_interface -*/ - -////////////////////////////////////////////// -/** @name ANT Channel Init Definitions -@{ */ -////////////////////////////////////////////// -#define MAX_ANT_CHANNELS ((uint8_t)15) -#define SIZE_OF_NONENCRYPTED_ANT_CHANNEL ((uint8_t)88) -#define SIZE_OF_ENCRYPTED_ANT_CHANNEL ((uint8_t)21) -#define MIN_ANT_TX_BURST_QUEUE_SIZE ((uint8_t)64) - -#define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) ) - -#define GET_TX_BURST_QUEUE_SIZE(requestedSize) \ - (requestedSize < MIN_ANT_TX_BURST_QUEUE_SIZE ? MIN_ANT_TX_BURST_QUEUE_SIZE : (IS_POWER_OF_TWO(requestedSize) ? requestedSize : MIN_ANT_TX_BURST_QUEUE_SIZE)) - -#define ANT_ENABLE_GET_REQUIRED_SPACE_MORE_THAN_TWO_CH(ucTotalNumberOfChannels, ucNumberOfEncryptedChannels, usTxQueueByteSize) \ - ((ucTotalNumberOfChannels - 2) * SIZE_OF_NONENCRYPTED_ANT_CHANNEL) + (ucNumberOfEncryptedChannels * SIZE_OF_ENCRYPTED_ANT_CHANNEL) + GET_TX_BURST_QUEUE_SIZE(usTxQueueByteSize) - -#define ANT_ENABLE_GET_REQUIRED_SPACE_LESS_THAN_OR_EQ_TWO_CH(ucNumberOfEncryptedChannels, usTxQueueByteSize) \ - (ucNumberOfEncryptedChannels * SIZE_OF_ENCRYPTED_ANT_CHANNEL) + GET_TX_BURST_QUEUE_SIZE(usTxQueueByteSize) - -#define ANT_ENABLE_GET_REQUIRED_SPACE(ucTotalNumberOfChannels, ucNumberOfEncryptedChannels, usTxQueueByteSize) \ - ucTotalNumberOfChannels > 2 ? \ - ANT_ENABLE_GET_REQUIRED_SPACE_MORE_THAN_TWO_CH(ucTotalNumberOfChannels, ucNumberOfEncryptedChannels, usTxQueueByteSize) : \ - ANT_ENABLE_GET_REQUIRED_SPACE_LESS_THAN_OR_EQ_TWO_CH(ucNumberOfEncryptedChannels, usTxQueueByteSize) -/** @} */ - -////////////////////////////////////////////// -/** @brief ANT Clock Definition */ -////////////////////////////////////////////// -#define ANT_CLOCK_FREQUENCY ((uint32_t)32768) ///< ANT system clock frequency. - -////////////////////////////////////////////// -/** @brief ANT Message Payload Size */ -////////////////////////////////////////////// -#define ANT_STANDARD_DATA_PAYLOAD_SIZE ((uint8_t)8) ///< Standard data payload size - -////////////////////////////////////////////// -/** @name Radio TX Power Definitions -@{ */ -////////////////////////////////////////////// -#define RADIO_TX_POWER_LVL_CUSTOM ((uint8_t)0x80) ///< Custom tx power selection -#define RADIO_TX_POWER_LVL_0 ((uint8_t)0x00) ///< Lowest ANT Tx power level setting. (-20dBm). -#define RADIO_TX_POWER_LVL_1 ((uint8_t)0x01) ///< ANT Tx power > Lvl 0. (-12dBm) -#define RADIO_TX_POWER_LVL_2 ((uint8_t)0x02) ///< ANT Tx power > Lvl 1. (-4dBm) -#define RADIO_TX_POWER_LVL_3 ((uint8_t)0x03) ///< ANT Tx power > Lvl 2. Default tx power level. (0dBm) -#define RADIO_TX_POWER_LVL_4 ((uint8_t)0x04) ///< ANT Tx power > Lvl 3. (+4dBm) -/** @} */ - -////////////////////////////////////////////// -/** @name Radio Proximity Search Threshold -@{ */ -////////////////////////////////////////////// -#define PROXIMITY_THRESHOLD_CUSTOM ((uint8_t)0x80) ///< Custom proximity search selection. -#define PROXIMITY_THRESHOLD_OFF ((uint8_t)0x00) ///< Disable proximity search detection. -#define PROXIMITY_THRESHOLD_1 ((uint8_t)0x01) ///< Proximity search detection radius > preset threshold (~ -44dBm on nRF51) -#define PROXIMITY_THRESHOLD_2 ((uint8_t)0x02) ///< Proximity search detection radius > preset threshold (~ -48dBm on nRF51). -#define PROXIMITY_THRESHOLD_3 ((uint8_t)0x03) ///< Proximity search detection radius > preset threshold (~ -52dBm on nRF51). -#define PROXIMITY_THRESHOLD_4 ((uint8_t)0x04) ///< Proximity search detection radius > preset threshold (~ -56dBm on nRF51). -#define PROXIMITY_THRESHOLD_5 ((uint8_t)0x05) ///< Proximity search detection radius > preset threshold (~ -60dBm on nRF51). -#define PROXIMITY_THRESHOLD_6 ((uint8_t)0x06) ///< Proximity search detection radius > preset threshold (~ -64dBm on nRF51). -#define PROXIMITY_THRESHOLD_7 ((uint8_t)0x07) ///< Proximity search detection radius > preset threshold (~ -68dBm on nRF51). -#define PROXIMITY_THRESHOLD_8 ((uint8_t)0x08) ///< Proximity search detection radius > preset threshold (~ -72dBm on nRF51). -#define PROXIMITY_THRESHOLD_9 ((uint8_t)0x09) ///< Proximity search detection radius > preset threshold (~ -76dBm on nRF51). -#define PROXIMITY_THRESHOLD_10 ((uint8_t)0x0A) ///< Proximity search detection radius > preset threshold (~ -80dBm on nRF51). -/** @} */ - -////////////////////////////////////////////// -/** @name Assign Channel Parameters -@{ */ -////////////////////////////////////////////// -#define PARAMETER_RX_NOT_TX ((uint8_t)0x00) ///< Bitfield for slave channel. -#define PARAMETER_TX_NOT_RX ((uint8_t)0x10) ///< Bitfield for master channel. -#define PARAMETER_SHARED_CHANNEL ((uint8_t)0x20) ///< Bitfield for enabling shared channel mode for master or slave channel. -#define PARAMETER_NO_TX_GUARD_BAND ((uint8_t)0x40) ///< Bitfield for enabling tx only mode for master channel. -#define PARAMETER_RX_ONLY ((uint8_t)0x40) ///< Bitfield for enabling rx only mode for slave channel. -/** @} */ - -////////////////////////////////////////////// -/** @name Extended Assign Channel Parameters -@{ */ -////////////////////////////////////////////// -#define EXT_PARAM_ALWAYS_SEARCH ((uint8_t)0x01) ///< Bitfield for enabling background searching behaviour. -#define EXT_PARAM_IGNORE_TRANSMISSION_TYPE ((uint8_t)0x02) ///< Bitfield for enabling ignore transmission type behaviour. -#define EXT_PARAM_FREQUENCY_AGILITY ((uint8_t)0x04) ///< Bitfield for enabling frequency agility behaviour. -#define EXT_PARAM_AUTO_SHARED_SLAVE ((uint8_t)0x08) ///< Auto shared channel. -#define EXT_PARAM_FAST_INITIATION_MODE ((uint8_t)0x10) ///< Channel fast initiation mode. -#define EXT_PARAM_ASYNC_TX_MODE ((uint8_t)0x20) ///< Async transmit channel. -/** @} */ - -////////////////////////////////////////////// -/** @name Assign Channel Types -@{ */ -////////////////////////////////////////////// -#define CHANNEL_TYPE_SLAVE ((uint8_t) 0x00) ///< Slave channel (PARAMETER_RX_NOT_TX). -#define CHANNEL_TYPE_MASTER ((uint8_t) 0x10) ///< Master channel (PARAMETER_TX_NOT_RX). -#define CHANNEL_TYPE_SLAVE_RX_ONLY ((uint8_t) 0x40) ///< Slave rx only channel (PARAMETER_RX_NOT_TX | PARAMETER_RX_ONLY). -#define CHANNEL_TYPE_MASTER_TX_ONLY ((uint8_t) 0x50) ///< Master tx only channel (PARAMETER_TX_NOT_RX | PARAMETER_NO_TX_GUARD_BAND). -#define CHANNEL_TYPE_SHARED_SLAVE ((uint8_t) 0x20) ///< Shared slave channel (PARAMETER_RX_NOT_TX | PARAMETER_SHARED_CHANNEL). -#define CHANNEL_TYPE_SHARED_MASTER ((uint8_t) 0x30) ///< Shared master channel (PARAMETER_TX_NOT_RX | PARAMETER_SHARED_CHANNEL). -/** @} */ - -////////////////////////////////////////////// -/** @name Channel ID Definitions -@{ */ -////////////////////////////////////////////// -#define ANT_ID_SIZE ((uint8_t)4) ///< 4 octet channel ID -#define ANT_ID_TRANS_TYPE_OFFSET ((uint8_t)3) ///< Transmission type offset in channel ID -#define ANT_ID_DEVICE_TYPE_OFFSET ((uint8_t)2) ///< Device type offset in channel ID -#define ANT_ID_DEVICE_NUMBER_HIGH_OFFSET ((uint8_t)1) ///< MSB Device number in channel ID -#define ANT_ID_DEVICE_NUMBER_LOW_OFFSET ((uint8_t)0) ///< LSB Device number in channel ID -#define ANT_ID_DEVICE_TYPE_PAIRING_FLAG ((uint8_t)0x80) ///< Pairing bit in device type field - -#define ANT_TRANS_TYPE_SHARED_ADDR_MASK ((uint8_t)0x03) ///< shared address mask in transmission type field -#define ANT_TRANS_TYPE_1_BYTE_SHARED_ADDRESS ((uint8_t)0x02) ///< 1 byte shared address field -#define ANT_TRANS_TYPE_2_BYTE_SHARED_ADDRESS ((uint8_t)0x03) ///< 2 byte shared address field -/** @} */ - -////////////////////////////////////////////// -/** @name Channel Status -@{ */ -////////////////////////////////////////////// -#define STATUS_CHANNEL_STATE_MASK ((uint8_t)0x03) ///< Channel state mask -#define STATUS_UNASSIGNED_CHANNEL ((uint8_t)0x00) ///< Indicates channel has not been assigned. -#define STATUS_ASSIGNED_CHANNEL ((uint8_t)0x01) ///< Indicates channel has been assigned. -#define STATUS_SEARCHING_CHANNEL ((uint8_t)0x02) ///< Indicates channel is active and in searching state. -#define STATUS_TRACKING_CHANNEL ((uint8_t)0x03) ///< Indicates channel is active and in tracking state. -/** @} */ - -////////////////////////////////////////////// -/** @name Standard capabilities defines -@{ */ -////////////////////////////////////////////// -#define CAPABILITIES_NO_RX_CHANNELS ((uint8_t)0x01) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no rx channel support. -#define CAPABILITIES_NO_TX_CHANNELS ((uint8_t)0x02) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no tx channel support. -#define CAPABILITIES_NO_RX_MESSAGES ((uint8_t)0x04) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no rx message support. -#define CAPABILITIES_NO_TX_MESSAGES ((uint8_t)0x08) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no tx message support. -#define CAPABILITIES_NO_ACKD_MESSAGES ((uint8_t)0x10) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no acknolwedged message support. -#define CAPABILITIES_NO_BURST_TRANSFER ((uint8_t)0x20) ///< Bitfield in CAPABILITIES_STANDARD byte indicating no burst transfer support. -/** @} */ - -////////////////////////////////////////////// -/** @name Advanced capabilities defines -@{ */ -////////////////////////////////////////////// -#define CAPABILITIES_NETWORK_ENABLED ((uint8_t)0x02) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating network support. -#define CAPABILITIES_SERIAL_NUMBER_ENABLED ((uint8_t)0x08) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating serial number support. -#define CAPABILITIES_PER_CHANNEL_TX_POWER_ENABLED ((uint8_t)0x10) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating per channel transmit power support. -#define CAPABILITIES_LOW_PRIORITY_SEARCH_ENABLED ((uint8_t)0x20) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating lower priority search support. -#define CAPABILITIES_SCRIPT_ENABLED ((uint8_t)0x40) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating scripting support. -#define CAPABILITIES_SEARCH_LIST_ENABLED ((uint8_t)0x80) ///< Bitfield in CAPABILITIES_ADVANCED byte indicating include/exclude list support. -/** @} */ - -////////////////////////////////////////////// -/** @name Advanced capabilities 2 defines -@{ */ -////////////////////////////////////////////// -#define CAPABILITIES_LED_ENABLED ((uint8_t)0x01) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating built-in LED support. -#define CAPABILITIES_EXT_MESSAGE_ENABLED ((uint8_t)0x02) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating extended messaging support. -#define CAPABILITIES_SCAN_MODE_ENABLED ((uint8_t)0x04) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating scanning mode support. -#define CAPABILITIES_RESERVED ((uint8_t)0x08) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte currently reserved for future use. -#define CAPABILITIES_PROX_SEARCH_ENABLED ((uint8_t)0x10) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating proximity search support. -#define CAPABILITIES_EXT_ASSIGN_ENABLED ((uint8_t)0x20) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating extended assign support. -#define CAPABILITIES_FS_ANTFS_ENABLED ((uint8_t)0x40) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating built-in FS/ANT-FS support -#define CAPABILITIES_FIT1_ENABLED ((uint8_t)0x80) ///< Bitfield in CAPABILITIES_ADVANCED_2 byte indicating FIT1 module support -/** @} */ - -////////////////////////////////////////////// -/** @name Advanced capabilities 3 defines -@{ */ -////////////////////////////////////////////// -#define CAPABILITIES_ADVANCED_BURST_ENABLED ((uint8_t)0x01) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating advanced burst support. -#define CAPABILITIES_EVENT_BUFFERING_ENABLED ((uint8_t)0x02) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating extended messaging support. -#define CAPABILITIES_EVENT_FILTERING_ENABLED ((uint8_t)0x04) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating event filtering support. -#define CAPABILITIES_HIGH_DUTY_SEARCH_MODE_ENABLED ((uint8_t)0x08) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating high duty search mode support. -#define CAPABILITIES_ACTIVE_SEARCH_SHARING_MODE_ENABLED ((uint8_t)0x10) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating active search sharing mode support. -#define CAPABILITIES_RADIO_COEX_CONFIG_ENABLED ((uint8_t)0x20) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating radio coexistence configuration support. -#define CAPABILITIES_SELECTIVE_DATA_UPDATE_ENABLED ((uint8_t)0x40) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating selective rx data update support. -#define CAPABILITIES_ENCRYPTED_CHANNEL_ENABLED ((uint8_t)0x80) ///< Bitfield in CAPABILITIES_ADVANCED_3 byte indicating encrypted channel support. -/** @} */ - -////////////////////////////////////////////// -/** @name Advanced capabilities 4 defines -@{ */ -////////////////////////////////////////////// -#define CAPABILITIES_RFACTIVE_NOTIFICATION_ENABLED ((uint8_t)0x01) ///< Bitfield in CAPABILITIES_ADVANCED_4 byte indicating rfactive notification support. -/** @} */ - - - -////////////////////////////////////////////// -/** @name Rx Burst Message Sequencing Defines -@{ */ -////////////////////////////////////////////// -#define CHANNEL_NUMBER_MASK ((uint8_t)0x1F) ///< Valid bitfields for channel number -#define SEQUENCE_NUMBER_MASK ((uint8_t)0xE0) ///< Valid bitfields for burst sequence -#define SEQUENCE_NUMBER_ROLLOVER ((uint8_t)0x60) ///< Sequence rollover -#define SEQUENCE_FIRST_MESSAGE ((uint8_t)0x00) ///< Sequence indicating first burst message -#define SEQUENCE_LAST_MESSAGE ((uint8_t)0x80) ///< Sequence indicating last burst message -#define SEQUENCE_NUMBER_INC ((uint8_t)0x20) ///< Incremental sequence value -/** @} */ - -////////////////////////////////////////////// -/** @name Tx Burst Handler Request Segment Defines -@{ */ -////////////////////////////////////////////// -#define BURST_SEGMENT_CONTINUE ((uint8_t)0x00) ///< Bitfield for indicating continuation of burst data segment (no starting or ending burst packet). -#define BURST_SEGMENT_START ((uint8_t)0x01) ///< Bitfield for indicating burst data segment containing starting burst packet. -#define BURST_SEGMENT_END ((uint8_t)0x02) ///< Bitfield for indicating burst data segment containing ending burst packet. -/** @} */ - -////////////////////////////////////////////// -/** @name ANT Library Config -@{ */ -////////////////////////////////////////////// -#define ANT_LIB_CONFIG_MASK_ALL ((uint8_t)0xFF) ///< libary configuration mask -#define ANT_LIB_CONFIG_RADIO_CONFIG_ALWAYS ((uint8_t)0x01) ///< Bitfield intended for platform specific configuration (unused) -#define ANT_LIB_CONFIG_MESG_OUT_INC_TIME_STAMP ((uint8_t)0x20) ///< Bitfield for enabling extended rx messages including ant time stamp field -#define ANT_LIB_CONFIG_MESG_OUT_INC_RSSI ((uint8_t)0x40) ///< Bitfield for enabling extended rx messages including RSSI measurement field -#define ANT_LIB_CONFIG_MESG_OUT_INC_DEVICE_ID ((uint8_t)0x80) ///< Bitfield for enabling extended rx messages including device ID field -/** @} */ - -////////////////////////////////////////////// -/** @name Extended Data Message Bitfield Definitions -@{ */ -////////////////////////////////////////////// -#define ANT_EXT_MESG_BITFIELD_DEVICE_ID ((uint8_t)0x80) ///< Bitfield for indicating device ID field present in extended data message after the extended message bitfield byte -#define ANT_EXT_MESG_BITFIELD_RSSI ((uint8_t)0x40) ///< Bitfield for indicating RSSI field present in extended data message after device id field (if present) -#define ANT_EXT_MESG_BITFIELD_TIME_STAMP ((uint8_t)0x20) ///< Bitfield for indicating timestamp field present in extended data message after rssi/agc field (if present) -#define ANT_EXT_MESG_BIFIELD_EXTENSION ((uint8_t)0x01) ///< Bitfield reserved -/** @} */ - -////////////////////////////////////////////// -/** @name RSSI Definitions in Extended Data Message -@{ */ -////////////////////////////////////////////// -#define RSSI_TYPE_AGC_EXT_MESG_FIELD_SIZE ((uint8_t)4) ///< Extended bitfield message size for AGC type RSSI measurement -#define RSSI_TYPE_DBM_EXT_MESG_FIELD_SIZE ((uint8_t)3) ///< Extended bitfield message size for DBM type RSSI measurement - -#define RSSI_TYPE_OFFSET ((uint8_t)0) ///< RSSI type offset in RSSI field in extended data message -#define RSSI_AGC_TYPE ((uint8_t)0x10) ///< RSSI type indicating support for AGC measurement -#define RSSI_DBM_TYPE ((uint8_t)0x20) ///< RSSI type indicating support for DBM measurement - -#define RSSI_TYPE_AGC_THRESHOLD_OFFSET ((uint8_t)1) ///< Offset of AGC value indicating above or below configured AGC threshold -#define RSSI_TYPE_AGC_REGISTER_LOW ((uint8_t)2) ///< Offset of LSB AGC threshold configuration in RSSI field -#define RSSI_TYPE_AGC_REGISTER_HIGH ((uint8_t)3) ///< Offset of MSB AGC threshold configuration in RSSI field - -#define RSSI_TYPE_DBM_VALUE ((uint8_t)1) ///< Offset of DBM value in RSSI field -#define RSSI_TYPE_DBM_SETTING ((uint8_t)2) ///< Offset of DBM threshold configuration in RSSI field -/** @} */ - -////////////////////////////////////////////// -/** @name Reset/Startup Mesg Codes -@{ */ -////////////////////////////////////////////// -#define RESET_FLAGS_MASK ((uint8_t)0xE0) ///< Message code mask -#define RESET_SUSPEND ((uint8_t)0x80) ///< Startup/Reset from suspend mode -#define RESET_SYNC ((uint8_t)0x40) ///< Startup/Reset from synchronous reset -#define RESET_CMD ((uint8_t)0x20) ///< Startup/Reset from ant message reset command -#define RESET_WDT ((uint8_t)0x02) ///< Startup/Reset from watchdog timeout -#define RESET_RST ((uint8_t)0x01) ///< Startup/Reset from HW reset pin -#define RESET_POR ((uint8_t)0x00) ///< Startup/Reset from HW power on reset -/** @} */ - -////////////////////////////////////////////// -/** @name Event Filtering -@{ */ -////////////////////////////////////////////// -#define FILTER_EVENT_RX_SEARCH_TIMEOUT ((uint16_t)0x0001) ///< Bitfield for filtering EVENT_RX_SEARCH_TIMEOUT -#define FILTER_EVENT_RX_FAIL ((uint16_t)0x0002) ///< Bitfield for filtering EVENT_RX_FAIL -#define FILTER_EVENT_TX ((uint16_t)0x0004) ///< Bitfield for filtering EVENT_TX -#define FILTER_EVENT_TRANSFER_RX_FAILED ((uint16_t)0x0008) ///< Bitfield for filtering EVENT_TRANSFER_RX_FAILED -#define FILTER_EVENT_TRANSFER_TX_COMPLETED ((uint16_t)0x0010) ///< Bitfield for filtering EVENT_TRANSFER_TX_COMPLETED -#define FILTER_EVENT_TRANSFER_TX_FAILED ((uint16_t)0x0020) ///< Bitfield for filtering EVENT_TRANSFER_TX_FAILED -#define FILTER_EVENT_CHANNEL_CLOSED ((uint16_t)0x0040) ///< Bitfield for filtering EVENT_CHANNEL_CLOSED -#define FILTER_EVENT_RX_FAIL_GO_TO_SEARCH ((uint16_t)0x0080) ///< Bitfield for filtering EVENT_RX_FAIL_GO_TO_SEARCH -#define FILTER_EVENT_CHANNEL_COLLISION ((uint16_t)0x0100) ///< Bitfield for filtering EVENT_CHANNEL_COLLISION -#define FILTER_EVENT_TRANSFER_TX_START ((uint16_t)0x0200) ///< Bitfield for filtering EVENT_TRANSFER_TX_START -/** @} */ - - -////////////////////////////////////////////// -/** @name Selective Data Update Mask Configuration Defines -@{ */ -////////////////////////////////////////////// -#define INVALID_SDU_MASK ((uint8_t)0xFF) ///< Selective data update configuration invalid mask. Used to disable SDU for a particular channel -#define SDU_MASK_ACK_CONFIG_BIT ((uint8_t)0x80) ///< Selective data acknowledge config bit. Use to enable SDU for acknowledged data in addition to broadcast data -/** @} */ - -////////////////////////////////////////////// -/** @name Advanced Burst Configuration Defines -@{ */ -////////////////////////////////////////////// -#define ADV_BURST_MODE_DISABLE ((uint8_t)0x00) ///< Set to disable advanced burst transfers -#define ADV_BURST_MODE_ENABLE ((uint8_t)0x01) ///< Set to enable advanced burst transfers - -#define ADV_BURST_MODES_MAX_SIZE ((uint8_t)0x03) ///< Maximum allowable value for advanced burst packets size configuration -#define ADV_BURST_MODES_SIZE_8_BYTES ((uint8_t)0x01) ///< 8-bytes packet size for maximum 20kbps advanced burst transfer rate -#define ADV_BURST_MODES_SIZE_16_BYTES ((uint8_t)0x02) ///< 16-bytes packet size for maximum 40kbps advanced burst transfer rate -#define ADV_BURST_MODES_SIZE_24_BYTES ((uint8_t)0x03) ///< 24-bytes packet size for maximum 60kbps advanced burst transfer rate - -#define ADV_BURST_MODES_MASK ((uint8_t)0x03) ///< Bitfield mask for advanced burst modes -#define ADV_BURST_MODES_FREQ_HOP ((uint8_t)0x01) ///< Bitfield for required/optional frequency hopping mode during advanced burst -#define ADV_BURST_MODES_RESERVED0 ((uint8_t)0x02) ///< Bitfield reserved -/** @} */ - -////////////////////////////////////////////// -/** @name Encrypted Channel Defines -@{ */ -////////////////////////////////////////////// -#define ENCRYPTION_DISABLED_MODE ((uint8_t) 0x00) ///< Set encryption mode to disabled -#define ENCRYPTION_BASIC_REQUEST_MODE ((uint8_t) 0x01) ///< Enable encryption mode with basic request (crypto ID exchange) -#define ENCRYPTION_USER_DATA_REQUEST_MODE ((uint8_t) 0x02) ///< Enable encryption mode with user data request (crypto ID + custom user data exchange) - -#define MAX_SUPPORTED_ENCRYPTION_MODE ENCRYPTION_USER_DATA_REQUEST_MODE ///< Maximum supported encryption mode -#define ENCRYPTION_USER_DATA_SIZE ((uint8_t)19) ///< Maximum size of custom user data - -#define ENCRYPTION_INFO_SET_CRYPTO_ID ((uint8_t)0x00) ///< Set configured crypto ID to be exchanged during encryption negotiation -#define ENCRYPTION_INFO_SET_CUSTOM_USER_DATA ((uint8_t)0x01) ///< Set configured custom user data to be exchanged during encryption negotation -#define ENCRYPTION_INFO_SET_RNG_SEED ((uint8_t)0x02) ///< Set RNG seed - -#define ENCRYPTION_INFO_GET_SUPPORTED_MODE ((uint8_t)0x00) ///< Get supported encrytped mode -#define ENCRYPTION_INFO_GET_CRYPTO_ID ((uint8_t)0x01) ///< Get configured crypto ID to be exchanged during encryption negotiation -#define ENCRYPTION_INFO_GET_CUSTOM_USER_DATA ((uint8_t)0x02) ///< Get configured custom user data to be exchanged during encryption negotiation -/** @} */ - -////////////////////////////////////////////// -/** @name RFActive Notification Defines -@{ */ -////////////////////////////////////////////// -#define RFACTIVE_NOTIFICATION_DISABLED_MODE ((uint8_t)0x00) ///< Set RF Active notification mode to disabled -#define RFACTIVE_NOTIFICATION_ONE_TIME_MODE ((uint8_t)0x01) ///< Set to generate RF Active notification event for only 1 time -#define RFACTIVE_NOTIFICATION_CONTINUOUS_MODE ((uint8_t)0x02) ///< Set to generate RF Active notification event continuously - -#define RFACTIVE_NOTIFICATION_MIN_TIME_THRESHOLD ((uint16_t)0x00A4) ///< Minimum time threshold of 5ms in 32768 time base -/** @} */ - -////////////////////////////////////////////// -/** @name WakeOn RF Activity Defines -@{ */ -////////////////////////////////////////////// -#define WAKEON_RF_ACTIVITY_NONE ((uint8_t)0x00) ///< Disable wakeon -#define WAKEON_RF_ACTIVITY_TX ((uint8_t)0x01) ///< Enable wakeon for ANT RF transmission windows -#define WAKEON_RF_ACTIVITY_RX ((uint8_t)0x02) ///< Enable wakeon for ANT RF reception windows -#define WAKEON_RF_ACTIVITY_ALL ((uint8_t)0x03) ///< (WAKE_ON_RF_ACTIVITY_TX | WAKE_ON_RF_ACTIVITY_RX)) -/** @} */ - -////////////////////////////////////////////// -/** @name Enhanced Channel Spacing Defines -@{ */ -////////////////////////////////////////////// -#define ENHANCED_CHANNEL_SPACING_DISABLE ((uint8_t)0x00) ///< Disable enhanced channel spacing -#define ENHANCED_CHANNEL_SPACING_ENABLE ((uint8_t)0x01) ///< Enable enhanced channel spacing -/** @} */ - - - - -////////////////////////////////////////////// -/** @name Channel Events and Command Response Codes -@{ */ -////////////////////////////////////////////// -#define RESPONSE_NO_ERROR ((uint8_t)0x00) ///< Command response with no error -#define NO_EVENT ((uint8_t)0x00) ///< No Event -#define EVENT_RX_SEARCH_TIMEOUT ((uint8_t)0x01) ///< ANT stack generated event when rx searching state for the channel has timed out -#define EVENT_RX_FAIL ((uint8_t)0x02) ///< ANT stack generated event when synchronous rx channel has missed receiving an ANT packet -#define EVENT_TX ((uint8_t)0x03) ///< ANT stack generated event when synchronous tx channel has occurred -#define EVENT_TRANSFER_RX_FAILED ((uint8_t)0x04) ///< ANT stack generated event when the completion of rx transfer has failed -#define EVENT_TRANSFER_TX_COMPLETED ((uint8_t)0x05) ///< ANT stack generated event when the completion of tx transfer has succeeded -#define EVENT_TRANSFER_TX_FAILED ((uint8_t)0x06) ///< ANT stack generated event when the completion of tx transfer has failed -#define EVENT_CHANNEL_CLOSED ((uint8_t)0x07) ///< ANT stack generated event when channel has closed -#define EVENT_RX_FAIL_GO_TO_SEARCH ((uint8_t)0x08) ///< ANT stack generated event when synchronous rx channel has lost tracking and is entering rx searching state -#define EVENT_CHANNEL_COLLISION ((uint8_t)0x09) ///< ANT stack generated event during a multi-channel setup where an instance of the current synchronous channel is blocked by another synchronous channel -#define EVENT_TRANSFER_TX_START ((uint8_t)0x0A) ///< ANT stack generated event when the start of tx transfer is occuring -//... -#define EVENT_TRANSFER_NEXT_DATA_BLOCK ((uint8_t)0x11) ///< ANT stack generated event when the stack requires the next transfer data block for tx transfer continuation or completion -//... -#define CHANNEL_IN_WRONG_STATE ((uint8_t)0x15) ///< Command response on attempt to perform an action from the wrong channel state -#define CHANNEL_NOT_OPENED ((uint8_t)0x16) ///< Command response on attempt to communicate on a channel that is not open -//... -#define CHANNEL_ID_NOT_SET ((uint8_t)0x18) ///< Command response on attempt to open a channel without setting the channel ID -#define CLOSE_ALL_CHANNELS ((uint8_t)0x19) ///< Command response when attempting to start scanning mode, when channels are still open -//... -#define TRANSFER_IN_PROGRESS ((uint8_t)0x1F) ///< Command response on attempt to communicate on a channel with a TX transfer in progress -#define TRANSFER_SEQUENCE_NUMBER_ERROR ((uint8_t)0x20) ///< Command response when sequence number of burst message or burst data segment is out of order -#define TRANSFER_IN_ERROR ((uint8_t)0x21) ///< Command response when transfer error has occured on supplied burst message or burst data segment -#define TRANSFER_BUSY ((uint8_t)0x22) ///< Command response when transfer is busy and cannot process supplied burst message or burst data segment -//... -#define MESSAGE_SIZE_EXCEEDS_LIMIT ((uint8_t)0x27) ///< Command response if a data message is provided that is too large -#define INVALID_MESSAGE ((uint8_t)0x28) ///< Command response when the message has an invalid parameter -#define INVALID_NETWORK_NUMBER ((uint8_t)0x29) ///< Command response when an invalid network number is provided -#define INVALID_LIST_ID ((uint8_t)0x30) ///< Command response when the provided list ID or size exceeds the limit -#define INVALID_SCAN_TX_CHANNEL ((uint8_t)0x31) ///< Command response when attempting to transmit on channel 0 when in scan mode -#define INVALID_PARAMETER_PROVIDED ((uint8_t)0x33) ///< Command response when an invalid parameter is specified in a configuration message -#define EVENT_QUE_OVERFLOW ((uint8_t)0x35) ///< ANT stack generated event when the event queue in the stack has overflowed and drop 1 or 2 events -#define EVENT_ENCRYPT_NEGOTIATION_SUCCESS ((uint8_t)0x38) ///< ANT stack generated event when connecting to an encrypted channel has succeeded -#define EVENT_ENCRYPT_NEGOTIATION_FAIL ((uint8_t)0x39) ///< ANT stack generated event when connecting to an encrypted channel has failed -#define EVENT_RFACTIVE_NOTIFICATION ((uint8_t)0x3A) ///< ANT stack generated event when the time to next synchronous channel RF activity exceeds configured time threshold -#define EVENT_CONNECTION_START ((uint8_t)0x3B) ///< Application generated event used to indicate when starting a connection to a channel -#define EVENT_CONNECTION_SUCCESS ((uint8_t)0x3C) ///< Application generated event used to indicate when successfuly connected to a channel -#define EVENT_CONNECTION_FAIL ((uint8_t)0x3D) ///< Application generated event used to indicate when failed to connect to a channel -#define EVENT_CONNECTION_TIMEOUT ((uint8_t)0x3E) ///< Application generated event used to indicate when connecting to a channel has timed out -#define EVENT_CONNECTION_UPDATE ((uint8_t)0x3F) ///< Application generated event used to indicate when connection parameters have been updated -//... -#define NO_RESPONSE_MESSAGE ((uint8_t)0x50) ///< Command response type intended to indicate that no serial reply message should be generated -#define EVENT_RX ((uint8_t)0x80) ///< ANT stack generated event indicating received data (eg. broadcast, acknowledge, burst) from the channel -#define EVENT_BLOCKED ((uint8_t)0xFF) ///< ANT stack generated event that should be ignored (eg. filtered events will generate this) -/** @} */ - - -#endif // !ANTDEFINES_H -/* - * Dynastream Innovations Inc. - * Cochrane, AB, CANADA - * - * Copyright (c) 2012 Dynastream Innovations Inc. - * THIS SOFTWARE IS AN EXAMPLE USAGE OF THE ANT PROTOCOL MODULE. - * IT MAY BE USED, MODIFIED and DISTRIBUTED ONLY WITH THE - * APPROPRIATE LICENSE AGREEMENT. - */ - -#ifndef ANTMESSAGE_H -#define ANTMESSAGE_H - -#include - -///////////////////////////////////////////////////////////////////////////// -// Message Format -// Messages are in the format: -// -// AX XX YY -------- CK -// -// where: AX is the 1 byte sync byte either transmit or recieve -// XX is the 1 byte size of the message (0-249) NOTE: THIS WILL BE LIMITED BY THE EMBEDDED RECEIVE BUFFER SIZE -// YY is the 1 byte ID of the message (1-255, 0 is invalid) -// ----- is the data of the message (0-249 bytes of data) -// CK is the 1 byte Checksum of the message -///////////////////////////////////////////////////////////////////////////// -#define MESG_TX_SYNC ((uint8_t)0xA4) -#define MESG_RX_SYNC ((uint8_t)0xA5) -#define MESG_SYNC_SIZE ((uint8_t)1) -#define MESG_SIZE_SIZE ((uint8_t)1) -#define MESG_ID_SIZE ((uint8_t)1) -#define MESG_CHANNEL_NUM_SIZE ((uint8_t)1) -#define MESG_EXT_MESG_BF_SIZE ((uint8_t)1) // NOTE: this could increase in the future -#define MESG_CHECKSUM_SIZE ((uint8_t)1) -#define MESG_DATA_SIZE ((uint8_t)9) - -////////////////////////////////////////////// -// ANT LIBRARY Extended Data Message Fields -// NOTE: You must check the extended message -// bitfield first to find out which fields -// are present before accessing them! -////////////////////////////////////////////// -#define ANT_EXT_MESG_DEVICE_ID_FIELD_SIZE ((uint8_t)4) -#define ANT_EXT_MESG_RSSI_FIELD_SIZE ((uint8_t)4) // maximum RSSI field size regardless of RSSI type -#define ANT_EXT_MESG_TIME_STAMP_FIELD_SIZE ((uint8_t)2) -#define ANT_EXT_STRING_SIZE ((uint8_t)16) // additional buffer to accommdate for 24 byte advance burst mode & encrypted usr data - -// The largest serial message is an ANT data message with all of the extended fields -#define MESG_ANT_MAX_PAYLOAD_SIZE ANT_STANDARD_DATA_PAYLOAD_SIZE - -#define MESG_MAX_EXT_DATA_SIZE (ANT_EXT_MESG_DEVICE_ID_FIELD_SIZE + ANT_EXT_MESG_RSSI_FIELD_SIZE + ANT_EXT_MESG_TIME_STAMP_FIELD_SIZE + ANT_EXT_STRING_SIZE) // ANT device ID (4 bytes) + ANT RSSI (4 bytes) + ANT timestamp (2 bytes) + ANT Ext String Size - -#define MESG_MAX_DATA_SIZE (MESG_ANT_MAX_PAYLOAD_SIZE + MESG_EXT_MESG_BF_SIZE + MESG_MAX_EXT_DATA_SIZE) // ANT data payload (8 bytes) + extended bitfield (1 byte) + extended data (10 bytes) -#define MESG_MAX_SIZE_VALUE (MESG_MAX_DATA_SIZE + MESG_CHANNEL_NUM_SIZE) // this is the maximum value that the serial message size value is allowed to be -#define MESG_BUFFER_SIZE (MESG_SIZE_SIZE + MESG_ID_SIZE + MESG_CHANNEL_NUM_SIZE + MESG_MAX_DATA_SIZE + MESG_CHECKSUM_SIZE) -#define MESG_FRAMED_SIZE (MESG_ID_SIZE + MESG_CHANNEL_NUM_SIZE + MESG_MAX_DATA_SIZE) -#define MESG_HEADER_SIZE (MESG_SYNC_SIZE + MESG_SIZE_SIZE + MESG_ID_SIZE) -#define MESG_FRAME_SIZE (MESG_HEADER_SIZE + MESG_CHECKSUM_SIZE) -#define MESG_MAX_SIZE (MESG_MAX_DATA_SIZE + MESG_FRAME_SIZE) - -#define MESG_SIZE_OFFSET (MESG_SYNC_SIZE) -#define MESG_ID_OFFSET (MESG_SYNC_SIZE + MESG_SIZE_SIZE) -#define MESG_DATA_OFFSET (MESG_HEADER_SIZE) - -////////////////////////////////////////////// -/** @name Message ID's -@{ */ -////////////////////////////////////////////// -#define MESG_INVALID_ID ((uint8_t)0x00) ///< invalid ANT message ID -#define MESG_EVENT_ID ((uint8_t)0x01) ///< ANT stack - channel event ID -//... -#define MESG_VERSION_ID ((uint8_t)0x3E) ///< ANT stack - version message ID -#define MESG_RESPONSE_EVENT_ID ((uint8_t)0x40) ///< ANT stack - channel/response event ANT message ID -#define MESG_UNASSIGN_CHANNEL_ID ((uint8_t)0x41) ///< ANT stack - channel unassign message ID -#define MESG_ASSIGN_CHANNEL_ID ((uint8_t)0x42) ///< ANT stack - channel assign message ID -#define MESG_CHANNEL_MESG_PERIOD_ID ((uint8_t)0x43) ///< ANT stack - channel period message ID -#define MESG_CHANNEL_SEARCH_TIMEOUT_ID ((uint8_t)0x44) ///< ANT stack - channel (high priority) search timeout message ID -#define MESG_CHANNEL_RADIO_FREQ_ID ((uint8_t)0x45) ///< ANT stack - channel radio frequency message ID -#define MESG_NETWORK_KEY_ID ((uint8_t)0x46) ///< ANT stack - network key message ID -#define MESG_RADIO_TX_POWER_ID ((uint8_t)0x47) ///< ANT stack - transmit power message ID -#define MESG_RADIO_CW_MODE_ID ((uint8_t)0x48) ///< ANT stack - CW test mode message ID -#define MESG_SEARCH_WAVEFORM_ID ((uint8_t)0x49) ///< ANT stack - search waveform message ID -#define MESG_SYSTEM_RESET_ID ((uint8_t)0x4A) ///< ANT application - system reset message ID -#define MESG_OPEN_CHANNEL_ID ((uint8_t)0x4B) ///< ANT stack - channel open message ID -#define MESG_CLOSE_CHANNEL_ID ((uint8_t)0x4C) ///< ANT stack - channel close message ID -#define MESG_REQUEST_ID ((uint8_t)0x4D) ///< ANT stack - request message ID -#define MESG_BROADCAST_DATA_ID ((uint8_t)0x4E) ///< ANT stack - broadcast message ID -#define MESG_ACKNOWLEDGED_DATA_ID ((uint8_t)0x4F) ///< ANT stack - acknowledged message ID -#define MESG_BURST_DATA_ID ((uint8_t)0x50) ///< ANT stack - burst message ID -#define MESG_CHANNEL_ID_ID ((uint8_t)0x51) ///< ANT stack - channel ID message ID -#define MESG_CHANNEL_STATUS_ID ((uint8_t)0x52) ///< ANT stack - channel status message ID -#define MESG_RADIO_CW_INIT_ID ((uint8_t)0x53) ///< ANT stack - CW test mode init message ID -#define MESG_CAPABILITIES_ID ((uint8_t)0x54) ///< ANT stack - capabilities message ID -//... -#define MESG_ID_LIST_ADD_ID ((uint8_t)0x59) ///< ANT stack - inc/exc list add message ID -#define MESG_ID_LIST_CONFIG_ID ((uint8_t)0x5A) ///< ANT stack - inc/exc list config message ID -#define MESG_OPEN_RX_SCAN_ID ((uint8_t)0x5B) ///< ANT stack - rx scanning channel open message ID -#define MESG_EXT_BROADCAST_DATA_ID ((uint8_t)0x5D) ///< ANT application - extended broadcast message ID -#define MESG_EXT_ACKNOWLEDGED_DATA_ID ((uint8_t)0x5E) ///< ANT application - extended acknowledged message ID -#define MESG_EXT_BURST_DATA_ID ((uint8_t)0x5F) ///< ANT application - extended burst message ID -#define MESG_CHANNEL_RADIO_TX_POWER_ID ((uint8_t)0x60) ///< ANT stack - channel transmit power message ID -#define MESG_GET_SERIAL_NUM_ID ((uint8_t)0x61) ///< ANT application - device serial number request message ID -#define MESG_SET_LP_SEARCH_TIMEOUT_ID ((uint8_t)0x63) ///< ANT stack - channel (low priority) search timeout message ID -#define MESG_SERIAL_NUM_SET_CHANNEL_ID_ID ((uint8_t)0x65) ///< ANT application - use serial number to set channel message ID -#define MESG_RX_EXT_MESGS_ENABLE_ID ((uint8_t)0x66) ///< ANT stack - extended rx message enable message ID -#define MESG_ANTLIB_CONFIG_ID ((uint8_t)0x6E) ///< ANT stack - lib config message ID -#define MESG_STARTUP_MESG_ID ((uint8_t)0x6F) ///< ANT application - startup message ID -#define MESG_AUTO_FREQ_CONFIG_ID ((uint8_t)0x70) ///< ANT stack - frequency agility config message ID -#define MESG_PROX_SEARCH_CONFIG_ID ((uint8_t)0x71) ///< ANT stack - proximity search config message ID -#define MESG_ADV_BURST_DATA_ID ((uint8_t)0x72) ///< ANT stack - advanced burst data message ID -#define MESG_COEX_PRIORITY_CONFIG_ID ((uint8_t)0x73) ///< ANT stack - coexistence priority config message ID -#define MESG_EVENT_BUFFERING_CONFIG_ID ((uint8_t)0x74) ///< ANT application - event buffering config message ID -#define MESG_SET_SEARCH_CH_PRIORITY_ID ((uint8_t)0x75) ///< ANT stack - search channel priority config message ID -#define MESG_CONFIG_ADV_BURST_ID ((uint8_t)0x78) ///< ANT stack - advanced burst config message ID -#define MESG_EVENT_FILTER_CONFIG_ID ((uint8_t)0x79) ///< ANT stack - event filtering config message ID -#define MESG_SDU_CONFIG_ID ((uint8_t)0x7A) ///< ANT stack - selective data update config message ID -#define MESG_SDU_SET_MASK_ID ((uint8_t)0x7B) ///< ANT stack - selective data update mask message ID -#define MESG_ENCRYPT_ENABLE_ID ((uint8_t)0x7D) ///< ANT stack - channel encryption mode enable message ID -#define MESG_SET_ENCRYPT_KEY_ID ((uint8_t)0x7E) ///< ANT stack - channel encryption key config message ID -#define MESG_SET_ENCRYPT_INFO_ID ((uint8_t)0x7F) ///< ANT stack - channel encryption info config message ID -#define MESG_ACTIVE_SEARCH_SHARING_ID ((uint8_t)0x81) ///< ANT stack - active seach sharing config message ID -#define MESG_COEX_ADV_PRIORITY_CONFIG_ID ((uint8_t)0x82) ///< ANT stack - advanced/platform specific coexistence priority config message ID -#define MESG_RFACTIVE_NOTIFICATION_ID ((uint8_t)0x84) ///< ANT stack - RF active notification config message ID -/** @} */ - -////////////////////////////////////////////// -/** @name Extended Message ID's -@{ */ -////////////////////////////////////////////// -#define MSG_EXT_ID_MASK ((uint8_t)0xE0) ///< ANT message ID extension mask -#define MESG_EXT_ID_0 ((uint8_t)0xE0) ///< ANT message ID extension 0xE1 -#define MESG_EXT_ID_1 ((uint8_t)0xE1) ///< ANT message ID 0xE1 extension -#define MESG_EXT_ID_2 ((uint8_t)0xE2) ///< ANT message ID 0xE2 extension -#define MESG_EXT_ID_3 ((uint8_t)0xE3) ///< ANT message ID 0xE3 extension -#define MESG_EXT_ID_4 ((uint8_t)0xE4) ///< ANT message ID 0xE4 extension - -// 0xE0 extended IDs -#define MESG_EXT_RESPONSE_ID ((uint16_t)0xE000) ///< Reserved for future use. ANT response messages using extended message IDs - -// 0xE1 extended IDs -#define MESG_EXT_REQUEST_ID ((uint16_t)0xE100) ///< Reserved for future use. ANT request messages using extended message IDs - - -// 0xE3 extended IDs -#define MESG_SET_SYNC_SERIAL_BIT_RATE ((uint16_t)0xE300) ///< ANT application - configure byte synchronous serial interface bit rate -#define MESG_SET_SYNC_SERIAL_SRDY_SLEEP ((uint16_t)0xE301) ///< ANT application - configure byte synchronous serial interface SRDY sleep delay - -// 0xE4 extended IDs -#define MESG_ANTFS_OTA_FW_UPDATE ((uint16_t)0xE400) ///< ANT application - run ANTFS over-the-air (OTA) device firmware update -/** @} */ - -////////////////////////////////////////////// -/** @name Debug Message ID's -@{ */ -////////////////////////////////////////////// -#define MESG_DEBUG_ID ((uint8_t)0xF0) // ANT application - debug message ID. Uses sub-index identifiers to differentiate message types -/** @} */ - -////////////////////////////////////////////// -/** @name Message Sizes -@{ */ -////////////////////////////////////////////// -#define MESG_INVALID_SIZE ((uint8_t)0) -#define MESG_VERSION_SIZE ((uint8_t)13) -#define MESG_RESPONSE_EVENT_SIZE ((uint8_t)3) -#define MESG_CHANNEL_STATUS_SIZE ((uint8_t)2) -#define MESG_UNASSIGN_CHANNEL_SIZE ((uint8_t)1) -#define MESG_ASSIGN_CHANNEL_SIZE ((uint8_t)3) -#define MESG_CHANNEL_ID_SIZE ((uint8_t)5) -#define MESG_CHANNEL_MESG_PERIOD_SIZE ((uint8_t)3) -#define MESG_CHANNEL_SEARCH_TIMEOUT_SIZE ((uint8_t)2) -#define MESG_CHANNEL_RADIO_FREQ_SIZE ((uint8_t)2) -#define MESG_CHANNEL_RADIO_TX_POWER_SIZE ((uint8_t)2) -#define MESG_NETWORK_KEY_SIZE ((uint8_t)9) -#define MESG_RADIO_TX_POWER_SIZE ((uint8_t)2) -#define MESG_RADIO_CW_MODE_SIZE ((uint8_t)3) -#define MESG_RADIO_CW_INIT_SIZE ((uint8_t)1) -#define MESG_SEARCH_WAVEFORM_SIZE ((uint8_t)3) -#define MESG_SYSTEM_RESET_SIZE ((uint8_t)1) -#define MESG_OPEN_CHANNEL_SIZE ((uint8_t)1) -#define MESG_CLOSE_CHANNEL_SIZE ((uint8_t)1) -#define MESG_REQUEST_SIZE ((uint8_t)2) -#define MESG_CAPABILITIES_SIZE ((uint8_t)8) -#define MESG_ID_LIST_ADD_SIZE ((uint8_t)6) -#define MESG_ID_LIST_CONFIG_SIZE ((uint8_t)3) -#define MESG_OPEN_RX_SCAN_SIZE ((uint8_t)2) -#define MESG_EXT_CHANNEL_RADIO_FREQ_SIZE ((uint8_t)3) -#define MESG_RADIO_CONFIG_ALWAYS_SIZE ((uint8_t)2) -#define MESG_RX_EXT_MESGS_ENABLE_SIZE ((uint8_t)2) -#define MESG_SET_TX_SEARCH_ON_NEXT_SIZE ((uint8_t)2) -#define MESG_SET_LP_SEARCH_TIMEOUT_SIZE ((uint8_t)2) -#define MESG_GET_SERIAL_NUM_SIZE ((uint8_t)4) -#define MESG_ANTLIB_CONFIG_SIZE ((uint8_t)2) -#define MESG_STARTUP_MESG_SIZE ((uint8_t)1) -#define MESG_AUTO_FREQ_CONFIG_SIZE ((uint8_t)4) -#define MESG_PROX_SEARCH_CONFIG_SIZE ((uint8_t)2) -#define MESG_COEX_PRIORITY_CONFIG_REQ_SIZE ((uint8_t)9) -#define MESG_EVENT_BUFFERING_CONFIG_REQ_SIZE ((uint8_t)6) -#define MESG_CONFIG_ADV_BURST_REQ_CAPABILITIES_SIZE ((uint8_t)4) -#define MESG_CONFIG_ADV_BURST_REQ_CONFIG_SIZE ((uint8_t)10) -#define MESG_CONFIG_ENCRYPT_REQ_CAPABILITIES_SIZE ((uint8_t)2) -#define MESG_CONFIG_ENCRYPT_REQ_CONFIG_ID_SIZE ((uint8_t)5) -#define MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE ((uint8_t)20) -#define MESG_CONFIG_ENCRYPT_REQ_CURRENT_CTR ((uint8_t)17) -#define MESG_EVENT_FILTER_CONFIG_REQ_SIZE ((uint8_t)3) -#define MESG_ACTIVE_SEARCH_SHARING_REQ_SIZE ((uint8_t)2) -#define MESG_COEX_ADV_PRIORITY_CONFIG_REQ_SIZE ((uint8_t)9) -#define MESG_RFACTIVE_NOTIFICATION_SIZE ((uint8_t)4) -#define MESG_FLASH_PROTECTION_CHECK_SIZE ((uint8_t)1) -#define MESG_BIST_SIZE ((uint8_t)6) -/** @} */ - -////////////////////////////////////////////// -/* ANT Message Structure */ -////////////////////////////////////////////// -/** @cond */ -typedef union -{ - uint8_t ucExtMesgBF; - struct - { - uint8_t bExtFieldCont : 1; - uint8_t : 1; - uint8_t : 1; - uint8_t : 1; - uint8_t : 1; - uint8_t bANTTimeStamp : 1; - uint8_t bANTRssi : 1; - uint8_t bANTDeviceID : 1; - }stExtMesgBF; - -} EXT_MESG_BF; // extended message bitfield - -typedef union -{ - uint32_t ulForceAlign; // force the struct to be 4-byte aligned, required for some casting in command.c - uint8_t aucMessage[MESG_BUFFER_SIZE]; // the complete message buffer pointer - struct - { - uint8_t ucSize; // the message size - union - { - uint8_t aucFramedData[MESG_FRAMED_SIZE]; // pointer for serial framer - struct - { - uint8_t ucMesgID; // the message ID - union - { - uint8_t aucMesgData[MESG_MAX_SIZE_VALUE]; // the message data - struct - { - union - { - uint8_t ucChannel; // ANT channel number - uint8_t ucSubID; // subID portion of ext ID message - }uData0; - uint8_t aucPayload[ANT_STANDARD_DATA_PAYLOAD_SIZE]; // ANT message payload - EXT_MESG_BF sExtMesgBF; // extended message bitfield (NOTE: this will not be here for longer data messages) - uint8_t aucExtData[MESG_MAX_EXT_DATA_SIZE]; // extended message data - }stMesgData; - }uMesgData; - }stFramedData; - }uFramedData; - uint8_t ucCheckSum; // the message checksum - }stMessage; - -} ANT_MESSAGE; -/* @endcond */ - -/** @brief Defines for accesssing ANT_MESSAGE members variables */ -/** @name ANT serial message structure -@{ */ -#define ANT_MESSAGE_ulForceAlign ulForceAlign -#define ANT_MESSAGE_aucMessage aucMessage -#define ANT_MESSAGE_ucSize stMessage.ucSize -#define ANT_MESSAGE_aucFramedData stMessage.uFramedData.aucFramedData -#define ANT_MESSAGE_ucMesgID stMessage.uFramedData.stFramedData.ucMesgID -#define ANT_MESSAGE_aucMesgData stMessage.uFramedData.stFramedData.uMesgData.aucMesgData -#define ANT_MESSAGE_ucChannel stMessage.uFramedData.stFramedData.uMesgData.stMesgData.uData0.ucChannel -#define ANT_MESSAGE_ucSubID stMessage.uFramedData.stFramedData.uMesgData.stMesgData.uData0.ucSubID -#define ANT_MESSAGE_aucPayload stMessage.uFramedData.stFramedData.uMesgData.stMesgData.aucPayload -#define ANT_MESSAGE_sExtMesgBF stMessage.uFramedData.stFramedData.uMesgData.stMesgData.sExtMesgBF -#define ANT_MESSAGE_ucExtMesgBF stMessage.uFramedData.stFramedData.uMesgData.stMesgData.sExtMesgBF.ucExtMesgBF -#define ANT_MESSAGE_stExtMesgBF stMessage.uFramedData.stFramedData.uMesgData.stMesgData.sExtMesgBF.stExtMesgBF -#define ANT_MESSAGE_aucExtData stMessage.uFramedData.stFramedData.uMesgData.stMesgData.aucExtData -#define ANT_MESSAGE_ucCheckSum stMessage.ucCheckSum -/** @} */ - -#endif // !ANTMESSAGE_H - -/** - @} - */ diff --git a/components/softdevice/s310/headers/ble.h b/components/softdevice/s310/headers/ble.h deleted file mode 100644 index b06321d..0000000 --- a/components/softdevice/s310/headers/ble.h +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_COMMON BLE SoftDevice Common - @{ - @defgroup ble_api Events, type definitions and API calls - @{ - - @brief Module independent events, type definitions and API calls for the BLE SoftDevice. - - */ - -#ifndef BLE_H__ -#define BLE_H__ - -#include "ble_ranges.h" -#include "ble_types.h" -#include "ble_gap.h" -#include "ble_l2cap.h" -#include "ble_gatt.h" -#include "ble_gattc.h" -#include "ble_gatts.h" - -/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations - * @{ */ - -/** - * @brief Common API SVC numbers. - */ -enum BLE_COMMON_SVCS -{ - SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */ - SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */ - SD_BLE_TX_BUFFER_COUNT_GET, /**< Get the total number of available application transmission buffers from the BLE stack. */ - SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific UUID. */ - SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */ - SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */ - SD_BLE_VERSION_GET, /**< Get the local version information (company id, Link Layer Version, Link Layer Subversion). */ - SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */ - SD_BLE_OPT_SET, /**< Set a BLE option. */ - SD_BLE_OPT_GET, /**< Get a BLE option. */ -}; - -/** - * @brief BLE Module Independent Event IDs. - */ -enum BLE_COMMON_EVTS -{ - BLE_EVT_TX_COMPLETE = BLE_EVT_BASE, /**< Transmission Complete. @ref ble_evt_tx_complete_t */ - BLE_EVT_USER_MEM_REQUEST, /**< User Memory request. @ref ble_evt_user_mem_request_t */ - BLE_EVT_USER_MEM_RELEASE /**< User Memory release. @ref ble_evt_user_mem_release_t */ -}; - -/**@brief Common Option IDs. - * IDs that uniquely identify a common option. - */ -enum BLE_COMMON_OPTS -{ - BLE_COMMON_OPT_RADIO_CPU_MUTEX = BLE_OPT_BASE /**< Radio CPU mutex option. @ref ble_common_opt_radio_cpu_mutex_t */ -}; -/** @} */ - -/** @addtogroup BLE_COMMON_DEFINES Defines - * @{ */ - -/** @brief Required pointer alignment for BLE Events. -*/ -#define BLE_EVTS_PTR_ALIGNMENT 4 - -/** @defgroup BLE_USER_MEM_TYPES User Memory Types - * @{ */ -#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */ -#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */ -/** @} */ - -/** @brief Maximum number of Vendor Specific UUIDs. -*/ -#define BLE_UUID_VS_MAX_COUNT 10 - -/** @} */ - -/** @addtogroup BLE_COMMON_STRUCTURES Structures - * @{ */ - -/**@brief User Memory Block. */ -typedef struct -{ - uint8_t *p_mem; /**< Pointer to the start of the user memory block. */ - uint16_t len; /**< Length in bytes of the user memory block. */ -} ble_user_mem_block_t; - -/** - * @brief Event structure for @ref BLE_EVT_TX_COMPLETE. - */ -typedef struct -{ - uint8_t count; /**< Number of packets transmitted. */ -} ble_evt_tx_complete_t; - -/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */ -typedef struct -{ - uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ -} ble_evt_user_mem_request_t; - -/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */ -typedef struct -{ - uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */ - ble_user_mem_block_t mem_block; /**< User memory block */ -} ble_evt_user_mem_release_t; - - -/**@brief Event structure for events not associated with a specific function module. */ -typedef struct -{ - uint16_t conn_handle; /**< Connection Handle on which this event occurred. */ - union - { - ble_evt_tx_complete_t tx_complete; /**< Transmission Complete. */ - ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */ - ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */ - } params; -} ble_common_evt_t; - -/**@brief BLE Event header. */ -typedef struct -{ - uint16_t evt_id; /**< Value from a BLE__EVT series. */ - uint16_t evt_len; /**< Length in octets excluding this header. */ -} ble_evt_hdr_t; - -/**@brief Common BLE Event type, wrapping the module specific event reports. */ -typedef struct -{ - ble_evt_hdr_t header; /**< Event header. */ - union - { - ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */ - ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */ - ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */ - ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */ - ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */ - } evt; -} ble_evt_t; - - -/** - * @brief Version Information. - */ -typedef struct -{ - uint8_t version_number; /**< Link Layer Version number for BT 4.1 spec is 7 (https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer). */ - uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */ - uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */ -} ble_version_t; - -/**@brief Mutual exclusion of radio activity and CPU execution. - * - * This option configures the application's access to the CPU when the radio is active. The - * application can configure itself to be blocked from using the CPU while the radio is - * active. By default, the application will be able to share CPU time with the SoftDevice - * during radio activity. This parameter structure is used together with @ref sd_ble_opt_set - * to configure the @ref BLE_COMMON_OPT_RADIO_CPU_MUTEX option. - * - * @note Note that the application should use this option to configure the SoftDevice to block the - * CPU during radio activity (i.e enable mutual exclusion) when running the SoftDevice on - * hardware affected by PAN #44 "CCM may exceed real time requirements"and PAN #45 "AAR may - * exceed real time requirements". - * - * @note Note that when acting as a scanner, the mutex is only enabled for radio TX activity. - * - * @note @ref sd_ble_opt_get is not supported for this option. - * - */ -typedef struct -{ - uint8_t enable : 1; /**< Enable mutual exclusion of radio activity and the CPU execution. */ -} ble_common_opt_radio_cpu_mutex_t; - -/**@brief Option structure for common options. */ -typedef union -{ - ble_common_opt_radio_cpu_mutex_t radio_cpu_mutex; /**< Parameters for the option for the mutual exclusion of radio activity and CPU execution. */ -} ble_common_opt_t; - -/**@brief Common BLE Option type, wrapping the module specific options. */ -typedef union -{ - ble_common_opt_t common_opt; /**< Common option, opt_id in BLE_COMMON_OPT_* series. */ - ble_gap_opt_t gap_opt; /**< GAP option, opt_id in BLE_GAP_OPT_* series. */ -} ble_opt_t; - -/** - * @brief BLE GATTS init options - */ -typedef struct -{ - ble_gatts_enable_params_t gatts_enable_params; /**< GATTS init options @ref ble_gatts_enable_params_t. */ -} ble_enable_params_t; - -/** @} */ - -/** @addtogroup BLE_COMMON_FUNCTIONS Functions - * @{ */ - -/**@brief Enable the BLE stack - * - * @param[in] p_ble_enable_params Pointer to ble_enable_params_t - * - * @details This call initializes the BLE stack, no other BLE related function can be called before this one. - * - * @return @ref NRF_SUCCESS BLE the BLE stack has been initialized successfully - * @retval @ref NRF_ERROR_INVALID_STATE the BLE stack had already been initialized and cannot be reinitialized. - * @return @ref NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. - * @return @ref NRF_ERROR_INVALID_LENGTH The specified Attribute Table size is either too small or not a multiple of 4. - * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. - * @return @ref NRF_ERROR_NO_MEM The Attribute Table size is too large. Decrease size in @ref ble_gatts_enable_params_t. - */ -SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(ble_enable_params_t * p_ble_enable_params)); - -/**@brief Get an event from the pending events queue. - * - * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length. This buffer must be 4-byte aligned in memory. - * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length. - * - * @details This call allows the application to pull a BLE event from the BLE stack. The application is signalled that an event is - * available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt. - * The application is free to choose whether to call this function from thread mode (main context) or directly from the Interrupt Service Routine - * that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher priority than the application, this function should be called - * in a loop (until @ref NRF_ERROR_NOT_FOUND is returned) every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. - * Failure to do so could potentially leave events in the internal queue without the application being aware of this fact. - * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to be copied into - * application memory. If the buffer provided is not large enough to fit the entire contents of the event, @ref NRF_ERROR_DATA_SIZE will be returned - * and the application can then call again with a larger buffer size. - * Please note that because of the variable length nature of some events, sizeof(ble_evt_t) will not always be large enough to fit certain events, - * and so it is the application's responsibility to provide an amount of memory large enough so that the relevant event is copied in full. - * The application may "peek" the event length by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return. - * - * @note The pointer supplied must be aligned to the extend defined by @ref BLE_EVTS_PTR_ALIGNMENT - * - * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied. - * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled. - * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer. - */ -SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len)); - - -/**@brief Get the total number of available application transmission buffers per link in the BLE stack. - * - * @details This call allows the application to obtain the total number of - * transmission buffers available per link for application data. Please note that - * this does not give the number of free buffers, but rather the total amount of them. - * The application has two options to handle its own application transmission buffers: - * - Use a simple arithmetic calculation: at boot time the application should use this function - * to find out the total amount of buffers available to it and store it in a variable. - * Every time a packet that consumes an application buffer is sent using any of the - * exposed functions in this BLE API, the application should decrement that variable. - * Conversely, whenever a @ref BLE_EVT_TX_COMPLETE event is received by the application - * it should retrieve the count field in such event and add that number to the same - * variable storing the number of available packets. - * This mechanism allows the application to be aware at any time of the number of - * application packets available in the BLE stack's internal buffers, and therefore - * it can know with certainty whether it is possible to send more data or it has to - * wait for a @ref BLE_EVT_TX_COMPLETE event before it proceeds. - * - Choose to simply not keep track of available buffers at all, and instead handle the - * @ref BLE_ERROR_NO_TX_BUFFERS error by queueing the packet to be transmitted and - * try again as soon as a @ref BLE_EVT_TX_COMPLETE event arrives. - * - * The API functions that may consume an application buffer depending on - * the parameters supplied to them can be found below: - * - * - @ref sd_ble_gattc_write (write without response only) - * - @ref sd_ble_gatts_hvx (notifications only) - * - @ref sd_ble_l2cap_tx (all packets) - * - * @param[out] p_count Pointer to a uint8_t which will contain the number of application transmission buffers upon - * successful return. - * - * @retval ::NRF_SUCCESS Number of application transmission buffers retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - */ -SVCALL(SD_BLE_TX_BUFFER_COUNT_GET, uint32_t, sd_ble_tx_buffer_count_get(uint8_t *p_count)); - - -/**@brief Add a Vendor Specific UUID. - * - * @details This call enables the application to add a vendor specific UUID to the BLE stack's table, - * for later use all other modules and APIs. This then allows the application to use the shorter, - * 24-bit @ref ble_uuid_t format when dealing with both 16-bit and 128-bit UUIDs without having to - * check for lengths and having split code paths. The way that this is accomplished is by extending the - * grouping mechanism that the Bluetooth SIG standard base UUID uses for all other 128-bit UUIDs. The - * type field in the @ref ble_uuid_t structure is an index (relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN) - * to the table populated by multiple calls to this function, and the uuid field in the same structure - * contains the 2 bytes at indices 12 and 13. The number of possible 128-bit UUIDs available to the - * application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536, - * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array. - * - * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by - * the 16-bit uuid field in @ref ble_uuid_t. - * - * - * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding - * bytes 12 and 13. - * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored. - * - * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID. - * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid. - * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs. - * @retval ::NRF_ERROR_FORBIDDEN If p_vs_uuid has already been added to the VS UUID table. - */ -SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type)); - - -/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure. - * - * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared - * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add - * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index - * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type. - * - * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE. - * - * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes). - * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes. - * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length. - * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs. - */ -SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid)); - - -/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit). - * - * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed. - * - * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes. - * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes). - * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored. - * - * @retval ::NRF_SUCCESS Successfully encoded into the buffer. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type. - */ -SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le)); - - -/**@brief Get Version Information. - * - * @details This call allows the application to get the BLE stack version information. - * - * @param[out] p_version Pointer to a ble_version_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Version information stored successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure). - */ -SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version)); - - -/**@brief Provide a user memory block. - * - * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application. - * - * @param[in] conn_handle Connection handle. - * @param[in,out] p_block Pointer to a user memory block structure. - * - * @retval ::NRF_SUCCESS Successfully queued a response to the peer. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no execute write request pending. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time. - */ -SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)); - -/**@brief Set a BLE option. - * - * @details This call allows the application to set the value of an option. - * - * @param[in] opt_id Option ID. - * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value. - * - * @retval ::NRF_SUCCESS Option set successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. - */ -SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)); - - -/**@brief Get a BLE option. - * - * @details This call allows the application to retrieve the value of an option. - * - * @param[in] opt_id Option ID. - * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in. - * - * @retval ::NRF_SUCCESS Option retrieved successfully. - * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied. - * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle. - * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints. - * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time. - * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed. - * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported. - * - */ -SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)); - -/** @} */ - -#endif /* BLE_H__ */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s310/headers/ble_err.h b/components/softdevice/s310/headers/ble_err.h deleted file mode 100644 index 6805e0e..0000000 --- a/components/softdevice/s310/headers/ble_err.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_COMMON - @{ - @addtogroup nrf_error - @{ - @ingroup BLE_COMMON - @} - - @defgroup ble_err General error codes - @{ - - @brief General error code definitions for the BLE API. - - @ingroup BLE_COMMON -*/ -#ifndef NRF_BLE_ERR_H__ -#define NRF_BLE_ERR_H__ - -#include "nrf_error.h" - -/* @defgroup BLE_ERRORS Error Codes - * @{ */ -#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */ -#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */ -#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */ -#define BLE_ERROR_NO_TX_BUFFERS (NRF_ERROR_STK_BASE_NUM+0x004) /**< Buffer capacity exceeded. */ -#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */ -/** @} */ - - -/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges - * @brief Assignment of subranges for module specific error codes. - * @note For specific error codes, see ble_.h or ble_error_.h. - * @{ */ -#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */ -#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */ -#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */ -#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */ -/** @} */ - -#endif - - -/** - @} - @} -*/ diff --git a/components/softdevice/s310/headers/ble_gatt.h b/components/softdevice/s310/headers/ble_gatt.h deleted file mode 100644 index 2e85599..0000000 --- a/components/softdevice/s310/headers/ble_gatt.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common - @{ - @brief Common definitions and prototypes for the GATT interfaces. - */ - -#ifndef BLE_GATT_H__ -#define BLE_GATT_H__ - -#include "ble_types.h" -#include "ble_ranges.h" - - -/** @addtogroup BLE_GATT_DEFINES Defines - * @{ */ - -/** @brief Default MTU size. */ -#define GATT_MTU_SIZE_DEFAULT 23 - -/** @brief Only the default MTU size of 23 is currently supported. */ -#define GATT_RX_MTU 23 - - -/**@brief Invalid Attribute Handle. */ -#define BLE_GATT_HANDLE_INVALID 0x0000 - -/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources - * @{ */ -#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */ -/** @} */ - -/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations - * @{ */ -#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */ -#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */ -#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */ -#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */ -#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */ -#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */ -/** @} */ - -/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags - * @{ */ -#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 -#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 -/** @} */ - -/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations - * @{ */ -#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */ -#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */ -#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */ -/** @} */ - -/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes - * @{ */ -#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */ -#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */ -#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */ -#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */ -#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */ -#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorisation. */ -#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */ -#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */ -#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */ -#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */ -#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */ -#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */ -#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */ -#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */ -#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */ -#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */ -#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */ -#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */ -#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */ -/** @} */ - - -/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats - * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml - * @{ */ -#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */ -#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */ -#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */ -#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */ -#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */ -#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */ -#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */ -#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */ -#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */ -#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */ -#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */ -#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */ -#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */ -#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */ -/** @} */ - -/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces - * @{ - */ -#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */ -#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */ -/** @} */ - -/** @} */ - -/** @addtogroup BLE_GATT_STRUCTURES Structures - * @{ */ - -/**@brief GATT Characteristic Properties. */ -typedef struct -{ - /* Standard properties */ - uint8_t broadcast :1; /**< Broadcasting of the value permitted. */ - uint8_t read :1; /**< Reading the value permitted. */ - uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */ - uint8_t write :1; /**< Writing the value with Write Request permitted. */ - uint8_t notify :1; /**< Notications of the value permitted. */ - uint8_t indicate :1; /**< Indications of the value permitted. */ - uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */ -} ble_gatt_char_props_t; - -/**@brief GATT Characteristic Extended Properties. */ -typedef struct -{ - /* Extended properties */ - uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */ - uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */ -} ble_gatt_char_ext_props_t; - -#endif // BLE_GATT_H__ - -/** @} */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s310/headers/ble_hci.h b/components/softdevice/s310/headers/ble_hci.h deleted file mode 100644 index 978f885..0000000 --- a/components/softdevice/s310/headers/ble_hci.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_COMMON - @{ -*/ - - -#ifndef BLE_HCI_H__ -#define BLE_HCI_H__ - -/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes - * @{ */ - -#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */ -#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */ -#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */ -/*0x03 Hardware Failure -0x04 Page Timeout -*/ -#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */ -#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */ -#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */ -#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */ -/*0x09 Connection Limit Exceeded -0x0A Synchronous Connection Limit To A Device Exceeded -0x0B ACL Connection Already Exists*/ -#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */ -/*0x0D Connection Rejected due to Limited Resources -0x0E Connection Rejected Due To Security Reasons -0x0F Connection Rejected due to Unacceptable BD_ADDR -0x10 Connection Accept Timeout Exceeded -0x11 Unsupported Feature or Parameter Value*/ -#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */ -#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */ -#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/ -#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */ -#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */ -/* -0x17 Repeated Attempts -0x18 Pairing Not Allowed -0x19 Unknown LMP PDU -*/ -#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */ -/* -0x1B SCO Offset Rejected -0x1C SCO Interval Rejected -0x1D SCO Air Mode Rejected*/ -#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */ -#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */ -/*0x20 Unsupported LMP Parameter Value -0x21 Role Change Not Allowed -*/ -#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */ -/*0x23 LMP Error Transaction Collision*/ -#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */ -/*0x25 Encryption Mode Not Acceptable -0x26 Link Key Can Not be Changed -0x27 Requested QoS Not Supported -*/ -#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */ -#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */ -#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */ -/* -0x2B Reserved -0x2C QoS Unacceptable Parameter -0x2D QoS Rejected -0x2E Channel Classification Not Supported -0x2F Insufficient Security -0x30 Parameter Out Of Mandatory Range -0x31 Reserved -0x32 Role Switch Pending -0x33 Reserved -0x34 Reserved Slot Violation -0x35 Role Switch Failed -0x36 Extended Inquiry Response Too Large -0x37 Secure Simple Pairing Not Supported By Host. -0x38 Host Busy - Pairing -0x39 Connection Rejected due to No Suitable Channel Found*/ -#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */ -#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */ -#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Adverisement Timeout. */ -#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */ -#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */ - -/** @} */ - - -#endif // BLE_HCI_H__ - -/** @} */ diff --git a/components/softdevice/s310/headers/ble_ranges.h b/components/softdevice/s310/headers/ble_ranges.h deleted file mode 100644 index 4d5c05b..0000000 --- a/components/softdevice/s310/headers/ble_ranges.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_COMMON - @{ - @defgroup ble_ranges Module specific SVC, event and option number subranges - @{ - - @brief Definition of SVC, event and option number subranges for each API module. - - @note - SVCs, event and option numbers are split into subranges for each API module. - Each module receives its entire allocated range of SVC calls, whether implemented or not, - but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range. - - Note that the symbols BLE__SVC_LAST is the end of the allocated SVC range, - rather than the last SVC function call actually defined and implemented. - - Specific SVC, event and option values are defined in each module's ble_.h file, - which defines names of each individual SVC code based on the range start value. -*/ - -#ifndef BLE_RANGES_H__ -#define BLE_RANGES_H__ - -#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */ -#define BLE_SVC_LAST 0x6B /**< Total: 12. */ - -#define BLE_RESERVED_SVC_BASE 0x6C /**< Reserved BLE SVC base. */ -#define BLE_RESERVED_SVC_LAST 0x6F /**< Total: 4. */ - -#define BLE_GAP_SVC_BASE 0x70 /**< GAP BLE SVC base. */ -#define BLE_GAP_SVC_LAST 0x8F /**< Total: 32. */ - -#define BLE_GATTC_SVC_BASE 0x90 /**< GATTC BLE SVC base. */ -#define BLE_GATTC_SVC_LAST 0x9F /**< Total: 32. */ - -#define BLE_GATTS_SVC_BASE 0xA0 /**< GATTS BLE SVC base. */ -#define BLE_GATTS_SVC_LAST 0xAF /**< Total: 16. */ - -#define BLE_L2CAP_SVC_BASE 0xB0 /**< L2CAP BLE SVC base. */ -#define BLE_L2CAP_SVC_LAST 0xBF /**< Total: 16. */ - - -#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */ - -#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */ -#define BLE_EVT_LAST 0x0F /**< Total: 15. */ - -#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */ -#define BLE_GAP_EVT_LAST 0x2F /**< Total: 32. */ - -#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */ -#define BLE_GATTC_EVT_LAST 0x4F /**< Total: 32. */ - -#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */ -#define BLE_GATTS_EVT_LAST 0x6F /**< Total: 32. */ - -#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */ -#define BLE_L2CAP_EVT_LAST 0x8F /**< Total: 32. */ - - -#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */ - -#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */ -#define BLE_OPT_LAST 0x1F /**< Total: 31. */ - -#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */ -#define BLE_GAP_OPT_LAST 0x3F /**< Total: 32. */ - -#define BLE_GATTC_OPT_BASE 0x40 /**< GATTC BLE Option base. */ -#define BLE_GATTC_OPT_LAST 0x5F /**< Total: 32. */ - -#define BLE_GATTS_OPT_BASE 0x60 /**< GATTS BLE Option base. */ -#define BLE_GATTS_OPT_LAST 0x7F /**< Total: 32. */ - -#define BLE_L2CAP_OPT_BASE 0x80 /**< L2CAP BLE Option base. */ -#define BLE_L2CAP_OPT_LAST 0x9F /**< Total: 32. */ - -#endif /* BLE_RANGES_H__ */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s310/headers/ble_types.h b/components/softdevice/s310/headers/ble_types.h deleted file mode 100644 index 643208e..0000000 --- a/components/softdevice/s310/headers/ble_types.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** - @addtogroup BLE_COMMON - @{ - @defgroup ble_types Common types and macro definitions - @{ - - @brief Common types and macro definitions for the BLE SoftDevice. - */ - -#ifndef BLE_TYPES_H__ -#define BLE_TYPES_H__ - -#include - -/** @addtogroup BLE_TYPES_DEFINES Defines - * @{ */ - -/** @defgroup BLE_CONN_HANDLES BLE Connection Handles - * @{ */ -#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */ -#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */ -/** @} */ - - -/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs - * @{ */ -/* Generic UUIDs, applicable to all services */ -#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */ -#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */ -#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */ -#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */ -#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */ -#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */ -#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */ -#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */ -/* GATT specific UUIDs */ -#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */ -#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */ -/* GAP specific UUIDs */ -#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */ -#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_PPF 0x2A02 /**< Peripheral Privacy Flag Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */ -#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */ -/** @} */ - - -/** @defgroup BLE_UUID_TYPES Types of UUID - * @{ */ -#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */ -#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */ -#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */ -/** @} */ - - -/** @defgroup BLE_APPEARANCES Bluetooth Appearance values - * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml - * @{ */ -#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */ -#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */ -#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */ -#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */ -#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */ -#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */ -#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */ -#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */ -#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */ -#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */ -#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */ -#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */ -#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */ -#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */ -#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */ -#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */ -#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */ -#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */ -#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */ -#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */ -#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */ -#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */ -#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */ -#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystiq (HID Subtype). */ -#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */ -#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */ -#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */ -#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */ -#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */ -#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */ -#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */ -#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */ -#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */ -#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */ -#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */ -#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */ -#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */ -#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */ -#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */ -#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */ -#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */ -#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */ -#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */ -#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */ -#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */ -#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */ -/** @} */ - -/** @brief Set .type and .uuid fields of ble_uuid_struct to specified uuid value. */ -#define BLE_UUID_BLE_ASSIGN(instance, value) do {\ - instance.type = BLE_UUID_TYPE_BLE; \ - instance.uuid = value;} while(0) - -/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */ -#define BLE_UUID_COPY_PTR(dst, src) do {\ - (dst)->type = (src)->type; \ - (dst)->uuid = (src)->uuid;} while(0) - -/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */ -#define BLE_UUID_COPY_INST(dst, src) do {\ - (dst).type = (src).type; \ - (dst).uuid = (src).uuid;} while(0) - -/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ -#define BLE_UUID_EQ(p_uuid1, p_uuid2) \ - (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid)) - -/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */ -#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \ - (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid)) - -/** @} */ - -/** @addtogroup BLE_TYPES_STRUCTURES Structures - * @{ */ - -/** @brief 128 bit UUID values. */ -typedef struct -{ - unsigned char uuid128[16]; /**< Little-Endian UUID bytes. */ -} ble_uuid128_t; - -/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */ -typedef struct -{ - uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */ - uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */ -} ble_uuid_t; - -/** @} */ - -#endif /* BLE_TYPES_H__ */ - -/** - @} - @} -*/ diff --git a/components/softdevice/s310/headers/nrf_error.h b/components/softdevice/s310/headers/nrf_error.h deleted file mode 100644 index d580aa3..0000000 --- a/components/softdevice/s310/headers/nrf_error.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - /** - @defgroup nrf_error SoftDevice Global Error Codes - @{ - - @brief Global Error definitions -*/ - -/* Header guard */ -#ifndef NRF_ERROR_H__ -#define NRF_ERROR_H__ - -/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions - * @{ */ -#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base -#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base -#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base -#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base -/** @} */ - -#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command -#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing -#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled -#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error -#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation -#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found -#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported -#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter -#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state -#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length -#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags -#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data -#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit -#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out -#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer -#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation -#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address -#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy - -#endif // NRF_ERROR_H__ - -/** - @} -*/ diff --git a/components/softdevice/s310/headers/nrf_error_sdm.h b/components/softdevice/s310/headers/nrf_error_sdm.h deleted file mode 100644 index b3b9b76..0000000 --- a/components/softdevice/s310/headers/nrf_error_sdm.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - /** - @addtogroup nrf_sdm_api - @{ - @defgroup nrf_sdm_error SoftDevice Manager Error Codes - @{ - - @brief Error definitions for the SDM API -*/ - -/* Header guard */ -#ifndef NRF_ERROR_SDM_H__ -#define NRF_ERROR_SDM_H__ - -#include "nrf_error.h" - -#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown lfclk source. -#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts). -#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erronous SoftDevice flashing). - -#endif // NRF_ERROR_SDM_H__ - -/** - @} - @} -*/ diff --git a/components/softdevice/s310/headers/nrf_error_soc.h b/components/softdevice/s310/headers/nrf_error_soc.h deleted file mode 100644 index d80d626..0000000 --- a/components/softdevice/s310/headers/nrf_error_soc.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - @addtogroup nrf_soc_api - @{ - @defgroup nrf_soc_error SoC Library Error Codes - @{ - - @brief Error definitions for the SoC library - -*/ - -/* Header guard */ -#ifndef NRF_ERROR_SOC_H__ -#define NRF_ERROR_SOC_H__ - -#include "nrf_error.h" - -/* Mutex Errors */ -#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken - -/* NVIC errors */ -#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available -#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed -#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return - -/* Power errors */ -#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown -#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown -#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return - -/* Rand errors */ -#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values - -/* PPI errors */ -#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel -#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group - -#endif // NRF_ERROR_SOC_H__ -/** - @} - @} -*/ diff --git a/components/softdevice/s310/headers/nrf_mbr.h b/components/softdevice/s310/headers/nrf_mbr.h deleted file mode 100644 index 3ac6dbf..0000000 --- a/components/softdevice/s310/headers/nrf_mbr.h +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - @defgroup nrf_mbr_api Master Boot Record API - @{ - - @brief APIs for updating SoftDevice and BootLoader - -*/ - -/* Header guard */ -#ifndef NRF_MBR_H__ -#define NRF_MBR_H__ - -#include "nrf_svc.h" -#include - - -/** @addtogroup NRF_MBR_DEFINES Defines - * @{ */ - -/**@brief MBR SVC Base number. */ -#define MBR_SVC_BASE (0x18) - -/** @} */ - -/** @addtogroup NRF_MBR_ENUMS Enumerations - * @{ */ - -/**@brief nRF Master Boot Record API SVC numbers. */ -enum NRF_MBR_SVCS -{ - SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */ -}; - -/**@brief Possible values for ::sd_mbr_command_t.command */ -enum NRF_MBR_COMMANDS -{ - SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see sd_mbr_command_copy_bl_t */ - SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/ - SD_MBR_COMMAND_INIT_SD, /**< Init forwarding interrupts to SD, and run reset function in SD*/ - SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/ - SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Start forwarding all exception to this address @see ::sd_mbr_command_vector_table_base_set_t*/ -}; - -/** @} */ - -/** @addtogroup NRF_MBR_TYPES Types - * @{ */ - -/**@brief This command copies part of a new SoftDevice - * The destination area is erased before copying. - * If dst is in the middle of a flash page, that whole flash page will be erased. - * If (dst+len) is in the middle of a flash page, that whole flash page will be erased. - * - * The user of this function is responsible for setting the PROTENSET registers. - * - * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly. - * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying. - */ -typedef struct -{ - uint32_t *src; /**< Pointer to the source of data to be copied.*/ - uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/ - uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of PAGE_SIZE_IN_WORDS words.*/ -} sd_mbr_command_copy_sd_t; - - -/**@brief This command works like memcmp, but takes the length in words. - * - * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal. - * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal. - */ -typedef struct -{ - uint32_t *ptr1; /**< Pointer to block of memory. */ - uint32_t *ptr2; /**< Pointer to block of memory. */ - uint32_t len; /**< Number of 32 bit words to compare.*/ -} sd_mbr_command_compare_t; - - -/**@brief This command copies a new BootLoader. - * With this command, destination of BootLoader is always the address written in NRF_UICR->BOOTADDR. - * - * Destination is erased by this function. - * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased. - * - * This function will use PROTENSET to protect the flash that is not intended to be written. - * - * On Success, this function will not return. It will start the new BootLoader from reset-vector as normal. - * - * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. - * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set. - * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area. - */ -typedef struct -{ - uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/ - uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */ -} sd_mbr_command_copy_bl_t; - -/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR - * - * Once this function has been called, this address is where the MBR will start to forward interrupts to after a reset. - * - * To restore default forwarding this function should be called with @param address set to 0. - * The MBR will then start forwarding to interrupts to the adress in NFR_UICR->BOOTADDR or to the SoftDevice if the BOOTADDR is not set. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen. - * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size. - */ -typedef struct -{ - uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/ -} sd_mbr_command_vector_table_base_set_t; - -typedef struct -{ - uint32_t command; /**< type of command to be issued see @ref NRF_MBR_COMMANDS. */ - union - { - sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/ - sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader.*/ - sd_mbr_command_compare_t compare; /**< Parameters for verify.*/ - sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set.*/ - } params; -} sd_mbr_command_t; - -/** @} */ - -/** @addtogroup NRF_MBR_FUNCTIONS Functions - * @{ */ - -/**@brief Issue Master Boot Record commands - * - * Commands used when updating a SoftDevice and bootloader. - * - * @param[in] param Pointer to a struct describing the command. - * - *@note for retvals see ::sd_mbr_command_copy_sd_t ::sd_mbr_command_copy_bl_t ::sd_mbr_command_compare_t - -*/ -SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param)); - -/** @} */ -#endif // NRF_MBR_H__ - -/** - @} -*/ diff --git a/components/softdevice/s310/headers/nrf_sd_def.h b/components/softdevice/s310/headers/nrf_sd_def.h deleted file mode 100644 index bda93bd..0000000 --- a/components/softdevice/s310/headers/nrf_sd_def.h +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_SD_DEF_H__ -#define NRF_SD_DEF_H__ - -#include - -#define SD_PPI_CHANNELS_USED 0xFFF0C000uL /**< PPI channels utilized by SotfDevice (not available to th application). */ -#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ -#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ -#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ - -#endif /* NRF_SD_DEF_H__ */ diff --git a/components/softdevice/s310/headers/nrf_sdm.h b/components/softdevice/s310/headers/nrf_sdm.h deleted file mode 100644 index 63a89ab..0000000 --- a/components/softdevice/s310/headers/nrf_sdm.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - @defgroup nrf_sdm_api SoftDevice Manager API - @{ - - @brief APIs for SoftDevice management. - -*/ - -/* Header guard */ -#ifndef NRF_SDM_H__ -#define NRF_SDM_H__ - -#include "nrf_svc.h" -#include "nrf51.h" -#include "nrf_soc.h" -#include "nrf_error_sdm.h" - -/** @addtogroup NRF_SDM_DEFINES Defines - * @{ */ - -/** @brief SoftDevice Manager SVC Base number. */ -#define SDM_SVC_BASE 0x10 - -/** @} */ - -/** @brief Defines the SoftDevice Information Structure location (address) as an offset from -the start of the softdevice (without MBR)*/ -#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000) - -/** @brief Defines the usual size reserverd for the MBR when a softdevice is written to flash. -This is the offset where the first byte of the softdevice hex file is written.*/ -#define MBR_SIZE (0x1000) - -/** @brief Defines the absolute Softdevice information structure location (address)*/ -#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE) - -/** @brief Defines the offset for Softdevice size value relative to Softdevice base address*/ -#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08) - -/** @brief Defines the offset for FWID value relative to Softdevice base address*/ -#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C) - -/** @brief Defines a macro for retreiving the actual Softdevice size value from a given base address - use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/ -#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET))) - -/** @brief Defines a macro for retreiving the actual FWID value from a given base address - use @ref MBR_SIZE when Softdevice is installed just above the MBR (the usual case)*/ -#define SD_FWID_GET(baseaddr) ((*((uint32_t *) ((baseaddr) + SD_FWID_OFFSET))) & 0xFFFF) - - -/** @addtogroup NRF_SDM_ENUMS Enumerations - * @{ */ - -/**@brief nRF SoftDevice Manager API SVC numbers. */ -enum NRF_SD_SVCS -{ - SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */ - SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */ - SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */ - SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */ - SVC_SDM_LAST /**< Placeholder for last SDM SVC */ -}; - -/**@brief Possible lfclk oscillator sources. */ -enum NRF_CLOCK_LFCLKSRCS -{ - NRF_CLOCK_LFCLKSRC_SYNTH_250_PPM, /**< LFCLK Synthesized from HFCLK. */ - NRF_CLOCK_LFCLKSRC_XTAL_500_PPM, /**< LFCLK crystal oscillator 500 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_250_PPM, /**< LFCLK crystal oscillator 250 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_150_PPM, /**< LFCLK crystal oscillator 150 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_100_PPM, /**< LFCLK crystal oscillator 100 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_75_PPM, /**< LFCLK crystal oscillator 75 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_50_PPM, /**< LFCLK crystal oscillator 50 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_30_PPM, /**< LFCLK crystal oscillator 30 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, /**< LFCLK crystal oscillator 20 PPM accuracy. */ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_250MS_CALIBRATION, /**< LFCLK RC oscillator, 250ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_500MS_CALIBRATION, /**< LFCLK RC oscillator, 500ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_1000MS_CALIBRATION, /**< LFCLK RC oscillator, 1000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_2000MS_CALIBRATION, /**< LFCLK RC oscillator, 2000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_4000MS_CALIBRATION, /**< LFCLK RC oscillator, 4000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_8000MS_CALIBRATION, /**< LFCLK RC oscillator, 8000ms calibration interval.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_1000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 1000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_2000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 2000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_4000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 4000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_8000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 8000ms, if changed above a threshold, a calibration is done.*/ - NRF_CLOCK_LFCLKSRC_RC_250_PPM_TEMP_16000MS_CALIBRATION, /**< LFCLK RC oscillator. Temperature checked every 16000ms, if changed above a threshold, a calibration is done.*/ -}; - -/** @} */ - -/** @addtogroup NRF_SDM_TYPES Types - * @{ */ - -/**@brief Type representing lfclk oscillator source. */ -typedef uint32_t nrf_clock_lfclksrc_t; - - -/**@brief SoftDevice Assertion Handler type. - * - * When an unexpected error occurs within the SoftDevice it will call the SoftDevice assertion handler callback. - * The protocol stack will be in an undefined state when this happens and the only way to recover will be to - * perform a reset, using e.g. CMSIS NVIC_SystemReset(). - * - * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the SoftDevice assert callback. - * - * @param[in] pc The program counter of the failed assert. - * @param[in] line_number Line number where the assert failed. - * @param[in] file_name File name where the assert failed. - */ -typedef void (*softdevice_assertion_handler_t)(uint32_t pc, uint16_t line_number, const uint8_t * p_file_name); - -/** @} */ - -/** @addtogroup NRF_SDM_FUNCTIONS Functions - * @{ */ - -/**@brief Enables the SoftDevice and by extension the protocol stack. - * - * Idempotent function to enable the SoftDevice. - * - * @note Some care must be taken if a low frequency clock source is already running when calling this function: - * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new - * clock source will be started. - * - * @note This function has no effect when returning with an error. - * - * @post If return code is ::NRF_SUCCESS - * - SoC library and protocol stack APIs are made available. - * - A portion of RAM will be unavailable (see relevant SDS documentation). - * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation). - * - Interrupts will not arrive from protected peripherals or interrupts. - * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the softdevice. - * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation). - * - Chosen low frequency clock source will be running. - * - * @param clock_source Low frequency clock source and accuracy. (Note: In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock). - * @param assertion_handler Callback for SoftDevice assertions. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and assertion handler cannot be updated. - * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDeviceinterrupt is already enabled, or an enabled interrupt has an illegal priority level. - * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected. - */ -SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lfclksrc_t clock_source, softdevice_assertion_handler_t assertion_handler)); - -/**@brief Disables the SoftDevice and by extension the protocol stack. - * - * Idempotent function to disable the SoftDevice. - * - * @post SoC library and protocol stack APIs are made unavailable. - * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest). - * @post All peripherals used by the SoftDevice will be reset to default values. - * @post All of RAM become available. - * @post All interrupts are forwarded to the application. - * @post LFCLK source chosen in ::sd_softdevice_enable will be left running. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void)); - -/**@brief Check if the SoftDevice is enabled. - * - * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled)); - -/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice - * - * This function is only intended to be called when a bootloader is enabled. - * - * @param[in] address The base address of the interrupt vector table for forwarded interrupts. - - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address)); - -/** @} */ - -#endif // NRF_SDM_H__ - -/** - @} -*/ diff --git a/components/softdevice/s310/headers/nrf_soc.h b/components/softdevice/s310/headers/nrf_soc.h deleted file mode 100644 index 752778a..0000000 --- a/components/softdevice/s310/headers/nrf_soc.h +++ /dev/null @@ -1,993 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ -/** - * @defgroup nrf_soc_api SoC Library API - * @{ - * - * @brief APIs for the SoC library. - * - */ - -#ifndef NRF_SOC_H__ -#define NRF_SOC_H__ - -#include -#include -#include "nrf_svc.h" -#include "nrf51.h" -#include "nrf51_bitfields.h" -#include "nrf_error_soc.h" - -/**@addtogroup NRF_SOC_DEFINES Defines - * @{ */ - -/**@brief The number of the lowest SVC number reserved for the SoC library. */ -#define SOC_SVC_BASE (0x20) -#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B) - -/**@brief Guranteed time for application to process radio inactive notification. */ -#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62) - -/**@brief The minimum allowed timeslot extension time. */ -#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200) - -#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */ -#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */ -#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */ - -#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */ -#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events. */ -#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */ -#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler. */ - -#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */ -#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */ - -#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */ - -#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */ - -#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */ - -/**@} */ - -/**@addtogroup NRF_SOC_TYPES Types - * @{ */ - -/**@brief The SVC numbers used by the SVC functions in the SoC library. */ -enum NRF_SOC_SVCS -{ - SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE, - SD_PPI_CHANNEL_ENABLE_SET, - SD_PPI_CHANNEL_ENABLE_CLR, - SD_PPI_CHANNEL_ASSIGN, - SD_PPI_GROUP_TASK_ENABLE, - SD_PPI_GROUP_TASK_DISABLE, - SD_PPI_GROUP_ASSIGN, - SD_PPI_GROUP_GET, - SD_FLASH_PAGE_ERASE, - SD_FLASH_WRITE, - SD_FLASH_PROTECT, - SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE, - SD_MUTEX_ACQUIRE, - SD_MUTEX_RELEASE, - SD_NVIC_ENABLEIRQ, - SD_NVIC_DISABLEIRQ, - SD_NVIC_GETPENDINGIRQ, - SD_NVIC_SETPENDINGIRQ, - SD_NVIC_CLEARPENDINGIRQ, - SD_NVIC_SETPRIORITY, - SD_NVIC_GETPRIORITY, - SD_NVIC_SYSTEMRESET, - SD_NVIC_CRITICAL_REGION_ENTER, - SD_NVIC_CRITICAL_REGION_EXIT, - SD_RAND_APPLICATION_POOL_CAPACITY, - SD_RAND_APPLICATION_BYTES_AVAILABLE, - SD_RAND_APPLICATION_GET_VECTOR, - SD_POWER_MODE_SET, - SD_POWER_SYSTEM_OFF, - SD_POWER_RESET_REASON_GET, - SD_POWER_RESET_REASON_CLR, - SD_POWER_POF_ENABLE, - SD_POWER_POF_THRESHOLD_SET, - SD_POWER_RAMON_SET, - SD_POWER_RAMON_CLR, - SD_POWER_RAMON_GET, - SD_POWER_GPREGRET_SET, - SD_POWER_GPREGRET_CLR, - SD_POWER_GPREGRET_GET, - SD_POWER_DCDC_MODE_SET, - SD_APP_EVT_WAIT, - SD_CLOCK_HFCLK_REQUEST, - SD_CLOCK_HFCLK_RELEASE, - SD_CLOCK_HFCLK_IS_RUNNING, - SD_RADIO_NOTIFICATION_CFG_SET, - SD_ECB_BLOCK_ENCRYPT, - SD_RADIO_SESSION_OPEN, - SD_RADIO_SESSION_CLOSE, - SD_RADIO_REQUEST, - SD_EVT_GET, - SD_TEMP_GET, - SVC_SOC_LAST -}; - -/**@brief Possible values of a ::nrf_mutex_t. */ -enum NRF_MUTEX_VALUES -{ - NRF_MUTEX_FREE, - NRF_MUTEX_TAKEN -}; - -/**@brief Possible values of ::nrf_app_irq_priority_t. */ -enum NRF_APP_PRIORITIES -{ - NRF_APP_PRIORITY_HIGH = 1, - NRF_APP_PRIORITY_LOW = 3 -}; - -/**@brief Possible values of ::nrf_power_mode_t. */ -enum NRF_POWER_MODES -{ - NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */ - NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */ -}; - - -/**@brief Possible values of ::nrf_power_failure_threshold_t */ -enum NRF_POWER_THRESHOLDS -{ - NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */ - NRF_POWER_THRESHOLD_V27 /**< 2.7 Volts power failure threshold. */ -}; - - -/**@brief Possible values of ::nrf_power_dcdc_mode_t. */ -enum NRF_POWER_DCDC_MODES -{ - NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */ - NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */ -}; - -/**@brief Possible values of ::nrf_radio_notification_distance_t. */ -enum NRF_RADIO_NOTIFICATION_DISTANCES -{ - NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */ - NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */ - NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */ -}; - - -/**@brief Possible values of ::nrf_radio_notification_type_t. */ -enum NRF_RADIO_NOTIFICATION_TYPES -{ - NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */ - NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */ -}; - -/**@brief SoC Events. */ -enum NRF_SOC_EVTS -{ - NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */ - NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */ - NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */ - NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */ - NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */ - NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */ - NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio signal callback handler return was invalid. */ - NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio session is idle. */ - NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio session is closed. */ - NRF_EVT_NUMBER_OF_EVTS -}; - -/**@} */ - -/**@addtogroup NRF_SOC_TYPES Types - * @{ */ - -/**@brief Represents a mutex for use with the nrf_mutex functions. - * @note Accessing the value directly is not safe, use the mutex functions! - */ -typedef volatile uint8_t nrf_mutex_t; - -/**@brief The interrupt priorities available to the application while the softdevice is active. */ -typedef uint8_t nrf_app_irq_priority_t; - -/**@brief Represents a power mode, used in power mode functions */ -typedef uint8_t nrf_power_mode_t; - -/**@brief Represents a power failure threshold value. */ -typedef uint8_t nrf_power_failure_threshold_t; - -/**@brief Represents a DCDC mode value. */ -typedef uint32_t nrf_power_dcdc_mode_t; - -/**@brief Radio notification distances. */ -typedef uint8_t nrf_radio_notification_distance_t; - -/**@brief Radio notification types. */ -typedef uint8_t nrf_radio_notification_type_t; - -/**@brief The Radio signal callback types. */ -enum NRF_RADIO_CALLBACK_SIGNAL_TYPE -{ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */ - NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */ -}; - -/**@brief The actions requested by the signal callback. - * - * This code gives the SOC instructions about what action to take when the signal callback has - * returned. - */ -enum NRF_RADIO_SIGNAL_CALLBACK_ACTION -{ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current timeslot (maximum execution time for this action is when the extension succeeded). */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */ - NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */ -}; - -/**@brief Radio timeslot high frequency clock source configuration. */ -enum NRF_RADIO_HFCLK_CFG -{ - NRF_RADIO_HFCLK_CFG_DEFAULT, /**< Use the currently selected oscillator as HF clock source during the timeslot (i.e. the source is not specified). */ - NRF_RADIO_HFCLK_CFG_FORCE_XTAL, /**< Force external crystal to be used as HF clock source during whole the timeslot. */ -}; - -/**@brief Radio timeslot priorities. */ -enum NRF_RADIO_PRIORITY -{ - NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */ - NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activites of the SoftDevice stack(s)). */ -}; - -/**@brief Radio timeslot request type. */ -enum NRF_RADIO_REQUEST_TYPE -{ - NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request timeslot as early as possible. This should always be used for the first request in a session. */ - NRF_RADIO_REQ_TYPE_NORMAL /**< Normal timeslot request. */ -}; - -/**@brief Parameters for a request for a timeslot as early as possible. */ -typedef struct -{ - uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ - uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ - uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */ - uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */ -} nrf_radio_request_earliest_t; - -/**@brief Parameters for a normal radio request. */ -typedef struct -{ - uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */ - uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */ - uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */ - uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */ -} nrf_radio_request_normal_t; - -/**@brief Radio request parameters. */ -typedef struct -{ - uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */ - union - { - nrf_radio_request_earliest_t earliest; /**< Parameters for a request for a timeslot as early as possible. */ - nrf_radio_request_normal_t normal; /**< Parameters for a normal radio request. */ - } params; -} nrf_radio_request_t; - -/**@brief Return parameters of the radio timeslot signal callback. */ -typedef struct -{ - uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */ - union - { - struct - { - nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */ - } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */ - struct - { - uint32_t length_us; /**< Requested extension of the timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */ - } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */ - } params; -} nrf_radio_signal_callback_return_param_t; - -/**@brief The radio signal callback type. - * - * @note In case of invalid return parameters, the radio timeslot will automatically end - * immediately after returning from the signal callback and the - * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent. - * @note The returned struct pointer must remain valid after the signal callback - * function returns. For instance, this means that it must not point to a stack variable. - * - * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE. - * - * @return Pointer to structure containing action requested by the application. - */ -typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type); - -/**@brief AES ECB data structure */ -typedef struct -{ - uint8_t key[SOC_ECB_KEY_LENGTH]; /**< Encryption key. */ - uint8_t cleartext[SOC_ECB_CLEARTEXT_LENGTH]; /**< Clear Text data. */ - uint8_t ciphertext[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Cipher Text data. */ -} nrf_ecb_hal_data_t; - -/**@} */ - -/**@addtogroup NRF_SOC_FUNCTIONS Functions - * @{ */ - -/**@brief Initialize a mutex. - * - * @param[in] p_mutex Pointer to the mutex to initialize. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex)); - -/**@brief Attempt to acquire a mutex. - * - * @param[in] p_mutex Pointer to the mutex to acquire. - * - * @retval ::NRF_SUCCESS The mutex was successfully acquired. - * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired. - */ -SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex)); - -/**@brief Release a mutex. - * - * @param[in] p_mutex Pointer to the mutex to release. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex)); - -/**@brief Enable External Interrupt. - * @note Corresponds to NVIC_EnableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was enabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application. - */ -SVCALL(SD_NVIC_ENABLEIRQ, uint32_t, sd_nvic_EnableIRQ(IRQn_Type IRQn)); - -/**@brief Disable External Interrupt. - * @note Corresponds to NVIC_DisableIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt was disabled. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application. - */ -SVCALL(SD_NVIC_DISABLEIRQ, uint32_t, sd_nvic_DisableIRQ(IRQn_Type IRQn)); - -/**@brief Get Pending Interrupt. - * @note Corresponds to NVIC_GetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS. - * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ. - * - * @retval ::NRF_SUCCESS The interrupt is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_GETPENDINGIRQ, uint32_t, sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)); - -/**@brief Set Pending Interrupt. - * @note Corresponds to NVIC_SetPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt is set pending. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_SETPENDINGIRQ, uint32_t, sd_nvic_SetPendingIRQ(IRQn_Type IRQn)); - -/**@brief Clear Pending Interrupt. - * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS. - * - * @retval ::NRF_SUCCESS The interrupt pending flag is cleared. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - */ -SVCALL(SD_NVIC_CLEARPENDINGIRQ, uint32_t, sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)); - -/**@brief Set Interrupt Priority. - * @note Corresponds to NVIC_SetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * @pre Priority is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS. - * @param[in] priority A valid IRQ priority for use by the application. - * - * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application. - */ -SVCALL(SD_NVIC_SETPRIORITY, uint32_t, sd_nvic_SetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t priority)); - -/**@brief Get Interrupt Priority. - * @note Corresponds to NVIC_GetPriority in CMSIS. - * - * @pre IRQn is valid and not reserved by the stack. - * - * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS. - * @param[out] p_priority Return value from NVIC_GetPriority. - * - * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority. - * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application. - */ -SVCALL(SD_NVIC_GETPRIORITY, uint32_t, sd_nvic_GetPriority(IRQn_Type IRQn, nrf_app_irq_priority_t * p_priority)); - -/**@brief System Reset. - * @note Corresponds to NVIC_SystemReset in CMSIS. - * - * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN - */ -SVCALL(SD_NVIC_SYSTEMRESET, uint32_t, sd_nvic_SystemReset(void)); - -/**@brief Enters critical region. - * - * @post Application interrupts will be disabled. - * @sa sd_nvic_critical_region_exit - * - * @param[out] p_is_nested_critical_region 1: If in a nested critical region. - * 0: Otherwise. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_NVIC_CRITICAL_REGION_ENTER, uint32_t, sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)); - -/**@brief Exit critical region. - * - * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter. - * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called. - * - * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_NVIC_CRITICAL_REGION_EXIT, uint32_t, sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)); - -/**@brief Query the capacity of the application random pool. - * - * @param[out] p_pool_capacity The capacity of the pool. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity)); - -/**@brief Get number of random bytes available to the application. - * - * @param[out] p_bytes_available The number of bytes currently available in the pool. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available)); - -/**@brief Get random bytes from the application pool. - * - * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes. - * @param[in] length Number of bytes to take from pool and place in p_buff. - * - * @retval ::NRF_SUCCESS The requested bytes were written to p_buff. - * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available. -*/ -SVCALL(SD_RAND_APPLICATION_GET_VECTOR, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length)); - -/**@brief Gets the reset reason register. - * - * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason)); - -/**@brief Clears the bits of the reset reason register. - * - * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk)); - -/**@brief Sets the power mode when in CPU sleep. - * - * @param[in] power_mode The power mode to use when in CPU sleep. @sa sd_app_evt_wait - * - * @retval ::NRF_SUCCESS The power mode was set. - * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown. - */ -SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(nrf_power_mode_t power_mode)); - -/**@brief Puts the chip in System OFF mode. - * - * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN - */ -SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void)); - -/**@brief Enables or disables the power-fail comparator. - * - * Enabling this will give a softdevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs. - * The event can be retrieved with sd_evt_get(); - * - * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable)); - -/**@brief Sets the power-fail threshold value. - * - * @param[in] threshold The power-fail threshold value to use. - * - * @retval ::NRF_SUCCESS The power failure threshold was set. - * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown. - */ -SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(nrf_power_failure_threshold_t threshold)); - -/**@brief Sets bits in the NRF_POWER->RAMON register. - * - * @param[in] ramon Contains the bits needed to be set in the NRF_POWER->RAMON register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAMON_SET, uint32_t, sd_power_ramon_set(uint32_t ramon)); - -/**@brief Clears bits in the NRF_POWER->RAMON register. - * - * @param ramon Contains the bits needed to be cleared in the NRF_POWER->RAMON register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAMON_CLR, uint32_t, sd_power_ramon_clr(uint32_t ramon)); - -/**@brief Get contents of NRF_POWER->RAMON register, indicates power status of ram blocks. - * - * @param[out] p_ramon Content of NRF_POWER->RAMON register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_RAMON_GET, uint32_t, sd_power_ramon_get(uint32_t * p_ramon)); - -/**@brief Set bits in the NRF_POWER->GPREGRET register. - * - * @param[in] gpregret_msk Bits to be set in the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_msk)); - -/**@brief Clear bits in the NRF_POWER->GPREGRET register. - * - * @param[in] gpregret_msk Bits to be clear in the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_msk)); - -/**@brief Get contents of the NRF_POWER->GPREGRET register. - * - * @param[out] p_gpregret Contents of the GPREGRET register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t *p_gpregret)); - -/**@brief Sets the DCDC mode. - * - * This function is to enable or disable the DCDC periperhal. - * - * @param[in] dcdc_mode The mode of the DCDC. - * - * @retval ::NRF_SUCCESS - * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid. - */ -SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(nrf_power_dcdc_mode_t dcdc_mode)); - -/**@brief Request the high frequency crystal oscillator. - * - * Will start the high frequency crystal oscillator, the startup time of the crystal varies - * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started. - * - * @see sd_clock_hfclk_is_running - * @see sd_clock_hfclk_release - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void)); - -/**@brief Releases the high frequency crystal oscillator. - * - * Will stop the high frequency crystal oscillator, this happens immediately. - * - * @see sd_clock_hfclk_is_running - * @see sd_clock_hfclk_request - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void)); - -/**@brief Checks if the high frequency crystal oscillator is running. - * - * @see sd_clock_hfclk_request - * @see sd_clock_hfclk_release - * - * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running)); - -/**@brief Waits for an application event. - * - * An application event is either an application interrupt or a pended interrupt when the - * interrupt is disabled. When the interrupt is enabled it will be taken immediately since - * this function will wait in thread mode, then the execution will return in the application's - * main thread. When an interrupt is disabled and gets pended it will return to the application's - * thread main. The application must ensure that the pended flag is cleared using - * ::sd_nvic_ClearPendingIRQ in order to sleep using this function. This is only necessary for - * disabled interrupts, as the interrupt handler will clear the pending flag automatically for - * enabled interrupts. - * - * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M0 - * System Control Register (SCR). @sa CMSIS_SCB - * - * @note If an application interrupt has happened since the last time sd_app_evt_wait was - * called this function will return immediately and not go to sleep. This is to avoid race - * conditions that can occur when a flag is updated in the interrupt handler and processed - * in the main loop. - * - * @post An application interrupt has happened or a interrupt pending flag is set. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void)); - -/**@brief Get PPI channel enable register contents. - * - * @param[out] p_channel_enable The contents of the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable)); - -/**@brief Set PPI channel enable register. - * - * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)); - -/**@brief Clear PPI channel enable register. - * - * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register. - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk)); - -/**@brief Assign endpoints to a PPI channel. - * - * @param[in] channel_num Number of the PPI channel to assign. - * @param[in] evt_endpoint Event endpoint of the PPI channel. - * @param[in] task_endpoint Task endpoint of the PPI channel. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint)); - -/**@brief Task to enable a channel group. - * - * @param[in] group_num Number of the channel group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num)); - -/**@brief Task to disable a channel group. - * - * @param[in] group_num Number of the PPI group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num)); - -/**@brief Assign PPI channels to a channel group. - * - * @param[in] group_num Number of the channel group. - * @param[in] channel_msk Mask of the channels to assign to the group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk)); - -/**@brief Gets the PPI channels of a channel group. - * - * @param[in] group_num Number of the channel group. - * @param[out] p_channel_msk Mask of the channels assigned to the group. - * - * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk)); - -/**@brief Configures the Radio Notification signal. - * - * @note - * - The notification signal latency depends on the interrupt priority settings of SWI used - * for notification signal. - * - To ensure that the radio notification signal behaves in a consistent way, always - * configure radio notifications when there is no protocol stack or other SoftDevice - * activity in progress. It is recommended that the radio notification signal is - * configured directly after the SoftDevice has been enabled. - * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice - * will interrupt the application to do Radio Event preparation. - * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have - * to shorten the connection events to have time for the Radio Notification signals. - * - * @param[in] type Type of notification signal. - * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio - * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is - * recommended (but not required) to be used with - * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE. - * - * @param[in] distance Distance between the notification signal and start of radio activity. - * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or - * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used. - * - * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid. - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(nrf_radio_notification_type_t type, nrf_radio_notification_distance_t distance)); - -/**@brief Encrypts a block according to the specified parameters. - * - * 128-bit AES encryption. - * - * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input - * parameters and one output parameter). - * - * @retval ::NRF_SUCCESS - */ -SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)); - -/**@brief Gets any pending events generated by the SoC API. - * - * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned. - * - * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending. - * - * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter. - * @retval ::NRF_ERROR_NOT_FOUND No pending events. - */ -SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id)); - -/**@brief Get the temperature measured on the chip - * - * This function will block until the temperature measurement is done. - * It takes around 50us from call to return. - * - * @note Pan #28 in PAN-028 v 1.6 "Negative measured values are not represented correctly" is corrected by this function. - * - * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees celsius. - * - * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp - */ -SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp)); - -/**@brief Flash Write -* -* Commands to write a buffer to flash -* -* If the SoftDevice is enabled: -* This call initiates the flash access command, and its completion will be communicated to the -* application with exactly one of the following events: -* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. -* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. -* -* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the - * write has been completed -* -* @note -* - This call takes control over the radio and the CPU during flash erase and write to make sure that -* they will not interfere with the flash access. This means that all interrupts will be blocked -* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual -* and the command parameters). -* -* -* @param[in] p_dst Pointer to start of flash location to be written. -* @param[in] p_src Pointer to buffer with data to be written. -* @param[in] size Number of 32-bit words to write. Maximum size is 256 32bit words. -* -* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned. -* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. -* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or more than 256 words. -* @retval ::NRF_ERROR_FORBIDDEN Tried to write to or read from protected location. -* @retval ::NRF_SUCCESS The command was accepted. -*/ -SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * const p_dst, uint32_t const * const p_src, uint32_t size)); - - -/**@brief Flash Erase page -* -* Commands to erase a flash page -* If the SoftDevice is enabled: -* This call initiates the flash access command, and its completion will be communicated to the -* application with exactly one of the following events: -* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed. -* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started. -* -* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the -* erase has been completed -* -* @note -* - This call takes control over the radio and the CPU during flash erase and write to make sure that -* they will not interfere with the flash access. This means that all interrupts will be blocked -* for a predictable time (depending on the NVMC specification in nRF51 Series Reference Manual -* and the command parameters). -* -* -* @param[in] page_number Pagenumber of the page to erase -* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. -* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page. -* @retval ::NRF_ERROR_BUSY The previous command has not yet completed. -* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a protected page. -* @retval ::NRF_SUCCESS The command was accepted. -*/ -SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number)); - - -/**@brief Flash Protection set - * - * Commands to set the flash protection registers PROTENSETx - * - * @note To read the values in PROTENSETx you can read them directly. They are only write-protected. - * - * @param[in] protenset0 Value to be written to PROTENSET0. - * @param[in] protenset1 Value to be written to PROTENSET1. - * - * @retval ::NRF_ERROR_FORBIDDEN Tried to protect the SoftDevice. - * @retval ::NRF_SUCCESS Values successfully written to PROTENSETx. - */ -SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t protenset0, uint32_t protenset1)); - -/**@brief Opens a session for radio requests. - * - * @note Only one session can be open at a time. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot - * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed - * by the application. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0 - * interrupt occurs. - * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO - * interrupt occurs. - * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This - * implies that none of the sd_* API calls can be used from p_radio_signal_callback(). - * - * @param[in] p_radio_signal_callback The signal callback. - * - * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer. - * @retval ::NRF_ERROR_BUSY If session cannot be opened. - * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback)); - -/**@brief Closes a session for radio requests. - * - * @note Any current radio timeslot will be finished before the session is closed. - * @note If a radio timeslot is scheduled when the session is closed, it will be canceled. - * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED - * event is received. - * - * @retval ::NRF_ERROR_FORBIDDEN If session not opened. - * @retval ::NRF_ERROR_BUSY If session is currently being closed. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void)); - -/**@brief Requests a radio timeslot. - * - * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST - * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type - * @ref NRF_RADIO_REQ_TYPE_EARLIEST. - * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by - * p_request->distance_us and is given relative to the start of the previous timeslot. - * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event. - * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event. - * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths. - * @note If an opportunity for the first radio timeslot is not found before 100ms after the call to this - * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent. - * The application may then try to schedule the first radio timeslot again. - * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START). - * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS. - * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us. - * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the - * specified radio timeslot start, but this does not affect the actual start time of the timeslot. - * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency - * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is - * guaranteed to be clocked from the external crystal. - * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral - * during the radio timeslot. - * - * @param[in] p_request Pointer to the request parameters. - * - * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE. - * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid. - * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid. - * @retval ::NRF_SUCCESS Otherwise. - */ - SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t * p_request )); - -/**@} */ - -#endif // NRF_SOC_H__ - -/**@} */ diff --git a/components/softdevice/s310/headers/nrf_svc.h b/components/softdevice/s310/headers/nrf_svc.h deleted file mode 100644 index 49f1425..0000000 --- a/components/softdevice/s310/headers/nrf_svc.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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 NRF_SVC__ -#define NRF_SVC__ - -#ifdef SVCALL_AS_NORMAL_FUNCTION -#define SVCALL(number, return_type, signature) return_type signature -#else - -#ifndef SVCALL -#if defined (__CC_ARM) -#define SVCALL(number, return_type, signature) return_type __svc(number) signature -#elif defined (__GNUC__) -#define SVCALL(number, return_type, signature) \ - _Pragma("GCC diagnostic ignored \"-Wunused-function\"") \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \ - __attribute__((naked)) static return_type signature \ - { \ - __asm( \ - "svc %0\n" \ - "bx r14" : : "I" (number) : "r0" \ - ); \ - } \ - _Pragma("GCC diagnostic pop") -#elif defined (__ICCARM__) -#define PRAGMA(x) _Pragma(#x) -#define SVCALL(number, return_type, signature) \ -PRAGMA(swi_number = number) \ - __swi return_type signature; -#else -#define SVCALL(number, return_type, signature) return_type signature -#endif -#endif // SVCALL - -#endif // SVCALL_AS_NORMAL_FUNCTION -#endif // NRF_SVC__ diff --git a/components/softdevice/s310/headers/softdevice_assert.h b/components/softdevice/s310/headers/softdevice_assert.h deleted file mode 100644 index 89e1d11..0000000 --- a/components/softdevice/s310/headers/softdevice_assert.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) Nordic Semiconductor ASA - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * 2. 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. - * - * 3. Neither the name of Nordic Semiconductor ASA nor the names of other - * contributors to this software may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * 4. This software must only be used in a processor manufactured by Nordic - * Semiconductor ASA, or in a processor manufactured by a third party that - * is used in combination with a processor manufactured by Nordic Semiconductor. - * - * - * 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 HOLDER 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. - * - */ - -/** @brief Utilities for verifying program logic - */ - -#ifndef SOFTDEVICE_ASSERT_H_ -#define SOFTDEVICE_ASSERT_H_ - -#include - -/** @brief This function handles assertions. - * - * - * @note - * This function is called when an assertion has triggered. - * - * - * @param line_num The line number where the assertion is called - * @param file_name Pointer to the file name - */ -void assert_softdevice_callback(uint16_t line_num, const uint8_t *file_name); - - -/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */ -/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \ -/** @brief Check intended for production code - * - * Check passes if "expr" evaluates to true. */ -#define ASSERT(expr) \ -if (expr) \ -{ \ -} \ -else \ -{ \ - assert_softdevice_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \ - /*lint -unreachable */ \ -} - -#endif /* SOFTDEVICE_ASSERT_H_ */ diff --git a/components/softdevice/s310/hex/s310_nrf51422_3.0.0_softdevice.hex b/components/softdevice/s310/hex/s310_nrf51422_3.0.0_softdevice.hex deleted file mode 100644 index c48d2be..0000000 --- a/components/softdevice/s310/hex/s310_nrf51422_3.0.0_softdevice.hex +++ /dev/null @@ -1,7295 +0,0 @@ -:020000040000FA -:10000000C0070000D1060000D1000000B1060000CA -:1000100000000000000000000000000000000000E0 -:100020000000000000000000000000005107000078 -:100030000000000000000000DB000000E500000000 -:10004000EF000000F9000000030100000D010000B6 -:1000500017010000210100002B0100003501000004 -:100060003F01000049010000530100005D01000054 -:1000700067010000710100007B01000085010000A4 -:100080008F01000099010000A3010000AD010000F4 -:10009000B7010000C1010000CB010000D501000044 -:1000A000DF010000E9010000F3010000FD01000094 -:1000B00007020000110200001B02000025020000E0 -:1000C0001FB5C046C04600F0EFFA04B00FB41FBD24 -:1000D00008205A49096809580847382057490968CB -:1000E000095808473C2055490968095808474020E5 -:1000F0005249096809580847442050490968095875 -:10010000084748204D490968095808474C204B4981 -:10011000096809580847502048490968095808479C -:100120005420464909680958084758204349096836 -:10013000095808475C204149096809580847602068 -:100140003E4909680958084764203C49096809582C -:100150000847682039490968095808476C20374919 -:100160000968095808477020344909680958084740 -:100170007420324909680958084778202F490968CE -:10018000095808477C202D490968095808478020EC -:100190002A490968095808478420284909680958E4 -:1001A0000847882025490968095808478C202349B1 -:1001B00009680958084790202049096809580847E4 -:1001C00094201E4909680958084798201B49096866 -:1001D000095808479C201949096809580847A02070 -:1001E0001649096809580847A4201449096809589C -:1001F0000847A8201149096809580847AC200F4949 -:10020000096809580847B0200C4909680958084787 -:10021000B4200A49096809580847B82007490968FD -:1002200009580847BC2005490968095808470000D3 -:1002300003480449024A034B7047000000000020B5 -:10024000C0070000C00700000122D84B5A6000BF61 -:10025000D74A1268002AFBD0016000BFD44A126856 -:10026000002AFBD00022D14B5A6000BFD04A12684E -:10027000002AFBD07047F0B505460E46174600240D -:1002800006E0A200B158A2005019FFF7DDFF641C80 -:10029000BC42F6D30020F0BD0120C043C549086030 -:1002A000401048607047014601229204086890425D -:1002B00001D9102070470020FCE7F0B505460C4638 -:1002C0001646002706E028462168FFF7BDFF2D1DD2 -:1002D000241D7F1CB742F6D3F0BD70B505460C4611 -:1002E0002E460BE0304600F075F9FF2C01D80024B3 -:1002F00001E0FF3C013C012080023618002CF1D1C6 -:1003000070BD0146012292044868904201D909203B -:100310007047A9484069401C01D10F20F8E7002030 -:10032000F6E7FEB504462068030000F037FA05043E -:100330002B4249598B00201DFFF7E3FF0546002D96 -:1003400001D02846FEBDFFF7A7FF0120C00200F044 -:1003500041F9042221469948FFF78DFF002801D07A -:100360000320EFE708222146944800F06DF90028A9 -:1003700006D1002192480068FFF766FF00F00CF9F3 -:100380000320DFE7A768E6686068019031463846D9 -:10039000FFF7A3FF324638460199FFF78EFFB20000 -:1003A0003846019900F050F9002800D1CAE703202F -:1003B000C8E700F0E3F9834800688349086041E03A -:1003C00060680190E668A0680090B200009901980A -:1003D00000F03AF90746002F00D1B3E70E20B1E74D -:1003E000201DFFF760FF0546002D01D02846A9E734 -:1003F0006068002807D1FFF74FFF0320800200F05C -:10040000E9F800F0C9F8FFF747FF0120C00200F04B -:10041000E1F8042221466948FFF72DFF002801D0AA -:1004200003208FE708222146644800F00DF90028D8 -:1004300006D1002162480068FFF706FF00F0ACF823 -:1004400003207FE700BF00207CE770B505460C461F -:10045000182D04D12068FFF764FF206002E001201E -:10046000206000BF00BF70BDF0B589B05248406940 -:1004700003905248806881000398081802900398FE -:10048000000B01900121090302984018401E000B47 -:1004900000900124002520462946019A00F0C4F866 -:1004A0000022401E91410791069001260027304608 -:1004B0003946009A00F0B8F80022401E914105919B -:1004C0000490049BDB43059AD2430698184307998E -:1004D00011430791069037490698086007984860CD -:1004E00009B0F0BD70B53448446934488568466841 -:1004F000AA003146204600F0A7F8002801D00020CD -:1005000070BD0120FCE72D484068002801D0012083 -:1005100000E000200546FFF7E5FF002807D0FFF7C1 -:10052000BBFE0320800200F055F800F035F8FFF71D -:100530009BFF002D0ED020484669204884684768FC -:1005400021463046FFF7C9FE224639463046FFF7BE -:10055000B4FE00BF00F020F810B5184844681A48EF -:100560000460204600F0DCF810BD15480068006803 -:10057000401C01D100BFFEE710480068002802D0EF -:10058000042806D101E0FFF7BEFFFFF7E5FF00BF3B -:10059000FEE700BF00BFFEE7BFF34F8F0B480C49DB -:1005A000C860BFF34F8F00BFFEE7000000E50140C9 -:1005B00000E40140000600400010001000080000A8 -:1005C000B8070000BC070000000000200400FA0586 -:1005D00000ED00E010B50146104B1A6808460223F2 -:1005E0000F4C636000BF0F4B1B68002BFBD0531CEC -:1005F00004D0904202D20A4B186101E0084B986087 -:1006000000BF084B1B68002BFBD00023044C636029 -:1006100000BF044B1B68002BFBD010BD0010001066 -:1006200000E5014000E4014010B5202A04DB01464A -:10063000203A9140002010BD914020239C1A03468F -:10064000E3401943904010BD034610B50B439B0790 -:100650000FD1042A0DD308C810C9121FA342F8D025 -:1006600018BA21BA884201D9012010BD0020C04328 -:1006700010BD002A03D0D30703D0521C07E000208E -:1006800010BD03780C78401C491C1B1B07D1037854 -:100690000C78401C491C1B1B01D1921EF1D118463D -:1006A00010BD70477047704710B500F007F810BDD7 -:1006B000014B1B68DB6818470000002019481A49E5 -:1006C0007047FFF7FBFFFFF7FBFC00BD20BFFDE716 -:1006D0001649174C24688C420BD1164B1B68994263 -:1006E0000CD1154B154A1360186810498842EDD09B -:1006F0000AE0134880F30888124B18470F4A13602A -:1007000018680A498842E1D080F308880E49884277 -:1007100004DD0E48026802210A4302605B68184744 -:100720000346DFE7C0070000C0070000FFFFFFFF30 -:10073000000C000014100010001000000000002049 -:10074000000400206B05000000200020240500406C -:100750000D48704502D1EFF3098101E0EFF3088104 -:10076000886902380078182802D1C046074A104725 -:10077000074A12682C3212681047000000B5054B7A -:10078000054A9B58984700BDFDFFFFFF4B04000042 -:1007900000000020001000000400000030B4744687 -:1007A000641E2578641CAB4204D3635D5B00E318D0 -:1007B00030BC18471D46F8E7000C00000010000090 -:10100000C01900201DCC01002514000083CB010075 -:1010100000000000000000000000000000000000D0 -:101020000000000000000000000000008DCC010066 -:10103000000000000000000025140000251400003E -:10104000F9CC0100FFCC010025140000251400009C -:1010500025140000251400002514000025140000AC -:1010600005CD010025140000251400000BCD010062 -:101070002514000011CD010017CD01001DCD010088 -:10108000251400002514000025140000251400007C -:10109000251400002514000025140000251400006C -:1010A00023CD010029CD01002514000025140000E6 -:1010B000251400002514000025140000251400004C -:1010C00000F002F81BF08BFD0CA030C80838241883 -:1010D0002D18A246671EAB4654465D46AC4201D170 -:1010E0001BF07DFD7E460F3E0FCCB64601263342F7 -:1010F00000D0FB1AA246AB4633431847A4BE0100FA -:10110000D4BE0100103A02D378C878C1FAD8520789 -:1011100001D330C830C101D504680C6070470000AD -:101120000023002400250026103A01D378C1FBD803 -:10113000520700D330C100D50B6070471FB5C046C1 -:10114000C0461BF0EEFC04B00FB41FBD40BA7047A0 -:10115000C0BA7047F0B44046494652465B460FB4A9 -:1011600002A0013001B50648004700BF01BC864619 -:101170000FBC8046894692469B46F0BC70470000F3 -:10118000C110000040BA7047C0BA70478269024976 -:101190008161024810447047A11100000100000065 -:1011A00001B41EB400B501F08EFC01B4019886466E -:1011B00001BC01B01EBD000040BA7047C0BA704704 -:1011C000401E00BF00BF00BF00BF00BF00BF00BF88 -:1011D00000BF00BF00BF00BF00BFF1D170470000DB -:1011E00070B505460C46164602E00FCC0FC5103E02 -:1011F000102EFAD2082E02D303CC03C5083E042ECB -:1012000007D301CC01C5361F03E021782970641C87 -:101210006D1C761EF9D270BD10B572B600F0DCF808 -:1012200000280BD000F0ACF901F091FF01F006FDB1 -:101230006E490020C86288626D49086062B600206D -:1012400010BDF3B5002501200007C06A81B0C0437E -:101250000006000E04D167480068401C00D101253B -:1012600072B600F0B9F8002802D062B60820FEBDC0 -:10127000FFF770FF00F08AF95F4B604E00211A689B -:10128000CA40D2071FD00246CA40D20718D14AB27C -:10129000002A07DA1407240F083CA408A400A419A4 -:1012A000E46904E09408564FA400E4192468920706 -:1012B000D20ED440A204120E012A04D0032A02D076 -:1012C00062B65048FEBD491C2029D8D301980300BE -:1012D0001BF06AFD142123232323232323230B0D37 -:1012E0000F11131F1517191B1D2E002416E00124C2 -:1012F00014E0022412E0032410E004240EE0082489 -:101300000CE009240AE00A2408E00B2406E00C247F -:1013100004E0052402E0072400E00624F06901212E -:101320000002000AC9070843F061002D04D009E05B -:1013300062B601200003FEBD2C4D3348E86200F088 -:1013400025F9A8622A4931480860314902980860A5 -:1013500000F01CF9214601F058FC01F0BCFE03F03E -:10136000EBFC03F05BFB019800F0B8F8040062B6F8 -:1013700003D0FFF751FF2046FEBD0020FEBD10B593 -:10138000044600F029F8002800D001202070002039 -:1013900010BD204908600020704710B50C46102889 -:1013A00008D011280BD012280CD013280ED0012001 -:1013B000086010BD61682068FFF743FF0AE0FFF78F -:1013C0002BFF07E02068FFF7DAFF03E011492068F0 -:1013D00008600020206010BD05480C490068884264 -:1013E00001D1012070470020704700000005004037 -:1013F0001C0000200010001000E100E000ED00E003 -:1014000000E400E001100000401A0000BEBAFECA6D -:1014100018000020040000200E4A12680C498A427D -:101420000AD118470B4A1268094B9A4204D101B5F8 -:1014300001F040FB03BC8E4607490968095808477C -:1014400006480749054A064B7047000000000000A7 -:10145000BEBAFECA1C00002004000020C0190020F3 -:10146000C019002010B50146202209481BF0F8F9E8 -:1014700007490020C877084610BD06490120486189 -:101480000548064A0168914201D100210160704778 -:10149000D4010020000500401C000020BEBAFECA96 -:1014A0008307FF22DB0E9A408907090E9940002826 -:1014B0000BDA0007000F083883083B489B001B1815 -:1014C000D86990430843D8617047830837489B0028 -:1014D0001B181868904308431860704710B5344AC9 -:1014E0000446D06980B23C2815D03249088CC0B27D -:1014F000012812D1888C00070FD1088D0006000F3B -:1015000001280AD1888D0006000F06D1D0692A492A -:10151000000C884201D1022010BD00210120FFF7FC -:10152000BFFF00211820FFF7BBFF00210B20FFF7B2 -:10153000B7FF02211920FFF7B3FF02210D20FFF7AB -:10154000AFFF02210E20FFF7ABFF02210F20FFF7B4 -:10155000A7FF0221C81FFFF7A3FF03211620FFF7F3 -:101560009FFF03211520FFF79BFF204600F0EAFEB6 -:10157000204600F029F8002010BD65210180704749 -:1015800010B500F0EEFE00F032F810BD0B487047C9 -:1015900010B5C02802D300F037FD10BD00F0E9FE01 -:1015A00010BD70477047704700ED00E000E400E0B8 -:1015B00040000010C00F00F0FFFF000003F90043DF -:1015C00010B508F0E6FE10BD10B5FD480178002901 -:1015D0000CD101210170FB484173203804F09AFAC4 -:1015E000F94804F0E7FA012005F070FF10BD10B5CE -:1015F000F3480178002907D000210170F1484173B8 -:1016000004F0BAFA04F09CFB10BD10B5EC48007869 -:10161000002808D004F0B0FA04F092FB002005F096 -:1016200055FF002010BD022010BDF8B516460C462F -:10163000054600F0CCFC002809D1204600F0C7FC8C -:10164000002804D1304600F0C2FC002801D0072059 -:10165000F8BD304606F0DFFC6946009048782070FF -:1016600009782970002801D00020F8BD0520F8BDB8 -:1016700070B50446D5481D460078401E844201DD01 -:10168000D34870BD072A02D9D1480A3870BD204618 -:1016900006F0D8F8002805D12946204606F04AF978 -:1016A0000028F3D001218903084370BD10B5C74954 -:1016B0000978491E884201DDC54810BD06F064F96D -:1016C0000028FAD001218903084310BD10B5BF4995 -:1016D0000978491E884201DDBD4810BD05F0C6FBF2 -:1016E0000028FAD001218903084310BD10B5B7497D -:1016F0000978491E884201DDB54810BD06F056F94B -:101700000028FAD001218903084310BD10B506F066 -:101710008CF9002802D001218903084310BD70B55F -:101720000446AA480E4600781546401E844201DD54 -:10173000A74870BD104600F04AFC002801D00720E1 -:1017400070BD2B4632460021204604F072FE502820 -:1017500003D001218903084370BD002070BD70B51E -:1017600004469A480E4600781546401E844201DD24 -:10177000974870BD104600F02AFC002801D00720D1 -:1017800070BD2B463246A021204604F052FE502860 -:1017900003D001218903084370BD002070BDF8B556 -:1017A00004468A481E4600780F46401E154684426D -:1017B00001DD8748F8BD104600F009FC002801D083 -:1017C0000720F8BD33462A463946204605F041FC3D -:1017D000502803D0012189030843F8BD0020F8BD3B -:1017E00010B5044600F0F3FB002801D0072010BD1F -:1017F000204605F097FC0028F9D001218903084311 -:1018000010BD10B505F09AFC002802D00121890313 -:10181000084310BD70B505466C480C460078401E64 -:10182000854201DD6A4870BD084600F0D0FB002803 -:1018300001D0072070BD284606F029F9207000204D -:1018400070BD10B506F001FA002010BD70B5044659 -:101850000D46072802D95E480A3870BD084600F0D8 -:10186000B6FB002801D0072070BD2946204605F0B0 -:101870002CFA002070BD10B5544A1278521E9042C6 -:1018800001DD534810BD05F016F8002010BD70B5FD -:1018900005464E480C460078401E854201DD4C4806 -:1018A00070BD084600F093FB002801D0072070BDF2 -:1018B000284605F00FF82070002070BD10B5434B8E -:1018C0001B785B1E984201DD414810BD04F0D9FF32 -:1018D000002010BD10B53D4B1B785B1E984201DD0A -:1018E0003B4810BD05F00FF8002010BD10B5374A79 -:1018F0001278521E904201DD354810BD05F03EFFC2 -:10190000002010BD70B5054630480C460078401EDA -:10191000854201DD2E4870BD084600F058FB0028C6 -:1019200001D0072070BD284605F043FF208000202D -:1019300070BD38B5254C2478641EA04201DD2448D2 -:1019400038BD6C462170090A6170A270E370694667 -:1019500005F008FF0028F3D001218903084338BDB2 -:10196000F8B5074619481C4600781546401E0E4635 -:10197000874201DD1648F8BD084600F028FB002824 -:1019800009D1284600F023FB002804D1204600F0AE -:101990001EFB002801D00720F8BD6946384605F037 -:1019A000BFFE6846017840780002084330806846F0 -:1019B000807828706846C07820700020F8BD00004C -:1019C0002000002014020020C11500009400002017 -:1019D0003340000010B5FC4A1278521E904201DDDF -:1019E000FA4810BD05F0F5FE002010BD10B5F64A0E -:1019F0001278521E904201DDF44810BD05F0E4FE5D -:101A0000002010BD10B5F04A1278521E904201DD40 -:101A1000EE4810BD05F0E2FE002010BD10B5EA4A08 -:101A20001278521E904201DDE84810BD05F0DDFE3F -:101A3000002010BD70B50546E3480C460078401EF6 -:101A4000854201DDE14870BD084600F0C0FA00287B -:101A500001D0072070BD284605F0CDFE2070002083 -:101A600070BD10B5D84A1278521E904201DDD74899 -:101A700010BD05F0A3FE002010BD70B50C46054654 -:101A800000F0A5FA002801D0072070BD21462846A5 -:101A900006F0E2F80028F8D001218903084370BD60 -:101AA00070B505460C46084600F091FA002801D0B2 -:101AB000072070BD2146284606F005F90028F8D019 -:101AC00001218903084370BD10B505F0FEFD002813 -:101AD00002D001218903084310BD10B505F0FEFDB9 -:101AE000002010BD10B5044600F071FA002801D0A6 -:101AF000072010BD05F0F7FD2070002010BD7CB55B -:101B00000546B148164600780C46401E854201DD68 -:101B1000AE487CBD084600F05AFA002801D00720E4 -:101B20007CBD21786846017061784170A178817030 -:101B3000E178C17006716946284605F025FB00284A -:101B4000EED00121890308437CBD08B59E4B1B786C -:101B50005B1E984201DD9D4808BD6B4619705A70A6 -:101B6000694605F0F5FA0028F6D0012189030843FB -:101B700008BD10B5944C2478641EA04201DD934842 -:101B800010BD05F029FB002010BD10B505F01AFBB3 -:101B9000002010BD38B5044600F019FA002801D025 -:101BA000072038BD684605F010FB6946087849787B -:101BB000090201432180002038BD70B505460C465E -:101BC000084600F004FA002801D0072070BD214625 -:101BD000284606F078FB0028F8D001218903084345 -:101BE00070BD70B505460C46084600F0F0F90028B7 -:101BF00001D0072070BD2146284606F070FB002862 -:101C0000F8D001218903084370BD10B56E4A1278DF -:101C1000521E904201DD6D4810BD06F06EFB00289B -:101C2000FAD001218903084310BD10B5664C247811 -:101C3000641EA04201DD654810BD06F06DFB002862 -:101C4000FAD001218903084310BD70B505460C4642 -:101C5000084600F0BCF9002801D0072070BD2146DD -:101C6000284606F041FC0028F8D0012189030843EA -:101C700070BD70B505460C46084600F0A8F900286E -:101C800001D0072070BD2146284606F04BFC0028F5 -:101C9000F8D001218903084370BD70B505460C4694 -:101CA000084600F094F9002801D0072070BD2146B5 -:101CB000284606F04AFC002070BD10B506F05BFC1B -:101CC000002802D001218903084310BD70B50C46DD -:101CD000054600F07CF9002804D1204600F077F991 -:101CE000002801D0072070BD2146284606F08AFC56 -:101CF000002070BD70B506463348144600780D4686 -:101D0000401E864201DD314870BD002D04D00846DA -:101D100000F05DF9002806D1002C06D0204600F026 -:101D200056F9002801D0072070BD002D03D02946A8 -:101D3000304605F099FA002C03D02146304605F0D4 -:101D4000D7FA002070BD70B506461F4814460078CB -:101D50000D46401E864201DD1C4870BD002D04D09A -:101D6000084600F034F9002806D1002C06D02046A1 -:101D700000F02DF9002801D0072070BD002D03D000 -:101D80002946304605F095FA002C03D0214630460E -:101D900005F0C3FA002070BD10B504460C48007869 -:101DA000002817D003F0E8FE03F0CAFF204605F034 -:101DB0001DFC002810D0044920780870002005F090 -:101DC00085FB002010BD000094000020334000007F -:101DD000200000200220F5E70720F3E710B50446B5 -:101DE00000F0F5F8002801D00720EBE705F07EFCB5 -:101DF00020700020E6E710B5044600F0E8F800285F -:101E000001D00720DEE705F076FC20700020D9E73E -:101E100070B5054676480C460078401E854201DDC7 -:101E2000744870BD084600F0D2F8002801D00720A1 -:101E300070BD284605F065FC2070002070BD70B5AF -:101E400005466B480C460078401E854201DD694816 -:101E500070BD084600F0BBF8002801D0072070BD17 -:101E6000284605F054FC2070002070BD10B504F029 -:101E7000EDFC0020A6E710B504F0EEFC0020A1E781 -:101E800010B5044600F0A3F8002801D0072099E718 -:101E900059480021425C6254491CC9B20B29F9D34C -:101EA00000208FE710B5044600F091F8002801D01B -:101EB000072087E74E48B221007820700820607024 -:101EC0000020A070E170362121716071F520A071B1 -:101ED0000120E071002075E7FFB5062581B01E46A0 -:101EE00017460C46002904D0084600F070F8002878 -:101EF0000DD1002F04D0384600F069F8002806D133 -:101F0000002E07D0304600F062F8002802D00720EB -:101F100005B0F0BD0198002804D0012806D00228A1 -:101F200008D109E0207803F03FFF02E003F040FF12 -:101F3000207000252846EBE7207806F06AFBF8E7DA -:101F4000FFB5062581B01E4617460C46002904D071 -:101F5000084600F03CF800280DD1002F04D0384688 -:101F600000F035F8002806D1002E06D0304600F0EB -:101F70002EF8002801D00720CAE70198002804D0D5 -:101F8000012811D002280DD119E0002528461B4E4A -:101F9000256004E0297800F0F5FF6D1C2060B54253 -:101FA000F8D300252846B3E7154822788105002A92 -:101FB000826A02D00A438262F3E78A43FBE7207811 -:101FC00006F032FBEDE710B50AF08BFCFAE60028CC -:101FD00009D00A49884206D301214907884204D31F -:101FE0000849884201D20120704700207047000054 -:101FF000940000203340000096CE010000D0010084 -:1020000000050040401A002010B5C0380C460300FF -:102010001AF0CAFE4021242933373B3F434A515A24 -:102020005F62676D727A82888D979DA3A9AFB5BAFA -:10203000C0C6CBEFF3F7FEEAE9E8E7E6E5E4E3E262 -:10204000E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2F8 -:10205000D1D1D0D1CFD1FFF7D8FA71E1204607C84E -:10206000FFF7E3FA6CE1207BC3B2207AC2B2207999 -:10207000C1B22078FFF7FCFA62E12078FFF716FB87 -:102080005EE12078FFF722FB5AE12078FFF72EFB74 -:1020900056E12078FFF73AFB52E12079A268C1B2FD -:1020A0002078FFF73CFB4BE12079A268C1B2207891 -:1020B000FFF755FB44E1207BA268C3B2A08881B240 -:1020C0002078FFF76CFB3BE120786168FFF7A2FB0B -:1020D00036E1FFF7B6FB33E120786168FFF7B6FB26 -:1020E0002EE12079C1B22078FFF7C5FB28E12078E6 -:1020F0006168FFF7CCFB23E1207AC2B22079C1B23C -:102100002078FFF7DBFB1BE1207AC2B22079C1B255 -:102110002078FFF7DFFB13E1A08881B22078FFF77A -:10212000E5FB0DE120786168FFF7ECFB08E1207B1F -:10213000C3B2207AC2B2A08881B22078FFF7F9FB3F -:10214000FEE0211D0EC92078FFF70AFCF8E0A08808 -:1021500081B22078FFF73EFCF2E02079C1B220780E -:10216000FFF744FCECE02079C1B22078FFF74AFC8D -:10217000E6E02079C1B22078FFF750FCE0E020785B -:102180006168FFF757FCDBE02079C1B22078FFF7E8 -:1021900068FCD5E02079C1B22068FFF76EFCCFE083 -:1021A00020786168FFF77CFCCAE02078FFF78CFCA0 -:1021B000C6E0C0E0B9E0C4E0B3E0ACE0A5E09FE079 -:1021C00098E092E08CE086E07BE074E06EE068E00E -:1021D00064E05FE05AE055E04AE046E040E03AE083 -:1021E00035E030E02BE025E01AE011E009E004E002 -:1021F000FFE72078FFF771FCA2E02068FFF772FC90 -:102200009EE0207A6168C2B22078FFF778FC97E000 -:10221000207AC2B22079C1B22078FFF796FC8FE015 -:10222000207BC3B2207AC2B22079C1B22078FFF7F6 -:10223000A0FC85E0208880B2FFF7A7FC80E0206842 -:10224000FFF7A8FC7CE02068FFF7C8FD78E0206875 -:10225000FFF7D1FD74E020786168FFF7D9FD6FE0EA -:1022600020786168FFF7EBFD6AE0FFF7FFFD67E0AC -:10227000207BC3B2207AC2B22079C1B22078FFF7A6 -:10228000FAFD5DE02068FFF7FBFD59E02068FFF7ED -:1022900009FE55E02068FFF7A3FA51E0FFF7B1FA15 -:1022A0004EE020786168FFF788FC49E0207861689B -:1022B000FFF797FC44E02079C1B22078FFF7A5FC36 -:1022C0003EE0207BC3B2207AC2B22079C1B220782E -:1022D000FFF7ABFC34E020786168FFF7B6FC2FE035 -:1022E00020786168FFF7C5FC2AE020786168FFF775 -:1022F000D4FC25E0A08881B22078FFF7DEFC1FE047 -:1023000061682068FFF7E2FC1AE02078A268616843 -:10231000FFF7F0FC14E02078A2686168FFF713FD76 -:102320000EE02068FFF738FD0AE0211D0EC9207875 -:10233000FFF7D2FD04E0211D0EC92078FFF700FE53 -:10234000206010BD70B505462D4C07202070A01CE4 -:10235000FFF713F95920A0802946204608F073FFA3 -:1023600070BD10B508F078FF25490020891E08705F -:1023700010BDF8B5224E0446B61E307801270D4632 -:10238000002807D0204660380B2808D8204609F0DE -:1023900017FB2BE0602CF9D01A480860F8BD2046E6 -:1023A0006C38032803D8204609F04BFB1EE020467A -:1023B00070381F2803D8204608F07AFC16E0204623 -:1023C00090380F2803D8204608F00FFD0EE0204675 -:1023D000A0380F2803D8204608F05CFD06E0204610 -:1023E000B0380F2804D8204600F0DEFD286000E059 -:1023F0002F60602CD2D128680028CFD13770F8BD6B -:10240000240000200130000001202549C00308609D -:1024100024490020087007202349C00588607047C0 -:1024200070B5204D04462878A04207D0002C05D076 -:10243000002803D01DA14D201AF09DFB2878A04252 -:102440000ED000211F4A18482C70002C1BD01E4BA8 -:10245000012C06D0022C0DD014A168201AF08BFBA1 -:1024600070BD116002211160536103210906816072 -:10247000416070BD11600321116053610121C905E4 -:102480008160416070BD116011600721C9058160E4 -:1024900070BD10B505A171201AF06DFB10BD0000D4 -:1024A00080E100E02A00002000F5014068616C5CDA -:1024B0007372635C68616C5F63636D5F6161722EF0 -:1024C0006300000000F500402402002030B4012128 -:1024D000BD48C9020160CD1005604A030260BB48D7 -:1024E00003681B021B0A036004680023240A2402F9 -:1024F0000460B7480468240A24020460B548012433 -:1025000044608460B44C23606360A360B34B196083 -:102510001D601A60B24B19601A600121016030BC65 -:10252000704710B40121A848CA0202600B02036080 -:102530000C060460A74841608160AA4841680029F0 -:10254000FCD1A5490020086048608860A34802606B -:102550000360046010BC70470121A048C9020160FB -:10256000C91001607047002805D0012805D0022855 -:1025700005D19D4870479D4870479D48704710B5EC -:102580009CA18C201AF0F7FA002010BD70B5002134 -:102590009F4CA04DA04A904B002808D001281DD088 -:1025A000022822D093A1B4201AF0E5FA70BD0120D0 -:1025B0000004A060A86011601960984BC2039A6083 -:1025C000974A9060804A00121060964801608748E0 -:1025D0000160954801609548017070BD012040047C -:1025E000A060A8605160596070BD01208004A060A7 -:1025F000A8609160996070BDF8B59446844A764FA2 -:10260000844D00240126002808D0012832D0022859 -:1026100040D078A1E9201AF0AEFAF8BD891E09026F -:10262000090A0120000490603C6068607A4A1160E9 -:10263000012B1DD000217D4A7D4B517061463D31FB -:10264000DC63DE637B4B5C6002249C6004241C61C1 -:10265000744B196074490E60604B89151960704B9A -:1026600058605F4801606D49C00548601670F8BD4C -:102670000121E0E701205E4E40046F4F012B04D1A1 -:102680003460506068603960F8BD906034606860A4 -:102690003960F8BD0120544E8004684F012BF4D1FD -:1026A000EEE750484068704770B54B4D28680026EB -:1026B000574C012806D1A068C00303D501200004AF -:1026C000A0602E606868012809D1A068800306D543 -:1026D00001204004A0606E60012001F075FCA86834 -:1026E000012809D1A068400306D501208004A0601C -:1026F000AE60022001F068FC70BD10B54B4908784F -:10270000002818D00120454AC0079060444AC00BF9 -:1027100090602D4A00121060424A00201060334A37 -:102720001060414A106008704A78002A02D0487050 -:1027300001F04AFC10BD0320FAE7012040490006E1 -:102740000860704701202549000608607047012095 -:102750003B4940050860704701202049400508605A -:10276000704733490020C86388151C4908607047CA -:10277000410A344AC005C00D50435143801C082211 -:102780005040400A0818704710B42F4C430B634365 -:102790001B0C5C020C602B4C6343C31A2B485C027D -:1027A0005843284B400D4343E31A9B1C08246340C5 -:1027B0005B1213700A681018086010BC704710B5DF -:1027C00001F0D9FC10BD000080E100E008E400E069 -:1027D00018E400E000B0004040B1004080E200E0BA -:1027E00000E100E000B5004048B1004040810040F9 -:1027F00044B100407372635C72656D5F68616C5FC9 -:102800006576656E745F74696D65722E6300000095 -:1028100000B3004040B3004040B5004000F5014027 -:1028200000830040408500400082004036000020C8 -:10283000C08F00400085004044B5004048B50040CE -:1028400000E200E0093D0000378600006F0C010047 -:1028500010B501F07CFC10BD00200449C8630120C4 -:1028600001218140024A116000BF7047C01F004033 -:1028700080E200E070B520380C4603001AF094FAAC -:1028800033BCC0C4C8CED2D6DBEFFCED1B1F232760 -:102890002C31373C41484E5155595D616F73676B20 -:1028A000767A7E82868A8E92969AB2B5B8E0F0EBFE -:1028B000EAE9F4F8E600206809F004FBF4E0206897 -:1028C00009F008FBF0E0206809F01CFBECE0207840 -:1028D00040B209F03AFBE7E0207840B209F05BFB38 -:1028E000E2E02078616840B209F071FBDCE020781A -:1028F00040B209F081FBD7E0207840B209F08CFBB0 -:10290000D2E02079C1B2207840B209F096FBCBE04A -:102910002078616840B209F0C6FBC5E009F0D2FB3F -:10292000C2E0206809F0D6FBBEE0207809F0EBFB9E -:10293000BAE0206809F0CEF9B6E0206809F0CEF9D7 -:10294000B2E02079C1B2206809F0CFF9ACE020688C -:1029500009F07AF8A8E0206809F07BF8A4E0207874 -:1029600009F07BF8A0E009F085F89DE0207809F0F7 -:1029700087F899E0207809F099F895E0206809F047 -:10298000B2F891E0206809F0B4F88DE0206809F011 -:10299000B6F889E0206809F0B7F885E0206809F00A -:1029A000B9F881E0206809F0BBF87DE0206809F003 -:1029B000BCF879E003F0FCF9C0070025002805D039 -:1029C00003F0FAF9002801D0256070BD03F0F0F99A -:1029D000800703D503F0F7F90028F5D12046FEF76C -:1029E000D5FB61E002F047FC5EE002F074FC5BE0C6 -:1029F000206802F07CFC57E0206809F019FC53E0E5 -:102A0000206809F021FC4FE0206809F028FC4BE029 -:102A10002078A268616809F02DFC45E0207809F073 -:102A20003EFC41E0207809F04FFC3DE020786168F1 -:102A300009F05FFC38E02078616809F071FC33E050 -:102A40002079C1B2207809F0ABFE2DE02EE00FE036 -:102A50000AE026E022E01DE002E016E00CE010E0D3 -:102A6000206809F096FB1FE0206809F013FF1BE0C7 -:102A7000206809F0F8FE17E0204607C802F098F831 -:102A800012E0206802F0EFF80EE06168206802F0C2 -:102A90001AF909E0206802F00CFB05E002F021FBC6 -:102AA00002E0206802F058FB206070BD0120086041 -:102AB00070BD00000C4908784A78401CC0B29042B2 -:102AC00000D008707047094A074820BF40BF20BFA8 -:102AD0004178037843701368002B02D103788B424E -:102AE000F3D00020704700003800002000E200E032 -:102AF000F8B50446800700250126002804DA584866 -:102B0000C563C66302208443E00404D55548C56309 -:102B1000C66380148443600003D553484560800534 -:102B20008443E00504D55148C563C66380158443DA -:102B3000A00404D54E48C563C663401484436004B2 -:102B40002104C00FC90F884203D04AA161201AF0A6 -:102B500012F82004800F0AD04B49CD634B48C5635F -:102B6000C563CE63C663C663032080038443200528 -:102B70000AD5474FFD632F20FEF722FBFE632F206F -:102B8000FEF71EFBF814844309F0E5FB41480442BC -:102B900003D038A18D2019F0EEFFF8BDF0B500216B -:102BA0000A46FF230446CC40E4072AD04CB2E6068E -:102BB000F60E0125B540384E3560384E3560002C94 -:102BC00011DA25072D0F083DAE08354DB6007719EF -:102BD000FD69A407E60E1C46B440A5431446B44064 -:102BE0002543FD610DE0A6082E4DB6007619356827 -:102BF000A407E70E1C46BC40A5431446BC40254331 -:102C00003560491C2029CDD3F0BD70B5264C0D464A -:102C10002060FFF76DFF2068FFF7C0FF284602F035 -:102C2000FBFB09F0A1FA08F0E8FF09F094FB08F0BB -:102C300088FF00F03BF801F0F1FE70BD10B51A4CB2 -:102C40002068FFF755FF2068FFF7A8FF09F083FB16 -:102C500002F05CFC0020206010BD13480068704743 -:102C6000C01F0040C0CF004000E50140C08F0040C1 -:102C7000C0DF00407372635C736F635F636F6E6687 -:102C800069672E6300000000C0EF0040C0FF0040F5 -:102C9000C0BF0040FEFF0FFC80E100E080E200E0EA -:102CA00000ED00E000E400E03C00002001203E498F -:102CB000400608603D4908603D490A68FF231B0241 -:102CC0009A4383121A430A60374980390860704773 -:102CD00010B502460620374904E0C3005B181B7993 -:102CE000002B0AD00346401EC0B2002BF5D132A102 -:102CF000482019F040FFFF2010BDC300CA50002239 -:102D000059184A718A7101220A7110BD294A00219D -:102D1000C00080180171704710B50446062803D31F -:102D200025A1572019F027FF2248E1000C1820792F -:102D3000012803D020A1582019F01DFF6079A17946 -:102D4000401CC0B2814200D060710120164940068B -:102D50008031086010BD70B515480068800B0228EE -:102D600003D015A1722019F006FF124D184C05264C -:102D70002078C10048190279012A07D14279837964 -:102D80009A4203D042798271685880472078401C6B -:102D9000C0B22070062801D3002020703046761E75 -:102DA000F6B20028E4D170BD80E100E080E200E0EE -:102DB00018E400E0EC0300207372635C736F635FE0 -:102DC0007369676E616C6C696E672E63000000004A -:102DD000400000208107C90E002808DA0007000F14 -:102DE000083880082D4A80008018C06904E08008F7 -:102DF0002B4A800080180068C8408009704710B5D1 -:102E00000D20FFF7E7FFC4B20420C043FFF7E2FF45 -:102E1000C0B2844203D023A11B2019F0ACFE264986 -:102E20000120486010BD0121244A48031060244B52 -:102E300000221A60234A5160234A1060234A11601D -:102E40001E4980390860704701211C4A4803106000 -:102E50001E4A51601A4A002111601B4908607047E0 -:102E600010B517490868012804D00EA15C2019F09C -:102E700082FE10BD104880680022C0B20A6008F0CF -:102E80007EFF10BD10B50E4801680029FCD0FFF789 -:102E9000E7FF01200C494003086010BD00ED00E091 -:102EA00000E400E07372635C736F635F68616C5F82 -:102EB000726E672E6300000000D5004080E100E0E4 -:102EC00000D1004000D3004080E200E000D000408C -:102ED00008B5027869460A7040784870088808BDCD -:102EE00008B5027869460A7042784A7082788A701A -:102EF000C078C870009808BD03E00B78491C0370C7 -:102F0000401C1346521ED2B2002BF6D1704701E08E -:102F10000170401C1346521ED2B2002BF8D17047EC -:102F200010B507E003780C78401C491CA34201D07F -:102F3000012010BD1346521ED2B2002BF2D1002048 -:102F400010BD02090007000E0243CC20104081088A -:102F50003320024090000143AA2008405522400837 -:102F600011404900084370470204120E0002024358 -:102F70004A401006000F5040010341400806C00CB3 -:102F800048407047C0434840064A0021C30702D06A -:102F90004008504000E04008491CC9B20829F5D358 -:102FA000C04370472083B8ED10B5B02805D0B128D4 -:102FB00008D0B2280BD0012010BD088880B212F0D2 -:102FC000FFF810BD088880B212F019F910BD08880A -:102FD0004B688A6880B2194612F022F910BD70B5AC -:102FE0000C4605460AF05CF82146284614F07FFDA1 -:102FF00070BD7047704770477047704770477047A3 -:1030000010FFFFFFDBE5B15100D001006500FFFFBD -:1030100003B40148019001BD09000020F8B5F74C48 -:10302000207BE17A88421CD00126F54D0027E07A0A -:10303000215C14200A4642435019037C052B11D011 -:10304000037C062B1CD0037C072B28D0437C012B50 -:1030500033D0ECA1EE4819F08EFD207BE17A884256 -:10306000E5D1F8BD0674E07A0A2807D0E07A401C62 -:10307000E072491CC8B2AA5802210CE00020F7E710 -:103080000674E07A0A2808D0E07A401CE072491CF5 -:10309000C8B2AA5803219047DFE70020F6E706747C -:1030A000E07A0A2807D0E07A401CE072491CC8B2D6 -:1030B000AA580821EFE70020F7E74774E07A0A28CA -:1030C00007D0E07A401CE072491CC8B2AA58072118 -:1030D000E1E70020F7E770B50024CE4E06207072BD -:1030E000CD4825464477047738300473C472CB4802 -:1030F00008F0E8FECA480575F572CA49601E886086 -:103100007571B570F57035717570C74864390570A3 -:1031100045701420604340180574641CE4B2052C0B -:10312000F7D30120FFF732FA0020FFF72FFA012032 -:10313000B071FFF7BBFDBD48FFF7CAFDBC4C207066 -:10314000BC48FFF7C5FD6070FFF7C0F970BD10B552 -:10315000FFF7E7F9B64C2078FFF7D8FD6078FFF766 -:10316000D5FDAC4C207A002803D002F09AF800205C -:10317000207210BD70B5A74CA079002804D0A1A181 -:10318000AD4819F0F8FC70BDE07A002803D19DA18C -:10319000AA4819F0F0FC0126A6710025E572607AB4 -:1031A000042114225043964A801801749D48816876 -:1031B000491C04D0691E81600120FFF7E7F9002057 -:1031C000FFF7E4F9FFF7C8F909F0E5F8FFF7C9FAE6 -:1031D0009B480560056001209A49C0030860FFF71D -:1031E0003BFB91480078022804D0032804D1E07802 -:1031F000002801D0A67000E0A570FFF79EFA70BD10 -:1032000003467F490520142242435218203A127F78 -:10321000002A04D0401E0006000EF4D1704714228C -:10322000424351180A46403AD362012220390A77B4 -:103230007047012805D0032805D1002903D10020BB -:1032400070470029FBD010B4724C00236370764A9B -:10325000002890700CD002280AD007291AD20B003F -:103260007B441B79DB189F441505070D0F111300D4 -:10327000D37003E01B2000E03A20D0700120607082 -:1032800010BC70475820F8E77720F6E79620F4E75F -:10329000B520F2E710BC0020704710B562484078B6 -:1032A000FFF766FA80B210BD411E1422504310B5DC -:1032B000534A8418203C042902D8207F002803D1D7 -:1032C00050A1614819F057FC207F012804D0B32099 -:1032D0004CA1800019F04FFC0020207710BD70B584 -:1032E0004D4C607F217F884201D1012500E00025FF -:1032F000FFF7D7F9FFF73CFA617F227F914201D1B6 -:10330000012100E00021A942EBD170BDF7B50646CE -:10331000481E84468EB0C0B2142202905043384AF0 -:10332000851828460695007C2D1D07282AD1334F85 -:103330000022F87A3B7B834221D03C5C029B9C427A -:1033400001D1012201E0002A04D00A2811D0431C37 -:10335000FB5C3B540A280ED0401C3B7BC0B283422E -:10336000EBD1002A0BD0387B002806D0387B401EDA -:1033700004E00023ECE70020EFE70A203873069A08 -:10338000012010746046234C042813D814204143B4 -:103390001B4808182038007F00280BD00698007CB6 -:1033A00001280BD00698007C012803D01098807A61 -:1033B000012807D013A1254819F0DDFB1098807A69 -:1033C00001286CD106980E4A007C022842D00B4C92 -:1033D000207B0A286FD0207BE17A401C884203D1F1 -:1033E00008A11B4819F0C7FB069901204874217BEE -:1033F00002986054207B0A2861D062E048030020D4 -:10340000580300207372635C72656D2E63000000C8 -:10341000CF050000DC03002010030020E80300209B -:1034200030030020BC0300202D0000205BC40000FE -:103430002B0000201D3000007D0200005E02000015 -:1034400000F5004080E200E0CB0200001503000020 -:1034500022030000607A029B0146984206D0014692 -:10346000142778438018807C9842F8D1637A83428D -:1034700008D1617A142359438918897C617201212A -:10348000A17207E0142343439B18142779439B7CC4 -:1034900089188B741423062158438018817410985E -:1034A000007A06281DD203007B441B79DB189F4459 -:1034B0000C161412100EE07A002891D094E7002028 -:1034C00001E0207B401C2073B9E000200FE0B42015 -:1034D0000DE073200BE0322009E00A2007E007200E -:1034E00005E0FF20FD49E03019F045FB0020019088 -:1034F000109801680198081A28601099097A002923 -:1035000012D00221401A0102090A296010980268AB -:10351000406810180002000A68601098807A02283B -:10352000109803D0007B74E00421EBE7007A0028B8 -:1035300013D0022201981018844610984268604601 -:1035400008301718E648019A4078904202D9E2788C -:10355000002A04D03846083005E00422EAE7019A40 -:10356000801AC0190830627A062A1CD0627A1423A5 -:103570005A43DC4BD2185268914214D0DA4B07936D -:10358000617A14225143D74A89184A688968921B84 -:10359000891B12020902120A090A90423AD89A4279 -:1035A00038D8994236D83018C01B0002000A28606B -:1035B00010996044CD4AC9680002000A9446421A34 -:1035C00001239B0507929A4201D2104614E00A1A81 -:1035D00008929A4201D207980EE0079A6346624524 -:1035E00003D9591A0818401C06E0089A624506D902 -:1035F000181A4018401C4042002860DC03E0B7491C -:10360000BB4819F0B8FA2868C0190002000A6860BF -:10361000002028726868082708300002000A6860E5 -:103620001098407AA8721098007A687203280ED217 -:1036300000280CD009F09CF9002803D007E00020F6 -:1036400011B0F0BD01983A210F1A32200190A44820 -:103650000178012901D0032909D1407801998842D4 -:1036600005D9E178002902D10199401AC7192868C3 -:103670009D4A801B844601026868090A801B030278 -:103680001B0A03938F421AD81346914217D8039905 -:10369000994214D8617A062915D0677A61460622C4 -:1036A0000392019214228F4B7A43D21893689B1B8A -:1036B0008B4216D80397977C062FF3D173E00298BC -:1036C00001F05AF9BBE70699022202980A74627A5D -:1036D000062A00D0627A8A7460720120A07211B04A -:1036E000F0BD062F5FD000223946944614227D4B50 -:1036F0004A43D21853689B1B834225D2917BAB7AF5 -:1037000099421BD806980521029D0174794C207BB3 -:103710000A280FD0207BE17A401C884203D16F49F0 -:10372000754819F028FA207B2554207B0A2800D000 -:10373000C7E6C4E6E07A0028F1D0F4E701218C4620 -:10374000917C0629D2D102E0604600282AD03D466D -:10375000019114202A46424362480621161831740A -:103760001038007B0A28634816D0017BC07A491CB8 -:10377000814203D161A1644819F0FDF95D48017BE4 -:103780004554017B0A290BD0017B491C0173B57C90 -:103790000198A842DDD106E0C07A0028EAD0EDE722 -:1037A0000021F3E70197069902204E4D0874607AD4 -:1037B000B84207D106990198887402986072012076 -:1037C000A07221E00398062F0FD0062803D14BA149 -:1037D0004E4819F0D0F90398142250434019029929 -:1037E00081740699019888740EE0062803D143A1DC -:1037F000474819F0C0F90398142250434019029920 -:103800008174069906208874012011B0F0BD70B54E -:103810000D46404A441900210B46101A8B4103D231 -:1038200036A13D4819F0A7F93C48854203DD33A194 -:103830003B4819F0A0F93B48854203DA2FA13A48EA -:1038400019F099F93948844205DA002C01DB204649 -:1038500070BD364800E03648201870BD401E70B577 -:10386000C0B2142148431F494418607B062813D274 -:1038700003007B441B79DB189F44020C0A080604F2 -:10388000002069E0B42010E073200EE032200CE04C -:103890000A200AE0072008E0FF2018A1E03019F014 -:1038A0006AF9617B0020002956D002214018616826 -:1038B00040180002000AFEF75BFF0C256557154A09 -:1038C000441900210B46101A8B4103D20BA1124858 -:1038D00019F051F91148854230DD2BE00434000025 -:1038E0002D00002058030020FFFF3F00FFFFFF00D6 -:1038F0000E07000048030020070200007372635C9B -:1039000072656D2E63000000C5030000DD0300003A -:10391000E3030000FF7F841EF50300000020A107E1 -:10392000F603000000E05EF8F70300000080841E4C -:1039300000807BE1FA49FB4819F01DF9FA488542FD -:1039400003DAF749F94819F016F9F948844207DA19 -:10395000002C03DB204670BD0421A7E7F44800E0FB -:10396000F448201870BDF0B5064683B0F2480190C7 -:10397000457A029534687068001B0702EF483F0AD9 -:10398000001B0090062D2DD0142029464143EC4801 -:103990000122081884464168E84892058646081BBB -:1039A000904210D3631A93420DD30246704672457B -:1039B00003D900984018401C05E073450ED9411A00 -:1039C0000819401C404200280CDA60460295857CAC -:1039D0000198C0790028D5D003B0F0BDD049D948AE -:1039E00019F0C9F80298854226D014214843D449D9 -:1039F0000123401802908068D0499B058C46011B2A -:103A00008646994210D3221A9A420DD363466145E5 -:103A100003D900997144491C06E0194662452DD925 -:103A2000091A0819401C4142002905DD0298B17AA3 -:103A3000807B814200D37446062D15D0C0491420E6 -:103A4000454368184268121B1202120ABA420BD28E -:103A5000B27A837B9A4200D38468857C0198C079CE -:103A60000028B9D1062DEAD13068A042B4D0E019BF -:103A70000002000A3460706003B0F0BDA849B1488C -:103A800019F079F8D8E7F0B5AF490446486885B031 -:103A9000C005C00D1BD0103840B200280BDA020759 -:103AA000120F083A920892005118C9698007C00E97 -:103AB000C140880908E08108A44A8900891809687A -:103AC0008007C00EC14088090006000E08D00026FD -:103AD0002078002806D0012804D0002005B0F0BDD1 -:103AE0000126F5E72079062813D203007B441B79D1 -:103AF000DB189F44020C0A080604002018E0B420DA -:103B000010E073200EE032200CE00A200AE00720CB -:103B100008E0FF208249E03019F02DF821790020DB -:103B2000002905D002214718834D002E02D003E062 -:103B30000421F8E70020E87102AA6946A068FEF7B0 -:103B400023FE694608228A56E06801A98018C01C35 -:103B500001221F2801DA019209E003AAFEF714FEF0 -:103B60006846007B002802D00198401C0190009913 -:103B70000198401808300002000A0190C81B00029A -:103B8000000A009060796946887200980390FEF7F9 -:103B900088FD009A019B121A181A6D491202000240 -:103BA000120A000A8A4210D888420ED86846FFF7E7 -:103BB000DAFE00990398814205D0C8190002000A74 -:103BC000FEF7D6FDA060012000E00020E979002981 -:103BD00084D0002EAED005B0F0BDF0B505468FB054 -:103BE0005C480C460B9008F075F9534E5A4F00286C -:103BF0000BD05A48007D002803D059A15B4818F02B -:103C0000BAFF207801287DD068E1787F0A280CD09F -:103C1000787F397F401C884203D151A1544818F065 -:103C2000AAFF2078012804D011E0387F0028F4D0C2 -:103C3000F7E75048401920380090C07F002803D093 -:103C400047A14D4818F097FF00990120C877797F68 -:103C500028461422494D51434919087420780228F6 -:103C600023D0787F14214843451920792872607940 -:103C700068722A460C322946A068FEF785FD0C20A2 -:103C800028560F2804DD1F3828732868401C286038 -:103C90000C216956281DE26801905018C01C1F288D -:103CA0006EDA019901200860FBE027494868C005E9 -:103CB000C00D20D0103840B200280BDA0207120FD6 -:103CC000083A920892005118C9698007C00EC14095 -:103CD000880908E081081D4A890089180968800759 -:103CE000C00EC14088090006000E04D105201CA1A9 -:103CF000000218F040FF787F142148434519002145 -:103D0000E06800E0DBE06A460491117004A9FEF768 -:103D10003BFD6A46002010560F2832DD012031E0BD -:103D2000FC380000F603000000E05EF8F703000036 -:103D30000080841E00807BE1DC030020FFFFFF0089 -:103D4000580300200E07000000ED00E000E400E052 -:103D5000FFFF3F00E8030020100300203003002095 -:103D60007372635C72656D2E6300000011050000C4 -:103D7000EF04000031000020F40400005002002095 -:103D800082E000200499401807900220A872207950 -:103D9000287260796872A068291DC01C04911F28D0 -:103DA00001DA012009E0FEF7EFFC68460078002800 -:103DB00004D0049804990068401C0860287A0628FA -:103DC00013D203007B441B79DB189F44020C0A08C2 -:103DD000060400200FE0B4200DE073200BE0322039 -:103DE00009E00A2007E0072005E0FF20FD49E03058 -:103DF00018F0C1FE00202179002943D0022140188B -:103E00000490696808300818079908900918049800 -:103E1000081A0C900020F071FEF743FC044628605D -:103E2000079820180002000AE860707A062825D05A -:103E3000707A14214843EC49401840680899019071 -:103E400040180002000A0290687A6946887301A847 -:103E5000FFF789FD0199029A091B121B0902120240 -:103E6000E24B090A120A0C98994207D8824205D8F7 -:103E70000199049808180002000A2860F0790028C7 -:103E8000C8D110E00421BAE704AA0199FEF77CFC2E -:103E90006846007C002804D0019801990068401C05 -:103EA00008602078A872787F0A2806D0787F401CA6 -:103EB00078770B9808F026F84BE00020F8E7CC481C -:103EC000401920380090C07F002804D0A320C9A149 -:103ED000C00018F050FE00990120C877C84805744A -:103EE0002078022803D1C3A1C64818F044FEC44D6F -:103EF00020792872607968722A460C322946A068B7 -:103F0000FEF742FC0C2028560F2804DD1F382873CA -:103F10002868401C28600C216956E0682A1D40185A -:103F2000C01C01921F2802DA012010600CE004AAD4 -:103F30000199FEF729FC6846007C002804D001980E -:103F400001990068401C08602078A872AC490120E3 -:103F50000875787F397F884224D0747A062C23D064 -:103F6000FEF79FFB14214C439F4961180A7C042AE9 -:103F700018D00A7C032A15D04B6889681B1A081AC6 -:103F80001B020002994A1B0A000A082B0AD3114699 -:103F9000934207D8884205D8787F397F884201D07C -:103FA000FEF7CBFB0FB0F0BD787F397F8842F7D1A9 -:103FB0000FB0F0BD10B50020FEF7D5FA10BD10B55A -:103FC0000120FEF7D0FA10BDF1B5009802287DD08F -:103FD0008D4C607A062803D186A18C4818F0CBFD61 -:103FE0000026A6710125E572607A032114227E4F16 -:103FF0005043C0190174FEF7A5FB0098002808D0B3 -:10400000012826D0022861D0032876D079A18048E3 -:104010003FE08048007F002803D076A17E4818F05A -:10402000AAFD65717B4D00202E60FEF7AFFAA968EE -:10403000481C04D0012300221846FEF7DDFA607AFE -:10404000617A401CC0B2142251437A580121904732 -:10405000F8BD0120FEF79AFA607900280DD06D486E -:104060008068401C09D0607A617A401CC0B214227A -:1040700051437A5806219047F8BD6648007F0128D1 -:104080000AD0022812D0032824D0042836D059A1FF -:10409000624818F070FDF8BD2079002803D0267121 -:1040A000FEF755FBE5705B480677F8BD207A0028DF -:1040B00002D101F0CDF82572607A617A401CC0B25D -:1040C000142251437A580021904700E030E05148D3 -:1040D0000677F8BD4F4F0123397B78680022411ADB -:1040E0001846FEF789FA2079002803D02671FEF7DA -:1040F0002EFBE57002203877F8BD1EE0454E217892 -:1041000070680123411A00221846FEF775FA207ADA -:10411000002802D101F09CF82572607A617A401C77 -:10412000C0B2142251437A58002190473577F8BD28 -:104130003B480078FEF7F0FDF8BD607A617A401CDC -:10414000C0B2142251437A5805219047F8BD10B5EA -:104150002D4C607A062803D126A1324818F00BFDB9 -:10416000607A617A401CC0B2142251431E4A5258F0 -:104170000421904710BDF0B583B006200290FEF7F1 -:1041800090FA214C0090617A27480190062920D0AE -:10419000617A1420414314480918097C042918D075 -:1041A000617A142251430818007C03287DD00198BD -:1041B000009E02684068921B801B0C49120200029C -:1041C000120A000A0B46082A6FD39A426DD8884219 -:1041D0006BD810488068401C03D006A1134818F023 -:1041E000CAFC25E0603D000058030020FFFF3F00AF -:1041F000310000207372635C72656D2E63000000F5 -:10420000300300201E050000DC0300204F050000E5 -:10421000A2050000BC0300205B050000960500001D -:104220002B000020A9050000CC030020E5050000BC -:1042300000206071607A062807D16078002804D0D9 -:10424000FE48C178417081780170607A062815D0E7 -:10425000617A14204143FA480918097C04290DD1D8 -:10426000617A0291627A012114235A43121811745F -:10427000627A5A431018807C6072A172F14D687F97 -:10428000297FF14F884233D0F04E287F14214843D4 -:104290008019007CC05D0128287F07D04843801921 -:1042A000007CC05D02282FD044E0FCE1142148438B -:1042B0008019807A01280AD0297F022014225143D4 -:1042C0008919097CC855287F0A2808D009E0297F68 -:1042D0000020142251438919097CC8552AE0002086 -:1042E00001E0287F401C2877687F297F8842CCD155 -:1042F000D74D287D00284CD0287CC15D012928D0CD -:10430000C05D022830D03AE0287F1421484380194C -:10431000807A012803D0CFA1D14818F02CFC297F46 -:1043200000201422514389198872297F5143891929 -:10433000097CC855287F142148438219287F4843A7 -:104340008019017C0098FEF7E1FF287F0A28C8D178 -:10435000C5E7A97A012904D00221C155002028759A -:104360000DE00021C1550AE0A87A012803D0B9A1C7 -:10437000BC4818F000FC0020A872297CC855287D94 -:10438000002806D0297CB24A0098FEF7BFFF002023 -:104390002875029806281ED014214843A8494018C1 -:1043A000017C012917D107210174AF4D287B0A2810 -:1043B0003CD0287BE97A401C884203D1A5A1AB48B8 -:1043C00018F0D9FB297B02986854287B0A2831D041 -:1043D000287B401C2873607A06287DD0A07A0028AC -:1043E0007BD00020A072617A142041439448A04BF6 -:1043F0000A18566891681D46D2687C35DE67AA6047 -:1044000069609C4D697E002916D00226617A1422CB -:104410008B4851430818407B06281BD203007B447D -:104420001B79DB189F440A1412100E0CE87A00283E -:10443000C4D0C7E70020CDE70426E7E700200FE05F -:10444000B4200DE073200BE0322009E00A2007E0E1 -:10445000072005E0FF207FA1E03018F08CFB002052 -:10446000C1B22973687E022801D0012810D12869C1 -:1044700042180098101A0002000A3A2808D90320AE -:104480006876323A1002000A28613220287308E068 -:10449000322906D2207A00280AD100F0D9FE012064 -:1044A00005E0207A002803D000F0FBFE00202072F7 -:1044B00062490822487820700978012901D003292F -:1044C00006D101212171297B884201D9421A083283 -:1044D000A378002B03D001E08EE09CE0921C2179B0 -:1044E000002901D1002B5DD09446634A00990092C7 -:1044F000019A176852687F1A511A3F0209023F0A4F -:10450000090ABC4538D85C4A974235D8009A91428E -:1045100032D8297B884214D92B69421A9A1A12027E -:10452000120A101880190002000A2A616860002926 -:1045300005D0032028770006000E3ED14CE0012074 -:10454000F8E781420BD92A69511889190902090A29 -:104550006960002801D00420ECE70220EAE7002B84 -:1045600003D13CA1454818F006FB286980190002D8 -:10457000000A6860002013E000202071A070297BF1 -:10458000002908D02869401880190002000A6860D4 -:104590000220287711E0296989190902090A69604E -:1045A000287719E0287B00280FD02969081880197E -:1045B0000002000A68600220287728690123811917 -:1045C00000221846FEF718F809E028698019000251 -:1045D000000A6860002028770120FDF7D7FF617A84 -:1045E0001420414316480C2208188256012300204B -:1045F0006968FEF701F80EE00120FDF7C7FF002013 -:10460000FDF7C4FFFDF7A8FF207A002803D000F0D3 -:1046100048FE00202072A078002804D0FEF797F80A -:104620000020E070A0706078002804D00348C178B2 -:104630004170817801702079002821E02D00002050 -:1046400058030020100300203000002050020020FA -:10465000300300207372635C72656D2E630000008E -:10466000070600002306000048030020350600006E -:1046700050030020BC030020FFFF3F00870600001E -:1046800006D00020CE49E0700978002900D12071C1 -:10469000CC48017BC07A814203D0CB484078FEF7FA -:1046A0003BFB0120E07103B0F0BDF0B5C74C0746FD -:1046B000607A83B0062803D1C5A1C84818F05BFA18 -:1046C000607A1421C64E48438019007C032803D029 -:1046D000BFA1C44818F04FFAC34DA868401C03D0CE -:1046E000BBA1C24818F047FA607A142148438119E7 -:1046F0000C20085600216A4600911171C01901AAC8 -:104700006946FEF741F86A46042010560F2801DD7D -:10471000012000E00020009940186968401801025B -:10472000090AA9606079002804D0012300221846F4 -:10473000FDF762FF03B0F0BD70B5AE4CAC4A0B1A8A -:10474000A34214D3451AA54211D3934203D9101A98 -:1047500043185B1C0BE0954204D9511A0818401C01 -:10476000434204E09AA1A44818F005FA0023184631 -:1047700070BD10B50146012300220220FDF73CFF69 -:1047800010BD10B50220FDF701FF10BD10B5FDF7FB -:1047900088FF10BDF0B58D4D0446E87A83B000283F -:1047A00003D18BA1954818F0E6F9642C4DD3944AB7 -:1047B00000210846121B884147D39248417F007F61 -:1047C000814242D19048007D00283ED1687A142170 -:1047D000834F4843844EC519306801AA00196946C1 -:1047E000FDF7D2FF694604200856002802DD009834 -:1047F000401C0090A96800986B680A18D21A12022F -:10480000824B120A9A4220D8AA7C062A08D0142386 -:104810005A43D2195268511A0902090A814214D323 -:10482000B068401C05D00120FDF7B0FE0020C04359 -:10483000B060306800193060A86800994018000224 -:10484000000A7061012003B0F0BD002003B0F0BD8C -:10485000F8B50646401EC5B21420614968434418A5 -:10486000207C002803D15AA1694818F084F96548D2 -:10487000017F407F81420CD0664A14234B439B1832 -:104880001B7CB3420CD00A290CD0491CC9B281420E -:10489000F3D15D48017D002964D0007CB04261D134 -:1048A0000020F8BD0021F1E7217C052905D0217CFD -:1048B000062902D0217C072928D101212174C17A3F -:1048C0000023027B8A4221D00246565CAE4201D1CF -:1048D000012301E0002B04D00A2911D04E1C965D63 -:1048E00056540A290ED0491C167BC9B28E42ECD10F -:1048F000002B0BD0117B002906D0117B491E04E050 -:104900000026ECE70021EFE70A211173617C002902 -:104910002AD06774C17A0023027B8A4224D0425C89 -:10492000AA4201D1012301E0002B04D00A2912D0B0 -:104930004A1C825C42540A290FD0491C027BC9B22E -:104940008A42ECD1002B0FD0027B0146002A06D010 -:104950000A7B521E04E00022EBE70021EEE70A2268 -:104960000A7301E017480027217C01299CD1617C52 -:10497000002999D10120F8BD70B505461420184AC8 -:1049800005216843801801740E4C207B0A2811D041 -:10499000207BE17A401C884203D10DA11E4818F00B -:1049A000EAF8207B2554207B0A2807D0207B401C76 -:1049B000207370BDE07A0028EFD0F2E70020F7E71F -:1049C0002D000020480300202B000020DC030020E5 -:1049D0007372635C72656D2E63000000EA0600006E -:1049E00058030020EB060000BC030020EC0600008A -:1049F000FF7F841E0020A1070E0700002D07000086 -:104A0000FF1FA1071003002030030020FFFF3F001D -:104A10006A0700005002002007020000B54800218C -:104A200001708170704770B5B34D01236B60B34B5B -:104A30001C68002CFCD0002407E00E6806601E688D -:104A4000002EFCD0001D091D641C9442F5D30020EB -:104A5000686018680028FCD070BD70B5A54C0E4683 -:104A60006178884203D0A6A16F2018F084F803254E -:104A7000330018F099F9095206242452525252492F -:104A800052002078022803D09DA1732018F073F8FB -:104A90002570A078022802D0012804D008E0A06880 -:104AA00007F044FF04E02269E168A068FFF7BBFF5C -:104AB0000020A070FEF75EFB0420207070BDFEF7A2 -:104AC0000EFC01466068FFF737FE06462078022894 -:104AD00003D08BA1872018F04EF88D4A8D498E485F -:104AE000964205D86269032A02D2521C626102E032 -:104AF000864207D84D71801BC86086496078FFF7F1 -:104B00006CF870BD032003E0A0780028FAD10220E1 -:104B100007F0ECFE00F0E5F870BD79A1B12018F0C7 -:104B20002AF870BD70B50546FEF7D9FB714C606080 -:104B30002078012803D072A1B82018F01CF875491C -:104B40000220087000220A718D6004224A71724AA4 -:104B5000CA6020706078FFF740F870BD10B5654CF2 -:104B6000A078002802D12078002801D0112010BDA3 -:104B70006A48FEF745FB60706078002804D0012089 -:104B800020700020606110BD032010BD10B501240D -:104B9000020B64040121624BA04202D291401868CA -:104BA00002E0203A58689140084000D0012010BD32 -:104BB000F8B50E46910004460F1915463F1F0091A7 -:104BC00007F0C5FE009980028919091FB14201D280 -:104BD000012200E00022002D03D0FF2101318D428F -:104BE00001D90920F8BD4F498C421DD3A7421BD3E0 -:104BF000844201D2874203D34B4820187C2803D833 -:104C000020463043800701D01020F8BD8E420BD3E0 -:104C1000002A09D12046FFF7B9FF002804D1384601 -:104C2000FFF7B4FF002801D00F20F8BD3F484049EE -:104C30000068884205D02A4631462046FFF7F3FE39 -:104C40000FE0FFF78BFF0028EFD12A480121C66053 -:104C50000561846081702846302148431830FFF791 -:104C600061FF0020F8BD10B504462E48800A84423A -:104C70000BD307F06CFEA04201D8102010BDA40297 -:104C80002046FFF783FF002801D00F2010BD2748E2 -:104C900027490068884203D0204607F047FE0AE013 -:104CA000FFF75CFF0028F1D1124802218460817077 -:104CB0002048FFF737FF002010BD1A48010B0120E4 -:104CC0008840401E704700B50B460246FFF7F5FFCF -:104CD000104201D00F2000BD114802604360002047 -:104CE00000BD10B5034C6078FEF7DEFA002020709E -:104CF000A07010BD4400002000E5014000E4014028 -:104D00007372635C736F635F666C6173682E6300BC -:104D1000307500001C040020D0FB01005B4A00003D -:104D20000006004000D0010080EFFFEF1C000020D3 -:104D3000BEBAFECA3A560000F7480521817000212C -:104D400001704170C1708160704710B5F3490A78F5 -:104D5000022A07D0CA681018C860C8689638FFF7DA -:104D6000A4FC10BD8A68101888608868F6E703788C -:104D7000EB49EC4A002B02D0012B10D014E0037950 -:104D8000002B01D0012B0FD14379002B01D0012B37 -:104D90000AD18368643B8B4206D2C06810E0037975 -:104DA000002B03D0012B01D0002070474379002B4A -:104DB00001D0012BF8D1C368643B8B42F4D28068E8 -:104DC0009042F1D801207047F8B504460226FFF75B -:104DD000F6F80068002803D0D3A1BD2017F0CBFE61 -:104DE0000127CD4D002C08D02078002817D00128AD -:104DF00005D0022811D0032813D02F710DE0606870 -:104E0000C82808D3FFF7C6FC002804D06068FFF765 -:104E10009CFF012603E0002601E000F0F7F9304690 -:104E2000F8BD28780028F8D16068FFF7A0FF0028B7 -:104E3000E3D060680078002826D0A878042803D042 -:104E4000B9A1F72017F097FEB44F002038706068C2 -:104E50000079012800D0002038716068407900286E -:104E600037D00420787160688168E868FEF7CFFC6D -:104E7000B8606068C0689630F8600320A870A749E1 -:104E8000E878FEF7AAFEC8E7A4480221017061682D -:104E90000979012919D00021017161684979002936 -:104EA00015D004214171616889689631816061681B -:104EB000C968C160C068984C14346060FEF70FFA8E -:104EC00020606F700220A870A7E70321E4E70321A8 -:104ED000E8E70320C6E7F8B58F4C0D46E178884235 -:104EE00004D0FF2090A1193017F045FE28468A4FC4 -:104EF000002501261437030017F056FF0906123764 -:104F0000607B8C96C39FC300A078032807D0A0784D -:104F1000022804D0FF2084A11D3017F02CFEF8BD1C -:104F2000A078032807D0A078022804D0FF207EA113 -:104F3000213017F020FE0420A07025712078002871 -:104F400010D1FFF702FFE078FEF788FCE0607D49B2 -:104F5000886A7D4A024022617B4AD24310408862BF -:104F600000204FE000F052F9F8BDA078032807D0E8 -:104F7000A078022804D0FF206BA1423017F0FBFD7F -:104F80002078002802D000F04DF9F8BDA078032861 -:104F900001D1042024E0FEF7A2F901463868FFF7AA -:104FA000CBFB002820DB796881421DDB091A5B48B6 -:104FB000C1600146E078FEF710FEF8BDA078032836 -:104FC00007D0A078022804D0FF2057A1633017F043 -:104FD000D2FD20780028D6D1A0780328DBD1052087 -:104FE00007F084FCA670F8BD042007F07FFCA570D4 -:104FF000F8BDA078042804D0FF204BA1843017F01E -:10500000BAFD0220A1688847FFF7DEFEFF260546AD -:10501000BD3642E0A078042804D0FF2042A18930A8 -:1050200017F0A9FD0120EDE7A07804289AD0FF2011 -:105030003DA18E3017F09FFD94E7A07804280AD098 -:105040006078002802D0A078022804D0FF2036A182 -:10505000933017F090FD2078002894D12079002813 -:1050600004D0062007F042FC2571BBE760780028D9 -:1050700005D02A49E078FEF7B0FD6570F8BD07203D -:10508000AEE7FF2028A1AE3047E7002D0AD0012D62 -:1050900006D025A1304617F06EFD022DF5D1F8BDE2 -:1050A000042000E00320A1688847FFF78DFE054635 -:1050B000F3E770B5050005D0174CA078052803D09C -:1050C000112070BD102070BD2048FEF799F8E070E7 -:1050D000E078002803D0A5600020A07070BD0320F8 -:1050E00070BD10B50C480178002901D0112010BD09 -:1050F000817805290ED08178012929D0817800296D -:1051000026D0012101708178012921D080780028E2 -:105110001ED01FE00F2010BD5C0000202C040020DA -:105120003D860100FF1FA1077372635C736F635FAD -:10513000726164696F5F74696D65736C6F742E63FF -:10514000000000000005004002810000D74E000072 -:1051500000F068F8002010BDF8B5394E0446B0786C -:10516000002801D001280DD1002C0DD02046FFF7DA -:10517000FEFD00280AD02078324D002808D0B078F3 -:10518000012823D00F20F8BD1020F8BD0720F8BD5E -:1051900002272F702079012814D00020287160790F -:1051A000002811D004206871A0689630A860E068DB -:1051B000E860E868224C14346060FEF790F82060E4 -:1051C000B77019E00320E9E70320ECE7002028701E -:1051D0002079012816D0002028716079002813D08A -:1051E00004206871A168F068FEF711FBA860E06810 -:1051F0009630E8600320B0701249F078FEF7EDFCBD -:105200000020F8BD0320E7E70320EAE710B50E48C9 -:10521000816A0E4A11400A4A126911438162FDF700 -:10522000A9FF10BD10B5064CE078FEF73DF8082048 -:1052300007F05CFB0520A07000202070607010BD9E -:105240005C0000202C04002000050040FD7EFFFFD4 -:1052500010B5EFF31080C407E40F72B6D14841785F -:10526000491C41704078012801D107F079FB002CDE -:1052700000D162B610BD70B5CA4CE07800280AD1E2 -:105280000125E570FFF7E4FF07F072FB002804D06A -:10529000002007F02BFB002070BDC34865714560FE -:1052A000F9E770B5EFF31080C507ED0F72B6BD4C8E -:1052B0006078002803D1BDA18F2017F05CFC6078D6 -:1052C000401E60706078002801D107F04DFB002D72 -:1052D00000D162B670BD10B5B248C178002904D0C3 -:1052E00000214171C170FFF7DCFF002010BD10B537 -:1052F000044607F03DFBAB49C978084000D00120C7 -:105300002060002010BDF8B50246A64C0026A6710C -:105310000420202101251027130017F045FD0D085A -:105320000A0B0D0F1113151D1F21242628002571AE -:1053300022E0022020711FE00820FBE727711BE01C -:10534000217119E0012617E0FFF782FF07F010FB3B -:105350000028FBD002260FE0207102E00820FBE7C6 -:105360002771A57108E02171FBE74020F4E7FF20D9 -:105370008EA1763017F0FFFB07F006FB002809D05E -:1053800007F008FBB04205D1304607F006FB0028C5 -:10539000FAD02CE001208007C5608C4900224A60C9 -:1053A0008B4A9661804B02225A6085608948026967 -:1053B000D243D206D51702696D1C10231A4302612D -:1053C0000F4600E020BF78680028FBD0304607F089 -:1053D000E4FA0028FAD0002D04D17E480269102199 -:1053E0008A43026170490220886000207860A079B9 -:1053F00000280CD007F0BCFA054607F001FA764AFF -:10540000002D02D0A260E06001E0E260A060002E0A -:1054100001D100F0A2F8F8BD10B5044607F0AEFACD -:10542000002805D05F490120C8704A78521C4A7094 -:105430002046FFF768FF10BDF8B5644DA868002648 -:10544000012802D1AE6007F051FA6868012800D146 -:105450006E6028680127534C012812D12E606079B4 -:10546000002803D0002007F041FA66712078002858 -:1054700007D007F07DFA002803D0012080070761DC -:10548000A770286901282AD12E6100F05FF8012059 -:1054900080074761A079002815D007F069FA0090CD -:1054A00007F0AEF90099002901D0E16800E0A16899 -:1054B000411A022901DA8A1C11DC0099002901D065 -:1054C000E06000E0A060FFF7C3FE07F051FA00289B -:1054D00004D0012080070761A77000E02770E8680A -:1054E000012812D100F032F800F030F800F02EF868 -:1054F000A078002804D1FF202CA1033017F03BFB3B -:10550000EE60A6702670FFF7CCFEF8BD10B5254CF6 -:10551000E078002801D107F027FA0120810788618F -:1055200000F014F8A07800280BD0284CE068002880 -:1055300003D107F032FA0028F8D10020E06000F033 -:1055400005F800201849C043886010BD5021084666 -:10555000491E89B20028FAD17047F8B512481927B8 -:1055600087601A4900200860C86007F001FABE078A -:1055700001240C4D002802D03461AC7000E02C7086 -:10558000FFF766FE08484760114928798863FFF7EE -:10559000DDFFB461FFF7DAFF0C4900200861746198 -:1055A000F8BD000078000020000300402E2E5C2E85 -:1055B0002E5C6C6962735C736F635C7372635C73A3 -:1055C0006F635F636C6F636B2E63000000010040CC -:1055D0000005004000ED00E0FFFFFF7F8307FF2292 -:1055E000DB0E9A408907090E994000280BDA000764 -:1055F000000F08388308FF489B001B18D8699043A8 -:105600000843D86170478308FB489B001B18186843 -:105610009043084318607047F849C86AC0070ED124 -:10562000F7480A6B42624A6B82628A6BC262C96B3C -:105630000163F24940310968C20511434163704773 -:1056400010B5F04949684872097ACA0701D00128A3 -:1056500003D0890703D5022801D1FCF7B4FC10BDA3 -:1056600070B5E9480024C4630125C563E7480460B8 -:10567000284600F0B8FBE649601E8860E5480461F2 -:10568000E5490D6101690029FCD00461C4604460F2 -:1056900084600460012000F0AEFB70BDF8B5DF4807 -:1056A0000125C560D8480026C663C563FFF7B4FF6F -:1056B000DB4C6661D34FDB4A7868C17809028918F0 -:1056C000A161A1696A069143A161D04A03211160D9 -:1056D000D0490E61CE604E600E60D349A1630907C8 -:1056E0008A692B4693431A02921C6263CF4AE26393 -:1056F0008279E2602563E6628B692A4689699A436A -:105700008D43AA409107890F2161001D00F0D7FB4E -:1057100078688078A060BE49102048600021012090 -:10572000FFF75CFF012000F057FBBC48C660F8BDE6 -:10573000F1B5BB4EB068B34C6568A97888420ED10C -:105740002D1D6878FDF7FDFB716AC9B2884206D14C -:105750002878FDF7F6FBF1690006884201D00020A9 -:10576000F8BDFDF7BCFD074660683946C069FEF725 -:10577000E3FF0546642800D264256068816A0269F7 -:105780004919914203D97D2149020161E7E7284681 -:10579000FFF700F80028E3D06168CF61886A4019FC -:1057A0008862FEF782FF0098012500280DD0FFF7E0 -:1057B00075FF01F047F8706097484560964A954933 -:1057C0001432091D0E2000F01DFB082000F00BFB19 -:1057D00001209749000448609648C5606068964972 -:1057E000406A086095490020086001460820FFF7DC -:1057F000F5FE082000F0FFFA082000F0EDFA01F0B5 -:1058000054FA0120F8BDF8B50A467E4901268A4DB2 -:1058100000244868130017F0C7FA090631ECEC7B46 -:10582000EBEA1EE91E000F460978022912D04078E3 -:105830007B4C834D01280FD001F0EDF8FFF72EFFD0 -:1058400001F002F860600120000568607868806AF5 -:10585000FEF72BFF7E70F8BD01F057F9FFF71EFF32 -:1058600000F0F0FF60600120400568606A4A694905 -:105870001432091D0E2000F0C5FAE7E70F464978FB -:1058800000291ED03978022922D0082000F0ABFA76 -:105890006A490C607868426A2A60027B002A25D037 -:1058A000203006730120624900044860002108206E -:1058B000FFF794FE082000F09EFA082000F08CFA12 -:1058C0001BE0407801F0E9F9F878FDF725FA06E0E9 -:1058D0004078012807D000F017FB00F09FFA3C70D9 -:1058E000FDF748FC10E000F0ABFAF6E720304A4A3A -:1058F000047310320F2000F085FA78684078012890 -:1059000004D00120FFF79CFE7C70F8BD0220F9E76F -:105910004C4A002753683B49DB07DB0F8B7040780C -:1059200001281ED001F03DF900F0EEFA354800786C -:1059300002282BD033482C214068095C002941D033 -:10594000007B00283ED001F008FF384323D0002F11 -:1059500038D02C4847683969B86A884221D93C61F7 -:1059600021E02C484168012905D1C068012802D1F5 -:105970001068012802D000F09CFAD7E7012701F057 -:1059800049F801F00EF900F05BFACFE700F046FAB3 -:105990001C48047083E00120FFF7CAFE002811D0E4 -:1059A000F8BD081A3861396900917D2149020098D3 -:1059B00016F0BFFF7D22C0B2520200995043081A70 -:1059C000801838610F4F786820300473F878FDF73D -:1059D000A3F90020FFF734FE3C70082000F003FA22 -:1059E000012013490004486012482DE03DE08EE09C -:1059F0003DE02FE000ED00E000E400E0800000105A -:105A00000017004088000020C01F00400012004026 -:105A1000001300400011004000100040000A004048 -:105A2000001500401E00010121100000FFFF0000D2 -:105A300000830040008000404085004040810040DD -:105A400000F5014000140040C660FF20913049E09D -:105A50002C70F8BD0D4609780229F9D0407801F084 -:105A60001CF9E878FDF758F9F2E70C70F8BDFE4A2A -:105A70001368002BFAD014602C22125C002A3FD04D -:105A80000F460978022907D0007B00280FD001F0CB -:105A900064FE002806D00AE000F0C0F93C70FDF773 -:105AA00069FBF8BD0020FFF743FE0028F9D1012073 -:105AB00000F099F9ED48006900F0FBF978682030B2 -:105AC0000473F878FDF728F90020FFF7B9FD3C7062 -:105AD000082000F088F90120E54900044860E54805 -:105AE000C66096202860E048046000210820FFF787 -:105AF00075FD082000F07FF9082000F06DF9F8BD71 -:105B00000878012803D0286896302860F8BD00F096 -:105B100085F9C4E770B5D84D6860012000F063F9DD -:105B2000012000F068F900210120FFF757FD012056 -:105B300000F052F90024D148AC60FDF761FB6968C0 -:105B40000870CC71012008724C728C72CC727D206E -:105B50000C734002086120310C732C706C70AC70B7 -:105B600070BD10B5C4484068C179002903D0002138 -:105B7000C171FFF796FB10BD10B5BF482D224168DB -:105B8000525C002A0AD00978002907D00178002940 -:105B900004D00221017001780029FCD172B6FFF710 -:105BA000E0FF62B610BDB4488168002901D0002032 -:105BB0000847704710B5002805D0AF4CA060B0482A -:105BC000FDF786F8E07010BD70B50C46054600F094 -:105BD0003BFE2246294616F043FE70BDF8B5A64CA2 -:105BE00015460026626801275670D0615176002B59 -:105BF00001D0177500E0167501F07DFD002804D076 -:105C000060687D210776C90003E0606803210176A2 -:105C10009C496918016261684D62086A643888624B -:105C20000E7308781431FDF7D8FF2770F8BDF8B56A -:105C3000914C164601256268069F5570D0615176D9 -:105C4000002B01D0157501E00020107501F053FD07 -:105C5000002804D060687D210576C90003E06068F3 -:105C60000321017687497118016261684E62086AF2 -:105C7000643888620F7308781431FDF7AEFF257021 -:105C8000F8BD10B57C48C078FDF746F810BD10B5DA -:105C9000FDF7BDFD10BD10B5FDF721FB10BD764928 -:105CA00049688871704774494968887070477249BB -:105CB00049688880704770494968C87070476E4964 -:105CC00001204968C8727047F0B56B4D0746686897 -:105CD000C1B0807A002831D16B480026C663012408 -:105CE000C463FFF799FCFFF7B3FA6A6867489179D4 -:105CF000C160066191788160654BF90716D0AA21D1 -:105D000041626449C161082141616349816146631F -:105D1000FE216D46297000216E187170491CC9B2B0 -:105D2000FE29F9D345600720186004E01C6057493C -:105D30000320403108604D480460947241B0F0BDCA -:105D400070B54D4D6868807A002814D0FFF788FC44 -:105D50004F4800240460514804614C4940310C60B4 -:105D6000424A0121116101690029FCD00461FFF759 -:105D700098FA6868847270BD4848C069002804D0E9 -:105D8000424840308068404240B270473A4880788C -:105D9000704710B538484068C179002903D1012106 -:105DA000C171FFF755FA10BD334949680872704751 -:105DB00031484068007A70472F484068407A01288F -:105DC00000D0002070472C484068407A022801D05B -:105DD0000020704701207047C106C90E012088408D -:105DE0002F4908607047C106C90E012088402C4920 -:105DF000803108607047C106C90E012088402949DA -:105E00000860704710B5284CC3001B1919605A6010 -:105E10000121814024481038416010BD10B5012097 -:105E20001349000488601349012048600E4900208E -:105E300008600820FFF7D7FF0820FFF7DCFF10BD40 -:105E400010B50A490120886114490020C8610E205C -:105E500000F065F8012014494005103988600F20D2 -:105E600000F05DF822E0000040810040001000409A -:105E70000083004000800040880000200758000098 -:105E8000A75B0000B80B0000C01F004000150040D9 -:105E900000120040BEBAFECAFF0004030011004019 -:105EA00000E100E080E200E010F50140FFF7D8FBE0 -:105EB00010BD10B500F075FEFFF7C2FF10BD70B544 -:105EC00005461C48002640681B4CC17A002907D0B3 -:105ED000C672606A000A00026062E069E66170BD35 -:105EE000606A000A000260626878FDF72AF8616A59 -:105EF00008436062E069E6612878FDF722F8E1690D -:105F000000060843E06170BD10B501200B49000593 -:105F100088600F2000F003F8FFF7A2FB10BD0121FD -:105F2000064A814091600021C000801801614161F2 -:105F300070470000880000200015004000F5014077 -:105F400070B50C460546FFF7A6FE01462846FEF74B -:105F5000F3FBFE49002805DA4042400216F0E9FC56 -:105F6000201A03E0400216F0E4FC001980B270BD74 -:105F700010B5F74C208F618F626E401AF34980B2E2 -:105F80004843410AC005C00D80186066820500D5EF -:105F9000491CC005C00D6066E06DFFF778FEA06586 -:105FA00010BD8100EB484158084640308278D20746 -:105FB00001D0C07870472031C8797047E64A042183 -:105FC0001078030741D5F8B5F72318401070E04A60 -:105FD000507A8300DF48C358184640308478E4077D -:105FE00001D0C07801E02033D879002804D00128FE -:105FF00004D0022803D101E0032100E00221D748A8 -:10600000D74C85792078C307D148DB0F006E002D6F -:1060100005D0D27ED200E132FFF7E0FD0BE0157A29 -:10602000CB4ACA4ED28D7243520A122D08D0002597 -:106030000095FFF7FCFD2078400840002070F8BD77 -:1060400001250095FFF7F3FDF5E77047C048407A5A -:106050008100C0484058017F490702D50121203006 -:10606000C1717047012A00DC0122491E401ED3077E -:1060700003D0491C0B78401C0370521007D04B789A -:106080004370891C801C0B780370521EF7D1704737 -:10609000C27B0F21521CC27304E0491EC9B2425C8C -:1060A000521C4254425C002A01D10029F5D17047AC -:1060B000002A4ED0FFB5AB4883B001461F311030E7 -:1060C000154601910090102D04D91024A54806F022 -:1060D0009EF805E02C46A34806F099F8002C22D043 -:1060E00003990498491E401E019AE30706D0491CF3 -:1060F000521C0B7816787340401C037063080CD058 -:106100004E785778891C7E404670921C0E7817781E -:10611000801C7E4006705B1EF2D10398001903902C -:1061200004980019049000990F20CA7B521CCA736E -:1061300004E0401EC0B20A5C521C0A540A5C002AE9 -:1061400001D10028F5D1281B05062D0EBBD107B0C3 -:10615000F0BD7047F8B580487D4C00787D4E8107D2 -:10616000607A8300002967DB7F48814D00788207D1 -:106170007E4801780DD17F480078400709D5C806D0 -:1061800007D52878C20904D1A22210432870F258FA -:1061900010712878C7076E48C27E501F002F30D07C -:1061A000754F09072BD57549921FA164082A09DD8F -:1061B000D2B20023891DB81DFFF77AFFA16C787950 -:1061C000487105E0C2B20023491D781DFFF770FF3A -:1061D000607A80003158694804F0FCFBA16C387982 -:1061E00008712878000704D5082265496548FFF73B -:1061F00039FF65488022017811430170F8BDA7641A -:10620000F8BD090718D55D4FC2B2A764F058002346 -:10621000401D791DFFF74CFF607A05228000315840 -:10622000A06CFFF71FFF28780007E9D50822791D29 -:106230005448FFF717FFF8BDF058A064F8BDF8B553 -:10624000474C434D2078800605D400266E87FFF723 -:1062500022FD6E66E865698FE86DFFF771FE28879D -:10626000FFF719FDA865298F6987E865FFF768FEC4 -:1062700007462078F7210840207072B6FFF789FDA5 -:1062800062B64137344801260178314301702F87C7 -:1062900004F06DFBFFF7F5FC2078810601D5304353 -:1062A0002070102028722078202108432070F8BD2B -:1062B000F8B527482D4D017A467A264F102941D14D -:1062C000E91C0978490604D50021417211210172A7 -:1062D00038E02E4C2178CA0634D5FF224272037969 -:1062E0009E4200D10271B00038584030007A8006DA -:1062F00011D5EF2001401D48217000780A07800861 -:106300008000002A01DA801C00E0401C2870F72081 -:106310000140217016E00721304600F06AFA20782B -:10632000EF21084020702878114C80088000401C24 -:1063300028702078C00903D00621304600F059FAB1 -:10634000022020700A480178B00021E0093D0000D9 -:1063500094000020D8040020BC000020B4000020DD -:10636000A3000020EC070020AA000020A0000020CD -:10637000A8000020A10000207A0400203C04002096 -:106380004104002012010020A4000020A5000020EC -:106390003A581171FE490978490603D438582978CA -:1063A0004030C171F8BDF8B5FA4D07468600A859CE -:1063B0004030017A89060DD5C1798907890F0129F5 -:1063C00008D100218171A8594030C179890889001C -:1063D000891CC171EE480078800627D5EE4C618F8C -:1063E000E06DFFF7ADFDEA4909780A07EB4909D5E9 -:1063F000627AFF2A13D09200AA58128A101A80B229 -:1064000058280CD8A8594030007A800606D5607A02 -:10641000874203D10878082210430870F8BD087835 -:10642000C00603D510202072FFF742FFFFF707FFD9 -:10643000F8BD082A01D927207047FFB50546D44882 -:1064400081B00278D348530604D5002D08D13120FD -:1064500005B0F0BDAB00C3584033DB799B0716D0C5 -:10646000CC48AF00C3599C464033D879C40611D4F8 -:106470001B7A9C060BD4440609D4DB0707D15206CD -:1064800008D40A0606D58007800F022802D21520FC -:1064900005B0F0BDA020014002200143C04EBE481F -:1064A000F571427ABF480C46002100789646954225 -:1064B00008D1002806D0430704D4BB490978C9098C -:1064C0002AD10121B54B1B789A0613D5DF22134040 -:1064D000B24A7545137003D1002901D100280FD1AC -:1064E000B24801788906890E0170FF20F0712120E1 -:1064F00005B0F0BD624613791B0601D500290BD00B -:10650000754512D1AA4A00290BD0D11C0C70491E26 -:10651000F7231840087007E0FF20F0711F2005B036 -:10652000F0BD10782043107014789A4861460C71C1 -:10653000C0590822401D0499FFF794FD9648407AFF -:10654000854207D197480078002803D1200601D55D -:10655000FFF77CFD8F49DF23C859403082791A400C -:106560008271FF20F071C8594030007A800605D54D -:106570002846FFF718FF502005B0F0BD502005B0A9 -:10658000F0BD01898388C288481E934201D180B240 -:1065900070479A1A891A0140491E88B27047F0B5AF -:1065A000844B0F461C46064625899888D9886C1E60 -:1065B000884201D1A1B204E0411A691A2140491E62 -:1065C00089B2914227D31446281A734A794985B271 -:1065D0008988D06E0818AC4202D82246394608E0B5 -:1065E000EAB23946FFF73EFD601BC2B26A4879192C -:1065F000C06EFFF737FDB00604D5684880220178E9 -:10660000114301706B48818802890919521E11409B -:1066100081805020F0BD2220F0BDF8B5604C82276B -:10662000A07A012813D1644DA88800280FD05A4EB3 -:10663000706F002804D001210170A88800285BD069 -:10664000207B810706D5A988082902D002E02120F5 -:10665000F8BDA027C00720D1E07A81004D484058FE -:106660000079000614D508223846316FFFF797FFEE -:10667000502859D1306F08303067A8880838A88072 -:10668000B80636D54548802201781143017030E0C4 -:106690004248202201781143017008223946E07AED -:1066A000336FFFF7C6FE5028D2D1306F0830306705 -:1066B000A8880838A880227BD0071AD03F480378E2 -:1066C000590608D5811D097800291DD0490702D433 -:1066D00020210B430370E07A6072364900208880E5 -:1066E000C8802E4801784906490E017050084000C4 -:1066F0002073A8880028A3D10220A072706F002800 -:106700000ED0002101700FE010210B4303702C49C3 -:10671000002008702070B08E7086A0786070DAE774 -:106720001121607A00F065F85020F8BD10B51C4AC0 -:10673000D37A984215D1052907D0062905D0852995 -:106740000FD1FFF76AFF00210BE0FF231A4CD37231 -:106750000020A0809072403C646F002C00D020701C -:106760005372084610BD10B4164B0A4A09292BD0A3 -:1067700002290AD1800010584721095CC90604D4B7 -:106780002721095C00292ED0438410BC70470000EB -:10679000A3000020D804002094000020A5000020C1 -:1067A000B4000020AA000020AB000020A7000020B9 -:1067B000A80000201C080020D4000020A400002015 -:1067C000B3000020FFFF0000810050584724245CE4 -:1067D000E40601D5038400E043845058FE232030B2 -:1067E000437110BC7047418C428A8918418410BCA7 -:1067F000704770B504460D46FFF7B5FF29462046A1 -:10680000FFF794FFFC4B1D786907C90F491E014231 -:1068100017D0FA49CA78561CF6B2CE70202E01D392 -:106820000026CE708978F6B28E4203D1042005434B -:106830001D7035205100F24A545489184870FBF7F6 -:10684000C2FB70BDEF487047EF48704710B5FFF7C7 -:1068500093F9FFF775FA10BD70B505461C4608069A -:1068600001D5104604E0052900D30421E748405C27 -:10687000FFF715FA2846FFF716FA2046FFF724FA25 -:1068800070BD70B5E24C850063590E062033002EB2 -:1068900001DADA7705E0052900D30421DB4A515CEF -:1068A000D977D649497A884204D160592030C07FCF -:1068B000FFF7F5F970BDD64A8300D25820329177A0 -:1068C000CE4A527A904204D110B50846FFF7EBF950 -:1068D00010BD7047CE49800008582030807F704737 -:1068E000CC4B42009952C54A527AFF2A0AD0C84B73 -:1068F00092009A58527B824204D110B50846FFF7A5 -:10690000D6F910BD7047830030B4C148B024C558D3 -:1069100040356C70C4584034A5796D066D0EA57174 -:106920000D068024002D09DAC15840314A70C05844 -:10693000403081792143817130BC70470029FBD000 -:1069400027228900D243511AC25840325170C05890 -:10695000403081792143817130BC7047704770B5F8 -:10696000A64CE18FA06EFFF7EBFAAB49A087097840 -:10697000A74D890706D0617A890069584031897925 -:10698000C90646D4A54910230A781A430A70218FF4 -:10699000E27E081A411E13460D3BDB105B1C090406 -:1069A000490CDBB20004A371000C05D00126F603EC -:1069B000B04201D85818A0710D2A1CD991489849A5 -:1069C000012A00DC0122401E491ED30705D0491CC4 -:1069D00043780E7873404370401C52100BD04678B9 -:1069E0004B78891C5E40467083780E7873408370C4 -:1069F000801C521EF3D1FFF7BFF9617A89006958F4 -:106A000040310870207A122803D1A08F20870520FA -:106A1000A07170BDA3E7F8B5FFF79CFB7F4EF7218F -:106A200030780840307072B6FFF7B3F962B67D482F -:106A3000724C00782546C0072035002805D0E8783C -:106A4000062802D27849085C0EE03078410670488A -:106A500005D500682030807FFFF725F906E0617AD0 -:106A6000890040582030807FFFF71DF9E07EFFF756 -:106A700022F96E486E49007808716E4909788907D5 -:106A800001D4A16C0871C00734D0E07E84460D2883 -:106A900026D969480078C009A06C1DD06646604AB6 -:106AA000012E00DC0126401E521EF10705D0521CAB -:106AB000437817787B404370401C731010D04778A0 -:106AC0005178921C4F404770877811784F408770FB -:106AD000801C5B1EF3D103E00179ED22514001716E -:106AE000554801784906490E01706146A06CFFF7D0 -:106AF0006BF803E00D21A06CFFF766F8E879617A86 -:106B0000884201D1FFF7DBF8F8BD70B5434CF7219F -:106B100020780840207072B6FFF73BF962B6414812 -:106B2000364D0078C00706D04448C078062802D207 -:106B30003D49085C0EE020784106354805D50068DF -:106B40002030807FFFF7AFF806E0697A890040586F -:106B50002030807FFFF7A7F8E87EFFF7ACF870BD24 -:106B600026492648497AC379002229488900092BF9 -:106B700009D0032B0ED0042B04D140582421095CEA -:106B8000C90705D0704740584721095C4906F9D527 -:106B900002847047214B1B78DB06FAD540584284AB -:106BA0007047DDE770B415491448497AC279244C1E -:106BB000012317488900092A44D0032A4DD0042A0A -:106BC00052D00C2A01D0052A4CD1134A12789207D0 -:106BD00048D04258107F400744D518491446487B96 -:106BE0002034401CC5B24D73E6790020002E4DD0F4 -:106BF0000222E2714EE00000A50000209400002077 -:106C000088060020B60400205A040020A2CE01000D -:106C1000D8040020DC070020AA000020A3000020E8 -:106C2000A7CE0100B30000200C010020A800002026 -:106C30007A040020BC000020A4000020B400002042 -:106C4000FFFF000042582725AD5C002D01D01484C1 -:106C500003E0148C558A641914844058203001795B -:106C60001943017170BC70474058014620310A79C0 -:106C7000D207F7D1C979002902D0048470BC7047CB -:106C8000018C428A8918018470BC7047D27FAA4265 -:106C9000FAD8E371487370BC704710B5002801D171 -:106CA000FFF758FAFFF77EFF10BD10B5F74CE18FE4 -:106CB0006187A06EE065FFF743F92087FFF758F979 -:106CC000208FE087A06DA06610BDF3B5CF788B78DC -:106CD0008FB05F40CF700E797E400E714D79B44613 -:106CE00075404D710B95887968408871CA7942402A -:106CF000CA714C7854404C7008940E78A646664091 -:106D00000E70EF24079626408F2466400096744646 -:106D1000BE26344036267440009E3443A646EC24FA -:106D20001E4626402024664074462643B646BC06CE -:106D3000A40E1A26744076463443A6466646D724E7 -:106D400026404724664074462643DB242540112410 -:106D500065403543792604463440502674402C4320 -:106D6000F725154093267540254305D0C8490F984F -:106D7000FFF7B6FD11B0F0BD079C10252C40089D13 -:106D80004126354025436446282634402C43862539 -:106D90002840204313242340BC09A40108701C434D -:106DA0000B9B24252B402343082422401A434A707E -:106DB000110201430F98FFF793FD11B0F0BD70472A -:106DC000704710B504F0B5FF10BD10B5102104F0E8 -:106DD000B0FF10BD00B501461022AE48FFF742F9E2 -:106DE00000BD00B501461022AB48FFF73BF900BDDE -:106DF00030B50D460446002A13D0012A10D1214691 -:106E000003220D312846FFF72DF90A22E11CE81C68 -:106E1000FFF728F92846032221460D30FFF722F913 -:106E200030BD214604220C312846FFF71BF9082209 -:106E3000211D281DFFF716F90422284621460C3093 -:106E4000ECE710B4914B954AD86E1060002090800A -:106E50009349D0804C881481924AFF245472088050 -:106E6000D47288809072586710BC704770B58E4994 -:106E700082008B5840331C7AA40608D4DC79A4071E -:106E8000A40F012C03D1894C2478650601D5152067 -:106E900070BD9D79ED0901D0A02500E020259D71F0 -:106EA0008B584033DD79AD08AD00AD1CDD718B58DA -:106EB000DD7D6D086D00DD758D580023EB81A30627 -:106EC00002D4FFF7BCF906E089584031097AC906B7 -:106ED00001D5FFF768FA002070BD13B582B0714A82 -:106EE0000C466846017A537A407A994205D138288F -:106EF00001D0392801D1FF20507288006A49085812 -:106F00004030007A400703D52146029803F06BFD1C -:106F10000298009068464078421E092A06D801214E -:106F200091405F4A1288114200D0FF2069464872A2 -:106F30000021FF2800D121706846008904B010BDEF -:106F4000402801D2002070470120704710B4544AF5 -:106F5000FF28508002D9FF20013050805388402004 -:106F6000402B09D054884300A34201D898B200E0D6 -:106F7000508053888342F5D14448C16610BC7047A5 -:106F80008188C2880089891A401E014088B27047F2 -:106F9000F8B504464148464E8288C3880089D21A13 -:106FA000401E0240C80600216170050E832192B286 -:106FB000A01C217095420ED93178C9091CD001213D -:106FC0006170D1080170471CD5B2072200213846F4 -:106FD000FBF79DFFF81D294603F05FFD3078C009DF -:106FE00010D02E488188C2880089891A401E01402D -:106FF0000804000C02D005E00020F8BD2078202114 -:10700000084320700120F8BD70B5244D0446A888BF -:10701000E988401A2989491E08400004000C17D04D -:10702000822020700821601C03F037FD2048007882 -:10703000C0090CD0A888E988401A2989491E08404F -:107040000004000C03D12078202108432070012087 -:1070500070BDF8B59446154A06461D461278CB0811 -:107060002120520603D5002E24D13120F8BD0E4A2E -:10707000B40012594032147AA4061BD4D279920774 -:10708000920F022A16D81620F8BD000094000020A6 -:107090005B250000EC070020FC0700201C080020F6 -:1070A000D4000020B4000020D8040020A300002059 -:1070B000A5000020FB4CA27AE77A002A09D0012A19 -:1070C0002ED0022AE0D1F8480078C0090AD01F204B -:1070D000DAE7E80708D0FF2FF9D1D80088420AD1B3 -:1070E000E6720AE0E80701D02020CDE7B74202D1DE -:1070F000D800884201D03320C6E7EC4A60461067CA -:10710000EB48818025730120A072FFF786FAE9071A -:10711000BAD05028B8D0FF21E1720021A172B3E7A4 -:107120002220B1E7DF49897A002901D01F2103E03D -:10713000DE4A00215067017008467047D948807ABE -:10714000002801D01F207047D84A002050677047A0 -:107150000B78042B01D93020704730B4D54C850012 -:1071600062595B064032507A5B0EC009C001184379 -:1071700050726259400649784032400EC9010843B6 -:10718000507230BC002070470A79042A01D33020A5 -:10719000704700B5C74B80001B5890002E30181860 -:1071A0000422FEF75FFF002000BD8200C148835823 -:1071B00059718058C2789207920F022A01D0090AA9 -:1071C00081717047BA4908807047B9490A780270DE -:1071D0000988090A4170704770B5B64C8500665938 -:1071E0002036F17266592036327362592032537359 -:1071F000FFF761FB70BDF0B4AC48002305781A4678 -:10720000002D2DD9AB480427990046580D2434771A -:1072100044585B1C62774458DBB2A7771D2446585C -:10722000640234834658748346580324F4774458E0 -:107230004034A270465802244036F470445820343A -:10724000227144582034627144582034A271445849 -:1072500022844458628441582031CA71AB42D3D34E -:1072600090484273F0BC704710B40A78130782004C -:1072700090481B0F845823774B7884581B071B0FAB -:1072800063778B7884581B071B0FE377CB78845880 -:107290001B071B0FA3774B790C791B0223438458E0 -:1072A0002383CB798C79190280582143418310BC08 -:1072B000704782007F4883581B7F1B071B0F0B7092 -:1072C00083585B7F4B708358DB7F8B7083589B7F29 -:1072D000CB7083581B7E0B7183581B8B1B0A4B7121 -:1072E00083589B7E8B718058408B000AC871704711 -:1072F00010B40A78D40782006E48E40F83584033F4 -:107300009C70835849784033D970805840300229A6 -:1073100001D90221C17010BC7047820065488358B2 -:1073200040339B780B7080584030C0784870002004 -:107330008870C870087148718871C8717047F0B45E -:107340005A4900234A7A5B49840094461D4690427C -:107350000CD10A59FB27203216797608760016716F -:107360000A5920323E4016714E4A55730A59472633 -:10737000B65CB707BF0F022F10D0F043800756D17D -:10738000107FC00733D04C48F60626D5168C178BD5 -:10739000BE422CD386421DD102231CE0434E6045E1 -:1073A00002D1F079082810D020329079401CC6B262 -:1073B00096710A59107F00072CD51046927F203015 -:1073C000964227D30123857124E0107F00072BD537 -:1073D000012329E00123158409E0568C578BBE4216 -:1073E00005D3864201D1022300E0012355840859C8 -:1073F00020304279521CD6B246710A59107F80075C -:1074000008D51046527F2030964203D3FF2E10D06D -:107410000123457108594030C0798207920F022A32 -:1074200002D0C043800702D108592030C371F0BC9C -:1074300070470223EDE721481E4A007881061B4869 -:10744000407A80001058002903DB1D49097889061D -:1074500006D5017F490702D502212030C17170474E -:10746000014620310A79520705D5007F4007F6D53D -:107470000120C87170470020C8710A4948737047DD -:1074800000B50C490F480860084901200870487091 -:107490000C490D4A0846583010606D314320FFF703 -:1074A00055FD00BDB4000020A50000209400002080 -:1074B000D4000020D8040020FFFF0000A800002016 -:1074C000A90000205005002000060020F8B58446E1 -:1074D000FE4800250570FE48FF260090C671FD4855 -:1074E000FD4C021D29460F238F00E551167008320E -:1074F000491C5B1EF8D161460127F84C00290CD0CD -:10750000F849F74A0A6078310A462770677058329E -:1075100002606D314320FFF719FDFFF792FCFFF782 -:107520006AFEF14900200870F04A02211170FF2123 -:107530002171EF4A6071F04B17701870EF4BED4AF4 -:107540001870EF4B1870EF4B1870A070E07020723D -:107550006172ED4908700D21E1760321A176207753 -:10756000EA48A086009881700A20107072B6FEF773 -:10757000F8FA62B6E64E00203146FFF7B1F9E54F62 -:10758000012569007E52617A3046FF2907D0D54A2D -:10759000890051584A7BAA4201D1FEF788FB6D1C35 -:1075A000EDB2082DEDD3009900200871411EE1864F -:1075B000D949DA4A08702178491E1170C949FF2655 -:1075C00013789C000D594035A8710D594035E8716C -:1075D0000D59403528720D59403568720C594034A8 -:1075E000A6725C1E1470002BEAD1F8BDF0B50278CB -:1075F0004378048941680F2A21D893421FD8002A72 -:107600001DD000291BD0002C19D018461525684321 -:1076100084460846022A06D9951E002D03DD58250A -:1076200055436818B038002B00D06044401A80B22F -:10763000A04204D8201A864680B2402801D20020F9 -:10764000F0BDA648A74C027043700020A44F08E08C -:10765000582545438600ED19401CC0B2A5510228AB -:1076600001D29042F4D3951E002D10DD0020EDB222 -:1076700058264643870076183F19401C6D1E2D067C -:10768000BE602D0EF4D1582042435118B039002B62 -:1076900015D0A3480022DC0702D008300122016087 -:1076A0005B080BD0152454436418846015341030E3 -:1076B000921C5B1E1B0604601B0EF3D161447046D6 -:1076C00080B2FFF743FC0120F0BD89490A780243EC -:1076D000C0060A70000F00D03320704784490A7832 -:1076E00082430A707047824800787047814800786A -:1076F0008006C00F70477F4800780007C017401C05 -:1077000070477849800008584030C0797047754903 -:1077100080000858403080798006C017401C7047B0 -:1077200010B50C466F4980000958204603F052F905 -:10773000A0784006400EA07010BD6A49800008582D -:10774000C0787047810067484158088A4031C9793C -:10775000C90601D55B3080B2704768480078C00622 -:10776000C00F704710B55A4C5E4AE0718000105847 -:1077700003F030F9FF20E071002010BD70B5594DC5 -:107780000C468600A9594A8AA2420FD20B8A9A1A3D -:107790000A82A95912190A825049497A884205D1A8 -:1077A00054480078000701D5FEF749FDA8594482E6 -:1077B00070BD4C4980000858408A7047494A800093 -:1077C0001058403041717047464A8000105881750A -:1077D0007047444A80001058818270470907C90EDB -:1077E000404A80001058C17570473E4A80001058CA -:1077F0004030017170473B498000085840300079A3 -:107800007047384A8300D258C9074032D379090EED -:107810005B065B0E0B43D371304A527A904205D11E -:10782000404802785206520E0A43027070470B46D7 -:1078300000B52C49800009580822491D1846FEF75A -:1078400011FC00BDF0B4274B80001D584724645D37 -:10785000A40702D0F0BC15207047082A02D3F0BC60 -:107860002920704700242035EC771D58422620350A -:10787000AE771E58B025403675701E58022540362A -:107880007571FF261F583D36BE821F580A26BE75E9 -:107890001E580909F4751E580901403634711E58E6 -:1078A000491C35711D584035E97101211D584903A6 -:1078B000698219584A7319584C711858C178890748 -:1078C000890F022900D0847117482FE0BC000020E6 -:1078D000B4000020000600201405002094000020C1 -:1078E00050050020D8040020AA000020AB00002092 -:1078F000A2000020A3000020A4000020A50000207A -:10790000A6000020A8000020A10000208A0C000092 -:107910005B250000DC070020B9000020A700002044 -:10792000F8050020A0000020B30000200470F0BC87 -:1079300000207047F8B50C46FA4A8100535840338E -:107940001C725558630713D500232035AB72555868 -:107950004B262B85575803232037FB725758272572 -:1079600020373D73515820314E731946FEF7A3FF5F -:10797000C820044201D03320F8BDA00602D5EA4950 -:10798000002008710020F8BD8300E648C15840314E -:10799000CA799207920F012A01D015207047002260 -:1079A000CA71C0584030027210467047F8B5DD4CBD -:1079B00005468600A059014640310A7A920604D451 -:1079C000C9798907890F012901D81520F8BDD64F3B -:1079D0000621FD7120308172D448417A8D4205D153 -:1079E000D34810220178114301701AE001798D42C9 -:1079F00001D1FF210171A0594030C1798908890066 -:107A0000491CC17107212846FEF7F3FEA0590079F1 -:107A1000000603D506212846FEF7EBFEA1590220F9 -:107A20000871FF20F8710020F8BDF8B50446C14880 -:107A30000078800601D51920F8BD0020FFF716FA5E -:107A40000028F9D1BA49FD2208781040E207920FC8 -:107A500010430870B34CB848216802F0BBFFB3492B -:107A600001200B78012B0DD9202602278200A15876 -:107A7000401C40318D79C0B235438D71A158984278 -:107A80000F71F3D3A948112101720020F8BD70B520 -:107A9000A54CA649E0714A7AFF25022190420AD1FD -:107AA000A64A1278002A02D0E571002070BDA44ACF -:107AB0001170A44A11709B4A8300D6583171D15875 -:107AC000202340318A791A438A710621FEF791FEFC -:107AD000E571012070BDF8B5994900240B789A49E9 -:107AE0005D06097820D4002807D0480703D5C806CA -:107AF00001D4382413E0052411E093484A0706D541 -:107B0000CA0604D43924F7221140017000E006248B -:107B1000980604D48D4801788906890E01700220E8 -:107B20008749012208704AE0844B1B78002B46D01D -:107B3000002805D048072BD5C80629D538242AE0C7 -:107B4000480703D5C80601D5392400E00424774945 -:107B50008878CB78497A984211D07D4A4500AE1892 -:107B60007778802F04D1555D8D4201D1FF25757046 -:107B7000401CC0B2202800D300209842EED16948B2 -:107B800089004058EF22403081791140817102E034 -:107B9000002002F0B8FF6F49EF250878684B0246D5 -:107BA0009206D20F284012011043DF2210400870C5 -:107BB000C81D00781870881D00780007C20F5B4848 -:107BC0000D21C1760027634B07761D78F7263540D7 -:107BD000614E06213770761C3770F1706906490EC8 -:107BE0001970591C0B78BF252B400B70C91C0B78E2 -:107BF0005A49067FDD0705D002252E4306770E7809 -:107C00002E4304E0FD252E4006770E782E400E70A0 -:107C1000382C01D0392C04D14B49FB260D78354046 -:107C20000D70464D3F492F70407AD20785004E595E -:107C3000920E33714959DF2540318B792B40134324 -:107C40008B712146FEF7D5FDF8BD3C480078002831 -:107C500001D000203FE770474378032B01D9332040 -:107C6000704710B4314A937683789C080FD1C4785A -:107C7000002C0CD10479002C09D1137743799C088E -:107C800005D18479002C02D1C479002C02D010BC1B -:107C90003320704753770A2904D3437A047A1B02AE -:107CA000234393860B2902D31F49827A8A7029497C -:107CB00000780A78BF23C0071A40400E02430A70BA -:107CC00010BC002070470022002812D01748837E85 -:107CD0000B70037F4B708A70CA70437F0B714A71BF -:107CE0008A71808EC871000A08720F4880784872C5 -:107CF00004E00320087048708A70CA700020704742 -:107D0000F7B50C4A0C464109C6061278002749010E -:107D1000F60E82B0520623D5002E30D1312005B0A8 -:107D2000F0BD0000D8040020B40000209400002022 -:107D3000A5000020A3000020E0000020AA000020F1 -:107D4000A8000020AB000020A0000020A700002019 -:107D500088060020A4000020B3000020B20000200C -:107D6000FE4AB300D2584032137A9B0607D4D27928 -:107D70009207920F022A02D8162005B0F0BD6207C2 -:107D800002D0272005B0F0BD0A0600D5012749061C -:107D90000A0EF34D0092697A0DD0F24A009B1278D8 -:107DA0009509AD019D4242D0EE489106890E0170C1 -:107DB000202005B0F0BDFF2902D01F2005B0F0BD86 -:107DC000082282213046049BFEF733FB5028F5D170 -:107DD000E5490A78530608D5E44B1B78002B19D0E7 -:107DE0005B0702D420231A430A70E1496E72002215 -:107DF0008A80CA80DF490A785206520E0A70891CAE -:107E00000A789206920E0A7004990831083CE4B28E -:107E1000049116E010231A430A70D74A002111700A -:107E20002970D6498A8E4A86A9786970DDE7B14201 -:107E300002D0212005B0F0BDCD498A88CB889A4276 -:107E400004D1CB490989491E89B206E00989D21AB1 -:107E50008A1A491E0A40521E91B2C900A14202D29A -:107E6000222005B0F0BD002F05D0BE490A78920649 -:107E7000920E0A7006E00099C029BA490A7814D017 -:107E800040320A70002C04D0224600200499FEF7EC -:107E900086FB5028E5D1002F04D0B6488022017817 -:107EA00011430170502005B0F0BD5206520EE8E7B4 -:107EB000F7B58E46AB4909788A0994467246082A76 -:107EC00002D9272003B0F0BD4209C406AC485201D4 -:107ED0000078E40E400604D5002C11D1312003B007 -:107EE000F0BD9E48A300C0584030037A9B0607D4DB -:107EF000C0798007800F022802D8162003B0F0BD99 -:107F00008226100600D5A0265006954D070E687AE9 -:107F1000024643D093488B0900789B018006800E6F -:107F2000BB4204D08F490870202003B0F0BDB306D7 -:107F300002D58C49087004E08A48C02F11D0403126 -:107F400001708648A10040580079000620D5A24261 -:107F50000AD1724630460299FEF721FB502804D11F -:107F60000DE04906490EEBE721207E490A78930689 -:107F70009B0E6246920113430B7003B0F0BDB10635 -:107F8000FBD57C4980230A781A430A7003B0F0BD00 -:107F90007848202201781143017004E0FF2802D0C4 -:107FA0001F2003B0F0BD724631462046029BFEF70B -:107FB00040FA0346002F1FD1502B1DD16A480022E2 -:107FC00001784E06002E08DA861D3678002E16D06F -:107FD000760702D420263143017065486C72828096 -:107FE000C280644801784906490E0170801C0178FE -:107FF0008906890E40310170184603B0F0BD102685 -:10800000314301705C4802702A701F38818E4186AE -:10801000A8786870E1E7F8B504460020207069464A -:108020004870544B5548197882784D0705D4C57867 -:10803000AA4202D168460088F8BD5500514E521C34 -:10804000AD192D886E46D2B235808270202A01D3B8 -:1080500000228270FB20014019703778A770767873 -:10806000404D802E11D0832E76D0842E74D0802E59 -:1080700006D203202070402060700120E07026713D -:10808000382E6AD0392E68D00EE10920207033488E -:10809000BE0081594F20475C50310822E01CFDF79B -:1080A000E1FF2E48815920464B310C3002F092FC02 -:1080B0002A48EF2281594031887910408871274938 -:1080C00089594031C979490628D4390626D580070F -:1080D00008D52878CF2108402870B80602D54F204F -:1080E000607012E050206070202007402878302215 -:1080F000790002400A435100A2780A438106890FA1 -:10810000A270032907D0103028700020E072A078F8 -:10811000400905D0C8E0DF210840F5E74E20DFE741 -:10812000194900200A78D10902D08020E072042089 -:10813000510632D5E17A40231943E17223182021F8 -:1081400019730649401C8B59C0B2403325181B785F -:10815000401C2B73C0B219E042E086E0D804002036 -:10816000B4000020A7000020A4000020AA000020E6 -:108170001C080020A5000020B3000020940000206F -:10818000A300002088060020A2000020895923189F -:1081900040314978401C1973C0B2910618D5F8498E -:1081A00020258A59138AE27A2A43E2728A59518A2F -:1081B000591A4032D27989B2D20601D55B3100E03A -:1081C000153189B222181173090A801C5173C0B28B -:1081D000E17A002901D0401CC0B22178081862E081 -:1081E000E849842E0879844633D04879891DC00631 -:1081F000020E2270E01CFDF735FFE149BA008858F5 -:10820000EF2640308379334083712078401C207002 -:10821000885840308079800703D52878CF210840DE -:108220002870722060706046202108404100287844 -:10823000302202400A435100A2780A438106890F86 -:10824000A27003290ED01030287080206946487033 -:108250002AE08879CC49C006020E2270E01CFDF7A6 -:1082600001FFCAE7DF210840EEE70422C749601D8D -:10827000FDF7F8FE2078001D2070382E14D1C0497B -:10828000B80009584031C979C9060DD5C049085808 -:10829000407C022808D120461322BE490930FDF750 -:1082A000E1FE20781330207021460098FEF715FE7D -:1082B000009068460088F8BD10B5FEF79AFA10BD28 -:1082C000B548407A7047022801D333207047B34A3B -:1082D00010B5C000801814F056FD002010BD022813 -:1082E00001D333207047AD4AC000821810B508464C -:1082F000114614F048FD002010BDFF2903D0CA0626 -:10830000D20E022A06D29E4A800010584030817256 -:108310000020704733207047FFB5054681B09E4866 -:1083200002999F4A40789A4B002954D09D49097878 -:10833000490614D50499002911D0AC0019460959F1 -:1083400000291AD1002818D9471E1646CA009319C9 -:108350001B79AB4211D0FF2B04D0B94209D1332095 -:1083600005B0F0BDC8003158894801519019057118 -:1083700003E0491CC9B28142E8D38148082301596E -:10838000834E4031CA7901271A43CA713259039981 -:10839000117400594030C079C006002878DB30469F -:1083A00002592846802108431021FFF7A9FC5028D4 -:1083B000D6D1794902200A7F02430A777A490A789E -:1083C00002436F480A700359784A197910780E46AB -:1083D000864328D029E000216F4C002810D9CE0018 -:1083E000B6183679AE4207D10020AE009851FF2072 -:1083F000C9008918087103E0491CC9B28142EED353 -:10840000607A854204D16A48F722017811400170F0 -:108410005B48A9004058F7224030C1791140C17132 -:10842000002005B0F0BD384310705548394319712C -:10843000005904224030C1791143C1715448029956 -:10844000035959740359002199740659049BF37414 -:10845000005901755048407A854242D1544D2878E0 -:1084600010432870039810220101524809185248FD -:10847000FDF7F8FD2878F7210840414909594031B6 -:10848000C9790907C90FC9000843287029E0FFE727 -:108490003059102103F04DFC315910224748FDF7A7 -:1084A000E1FD3159002088743159CF743159087574 -:1084B0003948407A854214D10398102201013D4881 -:1084C00009183D48FDF7CEFD3948F72201781140E3 -:1084D0002B4A12594032D2791207D20FD2001143DF -:1084E0000170002005B0F0BD0F2801D33320704784 -:1084F00030B5054602012F48101804461022FDF73A -:10850000B1FD2548407AFF280AD02149800008584B -:10851000007CA84204D1214610222748FDF7A2FD85 -:10852000002030BD10B5002805D0012807D0022852 -:1085300009D0332010BD224802F04CFA03E0132288 -:108540001448FDF78FFD002010BD10B50B46002824 -:1085500009D001280AD0022804D113220D49184657 -:10856000FDF780FD10BD0220087010BD14491846AB -:1085700002F030FA10BDA42924D233207047000045 -:10858000D804002098040020A6040020E800002061 -:1085900014050020C8060020940000207806002062 -:1085A00000060020A4000020B2000020A800002047 -:1085B000A0000020EB060020EC070020FC070020B4 -:1085C000E400002070B4FE4D00222B78002B0DD962 -:1085D000FC4E940034594034247AA40602D570BC71 -:1085E00015207047521CD2B29A42F2D3002803D011 -:1085F000F54A1071E98602E00020C043E88670BCAD -:1086000000207047F04A12790270ED48C08E088051 -:108610007047EE4A0028117802D00220014301E0A1 -:10862000FD20014011707047E9490870704770B42F -:108630008200E448825810462E304032557A6A064D -:10864000520E29D004780123002C02D14678002E46 -:1086500007D00E78A64203D14C784678B44200D0B9 -:1086600000238478002C03D08E78A64200D000230B -:10867000C478002C04D0CE78A64201D0001D05E0BD -:10868000001D002B02D0E80906D008E0521E120699 -:10869000120ED7D1E80902D070BC0120704770BC1F -:1086A00000207047F8B5CB48CB4A00781378C40750 -:1086B000CA48C34D017802D0D8070FD10CE0C74893 -:1086C000CC067DD5EF242140017058084000107081 -:1086D000287F800775D4D0E2C80671D5687AB94E74 -:1086E00080003158BE4CBF4FBF4802F073F9BF48FD -:1086F00000784107B44873D5B84909788C46C90653 -:108700006FD502780223032A6FD006DC002A09D035 -:10871000012A30D0022A7DD139E0042A7BD0FF2AF9 -:1087200078D116E02178641C22295CD12278AB7EB6 -:1087300061789A4201D22A7600E02B762A7F13468E -:108740008B4350D16B7FAA4C19400A432270FF2102 -:1087500044E02178222946D1297EA54CC900891DF3 -:1087600069762178A34A8B089B0089071370890FCB -:108770002170FE2109E02178242966D19D49012339 -:108780000A781A430A70FE21C170017084E02178D2 -:10879000641C292959D1974A1178194311702378FB -:1087A000641C22789449641C0A7022784A70641C04 -:1087B00022788A70641C2278641CCA70012B01E044 -:1087C0005BE210E00FD0697A23788A008B498958E0 -:1087D0000B708A4B61789A585170032101706BE0DD -:1087E0007CE110E201E00520F8BD2178641C2A2913 -:1087F0002BD1804A117819431170697A7F4A890018 -:108800005258237893707D4A63785258D370A37876 -:108810007A4A01E019E014E052581371774AE3787C -:1088200052585371754A237952589371734A637938 -:108830005258D371714BA27959580A7204210170B0 -:108840003AE02178641C2B2902D0FE2A24D033E0A0 -:10885000684A117819431170697A684A8900525838 -:1088600023785372654A637852589372634AA378A7 -:108870005258D372614AE378525813735F4A23798E -:10888000525853735D4A6379525893735B4BA27984 -:108890005958CA73FE210170554C2278002A0BD01A -:1088A0000121D307DB0F04D14906090E13460B4201 -:1088B000FAD001708A432270007803287ED004DC4D -:1088C00001282AD0022804D19FE0042877D0FF286D -:1088D00005D042486146EF221140017001E23E4955 -:1088E0000122087810430870387020207870287EA4 -:1088F000B8703F4804220078F87000203871787111 -:10890000B871F87138720D206876687A8000305836 -:108910002030017911430171AAE1288F0007000F6F -:108920000C2800D90C20C11CCAB235490A7000922B -:1089300002462A32D2B2CA70322A01D13022CA701B -:108940006A7A92009446B2582032947F23071B0F14 -:1089500043400C2B00D90C2318461030C2B22730EC -:10896000C0B24A700871392802D04D79422D01D128 -:10897000801E0871200958400C2800D90C2003469D -:108980001D338B704430144D48712C7801263443CC -:108990002C703C7023247C70FE24BC70009CFC7006 -:1089A0003A717B71CA78BA710979F97138720548E0 -:1089B0006146405820300179042223E04AE06BE010 -:1089C00094000020D8040020B4000020A300002060 -:1089D000B9000020A9000020A8000020A400002069 -:1089E000BB0400207E0400207A040020AA0000209E -:1089F000B2000020B3000020E80000201405002091 -:108A00000C0100201143017132E1FE490122087876 -:108A100010430870387026207870687AFA49800010 -:108A20000958497CB970F9490A78FA704A783A715C -:108A30008A787A71C978B971F5490A78FA714A78F1 -:108A40003A728978797230580422203001791143C2 -:108A500001710DE1EB49012208781043087038706C -:108A600027207870EA480422C178B9700179F9703A -:108A70004179397181797971C179B971017AF97165 -:108A8000417A3972807A7872687A80003058203062 -:108A9000017911430171EBE0DA49012208781043B2 -:108AA0000870387028207870D9480422C17AB970CB -:108AB000017BF970417B3971817B7971C17BB9711F -:108AC000017CF971417C3972807C7872687A80000F -:108AD00030582030017911430171C9E022217970A9 -:108AE000A97EB9700321F970002139717971B971CA -:108AF000F9712178641C203909297DD20B007B444F -:108B00001B79DB189F4404EDED17EDED4082BB00AF -:108B100021782976BF4A637813700622C270C80094 -:108B2000801D6876687A04228000305820300179F0 -:108B3000114301719CE02178C170B74967780F70CB -:108B40000097A7784F70BE46E7788F702379CB7077 -:108B500062790A71A4794C71BC46B04924274F71DF -:108B6000C0788871009FCF7177460F7267464F7249 -:108B70008B72CA720C73687A0422800030582030DD -:108B800001791143017173E0687A9F4F8200BB58ED -:108B900021785974A24963780B70A3784B70E378FD -:108BA0008B702379CB709A4963790B70A3794B70E2 -:108BB000E3798B70B9589B4C497C012901D002297B -:108BC00022D19749FFF733FD00281DD0002029212D -:108BD000217060708D480178A1704178E1708178D2 -:108BE0002171C0786071687A800039580978A17164 -:108BF00039584978E17100E073E0305804222030A0 -:108C000001791143017133E00120E0E780482178C8 -:108C1000C17061780171A1784171E1788171217928 -:108C2000C17161790172A1794172E17981727B48E8 -:108C30002A214171697A744A890053589B7883715B -:108C40005358DB78C37153581B79037253585B79BF -:108C5000437253589B7983725358DB79C3725258CD -:108C6000127A027370580422203001791143017185 -:108C70006D4808220178114301700220F8BD644854 -:108C80002178C17261780173A1784173E1788173B1 -:108C90002179C17361790174A1794174E179817499 -:108CA0005E482B214171697A574A890053585B7A93 -:108CB000837153589B7AC3715358DB7A03725358AC -:108CC0001B7B437253585B7B837253589B7BC372ED -:108CD0005258D27B0273705804222030017911431C -:108CE000C5E7687AFB2280003058203001791140B6 -:108CF000BDE7F8B54D4801784A064D49520E0D784A -:108D0000AB07DB0FDB011A430270E8090AD04948C0 -:108D10003C4C02782078930719D0014669404B06F5 -:108D200001D40520F8BDC90602D4410602D503E0EE -:108D3000410601D50320F8BDA90606D5510701D586 -:108D40000420F8BD2021084320700220F8BD5021E6 -:108D50000D4201D00720F8BD3749384B08700D216E -:108D6000D976002230491A760978F7263140294E03 -:108D70003270334E3270B77877709E8E5E86DF2603 -:108D80000E40C906C90F49010E43EF210E40264986 -:108D90000E7071061AD52B4E012720491F763778A1 -:108DA0000F7077784F70B7788F70F678CE70032693 -:108DB0000E7122274F719B7E8B71CE710A724A729F -:108DC0008A72CA720A730121084320701E4E3078DD -:108DD000010714D5E90712D0C00610D51B4813F0BF -:108DE000BBFF08221A491B48FDF73CF9194910221C -:108DF0001948FDF737F9307804210843307020789E -:108E000000072BE0A800002014050020E40000204B -:108E1000C8060020B30000200C0100207A040020C6 -:108E2000E80000207F040020A4000020A300002010 -:108E3000A9000020AA000020AB0000209400002020 -:108E4000B4000020B6040020A0000020E3060020AB -:108E500012010020DB060020FC070020FE49000F65 -:108E6000097809090901084320700120F8BDF8B507 -:108E70000546FA48FA4C007801071DD5400708D589 -:108E8000F5480078000704D50822F649F648FDF7B2 -:108E9000E9F8E07E0146801F082805DDC2B2F348EC -:108EA0000123811D801D05E0491FF048CAB2411D04 -:108EB0000123401DFDF7FCF8012D01D0002D36D116 -:108EC000EB48FB22017811400170607A8C468100EA -:108ED000E84841584A20405CFF2828D0C206E34FAA -:108EE000C0093B79D20EC0011E0608D500281ED04D -:108EF000A02098431BD1E0480078800717D1DF4BB2 -:108F00000020D200D31802465032D84F8E5C1A5C33 -:108F10003F187F7916401740BE4208D1401CC0B2AE -:108F20000828F0D3D2486146042211430170022D73 -:108F300001D0042D04D1FFF7B5FB022800D005466F -:108F4000002001220227CE4ECE49082D77D22B00D9 -:108F50007B441B79DB189F4403072DAFECF19E0582 -:108F600001F0BDFD0020F8BD307850214840307040 -:108F7000607AC04985004C59BF4B4034A0793843D2 -:108F8000A0718406E40F4959E40022431A70DF22DD -:108F9000403110408871B1480078410701D5C006C2 -:108FA00005D4AD480078800601D401F098FDFDF7A6 -:108FB0004DF8B9E0B04B0C251A782A403A431A70A4 -:108FC000327810235A40B04D32702B781F0702D5EB -:108FD0008878487000E04870AC48BF270178394075 -:108FE0000170500607D59C480078800650D40120B7 -:108FF00001F089FD4CE0D80603D5802003432B7097 -:1090000042E0D00726D0A24F217E381DFDF7C0FFD9 -:10901000002815D030783979DF2208433070387154 -:10902000A08E6086607A81009248405840308179F5 -:1090300011408171287880210843287024E07DE068 -:10904000607A202281008B4840584030817911435A -:10905000817119E0607A874D80002858001DFDF766 -:10906000D3FF002808D0617A3078890069580A79DE -:1090700010433070087107E0607A20228000285881 -:1090800040308179114381718521607AFDF7B1FB10 -:10909000FEF7D1F948E0784A1278520702D43278C4 -:1090A000920646D4627A9300724AD258403292793C -:1090B000D20601D46D4A50716F4A107803091B0122 -:1090C000502B3BD2931F1B781B0718D5638E002BA8 -:1090D00015D045070FD4850711D0657AAE00654DD0 -:1090E000AD594035AD79ED0609D5252168485B1E9F -:1090F0004171638612E05D4D6D79252D16D01030DB -:10910000C3B2180900011370502807D3487800280B -:1091100004D01B071B0F1370401E487010780321EA -:1091200080088000084310700120F8BD5B1E638634 -:10913000F4E70120FEF7CFFC0020F8BD0020FEF789 -:10914000CAFC0FE7534909788A07484907D4C2780F -:10915000002A04D0CB789A4201D00020704730B466 -:109160008478424B62069B78520E03D05D066D0EEA -:10917000954212D10278002A05D14578002D02D1FE -:109180005C40230606D50B789A4206D14078497890 -:10919000884202D130BC0120704730BC00207047AB -:1091A00070B52F4D298F401884B2698FE86DFCF798 -:1091B000C7FE401C83B23848F7220178CE07002E44 -:1091C00002D02C8711400DE0294E367836070BD49B -:1091D000E31A01269BB2F603B34205D911400122DE -:1091E0002C871143017070BD2C8701F0C0FB70BD4E -:1091F000F8B519481F4D07781538437A1B49980070 -:1092000028580C79144906460C701539CA790F3163 -:109210000E360978052A7DD006DC022A5AD0032AA8 -:109220003FD0042A55D15CE2082A43D0122A50D1FB -:109230000E490B4C1846FFF7FAF9002849D0607A1E -:109240008000285840308179CA0642D4C90928D004 -:1092500000214156012221E0A9000020A0000020A9 -:1092600094000020BB04002012010020B60400205E -:10927000A3000020D8040020AA00002078060020C7 -:10928000A8000020B4000020A4000020A5000020B9 -:109290007A040020A1000020BC00002082569142E8 -:1092A00017DBFE4F3878C0067ED5FD4CE0790328E9 -:1092B0007BD118E1C9060CD4018A428A8918F94A7F -:1092C0008918018200203080F74803220178114379 -:1092D0000170F8BDC90669D5210767D5403082798C -:1092E000FD231A408271F148ED49027813090A788A -:1092F0001B011407240F2343521E0370D4B2A7008E -:10930000E859FFF71FFF00285AD0E85901464031BD -:10931000CA7900E078E113231A40032A02D0022A16 -:109320000BD04DE0E148DE4A0178127809090901C5 -:109330001207120F1143017047E0D94A1279A24275 -:109340000FD084462030837F900028580090203032 -:10935000827F934234D100986246527B407B8242A6 -:109360002ED1D24800780207CD48120F00788242F1 -:1093700002D0087AC00723D1CD492046FFF757F91C -:1093800000281DD0E85940308179C90910D0C4495E -:109390000022497A012389006958C35640318A5610 -:1093A0009A420DDB097802E0E3E0A0E061E00170A1 -:1093B000BE492207087800090001120F1043087007 -:1093C0002046641EE4B2002899D1B848B44A017816 -:1093D00012780907090F91424BD08800285848217C -:1093E000095C2C46C90726D1B04FB14901F0F2FA09 -:1093F00038780107090F8B00E25803204032D779F3 -:109400000743D771E25840329379DF0902D05B06F7 -:109410005B0E9371A24A537A994205D1FF231371CF -:109420000C32137803431370084601F0F1FBA14896 -:109430000078C0091DD19D4F472138780007800E64 -:109440002058095C890614D4994A002111714B30C7 -:109450000D229749FCF706FE387810230007000F0D -:109460008100615840318A791A438A718021FDF761 -:10947000C0F98B48407A81006A5840325279FF2AFD -:1094800000D126E732780A2AFBD30A3A32708A4A98 -:109490001378DC0712D07478641CE4B274706F58CF -:1094A00040377F79BC42ECD35B085B00137000222D -:1094B00072706958897D00290CD0F8BD6A58927D78 -:1094C000FF2AFAD07278521CD2B272706958897D24 -:1094D0008A42F2D3794910230A781A430A7001218B -:1094E000FDF787F9F8BD73480078000741D5607A29 -:1094F00080002858FFF726FE00283AD0607AFD2326 -:109500008100695840318A791A408A7101F080FBE4 -:10951000012001F057FB002819D0E079122807D16B -:1095200066480078800703D56248007800070ED5AA -:109530000620E0715C480078C10901D1400602D5DF -:1095400001F0CDFA03E0FFF7D4FBFFF790FC387889 -:10955000400707D556480179607A80002858403086 -:10956000C173F8BD607A5249800028584B300D22F3 -:109570000CE138784006F4D44948514B407A022136 -:109580008200AC58678A9F42737814D95B1CDBB2A7 -:109590007370042B28D344490B789B089B009B1CB9 -:1095A0000B70AB580821DC7D64086400DC75AA5898 -:1095B0000023D38118E03F0AFF18FFB2BB4201D15C -:1095C0007F1CFFB2BB4201D277700DE036490B78A9 -:1095D0009B089B009B1C0B70E37D08215B085B00D4 -:1095E000E375AA580023D381FDF703F935480078C5 -:1095F000C009B6D02C4800788007800F0228B0D16F -:109600000020FEF768FAF8BD0624C90610D5FFF75A -:1096100099FD00280CD02248FD22407A800028586D -:109620004030817911408171FFF763FB044601E00E -:1096300020480770244800784007C70F2046FFF7EE -:1096400016FC8446062C14D01A480078C00707D0B0 -:109650001348017E002903D0C27E15491B4806E04D -:109660000F480D22407A1249800028584B30FCF7F1 -:10967000F9FC60460028C6D109480021C1710A4999 -:10968000002F097824D0C906BDD5062C04D1034982 -:1096900080230A781A430A700B211CE0A3000020E3 -:1096A000940000200300FFFFA0000020A70000207E -:1096B000B6040020A9000020A4000020A50000207E -:1096C0005D740000A8000020AA000020980400207B -:1096D000C90602D40521C171F8BD062CFCD10421B4 -:1096E000C1717278002A1DD0FE49FF4B887A497AF1 -:1096F000890069584C8A9C4200D94008D20902D19D -:109700000A8A121A0A8271784A06520E824202D8D6 -:109710000020707006E0CA09081AD2014006400E07 -:1097200002437270F1480078C006D5D5ED4C607ADE -:1097300080002858FFF706FD00286DD0EC4F3878E0 -:10974000400769D4607AFD22800028584030817932 -:10975000114081710A20E071E6480078C10901D109 -:10976000400602D501F0BBF907E0FFF7C2FAFFF7A8 -:109770007EFB002801D00520E0713878C00708D0B2 -:10978000207E002805D0E27EDB49DC48FCF76AFC3D -:10979000F8BDD6480078400707D5D7480179607AE8 -:1097A000800028584030C17307E0607A0D228000A5 -:1097B0002858D1494B30FCF755FCD14A1378D807CB -:1097C000E6D0607AA0278400285901464030C67B45 -:1097D0003E42DDD0067C442EDAD1467C022ED7D123 -:1097E000C07C5E0703D54007000FC64E02E040076D -:1097F000C54E000F305A002808D00E8A4F8AF61B3B -:109800000E82295936180E82295948829807BFD4EA -:10981000580840001070F8BDB5480078010701D421 -:109820004007F8D5707800281FD1FCF734FAC0B291 -:109830001A2113F07EF80746FCF72DFA1A214F4340 -:10984000C01BC0B24106490E70700D2905D280219F -:109850000843C009C0017E3006E00721C841192134 -:10986000C90640181921C8417070A1480078400706 -:1098700003D570784006400E7070A449A08F0A7816 -:109880005307C8D4238FC01A1330012380B2DB03DF -:10989000984201D9032006E0022801D2022002E00A -:1098A0000428B8D2012004231A430A70617A89007F -:1098B00069580A8A101A0882F8BDF0B48B488D4C9A -:1098C0000178954F4906490E01700F38417A8A0098 -:1098D0008F498A588F49138A038615790D7011466E -:1098E0004031CE792670B407A40FC471097A39705B -:1098F000F10608D5A41DC4710824F91D25430D7077 -:109900001571DB1E0386002101768049FB230A784E -:109910001A400A702021C185C1790172F0BC7047DC -:109920007248007840067DD4F0B56E488BB0018F48 -:1099300009318FB2017A102901D10C37BFB2417AB7 -:10994000734A8900515840318979490703D5018EFE -:10995000FF392D390186018E791A018600246C4960 -:10996000A50048594722125C9207920F012A74D928 -:10997000664B1B780593DB0706D05A4E33799C4221 -:1099800002D1338E5A333386038AF91A8EB255497F -:10999000098E8E427ED8032A10D052480079079152 -:1099A0005B4901904859034640339C46DB790246A7 -:1099B0009E070E32B60F022E6DD0FBE0428A54494C -:1099C0009A1802824748407A844211D14A590020AD -:1099D000907348594030C07900075BD54F484059D3 -:1099E000017D002956D1817CC27C89188174ECE00C -:1099F00080004749079008584721095C8907890F6B -:109A000002295AD04249468A48590890408A009013 -:109A1000864214D90146304612F08BFF009941432B -:109A2000701A00E0F6E0009980B24908814204D241 -:109A30000099081A80B2002111E001210FE031469F -:109A400012F077FF00997043081A80B271088142C2 -:109A500004D2301A80B2012101E0C1E000210028C7 -:109A600000D10121089A927B521CD3B2089A022B92 -:109A7000937306D3264A04265259403293793343CE -:109A80009371052819D2224E079846223058125C4D -:109A9000520701E06BE06BE001D500290DD11549BB -:109AA0000A78132191433FD01A4904200A780243CF -:109AB0000A701B490A7802430A7009212046FCF704 -:109AC00098FE134840594030C07900077DD5134AAD -:109AD00000235059C07C002877D951590F20CE7BE4 -:109AE000761C1FE0940000205D740000A30000209D -:109AF000A9000020A0000020B60400209804002047 -:109B0000B9000020D6CE0100C6CE0100A40000207E -:109B1000D8040020A8000020A10000201405002087 -:109B2000AB000020CE7317E00599FA4A4907C4D468 -:109B30000599042319431170028AD21E02820798E4 -:109B40003058C17B0029B8D17E21C173B5E7401ED2 -:109B5000C0B20E5C761C0E540E5C002E01D10028A3 -:109B6000F5D150595B1CC07CDBB29842B5D82CE0D3 -:109B7000DB061FD4038A868ADB04DB0CF618B6B238 -:109B80009E4201D2082300E0730B0093019BA34285 -:109B90000CD0FF2B0ED063461B79002B0AD0C37D5F -:109BA000019880000858C07D834203D11378009843 -:109BB000181810704A59138A908A18181082381A87 -:109BC00082B20798824200D8ECE6D2480078C007FB -:109BD00006D0D14801798C4202D1018E5A390186D2 -:109BE000CD48641C0078E4B2844200D2B7E6CA488B -:109BF0000786407A8300C948C058403081794A07B7 -:109C000002D5FB2211408171C5490020C958087551 -:109C10000BB0F0BD7047F0B5BF4885B010210172A0 -:109C20000D21C172017910300078FF29844603D0DC -:109C3000C00701D1B849C871BA480678BA4800903F -:109C4000BA480490B448B107447AB948A2000078F1 -:109C500000297AD0B049B84BCF79B6491D78097838 -:109C60000391B649CB785B1CDBB20293AA4B052F5C -:109C70005B7E019322D0A84B062F9B7907D0092F3A -:109C80007AD00C2F33D00020FDF725FF60E1A249E8 -:109C90000C230B720B469B79ED095B00002D03D062 -:109CA0002525EB1ACB7202E01625EB1ACB720523A1 -:109CB0008B7100075FD5FF2C79D149E196480C22C2 -:109CC0000272EA0901D00722C2726246120752D517 -:109CD000720701D40D2168E0039AD20705D0029AD9 -:109CE000CA70062A01D10022CA70C37630E1904CB6 -:109CF000C00607D492480078800603D5B007800FCD -:109D0000012808D0844805220272EA0938D02322AB -:109D1000D21AC27237E00120FDF7DDFE00F095FF98 -:109D2000002828D07C4D0C202872217808071AD5ED -:109D3000687AFF2817D0490708D4810078480122A3 -:109D400040588049FDF754F808E041E0049813F0CA -:109D500003F808227C497B48FCF784F979491022F2 -:109D60000098FCF77FF974480078C009A87904D0FE -:109D70007621081AE872EBE01AE07821081AE6E08A -:109D80003822D21AC272624612077AD5720702D5F9 -:109D90000D21C176DCE0039AD20705D0029ACA7081 -:109DA000062A01D10022CA700199C176D0E008E0EC -:109DB000594905230B723523CB72000761D5FF2C5F -:109DC0005FD057485F4980580022FDF711F878E0CE -:109DD000514D0421EE79761F072E52D233007B4479 -:109DE0001B79DB189F44733DB4B4030D2500430673 -:109DF00047D429723521E972000742D5FF2CE0D102 -:109E0000A6E0297200070CD5FF2C0AD044484D4922 -:109E100080580122FCF7ECFF4A4910220098FCF719 -:109E200021F945480078C00901D03A208FE0602030 -:109E30008DE0297200070CD5FF2C0AD03848414923 -:109E400080580122FCF7D4FF3E4910220098FCF70D -:109E500009F939480078C00901D04A2077E05F202D -:109E600075E000F0F2FE002872D00C202872324813 -:109E70000078C009A87905D041002520401AE87271 -:109E800004E065E041001620401AE8720520A87140 -:109E90002748007801075BD5697AFF2958D0400729 -:109EA00007D41F488900405800222649FCF7A0FF2C -:109EB00007E0049812F050FF082223492148FCF7DC -:109EC000D1F8204910220098FCF7CCF840E000F0CF -:109ED000BCFE00283CD00C202872154800780007F2 -:109EE0000ED5687AFF280BD081000D48012240581A -:109EF0001449FCF77DFF134910220098FCF7B2F8D3 -:109F00000D480078C00921D02020E8720620A871F1 -:109F10001EE00000A400002094000020D8040020CF -:109F200014050020AA000020FC070020E306002002 -:109F3000A0000020B3000020A3000020B4000020F7 -:109F4000A8000020DB060020120100200D20E8728E -:109F5000FC4CE07AFFF724F91020E0721520E08530 -:109F6000207AE07105B0F0BDF0B58FB0F648F54B42 -:109F70000690597A0091002119721A8F18860932B9 -:109F800094B2FF20F14A58721070187905901B782E -:109F90000A46EF4D9600AE594725AD5DAC46AD077C -:109FA000AD0F022D0CD1FF2806D0E94D8700ED59E9 -:109FB000F67DED7DAE4203D96546ED0600D4104630 -:109FC000521CD2B29A42E4D3059A904202D0DD4D9F -:109FD00000226A71FF283AD0DD4F85007A590D9230 -:109FE00040321579D74A5679B5422CD800250996C2 -:109FF0005E1E02460E96521CD2B29A4200D3002236 -:10A00000D34E9700F6590C964036B446F679B7070A -:10A01000BF0F022F0FD1F6060DD466463679002EFB -:10A0200009D00C9EF77D0D9EF67DB74203D300202C -:10A030000990104604E06D1C0E9EEDB2B542DADBCD -:10A04000C04A099D5571BF4A55796D1C5571059AD5 -:10A05000904214D0FF2A0ED0BD4F9600BA59D57D3C -:10A060006D086D00D575BB4A1278D20703D1BA5975 -:10A0700001263543D57580221043B24A1071B44889 -:10A080008A0085584726765DB707BF0F022F02D09A -:10A09000032F53D125E0F60602D5AC4801704DE000 -:10A0A000A84E37797E06760E8E4247D13E0618D5E9 -:10A0B0002C82A44DA74E2971357845276D086D0077 -:10A0C00035708658BF5D002F03D001273D43A14F57 -:10A0D0003D70F57DED0704D09E4D2E787608760014 -:10A0E0002E708558974A288A1679001B80B2B14293 -:10A0F0000BD1984E3678F60701D05A3004E01E286E -:10A1000001D2002001E01E3880B24035EE79F643DE -:10A11000B7070BD1AD796D0708D5FF252D35A842BE -:10A1200001D2002002E0FF382D3880B2158EA842FF -:10A1300004D810865172B20700D10690491CC9B2EA -:10A1400099429CD37F48457AFF2D09D001798D42F1 -:10A1500006D180490978C90702D0018E5A39018693 -:10A160007D4800780590800756D57648008E079088 -:10A17000CB2851D2FF2D4FD00098FF284CD08542DC -:10A180004AD0800072490A900F584720C05D09905C -:10A19000C043800740D1A80008584722125CD24330 -:10A1A000920739D1408A01907E8AB04211D9314656 -:10A1B00012F0BFFB01997043081A80B27108814206 -:10A1C00004D2301A80B2052819D316E0032816D31A -:10A1D00013E00146304612F0ACFB01994143701A7E -:10A1E000019980B24908814205D20199081A80B2CA -:10A1F000032804D301E0052801D300280CD10998D5 -:10A200001321534E8143042200294CD00798C128C2 -:10A2100002D93879104338714C480278FF2A58D057 -:10A220000698CB2855D9FF2D18D04648007985428D -:10A2300014D14749AB00CB581B8A1B1B9BB2B42BD4 -:10A240000CD8AD008300C858068A878AF6190682A2 -:10A250004859008A001B80B2B428F4D93C489600C3 -:10A2600081590B4640331D7AEF0601D4AD062BD53C -:10A270000979090604D5FF2506994935A94246D32F -:10A28000D97903252943D97181590C822D494A7204 -:10A2900080594030007A800639D530481022017844 -:10A2A0001143017033E02B4908784307B4D4FB7B9A -:10A2B000002BB1D10323FB73104308700A98305868 -:10A2C000018AC91E0182A7E7B4341E480C8242727B -:10A2D0001DE01C4D288E522819D905981E490822C8 -:10A2E0001043087072B6FBF73CFC62B61C4C207938 -:10A2F00000280CD0288EE98E884208D33A21687A4B -:10A30000FCF777FA2079012801D1002020710D4C4B -:10A31000607AFF282ED0FFF7D0FA607A47228100BA -:10A320000B484058018A125CC904C90C491CD2432D -:10A33000920717D0828A501880B2884216D208201D -:10A3400015E0000094000020FFFF0000A80000209E -:10A35000D8040020A4000020A3000020A5000020B5 -:10A36000B4000020428A501880B2E6E7400BA07289 -:10A370000FB0F0BDF74C082120780843207072B66A -:10A38000FBF7EFFB62B62078DF21084020700FB0AA -:10A39000F0BDF0B5F04EF14C83B0F7272078C1073F -:10A3A00006D1317A122919D0318F7187B16DF165DB -:10A3B0004008400038402070307A801E11287CD23E -:10A3C00003007B441B79DB189F440C1134347777EE -:10A3D00011607777853D54FE77FDFC00F18F718722 -:10A3E000B16EE4E7308E1E3830862920F085207863 -:10A3F000400840002070707AFCF7A1FF707AD84DB9 -:10A4000080002858018A31872030C07FFBF747FC45 -:10A41000707A800028582030807FFBF744FC707AE7 -:10A42000D04980002858407B4000085AFBF73FFC89 -:10A430000020F0722078400840002070F07AFEF78B -:10A44000AFFE0D2030722078C00703D1308F7087A7 -:10A45000B06DF065308FF087B06DB066F08DFEF7AF -:10A460009FFE0320B071BB48EF22017811400170BC -:10A470000E2001E120780121084320700E20FEF714 -:10A480008FFEFEF7B5FE0F2030726AE2207840089A -:10A4900040002070707AFCF752FF707AB04D800057 -:10A4A0002858018A31872030C07FFBF7F8FB707A8B -:10A4B000800028582030807F00E000E2FBF7F3FBAB -:10A4C000707AA84980002858407B4000085AFBF762 -:10A4D000EEFB0C2030722078400840002070A2482B -:10A4E0000078800772D0717A9D4D88002B584620E5 -:10A4F000C25C92066AD59D4A1278D20747D09C4822 -:10A50000407A884226D19B480078400622D4317E8A -:10A510009948FCF73DFD00281CD0707A800029582E -:10A52000964800F057FA914B944918780A791043ED -:10A5300018700871707ADF2180002A5840329079B3 -:10A5400008409071B08E70868D488022017811434A -:10A5500001703BE0708E00284ED0707A8000295840 -:10A56000864800F037FA81488022017883480171DB -:10A5700025214171708E401E7086814801781143FB -:10A580000170401C01784022114301701EE0784A9E -:10A59000527A8A4230D1181DFCF736FD00282BD0A4 -:10A5A000717A72488D006E4900784A596F49137963 -:10A5B0001843087010716A48DF2240594030817991 -:10A5C000114002E09AE060E019E18171707A64491B -:10A5D00080000858FB22001D01781140017063497A -:10A5E0000D78690703D560490978002909D05E48CC -:10A5F0000078800725D028E02078052108432070C6 -:10A6000023E0604AFB2113780D400B401370D21EEB -:10A6100015700C210170431E1A7855214A401A709A -:10A62000801E02784A400270401E02784A40027042 -:10A63000401E02784A4002702078022108432070B0 -:10A6400003E0E80901D0FBF701FD48480078000766 -:10A6500003D50720FEF7A4FD08E03E480078C009B6 -:10A6600001D00D2000E01E20FEF79AFD2078C007E3 -:10A6700006D0FBF76FFD0F203072FBF79FFC70E1F7 -:10A68000308F7087B06DF065F5E7207840084000A6 -:10A6900020702920FEF784FD308FF087B06DB06602 -:10A6A00000207072FFF709F9707A2D4D800028584C -:10A6B000354900F08FF9707A800028582030C07F2B -:10A6C000FBF7EDFA707A800028582030807FFBF786 -:10A6D000EAFA707A234980002858407B4000085AE3 -:10A6E000FBF7E5FA1B49EF2208781040402210439F -:10A6F0000870122030722120F085BEE7154D2878B1 -:10A70000C0060DD4F18FB06EFBF71AFCF18F012358 -:10A71000421A92B2DB039A4201D9318700E03087B6 -:10A72000207814494008400020701220F0712878E9 -:10A730004006400E28700978C90627D510213172CD -:10A74000BF21084028700A48FF214172FBF7B0FD85 -:10A750003FE00000A300002094000020BC00002087 -:10A76000D8040020DC070020AA000020A800002058 -:10A77000B4000020A50000207E0400207A04002000 -:10A78000A4000020AB000020E0000020C00620D57F -:10A79000FEF72EFDF07906281BD1F9480078002835 -:10A7A00003D100F0D5F9002813D000F0D1F9F54D10 -:10A7B00080002858F44900F00DF9707AF2498000C1 -:10A7C000285800F007F91820FEF7EAFC0F20307235 -:10A7D00006E02878EF2108402870307A122804D04B -:10A7E0002078012108432070BBE02120F08529203A -:10A7F000FEF7D6FC308FF087B06DB0663DE7F0799C -:10A80000092801D00C284FD1E04801783940017067 -:10A810008C462178480703D5FB200140217043E096 -:10A82000707A00908000D74D01902858FB23001DBE -:10A8300002781A4002708A0714D5FD221140217057 -:10A84000421E137855214B401370801E02784A40F7 -:10A850000270401E02784A400270401E02784A4050 -:10A86000027021E0C648017889071DD16146C909F7 -:10A870000FD05E2101706046800615D4C448007870 -:10A88000410701D5C0060FD50A210098FBF7B1FF9B -:10A890000AE00198202228584030817911438171C3 -:10A8A00003210098FBF7A5FF2078012108432070C1 -:10A8B000FFF7B1F9FFF734F8FBF7FAFC51E0207825 -:10A8C00041084900B34821700278930646D501201B -:10A8D000014321700C20FEF763FCAD4800780007AF -:10A8E00020D5707AFF281DD0AB4A81005158897C51 -:10A8F000002917D08300D1580F20CD7B6D1CCD735C -:10A9000004E0401EC0B20D5C6D1C0D540D5C002DAA -:10A9100001D10028F5D1D158887C401E0006000ED8 -:10A920008874E8D1FFF720FB99480078000718D514 -:10A93000707AFF2815D0984D800028589749007CE0 -:10A940001022000141189648FBF78CFB707A102208 -:10A95000800029589348FBF785FB02E05108490025 -:10A9600001702078C00700D018E503B0F0BD10B525 -:10A970008D48007A801E11281AD203007B441B796F -:10A98000DB189F4408080808151508161515162425 -:10A99000151515080800FBF7EBFA83480822816DAE -:10A9A000016682480021817181480178114301705C -:10A9B00010BDFBF7DDFA7C480822816D016601219C -:10A9C00020308171083001781143017010BDFBF710 -:10A9D000CFFA10BD0A7802704A7842708A78827085 -:10A9E000C978C170704773B56A461078654B8400AA -:10A9F00019594722525CD6066A4655780022002E25 -:10AA000020DA052D05D0062D07D0072D03D12031E2 -:10AA10008A721859028502B070BD0D8D4E8AAE192A -:10AA2000B6B20E851959AE42F5D820318D7AED1C9B -:10AA3000EDB28D7219590E46B67D2031B542EAD974 -:10AA40008A7212E0012D0CD0072D16D0082D0CD0E3 -:10AA5000802DE0D12031887A0628DCD28A7202B0BB -:10AA600070BD20318A7A521C8A721A592032937F23 -:10AA7000D17A8B4209D1117B0BE020318B7A062BE6 -:10AA8000ECD2FCF7F3F902B070BD147BA34200D105 -:10AA9000517BFBF710FF02B070BDF0B5454C84460A -:10AAA000E288414F0E462089F96E801A85B251180E -:10AAB000AE4202D83246604608E0EAB26046FBF792 -:10AAC000D1FA701BC2B260464019F96EFBF7CAFAA0 -:10AAD000E08821898019491E0840E080F0BD2D489A -:10AAE000007840070ED410B52F482649407A10232D -:10AAF0008200895840318A791A438A718021FBF794 -:10AB000078FE10BD704770B52B490978C9071CD075 -:10AB10002A4C002800D02A4C2078002801D0012897 -:10AB200012D1214D1749687A10238200895840318B -:10AB30008A791A438A7121788331C9B2FBF759FEA9 -:10AB4000287E2070A88E688670BDFFF7C8FF70BD94 -:10AB500070B515480078401E0406240E0ED0094D2D -:10AB6000A00028584621095C890603D4FEF7EAFABA -:10AB7000002803D1641E2406240EF1D1204670BDA6 -:10AB8000AA000020D8040020B6040020A80000205D -:10AB9000A0000020A300002014050020EB060020E8 -:10ABA000EC070020FC07002094000020B4000020E7 -:10ABB000BC0000201C080020A90000209D040020EB -:10ABC000BB0400203349497A8A0033498B58334A01 -:10ABD000D97812788907890F920601D4012070472D -:10ABE00030B42F4A5D7954799279AC4207D1022969 -:10ABF00002D09B799A4202D1012030BC7047002CD0 -:10AC000003D10229F9D0002AF7D030BC00207047C8 -:10AC100010B4214980001F4B0A589B8F548A153B62 -:10AC2000E31813820B580022DA8109584031C979A0 -:10AC3000090708D51B4A11588B7CCC7C1B198B74D7 -:10AC400010580121017510BC704770B51648114CA1 -:10AC50000078114D154E400608D5FBF729FBFFF78C -:10AC600077FF607280002858007930703078400794 -:10AC70000BD4607A8000285840308079800606D452 -:10AC80000020FFF79FFF002801D0012070BD0020A9 -:10AC900070BD000094000020D8040020A000002017 -:10ACA000B604002014050020A3000020A800002006 -:10ACB00010B57038030012F077F81B0F1519212515 -:10ACC000282F363B4044484C53585F688D7079803C -:10ACD000888D8D8D8D8F96004A680878114605F015 -:10ACE000DCF810BD086805F029F910BD0C790B7B64 -:10ACF0008A680868214605F032F910BD086805F039 -:10AD0000F0F910BD04F044FE10BD08884A6880B216 -:10AD1000114605F022FB10BD0A790888114680B261 -:10AD200005F0B2FB10BD087840B205F0BBFB10BDCA -:10AD3000088880B205F0CFFB10BD086805F0DDFB88 -:10AD400010BD086805F06BFD10BD086805F095FDA5 -:10AD500010BD088982B209C9194605F0E6FB10BD8D -:10AD600005C9114605F030FC10BD08884A6880B25C -:10AD7000114606F043FD10BD0C790888CB688A683F -:10AD800080B2214606F062FE10BD0B7908888A6801 -:10AD900080B2194607F00AF810BD08884C68CB68E5 -:10ADA0008A6880B2214607F072F810BD08884A68A8 -:10ADB00080B2114607F0B5F810BD0B7908880A7A01 -:10ADC00080B2194605F023FC10BD088880B205F05A -:10ADD00023FC10BD062010BD08884A6880B21146C9 -:10ADE00005F021FC10BD012010BD10B59038030006 -:10ADF00011F0DAFF09060F161D242C363F464E00CF -:10AE000088888A6883B20888194680B207F0D6FC21 -:10AE100010BD08884A6880B2114607F00AFD10BDCF -:10AE200008884A6880B2114607F00FFD10BD0888F7 -:10AE30004A6880B2114607F015FD10BD08884B68BE -:10AE40008A6880B2194607F020FD10BD088982B2D9 -:10AE5000888883B20888194680B207F01FFD10BDAC -:10AE600008894B6882B20888194680B207F035FD20 -:10AE700010BD08884A6880B2114607F040FD10BD39 -:10AE8000888882B20888114680B207F094FD10BD10 -:10AE9000012010BD10B5A038030011F085FF0B078D -:10AEA0000E172028313A414B525C65004B680878F8 -:10AEB0008A68194609F010FA10BD88888A6883B23A -:10AEC0000888194680B209F016FA10BD08884C6847 -:10AED000CB688A6880B2214609F011FA10BD088853 -:10AEE0004B688A6880B2194609F025FA10BD888837 -:10AEF0008A6883B20888194680B209F031FA10BD19 -:10AF000088888A6883B20888194680B209F06BFA8B -:10AF100010BD08884A6880B2114609F0AAFA10BD2F -:10AF2000088982B2888883B20888194680B209F0FD -:10AF3000ABFA10BD08884A6880B2114609F0C8FA19 -:10AF400010BD08894C6882B20888CB6880B221465F -:10AF500009F042FB10BD08884C68CB688A6880B253 -:10AF6000214609F054FC10BD012010BD10B50300AE -:10AF700011F01AFF0A0609060C0C0F0F060606123E -:10AF800004F02EFD10BD09F003FF10BDF8F727F8FF -:10AF900010BD03F00FFE10BDFAA1FE4811F0EBFD4D -:10AFA00010BD3EB5FC49054603C900900191FF2044 -:10AFB000C33069460881F94A092310460A21283816 -:10AFC00001F0BDFA0024F64801F0D7FA641CE4B29F -:10AFD0000A2CF8D3F14801231A4602A990300AF04E -:10AFE00064FA002804D0FF20E6A13D3011F0C3FD33 -:10AFF000686800F024FC00211E22084601F0DCFCF9 -:10B0000004F0FDFE02222421E6480AF04BF9E5484F -:10B0100001222C214C300AF045F9E2490B20B039CD -:10B0200003F02EFE002804D0FF20D6A1513011F0ED -:10B03000A2FD09F07CFE08F0CFFA6B460022082141 -:10B04000D9A004F0B7FD002804D0FF20CDA15730CF -:10B0500011F091FD284608F01FFE002804D0FF20C3 -:10B06000C8A1593011F087FDF3218900D14811F0B2 -:10B0700056FCD04801214171022181710721C17123 -:10B080003EBD10B5CB4CA0780A2804D3FF20BDA14B -:10B09000903011F070FD20786021484300190021A4 -:10B0A0000173417BF722C908C900C91C1140EF2276 -:10B0B000114041730121E1700C3010BD70B50E4696 -:10B0C00000211C4619801546030011F06DFE072370 -:10B0D000050B1711231D230022462946304609F08F -:10B0E00075FE70BD22462946304604F0CFFA70BD89 -:10B0F00022462946304608F01AF970BD22462946F4 -:10B10000304607F0DCF970BD22462946304600F093 -:10B1100010FC70BDFF209BA1EF3011F02CFD03202F -:10B1200070BD70B5A34CE078002818D0207860215D -:10B1300048430019407B00254007400F011908795A -:10B14000401E08712078401CC0B220700A2800D12F -:10B150002570A078401CA07001F0C3FBE57070BDA5 -:10B160009448C079002800D08BE7704770B5914DA6 -:10B17000A86800280CD0FFF7F3FF002862D06022F7 -:10B18000A968F6F72DF8FFF7CCFF0020A860EFE7DD -:10B190006879002856D0FFF774FF044681484C3088 -:10B1A0000AF090F86060002804D17A4875A14A300E -:10B1B00011F0E1FC60680AF0E8F800280DD02046A4 -:10B1C00004F045F96078010703D5C008C000401CB1 -:10B1D0002BE0744861684C302DE0724861684C3057 -:10B1E0000AF079F800F05AFB00282BD1FFF749FF4D -:10B1F00004466C480AF066F86060002804D13320E9 -:10B2000060A1000111F0B7FC60680AF0C2F80028E4 -:10B2100014D0606800886080204609F00AFE6078DB -:10B22000010706D5C008C000801C6070FFF779FFD9 -:10B230009EE75C4861680AF04EF899E759486168F2 -:10B240000AF049F870BD10B55B4CE160A0605B4846 -:10B25000F7F73EFD607010BD574900200870704739 -:10B2600070B5574E0546706A94B00C46401C04D128 -:10B27000B06AC0430004000C0BD0306AC007C00F96 -:10B280002870706A11F04DFBB06A2071000A60717D -:10B2900014E02B206946087009A968460AF049F8AD -:10B2A000002804D03B4837A17E3811F064FC01200F -:10B2B000287006220AA9204611F0D2FA2878002820 -:10B2C00003D06079C0210843607114B070BDF0B53F -:10B2D0003B4C0646206895B00D4637460837401C63 -:10B2E00008D16068401C05D1A068401C02D1E0680C -:10B2F000401C11D02068314611F013FB6068311DED -:10B3000011F00FFBA068394611F00BFBE0683146E5 -:10B310000C3111F006FB25E02B206946087009A9C5 -:10B3200068460AF006F8002804D01A4815A15538D6 -:10B3300011F021FC08220AA9304611F091FA2B20C5 -:10B340006946087009A9684609F0F3FF002804D08F -:10B3500010480CA14E3811F00EFC08220AA93846FC -:10B3600011F07EFA20692E460836401C08D160692B -:10B37000401C05D1A069401C02D1E069401C33D0BB -:10B3800020691FE07372635C686F73745F636F7230 -:10B39000652E6300C3020000E8CE010050080020C3 -:10B3A0006DAF0000200F00206E524635313832322A -:10B3B00000000000A40A00201C0100206DB1000064 -:10B3C00080000010294611F0ACFA6069291D11F0C7 -:10B3D000A8FAA069314611F0A4FAE06929460C31B7 -:10B3E00011F09FFA15B0F0BD2B246846047009A92E -:10B3F00009F09FFF002803D0F649F74811F0BBFB86 -:10B40000082209AF28460AA911F02AFA68460470F2 -:10B4100009A909F08EFF002804D0EF48ED49C01DAE -:10B4200011F0A9FB0822391D304611F019FAD9E7AD -:10B4300070B5EA4C0546A068002804D0E648E54906 -:10B44000563011F098FBA56070BD10B50146E44878 -:10B4500009F041FFE1498879401CC0B28871012898 -:10B4600003D1E0484078F7F757FC10BD70B50446AB -:10B47000DD4816460D46814204D1D748D549CB3028 -:10B4800011F079FB012E05D0D348D249DA3011F002 -:10B4900072FB70BD6620207000202072A581012003 -:10B4A000A07370BD70B515460C460646FFF758FEF2 -:10B4B00000280CD0662101704680012101722168AC -:10B4C0000161A18881820573FFF72BFE70BD1321F6 -:10B4D000304604F0D9FF70BDC2494968884201D2A4 -:10B4E00010207047072101700020704770B5BD4CD7 -:10B4F00005462078002694B0002801D00820E4E614 -:10B50000BA4A6260954201D21020DEE668680028DF -:10B5100009D00921D82804D3C31C9B089B0083426F -:10B5200005D00846D1E60720000268600EE0012140 -:10B5300009074B6B896B4B43AD49511A0122591ACC -:10B54000D202891A814201D20421EAE70BF004FBFE -:10B550006178A0680AF042F9E068401E07280BD81D -:10B56000302269460A70887068460BF0F7F90028A7 -:10B5700002D009A80AF06CFB2846FFF712FD012053 -:10B5800020703046A1E6F8B5044696480F4640685C -:10B59000814208D3002C01D0844204D3E01C8008EF -:10B5A0008000A04201D01020F8BD8C48817800298D -:10B5B00011D0398800914178602251430D18287BC1 -:10B5C0000C350007000F3B4600222946FFF776FDA9 -:10B5D000060004D015E0002038800520F8BD002CBE -:10B5E00013D039880098814201D90C260DE02878C3 -:10B5F0003B460007000F22462946FFF75FFD060085 -:10B6000005D00C2E01D0002038803046F8BD734C98 -:10B610006078401CC0B260700A2801D100206070C0 -:10B62000A078401EA07068784107490F01290ED00C -:10B63000022906D003291AD066496E4811F09BFAF8 -:10B64000E3E7C006E1D46868FFF7FFFEDDE7644882 -:10B6500069684C3009F03FFE6079401CC0B26071EF -:10B660000128D2D15F484078F7F756FBCDE7E07963 -:10B67000401CE071C9E7604A10B5904209D3594AAD -:10B680000124A4045268A04201D3904201D3914204 -:10B6900001D2102010BD03F02CFB10BD564B10B58D -:10B6A000994209D34F4B0124A4045B68A14201D302 -:10B6B000994201D39A4201D2102010BD022803D032 -:10B6C000102801D0092010BD03F039FB0028FAD062 -:10B6D000052010BD484B10B598420DD3414B0124B5 -:10B6E000A4045B68A04201D3984205D3994203D3D6 -:10B6F000002A03D09A4201D2102010BD03F045FB6E -:10B700000028FAD0072010BD10B50446354894B083 -:10B710004068844202D2102014B010BD0F2008A946 -:10B72000087369460BA809F004FE0028F4D16846A6 -:10B73000007A207068464089608068468089A080D1 -:10B740000020E9E710B500290BD0264A5268914243 -:10B7500002D30B68934201D2102010BD8A88002AC0 -:10B7600002D007F092FF10BD092010BD10B5224A8B -:10B7700094B091420ED31B4A01239B045268994214 -:10B7800001D3914206D3441E1E2C41D8994203D3C3 -:10B79000914201D21020BFE7012837D10878002458 -:10B7A000C007C00F002803D003206946887001E05D -:10B7B0006846847038206946087009A9684609F00F -:10B7C000B8FD002804D041200CA1C00011F0D3F92D -:10B7D0002046A1E784B3000093020000A40A0020E1 -:10B7E000200F00201C010020FFFF0000401A002055 -:10B7F000000000200A04000000D001007372635CA6 -:10B80000686F73745F636F72652E6300072083E750 -:10B810000246203A1F2AF9D804F033FA7CE710B523 -:10B820005F4A5268914201D2102010BD0246203A70 -:10B830001F2A02D804F09FFA10BD072010BD70B572 -:10B840000546584C00202070204646195448466052 -:10B85000E01C80088000A04204D0FF205249133031 -:10B8600011F089F901200007C06AC0430006000EEC -:10B8700003D14E480068401C03D04D484D49301A52 -:10B88000C862A8B20122214601F0A9FC002804D018 -:10B89000FF204549233011F06EF970BDF0B595B029 -:10B8A0003B2008A9087369460BA809F042FD00284F -:10B8B00004D0FF203C496B3011F05DF93E4E00246E -:10B8C0006D4630E02F19B87DC10706D0400704D47B -:10B8D00060004019C08809F0CBFB38488079002807 -:10B8E0001FD0B87D80071CD560004019C088002299 -:10B8F000062109F0DAFB002813D03C2108A80173C7 -:10B9000060004019C1886846C18569460BA809F0E6 -:10B9100010FD06000BD0FF2023497F3011F02BF9DA -:10B9200005E0641CE4B268460079A042CAD83046FB -:10B9300058E5F7B505460078002700090C463E4655 -:10B94000062804D0FF201849A83011F014F9287AED -:10B9500000280ED0012814D0FF201349C93011F05F -:10B960000AF90298002C068001D02780668000200A -:10B97000FEBD02270926002C0ED0A889A080A87B36 -:10B9800008E003271426002C06D02869E060A88A66 -:10B990002082287B2072E4E702980680E7E7000017 -:10B9A0001C010020401A0020FCB70000001000100D -:10B9B000000000200005004004300000A40A002020 -:10B9C00010B56038030011F0EFF90A060A0F1318DA -:10B9D0001F252930353A0868FFF788FD10BD05C9D5 -:10B9E0001146FFF7D0FD10BD0868FFF775FD10BDCB -:10B9F00005C91146FFF73FFE10BD4B6808788A68FD -:10BA00001946FFF74BFE10BD8A6809C91946FFF7B2 -:10BA100061FE10BD0868FFF777FE10BD08884A6810 -:10BA200080B21146FFF78EFE10BD05C91146FFF723 -:10BA30009DFE10BD05C91146FFF7F1FE10BD0120A6 -:10BA400010BD0120704700004749096801600020CF -:10BA5000704745490860002070470121434A00288B -:10BA600003D0012803D042487047916300E0D163BE -:10BA7000002070473F49012008603D48801C704706 -:10BA800004223D4B3B49002805D05A600869012239 -:10BA90001043086108E008694008400008619A60A6 -:10BAA00032490020C03188600020704731490622A9 -:10BAB000002808D0012809D002280DD003280FD073 -:10BAC0002B48401C70470869904302E00869904386 -:10BAD000801C08610020704708699043001DF8E74A -:10BAE00008691043F5E723494A6A02434A62002085 -:10BAF000704720494A6A82434A62002070471D49C4 -:10BB0000496A0160002070471A49CA690243CA6144 -:10BB1000002070471749CA698243CA6100207047F4 -:10BB20001449C9690160002070471249024600208B -:10BB30004031002A03D0012A01D0072070478A63D0 -:10BB400070470D490420886008490020C031886092 -:10BB50000A4801688022090A090211430160084964 -:10BB600001200860704700000004004040000040D1 -:10BB700004200000000500400003004000E400E055 -:10BB800000E100E08107C90E002808DA0007000F75 -:10BB900008388008C24A80008018C06904E0800824 -:10BBA000C04A800080180068C84080097047BE49BC -:10BBB00048788978884201D3401A02E02122511A3C -:10BBC0000818C0B27047B84923314878897888424C -:10BBD00001D3401A02E02122511A0818C0B270475E -:10BBE000B149463148788978884201D3401A02E049 -:10BBF0002122511A0818C0B27047AA4910B50C3159 -:10BC00000868FF22120290430122D2031043086009 -:10BC1000A549002023314870887023394870887006 -:10BC2000463148708870A14800F04CF99F48401C8C -:10BC300000F048F9F7F7E3F800F028F910BD2020EC -:10BC40007047B4E770B50C4605460026FFF7AFFF16 -:10BC50009549A04214D30A46203A00232046641E88 -:10BC6000E4B200280BD08878105C287088786D1CAE -:10BC7000401CC0B288702128F0D18B70EEE70126FD -:10BC800000F004F9304670BD202070479BE770B586 -:10BC90000C4605460026FFF796FF83492331A04254 -:10BCA00014D30A46203A00232046641EE4B200283A -:10BCB0000BD08878105C287088786D1C401CC0B24E -:10BCC00088702128F0D18B70EEE7012600F0DEF8B5 -:10BCD000304670BD202101700020704710B5044629 -:10BCE000FFF77EFF2070002010BD70B50C460546A2 -:10BCF000FFF776FF6C494631A04215D30A46203A39 -:10BD000000232046641EE4B200280BD08878105C23 -:10BD1000287088786D1C401CC0B288702128F0D132 -:10BD20008B70EEE7002400E0614C00F0AFF8204695 -:10BD300070BD70B50C460546212904D9FF205DA1D0 -:10BD4000473010F018FF56484068103840B2FFF7EF -:10BD500019FFC6B20D20FFF715FFC0B2864207D209 -:10BD6000FF2054A14D3010F006FF01E0F7F78AF8EC -:10BD700021462846FFF766FF0028F7D070BDF8B5CA -:10BD800007464A48484C401E474E007825464636EE -:10BD90002335002806D1A9786878212200F06BF8B5 -:10BDA00000280ED0A1786078212200F064F80028E5 -:10BDB00014D0B1787078212200F05DF8002828D0E6 -:10BDC00033E039496878C91C0F546878401CC0B208 -:10BDD0006870212829D10020687026E032496078F7 -:10BDE00020390F546078401CC0B26070212801D106 -:10BDF000002060702D4F7F1E3878002815D0A17864 -:10BE00006078212200F037F800280ED0002038702A -:10BE10000BE02549707826310F547078401CC0B271 -:10BE20007070212801D100207070A97868782122D3 -:10BE300000F021F800281DD0A1786078212200F0C0 -:10BE40001AF8002816D0B1787078212200F013F883 -:10BE500000280FD0F6F7F8FF144800F03BF8012156 -:10BE60004903884203D013A1C12010F084FE0F487B -:10BE700000F048F8F8BD401C884205D0904201D13E -:10BE8000002901D0002070470120704710B50748F5 -:10BE900000F020F8002801D1F6F7C5FF10BD000022 -:10BEA00000ED00E000E400E0BC0F00202D010020C8 -:10BEB000072000007372635C736F635F72616E646E -:10BEC0002E630000002101700846704701460020E3 -:10BED00008707047EFF31081C907C90F72B6027876 -:10BEE000012A01D0012200E0002201230370002971 -:10BEF00000D162B6002A01D0002070470120400323 -:10BF00007047E7E7EFF31081C907C90F72B6002247 -:10BF10000270002900D162B600207047F2E70000ED -:10BF20008107C90E002808DA0007000F08388008CA -:10BF3000864A80008018C06904E08008844A800036 -:10BF400080180068C8408009704710B5044600F0AA -:10BF5000E7F8002813D02046FFF7E2FFC0B200F058 -:10BF6000EDF800280DD07B4801210278002A0BD083 -:10BF7000E206D20E914042681143416009E07648E2 -:10BF800010BD7548401C10BDE006C00E81407348CE -:10BF90000160002010BD10B5044600F0C1F8002873 -:10BFA0000BD06C4901200A78002A08D0E206D20E94 -:10BFB00090404A6882434A6007E0674810BDE10646 -:10BFC000C90E8840654980310860002010BD70B5F9 -:10BFD0000D46044600F0A4F800280BD06048006825 -:10BFE000E206D20E01219140084000D001202860D5 -:10BFF000002070BD584870BD10B5044600F090F8A0 -:10C00000002807D0E106C90E012088405449086085 -:10C01000002010BD504810BD10B5044600F080F857 -:10C02000002808D0E106C90E012088404C49803123 -:10C030000860002010BD484810BD70B50D4604468C -:10C0400000F06EF8002819D0284600F077F8002894 -:10C0500016D0FF20002C16DA2107090F08398A08AC -:10C060003A4992005118CB69A207D20E90408343FF -:10C07000A807000E90400343CB6112E0364870BD24 -:10C080003548401C70BDA2083149920051180A6819 -:10C09000A307DB0E98408243A807000E9840024396 -:10C0A0000A60002070BD70B50C46054600F038F8F7 -:10C0B000002805D02846FFF733FF2070002070BD10 -:10C0C000254870BDBFF34F8F20492648C860BFF395 -:10C0D0004F8FFEE770B51F4C0546217801200029DF -:10C0E0000ED1207072B6F6F7B8FD1C4E803631685E -:10C0F00081436160F6F7B1FDC043306062B6002055 -:10C100002870002070BD13490A78002A06D0002844 -:10C1100004D1124A4868106000200870002070475F -:10C1200010B50446202805DAF6F797FD0121A14055 -:10C13000084201D0002010BD012010BD012803D00D -:10C14000032801D0002070470120704700ED00E077 -:10C1500000E400E0300100200120000000E100E0E8 -:10C1600000E200E00400FA0510B52948FFF7AAFE36 -:10C17000002803D027A11D2010F0FDFC2448401CFE -:10C18000FFF7A0FE002803D022A1212010F0F3FC2D -:10C1900010BDF8B5234D07466868009001261C487D -:10C1A000FFF798FE1A4C002803D10026601CFFF709 -:10C1B000A9FE1D4A1D4900230120506000BF00BF99 -:10C1C00000BF00BF00BF0B604B606F60106000BF1E -:10C1D00000BF00BF00BF00BF0868002802D1486848 -:10C1E0000028F9D048680028E6D1002E05D0009834 -:10C1F0006860601CFFF76EFE07E0601CFFF76AFED8 -:10C200000028D3D10248FFF77DFE0020F8BDC0E72B -:10C21000380100207372635C736F635F6563622E25 -:10C220006300000000E5004000E0004000E1004045 -:10C230005B495C4B0A685C499A42096801D18904F0 -:10C24000890C0160002070475549564B0A685649D1 -:10C250009A4201D18004800C486000207047504908 -:10C26000504B0A6850499A4201D18004800C886082 -:10C270000020704730B54A4B4A4D1C684B4BAC42CE -:10C2800002D0102802D203E00E2801D3184630BD98 -:10C29000C3004548181801614261002030BD404983 -:10C2A000404B0A684149491C9A4202D0042802D2F4 -:10C2B00003E0022801D3084670473D4A0121C0002F -:10C2C00080180160002070473549364B0A683749AD -:10C2D000491C9A4202D0042802D203E0022801D36A -:10C2E00008467047324A0121C00080184160002092 -:10C2F000704730B52A4A2D4B2A4D14685B1C2D4AD5 -:10C30000AC4206D0042806D28000801801600020CC -:10C3100030BD022801D3184630BD8904890CF3E7EB -:10C3200030B51F4A214B1F4D14685B1C214AAC429B -:10C3300005D0042805D280008018006808E0022893 -:10C3400001D3184630BD8000801800688004800C3E -:10C350000860002030BD10B5134A174890600E20C9 -:10C360000021C3009B1819615961401C1028F8D3A3 -:10C370000020104A05E0022803D383009B181960AF -:10C3800005E083009B181C68A404A40C1C60401CDE -:10C390000428F0D310BD04490748886070470000A6 -:10C3A0001C000020BEBAFECA00F5014008200000B3 -:10C3B00000F0014000F8014000C0FFFFFEB5F34C63 -:10C3C00007466068FF213E0181552178FF2913D07F -:10C3D0000901083141583246491E083209020192CA -:10C3E000090A805800F0C8F9002802D024782546B0 -:10C3F00015E06168207888552770FEBDE3484268E3 -:10C4000001981158280100900830105800F0B4F934 -:10C41000002806D1DD482C46416800980D5CFF2DB0 -:10C42000ECD1DA482101406885554754FEBD70B50E -:10C43000D64A04460020157A53680AE00201561CC9 -:10C440009E5DA64203D10C329A588A4204D0401C09 -:10C45000C0B28542F2D8FF2070BDF8B5CB4F3E7810 -:10C46000F8F794F90146FF2E68D034012546786824 -:10C470000835405900F080F9022802D978684059FF -:10C480005AE0C2494868025D0A70A11C425C002A59 -:10C490000CD0521E425441590122D205891809027A -:10C4A000090A41513046FFF789FF30E0631CC25C46 -:10C4B0000092221D94468258002A10D001239B022C -:10C4C0009A420FD99205920D43595703DB191B026B -:10C4D0001B0A43516346C3589A1A920A09E0FF2186 -:10C4E000C1540AE0435952039A181202120A4251E7 -:10C4F000002242543046FFF761FFA4480C344168E3 -:10C50000C2680098095980001258009890479F4CC3 -:10C510002078FF2812D0F8F739F9014620786268B0 -:10C5200000010830105800F027F9012896D920782A -:10C530006168000108300858F8F71BF9F8BDF8B534 -:10C540001C4615460E460746FF2B03D390A1D32069 -:10C5500010F011FB8D48FF21C7604560047206741E -:10C56000017000224270104604E00201521C401C7F -:10C57000A954C0B2A042F8D3F8BD70B5834C0646AA -:10C580006578207C854203D381A1E62010F0F3FA80 -:10C59000E068A90046506078401C6070284670BD75 -:10C5A000FFB581B01D46FF24F8F7F0F8774F064637 -:10C5B00079780198814203D875A1F42010F0DBFA54 -:10C5C00072480021037A406810E00A019446521C28 -:10C5D000825CFF2A24D0019FBA4205D162460C3208 -:10C5E0008758029A97421DD0491CC9B28B42ECD899 -:10C5F000FF2C17D021014B1C019AC2540B33029A15 -:10C60000C250039B614F0022012B0ED00B1DC25064 -:10C6100001239B029D4216D9AA05920D08D008E07D -:10C620000C46E1E7FF2005B0F0BD0B1DC550EFE75C -:10C630001A4653039B190E461B0208361B0AAA1AF8 -:10C640008351920A09E0002D00D101256B039B194B -:10C650001D022D0A0B460833C550891C42543D4625 -:10C660003E782046FFF7AAFE2878B04215D0F8F7AA -:10C670008DF8014628786A6800010830105800F0EB -:10C680007BF8012807D92878696800010830085824 -:10C69000F8F76FF801E0FFF7E0FE0198C3E770B527 -:10C6A0000C460546F8F772F8064621462846FFF77D -:10C6B000BEFEFF2817D0354D0401204669680830BA -:10C6C0000858314600F058F80121090340186968FC -:10C6D000A41C095D400B002901D08902081800281C -:10C6E00000D1012070BD002070BDF3B581B00746B8 -:10C6F0000299FFF79CFEFF282AD0244D2E78696806 -:10C700003246344604E0844205D026462301CC5C00 -:10C71000FF2CF8D11CE0FF2C1AD0A6421FD110012B -:10C72000085C2870FF2818D0F8F730F82A780146FE -:10C73000120168680832805800F01EF8012809D9F3 -:10C7400028786968000108300858F8F712F806E000 -:10C750000020FEBDFFF781FE01E0F8F712F8384631 -:10C760000299FFF79CFF22016968FF23541C0B55B7 -:10C770008A5C3301CA54FEBD401A00020121000A3E -:10C78000C905884200D90020704700000810002029 -:10C790007372635C736F635F74696D65722E63009F -:10C7A00070B5002402460D4620462146002A20D0BE -:10C7B000012A04D0022A04D0032A0DD103E001206B -:10C7C00002E0022015E003202B0010F0EDFA07052F -:10C7D00007090B0D0F11050007240EE0012108E0E9 -:10C7E000022106E0032104E0042102E0052100E02B -:10C7F0000621F6F71EFD0028EED0204670BD000091 -:10C80000F0B51C48002701211B4A831447601360C0 -:10C810001A4A17601A4C23601A4B1C691E69E443BC -:10C82000E406E417641C10252E431E61164B596064 -:10C83000164E316000E020BF1668002EFBD0002CA1 -:10C8400003D1104C2669AE43266184688068A40534 -:10C8500001D50F4C20430D4C616099601760084A68 -:10C86000A1141160F0BD10B50446FFF7C9FF2060A8 -:10C87000002010BD00C5004080E100E000C1004084 -:10C8800080E200E000ED00E000C3004000C0004096 -:10C8900000FCFFFF70B51F490A68002A17D000236B -:10C8A0001D4601244A68521C4A60092A00D34D6083 -:10C8B0000E792246B2400E6816420AD072B60B6854 -:10C8C00093430B6062B649680160002070BD05208B -:10C8D00070BD5B1C092BE5D30FA1362010F04BF97E -:10C8E000F5E701201049800508607047EFF31081DB -:10C8F000CA07D20F72B60121814006480368194366 -:10C900000160002A00D162B6EBE702480021016015 -:10C91000416070473C0100207372635C736F635F1A -:10C920006576742E6300000000E200E00A4A0221EE -:10C9300051600A490B68002BFCD090600868002801 -:10C94000FCD00020506008680028FCD0704701200F -:10C95000000740697047000000E5014000E4014025 -:10C9600001208107086070470120810748607047F7 -:10C970001048C068C00700D0012070470D4880688B -:10C98000C00700D0012070470A484069C00700D0A6 -:10C99000012070470748C069704706498A69D20379 -:10C9A00006D589698907890F814201D10120704725 -:10C9B000002070470004004010B5FE4B586019720B -:10C9C0001A80C9000FF0ABFF10BD00210180704735 -:10C9D00010B50022D24302800320FFF786FE10BD6F -:10C9E0007047F0B50E460446017801208840F249B0 -:10C9F00099B008400090616815460888EF4A904257 -:10CA000006D0009A002A06D0EB4A521E104202D0ED -:10CA1000012019B0F0BD009A10430880002D12D0FB -:10CA2000002028702178EA1C0027681C01920B0066 -:10CA300010F0BAF910F30E16233A59616F3CB4B0F6 -:10CA40008AB8F2F1F0F320780B28EBD00420E0E76D -:10CA500002212970A1890170090A4170032097E021 -:10CA600004212970A1890170090A41700198E189A6 -:10CA70000170090A417005208AE006212970A18908 -:10CA80000170090A41700199E2890A70120A4A701C -:10CA9000218A0171090A4171A28AE81DA1690FF07A -:10CAA000DFFEA08AC01D73E00821297021780829C3 -:10CAB00001D110212970A1890170090A41700198E2 -:10CAC000E1890170090A41700520308020466A1D05 -:10CAD00002A9103002F059F900287DD1694630884A -:10CAE000097A401854E00A212970A1890170090AC5 -:10CAF000417003200BE00C212970A1890170090A03 -:10CB000041700198E1890170090A41700520308067 -:10CB10009CE0A08984464000401C81B23088884255 -:10CB20005AD3052958D30E202870002008E0236925 -:10CB300042009B5A521953701B0A401C937080B2DA -:10CB40006045F4D33180B9E09A48417A002973D026 -:10CB5000491E4172217B4068C9004518A988286890 -:10CB600008224018083821690FF07AFE0221684631 -:10CB700001710021417128680390A98868460181EC -:10CB8000002101A805F00EFC0020A880002E00D096 -:10CB9000308093E02978802211432970297840223F -:10CBA0001143297029788909890112312970A189D5 -:10CBB0000170090A4170E289E81C21690FF050FEFA -:10CBC000E089C01C3080287841063FD5C00975D067 -:10CBD00001216846017200E02CE000214172318899 -:10CBE000091D81810495E189019808180590001DAF -:10CBF00006907048017A68460177002102A805F086 -:10CC0000D1FB074630880C303080022F06D0002F31 -:10CC100054D065E03DE033E01CE05EE065486946E5 -:10CC2000097F4268CB00D218037A994202D29188D8 -:10CC3000002902D0042753E02FE0417A491C4172B9 -:10CC40001560308890800020308049E06168A089BC -:10CC5000888033E029788909890116312970A189F2 -:10CC60000170090A41700198E1890170090A417057 -:10CC7000228A681D61690FF0F3FD208A401D46E796 -:10CC800028788009800118302870207B6870022085 -:10CC90007EE760680188090401D4052720E0C08888 -:10CCA000A189884201D006271AE01E2028700120A1 -:10CCB0003080606801884904490C01800098002890 -:10CCC0000ED03C4800220088A16883000320FFF7B3 -:10CCD00067FC61682078887007E0002030800327B7 -:10CCE0006068009902888A430280384691E6FFB561 -:10CCF0009FB0289D0E46002805D0172803D82A8803 -:10CD00002E4B9A4202D1072023B0F0BD3278530651 -:10CD100001D4D20901D00820F6E700226B461A712F -:10CD20005A7114463278431E1D939BB2189303AB7D -:10CD30001A939706CB1CBF0E1B93821E711C3B00DF -:10CD400010F032F8209011EE66EE74EEB0EED4EEF4 -:10CD5000EDEEECEEEBEEEAEEE9EEEEEEE8EEE7EE0F -:10CD6000E6EEE5EE90EE05287CD1042168460171DF -:10CD7000A9780172F078B2780102114368464181C6 -:10CD80003179417170788006800E0C282ED009DC34 -:10CD9000801E030010F008F80919661C662166243D -:10CDA0006627660012282AD00ADC0E2821D0102817 -:10CDB000DAD121E01C100020FF710000FFFF00000D -:10CDC00016281FD01828CFD11FE02878800701E04F -:10CDD00028784007002845DA45E128780007F9E778 -:10CDE0002878C006F6E728788006F3E7287840061A -:10CDF000F0E728780006EDE72888C005EAE72888EC -:10CE0000C004E7E728888004E4E728884004E1E7D5 -:10CE10002A78920726D50328A6D105206A461071E4 -:10CE2000487809780002084310811CE129784907F5 -:10CE3000F0D5062816D3717890B2012902D00229C4 -:10CE400092D101E0022100E01021189106216A46EA -:10CE500011710021118102AF189AB11C0237921C86 -:10CE60001B921AE0B3E04A780B7812021A433A8018 -:10CE7000801E891C1790BA1C1A91189801F05FFF48 -:10CE80001A991898189A091817986B46801A1A89CF -:10CE900080B2521C1A811B9ABF1D8242E3D900281E -:10CEA00086D1E0E028780007B4D51D98694682B2A3 -:10CEB0000720087100200881701C0A3111E04378B6 -:10CEC00007781B023B430B80C37887781B023B43E8 -:10CED0004B806F463B89121F5B1C001D92B23B8149 -:10CEE000091D042AEBD2002A71D1BCE02978C906B9 -:10CEF0006DD502286BD3082069460871002048814F -:10CF000070780872844692B2B01C1A9919E089E0D0 -:10CF100090E07EE067E05BE030E025E019E013E0C0 -:10CF2000BCE0437807781B023B430B80831C4B60BB -:10CF30006346D21A6F467B8960445B1C92B27B8148 -:10CF400008319445EDD9CEE7287880063FD50922EF -:10CF500003E0287840063AD50A2268460271AA887A -:10CF60000281189A428107E0287800062FD50B200D -:10CF70006A46107118981081039174E02988C905D8 -:10CF800025D5022823D30C2069460871002048814A -:10CF900070780872844692B2B01C1A9914E04378F3 -:10CFA00007781B023B430B80C37887781B023B4307 -:10CFB0004B80031D4B606346D21A6F467B896044E9 -:10CFC0005B1C92B27B8108319445E8D98BE763E022 -:10CFD0002988C90460D501285ED10D2168460171F8 -:10CFE000A98801813FE02988890455D5052853D3B4 -:10CFF0000E2269460A71AA880A811B99401F4A7845 -:10D00000097812020A4369464A818881701D04909A -:10D0100029E0298849043FD501283DD10F206946E0 -:10D02000087120E02A88120436D44A780B7812025C -:10D030001A43EA8003282FD332789206920E1B2AD5 -:10D0400026D011226B461A712A880123DB031A436A -:10D050002A804A78097812020A4369460A81C01E6A -:10D0600048811B98039030788006800E1B2809D0D9 -:10D070001D2807D003202299FFF737FB2888C00B13 -:10D08000C003288001A8219905F08CF920463BE6D1 -:10D0900010226B461A71DCE70724F7E70824F5E74E -:10D0A00000B597B0032806D16A461070019100219F -:10D0B000684605F077F917B000BD000010B58B7811 -:10D0C000002B11D082789A4207D10B88002B0BD00D -:10D0D00003E08B79091D002B08D08B789A42F8D198 -:10D0E00003880C88A342F4D1002010BD812010BD1C -:10D0F000052826D0002A02D0012A0DD102E0098895 -:10D10000090501E009888904890F07D0012918D091 -:10D11000022909D003290ED081207047002A01D0AE -:10D12000032070470220704703280AD0042808D043 -:10D13000002804D007E0042803D0022803D00520EB -:10D140007047002070470F20704770B51388054660 -:10D1500014460B8018061DD5FE481022807AA8427E -:10D1600003D813430B80002070BDA0689343007860 -:10D17000E840C007C00E03430B802078A1788007E9 -:10D18000800D0843F4490FF0D4FBA06869430818E8 -:10D19000401C70BD906870BD37B569468B881380A0 -:10D1A00019061BD5EB4C0125A47A9168844209D855 -:10D1B000FE280FD1D80602D5A5406D1E00E000253F -:10D1C0000D7007E085400C78DB06DB0FAC43834035 -:10D1D0001C430C7010881021884310803EBDF8B5A8 -:10D1E0000746C81C80080E468000B04201D0862049 -:10D1F000F8BD082A01D90E20F8BDD64D00202E60BA -:10D20000AF802881AA723446E88016E0E988491C7C -:10D21000E980810610D48007A178800D0843CE49AB -:10D220000FF087FB206800F0BAFA2989401880B215 -:10D230002881381A8019A0600C3420884107E5D471 -:10D240000020F8BDFFB589B09F041646139DBF0CA2 -:10D250000193099800F095FA04000AD0207800069E -:10D2600009D5BC48817A0A98814204D887200DB03C -:10D27000F0BD0120FBE7224669460A98FFF765FFEB -:10D280000690002069460872052D14D0012221461F -:10D290002846FFF72DFF0028E9D1207840060AD55F -:10D2A000022168460172099981810188C181068243 -:10D2B0004782129805900198000404D500273E4645 -:10D2C0000125079709E02078A1788007800D0843A1 -:10D2D000A14907900FF02DFB0D46019840040AD597 -:10D2E0000798A84207D12088E1788005800F0002C6 -:10D2F0000843B04201D3AE4201D90720B7E7B819BD -:10D3000080B20190A84201D90D20B0E76846007AAA -:10D31000002804D002A805F0CEFE0028A7D1079867 -:10D32000A8420BD12088032109028843019989056D -:10D33000890F0902084320800198E07014980028A2 -:10D3400000D007801298002815D006983A46801918 -:10D3500012990FF085FA224669460A98FFF7F5FE02 -:10D36000694608881021884369460880224600994A -:10D370000A98FFF711FF002079E7FFB5754D0C22E1 -:10D38000E8882968504383B00C180D9F72490598AE -:10D390000FF0CFFA0091049800F001FA29682A8969 -:10D3A0008E46611A0C310918944651188AB2A98820 -:10D3B000914202D8842007B0F0BD6A46168A320630 -:10D3C00003D5B20601D58520F5E7EA88521C92B252 -:10D3D000EA800E9B002B00D01A80B20601D5A76010 -:10D3E00006E0604480B22881091A70460818A060DF -:10D3F0002246FE200499FFF7CFFE0598A070009802 -:10D40000E07020880599800889058000890F08430D -:10D4100003210902884300998905890F09020843FD -:10D4200004210843208003988078A0710398008825 -:10D43000A08000202073310601D5AC7A00E00124E1 -:10D44000B10600D5002700260EE00521002001913D -:10D4500002900097E88831460C9B069AFFF7F2FE8F -:10D460000028A8D1761CF6B2A642EED30020A2E78F -:10D47000F1B5009800F085F9060002D00025009C67 -:10D4800014E00120F8BD204600F07BF90746007843 -:10D4900031498007820DB87810430FF04AFA386896 -:10D4A00000F07DF94019641C85B2A4B22948C188F6 -:10D4B000601E8142E7DC00992648491EC18001892F -:10D4C000491B018100203070F8BD002804D0401EA7 -:10D4D00010809170002070470120704710B50446FD -:10D4E00001881C48C288914201D3822010BD006887 -:10D4F0000C22514342189079A072908820811088A4 -:10D50000D1788005800F00020843A081A078211DFA -:10D51000FFF71BFE20612088401C2080E080002057 -:10D5200010BD012101827047F7B50546002084B087 -:10D53000C0431080686817468178684681706868C3 -:10D5400001886846018000218171288A2C88A042C8 -:10D5500005D303E0281000200102000004462C82BD -:10D5600035E0288A401C2882301D6968FFF7A6FD37 -:10D5700000282AD139889248814201D1601E388022 -:10D580006888A04228D33088F1788005800F000297 -:10D59000084302906946301DFFF790FD002814D122 -:10D5A0006989874881421BD0002231460598FFF7E0 -:10D5B0009FFD002809D16A890298824205D1E96855 -:10D5C000B0680FF020F900280AD0641CA4B22046ED -:10D5D00000F0D7F80600C4D1641E2C828220EAE64F -:10D5E0007C80B079B871B088B8803078B178800725 -:10D5F000800D084378810298B8813946287A3246EE -:10D600000831FFF7A2FD38610020D4E6FFB585B0F0 -:10D610001C460F46059800F0B4F8050009D028789C -:10D62000000608D56748807AB84204D8872009B038 -:10D63000F0BD0120FBE707982A468605B60D69462E -:10D640003846FFF782FD07460E98052816D00022BF -:10D650002946FFF74DFD0028E9D1287840060DD571 -:10D660000121684601710599018101884181868106 -:10D67000C48101A805F01FFD0028D8D12888AA7808 -:10D680008107890D11438005800FEA78000210435D -:10D69000079A964207D04C4A914204D3611E8142B8 -:10D6A00001DD0B20C3E7864201D90720BFE7801BBD -:10D6B00082B2A24200D922461098002800D00280EF -:10D6C0000F98002802D0B9190FF0CAF80020AEE771 -:10D6D000F8B51D4617460E4600F053F8040008D072 -:10D6E0002078000607D53748807AB04203D88720D3 -:10D6F000F8BD0120F8BD224639463046FFF725FD2A -:10D70000002D0BD02078A1788007800D08432E498A -:10D71000884201D2012000E0002028700020F8BDDE -:10D72000F8B51E4617460D4600F02BF8040008D049 -:10D730002078000607D52348807AA84203D887209E -:10D74000F8BD0120F8BD224639462846FFF724FDE2 -:10D75000FF2E14D02588A178A807800D08431A4908 -:10D760000FF0E7F8002E03D1FF31FF31033189B20A -:10D77000A170A80880008905890F08432080002037 -:10D78000F8BD1049CA88824207D3002805D00C2270 -:10D79000096850430C38081870470020704703B5DB -:10D7A0000846694609888A0607D4090604D505494A -:10D7B000897A4143491C88B20CBD00200CBD000091 -:10D7C000FFFF00002810002001020000F8B50778D4 -:10D7D0000D460446012F19D0072F02D00C2F19D166 -:10D7E00014E0A068216906780B2E0BD00520FEF707 -:10D7F0007CFF052E0ED07823002205202169FEF73C -:10D80000CFFE07E0782300220620F8E705202169F3 -:10D81000FEF76BFF002D0ED0002028702946204611 -:10D8200003F036F9FE482978C05D884201D1032013 -:10D83000F8BD0220F8BD0021204603F029F90020A0 -:10D84000F8BD70B50E460C462036317901208AB0FD -:10D850001546002909D0012905D12978042902D1CA -:10D860000520107000200AB070BD6068019005A806 -:10D8700002900D21C01C0FF050F8032205A8A168EA -:10D880000EF0EEFF01203071062069460870206A14 -:10D89000049029466846FFF799FFE4E770B50C4607 -:10D8A000154620310A790120062686B0002A2CD0A0 -:10D8B000012A28D12978042925D169681022A06875 -:10D8C00001F0B4F96868C07B000606D5D44AA068A8 -:10D8D0001023103A014601F09EF91022A168E06879 -:10D8E00001F0A4F9A068C07B000606D5CC4AE06828 -:10D8F0001023103A014601F08EF92E70A06868607E -:10D90000E068A860002006B070BD60680190C4485F -:10D91000203802900120087168460670206A049041 -:10D9200029466846FFF752FFEDE7027B032A06D03F -:10D93000002224235A540B78092B02D003E0042040 -:10D9400070470A76CA61027B9300521C0273C15071 -:10D9500003207047F0B50E4615460C4620360246A9 -:10D9600031790120072393B000290CD0012924D05C -:10D9700002292ED0032904D12978042901D12B7042 -:10D98000002013B0F0BD01203071606800280DD078 -:10D99000A1690B7060684860206988606069C86030 -:10D9A000206A08621046FFF7C0FFEAE706202870E9 -:10D9B000206968606069A86009E029780629E0D1DB -:10D9C00002203071042028709548203868600320B8 -:10D9D000D7E729780429D4D1A08910280AD910388A -:10D9E00080B2A081A1681023091805A86A6801F017 -:10D9F00012F923E010282FD0C2B21020801AA1689B -:10DA00000DAF1190C0190EF02BFF11980006000EFB -:10DA100006D0401EC1B28020785438460EF07DFFFB -:10DA2000626910230DA909A801F0F5F8102309A9CE -:10DA300005A86A6801F0EFF8032030716068019072 -:10DA400005A80290062069460870206A04902946BD -:10DA50006846FFF7BBFE94E710232269A168E2E75E -:10DA6000F0B50E460C4620363179012006278FB0DE -:10DA7000154600290BD0012932D0022905D1297879 -:10DA8000042902D10820107000200FB0F0BD217DC4 -:10DA900008A8CA07D20F02718807C10F08A8017130 -:10DAA0006846027041700722801CE1680EF0D8FEC3 -:10DAB00002A80722013021690EF0D2FE60680590AD -:10DAC0000AA8069010236A46A16801F0A4F8012074 -:10DAD000307168460774206A0890294604A820E03F -:10DAE00029780429D1D1062205A8E1690EF0B8FEF3 -:10DAF00006A806220230A1690EF0B2FE00200890AE -:10DB00006068019009A80290102305AA696801F0D5 -:10DB100082F80220307168460770206A0490294616 -:10DB20006846FFF753FEB0E770B50D460C4620354A -:10DB3000297901208CB01646002909D0012905D188 -:10DB40003178042902D10920107000200CB070BD7A -:10DB50006068019006A802900822E1680EF080FE3D -:10DB6000082208A8A1680EF07BFE0120287106207B -:10DB700069460870206A049031466846FFF726FE21 -:10DB8000E4E770B50D460C462035297901208CB0AC -:10DB90001646002908D00129D8D131780429D5D1D9 -:10DBA0000A2010700020D1E76068019006A802905A -:10DBB0000822A1680EF054FE002008900990012070 -:10DBC0002871062069460870206A0490314668462C -:10DBD000FFF7FCFDBAE730B50B4620331C79012076 -:10DBE0008BB0002C09D0012C05D11178042902D169 -:10DBF0000B20107000200BB030BD4868019005A8C4 -:10DC000002908C6868462578057564784475CC6800 -:10DC1000257885756478C47500200690079001E02A -:10DC200018CF010008900120187106236846037080 -:10DC3000086A049011466846FFF7C8FDDBE770B537 -:10DC40000C462034034625790120002D0AD0012DF1 -:10DC500014D0022D05D111780A2902D10C201070A0 -:10DC6000002070BD01202071C868052202704A683A -:10DC70004260F84A8260921CC2600BE015780B2D5E -:10DC8000EFD102202071C8680424047052684260F9 -:10DC90008A688260096A016201461846FFF745FEFC -:10DCA00070BD30B5011D0246313294780325837969 -:10DCB000ED432C4323408371DB070DD04B7954791E -:10DCC00023404B710B79127913400B718278C9781C -:10DCD0008A4200D9817030BD00224A710A71F5E78D -:10DCE000F7B50C4686B000206946264608702036F7 -:10DCF000317901271E2015461F2977D24B007B441E -:10DD00009B885B009F441E0017023E025602690278 -:10DD100088029A02D102F5022E03590371037F0390 -:10DD2000AE03C303CC03F7031A0464049A04AB04E0 -:10DD3000DF04FE0410052A0565059B05C60583055D -:10DD400087058B056069002802D0007813287DD0F4 -:10DD5000A0680590002849D0012168460170206A1A -:10DD600004900321684601710A214171E069029023 -:10DD700020790028EFD0059909780029E7D00C29EF -:10DD800064D20B000FF010F80CFD1A4B90B5E8FCB4 -:10DD9000FBFAF9F807FD022828D16069002802D0B3 -:10DDA0000078082852D1022168460170206A049048 -:10DDB00005984178684601710021B9E20620216A80 -:10DDC000FEF793FC20790728E6D1606900F050FF48 -:10DDD00002280CD0606900F04BFF042807D060696E -:10DDE0000028B8D000780128D6D103E01BE2616991 -:10DDF0000120087005980079C11F0A2901D30A2063 -:10DE000050E06169072288706069059930300EF032 -:10DE100027FD0120307161690320087034E0072874 -:10DE2000BAD16069002896D001780929B4D1059942 -:10DE3000C978890707D1059949790029DFD1059962 -:10DE400089790029DBD105994A7900E04EE2014643 -:10DE500020314B7D9A43D2D1059A8B7D92799A439A -:10DE6000CDD1059A1279D31F0A2BC8D209799142D4 -:10DE700036D80722C01C05990EF0F2FC0120307143 -:10DE800061690A200870032069460870206A0490BE -:10DE90006069313001906069001D029060691C303A -:10DEA0000390A1E22076F2E311288DD1606900F0A1 -:10DEB000DFFE042804D0606900F0DAFE0B2893D15D -:10DEC0006069059910223730491C0EF0C9FC606961 -:10DED000017804297CD12421095C8278914201D9FE -:10DEE0000620DFE7052101700320307168460170CC -:10DEF000E2E3112894D1606900F0BAFE062804D04C -:10DF0000606900F0B5FE0C288AD1E068002813D0C3 -:10DF10002069002810D060690178062910D00D21F1 -:10DF200001706069059910225730491C0EF098FC69 -:10DF30006069573009218CE100206946087072E160 -:10DF4000072101706069059910224730491C0EF0C5 -:10DF500087FC60694730EDE70228F0D1606900F086 -:10DF600087FE0028EBD0606900F082FE0128E6D031 -:10DF7000606900F07DFE05E0B1E08DE06CE02AE034 -:10DF80000AE0D6E00828DAD0052168460171059834 -:10DF900041786846417146E11128D0D16069002876 -:10DFA000CDD001780E29CAD1C16A4078022810D09C -:10DFB0000020142250431430085805991022491C9F -:10DFC0000EF04EFC0520216A00F040FE0F205EE0BE -:10DFD000F1E10120EDE70B28B1D160690028AED056 -:10DFE00001780F29ABD1C16A4078022826D00020E1 -:10DFF000142250430C300958059842780A708078F2 -:10E0000048706069C16A4078022819D00020142243 -:10E0100050431030085805990822C91C0EF020FC06 -:10E020000520216A00F012FE60694178022909D0BA -:10E0300000220832825C5208520073E00120D7E7C8 -:10E040000120E4E70122F4E7012100E0002108318A -:10E050004254BCE3F2CE010011289CD16069002833 -:10E0600099D00178102996D1C16A4078022811D040 -:10E070000020142250431830085805991022491CDA -:10E080000EF0EEFB0520216A00F0E0FD1120616931 -:10E090000870B4E30120ECE7082884D16069002807 -:10E0A0009DD00178112997D10599C06A49780170EE -:10E0B00060690599C06A0622401C891C0EF0D0FBDD -:10E0C0000520216A00F0C2FD60694178022904D070 -:10E0D00000220832825CFD2323E00122F9E71128A7 -:10E0E000BBD160690028BBD001781229B5D1C16AC3 -:10E0F0004078022819D00020142250431C300858C0 -:10E1000005991022491C0EF0ABFB0520216A00F096 -:10E110009DFD60694178022909D000220832825CA5 -:10E12000FB231A40022991D18EE70120E4E7012266 -:10E13000F4E70720B6E6287801288ED1606969687F -:10E1400014221C30F3F74CF86069017F002901D0DC -:10E150002176ACE30178032901D0032037E00227C0 -:10E16000C77081794907490F8171017A4907490FC1 -:10E170000172417A4907490F41726069FFF791FDC9 -:10E18000377196E228780F28E3D107206946087096 -:10E19000216A0491916802916946087161690722B8 -:10E1A000C91C02980EF05CFB616904200870002015 -:10E1B0003071BBE028780328CBD16069017805294C -:10E1C000696807D0082247300EF04AFB04203071FE -:10E1D00005206FE208225730F6E728780328B8D1E7 -:10E1E000606901780529696811D008224F300EF066 -:10E1F00037FB052030716069006A00280AD00220D0 -:10E200002870002028716069006AA860F9E008227F -:10E210005F30ECE704204DE22878022899D1287974 -:10E22000002801D0207642E36069A9680162606934 -:10E23000002901D1F949016206200BE228780F2854 -:10E2400087D1A868E0616069017805292BD0473043 -:10E2500007213171E16802220A706269126A4A601C -:10E26000886060693030C8606069C01C086162699C -:10E27000087D926A400812784000D207D20F1043FE -:10E2800008756269926A521C8A61FD2210406269B7 -:10E29000D26A1278D207920F104308756069C06A7B -:10E2A000401CC86153E25730D2E728780828BAD119 -:10E2B0006069017805291AD00B2101700720694691 -:10E2C0000870206A0490E069029011200871029899 -:10E2D0000321017051681022401C0EF0C1FA002188 -:10E2E0006846FFF773FA00203071E06187E206218B -:10E2F000E3E728780F2896D1072069460870206A3E -:10E300000490A868029011200871029804210170FD -:10E3100061690A78072A0ED0002232710C220A7035 -:10E3200061691022401C47310EF09AFA00216846BC -:10E33000FFF74CFA63E21022401C57310EF090FABE -:10E3400000216846FFF742FA0A203071E168032095 -:10E3500008706069006A4860606957308860606969 -:10E360004730F3E128780828A1D160696968102254 -:10E3700037300EF048FA002801D0042092E5606999 -:10E380000078072817D00A203071E1680320087050 -:10E390006069006A4860606957308860606947302A -:10E3A000C860206A08620698FFF7BFFA07466069EE -:10E3B000FFF777FC6BE208207AE1287809289AD1E8 -:10E3C0000B20307161696868897810224018511AF1 -:10E3D0000EF0A3FA082069460870206A0490686865 -:10E3E000019060698078087268E129780D29BBD1B5 -:10E3F00061698979C90703D00C20307109203EE09A -:10E400003071032770E228780E28ADD1606914229C -:10E41000291D1C30F2F7E4FE6069018DC06A41726B -:10E42000090A817260698178C06AC1716169CA6ACA -:10E43000081D117AC909C90111724379626919432A -:10E440008378D26A9B079B0F012B00D000230079B1 -:10E450009B01C00003431943117260694078012891 -:10E4600076D0B4E160694178022901D0012100E051 -:10E4700000210831405CC00707D00E20EAE0694661 -:10E480000870206A1146049019E11320B8E7287833 -:10E490000F2894D1A868E0610F2030710520EEE7C5 -:10E4A000287803288BD16069C16A4078022801D09E -:10E4B000012000E0002014225043103008580822A8 -:10E4C00069680EF0CDF910203071E16806202269EC -:10E4D00008706069406A48606069C36A40780228D1 -:10E4E00001D0012000E00020142778431030185894 -:10E4F000CA6088602BE128780C2886D16069C26ADE -:10E500004078022801D0012000E000201421484377 -:10E510000C30105802230932696800F07CFB11208E -:10E520003071E168052008706069006A48606069C0 -:10E53000C06A093088603948001F07E128780B2835 -:10E54000A7D161694878CA6A022802D0012001E097 -:10E5500059E1002014235843143010588A78696810 -:10E560000EF07EF960694178C26A022901D001216A -:10E5700000E0002114235943143152588178501877 -:10E580001022511A0EF0C9F9072069460870206A56 -:10E590000490E06902901120087102980621017030 -:10E5A0006169CA6A4978022901D0012100E000218D -:10E5B00014235943143151581022401C0EF050F9C5 -:10E5C00000216846FFF702F90020E06112206FE0A9 -:10E5D00028780F2891D1072168460170206A04909D -:10E5E000906802900B22684602710298017061697E -:10E5F000CA6A4978022901D0012100E000211423D0 -:10E6000059430C3151580A784270497881706169D8 -:10E61000CA6A4978022903D0012102E0F8CE01003C -:10E62000002114235943103151580822C01C0EF008 -:10E6300017F900216846FFF7C9F826E760694178B5 -:10E64000022901D0012100E000210831405C80074F -:10E6500003D5142030710A2011E71620D0E628785F -:10E660000F287AD1A868E061072069460870206AFF -:10E670000490E0690290112008710298082101704D -:10E680006169CA6A4978022902D0012101E011E1D9 -:10E69000002114235943183151581022401C0EF008 -:10E6A000DFF800216846FFF791F80020E0611520AF -:10E6B00030710A2069460870206A0490294668462D -:10E6C000FFF784F82BE028780F2846D10720694609 -:10E6D0000870206A049090680290082008710298DF -:10E6E0000921017061690622C9690978417061696F -:10E6F000801CC969491C0EF0B3F800216846FFF779 -:10E7000065F8AAE760694178022901D0012200E09A -:10E7100000220832805C400703D51720C8E707466F -:10E72000B5E0012953D070E028780F2815D1A868EA -:10E73000E06118203071E168052008706069006AA6 -:10E7400048606069C06A09308860F848C860206A1B -:10E7500008620698FFF7E9F8E1E76FE028780B28F0 -:10E760006CD16069C16A4078022801D0012000E0C4 -:10E770000020142250431C300858102269680EF003 -:10E780006FF8072069460870206A0490E0690290DB -:10E790001120087102980A2101706169CA6A4978DA -:10E7A000022901D0012100E00021142359431C312A -:10E7B00051581022401C0EF053F800216846FFF714 -:10E7C00005F80020E0616069407801281DD119201A -:10E7D00016E660694278022A09D000210831411802 -:10E7E000097800290DD0CA0703D00E2106E00121C7 -:10E7F000F4E7890701D5102100E0122101700027FC -:10E8000072E0012A01D00D20FAE51C20F8E51D2058 -:10E8100030710B2033E62978102948D1F0E5606982 -:10E820000178012943D0082941D00021317100F03D -:10E8300019FA0C2069460870206A049037E028789D -:10E840000F2805D01020107003271B2030714BE0DB -:10E85000072168460170206A0490A868029002218E -:10E8600068460171029805210170217E41700021E6 -:10E870006846FEF7ABFF0B2168460170206A0490E2 -:10E8800029466846FEF7A2FF07461B203071012F7C -:10E890000DD029E0012168460170206A049004210E -:10E8A00068460171217E41710020207612E0207EB1 -:10E8B00000280FD06169132008701A2030710A20D7 -:10E8C00069460870206A049029466846FEF77EFF74 -:10E8D000074609E06069002801D0142101706846EC -:10E8E0000078002800D021E5384609B0F0BDF7B522 -:10E8F0000F4620373879012686B00C46002804D010 -:10E90000012828D002281CD197E02079012804D0C2 -:10E91000022811D0032814D10AE0A0684078012809 -:10E920000ED10620216AFDF7BAFE00287FD10CE047 -:10E93000A1681320087008E0A0684178022901D07E -:10E94000052674E00078082871D1012038710A206A -:10E950006946087033E0089800780F2867D10721CE -:10E9600068460170206A04900898856802952279AB -:10E970000220012A04D0022A29D0032A57D10FE00D -:10E980000646684606710B202870207B0021400750 -:10E99000400F68706846FEF719FFA068067045E0F2 -:10E9A00006466846067105202870207B68700021A5 -:10E9B0006846FEF70BFF3E710B2168460170206A26 -:10E9C000049068460899FEF701FF06462FE0684666 -:10E9D000017101202870207C6870607CC007C00F26 -:10E9E000A870A07C4007400FE870E17C2971C00747 -:10E9F0001FD0207D4007400F6871607D4007400FA9 -:10EA0000A87100216846FEF7E1FEA06807222946AA -:10EA100030300DF025FFE068017AA06820300171E8 -:10EA2000A16828798870A1680920087000263046FE -:10EA30005BE70020A8716871E3E7A1681420087003 -:10EA4000012168460170206A049004216846017122 -:10EA5000217B41710021FEF7B9FEE7E7F0B585B0F3 -:10EA60000F4605460124287B800040198038C66F78 -:10EA70003078411E0A290AD22C49800032314018D0 -:10EA80008038C36F3A463146284698470446002CE2 -:10EA900001D0012C11D1287B401E0006000E2873E6 -:10EAA00001D00324DFE70D2069460870306A049026 -:10EAB000002101966846FEF789FE032CD3D020463C -:10EAC00005B0F0BD70B515460A4604462946104605 -:10EAD000FFF7C4FF0646002C0FD0207814280CD175 -:10EAE000207E002806D000202870204629460C30C1 -:10EAF000FFF7B4FF204600F0B5F8304670BD704710 -:10EB000010B5012903D0022901D0052010BD4170A4 -:10EB100000F0A8F8002010BD002809D0027E002ACD -:10EB200006D00A4601460C31CCE70000F6CE0100C3 -:10EB30000120704730B5044687B00D460620FDF72A -:10EB4000D4FD29460520FDF7D0FD2078142805D0F6 -:10EB50000020694608702046FFF7DEFF07B030BD91 -:10EB60007FB50E4600216A4611730178092903D04A -:10EB70000A2903D0002407E0446900E08468002CDF -:10EB800002D0217E002912D0154601462846FEF704 -:10EB9000CCFE032809D1324629462046FFF792FFD2 -:10EBA0006946097B002900D0042004B070BD2546C9 -:10EBB0000C35EAE700B50023012285B005280CD00A -:10EBC000062808D168460270049102210171437140 -:10EBD0000021FEF7FBFD05B000BD68460270049100 -:10EBE0000271F4E710B590B00C4605216A46117029 -:10EBF000019022480290001D03900AA96846FFF781 -:10EC0000AFFF002805D1102220460B990DF028FEF9 -:10EC1000002010B010BD30B505E05B1EDBB2CC5C4F -:10EC2000D55C6C40C454002BF7D130BD10B5002426 -:10EC300009E00B78521E5B00234303700B78401CE5 -:10EC4000DC09D2B2491C002AF3D110BD70B50C46C4 -:10EC50000546FDF74AFD7823002221462846FDF7A8 -:10EC60009FFC70BD4178012900D0082101707047D8 -:10EC7000002801D00078704708207047F0CE0100CE -:10EC800070B50D46040012D0002D10D02101284689 -:10EC90000DF043FE1022544928460DF0E1FD524884 -:10ECA00001210838018044804560002070BD0120AA -:10ECB00070BD70B54C4E00240546083E11E07168E9 -:10ECC00020014018817BAA7B914209D1C17BEA7B5C -:10ECD000914205D10C2229460DF095FD002806D061 -:10ECE000641C30888442EADB0020C04370BD2046AB -:10ECF00070BD70B50D4606000AD0002D08D03A4C04 -:10ED0000083C20886188401C884203D9042070BDDB -:10ED1000102070BD3046FFF7CCFF002801DB401CFF -:10ED20000AE02088616800014018102231460DF089 -:10ED300097FD2088401C20802870002070BD70B591 -:10ED400014460D001FD0002C1DD00021A1700228F8 -:10ED500002D0102817D108E068782978000208430B -:10ED600011D00121A17010800BE02846FFF7A1FF10 -:10ED7000002808DB401CA070687B297B0002084348 -:10ED80002080002070BD012070BD70B5054614467E -:10ED90000E000AD000203070A878012807D004D9CE -:10EDA000114908390A8890420BD9012070BD002C06 -:10EDB00004D0287820702888000A5070022008703B -:10EDC00010E0002C0CD049680001411810222046A8 -:10EDD00010390DF045FD287820732888000A6073EB -:10EDE00010203070002070BD4C01002070B5FD4D2A -:10EDF000040008D0012C10D0022C07D0032C05D021 -:10EE0000F9A1702007E0F8A1672004E02878012824 -:10EE100003D0F5A16D200DF0AEFE2C7070BD70B565 -:10EE2000F04D044610280AD0112C16D028468178BF -:10EE3000122C07D0132C0AD0EBA19F200BE0EAA1E3 -:10EE4000942008E0112908D0E7A1992003E01129B6 -:10EE500003D0E5A19C200DF08EFEAC7070BD10B506 -:10EE6000E04894B0007B002819D01720694608704C -:10EE7000DC4900A806220D3102300DF0F1FC09A991 -:10EE8000684606F056FA0446112805D0002C03D037 -:10EE9000D5A1BB200DF06FFE204614B010BD32206E -:10EEA000E4E710B501220023114606F03FFB10BD38 -:10EEB000FFB595B01D460E460746FFF7F2FF04006A -:10EEC0000AD02078222804D3A07F8006C00FA84251 -:10EED00004D1082019B0F0BDC748FBE737216846C8 -:10EEE00001704780002D05D00121017146711799ED -:10EEF000817102E000206946087109A9684606F0A0 -:10EF000018FAA07FDF21084069010843A07700209C -:10EF1000E0E770B50446084620380D4603000DF0C2 -:10EF200043FF0A060A11232C334249505761FF2040 -:10EF3000ADA1083052E02078202851D1FF20AAA1AD -:10EF40000B304BE0A7480178032949D0807813287B -:10EF500046D02078242843D0252841D023283FD0EC -:10EF6000FF20A1A10E3039E02078222838D02328B4 -:10EF700036D8FF209CA1153030E0207822282FD0F1 -:10EF8000FF2099A1193029E02078222828D02428B0 -:10EF900026D0262824D0272822D0292820D0FF2098 -:10EFA00091A11C301AE02078252819D0FF208EA1CD -:10EFB000233013E02078252812D0FF208AA12630A4 -:10EFC0000CE0207825280BD0FF2087A1293005E010 -:10EFD0002078282804D0FF2083A12C300DF0CBFD11 -:10EFE000257070BDFF2080A12F30F7E730B5834C2E -:10EFF0000B88834A022801D0934204D09D1FA5426A -:10F0000025D2022802D04D88954203D04D88AD1FED -:10F01000A5421CD24C88A34219D88B88FF25F43511 -:10F02000AB4214D8022802D0C888904205D0C888C4 -:10F03000724D0A382D1FA84209D2C888904208D0C4 -:10F04000944206D05B1C63438000834201DB0720AF -:10F0500030BD002030BDF0B56A49884245D36A4AC8 -:10F060000125AD041368A84201D398423DD302792B -:10F07000002A06D0082A02D8067B082E05D90720C8 -:10F08000F0BD047B002CFAD0F6E7002A06D0046815 -:10F090008C422AD3AC4201D39C4226D3002E06D008 -:10F0A00084688C4221D3AC4201D39C421DD30024FE -:10F0B0000CE00568A700ED598D4216D30127BF0467 -:10F0C000BD4201D39D4210D3641CE4B2A242F0D8E9 -:10F0D00000220125AD040CE084689700E4598C42BD -:10F0E00003D3AC4203D39C4201D21020F0BD521C8A -:10F0F000D2B29642F0D80020F0BDFFB50022099BA5 -:10F10000002802D0994205DC58E0002902D10020F5 -:10F1100004B0F0BD0920FBE7845C002C12D08718F6 -:10F120007D78112D43D010DC2B000DF03DFE0A4000 -:10F130001726262C2C2E2E363640835C002B30D101 -:10F14000521CD2B28A42F8DBE1E71C2D2FDA123DC5 -:10F150002B000DF029FE042C2C121A2C022CD9D1D4 -:10F16000BB78039C072B237001D25B0701D40A20D4 -:10F17000CEE7029B01241B7816E0E343DB0708E09F -:10F18000012C08D013E00620C2E70F2523072D0726 -:10F190005B19002BF4D03046BAE7029B1B789C0722 -:10F1A00001D50B20B4E702242343029C2370835C27 -:10F1B000521C9A18D2B28A4202DDABE719267602B7 -:10F1C0008A42A9DBA3E710B504780B46002C1FD0B8 -:10F1D00001210E4A012C1ED0022C22D0032C2AD150 -:10F1E00025E00000341000207372635C6761705F7B -:10F1F000636F72652E630000023000007B0C00001C -:10F20000FFFF000000D001002001002002320000BA -:10F210000021197011E019708179890903290AD137 -:10F220000BE0197081798909012904D105E0197071 -:10F230008179890901D0104610BD411C0622581C55 -:10F240000DF00EFB002010BD08B51346002806D0B7 -:10F25000FEA00068009048796A468009105C18702A -:10F260000622581C0DF0FCFA08BD30B50C46097892 -:10F2700095B0222902D2082015B030BD2823694656 -:10F280000B704880132A03D03B2A01D00720F3E7F4 -:10F2900008460A7109A906F04CF8050003D121219E -:10F2A0002046FFF736FE2846E6E700B595B0232353 -:10F2B00069460B704880108888805088C880D08844 -:10F2C00048819088088100208881C88109A9684602 -:10F2D00006F02FF815B000BD70B50C00064610D032 -:10F2E000FFF7DFFD050003D1D949DA480DF043FCF3 -:10F2F000A6802889E0802889208168896081A88982 -:10F30000A08170BD70B50E46050003D00021092014 -:10F31000FDF7EBF90120D04C022E207324D0032EF0 -:10F3200004D0CC48CA491E300DF025FCCA4806213D -:10F330000D30FCF7FEFCA07C8006800EA074FFF769 -:10F340008EFDA08B00280ED0002D0CD08300012252 -:10F3500000210920FDF724F9092804D0BD48BC4943 -:10F3600028300DF008FC70BDBB4803211030FCF7BD -:10F37000E0FCA07C40218006800E0843A074B648C3 -:10F380000C3002F0D3F9DAE77FB501A9012006F0CD -:10F390004DF9002804D0AF48AD4967300DF0EBFBC4 -:10F3A000AE4E01A806F050F9050002D0052D4CD054 -:10F3B00048E0029CA07F01072CD520462230009017 -:10F3C00068462346628E80882146343301F039FB3B -:10F3D0000546A07FF7210840A077002D05D0B54253 -:10F3E0002FD09C489A49783029E0E17F4808890766 -:10F3F0004000C90F08432021095D4007400FC900A4 -:10F400000843E077207828281CD129212046FFF7DF -:10F4100080FD17E04007C4D5684622468088214613 -:10F420000E32FFF742FF0546A07FFB210840A07780 -:10F43000002D07D0B54204D08648854992300DF0A2 -:10F440009AFB0025284604B070BD0020FBE7F8B504 -:10F45000040004D1ED207E4980000DF08CFB722069 -:10F460002070606808250178091F0B000DF09CFCD6 -:10F4700011F90A3D5FF83D0EF8F83E3D3D3D3DF97E -:10F4800086F93D0073487249AA3074E0878838468F -:10F49000FFF707FD060004D16E486D49B2300DF04C -:10F4A0006AFB60780421284360706B4CA07F08439E -:10F4B000A07721213046FFF72CFDB07F8007800F19 -:10F4C000012801D1801EA080384605F05BFC38463B -:10F4D00002F0E2FF384604F0C4F839460220FDF796 -:10F4E00004F9B07FEF210840B077F8BD8688304638 -:10F4F000FFF7D7FC002804D156485549D0300DF00D -:10F500003AFB60688078012804D052485049D230D4 -:10F510000DF031FB60688179304605F052FD00281E -:10F52000E3D06178294361706168C880F8BD87883D -:10F530003846FFF7B6FC060004D146484449E3309C -:10F540000DF019FB60783946284360706068C08808 -:10F55000308160680089708160684089B0810220D4 -:10F56000FDF7C3F80020B075FFF70EFF0028DDD0CF -:10F570000120374980020DF0FEFAF8BD80783C2862 -:10F5800015D00027022815D00026002804D03148C5 -:10F590002F49F8300DF0EFFA00210846FDF7A5F8E5 -:10F5A00000210720FDF7A1F8002E05D046E0012735 -:10F5B0000026F1E70126EAE76078284360702648D4 -:10F5C000817F29438177002F38D160688688304653 -:10F5D00001F055F80546807F6168800889798000D0 -:10F5E000012900D002210843A87760680622C08A5A -:10F5F00028816068008B68816068408BA8816068A2 -:10F60000C079E87561682846183008310DF028F98E -:10F6100060680622807B68706168A81C0F310DF05D -:10F620001FF9A87F8107890F304605F094FBA87F5A -:10F630008007800F012801D107488680064801789D -:10F64000032913D08078132814D00BE00302FF01A4 -:10F65000E8F1000013030000341000200230000025 -:10F660000CE00FE0FF20FCA1453084E70120FFF70C -:10F67000BDFBF8BD1120FFF7D2FBF8BD204601F01D -:10F68000E8FCF8BD607828436070F8BDF7B5054622 -:10F690000078002700090C463E4601287ED0002253 -:10F6A000F14902287BD0072804D00A2878D0EAA1A3 -:10F6B000EE482DE1686803780D2B31D006DC042B71 -:10F6C0006FD0072B36D00A2B6AD106E0122B38D028 -:10F6D000132B40D0142BF7D1B2E011270726002CB2 -:10F6E00072D08088A0806968FB238979A171E04984 -:10F6F00005468A7F1A408A77032105F04FFF0421CF -:10F70000284605F04BFF0021284605F047FF02215F -:10F71000284605F043FF0121284605F03FFFF9E0A8 -:10F7200001270926002CDBD08088A08068688079BA -:10F730002072EFE012270E2680882146FFF7CCFDCD -:10F74000E8E01A270726002CCAD04088A080686805 -:10F750000079A071DEE081783C2936D010271E2682 -:10F76000002CBDD08088A0806868C08A208368682B -:10F77000C08AE0826868008B60836868408BA083E1 -:10F780006968207D497F4008C9074000C90F0843C8 -:10F7900020756968C007C00F497F03E05FE08AE019 -:10F7A000ADE01CE049084900084320756968A21DC6 -:10F7B000C8790831FFF748FD69682246887B0D3219 -:10F7C0000F31FFF741FD05E074E019270726002CF3 -:10F7D00070D0A271A648F722817F11407DE01B27DF -:10F7E0002E26002C66D0A1806968A21D0879491DCB -:10F7F000FFF72AFD68682030C07A60736868C078B7 -:10F800000428A07B19D040084000A073F9210840CB -:10F8100069681F22C9788907490F0843A07369687E -:10F820004007C97A400FC9000843A07369682046A1 -:10F830000F300C310DF014F86CE001210843E4E7BF -:10F840001E270E26002C6DD0A1806868E21D407A2C -:10F85000A07169688878C91CFFF7F6FC5AE0287A1D -:10F86000012805D0022815D080487BA132384FE00E -:10F870001D270E26002C55D06888A080A889E0801E -:10F88000E8892081288A6081688AA0817848DF22FF -:10F89000817FA2E712270E266888FFF71DFD002C46 -:10F8A00040D068784007400F032833D17048FD22CC -:10F8B000817F92E736E0287A03000DF075FA06049E -:10F8C00010102020202619270726002C2AD0A180DE -:10F8D0006748A271817F4908490081771AE019279A -:10F8E0000726002C1ED0A180287A012805D00320ED -:10F8F000A0715F48EF22817F6FE70220F8E7214681 -:10F900002846029A01F009FDFEBD532052A10001D4 -:10F910000DF031F90298002C068001D02780668016 -:10F920000020FEBD02980680FAE710B5504894B05A -:10F930008078132802D0082014B010BD2220694618 -:10F94000087009A9684605F0F4FC04460021072068 -:10F95000FCF7CBFE2046EFE700B5454895B0807830 -:10F96000122801D00820B5E41E216846017000214C -:10F970008170C17009A905F0DCFC0028F3D10021D9 -:10F980000720FCF7B2FE1120FFF749FA0020A1E49E -:10F9900000B5374895B00078022801D0032818D167 -:10F9A0001B2108A801730021817369460BA805F08B -:10F9B000C0FC002804D1684640781B2801D00320F1 -:10F9C00088E400210846FCF790FE6846807800280D -:10F9D00001D008207EE40120FFF708FA002079E436 -:10F9E000F8B5234C03000DF0DFF90A06801780807C -:10F9F00080804B356E80FFF7CBFF00282AD1FBF7C4 -:10FA0000AFFB002826D02221017000210172FBF7F4 -:10FA100088FBA07F012152E08EB23046FFF741FA09 -:10FA2000050004D111480CA12E300DF0A4F828785F -:10FA300021280FD0FBF794FB00281BD01221017066 -:10FA40000227077246800020A875FBF76AFBA07F9B -:10FA50003843A077F8BD00007372635C6761705F24 -:10FA6000636F72652E630000FFFF00003605000023 -:10FA700034100020132229463046FFF7F6FBE9E751 -:10FA8000A578122D06D0132D07D0FA49FA480DF0AB -:10FA900072F8DFE7FFF760FF01E0FFF746FF00289D -:10FAA000D8D1FBF75DFB0028D4D022210170122DA4 -:10FAB00007D002210172FBF734FBA07F102108431D -:10FAC000C7E70121F6E7A07C810901290BD0800955 -:10FAD00004D0E948E74922300DF04DF80321002019 -:10FAE000FFF710FCB6E70221F9E7E348E1492930C6 -:10FAF000CDE7F7B514460D0004D1DF48DD493130BC -:10FB00000DF039F828780827012807D002281FD0DF -:10FB1000D948D84962300DF02EF8FEBD0098FFF7A5 -:10FB2000C0F9060004D1D448D24938300DF023F88A -:10FB30000220B0751030207060783843607007CDB7 -:10FB4000083407C4CD482022817F11438177FEBD50 -:10FB50000098FFF7A6F9060004D1C748C54946300A -:10FB60000DF009F8A988C648814208D1EA88824286 -:10FB700005D1132231460098FFF777FBFEBD814285 -:10FB800002D1E888002809D012202070607838431C -:10FB9000607007CD083407C4002006E078230022F7 -:10FBA00002200099FCF7FCFC0120B075FEBDB348B3 -:10FBB00040897047FFB591B0149800F0DBFD002834 -:10FBC0005DD10124684603218471C902818000222D -:10FBD00001A9204604F017F8002850D168461521E5 -:10FBE00084714902818000261C2102A800960CF035 -:10FBF00096FE012001466846103101700020014642 -:10FC0000684641708178F9273940891C2143817009 -:10FC1000017A02252943017212998186C6861F2125 -:10FC200001870C9011980F9001A80B9009AA0BA9BD -:10FC300002A803F0B3FD002821D168468F4E808CC6 -:10FC4000F080684684718F498180807809AA3840A5 -:10FC5000801C41084900684681708586058713A885 -:10FC60000F900BA902A803F099FD002807D1684660 -:10FC7000808C308131460A31149800F08EFD15B029 -:10FC8000F0BD30B50C46804995B08C4241D37F49D8 -:10FC9000012292040968944201D38C4239D320385E -:10FCA0000022012503000DF07FF806042F494D5373 -:10FCB0005C6400210820FCF7F2FC002802D011202F -:10FCC00015B030BD24206946087000A80522A11C8B -:10FCD00002300CF0C5FD09A9684605F02AFB0500B5 -:10FCE00002D0082D0ED031E008230022114618461C -:10FCF000FCF756FC082829D05F485E49D6300CF046 -:10FD00003AFF23E00620DBE76068002803D0884242 -:10FD100001D21020D4E73D2168460170218841803E -:10FD20006188818009A905F004FB05000ED1606897 -:10FD300000280BD06946098D018007E0206801F09A -:10FD400037FD02E0204600F0D8FC05462846B7E71C -:10FD50003E2007E0857000E0827009A905F0E9FA0D -:10FD6000F3E73420694608702078C0076846F3D06E -:10FD7000F0E70720A4E730B50C46444995B0096880 -:10FD80008C4201D210209BE7203803000DF00CF8C4 -:10FD900005042121232132002088FFF782F8002862 -:10FDA00004D00078222803D2082089E7384887E762 -:10FDB0002521684601702188418009A905F0B9FA1A -:10FDC000050015D10AA905220231A01C0CF048FD3E -:10FDD0000EE006250CE02068002805D0884201D2FC -:10FDE000102505E001F0D9FC24480025808BA08077 -:10FDF000284665E7072063E720481330704710B5B1 -:10FE000020211E480CF089FD0120FEF7EFFF112094 -:10FE1000FFF705F800211948C94381800021817648 -:10FE2000E1218900818301460C300D310446FBF746 -:10FE300017FA12480722214613300CF011FDFFF784 -:10FE40000EF8002803D00B4912480CF094FE01F084 -:10FE500093F810BD10B504463C210CF05EFDA07F68 -:10FE600080088000A077202020700020A07520341A -:10FE7000607010BD58FA00008C050000341000209E -:10FE8000FFFF0000012A000000D001002001002037 -:10FE900002300000FB0600007047FEB50546FF4833 -:10FEA0000C46814207D301208004844205D3FC48DC -:10FEB0000068844201D21020FEBD002D02D0012D29 -:10FEC00032D126E0F74908220F4668460CF0C8FCFC -:10FED00039462046FFF777F90028EDD1FEF7BFFF3E -:10FEE000060006D00722694638460CF0B9FC3046B9 -:10FEF000FEBD2078002801D0012805D1E94807225D -:10FF00003946C01D0CF0ACFC00210920FCF7EDFBCC -:10FF10000FE00978002907D0012905D0022905D072 -:10FF2000032903D0E048FEBD0720FEBD0120FFF7F6 -:10FF3000E9F9DC480C3885760020FEBD10B5D849BB -:10FF40000968884201D2102093E7D64902460C394D -:10FF50000B7B0D311846FFF777F9002089E7FFB5D5 -:10FF600099B00546002069460871087208A908740E -:10FF700008751446CA480122C849920400681E4602 -:10FF8000002D05D08D420BD3954201D3854207D376 -:10FF9000002C08D08C4203D3944204D3844202D272 -:10FFA00010201DB0F0BD2846204318D01F270CABF1 -:10FFB00001AA009728461A99FFF79FF80028F0D168 -:10FFC0000DAB02AA314620460097FFF796F80028AD -:10FFD000E7D16846007AC10703D00A20E1E707208D -:10FFE000DFE7800705D568460079800701D50B203B -:10FFF000D7E703AF002D0FD01A20694608731A986F -:020000040001F9 -:1000000088732946F81C1A9A0CF02AFC0EA903A83A -:1000100005F08FF90028C4D1002C0ED020216846AD -:100020000173867332462146F81C0CF019FC0EA9A8 -:1000300003A805F07EF90028B3D19A4908A8007CEE -:100040000C3948700020ACE770B504460A202070D7 -:100050000D46204605F06DF9002805D139202070A5 -:100060002946204605F065F970BDF7B500260C4617 -:1000700005460B271AE02968B000095809780029BD -:1000800003D0012901D00720FEBDA17029680622F6 -:100090000958E01C491C0CF0E3FB2770204602992C -:1000A00005F047F90028EFD1761CF6B22879B04266 -:1000B000E1D800263A270FE0A868B1004158102285 -:1000C000A01C0CF0CDFB27702046029905F031F9F9 -:1000D0000028D9D1761CF6B2287BB042ECD800209B -:1000E000FEBDF0B5044671A003C897B06B4B002766 -:1000F000159114909C4211D369480125AD04026802 -:10010000AC4201D3944209D32078012809D1616817 -:10011000994203D3A94204D3914202D2102017B0CE -:10012000F0BD60490C390A78012A0CD18A88614BEC -:100130009A4203D0002806D0012804D08A7F1307F2 -:100140009B0F06D101E00820E9E7D30701D1910711 -:1001500001D51120E3E7218A574B0A46203A9A42FB -:1001600007D3012875D1002973D1628A002A70D182 -:1001700011E0022801D0032801D1A02969D3012868 -:1001800009D0484A0C3A5278D20704D0628A002A31 -:100190005FD0B42A5DD8002806D0012808D00228F4 -:1001A00004D0032855D117E0002518E0022516E0F9 -:1001B000002902D1608A00280CD0042560680078EC -:1001C00000280CD0012809D0022807D0032805D028 -:1001D0003548A4E70125F1E7032500E00127207A4F -:1001E000002806D0012806D0022806D003287CD19A -:1001F00005E0002604E0012602E0022600E00326D6 -:10020000002D01D0022D14D1002E12D0E068FEF78F -:1002100022FF002883D123480C384078800702D081 -:100220002148401E7BE7022D03D1022E5DD0032E14 -:100230005BD0182168460170218A4180218A818023 -:10024000857118480C38007B002803D001286FD135 -:1002500004E04AE000216846C17102E001206946DD -:10026000C8716846077221780930012937D0062104 -:100270000CF053FB69460E74207D8207C107D20F34 -:100280004007C90F5200C00F11438000014314A85A -:10029000405C6946C873002827D00FE000D00100F9 -:1002A0002001002040100020023200000706050453 -:1002B00003020100FFFF0000E13F000009A96846BA -:1002C00005F037F8002884D109A96846FFF7BCFE7D -:1002D0000028A7D1002D0AD0022D08D010E06168B7 -:1002E0000622491C0CF0BCFAC4E7072017E7002ED1 -:1002F00006D009AA6946E068FFF7B7FE002891D149 -:100300001B20694608700120887009A9684605F01D -:1003100010F8002886D108A840791B2819D12B0095 -:100320000CF042FD0504040707040A00032001E065 -:100330000FE00220FEF75AFD012D0CD0608A002844 -:1003400009D00022830011461046FCF729F9002845 -:1003500001D00320E3E60020E1E6F3B5032687B0F1 -:100360000D4600290AD0FA4885426FD30120800447 -:10037000854203D3F7480068854267D30798FEF7A4 -:1003800090FD040005D02078222804D2082009B06E -:10039000F0BDF148FBE7A07F8707BF0F002D05D018 -:1003A00029463846FEF722FE0600F0D139460027DE -:1003B000EA48012907D0022931D0E949E9480CF07F -:1003C000DAFB3046E3E7A27D2946012A02D0827F8C -:1003D000920701D51120DAE700291BD108216A46CE -:1003E000049711820592418904AADF4803F0FBFFBC -:1003F0000028CCD16846008A082801D00320C6E72F -:100400006846018801814188418181888181C18854 -:10041000C18102A9079804F065FD0646D1E7A17DD8 -:10042000022916D1807F800613D4002D04D0A07F2E -:1004300040070CD4002100E00121079804F093FD4F -:100440000600BED1A775002DBBD004E01AE011262E -:10045000B7E7002D16D02A4621460798FEF725FF5C -:1004600006461128ADD1A07F4007AAD42046082215 -:1004700029460E300CF0F4F9A07F04210843A07740 -:1004800000269EE7102082E770B50C460546FEF771 -:1004900008FD010004D022462846FEF7E6FE70BDA6 -:1004A000AD4870BD00B50146143195B0192901D28F -:1004B000810707D001461E3104D00A3102D007203F -:1004C00015B000BD312269460A70887009A96846D6 -:1004D00004F02FFFF4E701B582B0022069460880DE -:1004E0009E4802AB00896A46002103F0E5FD69469B -:1004F0000988022900D003200EBD1CB500210091FF -:1005000002216A461180934901900968884201D20C -:1005100010201CBD91480189934803F064FF69468F -:1005200009880229F5D003201CBDF0B50E46884984 -:1005300085B0174605468E4207D3864801229204AD -:100540000068964204D3864202D2102005B0F0BD66 -:100550001F2F01D90C20F9E7804C8D4226D39542FC -:1005600001D3854222D3E08803A903F056FD002879 -:10057000ECD1287869464873E08803A903F02EFD82 -:100580000028E3D1694600900878022108436946B3 -:100590000870497B090703D00821084369460870A1 -:1005A000E088694603F0B3FC0028CFD169468F800C -:1005B000E088334601AA002103F07EFD6946898860 -:1005C000B942C3D00320C1E71CB50C4600210091FD -:1005D0000191228869460A805E49019009680028D5 -:1005E00001D0884201D38C4201D210201CBD0028CA -:1005F00001D0002A09D059486A46C1885A4803F0F8 -:10060000F2FE6946098821801CBD0C201CBD10B576 -:100610000123FEF74DFC2CE4002310B51A461946C1 -:10062000FEF746FC25E430B505464A4895B000681B -:100630000C46814202D2102015B030BD2846FEF78C -:1006400030FC002807D00178222902D3807F800661 -:1006500003D40820F0E74048EEE713216846017014 -:10066000458009A904F065FE0028E5D108AA0A2101 -:1006700051567F2901D02170DEE70520DCE7F8B56F -:10068000012304461A46194604F050FF0746012389 -:100690001A460221204604F049FF064601231A4665 -:1006A0000421204604F042FF054601231A46032197 -:1006B000204604F03BFF0446002F03D128492B4875 -:1006C0000CF059FA002E04D1AD20254980000CF021 -:1006D00052FA002D04D125482149801C0CF04BFA18 -:1006E000002C04D121481E49C01C0CF044FA2221E0 -:1006F0003846FEF70EFC3846F8BD10B504460068D3 -:1007000000280CD01249884207D30121890488426D -:1007100005D310490968884201D2102014E401F081 -:100720002FF8A0880D4CA083A07E01280DD10021B8 -:100730000920FBF7B4FF002800D00120A17C890923 -:10074000012915D00321FEF7DDFD002006E400009D -:1007500000D00100200100200230000034100020F1 -:1007600058FA0000C6090000FFFF0000B3020000B5 -:100770000221E8E75A4910B5884207D301218904CC -:10078000884205D357490968884201D2102010BD1C -:1007900001460120FEF72AFC10BD30B5044693B097 -:1007A00000200D46079014210BA80CF0B8F81C216E -:1007B00068460CF0B4F86A46112010770020507794 -:1007C000107802210843107007A80C90012008AA95 -:1007D000907245486A4610850AA80B9020881084BC -:1007E00060885084A0889084E088D084907FF9212C -:1007F0000840801C400840009077082090861087B1 -:1008000008A80F9010AA0BA9684602F0C7FF00289D -:1008100003D110A800882880002013B030BD3EB559 -:1008200004460820694608802D48844207D30120E9 -:100830008004844205D32B480068844201D21020F2 -:100840003EBD21460120FEF7D1FB0028F8D12088CB -:10085000694688806088C880A0880881E0884881CF -:10086000FFF7A5F901AB6A46002103F025FC6946B4 -:1008700009880829E4D003203EBD1FB504460020A6 -:10088000029008206946088115480391844207D3E5 -:1008900001208004844206D312480068844202D2B8 -:1008A000102004B010BDFFF782F9014602AA0F48DC -:1008B00003F099FD0028F4D169460989082901D07F -:1008C0000320EEE7694609882180694649886180EE -:1008D00069468988A1806946C988E180E1E700000E -:1008E00000D0010020010020042A0000FFFF0000CA -:1008F00030B5F74B9A4207D301239B049A4205D3A4 -:10090000F44B1B689A4201D2102030BD1578EB06DB -:100910005B0F042B07D85478072C04D39378102B43 -:1009200001D8A34201D2072030BDD3785B0702D49F -:1009300013795B0701D5062030BDC37FAC075B0888 -:100940005B00E40F2343C3770878EF231840137844 -:100950009B06DB0F1B0118430870F1231840137826 -:10096000DB065B0F5B0018430870507808730020AB -:1009700030BD30B500240C70C378DB07DB0F0B7083 -:10098000C578AD07ED0F6D002B430B70C5786D0773 -:10099000ED0FAD002B430B7014700179C907C90F1F -:1009A000117003799B07DB0F5B001943117000790D -:1009B0004007C00F80000143117030BD70B5144670 -:1009C0000D460646FAF7CCFB002809D0A22101709B -:1009D000142221460830F0F703FCFAF7A2FB70BDA1 -:1009E000132229463046FEF740FC70BD70B5144610 -:1009F0000E460546FAF7B4FB002809D02221017003 -:100A000045802178017261784172FAF78AFB70BDE6 -:100A1000132231462846FEF728FC70BD10B5AE4CB7 -:100A2000207C00280CD1204621461038FEF7DAF849 -:100A3000002803D0A9A1F2200CF09DF80120207419 -:100A400010BD70B594B015460C462C226946189E10 -:100A50000A704880002B17D00822194601A80BF015 -:100A6000FFFE68468581102231460E300BF0F8FEFD -:100A700009A9684604F05DFC002803D1A17F10227B -:100A80001143A17714B070BD002001900290E8E7F7 -:100A9000F0B50646008A97B080B20D460190FEF789 -:100AA00000FA04468C48317848380746E837099000 -:100AB0000B000CF079F90EFCFB48085F8798B8D959 -:100AC000FAF9F8F7F6FC002301221946019804F020 -:100AD0002DFD050004D1FF2080A130300CF04BF833 -:100AE000002C04D1FF207DA131300CF044F8387E79 -:100AF000C00904D078486030C06DA86112E02B2096 -:100B0000694608720BA902A804F013FC002804D05F -:100B1000FF2072A13C300CF02EF874490C980BF0B9 -:100B200008FFA9617068A862B068E862A07F8007CA -:100B3000800F012820780DD0252804D0FF2067A140 -:100B40004D300CF018F8324621460198FFF736FF79 -:100B500017B0F0BD2528F6D0222806D0242804D0CE -:100B6000FF205EA146300CF006F825212046FEF756 -:100B7000D0F9E8E7002301221946019804F0D6FCD9 -:100B8000060004D1FF2055A158300BF0F4FF002CD3 -:100B900004D1FF2051A159300BF0EDFF207825281A -:100BA00004D03078012108433070D1E7022028704A -:100BB000B068A860B068002802D000202871C7E79C -:100BC0000120FBE72B2069460870434968464C39F1 -:100BD00004F0AFFB002804D0FF2040A178300BF0D8 -:100BE000CAFF03201BE02A206946087000A81022D3 -:100BF000023071680BF034FE04A810220230B16894 -:100C00000BF02EFE344968464C3904F092FB002864 -:100C100004D0FF2031A189300BF0ADFF04202870F3 -:100C20000998686094E7B068002804D1FF202BA1E0 -:100C300095300BF0A0FFE07F400704D5FF2027A1EF -:100C400096300BF098FFB06806220A38009033798E -:100C50000421019803F041FF0028A6D0FF201FA126 -:100C60009B300BF088FF73E7002C04D1FF201BA101 -:100C7000A3300BF080FF2046223010220546716819 -:100C80000BF0EEFD28212046FEF743F9A07F8007F8 -:100C9000800F022814D100231A462146009501989E -:100CA00006E04BE1BAE0B0E095E03FE071E05FE1E3 -:100CB000FFF7C7FE11281BD029212046FEF729F98E -:100CC000E07F317A4007400FC9000843E0773FE7F3 -:100CD00000D0010020010020001100207372635C2D -:100CE0006761705F7365632E6300000040420F0010 -:100CF000A07F000704D5FF20FD49B0300BF03BFF7B -:100D0000A07F08210843A077002060862046343069 -:100D10000BF003FEE07FFD220146C9071040890F5A -:100D20000843E077307A2034207011E70023012255 -:100D30001946019804F0FAFB040004D1FF20EC49A5 -:100D4000CD300BF018FF2B2069460872E94902A844 -:100D500004F0EFFA002804D0FF20E549D2300BF070 -:100D60000AFFE4488188204621300176090A41764D -:100D70000E2129702146FC316960017E2974407E74 -:100D80006874DC482C30A860103030346C61E86046 -:100D9000DEE6002C04D1FF20D549E6300BF0EBFE57 -:100DA0002078212893D93079012802D0022808D14F -:100DB00003E0E07F04210843E077387E0121084307 -:100DC0003876324621460198FFF7F8FD2321204668 -:100DD000FEF79FF8BCE601220421019804F065F9B2 -:100DE0000028A2D0002301221946019804F09EFB9E -:100DF000040003D1BE49C0480BF0BDFE0F2028708F -:100E0000172028716E34AC60A2E60421019804F02A -:100E10009CF9002889D11020287099E6002301222E -:100E20001946019804F082FB050004D18720B049DF -:100E300080000BF0A0FE2E462036307E41064DD5B8 -:100E4000A17F8F07BF0FC00713D029468031486F9D -:100E500000280ED0027CF37DD207D20F5B001A432C -:100E60000274486F5108E27F4900D207D20F114344 -:100E70000174307E000713D52A468032116F002995 -:100E80000ED0087CF37DC007C00F5B0018430874C8 -:100E9000116FE27F40084000D207D20F1043087460 -:100EA000307E80070BD5F8204259002A07D0012F49 -:100EB00005D02946307C31311032FEF7C5F9307E3D -:100EC000C0060BD5F8204259002A07D0012F05D1C2 -:100ED0002946307C31311032FEF7B6F905236846D9 -:100EE0000370357E4570834822216038019A017075 -:100EF0004178C908C900C91C41704280037245721B -:100F0000FAF796FA2078252809D021280BD07A48BC -:100F100077495B300BF02FFE2078222803D922215D -:100F20002046FDF7F6FF0021019804F037FB00286A -:100F300000D10DE670486E49633092E674686D4DDD -:100F400020786035092802D00A28F2D10BE0E16848 -:100F5000002902D0284604F0BEF92169002902D0F8 -:100F6000284604F0B8F92146284604F0B4F9EFE524 -:100F700061485F49883074E65E4810B50422282134 -:100F8000603004F08FF95B480024EC30017E4906A4 -:100F9000490E01764038C465FDF7B1FD55493C3135 -:100FA00008461038FAF793F952484C30047410BDD3 -:100FB00070B50D46FDF775FF040004D14E484C494D -:100FC000A7300BF0D8FDFF21053128460BF0A7FC18 -:100FD000A07F8007800F01280CD00221284688308E -:100FE000FDF78EFD002804D043484149AC300BF09A -:100FF000C2FD70BD0121F1E70A46014610B5104659 -:101000008830FDF797FD10BD70B5054611200C46E0 -:101010000870002161702121495D002908D0032951 -:101020000ED0042910D034483149C6300BF0A3FD4E -:1010300020780009012802D9E87FC008607070BDDF -:101040000007000F203002E00007000F3030207052 -:10105000EEE7F0B504464068082601789BB0082901 -:101060000DD00B2903D00C294BD10121817160686F -:1010700087883846FDF715FF05004CD147E04788C3 -:101080003846FDF70EFF050004D11720184940012E -:101090000BF071FD2878212833D0282833D16068DF -:1010A00002210C3000F050FF00282CD0606808218D -:1010B000001D00F049FF002825D02D216846017051 -:1010C000478029461022223101A80BF0C9FB0FA945 -:1010D000684604F02EF9002804D007480449EF3090 -:1010E0000BF049FDA87F10210843A877292105E0CE -:1010F000DC0C0100B4100020030200002846FDF7BC -:1011000008FF1BB0F0BD607830436070F9E7FE491E -:10111000FE480BF030FDA87FEF210840A877297822 -:1011200021290FD061688A79002A02D089780029A4 -:1011300012D08007800F022849D0F448F249343099 -:101140000BF019FDFEF720F90028DAD0EF48EE4940 -:101150003F300BF010FDD4E7607830436070E87FDB -:10116000C00701D0042100E0032121204155287847 -:1011700029280BD039460620FBF7B7FA287824280F -:10118000E0D122212846FDF7C4FEDBE7002301223F -:101190001946384604F0CAF9040004D1C920DA49D6 -:1011A00080000BF0E8FC25212846FDF7B2FE0D205B -:1011B00008A90871204609A98830FDF7ADFC02286E -:1011C000C0D00028BED0D148CF491D30B8E76078E4 -:1011D00030436070B6E7F7B58AB015460646FDF7AE -:1011E00060FE002841D0017822293ED323293CD03B -:1011F000C17F490739D4807F8007800F01280DD037 -:10120000002301220021304604F090F90746C0482F -:10121000029004F057F8040007D101E00123F0E741 -:10122000BA48B94959300BF0A6FC002F1FD08837B7 -:101230006761029804F046F80746029804F042F805 -:1012400009212170266225710B99E760A160206158 -:1012500003A92046FDF784FC022806D0002804D00C -:10126000AA48A94975300BF086FC0DB0F0BD0020EE -:1012700007466061E4E730B5002387B005460122E8 -:10128000194604F053F904462846FDF70AFE007893 -:1012900022281BD9002C04D19C489B4981300BF09B -:1012A0006AFC0F21684601701721017120466E30DB -:1012B000029069461A30FDF72FFC022806D000285C -:1012C00004D0E520904980000BF055FC07B030BDFC -:1012D00030B5002387B005460122194604F026F9EF -:1012E00004462846FDF7DDFD00782228EED9002CC3 -:1012F00004D18648844993300BF03DFC10206946A8 -:10130000087020468830FDF707FC0028DED0E92071 -:101310007D4980000BF02FFCD8E7F7B50546007833 -:101320000027000982B00C463E4602287ED00728DE -:1013300002D00A284AD14AE068680178082907D013 -:101340000B2930D00C292ED070486F49D33060E182 -:1013500014271A26002C6AD04088A080FDF7A1FD32 -:101360000090002804D169486749AF300BF003FCB6 -:1013700000980099C07DA21D1831FDF765FF6868CF -:1013800008228089E081696820461030091D0BF031 -:1013900067FA207E01210843F92108402076009851 -:1013A0004021807F47E018270826002CD3D0808872 -:1013B000A080FDF776FD050004D1F720524980009A -:1013C0000BF0D9FBA11D2846FFF71EFE23E1002CE0 -:1013D00001D0288BA080287A01287DD0022804D053 -:1013E00003282FD048494B4813E11C270726002C1F -:1013F000B1D0A088FDF755FD0090002804D1FD2054 -:10140000414980000BF0B7FB287B8007800F012843 -:10141000A07914D040084000A071FD210840297B2C -:101420004907C90F49000843A07101E0E3E0DFE08C -:1014300000988021807F084300998877EBE00121A4 -:101440000843E9E713270B26002C84D0A088FDF77A -:1014500028FD00900023A0880122194604F066F8B8 -:1014600005460098002804D12A48274960380BF027 -:1014700082FB002D04D181202349C0000BF07BFBAF -:101480000098807F8007800F012859D0E86A817812 -:101490008907890F0129A17954D049084900A17110 -:1014A0008278FD255207D20F294052001143A171C5 -:1014B000E322114002785207D20E1143A171DF22BC -:1014C00011404278D207920E1143A1710021E171BF -:1014D000C1782172427900E037E00179607AD30760 -:1014E00040084000DB0F18439307DB0F28405B00E8 -:1014F00018435207FB23D20F18409200104360722A -:10150000A07A4008400007E0DC0C01000E03000058 -:101510001411002067040000CA07D20F10438A0785 -:10152000D20F2840520049071043C90F18408900C4 -:101530000843A0720098007823286CD92621AFE0D8 -:10154000A86AA4E701221143A9E7297BFE480229E2 -:1015500010D017270C26002C4AD0012911D00329BE -:101560001ED004291FD005291DD0F849F8480BF0DA -:1015700002FB23E019270726002C4CD00121A17182 -:1015800005E00121A171E17989088900E171017EFD -:10159000CA094906D201890E49000A4302760DE0C4 -:1015A0000220A07106E0687B0007000F8030A07168 -:1015B000052918D0E07980088000E071A088FDF747 -:1015C00070FC05460078212825D0232804D0E04867 -:1015D000DE490C300BF0CFFAA088002103F0DEFFCB -:1015E000222128465DE0E07980088000401CE4E785 -:1015F0000498068015E0002C01D06888A080287A25 -:10160000032828D004280FD005284DD0D048CF4932 -:1016100064300BF0B0FA0498002C068001D02780CB -:101620006680002005B0F0BD15270C26002CDFD009 -:101630000023A0880122194603F078FF050004D199 -:10164000C348C2492A300BF096FA0622A11DA869A8 -:1016500006F01CFBDFE716270726002CC8D0A08861 -:10166000FDF71FFC00900023A0880122194603F01B -:101670005DFF05460098002801D0002D04D1B44834 -:10168000B24938300BF077FA2878C00601D502202D -:1016900000E00120A071009800782328BBD9272101 -:1016A0000098FDF736FCB6E717270C26002C9FD0D4 -:1016B000A088FDF7F6FB00906D7A002804D1A448BD -:1016C000A2494B300BF057FA0621A01D0BF025F96B -:1016D0000020A071207A032108432072FB210840DA -:1016E0000099C97FC907490F08432072680692D53F -:1016F000E07904210843E071A07AE907400840003E -:10170000C90F0843E17A2A0749084900D20F11435B -:10171000FD22AB07DB0F10405B001843A072E80608 -:10172000C00F114040000143E17274E710B5044658 -:10173000807990B08009012804D04D2083490001B0 -:101740000BF019FAFFF76AF90120694608707E4824 -:101750000AA9A0380190201D0290601C0B906846D9 -:10176000FDF7FEF9002804D07948784987300BF05E -:1017700002FA0322601C0B990BF072F810B010BD36 -:1017800010B5714CA03C002805D00146102220461F -:101790000BF066F80120207410BD10B50446FFF769 -:1017A0003DF969491022A03920460BF059F810BDC7 -:1017B00070B50025644C00281CD06649884207D3C8 -:1017C00001218904884205D363490968884201D20E -:1017D00010250DE0062106F043FA411C07D05A49B6 -:1017E0004039C865207E80210843207600E0072527 -:1017F000284670BD207E4006400EF6E7F3B5002077 -:1018000089B00D46029000290AD0524885421CD367 -:1018100001208004854203D34F480068854214D3D9 -:101820000998FDF73EFB060003D03078222815D139 -:1018300002E04A480BB0F0BD002D08D1B07FC109CD -:1018400003D08007800F022801D01020F2E7B07F7C -:10185000C10601D4000703D5002D01D00820E9E717 -:101860003948007EC00712D1F07F400701D50D2016 -:10187000E0E7002201231146099803F057FE070014 -:1018800005D0B07F8007800F022802D00BE0112026 -:10189000D0E7002D07D02A4639463046FFF728F812 -:1018A00002900028C6D128488C3803F00BFD0400B4 -:1018B00003D126492A480BF05EF90A2020700998C6 -:1018C000206238468830A060B07FFB218007800FFF -:1018D000012829D0002D4CD002202071381DE06055 -:1018E00038780007400F20743878C006C00F607445 -:1018F000A07C2A788008D2078000D20F1043A07401 -:101900000840F17F01AAC907490F0843A074A878CD -:10191000E07469462846FFF72CF868460079207580 -:1019200068460078607528E001202071207B2A78C5 -:101930008008D2078000D20F104320730840297816 -:101940008907C90F89000DE0A0110020DC0C0100FF -:101950005304000000D001002001002002300000EC -:10196000630500000843207324213046FDF7D1FAB7 -:101970000BE0032020710520207325213046FDF760 -:10198000C8FAB07F4006400EB07703A92046FDF7A5 -:10199000E7F8022805D0002803D0FD49FD480BF0E8 -:1019A000EAF8029846E7FFB581B00A9D06461C4654 -:1019B0001746142128460AF0B2FF0B980021016057 -:1019C000F8070ED0F44920680968884239D31230EC -:1019D00028602068143068602068A8600B9821682F -:1019E0000160B80726D56068002803D0EA49096875 -:1019F000884226D3029900290AD0FC3600280ED04E -:101A000031461030FDF7DFFB00281BD1606810E085 -:101A1000002816D0E86080366068B0670AE0FEF7FC -:101A2000EBF90146072230460AF01AFFFEF7F6FFEF -:101A3000DA48E860780707D5D749A068096888427E -:101A400001D21020EEE528610020EBE5FFB5D44A75 -:101A50000E4607CA97B002AB07C30027009701974D -:101A60001798FDF71EFA050005D02878262804D01F -:101A700008201BB0F0BDCB48FBE700231A461946EF -:101A8000179803F053FD040004D1C248C0498030C8 -:101A90000BF071F8A87F8007800F1690012814D0F2 -:101AA000022824D0BB48BA4999300BF064F80121D0 -:101AB0000022852E31D01EDC002E26D0812E26D08D -:101AC000822E26D0832E1ED125E0002EEFD1214676 -:101AD0002846199AFEF70CFF0028CAD11998807879 -:101AE000009019980078C007C00F0190DFE719989F -:101AF000002808D1DBE7862E11D0882E11D0892E40 -:101B000011D08A2E11D00720B3E710460EE0084608 -:101B10000CE002200AE0032008E0052006E0062091 -:101B200004E0082002E0092000E00A2000222271DF -:101B300001216A461176211D0791002801D02071EC -:101B4000FAE0169801280CD0A66AE06A0222012168 -:101B500010900020A0602846173002291AD00121D9 -:101B600019E0E66AA06A1090032030702078FB2309 -:101B7000C006C00F7070B07801221840009BF3704F -:101B80008008019B800018430221B0700020707112 -:101B90003071DEE70021890009190861681C022AFA -:101BA00001D0012100E00021890009190861B07805 -:101BB0008007800F01285ED1109880788007800F01 -:101BC000012858D1109800798446109840790090E7 -:101BD000169801281DD0317908A801747179017512 -:101BE00008A8027C6046024008A8007D00990840D1 -:101BF000139010433FD06C491A98884207D30121B3 -:101C00008904884215D364490968884211D210209A -:101C10002FE70CAA0DA91998FEF7ABFE08A8007CC7 -:101C200061460840307108A8007D00990840707135 -:101C3000D6E720463C3021460090F03116980191BD -:101C4000022834D000211A9B20460C33FFF7ABFE4C -:101C50000028DDD12046503021460090F4311698FE -:101C60000191012825D0002120461A9B139AFFF7E5 -:101C70009AFE0028CCD110988078400702D4E87FE3 -:101C8000C0072BD0169902A8012914D01099097801 -:101C90004900405A21780907490F4900C840870781 -:101CA000BF0F2AD0012F14D0022F0FD113E0012132 -:101CB000C9E70121D8E721780907490F4900405AAF -:101CC000109909784900C8408707BF0F032F04D037 -:101CD00004E0022711E001270FE0022716980128EF -:101CE0000BD1B078FB210840E97FC907490F0843B1 -:101CF000B07020780007400F307020781022400824 -:101D0000400020701099D2434978C907C90E114389 -:101D100008402070C00623D4022F21D0012F21D0EB -:101D20000020A061E0612062606220461830A0605F -:101D3000E87F40084000E877204606A98830FCF795 -:101D4000EBFE002806D0022804D06F2010490001C5 -:101D50000AF011FF25212846FDF7DBF8002088E670 -:101D6000032008E020460D211B300AF0D6FD204656 -:101D70001830A060042069460875E87F01210843F7 -:101D8000E87705AA29461798FEF730FED4E7000049 -:101D9000DC0C01008E050000200100200011002055 -:101DA00050CF01000230000000D00100F0B587B034 -:101DB00015460E0004460DD06A48854207D301201F -:101DC0008004854206D368480068854202D210200C -:101DD00007B0F0BD2046FDF764F8070004D038785E -:101DE000272803D00820F3E76048F1E700231A46CC -:101DF0001946204603F09AFB040003D15C495D4874 -:101E00000AF0B9FE0020002E05D0022E08D0012EC7 -:101E100011D00720DCE701216A461171A06018E0AB -:101E2000234618336946A3600871102229461846D4 -:101E30000AF016FD0DE021461831A16069460871CF -:101E4000A061E061206260620621284605F008FF7B -:101E5000A0612078C10714D0400840002070022003 -:101E6000694608702046183002907030FCF754FE26 -:101E7000022806D0002804D03E483D4923300AF00D -:101E80007AFE25213846FDF744F80020A0E770B51A -:101E900094B00D460646002B02D0072014B070BD4A -:101EA000FCF7FFFF040007D02078222802D3A07F90 -:101EB000400603D40820F1E72C48EFE7002D19D0A5 -:101EC0002D216846017046801022294601A80AF09B -:101ED000C7FCE07F297C4008C9074000C90F0843C0 -:101EE000E077297C40078906400FC90EC9000843E6 -:101EF000E07703E02E2168460170468009A9684614 -:101F000003F017FA694609782D2905D1002803D175 -:101F1000A17F10221143A177A17FBF221140A17799 -:101F2000BCE710B50C46FCF7BCFF002805D00E49F5 -:101F300009688C4203D2102010BD0C4810BD214608 -:101F4000FFF762F8002010BD05E00278401C002A6F -:101F500001D0002070470A46491E89B2002AF4D1F8 -:101F60000120704700D00100200100200230000055 -:101F7000DC0C01000F070000F8B500780C4616468F -:101F800010340E36069F022809D0032836D00528C3 -:101F90007ED0FF20F6A1E5300AF0EDFDF8BDCD8939 -:101FA0000A2068430E30188031203880002AF5D08E -:101FB000087B9581801FC7B21AE020886168308055 -:101FC00048780A7800021043F080C8788A780002C6 -:101FD00010433081B21C3846091DFCF7B0FE002FBB -:101FE00001D0002802D000203071708008340A36F9 -:101FF00028466D1EADB20028DFD1F8BDCD890A207C -:1020000068430E30188032203880002AF5D0087BD3 -:102010009581401FC7B243E0616822880878F2804A -:102020003279C30752085200DB0F1A43FD231A40CE -:102030008307DB0F5B001A43FB231A404307DB0FC8 -:102040009B001A43F7231A400307DB0FDB001A43F8 -:10205000EF231A40C306DB0F1B011A43DF231A408C -:102060008306DB0F5B011A43BF231A404306DB0FD5 -:102070009B011A433271C00970718A784B78100243 -:102080001843308132463846C91CFCF758FE00E040 -:102090000CE0002802D00020B070308008340A36EE -:1020A00028466D1EADB20028B6D1F8BD087BCD899B -:1020B000801E86B2304608306843103018803420C5 -:1020C0003880002AF1D0174695811037E800D68174 -:1020D000C01900900DE02088388000987860324662 -:1020E000616800980AF0BCFB009808348019083732 -:1020F000009028466D1EADB20028ECD1F8BDFFB5AA -:1021000081B00A9D1E460C46002A05D0607AFF3039 -:102110000130D080E089108101980E2700780300FB -:102120000AF042FE0B7E0719293541536C78787806 -:102130007E000092087B082805D0032803D091A1D7 -:1021400095480AF018FD378030200FE000990020F4 -:10215000888105B0F0BD0092087B042804D08E4829 -:1021600088A114300AF007FD3780312028800098BC -:102170000028EBD1EDE70092087B042804D09320DF -:1021800080A180000AF0F7FC37803220EEE7009251 -:10219000087B022804D080487AA13A300AF0EBFC90 -:1021A00037803320E2E7087B1746042804D07A48BA -:1021B00074A14C300AF0DFFC1020308034202880DD -:1021C000002FC6D00020B88116E0207B17460528D6 -:1021D00006D0062804D070486AA160300AF0CBFC13 -:1021E0001220308035202880002FB2D0E089B881BD -:1021F0000020388201984088F881AAE70092087B85 -:10220000072804D064485FA171300AF0B4FC37801D -:102210003620ABE733460095019800F00EFC98E7B6 -:102220002F2053A100010AF0A6FC92E770B50C46DE -:102230000546FCF736FE002804D00078222803D299 -:10224000082070BD554870BD00231A460421284659 -:1022500003F06CF92060002801D0002070BD03203D -:1022600070BDFFB58BB00D4607461720694608853F -:102270000E9803261446002805D10EA93846FFF70C -:10228000D5FF002834D1002D0BD000220321384681 -:1022900002F00BFF002834D00E980078002830D1CF -:1022A00008E02078092819D00F2823D030A13C4815 -:1022B0000AF061FC0E98A760801D03AA60600232DC -:1022C0000AA92046FAF78DFB002827D003000AF060 -:1022D0006BFD071A182323211C1E2300072600224A -:1022E0003146384602F0E1FE0028E3D12B48801C3D -:1022F0000FB0F0BD00220321384602F0D6FE0028C0 -:10230000D8D11120F4E70020F2E70820F0E72348B5 -:10231000401CEDE70720EBE70320E9E701A8009068 -:102320006846038D04223146384602F0D6FB002869 -:10233000DED1002DDCD00E990D70D9E730B587B015 -:102340001D460C46002A11D0042369460B701388E1 -:102350008B815288CA81A2788A7422880A820023DB -:102360006A462946FFF77DFF07B030BD1020FBE726 -:102370007372635C67617474635F636F72652E630D -:10238000000000007372635C67617474635F636F65 -:1023900072652E630000000025020000023000007C -:1023A0004F030000F3B581B001980C460078082671 -:1023B00003000AF0F9FC125F47471B134B0A0A0A95 -:1023C0000A0A0A0A0A0A0A0A0A5F002C02D1F84914 -:1023D000F84808E06078304360703CE0002CF9D1A8 -:1023E000F448F34908300AF0C6FBF3E701980023EC -:1023F0008088012287B20421384603F097F8054609 -:10240000002C04D07520EA49C0000AF0B4FB002D6E -:1024100004D1E848E64914300AF0ADFB3946A81D5E -:10242000FAF7D6FAF8F79CFE040006D0607830433D -:1024300060706780F8F775FE0FE013213846FEF7ED -:1024400023F815E0DB48DA49283002E0D948D849BA -:102450002D300AF090FB002C0AD06078000707D5D9 -:10246000932020702046582208300199EEF7B8FEDC -:102470000020FEBDCF48CE493130EAE710B500213B -:102480000170801DFAF7A1FA10BD0A4610B5014689 -:10249000901DFAF7A5FA10BD70B5002305461A463F -:1024A000042103F043F8040004D1F920C04980005E -:1024B0000AF061FB2946A01DFAF78AFA70BDF7B54C -:1024C000054684B00C4600206946088188806F88E4 -:1024D000034601220421384603F028F8060004D1FF -:1024E000FD20B34980000AF046FB002C03D0A780F2 -:1024F0000020E0802081297A20461230C91E14274E -:1025000000900B000AF050FC0FFEFDFC3809A95E9C -:10251000657A2FB2C9E99191FC003078012804D086 -:10252000A349702014310AF026FBA9896A46C80025 -:102530000E30908030201081002C13D0A18100201B -:102540000DE0C100327909190A747288CA818200CB -:102550005319DA894A821A8A401C8A8280B2A18978 -:102560008142EED8F1E002A8009001AB2246294654 -:10257000304600F02BFAE8E03078042804D08C498B -:10258000BD2014310AF0F7FAA8890622014650430B -:102590006A460E30908033201081002CE2D0A18159 -:1025A00000200BE0062141434F190919FA89CA811D -:1025B000BA7C8A743A8A401C0A8280B2A18981421C -:1025C000F0D8C2E0307806280BD079491431D720F2 -:1025D00005E03078062804D07549EB2014310AF064 -:1025E000CAFAE88969461230888035200881002CB3 -:1025F000B8D0A989A1817188E18126E030780728C7 -:1026000004D06B49FF2014310AF0B5FAA8896A4654 -:1026100001460E30908036201081002CA2D0A1817E -:102620002046AA890E30296954E0E88969461230AB -:1026300080B2382288800A81002C7ED0A989A181AD -:10264000287A102807D00221A173E9892182EA891A -:10265000296900983EE00121F6E702A8009001AB4D -:10266000224629463046FFF787FC6EE0307808287E -:1026700005D04F49FF201431EE300AF07CFA68464D -:10268000372187800181002C5FD0A989A18100209A -:10269000608220820120A07357E03078092805D09D -:1026A0004349FF201431FF300AF065FA288A694651 -:1026B0001430888037200881002C46D00421A17373 -:1026C000A989A181E9892182298A618220462A8AF1 -:1026D000143069690AF0C4F837E030780A2804D069 -:1026E0003349354814310AF046FA68463721878065 -:1026F0000181002C29D00521A1730020A08102E0D6 -:102700001EE003E00CE0208260821EE002A8009040 -:1027100001AB224629463046FFF7F1FC15E00CE0FC -:102720000D206946392288800A81002C05D00120BD -:10273000E08000202081207307E00699088019E0DE -:102740001C481B49A4300AF016FA6846069980888E -:102750000880002C0ED0684600892080684680885A -:102760006080287A032805D0102803D0112801D0D2 -:1027700000203070002007B0F0BDF7B55688154630 -:102780000F46002382B01A460421304602F0CEFEE6 -:10279000040004D107480649C4300AF0ECF9A41D2E -:1027A00033462A46394600940298FAF7A0FAD0E454 -:1027B000702301009503000013020000F7B58CB0F0 -:1027C0000D46144607A90C98FFF730FD002812D1DA -:1027D000B64E0127002C0FD003216846017010214E -:1027E000818208A802460690204605A9FCF7CDFA8A -:1027F00000280BD007207BE5082168460170858101 -:10280000C68105218774C90201820BE00798A1786F -:10281000017121884180684605218774C9020182BF -:102820008581C68102460121079B0C98FFF719FD9F -:102830005EE508B501236A4693709D4B13800A46F6 -:1028400002236946FFF77AFD08BD08B501236A46F1 -:102850009370974B5B1C13800A4603236946FFF76E -:102860006DFD08BD00B587B000290CD002236A4673 -:1028700013700B8893814988D18100230421FFF7CD -:10288000F0FC07B000BD1020FBE710B5002903D015 -:102890000523FFF753FD10BD072010BD70B588B0AC -:1028A0000D461446064607A9FFF7C0FC00280DD1C7 -:1028B000002C0DD00621684601708581C481079BDC -:1028C00002465C8006213046FFF7CBFC08B070BDA5 -:1028D0000521684601708581F1E710B588B00029AF -:1028E0000BD007246B461C709A81049100236A4622 -:1028F0002146FFF7B6FC08B010BD1020FBE770B50D -:102900000024172288B0002914D00D782B000AF07B -:102910004BFA0623050519041B231522D21E93B278 -:10292000CA88002A02D08E68002E03D09A4203D9AA -:102930000C20CBE71020C9E7042D05D08A88002A97 -:102940000AD101E00620C1E7012D11D0022D05D0EA -:10295000042D18D0052D23D00720B7E709236A4698 -:1029600013704B889381CB88D381896804911DE0D3 -:102970000C236A4613704B889381CB88D381896876 -:102980000824049112E00D236A4613704B8893814A -:102990008B88D381CB88138289680924059105E04F -:1029A0000E236A461370497811730A2400232146C6 -:1029B000FFF757FC8AE700B587B00F236A4613700C -:1029C000918100231946FFF74CFC5AE7FEB50078C9 -:1029D000089D1C4616460F46012803D03549912014 -:1029E0000AF0C9F8F889C0000E3020803020288015 -:1029F000387B001FC0B20190002E1DD0F889B08135 -:102A0000002516E0E8008419C019009022464169AB -:102A10000E320198FCF793F9002802D000202074B0 -:102A2000E08100986D1C008A60820098ADB2408AF7 -:102A3000A082B089A842E5D8FEBD70B51446142521 -:102A4000049A1D8037231380002C0ED0CA89A281DE -:102A5000002262820078082808D0092810D00A28AD -:102A600019D0144914480AF086F870BD087B0C2868 -:102A700004D011480F490C380AF07DF8012008E015 -:102A8000087B0D2804D00C480A4908380AF073F86E -:102A90000420A07370BD087B0E2804D006480549A9 -:102AA000001F0AF068F80520F3E70000FFFF0000B0 -:102AB0000228000084230100BB020000002803D08C -:102AC0008178012939D101E0102070470188FE4A40 -:102AD000881A914233D01BDCFC4A881A91422ED0CE -:102AE0000BDC00292BD00320C002081A27D00128B4 -:102AF00025D001210903401A07E001281FD0022830 -:102B00001DD0FF281BD0FF380138002815D116E052 -:102B1000FF220132811A904211D008DC01280ED028 -:102B200002280CD0FE280AD0FF2806D107E0012990 -:102B300005D0022903D0032901D0002070470F20BF -:102B4000704700B50B2826D009DC03000AF02CF9E9 -:102B50000B1D2125251B25292325271F1B00112897 -:102B60001BD008DC0C2816D00D281CD00F2814D040 -:102B7000102808D10FE0822809D084280FD085289A -:102B80000FD0872811D0032000BD002000BD0520F4 -:102B900000BDCF4800BD072000BD0F2000BD0420B0 -:102BA00000BD062000BD0C2000BD0D20800200BD30 -:102BB00070B500290BD0CB1FFA3B81241E46CDB245 -:102BC000112B1BD2012805D0022806D009E00020D5 -:102BD00010701DE0FF20043001E0FF20033081422F -:102BE00018D033000AF0E0F8111613131613161656 -:102BF0001316161613131313161316000846FF3870 -:102C000081381F2803D9FF39FE39022902D81570EF -:102C1000002070BD1470072070BD00B503000AF0DD -:102C2000C3F8060406040C080A0C002000BD11209D -:102C300000BD072000BD082000BD032000BD0078B6 -:102C40000207120F04D0012A05D0022A0AD10EE091 -:102C5000000907D108E00009012805D0022803D0A7 -:102C6000032801D007207047087000207047062015 -:102C70007047002807D0012807D0022807D0032872 -:102C800007D007207047002004E0112002E0212037 -:102C900000E0312008700020704738B50C46050070 -:102CA0004FD06946FFF7CBFF002822D120880321AF -:102CB00089028843694609788907090D08432080FD -:102CC0006946681CFFF7BBFF002812D1218803204A -:102CD00000038143684600788007800C014321800F -:102CE000A8784007820F2020012A03D0022A03D0AF -:102CF000072038BD814300E00143218088B20105EF -:102D0000890F08D0012189038843A9780907C90FD1 -:102D100089030843208080B28104890F0AD0A978F2 -:102D20004004C906C90F400CC90308432080800431 -:102D3000800F02D12088400403D520884021084319 -:102D40002080002038BD70B504460020088015465C -:102D50006068FFF7A2FF002815D12189A089814270 -:102D600010D861688978C90708D0012149028842D2 -:102D700008D8491C09F0DDFD298009E0FF21FF3159 -:102D8000884201D90C2070BDFF30FF30033028800D -:102D9000002070BD10B5137804785B08E4075B0071 -:102DA000E40F23431370FD2423400478A407E40FA9 -:102DB000640023431370FB24234004786407E40F6A -:102DC000A40023431370F724234004782407E40F5E -:102DD000E40023431370EF2423400478E406E40F57 -:102DE000240123431370DF2423400478A406E40F56 -:102DF0006401234313700078BF244006C00F2340B2 -:102E0000800103431370002906D00878C10701D15F -:102E1000800701D5012000E00020C0015906490EBD -:102E20000843107010BD30B50A8803239B02048844 -:102E30009A4323059D0F02D1A3049C0F01D09B0F41 -:102E400000E001239B021A4303230A801B039A43D9 -:102E500003889804840F02D11805830F01D0800FD6 -:102E600000E00120000302430A8030BDF3B593B0B7 -:102E70000D000FD0139800280FD01221284609F01A -:102E80004CFD03AAFF210120FAF71FFB0024264670 -:102E900037467AE0102015B0F0BD0720FBE7684602 -:102EA000807D01280BD16846818A0520C002081A5E -:102EB00010D0012810D0022812D0032812D0042CE0 -:102EC00014D0052C15D113E00229000001280000C0 -:102ED00003300000012400E002246846468A08E02E -:102EE000032406E068460424478A02E0052400E043 -:102EF00006246846418A1398814246D12C74002EDC -:102F000041D00DAA0EA90520029201910090102334 -:102F10000022FF213046FAF779FB002823D16846CA -:102F2000808E2A46C0B20EA9FBF709FF00281AD1ED -:102F3000AE81002F27D00DA9052008AE0291009088 -:102F4000132300220196FF213846FAF75FFB002881 -:102F500009D16846808EF11CC01EC0B22A1DFBF745 -:102F6000EEFE002801D0032095E708A8817842787A -:102F700008021043E881062C05D16846807DA872BE -:102F80006846808A2881002085E703A8FAF7A6FA18 -:102F9000002884D0FFF7D5FD7DE7002805D0F94A49 -:102FA000012903D0022903D003207047518800E093 -:102FB0009188814201D1002070470720704770B589 -:102FC0000C4605461C21204609F0A7FC0020208065 -:102FD000002D08D0012D04D0EBA1F04809F0CBFD65 -:102FE00070BD062000E00520A07070BD70B592B0E5 -:102FF0001546064601206A4610711074537408463F -:1030000008300395029048889082F8F7A9F80400E8 -:1030100019D06580172069468883203600940AAB52 -:103020007178023307AA01A804F069FB06466078AC -:10303000000701D5F8F775F8002E0AD03046FFF7E3 -:10304000ECFD12B070BD13212846FDF71DFA0320D8 -:10305000F7E708A800906846838B042201212846E0 -:1030600001F03BFDEDE770B506468AB000200D4645 -:1030700007900590069003A904900524024602914A -:1030800001901023009429463046FAF7BFFA002831 -:103090000DD108A804A90091029001946846838983 -:1030A000002229463046FAF7CDF8002801D0FFF774 -:1030B00048FD0AB070BD10B504F027FD10BDF0B595 -:1030C00089B000260546059600780C4608270300BF -:1030D00009F06AFE0CFD070C3A0B77779EC2FCD80C -:1030E000E8FD68680A38F8F7B0F90DE1A888002310 -:1030F00080B201220321009002F018FA0290002C05 -:1031000004D0A648A0A16E3009F035FD0298002831 -:1031100004D1A2489CA16F3009F02DFD02980099BE -:10312000083003F021FFF8F71BF8040007D060789F -:103130003843607000986080F7F7F3FFE6E01321F2 -:103140000098FDF7A1F9EFE0002C04D1BD208EA17D -:10315000800009F010FD608800230122032102F0A5 -:10316000E5F90090002804D18C4887A1883009F047 -:1031700002FD0099002008802A7994461EE0C300D1 -:103180005B199B6807936B469B8B1A0708D5DA0679 -:1031900006D56046C20050194038C08F088006E04E -:1031A0005B0409D50871C2005019C0884880607856 -:1031B000384360700226A7E0401CC0B28445DED8C8 -:1031C000A2E0E888694608800090002C04D173488A -:1031D0006DA1983009F0CFFC2878062814D100980A -:1031E000C00B11D0608800230122032102F09EF958 -:1031F000060004D1694864A1A23009F0BCFC00209B -:103200003071A88870803BE06078384360707BE064 -:10321000002C04D161485CA1B43009F0ACFC60889A -:1032200000230122032102F081F90090002804D13B -:103230005A4855A1B73009F09EFC0098083004F0B8 -:10324000B6FC0121484002D1E888C00B5CD0009850 -:1032500061880226C180D7E7002C04D14F484AA1DB -:10326000D03009F088FC608800230122032102F09D -:103270005DF9002804D1494843A1D33009F07BFC13 -:103280000226C1E7002C04D144483FA1DC3009F0FC -:1032900072FC0226618801222046F8F7E7F8012037 -:1032A0000590B1E7A889002380B201220321009094 -:1032B00002F03CF90746002C04D0384832A1EE3029 -:1032C00009F059FC002F07D12FA101E00FE016E013 -:1032D0003248EF3009F04FFC68680290288969464F -:1032E0008881012202A90098F8F7DCF80CE0002C94 -:1032F0008AD16D2024A1C00009F03DFC84E7274855 -:1033000021A1FE3009F037FC002C0DD060780007B9 -:103310000AD50598002807D184202070204658221D -:1033200029460830EDF75CFF304609B0F0BDF7B52F -:103330000C460546007A224688B00A320292921C58 -:1033400004920027811E16323E4601920B0009F0BE -:103350002BFD08F605F548488DD1F4F56888002363 -:103360000122032102F0E2F80190002803D106A116 -:103370000B4809F000FC01980088002812D0522761 -:10338000072601E1C01100207372635C67617474E9 -:10339000735F636F72652E63000000006F020000B0 -:1033A0008603000051271E26002C7DD06888A0804F -:1033B0000120A071019802990079C0004019C089CC -:1033C000FFF754FD002870D101980079C000401922 -:1033D000C089208101980079C0004019408AA083EB -:1033E000F2E0698A0091062820D1E889C00B1DD03F -:1033F00008462230512786B2002CD6D0A8890499DD -:10340000FFF734FD002873D16888A0800220A071E6 -:10341000A88920810120A072288AE0830098208456 -:103420006969009A019809F01BFACDE0084620303E -:10343000502786B2002CB8D0A8890299FFF716FD54 -:10344000002855D16888A080A889E080287A0628BD -:103450000AD002202072288AA0830098E0832046A8 -:1034600069692030009ADEE70120F3E768880023CD -:103470000122032102F05AF80690688A009006980B -:10348000002803D1FD49FE4809F075FB0698083075 -:1034900004F08DFB0121484002D1E889C00B26D001 -:1034A0000098223086B201E073E021E05127002C21 -:1034B00079D06888A080A8890499FFF7D7FC0028F4 -:1034C00016D10220A071A88920810420A072288A28 -:1034D000E083009820846969009A019809F0C0F996 -:1034E0000699002008710698A98941806CE00320A4 -:1034F0000BB0F0BD6888FBF7D4FC0190688800230E -:103500000122032102F012F800900198002804D152 -:10351000DB48DA492C3009F02EFB0098002804D152 -:10352000D748D6492D3009F026FB0098D549C088E8 -:10353000884205D05127222604E01EE03FE035E016 -:1035400050272026002C2ED06888A080502F07D02E -:103550000220A0712146287B0831FFF730FD33E0BF -:10356000287BA11DFFF72BFD6A8800230099019895 -:10357000FFF73CFD0028BBD126E0C349A889C988D4 -:10358000814207D154270626002C0CD06888A080E1 -:103590001AE008E053270826002C04D06888A08091 -:1035A000A889E08010E00A98068013E055270726D6 -:1035B000002CF8D0A889A0800020A07104E08D2004 -:1035C000AE49C00009F0D7FA0A98002C068001D055 -:1035D0002780668000208BE7AB4900200870704789 -:1035E00030B585B00C4601F0E0F90546FF2804D15E -:1035F000A348A249953009F0BEFA0020208020712E -:103600006080401EE08020462946083003F0A0FC80 -:103610006A4629460120F9F758FF102412E068464F -:10362000808800070ED56846C0882946FFF71BFD35 -:1036300068468188FF2321438180C0882946019AFA -:10364000FAF76EF86846F9F749FF0028E7D005B0A9 -:1036500030BD0A46014610B51046083003F08CFC18 -:1036600010BD70B5002305461A46032101F05EFF28 -:10367000040004D182488149B73009F07CFA204621 -:103680002946083003F070FC70BDF0B591B00C46CF -:103690000746FBF706FC050005D02878222804D24F -:1036A000082011B0F0BD7948FBE700231A4603213A -:1036B000384601F03BFF0646002C02D0A0880028C7 -:1036C0000CD001206946087102200874002048745B -:1036D000002C05D0A0880883206802E00920E0E7DC -:1036E000088305903046083003970290F7F738FDBD -:1036F000040018D06780172069468883203500941D -:103700000AAB6978023307AA01A803F0F8FF05465F -:103710006078000701D5F7F704FD002D09D0284691 -:10372000FFF77BFABDE713213846FCF7ADFE032017 -:10373000B7E708A800906846838B04220121384629 -:1037400001F0CBF90021C943F180AAE7FFB585B0AC -:103750000E9E77883846FBF7A4FB054600231A46E1 -:103760000321384601F0E2FE0446002D03D143490F -:10377000474809F000FA002C04D145483F49401C55 -:1037800009F0F9F90834089869460394C1C105A8FD -:103790000DC82035697803F021FCC6E5F0B5044674 -:1037A000002099B00D4601460D9010A88181164663 -:1037B00001818180344A68469180018510A801808A -:1037C00068460187818581841078012808D0022805 -:1037D00006D0032804D0042802D0082019B0F0BD78 -:1037E0002C4A944273D32C4F0121890438688C42AF -:1037F00001D3844278D3274A954275D301218904A5 -:103800008D4201D385426FD36168002913D0214ACC -:10381000914269D301229204914201D3814263D340 -:1038200060892189884203D801225202914201D93C -:103830000C20D3E70D9016AA0EA92846FFF783FAAD -:103840000028CBD1686880784007800F02280AD111 -:103850006846008F8004800F05D02869002802D0B8 -:103860003968884240D30AA92069FFF716FA002870 -:10387000B4D1206900281CD060780FE088330100A3 -:10388000EE030000FFFF0000C01100200230000026 -:103890000C05000000D001002001002080076846D0 -:1038A000008D03D58004800F68D002E08004800F73 -:1038B00064D16846008D810618D58004800F606849 -:1038C00006D0002812D0396888420DD302E00BE000 -:1038D00000280BD0FE49884206D301218904884282 -:1038E00004D33968884201D2102077E709A96069BA -:1038F000FFF7D3F900289CD16069002808D06846FA -:10390000808C0105890F012938D18004800F35D0C2 -:103910000BA9A069FFF7C1F900288AD16846808CFD -:1039200080062BD46846808D810627D4A1690029A2 -:1039300006D00105890F012920D18004800F1DD0F8 -:10394000E068002804D00078002817D01C2815D281 -:1039500004AA611C2046FFF71DFA0121890210A864 -:103960000180012768468773DA49818104AA0332FE -:1039700017A92868FBF709FA002801D007202DE7CE -:1039800010A8007F15A9C01CC2B200200C920190A3 -:10399000FF32009003460291FF3203A803321099D0 -:1039A000F9F7EBFC002826D110A9888A0F902A8904 -:1039B0002969C94801910092029010A90A8B6B896C -:1039C00028680E99F9F7D9FC01007DD1C24800257D -:1039D000001F818868464174090A8174052104A882 -:1039E0006A4623C210A82A46FF21808A0C9BF9F759 -:1039F00029FC002802D0FFF7A4F8EFE66846007C17 -:103A00000322C109002092029043012292028018F1 -:103A10001490002928D0014610A801806846292169 -:103A2000877309028181058608A8007C002341086C -:103A300060784900C007C00F014308A80174FD2049 -:103A400001406078A54A8007C00F4000014308A8E4 -:103A500001740CA9022001910090029503A810990D -:103A6000F9F78BFC01002FD16068002828D020696D -:103A700000280DD10AA90EA8FFF7D5F960788007B4 -:103A800006D46946088D03210903884369460885E1 -:103A9000904968468773FE31818190492089891E4B -:103AA00008F047FF62680D9811AB019200900293F5 -:103AB0000A46002303A80A99F9F75FFC010003D125 -:103AC0002078C10603D400E086E080062AD5684647 -:103AD0000586606900280DD109A90EA8FFF7A3F992 -:103AE0006846818C032080028143012080020918EE -:103AF000684681846946888CC82108436946888461 -:103B000074488F73FF30888112AA0CA90220029298 -:103B1000019100900023714A03A80999F9F72DFC3F -:103B2000010059D12078C00729D068460586A069D0 -:103B300000280DD10BA90EA8FFF775F96846818DF5 -:103B40000320800281430120800209186846818594 -:103B50006846818D402001436846818587736049AE -:103B6000818113AA0CA902200292019100900023E6 -:103B70005A4A03A80B99F9F700FC01002CD1E06820 -:103B800000282DD010A814990180554968468773E4 -:103B9000491C8181E16808A80A7802744978417457 -:103BA000E0684122418868464186E0680023017947 -:103BB00008A80175E068D200C18808A84175090A03 -:103BC00081750CA8072101900091029503A8109916 -:103BD000F9F7D3FB010003D00F9800F0EAFEFDE5F2 -:103BE0003D480321001F0170002E0AD080883080DC -:103BF00010A88088708010A80089B08010A88089E3 -:103C0000F0800020EAE530B501248BB015460B4664 -:103C1000012802D002281CD104E0684605218473E3 -:103C2000C90203E02B4968468473891E8181002BF9 -:103C300012D0032100208902884301218902401803 -:103C40006946888405AA04A91846FBF79EF800284F -:103C500004D007200BB030BD1020FBE76A46127C71 -:103C60001D480092801E05A9FF3201910290FF328B -:103C7000002303A803320999F9F77FFB002802D03B -:103C8000FEF75FFFE6E71448001F002D01D04188D2 -:103C9000298004700020DDE770B592B0044601264B -:103CA00008A886700F496846018410AA08A9304602 -:103CB000FFF7A9FF00284DD12078074DC007002449 -:103CC0002D1F002848D01C21684608F028FE0BE074 -:103CD00000D0010003280000C411002003020000EE -:103CE00003290000011800006846017820200143E4 -:103CF0006846017008A88670F949684601841194E5 -:103D00000794817FF92001406846891C8177002053 -:103D10000146684601770020014668464177042144 -:103D20008185C485018607A80A9011A80D9008A86E -:103D300009900EAA09A96846FFF730FD002809D1AD -:103D40006846008FE8806846808F2881401C688123 -:103D50002C70002012B070BDEC802C8110A800885F -:103D6000F4E7F7B5DF4900260A789EB0012A04D0AF -:103D7000022A02D0082021B0F0BD4A88824201D038 -:103D80000620F8E71F98824201D10720F3E70122BD -:103D900010A98A75D4488882002003239B0201461B -:103DA00099439302CB1810A90B8669468A81CF4AA2 -:103DB000CA8118A9887110A9888419A90491694633 -:103DC000CA820690FF20087503A8F9F7AAFB002411 -:103DD0002546274608AA052103A8F9F7A5FB0028D0 -:103DE00010D082286FD1002C6FD0002D6DD010A87C -:103DF0008480C5800021017418A8807B11AC012843 -:103E000065D06DE008A88079002F21D0012857D116 -:103E10006846818CB44881421CD113AA0DA90520A3 -:103E20006B4607C36846408C10230022FF21F9F738 -:103E3000EDFB002868D110A88089042801D006284D -:103E40004CD16846818E1F98814239D10F2092E76C -:103E5000012835D16846808C0521C902884202D0EC -:103E6000491C88422CD19F4841886846408C814239 -:103E700001D1012700E00027002C01D0002D10D037 -:103E80001F9988421CD113AB0DAA05216E460EC6A0 -:103E9000044610230022FF21F9F7B8FB002833D194 -:103EA00001E035460CE010A88089022801D01028D6 -:103EB00014D1C0B21BAA0DA9FAF741FF00280DD1F9 -:103EC0006846468C86E71FE0FFE7052053E714A904 -:103ED0001BA8221DFAF759FF002801D003204AE74A -:103EE00010A8007C0023001DC2B210A80274209804 -:103EF00002900194009215A81C99F9F73EFA002847 -:103F000002D1784902220A70FEF71BFE33E710B592 -:103F10000B46401E86B084B203AA00211846FEF765 -:103F200039FF04AA052103A8029201910090012300 -:103F30000022FF212046F9F785F904466846008AE9 -:103F4000012804D06D206A49000108F014FE2046C3 -:103F5000FEF7F7FD06B010BDF0B5624F04463878A5 -:103F600087B00E46032804D0042802D0082007B0EA -:103F7000F0BD04AA03A92046FEF7E5FE0500F6D130 -:103F8000606880784007800F02280DD168468089DC -:103F90008004800F08D02069002805D055490968A1 -:103FA000884201D21020E2E7208905AA6B462169E8 -:103FB00007C369460A8A638920680399F9F7DDF91E -:103FC000002802D0FEF7BDFDD1E7002E02D06846E2 -:103FD000808A3080042038702846C8E738B50C0045 -:103FE000054609D000236A46FF21F9F771FB002836 -:103FF00004D0FEF7A6FD38BD102038BD6946204626 -:10400000FEF74BFE0028F8D1A078FF21C307DB0F95 -:104010002846009AF9F784FBEBE73EB50C0009D07F -:1040200002AB6A46FF21F9F753FB002804D0FEF7E4 -:1040300088FD3EBD10203EBD0321204608F06DFCEA -:104040006846008801A90005800FFEF712FE0028CF -:104050000BD16846007920706846008801A9800469 -:10406000800FFEF706FE002801D003203EBD684603 -:1040700000796070A278EF20024068460088C10B8A -:1040800009010A43F7210A404104C90FC9000A4344 -:10409000A270F9210A40800601D5022000E001202B -:1040A000400069460243097A50084000C907C90F19 -:1040B0000843A07000203EBD7FB514460522019242 -:1040C00003AD029500930A462388FF21F9F7BAF859 -:1040D000694689892180FEF734FD04B070BD000077 -:1040E000052A0000C011002002280000FFFF000088 -:1040F0008833010020010020F3B5002799B06846FD -:104100000C4607873D4600291ED0E068002806D0EF -:10411000A068002818D001886A461187078019987E -:10412000FAF7BFFE002812D0007822287ED3199813 -:1041300000F03BFC002300901A460321199801F07F -:10414000F5F9060009D104E010201BB0F0BDFD48D0 -:10415000FBE7FD49FD4808F00EFDA078012803D0DB -:10416000022801D00720F0E72088002808D0401E50 -:1041700080B203AA0099F9F7A8F9002859D11DE0E7 -:10418000F048401CE1E76946498A228891420BD2F7 -:104190006846807D0025012810D16846808AEC4958 -:1041A00088420BD1012509E0914203D1002D2AD08C -:1041B0006D1C01E0022D0BD0032D04D203A8F9F7EA -:1041C0008DF90028DFD082281BD0002831D11DE0D6 -:1041D0006946897D0129F1D16946DD4B8A8A5B1EDA -:1041E000D11A9A420FD005DCDA48101A0BD00128F8 -:1041F000E4D108E0012906D0FF390129DED10325E9 -:10420000E1E7022D15D10D2080029EE7E06800282D -:1042100016D00EA9052202910192009069460B8FDB -:10422000A2882088FF21F9F70DF800E01EE00028A1 -:1042300002D0FEF786FC88E76846A168008F0880F8 -:104240006846008AC00601D5C3487EE70798002863 -:1042500003D06846008B022801D0032075E7079839 -:10426000A1780078012903D0800710D408206CE7DA -:10427000C007FBD000220721199800F016FF002884 -:1042800002D00725022004E0AE48801C5DE702252D -:10429000032008A908702188684681851998083686 -:1042A0000A90099617216846818712AB02330FAA3C -:1042B000052108A8009703F022FA002802D0FEF793 -:1042C000ACFC42E710A800906846838F0422294680 -:1042D000199800F002FC38E770B5064615460C4602 -:1042E0000846FEF7EBFB002804D12A46214630465B -:1042F000FFF789FCF2E610B5FFF733FD10BD70B58E -:104300001E4614460D0014D0002C12D061680029FE -:104310000FD00121FEF741FE002809D12068FEF7E9 -:10432000CDFB002804D1324621462846FFF736FA55 -:10433000D4E61020D2E670B515460C000ED002214E -:10434000FEF72BFE002808D12068FEF7B7FB0028F7 -:1043500003D129462046FFF7FFFDBFE61020BDE64A -:10436000F8B506467D480D46016814468A4231D3A9 -:104370006068002808D07A4A90422BD30122920428 -:10438000904201D3884225D37648864204D03046F5 -:10439000FAF787FD00280CD0304600F006FB0646F1 -:1043A000284600F0BFFA002804D16068002802D037 -:1043B00012E06448F8BD00236A4631462846F9F702 -:1043C00087F9002802D0FEF7BCFBF8BD68460088DC -:1043D000800601D41020F8BD618822462846636813 -:1043E000FFF76AFEF8BDF7B55C4E0746306886B049 -:1043F0001446824202D2102009B0F0BD384600F0C7 -:10440000D4FA05465748874201D0FF2D08D0002333 -:1044100004AA29460798F9F75BF9002826D101E09C -:104420004848E9E76846008AC00601D54A48E3E7FC -:1044300003A9002002910527019000976288494B4B -:1044400029460798F9F7E2F800280FD16168326829 -:10445000914208D3019102900097238862882946EF -:104460000798F9F7D3F8694689892180FEF769FB37 -:10447000C2E7002907D03C4B0A881B899A4202D820 -:104480003048401C704737E610B586B004236C46B0 -:10449000A382354BDC88002C07D01B898B4201D2CC -:1044A000914204D92748401C54E5062052E56B464A -:1044B00019825A820021009101911C800221997079 -:1044C00005A9029104A903916946FFF715FE41E58C -:1044D000F3B50C4685B0812069460873002C1BD0CB -:1044E0000598FAF7DEFC070018D03878222869D33F -:1044F000059800F05AFA049000220121059800F076 -:10450000D4FD00280CD000231A460321059801F0A1 -:104510000DF805000AD105E0102028E5094826E538 -:10452000112024E50849114808F025FB28460830E9 -:1045300002F03CFD06462078012819D0022838D028 -:10454000072014E50230000088330100E108000074 -:104550000328000000280000013400002001002092 -:1045600000D00100FFFF0000C0110020840A0000FD -:10457000A18803AAFEF71CFB0028CED1B00721D5E5 -:104580006846007B00281FD1A079C0071CD0E068D6 -:10459000002205216B4607C3638922896888049934 -:1045A000F8F750FE6946087300280DD0FEF7C9FAE7 -:1045B000DDE4A18803AAFEF7FBFA0028ADD1342080 -:1045C000064201D10820D2E46846037B29463846DA -:1045D000059AFEF70BFDCAE4FFB597B000200190E5 -:1045E0001F4615460C460E461798FAF75AFC002847 -:1045F00004D00078222803D20820A6E5F448A4E5D8 -:10460000B80801D00720A0E5032F00D10027179894 -:1046100000F0CBF90890002C1BD0022D77D3ED4889 -:10462000006884427CD361190091012902D0491E9F -:10463000814275D3AD1EAAB22146E74803F036FB8E -:1046400000991E394A7F0B7F11021943884267D1B6 -:10465000ADB2E248B90702D50189491C00E0012149 -:1046600089B20091F90701D0078900E0DA4F03AA67 -:1046700008990098F8F729FF0DE0F078B17800026A -:10468000084310284CD80199091D401880B20190A8 -:10469000A84245D82618002E60D0707831780002E4 -:1046A000084300998842E8D358E06946098A0A0716 -:1046B00054D5002C3FD0019AA618121D92B209922F -:1046C000F278B37812021A439446102A28D8099A2D -:1046D0006244AA4224D87278337812021A43904274 -:1046E0001ED1C8061ED509980AAA052120186B46B6 -:1046F00007C37078317800020843634600220899A6 -:10470000F8F7A0FD002803D0FEF71BFA1DE507E02F -:10471000F078B178000208436946098D884201D0DB -:104720000B2012E5F078B17800020843099940188F -:1047300080B2019006E0C90604D50899FEF793FC03 -:104740000028E3D16946088A102188436946088217 -:10475000488AFF23049A0899F8F7E2FF03A8F8F7BC -:10476000BDFE002803D16846408AB8429DD9002387 -:104770001A460321179800F0D9FE040003D1984986 -:10478000984808F0F8F920880028BFD0012108A82F -:104790000170017300264673218868460186204611 -:1047A0000830099017980A90F6F7DAFC05001BD03C -:1047B0001798688017206946888010AB023301AAD9 -:1047C000052108A8009502F09AFF074668780007BF -:1047D00004D584488249223008F0CDF9002F09D051 -:1047E0003846FEF71AFAB0E413211798FBF74CFE8F -:1047F0000320AAE40EA800906846838804220121C1 -:10480000179800F06AF900288BD126809DE4F0B556 -:1048100000248DB01F4615460E46002A04D0B90864 -:1048200004D007200DB0F0BD1020FBE7032F00D10E -:10483000002700F0BAF80390FF2804D06749B807B2 -:1048400003D5488902E06248ECE70120FA0702D06C -:104850004989491E00E0604906AA8FB20399F8F71A -:1048600034FE38E06946898B090734D504AB05214D -:104870000022029300910192574B0399F8F7C6FE6C -:10488000002821D1002E21D06A46128A2988A21838 -:104890003019121D914234D36946CA8B0270120A34 -:1048A00042700A8A8270120AC27004A90522001D91 -:1048B0000092029101906946C88B0B8A00220399ED -:1048C000F8F7A4FE002801D00320ABE76846008A71 -:1048D0002018001D84B206A8F8F700FE002804D0B6 -:1048E000822806D0FEF72DF99CE76846C08BB842B7 -:1048F000B8D9002C07D0002E10D02988A01C8142E6 -:1049000003D20C208EE705208CE722463146324840 -:1049100003F0CCF931190870000A4870A41C2C80EF -:1049200000207FE700B585B06946FEF79FFA0028B2 -:104930000AD16846007C030008F036FA08052F2FDC -:104940002F2F08080531032005B000BD6846807888 -:10495000012807D1684600880321C902401A1CD0EB -:1049600001281AD068468079012806D168468088D7 -:1049700015214902401A05280FD96846807A012876 -:1049800011D16846018929200002081A05D00228A1 -:1049900003D0032801D0042805D10F20D4E712A1A9 -:1049A000164808F0E8F80020CEE710B500F0B4FD96 -:1049B00010BD10B50C46F8F75BFD002803D00AA126 -:1049C0000F4808F0D8F82046FEF7BBF810BD0000ED -:1049D0000230000020010020FFFF0000C011002075 -:1049E000883301003F0B00007372635C676174746D -:1049F000735F636F72652E63000000002202000087 -:104A0000BB06000030B50346072903D00820DA783A -:104A10001C7916E00720FAE707290BD05500ED189E -:104A20006D79072D01D0401EC0B2521CD2B20F2AA0 -:104A300007D105E05500ED186D79072DF3D0F4E7A7 -:104A400000222546641EE4B2002DE5D130BDFFB53D -:104A500081B00C461646114620460A9F0B9DFFF773 -:104A6000D1FF00280AD020790F2803D3FEA1A0206F -:104A700008F081F8A078C00907D019E0072E02D00D -:104A8000112005B0F0BDFD48FBE701982880381DD6 -:104A90006880002068712871EF800498288128467A -:104AA00000F06FFC002803D1EFA1AD2008F063F8FF -:104AB000E07821794018491CC0B221710F2801D338 -:104AC0000F38C0B24000001946718179F1224908BF -:104AD0004900114081710020D3E7FFB583B01C4627 -:104AE00016460F4600231A4602210C9D039800F03B -:104AF0001DFD010008D033463A4601950094039805 -:104B0000FFF7A5FF07B0F0BDDC48801EFAE7F0B55F -:104B1000054616460F4650888DB00023012202211B -:104B200000F004FD040003D1CFA1DF2008F023F83A -:104B3000002069460871A078400603D1CAA1E3208D -:104B400008F019F8042F5ED32A78D007C017401C4C -:104B500006D161786B78994255D12178090752D0F6 -:104B60000121142A46DA012A42D0122A02D0132A3D -:104B700040D128E00C2F3DD1A2785206520E012AD6 -:104B800038D0207800090001401C207068786070DF -:104B90006846017168792A790102114368460181EA -:104BA000E879AA790102114368464181687A2A7A34 -:104BB0000102114368468181E87AAA7A0102114311 -:104BC0006846C1811AE0062F14D12078000900013F -:104BD000207071880120F7F788FD02216846017175 -:104BE000C91E018168792A790102114368461FE0D4 -:104BF000062F0AD06A461279002A1BD070883246E6 -:104C000001A9FAF776FF0DB0F0BD20780009000188 -:104C1000207071880120F7F768FD02216846017154 -:104C200068792A7901021143684601810021C9434C -:104C30004181E3E70028E6D0748868468176697888 -:104C4000C176022181830021C18304A8052200903E -:104C5000062311462046FFF740FF0028D3D088A145 -:104C6000D62007F088FFCEE7F7B58CB015460C9933 -:104C70000D98FDF782FDC0B2082851D10020694689 -:104C80008885688800230122022100F04FFC04007F -:104C900004D1FF2074A1633007F06DFF01230021D0 -:104CA000E07822790BE04600361976799E4201D1F0 -:104CB000491CC9B2401CC0B20F2800D100201646C2 -:104CC000521ED2B2002EEED1002902D11720694621 -:104CD000888504AB02330BAA00950C990D98FEF75A -:104CE00035FD0006000E07D002281BD0032817D080 -:104CF000FF205DA1893011E06846808D00280FD02B -:104D000002A9019100906888042301222146FFF73F -:104D10009EFE002804D0FF2053A1763007F02BFF21 -:104D20000FB0F0BD6878102108436870F8E70020E4 -:104D3000584902464300401CCA520828FAD370471B -:104D40000021817001780909090101700021417079 -:104D5000C1700171704770B50D4600230122022118 -:104D600000F0E4FB040004D1FF203FA1CF3007F0A6 -:104D700002FFA0786906C009C001490E0843A0706F -:104D800070BD704710B501460120F7F7AEFC10BDAD -:104D90003EB58DB2002301220221284600F0C6FB59 -:104DA000040004D1FF2030A1E43007F0E4FE2078B5 -:104DB000694600090001207002200870364888808A -:104DC000C88000222846FAF794FE3EBDF7B5054696 -:104DD0000078002700090C463E46012804D0FF2039 -:104DE00021A1F33007F0C7FE287A03280CD0412018 -:104DF0001DA1C00007F0BFFE0298002C068001D064 -:104E0000278066800020FEBDEA89702710460A30A0 -:104E100086B2002C0AD06888A080A8892081E28010 -:104E200020460A30296907F01BFDE5E70298068055 -:104E3000E8E7F8B543680246D9799C79090221432D -:104E40005C7A1E7A25025C88981D3543241FA14296 -:104E500038D11B79022B35D1042D34D0052D3DD00E -:104E6000062D34D0402D19E07372635C6C3263619F -:104E7000705F636F72652E630000000004300000F5 -:104E80007372635C6C326361705F636F72652E6313 -:104E900000000000CC110020FFFF000012D3061D0F -:104EA0000F461446284600F0E9F908280AD01120D8 -:104EB000207003202072A581E78126616078082197 -:104EC00008436070F8BD001DFFF7CEFEF8BD031D5E -:104ED00050880A461946FCF77EF9F8BD001DFFF719 -:104EE00016FEF8BD70B50D4600238CB006461A4676 -:104EF000022100F01BFB040031D020780007000FD6 -:104F000001282ED012206946887460780523801C01 -:104F1000C874082088822888C88268880883A8887E -:104F20004883E888888302A90C20019100901A46E2 -:104F300021463046FFF78BFD00280ED1F0230022DA -:104F400031460120F7F72CFB207800090001401CB6 -:104F500020706078801C607000200CB070BDCD485F -:104F6000FBE71120F9E770B50D4600238CB006462B -:104F70001A46022100F0DAFA040006D02078000771 -:104F8000000F012803D00820E7E7C248E5E7132116 -:104F9000684681746178C17402218182C58202A948 -:104FA00006200523019100901A4621463046FFF75E -:104FB0004EFD0028D1D1207800090001207000208A -:104FC000CBE7F3B581B00D46002301220221019801 -:104FD00000F0ACFA00260446002803D1AE49AF48E1 -:104FE00007F0C9FD2079A8423BD2AC48AA49401C31 -:104FF00007F0C1FD35E0E07841000F19401C7979D8 -:10500000C0B20091E0700F2801D10020E07020793B -:10501000401E2071B879C00708D000980199042873 -:1050200015D09D498220183107F0A5FDB8790007F9 -:10503000410F08D0400F019904280CD096498F20C9 -:10504000183107F098FD009807280AD107E00846B4 -:10505000FCF73EF9EAE70846FCF70DF9F3E7761CA2 -:10506000F6B228466D1EEDB20028C4D13046FEBD12 -:1050700010B500230122022100F058FA040004D1E7 -:10508000B5208549800007F076FDE0782179401849 -:10509000C0B2E0700F2801D30F38E07000202071FB -:1050A000A07880210843A07010BDF8B517460D46C2 -:1050B00000231A46022100F039FA040005D0002D21 -:1050C0000CD0002F07D0062006E0072D01D00820C5 -:1050D000F8BD0720F8BD0820A84204D86F486E49E3 -:1050E000423007F048FD29462046FFF78BFC064674 -:1050F000002F28D0002E26D1E07821791CE0420034 -:1051000012195379072B03D093791B075B0F04D037 -:10511000401CC0B20F280CD00CE040000019807970 -:10512000F12318406B071B0F1843907100290AD117 -:1051300004E00020491EC9B20029E0D15748564971 -:105140005A3007F018FD3046F8BDF8B50D4600237B -:105150001A46022100F0EAF9040004D14F484E49F2 -:10516000683007F008FD681E052804D34B484A49FB -:10517000693007F000FD0F21E2782079002310E06C -:10518000560036197779AF4206D1B17949084900FE -:10519000B1715B1CDBB21146521CD2B20F2A00D196 -:1051A00000220646401EC0B2002EE9D10F2905D2CA -:1051B0004800001981790122114381711846F8BD18 -:1051C00010B50446402801D2072010BD00F056F863 -:1051D000082802D03120000210BD0021304802E032 -:1051E000491C082903D24A00825A002AF8D108290A -:1051F00003D049004452002010BD042010BD10B55A -:10520000402801D2072010BD00F038F8082805D04A -:105210000021234A40001152084610BD052010BD50 -:10522000F0B58BB016460C00074607D0002E05D00F -:105230006188402904D207200BB0F0BD1020FBE7A5 -:105240002088002801D0172801D90C20F4E708464F -:1052500000F014F808280FD0258803A82A46314604 -:10526000023007F0FDFA01A8009062882B46072162 -:105270003846FFF732FCDFE70520DDE70146002076 -:10528000074A02E0401C082803D24300D35A8B424D -:10529000F8D1704702300000684E0100AD020000F6 -:1052A000CC11002010B5031D03600020521E04E045 -:1052B0005C181C60401C2346C0B29042F8DB002002 -:1052C000186010BD01460A680020002A02D010466E -:1052D00012680A60704702680A6001607047000047 -:1052E00000B51E2823D00BDC0C281CD01FDC0300CB -:1052F00007F05AFD090F1D111D1D171713151D006D -:10530000302814DD3A38030007F04EFD030F110971 -:105310001100002000BD214800BD042000BD0D206B -:1053200000BD0F2000BD082000BD112000BD0320DE -:1053300000BD10B50C4601F011FB00281ED0204620 -:1053400000F086FC002816D022780E2A0DD00F2AF5 -:105350000BD0022A09D0032A07D0102A09D010A1A5 -:105360007C2007F008FC002010BDA078FFF7B8FFF4 -:1053700010BD112010BD0AA18220F2E708A18820EB -:10538000EFE710B500F0A5FA10BD10B500F060FC15 -:1053900010BD10B500F0FBFA10BD00000230000097 -:1053A0007372635C686F73745F6863692E63000077 -:1053B000F8B50546E54C079E069821706270A3700B -:1053C000E6702071681C42085200E14B0021880001 -:1053D00000198446C261605C40008218002D0AD02A -:1053E000002005E066464700F669401CF353C0B252 -:1053F000665C8642F6D8491CC9B20529E7D3002667 -:10540000D21C9708B000BF0000198760304600F03A -:1054100042F9A15D761C4843C219F6B2052EEFD3BE -:10542000501B80B2F8BDF0B50546C84F8C46002031 -:10543000FF247E5DA90096460346CF190CE0F9696A -:105440005A008A5AC2498A4204D1401CC0B2FF2C79 -:1054500000D11C465B1CDBB29E42F0D8614600299D -:1054600009D100280BD0002D07D0B84949788E42C9 -:1054700003D2401EC0B2002801D071460C70F0BDAE -:1054800070B5B24C8D0000232D19615C09E0EC6908 -:105490005E00A45B844202D11370012070BD5B1CCE -:1054A000DBB29942F3D8002070BDFEB51C4617460A -:1054B0000D46060008D0002D06D0F01C80088000A4 -:1054C000B04203D01020FEBD0E20FEBD002F03D041 -:1054D000002C01D0A74201D90720FEBD009423462D -:1054E0002246394600200194FFF762FF2988814255 -:1054F00007D0814201D2042100E00921288008461A -:10550000FEBD009423462246394630460194FFF7FB -:105510004FFF28800020FEBD10B5044600F0C5F8FE -:10552000002801D0E0B210BDFF2010BDFFB5054638 -:10553000874881B01E460C46854204D0052C02D215 -:105540000398022802D3002005B0F0BD0027694669 -:105550000F7028466A462146FFF792FF00280ED0BA -:1055600068460178204600F0A8F8002EECD000280C -:10557000EAD1284600F099F8002809D103E038461E -:10558000002EF6D1E0E7FF2072A15C3007F0F3FABD -:1055900021462846039A00F09CF8D5E7F8B5054661 -:1055A0000C4600206A4E69466E4F0870B5423BD0EB -:1055B000052C01D30720F8BD0A4621462846FFF7EF -:1055C0005FFF002830D068460178204600F075F86B -:1055D000230007F0E9FB0504090C11161B00014626 -:1055E0002846FBF709FD15E0FAF756FC12E00146E4 -:1055F0002846FFF7C6FB0DE001462846FEF729F8CE -:1056000008E001462846FCF740FF03E056A17B2056 -:1056100007F0B1FA4D4A6846A10000788918C969B7 -:1056200040000E520020F8BD3846F8BD524A1268BC -:10563000914201D210207047052801D307207047FE -:105640000872002048727047F8B504464A4800685E -:10565000844201D21020F8BD207A3C4A83009B1876 -:10566000617A3B4D125C11E0DE694F00F65BAE42A1 -:105670000AD04A1C6272DA694B00D25A228000F0CA -:105680001CF860600020F8BD491CC9B28A42EBD802 -:1056900061720520F8BD0EB5384B40000ECB00916D -:1056A000029301926946085A0EBD28494978814201 -:1056B00001D9012070470020704770B50C4605469F -:1056C000FFF7E9FF214AA90089188968604340185B -:1056D00070BDF8B50C4606460020694613460870B2 -:1056E0006A4619462046FFF79EFE002500282BD06B -:1056F000164A6846A10000788918C96940000E5210 -:10570000684601782046FFF7D8FF0546230007F0DA -:105710004BFB0504090C0F14170029463046FBF714 -:1057200047FC11E0FAF796FB0EE0FFF709FB0BE0F0 -:1057300029463046FDF754FF06E0FCF79FFE03E0E4 -:1057400009A1622007F017FA2846F8BDDC110020F5 -:10575000FFFF00007372635C686F73745F636D2E8C -:1057600063000000023000007372635C686F737442 -:105770005F636D2E63000000200100205CCF0100FC -:1057800038B50446002069460870204602F0E3FF61 -:10579000002803D1FBA1A32007F0EDF9204602F079 -:1057A00029FF002803D1F7A1A82007F0E4F96846F3 -:1057B000007838BD70B5F84D002428462C7720308D -:1057C0008471C47101F09AF9284640380470203081 -:1057D0008473847484772C75AC7170BD10B50C46DD -:1057E000EE4982888A8042884A800078087008469C -:1057F0000E38847002F0E0FE02F08DFAFFF7DAFF57 -:10580000204604F0A3FAE449A8310846813803F0A1 -:105810003DF9E24805F0B1FDE0480A3802F08EFAA1 -:10582000002803D0D7A1C52007F0A5F901F066F93B -:1058300010BD7CB50E461D46144601A902F098FA2B -:10584000002807D103F021FE022803D1D248007DB1 -:10585000002801D001207CBD01988030807C02F0BE -:10586000DDFE00280CD0684602F0E2FE0028F2D0EF -:10587000002C03D002F0A1FEA04206D200207CBD85 -:10588000C0A1C74807F077F9F8E7009802F068FB75 -:105890003146009802F06BFBE2B22946009802F014 -:1058A00080FC02F0D5FE002804D1BD48B5A11E3011 -:1058B00007F061F9B94C00250E3C6068A0304179D1 -:1058C000002902D0457104F068FB60688030458390 -:1058D000C0E730B40179002904D0012907D030BCD9 -:1058E00000207047831D42880488022103E042881B -:1058F0000488831D0121204630BC9AE7F8B51D4677 -:1059000014460E46074603F0C0FD022803D0A24805 -:10591000007D002823D0A1480E384168498839808D -:1059200040688030807C02F0F9FF002804D15320C9 -:1059300094A1C00007F01FF9684602F0F9FF0028A3 -:105940000DD0009802F04AFB3070022808D00128E0 -:1059500006D093488BA1673007F00DF90020F8BD01 -:105960002946009802F034FC2080002804D15520FC -:1059700084A1C00007F0FFF802F0EDFF002804D179 -:10598000874880A1603007F0F6F80120F8BD38B5EF -:105990000446831D821C6946FFF7B0FF00280DD026 -:1059A0000020607168460078012808D0022806D0DF -:1059B000FF2074A1013007F0DEF8012038BD20710E -:1059C000FBE7F8B503F061FD744D734C0E3D022802 -:1059D00002D0207D00287DD0207F0026102818D1FD -:1059E000A079002803D067A16E4807F0C4F8686862 -:1059F00001464030827F92070BD52672498861812B -:105A0000C17F2173018CE181408C20820120A07133 -:105A10002677614F203FB87C00285ED168686946D0 -:105A20008030807C02F097FE002805D069466878B7 -:105A300009784018687004E05A4852A1193007F0FC -:105A40009AF8207D00283AD068684188524840384A -:105A5000806D4088814204D00F204AA1C00107F028 -:105A60008AF868688030807C02F058FF002804D1F2 -:105A70004C4844A1243007F07EF802F07EFF002855 -:105A80001DD068688030807CFFF77AFE6978401806 -:105A9000687041484038806D4030417A01290DD10D -:105AA0002670696849886180807A20710120B87702 -:105AB000207F102801D0282800D126772675697804 -:105AC00000290AD06868428833484038C286018776 -:105AD000012000E001E0B8746E7003F0B9FC00280A -:105AE00005D1207D002802D0A878EDF715F9F8BD82 -:105AF000F8B50446FFF765FF274D0026203DA87E38 -:105B0000002808D0667010202070E87EA070287FE2 -:105B1000E070AE769AE0204F403F3878002808D0F9 -:105B20002C22B91C204606F09BFE0E2020703E70F1 -:105B30008CE0A87B184F002815D0387F102808D09B -:105B4000282806D0002804D0FF200EA1C23007F07C -:105B500012F80120E070E87BA070287C60700F20B4 -:105B60002070AE7372E00121204602F029FF002868 -:105B70001AD0387D002857D10021204602F020FF9E -:105B8000F8BD00007372635C6C6C5F6374726C2EA2 -:105B900073302E63000000007C1200206A01002098 -:105BA0004F02000062070000A97CF8480090F84806 -:105BB000002910D0017805290DD2491C01706670AA -:105BC0000D202070012028750622A01C009906F0E7 -:105BD00047FEAE743AE0EE480670B879002812D05D -:105BE000387F002804D00120EA49400206F0C3FFB4 -:105BF00066700120E54920700A221431A01C06F0CD -:105C00002FFEBE7122E0204605F013FB00281DD1B7 -:105C1000A87C002802D0DE480178CEE7A87F0028C3 -:105C200002D0387D002801D00020A9E7387F002865 -:105C300003D0D849D84806F09EFF66700A2020702D -:105C400006223946A01C06F00BFEAE77012097E72E -:105C50004EE710B5CD4C343C2178002904D01321F7 -:105C60000E2000F052FF10BDC9490088091D02F046 -:105C70007FF8002801D0022007E0C54840680146AF -:105C800020318A79012A02D00C20207105E00022FF -:105C90002271097E21724088E08001206071132109 -:105CA000E1700E21A170207010BDB84810B53438D5 -:105CB0000178002904D024210E2000F026FF10BD19 -:105CC000012101702422C2700C220271417110BDA9 -:105CD00070B5AE4C0546343C2078002804D03E21F7 -:105CE0000E2000F012FF70BD03F0CFFB002808D19A -:105CF00003F0CEFB002804D1A4480C30007F00281C -:105D000001D00C2003E0287802F0C3FF00202071AE -:105D1000012060713E21E170207070BD9B4810B57C -:105D200034380178002904D03C210E2000F0EDFE2B -:105D300010BD00210171012141713C22C27001702E -:105D400010BDF8B5914C343C2078002804D03B219C -:105D50000E2000F0DAFE13E70020A07103F095FB9F -:105D60008A4E01250C36022802D0307D002840D012 -:105D7000874F694678688030807C02F003FD0028F8 -:105D800003D18449854806F0F6FE307D002806D010 -:105D9000A06D4030407A002801D0012600E00026A6 -:105DA00078688030807C02F0B9FD002804D17B48FF -:105DB0007849083006F0DFFE02F0DFFD684031462A -:105DC000014316D07968FD2249882181217E400057 -:105DD0004908490031431140014321766846007863 -:105DE000002802D00420014301E0FB20014021767D -:105DF000A5710020207165713B20E0702570BFE621 -:105E000010B5624C343C2078002804D00E2108469E -:105E100000F07BFE10BD5E4906220831A01D06F091 -:105E20001FFD00202071012060710E21E1702070A3 -:105E300010BD70B5554C0546343C2078002804D080 -:105E400038210E2000F061FE70BD50480C30007FFC -:105E5000002807D00C202071012060713821E170EA -:105E6000207070BD287802F002FF287805F0EBFB67 -:105E70000020F0E770B5454D0446343D28780028F1 -:105E800004D037210E2000F040FE70BD3F480C309A -:105E9000007F002801D00C200AE03D4E2188706868 -:105EA0004088884203D103F0F0FA022807D002208C -:105EB0002871012068713721E970287070BD716800 -:105EC0007F2020310876487600208876A2788A7173 -:105ED000E278CA7122790A72EAE710B52B4C343C99 -:105EE0002078002804D039210E2000F00EFE10BDCD -:105EF00003F0CBFA032808D003F0CAFA032804D031 -:105F000022480C30007F002801D00C2003E01F49FC -:105F100000202C31C8712071012060713921E1709D -:105F2000207010BD70B5194C0646343C207800280E -:105F300004D03A210E2000F0E8FD70BD03F0A5FA70 -:105F4000032808D003F0A4FA032804D00F480C302B -:105F5000007F002801D00C2011E00C4D2C35E87991 -:105F600008280BD20001001910223146683000F0D9 -:105F7000D6FDE879401CE871002000E00720207180 -:105F8000012060713A21E170207070BD7012002014 -:105F90005C010020845B0100210200001708000062 -:105FA000F8B5FA4E04463078002804D03D210E2082 -:105FB00000F0ABFDE4E5F5484030007F002801D05B -:105FC0000C2034E0F24D218868684088884203D173 -:105FD00003F05BFA022801D0022028E06F68648891 -:105FE000FD883A896800B988401C844218D3E94882 -:105FF00041431046E84A504306F09BFC401EFF21F7 -:1060000080B2F531884200D90846844200D2204649 -:10601000691C401C06F08DFC6D1C6843401E85B257 -:10602000E620C05D002800D1BD84F58000203071DD -:10603000012070713D21F1703070A1E5F8B5D34CAD -:1060400005462078002804D035210E2000F05DFDA3 -:1060500096E5CE484030007F002801D00C2016E0A5 -:10606000A878002801D0012804D1A888FF21F531A3 -:10607000884201D912200AE0C54F298878684088F3 -:10608000884203D103F001FA022807D002202071D0 -:10609000012060713521E170207071E5796800267A -:1060A0000846C0310E70AA884A800122A0300271D1 -:1060B000AA78012A00D000220A704079002801D075 -:1060C00003F06BFF2671E3E770B5B04C054620780E -:1060D000002804D030210E2000F017FD55E703F012 -:1060E000D4F9002804D1A9484030007F002801D00D -:1060F0000C2003E0287803F070FE002020710120BE -:1061000060713021E17020703FE770B59F4C05460B -:106110002078002804D033210E2000F0F6FC34E76C -:1061200003F0B3F9002804D198484030007F0028DC -:1061300001D00C2018E02978002911D00A290FD0AD -:1061400014290DD01E290BD0282909D0322907D0B7 -:106150004B2905D0642903D0FF2901D0122003E088 -:10616000284603F0B3FE0020207101206071332126 -:10617000E170207009E770B5844C06462078251D33 -:10618000002804D032210E2000F0BFFCFDE631468D -:10619000002002F03EFD2870002805D17C48062230 -:1061A0003146083006F05CFB012060713221E1705D -:1061B0002070EAE670B5754C2178002904D03121B1 -:1061C0000E2000F0A2FCE0E6002141560125042942 -:1061D00012D0002910D0081D0ED0001D0CD0001DBB -:1061E0000AD0001D08D0001D06D00A3004D00A30A5 -:1061F00002D01220207103E0084605F063FE6571AD -:106200003120E0702570C0E6FEB5604C074620786E -:10621000002804D025210E2000F077FCFEBD388830 -:10622000694601F0A5FD594D0146002008350029B9 -:1062300004D002212171286028710FE00098009E8F -:106240000A30019060360020B0710522284601997D -:1062500006F006FBB0790028F5D13888E0800E20E2 -:10626000A0702520E070012060712070FEBD10B587 -:10627000464C2078002804D005210E2000F045FC73 -:1062800010BD0020207102F098F9E08002F061FA60 -:106290002072012060710521E170207010BDF1B500 -:1062A0003A4C2034A07B002804D010210F2000F0AD -:1062B0002CFC65E4354D4035A8790C2610270028C4 -:1062C00016D1287F002813D103F0DFF8022824D14B -:1062D0002F4800994068098842888A421DD10146AA -:1062E000C0310A7A002A05D04030807F80070DD463 -:1062F000E6730EE05E22125C920707D406220A7251 -:10630000A0304079002801D003F047FE2F7700200D -:10631000E07327740120A07332E40220F8E710B57F -:106320001A480178002904D00F210E2000F0EDFB5F -:1063300010BD00210171FF2181710021C94301813C -:1063400013490E310A7882728A8882814988C18114 -:10635000012141710E2282700F22C270017010BDA6 -:1063600010B50A4C2078002804D02B210E2000F014 -:10637000CCFB10BD0821A01DF5F7DBFC002020712F -:10638000012060712B21E170207010BD3C120020B3 -:106390005C010020C40900001027000070B5FA4D10 -:1063A00004462878002804D02A210E2000F0ADFBF6 -:1063B000EBE5F54810222146303800F0B0FBF248FA -:1063C0001022A118203800F0AAFBEF483038F5F76A -:1063D0001EFFED49102210392C46A81D00F09FFB2E -:1063E000002020710E20A0702A20E0700120607132 -:1063F0002070CAE5F8B50546E348E34C403000900C -:10640000007F0C2628272034002801D0E6733EE0C8 -:10641000A07B002804D028210F2000F076FB04E4A4 -:10642000A87805280DD013280BD0142809D01528DA -:1064300007D01A2805D0292803D03D2801D03B28B1 -:1064400003D12888D149884201D912201EE003F0E7 -:106450001CF80228DAD1CE482A8840684188914247 -:1064600013D10146C0310A79002ACFD1AA784A71E6 -:1064700001220A710099A0300F770021E173407961 -:10648000002804D003F089FD01E00220E0732774A6 -:106490000120A0735FE4F8B5BB4F064638783D1D78 -:1064A000002804D017210E2000F02FFB53E43146C2 -:1064B000012002F0AEFB01242870002807D1B24869 -:1064C000062260303146054606F0CAF9AC717C718F -:1064D0001720F8703C703EE470B5AB4C064620784F -:1064E000002804D00B210E2000F00FFB4DE502F038 -:1064F000CCFF032808D002F0CBFF032804D0A24829 -:106500004030007F002801D00C2016E03378002BAB -:1065100003D0012B01D012200FE09B4DE035297AEA -:10652000082909D22846721C0C3005F07AFC287A1A -:10653000401C2872002000E00720207101206071BB -:106540000B21E170207020E510B58F4C20780028D9 -:1065500004D00A210E2000F0D8FA16E702F095FFC9 -:10656000032808D002F094FF032804D08648403066 -:10657000007F002801D00C2002E000F0BFFA0020CC -:106580002071012060710A21E1702070FDE610B5D4 -:1065900003F0C2FB002803D07E497F4806F0EBFAE7 -:1065A00001F0DBFF04F0E1FE002804D01720794958 -:1065B000400106F0E0FA02F03CFA002804D0B920CD -:1065C0007449800006F0D7FA00F098FAFFF7F2F865 -:1065D0006D4800210171012141710222C2700170D8 -:1065E000D3E610B5684C2178002904D020210E2074 -:1065F00000F08BFAC9E601781F290ED8411C0CD097 -:10660000002121710278411C104602F01FFB01207D -:1066100060712021E1702070B7E612202071F6E74A -:10662000F8B5594C2178002904D01B210E2000F028 -:106630006CFABFE401216171534E0C212171403687 -:10664000317F00296FD10078514F0025012804D0F7 -:1066500000284AD01220207165E002F016FF0028C1 -:1066600003D102F015FF002804D002F00EFF02282B -:1066700022D058E002F01FFA002854D0307D0028C4 -:1066800051D1786801224580032101F044FE7868E9 -:1066900002F0EAFB7868923001F091FF002803D104 -:1066A0003C493E4806F067FA03F09BFB002839D0CE -:1066B00085203849C00015E002F0EAFE002832D1FA -:1066C000707F00282FD001282DD004282BD002F075 -:1066D000F2F9002827D003F084FB002822D02F48AD -:1066E0002C49183006F047FA1CE002F0CEFE0328D1 -:1066F00004D002F0CDFE03280FD014E0002003F0F8 -:1067000095FA00280FD12571307D00280BD17868CB -:106710008030807CFFF734F805E0002003F086FA33 -:10672000002800D125711B20E0700120207041E479 -:1067300010B5154C2178002904D01A210E2000F044 -:10674000E4F922E601781F290ED8411C0CD0002163 -:1067500021710278411C104602F08DFA012060710F -:106760001A21E170207010E612202071F6E770B552 -:10677000054E044630780C25002811D018210E2033 -:1067800000F0C3F9AAE400003C120020FF0E000054 -:106790005C010020845B0100D3020000240400009F -:1067A00002F073FE03285AD002F072FE032856D07E -:1067B000E14A107F002852D16079002801D00128D9 -:1067C0002DD1A079002801D0012828D1A07B002854 -:1067D00005D0012803D0022801D003281FD1607BF7 -:1067E00000281CD0C0081AD1618801208003814292 -:1067F00002D82388834203D9207901280FD119E0D8 -:106800002079002806D0012814D0022805D00328BA -:1068100005D102E020290BD30CE0A02B0AD220796D -:10682000042805D12088202802D36188884201D914 -:10683000122514E0207950776079002802D00128D1 -:1068400003D00CE0BD4A002105E0BB4A203290791C -:10685000002804D00121204602F05EF905460120FF -:10686000357170711821F170307037E470B5B24C29 -:106870000546403C2078002804D02E210E2000F050 -:1068800044F92BE402F001FE0C22022815D1AA489B -:10689000007F002811D1A9482B8808384168488812 -:1068A00083421AD10846C030037A002B05D120312B -:1068B000C97E0F2903D0102901D0227103E00521E0 -:1068C0000172002020710E20A0702E20E070288818 -:1068D000E08001206071207016E40220F2E770B5BC -:1068E000954C0546403C2078002804D02D210E20F0 -:1068F00000F00BF908E402F0C8FD0C21022814D1C5 -:106900008D48007F002810D18C4E2A88083E706880 -:1069100043889A4220D1C822125C002A05D13B222A -:10692000125C0F2A03D0102A01D021710AE0102234 -:10693000A91CD63005F094FF70680421C0300172A4 -:10694000002020710E20A0702D20E0702888E080AB -:106950000120607120700DE40220F2E710B501788B -:106960000B0006F021FA3F9E9E399E9E599E9E9EE8 -:106970009E3C3F9E9E8752559E9E999E9E9E432979 -:106980009E2D319E9E9E9E359E9E9E955C9E9E4710 -:106990009E4B4F9E21259E6C6064689E709E7F83F7 -:1069A0007C788A8D74919E00801CFFF798FF76E0BA -:1069B000801CFFF75BFF72E0801CFFF7D8FE6EE0E3 -:1069C000801CFFF7B5FE6AE0801CFFF729FE66E039 -:1069D000801CFFF706FE62E0FFF7D9FD5FE0FFF7DE -:1069E000B3FD5CE0801CFFF777FD58E0801CFFF7EB -:1069F00052FD54E0801CFFF7FDFC50E0801CFFF7C7 -:106A0000CDFC4CE0FFF7ACFC49E0FFF788FC46E02A -:106A1000801CFFF744FC42E0FFF729FC3FE0801CAC -:106A2000FFF7F2FB3BE0801CFFF7C4FB37E0801C64 -:106A3000FFF7A1FB33E0801CFFF767FB2FE0801C12 -:106A4000FFF742FB2BE0801CFFF7F8FA27E0801CE1 -:106A5000FFF7A6FA23E0801CFFF764FA1FE0FFF7B8 -:106A60003CFA1CE0801CFFF705FA18E0801CFFF7D9 -:106A7000E0F914E0FFF7C4F911E0FFF762F90EE066 -:106A8000801CFFF74BF90AE0801CFFF721F906E0B4 -:106A9000801CFFF70AF902E0801CFFF7DAF80120FA -:106AA00073E4002071E470B52349244C0546403955 -:106AB000083C0A460126403260682B0006F074F953 -:106AC00005171A1A04171A000122002101F023FCED -:106AD000616800220846C0310A724A7203F0F7F971 -:106AE000002803D016A11B4806F045F860E416758F -:106AF00088655DE4174812A13330F5E70E490020A0 -:106B0000C031C8612039087270470B4A203A937E21 -:106B1000002B03D1D076117701209076704730B5E5 -:106B2000134606E0CC18203CE47FD51A44555B1E82 -:106B3000DBB2002BF6D130BD7C12002064010020B6 -:106B40007372635C6C6C5F6374726C2E73302E6353 -:106B5000000000005108000010B505F0BFF8F5F77F -:106B60004CF8EBF751FCF5F7FFFA04F0C1FF05F024 -:106B700041F810BDFFB593B0044600201D9E04905F -:106B800015981C9D1027082806D0E06901F014F81C -:106B9000002809D03770CCE02888092138432880A4 -:106BA0001F980227017016E0E16901208871052114 -:106BB000E269C9029180E1698872E169F948088156 -:106BC000E16900208873288820210843288011214A -:106BD0001F98042701701F980225801C03903078AD -:106BE00010900A203070204618301190F6F799FC6A -:106BF00000206FE01598102809D1022D07D06846B3 -:106C0000828A04990398401A8270110AC1706846FA -:106C1000C08A1699884203D9E349097A149106E09B -:106C2000884204D11099002901D0317021E00399E4 -:106C30000870000A48701E980088401BC01B83B271 -:106C4000FF20C01B984200D203460398149AC01933 -:106C50000CA90092019002912020015D6846C08A33 -:106C60000022F6F7D3FC3070002806D0C0B283288B -:106C700062D06846C08A208345E00F98002805D07E -:106C8000C948006800790A2830D33CE06846008E85 -:106C9000C119C9B20491022D0FD01F99049A4978E5 -:106CA000914203D16A46128C824209D0BE480491B7 -:106CB00000680178032909D027E008461F99487029 -:106CC000B94800680178042906D008E000790A284C -:106CD0001BD201200F9009E06946C98A818003997F -:106CE0000498081803900498281885B205AA1499E6 -:106CF0001198F6F719FC002805D11E980088401B52 -:106D0000B84200DB76E7022D0ED01598102807D187 -:106D1000049A03996846808A891A8870000AC870A4 -:106D20001E980580002030709F4800680078032876 -:106D300002D0002017B0F0BD0220FBE7F8B50446F2 -:106D4000406B0026134600282BD0491F8DB2618F5F -:106D50002A460832278F8A18BA4221D89A784018D2 -:106D60005F78110239430170090A41701A79DF789E -:106D7000110239438170090AC1700571290A4171F4 -:106D80002A46591D801D05F06BFD608FAD1D401911 -:106D900080B26087626B002110180170417000E0C2 -:106DA00009263046F8BD30B50B88048F9C4212D9B5 -:106DB000446BE0184478057824022C430BD04479C6 -:106DC000057924022C436404640CA41D1B190B8058 -:106DD0001060002030BD822030BDF7B588B000259E -:106DE0006846058205275DE00398417802780E0227 -:106DF00016434179027908021043000452D40A98DC -:106E00000123068005A802905B02002200970195ED -:106E100030460999F6F7FAFB04004AD16846018A20 -:106E2000018303984179027909021143437802787A -:106E30001C021443B4421ED10A041CD44B04012189 -:106E40005B0C890300950B4301970295C17880780C -:106E50000A02024320460999F6F7F4F9040011D119 -:106E6000039948790A79000210430122D2031043A2 -:106E70000871000A487103AA06A90898FFF793FF52 -:106E80000400CED0039900950197029548780978BF -:106E90000002084369468B8A00220999F6F7D2F965 -:106EA000822C06D103AA04A90898FFF77CFF0400EE -:106EB0009AD06846058209E003984179027909026F -:106EC00011434904490C0171090A417103AA04A93B -:106ED0000898FFF768FF0028EED0822C02D02046E9 -:106EE0000BB0F0BD0020FBE730B50446406B002539 -:106EF00097B000280DD00B2268460270228F0281C5 -:106F0000606B0391019000216846FCF7D8F8684651 -:106F1000057065636587258717B030BDF8B50F46E6 -:106F20000546696B0020069E144600290FD0012BF0 -:106F30000DD1324639462846FFF74FFF002806D1CB -:106F4000002C04D032463946284600F044FEF8BDF5 -:106F500000220280C262831D0263C36142634287D2 -:106F6000028720300170704710B50022D2430280A2 -:106F70000420F5F7BAFB10BD10B596B00446FFF734 -:106F8000B3FF208E002808D0012069460870E06A0F -:106F9000019000216846FCF792F80020E06220632F -:106FA00016B010BD012800005C13002001460988BE -:106FB00000200A0700D501200A06120F01D0022284 -:106FC0001043CA0501D5042210438A0501D51022B9 -:106FD0001043490501D5202108437047FFB5A9B0EA -:106FE0000600329D359C2B981F46229016D00078C3 -:106FF00041060FD48106890E1E2909D021884A0531 -:10700000520E0BD13A88172A08D3FE4A914205D076 -:10701000C10906D08006800E122802D003202DB0B0 -:10702000F0BD20462C302690F7492A98087200209F -:1070300018AA039010726A46107404AA0A60339A60 -:107040004A6020AA90809081229800780190810661 -:10705000681C1C90701F1D902B98890EC21C2492D6 -:10706000224620321B92083A401C02920B0005F087 -:107070009BFE1FFDFD11FD1FFD8EFDFCFDFBFDFABE -:10708000FDF9FDFCFDF8FDFDFDF7FDF6FDFDFDFD47 -:10709000FDF5FD00032E76D102E018A9087219E370 -:1070A000032028701C9917220A7000224A70CFE230 -:1070B000052EF0D14178027808021043208320A9E0 -:1070C0008880249A5178127809021143618300283C -:1070D0007ED088427CD800202072E080401E6084F0 -:1070E0000298F6F71EFA05202870A81C01900220CD -:1070F00000901BAA2A990298F6F716FA002868D180 -:1071000018A8807C012803D002206870102002E0BB -:107110000120687002202490002225A91CA8F7F7FE -:1071200034FE00282BD120A8007D2499814226D14D -:107130003A880099801C511A814220DB10A8C18D29 -:1071400001980170090A417001991CA8891C0191DC -:107150000099019A891C009125A9F7F716FE20A82D -:10716000007D01991BAA091801910099081880B2A5 -:1071700000902A990298F6F7D7F90028CCD0009809 -:10718000022826D064E272E018A9087261E2072E94 -:107190006DD341780346027808021043208320A96A -:1071A0008880249A5178127809021143618300285B -:1071B0000ED088420CD8012020725879197900022B -:1071C0000843E08000202073E06900F0F5FC01E056 -:1071D00098E0A9E000280ED1E1690120887105211D -:1071E000E269C9029180E1698872E1698748088192 -:1071F000E16900208873F01F60842298C01D6062DE -:107200000298F6F78EF907202870681C009001207C -:107210000190002010A9C8852FE00198012814D002 -:10722000E0698079012830D000981E38417F007FC6 -:107230000902014300980170090A41700098801CFE -:1072400000900198801C80B2019010A8C18D009818 -:107250000170090A41700098801C09E00AE296E179 -:107260003BE1DFE004E29BE077E036E016E2AFE0EE -:1072700000900198801C80B201901BAA2A99029864 -:10728000F6F752F9002803D007E010A8818DD1E766 -:1072900039880198081A0428BFDA0198012843D0D8 -:1072A000E0698079012804D010A8818D5548814279 -:1072B00006D110A8818D00980170090A417009E07B -:1072C00000981E38417F027F080200991043087021 -:1072D000000A48700198801CBAE1072E01D0152ED3 -:1072E00076D14178027808021043208320A9888053 -:1072F000249A51781278090211436183002801D041 -:10730000884201D901203FE7012020720020E0805F -:107310002073052E0AD01D982299E269C0B2491D3A -:10732000F7F70DFD002801D00A202DE70020C0430B -:1073300060841AA8019023A92298029703950091CE -:10734000007800238206920E20462A99FFF712FC4D -:107350000390208B20A988807BE1032EC0D140229E -:1073600020A98A814178027808021043208320A94D -:1073700088802A991EAB1C9A029301920091398849 -:107380000022491E8BB21B990978F6F73FF918A91C -:107390000872002833D10B20287010A8008F3FE01E -:1073A000052E9DD1802220A98A8141780278080289 -:1073B00010432083249984464A78097812020A43AC -:1073C000628420A988801248824202D30720DBE62B -:1073D000AFE03F208002024362842A981FAB1C99D1 -:1073E0000293019100903888401E83B21B98017867 -:1073F0006046F6F70BF918A9087200280CD083280C -:10740000AAD107E0FFFF00005C1300200128000064 -:10741000010200000220B8E00D20287010A8808F23 -:10742000401C15E101990C22C9095143C91CB14204 -:1074300004D9019840067CD5002009E14278037800 -:107440001002184320AA90808446229800784006B3 -:1074500009D505206A46107422980078C00905D025 -:10746000002010741DE106206A46107424981F90B5 -:107470002A9A00900023701A029383B21E90019200 -:107480001B98002201786046F5F7DCFE18A9087207 -:10749000002269460A74832801D1022003902298B1 -:1074A000007840060DD52088C00506D520A9208B80 -:1074B0008988884201D100206062002018A90872E2 -:1074C000C6E0FF21013120A88181808820831E9899 -:1074D00060841F9860621320B8E0052E29D341789C -:1074E00002780802104320A98880218F002902D049 -:1074F000FE4A914206D10A216A4611740121C9430C -:10750000218702E007216A46117422992A9A491DAF -:107510000192009101221D990023D203029311438D -:107520008BB224994A78097812020A431B99097888 -:1075300000E0C9E0F5F786FE18A908720022694646 -:107540000A740122520220A98A81832808D00028C7 -:1075500009D0218FE54881427ED10020208778E044 -:10756000888820834DE7606B002808D0314620468C -:10757000229AFFF7E3FB18A90872002869D12B466D -:107580003A463046229900F056FB039061E022987B -:10759000022E407801907DD1002801D0012879D1B8 -:1075A0000820694608740198087521A800901B9866 -:1075B000002201782046019BFFF7B0FC69460022BB -:1075C00048758A75002802D10198012809D0208FBA -:1075D000002806D0002008740120800220A988819C -:1075E0000EE004A83399FBF76AFD0390002069467A -:1075F00008740120800220A988810398022807D0FE -:10760000BB4800688079002805D018A908722BE0D3 -:10761000019820831DE00398002803D0812018A939 -:10762000087240E021A800901B98012201782046B2 -:10763000019BFFF773FC18A9087220463499FFF7E5 -:1076400053FC18A9087A002803D1192028700120BA -:1076500038806846007C00E03CE0002804D004A8A4 -:107660003399FBF72CFD0390039800282ED01AE0E5 -:10767000062012E52078000713D5012E11D109212B -:1076800068460174A188818204203499F5F72DF8A9 -:10769000082100E005E020A88181CDE601984006A0 -:1076A00012D50320039020A92088898908432080CF -:1076B00020A988894005400E04D026992B9808609F -:1076C000269886800398AAE40420E6E418A8007AA5 -:1076D00000280ED00120287022980078687020A819 -:1076E0008088A870000AE87018A8007A2871052020 -:1076F000388020A92088898988432080E2E7FFB567 -:107700000746A1B000201C903A7801209040794AA9 -:107710007C68104010AA1087744B22885B1C9A4228 -:1077200003D0002804D0100702D5012025B0F0BDF9 -:10773000249E0020307023980025028810A802851E -:1077400018A805756A4B68461972057404A8186074 -:1077500020462C301B902A985860249E94463878F6 -:10776000721C0521039201282DD0022808D003287D -:107770007DD13078800980011D303070B889A080BB -:107780003878022804D13078800980011B303070AD -:10779000F01C1FAA01900292009110A8008D0022F7 -:1077A000C01E83B22020015DB889F5F72FFF0028A5 -:1077B000DED10398B9890170090A417010A9888F38 -:1077C000C01C088528E1787B18AA10753A7B012A2D -:1077D00002D0022ACCD1FCE022887F231B011A4070 -:1077E00010AB1A87802A4AD006DC102A10D0202A33 -:1077F0000ED0402A0AD124E0FF3A013A65D0FF3A80 -:10780000013A79D0FF3AFF3A022A76D00525A2E064 -:107810002078C00601D5082000E010201C9004202C -:107820006A461074002090821AA81DAA1EAB039607 -:107830000192029000933B8A20461C9AFFF79AF926 -:1078400084E0228B3B8A9646934268D10A221C929E -:10785000002839D1039801906046401E1FAA83B2C8 -:10786000029220200091015D0022704600E0BAE003 -:10787000F5F7CCFE014618A801750B201AE0228B03 -:107880003B8A964693424AD10C221C92002862D130 -:107890000398019060461FAA401E0292009183B295 -:1078A0002020015D628C7046F5F7B0FE014618A8F5 -:1078B00001750D20307010A8818F491C01850421AD -:1078C00068460174218B818245E0238B3A8A9C466D -:1078D0009A4224D112221C9200283CD1606A0028CE -:1078E00013D000226B4607C3638C07E0FEFF000045 -:1078F0005C13002009F800000DE04BE02020015D42 -:107900006046F5F79FFC18A9087513203070012018 -:1079100010A908851FE0398A228B914201D00425E5 -:10792000B6E016211C91002815D11B9881880268A9 -:107930002046FFF703FA18A9087500280BD11B98F9 -:107940003346016880881AAA00F075F905460228B6 -:107950001BD0042D19D01B988088002811D06846B0 -:10796000007C002804D004A82A99FBF7A8FB054650 -:107970000120694608741B981B9900680590002037 -:107980008880002D48D0052D2ED06846007C032825 -:1079900078D07DE018211C91002806D0388A2083F9 -:1079A0002046B968FFF7A0FAD5E7204618300090C6 -:1079B0002020015D237E01222046FFF7AFFA18A99F -:1079C00008750028ECD119203070012010A9088515 -:1079D000E6E7208801214902084010A90887FF38FE -:1079E000FF38022806D0052510A92088098F884372 -:1079F00020804DE0208F9849884290D116201C901D -:107A00003869002805D06063B88A20870020608725 -:107A100002E00020C043208710A8008F7F210901C9 -:107A200002468A430DD0782300220420B968F4F777 -:107A3000B7FD3878A07010A92088098F08432080EE -:107A400002E02188814321806846007C002805D01F -:107A50008248416804A8FBF732FB054618A8007D60 -:107A6000002815D01C98707001203070208BB070E9 -:107A7000000AF07018A8007D3071052110A801855A -:107A800006E0FFE77548416804A8FBF718FB0546C8 -:107A90007248017A20884005400E22D11B988088C8 -:107AA00000281ED0239A0026138810AA1385249A32 -:107AB0002A9B6F464CC71B9A039412681AABFFF7B8 -:107AC0008DFA054602280CD00120694608741B98DF -:107AD0002A990068059004A8FBF7F1FA05461B985F -:107AE000868010A8018D2398018028461EE600B5E7 -:107AF00097B0042807D102206A4610700191002136 -:107B00006846FBF7DCFA17B000BD10B5534C03789C -:107B100000222168012B02D0022B42D126E00B78F3 -:107B2000002B01D0042B03D10A71226803211170AC -:107B3000216883880A79D200921D8B5221680A79C4 -:107B4000D20008328918C2880A80216803890A791C -:107B5000D2000A328B52428920680179C9000C3167 -:107B6000425221680879401C08711EE00A7482881C -:107B70008A802168C288CA802268018911812268AE -:107B800041895181C1682068C1606168FBF797FA3B -:107B90000146022807D02068007C002802D1002975 -:107BA00003D0812010BD832010BD002010BD406B8C -:107BB000002800D0012070478178012909D1008870 -:107BC0000521C902884202D0491C884201D1002007 -:107BD000704705207047F7B586B000246846154603 -:107BE0000F46848105261AE004984178027809023C -:107BF00011432980811D01960294009141790279F7 -:107C00000B021343C178827809020A434178007855 -:107C1000090208433946F5F715FB002806D104AAE6 -:107C200003A90698FFF7BFF80028DDD0822800D10D -:107C3000002009B0F0BD10B51488844201D205209F -:107C400010BD17241C701080421E581C491C04F0E3 -:107C500007FE002010BD0000FEFF00005C130020A6 -:107C600030B50346002002460DE09C5C2546303DC1 -:107C70000A2D02D30020C04330BD0A2568433038A6 -:107C80002018521CD2B28A42EFD330BD70B50D46D7 -:107C9000144608E00A2104F04CFE2A193031203A3B -:107CA000641ED177E4B2002CF4D170BD10B500236E -:107CB00010E0040A00020443A0B2CC5C4440200659 -:107CC000000F60400407240C44402006C00C6040B4 -:107CD0005B1C9BB29342ECD310BD000010B5404832 -:107CE000F4F7F8F8002801D00C2010BDFF21113165 -:107CF0003C4804F014FE3B490120087000204880F5 -:107D0000E031887188748875203108713448F4F73F -:107D1000F9F8002010BD10B53148F4F7D3F8002869 -:107D200003D031A1312004F026FFFFF7D7FF002850 -:107D300003D02DA1382004F01EFF10BD10B504465D -:107D40002748F4F7C7F8002801D00C2010BD2549BA -:107D50000878002807D00020087021482160F4F737 -:107D6000D1F8002010BD1E48F4F7CCF81F2010BD3C -:107D700070B505460C461A48F4F7ACF8002801D057 -:107D80000C2070BD174A5088A84202D110780028F4 -:107D900004D01348F4F7B6F8122070BD10482260E2 -:107DA000F4F7B0F8002070BD10B504460C48F4F7A5 -:107DB00091F8002801D00C2010BD0A480178002954 -:107DC00007D00020C04320800548F4F79BF812201C -:107DD00010BD408820800248F4F794F8002010BDC0 -:107DE00070010020681300207372635C6C6C5F6428 -:107DF000622E630010B5282104F08FFD10BD70B510 -:107E0000054600780A0700090001120F1043287088 -:107E10000B0004F0C9FF07050705070509050B005E -:107E2000062408E00C2406E0222404E00024F2A149 -:107E3000572004F0A0FE6878800980012043687014 -:107E400070BD00780007000F704710B50622C01CF7 -:107E500004F006FD10BD10B50622093004F000FD47 -:107E600010BD0278BF23C9071A40490E0A430270A9 -:107E7000704702785206520EC9010A4302707047D9 -:107E800070B515460E4604461F2A03D9DAA1A8206C -:107E900004F071FE20462A463146093004F0E0FC29 -:107EA0006078AD1D80098001A906890E08436070C5 -:107EB00070BD70B515460E4604461F2A03D9CEA1E3 -:107EC000CC2004F058FE20462A463146093004F002 -:107ED000C7FC6078AD1D80098001A906890E0843A2 -:107EE000607070BD70B501780907090F03292ED0A5 -:107EF000052931D1411C827E0C46437E1102194373 -:107F0000037FC27D1D02037EC67E1B021343827D5A -:107F1000407835438006800E22281DD106291BD3C8 -:107F20001920C001814217D8FF26F436B54213D874 -:107F3000002A11D0082A0FD88A420DD28B420BD8C2 -:107F4000617F227F09021143814207D904E0407812 -:107F50008006800E0C2801D0002070BD012070BD6D -:107F600000210A464254491C2229FBDB704710B508 -:107F700002788B07920892009B0F1A430270427896 -:107F8000520952014270012908D0022906D0032962 -:107F900005D0FF2098A1EE3004F0EDFD10BD0121C9 -:107FA0000A43427010BD10B502788B079208920008 -:107FB0009B0F1A4302704278520952014270012904 -:107FC00007D0022905D0032904D08BA18E4804F0E4 -:107FD000D2FD10BD01210A43427010BD0078800718 -:107FE000800F70470278EF23C9071A40C90E0A4371 -:107FF0000270704770B50546C1700B0004F0D4FEE6 -:108000000E080A0C0E1012120C14141212160C1870 -:108010000C2413E0082411E002240FE017240DE0E3 -:108020000D240BE0012409E0092407E0062405E003 -:108030007548002470A1A03004F09DFD68784009C7 -:1080400040012043687070BDC0787047017AC279E2 -:10805000080210437047817A427A08021043704741 -:10806000017BC27A08021043704781794279080285 -:108070001043704700797047817B427B08021043B0 -:10808000704770B5017AC37909021943431C857A98 -:108090001C46467A2B023343657926792C023443F9 -:1080A000C21C5A4E00798D1FB54214D8FF25F435F5 -:1080B000AB4210D800280ED008280CD888420AD22B -:1080C0008C4208D8507A117A00020843B11D8842C8 -:1080D00001D8012070BD002070BD0B4610B5011DF8 -:1080E0000522184604F0BCFB10BD817A427A0802D2 -:1080F0001043704701717047007970470B4610B507 -:10810000011D0822184604F0ABFB10BD027B0A706B -:10811000407B487070470B46014610B508220E316F -:10812000184604F09DFB10BD0B46014610B5042215 -:108130001631184604F094FB10BD10B50822001D3E -:1081400004F08EFB10BD10B504220C3004F088FB47 -:1081500010BD017170474171090A81717047C17189 -:10816000090A0172704700797047817942790802E3 -:1081700010437047017AC2790802104370470171B9 -:108180007047017170470B4610B5011D0822184653 -:1081900004F066FB10BD10B50822001D04F060FB62 -:1081A00010BD70B515460E4604461B2A03D912A110 -:1081B000174804F0E0FC2A463146E01C04F050FB6E -:1081C0006078E90640094001C90E0843607070BD3F -:1081D00070B5054640780E46C406E40E1B2C04D943 -:1081E0000B4805A10C3004F0C6FC2246E91C3046C1 -:1081F00004F036FB204670BD7372635C756C5F7073 -:1082000064752E6300000000070200007A0C000075 -:10821000F7030000C1074008C207C90FD20F511869 -:108220004008C207D20F51184008C207D20F511898 -:108230004008C207D20F51184208D007C00F40189B -:108240005208D107C90F091850084018704700227A -:1082500002808271C271C272027342738273827031 -:10826000C270027142714276828303464284203397 -:108270009A7102859A72C2750276C2730274DA72BA -:108280001A739A7319750284FF21603081709A7590 -:10829000704770B504460020A083208C1E464843DA -:1082A0001546114604F053FB2084F000294604F0E3 -:1082B00040FB401C80B20146192269439202E083D0 -:1082C000914201DD401EE0837D202946000204F03A -:1082D00030FB401CA08470BD70B50546087B0E467F -:1082E000C006C00E08730020A87504463019007A35 -:1082F000FFF790FF29194874A97D641C0818E4B29F -:10830000A875052CF2D3C0B2252803D979A18A20FB -:1083100004F031FC70BDF8B50446303026462746DF -:108320002546C036A03780350090032909D00029A2 -:108330001AD0012924D0022902D1A11CFFF7CCFFB9 -:10834000F8BD1146FFF783FF002028836883A883C8 -:10835000E883288468847871E88538732621085575 -:10836000A08430703071F8BD0020E885B871A18814 -:1083700023890A460098FFF78CFFA11C0098DDE7CF -:108380000020E885B38A328AA1880098FFF781FF30 -:10839000F8BD70B5867D0D460446002E01D0252E11 -:1083A00001D9122070BD002A18D0287EE17D5043EB -:1083B0000818252104F0BDFA0846E1754207520F5E -:1083C000C908504B69189A5C097A8A4368D03146CB -:1083D00004F0AFFA491CCAB2002007E0002070BDCB -:1083E000002803D02118097C511ACAB22118497CEF -:1083F00091423AD32918097AC943CB07DB17D21A1D -:10840000521E1206120E35D08B07DB17D21A521EDF -:108410001206120E30D04B07DB17D21A521E12066C -:10842000120E2CD00B07DB17D21A521E1206120E98 -:1084300028D0CB06DB17D21A521E1206120E24D0F9 -:108440008B06DB17D21A521E1206120E20D04B06D4 -:10845000DB17D21A521E1206120E1CD00906C917BB -:10846000511A491E0A06120E18D0401C0528B7DB07 -:108470001F2070BDC00013E0C000401C10E0C00011 -:10848000801C0DE0C000C01C0AE0C000001D07E019 -:10849000C000401D04E0C000801D01E0C000C01D00 -:1084A00020769BE738B505460C46684603F0E0FEAB -:1084B00000281ED069460020085620720921615606 -:1084C0000022411A00D5494220356B798B420FDCDE -:1084D000FF2B0DD0A17A491CC9B2A172AB79994288 -:1084E00002D8617A7F2903D160720020A072012234 -:1084F000104638BD7372635C6C6C5F7574696C2E6A -:108500006300000066CF010010B5040004D0FF2016 -:10851000FAA1AB3004F02FFBFB4821464143FB4856 -:10852000FF230918FF330022581C5A544254C81D17 -:10853000FF30FA3002704270F448001FC378A34243 -:1085400002D18270FF23C370EF48EF4BC01E0818A2 -:108550009B1EC91802700A7010BD70B5EB4800264A -:10856000001F8670FF24C47035462846FFF7CCFFF5 -:108570006D1C2D062D0EF8D00020E4490B2292012F -:10858000E14B43435B189B181E74401C0006000E11 -:10859000F6D0DF48FFF7E4FC0021DD48FFF722FDBD -:1085A0000121DB48FFF7E3FCDA4804704470847073 -:1085B000C4700471447170BDCFE71B20704730B5A3 -:1085C0000021D24A0B239B01CF4C4C43A418E41842 -:1085D000247C002C05D0491C0906090EF4D000208B -:1085E00030BDC94C01254C43A218D2181574017036 -:1085F000284630BD10B5044600F0D0F900280CD054 -:108600002046FFF781FFC0490B224C43BF490020A1 -:108610006118920189180874012010BD10B5044634 -:1086200000F0BCF9002802D0BA484471012010BD06 -:10863000034610B5B748B44940794843B349421896 -:108640001046FF30E130C17F807F04F00DFC10BD8B -:1086500010B5B048AC4940790F224843AB494018A7 -:10866000A949D239095CFF30FF3004F0D7FB10BDB7 -:1086700010B5044600F092F9002802D0A548047114 -:10868000012010BD034610B5A2489F490079484318 -:108690009E4942181046FF30E130C17F807F04F0D0 -:1086A000D0FB10BD70B59B4C97492079974D48433E -:1086B0004019C11DFF31F931FF30E130807F0F22B9 -:1086C00004F09CFB002813D020798F4948434019BF -:1086D000FF30FF3002300178491C0170017840788A -:1086E000814204D1884885A1773804F044FA0120FA -:1086F00070BD884884490079484384494018FF3058 -:10870000E130C17F807F814201D10120704700208C -:10871000704770B57F487C49007948437B494018D1 -:10872000FF30E130867FC57F0F242946304604F0B4 -:108730005EFB002801D0204670BD70066906400E21 -:10874000490E884201D3401A01E0081A201AC0B22B -:1087500070BD0F20704770B50C46054600F01EF93D -:1087600000280ED00020207067484543674828182D -:10877000FF30FF300230017842788A1A227041704F -:10878000012070BD70B50C46054600F007F90028C1 -:108790000BD05D4845435D482818FF30FF3002305C -:1087A00001784078081A2070012070BD5849016096 -:1087B000704710B5044600F0F1F8002802D0554883 -:1087C0000470012010BD5149091FCA78FF2A02D048 -:1087D0000021016007E08A784C492439012A02D03F -:1087E000016001207047002070474848801E0178D2 -:1087F000012908D001210170464801784348001F33 -:10880000C170012070470020704710B5044600F089 -:10881000C5F8002802D03F484470012010BD3B49F4 -:108820003C4B091FCA785B789A4206D18A78203976 -:10883000002A02D0016001207047002070473348B1 -:10884000344A001FC1785278914209D1FF21C1708A -:10885000801C0178002903D000210170012070479D -:108860000020704729482B4A001FC1785278914256 -:1088700004D18078002801D0002070470120704783 -:1088800010B5044600F08AF8002802D02148C470D0 -:10889000012010BD034610B51E481B49C07848434F -:1088A0001A494018C21DFF320B21FC3289014018C1 -:1088B000C17B807B04F0D8FA10BD10B51548124971 -:1088C000C0784843114940180B2189014118C97BE0 -:1088D0000D4AD21E8018062204F0A0FA10BD0D48E1 -:1088E0000949C0784843094941180B2080010818FC -:1088F000C17B807B81420FD1012070477372635C22 -:10890000646D5F712E630000D10200009C14002092 -:108910006D170020710100200020EEE710B504461D -:1089200000F03CF8002802D021488470012010BDDE -:10893000034610B51E481F49807848431E49401819 -:10894000C21DFF320B21FC3289014018C17B807BA4 -:1089500004F077FA10BD10B51548164980780B223F -:1089600048431549920140181249891E4118801840 -:10897000807B062204F042FA10BD0D480D49807834 -:1089800048430D4941180B2080010818C17B807BAA -:10899000814201D10120B0E70020AEE7002805D1D7 -:1089A0000648007C002801D00120A6E70020A4E7AB -:1089B00071010020D10200009C1400205C170020EF -:1089C000F8B5FF4E0446B079002500280AD00029EA -:1089D0002DD1657010202070F079A070307AE07091 -:1089E000B57124E0F64F203F387A012804D0707A20 -:1089F000012810D00020F8BD002918D1657013207F -:108A0000EF4920701C221639A01C03F029FF012019 -:108A1000A0713D720BE0002909D165701420E8496E -:108A2000207008220A31A01C03F01AFF7572012081 -:108A3000F8BDF8B5E3480178002902D00C2630468D -:108A4000F8BD0026DE4D3446403D2E756E75EE7540 -:108A50002E76AE75294620396E730F464E73403719 -:108A60007E717F218170687E002804D003F0E5FBD1 -:108A700003F066F86C763C72D14884711430FFF7CD -:108A8000B9F9CF483C30FFF7B5F9D8E710B5CD4B71 -:108A900000221A70CA4B203B1A711A46603A1166BE -:108AA000D065FFF7C6FF002804D0FF20C6A187309D -:108AB00004F061F810BDC2484038007D7047C049DD -:108AC00010B54039C87B897B42078307D20FDB0F83 -:108AD000D218C007C00F101840000B0004F064F952 -:108AE000050B060B04080F00BB4906E0BB4810BD90 -:108AF000B949083101E0B8490839085A10BDFF20CA -:108B0000B1A1A73004F037F8002010BDAC48B4493B -:108B10004038008A48437047F8B5A94C0646407B68 -:108B2000403CE07337791346A773012F26D0308875 -:108B30002082A348B27B203882710546603D2970AF -:108B400006221946681C03F08BFEB0796873062272 -:108B5000F11DE81D03F084FE607B0126002800D093 -:108B6000667597486038407B002800D0A6753B00AA -:108B700004F01AF90506082549084B000020D7E73C -:108B800000211DE08E4801211430FFF738F98C4890 -:108B9000E91D1430FFF75FF9687B002807D0012832 -:108BA00007D0FF2088A1EE3003F0E5FF0CE00021A4 -:108BB00000E0012182481430FFF75BF904E0062150 -:108BC0007F481430FFF71BF90020E07520767C48C1 -:108BD000691C1430FFF739F9794829781430FFF708 -:108BE00040F9774804213C30FFF709F97448691CC3 -:108BF0003C30FFF72AF9724829783C30FFF731F909 -:108C000026750020F8BD0221DAE7FF206EA1F830BA -:108C1000CAE770B56A4C0125403C034625762046DC -:108C20002030007A002801D03A2070BD644800222C -:108C3000803806789E4206D1E2750622401C03F079 -:108C40000FFEE57500E02276002070BD70B5044689 -:108C50005B4D0020403DA87528462246323803F07F -:108C6000FFFD2846203844730120A87570BD544983 -:108C700020390871704710B5514C0022403C627594 -:108C8000607302462046123803F0EAFD0120607549 -:108C900010BD4B49203948717047F8B500F0A4FB6E -:108CA000474C0025403C607E002804D003F0C5FA04 -:108CB00002F046FF6576434F3D7003F069FAA07BF2 -:108CC000012804D00021084601F0A6FAF8BD0021D1 -:108CD000022001F0A1FA3A4C203C207A002809D069 -:108CE000374881790029F1D11321C1710572012121 -:108CF0008171F8BD78780028FBD0314E0622803E85 -:108D0000707BE0733078A0753046F11D703003F051 -:108D1000A7FD30460622711C773003F0A1FD3C20F0 -:108D2000A072012020727D70F8BD10B5244C403C2B -:108D3000E17BA07CCA0701D0C2070BD08A070FD500 -:108D400082070DD4262003F006F9A07C02210843F7 -:108D5000A07410BD252003F0FEF8A07C0121F6E7E9 -:108D60004907F6D54007F4D4272003F0F4F8A07C97 -:108D70000421ECE770B5134E3078002872D1104C06 -:108D8000403C207D00286DD003F0F7F90025A57444 -:108D9000E5747570284603F0EDF9002002F0B9FF84 -:108DA0000D480D3803F0C5F80B48103803F077F97B -:108DB00003F010FAFFF7B9FF03F0D8F9012111E031 -:108DC00010180020780100207372635C6C6C5F6186 -:108DD00064762E63000000007ECF01009A891300A4 -:108DE00071020000002003F0D2F80F21052003F0EB -:108DF00014F82646403E3178701C03F002F8A07B40 -:108E000001280CD004280AD0607D002807D0214614 -:108E100012390846627B6630FFF732F86575A07D2F -:108E2000002807D0FE480146427B12399C30FFF7EC -:108E300040F8A575306E0178002903D00178001D37 -:108E400003F022F8F06D0178002906D0F44A401CA6 -:108E5000C73202F054FE0120607603F099F9002039 -:108E600070BDFFE70C20FBE7EE494860704770B526 -:108E7000050001D0FFF759FFE94C2034E07C0028C1 -:108E80000AD0A07B012804D19920E749C00003F053 -:108E900072FEFFF702FFE3E7002D0DD00221002054 -:108EA00003F075F8DE4840300079032801D001282E -:108EB00002D1022003F09AFAE07D002600280DD0AE -:108EC000D74D203D2846691C9430FEF7BEFF28464A -:108ED000691CBC30FEF7B9FFE6752676D0487430C1 -:108EE00003F05BF9A07B030003F05EFF05040404BC -:108EF0000D0409000121084603F0CAF903E0CA493C -:108F0000CA4803F038FEE17BA07C814301200029A0 -:108F100003D1A17B012903D0E074C24908709FE707 -:108F2000A674FAE710B503F028F9BE4800780028C7 -:108F300018D1BB482030007D002813D00020FFF757 -:108F400096FFB74840300079002809D001280FD09B -:108F5000022805D003280BD0B349B54803F00BFE17 -:108F6000002010BD00F040FA03F012F90C2010BDF3 -:108F7000EAF74EF8F4E7AB49012048707047F8B5BE -:108F8000002400F0E0FF002824D0FF202D3002F064 -:108F9000FBFFA44D2878A24F403701281DD002289E -:108FA00001D0032834D0A2489F496B3003F0E3FD81 -:108FB000287800280DD0387900280AD0012808D058 -:108FC000022838D0032836D099489749803003F0DA -:108FD000D2FDF8BDFFF761FEF8BD914E2036B07BA3 -:108FE000032815D0707E002803D002F098FD03F00E -:108FF0001CF98B48C43003F0D0F8B07B012812D0A4 -:10900000042810D0B879012806D0032804D004E041 -:109010000120FFF72CFFCBE7102421460E2001434F -:10902000002003F035F97879012801D103F017F910 -:1090300002202870BCE728780228CDD1012003F057 -:10904000D5F9F8BD70B5764840304079012801D196 -:1090500000F0D4F9724C2034607E002803D003F075 -:10906000ECF802F06DFD00F06EFF00280CD06D4DA5 -:109070002878022804D06E486B49A33003F07BFDAA -:10908000A07B012803D006E0FFF707FEE8E6992061 -:10909000800002F079FF0120FFF7E9FE2878002820 -:1090A000F4D028780128F1D039205F49000103F07D -:1090B00062FDD5E6F0B5074689B00020069002F0C3 -:1090C00035FF00900020019056480078022804D017 -:1090D00057485549F03003F04EFD514D4035687901 -:1090E000012801D100F08AF94D48C430FEF7A9FEED -:1090F0004B4E04462036002F70D03046A430FEF789 -:10910000F1FE0028F8D002F085FE0028F4D0707E31 -:1091100000280AD005277F1EFFB202F032FD022888 -:109120000FD0012800D0002001903D492046C431D5 -:109130000C46643C030003F037FE06A4A4A40CA470 -:1091400056A4002FE7D177203AA1C00003F013FD09 -:10915000E9E7B07B012841D004283FD0019A00986C -:10916000104304D1A879002801D0022836D16879AB -:1091700001281DD1607A00281AD101206072087878 -:1091800006224006C00FA0722548C91C6B3003F0B0 -:1091900067FB244C224FA07871377F2804D1A92087 -:1091A00024A1C00003F0E7FCA07838707F20A070F5 -:1091B0001B489C3002F0F1FF1A4803210170287906 -:1091C000002860D001280AD002285CD0032806D0ED -:1091D000164818A1E03803F0CEFC54E051E001201D -:1091E00003F004F94FE00E480F462038C978C079E3 -:1091F000814230D10A4839792038027A91422AD105 -:109200007979427A914226D1B979827A914222D1F2 -:10921000F979C27A91421ED1397A027B914211E0EA -:10922000B017002078010020C88D0100F60400006E -:10923000DE0200007372635C6C6C5F6164762E63A7 -:109240000000000007D13978407B4906C90F8142F0 -:1092500001D1012100E00021B07B012801D00428C8 -:1092600001D100290AD100280BD1019900980843A7 -:1092700004D1A879002801D0012802D1307E00282D -:109280001FD001200690707E002803D002F0D5FF89 -:1092900002F056FC0698002802D00120FFF7E7FDF7 -:1092A0005D48017800290AD00178012907D00078AB -:1092B000032804D095205949C00003F05CFC09B094 -:1092C000F0BD55480422406855490F3003F0C8FAF4 -:1092D000387806224006C10F4F4840680177F91CD4 -:1092E0001D3003F0BDFA4C484D4940680322091D6A -:1092F000133003F0B5FA4848494A4068B97D817592 -:109300000F3A117ED37D09021943018311468B7EEA -:109310004F7E1B023B438380137FD77E1A023A4362 -:10932000C2808A7F4B7F1102194301813C4905228B -:1093300010310A3003F094FA3948374A1130017974 -:109340005768C906C90EB97600794009F876287AB7 -:10935000002809D0A07900283AD11320E07100201C -:1093600020720120A07133E00020A8727888B085B7 -:10937000387FE8732A48394606221D31833803F0C6 -:109380006FFA27490622F3390878A875084677301E -:10939000491C03F065FAB888F087F888208038897E -:1093A0006080F87E20710198002860790BD001213F -:1093B0000843607102F0FEFB61794000C907C90FE4 -:1093C0000143617102E04008400060710120287291 -:1093D000114C0020207000F007F802F0D9FE0120A7 -:1093E000616800F019FF4EE710B502F012FF02F0BD -:1093F00005FF02F01AFE02F0B3FE10BD064810B5DC -:10940000801C02F035FF002802D103497F208870BC -:1094100002F01CFF10BD0000780100203492010012 -:10942000831800208107C90E002808DA0007000F02 -:1094300008388008F74A80008018C06904E0800876 -:10944000F54A800080180068C8400006800F704709 -:1094500010B500F03BFF10BD70B5F04C05466268DA -:10946000002908D0002A04D0FF20EDA10C3003F021 -:1094700082FB656070BD002A04D1FF20E8A1123094 -:1094800003F079FB0020606070BDE948C07E704742 -:10949000E7482830C07E704738B5E04C2068016846 -:1094A0004978012925D001216846F2F7F0FB68468A -:1094B0000078E049000203F03CFA2068426AC06884 -:1094C00012685118EAF7A3F92168C860D84A2068E1 -:1094D00028320321904218D0028B002A15D0012295 -:1094E0004272017200210171021D017F00F0FBFE3A -:1094F00038BD7D21C068C900EAF789F92168C860D4 -:10950000FFF7DDFA21680861E0E7028B521C028355 -:109510004172E6E7FFB5C64E85B0706A34680568EB -:1095200060680190306A0390298E0798401A80B2D3 -:1095300002900898002804D0274638372046483043 -:1095400002E0371D2846A8300090032038710598A6 -:10955000002820D001287DD002285ED003287AD0B0 -:10956000AFA1B54803F007FB0898002807D0387969 -:10957000032804D0B048AAA1093003F0FCFAA16A7C -:109580007069EAF744F9B860616A206A88427DD957 -:10959000009801601FE1306A002804D1A648A0A10C -:1095A0007A3803F0E8FAA449288B37394843401841 -:1095B000069900F0A6FEA0619F49A8883739484364 -:1095C000069900F09EFEE061316A9B48891CA16209 -:1095D0002A8B37384243A069974B121AE63BD218C0 -:1095E0005118A162944BAA7D373B5A434000801822 -:1095F000FF30193020626062306A081AED21FF38AE -:10960000C90015388842AFD28C49884204D28A48B2 -:1096100083A15D3803F0AFFAB6E0874A288B373A6A -:10962000E16850430818069900F06BFEA06182497A -:10963000A88837394843069900F063FEE061306A34 -:10964000002804D17C4876A1553803F094FAAE2066 -:10965000405B01E02CE05AE00028288B784AE16862 -:109660001DD050430818A169401AA0622169A06862 -:10967000734A4843A1694018A97D400051434018EE -:10968000FF3017302062A888504300E0A1E0E16974 -:10969000411A6F20C000081A6062A06A34E050438B -:1096A0000818A169401A3168D63849684018DCE7C3 -:1096B000284680300190C08D002802D0306A0028F2 -:1096C00004D15F4856A1401F03F055FAA8885C49B1 -:1096D000E3694843C01AA06201999C46CA8D21697A -:1096E000A368521A4B43A169591863465343C918DA -:1096F000AA7D534B49005A438918FF311731216223 -:109700006F21C900411A6162316A401A35E0089838 -:10971000002803D03420005D002878D1A88848496B -:109720004843E169401A02994843A06228468030C4 -:109730000490C08D0028019829D0002804D03E480C -:1097400037A1163803F017FA04983D4AC18D0298E4 -:109750000818E16948434000FF3017302062A888AC -:109760005043411A6F20C000081A606200F0AEFD3D -:1097700000281CD0A16A0398081AED21FF38C900FF -:109780005538884200D3EFE601203871ECE6002816 -:1097900002D00398002804D1294821A11A3003F0EF -:1097A000EAF90198A16AD6380818A062CCE7E9F76F -:1097B00096FD726901461046EAF7BEFFA16A081AD3 -:1097C000ED21FF38C90050388842DCD2012009B0B1 -:1097D000F0BD0099086000981A49006880350818A3 -:1097E000F860298B0798081A00B2002804DD059854 -:1097F000022801D0032000E0012078710898387019 -:109800000898002820D03420005D00281CD00220B9 -:10981000DDE7000000ED00E000E400E0880100204A -:109820007372635C6C6C5F6C6D2E73302E63000022 -:109830009C180020102700001905000029020000D4 -:10984000E20400004B170000089801214840203432 -:109850006075317F3A46304600F045FD0020B6E79E -:1098600010B5FE4900280A68516A096807D01268D5 -:109870008988FB4BD2695943891A03F05AF810BD05 -:10988000F8B5F64F38680468416A26460D682036F8 -:10989000717D00290AD0618E2A8E914206D1407ACC -:1098A000012803D1EF49F04803F065F9E9F717FD06 -:1098B000014638684069EAF73FFFFFF7D1FF2A8E7B -:1098C000618E1318994202DB491C618602E0401C3C -:1098D00010186086B07D002806D19C21608E495BFF -:1098E000884201D1401C6086DC480168088B03284F -:1098F00002D2401C088302E0618E98204153284622 -:1099000040300646C1898089081A298E401E4018B9 -:1099100087B218E0D148EB7E00685B00406A0079AE -:109920004100D248415AC05A401881B2207D0023DC -:10993000FFF7F0FD00280FD001280ED0CA48C94912 -:109940003A3003F018F9628EB81A00B20028E1DA52 -:109950000820B07200F010FEF8BD608E401C6086DA -:10996000F1E770B5BD4D002168680162C27E130049 -:1099700003F01AFA045656034A56426A14680268FB -:1099800011700268516000682030407D002808D1C5 -:10999000E9F7A5FC69680968096CEAF7CDFE0028BB -:1099A00018DC6868228E0168498E914206D12146F2 -:1099B00080318B8B9A1ACA83238605E0891A9E22EE -:1099C00011530168498E21860268C1681164C1681B -:1099D000416111E068680168098E228E8B1A224667 -:1099E0008032D3830168098E218601680B6CC360C5 -:1099F0000B6C4361886C9062204601F0D8FC002813 -:109A00000DD098499A4808E0C1684161FFF7B2F962 -:109A1000002804D096489349801D03F0ACF870BD2F -:109A2000934890490D30F8E710B58C4A0B00126846 -:109A300003F0BAF90906090F1F0C2E2E082B2E0071 -:109A4000FFF78FFF10BD00F068FC10BD02F0D1FCE5 -:109A500010BDD07E022806D0D07E032806D0FF207D -:109A60008049A3300EE0FFF70BFF10BDFFF714FD98 -:109A700010BDD07E0228F6D0D07E0328F6D0FF207D -:109A80007849AE3003F077F8F0E7E9F70DFC10BD48 -:109A9000FF207449BC3003F06EF810BDF3B581B0FF -:109AA0000E4601276D4D734C0B0003F07DF909063E -:109AB0002F39392F40403939400001216D48FFF7D7 -:109AC000CBFC31460198FFF7AFFFE07E022826D19C -:109AD00068680568406A0668E9F7DFFBB188604A94 -:109AE0005143EA69891AD639E962B72802D2624835 -:109AF000081803E0081A6049B7314018E8625F4867 -:109B0000E96A814200D80846E86205E00198FFF75B -:109B10008BFFE07E022802D1206820300775FEBD51 -:109B20002C600198FFF780FF00202860FEBDFF2019 -:109B30004C495C3003F01FF8FEBD70B50C4606467C -:109B40000B0003F031F909060D10100D1A1A101050 -:109B50001A00484801212830FFF77EFC2146304694 -:109B6000FFF762FF70BD43483C4D28302860304607 -:109B7000FFF75AFF0020286070BDFF20394982306E -:109B800002F0F9FF70BDF0B5344C0020216885B0BB -:109B900003258D76CA7E0746032A03D0C97E002995 -:109BA00029D029E0087F002803D12E49344802F04B -:109BB000E2FF2068067F684605714571E9F78FFB73 -:109BC0000290FF20F530039001216846017069463C -:109BD0003046EAF702F800E020BF2068007FEAF78D -:109BE00037FE0028F8D02068007FE9F75DFB206889 -:109BF000077700F072FB012021688F7605B0F0BD79 -:109C000016490A68907600E020BF0A68D07E0028D6 -:109C100003D0D07E937E9842F6D0D07E002803D029 -:109C200000200021917670470120FAE770B51149B4 -:109C30000024CA7E094D032A03D02831CA7E032A94 -:109C40002ED12960002827D0012821D00C480549B1 -:109C5000973002F090FF0020296813E0880100206F -:109C6000E204000020980100F70500008ECF0100FB -:109C7000A10300009C180020C4F8FFFF3812000068 -:109C800072020000086048622860002C08D070BD95 -:109C90000320FFF7B5FF01E0FFF775FF0446DAE7A1 -:109CA0000C2070BDF8B5F94F04461F25E67E330041 -:109CB00003F07AF8042920031B20F548844204D0DD -:109CC000FF20F449FC3002F056FF02203C60FFF711 -:109CD00097FF002805D03968002008604862386086 -:109CE00011E00C25002038600AE00120FFF79EFFFC -:109CF000054603E0E749E84802F03DFF002D02D0A9 -:109D0000E07EB042D2D1E07E002804D0E248E149B2 -:109D1000801D02F030FFF8BD10B5DD48FFF7C2FF2F -:109D2000DB482830FFF7BEFFD949002050310875C5 -:109D3000D649C91F4870D64948610A462832506141 -:109D400088769076D1494860086010BD70B50446A9 -:109D50000120FFF767FBC5B20B20FFF763FBC0B222 -:109D6000854204D0FF20CB49C63002F004FF012019 -:109D7000FFF758FBC5B21820FFF754FBC0B285426D -:109D800004D0FF20C349C73002F0F5FE0420C043D1 -:109D9000FFF748FBC5B21920FFF744FBC0B285426C -:109DA00004D0FF20BB49C83002F0E5FEB748B849EF -:109DB000083804700020C87688760A462832D076A3 -:109DC0009076B24B012408331C71186048625062CF -:109DD00008601060FFF7A0FF70BDAC490831087142 -:109DE0007047FEB5AA49CA7E08462830A74C002A0B -:109DF00002D1C27E002A03D0C97E022903D005E029 -:109E0000A648216006E0C17E002901D00C20FEBDDD -:109E10002060A348E9F7F4F9216808779B49206896 -:109E2000C91F0160C91C4162007F002804D1AD2018 -:109E30009849800002F09FFEE9F72FFA994988427D -:109E400000D20846FF30C83086B220680325C576A8 -:109E5000FEF735FE21680861FEF758FE002700284E -:109E600027D0FEF753FE21684A6A10600968012076 -:109E7000087001466846F1F70AFF684600788A498B -:109E8000000202F056FD0191E9F729FA01997118D3 -:109E9000E9F7BDFC2168C86020680572457207714A -:109EA000021D017F00F01FFA206807830020276051 -:109EB000FEBDE9F714FA3146E9F7A9FC2168C8604C -:109EC00008680770096801204870E5E77047F8B531 -:109ED0006F4EF17E002904D131462831C97E002918 -:109EE00001D00C20F8BD0221F176694C674F503447 -:109EF0000837776234600025386025753979C07E6F -:109F00004A006A4940008A5A085A2B46101881B202 -:109F10002A462846FFF7FEFA002804D0CF205D49E4 -:109F2000800002F028FE25610120A560207565866D -:109F300025865748703085753968088E401E08861A -:109F400035830020F8BD10B5504801244068817E5B -:109F500003290CD001684978002906D0006A5449C9 -:109F6000884202D90024FFF706F8204610BD0024DD -:109F7000FBE74648406802681178491C1170016A85 -:109F80000068C26A914204D8007D012801D00120F6 -:109F900070470020704700207047F8B53B4C3C48A4 -:109FA0002060416A00680D68002634210E54A62105 -:109FB000495D00294BD1007D032848D1E9F78FF98D -:109FC000014620684069EAF7B7FB00283FDDFFF74C -:109FD00047FC298E401C41182068026811860068E1 -:109FE000018E9C22525B511A09B200292FDD0121FA -:109FF0002030817528464030C1898089081A298E11 -:10A00000401E401887B21BE0496A09794A00274977 -:10A010008B5A028E007D9446EA7E5200895AC918F6 -:10A0200089B201236246FFF775FA00280FD0012894 -:10A030000FD002280BD01B481649193802F09BFD9F -:10A0400021680868028EBA1A12B2002ADCDA266089 -:10A05000F8BD20680068018E491C0186F0E7F8B55C -:10A060000A4D00266A680128516A0C6853D10879A4 -:10A070000E4940000B5A1068077D032F1AD0027D4D -:10A08000022A24D0007D012834D044E08801002039 -:10A090009C18002020980100070200009D9A0100F2 -:10A0A0003B9B0100F6050000102700008ECF010049 -:10A0B000D98213000661106886609C20025BE07EF6 -:10A0C0004000085AC01881B2002303201BE022463A -:10A0D0008032D78D0761E07E928B4000085AC0180D -:10A0E00081B200230220FFF715FA6A680121126885 -:10A0F00011750AE09C20025BE07E4000085AC018FF -:10A1000081B200230120FFF705FA002803D09C4903 -:10A110009C4802F030FDE9F72DF89B480078E8F7FD -:10A12000FBFD686806830268218E51860068203036 -:10A130008675F8BD38B5944C0021083460680D462A -:10A1400000684278002A01D045701FE0007800289E -:10A1500009D001216846F1F79AFD684600788B49DD -:10A16000000202F0E6FB6068426AC068126851189B -:10A17000E9F74DFB01466068C1600571032141723A -:10A18000021D017F00F0AFF860680583E8F7F2FF79 -:10A190007D480078E8F7C0FD38BD7B4A10B5014620 -:10A1A000083250680B0002F0FFFD060D1504081779 -:10A1B0000C31012100F0D1F807E00021106800F017 -:10A1C000CCF810BD0120FFF74AFF00210846FFF739 -:10A1D00043F910BD032116E0416A02680968D3699A -:10A1E00093608A886A4B5A430368DA600A46C03231 -:10A1F000D3890B83137B8B75138A8B80538ACB8017 -:10A20000928A0A8102210068017510BD5D485C498F -:10A21000913002F0B0FC10BD70B500280BD05A4C44 -:10A22000083401280ED002281ED056485449B430B4 -:10A2300002F0A1FC70BDFFF77DFF00210846FFF78B -:10A240000BF970BD6068002501684D7000F045F89D -:10A250000320FCF728FCE8F78DFF4B486560007889 -:10A26000E8F75AFD656070BDFFF764FF606800F0B5 -:10A2700034F800210846FFF7EFF80420FCF713FC40 -:10A2800070BD414908314968CA7E022A08D10A686E -:10A290001378002B04D150600968CA6A1018C8628C -:10A2A0007047394A10B50832526800290CD001298C -:10A2B00007D0022907D033483149D93002F05BFC7E -:10A2C00010BD801E00E0401F106210BD2E480830F7 -:10A2D0004068002800D0012070470021C1768176B7 -:10A2E00001604162704710B50B46C17E847EA14279 -:10A2F00004D011461846E9F770FC10BDFFF7EDFFDA -:10A3000010BD024610B50020002905D00846504374 -:10A31000204902F00EFB401C10BD1B4810B5083050 -:10A320004068C07E030002F03FFD041515030B15C5 -:10A3300001F05EF900280CD00F2017A1800106E083 -:10A34000FEF7F0FD002804D0F12013A1800002F0F8 -:10A3500012FC10BD10A11448F9E710B504460029FD -:10A3600003D00020FFF77BFE03E007480078E8F702 -:10A37000D3FC2046FFF7B1FF0020FCF794FB10BD93 -:10A3800020980100920600008001002010270000A4 -:10A39000E204000040420F007372635C6C6C5F6CFF -:10A3A0006D2E73302E630000CB030000F8B5FEF76E -:10A3B000B0F90446FEF756FAF84E054670692030AB -:10A3C000407D002809D0012827D002282AD0032860 -:10A3D00032D0FF20F2A19A3037E0F0481830FEF773 -:10A3E0001EFA002801D003200FE0EC481830FEF7D9 -:10A3F00049F9002804D070695B21095C002908D064 -:10A40000E6481830FEF7D2F901207169203148750D -:10A410001DE002212030417519E0E0481830FEF7B8 -:10A42000C5F914E0DD481830FEF72CF900280ED1EC -:10A43000FF20DBA18C3008E0D8481830FEF7EFF998 -:10A44000002804D1FF20D6A1943002F094FBB0691B -:10A45000F72201781140017072692032937DDB0789 -:10A460001B0F1943FB2319400170D37DDB075B0FE2 -:10A4700019430170577DEF23022F04D0012F07D01D -:10A48000032F07D00CE0012C06D8002D04D007E0E4 -:10A490006D1E2C43002C03D019401023194300E0FB -:10A4A00019400170D17F002916D0517D012913D0A8 -:10A4B000BF4801F072FEBE48002128300176726963 -:10A4C000916ED26E42610161B949B26901F097FBA8 -:10A4D000002001F0A3FB03E001F05FFE01F0C1FBEF -:10A4E000B0690078C00606D4F0690078C00602D4CE -:10A4F000F079002806D0B079002803D10121084660 -:10A5000001F0C6FE032030703079002803D101F03D -:10A5100061FE01203071F8BD70B5A0481C30FEF717 -:10A52000B9F901259D4C002802D00020607002E09E -:10A5300065709F48E061606940300078002802D073 -:10A540006078002805D0E06901F027FE01F089FB62 -:10A5500070BD974801F021FE954828300576626964 -:10A56000116F526F42610161914AE16901F047FB4D -:10A57000012001F053FB70BD10B5884900234869E4 -:10A5800002462030C3768377012049239854A032B5 -:10A590009279002A03D008700021022001E00021F6 -:10A5A0000320FFF7FAFD10BD70B57C4C6079C20640 -:10A5B0002046406901468031002A01DA002202E08B -:10A5C000CA8DCB8BD218CA850246C0321379002BB4 -:10A5D00005D0034640331D8AC98B69181982617AF8 -:10A5E000002903D03D2001F051F94AE00346203311 -:10A5F000D97E042945D0217A002913D0480701D4F7 -:10A60000C80601D51E2030E0080701D53D202CE00A -:10A61000C80705D1880703D461A1664802F0ABFAE8 -:10A620002A2022E04030817D002905D0418A4D1C3E -:10A630004582858AA9420FD2517A062902D0117A21 -:10A64000062905D1018B4A1C0283828A914203D2DA -:10A65000028AC1898A4201D3222006E09A7F80893A -:10A66000002A0AD088420FD3082001F00FF9606950 -:10A670002030C07E042804D006E0062804D33E2003 -:10A68000F3E7FFF779FF70BD012020700021084635 -:10A69000FFF783FD70BD10B5404840690146203189 -:10A6A0008A7F002A29D0012A27D0022A06D0032A2D -:10A6B00004D03BA1404802F05EFA10BDC97E0329D8 -:10A6C0000FD0082919D001464031CA898989511A09 -:10A6D000891E89B2032900D303218030828B51184F -:10A6E00009E0014640318A89032A06D3028EC989CE -:10A6F00080305118491C018310BD8030818BFAE7EE -:10A7000000B5030002F050FB0604070B0F121217EE -:10A7100000290ED00FE0891E02290AD90BE0891FFB -:10A72000012906D907E0082903D004E00B390C29D8 -:10A7300001D8012000BD002000BDFEB50546174828 -:10A740001830FEF740F8002804D11B4814A1D13876 -:10A7500002F011FA114CA069FDF702FC0321A06977 -:10A76000FDF721FCA069EF22017811400170294614 -:10A77000FDF740FC002601272B0002F015FB0E5CC4 -:10A780005C085C2C6060255C4C5C603C375C6069FC -:10A790006521095C002911D0062111E098010020F3 -:10A7A0007372635C6C6C5F736C6176652E63000022 -:10A7B00038190020430200005C080000C0304179D5 -:10A7C000A069FDF797FC3AE060698030417CA069A0 -:10A7D000FDF7D7FC33E06169A069B831FDF7ADFC46 -:10A7E0006169A0698C31FDF7AEFC28E00621A06903 -:10A7F000FDF7C5FC23E020690178A069FDF7A9FCFD -:10A8000020698188A069FDF7A6FC20694188A069BC -:10A81000FDF7A5FC13E000960196606960300079B1 -:10A82000002803D069460878384308706946A06953 -:10A83000FDF7B1FC03E0F949F94802F09CF9FDF796 -:10A84000D4FF002804D1F648F449801D02F093F9A2 -:10A850000C2D06D0072D03D06069403046828775E5 -:10A86000FEBD606940300683FEBDF0B5ED4CC820EA -:10A8700061698DB0405C04280AD0052835D15C2080 -:10A88000405C00282AD0012060314871022026E077 -:10A8900010226846D63101F030F86169102204A810 -:10A8A000B03101F02AF86846F1F7B1FC08AE8DCE60 -:10A8B000616984250E4678360DC66F5000250D67F8 -:10A8C0004D67012540267554D74D88318DC52846E2 -:10A8D0000822093001F0C4FF052000E00D20FFF739 -:10A8E0002CFF61690020C03108720DB0F0BDF8B5D1 -:10A8F000CC481830FDF767FF002848D0C94C207AB3 -:10A90000002844D16069C421095C002500290ED0CB -:10A910002030C17E0120FFF7F3FE002807D16069D7 -:10A920002030C17E0420FFF7EBFE002806D06069CE -:10A93000C921095C0126062907D00DE06069502174 -:10A940000D526030457102204EE02030C17E04205F -:10A95000FFF7D6FE002813D0616908462030C27E7A -:10A96000921E130002F020FA166262621D62626299 -:10A9700060621F6262622843626262626262466271 -:10A9800060695E21095CC90702D0C0304572F8BD1C -:10A990000C20FFF7D2FE60694030817F3143817720 -:10A9A000F8BD072020E0FDF79AFF0028F8D0606985 -:10A9B000403005700B2017E0F1F768F90C28EFD351 -:10A9C00060690821B830F1F762F9002806D06069A3 -:10A9D00004218C30F1F75BF9002804D1C72093A142 -:10A9E000C00002F0C8F80420FFF7A7FEF8BDFFF78B -:10A9F0003CFFF8BD00228A66CA66C6770A467831EF -:10AA0000C8C9894878322838D26842632830C8C01B -:10AA100008220D30091D01F023FF0620FFF78DFEEF -:10AA2000606940308575F8BD0920DDE700F036FF2C -:10AA3000F8BD70B57B4C3B216069095C08292FD1BA -:10AA40000146028EC0314B89521C9A4228D1227A8B -:10AA5000002A25D10A8A83889A4207D14B8AC58861 -:10AA6000AB4203D18B8A0589AB4209D043884B8521 -:10AA70008A854A8ACA858A8A0A860122E6210A5478 -:10AA800001221146FDF747FC00210420FFF785FB5A -:10AA900060690021C92211542030C17603218177D9 -:10AAA00070BD70B55F4C60692030C07E172803D040 -:10AAB0005EA1624802F05FF8616900220B464033F4 -:10AAC000DA7608469A75E030867D0B240125002E43 -:10AAD00006D0837C002B14D1C4740275857410E0F9 -:10AAE0001E7F002E07D01A774C88FA235C5202761C -:10AAF0000C23837505E04E88FA235E5202760577B3 -:10AB000084752031CA7670BD70B5464CA079800737 -:10AB100036D5207A002833D160692030C17E0120EB -:10AB2000FFF7EEFD00282BD1A0690126C078002593 -:10AB3000030002F039F90E8585088537465F0A85DE -:10AB4000168526625285032152E060692030C07E5E -:10AB5000052804D0394835A1333802F00CF8606973 -:10AB60000CE060692030C07E092804D033482FA152 -:10AB70002D3802F000F8606956210D542030C5765A -:10AB800070BD60692030C07E0B2804D02B4827A1FF -:10AB9000263801F0F0FF60695B210E540C21203053 -:10ABA000C17670BD60692030C07E0F2804D0234874 -:10ABB0001EA11F3801F0DFFF60695B210E541021D8 -:10ABC000EDE760692030C07E102804D01B4817A133 -:10ABD000183801F0D0FF12210AE060692030C07EF1 -:10ABE000102804D0154811A1123801F0C4FF142117 -:10ABF0006069D4E7FFF755FF70BD60690146C0305A -:10AC0000027A062A04D14031897F890700D505726E -:10AC1000417A0629F0D1457270BD0000A0A701005D -:10AC2000CD07000098010020601900207372635C5A -:10AC30006C6C5F736C6176652E6300004C050000E0 -:10AC4000FD49FE4801F097FFE6E710B5FC4C60694E -:10AC50002030C17E0020FFF753FD002803D1207A69 -:10AC6000012108432072207A002808D1E069FDF70D -:10AC7000EBF961699122505405202031C87610BD4E -:10AC800010B5EF4C60690146C0314A7A002A06D0FF -:10AC9000097A062903D0217A012211432172217AEF -:10ACA000002928D14030807F800715D4E069FDF766 -:10ACB0005AFA61694031C877E069FDF756FA61696F -:10ACC00040310884E069FDF755FA6169022240319C -:10ACD0004884887F10438877606900220146C0312C -:10ACE0000B7A062B00D10A724030837FDB0702D13A -:10ACF00006234B72028310BDF8B5D14C6069203039 -:10AD0000C17E0020FFF7FCFC0125002807D1606907 -:10AD10004030007F002802D1207A28432072207A18 -:10AD2000002830D160690026014640304682857592 -:10AD3000B031E069FDF7EFF96169E0698831FDF74D -:10AD4000F3F960690146E030827D0827002A06D0C9 -:10AD5000817C002913D1C774067585740FE04A8879 -:10AD6000F8204252FA31E069FDF7C8F96169E069FB -:10AD7000FF310331FDF7CAF96069E030877560691A -:10AD80000F212030C176F8BD10B5AD4C6069203080 -:10AD9000C17E0020FFF7B4FC002803D1207A0121F6 -:10ADA00008432072207A002812D1E069FDF769F982 -:10ADB00000280ED0E069FDF75FF96169CA225052A0 -:10ADC000098E00F0D6FD002806D0282000F05EFD98 -:10ADD00010BDFFF73AFF10BDE069FDF74BF961695F -:10ADE000C0310873E069FDF740F96169C031C8817D -:10ADF000E069FDF72BF96169C0310882E069FDF770 -:10AE00002AF96169C0314882E069FDF729F9616971 -:10AE1000D422505208202031C87610BDF8B5884C95 -:10AE2000A079C00776D0207A002873D160692030DD -:10AE3000C17E0120FFF764FC002863D1E069002592 -:10AE4000C178022701260B0001F0AEFF0D16130892 -:10AE5000415A5A445C575A192F545A00FDF74CF97D -:10AE60006169C62250543B20475440314D828E7553 -:10AE700048E000F093FD45E0FFF786FF42E060699F -:10AE80002030C17E0020FFF73BFC002802D1207A51 -:10AE900030432072207A002834D160690146403165 -:10AEA0004D828E750B2120300FE060690146203005 -:10AEB000C27E0C2A02D0227A3A432272227A002AD7 -:10AEC00020D1C57740310E770D21C1761AE0FFF70A -:10AED00013FF17E0606901462030C27E122A02D0BB -:10AEE000227A3A432272227A002A0BD140318D75A0 -:10AEF0001721EAE7FFF7C4FE04E000F00DFD01E0D2 -:10AF0000FFF7A3FE62690023106F516F401C594187 -:10AF100051671067F8BDF8B5494C054660692030A7 -:10AF20008079012801D101F091F9012D14D16069D6 -:10AF30004021095C002903D12030C07F002801D0C6 -:10AF400000F08FFE01F065F901F058F901F06DF89D -:10AF500001F006F901F01CF960790225C10701260C -:10AF6000002901D180070ED560692030817F00293A -:10AF700002D0032902D006E0867700E08577002121 -:10AF80000120FFF70AF960692030817F012903D190 -:10AF90006179090700D58577607A002803D100F030 -:10AFA00027FDFFF7A4FC207900250028606902D066 -:10AFB0008030058403E08030018C491C0184607975 -:10AFC000C00705D06069AC210D544030858104E094 -:10AFD000616940318889401C8881E079002806D069 -:10AFE0006169A031087B022806D8401C087360699B -:10AFF000A030007B022806D96069014680300584B4 -:10B000004584A0310D7360692030C17E0020FFF7B8 -:10B0100077FB002804D160692030C07E072855D115 -:10B0200060690146C0310A7A062A4FD0497A06295A -:10B030004CD03E21095C05E02CAC0100BA050000B3 -:10B0400098010020022941D1A030007B00283DD189 -:10B05000FDF74FFB002839D0FDF704FC002835D060 -:10B0600061690A468032508B01282FD90846A030EA -:10B07000844646716038C7898389B81E834201DBE4 -:10B08000012002E0F81A401E80B2138CA789BB424F -:10B0900001D3012302E0FB1A5B1C9BB2984200D94A -:10B0A0001846012801D163465D71C0310B78002B31 -:10B0B00010D0528C49888A4201D3012102E0891ABA -:10B0C000491C89B2884205D9084603E0616901201C -:10B0D000A0314D7161690A8E803110188883FFF7A5 -:10B0E000DAFAFFF761FAFEF756FF002809D0606927 -:10B0F0000146FF3001300279002A02D14988C1801F -:10B1000006716069A0308571F8BD70B5F84C606952 -:10B110002030407D00283ED0022810D1FDF7C2FA31 -:10B12000002804D17120F349000101F024FD626977 -:10B130000023916ED06E491C58419166D0666069BB -:10B14000002520304575017D012904D10575A179BF -:10B1500010221143A171C17C012915D1C574A079B8 -:10B1600008210843A071FDF76AFB002804D1E520FF -:10B17000E049C00001F0FFFC60690023816EC26EEF -:10B18000491C5A41C266816660692030817D01296F -:10B1900002D0012181753FE585753DE570B5D44C40 -:10B1A0000026E169012508788207920F0420012A10 -:10B1B00015D0022A13D0032A03D0217A0143217229 -:10B1C0002AE560780028FBD1606920308574A17978 -:10B1D0002943A17122E0C6751EE5C5751CE54978B5 -:10B1E000CA0624D06278002AEAD1C906C90E1B29F2 -:10B1F00018D8617901436171FDF75FFB002804D124 -:10B200003B20BC49400101F0B6FC60690023016F9E -:10B21000426F491C5A41426701672030C17D0129B4 -:10B22000DBD1D8E7207A102108432072F4E460696A -:10B23000F3E77CB504460020C0436946888001A836 -:10B24000FCF7B2FD00287AD169468888FCF790FDAA -:10B25000002803D0A749A84801F08DFC00980146BA -:10B26000E030827C0025002A08D065701021217012 -:10B27000C17CA170017DE170857472E082799C4E81 -:10B28000002A13D065700720207008E07169E6205D -:10B290008D8445540A22A01CE83101F0E1FA00989F -:10B2A000E03080790028F1D1A5705AE0827D002A33 -:10B2B00038D0827D130001F077FD0D2F2F2F2F2F17 -:10B2C0002F2F2F112F2F24082F0065700C21217094 -:10B2D000017EA17071694988A18010E06570082025 -:10B2E00020707069082240886080201DFA3101F0CA -:10B2F000B7FAFF2100980331095AA181E030857522 -:10B300002FE065700B212170017EA1707169498861 -:10B31000A180017FA171F2E7774876495D3001F0A5 -:10B320002AFC1EE0C81DF9300279002A08D011223B -:10B3300065702270811C89886180057111E012E0BE -:10B34000027A002A0FD012226570FF312270033179 -:10B3500004E005720A8962804A89A280027A002A82 -:10B36000F7D101207CBD00207CBD61480078012818 -:10B3700001D00C2070470020704770B55C4C05462A -:10B380002078002804D05C485A49933001F0F3FB40 -:10B3900000202561A07201202070FFF7E6FF002841 -:10B3A00004D0554853499E3001F0E5FB34E4F8B52C -:10B3B0004F4F3978012901D00C20F8BD0126A62174 -:10B3C00078610E548030807CFDF752F900282FD030 -:10B3D00078698030807CFDF753FA002828D078699E -:10B3E0008030807CFDF7E5F9002821D07869803035 -:10B3F000807CFDF70AFA00281AD000F0BEFE7869BA -:10B4000000258030408B002827D039481830FDF7C0 -:10B41000DAF9002821D07869C421095C00291CD000 -:10B420002030C17E0120FFF76BF9002802D014E024 -:10B430001220F8BD78692030C17E0420FFF760F942 -:10B4400000280AD1786950210D52603045710220E0 -:10B45000FFF773F97869A03045717869E621095CD6 -:10B46000002903D1818CC288914200D8C188B9815A -:10B4700001468031CA8B521E93B20A8CD21892B206 -:10B480000A8494460246A0321479002C02D04D84DE -:10B49000157102E04C8CE4184C8404464034A789B2 -:10B4A000FF18A7814C8B012C01D8641C4C83002B06 -:10B4B00000D015732030C07E0D4C04281ED050796A -:10B4C00000281DD0A1898C451AD2FDF712F9002859 -:10B4D00016D060690146C0310A78002A10D0803049 -:10B4E000408C498888420BD3A570E6700AE00000C2 -:10B4F000980100202CAC010081080000A67001E03A -:10B50000A570E5706069A5210D543B21095C0629F1 -:10B5100001D0072918D1CA21028E095A511A09B23D -:10B52000002911DB01460522CC310A3001F098F9DF -:10B53000012202216069FCF7EEFE6069C9210D5409 -:10B540003B210D546030867160699E210A5A811C2E -:10B550003030FCF71EFFA07800283DD16069C02183 -:10B56000095C002901D080304584012000F0D1FB26 -:10B570006069133000F093FD60690F3000F0D9FC72 -:10B58000012000F0F7FD61694020405C002803D1F4 -:10B590003F20405C00280DD00A467831C8C9F948E0 -:10B5A0007832D26842632830C8C008220D30091DA5 -:10B5B00001F056F900F0DAFD0121084600F0E7FC41 -:10B5C00060698030806A00F0EBFDFEF7A5FF6069DE -:10B5D0004030007A00F0BFFC6571E571A5712572FD -:10B5E000657225710220207000F0D2FD0020F8BDA8 -:10B5F00010B5E54C2078022801D00C2010BDA078B1 -:10B60000002803D00020FFF786FC17E000F0B5FD0E -:10B6100000F033F9606920308079012801D100F011 -:10B620001EFEA07A002809D0012807D0022807D0E2 -:10B63000032805D0D549D64801F09DFA002010BD59 -:10B64000E7F7E6FCFAE7D0498872704710B5CE4CB0 -:10B650002078032804D0CE48CC49293001F08BFA59 -:10B66000606901212030827C002A06D00022827489 -:10B670000175A27904231A43A271A2691378DB43EE -:10B680009B0707D1C37C002B04D1C174A079022190 -:10B690000843A0711078C00606D4E0690078C0069F -:10B6A00002D4E07900280CD06078002809D1A07974 -:10B6B000002806D1FEF75DFC002802D0207A002881 -:10B6C00003D00120FFF727FC03E0FEF725FF00F081 -:10B6D000D4F8207801280DD0A07A00280AD00128BB -:10B6E00008D0022807D0032805D0A948A749683008 -:10B6F00001F041FA10BD012000F078FE10BD10B538 -:10B70000A14C606920308079012812D100F09EFDA3 -:10B710006169881C3031FCF7C5FE002809D06069DA -:10B72000C21D4388F93253812030007E10730120FE -:10B73000107210BD70B5944C05462078042804D0D2 -:10B7400093489249803001F016FA61791020014344 -:10B750006171002D50D000F09CFA617801250843FA -:10B76000002811D160694021095C00290CD0E169F1 -:10B770004A78D20608D0097820300907C07DC90F61 -:10B78000814201D165724EE0E078002809D0E0697D -:10B790004178C90605D10078C00602D4FFF7AFFF93 -:10B7A00041E0FFF7ACFFE06900784007C10F606936 -:10B7B0002030807D814205D0FFF7A7FC6079082109 -:10B7C00008436071E06900780007C10F60692030AC -:10B7D000C07D814201D1FFF7E1FC607928436071AF -:10B7E0000020E071A079000704D560692030C07E98 -:10B7F000032818D0207A14E0022001436171E07917 -:10B80000401CC0B2E07101280DD86069403000785A -:10B8100000280CD05B484078C106C90E052906D225 -:10B82000C006002803D00120FFF775FB01E0FEF7FA -:10B83000BDFD207801280DD0A07A00280AD001286B -:10B8400009D0022806D0032805D051484F49E230DC -:10B8500001F091F99FE4012000F0C8FD9BE410B5D0 -:10B8600049480078042804D049484849EA3001F0A2 -:10B8700082F90120FFF74FFB10BD10B50121002018 -:10B8800000F006FD40490420087010BD3E494A22E0 -:10B890004969505404202031C876704710B53A4C9D -:10B8A000C8206169405C00281CD0062806D02031E1 -:10B8B000C97E0020FEF724FF002813D060690146EE -:10B8C000C0310A7A130001F06FFA070D0D0D0D0D4E -:10B8D0000D050D004030807FC20704D0C0438007B3 -:10B8E00000D1087210BD0C20FEF727FF606901220D -:10B8F0004030817F1143817710BD10B5002A0AD0F6 -:10B90000002306E0D41A6418203CE47FC4545B1C76 -:10B91000DBB29342F6D310BD7CB51B4C606920307E -:10B92000C17E0020FEF7ECFE0125002802D1207A1E -:10B9300028432072207A00281AD16946E069FCF772 -:10B9400022FC684600780022C107C90F68460170D2 -:10B950006069002902D06030057101E06030027139 -:10B960006069014640304282857509202031C876E1 -:10B970007CBD401A074900B2884201DC00280BDC7C -:10B980000120704738190020980100202CAC0100DC -:10B99000F4090000FE7F00000020F2E710B5534CD0 -:10B9A00060692030C17E0020FEF7AAFE0028207AC0 -:10B9B00010D000280DD1E069FCF797FB6169CA221D -:10B9C0005052098EFFF7D5FF002807D02820FFF737 -:10B9D0005DFF10BD01210843207210BD6169E0695F -:10B9E000CC31FCF77AFB606906212030C17610BDAE -:10B9F00010B500F04EF83D4C607940070BD56069FA -:10BA00002030C17E0520FEF77BFE002803D0207A7F -:10BA1000082108432072FFF701FA00F018F8FFF739 -:10BA200073F8A079C0060FD5207A00280CD1606980 -:10BA30002030C17E0B0001F0B7F9070707070707A1 -:10BA4000070507000721C176FEF7F3FF10BD10B50B -:10BA500026488179490715D5017A002912D1406914 -:10BA60003B21095C891E0B0001F09EF907050C0CB7 -:10BA70000C0D0C0F0C00002256210A54C0308079A6 -:10BA8000FFF704FF10BD012100E00221C030417228 -:10BA900010BD10B515488179090720D5017A002914 -:10BAA0001DD1406902462032D47EA41E230001F03D -:10BAB0007BF913160B1616161616161616161616EC -:10BAC00016161616161716005622115460304079B5 -:10BAD000002801D0062000E01620FFF7D7FE10BD99 -:10BAE0004030C1768175D17610BD000098010020EC -:10BAF0003B4800210170417010218170704770B582 -:10BB0000064614460D460220E6F78AFC0120344919 -:10BB1000344A0870E41E14619660556070BD10B51B -:10BB20000220E6F77DFC2E49012008702E480021F6 -:10BB300001604160816001202C49C005486010BD52 -:10BB400010B527480178002917D00121274AC905D7 -:10BB5000916025490B680022002B05D04B68002B13 -:10BB600002D08968002902D04270102103E001212F -:10BB700041701F490968817002700020E6F750FC8F -:10BB800010BD17480178002912D017480168002914 -:10BB90000AD00168002905D04168002902D08068D8 -:10BBA000002803D000207047022070470120704712 -:10BBB000407870470A48017800290FD00A48016888 -:10BBC000002905D04168002902D08068002801D0F2 -:10BBD0001020704706480068C0B2704780787047F0 -:10BBE000B801002000F5004000F1004000F50140E0 -:10BBF00000F400402E48002101704170704770B57C -:10BC0000064614460D460120E6F70AFC28490120A5 -:10BC1000284B08709E60DC601D6170BDF8B504465D -:10BC20000120E6F7FDFB22490120087021494C6004 -:10BC3000214900264E600321204D0906A960204FAE -:10BC4000002C0AD0012C03D01EA1412000F093FF4C -:10BC50003E60032000066860F8BD386001200006E1 -:10BC6000F9E710B51248017800290ED00321134AD4 -:10BC70000906916010494A680021002A03D0164A3B -:10BC80001268427000E0417001700020E6F7C8FBC6 -:10BC900010BD07480178002907D0074840680028F0 -:10BCA00002D00D480068C0B270474078704700006D -:10BCB000BB01002000F5004000F1004000F501400C -:10BCC00000F2004068616C5C7372635C68616C5F79 -:10BCD00063636D2E6300000000F4004070B5F84D02 -:10BCE00000246C702C70AC616C72AC720120E87234 -:10BCF000F4484470C473AC62F3482C63F0F7E2F884 -:10BD0000002804D0FF20F1A14E3000F034FF2C7742 -:10BD100070BDF8B5F24902250D60F2490026CE63E8 -:10BD20000127CF63F049C96A09070DD4EF49CB6AEF -:10BD3000EF4A53620B6B93624B6BD3628B6B136353 -:10BD4000C96BD30519435163EA4C002823D001285D -:10BD500025D0FF20DDA1A13000F00DFFE648A06353 -:10BD6000FF2004306063276303202061E3499620AD -:10BD70004860D3491C2008560B22D243811A9042B6 -:10BD800037D011DC1C313AD00A2938D0142934D0EC -:10BD9000182911D12FE0DA486061DA4802E0DA4868 -:10BDA0006061DA48A061D9E708301FD004281BD0B1 -:10BDB000082817D00C2812D0FF20C4A1753000F03D -:10BDC000DAFED449D2488860D448D3494160D44986 -:10BDD0000160D4480560D44910204860F8BD0420B3 -:10BDE000E060EEE7E660ECE7FC2000E0F820E060D1 -:10BDF000E7E7F420FBE7F020F9E7EC20F7E7D820AD -:10BE0000F5E710B50C460146C84800F0AFFFAC4856 -:10BE1000047210BDAB4840787047A94A5170107049 -:10BE20007047F8B504460D46507911790002084371 -:10BE3000690009190884501C01460E780127304614 -:10BE40004E78360230438E78C9783604304309067E -:10BE50000843117800020843A900605028460830C2 -:10BE60003E468640002B0CD0012B04D0FF2097A12A -:10BE7000E83000F080FE206B3043AF403843206351 -:10BE8000F8BD206BB043F8E770B50D4604460829AD -:10BE900004D9FF208DA1F93000F06DFE0022002DA5 -:10BEA0000CD9A3489100635809180B6053001B1963 -:10BEB0001B8C0B62521CD2B2AA42F3D3206B9D4959 -:10BEC000086070BD10B504460B22D2430C3089497E -:10BED000944223D008DC1C3026D00A2824D0142811 -:10BEE00020D0182809D11BE02046083014D004289F -:10BEF00010D008280BD00C2807D0FF2073A1753074 -:10BF000000F039FE6E48047710BD042000E00020E8 -:10BF1000C860F7E7FC20FBE7F820F9E7F420F7E733 -:10BF2000F020F5E7EC20F3E7D820F1E76548007B47 -:10BF300070477049C2784A620246137818465378AF -:10BF40001B0218439378D2781B041843120610433F -:10BF50000002C8617047252808D0262808D0272865 -:10BF600008D00A2808D84100091D07E0022106E090 -:10BF70001A2104E0502102E04100891DC9B25D4A46 -:10BF800091605E49486170474D498861704770B55E -:10BF9000002817D002224A4C674BA2720320186077 -:10BFA0005C4D5B48686000200126207500290BD09D -:10BFB000012910D002291ED0952044A1800000F054 -:10BFC000DAFD70BD0122E6E75C48012A01D0466037 -:10BFD00070BD066070BD3A48012A006B05D0012192 -:10BFE000490508432063696070BD012109050843C4 -:10BFF0002063696070BDA069002803D133A1504857 -:10C0000000F0B9FDA169A06A40184E498860434814 -:10C010004D4981604D49C1600120216BC00301433E -:10C02000216368602748C67370BDF8B54249086847 -:10C0300087083D48BF004268D206D60F10228260B2 -:10C0400000240C60334932488860414D0C202C613B -:10C050003A4A012111610BE000BF00BF00BF00BFE1 -:10C0600000BF00BF00BF00BF401E0006000E04D08E -:10C0700029690029F0D0002803D114A1354800F027 -:10C080007AFD2C610E48012144728472C1722A48E3 -:10C090000760002E02D0244910204860F8BD0146F8 -:10C0A0000A7810464A78120210438A78C978120436 -:10C0B00010430906084300020E49000AC86370478E -:10C0C00088190020A8190020BC19002068616C5C48 -:10C0D0007372635C68616C5F7263732E630000004F -:10C0E00080E100E0C01F004080000010C000001090 -:10C0F00000170040001500405B060000401500409E -:10C100000601020025000302050103001F000302CF -:10C110000040000400F501404080004080F50140EF -:10C120001011004080E200E0001300408A19002056 -:10C130000016004040160040001200400010004071 -:10C140004702000040850040488100401010004038 -:10C150000011004067020000F749022008607047A4 -:10C16000F54902200860F54908607047F44902204B -:10C1700008607047F3490870704710B5F248EFF750 -:10C18000A9FE002803D0F149F14800F0F4FC10BDED -:10C1900010B5ED48EFF7B6FE10BDEE4948607047A8 -:10C1A00070B5ED4C0546A06AA84203D3E749EB48B9 -:10C1B00000F0E1FC01202073E9490020256148607E -:10C1C000E84845600120216B800501432163E64971 -:10C1D000486070BDE04802210173C6210161E04A58 -:10C1E00000215160816ADF4AC63151600121026B32 -:10C1F00089050A430263DC48416070470121DA483F -:10C2000089058160D448026B8A430021026301736F -:10C210007047D64801214160C160D1490020486083 -:10C22000D0494860CC4988627047D14940200862B3 -:10C23000D0490A6802430A607047CE48016840222C -:10C2400091430160CA49002008627047C9480168EB -:10C25000102291430160C849012088617047C74995 -:10C260000020C861C3480168102211430160704773 -:10C27000C249CA69012A01D000207047BC4A9268AD -:10C280005206520E524202700020C86101207047CF -:10C2900070B50C00054603D1AC49B94800F06BFC01 -:10C2A000E00706D0012C04D06D20A849C00000F0A2 -:10C2B00062FC002D0DD00221A74801294172C472F1 -:10C2C000AC4808D002290BD0A049AE4800F053FC7E -:10C2D00070BD0121F0E7016804221143016070BDC7 -:10C2E000016808221143016070BDF8B59A4C002323 -:10C2F000E27A910701D5410712D4A349D50605D5A5 -:10C300004D7B002D02D08D7B002D09D0150702D565 -:10C310000D78002D04D1520703D54978002900D1AA -:10C320000123657A00210122924E002D18D00227A8 -:10C330003840184341D0304603689F08934BBF00F4 -:10C340005D68ED06EE0F10259D600160864B9048FC -:10C3500098608A4D0C202961874A0121116115E0FE -:10C36000814B8B4898603068800880003060A172F3 -:10C37000E272F8BD00BF00BF00BF00BF00BF00BF3A -:10C3800000BF00BF401E0006000E04D0296900292E -:10C39000F0D0002803D16D497E4800F0ECFB00206E -:10C3A00028616072A0720120E07272480760002E5E -:10C3B000DFD0764910204860F8BD012D06D0022D4F -:10C3C0000CD06249744800F0D6FBF8BD30680423F5 -:10C3D000984330606172E272A272F8BD306808233F -:10C3E000984330606172E272A772F8BD5A490875CD -:10C3F0007047F8B5644E584AF07B604D0024136BCB -:10C40000002851D05849E813886083435948136382 -:10C4100007685E4B10229A60002202600014886058 -:10C420000C202C462A61544D012129610BE000BFEC -:10C4300000BF00BF00BF00BF00BF00BF00BF401E65 -:10C440000006000E04D021690029F0D0002803D195 -:10C450003E49504800F08FFB0020E06020616060A2 -:10C460006061A061434807603F4900144860474944 -:10C4700010204860384CA07A01280FD0022810D034 -:10C480003249464800F077FB0020F073207D0228F7 -:10C4900003D1434801688907FCD5F8BD0120286015 -:10C4A000F2E701206860EFE72F4883601463107B98 -:10C4B0002746002803D02A484068012809D00023D5 -:10C4C00028692C46012806D00025907A012804D03E -:10C4D00006E00123F4E74025F7E7E168012904D0ED -:10C4E00000212943012802D004E02021F9E76568F2 -:10C4F000012D05D000250D432A4A022802D007E06D -:10C500001025F8E71168012902D1E168012904D05A -:10C5100000212943022802D007E00821F9E7126828 -:10C52000002A02D1E268012A04D000220A4302282C -:10C530003AD03DE00422F9E780E100E080E200E04B -:10C5400000E100E0BD010020BC190020CCC00100CA -:10C55000A10200000015004088190020B20200006E -:10C56000408100404085004000F5014000800040CF -:10C570004015004000120040001000400011004033 -:10C58000630300007D030000A81900200013004091 -:10C590000040000467020000CE0300005D030000BD -:10C5A00000E200E000140040002B01D0022100E076 -:10C5B00000211143022808D16068012805D1824872 -:10C5C0004068012801D0012500E000257F480D4387 -:10C5D00001680906090E02D06169012900D0002115 -:10C5E000317300680006000E02D0A069012800D057 -:10C5F000002070737648006A002803D0FFF7C1FA64 -:10C60000012800D00020B073E76027616760676190 -:10C61000A7616D4847602C466E4D6F482F75436883 -:10C620006B620068A862A97A022909D16978002999 -:10C6300006D06A4A526812780A40297891430AD093 -:10C640003770E1070AD01846FDF71BFE0121A86AE2 -:10C65000FDF727FE0BE001213170F2E7A10601D5BD -:10C66000022102E0A10702D50021FDF71AFE5B4876 -:10C67000416806220931A81C00F0C5F8002808D13D -:10C680005648297A40680078C009814201D10120CA -:10C6900000E0002070702046FFF727FE5048007829 -:10C6A00000280DD001281ED002282FD003284AD000 -:10C6B0004C494D4800F05FFAA87A022856D074E041 -:10C6C000A00701D5FCF7BEFC200702D50120FCF72E -:10C6D000F1FC600702D50020FCF7ECFCA006EBD5CE -:10C6E000FCF74DFCE8E7A00701D5FFF7B8F82007F5 -:10C6F00002D50120FFF71EF8600702D50020FFF7E2 -:10C7000019F8A006D8D5FEF7A1FFD5E7A007BF26E8 -:10C71000002802DA3440E6F76EFC200703D53440E7 -:10C720000120E6F767FC600703D534400020E6F7F8 -:10C7300061FCA00602D53440E6F75BFC6006BBD581 -:10C74000E6F75AFCB8E7A00701D5E6F758FC200742 -:10C7500002D50120E6F752FC600702D50020E6F77B -:10C760004DFCA006A8D5E6F748FCA5E7287B0028E5 -:10C770001BD015494F60022820D0012803D0194949 -:10C780001A4800F0F8F9A96A2869884203D81549BF -:10C79000174800F0F0F91048296941600120296B21 -:10C7A00080050143296313494860287D012800D092 -:10C7B00073E6114801688907FCD5F8BD2969A86AA4 -:10C7C000411805484160E9E74081004040160040BB -:10C7D00040150040881900204085004000150040A9 -:10C7E000BD010020CCC00100E6040000FB040000F5 -:10C7F000FC04000000F5014000E200E070477047D3 -:10C80000704770477047034610B50B439B070FD125 -:10C81000042A0DD308C810C9121FA342F8D018BAB1 -:10C8200021BA884201D9012010BD0020C04310BDAB -:10C83000002A03D0D30703D0521C07E0002010BD0C -:10C8400003780C78401C491C1B1B07D103780C781B -:10C85000401C491C1B1B01D1921EF1D1184610BD72 -:10C86000F8B5042A2CD3830712D00B78491C037027 -:10C87000401C521E83070BD00B78491C0370401CD0 -:10C88000521E830704D00B78491C0370401C521EB3 -:10C890008B079B0F05D0C91ADF002023DE1B08C9B8 -:10C8A0000AE0E4F79DFCF8BD1D4608C9FD401C46A2 -:10C8B000B4402C4310C0121F042AF5D2F308C91A41 -:10C8C000521EF0D40B78491C0370401C521EEAD44F -:10C8D0000B78491C0370401C521EE4D40978017087 -:10C8E000F8BD01E004C0091F0429FBD28B0701D564 -:10C8F0000280801CC90700D00270704700290BD04D -:10C90000C30702D00270401C491E022904D38307CA -:10C9100002D50280801C891EE3E70022EEE7002298 -:10C92000DFE7020A08704A70020C8A70020ECA70B1 -:10C930007047002203098B4273D3030A8B4258D3FA -:10C94000030B8B423CD3030C8B4221D312E00346F2 -:10C950000B437FD4002243088B4274D303098B42DC -:10C960005FD3030A8B4244D3030B8B4228D3030CBF -:10C970008B420DD3FF22090212BA030C8B4202D361 -:10C980001212090265D0030B8B4219D300E0090A89 -:10C99000C30B8B4201D3CB03C01A5241830B8B4292 -:10C9A00001D38B03C01A5241430B8B4201D34B037B -:10C9B000C01A5241030B8B4201D30B03C01A5241E0 -:10C9C000C30A8B4201D3CB02C01A5241830A8B4265 -:10C9D00001D38B02C01A5241430A8B4201D34B024E -:10C9E000C01A5241030A8B4201D30B02C01A5241B2 -:10C9F000CDD2C3098B4201D3CB01C01A5241830966 -:10CA00008B4201D38B01C01A524143098B4201D39F -:10CA10004B01C01A524103098B4201D30B01C01ACA -:10CA20005241C3088B4201D3CB00C01A5241830844 -:10CA30008B4201D38B00C01A524143088B4201D371 -:10CA40004B00C01A5241411A00D2014652411046D1 -:10CA500070475DE0CA0F00D04942031000D3404246 -:10CA6000534000229C4603098B422DD3030A8B427C -:10CA700012D3FC22890112BA030A8B420CD389011A -:10CA800092118B4208D3890192118B4204D3890100 -:10CA90003AD0921100E08909C3098B4201D3CB013E -:10CAA000C01A524183098B4201D38B01C01A5241F3 -:10CAB00043098B4201D34B01C01A524103098B42F7 -:10CAC00001D30B01C01A5241C3088B4201D3CB00E2 -:10CAD000C01A524183088B4201D38B00C01A5241C5 -:10CAE000D9D243088B4201D34B00C01A5241411A9C -:10CAF00000D20146634652415B10104601D34042CA -:10CB0000002B00D54942704763465B1000D340427A -:10CB100001B50020C046C04602BD7047704770474F -:10CB2000704710B500F058F810BD30B58C18027879 -:10CB3000401C13071B0F01D10378401C120906D1BA -:10CB40000278401C03E00578401C0D70491C5B1EF8 -:10CB5000F9D101E00B70491C521EFBD1A142E6D372 -:10CB6000002030BD012308CB134B1860134B196014 -:10CB7000134B1A607047134A134B13607246053A01 -:10CB8000F0E7114A0F4B1B689A420ED10D4B002063 -:10CB9000186001980D4B04B598470CBC9E460246A0 -:10CBA000029800990A4B1B68184706980599094B8B -:10CBB0001B68DB6818470000C8010020CC0100207A -:10CBC000D0010020C0010020EFBEADDE65140000E2 -:10CBD00018000020040000201D481E497047FFF780 -:10CBE000FBFFE4F7ABFA00BD01200007C06AC0B24A -:10CBF000FF2804D1184819490968884202D018480A -:10CC000018490160184819490968884203D1184A2F -:10CC100013605B68184700BD20BFFDE71248134949 -:10CC2000096888420ED1134B18680B498842F3D02B -:10CC300080F308881049884204DD10480268022108 -:10CC40000A4302600E4880470E4880470E4800475E -:10CC5000C0190020C0190020FFFFFFFF00100010C6 -:10CC60002C0500400800000000100000000000201B -:10CC70000400002000D00100002000202405004016 -:10CC80007B140000E9CB010065CB0100134870451F -:10CC900002D1EFF3098101E0EFF3088188690238DE -:10CCA0000078102814DB202810DB2B280BDB0C4A23 -:10CCB00012680C4B9A4203D1602804DB0A4A1047E1 -:10CCC000022008607047094A10470000084A1047D0 -:10CCD000084A12682C32126810470000FDFFFFFF5F -:10CCE0001C000020BEBAFECA911500007528000085 -:10CCF0009B130000040000200D4B0E4908470E4B0B -:10CD00000C4908470D4B0B4908470D4B094908478B -:10CD10000C4B084908470C4B064908470B4B054983 -:10CD200008470B4B034908470A4B024908470000D4 -:10CD3000395400001914000051280000FB2600009F -:10CD4000A9260000612E0000A71500009324000012 -:10CD5000BF270000572D0000002101704170817035 -:10CD6000C170017141718171C17170470A7802709F -:10CD70004B7843708A788270CA78C2700B790371DD -:10CD80004A79427170470A7802704B7843708A780A -:10CD90008270CA78C2700B7903714A7942718A79BC -:10CDA0008271CB79C371704730B47446641E2578A4 -:10CDB000641CAB4200D21D46635D5B00E31830BCCF -:10CDC000184703B5684600784006400E401C88426C -:10CDD00005D269460878401CC0B208700CBD684690 -:10CDE0000078000601D500200CBD80200CBD41401C -:10CDF000802901D0002070470120704737B508789E -:10CE00000C4669460978884206D020781146FFF71B -:10CE1000D8FF207001203EBD00203EBD37B504463E -:10CE20000078154669460979FFF7E1FF002801D02F -:10CE300000203EBD20782946FFF7C3FF2070012067 -:10CE40003EBD0FB568460179007881420AD0684638 -:10CE5000007922214006400E4843801818600120C6 -:10CE600004B000BD0020FBE77FB5684601791C4691 -:10CE700015460078FFF7BBFF002802D0002004B061 -:10CE800070BD6846007822214006400E4843401994 -:10CE900020600120F3E742414A352E3030423030E5 -:10CEA0000000ECF4FC0004FFE11D9AED853324EA58 -:10CEB0007AD2397097570A547D2DD86D0DBA8F6785 -:10CEC00059C7A2BF3400FFFF0080004000200010BF -:10CED000000000000000F8FC7C7E3E3F9F1FCF0F4B -:10CEE000E707000000000000FFFFFFFF0000FFFF5A -:10CEF000010003000000010000000000000000002D -:10CF0000000000000000000087000000000000009A -:10CF10000000000000000000000000010203040007 -:10CF20000D0E0F100000000043D8000061DA000071 -:10CF300029DB000083DB0000D7DB00003FDC0000C2 -:10CF40009DD8000055D90000E1DC0000EFE80000AA -:10CF5000100110013A0200001A02000004013C0016 -:10CF6000230044000E0001020408102040805555A3 -:10CF700055D6BE898E0000007006120DB413000055 -:10CF800014035A06A00900006004F208840DF4019D -:10CF9000FA00960064004B0032001E0014000000EE -:10CFA000D0CF010008000020100000000411000094 -:10CFB000E0CF010018000020BC0100002ACB0100D6 -:10CFC00000D00100D4010020EC1700002011000067 -:10CFD000024801688907FCD57047000000E200E0C4 -:10CFE00001FF01170218013E010001004C01002061 -:10CFF000FB349B5F80046F800010E469CB0100006C -:00000001FF diff --git a/components/softdevice/s310/toolchain/armgcc/armgcc_s310_nrf51422_xxaa.ld b/components/softdevice/s310/toolchain/armgcc/armgcc_s310_nrf51422_xxaa.ld deleted file mode 100644 index c7ded65..0000000 --- a/components/softdevice/s310/toolchain/armgcc/armgcc_s310_nrf51422_xxaa.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x1d000, LENGTH = 0x23000 - RAM (rwx) : ORIGIN = 0x20002200, LENGTH = 0x1e00 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s310/toolchain/armgcc/armgcc_s310_nrf51422_xxac.ld b/components/softdevice/s310/toolchain/armgcc/armgcc_s310_nrf51422_xxac.ld deleted file mode 100644 index 1e0d676..0000000 --- a/components/softdevice/s310/toolchain/armgcc/armgcc_s310_nrf51422_xxac.ld +++ /dev/null @@ -1,22 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -GROUP(-lgcc -lc -lnosys) - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x1d000, LENGTH = 0x23000 - RAM (rwx) : ORIGIN = 0x20002200, LENGTH = 0x5e00 -} - -SECTIONS -{ - .fs_data_out ALIGN(4): - { - PROVIDE( __start_fs_data = .); - KEEP(*(fs_data)) - PROVIDE( __stop_fs_data = .); - } = 0 -} - -INCLUDE "nrf5x_common.ld" \ No newline at end of file diff --git a/components/softdevice/s310/toolchain/iar/iar_s310_nrf51422_xxaa.icf b/components/softdevice/s310/toolchain/iar/iar_s310_nrf51422_xxaa.icf deleted file mode 100644 index 9d9cd00..0000000 --- a/components/softdevice/s310/toolchain/iar/iar_s310_nrf51422_xxaa.icf +++ /dev/null @@ -1,31 +0,0 @@ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ -/*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x1d000; -/*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x1d000; -define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002200; -define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; -/*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 0x800; -define symbol __ICFEDIT_size_heap__ = 0x200; -/**** End of ICF editor section. ###ICF###*/ - -define memory mem with size = 4G; -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; - -define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; -define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; - -initialize by copy { readwrite }; -do not initialize { section .noinit }; - -keep { section .intvec }; -place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; -place in ROM_region { readonly }; -place in RAM_region { readwrite, - block CSTACK, - block HEAP }; diff --git a/components/softdevice/s310/toolchain/iar/iar_s310_nrf51422_xxac.icf b/components/softdevice/s310/toolchain/iar/iar_s310_nrf51422_xxac.icf deleted file mode 100644 index f809761..0000000 --- a/components/softdevice/s310/toolchain/iar/iar_s310_nrf51422_xxac.icf +++ /dev/null @@ -1,31 +0,0 @@ -/*###ICF### Section handled by ICF editor, don't touch! ****/ -/*-Editor annotation file-*/ -/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ -/*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x1d000; -/*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x1d000; -define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002200; -define symbol __ICFEDIT_region_RAM_end__ = 0x20007fff; -/*-Sizes-*/ -define symbol __ICFEDIT_size_cstack__ = 0x800; -define symbol __ICFEDIT_size_heap__ = 0x200; -/**** End of ICF editor section. ###ICF###*/ - -define memory mem with size = 4G; -define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; -define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; - -define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; -define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; - -initialize by copy { readwrite }; -do not initialize { section .noinit }; - -keep { section .intvec }; -place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; -place in ROM_region { readonly }; -place in RAM_region { readwrite, - block CSTACK, - block HEAP }; diff --git a/components/softdevice/s332/headers/nrf_sd_def.h b/components/softdevice/s332/headers/nrf_sd_def.h new file mode 100644 index 0000000..5d29025 --- /dev/null +++ b/components/softdevice/s332/headers/nrf_sd_def.h @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2015 - 2017, Nordic Semiconductor ASA + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 NRF_SD_DEF_H__ +#define NRF_SD_DEF_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SD_PPI_CHANNELS_USED 0xFFF0C000uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */ +#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */ +#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */ +#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */ + + +#ifdef __cplusplus +} +#endif + +#endif /* NRF_SD_DEF_H__ */ diff --git a/components/softdevice/s332/toolchain/armgcc/armgcc_s332_nrf52832_xxaa.ld b/components/softdevice/s332/toolchain/armgcc/armgcc_s332_nrf52832_xxaa.ld new file mode 100644 index 0000000..6e92268 --- /dev/null +++ b/components/softdevice/s332/toolchain/armgcc/armgcc_s332_nrf52832_xxaa.ld @@ -0,0 +1,28 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x29000, LENGTH = 0x57000 + RAM (rwx) : ORIGIN = 0x20001e30, LENGTH = 0xe1d0 +} + +SECTIONS +{ + .fs_data : + { + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + } > RAM + .pwr_mgmt_data : + { + PROVIDE(__start_pwr_mgmt_data = .); + KEEP(*(.pwr_mgmt_data)) + PROVIDE(__stop_pwr_mgmt_data = .); + } > RAM +} INSERT AFTER .data; + +INCLUDE "nrf5x_common.ld" diff --git a/components/softdevice/s110/toolchain/iar/iar_s110_nrf51422_xxaa.icf b/components/softdevice/s332/toolchain/iar/iar_s332_nrf52832_xxaa.icf similarity index 74% rename from components/softdevice/s110/toolchain/iar/iar_s110_nrf51422_xxaa.icf rename to components/softdevice/s332/toolchain/iar/iar_s332_nrf52832_xxaa.icf index 7b19877..294dc71 100644 --- a/components/softdevice/s110/toolchain/iar/iar_s110_nrf51422_xxaa.icf +++ b/components/softdevice/s332/toolchain/iar/iar_s332_nrf52832_xxaa.icf @@ -2,12 +2,14 @@ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ -define symbol __ICFEDIT_intvec_start__ = 0x18000; +define symbol __ICFEDIT_intvec_start__ = 0x29000; /*-Memory Regions-*/ -define symbol __ICFEDIT_region_ROM_start__ = 0x18000; -define symbol __ICFEDIT_region_ROM_end__ = 0x3ffff; -define symbol __ICFEDIT_region_RAM_start__ = 0x20002000; -define symbol __ICFEDIT_region_RAM_end__ = 0x20003fff; +define symbol __ICFEDIT_region_ROM_start__ = 0x29000; +define symbol __ICFEDIT_region_ROM_end__ = 0x7ffff; +define symbol __ICFEDIT_region_RAM_start__ = 0x20001e30; +define symbol __ICFEDIT_region_RAM_end__ = 0x2000ffff; +export symbol __ICFEDIT_region_RAM_start__; +export symbol __ICFEDIT_region_RAM_end__; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x800; define symbol __ICFEDIT_size_heap__ = 0x200; @@ -29,3 +31,4 @@ place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; + diff --git a/components/toolchain/arm/arm_startup_nrf51.s b/components/toolchain/arm/arm_startup_nrf51.s index ee2c1c0..fde9487 100644 --- a/components/toolchain/arm/arm_startup_nrf51.s +++ b/components/toolchain/arm/arm_startup_nrf51.s @@ -1,38 +1,38 @@ -; Copyright (c) 2015, Nordic Semiconductor ASA -; 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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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. - -; NOTE: Template files (including this one) are application specific and therefore -; expected to be copied into the application project folder prior to its use! - -; Description message - - IF :DEF: __STACK_SIZE -Stack_Size EQU __STACK_SIZE +;/* Copyright (c) 2012 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 :DEF: __STARTUP_CONFIG +#include "startup_config.h" + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Size EQU __STARTUP_CONFIG_STACK_SIZE + ELIF :DEF: __STACK_SIZE +Stack_Size EQU __STACK_SIZE ELSE Stack_Size EQU 2048 ENDIF @@ -41,8 +41,10 @@ Stack_Size EQU 2048 Stack_Mem SPACE Stack_Size __initial_sp - IF :DEF: __HEAP_SIZE -Heap_Size EQU __HEAP_SIZE + IF :DEF: __STARTUP_CONFIG +Heap_Size EQU __STARTUP_CONFIG_HEAP_SIZE + ELIF :DEF: __HEAP_SIZE +Heap_Size EQU __HEAP_SIZE ELSE Heap_Size EQU 2048 ENDIF @@ -129,7 +131,7 @@ Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main - + MOVS R1, #NRF_POWER_RAMONx_RAMxON_ONMODE_Msk LDR R0, =NRF_POWER_RAMON_ADDRESS @@ -141,7 +143,7 @@ Reset_Handler PROC LDR R2, [R0] ORRS R2, R2, R1 STR R2, [R0] - + LDR R0, =SystemInit BLX R0 LDR R0, =__main @@ -231,7 +233,7 @@ SWI5_IRQHandler ; User Initial Stack & Heap IF :DEF:__MICROLIB - + EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit @@ -240,13 +242,15 @@ SWI5_IRQHandler IMPORT __use_two_region_memory EXPORT __user_initial_stackheap -__user_initial_stackheap + +__user_initial_stackheap PROC LDR R0, = Heap_Mem LDR R1, = (Stack_Mem + Stack_Size) LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR + ENDP ALIGN diff --git a/components/toolchain/arm/arm_startup_nrf52.s b/components/toolchain/arm/arm_startup_nrf52.s index 5c763b5..532cd67 100644 --- a/components/toolchain/arm/arm_startup_nrf52.s +++ b/components/toolchain/arm/arm_startup_nrf52.s @@ -1,38 +1,38 @@ -; Copyright (c) 2015, Nordic Semiconductor ASA -; 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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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. - -; NOTE: Template files (including this one) are application specific and therefore -; expected to be copied into the application project folder prior to its use! - -; Description message - - IF :DEF: __STACK_SIZE -Stack_Size EQU __STACK_SIZE +;/* Copyright (c) 2012 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 :DEF: __STARTUP_CONFIG +#include "startup_config.h" + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Size EQU __STARTUP_CONFIG_STACK_SIZE + ELIF :DEF: __STACK_SIZE +Stack_Size EQU __STACK_SIZE ELSE Stack_Size EQU 8192 ENDIF @@ -41,8 +41,10 @@ Stack_Size EQU 8192 Stack_Mem SPACE Stack_Size __initial_sp - IF :DEF: __HEAP_SIZE -Heap_Size EQU __HEAP_SIZE + IF :DEF: __STARTUP_CONFIG +Heap_Size EQU __STARTUP_CONFIG_HEAP_SIZE + ELIF :DEF: __HEAP_SIZE +Heap_Size EQU __HEAP_SIZE ELSE Heap_Size EQU 8192 ENDIF @@ -74,7 +76,7 @@ __Vectors DCD __initial_sp ; Top of Stack DCD 0 ; Reserved DCD 0 ; Reserved DCD SVC_Handler - DCD 0 ; Reserved + DCD DebugMon_Handler DCD 0 ; Reserved DCD PendSV_Handler DCD SysTick_Handler @@ -118,7 +120,7 @@ __Vectors DCD __initial_sp ; Top of Stack DCD SPIM2_SPIS2_SPI2_IRQHandler DCD RTC2_IRQHandler DCD I2S_IRQHandler - DCD 0 ; Reserved + DCD FPU_IRQHandler DCD 0 ; Reserved DCD 0 ; Reserved DCD 0 ; Reserved @@ -334,7 +336,8 @@ Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main - + + LDR R0, =SystemInit BLX R0 LDR R0, =__main @@ -371,6 +374,11 @@ SVC_Handler PROC EXPORT SVC_Handler [WEAK] B . ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP PendSV_Handler PROC EXPORT PendSV_Handler [WEAK] B . @@ -418,6 +426,7 @@ Default_Handler PROC EXPORT SPIM2_SPIS2_SPI2_IRQHandler [WEAK] EXPORT RTC2_IRQHandler [WEAK] EXPORT I2S_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] POWER_CLOCK_IRQHandler RADIO_IRQHandler UARTE0_UART0_IRQHandler @@ -454,6 +463,7 @@ PWM2_IRQHandler SPIM2_SPIS2_SPI2_IRQHandler RTC2_IRQHandler I2S_IRQHandler +FPU_IRQHandler B . ENDP ALIGN @@ -461,7 +471,7 @@ I2S_IRQHandler ; User Initial Stack & Heap IF :DEF:__MICROLIB - + EXPORT __initial_sp EXPORT __heap_base EXPORT __heap_limit @@ -470,13 +480,15 @@ I2S_IRQHandler IMPORT __use_two_region_memory EXPORT __user_initial_stackheap -__user_initial_stackheap + +__user_initial_stackheap PROC LDR R0, = Heap_Mem LDR R1, = (Stack_Mem + Stack_Size) LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR + ENDP ALIGN diff --git a/components/toolchain/arm/arm_startup_nrf52840.s b/components/toolchain/arm/arm_startup_nrf52840.s new file mode 100644 index 0000000..57d8d37 --- /dev/null +++ b/components/toolchain/arm/arm_startup_nrf52840.s @@ -0,0 +1,509 @@ +;/* Copyright (c) 2012 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 :DEF: __STARTUP_CONFIG +#include "startup_config.h" + ENDIF + + IF :DEF: __STARTUP_CONFIG +Stack_Size EQU __STARTUP_CONFIG_STACK_SIZE + ELIF :DEF: __STACK_SIZE +Stack_Size EQU __STACK_SIZE + ELSE +Stack_Size EQU 8192 + ENDIF + + AREA STACK, NOINIT, READWRITE, ALIGN=3 +Stack_Mem SPACE Stack_Size +__initial_sp + + IF :DEF: __STARTUP_CONFIG +Heap_Size EQU __STARTUP_CONFIG_HEAP_SIZE + ELIF :DEF: __HEAP_SIZE +Heap_Size EQU __HEAP_SIZE + ELSE +Heap_Size EQU 8192 + ENDIF + + AREA HEAP, NOINIT, READWRITE, ALIGN=3 +__heap_base +Heap_Mem SPACE Heap_Size +__heap_limit + + PRESERVE8 + THUMB + +; Vector Table Mapped to Address 0 at Reset + + AREA RESET, DATA, READONLY + EXPORT __Vectors + EXPORT __Vectors_End + EXPORT __Vectors_Size + +__Vectors DCD __initial_sp ; Top of Stack + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD MemoryManagement_Handler + DCD BusFault_Handler + DCD UsageFault_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 ; Reserved + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UARTE0_UART0_IRQHandler + DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + DCD NFCT_IRQHandler + DCD GPIOTE_IRQHandler + DCD SAADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD COMP_LPCOMP_IRQHandler + DCD SWI0_EGU0_IRQHandler + DCD SWI1_EGU1_IRQHandler + DCD SWI2_EGU2_IRQHandler + DCD SWI3_EGU3_IRQHandler + DCD SWI4_EGU4_IRQHandler + DCD SWI5_EGU5_IRQHandler + DCD TIMER3_IRQHandler + DCD TIMER4_IRQHandler + DCD PWM0_IRQHandler + DCD PDM_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD MWU_IRQHandler + DCD PWM1_IRQHandler + DCD PWM2_IRQHandler + DCD SPIM2_SPIS2_SPI2_IRQHandler + DCD RTC2_IRQHandler + DCD I2S_IRQHandler + DCD FPU_IRQHandler + DCD USBD_IRQHandler + DCD UARTE1_IRQHandler + DCD QSPI_IRQHandler + DCD CRYPTOCELL_IRQHandler + DCD SPIM3_IRQHandler + DCD 0 ; Reserved + DCD PWM3_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + +__Vectors_End + +__Vectors_Size EQU __Vectors_End - __Vectors + + AREA |.text|, CODE, READONLY + +; Reset Handler + + +Reset_Handler PROC + EXPORT Reset_Handler [WEAK] + IMPORT SystemInit + IMPORT __main + + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__main + BX R0 + ENDP + +; Dummy Exception Handlers (infinite loops which can be modified) + +NMI_Handler PROC + EXPORT NMI_Handler [WEAK] + B . + ENDP +HardFault_Handler\ + PROC + EXPORT HardFault_Handler [WEAK] + B . + ENDP +MemoryManagement_Handler\ + PROC + EXPORT MemoryManagement_Handler [WEAK] + B . + ENDP +BusFault_Handler\ + PROC + EXPORT BusFault_Handler [WEAK] + B . + ENDP +UsageFault_Handler\ + PROC + EXPORT UsageFault_Handler [WEAK] + B . + ENDP +SVC_Handler PROC + EXPORT SVC_Handler [WEAK] + B . + ENDP +DebugMon_Handler\ + PROC + EXPORT DebugMon_Handler [WEAK] + B . + ENDP +PendSV_Handler PROC + EXPORT PendSV_Handler [WEAK] + B . + ENDP +SysTick_Handler PROC + EXPORT SysTick_Handler [WEAK] + B . + ENDP + +Default_Handler PROC + + EXPORT POWER_CLOCK_IRQHandler [WEAK] + EXPORT RADIO_IRQHandler [WEAK] + EXPORT UARTE0_UART0_IRQHandler [WEAK] + EXPORT SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler [WEAK] + EXPORT SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler [WEAK] + EXPORT NFCT_IRQHandler [WEAK] + EXPORT GPIOTE_IRQHandler [WEAK] + EXPORT SAADC_IRQHandler [WEAK] + EXPORT TIMER0_IRQHandler [WEAK] + EXPORT TIMER1_IRQHandler [WEAK] + EXPORT TIMER2_IRQHandler [WEAK] + EXPORT RTC0_IRQHandler [WEAK] + EXPORT TEMP_IRQHandler [WEAK] + EXPORT RNG_IRQHandler [WEAK] + EXPORT ECB_IRQHandler [WEAK] + EXPORT CCM_AAR_IRQHandler [WEAK] + EXPORT WDT_IRQHandler [WEAK] + EXPORT RTC1_IRQHandler [WEAK] + EXPORT QDEC_IRQHandler [WEAK] + EXPORT COMP_LPCOMP_IRQHandler [WEAK] + EXPORT SWI0_EGU0_IRQHandler [WEAK] + EXPORT SWI1_EGU1_IRQHandler [WEAK] + EXPORT SWI2_EGU2_IRQHandler [WEAK] + EXPORT SWI3_EGU3_IRQHandler [WEAK] + EXPORT SWI4_EGU4_IRQHandler [WEAK] + EXPORT SWI5_EGU5_IRQHandler [WEAK] + EXPORT TIMER3_IRQHandler [WEAK] + EXPORT TIMER4_IRQHandler [WEAK] + EXPORT PWM0_IRQHandler [WEAK] + EXPORT PDM_IRQHandler [WEAK] + EXPORT MWU_IRQHandler [WEAK] + EXPORT PWM1_IRQHandler [WEAK] + EXPORT PWM2_IRQHandler [WEAK] + EXPORT SPIM2_SPIS2_SPI2_IRQHandler [WEAK] + EXPORT RTC2_IRQHandler [WEAK] + EXPORT I2S_IRQHandler [WEAK] + EXPORT FPU_IRQHandler [WEAK] + EXPORT USBD_IRQHandler [WEAK] + EXPORT UARTE1_IRQHandler [WEAK] + EXPORT QSPI_IRQHandler [WEAK] + EXPORT CRYPTOCELL_IRQHandler [WEAK] + EXPORT SPIM3_IRQHandler [WEAK] + EXPORT PWM3_IRQHandler [WEAK] +POWER_CLOCK_IRQHandler +RADIO_IRQHandler +UARTE0_UART0_IRQHandler +SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler +SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler +NFCT_IRQHandler +GPIOTE_IRQHandler +SAADC_IRQHandler +TIMER0_IRQHandler +TIMER1_IRQHandler +TIMER2_IRQHandler +RTC0_IRQHandler +TEMP_IRQHandler +RNG_IRQHandler +ECB_IRQHandler +CCM_AAR_IRQHandler +WDT_IRQHandler +RTC1_IRQHandler +QDEC_IRQHandler +COMP_LPCOMP_IRQHandler +SWI0_EGU0_IRQHandler +SWI1_EGU1_IRQHandler +SWI2_EGU2_IRQHandler +SWI3_EGU3_IRQHandler +SWI4_EGU4_IRQHandler +SWI5_EGU5_IRQHandler +TIMER3_IRQHandler +TIMER4_IRQHandler +PWM0_IRQHandler +PDM_IRQHandler +MWU_IRQHandler +PWM1_IRQHandler +PWM2_IRQHandler +SPIM2_SPIS2_SPI2_IRQHandler +RTC2_IRQHandler +I2S_IRQHandler +FPU_IRQHandler +USBD_IRQHandler +UARTE1_IRQHandler +QSPI_IRQHandler +CRYPTOCELL_IRQHandler +SPIM3_IRQHandler +PWM3_IRQHandler + B . + ENDP + ALIGN + +; User Initial Stack & Heap + + IF :DEF:__MICROLIB + + EXPORT __initial_sp + EXPORT __heap_base + EXPORT __heap_limit + + ELSE + + IMPORT __use_two_region_memory + EXPORT __user_initial_stackheap + +__user_initial_stackheap PROC + + LDR R0, = Heap_Mem + LDR R1, = (Stack_Mem + Stack_Size) + LDR R2, = (Heap_Mem + Heap_Size) + LDR R3, = Stack_Mem + BX LR + ENDP + + ALIGN + + ENDIF + + END diff --git a/components/toolchain/arm/uicr_config.h b/components/toolchain/arm/uicr_config.h index 64ba577..be5a40c 100644 --- a/components/toolchain/arm/uicr_config.h +++ b/components/toolchain/arm/uicr_config.h @@ -1,34 +1,44 @@ -/* Copyright (c) 2013, Nordic Semiconductor ASA +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * * 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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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. - * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* Template files (including this one) are application specific and therefore expected to +/* Template files (including this one) are application specific and therefore expected to be copied into the application project folder prior to its use! */ #ifndef _UICR_CONFIG_H @@ -38,23 +48,23 @@ #include -/* - * Include this file in your project if you want to include in your compiled code files data - * for the User Information Configuration Registers (UICR) area; see nRF51 Series Reference +/* + * Include this file in your project if you want to include in your compiled code files data + * for the User Information Configuration Registers (UICR) area; see nRF51 Series Reference * Manual chapter User Information Configuration Registers. This file declares one variable - * per register of the UICR area and informs the linker where to place them. To include + * per register of the UICR area and informs the linker where to place them. To include * the desired value in the desired address, uncomment the variable with the proper address * at the target area and update the assignment value. * * Please note that UICR values are stored in a reserved area of the flash and should only be - * stored into when downloading a hex file. Do not use these defined variables to store data + * stored into when downloading a hex file. Do not use these defined variables to store data * at run time. - * - * Note as well that this file uses one non-standard attribute ("at"). It will only function + * + * Note as well that this file uses one non-standard attribute ("at"). It will only function * with the ARMCC compiler toolset. * * Note that the hex file generated when this file is included will fail to download when using - * the standard download algorithm provided by Nordic. See example project "uicr_config_example" + * the standard download algorithm provided by Nordic. See example project "uicr_config_example" * in any of the board example folders for an example of the recommended download method as well * as the documentation that follows with the SDK. nrfjprog can be used as normal. * diff --git a/components/toolchain/gcc/Makefile.common b/components/toolchain/gcc/Makefile.common index 50c69ad..acb6505 100644 --- a/components/toolchain/gcc/Makefile.common +++ b/components/toolchain/gcc/Makefile.common @@ -1,156 +1,169 @@ -DEVICE := NRF51 -DEVICESERIES := nrf51 +# Copyright (c) 2016 Nordic Semiconductor. All Rights Reserved. +# +# The information contained herein is property of Nordic Semiconductor ASA. +# Terms and conditions of usage are described in detail in NORDIC +# 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. + +PLATFORM_SUFFIX := $(if $(filter Windows%,$(OS)),windows,posix) +TOOLCHAIN_CONFIG_FILE := $(TEMPLATE_PATH)/Makefile.$(PLATFORM_SUFFIX) +include $(TOOLCHAIN_CONFIG_FILE) -SDK_INCLUDE_PATH = $(SDK_PATH)/Include/ -SDK_SOURCE_PATH = $(SDK_PATH)/Source/ -TEMPLATE_PATH += $(SDK_SOURCE_PATH)/templates/gcc/ -OUTPUT_BINARY_DIRECTORY := _build - -ifeq ($(OS),Windows_NT) -include $(TEMPLATE_PATH)Makefile.windows -else -include $(TEMPLATE_PATH)Makefile.posix -endif - -ifeq ($(LINKER_SCRIPT),) - ifeq ($(USE_SOFTDEVICE), S110) - LINKER_SCRIPT = gcc_$(DEVICESERIES)_s110_$(DEVICE_VARIANT).ld - OUTPUT_FILENAME := $(OUTPUT_FILENAME)_s110_$(DEVICE_VARIANT) - else - ifeq ($(USE_SOFTDEVICE), S210) - LINKER_SCRIPT = gcc_$(DEVICESERIES)_s210_$(DEVICE_VARIANT).ld - OUTPUT_FILENAME := $(OUTPUT_FILENAME)_s210_$(DEVICE_VARIANT) - else - LINKER_SCRIPT = gcc_$(DEVICESERIES)_blank_$(DEVICE_VARIANT).ld - OUTPUT_FILENAME := $(OUTPUT_FILENAME)_$(DEVICE_VARIANT) - endif - endif +# Toolchain commands +CC := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc" +CXX := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-c++" +AS := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as" +AR := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar" -r +LD := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld" +NM := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm" +OBJDUMP := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump" +OBJCOPY := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy" +SIZE := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-size" +$(if $(shell $(CC) --version),,$(info Cannot find: $(CC).) \ + $(info Please set values in: "$(abspath $(TOOLCHAIN_CONFIG_FILE))") \ + $(info according to the actual configuration of your system.) \ + $(error Cannot continue)) + +# Use ccache on linux if available +CCACHE := $(if $(filter Windows%,$(OS)),, \ + $(if $(wildcard /usr/bin/ccache),ccache)) +CC := $(CCACHE) $(CC) + +MK := mkdir +RM := rm -rf + +# echo suspend +ifeq ($(VERBOSE),1) + NO_ECHO := else -# Use externally defined settings + NO_ECHO := @ endif -CPU := cortex-m0 - -# Toolchain commands -CC := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-gcc" -AS := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-as" -AR := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ar" -r -LD := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-ld" -NM := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-nm" -OBJDUMP := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objdump" -OBJCOPY := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)-objcopy" - -MK := mkdir -RM := rm -rf - -OBJECT_DIRECTORY := _build -LISTING_DIRECTORY := _build - -C_SOURCE_FILES += system_$(DEVICESERIES).c -ASSEMBLER_SOURCE_FILES += gcc_startup_$(DEVICESERIES).s - -# Linker flags -#LDFLAGS += -L"$(GNU_INSTALL_ROOT)/arm-none-eabi/lib/armv6-m" -#LDFLAGS += -L"$(GNU_INSTALL_ROOT)/lib/gcc/arm-none-eabi/$(GNU_VERSION)/armv6-m" -LDFLAGS += -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map -LDFLAGS += -mcpu=$(CPU) -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT) - -# Compiler flags -CFLAGS += -mcpu=$(CPU) -mthumb -mabi=aapcs -D$(DEVICE) -D$(BOARD) -D$(TARGET_CHIP) --std=gnu99 -CFLAGS += -Wall -Werror -CFLAGS += -mfloat-abi=soft - -# Assembler flags -ASMFLAGS += -x assembler-with-cpp - -INCLUDEPATHS += -I"../" -INCLUDEPATHS += -I"$(SDK_PATH)Include" -INCLUDEPATHS += -I"$(SDK_PATH)Include/gcc" -INCLUDEPATHS += -I"$(SDK_PATH)Include/ext_sensors" - -# Sorting removes duplicates -BUILD_DIRECTORIES := $(sort $(OBJECT_DIRECTORY) $(OUTPUT_BINARY_DIRECTORY) $(LISTING_DIRECTORY) ) - -#################################################################### -# Rules # -#################################################################### - -C_SOURCE_FILENAMES = $(notdir $(C_SOURCE_FILES) ) -ASSEMBLER_SOURCE_FILENAMES = $(notdir $(ASSEMBLER_SOURCE_FILES) ) - -# Make a list of source paths -C_SOURCE_PATHS += ../ $(SDK_SOURCE_PATH) $(TEMPLATE_PATH) $(wildcard $(SDK_SOURCE_PATH)*/) $(wildcard $(SDK_SOURCE_PATH)ext_sensors/*/) $(wildcard $(SDK_SOURCE_PATH)ble/*/) -ASSEMBLER_SOURCE_PATHS = ../ $(SDK_SOURCE_PATH) $(TEMPLATE_PATH) $(wildcard $(SDK_SOURCE_PATH)*/) - -C_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(C_SOURCE_FILENAMES:.c=.o) ) -ASSEMBLER_OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(ASSEMBLER_SOURCE_FILENAMES:.s=.o) ) - -# Set source lookup paths -vpath %.c $(C_SOURCE_PATHS) -vpath %.s $(ASSEMBLER_SOURCE_PATHS) - -# Include automatically previously generated dependencies --include $(addprefix $(OBJECT_DIRECTORY)/, $(COBJS:.o=.d)) - -### Targets -debug: CFLAGS += -DDEBUG -g3 -O0 -debug: ASMFLAGS += -DDEBUG -g3 -O0 -debug: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex - -.PHONY: release -release: clean -release: CFLAGS += -DNDEBUG -O3 -release: ASMFLAGS += -DNDEBUG -O3 -release: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex - -echostuff: - @echo C_OBJECTS: [$(C_OBJECTS)] - @echo C_SOURCE_FILES: [$(C_SOURCE_FILES)] - @echo C_SOURCE_PATHS: [$(C_SOURCE_PATHS)] - -## Create build directories -$(BUILD_DIRECTORIES): - $(MK) $@ - -## Create objects from C source files -$(OBJECT_DIRECTORY)/%.o: %.c -# Build header dependencies - $(CC) $(CFLAGS) $(INCLUDEPATHS) -M $< -MF "$(@:.o=.d)" -MT $@ -# Do the actual compilation - $(CC) $(CFLAGS) $(INCLUDEPATHS) -c -o $@ $< - -## Assemble .s files -$(OBJECT_DIRECTORY)/%.o: %.s - $(CC) $(ASMFLAGS) $(INCLUDEPATHS) -c -o $@ $< - -## Link C and assembler objects to an .out file -$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out: $(BUILD_DIRECTORIES) $(C_OBJECTS) $(ASSEMBLER_OBJECTS) $(LIBRARIES) - $(CC) $(LDFLAGS) $(C_OBJECTS) $(ASSEMBLER_OBJECTS) $(LIBRARIES) -o $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out - -## Create binary .bin file from the .out file -$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out - $(OBJCOPY) -O binary $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).bin - -## Create binary .hex file from the .out file -$(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out - $(OBJCOPY) -O ihex $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).out $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex - -## Default build target -.PHONY: all -all: clean release +# $1 type of item +# $2 path to check +define ensure_exists +$(if $(wildcard $(2)),, $(warning Cannot find $(1): $(2))) +endef + +# $1 object file +# $2 source file +define bind_obj_with_src +$(eval $(1) := $(2)) +endef + +# $1 object file +# $2 target name +define bind_obj_with_target +$(eval $(1)T := $(2)) +endef + +# $1 target name +# $2 source file name +# Note: this additional .o for .s-files is a workaround for issues with make 4.1 +# from MinGW (it does nothing to remake .s.o files when a rule for .S.o +# files is defined as well). +define get_object_file_name +$(OUTPUT_DIRECTORY)/$(strip $(1))_$(patsubst %.s,%.s.o,$(notdir $(2))).o +endef + +# $1 target name +# $2 list of source files +define get_object_files +$(foreach src_file, $(2), \ + $(call ensure_exists,source file, $(src_file)) \ + $(eval obj_file := $(call get_object_file_name, $(1), $(src_file))) \ + $(eval DEPENDENCIES += $(obj_file:.o=.d)) \ + $(call bind_obj_with_src, $(obj_file), $(src_file)) \ + $(call bind_obj_with_target, $(obj_file), $(1)) \ + $(eval $(obj_file): Makefile) \ + $(obj_file)) +endef + +# $1 variable name +# $2 target name +define target_specific +$($(addsuffix _$(strip $(2)), $(1))) +endef + +# $1 target name +# $2 link target name +define prepare_build +$(eval DEPENDENCIES :=) \ +$(eval $(2): \ + $(call get_object_files, $(1), $(SRC_FILES) \ + $(call target_specific, SRC_FILES, $(1)))) \ +$(eval -include $(DEPENDENCIES)) \ +$(eval INC_PATHS_$(strip $(1)) := \ + $(foreach folder, $(INC_FOLDERS) $(call target_specific, INC_FOLDERS, $(1)), \ + $(call ensure_exists,include folder, $(folder)) \ + -I"$(folder)")) +endef + +INC_PATHS = $(call target_specific, INC_PATHS, $($@T)) + +# $1 target name +define define_target +$(eval OUTPUT_FILE := $(OUTPUT_DIRECTORY)/$(strip $(1))) \ +$(eval $(1): $(OUTPUT_FILE).out $(OUTPUT_FILE).hex $(OUTPUT_FILE).bin) \ +$(call prepare_build, $(1), $(OUTPUT_FILE).out) +endef + +# $1 target name +# $2 library file name +define define_library +$(eval $(1) := $(2)) \ +$(call prepare_build, $(1), $(1)) +endef + +.PHONY: $(TARGETS) default all clean help flash + +all: $(TARGETS) clean: - $(RM) $(OUTPUT_BINARY_DIRECTORY) + $(RM) $(OUTPUT_DIRECTORY) -## Program device -.PHONY: flash -flash: $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex - nrfjprog --reset --program $(OUTPUT_BINARY_DIRECTORY)/$(OUTPUT_FILENAME).hex - -.PHONY: reset -reset: - nrfjprog --reset +# Create build directories +$(OUTPUT_DIRECTORY): + $(MK) $@ -.PHONY: erase -erase: - nrfjprog --erase +# Create objects from C source files +$(OUTPUT_DIRECTORY)/%.c.o: | $(OUTPUT_DIRECTORY) + @echo Compiling file: $(notdir $($@)) + $(NO_ECHO)$(CC) -MP -MD -std=c99 $(CFLAGS) $(INC_PATHS) -c -o $@ "$($@)" + +# Create objects from C++ source files +$(OUTPUT_DIRECTORY)/%.cpp.o: | $(OUTPUT_DIRECTORY) + @echo Compiling file: $(notdir $($@)) + $(NO_ECHO)$(CXX) -MP -MD $(CFLAGS) $(CXXFLAGS) $(INC_PATHS) -c -o $@ "$($@)" + +# Create objects from assembly files +$(OUTPUT_DIRECTORY)/%.S.o \ +$(OUTPUT_DIRECTORY)/%.s.o.o: | $(OUTPUT_DIRECTORY) + @echo Assembling file: $(notdir $($@)) + $(NO_ECHO)$(CC) -MP -MD -std=c99 $(ASMFLAGS) $(INC_PATHS) -c -o $@ "$($@)" + +export FILE_LIST +DUMP_FILE_LIST := \ + "$(MAKE)" -s --no-print-directory -f $(TEMPLATE_PATH)/file_list.mk +# Link object files +%.out: + $(eval FILE_LIST := $^ $(LIB_FILES)) + $(NO_ECHO)$(DUMP_FILE_LIST) > $(@:.out=.in) + @echo Linking target: $@ + $(NO_ECHO)$(CC) -Wl,-Map=$(@:.out=.map) $(LDFLAGS) @$(@:.out=.in) -lm -o $@ + -@echo '' + $(NO_ECHO)$(SIZE) $@ + -@echo '' + +# Create binary .bin file from the .out file +%.bin: %.out + @echo Preparing: $@ + $(NO_ECHO)$(OBJCOPY) -O binary $< $@ + +# Create binary .hex file from the .out file +%.hex: %.out + @echo Preparing: $@ + $(NO_ECHO)$(OBJCOPY) -O ihex $< $@ diff --git a/components/toolchain/gcc/Makefile.posix b/components/toolchain/gcc/Makefile.posix index 6994c4b..b37277d 100644 --- a/components/toolchain/gcc/Makefile.posix +++ b/components/toolchain/gcc/Makefile.posix @@ -1,4 +1,3 @@ -GNU_INSTALL_ROOT := /usr/local/gcc-arm-none-eabi-4_9-2015q1 +GNU_INSTALL_ROOT := /usr/local/gcc-arm-none-eabi-4_9-2015q3 GNU_VERSION := 4.9.3 GNU_PREFIX := arm-none-eabi - diff --git a/components/toolchain/gcc/Makefile.windows b/components/toolchain/gcc/Makefile.windows index 5b36007..87109c4 100644 --- a/components/toolchain/gcc/Makefile.windows +++ b/components/toolchain/gcc/Makefile.windows @@ -1,10 +1,3 @@ -ifeq ($(findstring 86, $(ProgramFiles)), ) - PROGFILES := C:/Program Files -else - PROGFILES := C:/Program Files (x86) -endif - -GNU_INSTALL_ROOT := $(PROGFILES)/GNU Tools ARM Embedded/4.9 2015q1 +GNU_INSTALL_ROOT := C:/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q3 GNU_VERSION := 4.9.3 GNU_PREFIX := arm-none-eabi - diff --git a/components/toolchain/gcc/arm_common_tables.h b/components/toolchain/gcc/arm_common_tables.h deleted file mode 100644 index 76aadca..0000000 --- a/components/toolchain/gcc/arm_common_tables.h +++ /dev/null @@ -1,136 +0,0 @@ -/* ---------------------------------------------------------------------- -* Copyright (C) 2010-2014 ARM Limited. All rights reserved. -* -* $Date: 31. July 2014 -* $Revision: V1.4.4 -* -* Project: CMSIS DSP Library -* Title: arm_common_tables.h -* -* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions -* -* Target Processor: Cortex-M4/Cortex-M3 -* -* 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 LIMITED 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 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 _ARM_COMMON_TABLES_H -#define _ARM_COMMON_TABLES_H - -#include "arm_math.h" - -extern const uint16_t armBitRevTable[1024]; -extern const q15_t armRecipTableQ15[64]; -extern const q31_t armRecipTableQ31[64]; -//extern const q31_t realCoefAQ31[1024]; -//extern const q31_t realCoefBQ31[1024]; -extern const float32_t twiddleCoef_16[32]; -extern const float32_t twiddleCoef_32[64]; -extern const float32_t twiddleCoef_64[128]; -extern const float32_t twiddleCoef_128[256]; -extern const float32_t twiddleCoef_256[512]; -extern const float32_t twiddleCoef_512[1024]; -extern const float32_t twiddleCoef_1024[2048]; -extern const float32_t twiddleCoef_2048[4096]; -extern const float32_t twiddleCoef_4096[8192]; -#define twiddleCoef twiddleCoef_4096 -extern const q31_t twiddleCoef_16_q31[24]; -extern const q31_t twiddleCoef_32_q31[48]; -extern const q31_t twiddleCoef_64_q31[96]; -extern const q31_t twiddleCoef_128_q31[192]; -extern const q31_t twiddleCoef_256_q31[384]; -extern const q31_t twiddleCoef_512_q31[768]; -extern const q31_t twiddleCoef_1024_q31[1536]; -extern const q31_t twiddleCoef_2048_q31[3072]; -extern const q31_t twiddleCoef_4096_q31[6144]; -extern const q15_t twiddleCoef_16_q15[24]; -extern const q15_t twiddleCoef_32_q15[48]; -extern const q15_t twiddleCoef_64_q15[96]; -extern const q15_t twiddleCoef_128_q15[192]; -extern const q15_t twiddleCoef_256_q15[384]; -extern const q15_t twiddleCoef_512_q15[768]; -extern const q15_t twiddleCoef_1024_q15[1536]; -extern const q15_t twiddleCoef_2048_q15[3072]; -extern const q15_t twiddleCoef_4096_q15[6144]; -extern const float32_t twiddleCoef_rfft_32[32]; -extern const float32_t twiddleCoef_rfft_64[64]; -extern const float32_t twiddleCoef_rfft_128[128]; -extern const float32_t twiddleCoef_rfft_256[256]; -extern const float32_t twiddleCoef_rfft_512[512]; -extern const float32_t twiddleCoef_rfft_1024[1024]; -extern const float32_t twiddleCoef_rfft_2048[2048]; -extern const float32_t twiddleCoef_rfft_4096[4096]; - - -/* floating-point bit reversal tables */ -#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 ) -#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 ) -#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 ) -#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 ) -#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 ) -#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 ) -#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800) -#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808) -#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032) - -extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH]; - -/* fixed-point bit reversal tables */ -#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 ) -#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 ) -#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 ) -#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 ) -#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 ) -#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 ) -#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 ) -#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) -#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) - -extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; -extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; - -/* Tables for Fast Math Sine and Cosine */ -extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; -extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; -extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; - -#endif /* ARM_COMMON_TABLES_H */ diff --git a/components/toolchain/gcc/arm_const_structs.h b/components/toolchain/gcc/arm_const_structs.h deleted file mode 100644 index 217f1d5..0000000 --- a/components/toolchain/gcc/arm_const_structs.h +++ /dev/null @@ -1,79 +0,0 @@ -/* ---------------------------------------------------------------------- -* Copyright (C) 2010-2014 ARM Limited. All rights reserved. -* -* $Date: 31. July 2014 -* $Revision: V1.4.4 -* -* Project: CMSIS DSP Library -* Title: arm_const_structs.h -* -* Description: This file has constant structs that are initialized for -* user convenience. For example, some can be given as -* arguments to the arm_cfft_f32() function. -* -* Target Processor: Cortex-M4/Cortex-M3 -* -* 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 LIMITED 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 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 _ARM_CONST_STRUCTS_H -#define _ARM_CONST_STRUCTS_H - -#include "arm_math.h" -#include "arm_common_tables.h" - - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; - extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; - - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; - extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; - - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; - extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; - -#endif diff --git a/components/toolchain/gcc/arm_math.h b/components/toolchain/gcc/arm_math.h deleted file mode 100644 index 49e23ee..0000000 --- a/components/toolchain/gcc/arm_math.h +++ /dev/null @@ -1,7544 +0,0 @@ -/* ---------------------------------------------------------------------- -* Copyright (C) 2010-2014 ARM Limited. All rights reserved. -* -* $Date: 12. March 2014 -* $Revision: V1.4.4 -* -* Project: CMSIS DSP Library -* Title: arm_math.h -* -* Description: Public header file for CMSIS DSP Library -* -* Target Processor: Cortex-M7/Cortex-M4/Cortex-M3/Cortex-M0 -* -* 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 LIMITED 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 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. - * -------------------------------------------------------------------- */ - -/** - \mainpage CMSIS DSP Software Library - * - * Introduction - * ------------ - * - * This user manual describes the CMSIS DSP software library, - * a suite of common signal processing functions for use on Cortex-M processor based devices. - * - * The library is divided into a number of functions each covering a specific category: - * - Basic math functions - * - Fast math functions - * - Complex math functions - * - Filters - * - Matrix functions - * - Transforms - * - Motor control functions - * - Statistical functions - * - Support functions - * - Interpolation functions - * - * The library has separate functions for operating on 8-bit integers, 16-bit integers, - * 32-bit integer and 32-bit floating-point values. - * - * Using the Library - * ------------ - * - * The library installer contains prebuilt versions of the libraries in the Lib folder. - * - arm_cortexM7lfdp_math.lib (Little endian and Double Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7bfdp_math.lib (Big endian and Double Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7lfsp_math.lib (Little endian and Single Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7bfsp_math.lib (Big endian and Single Precision Floating Point Unit on Cortex-M7) - * - arm_cortexM7l_math.lib (Little endian on Cortex-M7) - * - arm_cortexM7b_math.lib (Big endian on Cortex-M7) - * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) - * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) - * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) - * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) - * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) - * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) - * - arm_cortexM0l_math.lib (Little endian on Cortex-M0 / CortexM0+) - * - arm_cortexM0b_math.lib (Big endian on Cortex-M0 / CortexM0+) - * - * The library functions are declared in the public file arm_math.h which is placed in the Include folder. - * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single - * public header file arm_math.h for Cortex-M7/M4/M3/M0/M0+ with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. - * Define the appropriate pre processor MACRO ARM_MATH_CM7 or ARM_MATH_CM4 or ARM_MATH_CM3 or - * ARM_MATH_CM0 or ARM_MATH_CM0PLUS depending on the target processor in the application. - * - * Examples - * -------- - * - * The library ships with a number of examples which demonstrate how to use the library functions. - * - * Toolchain Support - * ------------ - * - * The library has been developed and tested with MDK-ARM version 4.60. - * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. - * - * Building the Library - * ------------ - * - * The library installer contains a project file to re build libraries on MDK-ARM Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. - * - arm_cortexM_math.uvproj - * - * - * The libraries can be built by opening the arm_cortexM_math.uvproj project in MDK-ARM, selecting a specific target, and defining the optional pre processor MACROs detailed above. - * - * Pre-processor Macros - * ------------ - * - * Each library project have differant pre-processor macros. - * - * - UNALIGNED_SUPPORT_DISABLE: - * - * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access - * - * - ARM_MATH_BIG_ENDIAN: - * - * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. - * - * - ARM_MATH_MATRIX_CHECK: - * - * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices - * - * - ARM_MATH_ROUNDING: - * - * Define macro ARM_MATH_ROUNDING for rounding on support functions - * - * - ARM_MATH_CMx: - * - * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target - * and ARM_MATH_CM0 for building library on cortex-M0 target, ARM_MATH_CM0PLUS for building library on cortex-M0+ target. - * - * - __FPU_PRESENT: - * - * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries - * - *


- * CMSIS-DSP in ARM::CMSIS Pack - * ----------------------------- - * - * The following files relevant to CMSIS-DSP are present in the ARM::CMSIS Pack directories: - * |File/Folder |Content | - * |------------------------------|------------------------------------------------------------------------| - * |\b CMSIS\\Documentation\\DSP | This documentation | - * |\b CMSIS\\DSP_Lib | Software license agreement (license.txt) | - * |\b CMSIS\\DSP_Lib\\Examples | Example projects demonstrating the usage of the library functions | - * |\b CMSIS\\DSP_Lib\\Source | Source files for rebuilding the library | - * - *
- * Revision History of CMSIS-DSP - * ------------ - * Please refer to \ref ChangeLog_pg. - * - * Copyright Notice - * ------------ - * - * Copyright (C) 2010-2014 ARM Limited. All rights reserved. - */ - - -/** - * @defgroup groupMath Basic Math Functions - */ - -/** - * @defgroup groupFastMath Fast Math Functions - * This set of functions provides a fast approximation to sine, cosine, and square root. - * As compared to most of the other functions in the CMSIS math library, the fast math functions - * operate on individual values and not arrays. - * There are separate functions for Q15, Q31, and floating-point data. - * - */ - -/** - * @defgroup groupCmplxMath Complex Math Functions - * This set of functions operates on complex data vectors. - * The data in the complex arrays is stored in an interleaved fashion - * (real, imag, real, imag, ...). - * In the API functions, the number of samples in a complex array refers - * to the number of complex values; the array contains twice this number of - * real values. - */ - -/** - * @defgroup groupFilters Filtering Functions - */ - -/** - * @defgroup groupMatrix Matrix Functions - * - * This set of functions provides basic matrix math operations. - * The functions operate on matrix data structures. For example, - * the type - * definition for the floating-point matrix structure is shown - * below: - *
- *     typedef struct
- *     {
- *       uint16_t numRows;     // number of rows of the matrix.
- *       uint16_t numCols;     // number of columns of the matrix.
- *       float32_t *pData;     // points to the data of the matrix.
- *     } arm_matrix_instance_f32;
- * 
- * There are similar definitions for Q15 and Q31 data types. - * - * The structure specifies the size of the matrix and then points to - * an array of data. The array is of size numRows X numCols - * and the values are arranged in row order. That is, the - * matrix element (i, j) is stored at: - *
- *     pData[i*numCols + j]
- * 
- * - * \par Init Functions - * There is an associated initialization function for each type of matrix - * data structure. - * The initialization function sets the values of the internal structure fields. - * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() - * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. - * - * \par - * Use of the initialization function is optional. However, if initialization function is used - * then the instance structure cannot be placed into a const data section. - * To place the instance structure in a const data - * section, manually initialize the data structure. For example: - *
- * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
- * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
- * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
- * 
- * where nRows specifies the number of rows, nColumns - * specifies the number of columns, and pData points to the - * data array. - * - * \par Size Checking - * By default all of the matrix functions perform size checking on the input and - * output matrices. For example, the matrix addition function verifies that the - * two input matrices and the output matrix all have the same number of rows and - * columns. If the size check fails the functions return: - *
- *     ARM_MATH_SIZE_MISMATCH
- * 
- * Otherwise the functions return - *
- *     ARM_MATH_SUCCESS
- * 
- * There is some overhead associated with this matrix size checking. - * The matrix size checking is enabled via the \#define - *
- *     ARM_MATH_MATRIX_CHECK
- * 
- * within the library project settings. By default this macro is defined - * and size checking is enabled. By changing the project settings and - * undefining this macro size checking is eliminated and the functions - * run a bit faster. With size checking disabled the functions always - * return ARM_MATH_SUCCESS. - */ - -/** - * @defgroup groupTransforms Transform Functions - */ - -/** - * @defgroup groupController Controller Functions - */ - -/** - * @defgroup groupStats Statistics Functions - */ -/** - * @defgroup groupSupport Support Functions - */ - -/** - * @defgroup groupInterpolation Interpolation Functions - * These functions perform 1- and 2-dimensional interpolation of data. - * Linear interpolation is used for 1-dimensional data and - * bilinear interpolation is used for 2-dimensional data. - */ - -/** - * @defgroup groupExamples Examples - */ -#ifndef _ARM_MATH_H -#define _ARM_MATH_H - -#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ - -#if defined(ARM_MATH_CM7) - #include "core_cm7.h" -#elif defined (ARM_MATH_CM4) - #include "core_cm4.h" -#elif defined (ARM_MATH_CM3) - #include "core_cm3.h" -#elif defined (ARM_MATH_CM0) - #include "core_cm0.h" -#define ARM_MATH_CM0_FAMILY - #elif defined (ARM_MATH_CM0PLUS) -#include "core_cm0plus.h" - #define ARM_MATH_CM0_FAMILY -#else - #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0" -#endif - -#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ -#include "string.h" -#include "math.h" -#ifdef __cplusplus -extern "C" -{ -#endif - - - /** - * @brief Macros required for reciprocal calculation in Normalized LMS - */ - -#define DELTA_Q31 (0x100) -#define DELTA_Q15 0x5 -#define INDEX_MASK 0x0000003F -#ifndef PI -#define PI 3.14159265358979f -#endif - - /** - * @brief Macros required for SINE and COSINE Fast math approximations - */ - -#define FAST_MATH_TABLE_SIZE 512 -#define FAST_MATH_Q31_SHIFT (32 - 10) -#define FAST_MATH_Q15_SHIFT (16 - 10) -#define CONTROLLER_Q31_SHIFT (32 - 9) -#define TABLE_SIZE 256 -#define TABLE_SPACING_Q31 0x400000 -#define TABLE_SPACING_Q15 0x80 - - /** - * @brief Macros required for SINE and COSINE Controller functions - */ - /* 1.31(q31) Fixed value of 2/360 */ - /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ -#define INPUT_SPACING 0xB60B61 - - /** - * @brief Macro for Unaligned Support - */ -#ifndef UNALIGNED_SUPPORT_DISABLE - #define ALIGN4 -#else - #if defined (__GNUC__) - #define ALIGN4 __attribute__((aligned(4))) - #else - #define ALIGN4 __align(4) - #endif -#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ - - /** - * @brief Error status returned by some functions in the library. - */ - - typedef enum - { - ARM_MATH_SUCCESS = 0, /**< No error */ - ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ - ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ - ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ - ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ - ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ - ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ - } arm_status; - - /** - * @brief 8-bit fractional data type in 1.7 format. - */ - typedef int8_t q7_t; - - /** - * @brief 16-bit fractional data type in 1.15 format. - */ - typedef int16_t q15_t; - - /** - * @brief 32-bit fractional data type in 1.31 format. - */ - typedef int32_t q31_t; - - /** - * @brief 64-bit fractional data type in 1.63 format. - */ - typedef int64_t q63_t; - - /** - * @brief 32-bit floating-point type definition. - */ - typedef float float32_t; - - /** - * @brief 64-bit floating-point type definition. - */ - typedef double float64_t; - - /** - * @brief definition to read/write two 16 bit values. - */ -#if defined __CC_ARM -#define __SIMD32_TYPE int32_t __packed -#define CMSIS_UNUSED __attribute__((unused)) -#elif defined __ICCARM__ -#define CMSIS_UNUSED -#define __SIMD32_TYPE int32_t __packed -#elif defined __GNUC__ -#define __SIMD32_TYPE int32_t -#define CMSIS_UNUSED __attribute__((unused)) -#elif defined __CSMC__ /* Cosmic */ -#define CMSIS_UNUSED -#define __SIMD32_TYPE int32_t -#else -#error Unknown compiler -#endif - -#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) -#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) - -#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) - -#define __SIMD64(addr) (*(int64_t **) & (addr)) - -#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) - /** - * @brief definition to pack two 16 bit values. - */ -#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ - (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) -#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ - (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) - -#endif - - - /** - * @brief definition to pack four 8 bit values. - */ -#ifndef ARM_MATH_BIG_ENDIAN - -#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ - (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ - (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ - (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) -#else - -#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ - (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ - (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ - (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) - -#endif - - - /** - * @brief Clips Q63 to Q31 values. - */ - static __INLINE q31_t clip_q63_to_q31( - q63_t x) - { - return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? - ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; - } - - /** - * @brief Clips Q63 to Q15 values. - */ - static __INLINE q15_t clip_q63_to_q15( - q63_t x) - { - return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? - ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); - } - - /** - * @brief Clips Q31 to Q7 values. - */ - static __INLINE q7_t clip_q31_to_q7( - q31_t x) - { - return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? - ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; - } - - /** - * @brief Clips Q31 to Q15 values. - */ - static __INLINE q15_t clip_q31_to_q15( - q31_t x) - { - return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? - ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; - } - - /** - * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. - */ - - static __INLINE q63_t mult32x64( - q63_t x, - q31_t y) - { - return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + - (((q63_t) (x >> 32) * y))); - } - - -#if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) -#define __CLZ __clz -#endif - -#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ||(defined (__GNUC__)) || defined (__TASKING__) ) - - static __INLINE uint32_t __CLZ( - q31_t data); - - - static __INLINE uint32_t __CLZ( - q31_t data) - { - uint32_t count = 0; - uint32_t mask = 0x80000000; - - while((data & mask) == 0) - { - count += 1u; - mask = mask >> 1u; - } - - return (count); - - } - -#endif - - /** - * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. - */ - - static __INLINE uint32_t arm_recip_q31( - q31_t in, - q31_t * dst, - q31_t * pRecipTable) - { - - uint32_t out, tempVal; - uint32_t index, i; - uint32_t signBits; - - if(in > 0) - { - signBits = __CLZ(in) - 1; - } - else - { - signBits = __CLZ(-in) - 1; - } - - /* Convert input sample to 1.31 format */ - in = in << signBits; - - /* calculation of index for initial approximated Val */ - index = (uint32_t) (in >> 24u); - index = (index & INDEX_MASK); - - /* 1.31 with exp 1 */ - out = pRecipTable[index]; - - /* calculation of reciprocal value */ - /* running approximation for two iterations */ - for (i = 0u; i < 2u; i++) - { - tempVal = (q31_t) (((q63_t) in * out) >> 31u); - tempVal = 0x7FFFFFFF - tempVal; - /* 1.31 with exp 1 */ - //out = (q31_t) (((q63_t) out * tempVal) >> 30u); - out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u); - } - - /* write output */ - *dst = out; - - /* return num of signbits of out = 1/in value */ - return (signBits + 1u); - - } - - /** - * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. - */ - static __INLINE uint32_t arm_recip_q15( - q15_t in, - q15_t * dst, - q15_t * pRecipTable) - { - - uint32_t out = 0, tempVal = 0; - uint32_t index = 0, i = 0; - uint32_t signBits = 0; - - if(in > 0) - { - signBits = __CLZ(in) - 17; - } - else - { - signBits = __CLZ(-in) - 17; - } - - /* Convert input sample to 1.15 format */ - in = in << signBits; - - /* calculation of index for initial approximated Val */ - index = in >> 8; - index = (index & INDEX_MASK); - - /* 1.15 with exp 1 */ - out = pRecipTable[index]; - - /* calculation of reciprocal value */ - /* running approximation for two iterations */ - for (i = 0; i < 2; i++) - { - tempVal = (q15_t) (((q31_t) in * out) >> 15); - tempVal = 0x7FFF - tempVal; - /* 1.15 with exp 1 */ - out = (q15_t) (((q31_t) out * tempVal) >> 14); - } - - /* write output */ - *dst = out; - - /* return num of signbits of out = 1/in value */ - return (signBits + 1); - - } - - - /* - * @brief C custom defined intrinisic function for only M0 processors - */ -#if defined(ARM_MATH_CM0_FAMILY) - - static __INLINE q31_t __SSAT( - q31_t x, - uint32_t y) - { - int32_t posMax, negMin; - uint32_t i; - - posMax = 1; - for (i = 0; i < (y - 1); i++) - { - posMax = posMax * 2; - } - - if(x > 0) - { - posMax = (posMax - 1); - - if(x > posMax) - { - x = posMax; - } - } - else - { - negMin = -posMax; - - if(x < negMin) - { - x = negMin; - } - } - return (x); - - - } - -#endif /* end of ARM_MATH_CM0_FAMILY */ - - - - /* - * @brief C custom defined intrinsic function for M3 and M0 processors - */ -#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) - - /* - * @brief C custom defined QADD8 for M3 and M0 processors - */ - static __INLINE q31_t __QADD8( - q31_t x, - q31_t y) - { - - q31_t sum; - q7_t r, s, t, u; - - r = (q7_t) x; - s = (q7_t) y; - - r = __SSAT((q31_t) (r + s), 8); - s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8); - t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8); - u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8); - - sum = - (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) | - (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF); - - return sum; - - } - - /* - * @brief C custom defined QSUB8 for M3 and M0 processors - */ - static __INLINE q31_t __QSUB8( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s, t, u; - - r = (q7_t) x; - s = (q7_t) y; - - r = __SSAT((r - s), 8); - s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8; - t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16; - u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24; - - sum = - (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r & - 0x000000FF); - - return sum; - } - - /* - * @brief C custom defined QADD16 for M3 and M0 processors - */ - - /* - * @brief C custom defined QADD16 for M3 and M0 processors - */ - static __INLINE q31_t __QADD16( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (q15_t) x; - s = (q15_t) y; - - r = __SSAT(r + s, 16); - s = __SSAT(((q31_t) ((x >> 16) + (y >> 16))), 16) << 16; - - sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return sum; - - } - - /* - * @brief C custom defined SHADD16 for M3 and M0 processors - */ - static __INLINE q31_t __SHADD16( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (q15_t) x; - s = (q15_t) y; - - r = ((r >> 1) + (s >> 1)); - s = ((q31_t) ((x >> 17) + (y >> 17))) << 16; - - sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return sum; - - } - - /* - * @brief C custom defined QSUB16 for M3 and M0 processors - */ - static __INLINE q31_t __QSUB16( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (q15_t) x; - s = (q15_t) y; - - r = __SSAT(r - s, 16); - s = __SSAT(((q31_t) ((x >> 16) - (y >> 16))), 16) << 16; - - sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return sum; - } - - /* - * @brief C custom defined SHSUB16 for M3 and M0 processors - */ - static __INLINE q31_t __SHSUB16( - q31_t x, - q31_t y) - { - - q31_t diff; - q31_t r, s; - - r = (q15_t) x; - s = (q15_t) y; - - r = ((r >> 1) - (s >> 1)); - s = (((x >> 17) - (y >> 17)) << 16); - - diff = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return diff; - } - - /* - * @brief C custom defined QASX for M3 and M0 processors - */ - static __INLINE q31_t __QASX( - q31_t x, - q31_t y) - { - - q31_t sum = 0; - - sum = - ((sum + - clip_q31_to_q15((q31_t) ((q15_t) (x >> 16) + (q15_t) y))) << 16) + - clip_q31_to_q15((q31_t) ((q15_t) x - (q15_t) (y >> 16))); - - return sum; - } - - /* - * @brief C custom defined SHASX for M3 and M0 processors - */ - static __INLINE q31_t __SHASX( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (q15_t) x; - s = (q15_t) y; - - r = ((r >> 1) - (y >> 17)); - s = (((x >> 17) + (s >> 1)) << 16); - - sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return sum; - } - - - /* - * @brief C custom defined QSAX for M3 and M0 processors - */ - static __INLINE q31_t __QSAX( - q31_t x, - q31_t y) - { - - q31_t sum = 0; - - sum = - ((sum + - clip_q31_to_q15((q31_t) ((q15_t) (x >> 16) - (q15_t) y))) << 16) + - clip_q31_to_q15((q31_t) ((q15_t) x + (q15_t) (y >> 16))); - - return sum; - } - - /* - * @brief C custom defined SHSAX for M3 and M0 processors - */ - static __INLINE q31_t __SHSAX( - q31_t x, - q31_t y) - { - - q31_t sum; - q31_t r, s; - - r = (q15_t) x; - s = (q15_t) y; - - r = ((r >> 1) + (y >> 17)); - s = (((x >> 17) - (s >> 1)) << 16); - - sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); - - return sum; - } - - /* - * @brief C custom defined SMUSDX for M3 and M0 processors - */ - static __INLINE q31_t __SMUSDX( - q31_t x, - q31_t y) - { - - return ((q31_t) (((q15_t) x * (q15_t) (y >> 16)) - - ((q15_t) (x >> 16) * (q15_t) y))); - } - - /* - * @brief C custom defined SMUADX for M3 and M0 processors - */ - static __INLINE q31_t __SMUADX( - q31_t x, - q31_t y) - { - - return ((q31_t) (((q15_t) x * (q15_t) (y >> 16)) + - ((q15_t) (x >> 16) * (q15_t) y))); - } - - /* - * @brief C custom defined QADD for M3 and M0 processors - */ - static __INLINE q31_t __QADD( - q31_t x, - q31_t y) - { - return clip_q63_to_q31((q63_t) x + y); - } - - /* - * @brief C custom defined QSUB for M3 and M0 processors - */ - static __INLINE q31_t __QSUB( - q31_t x, - q31_t y) - { - return clip_q63_to_q31((q63_t) x - y); - } - - /* - * @brief C custom defined SMLAD for M3 and M0 processors - */ - static __INLINE q31_t __SMLAD( - q31_t x, - q31_t y, - q31_t sum) - { - - return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + - ((q15_t) x * (q15_t) y)); - } - - /* - * @brief C custom defined SMLADX for M3 and M0 processors - */ - static __INLINE q31_t __SMLADX( - q31_t x, - q31_t y, - q31_t sum) - { - - return (sum + ((q15_t) (x >> 16) * (q15_t) (y)) + - ((q15_t) x * (q15_t) (y >> 16))); - } - - /* - * @brief C custom defined SMLSDX for M3 and M0 processors - */ - static __INLINE q31_t __SMLSDX( - q31_t x, - q31_t y, - q31_t sum) - { - - return (sum - ((q15_t) (x >> 16) * (q15_t) (y)) + - ((q15_t) x * (q15_t) (y >> 16))); - } - - /* - * @brief C custom defined SMLALD for M3 and M0 processors - */ - static __INLINE q63_t __SMLALD( - q31_t x, - q31_t y, - q63_t sum) - { - - return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + - ((q15_t) x * (q15_t) y)); - } - - /* - * @brief C custom defined SMLALDX for M3 and M0 processors - */ - static __INLINE q63_t __SMLALDX( - q31_t x, - q31_t y, - q63_t sum) - { - - return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + - ((q15_t) x * (q15_t) (y >> 16)); - } - - /* - * @brief C custom defined SMUAD for M3 and M0 processors - */ - static __INLINE q31_t __SMUAD( - q31_t x, - q31_t y) - { - - return (((x >> 16) * (y >> 16)) + - (((x << 16) >> 16) * ((y << 16) >> 16))); - } - - /* - * @brief C custom defined SMUSD for M3 and M0 processors - */ - static __INLINE q31_t __SMUSD( - q31_t x, - q31_t y) - { - - return (-((x >> 16) * (y >> 16)) + - (((x << 16) >> 16) * ((y << 16) >> 16))); - } - - - /* - * @brief C custom defined SXTB16 for M3 and M0 processors - */ - static __INLINE q31_t __SXTB16( - q31_t x) - { - - return ((((x << 24) >> 24) & 0x0000FFFF) | - (((x << 8) >> 8) & 0xFFFF0000)); - } - - -#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ - - - /** - * @brief Instance structure for the Q7 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - } arm_fir_instance_q7; - - /** - * @brief Instance structure for the Q15 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - } arm_fir_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - } arm_fir_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of filter coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - } arm_fir_instance_f32; - - - /** - * @brief Processing function for the Q7 FIR filter. - * @param[in] *S points to an instance of the Q7 FIR filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_q7( - const arm_fir_instance_q7 * S, - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q7 FIR filter. - * @param[in,out] *S points to an instance of the Q7 FIR structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed. - * @return none - */ - void arm_fir_init_q7( - arm_fir_instance_q7 * S, - uint16_t numTaps, - q7_t * pCoeffs, - q7_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 FIR filter. - * @param[in] *S points to an instance of the Q15 FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_q15( - const arm_fir_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q15 FIR filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_fast_q15( - const arm_fir_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q15 FIR filter. - * @param[in,out] *S points to an instance of the Q15 FIR filter structure. - * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if - * numTaps is not a supported value. - */ - - arm_status arm_fir_init_q15( - arm_fir_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR filter. - * @param[in] *S points to an instance of the Q31 FIR filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_q31( - const arm_fir_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q31 FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_fast_q31( - const arm_fir_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 FIR filter. - * @param[in,out] *S points to an instance of the Q31 FIR structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return none. - */ - void arm_fir_init_q31( - arm_fir_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the floating-point FIR filter. - * @param[in] *S points to an instance of the floating-point FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_f32( - const arm_fir_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point FIR filter. - * @param[in,out] *S points to an instance of the floating-point FIR filter structure. - * @param[in] numTaps Number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of samples that are processed at a time. - * @return none. - */ - void arm_fir_init_f32( - arm_fir_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q15 Biquad cascade filter. - */ - typedef struct - { - int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ - - } arm_biquad_casd_df1_inst_q15; - - - /** - * @brief Instance structure for the Q31 Biquad cascade filter. - */ - typedef struct - { - uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ - - } arm_biquad_casd_df1_inst_q31; - - /** - * @brief Instance structure for the floating-point Biquad cascade filter. - */ - typedef struct - { - uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ - float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ - - - } arm_biquad_casd_df1_inst_f32; - - - - /** - * @brief Processing function for the Q15 Biquad cascade filter. - * @param[in] *S points to an instance of the Q15 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_q15( - const arm_biquad_casd_df1_inst_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q15 Biquad cascade filter. - * @param[in,out] *S points to an instance of the Q15 Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format - * @return none - */ - - void arm_biquad_cascade_df1_init_q15( - arm_biquad_casd_df1_inst_q15 * S, - uint8_t numStages, - q15_t * pCoeffs, - q15_t * pState, - int8_t postShift); - - - /** - * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q15 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_fast_q15( - const arm_biquad_casd_df1_inst_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 Biquad cascade filter - * @param[in] *S points to an instance of the Q31 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_q31( - const arm_biquad_casd_df1_inst_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q31 Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_fast_q31( - const arm_biquad_casd_df1_inst_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 Biquad cascade filter. - * @param[in,out] *S points to an instance of the Q31 Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format - * @return none - */ - - void arm_biquad_cascade_df1_init_q31( - arm_biquad_casd_df1_inst_q31 * S, - uint8_t numStages, - q31_t * pCoeffs, - q31_t * pState, - int8_t postShift); - - /** - * @brief Processing function for the floating-point Biquad cascade filter. - * @param[in] *S points to an instance of the floating-point Biquad cascade structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df1_f32( - const arm_biquad_casd_df1_inst_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point Biquad cascade filter. - * @param[in,out] *S points to an instance of the floating-point Biquad cascade structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @return none - */ - - void arm_biquad_cascade_df1_init_f32( - arm_biquad_casd_df1_inst_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Instance structure for the floating-point matrix structure. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - float32_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_f32; - - - /** - * @brief Instance structure for the floating-point matrix structure. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - float64_t *pData; /**< points to the data of the matrix. */ - } arm_matrix_instance_f64; - - /** - * @brief Instance structure for the Q15 matrix structure. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - q15_t *pData; /**< points to the data of the matrix. */ - - } arm_matrix_instance_q15; - - /** - * @brief Instance structure for the Q31 matrix structure. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows of the matrix. */ - uint16_t numCols; /**< number of columns of the matrix. */ - q31_t *pData; /**< points to the data of the matrix. */ - - } arm_matrix_instance_q31; - - - - /** - * @brief Floating-point matrix addition. - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_add_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix addition. - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_add_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix addition. - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_add_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - /** - * @brief Floating-point, complex, matrix multiplication. - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_cmplx_mult_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15, complex, matrix multiplication. - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_cmplx_mult_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pScratch); - - /** - * @brief Q31, complex, matrix multiplication. - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_cmplx_mult_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix transpose. - * @param[in] *pSrc points to the input matrix - * @param[out] *pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_trans_f32( - const arm_matrix_instance_f32 * pSrc, - arm_matrix_instance_f32 * pDst); - - - /** - * @brief Q15 matrix transpose. - * @param[in] *pSrc points to the input matrix - * @param[out] *pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_trans_q15( - const arm_matrix_instance_q15 * pSrc, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix transpose. - * @param[in] *pSrc points to the input matrix - * @param[out] *pDst points to the output matrix - * @return The function returns either ARM_MATH_SIZE_MISMATCH - * or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_trans_q31( - const arm_matrix_instance_q31 * pSrc, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix multiplication - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix multiplication - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @param[in] *pState points to the array for storing intermediate results - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pState); - - /** - * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @param[in] *pState points to the array for storing intermediate results - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_fast_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst, - q15_t * pState); - - /** - * @brief Q31 matrix multiplication - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - /** - * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_mult_fast_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Floating-point matrix subtraction - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_sub_f32( - const arm_matrix_instance_f32 * pSrcA, - const arm_matrix_instance_f32 * pSrcB, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix subtraction - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_sub_q15( - const arm_matrix_instance_q15 * pSrcA, - const arm_matrix_instance_q15 * pSrcB, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix subtraction - * @param[in] *pSrcA points to the first input matrix structure - * @param[in] *pSrcB points to the second input matrix structure - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_sub_q31( - const arm_matrix_instance_q31 * pSrcA, - const arm_matrix_instance_q31 * pSrcB, - arm_matrix_instance_q31 * pDst); - - /** - * @brief Floating-point matrix scaling. - * @param[in] *pSrc points to the input matrix - * @param[in] scale scale factor - * @param[out] *pDst points to the output matrix - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_scale_f32( - const arm_matrix_instance_f32 * pSrc, - float32_t scale, - arm_matrix_instance_f32 * pDst); - - /** - * @brief Q15 matrix scaling. - * @param[in] *pSrc points to input matrix - * @param[in] scaleFract fractional portion of the scale factor - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to output matrix - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_scale_q15( - const arm_matrix_instance_q15 * pSrc, - q15_t scaleFract, - int32_t shift, - arm_matrix_instance_q15 * pDst); - - /** - * @brief Q31 matrix scaling. - * @param[in] *pSrc points to input matrix - * @param[in] scaleFract fractional portion of the scale factor - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to output matrix structure - * @return The function returns either - * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. - */ - - arm_status arm_mat_scale_q31( - const arm_matrix_instance_q31 * pSrc, - q31_t scaleFract, - int32_t shift, - arm_matrix_instance_q31 * pDst); - - - /** - * @brief Q31 matrix initialization. - * @param[in,out] *S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] *pData points to the matrix data array. - * @return none - */ - - void arm_mat_init_q31( - arm_matrix_instance_q31 * S, - uint16_t nRows, - uint16_t nColumns, - q31_t * pData); - - /** - * @brief Q15 matrix initialization. - * @param[in,out] *S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] *pData points to the matrix data array. - * @return none - */ - - void arm_mat_init_q15( - arm_matrix_instance_q15 * S, - uint16_t nRows, - uint16_t nColumns, - q15_t * pData); - - /** - * @brief Floating-point matrix initialization. - * @param[in,out] *S points to an instance of the floating-point matrix structure. - * @param[in] nRows number of rows in the matrix. - * @param[in] nColumns number of columns in the matrix. - * @param[in] *pData points to the matrix data array. - * @return none - */ - - void arm_mat_init_f32( - arm_matrix_instance_f32 * S, - uint16_t nRows, - uint16_t nColumns, - float32_t * pData); - - - - /** - * @brief Instance structure for the Q15 PID Control. - */ - typedef struct - { - q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ -#ifdef ARM_MATH_CM0_FAMILY - q15_t A1; - q15_t A2; -#else - q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ -#endif - q15_t state[3]; /**< The state array of length 3. */ - q15_t Kp; /**< The proportional gain. */ - q15_t Ki; /**< The integral gain. */ - q15_t Kd; /**< The derivative gain. */ - } arm_pid_instance_q15; - - /** - * @brief Instance structure for the Q31 PID Control. - */ - typedef struct - { - q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ - q31_t A2; /**< The derived gain, A2 = Kd . */ - q31_t state[3]; /**< The state array of length 3. */ - q31_t Kp; /**< The proportional gain. */ - q31_t Ki; /**< The integral gain. */ - q31_t Kd; /**< The derivative gain. */ - - } arm_pid_instance_q31; - - /** - * @brief Instance structure for the floating-point PID Control. - */ - typedef struct - { - float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ - float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ - float32_t A2; /**< The derived gain, A2 = Kd . */ - float32_t state[3]; /**< The state array of length 3. */ - float32_t Kp; /**< The proportional gain. */ - float32_t Ki; /**< The integral gain. */ - float32_t Kd; /**< The derivative gain. */ - } arm_pid_instance_f32; - - - - /** - * @brief Initialization function for the floating-point PID Control. - * @param[in,out] *S points to an instance of the PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - * @return none. - */ - void arm_pid_init_f32( - arm_pid_instance_f32 * S, - int32_t resetStateFlag); - - /** - * @brief Reset function for the floating-point PID Control. - * @param[in,out] *S is an instance of the floating-point PID Control structure - * @return none - */ - void arm_pid_reset_f32( - arm_pid_instance_f32 * S); - - - /** - * @brief Initialization function for the Q31 PID Control. - * @param[in,out] *S points to an instance of the Q15 PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - * @return none. - */ - void arm_pid_init_q31( - arm_pid_instance_q31 * S, - int32_t resetStateFlag); - - - /** - * @brief Reset function for the Q31 PID Control. - * @param[in,out] *S points to an instance of the Q31 PID Control structure - * @return none - */ - - void arm_pid_reset_q31( - arm_pid_instance_q31 * S); - - /** - * @brief Initialization function for the Q15 PID Control. - * @param[in,out] *S points to an instance of the Q15 PID structure. - * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. - * @return none. - */ - void arm_pid_init_q15( - arm_pid_instance_q15 * S, - int32_t resetStateFlag); - - /** - * @brief Reset function for the Q15 PID Control. - * @param[in,out] *S points to an instance of the q15 PID Control structure - * @return none - */ - void arm_pid_reset_q15( - arm_pid_instance_q15 * S); - - - /** - * @brief Instance structure for the floating-point Linear Interpolate function. - */ - typedef struct - { - uint32_t nValues; /**< nValues */ - float32_t x1; /**< x1 */ - float32_t xSpacing; /**< xSpacing */ - float32_t *pYData; /**< pointer to the table of Y values */ - } arm_linear_interp_instance_f32; - - /** - * @brief Instance structure for the floating-point bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - float32_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_f32; - - /** - * @brief Instance structure for the Q31 bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q31_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q31; - - /** - * @brief Instance structure for the Q15 bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q15_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q15; - - /** - * @brief Instance structure for the Q15 bilinear interpolation function. - */ - - typedef struct - { - uint16_t numRows; /**< number of rows in the data table. */ - uint16_t numCols; /**< number of columns in the data table. */ - q7_t *pData; /**< points to the data table. */ - } arm_bilinear_interp_instance_q7; - - - /** - * @brief Q7 vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Floating-point vector multiplication. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_mult_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - - - - - - /** - * @brief Instance structure for the Q15 CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix2_instance_q15; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_q15( - arm_cfft_radix2_instance_q15 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_q15( - const arm_cfft_radix2_instance_q15 * S, - q15_t * pSrc); - - - - /** - * @brief Instance structure for the Q15 CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q15_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix4_instance_q15; - -/* Deprecated */ - arm_status arm_cfft_radix4_init_q15( - arm_cfft_radix4_instance_q15 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix4_q15( - const arm_cfft_radix4_instance_q15 * S, - q15_t * pSrc); - - /** - * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q31_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix2_instance_q31; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_q31( - arm_cfft_radix2_instance_q31 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_q31( - const arm_cfft_radix2_instance_q31 * S, - q31_t * pSrc); - - /** - * @brief Instance structure for the Q31 CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - q31_t *pTwiddle; /**< points to the twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - } arm_cfft_radix4_instance_q31; - -/* Deprecated */ - void arm_cfft_radix4_q31( - const arm_cfft_radix4_instance_q31 * S, - q31_t * pSrc); - -/* Deprecated */ - arm_status arm_cfft_radix4_init_q31( - arm_cfft_radix4_instance_q31 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - float32_t onebyfftLen; /**< value of 1/fftLen. */ - } arm_cfft_radix2_instance_f32; - -/* Deprecated */ - arm_status arm_cfft_radix2_init_f32( - arm_cfft_radix2_instance_f32 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix2_f32( - const arm_cfft_radix2_instance_f32 * S, - float32_t * pSrc); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ - uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ - float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ - float32_t onebyfftLen; /**< value of 1/fftLen. */ - } arm_cfft_radix4_instance_f32; - -/* Deprecated */ - arm_status arm_cfft_radix4_init_f32( - arm_cfft_radix4_instance_f32 * S, - uint16_t fftLen, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - -/* Deprecated */ - void arm_cfft_radix4_f32( - const arm_cfft_radix4_instance_f32 * S, - float32_t * pSrc); - - /** - * @brief Instance structure for the fixed-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_q15; - -void arm_cfft_q15( - const arm_cfft_instance_q15 * S, - q15_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the fixed-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_q31; - -void arm_cfft_q31( - const arm_cfft_instance_q31 * S, - q31_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the floating-point CFFT/CIFFT function. - */ - - typedef struct - { - uint16_t fftLen; /**< length of the FFT. */ - const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ - const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ - uint16_t bitRevLength; /**< bit reversal table length. */ - } arm_cfft_instance_f32; - - void arm_cfft_f32( - const arm_cfft_instance_f32 * S, - float32_t * p1, - uint8_t ifftFlag, - uint8_t bitReverseFlag); - - /** - * @brief Instance structure for the Q15 RFFT/RIFFT function. - */ - - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_q15; - - arm_status arm_rfft_init_q15( - arm_rfft_instance_q15 * S, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_q15( - const arm_rfft_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst); - - /** - * @brief Instance structure for the Q31 RFFT/RIFFT function. - */ - - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_q31; - - arm_status arm_rfft_init_q31( - arm_rfft_instance_q31 * S, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_q31( - const arm_rfft_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst); - - /** - * @brief Instance structure for the floating-point RFFT/RIFFT function. - */ - - typedef struct - { - uint32_t fftLenReal; /**< length of the real FFT. */ - uint16_t fftLenBy2; /**< length of the complex FFT. */ - uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ - uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ - uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ - float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ - float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ - arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ - } arm_rfft_instance_f32; - - arm_status arm_rfft_init_f32( - arm_rfft_instance_f32 * S, - arm_cfft_radix4_instance_f32 * S_CFFT, - uint32_t fftLenReal, - uint32_t ifftFlagR, - uint32_t bitReverseFlag); - - void arm_rfft_f32( - const arm_rfft_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst); - - /** - * @brief Instance structure for the floating-point RFFT/RIFFT function. - */ - -typedef struct - { - arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ - uint16_t fftLenRFFT; /**< length of the real sequence */ - float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ - } arm_rfft_fast_instance_f32 ; - -arm_status arm_rfft_fast_init_f32 ( - arm_rfft_fast_instance_f32 * S, - uint16_t fftLen); - -void arm_rfft_fast_f32( - arm_rfft_fast_instance_f32 * S, - float32_t * p, float32_t * pOut, - uint8_t ifftFlag); - - /** - * @brief Instance structure for the floating-point DCT4/IDCT4 function. - */ - - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - float32_t normalize; /**< normalizing factor. */ - float32_t *pTwiddle; /**< points to the twiddle factor table. */ - float32_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_f32; - - /** - * @brief Initialization function for the floating-point DCT4/IDCT4. - * @param[in,out] *S points to an instance of floating-point DCT4/IDCT4 structure. - * @param[in] *S_RFFT points to an instance of floating-point RFFT/RIFFT structure. - * @param[in] *S_CFFT points to an instance of floating-point CFFT/CIFFT structure. - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. - */ - - arm_status arm_dct4_init_f32( - arm_dct4_instance_f32 * S, - arm_rfft_instance_f32 * S_RFFT, - arm_cfft_radix4_instance_f32 * S_CFFT, - uint16_t N, - uint16_t Nby2, - float32_t normalize); - - /** - * @brief Processing function for the floating-point DCT4/IDCT4. - * @param[in] *S points to an instance of the floating-point DCT4/IDCT4 structure. - * @param[in] *pState points to state buffer. - * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. - * @return none. - */ - - void arm_dct4_f32( - const arm_dct4_instance_f32 * S, - float32_t * pState, - float32_t * pInlineBuffer); - - /** - * @brief Instance structure for the Q31 DCT4/IDCT4 function. - */ - - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - q31_t normalize; /**< normalizing factor. */ - q31_t *pTwiddle; /**< points to the twiddle factor table. */ - q31_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_q31; - - /** - * @brief Initialization function for the Q31 DCT4/IDCT4. - * @param[in,out] *S points to an instance of Q31 DCT4/IDCT4 structure. - * @param[in] *S_RFFT points to an instance of Q31 RFFT/RIFFT structure - * @param[in] *S_CFFT points to an instance of Q31 CFFT/CIFFT structure - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. - */ - - arm_status arm_dct4_init_q31( - arm_dct4_instance_q31 * S, - arm_rfft_instance_q31 * S_RFFT, - arm_cfft_radix4_instance_q31 * S_CFFT, - uint16_t N, - uint16_t Nby2, - q31_t normalize); - - /** - * @brief Processing function for the Q31 DCT4/IDCT4. - * @param[in] *S points to an instance of the Q31 DCT4 structure. - * @param[in] *pState points to state buffer. - * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. - * @return none. - */ - - void arm_dct4_q31( - const arm_dct4_instance_q31 * S, - q31_t * pState, - q31_t * pInlineBuffer); - - /** - * @brief Instance structure for the Q15 DCT4/IDCT4 function. - */ - - typedef struct - { - uint16_t N; /**< length of the DCT4. */ - uint16_t Nby2; /**< half of the length of the DCT4. */ - q15_t normalize; /**< normalizing factor. */ - q15_t *pTwiddle; /**< points to the twiddle factor table. */ - q15_t *pCosFactor; /**< points to the cosFactor table. */ - arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ - arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ - } arm_dct4_instance_q15; - - /** - * @brief Initialization function for the Q15 DCT4/IDCT4. - * @param[in,out] *S points to an instance of Q15 DCT4/IDCT4 structure. - * @param[in] *S_RFFT points to an instance of Q15 RFFT/RIFFT structure. - * @param[in] *S_CFFT points to an instance of Q15 CFFT/CIFFT structure. - * @param[in] N length of the DCT4. - * @param[in] Nby2 half of the length of the DCT4. - * @param[in] normalize normalizing factor. - * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. - */ - - arm_status arm_dct4_init_q15( - arm_dct4_instance_q15 * S, - arm_rfft_instance_q15 * S_RFFT, - arm_cfft_radix4_instance_q15 * S_CFFT, - uint16_t N, - uint16_t Nby2, - q15_t normalize); - - /** - * @brief Processing function for the Q15 DCT4/IDCT4. - * @param[in] *S points to an instance of the Q15 DCT4 structure. - * @param[in] *pState points to state buffer. - * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. - * @return none. - */ - - void arm_dct4_q15( - const arm_dct4_instance_q15 * S, - q15_t * pState, - q15_t * pInlineBuffer); - - /** - * @brief Floating-point vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Q7 vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector addition. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_add_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Floating-point vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Q7 vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_q7( - q7_t * pSrcA, - q7_t * pSrcB, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector subtraction. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_sub_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a floating-point vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scale scale factor to be applied - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_f32( - float32_t * pSrc, - float32_t scale, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a Q7 vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_q7( - q7_t * pSrc, - q7_t scaleFract, - int8_t shift, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a Q15 vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_q15( - q15_t * pSrc, - q15_t scaleFract, - int8_t shift, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Multiplies a Q31 vector by a scalar. - * @param[in] *pSrc points to the input vector - * @param[in] scaleFract fractional portion of the scale value - * @param[in] shift number of bits to shift the result by - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_scale_q31( - q31_t * pSrc, - q31_t scaleFract, - int8_t shift, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Q7 vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Floating-point vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Q15 vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Q31 vector absolute value. - * @param[in] *pSrc points to the input buffer - * @param[out] *pDst points to the output buffer - * @param[in] blockSize number of samples in each vector - * @return none. - */ - - void arm_abs_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Dot product of floating-point vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_f32( - float32_t * pSrcA, - float32_t * pSrcB, - uint32_t blockSize, - float32_t * result); - - /** - * @brief Dot product of Q7 vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_q7( - q7_t * pSrcA, - q7_t * pSrcB, - uint32_t blockSize, - q31_t * result); - - /** - * @brief Dot product of Q15 vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_q15( - q15_t * pSrcA, - q15_t * pSrcB, - uint32_t blockSize, - q63_t * result); - - /** - * @brief Dot product of Q31 vectors. - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] blockSize number of samples in each vector - * @param[out] *result output result returned here - * @return none. - */ - - void arm_dot_prod_q31( - q31_t * pSrcA, - q31_t * pSrcB, - uint32_t blockSize, - q63_t * result); - - /** - * @brief Shifts the elements of a Q7 vector a specified number of bits. - * @param[in] *pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_shift_q7( - q7_t * pSrc, - int8_t shiftBits, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Shifts the elements of a Q15 vector a specified number of bits. - * @param[in] *pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_shift_q15( - q15_t * pSrc, - int8_t shiftBits, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Shifts the elements of a Q31 vector a specified number of bits. - * @param[in] *pSrc points to the input vector - * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_shift_q31( - q31_t * pSrc, - int8_t shiftBits, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a floating-point vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_f32( - float32_t * pSrc, - float32_t offset, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a Q7 vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_q7( - q7_t * pSrc, - q7_t offset, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a Q15 vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_q15( - q15_t * pSrc, - q15_t offset, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Adds a constant offset to a Q31 vector. - * @param[in] *pSrc points to the input vector - * @param[in] offset is the offset to be added - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_offset_q31( - q31_t * pSrc, - q31_t offset, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a floating-point vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a Q7 vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a Q15 vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Negates the elements of a Q31 vector. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] blockSize number of samples in the vector - * @return none. - */ - - void arm_negate_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - /** - * @brief Copies the elements of a floating-point vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Copies the elements of a Q7 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_q7( - q7_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Copies the elements of a Q15 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Copies the elements of a Q31 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_copy_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - /** - * @brief Fills a constant value into a floating-point vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_f32( - float32_t value, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Fills a constant value into a Q7 vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_q7( - q7_t value, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Fills a constant value into a Q15 vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_q15( - q15_t value, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Fills a constant value into a Q31 vector. - * @param[in] value input value to be filled - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_fill_q31( - q31_t value, - q31_t * pDst, - uint32_t blockSize); - -/** - * @brief Convolution of floating-point sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst); - - - /** - * @brief Convolution of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return none. - */ - - - void arm_conv_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - -/** - * @brief Convolution of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - /** - * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - /** - * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return none. - */ - - void arm_conv_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - - /** - * @brief Convolution of Q31 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - /** - * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - /** - * @brief Convolution of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - * @return none. - */ - - void arm_conv_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - - /** - * @brief Convolution of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. - * @return none. - */ - - void arm_conv_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst); - - - /** - * @brief Partial convolution of floating-point sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - /** - * @brief Partial convolution of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] * pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - -/** - * @brief Partial convolution of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - /** - * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] * pScratch2 points to scratch buffer of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Partial convolution of Q31 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - /** - * @brief Partial convolution of Q7 sequences - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - uint32_t firstIndex, - uint32_t numPoints, - q15_t * pScratch1, - q15_t * pScratch2); - - -/** - * @brief Partial convolution of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data - * @param[in] firstIndex is the first output sample to start with. - * @param[in] numPoints is the number of output points to be computed. - * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. - */ - - arm_status arm_conv_partial_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - uint32_t firstIndex, - uint32_t numPoints); - - - - /** - * @brief Instance structure for the Q15 FIR decimator. - */ - - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - } arm_fir_decimate_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR decimator. - */ - - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - - } arm_fir_decimate_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR decimator. - */ - - typedef struct - { - uint8_t M; /**< decimation factor. */ - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - - } arm_fir_decimate_instance_f32; - - - - /** - * @brief Processing function for the floating-point FIR decimator. - * @param[in] *S points to an instance of the floating-point FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_f32( - const arm_fir_decimate_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point FIR decimator. - * @param[in,out] *S points to an instance of the floating-point FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - - arm_status arm_fir_decimate_init_f32( - arm_fir_decimate_instance_f32 * S, - uint16_t numTaps, - uint8_t M, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q15 FIR decimator. - * @param[in] *S points to an instance of the Q15 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_q15( - const arm_fir_decimate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q15 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_fast_q15( - const arm_fir_decimate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - - /** - * @brief Initialization function for the Q15 FIR decimator. - * @param[in,out] *S points to an instance of the Q15 FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - - arm_status arm_fir_decimate_init_q15( - arm_fir_decimate_instance_q15 * S, - uint16_t numTaps, - uint8_t M, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR decimator. - * @param[in] *S points to an instance of the Q31 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_q31( - const arm_fir_decimate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. - * @param[in] *S points to an instance of the Q31 FIR decimator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of input samples to process per call. - * @return none - */ - - void arm_fir_decimate_fast_q31( - arm_fir_decimate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 FIR decimator. - * @param[in,out] *S points to an instance of the Q31 FIR decimator structure. - * @param[in] numTaps number of coefficients in the filter. - * @param[in] M decimation factor. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * blockSize is not a multiple of M. - */ - - arm_status arm_fir_decimate_init_q31( - arm_fir_decimate_instance_q31 * S, - uint16_t numTaps, - uint8_t M, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - - /** - * @brief Instance structure for the Q15 FIR interpolator. - */ - - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ - } arm_fir_interpolate_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR interpolator. - */ - - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ - } arm_fir_interpolate_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR interpolator. - */ - - typedef struct - { - uint8_t L; /**< upsample factor. */ - uint16_t phaseLength; /**< length of each polyphase filter component. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ - float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ - } arm_fir_interpolate_instance_f32; - - - /** - * @brief Processing function for the Q15 FIR interpolator. - * @param[in] *S points to an instance of the Q15 FIR interpolator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_interpolate_q15( - const arm_fir_interpolate_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 FIR interpolator. - * @param[in,out] *S points to an instance of the Q15 FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - - arm_status arm_fir_interpolate_init_q15( - arm_fir_interpolate_instance_q15 * S, - uint8_t L, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 FIR interpolator. - * @param[in] *S points to an instance of the Q15 FIR interpolator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_interpolate_q31( - const arm_fir_interpolate_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 FIR interpolator. - * @param[in,out] *S points to an instance of the Q31 FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - - arm_status arm_fir_interpolate_init_q31( - arm_fir_interpolate_instance_q31 * S, - uint8_t L, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point FIR interpolator. - * @param[in] *S points to an instance of the floating-point FIR interpolator structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_interpolate_f32( - const arm_fir_interpolate_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point FIR interpolator. - * @param[in,out] *S points to an instance of the floating-point FIR interpolator structure. - * @param[in] L upsample factor. - * @param[in] numTaps number of filter coefficients in the filter. - * @param[in] *pCoeffs points to the filter coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] blockSize number of input samples to process per call. - * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if - * the filter length numTaps is not a multiple of the interpolation factor L. - */ - - arm_status arm_fir_interpolate_init_f32( - arm_fir_interpolate_instance_f32 * S, - uint8_t L, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - uint32_t blockSize); - - /** - * @brief Instance structure for the high precision Q31 Biquad cascade filter. - */ - - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ - q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ - - } arm_biquad_cas_df1_32x64_ins_q31; - - - /** - * @param[in] *S points to an instance of the high precision Q31 Biquad cascade filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cas_df1_32x64_q31( - const arm_biquad_cas_df1_32x64_ins_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @param[in,out] *S points to an instance of the high precision Q31 Biquad cascade filter structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format - * @return none - */ - - void arm_biquad_cas_df1_32x64_init_q31( - arm_biquad_cas_df1_32x64_ins_q31 * S, - uint8_t numStages, - q31_t * pCoeffs, - q63_t * pState, - uint8_t postShift); - - - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ - float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_df2T_instance_f32; - - - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ - float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_stereo_df2T_instance_f32; - - - - /** - * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. - */ - - typedef struct - { - uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ - float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ - float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ - } arm_biquad_cascade_df2T_instance_f64; - - - /** - * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in] *S points to an instance of the filter data structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df2T_f32( - const arm_biquad_cascade_df2T_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels - * @param[in] *S points to an instance of the filter data structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_stereo_df2T_f32( - const arm_biquad_cascade_stereo_df2T_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in] *S points to an instance of the filter data structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_biquad_cascade_df2T_f64( - const arm_biquad_cascade_df2T_instance_f64 * S, - float64_t * pSrc, - float64_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in,out] *S points to an instance of the filter data structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @return none - */ - - void arm_biquad_cascade_df2T_init_f32( - arm_biquad_cascade_df2T_instance_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in,out] *S points to an instance of the filter data structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @return none - */ - - void arm_biquad_cascade_stereo_df2T_init_f32( - arm_biquad_cascade_stereo_df2T_instance_f32 * S, - uint8_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - - /** - * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. - * @param[in,out] *S points to an instance of the filter data structure. - * @param[in] numStages number of 2nd order stages in the filter. - * @param[in] *pCoeffs points to the filter coefficients. - * @param[in] *pState points to the state buffer. - * @return none - */ - - void arm_biquad_cascade_df2T_init_f64( - arm_biquad_cascade_df2T_instance_f64 * S, - uint8_t numStages, - float64_t * pCoeffs, - float64_t * pState); - - - - /** - * @brief Instance structure for the Q15 FIR lattice filter. - */ - - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_q15; - - /** - * @brief Instance structure for the Q31 FIR lattice filter. - */ - - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_q31; - - /** - * @brief Instance structure for the floating-point FIR lattice filter. - */ - - typedef struct - { - uint16_t numStages; /**< number of filter stages. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ - } arm_fir_lattice_instance_f32; - - /** - * @brief Initialization function for the Q15 FIR lattice filter. - * @param[in] *S points to an instance of the Q15 FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] *pState points to the state buffer. The array is of length numStages. - * @return none. - */ - - void arm_fir_lattice_init_q15( - arm_fir_lattice_instance_q15 * S, - uint16_t numStages, - q15_t * pCoeffs, - q15_t * pState); - - - /** - * @brief Processing function for the Q15 FIR lattice filter. - * @param[in] *S points to an instance of the Q15 FIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - void arm_fir_lattice_q15( - const arm_fir_lattice_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 FIR lattice filter. - * @param[in] *S points to an instance of the Q31 FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] *pState points to the state buffer. The array is of length numStages. - * @return none. - */ - - void arm_fir_lattice_init_q31( - arm_fir_lattice_instance_q31 * S, - uint16_t numStages, - q31_t * pCoeffs, - q31_t * pState); - - - /** - * @brief Processing function for the Q31 FIR lattice filter. - * @param[in] *S points to an instance of the Q31 FIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_fir_lattice_q31( - const arm_fir_lattice_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - -/** - * @brief Initialization function for the floating-point FIR lattice filter. - * @param[in] *S points to an instance of the floating-point FIR lattice structure. - * @param[in] numStages number of filter stages. - * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. - * @param[in] *pState points to the state buffer. The array is of length numStages. - * @return none. - */ - - void arm_fir_lattice_init_f32( - arm_fir_lattice_instance_f32 * S, - uint16_t numStages, - float32_t * pCoeffs, - float32_t * pState); - - /** - * @brief Processing function for the floating-point FIR lattice filter. - * @param[in] *S points to an instance of the floating-point FIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_fir_lattice_f32( - const arm_fir_lattice_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Instance structure for the Q15 IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_q15; - - /** - * @brief Instance structure for the Q31 IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_q31; - - /** - * @brief Instance structure for the floating-point IIR lattice filter. - */ - typedef struct - { - uint16_t numStages; /**< number of stages in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ - float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ - float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ - } arm_iir_lattice_instance_f32; - - /** - * @brief Processing function for the floating-point IIR lattice filter. - * @param[in] *S points to an instance of the floating-point IIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_f32( - const arm_iir_lattice_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point IIR lattice filter. - * @param[in] *S points to an instance of the floating-point IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize-1. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_init_f32( - arm_iir_lattice_instance_f32 * S, - uint16_t numStages, - float32_t * pkCoeffs, - float32_t * pvCoeffs, - float32_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q31 IIR lattice filter. - * @param[in] *S points to an instance of the Q31 IIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_q31( - const arm_iir_lattice_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q31 IIR lattice filter. - * @param[in] *S points to an instance of the Q31 IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. - * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. - * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_init_q31( - arm_iir_lattice_instance_q31 * S, - uint16_t numStages, - q31_t * pkCoeffs, - q31_t * pvCoeffs, - q31_t * pState, - uint32_t blockSize); - - - /** - * @brief Processing function for the Q15 IIR lattice filter. - * @param[in] *S points to an instance of the Q15 IIR lattice structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_iir_lattice_q15( - const arm_iir_lattice_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - -/** - * @brief Initialization function for the Q15 IIR lattice filter. - * @param[in] *S points to an instance of the fixed-point Q15 IIR lattice structure. - * @param[in] numStages number of stages in the filter. - * @param[in] *pkCoeffs points to reflection coefficient buffer. The array is of length numStages. - * @param[in] *pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. - * @param[in] *pState points to state buffer. The array is of length numStages+blockSize. - * @param[in] blockSize number of samples to process per call. - * @return none. - */ - - void arm_iir_lattice_init_q15( - arm_iir_lattice_instance_q15 * S, - uint16_t numStages, - q15_t * pkCoeffs, - q15_t * pvCoeffs, - q15_t * pState, - uint32_t blockSize); - - /** - * @brief Instance structure for the floating-point LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - float32_t mu; /**< step size that controls filter coefficient updates. */ - } arm_lms_instance_f32; - - /** - * @brief Processing function for floating-point LMS filter. - * @param[in] *S points to an instance of the floating-point LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_f32( - const arm_lms_instance_f32 * S, - float32_t * pSrc, - float32_t * pRef, - float32_t * pOut, - float32_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for floating-point LMS filter. - * @param[in] *S points to an instance of the floating-point LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to the coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_init_f32( - arm_lms_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - float32_t mu, - uint32_t blockSize); - - /** - * @brief Instance structure for the Q15 LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q15_t mu; /**< step size that controls filter coefficient updates. */ - uint32_t postShift; /**< bit shift applied to coefficients. */ - } arm_lms_instance_q15; - - - /** - * @brief Initialization function for the Q15 LMS filter. - * @param[in] *S points to an instance of the Q15 LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to the coefficient buffer. - * @param[in] *pState points to the state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_init_q15( - arm_lms_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - q15_t mu, - uint32_t blockSize, - uint32_t postShift); - - /** - * @brief Processing function for Q15 LMS filter. - * @param[in] *S points to an instance of the Q15 LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_q15( - const arm_lms_instance_q15 * S, - q15_t * pSrc, - q15_t * pRef, - q15_t * pOut, - q15_t * pErr, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q31 LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q31_t mu; /**< step size that controls filter coefficient updates. */ - uint32_t postShift; /**< bit shift applied to coefficients. */ - - } arm_lms_instance_q31; - - /** - * @brief Processing function for Q31 LMS filter. - * @param[in] *S points to an instance of the Q15 LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_q31( - const arm_lms_instance_q31 * S, - q31_t * pSrc, - q31_t * pRef, - q31_t * pOut, - q31_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for Q31 LMS filter. - * @param[in] *S points to an instance of the Q31 LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_init_q31( - arm_lms_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - q31_t mu, - uint32_t blockSize, - uint32_t postShift); - - /** - * @brief Instance structure for the floating-point normalized LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - float32_t mu; /**< step size that control filter coefficient updates. */ - float32_t energy; /**< saves previous frame energy. */ - float32_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_f32; - - /** - * @brief Processing function for floating-point normalized LMS filter. - * @param[in] *S points to an instance of the floating-point normalized LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_f32( - arm_lms_norm_instance_f32 * S, - float32_t * pSrc, - float32_t * pRef, - float32_t * pOut, - float32_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for floating-point normalized LMS filter. - * @param[in] *S points to an instance of the floating-point LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_init_f32( - arm_lms_norm_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - float32_t mu, - uint32_t blockSize); - - - /** - * @brief Instance structure for the Q31 normalized LMS filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q31_t mu; /**< step size that controls filter coefficient updates. */ - uint8_t postShift; /**< bit shift applied to coefficients. */ - q31_t *recipTable; /**< points to the reciprocal initial value table. */ - q31_t energy; /**< saves previous frame energy. */ - q31_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_q31; - - /** - * @brief Processing function for Q31 normalized LMS filter. - * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_q31( - arm_lms_norm_instance_q31 * S, - q31_t * pSrc, - q31_t * pRef, - q31_t * pOut, - q31_t * pErr, - uint32_t blockSize); - - /** - * @brief Initialization function for Q31 normalized LMS filter. - * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_norm_init_q31( - arm_lms_norm_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - q31_t mu, - uint32_t blockSize, - uint8_t postShift); - - /** - * @brief Instance structure for the Q15 normalized LMS filter. - */ - - typedef struct - { - uint16_t numTaps; /**< Number of coefficients in the filter. */ - q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ - q15_t mu; /**< step size that controls filter coefficient updates. */ - uint8_t postShift; /**< bit shift applied to coefficients. */ - q15_t *recipTable; /**< Points to the reciprocal initial value table. */ - q15_t energy; /**< saves previous frame energy. */ - q15_t x0; /**< saves previous input sample. */ - } arm_lms_norm_instance_q15; - - /** - * @brief Processing function for Q15 normalized LMS filter. - * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. - * @param[in] *pSrc points to the block of input data. - * @param[in] *pRef points to the block of reference data. - * @param[out] *pOut points to the block of output data. - * @param[out] *pErr points to the block of error data. - * @param[in] blockSize number of samples to process. - * @return none. - */ - - void arm_lms_norm_q15( - arm_lms_norm_instance_q15 * S, - q15_t * pSrc, - q15_t * pRef, - q15_t * pOut, - q15_t * pErr, - uint32_t blockSize); - - - /** - * @brief Initialization function for Q15 normalized LMS filter. - * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. - * @param[in] numTaps number of filter coefficients. - * @param[in] *pCoeffs points to coefficient buffer. - * @param[in] *pState points to state buffer. - * @param[in] mu step size that controls filter coefficient updates. - * @param[in] blockSize number of samples to process. - * @param[in] postShift bit shift applied to coefficients. - * @return none. - */ - - void arm_lms_norm_init_q15( - arm_lms_norm_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - q15_t mu, - uint32_t blockSize, - uint8_t postShift); - - /** - * @brief Correlation of floating-point sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_f32( - float32_t * pSrcA, - uint32_t srcALen, - float32_t * pSrcB, - uint32_t srcBLen, - float32_t * pDst); - - - /** - * @brief Correlation of Q15 sequences - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @return none. - */ - void arm_correlate_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch); - - - /** - * @brief Correlation of Q15 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - /** - * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_fast_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst); - - - - /** - * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @return none. - */ - - void arm_correlate_fast_opt_q15( - q15_t * pSrcA, - uint32_t srcALen, - q15_t * pSrcB, - uint32_t srcBLen, - q15_t * pDst, - q15_t * pScratch); - - /** - * @brief Correlation of Q31 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - /** - * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_fast_q31( - q31_t * pSrcA, - uint32_t srcALen, - q31_t * pSrcB, - uint32_t srcBLen, - q31_t * pDst); - - - - /** - * @brief Correlation of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. - * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). - * @return none. - */ - - void arm_correlate_opt_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst, - q15_t * pScratch1, - q15_t * pScratch2); - - - /** - * @brief Correlation of Q7 sequences. - * @param[in] *pSrcA points to the first input sequence. - * @param[in] srcALen length of the first input sequence. - * @param[in] *pSrcB points to the second input sequence. - * @param[in] srcBLen length of the second input sequence. - * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. - * @return none. - */ - - void arm_correlate_q7( - q7_t * pSrcA, - uint32_t srcALen, - q7_t * pSrcB, - uint32_t srcBLen, - q7_t * pDst); - - - /** - * @brief Instance structure for the floating-point sparse FIR filter. - */ - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_f32; - - /** - * @brief Instance structure for the Q31 sparse FIR filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q31; - - /** - * @brief Instance structure for the Q15 sparse FIR filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q15; - - /** - * @brief Instance structure for the Q7 sparse FIR filter. - */ - - typedef struct - { - uint16_t numTaps; /**< number of coefficients in the filter. */ - uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ - q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ - q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ - uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ - int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ - } arm_fir_sparse_instance_q7; - - /** - * @brief Processing function for the floating-point sparse FIR filter. - * @param[in] *S points to an instance of the floating-point sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_f32( - arm_fir_sparse_instance_f32 * S, - float32_t * pSrc, - float32_t * pDst, - float32_t * pScratchIn, - uint32_t blockSize); - - /** - * @brief Initialization function for the floating-point sparse FIR filter. - * @param[in,out] *S points to an instance of the floating-point sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_f32( - arm_fir_sparse_instance_f32 * S, - uint16_t numTaps, - float32_t * pCoeffs, - float32_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - /** - * @brief Processing function for the Q31 sparse FIR filter. - * @param[in] *S points to an instance of the Q31 sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_q31( - arm_fir_sparse_instance_q31 * S, - q31_t * pSrc, - q31_t * pDst, - q31_t * pScratchIn, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q31 sparse FIR filter. - * @param[in,out] *S points to an instance of the Q31 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_q31( - arm_fir_sparse_instance_q31 * S, - uint16_t numTaps, - q31_t * pCoeffs, - q31_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - /** - * @brief Processing function for the Q15 sparse FIR filter. - * @param[in] *S points to an instance of the Q15 sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] *pScratchOut points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_q15( - arm_fir_sparse_instance_q15 * S, - q15_t * pSrc, - q15_t * pDst, - q15_t * pScratchIn, - q31_t * pScratchOut, - uint32_t blockSize); - - - /** - * @brief Initialization function for the Q15 sparse FIR filter. - * @param[in,out] *S points to an instance of the Q15 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_q15( - arm_fir_sparse_instance_q15 * S, - uint16_t numTaps, - q15_t * pCoeffs, - q15_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - /** - * @brief Processing function for the Q7 sparse FIR filter. - * @param[in] *S points to an instance of the Q7 sparse FIR structure. - * @param[in] *pSrc points to the block of input data. - * @param[out] *pDst points to the block of output data - * @param[in] *pScratchIn points to a temporary buffer of size blockSize. - * @param[in] *pScratchOut points to a temporary buffer of size blockSize. - * @param[in] blockSize number of input samples to process per call. - * @return none. - */ - - void arm_fir_sparse_q7( - arm_fir_sparse_instance_q7 * S, - q7_t * pSrc, - q7_t * pDst, - q7_t * pScratchIn, - q31_t * pScratchOut, - uint32_t blockSize); - - /** - * @brief Initialization function for the Q7 sparse FIR filter. - * @param[in,out] *S points to an instance of the Q7 sparse FIR structure. - * @param[in] numTaps number of nonzero coefficients in the filter. - * @param[in] *pCoeffs points to the array of filter coefficients. - * @param[in] *pState points to the state buffer. - * @param[in] *pTapDelay points to the array of offset times. - * @param[in] maxDelay maximum offset time supported. - * @param[in] blockSize number of samples that will be processed per block. - * @return none - */ - - void arm_fir_sparse_init_q7( - arm_fir_sparse_instance_q7 * S, - uint16_t numTaps, - q7_t * pCoeffs, - q7_t * pState, - int32_t * pTapDelay, - uint16_t maxDelay, - uint32_t blockSize); - - - /* - * @brief Floating-point sin_cos function. - * @param[in] theta input value in degrees - * @param[out] *pSinVal points to the processed sine output. - * @param[out] *pCosVal points to the processed cos output. - * @return none. - */ - - void arm_sin_cos_f32( - float32_t theta, - float32_t * pSinVal, - float32_t * pCcosVal); - - /* - * @brief Q31 sin_cos function. - * @param[in] theta scaled input value in degrees - * @param[out] *pSinVal points to the processed sine output. - * @param[out] *pCosVal points to the processed cosine output. - * @return none. - */ - - void arm_sin_cos_q31( - q31_t theta, - q31_t * pSinVal, - q31_t * pCosVal); - - - /** - * @brief Floating-point complex conjugate. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_conj_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex conjugate. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_conj_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - /** - * @brief Q15 complex conjugate. - * @param[in] *pSrc points to the input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_conj_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - - /** - * @brief Floating-point complex magnitude squared - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_squared_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex magnitude squared - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_squared_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - /** - * @brief Q15 complex magnitude squared - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_squared_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - - /** - * @ingroup groupController - */ - - /** - * @defgroup PID PID Motor Control - * - * A Proportional Integral Derivative (PID) controller is a generic feedback control - * loop mechanism widely used in industrial control systems. - * A PID controller is the most commonly used type of feedback controller. - * - * This set of functions implements (PID) controllers - * for Q15, Q31, and floating-point data types. The functions operate on a single sample - * of data and each call to the function returns a single processed value. - * S points to an instance of the PID control data structure. in - * is the input sample value. The functions return the output value. - * - * \par Algorithm: - *
-   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
-   *    A0 = Kp + Ki + Kd
-   *    A1 = (-Kp ) - (2 * Kd )
-   *    A2 = Kd  
- * - * \par - * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant - * - * \par - * \image html PID.gif "Proportional Integral Derivative Controller" - * - * \par - * The PID controller calculates an "error" value as the difference between - * the measured output and the reference input. - * The controller attempts to minimize the error by adjusting the process control inputs. - * The proportional value determines the reaction to the current error, - * the integral value determines the reaction based on the sum of recent errors, - * and the derivative value determines the reaction based on the rate at which the error has been changing. - * - * \par Instance Structure - * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. - * A separate instance structure must be defined for each PID Controller. - * There are separate instance structure declarations for each of the 3 supported data types. - * - * \par Reset Functions - * There is also an associated reset function for each data type which clears the state array. - * - * \par Initialization Functions - * There is also an associated initialization function for each data type. - * The initialization function performs the following operations: - * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. - * - Zeros out the values in the state buffer. - * - * \par - * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. - * - * \par Fixed-Point Behavior - * Care must be taken when using the fixed-point versions of the PID Controller functions. - * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup PID - * @{ - */ - - /** - * @brief Process function for the floating-point PID Control. - * @param[in,out] *S is an instance of the floating-point PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - */ - - - static __INLINE float32_t arm_pid_f32( - arm_pid_instance_f32 * S, - float32_t in) - { - float32_t out; - - /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ - out = (S->A0 * in) + - (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @brief Process function for the Q31 PID Control. - * @param[in,out] *S points to an instance of the Q31 PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 64-bit accumulator. - * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. - * Thus, if the accumulator result overflows it wraps around rather than clip. - * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. - * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. - */ - - static __INLINE q31_t arm_pid_q31( - arm_pid_instance_q31 * S, - q31_t in) - { - q63_t acc; - q31_t out; - - /* acc = A0 * x[n] */ - acc = (q63_t) S->A0 * in; - - /* acc += A1 * x[n-1] */ - acc += (q63_t) S->A1 * S->state[0]; - - /* acc += A2 * x[n-2] */ - acc += (q63_t) S->A2 * S->state[1]; - - /* convert output to 1.31 format to add y[n-1] */ - out = (q31_t) (acc >> 31u); - - /* out += y[n-1] */ - out += S->state[2]; - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @brief Process function for the Q15 PID Control. - * @param[in,out] *S points to an instance of the Q15 PID Control structure - * @param[in] in input sample to process - * @return out processed output sample. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using a 64-bit internal accumulator. - * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. - * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. - * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. - * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. - * Lastly, the accumulator is saturated to yield a result in 1.15 format. - */ - - static __INLINE q15_t arm_pid_q15( - arm_pid_instance_q15 * S, - q15_t in) - { - q63_t acc; - q15_t out; - -#ifndef ARM_MATH_CM0_FAMILY - __SIMD32_TYPE *vstate; - - /* Implementation of PID controller */ - - /* acc = A0 * x[n] */ - acc = (q31_t) __SMUAD(S->A0, in); - - /* acc += A1 * x[n-1] + A2 * x[n-2] */ - vstate = __SIMD32_CONST(S->state); - acc = __SMLALD(S->A1, (q31_t) *vstate, acc); - -#else - /* acc = A0 * x[n] */ - acc = ((q31_t) S->A0) * in; - - /* acc += A1 * x[n-1] + A2 * x[n-2] */ - acc += (q31_t) S->A1 * S->state[0]; - acc += (q31_t) S->A2 * S->state[1]; - -#endif - - /* acc += y[n-1] */ - acc += (q31_t) S->state[2] << 15; - - /* saturate the output */ - out = (q15_t) (__SSAT((acc >> 15), 16)); - - /* Update state */ - S->state[1] = S->state[0]; - S->state[0] = in; - S->state[2] = out; - - /* return to application */ - return (out); - - } - - /** - * @} end of PID group - */ - - - /** - * @brief Floating-point matrix inverse. - * @param[in] *src points to the instance of the input floating-point matrix structure. - * @param[out] *dst points to the instance of the output floating-point matrix structure. - * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. - * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. - */ - - arm_status arm_mat_inverse_f32( - const arm_matrix_instance_f32 * src, - arm_matrix_instance_f32 * dst); - - - /** - * @brief Floating-point matrix inverse. - * @param[in] *src points to the instance of the input floating-point matrix structure. - * @param[out] *dst points to the instance of the output floating-point matrix structure. - * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. - * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. - */ - - arm_status arm_mat_inverse_f64( - const arm_matrix_instance_f64 * src, - arm_matrix_instance_f64 * dst); - - - - /** - * @ingroup groupController - */ - - - /** - * @defgroup clarke Vector Clarke Transform - * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. - * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents - * in the two-phase orthogonal stator axis Ialpha and Ibeta. - * When Ialpha is superposed with Ia as shown in the figure below - * \image html clarke.gif Stator current space vector and its components in (a,b). - * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta - * can be calculated using only Ia and Ib. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html clarkeFormula.gif - * where Ia and Ib are the instantaneous stator phases and - * pIalpha and pIbeta are the two coordinates of time invariant vector. - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Clarke transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup clarke - * @{ - */ - - /** - * - * @brief Floating-point Clarke transform - * @param[in] Ia input three-phase coordinate a - * @param[in] Ib input three-phase coordinate b - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @return none. - */ - - static __INLINE void arm_clarke_f32( - float32_t Ia, - float32_t Ib, - float32_t * pIalpha, - float32_t * pIbeta) - { - /* Calculate pIalpha using the equation, pIalpha = Ia */ - *pIalpha = Ia; - - /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ - *pIbeta = - ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); - - } - - /** - * @brief Clarke transform for Q31 version - * @param[in] Ia input three-phase coordinate a - * @param[in] Ib input three-phase coordinate b - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition, hence there is no risk of overflow. - */ - - static __INLINE void arm_clarke_q31( - q31_t Ia, - q31_t Ib, - q31_t * pIalpha, - q31_t * pIbeta) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - - /* Calculating pIalpha from Ia by equation pIalpha = Ia */ - *pIalpha = Ia; - - /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ - product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); - - /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ - product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); - - /* pIbeta is calculated by adding the intermediate products */ - *pIbeta = __QADD(product1, product2); - } - - /** - * @} end of clarke group - */ - - /** - * @brief Converts the elements of the Q7 vector to Q31 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_q7_to_q31( - q7_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup inv_clarke Vector Inverse Clarke Transform - * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html clarkeInvFormula.gif - * where pIa and pIb are the instantaneous stator phases and - * Ialpha and Ibeta are the two coordinates of time invariant vector. - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Clarke transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup inv_clarke - * @{ - */ - - /** - * @brief Floating-point Inverse Clarke transform - * @param[in] Ialpha input two-phase orthogonal vector axis alpha - * @param[in] Ibeta input two-phase orthogonal vector axis beta - * @param[out] *pIa points to output three-phase coordinate a - * @param[out] *pIb points to output three-phase coordinate b - * @return none. - */ - - - static __INLINE void arm_inv_clarke_f32( - float32_t Ialpha, - float32_t Ibeta, - float32_t * pIa, - float32_t * pIb) - { - /* Calculating pIa from Ialpha by equation pIa = Ialpha */ - *pIa = Ialpha; - - /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ - *pIb = -0.5 * Ialpha + (float32_t) 0.8660254039 *Ibeta; - - } - - /** - * @brief Inverse Clarke transform for Q31 version - * @param[in] Ialpha input two-phase orthogonal vector axis alpha - * @param[in] Ibeta input two-phase orthogonal vector axis beta - * @param[out] *pIa points to output three-phase coordinate a - * @param[out] *pIb points to output three-phase coordinate b - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the subtraction, hence there is no risk of overflow. - */ - - static __INLINE void arm_inv_clarke_q31( - q31_t Ialpha, - q31_t Ibeta, - q31_t * pIa, - q31_t * pIb) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - - /* Calculating pIa from Ialpha by equation pIa = Ialpha */ - *pIa = Ialpha; - - /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ - product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); - - /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ - product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); - - /* pIb is calculated by subtracting the products */ - *pIb = __QSUB(product2, product1); - - } - - /** - * @} end of inv_clarke group - */ - - /** - * @brief Converts the elements of the Q7 vector to Q15 vector. - * @param[in] *pSrc input pointer - * @param[out] *pDst output pointer - * @param[in] blockSize number of samples to process - * @return none. - */ - void arm_q7_to_q15( - q7_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - - - /** - * @ingroup groupController - */ - - /** - * @defgroup park Vector Park Transform - * - * Forward Park transform converts the input two-coordinate vector to flux and torque components. - * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents - * from the stationary to the moving reference frame and control the spatial relationship between - * the stator vector current and rotor flux vector. - * If we consider the d axis aligned with the rotor flux, the diagram below shows the - * current vector and the relationship from the two reference frames: - * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html parkFormula.gif - * where Ialpha and Ibeta are the stator vector components, - * pId and pIq are rotor vector components and cosVal and sinVal are the - * cosine and sine values of theta (rotor flux position). - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Park transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup park - * @{ - */ - - /** - * @brief Floating-point Park transform - * @param[in] Ialpha input two-phase vector coordinate alpha - * @param[in] Ibeta input two-phase vector coordinate beta - * @param[out] *pId points to output rotor reference frame d - * @param[out] *pIq points to output rotor reference frame q - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - * - * The function implements the forward Park transform. - * - */ - - static __INLINE void arm_park_f32( - float32_t Ialpha, - float32_t Ibeta, - float32_t * pId, - float32_t * pIq, - float32_t sinVal, - float32_t cosVal) - { - /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ - *pId = Ialpha * cosVal + Ibeta * sinVal; - - /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ - *pIq = -Ialpha * sinVal + Ibeta * cosVal; - - } - - /** - * @brief Park transform for Q31 version - * @param[in] Ialpha input two-phase vector coordinate alpha - * @param[in] Ibeta input two-phase vector coordinate beta - * @param[out] *pId points to output rotor reference frame d - * @param[out] *pIq points to output rotor reference frame q - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition and subtraction, hence there is no risk of overflow. - */ - - - static __INLINE void arm_park_q31( - q31_t Ialpha, - q31_t Ibeta, - q31_t * pId, - q31_t * pIq, - q31_t sinVal, - q31_t cosVal) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - q31_t product3, product4; /* Temporary variables used to store intermediate results */ - - /* Intermediate product is calculated by (Ialpha * cosVal) */ - product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); - - /* Intermediate product is calculated by (Ibeta * sinVal) */ - product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); - - - /* Intermediate product is calculated by (Ialpha * sinVal) */ - product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); - - /* Intermediate product is calculated by (Ibeta * cosVal) */ - product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); - - /* Calculate pId by adding the two intermediate products 1 and 2 */ - *pId = __QADD(product1, product2); - - /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ - *pIq = __QSUB(product4, product3); - } - - /** - * @} end of park group - */ - - /** - * @brief Converts the elements of the Q7 vector to floating-point vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q7_to_float( - q7_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @ingroup groupController - */ - - /** - * @defgroup inv_park Vector Inverse Park transform - * Inverse Park transform converts the input flux and torque components to two-coordinate vector. - * - * The function operates on a single sample of data and each call to the function returns the processed output. - * The library provides separate functions for Q31 and floating-point data types. - * \par Algorithm - * \image html parkInvFormula.gif - * where pIalpha and pIbeta are the stator vector components, - * Id and Iq are rotor vector components and cosVal and sinVal are the - * cosine and sine values of theta (rotor flux position). - * \par Fixed-Point Behavior - * Care must be taken when using the Q31 version of the Park transform. - * In particular, the overflow and saturation behavior of the accumulator used must be considered. - * Refer to the function specific documentation below for usage guidelines. - */ - - /** - * @addtogroup inv_park - * @{ - */ - - /** - * @brief Floating-point Inverse Park transform - * @param[in] Id input coordinate of rotor reference frame d - * @param[in] Iq input coordinate of rotor reference frame q - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - */ - - static __INLINE void arm_inv_park_f32( - float32_t Id, - float32_t Iq, - float32_t * pIalpha, - float32_t * pIbeta, - float32_t sinVal, - float32_t cosVal) - { - /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ - *pIalpha = Id * cosVal - Iq * sinVal; - - /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ - *pIbeta = Id * sinVal + Iq * cosVal; - - } - - - /** - * @brief Inverse Park transform for Q31 version - * @param[in] Id input coordinate of rotor reference frame d - * @param[in] Iq input coordinate of rotor reference frame q - * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha - * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta - * @param[in] sinVal sine value of rotation angle theta - * @param[in] cosVal cosine value of rotation angle theta - * @return none. - * - * Scaling and Overflow Behavior: - * \par - * The function is implemented using an internal 32-bit accumulator. - * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. - * There is saturation on the addition, hence there is no risk of overflow. - */ - - - static __INLINE void arm_inv_park_q31( - q31_t Id, - q31_t Iq, - q31_t * pIalpha, - q31_t * pIbeta, - q31_t sinVal, - q31_t cosVal) - { - q31_t product1, product2; /* Temporary variables used to store intermediate results */ - q31_t product3, product4; /* Temporary variables used to store intermediate results */ - - /* Intermediate product is calculated by (Id * cosVal) */ - product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); - - /* Intermediate product is calculated by (Iq * sinVal) */ - product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); - - - /* Intermediate product is calculated by (Id * sinVal) */ - product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); - - /* Intermediate product is calculated by (Iq * cosVal) */ - product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); - - /* Calculate pIalpha by using the two intermediate products 1 and 2 */ - *pIalpha = __QSUB(product1, product2); - - /* Calculate pIbeta by using the two intermediate products 3 and 4 */ - *pIbeta = __QADD(product4, product3); - - } - - /** - * @} end of Inverse park group - */ - - - /** - * @brief Converts the elements of the Q31 vector to floating-point vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q31_to_float( - q31_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - /** - * @ingroup groupInterpolation - */ - - /** - * @defgroup LinearInterpolate Linear Interpolation - * - * Linear interpolation is a method of curve fitting using linear polynomials. - * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line - * - * \par - * \image html LinearInterp.gif "Linear interpolation" - * - * \par - * A Linear Interpolate function calculates an output value(y), for the input(x) - * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) - * - * \par Algorithm: - *
-   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
-   *       where x0, x1 are nearest values of input x
-   *             y0, y1 are nearest values to output y
-   * 
- * - * \par - * This set of functions implements Linear interpolation process - * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single - * sample of data and each call to the function returns a single processed value. - * S points to an instance of the Linear Interpolate function data structure. - * x is the input sample value. The functions returns the output value. - * - * \par - * if x is outside of the table boundary, Linear interpolation returns first value of the table - * if x is below input range and returns last value of table if x is above range. - */ - - /** - * @addtogroup LinearInterpolate - * @{ - */ - - /** - * @brief Process function for the floating-point Linear Interpolation Function. - * @param[in,out] *S is an instance of the floating-point Linear Interpolation structure - * @param[in] x input sample to process - * @return y processed output sample. - * - */ - - static __INLINE float32_t arm_linear_interp_f32( - arm_linear_interp_instance_f32 * S, - float32_t x) - { - - float32_t y; - float32_t x0, x1; /* Nearest input values */ - float32_t y0, y1; /* Nearest output values */ - float32_t xSpacing = S->xSpacing; /* spacing between input values */ - int32_t i; /* Index variable */ - float32_t *pYData = S->pYData; /* pointer to output table */ - - /* Calculation of index */ - i = (int32_t) ((x - S->x1) / xSpacing); - - if(i < 0) - { - /* Iniatilize output for below specified range as least output value of table */ - y = pYData[0]; - } - else if((uint32_t)i >= S->nValues) - { - /* Iniatilize output for above specified range as last output value of table */ - y = pYData[S->nValues - 1]; - } - else - { - /* Calculation of nearest input values */ - x0 = S->x1 + i * xSpacing; - x1 = S->x1 + (i + 1) * xSpacing; - - /* Read of nearest output values */ - y0 = pYData[i]; - y1 = pYData[i + 1]; - - /* Calculation of output */ - y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); - - } - - /* returns output value */ - return (y); - } - - /** - * - * @brief Process function for the Q31 Linear Interpolation Function. - * @param[in] *pYData pointer to Q31 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - * - */ - - - static __INLINE q31_t arm_linear_interp_q31( - q31_t * pYData, - q31_t x, - uint32_t nValues) - { - q31_t y; /* output */ - q31_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & 0xFFF00000) >> 20); - - if(index >= (int32_t)(nValues - 1)) - { - return (pYData[nValues - 1]); - } - else if(index < 0) - { - return (pYData[0]); - } - else - { - - /* 20 bits for the fractional part */ - /* shift left by 11 to keep fract in 1.31 format */ - fract = (x & 0x000FFFFF) << 11; - - /* Read two nearest output values from the index in 1.31(q31) format */ - y0 = pYData[index]; - y1 = pYData[index + 1u]; - - /* Calculation of y0 * (1-fract) and y is in 2.30 format */ - y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); - - /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ - y += ((q31_t) (((q63_t) y1 * fract) >> 32)); - - /* Convert y to 1.31 format */ - return (y << 1u); - - } - - } - - /** - * - * @brief Process function for the Q15 Linear Interpolation Function. - * @param[in] *pYData pointer to Q15 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - * - */ - - - static __INLINE q15_t arm_linear_interp_q15( - q15_t * pYData, - q31_t x, - uint32_t nValues) - { - q63_t y; /* output */ - q15_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - int32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - index = ((x & 0xFFF00000) >> 20u); - - if(index >= (int32_t)(nValues - 1)) - { - return (pYData[nValues - 1]); - } - else if(index < 0) - { - return (pYData[0]); - } - else - { - /* 20 bits for the fractional part */ - /* fract is in 12.20 format */ - fract = (x & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y0 = pYData[index]; - y1 = pYData[index + 1u]; - - /* Calculation of y0 * (1-fract) and y is in 13.35 format */ - y = ((q63_t) y0 * (0xFFFFF - fract)); - - /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ - y += ((q63_t) y1 * (fract)); - - /* convert y to 1.15 format */ - return (y >> 20); - } - - - } - - /** - * - * @brief Process function for the Q7 Linear Interpolation Function. - * @param[in] *pYData pointer to Q7 Linear Interpolation table - * @param[in] x input sample to process - * @param[in] nValues number of table values - * @return y processed output sample. - * - * \par - * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. - * This function can support maximum of table size 2^12. - */ - - - static __INLINE q7_t arm_linear_interp_q7( - q7_t * pYData, - q31_t x, - uint32_t nValues) - { - q31_t y; /* output */ - q7_t y0, y1; /* Nearest output values */ - q31_t fract; /* fractional part */ - uint32_t index; /* Index to read nearest output values */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - if (x < 0) - { - return (pYData[0]); - } - index = (x >> 20) & 0xfff; - - - if(index >= (nValues - 1)) - { - return (pYData[nValues - 1]); - } - else - { - - /* 20 bits for the fractional part */ - /* fract is in 12.20 format */ - fract = (x & 0x000FFFFF); - - /* Read two nearest output values from the index and are in 1.7(q7) format */ - y0 = pYData[index]; - y1 = pYData[index + 1u]; - - /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ - y = ((y0 * (0xFFFFF - fract))); - - /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ - y += (y1 * fract); - - /* convert y to 1.7(q7) format */ - return (y >> 20u); - - } - - } - /** - * @} end of LinearInterpolate group - */ - - /** - * @brief Fast approximation to the trigonometric sine function for floating-point data. - * @param[in] x input value in radians. - * @return sin(x). - */ - - float32_t arm_sin_f32( - float32_t x); - - /** - * @brief Fast approximation to the trigonometric sine function for Q31 data. - * @param[in] x Scaled input value in radians. - * @return sin(x). - */ - - q31_t arm_sin_q31( - q31_t x); - - /** - * @brief Fast approximation to the trigonometric sine function for Q15 data. - * @param[in] x Scaled input value in radians. - * @return sin(x). - */ - - q15_t arm_sin_q15( - q15_t x); - - /** - * @brief Fast approximation to the trigonometric cosine function for floating-point data. - * @param[in] x input value in radians. - * @return cos(x). - */ - - float32_t arm_cos_f32( - float32_t x); - - /** - * @brief Fast approximation to the trigonometric cosine function for Q31 data. - * @param[in] x Scaled input value in radians. - * @return cos(x). - */ - - q31_t arm_cos_q31( - q31_t x); - - /** - * @brief Fast approximation to the trigonometric cosine function for Q15 data. - * @param[in] x Scaled input value in radians. - * @return cos(x). - */ - - q15_t arm_cos_q15( - q15_t x); - - - /** - * @ingroup groupFastMath - */ - - - /** - * @defgroup SQRT Square Root - * - * Computes the square root of a number. - * There are separate functions for Q15, Q31, and floating-point data types. - * The square root function is computed using the Newton-Raphson algorithm. - * This is an iterative algorithm of the form: - *
-   *      x1 = x0 - f(x0)/f'(x0)
-   * 
- * where x1 is the current estimate, - * x0 is the previous estimate, and - * f'(x0) is the derivative of f() evaluated at x0. - * For the square root function, the algorithm reduces to: - *
-   *     x0 = in/2                         [initial guess]
-   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
-   * 
- */ - - - /** - * @addtogroup SQRT - * @{ - */ - - /** - * @brief Floating-point square root function. - * @param[in] in input value. - * @param[out] *pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - - static __INLINE arm_status arm_sqrt_f32( - float32_t in, - float32_t * pOut) - { - if(in > 0) - { - -// #if __FPU_USED -#if (__FPU_USED == 1) && defined ( __CC_ARM ) - *pOut = __sqrtf(in); -#else - *pOut = sqrtf(in); -#endif - - return (ARM_MATH_SUCCESS); - } - else - { - *pOut = 0.0f; - return (ARM_MATH_ARGUMENT_ERROR); - } - - } - - - /** - * @brief Q31 square root function. - * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. - * @param[out] *pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - arm_status arm_sqrt_q31( - q31_t in, - q31_t * pOut); - - /** - * @brief Q15 square root function. - * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. - * @param[out] *pOut square root of input value. - * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if - * in is negative value and returns zero output for negative values. - */ - arm_status arm_sqrt_q15( - q15_t in, - q15_t * pOut); - - /** - * @} end of SQRT group - */ - - - - - - - /** - * @brief floating-point Circular write function. - */ - - static __INLINE void arm_circularWrite_f32( - int32_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const int32_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if(wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = wOffset; - } - - - - /** - * @brief floating-point Circular Read function. - */ - static __INLINE void arm_circularRead_f32( - int32_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - int32_t * dst, - int32_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if(dst == (int32_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update rOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if(rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - /** - * @brief Q15 Circular write function. - */ - - static __INLINE void arm_circularWrite_q15( - q15_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const q15_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if(wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = wOffset; - } - - - - /** - * @brief Q15 Circular Read function. - */ - static __INLINE void arm_circularRead_q15( - q15_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - q15_t * dst, - q15_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if(dst == (q15_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update wOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if(rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - - /** - * @brief Q7 Circular write function. - */ - - static __INLINE void arm_circularWrite_q7( - q7_t * circBuffer, - int32_t L, - uint16_t * writeOffset, - int32_t bufferInc, - const q7_t * src, - int32_t srcInc, - uint32_t blockSize) - { - uint32_t i = 0u; - int32_t wOffset; - - /* Copy the value of Index pointer that points - * to the current location where the input samples to be copied */ - wOffset = *writeOffset; - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the input sample to the circular buffer */ - circBuffer[wOffset] = *src; - - /* Update the input pointer */ - src += srcInc; - - /* Circularly update wOffset. Watch out for positive and negative value */ - wOffset += bufferInc; - if(wOffset >= L) - wOffset -= L; - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *writeOffset = wOffset; - } - - - - /** - * @brief Q7 Circular Read function. - */ - static __INLINE void arm_circularRead_q7( - q7_t * circBuffer, - int32_t L, - int32_t * readOffset, - int32_t bufferInc, - q7_t * dst, - q7_t * dst_base, - int32_t dst_length, - int32_t dstInc, - uint32_t blockSize) - { - uint32_t i = 0; - int32_t rOffset, dst_end; - - /* Copy the value of Index pointer that points - * to the current location from where the input samples to be read */ - rOffset = *readOffset; - - dst_end = (int32_t) (dst_base + dst_length); - - /* Loop over the blockSize */ - i = blockSize; - - while(i > 0u) - { - /* copy the sample from the circular buffer to the destination buffer */ - *dst = circBuffer[rOffset]; - - /* Update the input pointer */ - dst += dstInc; - - if(dst == (q7_t *) dst_end) - { - dst = dst_base; - } - - /* Circularly update rOffset. Watch out for positive and negative value */ - rOffset += bufferInc; - - if(rOffset >= L) - { - rOffset -= L; - } - - /* Decrement the loop counter */ - i--; - } - - /* Update the index pointer */ - *readOffset = rOffset; - } - - - /** - * @brief Sum of the squares of the elements of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_power_q31( - q31_t * pSrc, - uint32_t blockSize, - q63_t * pResult); - - /** - * @brief Sum of the squares of the elements of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_power_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - /** - * @brief Sum of the squares of the elements of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_power_q15( - q15_t * pSrc, - uint32_t blockSize, - q63_t * pResult); - - /** - * @brief Sum of the squares of the elements of a Q7 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_power_q7( - q7_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - /** - * @brief Mean value of a Q7 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_mean_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * pResult); - - /** - * @brief Mean value of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - void arm_mean_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - /** - * @brief Mean value of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - void arm_mean_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - /** - * @brief Mean value of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - void arm_mean_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - /** - * @brief Variance of the elements of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_var_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - /** - * @brief Variance of the elements of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_var_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - /** - * @brief Variance of the elements of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_var_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - /** - * @brief Root Mean Square of the elements of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_rms_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - /** - * @brief Root Mean Square of the elements of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_rms_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - /** - * @brief Root Mean Square of the elements of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_rms_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - /** - * @brief Standard deviation of the elements of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_std_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult); - - /** - * @brief Standard deviation of the elements of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_std_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult); - - /** - * @brief Standard deviation of the elements of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output value. - * @return none. - */ - - void arm_std_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult); - - /** - * @brief Floating-point complex magnitude - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_f32( - float32_t * pSrc, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex magnitude - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_q31( - q31_t * pSrc, - q31_t * pDst, - uint32_t numSamples); - - /** - * @brief Q15 complex magnitude - * @param[in] *pSrc points to the complex input vector - * @param[out] *pDst points to the real output vector - * @param[in] numSamples number of complex samples in the input vector - * @return none. - */ - - void arm_cmplx_mag_q15( - q15_t * pSrc, - q15_t * pDst, - uint32_t numSamples); - - /** - * @brief Q15 complex dot product - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] *realResult real part of the result returned here - * @param[out] *imagResult imaginary part of the result returned here - * @return none. - */ - - void arm_cmplx_dot_prod_q15( - q15_t * pSrcA, - q15_t * pSrcB, - uint32_t numSamples, - q31_t * realResult, - q31_t * imagResult); - - /** - * @brief Q31 complex dot product - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] *realResult real part of the result returned here - * @param[out] *imagResult imaginary part of the result returned here - * @return none. - */ - - void arm_cmplx_dot_prod_q31( - q31_t * pSrcA, - q31_t * pSrcB, - uint32_t numSamples, - q63_t * realResult, - q63_t * imagResult); - - /** - * @brief Floating-point complex dot product - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[in] numSamples number of complex samples in each vector - * @param[out] *realResult real part of the result returned here - * @param[out] *imagResult imaginary part of the result returned here - * @return none. - */ - - void arm_cmplx_dot_prod_f32( - float32_t * pSrcA, - float32_t * pSrcB, - uint32_t numSamples, - float32_t * realResult, - float32_t * imagResult); - - /** - * @brief Q15 complex-by-real multiplication - * @param[in] *pSrcCmplx points to the complex input vector - * @param[in] *pSrcReal points to the real input vector - * @param[out] *pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - * @return none. - */ - - void arm_cmplx_mult_real_q15( - q15_t * pSrcCmplx, - q15_t * pSrcReal, - q15_t * pCmplxDst, - uint32_t numSamples); - - /** - * @brief Q31 complex-by-real multiplication - * @param[in] *pSrcCmplx points to the complex input vector - * @param[in] *pSrcReal points to the real input vector - * @param[out] *pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - * @return none. - */ - - void arm_cmplx_mult_real_q31( - q31_t * pSrcCmplx, - q31_t * pSrcReal, - q31_t * pCmplxDst, - uint32_t numSamples); - - /** - * @brief Floating-point complex-by-real multiplication - * @param[in] *pSrcCmplx points to the complex input vector - * @param[in] *pSrcReal points to the real input vector - * @param[out] *pCmplxDst points to the complex output vector - * @param[in] numSamples number of samples in each vector - * @return none. - */ - - void arm_cmplx_mult_real_f32( - float32_t * pSrcCmplx, - float32_t * pSrcReal, - float32_t * pCmplxDst, - uint32_t numSamples); - - /** - * @brief Minimum value of a Q7 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *result is output pointer - * @param[in] index is the array index of the minimum value in the input buffer. - * @return none. - */ - - void arm_min_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * result, - uint32_t * index); - - /** - * @brief Minimum value of a Q15 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output pointer - * @param[in] *pIndex is the array index of the minimum value in the input buffer. - * @return none. - */ - - void arm_min_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult, - uint32_t * pIndex); - - /** - * @brief Minimum value of a Q31 vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output pointer - * @param[out] *pIndex is the array index of the minimum value in the input buffer. - * @return none. - */ - void arm_min_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult, - uint32_t * pIndex); - - /** - * @brief Minimum value of a floating-point vector. - * @param[in] *pSrc is input pointer - * @param[in] blockSize is the number of samples to process - * @param[out] *pResult is output pointer - * @param[out] *pIndex is the array index of the minimum value in the input buffer. - * @return none. - */ - - void arm_min_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult, - uint32_t * pIndex); - -/** - * @brief Maximum value of a Q7 vector. - * @param[in] *pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] *pResult maximum value returned here - * @param[out] *pIndex index of maximum value returned here - * @return none. - */ - - void arm_max_q7( - q7_t * pSrc, - uint32_t blockSize, - q7_t * pResult, - uint32_t * pIndex); - -/** - * @brief Maximum value of a Q15 vector. - * @param[in] *pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] *pResult maximum value returned here - * @param[out] *pIndex index of maximum value returned here - * @return none. - */ - - void arm_max_q15( - q15_t * pSrc, - uint32_t blockSize, - q15_t * pResult, - uint32_t * pIndex); - -/** - * @brief Maximum value of a Q31 vector. - * @param[in] *pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] *pResult maximum value returned here - * @param[out] *pIndex index of maximum value returned here - * @return none. - */ - - void arm_max_q31( - q31_t * pSrc, - uint32_t blockSize, - q31_t * pResult, - uint32_t * pIndex); - -/** - * @brief Maximum value of a floating-point vector. - * @param[in] *pSrc points to the input buffer - * @param[in] blockSize length of the input vector - * @param[out] *pResult maximum value returned here - * @param[out] *pIndex index of maximum value returned here - * @return none. - */ - - void arm_max_f32( - float32_t * pSrc, - uint32_t blockSize, - float32_t * pResult, - uint32_t * pIndex); - - /** - * @brief Q15 complex-by-complex multiplication - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_mult_cmplx_q15( - q15_t * pSrcA, - q15_t * pSrcB, - q15_t * pDst, - uint32_t numSamples); - - /** - * @brief Q31 complex-by-complex multiplication - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_mult_cmplx_q31( - q31_t * pSrcA, - q31_t * pSrcB, - q31_t * pDst, - uint32_t numSamples); - - /** - * @brief Floating-point complex-by-complex multiplication - * @param[in] *pSrcA points to the first input vector - * @param[in] *pSrcB points to the second input vector - * @param[out] *pDst points to the output vector - * @param[in] numSamples number of complex samples in each vector - * @return none. - */ - - void arm_cmplx_mult_cmplx_f32( - float32_t * pSrcA, - float32_t * pSrcB, - float32_t * pDst, - uint32_t numSamples); - - /** - * @brief Converts the elements of the floating-point vector to Q31 vector. - * @param[in] *pSrc points to the floating-point input vector - * @param[out] *pDst points to the Q31 output vector - * @param[in] blockSize length of the input vector - * @return none. - */ - void arm_float_to_q31( - float32_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - /** - * @brief Converts the elements of the floating-point vector to Q15 vector. - * @param[in] *pSrc points to the floating-point input vector - * @param[out] *pDst points to the Q15 output vector - * @param[in] blockSize length of the input vector - * @return none - */ - void arm_float_to_q15( - float32_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Converts the elements of the floating-point vector to Q7 vector. - * @param[in] *pSrc points to the floating-point input vector - * @param[out] *pDst points to the Q7 output vector - * @param[in] blockSize length of the input vector - * @return none - */ - void arm_float_to_q7( - float32_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q31 vector to Q15 vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q31_to_q15( - q31_t * pSrc, - q15_t * pDst, - uint32_t blockSize); - - /** - * @brief Converts the elements of the Q31 vector to Q7 vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q31_to_q7( - q31_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - /** - * @brief Converts the elements of the Q15 vector to floating-point vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q15_to_float( - q15_t * pSrc, - float32_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q15 vector to Q31 vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q15_to_q31( - q15_t * pSrc, - q31_t * pDst, - uint32_t blockSize); - - - /** - * @brief Converts the elements of the Q15 vector to Q7 vector. - * @param[in] *pSrc is input pointer - * @param[out] *pDst is output pointer - * @param[in] blockSize is the number of samples to process - * @return none. - */ - void arm_q15_to_q7( - q15_t * pSrc, - q7_t * pDst, - uint32_t blockSize); - - - /** - * @ingroup groupInterpolation - */ - - /** - * @defgroup BilinearInterpolate Bilinear Interpolation - * - * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. - * The underlying function f(x, y) is sampled on a regular grid and the interpolation process - * determines values between the grid points. - * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. - * Bilinear interpolation is often used in image processing to rescale images. - * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. - * - * Algorithm - * \par - * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. - * For floating-point, the instance structure is defined as: - *
-   *   typedef struct
-   *   {
-   *     uint16_t numRows;
-   *     uint16_t numCols;
-   *     float32_t *pData;
-   * } arm_bilinear_interp_instance_f32;
-   * 
- * - * \par - * where numRows specifies the number of rows in the table; - * numCols specifies the number of columns in the table; - * and pData points to an array of size numRows*numCols values. - * The data table pTable is organized in row order and the supplied data values fall on integer indexes. - * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. - * - * \par - * Let (x, y) specify the desired interpolation point. Then define: - *
-   *     XF = floor(x)
-   *     YF = floor(y)
-   * 
- * \par - * The interpolated output point is computed as: - *
-   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
-   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
-   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
-   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
-   * 
- * Note that the coordinates (x, y) contain integer and fractional components. - * The integer components specify which portion of the table to use while the - * fractional components control the interpolation processor. - * - * \par - * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. - */ - - /** - * @addtogroup BilinearInterpolate - * @{ - */ - - /** - * - * @brief Floating-point bilinear interpolation. - * @param[in,out] *S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate. - * @param[in] Y interpolation coordinate. - * @return out interpolated value. - */ - - - static __INLINE float32_t arm_bilinear_interp_f32( - const arm_bilinear_interp_instance_f32 * S, - float32_t X, - float32_t Y) - { - float32_t out; - float32_t f00, f01, f10, f11; - float32_t *pData = S->pData; - int32_t xIndex, yIndex, index; - float32_t xdiff, ydiff; - float32_t b1, b2, b3, b4; - - xIndex = (int32_t) X; - yIndex = (int32_t) Y; - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 - || yIndex > (S->numCols - 1)) - { - return (0); - } - - /* Calculation of index for two nearest points in X-direction */ - index = (xIndex - 1) + (yIndex - 1) * S->numCols; - - - /* Read two nearest points in X-direction */ - f00 = pData[index]; - f01 = pData[index + 1]; - - /* Calculation of index for two nearest points in Y-direction */ - index = (xIndex - 1) + (yIndex) * S->numCols; - - - /* Read two nearest points in Y-direction */ - f10 = pData[index]; - f11 = pData[index + 1]; - - /* Calculation of intermediate values */ - b1 = f00; - b2 = f01 - f00; - b3 = f10 - f00; - b4 = f00 - f01 - f10 + f11; - - /* Calculation of fractional part in X */ - xdiff = X - xIndex; - - /* Calculation of fractional part in Y */ - ydiff = Y - yIndex; - - /* Calculation of bi-linear interpolated output */ - out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; - - /* return to application */ - return (out); - - } - - /** - * - * @brief Q31 bilinear interpolation. - * @param[in,out] *S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - - static __INLINE q31_t arm_bilinear_interp_q31( - arm_bilinear_interp_instance_q31 * S, - q31_t X, - q31_t Y) - { - q31_t out; /* Temporary output */ - q31_t acc = 0; /* output */ - q31_t xfract, yfract; /* X, Y fractional parts */ - q31_t x1, x2, y1, y2; /* Nearest output values */ - int32_t rI, cI; /* Row and column indices */ - q31_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & 0xFFF00000) >> 20u); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & 0xFFF00000) >> 20u); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) - { - return (0); - } - - /* 20 bits for the fractional part */ - /* shift left xfract by 11 to keep 1.31 format */ - xfract = (X & 0x000FFFFF) << 11u; - - /* Read two nearest output values from the index */ - x1 = pYData[(rI) + nCols * (cI)]; - x2 = pYData[(rI) + nCols * (cI) + 1u]; - - /* 20 bits for the fractional part */ - /* shift left yfract by 11 to keep 1.31 format */ - yfract = (Y & 0x000FFFFF) << 11u; - - /* Read two nearest output values from the index */ - y1 = pYData[(rI) + nCols * (cI + 1)]; - y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ - out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); - acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); - - /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); - - /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); - - /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ - out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); - acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); - - /* Convert acc to 1.31(q31) format */ - return (acc << 2u); - - } - - /** - * @brief Q15 bilinear interpolation. - * @param[in,out] *S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - - static __INLINE q15_t arm_bilinear_interp_q15( - arm_bilinear_interp_instance_q15 * S, - q31_t X, - q31_t Y) - { - q63_t acc = 0; /* output */ - q31_t out; /* Temporary output */ - q15_t x1, x2, y1, y2; /* Nearest output values */ - q31_t xfract, yfract; /* X, Y fractional parts */ - int32_t rI, cI; /* Row and column indices */ - q15_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & 0xFFF00000) >> 20); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & 0xFFF00000) >> 20); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) - { - return (0); - } - - /* 20 bits for the fractional part */ - /* xfract should be in 12.20 format */ - xfract = (X & 0x000FFFFF); - - /* Read two nearest output values from the index */ - x1 = pYData[(rI) + nCols * (cI)]; - x2 = pYData[(rI) + nCols * (cI) + 1u]; - - - /* 20 bits for the fractional part */ - /* yfract should be in 12.20 format */ - yfract = (Y & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y1 = pYData[(rI) + nCols * (cI + 1)]; - y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ - - /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ - /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ - out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); - acc = ((q63_t) out * (0xFFFFF - yfract)); - - /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); - acc += ((q63_t) out * (xfract)); - - /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); - acc += ((q63_t) out * (yfract)); - - /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ - out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); - acc += ((q63_t) out * (yfract)); - - /* acc is in 13.51 format and down shift acc by 36 times */ - /* Convert out to 1.15 format */ - return (acc >> 36); - - } - - /** - * @brief Q7 bilinear interpolation. - * @param[in,out] *S points to an instance of the interpolation structure. - * @param[in] X interpolation coordinate in 12.20 format. - * @param[in] Y interpolation coordinate in 12.20 format. - * @return out interpolated value. - */ - - static __INLINE q7_t arm_bilinear_interp_q7( - arm_bilinear_interp_instance_q7 * S, - q31_t X, - q31_t Y) - { - q63_t acc = 0; /* output */ - q31_t out; /* Temporary output */ - q31_t xfract, yfract; /* X, Y fractional parts */ - q7_t x1, x2, y1, y2; /* Nearest output values */ - int32_t rI, cI; /* Row and column indices */ - q7_t *pYData = S->pData; /* pointer to output table values */ - uint32_t nCols = S->numCols; /* num of rows */ - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - rI = ((X & 0xFFF00000) >> 20); - - /* Input is in 12.20 format */ - /* 12 bits for the table index */ - /* Index value calculation */ - cI = ((Y & 0xFFF00000) >> 20); - - /* Care taken for table outside boundary */ - /* Returns zero output when values are outside table boundary */ - if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) - { - return (0); - } - - /* 20 bits for the fractional part */ - /* xfract should be in 12.20 format */ - xfract = (X & 0x000FFFFF); - - /* Read two nearest output values from the index */ - x1 = pYData[(rI) + nCols * (cI)]; - x2 = pYData[(rI) + nCols * (cI) + 1u]; - - - /* 20 bits for the fractional part */ - /* yfract should be in 12.20 format */ - yfract = (Y & 0x000FFFFF); - - /* Read two nearest output values from the index */ - y1 = pYData[(rI) + nCols * (cI + 1)]; - y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; - - /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ - out = ((x1 * (0xFFFFF - xfract))); - acc = (((q63_t) out * (0xFFFFF - yfract))); - - /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ - out = ((x2 * (0xFFFFF - yfract))); - acc += (((q63_t) out * (xfract))); - - /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ - out = ((y1 * (0xFFFFF - xfract))); - acc += (((q63_t) out * (yfract))); - - /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ - out = ((y2 * (yfract))); - acc += (((q63_t) out * (xfract))); - - /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ - return (acc >> 40); - - } - - /** - * @} end of BilinearInterpolate group - */ - - -//SMMLAR -#define multAcc_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) - -//SMMLSR -#define multSub_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) - -//SMMULR -#define mult_32x32_keep32_R(a, x, y) \ - a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) - -//SMMLA -#define multAcc_32x32_keep32(a, x, y) \ - a += (q31_t) (((q63_t) x * y) >> 32) - -//SMMLS -#define multSub_32x32_keep32(a, x, y) \ - a -= (q31_t) (((q63_t) x * y) >> 32) - -//SMMUL -#define mult_32x32_keep32(a, x, y) \ - a = (q31_t) (((q63_t) x * y ) >> 32) - - -#if defined ( __CC_ARM ) //Keil - -//Enter low optimization region - place directly above function definition - #ifdef ARM_MATH_CM4 - #define LOW_OPTIMIZATION_ENTER \ - _Pragma ("push") \ - _Pragma ("O1") - #else - #define LOW_OPTIMIZATION_ENTER - #endif - -//Exit low optimization region - place directly after end of function definition - #ifdef ARM_MATH_CM4 - #define LOW_OPTIMIZATION_EXIT \ - _Pragma ("pop") - #else - #define LOW_OPTIMIZATION_EXIT - #endif - -//Enter low optimization region - place directly above function definition - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - -//Exit low optimization region - place directly after end of function definition - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined(__ICCARM__) //IAR - -//Enter low optimization region - place directly above function definition - #ifdef ARM_MATH_CM4 - #define LOW_OPTIMIZATION_ENTER \ - _Pragma ("optimize=low") - #else - #define LOW_OPTIMIZATION_ENTER - #endif - -//Exit low optimization region - place directly after end of function definition - #define LOW_OPTIMIZATION_EXIT - -//Enter low optimization region - place directly above function definition - #ifdef ARM_MATH_CM4 - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ - _Pragma ("optimize=low") - #else - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - #endif - -//Exit low optimization region - place directly after end of function definition - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined(__GNUC__) - - #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") )) - - #define LOW_OPTIMIZATION_EXIT - - #define IAR_ONLY_LOW_OPTIMIZATION_ENTER - - #define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#elif defined(__CSMC__) // Cosmic - -#define LOW_OPTIMIZATION_ENTER -#define LOW_OPTIMIZATION_EXIT -#define IAR_ONLY_LOW_OPTIMIZATION_ENTER -#define IAR_ONLY_LOW_OPTIMIZATION_EXIT - -#endif - - -#ifdef __cplusplus -} -#endif - - -#endif /* _ARM_MATH_H */ - -/** - * - * End of file. - */ diff --git a/components/toolchain/gcc/core_cm0.h b/components/toolchain/gcc/core_cm0.h deleted file mode 100644 index 5186cb4..0000000 --- a/components/toolchain/gcc/core_cm0.h +++ /dev/null @@ -1,711 +0,0 @@ -/**************************************************************************//** - * @file core_cm0.h - * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File - * @version V4.00 - * @date 22. August 2014 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2014 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 */ -#endif - -#ifndef __CORE_CM0_H_GENERIC -#define __CORE_CM0_H_GENERIC - -#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.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup Cortex_M0 - @{ - */ - -/* CMSIS CM0 definitions */ -#define __CM0_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */ -#define __CM0_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ -#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | \ - __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x00) /*!< 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 ( __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 /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ - #define __STATIC_INLINE static inline - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - This core does not support an FPU at all -*/ -#define __FPU_USED 0 - -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI__VFP_SUPPORT____ - #warning "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__ ) /* Cosmic */ - #if ( __CSMC__ & 0x400) // FPU present for parser - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #endif -#endif - -#include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM0_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM0_H_DEPENDANT -#define __CORE_CM0_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM0_REV - #define __CM0_REV 0x0000 - #warning "__CM0_REV not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 2 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #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 - - IO Type Qualifiers 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 */ - -/*@} end of group Cortex_M0 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick 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 - { -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ -#else - uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ -#endif - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - 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; - - -/** \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; - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ -#else - uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ -#endif - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - 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; - - -/** \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 FPCA:1; /*!< bit: 2 FP extension active flag */ - uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/*@} 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 -{ - __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[31]; - __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[31]; - __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[31]; - __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[31]; - uint32_t RESERVED4[64]; - __IO uint32_t IP[8]; /*!< 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 -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - uint32_t RESERVED0; - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - uint32_t RESERVED1; - __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< 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 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< 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 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< 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 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< 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 15 /*!< 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 -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \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_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 */ - - -/*@} */ - - - -/******************************************************************************* - * 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)(IRQn) ) & 0x03) * 8 ) -#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) -#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) - - -/** \brief Enable External Interrupt - - The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - - -/** \brief Disable External Interrupt - - The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - - -/** \brief Get Pending Interrupt - - The function reads the pending register in the NVIC and returns 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[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - - -/** \brief Set Pending Interrupt - - The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - - -/** \brief Clear Pending Interrupt - - The function 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[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ -} - - -/** \brief Set Interrupt Priority - - The function 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(IRQn < 0) { - SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | - (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } - else { - NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | - (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } -} - - -/** \brief Get Interrupt Priority - - The function 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(IRQn < 0) { - return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ - else { - return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & 0xFF) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ -} - - -/** \brief System Reset - - The function 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 = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | - SCB_AIRCR_SYSRESETREQ_Msk); - __DSB(); /* Ensure completion of memory access */ - while(1); /* wait until reset */ -} - -/*@} 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 == 0) - -/** \brief System Tick Configuration - - The function 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 __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ - - SysTick->LOAD = ticks - 1; /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0; /* 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 (0); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM0_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/components/toolchain/gcc/core_cm4.h b/components/toolchain/gcc/core_cm4.h deleted file mode 100644 index bb6be13..0000000 --- a/components/toolchain/gcc/core_cm4.h +++ /dev/null @@ -1,1802 +0,0 @@ -/**************************************************************************//** - * @file core_cm4.h - * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File - * @version V4.00 - * @date 22. August 2014 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2014 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 */ -#endif - -#ifndef __CORE_CM4_H_GENERIC -#define __CORE_CM4_H_GENERIC - -#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.
- Function definitions in header files are used to allow 'inlining'. - - \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
- Unions are used for effective representation of core registers. - - \li Advisory Rule 19.7, Function-like macro defined.
- Function-like macros are used to allow more efficient code. - */ - - -/******************************************************************************* - * CMSIS definitions - ******************************************************************************/ -/** \ingroup Cortex_M4 - @{ - */ - -/* CMSIS CM4 definitions */ -#define __CM4_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */ -#define __CM4_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ -#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ - __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ - -#define __CORTEX_M (0x04) /*!< 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 ( __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 /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */ - #define __STATIC_INLINE static inline - -#endif - -/** __FPU_USED indicates whether an FPU is used or not. - For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. -*/ -#if defined ( __CC_ARM ) - #if defined __TARGET_FPU_VFP - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __GNUC__ ) - #if defined (__VFP_FP__) && !defined(__SOFTFP__) - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __ICCARM__ ) - #if defined __ARMVFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TMS470__ ) - #if defined __TI_VFP_SUPPORT__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __TASKING__ ) - #if defined __FPU_VFP__ - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif - -#elif defined ( __CSMC__ ) /* Cosmic */ - #if ( __CSMC__ & 0x400) // FPU present for parser - #if (__FPU_PRESENT == 1) - #define __FPU_USED 1 - #else - #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" - #define __FPU_USED 0 - #endif - #else - #define __FPU_USED 0 - #endif -#endif - -#include /* standard types definitions */ -#include /* Core Instruction Access */ -#include /* Core Function Access */ -#include /* Compiler specific SIMD Intrinsics */ - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM4_H_GENERIC */ - -#ifndef __CMSIS_GENERIC - -#ifndef __CORE_CM4_H_DEPENDANT -#define __CORE_CM4_H_DEPENDANT - -#ifdef __cplusplus - extern "C" { -#endif - -/* check device defines and use defaults */ -#if defined __CHECK_DEVICE_DEFINES - #ifndef __CM4_REV - #define __CM4_REV 0x0000 - #warning "__CM4_REV not defined in device header file; using default!" - #endif - - #ifndef __FPU_PRESENT - #define __FPU_PRESENT 0 - #warning "__FPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __MPU_PRESENT - #define __MPU_PRESENT 0 - #warning "__MPU_PRESENT not defined in device header file; using default!" - #endif - - #ifndef __NVIC_PRIO_BITS - #define __NVIC_PRIO_BITS 4 - #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" - #endif - - #ifndef __Vendor_SysTickConfig - #define __Vendor_SysTickConfig 0 - #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 - - IO Type Qualifiers 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 */ - -/*@} end of group Cortex_M4 */ - - - -/******************************************************************************* - * Register Abstraction - Core Register contain: - - Core Register - - Core NVIC Register - - Core SCB Register - - Core SysTick Register - - Core Debug Register - - Core MPU Register - - Core FPU 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 - { -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ -#else - uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ -#endif - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - 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; - - -/** \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; - - -/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). - */ -typedef union -{ - struct - { - uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ -#if (__CORTEX_M != 0x04) - uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ -#else - uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ - uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ - uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ -#endif - uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ - uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ - uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ - 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; - - -/** \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 FPCA:1; /*!< bit: 2 FP extension active flag */ - uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ - } b; /*!< Structure used for bit access */ - uint32_t w; /*!< Type used for word access */ -} CONTROL_Type; - -/*@} 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 -{ - __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ - uint32_t RESERVED0[24]; - __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ - uint32_t RSERVED1[24]; - __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ - uint32_t RESERVED2[24]; - __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ - uint32_t RESERVED3[24]; - __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ - uint32_t RESERVED4[56]; - __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ - uint32_t RESERVED5[644]; - __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ -} NVIC_Type; - -/* Software Triggered Interrupt Register Definitions */ -#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ -#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ - -/*@} 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 -{ - __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ - __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ - __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ - __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ - __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ - __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ - __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ - __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ - __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ - __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ - __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ - __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ - __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ - __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ - __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ - __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ - __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ - __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ - __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ - uint32_t RESERVED0[5]; - __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ -} SCB_Type; - -/* SCB CPUID Register Definitions */ -#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ -#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ - -#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ -#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ - -#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ -#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ - -#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ -#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ - -#define SCB_CPUID_REVISION_Pos 0 /*!< 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 31 /*!< SCB ICSR: NMIPENDSET Position */ -#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ - -#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ -#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ - -#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ -#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ - -#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ -#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ - -#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ -#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ - -#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ -#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ - -#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ -#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ - -#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ -#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ - -#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ -#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ - -#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ -#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ - -/* SCB Vector Table Offset Register Definitions */ -#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ -#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ - -/* SCB Application Interrupt and Reset Control Register Definitions */ -#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ -#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ - -#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ -#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ - -#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ -#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ - -#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ -#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ - -#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ -#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ - -#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ -#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ - -#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ -#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ - -/* SCB System Control Register Definitions */ -#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ -#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ - -#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ -#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ - -#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< 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 9 /*!< SCB CCR: STKALIGN Position */ -#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ - -#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ -#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ - -#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ -#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ - -#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ -#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ - -#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ -#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ - -#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ -#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ - -/* SCB System Handler Control and State Register Definitions */ -#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ -#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ - -#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ -#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ - -#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ -#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ - -#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ -#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ - -#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ -#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ - -#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ -#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ - -#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ -#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ - -#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ -#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ - -#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ -#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ - -#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ -#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ - -#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ -#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ - -#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ -#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ - -#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ -#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ - -#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ -#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ - -/* SCB Configurable Fault Status Registers Definitions */ -#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ -#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ - -#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ -#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ - -#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ -#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ - -/* SCB Hard Fault Status Registers Definitions */ -#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ -#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ - -#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ -#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ - -#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ -#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ - -/* SCB Debug Fault Status Register Definitions */ -#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ -#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ - -#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ -#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ - -#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ -#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ - -#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ -#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ - -#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ -#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ - -/*@} end of group CMSIS_SCB */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) - \brief Type definitions for the System Control and ID Register not in the SCB - @{ - */ - -/** \brief Structure type to access the System Control and ID Register not in the SCB. - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ - __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ -} SCnSCB_Type; - -/* Interrupt Controller Type Register Definitions */ -#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ -#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ - -/* Auxiliary Control Register Definitions */ -#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ -#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ - -#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ -#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ - -#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ -#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ - -#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ -#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ - -#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ -#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ - -/*@} end of group CMSIS_SCnotSCB */ - - -/** \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 -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ - __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ - __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ - __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ -} SysTick_Type; - -/* SysTick Control / Status Register Definitions */ -#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ -#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ - -#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ -#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ - -#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ -#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ - -#define SysTick_CTRL_ENABLE_Pos 0 /*!< 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 0 /*!< 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 0 /*!< 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 31 /*!< SysTick CALIB: NOREF Position */ -#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ - -#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ -#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ - -#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ -#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_CALIB_TENMS_Pos) /*!< SysTick CALIB: TENMS Mask */ - -/*@} end of group CMSIS_SysTick */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) - \brief Type definitions for the Instrumentation Trace Macrocell (ITM) - @{ - */ - -/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). - */ -typedef struct -{ - __O union - { - __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ - __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ - __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ - } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ - uint32_t RESERVED0[864]; - __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ - uint32_t RESERVED1[15]; - __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ - uint32_t RESERVED2[15]; - __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ - uint32_t RESERVED3[29]; - __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ - __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ - __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ - uint32_t RESERVED4[43]; - __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ - __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ - uint32_t RESERVED5[6]; - __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ - __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ - __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ - __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ - __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ - __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ - __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ - __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ - __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ - __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ - __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ - __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ -} ITM_Type; - -/* ITM Trace Privilege Register Definitions */ -#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ -#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ - -/* ITM Trace Control Register Definitions */ -#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ -#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ - -#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ -#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ - -#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ -#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ - -#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ -#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ - -#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ -#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ - -#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ -#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ - -#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ -#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ - -#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ -#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ - -#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ -#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ - -/* ITM Integration Write Register Definitions */ -#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ -#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ - -/* ITM Integration Read Register Definitions */ -#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ -#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ - -/* ITM Integration Mode Control Register Definitions */ -#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ -#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ - -/* ITM Lock Status Register Definitions */ -#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ -#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ - -#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ -#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ - -#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ -#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ - -/*@}*/ /* end of group CMSIS_ITM */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) - \brief Type definitions for the Data Watchpoint and Trace (DWT) - @{ - */ - -/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). - */ -typedef struct -{ - __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ - __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ - __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ - __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ - __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ - __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ - __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ - __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ - __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ - __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ - __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ - uint32_t RESERVED0[1]; - __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ - __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ - __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ - uint32_t RESERVED1[1]; - __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ - __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ - __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ - uint32_t RESERVED2[1]; - __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ - __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ - __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ -} DWT_Type; - -/* DWT Control Register Definitions */ -#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ -#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ - -#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ -#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ - -#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ -#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ - -#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ -#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ - -#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ -#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ - -#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ -#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ - -#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ -#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ - -#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ -#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ - -#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ -#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ - -#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ -#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ - -#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ -#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ - -#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ -#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ - -#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ -#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ - -#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ -#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ - -#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ -#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ - -#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ -#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ - -#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ -#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ - -#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ -#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ - -/* DWT CPI Count Register Definitions */ -#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ -#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ - -/* DWT Exception Overhead Count Register Definitions */ -#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ -#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ - -/* DWT Sleep Count Register Definitions */ -#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ -#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ - -/* DWT LSU Count Register Definitions */ -#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ -#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ - -/* DWT Folded-instruction Count Register Definitions */ -#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ -#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ - -/* DWT Comparator Mask Register Definitions */ -#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ -#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ - -/* DWT Comparator Function Register Definitions */ -#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ -#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ - -#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ -#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ - -#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ -#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ - -#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ -#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ - -#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ -#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ - -#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ -#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ - -#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ -#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ - -#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ -#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ - -#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ -#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ - -/*@}*/ /* end of group CMSIS_DWT */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_TPI Trace Port Interface (TPI) - \brief Type definitions for the Trace Port Interface (TPI) - @{ - */ - -/** \brief Structure type to access the Trace Port Interface Register (TPI). - */ -typedef struct -{ - __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ - __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ - uint32_t RESERVED0[2]; - __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ - uint32_t RESERVED1[55]; - __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ - uint32_t RESERVED2[131]; - __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ - __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ - __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ - uint32_t RESERVED3[759]; - __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ - __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ - __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ - uint32_t RESERVED4[1]; - __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ - __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ - __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ - uint32_t RESERVED5[39]; - __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ - __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ - uint32_t RESERVED7[8]; - __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ - __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ -} TPI_Type; - -/* TPI Asynchronous Clock Prescaler Register Definitions */ -#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ -#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ - -/* TPI Selected Pin Protocol Register Definitions */ -#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ -#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ - -/* TPI Formatter and Flush Status Register Definitions */ -#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ -#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ - -#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ -#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ - -#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ -#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ - -#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ -#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ - -/* TPI Formatter and Flush Control Register Definitions */ -#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ -#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ - -#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ -#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ - -/* TPI TRIGGER Register Definitions */ -#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ -#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ - -/* TPI Integration ETM Data Register Definitions (FIFO0) */ -#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ -#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ - -#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ -#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ - -#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ -#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ - -#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ -#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ - -#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ -#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ - -#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ -#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ - -#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ -#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ - -/* TPI ITATBCTR2 Register Definitions */ -#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ -#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ - -/* TPI Integration ITM Data Register Definitions (FIFO1) */ -#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ -#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ - -#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ -#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ - -#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ -#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ - -#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ -#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ - -#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ -#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ - -#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ -#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ - -#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ -#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ - -/* TPI ITATBCTR0 Register Definitions */ -#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ -#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ - -/* TPI Integration Mode Control Register Definitions */ -#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ -#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ - -/* TPI DEVID Register Definitions */ -#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ -#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ - -#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ -#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ - -#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ -#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ - -#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ -#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ - -#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ -#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ - -#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ -#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ - -/* TPI DEVTYPE Register Definitions */ -#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ -#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ - -#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ -#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ - -/*@}*/ /* end of group CMSIS_TPI */ - - -#if (__MPU_PRESENT == 1) -/** \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 -{ - __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ - __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ - __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ - __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ - __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ - __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ - __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ - __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ - __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ - __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ - __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ -} MPU_Type; - -/* MPU Type Register */ -#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ -#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ - -#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ -#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ - -#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ -#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ - -/* MPU Control Register */ -#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ -#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ - -#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ -#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ - -#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ -#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ - -/* MPU Region Number Register */ -#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ -#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ - -/* MPU Region Base Address Register */ -#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ -#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ - -#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ -#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ - -#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ -#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ - -/* MPU Region Attribute and Size Register */ -#define MPU_RASR_ATTRS_Pos 16 /*!< 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 28 /*!< 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 24 /*!< 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 19 /*!< 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 18 /*!< 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 17 /*!< 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 16 /*!< 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 8 /*!< 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 1 /*!< 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 0 /*!< MPU RASR: Region enable bit Position */ -#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ - -/*@} end of group CMSIS_MPU */ -#endif - - -#if (__FPU_PRESENT == 1) -/** \ingroup CMSIS_core_register - \defgroup CMSIS_FPU Floating Point Unit (FPU) - \brief Type definitions for the Floating Point Unit (FPU) - @{ - */ - -/** \brief Structure type to access the Floating Point Unit (FPU). - */ -typedef struct -{ - uint32_t RESERVED0[1]; - __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ - __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ - __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ - __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ - __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ -} FPU_Type; - -/* Floating-Point Context Control Register */ -#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ -#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ - -#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ -#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ - -#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ -#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ - -#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ -#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ - -#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ -#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ - -#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ -#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ - -#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ -#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ - -#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ -#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ - -#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ -#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ - -/* Floating-Point Context Address Register */ -#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ -#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ - -/* Floating-Point Default Status Control Register */ -#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ -#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ - -#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ -#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ - -#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ -#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ - -#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ -#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ - -/* Media and FP Feature Register 0 */ -#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ -#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ - -#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ -#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ - -#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ -#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ - -#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ -#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ - -#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ -#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ - -#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ -#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ - -#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ -#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ - -#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ -#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ - -/* Media and FP Feature Register 1 */ -#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ -#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ - -#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ -#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ - -#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ -#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ - -#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ -#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ - -/*@} end of group CMSIS_FPU */ -#endif - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) - \brief Type definitions for the Core Debug Registers - @{ - */ - -/** \brief Structure type to access the Core Debug Register (CoreDebug). - */ -typedef struct -{ - __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ - __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ - __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ - __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ -} CoreDebug_Type; - -/* Debug Halting Control and Status Register */ -#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ -#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ - -#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ -#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ - -#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ -#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ - -#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ -#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ - -#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ -#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ - -#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ -#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ - -#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ -#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ - -#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ -#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ - -#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ -#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ - -#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ -#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ - -#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ -#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ - -#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ -#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ - -/* Debug Core Register Selector Register */ -#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ -#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ - -#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ -#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ - -/* Debug Exception and Monitor Control Register */ -#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ -#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ - -#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ -#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ - -#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ -#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ - -#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ -#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ - -#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ -#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ - -#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ -#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ - -#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ -#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ - -#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ -#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ - -#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ -#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ - -#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ -#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ - -#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ -#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ - -#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ -#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ - -#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ -#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ - -/*@} end of group CMSIS_CoreDebug */ - - -/** \ingroup CMSIS_core_register - \defgroup CMSIS_core_base Core Definitions - \brief Definitions for base addresses, unions, and structures. - @{ - */ - -/* Memory mapping of Cortex-M4 Hardware */ -#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ -#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ -#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ -#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ -#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug 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 SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ -#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 */ -#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ -#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ -#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ -#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ - -#if (__MPU_PRESENT == 1) - #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ - #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ -#endif - -#if (__FPU_PRESENT == 1) - #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ - #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ -#endif - -/*@} */ - - - -/******************************************************************************* - * Hardware Abstraction Layer - Core Function Interface contains: - - Core NVIC Functions - - Core SysTick Functions - - Core Debug 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. - @{ - */ - -/** \brief Set Priority Grouping - - The function sets the priority grouping field using the required unlock sequence. - The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. - Only values from 0..7 are used. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Priority grouping field. - */ -__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) -{ - uint32_t reg_value; - uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ - - reg_value = SCB->AIRCR; /* read old register configuration */ - reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ - reg_value = (reg_value | - ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ - SCB->AIRCR = reg_value; -} - - -/** \brief Get Priority Grouping - - The function reads the priority grouping field from the NVIC Interrupt Controller. - - \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). - */ -__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) -{ - return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ -} - - -/** \brief Enable External Interrupt - - The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ - NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ -} - - -/** \brief Disable External Interrupt - - The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ -} - - -/** \brief Get Pending Interrupt - - The function reads the pending register in the NVIC and returns 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[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ -} - - -/** \brief Set Pending Interrupt - - The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ -} - - -/** \brief Clear Pending Interrupt - - The function 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ -} - - -/** \brief Get Active Interrupt - - The function reads the active register in NVIC and returns the active bit. - - \param [in] IRQn Interrupt number. - - \return 0 Interrupt status is not active. - \return 1 Interrupt status is active. - */ -__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ -} - - -/** \brief Set Interrupt Priority - - The function 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(IRQn < 0) { - SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ - else { - NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ -} - - -/** \brief Get Interrupt Priority - - The function 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(IRQn < 0) { - return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ - else { - return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ -} - - -/** \brief Encode Priority - - The function encodes the priority for an interrupt with the given priority group, - preemptive priority value, and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. - - \param [in] PriorityGroup Used priority group. - \param [in] PreemptPriority Preemptive priority value (starting from 0). - \param [in] SubPriority Subpriority value (starting from 0). - \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). - */ -__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; - SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - - return ( - ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | - ((SubPriority & ((1 << (SubPriorityBits )) - 1))) - ); -} - - -/** \brief Decode Priority - - The function decodes an interrupt priority value with a given priority group to - preemptive priority value and subpriority value. - In case of a conflict between priority grouping and available - priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. - - \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). - \param [in] PriorityGroup Used priority group. - \param [out] pPreemptPriority Preemptive priority value (starting from 0). - \param [out] pSubPriority Subpriority value (starting from 0). - */ -__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) -{ - uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ - uint32_t PreemptPriorityBits; - uint32_t SubPriorityBits; - - PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; - SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; - - *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); - *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); -} - - -/** \brief System Reset - - The function 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 = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | - (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | - SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ - __DSB(); /* Ensure completion of memory access */ - while(1); /* wait until reset */ -} - -/*@} 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 == 0) - -/** \brief System Tick Configuration - - The function 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 __Vendor_SysTickConfig is set to 1, then the - function SysTick_Config is not included. In this case, the file device.h - must contain a vendor-specific implementation of this function. - - */ -__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) -{ - if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ - - SysTick->LOAD = ticks - 1; /* set reload register */ - NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ - SysTick->VAL = 0; /* 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 (0); /* Function successful */ -} - -#endif - -/*@} end of CMSIS_Core_SysTickFunctions */ - - - -/* ##################################### Debug In/Output function ########################################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_core_DebugFunctions ITM Functions - \brief Functions that access the ITM debug interface. - @{ - */ - -extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ -#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ - - -/** \brief ITM Send Character - - The function transmits a character via the ITM channel 0, and - \li Just returns when no debugger is connected that has booked the output. - \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. - - \param [in] ch Character to transmit. - - \returns Character to transmit. - */ -__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) -{ - if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ - (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ - { - while (ITM->PORT[0].u32 == 0); - ITM->PORT[0].u8 = (uint8_t) ch; - } - return (ch); -} - - -/** \brief ITM Receive Character - - The function inputs a character via the external variable \ref ITM_RxBuffer. - - \return Received character. - \return -1 No character pending. - */ -__STATIC_INLINE int32_t ITM_ReceiveChar (void) { - int32_t ch = -1; /* no character available */ - - if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { - ch = ITM_RxBuffer; - ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ - } - - return (ch); -} - - -/** \brief ITM Check Character - - The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. - - \return 0 No character available. - \return 1 Character available. - */ -__STATIC_INLINE int32_t ITM_CheckChar (void) { - - if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { - return (0); /* no character available */ - } else { - return (1); /* character available */ - } -} - -/*@} end of CMSIS_core_DebugFunctions */ - - - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CM4_H_DEPENDANT */ - -#endif /* __CMSIS_GENERIC */ diff --git a/components/toolchain/gcc/core_cmFunc.h b/components/toolchain/gcc/core_cmFunc.h deleted file mode 100644 index 01089f1..0000000 --- a/components/toolchain/gcc/core_cmFunc.h +++ /dev/null @@ -1,637 +0,0 @@ -/**************************************************************************//** - * @file core_cmFunc.h - * @brief CMSIS Cortex-M Core Function Access Header File - * @version V4.00 - * @date 28. August 2014 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2014 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. - ---------------------------------------------------------------------------*/ - - -#ifndef __CORE_CMFUNC_H -#define __CORE_CMFUNC_H - - -/* ########################### Core Function Access ########################### */ -/** \ingroup CMSIS_Core_FunctionInterface - \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions - @{ - */ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - -/* intrinsic void __enable_irq(); */ -/* intrinsic void __disable_irq(); */ - -/** \brief Get Control Register - - This function returns 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 - - This function 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 - - This function returns 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 - - This function returns 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 - - This function returns 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 - - This function returns 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 - - This function 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 - - This function returns 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 - - This function 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 - - This function returns 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 - - This function 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 (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - -/** \brief Enable FIQ - - This function 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 - - This function 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 - - This function returns 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 - - This function 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 & 0xff); -} - - -/** \brief Get Fault Mask - - This function returns 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 - - This function 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)1); -} - -#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ - - -#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) - -/** \brief Get FPSCR - - This function returns 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 (__FPU_PRESENT == 1) && (__FPU_USED == 1) - register uint32_t __regfpscr __ASM("fpscr"); - return(__regfpscr); -#else - return(0); -#endif -} - - -/** \brief Set FPSCR - - This function 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 (__FPU_PRESENT == 1) && (__FPU_USED == 1) - register uint32_t __regfpscr __ASM("fpscr"); - __regfpscr = (fpscr); -#endif -} - -#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */ - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/** \brief Enable IRQ Interrupts - - This function enables IRQ interrupts by clearing the I-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) -{ - __ASM volatile ("cpsie i" : : : "memory"); -} - - -/** \brief Disable IRQ Interrupts - - This function disables IRQ interrupts by setting the I-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) -{ - __ASM volatile ("cpsid i" : : : "memory"); -} - - -/** \brief Get Control Register - - This function returns the content of the Control Register. - - \return Control Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, control" : "=r" (result) ); - return(result); -} - - -/** \brief Set Control Register - - This function writes the given value to the Control Register. - - \param [in] control Control Register value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) -{ - __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); -} - - -/** \brief Get IPSR Register - - This function returns the content of the IPSR Register. - - \return IPSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get APSR Register - - This function returns the content of the APSR Register. - - \return APSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, apsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get xPSR Register - - This function returns the content of the xPSR Register. - - \return xPSR Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); - return(result); -} - - -/** \brief Get Process Stack Pointer - - This function returns the current value of the Process Stack Pointer (PSP). - - \return PSP Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) -{ - register uint32_t result; - - __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); - return(result); -} - - -/** \brief Set Process Stack Pointer - - This function assigns the given value to the Process Stack Pointer (PSP). - - \param [in] topOfProcStack Process Stack Pointer value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) -{ - __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); -} - - -/** \brief Get Main Stack Pointer - - This function returns the current value of the Main Stack Pointer (MSP). - - \return MSP Register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) -{ - register uint32_t result; - - __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); - return(result); -} - - -/** \brief Set Main Stack Pointer - - This function assigns the given value to the Main Stack Pointer (MSP). - - \param [in] topOfMainStack Main Stack Pointer value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) -{ - __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); -} - - -/** \brief Get Priority Mask - - This function returns the current state of the priority mask bit from the Priority Mask Register. - - \return Priority Mask value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, primask" : "=r" (result) ); - return(result); -} - - -/** \brief Set Priority Mask - - This function assigns the given value to the Priority Mask Register. - - \param [in] priMask Priority Mask - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) -{ - __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); -} - - -#if (__CORTEX_M >= 0x03) - -/** \brief Enable FIQ - - This function enables FIQ interrupts by clearing the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) -{ - __ASM volatile ("cpsie f" : : : "memory"); -} - - -/** \brief Disable FIQ - - This function disables FIQ interrupts by setting the F-bit in the CPSR. - Can only be executed in Privileged modes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) -{ - __ASM volatile ("cpsid f" : : : "memory"); -} - - -/** \brief Get Base Priority - - This function returns the current value of the Base Priority register. - - \return Base Priority register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); - return(result); -} - - -/** \brief Set Base Priority - - This function assigns the given value to the Base Priority register. - - \param [in] basePri Base Priority value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) -{ - __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); -} - - -/** \brief Get Fault Mask - - This function returns the current value of the Fault Mask register. - - \return Fault Mask register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) -{ - uint32_t result; - - __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); - return(result); -} - - -/** \brief Set Fault Mask - - This function assigns the given value to the Fault Mask register. - - \param [in] faultMask Fault Mask value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) -{ - __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); -} - -#endif /* (__CORTEX_M >= 0x03) */ - - -#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) - -/** \brief Get FPSCR - - This function returns the current value of the Floating Point Status/Control register. - - \return Floating Point Status/Control register value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - uint32_t result; - - /* Empty asm statement works as a scheduling barrier */ - __ASM volatile (""); - __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); - __ASM volatile (""); - return(result); -#else - return(0); -#endif -} - - -/** \brief Set FPSCR - - This function assigns the given value to the Floating Point Status/Control register. - - \param [in] fpscr Floating Point Status/Control value to set - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) -{ -#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - /* Empty asm statement works as a scheduling barrier */ - __ASM volatile (""); - __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); - __ASM volatile (""); -#endif -} - -#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */ - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ -#include - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ -#include - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ -/* - * 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. - */ - - -#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ -/* Cosmic specific functions */ -#include - -#endif - -/*@} end of CMSIS_Core_RegAccFunctions */ - -#endif /* __CORE_CMFUNC_H */ diff --git a/components/toolchain/gcc/core_cmInstr.h b/components/toolchain/gcc/core_cmInstr.h deleted file mode 100644 index d14110b..0000000 --- a/components/toolchain/gcc/core_cmInstr.h +++ /dev/null @@ -1,880 +0,0 @@ -/**************************************************************************//** - * @file core_cmInstr.h - * @brief CMSIS Cortex-M Core Instruction Access Header File - * @version V4.00 - * @date 28. August 2014 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2014 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. - ---------------------------------------------------------------------------*/ - - -#ifndef __CORE_CMINSTR_H -#define __CORE_CMINSTR_H - - -/* ########################## Core Instruction Access ######################### */ -/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface - Access to dedicated instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ - -#if (__ARMCC_VERSION < 400677) - #error "Please use ARM Compiler Toolchain V4.0.677 or later!" -#endif - - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -#define __NOP __nop - - -/** \brief Wait For Interrupt - - 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 - - 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 - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -#define __SEV __sev - - -/** \brief Instruction Synchronization Barrier - - 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() __isb(0xF) - - -/** \brief Data Synchronization Barrier - - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -#define __DSB() __dsb(0xF) - - -/** \brief Data Memory Barrier - - This function ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ -#define __DMB() __dmb(0xF) - - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -#define __REV __rev - - -/** \brief Reverse byte order (16 bit) - - This function reverses the byte order in two unsigned short values. - - \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 in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -#ifndef __NO_EMBEDDED_ASM -__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) -{ - revsh r0, r0 - bx lr -} -#endif - - -/** \brief Rotate Right in unsigned value (32 bit) - - This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. - - \param [in] value Value to rotate - \param [in] value Number of Bits to rotate - \return Rotated value - */ -#define __ROR __ror - - -/** \brief Breakpoint - - This function 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) - - -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - -/** \brief Reverse bit order of value - - This function reverses the bit order of the given value. - - \param [in] value Value to reverse - \return Reversed value - */ -#define __RBIT __rbit - - -/** \brief LDR Exclusive (8 bit) - - This function executes a exclusive LDR instruction for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) - - -/** \brief LDR Exclusive (16 bit) - - This function executes a exclusive LDR instruction for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) - - -/** \brief LDR Exclusive (32 bit) - - This function executes a exclusive LDR instruction for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) - - -/** \brief STR Exclusive (8 bit) - - This function 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 - */ -#define __STREXB(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (16 bit) - - This function 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 - */ -#define __STREXH(value, ptr) __strex(value, ptr) - - -/** \brief STR Exclusive (32 bit) - - This function 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 - */ -#define __STREXW(value, ptr) __strex(value, ptr) - - -/** \brief Remove the exclusive lock - - This function removes the exclusive lock which is created by LDREX. - - */ -#define __CLREX __clrex - - -/** \brief Signed Saturate - - This function 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 - - This function 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 Count leading zeros - - This function 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 - - -/** \brief Rotate Right with Extend (32 bit) - - This function 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) - - This function 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) - - This function 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) - - This function 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) - - This function 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) - - This function 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) - - This function 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) - -#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ - -/* Define macros for porting to both thumb1 and thumb2. - * For thumb1, use low register (r0-r7), specified by constrant "l" - * Otherwise, use general registers, specified by constrant "r" */ -#if defined (__thumb__) && !defined (__thumb2__) -#define __CMSIS_GCC_OUT_REG(r) "=l" (r) -#define __CMSIS_GCC_USE_REG(r) "l" (r) -#else -#define __CMSIS_GCC_OUT_REG(r) "=r" (r) -#define __CMSIS_GCC_USE_REG(r) "r" (r) -#endif - -/** \brief No Operation - - No Operation does nothing. This instruction can be used for code alignment purposes. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) -{ - __ASM volatile ("nop"); -} - - -/** \brief Wait For Interrupt - - Wait For Interrupt is a hint instruction that suspends execution - until one of a number of events occurs. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) -{ - __ASM volatile ("wfi"); -} - - -/** \brief Wait For Event - - 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. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) -{ - __ASM volatile ("wfe"); -} - - -/** \brief Send Event - - Send Event is a hint instruction. It causes an event to be signaled to the CPU. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) -{ - __ASM volatile ("sev"); -} - - -/** \brief Instruction Synchronization Barrier - - 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. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) -{ - __ASM volatile ("isb"); -} - - -/** \brief Data Synchronization Barrier - - This function acts as a special kind of Data Memory Barrier. - It completes when all explicit memory accesses before this instruction complete. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) -{ - __ASM volatile ("dsb"); -} - - -/** \brief Data Memory Barrier - - This function ensures the apparent order of the explicit memory operations before - and after the instruction, without ensuring their completion. - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) -{ - __ASM volatile ("dmb"); -} - - -/** \brief Reverse byte order (32 bit) - - This function reverses the byte order in integer value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE 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) - - This function reverses the byte order in two unsigned short values. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE 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 in signed short value - - This function reverses the byte order in a signed short value with sign extension to integer. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) -{ -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - return (short)__builtin_bswap16(value); -#else - uint32_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) - - This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. - - \param [in] value Value to rotate - \param [in] value Number of Bits to rotate - \return Rotated value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) -{ - return (op1 >> op2) | (op1 << (32 - op2)); -} - - -/** \brief Breakpoint - - This function 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) - - -#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) - -/** \brief Reverse bit order of value - - This function reverses the bit order of the given value. - - \param [in] value Value to reverse - \return Reversed value - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); - return(result); -} - - -/** \brief LDR Exclusive (8 bit) - - This function executes a exclusive LDR instruction for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE 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) - - This function executes a exclusive LDR instruction for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE 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) - - This function executes a exclusive LDR instruction for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE 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) - - This function 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 - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE 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) - - This function 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 - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE 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) - - This function 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 - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE 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 - - This function removes the exclusive lock which is created by LDREX. - - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) -{ - __ASM volatile ("clrex" ::: "memory"); -} - - -/** \brief Signed Saturate - - This function 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(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Unsigned Saturate - - This function 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(ARG1,ARG2) \ -({ \ - uint32_t __RES, __ARG1 = (ARG1); \ - __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ - __RES; \ - }) - - -/** \brief Count leading zeros - - This function 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 - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) -{ - uint32_t result; - - __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); - return ((uint8_t) result); /* Add explicit type cast here */ -} - - -/** \brief Rotate Right with Extend (32 bit) - - This function 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 - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE 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) - - This function executes a Unprivileged LDRT instruction for 8 bit value. - - \param [in] ptr Pointer to data - \return value of type uint8_t at (*ptr) - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrbt %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 ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint8_t) result); /* Add explicit type cast here */ -} - - -/** \brief LDRT Unprivileged (16 bit) - - This function executes a Unprivileged LDRT instruction for 16 bit values. - - \param [in] ptr Pointer to data - \return value of type uint16_t at (*ptr) - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) -{ - uint32_t result; - -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) - __ASM volatile ("ldrht %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 ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); -#endif - return ((uint16_t) result); /* Add explicit type cast here */ -} - - -/** \brief LDRT Unprivileged (32 bit) - - This function executes a Unprivileged LDRT instruction for 32 bit values. - - \param [in] ptr Pointer to data - \return value of type uint32_t at (*ptr) - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) -{ - uint32_t result; - - __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) ); - return(result); -} - - -/** \brief STRT Unprivileged (8 bit) - - This function executes a Unprivileged STRT instruction for 8 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) -{ - __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); -} - - -/** \brief STRT Unprivileged (16 bit) - - This function executes a Unprivileged STRT instruction for 16 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) -{ - __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); -} - - -/** \brief STRT Unprivileged (32 bit) - - This function executes a Unprivileged STRT instruction for 32 bit values. - - \param [in] value Value to store - \param [in] ptr Pointer to location - */ -__attribute__( ( always_inline ) ) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) -{ - __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) ); -} - -#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */ - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ -#include - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ -#include - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ -/* - * 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. - */ - - -#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ -/* Cosmic specific functions */ -#include - -#endif - -/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ - -#endif /* __CORE_CMINSTR_H */ diff --git a/components/toolchain/gcc/core_cmSimd.h b/components/toolchain/gcc/core_cmSimd.h deleted file mode 100644 index ee58eee..0000000 --- a/components/toolchain/gcc/core_cmSimd.h +++ /dev/null @@ -1,697 +0,0 @@ -/**************************************************************************//** - * @file core_cmSimd.h - * @brief CMSIS Cortex-M SIMD Header File - * @version V4.00 - * @date 22. August 2014 - * - * @note - * - ******************************************************************************/ -/* Copyright (c) 2009 - 2014 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 */ -#endif - -#ifndef __CORE_CMSIMD_H -#define __CORE_CMSIMD_H - -#ifdef __cplusplus - extern "C" { -#endif - - -/******************************************************************************* - * Hardware Abstraction Layer - ******************************************************************************/ - - -/* ################### Compiler specific Intrinsics ########################### */ -/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics - Access to dedicated SIMD instructions - @{ -*/ - -#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ -/* ARM armcc specific functions */ -#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) << 32) ) >> 32)) - - -#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ -/* GNU gcc specific functions */ -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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) \ -({ \ - uint32_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; \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) -{ - uint32_t result; - - __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE 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); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) -{ - uint32_t result; - - __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); - return(result); -} - -#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; \ - }) - -__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_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); -} - - -#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ -/* IAR iccarm specific functions */ -#include - - -#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ -/* TI CCS specific functions */ -#include - - -#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ -/* TASKING carm specific functions */ -/* not yet supported */ - - -#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/ -/* Cosmic specific functions */ -#include - -#endif - -/*@} end of group CMSIS_SIMD_intrinsics */ - - -#ifdef __cplusplus -} -#endif - -#endif /* __CORE_CMSIMD_H */ diff --git a/components/toolchain/gcc/file_list.mk b/components/toolchain/gcc/file_list.mk new file mode 100644 index 0000000..bd5cd68 --- /dev/null +++ b/components/toolchain/gcc/file_list.mk @@ -0,0 +1,2 @@ +$(info $(FILE_LIST)) +all: ; diff --git a/components/toolchain/gcc/gcc_nrf51_common.ld b/components/toolchain/gcc/gcc_nrf51_common.ld index 3bf8634..a4b8b28 100644 --- a/components/toolchain/gcc/gcc_nrf51_common.ld +++ b/components/toolchain/gcc/gcc_nrf51_common.ld @@ -21,7 +21,7 @@ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: * Reset_Handler : Entry of reset handler - * + * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end @@ -74,9 +74,9 @@ SECTIONS *(.eh_frame*) . = ALIGN(4); } > FLASH - - .ARM.extab : + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) . = ALIGN(4); @@ -91,7 +91,7 @@ SECTIONS __exidx_end = .; __etext = .; - + .data : AT (__etext) { __data_start__ = .; @@ -135,7 +135,7 @@ SECTIONS . = ALIGN(4); __bss_end__ = .; } > RAM - + .heap (COPY): { __end__ = .; @@ -157,7 +157,7 @@ SECTIONS __StackTop = ORIGIN(RAM) + LENGTH(RAM); __StackLimit = __StackTop - SIZEOF(.stack_dummy); PROVIDE(__stack = __StackTop); - + /* Check if data + heap + stack exceeds RAM limit */ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") } diff --git a/components/toolchain/gcc/gcc_startup_nrf51.s b/components/toolchain/gcc/gcc_startup_nrf51.s index 90717c1..381a28a 100644 --- a/components/toolchain/gcc/gcc_startup_nrf51.s +++ b/components/toolchain/gcc/gcc_startup_nrf51.s @@ -1,77 +1,77 @@ -/* -Copyright (c) 2015, Nordic Semiconductor ASA -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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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. -*/ - -/* -NOTE: Template files (including this one) are application specific and therefore -expected to be copied into the application project folder prior to its use! -*/ +/* Copyright (c) 2013 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. + ---------------------------------------------------------------------------*/ .syntax unified .arch armv6-m +#ifdef __STARTUP_CONFIG +#include "startup_config.h" +#endif + .section .stack .align 3 -#ifdef __STACK_SIZE +#if defined(__STARTUP_CONFIG) + .equ Stack_Size, __STARTUP_CONFIG_STACK_SIZE +#elif defined(__STACK_SIZE) .equ Stack_Size, __STACK_SIZE #else .equ Stack_Size, 2048 #endif - .globl __StackTop - .globl __StackLimit + .globl __StackTop + .globl __StackLimit __StackLimit: - .space Stack_Size + .space Stack_Size .size __StackLimit, . - __StackLimit __StackTop: .size __StackTop, . - __StackTop .section .heap .align 3 -#ifdef __HEAP_SIZE - .equ Heap_Size, __HEAP_SIZE +#if defined(__STARTUP_CONFIG) + .equ Heap_Size, __STARTUP_CONFIG_HEAP_SIZE +#elif defined(__HEAP_SIZE) + .equ Heap_Size, __HEAP_SIZE #else .equ Heap_Size, 2048 #endif - .globl __HeapBase - .globl __HeapLimit + .globl __HeapBase + .globl __HeapLimit __HeapBase: - .if Heap_Size - .space Heap_Size + .if Heap_Size + .space Heap_Size .endif .size __HeapBase, . - __HeapBase __HeapLimit: .size __HeapLimit, . - __HeapLimit - - .section .Vectors + + .section .isr_vector .align 2 - .globl __Vectors -__Vectors: + .globl __isr_vector +__isr_vector: .long __StackTop /* Top of Stack */ .long Reset_Handler .long NMI_Handler @@ -123,7 +123,7 @@ __Vectors: .long 0 /*Reserved */ .long 0 /*Reserved */ - .size __Vectors, . - __Vectors + .size __isr_vector, . - __isr_vector /* Reset Handler */ @@ -135,12 +135,10 @@ __Vectors: .thumb .thumb_func .align 1 - .globl Reset_Handler - .type Reset_Handler, %function + .globl Reset_Handler + .type Reset_Handler, %function Reset_Handler: - .fnstart -/* Make sure ALL RAM banks are powered on */ MOVS R1, #NRF_POWER_RAMONx_RAMxON_ONMODE_Msk LDR R0, =NRF_POWER_RAMON_ADDRESS @@ -153,35 +151,69 @@ Reset_Handler: ORRS R2, R1 STR R2, [R0] -/* Loop to copy data from read only memory to RAM. The ranges - * of copy from/to are specified by following symbols evaluated in - * linker script. - * __etext: End of code section, i.e., begin of data sections to copy from. - * __data_start__/__data_end__: RAM address range that data should be - * copied to. Both must be aligned to 4 bytes boundary. */ - - ldr r1, =__etext - ldr r2, =__data_start__ - ldr r3, =__data_end__ - - subs r3, r2 - ble .LC0 - -.LC1: - subs r3, 4 - ldr r0, [r1,r3] - str r0, [r2,r3] - bgt .LC1 -.LC0: - - LDR R0, =SystemInit - BLX R0 - LDR R0, =_start - BX R0 +/* Loop to copy data from read only memory to RAM. + * The ranges of copy from/to are specified by following symbols: + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to. + * __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__ + * the user can add their own initialized data section before BSS section with the INTERT AFTER command. + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__bss_start__ + + subs r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: + +/* This part of work usually is done in C library startup code. Otherwise, + * define __STARTUP_CLEAR_BSS to enable it in this startup. This section + * clears the RAM where BSS data is located. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * All addresses must be aligned to 4 bytes boundary. + */ +#ifdef __STARTUP_CLEAR_BSS + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + + subs r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, #4 + str r0, [r1, r2] + bgt .L_loop3 + +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS */ + +/* Execute SystemInit function. */ + bl SystemInit + +/* Call _start function provided by libraries. + * If those libraries are not accessible, define __START as your entry point. + */ +#ifndef __START +#define __START _start +#endif + bl __START .pool - .cantunwind - .fnend .size Reset_Handler,.-Reset_Handler .section ".text" @@ -192,35 +224,35 @@ Reset_Handler: .weak NMI_Handler .type NMI_Handler, %function NMI_Handler: - B . + b . .size NMI_Handler, . - NMI_Handler .weak HardFault_Handler .type HardFault_Handler, %function HardFault_Handler: - B . + b . .size HardFault_Handler, . - HardFault_Handler .weak SVC_Handler .type SVC_Handler, %function SVC_Handler: - B . + b . .size SVC_Handler, . - SVC_Handler .weak PendSV_Handler .type PendSV_Handler, %function PendSV_Handler: - B . + b . .size PendSV_Handler, . - PendSV_Handler .weak SysTick_Handler .type SysTick_Handler, %function SysTick_Handler: - B . + b . .size SysTick_Handler, . - SysTick_Handler @@ -229,7 +261,7 @@ SysTick_Handler: .globl Default_Handler .type Default_Handler, %function Default_Handler: - B . + b . .size Default_Handler, . - Default_Handler .macro IRQ handler diff --git a/components/toolchain/gcc/gcc_startup_nrf52.s b/components/toolchain/gcc/gcc_startup_nrf52.s index 579739d..7b6dc86 100644 --- a/components/toolchain/gcc/gcc_startup_nrf52.s +++ b/components/toolchain/gcc/gcc_startup_nrf52.s @@ -1,77 +1,77 @@ -/* -Copyright (c) 2015, Nordic Semiconductor ASA -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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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. -*/ - -/* -NOTE: Template files (including this one) are application specific and therefore -expected to be copied into the application project folder prior to its use! -*/ +/* Copyright (c) 2013 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. + ---------------------------------------------------------------------------*/ .syntax unified .arch armv7e-m +#ifdef __STARTUP_CONFIG +#include "startup_config.h" +#endif + .section .stack .align 3 -#ifdef __STACK_SIZE +#if defined(__STARTUP_CONFIG) + .equ Stack_Size, __STARTUP_CONFIG_STACK_SIZE +#elif defined(__STACK_SIZE) .equ Stack_Size, __STACK_SIZE #else .equ Stack_Size, 8192 #endif - .globl __StackTop - .globl __StackLimit + .globl __StackTop + .globl __StackLimit __StackLimit: - .space Stack_Size + .space Stack_Size .size __StackLimit, . - __StackLimit __StackTop: .size __StackTop, . - __StackTop .section .heap .align 3 -#ifdef __HEAP_SIZE - .equ Heap_Size, __HEAP_SIZE +#if defined(__STARTUP_CONFIG) + .equ Heap_Size, __STARTUP_CONFIG_HEAP_SIZE +#elif defined(__HEAP_SIZE) + .equ Heap_Size, __HEAP_SIZE #else .equ Heap_Size, 8192 #endif - .globl __HeapBase - .globl __HeapLimit + .globl __HeapBase + .globl __HeapLimit __HeapBase: - .if Heap_Size - .space Heap_Size + .if Heap_Size + .space Heap_Size .endif .size __HeapBase, . - __HeapBase __HeapLimit: .size __HeapLimit, . - __HeapLimit - - .section .Vectors + + .section .isr_vector .align 2 - .globl __Vectors -__Vectors: + .globl __isr_vector +__isr_vector: .long __StackTop /* Top of Stack */ .long Reset_Handler .long NMI_Handler @@ -84,7 +84,7 @@ __Vectors: .long 0 /*Reserved */ .long 0 /*Reserved */ .long SVC_Handler - .long 0 /*Reserved */ + .long DebugMon_Handler .long 0 /*Reserved */ .long PendSV_Handler .long SysTick_Handler @@ -128,7 +128,7 @@ __Vectors: .long SPIM2_SPIS2_SPI2_IRQHandler .long RTC2_IRQHandler .long I2S_IRQHandler - .long 0 /*Reserved */ + .long FPU_IRQHandler .long 0 /*Reserved */ .long 0 /*Reserved */ .long 0 /*Reserved */ @@ -331,49 +331,83 @@ __Vectors: .long 0 /*Reserved */ .long 0 /*Reserved */ - .size __Vectors, . - __Vectors + .size __isr_vector, . - __isr_vector /* Reset Handler */ + .text .thumb .thumb_func .align 1 - .globl Reset_Handler - .type Reset_Handler, %function + .globl Reset_Handler + .type Reset_Handler, %function Reset_Handler: - .fnstart - - -/* Loop to copy data from read only memory to RAM. The ranges - * of copy from/to are specified by following symbols evaluated in - * linker script. - * __etext: End of code section, i.e., begin of data sections to copy from. - * __data_start__/__data_end__: RAM address range that data should be - * copied to. Both must be aligned to 4 bytes boundary. */ - - ldr r1, =__etext - ldr r2, =__data_start__ - ldr r3, =__data_end__ - - subs r3, r2 - ble .LC0 - -.LC1: - subs r3, 4 - ldr r0, [r1,r3] - str r0, [r2,r3] - bgt .LC1 -.LC0: - - LDR R0, =SystemInit - BLX R0 - LDR R0, =_start - BX R0 + + +/* Loop to copy data from read only memory to RAM. + * The ranges of copy from/to are specified by following symbols: + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to. + * __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__ + * the user can add their own initialized data section before BSS section with the INTERT AFTER command. + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__bss_start__ + + subs r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: + +/* This part of work usually is done in C library startup code. Otherwise, + * define __STARTUP_CLEAR_BSS to enable it in this startup. This section + * clears the RAM where BSS data is located. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * All addresses must be aligned to 4 bytes boundary. + */ +#ifdef __STARTUP_CLEAR_BSS + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + + subs r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, #4 + str r0, [r1, r2] + bgt .L_loop3 + +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS */ + +/* Execute SystemInit function. */ + bl SystemInit + +/* Call _start function provided by libraries. + * If those libraries are not accessible, define __START as your entry point. + */ +#ifndef __START +#define __START _start +#endif + bl __START .pool - .cantunwind - .fnend .size Reset_Handler,.-Reset_Handler .section ".text" @@ -384,56 +418,63 @@ Reset_Handler: .weak NMI_Handler .type NMI_Handler, %function NMI_Handler: - B . + b . .size NMI_Handler, . - NMI_Handler .weak HardFault_Handler .type HardFault_Handler, %function HardFault_Handler: - B . + b . .size HardFault_Handler, . - HardFault_Handler .weak MemoryManagement_Handler .type MemoryManagement_Handler, %function MemoryManagement_Handler: - B . + b . .size MemoryManagement_Handler, . - MemoryManagement_Handler .weak BusFault_Handler .type BusFault_Handler, %function BusFault_Handler: - B . + b . .size BusFault_Handler, . - BusFault_Handler .weak UsageFault_Handler .type UsageFault_Handler, %function UsageFault_Handler: - B . + b . .size UsageFault_Handler, . - UsageFault_Handler .weak SVC_Handler .type SVC_Handler, %function SVC_Handler: - B . + b . .size SVC_Handler, . - SVC_Handler + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + b . + .size DebugMon_Handler, . - DebugMon_Handler + + .weak PendSV_Handler .type PendSV_Handler, %function PendSV_Handler: - B . + b . .size PendSV_Handler, . - PendSV_Handler .weak SysTick_Handler .type SysTick_Handler, %function SysTick_Handler: - B . + b . .size SysTick_Handler, . - SysTick_Handler @@ -442,7 +483,7 @@ SysTick_Handler: .globl Default_Handler .type Default_Handler, %function Default_Handler: - B . + b . .size Default_Handler, . - Default_Handler .macro IRQ handler @@ -486,5 +527,6 @@ Default_Handler: IRQ SPIM2_SPIS2_SPI2_IRQHandler IRQ RTC2_IRQHandler IRQ I2S_IRQHandler + IRQ FPU_IRQHandler .end diff --git a/components/toolchain/gcc/gcc_startup_nrf52840.S b/components/toolchain/gcc/gcc_startup_nrf52840.S new file mode 100644 index 0000000..28e83af --- /dev/null +++ b/components/toolchain/gcc/gcc_startup_nrf52840.S @@ -0,0 +1,538 @@ +/* Copyright (c) 2013 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. + ---------------------------------------------------------------------------*/ + + .syntax unified + .arch armv7e-m + +#ifdef __STARTUP_CONFIG +#include "startup_config.h" +#endif + + .section .stack + .align 3 +#if defined(__STARTUP_CONFIG) + .equ Stack_Size, __STARTUP_CONFIG_STACK_SIZE +#elif defined(__STACK_SIZE) + .equ Stack_Size, __STACK_SIZE +#else + .equ Stack_Size, 8192 +#endif + .globl __StackTop + .globl __StackLimit +__StackLimit: + .space Stack_Size + .size __StackLimit, . - __StackLimit +__StackTop: + .size __StackTop, . - __StackTop + + .section .heap + .align 3 +#if defined(__STARTUP_CONFIG) + .equ Heap_Size, __STARTUP_CONFIG_HEAP_SIZE +#elif defined(__HEAP_SIZE) + .equ Heap_Size, __HEAP_SIZE +#else + .equ Heap_Size, 8192 +#endif + .globl __HeapBase + .globl __HeapLimit +__HeapBase: + .if Heap_Size + .space Heap_Size + .endif + .size __HeapBase, . - __HeapBase +__HeapLimit: + .size __HeapLimit, . - __HeapLimit + + .section .isr_vector + .align 2 + .globl __isr_vector +__isr_vector: + .long __StackTop /* Top of Stack */ + .long Reset_Handler + .long NMI_Handler + .long HardFault_Handler + .long MemoryManagement_Handler + .long BusFault_Handler + .long UsageFault_Handler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long SVC_Handler + .long DebugMon_Handler + .long 0 /*Reserved */ + .long PendSV_Handler + .long SysTick_Handler + + /* External Interrupts */ + .long POWER_CLOCK_IRQHandler + .long RADIO_IRQHandler + .long UARTE0_UART0_IRQHandler + .long SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + .long SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + .long NFCT_IRQHandler + .long GPIOTE_IRQHandler + .long SAADC_IRQHandler + .long TIMER0_IRQHandler + .long TIMER1_IRQHandler + .long TIMER2_IRQHandler + .long RTC0_IRQHandler + .long TEMP_IRQHandler + .long RNG_IRQHandler + .long ECB_IRQHandler + .long CCM_AAR_IRQHandler + .long WDT_IRQHandler + .long RTC1_IRQHandler + .long QDEC_IRQHandler + .long COMP_LPCOMP_IRQHandler + .long SWI0_EGU0_IRQHandler + .long SWI1_EGU1_IRQHandler + .long SWI2_EGU2_IRQHandler + .long SWI3_EGU3_IRQHandler + .long SWI4_EGU4_IRQHandler + .long SWI5_EGU5_IRQHandler + .long TIMER3_IRQHandler + .long TIMER4_IRQHandler + .long PWM0_IRQHandler + .long PDM_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long MWU_IRQHandler + .long PWM1_IRQHandler + .long PWM2_IRQHandler + .long SPIM2_SPIS2_SPI2_IRQHandler + .long RTC2_IRQHandler + .long I2S_IRQHandler + .long FPU_IRQHandler + .long USBD_IRQHandler + .long UARTE1_IRQHandler + .long QSPI_IRQHandler + .long CRYPTOCELL_IRQHandler + .long SPIM3_IRQHandler + .long 0 /*Reserved */ + .long PWM3_IRQHandler + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + .long 0 /*Reserved */ + + .size __isr_vector, . - __isr_vector + +/* Reset Handler */ + + + .text + .thumb + .thumb_func + .align 1 + .globl Reset_Handler + .type Reset_Handler, %function +Reset_Handler: + + +/* Loop to copy data from read only memory to RAM. + * The ranges of copy from/to are specified by following symbols: + * __etext: LMA of start of the section to copy from. Usually end of text + * __data_start__: VMA of start of the section to copy to. + * __bss_start__: VMA of end of the section to copy to. Normally __data_end__ is used, but by using __bss_start__ + * the user can add their own initialized data section before BSS section with the INTERT AFTER command. + * + * All addresses must be aligned to 4 bytes boundary. + */ + ldr r1, =__etext + ldr r2, =__data_start__ + ldr r3, =__bss_start__ + + subs r3, r2 + ble .L_loop1_done + +.L_loop1: + subs r3, #4 + ldr r0, [r1,r3] + str r0, [r2,r3] + bgt .L_loop1 + +.L_loop1_done: + +/* This part of work usually is done in C library startup code. Otherwise, + * define __STARTUP_CLEAR_BSS to enable it in this startup. This section + * clears the RAM where BSS data is located. + * + * The BSS section is specified by following symbols + * __bss_start__: start of the BSS section. + * __bss_end__: end of the BSS section. + * + * All addresses must be aligned to 4 bytes boundary. + */ +#ifdef __STARTUP_CLEAR_BSS + ldr r1, =__bss_start__ + ldr r2, =__bss_end__ + + movs r0, 0 + + subs r2, r1 + ble .L_loop3_done + +.L_loop3: + subs r2, #4 + str r0, [r1, r2] + bgt .L_loop3 + +.L_loop3_done: +#endif /* __STARTUP_CLEAR_BSS */ + +/* Execute SystemInit function. */ + bl SystemInit + +/* Call _start function provided by libraries. + * If those libraries are not accessible, define __START as your entry point. + */ +#ifndef __START +#define __START _start +#endif + bl __START + + .pool + .size Reset_Handler,.-Reset_Handler + + .section ".text" + + +/* Dummy Exception Handlers (infinite loops which can be modified) */ + + .weak NMI_Handler + .type NMI_Handler, %function +NMI_Handler: + b . + .size NMI_Handler, . - NMI_Handler + + + .weak HardFault_Handler + .type HardFault_Handler, %function +HardFault_Handler: + b . + .size HardFault_Handler, . - HardFault_Handler + + + .weak MemoryManagement_Handler + .type MemoryManagement_Handler, %function +MemoryManagement_Handler: + b . + .size MemoryManagement_Handler, . - MemoryManagement_Handler + + + .weak BusFault_Handler + .type BusFault_Handler, %function +BusFault_Handler: + b . + .size BusFault_Handler, . - BusFault_Handler + + + .weak UsageFault_Handler + .type UsageFault_Handler, %function +UsageFault_Handler: + b . + .size UsageFault_Handler, . - UsageFault_Handler + + + .weak SVC_Handler + .type SVC_Handler, %function +SVC_Handler: + b . + .size SVC_Handler, . - SVC_Handler + + + .weak DebugMon_Handler + .type DebugMon_Handler, %function +DebugMon_Handler: + b . + .size DebugMon_Handler, . - DebugMon_Handler + + + .weak PendSV_Handler + .type PendSV_Handler, %function +PendSV_Handler: + b . + .size PendSV_Handler, . - PendSV_Handler + + + .weak SysTick_Handler + .type SysTick_Handler, %function +SysTick_Handler: + b . + .size SysTick_Handler, . - SysTick_Handler + + +/* IRQ Handlers */ + + .globl Default_Handler + .type Default_Handler, %function +Default_Handler: + b . + .size Default_Handler, . - Default_Handler + + .macro IRQ handler + .weak \handler + .set \handler, Default_Handler + .endm + + IRQ POWER_CLOCK_IRQHandler + IRQ RADIO_IRQHandler + IRQ UARTE0_UART0_IRQHandler + IRQ SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + IRQ SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + IRQ NFCT_IRQHandler + IRQ GPIOTE_IRQHandler + IRQ SAADC_IRQHandler + IRQ TIMER0_IRQHandler + IRQ TIMER1_IRQHandler + IRQ TIMER2_IRQHandler + IRQ RTC0_IRQHandler + IRQ TEMP_IRQHandler + IRQ RNG_IRQHandler + IRQ ECB_IRQHandler + IRQ CCM_AAR_IRQHandler + IRQ WDT_IRQHandler + IRQ RTC1_IRQHandler + IRQ QDEC_IRQHandler + IRQ COMP_LPCOMP_IRQHandler + IRQ SWI0_EGU0_IRQHandler + IRQ SWI1_EGU1_IRQHandler + IRQ SWI2_EGU2_IRQHandler + IRQ SWI3_EGU3_IRQHandler + IRQ SWI4_EGU4_IRQHandler + IRQ SWI5_EGU5_IRQHandler + IRQ TIMER3_IRQHandler + IRQ TIMER4_IRQHandler + IRQ PWM0_IRQHandler + IRQ PDM_IRQHandler + IRQ MWU_IRQHandler + IRQ PWM1_IRQHandler + IRQ PWM2_IRQHandler + IRQ SPIM2_SPIS2_SPI2_IRQHandler + IRQ RTC2_IRQHandler + IRQ I2S_IRQHandler + IRQ FPU_IRQHandler + IRQ USBD_IRQHandler + IRQ UARTE1_IRQHandler + IRQ QSPI_IRQHandler + IRQ CRYPTOCELL_IRQHandler + IRQ SPIM3_IRQHandler + IRQ PWM3_IRQHandler + + .end diff --git a/components/toolchain/gcc/nrf51_common.ld b/components/toolchain/gcc/nrf51_common.ld index af3d2df..e49ee30 100644 --- a/components/toolchain/gcc/nrf51_common.ld +++ b/components/toolchain/gcc/nrf51_common.ld @@ -1,4 +1,4 @@ -/* Linker script for Nordic Semiconductor nRF5 devices +/* Linker script for Nordic Semiconductor nRF51 devices * * Version: Sourcery G++ 4.5-1 * Support: https://support.codesourcery.com/GNUToolchain/ @@ -21,7 +21,7 @@ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: * Reset_Handler : Entry of reset handler - * + * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end @@ -38,6 +38,7 @@ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") * __bss_end__ * __end__ * end + * __HeapBase * __HeapLimit * __StackLimit * __StackTop @@ -47,118 +48,114 @@ ENTRY(Reset_Handler) SECTIONS { - .text : - { - KEEP(*(.Vectors)) - *(.text*) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.rodata*) - - *(.eh_frame*) - . = ALIGN(4); - } > FLASH - - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - . = ALIGN(4); - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - . = ALIGN(4); - } > FLASH - __exidx_end = .; - - __etext = .; - - .data : AT (__etext) - { - __data_start__ = .; - *(vtable) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - *(SORT(.init_array.*)) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - KEEP(*(.fini_array)) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.jcr) - . = ALIGN(4); - /* All data end */ - __data_end__ = .; - - } > RAM - - .bss : - { - . = ALIGN(4); - __bss_start__ = .; - *(.bss*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (COPY): - { - __end__ = .; - end = __end__; - *(.heap*) - __HeapLimit = .; - } > RAM - - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > RAM - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + PROVIDE(end = .); + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") } - diff --git a/components/toolchain/gcc/nrf52840_xxaa.ld b/components/toolchain/gcc/nrf52840_xxaa.ld new file mode 100644 index 0000000..24c4e13 --- /dev/null +++ b/components/toolchain/gcc/nrf52840_xxaa.ld @@ -0,0 +1,13 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +GROUP(-lgcc -lc -lnosys) + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x100000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 +} + + +INCLUDE "nrf52_common.ld" diff --git a/components/toolchain/gcc/nrf52_common.ld b/components/toolchain/gcc/nrf52_common.ld index af3d2df..013e0b4 100644 --- a/components/toolchain/gcc/nrf52_common.ld +++ b/components/toolchain/gcc/nrf52_common.ld @@ -1,4 +1,4 @@ -/* Linker script for Nordic Semiconductor nRF5 devices +/* Linker script for Nordic Semiconductor nRF52 devices * * Version: Sourcery G++ 4.5-1 * Support: https://support.codesourcery.com/GNUToolchain/ @@ -21,7 +21,7 @@ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: * Reset_Handler : Entry of reset handler - * + * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end @@ -38,6 +38,7 @@ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") * __bss_end__ * __end__ * end + * __HeapBase * __HeapLimit * __StackLimit * __StackTop @@ -47,118 +48,114 @@ ENTRY(Reset_Handler) SECTIONS { - .text : - { - KEEP(*(.Vectors)) - *(.text*) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.rodata*) - - *(.eh_frame*) - . = ALIGN(4); - } > FLASH - - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - . = ALIGN(4); - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - . = ALIGN(4); - } > FLASH - __exidx_end = .; - - __etext = .; - - .data : AT (__etext) - { - __data_start__ = .; - *(vtable) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - *(SORT(.init_array.*)) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - KEEP(*(.fini_array)) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.jcr) - . = ALIGN(4); - /* All data end */ - __data_end__ = .; - - } > RAM - - .bss : - { - . = ALIGN(4); - __bss_start__ = .; - *(.bss*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (COPY): - { - __end__ = .; - end = __end__; - *(.heap*) - __HeapLimit = .; - } > RAM - - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > RAM - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + PROVIDE(end = .); + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") } - diff --git a/components/toolchain/gcc/nrf5x_common.ld b/components/toolchain/gcc/nrf5x_common.ld index af3d2df..e49ee30 100644 --- a/components/toolchain/gcc/nrf5x_common.ld +++ b/components/toolchain/gcc/nrf5x_common.ld @@ -1,4 +1,4 @@ -/* Linker script for Nordic Semiconductor nRF5 devices +/* Linker script for Nordic Semiconductor nRF51 devices * * Version: Sourcery G++ 4.5-1 * Support: https://support.codesourcery.com/GNUToolchain/ @@ -21,7 +21,7 @@ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") * with other linker script that defines memory regions FLASH and RAM. * It references following symbols, which must be defined in code: * Reset_Handler : Entry of reset handler - * + * * It defines following symbols, which code can use without definition: * __exidx_start * __exidx_end @@ -38,6 +38,7 @@ OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") * __bss_end__ * __end__ * end + * __HeapBase * __HeapLimit * __StackLimit * __StackTop @@ -47,118 +48,114 @@ ENTRY(Reset_Handler) SECTIONS { - .text : - { - KEEP(*(.Vectors)) - *(.text*) - - KEEP(*(.init)) - KEEP(*(.fini)) - - /* .ctors */ - *crtbegin.o(.ctors) - *crtbegin?.o(.ctors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) - *(SORT(.ctors.*)) - *(.ctors) - - /* .dtors */ - *crtbegin.o(.dtors) - *crtbegin?.o(.dtors) - *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) - *(SORT(.dtors.*)) - *(.dtors) - - *(.rodata*) - - *(.eh_frame*) - . = ALIGN(4); - } > FLASH - - - .ARM.extab : - { - *(.ARM.extab* .gnu.linkonce.armextab.*) - . = ALIGN(4); - } > FLASH - - __exidx_start = .; - .ARM.exidx : - { - *(.ARM.exidx* .gnu.linkonce.armexidx.*) - . = ALIGN(4); - } > FLASH - __exidx_end = .; - - __etext = .; - - .data : AT (__etext) - { - __data_start__ = .; - *(vtable) - *(.data*) - - . = ALIGN(4); - /* preinit data */ - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP(*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - - . = ALIGN(4); - /* init data */ - PROVIDE_HIDDEN (__init_array_start = .); - *(SORT(.init_array.*)) - KEEP(*(.init_array)) - PROVIDE_HIDDEN (__init_array_end = .); - - - . = ALIGN(4); - /* finit data */ - PROVIDE_HIDDEN (__fini_array_start = .); - *(SORT(.fini_array.*)) - KEEP(*(.fini_array)) - PROVIDE_HIDDEN (__fini_array_end = .); - - *(.jcr) - . = ALIGN(4); - /* All data end */ - __data_end__ = .; - - } > RAM - - .bss : - { - . = ALIGN(4); - __bss_start__ = .; - *(.bss*) - *(COMMON) - . = ALIGN(4); - __bss_end__ = .; - } > RAM - - .heap (COPY): - { - __end__ = .; - end = __end__; - *(.heap*) - __HeapLimit = .; - } > RAM - - /* .stack_dummy section doesn't contains any symbols. It is only - * used for linker to calculate size of stack sections, and assign - * values to stack symbols later */ - .stack_dummy (COPY): - { - *(.stack*) - } > RAM - - /* Set stack top to end of RAM, and stack limit move down by - * size of stack_dummy section */ - __StackTop = ORIGIN(RAM) + LENGTH(RAM); - __StackLimit = __StackTop - SIZEOF(.stack_dummy); - PROVIDE(__stack = __StackTop); - - /* Check if data + heap + stack exceeds RAM limit */ - ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") + .text : + { + KEEP(*(.isr_vector)) + *(.text*) + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.rodata*) + + KEEP(*(.eh_frame*)) + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + __etext = .; + + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + KEEP(*(.jcr*)) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + + } > RAM + + .bss : + { + . = ALIGN(4); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __HeapBase = .; + __end__ = .; + PROVIDE(end = .); + KEEP(*(.heap*)) + __HeapLimit = .; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + KEEP(*(.stack*)) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") } - diff --git a/components/toolchain/iar/iar_startup_nrf51.s b/components/toolchain/iar/iar_startup_nrf51.s index dcf527b..ec67462 100644 --- a/components/toolchain/iar/iar_startup_nrf51.s +++ b/components/toolchain/iar/iar_startup_nrf51.s @@ -1,46 +1,68 @@ -;; Copyright (c) 2015, Nordic Semiconductor ASA -;; 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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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. - - - -;; NOTE: Template files (including this one) are application specific and therefore -;; expected to be copied into the application project folder prior to its use! - -;; Description message +;/* Copyright (c) 2012 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. +; ---------------------------------------------------------------------------*/ + + +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. + + MODULE ?cstartup +#if defined(__STARTUP_CONFIG) + + #include "startup_config.h" + + SECTION CSTACK:DATA:NOROOT(3) + DS8 __STARTUP_CONFIG_STACK_SIZE + + SECTION HEAP:DATA:NOROOT(3) + DS8 __STARTUP_CONFIG_HEAP_SIZE + +#else + ;; Stack size default : Defined in *.icf (linker file). Can be modified inside EW. ;; Heap size default : Defined in *.icf (linker file). Can be modified inside EW. ;; Forward declaration of sections. SECTION CSTACK:DATA:NOROOT(3) +#endif + + SECTION .intvec:CODE:NOROOT(2) EXTERN __iar_program_start @@ -71,38 +93,38 @@ __vector_table DCD SysTick_Handler ; External Interrupts - DCD POWER_CLOCK_IRQHandler - DCD RADIO_IRQHandler - DCD UART0_IRQHandler - DCD SPI0_TWI0_IRQHandler - DCD SPI1_TWI1_IRQHandler - DCD 0 ; Reserved - DCD GPIOTE_IRQHandler - DCD ADC_IRQHandler - DCD TIMER0_IRQHandler - DCD TIMER1_IRQHandler - DCD TIMER2_IRQHandler - DCD RTC0_IRQHandler - DCD TEMP_IRQHandler - DCD RNG_IRQHandler - DCD ECB_IRQHandler - DCD CCM_AAR_IRQHandler - DCD WDT_IRQHandler - DCD RTC1_IRQHandler - DCD QDEC_IRQHandler - DCD LPCOMP_IRQHandler - DCD SWI0_IRQHandler - DCD SWI1_IRQHandler - DCD SWI2_IRQHandler - DCD SWI3_IRQHandler - DCD SWI4_IRQHandler - DCD SWI5_IRQHandler - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UART0_IRQHandler + DCD SPI0_TWI0_IRQHandler + DCD SPI1_TWI1_IRQHandler + DCD 0 ; Reserved + DCD GPIOTE_IRQHandler + DCD ADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD LPCOMP_IRQHandler + DCD SWI0_IRQHandler + DCD SWI1_IRQHandler + DCD SWI2_IRQHandler + DCD SWI3_IRQHandler + DCD SWI4_IRQHandler + DCD SWI5_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved __Vectors_End __Vectors EQU __vector_table @@ -124,7 +146,7 @@ Reset_Handler LDR R2, [R0] ORRS R2, R2, R1 STR R2, [R0] - + LDR R0, =NRF_POWER_RAMONB_ADDRESS LDR R2, [R0] ORRS R2, R2, R1 @@ -136,7 +158,7 @@ Reset_Handler BX R0 ; Dummy exception handlers - + PUBWEAK NMI_Handler SECTION .text:CODE:REORDER:NOROOT(1) @@ -170,103 +192,128 @@ SysTick_Handler SECTION .text:CODE:REORDER:NOROOT(1) POWER_CLOCK_IRQHandler B . + PUBWEAK RADIO_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) RADIO_IRQHandler B . + PUBWEAK UART0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) UART0_IRQHandler B . + PUBWEAK SPI0_TWI0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SPI0_TWI0_IRQHandler B . + PUBWEAK SPI1_TWI1_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SPI1_TWI1_IRQHandler B . + PUBWEAK GPIOTE_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) GPIOTE_IRQHandler B . + PUBWEAK ADC_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) ADC_IRQHandler B . + PUBWEAK TIMER0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) TIMER0_IRQHandler B . + PUBWEAK TIMER1_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) TIMER1_IRQHandler B . + PUBWEAK TIMER2_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) TIMER2_IRQHandler B . + PUBWEAK RTC0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) RTC0_IRQHandler B . + PUBWEAK TEMP_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) TEMP_IRQHandler B . + PUBWEAK RNG_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) RNG_IRQHandler B . + PUBWEAK ECB_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) ECB_IRQHandler B . + PUBWEAK CCM_AAR_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) CCM_AAR_IRQHandler B . + PUBWEAK WDT_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) WDT_IRQHandler B . + PUBWEAK RTC1_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) RTC1_IRQHandler B . + PUBWEAK QDEC_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) QDEC_IRQHandler B . + PUBWEAK LPCOMP_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) LPCOMP_IRQHandler B . + PUBWEAK SWI0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI0_IRQHandler B . + PUBWEAK SWI1_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI1_IRQHandler B . + PUBWEAK SWI2_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI2_IRQHandler B . + PUBWEAK SWI3_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI3_IRQHandler B . + PUBWEAK SWI4_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI4_IRQHandler B . + PUBWEAK SWI5_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI5_IRQHandler B . + END diff --git a/components/toolchain/iar/iar_startup_nrf52.s b/components/toolchain/iar/iar_startup_nrf52.s index 8ff1814..d6ebb4b 100644 --- a/components/toolchain/iar/iar_startup_nrf52.s +++ b/components/toolchain/iar/iar_startup_nrf52.s @@ -1,46 +1,68 @@ -;; Copyright (c) 2015, Nordic Semiconductor ASA -;; 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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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. - - - -;; NOTE: Template files (including this one) are application specific and therefore -;; expected to be copied into the application project folder prior to its use! - -;; Description message +;/* Copyright (c) 2012 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. +; ---------------------------------------------------------------------------*/ + + +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. + + MODULE ?cstartup +#if defined(__STARTUP_CONFIG) + + #include "startup_config.h" + + SECTION CSTACK:DATA:NOROOT(3) + DS8 __STARTUP_CONFIG_STACK_SIZE + + SECTION HEAP:DATA:NOROOT(3) + DS8 __STARTUP_CONFIG_HEAP_SIZE + +#else + ;; Stack size default : Defined in *.icf (linker file). Can be modified inside EW. ;; Heap size default : Defined in *.icf (linker file). Can be modified inside EW. ;; Forward declaration of sections. SECTION CSTACK:DATA:NOROOT(3) +#endif + + SECTION .intvec:CODE:NOROOT(2) EXTERN __iar_program_start @@ -65,257 +87,258 @@ __vector_table DCD 0 ; Reserved DCD 0 ; Reserved DCD SVC_Handler - DCD 0 ; Reserved + DCD DebugMon_Handler DCD 0 ; Reserved DCD PendSV_Handler DCD SysTick_Handler ; External Interrupts - DCD POWER_CLOCK_IRQHandler - DCD RADIO_IRQHandler - DCD UARTE0_UART0_IRQHandler - DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler - DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler - DCD NFCT_IRQHandler - DCD GPIOTE_IRQHandler - DCD SAADC_IRQHandler - DCD TIMER0_IRQHandler - DCD TIMER1_IRQHandler - DCD TIMER2_IRQHandler - DCD RTC0_IRQHandler - DCD TEMP_IRQHandler - DCD RNG_IRQHandler - DCD ECB_IRQHandler - DCD CCM_AAR_IRQHandler - DCD WDT_IRQHandler - DCD RTC1_IRQHandler - DCD QDEC_IRQHandler - DCD COMP_LPCOMP_IRQHandler - DCD SWI0_EGU0_IRQHandler - DCD SWI1_EGU1_IRQHandler - DCD SWI2_EGU2_IRQHandler - DCD SWI3_EGU3_IRQHandler - DCD SWI4_EGU4_IRQHandler - DCD SWI5_EGU5_IRQHandler - DCD TIMER3_IRQHandler - DCD TIMER4_IRQHandler - DCD PWM0_IRQHandler - DCD PDM_IRQHandler - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD MWU_IRQHandler - DCD PWM1_IRQHandler - DCD PWM2_IRQHandler - DCD SPIM2_SPIS2_SPI2_IRQHandler - DCD RTC2_IRQHandler - DCD I2S_IRQHandler - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved - DCD 0 ; Reserved + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UARTE0_UART0_IRQHandler + DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + DCD NFCT_IRQHandler + DCD GPIOTE_IRQHandler + DCD SAADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD COMP_LPCOMP_IRQHandler + DCD SWI0_EGU0_IRQHandler + DCD SWI1_EGU1_IRQHandler + DCD SWI2_EGU2_IRQHandler + DCD SWI3_EGU3_IRQHandler + DCD SWI4_EGU4_IRQHandler + DCD SWI5_EGU5_IRQHandler + DCD TIMER3_IRQHandler + DCD TIMER4_IRQHandler + DCD PWM0_IRQHandler + DCD PDM_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD MWU_IRQHandler + DCD PWM1_IRQHandler + DCD PWM2_IRQHandler + DCD SPIM2_SPIS2_SPI2_IRQHandler + DCD RTC2_IRQHandler + DCD I2S_IRQHandler + DCD FPU_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved __Vectors_End __Vectors EQU __vector_table __Vectors_Size EQU __Vectors_End - __Vectors + ; Default handlers. THUMB @@ -329,7 +352,7 @@ Reset_Handler BX R0 ; Dummy exception handlers - + PUBWEAK NMI_Handler SECTION .text:CODE:REORDER:NOROOT(1) @@ -361,6 +384,11 @@ UsageFault_Handler SVC_Handler B . + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B . + PUBWEAK PendSV_Handler SECTION .text:CODE:REORDER:NOROOT(1) PendSV_Handler @@ -378,147 +406,188 @@ SysTick_Handler SECTION .text:CODE:REORDER:NOROOT(1) POWER_CLOCK_IRQHandler B . + PUBWEAK RADIO_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) RADIO_IRQHandler B . + PUBWEAK UARTE0_UART0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) UARTE0_UART0_IRQHandler B . + PUBWEAK SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler B . + PUBWEAK SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler B . + PUBWEAK NFCT_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) NFCT_IRQHandler B . + PUBWEAK GPIOTE_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) GPIOTE_IRQHandler B . + PUBWEAK SAADC_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SAADC_IRQHandler B . + PUBWEAK TIMER0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) TIMER0_IRQHandler B . + PUBWEAK TIMER1_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) TIMER1_IRQHandler B . + PUBWEAK TIMER2_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) TIMER2_IRQHandler B . + PUBWEAK RTC0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) RTC0_IRQHandler B . + PUBWEAK TEMP_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) TEMP_IRQHandler B . + PUBWEAK RNG_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) RNG_IRQHandler B . + PUBWEAK ECB_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) ECB_IRQHandler B . + PUBWEAK CCM_AAR_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) CCM_AAR_IRQHandler B . + PUBWEAK WDT_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) WDT_IRQHandler B . + PUBWEAK RTC1_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) RTC1_IRQHandler B . + PUBWEAK QDEC_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) QDEC_IRQHandler B . + PUBWEAK COMP_LPCOMP_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) COMP_LPCOMP_IRQHandler B . + PUBWEAK SWI0_EGU0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI0_EGU0_IRQHandler B . + PUBWEAK SWI1_EGU1_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI1_EGU1_IRQHandler B . + PUBWEAK SWI2_EGU2_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI2_EGU2_IRQHandler B . + PUBWEAK SWI3_EGU3_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI3_EGU3_IRQHandler B . + PUBWEAK SWI4_EGU4_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI4_EGU4_IRQHandler B . + PUBWEAK SWI5_EGU5_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SWI5_EGU5_IRQHandler B . + PUBWEAK TIMER3_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) TIMER3_IRQHandler B . + PUBWEAK TIMER4_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) TIMER4_IRQHandler B . + PUBWEAK PWM0_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) PWM0_IRQHandler B . + PUBWEAK PDM_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) PDM_IRQHandler B . + PUBWEAK MWU_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) MWU_IRQHandler B . + PUBWEAK PWM1_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) PWM1_IRQHandler B . + PUBWEAK PWM2_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) PWM2_IRQHandler B . + PUBWEAK SPIM2_SPIS2_SPI2_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) SPIM2_SPIS2_SPI2_IRQHandler B . + PUBWEAK RTC2_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) RTC2_IRQHandler B . + PUBWEAK I2S_IRQHandler SECTION .text:CODE:REORDER:NOROOT(1) I2S_IRQHandler B . + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +FPU_IRQHandler + B . + + END diff --git a/components/toolchain/iar/iar_startup_nrf52840.s b/components/toolchain/iar/iar_startup_nrf52840.s new file mode 100644 index 0000000..1d16059 --- /dev/null +++ b/components/toolchain/iar/iar_startup_nrf52840.s @@ -0,0 +1,623 @@ +;/* Copyright (c) 2012 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. +; ---------------------------------------------------------------------------*/ + + +; The modules in this file are included in the libraries, and may be replaced +; by any user-defined modules that define the PUBLIC symbol _program_start or +; a user defined start symbol. +; To override the cstartup defined in the library, simply add your modified +; version to the workbench project. +; +; The vector table is normally located at address 0. +; When debugging in RAM, it can be located in RAM, aligned to at least 2^6. +; The name "__vector_table" has special meaning for C-SPY: +; it is where the SP start value is found, and the NVIC vector +; table register (VTOR) is initialized to this address if != 0. + + + + MODULE ?cstartup + +#if defined(__STARTUP_CONFIG) + + #include "startup_config.h" + + SECTION CSTACK:DATA:NOROOT(3) + DS8 __STARTUP_CONFIG_STACK_SIZE + + SECTION HEAP:DATA:NOROOT(3) + DS8 __STARTUP_CONFIG_HEAP_SIZE + +#else + + ;; Stack size default : Defined in *.icf (linker file). Can be modified inside EW. + ;; Heap size default : Defined in *.icf (linker file). Can be modified inside EW. + + ;; Forward declaration of sections. + SECTION CSTACK:DATA:NOROOT(3) + +#endif + + + SECTION .intvec:CODE:NOROOT(2) + + EXTERN __iar_program_start + EXTERN SystemInit + PUBLIC __vector_table + PUBLIC __Vectors + PUBLIC __Vectors_End + PUBLIC __Vectors_Size + + DATA + +__vector_table + DCD sfe(CSTACK) + DCD Reset_Handler + DCD NMI_Handler + DCD HardFault_Handler + DCD MemoryManagement_Handler + DCD BusFault_Handler + DCD UsageFault_Handler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD SVC_Handler + DCD DebugMon_Handler + DCD 0 ; Reserved + DCD PendSV_Handler + DCD SysTick_Handler + + ; External Interrupts + DCD POWER_CLOCK_IRQHandler + DCD RADIO_IRQHandler + DCD UARTE0_UART0_IRQHandler + DCD SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + DCD SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + DCD NFCT_IRQHandler + DCD GPIOTE_IRQHandler + DCD SAADC_IRQHandler + DCD TIMER0_IRQHandler + DCD TIMER1_IRQHandler + DCD TIMER2_IRQHandler + DCD RTC0_IRQHandler + DCD TEMP_IRQHandler + DCD RNG_IRQHandler + DCD ECB_IRQHandler + DCD CCM_AAR_IRQHandler + DCD WDT_IRQHandler + DCD RTC1_IRQHandler + DCD QDEC_IRQHandler + DCD COMP_LPCOMP_IRQHandler + DCD SWI0_EGU0_IRQHandler + DCD SWI1_EGU1_IRQHandler + DCD SWI2_EGU2_IRQHandler + DCD SWI3_EGU3_IRQHandler + DCD SWI4_EGU4_IRQHandler + DCD SWI5_EGU5_IRQHandler + DCD TIMER3_IRQHandler + DCD TIMER4_IRQHandler + DCD PWM0_IRQHandler + DCD PDM_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD MWU_IRQHandler + DCD PWM1_IRQHandler + DCD PWM2_IRQHandler + DCD SPIM2_SPIS2_SPI2_IRQHandler + DCD RTC2_IRQHandler + DCD I2S_IRQHandler + DCD FPU_IRQHandler + DCD USBD_IRQHandler + DCD UARTE1_IRQHandler + DCD QSPI_IRQHandler + DCD CRYPTOCELL_IRQHandler + DCD SPIM3_IRQHandler + DCD 0 ; Reserved + DCD PWM3_IRQHandler + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + DCD 0 ; Reserved + +__Vectors_End +__Vectors EQU __vector_table +__Vectors_Size EQU __Vectors_End - __Vectors + + +; Default handlers. + THUMB + + PUBWEAK Reset_Handler + SECTION .text:CODE:REORDER:NOROOT(2) +Reset_Handler + + LDR R0, =SystemInit + BLX R0 + LDR R0, =__iar_program_start + BX R0 + + ; Dummy exception handlers + + + PUBWEAK NMI_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +NMI_Handler + B . + + PUBWEAK HardFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +HardFault_Handler + B . + + PUBWEAK MemoryManagement_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +MemoryManagement_Handler + B . + + PUBWEAK BusFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +BusFault_Handler + B . + + PUBWEAK UsageFault_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +UsageFault_Handler + B . + + PUBWEAK SVC_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SVC_Handler + B . + + PUBWEAK DebugMon_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +DebugMon_Handler + B . + + PUBWEAK PendSV_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +PendSV_Handler + B . + + PUBWEAK SysTick_Handler + SECTION .text:CODE:REORDER:NOROOT(1) +SysTick_Handler + B . + + + ; Dummy interrupt handlers + + PUBWEAK POWER_CLOCK_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +POWER_CLOCK_IRQHandler + B . + + PUBWEAK RADIO_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RADIO_IRQHandler + B . + + PUBWEAK UARTE0_UART0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +UARTE0_UART0_IRQHandler + B . + + PUBWEAK SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler + B . + + PUBWEAK SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM1_SPIS1_TWIM1_TWIS1_SPI1_TWI1_IRQHandler + B . + + PUBWEAK NFCT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +NFCT_IRQHandler + B . + + PUBWEAK GPIOTE_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +GPIOTE_IRQHandler + B . + + PUBWEAK SAADC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SAADC_IRQHandler + B . + + PUBWEAK TIMER0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER0_IRQHandler + B . + + PUBWEAK TIMER1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER1_IRQHandler + B . + + PUBWEAK TIMER2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER2_IRQHandler + B . + + PUBWEAK RTC0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC0_IRQHandler + B . + + PUBWEAK TEMP_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TEMP_IRQHandler + B . + + PUBWEAK RNG_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RNG_IRQHandler + B . + + PUBWEAK ECB_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +ECB_IRQHandler + B . + + PUBWEAK CCM_AAR_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +CCM_AAR_IRQHandler + B . + + PUBWEAK WDT_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +WDT_IRQHandler + B . + + PUBWEAK RTC1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC1_IRQHandler + B . + + PUBWEAK QDEC_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +QDEC_IRQHandler + B . + + PUBWEAK COMP_LPCOMP_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +COMP_LPCOMP_IRQHandler + B . + + PUBWEAK SWI0_EGU0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI0_EGU0_IRQHandler + B . + + PUBWEAK SWI1_EGU1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI1_EGU1_IRQHandler + B . + + PUBWEAK SWI2_EGU2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI2_EGU2_IRQHandler + B . + + PUBWEAK SWI3_EGU3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI3_EGU3_IRQHandler + B . + + PUBWEAK SWI4_EGU4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI4_EGU4_IRQHandler + B . + + PUBWEAK SWI5_EGU5_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SWI5_EGU5_IRQHandler + B . + + PUBWEAK TIMER3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER3_IRQHandler + B . + + PUBWEAK TIMER4_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +TIMER4_IRQHandler + B . + + PUBWEAK PWM0_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM0_IRQHandler + B . + + PUBWEAK PDM_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PDM_IRQHandler + B . + + PUBWEAK MWU_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +MWU_IRQHandler + B . + + PUBWEAK PWM1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM1_IRQHandler + B . + + PUBWEAK PWM2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM2_IRQHandler + B . + + PUBWEAK SPIM2_SPIS2_SPI2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM2_SPIS2_SPI2_IRQHandler + B . + + PUBWEAK RTC2_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +RTC2_IRQHandler + B . + + PUBWEAK I2S_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +I2S_IRQHandler + B . + + PUBWEAK FPU_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +FPU_IRQHandler + B . + + PUBWEAK USBD_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +USBD_IRQHandler + B . + + PUBWEAK UARTE1_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +UARTE1_IRQHandler + B . + + PUBWEAK QSPI_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +QSPI_IRQHandler + B . + + PUBWEAK CRYPTOCELL_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +CRYPTOCELL_IRQHandler + B . + + PUBWEAK SPIM3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +SPIM3_IRQHandler + B . + + PUBWEAK PWM3_IRQHandler + SECTION .text:CODE:REORDER:NOROOT(1) +PWM3_IRQHandler + B . + + + END + + diff --git a/components/toolchain/system_nrf51.c b/components/toolchain/system_nrf51.c index 9bfe509..0ad09d5 100644 --- a/components/toolchain/system_nrf51.c +++ b/components/toolchain/system_nrf51.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, Nordic Semiconductor ASA +/* Copyright (c) 2012 ARM LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,9 +11,9 @@ * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - * * Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * * 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 @@ -27,8 +27,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - -/* NOTE: Template files (including this one) are application specific and therefore expected to + +/* NOTE: Template files (including this one) are application specific and therefore expected to be copied into the application project folder prior to its use! */ #include @@ -43,10 +43,11 @@ static bool is_manual_peripheral_setup_needed(void); static bool is_disabled_in_debug_needed(void); +static bool is_peripheral_domain_setup_needed(void); #if defined ( __CC_ARM ) - uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; #elif defined ( __ICCARM__ ) __root uint32_t SystemCoreClock = __SYSTEM_CLOCK; #elif defined ( __GNUC__ ) @@ -65,7 +66,7 @@ void SystemInit(void) /* Prepare the peripherals for use as indicated by the PAN 26 "System: Manual setup is required to enable the use of peripherals" found at Product Anomaly document for your device found at - https://www.nordicsemi.com/. The side effect of executing these instructions in the devices + https://www.nordicsemi.com/. The side effect of executing these instructions in the devices that do not need it is that the new peripherals in the second generation devices (LPCOMP for example) will not be available. */ if (is_manual_peripheral_setup_needed()) @@ -73,18 +74,30 @@ void SystemInit(void) *(uint32_t volatile *)0x40000504 = 0xC007FFDF; *(uint32_t volatile *)0x40006C18 = 0x00008000; } - + /* Disable PROTENSET registers under debug, as indicated by PAN 59 "MPU: Reset value of DISABLEINDEBUG - register is incorrect" found at Product Anomaly document four your device found at + register is incorrect" found at Product Anomaly document for your device found at https://www.nordicsemi.com/. There is no side effect of using these instruction if not needed. */ if (is_disabled_in_debug_needed()) { NRF_MPU->DISABLEINDEBUG = MPU_DISABLEINDEBUG_DISABLEINDEBUG_Disabled << MPU_DISABLEINDEBUG_DISABLEINDEBUG_Pos; } + + /* Execute the following code to eliminate excessive current in sleep mode with RAM retention in nRF51802 devices, + as indicated by PAN 76 "System: Excessive current in sleep mode with retention" found at Product Anomaly document + for your device found at https://www.nordicsemi.com/. */ + if (is_peripheral_domain_setup_needed()){ + if (*(uint32_t volatile *)0x4006EC00 != 1){ + *(uint32_t volatile *)0x4006EC00 = 0x9375; + while (*(uint32_t volatile *)0x4006EC00 != 1){ + } + } + *(uint32_t volatile *)0x4006EC14 = 0xC0; + } } -static bool is_manual_peripheral_setup_needed(void) +static bool is_manual_peripheral_setup_needed(void) { if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) { @@ -101,11 +114,11 @@ static bool is_manual_peripheral_setup_needed(void) return true; } } - + return false; } -static bool is_disabled_in_debug_needed(void) +static bool is_disabled_in_debug_needed(void) { if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) { @@ -114,7 +127,24 @@ static bool is_disabled_in_debug_needed(void) return true; } } - + + return false; +} + +static bool is_peripheral_domain_setup_needed(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) + { + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xA0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0xD0) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) + { + return true; + } + } + return false; } diff --git a/components/toolchain/system_nrf51.h b/components/toolchain/system_nrf51.h index 4901173..71c4039 100644 --- a/components/toolchain/system_nrf51.h +++ b/components/toolchain/system_nrf51.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, Nordic Semiconductor ASA +/* Copyright (c) 2012 ARM LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,9 +11,9 @@ * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - * * Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * * 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 @@ -27,7 +27,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - + #ifndef SYSTEM_NRF51_H #define SYSTEM_NRF51_H diff --git a/components/toolchain/system_nrf51422.c b/components/toolchain/system_nrf51422.c index 712114e..abf0ad3 100644 --- a/components/toolchain/system_nrf51422.c +++ b/components/toolchain/system_nrf51422.c @@ -1,34 +1,45 @@ -/* Copyright (c) 2013, Nordic Semiconductor ASA +/** + * Copyright (c) 2013 - 2017, Nordic Semiconductor ASA + * * 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 Nordic Semiconductor ASA 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 THE COPYRIGHT HOLDER 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. - * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form, except as embedded into a Nordic + * Semiconductor ASA integrated circuit in a product or a software update for + * such product, 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. + * + * 3. Neither the name of Nordic Semiconductor ASA nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * 4. This software, with or without modification, must only be used with a + * Nordic Semiconductor ASA integrated circuit. + * + * 5. Any software provided in binary form under this license must not be reverse + * engineered, decompiled, modified and/or disassembled. + * + * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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. + * */ -/* NOTE: Template files (including this one) are application specific and therefore expected to + +/* NOTE: Template files (including this one) are application specific and therefore expected to be copied into the application project folder prior to its use! */ #include @@ -46,7 +57,7 @@ static bool is_disabled_in_debug_needed(void); #if defined ( __CC_ARM ) - uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK; #elif defined ( __ICCARM__ ) __root uint32_t SystemCoreClock = __SYSTEM_CLOCK; #elif defined ( __GNUC__ ) @@ -65,7 +76,7 @@ void SystemInit(void) /* Prepare the peripherals for use as indicated by the PAN 26 "System: Manual setup is required to enable the use of peripherals" found at Product Anomaly document for your device found at - https://www.nordicsemi.com/. The side effect of executing these instructions in the devices + https://www.nordicsemi.com/. The side effect of executing these instructions in the devices that do not need it is that the new peripherals in the second generation devices (LPCOMP for example) will not be available. */ if (is_manual_peripheral_setup_needed()) @@ -73,9 +84,9 @@ void SystemInit(void) *(uint32_t volatile *)0x40000504 = 0xC007FFDF; *(uint32_t volatile *)0x40006C18 = 0x00008000; } - + /* Disable PROTENSET registers under debug, as indicated by PAN 59 "MPU: Reset value of DISABLEINDEBUG - register is incorrect" found at Product Anomaly document four your device found at + register is incorrect" found at Product Anomaly document four your device found at https://www.nordicsemi.com/. There is no side effect of using these instruction if not needed. */ if (is_disabled_in_debug_needed()) { @@ -84,7 +95,7 @@ void SystemInit(void) } -static bool is_manual_peripheral_setup_needed(void) +static bool is_manual_peripheral_setup_needed(void) { if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) { @@ -101,11 +112,11 @@ static bool is_manual_peripheral_setup_needed(void) return true; } } - + return false; } -static bool is_disabled_in_debug_needed(void) +static bool is_disabled_in_debug_needed(void) { if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x1) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) { @@ -114,7 +125,7 @@ static bool is_disabled_in_debug_needed(void) return true; } } - + return false; } diff --git a/components/toolchain/system_nrf52.c b/components/toolchain/system_nrf52.c index 26f24f2..b96b417 100644 --- a/components/toolchain/system_nrf52.c +++ b/components/toolchain/system_nrf52.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, Nordic Semiconductor ASA +/* Copyright (c) 2012 ARM LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,9 +11,9 @@ * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - * * Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * * 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 @@ -27,7 +27,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - + #include #include #include "nrf.h" @@ -35,21 +35,23 @@ /*lint ++flb "Enter library region" */ -#define __SYSTEM_CLOCK_16M (16000000UL) -#define __SYSTEM_CLOCK_64M (64000000UL) +#define __SYSTEM_CLOCK_64M (64000000UL) -static bool errata_31(void); -static bool errata_32(void); -static bool errata_36(void); -static bool errata_37(void); -static bool errata_66(void); +static bool errata_16(void); +static bool errata_31(void); +static bool errata_32(void); +static bool errata_36(void); +static bool errata_37(void); +static bool errata_57(void); +static bool errata_66(void); +static bool errata_108(void); #if defined ( __CC_ARM ) uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; #elif defined ( __ICCARM__ ) __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M; -#elif defined ( __GNUC__ ) +#elif defined ( __GNUC__ ) uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; #endif @@ -60,35 +62,50 @@ void SystemCoreClockUpdate(void) void SystemInit(void) { - /* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document + /* Workaround for Errata 16 "System: RAM may be corrupt on wakeup from CPU IDLE" found at the Errata document for your device located at https://infocenter.nordicsemi.com/ */ - if (errata_31()){ + if (errata_16()){ + *(volatile uint32_t *)0x4007C074 = 3131961357ul; + } + + /* Workaround for Errata 31 "CLOCK: Calibration values are not correctly loaded from FICR at reset" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_31()){ *(volatile uint32_t *)0x4000053C = ((*(volatile uint32_t *)0x10000244) & 0x0000E000) >> 13; } - - /* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document + + /* Workaround for Errata 32 "DIF: Debug session automatically enables TracePort pins" found at the Errata document for your device located at https://infocenter.nordicsemi.com/ */ - if (errata_32()){ + if (errata_32()){ CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; } - - /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document + + /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document for your device located at https://infocenter.nordicsemi.com/ */ - if (errata_36()){ + if (errata_36()){ NRF_CLOCK->EVENTS_DONE = 0; NRF_CLOCK->EVENTS_CTTO = 0; NRF_CLOCK->CTIV = 0; } - - /* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document + + /* Workaround for Errata 37 "RADIO: Encryption engine is slow by default" found at the Errata document for your device located at https://infocenter.nordicsemi.com/ */ - if (errata_37()){ + if (errata_37()){ *(volatile uint32_t *)0x400005A0 = 0x3; } - - /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document + + /* Workaround for Errata 57 "NFCT: NFC Modulation amplitude" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_57()){ + *(volatile uint32_t *)0x40005610 = 0x00000005; + *(volatile uint32_t *)0x40005688 = 0x00000001; + *(volatile uint32_t *)0x40005618 = 0x00000000; + *(volatile uint32_t *)0x40005614 = 0x0000003F; + } + + /* Workaround for Errata 66 "TEMP: Linearity specification not met with default settings" found at the Errata document for your device located at https://infocenter.nordicsemi.com/ */ - if (errata_66()){ + if (errata_66()){ NRF_TEMP->A0 = NRF_FICR->TEMP.A0; NRF_TEMP->A1 = NRF_FICR->TEMP.A1; NRF_TEMP->A2 = NRF_FICR->TEMP.A2; @@ -107,37 +124,43 @@ void SystemInit(void) NRF_TEMP->T3 = NRF_FICR->TEMP.T3; NRF_TEMP->T4 = NRF_FICR->TEMP.T4; } + + /* Workaround for Errata 108 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_108()){ + *(volatile uint32_t *)0x40000EE4 = *(volatile uint32_t *)0x10000258 & 0x0000004F; + } - /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the - * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit + /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the + * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit * operations are not used in your code. */ #if (__FPU_USED == 1) - SCB->CPACR |= (3UL << 20) | (3UL << 22); + SCB->CPACR |= (3UL << 20) | (3UL << 22); __DSB(); __ISB(); #endif - - /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined, - two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as + + /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined, + two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as normal GPIOs. */ #if defined (CONFIG_NFCT_PINS_AS_GPIOS) if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; - while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} NVIC_SystemReset(); } #endif - + /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not - defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be + defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be reserved for PinReset and not available as normal GPIO. */ #if defined (CONFIG_GPIO_AS_PINRESET) - if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || - ((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){ + if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || + ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} NRF_UICR->PSELRESET[0] = 21; @@ -149,16 +172,16 @@ void SystemInit(void) NVIC_SystemReset(); } #endif - - /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product + + /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product Specification to see which one). */ #if defined (ENABLE_SWO) CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos; NRF_P0->PIN_CNF[18] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); #endif - - /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product + + /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product Specification to see which ones). */ #if defined (ENABLE_TRACE) CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; @@ -174,90 +197,112 @@ void SystemInit(void) } +static bool errata_16(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + } + + return false; +} + static bool errata_31(void) { - if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) - { - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ return true; } - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ return true; } - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ return true; } } - + return false; } static bool errata_32(void) { - if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) - { - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ return true; } } - + return false; } static bool errata_36(void) { - if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) - { - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ return true; } - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ return true; } - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ return true; } } - + return false; } static bool errata_37(void) { - if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) - { - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ return true; } } - + return false; } -static bool errata_66(void) +static bool errata_57(void) { - if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)) - { - if ((((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50) && (((*(uint32_t *)0xF0000FEC) & 0x000000F0) == 0x0)) - { + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ return true; } } - + return false; } +static bool errata_66(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + + return false; +} +static bool errata_108(void) +{ + if ((((*(uint32_t *)0xF0000FE0) & 0x000000FF) == 0x6) && (((*(uint32_t *)0xF0000FE4) & 0x0000000F) == 0x0)){ + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x40){ + return true; + } + if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x50){ + return true; + } + } + return false; +} /*lint --flb "Leave library region" */ diff --git a/components/toolchain/system_nrf52.h b/components/toolchain/system_nrf52.h index f0464c1..9201e79 100644 --- a/components/toolchain/system_nrf52.h +++ b/components/toolchain/system_nrf52.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015, Nordic Semiconductor ASA +/* Copyright (c) 2012 ARM LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -11,9 +11,9 @@ * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - * * Neither the name of Nordic Semiconductor ASA nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. + * * 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 @@ -27,7 +27,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - + #ifndef SYSTEM_NRF52_H #define SYSTEM_NRF52_H diff --git a/components/toolchain/system_nrf52840.c b/components/toolchain/system_nrf52840.c new file mode 100644 index 0000000..de2aa1d --- /dev/null +++ b/components/toolchain/system_nrf52840.c @@ -0,0 +1,209 @@ +/* Copyright (c) 2012 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 THE COPYRIGHT HOLDER 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. + * + */ + +#include +#include +#include "nrf.h" +#include "system_nrf52840.h" + +/*lint ++flb "Enter library region" */ + +#define __SYSTEM_CLOCK_64M (64000000UL) + +static bool errata_36(void); +static bool errata_98(void); +static bool errata_103(void); +static bool errata_115(void); +static bool errata_120(void); + + +#if defined ( __CC_ARM ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; +#elif defined ( __ICCARM__ ) + __root uint32_t SystemCoreClock = __SYSTEM_CLOCK_64M; +#elif defined ( __GNUC__ ) + uint32_t SystemCoreClock __attribute__((used)) = __SYSTEM_CLOCK_64M; +#endif + +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = __SYSTEM_CLOCK_64M; +} + +void SystemInit(void) +{ + /* Workaround for Errata 36 "CLOCK: Some registers are not reset when expected" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_36()){ + NRF_CLOCK->EVENTS_DONE = 0; + NRF_CLOCK->EVENTS_CTTO = 0; + NRF_CLOCK->CTIV = 0; + } + + /* Workaround for Errata 98 "NFCT: Not able to communicate with the peer" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_98()){ + *(volatile uint32_t *)0x4000568Cul = 0x00038148ul; + } + + /* Workaround for Errata 103 "CCM: Wrong reset value of CCM MAXPACKETSIZE" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_103()){ + NRF_CCM->MAXPACKETSIZE = 0xFBul; + } + + /* Workaround for Errata 115 "RAM: RAM content cannot be trusted upon waking up from System ON Idle or System OFF mode" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_115()){ + *(volatile uint32_t *)0x40000EE4 = (*(volatile uint32_t *)0x40000EE4 & 0xFFFFFFF0) | (*(uint32_t *)0x10000258 & 0x0000000F); + } + + /* Workaround for Errata 120 "QSPI: Data read or written is corrupted" found at the Errata document + for your device located at https://infocenter.nordicsemi.com/ */ + if (errata_120()){ + *(volatile uint32_t *)0x40029640ul = 0x200ul; + } + + /* Enable the FPU if the compiler used floating point unit instructions. __FPU_USED is a MACRO defined by the + * compiler. Since the FPU consumes energy, remember to disable FPU use in the compiler if floating point unit + * operations are not used in your code. */ + #if (__FPU_USED == 1) + SCB->CPACR |= (3UL << 20) | (3UL << 22); + __DSB(); + __ISB(); + #endif + + /* Configure NFCT pins as GPIOs if NFCT is not to be used in your code. If CONFIG_NFCT_PINS_AS_GPIOS is not defined, + two GPIOs (see Product Specification to see which ones) will be reserved for NFC and will not be available as + normal GPIOs. */ + #if defined (CONFIG_NFCT_PINS_AS_GPIOS) + if ((NRF_UICR->NFCPINS & UICR_NFCPINS_PROTECT_Msk) == (UICR_NFCPINS_PROTECT_NFC << UICR_NFCPINS_PROTECT_Pos)){ + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->NFCPINS &= ~UICR_NFCPINS_PROTECT_Msk; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NVIC_SystemReset(); + } + #endif + + /* Configure GPIO pads as pPin Reset pin if Pin Reset capabilities desired. If CONFIG_GPIO_AS_PINRESET is not + defined, pin reset will not be available. One GPIO (see Product Specification to see which one) will then be + reserved for PinReset and not available as normal GPIO. */ + #if defined (CONFIG_GPIO_AS_PINRESET) + if (((NRF_UICR->PSELRESET[0] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos)) || + ((NRF_UICR->PSELRESET[1] & UICR_PSELRESET_CONNECT_Msk) != (UICR_PSELRESET_CONNECT_Connected << UICR_PSELRESET_CONNECT_Pos))){ + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->PSELRESET[0] = 18; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_UICR->PSELRESET[1] = 18; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos; + while (NRF_NVMC->READY == NVMC_READY_READY_Busy){} + NVIC_SystemReset(); + } + #endif + + /* Enable SWO trace functionality. If ENABLE_SWO is not defined, SWO pin will be used as GPIO (see Product + Specification to see which one). */ + #if defined (ENABLE_SWO) + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Serial << CLOCK_TRACECONFIG_TRACEMUX_Pos; + NRF_P1->PIN_CNF[0] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + #endif + + /* Enable Trace functionality. If ENABLE_TRACE is not defined, TRACE pins will be used as GPIOs (see Product + Specification to see which ones). */ + #if defined (ENABLE_TRACE) + CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; + NRF_CLOCK->TRACECONFIG |= CLOCK_TRACECONFIG_TRACEMUX_Parallel << CLOCK_TRACECONFIG_TRACEMUX_Pos; + NRF_P0->PIN_CNF[7] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P1->PIN_CNF[0] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[12] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P0->PIN_CNF[11] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + NRF_P1->PIN_CNF[9] = (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos); + #endif + + SystemCoreClockUpdate(); +} + + +static bool errata_36(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + + +static bool errata_98(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + + +static bool errata_103(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + + +static bool errata_115(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + + +static bool errata_120(void) +{ + if ((*(uint32_t *)0x10000130ul == 0x8ul) && (*(uint32_t *)0x10000134ul == 0x0ul)){ + return true; + } + + return false; +} + +/*lint --flb "Leave library region" */ diff --git a/components/toolchain/system_nrf52840.h b/components/toolchain/system_nrf52840.h new file mode 100644 index 0000000..e4fb74a --- /dev/null +++ b/components/toolchain/system_nrf52840.h @@ -0,0 +1,69 @@ +/* Copyright (c) 2012 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 THE COPYRIGHT HOLDER 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 SYSTEM_NRF52840_H +#define SYSTEM_NRF52840_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +/** + * Initialize the system + * + * @param none + * @return none + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +extern void SystemInit (void); + +/** + * Update SystemCoreClock variable + * + * @param none + * @return none + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +extern void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_NRF52840_H */ diff --git a/config/bsp.h b/config/bsp.h deleted file mode 100644 index 49eb0c5..0000000 --- a/config/bsp.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef EPD_BSP_H__ -#define EPD_BSP_H__ - -#define RX_PIN_NUMBER 0 -#define TX_PIN_NUMBER 6 -#define RTS_PIN_NUMBER 0 -#define CTS_PIN_NUMBER 0 - -#endif diff --git a/config/nrf_drv_config.h b/config/nrf_drv_config.h deleted file mode 100644 index 5ff228c..0000000 --- a/config/nrf_drv_config.h +++ /dev/null @@ -1,341 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_DRV_CONFIG_H -#define NRF_DRV_CONFIG_H - -/* CLOCK */ -#define CLOCK_CONFIG_XTAL_FREQ NRF_CLOCK_XTALFREQ_Default -#define CLOCK_CONFIG_LF_SRC NRF_CLOCK_LF_SRC_Xtal -#define CLOCK_CONFIG_LF_RC_CAL_INTERVAL RC_2000MS_CALIBRATION_INTERVAL -#define CLOCK_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -/* GPIOTE */ -#define GPIOTE_ENABLED 1 - -#if (GPIOTE_ENABLED == 1) -#define GPIOTE_CONFIG_USE_SWI_EGU false -#define GPIOTE_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 4 -#endif - -/* TIMER */ -#define TIMER0_ENABLED 0 - -#if (TIMER0_ENABLED == 1) -#define TIMER0_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz -#define TIMER0_CONFIG_MODE TIMER_MODE_MODE_Timer -#define TIMER0_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit -#define TIMER0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TIMER0_INSTANCE_INDEX 0 -#endif - -#define TIMER1_ENABLED 0 - -#if (TIMER1_ENABLED == 1) -#define TIMER1_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz -#define TIMER1_CONFIG_MODE TIMER_MODE_MODE_Timer -#define TIMER1_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TIMER1_INSTANCE_INDEX (TIMER0_ENABLED) -#endif - -#define TIMER2_ENABLED 0 - -#if (TIMER2_ENABLED == 1) -#define TIMER2_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz -#define TIMER2_CONFIG_MODE TIMER_MODE_MODE_Timer -#define TIMER2_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TIMER2_INSTANCE_INDEX (TIMER1_ENABLED+TIMER0_ENABLED) -#endif - -#define TIMER3_ENABLED 0 - -#if (TIMER3_ENABLED == 1) -#define TIMER3_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz -#define TIMER3_CONFIG_MODE TIMER_MODE_MODE_Timer -#define TIMER3_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER3_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TIMER3_INSTANCE_INDEX (TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED) -#endif - -#define TIMER4_ENABLED 0 - -#if (TIMER4_ENABLED == 1) -#define TIMER4_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz -#define TIMER4_CONFIG_MODE TIMER_MODE_MODE_Timer -#define TIMER4_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit -#define TIMER4_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TIMER4_INSTANCE_INDEX (TIMER3_ENABLED+TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED) -#endif - - -#define TIMER_COUNT (TIMER0_ENABLED + TIMER1_ENABLED + TIMER2_ENABLED + TIMER3_ENABLED + TIMER4_ENABLED) - -/* RTC */ -#define RTC0_ENABLED 0 - -#if (RTC0_ENABLED == 1) -#define RTC0_CONFIG_FREQUENCY 32678 -#define RTC0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#define RTC0_CONFIG_RELIABLE false - -#define RTC0_INSTANCE_INDEX 0 -#endif - -#define RTC1_ENABLED 0 - -#if (RTC1_ENABLED == 1) -#define RTC1_CONFIG_FREQUENCY 32768 -#define RTC1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#define RTC1_CONFIG_RELIABLE false - -#define RTC1_INSTANCE_INDEX (RTC0_ENABLED) -#endif - -#define RTC_COUNT (RTC0_ENABLED+RTC1_ENABLED) - -#define NRF_MAXIMUM_LATENCY_US 2000 - -/* RNG */ -#define RNG_ENABLED 0 - -#if (RNG_ENABLED == 1) -#define RNG_CONFIG_ERROR_CORRECTION true -#define RNG_CONFIG_POOL_SIZE 8 -#define RNG_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#endif - -/* SPI */ -#define SPI0_ENABLED 1 - -#if (SPI0_ENABLED == 1) -#define SPI0_USE_EASY_DMA 0 - -#define SPI0_CONFIG_SCK_PIN 2 -#define SPI0_CONFIG_MOSI_PIN 3 -#define SPI0_CONFIG_MISO_PIN 4 -#define SPI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPI0_INSTANCE_INDEX 0 -#endif - -#define SPI1_ENABLED 0 - -#if (SPI1_ENABLED == 1) -#define SPI1_USE_EASY_DMA 0 - -#define SPI1_CONFIG_SCK_PIN 2 -#define SPI1_CONFIG_MOSI_PIN 3 -#define SPI1_CONFIG_MISO_PIN 4 -#define SPI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPI1_INSTANCE_INDEX (SPI0_ENABLED) -#endif - -#define SPI2_ENABLED 0 - -#if (SPI2_ENABLED == 1) -#define SPI2_USE_EASY_DMA 0 - -#define SPI2_CONFIG_SCK_PIN 2 -#define SPI2_CONFIG_MOSI_PIN 3 -#define SPI2_CONFIG_MISO_PIN 4 -#define SPI2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPI2_INSTANCE_INDEX (SPI0_ENABLED + SPI1_ENABLED) -#endif - -#define SPI_COUNT (SPI0_ENABLED + SPI1_ENABLED + SPI2_ENABLED) - -/* SPIS */ -#define SPIS0_ENABLED 0 - -#if (SPIS0_ENABLED == 1) -#define SPIS0_CONFIG_SCK_PIN 2 -#define SPIS0_CONFIG_MOSI_PIN 3 -#define SPIS0_CONFIG_MISO_PIN 4 -#define SPIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPIS0_INSTANCE_INDEX 0 -#endif - -#define SPIS1_ENABLED 0 - -#if (SPIS1_ENABLED == 1) -#define SPIS1_CONFIG_SCK_PIN 2 -#define SPIS1_CONFIG_MOSI_PIN 3 -#define SPIS1_CONFIG_MISO_PIN 4 -#define SPIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPIS1_INSTANCE_INDEX SPIS0_ENABLED -#endif - -#define SPIS2_ENABLED 0 - -#if (SPIS2_ENABLED == 1) -#define SPIS2_CONFIG_SCK_PIN 2 -#define SPIS2_CONFIG_MOSI_PIN 3 -#define SPIS2_CONFIG_MISO_PIN 4 -#define SPIS2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define SPIS2_INSTANCE_INDEX (SPIS0_ENABLED + SPIS1_ENABLED) -#endif - -#define SPIS_COUNT (SPIS0_ENABLED + SPIS1_ENABLED + SPIS2_ENABLED) - -/* UART */ -#define UART0_ENABLED 1 - -#if (UART0_ENABLED == 1) -#define UART0_CONFIG_HWFC NRF_UART_HWFC_DISABLED -#define UART0_CONFIG_PARITY NRF_UART_PARITY_EXCLUDED -#define UART0_CONFIG_BAUDRATE NRF_UART_BAUDRATE_38400 -#define UART0_CONFIG_PSEL_TXD 0 -#define UART0_CONFIG_PSEL_RXD 0 -#define UART0_CONFIG_PSEL_CTS 0 -#define UART0_CONFIG_PSEL_RTS 0 -#define UART0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#ifdef NRF52 -#define UART0_CONFIG_USE_EASY_DMA false -//Compile time flag -#define UART_EASY_DMA_SUPPORT 1 -#define UART_LEGACY_SUPPORT 1 -#endif //NRF52 -#endif - -#define TWI0_ENABLED 0 - -#if (TWI0_ENABLED == 1) -#define TWI0_CONFIG_FREQUENCY NRF_TWI_FREQ_100K -#define TWI0_CONFIG_SCL 0 -#define TWI0_CONFIG_SDA 1 -#define TWI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TWI0_INSTANCE_INDEX 0 -#endif - -#define TWI1_ENABLED 1 - -#if (TWI1_ENABLED == 1) -#define TWI1_CONFIG_FREQUENCY NRF_TWI_FREQ_100K -#define TWI1_CONFIG_SCL 0 -#define TWI1_CONFIG_SDA 1 -#define TWI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - -#define TWI1_INSTANCE_INDEX (TWI0_ENABLED) -#endif - -#define TWI_COUNT (TWI0_ENABLED+TWI1_ENABLED) - -/* TWIS */ -#define TWIS0_ENABLED 0 - -#if (TWIS0_ENABLED == 1) - #define TWIS0_CONFIG_ADDR0 0 - #define TWIS0_CONFIG_ADDR1 0 /* 0: Disabled */ - #define TWIS0_CONFIG_SCL 0 - #define TWIS0_CONFIG_SDA 1 - #define TWIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - - #define TWIS0_INSTANCE_INDEX 0 -#endif - -#define TWIS1_ENABLED 0 - -#if (TWIS1_ENABLED == 1) - #define TWIS1_CONFIG_ADDR0 0 - #define TWIS1_CONFIG_ADDR1 0 /* 0: Disabled */ - #define TWIS1_CONFIG_SCL 0 - #define TWIS1_CONFIG_SDA 1 - #define TWIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW - - #define TWIS1_INSTANCE_INDEX (TWIS0_ENABLED) -#endif - -#define TWIS_COUNT (TWIS0_ENABLED + TWIS1_ENABLED) -/* For more documentation see nrf_drv_twis.h file */ -#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 -/* For more documentation see nrf_drv_twis.h file */ -#define TWIS_NO_SYNC_MODE 0 -/** - * @brief Definition for patching PAN problems - * - * Set this definition to nonzero value to patch anomalies - * from MPW3 - first lunch microcontroller. - * - * Concerns: - * - PAN-29: TWIS: incorrect bits in ERRORSRC - * - PAN-30: TWIS: STOP task does not work as expected - */ -#define NRF_TWIS_PATCH_FOR_MPW3 1 - - -/* QDEC */ -#define QDEC_ENABLED 0 - -#if (QDEC_ENABLED == 1) -#define QDEC_CONFIG_REPORTPER NRF_QDEC_REPORTPER_10 -#define QDEC_CONFIG_SAMPLEPER NRF_QDEC_SAMPLEPER_16384us -#define QDEC_CONFIG_PIO_A 1 -#define QDEC_CONFIG_PIO_B 2 -#define QDEC_CONFIG_PIO_LED 3 -#define QDEC_CONFIG_LEDPRE 511 -#define QDEC_CONFIG_LEDPOL NRF_QDEC_LEPOL_ACTIVE_HIGH -#define QDEC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#define QDEC_CONFIG_DBFEN false -#define QDEC_CONFIG_SAMPLE_INTEN false -#endif - -/* SAADC */ -#define SAADC_ENABLED 0 - -#if (SAADC_ENABLED == 1) -#define SAADC_CONFIG_RESOLUTION NRF_SAADC_RESOLUTION_10BIT -#define SAADC_CONFIG_OVERSAMPLE NRF_SAADC_OVERSAMPLE_DISABLED -#define SAADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#endif - -/* LPCOMP */ -#define LPCOMP_ENABLED 0 - -#if (LPCOMP_ENABLED == 1) -#define LPCOMP_CONFIG_REFERENCE NRF_LPCOMP_REF_SUPPLY_4_8 -#define LPCOMP_CONFIG_DETECTION NRF_LPCOMP_DETECT_DOWN -#define LPCOMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW -#define LPCOMP_CONFIG_INPUT NRF_LPCOMP_INPUT_0 -#endif - -/* WDT */ -#define WDT_ENABLED 0 - -#if (WDT_ENABLED == 1) -#define WDT_CONFIG_BEHAVIOUR NRF_WDT_BEHAVIOUR_RUN_SLEEP -#define WDT_CONFIG_RELOAD_VALUE 2000 -#define WDT_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH -#endif - -/* SWI EGU */ -#ifdef NRF52 - #define EGU_ENABLED 0 -#endif - - -#include "nrf_drv_config_validation.h" - -#endif // NRF_DRV_CONFIG_H diff --git a/config/pstorage_platform.h b/config/pstorage_platform.h deleted file mode 100644 index 910b99b..0000000 --- a/config/pstorage_platform.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - */ - - /** @cond To make doxygen skip this file */ - -/** @file - * This header contains defines with respect persistent storage that are specific to - * persistent storage implementation and application use case. - */ -#ifndef PSTORAGE_PL_H__ -#define PSTORAGE_PL_H__ - -#include -#include "nrf.h" - -static __INLINE uint16_t pstorage_flash_page_size() -{ - return (uint16_t)NRF_FICR->CODEPAGESIZE; -} - -#define PSTORAGE_FLASH_PAGE_SIZE pstorage_flash_page_size() /**< Size of one flash page. */ -#define PSTORAGE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */ - -#ifdef NRF51 -#define BOOTLOADER_ADDRESS (NRF_UICR->BOOTLOADERADDR) -#elif defined NRF52 -#define BOOTLOADER_ADDRESS (PSTORAGE_FLASH_EMPTY_MASK) -#endif - -static __INLINE uint32_t pstorage_flash_page_end() -{ - uint32_t bootloader_addr = BOOTLOADER_ADDRESS; - - return ((bootloader_addr != PSTORAGE_FLASH_EMPTY_MASK) ? - (bootloader_addr/ PSTORAGE_FLASH_PAGE_SIZE) : NRF_FICR->CODESIZE); -} - -#define PSTORAGE_FLASH_PAGE_END pstorage_flash_page_end() - -#define PSTORAGE_NUM_OF_PAGES 1 /**< Number of flash pages allocated for the pstorage module excluding the swap page, configurable based on system requirements. */ -#define PSTORAGE_MIN_BLOCK_SIZE 0x0010 /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation is not have this value to be at least size of word. */ - -#define PSTORAGE_DATA_START_ADDR ((PSTORAGE_FLASH_PAGE_END - PSTORAGE_NUM_OF_PAGES - 1) \ - * PSTORAGE_FLASH_PAGE_SIZE) /**< Start address for persistent data, configurable according to system requirements. */ -#define PSTORAGE_DATA_END_ADDR ((PSTORAGE_FLASH_PAGE_END - 1) * PSTORAGE_FLASH_PAGE_SIZE) /**< End address for persistent data, configurable according to system requirements. */ -#define PSTORAGE_SWAP_ADDR PSTORAGE_DATA_END_ADDR /**< Top-most page is used as swap area for clear and update. */ - -#define PSTORAGE_MAX_BLOCK_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. And should be greater than or equal to the minimum size. */ -#define PSTORAGE_CMD_QUEUE_SIZE 10 /**< Maximum number of flash access commands that can be maintained by the module for all applications. Configurable. */ - - -/** Abstracts persistently memory block identifier. */ -typedef uint32_t pstorage_block_t; - -typedef struct -{ - uint32_t module_id; /**< Module ID.*/ - pstorage_block_t block_id; /**< Block ID.*/ -} pstorage_handle_t; - -typedef uint16_t pstorage_size_t; /** Size of length and offset fields. */ - -/**@brief Handles Flash Access Result Events. To be called in the system event dispatcher of the application. */ -void pstorage_sys_event_handler (uint32_t sys_evt); - -#endif // PSTORAGE_PL_H__ - -/** @} */ -/** @endcond */ diff --git a/config/sdk_config.h b/config/sdk_config.h new file mode 100644 index 0000000..ae76909 --- /dev/null +++ b/config/sdk_config.h @@ -0,0 +1,3738 @@ + + +#ifndef SDK_CONFIG_H +#define SDK_CONFIG_H +// <<< Use Configuration Wizard in Context Menu >>>\n +#ifdef USE_APP_CONFIG +#include "app_config.h" +#endif +// nRF_BLE + +//========================================================== +// BLE_ADVERTISING_ENABLED - ble_advertising - Advertising module + + +#ifndef BLE_ADVERTISING_ENABLED +#define BLE_ADVERTISING_ENABLED 1 +#endif + +// BLE_DTM_ENABLED - ble_dtm - Module for testing RF/PHY using DTM commands + + +#ifndef BLE_DTM_ENABLED +#define BLE_DTM_ENABLED 0 +#endif + +// BLE_RACP_ENABLED - ble_racp - Record Access Control Point library + + +#ifndef BLE_RACP_ENABLED +#define BLE_RACP_ENABLED 0 +#endif + +// NRF_BLE_QWR_ENABLED - nrf_ble_qwr - Queued writes support module (prepare/execute write) + + +#ifndef NRF_BLE_QWR_ENABLED +#define NRF_BLE_QWR_ENABLED 0 +#endif + +// PEER_MANAGER_ENABLED - peer_manager - Peer Manager + + +#ifndef PEER_MANAGER_ENABLED +#define PEER_MANAGER_ENABLED 0 +#endif + +// +//========================================================== + +// nRF_BLE_Services + +//========================================================== +// BLE_ANCS_C_ENABLED - ble_ancs_c - Apple Notification Service Client + + +#ifndef BLE_ANCS_C_ENABLED +#define BLE_ANCS_C_ENABLED 0 +#endif + +// BLE_ANS_C_ENABLED - ble_ans_c - Alert Notification Service Client + + +#ifndef BLE_ANS_C_ENABLED +#define BLE_ANS_C_ENABLED 0 +#endif + +// BLE_BAS_C_ENABLED - ble_bas_c - Battery Service Client + + +#ifndef BLE_BAS_C_ENABLED +#define BLE_BAS_C_ENABLED 0 +#endif + +// BLE_BAS_ENABLED - ble_bas - Battery Service + + +#ifndef BLE_BAS_ENABLED +#define BLE_BAS_ENABLED 0 +#endif + +// BLE_CSCS_ENABLED - ble_cscs - Cycling Speed and Cadence Service + + +#ifndef BLE_CSCS_ENABLED +#define BLE_CSCS_ENABLED 0 +#endif + +// BLE_CTS_C_ENABLED - ble_cts_c - Current Time Service Client + + +#ifndef BLE_CTS_C_ENABLED +#define BLE_CTS_C_ENABLED 0 +#endif + +// BLE_DIS_ENABLED - ble_dis - Device Information Service + + +#ifndef BLE_DIS_ENABLED +#define BLE_DIS_ENABLED 0 +#endif + +// BLE_GLS_ENABLED - ble_gls - Glucose Service + + +#ifndef BLE_GLS_ENABLED +#define BLE_GLS_ENABLED 0 +#endif + +// BLE_HIDS_ENABLED - ble_hids - Human Interface Device Service + + +#ifndef BLE_HIDS_ENABLED +#define BLE_HIDS_ENABLED 0 +#endif + +// BLE_HRS_C_ENABLED - ble_hrs_c - Heart Rate Service Client +//========================================================== +#ifndef BLE_HRS_C_ENABLED +#define BLE_HRS_C_ENABLED 0 +#endif +#if BLE_HRS_C_ENABLED +// BLE_HRS_C_RR_INTERVALS_MAX_CNT - Maximum number of RR_INTERVALS per notification to be decoded +#ifndef BLE_HRS_C_RR_INTERVALS_MAX_CNT +#define BLE_HRS_C_RR_INTERVALS_MAX_CNT 30 +#endif + +#endif //BLE_HRS_C_ENABLED +// + +// BLE_HRS_ENABLED - ble_hrs - Heart Rate Service + + +#ifndef BLE_HRS_ENABLED +#define BLE_HRS_ENABLED 0 +#endif + +// BLE_HTS_ENABLED - ble_hts - Health Thermometer Service + + +#ifndef BLE_HTS_ENABLED +#define BLE_HTS_ENABLED 0 +#endif + +// BLE_IAS_C_ENABLED - ble_ias_c - Immediate Alert Service Client + + +#ifndef BLE_IAS_C_ENABLED +#define BLE_IAS_C_ENABLED 0 +#endif + +// BLE_IAS_ENABLED - ble_ias - Immediate Alert Service + + +#ifndef BLE_IAS_ENABLED +#define BLE_IAS_ENABLED 0 +#endif + +// BLE_LBS_C_ENABLED - ble_lbs_c - Nordic LED Button Service Client + + +#ifndef BLE_LBS_C_ENABLED +#define BLE_LBS_C_ENABLED 0 +#endif + +// BLE_LBS_ENABLED - ble_lbs - LED Button Service + + +#ifndef BLE_LBS_ENABLED +#define BLE_LBS_ENABLED 0 +#endif + +// BLE_LLS_ENABLED - ble_lls - Link Loss Service + + +#ifndef BLE_LLS_ENABLED +#define BLE_LLS_ENABLED 0 +#endif + +// BLE_NUS_C_ENABLED - ble_nus_c - Nordic UART Central Service + + +#ifndef BLE_NUS_C_ENABLED +#define BLE_NUS_C_ENABLED 0 +#endif + +// BLE_NUS_ENABLED - ble_nus - Nordic UART Service + + +#ifndef BLE_NUS_ENABLED +#define BLE_NUS_ENABLED 0 +#endif + +// BLE_RSCS_C_ENABLED - ble_rscs_c - Running Speed and Cadence Client + + +#ifndef BLE_RSCS_C_ENABLED +#define BLE_RSCS_C_ENABLED 0 +#endif + +// BLE_RSCS_ENABLED - ble_rscs - Running Speed and Cadence Service + + +#ifndef BLE_RSCS_ENABLED +#define BLE_RSCS_ENABLED 0 +#endif + +// BLE_TPS_ENABLED - ble_tps - TX Power Service + + +#ifndef BLE_TPS_ENABLED +#define BLE_TPS_ENABLED 0 +#endif + +// +//========================================================== + +// nRF_Drivers + +//========================================================== +// ADC_ENABLED - nrf_drv_adc - Driver for ADC peripheral (nRF51) +//========================================================== +#ifndef ADC_ENABLED +#define ADC_ENABLED 0 +#endif +#if ADC_ENABLED +// ADC_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef ADC_CONFIG_IRQ_PRIORITY +#define ADC_CONFIG_IRQ_PRIORITY 3 +#endif + +// ADC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef ADC_CONFIG_LOG_ENABLED +#define ADC_CONFIG_LOG_ENABLED 0 +#endif +#if ADC_CONFIG_LOG_ENABLED +// ADC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef ADC_CONFIG_LOG_LEVEL +#define ADC_CONFIG_LOG_LEVEL 3 +#endif + +// ADC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef ADC_CONFIG_INFO_COLOR +#define ADC_CONFIG_INFO_COLOR 0 +#endif + +// ADC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef ADC_CONFIG_DEBUG_COLOR +#define ADC_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //ADC_CONFIG_LOG_ENABLED +// + +#endif //ADC_ENABLED +// + +// APP_USBD_ENABLED - app_usbd - USB Device library +//========================================================== +#ifndef APP_USBD_ENABLED +#define APP_USBD_ENABLED 0 +#endif +#if APP_USBD_ENABLED +// APP_USBD_VID - Vendor ID <0x0000-0xFFFF> + + +// Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/ + +#ifndef APP_USBD_VID +#define APP_USBD_VID 0 +#endif + +// APP_USBD_PID - Product ID <0x0000-0xFFFF> + + +// Selected Product ID + +#ifndef APP_USBD_PID +#define APP_USBD_PID 0 +#endif + +// APP_USBD_DEVICE_VER_MAJOR - Device version, major part <0-99> + + +// Device version, will be converted automatically to BCD notation. Use just decimal values. + +#ifndef APP_USBD_DEVICE_VER_MAJOR +#define APP_USBD_DEVICE_VER_MAJOR 1 +#endif + +// APP_USBD_DEVICE_VER_MINOR - Device version, minor part <0-99> + + +// Device version, will be converted automatically to BCD notation. Use just decimal values. + +#ifndef APP_USBD_DEVICE_VER_MINOR +#define APP_USBD_DEVICE_VER_MINOR 0 +#endif + +#endif //APP_USBD_ENABLED +// + +// CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver +//========================================================== +#ifndef CLOCK_ENABLED +#define CLOCK_ENABLED 1 +#endif +#if CLOCK_ENABLED +// CLOCK_CONFIG_XTAL_FREQ - HF XTAL Frequency + +// <0=> Default (64 MHz) +// <255=> Default (16 MHz) +// <0=> 32 MHz + +#ifndef CLOCK_CONFIG_XTAL_FREQ +#define CLOCK_CONFIG_XTAL_FREQ 255 +#endif + +// CLOCK_CONFIG_LF_SRC - LF Clock Source + +// <0=> RC +// <1=> XTAL +// <2=> Synth + +#ifndef CLOCK_CONFIG_LF_SRC +#define CLOCK_CONFIG_LF_SRC 1 +#endif + +// CLOCK_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef CLOCK_CONFIG_IRQ_PRIORITY +#define CLOCK_CONFIG_IRQ_PRIORITY 3 +#endif + +// CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef CLOCK_CONFIG_LOG_ENABLED +#define CLOCK_CONFIG_LOG_ENABLED 0 +#endif +#if CLOCK_CONFIG_LOG_ENABLED +// CLOCK_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef CLOCK_CONFIG_LOG_LEVEL +#define CLOCK_CONFIG_LOG_LEVEL 3 +#endif + +// CLOCK_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef CLOCK_CONFIG_INFO_COLOR +#define CLOCK_CONFIG_INFO_COLOR 0 +#endif + +// CLOCK_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef CLOCK_CONFIG_DEBUG_COLOR +#define CLOCK_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //CLOCK_CONFIG_LOG_ENABLED +// + +#endif //CLOCK_ENABLED +// + +// COMP_ENABLED - nrf_drv_comp - COMP peripheral driver +//========================================================== +#ifndef COMP_ENABLED +#define COMP_ENABLED 0 +#endif +#if COMP_ENABLED +// COMP_CONFIG_REF - Reference voltage + +// <0=> Internal 1.2V +// <1=> Internal 1.8V +// <2=> Internal 2.4V +// <4=> VDD +// <7=> ARef + +#ifndef COMP_CONFIG_REF +#define COMP_CONFIG_REF 1 +#endif + +// COMP_CONFIG_MAIN_MODE - Main mode + +// <0=> Single ended +// <1=> Differential + +#ifndef COMP_CONFIG_MAIN_MODE +#define COMP_CONFIG_MAIN_MODE 0 +#endif + +// COMP_CONFIG_SPEED_MODE - Speed mode + +// <0=> Low power +// <1=> Normal +// <2=> High speed + +#ifndef COMP_CONFIG_SPEED_MODE +#define COMP_CONFIG_SPEED_MODE 2 +#endif + +// COMP_CONFIG_HYST - Hystheresis + +// <0=> No +// <1=> 50mV + +#ifndef COMP_CONFIG_HYST +#define COMP_CONFIG_HYST 0 +#endif + +// COMP_CONFIG_ISOURCE - Current Source + +// <0=> Off +// <1=> 2.5 uA +// <2=> 5 uA +// <3=> 10 uA + +#ifndef COMP_CONFIG_ISOURCE +#define COMP_CONFIG_ISOURCE 0 +#endif + +// COMP_CONFIG_INPUT - Analog input + +// <0=> 0 +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef COMP_CONFIG_INPUT +#define COMP_CONFIG_INPUT 0 +#endif + +// COMP_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef COMP_CONFIG_IRQ_PRIORITY +#define COMP_CONFIG_IRQ_PRIORITY 3 +#endif + +// COMP_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef COMP_CONFIG_LOG_ENABLED +#define COMP_CONFIG_LOG_ENABLED 0 +#endif +#if COMP_CONFIG_LOG_ENABLED +// COMP_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef COMP_CONFIG_LOG_LEVEL +#define COMP_CONFIG_LOG_LEVEL 3 +#endif + +// COMP_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMP_CONFIG_INFO_COLOR +#define COMP_CONFIG_INFO_COLOR 0 +#endif + +// COMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMP_CONFIG_DEBUG_COLOR +#define COMP_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //COMP_CONFIG_LOG_ENABLED +// + +#endif //COMP_ENABLED +// + +// EGU_ENABLED - nrf_drv_swi - SWI(EGU) peripheral driver +//========================================================== +#ifndef EGU_ENABLED +#define EGU_ENABLED 0 +#endif +#if EGU_ENABLED +// SWI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SWI_CONFIG_LOG_ENABLED +#define SWI_CONFIG_LOG_ENABLED 0 +#endif +#if SWI_CONFIG_LOG_ENABLED +// SWI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SWI_CONFIG_LOG_LEVEL +#define SWI_CONFIG_LOG_LEVEL 3 +#endif + +// SWI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SWI_CONFIG_INFO_COLOR +#define SWI_CONFIG_INFO_COLOR 0 +#endif + +// SWI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SWI_CONFIG_DEBUG_COLOR +#define SWI_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //SWI_CONFIG_LOG_ENABLED +// + +#endif //EGU_ENABLED +// + +// GPIOTE_ENABLED - nrf_drv_gpiote - GPIOTE peripheral driver +//========================================================== +#ifndef GPIOTE_ENABLED +#define GPIOTE_ENABLED 0 +#endif +#if GPIOTE_ENABLED +// GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins +#ifndef GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS +#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 4 +#endif + +// GPIOTE_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef GPIOTE_CONFIG_IRQ_PRIORITY +#define GPIOTE_CONFIG_IRQ_PRIORITY 3 +#endif + +// GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef GPIOTE_CONFIG_LOG_ENABLED +#define GPIOTE_CONFIG_LOG_ENABLED 0 +#endif +#if GPIOTE_CONFIG_LOG_ENABLED +// GPIOTE_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef GPIOTE_CONFIG_LOG_LEVEL +#define GPIOTE_CONFIG_LOG_LEVEL 3 +#endif + +// GPIOTE_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef GPIOTE_CONFIG_INFO_COLOR +#define GPIOTE_CONFIG_INFO_COLOR 0 +#endif + +// GPIOTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef GPIOTE_CONFIG_DEBUG_COLOR +#define GPIOTE_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //GPIOTE_CONFIG_LOG_ENABLED +// + +#endif //GPIOTE_ENABLED +// + +// I2S_ENABLED - nrf_drv_i2s - I2S peripheral driver +//========================================================== +#ifndef I2S_ENABLED +#define I2S_ENABLED 0 +#endif +#if I2S_ENABLED +// I2S_CONFIG_SCK_PIN - SCK pin <0-31> + + +#ifndef I2S_CONFIG_SCK_PIN +#define I2S_CONFIG_SCK_PIN 31 +#endif + +// I2S_CONFIG_LRCK_PIN - LRCK pin <1-31> + + +#ifndef I2S_CONFIG_LRCK_PIN +#define I2S_CONFIG_LRCK_PIN 30 +#endif + +// I2S_CONFIG_MCK_PIN - MCK pin +#ifndef I2S_CONFIG_MCK_PIN +#define I2S_CONFIG_MCK_PIN 255 +#endif + +// I2S_CONFIG_SDOUT_PIN - SDOUT pin <0-31> + + +#ifndef I2S_CONFIG_SDOUT_PIN +#define I2S_CONFIG_SDOUT_PIN 29 +#endif + +// I2S_CONFIG_SDIN_PIN - SDIN pin <0-31> + + +#ifndef I2S_CONFIG_SDIN_PIN +#define I2S_CONFIG_SDIN_PIN 28 +#endif + +// I2S_CONFIG_MASTER - Mode + +// <0=> Master +// <1=> Slave + +#ifndef I2S_CONFIG_MASTER +#define I2S_CONFIG_MASTER 0 +#endif + +// I2S_CONFIG_FORMAT - Format + +// <0=> I2S +// <1=> Aligned + +#ifndef I2S_CONFIG_FORMAT +#define I2S_CONFIG_FORMAT 0 +#endif + +// I2S_CONFIG_ALIGN - Alignment + +// <0=> Left +// <1=> Right + +#ifndef I2S_CONFIG_ALIGN +#define I2S_CONFIG_ALIGN 0 +#endif + +// I2S_CONFIG_SWIDTH - Sample width (bits) + +// <0=> 8 +// <1=> 16 +// <2=> 24 + +#ifndef I2S_CONFIG_SWIDTH +#define I2S_CONFIG_SWIDTH 1 +#endif + +// I2S_CONFIG_CHANNELS - Channels + +// <0=> Stereo +// <1=> Left +// <2=> Right + +#ifndef I2S_CONFIG_CHANNELS +#define I2S_CONFIG_CHANNELS 1 +#endif + +// I2S_CONFIG_MCK_SETUP - MCK behavior + +// <0=> Disabled +// <2147483648=> 32MHz/2 +// <1342177280=> 32MHz/3 +// <1073741824=> 32MHz/4 +// <805306368=> 32MHz/5 +// <671088640=> 32MHz/6 +// <536870912=> 32MHz/8 +// <402653184=> 32MHz/10 +// <369098752=> 32MHz/11 +// <285212672=> 32MHz/15 +// <268435456=> 32MHz/16 +// <201326592=> 32MHz/21 +// <184549376=> 32MHz/23 +// <142606336=> 32MHz/30 +// <138412032=> 32MHz/31 +// <134217728=> 32MHz/32 +// <100663296=> 32MHz/42 +// <68157440=> 32MHz/63 +// <34340864=> 32MHz/125 + +#ifndef I2S_CONFIG_MCK_SETUP +#define I2S_CONFIG_MCK_SETUP 536870912 +#endif + +// I2S_CONFIG_RATIO - MCK/LRCK ratio + +// <0=> 32x +// <1=> 48x +// <2=> 64x +// <3=> 96x +// <4=> 128x +// <5=> 192x +// <6=> 256x +// <7=> 384x +// <8=> 512x + +#ifndef I2S_CONFIG_RATIO +#define I2S_CONFIG_RATIO 2000 +#endif + +// I2S_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef I2S_CONFIG_IRQ_PRIORITY +#define I2S_CONFIG_IRQ_PRIORITY 3 +#endif + +// I2S_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef I2S_CONFIG_LOG_ENABLED +#define I2S_CONFIG_LOG_ENABLED 0 +#endif +#if I2S_CONFIG_LOG_ENABLED +// I2S_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef I2S_CONFIG_LOG_LEVEL +#define I2S_CONFIG_LOG_LEVEL 3 +#endif + +// I2S_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef I2S_CONFIG_INFO_COLOR +#define I2S_CONFIG_INFO_COLOR 0 +#endif + +// I2S_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef I2S_CONFIG_DEBUG_COLOR +#define I2S_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //I2S_CONFIG_LOG_ENABLED +// + +#endif //I2S_ENABLED +// + +// LPCOMP_ENABLED - nrf_drv_lpcomp - LPCOMP peripheral driver +//========================================================== +#ifndef LPCOMP_ENABLED +#define LPCOMP_ENABLED 0 +#endif +#if LPCOMP_ENABLED +// LPCOMP_CONFIG_REFERENCE - Reference voltage + +// <0=> Supply 1/8 +// <1=> Supply 2/8 +// <2=> Supply 3/8 +// <3=> Supply 4/8 +// <4=> Supply 5/8 +// <5=> Supply 6/8 +// <6=> Supply 7/8 +// <8=> Supply 1/16 (nRF52) +// <9=> Supply 3/16 (nRF52) +// <10=> Supply 5/16 (nRF52) +// <11=> Supply 7/16 (nRF52) +// <12=> Supply 9/16 (nRF52) +// <13=> Supply 11/16 (nRF52) +// <14=> Supply 13/16 (nRF52) +// <15=> Supply 15/16 (nRF52) +// <7=> External Ref 0 +// <65543=> External Ref 1 + +#ifndef LPCOMP_CONFIG_REFERENCE +#define LPCOMP_CONFIG_REFERENCE 3 +#endif + +// LPCOMP_CONFIG_DETECTION - Detection + +// <0=> Crossing +// <1=> Up +// <2=> Down + +#ifndef LPCOMP_CONFIG_DETECTION +#define LPCOMP_CONFIG_DETECTION 2 +#endif + +// LPCOMP_CONFIG_INPUT - Analog input + +// <0=> 0 +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef LPCOMP_CONFIG_INPUT +#define LPCOMP_CONFIG_INPUT 0 +#endif + +// LPCOMP_CONFIG_HYST - Hysteresis + + +#ifndef LPCOMP_CONFIG_HYST +#define LPCOMP_CONFIG_HYST 0 +#endif + +// LPCOMP_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef LPCOMP_CONFIG_IRQ_PRIORITY +#define LPCOMP_CONFIG_IRQ_PRIORITY 3 +#endif + +// LPCOMP_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef LPCOMP_CONFIG_LOG_ENABLED +#define LPCOMP_CONFIG_LOG_ENABLED 0 +#endif +#if LPCOMP_CONFIG_LOG_ENABLED +// LPCOMP_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef LPCOMP_CONFIG_LOG_LEVEL +#define LPCOMP_CONFIG_LOG_LEVEL 3 +#endif + +// LPCOMP_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef LPCOMP_CONFIG_INFO_COLOR +#define LPCOMP_CONFIG_INFO_COLOR 0 +#endif + +// LPCOMP_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef LPCOMP_CONFIG_DEBUG_COLOR +#define LPCOMP_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //LPCOMP_CONFIG_LOG_ENABLED +// + +#endif //LPCOMP_ENABLED +// + +// PDM_ENABLED - nrf_drv_pdm - PDM peripheral driver +//========================================================== +#ifndef PDM_ENABLED +#define PDM_ENABLED 0 +#endif +#if PDM_ENABLED +// PDM_CONFIG_MODE - Mode + +// <0=> Stereo +// <1=> Mono + +#ifndef PDM_CONFIG_MODE +#define PDM_CONFIG_MODE 1 +#endif + +// PDM_CONFIG_EDGE - Edge + +// <0=> Left falling +// <1=> Left rising + +#ifndef PDM_CONFIG_EDGE +#define PDM_CONFIG_EDGE 0 +#endif + +// PDM_CONFIG_CLOCK_FREQ - Clock frequency + +// <134217728=> 1000k +// <138412032=> 1032k (default) +// <142606336=> 1067k + +#ifndef PDM_CONFIG_CLOCK_FREQ +#define PDM_CONFIG_CLOCK_FREQ 138412032 +#endif + +// PDM_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef PDM_CONFIG_IRQ_PRIORITY +#define PDM_CONFIG_IRQ_PRIORITY 3 +#endif + +// PDM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PDM_CONFIG_LOG_ENABLED +#define PDM_CONFIG_LOG_ENABLED 0 +#endif +#if PDM_CONFIG_LOG_ENABLED +// PDM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PDM_CONFIG_LOG_LEVEL +#define PDM_CONFIG_LOG_LEVEL 3 +#endif + +// PDM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PDM_CONFIG_INFO_COLOR +#define PDM_CONFIG_INFO_COLOR 0 +#endif + +// PDM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PDM_CONFIG_DEBUG_COLOR +#define PDM_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //PDM_CONFIG_LOG_ENABLED +// + +#endif //PDM_ENABLED +// + +// PERIPHERAL_RESOURCE_SHARING_ENABLED - nrf_drv_common - Peripheral drivers common module +//========================================================== +#ifndef PERIPHERAL_RESOURCE_SHARING_ENABLED +#define PERIPHERAL_RESOURCE_SHARING_ENABLED 0 +#endif +#if PERIPHERAL_RESOURCE_SHARING_ENABLED +// COMMON_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef COMMON_CONFIG_LOG_ENABLED +#define COMMON_CONFIG_LOG_ENABLED 0 +#endif +#if COMMON_CONFIG_LOG_ENABLED +// COMMON_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef COMMON_CONFIG_LOG_LEVEL +#define COMMON_CONFIG_LOG_LEVEL 3 +#endif + +// COMMON_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMMON_CONFIG_INFO_COLOR +#define COMMON_CONFIG_INFO_COLOR 0 +#endif + +// COMMON_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef COMMON_CONFIG_DEBUG_COLOR +#define COMMON_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //COMMON_CONFIG_LOG_ENABLED +// + +#endif //PERIPHERAL_RESOURCE_SHARING_ENABLED +// + +// POWER_ENABLED - nrf_drv_power - POWER peripheral driver +//========================================================== +#ifndef POWER_ENABLED +#define POWER_ENABLED 0 +#endif +#if POWER_ENABLED +// POWER_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef POWER_CONFIG_IRQ_PRIORITY +#define POWER_CONFIG_IRQ_PRIORITY 3 +#endif + +// POWER_CONFIG_DEFAULT_DCDCEN - The default configuration of main DCDC regulator + + +// This settings means only that components for DCDC regulator are installed and it can be enabled. + +#ifndef POWER_CONFIG_DEFAULT_DCDCEN +#define POWER_CONFIG_DEFAULT_DCDCEN 0 +#endif + +// POWER_CONFIG_DEFAULT_DCDCENHV - The default configuration of High Voltage DCDC regulator + + +// This settings means only that components for DCDC regulator are installed and it can be enabled. + +#ifndef POWER_CONFIG_DEFAULT_DCDCENHV +#define POWER_CONFIG_DEFAULT_DCDCENHV 0 +#endif + +#endif //POWER_ENABLED +// + +// PPI_ENABLED - nrf_drv_ppi - PPI peripheral driver +//========================================================== +#ifndef PPI_ENABLED +#define PPI_ENABLED 0 +#endif +#if PPI_ENABLED +// PPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PPI_CONFIG_LOG_ENABLED +#define PPI_CONFIG_LOG_ENABLED 0 +#endif +#if PPI_CONFIG_LOG_ENABLED +// PPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PPI_CONFIG_LOG_LEVEL +#define PPI_CONFIG_LOG_LEVEL 3 +#endif + +// PPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PPI_CONFIG_INFO_COLOR +#define PPI_CONFIG_INFO_COLOR 0 +#endif + +// PPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PPI_CONFIG_DEBUG_COLOR +#define PPI_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //PPI_CONFIG_LOG_ENABLED +// + +#endif //PPI_ENABLED +// + +// PWM_ENABLED - nrf_drv_pwm - PWM peripheral driver +//========================================================== +#ifndef PWM_ENABLED +#define PWM_ENABLED 0 +#endif +#if PWM_ENABLED +// PWM_DEFAULT_CONFIG_OUT0_PIN - Out0 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT0_PIN +#define PWM_DEFAULT_CONFIG_OUT0_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_OUT1_PIN - Out1 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT1_PIN +#define PWM_DEFAULT_CONFIG_OUT1_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_OUT2_PIN - Out2 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT2_PIN +#define PWM_DEFAULT_CONFIG_OUT2_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_OUT3_PIN - Out3 pin <0-31> + + +#ifndef PWM_DEFAULT_CONFIG_OUT3_PIN +#define PWM_DEFAULT_CONFIG_OUT3_PIN 31 +#endif + +// PWM_DEFAULT_CONFIG_BASE_CLOCK - Base clock + +// <0=> 16 MHz +// <1=> 8 MHz +// <2=> 4 MHz +// <3=> 2 MHz +// <4=> 1 MHz +// <5=> 500 kHz +// <6=> 250 kHz +// <7=> 125 MHz + +#ifndef PWM_DEFAULT_CONFIG_BASE_CLOCK +#define PWM_DEFAULT_CONFIG_BASE_CLOCK 4 +#endif + +// PWM_DEFAULT_CONFIG_COUNT_MODE - Count mode + +// <0=> Up +// <1=> Up and Down + +#ifndef PWM_DEFAULT_CONFIG_COUNT_MODE +#define PWM_DEFAULT_CONFIG_COUNT_MODE 0 +#endif + +// PWM_DEFAULT_CONFIG_TOP_VALUE - Top value +#ifndef PWM_DEFAULT_CONFIG_TOP_VALUE +#define PWM_DEFAULT_CONFIG_TOP_VALUE 1000 +#endif + +// PWM_DEFAULT_CONFIG_LOAD_MODE - Load mode + +// <0=> Common +// <1=> Grouped +// <2=> Individual +// <3=> Waveform + +#ifndef PWM_DEFAULT_CONFIG_LOAD_MODE +#define PWM_DEFAULT_CONFIG_LOAD_MODE 0 +#endif + +// PWM_DEFAULT_CONFIG_STEP_MODE - Step mode + +// <0=> Auto +// <1=> Triggered + +#ifndef PWM_DEFAULT_CONFIG_STEP_MODE +#define PWM_DEFAULT_CONFIG_STEP_MODE 0 +#endif + +// PWM_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 +// <4=> 4 +// <5=> 5 +// <6=> 6 +// <7=> 7 + +#ifndef PWM_DEFAULT_CONFIG_IRQ_PRIORITY +#define PWM_DEFAULT_CONFIG_IRQ_PRIORITY 7 +#endif + +// PWM0_ENABLED - Enable PWM0 instance + + +#ifndef PWM0_ENABLED +#define PWM0_ENABLED 0 +#endif + +// PWM1_ENABLED - Enable PWM1 instance + + +#ifndef PWM1_ENABLED +#define PWM1_ENABLED 0 +#endif + +// PWM2_ENABLED - Enable PWM2 instance + + +#ifndef PWM2_ENABLED +#define PWM2_ENABLED 0 +#endif + +// PWM_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef PWM_CONFIG_LOG_ENABLED +#define PWM_CONFIG_LOG_ENABLED 0 +#endif +#if PWM_CONFIG_LOG_ENABLED +// PWM_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef PWM_CONFIG_LOG_LEVEL +#define PWM_CONFIG_LOG_LEVEL 3 +#endif + +// PWM_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PWM_CONFIG_INFO_COLOR +#define PWM_CONFIG_INFO_COLOR 0 +#endif + +// PWM_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef PWM_CONFIG_DEBUG_COLOR +#define PWM_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //PWM_CONFIG_LOG_ENABLED +// + +#endif //PWM_ENABLED +// + +// QDEC_ENABLED - nrf_drv_qdec - QDEC peripheral driver +//========================================================== +#ifndef QDEC_ENABLED +#define QDEC_ENABLED 0 +#endif +#if QDEC_ENABLED +// QDEC_CONFIG_REPORTPER - Report period + +// <0=> 10 Samples +// <1=> 40 Samples +// <2=> 80 Samples +// <3=> 120 Samples +// <4=> 160 Samples +// <5=> 200 Samples +// <6=> 240 Samples +// <7=> 280 Samples + +#ifndef QDEC_CONFIG_REPORTPER +#define QDEC_CONFIG_REPORTPER 0 +#endif + +// QDEC_CONFIG_SAMPLEPER - Sample period + +// <0=> 128 us +// <1=> 256 us +// <2=> 512 us +// <3=> 1024 us +// <4=> 2048 us +// <5=> 4096 us +// <6=> 8192 us +// <7=> 16384 us + +#ifndef QDEC_CONFIG_SAMPLEPER +#define QDEC_CONFIG_SAMPLEPER 7 +#endif + +// QDEC_CONFIG_PIO_A - A pin <0-31> + + +#ifndef QDEC_CONFIG_PIO_A +#define QDEC_CONFIG_PIO_A 31 +#endif + +// QDEC_CONFIG_PIO_B - B pin <0-31> + + +#ifndef QDEC_CONFIG_PIO_B +#define QDEC_CONFIG_PIO_B 31 +#endif + +// QDEC_CONFIG_PIO_LED - LED pin <0-31> + + +#ifndef QDEC_CONFIG_PIO_LED +#define QDEC_CONFIG_PIO_LED 31 +#endif + +// QDEC_CONFIG_LEDPRE - LED pre +#ifndef QDEC_CONFIG_LEDPRE +#define QDEC_CONFIG_LEDPRE 511 +#endif + +// QDEC_CONFIG_LEDPOL - LED polarity + +// <0=> Active low +// <1=> Active high + +#ifndef QDEC_CONFIG_LEDPOL +#define QDEC_CONFIG_LEDPOL 1 +#endif + +// QDEC_CONFIG_DBFEN - Debouncing enable + + +#ifndef QDEC_CONFIG_DBFEN +#define QDEC_CONFIG_DBFEN 0 +#endif + +// QDEC_CONFIG_SAMPLE_INTEN - Sample ready interrupt enable + + +#ifndef QDEC_CONFIG_SAMPLE_INTEN +#define QDEC_CONFIG_SAMPLE_INTEN 0 +#endif + +// QDEC_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef QDEC_CONFIG_IRQ_PRIORITY +#define QDEC_CONFIG_IRQ_PRIORITY 3 +#endif + +// QDEC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef QDEC_CONFIG_LOG_ENABLED +#define QDEC_CONFIG_LOG_ENABLED 0 +#endif +#if QDEC_CONFIG_LOG_ENABLED +// QDEC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef QDEC_CONFIG_LOG_LEVEL +#define QDEC_CONFIG_LOG_LEVEL 3 +#endif + +// QDEC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef QDEC_CONFIG_INFO_COLOR +#define QDEC_CONFIG_INFO_COLOR 0 +#endif + +// QDEC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef QDEC_CONFIG_DEBUG_COLOR +#define QDEC_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //QDEC_CONFIG_LOG_ENABLED +// + +#endif //QDEC_ENABLED +// + +// RNG_ENABLED - nrf_drv_rng - RNG peripheral driver +//========================================================== +#ifndef RNG_ENABLED +#define RNG_ENABLED 0 +#endif +#if RNG_ENABLED +// RNG_CONFIG_ERROR_CORRECTION - Error correction + + +#ifndef RNG_CONFIG_ERROR_CORRECTION +#define RNG_CONFIG_ERROR_CORRECTION 0 +#endif + +// RNG_CONFIG_POOL_SIZE - Pool size +#ifndef RNG_CONFIG_POOL_SIZE +#define RNG_CONFIG_POOL_SIZE 32 +#endif + +// RNG_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef RNG_CONFIG_IRQ_PRIORITY +#define RNG_CONFIG_IRQ_PRIORITY 3 +#endif + +// RNG_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef RNG_CONFIG_LOG_ENABLED +#define RNG_CONFIG_LOG_ENABLED 0 +#endif +#if RNG_CONFIG_LOG_ENABLED +// RNG_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef RNG_CONFIG_LOG_LEVEL +#define RNG_CONFIG_LOG_LEVEL 3 +#endif + +// RNG_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RNG_CONFIG_INFO_COLOR +#define RNG_CONFIG_INFO_COLOR 0 +#endif + +// RNG_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RNG_CONFIG_DEBUG_COLOR +#define RNG_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //RNG_CONFIG_LOG_ENABLED +// + +#endif //RNG_ENABLED +// + +// RTC_ENABLED - nrf_drv_rtc - RTC peripheral driver +//========================================================== +#ifndef RTC_ENABLED +#define RTC_ENABLED 0 +#endif +#if RTC_ENABLED +// RTC_DEFAULT_CONFIG_FREQUENCY - Frequency <16-32768> + + +#ifndef RTC_DEFAULT_CONFIG_FREQUENCY +#define RTC_DEFAULT_CONFIG_FREQUENCY 32768 +#endif + +// RTC_DEFAULT_CONFIG_RELIABLE - Ensures safe compare event triggering + + +#ifndef RTC_DEFAULT_CONFIG_RELIABLE +#define RTC_DEFAULT_CONFIG_RELIABLE 0 +#endif + +// RTC_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef RTC_DEFAULT_CONFIG_IRQ_PRIORITY +#define RTC_DEFAULT_CONFIG_IRQ_PRIORITY 3 +#endif + +// RTC0_ENABLED - Enable RTC0 instance + + +#ifndef RTC0_ENABLED +#define RTC0_ENABLED 0 +#endif + +// RTC1_ENABLED - Enable RTC1 instance + + +#ifndef RTC1_ENABLED +#define RTC1_ENABLED 0 +#endif + +// RTC2_ENABLED - Enable RTC2 instance + + +#ifndef RTC2_ENABLED +#define RTC2_ENABLED 0 +#endif + +// NRF_MAXIMUM_LATENCY_US - Maximum possible time[us] in highest priority interrupt +#ifndef NRF_MAXIMUM_LATENCY_US +#define NRF_MAXIMUM_LATENCY_US 2000 +#endif + +// RTC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef RTC_CONFIG_LOG_ENABLED +#define RTC_CONFIG_LOG_ENABLED 0 +#endif +#if RTC_CONFIG_LOG_ENABLED +// RTC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef RTC_CONFIG_LOG_LEVEL +#define RTC_CONFIG_LOG_LEVEL 3 +#endif + +// RTC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RTC_CONFIG_INFO_COLOR +#define RTC_CONFIG_INFO_COLOR 0 +#endif + +// RTC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef RTC_CONFIG_DEBUG_COLOR +#define RTC_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //RTC_CONFIG_LOG_ENABLED +// + +#endif //RTC_ENABLED +// + +// SAADC_ENABLED - nrf_drv_saadc - SAADC peripheral driver +//========================================================== +#ifndef SAADC_ENABLED +#define SAADC_ENABLED 0 +#endif +#if SAADC_ENABLED +// SAADC_CONFIG_RESOLUTION - Resolution + +// <0=> 8 bit +// <1=> 10 bit +// <2=> 12 bit +// <3=> 14 bit + +#ifndef SAADC_CONFIG_RESOLUTION +#define SAADC_CONFIG_RESOLUTION 1 +#endif + +// SAADC_CONFIG_OVERSAMPLE - Sample period + +// <0=> Disabled +// <1=> 2x +// <2=> 4x +// <3=> 8x +// <4=> 16x +// <5=> 32x +// <6=> 64x +// <7=> 128x +// <8=> 256x + +#ifndef SAADC_CONFIG_OVERSAMPLE +#define SAADC_CONFIG_OVERSAMPLE 0 +#endif + +// SAADC_CONFIG_LP_MODE - Enabling low power mode + + +#ifndef SAADC_CONFIG_LP_MODE +#define SAADC_CONFIG_LP_MODE 0 +#endif + +// SAADC_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef SAADC_CONFIG_IRQ_PRIORITY +#define SAADC_CONFIG_IRQ_PRIORITY 3 +#endif + +// SAADC_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SAADC_CONFIG_LOG_ENABLED +#define SAADC_CONFIG_LOG_ENABLED 0 +#endif +#if SAADC_CONFIG_LOG_ENABLED +// SAADC_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SAADC_CONFIG_LOG_LEVEL +#define SAADC_CONFIG_LOG_LEVEL 3 +#endif + +// SAADC_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SAADC_CONFIG_INFO_COLOR +#define SAADC_CONFIG_INFO_COLOR 0 +#endif + +// SAADC_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SAADC_CONFIG_DEBUG_COLOR +#define SAADC_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //SAADC_CONFIG_LOG_ENABLED +// + +#endif //SAADC_ENABLED +// + +// SPIS_ENABLED - nrf_drv_spis - SPI Slave driver +//========================================================== +#ifndef SPIS_ENABLED +#define SPIS_ENABLED 0 +#endif +#if SPIS_ENABLED +// SPIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef SPIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define SPIS_DEFAULT_CONFIG_IRQ_PRIORITY 3 +#endif + +// SPIS_DEFAULT_MODE - Mode + +// <0=> MODE_0 +// <1=> MODE_1 +// <2=> MODE_2 +// <3=> MODE_3 + +#ifndef SPIS_DEFAULT_MODE +#define SPIS_DEFAULT_MODE 0 +#endif + +// SPIS_DEFAULT_BIT_ORDER - SPIS default bit order + +// <0=> MSB first +// <1=> LSB first + +#ifndef SPIS_DEFAULT_BIT_ORDER +#define SPIS_DEFAULT_BIT_ORDER 0 +#endif + +// SPIS_DEFAULT_DEF - SPIS default DEF character <0-255> + + +#ifndef SPIS_DEFAULT_DEF +#define SPIS_DEFAULT_DEF 255 +#endif + +// SPIS_DEFAULT_ORC - SPIS default ORC character <0-255> + + +#ifndef SPIS_DEFAULT_ORC +#define SPIS_DEFAULT_ORC 255 +#endif + +// SPIS0_ENABLED - Enable SPIS0 instance + + +#ifndef SPIS0_ENABLED +#define SPIS0_ENABLED 0 +#endif + +// SPIS1_ENABLED - Enable SPIS1 instance + + +#ifndef SPIS1_ENABLED +#define SPIS1_ENABLED 0 +#endif + +// SPIS2_ENABLED - Enable SPIS2 instance + + +#ifndef SPIS2_ENABLED +#define SPIS2_ENABLED 0 +#endif + +// SPIS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SPIS_CONFIG_LOG_ENABLED +#define SPIS_CONFIG_LOG_ENABLED 0 +#endif +#if SPIS_CONFIG_LOG_ENABLED +// SPIS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SPIS_CONFIG_LOG_LEVEL +#define SPIS_CONFIG_LOG_LEVEL 3 +#endif + +// SPIS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPIS_CONFIG_INFO_COLOR +#define SPIS_CONFIG_INFO_COLOR 0 +#endif + +// SPIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPIS_CONFIG_DEBUG_COLOR +#define SPIS_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //SPIS_CONFIG_LOG_ENABLED +// + +#endif //SPIS_ENABLED +// + +// SPI_ENABLED - nrf_drv_spi - SPI/SPIM peripheral driver +//========================================================== +#ifndef SPI_ENABLED +#define SPI_ENABLED 1 +#endif +#if SPI_ENABLED +// SPI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef SPI_DEFAULT_CONFIG_IRQ_PRIORITY +#define SPI_DEFAULT_CONFIG_IRQ_PRIORITY 3 +#endif + +// SPI0_ENABLED - Enable SPI0 instance +//========================================================== +#ifndef SPI0_ENABLED +#define SPI0_ENABLED 1 +#endif +#if SPI0_ENABLED +// SPI0_USE_EASY_DMA - Use EasyDMA + + +#ifndef SPI0_USE_EASY_DMA +#define SPI0_USE_EASY_DMA 0 +#endif + +// SPI0_DEFAULT_FREQUENCY - SPI frequency + +// <33554432=> 125 kHz +// <67108864=> 250 kHz +// <134217728=> 500 kHz +// <268435456=> 1 MHz +// <536870912=> 2 MHz +// <1073741824=> 4 MHz +// <2147483648=> 8 MHz + +#ifndef SPI0_DEFAULT_FREQUENCY +#define SPI0_DEFAULT_FREQUENCY 1073741824 +#endif + +#endif //SPI0_ENABLED +// + +// SPI1_ENABLED - Enable SPI1 instance +//========================================================== +#ifndef SPI1_ENABLED +#define SPI1_ENABLED 0 +#endif +#if SPI1_ENABLED +// SPI1_USE_EASY_DMA - Use EasyDMA + + +#ifndef SPI1_USE_EASY_DMA +#define SPI1_USE_EASY_DMA 0 +#endif + +// SPI1_DEFAULT_FREQUENCY - SPI frequency + +// <33554432=> 125 kHz +// <67108864=> 250 kHz +// <134217728=> 500 kHz +// <268435456=> 1 MHz +// <536870912=> 2 MHz +// <1073741824=> 4 MHz +// <2147483648=> 8 MHz + +#ifndef SPI1_DEFAULT_FREQUENCY +#define SPI1_DEFAULT_FREQUENCY 1073741824 +#endif + +#endif //SPI1_ENABLED +// + +// SPI2_ENABLED - Enable SPI2 instance +//========================================================== +#ifndef SPI2_ENABLED +#define SPI2_ENABLED 0 +#endif +#if SPI2_ENABLED +// SPI2_USE_EASY_DMA - Use EasyDMA + + +#ifndef SPI2_USE_EASY_DMA +#define SPI2_USE_EASY_DMA 0 +#endif + +// SPI2_DEFAULT_FREQUENCY - Use EasyDMA + + +#ifndef SPI2_DEFAULT_FREQUENCY +#define SPI2_DEFAULT_FREQUENCY 0 +#endif + +#endif //SPI2_ENABLED +// + +// SPI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef SPI_CONFIG_LOG_ENABLED +#define SPI_CONFIG_LOG_ENABLED 0 +#endif +#if SPI_CONFIG_LOG_ENABLED +// SPI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef SPI_CONFIG_LOG_LEVEL +#define SPI_CONFIG_LOG_LEVEL 3 +#endif + +// SPI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPI_CONFIG_INFO_COLOR +#define SPI_CONFIG_INFO_COLOR 0 +#endif + +// SPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef SPI_CONFIG_DEBUG_COLOR +#define SPI_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //SPI_CONFIG_LOG_ENABLED +// + +#endif //SPI_ENABLED +// + +// TIMER_ENABLED - nrf_drv_timer - TIMER periperal driver +//========================================================== +#ifndef TIMER_ENABLED +#define TIMER_ENABLED 0 +#endif +#if TIMER_ENABLED +// TIMER_DEFAULT_CONFIG_FREQUENCY - Timer frequency if in Timer mode + +// <0=> 16 MHz +// <1=> 8 MHz +// <2=> 4 MHz +// <3=> 2 MHz +// <4=> 1 MHz +// <5=> 500 kHz +// <6=> 250 kHz +// <7=> 125 kHz +// <8=> 62.5 kHz +// <9=> 31.25 kHz + +#ifndef TIMER_DEFAULT_CONFIG_FREQUENCY +#define TIMER_DEFAULT_CONFIG_FREQUENCY 0 +#endif + +// TIMER_DEFAULT_CONFIG_MODE - Timer mode or operation + +// <0=> Timer +// <1=> Counter + +#ifndef TIMER_DEFAULT_CONFIG_MODE +#define TIMER_DEFAULT_CONFIG_MODE 0 +#endif + +// TIMER_DEFAULT_CONFIG_BIT_WIDTH - Timer counter bit width + +// <0=> 16 bit +// <1=> 8 bit +// <2=> 24 bit +// <3=> 32 bit + +#ifndef TIMER_DEFAULT_CONFIG_BIT_WIDTH +#define TIMER_DEFAULT_CONFIG_BIT_WIDTH 0 +#endif + +// TIMER_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef TIMER_DEFAULT_CONFIG_IRQ_PRIORITY +#define TIMER_DEFAULT_CONFIG_IRQ_PRIORITY 3 +#endif + +// TIMER0_ENABLED - Enable TIMER0 instance + + +#ifndef TIMER0_ENABLED +#define TIMER0_ENABLED 0 +#endif + +// TIMER1_ENABLED - Enable TIMER1 instance + + +#ifndef TIMER1_ENABLED +#define TIMER1_ENABLED 0 +#endif + +// TIMER2_ENABLED - Enable TIMER2 instance + + +#ifndef TIMER2_ENABLED +#define TIMER2_ENABLED 0 +#endif + +// TIMER3_ENABLED - Enable TIMER3 instance + + +#ifndef TIMER3_ENABLED +#define TIMER3_ENABLED 0 +#endif + +// TIMER4_ENABLED - Enable TIMER4 instance + + +#ifndef TIMER4_ENABLED +#define TIMER4_ENABLED 0 +#endif + +// TIMER_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TIMER_CONFIG_LOG_ENABLED +#define TIMER_CONFIG_LOG_ENABLED 0 +#endif +#if TIMER_CONFIG_LOG_ENABLED +// TIMER_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TIMER_CONFIG_LOG_LEVEL +#define TIMER_CONFIG_LOG_LEVEL 3 +#endif + +// TIMER_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TIMER_CONFIG_INFO_COLOR +#define TIMER_CONFIG_INFO_COLOR 0 +#endif + +// TIMER_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TIMER_CONFIG_DEBUG_COLOR +#define TIMER_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //TIMER_CONFIG_LOG_ENABLED +// + +#endif //TIMER_ENABLED +// + +// TWIS_ENABLED - nrf_drv_twis - TWIS peripheral driver +//========================================================== +#ifndef TWIS_ENABLED +#define TWIS_ENABLED 0 +#endif +#if TWIS_ENABLED +// TWIS_DEFAULT_CONFIG_ADDR0 - Address0 +#ifndef TWIS_DEFAULT_CONFIG_ADDR0 +#define TWIS_DEFAULT_CONFIG_ADDR0 0 +#endif + +// TWIS_DEFAULT_CONFIG_ADDR1 - Address1 +#ifndef TWIS_DEFAULT_CONFIG_ADDR1 +#define TWIS_DEFAULT_CONFIG_ADDR1 0 +#endif + +// TWIS_DEFAULT_CONFIG_SCL_PULL - SCL pin pull configuration + +// <0=> Disabled +// <1=> Pull down +// <3=> Pull up + +#ifndef TWIS_DEFAULT_CONFIG_SCL_PULL +#define TWIS_DEFAULT_CONFIG_SCL_PULL 0 +#endif + +// TWIS_DEFAULT_CONFIG_SDA_PULL - SDA pin pull configuration + +// <0=> Disabled +// <1=> Pull down +// <3=> Pull up + +#ifndef TWIS_DEFAULT_CONFIG_SDA_PULL +#define TWIS_DEFAULT_CONFIG_SDA_PULL 0 +#endif + +// TWIS_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef TWIS_DEFAULT_CONFIG_IRQ_PRIORITY +#define TWIS_DEFAULT_CONFIG_IRQ_PRIORITY 3 +#endif + +// TWIS0_ENABLED - Enable TWIS0 instance + + +#ifndef TWIS0_ENABLED +#define TWIS0_ENABLED 0 +#endif + +// TWIS1_ENABLED - Enable TWIS1 instance + + +#ifndef TWIS1_ENABLED +#define TWIS1_ENABLED 0 +#endif + +// TWIS_ASSUME_INIT_AFTER_RESET_ONLY - Assume that any instance would be initialized only once + + +// Optimization flag. Registers used by TWIS are shared by other peripherals. Normally, during initialization driver tries to clear all registers to known state before doing the initialization itself. This gives initialization safe procedure, no matter when it would be called. If you activate TWIS only once and do never uninitialize it - set this flag to 1 what gives more optimal code. + +#ifndef TWIS_ASSUME_INIT_AFTER_RESET_ONLY +#define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 +#endif + +// TWIS_NO_SYNC_MODE - Remove support for synchronous mode + + +// Synchronous mode would be used in specific situations. And it uses some additional code and data memory to safely process state machine by polling it in status functions. If this functionality is not required it may be disabled to free some resources. + +#ifndef TWIS_NO_SYNC_MODE +#define TWIS_NO_SYNC_MODE 0 +#endif + +// TWIS_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TWIS_CONFIG_LOG_ENABLED +#define TWIS_CONFIG_LOG_ENABLED 0 +#endif +#if TWIS_CONFIG_LOG_ENABLED +// TWIS_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TWIS_CONFIG_LOG_LEVEL +#define TWIS_CONFIG_LOG_LEVEL 3 +#endif + +// TWIS_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWIS_CONFIG_INFO_COLOR +#define TWIS_CONFIG_INFO_COLOR 0 +#endif + +// TWIS_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWIS_CONFIG_DEBUG_COLOR +#define TWIS_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //TWIS_CONFIG_LOG_ENABLED +// + +#endif //TWIS_ENABLED +// + +// TWI_ENABLED - nrf_drv_twi - TWI/TWIM peripheral driver +//========================================================== +#ifndef TWI_ENABLED +#define TWI_ENABLED 1 +#endif +#if TWI_ENABLED +// TWI_DEFAULT_CONFIG_FREQUENCY - Frequency + +// <26738688=> 100k +// <67108864=> 250k +// <104857600=> 400k + +#ifndef TWI_DEFAULT_CONFIG_FREQUENCY +#define TWI_DEFAULT_CONFIG_FREQUENCY 26738688 +#endif + +// TWI_DEFAULT_CONFIG_CLR_BUS_INIT - Enables bus clearing procedure during init + + +#ifndef TWI_DEFAULT_CONFIG_CLR_BUS_INIT +#define TWI_DEFAULT_CONFIG_CLR_BUS_INIT 0 +#endif + +// TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT - Enables bus holding after uninit + + +#ifndef TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT +#define TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT 0 +#endif + +// TWI_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef TWI_DEFAULT_CONFIG_IRQ_PRIORITY +#define TWI_DEFAULT_CONFIG_IRQ_PRIORITY 3 +#endif + +// TWI0_ENABLED - Enable TWI0 instance +//========================================================== +#ifndef TWI0_ENABLED +#define TWI0_ENABLED 0 +#endif +#if TWI0_ENABLED +// TWI0_USE_EASY_DMA - Use EasyDMA (if present) + + +#ifndef TWI0_USE_EASY_DMA +#define TWI0_USE_EASY_DMA 0 +#endif + +#endif //TWI0_ENABLED +// + +// TWI1_ENABLED - Enable TWI1 instance +//========================================================== +#ifndef TWI1_ENABLED +#define TWI1_ENABLED 1 +#endif +#if TWI1_ENABLED +// TWI1_USE_EASY_DMA - Use EasyDMA (if present) + + +#ifndef TWI1_USE_EASY_DMA +#define TWI1_USE_EASY_DMA 0 +#endif + +#endif //TWI1_ENABLED +// + +// TWI_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef TWI_CONFIG_LOG_ENABLED +#define TWI_CONFIG_LOG_ENABLED 0 +#endif +#if TWI_CONFIG_LOG_ENABLED +// TWI_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef TWI_CONFIG_LOG_LEVEL +#define TWI_CONFIG_LOG_LEVEL 3 +#endif + +// TWI_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWI_CONFIG_INFO_COLOR +#define TWI_CONFIG_INFO_COLOR 0 +#endif + +// TWI_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef TWI_CONFIG_DEBUG_COLOR +#define TWI_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //TWI_CONFIG_LOG_ENABLED +// + +#endif //TWI_ENABLED +// + +// UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver +//========================================================== +#ifndef UART_ENABLED +#define UART_ENABLED 1 +#endif +#if UART_ENABLED +// UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef UART_DEFAULT_CONFIG_HWFC +#define UART_DEFAULT_CONFIG_HWFC 0 +#endif + +// UART_DEFAULT_CONFIG_PARITY - Parity + +// <0=> Excluded +// <14=> Included + +#ifndef UART_DEFAULT_CONFIG_PARITY +#define UART_DEFAULT_CONFIG_PARITY 0 +#endif + +// UART_DEFAULT_CONFIG_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <10289152=> 38400 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30924800=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 57600 baud + +#ifndef UART_DEFAULT_CONFIG_BAUDRATE +#define UART_DEFAULT_CONFIG_BAUDRATE 30924800 +#endif + +// UART_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY +#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 3 +#endif + +// UART_EASY_DMA_SUPPORT - Driver supporting EasyDMA + + +#ifndef UART_EASY_DMA_SUPPORT +#define UART_EASY_DMA_SUPPORT 1 +#endif + +// UART_LEGACY_SUPPORT - Driver supporting Legacy mode + + +#ifndef UART_LEGACY_SUPPORT +#define UART_LEGACY_SUPPORT 1 +#endif + +// UART0_ENABLED - Enable UART0 instance +//========================================================== +#ifndef UART0_ENABLED +#define UART0_ENABLED 1 +#endif +#if UART0_ENABLED +// UART0_CONFIG_USE_EASY_DMA - Default setting for using EasyDMA + + +#ifndef UART0_CONFIG_USE_EASY_DMA +#define UART0_CONFIG_USE_EASY_DMA 1 +#endif + +#endif //UART0_ENABLED +// + +// UART_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef UART_CONFIG_LOG_ENABLED +#define UART_CONFIG_LOG_ENABLED 0 +#endif +#if UART_CONFIG_LOG_ENABLED +// UART_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef UART_CONFIG_LOG_LEVEL +#define UART_CONFIG_LOG_LEVEL 3 +#endif + +// UART_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef UART_CONFIG_INFO_COLOR +#define UART_CONFIG_INFO_COLOR 0 +#endif + +// UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef UART_CONFIG_DEBUG_COLOR +#define UART_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //UART_CONFIG_LOG_ENABLED +// + +#endif //UART_ENABLED +// + +// USBD_ENABLED - nrf_drv_usbd - USB driver +//========================================================== +#ifndef USBD_ENABLED +#define USBD_ENABLED 0 +#endif +#if USBD_ENABLED +// NRF_DRV_USBD_DMASCHEDULER_MODE - USBD SMA scheduler working scheme + +// <0=> Prioritized access +// <1=> Round Robin + +#ifndef NRF_DRV_USBD_DMASCHEDULER_MODE +#define NRF_DRV_USBD_DMASCHEDULER_MODE 0 +#endif + +// NRF_USBD_DRV_LOG_ENABLED - Enable logging. + + +#ifndef NRF_USBD_DRV_LOG_ENABLED +#define NRF_USBD_DRV_LOG_ENABLED 0 +#endif + +#endif //USBD_ENABLED +// + +// WDT_ENABLED - nrf_drv_wdt - WDT peripheral driver +//========================================================== +#ifndef WDT_ENABLED +#define WDT_ENABLED 0 +#endif +#if WDT_ENABLED +// WDT_CONFIG_BEHAVIOUR - WDT behavior in CPU SLEEP or HALT mode + +// <1=> Run in SLEEP, Pause in HALT +// <8=> Pause in SLEEP, Run in HALT +// <9=> Run in SLEEP and HALT +// <0=> Pause in SLEEP and HALT + +#ifndef WDT_CONFIG_BEHAVIOUR +#define WDT_CONFIG_BEHAVIOUR 1 +#endif + +// WDT_CONFIG_RELOAD_VALUE - Reload value <15-4294967295> + + +#ifndef WDT_CONFIG_RELOAD_VALUE +#define WDT_CONFIG_RELOAD_VALUE 2000 +#endif + +// WDT_CONFIG_IRQ_PRIORITY - Interrupt priority + + +// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice +// <0=> 0 (highest) +// <1=> 1 +// <2=> 2 +// <3=> 3 + +#ifndef WDT_CONFIG_IRQ_PRIORITY +#define WDT_CONFIG_IRQ_PRIORITY 3 +#endif + +// WDT_CONFIG_LOG_ENABLED - Enables logging in the module. +//========================================================== +#ifndef WDT_CONFIG_LOG_ENABLED +#define WDT_CONFIG_LOG_ENABLED 0 +#endif +#if WDT_CONFIG_LOG_ENABLED +// WDT_CONFIG_LOG_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef WDT_CONFIG_LOG_LEVEL +#define WDT_CONFIG_LOG_LEVEL 3 +#endif + +// WDT_CONFIG_INFO_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef WDT_CONFIG_INFO_COLOR +#define WDT_CONFIG_INFO_COLOR 0 +#endif + +// WDT_CONFIG_DEBUG_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef WDT_CONFIG_DEBUG_COLOR +#define WDT_CONFIG_DEBUG_COLOR 0 +#endif + +#endif //WDT_CONFIG_LOG_ENABLED +// + +#endif //WDT_ENABLED +// + +// +//========================================================== + +// nRF_Libraries + +//========================================================== +// APP_FIFO_ENABLED - app_fifo - Software FIFO implementation + + +#ifndef APP_FIFO_ENABLED +#define APP_FIFO_ENABLED 0 +#endif + +// APP_GPIOTE_ENABLED - app_gpiote - GPIOTE events dispatcher + + +#ifndef APP_GPIOTE_ENABLED +#define APP_GPIOTE_ENABLED 0 +#endif + +// APP_PWM_ENABLED - app_pwm - PWM functionality + + +#ifndef APP_PWM_ENABLED +#define APP_PWM_ENABLED 0 +#endif + +// APP_SCHEDULER_ENABLED - app_scheduler - Events scheduler +//========================================================== +#ifndef APP_SCHEDULER_ENABLED +#define APP_SCHEDULER_ENABLED 0 +#endif +#if APP_SCHEDULER_ENABLED +// APP_SCHEDULER_WITH_PAUSE - Enabling pause feature + + +#ifndef APP_SCHEDULER_WITH_PAUSE +#define APP_SCHEDULER_WITH_PAUSE 0 +#endif + +// APP_SCHEDULER_WITH_PROFILER - Enabling scheduler profiling + + +#ifndef APP_SCHEDULER_WITH_PROFILER +#define APP_SCHEDULER_WITH_PROFILER 0 +#endif + +#endif //APP_SCHEDULER_ENABLED +// + +// APP_TIMER_ENABLED - app_timer - Application timer functionality +//========================================================== +#ifndef APP_TIMER_ENABLED +#define APP_TIMER_ENABLED 1 +#endif +#if APP_TIMER_ENABLED +// APP_TIMER_WITH_PROFILER - Enable app_timer profiling + + +#ifndef APP_TIMER_WITH_PROFILER +#define APP_TIMER_WITH_PROFILER 0 +#endif + +// APP_TIMER_KEEPS_RTC_ACTIVE - Enable RTC always on + + +// If option is enabled RTC is kept running even if there is no active timers. +// This option can be used when app_timer is used for timestamping. + +#ifndef APP_TIMER_KEEPS_RTC_ACTIVE +#define APP_TIMER_KEEPS_RTC_ACTIVE 0 +#endif + +#endif //APP_TIMER_ENABLED +// + +// APP_TWI_ENABLED - app_twi - TWI transaction manager + + +#ifndef APP_TWI_ENABLED +#define APP_TWI_ENABLED 0 +#endif + +// APP_UART_ENABLED - app_uart - UART driver +//========================================================== +#ifndef APP_UART_ENABLED +#define APP_UART_ENABLED 0 +#endif +#if APP_UART_ENABLED +// APP_UART_DRIVER_INSTANCE - UART instance used + +// <0=> 0 + +#ifndef APP_UART_DRIVER_INSTANCE +#define APP_UART_DRIVER_INSTANCE 0 +#endif + +#endif //APP_UART_ENABLED +// + +// APP_USBD_CLASS_AUDIO_ENABLED - app_usbd_audio - USB AUDIO class + + +#ifndef APP_USBD_CLASS_AUDIO_ENABLED +#define APP_USBD_CLASS_AUDIO_ENABLED 0 +#endif + +// APP_USBD_CLASS_HID_ENABLED - app_usbd_hid - USB HID class + + +#ifndef APP_USBD_CLASS_HID_ENABLED +#define APP_USBD_CLASS_HID_ENABLED 0 +#endif + +// APP_USBD_HID_GENERIC_ENABLED - app_usbd_hid_generic - USB HID generic + + +#ifndef APP_USBD_HID_GENERIC_ENABLED +#define APP_USBD_HID_GENERIC_ENABLED 0 +#endif + +// APP_USBD_HID_KBD_ENABLED - app_usbd_hid_kbd - USB HID keyboard + + +#ifndef APP_USBD_HID_KBD_ENABLED +#define APP_USBD_HID_KBD_ENABLED 0 +#endif + +// APP_USBD_HID_MOUSE_ENABLED - app_usbd_hid_mouse - USB HID mouse + + +#ifndef APP_USBD_HID_MOUSE_ENABLED +#define APP_USBD_HID_MOUSE_ENABLED 0 +#endif + +// BUTTON_ENABLED - app_button - buttons handling module + + +#ifndef BUTTON_ENABLED +#define BUTTON_ENABLED 0 +#endif + +// CRC16_ENABLED - crc16 - CRC16 calculation routines + + +#ifndef CRC16_ENABLED +#define CRC16_ENABLED 0 +#endif + +// CRC32_ENABLED - crc32 - CRC32 calculation routines + + +#ifndef CRC32_ENABLED +#define CRC32_ENABLED 0 +#endif + +// ECC_ENABLED - ecc - Elliptic Curve Cryptography Library + + +#ifndef ECC_ENABLED +#define ECC_ENABLED 0 +#endif + +// FDS_ENABLED - fds - Flash data storage module +//========================================================== +#ifndef FDS_ENABLED +#define FDS_ENABLED 0 +#endif +#if FDS_ENABLED +// FDS_OP_QUEUE_SIZE - Size of the internal queue. +#ifndef FDS_OP_QUEUE_SIZE +#define FDS_OP_QUEUE_SIZE 4 +#endif + +// FDS_CHUNK_QUEUE_SIZE - Determines how many @ref fds_record_chunk_t structures can be buffered at any time. +#ifndef FDS_CHUNK_QUEUE_SIZE +#define FDS_CHUNK_QUEUE_SIZE 8 +#endif + +// FDS_MAX_USERS - Maximum number of callbacks that can be registered. +#ifndef FDS_MAX_USERS +#define FDS_MAX_USERS 8 +#endif + +// FDS_VIRTUAL_PAGES - Number of virtual flash pages to use. +// One of the virtual pages is reserved by the system for garbage collection. +// Therefore, the minimum is two virtual pages: one page to store data and +// one page to be used by the system for garbage collection. The total amount +// of flash memory that is used by FDS amounts to @ref FDS_VIRTUAL_PAGES +// @ref FDS_VIRTUAL_PAGE_SIZE * 4 bytes. + +#ifndef FDS_VIRTUAL_PAGES +#define FDS_VIRTUAL_PAGES 3 +#endif + +// FDS_VIRTUAL_PAGE_SIZE - The size of a virtual page of flash memory, expressed in number of 4-byte words. + + +// By default, a virtual page is the same size as a physical page. +// The size of a virtual page must be a multiple of the size of a physical page. +// <256=> 256 +// <512=> 512 +// <1024=> 1024 + +#ifndef FDS_VIRTUAL_PAGE_SIZE +#define FDS_VIRTUAL_PAGE_SIZE 256 +#endif + +#endif //FDS_ENABLED +// + +// FSTORAGE_ENABLED - fstorage - Flash storage module +//========================================================== +#ifndef FSTORAGE_ENABLED +#define FSTORAGE_ENABLED 1 +#endif +#if FSTORAGE_ENABLED +// FS_QUEUE_SIZE - Configures the size of the internal queue. +// Increase this if there are many users, or if it is likely that many +// operation will be queued at once without waiting for the previous operations +// to complete. In general, increase the queue size if you frequently receive +// @ref FS_ERR_QUEUE_FULL errors when calling @ref fs_store or @ref fs_erase. + +#ifndef FS_QUEUE_SIZE +#define FS_QUEUE_SIZE 4 +#endif + +// FS_OP_MAX_RETRIES - Number attempts to execute an operation if the SoftDevice fails. +// Increase this value if events return the @ref FS_ERR_OPERATION_TIMEOUT +// error often. The SoftDevice may fail to schedule flash access due to high BLE activity. + +#ifndef FS_OP_MAX_RETRIES +#define FS_OP_MAX_RETRIES 3 +#endif + +// FS_MAX_WRITE_SIZE_WORDS - Maximum number of words to be written to flash in a single operation. +// Tweaking this value can increase the chances of the SoftDevice being +// able to fit flash operations in between radio activity. This value is bound by the +// maximum number of words which the SoftDevice can write to flash in a single call to +// @ref sd_flash_write, which is 256 words for nRF51 ICs and 1024 words for nRF52 ICs. + +#ifndef FS_MAX_WRITE_SIZE_WORDS +#define FS_MAX_WRITE_SIZE_WORDS 256 +#endif + +#endif //FSTORAGE_ENABLED +// + +// HARDFAULT_HANDLER_ENABLED - hardfault_default - HardFault default handler for debugging and release + + +#ifndef HARDFAULT_HANDLER_ENABLED +#define HARDFAULT_HANDLER_ENABLED 0 +#endif + +// HCI_MEM_POOL_ENABLED - hci_mem_pool - memory pool implementation used by HCI +//========================================================== +#ifndef HCI_MEM_POOL_ENABLED +#define HCI_MEM_POOL_ENABLED 0 +#endif +#if HCI_MEM_POOL_ENABLED +// HCI_TX_BUF_SIZE - TX buffer size in bytes. +#ifndef HCI_TX_BUF_SIZE +#define HCI_TX_BUF_SIZE 600 +#endif + +// HCI_RX_BUF_SIZE - RX buffer size in bytes. +#ifndef HCI_RX_BUF_SIZE +#define HCI_RX_BUF_SIZE 600 +#endif + +// HCI_RX_BUF_QUEUE_SIZE - RX buffer queue size. +#ifndef HCI_RX_BUF_QUEUE_SIZE +#define HCI_RX_BUF_QUEUE_SIZE 4 +#endif + +#endif //HCI_MEM_POOL_ENABLED +// + +// HCI_SLIP_ENABLED - hci_slip - SLIP protocol implementation used by HCI +//========================================================== +#ifndef HCI_SLIP_ENABLED +#define HCI_SLIP_ENABLED 0 +#endif +#if HCI_SLIP_ENABLED +// HCI_UART_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <10289152=> 38400 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30924800=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 57600 baud + +#ifndef HCI_UART_BAUDRATE +#define HCI_UART_BAUDRATE 30924800 +#endif + +// HCI_UART_FLOW_CONTROL - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef HCI_UART_FLOW_CONTROL +#define HCI_UART_FLOW_CONTROL 0 +#endif + +// HCI_UART_RX_PIN - UART RX pin +#ifndef HCI_UART_RX_PIN +#define HCI_UART_RX_PIN 11 +#endif + +// HCI_UART_TX_PIN - UART TX pin +#ifndef HCI_UART_TX_PIN +#define HCI_UART_TX_PIN 9 +#endif + +// HCI_UART_RTS_PIN - UART RTS pin +#ifndef HCI_UART_RTS_PIN +#define HCI_UART_RTS_PIN 8 +#endif + +// HCI_UART_CTS_PIN - UART CTS pin +#ifndef HCI_UART_CTS_PIN +#define HCI_UART_CTS_PIN 10 +#endif + +#endif //HCI_SLIP_ENABLED +// + +// HCI_TRANSPORT_ENABLED - hci_transport - HCI transport +//========================================================== +#ifndef HCI_TRANSPORT_ENABLED +#define HCI_TRANSPORT_ENABLED 0 +#endif +#if HCI_TRANSPORT_ENABLED +// HCI_MAX_PACKET_SIZE_IN_BITS - Maximum size of a single application packet in bits. +#ifndef HCI_MAX_PACKET_SIZE_IN_BITS +#define HCI_MAX_PACKET_SIZE_IN_BITS 8000 +#endif + +#endif //HCI_TRANSPORT_ENABLED +// + +// LED_SOFTBLINK_ENABLED - led_softblink - led_softblink module + + +#ifndef LED_SOFTBLINK_ENABLED +#define LED_SOFTBLINK_ENABLED 0 +#endif + +// LOW_POWER_PWM_ENABLED - low_power_pwm - low_power_pwm module + + +#ifndef LOW_POWER_PWM_ENABLED +#define LOW_POWER_PWM_ENABLED 0 +#endif + +// MEM_MANAGER_ENABLED - mem_manager - Dynamic memory allocator +//========================================================== +#ifndef MEM_MANAGER_ENABLED +#define MEM_MANAGER_ENABLED 0 +#endif +#if MEM_MANAGER_ENABLED +// MEMORY_MANAGER_SMALL_BLOCK_COUNT - Size of each memory blocks identified as 'small' block. <0-255> + + +#ifndef MEMORY_MANAGER_SMALL_BLOCK_COUNT +#define MEMORY_MANAGER_SMALL_BLOCK_COUNT 1 +#endif + +// MEMORY_MANAGER_SMALL_BLOCK_SIZE - Size of each memory blocks identified as 'small' block. +// Size of each memory blocks identified as 'small' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_SMALL_BLOCK_SIZE +#define MEMORY_MANAGER_SMALL_BLOCK_SIZE 32 +#endif + +// MEMORY_MANAGER_MEDIUM_BLOCK_COUNT - Size of each memory blocks identified as 'medium' block. <0-255> + + +#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_COUNT +#define MEMORY_MANAGER_MEDIUM_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_MEDIUM_BLOCK_SIZE - Size of each memory blocks identified as 'medium' block. +// Size of each memory blocks identified as 'medium' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_SIZE +#define MEMORY_MANAGER_MEDIUM_BLOCK_SIZE 256 +#endif + +// MEMORY_MANAGER_LARGE_BLOCK_COUNT - Size of each memory blocks identified as 'large' block. <0-255> + + +#ifndef MEMORY_MANAGER_LARGE_BLOCK_COUNT +#define MEMORY_MANAGER_LARGE_BLOCK_COUNT 0 +#endif + +// MEMORY_MANAGER_LARGE_BLOCK_SIZE - Size of each memory blocks identified as 'large' block. +// Size of each memory blocks identified as 'large' block. Memory block are recommended to be word-sized. + +#ifndef MEMORY_MANAGER_LARGE_BLOCK_SIZE +#define MEMORY_MANAGER_LARGE_BLOCK_SIZE 256 +#endif + +// MEM_MANAGER_ENABLE_LOGS - Enable debug trace in the module. + + +#ifndef MEM_MANAGER_ENABLE_LOGS +#define MEM_MANAGER_ENABLE_LOGS 0 +#endif + +// MEM_MANAGER_DISABLE_API_PARAM_CHECK - Disable API parameter checks in the module. + + +#ifndef MEM_MANAGER_DISABLE_API_PARAM_CHECK +#define MEM_MANAGER_DISABLE_API_PARAM_CHECK 0 +#endif + +#endif //MEM_MANAGER_ENABLED +// + +// NRF_CSENSE_ENABLED - nrf_csense - nrf_csense module +//========================================================== +#ifndef NRF_CSENSE_ENABLED +#define NRF_CSENSE_ENABLED 0 +#endif +#if NRF_CSENSE_ENABLED +// NRF_CSENSE_PAD_HYSTERESIS - Minimal value of change to decide that pad was touched. +#ifndef NRF_CSENSE_PAD_HYSTERESIS +#define NRF_CSENSE_PAD_HYSTERESIS 15 +#endif + +// NRF_CSENSE_PAD_DEVIATION - Minimal value measured on pad to take its value while calculating step. +#ifndef NRF_CSENSE_PAD_DEVIATION +#define NRF_CSENSE_PAD_DEVIATION 70 +#endif + +// NRF_CSENSE_MIN_PAD_VALUE - Minimum normalized value on pad to take its value into account. +#ifndef NRF_CSENSE_MIN_PAD_VALUE +#define NRF_CSENSE_MIN_PAD_VALUE 20 +#endif + +// NRF_CSENSE_MAX_PADS_NUMBER - Maximum number of pads used for one instance. +#ifndef NRF_CSENSE_MAX_PADS_NUMBER +#define NRF_CSENSE_MAX_PADS_NUMBER 20 +#endif + +// NRF_CSENSE_MAX_VALUE - Maximum normalized value got from measurement. +#ifndef NRF_CSENSE_MAX_VALUE +#define NRF_CSENSE_MAX_VALUE 1000 +#endif + +// NRF_CSENSE_OUTPUT_PIN - Output pin used by lower module. +// This is only used when running on NRF51. + +#ifndef NRF_CSENSE_OUTPUT_PIN +#define NRF_CSENSE_OUTPUT_PIN 30 +#endif + +#endif //NRF_CSENSE_ENABLED +// + +// NRF_DRV_CSENSE_ENABLED - nrf_drv_csense - Capacitive sensor module +//========================================================== +#ifndef NRF_DRV_CSENSE_ENABLED +#define NRF_DRV_CSENSE_ENABLED 0 +#endif +#if NRF_DRV_CSENSE_ENABLED +// TIMER0_FOR_CSENSE - First TIMER instance used by the driver (except nRF51) +#ifndef TIMER0_FOR_CSENSE +#define TIMER0_FOR_CSENSE 1 +#endif + +// TIMER1_FOR_CSENSE - Second TIMER instance used by the driver (except nRF51) +#ifndef TIMER1_FOR_CSENSE +#define TIMER1_FOR_CSENSE 2 +#endif + +// MEASUREMENT_PERIOD - Single measurement period. +// Time of single measurement can be calculated as T = (1/2)*MEASUREMENT_PERIOD*(1/f_OSC) where f_OSC = I_SOURCE / (2C*(VUP-VDOWN) ). I_SOURCE, VUP and VDOWN are values used to initialize COMP and C is capacitance of used pad. + +#ifndef MEASUREMENT_PERIOD +#define MEASUREMENT_PERIOD 20 +#endif + +#endif //NRF_DRV_CSENSE_ENABLED +// + +// NRF_QUEUE_ENABLED - nrf_queue - Queue module + + +#ifndef NRF_QUEUE_ENABLED +#define NRF_QUEUE_ENABLED 0 +#endif + +// RETARGET_ENABLED - retarget - Retargeting stdio functions + + +#ifndef RETARGET_ENABLED +#define RETARGET_ENABLED 0 +#endif + +// SLIP_ENABLED - slip - SLIP encoding decoding + + +#ifndef SLIP_ENABLED +#define SLIP_ENABLED 0 +#endif + +// app_usbd_cdc_acm - USB CDC ACM class + +//========================================================== +// APP_USBD_CLASS_CDC_ACM_ENABLED - Enabling USBD CDC ACM Class library + + +#ifndef APP_USBD_CLASS_CDC_ACM_ENABLED +#define APP_USBD_CLASS_CDC_ACM_ENABLED 0 +#endif + +// APP_USBD_CDC_ACM_LOG_ENABLED - Enables logging in the module. + + +#ifndef APP_USBD_CDC_ACM_LOG_ENABLED +#define APP_USBD_CDC_ACM_LOG_ENABLED 0 +#endif + +// +//========================================================== + +// app_usbd_msc - USB MSC class + +//========================================================== +// APP_USBD_CLASS_MSC_ENABLED - Enabling USBD MSC Class library + + +#ifndef APP_USBD_CLASS_MSC_ENABLED +#define APP_USBD_CLASS_MSC_ENABLED 0 +#endif + +// APP_USBD_MSC_CLASS_LOG_ENABLED - Enables logging in the module. + + +#ifndef APP_USBD_MSC_CLASS_LOG_ENABLED +#define APP_USBD_MSC_CLASS_LOG_ENABLED 0 +#endif + +// +//========================================================== + +// +//========================================================== + +// nRF_Log + +//========================================================== +// NRF_LOG_ENABLED - nrf_log - Logging +//========================================================== +#ifndef NRF_LOG_ENABLED +#define NRF_LOG_ENABLED 1 +#endif +#if NRF_LOG_ENABLED +// NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string +//========================================================== +#ifndef NRF_LOG_USES_COLORS +#define NRF_LOG_USES_COLORS 0 +#endif +#if NRF_LOG_USES_COLORS +// NRF_LOG_COLOR_DEFAULT - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_COLOR_DEFAULT +#define NRF_LOG_COLOR_DEFAULT 0 +#endif + +// NRF_LOG_ERROR_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_ERROR_COLOR +#define NRF_LOG_ERROR_COLOR 0 +#endif + +// NRF_LOG_WARNING_COLOR - ANSI escape code prefix. + +// <0=> Default +// <1=> Black +// <2=> Red +// <3=> Green +// <4=> Yellow +// <5=> Blue +// <6=> Magenta +// <7=> Cyan +// <8=> White + +#ifndef NRF_LOG_WARNING_COLOR +#define NRF_LOG_WARNING_COLOR 0 +#endif + +#endif //NRF_LOG_USES_COLORS +// + +// NRF_LOG_DEFAULT_LEVEL - Default Severity level + +// <0=> Off +// <1=> Error +// <2=> Warning +// <3=> Info +// <4=> Debug + +#ifndef NRF_LOG_DEFAULT_LEVEL +#define NRF_LOG_DEFAULT_LEVEL 3 +#endif + +// NRF_LOG_DEFERRED - Enable deffered logger. + +// Log data is buffered and can be processed in idle. +//========================================================== +#ifndef NRF_LOG_DEFERRED +#define NRF_LOG_DEFERRED 1 +#endif +#if NRF_LOG_DEFERRED +// NRF_LOG_DEFERRED_BUFSIZE - Size of the buffer for logs in words. +// Must be power of 2 + +#ifndef NRF_LOG_DEFERRED_BUFSIZE +#define NRF_LOG_DEFERRED_BUFSIZE 256 +#endif + +#endif //NRF_LOG_DEFERRED +// + +// NRF_LOG_USES_TIMESTAMP - Enable timestamping + + +// Function for getting the timestamp is provided by the user + +#ifndef NRF_LOG_USES_TIMESTAMP +#define NRF_LOG_USES_TIMESTAMP 0 +#endif + +#endif //NRF_LOG_ENABLED +// + +// nrf_log_backend - Logging sink + +//========================================================== +// NRF_LOG_BACKEND_MAX_STRING_LENGTH - Buffer for storing single output string +// Logger backend RAM usage is determined by this value. + +#ifndef NRF_LOG_BACKEND_MAX_STRING_LENGTH +#define NRF_LOG_BACKEND_MAX_STRING_LENGTH 256 +#endif + +// NRF_LOG_TIMESTAMP_DIGITS - Number of digits for timestamp +// If higher resolution timestamp source is used it might be needed to increase that + +#ifndef NRF_LOG_TIMESTAMP_DIGITS +#define NRF_LOG_TIMESTAMP_DIGITS 8 +#endif + +// NRF_LOG_BACKEND_SERIAL_USES_UART - If enabled data is printed over UART +//========================================================== +#ifndef NRF_LOG_BACKEND_SERIAL_USES_UART +#define NRF_LOG_BACKEND_SERIAL_USES_UART 0 +#endif +#if NRF_LOG_BACKEND_SERIAL_USES_UART +// NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE - Default Baudrate + +// <323584=> 1200 baud +// <643072=> 2400 baud +// <1290240=> 4800 baud +// <2576384=> 9600 baud +// <3862528=> 14400 baud +// <5152768=> 19200 baud +// <7716864=> 28800 baud +// <10289152=> 38400 baud +// <15400960=> 57600 baud +// <20615168=> 76800 baud +// <30924800=> 115200 baud +// <61865984=> 230400 baud +// <67108864=> 250000 baud +// <121634816=> 460800 baud +// <251658240=> 921600 baud +// <268435456=> 57600 baud + +#ifndef NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE +#define NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE 30924800 +#endif + +// NRF_LOG_BACKEND_SERIAL_UART_TX_PIN - UART TX pin +#ifndef NRF_LOG_BACKEND_SERIAL_UART_TX_PIN +#define NRF_LOG_BACKEND_SERIAL_UART_TX_PIN 9 +#endif + +// NRF_LOG_BACKEND_SERIAL_UART_RX_PIN - UART RX pin +#ifndef NRF_LOG_BACKEND_SERIAL_UART_RX_PIN +#define NRF_LOG_BACKEND_SERIAL_UART_RX_PIN 11 +#endif + +// NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN - UART RTS pin +#ifndef NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN +#define NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN 8 +#endif + +// NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN - UART CTS pin +#ifndef NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN +#define NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN 10 +#endif + +// NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL - Hardware Flow Control + +// <0=> Disabled +// <1=> Enabled + +#ifndef NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL +#define NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL 0 +#endif + +// NRF_LOG_BACKEND_UART_INSTANCE - UART instance used + +// <0=> 0 + +#ifndef NRF_LOG_BACKEND_UART_INSTANCE +#define NRF_LOG_BACKEND_UART_INSTANCE 0 +#endif + +#endif //NRF_LOG_BACKEND_SERIAL_USES_UART +// + +// NRF_LOG_BACKEND_SERIAL_USES_RTT - If enabled data is printed using RTT +//========================================================== +#ifndef NRF_LOG_BACKEND_SERIAL_USES_RTT +#define NRF_LOG_BACKEND_SERIAL_USES_RTT 1 +#endif +#if NRF_LOG_BACKEND_SERIAL_USES_RTT +// NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE - RTT output buffer size. +// Should be equal or bigger than \ref NRF_LOG_BACKEND_MAX_STRING_LENGTH. +// This value is used in Segger RTT configuration to set the buffer size +// if it is bigger than default RTT buffer size. + +#ifndef NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE +#define NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE 512 +#endif + +#endif //NRF_LOG_BACKEND_SERIAL_USES_RTT +// + +// +//========================================================== + +// +//========================================================== + +// nRF_Segger_RTT + +//========================================================== +// segger_rtt - SEGGER RTT + +//========================================================== +// SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer. +#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP +#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 64 +#endif + +// SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Size of upstream buffer. +#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS +#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2 +#endif + +// SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of upstream buffer. +#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN +#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16 +#endif + +// SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Size of upstream buffer. +#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS +#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2 +#endif + +// +//========================================================== + +// +//========================================================== + +// <<< end of configuration section >>> +#endif //SDK_CONFIG_H + diff --git a/main.c b/main.c index 56eabc9..ed5b68b 100644 --- a/main.c +++ b/main.c @@ -14,8 +14,6 @@ #include #include "nordic_common.h" #include "nrf.h" -#include "nrf_log.h" -#include "nrf_nvmc.h" #include "ble.h" #include "ble_hci.h" #include "ble_srv_common.h" @@ -23,15 +21,16 @@ #include "ble_advertising.h" #include "ble_conn_params.h" #include "softdevice_handler.h" -#include "pstorage.h" +#include "fstorage.h" #include "app_error.h" #include "app_timer.h" #include "EPD_ble.h" -#ifdef DEBUG -#include "EPD_Test.h" -#endif +#define NRF_LOG_MODULE_NAME "main" +#include "nrf_log.h" +#include "nrf_log_ctrl.h" -#define IS_SRVC_CHANGED_CHARACT_PRESENT 1 /**< Include or not the service_changed characteristic. if not enabled, the server's database cannot be changed for the lifetime of the device*/ +#define CENTRAL_LINK_COUNT 0 /**< Number of central links used by the application. When changing this number remember to adjust the RAM settings*/ +#define PERIPHERAL_LINK_COUNT 1 /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/ #define DEVICE_NAME "NRF_EPD" /**< Name of device. Will be included in the advertising data. */ #define APP_ADV_INTERVAL 300 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */ @@ -86,7 +85,7 @@ static void services_init(void) { uint32_t err_code; - err_code = pstorage_init(); + err_code = fs_init(); APP_ERROR_CHECK(err_code); memset(&m_epd, 0, sizeof(ble_epd_t)); @@ -96,8 +95,8 @@ static void services_init(void) /**@brief Function for the GAP initialization. * - * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the - * device including the device name, appearance, and the preferred connection parameters. + * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of + * the device. It also sets the permissions and appearance. */ static void gap_params_init(void) { @@ -112,7 +111,7 @@ static void gap_params_init(void) err_code = sd_ble_gap_address_get(&addr); APP_ERROR_CHECK(err_code); - NRF_LOG_PRINTF("Bluetooth MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", + NRF_LOG_INFO("Bluetooth MAC Address: %02X:%02X:%02X:%02X:%02X:%02X\n", addr.addr[5], addr.addr[4], addr.addr[3], addr.addr[2], addr.addr[1], addr.addr[0]); @@ -133,13 +132,14 @@ static void gap_params_init(void) APP_ERROR_CHECK(err_code); } -/**@brief Function for handling the Connection Parameters Module. +/**@brief Function for handling an event from the Connection Parameters Module. * - * @details This function will be called for all events in the Connection Parameters Module which - * are passed to the application. - * @note All this function does is to disconnect. This could have been done by simply - * setting the disconnect_on_fail config parameter, but instead we use the event - * handler mechanism to demonstrate its use. + * @details This function will be called for all events in the Connection Parameters Module + * which are passed to the application. + * + * @note All this function does is to disconnect. This could have been done by simply setting + * the disconnect_on_fail config parameter, but instead we use the event handler + * mechanism to demonstrate its use. * * @param[in] p_evt Event received from the Connection Parameters Module. */ @@ -155,7 +155,7 @@ static void on_conn_params_evt(ble_conn_params_evt_t * p_evt) } -/**@brief Function for handling a Connection Parameters error. +/**@brief Function for handling errors from the Connection Parameters module. * * @param[in] nrf_error Error code containing information about what went wrong. */ @@ -223,9 +223,9 @@ static void on_adv_evt(ble_adv_evt_t ble_adv_evt) } } -/**@brief Function for handling the Application's BLE Stack events. +/**@brief Function for the application's SoftDevice event handler. * - * @param[in] p_ble_evt Bluetooth stack event. + * @param[in] p_ble_evt SoftDevice event. */ static void on_ble_evt(ble_evt_t * p_ble_evt) { @@ -234,10 +234,12 @@ static void on_ble_evt(ble_evt_t * p_ble_evt) switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: + NRF_LOG_INFO("CONNECTED\n"); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: + NRF_LOG_INFO("DISCONNECTED\n"); m_conn_handle = BLE_CONN_HANDLE_INVALID; err_code = ble_advertising_start(BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); @@ -275,12 +277,13 @@ static void on_ble_evt(ble_evt_t * p_ble_evt) } -/**@brief Function for dispatching a BLE stack event to all modules with a BLE stack event handler. +/**@brief Function for dispatching a SoftDevice event to all modules with a SoftDevice + * event handler. * - * @details This function is called from the BLE Stack event interrupt handler after a BLE stack - * event has been received. + * @details This function is called from the SoftDevice event interrupt handler after a + * SoftDevice event has been received. * - * @param[in] p_ble_evt Bluetooth stack event. + * @param[in] p_ble_evt SoftDevice event. */ static void ble_evt_dispatch(ble_evt_t * p_ble_evt) { @@ -300,33 +303,52 @@ static void ble_evt_dispatch(ble_evt_t * p_ble_evt) */ static void sys_evt_dispatch(uint32_t sys_evt) { - pstorage_sys_event_handler(sys_evt); + // Dispatch the system event to the fstorage module, where it will be + // dispatched to the Flash Data Storage (FDS) module. + fs_sys_event_handler(sys_evt); + + // Dispatch to the Advertising module last, since it will check if there are any + // pending flash operations in fstorage. Let fstorage process system events first, + // so that it can report correctly to the Advertising module. ble_advertising_on_sys_evt(sys_evt); } -/**@brief Function for initializing the BLE stack. +/**@brief Function for the SoftDevice initialization. * - * @details Initializes the SoftDevice and the BLE event interrupt. + * @details This function initializes the SoftDevice and the BLE event interrupt. */ static void ble_stack_init(void) { uint32_t err_code; + nrf_clock_lf_cfg_t clock_lf_cfg = {.source = NRF_CLOCK_LF_SRC_SYNTH, + .rc_ctiv = 0, + .rc_temp_ctiv = 0, + .xtal_accuracy = NRF_CLOCK_LF_XTAL_ACCURACY_20_PPM, + }; + // Initialize the SoftDevice handler module. - SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_SYNTH_250_PPM, NULL); + SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL); - // Enable BLE stack. ble_enable_params_t ble_enable_params; - memset(&ble_enable_params, 0, sizeof(ble_enable_params)); - err_code = sd_ble_enable(&ble_enable_params); + err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT, + PERIPHERAL_LINK_COUNT, + &ble_enable_params); + APP_ERROR_CHECK(err_code); + + // Check the ram settings against the used number of links + CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT); + + // Enable BLE stack. + err_code = softdevice_enable(&ble_enable_params); APP_ERROR_CHECK(err_code); - // Register with the SoftDevice handler module for BLE events. + // Subscribe for BLE events. err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch); APP_ERROR_CHECK(err_code); - // Register with the SoftDevice handler module for BLE events. + // Subscribe for System events. err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch); APP_ERROR_CHECK(err_code); } @@ -335,13 +357,13 @@ static void ble_stack_init(void) */ static void advertising_init(void) { - uint32_t err_code; - ble_advdata_t advdata; - ble_advdata_t scanrsp; + uint32_t err_code; + ble_advdata_t advdata; + ble_advdata_t scanrsp; + ble_adv_modes_config_t options; // Build advertising data struct to pass into @ref ble_advertising_init. memset(&advdata, 0, sizeof(advdata)); - advdata.name_type = BLE_ADVDATA_FULL_NAME; advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE; @@ -349,8 +371,8 @@ static void advertising_init(void) scanrsp.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); scanrsp.uuids_complete.p_uuids = m_adv_uuids; - ble_adv_modes_config_t options = {0}; - options.ble_adv_fast_enabled = BLE_ADV_FAST_ENABLED; + memset(&options, 0, sizeof(options)); + options.ble_adv_fast_enabled = true; options.ble_adv_fast_interval = APP_ADV_INTERVAL; options.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS; @@ -372,10 +394,10 @@ int main(void) { uint32_t err_code; - err_code = NRF_LOG_INIT(); + err_code = NRF_LOG_INIT(NULL); APP_ERROR_CHECK(err_code); - NRF_LOG_PRINTF("start..\n"); + NRF_LOG_DEBUG("init..\n"); timers_init(); ble_stack_init(); @@ -384,17 +406,17 @@ int main(void) advertising_init(); conn_params_init(); + NRF_LOG_DEBUG("start..\n"); err_code = ble_advertising_start(BLE_ADV_MODE_FAST); APP_ERROR_CHECK(err_code); - NRF_LOG_PRINTF("done.\n"); - -#ifdef DEBUG - EPD_4in2_test(); -#endif + NRF_LOG_DEBUG("done.\n"); for (;;) { - power_manage(); + if (NRF_LOG_PROCESS() == false) + { + power_manage(); + } } }

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 diff --git a/components/properitary_rf/esb/nrf_esb.h b/components/properitary_rf/esb/nrf_esb.h deleted file mode 100644 index c61cefd..0000000 --- a/components/properitary_rf/esb/nrf_esb.h +++ /dev/null @@ -1,714 +0,0 @@ -/* Copyright (c) 2011 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - * $LastChangedRevision: 39629 $ - */ - -/** - * @file - * @brief Enhanced ShockBurst API. - * -*/ - -#ifndef NRF_ESB_H__ -#define NRF_ESB_H__ - -#include -#include -#include "nrf_esb_constants.h" - - -/** - * @defgroup esb_02_api Application Programming Interface (API) - * @{ - * @ingroup modules_02_esb - * @brief Enhanced ShockBurst Application Programming Interface (API). -*/ - - -/** - * @enum nrf_esb_mode_t - * @brief Enumerator used for selecting the ESB mode. - */ -typedef enum -{ - NRF_ESB_MODE_PTX, ///< Primary Transmitter mode - NRF_ESB_MODE_PRX, ///< Primary Receiver mode -} nrf_esb_mode_t; - -/** - * @enum nrf_esb_packet_t - * @brief Enumerator used for selecting TX packet type used in - * PTX mode. - */ -typedef enum -{ - NRF_ESB_PACKET_USE_ACK, ///< PTX packet requires ACK. - NRF_ESB_PACKET_NO_ACK, ///< PTX packet does not require ACK. -} nrf_esb_packet_t ; - - -/** - * @enum nrf_esb_base_address_length_t - * @brief Enumerator used for selecting the base address length. - */ -typedef enum -{ - NRF_ESB_BASE_ADDRESS_LENGTH_2B, ///< 2 byte address length - NRF_ESB_BASE_ADDRESS_LENGTH_3B, ///< 3 byte address length - NRF_ESB_BASE_ADDRESS_LENGTH_4B ///< 4 byte address length -} nrf_esb_base_address_length_t; - - -/** - * @enum nrf_esb_output_power_t - * @brief Enumerator used for selecting the TX output power. - */ -typedef enum -{ - NRF_ESB_OUTPUT_POWER_4_DBM, ///< 4 dBm output power. - NRF_ESB_OUTPUT_POWER_0_DBM, ///< 0 dBm output power. - NRF_ESB_OUTPUT_POWER_N4_DBM, ///< -4 dBm output power. - NRF_ESB_OUTPUT_POWER_N8_DBM, ///< -8 dBm output power. - NRF_ESB_OUTPUT_POWER_N12_DBM, ///< -12 dBm output power. - NRF_ESB_OUTPUT_POWER_N16_DBM, ///< -16 dBm output power. - NRF_ESB_OUTPUT_POWER_N20_DBM ///< -20 dBm output power. -} nrf_esb_output_power_t; - - -/** - * @enum nrf_esb_datarate_t - * @brief Enumerator used for selecting the radio data rate. - */ -typedef enum -{ - NRF_ESB_DATARATE_250_KBPS, ///< 250 Kbps datarate - NRF_ESB_DATARATE_1_MBPS, ///< 1 Mbps datarate - NRF_ESB_DATARATE_2_MBPS, ///< 1 Mbps datarate -} nrf_esb_datarate_t; - - -/** - * @enum nrf_esb_crc_length_t - * @brief Enumerator used for selecting the CRC length. - */ -typedef enum -{ - NRF_ESB_CRC_OFF, ///< CRC check disabled - NRF_ESB_CRC_LENGTH_1_BYTE, ///< CRC check set to 8-bit - NRF_ESB_CRC_LENGTH_2_BYTE ///< CRC check set to 16-bit -} nrf_esb_crc_length_t; - -/** - * @enum nrf_esb_xosc_ctl_t - * @brief Enumerator used for specifying whether switching the - * external 16 MHz oscillator on/off shall be handled automatically - * inside ESB or manually by the application. - */ -typedef enum -{ - NRF_ESB_XOSC_CTL_AUTO, ///< Switch XOSC on/off automatically - NRF_ESB_XOSC_CTL_MANUAL ///< Switch XOSC on/off manually -} nrf_esb_xosc_ctl_t; - -/******************************************************************************/ -/** @name General API functions - * @{ */ -/******************************************************************************/ - -/** - * @brief Initialize ESB. - * - * @param mode The mode to initialize ESB in. - * - * @retval true If ESB initialized. - * @retval false If ESB failed to initialize. - */ -bool nrf_esb_init(nrf_esb_mode_t mode); - - -/** - * @brief Enable ESB. - * - * Equivalent to setting CE high in legacy ESB. - * - * When enabled the behaviour described for the current ESB mode will apply. - */ -void nrf_esb_enable(void); - -/** - * @brief Disable ESB. - * - * Equivalent to setting CE low in legacy ESB. - * - * When calling this function ESB will begin disabling, - * and will be fully disabled when ESB calls nrf_esb_disabled(). - * If there are any pending notifications (callbacks) , or if any new notifications - * are being added to the internal notification queue while ESB is disabling, - * these will be sent to the application before ESB is fully disabled. - * - * After ESB has been fully disabled, no more notifications will be - * sent to the application. - */ -void nrf_esb_disable(void); - -/** Check whether ESB is enabled or disabled. - * - * @retval true If ESB is enabled. - * @retval false If ESB is disabled. - */ -bool nrf_esb_is_enabled(void); - -/** @} */ - - -/******************************************************************************/ -/** @name functions - * @{ */ -/******************************************************************************/ - -/** - * @brief TX success callback. - * - * In PTX mode this function is called after the PTX has sent a packet - * and received the corresponding ACK packet from a PRX. - * - * In PRX mode this function is called after a payload in ACK is assumed - * successfully transmitted, that is when the PRX received a new packet - * (new PID or CRC) and the previous ACK sent to a PTX contained a - * payload. - * - * @param tx_pipe The pipe on which the ACK packet was received. - * - * @param rssi Received signal strength indicator in dBm of measured ACK. - * - * As the RSSI measurement requires a minimum on-air duration of the received - * packet, the measured RSSI value will not be reliable when ALL of the following - * criteria are met: - * - * - Datarate = 2 Mbps - * - Payload length = 0 - * - CRC is off - * - */ -void nrf_esb_tx_success(uint32_t tx_pipe, int32_t rssi); - - -/** - * @brief TX failed callback (PTX mode only). - * - * This is called after the maximum number of TX attempts - * were reached for a packet. The packet is deleted from the TX FIFO. - * - * Note that when NRF_ESB_PACKET_NO_ACK is used this callback is - * always made after sending a packet. - * @sa nrf_esb_set_max_number_of_tx_attempts(). - * - * @param tx_pipe The pipe that failed to send a packet. - */ -void nrf_esb_tx_failed(uint32_t tx_pipe); - - -/** - * @brief RX data ready callback. - * - * PTX mode: This is called after an ACK is received from a PRX containing a - * payload. - * - * PRX mode: This is called after a packet is received from a PTX ACK is - * received from a PRX containing a payload. - * - * @param rx_pipe is the pipe on which a packet was received. - * This value must be < NRF_ESB_CONST_PIPE_COUNT. - * - * @param rssi Received signal strength indicator in dBm of packet. - * - * As the RSSI measurement requires a minimum on-air duration of the received - * packet, the measured RSSI value will not be reliable when ALL of the following - * criteria are met: - * - * - Datarate = 2 Mbps - * - Payload length = 0 - * - CRC is off - * - */ -void nrf_esb_rx_data_ready(uint32_t rx_pipe, int32_t rssi); - - -/** - * @brief Disabled callback. - * - * This is called after ESB enters the disabled state. - * There is no further CPU use by ESB, the radio is disabled and the timer is - * powered down. - */ -void nrf_esb_disabled(void); - -/** @} */ - - -/******************************************************************************/ -/** @name Packet transmission and receiving functions - * @{ */ -/******************************************************************************/ - -/** - * @brief Add a packet to the tail of the TX FIFO. - * - * In PTX mode, the packet will be transmitted at the next occation when ESB is enabled. - * In PRX mode, the payload will be piggybacked to onto an ACK. - * - * @param payload Pointer to the payload. - * @param payload_length The number of bytes of the payload to transmit. - * @param pipe The pipe for which to add the payload. This value must be < NRF_ESB_CONST_PIPE_COUNT. - * @param packet_type Specifies whether an ACK is required (ignored when in - * PRX mode, or when the dynamic ack feature is disabled). - * @sa nrf_esb_enable_dyn_ack() - * - * @retval true If the packet was successfully added to the TX FIFO. - * @retval false If pipe was invalid, payload pointer was NULL, payload length - was invalid, insufficient space in FIFO memory pool or - insufficient packets in TX queue. - */ -bool nrf_esb_add_packet_to_tx_fifo(uint32_t pipe, uint8_t * payload, uint32_t payload_length, nrf_esb_packet_t packet_type); - - -/** - * @brief Fetch a packet from the head of the RX FIFO. - * - * @param payload Pointer to copy the payload to. - * @param payload_length Pointer to copy the payload length to. The - * payload length is given in bytes (0 to NRF_ESB_CONST_MAX_PAYLOAD_LENGTH). - * @param pipe Pipe for which to add the payload. This value must be < NRF_ESB_CONST_PIPE_COUNT. - * - * @retval true If the fetch was successful. - * @retval false If there was no packet in the FIFO or the payload pointer - * was NULL. - */ -bool nrf_esb_fetch_packet_from_rx_fifo(uint32_t pipe, uint8_t * payload, uint32_t* payload_length); - - -/** - * @brief Get the number of packets residing in the TX FIFO on a specific - * pipe. - * - * @param pipe The pipe for which to check. This value must be < NRF_ESB_CONST_PIPE_COUNT. - * - * @retval The number of packets in the TX FIFO for the pipe. - */ -uint32_t nrf_esb_get_tx_fifo_packet_count(uint32_t pipe); - - -/** - * @brief Get the number of packets residing in the RX FIFO on a specific - * pipe. - * - * @param pipe The pipe for which to check. This value must be < NRF_ESB_CONST_PIPE_COUNT. - * - * @retval The number of packets in the RX FIFO for the pipe. - */ -uint32_t nrf_esb_get_rx_fifo_packet_count(uint32_t pipe); - - -/** - * @brief Flush the RX FIFO for a specific pipe. - * - * Delete all the packets and free the memory of the TX FIFO for a - * specific pipe. - * - * Note that it is not allowed to flush a TX FIFO when - * ESB is enabled. - * - * @param pipe The pipe for which to flush. This value must be < NRF_ESB_CONST_PIPE_COUNT. - */ -void nrf_esb_flush_tx_fifo(uint32_t pipe); - - -/** - * @brief Flush the RX FIFO for a specific pipe. - * - * Delete all the packets and free the memory of the RX FIFO for a - * specific pipe. - * - * @param pipe The pipe for which to flush. This value must be < NRF_ESB_CONST_PIPE_COUNT. - */ -void nrf_esb_flush_rx_fifo(uint32_t pipe); - - -/** - * @brief Get the total number of transmission attempts - * used for sending the previous successful packet. - * - * The value applies to the packet for which the latest - * nrf_esb_tx_data_sent callback was made. - * - * @return The number of transmission attempts for the - * previous transmitted packet. - */ -uint16_t nrf_esb_get_tx_attempts(void); - - -/** -* @brief Specify that the previous used 2 bit packet ID (PID) shall be reused for -* a given pipe. -* -* This function can be used for continue retransmitting a packet that previously failed -* to be transmitted. - -* Example: -* 1. Upload initial packet: -* nrf_esb_add_packet_to_tx_fifo(PIPE_NUMBER, my_tx_payload, TX_PAYLOAD_LENGTH, NRF_ESB_PACKET_USE_ACK); -* 2. If the initial packet fails to be transmitted, specify the PID to be reused: -* nrf_esb_reuse_pid(PIPE_NUMBER); -* 3. Continue re-transmission of the packet by re-uploading it to the TX FIFO: -* nrf_esb_add_packet_to_tx_fifo(PIPE_NUMBER, my_tx_payload, TX_PAYLOAD_LENGTH, NRF_ESB_PACKET_USE_ACK); -* -* @param pipe is the pipe for which to reuse the PID. -*/ -void nrf_esb_reuse_pid(uint32_t pipe); - -/** @} */ - - -/******************************************************************************/ -/** @name Configuration functions - * - * Configuration 'set' functions may only be called while ESB is disabled. The - * new parameter comes into effect when ESB is enabled again. - * - * Configuration 'get' functions may be called at any time. - * - * @{ */ -/******************************************************************************/ - - -/** - * @brief Set the mode. - * - * @param mode The mode to be used. - * See nrf_esb_mode_t for a list of valid modes. - * - * @retval true if the mode was set properly. - * @retval false if the mode is invalid. - */ -bool nrf_esb_set_mode(nrf_esb_mode_t mode); - - -/** - * @brief Get function counterpart to nrf_esb_set_mode(). - * - * @return The current ESB mode. - */ -nrf_esb_mode_t nrf_esb_get_mode(void); - - -/** - * @brief Set the base address length. - * - * @param length The base address length. - * - * @retval true If the address length was set. - * @retval false If the length was invalid. - */ -bool nrf_esb_set_base_address_length(nrf_esb_base_address_length_t length); - - -/** - * @brief Get function counterpart to nrf_esb_set_base_address_length(). - * - * @return The current base_address length. - */ -nrf_esb_base_address_length_t nrf_esb_get_base_address_length(void); - - -/** - * @brief Set the base address for pipe 0. - * - * The full on-air address for each pipe is composed of a multi-byte base address - * and a prefix address byte. - * - * For packets to be received correctly, the most significant byte of - * the base address should not be an alternating sequence of 0s and 1s i.e. - * it should not be 0x55 or 0xAA. - * - * @param base_address is the 4 byte base address. The parameter is - * 4 bytes, however only the least L significant bytes are used, where L is - * set by nrf_esb_set_base_address_length(). - * - * @retval true if base_address_0 was set. - * @retval false if ESB was enabled. - */ -bool nrf_esb_set_base_address_0(uint32_t base_address); - - -/** - * @brief Get function counterpart to nrf_esb_set_base_address_0(). - * - * @return Base address 0. - */ -uint32_t nrf_esb_get_base_address_0(void); - - -/** - * @brief Set the base address for pipes 1-7. - * - * Pipes 1 through 7 share base_address_1. @sa nrf_esb_set_base_address_0. - * - * @param base_address is the 4 byte base address. The parameter is - * 4 bytes, however only the least L significant bytes are used, where L is - * set by nrf_esb_set_base_address_length(). - * - * @retval true If base_address_1 was set. - * @retval false If ESB was enabled. - */ -bool nrf_esb_set_base_address_1(uint32_t base_address); - - -/** - * @brief Get function counterpart to nrf_esb_set_base_address_1(). - * - * @return Base address 1. - */ -uint32_t nrf_esb_get_base_address_1(void); - - -/** - * @brief Set the address prefix byte for a specific pipe. - * - * Each pipe should have its own unique prefix byte. - * - * @param pipe The pipe that the address should apply to. This value must be < NRF_ESB_CONST_PIPE_COUNT. - * @param address The address prefix byte. - * - * @retval true If the address prefix byte was set. - * @retval false If ESB was enabled or if the pipe was invalid. - */ -bool nrf_esb_set_address_prefix_byte(uint32_t pipe, uint8_t address); - - -/** - * @brief Get function counterpart to nrf_esb_set_address_prefix_byte(). - * - * @param pipe the pipe for which to get the address. This value must be < NRF_ESB_CONST_PIPE_COUNT. - * @param out_address is the pointer in which to return the address byte. - * - * @retval true If the value was set. - * @retval false If ESB was enabled, or the pipe was invalid, - * or the out_address pointer was NULL. - */ -bool nrf_esb_get_address_prefix_byte(uint32_t pipe, uint8_t* out_address); - - -/** - * @brief Set which pipes the node shall listen on in PRX mode. - * - * This value is a bitmap, and each bit corresponds to a given pipe number. - * Bit 0 set to "1" enables pipes 0, bit 1 set to "1" enables pipe 1 - * and so forth. - * The maximum number of pipes is defined by NRF_CONST_ESB_PIPE_COUNT. - * - * @param pipes A bitmap specifying which pipes to monitor. - * - * @retval true If the bitmap was set. - * @retval false If ESB was enabled. - */ -bool nrf_esb_set_enabled_prx_pipes(uint32_t pipes); - - -/** - * @brief Get function counterpart to nrf_esb_set_enabled_prx_pipes(). - * - * @return Bitmap holding the current enabled pipes. - */ -uint32_t nrf_esb_get_enabled_prx_pipes(void); - - -/** - * @brief Set the retransmission delay. - * - * The retransmission delay is the delay from the start of a packet - * that failed to receive the ACK until the start of the retransmission - * attempt. - * - * The minimum value of the retransmission delay is dependent of the - * radio data rate and the payload size(s).(@sa nrf_esb_set_datarate()). - * As a rule of thumb, when using 32 byte payloads in each direction (forward and ACK): - * - * - For NRF_ESB_DATARATE_2_MBPS the retransmission delay must be >= 600 us. - * - For NRF_ESB_DATARATE_1_MBPS the retransmission delay must >= 900 us. - * - For NRF_ESB_DATARATE_250_KBPS the retransmission delay must be >= 2700 us. - * - * @param delay_us The delay in microseconds between each - * retransmission attempt. - * - * @retval true If the retransmit delay was set. - * @retval false If ESB was enabled. - */ -bool nrf_esb_set_retransmit_delay(uint32_t delay_us); - - -/** - * @brief Get function counterpart to nrf_esb_set_retransmit_delay(). - * - * @return The current retransmission delay. - */ -uint32_t nrf_esb_get_retransmit_delay(void); - - -/** - * @brief Set the maximum number of TX attempts - * that can be used for a single packet. - * - * @param attempts The maximum number of TX attempts. - * 0 indicates that a packet can use a infinite number of attempts. - * - * @retval false If ESB was enabled. - */ -bool nrf_esb_set_max_number_of_tx_attempts(uint16_t attempts); - - -/** - * @brief Get function counterpart to nrf_esb_set_max_number_of_retransmits(). - * - * @return The current number of maximum retransmission attempts. - */ -uint16_t nrf_esb_get_max_number_of_tx_attempts(void); - - -/** - * @brief Set the Radio Frequency (RF) channel. - * - * The valid channels are in the range 0 <= channel <= 125, where the - * actual centre frequency is (2400 + channel) MHz. - * - * @param channel The RF Channel to use. - * - * @return false If ESB was enabled. - */ -bool nrf_esb_set_channel(uint32_t channel); - - -/** - * @brief Get function counterpart to nrf_esb_set_channel(). - * - * @return The current RF channel. - */ -uint32_t nrf_esb_get_channel(void); - - -/** - * @brief Set the radio TX output power. - * - * @param power The output power. - * - * @return false If the output_power was invalid. - */ -bool nrf_esb_set_output_power(nrf_esb_output_power_t power); - - -/** - * @brief Get function counterpart to nrf_esb_set_output_power(). - * - * @return The output power. - */ -nrf_esb_output_power_t nrf_esb_get_output_power(void); - - -/** - * @brief Set the radio datarate. - * - * @param datarate Datarate. - * - * @retval false If the datarate was invalid. - */ -bool nrf_esb_set_datarate(nrf_esb_datarate_t datarate); - - -/** - * @brief Get function counterpart to nrf_esb_set_datarate(). - * - * @return The current datarate. - */ -nrf_esb_datarate_t nrf_esb_get_datarate(void); - - -/** - * @brief Set the CRC length. - * - * The CRC length should be the same on both PTX and PRX in order - * to ensure correct operation. - * - * @param length The CRC length. - * - * @retval false If ESB was enabled or the length was invalid. - */ -bool nrf_esb_set_crc_length(nrf_esb_crc_length_t length); - - -/** - * @brief Get function counterpart to nrf_esb_set_crc_length(). - * - * @return The current CRC length. - */ -nrf_esb_crc_length_t nrf_esb_get_crc_length(void); - - -/** - * @brief Set whether start/stop of external oscillator (XOSC) shall be handled - * automatically inside ESB or manually by the application. - * - * When controlling the XOSC manually from the application it is - * required that the XOSC is started before ESB is enabled. - * - * When start/stop of the XOSC is handled automatically by ESB, - * the XOSC will only be running when needed, that is when the radio - * is being used or when ESB needs to maintain synchronization. - * - * It is required that the XOSC is started in order for the radio to be - * able to send or receive any packets. - * - * @param xosc_ctl setting for XOSC control. - * - * @retval true if the parameter was set. - * @retval false if Gazell was enabled or the xosc_ctl value was invalid. - */ -bool nrf_esb_set_xosc_ctl(nrf_esb_xosc_ctl_t xosc_ctl); - - -/** - * @brief Enable dynamic ACK feature. After initialization this feature is disabled. - * - * The dynamic ACK feature must be enabled in order for the @b packet_type - * parameter in the nrf_esb_add_packet_to_tx_fifo() function to have any effect, - * or for the ACK bit of received packets to be evaluated. - * - * When the dynamic ACK feature is disabled, all packets will be ACK'ed. - */ -void nrf_esb_enable_dyn_ack(void); - -/** - * @brief Disable dynamic ACK feature. - * - * @sa nrf_esb_enable_dyn_ack() - */ -void nrf_esb_disable_dyn_ack(void); - - -/** - * Get function counterpart for nrf_esb_set_xosc_ctl(); - * - * @return The XOSC control setting. - */ -nrf_esb_xosc_ctl_t nrf_esb_get_xosc_ctl(void); - - -/** @} */ -/** @} */ -#endif diff --git a/components/properitary_rf/esb/nrf_esb_constants.h b/components/properitary_rf/esb/nrf_esb_constants.h deleted file mode 100644 index 2a9be62..0000000 --- a/components/properitary_rf/esb/nrf_esb_constants.h +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright (c) 2012 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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. - * - * $LastChangedRevision: 32956 $ - */ - - -/** - * @file - * @brief Enhanced ShockBurst constants and default values. - * - * NOTE! Changing values here has no effect. They are only provided as a reference. - */ - -#ifndef NRF_ESB_CONSTANTS_H__ -#define NRF_ESB_CONSTANTS_H__ - -/** - * @addtogroup esb_02_api - * @{ -*/ - - -/*****************************************************************************/ -/** @name Hardware resources used by Enhanced ShockBurst */ -/*****************************************************************************/ -#define NRF_ESB_HIGH_IRQ_PRIORITY 0 ///< Interrupt priority the ESB timer and the radio -#define NRF_ESB_LOW_IRQ_PRIORITY 1 ///< Interrupt priority for ESB callback functions. - -#ifndef USE_SD_HW_RESOURCES -#define NRF_ESB_SWI_IRQn SWI0_IRQn ///< Software interrupt # used for callback functions. -#define NRF_ESB_SWI_IRQ_HANDLER SWI0_IRQHandler ///< Software interrupt handler used for callback functions. - -#define NRF_ESB_TIMER NRF_TIMER2 ///< Timer to be used as flywheel timer. -#define NRF_ESB_TIMER_PERPOWER_Msk POWER_PERPOWER_TIMER2_Msk ///< PERPOWER mask for the timer. -#define NRF_ESB_TIMER_IRQn TIMER2_IRQn ///< Interrupt # for the timer. -#define NRF_ESB_TIMER_IRQ_HANDLER TIMER2_IRQHandler ///< Interrupt handler for the timer. - -// In addition, ESB uses the radio peripheral and radio interrupts. - -/* - * PPI configuration - */ -#define NRF_ESB_PPI_EEP0 (NRF_PPI -> CH0_EEP) ///< ESB PPI event endpoint 0. -#define NRF_ESB_PPI_TEP0 (NRF_PPI -> CH0_TEP) ///< ESB PPI task endpoint 0. -#define NRF_ESB_PPI_EEP1 (NRF_PPI -> CH1_EEP) ///< ESB PPI event endpoint 1. -#define NRF_ESB_PPI_TEP1 (NRF_PPI -> CH1_TEP) ///< ESB PPI task endpoint 1. -#define NRF_ESB_PPI_EEP2 (NRF_PPI -> CH2_EEP) ///< ESB PPI event endpoint 2. -#define NRF_ESB_PPI_TEP2 (NRF_PPI -> CH2_TEP) ///< ESB PPI task endpoint 2. - -#define NRF_ESB_PPI_CHEN_MSK_0_AND_1 (0x03) ///< Channel enable/disable mask for PPI endpoint 0 and 1. -#define NRF_ESB_PPI_CHEN_MSK_2 (0x04) ///< Channel enable/disable mask for PPI endpoint 2. -#else -#define NRF_ESB_SWI_IRQn SWI1_IRQn ///< Software interrupt # used for callback functions. -#define NRF_ESB_SWI_IRQ_HANDLER SWI1_IRQHandler ///< Software interrupt handler used for callback functions. - -#define NRF_ESB_TIMER NRF_TIMER0 ///< Timer to be used as flywheel timer. -#define NRF_ESB_TIMER_PERPOWER_Msk POWER_PERPOWER_TIMER0_Msk ///< PERPOWER mask for the timer. -#define NRF_ESB_TIMER_IRQn TIMER0_IRQn ///< Interrupt # for the timer. -#define NRF_ESB_TIMER_IRQ_HANDLER TIMER0_IRQHandler ///< Interrupt handler for the timer. - -// In addition, ESB uses the radio peripheral and radio interrupts. - -/* - * PPI configuration - */ -#define NRF_ESB_PPI_EEP0 (NRF_PPI -> CH8_EEP) ///< ESB PPI event endpoint 0. -#define NRF_ESB_PPI_TEP0 (NRF_PPI -> CH8_TEP) ///< ESB PPI task endpoint 0. -#define NRF_ESB_PPI_EEP1 (NRF_PPI -> CH9_EEP) ///< ESB PPI event endpoint 1. -#define NRF_ESB_PPI_TEP1 (NRF_PPI -> CH9_TEP) ///< ESB PPI task endpoint 1. -#define NRF_ESB_PPI_EEP2 (NRF_PPI -> CH10_EEP) ///< ESB PPI event endpoint 2. -#define NRF_ESB_PPI_TEP2 (NRF_PPI -> CH10_TEP) ///< ESB PPI task endpoint 2. - -#define NRF_ESB_PPI_CHEN_MSK_0_AND_1 (0x300) ///< Channel enable/disable mask for PPI endpoint 0 and 1. -#define NRF_ESB_PPI_CHEN_MSK_2 (0x400) ///< Channel enable/disable mask for PPI endpoint 2. - -#endif - -#define NRF_ESB_CONST_PIPE_COUNT 8 ///< Number of TX pipes (at least one for each Device-Host pairs). -#define NRF_ESB_CONST_FIFO_LENGTH 3 ///< Maximum number of packets allowed in a TX or RX FIFO. -#define NRF_ESB_CONST_MAX_TOTAL_PACKETS 6 ///< Maximum number of packets available for reservation at any one time. -#define NRF_ESB_CONST_MAX_PAYLOAD_LENGTH 32 ///< Maximum allowed payload length in bytes. -#define NRF_ESB_CONST_CALLBACK_QUEUE_LENGTH 10 ///< Maximum number of notifications allowed in the callback queue. -/** @} */ - - -/*****************************************************************************/ -/** @name Constant pipe and FIFO configuration */ -/*****************************************************************************/ -#define NRF_ESB_CONST_PIPE_COUNT 8 ///< Number of transmission pipes (at least one for each Device-Host pairs). -#define NRF_ESB_CONST_QUEUE_LENGTH 3 ///< Maximum number of packets allowed in a TX or RX queue. -#define NRF_ESB_CONST_MAX_TOTAL_PACKETS 6 ///< Maximum number of packets available for reservation at any one time. -#define NRF_ESB_CONST_MAX_PAYLOAD_LENGTH 32 ///< Maximum allowed payload length in bytes. -#define NRF_ESB_CONST_CALLBACK_QUEUE_LENGTH 10 ///< Maximum number of notifications allowed in the callback queue. - -/** @} */ - -/*****************************************************************************/ -/** @name Default parameters */ -/*****************************************************************************/ - -/* -Corresponds to Legacy nRFgo SDK ESB addresses: -Address pipe 0 {0xE7, 0xE7, 0xE7, 0xE7, 0xE7} -Address pipe 1 {0xC2, 0xC2, 0xC2, 0xC2, 0xC2} -Address pipe 2 {0xC3, 0xC2, 0xC2, 0xC2, 0xC2} -Address pipe 3 {0xC4, 0xC2, 0xC2, 0xC2, 0xC2} -*/ - -#define NRF_ESB_DEFAULT_BASE_ADDRESS_0 0xE7E7E7E7 ///< Default base address 0. -#define NRF_ESB_DEFAULT_BASE_ADDRESS_1 0xC2C2C2C2 ///< Default base address 1. -#define NRF_ESB_DEFAULT_PREFIX_BYTE_0 0xE7 ///< Default prefix address pipe 0. -#define NRF_ESB_DEFAULT_PREFIX_BYTE_1 0xC2 ///< Default prefix address pipe 1. -#define NRF_ESB_DEFAULT_PREFIX_BYTE_2 0xC3 ///< Default prefix address pipe 2. -#define NRF_ESB_DEFAULT_PREFIX_BYTE_3 0xC4 ///< Default prefix address pipe 3. -#define NRF_ESB_DEFAULT_PREFIX_BYTE_4 0xC5 ///< Default prefix address pipe 4. -#define NRF_ESB_DEFAULT_PREFIX_BYTE_5 0xC6 ///< Default prefix address pipe 5. -#define NRF_ESB_DEFAULT_PREFIX_BYTE_6 0xC7 ///< Default prefix address pipe 6. -#define NRF_ESB_DEFAULT_PREFIX_BYTE_7 0xC8 ///< Default prefix address pipe 7. -#define NRF_ESB_DEFAULT_BASE_ADDRESS_LENGTH NRF_ESB_BASE_ADDRESS_LENGTH_4B ///< Default on-air base address length. -#define NRF_ESB_DEFAULT_CRC_LENGTH NRF_ESB_CRC_LENGTH_1_BYTE ///< Default CRC length. -#define NRF_ESB_DEFAULT_ENABLED_PRX_PIPES 0xFF ///< Default enabled RX pipes. -#define NRF_ESB_DEFAULT_MAX_NUMBER_OF_RETRANSMITS 15 ///< Default number of retransmits. -#define NRF_ESB_DEFAULT_OUTPUT_POWER NRF_ESB_OUTPUT_POWER_0_DBM ///< Default TX output power. -#define NRF_ESB_DEFAULT_DATARATE NRF_ESB_DATARATE_2_MBPS ///< Default datarate. -#define NRF_ESB_DEFAULT_RETRANSMIT_DELAY 600 ///< Default retransmit delay. -#define NRF_ESB_DEFAULT_CHANNEL (10) -#define NRF_ESB_DEFAULT_XOSC_CTL NRF_ESB_XOSC_CTL_AUTO ///< Default setting for controlling the XOSC - -/** @} */ - -/** @} */ - -#endif diff --git a/components/properitary_rf/esb/nrf_esb_resources.h b/components/properitary_rf/esb/nrf_esb_resources.h deleted file mode 100644 index 16293c7..0000000 --- a/components/properitary_rf/esb/nrf_esb_resources.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. - * - * The information contained herein is property of Nordic Semiconductor ASA. - * Terms and conditions of usage are described in detail in NORDIC - * 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 NRF_ESB_RESOURCES_H__ -#define NRF_ESB_RESOURCES_H__ - -#include - -#ifndef ESB_ALTERNATIVE_RESOURCES - #define ESB_PPI_CHANNELS_USED 0x00000007uL /**< PPI channels utilized by ESB (not available to th spplication). */ - #define ESB_TIMERS_USED 0x00000004uL /**< Timers used by ESB. */ - #define ESB_SWI_USED 0x00000001uL /**< Software interrupts used by ESB */ -#else - #define ESB_PPI_CHANNELS_USED 0x00000700uL /**< PPI channels utilized by ESB (not available to th spplication). */ - #define ESB_TIMERS_USED 0x00000001uL /**< Timers used by ESB. */ - #define ESB_SWI_USED 0x00000002uL /**< Software interrupts used by ESB */ -#endif - - - -#endif /* NRF_ESB_RESOURCES_H__ */ diff --git a/components/properitary_rf/gzll/arm/gzll_arm.lib b/components/properitary_rf/gzll/arm/gzll_arm.lib deleted file mode 100644 index 4a5e607acbb5989d7fb60c4bc701f05642c0fd9f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145794 zcmeFa3t$x2c{Y4zceUEpbtQ2TAn@n{EEw=g2#^SNbVJ_7U@&0ENl12A(!#D0(neZ9 z*p34>POzP(ZsMj+>$W6KQj$9P9oMu@YZ~I%DM{0>3%IFs{ggDV-Nfndv~EIOfARmk z?>T37W~3G1%in%!kF;~ndp+-Y&vjrns!%mzN8p*za%e6vltT z&og^KT+(mF^}-{6@py84UpyXfYmJYL?T!zolOrRk;rPDfNODhVEIt@t+cuaQXxqIG zJn`)tZ)#mDE>~nnR7lnP;;D($;Qm}HKAsubGn|U&GJ|`k&$D2oJh}#3BV6gbGrLErrgul$Q^~e9 zQ)_xgK2&culSQ58lDYlkLMj^_$)U!^Me;y0Gn^biU1yVndsD#3IG!CH9iBps501ix zTm)9LdwBo2bf5&sQd&=ehZ=}G7q=ebQTe)Zu-X7;kR8n`zJmVjel1(Tjir)9Qy9lm zjv8f2Rhdc#hEaa8crUH!*Q1);O>I0Gbm?XRL4+-TMkrcC0QakOf9B{fuV zifpNSZbf#3@nlDGcWO<0s%T4{o)6AQj-!%LCaaw>XKHM06l2}!5c=O}F0(r`n9OC+ zw+08;FeQ{hn;siU!T=O{0L__+tROk0+e17z8qZC{sW}zMgTtxh7>{=DoQE>w)H@2S zsSzimxUMxlH;j3 z3dLNJ8ECCenw~y#&O(q%2MH6vt*$JGl4upwOdW;{r4D2U(Nxv6G@cqx4RY0FM~5?m zhn&pzYP6Tes<@%l!2Ug|p6v|#k`q*E$y_eAFN-nCVZuIc7It=31G-jRjfn~i4jL23 zoPj=~K4Va1eAOq60>XbR2Ng@~q` zx~mHjX=)c??4@=QVlLX!ndoTggel&RiCUx`6G^u>YLSliY9|(HuSHod-dK?@rAORs1`V0V$1E132gfpsz{c8JI3sM+lnsuLjgM!z7c+9|#AHL;Cnkw@t?n2} zV_#u)Cl_gIAxVR@#pCF0!>N%yIk|4M7<9Lqb_OYMjbUJ(M%vNyEba`}OVaO|+#y|u z4zsAc(a3oaEyz8=SZb^Z#=`J=I^q~Y3SK3b$jPOZhQM_*vAO1VD+4`)sYd9qdD=d2 zNlxwa7HPUZKZWS%^Rh#uxmmN$rSQ9Fs)CG~f2J!Hyk8g$Y=Yz&37vx3rt1_$DBkdiTBP9?%EhMCuzPe2=NR@mPU5YxK!WfwrU9iu;oKs*hzK&NvG~*)gmM zV7r=aGb1=t)Shiy%bsx;r`VM! zC+J3_lvw=(V(v+iP_8Kvs3{Yo#<{#qr)RcnX)3>QTt&gf5Omi#xrrwPtbm9W7YVez zH1thhXcP-QFaHV}po4+&xG80HQ*u~t1(?(nWnPM28SKA3W)EZ)(E)2G$R>H4|6<8Vw_o4A8U1{Wu2EtBLVGxv92*j4SGjIXUhKYPYwJ37=Q2@76{%NIYLr?v zdKIG`Bb|%p9M`mjtQ%GF8tE!1q06qan+RK4S9f+sR=2HbYcoyzJ=E4nWbN9urrEi= zyGJ4(J-+iEU_6Yu za4ObtL&8iS>G}8b?`sg|+{Cs-GX3j4|8hQ*xNs_atm_D5D+Lb+}`5r~-ji^X#dyQz9l@6Ws3C~$6>5Ga+U&0qP65WZ=DIsthk4r~- zz}H^_9bM_;J)UQMoRc@|V?JW~B6#h5!ok;P@jb2hAR7~~8ye@6T@*-Zx&q}n-V@3%+yvbDR#;OpuQk0Ly3F}qi|(Bt?G4o%`L21; z*>VaTvsfwuYaWL+wG357yVIY6HD81^h|dkf8sg}h-#2e{+U%d7zG426p6@;T_H=B~ z4ZQ)<#UZV1BU{PN?8&MvzW%WCZ-pwUk^Xp3W&Y#HdpYcyHE%iSXpi#~uy0#$eSP+n zF!4js`lNPwj39ay!J8c0H#m5uFmA7^trVrA)F}0odIP>dNx&Z{4Fm$gKv|%?v?72# z1Qj*~R3C4IjP{Abznr*7I^cgIoBhYWFPIs#M5umn0TO;+aLV9S3P>E60q zkCxo+d%yPsWW`Ln0-iv@r&H{JYcI==dYc^^knXO#{iyG5@B1&^7gNjA!+I{YJoYv+ zRo91Jr!IT>%-2!A%WW?KW9EAD!fZ(kC+Ar3UcG8poUPrpCwXgX zczD;e>k6`G1-vGmviN$FsJ z=f-Q}V1`3R_w9}kjEx=~PhFA^2gi1smQ!5qW7>{2$gRnBs4TG~4B>=5F4!x|z)$n3 z3|<%A$8?%AW$?M^B}_LpS(Lcwex}p-D}&!fFLlvNUGxCc<iym~*%Utv_ z7rmV6G>^+r?xI&Po#t2>DqQqRrqjGBL#2ye#dMnMWvCLrqy?B2s$K9R@mDswPyFoF zFDaNJFV>WQ?11SEM}|H`UJ=rukZ_GSs`!aO`sUbR;W300_J|8!O9k|K#rtir@OZ_D z4faB#lkOAS9P|Y|s5UlxiC>jEx%Kz!Rl54z|<@#hYDnTuW~ zKI)*CyXfU&w}W2cqF0D!2fflouN41Bo_?{Dy`suRuM)pdbXv1}MYW4wEnZY~szw9! ze*#SDfP(Wj{f4L&f9ini#P2%bS>i4SJX>TO@Eoz#0nZg{9B{o@;DF}|+bKHin=hV& zT{;+If%t0;AT~sU_+tmWkRd~OY7c{o;Pa6`w*Wy9p)gq0qK&-l5njoWB?=EwwH}}h z6QzdlO1AU)zaP*l1Flq%@YafIj~}W^!9_j>LjZW+o$3VicKLHk4zYDRPYt@oYvDVL_6_a zrQjX~FII4`f|n{7%9($Sf;TGoEeh^e@Hz$Kng;WCDj0=ic$tD@3T{;}3d{5>6?~n7 zvCxf>otqWB62K}fTvlOE)>vi$dxpows`1lD`ZtK_DI-Pm1`603m7tdeVP zT&Ja-#A;KndkbuFPJJ=my7{H|=1#ZU_BE)P!AQNvQ9Fm7%IV6h+cuXjJB!vOH$*#C z@daHc%6_3(m)xb@&N7qsY4}{4^fqv=pdvK;7V%X$Gvk^clqX1H70&nKIE9L*u@e{D z$yU*QYEpDyJRQdgT8`7LYh_w&&J47)Y)|1X)p)L@h0hfS=wf{;Igp9(&*0Pr=VF(5 zmDzR0TRWm~XUnx=9+$5#SA_T2qw&Z0jAi5Y_T93&1InhStSL%qD@JMSEJ~qW{?q2u zwz?=KQjF5Nt|+CwD5bR+rKk(m@I4XS8d1BcWTUvW;b3|$cXy-vp1e(ex}o4QRfr<| zdZ(*=c%Z;!@7q=fot~`Qr0n_y9`5!9(B4m{(P$?Z(>M)}tz6D--a{90x~<{7rDbPy zOFXut`@rfgEjwDaZEWdYzqzfg<>vL9TU%RpAQjuVabs&s>}@SK?%25FrnN11?AUo- z?{$3=Tn8|^xn(QuUvJsi)7{ased7%sE!(zl+|kjpvAZXBplupU?1RdiW6utpQY(WT zwp`|UY_XvXYUnxv|8%9Op=Vc-Q{t8(C`%6W2-z|uT5_WM7R;_Z_z8p7d|kpriwCc- z#9tZ+mX%jjR#l7MwpEd}qQtu3CHxgZqsFN9%<{}N>Wz8Ed}EQvgY||mJX6_-X`Zpj zhjoC!I3hf>dIw{bQEPZ+Psyy-0O~adgO))0l=>Q^vHbV=_#{B;Y~x5TH6HVjV<*)+8LHeTK*ZI;(J$rr^_ABke2)Lpc0D+C0jO)~!N3&qra9UpQz< z8Gm4wR!SnuL})hwLBz=n)*+h?CWZ+ivl2HLS^;~B=sS5Ct%ZDo>PZKvV-)X#pAFD*xDX^s z!dQDk$zu{gWp_A?lW4y4gEJA!AwYXqyrP>1o&4y4B{4!D`68fjGPlhN5|RUu{S=Rg zeWa&Pv)SUMQp5dpmZeR9hUi`>(+IhQw}CbVD#@(K-d2o|*sK-oV#5@TkeXmuM195z zKEcid=YtAo6iTPLY?+CrlUk|r24^AjF=VqVTz1obvK$AE29s5;0+~(dY_wvQDkwS4 zbmSm2(cJ813+uP6R>gDJEGtvVcWDi}Zx&!%N_*+3Y)hy=NA^~`(IS4T67C0#In8H} znn-aS9ax7Uo&v9br*7Cp5R|!;m7IN?cNdq!K70n!CudS<>4+jQyd+jH4#Q;9Px;t_ zNqqB2xAgV>PCGcy1uT`NEL_BX+#Z_ zG|_etNfVViHc%`iGKfC*L7pLIQ(S5^GC)9K5GLv3l9!Ww2-WEE)P^jOXA5IFLF)x} zY822&Jy3ukNg2%Nn|8GI4I7zE3fA7G)zj}?>S$ks9ZVDwWf$AKbXs!k+VMcppi)zoIePyE@iYZ`_|2tLj^$k$Q1|Xr@jK#~o9~?1-f(C3&WXbf-sQ%5(d5YgNw*W_EGM|(VHn_03M zdvpBAr-`8}VyNh}SXS|^D>mIF&fok8J>IhmnNl^`)o}XJV?FUclmWB6rHF4$bsZ?d)XSZ`xmnDy6-W#!+x zQ#^X}XJPAXm#wvyt$$>*wTijSbY<+Yh}?{QS9!TF3H!Cg{%u_iW{GDU#WknKAHV^_Uz8ChEVwD=SAcEEeo#ueoI+@liAbzA+c@VgEu_9voCuz z`&8EVp1$`Sea}*Sw`m+9I=g*hK{AM7LeM0WKA|H{zC}dBH#XfE~)m+AesERe! zAKN9ub@>XjueUtfT)(aU=)@<*!nYrt7-~40JxVQP1zJe6H+yUsTFB0DfA$pB2?eSn z+Rp`@%RJ}Ro-1x6{(fpD3$0et;PU*usAy_xyrH+8Tgmo@bC3F$|6J|AN{hNp%j&o7 z@`h)ft1vhA)QI>KDvRS_X8ry_4I$w zJ~6q+izfs!9^oi{-F5Fh>b=|Ze#6sMC!Tuxt6|{mWtwTvnOZ-QDzOW{*Sgoru4m+R z=&_gWgRJMZ@7c236nz~w&4R2B)UPjZU!L4QW@-h9C-Lj9yRERduDfo+v#;*9%c(cJ zO;pa;Vp9d=bkJwT|2_6z$rTFro?Lvx)#}dnU+oQ7RKPZF2KupuRippOyR5A0nPF=c z^Zd_#s>|O`#g21qq9P1mCYB^UBsgNPI)jo(Y!q<7*ks^X=%U?83!Ez{%M|& z!RMmmgaq`XnvBaIPI-)0pwpNxgWp9jWjf6tGL*XL0jASfETf78iA7P$W86~AYLX@8TG?h_w!&`VtO5;5VR z`(1Ru7;w-_UG!3Mor4~5(F3B@K@Ym8Jfe zFVSLD1q0XfzU_c#iPH{vw)nIIo+Cc!fai)a2V5_1vccGW=(49$L>%;L7rmO!lMS?b z9BWZq%uEL#OvgT+Ngdo`e1VFZ;3 zX95;^VTqB3Xd+ewS}T=pl{Zf)-mT!Aia(^{$5i}v75@maXO+COL-7TI$<6Q;!E_Ev zah2j3da7Y*S8;uCS3WXuTOSj-8dGfdbUu$UdlyxJs>-UT6jO5i$o9Qst1VO zl)}sJTol)KAvVzd9JGs_pPR-mtxMapGcb;wU6-|S=hB`AEwX<_uY9>K93H+Dfx@e3 z9HI)C_ML|AHzM*=%k+S#{gr<+y@%1ZfoR6}Fk;t`+}mL_pd!|~xEv)Z;)MUwyMEN> zFKS4(qPcpAgHq@nHngp0*s+CPVZ+*X(oE?MZ_d7wi|=!hhVUCR-y9Pzy0wKYu%BHN z>(+V$3&kvB7n)|fN*aT&bGr(Lb*!`1c9qIEYO~5xXq~cIg>Kl|v%2i9Dtl-` z{l9Dk5_TEMDkYznr!Nu^;&!6_Ei*uZGQ)NfYhgtYZyWcEKd1D=co3apmvR>46OY@q zUShFaMIu5R7vfG%fHOzs_CL-bADkK$WIarA6Fce|8xyTN5TJ#SSU@1y$h2T0gMcE7 z?AwQklfptVR6#LVVxorD6F$GG_Nx${DKbGvE(}(r1&mCshbEPAMU(@50miA;tTSYs(!xH5HWeQx8h%|Wg958@ zRG~Op2ZC(JS^?0jnH%RpSBJ2J;VK)2Z7;#C=mg(ymiLcCd}l;FWN`NjIM~S^zPYUK zZp*xV;uU22D%zjaKv-He3!lm6pha-_2_2PqjpVHdhWEr+k~=lWSy>Qy7TKjwCgGo9 zGD)iWQ>0`dc?f`1Lpmjd<(oPLvQ*P{8M*k`~gO3Ox&G#iy_$jNu(jD^jHK@i?dASdFn#*qz?*ouS$-q{`?r#j#2O# znzm%oJ)En$AdmSZi=mJM_tBL|%Fc=eHDf*-QEvvPeH0hlL$PjME8Yx4;o^HJ!m?7V zJrt{P224X4m00hg=vpMcH2vSt&eEOpUz{xM7cGXlDkglh`;R47UjN912z&A?_};6y z%5(NgPG!@CUB>Bf|G|W@bmoh!u|!=|EG|jZZcdPWXXQSPPh|(wp{UW6O7tYE@m3U( z{!QQA_|`zSWbz0~AgxPeAG{X#wqXP11=ougC|~4BHi&5U+9=W# z6CL-fC-i$_vL|bz#^Q~MrxT&;MayHzZ6khN>??V1U6_@z)4j(Mm3Tvq&x|B1qJ4>y zY#;Ve1ZJ1T0txydZ_m+R@-4$SuXW{ zdlYh)cE5e*_jXiWvJGGJ9kX$ZLJL8jBZ zDMQdjFJn5*hccA8=;cf|HCdFq=oPN~E5!eH__NXl&li7Yqtku*&nuXGK=Ay|}95q?d>-4!Yk(_lt;wUh1Nk((PX>(0fUo`tcqc2R-Pb2gS?QnG)Gw=Axti z9rSV+y_;W~5-O~?m6%r2+K?U3} z7q>a!T9I_Xb>dnFJWH%}z_Uf21D+%PT`Nay;K7Ig?SSjW(+(InR3D&5N39Qv z$s{AqrJ!?N;87s5UwAgili!-krGy9CYv!v`@dWz@r|RU}m(~3UELe+Yr#Pk>E~%3yjcGW|WIs^QV02m<)s3^A*5@ zOJ+_e3Lf=1Na6J$#L*=8`<88!@A;sZ*83E1Qt^n2A5-xe#2(x)rhUT1w@bm)9tcmK zBm9tpXQ{YF#hR~!;0D)yY+QucKzJx;I+QWIK;2iyHQ;ul3NHSuTn6Wnck}4 zs}+2ug0E5VY6W9U2J<&7xJ$vPP1fJ7;AIN#QSf49{<_|?K_B;Wf3(YXKbXJvh3|X0 zQS>@_C(eD78ItsLx%DM6$vyRRWfD*Kgvk{Bj&{6eZunAfL96?EDnr*-&78z3-$PrK z+BZ;m;l!oCeBx5?Vaty*Udm_Q^h+i#%4_?A<4nACY0CC(y6ImA@vHU%3H8!=`taMq zWF|*1g~Vsz@Ja^$GM@c~64SN&LR;Z)+Sx&B?*-U?``F#i3tZIvFRwLbR!!|6Z_d5o znQuo=+Z*2;LoR+(y2z6H;yu@Kn_6peugov$b~R=bq3>2#R9@n%6)>e?V#LbK{R#&C zZUv0(@^*El;^dbr(By2(>oRUvZ`c7*cTkfr-Js@$g1p6cE!gDi0lKt+WMm%6Sa<;5 z08QaEH)2d_i)j5X&jDUy%2#Z3OJu091Sp&@0QX1WxLM!lQ+ATPVY@L-iwA>dYSyO3 zpCUw&;5U56H!NC!Y)7D#%l({^2VIskb* zS_&2NVH&Nr9HHP-3HCA$>bQ-3}xLDpVPi7)7YjrH@Zx zl>&4u!Otj^9IwSI(5yPqjNmJfZMM-afWxfHCQM1mBaczGPMeIl=IOpx$P_V zLYI&%KZMyWHenA|s#bWBQX%|IT*~@(5Ozr|K2hC(BsH{P$Cq$)+-7E29;!u2NY~FF zN?{U`p#c%y1f(AY-v?lkR&(wgRi1)|Ew z8u>u71&(TZ<)RAJs4W+^IaZ#rr`s@F+9CN0nHqS`SBAKX9T7U4SLQ%ZZ>X+kany*P{UHHf3xh;f0{5%#Z8(Ua z&3+IETENr0p{G2bk1vQ!_id5Yt$3TdN#Wx6mLGf@TVUN={(CXWa}yO>-&?+L((7AL zRn;#(@|8#Nf>1hdZ<$-s)$^N=`mcQFx%uMOzS=_{uK%q*&#a|AZ{2`55ao@=ivDH3 ztNXEj>8@8s zmFnPfdm#~=23Ka`$R1DFcP`+-`1<|Xt_h?Sm9$|m|4>5RdQ5n>4VUzLR@}bMfx4-2e20)w8HzXQnQ|I65*13 zS)wGSE%RzT>A(;7(D}PHQm1GkKCZX0_pC8#w1`Phi`h^4*lD=j$ykyv>>)6sr)|1O zleSNU1K6Dr!0wDdUbY1f%0oZ$8JtfLu?Xk#S8wgQ4TW@FdP?{_?OmV*l{kRfdtcDk>^Ce~n>bH9GnyfKd%ITjzXPCt6 zoAmHb6(#qvK$p1R$CM`YwR_UBJJ6T%S45Yh?|LSQ>#F{Sn0WA>bZHl8CQ<97{;b(A zsp0<8u32g<^y2*?MDb3_yu$sJvC^)4@zxJ&ndxB9h5^+~(j z#pyMhKY?+@T<}z2U>=#7xos*RZ~0rd$fR|QAoX8iKUCOd z$4q;f>ygZ&|25U#|}8ix<;zvHn39+h1$jqBeW6 z{4dtW18;zi|0;I85q0`T==iVVk2k`OzF(pC@kaRLSE;}Jk3XCj+5i8Wt7m?8fZ7<1 zL-z9@ecthU=aZSfOH21D-kf~@v&#G0^QC!nCSR4oR}}txydO~BA-SaI5!S5z6@Nb< z6_Cz|?e~seb31rro<*>#XNKnxnCE|3OsU$}-+?V^X6 zt~Ws8YO#x6CXS?7z%wH()92b2q(`nrz!(11=-UZKd!Sh}A z%y-cjxZnmCywC+Na=}-)?7PB6H(hX}3vQC~*6sc#7rmM3h4$O*qPMu<#mrCFF=SZm zqAzjjTjHWGbMQJ`FJn5bvt(H2qAzDUt;=Ot?xJ7mqF?EvuV8vqi{t$* z&hcO+)9Jdh3@csqRZN$&8*!|1(XVplf0c_KVR~Wwin!>lF8Nj$z0E~$bJ173=&N1y zb{DG?{v{EP^@G5g8$ZujgI-C!v%M`;PozeOtjhL z>G`H53a0Hdv`cTk11@ZGr1N&KzylL1NO*$?y7c`{p)q2QqamEIN8Dqh)ALz#ZLq+; z+Y9_A4w(r(KjozR#NRpSB`$i2_;Ux{@1py~2?xE@MK2W}bF8UI2#z9}|qAwMna?ryrdRW}!pf7XLmx;X&`f?Y2 zx!B^MU+JP>DIyN~3KxBasCUp;y67v#KiO_9dNJQR`_C%zbqD<_7yT;nCk}eVMURM& zI_Rw~daF3(ptrf`ZQ>mc`f3+_wOHezx4Y==;(~4CuUD*b(btGc2Ys!JzE+%Z(AT-> z>%>evY=yOnGVe z9QbL7q#yBX{Y3ZT8&OVs){EOz{vd<@YBAt|uMtrP{8q8b0e6X64!B#qTsZlIz8*2@ zfP2MP9dMs`*a2@8A9ld~V!{DmE8gvZqoU6N$FNz4N+N@Sr$|E%_&V`(Ycn*JceD7e z1KuK@bimh(6ApN*_>cqMCUOq=2JsFDyj^rT;2mO#1Kuer9Po|eUkWD=uEFO%8aMc#8vm7dCro?~#ArElM14T>QAyPEUxxallFO zm;)XVA9KKi;tmHqBnBODN<?SO~H zeGYh^$U5K=aiaqs73&>vR$SqL-$Ty9+2JqnY&9Z$Vwb&z@9$FTZ}0#=mS;HKlW05{ z^d!-1I*HQ|pGW$>T69xVLF*=u_&)kAgkQ!U^D@GUZ{b%fO5{^MHJ=3p>?ty$MtB0` z9^#@<>-p>)ARokJi=Lc>ZiT=^#M} z@pph1)rc^?#xy`L+hYRW+Aabf@k4sQK0+0ZIS`MKh%iF*{KeCM03ZY;yD6kN@u<{& z(9uAnRA?83=8ytp>cNO1pIfh^m&(&H#!89opJiM@)~W*5qG5(+d$7lraJ6#?{eq~j zHRgJd@fqOcWe6BqkGJ4MOs$N-kIWI~8P$PWLe?67&;0i=jt|vr!uAE=42YFD`>p0D z+CdB8?fk}zB0wAC^@|FD!E@p$eua37u%0Uj!c+1_?eRJIzFVI#!CeKPaLr`dFjmkA zcO!Ctnn-C?voOfoT8v$!jZ)>1UQEuR3k3ms^((%sMb2M>@4bE<43%`I#55cX zzJ6Exhp446UaSu#%jh#)_b~@OSO@};4PyB|_BuNhxGRD4Y()V@WgER{HOg%BYe9m} zj+K-F1Yz?kA=enTbc-x2r z0bS%6bIP8EoIHmlMc{D`-7nefK7|J-@_`xrrUZ#>gCZ^oh=r?KL@OcdNjVonh=23R z601n!CpGzNBtrSp!+?(>rQd(ZNl5;#oWY3+k3Gpp2Bl^U06Q2h-v)6tRj3R!rRxlQ z^+-yJRxSISRPqlrs8EnBf8o`vKoJMPPZ3#hQQ{uvt@Vn%M6lS11nzBaoPt+d8bqzi zgee{jek8}%Q|5ncDWI}T8wfAM2MUY|0~-DhflZy@Kq}x%S79h0^G4inNe4cr`C8EBj^D725k%3 z&ksRCl;vK57HzVUAg%fmJCU?f@fF1&`9DpNw183v2wMOF^k~I;^imI}7MN(*g%xe0 zihSdt_i?CzG@D1`u_${dt&|Y&pcMhVU&G+{YY={n;O&O^kitJeG4Kyjd?VhkL-9^S zoS^tFg9qla5rbbZU51aQJWF`!n?&sS4h`Xmfuy=2crD_xTWBSRc*x-QeU$CO_ecmH zGx&X@Wj7f7J(04k$`|?`R`N8Kl0GUl*?SCe z4aK8|*iJF>xtU^=Z-8RtgW;U*WIb;$=xHMQI}CnfHR+|%qij%)%>=VONjXlI4H&{C zI`l^n6TMx}BtkZyYas7tO+wPsgk;uJk1geprv}<8rF$wnKdRt=Rq!Vj z{E~tnRq($l_zngCT*0?1_!kO(K*1Lj{C)-hyMm7?_+j@> zaH)cSTfqSZpHpy9!JklYnS%2QE?4kz1y?Bes|v1E@P`##rQi=LxLU!VRd7hbIR)1! z_#p*j^~(1DnS$|hFNQy);8_ZOOu@4ie7}O{DELnlJXgV4bh_8|{wCT35Ff{zW+q0* z2jhb|yftYoH7s93W6^RG@$Bfq)Y!DN%)Zq4@Mvy4o=uI#2l1|)k<@VfU^+E|*9RTQ z45s3v_~g*&?)dnjk-rHpgErayv?uSbJeSHJlpEW$+52?C5Z2@X&M?4JC8Qv1D%A z9JQVt**cx@Kyo}4PYw;?V>jdR){AmPrsGKN&yB{1GULVa(CYDOt=*Z4_`sp5w$itD za`DVaE;Tli97eql?B9d$T1|DMWK4~XjiRYcLm%B6hcU=eeWQvXxST!`<2F50v<_Ww z6601(?@}t(!iiR_g)16=TgUOCBv&tCzR?^Cj~9=P4x&D-BDlZbW!Xb*^fmV!&Tu*f zZa>)>i}W1HGPrljr^qZ*XY5xbezAU~crMA0)Ac`+zexWhmP=@Y#8$ik67@1WF^d%G z#6)v+;`n&x)+s%C3fFXXICEDg6%LLmU7a{Cp)2#p+luu$Nkm;w*C8?J4yJX#-90wC zj~c~vjB@C8m$AqQG&r0}j>U7CVy*LHV?}a&JT+!(81!Pmf#l#`o&9Jovpa+SN`v&^ zz@@%2a8==BW86om$#O;SkyFZnOMep}?YhhC%ep3E2i6*#oY?7lznpmOGw!9zWJcr+ zJuSZ;I2=Uhpx_`)84es&`%K~_@YLK&qy9QabLN+sSYF~!=tX8=;1R^3nZ^zpnGa%I zw$I@XCTl8oU>*I}X^19Gndcn}9Q|@QHL@p{E~s&Rrp^)^OW`ARx&v8Q`bM3e4+}_q zqHYQ&rbpGIh6-w`KL5SA{J?k zL@M4G6_sbD=}I+iLnR@(hMcjXYPNW>hDr?1hRT?WHB@4n+E595@zzLOg^xnoCgbr! z8?k@b)2d?Utl&aVX?t>jkB^OyX9{}NsBg*Y@tzPohNefyxvr>iaccgDSeR*!rYte? z+yZTKeE;AemcKS;i?lnLp*22UjhadhWa9f$`v$Xz#HGD^)w0XBSWuIRT+vxCT$La1 zWUB__$&Tdi)SC8G9AW#$o2Gueb9z30DeJWFSZ!U~iULeeTGLUSw5B+ztthFz=nGw2 z+t(JCT3wtJDN0(st~jZ^IH|Zd+KPLlt++SZihHBAxHo2~uh!z;Xf5uINO5mOihCnc z)Ek{eozYp;7oA02(NWYB9Yvc(M^Qg?6m`S8qFz{6)Cuc~`e1EQAFM6vgSAC{u%@UF z))e)@nxZ~fQ`86TMSaj-)CcWFeXzQy4^|iT!Rn$uXe;W2wxT}xFa7OcYm}ev%uy~l z<)@mbd}Nr%amR(TVi(Qa_~Of+X)c&uim-aKv}KXLu%H)8E*;LLl8ZQHvE-ujip7m{ zT^MtbFLpldX4mJ^F1%je$ctevqGOHS>UM~O8gWw{7r5-ba1%q!_ny+U6PbLsE#g4)QfaG=jn*eDCY$#JE7>sDI1eIMX_P@ zNs0|M<${!rHvPpY$x!q{)SL5O{Fz_SKjOOV_2$?x^Sk+VV_wB~g{Hk?rr*GCW1Z%G z`@e~MV9w9O4+3L-v%R9Ssyb9tTQ_U=oVoS$<}YYixabPAv8lOb@sg$CWy`Nzv2xW_ zk=C}=?Q7Pq>*!p6iErm`L>72MdeN8j?*x6yx8%ECk6mg598_Fdz_tbo{PkttWw8Me z?|H>GDJ%HIZ^*RYLNO0RP~j6@lF+B<7M~9YW_^pIyo8&;a(AW(mGZU)CJ-NodK}3p z%P=H;>N5fYH^dzwDg^F@s!)MU&*K)gC94y_v-&5n6#>*amT_!HK#9u;wM79(zt1$0 z`n0x$&;?0?5Z=qj0$NH7(Zv}~fa+)Y1oNpf@#ob|!r-Gw9Ldsq=%%_m^b*47f0pvF z`-FG;xS6GeD3Mpb30xZXG8fy%>kZKMUkY@4nL>$-^wCQRDU5sOf_6=9@CdK}Pc0jy zM-_jEj7zMy_Y+Jyj0#DiBU+HJ|@X(XJlKE-U-k)Az3#nA2JDFbHLH|i2$ZOxk6Qs z)+EGtNmz<=dH7S`V74@3UxEZVJ3ntG0>Y2|D72vne7bSU{nwHiM=RW@Q-0=Lfv!>r zD(%5znZi#s4TQuYKRY9fXphJ&!O`Vl^34L5U$&&5a2eei3`mlHxU5musUi6l5JC}y z4xfdFZB`M1Wul+=Zjo|Q1UqgV!o!RNz{E77oBLi#9cg&-1K%jiDn0Uq2G4m_ln`wi z_V9pdX`?M-sQxdLHk*pB0)tH{7A7|f4wEF6DB1{d9@OJ1RHh`3UZ9ct}1N65hjrkm<6M; zm1Hba4Dq4`=)^Wo_{BF^f&pld8Fon~%tw#t4`j$4g&mT>M<0z*x@4R^&0o-gv7Wde zW9S{s%Y3Gs;3R^Nn6GS*E&^+n(`FAw-e)9>#VPxpsVbS!FoKYa)EhFSvjmM+LYVlm zgsf3QA$;4?W=16jM`B~HLZM(%n&>8e{x47pfz`>R5-=rnOe0k+ZIfT<04mE(j(6Mw zvMhl40h#a31$lC`cDAzI>Q2D|8>M&{p@hAJ;K_AR{|b=P@tHwU>IGe^Bz7*8{?-E{ z=-{)|5i~*vQ5uw%$u__!9G1#NpH&b_>~b2{X9E?#5HPDnZ_D1JnF^+`V3 zDIB(mxFq_tSzxgwkcpLf83^c{DiEZ?QnxKo@Q5b5auLQ$pjbMwgVV~5Bn+Zht}Z8( z4zS6ti@FfQWNSg66w!=`byBLaG%h_2#D;>PV%yAY_ynZj?Ya!9LsZTX$SPr>Ny?c4 z5EUnExV}QVV5F4aKoO*0kf1zDCTf0KuNIRq9VhU-i@hQ(c`c$460AHfHOQh_yqqgN z2txrih#>j7?&%N_RXT4)bm=D{v>3!VCGdFQ68|6`38Op;c>{3vw>&*lW@XC-E~uU*lh_7o>2T&?aFVT&EuvV`g zg3%>X zwhFs+!q#CZGaigJ4eU#?(b<8sXYinAw8xUWFke0+j6$}=NLF*dxAdxF%V@4$nX0tS zx&TCjm=YjXyC(qxrHD4hV~n%1BbI4I_1D*ZlnDh(k;0VL3w}t7iKW*0ATxqQLCY3S z4z~eYUkaWdAc3a@H3tMj@+@=<39@LrSQnsH19lm5G|5>DAib{o2I~k=*9>S*DHF`m zDGZaJ;R(s2^GRtJxP8IG1qeJeK_MWya%&*z=XEwc(#Oxs*cNxHgwkfpLOvhwN6wIc zoD{9013|ExSHQtf0EU?yLdtB(*AcMF#nd$bbGZ5fpilDCE1g_uG}(?f{3EYe!ZiOiK6J^>D?t2At)@8{A#k{=rI z7_G!SOlb0e|PjHHFG&-XE#fg7T8Y3&e_0CrplE zP$1~D)D!OCB_!PjdeHY0u+kqyr_?N+m`w?G41dCpXj1%}On8NR1CI{&55+NykDnh~ z3%;OKPD2KIEtLWYy4u6pup;qMiinwh6nt=aPSvfHhtwEd>e0ccOp!7^$uv&{R%iwx zZXl-zSf^Cgu5L$b)p9%|1Skt=oNsy9nIA0ejrcIrYO@Zk)W^5RUrG6Elm>v3u&J>p#}pJSI+Gp}x5IT+Ul zb}p_tOoEcm3`pv%B%atQNbk@k!yFhIfswhgY!k~&Fe4RSI)ko6(0MH}-cGbY;3bME zSgA+uIdMu^REg;r$X&A|-8uP*X4J9jelI^Xk9IQxDF*G6dU3%tO+JnZvE+D=s2Q^hH zbXpofC{RwyN``SzTH6UtCaI<-#OIV*XlfNwnnY*>l_E+{NOW*fhee=c8#2&VLYZor zB&I_{A@>f#A-{GJLiNdjxm+=5_iX^2>ma524v*%gxH$xGG)wC?NP-gV;Ib-XpkuRL z3~A0?l5@VRiMg3M0+?K_`q0J>gW3VxWVlA##yZgYZzsG}ZnjFXVuF@ZJmP7jy#|}f zk}lLt?t^3iRI>n^5bP!iU*Vbv&*KuOklGX|=ph1!U^A3FtN>Xo270l22|d9{T{5WA zDpaYzq2v(pK-HJytoS>ql7x~HFFspZ(7jRGL$-gHx%&Cok&`^W7YI~2SRKsX7GHtF zW^yR|QF30(I<(tGu#;hxDUTOY1GuBKgo)t=QCb7PjD^cqFp@Q)*6ZQ>LWDP&?3Rlp3-&!n|p%a1=7i=Z*a}$=nS&pQ5M%4 zsf*r7t&8#}9(nzj4AGe*X%D`TYr#$BX~y7qld23h4tk}_&;~=Dc3p2{KR~&y^=nDI z_^5*NLh)|aCcm8$&;?wxm9VsHTFz0q}Ch~zepd=`>C8Kkw zR26)3HKQORQdl1+x2mErh7LqsPlO;hJ=U6F7ic5d3b2uh58;Q9q=WRvdVW`h5DzP3 z*ONxpN2*-8!CGqfPmnmmAbxCJkn^%J4@u{d9t3LnlsgA5C7ph%R-*AJMv9fGOnp4^ zkr?|(%1ak3(WU_h2s z-z3;fNN|7`Q@Zp8O{_8{70@y87VQDuM)yghh%uyYq>zameB3H2spb`XyR+tJF$#V* zhflD`PGvGHkqe1nmOMm7M1Tz+q_|n&3j# zZO!!G(r%A*tZg?bT>M+wCuB8P-_ou#LcCRl{G-36{o=`3^u9;D>1Zsr$-wtSuiGoG zEIGR)yj8x z^&ja!(w9Aw{c4uJuo{_M#yl&ehOyGSz7Gvp=>|e5; zib;Vl>U#S<{YJlWKWX;Cp4lv2vDr+EaB1E!6Z>nUW|F?7U5@W)6PEzaOj3$4I7jco z1Ke)|ch)VK;0RiyN*t%*Dw_c0qJOOk@IsY)kkG{x-B1`sT9b9{#$h;3IJmrG_aH z&b3-`MY2`V#mUJ;mdoS`|L{C1}I!WTa)IQcR%w=8qHhiyLeiOMQ+;z?nhx&qtV)eh?=jmA3fz{+vF7N%H zzULqAp_He8X*AQ{mA>n})miVyjNi!gR~^}MWK&j{_hrvy)7&l>PEM7YKdqEulk!Z~ zSyq|JnrKa|Co_;}p7300AsVq@yqqQ+#)@vSPJ|kR<9vDIotT>C|?}7RK^Uyzy2Z)o}et=8meI#;9C_n$} zb7ZR({>|um-Ux~dCqKJInCYZ<$>$R%VrK>o^UUBMZcb$GnSHD`kwnen{fvhfQmVQ! z=sVWi>g%dcB#&o|#+d(D?{TDJp#aCY;OQ|Vgn6|w=pouiWBB?oTl;+Sf#`|kNa6vu z>Lame;v>;dWV+v1+PuK`+r2?wS??#3qS1RxS%3Y~Z;JZ<7rRbBdUxqlr9Z81srsC; zxVNwLN7X~dirx}nRsw#?|D)<3i50zf`+r*fIRQH0A;71DX73XVj(2TuFnZ5D>RbNo z`CRnN$qDqyUg*}EpDJBkbrc#u35^?}aUV4L0Ji{s8XA8JjYpyJlhC*k@IJt&gJGBE zcW+rXFmSzSiOe%2;?}^5>(70>^lMeGHr?BGuGhDs`P|-H>bmw0JXu;-b!X|h>JJ<9 zdwWa2Q~ge(uGa&&7Vua6->LqNsO!Dc54r#y@H+vY4%YV`>&n~`=uHnSnfxQ@`J;im zN}q&uZPo7^b9;Lrzr!FcZ|QaG`7O}{ZQI2az3ZVT1U;XDo)ZI}$qx4YP(xtFr@pgx zvw8dTiNx)hy}`1eCo?F*4H(lGqD3u6i@Gv@74sgyebsfVVpnaxYLf^r2fYpS(zD^@ z2M1O}uNycsaAkDUU|{gVsr26T;PcO=_o7GlrUzd&pT{o{IWhQs;5>|LiatNs6!lN0 z_j(yN0SoiQ;9ox{OwzZI^))Dc2IJ;4ZeBDnI4>GSE@-)Ev!}0+WAx!4ib=f0)EcX) zU3Yqem>aV92*+Lx5IGB4>xD=4Kd*bt_e5~;+mn| z;`^t6{Z9FG3Quc2e5(QbTO-Jd@)fp4gvH5!j_KNL)(F_QXI_GHcG1bTP_kAKx$ zPGGL_oULO2r8!-}Y3i3W1_l|DBMN4u1BA~iT{LFA+Y=OV{C49<-%R(>=n0Kpmh(n^ z`{n5TbCi+Bb$si-@d#{X{mL?ulh{BkFd;BkM`58SU&1=n{H%DX3@>wD)9E3tp;Jb* z>wV-G3Px0@uewuOf8m|e_t|(RC{4P-e@g-1Wu@i!;63Mcxdiv3(5Y^!JA@F=m6W&0 z*yQc$bOC?bmOgByZ8|LbFP!xE%i7(Ec{qXb)XaV=n@W5t@u?&KaAYxdf-gRBeKd8T zB(X7ZcjDG`$y_XZMO zQ6t^e^o8Dc#H)7 z?nY}XiC*Bf#_vD(NV+5OwdXn#e}j3E>YLgmwPS2znhfAK3qJyVrDc^Rf$}O7=?!Ra z)PKEbKX{jK9+q8e;79U~_RK9ibPBkpJ9QfmS7L6X9_c$PrDa`Ee>LzOcHKLrE~2q~ zp^p@FvgcV^;YwoBgC((hGjdiEK2PtxN!`Y1U1-Dt2Q-{LSs_aLJ!ebVb7H0EtXu<@ zMDI@YsTrO6brkJ6h9CJPbh17c&DF;??X4}V^=!hZ8^owuhEcT!qi%h^mUV?rMfXMr z>1Z^CdZQRi&+vHapN#JHFeVs1GZ>5>V;(PKN`Vn3VaUH^D~*BnvCirXv8YuBBNn|& zmq+_O5G$Lwvj-zamd1<{TN@2=jbBjp{NiKvvA}?6Ebp&h@;%|{|8dv3N1rKOTJ-?W zs~dXXR{Co7`;4W%vv^+J(EE4(SF2wY8+v~W@t4HX-km&SZ|FT2Z0gM|_(az`8)|yL z^QiC2XE7ptIr-uf+Ab;!Q{|fW=_wWYq?^Hh|uH!lUYe8SQE?RZ2>z0nLnynK9 ziT+S;N$-l@=H7X|6SsV!%ji8caN*QpP=i|^cTgW^>K8%vackgtPt_^SZ)k&7n?(KD z(+Taf&|?_)H=Rk$nh0FyS>efV#|Yrb*C#^o>anzpNhS3WZkNn|%)#%?pHZAs`C-FB zomciG)}@=f(p^~Lm*fqT`qS}yx*Coj5lbp#k^bwGm9b6fVEV@SL`h^$^mxw8IWUni znwHI%{bzTQ`U(ZIiRO8Vwy3rAizi=>zP!0B^YZoovGoIwh_F|kYs|^Nw1wtaBj2?s zod{2OFvn%mV%eem&(e*F&tQz$&+V6TF2(Bo`KVYdc)at#*5D-feWbqlgN_Mb_`T?Z zw=w_squtPA>Wn<%vlrV zdpe(lB~P9;mVT*JgonYmH~(kM^Z0Y``@!KKkan5dl6>|)5xzbD@q3Q+96E0_suc&H zSC!oViF{^32|4-;>uzd9=>*ZrV`&#QdDU3SF#+nbI=v%i-8YjtMzhm*~$*%N;6 zd9p&zF+TQzz^d@KCd~}z%C#@^Pv>bqrSwN)X9g(7`l9RpsKMvDzaEq41;2(ffnSTB z;hFWGm^`!bPX5K@?@xYr@~e|Zc#QM#gm>j{o{V5T3adQdZE3&FrhP(bKM3t&@=o#L_)v)18cp$>vFEeOy`pF6e%j(*1Tz_d2D! zHUBoQnU$Oad0;2{?nJsP9ZeeMx-?-Dna6t?&u^Jr$UL-0+sraV+ZekieXPfmpG0q( zWKVWkdB}0u6aMS7!u*@(4D+v_qjuCee+^5glK=3JbUlQ$tY$67S@B>A=W!Ku7@&1d zbS(<>7_!XfLCczNpZ8A+8+`8k6|D1rsa7oVcl{&j72%gz)(HQc%NxP@Y&p(nClUe9 z#|Zz}!v8B;KFOpKsehE$WT-c0(?(Nwz#HvO$}xa&g)xcxKLtGo+>C3HV{|=8O^E|jArnn{vQE(L6~+b-u`BW$V`=E=(| zH==1#VrR$OMUy9SXGu*$d`bQp==HC#omk40hJg^t0OBk3V zPrl{)yB>*5yl3KA&%QjyM9wQav33i#k>KpaYo17ueMZ=ak;MZ~)SmTC>T3g~xB@u! z8bX+D8|HE?*|K!&io|eYMe^aq3kiAsiG1C_wM`?U))it*Lv%&bm!%xNIA?TgkMJmx z#n@e!uZ#YB+DK$4B3a*JjHAsZS>q$#BfUp@tt%gf=|$TJM!yKYALERXAU#h!k82pZ zJ&-$i?MVp)1HW$kK7e23vAMCin~&w@URNKh-!yNFz&g?h&*3v#GkM*>?C8BXqn#by zf-~9(tv*b`)-txn!WxXNVr&)8OsjBa%G~H~2vqMy&O4_&*ChLT@jHf}Cl<(gVrO^` zHvy9_qHo0S9{h}`xSi%)lhXJhDek3ow9A2y0e2tc4_o*MVEZ?-joYj6HHA_^-*PVX z27G~%fImQBmD>ufn*^3x>&u<+;03cmgWCO zS$kWTZOiWe7WUcujv8Ca(5$-4dvLt8x|~7RW~uA{Ywum)<0|fZ@j0uNw3208mW}b- zYfH9-v1Pq%%Z@RUCEF5~dH4Y&QKFTlwWT0Siyp=hhZy1zlTeqWBqb?LA(v9pl9r~B zk`!{?gr>Bmt(?-{+?KXZN&-#OT++)wrENat|NZ`cGiT2^+Vu-^lRn1Q&itP9o8Qct zGiT1soVK&-`bqgR=nri}EUyc%BGEegz1iz_>+B=3L#4Cd+d6Ig?Dt++I}i3LTmk#|GE6c@vRHk=?7avWjq}Fpp-H1_#>Cj4yO?D<9N^w>D)ehyjxV>D!&Ey zcoKK=S0CJZrrjo}3-)WUPrM3w`_F`LV*G}8-4|6qNyxcyFA}Y@-*>#=gLux}I{UWw zm(G4)>$Lo1x?DaDwneT)l{WK1?|ME-{9fy{t8BcJAbE4o2}~WE1fNq&A$PH|XY0dr zl_!|*o0WyxrfuXO!nXo&s{9qT-92J$_rc!V(nCYt!4;3-I(#6_ zQw*;-Ff!VgE;XIQkYTY8!3SelKAY*^-?Rq1T`t}+y<>;Mejy@SqWbl94Xf+xHZ+2A z_G0yB`o^wUE5|6_GBSEoHU&vIxPS2QV1GK9Y}?em4mIuWrzTn#v}Q8xI1{nE z3mfVd5{d7zDxKl0Ymy0fL>*%4jwm@kWMv*pdgn46`p+OvIuU`&At@b6?jGUu- z`qP>8aR1pVk!>gHG4YY_qU4%u;MQw+cx-Y_Cyw6p|91}e4NbsXIkDY5Vl+sK!Z<}2 z>t?|LU++v04t3*->E3;PV|{n$)ol^%PvecBI?4ZQZw{2h4ED z$e{y0`$tD^8B3qdb$z1;lD;prG{MWGj~zlJlz zxd)sLB|_)iq6Vys3eig=@HFA)bB2a#5qg=>w>vUsy2JXW3q5;(o*tpkh`=+2pU;LG zW=81vbacqxSrHhYO$MF!6%7>;`s@gOc7#4BLZ1_%UlO5T5~0tH(C0?zmqzH9M(Fb* z^m!5be4%IkIX^;Q5P=s)^ev3g7e(mUFc$Lf;s||lguWy~UlO4&jnJ1y=*bAYEW*Dm zLSHU)&i83p9-&tXo%3cIDkJo&2)si0InShFMTEXG0#`@inh1QE=;OSy&{f49KV-zM}LJUeMnI-jK+9G2fK@_bg&usNdt3ZcL1 z$mR;;h4SALfv=3nw~Bmr2V84}-X?TDKWJ!+(6&dk+>x zy1e;r^#^afU}3t9$A>-_g8dtx95qrPU!Yd`cH!S?el4Q!iU4eI@GQG;GvhzA^t>! zKVddmevTnx7*AXh;xCEtmzYZ}KgSd?Y;gG33Msk#6kr=exV)w2vmdUOg%SEf^LN>sH|UEZ^hM^`5PflkzSw*$L|+o2FEQOA`qBt}so4^u zCnNNvSs9`)i_n*uxgq-U2z|MEV`i{^DS%}^kp*I>YL~n}F zo6JkogY9Qsguc%FUWmRvLSJuwE=1oDp>Htn3elS*^k%ayMBf;pZ#0WT^i2`^Ci5?W z3BUsE5)R)V-e$fZqHm7SH=9>M=l$$z{Kasj&Y2MZ6%qa`%(pE6tHOVU`76sm4!8iP z(1i2fVkSW!0F7)O=znPW6T*LGg#SwO4Cowd@Xy0ZCl6bGfPlNqM?&x}b8`s3+T0L= zuQ6AI;A>4~2)@pggy7xg|6o4Z1rH}l{CNo8YknsL?=ugD;OotYLhuddPzb)!>WCw@v$Ggnw5d3cQ+ab8e{9*`BnGb~EUNabi_nT`%aGzNh zg8R+F5S%t%2tHt5#H$oA^MI8eFxSb zXZ=}VIwSN>65~Y`ats0bI~0+>-@vhcaTCLlexCWNj;OW}YQni%j4%e{lMdFi{noYo zx&{GLh{2ng_3;>wOB6|eEOvloLLV-SePp9BlSM{y7P`Ao$8}}w=gi-V#t*r%+zH}{ zn)Ug34R>@G(9DWuK+3V-6+chvY|kWlzc_6o2 zJf5~&Q9dVzxPk?_jus>csRmCz98wGJ*+fu9QBj524m@?33Vf$w2a%>0wjlxss>?Iq zno~sGCZ--E@9)5rStfP~B~#R>c(yi)8qTZw^#^o7{`=w-~v74R%@zkM^jb6-!{jeNq}i z?*`{mI7BLm$7xE&x@H`o>EH~(fYWSgfKoseazxJz9%$&9 zMrcK-_!xg;awIDS3TA*!kCQ_Kjun~jc;@$!LOX*PPmTi<{(pSKbW_DzVq0a5Pf6kc z1P--$6}73oMWrB4H#=aR7L5lzExl@!GB zdtr9`1@@hiR!)6{1)d#=h8WJMWWeLCBAAwB3{xOfW87zjBz@X)6=)u&;0cR}8Fm#F zkO>Fn1Nx}o*?td7N;uzvk({+v#kvqdH}m2j421y4dm3WZ5|aefOpBI_!g4^2Sdl{X zl1-~Z?NfyF5BOX08_FlY4{I8n4mrjoC0&TA=`Oz;l}L8^lRjUCNr~|y(O{J1e-q0 zn0=5R4(f#?*VA$-oyCkIATNm1V=^+ ze}eI&p7bK5KW6ctw|q}q_-`!VtBj%VUoD>VcBTIVy)t9G_^3l1L(McX#`l)?GJdBg zl~4Ui$PthGu<)&Be4|vj=wTI15#-vlOf$=YUa)M#$ujtX=q;I$M-8SCO__MaW zU-qQ`p*_4XneQ>ifbV0BeA%fmr?H1 zo_qwW^dS$OJ>cJi-xhoaJa? z4EYYkl<%@J?@wX}VdR^%c&We7d2;EJPJHRFYrCPm(0{|Wug4X3_zQ`p9MHeW=8NLW zbwvH=qeu9^kj;NH<$uYxuV1z8__wvZrO(>-_DN4}fAmL!_3#Yp!PZ9uWBBzd#-3-o z5z~&8jr(mpZsTJ%mUiy^@|5+@7d?JpNc`Sp%Om!F$%NvTu6K<8<@)YojQ$5*oAgUZ z8AJbZ#>nq}#`wV{Zc0&KXoAuY;nFds|I;(5dXf8zjsJu(^!)|n-^5b{<4<_zyNr?V zk8E6qhC_MjFMi82Ny3O%GlqOKW5~BNhI|)e$nUlByBVWj9AFGRo z`EM~szTZR4_V%icU$gP+j0@rXxVAr@mrcGoj6aIKoQT=pni)gy)fV2%80Adac$6{9 zaT{as-NhLBe~dBmf7HfLAZC6~Ge&!d+oU|w4}2B*+V&~^3FJBmKZyE8On!I0R1lB; ztBNuFvxzb8OI?g{zmoeb^6w^$_I;b>llv_Aq#poY#xIcnRVydg3)=asfawQbFN_WT zGmbNc{p?Q(r!2k9#;zZT#?7SPDWC2zv158Pb?gHczC-uS#-Ox`eD_N|SQt;o0{_s$coY}-jD;&K3@6pm&e<0J zmWAh7_%#b(V&Q+X@LUVSxgvk5g}-lM+?*u8H!M8g!Y^5PfrX#5@InheVBtj;{*;9m zTlfzxyu`wfTX?C3U$8JbMalnR3oo94Yc2e! zg)#UR`u8kcZ{aUlxWU3-ws50`Pg%Ih!e6oQIt%~0h1Xm7(-z)fVO)Gto@NU_X5oz% z{+fk1S@>rx{5A`J$ikZ~e7A+Ku<%DLyv4#lYvC&`{I3>nvGD5_ZnZEv0kLnZg+FHD z>n+@7$168jc$e6P-yd7OU3wj*pKH?w=S>kD1!B@zL?#{fGx# z3hT6M`_ua;4)z=v?LCw>wLs`6zp++ys3-J=^&GUm(Y~Ic^zgy)fn1W~M|v_Nx1>j- zv@v`n{cJR>K=0)maVw`w(tG4X^lHP{p`J0Yj89QK&Xwf{CWd>s5O{281S^rx&S$?i zKZXU!J(=FVo6=Kt!q_7tV|_h+<3m&OV?k_AV?CMlsQ=mdTL#j@Jy@OIGjaec+=t~W z;X%iW3-U`24xdws*$s~L=Q4>I_6!XkNYl1l45O%+!AyFrM?V^$Qwdh#9~eB+v;S7V z9_;GzA*}8mxAOH|;lH70fA3h@efB>q+9edAamKYnXZ-^lQR!GpQ@`fnWu+fCL1xj6DSZRXQA&^tVw9_qp6 zG?dfDj$tf4q-)`EDGUwv-I^<_p!@P%PS_HW9zC4S(?&U83+v(o{NTk z5Oiox(nzK!kJR88b|8$g;8PmT;PBv-3y6J4z6*#nYXGm*@rfywDjfMQl(Sr7=a9^E zi3O$dTw-K7>m^2pb6sMVhps695n1%19>34S#XdeVihgWpsAu376au$qSB8Tl=yAi6_8!LWY&6}M9z5({m%Y+V zd10lc;{-<^c6$w_{XRX&fpUqV*p+2%icqCrb-i7XrgzRj?%32N0}bTHO;)BBTg7^? z4XbAWJrxH8yv3W^{bOTBM;iw-gD92^M6fHY=a$hyHSsVjBYi|VmBaPxHEp^E_g7Wz zPTxEMM^#nHHnjb+xrqYkP6+@D6yqlX9k;C$u-P8oWTErJ-$B4CNT6WQ+1%0~Ko9~Hiw};UeMYiMlf;{Rw$~awklFUVweQneho2&isYgH=viNYa?#xoRjEo4ujY~suv8!eZvSa zqrAF;#N4`aaQK$ki@s+J^^BXz_+Z~n2HWn$pRPh!bV0W6*|Tl;-k#2@_io#Lb!!(p zY>tQVNP!BurFXR7^z`6StmoiprYHEcRYi}<*bUw`fBhtB;S;+I&Oy&#H z92g`^IRZBYqfOEd!LudRQJ!$i?#A|+yo}Qli26r#S-pii8o^)^BhNg`e z{3Gn%cKx0X`18Ct>(|@c%hZS2$U|=O;Dh zC)MR8t>2KJ)Rdo8pO>@_%P4ZU<@$B&@{=0!lA7{+qba{Pn(}+2DZe)w^LwK)zc(85 zd!r%0HyZMLqanXH>hpU8Z8@Lk>+^e~KEF5W@_VB$zc=dgdShc=XKc*ti;a0*(VW*4 z&3PTsoYxP{dEKxfuNOAtb;5?cK3JdE2kZ0tV0~U6tjp_zb$NZTF0T*P<@G^RULQ2& z^+8i!A2jCmL1SJYH0Jd|LtY;=-D%FVmvk#KV^ z5psCGB|^mDIXs;ip$BJCq9mCH%{7CPgE2aL5@C^^Z|l)xiv6z`tH0{GygYY-iHd<~$3Q;|V5ry&C{ z$8otDxE1Qcno{NKm`KK2nUdlDU zA7P1J9Mqq0UOyswu8V`J+!Nl}+A;ag(T>TIXQClsRB*B(hz?CSOd;fG?7=C+0RPl0 z+)el?Q_jh(^J^zGv^www>(?ZUETPRdvnY&RyH8wry=~uG+ory5_2DcW>L%T(zxrYvBf zMCT@dJofCt;Xl@(kS%9DdI#^Xa?Wo;i02o{AD&$C5ZoO;v!|*bqP;^hiCWcfs>V(0 zFJbWnz89n%xGiH|0s+c|JlDU`8o4;V;qQy&=CYLR* ztXi?My5_P~m#rp|NS*`VGw+H@$816g@^bb zQ)aUhEJ6ZbWXG>6Ln=;M3x6DvDZ!fGWs))=b>oME5|)8#rac`>>+1 zhCePPU?Z}Mk>c(X|7*xhODISc^Gms4drXBKL1Jr-G{+DDKrCZW08{jcF~uLJ9mQ(! zxXW^NRDv*V3I-`aktu%AbW{BO_ybBcAq{q{vdD&hO%_+tIg%#t)EhWN#f(R-4` zssJMvvsfFstVKgSLCfY839~~=3_Qyz+hb=2s)sE`Y9q@{t)e+$zO9!D5Pn(6hb1x$ zMaqSBlLTZHd;DJCD!*9-bHm~iFu=S>JA-;OF+aSA7pDtlkJ6l=0iy9r(q*%ZFjkW( zQf_KYz^*t~kOtI)FQD#}a9IY)`1wL?UQ~KKsJa15AcaBAEuCUsyvR(uG^@;S zXK@p67POx!O$!EU+)RB~d-`v(pW4>_-vS|_U4AKtC6)-&Z09Iw$la($Wo`OhOChUl zuETFI+oYwd9GHsW)B>y%9I^yIq6xzWHvlV67f$nA8QT*V`8N6dnwWM!<7|$uzj)p` z!In%oq{!TKCzlN5P<)|tLnQXGarc62)Mbk5YAH*L6__bUF%B}Pa0#GJqSqBm&VTSo`ncx0^0n;KO_~z^WL?xjhQu^O_ zELv1kBiE?~goYn1fi`jOjAT%n)cp;FVN^e37wX8tJcY67KJ}SU(cXxZVh92dzCRxc zB4=^X^I$)Y%h0^J-xGn#PsyH9|0e#j5G;*p5tt3jsO?$6-yn8spf1^HBbT}8hN$;7 zAjOVg6SNI9k!|-6;j=^IqQUmuaq|nZdQ@@JsF6%SSN2FQ4p>~cQxda~*<)qqqyWNb zIpWeaa!awa2>8+kd^TMIR*fQvsW1B13zl{=#ASmLu40?_N#x^#sCeTyF`)cvNRKD>^>M*`IY! zlBB)(v-vqy*tRVeuclcC$)s6;QH5u1B9it>L6Ma1m>VaE#f8FzADpy9=+-c~(^M-C z{OykFgs}nRgpczr5KLAIpj0AEeBM@6R>qKztLSa;1mU1Se5qs(M*I)nZyZaPB&xCU z|60;L$zQr-$ALJTk0P&SZoW24l{P_olv`y&1dk=FrfcW1QP?21Kr<9%b%4QzK+>U3 z`K&0XiaL_UP-MMm=0mF#PbjEipQGBeSYWfu8QbXt;bM7AV5NZN#!j4If1gS0ju-Q zjg-pedx6;Pu*g9N7l>zd6hVS{bY(g5gyH(lG znZlrI-zS!}+TP7%GpcW~`oe)vWYtQ_HUlBsQY|9E=J_hqf?p)LIWCFmmYLC;c=M z%kk%XFFS<8<`Nqu;a}`zXK)_M7S2&z?$yVYQ;nJG1JkY&E+bzf#ZK|ZnpH^+kavvP z-i}N*SbCO6jw`Xm7Uu*Zi$0+oRl09mh|MR*fzwy zK2A4yljKVhK&Y0jfRdEE4_jcBfWBLN8Hd*alrd+(M}7QTfxmFjoQ@C)JJ7+gYQ-Wa zlSAk+VOPhC(PTCs};NNpcz${}~eU zTOGR4APfE%lq7WgC_lPc33rPAa_+X}Iq{O2ZvGbXtVKKwCu4TGY>jEXx$Gbh4wzed{kO>y9|oPg_lN%UlX>;m}zee-O5OD~v6s;?$qwhl!JrhU%+?r%E+(s)v79nMd)fb{vlf zw6_3_a20bb$$Cez`g?NPN6Vj0y!Qn_YIT{K*AZlbYM1xCxE+!(61G#4UknpY2>w6P=Z!k ziTS2JZOK+(3KpG|HsUM%5|J+S!$>i!$bf;T*=DmS0u$Ub8gD)8 zAsypRimN5g3Bppi5V;CoeEc4&kic!>3|0|~2h7t}xRV+AGsHL~7i8Z99FU62m5gXE zb(K()S^%XbuL81R2@Cf;0BEqel5)~1e4#`~Vev1B0Ca%MYNC{A7D*tJ!sC9>k$@Y% zwBwYWXctnV#7oNJ@)LDOv<%B}mJ69|S;@jb-jDk6$EuG@7t&=p1RIxotuzW@;!jDy z%qkq)76{OYJi8E`MB82ADC0!qYNO`3JdTkfQz5g3ht!`bP`?JgO&n0YJVzjxz9OZc}*uSjh{VxtB$nHma zH=pNJecEZNLxN6XUGE|i(@MtFGX-(qbjY35Gtja)uq?U?XC$4ZoKs9eNU|$PaHxd> z2#Ps03SpO1ju`Cg%x38Pj*w`LPu4rVbJtgm zw_bVVSNaYqp%~O|UFO>ZO((sdu{ROgim)LdZ}v1x(LGT5iC3deO8=KFmPl-nEIdhX zl=ImVkd2F_6x+mdOtbE75jOrD#~&m`PV$!nC1~NZB-5zB!|&TnOzMT1P+R;7^8%vH z_>*ugCYXE%i%XajP#tJL(0YaWicq0L>-k#CjQdh+sFMKsI!BXvt49?2Fbtp-Z9Y*n z9kpOQ;iR?+CZX9#8f8rk(+!kYHg#x1#<};{K2V7}0)jF!BCFu&90^c^#v+RDBO<{Y z&vo&uY|(_rZ={t3nQ^(`AM>9^I8=ge*QH_)NWaDg?`Yx0U%@RKx>NGZQED^2TYT<5;Y)<{tvBl zW-x~rB|~z)Tgx3Rij}G?(SZj*FH zaub_5kmV(N_A`$~p@Fku*7=1p-TDPF9*D^mqvXD@Wb7wAS*YzEnBYNkh9;xb)c==18si zZ1D%s+C)cr))=KqnQoKxV>EzVGD1_b`+YCXsg(S!YUa#F2pp6q)Fx}ENlgJUFn?DG0d%sK5T8fa_W(eG_aLV-| zj5#n{VNJ1;V)zLQI1MNF9mS0#EM2*;{GO7#ofMUbg<)@ttIFkZeR;(X~%_d@)h|v}1GcHSK`?e`~E2Sn|8={1MKn7SwFFs6d|zgezmrze{2a zzmKY*$}5xna;qx8%8UI&qv_g_we^h~H`X;atZP`GOx7hC^tZmQZvA@THa0XVBAF`v z=WBMic{1^>$~g%d$lpAwuO$ncgj|DjCmZECj0J7^Qf9{~{Ix7G|1cXYn<>Vj2Qp8mrDvug9Cx3*w1 zws!604IQ68Q@q^_7Jz@B@W+zPnJ*4@F8X5c?#{B*?=Jal>blNEYG=o@sdy^h+ny>| zc5CKnYV$io#S?@T<~+qu(A-jCmS^8VC4smTFTv+4Bf&zM0En%hM) zt$F>Kg0=m~y%xFuaB}OBD|c3SU!R9>l~XS zbEf4I;LGv%|9LGB6VCwLUm#unq^U_vdNoCpv6}c~k?1wa@@KGM<_JFeI?1$$zki9T z-0M#+>WEbrrxtd$TzVq4umhAZ#uPVXJX~MQ}lQFWX;vTIZ$)W9TUw1Eyb}HszvtOy(>|w z6TR`|Q>iCYNz`;~a=B2>NIEI$WQQ3zRvi2Dr2^p3L5*8S5vz5T2Mvus*N!E!INHPf2%dcBF(i903| z;411Uw{3~Oo@3ie+_oq6apCq=_|)L4t{wA|a-Cl$WyPG{npKnDnwrVjnw66)1Xrb$ zWtANVCjOx9j@0tbSTd1X-jU9jfr2&Oz(c8)ft9_F^qxs=8rYv&`1M6QH{G@%^>4Q= zyvkgjn7lT1Eqpiqbjg_{THs$z{;!v>6HNT{oDSF~x~F&CdRr^XW(IJxuR&d}DL6f| z^O1>ovLodsQxopWFqmg7HEg?o%~PRW8=`~hUtSlu1`2siz^AW2xumOjd-}-Y&Khs~ zywv;Hhb)x*w8Zlz?Iq2!Ul*clj#Gq~^Ny{vZ$C~g7psGE7o#IsrpHCc#g{3li-Yy^^AFy+c!^k|AQ4X# zCW;cpi7D+R23;58m!KV!=WR!{{Z6g(+fm8qSEk&$>{uQaWv_=e9KSU(jMH*9C9xeU zNpNr|J(^rsTi2A-UEj(2WX*nVnoBlqyezqQWMpVlQjWM9zA5?6b#+a3bxj-JWgKSB z8k{yWKG=(|*smEL;UPjehHGe~Z;XdhP2lXD1B1iqekC4E5A)=qG&WvlaLN`AFuL{7 z{*j?EQ2Pga0ZwGF8+2^!iuLQ88i4G}OkCmb`vQCb@Sc$aXYHJG=SYecE<3?CGmKhqvj$u7@5_Q{` zTr*PJZOuE_ds}*FNOlv3E2%%7!MRuGs7AZkn}y`dp}YaebQZoekSy`ZE>Cn z!?6fl5P{={=cuzU(-4o)3x&@9RzqQgUL~}R3N9YNmXWz9YB6Q4> z!9L!LG?YZ>r9#)qAaayO=+n%BkblY|@bm~gBO+fe`m=p?d4zwlxiX-i-^*^aFrxyD zu&P5aKI~*+jyL#yYZuxDp5;KJa76^3ZT>YYg0a&N-nb_K8?4L z05%u{ew#N~8w#+xAxtkce-xr)e`QF%$oy=Gj(cB-UTi)JI-48Y1iznsdx$>~;ZK-U zh+Yz*m&kV+vi6on=%uDMBtI=epN2Iu;U&Px z^@kOlS=+DQUX$;(G3zpUN`dYemhM%cGl*^H!^Jd+P!>|63TduvVw&b6_-JoA$Ks`! zgl)I+r)~Th#;dVR25Lw@hB&s)NPWaGPI-bbUi!mhLI}={y9R80kHvFbNIppNZC=#dd;K1@x9^qoo0?{KvabjZ#cISUY<--SlDs}I+ zJ$tXYy6f%!(U@{@Cl3G}N+0ZXXV~vM&rqK|+jnr72b8A|?av*O3tf2f9|DEDt{Jg}~Re{YVXD9_0(C-~WOE6>JEd*rOv9@uhLuje@s@IUCu zXxVx|Gm>-rr6u{7lshK0_PknI&~bWE`HDhLoqFX4CFQCOA};ib4a$bE*1_6yU8z5w zqiW86bk3B1;m2ddInT@SFS;quN9XQ7+}SydvwEf|%5jR$dvLc1pQ3~Npa~qJQ+}T3 z;qYGT;X|%d&dqTL;#>v>IS^;M<&+a~=0tP5sIzUL#1Ed^KK}@A(EbK*A;*0t^C>3v zGtF{HM~jefkC#CbMgkc6;J*$2K?Xjo8^bMF8{%il{vJUSFS`zcvz%%iJ<LZ)e_!?`| zhA5B2Gj72jcc;RNV!{%j)me4i;q-zCaaq!H8h2TFmDD^XEtVv}BsgB_HU#VnBrTDH zYLl`;32RTbP!Eu7x4b)B14=YWc1OeoLL00?Nm;;g5XVO^`G~S)A7GA?O0D`iR@cPH zFM-`6q%^01C^jEiD!SOY z;cqFHb_SO)>!m`;!~8+P0>Li=0n<#*Ti-JwRFzxfSo{yHOTEoQOi7+O2&>$ z=)kIvEAdX!YRwWL!jd|x<{p$y1{=Gg5@ z^Tdfl5k=I0zcRuC>>p2Sf zLAwNi_Oi;{hjhS5uV8IMV=@^0HANfTYNGI(qILC6&B}l7HAO=+#Sni@(Gq0Mdk6jK z))c+|WOCQ)?Z=wDrU0V(Uw170qb7W8luaPu>0VpEvR1w$wn&k`&fwU>y>EOKZG8Gs$Gi zNDh||Y}#J8{r(+ads$)kzCH8gyj}6_HS#8YuDpq#dvyk~u|K;+pjSp{Q|tWXk;KiZ zBONzCc;v**XO28~b86s3DtY&bJ5qN)cSi;}W>T+=v@Ck%;434V?<)trWMQW%Or$ch zs-g+gSI1EPb=>rUbsBvCUb-x?;MC_cJBTlTGHzn0izUw@tQa!M=MENP^%K`J#6?f} zGnY{o;TV6uY0lIk3clz5NxieLiP&+r_wDvdV+pu7=%U_l&l73==@%VGkHQBnJ^rSzy;>tz|a0nLqUWd7drb~4eorQ4h4KK`>7C|Wo{R`KXQ{Nx&n*|d$TMUg#F-+|LYHxAb>Yg zVK`>K8KCn$???bPnETlufcYLaOpjx6pq7-sd=DF@7h^O(7zXK0 zj4?76IBDTaExgRa7?cYg77G6*5PDPZo7@-YvafnB=(}?vF@Akc5qoavth=DMJ@Wnr zvN;bZ&;0?$^Lsyo((r{;;5AFbdU?%~tLMTSm%82!>+6~~*_gw-X zwRBaf?*J~S8hsH~;g4qu{_O7oq7CN9W5YRL1LSHHXS>hkYq7ys0y%Y_O=*r71^aQC zhhG%17m&m3&+`odIuP`Y`Ckx_KIO!GPKjwI7x-d;9V~lV2J~~7TJ|Rzm_*=R)BK^G zJ!V>Gois%vZU%wSZax-(+!PE^Wb|kx!>k=BX3#Sg+SoC{QTTkf8AweTmOr|_N-aloI+1cu1Ws-#y)xg0ZKL|^dFUUa7 zEWKO>QQwlK(qf8qzgi^FA=crLj77}@QOsuClU13=gGwdXmjg&gbO(g10%igIq+cr> zgam+q2n`t5y}x*GQUf*(ELA9@MXaWWNqm5WN~VfW@wb~l2$U^#o9j3ch~?lEvf+J! z`M;!{5-e4tcsK748@Qb~&J~v*R~@B_5Ugw%MON}E0Fh|EhkWyFZ75rlKN(3lAvTu_ z_ruB{d6w$rCoyr@EQJtOcN9G&tlB^k1f%H6XJLyiis;3DR#L=bSoK1%?bBMC&QOVo z9a@cfSwV?_%c{)2vl32UguMgh)eDLv8BLyo=^~_I~ZRZY~>t$ALFLtwWui;*SuI)HA(t2cf z#~&7Z_nK8pP9HmJY8GNQjJdb)ep53%S$uzIv5DP1)0A%CSyGf}`;0j~@9vw-@)^Hy zV(WrbL#p83cTZk<&FdrBd34%4<0ZfKa*OEQ)Uj;)sgXo|?4z>R3j66ya$Toa{oFxw z2AA^v%`JG*y0&F9cK;n_ZAZzxg8NVOCO$cH>w4@{Gw+gF(CsQ2JH19UCIyb&Yiedq zdiSr`j#DYH+X=hP1|Qw(ohI+%PLu4Mf2=-{Np^PZoAJrm{fX3!Pnye0CRzH$qQxwm z-w|8k?JGF5pyP)xSDf)yV4}RHbW*j~rA$r1WO;|T%-iRksptT_)|)Ik6JJr(b!J5D zNuD`afP4}eLN(h<9)DHlHQ$NhemDM(p$2|*BjDGcT+>ywJ$YpM zb`SoDp$=B5O|>f*L zlRQ>mcvT`(zEAy~dFGgC(4X=rRfE@==$5@*K>N6kQv(j?bsP(%TLS50N6AB-L3=#3 zcqi-hWh5`Nd`{OTSC?=1ihj;`Z42jrvUm3O!Xj^bqVck}Uo>mxf429bd2CPLl;6kq z?p~Bw^~#?mGpW>rsWYi$Z*ga;H!)sxRmXVw;WG!ZH*#EOxwSmBqXmCiTQX11*dE_* zR!B?2Uejfmi`R5)lCigmJQ>n zLF_&rY*_@$YP{1Xnd&8 z2Z&$BAKHcAURVYO_W68g^)~!vcGThbKiZpxd9c}qcOcO^`^~=<;JCB~e?eckw;KuX z>~9p#CL7*Wsk_qVIO7rXj&?CS|AIO=ka)8?F4m4FAqQnIrO(qCCO+S@|aFC#Z+Bp%;7Y1_m%|1l`*LW{%zsY$)Z-nbNZ0P$>{YqF0$ali}RygXTpYZ$Os5xhU6CC0G?{~l# z{th_e!qD5_Fiobe!>F8ZeEWGz_Jb#98~Pw-OTzR5(+hsyJv9_W=y9QE-x=avUr2vp z1TGSO-gPt-Md-y5I3fHTDQieX=p_-jG{RpRp-+p@r$y*x5qepKK0QL89-+^Oz%wKK zGb8l!2s}&p`E;UTR)k&=f$=rAkiX|d;7cO#+z5QBDj>s>K&^Mc^fIQ#dyW_0mFp%p3$}C;s>^-+# z=t(UGeidG3{S!4PH!#;h0GU=v)u*{cPjKJb8in>j2F40AYIEd@V#T zjL-|sZ-nSY5qgpNRES<2p%rnMeO81%%M69+ z6%l%cxgkWK9ih)Qts(lH2z`#ZJVd`FLche!4$yv;bdV2-6pv zw+HllSQ63_f-B9+5M1RxUPzU=`d65LDv+dwSDJ5x;A->b5L{y(4#Ah14~O7YCKG}$ zH`j;Y)n;=DUSpPr;98Ri!E4R;vt1JGturr#;Cl0=5ZquM48e`&t`OX0hC=W46!f<_Y#_&_70(FA7p7?>V z?9s~qMrkb z=?k?A@~yYxP=;^!7R8Dx=6cjD-;pk?;Ky)rM-Ys85vQXe|Cn5^GbGzs#VJz?rd}6cAJ1Vps!^nkes$$sr;b|985nE}@+xb2bi>nIT zc&G#e-+{5ng(!}92}Ov-ilmCU{ML#2$GExFGc7=q3&E?H2b)iun7wlFUeNn8gyOud zSHylz&=m{J1L`{*-w=}`E+paoJhs966U+@mLK*xeW_k*P94i6NzrtT2R6H*Lr0`!Y zHs-ep!K|OlGTy35r^P4Sq%x=|2~eWNY4bU#*cMT66*wzF@&Ys$e<792)%uv8yYMTz z_PiAFQE)Q;Fyr6Q&n%QaW(uA70W9(7bWH&B zNm;%9i~$eWSmaR{%9kQP@ej(+*;6Phgi`P~ zFn%=4@90a2hu&3|e>-F7-OCtq;}*{`F71BU#x9>`!ce}MF`O!JqlN3OpAT6-@3HW( zg-mI~91Ng%4Y})55n{c!!12 z=!Acpg>jJz+-G6zv=#VD3%}RG*I5`BmC!d>_#=^H-7#A~KW@7KRFfMk1k6HK% z3*TYkw_Es53-7b=2P}*`h{zweaIb|wXyKg}zQ@9MA@eu2jx%$pXM7+%n&!b98Jy=~ zAJB0s-~KdCXB#~{*q3&zGr0=@{CZ3QnC+s?FnTnKPLKEW-#XmW+jo;&QJG!*Np0!g z(Y}Em96F%+4`$Ll6VPTI&H|_Y!J@P^GD_?1??C|$4D##_94@G96OqGc8WbD_GL?c8 z{&I_CMl!i2BFCdZ`$3e?W}CBoq|4DJVWWt)HsuvNo7*VgH!(Vj!wG%AP0b<1ff`7U zpPh%5lo=nL%G7(fcW|h8|4>@IXe(eW2Okym-a0e_m-D1P9N!pbIxw2fU4I9LCV0k5 zu4+YsLARE1HbZp6NC4w;au$cX0QqBulVeG4kwATQh?$P@2 zk!*}paA=27oHRjSitWH&vwb5I!{f45N6J7-w%T&@1Z%@rDemU!GU?v^gFT1RhsMxs z&TrLpo|9hA=4ECJy0pAV!vQ+F2D?tyVB5mjiFvHPZtUN-Ti{hvPJy zp9I!j57wT|%seIAumL$?{cF#`(M(Tme|rDK!JY%7y@%3O8}hE#-cX-UW_@#B%DTLi zhJ2KD8}m}u=cP2}rPSr4H0AX{Q(hl5<@G^hULQ2(^+97^A2j6k!GF-xhXS3Fe}g-Z z8@SJ#y?IAb=rFS=^c|7APk?sT8@A6E>HGrtz>PYLbzQuV4c?%$$iU6nM+Qzn!ez|9 zFLG1%IZ4wSatIZ<8HZ^3TtQW#TP*G)Stm}RYKI@v9F%r9-w;E#2iF^u=y2z4*^=h! zJAEa=E%)USqX$6YAv8{iQ>%f1$4P{KG8XWGxyUjR8wqjKexJ_sfV+rG)X5vtrV^O%lZ*j< z!_O7KYjVUTB*Wo<1LPw-f`_v!b&^nFWK(KW!V)v50DjqN=OcAi9j#Hy>pJU~m4tfD zAz^+Q79DdGE6fM}U`b@c(jsmY8XoDX0PB4P6uGPwWG!k090Lc!9AS$5sAF-U65Tda ziCISpoa8UxRH;|Nx7sh>KW5L62b1QF-#=!JO|1i^i#5$g=j^DP!IF&m9OX*e73&E8 zo>4zz%YUu%eFBSLorZ2j0aOFjH#%Q~8aN#92ZK8yifI>|0+kyA8nx_ZPlbu9@I)>F zADLm0JUCUO;V+E`jIYTr#EM1)QG#ZdSj@V%O-vuFs&#K@Km2U|_ zcmi!skYKEk1b-HpjxYGW0}N67!-QHabl)MLP&%{IhA4cLvlbx9%QT?1!)HMPGbE1> zAO@Rna_BOCO1SlBpbRt9Hu&6Xq{S9BYvMlNJzBeQ6&wc@b4Q9}hQ2zB1d2QwxbX@z zGcq+Pv&xvZVJJJQdxxFskQy=w!8h;(bHP-9%)~H{BjLj=Z6NzVYn;8f^x=bw<2A7r9m1X=ilcLYD6l?1O=rC@3nM%0~<#4p`I89wH zVPo5R8mgTZD7#&zLbHs%ew&rZ&=z~3nO{&3{`*o^E}Ig!b8lX*0Q3+2Mr;|tTcXL1 zY+vF`j3^PW;9ZcxoF)T&r#T71>iM#ga+u)RE|VmY(9Xjt5jnlP;di&{6lC;gGqTO< z&!)0`rJ!2{?e4>MqsHie?pL_4q=M z*kg$t$!~r03l}v1jgT&F;tMcMRv9_t{*M`|c|GDD3Ok%MyTYM(T ztZ1*n+jbl5WmZEsl=x~$q?9`s&k|JT=weaxP%$oCQLXxU>G7{*v2rtgTqWe)8hpU7 zgzg0s7`FHp2n)Z6E`i^Tgd~2~#?4|LBc2V^C}RhGhb&xPx%D<)k4b;%y&#Q>B4EmyPwbqfA&y-vWg&Nwy=Bj85$^bsg zWaEzsVm|OCB7`?pCP~@QtxUA^13Scg7dRE3IvvjnzbEba3P21*TCsiO(MP6LvVcKe-~Bfr!vW-M(7@v;(Tn)Mb?5~gDI zs=eTbbctEIihRr;S&KfuG`18_(O)ihTrMh^%&J9CstQ;0%uN@@B_T^K#5*MvI_{`z zB%%DsZK;%A`yo*191UU)?~wO7jKq>n$-|Xq%Tlv8OR?u6tItG~v?uED6S@q!H{F%7 zoX7P90@}?M`uth5_#D0aPoxDxj84(3X@sngq!?-?ADKK9m^z`_TAcoD7q}cVUO+w2-Kgq-mcnWo0 zFl7r?`()L$7N1rN27iD5#@ze+*EQFj_qn0>tLqD;0pRkl#wr;OE9gkKzdzpL9l0aZ zdc@0MXw{jxQBM-q3dFuvf4{TW(Go}>^V6};6Pb=oB9q-09p8=}>3IrcWOnfIr~PfF!O)!)4K3| zT44`{wrPb(@=7X%$+b!A0|jVPe(+2fjz!=Ca}4|yK7T=k9v6Cc;y50m7e?rX5qeRC zUKF7h3!V254aE_9Lg>6lXh@jxQ29zCaD~|xpmWd7MhkOr$2TKuLNG@F8rl&RWM3B9 zJv{gWF z49Y_AEc2&cOuzJC8>K|*!`P?g(=sp$@O?Co2Z)v&moXgdWEBG`-w2ci+8+d;_c|ud z<*g^lF>?k!wOQhA0Cy4;J*RYP^@zhvF>@_uvy|C5K-g9g`wZYYVh?v4P?-idc-K|& z${=LUsH2H!SgsM$ zpLda3ecnZCdDp0|v#UmRNew*`ZX`ZFuwH3uGxND3O)P|WONX?1{dg9}oO^9fpfUe= zOgQJ-oKWk^Ief`?5d}|M4Qt7%Cday*esoRYbvX^d$kC^m3vO$uty@3!=+ufBzpggV zo9`{~mc-ayp7n%Pbe~g~;BXG!Wpjb6Z6L|u?id2#lWX{VoFcR1Fn>~sJm6^g7sQTi z<$qt~`J;raT27y1F^K{{8~2Nf1E<*aE}9!&K=5zfcG;w5@E_XIdGJz=Hqe~ z1s_HME`ZBrM3hyx)spXXY#Ngj0xXWRnzujZ^tf+`3=@E{;c3S04ze+sagX#vR@m1} znvVuARS1lPkM|X5f_VJlRxHZ-b1XNv)4 zQ~Yu4;Nv0@Myj!toF~i>FwY^S?J}f_jB(^f8HRV*oU>o?DhAe0F=H29P}ok~mL_~= zF$@~M0U38i5Qp?Dh?q?&bEI`(YZ9FO0Z&O~0((hILzzI_n&ec*%^ZE}?$6F!4ZzZp zguKBlVb7-Tew94U8DzQVLG7IB1jtE?U}lYV#55@haT4UEiG7Vv_cup$&7g@?Bf-h? z&5MK%Gp!_{rI1B$Ds8g_2S`o^ncS$Fv_=N}wxHSbt+^WO@{5=Pa)CF0mTxQ#zy%=f z_-+Dz@Cqb(myeKd8Sqd74JY7_naTr1hDiTvki^=JO~I+|_AEJo(aRT2wY$qLi`vL1YpilzGiO?yghOL>Xi_j zWo{R`f47q{DCY>j+RAP+>S`sseP*QGPyHK+I8oG62h}YR+tNR_=h_ z#TxC5F;>$eLw>AB7raw#0-syOG?c&g2B}zVdG_W<5=&Hyxv6HR(SdWo$u;HzVKx?EYj!|?g)_CeYMz6 zx#%!mu6tm;cK_Kw+vf!&!^w8`HvB`t!)uqO^!HvwmJ~!Y-5y;s%uba-`Sln25MJO< zKn*MpKqMM-^E~>(M=uJo5WQE}WMwT&&c5$jJR9IiGaFL!gb>H3o^nw|w=|vNlZt%? zL*Iyi#|hS1G?2R-e^jrG;36XtmGbN=hxY)|piJc@Sa+mPo9^+81ZXP?qy`(;vRrL>hKcJDprTJ3Y4d+J<)vh>u`}s_u$xA5^`Rn_k5SROR{J0Rm?tj0WEyREGKjY(X6_@q*#7n{`_V?|N3**1w z&z$oOF|EI=Okv8uWHLRnKbcInG$#j#_aytW>A}IwKyrV2FugZ3oa{@kZRyMOw(MC4 zp5%^=H#V;omn*U}E~M)H$;@b`??54w9LWvt9mpgLxxRf9XoMWGuzNFwWZ!||;mjan zY1~w_WNxrOGdd|pA-6v>GB8xIh`GU>4UA08$D_;1F+mp_ojfpD$PH*SlOu<6g}$tn zor^`4Nb5mX$>H?i-pu83Cx-@;{h5*6aHe19I;jFLkFLSy7+3n9+@2w-={>R5OuA*w z#G0Ox57nE`xjPUeS(1}0FGeM4{| z7lGC688|Q^9Vo%!jMiiGPy_Mi;?+YuDql|yRvX|9@3p4FFJ*Voe5yMA4Nk_r8pf%M@d95)>SZx?KyLOJuIa)u8K zQq^R{)*U^`Jp+f5`Qc1HJ)BAQr3VJYuEds&J7USij_c#;!Ty2Fuq-9m$Z45T^tyDu zZ~*Lu^oZ=Nq=SeQla6HOAnMvBXXQy9pZIJ)1AsZhHvdRrC~pZ9?IC zTk76hkX>Ig-Im^yS<{*++EORygEP`2s3erhYG=%u86FOz0EO;Fb7mqdNcZdZkSq)(3!_PDPByu3Ad?>E(axK5e{O_&hs~N9 zbi;cx7(;a9-7`G2KRN8x&b_1>^P)%`Jh@m$7(E-1gUh9Fag}+$+AC(BHa*sJQ<$*?~?N|lx_6f*ns7^7S!?B{0TWLGtyYsJ%;sIcImF>xd* ztFzy&apdq|UveOas>PJ#Ceb9}Z6l=6nke#_;oOi%pC+P0Y07rYl2(OI%96y0L=yU4*gI?IOfnw52oA)zS%5yd4v@NINEyZg12gUG3FLEYeImfFP8fa7TYd74Rt)s zz`%?iaq~GeWF8;$Sd1PT&M5*L>ulkSa7?$cYn^1MQrcB-*pOV@#@OnDt8bWNZl1t>|(o93(x~bSa^ShOSp21WjblE&`{S zT_q?7+Og|oU&7p$TT_yvrX11h)}%Y6SYXgCsNUd?<7vA;a`G( z(uU766B;*RCpK=LRFZoRSc|@q%%EP-*-hEzvI+(iuGp+A)HOUw4&(-DtxD5ZvUmOJ zJ!|@V)5Wf7r;?a(QF}>dOs>>FSFcWv9c`7PG%BUvsiCI>Qm z({iyXHS8H0#x;g>j+1z6ERdkSZXUv#hOZADMxgEJwc`G?zUyPzhbvB7C_juf0c=;Z zZEg@(irTX+YuU4|i%|PkTr9nAZLE!M9C%%JS#spP{rYyz&NnBTon9lqf{Ma$>5$~> znaut)yfL^pIfCVXhHh86Y<%Z|%mH~N0|9oMRU&!et}YtvvaIf3zb>-}_j4weWqJ}Q zMcyg}Sq+F*HTm@6fg!p*gQiUjA4TGZJ}mDHf|J351x{S4fJY*o12rK%s}!JkjZ!@4 zODtiO0)3A&kNmh81$ifC60-EAE*PnI3eza)r1h(@T6GiU4zARR)1}Iddx}$ua)NF& zN{Q7!Am*JE3FVm*ftoNOYMjT*bb02um!|R?!Ce&G3_*8IlACx!zzT?1ag#vXOGDq} zg+{T^6Z3W}Pzbvn6tWo%XBZ+_KQApGKxgY<2`6EY zZtqRNVwgMV##;4Exx>2-IbCA)_+Y}FvSeEeE}vGXC+p|(iNhsDP-?n!*|Bry#vQwo ziLJXf?%3L~8U1{i?ona>LVGxr9_|-qS9u;xUh27IbMrd&+O|HWFFi+T5a_ zr2c%{jxNJ6@IX}tLj;8l2{Cg%<4amOii$UiHwY8yApY9_EPw6e_zT6$Hg#kZ^&P32 zY;E?VoxuyDu`6W&W2AOuKiDZQ_)__6h48Zu{6t&EE}ojZY3_A%ve#$pvqrRjtgX6L_N2&XQd&R?tZ%%2Kw32a`Ljbszqlbz;;k~rlO z%{F9@X4`k?PiwwMPiPBsTizz4A#^zR2lEceg@Wj0oEWsKLBfpqkUfY+|}7g&%EsQ^Nw}?;HkG{6AQ2J z3X(1kS!Em9N_OT?Rc`V3M3sLlR7s8OCpu@0eFAwehg~!0E(aa$ab61cZSSh9%bykz z{2^$4QoH<(A$l3Xmmc2V*LS5bj#Spn5T&BjC^bucL4U9$7zmaIgTYX+ELdJz5v&xV z!l8ib_QS(=Cs)jZD<_ zfmf-^S-!}tDBtC_m!L6qJq2LP<+PXABY&76x`y`WhX(QV@ajm%jx7-ab9e?BS+gqE z8aa^1-G@x1ITGzXkQ?Zaw60$k*@ef(S4Ys(>Ebi;wl%TVSgdvZ+l9ugT#0o-A(tMA ztXw%LpAQUY@Z@5ImT?ELH((EzV*Qf1H#0~Vav7}9^0?=TYn#LSdxr)_K<&?^0UpR> zEi^K6&DyoCEkO3=4_wnVG+fAxuG|s>ya({kp*@8gd$t3@#W@zd*R0x|WNUZtP2ZBi z!^)9%=Kp?k*=$E-++bl z$nKFtc*>+4(~-}2<5}PC&3K+PuzMGtxb5chwV*vr>Y!I#?vCO8U0sf1OBiKazaDmu ztZxsPw+b%Ar?Od;J-@*1Y_hr)KDNGdtGuYh>j%)WtTs4HH?JShZ@m^*=G# zH*f$ho)o*Ao|-vHUKsb(@OT3psG#dIxq;p2e7kqtxVm|FVr!QNy}hIBI;MAR*_qh6 zd-bZ8*s9ju60of3P9`_r*s(dX5{WH|t{vMpCprOO-M*$-$89Yw$?JPMI+9%-K!G9I zc|&4zH`3i3J8!r)31*~k*ts#evpX4oGd3IT+;+o`u8lk4rlI|NlD)%2hek4&@8-VY zJrT=qo+bXIJ+hBRCU=-o;)D(1hD{Ib6J_A1Iavmuhwf)O&AT%AJ@gW$M>JWKc<2G9 z(-hm?9t6rGM;#=_*NvZbUv2)}WAZ zwK$>pi9q^hJ78fN!VR0^qR&zReLnGC2P{mV7<9lsXmr#4V!Ml8;-Qy_6)t+fLr42? z(Mvt_Qt?Z>$gnQxp$ElxUG$KL9uoh{MKANv%fv@q^l}fqT1@dI4<*H-#qaQ?9#yy^Tl6j0I?zJ#UH!i1q>O&tT_rQ zg5OX6+yVqagu-A|gEsP#DSVP6PZS=aYD}Pv2ucm#mF(bq2mwH=47gH3!dD}z%m7rC zf{T0%h9C?D1M8ayMw#39Lxe#7rx8OZQe{LnFkaM%a)R$AY(=NYvUx;<#9}c+;M&Bj zA=6RC6yTN(H7}Eh3`?Z|Be0{H6lxkM>S1Gtt!HX5#rQoFshH~a#qu`ASeuIL0 z6ueHsxG%!|>lKVbGQ3Q|2?aMR7=>l}l?uL2!B`;2$j;3QUI}0oRyM1!uWLBhi+#r< zV%11t7>_>@XLSnK2dm`9hdtP#krAta$gPqqQQYgL-NE+>oDB{x;ORq;(>H_CalS(n_S-N`bQ_DT3Wn)Ft3 zuAm|`=Qi_IxVqz-?~~V6Vim3#leqFqX0e+WThdn1vu;v!a3q_=MP7l^&1+>^Y|iyI zHSNgYN!LiBsfn*Qd+COMCf%D$9?0R62bXZuyi@JDYpxw(KOOUIy2mZ>%N5~$`e^*g zy~FvWvwb(MZiBMPDQk*ST8dFx))%GFn*x*O)3UlKC02~mysjvvwJ4>z7^SES*6?!` zJYG>dvSg!}-f%EEm$$povs2#cKiN=lnJPpPe!W{(zJOpeIs3NNK_@5cHYvNl&BNW^ z2A%zM5{*uBF^!Y(ILhVj=ACpSsKXl0o0@jTwj1_#H*KRm@J$;#JKCCdY`ng$ zX*;ew+nP3ZbS4hAOk#<1P6dE&r47y5W2lZB^?n|{1hOqK&)T{uogm4I*}?!MfSD3MLkE1 zaxq?z$!BGRUs|S8AU*#d8Nl{RqqXVG@IL$kVekSH?vfdEZZ@Bld4GhtiHTjyDj-a( z*GoX>3R*Yw^6pW>^0_f^(%3yE~%;Mkd$RC*TDFh7x z`&JmZ83vn34AH2~j~i|Xac6;SqLq5wN+AIsmVn>sG16=oc>~;_TMr2;7dUkgcRM3= zNgx2lLY!c%{$Vw&oB5=3nJ6D9%ZwgJi>lWmh>^b)j9Mf~So)XRFEg;_GYqL8y4WKU zSjIVNqSiLx(prXcQL;rP5e5G-1g+IlMpZgDR^%OFHq|plbqE;0p<0Qh!H=5{L4rOP zDskGY#rl;Vqng-mBTmbw)dcbV0HQ@?d4u8z%<`v*CPK^-DP=(YoREG11R%!m+V2kCf%WxuK}|Bfs_ zb`Mxwe)5$CJuOp&pg)*{l2(xIpF&dQ%Z2Cr7w=$Xgr3kzV?r|+BYz_5-iP)t>07~; z)9s2@FsTAWx>-Qo5)q9AffSNf;+O1z(GiXaBrTeqktDMV9#$GHA~6P`k?;}x3DM7T zwgbRX8y0?K5wWD$0?dFMBK)faZ2gc6HqMkRvJXisq5dA&H;a8N6)#hR0o}*}YLOL<23BDy?HB%tHF~fWlpS12C1DFV zhKfcOUZ9JojiP%>_-lg z&d>X3`y4hy@wO&w{}XmOO}783ZB0uXGe%Nnm)idnl*O?2KdlihG$f)%Fl4L!PtTva z?ctK1aMZl8hWDaGdny{@U8@uAb;jLUv8t{)9;*{~hgX^xVoYC|IQe!Fy?#vGYkcgs z(cckI-gJC)NB!~q@zJC8zU9URvB=Dye0%%ClQ)PJZyalipXfBtHL_$Q_V)yk&mxAd zNQg)%E0$G!=Za0Yi3>OVey8u;0;W`sx7R=Z$jQ!syD$&?lol=8)Ky#e`<;QYME%zv z2`qc@!ffWMidSzF*`s3pP37@po#t3IW6R=3_D=D|?X-LAfoFUVKY#k$sHvFp^{0{k z{0~3>!|$ouyB+cKpuLEgmMQN=d=h{8Q}Z{M^hDU&xvaM#DLo<)()t`CUqbML+Wp0sQb`~ zLuU>}V*Y%hzB?aScHu%vA`l6t@?VrYx5!82FADinVzHmwO%<0hB`On(>Q3$!(b}V3-HFi$#Dce+811h=kv~B#WCdDCqc4AQH(JQ9Xixq$)d>ZvBia)Noy*J% zYTp*Okw6c%k_A>PsrPt(Zd@!{)Np-QIk%D>_2(Z6EPqk$;mV5IP0Q-G@AgG!p09{( z?5d7mS$DE-F7v>jH73xWLh-RzD zO-Pl#p)MHj+%1*|$0`=>>I!W7WL>cC=;%=qz6m?*BH`12>X6N!nw=0$Wm&O&@z~vB z=5;f-JYILS?aa`QgBusSEB7pFZp0tpXnnSb9$(l3Y*!@9Z^``^20J z$`dF=gS76r~(rm6O=*^3T&CGbl3YdQ7MwDC&yILk&$y^d+` zW1G0|%V|^mRoH|n*9z3HFK=(3+=CXeG{`l4NA0`p{dpa=qvrnFcU?}sIc=hHz7m_T zV6}o?!T&ehza^I|*pqU}O){jI;&ySBK1E!-&RahdeYuhMQUtFETIMT-UgXJ6Lq zvM-B$>)MP(7{1{wN!I9MCw#ctu>&?7xL|BnaKTth0Uoymu+zpx2Y~-H-^k$i&~Xg| z`Uy?OHH}*yqaNrqH^>n1&~cXnbee}`DD}{TOs6?PhMcaP)?{3{y`ZkRB&y5< zmwV)~x`DhskInGVv7!N8kKF?MT-^HSi*GyfqkT<(sbGj=NUs$k&a z{ktxBrg+>1&k~<@!L!BtUGN++?1JmWjSd*Q7(MpP5HT0M%0sWB>utLGhTj_07Bkb2 zAEskJ&^X;gE3=-NRLjCW9us9><12N#nSj+i(A=iW9wh{BR+c>&6yIbHv;0kjp=K@b zJTUiuEZj8+2?}#fV%WfGw6PkoY}|+TH)z~%`sIxs&K!HcXg&i5JB`p$kl?Iu0s^}{ zjS^9F;%-y1f-!ze0C;do({OL?IwMM->zbfj{+wBTUD&(?ooXAsrUgE zKd53f7M5#OaGQ#e1><+An8r}DBSkTY11i??^$HGB3_jL_dv4S~Ok5x`3?_zg5eODx zwy1qYO$x?-Ber9Of&nm$%42@)e_|MgWq7TE;cSMn|B30#6^u+7jwpDeg4Zj!Tfx{z z_3HLD(R3@{TK1gIr%s--clB7D>ODt!)Rl+sd0BS?)jliFL!uXi)yvFYihU5DhvM0G z#0EOw$@Z}GJKWgqHNCw*y(8Emc3B&MruSxQk$o_F(ad$>^6+#7>|=3Uq6(Pwd`0i+ zjQj>Qy{zgyesHQYAsri$raTi8yN~1^5vu_evDU-oDoGJ1{7Ua0Qk%%AAvucX=^-wP z-8&p;N6&C#?Ox%)I(Fnt=nb#W{*+7amyw3>>7B2S376a=Ll!u%EsAw(y%C0DmT?MA zvh5{{!PmX*1;aYl*=pO%jMr+@%Tj2au<3;!`Z%+?%q=gp^rGOGk@_VpmO2P~G2wys zHU@x18bmGCuFxE@3j9bxY{c$nwC0sNn0ec>lD8>J<|bb1vmS`v&GctEw|ne79a;X1 zl2Z~#C}(R4r6vAG>l3@cK4yzs*@MCPvcf~eVu<@$xg~7LZSWnj(yqi~#~EY^Ls>?T zHud$(jUaPcE`OQ%Nvz{^7W~v740vj%^hygI8;!86kP9bkDeLbSF+cbdI6PfR$)y$p zT9Kq|5WW5gk`5QaW0Z+4ibZo=w+4R&%k9SR)%dfNAwfb}EKZPgXw!w3ax9D=?dPRv z5S9)i!Z!%isu2{|V-muz#oEoJUjVh)Nt6Q4y&0g!9hc%3GZMT*gb^f$zq?hwD69@r zAweaUIh^HFibFBje1s?SOO`5}+J&X~t%x#d($D}Wx^=lF+AA+%)sxtor4K6w+qEJq zMh$>psVKEPYSHE96C2buhBqY`Nku4Cy_FGYiS3RGfJ#gKQA#6Vp=t;9iU(@!1S8eM z-R*E>xco_N8EL#mKVgOqtHo8e3e`&tEUc;GQ({5zX-SpOsyQ82S9A;P#(_4dE$v1s zC|<@dL{uNG{wLYEgT#gq0W)fsg4SDoA7yBVI_?eZdPou1IVQpj3usdS2cX-bN^TSR zQ-!pnYEtFhpLUv<4l0OIHz*iHEOIMPv1DHj1{fIJQC54CuiF zT4A@+7gAEne3l`)-kwm)x!15ph$y!lu_{GhHM0yUnTZq(2?rNYK0&FT#b$BFicx0d zC$Cd6LR=Pk84W3$bAfnBNg%56V`C46ITizCso1i_MA8-aO(6Ysp+<+3h-@)PXE_`s z6_Mia6B}uS3rU^ai=bVi1%-Hyi11ICUY3#tlB^@ZBcP+#{6Z$xuTNqb3dnK5o*;k) zeMqvB8xivOJHRQZGxY62QX{X|6-n;JP^XmBehh0b#_GxUVys)&);it271Y8IZ%2U9`Io&NHWQ zB8m|a<0A4Ww&Yw?U6Hc(z<$8(e~@+2EXJb!H*X^M%C z=ia0G%$oeE>bS9ZW9qA^@K(|ED016~zjpSOd`2%KGZK$?olMQZX*vE#EL{=rPL<@l zu@~dytg=KfMSsYf^dm2w=NjbiwCCuL;kzG+abLoKhkfMdJljBW2;oOd<3>YA>dPsy zs3acP+?ndkmz#~L<9Q<=rhOWUkM!XDAIpA{r4YlP^I7+Q)mbsG){ccJN7Pf6={~oQ zLvDJ{+owK5q;lFe$bAUbya>4n+wh(f##U@Wm_kp`nA!%Kxr_PX)yTTf4x0E(o@~Zr zc>9^WnW}x)tFQ&V;1!o+D%r`(;jD*UTn_up9f1EG&t%zSO?%UNuD>qb_v`&!p9(wA=ly@EVDbSy@BgF=HpRUP zru7FspVy(AVcT*ES7|cel%R7|4%s4D`TgwWkOQXu0B+dyz&`P>rlk_O`^8ZQEKI)` zaKJv?k#N&X#1P~FoXPB{|y5J3ez zco*+-!8Ic7f@{UKE_kL`>4Im8S{FQ9{D)SK*uX0o|Jw!EiLbg~Tp8a(jgDF$6v>l7 zgdcaHvRn$ftOgzhBKw88L0)H9&sa)$piR^N0@KexTAH#8=s{tW5G#2C!9X0qQ+>a{ z6KVv2HKN5|iuM^W=9@vOm6_3E>2?k<*v^2CjRbcBT(Uz;nNcokB0q&30{;XqQ~(by znK|Jpm_lA3+sBm<$0E7^xNN(;p-3@ZH&DDu#e*t-RK;fzn|SU_`<97sw}PoX5S~0o z_34 zS>{F25&3SM_hB_8>1}uG>u8dD;wRW7o}Mj}Df--b`s~@~f6fCgCTsV0TjB5YIYDagHtc*1?QQ2a7d8LOYmK>86Z^;O^Gtc_ z$J&$j#@EM?OF!H$vY@_n&viZS)>^#l@@YNx#%zMeEBdg9X&&`}DGd`NR%YHKA@o@f z7~ADzZ+cUQIQg&#nsFU@UFKtN(nJdIM=6eJ;u1UQho52F)3G1VHNjycu9ZxpUB=xC zbVT3{_%WGDA(~%A_?W^)dsD?5MZ#C6~VMta|9GqJMDgr_KE)_8>nSz zW|h-}nnlOmNIa(jtMK3kLCdN~u2_cZ2f>z`XjMXi)VKne9l;<|IKBy}v&u?GXAVKk(~fHO>C-de|b|6xwJjDMCH{RJpT4E2O{=cM;#z_9ce3K~?mi z@9sYcD6Loq_aJ`j)dNF|CoBT*Oe9j80ji$1 zTB~}}o>7*H9pJG}KCs>*S9;1xjKkx+AV14#Qb;9ICTmShLocNq=u(K78u2%VKgz@r z!c}A%1$m=@*vRm4k|LD05}tZq5{ZG(ptES${b&|OkR5)}s1)l>1T4o6q!jeA^Oer9 zMbIYVJF~%6f93%@{bV-N+aF%GN6a_W}`VmW& zT)~{gHKC$Pz1vwf=u{@na%!JLOe~fXR4_6Cq0UmJ%2J=V4AYq?Rw)3RB_1x|TyXJS z&m2cJ1FNKtos^HaWgov=lYKhD=Y(oN{7i1uXX?L5ta^T(r<&J6DwEJGM0cY@QnHXz%>+BY`X5c7C3?rMu?vhw6U2+nl+y^GzFYGSZmQP|>r@e@ze8FI^Q~ zG5$iz@}7nsaW6fEzIeJZel**Tts&;Q27cx&IU0JRexvJZi%V+~et(x(RyrnDndjt5 z0GeOxlUn63JrkyHyBMQl+0Vz0;k*HJEV1wyzOF)a5qTQ(0moNF^4Cf}18=WOJr_^S?y15X`Xq(( zW}+2i;;PEAh_qp}8Q-xfKQGIE@pL)caPhSCz{S&&3x~dp-CtiewrKPd^=&;ZDbge< z^xnPv+KjYb*F^~?yznXVbVewa`Eg36Il_a!f zK8+_G_`|b!{uYnaDVm6n>n-X#XN((7V%%(s^iV!d8g6$omgMcd2uA#Ihc42j?Gw=; zc6kJ`%Of}@+k%Pm&>#7Y%9gkM>1ThoUt!n3w9TmxGA_H_G}|YH4>SblksaJCth$mC zq?vqaaJiq4&K?VVU*Ojt4UIh)tvMGSe<4~nb`kyO7twO~Lo@~9kHEOE$v^IIGRI5c zpTLy<`Pr$BTaG_0npWhy8U z=R6e_v&Mqlde_GfXUS3{BJMWPk7vM(Rq$ffSV^P}^;D8KW_4l z7bW-6V7s{6&y+>zYj5B%xOSV((2IrYk+DRi@lhjM&irS&VV~idp z!>2-WF|LA6 z*;p`9qV!5V?l!8&@k{&d)%yL_%FmqCSEbA6oUaw{>Yji2dv(9p?W-&)4VBLj80E)* z5ebZ6jQGc2h?wKg!}rf|KP2BNT(<{u=0@$6~L#M0qZ?hUYIj%DboBLpIr7E@%6rXMTxG zwBbwbiKAO&z6LseRqS{z>h!hH@vGvG*TRnOU!(T%TKMDFslWV>Kh#^rXyX+A|C_6)eg}ct z7>z^D>mPmH@oMLjslK&K55-@feE+M;`^xjBd2=dXmBCjO{u`cGC?A(h>%E5N=3nox z%r;X2>GD{<*C0LfiW|l2@J@qOSJQo;fd&5OU53}?T?Y28{T_q$=&_F*ko#v>trIqc z8#X<#Ph1av8oOoiF`e$YXqf19??J5X z^}s>qr|UQwf*yK^>2w_~L&!rf^T?NZ=;chOYfTx-J@g8u+y1KX&}VqyN)KGc^7g%$ zDi1x(bbDV>*h8=Oz%?GY)+1l*q0jWtXL{(fJn(Ghx63=*L!ZNRTK~u}$3w64z;iwD zJdZu|JoNbFY)MG;-N3~(3g7XQKsAV74^`UF`d?HGA#4ZmouH#_cAQ^(698+uk_GYFg>ot z@ued7c(9V`bbnfgl^*&krpt+uI97S+S9$Wk%0rJa-5$SU9(uD!zS%=>@z7g5^wl2v zY7f2DLvQua*Ldh_JoL3pU!uGt#9F4?<&pGV9=ZkMd=wh5ZU3zk8(s53n+IO+fv@(! z!=l9@Pwz=BQ84ZFq4%=pxnO&1B3=Lc1YW#QLBbnE$fNIf?8b?PG~J>!L69(3gr&x#&?3Ju2>S(U*DX%fvnx zeYuCeTx@aCuk_Hb6fqZlg@?XE)Vb&@J@l309~}=UeVA|EZT(tKLWBgm=p|26+F8W#zeXTg_ zqObGN*NLwvI+@|a`vGqMwTVA*&~eJRIIZ9a^RM^tuNMzvyra35{tU5R{1NzReW~Gl z08?HXJ`a8xBI%F#wSJ=eaDblMo~y;XRQ@1?{~FQjg5N0OF8EDil?!ecGhJ|pc*(x_ zgT78N?t;6-*IaP7c*q5B6d!WIJz~@aUn}0>g5#pw1t+lShe{%Yfwxh^F8Dg}qS}8= z9Q5JF@4MhF;t3bLRXpf|w}}t9;O(N|g0B~Eb-_DCy9?eamblh;8Fh(AR7t{QYxQbFrlQ~VJ97Q!##4fis_itpgBMwFNgRDTu_u&2q0 zYGL9)Iy&85h8pv;vw^%9YjRo>Vku7N)gd`z;=OY0#pg_Dg+322(7#po6Xa@&j&i)m zww$z(AcRaBVHQ@?w{i_=!4$#-oFXrRruZ?P_m5CXV-Cb)Y`hVsHzmIM`vAf~vYWz+ z6E8>I1s(M?N`-erXf`Q8rY1%V`Tlz?9db{@7%L@mV5V^eS*r?2r}l+snb@mKxSH97 zeoj=?7;{Wyd=@x)8v;hw;Z%Nzsg)7qQ1Zji4K5P#dezUH!LYyJ2c?Bz}#Fqu`pN;RM(O@QSj}QoK%(K8vbR3)FAWs*8wFh z(5hvhljOgrL4|^3`E#FU1&TNTeu~J7ixPJ*Z;emvBZ9?7Byex{;uO5v(jaP7CQLCg z_>ml2PnrL*r9hzU(gwoI@IISSVL-$G!(dc3!Y4(rjpjC%Cq}Ty0wZ}f6IopP%#^3! zavd`lwJ;sfl&CGsptBIhR~bRWED`1KRU_X4Mcb4D+{A~NQCE&xW4xUa^aJ_^Z422? zFAWjQa=$=Qn@o5F(yDK<6GC- zel4)UnoD~r+lbCmA%st zZ=`t05IZPFJ~vT}a`#eL#U^68lMC6&IE!6(&{eOyje9xLCB;@hM2X#eb0 z_^gU^Du%yV59)#ZLVDPqeafBzLzZv9!BZ5Kqm%4Cpz3MV5VsJF_$0+6bgnt#f+7B# z;$w#RF2x58@vjsgH~2I5Wj7%|G(*a-o?_S;p%_4u!t3(0|6w1^6I6dq6vOTfh)G`a z={Q1k92yi=blRUt`YA3uY}X^hx7cum=qMk_QTgJCN&jXQQ~gmn+7!H;V3bqWC+j<8 z>zhY(_+^QTb^SBn5u1-;yx&gcqx=}Y)dRoB10S{FZqg4w?^5z?7yR6+V750WUv4({ zs&jO1R&Z9GWAk^aUH+|tpH}b_3jTWqKdInk1O~e6?{;^KT+_* z3jQYrqw}+$o>MS7JHtO!@Th|SS;2p(V62?Dyu%89UcqRbEdMhFV`ya+LtAbxt@DT<7T*3D!_@aW}tKk1o@JR)~q~I?q_&*hVT*1FkFgg+2 z`+pRCLczaO@M8*oS;0pYEL8n}L&1iE?^Up=;5!wJ?`5+;9#pVj!GEn_T*EN^;|j(p z&={*1%Fn- zVFecyT&>{y6pYm?+xKS*#vx%0e?Y-A75u1zXDRq@1CVKkW^I+Pinl$P6{85tNVj3o1!;bb4q+!@RaBoAdX zgE)rhV6HEd9Kt7%hV~>!4iENCTftO}lu>S|e=-)zBRP=UlPSQe$ry%Fl3YGBlFSUI zdj~R;D%n5OKdJ2g^k@>ENEZs3{rLiaMakxjA_a4}b?`%zUqh!ns4-cWKOhO;pmxM9MQGGLuAh?`9TH`f6 zSF{d2Cz5e1rZbs}wQ!;pYvGE<-}-TVxXIH?m~W_n!s7t5p+3~7RRr(%#4LNLjlSZZ z!x>Jd!0RU`W09UCS^D;&N)8M<&v&y-ow8q%_@(-l;+d8oC+mMCe~JD_EYoO$#8$ik z67@1WF^d%G#6)v-;^au~mI*z10@q}9ICWPi6)uhmU7a|l(UtjQa>e?bB%-b->yQ|9 z`?9*Kn+Uhm(a|vDSI1u_8S(k{Nb13_4)2H{G{SXFpWP z?a86P(jeW}JKduPSJ@vw<32)7mMeO%oKg->|3pFBbC=tn_e{brtTi~fv6JJ4qQ~{OyVZ+)Z9#?{yJB4=0i~|FYzb+VpA~i2;$OA zV+W1QhcGTX=WrL3H5I$CuKw#bM3W}W^DYIhemRgC+*`=nYCNCKvjm4T_-LN)Ko*w1 znWyJN8;MWmP2j}zsCrbtof*%JmK==;)|}|VPHb?*t1?cik14t(F0(PRzTz?y8l#hc zLSrOik;X`*;*C*Jc~+XNRFgJT5|V4kDI2P0OBQRW#NckIjJZ@pC8miDm9Up?jl^Yt zq|z}NkJxR*`Jqv(iruq<2R)(f$pJn&JTj8A^{P?dlGWoqA$SbU4vlbKQQ?x*{13A* z(_BqiV&t_2+T_TAzCJ8}9n2PKPdZ0yd>pZwN%!WG`!oCd@`uIr&TzHtax50qWFnVI z*1@gvW1?(TUozd6-ji9=nn@z;*m&c_kBLss$A`O4dRA-m+GZ4Ba?+Z%;-odjNi9W5 ztwj%pZEjs#TxxZ3QmiOx^}6Du*5ah%-e@WAjh5oxXesWE=HlL%qQ07od!xCyH)6%T z5i9PESW$1RFY1i-MSZcps4LovdZMjpvuG>ohqj__SXa~w>xw#IT~QybE$V}{MSZZg zs1Mc@^}(8=K3G%K2WyJ@ptYzET8sLiwWtqP7xlsFqCQw%)CVm^eb7?W2fxzaGPXwf z$*vsbf>VAvdcsGKc^r4$I4gG3%!@C+?3v_-*>r@}3DuTG`o@A@D0y_amr5SugvFAF z&MOu#&U0hTL%!7Yw3l69OMCEoc_VLzd5EqxcC*(ZE^5q6b=?5-=$-6}*}+o$#@7TU z$1=h}o9c#_gUxk)>A*W~f;q8+Ielt5w+UMISqps!AK|T~{zSZEeW>mXd3mO~;pOFh zrLCTgoJ`nRjZUUXTD>G&w-7w073~isHdTL6^h^55+h<75do#;p)1<@EDr>YN4U;!0 zqFhFYWA;fp9N}FZPTsikSn1;M)`zRpxw<4NcTrtklBk#HcJ9j&hf(euR8B(Cn^O)Z zb&2A@=!+BwYQhaE2W|43QIetPji}e>eEq2p`XBV%_IiD6nEH%=-I!PLQ=v)knCX-J z9jud_+y7xa19N|_z7H7d8}b!1DyzcPHMKKm&7M;?ci#N^1q-i;G%RXtTD)XwblLJN zSFBuhRjj#Xb?ch7>)O^|JwZ5s-U? zeivI_{S&0y8KZZ@@`?BU4-yU=BUI2t0^gvHrw5gEz0j?AIBLUhDdCYLLYRMTO|%C? z2m5IKM}>js;aUa>aK$y7L&8epX?2B_#|4=cq=G8fFRCqea^t5|WNLkg$!y*>gRcW1 ze42jj5QzXAV7iSI?MVB@yM-7fpX z+IB4z@bk8}AaR0bm6%}K70F?Rj3n9jlBGkTWl@7A^n{reu(lE{WXEV30hl9q*Wro0 z4sCqAzf$|BvQR`*D%e6%fhGcxBU%VC)u`kN91z%_mxiM0ZPuM zABP}k*7?PN%#>_#>(Ev;$&FqD8y8%m0t12Iy<%J*QXo}$y#_R83t!R8ew@pb-+jVz zHHm$nesr_ND~eJXArWkS5>3A{Meaw<8RBEe!C^g9xo$|FLO?Vfv}GiYl|V}3Wj-s& z(i;?=NfnUwPf)&&HyJQr5c_;o-n_B2ov})(Z9DeGNQ;nz#Oi!y1&|aDD&{7$omCJ* zCuA(;KI>;isw%NBM%)C~p*lR=maIWJP;QWiyO7>NzX<&@!Y`2>@`1I0P5u^zZQfDf zC{WJan&uG%`WcGtqCyX;(;>hcu^8g68Th^?)61v`Qj(H^=UBO>SFjNMXnkP9h#7EX z7G^&jR^9+34KQDZNIS_v^-PLo;M_FejL8C;S3UtJSl=~4o~#u=YzSaO4N?x-KuQ5< z(AVp-kUpK6Hl02kp{*3nWZAuSb~!Yct@YoV8&giSs7_tTF|B0>C+B&&5Gnnl-1sU4K3r3^8X5Ho^UMu;f=I0Ahm zMuxHhmAiwgliikXg`rMm2i6Qwn#3w0@Pf_2DP=JB!SPpubiPDWBq?A6OUoJ4&DBFm zDRV^eE2Egn7Q!nQ;C!6e5x~P8QbPE(7?+m+!a^#%MFYIqN#t}KzbWXGT!tL$EG~!a zgR+1`0@i9}jsiQFiR(Enz`Pr58`a-FMqWAmpRg6$^8t8NO*mDNq*D*`pVe7doZ4v>)^!D1mqoR7 zkT!&+VYC@1)rPtqtpS{pNowcx`&mJlwb-*3!_4dwcV__^Nu9|$lnO-jX;~-hQiJ)b zEjCVIfORrK8G(i_Iq}@bjPygY<2qrk!?anFs9UNmj6#x$yBxd@J;2@zkn+-%XBP-ZSx~?)TBrlf*zfbN{+UErF1h*T z3eB}aWwM(QN~6I`bIn5WQZ-lb`Zy2EsmQd^*{1&hn1z4_!dqHCv`j7oa#+PT*%t1D|9aP8UzGd3Xlg$xfUQWge-V21@VvRT3L}xh>LRdTQh0M`FcKG zf3M}TvyAu+MAAskMP<&Y37O5R8j2R~b_Il)_q zuo_LL0Y8M9KpHKz;D{$C6XQ%-PQ2!VLIjCG*tN3ovk1#YC1ke{e~XCiw;TtAb^ZZ; z36Eb7oGtw5;j*A`3@h6W5<+MWTcT_%$b7^{m{w3&2BfY5O4kib75D-m>m&^%8FcZB z(Dm}ua-iZ%gR7Z~#HBE&tn@q-6VgWt=*NC#1aUx!igrSX`RoX!btZ(beShsL_KKIA+YRSPCP^22GG;`Xv+n#I!{ji6TWM*(yAHiRXO~N#_a45L{=o ztfUwA$tY52uA^TbG5MMe)oycw03FMTLCu<6mf*U7B+QlIWMKmCQ<)+e3KDaKu>OZw zfRY@}((9_y!w-c74EZKFIb_d5!*{{R_wC?H3vl2bi`0&DdrO8rFjh7WV>ELQ16S)}BqKeZ&R%!JzGx!jyo~Ha10oil{Qli=;g%>oxVzUU!NQiae zC?#DoowH`63@C(%h1OZ!h=PsmOGXh|2h6oiNc+PZVTQA$Fcyk?Ktp!OxK&EPB&QBe zH_9%l=d){>6O7V}lsg5m?&1V;iE~1_AxwP8%1>=C0RolB&Vy>kwu`lHvZ@p{jG$&l zN|GdT%d833sq6fO69j{sm1}RY2AQdJ7&FP)idL?hB`h#mlAJY$Ih(};$RxZ)F{&(K zwk!rrM%c=~1=0AZbQXgsS);a(5ZglX@dBl(+{z2itiaBii6tbqb19xwoB$*ZWg^k* z(b#0}$|l>7P_u(nAg~nJi5ODeaNPLQ1{VAwewkk9p-ur&Zj_(%WqnukFB)DjWaS65 zb}{;fCPkGIbm~A=39GIqJ8o3SMybmxFrf>?g-`9aN*S}Iy(krxRluls*7Nj3Gj8U@L!fz0GJ1MyO0f{e&tF_7C=28kiD&tYR z^}tFH&L~A3g$qg8Lz0}ClLT(YkprK!2y8Q3)F@KY9c(*T)8cB%xA3&nTozPrdqD}y zdE;uy*2^3a_6L9aw`d6bi2V zgI*t^GQfBQX3BBW{sHn0jW;V;iXp!O`+z-l0#=bEfJS+64%?$OsGPK`@Y*)<$%B6GFUbmw3v#w5vNOEEz-JT+_blGvLwc^g;v-O~ z0mk@UO3Ryn^0sRiA!yAf**M8V*iZ6~aTI9UfP~$^>4CKTDtGhh_3LA+Th^>z6N$tk z6y$GnEVgznKE~Y|TferA@t6K4clZF=AWB*}ii%nz%ui9tZ~B|u&!0-f?|RsmjVBVD z41AaLx_#oxl5;z=^G73B8c!LGVq7$KZSmpTxT2|jleltb>dj*(vd6RE=)Go>?=!}S z#0Q_q8jTG-b?R%&_p`e=Sd6YK@IAW1baK!?~p%4NVRWzK>^n%)Ds4xySfO?XjKE zVk|wD{|nYrF)r|BUSE&dWAqqzlV(5cnZ?o-n|ryjowLzpGupSuC#KYD5;NWBK{<`3aE=_OUI|EBG7JKIognmYe*Q zQo+B(L6mBy#5mU~#TCm}#uul@Q+Y0v8U67E;!dSR^atmH@$WpN^Jk+`zN4_|B>u=Y z3hzQ3KIKc$w_!P)WZzgko0cd=JM?3+3s5gY9yhfN>Q5-DrQ-2#JfQKDR|gvT5Iv&u&|5{(0&%iL-r1w$4{3pAb&Gx!f`u?2JkO-XYx*w@TILI;XcbbtHVP0+s znMC{T1iog>Hb0yGaQwmat*H;QZTBSNse9s|$aTJ_v~j-wqg^%r>aI_uMT76=vYxu7 ze=F*Go^OBrk=skpl>W4;sq*v2;;!z}r>pvn6-cbp1%=ud;YQg>yLc1bV=p=q45Eu zwQFnXi&Y1WC0!MOn*jfH;KiyJMQhgw5dVo-(zTg2w|0F!)X;Tg{wJV0s5B?HM0@+T zil*4yNKD)kT(R~1CrZCw`SPMW+s}9TS2UjAcXMs~zTPKFYb%eJp0E0lF|Vtu^m|or zGitj`z%_us68K)#_e5>i@xb}2-xi(t-65{%x*DYjcb#m{-5l)7_AVL!9Q1r{+Il`D zkPq~}4SF9B)j`i^py$C}b6oby{`%mGPknFQ=E#v}Q>i1leW9|Dnd=kLdW`K0(5@Dv zU0pdA<9fRP$W_-}wJDZ}Z5GkxptpctdM=vY*}F3S!QQdn74cnt;l7Kfv-`4r&pwmg zho0S)?Rz=$EdGMA2m5{qoXNPx__KYD@xXX?pO4`Nz#{Ts-(Ni=BBXC2>sz4o8H}6H zxOwq#-@N#C`sk0vI1V(m#%*fa>wO_i2|_%97z6Mqo}jejT5Q)F zJFAWdk5;5k_7CHGWVr8#vv=@aGT{Sm5pX8r>i#|AhmZf}arymoBXacL!Y51P9r#{* zVC>i^zRP~jXgJ1wQZS9iOX^qoQ`MVO=Xy}51)cvu$A>I%ScXQ zg9$vL!Mq)Zh2~fZ>rivG;-xaY#Cc7ohqQ)I8}at{kY6YmaiP8xPig(tcuwEt;2EVf z=?4GJHoo0T%Wuq^7j(G<_oVRY4yrqZFwdKmx5zo3iQa@ z-Gw-!_IfCc5Hf*_W3*(p8o+v(4t6U1q9dQ#gCF%V@a67wihBWS$M9#yVc(qOOG5{6OZ+-iRbZWG#JBXL&vah(edH043{i2M*@pFM@knR9|55;bX>Rb=!~&ooO-1HoRpSzLH*Uhx7~H`l)8w<@^&Awb+YGKTH#6(@k1qvJ99KM zeXL9P&8|Dsx{c8q(MSXjYB+zYLX`BF=StagVx@Ubt_Mrvx2L+*>`whUj`p0uANeGF zsxA>P)Fn3Ut0}87H(}%rVPq}C$Xbn&w{EP4b%jsI_r?3@*H{$pieo%I%VTO_JigCl zOelV~FBCt?JU+&h0wW@XA^(!CGzL1yI;$@v;#L`qMEo{g9_{yFqHOedCq|4sjTt45 zHX7y{zo_c@`A6##!Cui&-cz^a2g2<6N&ERno-AEjc@NL68@k?H`f}BKjHO*Od2Zd% z_3gmRRWFMTUB8X^OJZr)E}mOAbe#_^>MG3tWc%CdtGmAUi2ur`Fd}?8{rnfTT~rpz zEB-p=W%Ro9x_BxW?Kt1KsirQ{QayaU^lve%Khpl~uDeRVff>A}@^>(YZ^9hD19Nye zF!PQ3dj1k~?hkO9_xGyq6W8(l`}L4NS{tuC-+psjd-b-_-c(PxtE6j1S7X=QuF;$S zsNLu~+b^WxsL<~(6$)e% z&-IA6sCD)8r(TM`w7EU^($@dn_P&Qj)TgdHW{*;p>gi}NPXc)ZKM9^yU_>V#r!{vcR-6VmRQ)4 zGDgj1<`}_qS*yS2C}z}ImR>WOzu;Sv?Ga4@YxRD6{;PSN=O1OCen#d~jdAW^meQ%* z!|=k_xqitD&GY_()0y<&JQIQTTQMrk#i;PEu_qXxztxDIJr_awzB-nMB~P3)mVT*J zLx=fg;|5>%{$@g68~g^Y27V)cmS@&G67m|yH~#12 zzc>E<@vn^=(P7TRjP4%0X*`DUD5~;&ho${p4(+2#`ypr-<2P{q7LY?h<&al77}1Q< zn;cugTn)LCovo@>#Vp(XQ&;mpSOmkGwHwo2f8;xT2`|b z-@OnR7Y_LRg)3O+U#nIu#%}uu(kr4bv8)k&k;@yywQV`BZAVi<&c}%U#KQj@T0Y5S zQkj2{_h+a#=Cj74j-W5zk(Ofs;p{O9-JgRV18&0OgJF7vfN@aY+gOP4fyRn5+{<`B zXn&OT{ey`)mF8%H7>G)N|2X&spnGieiZq;UbWs?V_I97F$?1>(*8Vo#fNK0ul^X1BzcVAwYY2dA6X-n zAC2YxG?p&LSo-0TV;hfcwC;o$5g*z|dHf6D`^hse&gPSaIoH)C>Nd^YBCw`3qO*PUcv7yeG-&rAdhX5uW*=Mli9 zi|8BicL)BAxHv-dZ-mnLLsHyH>3F*fp8)PI#virtF~H7mavMh~@s)*ALEnll^#%RG zl3*ZM8Vm+Q!Lnd^X$3wvVQ-0tEZu5r0p}ouR}i) z9ksWfFh5{imX3O@0P%-d$1NvHZuh^}_de1zU3-G;%Lw>&=tZKV_Q(nU?Y{S#?=yyK z#hI^u?Jxdo^;Kx&5YNWn<@nm^r$0nRb=1BRKTWK+Ap7Z3^)_|82~1g*{}*MQZC$o4 zr~jMSXYV=jf7^Q(z_^a`YJe=4%{BvSeF|<;3wN3B<4~ zOKVF+mNvRLP6*&Y2!W<4<&8lt6R{UOAU7kZ%x7F2t zPF+7LUk3eQ+Yrm^!uOGAoB8(qb-Q)uvDk3M%(u5q*)j9&7uU{%eF|5=U230#Pc>Z9 zwKCfk67hDiNBfkE?B{~zT7CiLN}i{$u7ZwYZSH)s=e}Mi*LBc#re9B;{IGSj{FvBr zVg2VD@6#WK9X~EQR{dY9+e^7lE=4vx9-MqnW}owVuCZWWW&4=(_f?ltj!Tg}-&piq zeblAo``=CWhtbx45`A{Qa^unKbzNh;=emH;CPGJO+>?vFPsTl+mon~2A%jc3{*Q@{ z^I!jk{KWCC3;5JYw2Vh%@0BtZ9e)(k+36G_K7|L}kl(h?96KN??~vd4{hq{K{Iw5m z=_z*#>Z1J`>=Um=-u^S;C5+$j-urdcPYQA_*k|2$+!KElxsEKNszq3xrzLoz~r$>@Hw>ta<5nRTzz<$?He8*+?47W zIWjmfbZhFCwGAx|4J{krVjO1m>Rivr*g(%4Ag6Og^R@vGa1N5-